@ark/schema
Advanced tools
Comparing version 0.30.0 to 0.31.0
@@ -25,4 +25,3 @@ import type { ArkRegistry, mutable, requireKeys, show } from "@ark/util"; | ||
export type NodeConfig<kind extends NodeKind = NodeKind> = NodeConfigsByKind[kind]; | ||
type UnknownNodeConfig = { | ||
description?: DescriptionWriter; | ||
export interface UnknownErrorWriters { | ||
expected?: ExpectedWriter; | ||
@@ -32,3 +31,6 @@ actual?: ActualWriter; | ||
message?: MessageWriter; | ||
}; | ||
} | ||
interface UnknownNodeConfig extends UnknownErrorWriters { | ||
description?: DescriptionWriter; | ||
} | ||
export type ResolvedUnknownNodeConfig = requireKeys<UnknownNodeConfig, "description">; | ||
@@ -35,0 +37,0 @@ export declare const configure: (config: ArkConfig) => ArkConfig; |
import { append, appendUnique, capitalize, isArray, throwInternalError, throwParseError } from "@ark/util"; | ||
import { BaseNode } from "./node.js"; | ||
import { Disjoint } from "./shared/disjoint.js"; | ||
import { compileErrorContext, constraintKeys } from "./shared/implement.js"; | ||
import { compileObjectLiteral, constraintKeys } from "./shared/implement.js"; | ||
import { intersectNodesRoot, intersectOrPipeNodes } from "./shared/intersections.js"; | ||
@@ -25,3 +25,3 @@ import { $ark } from "./shared/registry.js"; | ||
if (!this.traverseAllows(data, ctx)) | ||
ctx.error(this.errorContext); | ||
ctx.errorFromNodeContext(this.errorContext); | ||
}; | ||
@@ -32,10 +32,15 @@ compile(js) { | ||
else { | ||
js.if(this.compiledNegation, () => js.line(`${js.ctx}.error(${this.compiledErrorContext})`)); | ||
js.if(this.compiledNegation, () => js.line(`${js.ctx}.errorFromNodeContext(${this.compiledErrorContext})`)); | ||
} | ||
} | ||
get errorContext() { | ||
return { code: this.kind, description: this.description, ...this.inner }; | ||
return { | ||
code: this.kind, | ||
description: this.description, | ||
meta: this.meta, | ||
...this.inner | ||
}; | ||
} | ||
get compiledErrorContext() { | ||
return compileErrorContext(this.errorContext); | ||
return compileObjectLiteral(this.errorContext); | ||
} | ||
@@ -42,0 +47,0 @@ } |
@@ -33,2 +33,3 @@ import { Callable, type GuardablePredicate, type JsonStructure, type Key, type array, type conform, type listable, type mutable } from "@ark/util"; | ||
readonly referencesById: Record<string, BaseNode>; | ||
readonly compiledMeta: string; | ||
protected cacheGetter<name extends keyof this>(name: name, value: this[name]): this[name]; | ||
@@ -35,0 +36,0 @@ get description(): string; |
@@ -46,2 +46,3 @@ import { Callable, appendUnique, flatMorph, includes, isArray, isEmptyObject, stringifyPath, throwError } from "@ark/util"; | ||
referencesById = this.children.reduce((result, child) => Object.assign(result, child.referencesById), { [this.id]: this }); | ||
compiledMeta = JSON.stringify(this.metaJson); | ||
cacheGetter(name, value) { | ||
@@ -48,0 +49,0 @@ Object.defineProperty(this, name, { value }); |
import { throwParseError } from "@ark/util"; | ||
import { BaseConstraint } from "./constraint.js"; | ||
import { compileErrorContext, implementNode } from "./shared/implement.js"; | ||
import { compileObjectLiteral, implementNode } from "./shared/implement.js"; | ||
import { writeUnsupportedJsonSchemaTypeMessage } from "./shared/jsonSchema.js"; | ||
@@ -34,8 +34,9 @@ import { registeredReference } from "./shared/registry.js"; | ||
code: "predicate", | ||
description: this.description | ||
description: this.description, | ||
meta: this.meta | ||
}; | ||
compiledErrorContext = compileErrorContext(this.errorContext); | ||
compiledErrorContext = compileObjectLiteral(this.errorContext); | ||
traverseApply = (data, ctx) => { | ||
if (!this.predicate(data, ctx) && !ctx.hasError()) | ||
ctx.error(this.errorContext); | ||
if (!this.predicate(data, ctx.external) && !ctx.hasError()) | ||
ctx.errorFromNodeContext(this.errorContext); | ||
}; | ||
@@ -47,3 +48,3 @@ compile(js) { | ||
} | ||
js.if(`${this.compiledNegation} && !ctx.hasError()`, () => js.line(`ctx.error(${this.compiledErrorContext})`)); | ||
js.if(`${this.compiledNegation} && !ctx.hasError()`, () => js.line(`ctx.errorFromNodeContext(${this.compiledErrorContext})`)); | ||
} | ||
@@ -50,0 +51,0 @@ reduceJsonSchema() { |
@@ -1,2 +0,2 @@ | ||
import { compileErrorContext } from "../shared/implement.js"; | ||
import { compileObjectLiteral } from "../shared/implement.js"; | ||
import { BaseRoot } from "./root.js"; | ||
@@ -6,9 +6,14 @@ export class InternalBasis extends BaseRoot { | ||
if (!this.traverseAllows(data, ctx)) | ||
ctx.error(this.errorContext); | ||
ctx.errorFromNodeContext(this.errorContext); | ||
}; | ||
get errorContext() { | ||
return { code: this.kind, description: this.description, ...this.inner }; | ||
return { | ||
code: this.kind, | ||
description: this.description, | ||
meta: this.meta, | ||
...this.inner | ||
}; | ||
} | ||
get compiledErrorContext() { | ||
return compileErrorContext(this.errorContext); | ||
return compileObjectLiteral(this.errorContext); | ||
} | ||
@@ -19,5 +24,5 @@ compile(js) { | ||
else { | ||
js.if(this.compiledNegation, () => js.line(`${js.ctx}.error(${this.compiledErrorContext})`)); | ||
js.if(this.compiledNegation, () => js.line(`${js.ctx}.errorFromNodeContext(${this.compiledErrorContext})`)); | ||
} | ||
} | ||
} |
@@ -169,3 +169,3 @@ import { appendUnique, arrayEquals, domainDescriptions, flatMorph, groupBy, isArray, jsTypeOfDescriptions, printable, throwParseError } from "@ark/util"; | ||
} | ||
ctx.error({ code: "union", errors }); | ||
ctx.errorFromNodeContext({ code: "union", errors, meta: this.meta }); | ||
}; | ||
@@ -210,6 +210,9 @@ compile(js) { | ||
: `${serializedPrintable}(${condition})`; | ||
js.line(`ctx.error({ | ||
// TODO: should have its own error code | ||
js.line(`ctx.errorFromNodeContext({ | ||
code: "predicate", | ||
expected: ${serializedExpected}, | ||
actual: ${serializedActual}, | ||
relativePath: [${serializedPathSegments}] | ||
relativePath: [${serializedPathSegments}], | ||
meta: ${this.compiledMeta} | ||
})`); | ||
@@ -227,3 +230,3 @@ } | ||
.line("errors.push(ctx.popBranch().error)")); | ||
js.line(`ctx.error({ code: "union", errors })`); | ||
js.line(`ctx.errorFromNodeContext({ code: "union", errors, meta: ${this.compiledMeta} })`); | ||
} | ||
@@ -230,0 +233,0 @@ else { |
@@ -48,3 +48,2 @@ import { ParseError, type JsonStructure, type anyOrNever, type array, type conform, type flattenListable, type listable, type noSuggest } from "@ark/util"; | ||
}; | ||
readonly json: JsonStructure; | ||
exportedNames: string[]; | ||
@@ -59,2 +58,4 @@ readonly aliases: Record<string, unknown>; | ||
get internal(): this; | ||
private _json; | ||
get json(): JsonStructure; | ||
defineSchema<def extends RootSchema>(def: def): def; | ||
@@ -61,0 +62,0 @@ generic: GenericRootParser; |
@@ -29,3 +29,2 @@ import { ParseError, flatMorph, hasDomain, isArray, isThunk, printable, throwInternalError, throwParseError } from "@ark/util"; | ||
resolutions = {}; | ||
json = {}; | ||
exportedNames = []; | ||
@@ -87,2 +86,10 @@ aliases = {}; | ||
} | ||
// json is populated when the scope is exported, so ensure it is populated | ||
// before allowing external access | ||
_json; | ||
get json() { | ||
if (!this._json) | ||
this.export(); | ||
return this._json; | ||
} | ||
defineSchema(def) { | ||
@@ -265,3 +272,3 @@ return def; | ||
this._exportedResolutions = resolutionsOfModule(this, this._exports); | ||
Object.assign(this.json, resolutionsToJson(this._exportedResolutions)); | ||
this._json = resolutionsToJson(this._exportedResolutions); | ||
Object.assign(this.resolutions, this._exportedResolutions); | ||
@@ -268,0 +275,0 @@ this.references = Object.values(this.referencesById); |
import type { merge, show } from "@ark/util"; | ||
import type { UnknownErrorWriters } from "../config.ts"; | ||
import type { nodeOfKind, reducibleKindOf } from "../kinds.ts"; | ||
@@ -9,3 +10,3 @@ import type { Disjoint } from "./disjoint.ts"; | ||
}; | ||
export interface BaseMeta extends JsonSchema.Meta { | ||
export interface BaseMeta extends JsonSchema.Meta, UnknownErrorWriters { | ||
alias?: string; | ||
@@ -39,2 +40,3 @@ } | ||
readonly code: kind; | ||
readonly meta: BaseMeta; | ||
} | ||
@@ -41,0 +43,0 @@ export type defaultErrorContext<d extends DeclarationInput> = show<BaseErrorContext<d["kind"]> & d["inner"]>; |
@@ -1,3 +0,4 @@ | ||
import { CastableBase, ReadonlyArray, ReadonlyPath, type array, type propwiseXor, type show } from "@ark/util"; | ||
import { CastableBase, ReadonlyArray, ReadonlyPath, type array, type merge, type propwiseXor, type show } from "@ark/util"; | ||
import type { Prerequisite, errorContext } from "../kinds.ts"; | ||
import type { BaseMeta } from "./declare.ts"; | ||
import type { NodeKind } from "./implement.ts"; | ||
@@ -65,3 +66,8 @@ import type { StandardSchemaV1 } from "./standardSchema.ts"; | ||
}; | ||
export type ArkErrorContextInput<code extends ArkErrorCode = ArkErrorCode> = ArkErrorContextInputsByCode[code]; | ||
export type ArkErrorContextInput<code extends ArkErrorCode = ArkErrorCode> = merge<ArkErrorContextInputsByCode[code], { | ||
meta?: BaseMeta; | ||
}>; | ||
export type NodeErrorContextInput<code extends ArkErrorCode = ArkErrorCode> = ArkErrorContextInputsByCode[code] & { | ||
meta: BaseMeta; | ||
}; | ||
export type MessageContext<code extends ArkErrorCode = ArkErrorCode> = Omit<ArkError<code>, "message">; | ||
@@ -68,0 +74,0 @@ export type ProblemContext<code extends ArkErrorCode = ArkErrorCode> = Omit<MessageContext<code>, "problem">; |
@@ -9,2 +9,3 @@ import { CastableBase, ReadonlyArray, ReadonlyPath, append, defineProperties, stringifyPath } from "@ark/util"; | ||
input; | ||
// TS gets confused by <code>, so internally we just use the base type for input | ||
constructor(input, ctx) { | ||
@@ -33,12 +34,20 @@ super(); | ||
get expected() { | ||
return (this.input.expected ?? this.nodeConfig.expected?.(this.input)); | ||
return (this.input.expected ?? | ||
this.meta?.expected?.(this.input) ?? | ||
this.nodeConfig.expected?.(this.input)); | ||
} | ||
get actual() { | ||
return this.input.actual ?? this.nodeConfig.actual?.(this.data); | ||
return (this.input.actual ?? | ||
this.meta?.actual?.(this.data) ?? | ||
this.nodeConfig.actual?.(this.data)); | ||
} | ||
get problem() { | ||
return this.input.problem ?? this.nodeConfig.problem(this); | ||
return (this.input.problem ?? | ||
this.meta?.problem?.(this) ?? | ||
this.nodeConfig.problem(this)); | ||
} | ||
get message() { | ||
return this.input.message ?? this.nodeConfig.message(this); | ||
return (this.input.message ?? | ||
this.meta?.message?.(this) ?? | ||
this.nodeConfig.message(this)); | ||
} | ||
@@ -45,0 +54,0 @@ toString() { |
@@ -114,3 +114,3 @@ import { type Entry, type Json, type JsonStructure, type KeySet, type arrayIndexOf, type keySetOf, type listable, type requireKeys, type show } from "@ark/util"; | ||
} | ||
export declare const compileErrorContext: (ctx: object) => string; | ||
export declare const compileObjectLiteral: (ctx: object) => string; | ||
export type nodeImplementationOf<d extends BaseNodeDeclaration> = nodeImplementationInputOf<d> & { | ||
@@ -117,0 +117,0 @@ intersections: IntersectionMap<d["kind"]>; |
@@ -72,3 +72,3 @@ import { flatMorph, printable, throwParseError } from "@ark/util"; | ||
}; | ||
export const compileErrorContext = (ctx) => { | ||
export const compileObjectLiteral = (ctx) => { | ||
let result = "{ "; | ||
@@ -75,0 +75,0 @@ for (const [k, v] of Object.entries(ctx)) |
import { ReadonlyPath, type array } from "@ark/util"; | ||
import type { ResolvedArkConfig } from "../config.ts"; | ||
import type { Morph } from "../roots/morph.ts"; | ||
import { ArkError, ArkErrors, type ArkErrorCode, type ArkErrorInput } from "./errors.ts"; | ||
import { ArkError, ArkErrors, type ArkErrorCode, type ArkErrorInput, type NodeErrorContextInput } from "./errors.ts"; | ||
export type MorphsAtPath = { | ||
@@ -13,2 +13,3 @@ path: ReadonlyPath; | ||
}; | ||
export type InternalTraversalContext = Omit<TraversalContext, "error" | "mustBe" | "reject">; | ||
export declare class TraversalContext { | ||
@@ -25,2 +26,3 @@ path: PropertyKey[]; | ||
constructor(root: unknown, config: ResolvedArkConfig); | ||
get external(): this; | ||
get currentBranch(): BranchTraversalContext | undefined; | ||
@@ -34,5 +36,7 @@ queueMorphs(morphs: array<Morph>): void; | ||
get failFast(): boolean; | ||
errorFromNodeContext<input extends NodeErrorContextInput>(input: input): ArkError<input["code"]>; | ||
error<input extends ArkErrorInput>(input: input): ArkError<input extends { | ||
code: ArkErrorCode; | ||
} ? input["code"] : "predicate">; | ||
private errorFromContext; | ||
get data(): unknown; | ||
@@ -44,3 +48,3 @@ reject(input: ArkErrorInput): false; | ||
} | ||
export declare const traverseKey: <result>(key: PropertyKey, fn: () => result, ctx: TraversalContext | undefined) => result; | ||
export declare const traverseKey: <result>(key: PropertyKey, fn: () => result, ctx: InternalTraversalContext | undefined) => result; | ||
export type TraversalMethodsByKind<input = unknown> = { | ||
@@ -51,3 +55,3 @@ Allows: TraverseAllows<input>; | ||
export type TraversalKind = keyof TraversalMethodsByKind; | ||
export type TraverseAllows<data = unknown> = (data: data, ctx: TraversalContext) => boolean; | ||
export type TraverseApply<data = unknown> = (data: data, ctx: TraversalContext) => void; | ||
export type TraverseAllows<data = unknown> = (data: data, ctx: InternalTraversalContext) => boolean; | ||
export type TraverseApply<data = unknown> = (data: data, ctx: InternalTraversalContext) => void; |
@@ -16,2 +16,8 @@ import { ReadonlyPath } from "@ark/util"; | ||
} | ||
// convenience for casting from InternalTraversalContext to TraversalContext | ||
// for cases where the extra methods on the external type are expected, e.g. | ||
// a morph or predicate | ||
get external() { | ||
return this; | ||
} | ||
get currentBranch() { | ||
@@ -109,2 +115,5 @@ return this.branches.at(-1); | ||
} | ||
errorFromNodeContext(input) { | ||
return this.errorFromContext(input); | ||
} | ||
error(input) { | ||
@@ -116,2 +125,5 @@ const errCtx = typeof input === "object" ? | ||
: { code: "predicate", expected: input }; | ||
return this.errorFromContext(errCtx); | ||
} | ||
errorFromContext(errCtx) { | ||
const error = new ArkError(errCtx, this); | ||
@@ -118,0 +130,0 @@ if (this.currentBranch) |
@@ -74,3 +74,3 @@ import { append, printable, throwParseError, unset } from "@ark/util"; | ||
else if (this.hasKind("required")) | ||
ctx.error(this.errorContext); | ||
ctx.errorFromNodeContext(this.errorContext); | ||
else if (this.hasDefault()) | ||
@@ -83,4 +83,5 @@ ctx.queueMorphs(this.defaultValueMorphs); | ||
js.else(() => { | ||
if (js.traversalKind === "Apply") | ||
return js.line(`ctx.error(${this.compiledErrorContext})`); | ||
if (js.traversalKind === "Apply") { | ||
return js.line(`ctx.errorFromNodeContext(${this.compiledErrorContext})`); | ||
} | ||
else | ||
@@ -87,0 +88,0 @@ return js.return(false); |
import type { BaseErrorContext, declareNode } from "../shared/declare.ts"; | ||
import type { ArkErrorContextInput } from "../shared/errors.ts"; | ||
import type { NodeErrorContextInput } from "../shared/errors.ts"; | ||
import { type nodeImplementationOf } from "../shared/implement.ts"; | ||
@@ -23,3 +23,3 @@ import { BaseProp, type Prop } from "./prop.ts"; | ||
expression: string; | ||
errorContext: ArkErrorContextInput<"required">; | ||
errorContext: NodeErrorContextInput<"required">; | ||
compiledErrorContext: string; | ||
@@ -26,0 +26,0 @@ } |
@@ -1,2 +0,2 @@ | ||
import { compileErrorContext, implementNode } from "../shared/implement.js"; | ||
import { compileObjectLiteral, implementNode } from "../shared/implement.js"; | ||
import { BaseProp, intersectProps } from "./prop.js"; | ||
@@ -30,5 +30,6 @@ const implementation = implementNode({ | ||
missingValueDescription: this.value.shortDescription, | ||
relativePath: [this.key] | ||
relativePath: [this.key], | ||
meta: this.meta | ||
}); | ||
compiledErrorContext = compileErrorContext(this.errorContext); | ||
compiledErrorContext = compileObjectLiteral(this.errorContext); | ||
} | ||
@@ -35,0 +36,0 @@ export const Required = { |
@@ -11,3 +11,3 @@ import { type array, type Key, type listable } from "@ark/util"; | ||
import { type RegisteredReference } from "../shared/registry.ts"; | ||
import { type TraversalContext, type TraversalKind, type TraverseAllows, type TraverseApply } from "../shared/traversal.ts"; | ||
import { type InternalTraversalContext, type TraversalKind, type TraverseAllows, type TraverseApply } from "../shared/traversal.ts"; | ||
import { makeRootAndArrayPropertiesMutable } from "../shared/utils.ts"; | ||
@@ -74,3 +74,3 @@ import type { Index } from "./index.ts"; | ||
traverseApply: TraverseApply<object>; | ||
protected _traverse: (traversalKind: TraversalKind, data: object, ctx: TraversalContext) => boolean; | ||
protected _traverse: (traversalKind: TraversalKind, data: object, ctx: InternalTraversalContext) => boolean; | ||
compile(js: NodeCompiler): void; | ||
@@ -77,0 +77,0 @@ protected compileExhaustiveEntry(js: NodeCompiler): NodeCompiler; |
@@ -373,4 +373,12 @@ import { append, conflatenate, flatMorph, printable, spliterate, throwParseError } from "@ark/util"; | ||
return false; | ||
if (this.undeclared === "reject") | ||
ctx.error({ expected: "removed", actual: "", relativePath: [k] }); | ||
if (this.undeclared === "reject") { | ||
ctx.errorFromNodeContext({ | ||
// TODO: this should have its own error code | ||
code: "predicate", | ||
expected: "removed", | ||
actual: "", | ||
relativePath: [k], | ||
meta: this.meta | ||
}); | ||
} | ||
else { | ||
@@ -435,3 +443,5 @@ ctx.queueMorphs([ | ||
js | ||
.line(`ctx.error({ expected: "removed", actual: "", relativePath: [k] })`) | ||
.line( | ||
// TODO: should have its own error code | ||
`ctx.errorFromNodeContext({ code: "predicate", expected: "removed", actual: "", relativePath: [k], meta: ${this.compiledMeta} })`) | ||
.if("ctx.failFast", () => js.return()) | ||
@@ -438,0 +448,0 @@ : js.line(`ctx.queueMorphs([data => { delete data[k]; return data }])`); |
{ | ||
"name": "@ark/schema", | ||
"version": "0.30.0", | ||
"version": "0.31.0", | ||
"license": "MIT", | ||
@@ -32,3 +32,3 @@ "author": { | ||
"dependencies": { | ||
"@ark/util": "0.30.0" | ||
"@ark/util": "0.31.0" | ||
}, | ||
@@ -35,0 +35,0 @@ "publishConfig": { |
362457
8474
+ Added@ark/util@0.31.0(transitive)
- Removed@ark/util@0.30.0(transitive)
Updated@ark/util@0.31.0