UNPKG

juniper

Version:

ESM JSON Schema builder for static Typescript inference.

397 lines 14.7 kB
import { type JsonSchema, type ReservedWords, type SchemaType, type ToJsonParams, type typeCache } from './types.js'; declare const allOfSym: unique symbol; declare const anyOfSym: unique symbol; declare const conditionalsSym: unique symbol; declare const examplesSym: unique symbol; declare const metadataSym: unique symbol; declare const notSym: unique symbol; declare const nullableSym: unique symbol; declare const oneOfSym: unique symbol; declare const refSym: unique symbol; export interface SchemaParams<T> { default?: T; deprecated?: boolean; description?: string | null; readOnly?: boolean; writeOnly?: boolean; title?: string | null; [allOfSym]?: AbstractSchema<SchemaGenerics<T>>[]; [anyOfSym]?: AbstractSchema<SchemaGenerics<T>>[][]; [conditionalsSym]?: { if: AbstractSchema<SchemaGenerics<T>>; then: AbstractSchema<SchemaGenerics<T>> | null; else: AbstractSchema<SchemaGenerics<T>> | null; }[]; [examplesSym]?: T[]; [metadataSym]?: Record<string, unknown>; [notSym]?: AbstractSchema<SchemaGenerics<T>>[]; [nullableSym]?: boolean; [oneOfSym]?: AbstractSchema<SchemaGenerics<T>>[][]; [refSym]?: { path: string; schema: AbstractSchema<SchemaGenerics<T>>; } | null; } export interface SchemaGenerics<T> { type: T; params: SchemaParams<this['type']>; } export type ConditionalResult<T, E = T> = { then: T; else: E; } | { then: T; else?: null; } | { then?: null; else: E; }; export interface SerializationParams { /** * Inside composition (e.g. `allOf`). * * Pass base type information to prevent unnecessary duplicates. */ composition?: { type: string | null; nullable: boolean; }; /** * Comply with OpenAPI 3.0 spec. */ openApi30: boolean; } /** * Base class for JSON Schema generation and serialization. * * @template T */ export declare abstract class AbstractSchema<T extends SchemaGenerics<any>> { #private; /** * "Abstract" convenient wrapper around `new` keyword. * * Child classes MUST implement method with proper typings. * * @param options - constructor parameters * @returns new schema instance */ protected static create: (this: void, options?: any) => AbstractSchema<any>; protected readonly schemaType?: string; /** * Used to store type information. * Not actually defined and should not be accessed via JS. */ readonly [typeCache]: T; /** * Create instance of Schema. See `create` for convenient wrapper. * * @param [options] - optional * @param [options.title] - Add title to schema * @param [options.description] - Add description to schema * @param [options.deprecated] - flag schema as deprecated * @param [options.readOnly] - value should not be modified * @param [options.writeOnly] - value should be hidden * @returns new schema instance */ constructor(options?: T['params']); /** * A dictionary of "default" values for a schema. Only need to include * those that are omitted from a schema when at a certain value. * * e.g. StringSchema omits `minProperties` when set to `0`. * * Used by `$ref` to ensure defaulted properties are not mistakenly overwritten * by the referenced schema. * * Child classes SHOULD extend this response when implementing default-able properties. * * @returns map of property name -> default value. */ protected static getDefaultValues(params: SerializationParams): Record<string, unknown>; /** * Generate the JSON Schema document. * * The output will be an object, but not much else should be inferred about the * response. It should instead be passed to a validator library like [ajv](https://www.npmjs.com/package/ajv) * or serialized for export. * * The structure being described by the schema can be extracted via `SchemaType`. * * @example * const schema = StringSchema.create().enums(['a', 'b'] as const).toJSON(); * type MyString = SchemaType<typeof schema>; // 'a' | 'b' * * @param [options] - optional * @param [options.id] - $id property of schema * @param [options.openApi30=false] - Use syntax complaint with OpenAPI 3.0. * @param [options.schema=false] - Include `$schema` keyword for draft 2020-12. * @returns serializable JSON Schema */ toJSON({ id, openApi30, schema, }?: ToJsonParams): JsonSchema<T['type']>; /** * Set the `title` of the schema. * Use `null` to effectively unset. * * @see {@link https://json-schema.org/draft/2020-12/json-schema-validation.html#rfc.section.9.1} * * @param this - this instance * @param title - title property * @returns cloned schema */ title(this: this, title: string | null): this; /** * Set the `description` of the schema. * Use `null` to effectively unset. * * While multiline may be supported, whitespace itself is not trimmed. * Refer to a library like [dedent](https://www.npmjs.com/package/dedent) for this functionality. * * @see {@link https://json-schema.org/draft/2020-12/json-schema-validation.html#rfc.section.9.1} * * @param this - this instance * @param description - description property * @returns cloned schema */ description(this: this, description: string | null): this; /** * Set the `default` of the schema. * Omit parameter to unset. * * Application of the `default` value is implementation-specific, so does not alter typings. * Overwrites existing default. * * Default is not type checked against future settings, so it is possible to set a valid * default that becomes invalid with more restrictions. * * @see {@link https://json-schema.org/draft/2020-12/json-schema-validation.html#rfc.section.9.2} * * @param this - this instance * @param [val] - default value of schema * @returns cloned schema */ default(this: this, val?: T['type']): this; /** * Set the `deprecated` of the schema. * * @see {@link https://json-schema.org/draft/2020-12/json-schema-validation.html#rfc.section.9.3} * * @param this - this instance * @param deprecated - deprecated property * @returns cloned schema */ deprecated(this: this, deprecated: boolean): this; /** * Append an example literal to the schema. * * Convenience method for calling `examples([example])`. * * @param this - this instance * @param example - example literal * @returns cloned schema */ example(this: this, example: T['type']): this; /** * Append multiple example values to the schema. * * While the example is type-checked, it is not asserted against the schema. * * @see {@link https://json-schema.org/draft/2020-12/json-schema-validation.html#rfc.section.9.5} * * @param this - this instance * @param examples - example literal array * @returns cloned schema */ examples(this: this, examples: T['type'][]): this; /** * Set the schema as `readOnly`. * * Has no impact on validation (or typings), but as a hint that attempts to modify may be rejected/ignored. * * @see {@link https://json-schema.org/draft/2020-12/json-schema-validation.html#rfc.section.9.4} * * @param this - this instance * @param readOnly - read only property * @returns cloned schema */ readOnly(this: this, readOnly: boolean): this; /** * Set the schema as `writeOnly`. * * Has no impact on validation (or typings), but as a hint that data may be omitted when retrieved from authority. * * @see {@link https://json-schema.org/draft/2020-12/json-schema-validation.html#rfc.section.9.4} * * @param this - this instance * @param writeOnly - write only property * @returns cloned schema */ writeOnly(this: this, writeOnly: boolean): this; /** * Append custom metadata to schema. * Any JSON Schema reserved words are forbidden. * * Besides ensuring no overlap with reserved words, no content * validation or type inference occurs. All values are returned unaltered, regardless * of generation parameters. * * Useful to append metadata for implementation specific needs, such as (but not exclusive to) * [OpenAPI's `x-` prefix](https://swagger.io/specification/#specification-extensions) or self-implementing * [custom keywords](https://json-schema.org/understanding-json-schema/reference/schema.html#id6). * * This method _may_ be used for self-implement missing features * but such usage may be disabled at any time (via implementation). * * @param this - this instance * @param meta - custom metadata * @returns cloned schema * @throws when reserved word is used as keyword */ metadata<K extends string, V>(this: this, ...meta: (K & ReservedWords extends never ? unknown[] : [never]) & ([K, V] | [Record<K, V>])): this; /** * Reference schema via `$ref`. * Path to ref must be provided, and is not validated. * * Any "edits" to the resulting object are merged into the `$ref` object. * * The `$ref` object is expected to be the value of the schema called with `toJSON()`. * * Note that this syntax is valid in OpenApi 3.0, but behavior is _generally_ * expected to ignore any sibling properties. * Actual implementation is up to user (many `$ref` parsers will merge objects). * * @see {@link https://json-schema.org/understanding-json-schema/structuring.html#ref} * * @param this - this instance * @param path - $ref path property * @returns cloned schema */ ref(this: this, path: string): this; /** * Explicitly cast schema. * * Use with caution as any types are not enforced and * no more type-specific extensions are possible. * * Convenience method for tacking on custom symbols or attributes * that vary by implementation/usage. * * @returns typed schema */ cast<NewT extends T['type']>(): AbstractSchema<SchemaGenerics<NewT>>; /** * Append an `allOf` restriction on schema. * * @see {@link https://json-schema.org/understanding-json-schema/reference/combining.html#allof} * * @param schema - all of schema must be valid * @returns cloned schema */ protected allOf(schema: never): unknown; /** * Define a `anyOf` restriction on schema. * * @see {@link https://json-schema.org/understanding-json-schema/reference/combining.html#anyof} * * @param schemas - any of schema must be valid * @returns cloned schema */ protected anyOf(schemas: never[]): unknown; /** * Apply conditional schemas. * * @see {@link https://json-schema.org/understanding-json-schema/reference/conditionals.html#if-then-else} * * @param schema - "if" schema property * @param conditionals - "then" + "else" schemas, at least one is required. * @returns cloned schema */ protected if(schema: never, conditionals: ConditionalResult<never>): unknown; /** * A schema definition that would render the schema invalid. * * Does not alter types, as the closest typescript equivalent `Exclude` * doesn't actually ensure excluded types. * * ```ts * type NotReallyExcluded = Exclude<{ abc: string; efg?: number }, { abc: 123 }>; * const shouldBeInvalid: NotReallyExcluded = { abc: 123 }; * ``` * * Schemas that support `nullable()` may exclude `null` if appropriate. * * @see {@link https://json-schema.org/understanding-json-schema/reference/combining.html#not} * * @param schema - schema to validate against * @returns cloned schema */ protected not(schema: never): unknown; /** * Set schema as `nullable`. * Allowing `type=null` as well as existing type. * * @returns cloned schema */ protected nullable(): unknown; /** * Define a `oneOf` restriction on schema. * * @see {@link https://json-schema.org/understanding-json-schema/reference/combining.html#oneof} * * @param schemas - one of schema must be valid * @returns cloned schema */ protected oneOf(schemas: never[]): unknown; /** * Instance method to call static method (using constructor for inheritance). * * @param this - this instance * @param params - serialization params * @returns JSON Schema */ protected getChildSchema<T2>(this: AbstractSchema<SchemaGenerics<T2>>, params: SerializationParams): JsonSchema<T2>; /** * Returns default constructor params for child class. * * Child classes SHOULD implement, and MUST extend response from `super.getCloneParams()`. * If no extra parameters are used, do not need to implement. * * @returns schema params based on instance */ protected getCloneParams(): Required<SchemaParams<T['type']>> & T['params']; /** * Creates a new instance of this schema class, * with parameters to set attributes to same as this instance. * * Override existing values via the `overrideParams`. * * Child classes MUST NOT override. * * @param overrideParams - override constructor params * @returns schema params */ protected clone(overrideParams: Partial<T['params']>): this; /** * Generate JSON Schema for this data type. * * Child classes SHOULD override and extend value of `super.toSchema()`. * If no extra schema data is added, do not need to implement. * * @param params - serialization params * @returns JSON Schema */ protected toSchema(params: SerializationParams): JsonSchema<SchemaType<this>>; /** * Method to get JSON schema of a internal property (e.g. array item). * * Child classes MUST NOT override. * * @param schema - juniper schema * @param params - serialization params (stripped of composition context) * @param params.openApi30 - open api 3.0 compliant * @returns JSON Schema */ protected static getSchema<T2>(schema: AbstractSchema<SchemaGenerics<T2>>, { openApi30 }: SerializationParams): JsonSchema<T2>; } export {}; //# sourceMappingURL=schema.d.ts.map