Comparing version 1.1.0-dev-1 to 1.1.0-dev-2
1458
dist/main.js
@@ -1,1450 +0,8 @@ | ||
// main.ts | ||
import { Problem, Problems } from "@arktype/schema"; | ||
// scope.ts | ||
import { builtins as builtins3 } from "@arktype/schema"; | ||
import { | ||
domainOf, | ||
hasDomain, | ||
isThunk as isThunk2, | ||
throwParseError as throwParseError8, | ||
transform as transform2 | ||
} from "@arktype/util"; | ||
// type.ts | ||
import { | ||
In, | ||
TraversalState, | ||
arkKind, | ||
builtins, | ||
registry | ||
} from "@arktype/schema"; | ||
import { | ||
CompiledFunction, | ||
transform | ||
} from "@arktype/util"; | ||
// parser/generic.ts | ||
import { throwParseError as throwParseError5 } from "@arktype/util"; | ||
// parser/string/reduce/dynamic.ts | ||
import { | ||
isKeyOf as isKeyOf4, | ||
throwInternalError, | ||
throwParseError as throwParseError3 | ||
} from "@arktype/util"; | ||
// parser/string/shift/operator/bounds.ts | ||
import { isKeyOf as isKeyOf3, tryParseNumber as tryParseNumber3 } from "@arktype/util"; | ||
// parser/string/reduce/shared.ts | ||
var writeUnmatchedGroupCloseMessage = (unscanned) => `Unmatched )${unscanned === "" ? "" : ` before ${unscanned}`}`; | ||
var writeUnclosedGroupMessage = (missingChar) => `Missing ${missingChar}`; | ||
var writeOpenRangeMessage = (min, comparator) => `Left bounds are only valid when paired with right bounds (try ...${comparator}${min})`; | ||
var writeUnpairableComparatorMessage = (comparator) => `Left-bounded expressions must specify their limits using < or <= (was ${comparator})`; | ||
var writeMultipleLeftBoundsMessage = (openLimit, openComparator, limit, comparator) => `An expression may have at most one left bound (parsed ${openLimit}${invertedComparators[openComparator]}, ${limit}${invertedComparators[comparator]})`; | ||
// parser/string/shift/operand/date.ts | ||
import { throwParseError, tryParseNumber } from "@arktype/util"; | ||
var isDateLiteral = (value) => typeof value === "string" && value[0] === "d" && (value[1] === "'" || value[1] === '"') && value.at(-1) === value[1]; | ||
var isValidDate = (d) => d.toString() !== "Invalid Date"; | ||
var extractDateLiteralSource = (literal) => literal.slice(2, -1); | ||
var writeInvalidDateMessage = (source) => `'${source}' could not be parsed by the Date constructor`; | ||
var tryParseDate = (source, errorOnFail) => maybeParseDate(source, errorOnFail); | ||
var maybeParseDate = (source, errorOnFail) => { | ||
const stringParsedDate = new Date(source); | ||
if (isValidDate(stringParsedDate)) { | ||
return stringParsedDate; | ||
} | ||
const epochMillis = tryParseNumber(source); | ||
if (epochMillis !== void 0) { | ||
const numberParsedDate = new Date(epochMillis); | ||
if (isValidDate(numberParsedDate)) { | ||
return numberParsedDate; | ||
} | ||
} | ||
return errorOnFail ? throwParseError( | ||
errorOnFail === true ? writeInvalidDateMessage(source) : errorOnFail | ||
) : void 0; | ||
}; | ||
// parser/string/shift/scanner.ts | ||
import { isKeyOf } from "@arktype/util"; | ||
var Scanner = class _Scanner { | ||
chars; | ||
i; | ||
constructor(def) { | ||
this.chars = [...def]; | ||
this.i = 0; | ||
} | ||
/** Get lookahead and advance scanner by one */ | ||
shift() { | ||
return this.chars[this.i++] ?? ""; | ||
} | ||
get lookahead() { | ||
return this.chars[this.i] ?? ""; | ||
} | ||
get length() { | ||
return this.chars.length; | ||
} | ||
shiftUntil(condition) { | ||
let shifted = ""; | ||
while (this.lookahead) { | ||
if (condition(this, shifted)) { | ||
if (shifted[shifted.length - 1] === _Scanner.escapeToken) { | ||
shifted = shifted.slice(0, -1); | ||
} else { | ||
break; | ||
} | ||
} | ||
shifted += this.shift(); | ||
} | ||
return shifted; | ||
} | ||
shiftUntilNextTerminator() { | ||
this.shiftUntilNonWhitespace(); | ||
return this.shiftUntil(_Scanner.lookaheadIsTerminator); | ||
} | ||
shiftUntilNonWhitespace() { | ||
return this.shiftUntil(_Scanner.lookaheadIsNotWhitespace); | ||
} | ||
jumpToIndex(i) { | ||
this.i = i < 0 ? this.length + i : i; | ||
} | ||
get location() { | ||
return this.i; | ||
} | ||
get unscanned() { | ||
return this.chars.slice(this.i, this.length).join(""); | ||
} | ||
get scanned() { | ||
return this.chars.slice(0, this.i).join(""); | ||
} | ||
sliceChars(start, end) { | ||
return this.chars.slice(start, end).join(""); | ||
} | ||
lookaheadIs(char) { | ||
return this.lookahead === char; | ||
} | ||
lookaheadIsIn(tokens) { | ||
return this.lookahead in tokens; | ||
} | ||
}; | ||
((Scanner2) => { | ||
Scanner2.lookaheadIsTerminator = (scanner) => scanner.lookahead in Scanner2.terminatingChars; | ||
Scanner2.lookaheadIsNotWhitespace = (scanner) => !(scanner.lookahead in Scanner2.whiteSpaceTokens); | ||
Scanner2.terminatingChars = { | ||
"<": true, | ||
">": true, | ||
"=": true, | ||
"|": true, | ||
"&": true, | ||
")": true, | ||
"[": true, | ||
"%": true, | ||
" ": true, | ||
",": true | ||
}; | ||
Scanner2.finalizingLookaheads = { | ||
">": true, | ||
",": true, | ||
"": true | ||
}; | ||
Scanner2.escapeToken = "\\"; | ||
Scanner2.whiteSpaceTokens = { | ||
" ": true, | ||
"\n": true | ||
}; | ||
Scanner2.lookaheadIsFinalizing = (lookahead, unscanned) => lookahead === ">" ? unscanned[0] === "=" ? ( | ||
// >== would only occur in an expression like Array<number>==5 | ||
// otherwise, >= would only occur as part of a bound like number>=5 | ||
unscanned[1] === "=" | ||
) : ( | ||
// if > is the end of a generic instantiation, the next token will be an operator or the end of the string | ||
unscanned.trimStart() === "" || isKeyOf(unscanned.trimStart()[0], Scanner2.terminatingChars) | ||
) : ( | ||
// if the lookahead is a finalizing token but not >, it's unambiguously a finalizer (currently just ",") | ||
lookahead === "," | ||
); | ||
})(Scanner || (Scanner = {})); | ||
// parser/string/shift/operand/enclosed.ts | ||
import { node } from "@arktype/schema"; | ||
import { isKeyOf as isKeyOf2 } from "@arktype/util"; | ||
var parseEnclosed = (s, enclosing) => { | ||
const enclosed = s.scanner.shiftUntil( | ||
untilLookaheadIsClosing[enclosingTokens[enclosing]] | ||
); | ||
if (s.scanner.lookahead === "") { | ||
return s.error(writeUnterminatedEnclosedMessage(enclosed, enclosing)); | ||
} | ||
const token = `${enclosing}${enclosed}${s.scanner.shift()}`; | ||
if (enclosing === "/") { | ||
new RegExp(enclosed); | ||
s.root = node({ basis: "string", pattern: token }); | ||
} else if (isKeyOf2(enclosing, enclosingQuote)) { | ||
s.root = node({ is: enclosed }); | ||
} else { | ||
const date2 = tryParseDate(enclosed, writeInvalidDateMessage(enclosed)); | ||
s.root = node({ is: date2, description: token }); | ||
} | ||
}; | ||
var enclosingQuote = { | ||
"'": 1, | ||
'"': 1 | ||
}; | ||
var enclosingChar = { | ||
"/": 1, | ||
...enclosingQuote | ||
}; | ||
var enclosingTokens = { | ||
"d'": "'", | ||
'd"': '"', | ||
"'": "'", | ||
'"': '"', | ||
"/": "/" | ||
}; | ||
var untilLookaheadIsClosing = { | ||
"'": (scanner) => scanner.lookahead === `'`, | ||
'"': (scanner) => scanner.lookahead === `"`, | ||
"/": (scanner) => scanner.lookahead === `/` | ||
}; | ||
var enclosingCharDescriptions = { | ||
'"': "double-quote", | ||
"'": "single-quote", | ||
"/": "forward slash" | ||
}; | ||
var writeUnterminatedEnclosedMessage = (fragment, enclosingStart) => `${enclosingStart}${fragment} requires a closing ${enclosingCharDescriptions[enclosingTokens[enclosingStart]]}`; | ||
// parser/string/shift/operand/unenclosed.ts | ||
import { isNode, node as node2 } from "@arktype/schema"; | ||
import { | ||
stringify, | ||
throwParseError as throwParseError2, | ||
tryParseNumber as tryParseNumber2, | ||
tryParseWellFormedBigint | ||
} from "@arktype/util"; | ||
var parseUnenclosed = (s) => { | ||
const token = s.scanner.shiftUntilNextTerminator(); | ||
if (token === "keyof") { | ||
s.addPrefix("keyof"); | ||
} else { | ||
s.root = unenclosedToNode(s, token); | ||
} | ||
}; | ||
var parseGenericInstantiation = (name, g, s) => { | ||
s.scanner.shiftUntilNonWhitespace(); | ||
const lookahead = s.scanner.shift(); | ||
if (lookahead !== "<") { | ||
return s.error(writeInvalidGenericArgsMessage(name, g.parameters, [])); | ||
} | ||
const parsedArgs = parseGenericArgs( | ||
name, | ||
g.parameters, | ||
s.scanner.unscanned, | ||
s.ctx | ||
); | ||
const remainingChars = parsedArgs.unscanned.length; | ||
s.scanner.jumpToIndex( | ||
remainingChars === 0 ? s.scanner.length : -remainingChars | ||
); | ||
return g(...parsedArgs.result).root; | ||
}; | ||
var unenclosedToNode = (s, token) => maybeParseReference(s, token) ?? maybeParseUnenclosedLiteral(s, token) ?? s.error( | ||
token === "" ? writeMissingOperandMessage(s) : writeUnresolvableMessage(token) | ||
); | ||
var maybeParseReference = (s, token) => { | ||
if (s.ctx.args?.[token]) { | ||
return s.ctx.args[token]; | ||
} | ||
const resolution = s.ctx.scope.maybeResolve(token); | ||
if (isNode(resolution)) { | ||
return resolution; | ||
} | ||
if (resolution === void 0) { | ||
return; | ||
} | ||
if (hasArkKind(resolution, "generic")) { | ||
return parseGenericInstantiation(token, resolution, s); | ||
} | ||
return throwParseError2(`Unexpected resolution ${stringify(resolution)}`); | ||
}; | ||
var maybeParseUnenclosedLiteral = (s, token) => { | ||
const maybeNumber = tryParseNumber2(token, { strict: true }); | ||
if (maybeNumber !== void 0) { | ||
return node2({ is: maybeNumber }); | ||
} | ||
const maybeBigint = tryParseWellFormedBigint(token); | ||
if (maybeBigint !== void 0) { | ||
return node2({ is: maybeBigint }); | ||
} | ||
}; | ||
var writeNonSubmoduleDotMessage = (name) => `'${name}' must reference a scope to be accessed using dot syntax`; | ||
var writeMissingSubmoduleAccessMessage = (name) => `Reference to submodule '${name}' must specify an alias`; | ||
var writeUnresolvableMessage = (token) => `'${token}' is unresolvable`; | ||
var writeMissingOperandMessage = (s) => { | ||
const operator = s.previousOperator(); | ||
return operator ? writeMissingRightOperandMessage(operator, s.scanner.unscanned) : writeExpressionExpectedMessage(s.scanner.unscanned); | ||
}; | ||
var writeMissingRightOperandMessage = (token, unscanned = "") => `Token '${token}' requires a right operand${unscanned ? ` before '${unscanned}'` : ""}`; | ||
var writeExpressionExpectedMessage = (unscanned) => `Expected an expression${unscanned ? ` before '${unscanned}'` : ""}`; | ||
// parser/string/shift/operand/operand.ts | ||
var parseOperand = (s) => s.scanner.lookahead === "" ? s.error(writeMissingOperandMessage(s)) : s.scanner.lookahead === "(" ? s.shiftedByOne().reduceGroupOpen() : s.scanner.lookaheadIsIn(enclosingChar) ? parseEnclosed(s, s.scanner.shift()) : s.scanner.lookaheadIsIn(Scanner.whiteSpaceTokens) ? parseOperand(s.shiftedByOne()) : s.scanner.lookahead === "d" ? s.shiftedByOne().scanner.lookaheadIsIn(enclosingChar) ? parseEnclosed(s, `d${s.scanner.shift()}`) : parseUnenclosed(s) : parseUnenclosed(s); | ||
// parser/string/shift/operator/bounds.ts | ||
var parseBound = (s, start) => { | ||
const comparator = shiftComparator(s, start); | ||
if (s.root.kind === "unit") { | ||
if (typeof s.root.is === "number") { | ||
s.unsetRoot(); | ||
return s.reduceLeftBound(s.root.is, comparator); | ||
} | ||
if (s.root.is instanceof Date) { | ||
s.unsetRoot(); | ||
const literal = `d'${s.root.description ?? s.root.is.toISOString()}'`; | ||
return s.reduceLeftBound(literal, comparator); | ||
} | ||
} | ||
return parseRightBound(s, comparator); | ||
}; | ||
var minComparators = { | ||
">": true, | ||
">=": true | ||
}; | ||
var maxComparators = { | ||
"<": true, | ||
"<=": true | ||
}; | ||
var comparators = { | ||
...minComparators, | ||
...maxComparators, | ||
"==": true | ||
}; | ||
var oneCharComparators = { | ||
"<": true, | ||
">": true | ||
}; | ||
var comparatorStartChars = { | ||
"<": 1, | ||
">": 1, | ||
"=": 1 | ||
}; | ||
var shiftComparator = (s, start) => s.scanner.lookaheadIs("=") ? `${start}${s.scanner.shift()}` : isKeyOf3(start, oneCharComparators) ? start : s.error(singleEqualsMessage); | ||
var singleEqualsMessage = `= is not a valid comparator. Use == to check for equality`; | ||
var openLeftBoundToSchema = (leftBound) => ({ | ||
min: isDateLiteral(leftBound.limit) ? extractDateLiteralSource(leftBound.limit) : leftBound.limit, | ||
exclusive: leftBound.comparator.length === 1 | ||
}); | ||
var parseRightBound = (s, comparator) => { | ||
const previousRoot = s.unsetRoot(); | ||
const previousScannerIndex = s.scanner.location; | ||
parseOperand(s); | ||
const limitToken = s.scanner.sliceChars( | ||
previousScannerIndex, | ||
s.scanner.location | ||
); | ||
s.setRoot(previousRoot); | ||
const limit = tryParseNumber3(limitToken) ?? (isDateLiteral(limitToken) ? extractDateLiteralSource(limitToken) : s.error(writeInvalidLimitMessage(comparator, limitToken, "right"))); | ||
const exclusive = comparator.length === 1; | ||
if (comparator[0] !== ">") { | ||
s.constrainRoot("max", { max: limit, exclusive }); | ||
} | ||
if (comparator[0] !== "<") { | ||
s.constrainRoot("min", { min: limit, exclusive }); | ||
} | ||
if (!s.branches.leftBound) { | ||
return; | ||
} | ||
if (!isKeyOf3(comparator, maxComparators)) { | ||
return s.error(writeUnpairableComparatorMessage(comparator)); | ||
} | ||
s.constrainRoot("min", openLeftBoundToSchema(s.branches.leftBound)); | ||
delete s.branches.leftBound; | ||
}; | ||
var writeInvalidLimitMessage = (comparator, limit, boundKind) => `Comparator ${comparator} must be ${boundKind === "left" ? "preceded" : "followed"} by a corresponding literal (was '${limit}')`; | ||
var invertedComparators = { | ||
"<": ">", | ||
">": "<", | ||
"<=": ">=", | ||
">=": "<=", | ||
"==": "==" | ||
}; | ||
// parser/string/reduce/dynamic.ts | ||
var DynamicState = class { | ||
constructor(def, ctx) { | ||
this.ctx = ctx; | ||
this.scanner = new Scanner(def); | ||
} | ||
scanner; | ||
root; | ||
branches = { | ||
prefixes: [] | ||
}; | ||
finalizer; | ||
groups = []; | ||
error(message) { | ||
return throwParseError3(message); | ||
} | ||
hasRoot() { | ||
return this.root !== void 0; | ||
} | ||
unsetRoot() { | ||
const value = this.root; | ||
this.root = void 0; | ||
return value; | ||
} | ||
constrainRoot(...args) { | ||
this.root = this.root.constrain(...args); | ||
} | ||
setRoot(root) { | ||
this.root = root; | ||
} | ||
finalize(finalizer) { | ||
if (this.groups.length) { | ||
return this.error(writeUnclosedGroupMessage(")")); | ||
} | ||
this.finalizeBranches(); | ||
this.finalizer = finalizer; | ||
} | ||
reduceLeftBound(limit, comparator) { | ||
const invertedComparator = invertedComparators[comparator]; | ||
if (!isKeyOf4(invertedComparator, minComparators)) { | ||
return this.error(writeUnpairableComparatorMessage(comparator)); | ||
} | ||
if (this.branches.leftBound) { | ||
return this.error( | ||
writeMultipleLeftBoundsMessage( | ||
this.branches.leftBound.limit, | ||
this.branches.leftBound.comparator, | ||
limit, | ||
invertedComparator | ||
) | ||
); | ||
} | ||
this.branches.leftBound = { | ||
comparator: invertedComparator, | ||
limit | ||
}; | ||
} | ||
finalizeBranches() { | ||
this.assertRangeUnset(); | ||
if (this.branches["|"]) { | ||
this.pushRootToBranch("|"); | ||
this.root = this.branches["|"]; | ||
} else if (this.branches["&"]) { | ||
this.pushRootToBranch("&"); | ||
this.root = this.branches["&"]; | ||
} else { | ||
this.applyPrefixes(); | ||
} | ||
} | ||
finalizeGroup() { | ||
this.finalizeBranches(); | ||
const topBranchState = this.groups.pop(); | ||
if (!topBranchState) { | ||
return this.error(writeUnmatchedGroupCloseMessage(this.scanner.unscanned)); | ||
} | ||
this.branches = topBranchState; | ||
} | ||
addPrefix(prefix) { | ||
this.branches.prefixes.push(prefix); | ||
} | ||
applyPrefixes() { | ||
while (this.branches.prefixes.length) { | ||
const lastPrefix = this.branches.prefixes.pop(); | ||
this.root = lastPrefix === "keyof" ? this.root.keyof() : throwInternalError(`Unexpected prefix '${lastPrefix}'`); | ||
} | ||
} | ||
pushRootToBranch(token) { | ||
this.assertRangeUnset(); | ||
this.applyPrefixes(); | ||
const root = this.root; | ||
this.branches["&"] = this.branches["&"]?.and(root) ?? root; | ||
if (token === "|") { | ||
this.branches["|"] = this.branches["|"]?.or(this.branches["&"]) ?? this.branches["&"]; | ||
delete this.branches["&"]; | ||
} | ||
this.root = void 0; | ||
} | ||
assertRangeUnset() { | ||
if (this.branches.leftBound) { | ||
return this.error( | ||
writeOpenRangeMessage( | ||
this.branches.leftBound.limit, | ||
this.branches.leftBound.comparator | ||
) | ||
); | ||
} | ||
} | ||
reduceGroupOpen() { | ||
this.groups.push(this.branches); | ||
this.branches = { | ||
prefixes: [] | ||
}; | ||
} | ||
previousOperator() { | ||
return this.branches.leftBound?.comparator ?? this.branches.prefixes.at(-1) ?? (this.branches["&"] ? "&" : this.branches["|"] ? "|" : void 0); | ||
} | ||
shiftedByOne() { | ||
this.scanner.shift(); | ||
return this; | ||
} | ||
}; | ||
// parser/string/shift/operator/operator.ts | ||
import { isKeyOf as isKeyOf5 } from "@arktype/util"; | ||
// parser/string/shift/operator/divisor.ts | ||
import { tryParseInteger } from "@arktype/util"; | ||
var parseDivisor = (s) => { | ||
const divisorToken = s.scanner.shiftUntilNextTerminator(); | ||
const divisor = tryParseInteger(divisorToken, { | ||
errorOnFail: writeInvalidDivisorMessage(divisorToken) | ||
}); | ||
if (divisor === 0) { | ||
s.error(writeInvalidDivisorMessage(0)); | ||
} | ||
s.root = s.root.constrain("divisor", divisor); | ||
}; | ||
var writeInvalidDivisorMessage = (divisor) => `% operator must be followed by a non-zero integer literal (was ${divisor})`; | ||
// parser/string/shift/operator/operator.ts | ||
var parseOperator = (s) => { | ||
const lookahead = s.scanner.shift(); | ||
return lookahead === "" ? s.finalize("") : lookahead === "[" ? s.scanner.shift() === "]" ? s.setRoot(s.root.array()) : s.error(incompleteArrayTokenMessage) : lookahead === "|" || lookahead === "&" ? s.pushRootToBranch(lookahead) : lookahead === ")" ? s.finalizeGroup() : Scanner.lookaheadIsFinalizing(lookahead, s.scanner.unscanned) ? s.finalize(lookahead) : isKeyOf5(lookahead, comparatorStartChars) ? parseBound(s, lookahead) : lookahead === "%" ? parseDivisor(s) : lookahead === " " ? parseOperator(s) : s.error(writeUnexpectedCharacterMessage(lookahead)); | ||
}; | ||
var writeUnexpectedCharacterMessage = (char, shouldBe = "") => `'${char}' is not allowed here${shouldBe && ` (should be ${shouldBe})`}`; | ||
var incompleteArrayTokenMessage = `Missing expected ']'`; | ||
// parser/string/string.ts | ||
import { throwParseError as throwParseError4 } from "@arktype/util"; | ||
// parser/semantic/validate.ts | ||
var writeUnsatisfiableExpressionError = (expression) => `${expression} results in an unsatisfiable type`; | ||
// parser/string/string.ts | ||
var parseString = (def, ctx) => ctx.scope.maybeResolveNode(def) ?? (def.endsWith("[]") && ctx.scope.maybeResolveNode(def.slice(0, -2))?.array() || fullStringParse(def, ctx)); | ||
var fullStringParse = (def, ctx) => { | ||
const s = new DynamicState(def, ctx); | ||
parseOperand(s); | ||
const result = parseUntilFinalizer(s).root; | ||
s.scanner.shiftUntilNonWhitespace(); | ||
if (s.scanner.lookahead) { | ||
throwParseError4(writeUnexpectedCharacterMessage(s.scanner.lookahead)); | ||
} | ||
return result.isNever() ? throwParseError4(writeUnsatisfiableExpressionError(def)) : result; | ||
}; | ||
var parseUntilFinalizer = (s) => { | ||
while (s.finalizer === void 0) { | ||
next(s); | ||
} | ||
return s; | ||
}; | ||
var next = (s) => s.hasRoot() ? parseOperator(s) : parseOperand(s); | ||
// parser/generic.ts | ||
var parseGenericParams = (def) => parseGenericParamsRecurse(new Scanner(def)); | ||
var emptyGenericParameterMessage = `An empty string is not a valid generic parameter name`; | ||
var parseGenericParamsRecurse = (scanner) => { | ||
const param = scanner.shiftUntilNextTerminator(); | ||
if (param === "") { | ||
throwParseError5(emptyGenericParameterMessage); | ||
} | ||
scanner.shiftUntilNonWhitespace(); | ||
const nextNonWhitespace = scanner.shift(); | ||
return nextNonWhitespace === "" ? [param] : nextNonWhitespace === "," ? [param, ...parseGenericParamsRecurse(scanner)] : throwParseError5(writeUnexpectedCharacterMessage(nextNonWhitespace, ",")); | ||
}; | ||
var parseGenericArgs = (name, params, unscanned, ctx) => parseGenericArgsRecurse(name, params, unscanned, ctx, [], []); | ||
var parseGenericArgsRecurse = (name, params, unscanned, ctx, argDefs, argNodes) => { | ||
const s = parseUntilFinalizer(new DynamicState(unscanned, ctx)); | ||
argDefs.push(s.scanner.scanned.slice(0, -1)); | ||
argNodes.push(s.root); | ||
const nextUnscanned = s.scanner.unscanned; | ||
if (s.finalizer === ">") { | ||
if (argNodes.length === params.length) { | ||
return { | ||
result: argNodes, | ||
unscanned: nextUnscanned | ||
}; | ||
} else { | ||
return s.error(writeInvalidGenericArgsMessage(name, params, argDefs)); | ||
} | ||
} else if (s.finalizer === ",") { | ||
return parseGenericArgsRecurse( | ||
name, | ||
params, | ||
nextUnscanned, | ||
ctx, | ||
argDefs, | ||
argNodes | ||
); | ||
} | ||
return s.error(writeUnclosedGroupMessage(">")); | ||
}; | ||
var writeInvalidGenericArgsMessage = (name, params, argDefs) => `${name}<${params.join(", ")}> requires exactly ${params.length} args (got ${argDefs.length}${argDefs.length === 0 ? "" : ": " + argDefs.join(", ")})`; | ||
// type.ts | ||
var createTypeParser = (scope2) => { | ||
const parser = (...args) => { | ||
if (args.length === 1) { | ||
return new Type(args[0], scope2); | ||
} | ||
if (args.length === 2 && typeof args[0] === "string" && args[0][0] === "<" && args[0].at(-1) === ">") { | ||
const params = parseGenericParams(args[0].slice(1, -1)); | ||
const def = args[1]; | ||
return validateUninstantiatedGeneric(generic(params, def, scope2)); | ||
} | ||
return new Type(args, scope2); | ||
}; | ||
return parser; | ||
}; | ||
var addArkKind = (value, kind) => Object.defineProperty(value, arkKind, { | ||
value: kind, | ||
enumerable: false | ||
}); | ||
var hasArkKind = (value, kind) => value?.[arkKind] === kind; | ||
registry().register(TraversalState, "state"); | ||
var Type = class _Type extends CompiledFunction { | ||
constructor(definition, scope2) { | ||
const root = parseTypeRoot(definition, scope2); | ||
super(In, `return true ? { data: ${In} } : { problems: [] } `); | ||
this.definition = definition; | ||
this.scope = scope2; | ||
this.root = root; | ||
this.allows = root.allows; | ||
this.config = scope2.config; | ||
this.json = this.root.json; | ||
this.alias = this.root.alias; | ||
} | ||
config; | ||
root; | ||
condition = ""; | ||
alias; | ||
allows; | ||
json; | ||
configure(config) { | ||
this.config = { ...this.config, ...config }; | ||
return this; | ||
} | ||
// TODO: should return out | ||
from(literal) { | ||
return literal; | ||
} | ||
fromIn(literal) { | ||
return literal; | ||
} | ||
// TODO: Morph intersections, ordering | ||
and(def) { | ||
return new _Type( | ||
this.root.and(parseTypeRoot(def, this.scope)), | ||
this.scope | ||
); | ||
} | ||
or(def) { | ||
return new _Type( | ||
this.root.or(parseTypeRoot(def, this.scope)), | ||
this.scope | ||
); | ||
} | ||
morph(morph, outValidator) { | ||
outValidator; | ||
return this; | ||
} | ||
// TODO: based on below, should maybe narrow morph output if used after | ||
narrow(def) { | ||
return new _Type(this.root.constrain("predicate", def), this.scope); | ||
} | ||
array() { | ||
return new _Type(this.root.array(), this.scope); | ||
} | ||
keyof() { | ||
return new _Type(this.root.keyof(), this.scope); | ||
} | ||
assert(data) { | ||
const result = this.call(null, data); | ||
return result.problems ? result.problems.throw() : result.data; | ||
} | ||
// TODO: parse these | ||
equals(other) { | ||
return this.root === other.root; | ||
} | ||
extends(other) { | ||
return this.root.extends(other.root); | ||
} | ||
}; | ||
var parseTypeRoot = (def, scope2, args) => scope2.parseDefinition(def, { args: args ?? bindThis(), baseName: "type" }); | ||
var validateUninstantiatedGeneric = (g) => { | ||
g.scope.parseDefinition( | ||
g.definition, | ||
// once we support constraints on generic parameters, we'd use | ||
// the base type here: https://github.com/arktypeio/arktype/issues/796 | ||
{ | ||
baseName: "generic", | ||
args: transform(g.parameters, ([, name]) => [name, builtins.unknown]) | ||
} | ||
); | ||
return g; | ||
}; | ||
var generic = (parameters, definition, scope2) => { | ||
return Object.assign( | ||
(...args) => { | ||
const argNodes = transform(parameters, ([i, param]) => [ | ||
param, | ||
parseTypeRoot(args[i], scope2) | ||
]); | ||
const root = parseTypeRoot(definition, scope2, argNodes); | ||
return new Type(root, scope2); | ||
}, | ||
{ | ||
[arkKind]: "generic", | ||
parameters, | ||
definition, | ||
scope: scope2 | ||
// $ is only needed at compile-time | ||
} | ||
); | ||
}; | ||
// match.ts | ||
var createWhenParser = (scope2) => { | ||
const parser = (def) => new Type(def, scope2).alias; | ||
return parser; | ||
}; | ||
var createMatchParser = (scope2) => { | ||
const parser = (cases) => { | ||
const caseArray = Object.entries(cases).map(([def, morph]) => ({ | ||
when: new Type(def, scope2).allows, | ||
then: morph | ||
})); | ||
return (data) => { | ||
for (const c of caseArray) { | ||
if (c.when(data)) { | ||
return c.then(data, {}); | ||
} | ||
} | ||
}; | ||
}; | ||
return parser; | ||
}; | ||
// parser/definition.ts | ||
import { isNode as isNode2, node as node5 } from "@arktype/schema"; | ||
import { | ||
isThunk, | ||
objectKindOf, | ||
stringify as stringify4, | ||
throwParseError as throwParseError7 | ||
} from "@arktype/util"; | ||
// parser/objectLiteral.ts | ||
import { node as node3 } from "@arktype/schema"; | ||
import { | ||
stringify as stringify2 | ||
} from "@arktype/util"; | ||
// parser/shared.ts | ||
var getInnerValue = (value) => { | ||
if (typeof value === "string") { | ||
if (value[value.length - 1] === "?") { | ||
return { | ||
kind: "optional", | ||
innerValue: value.slice(0, -1) | ||
}; | ||
} | ||
} else if (Array.isArray(value)) { | ||
if (value.length === 2 && value[1] === "?") { | ||
return { | ||
kind: "optional", | ||
innerValue: getInnerValue(value[0]).innerValue | ||
}; | ||
} | ||
} | ||
return { | ||
kind: "required", | ||
innerValue: value | ||
}; | ||
}; | ||
var parseEntry = ([key, value]) => { | ||
const keyParseResult = typeof key === "string" && key.at(-1) === "?" ? key.at(-2) === Scanner.escapeToken ? { innerKey: `${key.slice(0, -2)}?`, kind: "required" } : { innerKey: key.slice(0, -1), kind: "optional" } : { innerKey: key, kind: "required" }; | ||
const valueParseResult = getInnerValue(value); | ||
return { | ||
innerKey: keyParseResult.innerKey, | ||
innerValue: valueParseResult.innerValue, | ||
kind: keyParseResult.kind === "indexed" ? "indexed" : valueParseResult.kind === "optional" ? "optional" : keyParseResult.kind | ||
}; | ||
}; | ||
// parser/objectLiteral.ts | ||
var stringAndSymbolicEntriesOf = (o) => [ | ||
...Object.entries(o), | ||
...Object.getOwnPropertySymbols(o).map((k) => [k, o[k]]) | ||
]; | ||
var parseObjectLiteral = (def, ctx) => { | ||
const required = []; | ||
const optional = []; | ||
for (const entry of stringAndSymbolicEntriesOf(def)) { | ||
const result = parseEntry(entry); | ||
ctx.path.push( | ||
`${typeof result.innerKey === "symbol" ? `[${stringify2(result.innerKey)}]` : result.innerKey}` | ||
); | ||
const valueNode = ctx.scope.parse(result.innerValue, ctx); | ||
if (result.kind === "optional") { | ||
optional.push({ | ||
key: result.innerKey, | ||
value: valueNode | ||
}); | ||
} else { | ||
required.push({ | ||
key: result.innerKey, | ||
value: valueNode | ||
}); | ||
} | ||
ctx.path.pop(); | ||
} | ||
return node3({ | ||
basis: "object", | ||
required, | ||
optional | ||
}); | ||
}; | ||
// parser/tuple.ts | ||
import { | ||
builtins as builtins2, | ||
node as node4 | ||
} from "@arktype/schema"; | ||
import { | ||
isArray, | ||
objectKindOrDomainOf, | ||
stringify as stringify3, | ||
throwParseError as throwParseError6 | ||
} from "@arktype/util"; | ||
var parseTuple = (def, ctx) => maybeParseTupleExpression(def, ctx) ?? parseTupleLiteral(def, ctx); | ||
var parseTupleLiteral = (def, ctx) => { | ||
const props = []; | ||
let isVariadic = false; | ||
for (let i = 0; i < def.length; i++) { | ||
let elementDef = def[i]; | ||
ctx.path.push(`${i}`); | ||
if (typeof elementDef === "string" && elementDef.startsWith("...")) { | ||
elementDef = elementDef.slice(3); | ||
isVariadic = true; | ||
} else if (isArray(elementDef) && elementDef.length === 2 && elementDef[0] === "...") { | ||
elementDef = elementDef[1]; | ||
isVariadic = true; | ||
} | ||
const parsedEntry = parseEntry([`${i}`, elementDef]); | ||
const value = ctx.scope.parse(parsedEntry.innerValue, ctx); | ||
if (isVariadic) { | ||
if (!value.extends(builtins2.array)) { | ||
return throwParseError6(writeNonArrayRestMessage(elementDef)); | ||
} | ||
if (i !== def.length - 1) { | ||
return throwParseError6(prematureRestMessage); | ||
} | ||
const elementType = value.getPath(); | ||
props.push({ key: builtins2.number, value: elementType }); | ||
} else { | ||
props.push({ | ||
key: { | ||
name: `${i}`, | ||
prerequisite: false, | ||
optional: parsedEntry.kind === "optional" | ||
}, | ||
value | ||
}); | ||
} | ||
ctx.path.pop(); | ||
} | ||
if (!isVariadic) { | ||
props.push({ | ||
key: { | ||
name: "length", | ||
prerequisite: true, | ||
optional: false | ||
}, | ||
// , ctx | ||
value: node4({ is: def.length }) | ||
}); | ||
} | ||
return node4(Array); | ||
}; | ||
var maybeParseTupleExpression = (def, ctx) => { | ||
const tupleExpressionResult = isIndexOneExpression(def) ? indexOneParsers[def[1]](def, ctx) : isIndexZeroExpression(def) ? prefixParsers[def[0]](def, ctx) : void 0; | ||
if (tupleExpressionResult) { | ||
return tupleExpressionResult.isNever() ? throwParseError6( | ||
writeUnsatisfiableExpressionError( | ||
def.map((def2) => typeof def2 === "string" ? def2 : stringify3(def2)).join(" ") | ||
) | ||
) : tupleExpressionResult; | ||
} | ||
}; | ||
var writeNonArrayRestMessage = (operand) => `Rest element ${typeof operand === "string" ? `'${operand}'` : ""} must be an array`; | ||
var prematureRestMessage = `Rest elements are only allowed at the end of a tuple`; | ||
var parseKeyOfTuple = (def, ctx) => ctx.scope.parse(def[1], ctx).keyof(); | ||
var parseBranchTuple = (def, ctx) => { | ||
if (def[2] === void 0) { | ||
return throwParseError6(writeMissingRightOperandMessage(def[1], "")); | ||
} | ||
const l = ctx.scope.parse(def[0], ctx); | ||
const r = ctx.scope.parse(def[2], ctx); | ||
return def[1] === "&" ? l.and(r) : l.or(r); | ||
}; | ||
var parseArrayTuple = (def, ctx) => ctx.scope.parse(def[0], ctx).array(); | ||
var isIndexOneExpression = (def) => indexOneParsers[def[1]] !== void 0; | ||
var parseMorphTuple = (def, ctx) => { | ||
if (typeof def[2] !== "function") { | ||
return throwParseError6( | ||
writeMalformedFunctionalExpressionMessage("=>", def[2]) | ||
); | ||
} | ||
return ctx.scope.parse(def[0], ctx); | ||
}; | ||
var writeMalformedFunctionalExpressionMessage = (operator, value) => `${operator === ":" ? "Narrow" : "Morph"} expression requires a function following '${operator}' (was ${typeof value})`; | ||
var parseNarrowTuple = (def, ctx) => { | ||
if (typeof def[2] !== "function") { | ||
return throwParseError6( | ||
writeMalformedFunctionalExpressionMessage(":", def[2]) | ||
); | ||
} | ||
return ctx.scope.parse(def[0], ctx).constrain("predicate", def[2]); | ||
}; | ||
var parseAttributeTuple = (def, ctx) => { | ||
return ctx.scope.parse(def[0], ctx); | ||
}; | ||
var indexOneParsers = { | ||
"|": parseBranchTuple, | ||
"&": parseBranchTuple, | ||
"[]": parseArrayTuple, | ||
":": parseNarrowTuple, | ||
"=>": parseMorphTuple, | ||
"@": parseAttributeTuple | ||
}; | ||
var prefixParsers = { | ||
keyof: parseKeyOfTuple, | ||
instanceof: (def, ctx) => { | ||
if (typeof def[1] !== "function") { | ||
return throwParseError6( | ||
writeInvalidConstructorMessage(objectKindOrDomainOf(def[1])) | ||
); | ||
} | ||
const branches = def.slice(1).map( | ||
(ctor) => typeof ctor === "function" ? { basis: ctor } : throwParseError6( | ||
writeInvalidConstructorMessage(objectKindOrDomainOf(ctor)) | ||
) | ||
); | ||
return node4(...branches); | ||
}, | ||
"===": (def) => node4({ is: def.slice(1) }) | ||
}; | ||
var isIndexZeroExpression = (def) => prefixParsers[def[0]] !== void 0; | ||
var writeInvalidConstructorMessage = (actual) => `Expected a constructor following 'instanceof' operator (was ${actual}).`; | ||
// parser/definition.ts | ||
var parseObject = (def, ctx) => { | ||
const objectKind = objectKindOf(def); | ||
switch (objectKind) { | ||
case void 0: | ||
if (isNode2(def)) { | ||
return def; | ||
} | ||
return parseObjectLiteral(def, ctx); | ||
case "Array": | ||
return parseTuple(def, ctx); | ||
case "RegExp": | ||
return node5({ basis: "string", pattern: def }); | ||
case "Function": | ||
const resolvedDef = isThunk(def) ? def() : def; | ||
if (resolvedDef instanceof Type) { | ||
return resolvedDef.root; | ||
} | ||
return throwParseError7(writeBadDefinitionTypeMessage("Function")); | ||
default: | ||
return throwParseError7( | ||
writeBadDefinitionTypeMessage(objectKind ?? stringify4(def)) | ||
); | ||
} | ||
}; | ||
var writeBadDefinitionTypeMessage = (actual) => `Type definitions must be strings or objects (was ${actual})`; | ||
// scope.ts | ||
var bindThis = () => ({ | ||
// TODO: fix | ||
this: builtins3.unknown | ||
}); | ||
var Scope = class _Scope { | ||
config; | ||
parseCache = {}; | ||
resolutions; | ||
/** The set of names defined at the root-level of the scope mapped to their | ||
* corresponding definitions.**/ | ||
aliases = {}; | ||
exportedNames = []; | ||
ambient; | ||
references = []; | ||
constructor(def, config) { | ||
for (const k in def) { | ||
const parsedKey = parseScopeKey(k); | ||
this.aliases[parsedKey.name] = parsedKey.params.length ? generic(parsedKey.params, def[k], this) : def[k]; | ||
if (!parsedKey.isLocal) { | ||
this.exportedNames.push(parsedKey.name); | ||
} | ||
} | ||
this.ambient = config.ambient ?? null; | ||
if (this.ambient) { | ||
this.ambient.export(); | ||
this.resolutions = { ...this.ambient.exportedResolutions }; | ||
} else { | ||
this.resolutions = {}; | ||
} | ||
this.config = config; | ||
} | ||
static root = (aliases) => { | ||
return new _Scope(aliases, {}); | ||
}; | ||
type = createTypeParser(this); | ||
match = createMatchParser(this); | ||
when = createWhenParser(this); | ||
// TODO: decide if this API will be used for non-validated types | ||
declare = () => ({ type: this.type }); | ||
scope = (def, config = {}) => { | ||
return new _Scope(def, { | ||
ambient: this.ambient, | ||
...this.config, | ||
...config | ||
}); | ||
}; | ||
define = (def) => def; | ||
toAmbient() { | ||
return new _Scope(this.aliases, { | ||
ambient: this, | ||
...this.config | ||
}); | ||
} | ||
// TODO: name? | ||
get(name) { | ||
return this.export()[name]; | ||
} | ||
createRootContext(input) { | ||
return { | ||
path: [], | ||
scope: this, | ||
...input | ||
}; | ||
} | ||
parseDefinition(def, input) { | ||
return this.parse(def, this.createRootContext(input)); | ||
} | ||
parse(def, ctx) { | ||
if (typeof def === "string") { | ||
if (ctx.args !== void 0) { | ||
return parseString(def, ctx); | ||
} | ||
if (!this.parseCache[def]) { | ||
this.parseCache[def] = parseString(def, ctx); | ||
} | ||
return this.parseCache[def]; | ||
} | ||
return hasDomain(def, "object") ? parseObject(def, ctx) : throwParseError8(writeBadDefinitionTypeMessage(domainOf(def))); | ||
} | ||
maybeResolve(name) { | ||
const cached = this.resolutions[name]; | ||
if (cached) { | ||
return cached; | ||
} | ||
let def = this.aliases[name]; | ||
if (!def) { | ||
return this.maybeResolveSubalias(name); | ||
} | ||
if (isThunk2(def) && !hasArkKind(def, "generic")) { | ||
def = def(); | ||
} | ||
const resolution = hasArkKind(def, "generic") ? validateUninstantiatedGeneric(def) : hasArkKind(def, "module") ? throwParseError8(writeMissingSubmoduleAccessMessage(name)) : this.parseDefinition( | ||
def, | ||
this.createRootContext({ baseName: name, args: {} }) | ||
); | ||
this.resolutions[name] = resolution; | ||
return resolution; | ||
} | ||
/** If name is a valid reference to a submodule alias, return its resolution */ | ||
maybeResolveSubalias(name) { | ||
const dotIndex = name.indexOf("."); | ||
if (dotIndex === -1) { | ||
return; | ||
} | ||
const dotPrefix = name.slice(0, dotIndex); | ||
const prefixDef = this.aliases[dotPrefix]; | ||
if (hasArkKind(prefixDef, "module")) { | ||
const resolution = prefixDef[name.slice(dotIndex + 1)]?.root; | ||
if (!resolution) { | ||
return throwParseError8(writeUnresolvableMessage(name)); | ||
} | ||
this.resolutions[name] = resolution; | ||
return resolution; | ||
} | ||
if (prefixDef !== void 0) { | ||
return throwParseError8(writeNonSubmoduleDotMessage(dotPrefix)); | ||
} | ||
} | ||
maybeResolveNode(name) { | ||
const result = this.maybeResolve(name); | ||
return hasArkKind(result, "node") ? result : void 0; | ||
} | ||
import(...names) { | ||
return addArkKind( | ||
transform2(this.export(...names), ([alias, value]) => [ | ||
`#${alias}`, | ||
value | ||
]), | ||
"module" | ||
); | ||
} | ||
compile() { | ||
return ""; | ||
} | ||
exportedResolutions; | ||
exportCache; | ||
export(...names) { | ||
if (!this.exportCache) { | ||
this.exportCache = {}; | ||
for (const name of this.exportedNames) { | ||
let def = this.aliases[name]; | ||
if (hasArkKind(def, "generic")) { | ||
this.exportCache[name] = def; | ||
continue; | ||
} | ||
if (isThunk2(def)) { | ||
def = def(); | ||
} | ||
if (hasArkKind(def, "module")) { | ||
this.exportCache[name] = def; | ||
} else { | ||
this.exportCache[name] = new Type(this.maybeResolve(name), this); | ||
} | ||
} | ||
this.exportedResolutions = resolutionsOfModule(this.exportCache); | ||
Object.assign(this.resolutions, this.exportedResolutions); | ||
} | ||
const namesToExport = names.length ? names : this.exportedNames; | ||
return addArkKind( | ||
transform2(namesToExport, ([, name]) => [ | ||
name, | ||
this.exportCache[name] | ||
]), | ||
"module" | ||
); | ||
} | ||
}; | ||
var resolutionsOfModule = (typeSet) => { | ||
const result = {}; | ||
for (const k in typeSet) { | ||
const v = typeSet[k]; | ||
if (hasArkKind(v, "module")) { | ||
const innerResolutions = resolutionsOfModule(v); | ||
const prefixedResolutions = transform2( | ||
innerResolutions, | ||
([innerK, innerV]) => [`${k}.${innerK}`, innerV] | ||
); | ||
Object.assign(result, prefixedResolutions); | ||
} else if (hasArkKind(v, "generic")) { | ||
result[k] = v; | ||
} else { | ||
result[k] = v.root; | ||
} | ||
} | ||
return result; | ||
}; | ||
var parseScopeKey = (k) => { | ||
const isLocal = k[0] === "#"; | ||
const name = isLocal ? k.slice(1) : k; | ||
const firstParamIndex = k.indexOf("<"); | ||
if (firstParamIndex === -1) { | ||
return { | ||
isLocal, | ||
name, | ||
params: [] | ||
}; | ||
} | ||
if (k.at(-1) !== ">") { | ||
throwParseError8( | ||
`'>' must be the last character of a generic declaration in a scope` | ||
); | ||
} | ||
return { | ||
isLocal, | ||
name: name.slice(0, firstParamIndex), | ||
params: parseGenericParams(k.slice(firstParamIndex + 1, -1)) | ||
}; | ||
}; | ||
// scopes/jsObjects.ts | ||
import { node as node6 } from "@arktype/schema"; | ||
var jsObjects = Scope.root({ | ||
Function: node6(Function), | ||
Date: node6(Date), | ||
Error: node6(Error), | ||
Map: node6(Map), | ||
RegExp: node6(RegExp), | ||
Set: node6(Set), | ||
WeakMap: node6(WeakMap), | ||
WeakSet: node6(WeakSet), | ||
Promise: node6(Promise) | ||
}); | ||
var jsObjectsModule = jsObjects.export(); | ||
// scopes/parsing.ts | ||
import { node as node8 } from "@arktype/schema"; | ||
import { | ||
wellFormedIntegerMatcher, | ||
wellFormedNumberMatcher | ||
} from "@arktype/util"; | ||
// scopes/utils/date.ts | ||
import { node as node7 } from "@arktype/schema"; | ||
import { throwInternalError as throwInternalError2 } from "@arktype/util"; | ||
var dayDelimiterMatcher = /^[./-]$/; | ||
var iso8601Matcher = /^([+-]?\d{4}(?!\d{2}\b))((-?)((0[1-9]|1[0-2])(\3([12]\d|0[1-9]|3[01]))?|W([0-4]\d|5[0-3])(-?[1-7])?|(00[1-9]|0[1-9]\d|[12]\d{2}|3([0-5]\d|6[1-6])))([T]((([01]\d|2[0-3])((:?)[0-5]\d)?|24:?00)([.,]\d+(?!:))?)?(\17[0-5]\d([.,]\d+)?)?([zZ]|([+-])([01]\d|2[0-3]):?([0-5]\d)?)?)?)?$/; | ||
var isValidDateInstance = (date2) => !isNaN(date2); | ||
var writeFormattedMustBe = (format) => `a ${format}-formatted date`; | ||
var tryParseDatePattern = (data, opts) => { | ||
if (!opts?.format) { | ||
const result = new Date(data); | ||
return isValidDateInstance(result) ? result : "a valid date"; | ||
} | ||
if (opts.format === "iso8601") { | ||
return iso8601Matcher.test(data) ? new Date(data) : writeFormattedMustBe("iso8601"); | ||
} | ||
const dataParts = data.split(dayDelimiterMatcher); | ||
const delimiter = data[dataParts[0].length]; | ||
const formatParts = delimiter ? opts.format.split(delimiter) : [opts.format]; | ||
if (dataParts.length !== formatParts.length) { | ||
return writeFormattedMustBe(opts.format); | ||
} | ||
const parsedParts = {}; | ||
for (let i = 0; i < formatParts.length; i++) { | ||
if (dataParts[i].length !== formatParts[i].length && // if format is "m" or "d", data is allowed to be 1 or 2 characters | ||
!(formatParts[i].length === 1 && dataParts[i].length === 2)) { | ||
return writeFormattedMustBe(opts.format); | ||
} | ||
parsedParts[formatParts[i][0]] = dataParts[i]; | ||
} | ||
const date2 = /* @__PURE__ */ new Date(`${parsedParts.m}/${parsedParts.d}/${parsedParts.y}`); | ||
if (`${date2.getDate()}` === parsedParts.d) { | ||
return date2; | ||
} | ||
return writeFormattedMustBe(opts.format); | ||
}; | ||
var parsedDate = node7({ | ||
in: "string", | ||
morph: (s) => { | ||
const result = tryParseDatePattern(s); | ||
return typeof result === "string" ? ( | ||
// TODO: Fix | ||
throwInternalError2("Unsupported") | ||
) : ( | ||
//state.mustBe(result, s, state.basePath) | ||
result | ||
); | ||
} | ||
}); | ||
// scopes/parsing.ts | ||
var number = node8({ | ||
in: { | ||
basis: "string", | ||
pattern: wellFormedNumberMatcher, | ||
description: "a well-formed numeric string" | ||
}, | ||
morph: (s) => parseFloat(s) | ||
}); | ||
var integer = node8({ | ||
in: { | ||
basis: "string", | ||
pattern: wellFormedIntegerMatcher | ||
}, | ||
morph: (s) => { | ||
return parseInt(s); | ||
} | ||
}); | ||
var url = node8({ | ||
in: { | ||
basis: "string", | ||
description: "a valid URL" | ||
}, | ||
morph: (s) => { | ||
return new URL(s); | ||
} | ||
}); | ||
var json = node8({ | ||
in: { | ||
basis: "string", | ||
description: "a JSON-parsable string" | ||
}, | ||
morph: (s) => JSON.parse(s) | ||
}); | ||
var date = parsedDate; | ||
var parsing = Scope.root({ | ||
url, | ||
number, | ||
integer, | ||
date, | ||
json | ||
}); | ||
var parsingModule = parsing.export(); | ||
// scopes/tsGenerics.ts | ||
var tsGenerics = Scope.root({ | ||
// "Record<K, V>": { | ||
// // Remove this once we support constraints on generic parameters: | ||
// // https://github.com/arktypeio/arktype/issues/796 | ||
// /** @ts-expect-error */ | ||
// "[K]": "V" | ||
// } | ||
// unfortunately TS won't let us assign this directly, so we need to be | ||
// careful to keep the inferred types in sync | ||
}); | ||
var tsGenericsModule = tsGenerics.export(); | ||
// scopes/tsKeywords.ts | ||
import { node as node9 } from "@arktype/schema"; | ||
var tsKeywords = Scope.root({ | ||
any: "unknown", | ||
bigint: node9("bigint"), | ||
boolean: "true|false", | ||
false: node9.units(false), | ||
never: node9(), | ||
null: node9.units(null), | ||
number: node9("number"), | ||
object: node9("object"), | ||
string: node9("string"), | ||
symbol: node9("symbol"), | ||
true: node9.units(true), | ||
unknown: node9({}), | ||
void: "undefined", | ||
undefined: node9.units(void 0) | ||
}); | ||
var tsKeywordsModule = tsKeywords.export(); | ||
// scopes/validation.ts | ||
import { node as node11 } from "@arktype/schema"; | ||
// scopes/utils/creditCard.ts | ||
import { node as node10 } from "@arktype/schema"; | ||
var isLuhnValid = (creditCardInput) => { | ||
const sanitized = creditCardInput.replace(/[- ]+/g, ""); | ||
let sum = 0; | ||
let digit; | ||
let tmpNum; | ||
let shouldDouble; | ||
for (let i = sanitized.length - 1; i >= 0; i--) { | ||
digit = sanitized.substring(i, i + 1); | ||
tmpNum = parseInt(digit, 10); | ||
if (shouldDouble) { | ||
tmpNum *= 2; | ||
if (tmpNum >= 10) { | ||
sum += tmpNum % 10 + 1; | ||
} else { | ||
sum += tmpNum; | ||
} | ||
} else { | ||
sum += tmpNum; | ||
} | ||
shouldDouble = !shouldDouble; | ||
} | ||
return !!(sum % 10 === 0 ? sanitized : false); | ||
}; | ||
var creditCardMatcher = /^(?:4[0-9]{12}(?:[0-9]{3,6})?|5[1-5][0-9]{14}|(222[1-9]|22[3-9][0-9]|2[3-6][0-9]{2}|27[01][0-9]|2720)[0-9]{12}|6(?:011|5[0-9][0-9])[0-9]{12,15}|3[47][0-9]{13}|3(?:0[0-5]|[68][0-9])[0-9]{11}|(?:2131|1800|35\d{3})\d{11}|6[27][0-9]{14}|^(81[0-9]{14,17}))$/; | ||
var creditCard = node10({ | ||
basis: "string", | ||
pattern: creditCardMatcher, | ||
predicate: isLuhnValid, | ||
description: "a valid credit card number" | ||
}); | ||
// scopes/validation.ts | ||
var url2 = node11({ | ||
basis: "string", | ||
predicate: (s) => { | ||
try { | ||
new URL(s); | ||
} catch { | ||
return false; | ||
} | ||
return true; | ||
}, | ||
description: "a valid URL" | ||
}); | ||
var emailMatcher = /^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$/; | ||
var email = node11({ | ||
basis: "string", | ||
pattern: emailMatcher, | ||
description: "a valid email" | ||
}); | ||
var uuidMatcher = /^[0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{12}$/; | ||
var uuid = node11({ | ||
basis: "string", | ||
pattern: uuidMatcher, | ||
description: "a valid UUID" | ||
}); | ||
var semverMatcher = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$/; | ||
var semver = node11({ | ||
basis: "string", | ||
pattern: semverMatcher, | ||
description: "a valid semantic version (see https://semver.org/)" | ||
}); | ||
var validation = Scope.root({ | ||
// Character sets | ||
alpha: [/^[A-Za-z]*$/, "@", "only letters"], | ||
alphanumeric: [/^[A-Za-z\d]*$/, "@", "only letters and digits"], | ||
lowercase: [/^[a-z]*$/, "@", "only lowercase letters"], | ||
uppercase: [/^[A-Z]*$/, "@", "only uppercase letters"], | ||
creditCard, | ||
email, | ||
uuid, | ||
url: url2, | ||
semver, | ||
integer: node11({ | ||
basis: "number", | ||
divisor: 1, | ||
description: "an integer" | ||
}) | ||
}); | ||
var validationModule = validation.export(); | ||
// scopes/ark.ts | ||
var ark = Scope.root({ | ||
...tsKeywordsModule, | ||
...jsObjectsModule, | ||
...validationModule, | ||
parse: parsingModule, | ||
// again, unfortunately TS won't handle comparing generics well here, so we | ||
// have to cast. that said, since each individual root scope is checked, | ||
// this is low risk | ||
...tsGenericsModule | ||
}).toAmbient(); | ||
var arktypes = ark.export(); | ||
var scope = ark.scope; | ||
var type = ark.type; | ||
var match = ark.match; | ||
var when = ark.when; | ||
var define = ark.define; | ||
var declare = ark.declare; | ||
export { | ||
Problem, | ||
Problems, | ||
Type, | ||
ark, | ||
arktypes, | ||
declare, | ||
define, | ||
jsObjects, | ||
match, | ||
scope, | ||
tsGenerics, | ||
tsKeywords, | ||
type, | ||
validation, | ||
when | ||
}; | ||
export { Problem, Problems } from "@arktype/schema"; | ||
export { ark, arktypes, declare, define, match, scope, type, when } from "./scopes/ark.js"; | ||
export { jsObjects } from "./scopes/jsObjects.js"; | ||
export { tsGenerics } from "./scopes/tsGenerics.js"; | ||
export { tsKeywords } from "./scopes/tsKeywords.js"; | ||
export { validation } from "./scopes/validation.js"; | ||
export { Type } from "./type.js"; | ||
//# sourceMappingURL=main.js.map |
{ | ||
"name": "arktype", | ||
"description": "TypeScript's 1:1 validator, optimized from editor to runtime", | ||
"version": "1.1.0-dev-1", | ||
"version": "1.1.0-dev-2", | ||
"license": "MIT", | ||
@@ -19,20 +19,25 @@ "author": { | ||
"arktype-repo": "./main.js", | ||
"import": "./dist/main.js" | ||
"types": "./dist/main.d.ts", | ||
"default": "./dist/main.js" | ||
}, | ||
"./internal/*": { | ||
"arktype-repo": "./*", | ||
"import": "./dist/*" | ||
"types": "./dist/*", | ||
"default": "./dist/*" | ||
} | ||
}, | ||
"files": [ | ||
"dist" | ||
"dist", | ||
"**/*.ts", | ||
"!**/*.tsBuildInfo", | ||
"!__tests__" | ||
], | ||
"scripts": { | ||
"build": "tsup --config ../repo/tsup.config.ts", | ||
"build": "tsc --build ./tsconfig.build.json", | ||
"test": "ts ../repo/testPackage.ts" | ||
}, | ||
"dependencies": { | ||
"@arktype/util": "0.0.4", | ||
"@arktype/schema": "0.0.1" | ||
"@arktype/util": "0.0.5", | ||
"@arktype/schema": "0.0.2" | ||
} | ||
} |
Sorry, the diff of this file is too big to display
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
434976
176
7120
+ Added@arktype/schema@0.0.2(transitive)
+ Added@arktype/util@0.0.5(transitive)
- Removed@arktype/schema@0.0.1(transitive)
- Removed@arktype/util@0.0.4(transitive)
Updated@arktype/schema@0.0.2
Updated@arktype/util@0.0.5