typia
Version:
Superfast runtime validators with only one line
84 lines • 4.68 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports._randomFormatLength = exports._randomLengthPick = exports._randomLengthWindow = exports._randomSegmentLength = exports._RANDOM_LENGTH_ERROR = void 0;
const _randomInteger_1 = require("./_randomInteger");
const _randomString_1 = require("./_randomString");
exports._RANDOM_LENGTH_ERROR = "unable to generate a random string satisfying both the format and the length constraints.";
/**
* Builds the variable segment of a fixed-shape format string so that the total
* length `fixed + segment.length` lands inside the requested window.
*
* `fixed` is the number of characters the format always contributes around the
* segment, `fallback` is the segment length used when the leaf is unconstrained
* on that side, and `minimum` is the smallest segment the format still
* validates with. Throws when the window cannot be satisfied by this format's
* shape (e.g. `Format<"email"> & MaxLength<3>`).
*/
const _randomSegmentLength = (props, fixed, fallback, minimum) => {
let low = (props === null || props === void 0 ? void 0 : props.minLength) === undefined ? minimum : props.minLength - fixed;
if (low < minimum)
low = minimum;
// With only a lower bound, spread the segment across `fallback` extra
// characters so the generated length varies, mirroring `_randomString`.
const high = (props === null || props === void 0 ? void 0 : props.maxLength) === undefined ? low + fallback : props.maxLength - fixed;
if (high < low || high < minimum)
throw new Error(exports._RANDOM_LENGTH_ERROR);
return (0, _randomString_1._randomString)({ type: "string", minLength: low, maxLength: high });
};
exports._randomSegmentLength = _randomSegmentLength;
/**
* Intersects the requested length window with the lengths a format's grammar
* can express, and draws one of them.
*
* `minimum` and `maximum` are the shortest and longest values the format admits
* — omit `maximum` when the grammar is open above — and `spread` is how far
* past the floor an unbounded request may reach, so an open side still varies
* the way `_randomString` does. The caller draws from the returned window and
* applies whatever step its grammar has (base64 lengths are multiples of four,
* a fractional second needs at least one digit).
*
* Throws only when the window and the grammar do not overlap at all. That is
* the distinction the retry driver below cannot make: it redraws one shape, so
* it gives up on every length that shape never emits even when the format
* itself accepts one (issue #2284).
*/
const _randomLengthWindow = (props, format) => {
var _a, _b, _c, _d;
const ceiling = (_a = format.maximum) !== null && _a !== void 0 ? _a : Number.MAX_SAFE_INTEGER;
const low = Math.max((_b = props === null || props === void 0 ? void 0 : props.minLength) !== null && _b !== void 0 ? _b : format.minimum, format.minimum);
const high = Math.min((_c = props === null || props === void 0 ? void 0 : props.maxLength) !== null && _c !== void 0 ? _c : low + ((_d = format.spread) !== null && _d !== void 0 ? _d : 0), ceiling);
if (low > high)
throw new Error(exports._RANDOM_LENGTH_ERROR);
return { low, high };
};
exports._randomLengthWindow = _randomLengthWindow;
/** Draws a length inside a window produced by {@link _randomLengthWindow}. */
const _randomLengthPick = (window) => (0, _randomInteger_1._randomInteger)({
type: "integer",
minimum: window.low,
maximum: window.high,
});
exports._randomLengthPick = _randomLengthPick;
/**
* Wraps a fixed-length format generator (uuid, date) with the requested length
* window.
*
* Use it only where the grammar admits exactly one length, so a window that
* excludes it is genuinely unsatisfiable. A format that can express more than
* one length must build its value at a length drawn from
* {@link _randomLengthWindow} instead; redrawing one shape cannot reach a length
* that shape never emits.
*/
const _randomFormatLength = (props, generate) => {
if ((props === null || props === void 0 ? void 0 : props.minLength) === undefined && (props === null || props === void 0 ? void 0 : props.maxLength) === undefined)
return generate();
for (let i = 0; i < 256; ++i) {
const value = generate();
if ((props.minLength === undefined || value.length >= props.minLength) &&
(props.maxLength === undefined || value.length <= props.maxLength))
return value;
}
throw new Error(exports._RANDOM_LENGTH_ERROR);
};
exports._randomFormatLength = _randomFormatLength;
//# sourceMappingURL=_randomStringLength.js.map