@nxara/olio-schema 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 ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Nxara contributors
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,141 @@
1
- # Temporary Holding Version
1
+ # @nxara/olio-schema
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ Compose module SDL into one validated GraphQL schema.
4
+
5
+ `@nxara/olio-schema` is the step between your `.gql` files and a schema. Codegen and olio both go through it, so they always agree on the schema and on which module owns which field. It provides:
6
+
7
+ - **`compose(modules, directives)`**: merges every module's SDL, adds root types that modules only extend, applies directives, validates, and reports which module declares each field.
8
+ - **`@implements` and `@copy`**: schema-design directives that save repeating fields across types. The output is ordinary GraphQL: the directives, and their definitions if you declared them, are removed.
9
+
10
+ ## Install
11
+
12
+ ```sh
13
+ bun add @nxara/olio-schema graphql@16
14
+ ```
15
+
16
+ `graphql` 16 is a peer dependency (not 17, which is about 4× slower on small queries).
17
+
18
+ ## compose
19
+
20
+ ```ts
21
+ import { compose } from "@nxara/olio-schema";
22
+
23
+ const { document, schema, ownership } = compose(
24
+ [
25
+ { id: "users", typeDefs: [usersDoc] },
26
+ { id: "posts", typeDefs: [postsDoc] }
27
+ ],
28
+ directives
29
+ );
30
+ ```
31
+
32
+ - **Root types come for free.** If modules only `extend type Query`, a `type Query` is added, so no module needs a placeholder `_empty` field.
33
+ - **Root names are yours.** With `schema { query: RootQuery }` (or `extend schema`), the roots are the types named there; without a schema definition, GraphQL's defaults apply. `roots` reports the ones the schema has: `{ query: "RootQuery" }`, never a default with no type behind it.
34
+ - **`ownership`** maps module id → type → the fields that module declares, in a definition or an `extend`. The defining module also owns `__isTypeOf` or `__resolveType`. Enum values are owned the same way, so only the declaring module can give them internal values. A scalar is owned by the module that defines it (marked `__scalar`).
35
+ - **Errors point at files.** SDL and schema errors are collected and reported as `file:line:column: message`, using each document's `Source` name.
36
+ - **`bypass`** (`Map<"Type.field", Set<key>>`) holds what `@bypass(keys: …)` gives each field: on a field, or on an object type or `extend` block for the fields it declares. Every `@bypass` is removed from `document` and `schema`, before the other directives run. olio hands the keys to middleware; see its README.
37
+
38
+ You rarely call this yourself: codegen and olio call it with the `directives` you pass them.
39
+
40
+ ## Directives
41
+
42
+ Pass the same list to codegen and to olio, so both see the same schema:
43
+
44
+ ```ts
45
+ // directives.ts
46
+ import { copyDirective, implementsDirective } from "@nxara/olio-schema";
47
+
48
+ export const directives = [implementsDirective(), copyDirective()];
49
+
50
+ // codegen.ts
51
+ await codegen({
52
+ modules: "src/modules",
53
+ typeDefs: "**/typedefs/**/*.gql",
54
+ output: "src/generated.ts",
55
+ directives
56
+ });
57
+
58
+ // index.ts
59
+ export const app = olio({ modules, directives });
60
+ ```
61
+
62
+ Codegen records the directives' names in `Application` (`"~directives": "implements" | "copy"`), so in a typed app `olio()` doesn't compile without the same ones. A directive's `name` is its literal type (`SchemaDirective<"copy">`) for that check.
63
+
64
+ Or apply them yourself:
65
+
66
+ ```ts
67
+ import { applyDirectives } from "@nxara/olio-schema";
68
+
69
+ const document = applyDirectives(parse(sdl), directives);
70
+ ```
71
+
72
+ Only the directives you pass are enabled. Their order doesn't matter: `applyDirectives` runs in passes, and a type waits until the types it copies from are done. So chains work (`C` copies `B`, which copies `A`, which implements `Node`), and a cycle is an error.
73
+
74
+ ## @implements
75
+
76
+ On object types and their extensions. It adds the interfaces to the type's `implements` list and copies their fields.
77
+
78
+ ```graphql
79
+ interface Node {
80
+ id: ID!
81
+ }
82
+ interface Timestamped {
83
+ createdAt: DateTime!
84
+ }
85
+
86
+ type User @implements(from: ["Node", "Timestamped"]) {
87
+ name: String!
88
+ }
89
+ ```
90
+
91
+ becomes:
92
+
93
+ ```graphql
94
+ type User implements Node & Timestamped {
95
+ id: ID!
96
+ createdAt: DateTime!
97
+ name: String!
98
+ }
99
+ ```
100
+
101
+ Interface fields can't be overridden. Redeclaring one with a different type, arguments or directives, whether locally or from a second interface, is an error, so the mismatch shows up when the SDL loads. Repeating a field exactly, for example to add a description, is fine.
102
+
103
+ ## @copy
104
+
105
+ On object types, input types, and their extensions. It copies fields without adding an `implements` clause. Objects copy from objects and interfaces, inputs from inputs.
106
+
107
+ ```graphql
108
+ input CommonPagination {
109
+ cursor: String
110
+ limit: Int
111
+ }
112
+
113
+ input UserPagination @copy(from: ["CommonPagination"]) {
114
+ cursor: ID
115
+ }
116
+ ```
117
+
118
+ becomes:
119
+
120
+ ```graphql
121
+ input UserPagination {
122
+ cursor: ID
123
+ limit: Int
124
+ }
125
+ ```
126
+
127
+ Overriding is allowed, with spread semantics (`{ ...A, ...B, ...local }`): a later source overrides an earlier one, local fields override every source, and each field keeps the position where it first appeared.
128
+
129
+ ## Both directives
130
+
131
+ - `from` takes a list of type names, or one name: `@copy(from: "Base")`.
132
+ - On an extension, fields the type already declares elsewhere are skipped, so a module can `extend type User @implements(from: ["Timestamped"])`.
133
+ - Errors carry the file, line and column, and name the target type:
134
+
135
+ ```
136
+ users/user.gql:4:11: @copy on "User" references unknown type "Nope"
137
+ ```
138
+
139
+ ## Writing a directive
140
+
141
+ A directive is a `SchemaDirective`: a `name`, its SDL `definition`, an optional `validate(document)` that runs before any transform, and `transform(document, context)`. A transform that reads from other types should skip a target while `context.isPending(source)` is true. `applyDirectives` will call it again on the next pass.
@@ -0,0 +1,12 @@
1
+ import { type DocumentNode } from "graphql";
2
+ export interface DirectiveContext {
3
+ isPending(typeName: string): boolean;
4
+ }
5
+ export interface SchemaDirective<Name extends string = string> {
6
+ name: Name;
7
+ definition: string;
8
+ validate?(document: DocumentNode): void;
9
+ transform(document: DocumentNode, context: DirectiveContext): DocumentNode;
10
+ }
11
+ export declare function applyDirectives(document: DocumentNode, directives: readonly SchemaDirective[]): DocumentNode;
12
+ //# sourceMappingURL=apply-directives.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"apply-directives.d.ts","sourceRoot":"","sources":["../src/apply-directives.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,KAAK,YAAY,EAAE,MAAM,SAAS,CAAC;AAIlD,MAAM,WAAW,gBAAgB;IAK/B,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC;CACtC;AAMD,MAAM,WAAW,eAAe,CAAC,IAAI,SAAS,MAAM,GAAG,MAAM;IAE3D,IAAI,EAAE,IAAI,CAAC;IAEX,UAAU,EAAE,MAAM,CAAC;IAEnB,QAAQ,CAAC,CAAC,QAAQ,EAAE,YAAY,GAAG,IAAI,CAAC;IACxC,SAAS,CAAC,QAAQ,EAAE,YAAY,EAAE,OAAO,EAAE,gBAAgB,GAAG,YAAY,CAAC;CAC5E;AAID,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,YAAY,EACtB,UAAU,EAAE,SAAS,eAAe,EAAE,GACrC,YAAY,CA+Bd"}
@@ -0,0 +1,29 @@
1
+ import { Kind } from "graphql";
2
+ import { directiveUsages } from "./directives/shared.js";
3
+ export function applyDirectives(document, directives) {
4
+ if (directives.length === 0)
5
+ return document;
6
+ const names = new Set(directives.map((d) => d.name));
7
+ for (const directive of directives)
8
+ directive.validate?.(document);
9
+ let current = document;
10
+ let pending = directiveUsages(current, names);
11
+ while (pending.size > 0) {
12
+ for (const directive of directives) {
13
+ const types = directiveUsages(current, names);
14
+ current = directive.transform(current, {
15
+ isPending: (type) => types.has(type)
16
+ });
17
+ }
18
+ const left = directiveUsages(current, names);
19
+ if (left.size === pending.size) {
20
+ throw new Error(`Schema directives reference each other in a cycle: ${[...left].map((t) => `"${t}"`).join(", ")}`);
21
+ }
22
+ pending = left;
23
+ }
24
+ return {
25
+ ...current,
26
+ definitions: current.definitions.filter((def) => def.kind !== Kind.DIRECTIVE_DEFINITION || !names.has(def.name.value))
27
+ };
28
+ }
29
+ //# sourceMappingURL=apply-directives.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"apply-directives.js","sourceRoot":"","sources":["../src/apply-directives.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAqB,MAAM,SAAS,CAAC;AAElD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AA0BzD,MAAM,UAAU,eAAe,CAC7B,QAAsB,EACtB,UAAsC;IAEtC,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,QAAQ,CAAC;IAC7C,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IAErD,KAAK,MAAM,SAAS,IAAI,UAAU;QAAE,SAAS,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,CAAC;IAEnE,IAAI,OAAO,GAAG,QAAQ,CAAC;IACvB,IAAI,OAAO,GAAG,eAAe,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IAC9C,OAAO,OAAO,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC;QACxB,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;YACnC,MAAM,KAAK,GAAG,eAAe,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;YAC9C,OAAO,GAAG,SAAS,CAAC,SAAS,CAAC,OAAO,EAAE;gBACrC,SAAS,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC;aACrC,CAAC,CAAC;QACL,CAAC;QACD,MAAM,IAAI,GAAG,eAAe,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;QAC7C,IAAI,IAAI,CAAC,IAAI,KAAK,OAAO,CAAC,IAAI,EAAE,CAAC;YAC/B,MAAM,IAAI,KAAK,CACb,sDAAsD,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAClG,CAAC;QACJ,CAAC;QACD,OAAO,GAAG,IAAI,CAAC;IACjB,CAAC;IAED,OAAO;QACL,GAAG,OAAO;QACV,WAAW,EAAE,OAAO,CAAC,WAAW,CAAC,MAAM,CACrC,CAAC,GAAG,EAAE,EAAE,CACN,GAAG,CAAC,IAAI,KAAK,IAAI,CAAC,oBAAoB,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CACvE;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,8 @@
1
+ import { type DocumentNode } from "graphql";
2
+ export type Bypass = Map<string, Set<string>>;
3
+ export declare const bypassDefinition = "directive @bypass(keys: [String!]!) on OBJECT | FIELD_DEFINITION";
4
+ export declare function extractBypass(document: DocumentNode): {
5
+ document: DocumentNode;
6
+ bypass: Bypass;
7
+ };
8
+ //# sourceMappingURL=bypass.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bypass.d.ts","sourceRoot":"","sources":["../src/bypass.ts"],"names":[],"mappings":"AAAA,OAAO,EAKL,KAAK,YAAY,EAGlB,MAAM,SAAS,CAAC;AAKjB,MAAM,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;AAG9C,eAAO,MAAM,gBAAgB,qEACuC,CAAC;AA0CrE,wBAAgB,aAAa,CAAC,QAAQ,EAAE,YAAY,GAAG;IACrD,QAAQ,EAAE,YAAY,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;CAChB,CAiCA"}
package/dist/bypass.js ADDED
@@ -0,0 +1,58 @@
1
+ import { Kind, visit } from "graphql";
2
+ import { fail } from "./directives/shared.js";
3
+ export const bypassDefinition = "directive @bypass(keys: [String!]!) on OBJECT | FIELD_DEFINITION";
4
+ const isObject = (node) => node?.kind === Kind.OBJECT_TYPE_DEFINITION ||
5
+ node?.kind === Kind.OBJECT_TYPE_EXTENSION;
6
+ function keysOf(directive, target) {
7
+ const args = directive.arguments ?? [];
8
+ const other = args.find((arg) => arg.name.value !== "keys");
9
+ if (other) {
10
+ fail(other, `@bypass on ${target} takes only keys, not "${other.name.value}"`);
11
+ }
12
+ const keys = args[0];
13
+ if (!keys) {
14
+ fail(directive, `@bypass on ${target} needs keys, e.g. @bypass(keys: ["tokenCheck"])`);
15
+ }
16
+ const values = keys.value.kind === Kind.LIST ? keys.value.values : [keys.value];
17
+ if (values.length === 0)
18
+ fail(keys, `@bypass on ${target} needs at least one key`);
19
+ return values.map((value) => {
20
+ if (value.kind !== Kind.STRING || value.value === "") {
21
+ fail(value, `@bypass on ${target}: keys are non-empty strings`);
22
+ }
23
+ return value.value;
24
+ });
25
+ }
26
+ export function extractBypass(document) {
27
+ const bypass = new Map();
28
+ const add = (field, keys) => {
29
+ const set = bypass.get(field) ?? new Set();
30
+ for (const key of keys)
31
+ set.add(key);
32
+ bypass.set(field, set);
33
+ };
34
+ const stripped = visit(document, {
35
+ DirectiveDefinition: (node) => node.name.value === "bypass" ? null : undefined,
36
+ Directive(node, _key, _parent, _path, ancestors) {
37
+ if (node.name.value !== "bypass")
38
+ return undefined;
39
+ const owner = ancestors.at(-1);
40
+ const type = ancestors.at(-3);
41
+ if (isObject(owner)) {
42
+ const keys = keysOf(node, `"${owner.name.value}"`);
43
+ for (const field of owner.fields ?? []) {
44
+ add(`${owner.name.value}.${field.name.value}`, keys);
45
+ }
46
+ return null;
47
+ }
48
+ if (owner?.kind === Kind.FIELD_DEFINITION && isObject(type)) {
49
+ const field = `${type.name.value}.${owner.name.value}`;
50
+ add(field, keysOf(node, `"${field}"`));
51
+ return null;
52
+ }
53
+ return fail(node, "@bypass applies to object types and their fields only");
54
+ }
55
+ });
56
+ return { document: stripped, bypass };
57
+ }
58
+ //# sourceMappingURL=bypass.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bypass.js","sourceRoot":"","sources":["../src/bypass.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ import { type DocumentNode, type GraphQLSchema } from "graphql";
2
+ import { type SchemaDirective } from "./apply-directives.js";
3
+ import { type Bypass } from "./bypass.js";
4
+ export interface ModuleSDL {
5
+ id: string;
6
+ typeDefs: readonly DocumentNode[];
7
+ }
8
+ export type Ownership = Map<string, Map<string, Set<string>>>;
9
+ export type Operation = "query" | "mutation" | "subscription";
10
+ export type RootTypes = Partial<Record<Operation, string>>;
11
+ export declare const SCALAR = "__scalar";
12
+ export interface Composed {
13
+ document: DocumentNode;
14
+ schema: GraphQLSchema;
15
+ ownership: Ownership;
16
+ roots: RootTypes;
17
+ bypass: Bypass;
18
+ }
19
+ export declare function compose(modules: readonly ModuleSDL[], directives?: readonly SchemaDirective[]): Composed;
20
+ //# sourceMappingURL=compose.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compose.d.ts","sourceRoot":"","sources":["../src/compose.ts"],"names":[],"mappings":"AAAA,OAAO,EAML,KAAK,YAAY,EAEjB,KAAK,aAAa,EAEnB,MAAM,SAAS,CAAC;AAMjB,OAAO,EAAmB,KAAK,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAC9E,OAAO,EAAiB,KAAK,MAAM,EAAE,MAAM,aAAa,CAAC;AAIzD,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,SAAS,YAAY,EAAE,CAAC;CACnC;AAGD,MAAM,MAAM,SAAS,GAAG,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AAE9D,MAAM,MAAM,SAAS,GAAG,OAAO,GAAG,UAAU,GAAG,cAAc,CAAC;AAE9D,MAAM,MAAM,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC,CAAC;AAG3D,eAAO,MAAM,MAAM,aAAa,CAAC;AAEjC,MAAM,WAAW,QAAQ;IACvB,QAAQ,EAAE,YAAY,CAAC;IACvB,MAAM,EAAE,aAAa,CAAC;IACtB,SAAS,EAAE,SAAS,CAAC;IACrB,KAAK,EAAE,SAAS,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;CAChB;AAwKD,wBAAgB,OAAO,CACrB,OAAO,EAAE,SAAS,SAAS,EAAE,EAC7B,UAAU,GAAE,SAAS,eAAe,EAAO,GAC1C,QAAQ,CAiCV"}
@@ -0,0 +1,149 @@
1
+ import { buildASTSchema, concatAST, Kind, validateSchema } from "graphql";
2
+ import { validateSDL } from "graphql/validation/validate.js";
3
+ import { applyDirectives } from "./apply-directives.js";
4
+ import { extractBypass } from "./bypass.js";
5
+ import { located, position } from "./directives/shared.js";
6
+ export const SCALAR = "__scalar";
7
+ function schemaRoots(schema) {
8
+ const roots = {};
9
+ const types = {
10
+ query: schema.getQueryType(),
11
+ mutation: schema.getMutationType(),
12
+ subscription: schema.getSubscriptionType()
13
+ };
14
+ for (const [operation, type] of Object.entries(types)) {
15
+ if (type)
16
+ roots[operation] = type.name;
17
+ }
18
+ return roots;
19
+ }
20
+ function rootTypes(document) {
21
+ const declared = {};
22
+ let hasSchema = false;
23
+ for (const def of document.definitions) {
24
+ if (def.kind !== Kind.SCHEMA_DEFINITION &&
25
+ def.kind !== Kind.SCHEMA_EXTENSION) {
26
+ continue;
27
+ }
28
+ hasSchema = true;
29
+ for (const { operation, type } of def.operationTypes ?? []) {
30
+ declared[operation] = type.name.value;
31
+ }
32
+ }
33
+ return hasSchema
34
+ ? declared
35
+ : { query: "Query", mutation: "Mutation", subscription: "Subscription" };
36
+ }
37
+ function withRootTypes(document, roots) {
38
+ const defined = new Set();
39
+ const extended = new Set();
40
+ for (const def of document.definitions) {
41
+ if (def.kind === Kind.OBJECT_TYPE_DEFINITION)
42
+ defined.add(def.name.value);
43
+ if (def.kind === Kind.OBJECT_TYPE_EXTENSION)
44
+ extended.add(def.name.value);
45
+ }
46
+ const missing = Object.values(roots).filter((t) => extended.has(t) && !defined.has(t));
47
+ return {
48
+ ...document,
49
+ definitions: [
50
+ ...missing.map((name) => ({
51
+ kind: Kind.OBJECT_TYPE_DEFINITION,
52
+ name: { kind: Kind.NAME, value: name },
53
+ fields: []
54
+ })),
55
+ ...document.definitions
56
+ ]
57
+ };
58
+ }
59
+ function moduleTracker(modules) {
60
+ const origin = new Map();
61
+ for (const { id, typeDefs } of modules) {
62
+ for (const doc of typeDefs) {
63
+ for (const def of doc.definitions) {
64
+ origin.set(def, id);
65
+ if (def.loc)
66
+ origin.set(def.loc.source, id);
67
+ }
68
+ }
69
+ }
70
+ return (definition) => {
71
+ const id = origin.get(definition) ??
72
+ (definition.loc ? origin.get(definition.loc.source) : undefined);
73
+ if (id === undefined) {
74
+ const name = "name" in definition ? definition.name?.value : undefined;
75
+ throw new Error(`Cannot tell which module declares "${name ?? definition.kind}"`);
76
+ }
77
+ return id;
78
+ };
79
+ }
80
+ function collectOwnership(document, moduleOf, ids, roots) {
81
+ const rootNames = new Set(Object.values(roots));
82
+ const ownership = new Map(ids.map((id) => [id, new Map()]));
83
+ const own = (definition, type, names) => {
84
+ if (names.length === 0)
85
+ return;
86
+ const id = moduleOf(definition);
87
+ const types = ownership.get(id) ?? new Map();
88
+ const fields = types.get(type) ?? new Set();
89
+ for (const name of names)
90
+ fields.add(name);
91
+ types.set(type, fields);
92
+ ownership.set(id, types);
93
+ };
94
+ for (const def of document.definitions) {
95
+ if (def.kind === Kind.OBJECT_TYPE_DEFINITION ||
96
+ def.kind === Kind.OBJECT_TYPE_EXTENSION) {
97
+ const type = def.name.value;
98
+ const fields = (def.fields ?? []).map((f) => f.name.value);
99
+ const definesObject = def.kind === Kind.OBJECT_TYPE_DEFINITION && !rootNames.has(type);
100
+ own(def, type, definesObject ? ["__isTypeOf", ...fields] : fields);
101
+ }
102
+ else if (def.kind === Kind.INTERFACE_TYPE_DEFINITION ||
103
+ def.kind === Kind.UNION_TYPE_DEFINITION) {
104
+ own(def, def.name.value, ["__resolveType"]);
105
+ }
106
+ else if (def.kind === Kind.SCALAR_TYPE_DEFINITION) {
107
+ own(def, def.name.value, [SCALAR]);
108
+ }
109
+ else if (def.kind === Kind.ENUM_TYPE_DEFINITION ||
110
+ def.kind === Kind.ENUM_TYPE_EXTENSION) {
111
+ own(def, def.name.value, (def.values ?? []).map((v) => v.name.value));
112
+ }
113
+ }
114
+ return ownership;
115
+ }
116
+ function assertNoErrors(errors, title) {
117
+ if (errors.length === 0)
118
+ return;
119
+ const lines = errors.map(({ nodes = [], message }) => [
120
+ ` ${located(nodes[0], message)}`,
121
+ ...nodes.slice(1).map((node) => ` also at ${position(node)}`)
122
+ ].join("\n"));
123
+ if (errors.some((e) => e.message.startsWith("Unknown directive"))) {
124
+ lines.push("A schema directive (e.g. @copy) must be passed as `directives`, to codegen and olio() alike.");
125
+ }
126
+ throw new Error(`${title}:\n${lines.join("\n")}`);
127
+ }
128
+ export function compose(modules, directives = []) {
129
+ const merged = new Map();
130
+ for (const { id, typeDefs } of modules) {
131
+ merged.set(id, [...(merged.get(id) ?? []), ...typeDefs]);
132
+ }
133
+ const grouped = [...merged].map(([id, typeDefs]) => ({ id, typeDefs }));
134
+ const { document: sdl, bypass } = extractBypass(concatAST(grouped.flatMap((m) => m.typeDefs)));
135
+ const candidates = rootTypes(sdl);
136
+ const document = applyDirectives(withRootTypes(sdl, candidates), directives);
137
+ assertNoErrors(validateSDL(document), "Invalid SDL");
138
+ const schema = buildASTSchema(document, { assumeValidSDL: true });
139
+ assertNoErrors(validateSchema(schema), "Invalid schema");
140
+ const roots = schemaRoots(schema);
141
+ return {
142
+ document,
143
+ schema,
144
+ ownership: collectOwnership(document, moduleTracker(grouped), grouped.map((m) => m.id), roots),
145
+ roots,
146
+ bypass
147
+ };
148
+ }
149
+ //# sourceMappingURL=compose.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compose.js","sourceRoot":"","sources":["../src/compose.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { SchemaDirective } from "../apply-directives.js";
2
+ export declare function copyDirective(): SchemaDirective<"copy">;
3
+ //# sourceMappingURL=copy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"copy.d.ts","sourceRoot":"","sources":["../../src/directives/copy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAQ9D,wBAAgB,aAAa,IAAI,eAAe,CAAC,MAAM,CAAC,CAOvD"}
@@ -0,0 +1,10 @@
1
+ import { fieldCopyDirective } from "./shared.js";
2
+ export function copyDirective() {
3
+ return fieldCopyDirective({
4
+ name: "copy",
5
+ definition: "directive @copy(from: [String!]!) on OBJECT | INPUT_OBJECT",
6
+ sourceKinds: { object: ["object", "interface"], input: ["input"] },
7
+ overrides: true
8
+ });
9
+ }
10
+ //# sourceMappingURL=copy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"copy.js","sourceRoot":"","sources":["../../src/directives/copy.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAOjD,MAAM,UAAU,aAAa;IAC3B,OAAO,kBAAkB,CAAC;QACxB,IAAI,EAAE,MAAM;QACZ,UAAU,EAAE,4DAA4D;QACxE,WAAW,EAAE,EAAE,MAAM,EAAE,CAAC,QAAQ,EAAE,WAAW,CAAC,EAAE,KAAK,EAAE,CAAC,OAAO,CAAC,EAAE;QAClE,SAAS,EAAE,IAAI;KAChB,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { SchemaDirective } from "../apply-directives.js";
2
+ export declare function implementsDirective(): SchemaDirective<"implements">;
3
+ //# sourceMappingURL=implements.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"implements.d.ts","sourceRoot":"","sources":["../../src/directives/implements.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAO9D,wBAAgB,mBAAmB,IAAI,eAAe,CAAC,YAAY,CAAC,CAQnE"}
@@ -0,0 +1,11 @@
1
+ import { fieldCopyDirective } from "./shared.js";
2
+ export function implementsDirective() {
3
+ return fieldCopyDirective({
4
+ name: "implements",
5
+ definition: "directive @implements(from: [String!]!) on OBJECT",
6
+ sourceKinds: { object: ["interface"] },
7
+ addInterfaces: true,
8
+ overrides: false
9
+ });
10
+ }
11
+ //# sourceMappingURL=implements.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"implements.js","sourceRoot":"","sources":["../../src/directives/implements.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAMjD,MAAM,UAAU,mBAAmB;IACjC,OAAO,kBAAkB,CAAC;QACxB,IAAI,EAAE,YAAY;QAClB,UAAU,EAAE,mDAAmD;QAC/D,WAAW,EAAE,EAAE,MAAM,EAAE,CAAC,WAAW,CAAC,EAAE;QACtC,aAAa,EAAE,IAAI;QACnB,SAAS,EAAE,KAAK;KACjB,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,17 @@
1
+ import { type ASTNode, type DocumentNode } from "graphql";
2
+ import type { SchemaDirective } from "../apply-directives.js";
3
+ type TargetKind = "object" | "input";
4
+ export declare function position(node: ASTNode | undefined): string;
5
+ export declare function located(node: ASTNode | undefined, message: string): string;
6
+ export declare function fail(node: ASTNode, message: string): never;
7
+ export declare function directiveUsages(document: DocumentNode, names: ReadonlySet<string>): Set<string>;
8
+ export interface FieldCopySpec<Name extends string> {
9
+ name: Name;
10
+ definition: string;
11
+ sourceKinds: Partial<Record<TargetKind, readonly string[]>>;
12
+ addInterfaces?: boolean;
13
+ overrides: boolean;
14
+ }
15
+ export declare function fieldCopyDirective<Name extends string>(spec: FieldCopySpec<Name>): SchemaDirective<Name>;
16
+ export {};
17
+ //# sourceMappingURL=shared.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../src/directives/shared.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,OAAO,EAGZ,KAAK,YAAY,EAIlB,MAAM,SAAS,CAAC;AAEjB,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAG9D,KAAK,UAAU,GAAG,QAAQ,GAAG,OAAO,CAAC;AAqBrC,wBAAgB,QAAQ,CAAC,IAAI,EAAE,OAAO,GAAG,SAAS,GAAG,MAAM,CAK1D;AAED,wBAAgB,OAAO,CAAC,IAAI,EAAE,OAAO,GAAG,SAAS,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAG1E;AAED,wBAAgB,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,GAAG,KAAK,CAE1D;AAaD,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,YAAY,EACtB,KAAK,EAAE,WAAW,CAAC,MAAM,CAAC,GACzB,GAAG,CAAC,MAAM,CAAC,CASb;AAoID,MAAM,WAAW,aAAa,CAAC,IAAI,SAAS,MAAM;IAChD,IAAI,EAAE,IAAI,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,OAAO,CAAC,MAAM,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE,CAAC,CAAC,CAAC;IAC5D,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,wBAAgB,kBAAkB,CAAC,IAAI,SAAS,MAAM,EACpD,IAAI,EAAE,aAAa,CAAC,IAAI,CAAC,GACxB,eAAe,CAAC,IAAI,CAAC,CAiHvB"}
@@ -0,0 +1,223 @@
1
+ import { getLocation, Kind, print } from "graphql";
2
+ const KINDS = {
3
+ [Kind.OBJECT_TYPE_DEFINITION]: "object",
4
+ [Kind.OBJECT_TYPE_EXTENSION]: "object",
5
+ [Kind.INTERFACE_TYPE_DEFINITION]: "interface",
6
+ [Kind.INTERFACE_TYPE_EXTENSION]: "interface",
7
+ [Kind.INPUT_OBJECT_TYPE_DEFINITION]: "input",
8
+ [Kind.INPUT_OBJECT_TYPE_EXTENSION]: "input",
9
+ [Kind.UNION_TYPE_DEFINITION]: "union",
10
+ [Kind.UNION_TYPE_EXTENSION]: "union",
11
+ [Kind.ENUM_TYPE_DEFINITION]: "enum",
12
+ [Kind.ENUM_TYPE_EXTENSION]: "enum",
13
+ [Kind.SCALAR_TYPE_DEFINITION]: "scalar",
14
+ [Kind.SCALAR_TYPE_EXTENSION]: "scalar"
15
+ };
16
+ const article = (kind) => /^[aeiou]/.test(kind) ? `an ${kind}` : `a ${kind}`;
17
+ export function position(node) {
18
+ if (!node?.loc)
19
+ return "";
20
+ const { line, column } = getLocation(node.loc.source, node.loc.start);
21
+ const file = node.loc.source.name;
22
+ return `${file === "GraphQL request" ? "" : `${file}:`}${line}:${column}`;
23
+ }
24
+ export function located(node, message) {
25
+ const at = position(node);
26
+ return at ? `${at}: ${message}` : message;
27
+ }
28
+ export function fail(node, message) {
29
+ throw new Error(located(node, message));
30
+ }
31
+ const asType = (def) => KINDS[def.kind] ? def : undefined;
32
+ export function directiveUsages(document, names) {
33
+ const types = new Set();
34
+ for (const def of document.definitions) {
35
+ const type = asType(def);
36
+ if (type?.directives?.some((d) => names.has(d.name.value))) {
37
+ types.add(type.name.value);
38
+ }
39
+ }
40
+ return types;
41
+ }
42
+ function analyze(document) {
43
+ const analysis = {
44
+ kinds: new Map(),
45
+ fields: new Map(),
46
+ interfaces: new Map()
47
+ };
48
+ for (const def of document.definitions) {
49
+ const type = asType(def);
50
+ const kind = KINDS[def.kind];
51
+ if (!type || !kind)
52
+ continue;
53
+ const name = type.name.value;
54
+ analysis.kinds.set(name, kind);
55
+ analysis.fields.set(name, [
56
+ ...(analysis.fields.get(name) ?? []),
57
+ ...(type.fields ?? [])
58
+ ]);
59
+ const interfaces = analysis.interfaces.get(name) ?? new Set();
60
+ for (const i of type.interfaces ?? [])
61
+ interfaces.add(i.name.value);
62
+ analysis.interfaces.set(name, interfaces);
63
+ }
64
+ return analysis;
65
+ }
66
+ function sourceNames(directive, name) {
67
+ const arg = directive.arguments?.find((a) => a.name.value === "from");
68
+ if (!arg) {
69
+ fail(directive, `@${name} needs a "from" argument, e.g. @${name}(from: ["Node"])`);
70
+ }
71
+ const values = arg.value.kind === Kind.LIST ? arg.value.values : [arg.value];
72
+ return values.map((value) => value.kind === Kind.STRING
73
+ ? value.value
74
+ : fail(value, `@${name} "from" takes type names as strings, e.g. @${name}(from: ["Node"])`));
75
+ }
76
+ const shape = (field) => print({ ...field, description: undefined });
77
+ function mergeFields(merge) {
78
+ const merged = new Map();
79
+ const entries = [
80
+ ...merge.sources.flatMap(([from, fields]) => fields.map((f) => [from, f])),
81
+ ...merge.local.map((f) => [merge.target, f])
82
+ ];
83
+ for (const [from, field] of entries) {
84
+ const name = field.name.value;
85
+ if (merge.declaredElsewhere.has(name))
86
+ continue;
87
+ const previous = merged.get(name);
88
+ if (previous && !merge.overrides && shape(previous[1]) !== shape(field)) {
89
+ fail(merge.directive, `@${merge.directive.name.value} on "${merge.target}": "${from}" redeclares field "${name}" from "${previous[0]}" (${shape(previous[1])} vs ${shape(field)}). Remove one, or use @copy to override.`);
90
+ }
91
+ merged.set(name, [from, field]);
92
+ }
93
+ return [...merged.values()].map(([, field]) => field);
94
+ }
95
+ function findCycle(edges) {
96
+ const done = new Set();
97
+ const path = [];
98
+ const visit = (type) => {
99
+ const at = path.findIndex((step) => step.type === type);
100
+ if (at !== -1) {
101
+ const steps = path.slice(at);
102
+ return {
103
+ usages: steps.map((step) => step.via),
104
+ path: [...steps.map((step) => step.type), type]
105
+ };
106
+ }
107
+ if (done.has(type))
108
+ return undefined;
109
+ const step = { type };
110
+ path.push(step);
111
+ for (const { directive, sources } of edges.get(type) ?? []) {
112
+ step.via = directive;
113
+ for (const source of sources) {
114
+ const cycle = visit(source);
115
+ if (cycle)
116
+ return cycle;
117
+ }
118
+ }
119
+ path.pop();
120
+ done.add(type);
121
+ return undefined;
122
+ };
123
+ for (const type of edges.keys()) {
124
+ const cycle = visit(type);
125
+ if (cycle)
126
+ return cycle;
127
+ }
128
+ return undefined;
129
+ }
130
+ export function fieldCopyDirective(spec) {
131
+ const { name } = spec;
132
+ const targets = Object.keys(spec.sourceKinds).map((k) => `${k} types`);
133
+ const usage = (type) => type.directives?.find((d) => d.name.value === name);
134
+ const resolve = (type, directive, analysis) => {
135
+ const kind = KINDS[type.kind] ?? "";
136
+ const allowed = spec.sourceKinds[kind];
137
+ const target = type.name.value;
138
+ if (!allowed) {
139
+ fail(directive, `@${name} can only be used on ${targets.join(" and ")}, but "${target}" is ${article(kind)}`);
140
+ }
141
+ return sourceNames(directive, name).map((source) => {
142
+ const sourceKind = analysis.kinds.get(source);
143
+ if (!sourceKind) {
144
+ fail(directive, `@${name} on "${target}" references unknown type "${source}"`);
145
+ }
146
+ if (!allowed.includes(sourceKind)) {
147
+ fail(directive, `@${name} on "${target}" can copy from ${allowed.map((k) => `${k} types`).join(" and ")}, but "${source}" is ${article(sourceKind)}`);
148
+ }
149
+ return source;
150
+ });
151
+ };
152
+ return {
153
+ name,
154
+ definition: spec.definition,
155
+ validate(document) {
156
+ const analysis = analyze(document);
157
+ const edges = new Map();
158
+ for (const def of document.definitions) {
159
+ const type = asType(def);
160
+ const directive = type && usage(type);
161
+ if (!type || !directive)
162
+ continue;
163
+ const sources = resolve(type, directive, analysis);
164
+ const target = type.name.value;
165
+ edges.set(target, [
166
+ ...(edges.get(target) ?? []),
167
+ { directive, sources }
168
+ ]);
169
+ }
170
+ const cycle = findCycle(edges);
171
+ if (cycle) {
172
+ const chain = cycle.path.map((t) => `"${t}"`).join(" -> ");
173
+ const [first, ...others] = cycle.usages;
174
+ throw new Error([
175
+ located(first, `@${name} cycle: ${chain}`),
176
+ ...others.map((usage) => ` also at ${position(usage)}`)
177
+ ].join("\n"));
178
+ }
179
+ },
180
+ transform(document, context) {
181
+ const analysis = analyze(document);
182
+ const definitions = document.definitions.map((def) => {
183
+ const type = asType(def);
184
+ const directive = type && usage(type);
185
+ if (!type || !directive)
186
+ return def;
187
+ const sources = resolve(type, directive, analysis);
188
+ if (sources.some((s) => context.isPending(s)))
189
+ return def;
190
+ const target = type.name.value;
191
+ const local = type.fields ?? [];
192
+ const elsewhere = new Set((analysis.fields.get(target) ?? [])
193
+ .filter((f) => !local.includes(f))
194
+ .map((f) => f.name.value));
195
+ const next = {
196
+ ...type,
197
+ fields: mergeFields({
198
+ directive,
199
+ target,
200
+ sources: sources.map((s) => [s, analysis.fields.get(s) ?? []]),
201
+ local,
202
+ declaredElsewhere: elsewhere,
203
+ overrides: spec.overrides
204
+ }),
205
+ directives: type.directives?.filter((d) => d !== directive)
206
+ };
207
+ if (spec.addInterfaces) {
208
+ const declared = analysis.interfaces.get(target) ?? new Set();
209
+ const added = sources
210
+ .filter((s) => !declared.has(s))
211
+ .map((s) => ({
212
+ kind: Kind.NAMED_TYPE,
213
+ name: { kind: Kind.NAME, value: s }
214
+ }));
215
+ next.interfaces = [...(type.interfaces ?? []), ...added];
216
+ }
217
+ return next;
218
+ });
219
+ return { ...document, definitions };
220
+ }
221
+ };
222
+ }
223
+ //# sourceMappingURL=shared.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shared.js","sourceRoot":"","sources":["../../src/directives/shared.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ export { applyDirectives } from "./apply-directives.js";
2
+ export type { DirectiveContext, SchemaDirective } from "./apply-directives.js";
3
+ export { bypassDefinition } from "./bypass.js";
4
+ export type { Bypass } from "./bypass.js";
5
+ export { compose, SCALAR } from "./compose.js";
6
+ export type { Composed, ModuleSDL, Operation, Ownership, RootTypes } from "./compose.js";
7
+ export { implementsDirective } from "./directives/implements.js";
8
+ export { copyDirective } from "./directives/copy.js";
9
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,YAAY,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAC/E,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/C,YAAY,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAC/C,YAAY,EACV,QAAQ,EACR,SAAS,EACT,SAAS,EACT,SAAS,EACT,SAAS,EACV,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,6 @@
1
+ export { applyDirectives } from "./apply-directives.js";
2
+ export { bypassDefinition } from "./bypass.js";
3
+ export { compose, SCALAR } from "./compose.js";
4
+ export { implementsDirective } from "./directives/implements.js";
5
+ export { copyDirective } from "./directives/copy.js";
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAExD,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAE/C,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAQ/C,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,44 @@
1
1
  {
2
2
  "name": "@nxara/olio-schema",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "0.1.0",
4
+ "description": "Compose module SDL into one validated GraphQL schema, with schema-design directives.",
5
+ "keywords": [
6
+ "compose",
7
+ "directives",
8
+ "graphql",
9
+ "nxara",
10
+ "schema",
11
+ "sdl"
12
+ ],
13
+ "license": "MIT",
14
+ "repository": {
15
+ "type": "git",
16
+ "url": "git+https://github.com/nxara-hub/olio.git",
17
+ "directory": "packages/schema"
18
+ },
19
+ "files": [
20
+ "dist"
21
+ ],
22
+ "type": "module",
23
+ "sideEffects": false,
24
+ "exports": {
25
+ ".": {
26
+ "types": "./dist/index.d.ts",
27
+ "default": "./dist/index.js"
28
+ }
29
+ },
30
+ "publishConfig": {
31
+ "access": "public"
32
+ },
33
+ "scripts": {
34
+ "build": "tsc",
35
+ "test": "bun test",
36
+ "check-types": "tsc -p tsconfig.test.json"
37
+ },
38
+ "devDependencies": {
39
+ "graphql": "^16.14.2"
40
+ },
41
+ "peerDependencies": {
42
+ "graphql": "^16.13.0"
43
+ }
44
+ }