feat: Reinitialize frontend with SvelteKit and TypeScript

- Delete old Vite+Svelte frontend
- Initialize new SvelteKit project with TypeScript
- Configure Tailwind CSS v4 + DaisyUI
- Implement JWT authentication with auto-refresh
- Create login page with form validation (Zod)
- Add protected route guards
- Update Docker configuration for single-stage build
- Add E2E tests with Playwright (6/11 passing)
- Fix Svelte 5 reactivity with $state() runes

Known issues:
- 5 E2E tests failing (timing/async issues)
- Token refresh implementation needs debugging
- Validation error display timing
This commit is contained in:
2026-02-17 16:19:59 -05:00
parent 54df6018f5
commit de2d83092e
28274 changed files with 3816354 additions and 90 deletions

45
frontend/node_modules/@ark/schema/out/roots/alias.d.ts generated vendored Normal file
View File

@@ -0,0 +1,45 @@
import { type NodeId } from "../parse.ts";
import type { NodeCompiler } from "../shared/compile.ts";
import type { BaseNormalizedSchema, declareNode } from "../shared/declare.ts";
import { type nodeImplementationOf } from "../shared/implement.ts";
import type { JsonSchema } from "../shared/jsonSchema.ts";
import type { ToJsonSchema } from "../shared/toJsonSchema.ts";
import type { TraverseAllows, TraverseApply } from "../shared/traversal.ts";
import { BaseRoot } from "./root.ts";
export declare namespace Alias {
type Schema<alias extends string = string> = `$${alias}` | NormalizedSchema<alias>;
interface NormalizedSchema<alias extends string = string> extends BaseNormalizedSchema {
readonly reference: alias;
readonly resolve?: () => BaseRoot;
}
interface Inner<alias extends string = string> {
readonly reference: alias;
readonly resolve?: () => BaseRoot;
}
interface Declaration extends declareNode<{
kind: "alias";
schema: Schema;
normalizedSchema: NormalizedSchema;
inner: Inner;
}> {
}
type Node = AliasNode;
}
export declare const normalizeAliasSchema: (schema: Alias.Schema) => Alias.Inner;
export declare class AliasNode extends BaseRoot<Alias.Declaration> {
readonly expression: string;
readonly structure: undefined;
get resolution(): BaseRoot;
protected _resolve(): BaseRoot;
get resolutionId(): NodeId;
get defaultShortDescription(): string;
protected innerToJsonSchema(ctx: ToJsonSchema.Context): JsonSchema;
traverseAllows: TraverseAllows;
traverseApply: TraverseApply;
compile(js: NodeCompiler): void;
}
export declare const writeShallowCycleErrorMessage: (name: string, seen: string[]) => string;
export declare const Alias: {
implementation: nodeImplementationOf<Alias.Declaration>;
Node: typeof AliasNode;
};

115
frontend/node_modules/@ark/schema/out/roots/alias.js generated vendored Normal file
View File

@@ -0,0 +1,115 @@
import { append, domainDescriptions, printable, throwInternalError, throwParseError } from "@ark/util";
import { nodesByRegisteredId } from "../parse.js";
import { Disjoint } from "../shared/disjoint.js";
import { implementNode } from "../shared/implement.js";
import { intersectOrPipeNodes } from "../shared/intersections.js";
import { $ark } from "../shared/registry.js";
import { hasArkKind } from "../shared/utils.js";
import { BaseRoot } from "./root.js";
import { defineRightwardIntersections } from "./utils.js";
export const normalizeAliasSchema = (schema) => typeof schema === "string" ? { reference: schema } : schema;
const neverIfDisjoint = (result) => result instanceof Disjoint ? $ark.intrinsic.never.internal : result;
const implementation = implementNode({
kind: "alias",
hasAssociatedError: false,
collapsibleKey: "reference",
keys: {
reference: {
serialize: s => (s.startsWith("$") ? s : `$ark.${s}`)
},
resolve: {}
},
normalize: normalizeAliasSchema,
defaults: {
description: node => node.reference
},
intersections: {
alias: (l, r, ctx) => ctx.$.lazilyResolve(() => neverIfDisjoint(intersectOrPipeNodes(l.resolution, r.resolution, ctx)), `${l.reference}${ctx.pipe ? "=>" : "&"}${r.reference}`),
...defineRightwardIntersections("alias", (l, r, ctx) => {
if (r.isUnknown())
return l;
if (r.isNever())
return r;
if (r.isBasis() && !r.overlaps($ark.intrinsic.object)) {
// can be more robust as part of https://github.com/arktypeio/arktype/issues/1026
return Disjoint.init("assignability", $ark.intrinsic.object, r);
}
return ctx.$.lazilyResolve(() => neverIfDisjoint(intersectOrPipeNodes(l.resolution, r, ctx)), `${l.reference}${ctx.pipe ? "=>" : "&"}${r.id}`);
})
}
});
export class AliasNode extends BaseRoot {
expression = this.reference;
structure = undefined;
get resolution() {
const result = this._resolve();
return (nodesByRegisteredId[this.id] = result);
}
_resolve() {
if (this.resolve)
return this.resolve();
if (this.reference[0] === "$")
return this.$.resolveRoot(this.reference.slice(1));
const id = this.reference;
let resolution = nodesByRegisteredId[id];
const seen = [];
while (hasArkKind(resolution, "context")) {
if (seen.includes(resolution.id)) {
return throwParseError(writeShallowCycleErrorMessage(resolution.id, seen));
}
seen.push(resolution.id);
resolution = nodesByRegisteredId[resolution.id];
}
if (!hasArkKind(resolution, "root")) {
return throwInternalError(`Unexpected resolution for reference ${this.reference}
Seen: [${seen.join("->")}]
Resolution: ${printable(resolution)}`);
}
return resolution;
}
get resolutionId() {
if (this.reference.includes("&") || this.reference.includes("=>"))
return this.resolution.id;
if (this.reference[0] !== "$")
return this.reference;
const alias = this.reference.slice(1);
const resolution = this.$.resolutions[alias];
if (typeof resolution === "string")
return resolution;
if (hasArkKind(resolution, "root"))
return resolution.id;
return throwInternalError(`Unexpected resolution for reference ${this.reference}: ${printable(resolution)}`);
}
get defaultShortDescription() {
return domainDescriptions.object;
}
innerToJsonSchema(ctx) {
return this.resolution.toJsonSchemaRecurse(ctx);
}
traverseAllows = (data, ctx) => {
const seen = ctx.seen[this.reference];
if (seen?.includes(data))
return true;
ctx.seen[this.reference] = append(seen, data);
return this.resolution.traverseAllows(data, ctx);
};
traverseApply = (data, ctx) => {
const seen = ctx.seen[this.reference];
if (seen?.includes(data))
return;
ctx.seen[this.reference] = append(seen, data);
this.resolution.traverseApply(data, ctx);
};
compile(js) {
const id = this.resolutionId;
js.if(`ctx.seen.${id} && ctx.seen.${id}.includes(data)`, () => js.return(true));
js.if(`!ctx.seen.${id}`, () => js.line(`ctx.seen.${id} = []`));
js.line(`ctx.seen.${id}.push(data)`);
js.return(js.invoke(id));
}
}
export const writeShallowCycleErrorMessage = (name, seen) => `Alias '${name}' has a shallow resolution cycle: ${[...seen, name].join("->")}`;
export const Alias = {
implementation,
Node: AliasNode
};

12
frontend/node_modules/@ark/schema/out/roots/basis.d.ts generated vendored Normal file
View File

@@ -0,0 +1,12 @@
import type { NodeCompiler } from "../shared/compile.ts";
import type { TraverseApply } from "../shared/traversal.ts";
import { BaseRoot, type InternalRootDeclaration } from "./root.ts";
export declare abstract class InternalBasis<d extends InternalRootDeclaration = InternalRootDeclaration> extends BaseRoot<d> {
abstract compiledCondition: string;
abstract compiledNegation: string;
structure: undefined;
traverseApply: TraverseApply<d["prerequisite"]>;
get errorContext(): d["errorContext"];
get compiledErrorContext(): string;
compile(js: NodeCompiler): void;
}

26
frontend/node_modules/@ark/schema/out/roots/basis.js generated vendored Normal file
View File

@@ -0,0 +1,26 @@
import { compileObjectLiteral } from "../shared/implement.js";
import { BaseRoot } from "./root.js";
export class InternalBasis extends BaseRoot {
traverseApply = (data, ctx) => {
if (!this.traverseAllows(data, ctx))
ctx.errorFromNodeContext(this.errorContext);
};
get errorContext() {
return {
code: this.kind,
description: this.description,
meta: this.meta,
...this.inner
};
}
get compiledErrorContext() {
return compileObjectLiteral(this.errorContext);
}
compile(js) {
if (js.traversalKind === "Allows")
js.return(this.compiledCondition);
else {
js.if(this.compiledNegation, () => js.line(`ctx.errorFromNodeContext(${this.compiledErrorContext})`));
}
}
}

View File

@@ -0,0 +1,45 @@
import { type Domain as _Domain } from "@ark/util";
import type { BaseErrorContext, BaseNormalizedSchema, declareNode } from "../shared/declare.ts";
import { type nodeImplementationOf } from "../shared/implement.ts";
import type { JsonSchema } from "../shared/jsonSchema.ts";
import type { ToJsonSchema } from "../shared/toJsonSchema.ts";
import type { TraverseAllows } from "../shared/traversal.ts";
import { InternalBasis } from "./basis.ts";
export type Domain = _Domain;
export declare namespace Domain {
type Enumerable = "undefined" | "null" | "boolean";
type NonEnumerable = Exclude<Domain, Enumerable>;
interface Inner<domain extends NonEnumerable = NonEnumerable> {
readonly domain: domain;
readonly numberAllowsNaN?: boolean;
}
interface NormalizedSchema<domain extends NonEnumerable = NonEnumerable> extends BaseNormalizedSchema, Inner<domain> {
}
type Schema<domain extends NonEnumerable = NonEnumerable> = domain | NormalizedSchema<domain>;
interface ErrorContext extends BaseErrorContext<"domain">, Inner {
}
interface Declaration extends declareNode<{
kind: "domain";
schema: Schema;
normalizedSchema: NormalizedSchema;
inner: Inner;
errorContext: ErrorContext;
}> {
}
type Node = DomainNode;
}
export declare class DomainNode extends InternalBasis<Domain.Declaration> {
private readonly requiresNaNCheck;
readonly traverseAllows: TraverseAllows;
readonly compiledCondition: string;
readonly compiledNegation: string;
readonly expression: string;
get nestableExpression(): string;
get defaultShortDescription(): string;
protected innerToJsonSchema(ctx: ToJsonSchema.Context): JsonSchema.Constrainable;
}
export declare const Domain: {
implementation: nodeImplementationOf<Domain.Declaration>;
Node: typeof DomainNode;
writeBadAllowNanMessage: (actual: Exclude<Domain.NonEnumerable, "number">) => string;
};

72
frontend/node_modules/@ark/schema/out/roots/domain.js generated vendored Normal file
View File

@@ -0,0 +1,72 @@
import { domainDescriptions, domainOf, hasKey, throwParseError } from "@ark/util";
import { Disjoint } from "../shared/disjoint.js";
import { implementNode } from "../shared/implement.js";
import { InternalBasis } from "./basis.js";
const implementation = implementNode({
kind: "domain",
hasAssociatedError: true,
collapsibleKey: "domain",
keys: {
domain: {},
numberAllowsNaN: {}
},
normalize: schema => typeof schema === "string" ? { domain: schema }
: hasKey(schema, "numberAllowsNaN") && schema.domain !== "number" ?
throwParseError(Domain.writeBadAllowNanMessage(schema.domain))
: schema,
applyConfig: (schema, config) => (schema.numberAllowsNaN === undefined &&
schema.domain === "number" &&
config.numberAllowsNaN) ?
{ ...schema, numberAllowsNaN: true }
: schema,
defaults: {
description: node => domainDescriptions[node.domain],
actual: data => Number.isNaN(data) ? "NaN" : domainDescriptions[domainOf(data)]
},
intersections: {
domain: (l, r) =>
// since l === r is handled by default, remaining cases are disjoint
// outside those including options like numberAllowsNaN
l.domain === "number" && r.domain === "number" ?
l.numberAllowsNaN ?
r
: l
: Disjoint.init("domain", l, r)
}
});
export class DomainNode extends InternalBasis {
requiresNaNCheck = this.domain === "number" && !this.numberAllowsNaN;
traverseAllows = this.requiresNaNCheck ?
data => typeof data === "number" && !Number.isNaN(data)
: data => domainOf(data) === this.domain;
compiledCondition = this.domain === "object" ?
`((typeof data === "object" && data !== null) || typeof data === "function")`
: `typeof data === "${this.domain}"${this.requiresNaNCheck ? " && !Number.isNaN(data)" : ""}`;
compiledNegation = this.domain === "object" ?
`((typeof data !== "object" || data === null) && typeof data !== "function")`
: `typeof data !== "${this.domain}"${this.requiresNaNCheck ? " || Number.isNaN(data)" : ""}`;
expression = this.numberAllowsNaN ? "number | NaN" : this.domain;
get nestableExpression() {
return this.numberAllowsNaN ? `(${this.expression})` : this.expression;
}
get defaultShortDescription() {
return domainDescriptions[this.domain];
}
innerToJsonSchema(ctx) {
if (this.domain === "bigint" || this.domain === "symbol") {
return ctx.fallback.domain({
code: "domain",
base: {},
domain: this.domain
});
}
return {
type: this.domain
};
}
}
export const Domain = {
implementation,
Node: DomainNode,
writeBadAllowNanMessage: (actual) => `numberAllowsNaN may only be specified with domain "number" (was ${actual})`
};

View File

@@ -0,0 +1,98 @@
import { type array, type listable, type show } from "@ark/util";
import type { nodeOfKind, NodeSchema, Prerequisite, RootSchema } from "../kinds.ts";
import type { PredicateNode } from "../predicate.ts";
import type { NodeCompiler } from "../shared/compile.ts";
import type { BaseErrorContext, BaseNormalizedSchema, declareNode } from "../shared/declare.ts";
import type { ArkError } from "../shared/errors.ts";
import { type ConstraintKind, type nodeImplementationOf, type OpenNodeKind, type PrestructuralKind, type RefinementKind, type StructuralKind } from "../shared/implement.ts";
import type { JsonSchema } from "../shared/jsonSchema.ts";
import type { ToJsonSchema } from "../shared/toJsonSchema.ts";
import type { TraverseAllows, TraverseApply } from "../shared/traversal.ts";
import { type makeRootAndArrayPropertiesMutable } from "../shared/utils.ts";
import type { Structure, UndeclaredKeyBehavior } from "../structure/structure.ts";
import type { Domain } from "./domain.ts";
import type { Morph } from "./morph.ts";
import type { Proto } from "./proto.ts";
import { BaseRoot } from "./root.ts";
export declare namespace Intersection {
type BasisKind = "domain" | "proto";
type ChildKind = BasisKind | RefinementKind;
type FlattenedChildKind = ChildKind | StructuralKind;
type RefinementsInner = {
[k in RefinementKind]?: intersectionChildInnerValueOf<k>;
};
interface Inner extends RefinementsInner {
domain?: Domain.Node;
proto?: Proto.Node;
structure?: Structure.Node;
predicate?: array<PredicateNode>;
}
namespace Inner {
type mutable = makeRootAndArrayPropertiesMutable<Inner>;
}
type ConstraintsSchema<inferredBasis = any> = show<BaseNormalizedSchema & {
domain?: Domain.Schema;
proto?: Proto.Schema;
} & conditionalRootOf<inferredBasis>>;
type NormalizedSchema = Omit<ConstraintsSchema, StructuralKind | "undeclared">;
type Schema<inferredBasis = any> = ConstraintsSchema<inferredBasis>;
interface AstSchema extends BaseNormalizedSchema {
intersection: readonly RootSchema[];
}
interface ErrorContext extends BaseErrorContext<"intersection">, Inner {
errors: readonly ArkError[];
}
type Declaration = declareNode<{
kind: "intersection";
schema: Schema;
normalizedSchema: NormalizedSchema;
inner: Inner;
reducibleTo: "intersection" | BasisKind;
errorContext: ErrorContext;
childKind: ChildKind;
}>;
type Node = IntersectionNode;
}
export declare class IntersectionNode extends BaseRoot<Intersection.Declaration> {
basis: nodeOfKind<Intersection.BasisKind> | null;
prestructurals: array<nodeOfKind<PrestructuralKind>>;
refinements: array<nodeOfKind<RefinementKind>>;
structure: Structure.Node | undefined;
expression: string;
get shallowMorphs(): array<Morph>;
get defaultShortDescription(): string;
protected innerToJsonSchema(ctx: ToJsonSchema.Context): JsonSchema;
traverseAllows: TraverseAllows;
traverseApply: TraverseApply;
compile(js: NodeCompiler): void;
}
export declare const Intersection: {
implementation: nodeImplementationOf<{
intersectionIsOpen: false;
prerequisite: unknown;
kind: "intersection";
schema: Intersection.Schema;
normalizedSchema: Intersection.NormalizedSchema;
inner: Intersection.Inner;
reducibleTo: "intersection" | Intersection.BasisKind;
errorContext: Intersection.ErrorContext;
childKind: Intersection.ChildKind;
}>;
Node: typeof IntersectionNode;
};
export type ConditionalTerminalIntersectionRoot = {
undeclared?: UndeclaredKeyBehavior;
};
type ConditionalTerminalIntersectionKey = keyof ConditionalTerminalIntersectionRoot;
type ConditionalIntersectionKey = ConstraintKind | ConditionalTerminalIntersectionKey;
export type constraintKindOf<t> = {
[k in ConstraintKind]: t extends Prerequisite<k> ? k : never;
}[ConstraintKind];
type conditionalIntersectionKeyOf<t> = constraintKindOf<t> | (t extends object ? "undeclared" : never);
type intersectionChildSchemaValueOf<k extends Intersection.FlattenedChildKind> = k extends OpenNodeKind ? listable<NodeSchema<k>> : NodeSchema<k>;
type conditionalSchemaValueOfKey<k extends ConditionalIntersectionKey> = k extends Intersection.FlattenedChildKind ? intersectionChildSchemaValueOf<k> : ConditionalTerminalIntersectionRoot[k & ConditionalTerminalIntersectionKey];
type intersectionChildInnerValueOf<k extends Intersection.FlattenedChildKind> = k extends OpenNodeKind ? readonly nodeOfKind<k>[] : nodeOfKind<k>;
export type conditionalRootOf<t> = {
[k in conditionalIntersectionKeyOf<t>]?: conditionalSchemaValueOfKey<k>;
};
export {};

View File

@@ -0,0 +1,292 @@
import { flatMorph, hasDomain, includes, isEmptyObject, isKeyOf, throwParseError } from "@ark/util";
import { constraintKeyParser, flattenConstraints, intersectConstraints } from "../constraint.js";
import { Disjoint } from "../shared/disjoint.js";
import { implementNode, prestructuralKinds, structureKeys } from "../shared/implement.js";
import { intersectOrPipeNodes } from "../shared/intersections.js";
import { hasArkKind, isNode } from "../shared/utils.js";
import { BaseRoot } from "./root.js";
import { defineRightwardIntersections } from "./utils.js";
const implementation = implementNode({
kind: "intersection",
hasAssociatedError: true,
normalize: rawSchema => {
if (isNode(rawSchema))
return rawSchema;
const { structure, ...schema } = rawSchema;
const hasRootStructureKey = !!structure;
const normalizedStructure = structure ?? {};
const normalized = flatMorph(schema, (k, v) => {
if (isKeyOf(k, structureKeys)) {
if (hasRootStructureKey) {
throwParseError(`Flattened structure key ${k} cannot be specified alongside a root 'structure' key.`);
}
normalizedStructure[k] = v;
return [];
}
return [k, v];
});
if (hasArkKind(normalizedStructure, "constraint") ||
!isEmptyObject(normalizedStructure))
normalized.structure = normalizedStructure;
return normalized;
},
finalizeInnerJson: ({ structure, ...rest }) => hasDomain(structure, "object") ? { ...structure, ...rest } : rest,
keys: {
domain: {
child: true,
parse: (schema, ctx) => ctx.$.node("domain", schema)
},
proto: {
child: true,
parse: (schema, ctx) => ctx.$.node("proto", schema)
},
structure: {
child: true,
parse: (schema, ctx) => ctx.$.node("structure", schema),
serialize: node => {
if (!node.sequence?.minLength)
return node.collapsibleJson;
const { sequence, ...structureJson } = node.collapsibleJson;
const { minVariadicLength, ...sequenceJson } = sequence;
const collapsibleSequenceJson = sequenceJson.variadic && Object.keys(sequenceJson).length === 1 ?
sequenceJson.variadic
: sequenceJson;
return { ...structureJson, sequence: collapsibleSequenceJson };
}
},
divisor: {
child: true,
parse: constraintKeyParser("divisor")
},
max: {
child: true,
parse: constraintKeyParser("max")
},
min: {
child: true,
parse: constraintKeyParser("min")
},
maxLength: {
child: true,
parse: constraintKeyParser("maxLength")
},
minLength: {
child: true,
parse: constraintKeyParser("minLength")
},
exactLength: {
child: true,
parse: constraintKeyParser("exactLength")
},
before: {
child: true,
parse: constraintKeyParser("before")
},
after: {
child: true,
parse: constraintKeyParser("after")
},
pattern: {
child: true,
parse: constraintKeyParser("pattern")
},
predicate: {
child: true,
parse: constraintKeyParser("predicate")
}
},
// leverage reduction logic from intersection and identity to ensure initial
// parse result is reduced
reduce: (inner, $) =>
// we cast union out of the result here since that only occurs when intersecting two sequences
// that cannot occur when reducing a single intersection schema using unknown
intersectIntersections({}, inner, {
$,
invert: false,
pipe: false
}),
defaults: {
description: node => {
if (node.children.length === 0)
return "unknown";
if (node.structure)
return node.structure.description;
const childDescriptions = [];
if (node.basis &&
!node.prestructurals.some(r => r.impl.obviatesBasisDescription))
childDescriptions.push(node.basis.description);
if (node.prestructurals.length) {
const sortedRefinementDescriptions = node.prestructurals
.slice()
// override alphabetization to describe min before max
.sort((l, r) => (l.kind === "min" && r.kind === "max" ? -1 : 0))
.map(r => r.description);
childDescriptions.push(...sortedRefinementDescriptions);
}
if (node.inner.predicate) {
childDescriptions.push(...node.inner.predicate.map(p => p.description));
}
return childDescriptions.join(" and ");
},
expected: source => `${source.errors.map(e => e.expected).join("\n ◦ ")}`,
problem: ctx => `(${ctx.actual}) must be...\n${ctx.expected}`
},
intersections: {
intersection: (l, r, ctx) => intersectIntersections(l.inner, r.inner, ctx),
...defineRightwardIntersections("intersection", (l, r, ctx) => {
// if l is unknown, return r
if (l.children.length === 0)
return r;
const { domain, proto, ...lInnerConstraints } = l.inner;
const lBasis = proto ?? domain;
const basis = lBasis ? intersectOrPipeNodes(lBasis, r, ctx) : r;
return (basis instanceof Disjoint ? basis
: l?.basis?.equals(basis) ?
// if the basis doesn't change, return the original intesection
l
// given we've already precluded l being unknown, the result must
// be an intersection with the new basis result integrated
: l.$.node("intersection", { ...lInnerConstraints, [basis.kind]: basis }, { prereduced: true }));
})
}
});
export class IntersectionNode extends BaseRoot {
basis = this.inner.domain ?? this.inner.proto ?? null;
prestructurals = [];
refinements = this.children.filter((node) => {
if (!node.isRefinement())
return false;
if (includes(prestructuralKinds, node.kind))
// mutation is fine during initialization
this.prestructurals.push(node);
return true;
});
structure = this.inner.structure;
expression = writeIntersectionExpression(this);
get shallowMorphs() {
return this.inner.structure?.structuralMorph ?
[this.inner.structure.structuralMorph]
: [];
}
get defaultShortDescription() {
return this.basis?.defaultShortDescription ?? "present";
}
innerToJsonSchema(ctx) {
return this.children.reduce(
// cast is required since TS doesn't know children have compatible schema prerequisites
(schema, child) => child.isBasis() ?
child.toJsonSchemaRecurse(ctx)
: child.reduceJsonSchema(schema, ctx), {});
}
traverseAllows = (data, ctx) => this.children.every(child => child.traverseAllows(data, ctx));
traverseApply = (data, ctx) => {
const errorCount = ctx.currentErrorCount;
if (this.basis) {
this.basis.traverseApply(data, ctx);
if (ctx.currentErrorCount > errorCount)
return;
}
if (this.prestructurals.length) {
for (let i = 0; i < this.prestructurals.length - 1; i++) {
this.prestructurals[i].traverseApply(data, ctx);
if (ctx.failFast && ctx.currentErrorCount > errorCount)
return;
}
this.prestructurals[this.prestructurals.length - 1].traverseApply(data, ctx);
if (ctx.currentErrorCount > errorCount)
return;
}
if (this.structure) {
this.structure.traverseApply(data, ctx);
if (ctx.currentErrorCount > errorCount)
return;
}
if (this.inner.predicate) {
for (let i = 0; i < this.inner.predicate.length - 1; i++) {
this.inner.predicate[i].traverseApply(data, ctx);
if (ctx.failFast && ctx.currentErrorCount > errorCount)
return;
}
this.inner.predicate[this.inner.predicate.length - 1].traverseApply(data, ctx);
}
};
compile(js) {
if (js.traversalKind === "Allows") {
for (const child of this.children)
js.check(child);
js.return(true);
return;
}
js.initializeErrorCount();
if (this.basis) {
js.check(this.basis);
// we only have to return conditionally if this is not the last check
if (this.children.length > 1)
js.returnIfFail();
}
if (this.prestructurals.length) {
for (let i = 0; i < this.prestructurals.length - 1; i++) {
js.check(this.prestructurals[i]);
js.returnIfFailFast();
}
js.check(this.prestructurals[this.prestructurals.length - 1]);
if (this.structure || this.inner.predicate)
js.returnIfFail();
}
if (this.structure) {
js.check(this.structure);
if (this.inner.predicate)
js.returnIfFail();
}
if (this.inner.predicate) {
for (let i = 0; i < this.inner.predicate.length - 1; i++) {
js.check(this.inner.predicate[i]);
// since predicates can be chained, we have to fail immediately
// if one fails
js.returnIfFail();
}
js.check(this.inner.predicate[this.inner.predicate.length - 1]);
}
}
}
export const Intersection = {
implementation,
Node: IntersectionNode
};
const writeIntersectionExpression = (node) => {
if (node.structure?.expression)
return node.structure.expression;
const basisExpression = (node.basis &&
!node.prestructurals.some(n => n.impl.obviatesBasisExpression)) ?
node.basis.nestableExpression
: "";
const refinementsExpression = node.prestructurals
.map(n => n.expression)
.join(" & ");
const fullExpression = `${basisExpression}${basisExpression ? " " : ""}${refinementsExpression}`;
if (fullExpression === "Array == 0")
return "[]";
return fullExpression || "unknown";
};
const intersectIntersections = (l, r, ctx) => {
const baseInner = {};
const lBasis = l.proto ?? l.domain;
const rBasis = r.proto ?? r.domain;
const basisResult = lBasis ?
rBasis ?
intersectOrPipeNodes(lBasis, rBasis, ctx)
: lBasis
: rBasis;
if (basisResult instanceof Disjoint)
return basisResult;
if (basisResult)
baseInner[basisResult.kind] = basisResult;
return intersectConstraints({
kind: "intersection",
baseInner,
l: flattenConstraints(l),
r: flattenConstraints(r),
roots: [],
ctx
});
};

62
frontend/node_modules/@ark/schema/out/roots/morph.d.ts generated vendored Normal file
View File

@@ -0,0 +1,62 @@
import { type array, type listable } from "@ark/util";
import type { RootSchema } from "../kinds.ts";
import type { NodeCompiler } from "../shared/compile.ts";
import type { BaseNormalizedSchema, declareNode } from "../shared/declare.ts";
import { type nodeImplementationOf, type RootKind } from "../shared/implement.ts";
import type { JsonSchema } from "../shared/jsonSchema.ts";
import type { ToJsonSchema } from "../shared/toJsonSchema.ts";
import type { Traversal, TraverseAllows, TraverseApply } from "../shared/traversal.ts";
import { BaseRoot } from "./root.ts";
export declare namespace Morph {
interface Inner {
readonly in?: BaseRoot;
readonly morphs: array<Morph | BaseRoot>;
readonly declaredIn?: BaseRoot;
readonly declaredOut?: BaseRoot;
}
interface Schema extends BaseNormalizedSchema {
readonly in?: RootSchema;
readonly morphs: listable<Morph | BaseRoot>;
readonly declaredIn?: BaseRoot;
readonly declaredOut?: BaseRoot;
}
interface Declaration extends declareNode<{
kind: "morph";
schema: Schema;
normalizedSchema: Schema;
inner: Inner;
childKind: RootKind;
}> {
}
type Node = MorphNode;
type In<morph extends Morph> = morph extends Morph<infer i> ? i : never;
type Out<morph extends Morph> = morph extends Morph<never, infer o> ? o : never;
type ContextFree<i = never, o = unknown> = (In: i) => o;
}
export type Morph<i = never, o = unknown> = (In: i, ctx: Traversal) => o;
export declare class MorphNode extends BaseRoot<Morph.Declaration> {
serializedMorphs: string[];
compiledMorphs: string;
lastMorph: Morph | BaseRoot | undefined;
lastMorphIfNode: BaseRoot | undefined;
introspectableIn: BaseRoot | undefined;
introspectableOut: BaseRoot | undefined;
get shallowMorphs(): array<Morph>;
get rawIn(): BaseRoot;
get rawOut(): BaseRoot;
declareIn(declaredIn: BaseRoot): MorphNode;
declareOut(declaredOut: BaseRoot): MorphNode;
expression: string;
get defaultShortDescription(): string;
protected innerToJsonSchema(ctx: ToJsonSchema.Context): JsonSchema;
compile(js: NodeCompiler): void;
traverseAllows: TraverseAllows;
traverseApply: TraverseApply;
/** Check if the morphs of r are equal to those of this node */
hasEqualMorphs(r: MorphNode): boolean;
}
export declare const Morph: {
implementation: nodeImplementationOf<Morph.Declaration>;
Node: typeof MorphNode;
};
export declare const writeMorphIntersectionMessage: (lDescription: string, rDescription: string) => string;

159
frontend/node_modules/@ark/schema/out/roots/morph.js generated vendored Normal file
View File

@@ -0,0 +1,159 @@
import { arrayEquals, liftArray, throwParseError } from "@ark/util";
import { Disjoint } from "../shared/disjoint.js";
import { implementNode } from "../shared/implement.js";
import { intersectOrPipeNodes } from "../shared/intersections.js";
import { $ark, registeredReference } from "../shared/registry.js";
import { hasArkKind } from "../shared/utils.js";
import { BaseRoot } from "./root.js";
import { defineRightwardIntersections } from "./utils.js";
const implementation = implementNode({
kind: "morph",
hasAssociatedError: false,
keys: {
in: {
child: true,
parse: (schema, ctx) => ctx.$.parseSchema(schema)
},
morphs: {
parse: liftArray,
serialize: morphs => morphs.map(m => hasArkKind(m, "root") ? m.json : registeredReference(m))
},
declaredIn: {
child: false,
serialize: node => node.json
},
declaredOut: {
child: false,
serialize: node => node.json
}
},
normalize: schema => schema,
defaults: {
description: node => `a morph from ${node.rawIn.description} to ${node.rawOut?.description ?? "unknown"}`
},
intersections: {
morph: (l, r, ctx) => {
if (!l.hasEqualMorphs(r)) {
return throwParseError(writeMorphIntersectionMessage(l.expression, r.expression));
}
const inTersection = intersectOrPipeNodes(l.rawIn, r.rawIn, ctx);
if (inTersection instanceof Disjoint)
return inTersection;
const baseInner = {
morphs: l.morphs
};
if (l.declaredIn || r.declaredIn) {
const declaredIn = intersectOrPipeNodes(l.rawIn, r.rawIn, ctx);
// we can't treat this as a normal Disjoint since it's just declared
// it should only happen if someone's essentially trying to create a broken type
if (declaredIn instanceof Disjoint)
return declaredIn.throw();
else
baseInner.declaredIn = declaredIn;
}
if (l.declaredOut || r.declaredOut) {
const declaredOut = intersectOrPipeNodes(l.rawOut, r.rawOut, ctx);
if (declaredOut instanceof Disjoint)
return declaredOut.throw();
else
baseInner.declaredOut = declaredOut;
}
// in case from is a union, we need to distribute the branches
// to can be a union as any schema is allowed
return inTersection.distribute(inBranch => ctx.$.node("morph", {
...baseInner,
in: inBranch
}), ctx.$.parseSchema);
},
...defineRightwardIntersections("morph", (l, r, ctx) => {
const inTersection = l.inner.in ? intersectOrPipeNodes(l.inner.in, r, ctx) : r;
return (inTersection instanceof Disjoint ? inTersection
: inTersection.equals(l.inner.in) ? l
: ctx.$.node("morph", {
...l.inner,
in: inTersection
}));
})
}
});
export class MorphNode extends BaseRoot {
serializedMorphs = this.morphs.map(registeredReference);
compiledMorphs = `[${this.serializedMorphs}]`;
lastMorph = this.inner.morphs[this.inner.morphs.length - 1];
lastMorphIfNode = hasArkKind(this.lastMorph, "root") ? this.lastMorph : undefined;
introspectableIn = this.inner.in;
introspectableOut = this.lastMorphIfNode ?
Object.assign(this.referencesById, this.lastMorphIfNode.referencesById) &&
this.lastMorphIfNode.rawOut
: undefined;
get shallowMorphs() {
// if the morph input is a union, it should not contain any other shallow morphs
return Array.isArray(this.inner.in?.shallowMorphs) ?
[...this.inner.in.shallowMorphs, ...this.morphs]
: this.morphs;
}
get rawIn() {
return (this.declaredIn ?? this.inner.in?.rawIn ?? $ark.intrinsic.unknown.internal);
}
get rawOut() {
return (this.declaredOut ??
this.introspectableOut ??
$ark.intrinsic.unknown.internal);
}
declareIn(declaredIn) {
return this.$.node("morph", {
...this.inner,
declaredIn
});
}
declareOut(declaredOut) {
return this.$.node("morph", {
...this.inner,
declaredOut
});
}
expression = `(In: ${this.rawIn.expression}) => ${this.lastMorphIfNode ? "To" : "Out"}<${this.rawOut.expression}>`;
get defaultShortDescription() {
return this.rawIn.meta.description ?? this.rawIn.defaultShortDescription;
}
innerToJsonSchema(ctx) {
return ctx.fallback.morph({
code: "morph",
base: this.rawIn.toJsonSchemaRecurse(ctx),
out: this.introspectableOut?.toJsonSchemaRecurse(ctx) ?? null
});
}
compile(js) {
if (js.traversalKind === "Allows") {
if (!this.introspectableIn)
return;
js.return(js.invoke(this.introspectableIn));
return;
}
if (this.introspectableIn)
js.line(js.invoke(this.introspectableIn));
js.line(`ctx.queueMorphs(${this.compiledMorphs})`);
}
traverseAllows = (data, ctx) => !this.introspectableIn || this.introspectableIn.traverseAllows(data, ctx);
traverseApply = (data, ctx) => {
if (this.introspectableIn)
this.introspectableIn.traverseApply(data, ctx);
ctx.queueMorphs(this.morphs);
};
/** Check if the morphs of r are equal to those of this node */
hasEqualMorphs(r) {
return arrayEquals(this.morphs, r.morphs, {
isEqual: (lMorph, rMorph) => lMorph === rMorph ||
(hasArkKind(lMorph, "root") &&
hasArkKind(rMorph, "root") &&
lMorph.equals(rMorph))
});
}
}
export const Morph = {
implementation,
Node: MorphNode
};
export const writeMorphIntersectionMessage = (lDescription, rDescription) => `The intersection of distinct morphs at a single path is indeterminate:
Left: ${lDescription}
Right: ${rDescription}`;

53
frontend/node_modules/@ark/schema/out/roots/proto.d.ts generated vendored Normal file
View File

@@ -0,0 +1,53 @@
import { type BuiltinObjectKind, type Constructor } from "@ark/util";
import type { BaseErrorContext, BaseNormalizedSchema, declareNode } from "../shared/declare.ts";
import { type nodeImplementationOf } from "../shared/implement.ts";
import type { JsonSchema } from "../shared/jsonSchema.ts";
import type { ToJsonSchema } from "../shared/toJsonSchema.ts";
import type { TraverseAllows } from "../shared/traversal.ts";
import { InternalBasis } from "./basis.ts";
export declare namespace Proto {
type Reference = Constructor | BuiltinObjectKind;
type Schema<proto extends Reference = Reference> = proto | ExpandedSchema<proto>;
interface NormalizedSchema<proto extends Constructor = Constructor> extends BaseNormalizedSchema {
readonly proto: proto;
readonly dateAllowsInvalid?: boolean;
}
interface ExpandedSchema<proto extends Reference = Reference> {
readonly proto: proto;
readonly dateAllowsInvalid?: boolean;
}
interface Inner<proto extends Constructor = Constructor> {
readonly proto: proto;
readonly dateAllowsInvalid?: boolean;
}
interface ErrorContext extends BaseErrorContext<"proto">, Inner {
}
interface Declaration extends declareNode<{
kind: "proto";
schema: Schema;
normalizedSchema: NormalizedSchema;
inner: Inner;
errorContext: ErrorContext;
}> {
}
type Node = ProtoNode;
}
export declare class ProtoNode extends InternalBasis<Proto.Declaration> {
builtinName: BuiltinObjectKind | null;
serializedConstructor: string;
private readonly requiresInvalidDateCheck;
traverseAllows: TraverseAllows;
compiledCondition: string;
compiledNegation: string;
protected innerToJsonSchema(ctx: ToJsonSchema.Context): JsonSchema;
expression: string;
get nestableExpression(): string;
readonly domain = "object";
get defaultShortDescription(): string;
}
export declare const Proto: {
implementation: nodeImplementationOf<Proto.Declaration>;
Node: typeof ProtoNode;
writeBadInvalidDateMessage: (actual: Constructor) => string;
writeInvalidSchemaMessage: (actual: unknown) => string;
};

101
frontend/node_modules/@ark/schema/out/roots/proto.js generated vendored Normal file
View File

@@ -0,0 +1,101 @@
import { builtinConstructors, constructorExtends, domainOf, getBuiltinNameOfConstructor, hasKey, objectKindDescriptions, objectKindOrDomainOf, throwParseError } from "@ark/util";
import { Disjoint } from "../shared/disjoint.js";
import { defaultValueSerializer, implementNode } from "../shared/implement.js";
import { $ark } from "../shared/registry.js";
import { isNode } from "../shared/utils.js";
import { InternalBasis } from "./basis.js";
const implementation = implementNode({
kind: "proto",
hasAssociatedError: true,
collapsibleKey: "proto",
keys: {
proto: {
serialize: ctor => getBuiltinNameOfConstructor(ctor) ?? defaultValueSerializer(ctor)
},
dateAllowsInvalid: {}
},
normalize: schema => {
const normalized = typeof schema === "string" ? { proto: builtinConstructors[schema] }
: typeof schema === "function" ?
isNode(schema) ? schema
: { proto: schema }
: typeof schema.proto === "string" ?
{ ...schema, proto: builtinConstructors[schema.proto] }
: schema;
if (typeof normalized.proto !== "function")
throwParseError(Proto.writeInvalidSchemaMessage(normalized.proto));
if (hasKey(normalized, "dateAllowsInvalid") && normalized.proto !== Date)
throwParseError(Proto.writeBadInvalidDateMessage(normalized.proto));
return normalized;
},
applyConfig: (schema, config) => {
if (schema.dateAllowsInvalid === undefined &&
schema.proto === Date &&
config.dateAllowsInvalid)
return { ...schema, dateAllowsInvalid: true };
return schema;
},
defaults: {
description: node => node.builtinName ?
objectKindDescriptions[node.builtinName]
: `an instance of ${node.proto.name}`,
actual: data => data instanceof Date && data.toString() === "Invalid Date" ?
"an invalid Date"
: objectKindOrDomainOf(data)
},
intersections: {
proto: (l, r) => l.proto === Date && r.proto === Date ?
// since l === r is handled by default,
// exactly one of l or r must have allow invalid dates
l.dateAllowsInvalid ?
r
: l
: constructorExtends(l.proto, r.proto) ? l
: constructorExtends(r.proto, l.proto) ? r
: Disjoint.init("proto", l, r),
domain: (proto, domain) => domain.domain === "object" ?
proto
: Disjoint.init("domain", $ark.intrinsic.object.internal, domain)
}
});
export class ProtoNode extends InternalBasis {
builtinName = getBuiltinNameOfConstructor(this.proto);
serializedConstructor = this.json.proto;
requiresInvalidDateCheck = this.proto === Date && !this.dateAllowsInvalid;
traverseAllows = this.requiresInvalidDateCheck ?
data => data instanceof Date && data.toString() !== "Invalid Date"
: data => data instanceof this.proto;
compiledCondition = `data instanceof ${this.serializedConstructor}${this.requiresInvalidDateCheck ? ` && data.toString() !== "Invalid Date"` : ""}`;
compiledNegation = `!(${this.compiledCondition})`;
innerToJsonSchema(ctx) {
switch (this.builtinName) {
case "Array":
return {
type: "array"
};
case "Date":
return (ctx.fallback.date?.({ code: "date", base: {} }) ??
ctx.fallback.proto({ code: "proto", base: {}, proto: this.proto }));
default:
return ctx.fallback.proto({
code: "proto",
base: {},
proto: this.proto
});
}
}
expression = this.dateAllowsInvalid ? "Date | InvalidDate" : this.proto.name;
get nestableExpression() {
return this.dateAllowsInvalid ? `(${this.expression})` : this.expression;
}
domain = "object";
get defaultShortDescription() {
return this.description;
}
}
export const Proto = {
implementation,
Node: ProtoNode,
writeBadInvalidDateMessage: (actual) => `dateAllowsInvalid may only be specified with constructor Date (was ${actual.name})`,
writeInvalidSchemaMessage: (actual) => `instanceOf operand must be a function (was ${domainOf(actual)})`
};

145
frontend/node_modules/@ark/schema/out/roots/root.d.ts generated vendored Normal file
View File

@@ -0,0 +1,145 @@
import { inferred, type array } from "@ark/util";
import { type Constraint } from "../constraint.ts";
import type { NodeSchema, nodeOfKind, reducibleKindOf } from "../kinds.ts";
import { BaseNode, type GettableKeyOrNode, type KeyOrKeyNode, type NodeSelector } from "../node.ts";
import type { Predicate } from "../predicate.ts";
import type { Divisor } from "../refinements/divisor.ts";
import type { ExactLength } from "../refinements/exactLength.ts";
import type { Pattern } from "../refinements/pattern.ts";
import type { ExclusiveDateRangeSchema, ExclusiveNumericRangeSchema, InclusiveDateRangeSchema, InclusiveNumericRangeSchema, LimitSchemaValue, UnknownRangeSchema } from "../refinements/range.ts";
import type { BaseScope } from "../scope.ts";
import type { BaseNodeDeclaration, TypeMeta } from "../shared/declare.ts";
import { Disjoint } from "../shared/disjoint.ts";
import { type NodeKind, type RootKind, type UnknownAttachments, type kindRightOf } from "../shared/implement.ts";
import type { JsonSchema } from "../shared/jsonSchema.ts";
import type { StandardJSONSchemaV1, StandardSchemaV1 } from "../shared/standardSchema.ts";
import type { ToJsonSchema } from "../shared/toJsonSchema.ts";
import { arkKind } from "../shared/utils.ts";
import type { Prop } from "../structure/prop.ts";
import type { PropFlatMapper, UndeclaredKeyBehavior } from "../structure/structure.ts";
import type { Morph } from "./morph.ts";
import type { Union } from "./union.ts";
export interface InternalRootDeclaration extends BaseNodeDeclaration {
kind: RootKind;
}
export declare abstract class BaseRoot<
/** @ts-ignore cast variance */
out d extends InternalRootDeclaration = InternalRootDeclaration> extends BaseNode<d> implements StandardSchemaV1, StandardJSONSchemaV1 {
readonly [arkKind]: "root";
readonly [inferred]: unknown;
constructor(attachments: UnknownAttachments, $: BaseScope);
get rawIn(): BaseRoot;
get rawOut(): BaseRoot;
get internal(): this;
get "~standard"(): StandardSchemaV1.ArkTypeProps;
as(): this;
brand(name: string): this;
readonly(): this;
readonly branches: readonly nodeOfKind<Union.ChildKind>[];
distribute<mapOut, reduceOut = mapOut[]>(mapBranch: (branch: nodeOfKind<Union.ChildKind>, i: number, branches: array<nodeOfKind<Union.ChildKind>>) => mapOut, reduceMapped?: (mappedBranches: mapOut[]) => reduceOut): reduceOut;
abstract get defaultShortDescription(): string;
get shortDescription(): string;
toJsonSchema(opts?: ToJsonSchema.Options): JsonSchema;
toJsonSchemaRecurse(ctx: ToJsonSchema.Context): JsonSchema;
get alwaysExpandJsonSchema(): boolean;
protected toResolvedJsonSchema(ctx: ToJsonSchema.Context): JsonSchema;
protected abstract innerToJsonSchema(ctx: ToJsonSchema.Context): JsonSchema;
intersect(r: unknown): BaseRoot | Disjoint;
rawIntersect(r: BaseRoot): BaseRoot;
toNeverIfDisjoint(): BaseRoot;
and(r: unknown): BaseRoot;
rawAnd(r: BaseRoot): BaseRoot;
or(r: unknown): BaseRoot;
rawOr(r: BaseRoot): BaseRoot;
map(flatMapEntry: PropFlatMapper): BaseRoot;
pick(...keys: KeyOrKeyNode[]): BaseRoot;
omit(...keys: KeyOrKeyNode[]): BaseRoot;
required(): BaseRoot;
partial(): BaseRoot;
private _keyof?;
keyof(): BaseRoot;
get props(): Prop.Node[];
merge(r: unknown): BaseRoot;
private applyStructuralOperation;
get(...path: GettableKeyOrNode[]): BaseRoot;
extract(r: unknown): BaseRoot;
exclude(r: unknown): BaseRoot;
array(): BaseRoot;
overlaps(r: unknown): boolean;
extends(r: unknown): boolean;
ifExtends(r: unknown): BaseRoot | undefined;
subsumes(r: unknown): boolean;
configure(meta: TypeMeta.MappableInput, selector?: NodeSelector): this;
describe(description: string, selector?: NodeSelector): this;
optional(): [this, "?"];
default(thunkableValue: unknown): [this, "=", unknown];
from(input: unknown): unknown;
protected _pipe(...morphs: Morph[]): BaseRoot;
protected tryPipe(...morphs: Morph[]): BaseRoot;
pipe: ((...morphs: Morph[]) => BaseRoot) & {
try: (...morphs: Morph[]) => BaseRoot;
};
to(def: unknown): BaseRoot;
private toNode;
rawPipeOnce(morph: Morph): BaseRoot;
narrow(predicate: Predicate): BaseRoot;
constrain<kind extends Constraint.PrimitiveKind>(kind: kind, schema: NodeSchema<kind>): BaseRoot;
constrainIn<kind extends Constraint.PrimitiveKind>(kind: kind, schema: NodeSchema<kind>): BaseRoot;
constrainOut<kind extends Constraint.PrimitiveKind>(kind: kind, schema: NodeSchema<kind>): BaseRoot;
private _constrain;
onUndeclaredKey(cfg: UndeclaredKeyBehavior | UndeclaredKeyConfig): BaseRoot;
hasEqualMorphs(r: BaseRoot): boolean;
onDeepUndeclaredKey(behavior: UndeclaredKeyBehavior): BaseRoot;
filter(predicate: Predicate): BaseRoot;
divisibleBy(schema: Divisor.Schema): BaseRoot;
matching(schema: Pattern.Schema): BaseRoot;
atLeast(schema: InclusiveNumericRangeSchema): BaseRoot;
atMost(schema: InclusiveNumericRangeSchema): BaseRoot;
moreThan(schema: ExclusiveNumericRangeSchema): BaseRoot;
lessThan(schema: ExclusiveNumericRangeSchema): BaseRoot;
atLeastLength(schema: InclusiveNumericRangeSchema): BaseRoot;
atMostLength(schema: InclusiveNumericRangeSchema): BaseRoot;
moreThanLength(schema: ExclusiveNumericRangeSchema): BaseRoot;
lessThanLength(schema: ExclusiveNumericRangeSchema): BaseRoot;
exactlyLength(schema: ExactLength.Schema): BaseRoot;
atOrAfter(schema: InclusiveDateRangeSchema): BaseRoot;
atOrBefore(schema: InclusiveDateRangeSchema): BaseRoot;
laterThan(schema: ExclusiveDateRangeSchema): BaseRoot;
earlierThan(schema: ExclusiveDateRangeSchema): BaseRoot;
}
export type UndeclaredKeyConfig = {
rule: UndeclaredKeyBehavior;
deep?: boolean;
};
export declare const emptyBrandNameMessage = "Expected a non-empty brand name after #";
export type emptyBrandNameMessage = typeof emptyBrandNameMessage;
export declare const writeInvalidJsonSchemaTargetMessage: (target: string) => string;
export declare const exclusivizeRangeSchema: <schema extends UnknownRangeSchema>(schema: schema) => schema;
export type exclusivizeRangeSchema<schema extends UnknownRangeSchema> = schema extends LimitSchemaValue ? {
rule: schema;
exclusive: true;
} : schema;
export declare const typeOrTermExtends: (t: unknown, base: unknown) => boolean;
export type intersectRoot<l extends RootKind, r extends NodeKind> = [
l,
r
] extends [r, l] ? l : asymmetricIntersectionOf<l, r> | asymmetricIntersectionOf<r, l>;
type asymmetricIntersectionOf<l extends NodeKind, r extends NodeKind> = l extends unknown ? r extends kindRightOf<l> ? l | reducibleKindOf<l> : never : never;
export type schemaKindRightOf<kind extends RootKind> = Extract<kindRightOf<kind>, RootKind>;
export type schemaKindOrRightOf<kind extends RootKind> = kind | schemaKindRightOf<kind>;
export type StructuralOperationBranchResultByName = {
keyof: Union.ChildNode;
pick: Union.ChildNode;
omit: Union.ChildNode;
get: Union.ChildNode;
map: Union.ChildNode;
required: Union.ChildNode;
partial: Union.ChildNode;
merge: Union.ChildNode;
props: array<Prop.Node>;
};
export type StructuralOperationName = keyof StructuralOperationBranchResultByName;
export declare const writeLiteralUnionEntriesMessage: (expression: string) => string;
export declare const writeNonStructuralOperandMessage: <operation extends StructuralOperationName, operand extends string>(operation: operation, operand: operand) => writeNonStructuralOperandMessage<operation, operand>;
export type writeNonStructuralOperandMessage<operation extends StructuralOperationName, operand extends string> = `${operation} operand must be an object (was ${operand})`;
export {};

455
frontend/node_modules/@ark/schema/out/roots/root.js generated vendored Normal file
View File

@@ -0,0 +1,455 @@
import { arrayEquals, flatMorph, includes, inferred, omit, throwInternalError, throwParseError } from "@ark/util";
import { mergeToJsonSchemaConfigs } from "../config.js";
import { throwInvalidOperandError } from "../constraint.js";
import { BaseNode } from "../node.js";
import { Disjoint, writeUnsatisfiableExpressionError } from "../shared/disjoint.js";
import { ArkErrors } from "../shared/errors.js";
import { structuralKinds } from "../shared/implement.js";
import { intersectNodesRoot, pipeNodesRoot } from "../shared/intersections.js";
import { $ark } from "../shared/registry.js";
import { arkKind, hasArkKind } from "../shared/utils.js";
import { assertDefaultValueAssignability } from "../structure/optional.js";
export class BaseRoot extends BaseNode {
constructor(attachments, $) {
super(attachments, $);
// define as a getter to avoid it being enumerable/spreadable
Object.defineProperty(this, arkKind, { value: "root", enumerable: false });
}
// doesn't seem possible to override this at a type-level (e.g. via declare)
// without TS complaining about getters
get rawIn() {
return super.rawIn;
}
get rawOut() {
return super.rawOut;
}
get internal() {
return this;
}
get "~standard"() {
return {
vendor: "arktype",
version: 1,
validate: input => {
const out = this(input);
if (out instanceof ArkErrors)
return out;
return { value: out };
},
jsonSchema: {
input: opts => this.rawIn.toJsonSchema({
target: validateStandardJsonSchemaTarget(opts.target),
...opts.libraryOptions
}),
output: opts => this.rawOut.toJsonSchema({
target: validateStandardJsonSchemaTarget(opts.target),
...opts.libraryOptions
})
}
};
}
as() {
return this;
}
brand(name) {
if (name === "")
return throwParseError(emptyBrandNameMessage);
return this;
}
readonly() {
return this;
}
branches = this.hasKind("union") ? this.inner.branches : [this];
distribute(mapBranch, reduceMapped) {
const mappedBranches = this.branches.map(mapBranch);
return reduceMapped?.(mappedBranches) ?? mappedBranches;
}
get shortDescription() {
return this.meta.description ?? this.defaultShortDescription;
}
toJsonSchema(opts = {}) {
const ctx = mergeToJsonSchemaConfigs(this.$.resolvedConfig.toJsonSchema, opts);
ctx.useRefs ||= this.isCyclic;
// ensure $schema is the first key if present
const schema = typeof ctx.dialect === "string" ? { $schema: ctx.dialect } : {};
Object.assign(schema, this.toJsonSchemaRecurse(ctx));
if (ctx.useRefs) {
const defs = flatMorph(this.references, (i, ref) => ref.isRoot() && !ref.alwaysExpandJsonSchema ?
[ref.id, ref.toResolvedJsonSchema(ctx)]
: []);
// draft-2020-12 uses $defs, draft-07 uses definitions
if (ctx.target === "draft-07")
Object.assign(schema, { definitions: defs });
else
schema.$defs = defs;
}
return schema;
}
toJsonSchemaRecurse(ctx) {
if (ctx.useRefs && !this.alwaysExpandJsonSchema) {
// draft-2020-12 uses $defs, draft-07 uses definitions
const defsKey = ctx.target === "draft-07" ? "definitions" : "$defs";
return { $ref: `#/${defsKey}/${this.id}` };
}
return this.toResolvedJsonSchema(ctx);
}
get alwaysExpandJsonSchema() {
return (this.isBasis() ||
this.kind === "alias" ||
(this.hasKind("union") && this.isBoolean));
}
toResolvedJsonSchema(ctx) {
const result = this.innerToJsonSchema(ctx);
return Object.assign(result, this.metaJson);
}
intersect(r) {
const rNode = this.$.parseDefinition(r);
const result = this.rawIntersect(rNode);
if (result instanceof Disjoint)
return result;
return this.$.finalize(result);
}
rawIntersect(r) {
return intersectNodesRoot(this, r, this.$);
}
toNeverIfDisjoint() {
return this;
}
and(r) {
const result = this.intersect(r);
return result instanceof Disjoint ? result.throw() : result;
}
rawAnd(r) {
const result = this.rawIntersect(r);
return result instanceof Disjoint ? result.throw() : result;
}
or(r) {
const rNode = this.$.parseDefinition(r);
return this.$.finalize(this.rawOr(rNode));
}
rawOr(r) {
const branches = [...this.branches, ...r.branches];
return this.$.node("union", branches);
}
map(flatMapEntry) {
return this.$.schema(this.applyStructuralOperation("map", [flatMapEntry]));
}
pick(...keys) {
return this.$.schema(this.applyStructuralOperation("pick", keys));
}
omit(...keys) {
return this.$.schema(this.applyStructuralOperation("omit", keys));
}
required() {
return this.$.schema(this.applyStructuralOperation("required", []));
}
partial() {
return this.$.schema(this.applyStructuralOperation("partial", []));
}
_keyof;
keyof() {
if (this._keyof)
return this._keyof;
const result = this.applyStructuralOperation("keyof", []).reduce((result, branch) => result.intersect(branch).toNeverIfDisjoint(), $ark.intrinsic.unknown.internal);
if (result.branches.length === 0) {
throwParseError(writeUnsatisfiableExpressionError(`keyof ${this.expression}`));
}
return (this._keyof = this.$.finalize(result));
}
get props() {
if (this.branches.length !== 1)
return throwParseError(writeLiteralUnionEntriesMessage(this.expression));
return [...this.applyStructuralOperation("props", [])[0]];
}
merge(r) {
const rNode = this.$.parseDefinition(r);
return this.$.schema(rNode.distribute(branch => this.applyStructuralOperation("merge", [
structureOf(branch) ??
throwParseError(writeNonStructuralOperandMessage("merge", branch.expression))
])));
}
applyStructuralOperation(operation, args) {
return this.distribute(branch => {
if (branch.equals($ark.intrinsic.object) && operation !== "merge")
// ideally this wouldn't be a special case, but for now it
// allows us to bypass `assertHasKeys` checks on base
// instantiations of generics like Pick and Omit. Could
// potentially be removed once constraints can reference each other:
// https://github.com/arktypeio/arktype/issues/1053
return branch;
const structure = structureOf(branch);
if (!structure) {
throwParseError(writeNonStructuralOperandMessage(operation, branch.expression));
}
if (operation === "keyof")
return structure.keyof();
if (operation === "get")
return structure.get(...args);
if (operation === "props")
return structure.props;
const structuralMethodName = operation === "required" ? "require"
: operation === "partial" ? "optionalize"
: operation;
return this.$.node("intersection", {
domain: "object",
structure: structure[structuralMethodName](...args)
});
});
}
get(...path) {
if (path[0] === undefined)
return this;
return this.$.schema(this.applyStructuralOperation("get", path));
}
extract(r) {
const rNode = this.$.parseDefinition(r);
return this.$.schema(this.branches.filter(branch => branch.extends(rNode)));
}
exclude(r) {
const rNode = this.$.parseDefinition(r);
return this.$.schema(this.branches.filter(branch => !branch.extends(rNode)));
}
array() {
return this.$.schema(this.isUnknown() ?
{ proto: Array }
: {
proto: Array,
sequence: this
}, { prereduced: true });
}
overlaps(r) {
const intersection = this.intersect(r);
return !(intersection instanceof Disjoint);
}
extends(r) {
if (this.isNever())
return true;
const intersection = this.intersect(r);
return (!(intersection instanceof Disjoint) && this.equals(intersection));
}
ifExtends(r) {
return this.extends(r) ? this : undefined;
}
subsumes(r) {
const rNode = this.$.parseDefinition(r);
return rNode.extends(this);
}
configure(meta, selector = "shallow") {
return this.configureReferences(meta, selector);
}
describe(description, selector = "shallow") {
return this.configure({ description }, selector);
}
// these should ideally be implemented in arktype since they use its syntax
// https://github.com/arktypeio/arktype/issues/1223
optional() {
return [this, "?"];
}
// these should ideally be implemented in arktype since they use its syntax
// https://github.com/arktypeio/arktype/issues/1223
default(thunkableValue) {
assertDefaultValueAssignability(this, thunkableValue, null);
return [this, "=", thunkableValue];
}
from(input) {
// ideally we might not validate here but for now we need to do determine
// which morphs to apply
return this.assert(input);
}
_pipe(...morphs) {
const result = morphs.reduce((acc, morph) => acc.rawPipeOnce(morph), this);
return this.$.finalize(result);
}
tryPipe(...morphs) {
const result = morphs.reduce((acc, morph) => acc.rawPipeOnce(hasArkKind(morph, "root") ? morph : ((In, ctx) => {
try {
return morph(In, ctx);
}
catch (e) {
return ctx.error({
code: "predicate",
predicate: morph,
actual: `aborted due to error:\n ${e}\n`
});
}
})), this);
return this.$.finalize(result);
}
pipe = Object.assign(this._pipe.bind(this), {
try: this.tryPipe.bind(this)
});
to(def) {
return this.$.finalize(this.toNode(this.$.parseDefinition(def)));
}
toNode(root) {
const result = pipeNodesRoot(this, root, this.$);
if (result instanceof Disjoint)
return result.throw();
return result;
}
rawPipeOnce(morph) {
if (hasArkKind(morph, "root"))
return this.toNode(morph);
return this.distribute(branch => branch.hasKind("morph") ?
this.$.node("morph", {
in: branch.inner.in,
morphs: [...branch.morphs, morph]
})
: this.$.node("morph", {
in: branch,
morphs: [morph]
}), this.$.parseSchema);
}
narrow(predicate) {
return this.constrainOut("predicate", predicate);
}
constrain(kind, schema) {
return this._constrain("root", kind, schema);
}
constrainIn(kind, schema) {
return this._constrain("in", kind, schema);
}
constrainOut(kind, schema) {
return this._constrain("out", kind, schema);
}
_constrain(io, kind, schema) {
const constraint = this.$.node(kind, schema);
if (constraint.isRoot()) {
// if the node reduces to `unknown`, nothing to do (e.g. minLength: 0)
return constraint.isUnknown() ? this : (throwInternalError(`Unexpected constraint node ${constraint}`));
}
const operand = io === "root" ? this
: io === "in" ? this.rawIn
: this.rawOut;
if (operand.hasKind("morph") ||
(constraint.impliedBasis && !operand.extends(constraint.impliedBasis))) {
return throwInvalidOperandError(kind, constraint.impliedBasis, this);
}
const partialIntersection = this.$.node("intersection", {
// important this is constraint.kind instead of kind in case
// the node was reduced during parsing
[constraint.kind]: constraint
});
const result = io === "out" ?
pipeNodesRoot(this, partialIntersection, this.$)
: intersectNodesRoot(this, partialIntersection, this.$);
if (result instanceof Disjoint)
result.throw();
return this.$.finalize(result);
}
onUndeclaredKey(cfg) {
const rule = typeof cfg === "string" ? cfg : cfg.rule;
const deep = typeof cfg === "string" ? false : cfg.deep;
return this.$.finalize(this.transform((kind, inner) => kind === "structure" ?
rule === "ignore" ?
omit(inner, { undeclared: 1 })
: { ...inner, undeclared: rule }
: inner, deep ? undefined : ({ shouldTransform: node => !includes(structuralKinds, node.kind) })));
}
hasEqualMorphs(r) {
if (!this.includesTransform && !r.includesTransform)
return true;
if (!arrayEquals(this.shallowMorphs, r.shallowMorphs))
return false;
if (!arrayEquals(this.flatMorphs, r.flatMorphs, {
isEqual: (l, r) => l.propString === r.propString &&
(l.node.hasKind("morph") && r.node.hasKind("morph") ?
l.node.hasEqualMorphs(r.node)
: l.node.hasKind("intersection") && r.node.hasKind("intersection") ?
l.node.structure?.structuralMorphRef ===
r.node.structure?.structuralMorphRef
: false)
}))
return false;
return true;
}
onDeepUndeclaredKey(behavior) {
return this.onUndeclaredKey({ rule: behavior, deep: true });
}
filter(predicate) {
return this.constrainIn("predicate", predicate);
}
divisibleBy(schema) {
return this.constrain("divisor", schema);
}
matching(schema) {
return this.constrain("pattern", schema);
}
atLeast(schema) {
return this.constrain("min", schema);
}
atMost(schema) {
return this.constrain("max", schema);
}
moreThan(schema) {
return this.constrain("min", exclusivizeRangeSchema(schema));
}
lessThan(schema) {
return this.constrain("max", exclusivizeRangeSchema(schema));
}
atLeastLength(schema) {
return this.constrain("minLength", schema);
}
atMostLength(schema) {
return this.constrain("maxLength", schema);
}
moreThanLength(schema) {
return this.constrain("minLength", exclusivizeRangeSchema(schema));
}
lessThanLength(schema) {
return this.constrain("maxLength", exclusivizeRangeSchema(schema));
}
exactlyLength(schema) {
return this.constrain("exactLength", schema);
}
atOrAfter(schema) {
return this.constrain("after", schema);
}
atOrBefore(schema) {
return this.constrain("before", schema);
}
laterThan(schema) {
return this.constrain("after", exclusivizeRangeSchema(schema));
}
earlierThan(schema) {
return this.constrain("before", exclusivizeRangeSchema(schema));
}
}
export const emptyBrandNameMessage = `Expected a non-empty brand name after #`;
const supportedJsonSchemaTargets = [
"draft-2020-12",
"draft-07"
];
export const writeInvalidJsonSchemaTargetMessage = (target) => `JSONSchema target '${target}' is not supported (must be ${supportedJsonSchemaTargets.map(t => `"${t}"`).join(" or ")})`;
const validateStandardJsonSchemaTarget = (target) => {
if (!includes(supportedJsonSchemaTargets, target))
throwParseError(writeInvalidJsonSchemaTargetMessage(target));
return target;
};
export const exclusivizeRangeSchema = (schema) => (typeof schema === "object" && !(schema instanceof Date) ?
{ ...schema, exclusive: true }
: {
rule: schema,
exclusive: true
});
export const typeOrTermExtends = (t, base) => hasArkKind(base, "root") ?
hasArkKind(t, "root") ? t.extends(base)
: base.allows(t)
: hasArkKind(t, "root") ? t.hasUnit(base)
: base === t;
const structureOf = (branch) => {
if (branch.hasKind("morph"))
return null;
if (branch.hasKind("intersection")) {
return (branch.inner.structure ??
(branch.basis?.domain === "object" ?
branch.$.bindReference($ark.intrinsic.emptyStructure)
: null));
}
if (branch.isBasis() && branch.domain === "object")
return branch.$.bindReference($ark.intrinsic.emptyStructure);
return null;
};
export const writeLiteralUnionEntriesMessage = (expression) => `Props cannot be extracted from a union. Use .distribute to extract props from each branch instead. Received:
${expression}`;
export const writeNonStructuralOperandMessage = (operation, operand) => `${operation} operand must be an object (was ${operand})`;

99
frontend/node_modules/@ark/schema/out/roots/union.d.ts generated vendored Normal file
View File

@@ -0,0 +1,99 @@
import { type JsonStructure, type SerializedPrimitive, type array, type show } from "@ark/util";
import type { NodeSchema, RootSchema, nodeOfKind } from "../kinds.ts";
import type { BaseNode } from "../node.ts";
import { type NodeCompiler } from "../shared/compile.ts";
import type { BaseErrorContext, BaseNormalizedSchema, declareNode } from "../shared/declare.ts";
import { Disjoint } from "../shared/disjoint.ts";
import type { ArkError } from "../shared/errors.ts";
import { type IntersectionContext, type RootKind, type UnionChildKind, type nodeImplementationOf } from "../shared/implement.ts";
import type { JsonSchema } from "../shared/jsonSchema.ts";
import { type RegisteredReference } from "../shared/registry.ts";
import type { ToJsonSchema } from "../shared/toJsonSchema.ts";
import { type TraverseAllows, type TraverseApply } from "../shared/traversal.ts";
import type { Domain } from "./domain.ts";
import type { Morph } from "./morph.ts";
import { BaseRoot } from "./root.ts";
export declare namespace Union {
type ChildKind = UnionChildKind;
type ChildSchema = NodeSchema<ChildKind>;
type ChildNode = nodeOfKind<ChildKind>;
type Schema = NormalizedSchema | readonly RootSchema[];
interface NormalizedSchema extends BaseNormalizedSchema {
readonly branches: array<RootSchema>;
readonly ordered?: true;
}
interface Inner {
readonly branches: readonly ChildNode[];
readonly ordered?: true;
}
interface ErrorContext extends BaseErrorContext<"union"> {
errors: readonly ArkError[];
}
interface Declaration extends declareNode<{
kind: "union";
schema: Schema;
normalizedSchema: NormalizedSchema;
inner: Inner;
errorContext: ErrorContext;
reducibleTo: RootKind;
childKind: UnionChildKind;
}> {
}
type Node = UnionNode;
}
export declare class UnionNode extends BaseRoot<Union.Declaration> {
isBoolean: boolean;
get branchGroups(): BaseRoot[];
unitBranches: (import("./morph.ts").MorphNode | import("./unit.ts").UnitNode)[];
discriminant: Discriminant<DiscriminantKind> | null;
discriminantJson: JsonStructure | null;
expression: string;
createBranchedOptimisticRootApply(): BaseNode["rootApply"];
get shallowMorphs(): array<Morph>;
get defaultShortDescription(): string;
protected innerToJsonSchema(ctx: ToJsonSchema.Context): JsonSchema;
traverseAllows: TraverseAllows;
traverseApply: TraverseApply;
traverseOptimistic: (data: unknown) => unknown;
compile(js: NodeCompiler): void;
private compileIndiscriminable;
get nestableExpression(): string;
discriminate(): Discriminant | null;
}
export declare const Union: {
implementation: nodeImplementationOf<Union.Declaration>;
Node: typeof UnionNode;
};
type DescribeBranchesOptions = {
delimiter?: string;
finalDelimiter?: string;
};
export declare const describeBranches: (descriptions: string[], opts?: DescribeBranchesOptions) => string;
export declare const intersectBranches: (l: readonly Union.ChildNode[], r: readonly Union.ChildNode[], ctx: IntersectionContext) => readonly Union.ChildNode[] | Disjoint;
export declare const reduceBranches: ({ branches, ordered }: Union.Inner) => readonly Union.ChildNode[];
export type CaseKey<kind extends DiscriminantKind = DiscriminantKind> = DiscriminantKind extends kind ? string : DiscriminantKinds[kind] | "default";
type DiscriminantLocation<kind extends DiscriminantKind = DiscriminantKind> = {
path: PropertyKey[];
optionallyChainedPropString: string;
kind: kind;
};
export interface Discriminant<kind extends DiscriminantKind = DiscriminantKind> extends DiscriminantLocation<kind> {
cases: DiscriminatedCases<kind>;
}
export type CaseContext = {
branchIndices: number[];
condition: nodeOfKind<DiscriminantKind> | Domain.Enumerable;
};
export type CaseDiscriminant = nodeOfKind<DiscriminantKind> | Domain.Enumerable;
export type DiscriminatedCases<kind extends DiscriminantKind = DiscriminantKind> = {
[caseKey in CaseKey<kind>]: BaseRoot | true;
};
export type DiscriminantKinds = {
domain: Domain;
unit: SerializedPrimitive | RegisteredReference;
};
export type DiscriminantKind = show<keyof DiscriminantKinds>;
export declare const pruneDiscriminant: (discriminantBranch: BaseRoot, discriminantCtx: DiscriminantLocation) => BaseRoot | null;
export declare const writeIndiscriminableMorphMessage: (lDescription: string, rDescription: string) => string;
export declare const writeOrderedIntersectionMessage: (lDescription: string, rDescription: string) => string;
export {};

718
frontend/node_modules/@ark/schema/out/roots/union.js generated vendored Normal file
View File

@@ -0,0 +1,718 @@
import { appendUnique, arrayEquals, domainDescriptions, flatMorph, groupBy, hasKey, isArray, jsTypeOfDescriptions, printable, range, throwParseError, unset } from "@ark/util";
import { compileLiteralPropAccess, compileSerializedValue } from "../shared/compile.js";
import { Disjoint } from "../shared/disjoint.js";
import { implementNode } from "../shared/implement.js";
import { intersectNodesRoot, intersectOrPipeNodes } from "../shared/intersections.js";
import { $ark, registeredReference } from "../shared/registry.js";
import { Traversal } from "../shared/traversal.js";
import { hasArkKind } from "../shared/utils.js";
import { BaseRoot } from "./root.js";
import { defineRightwardIntersections } from "./utils.js";
const implementation = implementNode({
kind: "union",
hasAssociatedError: true,
collapsibleKey: "branches",
keys: {
ordered: {},
branches: {
child: true,
parse: (schema, ctx) => {
const branches = [];
for (const branchSchema of schema) {
const branchNodes = hasArkKind(branchSchema, "root") ?
branchSchema.branches
: ctx.$.parseSchema(branchSchema).branches;
for (const node of branchNodes) {
if (node.hasKind("morph")) {
const matchingMorphIndex = branches.findIndex(matching => matching.hasKind("morph") && matching.hasEqualMorphs(node));
if (matchingMorphIndex === -1)
branches.push(node);
else {
const matchingMorph = branches[matchingMorphIndex];
branches[matchingMorphIndex] = ctx.$.node("morph", {
...matchingMorph.inner,
in: matchingMorph.rawIn.rawOr(node.rawIn)
});
}
}
else
branches.push(node);
}
}
if (!ctx.def.ordered)
branches.sort((l, r) => (l.hash < r.hash ? -1 : 1));
return branches;
}
}
},
normalize: schema => (isArray(schema) ? { branches: schema } : schema),
reduce: (inner, $) => {
const reducedBranches = reduceBranches(inner);
if (reducedBranches.length === 1)
return reducedBranches[0];
if (reducedBranches.length === inner.branches.length)
return;
return $.node("union", {
...inner,
branches: reducedBranches
}, { prereduced: true });
},
defaults: {
description: node => node.distribute(branch => branch.description, describeBranches),
expected: ctx => {
const byPath = groupBy(ctx.errors, "propString");
const pathDescriptions = Object.entries(byPath).map(([path, errors]) => {
const branchesAtPath = [];
for (const errorAtPath of errors)
appendUnique(branchesAtPath, errorAtPath.expected);
const expected = describeBranches(branchesAtPath);
// if there are multiple actual descriptions that differ,
// just fall back to printable, which is the most specific
const actual = errors.every(e => e.actual === errors[0].actual) ?
errors[0].actual
: printable(errors[0].data);
return `${path && `${path} `}must be ${expected}${actual && ` (was ${actual})`}`;
});
return describeBranches(pathDescriptions);
},
problem: ctx => ctx.expected,
message: ctx => {
if (ctx.problem[0] === "[") {
// clarify paths like [1], [0][1], and ["key!"] that could be confusing
return `value at ${ctx.problem}`;
}
return ctx.problem;
}
},
intersections: {
union: (l, r, ctx) => {
if (l.isNever !== r.isNever) {
// if exactly one operand is never, we can use it to discriminate based on presence
return Disjoint.init("presence", l, r);
}
let resultBranches;
if (l.ordered) {
if (r.ordered) {
throwParseError(writeOrderedIntersectionMessage(l.expression, r.expression));
}
resultBranches = intersectBranches(r.branches, l.branches, ctx);
if (resultBranches instanceof Disjoint)
resultBranches.invert();
}
else
resultBranches = intersectBranches(l.branches, r.branches, ctx);
if (resultBranches instanceof Disjoint)
return resultBranches;
return ctx.$.parseSchema(l.ordered || r.ordered ?
{
branches: resultBranches,
ordered: true
}
: { branches: resultBranches });
},
...defineRightwardIntersections("union", (l, r, ctx) => {
const branches = intersectBranches(l.branches, [r], ctx);
if (branches instanceof Disjoint)
return branches;
if (branches.length === 1)
return branches[0];
return ctx.$.parseSchema(l.ordered ? { branches, ordered: true } : { branches });
})
}
});
export class UnionNode extends BaseRoot {
isBoolean = this.branches.length === 2 &&
this.branches[0].hasUnit(false) &&
this.branches[1].hasUnit(true);
get branchGroups() {
const branchGroups = [];
let firstBooleanIndex = -1;
for (const branch of this.branches) {
if (branch.hasKind("unit") && branch.domain === "boolean") {
if (firstBooleanIndex === -1) {
firstBooleanIndex = branchGroups.length;
branchGroups.push(branch);
}
else
branchGroups[firstBooleanIndex] = $ark.intrinsic.boolean;
continue;
}
branchGroups.push(branch);
}
return branchGroups;
}
unitBranches = this.branches.filter((n) => n.rawIn.hasKind("unit"));
discriminant = this.discriminate();
discriminantJson = this.discriminant ? discriminantToJson(this.discriminant) : null;
expression = this.distribute(n => n.nestableExpression, expressBranches);
createBranchedOptimisticRootApply() {
return (data, onFail) => {
const optimisticResult = this.traverseOptimistic(data);
if (optimisticResult !== unset)
return optimisticResult;
const ctx = new Traversal(data, this.$.resolvedConfig);
this.traverseApply(data, ctx);
return ctx.finalize(onFail);
};
}
get shallowMorphs() {
return this.branches.reduce((morphs, branch) => appendUnique(morphs, branch.shallowMorphs), []);
}
get defaultShortDescription() {
return this.distribute(branch => branch.defaultShortDescription, describeBranches);
}
innerToJsonSchema(ctx) {
// special case to simplify { const: true } | { const: false }
// to the canonical JSON Schema representation { type: "boolean" }
if (this.branchGroups.length === 1 &&
this.branchGroups[0].equals($ark.intrinsic.boolean))
return { type: "boolean" };
const jsonSchemaBranches = this.branchGroups.map(group => group.toJsonSchemaRecurse(ctx));
if (jsonSchemaBranches.every((branch) =>
// iff all branches are pure unit values with no metadata,
// we can simplify the representation to an enum
Object.keys(branch).length === 1 && hasKey(branch, "const"))) {
return {
enum: jsonSchemaBranches.map(branch => branch.const)
};
}
return {
anyOf: jsonSchemaBranches
};
}
traverseAllows = (data, ctx) => this.branches.some(b => b.traverseAllows(data, ctx));
traverseApply = (data, ctx) => {
const errors = [];
for (let i = 0; i < this.branches.length; i++) {
ctx.pushBranch();
this.branches[i].traverseApply(data, ctx);
if (!ctx.hasError()) {
if (this.branches[i].includesTransform)
return ctx.queuedMorphs.push(...ctx.popBranch().queuedMorphs);
return ctx.popBranch();
}
errors.push(ctx.popBranch().error);
}
ctx.errorFromNodeContext({ code: "union", errors, meta: this.meta });
};
traverseOptimistic = (data) => {
for (let i = 0; i < this.branches.length; i++) {
const branch = this.branches[i];
if (branch.traverseAllows(data)) {
if (branch.contextFreeMorph)
return branch.contextFreeMorph(data);
// if we're calling this function and the matching branch didn't have
// a context-free morph, it shouldn't have morphs at all
return data;
}
}
return unset;
};
compile(js) {
if (!this.discriminant ||
// if we have a union of two units like `boolean`, the
// undiscriminated compilation will be just as fast
(this.unitBranches.length === this.branches.length &&
this.branches.length === 2))
return this.compileIndiscriminable(js);
// we need to access the path as optional so we don't throw if it isn't present
let condition = this.discriminant.optionallyChainedPropString;
if (this.discriminant.kind === "domain")
condition = `typeof ${condition} === "object" ? ${condition} === null ? "null" : "object" : typeof ${condition} === "function" ? "object" : typeof ${condition}`;
const cases = this.discriminant.cases;
const caseKeys = Object.keys(cases);
const { optimistic } = js;
// only the first layer can be optimistic
js.optimistic = false;
js.block(`switch(${condition})`, () => {
for (const k in cases) {
const v = cases[k];
const caseCondition = k === "default" ? k : `case ${k}`;
let caseResult;
if (v === true)
caseResult = optimistic ? "data" : "true";
else if (optimistic) {
if (v.rootApplyStrategy === "branchedOptimistic")
caseResult = js.invoke(v, { kind: "Optimistic" });
else if (v.contextFreeMorph)
caseResult = `${js.invoke(v)} ? ${registeredReference(v.contextFreeMorph)}(data) : "${unset}"`;
else
caseResult = `${js.invoke(v)} ? data : "${unset}"`;
}
else
caseResult = js.invoke(v);
js.line(`${caseCondition}: return ${caseResult}`);
}
return js;
});
if (js.traversalKind === "Allows") {
js.return(optimistic ? `"${unset}"` : false);
return;
}
const expected = describeBranches(this.discriminant.kind === "domain" ?
caseKeys.map(k => {
const jsTypeOf = k.slice(1, -1);
return jsTypeOf === "function" ?
domainDescriptions.object
: domainDescriptions[jsTypeOf];
})
: caseKeys);
const serializedPathSegments = this.discriminant.path.map(k => typeof k === "symbol" ? registeredReference(k) : JSON.stringify(k));
const serializedExpected = JSON.stringify(expected);
const serializedActual = this.discriminant.kind === "domain" ?
`${serializedTypeOfDescriptions}[${condition}]`
: `${serializedPrintable}(${condition})`;
js.line(`ctx.errorFromNodeContext({
code: "predicate",
expected: ${serializedExpected},
actual: ${serializedActual},
relativePath: [${serializedPathSegments}],
meta: ${this.compiledMeta}
})`);
}
compileIndiscriminable(js) {
if (js.traversalKind === "Apply") {
js.const("errors", "[]");
for (const branch of this.branches) {
js.line("ctx.pushBranch()")
.line(js.invoke(branch))
.if("!ctx.hasError()", () => js.return(branch.includesTransform ?
"ctx.queuedMorphs.push(...ctx.popBranch().queuedMorphs)"
: "ctx.popBranch()"))
.line("errors.push(ctx.popBranch().error)");
}
js.line(`ctx.errorFromNodeContext({ code: "union", errors, meta: ${this.compiledMeta} })`);
}
else {
const { optimistic } = js;
// only the first layer can be optimistic
js.optimistic = false;
for (const branch of this.branches) {
js.if(`${js.invoke(branch)}`, () => js.return(optimistic ?
branch.contextFreeMorph ?
`${registeredReference(branch.contextFreeMorph)}(data)`
: "data"
: true));
}
js.return(optimistic ? `"${unset}"` : false);
}
}
get nestableExpression() {
// avoid adding unnecessary parentheses around boolean since it's
// already collapsed to a single keyword
return this.isBoolean ? "boolean" : `(${this.expression})`;
}
discriminate() {
if (this.branches.length < 2 || this.isCyclic)
return null;
if (this.unitBranches.length === this.branches.length) {
const cases = flatMorph(this.unitBranches, (i, n) => [
`${n.rawIn.serializedValue}`,
n.hasKind("morph") ? n : true
]);
return {
kind: "unit",
path: [],
optionallyChainedPropString: "data",
cases
};
}
const candidates = [];
for (let lIndex = 0; lIndex < this.branches.length - 1; lIndex++) {
const l = this.branches[lIndex];
for (let rIndex = lIndex + 1; rIndex < this.branches.length; rIndex++) {
const r = this.branches[rIndex];
const result = intersectNodesRoot(l.rawIn, r.rawIn, l.$);
if (!(result instanceof Disjoint))
continue;
for (const entry of result) {
if (!entry.kind || entry.optional)
continue;
let lSerialized;
let rSerialized;
if (entry.kind === "domain") {
const lValue = entry.l;
const rValue = entry.r;
lSerialized = `"${typeof lValue === "string" ? lValue : lValue.domain}"`;
rSerialized = `"${typeof rValue === "string" ? rValue : rValue.domain}"`;
}
else if (entry.kind === "unit") {
lSerialized = entry.l.serializedValue;
rSerialized = entry.r.serializedValue;
}
else
continue;
const matching = candidates.find(d => arrayEquals(d.path, entry.path) && d.kind === entry.kind);
if (!matching) {
candidates.push({
kind: entry.kind,
cases: {
[lSerialized]: {
branchIndices: [lIndex],
condition: entry.l
},
[rSerialized]: {
branchIndices: [rIndex],
condition: entry.r
}
},
path: entry.path
});
}
else {
if (matching.cases[lSerialized]) {
matching.cases[lSerialized].branchIndices = appendUnique(matching.cases[lSerialized].branchIndices, lIndex);
}
else {
matching.cases[lSerialized] ??= {
branchIndices: [lIndex],
condition: entry.l
};
}
if (matching.cases[rSerialized]) {
matching.cases[rSerialized].branchIndices = appendUnique(matching.cases[rSerialized].branchIndices, rIndex);
}
else {
matching.cases[rSerialized] ??= {
branchIndices: [rIndex],
condition: entry.r
};
}
}
}
}
}
const viableCandidates = this.ordered ?
viableOrderedCandidates(candidates, this.branches)
: candidates;
if (!viableCandidates.length)
return null;
const ctx = createCaseResolutionContext(viableCandidates, this);
const cases = {};
for (const k in ctx.best.cases) {
const resolution = resolveCase(ctx, k);
if (resolution === null) {
cases[k] = true;
continue;
}
// if all the branches ended up back in pruned, we'd loop if we continued
// so just bail out- nothing left to discriminate
if (resolution.length === this.branches.length)
return null;
if (this.ordered) {
// ensure the original order of the pruned branches is preserved
resolution.sort((l, r) => l.originalIndex - r.originalIndex);
}
const branches = resolution.map(entry => entry.branch);
const caseNode = branches.length === 1 ?
branches[0]
: this.$.node("union", this.ordered ? { branches, ordered: true } : branches);
Object.assign(this.referencesById, caseNode.referencesById);
cases[k] = caseNode;
}
if (ctx.defaultEntries.length) {
// we don't have to worry about order here as it is always preserved
// within defaultEntries
const branches = ctx.defaultEntries.map(entry => entry.branch);
cases.default = this.$.node("union", this.ordered ? { branches, ordered: true } : branches, {
prereduced: true
});
Object.assign(this.referencesById, cases.default.referencesById);
}
return Object.assign(ctx.location, {
cases
});
}
}
const createCaseResolutionContext = (viableCandidates, node) => {
const ordered = viableCandidates.sort((l, r) => l.path.length === r.path.length ?
Object.keys(r.cases).length - Object.keys(l.cases).length
// prefer shorter paths first
: l.path.length - r.path.length);
const best = ordered[0];
const location = {
kind: best.kind,
path: best.path,
optionallyChainedPropString: optionallyChainPropString(best.path)
};
const defaultEntries = node.branches.map((branch, originalIndex) => ({
originalIndex,
branch
}));
return {
best,
location,
defaultEntries,
node
};
};
const resolveCase = (ctx, key) => {
const caseCtx = ctx.best.cases[key];
const discriminantNode = discriminantCaseToNode(caseCtx.condition, ctx.location.path, ctx.node.$);
let resolvedEntries = [];
const nextDefaults = [];
for (let i = 0; i < ctx.defaultEntries.length; i++) {
const entry = ctx.defaultEntries[i];
if (caseCtx.branchIndices.includes(entry.originalIndex)) {
const pruned = pruneDiscriminant(ctx.node.branches[entry.originalIndex], ctx.location);
if (pruned === null) {
// if any branch of the union has no constraints (i.e. is
// unknown), the others won't affect the resolution type, but could still
// remove additional cases from defaultEntries
resolvedEntries = null;
}
else {
resolvedEntries?.push({
originalIndex: entry.originalIndex,
branch: pruned
});
}
}
else if (
// we shouldn't need a special case for alias to avoid the below
// once alias resolution issues are improved:
// https://github.com/arktypeio/arktype/issues/1026
entry.branch.hasKind("alias") &&
discriminantNode.hasKind("domain") &&
discriminantNode.domain === "object")
resolvedEntries?.push(entry);
else {
if (entry.branch.rawIn.overlaps(discriminantNode)) {
// include cases where an object not including the
// discriminant path might have that value present as an undeclared key
const overlapping = pruneDiscriminant(entry.branch, ctx.location);
resolvedEntries?.push({
originalIndex: entry.originalIndex,
branch: overlapping
});
}
nextDefaults.push(entry);
}
}
ctx.defaultEntries = nextDefaults;
return resolvedEntries;
};
const viableOrderedCandidates = (candidates, originalBranches) => {
const viableCandidates = candidates.filter(candidate => {
const caseGroups = Object.values(candidate.cases).map(caseCtx => caseCtx.branchIndices);
// compare each group against all subsequent groups.
for (let i = 0; i < caseGroups.length - 1; i++) {
const currentGroup = caseGroups[i];
for (let j = i + 1; j < caseGroups.length; j++) {
const nextGroup = caseGroups[j];
// for each group pair, check for branches whose order was reversed
for (const currentIndex of currentGroup) {
for (const nextIndex of nextGroup) {
if (currentIndex > nextIndex) {
if (originalBranches[currentIndex].overlaps(originalBranches[nextIndex])) {
// if the order was not preserved and the branches overlap,
// this is not a viable discriminant as it cannot guarantee the same behavior
return false;
}
}
}
}
}
}
// branch groups preserved order for non-disjoint pairs and is viable
return true;
});
return viableCandidates;
};
const discriminantCaseToNode = (caseDiscriminant, path, $) => {
let node = caseDiscriminant === "undefined" ? $.node("unit", { unit: undefined })
: caseDiscriminant === "null" ? $.node("unit", { unit: null })
: caseDiscriminant === "boolean" ? $.units([true, false])
: caseDiscriminant;
for (let i = path.length - 1; i >= 0; i--) {
const key = path[i];
node = $.node("intersection", typeof key === "number" ?
{
proto: "Array",
// create unknown for preceding elements (could be optimized with safe imports)
sequence: [...range(key).map(_ => ({})), node]
}
: {
domain: "object",
required: [{ key, value: node }]
});
}
return node;
};
const optionallyChainPropString = (path) => path.reduce((acc, k) => acc + compileLiteralPropAccess(k, true), "data");
const serializedTypeOfDescriptions = registeredReference(jsTypeOfDescriptions);
const serializedPrintable = registeredReference(printable);
export const Union = {
implementation,
Node: UnionNode
};
const discriminantToJson = (discriminant) => ({
kind: discriminant.kind,
path: discriminant.path.map(k => typeof k === "string" ? k : compileSerializedValue(k)),
cases: flatMorph(discriminant.cases, (k, node) => [
k,
node === true ? node
: node.hasKind("union") && node.discriminantJson ? node.discriminantJson
: node.json
])
});
const describeExpressionOptions = {
delimiter: " | ",
finalDelimiter: " | "
};
const expressBranches = (expressions) => describeBranches(expressions, describeExpressionOptions);
export const describeBranches = (descriptions, opts) => {
const delimiter = opts?.delimiter ?? ", ";
const finalDelimiter = opts?.finalDelimiter ?? " or ";
if (descriptions.length === 0)
return "never";
if (descriptions.length === 1)
return descriptions[0];
if ((descriptions.length === 2 &&
descriptions[0] === "false" &&
descriptions[1] === "true") ||
(descriptions[0] === "true" && descriptions[1] === "false"))
return "boolean";
// keep track of seen descriptions to avoid duplication
const seen = {};
const unique = descriptions.filter(s => (seen[s] ? false : (seen[s] = true)));
const last = unique.pop();
return `${unique.join(delimiter)}${unique.length ? finalDelimiter : ""}${last}`;
};
export const intersectBranches = (l, r, ctx) => {
// If the corresponding r branch is identified as a subtype of an l branch, the
// value at rIndex is set to null so we can avoid including previous/future
// intersections in the reduced result.
const batchesByR = r.map(() => []);
for (let lIndex = 0; lIndex < l.length; lIndex++) {
let candidatesByR = {};
for (let rIndex = 0; rIndex < r.length; rIndex++) {
if (batchesByR[rIndex] === null) {
// rBranch is a subtype of an lBranch and
// will not yield any distinct intersection
continue;
}
if (l[lIndex].equals(r[rIndex])) {
// Combination of subtype and supertype cases
batchesByR[rIndex] = null;
candidatesByR = {};
break;
}
const branchIntersection = intersectOrPipeNodes(l[lIndex], r[rIndex], ctx);
if (branchIntersection instanceof Disjoint) {
// Doesn't tell us anything useful about their relationships
// with other branches
continue;
}
if (branchIntersection.equals(l[lIndex])) {
// If the current l branch is a subtype of r, intersections
// with previous and remaining branches of r won't lead to
// distinct intersections.
batchesByR[rIndex].push(l[lIndex]);
candidatesByR = {};
break;
}
if (branchIntersection.equals(r[rIndex])) {
// If the current r branch is a subtype of l, set its batch to
// null, removing any previous intersections and preventing any
// of its remaining intersections from being computed.
batchesByR[rIndex] = null;
}
else {
// If neither l nor r is a subtype of the other, add their
// intersection as a candidate (could still be removed if it is
// determined l or r is a subtype of a remaining branch).
candidatesByR[rIndex] = branchIntersection;
}
}
for (const rIndex in candidatesByR) {
// batchesByR at rIndex should never be null if it is in candidatesByR
batchesByR[rIndex][lIndex] = candidatesByR[rIndex];
}
}
// Compile the reduced intersection result, including:
// 1. Remaining candidates resulting from distinct intersections or strict subtypes of r
// 2. Original r branches corresponding to indices with a null batch (subtypes of l)
const resultBranches = batchesByR.flatMap(
// ensure unions returned from branchable intersections like sequence are flattened
(batch, i) => batch?.flatMap(branch => branch.branches) ?? r[i]);
return resultBranches.length === 0 ?
Disjoint.init("union", l, r)
: resultBranches;
};
export const reduceBranches = ({ branches, ordered }) => {
if (branches.length < 2)
return branches;
const uniquenessByIndex = branches.map(() => true);
for (let i = 0; i < branches.length; i++) {
for (let j = i + 1; j < branches.length && uniquenessByIndex[i] && uniquenessByIndex[j]; j++) {
if (branches[i].equals(branches[j])) {
// if the two branches are equal, only "j" is marked as
// redundant so at least one copy could still be included in
// the final set of branches.
uniquenessByIndex[j] = false;
continue;
}
const intersection = intersectNodesRoot(branches[i].rawIn, branches[j].rawIn, branches[0].$);
if (intersection instanceof Disjoint)
continue;
if (!ordered)
assertDeterminateOverlap(branches[i], branches[j]);
if (intersection.equals(branches[i].rawIn)) {
// preserve ordered branches that are a subtype of a subsequent branch
uniquenessByIndex[i] = !!ordered;
}
else if (intersection.equals(branches[j].rawIn))
uniquenessByIndex[j] = false;
}
}
return branches.filter((_, i) => uniquenessByIndex[i]);
};
const assertDeterminateOverlap = (l, r) => {
if (!l.includesTransform && !r.includesTransform)
return;
if (!arrayEquals(l.shallowMorphs, r.shallowMorphs)) {
throwParseError(writeIndiscriminableMorphMessage(l.expression, r.expression));
}
if (!arrayEquals(l.flatMorphs, r.flatMorphs, {
isEqual: (l, r) => l.propString === r.propString &&
(l.node.hasKind("morph") && r.node.hasKind("morph") ?
l.node.hasEqualMorphs(r.node)
: l.node.hasKind("intersection") && r.node.hasKind("intersection") ?
l.node.structure?.structuralMorphRef ===
r.node.structure?.structuralMorphRef
: false)
})) {
throwParseError(writeIndiscriminableMorphMessage(l.expression, r.expression));
}
};
export const pruneDiscriminant = (discriminantBranch, discriminantCtx) => discriminantBranch.transform((nodeKind, inner) => {
if (nodeKind === "domain" || nodeKind === "unit")
return null;
return inner;
}, {
shouldTransform: (node, ctx) => {
// safe to cast here as index nodes are never discriminants
const propString = optionallyChainPropString(ctx.path);
if (!discriminantCtx.optionallyChainedPropString.startsWith(propString))
return false;
if (node.hasKind("domain") && node.domain === "object")
// if we've already checked a path at least as long as the current one,
// we don't need to revalidate that we're in an object
return true;
if ((node.hasKind("domain") || discriminantCtx.kind === "unit") &&
propString === discriminantCtx.optionallyChainedPropString)
// if the discriminant has already checked the domain at the current path
// (or a unit literal, implying a domain), we don't need to recheck it
return true;
// we don't need to recurse into index nodes as they will never
// have a required path therefore can't be used to discriminate
return node.children.length !== 0 && node.kind !== "index";
}
});
export const writeIndiscriminableMorphMessage = (lDescription, rDescription) => `An unordered union of a type including a morph and a type with overlapping input is indeterminate:
Left: ${lDescription}
Right: ${rDescription}`;
export const writeOrderedIntersectionMessage = (lDescription, rDescription) => `The intersection of two ordered unions is indeterminate:
Left: ${lDescription}
Right: ${rDescription}`;

41
frontend/node_modules/@ark/schema/out/roots/unit.d.ts generated vendored Normal file
View File

@@ -0,0 +1,41 @@
import { type Domain, type JsonPrimitive } from "@ark/util";
import type { BaseErrorContext, BaseNormalizedSchema, declareNode } from "../shared/declare.ts";
import { type nodeImplementationOf } from "../shared/implement.ts";
import type { JsonSchema } from "../shared/jsonSchema.ts";
import type { ToJsonSchema } from "../shared/toJsonSchema.ts";
import type { TraverseAllows } from "../shared/traversal.ts";
import { InternalBasis } from "./basis.ts";
export declare namespace Unit {
interface Schema<value = unknown> extends BaseNormalizedSchema {
readonly unit: value;
}
interface Inner<value = unknown> {
readonly unit: value;
}
interface ErrorContext<value = unknown> extends BaseErrorContext<"unit">, Inner<value> {
}
interface Declaration extends declareNode<{
kind: "unit";
schema: Schema;
normalizedSchema: Schema;
inner: Inner;
errorContext: ErrorContext;
}> {
}
type Node = UnitNode;
}
export declare class UnitNode extends InternalBasis<Unit.Declaration> {
compiledValue: JsonPrimitive;
serializedValue: string;
compiledCondition: string;
compiledNegation: string;
expression: string;
domain: Domain;
get defaultShortDescription(): string;
protected innerToJsonSchema(ctx: ToJsonSchema.Context): JsonSchema;
traverseAllows: TraverseAllows;
}
export declare const Unit: {
implementation: nodeImplementationOf<Unit.Declaration>;
Node: typeof UnitNode;
};

86
frontend/node_modules/@ark/schema/out/roots/unit.js generated vendored Normal file
View File

@@ -0,0 +1,86 @@
import { domainDescriptions, domainOf, printable } from "@ark/util";
import { Disjoint } from "../shared/disjoint.js";
import { defaultValueSerializer, implementNode } from "../shared/implement.js";
import { $ark } from "../shared/registry.js";
import { InternalBasis } from "./basis.js";
import { defineRightwardIntersections } from "./utils.js";
const implementation = implementNode({
kind: "unit",
hasAssociatedError: true,
keys: {
unit: {
preserveUndefined: true,
serialize: schema => schema instanceof Date ?
schema.toISOString()
: defaultValueSerializer(schema)
}
},
normalize: schema => schema,
defaults: {
description: node => printable(node.unit),
problem: ({ expected, actual }) => `${expected === actual ? `must be reference equal to ${expected} (serialized to the same value)` : `must be ${expected} (was ${actual})`}`
},
intersections: {
unit: (l, r) => Disjoint.init("unit", l, r),
...defineRightwardIntersections("unit", (l, r) => {
if (r.allows(l.unit))
return l;
// will always be a disjoint at this point, but we try to use
// a domain Disjoint if possible since it's better for discrimination
const rBasis = r.hasKind("intersection") ? r.basis : r;
if (rBasis) {
const rDomain = rBasis.hasKind("domain") ? rBasis : $ark.intrinsic.object;
if (l.domain !== rDomain.domain) {
const lDomainDisjointValue = (l.domain === "undefined" ||
l.domain === "null" ||
l.domain === "boolean") ?
l.domain
: $ark.intrinsic[l.domain];
return Disjoint.init("domain", lDomainDisjointValue, rDomain);
}
}
return Disjoint.init("assignability", l, r.hasKind("intersection") ?
r.children.find(rConstraint => !rConstraint.allows(l.unit))
: r);
})
}
});
export class UnitNode extends InternalBasis {
compiledValue = this.json.unit;
serializedValue = typeof this.unit === "string" || this.unit instanceof Date ?
JSON.stringify(this.compiledValue)
: `${this.compiledValue}`;
compiledCondition = compileEqualityCheck(this.unit, this.serializedValue);
compiledNegation = compileEqualityCheck(this.unit, this.serializedValue, "negated");
expression = printable(this.unit);
domain = domainOf(this.unit);
get defaultShortDescription() {
return this.domain === "object" ?
domainDescriptions.object
: this.description;
}
innerToJsonSchema(ctx) {
return (
// this is the more standard JSON schema representation, especially for Open API
this.unit === null ? { type: "null" }
: $ark.intrinsic.jsonPrimitive.allows(this.unit) ? { const: this.unit }
: ctx.fallback.unit({ code: "unit", base: {}, unit: this.unit }));
}
traverseAllows = this.unit instanceof Date ?
data => data instanceof Date && data.toISOString() === this.compiledValue
: Number.isNaN(this.unit) ? data => Number.isNaN(data)
: data => data === this.unit;
}
export const Unit = {
implementation,
Node: UnitNode
};
const compileEqualityCheck = (unit, serializedValue, negated) => {
if (unit instanceof Date) {
const condition = `data instanceof Date && data.toISOString() === ${serializedValue}`;
return negated ? `!(${condition})` : condition;
}
if (Number.isNaN(unit))
return `${negated ? "!" : ""}Number.isNaN(data)`;
return `data ${negated ? "!" : "="}== ${serializedValue}`;
};

View File

@@ -0,0 +1,3 @@
import { type RootIntersection, type RootKind } from "../shared/implement.ts";
import type { schemaKindRightOf } from "./root.ts";
export declare const defineRightwardIntersections: <kind extends RootKind>(kind: kind, implementation: RootIntersection<kind, schemaKindRightOf<kind>>) => { [k in schemaKindRightOf<kind>]: RootIntersection<kind, k>; };

6
frontend/node_modules/@ark/schema/out/roots/utils.js generated vendored Normal file
View File

@@ -0,0 +1,6 @@
import { flatMorph } from "@ark/util";
import { schemaKindsRightOf } from "../shared/implement.js";
export const defineRightwardIntersections = (kind, implementation) => flatMorph(schemaKindsRightOf(kind), (i, kind) => [
kind,
implementation
]);