@znight/graphql 0.0.0-stage → 0.2.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.
Files changed (62) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +1062 -2
  3. package/dist/compiler.d.mts +93 -0
  4. package/dist/compiler.mjs +2832 -0
  5. package/dist/compiler.mjs.map +1 -0
  6. package/dist/index.d.mts +542 -0
  7. package/dist/index.mjs +128 -0
  8. package/dist/index.mjs.map +1 -0
  9. package/dist/names-BlzDM5cF.mjs +111 -0
  10. package/dist/names-BlzDM5cF.mjs.map +1 -0
  11. package/dist/plugin-BdBxr5NQ.mjs +3222 -0
  12. package/dist/plugin-BdBxr5NQ.mjs.map +1 -0
  13. package/dist/testing.d.mts +101 -0
  14. package/dist/testing.mjs +306 -0
  15. package/dist/testing.mjs.map +1 -0
  16. package/dist/types-CgbV9LjD.d.mts +234 -0
  17. package/package.json +95 -4
  18. package/src/compiler/analyze.ts +608 -0
  19. package/src/compiler/builder.ts +1640 -0
  20. package/src/compiler/constants.ts +74 -0
  21. package/src/compiler/data.ts +73 -0
  22. package/src/compiler/defaults.ts +92 -0
  23. package/src/compiler/discriminators.ts +53 -0
  24. package/src/compiler/docs.ts +55 -0
  25. package/src/compiler/generate.ts +405 -0
  26. package/src/compiler/ids.ts +128 -0
  27. package/src/compiler/index.ts +93 -0
  28. package/src/compiler/locate.ts +44 -0
  29. package/src/compiler/model.ts +122 -0
  30. package/src/compiler/options.ts +54 -0
  31. package/src/compiler/scalars.ts +138 -0
  32. package/src/compiler/sdl-view.ts +59 -0
  33. package/src/context.ts +181 -0
  34. package/src/decisions.ts +169 -0
  35. package/src/decorators.ts +196 -0
  36. package/src/errors.ts +89 -0
  37. package/src/execution.ts +1064 -0
  38. package/src/format.ts +285 -0
  39. package/src/index.ts +84 -0
  40. package/src/limits.ts +177 -0
  41. package/src/loaders.ts +149 -0
  42. package/src/memory-pubsub.ts +133 -0
  43. package/src/metadata.ts +195 -0
  44. package/src/names.ts +47 -0
  45. package/src/options.ts +309 -0
  46. package/src/pipeline.ts +277 -0
  47. package/src/plugin.ts +557 -0
  48. package/src/pubsub.ts +36 -0
  49. package/src/scalars.ts +131 -0
  50. package/src/schema-hash.ts +18 -0
  51. package/src/schema.ts +557 -0
  52. package/src/sdl.ts +515 -0
  53. package/src/testing.ts +454 -0
  54. package/src/tokens.ts +22 -0
  55. package/src/transport/abort.ts +80 -0
  56. package/src/transport/accept.ts +155 -0
  57. package/src/transport/graphiql.ts +106 -0
  58. package/src/transport/http.ts +373 -0
  59. package/src/transport/sse.ts +45 -0
  60. package/src/type-ref.ts +89 -0
  61. package/src/types.ts +190 -0
  62. package/src/validate-args.ts +48 -0
@@ -0,0 +1,542 @@
1
+ import { _ as GraphQLErrorCode, a as GraphQLContext, b as GraphQLExceptionOptions, c as GraphQLGuard, d as GraphQLTransport, f as LoaderKey, g as ScalarDefinition, h as ResolverContext, i as GraphQLArgs, l as GraphQLGuardClass, m as LoaderValue, n as BatchLoadClass, o as GraphQLErrorMapper, p as LoaderOptions, r as BatchLoader, s as GraphQLErrorMapperClass, t as BatchLoad, u as GraphQLOperationKind, v as GraphQLErrorCodeValue, y as GraphQLException } from "./types-CgbV9LjD.mjs";
2
+ import { ClassMarker, MethodMarker, ParameterMarker, Plugin, PluginContext, PluginOptions, PluginRootsContext, ProviderKey, Scope, Token, TypedToken, ZnightError } from "@znight/core";
3
+ import { ByteSize, GuardRef, HttpContext, HttpRouteGroupDefinition, InferSchemaOutput, PluginHttpRoutes, PluginHttpRoutesContext, PluginRoute, RouteMetaEntry, StandardSchemaV1, StandardSchemaV1 as StandardSchemaV1$1 } from "@znight/http";
4
+ import { DocumentNode, FormattedExecutionResult, GraphQLError, GraphQLFormattedError, GraphQLResolveInfo, GraphQLScalarType, GraphQLSchema } from "graphql";
5
+ /** GraphQL `ID`: a string on the wire and in TypeScript. Recognised by the compiler through the alias. */
6
+ type ID = string;
7
+ /** GraphQL `Int` (32-bit signed integer). A `number` in TypeScript; plain `number` maps to `Float`. */
8
+ type Int = number;
9
+ /** GraphQL `Float`. Same as `number`, for symmetry with {@link Int}. */
10
+ type Float = number;
11
+ /** Any JSON value: the `JSON` scalar. */
12
+ type JSONValue = string | number | boolean | null | readonly JSONValue[] | {
13
+ readonly [key: string]: JSONValue;
14
+ };
15
+ /**
16
+ * The DataLoader of the current execution for the loader provider `L`, injected with `@Loader()`:
17
+ * created on first use, cached for the operation (or for one subscription event), then dropped.
18
+ *
19
+ * ```ts
20
+ * @ResolveField()
21
+ * author(@Parent() book: Book, @Loader() authors: Loader<AuthorsById>): Promise<Author> {
22
+ * return authors.load(book.authorId)
23
+ * }
24
+ * ```
25
+ */
26
+ export type Loader<L extends BatchLoad<unknown, unknown>> = BatchLoader<LoaderKey<L>, LoaderValue<L>>;
27
+ /** Options of {@link Resolver} (static). */
28
+ interface ResolverOptions {
29
+ /** Provider scope. Default: `singleton`; `request` creates one resolver per operation. */
30
+ readonly scope?: Scope;
31
+ }
32
+ /**
33
+ * Declares a resolver: a provider (singleton by default) whose `@Query`, `@Mutation`,
34
+ * `@Subscription` and `@ResolveField` methods are fields of the schema. Route decorators of
35
+ * `@znight/http` (`createRouteDecorator`) on the class are the default decisions of its fields.
36
+ *
37
+ * ```ts
38
+ * @Resolver()
39
+ * export class BookResolver {
40
+ * constructor(private readonly catalog: CatalogService) {}
41
+ *
42
+ * @Query()
43
+ * book(@Args('id') id: ID): Promise<Book | null> {
44
+ * return this.catalog.find(id)
45
+ * }
46
+ * }
47
+ * ```
48
+ *
49
+ * @param options static: `{ scope? }`.
50
+ */
51
+ export declare function Resolver(_options?: ResolverOptions): ClassMarker;
52
+ /**
53
+ * A field of the `Query` root type. The method's declared return type is the field type
54
+ * (`Promise<T>` unwrapped), its `@Args` the arguments, its JSDoc the description.
55
+ *
56
+ * @param name static: field name. Default: the method name.
57
+ */
58
+ export declare function Query(_name?: string): MethodMarker;
59
+ /**
60
+ * A field of the `Mutation` root type.
61
+ *
62
+ * @param name static: field name. Default: the method name.
63
+ */
64
+ export declare function Mutation(_name?: string): MethodMarker;
65
+ /**
66
+ * A field of the `Subscription` root type. The method returns an `AsyncIterable<T>` (an async
67
+ * generator, or `pubsub.subscribe(...)`), each value being the field value of one event.
68
+ *
69
+ * @param name static: field name. Default: the method name.
70
+ */
71
+ export declare function Subscription(_name?: string): MethodMarker;
72
+ /**
73
+ * A field resolver: adds a field to the type of the `@Parent()` parameter (mandatory), or replaces
74
+ * the property field of the same name.
75
+ *
76
+ * @param name static: field name. Default: the method name.
77
+ */
78
+ export declare function ResolveField(_name?: string): MethodMarker;
79
+ /**
80
+ * Field arguments. Without a name, the properties of the parameter type become arguments
81
+ * (`@Args() filter: BookFilter`); with a name, one argument (`@Args('id') id: ID`). With a Standard
82
+ * Schema, the value is validated (and transformed) after GraphQL coerced it; a failure is a
83
+ * `BAD_USER_INPUT` error listing the issues.
84
+ *
85
+ * @param name static: argument name.
86
+ * @param schema value: a Standard Schema validating the value (its output is injected).
87
+ */
88
+ export declare function Args(): ParameterMarker;
89
+ export declare function Args(name: string, schema?: StandardSchemaV1$1): ParameterMarker;
90
+ export declare function Args(schema: StandardSchemaV1$1): ParameterMarker;
91
+ /** The parent object of a field resolver (`@ResolveField` only; its type is the parent type). */
92
+ export declare function Parent(): ParameterMarker;
93
+ /** The `GraphQLContext` of the operation. */
94
+ export declare function Ctx(): ParameterMarker;
95
+ /** The graphql-js `GraphQLResolveInfo` of the call (escape hatch). */
96
+ export declare function Info(): ParameterMarker;
97
+ /** The DataLoader of the current execution for the `Loader<L>` parameter type (see {@link Loader}). */
98
+ export declare function Loader(): ParameterMarker;
99
+ /**
100
+ * Guards of the fields of a resolver class or of one field, run after the global guards (class
101
+ * guards, then method guards). Guards are providers implementing `GraphQLGuard`.
102
+ *
103
+ * @param guards value: guard classes.
104
+ */
105
+ export declare function UseGuard(..._guards: [GraphQLGuardClass, ...GraphQLGuardClass[]]): ClassMarker & MethodMarker;
106
+ /**
107
+ * Maps the TypeScript type `T` to the GraphQL scalar `name` wherever it appears. `name` is static;
108
+ * the returned definition must be exported (`export const`): the generated module imports it.
109
+ * Returns `definition` unchanged.
110
+ *
111
+ * ```ts
112
+ * export type EmailAddress = string & { readonly __brand: 'EmailAddress' }
113
+ *
114
+ * export const EmailAddressScalar = scalar<EmailAddress>('EmailAddress', {
115
+ * serialize: value => value,
116
+ * parseValue: value => {
117
+ * if (typeof value !== 'string' || !value.includes('@')) throw new TypeError('Expected an e-mail address')
118
+ * return value.toLowerCase() as EmailAddress
119
+ * },
120
+ * })
121
+ *
122
+ * export const UrlScalar = scalar<URL>('URL', GraphQLURL) // a graphql-js GraphQLScalarType
123
+ * ```
124
+ *
125
+ * @param name static: the GraphQL name of the scalar.
126
+ * @param definition value: a {@link ScalarDefinition} or a graphql-js `GraphQLScalarType` (whose
127
+ * name must be `name`, ZNIGHT066 at boot otherwise).
128
+ */
129
+ export declare function scalar<T>(name: string, definition: ScalarDefinition<T>): ScalarDefinition<T>;
130
+ export declare function scalar<T>(name: string, definition: GraphQLScalarType): GraphQLScalarType<T>;
131
+ /** Options of {@link orderByKeys}. */
132
+ interface OrderByKeysOptions {
133
+ /**
134
+ * What a key without value gets: `'error'` (default) a `NOT_FOUND` `GraphQLException` failing that
135
+ * key only, `'null'` the value `null`.
136
+ */
137
+ readonly missing?: "error" | "null";
138
+ }
139
+ /**
140
+ * Reorders `values` (rows in any order, some keys possibly missing) to match `keys`, what a
141
+ * `BatchLoad.load()` must return. Keys are compared with `Map` semantics (`===`, `NaN` equal).
142
+ *
143
+ * ```ts
144
+ * async load(ids: readonly ID[]): Promise<readonly (Author | Error)[]> {
145
+ * return orderByKeys(ids, await this.authors.findMany(ids), author => author.id)
146
+ * }
147
+ * ```
148
+ */
149
+ export declare function orderByKeys<K, V>(keys: readonly K[], values: Iterable<V>, keyOf: (value: V) => K, options?: OrderByKeysOptions & {
150
+ readonly missing?: "error";
151
+ }): (V | Error)[];
152
+ export declare function orderByKeys<K, V>(keys: readonly K[], values: Iterable<V>, keyOf: (value: V) => K, options: OrderByKeysOptions & {
153
+ readonly missing: "null";
154
+ }): (V | null)[];
155
+ /** A GraphQL request: the body of a GraphQL-over-HTTP request, or the argument of `plugin.execute()`. */
156
+ interface GraphQLRequest {
157
+ readonly query: string;
158
+ readonly operationName?: string | null | undefined;
159
+ readonly variables?: Readonly<Record<string, unknown>> | null | undefined;
160
+ /** Request extensions (ignored by the executor; available to transports). */
161
+ readonly extensions?: Readonly<Record<string, unknown>> | null | undefined;
162
+ }
163
+ /** The results of a subscription (one per event), or the single result of a query sent as a stream. */
164
+ interface GraphQLResultStream extends AsyncIterableIterator<FormattedExecutionResult> {
165
+ /** Ends the stream: the source event stream is returned (unsubscribed). */
166
+ return(): Promise<IteratorResult<FormattedExecutionResult>>;
167
+ }
168
+ /**
169
+ * The `PubSub` contract (RFC 0005 §5.6, §8.7): topics and payloads of subscriptions. `PubSub` is
170
+ * an injectable external of `GraphQLPlugin` (`@znight/graphql#PubSub`, singleton), in memory by
171
+ * default; multi-instance deployments supply their own implementation through the `pubsub` option.
172
+ */
173
+ /** Options of {@link PubSub.subscribe}. */
174
+ interface SubscribeOptions {
175
+ /** Ends the subscription when it aborts (client gone, shutdown, `maxDuration`): pass `ctx.signal`. */
176
+ readonly signal?: AbortSignal;
177
+ }
178
+ /**
179
+ * Publishes events to the subscribers of a topic. `Events` maps each topic to its payload type.
180
+ *
181
+ * ```ts
182
+ * interface CatalogEvents {
183
+ * bookAdded: Book
184
+ * }
185
+ *
186
+ * constructor(private readonly events: PubSub<CatalogEvents>) {}
187
+ *
188
+ * await this.events.publish('bookAdded', book)
189
+ * for await (const book of this.events.subscribe('bookAdded', { signal: ctx.signal })) yield book
190
+ * ```
191
+ */
192
+ export declare abstract class PubSub<Events extends object = Record<string, unknown>> {
193
+ /** Delivers `payload` to the current subscribers of `topic`. */
194
+ abstract publish<K extends keyof Events & string>(topic: K, payload: Events[K]): Promise<void>;
195
+ /** The events of `topic` published from now on, until `options.signal` aborts or the iterator returns. */
196
+ abstract subscribe<K extends keyof Events & string>(topic: K, options?: SubscribeOptions): AsyncIterableIterator<Events[K]>;
197
+ }
198
+ /**
199
+ * A `PubSub` of any event map, for the `pubsub` option: `PubSub<Events>` types are not assignable
200
+ * to each other (generic methods over `keyof Events`), so the option accepts the structure.
201
+ */
202
+ interface AnyPubSub {
203
+ publish(topic: never, payload: never): Promise<void>;
204
+ subscribe(topic: never, options?: SubscribeOptions): AsyncIterableIterator<unknown>;
205
+ }
206
+ /** A global GraphQL guard: a provider class or an instance. */
207
+ type GraphQLGuardRef = GraphQLGuardClass | GraphQLGuard;
208
+ /** An error mapper: a provider class or an instance. */
209
+ type GraphQLErrorMapperRef = GraphQLErrorMapperClass | GraphQLErrorMapper;
210
+ /** Options of the GraphQL-over-HTTP endpoint. */
211
+ interface GraphQLHttpOptions {
212
+ /** Route metadata of the endpoint (`[Public.meta()]`), seen by HTTP guards and the route decision check. */
213
+ readonly meta?: readonly RouteMetaEntry[];
214
+ /** Guards of the endpoint (HTTP `CanActivate`), after the global `HttpPlugin` guards. */
215
+ readonly guards?: readonly GuardRef[];
216
+ /** Body limit of the endpoint. Default `'100kb'`. */
217
+ readonly bodyLimit?: ByteSize;
218
+ /** Queries over `GET`. Default `true`. */
219
+ readonly get?: boolean;
220
+ }
221
+ /** Request limits; `false` disables one. */
222
+ interface GraphQLLimits {
223
+ /** Tokens of a document (`parse`). Default 2 000. */
224
+ readonly maxTokens?: number | false;
225
+ /** Field nesting of an operation (introspection fields exempt). Default 12. */
226
+ readonly maxDepth?: number | false;
227
+ /**
228
+ * Aliases of a document, as written and as one operation executes them (a fragment spread several
229
+ * times counts each time). Default 30.
230
+ */
231
+ readonly maxAliases?: number | false;
232
+ /** Directives of a document. Default 50. */
233
+ readonly maxDirectives?: number | false;
234
+ }
235
+ /** Subscription options. */
236
+ interface GraphQLSubscriptionOptions {
237
+ /** Active subscriptions cap (every transport); beyond it, 503. Default 10 000. */
238
+ readonly maxActive?: number;
239
+ /** Events buffered per subscriber by the default `MemoryPubSub`. Default 100. */
240
+ readonly bufferSize?: number;
241
+ /** SSE heartbeat (ms), `false` for none. Default: the `HttpPlugin` `sse` option. */
242
+ readonly heartbeat?: number | false;
243
+ /** SSE maximum duration (ms). Default: none. */
244
+ readonly maxDuration?: number;
245
+ }
246
+ /** Options of `GraphQLPlugin.configure()`. */
247
+ interface GraphQLPluginOptions {
248
+ /** Path of the endpoint, joined with the `HttpPlugin` prefix. Default `'/graphql'`. */
249
+ readonly path?: string;
250
+ /** `false`: no HTTP transport (schema, `execute()` and `subscribe()` only). Default `{}`. */
251
+ readonly http?: GraphQLHttpOptions | false;
252
+ /** Global GraphQL guards (classes or instances): root fields, and field resolvers with metadata. */
253
+ readonly guards?: readonly GraphQLGuardRef[];
254
+ /** Error mappers (classes or instances), tried in order. */
255
+ readonly errorMappers?: readonly GraphQLErrorMapperRef[];
256
+ /** Unmasked messages for unexpected errors (development). Default `false`. */
257
+ readonly exposeErrors?: boolean;
258
+ /** Introspection; off, suggestions are hidden too. Default `NODE_ENV !== 'production'`. */
259
+ readonly introspection?: boolean;
260
+ /** GraphiQL on `GET path` with `accept: text/html`. Default `NODE_ENV === 'development'`. */
261
+ readonly graphiql?: boolean;
262
+ readonly limits?: GraphQLLimits;
263
+ /** Distinct documents kept parsed and validated (LRU); 0 disables the cache. Default 1 000. */
264
+ readonly documentCache?: number;
265
+ /** `false` disables subscriptions over SSE. */
266
+ readonly subscriptions?: GraphQLSubscriptionOptions | false;
267
+ /** The `PubSub` provided to the container. Default: a `MemoryPubSub` (closed with the application). */
268
+ readonly pubsub?: AnyPubSub;
269
+ /**
270
+ * How the boot check of route decisions on GraphQL fields (RFC 0001, ZNIGHT023) reports problems:
271
+ * `'error'` (default) fails the boot, `'warn'` logs.
272
+ */
273
+ readonly enforcement?: "error" | "warn";
274
+ }
275
+ /** Options of {@link MemoryPubSub}. */
276
+ interface MemoryPubSubOptions {
277
+ /**
278
+ * Events buffered per subscriber. A subscriber that falls further behind gets a final
279
+ * `SUBSCRIPTION_OVERFLOW` error and its subscription ends. Default 100.
280
+ */
281
+ readonly bufferSize?: number;
282
+ }
283
+ /**
284
+ * In-process fan-out of events to subscribers: what `GraphQLPlugin` provides as `PubSub` by default.
285
+ * Deployments with several instances supply their own `PubSub` (`pubsub` option).
286
+ *
287
+ * ```ts
288
+ * GraphQLPlugin.configure({ pubsub: new MemoryPubSub({ bufferSize: 500 }) })
289
+ * ```
290
+ */
291
+ export declare class MemoryPubSub<Events extends object = Record<string, unknown>> extends PubSub<Events> {
292
+ #private;
293
+ constructor(options?: MemoryPubSubOptions);
294
+ /** Subscribers of every topic. */
295
+ get subscribers(): number;
296
+ publish<K extends keyof Events & string>(topic: K, payload: Events[K]): Promise<void>;
297
+ subscribe<K extends keyof Events & string>(topic: K, options?: SubscribeOptions): AsyncIterableIterator<Events[K]>;
298
+ /** Ends every subscription; later subscriptions end at once. */
299
+ close(): void;
300
+ }
301
+ /** Format version of `metadata.extensions.graphql` (another version is ZNIGHT066 at boot). */
302
+ export declare const GRAPHQL_METADATA_VERSION = 1;
303
+ /** The schema of the application. The section is omitted when the application has no resolver. */
304
+ interface GraphQLMetadata {
305
+ /** {@link GRAPHQL_METADATA_VERSION}. */
306
+ readonly version: number;
307
+ /** First 16 hexadecimal characters of the SHA-256 of the SDL (`printSdl`): logs, caches. */
308
+ readonly schemaHash: string;
309
+ readonly roots: GraphQLRootTypes;
310
+ /** Every named type except the graphql-js specified scalars, sorted by name (code-unit order). */
311
+ readonly types: readonly GraphQLTypeDefinition[];
312
+ /**
313
+ * Route decorator groups used on resolvers that must be known at runtime (required, or holding
314
+ * several keys), by group name: the shape of `extensions.http.groups` (RFC 0001).
315
+ */
316
+ readonly groups?: Readonly<Record<string, HttpRouteGroupDefinition>>;
317
+ }
318
+ /** Names of the root operation types (`Query`, `Mutation`, `Subscription`). */
319
+ interface GraphQLRootTypes {
320
+ readonly query: string;
321
+ readonly mutation?: string;
322
+ readonly subscription?: string;
323
+ }
324
+ /** A named type of the schema. */
325
+ type GraphQLTypeDefinition = GraphQLObjectTypeDefinition | GraphQLInputTypeDefinition | GraphQLEnumTypeDefinition | GraphQLUnionTypeDefinition | GraphQLBuiltinScalarDefinition | GraphQLCustomScalarDefinition;
326
+ /** An object type: resolver return types, their fields, the root types. */
327
+ interface GraphQLObjectTypeDefinition {
328
+ readonly kind: "object";
329
+ readonly name: string;
330
+ readonly description?: string;
331
+ /** Declaration order (base members first), then field resolvers by resolver token and source order. */
332
+ readonly fields: readonly GraphQLFieldDefinition[];
333
+ }
334
+ /** An input object type. */
335
+ interface GraphQLInputTypeDefinition {
336
+ readonly kind: "input";
337
+ readonly name: string;
338
+ readonly description?: string;
339
+ readonly fields: readonly GraphQLInputFieldDefinition[];
340
+ }
341
+ /** An enum: a TypeScript `enum`, or a named alias of a union of string literals. */
342
+ interface GraphQLEnumTypeDefinition {
343
+ readonly kind: "enum";
344
+ readonly name: string;
345
+ readonly description?: string;
346
+ /** Declaration order. */
347
+ readonly values: readonly GraphQLEnumValueDefinition[];
348
+ }
349
+ /** A union of object types. */
350
+ interface GraphQLUnionTypeDefinition {
351
+ readonly kind: "union";
352
+ readonly name: string;
353
+ readonly description?: string;
354
+ /** Member type names, sorted. */
355
+ readonly members: readonly string[];
356
+ readonly discriminator: GraphQLDiscriminator;
357
+ }
358
+ /** A scalar implemented by `@znight/graphql`: `DateTime`, `BigInt` or `JSON` (`names.ts`). */
359
+ interface GraphQLBuiltinScalarDefinition {
360
+ readonly kind: "scalar";
361
+ readonly name: string;
362
+ readonly description?: string;
363
+ readonly builtin: true;
364
+ }
365
+ /** A scalar declared with `scalar<T>(name, definition)`: the definition is imported from user code. */
366
+ interface GraphQLCustomScalarDefinition {
367
+ readonly kind: "scalar";
368
+ readonly name: string;
369
+ /** `ScalarDefinition<T>` of any `T` (its methods are bivariant), or a graphql-js scalar named `name`. */
370
+ readonly scalar: ScalarDefinition<unknown> | GraphQLScalarType;
371
+ }
372
+ /** A field of an object type. */
373
+ interface GraphQLFieldDefinition {
374
+ readonly name: string;
375
+ /** Type reference (`'Book!'`, `'[Book!]!'`, `'Int'`), parsed by `type-ref.ts`. */
376
+ readonly type: string;
377
+ readonly description?: string;
378
+ readonly deprecationReason?: string;
379
+ readonly args?: readonly GraphQLArgumentDefinition[];
380
+ /** Absent: the graphql-js default resolver (`parent[name]`). */
381
+ readonly resolver?: GraphQLResolverBinding;
382
+ }
383
+ /** An argument of a field. */
384
+ interface GraphQLArgumentDefinition {
385
+ readonly name: string;
386
+ readonly type: string;
387
+ readonly description?: string;
388
+ readonly deprecationReason?: string;
389
+ /**
390
+ * Default value, as an external value: JSON-compatible, enum values by GraphQL name (passed to
391
+ * graphql-js as `default: { value }`). Absent: no default.
392
+ */
393
+ readonly defaultValue?: unknown;
394
+ /** The TypeScript type does not accept `null`: a `null` sent by the client becomes `undefined` (§5.4). */
395
+ readonly nullAsUndefined?: true;
396
+ }
397
+ /** A field of an input object type. */
398
+ interface GraphQLInputFieldDefinition extends GraphQLArgumentDefinition {}
399
+ /** A value of an enum. */
400
+ interface GraphQLEnumValueDefinition {
401
+ /** GraphQL name (the member name, or the literal). */
402
+ readonly name: string;
403
+ /** Internal value (the member value, or the literal), what resolvers receive and return. */
404
+ readonly value: string | number;
405
+ readonly description?: string;
406
+ readonly deprecationReason?: string;
407
+ }
408
+ /** How the runtime tells the members of a union apart (`resolveType`). */
409
+ type GraphQLDiscriminator = {
410
+ readonly by: "property";
411
+ readonly property: string;
412
+ /** Literal value of the property (as a string) → member type name. */
413
+ readonly values: Readonly<Record<string, string>>;
414
+ } | {
415
+ readonly by: "class";
416
+ /** Member classes and their type names, subclasses first (`instanceof` order). */
417
+ readonly classes: readonly (readonly [cls: abstract new (...args: never[]) => unknown, name: string])[];
418
+ } | {
419
+ readonly by: "typename";
420
+ };
421
+ /** Kind of field a resolver method provides. */
422
+ type GraphQLResolverOperation = "query" | "mutation" | "subscription" | "field";
423
+ /** The resolver method behind a field. */
424
+ interface GraphQLResolverBinding {
425
+ /** Provider token of the resolver class. */
426
+ readonly token: Token;
427
+ readonly method: string;
428
+ readonly operation: GraphQLResolverOperation;
429
+ /** Guard provider tokens: class `@UseGuard` guards, then method ones. */
430
+ readonly guards: readonly Token[];
431
+ /**
432
+ * Effective field metadata (`createRouteDecorator` values, method decisions over class ones, one
433
+ * decision per group). Empty: no metadata, so global guards skip a field resolver (§5.9).
434
+ */
435
+ readonly meta: Readonly<Record<string, unknown>>;
436
+ /** Informational: loader provider tokens the method injects. */
437
+ readonly loaders?: readonly Token[];
438
+ /**
439
+ * Calls the method: maps the graphql-js arguments to the method parameters (§7.3). Synchronous
440
+ * unless an argument is validated with a Standard Schema.
441
+ */
442
+ readonly invoke: (resolver: any, parent: unknown, args: GraphQLArgs, context: GraphQLContext, info: GraphQLResolveInfo) => unknown;
443
+ }
444
+ declare module "@znight/core" {
445
+ interface ZnightExtensionsMetadata {
446
+ readonly graphql?: GraphQLMetadata;
447
+ }
448
+ }
449
+ /** Options of {@link GraphQLPlugin.execute} and {@link GraphQLPlugin.subscribe}. */
450
+ interface DirectExecuteOptions {
451
+ /** Cancels the operation (graphql-js `abortSignal`, `GraphQLContext.signal`). */
452
+ readonly signal?: AbortSignal;
453
+ /** `GraphQLContext.requestId`. Default: the request id of the enclosing scope, or a UUID. */
454
+ readonly requestId?: string;
455
+ }
456
+ /** A value of type `T` or a promise of it. */
457
+ type MaybePromise<T> = T | Promise<T>;
458
+ /**
459
+ * The GraphQL plugin: `GraphQLPlugin.configure(options)` (name `graphql`).
460
+ *
461
+ * ```ts
462
+ * await Application.create({
463
+ * metadata: __ZNIGHT_METADATA__,
464
+ * plugins: [HttpPlugin.configure(), GraphQLPlugin.configure({ guards: [AccessGuard] })],
465
+ * })
466
+ * ```
467
+ */
468
+ export declare class GraphQLPlugin implements Plugin, PluginHttpRoutes {
469
+ #private;
470
+ readonly name = "graphql";
471
+ private constructor();
472
+ /**
473
+ * Creates the plugin. `options` may be a function of the container, evaluated once, when first
474
+ * needed after the container is initialised: `GraphQLPlugin.configure(c => ({ exposeErrors: c.get(Env).dev }))`.
475
+ */
476
+ static configure(options?: PluginOptions<GraphQLPluginOptions>): GraphQLPlugin;
477
+ /**
478
+ * Providers `TestApp` creates at boot: the classes of the `guards` and `errorMappers` options, and
479
+ * the resolvers, guards and loaders of the metadata.
480
+ */
481
+ initRoots(context?: PluginRootsContext): readonly ProviderKey[];
482
+ register(ctx: PluginContext): void;
483
+ /**
484
+ * The `PluginHttpRoutes` contract of `@znight/http`: the GraphQL endpoint (`GET` and `POST` on
485
+ * `path`). `[]` with `http: false`.
486
+ */
487
+ httpRoutes(context: PluginHttpRoutesContext): readonly PluginRoute[];
488
+ onBootstrap(ctx: PluginContext): void;
489
+ onStart(ctx: PluginContext): void;
490
+ onStop(): Promise<void>;
491
+ onDispose(): void;
492
+ /** The schema (after bootstrap). */
493
+ get schema(): GraphQLSchema;
494
+ /** The SDL of the schema (graphql-js `printSchema`). */
495
+ printSchema(): string;
496
+ /** The `PubSub` of the application: the `pubsub` option, or the plugin's `MemoryPubSub`. */
497
+ get pubsub(): PubSub;
498
+ /** Active subscriptions (every transport). */
499
+ get activeSubscriptions(): number;
500
+ /**
501
+ * Executes a query or a mutation outside of HTTP (custom transports, tests, a controller calling
502
+ * GraphQL), in the current request scope or in a scope of its own. Returns the result directly
503
+ * when every resolver is synchronous; `await` it. A subscription is an error result: use
504
+ * {@link subscribe}. Rejects only when `options.signal` aborts the execution.
505
+ */
506
+ execute(request: GraphQLRequest, options?: DirectExecuteOptions): MaybePromise<FormattedExecutionResult>;
507
+ /**
508
+ * Subscribes outside of HTTP: the results of the subscription, one per event, until the source
509
+ * ends, `options.signal` aborts, `return()` is called or the application stops. A request error
510
+ * or a query gives a stream of one result.
511
+ */
512
+ subscribe(request: GraphQLRequest, options?: DirectExecuteOptions): Promise<GraphQLResultStream>;
513
+ }
514
+ /**
515
+ * Tokens of the values `GraphQLPlugin` supplies to the container (declared in the package
516
+ * manifest). `GraphQLContext` is a request-scoped external: inject it in request-scoped providers
517
+ * or through `Lazy<GraphQLContext>`.
518
+ */
519
+ export declare const GraphQLTokens: {
520
+ /** The {@link GraphQLContext} of the current operation (request scope). */
521
+ readonly Context: TypedToken<GraphQLContext>;
522
+ /** The application {@link PubSub} (singleton). */
523
+ readonly PubSub: TypedToken<PubSub>;
524
+ /** The {@link GraphQLPlugin} instance (singleton). */
525
+ readonly Plugin: TypedToken<GraphQLPlugin>;
526
+ };
527
+ /**
528
+ * Validates an argument value (after GraphQL coercion) with a [Standard Schema](https://standardschema.dev)
529
+ * (Zod, Valibot, ArkType...) and returns the schema **output** (transforms run, defaults applied).
530
+ *
531
+ * Synchronous when the schema validates synchronously (no promise, no microtask), a promise
532
+ * otherwise: generated code `await`s the result, which is free for a plain value.
533
+ *
534
+ * @param label what is validated, for the message: the argument name (`'input'`), or `'arguments'`
535
+ * for `@Args(Schema)` without name.
536
+ * @throws GraphQLException `BAD_USER_INPUT`, `extensions.issues: [{ path, message }]`, when the
537
+ * value is invalid.
538
+ * @throws TypeError when `schema` is not a Standard Schema v1 (a programming error, masked).
539
+ */
540
+ export declare function validateArgs<S extends StandardSchemaV1$1>(schema: S, value: unknown, label: string): InferSchemaOutput<S> | Promise<InferSchemaOutput<S>>;
541
+ export { type AnyPubSub, type BatchLoad, type BatchLoadClass, type BatchLoader, type DirectExecuteOptions, type Float, type GraphQLArgs, type GraphQLArgumentDefinition, type GraphQLBuiltinScalarDefinition, type GraphQLContext, type GraphQLCustomScalarDefinition, type GraphQLDiscriminator, type GraphQLEnumTypeDefinition, type GraphQLEnumValueDefinition, GraphQLErrorCode, type GraphQLErrorCodeValue, type GraphQLErrorMapper, type GraphQLErrorMapperClass, type GraphQLErrorMapperRef, GraphQLException, type GraphQLExceptionOptions, type GraphQLFieldDefinition, type GraphQLGuard, type GraphQLGuardClass, type GraphQLGuardRef, type GraphQLHttpOptions, type GraphQLInputFieldDefinition, type GraphQLInputTypeDefinition, type GraphQLLimits, type GraphQLMetadata, type GraphQLObjectTypeDefinition, type GraphQLOperationKind, type GraphQLPluginOptions, type GraphQLRequest, type GraphQLResolverBinding, type GraphQLResolverOperation, type GraphQLResultStream, type GraphQLRootTypes, type GraphQLSubscriptionOptions, type GraphQLTransport, type GraphQLTypeDefinition, type GraphQLUnionTypeDefinition, type ID, type Int, type JSONValue, type LoaderKey, type LoaderOptions, type LoaderValue, type MaybePromise, type MemoryPubSubOptions, type OrderByKeysOptions, type ResolverContext, type ResolverOptions, type ScalarDefinition, type StandardSchemaV1, type SubscribeOptions };
542
+ //# sourceMappingURL=index.d.mts.map
package/dist/index.mjs ADDED
@@ -0,0 +1,128 @@
1
+ import { a as MemoryPubSub, c as GraphQLErrorCode, i as GraphQLTokens, l as GraphQLException, o as PubSub, s as orderByKeys, t as GraphQLPlugin } from "./plugin-BdBxr5NQ.mjs";
2
+ import { l as GRAPHQL_METADATA_VERSION } from "./names-BlzDM5cF.mjs";
3
+ import { isThenable, toIssueDetail } from "@znight/http";
4
+ // src/decorators.ts
5
+ function marker() {}
6
+ const classMarker = marker;
7
+ const methodMarker = marker;
8
+ const parameterMarker = marker;
9
+ const classOrMethodMarker = marker;
10
+ /**
11
+ * Declares a resolver: a provider (singleton by default) whose `@Query`, `@Mutation`,
12
+ * `@Subscription` and `@ResolveField` methods are fields of the schema. Route decorators of
13
+ * `@znight/http` (`createRouteDecorator`) on the class are the default decisions of its fields.
14
+ *
15
+ * ```ts
16
+ * @Resolver()
17
+ * export class BookResolver {
18
+ * constructor(private readonly catalog: CatalogService) {}
19
+ *
20
+ * @Query()
21
+ * book(@Args('id') id: ID): Promise<Book | null> {
22
+ * return this.catalog.find(id)
23
+ * }
24
+ * }
25
+ * ```
26
+ *
27
+ * @param options static: `{ scope? }`.
28
+ */
29
+ function Resolver(_options) {
30
+ return classMarker;
31
+ }
32
+ /**
33
+ * A field of the `Query` root type. The method's declared return type is the field type
34
+ * (`Promise<T>` unwrapped), its `@Args` the arguments, its JSDoc the description.
35
+ *
36
+ * @param name static: field name. Default: the method name.
37
+ */
38
+ function Query(_name) {
39
+ return methodMarker;
40
+ }
41
+ /**
42
+ * A field of the `Mutation` root type.
43
+ *
44
+ * @param name static: field name. Default: the method name.
45
+ */
46
+ function Mutation(_name) {
47
+ return methodMarker;
48
+ }
49
+ /**
50
+ * A field of the `Subscription` root type. The method returns an `AsyncIterable<T>` (an async
51
+ * generator, or `pubsub.subscribe(...)`), each value being the field value of one event.
52
+ *
53
+ * @param name static: field name. Default: the method name.
54
+ */
55
+ function Subscription(_name) {
56
+ return methodMarker;
57
+ }
58
+ /**
59
+ * A field resolver: adds a field to the type of the `@Parent()` parameter (mandatory), or replaces
60
+ * the property field of the same name.
61
+ *
62
+ * @param name static: field name. Default: the method name.
63
+ */
64
+ function ResolveField(_name) {
65
+ return methodMarker;
66
+ }
67
+ function Args(_nameOrSchema, _schema) {
68
+ return parameterMarker;
69
+ }
70
+ /** The parent object of a field resolver (`@ResolveField` only; its type is the parent type). */
71
+ function Parent() {
72
+ return parameterMarker;
73
+ }
74
+ /** The `GraphQLContext` of the operation. */
75
+ function Ctx() {
76
+ return parameterMarker;
77
+ }
78
+ /** The graphql-js `GraphQLResolveInfo` of the call (escape hatch). */
79
+ function Info() {
80
+ return parameterMarker;
81
+ }
82
+ /** The DataLoader of the current execution for the `Loader<L>` parameter type (see {@link Loader}). */
83
+ function Loader() {
84
+ return parameterMarker;
85
+ }
86
+ /**
87
+ * Guards of the fields of a resolver class or of one field, run after the global guards (class
88
+ * guards, then method guards). Guards are providers implementing `GraphQLGuard`.
89
+ *
90
+ * @param guards value: guard classes.
91
+ */
92
+ function UseGuard(..._guards) {
93
+ return classOrMethodMarker;
94
+ }
95
+ function scalar(_name, definition) {
96
+ return definition;
97
+ }
98
+ // src/validate-args.ts
99
+ /**
100
+ * Validates an argument value (after GraphQL coercion) with a [Standard Schema](https://standardschema.dev)
101
+ * (Zod, Valibot, ArkType...) and returns the schema **output** (transforms run, defaults applied).
102
+ *
103
+ * Synchronous when the schema validates synchronously (no promise, no microtask), a promise
104
+ * otherwise: generated code `await`s the result, which is free for a plain value.
105
+ *
106
+ * @param label what is validated, for the message: the argument name (`'input'`), or `'arguments'`
107
+ * for `@Args(Schema)` without name.
108
+ * @throws GraphQLException `BAD_USER_INPUT`, `extensions.issues: [{ path, message }]`, when the
109
+ * value is invalid.
110
+ * @throws TypeError when `schema` is not a Standard Schema v1 (a programming error, masked).
111
+ */
112
+ function validateArgs(schema, value, label) {
113
+ const props = schema !== null && (typeof schema === "object" || typeof schema === "function") ? schema["~standard"] : void 0;
114
+ if (props === null || typeof props !== "object" || props.version !== 1 || typeof props.validate !== "function") throw new TypeError(`The schema of ${label} is not a Standard Schema v1 (missing "~standard.validate")`);
115
+ const result = props.validate(value);
116
+ if (isThenable(result)) return Promise.resolve(result).then((settled) => unwrap(settled, label));
117
+ return unwrap(result, label);
118
+ }
119
+ function unwrap(result, label) {
120
+ if (result.issues === void 0) return result.value;
121
+ throw new GraphQLException(`Invalid ${label}`, {
122
+ code: GraphQLErrorCode.BadUserInput,
123
+ extensions: { issues: result.issues.map(toIssueDetail) }
124
+ });
125
+ }
126
+ export { Args, Ctx, GRAPHQL_METADATA_VERSION, GraphQLErrorCode, GraphQLException, GraphQLPlugin, GraphQLTokens, Info, Loader, MemoryPubSub, Mutation, Parent, PubSub, Query, ResolveField, Resolver, Subscription, UseGuard, orderByKeys, scalar, validateArgs };
127
+
128
+ //# sourceMappingURL=index.mjs.map