graphql-jerky 1.0.7 → 1.0.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -34,6 +34,27 @@ in the same directory.
34
34
  A path to a directory or file can be passed as the first parameter to limit to
35
35
  scope of the search.
36
36
 
37
+ ### Type extensions
38
+
39
+ Type extensions (`extend type`, `extend interface`, `extend union`,
40
+ `extend enum`, `extend input` and `extend scalar`) are merged into the type
41
+ that they extend. The extension and the definition can be in different files,
42
+ in any order.
43
+
44
+ ```gql
45
+ # user.graphql
46
+ type Query {
47
+ me: User
48
+ }
49
+
50
+ # post.graphql
51
+ extend type Query {
52
+ posts: [Post!]!
53
+ }
54
+ ```
55
+
56
+ An extension of a type that is not defined causes an error.
57
+
37
58
  ### Options
38
59
 
39
60
  #### --graphql
@@ -2,9 +2,9 @@
2
2
 
3
3
  'use strict';
4
4
 
5
- var path = require('path');
5
+ var fs = require('node:fs/promises');
6
+ var path = require('node:path');
6
7
  var commander = require('commander');
7
- var fs = require('fs/promises');
8
8
  var lib = require('../lib.cjs');
9
9
 
10
10
  commander.program
@@ -13,37 +13,43 @@ commander.program
13
13
  .description("Schema-first GraphQL typescript code generator")
14
14
  .argument("[schema]", "Path to schema file or directory.")
15
15
  .option("-o, --out <destination>", "Path to write schema_gen.ts.")
16
+ .option("-t", "Write types to a separate file.")
17
+ .option("--types-out <destination>", "Path to write types_gen.ts. Types will be written in types_gen.ts if omitted and -t is used.")
16
18
  .option("--graphql <module>", "graphql module import specifier.")
17
19
  .option("--scalars <module>", "scalars module import specifier.")
18
20
  .option("--resolvers <directory>", "resolvers directory path.")
19
21
  .option("--subscribers <module>", "subscriber module import specifier.")
20
22
  .option("--field-directives <module>", "field directives module import specifier.")
21
23
  .option("--input-directives <module>", "input directives module import specifier.")
24
+ .option("--include-ast-nodes", "Include ast nodes in graphql type objects")
25
+ .option("--include-subscription-resolvers", "Include subscription field resolvers in graphql type objects")
22
26
  .option("--ext <mode>", 'whether "keep", "replace", or "omit" the .ts extension in import statements.')
23
27
  .showHelpAfterError(true);
24
28
  commander.program.parse();
25
- const { out = "schema_gen.ts", graphql = "graphql", scalars, resolvers, subscribers, fieldDirectives, inputDirectives, ext = "omit", } = commander.program.opts();
29
+ const { out = "schema_gen.ts", typesOut, graphql = "graphql", scalars, resolvers, subscribers, fieldDirectives, inputDirectives, ext = "omit", t: splitTypesFile, includeAstNodes, includeSubscriptionResolvers: includeSubscriptionFieldResolvers, } = commander.program.opts();
26
30
  const [schema = "."] = commander.program.args;
27
- (async () => {
28
- let outfile = out;
29
- if (!outfile.pathname.endsWith("/")) {
31
+ async function normalizeOutfile(path, defaultFilename) {
32
+ if (!path.endsWith("/")) {
30
33
  // test if it's a directory
31
34
  try {
32
- const stat = await fs.stat(outfile);
35
+ const stat = await fs.stat(path);
33
36
  if (stat.isDirectory()) {
34
- outfile += "/";
37
+ path += "/";
35
38
  }
36
39
  }
37
40
  catch {
38
41
  // probably doesn't exist yet
39
42
  }
40
43
  }
41
- if (outfile.endsWith("/")) {
42
- outfile += "schema_gen.ts";
44
+ if (path.endsWith("/")) {
45
+ path += defaultFilename;
43
46
  }
44
- if (!outfile.endsWith(".ts")) {
45
- outfile += ".ts";
47
+ if (!path.endsWith(".ts")) {
48
+ path += ".ts";
46
49
  }
50
+ return path;
51
+ }
52
+ (async () => {
47
53
  switch (ext) {
48
54
  case "keep":
49
55
  case "replace":
@@ -52,7 +58,7 @@ const [schema = "."] = commander.program.args;
52
58
  default:
53
59
  throw new Error(`invalid mode for --ext: ${ext}`);
54
60
  }
55
- await fs.writeFile(outfile, lib.generate(await lib.parseSchema(path.resolve(schema)), outfile.pathname, {
61
+ const generator = lib.createGenerator(await lib.parseSchema(path.resolve(schema)), {
56
62
  scalarsInfo: scalars ? await lib.parseScalars(scalars) : undefined,
57
63
  fieldDirectivesInfo: fieldDirectives
58
64
  ? await lib.parseTypeResolvers("", fieldDirectives)
@@ -66,9 +72,22 @@ const [schema = "."] = commander.program.args;
66
72
  : undefined,
67
73
  graphqlModuleSpecifier: graphql,
68
74
  extMode: ext,
69
- }));
75
+ includeAstNodes,
76
+ includeSubscriptionFieldResolvers,
77
+ });
78
+ const outfile = await normalizeOutfile(out, "schema_gen.ts");
79
+ if (splitTypesFile || typesOut) {
80
+ const typesfile = await normalizeOutfile(typesOut ?? path.dirname(outfile), "types_gen.ts");
81
+ await Promise.all([
82
+ fs.writeFile(outfile, generator.generateSchema(outfile)),
83
+ fs.writeFile(typesfile, generator.generateTypes(typesfile)),
84
+ ]);
85
+ }
86
+ else {
87
+ await fs.writeFile(outfile, generator.generate(outfile));
88
+ }
70
89
  })().catch((err) => {
71
- console.error(err.message);
90
+ console.error(err.stack);
72
91
  console.log();
73
92
  if (process.argv.length === 2 ||
74
93
  (process.argv.length === 3 && process.argv[2] === "help")) {
@@ -1,10 +1,10 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- import path from 'path';
3
+ import fs from 'node:fs/promises';
4
+ import path from 'node:path';
4
5
  import { program } from 'commander';
5
- import fs from 'fs/promises';
6
- import { generate, parseScalars as parse, parseTypeResolvers, parseResolvers as parse$1, parseSchema as parse$2 } from '../lib.mjs';
7
- import 'url';
6
+ import { createGenerator, parseScalars as parse, parseTypeResolvers, parseResolvers as parse$1, parseSchema as parse$2 } from '../lib.mjs';
7
+ import 'node:url';
8
8
  import 'graphql';
9
9
  import 'jennifer-js';
10
10
  import 'jennifer-js/format';
@@ -21,37 +21,43 @@ program
21
21
  .description("Schema-first GraphQL typescript code generator")
22
22
  .argument("[schema]", "Path to schema file or directory.")
23
23
  .option("-o, --out <destination>", "Path to write schema_gen.ts.")
24
+ .option("-t", "Write types to a separate file.")
25
+ .option("--types-out <destination>", "Path to write types_gen.ts. Types will be written in types_gen.ts if omitted and -t is used.")
24
26
  .option("--graphql <module>", "graphql module import specifier.")
25
27
  .option("--scalars <module>", "scalars module import specifier.")
26
28
  .option("--resolvers <directory>", "resolvers directory path.")
27
29
  .option("--subscribers <module>", "subscriber module import specifier.")
28
30
  .option("--field-directives <module>", "field directives module import specifier.")
29
31
  .option("--input-directives <module>", "input directives module import specifier.")
32
+ .option("--include-ast-nodes", "Include ast nodes in graphql type objects")
33
+ .option("--include-subscription-resolvers", "Include subscription field resolvers in graphql type objects")
30
34
  .option("--ext <mode>", 'whether "keep", "replace", or "omit" the .ts extension in import statements.')
31
35
  .showHelpAfterError(true);
32
36
  program.parse();
33
- const { out = "schema_gen.ts", graphql = "graphql", scalars, resolvers, subscribers, fieldDirectives, inputDirectives, ext = "omit", } = program.opts();
37
+ const { out = "schema_gen.ts", typesOut, graphql = "graphql", scalars, resolvers, subscribers, fieldDirectives, inputDirectives, ext = "omit", t: splitTypesFile, includeAstNodes, includeSubscriptionResolvers: includeSubscriptionFieldResolvers, } = program.opts();
34
38
  const [schema = "."] = program.args;
35
- (async () => {
36
- let outfile = out;
37
- if (!outfile.pathname.endsWith("/")) {
39
+ async function normalizeOutfile(path, defaultFilename) {
40
+ if (!path.endsWith("/")) {
38
41
  // test if it's a directory
39
42
  try {
40
- const stat = await fs.stat(outfile);
43
+ const stat = await fs.stat(path);
41
44
  if (stat.isDirectory()) {
42
- outfile += "/";
45
+ path += "/";
43
46
  }
44
47
  }
45
48
  catch {
46
49
  // probably doesn't exist yet
47
50
  }
48
51
  }
49
- if (outfile.endsWith("/")) {
50
- outfile += "schema_gen.ts";
52
+ if (path.endsWith("/")) {
53
+ path += defaultFilename;
51
54
  }
52
- if (!outfile.endsWith(".ts")) {
53
- outfile += ".ts";
55
+ if (!path.endsWith(".ts")) {
56
+ path += ".ts";
54
57
  }
58
+ return path;
59
+ }
60
+ (async () => {
55
61
  switch (ext) {
56
62
  case "keep":
57
63
  case "replace":
@@ -60,7 +66,7 @@ const [schema = "."] = program.args;
60
66
  default:
61
67
  throw new Error(`invalid mode for --ext: ${ext}`);
62
68
  }
63
- await fs.writeFile(outfile, generate(await parse$2(path.resolve(schema)), outfile.pathname, {
69
+ const generator = createGenerator(await parse$2(path.resolve(schema)), {
64
70
  scalarsInfo: scalars ? await parse(scalars) : undefined,
65
71
  fieldDirectivesInfo: fieldDirectives
66
72
  ? await parseTypeResolvers("", fieldDirectives)
@@ -74,9 +80,22 @@ const [schema = "."] = program.args;
74
80
  : undefined,
75
81
  graphqlModuleSpecifier: graphql,
76
82
  extMode: ext,
77
- }));
83
+ includeAstNodes,
84
+ includeSubscriptionFieldResolvers,
85
+ });
86
+ const outfile = await normalizeOutfile(out, "schema_gen.ts");
87
+ if (splitTypesFile || typesOut) {
88
+ const typesfile = await normalizeOutfile(typesOut ?? path.dirname(outfile), "types_gen.ts");
89
+ await Promise.all([
90
+ fs.writeFile(outfile, generator.generateSchema(outfile)),
91
+ fs.writeFile(typesfile, generator.generateTypes(typesfile)),
92
+ ]);
93
+ }
94
+ else {
95
+ await fs.writeFile(outfile, generator.generate(outfile));
96
+ }
78
97
  })().catch((err) => {
79
- console.error(err.message);
98
+ console.error(err.stack);
80
99
  console.log();
81
100
  if (process.argv.length === 2 ||
82
101
  (process.argv.length === 3 && process.argv[2] === "help")) {
package/build/lib.cjs CHANGED
@@ -1,13 +1,13 @@
1
1
  'use strict';
2
2
 
3
- var path = require('path');
4
- var url = require('url');
3
+ var path = require('node:path');
4
+ var node_url = require('node:url');
5
5
  var graphql = require('graphql');
6
6
  var jen = require('jennifer-js');
7
7
  var format = require('jennifer-js/format');
8
8
  var partition = require('just-partition');
9
9
  var pascalCase = require('just-pascal-case');
10
- var fs = require('fs/promises');
10
+ var fs = require('node:fs/promises');
11
11
  var ts = require('typescript');
12
12
  var glob = require('glob');
13
13
  var pm = require('picomatch');
@@ -225,12 +225,12 @@ async function findExports(source, resolveModuleFn = resolveModule) {
225
225
  return exports;
226
226
  }
227
227
  async function parseModule(sourceOrPath) {
228
- const url$1 = typeof sourceOrPath === "string"
229
- ? url.pathToFileURL(path.resolve(sourceOrPath))
228
+ const url = typeof sourceOrPath === "string"
229
+ ? node_url.pathToFileURL(path.resolve(sourceOrPath))
230
230
  : new URL(sourceOrPath.fileName);
231
- const source = typeof sourceOrPath === "string" ? await parseSource(url$1) : sourceOrPath;
231
+ const source = typeof sourceOrPath === "string" ? await parseSource(url) : sourceOrPath;
232
232
  return {
233
- path: url$1,
233
+ path: url,
234
234
  exports: await findExports(source),
235
235
  source,
236
236
  };
@@ -305,7 +305,7 @@ function renderImports(base, imports, aliases, extMode = "omit") {
305
305
  return jen.statements(...imports.map(([pkg, symbols]) => {
306
306
  let mod = pkg;
307
307
  if (mod.startsWith("file:///")) {
308
- mod = url.fileURLToPath(mod);
308
+ mod = node_url.fileURLToPath(mod);
309
309
  }
310
310
  if (mod.startsWith("/")) {
311
311
  mod = path.relative(base, mod);
@@ -340,14 +340,8 @@ function renderAstNode(astNode) {
340
340
  }
341
341
  function isBuiltInDirective(name) {
342
342
  // https://spec.graphql.org/draft/#sec-Type-System.Directives.Built-in-Directives
343
- switch (name) {
344
- case "deprecated":
345
- case "skip":
346
- case "include":
347
- case "specifiedBy":
348
- return true;
349
- }
350
- return false;
343
+ // Use the list from graphql, because new versions add directives (for example, @oneOf).
344
+ return graphql.specifiedDirectives.some((d) => d.name === name);
351
345
  }
352
346
  function truthify(arr) {
353
347
  return arr.filter(Boolean);
@@ -371,7 +365,8 @@ class GeneratorContext {
371
365
  this._graphqlModuleSpecifier = options.graphqlModuleSpecifier ?? "graphql";
372
366
  this._pkgs = new RequiredPackages();
373
367
  this._extMode = options.extMode ?? "omit";
374
- this._includeSubscriptionFieldResolvers = options.includeSubscriptionFieldResolvers ?? false;
368
+ this._includeSubscriptionFieldResolvers =
369
+ options.includeSubscriptionFieldResolvers ?? false;
375
370
  }
376
371
  _gql(name) {
377
372
  return jen.id(this._pkgs.addRequires(this._graphqlModuleSpecifier, name));
@@ -603,7 +598,8 @@ class GeneratorContext {
603
598
  const typeInterfaces = type.getInterfaces();
604
599
  return jen.new
605
600
  .add(this._gql("GraphQLObjectType"))
606
- .call(jen.obj(jen.prop("name", jen.lit(type.name)), jen.prop("fields", this._renderFieldsThunk(type, inputFieldDirectives, includeAstNodes, !this._includeSubscriptionFieldResolvers && type.name === "Subscription")), ...truthify([
601
+ .call(jen.obj(jen.prop("name", jen.lit(type.name)), jen.prop("fields", this._renderFieldsThunk(type, inputFieldDirectives, includeAstNodes, !this._includeSubscriptionFieldResolvers &&
602
+ type.name === "Subscription")), ...truthify([
607
603
  type.description &&
608
604
  jen.prop("description", jen.lit(type.description)),
609
605
  typeInterfaces.length &&
@@ -865,22 +861,22 @@ class GeneratorContext {
865
861
  }
866
862
  _getGraphQLTypeClass(type) {
867
863
  if (type instanceof graphql.GraphQLObjectType) {
868
- return 'GraphQLObjectType';
864
+ return "GraphQLObjectType";
869
865
  }
870
866
  if (type instanceof graphql.GraphQLScalarType) {
871
- return 'GraphQLScalarType';
867
+ return "GraphQLScalarType";
872
868
  }
873
869
  if (type instanceof graphql.GraphQLInterfaceType) {
874
- return 'GraphQLInterfaceType';
870
+ return "GraphQLInterfaceType";
875
871
  }
876
872
  if (type instanceof graphql.GraphQLUnionType) {
877
- return 'GraphQLUnionType';
873
+ return "GraphQLUnionType";
878
874
  }
879
875
  if (type instanceof graphql.GraphQLInputObjectType) {
880
- return 'GraphQLInputObjectType';
876
+ return "GraphQLInputObjectType";
881
877
  }
882
878
  if (type instanceof graphql.GraphQLEnumType) {
883
- return 'GraphQLEnumType';
879
+ return "GraphQLEnumType";
884
880
  }
885
881
  throw new Error(`unhandled type: ${type.toString()}`);
886
882
  }
@@ -1611,6 +1607,9 @@ function setTraceToSchema(err, name, loc) {
1611
1607
  }
1612
1608
  return err;
1613
1609
  }
1610
+ function isMergableDefinitionNode(node) {
1611
+ return graphql.isTypeDefinitionNode(node) || node.kind === graphql.Kind.DIRECTIVE_DEFINITION;
1612
+ }
1614
1613
  function namedNodesDict(nodes = []) {
1615
1614
  return Object.fromEntries(nodes.map((node) => [node.name.value, node]));
1616
1615
  }
@@ -1724,7 +1723,7 @@ function mergeFieldDefinitionNodes(name, a, b) {
1724
1723
  console.warn(`WARNING: there is more than one declaration for ${name}.${f.name.value}${traceLine(f.loc)}${traceLine(prev.loc, "previously ")}\n`);
1725
1724
  fields[f.name.value] = {
1726
1725
  ...prev,
1727
- directives: mergeDirectiveNodes(`${name}.${f.name.value}`, prev.directives, f.directives),
1726
+ directives: mergeDirectiveNodes(prev.directives, f.directives),
1728
1727
  };
1729
1728
  }
1730
1729
  else {
@@ -1749,7 +1748,7 @@ function mergeInputValueDefinitionNodes(name, a, b) {
1749
1748
  console.warn(`WARNING: there is more than one declaration for ${name}.${f.name.value}${traceLine(f.loc)}${traceLine(prev.loc, "previously ")}\n`);
1750
1749
  fields[f.name.value] = {
1751
1750
  ...prev,
1752
- directives: mergeDirectiveNodes(`${name}.${f.name.value}`, prev.directives, f.directives),
1751
+ directives: mergeDirectiveNodes(prev.directives, f.directives),
1753
1752
  };
1754
1753
  }
1755
1754
  else {
@@ -1768,18 +1767,19 @@ function mergeNamedNodes(a, b) {
1768
1767
  }
1769
1768
  return Object.values(nodes);
1770
1769
  }
1771
- function mergeDirectiveNodes(name, a, b) {
1772
- const directives = namedNodesDict(a);
1773
- if (b) {
1774
- for (const d of b) {
1775
- if (d.name.value in directives &&
1776
- !isArgumentNodesEqual(directives[d.name.value].arguments, d.arguments)) {
1777
- throw setTraceToSchema(new graphql.GraphQLError(`Cannot merge duplicate directive with different arguments: ${name} @${d.name.value}`), `${name} @${d.name.value}`, d.loc);
1778
- }
1779
- directives[d.name.value] = d;
1780
- }
1781
- }
1782
- return Object.values(directives);
1770
+ function mergeDirectiveNodes(a, b) {
1771
+ // Keep each occurrence, because a repeatable directive can occur more than
1772
+ // once. Skip only an occurrence that is identical to one that is already
1773
+ // applied. buildASTSchema rejects a non-repeatable directive that occurs
1774
+ // more than once.
1775
+ const directives = Array.from(a ?? []);
1776
+ for (const d of b ?? []) {
1777
+ if (!directives.some((prev) => prev.name.value === d.name.value &&
1778
+ isArgumentNodesEqual(prev.arguments, d.arguments))) {
1779
+ directives.push(d);
1780
+ }
1781
+ }
1782
+ return directives;
1783
1783
  }
1784
1784
  function mergeScalarTypeDefinitionNodes(a, b) {
1785
1785
  if (a.name.value !== b.name.value) {
@@ -1787,8 +1787,10 @@ function mergeScalarTypeDefinitionNodes(a, b) {
1787
1787
  }
1788
1788
  return {
1789
1789
  kind: graphql.Kind.SCALAR_TYPE_DEFINITION,
1790
+ loc: a.loc,
1790
1791
  name: a.name,
1791
- directives: mergeDirectiveNodes(a.name.value, a.directives, b.directives),
1792
+ description: a.description || b.description,
1793
+ directives: mergeDirectiveNodes(a.directives, b.directives),
1792
1794
  };
1793
1795
  }
1794
1796
  function mergeObjectTypeDefinitionNodes(a, b) {
@@ -1798,7 +1800,7 @@ function mergeObjectTypeDefinitionNodes(a, b) {
1798
1800
  name: a.name,
1799
1801
  description: a.description || b.description,
1800
1802
  interfaces: mergeNamedNodes(a.interfaces, b.interfaces),
1801
- directives: mergeDirectiveNodes(a.name.value, a.directives, b.directives),
1803
+ directives: mergeDirectiveNodes(a.directives, b.directives),
1802
1804
  fields: mergeFieldDefinitionNodes(a.name.value, a.fields, b.fields),
1803
1805
  };
1804
1806
  }
@@ -1809,7 +1811,7 @@ function mergeInterfaceTypeDefinitionNodes(a, b) {
1809
1811
  name: a.name,
1810
1812
  description: a.description || b.description,
1811
1813
  interfaces: mergeNamedNodes(a.interfaces, b.interfaces),
1812
- directives: mergeDirectiveNodes(a.name.value, a.directives, b.directives),
1814
+ directives: mergeDirectiveNodes(a.directives, b.directives),
1813
1815
  fields: mergeFieldDefinitionNodes(a.name.value, a.fields, b.fields),
1814
1816
  };
1815
1817
  }
@@ -1819,7 +1821,7 @@ function mergeUnionTypeDefinitionNodes(a, b) {
1819
1821
  loc: a.loc,
1820
1822
  name: a.name,
1821
1823
  description: a.description || b.description,
1822
- directives: mergeDirectiveNodes(a.name.value, a.directives, b.directives),
1824
+ directives: mergeDirectiveNodes(a.directives, b.directives),
1823
1825
  types: mergeNamedNodes(a.types, b.types),
1824
1826
  };
1825
1827
  }
@@ -1828,7 +1830,7 @@ function mergeEnumTypeDefinitionNodes(a, b) {
1828
1830
  if (b) {
1829
1831
  for (const v of b.values || []) {
1830
1832
  if (v.name.value in values) {
1831
- throw setTraceToSchema(new graphql.GraphQLError(`Cannot merge duplicate enum value: ${v.name.value}.${v.name.value}`), `${v.name.value}.${v.name.value}`, v.loc);
1833
+ throw setTraceToSchema(new graphql.GraphQLError(`Cannot merge duplicate enum value: ${a.name.value}.${v.name.value}`), `${a.name.value}.${v.name.value}`, v.loc);
1832
1834
  }
1833
1835
  values[v.name.value] = v;
1834
1836
  }
@@ -1838,7 +1840,7 @@ function mergeEnumTypeDefinitionNodes(a, b) {
1838
1840
  loc: a.loc,
1839
1841
  name: a.name,
1840
1842
  description: a.description || b.description,
1841
- directives: mergeDirectiveNodes(a.name.value, a.directives, b.directives),
1843
+ directives: mergeDirectiveNodes(a.directives, b.directives),
1842
1844
  values: Object.values(values),
1843
1845
  };
1844
1846
  }
@@ -1848,26 +1850,74 @@ function mergeInputObjectTypeDefinitionNodes(a, b) {
1848
1850
  loc: a.loc,
1849
1851
  name: a.name,
1850
1852
  description: a.description || b.description,
1851
- directives: mergeDirectiveNodes(a.name.value, a.directives, b.directives),
1853
+ directives: mergeDirectiveNodes(a.directives, b.directives),
1852
1854
  fields: mergeInputValueDefinitionNodes(a.name.value, a.fields, b.fields),
1853
1855
  };
1854
1856
  }
1857
+ const EXTENSION_DEFINITION_KINDS = {
1858
+ [graphql.Kind.SCALAR_TYPE_EXTENSION]: graphql.Kind.SCALAR_TYPE_DEFINITION,
1859
+ [graphql.Kind.OBJECT_TYPE_EXTENSION]: graphql.Kind.OBJECT_TYPE_DEFINITION,
1860
+ [graphql.Kind.INTERFACE_TYPE_EXTENSION]: graphql.Kind.INTERFACE_TYPE_DEFINITION,
1861
+ [graphql.Kind.UNION_TYPE_EXTENSION]: graphql.Kind.UNION_TYPE_DEFINITION,
1862
+ [graphql.Kind.ENUM_TYPE_EXTENSION]: graphql.Kind.ENUM_TYPE_DEFINITION,
1863
+ [graphql.Kind.INPUT_OBJECT_TYPE_EXTENSION]: graphql.Kind.INPUT_OBJECT_TYPE_DEFINITION,
1864
+ };
1865
+ function mergeTypeDefinitionNodes(a, b) {
1866
+ switch (b.kind) {
1867
+ case graphql.Kind.SCALAR_TYPE_DEFINITION:
1868
+ return mergeScalarTypeDefinitionNodes(a, b);
1869
+ case graphql.Kind.OBJECT_TYPE_DEFINITION:
1870
+ return mergeObjectTypeDefinitionNodes(a, b);
1871
+ case graphql.Kind.INTERFACE_TYPE_DEFINITION:
1872
+ return mergeInterfaceTypeDefinitionNodes(a, b);
1873
+ case graphql.Kind.UNION_TYPE_DEFINITION:
1874
+ return mergeUnionTypeDefinitionNodes(a, b);
1875
+ case graphql.Kind.ENUM_TYPE_DEFINITION:
1876
+ return mergeEnumTypeDefinitionNodes(a, b);
1877
+ case graphql.Kind.INPUT_OBJECT_TYPE_DEFINITION:
1878
+ return mergeInputObjectTypeDefinitionNodes(a, b);
1879
+ }
1880
+ }
1881
+ function applyTypeExtensionNode(definitions, extension) {
1882
+ const name = extension.name.value;
1883
+ const definition = definitions[name];
1884
+ if (!definition) {
1885
+ throw setTraceToSchema(new graphql.GraphQLError(`Cannot extend type that is not defined: ${name}`), name, extension.loc);
1886
+ }
1887
+ const kind = EXTENSION_DEFINITION_KINDS[extension.kind];
1888
+ if (definition.kind !== kind) {
1889
+ throw setTraceToSchema(new graphql.GraphQLError(`Cannot extend ${definition.kind} with ${extension.kind}: ${name}`), name, extension.loc);
1890
+ }
1891
+ // An extension has the same shape as its definition, without a description.
1892
+ const merged = mergeTypeDefinitionNodes(definition, {
1893
+ ...extension,
1894
+ kind,
1895
+ directives: undefined,
1896
+ });
1897
+ // The directives of an extension are added to the directives of the type.
1898
+ // buildASTSchema rejects a non-repeatable directive that occurs more than
1899
+ // once.
1900
+ definitions[name] = {
1901
+ ...merged,
1902
+ directives: [
1903
+ ...(definition.directives ?? []),
1904
+ ...(extension.directives ?? []),
1905
+ ],
1906
+ };
1907
+ }
1855
1908
  function mergeDocumentNodes(documentNodes) {
1856
1909
  const definitions = {};
1910
+ const extensions = [];
1857
1911
  for (const documentNode of documentNodes) {
1858
1912
  for (const definition of documentNode.definitions) {
1859
- switch (definition.kind) {
1860
- case graphql.Kind.SCHEMA_DEFINITION:
1861
- case graphql.Kind.SCHEMA_EXTENSION:
1862
- case graphql.Kind.OPERATION_DEFINITION:
1863
- case graphql.Kind.FRAGMENT_DEFINITION:
1864
- case graphql.Kind.SCALAR_TYPE_EXTENSION:
1865
- case graphql.Kind.OBJECT_TYPE_EXTENSION:
1866
- case graphql.Kind.INTERFACE_TYPE_EXTENSION:
1867
- case graphql.Kind.UNION_TYPE_EXTENSION:
1868
- case graphql.Kind.ENUM_TYPE_EXTENSION:
1869
- case graphql.Kind.INPUT_OBJECT_TYPE_EXTENSION:
1870
- throw new Error(`unexpected definition kind: ${definition.kind}`);
1913
+ if (graphql.isTypeExtensionNode(definition)) {
1914
+ // Apply extensions after all definitions are known, because an
1915
+ // extension can occur before the definition that it extends.
1916
+ extensions.push(definition);
1917
+ continue;
1918
+ }
1919
+ if (!isMergableDefinitionNode(definition)) {
1920
+ throw new Error(`unexpected definition kind: ${definition.kind}`);
1871
1921
  }
1872
1922
  const prevDefinition = definitions[definition.name.value];
1873
1923
  if (!prevDefinition) {
@@ -1885,30 +1935,12 @@ function mergeDocumentNodes(documentNodes) {
1885
1935
  prevDefinition.description.value !== definition.description.value) {
1886
1936
  console.warn(`WARNING: different descriptions for type ${prevDefinition.name.value}: ${JSON.stringify(prevDefinition.description.value)} and ${JSON.stringify(definition.description.value)}${traceLine(definition.description.loc)}${traceLine(prevDefinition.description.loc, "previously ")}\n`);
1887
1937
  }
1888
- switch (definition.kind) {
1889
- case graphql.Kind.SCALAR_TYPE_DEFINITION:
1890
- definitions[definition.name.value] = mergeScalarTypeDefinitionNodes(prevDefinition, definition);
1891
- break;
1892
- case graphql.Kind.OBJECT_TYPE_DEFINITION:
1893
- definitions[definition.name.value] = mergeObjectTypeDefinitionNodes(prevDefinition, definition);
1894
- break;
1895
- case graphql.Kind.INTERFACE_TYPE_DEFINITION:
1896
- definitions[definition.name.value] =
1897
- mergeInterfaceTypeDefinitionNodes(prevDefinition, definition);
1898
- break;
1899
- case graphql.Kind.UNION_TYPE_DEFINITION:
1900
- definitions[definition.name.value] = mergeUnionTypeDefinitionNodes(prevDefinition, definition);
1901
- break;
1902
- case graphql.Kind.ENUM_TYPE_DEFINITION:
1903
- definitions[definition.name.value] = mergeEnumTypeDefinitionNodes(prevDefinition, definition);
1904
- break;
1905
- case graphql.Kind.INPUT_OBJECT_TYPE_DEFINITION:
1906
- definitions[definition.name.value] =
1907
- mergeInputObjectTypeDefinitionNodes(prevDefinition, definition);
1908
- break;
1909
- }
1938
+ definitions[definition.name.value] = mergeTypeDefinitionNodes(prevDefinition, definition);
1910
1939
  }
1911
1940
  }
1941
+ for (const extension of extensions) {
1942
+ applyTypeExtensionNode(definitions, extension);
1943
+ }
1912
1944
  return {
1913
1945
  kind: graphql.Kind.DOCUMENT,
1914
1946
  loc: documentNodes[0].loc,
package/build/lib.mjs CHANGED
@@ -1,11 +1,11 @@
1
- import path, { resolve, basename, extname, join } from 'path';
2
- import { pathToFileURL, fileURLToPath } from 'url';
3
- import { GraphQLNonNull, GraphQLList, GraphQLScalarType, GraphQLEnumType, GraphQLDirective, Kind, GraphQLObjectType, getNamedType, getNullableType, GraphQLInterfaceType, GraphQLUnionType, GraphQLInputObjectType, DirectiveLocation, GraphQLError, parse as parse$3, Source, buildASTSchema, validateSchema } from 'graphql';
1
+ import path, { resolve, basename, extname, join } from 'node:path';
2
+ import { pathToFileURL, fileURLToPath } from 'node:url';
3
+ import { GraphQLNonNull, GraphQLList, GraphQLScalarType, GraphQLEnumType, GraphQLDirective, Kind, GraphQLObjectType, getNamedType, getNullableType, GraphQLInterfaceType, GraphQLUnionType, GraphQLInputObjectType, DirectiveLocation, specifiedDirectives, isTypeExtensionNode, GraphQLError, isTypeDefinitionNode, parse as parse$3, Source, buildASTSchema, validateSchema } from 'graphql';
4
4
  import jen$1, { jen } from 'jennifer-js';
5
5
  import format from 'jennifer-js/format';
6
6
  import partition from 'just-partition';
7
7
  import pascalCase from 'just-pascal-case';
8
- import fs from 'fs/promises';
8
+ import fs from 'node:fs/promises';
9
9
  import ts, { getLineAndCharacterOfPosition } from 'typescript';
10
10
  import { globIterate } from 'glob';
11
11
  import pm from 'picomatch';
@@ -338,14 +338,8 @@ function renderAstNode(astNode) {
338
338
  }
339
339
  function isBuiltInDirective(name) {
340
340
  // https://spec.graphql.org/draft/#sec-Type-System.Directives.Built-in-Directives
341
- switch (name) {
342
- case "deprecated":
343
- case "skip":
344
- case "include":
345
- case "specifiedBy":
346
- return true;
347
- }
348
- return false;
341
+ // Use the list from graphql, because new versions add directives (for example, @oneOf).
342
+ return specifiedDirectives.some((d) => d.name === name);
349
343
  }
350
344
  function truthify(arr) {
351
345
  return arr.filter(Boolean);
@@ -369,7 +363,8 @@ class GeneratorContext {
369
363
  this._graphqlModuleSpecifier = options.graphqlModuleSpecifier ?? "graphql";
370
364
  this._pkgs = new RequiredPackages();
371
365
  this._extMode = options.extMode ?? "omit";
372
- this._includeSubscriptionFieldResolvers = options.includeSubscriptionFieldResolvers ?? false;
366
+ this._includeSubscriptionFieldResolvers =
367
+ options.includeSubscriptionFieldResolvers ?? false;
373
368
  }
374
369
  _gql(name) {
375
370
  return jen$1.id(this._pkgs.addRequires(this._graphqlModuleSpecifier, name));
@@ -601,7 +596,8 @@ class GeneratorContext {
601
596
  const typeInterfaces = type.getInterfaces();
602
597
  return jen$1.new
603
598
  .add(this._gql("GraphQLObjectType"))
604
- .call(jen$1.obj(jen$1.prop("name", jen$1.lit(type.name)), jen$1.prop("fields", this._renderFieldsThunk(type, inputFieldDirectives, includeAstNodes, !this._includeSubscriptionFieldResolvers && type.name === "Subscription")), ...truthify([
599
+ .call(jen$1.obj(jen$1.prop("name", jen$1.lit(type.name)), jen$1.prop("fields", this._renderFieldsThunk(type, inputFieldDirectives, includeAstNodes, !this._includeSubscriptionFieldResolvers &&
600
+ type.name === "Subscription")), ...truthify([
605
601
  type.description &&
606
602
  jen$1.prop("description", jen$1.lit(type.description)),
607
603
  typeInterfaces.length &&
@@ -863,22 +859,22 @@ class GeneratorContext {
863
859
  }
864
860
  _getGraphQLTypeClass(type) {
865
861
  if (type instanceof GraphQLObjectType) {
866
- return 'GraphQLObjectType';
862
+ return "GraphQLObjectType";
867
863
  }
868
864
  if (type instanceof GraphQLScalarType) {
869
- return 'GraphQLScalarType';
865
+ return "GraphQLScalarType";
870
866
  }
871
867
  if (type instanceof GraphQLInterfaceType) {
872
- return 'GraphQLInterfaceType';
868
+ return "GraphQLInterfaceType";
873
869
  }
874
870
  if (type instanceof GraphQLUnionType) {
875
- return 'GraphQLUnionType';
871
+ return "GraphQLUnionType";
876
872
  }
877
873
  if (type instanceof GraphQLInputObjectType) {
878
- return 'GraphQLInputObjectType';
874
+ return "GraphQLInputObjectType";
879
875
  }
880
876
  if (type instanceof GraphQLEnumType) {
881
- return 'GraphQLEnumType';
877
+ return "GraphQLEnumType";
882
878
  }
883
879
  throw new Error(`unhandled type: ${type.toString()}`);
884
880
  }
@@ -1609,6 +1605,9 @@ function setTraceToSchema(err, name, loc) {
1609
1605
  }
1610
1606
  return err;
1611
1607
  }
1608
+ function isMergableDefinitionNode(node) {
1609
+ return isTypeDefinitionNode(node) || node.kind === Kind.DIRECTIVE_DEFINITION;
1610
+ }
1612
1611
  function namedNodesDict(nodes = []) {
1613
1612
  return Object.fromEntries(nodes.map((node) => [node.name.value, node]));
1614
1613
  }
@@ -1722,7 +1721,7 @@ function mergeFieldDefinitionNodes(name, a, b) {
1722
1721
  console.warn(`WARNING: there is more than one declaration for ${name}.${f.name.value}${traceLine(f.loc)}${traceLine(prev.loc, "previously ")}\n`);
1723
1722
  fields[f.name.value] = {
1724
1723
  ...prev,
1725
- directives: mergeDirectiveNodes(`${name}.${f.name.value}`, prev.directives, f.directives),
1724
+ directives: mergeDirectiveNodes(prev.directives, f.directives),
1726
1725
  };
1727
1726
  }
1728
1727
  else {
@@ -1747,7 +1746,7 @@ function mergeInputValueDefinitionNodes(name, a, b) {
1747
1746
  console.warn(`WARNING: there is more than one declaration for ${name}.${f.name.value}${traceLine(f.loc)}${traceLine(prev.loc, "previously ")}\n`);
1748
1747
  fields[f.name.value] = {
1749
1748
  ...prev,
1750
- directives: mergeDirectiveNodes(`${name}.${f.name.value}`, prev.directives, f.directives),
1749
+ directives: mergeDirectiveNodes(prev.directives, f.directives),
1751
1750
  };
1752
1751
  }
1753
1752
  else {
@@ -1766,18 +1765,19 @@ function mergeNamedNodes(a, b) {
1766
1765
  }
1767
1766
  return Object.values(nodes);
1768
1767
  }
1769
- function mergeDirectiveNodes(name, a, b) {
1770
- const directives = namedNodesDict(a);
1771
- if (b) {
1772
- for (const d of b) {
1773
- if (d.name.value in directives &&
1774
- !isArgumentNodesEqual(directives[d.name.value].arguments, d.arguments)) {
1775
- throw setTraceToSchema(new GraphQLError(`Cannot merge duplicate directive with different arguments: ${name} @${d.name.value}`), `${name} @${d.name.value}`, d.loc);
1776
- }
1777
- directives[d.name.value] = d;
1778
- }
1779
- }
1780
- return Object.values(directives);
1768
+ function mergeDirectiveNodes(a, b) {
1769
+ // Keep each occurrence, because a repeatable directive can occur more than
1770
+ // once. Skip only an occurrence that is identical to one that is already
1771
+ // applied. buildASTSchema rejects a non-repeatable directive that occurs
1772
+ // more than once.
1773
+ const directives = Array.from(a ?? []);
1774
+ for (const d of b ?? []) {
1775
+ if (!directives.some((prev) => prev.name.value === d.name.value &&
1776
+ isArgumentNodesEqual(prev.arguments, d.arguments))) {
1777
+ directives.push(d);
1778
+ }
1779
+ }
1780
+ return directives;
1781
1781
  }
1782
1782
  function mergeScalarTypeDefinitionNodes(a, b) {
1783
1783
  if (a.name.value !== b.name.value) {
@@ -1785,8 +1785,10 @@ function mergeScalarTypeDefinitionNodes(a, b) {
1785
1785
  }
1786
1786
  return {
1787
1787
  kind: Kind.SCALAR_TYPE_DEFINITION,
1788
+ loc: a.loc,
1788
1789
  name: a.name,
1789
- directives: mergeDirectiveNodes(a.name.value, a.directives, b.directives),
1790
+ description: a.description || b.description,
1791
+ directives: mergeDirectiveNodes(a.directives, b.directives),
1790
1792
  };
1791
1793
  }
1792
1794
  function mergeObjectTypeDefinitionNodes(a, b) {
@@ -1796,7 +1798,7 @@ function mergeObjectTypeDefinitionNodes(a, b) {
1796
1798
  name: a.name,
1797
1799
  description: a.description || b.description,
1798
1800
  interfaces: mergeNamedNodes(a.interfaces, b.interfaces),
1799
- directives: mergeDirectiveNodes(a.name.value, a.directives, b.directives),
1801
+ directives: mergeDirectiveNodes(a.directives, b.directives),
1800
1802
  fields: mergeFieldDefinitionNodes(a.name.value, a.fields, b.fields),
1801
1803
  };
1802
1804
  }
@@ -1807,7 +1809,7 @@ function mergeInterfaceTypeDefinitionNodes(a, b) {
1807
1809
  name: a.name,
1808
1810
  description: a.description || b.description,
1809
1811
  interfaces: mergeNamedNodes(a.interfaces, b.interfaces),
1810
- directives: mergeDirectiveNodes(a.name.value, a.directives, b.directives),
1812
+ directives: mergeDirectiveNodes(a.directives, b.directives),
1811
1813
  fields: mergeFieldDefinitionNodes(a.name.value, a.fields, b.fields),
1812
1814
  };
1813
1815
  }
@@ -1817,7 +1819,7 @@ function mergeUnionTypeDefinitionNodes(a, b) {
1817
1819
  loc: a.loc,
1818
1820
  name: a.name,
1819
1821
  description: a.description || b.description,
1820
- directives: mergeDirectiveNodes(a.name.value, a.directives, b.directives),
1822
+ directives: mergeDirectiveNodes(a.directives, b.directives),
1821
1823
  types: mergeNamedNodes(a.types, b.types),
1822
1824
  };
1823
1825
  }
@@ -1826,7 +1828,7 @@ function mergeEnumTypeDefinitionNodes(a, b) {
1826
1828
  if (b) {
1827
1829
  for (const v of b.values || []) {
1828
1830
  if (v.name.value in values) {
1829
- throw setTraceToSchema(new GraphQLError(`Cannot merge duplicate enum value: ${v.name.value}.${v.name.value}`), `${v.name.value}.${v.name.value}`, v.loc);
1831
+ throw setTraceToSchema(new GraphQLError(`Cannot merge duplicate enum value: ${a.name.value}.${v.name.value}`), `${a.name.value}.${v.name.value}`, v.loc);
1830
1832
  }
1831
1833
  values[v.name.value] = v;
1832
1834
  }
@@ -1836,7 +1838,7 @@ function mergeEnumTypeDefinitionNodes(a, b) {
1836
1838
  loc: a.loc,
1837
1839
  name: a.name,
1838
1840
  description: a.description || b.description,
1839
- directives: mergeDirectiveNodes(a.name.value, a.directives, b.directives),
1841
+ directives: mergeDirectiveNodes(a.directives, b.directives),
1840
1842
  values: Object.values(values),
1841
1843
  };
1842
1844
  }
@@ -1846,26 +1848,74 @@ function mergeInputObjectTypeDefinitionNodes(a, b) {
1846
1848
  loc: a.loc,
1847
1849
  name: a.name,
1848
1850
  description: a.description || b.description,
1849
- directives: mergeDirectiveNodes(a.name.value, a.directives, b.directives),
1851
+ directives: mergeDirectiveNodes(a.directives, b.directives),
1850
1852
  fields: mergeInputValueDefinitionNodes(a.name.value, a.fields, b.fields),
1851
1853
  };
1852
1854
  }
1855
+ const EXTENSION_DEFINITION_KINDS = {
1856
+ [Kind.SCALAR_TYPE_EXTENSION]: Kind.SCALAR_TYPE_DEFINITION,
1857
+ [Kind.OBJECT_TYPE_EXTENSION]: Kind.OBJECT_TYPE_DEFINITION,
1858
+ [Kind.INTERFACE_TYPE_EXTENSION]: Kind.INTERFACE_TYPE_DEFINITION,
1859
+ [Kind.UNION_TYPE_EXTENSION]: Kind.UNION_TYPE_DEFINITION,
1860
+ [Kind.ENUM_TYPE_EXTENSION]: Kind.ENUM_TYPE_DEFINITION,
1861
+ [Kind.INPUT_OBJECT_TYPE_EXTENSION]: Kind.INPUT_OBJECT_TYPE_DEFINITION,
1862
+ };
1863
+ function mergeTypeDefinitionNodes(a, b) {
1864
+ switch (b.kind) {
1865
+ case Kind.SCALAR_TYPE_DEFINITION:
1866
+ return mergeScalarTypeDefinitionNodes(a, b);
1867
+ case Kind.OBJECT_TYPE_DEFINITION:
1868
+ return mergeObjectTypeDefinitionNodes(a, b);
1869
+ case Kind.INTERFACE_TYPE_DEFINITION:
1870
+ return mergeInterfaceTypeDefinitionNodes(a, b);
1871
+ case Kind.UNION_TYPE_DEFINITION:
1872
+ return mergeUnionTypeDefinitionNodes(a, b);
1873
+ case Kind.ENUM_TYPE_DEFINITION:
1874
+ return mergeEnumTypeDefinitionNodes(a, b);
1875
+ case Kind.INPUT_OBJECT_TYPE_DEFINITION:
1876
+ return mergeInputObjectTypeDefinitionNodes(a, b);
1877
+ }
1878
+ }
1879
+ function applyTypeExtensionNode(definitions, extension) {
1880
+ const name = extension.name.value;
1881
+ const definition = definitions[name];
1882
+ if (!definition) {
1883
+ throw setTraceToSchema(new GraphQLError(`Cannot extend type that is not defined: ${name}`), name, extension.loc);
1884
+ }
1885
+ const kind = EXTENSION_DEFINITION_KINDS[extension.kind];
1886
+ if (definition.kind !== kind) {
1887
+ throw setTraceToSchema(new GraphQLError(`Cannot extend ${definition.kind} with ${extension.kind}: ${name}`), name, extension.loc);
1888
+ }
1889
+ // An extension has the same shape as its definition, without a description.
1890
+ const merged = mergeTypeDefinitionNodes(definition, {
1891
+ ...extension,
1892
+ kind,
1893
+ directives: undefined,
1894
+ });
1895
+ // The directives of an extension are added to the directives of the type.
1896
+ // buildASTSchema rejects a non-repeatable directive that occurs more than
1897
+ // once.
1898
+ definitions[name] = {
1899
+ ...merged,
1900
+ directives: [
1901
+ ...(definition.directives ?? []),
1902
+ ...(extension.directives ?? []),
1903
+ ],
1904
+ };
1905
+ }
1853
1906
  function mergeDocumentNodes(documentNodes) {
1854
1907
  const definitions = {};
1908
+ const extensions = [];
1855
1909
  for (const documentNode of documentNodes) {
1856
1910
  for (const definition of documentNode.definitions) {
1857
- switch (definition.kind) {
1858
- case Kind.SCHEMA_DEFINITION:
1859
- case Kind.SCHEMA_EXTENSION:
1860
- case Kind.OPERATION_DEFINITION:
1861
- case Kind.FRAGMENT_DEFINITION:
1862
- case Kind.SCALAR_TYPE_EXTENSION:
1863
- case Kind.OBJECT_TYPE_EXTENSION:
1864
- case Kind.INTERFACE_TYPE_EXTENSION:
1865
- case Kind.UNION_TYPE_EXTENSION:
1866
- case Kind.ENUM_TYPE_EXTENSION:
1867
- case Kind.INPUT_OBJECT_TYPE_EXTENSION:
1868
- throw new Error(`unexpected definition kind: ${definition.kind}`);
1911
+ if (isTypeExtensionNode(definition)) {
1912
+ // Apply extensions after all definitions are known, because an
1913
+ // extension can occur before the definition that it extends.
1914
+ extensions.push(definition);
1915
+ continue;
1916
+ }
1917
+ if (!isMergableDefinitionNode(definition)) {
1918
+ throw new Error(`unexpected definition kind: ${definition.kind}`);
1869
1919
  }
1870
1920
  const prevDefinition = definitions[definition.name.value];
1871
1921
  if (!prevDefinition) {
@@ -1883,30 +1933,12 @@ function mergeDocumentNodes(documentNodes) {
1883
1933
  prevDefinition.description.value !== definition.description.value) {
1884
1934
  console.warn(`WARNING: different descriptions for type ${prevDefinition.name.value}: ${JSON.stringify(prevDefinition.description.value)} and ${JSON.stringify(definition.description.value)}${traceLine(definition.description.loc)}${traceLine(prevDefinition.description.loc, "previously ")}\n`);
1885
1935
  }
1886
- switch (definition.kind) {
1887
- case Kind.SCALAR_TYPE_DEFINITION:
1888
- definitions[definition.name.value] = mergeScalarTypeDefinitionNodes(prevDefinition, definition);
1889
- break;
1890
- case Kind.OBJECT_TYPE_DEFINITION:
1891
- definitions[definition.name.value] = mergeObjectTypeDefinitionNodes(prevDefinition, definition);
1892
- break;
1893
- case Kind.INTERFACE_TYPE_DEFINITION:
1894
- definitions[definition.name.value] =
1895
- mergeInterfaceTypeDefinitionNodes(prevDefinition, definition);
1896
- break;
1897
- case Kind.UNION_TYPE_DEFINITION:
1898
- definitions[definition.name.value] = mergeUnionTypeDefinitionNodes(prevDefinition, definition);
1899
- break;
1900
- case Kind.ENUM_TYPE_DEFINITION:
1901
- definitions[definition.name.value] = mergeEnumTypeDefinitionNodes(prevDefinition, definition);
1902
- break;
1903
- case Kind.INPUT_OBJECT_TYPE_DEFINITION:
1904
- definitions[definition.name.value] =
1905
- mergeInputObjectTypeDefinitionNodes(prevDefinition, definition);
1906
- break;
1907
- }
1936
+ definitions[definition.name.value] = mergeTypeDefinitionNodes(prevDefinition, definition);
1908
1937
  }
1909
1938
  }
1939
+ for (const extension of extensions) {
1940
+ applyTypeExtensionNode(definitions, extension);
1941
+ }
1910
1942
  return {
1911
1943
  kind: Kind.DOCUMENT,
1912
1944
  loc: documentNodes[0].loc,
package/package.json CHANGED
@@ -1,38 +1,38 @@
1
1
  {
2
- "name": "graphql-jerky",
3
- "version": "1.0.7",
4
- "description": "Jerky is a schema-first static graphql schema lightweight code generator.",
5
- "type": "module",
6
- "bin": "./build/bin/jerky.cjs",
7
- "types": "./build/lib.d.ts",
8
- "module": "./build/lib.mjs",
9
- "main": "./build/lib.cjs",
10
- "scripts": {
11
- "build": "rollup -c",
12
- "prepack": "npm run build"
13
- },
14
- "dependencies": {
15
- "commander": "^10.0.1",
16
- "glob": "^10.2.7",
17
- "graphql": "^16.6.0",
18
- "jennifer-js": "^1.0.0",
19
- "just-partition": "^2.2.0",
20
- "just-pascal-case": "^3.2.0",
21
- "just-zip-it": "^3.2.0",
22
- "picomatch": "^2.3.1",
23
- "typescript": "^5.1.3"
24
- },
25
- "devDependencies": {
26
- "@biomejs/biome": "^1.4.1",
27
- "@rollup/plugin-typescript": "^11.1.1",
28
- "@types/node": "^20.3.1",
29
- "@types/picomatch": "^2.3.0",
30
- "rollup": "^3.25.1",
31
- "rollup-plugin-dts": "^5.3.0",
32
- "tslib": "^2.5.3"
33
- },
34
- "files": [
35
- "build"
36
- ],
37
- "license": "MIT"
2
+ "name": "graphql-jerky",
3
+ "version": "1.0.9",
4
+ "description": "Jerky is a schema-first static graphql schema lightweight code generator.",
5
+ "type": "module",
6
+ "bin": "./build/bin/jerky.cjs",
7
+ "types": "./build/lib.d.ts",
8
+ "module": "./build/lib.mjs",
9
+ "main": "./build/lib.cjs",
10
+ "scripts": {
11
+ "build": "rollup -c",
12
+ "prepack": "npm run build"
13
+ },
14
+ "dependencies": {
15
+ "commander": "^10.0.1",
16
+ "glob": "^10.2.7",
17
+ "graphql": "^16.6.0",
18
+ "jennifer-js": "^1.0.0",
19
+ "just-partition": "^2.2.0",
20
+ "just-pascal-case": "^3.2.0",
21
+ "just-zip-it": "^3.2.0",
22
+ "picomatch": "^2.3.1",
23
+ "typescript": "^5.1.3"
24
+ },
25
+ "devDependencies": {
26
+ "@biomejs/biome": "^1.4.1",
27
+ "@rollup/plugin-typescript": "^11.1.1",
28
+ "@types/node": "^20.3.1",
29
+ "@types/picomatch": "^2.3.0",
30
+ "rollup": "^3.25.1",
31
+ "rollup-plugin-dts": "^5.3.0",
32
+ "tslib": "^2.5.3"
33
+ },
34
+ "files": [
35
+ "build"
36
+ ],
37
+ "license": "MIT"
38
38
  }