@nxgt/graphql-validation 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +63 -6
- package/dist/bad-user-input.d.ts +1 -1
- package/dist/builder/args-schema.d.ts +1 -1
- package/dist/builder/check-constraints.d.ts +6 -1
- package/dist/builder/check-constraints.d.ts.map +1 -1
- package/dist/builder/constraints.d.ts +1 -1
- package/dist/builder/input-code.d.ts +15 -2
- package/dist/builder/input-code.d.ts.map +1 -1
- package/dist/builder/input-schema.d.ts +3 -1
- package/dist/builder/input-schema.d.ts.map +1 -1
- package/dist/builder/leaf.d.ts +3 -3
- package/dist/builder/leaf.d.ts.map +1 -1
- package/dist/chunks/{index-s1kkmg35.js → index-1mzzydy3.js} +219 -23
- package/dist/chunks/index-1mzzydy3.js.map +25 -0
- package/dist/chunks/{index-rbxe5m3y.js → index-xcaf9kes.js} +24 -97
- package/dist/chunks/index-xcaf9kes.js.map +27 -0
- package/dist/cli.js +1 -1
- package/dist/codegen.d.ts +4 -3
- package/dist/codegen.d.ts.map +1 -1
- package/dist/codegen.js +19 -9
- package/dist/codegen.js.map +3 -3
- package/dist/formats/all.d.ts +8 -8
- package/dist/formats/byte.d.ts +1 -1
- package/dist/formats/byte.d.ts.map +1 -1
- package/dist/formats/date-time.d.ts +1 -1
- package/dist/formats/date-time.d.ts.map +1 -1
- package/dist/formats/date.d.ts +1 -1
- package/dist/formats/date.d.ts.map +1 -1
- package/dist/formats/email.d.ts +1 -1
- package/dist/formats/email.d.ts.map +1 -1
- package/dist/formats/format.d.ts +9 -3
- package/dist/formats/format.d.ts.map +1 -1
- package/dist/formats/index.d.ts +7 -9
- package/dist/formats/index.d.ts.map +1 -1
- package/dist/formats/ipv4.d.ts +1 -1
- package/dist/formats/ipv4.d.ts.map +1 -1
- package/dist/formats/ipv6.d.ts +1 -1
- package/dist/formats/ipv6.d.ts.map +1 -1
- package/dist/formats/registry.d.ts +50 -0
- package/dist/formats/registry.d.ts.map +1 -0
- package/dist/formats/uri.d.ts +1 -1
- package/dist/formats/uri.d.ts.map +1 -1
- package/dist/formats/uuid.d.ts +1 -1
- package/dist/formats/uuid.d.ts.map +1 -1
- package/dist/index.d.ts +8 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +18 -5
- package/dist/index.js.map +3 -3
- package/dist/rules/all.d.ts +15 -15
- package/dist/rules/contains.d.ts +1 -1
- package/dist/rules/ends-with.d.ts +1 -1
- package/dist/rules/exclusive-max.d.ts +1 -1
- package/dist/rules/exclusive-min.d.ts +1 -1
- package/dist/rules/format.d.ts +1 -1
- package/dist/rules/format.d.ts.map +1 -1
- package/dist/rules/index.d.ts +9 -4
- package/dist/rules/index.d.ts.map +1 -1
- package/dist/rules/max-items.d.ts +1 -1
- package/dist/rules/max-length.d.ts +1 -1
- package/dist/rules/max.d.ts +1 -1
- package/dist/rules/min-items.d.ts +1 -1
- package/dist/rules/min-length.d.ts +1 -1
- package/dist/rules/min.d.ts +1 -1
- package/dist/rules/multiple-of.d.ts +1 -1
- package/dist/rules/not-contains.d.ts +1 -1
- package/dist/rules/pattern.d.ts +1 -1
- package/dist/rules/rule.d.ts +20 -3
- package/dist/rules/rule.d.ts.map +1 -1
- package/dist/rules/starts-with.d.ts +1 -1
- package/dist/with-validation.d.ts +17 -1
- package/dist/with-validation.d.ts.map +1 -1
- package/docs/README.md +1 -1
- package/docs/guide/constraints.md +133 -4
- package/docs/guide/errors.md +4 -1
- package/docs/roadmap.md +21 -15
- package/docs/troubleshooting.md +165 -6
- package/package.json +2 -2
- package/dist/chunks/index-rbxe5m3y.js.map +0 -37
- package/dist/chunks/index-s1kkmg35.js.map +0 -14
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/builder/constraints.ts", "../src/builder/check-constraints.ts", "../src/formats/registry.ts", "../src/formats/byte.ts", "../src/formats/format.ts", "../src/formats/date.ts", "../src/formats/date-time.ts", "../src/formats/email.ts", "../src/formats/ipv4.ts", "../src/formats/ipv6.ts", "../src/formats/uri.ts", "../src/formats/uuid.ts", "../src/formats/index.ts", "../src/builder/args-schema.ts", "../src/builder/input-schema.ts", "../src/builder/leaf.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"import {\n\ttype DirectiveNode,\n\ttype GraphQLDirective,\n\tgetDirectiveValues,\n} from 'graphql';\nimport { type RegisteredRule, rules } from '../rules';\n\n/** One `@constraint` argument written on an argument or an input field. */\nexport interface Constraint {\n\treadonly rule: RegisteredRule;\n\treadonly value: string | number;\n}\n\n/**\n * The constraints written on a node, base rules (`format`) first so the\n * others narrow the schema they produce. Empty when the schema declares no\n * `@constraint` or the node carries none.\n */\nexport function constraintsOn(\n\tdirective: GraphQLDirective | undefined,\n\tnode:\n\t\t| { readonly directives?: ReadonlyArray<DirectiveNode> | undefined }\n\t\t| null\n\t\t| undefined,\n): Constraint[] {\n\tif (!directive || !node) return [];\n\tconst values =\n\t\tgetDirectiveValues(directive, { directives: node.directives ?? [] }) ?? {};\n\treturn Object.entries(values)\n\t\t.filter(([, value]) => value !== undefined && value !== null)\n\t\t.map(([argument, value]) => ({\n\t\t\trule: rules[argument as keyof typeof rules],\n\t\t\tvalue: value as string | number,\n\t\t}))\n\t\t.sort(\n\t\t\t(a, b) => Number(Boolean(b.rule.base)) - Number(Boolean(a.rule.base)),\n\t\t);\n}\n",
|
|
6
|
+
"import {\n\ttype GraphQLDirective,\n\ttype GraphQLField,\n\ttype GraphQLObjectType,\n\ttype GraphQLSchema,\n\tisInterfaceType,\n\tisObjectType,\n} from 'graphql';\nimport type { z } from 'zod';\nimport { assertOwnConstraint } from '../constraint-directive';\nimport { type FormatSchemas, registryOf } from '../formats/registry';\nimport { argsSchemaOf, assertInterfaceConstraintsKept } from './args-schema';\nimport { constraintsOn } from './constraints';\nimport { InputSchemas } from './input-schema';\n\n/**\n * Runs every check `withValidation` makes at startup, so a code generator\n * refuses the same schemas: the declaration is `constraintTypeDefs`', every\n * constraint applies where it is written (in every input type), none sits on\n * a directive's argument, objects keep their interfaces' constraints, and no\n * default value breaks its own. `onArgs` receives each object field's\n * arguments schema, for a field with something to check.\n *\n * `formats` are the application's own, which `@constraint(format: \"...\")`\n * may name beside the built-in ones; they are checked first (name, no\n * built-in replaced, a Zod string schema each).\n *\n * Returns the `@constraint` directive, or `undefined` when the schema\n * declares none (and so carries no constraint).\n */\nexport function checkConstraints(\n\tschema: GraphQLSchema,\n\tonArgs?: (\n\t\ttype: GraphQLObjectType,\n\t\tfield: GraphQLField<unknown, unknown>,\n\t\targs: z.ZodType,\n\t) => void,\n\tformats?: FormatSchemas,\n): GraphQLDirective | undefined {\n\tconst inputs = new InputSchemas(schema, registryOf(formats));\n\tif (!inputs.directive) return undefined;\n\tassertOwnConstraint(inputs.directive);\n\tinputs.buildAll(schema);\n\tassertNoDirectiveArgumentConstrained(inputs, schema);\n\tfor (const type of Object.values(schema.getTypeMap())) {\n\t\tif (type.name.startsWith('__')) continue;\n\t\t// An interface's fields resolve on its objects: built for their errors only.\n\t\tif (isInterfaceType(type)) {\n\t\t\tfor (const field of Object.values(type.getFields()))\n\t\t\t\targsSchemaOf(inputs, type.name, field);\n\t\t}\n\t\tif (!isObjectType(type)) continue;\n\t\tassertInterfaceConstraintsKept(inputs, type);\n\t\tfor (const field of Object.values(type.getFields()) as GraphQLField<\n\t\t\tunknown,\n\t\t\tunknown\n\t\t>[]) {\n\t\t\tconst args = argsSchemaOf(inputs, type.name, field);\n\t\t\tif (args) onArgs?.(type, field, args);\n\t\t}\n\t}\n\tinputs.checkDefaults();\n\treturn inputs.directive;\n}\n\n/**\n * Fails on a `@constraint` written on a directive's argument: graphql allows\n * it there (ARGUMENT_DEFINITION), but no resolver receives that argument, so\n * it would check nothing.\n */\nfunction assertNoDirectiveArgumentConstrained(\n\tinputs: InputSchemas,\n\tschema: GraphQLSchema,\n): void {\n\tfor (const directive of schema.getDirectives()) {\n\t\tfor (const arg of directive.args) {\n\t\t\tif (constraintsOn(inputs.directive, arg.astNode).length > 0) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`@constraint on @${directive.name}(${arg.name}:) checks nothing: a directive's argument reaches no resolver. Remove it.`,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n}\n",
|
|
7
|
+
"import { z } from 'zod';\nimport { RULE_PARAM } from '../rules/rule';\nimport type { Format, StringSchema } from './format';\nimport { formats as builtIns, type FormatName } from './index';\n\n/**\n * The application's own formats, keyed by the name `@constraint(format:\n * \"...\")` gives them: each a Zod string schema, `z.string()` or a string\n * format (`z.email()`), narrowed (`.regex()`, `.refine()`) but never\n * transformed nor rewritten (`.trim()`, `.toLowerCase()`, `z.url()`,\n * `z.coerce.string()`), so the resolver receives what was sent.\n */\nexport type FormatSchemas = { readonly [name: string]: StringSchema };\n\n/**\n * `F` with every key that names a built-in format typed `never`, so\n * replacing one is a type error before it is a startup error. The keys are\n * optional: a record typed wider than its literal (`FormatSchemas`,\n * `Record<string, z.ZodString>`) may hold none of them, and passes.\n */\nexport type OwnFormats<F extends FormatSchemas> = F & {\n\treadonly [K in keyof F & FormatName]?: never;\n};\n\nconst NAME = /^[a-z][a-z0-9-]*$/;\n\n/**\n * Every format `@constraint(format: \"...\")` can name: the built-in ones,\n * then the application's own. A lookup is one `Map` read, however many\n * formats there are.\n */\nexport class FormatRegistry {\n\treadonly #formats = new Map<string, Format>();\n\t#async: string | undefined;\n\n\t/**\n\t * Fails, naming the format, on a bad name, a built-in's name, a schema\n\t * that is not a string's, one zod cannot run, or one that rewrites the\n\t * value.\n\t */\n\tconstructor(own: FormatSchemas = {}) {\n\t\tfor (const format of Object.values(builtIns))\n\t\t\tthis.#formats.set(format.name, format);\n\t\tfor (const [name, schema] of Object.entries(own)) {\n\t\t\tif (!NAME.test(name)) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Invalid format name ${JSON.stringify(name)}: write it in lowercase letters, digits and hyphens, starting with a letter.`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (this.#formats.has(name)) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`The format \"${name}\" is built in: give yours another name.`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (!isStringSchema(schema)) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`The format \"${name}\" is not a Zod string schema: write z.string() or a string format such as z.email(), narrowed with .regex() or .refine(), never transformed.`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (!runnable(schema)) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`The format \"${name}\" cannot be run: its definition reads type: 'string' but it has no _zod.run, so it was not built by zod 4. Pass the schema z.string() or a string format returns, not an object shaped like one.`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (rewrites(schema)) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`The format \"${name}\" rewrites the value (.trim(), .toLowerCase(), .toUpperCase(), .normalize(), .slugify(), .overwrite(), z.url(), z.httpUrl() or z.coerce.string()): refuse what is not canonical with .regex() or .refine() instead, so the server and the client check the value as it was sent.`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tconst own = marked(name, schema, () => {\n\t\t\t\tthis.#async = name;\n\t\t\t});\n\t\t\tthis.#formats.set(name, { name, toZod: () => own });\n\t\t}\n\t}\n\n\t/** The format named `name`, or an error that lists the known ones. */\n\tnamed(name: string): Format {\n\t\tconst format = this.#formats.get(name);\n\t\tif (format) return format;\n\t\tthrow new Error(\n\t\t\t`Unknown @constraint format \"${name}\". Known formats: ${[...this.#formats.keys()].join(', ')}.`,\n\t\t);\n\t}\n\n\t/**\n\t * The format of the application that last went async, then forgotten: read\n\t * right after a synchronous parse threw zod's `$ZodAsyncError`, it names the\n\t * format that made it throw (zod stops at the first check that returns a\n\t * promise, and only an application's format can).\n\t */\n\ttakeAsync(): string | undefined {\n\t\tconst name = this.#async;\n\t\tthis.#async = undefined;\n\t\treturn name;\n\t}\n}\n\n/**\n * Whether a value is a Zod string schema, read from its definition rather\n * than `instanceof`, so a schema from another copy of zod is recognised. A\n * transform or a codec is a pipe, `.optional()` an optional: neither passes.\n */\nfunction isStringSchema(value: unknown): value is StringSchema {\n\treturn definition(value)?.type === 'string';\n}\n\n/**\n * Whether zod can run the schema: `marked` calls its `_zod.run` on every\n * value, so a definition alone (an object that only reads `type: 'string'`)\n * would pass startup and fail each request instead.\n */\nfunction runnable(schema: StringSchema): boolean {\n\treturn (\n\t\ttypeof (schema as { _zod?: { run?: unknown } } | null)?._zod?.run ===\n\t\t'function'\n\t);\n}\n\n/**\n * Whether a string schema rewrites the value it checks, though it stays\n * `type: 'string'`: `z.coerce.string()` (`coerce: true`) turns a number\n * into a string; `z.url()`, `z.httpUrl()` and `.url()` (`format: 'url'`, as\n * the schema or as one of its checks) trim the value and drop its tabs and\n * newlines, or normalise it; `.trim()`, `.toLowerCase()`, `.toUpperCase()`,\n * `.normalize()`, `.slugify()` and `.overwrite()` are each a check whose\n * definition reads `check: 'overwrite'`. Every other string format of zod 4\n * only checks. `format: 'url'` is read as the format's name, so a\n * `z.stringFormat('url', …)` of the application's is refused too. The\n * server checks the value as sent; a client chaining rules on a rewriting\n * schema would check the rewritten one. A custom check that sets the value\n * cannot be read here: `marked` catches it when it runs.\n */\nfunction rewrites(schema: StringSchema): boolean {\n\tconst def = definition(schema);\n\tif (def?.coerce || def?.format === 'url') return true;\n\treturn (def?.checks ?? []).some((check) => {\n\t\tconst own = definition(check);\n\t\treturn own?.check === 'overwrite' || own?.format === 'url';\n\t});\n}\n\ntype Definition = {\n\ttype?: unknown;\n\tcoerce?: unknown;\n\tformat?: unknown;\n\tcheck?: unknown;\n\tchecks?: readonly unknown[];\n};\n\nfunction definition(value: unknown): Definition | undefined {\n\treturn (value as { _zod?: { def?: Definition } } | null)?._zod?.def;\n}\n\n/**\n * The application's schema as a plain string schema the rules can narrow,\n * each of its issues re-raised as it was (code, message, and an abort that\n * stops the rules chained after it) and marked as the format's: a\n * `.regex()` inside it is the format's refusal, not `pattern`'s.\n * The value is checked, never changed: a schema that still returns another\n * value (a custom `.check()` setting `payload.value`, which `rewrites`\n * cannot see) throws, naming the format, as a resolver's bug would.\n *\n * The schema runs once per value, through its own `_zod.run` (what its\n * `safeParse` and `safeParseAsync` call) with `async: true`: a schema whose\n * checks are all synchronous returns its result at once, one with an async\n * check returns a promise, whatever zod copy it comes from. Nothing is\n * started and dropped, as a synchronous `safeParse` would drop the promise of\n * an async refine before running it again. That promise, returned to the\n * enclosing parse, gets a handler too: a synchronous parse (a default\n * value's check) throws zod's async error and drops it, and its rejection\n * must not surface as an unhandled one. `onAsync` is told before it is\n * returned.\n */\nfunction marked(\n\tname: string,\n\tschema: StringSchema,\n\tonAsync: () => void,\n): StringSchema {\n\treturn z.string().superRefine((value, ctx) => {\n\t\tconst raise = (result: z.core.ParsePayload<unknown>) => {\n\t\t\tif (result.issues.length === 0 && result.value !== value) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`The format \"${name}\" rewrote the value it checked: a format checks the value and never changes it, so the server and the client check the value as it was sent. Refuse what is not canonical with .regex() or .refine() instead of setting payload.value in a .check().`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tfor (const raw of result.issues) {\n\t\t\t\t// Finalised as the schema's own parse would: its message settled.\n\t\t\t\tconst issue = z.core.util.finalizeIssue(raw, RUN, z.core.config());\n\t\t\t\tconst params = 'params' in issue ? issue.params : undefined;\n\t\t\t\tctx.addIssue({\n\t\t\t\t\t...issue,\n\t\t\t\t\tparams: { ...params, [RULE_PARAM]: 'format' },\n\t\t\t\t\t// finalizeIssue drops `continue`: an aborting check of the format\n\t\t\t\t\t// (`.refine(…, { abort: true })`) still stops the rules after it,\n\t\t\t\t\t// as it does in the generated client. Once the format has gone\n\t\t\t\t\t// async, zod has already run those rules: the abort then stops\n\t\t\t\t\t// nothing, on the server only.\n\t\t\t\t\t...(raw.continue === false && { continue: false }),\n\t\t\t\t} as Parameters<typeof ctx.addIssue>[0]);\n\t\t\t}\n\t\t};\n\t\tconst result = schema._zod.run({ value, issues: [] }, RUN);\n\t\tif (!(result instanceof Promise)) {\n\t\t\traise(result);\n\t\t\treturn undefined;\n\t\t}\n\t\tconst pending = result.then(raise);\n\t\tpending.catch(() => {});\n\t\tonAsync();\n\t\treturn pending;\n\t});\n}\n\n/** How a format runs: async allowed, so an async check is never dropped. */\nconst RUN: z.core.ParseContextInternal = { async: true };\n\nconst builtInRegistry = new FormatRegistry();\nconst registries = new WeakMap<FormatSchemas, FormatRegistry>();\n\n/**\n * The registry of a set of formats, built (and checked) once per record: a\n * code generator hands the same record for every field.\n */\nexport function registryOf(own?: FormatSchemas): FormatRegistry {\n\tif (!own) return builtInRegistry;\n\tlet registry = registries.get(own);\n\tif (!registry) {\n\t\tregistry = new FormatRegistry(own);\n\t\tregistries.set(own, registry);\n\t}\n\treturn registry;\n}\n",
|
|
8
|
+
"import { z } from 'zod';\nimport { defineFormat } from './format';\n\nexport const byteFormat = defineFormat({\n\tname: 'byte',\n\ttoZod: () => z.base64(),\n\ttoCode: () => 'z.base64()',\n});\n",
|
|
9
|
+
"import type { z } from 'zod';\n\n/** A string schema, plain or a format (`z.email()` is not a `z.ZodString`). */\nexport type StringSchema = z.ZodString | z.ZodStringFormat;\n\n/**\n * One value of `@constraint(format: \"...\")`: the schema it stands for, as a\n * schema at startup and, for a built-in one, as source for a code generator.\n * A format of the application's own has no `toCode`: the generator writes a\n * reference to the application's schema instead.\n */\nexport interface Format<N extends string = string> {\n\treadonly name: N;\n\treadonly toZod: () => StringSchema;\n\treadonly toCode?: () => string;\n}\n\n/** A format this package ships: written twice, as a schema and as source. */\nexport interface BuiltInFormat<N extends string = string> extends Format<N> {\n\treadonly toCode: () => string;\n}\n\n/** Declares a built-in format, with its name kept literal. */\nexport function defineFormat<const N extends string>(\n\tformat: BuiltInFormat<N>,\n): BuiltInFormat<N> {\n\treturn format;\n}\n",
|
|
10
|
+
"import { z } from 'zod';\nimport { defineFormat } from './format';\n\nexport const dateFormat = defineFormat({\n\tname: 'date',\n\ttoZod: () => z.iso.date(),\n\ttoCode: () => 'z.iso.date()',\n});\n",
|
|
11
|
+
"import { z } from 'zod';\nimport { defineFormat } from './format';\n\n// RFC 3339 with an offset, in its canonical spelling only: an uppercase `T`\n// and `Z`, seconds present. graphql-constraint-directive (validator's\n// isRFC3339) also takes a lowercase `t`, `z` or a space.\nexport const dateTimeFormat = defineFormat({\n\tname: 'date-time',\n\ttoZod: () => z.iso.datetime({ offset: true }),\n\ttoCode: () => 'z.iso.datetime({ offset: true })',\n});\n",
|
|
12
|
+
"import { z } from 'zod';\nimport { defineFormat } from './format';\n\nexport const emailFormat = defineFormat({\n\tname: 'email',\n\ttoZod: () => z.email(),\n\ttoCode: () => 'z.email()',\n});\n",
|
|
13
|
+
"import { z } from 'zod';\nimport { defineFormat } from './format';\n\nexport const ipv4Format = defineFormat({\n\tname: 'ipv4',\n\ttoZod: () => z.ipv4(),\n\ttoCode: () => 'z.ipv4()',\n});\n",
|
|
14
|
+
"import { z } from 'zod';\nimport { defineFormat } from './format';\n\nexport const ipv6Format = defineFormat({\n\tname: 'ipv6',\n\ttoZod: () => z.ipv6(),\n\ttoCode: () => 'z.ipv6()',\n});\n",
|
|
15
|
+
"import { z } from 'zod';\nimport { defineFormat } from './format';\n\n// graphql-constraint-directive's `uri` is validator's isURL: http, https or\n// ftp. The scheme is required here, where isURL lets `example.com` through,\n// and nothing else gets in: no `javascript:`, no `mailto:`.\nexport const uriFormat = defineFormat({\n\tname: 'uri',\n\ttoZod: () => z.url({ protocol: /^(https?|ftp)$/ }),\n\ttoCode: () => 'z.url({ protocol: /^(https?|ftp)$/ })',\n});\n",
|
|
16
|
+
"import { z } from 'zod';\nimport { defineFormat } from './format';\n\nexport const uuidFormat = defineFormat({\n\tname: 'uuid',\n\ttoZod: () => z.uuid(),\n\ttoCode: () => 'z.uuid()',\n});\n",
|
|
17
|
+
"import * as all from './all';\nimport type { BuiltInFormat } from './format';\n\n/**\n * Every built-in format, keyed by the value `@constraint(format: \"...\")`\n * takes. Derived from what `./all` exports, so a new format is one file and\n * one line there.\n */\nexport const formats = Object.fromEntries(\n\tObject.values(all).map((format) => [format.name, format]),\n) as { readonly [N in FormatName]: BuiltInFormat<N> };\n\n/** A value `@constraint(format: \"...\")` takes without the application's formats. */\nexport type FormatName = (typeof all)[keyof typeof all]['name'];\n",
|
|
18
|
+
"import type { GraphQLArgument, GraphQLField, GraphQLObjectType } from 'graphql';\nimport { z } from 'zod';\nimport { constraintsOn } from './constraints';\nimport type { InputSchemas } from './input-schema';\n\n/**\n * The schema of a field's arguments, or `undefined` when none of them can\n * break a constraint, so a field with nothing to check is left untouched.\n * `parent` is the type's name, for errors: `Mutation.signUp(input:)`.\n */\nexport function argsSchemaOf(\n\tinputs: InputSchemas,\n\tparent: string,\n\tfield: GraphQLField<unknown, unknown>,\n): z.ZodType | undefined {\n\tif (!field.args.some((arg) => inputs.needsCheck(arg))) return undefined;\n\treturn z.object(\n\t\tObject.fromEntries(\n\t\t\tfield.args.map((arg) => [\n\t\t\t\targ.name,\n\t\t\t\tinputs.of(arg, `${parent}.${field.name}(${arg.name}:)`),\n\t\t\t]),\n\t\t),\n\t);\n}\n\n/** The constraints of an argument as written, sorted: `maxLength: 5, min: 1`. */\nfunction signature(inputs: InputSchemas, arg: GraphQLArgument): string {\n\treturn constraintsOn(inputs.directive, arg.astNode)\n\t\t.map(({ rule, value }) => `${rule.argument}: ${JSON.stringify(value)}`)\n\t\t.sort()\n\t\t.join(', ');\n}\n\n/** A signature as it reads in an error. */\nconst written = (signature: string) =>\n\tsignature ? `@constraint(${signature})` : 'no @constraint';\n\n/**\n * Fails when an object type's field does not repeat the `@constraint` its\n * interface writes on an argument. The object's field is the one that\n * resolves, and graphql lets it redeclare the argument bare: the interface's\n * constraint would then check nothing, in silence.\n */\nexport function assertInterfaceConstraintsKept(\n\tinputs: InputSchemas,\n\ttype: GraphQLObjectType,\n): void {\n\tfor (const contract of type.getInterfaces()) {\n\t\tfor (const [name, declared] of Object.entries(contract.getFields())) {\n\t\t\tconst field = type.getFields()[name];\n\t\t\tfor (const arg of declared.args) {\n\t\t\t\tconst wanted = signature(inputs, arg);\n\t\t\t\tif (!wanted) continue;\n\t\t\t\tconst own = field?.args.find(\n\t\t\t\t\t({ name: argName }) => argName === arg.name,\n\t\t\t\t);\n\t\t\t\tconst found = own ? signature(inputs, own) : wanted;\n\t\t\t\tif (found !== wanted) {\n\t\t\t\t\tconst verb = found ? 'differs on' : 'is not repeated on';\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t`@constraint on ${contract.name}.${name}(${arg.name}:) ${verb} ${type.name}.${name}(${arg.name}:), which resolves it (${written(wanted)} there, ${written(found)} here). Write the same @constraint on both.`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n",
|
|
19
|
+
"import {\n\ttype ConstValueNode,\n\ttype GraphQLArgument,\n\ttype GraphQLDirective,\n\ttype GraphQLInputField,\n\ttype GraphQLInputObjectType,\n\ttype GraphQLInputType,\n\ttype GraphQLSchema,\n\tgetNamedType,\n\tisInputObjectType,\n\tisListType,\n\tisNonNullType,\n\tvalueFromAST,\n} from 'graphql';\nimport { z } from 'zod';\nimport { type FormatRegistry, registryOf } from '../formats/registry';\nimport { applyRule } from '../rules';\nimport type { RuleContext } from '../rules/rule';\nimport { type Constraint, constraintsOn } from './constraints';\nimport { assertObjectTargets, leafSchema } from './leaf';\n\n/**\n * Builds the schemas of the arguments and input fields of one GraphQL\n * schema, once each: an input type is walked a single time however many\n * fields use it, and a recursive one (`input Filter { and: [Filter!] }`) is\n * reached through `z.lazy`.\n */\nexport class InputSchemas {\n\treadonly directive: GraphQLDirective | undefined;\n\treadonly #context: RuleContext;\n\treadonly #objects = new Map<string, z.ZodType>();\n\treadonly #defaults: {\n\t\tschema: z.ZodType;\n\t\tliteral: ConstValueNode;\n\t\ttype: GraphQLInputType;\n\t\twhere: string;\n\t}[] = [];\n\t/** The input types a value can break a constraint inside. */\n\treadonly #constrained = new Set<string>();\n\n\t/** `formats`: the built-in ones by default, the application's added. */\n\tconstructor(schema: GraphQLSchema, formats: FormatRegistry = registryOf()) {\n\t\tthis.#context = { formats };\n\t\tthis.directive = schema.getDirective('constraint') ?? undefined;\n\t\tconst objects = Object.values(schema.getTypeMap()).filter(\n\t\t\tisInputObjectType,\n\t\t);\n\t\t// A fixpoint, not a memoised walk: in a cycle, a type visited while it\n\t\t// is still being decided would be cached as unconstrained for good.\n\t\tfor (let changed = true; changed; ) {\n\t\t\tchanged = false;\n\t\t\tfor (const type of objects) {\n\t\t\t\tif (this.#constrained.has(type.name)) continue;\n\t\t\t\tconst constrained = Object.values(type.getFields()).some(\n\t\t\t\t\t(field) =>\n\t\t\t\t\t\tconstraintsOn(this.directive, field.astNode).length > 0 ||\n\t\t\t\t\t\tthis.isConstrained(field.type),\n\t\t\t\t);\n\t\t\t\tif (constrained) {\n\t\t\t\t\tthis.#constrained.add(type.name);\n\t\t\t\t\tchanged = true;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/** Whether a value of this type can break a constraint anywhere inside. */\n\tisConstrained(type: GraphQLInputType): boolean {\n\t\tconst named = getNamedType(type);\n\t\treturn isInputObjectType(named) && this.#constrained.has(named.name);\n\t}\n\n\t/**\n\t * Builds every constrained input type, reached by an argument or not, so\n\t * a constraint that cannot apply fails at startup wherever it is written.\n\t */\n\tbuildAll(schema: GraphQLSchema): void {\n\t\tfor (const type of Object.values(schema.getTypeMap())) {\n\t\t\tif (isInputObjectType(type)) this.#object(type);\n\t\t}\n\t}\n\n\t/** Whether an argument or input field needs checking at all. */\n\tneedsCheck(input: GraphQLArgument | GraphQLInputField): boolean {\n\t\treturn (\n\t\t\tconstraintsOn(this.directive, input.astNode).length > 0 ||\n\t\t\tthis.isConstrained(input.type)\n\t\t);\n\t}\n\n\t/** The schema of one argument or input field, `where` naming it in errors. */\n\tof(input: GraphQLArgument | GraphQLInputField, where: string): z.ZodType {\n\t\tconst schema = this.#typed(\n\t\t\tinput.type,\n\t\t\tconstraintsOn(this.directive, input.astNode),\n\t\t\twhere,\n\t\t);\n\t\tconst literal = input.astNode?.defaultValue;\n\t\tif (literal)\n\t\t\tthis.#defaults.push({ schema, literal, type: input.type, where });\n\t\treturn schema;\n\t}\n\n\t/**\n\t * Fails when a default value breaks its own constraint: every request that\n\t * leaves the value out would be refused for something the client never\n\t * sent. Run once every schema is built, so a recursive type is complete.\n\t */\n\tcheckDefaults(): void {\n\t\tfor (const { schema, literal, type, where } of this.#defaults.splice(0)) {\n\t\t\t// Coerced as graphql coerces it: a single value for a list, an input\n\t\t\t// object's own field defaults. One graphql refuses is its to report.\n\t\t\tconst value = valueFromAST(literal, type);\n\t\t\tif (value === undefined) continue;\n\t\t\tlet result: z.ZodSafeParseResult<unknown>;\n\t\t\ttry {\n\t\t\t\tresult = schema.safeParse(value);\n\t\t\t} catch (error) {\n\t\t\t\t// Thrown by this zod: only the formats' wrapper, ours, goes async.\n\t\t\t\tif (!(error instanceof z.core.$ZodAsyncError)) throw error;\n\t\t\t\tconst format = this.#context.formats.takeAsync();\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`The default value of ${where} cannot be checked at startup: ${format ? `the format \"${format}\"` : 'its format'} checks asynchronously, and a default value is checked synchronously. Drop the default, or move the async check out of the format into validated().`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (!result.success) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`The default value of ${where} breaks its @constraint: ${result.error.issues[0]?.message}`,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\t#typed(\n\t\ttype: GraphQLInputType,\n\t\tconstraints: readonly Constraint[],\n\t\twhere: string,\n\t): z.ZodType {\n\t\tif (isNonNullType(type))\n\t\t\treturn this.#required(type.ofType, constraints, where);\n\t\treturn this.#required(type, constraints, where).nullish();\n\t}\n\n\t#required(\n\t\ttype: GraphQLInputType,\n\t\tconstraints: readonly Constraint[],\n\t\twhere: string,\n\t): z.ZodType {\n\t\tif (isNonNullType(type))\n\t\t\treturn this.#required(type.ofType, constraints, where);\n\t\tif (isListType(type)) {\n\t\t\t// minItems and maxItems are the list's; every other rule is its items'.\n\t\t\tconst own = constraints.filter(({ rule }) => rule.target === 'list');\n\t\t\tconst items = constraints.filter(({ rule }) => rule.target !== 'list');\n\t\t\tlet list: z.ZodType = z.array(this.#typed(type.ofType, items, where));\n\t\t\tfor (const { rule, value } of own)\n\t\t\t\tlist = applyRule(rule, list, value, this.#context);\n\t\t\treturn list;\n\t\t}\n\t\tif (isInputObjectType(type)) {\n\t\t\tassertObjectTargets(type.name, constraints, where);\n\t\t\treturn this.#object(type);\n\t\t}\n\t\treturn leafSchema(type, constraints, where, this.#context);\n\t}\n\n\t#object(type: GraphQLInputObjectType): z.ZodType {\n\t\tif (!this.isConstrained(type)) return z.unknown();\n\t\tconst built = this.#objects.get(type.name);\n\t\tif (built) return built;\n\t\t// Registered before the walk, so a field that comes back here ends.\n\t\tlet schema: z.ZodType | undefined;\n\t\tthis.#objects.set(\n\t\t\ttype.name,\n\t\t\tz.lazy(() => schema as z.ZodType),\n\t\t);\n\t\tschema = z.object(\n\t\t\tObject.fromEntries(\n\t\t\t\tObject.values(type.getFields()).map((field) => [\n\t\t\t\t\tfield.name,\n\t\t\t\t\tthis.of(field, `${type.name}.${field.name}`),\n\t\t\t\t]),\n\t\t\t),\n\t\t);\n\t\tthis.#objects.set(type.name, schema);\n\t\treturn schema;\n\t}\n}\n",
|
|
20
|
+
"import {\n\tGraphQLBoolean,\n\tGraphQLFloat,\n\tGraphQLID,\n\tGraphQLInt,\n\ttype GraphQLLeafType,\n\tGraphQLString,\n} from 'graphql';\nimport { z } from 'zod';\nimport { applyRule } from '../rules';\nimport type { RuleContext, Target } from '../rules/rule';\nimport type { Constraint } from './constraints';\n\n/** The kind of value each built-in scalar holds once graphql parsed it. */\nconst kinds: Record<string, Exclude<Target, 'list'>> = {\n\t[GraphQLString.name]: 'string',\n\t[GraphQLID.name]: 'string',\n\t[GraphQLInt.name]: 'number',\n\t[GraphQLFloat.name]: 'number',\n};\n\nfunction baseOf(type: GraphQLLeafType): z.ZodType {\n\tif (type.name === GraphQLInt.name) return z.number().int();\n\treturn kinds[type.name] === 'number' ? z.number() : z.string();\n}\n\n/**\n * Fails unless every constraint applies to a value of `type`: `minLength` on\n * an `Int`, anything on a custom scalar or an enum, fails, naming `where`.\n * The runtime and the code generator refuse the same schemas with the same\n * message.\n */\nexport function assertLeafTargets(\n\ttype: GraphQLLeafType,\n\tconstraints: readonly Constraint[],\n\twhere: string,\n): void {\n\tconst misplaced = constraints.find(({ rule }) => rule.target === 'list');\n\tif (misplaced) throw misplacedOn(misplaced, where, type.name);\n\tconst kind = kinds[type.name];\n\tconst wrong = constraints.find(({ rule }) => rule.target !== kind);\n\tif (wrong) throw misplacedOn(wrong, where, type.name);\n}\n\n/** Fails when an input object carries a constraint: none applies to it. */\nexport function assertObjectTargets(\n\ttypeName: string,\n\tconstraints: readonly Constraint[],\n\twhere: string,\n): void {\n\tconst first =\n\t\tconstraints.find(({ rule }) => rule.target === 'list') ?? constraints[0];\n\tif (first) throw misplacedOn(first, where, typeName);\n}\n\nfunction misplacedOn(\n\t{ rule }: Constraint,\n\twhere: string,\n\ttypeName: string,\n): Error {\n\treturn new Error(\n\t\t`@constraint(${rule.argument}) on ${where} needs ${describeTarget(rule.target)}, not ${typeName}.`,\n\t);\n}\n\n/**\n * The schema of a scalar or enum value with its constraints applied. A leaf\n * without any is left as graphql parsed it. A constraint that cannot apply\n * fails here, at startup.\n */\nexport function leafSchema(\n\ttype: GraphQLLeafType,\n\tconstraints: readonly Constraint[],\n\twhere: string,\n\tcontext: RuleContext,\n): z.ZodType {\n\tif (constraints.length === 0) return z.unknown();\n\tassertLeafTargets(type, constraints, where);\n\tlet schema = baseOf(type);\n\tfor (const { rule, value } of constraints) {\n\t\tschema = applyRule(rule, schema, value, context);\n\t}\n\treturn schema;\n}\n\n/** The source of a built-in scalar's schema, before its constraints. */\nexport function baseCode(type: GraphQLLeafType): string | undefined {\n\t// graphql's Int is 32-bit: the client refuses what it refuses.\n\tif (type.name === GraphQLInt.name) return 'z.int32()';\n\tif (type.name === GraphQLFloat.name) return 'z.number()';\n\tif (type.name === GraphQLBoolean.name) return 'z.boolean()';\n\treturn kinds[type.name] === 'string' ? 'z.string()' : undefined;\n}\n\n/** What a rule's target reads as in an error. */\nexport function describeTarget(target: Target): string {\n\tif (target === 'string') return 'a String or an ID';\n\tif (target === 'number') return 'an Int or a Float';\n\treturn 'a list';\n}\n"
|
|
21
|
+
],
|
|
22
|
+
"mappings": "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",
|
|
23
|
+
"debugId": "3026B70F7346E03264756E2164756E21",
|
|
24
|
+
"names": []
|
|
25
|
+
}
|
|
@@ -17,8 +17,8 @@ var __export = (target, all) => {
|
|
|
17
17
|
import { DirectiveLocation } from "graphql";
|
|
18
18
|
|
|
19
19
|
// src/rules/all.ts
|
|
20
|
-
var
|
|
21
|
-
__export(
|
|
20
|
+
var exports_all = {};
|
|
21
|
+
__export(exports_all, {
|
|
22
22
|
containsRule: () => containsRule,
|
|
23
23
|
endsWithRule: () => endsWithRule,
|
|
24
24
|
exclusiveMaxRule: () => exclusiveMaxRule,
|
|
@@ -37,6 +37,7 @@ __export(exports_all2, {
|
|
|
37
37
|
});
|
|
38
38
|
|
|
39
39
|
// src/rules/rule.ts
|
|
40
|
+
var RULE_PARAM = "nxgtConstraint";
|
|
40
41
|
function defineRule(rule) {
|
|
41
42
|
return rule;
|
|
42
43
|
}
|
|
@@ -78,90 +79,6 @@ var exclusiveMinRule = defineRule({
|
|
|
78
79
|
toCode: (schema, value) => `${schema}.gt(${value})`,
|
|
79
80
|
owns: (issue) => issue.code === "too_small" && issue.origin === "number" && issue.inclusive === false
|
|
80
81
|
});
|
|
81
|
-
// src/formats/all.ts
|
|
82
|
-
var exports_all = {};
|
|
83
|
-
__export(exports_all, {
|
|
84
|
-
byteFormat: () => byteFormat,
|
|
85
|
-
dateFormat: () => dateFormat,
|
|
86
|
-
dateTimeFormat: () => dateTimeFormat,
|
|
87
|
-
emailFormat: () => emailFormat,
|
|
88
|
-
ipv4Format: () => ipv4Format,
|
|
89
|
-
ipv6Format: () => ipv6Format,
|
|
90
|
-
uriFormat: () => uriFormat,
|
|
91
|
-
uuidFormat: () => uuidFormat
|
|
92
|
-
});
|
|
93
|
-
|
|
94
|
-
// src/formats/byte.ts
|
|
95
|
-
import { z } from "zod";
|
|
96
|
-
|
|
97
|
-
// src/formats/format.ts
|
|
98
|
-
function defineFormat(format) {
|
|
99
|
-
return format;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
// src/formats/byte.ts
|
|
103
|
-
var byteFormat = defineFormat({
|
|
104
|
-
name: "byte",
|
|
105
|
-
toZod: () => z.base64(),
|
|
106
|
-
toCode: () => "z.base64()"
|
|
107
|
-
});
|
|
108
|
-
// src/formats/date.ts
|
|
109
|
-
import { z as z2 } from "zod";
|
|
110
|
-
var dateFormat = defineFormat({
|
|
111
|
-
name: "date",
|
|
112
|
-
toZod: () => z2.iso.date(),
|
|
113
|
-
toCode: () => "z.iso.date()"
|
|
114
|
-
});
|
|
115
|
-
// src/formats/date-time.ts
|
|
116
|
-
import { z as z3 } from "zod";
|
|
117
|
-
var dateTimeFormat = defineFormat({
|
|
118
|
-
name: "date-time",
|
|
119
|
-
toZod: () => z3.iso.datetime({ offset: true }),
|
|
120
|
-
toCode: () => "z.iso.datetime({ offset: true })"
|
|
121
|
-
});
|
|
122
|
-
// src/formats/email.ts
|
|
123
|
-
import { z as z4 } from "zod";
|
|
124
|
-
var emailFormat = defineFormat({
|
|
125
|
-
name: "email",
|
|
126
|
-
toZod: () => z4.email(),
|
|
127
|
-
toCode: () => "z.email()"
|
|
128
|
-
});
|
|
129
|
-
// src/formats/ipv4.ts
|
|
130
|
-
import { z as z5 } from "zod";
|
|
131
|
-
var ipv4Format = defineFormat({
|
|
132
|
-
name: "ipv4",
|
|
133
|
-
toZod: () => z5.ipv4(),
|
|
134
|
-
toCode: () => "z.ipv4()"
|
|
135
|
-
});
|
|
136
|
-
// src/formats/ipv6.ts
|
|
137
|
-
import { z as z6 } from "zod";
|
|
138
|
-
var ipv6Format = defineFormat({
|
|
139
|
-
name: "ipv6",
|
|
140
|
-
toZod: () => z6.ipv6(),
|
|
141
|
-
toCode: () => "z.ipv6()"
|
|
142
|
-
});
|
|
143
|
-
// src/formats/uri.ts
|
|
144
|
-
import { z as z7 } from "zod";
|
|
145
|
-
var uriFormat = defineFormat({
|
|
146
|
-
name: "uri",
|
|
147
|
-
toZod: () => z7.url({ protocol: /^(https?|ftp)$/ }),
|
|
148
|
-
toCode: () => "z.url({ protocol: /^(https?|ftp)$/ })"
|
|
149
|
-
});
|
|
150
|
-
// src/formats/uuid.ts
|
|
151
|
-
import { z as z8 } from "zod";
|
|
152
|
-
var uuidFormat = defineFormat({
|
|
153
|
-
name: "uuid",
|
|
154
|
-
toZod: () => z8.uuid(),
|
|
155
|
-
toCode: () => "z.uuid()"
|
|
156
|
-
});
|
|
157
|
-
// src/formats/index.ts
|
|
158
|
-
var formats = Object.fromEntries(Object.values(exports_all).map((format) => [format.name, format]));
|
|
159
|
-
function formatNamed(name) {
|
|
160
|
-
if (Object.hasOwn(formats, name))
|
|
161
|
-
return formats[name];
|
|
162
|
-
throw new Error(`Unknown @constraint format "${name}". Known formats: ${Object.keys(formats).join(", ")}.`);
|
|
163
|
-
}
|
|
164
|
-
|
|
165
82
|
// src/rules/format.ts
|
|
166
83
|
var NARROWING = new Set(["starts_with", "ends_with", "includes", "regex"]);
|
|
167
84
|
var formatRule = defineRule({
|
|
@@ -169,9 +86,16 @@ var formatRule = defineRule({
|
|
|
169
86
|
type: "String",
|
|
170
87
|
target: "string",
|
|
171
88
|
base: true,
|
|
172
|
-
toZod: (_schema, value) =>
|
|
173
|
-
toCode: (_schema, value) =>
|
|
174
|
-
|
|
89
|
+
toZod: (_schema, value, { formats }) => formats.named(value).toZod(),
|
|
90
|
+
toCode: (_schema, value, { formats, formatCode }) => {
|
|
91
|
+
const format = formats.named(value);
|
|
92
|
+
if (format.toCode)
|
|
93
|
+
return format.toCode();
|
|
94
|
+
if (formatCode)
|
|
95
|
+
return formatCode(value);
|
|
96
|
+
throw new Error(`@constraint(format: "${value}") is one of the application's formats: its source is the code generator's to write, through inputCode's format option.`);
|
|
97
|
+
},
|
|
98
|
+
owns: (issue) => issue.params?.[RULE_PARAM] === "format" || issue.code === "invalid_format" && !NARROWING.has(issue.format ?? "")
|
|
175
99
|
});
|
|
176
100
|
// src/rules/max.ts
|
|
177
101
|
var maxRule = defineRule({
|
|
@@ -272,17 +196,20 @@ var startsWithRule = defineRule({
|
|
|
272
196
|
owns: (issue) => issue.format === "starts_with"
|
|
273
197
|
});
|
|
274
198
|
// src/rules/index.ts
|
|
275
|
-
var rules = Object.fromEntries(Object.values(
|
|
276
|
-
function applyRule(rule, schema, value) {
|
|
199
|
+
var rules = Object.fromEntries(Object.values(exports_all).map((rule) => [rule.argument, rule]));
|
|
200
|
+
function applyRule(rule, schema, value, context) {
|
|
277
201
|
const toZod = rule.toZod;
|
|
278
|
-
return toZod(schema, value);
|
|
202
|
+
return toZod(schema, value, context);
|
|
279
203
|
}
|
|
280
|
-
function applyRuleCode(rule, source, value) {
|
|
204
|
+
function applyRuleCode(rule, source, value, context) {
|
|
281
205
|
const toCode = rule.toCode;
|
|
282
|
-
return toCode(source, value);
|
|
206
|
+
return toCode(source, value, context);
|
|
283
207
|
}
|
|
284
208
|
function constraintOf(issue) {
|
|
285
209
|
const fields = issue;
|
|
210
|
+
const marked = fields.params?.[RULE_PARAM];
|
|
211
|
+
if (typeof marked === "string" && Object.hasOwn(rules, marked))
|
|
212
|
+
return marked;
|
|
286
213
|
return Object.values(rules).find((rule) => rule.owns(fields))?.argument;
|
|
287
214
|
}
|
|
288
215
|
|
|
@@ -313,7 +240,7 @@ function assertOwnConstraint(directive) {
|
|
|
313
240
|
}
|
|
314
241
|
}
|
|
315
242
|
|
|
316
|
-
export { rules, applyRule, applyRuleCode, constraintOf, constraintTypeDefs2, assertOwnConstraint };
|
|
243
|
+
export { __export, RULE_PARAM, rules, applyRule, applyRuleCode, constraintOf, constraintTypeDefs2, assertOwnConstraint };
|
|
317
244
|
|
|
318
|
-
//# debugId=
|
|
319
|
-
//# sourceMappingURL=index-
|
|
245
|
+
//# debugId=AD9C9BDBBBE92EA564756E2164756E21
|
|
246
|
+
//# sourceMappingURL=index-xcaf9kes.js.map
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/constraint-directive.ts", "../src/rules/rule.ts", "../src/rules/contains.ts", "../src/rules/ends-with.ts", "../src/rules/exclusive-max.ts", "../src/rules/exclusive-min.ts", "../src/rules/format.ts", "../src/rules/max.ts", "../src/rules/max-items.ts", "../src/rules/max-length.ts", "../src/rules/min.ts", "../src/rules/min-items.ts", "../src/rules/min-length.ts", "../src/rules/multiple-of.ts", "../src/rules/not-contains.ts", "../src/rules/pattern.ts", "../src/rules/starts-with.ts", "../src/rules/index.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"import { DirectiveLocation, type GraphQLDirective } from 'graphql';\nimport { rules } from './rules';\n\n/**\n * The SDL of `@constraint`, to add to a schema-first server's `typeDefs`,\n * written from the rules: an argument is declared once its rule exists.\n *\n * Its arguments are graphql-constraint-directive's, minus `uniqueTypeName`\n * (a detail of that package's scalar wrapping). It is allowed on arguments\n * and input fields only, where that package also allows output fields: a\n * resolver's result is the output scalars' job, and a directive that checked\n * nothing there would be a promise broken in silence.\n */\nexport const constraintTypeDefs: string = `directive @constraint(\n${Object.values(rules)\n\t.map((rule) => `\\t${rule.argument}: ${rule.type}`)\n\t.join('\\n')}\n) on ARGUMENT_DEFINITION | INPUT_FIELD_DEFINITION\n`;\n\nconst allowed = new Set<string>([\n\tDirectiveLocation.ARGUMENT_DEFINITION,\n\tDirectiveLocation.INPUT_FIELD_DEFINITION,\n]);\n\n/**\n * Fails when the schema's `@constraint` is not the one\n * {@link constraintTypeDefs} declares — graphql-constraint-directive's, say,\n * kept from a migration. Its extra locations would be accepted and checked\n * by nothing, its extra arguments mean nothing here, and an argument of\n * another type would reach a rule as the wrong kind of value.\n */\nexport function assertOwnConstraint(directive: GraphQLDirective): void {\n\tconst problems = [\n\t\t...(directive.isRepeatable\n\t\t\t? ['repeatable, and only its first use is read']\n\t\t\t: []),\n\t\t...directive.locations\n\t\t\t.filter((location) => !allowed.has(location))\n\t\t\t.map((location) => `allowed on ${location}`),\n\t\t...directive.args.flatMap((arg) => {\n\t\t\tconst rule = (rules as Record<string, { type: string } | undefined>)[\n\t\t\t\targ.name\n\t\t\t];\n\t\t\tif (!rule) return [`declares ${arg.name}, which no rule reads`];\n\t\t\tconst type = String(arg.type);\n\t\t\treturn type === rule.type\n\t\t\t\t? []\n\t\t\t\t: [`declares ${arg.name}: ${type}, not ${rule.type}`];\n\t\t}),\n\t];\n\tif (problems.length > 0) {\n\t\tthrow new Error(\n\t\t\t`This schema's @constraint is not constraintTypeDefs': it is ${problems.join('; ')}. Declare it with constraintTypeDefs.`,\n\t\t);\n\t}\n}\n",
|
|
6
|
+
"import type { z } from 'zod';\nimport type { StringSchema } from '../formats/format';\nimport type { FormatRegistry } from '../formats/registry';\n\n/** The schema each kind of rule narrows. */\nexport interface Targets {\n\tstring: StringSchema;\n\tnumber: z.ZodNumber;\n\tlist: z.ZodArray<z.ZodType>;\n}\n\nexport type Target = keyof Targets;\n\n/**\n * What a rule may read besides its value: the formats `format` resolves\n * against, the built-in ones and the application's own, and, when writing\n * source, how to write one of the application's (`InputCodeOptions.format`).\n */\nexport interface RuleContext {\n\treadonly formats: FormatRegistry;\n\treadonly formatCode?: ((name: string) => string) | undefined;\n}\n\n/** What a `@constraint` argument's value can be. */\ninterface ValueOf {\n\tInt: number;\n\tFloat: number;\n\tString: string;\n}\n\n/**\n * One `@constraint` argument: its GraphQL type in the directive's SDL, the\n * kind of value it narrows, and the same narrowing twice — `toZod` applied to\n * a schema at startup, `toCode` written as source by a code generator. The\n * spec beside each rule proves the two accept and refuse the same values.\n *\n * A `base` rule (only `format`) replaces the schema instead of narrowing it,\n * so a builder applies it before every other rule of its target.\n */\nexport interface Rule<\n\tA extends string = string,\n\tT extends keyof ValueOf = keyof ValueOf,\n\tK extends Target = Target,\n> {\n\treadonly argument: A;\n\treadonly type: T;\n\treadonly target: K;\n\treadonly base?: true;\n\treadonly toZod: (\n\t\tschema: Targets[K],\n\t\tvalue: ValueOf[T],\n\t\tcontext: RuleContext,\n\t) => Targets[K];\n\t/**\n\t * `schema` is the source of the schema this rule narrows. The source names\n\t * zod as a free `z`: the generated file imports it.\n\t */\n\treadonly toCode: (\n\t\tschema: string,\n\t\tvalue: ValueOf[T],\n\t\tcontext: RuleContext,\n\t) => string;\n\t/**\n\t * Whether a Zod issue is this rule's refusal, so the error a client gets\n\t * names the rule (`constraint: 'minLength'`), which does not change with\n\t * Zod's own issue codes.\n\t */\n\treadonly owns: (issue: IssueFields) => boolean;\n}\n\n/** The fields of a Zod issue a rule recognises its refusal by. */\nexport interface IssueFields {\n\treadonly code: string;\n\treadonly origin?: string;\n\treadonly format?: string;\n\treadonly inclusive?: boolean;\n\treadonly params?: Readonly<Record<string, unknown>>;\n}\n\n/**\n * The `params` key that marks an issue as one argument's whatever its code:\n * an application format's issues carry `format` there, so a `.regex()` or a\n * `.refine()` inside one is not read as `pattern` or `notContains`.\n */\nexport const RULE_PARAM = 'nxgtConstraint';\n\n/** Declares a rule, with its argument name kept literal. */\nexport function defineRule<\n\tconst A extends string,\n\tT extends keyof ValueOf,\n\tK extends Target,\n>(rule: Rule<A, T, K>): Rule<A, T, K> {\n\treturn rule;\n}\n\n/** A string literal as source: quotes and escapes included. */\nexport const literal = (value: string): string => JSON.stringify(value);\n",
|
|
7
|
+
"import { defineRule, literal } from './rule';\n\nexport const containsRule = defineRule({\n\targument: 'contains',\n\ttype: 'String',\n\ttarget: 'string',\n\ttoZod: (schema, value) => schema.includes(value),\n\ttoCode: (schema, value) => `${schema}.includes(${literal(value)})`,\n\towns: (issue) => issue.format === 'includes',\n});\n",
|
|
8
|
+
"import { defineRule, literal } from './rule';\n\nexport const endsWithRule = defineRule({\n\targument: 'endsWith',\n\ttype: 'String',\n\ttarget: 'string',\n\ttoZod: (schema, value) => schema.endsWith(value),\n\ttoCode: (schema, value) => `${schema}.endsWith(${literal(value)})`,\n\towns: (issue) => issue.format === 'ends_with',\n});\n",
|
|
9
|
+
"import { defineRule } from './rule';\n\nexport const exclusiveMaxRule = defineRule({\n\targument: 'exclusiveMax',\n\ttype: 'Float',\n\ttarget: 'number',\n\ttoZod: (schema, value) => schema.lt(value),\n\ttoCode: (schema, value) => `${schema}.lt(${value})`,\n\towns: (issue) =>\n\t\tissue.code === 'too_big' &&\n\t\tissue.origin === 'number' &&\n\t\tissue.inclusive === false,\n});\n",
|
|
10
|
+
"import { defineRule } from './rule';\n\nexport const exclusiveMinRule = defineRule({\n\targument: 'exclusiveMin',\n\ttype: 'Float',\n\ttarget: 'number',\n\ttoZod: (schema, value) => schema.gt(value),\n\ttoCode: (schema, value) => `${schema}.gt(${value})`,\n\towns: (issue) =>\n\t\tissue.code === 'too_small' &&\n\t\tissue.origin === 'number' &&\n\t\tissue.inclusive === false,\n});\n",
|
|
11
|
+
"import { defineRule, RULE_PARAM } from './rule';\n\n// The string rules' own formats; every other invalid_format is a format's.\nconst NARROWING = new Set(['starts_with', 'ends_with', 'includes', 'regex']);\n\nexport const formatRule = defineRule({\n\targument: 'format',\n\ttype: 'String',\n\ttarget: 'string',\n\tbase: true,\n\ttoZod: (_schema, value, { formats }) => formats.named(value).toZod(),\n\ttoCode: (_schema, value, { formats, formatCode }) => {\n\t\tconst format = formats.named(value);\n\t\tif (format.toCode) return format.toCode();\n\t\tif (formatCode) return formatCode(value);\n\t\tthrow new Error(\n\t\t\t`@constraint(format: \"${value}\") is one of the application's formats: its source is the code generator's to write, through inputCode's format option.`,\n\t\t);\n\t},\n\t// An application format's issues are marked, whatever their code\n\t// (`custom` for a `.refine()`): see FormatRegistry.\n\towns: (issue) =>\n\t\tissue.params?.[RULE_PARAM] === 'format' ||\n\t\t(issue.code === 'invalid_format' && !NARROWING.has(issue.format ?? '')),\n});\n",
|
|
12
|
+
"import { defineRule } from './rule';\n\nexport const maxRule = defineRule({\n\targument: 'max',\n\ttype: 'Float',\n\ttarget: 'number',\n\ttoZod: (schema, value) => schema.lte(value),\n\ttoCode: (schema, value) => `${schema}.lte(${value})`,\n\towns: (issue) =>\n\t\tissue.code === 'too_big' &&\n\t\tissue.origin === 'number' &&\n\t\tissue.inclusive === true,\n});\n",
|
|
13
|
+
"import { defineRule } from './rule';\n\nexport const maxItemsRule = defineRule({\n\targument: 'maxItems',\n\ttype: 'Int',\n\ttarget: 'list',\n\ttoZod: (schema, value) => schema.max(value),\n\ttoCode: (schema, value) => `${schema}.max(${value})`,\n\towns: (issue) => issue.code === 'too_big' && issue.origin === 'array',\n});\n",
|
|
14
|
+
"import { defineRule } from './rule';\n\nexport const maxLengthRule = defineRule({\n\targument: 'maxLength',\n\ttype: 'Int',\n\ttarget: 'string',\n\ttoZod: (schema, value) => schema.max(value),\n\ttoCode: (schema, value) => `${schema}.max(${value})`,\n\towns: (issue) => issue.code === 'too_big' && issue.origin === 'string',\n});\n",
|
|
15
|
+
"import { defineRule } from './rule';\n\nexport const minRule = defineRule({\n\targument: 'min',\n\ttype: 'Float',\n\ttarget: 'number',\n\ttoZod: (schema, value) => schema.gte(value),\n\ttoCode: (schema, value) => `${schema}.gte(${value})`,\n\towns: (issue) =>\n\t\tissue.code === 'too_small' &&\n\t\tissue.origin === 'number' &&\n\t\tissue.inclusive === true,\n});\n",
|
|
16
|
+
"import { defineRule } from './rule';\n\nexport const minItemsRule = defineRule({\n\targument: 'minItems',\n\ttype: 'Int',\n\ttarget: 'list',\n\ttoZod: (schema, value) => schema.min(value),\n\ttoCode: (schema, value) => `${schema}.min(${value})`,\n\towns: (issue) => issue.code === 'too_small' && issue.origin === 'array',\n});\n",
|
|
17
|
+
"import { defineRule } from './rule';\n\nexport const minLengthRule = defineRule({\n\targument: 'minLength',\n\ttype: 'Int',\n\ttarget: 'string',\n\ttoZod: (schema, value) => schema.min(value),\n\ttoCode: (schema, value) => `${schema}.min(${value})`,\n\towns: (issue) => issue.code === 'too_small' && issue.origin === 'string',\n});\n",
|
|
18
|
+
"import { defineRule } from './rule';\n\nexport const multipleOfRule = defineRule({\n\targument: 'multipleOf',\n\ttype: 'Float',\n\ttarget: 'number',\n\ttoZod: (schema, value) => schema.multipleOf(value),\n\ttoCode: (schema, value) => `${schema}.multipleOf(${value})`,\n\towns: (issue) => issue.code === 'not_multiple_of',\n});\n",
|
|
19
|
+
"import { defineRule, literal } from './rule';\n\nconst message = (value: string) => `Must not contain ${literal(value)}`;\n\nexport const notContainsRule = defineRule({\n\targument: 'notContains',\n\ttype: 'String',\n\ttarget: 'string',\n\t// `refine` keeps the schema's own type, so later rules still chain.\n\ttoZod: (schema, value) =>\n\t\tschema.refine((input) => !input.includes(value), message(value)),\n\ttoCode: (schema, value) =>\n\t\t`${schema}.refine((input) => !input.includes(${literal(value)}), ${literal(message(value))})`,\n\towns: (issue) => issue.code === 'custom',\n});\n",
|
|
20
|
+
"import { defineRule, literal } from './rule';\n\n/** The pattern as a RegExp, or an error that names the argument. */\nfunction compile(value: string): RegExp {\n\ttry {\n\t\treturn new RegExp(value);\n\t} catch (error) {\n\t\tthrow new Error(\n\t\t\t`Invalid @constraint pattern ${literal(value)}: ${(error as Error).message}`,\n\t\t);\n\t}\n}\n\nexport const patternRule = defineRule({\n\targument: 'pattern',\n\ttype: 'String',\n\ttarget: 'string',\n\ttoZod: (schema, value) => schema.regex(compile(value)),\n\ttoCode: (schema, value) =>\n\t\t`${schema}.regex(new RegExp(${literal(compile(value).source)}))`,\n\towns: (issue) => issue.format === 'regex',\n});\n",
|
|
21
|
+
"import { defineRule, literal } from './rule';\n\nexport const startsWithRule = defineRule({\n\targument: 'startsWith',\n\ttype: 'String',\n\ttarget: 'string',\n\ttoZod: (schema, value) => schema.startsWith(value),\n\ttoCode: (schema, value) => `${schema}.startsWith(${literal(value)})`,\n\towns: (issue) => issue.format === 'starts_with',\n});\n",
|
|
22
|
+
"import type { z } from 'zod';\nimport * as all from './all';\nimport { type IssueFields, RULE_PARAM, type RuleContext } from './rule';\n\n/**\n * One of the rules, as its own type: a builder narrows it on `target`, so a\n * number schema never reaches a string rule.\n */\nexport type RegisteredRule = (typeof all)[keyof typeof all];\n\n/** An argument `@constraint` takes. */\nexport type ConstraintArgument = RegisteredRule['argument'];\n\n/**\n * Every rule, keyed by its `@constraint` argument. Derived from what\n * `./all` exports, so a new rule is one file and one line there, and the\n * directive's SDL follows.\n */\nexport const rules = Object.fromEntries(\n\tObject.values(all).map((rule) => [rule.argument, rule]),\n) as {\n\treadonly [A in ConstraintArgument]: Extract<RegisteredRule, { argument: A }>;\n};\n\n/**\n * Applies a rule to a schema its caller has already matched to the rule's\n * target: the one place the rule's typed `toZod` meets a schema built from\n * GraphQL types, which the compiler cannot relate.\n */\nexport function applyRule(\n\trule: RegisteredRule,\n\tschema: z.ZodType,\n\tvalue: string | number,\n\tcontext: RuleContext,\n): z.ZodType {\n\tconst toZod = rule.toZod as unknown as (\n\t\tschema: z.ZodType,\n\t\tvalue: string | number,\n\t\tcontext: RuleContext,\n\t) => z.ZodType;\n\treturn toZod(schema, value, context);\n}\n\n/** `applyRule` for source: the rule's typed `toCode` on a schema's source. */\nexport function applyRuleCode(\n\trule: RegisteredRule,\n\tsource: string,\n\tvalue: string | number,\n\tcontext: RuleContext,\n): string {\n\tconst toCode = rule.toCode as (\n\t\tschema: string,\n\t\tvalue: string | number,\n\t\tcontext: RuleContext,\n\t) => string;\n\treturn toCode(source, value, context);\n}\n\n/**\n * The `@constraint` argument whose rule refused with this issue, if any: the\n * one the issue is marked with (an application format's), else the one rule\n * that owns its shape.\n */\nexport function constraintOf(\n\tissue: z.core.$ZodIssue,\n): ConstraintArgument | undefined {\n\tconst fields = issue as unknown as IssueFields;\n\tconst marked = fields.params?.[RULE_PARAM];\n\tif (typeof marked === 'string' && Object.hasOwn(rules, marked))\n\t\treturn marked as ConstraintArgument;\n\treturn Object.values(rules).find((rule) => rule.owns(fields))?.argument;\n}\n"
|
|
23
|
+
],
|
|
24
|
+
"mappings": "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",
|
|
25
|
+
"debugId": "AD9C9BDBBBE92EA564756E2164756E21",
|
|
26
|
+
"names": []
|
|
27
|
+
}
|
package/dist/cli.js
CHANGED
package/dist/codegen.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
export { checkConstraints } from './builder/check-constraints';
|
|
2
|
-
export { type Constraint, constraintsOn } from './builder/constraints';
|
|
3
|
-
export { type InputCodeOptions, inputCode } from './builder/input-code';
|
|
1
|
+
export { checkConstraints } from './builder/check-constraints.js';
|
|
2
|
+
export { type Constraint, constraintsOn } from './builder/constraints.js';
|
|
3
|
+
export { type InputCodeOptions, inputCode } from './builder/input-code.js';
|
|
4
|
+
export type { FormatSchemas } from './formats/registry.js';
|
|
4
5
|
//# sourceMappingURL=codegen.d.ts.map
|
package/dist/codegen.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"codegen.d.ts","sourceRoot":"","sources":["../src/codegen.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,EAAE,KAAK,UAAU,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACvE,OAAO,EAAE,KAAK,gBAAgB,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC"}
|
|
1
|
+
{"version":3,"file":"codegen.d.ts","sourceRoot":"","sources":["../src/codegen.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,EAAE,KAAK,UAAU,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACvE,OAAO,EAAE,KAAK,gBAAgB,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACxE,YAAY,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC"}
|
package/dist/codegen.js
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import {
|
|
2
2
|
applyRuleCode
|
|
3
|
-
} from "./chunks/index-
|
|
3
|
+
} from "./chunks/index-xcaf9kes.js";
|
|
4
4
|
import {
|
|
5
|
+
registryOf,
|
|
5
6
|
constraintsOn2,
|
|
6
7
|
assertLeafTargets,
|
|
7
8
|
assertObjectTargets,
|
|
8
9
|
baseCode,
|
|
9
10
|
checkConstraints2
|
|
10
|
-
} from "./chunks/index-
|
|
11
|
+
} from "./chunks/index-1mzzydy3.js";
|
|
11
12
|
// src/builder/input-code.ts
|
|
12
13
|
import {
|
|
13
14
|
getNamedType,
|
|
@@ -15,8 +16,13 @@ import {
|
|
|
15
16
|
isListType,
|
|
16
17
|
isNonNullType
|
|
17
18
|
} from "graphql";
|
|
18
|
-
function inputCode(type, constraints, where, named, options = {}) {
|
|
19
|
-
const write = {
|
|
19
|
+
function inputCode(type, constraints, where, named, options = {}, formats) {
|
|
20
|
+
const write = {
|
|
21
|
+
where,
|
|
22
|
+
named,
|
|
23
|
+
options,
|
|
24
|
+
formats: registryOf(formats)
|
|
25
|
+
};
|
|
20
26
|
return typedCode(write, type, constraints);
|
|
21
27
|
}
|
|
22
28
|
function typedCode(write, type, constraints) {
|
|
@@ -30,7 +36,7 @@ function requiredCode(write, type, constraints) {
|
|
|
30
36
|
if (isListType(type)) {
|
|
31
37
|
const own = constraints.filter(({ rule }) => rule.target === "list");
|
|
32
38
|
const items = constraints.filter(({ rule }) => rule.target !== "list");
|
|
33
|
-
const code = applyCode(`z.array(${typedCode(write, type.ofType, items)})`, own);
|
|
39
|
+
const code = applyCode(write, `z.array(${typedCode(write, type.ofType, items)})`, own);
|
|
34
40
|
if (!write.options.list)
|
|
35
41
|
return code;
|
|
36
42
|
const single = requiredCode(write, getNamedType(type), []);
|
|
@@ -41,10 +47,14 @@ function requiredCode(write, type, constraints) {
|
|
|
41
47
|
return write.named(type);
|
|
42
48
|
}
|
|
43
49
|
assertLeafTargets(type, constraints, write.where);
|
|
44
|
-
return applyCode(baseCode(type) ?? write.named(type), constraints);
|
|
50
|
+
return applyCode(write, baseCode(type) ?? write.named(type), constraints);
|
|
45
51
|
}
|
|
46
|
-
function applyCode(source, constraints) {
|
|
47
|
-
|
|
52
|
+
function applyCode(write, source, constraints) {
|
|
53
|
+
const context = {
|
|
54
|
+
formats: write.formats,
|
|
55
|
+
formatCode: write.options.format
|
|
56
|
+
};
|
|
57
|
+
return constraints.reduce((code, { rule, value }) => applyRuleCode(rule, code, value, context), source);
|
|
48
58
|
}
|
|
49
59
|
export {
|
|
50
60
|
checkConstraints2 as checkConstraints,
|
|
@@ -52,5 +62,5 @@ export {
|
|
|
52
62
|
inputCode
|
|
53
63
|
};
|
|
54
64
|
|
|
55
|
-
//# debugId=
|
|
65
|
+
//# debugId=95B0758BEEE7072864756E2164756E21
|
|
56
66
|
//# sourceMappingURL=codegen.js.map
|
package/dist/codegen.js.map
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/builder/input-code.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
|
-
"import {\n\ttype GraphQLInputType,\n\ttype GraphQLList,\n\ttype GraphQLNamedInputType,\n\tgetNamedType,\n\tisInputObjectType,\n\tisListType,\n\tisNonNullType,\n} from 'graphql';\nimport { applyRuleCode } from '../rules';\nimport type { Constraint } from './constraints';\nimport { assertLeafTargets, assertObjectTargets, baseCode } from './leaf';\n\n/**\n * The source of the schema of one argument or input field: what\n * `InputSchemas` builds at startup, written for a code generator. The\n * source names zod as a free `z`.\n *\n * The runtime leaves what graphql already checked to graphql; generated\n * code checks every value, so each named type comes from `named`: an input\n * object's or an enum's schema by name, a custom scalar's from a mapping.\n * The built-in scalars are written here, with their constraints. A\n * constraint that cannot apply fails as it does at startup.\n */\nexport function inputCode(\n\ttype: GraphQLInputType,\n\tconstraints: readonly Constraint[],\n\twhere: string,\n\tnamed: (type: GraphQLNamedInputType) => string,\n\toptions: InputCodeOptions = {},\n): string {\n\tconst write: Write = {
|
|
5
|
+
"import {\n\ttype GraphQLInputType,\n\ttype GraphQLList,\n\ttype GraphQLNamedInputType,\n\tgetNamedType,\n\tisInputObjectType,\n\tisListType,\n\tisNonNullType,\n} from 'graphql';\nimport {\n\ttype FormatRegistry,\n\ttype FormatSchemas,\n\tregistryOf,\n} from '../formats/registry';\nimport { applyRuleCode } from '../rules';\nimport type { Constraint } from './constraints';\nimport { assertLeafTargets, assertObjectTargets, baseCode } from './leaf';\n\n/**\n * The source of the schema of one argument or input field: what\n * `InputSchemas` builds at startup, written for a code generator. The\n * source names zod as a free `z`.\n *\n * The runtime leaves what graphql already checked to graphql; generated\n * code checks every value, so each named type comes from `named`: an input\n * object's or an enum's schema by name, a custom scalar's from a mapping.\n * The built-in scalars are written here, with their constraints. A\n * constraint that cannot apply fails as it does at startup.\n *\n * `formats` are the application's own, as `withValidation` takes them: a\n * name among them is a known format, which a built-in one is not. Their\n * source is `options.format`'s to write.\n */\nexport function inputCode(\n\ttype: GraphQLInputType,\n\tconstraints: readonly Constraint[],\n\twhere: string,\n\tnamed: (type: GraphQLNamedInputType) => string,\n\toptions: InputCodeOptions = {},\n\tformats?: FormatSchemas,\n): string {\n\tconst write: Write = {\n\t\twhere,\n\t\tnamed,\n\t\toptions,\n\t\tformats: registryOf(formats),\n\t};\n\treturn typedCode(write, type, constraints);\n}\n\n/** How `inputCode` writes what a generator may want written otherwise. */\nexport interface InputCodeOptions {\n\t/**\n\t * A list's schema, given its `type`, `code` (the array with every rule)\n\t * and `single` (the list's named type, non-null, without rules): to\n\t * take a single value for a list, as graphql does, `single` wrapped then\n\t * piped into `code`. Default: `code`.\n\t */\n\treadonly list?: (list: {\n\t\treadonly type: GraphQLList<GraphQLInputType>;\n\t\treadonly code: string;\n\t\treadonly single: string;\n\t}) => string;\n\t/**\n\t * The source of one of the application's formats, given its name (a key\n\t * of the `formats` record): a reference to the application's own schema,\n\t * which the rules after `format` narrow (`formatSchemas.slug.max(40)`).\n\t * A built-in format is written inline and never reaches it. Without it,\n\t * a field using one of the application's formats throws.\n\t */\n\treadonly format?: (name: string) => string;\n}\n\ninterface Write {\n\treadonly where: string;\n\treadonly named: (type: GraphQLNamedInputType) => string;\n\treadonly options: InputCodeOptions;\n\treadonly formats: FormatRegistry;\n}\n\nfunction typedCode(\n\twrite: Write,\n\ttype: GraphQLInputType,\n\tconstraints: readonly Constraint[],\n): string {\n\tif (isNonNullType(type)) return requiredCode(write, type.ofType, constraints);\n\treturn `${requiredCode(write, type, constraints)}.nullish()`;\n}\n\nfunction requiredCode(\n\twrite: Write,\n\ttype: GraphQLInputType,\n\tconstraints: readonly Constraint[],\n): string {\n\tif (isNonNullType(type)) return requiredCode(write, type.ofType, constraints);\n\tif (isListType(type)) {\n\t\t// minItems and maxItems are the list's; every other rule is its items'.\n\t\tconst own = constraints.filter(({ rule }) => rule.target === 'list');\n\t\tconst items = constraints.filter(({ rule }) => rule.target !== 'list');\n\t\tconst code = applyCode(\n\t\t\twrite,\n\t\t\t`z.array(${typedCode(write, type.ofType, items)})`,\n\t\t\town,\n\t\t);\n\t\tif (!write.options.list) return code;\n\t\tconst single = requiredCode(write, getNamedType(type), []);\n\t\treturn write.options.list({ type, code, single });\n\t}\n\tif (isInputObjectType(type)) {\n\t\tassertObjectTargets(type.name, constraints, write.where);\n\t\treturn write.named(type);\n\t}\n\tassertLeafTargets(type, constraints, write.where);\n\treturn applyCode(write, baseCode(type) ?? write.named(type), constraints);\n}\n\nfunction applyCode(\n\twrite: Write,\n\tsource: string,\n\tconstraints: readonly Constraint[],\n): string {\n\tconst context = {\n\t\tformats: write.formats,\n\t\tformatCode: write.options.format,\n\t};\n\treturn constraints.reduce(\n\t\t(code, { rule, value }) => applyRuleCode(rule, code, value, context),\n\t\tsource,\n\t);\n}\n"
|
|
6
6
|
],
|
|
7
|
-
"mappings": "
|
|
8
|
-
"debugId": "
|
|
7
|
+
"mappings": ";;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAiCO,SAAS,SAAS,CACxB,MACA,aACA,OACA,OACA,UAA4B,CAAC,GAC7B,SACS;AAAA,EACT,MAAM,QAAe;AAAA,IACpB;AAAA,IACA;AAAA,IACA;AAAA,IACA,SAAS,WAAW,OAAO;AAAA,EAC5B;AAAA,EACA,OAAO,UAAU,OAAO,MAAM,WAAW;AAAA;AAiC1C,SAAS,SAAS,CACjB,OACA,MACA,aACS;AAAA,EACT,IAAI,cAAc,IAAI;AAAA,IAAG,OAAO,aAAa,OAAO,KAAK,QAAQ,WAAW;AAAA,EAC5E,OAAO,GAAG,aAAa,OAAO,MAAM,WAAW;AAAA;AAGhD,SAAS,YAAY,CACpB,OACA,MACA,aACS;AAAA,EACT,IAAI,cAAc,IAAI;AAAA,IAAG,OAAO,aAAa,OAAO,KAAK,QAAQ,WAAW;AAAA,EAC5E,IAAI,WAAW,IAAI,GAAG;AAAA,IAErB,MAAM,MAAM,YAAY,OAAO,GAAG,WAAW,KAAK,WAAW,MAAM;AAAA,IACnE,MAAM,QAAQ,YAAY,OAAO,GAAG,WAAW,KAAK,WAAW,MAAM;AAAA,IACrE,MAAM,OAAO,UACZ,OACA,WAAW,UAAU,OAAO,KAAK,QAAQ,KAAK,MAC9C,GACD;AAAA,IACA,IAAI,CAAC,MAAM,QAAQ;AAAA,MAAM,OAAO;AAAA,IAChC,MAAM,SAAS,aAAa,OAAO,aAAa,IAAI,GAAG,CAAC,CAAC;AAAA,IACzD,OAAO,MAAM,QAAQ,KAAK,EAAE,MAAM,MAAM,OAAO,CAAC;AAAA,EACjD;AAAA,EACA,IAAI,kBAAkB,IAAI,GAAG;AAAA,IAC5B,oBAAoB,KAAK,MAAM,aAAa,MAAM,KAAK;AAAA,IACvD,OAAO,MAAM,MAAM,IAAI;AAAA,EACxB;AAAA,EACA,kBAAkB,MAAM,aAAa,MAAM,KAAK;AAAA,EAChD,OAAO,UAAU,OAAO,SAAS,IAAI,KAAK,MAAM,MAAM,IAAI,GAAG,WAAW;AAAA;AAGzE,SAAS,SAAS,CACjB,OACA,QACA,aACS;AAAA,EACT,MAAM,UAAU;AAAA,IACf,SAAS,MAAM;AAAA,IACf,YAAY,MAAM,QAAQ;AAAA,EAC3B;AAAA,EACA,OAAO,YAAY,OAClB,CAAC,QAAQ,MAAM,YAAY,cAAc,MAAM,MAAM,OAAO,OAAO,GACnE,MACD;AAAA;",
|
|
8
|
+
"debugId": "95B0758BEEE7072864756E2164756E21",
|
|
9
9
|
"names": []
|
|
10
10
|
}
|
package/dist/formats/all.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
export * from './byte';
|
|
2
|
-
export * from './date';
|
|
3
|
-
export * from './date-time';
|
|
4
|
-
export * from './email';
|
|
5
|
-
export * from './ipv4';
|
|
6
|
-
export * from './ipv6';
|
|
7
|
-
export * from './uri';
|
|
8
|
-
export * from './uuid';
|
|
1
|
+
export * from './byte.js';
|
|
2
|
+
export * from './date.js';
|
|
3
|
+
export * from './date-time.js';
|
|
4
|
+
export * from './email.js';
|
|
5
|
+
export * from './ipv4.js';
|
|
6
|
+
export * from './ipv6.js';
|
|
7
|
+
export * from './uri.js';
|
|
8
|
+
export * from './uuid.js';
|
|
9
9
|
//# sourceMappingURL=all.d.ts.map
|
package/dist/formats/byte.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const byteFormat: import("./format").
|
|
1
|
+
export declare const byteFormat: import("./format.js").BuiltInFormat<"byte">;
|
|
2
2
|
//# sourceMappingURL=byte.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"byte.d.ts","sourceRoot":"","sources":["../../src/formats/byte.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,UAAU,
|
|
1
|
+
{"version":3,"file":"byte.d.ts","sourceRoot":"","sources":["../../src/formats/byte.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,UAAU,0CAIrB,CAAC"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const dateTimeFormat: import("./format").
|
|
1
|
+
export declare const dateTimeFormat: import("./format.js").BuiltInFormat<"date-time">;
|
|
2
2
|
//# sourceMappingURL=date-time.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"date-time.d.ts","sourceRoot":"","sources":["../../src/formats/date-time.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,cAAc,
|
|
1
|
+
{"version":3,"file":"date-time.d.ts","sourceRoot":"","sources":["../../src/formats/date-time.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,cAAc,+CAIzB,CAAC"}
|
package/dist/formats/date.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const dateFormat: import("./format").
|
|
1
|
+
export declare const dateFormat: import("./format.js").BuiltInFormat<"date">;
|
|
2
2
|
//# sourceMappingURL=date.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"date.d.ts","sourceRoot":"","sources":["../../src/formats/date.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,UAAU,
|
|
1
|
+
{"version":3,"file":"date.d.ts","sourceRoot":"","sources":["../../src/formats/date.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,UAAU,0CAIrB,CAAC"}
|
package/dist/formats/email.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const emailFormat: import("./format").
|
|
1
|
+
export declare const emailFormat: import("./format.js").BuiltInFormat<"email">;
|
|
2
2
|
//# sourceMappingURL=email.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"email.d.ts","sourceRoot":"","sources":["../../src/formats/email.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,WAAW,
|
|
1
|
+
{"version":3,"file":"email.d.ts","sourceRoot":"","sources":["../../src/formats/email.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,WAAW,2CAItB,CAAC"}
|
package/dist/formats/format.d.ts
CHANGED
|
@@ -3,13 +3,19 @@ import type { z } from 'zod';
|
|
|
3
3
|
export type StringSchema = z.ZodString | z.ZodStringFormat;
|
|
4
4
|
/**
|
|
5
5
|
* One value of `@constraint(format: "...")`: the schema it stands for, as a
|
|
6
|
-
* schema at startup and as source for a code generator.
|
|
6
|
+
* schema at startup and, for a built-in one, as source for a code generator.
|
|
7
|
+
* A format of the application's own has no `toCode`: the generator writes a
|
|
8
|
+
* reference to the application's schema instead.
|
|
7
9
|
*/
|
|
8
10
|
export interface Format<N extends string = string> {
|
|
9
11
|
readonly name: N;
|
|
10
12
|
readonly toZod: () => StringSchema;
|
|
13
|
+
readonly toCode?: () => string;
|
|
14
|
+
}
|
|
15
|
+
/** A format this package ships: written twice, as a schema and as source. */
|
|
16
|
+
export interface BuiltInFormat<N extends string = string> extends Format<N> {
|
|
11
17
|
readonly toCode: () => string;
|
|
12
18
|
}
|
|
13
|
-
/** Declares a format, with its name kept literal. */
|
|
14
|
-
export declare function defineFormat<const N extends string>(format:
|
|
19
|
+
/** Declares a built-in format, with its name kept literal. */
|
|
20
|
+
export declare function defineFormat<const N extends string>(format: BuiltInFormat<N>): BuiltInFormat<N>;
|
|
15
21
|
//# sourceMappingURL=format.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../../src/formats/format.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAE7B,+EAA+E;AAC/E,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,SAAS,GAAG,CAAC,CAAC,eAAe,CAAC;AAE3D
|
|
1
|
+
{"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../../src/formats/format.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAE7B,+EAA+E;AAC/E,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,SAAS,GAAG,CAAC,CAAC,eAAe,CAAC;AAE3D;;;;;GAKG;AACH,MAAM,WAAW,MAAM,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM;IAChD,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;IACjB,QAAQ,CAAC,KAAK,EAAE,MAAM,YAAY,CAAC;IACnC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,MAAM,CAAC;CAC/B;AAED,6EAA6E;AAC7E,MAAM,WAAW,aAAa,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,CAAE,SAAQ,MAAM,CAAC,CAAC,CAAC;IAC1E,QAAQ,CAAC,MAAM,EAAE,MAAM,MAAM,CAAC;CAC9B;AAED,8DAA8D;AAC9D,wBAAgB,YAAY,CAAC,KAAK,CAAC,CAAC,SAAS,MAAM,EAClD,MAAM,EAAE,aAAa,CAAC,CAAC,CAAC,GACtB,aAAa,CAAC,CAAC,CAAC,CAElB"}
|
package/dist/formats/index.d.ts
CHANGED
|
@@ -1,13 +1,11 @@
|
|
|
1
|
-
import * as all from './all';
|
|
2
|
-
import type {
|
|
1
|
+
import * as all from './all.js';
|
|
2
|
+
import type { BuiltInFormat } from './format.js';
|
|
3
3
|
/**
|
|
4
|
-
* Every format, keyed by the value `@constraint(format: "...")`
|
|
5
|
-
* Derived from what `./all` exports, so a new format is one file and
|
|
6
|
-
* line there.
|
|
4
|
+
* Every built-in format, keyed by the value `@constraint(format: "...")`
|
|
5
|
+
* takes. Derived from what `./all` exports, so a new format is one file and
|
|
6
|
+
* one line there.
|
|
7
7
|
*/
|
|
8
|
-
export declare const formats: { readonly [N in FormatName]:
|
|
9
|
-
/** A value `@constraint(format: "...")` takes. */
|
|
8
|
+
export declare const formats: { readonly [N in FormatName]: BuiltInFormat<N>; };
|
|
9
|
+
/** A value `@constraint(format: "...")` takes without the application's formats. */
|
|
10
10
|
export type FormatName = (typeof all)[keyof typeof all]['name'];
|
|
11
|
-
/** The format named `name`, or an error that lists the known ones. */
|
|
12
|
-
export declare function formatNamed(name: string): Format;
|
|
13
11
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/formats/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,GAAG,MAAM,OAAO,CAAC;AAC7B,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/formats/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,GAAG,MAAM,OAAO,CAAC;AAC7B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAE9C;;;;GAIG;AACH,eAAO,MAAM,OAAO,EAEf,EAAE,QAAQ,EAAE,CAAC,IAAI,UAAU,GAAG,aAAa,CAAC,CAAC,CAAC,GAAE,CAAC;AAEtD,oFAAoF;AACpF,MAAM,MAAM,UAAU,GAAG,CAAC,OAAO,GAAG,CAAC,CAAC,MAAM,OAAO,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC"}
|
package/dist/formats/ipv4.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const ipv4Format: import("./format").
|
|
1
|
+
export declare const ipv4Format: import("./format.js").BuiltInFormat<"ipv4">;
|
|
2
2
|
//# sourceMappingURL=ipv4.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ipv4.d.ts","sourceRoot":"","sources":["../../src/formats/ipv4.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,UAAU,
|
|
1
|
+
{"version":3,"file":"ipv4.d.ts","sourceRoot":"","sources":["../../src/formats/ipv4.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,UAAU,0CAIrB,CAAC"}
|