🎩 You're Invited:Meet the Socket team at Black Hat in Las Vegas, August 3-6.RSVP
Sign In

@ark/schema

Package Overview
Dependencies
Maintainers
1
Versions
79
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@ark/schema - npm Package Compare versions

Comparing version
0.55.0
to
0.56.0
+20
-2
out/config.js

@@ -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;

@@ -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;

@@ -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 ? {

@@ -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

{
"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": {