graphile-export 0.0.2-beta.3 → 0.0.2-beta.30

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.
@@ -1,15 +1,23 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.exportSchema = exports.exportSchemaAsString = exports.objectNullPrototype = exports.isNotNullish = exports.canRepresentAsIdentifier = void 0;
3
+ exports.canRepresentAsIdentifier = void 0;
4
+ exports.objectNullPrototype = objectNullPrototype;
5
+ exports.exportSchemaAsString = exportSchemaAsString;
6
+ exports.exportValueAsString = exportValueAsString;
7
+ exports.exportSchema = exportSchema;
4
8
  const tslib_1 = require("tslib");
5
9
  const promises_1 = require("node:fs/promises");
6
10
  const node_util_1 = require("node:util");
7
11
  const generator_1 = tslib_1.__importDefault(require("@babel/generator"));
8
12
  const parser_1 = require("@babel/parser");
9
13
  const template_1 = tslib_1.__importDefault(require("@babel/template"));
14
+ const traverse_1 = tslib_1.__importDefault(require("@babel/traverse"));
10
15
  const t = tslib_1.__importStar(require("@babel/types"));
11
16
  const graphql_1 = require("grafast/graphql");
17
+ const helpers_js_1 = require("./helpers.js");
12
18
  const index_js_1 = require("./optimize/index.js");
19
+ const reservedWords_js_1 = require("./reservedWords.js");
20
+ const utils_js_1 = require("./utils.js");
13
21
  const wellKnown_js_1 = require("./wellKnown.js");
14
22
  // Cannot import sql because it's optional
15
23
  // import { sql } from "pg-sql2";
@@ -27,7 +35,7 @@ function isSQL(thing) {
27
35
  else {
28
36
  // An approximation
29
37
  if (typeof sql === "object" && sql !== null) {
30
- return Object.getOwnPropertySymbols(thing).some((s) => s.description === "pg-sql2-type");
38
+ return Object.getOwnPropertySymbols(thing).some((s) => s.description?.startsWith("pg-sql2-type"));
31
39
  }
32
40
  else {
33
41
  return false;
@@ -48,6 +56,14 @@ function identifierOrLiteral(key) {
48
56
  return t.stringLiteral(key);
49
57
  }
50
58
  }
59
+ function literal(key) {
60
+ if (typeof key === "number") {
61
+ return t.numericLiteral(key);
62
+ }
63
+ else {
64
+ return t.stringLiteral(key);
65
+ }
66
+ }
51
67
  function locationHintToIdentifierName(locationHint) {
52
68
  let result = locationHint;
53
69
  result = result.replace(/[[.]/g, "__").replace(/\]/g, "");
@@ -59,7 +75,10 @@ function locationHintToIdentifierName(locationHint) {
59
75
  return result;
60
76
  }
61
77
  function getNameForThing(thing, locationHint, baseNameHint) {
62
- if (typeof thing === "function") {
78
+ if (thing.$exporter$name) {
79
+ return thing.$exporter$name;
80
+ }
81
+ else if (typeof thing === "function") {
63
82
  if (baseNameHint) {
64
83
  return baseNameHint;
65
84
  }
@@ -71,14 +90,17 @@ function getNameForThing(thing, locationHint, baseNameHint) {
71
90
  }
72
91
  else {
73
92
  const thingConstructor = thing.constructor;
74
- const thingConstructorNameRaw = thingConstructor?.name ?? thingConstructor?.displayName ?? null;
93
+ const thingConstructorNameRaw = thingConstructor?.$exporter$name ??
94
+ thingConstructor?.name ??
95
+ thingConstructor?.displayName ??
96
+ null;
75
97
  const thingConstructorName = ["Array", "Object", "Set", "Map"].includes(thingConstructorNameRaw)
76
98
  ? null
77
99
  : thingConstructorNameRaw;
78
100
  const thingName = thing.name ?? thing.displayName ?? null;
79
101
  const name = thingConstructorName && thingName
80
102
  ? `${thingName}${thingConstructorName}`
81
- : thingName ?? thingConstructorName ?? null;
103
+ : (thingName ?? thingConstructorName ?? null);
82
104
  return baseNameHint || name
83
105
  ? (baseNameHint ?? "") + (baseNameHint && name ? "-" : "") + (name ?? "")
84
106
  : "value";
@@ -102,15 +124,6 @@ const reallyGenerate = generator_1.default;
102
124
  const templateOptions = {
103
125
  plugins: ["typescript"],
104
126
  };
105
- function isNotNullish(input) {
106
- return input != null;
107
- }
108
- exports.isNotNullish = isNotNullish;
109
- function isImportable(thing) {
110
- return ((typeof thing === "object" || typeof thing === "function") &&
111
- thing !== null &&
112
- "$$export" in thing);
113
- }
114
127
  function isExportedFromFactory(thing) {
115
128
  return ((typeof thing === "object" || typeof thing === "function") &&
116
129
  thing !== null &&
@@ -120,54 +133,60 @@ const BUILTINS = ["Int", "Float", "Boolean", "ID", "String"];
120
133
  function isBuiltinType(type) {
121
134
  return type.name.startsWith("__") || BUILTINS.includes(type.name);
122
135
  }
136
+ const RESERVED_VARIABLES = {
137
+ // Reserved variables
138
+ AbortController: true,
139
+ Array: true,
140
+ Buffer: true,
141
+ DOMException: true,
142
+ Error: true,
143
+ Event: true,
144
+ EventTarget: true,
145
+ JSON: true,
146
+ Math: true,
147
+ MessageChannel: true,
148
+ MessageEvent: true,
149
+ MessagePort: true,
150
+ Object: true,
151
+ TextDecoder: true,
152
+ TextEncoder: true,
153
+ URL: true,
154
+ URLSearchParams: true,
155
+ WebAssembly: true,
156
+ __dirname: true,
157
+ __filename: true,
158
+ atob: true,
159
+ btoa: true,
160
+ clearImmediate: true,
161
+ clearInterval: true,
162
+ clearTimeout: true,
163
+ console: true,
164
+ exports: true,
165
+ global: true,
166
+ module: true,
167
+ performance: true,
168
+ process: true,
169
+ queueMicrotask: true,
170
+ require: true,
171
+ setImmediate: true,
172
+ setInterval: true,
173
+ setTimeout: true,
174
+ structuredClone: true,
175
+ };
176
+ for (const reservedWord of reservedWords_js_1.reservedWords) {
177
+ RESERVED_VARIABLES[reservedWord] = true;
178
+ }
179
+ Object.freeze(RESERVED_VARIABLES);
123
180
  class CodegenFile {
124
181
  constructor(options) {
125
182
  this.options = options;
126
- this._variables = Object.assign(Object.create(null), {
127
- // Reserved variables
128
- AbortController: true,
129
- Array: true,
130
- Buffer: true,
131
- DOMException: true,
132
- Error: true,
133
- Event: true,
134
- EventTarget: true,
135
- JSON: true,
136
- Math: true,
137
- MessageChannel: true,
138
- MessageEvent: true,
139
- MessagePort: true,
140
- Object: true,
141
- TextDecoder: true,
142
- TextEncoder: true,
143
- URL: true,
144
- URLSearchParams: true,
145
- WebAssembly: true,
146
- __dirname: true,
147
- __filename: true,
148
- atob: true,
149
- btoa: true,
150
- clearImmediate: true,
151
- clearInterval: true,
152
- clearTimeout: true,
153
- console: true,
154
- exports: true,
155
- global: true,
156
- module: true,
157
- performance: true,
158
- process: true,
159
- queueMicrotask: true,
160
- require: true,
161
- setImmediate: true,
162
- setInterval: true,
163
- setTimeout: true,
164
- structuredClone: true,
165
- });
183
+ this._variables = Object.assign(Object.create(null), RESERVED_VARIABLES);
166
184
  this._imports = Object.create(null);
167
185
  this._types = Object.create(null);
168
186
  this._directives = Object.create(null);
169
187
  this._statements = [];
170
188
  this._values = new Map();
189
+ this._funcToAstCache = new Map();
171
190
  }
172
191
  addStatements(statements) {
173
192
  if (Array.isArray(statements)) {
@@ -534,6 +553,9 @@ function canBeRegularObjectKey(key) {
534
553
  return key !== "__proto__";
535
554
  }
536
555
  function _convertToAST(file, thing, locationHint, nameHint, depth, reference) {
556
+ if ((0, helpers_js_1.isForbidden)(thing)) {
557
+ throw new Error(`The value at ${locationHint} is forbidden from being exported; please be more specific in your EXPORTABLE factories!`);
558
+ }
537
559
  const handleSubvalue = (value, tKey, key) => {
538
560
  const existingIdentifier = getExistingIdentifier(file, value);
539
561
  if (existingIdentifier) {
@@ -566,22 +588,25 @@ function _convertToAST(file, thing, locationHint, nameHint, depth, reference) {
566
588
  return func(file, thing, locationHint, nameHint);
567
589
  }
568
590
  else if ((0, graphql_1.isSchema)(thing)) {
569
- throw new Error("Attempted to export GraphQLSchema directly from `_convertToAST`; this is currently unsupported.");
591
+ throw new Error(`Attempted to export GraphQLSchema directly from \`_convertToAST\` (at ${locationHint}); this is currently unsupported.`);
570
592
  }
571
593
  else if (typeof thing === "object" && thing != null) {
572
594
  const prototype = Object.getPrototypeOf(thing);
573
595
  if (prototype !== null && prototype !== Object.prototype) {
574
- throw new Error(`Attempting to export an instance of a class; you should wrap this definition in EXPORTABLE! (Class: ${thing.constructor})`);
596
+ if (thing.constructor) {
597
+ throw new Error(`Attempting to export an instance of a class (at ${locationHint}); you should wrap this definition in EXPORTABLE! (Class: ${thing.constructor})`);
598
+ }
599
+ else {
600
+ throw new Error(`Attempting to export non-POJO object (at ${locationHint}); you should wrap this definition in EXPORTABLE! (Prototype: ${(0, node_util_1.inspect)(prototype)})`);
601
+ }
575
602
  }
576
603
  const propertyPairs = [];
577
- let hasUnsafeKeys = false;
578
- Object.entries(thing).forEach(([key, value]) => {
579
- const tKey = identifierOrLiteral(key);
604
+ const entries = Object.entries(thing);
605
+ const hasUnsafeKeys = entries.some(([key]) => !canBeRegularObjectKey(key));
606
+ entries.forEach(([key, value]) => {
607
+ const tKey = hasUnsafeKeys ? literal(key) : identifierOrLiteral(key);
580
608
  const subvalue = handleSubvalue(value, tKey, key);
581
609
  propertyPairs.push([tKey, subvalue]);
582
- if (!canBeRegularObjectKey(key)) {
583
- hasUnsafeKeys = true;
584
- }
585
610
  });
586
611
  if (prototype === null) {
587
612
  if (hasUnsafeKeys) {
@@ -590,20 +615,14 @@ function _convertToAST(file, thing, locationHint, nameHint, depth, reference) {
590
615
  t.arrayExpression(propertyPairs.map(([key, val]) => t.arrayExpression([key, val]))),
591
616
  ]);
592
617
  }
593
- else if (propertyPairs.length === 0) {
594
- return t.callExpression(t.memberExpression(t.identifier("Object"), t.identifier("create")), [t.nullLiteral()]);
595
- }
596
618
  else {
597
- const obj = t.objectExpression(propertyPairs.map(([key, val]) => t.objectProperty(key, val)));
598
- return t.callExpression(t.memberExpression(t.identifier("Object"), t.identifier("assign")), [
599
- t.callExpression(t.memberExpression(t.identifier("Object"), t.identifier("create")), [t.nullLiteral()]),
600
- obj,
601
- ]);
619
+ const obj = objectNullPrototype(propertyPairs.map(([key, val]) => t.objectProperty(key, val)));
620
+ return obj;
602
621
  }
603
622
  }
604
623
  else {
605
624
  if (hasUnsafeKeys) {
606
- throw new Error(`Unexportable key found on non-null-prototype object`);
625
+ throw new Error(`Unexportable key found on non-null-prototype object (at ${locationHint})`);
607
626
  }
608
627
  else {
609
628
  const obj = t.objectExpression(propertyPairs.map(([key, val]) => t.objectProperty(key, val)));
@@ -639,7 +658,7 @@ const getExistingIdentifier = (file, thing) => {
639
658
  const { moduleName, exportName } = (0, wellKnown_js_1.wellKnown)(file.options, thing);
640
659
  return file.import(moduleName, exportName);
641
660
  }
642
- else if (isImportable(thing)) {
661
+ else if ((0, utils_js_1.isImportable)(thing)) {
643
662
  const { moduleName, exportName } = thing.$$export;
644
663
  return file.import(moduleName, exportName);
645
664
  }
@@ -650,6 +669,21 @@ const getExistingIdentifier = (file, thing) => {
650
669
  return file.declareType(thing);
651
670
  }
652
671
  };
672
+ function importWellKnownOrFactory(file, value, locationHint, nameHint) {
673
+ if ((0, utils_js_1.isImportable)(value)) {
674
+ return file.import(value.$$export.moduleName, value.$$export.exportName);
675
+ }
676
+ else if ((0, wellKnown_js_1.wellKnown)(file.options, value)) {
677
+ const { moduleName, exportName } = (0, wellKnown_js_1.wellKnown)(file.options, value);
678
+ return file.import(moduleName, exportName);
679
+ }
680
+ else if (isExportedFromFactory(value)) {
681
+ return factoryAst(file, value, locationHint, nameHint);
682
+ }
683
+ else {
684
+ return undefined;
685
+ }
686
+ }
653
687
  function convertToIdentifierViaAST(file, thing, baseNameHint, locationHint, depth = 0) {
654
688
  const existingIdentifier = getExistingIdentifier(file, thing);
655
689
  if (existingIdentifier) {
@@ -659,9 +693,8 @@ function convertToIdentifierViaAST(file, thing, baseNameHint, locationHint, dept
659
693
  const nameHint = getNameForThing(thing, locationHint, baseNameHint);
660
694
  const variableIdentifier = file.makeVariable(nameHint || "value");
661
695
  file._values.set(thing, variableIdentifier);
662
- const ast = isExportedFromFactory(thing)
663
- ? factoryAst(file, thing, locationHint, nameHint)
664
- : _convertToAST(file, thing, locationHint, nameHint, depth, variableIdentifier);
696
+ const ast = importWellKnownOrFactory(file, thing, locationHint, nameHint) ??
697
+ _convertToAST(file, thing, locationHint, nameHint, depth, variableIdentifier);
665
698
  if (ast.type === "Identifier") {
666
699
  console.warn(`graphile-export error: AST returned an identifier '${ast.name}'; this could cause an infinite loop.`);
667
700
  }
@@ -679,20 +712,20 @@ function objectToObjectProperties(o) {
679
712
  .map(([key, value]) => t.objectProperty(identifierOrLiteral(key), value));
680
713
  }
681
714
  function extensions(file, extensions, locationHint, nameHint) {
682
- if (extensions == null || Object.keys(extensions).length === 0) {
683
- return null;
684
- }
685
- return convertToIdentifierViaAST(file, extensions, nameHint, locationHint);
715
+ return isNotEmpty(extensions)
716
+ ? convertToIdentifierViaAST(file, extensions, nameHint, locationHint)
717
+ : null;
686
718
  }
687
- /** Maps to `Object.assign(Object.create(null), {...})` */
719
+ /**
720
+ * Maps to `{__proto__: null, ...}` which is similar to
721
+ * `Object.assign(Object.create(null), {...})`
722
+ */
688
723
  function objectNullPrototype(properties) {
689
- const objectCreateNull = t.callExpression(t.memberExpression(t.identifier("Object"), t.identifier("create")), [t.nullLiteral()]);
690
- if (properties.length === 0) {
691
- return objectCreateNull;
692
- }
693
- return t.callExpression(t.memberExpression(t.identifier("Object"), t.identifier("assign")), [objectCreateNull, t.objectExpression(properties)]);
724
+ return t.objectExpression([
725
+ t.objectProperty(t.identifier("__proto__"), t.nullLiteral()),
726
+ ...properties,
727
+ ]);
694
728
  }
695
- exports.objectNullPrototype = objectNullPrototype;
696
729
  /*
697
730
  function iife(statements: t.Statement[]): t.Expression {
698
731
  return t.callExpression(
@@ -709,24 +742,13 @@ function func(file, fn, locationHint, nameHint) {
709
742
  // scope; e.g.:
710
743
  //
711
744
  // `(() => { const foo = 1, bar = 2; return /*>*/() => {return foo+bar}/*<*/})();`
712
- if (isExportedFromFactory(fn)) {
713
- return factoryAst(file, fn, locationHint, nameHint);
714
- }
715
- else if ((0, wellKnown_js_1.wellKnown)(file.options, fn)) {
716
- const { moduleName, exportName } = (0, wellKnown_js_1.wellKnown)(file.options, fn);
717
- return file.import(moduleName, exportName);
718
- }
719
- else if (isImportable(fn)) {
720
- return file.import(fn.$$export.moduleName, fn.$$export.exportName);
721
- }
722
- else {
723
- return funcToAst(fn, locationHint, nameHint);
724
- }
745
+ return (importWellKnownOrFactory(file, fn, locationHint, nameHint) ??
746
+ funcToAst(file, fn, locationHint, nameHint).ast);
725
747
  }
726
748
  const shouldOptimizeFactoryCalls = true;
727
749
  function factoryAst(file, fn, locationHint, nameHint) {
728
750
  const factory = fn.$exporter$factory;
729
- const funcAST = funcToAst(factory, locationHint, nameHint);
751
+ const { functionWithoutOwnAttributesAST: funcAST } = funcToAst(file, factory, locationHint, nameHint);
730
752
  const depArgs = fn.$exporter$args.map((arg, i) => {
731
753
  if (typeof arg === "string") {
732
754
  return t.stringLiteral(arg);
@@ -778,13 +800,79 @@ function factoryAst(file, fn, locationHint, nameHint) {
778
800
  return t.callExpression(funcAST, depArgs);
779
801
  }
780
802
  }
781
- function funcToAst(fn, locationHint, _nameHint) {
803
+ function funcToAst(file, fn, locationHint, _nameHint) {
804
+ if (file._funcToAstCache.has(fn)) {
805
+ return file._funcToAstCache.get(fn);
806
+ }
807
+ const path = _funcToAst(fn, locationHint, _nameHint);
808
+ const externalReferences = new Set();
809
+ const localBindings = path.scope.bindings;
810
+ path.traverse({
811
+ Identifier(path) {
812
+ if (t.isReferenced(path.node, path.parent) && // Is a variable reference
813
+ !path.scope.hasBinding(path.node.name) && // Not defined in local scope
814
+ !localBindings[path.node.name] // Not a parameter of the function
815
+ ) {
816
+ externalReferences.add(path.node.name);
817
+ }
818
+ },
819
+ });
820
+ // Remove global things they're allowed to reference
821
+ externalReferences.delete("Buffer");
822
+ externalReferences.delete("console");
823
+ externalReferences.delete("process");
824
+ externalReferences.delete("setTimeout");
825
+ externalReferences.delete("setInterval");
826
+ if (externalReferences.size > 0) {
827
+ throw new Error(`The function being exported as ${locationHint} references external variables: \`${[
828
+ ...externalReferences,
829
+ ].join("`, `")}\`. Please ensure this function is wrapped in \`EXPORTABLE(() => ...)\`. Fn:\n${fn}`);
830
+ }
831
+ const fnExpression = path.node;
832
+ const ownProps = Object.entries(fn);
833
+ const result = (() => {
834
+ if (ownProps.length > 0) {
835
+ // Need to assign things to it
836
+ const properties = ownProps.map(([key, value]) => {
837
+ return t.objectProperty(identifierOrLiteral(key), convertToIdentifierViaAST(file, value, `${locationHint}.${key}`, `${locationHint}['${key}']`));
838
+ });
839
+ return {
840
+ functionWithoutOwnAttributesAST: fnExpression,
841
+ ast: t.callExpression(t.memberExpression(t.identifier("Object"), t.identifier("assign")), [fnExpression, t.objectExpression(properties)]),
842
+ };
843
+ }
844
+ else {
845
+ return {
846
+ functionWithoutOwnAttributesAST: fnExpression,
847
+ ast: fnExpression,
848
+ };
849
+ }
850
+ })();
851
+ file._funcToAstCache.set(fn, result);
852
+ return result;
853
+ }
854
+ function parseExpressionViaDoc(funcString) {
855
+ const doc = (0, parser_1.parse)(`const f = ${funcString}`, {
856
+ sourceType: "module",
857
+ plugins: ["typescript"],
858
+ });
859
+ let result = null;
860
+ (0, traverse_1.default)(doc, {
861
+ VariableDeclaration(path) {
862
+ result = path.get("declarations.0.init");
863
+ path.stop();
864
+ },
865
+ });
866
+ if (!result) {
867
+ throw new Error(`graphile-export internal error - failed to find the variable declaration (?!!)`);
868
+ }
869
+ return result;
870
+ }
871
+ function _funcToAst(fn, locationHint, _nameHint) {
782
872
  const funcString = fn.toString().trim();
783
873
  try {
784
- const result = (0, parser_1.parseExpression)(funcString, {
785
- sourceType: "module",
786
- plugins: ["typescript"],
787
- });
874
+ const path = parseExpressionViaDoc(funcString);
875
+ const result = path.node;
788
876
  if (result.type !== "FunctionExpression" &&
789
877
  result.type !== "ArrowFunctionExpression") {
790
878
  if (result.type === "ClassExpression") {
@@ -793,7 +881,7 @@ Object.defineProperty(${result.id?.name ?? "MyClass"}, '$$export', { value: { mo
793
881
  }
794
882
  throw new Error(`Expected FunctionExpression or ArrowFunctionExpression but saw ${result.type}`);
795
883
  }
796
- return result;
884
+ return path;
797
885
  }
798
886
  catch (e) {
799
887
  if (e.retry === false) {
@@ -811,15 +899,13 @@ Object.defineProperty(${result.id?.name ?? "MyClass"}, '$$export', { value: { mo
811
899
  const modifiedDefinition = funcString.startsWith("async ")
812
900
  ? "async function " + funcString.slice(6)
813
901
  : "function " + funcString;
814
- const result = (0, parser_1.parseExpression)(modifiedDefinition, {
815
- sourceType: "module",
816
- plugins: ["typescript"],
817
- });
902
+ const path = parseExpressionViaDoc(modifiedDefinition);
903
+ const result = path.node;
818
904
  if (result.type !== "FunctionExpression" &&
819
905
  result.type !== "ArrowFunctionExpression") {
820
906
  throw new Error(`Expected FunctionExpression or ArrowFunctionExpression but saw ${result.type}`);
821
907
  }
822
- return result;
908
+ return path;
823
909
  }
824
910
  catch {
825
911
  throw new Error(`Function export error at ${locationHint} - failed to process function definition '${trimDef(fn.toString())}'\n ${String(e.stack ?? e)
@@ -848,14 +934,9 @@ function exportSchemaGraphQLJS({ config, customTypes, customDirectives, file, })
848
934
  ? t.arrayExpression(customDirectives.map((directive) => file.declareDirective(directive)))
849
935
  : null,
850
936
  extensions: extensions(file, config.extensions, "schema.extensions", "schema.extensions"),
851
- enableDeferStream: t.booleanLiteral(process.env.ENABLE_DEFER_STREAM === "1"),
852
- /*
853
- // TODO: use the below once https://github.com/graphql/graphql-js/pull/3450 is fixed:
854
- enableDeferStream:
855
- config.enableDeferStream != null
937
+ enableDeferStream: config.enableDeferStream != null
856
938
  ? t.booleanLiteral(config.enableDeferStream)
857
939
  : null,
858
- */
859
940
  assumeValid: null, // TODO: t.booleanLiteral(true),
860
941
  }));
861
942
  }
@@ -866,19 +947,30 @@ function exportSchemaGraphQLJS({ config, customTypes, customDirectives, file, })
866
947
  */
867
948
  function exportSchemaTypeDefs({ schema, customTypes, file, }) {
868
949
  const typeDefsExportName = file.makeVariable("typeDefs");
869
- const plansExportName = file.makeVariable("plans");
950
+ const objectPlansProperties = Object.create(null);
951
+ const interfacePlansProperties = Object.create(null);
952
+ const unionPlansProperties = Object.create(null);
953
+ const inputObjectPlansProperties = Object.create(null);
954
+ const scalarPlansProperties = Object.create(null);
955
+ const enumPlansProperties = Object.create(null);
870
956
  const schemaExportName = file.makeVariable("schema");
871
957
  const typeDefsString = (0, graphql_1.printSchema)(schema);
872
958
  const graphqlAST = t.templateLiteral([t.templateElement({ raw: typeDefsString.replace(/[\\`]/g, "\\$&") })], []);
873
959
  graphqlAST.leadingComments = [
874
960
  { type: "CommentBlock", value: " GraphQL " },
875
961
  ];
876
- const plansProperties = [];
877
962
  customTypes.forEach((type) => {
878
963
  if (type instanceof graphql_1.GraphQLObjectType) {
879
- const typeProperties = [];
964
+ const typeProperties = Object.create(null);
965
+ const plansProperties = Object.create(null);
880
966
  if (type.extensions.grafast?.assertStep) {
881
- typeProperties.push(t.objectProperty(t.identifier("__assertStep"), convertToIdentifierViaAST(file, type.extensions.grafast.assertStep, `${type.name}AssertStep`, `${type.name}.extensions.assertStep`)));
967
+ typeProperties.assertStep = convertToIdentifierViaAST(file, type.extensions.grafast.assertStep, `${type.name}AssertStep`, `${type.name}.extensions.assertStep`);
968
+ }
969
+ if (type.isTypeOf) {
970
+ typeProperties.isTypeOf = convertToIdentifierViaAST(file, type.isTypeOf, `${type.name}IsTypeOf`, `${type.name}.extensions.isTypeOf`);
971
+ }
972
+ if (type.extensions.grafast?.planType) {
973
+ typeProperties.planType = convertToIdentifierViaAST(file, type.extensions.grafast.planType, `${type.name}PlanType`, `${type.name}.extensions.planType`);
882
974
  }
883
975
  for (const [fieldName, field] of Object.entries(type.toConfig().fields)) {
884
976
  // Use shorthand if there's only a `plan` and nothing else
@@ -899,9 +991,38 @@ function exportSchemaTypeDefs({ schema, customTypes, file, }) {
899
991
  const args = field.args
900
992
  ? Object.entries(field.args)
901
993
  .map(([argName, arg]) => {
902
- return t.objectProperty(identifierOrLiteral(argName), convertToIdentifierViaAST(file, arg.extensions?.grafast, `${type.name}.${fieldName}.${argName}`, `${type.name}.fields[${fieldName}].args[${argName}].extensions.grafast`));
994
+ if (arg.extensions) {
995
+ const { grafast, ...rest } = arg.extensions;
996
+ const extensionsAST = extensions(file, rest, `${type.name}.${fieldName}.${argName}`, `${type.name}.fields[${fieldName}].args[${argName}].extensions`);
997
+ if (!extensionsAST) {
998
+ if (!grafast)
999
+ return null;
1000
+ const keys = Object.keys(grafast);
1001
+ if (keys.length === 1 && keys[0] === "applyPlan") {
1002
+ // Shorthand
1003
+ return t.objectProperty(identifierOrLiteral(argName), convertToIdentifierViaAST(file, grafast.applyPlan, `${type.name}.${fieldName}${argName}ApplyPlan`, `${type.name}.fields[${fieldName}].args[${argName}].applyPlan`));
1004
+ }
1005
+ }
1006
+ return t.objectProperty(identifierOrLiteral(argName), t.objectExpression([
1007
+ ...objectToObjectProperties({
1008
+ extensions: extensionsAST,
1009
+ }),
1010
+ ...(grafast
1011
+ ? Object.entries(grafast)
1012
+ .map(([k, v]) => {
1013
+ if (v == null)
1014
+ return null;
1015
+ return t.objectProperty(t.identifier(k), convertToIdentifierViaAST(file, grafast.applyPlan, `${type.name}.${fieldName}${argName}${k}`, `${type.name}.fields[${fieldName}].args[${argName}].extensions.grafast[${k}]`));
1016
+ })
1017
+ .filter(utils_js_1.isNotNullish)
1018
+ : []),
1019
+ ]));
1020
+ }
1021
+ else {
1022
+ return null;
1023
+ }
903
1024
  })
904
- .filter(isNotNullish)
1025
+ .filter(utils_js_1.isNotNullish)
905
1026
  : null;
906
1027
  const argsAST = args && args.length ? t.objectExpression(args) : null;
907
1028
  if (!planAST && !subscribePlanAST && !resolveAST && !subscribeAST) {
@@ -925,24 +1046,69 @@ function exportSchemaTypeDefs({ schema, customTypes, file, }) {
925
1046
  subscribe: subscribeAST,
926
1047
  args: argsAST,
927
1048
  }));
928
- typeProperties.push(t.objectProperty(identifierOrLiteral(fieldName), fieldSpec));
1049
+ plansProperties[fieldName] = fieldSpec;
929
1050
  }
930
- plansProperties.push(t.objectProperty(identifierOrLiteral(type.name), t.objectExpression(typeProperties)));
1051
+ setIfNotEmpty(typeProperties, "plans", plansProperties, true);
1052
+ setIfNotEmpty(objectPlansProperties, type.name, typeProperties, false);
931
1053
  }
932
1054
  else if (type instanceof graphql_1.GraphQLInputObjectType) {
933
- const typeProperties = [];
1055
+ const typeProperties = Object.create(null);
1056
+ const plansProperties = Object.create(null);
1057
+ if (type.extensions?.grafast?.baked) {
1058
+ typeProperties.baked = convertToIdentifierViaAST(file, type.extensions?.grafast.baked, `${type.name}.inputPlan`, `${type.name}.extensions.grafast.baked`);
1059
+ }
934
1060
  for (const [fieldName, field] of Object.entries(type.toConfig().fields)) {
935
- typeProperties.push(t.objectProperty(identifierOrLiteral(fieldName), convertToIdentifierViaAST(file, field.extensions?.grafast, `${type.name}.${fieldName}`, `${type.name}.fields[${fieldName}].extensions.grafast`)));
1061
+ if (!field.extensions)
1062
+ continue;
1063
+ const { grafast, ...rest } = field.extensions;
1064
+ const extensionsAST = extensions(file, rest, `${type.name}_${fieldName}Extensions`, `${type.name}.fields[${fieldName}].extensions`);
1065
+ if (!extensionsAST) {
1066
+ if (!grafast)
1067
+ continue;
1068
+ const keys = Object.keys(grafast);
1069
+ if (keys.length === 1 && keys[0] === "apply") {
1070
+ plansProperties[fieldName] = convertToIdentifierViaAST(file, grafast.apply, `${type.name}.${fieldName}Apply`, `${type.name}.fields[${fieldName}].extensions.grafast.apply`);
1071
+ continue;
1072
+ }
1073
+ }
1074
+ plansProperties[fieldName] = t.objectExpression([
1075
+ ...objectToObjectProperties({
1076
+ extensions: extensionsAST,
1077
+ }),
1078
+ ...(grafast
1079
+ ? Object.entries(grafast)
1080
+ .map(([k, v]) => {
1081
+ if (v == null)
1082
+ return null;
1083
+ return t.objectProperty(t.identifier(k), convertToIdentifierViaAST(file, v, `${type.name}.${fieldName}${k}`, `${type.name}.fields[${fieldName}].extensions.grafast[${k}]`));
1084
+ })
1085
+ .filter(utils_js_1.isNotNullish)
1086
+ : []),
1087
+ ]);
936
1088
  }
937
- plansProperties.push(t.objectProperty(identifierOrLiteral(type.name), t.objectExpression(typeProperties)));
1089
+ setIfNotEmpty(typeProperties, "plans", plansProperties, true);
1090
+ setIfNotEmpty(inputObjectPlansProperties, type.name, typeProperties, false);
938
1091
  }
939
1092
  else if (type instanceof graphql_1.GraphQLInterfaceType ||
940
1093
  type instanceof graphql_1.GraphQLUnionType) {
941
1094
  const config = type.toConfig();
942
- if (config.resolveType) {
943
- plansProperties.push(t.objectProperty(identifierOrLiteral(type.name), t.objectExpression(objectToObjectProperties({
944
- __resolveType: convertToIdentifierViaAST(file, type.resolveType, `${type.name}ResolveType`, `${type.name}.resolveType`),
945
- }))));
1095
+ if (config.resolveType ||
1096
+ config.extensions.grafast?.toSpecifier ||
1097
+ config.extensions.grafast?.planType) {
1098
+ const target = type instanceof graphql_1.GraphQLInterfaceType
1099
+ ? interfacePlansProperties
1100
+ : unionPlansProperties;
1101
+ target[type.name] = t.objectExpression(objectToObjectProperties({
1102
+ resolveType: type.resolveType
1103
+ ? convertToIdentifierViaAST(file, type.resolveType, `${type.name}ResolveType`, `${type.name}.resolveType`)
1104
+ : null,
1105
+ toSpecifier: type.extensions?.grafast?.toSpecifier
1106
+ ? convertToIdentifierViaAST(file, type.extensions?.grafast?.toSpecifier, `${type.name}ToSpecifier`, `${type.name}.toSpecifier`)
1107
+ : null,
1108
+ planType: type.extensions?.grafast?.planType
1109
+ ? convertToIdentifierViaAST(file, type.extensions?.grafast?.planType, `${type.name}PlanType`, `${type.name}.planType`)
1110
+ : null,
1111
+ }));
946
1112
  }
947
1113
  }
948
1114
  else if (type instanceof graphql_1.GraphQLScalarType) {
@@ -950,36 +1116,65 @@ function exportSchemaTypeDefs({ schema, customTypes, file, }) {
950
1116
  const planAST = config.extensions.grafast?.plan
951
1117
  ? convertToIdentifierViaAST(file, config.extensions?.grafast?.plan, `${type.name}Plan`, `${type.name}.extensions.grafast.plan`)
952
1118
  : null;
953
- if (planAST) {
954
- plansProperties.push(t.objectProperty(identifierOrLiteral(type.name), t.objectExpression(objectToObjectProperties({
955
- serialize: convertToIdentifierViaAST(file, type.serialize, `${type.name}Serialize`, `${type.name}.serialize`),
956
- parseValue: convertToIdentifierViaAST(file, type.parseValue, `${type.name}ParseValue`, `${type.name}.parseValue`),
957
- parseLiteral: convertToIdentifierViaAST(file, type.parseLiteral, `${type.name}ParseLiteral`, `${type.name}.parseLiteral`),
1119
+ if (planAST ||
1120
+ type.serialize !== graphql_1.GraphQLScalarType.prototype.serialize ||
1121
+ type.parseValue !== graphql_1.GraphQLScalarType.prototype.parseValue ||
1122
+ type.parseLiteral !== graphql_1.GraphQLScalarType.prototype.parseLiteral) {
1123
+ scalarPlansProperties[type.name] = t.objectExpression(objectToObjectProperties({
1124
+ serialize: type.serialize !== graphql_1.GraphQLScalarType.prototype.serialize
1125
+ ? convertToIdentifierViaAST(file, type.serialize, `${type.name}Serialize`, `${type.name}.serialize`)
1126
+ : null,
1127
+ parseValue: type.parseValue !== graphql_1.GraphQLScalarType.prototype.parseValue
1128
+ ? convertToIdentifierViaAST(file, type.parseValue, `${type.name}ParseValue`, `${type.name}.parseValue`)
1129
+ : null,
1130
+ parseLiteral: type.parseLiteral !== graphql_1.GraphQLScalarType.prototype.parseLiteral
1131
+ ? convertToIdentifierViaAST(file, type.parseLiteral, `${type.name}ParseLiteral`, `${type.name}.parseLiteral`)
1132
+ : null,
958
1133
  plan: planAST,
959
- }))));
1134
+ }));
960
1135
  }
961
1136
  }
962
1137
  else if (type instanceof graphql_1.GraphQLEnumType) {
963
1138
  const config = type.toConfig();
964
- const enumValues = [];
1139
+ const typeProperties = Object.create(null);
1140
+ const enumValueProperties = Object.create(null);
965
1141
  for (const [enumValueName, enumValueConfig] of Object.entries(config.values)) {
966
1142
  const valueAST = enumValueConfig.value !== undefined &&
967
1143
  enumValueConfig.value !== enumValueName
968
1144
  ? convertToIdentifierViaAST(file, enumValueConfig.value, `${type.name}_${enumValueName}`, `${type.name}.values[${enumValueName}].value`)
969
1145
  : null;
970
- const applyPlanAST = enumValueConfig.extensions?.grafast?.applyPlan
971
- ? convertToIdentifierViaAST(file, enumValueConfig.extensions.grafast.applyPlan, `${type.name}_${enumValueName}ApplyPlan`, `${type.name}.values[${enumValueName}].extensions.grafast.applyPlan`)
972
- : null;
973
- if (valueAST || applyPlanAST) {
974
- enumValues.push(t.objectProperty(identifierOrLiteral(enumValueName), t.objectExpression(objectToObjectProperties({
975
- value: valueAST,
976
- applyPlan: applyPlanAST,
977
- }))));
1146
+ const { grafast, ...rest } = enumValueConfig.extensions ?? {};
1147
+ const extensionsAST = extensions(file, rest, `${type.name}_${enumValueName}Extensions`, `${type.name}.values[${enumValueName}].extensions`);
1148
+ if (!valueAST && !extensionsAST) {
1149
+ if (!grafast)
1150
+ continue;
1151
+ const keys = Object.keys(grafast);
1152
+ if (keys.length === 1 && keys[0] === "apply") {
1153
+ enumValueProperties[enumValueName] = convertToIdentifierViaAST(file, grafast.apply, `${type.name}.${enumValueName}Apply`, `${type.name}.values[${enumValueName}].extensions.grafast.apply`);
1154
+ continue;
1155
+ }
1156
+ }
1157
+ const grafastProperties = grafast
1158
+ ? Object.entries(grafast)
1159
+ .map(([k, v]) => {
1160
+ if (v == null)
1161
+ return null;
1162
+ return t.objectProperty(t.identifier(k), convertToIdentifierViaAST(file, v, `${type.name}.${enumValueName}${k}`, `${type.name}.values[${enumValueName}].extensions.grafast[${k}]`));
1163
+ })
1164
+ .filter(utils_js_1.isNotNullish)
1165
+ : [];
1166
+ if (valueAST || extensionsAST || grafastProperties.length) {
1167
+ enumValueProperties[enumValueName] = t.objectExpression([
1168
+ ...objectToObjectProperties({
1169
+ value: valueAST,
1170
+ extensions: extensionsAST,
1171
+ }),
1172
+ ...grafastProperties,
1173
+ ]);
978
1174
  }
979
1175
  }
980
- if (enumValues.length > 0) {
981
- plansProperties.push(t.objectProperty(identifierOrLiteral(type.name), t.objectExpression(enumValues)));
982
- }
1176
+ setIfNotEmpty(typeProperties, "values", enumValueProperties, true);
1177
+ setIfNotEmpty(enumPlansProperties, type.name, typeProperties, false);
983
1178
  }
984
1179
  else {
985
1180
  const never = type;
@@ -989,17 +1184,40 @@ function exportSchemaTypeDefs({ schema, customTypes, file, }) {
989
1184
  const typeDefs = t.exportNamedDeclaration(t.variableDeclaration("const", [
990
1185
  t.variableDeclarator(typeDefsExportName, graphqlAST),
991
1186
  ]));
992
- const plans = t.exportNamedDeclaration(t.variableDeclaration("const", [
993
- t.variableDeclarator(plansExportName, t.objectExpression(plansProperties)),
994
- ]));
995
1187
  file.addStatements(typeDefs);
996
- file.addStatements(plans);
1188
+ const typeDefsEtc = {
1189
+ typeDefs: typeDefsExportName,
1190
+ };
1191
+ const stuff = Object.create(null);
1192
+ setIfNotEmpty(stuff, "objects", objectPlansProperties, [
1193
+ schema.getQueryType()?.name,
1194
+ schema.getMutationType()?.name,
1195
+ schema.getSubscriptionType()?.name,
1196
+ ].filter((n) => n != null));
1197
+ setIfNotEmpty(stuff, "interfaces", interfacePlansProperties, true);
1198
+ setIfNotEmpty(stuff, "unions", unionPlansProperties, true);
1199
+ setIfNotEmpty(stuff, "inputObjects", inputObjectPlansProperties, true);
1200
+ setIfNotEmpty(stuff, "scalars", scalarPlansProperties, true);
1201
+ setIfNotEmpty(stuff, "enums", enumPlansProperties, true);
1202
+ const todos = [];
1203
+ for (const [key, props] of Object.entries(stuff)) {
1204
+ const exportName = file.makeVariable(key);
1205
+ // Do this afterwards so all the variables are reserved first.
1206
+ todos.push(() => {
1207
+ const plans = t.exportNamedDeclaration(t.variableDeclaration("const", [
1208
+ t.variableDeclarator(exportName, props),
1209
+ ]));
1210
+ file.addStatements(plans);
1211
+ typeDefsEtc[key] = exportName;
1212
+ });
1213
+ }
1214
+ // Now all variables are declared, we can populate them
1215
+ for (const todo of todos) {
1216
+ todo();
1217
+ }
997
1218
  const makeGrafastSchemaAST = file.import("grafast", "makeGrafastSchema");
998
1219
  const schemaAST = t.callExpression(makeGrafastSchemaAST, [
999
- t.objectExpression(objectToObjectProperties({
1000
- typeDefs: typeDefsExportName,
1001
- plans: plansExportName,
1002
- })),
1220
+ t.objectExpression(objectToObjectProperties(typeDefsEtc)),
1003
1221
  ]);
1004
1222
  file.addStatements(t.exportNamedDeclaration(t.variableDeclaration("const", [
1005
1223
  t.variableDeclarator(schemaExportName, schemaAST),
@@ -1016,6 +1234,11 @@ async function exportSchemaAsString(schema, options) {
1016
1234
  "defer",
1017
1235
  "stream",
1018
1236
  ].includes(d.name));
1237
+ if (process.env.ENABLE_DEFER_STREAM === "1" ||
1238
+ config.directives.some((d) => d.name === "defer" || d.name === "skip")) {
1239
+ // Ref: https://github.com/graphql/graphql-js/pull/3450
1240
+ config.enableDeferStream = true;
1241
+ }
1019
1242
  const file = new CodegenFile(options);
1020
1243
  const schemaExportDetails = {
1021
1244
  schema,
@@ -1031,16 +1254,79 @@ async function exportSchemaAsString(schema, options) {
1031
1254
  else {
1032
1255
  exportSchemaGraphQLJS(schemaExportDetails);
1033
1256
  }
1257
+ return exportFile(file, options);
1258
+ }
1259
+ function exportFile(file, { disableOptimize }) {
1034
1260
  const ast = file.toAST();
1035
- const optimizedAst = (0, index_js_1.optimize)(ast);
1261
+ const optimizedAst = disableOptimize ? ast : (0, index_js_1.optimize)(ast);
1036
1262
  const { code } = reallyGenerate(optimizedAst, {});
1037
1263
  return { code };
1038
1264
  }
1039
- exports.exportSchemaAsString = exportSchemaAsString;
1040
- async function exportSchema(schema, toPath, options = {}) {
1041
- const { code } = await exportSchemaAsString(schema, options);
1042
- const HEADER = `/* eslint-disable graphile-export/export-instances, graphile-export/export-methods, graphile-export/exhaustive-deps */\n`;
1043
- const toFormat = HEADER + code;
1265
+ async function exportValueAsString(name, value, options) {
1266
+ const file = new CodegenFile(options);
1267
+ const exportName = file.makeVariable(name);
1268
+ const valueAST = convertToIdentifierViaAST(file, value, name, name);
1269
+ file.addStatements(t.exportNamedDeclaration(t.variableDeclaration("const", [
1270
+ t.variableDeclarator(exportName, valueAST),
1271
+ ])));
1272
+ return exportFile(file, options);
1273
+ }
1274
+ async function loadESLint() {
1275
+ try {
1276
+ return await import("eslint");
1277
+ }
1278
+ catch (e) {
1279
+ return null;
1280
+ }
1281
+ }
1282
+ async function lint(code, rawFilePath) {
1283
+ const eslintModule = await loadESLint();
1284
+ if (eslintModule == null) {
1285
+ console.warn(`graphile-export could not find 'eslint' so disabling additional checks`);
1286
+ return;
1287
+ }
1288
+ const filePath = typeof rawFilePath === "string" ? rawFilePath : rawFilePath.pathname;
1289
+ const { ESLint } = eslintModule;
1290
+ const eslint = new ESLint({
1291
+ overrideConfigFile: true, // Don't use external config
1292
+ allowInlineConfig: false, // Ignore `/* eslint-disable ... */` comments
1293
+ overrideConfig: {
1294
+ linterOptions: { reportUnusedDisableDirectives: false },
1295
+ languageOptions: {
1296
+ ecmaVersion: 2022,
1297
+ sourceType: "module",
1298
+ },
1299
+ rules: {
1300
+ "no-use-before-define": [
1301
+ "error",
1302
+ {
1303
+ functions: false,
1304
+ classes: false,
1305
+ // We often have cyclic dependencies between types, this is handled via callbacks, so we don't care about that.
1306
+ variables: false,
1307
+ allowNamedExports: false,
1308
+ },
1309
+ ],
1310
+ },
1311
+ },
1312
+ });
1313
+ const results = await eslint.lintText(code, {
1314
+ warnIgnored: true,
1315
+ // DO NOT PASS THE `filePath`; it can result in the file being ignored!
1316
+ });
1317
+ if (results.length !== 1) {
1318
+ console.dir({ filePath, results });
1319
+ throw new Error(`Expected ESLint results to have exactly one entry`);
1320
+ }
1321
+ const [result] = results;
1322
+ if (result.warningCount > 0 || result.errorCount > 0) {
1323
+ console.log(`ESLint found problems in the export; this likely indicates some issue with \`EXPORTABLE\` calls`);
1324
+ const formatter = await eslint.loadFormatter("stylish");
1325
+ const output = formatter.format(results);
1326
+ console.log(output);
1327
+ }
1328
+ }
1329
+ async function format(toFormat, toPath, options) {
1044
1330
  if (options.prettier) {
1045
1331
  const prettier = await import("prettier");
1046
1332
  const config = await prettier.resolveConfig(toPath.toString());
@@ -1048,11 +1334,65 @@ async function exportSchema(schema, toPath, options = {}) {
1048
1334
  parser: "babel",
1049
1335
  ...(config ?? {}),
1050
1336
  });
1051
- await (0, promises_1.writeFile)(toPath, formatted);
1337
+ return formatted;
1052
1338
  }
1053
1339
  else {
1054
- await (0, promises_1.writeFile)(toPath, toFormat);
1340
+ return toFormat;
1341
+ }
1342
+ }
1343
+ const HEADER = `/* eslint-disable graphile-export/export-instances, graphile-export/export-methods, graphile-export/exhaustive-deps */\n`;
1344
+ async function exportSchema(schema, toPath, options = {}) {
1345
+ const { code } = await exportSchemaAsString(schema, options);
1346
+ const toFormat = HEADER + code;
1347
+ const formatted = await format(toFormat, toPath, options);
1348
+ await (0, promises_1.writeFile)(toPath, formatted);
1349
+ await lint(formatted, toPath);
1350
+ }
1351
+ /**
1352
+ * Returns `false` for nullish values and empty objects, true otherwise.
1353
+ */
1354
+ function isNotEmpty(value) {
1355
+ if (value == null)
1356
+ return false;
1357
+ if (typeof value !== "object")
1358
+ return true;
1359
+ const proto = Object.getPrototypeOf(value);
1360
+ if (proto !== null && proto !== Object.prototype)
1361
+ return true;
1362
+ if (Object.getOwnPropertyNames(value).length === 0 &&
1363
+ Object.getOwnPropertySymbols(value).length === 0) {
1364
+ // Empty object!
1365
+ return false;
1366
+ }
1367
+ return true;
1368
+ }
1369
+ function setIfNotEmpty(target, key, value, sort) {
1370
+ if (Object.keys(value).length > 0) {
1371
+ const entries = Object.entries(value);
1372
+ if (typeof sort === "boolean") {
1373
+ entries.sort((a, z) => a[0].localeCompare(z[0], "und"));
1374
+ }
1375
+ else if (sort) {
1376
+ entries.sort((a, z) => {
1377
+ const ka = a[0];
1378
+ const kz = z[0];
1379
+ // First, compare keys against the specific defined order
1380
+ const sa = sort.indexOf(ka);
1381
+ const sz = sort.indexOf(kz);
1382
+ if (sa >= 0) {
1383
+ if (sz < 0)
1384
+ return -1;
1385
+ return sa - sz;
1386
+ }
1387
+ else if (sz >= 0) {
1388
+ return 1;
1389
+ }
1390
+ // Failing that, compare them alphabetically
1391
+ return ka.localeCompare(kz, "und");
1392
+ });
1393
+ }
1394
+ const finalProps = entries.map(([k, v]) => t.objectProperty(identifierOrLiteral(k), v));
1395
+ target[key] = t.objectExpression(finalProps);
1055
1396
  }
1056
1397
  }
1057
- exports.exportSchema = exportSchema;
1058
1398
  //# sourceMappingURL=exportSchema.js.map