@ark/schema
Advanced tools
+20
-2
@@ -46,5 +46,9 @@ import { isNodeKind } from "./shared/implement.js"; | ||
| }; | ||
| const jsonSchemaTargetToDialect = { | ||
| "draft-2020-12": "https://json-schema.org/draft/2020-12/schema", | ||
| "draft-07": "http://json-schema.org/draft-07/schema#" | ||
| }; | ||
| export const mergeToJsonSchemaConfigs = ((baseConfig, mergedConfig) => { | ||
| if (!baseConfig) | ||
| return mergedConfig ?? {}; | ||
| return resolveTargetToDialect(mergedConfig ?? {}, undefined); | ||
| if (!mergedConfig) | ||
@@ -61,4 +65,18 @@ return baseConfig; | ||
| } | ||
| return result; | ||
| return resolveTargetToDialect(result, mergedConfig); | ||
| }); | ||
| const resolveTargetToDialect = (opts, userOpts) => { | ||
| // If user explicitly provided a dialect, use it | ||
| // Otherwise, if user provided a target, resolve it to dialect | ||
| // If neither, use the default dialect from opts | ||
| if (userOpts?.dialect !== undefined) | ||
| return opts; // dialect was already merged | ||
| if (userOpts?.target !== undefined) { | ||
| return { | ||
| ...opts, | ||
| dialect: jsonSchemaTargetToDialect[userOpts.target] | ||
| }; | ||
| } | ||
| return opts; | ||
| }; | ||
| const mergeFallbacks = (base, merged) => { | ||
@@ -65,0 +83,0 @@ base = normalizeFallback(base); |
+2
-2
@@ -11,3 +11,3 @@ import { Callable, type GuardablePredicate, type JsonStructure, type Key, type array, type conform, type listable, type mutable, type requireKeys } from "@ark/util"; | ||
| import type { NodeCompiler } from "./shared/compile.ts"; | ||
| import type { BaseNodeDeclaration, NodeMeta, TypeMeta, attachmentsOf } from "./shared/declare.ts"; | ||
| import type { BaseNodeDeclaration, TypeMeta, attachmentsOf } from "./shared/declare.ts"; | ||
| import type { ArkErrors } from "./shared/errors.ts"; | ||
@@ -154,3 +154,3 @@ import { type BasisKind, type NodeKind, type OpenNodeKind, type RefinementKind, type StructuralKind, type UnknownAttachments } from "./shared/implement.ts"; | ||
| export type DeepNodeTransformation = <kind extends NodeKind>(kind: kind, innerWithMeta: Inner<kind> & { | ||
| meta: NodeMeta; | ||
| meta: ArkEnv.meta; | ||
| }, ctx: DeepNodeTransformContext) => NormalizedSchema<kind> | null; |
+1
-2
@@ -6,3 +6,2 @@ import { type Brand, type dict } from "@ark/util"; | ||
| import type { BaseScope } from "./scope.ts"; | ||
| import type { NodeMeta } from "./shared/declare.ts"; | ||
| import { type NodeKind, type RootKind } from "./shared/implement.ts"; | ||
@@ -48,3 +47,3 @@ import { type arkKind } from "./shared/utils.ts"; | ||
| inner: dict; | ||
| meta: NodeMeta; | ||
| meta: ArkEnv.meta; | ||
| $: BaseScope; | ||
@@ -51,0 +50,0 @@ ignoreCache?: true; |
+7
-2
@@ -37,3 +37,5 @@ import { BaseConstraint } from "./constraint.js"; | ||
| traverseApply = (data, ctx) => { | ||
| if (!this.predicate(data, ctx.external) && !ctx.hasError()) | ||
| const errorCount = ctx.currentErrorCount; | ||
| if (!this.predicate(data, ctx.external) && | ||
| ctx.currentErrorCount === errorCount) | ||
| ctx.errorFromNodeContext(this.errorContext); | ||
@@ -46,3 +48,6 @@ }; | ||
| } | ||
| js.if(`${this.compiledNegation} && !ctx.hasError()`, () => js.line(`ctx.errorFromNodeContext(${this.compiledErrorContext})`)); | ||
| js.initializeErrorCount(); | ||
| js.if( | ||
| // only add the default error if the predicate didn't add one itself | ||
| `${this.compiledNegation} && ctx.currentErrorCount === errorCount`, () => js.line(`ctx.errorFromNodeContext(${this.compiledErrorContext})`)); | ||
| } | ||
@@ -49,0 +54,0 @@ reduceJsonSchema(base, ctx) { |
@@ -15,3 +15,3 @@ import { inferred, type array } from "@ark/util"; | ||
| import type { JsonSchema } from "../shared/jsonSchema.ts"; | ||
| import type { StandardSchemaV1 } from "../shared/standardSchema.ts"; | ||
| import type { StandardJSONSchemaV1, StandardSchemaV1 } from "../shared/standardSchema.ts"; | ||
| import type { ToJsonSchema } from "../shared/toJsonSchema.ts"; | ||
@@ -28,3 +28,3 @@ import { arkKind } from "../shared/utils.ts"; | ||
| /** @ts-ignore cast variance */ | ||
| out d extends InternalRootDeclaration = InternalRootDeclaration> extends BaseNode<d> implements StandardSchemaV1.WithJSONSchemaSource { | ||
| out d extends InternalRootDeclaration = InternalRootDeclaration> extends BaseNode<d> implements StandardSchemaV1, StandardJSONSchemaV1 { | ||
| readonly [arkKind]: "root"; | ||
@@ -118,2 +118,3 @@ readonly [inferred]: unknown; | ||
| export type emptyBrandNameMessage = typeof emptyBrandNameMessage; | ||
| export declare const writeInvalidJsonSchemaTargetMessage: (target: string) => string; | ||
| export declare const exclusivizeRangeSchema: <schema extends UnknownRangeSchema>(schema: schema) => schema; | ||
@@ -120,0 +121,0 @@ export type exclusivizeRangeSchema<schema extends UnknownRangeSchema> = schema extends LimitSchemaValue ? { |
+30
-10
@@ -39,9 +39,11 @@ import { arrayEquals, flatMorph, includes, inferred, omit, throwInternalError, throwParseError } from "@ark/util"; | ||
| }, | ||
| toJSONSchema: opts => { | ||
| if (opts.target && opts.target !== "draft-2020-12") { | ||
| return throwParseError(`JSONSchema target '${opts.target}' is not supported (must be "draft-2020-12")`); | ||
| } | ||
| if (opts.io === "input") | ||
| return this.rawIn.toJsonSchema(); | ||
| return this.rawOut.toJsonSchema(); | ||
| jsonSchema: { | ||
| input: opts => this.rawIn.toJsonSchema({ | ||
| target: validateStandardJsonSchemaTarget(opts.target), | ||
| ...opts.libraryOptions | ||
| }), | ||
| output: opts => this.rawOut.toJsonSchema({ | ||
| target: validateStandardJsonSchemaTarget(opts.target), | ||
| ...opts.libraryOptions | ||
| }) | ||
| } | ||
@@ -76,5 +78,10 @@ }; | ||
| if (ctx.useRefs) { | ||
| schema.$defs = flatMorph(this.references, (i, ref) => ref.isRoot() && !ref.alwaysExpandJsonSchema ? | ||
| 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; | ||
| } | ||
@@ -84,4 +91,7 @@ return schema; | ||
| toJsonSchemaRecurse(ctx) { | ||
| if (ctx.useRefs && !this.alwaysExpandJsonSchema) | ||
| return { $ref: `#/$defs/${this.id}` }; | ||
| 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); | ||
@@ -412,2 +422,12 @@ } | ||
| 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) ? | ||
@@ -414,0 +434,0 @@ { ...schema, exclusive: true } |
@@ -15,3 +15,3 @@ import type { merge, show } from "@ark/util"; | ||
| } | ||
| export interface NodeMeta extends JsonSchema.UniversalMeta, UnknownErrorConfigs { | ||
| interface NodeMeta extends JsonSchema.UniversalMeta, UnknownErrorConfigs { | ||
| alias?: string; | ||
@@ -54,3 +54,3 @@ onFail?: ArkErrors.Handler; | ||
| readonly code: kind; | ||
| readonly meta: NodeMeta; | ||
| readonly meta: ArkEnv.meta; | ||
| } | ||
@@ -57,0 +57,0 @@ export type defaultErrorContext<d extends DeclarationInput> = show<BaseErrorContext<d["kind"]> & d["inner"]>; |
| import { CastableBase, ReadonlyArray, ReadonlyPath, type JsonArray, type JsonObject, type array, type merge, type propwiseXor, type show } from "@ark/util"; | ||
| import type { Prerequisite, errorContext } from "../kinds.ts"; | ||
| import type { NodeMeta } from "./declare.ts"; | ||
| import type { NodeKind } from "./implement.ts"; | ||
@@ -126,6 +125,6 @@ import type { StandardSchemaV1 } from "./standardSchema.ts"; | ||
| export type ArkErrorContextInput<code extends ArkErrorCode = ArkErrorCode> = merge<ArkErrorContextInputsByCode[code], { | ||
| meta?: NodeMeta; | ||
| meta?: ArkEnv.meta; | ||
| }>; | ||
| export type NodeErrorContextInput<code extends ArkErrorCode = ArkErrorCode> = ArkErrorContextInputsByCode[code] & { | ||
| meta: NodeMeta; | ||
| meta: ArkEnv.meta; | ||
| }; | ||
@@ -132,0 +131,0 @@ export type MessageContext<code extends ArkErrorCode = ArkErrorCode> = Omit<ArkError<code>, "message">; |
@@ -9,3 +9,3 @@ import { type Entry, type Json, type JsonStructure, type KeySet, type arrayIndexOf, type keySetOf, type listable, type requireKeys, type show } from "@ark/util"; | ||
| import type { Structure } from "../structure/structure.ts"; | ||
| import type { BaseErrorContext, BaseNodeDeclaration, BaseNormalizedSchema, NodeMeta } from "./declare.ts"; | ||
| import type { BaseErrorContext, BaseNodeDeclaration, BaseNormalizedSchema } from "./declare.ts"; | ||
| import type { Disjoint } from "./disjoint.ts"; | ||
@@ -136,3 +136,3 @@ import { type makeRootAndArrayPropertiesMutable } from "./utils.ts"; | ||
| readonly innerHash: string; | ||
| readonly meta: NodeMeta; | ||
| readonly meta: ArkEnv.meta; | ||
| readonly metaJson: object; | ||
@@ -139,0 +139,0 @@ readonly json: object; |
| /** From https://github.com/standard-schema/standard-schema */ | ||
| /** | ||
| * The Standard Schema interface. | ||
| */ | ||
| export type StandardSchemaV1<Input = unknown, Output = Input> = { | ||
| /** | ||
| * The Standard Schema properties. | ||
| */ | ||
| readonly "~standard": StandardSchemaV1.Props<Input, Output>; | ||
| }; | ||
| export declare namespace StandardSchemaV1 { | ||
| /** | ||
| * The Standard Schema properties interface. | ||
| */ | ||
| export interface Props<Input = unknown, Output = Input> { | ||
| /** | ||
| * The version number of the standard. | ||
| */ | ||
| /** The Standard Typed interface. This is a base type extended by other specs. */ | ||
| export interface StandardTypedV1<Input = unknown, Output = Input> { | ||
| /** The Standard properties. */ | ||
| readonly "~standard": StandardTypedV1.Props<Input, Output>; | ||
| } | ||
| export declare namespace StandardTypedV1 { | ||
| /** The Standard Typed properties interface. */ | ||
| interface Props<Input = unknown, Output = Input> { | ||
| /** The version number of the standard. */ | ||
| readonly version: 1; | ||
| /** | ||
| * The vendor name of the schema library. | ||
| */ | ||
| /** The vendor name of the schema library. */ | ||
| readonly vendor: string; | ||
| /** | ||
| * Validates unknown input values. | ||
| */ | ||
| readonly validate: (value: unknown) => Result<Output> | Promise<Result<Output>>; | ||
| /** | ||
| * Inferred types associated with the schema. | ||
| */ | ||
| /** Inferred types associated with the schema. */ | ||
| readonly types?: Types<Input, Output> | undefined; | ||
| } | ||
| export interface ArkTypeProps<Input = unknown, Output = Input> extends Props<Input, Output>, StandardJSONSchemaSourceV1.Props { | ||
| readonly vendor: "arktype"; | ||
| /** The Standard Typed types interface. */ | ||
| interface Types<Input = unknown, Output = Input> { | ||
| /** The input type of the schema. */ | ||
| readonly input: Input; | ||
| /** The output type of the schema. */ | ||
| readonly output: Output; | ||
| } | ||
| /** | ||
| * The result interface of the validate function. | ||
| */ | ||
| export type Result<Output> = SuccessResult<Output> | FailureResult; | ||
| /** | ||
| * The result interface if validation succeeds. | ||
| */ | ||
| export interface SuccessResult<Output> { | ||
| /** | ||
| * The typed output value. | ||
| */ | ||
| /** Infers the input type of a Standard Typed. */ | ||
| type InferInput<Schema extends StandardTypedV1> = NonNullable<Schema["~standard"]["types"]>["input"]; | ||
| /** Infers the output type of a Standard Typed. */ | ||
| type InferOutput<Schema extends StandardTypedV1> = NonNullable<Schema["~standard"]["types"]>["output"]; | ||
| } | ||
| /** The Standard Schema interface. */ | ||
| export interface StandardSchemaV1<Input = unknown, Output = Input> { | ||
| /** The Standard Schema properties. */ | ||
| readonly "~standard": StandardSchemaV1.Props<Input, Output>; | ||
| } | ||
| export declare namespace StandardSchemaV1 { | ||
| /** The Standard Schema properties interface. */ | ||
| interface Props<Input = unknown, Output = Input> extends StandardTypedV1.Props<Input, Output> { | ||
| /** Validates unknown input values. */ | ||
| readonly validate: (value: unknown, options?: StandardSchemaV1.Options | undefined) => Result<Output> | Promise<Result<Output>>; | ||
| } | ||
| /** The result interface of the validate function. */ | ||
| type Result<Output> = SuccessResult<Output> | FailureResult; | ||
| /** The result interface if validation succeeds. */ | ||
| interface SuccessResult<Output> { | ||
| /** The typed output value. */ | ||
| readonly value: Output; | ||
| /** | ||
| * The non-existent issues. | ||
| */ | ||
| /** A falsy value for `issues` indicates success. */ | ||
| readonly issues?: undefined; | ||
| } | ||
| /** | ||
| * The result interface if validation fails. | ||
| */ | ||
| export interface FailureResult { | ||
| /** | ||
| * The issues of failed validation. | ||
| */ | ||
| interface Options { | ||
| /** Explicit support for additional vendor-specific parameters, if needed. */ | ||
| readonly libraryOptions?: Record<string, unknown> | undefined; | ||
| } | ||
| /** The result interface if validation fails. */ | ||
| interface FailureResult { | ||
| /** The issues of failed validation. */ | ||
| readonly issues: ReadonlyArray<Issue>; | ||
| } | ||
| /** | ||
| * The issue interface of the failure output. | ||
| */ | ||
| export interface Issue { | ||
| /** | ||
| * The error message of the issue. | ||
| */ | ||
| /** The issue interface of the failure output. */ | ||
| interface Issue { | ||
| /** The error message of the issue. */ | ||
| readonly message: string; | ||
| /** | ||
| * The path of the issue, if any. | ||
| */ | ||
| /** The path of the issue, if any. */ | ||
| readonly path?: ReadonlyArray<PropertyKey | PathSegment> | undefined; | ||
| } | ||
| /** | ||
| * The path segment interface of the issue. | ||
| */ | ||
| export interface PathSegment { | ||
| /** | ||
| * The key representing a path segment. | ||
| */ | ||
| /** The path segment interface of the issue. */ | ||
| interface PathSegment { | ||
| /** The key representing a path segment. */ | ||
| readonly key: PropertyKey; | ||
| } | ||
| /** | ||
| * The Standard Schema types interface. | ||
| */ | ||
| export interface Types<Input = unknown, Output = Input> { | ||
| /** | ||
| * The input type of the schema. | ||
| */ | ||
| readonly input: Input; | ||
| /** | ||
| * The output type of the schema. | ||
| */ | ||
| readonly output: Output; | ||
| /** The Standard types interface. */ | ||
| interface Types<Input = unknown, Output = Input> extends StandardTypedV1.Types<Input, Output> { | ||
| } | ||
| /** | ||
| * Infers the input type of a Standard Schema. | ||
| */ | ||
| export type InferInput<Schema extends StandardSchemaV1> = NonNullable<Schema["~standard"]["types"]>["input"]; | ||
| /** | ||
| * Infers the output type of a Standard Schema. | ||
| */ | ||
| export type InferOutput<Schema extends StandardSchemaV1> = NonNullable<Schema["~standard"]["types"]>["output"]; | ||
| /** | ||
| * A Standard Schema that implements the Standard JSON Schema Source interface. | ||
| * */ | ||
| export interface WithJSONSchemaSource<Input = unknown, Output = Input> { | ||
| "~standard": StandardJSONSchemaSourceV1.PropsWithStandardSchema<Input, Output>; | ||
| /** Infers the input type of a Standard. */ | ||
| type InferInput<Schema extends StandardTypedV1> = StandardTypedV1.InferInput<Schema>; | ||
| /** Infers the output type of a Standard. */ | ||
| type InferOutput<Schema extends StandardTypedV1> = StandardTypedV1.InferOutput<Schema>; | ||
| /** ArkType-specific properties that extend the standard schema with JSON Schema support. */ | ||
| interface ArkTypeProps<Input = unknown, Output = Input> extends Props<Input, Output>, StandardJSONSchemaV1.Props<Input, Output> { | ||
| vendor: "arktype"; | ||
| } | ||
| export {}; | ||
| } | ||
| /** | ||
| * The Standard JSON Schema Source interface. A standard interface to be implemented by any object/instance that can be converted to JSON Schema. | ||
| */ | ||
| export interface StandardJSONSchemaSourceV1 { | ||
| "~standard": StandardJSONSchemaSourceV1.Props; | ||
| /** The Standard JSON Schema interface. */ | ||
| export interface StandardJSONSchemaV1<Input = unknown, Output = Input> { | ||
| /** The Standard JSON Schema properties. */ | ||
| readonly "~standard": StandardJSONSchemaV1.Props<Input, Output>; | ||
| } | ||
| export declare namespace StandardJSONSchemaSourceV1 { | ||
| interface Props { | ||
| /** | ||
| * Converts the Standard Schema to a JSON Schema. | ||
| * @param params - The options for the toJSONSchema method. | ||
| * | ||
| * @returns The JSON Schema. | ||
| */ | ||
| readonly toJSONSchema: (params: StandardJSONSchemaSourceV1.Options) => Record<string, unknown>; | ||
| export declare namespace StandardJSONSchemaV1 { | ||
| /** The Standard JSON Schema properties interface. */ | ||
| interface Props<Input = unknown, Output = Input> extends StandardTypedV1.Props<Input, Output> { | ||
| /** Methods for generating the input/output JSON Schema. */ | ||
| readonly jsonSchema: StandardJSONSchemaV1.Converter; | ||
| } | ||
| interface PropsWithStandardSchema<Input = unknown, Output = Input> extends Props, StandardSchemaV1.Props<Input, Output> { | ||
| /** The Standard JSON Schema converter interface. */ | ||
| interface Converter { | ||
| /** Converts the input type to JSON Schema. May throw if conversion is not supported. */ | ||
| readonly input: (options: StandardJSONSchemaV1.Options) => Record<string, unknown>; | ||
| /** Converts the output type to JSON Schema. May throw if conversion is not supported. */ | ||
| readonly output: (options: StandardJSONSchemaV1.Options) => Record<string, unknown>; | ||
| } | ||
| /** The target version of the JSON Schema spec. */ | ||
| type Target = "draft-04" | "draft-06" | "draft-07" | "draft-2019-09" | "draft-2020-12"; | ||
| type IO = "input" | "output"; | ||
| /** The options for the ~toJSONSchema method. */ | ||
| /** | ||
| * The target version of the generated JSON Schema. | ||
| * | ||
| * It is *strongly recommended* that implementers support `"draft-2020-12"` and `"draft-07"`, as they are both in wide use. All other targets can be implemented on a best-effort basis. Libraries should throw if they don't support a specified target. | ||
| * | ||
| * The `"openapi-3.0"` target is intended as a standardized specifier for OpenAPI 3.0 which is a superset of JSON Schema `"draft-04"`. | ||
| */ | ||
| type Target = "draft-2020-12" | "draft-07" | "openapi-3.0" | ({} & string); | ||
| /** The options for the input/output methods. */ | ||
| interface Options { | ||
| /** @ Specifies whether the generated JSON Schema should reflect the expected input or output values. */ | ||
| readonly io: IO; | ||
| /** Specifies the target version of the JSON Schema spec. Support for all versions is on a best-effort basis. If a given version is not supported, the library should throw. When unspecified, implementers should target "draft-2020-12". */ | ||
| readonly target?: Target; | ||
| /** Specifies the target version of the generated JSON Schema. Support for all versions is on a best-effort basis. If a given version is not supported, the library should throw. */ | ||
| readonly target: Target; | ||
| /** Explicit support for additional vendor-specific parameters, if needed. */ | ||
| readonly libraryOptions?: Record<string, unknown> | undefined; | ||
| } | ||
| /** The Standard types interface. */ | ||
| interface Types<Input = unknown, Output = Input> extends StandardTypedV1.Types<Input, Output> { | ||
| } | ||
| /** Infers the input type of a Standard. */ | ||
| type InferInput<Schema extends StandardTypedV1> = StandardTypedV1.InferInput<Schema>; | ||
| /** Infers the output type of a Standard. */ | ||
| type InferOutput<Schema extends StandardTypedV1> = StandardTypedV1.InferOutput<Schema>; | ||
| } |
@@ -5,2 +5,3 @@ import { type Constructor, type Domain, type Json, type requireKeys, type satisfy } from "@ark/util"; | ||
| import type { JsonSchema } from "./jsonSchema.ts"; | ||
| import type { StandardJSONSchemaV1 } from "./standardSchema.ts"; | ||
| declare class ToJsonSchemaError<code extends ToJsonSchema.Code = ToJsonSchema.Code> extends Error { | ||
@@ -111,2 +112,3 @@ readonly name = "ToJsonSchemaError"; | ||
| type FallbackOption = UniversalFallback | FallbackObject; | ||
| type Target = satisfy<StandardJSONSchemaV1.Target, "draft-2020-12" | "draft-07">; | ||
| interface Options { | ||
@@ -117,2 +119,3 @@ /** value to assign to the generated $schema key | ||
| * - does not affect the contents of the generated schema | ||
| * - if `target` is also specified, `dialect` takes precedence | ||
| * | ||
@@ -122,2 +125,12 @@ * @default "https://json-schema.org/draft/2020-12/schema" | ||
| dialect?: string | null; | ||
| /** | ||
| * Shorthand for specifying the target JSON Schema version. | ||
| * Maps to the appropriate `dialect` URL. | ||
| * | ||
| * - "draft-2020-12" -> "https://json-schema.org/draft/2020-12/schema" | ||
| * - "draft-07" -> "http://json-schema.org/draft-07/schema#" | ||
| * | ||
| * If `dialect` is also specified, `dialect` takes precedence. | ||
| */ | ||
| target?: Target; | ||
| useRefs?: boolean; | ||
@@ -124,0 +137,0 @@ fallback?: FallbackOption; |
@@ -16,2 +16,3 @@ import { printable, throwInternalError } from "@ark/util"; | ||
| const defaultConfig = { | ||
| target: "draft-2020-12", | ||
| dialect: "https://json-schema.org/draft/2020-12/schema", | ||
@@ -18,0 +19,0 @@ useRefs: false, |
@@ -187,3 +187,6 @@ import { ReadonlyPath, stringifyPath } from "@ark/util"; | ||
| // if an ArkError was returned, ensure it has been added to errors | ||
| this.errors.add(result); | ||
| // (it may have already been added via ctx.error() within the morph) | ||
| // Only add if it's not already in the errors collection | ||
| if (!this.errors.includes(result)) | ||
| this.errors.add(result); | ||
| // skip any remaining morphs at the current path | ||
@@ -190,0 +193,0 @@ break; |
@@ -305,4 +305,5 @@ import { append, conflatenate, printable, throwInternalError, throwParseError } from "@ark/util"; | ||
| reduceJsonSchema(schema, ctx) { | ||
| const isDraft07 = ctx.target === "draft-07"; | ||
| if (this.prevariadic.length) { | ||
| schema.prefixItems = this.prevariadic.map(el => { | ||
| const prefixSchemas = this.prevariadic.map(el => { | ||
| const valueSchema = el.node.toJsonSchemaRecurse(ctx); | ||
@@ -322,2 +323,7 @@ if (el.kind === "defaultables") { | ||
| }); | ||
| // draft-07 uses items as array, draft-2020-12 uses prefixItems | ||
| if (isDraft07) | ||
| schema.items = prefixSchemas; | ||
| else | ||
| schema.prefixItems = prefixSchemas; | ||
| } | ||
@@ -329,10 +335,13 @@ // by default JSON schema prefixElements are optional | ||
| if (this.variadic) { | ||
| // alias schema for narrowing (Object.assign mutates anyways) | ||
| const variadicSchema = Object.assign(schema, { | ||
| items: this.variadic.toJsonSchemaRecurse(ctx) | ||
| }); | ||
| const variadicItemSchema = this.variadic.toJsonSchemaRecurse(ctx); | ||
| // draft-07 uses additionalItems when items is an array (tuple), | ||
| // draft-2020-12 uses items | ||
| if (isDraft07 && this.prevariadic.length) | ||
| schema.additionalItems = variadicItemSchema; | ||
| else | ||
| schema.items = variadicItemSchema; | ||
| // maxLength constraint will be enforced by items: false | ||
| // for non-variadic arrays | ||
| if (this.maxLength) | ||
| variadicSchema.maxItems = this.maxLength; | ||
| schema.maxItems = this.maxLength; | ||
| // postfix can only be present if variadic is present so nesting this is fine | ||
@@ -343,3 +352,3 @@ if (this.postfix) { | ||
| code: "arrayPostfix", | ||
| base: variadicSchema, | ||
| base: schema, | ||
| elements | ||
@@ -350,3 +359,8 @@ }); | ||
| else { | ||
| schema.items = false; | ||
| // For fixed-length tuples without variadic elements | ||
| // draft-07 uses additionalItems: false, draft-2020-12 uses items: false | ||
| if (isDraft07) | ||
| schema.additionalItems = false; | ||
| else | ||
| schema.items = false; | ||
| // delete maxItems constraint that will have been added by the | ||
@@ -353,0 +367,0 @@ // base intersection node to enforce fixed length |
+2
-2
| { | ||
| "name": "@ark/schema", | ||
| "version": "0.55.0", | ||
| "version": "0.56.0", | ||
| "license": "MIT", | ||
@@ -40,3 +40,3 @@ "author": { | ||
| "dependencies": { | ||
| "@ark/util": "0.55.0" | ||
| "@ark/util": "0.56.0" | ||
| }, | ||
@@ -43,0 +43,0 @@ "publishConfig": { |
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
437628
1.14%10169
0.53%+ Added
- Removed
Updated