@nxgt/graphql-validation 0.0.0-stage → 0.1.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/LICENSE +21 -0
- package/README.md +209 -2
- package/dist/bad-user-input.d.ts +35 -0
- package/dist/bad-user-input.d.ts.map +1 -0
- package/dist/builder/args-schema.d.ts +17 -0
- package/dist/builder/args-schema.d.ts.map +1 -0
- package/dist/builder/constraints.d.ts +16 -0
- package/dist/builder/constraints.d.ts.map +1 -0
- package/dist/builder/input-schema.d.ts +31 -0
- package/dist/builder/input-schema.d.ts.map +1 -0
- package/dist/builder/leaf.d.ts +14 -0
- package/dist/builder/leaf.d.ts.map +1 -0
- package/dist/chunks/index-n3hypgpf.js +315 -0
- package/dist/chunks/index-n3hypgpf.js.map +37 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +69 -0
- package/dist/cli.js.map +11 -0
- package/dist/constraint-directive.d.ts +21 -0
- package/dist/constraint-directive.d.ts.map +1 -0
- package/dist/formats/all.d.ts +9 -0
- package/dist/formats/all.d.ts.map +1 -0
- package/dist/formats/byte.d.ts +2 -0
- package/dist/formats/byte.d.ts.map +1 -0
- package/dist/formats/date-time.d.ts +2 -0
- package/dist/formats/date-time.d.ts.map +1 -0
- package/dist/formats/date.d.ts +2 -0
- package/dist/formats/date.d.ts.map +1 -0
- package/dist/formats/email.d.ts +2 -0
- package/dist/formats/email.d.ts.map +1 -0
- package/dist/formats/format.d.ts +15 -0
- package/dist/formats/format.d.ts.map +1 -0
- package/dist/formats/index.d.ts +13 -0
- package/dist/formats/index.d.ts.map +1 -0
- package/dist/formats/ipv4.d.ts +2 -0
- package/dist/formats/ipv4.d.ts.map +1 -0
- package/dist/formats/ipv6.d.ts +2 -0
- package/dist/formats/ipv6.d.ts.map +1 -0
- package/dist/formats/uri.d.ts +2 -0
- package/dist/formats/uri.d.ts.map +1 -0
- package/dist/formats/uuid.d.ts +2 -0
- package/dist/formats/uuid.d.ts.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +315 -0
- package/dist/index.js.map +16 -0
- package/dist/rules/all.d.ts +16 -0
- package/dist/rules/all.d.ts.map +1 -0
- package/dist/rules/contains.d.ts +2 -0
- package/dist/rules/contains.d.ts.map +1 -0
- package/dist/rules/ends-with.d.ts +2 -0
- package/dist/rules/ends-with.d.ts.map +1 -0
- package/dist/rules/exclusive-max.d.ts +2 -0
- package/dist/rules/exclusive-max.d.ts.map +1 -0
- package/dist/rules/exclusive-min.d.ts +2 -0
- package/dist/rules/exclusive-min.d.ts.map +1 -0
- package/dist/rules/format.d.ts +2 -0
- package/dist/rules/format.d.ts.map +1 -0
- package/dist/rules/index.d.ts +26 -0
- package/dist/rules/index.d.ts.map +1 -0
- package/dist/rules/max-items.d.ts +2 -0
- package/dist/rules/max-items.d.ts.map +1 -0
- package/dist/rules/max-length.d.ts +2 -0
- package/dist/rules/max-length.d.ts.map +1 -0
- package/dist/rules/max.d.ts +2 -0
- package/dist/rules/max.d.ts.map +1 -0
- package/dist/rules/min-items.d.ts +2 -0
- package/dist/rules/min-items.d.ts.map +1 -0
- package/dist/rules/min-length.d.ts +2 -0
- package/dist/rules/min-length.d.ts.map +1 -0
- package/dist/rules/min.d.ts +2 -0
- package/dist/rules/min.d.ts.map +1 -0
- package/dist/rules/multiple-of.d.ts +2 -0
- package/dist/rules/multiple-of.d.ts.map +1 -0
- package/dist/rules/not-contains.d.ts +2 -0
- package/dist/rules/not-contains.d.ts.map +1 -0
- package/dist/rules/pattern.d.ts +2 -0
- package/dist/rules/pattern.d.ts.map +1 -0
- package/dist/rules/rule.d.ts +55 -0
- package/dist/rules/rule.d.ts.map +1 -0
- package/dist/rules/starts-with.d.ts +2 -0
- package/dist/rules/starts-with.d.ts.map +1 -0
- package/dist/typedefs-command.d.ts +10 -0
- package/dist/typedefs-command.d.ts.map +1 -0
- package/dist/validated.d.ts +22 -0
- package/dist/validated.d.ts.map +1 -0
- package/dist/with-validation.d.ts +26 -0
- package/dist/with-validation.d.ts.map +1 -0
- package/docs/README.md +15 -0
- package/docs/guide/constraints.md +291 -0
- package/docs/guide/errors.md +194 -0
- package/docs/roadmap.md +30 -0
- package/docs/troubleshooting.md +260 -0
- package/graphql/constraint.graphqls +20 -0
- package/package.json +67 -5
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Steve Tsala
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,210 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @nxgt/graphql-validation
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Validate GraphQL arguments and input fields with `@constraint` directives
|
|
4
|
+
written in your schema. Each directive becomes a Zod schema that checks the
|
|
5
|
+
arguments before your resolver runs; an invalid input is one `BAD_USER_INPUT`
|
|
6
|
+
error that lists every reason with its path, so a form can show each one beside
|
|
7
|
+
its field. For schema-first servers on `graphql` 16 and 17 (`graphql-js`,
|
|
8
|
+
GraphQL Yoga, Apollo Server).
|
|
9
|
+
|
|
10
|
+
## Install
|
|
11
|
+
|
|
12
|
+
```sh
|
|
13
|
+
bun add @nxgt/graphql-validation graphql zod typescript
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
Peers, all **required**:
|
|
17
|
+
|
|
18
|
+
| Peer | Range |
|
|
19
|
+
| --- | --- |
|
|
20
|
+
| `graphql` | `^16.11.0 \|\| ^17.0.0` |
|
|
21
|
+
| `zod` | `>=4.6.5 <5` |
|
|
22
|
+
| `typescript` | `^6.0.3` |
|
|
23
|
+
|
|
24
|
+
Your `tsconfig.json` needs:
|
|
25
|
+
|
|
26
|
+
```jsonc
|
|
27
|
+
{
|
|
28
|
+
"compilerOptions": {
|
|
29
|
+
"moduleResolution": "bundler" // `nodenext` is not supported
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Usage
|
|
35
|
+
|
|
36
|
+
### Constrain arguments and input fields
|
|
37
|
+
|
|
38
|
+
Add `constraintTypeDefs` to your type definitions, write `@constraint(...)`,
|
|
39
|
+
build the schema with any schema-first builder (`buildSchema` from `graphql`,
|
|
40
|
+
or `makeExecutableSchema` from `@graphql-tools/schema` as below), then call
|
|
41
|
+
`withValidation(schema)` **last**, once every resolver is attached.
|
|
42
|
+
|
|
43
|
+
```ts
|
|
44
|
+
import { makeExecutableSchema } from '@graphql-tools/schema';
|
|
45
|
+
import { constraintTypeDefs, withValidation } from '@nxgt/graphql-validation';
|
|
46
|
+
|
|
47
|
+
const typeDefs = [
|
|
48
|
+
constraintTypeDefs,
|
|
49
|
+
/* GraphQL */ `
|
|
50
|
+
input SignUp {
|
|
51
|
+
email: String! @constraint(format: "email", maxLength: 254)
|
|
52
|
+
age: Int @constraint(min: 18)
|
|
53
|
+
tags: [String!] @constraint(maxItems: 5, maxLength: 20)
|
|
54
|
+
}
|
|
55
|
+
type Query {
|
|
56
|
+
user(id: ID! @constraint(format: "uuid")): String
|
|
57
|
+
}
|
|
58
|
+
type Mutation {
|
|
59
|
+
signUp(input: SignUp!): Boolean
|
|
60
|
+
}
|
|
61
|
+
`,
|
|
62
|
+
];
|
|
63
|
+
|
|
64
|
+
const resolvers = {
|
|
65
|
+
Mutation: {
|
|
66
|
+
// `input` is already checked: this only runs for a valid one
|
|
67
|
+
signUp: (_: unknown, { input }: { input: { email: string } }) => {
|
|
68
|
+
console.log(input.email);
|
|
69
|
+
return true;
|
|
70
|
+
},
|
|
71
|
+
},
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
export const schema = withValidation(makeExecutableSchema({ typeDefs, resolvers }));
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
`withValidation` wraps, in place, the resolver of each field that has
|
|
78
|
+
something to check, and returns the same schema. A subscription field is
|
|
79
|
+
checked once, in `subscribe`. Calling it twice wraps nothing twice. A
|
|
80
|
+
constraint that cannot apply throws when you call it, not on the first
|
|
81
|
+
request. The resolver receives the parsed arguments.
|
|
82
|
+
|
|
83
|
+
Every argument, its rule and its Zod equivalent, and the formats, are in
|
|
84
|
+
[Constraints](docs/guide/constraints.md).
|
|
85
|
+
|
|
86
|
+
### Read the error
|
|
87
|
+
|
|
88
|
+
```json
|
|
89
|
+
{
|
|
90
|
+
"errors": [
|
|
91
|
+
{
|
|
92
|
+
"message": "Invalid arguments for Mutation.signUp. input.email: Invalid email address",
|
|
93
|
+
"path": ["signUp"],
|
|
94
|
+
"extensions": {
|
|
95
|
+
"code": "BAD_USER_INPUT",
|
|
96
|
+
"issues": [
|
|
97
|
+
{ "path": ["input", "email"], "message": "Invalid email address", "code": "invalid_format", "constraint": "format" },
|
|
98
|
+
{ "path": ["input", "age"], "message": "Too small: expected number to be >=18", "code": "too_small", "constraint": "min" }
|
|
99
|
+
]
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
]
|
|
103
|
+
}
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
`issues[].path` is relative to the arguments, and `issues[].constraint` names the
|
|
107
|
+
`@constraint` argument that refused. Mapping issues to form fields is
|
|
108
|
+
in [Errors](docs/guide/errors.md).
|
|
109
|
+
|
|
110
|
+
### Rules a directive cannot say
|
|
111
|
+
|
|
112
|
+
`validated(schema, resolver)` checks the arguments with a Zod schema you write,
|
|
113
|
+
for rules across fields, refinements and async checks. It raises the same error.
|
|
114
|
+
|
|
115
|
+
```ts
|
|
116
|
+
import { validated } from '@nxgt/graphql-validation';
|
|
117
|
+
import { z } from 'zod';
|
|
118
|
+
|
|
119
|
+
const resolvers = {
|
|
120
|
+
Query: {
|
|
121
|
+
range: validated(
|
|
122
|
+
z
|
|
123
|
+
.object({ from: z.number(), to: z.number() })
|
|
124
|
+
.refine(({ from, to }) => from <= to, {
|
|
125
|
+
message: 'from must not exceed to',
|
|
126
|
+
path: ['to'],
|
|
127
|
+
}),
|
|
128
|
+
(_, { from, to }) => to - from,
|
|
129
|
+
),
|
|
130
|
+
},
|
|
131
|
+
};
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
## IDE support
|
|
135
|
+
|
|
136
|
+
An IDE's GraphQL plugin (JetBrains GraphQL, VS Code GraphQL) reads your `.graphql`
|
|
137
|
+
files, not `constraintTypeDefs`, so it reports `Unknown directive "@constraint"`.
|
|
138
|
+
The package ships the directive as a file; add it to your `graphql.config.yml`:
|
|
139
|
+
|
|
140
|
+
```yaml
|
|
141
|
+
schema:
|
|
142
|
+
- src/**/*.graphql
|
|
143
|
+
- node_modules/@nxgt/graphql-validation/graphql/constraint.graphqls
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
If your IDE does not index `node_modules`, or you want the file committed with
|
|
147
|
+
your schema, write it into the project (Node or Bun), and list that path instead:
|
|
148
|
+
|
|
149
|
+
```sh
|
|
150
|
+
bunx nxgt-graphql-validation typedefs --out
|
|
151
|
+
# or: npx nxgt-graphql-validation typedefs --out
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
`--out` alone writes `generated/graphql/constraint.graphqls`, `--out <file>` writes
|
|
155
|
+
`<file>`, and without `--out` the SDL is printed. Regenerate the file after upgrading the package.
|
|
156
|
+
|
|
157
|
+
The schema must declare `@constraint` once. Pick one source for the server:
|
|
158
|
+
|
|
159
|
+
- **The generated file is part of your schema.** If the server loads its
|
|
160
|
+
type definitions by scanning `*.graphql(s)` files and the copy sits among
|
|
161
|
+
them, it already declares the directive: do not add `constraintTypeDefs`.
|
|
162
|
+
- **`constraintTypeDefs` declares it.** Then the copy is for the IDE only:
|
|
163
|
+
keep it out of the folders the server scans (or exclude it from the glob).
|
|
164
|
+
|
|
165
|
+
Both give the same schema, and `withValidation` accepts either: it checks that
|
|
166
|
+
the directive declared is this package's. Both at once throw
|
|
167
|
+
`There can be only one directive named "@constraint".`
|
|
168
|
+
|
|
169
|
+
## Exports
|
|
170
|
+
|
|
171
|
+
| Export | Is |
|
|
172
|
+
| --- | --- |
|
|
173
|
+
| `constraintTypeDefs` | the SDL of `@constraint`, to add to `typeDefs` |
|
|
174
|
+
| `withValidation(schema)` | checks every `@constraint` of a schema before its resolvers run |
|
|
175
|
+
| `validated(schema \| shape, resolver)` | a resolver whose arguments a Zod schema checks |
|
|
176
|
+
| `badUserInput(where, zodError)` | builds the error above, for code that validates by hand |
|
|
177
|
+
| `ValidationIssue`, `BadUserInputExtensions` | the types of `extensions.issues` and `extensions` |
|
|
178
|
+
| `ConstraintArgument` | the type of `issues[].constraint`: `'minLength' \| 'format' \| ...` |
|
|
179
|
+
| `ArgsSchema`, `SchemaOf` | the types `validated` accepts |
|
|
180
|
+
|
|
181
|
+
Also shipped, outside `exports`:
|
|
182
|
+
|
|
183
|
+
| File | Is |
|
|
184
|
+
| --- | --- |
|
|
185
|
+
| `graphql/constraint.graphqls` | the SDL of `@constraint` for IDEs; reference it by path, it is not importable |
|
|
186
|
+
| `nxgt-graphql-validation` (bin) | `typedefs [--out [<file>]]` prints or writes that SDL; `--help` |
|
|
187
|
+
|
|
188
|
+
## Traps
|
|
189
|
+
|
|
190
|
+
- `@constraint` is read from the SDL. A code-first schema does not declare the
|
|
191
|
+
directive, so `withValidation` throws; one that declares it but whose
|
|
192
|
+
constrained types and fields have no SDL (code-first, or merged pieces) is
|
|
193
|
+
checked for nothing, and no error says so. Use type definitions.
|
|
194
|
+
- Call `withValidation` last: a resolver set on a field afterwards replaces
|
|
195
|
+
the check.
|
|
196
|
+
- A `@constraint` on an interface field's argument must be repeated on each
|
|
197
|
+
implementing object's field, or `withValidation` throws at startup.
|
|
198
|
+
- `@constraint` is refused on an output field:
|
|
199
|
+
`Directive "@constraint" may not be used on FIELD_DEFINITION.`
|
|
200
|
+
- `format: "date-time"` takes the canonical RFC 3339 form only (uppercase `T`
|
|
201
|
+
and `Z`, seconds present).
|
|
202
|
+
|
|
203
|
+
Every startup error and its fix is in [Troubleshooting](docs/troubleshooting.md).
|
|
204
|
+
|
|
205
|
+
## Documentation
|
|
206
|
+
|
|
207
|
+
- [Documentation index](docs/README.md)
|
|
208
|
+
- Guides: [Constraints](docs/guide/constraints.md), [Errors](docs/guide/errors.md)
|
|
209
|
+
- [Troubleshooting](docs/troubleshooting.md)
|
|
210
|
+
- [Roadmap](docs/roadmap.md): a Zod codegen plugin, your own formats, schemas that read the context
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { GraphQLError } from 'graphql';
|
|
2
|
+
import type { z } from 'zod';
|
|
3
|
+
import type { ConstraintArgument } from './rules';
|
|
4
|
+
/** One reason an input was refused, at its path inside the arguments. */
|
|
5
|
+
export interface ValidationIssue {
|
|
6
|
+
/** `['input', 'address', 'zip']`: the argument, then the input fields. */
|
|
7
|
+
readonly path: readonly (string | number)[];
|
|
8
|
+
readonly message: string;
|
|
9
|
+
/** Zod's issue code: `too_small`, `invalid_format`, `custom`, ... */
|
|
10
|
+
readonly code: string;
|
|
11
|
+
/**
|
|
12
|
+
* The `@constraint` argument that refused (`minLength`, `format`), when a
|
|
13
|
+
* directive did: stable across Zod versions, unlike `code`. Absent for a
|
|
14
|
+
* refusal of `validated()`'s own schema.
|
|
15
|
+
*/
|
|
16
|
+
readonly constraint?: ConstraintArgument;
|
|
17
|
+
}
|
|
18
|
+
/** The `extensions` of the error an invalid input becomes. */
|
|
19
|
+
export type BadUserInputExtensions = {
|
|
20
|
+
readonly code: 'BAD_USER_INPUT';
|
|
21
|
+
readonly issues: readonly ValidationIssue[];
|
|
22
|
+
};
|
|
23
|
+
/** Names the `@constraint` argument behind an issue, when there is one. */
|
|
24
|
+
export type ConstraintOf = (issue: z.core.$ZodIssue) => ConstraintArgument | undefined;
|
|
25
|
+
/**
|
|
26
|
+
* The one error an invalid input becomes: `extensions.code` is
|
|
27
|
+
* `BAD_USER_INPUT`, the code Apollo and most clients already read, and
|
|
28
|
+
* `extensions.issues` lists every reason with its path, so a form can show
|
|
29
|
+
* each one beside its field. The message names the field and the first
|
|
30
|
+
* reason, for a log line.
|
|
31
|
+
*/
|
|
32
|
+
export declare function badUserInput(where: string, error: z.ZodError): GraphQLError;
|
|
33
|
+
/** The parsed arguments, or the error above, its issues named by `constraintOf`. */
|
|
34
|
+
export declare function parseArgs(schema: z.ZodType, args: unknown, where: string, constraintOf?: ConstraintOf): Promise<unknown>;
|
|
35
|
+
//# sourceMappingURL=bad-user-input.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bad-user-input.d.ts","sourceRoot":"","sources":["../src/bad-user-input.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAC7B,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAElD,yEAAyE;AACzE,MAAM,WAAW,eAAe;IAC/B,0EAA0E;IAC1E,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,CAAC;IAC5C,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,qEAAqE;IACrE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB;;;;OAIG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,kBAAkB,CAAC;CACzC;AAED,8DAA8D;AAC9D,MAAM,MAAM,sBAAsB,GAAG;IACpC,QAAQ,CAAC,IAAI,EAAE,gBAAgB,CAAC;IAChC,QAAQ,CAAC,MAAM,EAAE,SAAS,eAAe,EAAE,CAAC;CAC5C,CAAC;AAEF,2EAA2E;AAC3E,MAAM,MAAM,YAAY,GAAG,CAC1B,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,SAAS,KACnB,kBAAkB,GAAG,SAAS,CAAC;AA4BpC;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC,QAAQ,GAAG,YAAY,CAE3E;AAED,oFAAoF;AACpF,wBAAsB,SAAS,CAC9B,MAAM,EAAE,CAAC,CAAC,OAAO,EACjB,IAAI,EAAE,OAAO,EACb,KAAK,EAAE,MAAM,EACb,YAAY,CAAC,EAAE,YAAY,GACzB,OAAO,CAAC,OAAO,CAAC,CAKlB"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { GraphQLField, GraphQLObjectType } from 'graphql';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import type { InputSchemas } from './input-schema';
|
|
4
|
+
/**
|
|
5
|
+
* The schema of a field's arguments, or `undefined` when none of them can
|
|
6
|
+
* break a constraint, so a field with nothing to check is left untouched.
|
|
7
|
+
* `parent` is the type's name, for errors: `Mutation.signUp(input:)`.
|
|
8
|
+
*/
|
|
9
|
+
export declare function argsSchemaOf(inputs: InputSchemas, parent: string, field: GraphQLField<unknown, unknown>): z.ZodType | undefined;
|
|
10
|
+
/**
|
|
11
|
+
* Fails when an object type's field does not repeat the `@constraint` its
|
|
12
|
+
* interface writes on an argument. The object's field is the one that
|
|
13
|
+
* resolves, and graphql lets it redeclare the argument bare: the interface's
|
|
14
|
+
* constraint would then check nothing, in silence.
|
|
15
|
+
*/
|
|
16
|
+
export declare function assertInterfaceConstraintsKept(inputs: InputSchemas, type: GraphQLObjectType): void;
|
|
17
|
+
//# sourceMappingURL=args-schema.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"args-schema.d.ts","sourceRoot":"","sources":["../../src/builder/args-schema.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAmB,YAAY,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAChF,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEnD;;;;GAIG;AACH,wBAAgB,YAAY,CAC3B,MAAM,EAAE,YAAY,EACpB,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,GACnC,CAAC,CAAC,OAAO,GAAG,SAAS,CAUvB;AAcD;;;;;GAKG;AACH,wBAAgB,8BAA8B,CAC7C,MAAM,EAAE,YAAY,EACpB,IAAI,EAAE,iBAAiB,GACrB,IAAI,CAoBN"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { type DirectiveNode, type GraphQLDirective } from 'graphql';
|
|
2
|
+
import { type RegisteredRule } from '../rules';
|
|
3
|
+
/** One `@constraint` argument written on an argument or an input field. */
|
|
4
|
+
export interface Constraint {
|
|
5
|
+
readonly rule: RegisteredRule;
|
|
6
|
+
readonly value: string | number;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* The constraints written on a node, base rules (`format`) first so the
|
|
10
|
+
* others narrow the schema they produce. Empty when the schema declares no
|
|
11
|
+
* `@constraint` or the node carries none.
|
|
12
|
+
*/
|
|
13
|
+
export declare function constraintsOn(directive: GraphQLDirective | undefined, node: {
|
|
14
|
+
readonly directives?: ReadonlyArray<DirectiveNode> | undefined;
|
|
15
|
+
} | null | undefined): Constraint[];
|
|
16
|
+
//# sourceMappingURL=constraints.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constraints.d.ts","sourceRoot":"","sources":["../../src/builder/constraints.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,KAAK,aAAa,EAClB,KAAK,gBAAgB,EAErB,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,KAAK,cAAc,EAAS,MAAM,UAAU,CAAC;AAEtD,2EAA2E;AAC3E,MAAM,WAAW,UAAU;IAC1B,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAC;IAC9B,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC;CAChC;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAC5B,SAAS,EAAE,gBAAgB,GAAG,SAAS,EACvC,IAAI,EACD;IAAE,QAAQ,CAAC,UAAU,CAAC,EAAE,aAAa,CAAC,aAAa,CAAC,GAAG,SAAS,CAAA;CAAE,GAClE,IAAI,GACJ,SAAS,GACV,UAAU,EAAE,CAad"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { type GraphQLArgument, type GraphQLDirective, type GraphQLInputField, type GraphQLInputType, type GraphQLSchema } from 'graphql';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
/**
|
|
4
|
+
* Builds the schemas of the arguments and input fields of one GraphQL
|
|
5
|
+
* schema, once each: an input type is walked a single time however many
|
|
6
|
+
* fields use it, and a recursive one (`input Filter { and: [Filter!] }`) is
|
|
7
|
+
* reached through `z.lazy`.
|
|
8
|
+
*/
|
|
9
|
+
export declare class InputSchemas {
|
|
10
|
+
#private;
|
|
11
|
+
readonly directive: GraphQLDirective | undefined;
|
|
12
|
+
constructor(schema: GraphQLSchema);
|
|
13
|
+
/** Whether a value of this type can break a constraint anywhere inside. */
|
|
14
|
+
isConstrained(type: GraphQLInputType): boolean;
|
|
15
|
+
/**
|
|
16
|
+
* Builds every constrained input type, reached by an argument or not, so
|
|
17
|
+
* a constraint that cannot apply fails at startup wherever it is written.
|
|
18
|
+
*/
|
|
19
|
+
buildAll(schema: GraphQLSchema): void;
|
|
20
|
+
/** Whether an argument or input field needs checking at all. */
|
|
21
|
+
needsCheck(input: GraphQLArgument | GraphQLInputField): boolean;
|
|
22
|
+
/** The schema of one argument or input field, `where` naming it in errors. */
|
|
23
|
+
of(input: GraphQLArgument | GraphQLInputField, where: string): z.ZodType;
|
|
24
|
+
/**
|
|
25
|
+
* Fails when a default value breaks its own constraint: every request that
|
|
26
|
+
* leaves the value out would be refused for something the client never
|
|
27
|
+
* sent. Run once every schema is built, so a recursive type is complete.
|
|
28
|
+
*/
|
|
29
|
+
checkDefaults(): void;
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=input-schema.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"input-schema.d.ts","sourceRoot":"","sources":["../../src/builder/input-schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAEN,KAAK,eAAe,EACpB,KAAK,gBAAgB,EACrB,KAAK,iBAAiB,EAEtB,KAAK,gBAAgB,EACrB,KAAK,aAAa,EAMlB,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAKxB;;;;;GAKG;AACH,qBAAa,YAAY;;IACxB,QAAQ,CAAC,SAAS,EAAE,gBAAgB,GAAG,SAAS,CAAC;gBAWrC,MAAM,EAAE,aAAa;IAwBjC,2EAA2E;IAC3E,aAAa,CAAC,IAAI,EAAE,gBAAgB,GAAG,OAAO;IAK9C;;;OAGG;IACH,QAAQ,CAAC,MAAM,EAAE,aAAa,GAAG,IAAI;IAMrC,gEAAgE;IAChE,UAAU,CAAC,KAAK,EAAE,eAAe,GAAG,iBAAiB,GAAG,OAAO;IAO/D,8EAA8E;IAC9E,EAAE,CAAC,KAAK,EAAE,eAAe,GAAG,iBAAiB,EAAE,KAAK,EAAE,MAAM,GAAG,CAAC,CAAC,OAAO;IAYxE;;;;OAIG;IACH,aAAa,IAAI,IAAI;CAgFrB"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { type GraphQLLeafType } from 'graphql';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import type { Target } from '../rules/rule';
|
|
4
|
+
import type { Constraint } from './constraints';
|
|
5
|
+
/**
|
|
6
|
+
* The schema of a scalar or enum value with its constraints applied. A leaf
|
|
7
|
+
* without any is left as graphql parsed it. A constraint that cannot apply
|
|
8
|
+
* — `minLength` on an `Int`, anything on a custom scalar or an enum — fails
|
|
9
|
+
* here, at startup, naming `where`.
|
|
10
|
+
*/
|
|
11
|
+
export declare function leafSchema(type: GraphQLLeafType, constraints: readonly Constraint[], where: string): z.ZodType;
|
|
12
|
+
/** What a rule's target reads as in an error. */
|
|
13
|
+
export declare function describeTarget(target: Target): string;
|
|
14
|
+
//# sourceMappingURL=leaf.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"leaf.d.ts","sourceRoot":"","sources":["../../src/builder/leaf.ts"],"names":[],"mappings":"AAAA,OAAO,EAIN,KAAK,eAAe,EAEpB,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAehD;;;;;GAKG;AACH,wBAAgB,UAAU,CACzB,IAAI,EAAE,eAAe,EACrB,WAAW,EAAE,SAAS,UAAU,EAAE,EAClC,KAAK,EAAE,MAAM,GACX,CAAC,CAAC,OAAO,CAaX;AAED,iDAAiD;AACjD,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAIrD"}
|