@ptdgrp/typedgql 1.0.0-beta.15 → 1.0.0-beta.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/README.md +64 -4
  2. package/README.zh-CN.md +64 -4
  3. package/dist/cli.cjs +47 -0
  4. package/dist/cli.d.cts +1 -0
  5. package/dist/cli.d.mts +1 -0
  6. package/dist/cli.mjs +49 -0
  7. package/dist/cli.mjs.map +1 -0
  8. package/dist/{schema-loader-DolAa42F.cjs → config-loader-Bxj44SGD.cjs} +349 -42
  9. package/dist/{schema-loader-vNpUWFmU.mjs → config-loader-DZ7d_CWR.mjs} +343 -48
  10. package/dist/config-loader-DZ7d_CWR.mjs.map +1 -0
  11. package/dist/cyrb53-B2tdX6NT.mjs +921 -0
  12. package/dist/cyrb53-B2tdX6NT.mjs.map +1 -0
  13. package/dist/cyrb53-BTzxwvXR.cjs +1010 -0
  14. package/dist/cyrb53-DWYFRdWZ.d.mts +333 -0
  15. package/dist/cyrb53-DWYFRdWZ.d.mts.map +1 -0
  16. package/dist/cyrb53-FbY3n_2r.d.cts +333 -0
  17. package/dist/cyrb53-FbY3n_2r.d.cts.map +1 -0
  18. package/dist/index.cjs +18 -935
  19. package/dist/index.d.cts +2 -333
  20. package/dist/index.d.mts +2 -333
  21. package/dist/index.mjs +3 -920
  22. package/dist/node.cjs +6 -4
  23. package/dist/node.d.cts +63 -2
  24. package/dist/node.d.cts.map +1 -1
  25. package/dist/node.d.mts +63 -2
  26. package/dist/node.d.mts.map +1 -1
  27. package/dist/node.mjs +2 -2
  28. package/dist/{options-CgrZ2der.d.cts → options-B6mcYDIz.d.cts} +10 -1
  29. package/dist/options-B6mcYDIz.d.cts.map +1 -0
  30. package/dist/{options-BWcHrC-1.d.mts → options-T07dJfbz.d.mts} +10 -1
  31. package/dist/options-T07dJfbz.d.mts.map +1 -0
  32. package/dist/runtime.cjs +18 -0
  33. package/dist/runtime.d.cts +2 -0
  34. package/dist/runtime.d.mts +2 -0
  35. package/dist/runtime.mjs +3 -0
  36. package/dist/vite.cjs +68 -59
  37. package/dist/vite.d.cts +11 -17
  38. package/dist/vite.d.cts.map +1 -1
  39. package/dist/vite.d.mts +11 -17
  40. package/dist/vite.d.mts.map +1 -1
  41. package/dist/vite.mjs +66 -57
  42. package/dist/vite.mjs.map +1 -1
  43. package/package.json +23 -4
  44. package/dist/index.d.cts.map +0 -1
  45. package/dist/index.d.mts.map +0 -1
  46. package/dist/index.mjs.map +0 -1
  47. package/dist/options-BWcHrC-1.d.mts.map +0 -1
  48. package/dist/options-CgrZ2der.d.cts.map +0 -1
  49. package/dist/schema-loader-vNpUWFmU.mjs.map +0 -1
@@ -25,12 +25,15 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
25
25
  }) : target, mod));
26
26
 
27
27
  //#endregion
28
+ let node_fs_promises = require("node:fs/promises");
29
+ let node_path = require("node:path");
28
30
  let graphql = require("graphql");
29
31
  let fs_promises = require("fs/promises");
30
32
  let fs = require("fs");
31
33
  let path = require("path");
32
34
  let typescript = require("typescript");
33
35
  typescript = __toESM(typescript);
36
+ let smol_toml = require("smol-toml");
34
37
 
35
38
  //#region src/codegen/utils.ts
36
39
  /**
@@ -111,62 +114,63 @@ var JSImportCollector = class {
111
114
  return Array.from(map.entries()).sort((a, b) => a[0].localeCompare(b[0]));
112
115
  }
113
116
  };
114
- const RUNTIME_ENTRY_SOURCE = "../../dist/index.mjs";
117
+ const DEFAULT_RUNTIME_ENTRY_SOURCE = "../../dist/index.mjs";
118
+ const DEFAULT_ROOT_RUNTIME_ENTRY_SOURCE = "../dist/index.mjs";
115
119
  const TYPE_HIERARCHY_SOURCE = "../type-hierarchy";
116
120
  const ENUM_INPUT_METADATA_SOURCE = "../enum-input-metadata";
117
121
  const SCALAR_TYPES_SOURCE = "../scalar-types";
118
122
  const SCALAR_TYPES_NAMESPACE = "UserScalarTypes";
119
123
  const CODEGEN_IMPORT_SOURCE_MAP = {
120
124
  AcceptableVariables: {
121
- source: RUNTIME_ENTRY_SOURCE,
125
+ source: DEFAULT_RUNTIME_ENTRY_SOURCE,
122
126
  kind: "type"
123
127
  },
124
128
  UnresolvedVariables: {
125
- source: RUNTIME_ENTRY_SOURCE,
129
+ source: DEFAULT_RUNTIME_ENTRY_SOURCE,
126
130
  kind: "type"
127
131
  },
128
132
  DirectiveArgs: {
129
- source: RUNTIME_ENTRY_SOURCE,
133
+ source: DEFAULT_RUNTIME_ENTRY_SOURCE,
130
134
  kind: "type"
131
135
  },
132
136
  Selection: {
133
- source: RUNTIME_ENTRY_SOURCE,
137
+ source: DEFAULT_RUNTIME_ENTRY_SOURCE,
134
138
  kind: "type"
135
139
  },
136
140
  ShapeOf: {
137
- source: RUNTIME_ENTRY_SOURCE,
141
+ source: DEFAULT_RUNTIME_ENTRY_SOURCE,
138
142
  kind: "type"
139
143
  },
140
144
  VariablesOf: {
141
- source: RUNTIME_ENTRY_SOURCE,
145
+ source: DEFAULT_RUNTIME_ENTRY_SOURCE,
142
146
  kind: "type"
143
147
  },
144
148
  ValueOrThunk: {
145
- source: RUNTIME_ENTRY_SOURCE,
149
+ source: DEFAULT_RUNTIME_ENTRY_SOURCE,
146
150
  kind: "type"
147
151
  },
148
152
  FragmentSpread: {
149
- source: RUNTIME_ENTRY_SOURCE,
153
+ source: DEFAULT_RUNTIME_ENTRY_SOURCE,
150
154
  kind: "type"
151
155
  },
152
156
  createSelection: {
153
- source: RUNTIME_ENTRY_SOURCE,
157
+ source: DEFAULT_RUNTIME_ENTRY_SOURCE,
154
158
  kind: "value"
155
159
  },
156
160
  withOperationName: {
157
- source: RUNTIME_ENTRY_SOURCE,
161
+ source: DEFAULT_RUNTIME_ENTRY_SOURCE,
158
162
  kind: "value"
159
163
  },
160
164
  createSchemaType: {
161
- source: RUNTIME_ENTRY_SOURCE,
165
+ source: DEFAULT_RUNTIME_ENTRY_SOURCE,
162
166
  kind: "value"
163
167
  },
164
168
  registerSchemaTypeFactory: {
165
- source: RUNTIME_ENTRY_SOURCE,
169
+ source: DEFAULT_RUNTIME_ENTRY_SOURCE,
166
170
  kind: "value"
167
171
  },
168
172
  resolveRegisteredSchemaType: {
169
- source: RUNTIME_ENTRY_SOURCE,
173
+ source: DEFAULT_RUNTIME_ENTRY_SOURCE,
170
174
  kind: "value"
171
175
  },
172
176
  ENUM_INPUT_METADATA: {
@@ -186,10 +190,73 @@ const CODEGEN_IMPORT_SOURCE_MAP = {
186
190
  kind: "type"
187
191
  },
188
192
  EnumInputMetadataBuilder: {
189
- source: "../dist/index.mjs",
193
+ source: DEFAULT_ROOT_RUNTIME_ENTRY_SOURCE,
190
194
  kind: "value"
191
195
  }
192
196
  };
197
+ function createCodegenImportSourceMap(options) {
198
+ const runtimeEntrySource = options.runtimeEntrySource ?? DEFAULT_RUNTIME_ENTRY_SOURCE;
199
+ const rootRuntimeEntrySource = options.rootRuntimeEntrySource ?? DEFAULT_ROOT_RUNTIME_ENTRY_SOURCE;
200
+ return {
201
+ ...CODEGEN_IMPORT_SOURCE_MAP,
202
+ AcceptableVariables: {
203
+ source: runtimeEntrySource,
204
+ kind: "type"
205
+ },
206
+ UnresolvedVariables: {
207
+ source: runtimeEntrySource,
208
+ kind: "type"
209
+ },
210
+ DirectiveArgs: {
211
+ source: runtimeEntrySource,
212
+ kind: "type"
213
+ },
214
+ Selection: {
215
+ source: runtimeEntrySource,
216
+ kind: "type"
217
+ },
218
+ ShapeOf: {
219
+ source: runtimeEntrySource,
220
+ kind: "type"
221
+ },
222
+ VariablesOf: {
223
+ source: runtimeEntrySource,
224
+ kind: "type"
225
+ },
226
+ ValueOrThunk: {
227
+ source: runtimeEntrySource,
228
+ kind: "type"
229
+ },
230
+ FragmentSpread: {
231
+ source: runtimeEntrySource,
232
+ kind: "type"
233
+ },
234
+ createSelection: {
235
+ source: runtimeEntrySource,
236
+ kind: "value"
237
+ },
238
+ withOperationName: {
239
+ source: runtimeEntrySource,
240
+ kind: "value"
241
+ },
242
+ createSchemaType: {
243
+ source: runtimeEntrySource,
244
+ kind: "value"
245
+ },
246
+ registerSchemaTypeFactory: {
247
+ source: runtimeEntrySource,
248
+ kind: "value"
249
+ },
250
+ resolveRegisteredSchemaType: {
251
+ source: runtimeEntrySource,
252
+ kind: "value"
253
+ },
254
+ EnumInputMetadataBuilder: {
255
+ source: rootRuntimeEntrySource,
256
+ kind: "value"
257
+ }
258
+ };
259
+ }
193
260
 
194
261
  //#endregion
195
262
  //#region src/codegen/writer.ts
@@ -231,9 +298,10 @@ var Writer = class {
231
298
  importedTypes = /* @__PURE__ */ new Set();
232
299
  usesScalarTypeNamespaceImport = false;
233
300
  importFinalized = false;
234
- constructor(stream, options) {
301
+ constructor(stream, options, importSourceMap = CODEGEN_IMPORT_SOURCE_MAP) {
235
302
  this.stream = stream;
236
303
  this.options = options;
304
+ this.importSourceMap = importSourceMap;
237
305
  this.indent = options.indent ?? " ";
238
306
  }
239
307
  /**
@@ -415,7 +483,7 @@ var Writer = class {
415
483
  }
416
484
  writeMappedScalarImports() {
417
485
  if (!this.usesScalarTypeNamespaceImport) return;
418
- const source = CODEGEN_IMPORT_SOURCE_MAP.SCALAR_TYPE_NAMESPACE.source;
486
+ const source = this.importSourceMap.SCALAR_TYPE_NAMESPACE.source;
419
487
  const importSource = this.isUnderGlobalDir() ? source.replace(/^\.\.\//, "./") : source;
420
488
  this.stream.write(`import type { ${SCALAR_TYPES_NAMESPACE} } from '${importSource}';\n`);
421
489
  }
@@ -496,8 +564,8 @@ var SelectionWriter = class extends Writer {
496
564
  fieldCategoryMap;
497
565
  hasArgs;
498
566
  _declaredFieldNames;
499
- constructor(modelType, ctx, stream, options) {
500
- super(stream, options);
567
+ constructor(modelType, ctx, stream, options, importSourceMap) {
568
+ super(stream, options, importSourceMap);
501
569
  this.modelType = modelType;
502
570
  this.ctx = ctx;
503
571
  this.selectionTypeName = `${this.modelType.name}${options.selectionSuffix ?? "Selection"}`;
@@ -577,7 +645,7 @@ var SelectionWriter = class extends Writer {
577
645
  return "SCALAR";
578
646
  }
579
647
  prepareImports() {
580
- const imports = new JSImportCollector((stmt) => this.importStatement(stmt), CODEGEN_IMPORT_SOURCE_MAP);
648
+ const imports = new JSImportCollector((stmt) => this.importStatement(stmt), this.importSourceMap);
581
649
  imports.useMapped("DirectiveArgs");
582
650
  imports.useMapped("Selection");
583
651
  if (this.hasArgs) {
@@ -1203,7 +1271,7 @@ const COMMENT$1 = `/*
1203
1271
  * Any instance of this interface is immutable,
1204
1272
  * all the properties and functions can only be used to create new instances,
1205
1273
  * they cannot modify the current instance.
1206
- *
1274
+ *
1207
1275
  * So any instance of this interface is reuseable.
1208
1276
  */
1209
1277
  `;
@@ -1531,12 +1599,12 @@ var TypeHierarchyGraph = class {
1531
1599
  //#endregion
1532
1600
  //#region src/codegen/writers/enum-input-metadata.ts
1533
1601
  var EnumInputMetadataWriter = class EnumInputMetadataWriter extends Writer {
1534
- constructor(schema, stream, options) {
1535
- super(stream, options);
1602
+ constructor(schema, stream, options, importSourceMap) {
1603
+ super(stream, options, importSourceMap);
1536
1604
  this.schema = schema;
1537
1605
  }
1538
1606
  prepareImports() {
1539
- const imports = new JSImportCollector((stmt) => this.importStatement(stmt), CODEGEN_IMPORT_SOURCE_MAP);
1607
+ const imports = new JSImportCollector((stmt) => this.importStatement(stmt), this.importSourceMap);
1540
1608
  imports.useMapped("EnumInputMetadataBuilder");
1541
1609
  imports.emit();
1542
1610
  }
@@ -1607,7 +1675,7 @@ var EnumInputMetadataWriter = class EnumInputMetadataWriter extends Writer {
1607
1675
 
1608
1676
  //#endregion
1609
1677
  //#region \0raw:/home/runner/work/typedgql/typedgql/src/codegen/templates/async-runtime.template
1610
- var async_runtime_default = "import type { Selection } from \"../dist/index.mjs\";\nimport { TextBuilder, runtimeOf } from \"../dist/index.mjs\";\n\nexport type GraphQLExecutor = (\n request: string,\n variables: Record<string, unknown>,\n) => Promise<unknown>;\n\nexport type GraphQLSubscriber = (\n request: string,\n variables: Record<string, unknown>,\n) => AsyncIterable<unknown> | Promise<AsyncIterable<unknown>>;\n\n// Set global fallback executor used by `execute(...)`.\nexport function setGraphQLExecutor(executor: GraphQLExecutor) {\n graphQLExecutor = executor;\n}\n\n// Set global fallback subscriber used by `subscribe(...)`.\nexport function setGraphQLSubscriber(subscriber: GraphQLSubscriber) {\n graphQLSubscriber = subscriber;\n}\nexport type Simplify<T> = SimplifyDepth<T>;\ntype Primitive = string | number | boolean | bigint | symbol | null | undefined;\ntype Dec = [0,0,1,2,3,4,5,6,7,8,9];\ntype GraphQLRawResponse = {\n readonly data?: unknown;\n readonly errors?: unknown;\n};\nexport type SimplifyDepth<T, D extends number = 5> =\n D extends 0 ? T :\n T extends Primitive | Function ? T :\n T extends readonly (infer U)[] ? readonly SimplifyDepth<U, Dec[D]>[] :\n T extends object ? { [K in keyof T]: SimplifyDepth<T[K], Dec[D]> } & {} :\n T;\n\nexport async function execute<\n TData extends object,\n TVariables extends Record<string, unknown>,\n>(\n selection: Selection<\"Query\" | \"Mutation\", TData, TVariables>,\n options?: {\n readonly operationName?: string;\n readonly variables?: TVariables;\n readonly executor?: GraphQLExecutor;\n },\n): Promise<Simplify<TData>> {\n // Per-call override has priority over the globally registered executor.\n const executor = options?.executor ?? graphQLExecutor;\n if (executor === undefined) {\n throw new Error(\n \"Executor not set. Call 'setGraphQLExecutor' first or pass executor in options.\",\n );\n }\n\n const request = buildRequest(selection, options?.operationName);\n const rawResponse = exceptNullValues(\n await executor(request, options?.variables ?? {}),\n ) as GraphQLRawResponse;\n // GraphQL transport errors are surfaced as exceptions.\n if (rawResponse.errors) {\n throw new GraphQLError(rawResponse.errors);\n }\n return rawResponse.data as unknown as Simplify<TData>;\n}\n\nexport async function* subscribe<\n TData extends object,\n TVariables extends Record<string, unknown>,\n>(\n selection: Selection<\"Subscription\", TData, TVariables>,\n options?: {\n readonly operationName?: string;\n readonly variables?: TVariables;\n readonly subscriber?: GraphQLSubscriber;\n },\n): AsyncIterable<Simplify<TData>> {\n // Per-call override has priority over the globally registered subscriber.\n const subscriber = options?.subscriber ?? graphQLSubscriber;\n if (subscriber === undefined) {\n throw new Error(\n \"Subscriber not set. Call 'setGraphQLSubscriber' first or pass subscriber in options.\",\n );\n }\n\n const request = buildRequest(selection, options?.operationName);\n const stream = await subscriber(request, options?.variables ?? {});\n // Stream payloads follow standard GraphQL response shape.\n for await (const payload of stream) {\n const rawResponse = exceptNullValues(payload) as GraphQLRawResponse;\n if (rawResponse.errors) {\n throw new GraphQLError(rawResponse.errors);\n }\n yield rawResponse.data as unknown as Simplify<TData>;\n }\n}\n\nexport interface Response<TData> {\n readonly data?: TData;\n readonly error?: Error;\n}\n\nexport class GraphQLError extends Error {\n readonly errors: readonly GraphQLSubError[];\n\n constructor(errors: unknown) {\n super();\n this.errors = normalizeGraphQLErrors(errors);\n }\n}\n\nexport interface GraphQLSubError {\n readonly message: string;\n readonly path: string[];\n}\n\nlet graphQLExecutor: GraphQLExecutor | undefined = undefined;\nlet graphQLSubscriber: GraphQLSubscriber | undefined = undefined;\n\nfunction normalizeGraphQLErrors(errors: unknown): readonly GraphQLSubError[] {\n if (!Array.isArray(errors)) {\n return [{ message: \"Unknown GraphQL error\", path: [] }];\n }\n return errors.map((item) => {\n if (!item || typeof item !== \"object\") {\n return { message: String(item), path: [] };\n }\n const rec = item as Record<string, unknown>;\n return {\n message: typeof rec.message === \"string\" ? rec.message : \"Unknown GraphQL error\",\n path: Array.isArray(rec.path)\n ? rec.path.filter((p): p is string => typeof p === \"string\")\n : [],\n };\n });\n}\n\n// Build GraphQL document from selection tree and inferred variable declarations.\nfunction buildRequest<\n TData extends object,\n TVariables extends Record<string, unknown>,\n>(\n selection: Selection<\"Query\" | \"Mutation\" | \"Subscription\", TData, TVariables>,\n operationName?: string,\n): string {\n const runtime = runtimeOf(selection);\n const writer = new TextBuilder();\n writer.text(`${runtime.schemaType.name.toLowerCase()} ${operationName ?? runtime.operationName ?? \"\"}`);\n if (runtime.variableTypeMap.size !== 0) {\n writer.scope(\n {\n type: \"arguments\",\n multiLines: runtime.variableTypeMap.size > 2,\n suffix: \" \",\n },\n () => {\n for (const [name, registration] of runtime.variableTypeMap) {\n writer.separator();\n writer.text(`$${name}: ${registration.typeName}`);\n }\n },\n );\n }\n writer.text(selection.toString());\n writer.text(selection.toFragmentString());\n return writer.toString();\n}\n\n// Convert all nullable fields to `undefined` for easier TS optional-field ergonomics.\nfunction exceptNullValues<T>(value: T): T {\n if (value == null) return undefined as any;\n if (typeof value !== \"object\") return value;\n if (Array.isArray(value)) {\n return value.map((el) => el == null ? undefined : exceptNullValues(el)) as any;\n }\n const out: any = {};\n for (const k in value) {\n const v = value[k];\n out[k] = v != null ? exceptNullValues(v) : undefined;\n }\n return out;\n}\n";
1678
+ var async_runtime_default = "import type { Selection } from \"../dist/index.mjs\";\nimport { TextBuilder, runtimeOf } from \"../dist/index.mjs\";\n\nexport type GraphQLExecutor = (\n request: string,\n variables: Record<string, unknown>,\n) => Promise<unknown>;\n\nexport type GraphQLSubscriber = (\n request: string,\n variables: Record<string, unknown>,\n) => AsyncIterable<unknown> | Promise<AsyncIterable<unknown>>;\n\n// Set global fallback executor used by `execute(...)`.\nexport function setGraphQLExecutor(executor: GraphQLExecutor) {\n graphQLExecutor = executor;\n}\n\n// Set global fallback subscriber used by `subscribe(...)`.\nexport function setGraphQLSubscriber(subscriber: GraphQLSubscriber) {\n graphQLSubscriber = subscriber;\n}\nexport type Simplify<T> = SimplifyDepth<T>;\ntype Primitive = string | number | boolean | bigint | symbol | null | undefined;\ntype Dec = [0,0,1,2,3,4,5,6,7,8,9];\ntype IsEqual<A, B> =\n (<T>() => T extends A ? 1 : 2) extends\n (<T>() => T extends B ? 1 : 2)\n ? (<T>() => T extends B ? 1 : 2) extends\n (<T>() => T extends A ? 1 : 2)\n ? true\n : false\n : false;\ntype Includes<TItems extends readonly unknown[], TItem> =\n TItems extends readonly [infer Head, ...infer Tail]\n ? IsEqual<Head, TItem> extends true\n ? true\n : Includes<Tail, TItem>\n : false;\ntype GraphQLRawResponse = {\n readonly data?: unknown;\n readonly errors?: unknown;\n};\nexport type SimplifyDepth<\n T,\n D extends number = 5,\n Seen extends readonly unknown[] = [],\n> =\n D extends 0 ? T :\n T extends Primitive | Function ? T :\n Includes<Seen, T> extends true ? T :\n T extends readonly (infer U)[] ? readonly SimplifyDepth<U, Dec[D], [...Seen, T]>[] :\n T extends object ? { [K in keyof T]: SimplifyDepth<T[K], Dec[D], [...Seen, T]> } & {} :\n T;\n\nexport async function execute<\n TData extends object,\n TVariables extends Record<string, unknown>,\n>(\n selection: Selection<\"Query\" | \"Mutation\", TData, TVariables>,\n options?: {\n readonly operationName?: string;\n readonly variables?: TVariables;\n readonly executor?: GraphQLExecutor;\n },\n): Promise<Simplify<TData>> {\n // Per-call override has priority over the globally registered executor.\n const executor = options?.executor ?? graphQLExecutor;\n if (executor === undefined) {\n throw new Error(\n \"Executor not set. Call 'setGraphQLExecutor' first or pass executor in options.\",\n );\n }\n\n const request = buildRequest(selection, options?.operationName);\n const rawResponse = exceptNullValues(\n await executor(request, options?.variables ?? {}),\n ) as GraphQLRawResponse;\n // GraphQL transport errors are surfaced as exceptions.\n if (rawResponse.errors) {\n throw new GraphQLError(rawResponse.errors);\n }\n return rawResponse.data as unknown as Simplify<TData>;\n}\n\nexport async function* subscribe<\n TData extends object,\n TVariables extends Record<string, unknown>,\n>(\n selection: Selection<\"Subscription\", TData, TVariables>,\n options?: {\n readonly operationName?: string;\n readonly variables?: TVariables;\n readonly subscriber?: GraphQLSubscriber;\n },\n): AsyncIterable<Simplify<TData>> {\n // Per-call override has priority over the globally registered subscriber.\n const subscriber = options?.subscriber ?? graphQLSubscriber;\n if (subscriber === undefined) {\n throw new Error(\n \"Subscriber not set. Call 'setGraphQLSubscriber' first or pass subscriber in options.\",\n );\n }\n\n const request = buildRequest(selection, options?.operationName);\n const stream = await subscriber(request, options?.variables ?? {});\n // Stream payloads follow standard GraphQL response shape.\n for await (const payload of stream) {\n const rawResponse = exceptNullValues(payload) as GraphQLRawResponse;\n if (rawResponse.errors) {\n throw new GraphQLError(rawResponse.errors);\n }\n yield rawResponse.data as unknown as Simplify<TData>;\n }\n}\n\nexport interface Response<TData> {\n readonly data?: TData;\n readonly error?: Error;\n}\n\nexport class GraphQLError extends Error {\n readonly errors: readonly GraphQLSubError[];\n\n constructor(errors: unknown) {\n super();\n this.errors = normalizeGraphQLErrors(errors);\n }\n}\n\nexport interface GraphQLSubError {\n readonly message: string;\n readonly path: string[];\n}\n\nlet graphQLExecutor: GraphQLExecutor | undefined = undefined;\nlet graphQLSubscriber: GraphQLSubscriber | undefined = undefined;\n\nfunction normalizeGraphQLErrors(errors: unknown): readonly GraphQLSubError[] {\n if (!Array.isArray(errors)) {\n return [{ message: \"Unknown GraphQL error\", path: [] }];\n }\n return errors.map((item) => {\n if (!item || typeof item !== \"object\") {\n return { message: String(item), path: [] };\n }\n const rec = item as Record<string, unknown>;\n return {\n message: typeof rec.message === \"string\" ? rec.message : \"Unknown GraphQL error\",\n path: Array.isArray(rec.path)\n ? rec.path.filter((p): p is string => typeof p === \"string\")\n : [],\n };\n });\n}\n\n// Build GraphQL document from selection tree and inferred variable declarations.\nfunction buildRequest<\n TData extends object,\n TVariables extends Record<string, unknown>,\n>(\n selection: Selection<\"Query\" | \"Mutation\" | \"Subscription\", TData, TVariables>,\n operationName?: string,\n): string {\n const runtime = runtimeOf(selection);\n const writer = new TextBuilder();\n writer.text(`${runtime.schemaType.name.toLowerCase()} ${operationName ?? runtime.operationName ?? \"\"}`);\n if (runtime.variableTypeMap.size !== 0) {\n writer.scope(\n {\n type: \"arguments\",\n multiLines: runtime.variableTypeMap.size > 2,\n suffix: \" \",\n },\n () => {\n for (const [name, registration] of runtime.variableTypeMap) {\n writer.separator();\n writer.text(`$${name}: ${registration.typeName}`);\n }\n },\n );\n }\n writer.text(selection.toString());\n writer.text(selection.toFragmentString());\n return writer.toString();\n}\n\n// Convert all nullable fields to `undefined` for easier TS optional-field ergonomics.\nfunction exceptNullValues<T>(value: T): T {\n if (value == null) return undefined as any;\n if (typeof value !== \"object\") return value;\n if (Array.isArray(value)) {\n return value.map((el) => el == null ? undefined : exceptNullValues(el)) as any;\n }\n const out: any = {};\n for (const k in value) {\n const v = value[k];\n out[k] = v != null ? exceptNullValues(v) : undefined;\n }\n return out;\n}\n";
1611
1679
 
1612
1680
  //#endregion
1613
1681
  //#region src/codegen/scalar-type-declarations.ts
@@ -1638,12 +1706,123 @@ function analyzeScalarTypeDeclarations(source) {
1638
1706
  return { exportedNames };
1639
1707
  }
1640
1708
 
1709
+ //#endregion
1710
+ //#region src/codegen/prettier-formatter.ts
1711
+ let prettierInstance = void 0;
1712
+ let prettierDetected = false;
1713
+ /**
1714
+ * Detect and dynamically import prettier if available.
1715
+ * Returns null if prettier is not installed.
1716
+ */
1717
+ async function detectPrettier() {
1718
+ if (prettierDetected) return prettierInstance ?? null;
1719
+ prettierDetected = true;
1720
+ try {
1721
+ prettierInstance = await import("prettier");
1722
+ return prettierInstance;
1723
+ } catch {
1724
+ prettierInstance = null;
1725
+ return null;
1726
+ }
1727
+ }
1728
+ /**
1729
+ * Format TypeScript code using prettier if available.
1730
+ * Returns the original code if prettier is not installed or formatting fails.
1731
+ *
1732
+ * @param code - TypeScript code to format
1733
+ * @param filePath - File path for prettier config resolution
1734
+ * @returns Formatted code or original code if formatting fails
1735
+ */
1736
+ async function formatWithPrettier(code, filePath) {
1737
+ const prettier = await detectPrettier();
1738
+ if (!prettier) return code;
1739
+ try {
1740
+ const config = await prettier.resolveConfig(filePath);
1741
+ return await prettier.format(code, {
1742
+ ...config,
1743
+ parser: "typescript",
1744
+ filepath: filePath
1745
+ });
1746
+ } catch (error) {
1747
+ console.warn(`[typedgql] Failed to format ${filePath} with prettier: ${error.message}`);
1748
+ return code;
1749
+ }
1750
+ }
1751
+ /**
1752
+ * Check if prettier is available.
1753
+ * This is a lightweight check that doesn't actually import prettier.
1754
+ */
1755
+ async function isPrettierAvailable() {
1756
+ return await detectPrettier() !== null;
1757
+ }
1758
+
1759
+ //#endregion
1760
+ //#region src/codegen/buffered-stream.ts
1761
+ /**
1762
+ * A buffered write stream that collects content in memory
1763
+ * instead of writing directly to disk.
1764
+ * This allows post-processing (like prettier formatting) before writing.
1765
+ */
1766
+ var BufferedStream = class {
1767
+ buffer = [];
1768
+ ended = false;
1769
+ path;
1770
+ constructor(path) {
1771
+ this.path = path;
1772
+ }
1773
+ /**
1774
+ * Write content to the buffer.
1775
+ */
1776
+ write(chunk) {
1777
+ if (this.ended) throw new Error("Cannot write to ended stream");
1778
+ this.buffer.push(chunk);
1779
+ return true;
1780
+ }
1781
+ /**
1782
+ * Mark the stream as ended.
1783
+ * Returns a promise that resolves when the stream is closed.
1784
+ */
1785
+ end(callback) {
1786
+ this.ended = true;
1787
+ if (callback) callback();
1788
+ return Promise.resolve();
1789
+ }
1790
+ /**
1791
+ * Get the buffered content as a string.
1792
+ */
1793
+ getContent() {
1794
+ return this.buffer.join("");
1795
+ }
1796
+ /**
1797
+ * Write the buffered content to disk.
1798
+ */
1799
+ async flush(formatter) {
1800
+ let content = this.getContent();
1801
+ if (formatter) content = await formatter(content, this.path);
1802
+ await (0, fs_promises.writeFile)(this.path, content, "utf-8");
1803
+ }
1804
+ /**
1805
+ * Create a WriteStream-compatible interface for this buffered stream.
1806
+ * This allows it to be used with existing writer classes.
1807
+ */
1808
+ toWriteStream() {
1809
+ return {
1810
+ write: (chunk) => this.write(chunk),
1811
+ end: (callback) => {
1812
+ this.end(callback);
1813
+ }
1814
+ };
1815
+ }
1816
+ };
1817
+
1641
1818
  //#endregion
1642
1819
  //#region src/codegen/generator.ts
1643
1820
  /** Default output directory: node_modules/@ptdgrp/typedgql/__generated */
1644
1821
  const DEFAULT_TARGET_DIR = (0, path.resolve)(process.cwd(), "node_modules/@ptdgrp/typedgql/__generated");
1645
1822
  /** Parent package dir: node_modules/@ptdgrp/typedgql */
1646
1823
  const PACKAGE_DIR = (0, path.resolve)(process.cwd(), "node_modules/@ptdgrp/typedgql");
1824
+ const RUNTIME_PACKAGE_NAME = "@ptdgrp/typedgql/runtime";
1825
+ const GENERATED_FILE_BANNER = "/* eslint-disable */\n// This file was generated by @ptdgrp/typedgql. Do not edit it manually.\n\n";
1647
1826
  /** Field names reserved by the runtime SelectionNode implementation. */
1648
1827
  const RESERVED_FIELDS = new Set([
1649
1828
  "constructor",
@@ -1663,6 +1842,9 @@ const RESERVED_FIELDS = new Set([
1663
1842
  "toFragmentString"
1664
1843
  ]);
1665
1844
  var Generator = class {
1845
+ usePrettier = false;
1846
+ isCustomOutputDir = false;
1847
+ bufferedStreams = [];
1666
1848
  constructor(options) {
1667
1849
  this.options = options;
1668
1850
  }
@@ -1670,6 +1852,62 @@ var Generator = class {
1670
1852
  get targetDir() {
1671
1853
  return this.options.targetDir ?? DEFAULT_TARGET_DIR;
1672
1854
  }
1855
+ /**
1856
+ * Check if we should use prettier formatting.
1857
+ * Only enabled when using custom outputDir (not in node_modules).
1858
+ */
1859
+ async initializePrettier() {
1860
+ const targetDir = this.targetDir;
1861
+ this.isCustomOutputDir = !(0, path.normalize)(targetDir).includes("node_modules");
1862
+ if (this.options.prettier === false) {
1863
+ this.usePrettier = false;
1864
+ return;
1865
+ }
1866
+ if (this.options.prettier === true || this.isCustomOutputDir) {
1867
+ this.usePrettier = await isPrettierAvailable();
1868
+ if (this.usePrettier) console.log("[typedgql] Prettier detected, will format generated files");
1869
+ }
1870
+ }
1871
+ /**
1872
+ * Create a stream for writing generated code.
1873
+ * Uses BufferedStream when prettier formatting is enabled.
1874
+ */
1875
+ createCodeStream(path$1) {
1876
+ const writeBanner = (stream) => {
1877
+ stream.write(GENERATED_FILE_BANNER);
1878
+ return stream;
1879
+ };
1880
+ if (this.usePrettier) {
1881
+ const buffered = new BufferedStream(path$1);
1882
+ this.bufferedStreams.push(buffered);
1883
+ return writeBanner(buffered.toWriteStream());
1884
+ }
1885
+ return writeBanner((0, fs.createWriteStream)(path$1));
1886
+ }
1887
+ get rootRuntimeImportSource() {
1888
+ return this.usesPackageInternalRuntimeImports ? "../dist/index.mjs" : RUNTIME_PACKAGE_NAME;
1889
+ }
1890
+ get nestedRuntimeImportSource() {
1891
+ return this.usesPackageInternalRuntimeImports ? "../../dist/index.mjs" : RUNTIME_PACKAGE_NAME;
1892
+ }
1893
+ get usesPackageInternalRuntimeImports() {
1894
+ return (0, path.normalize)(this.targetDir) === (0, path.normalize)(DEFAULT_TARGET_DIR);
1895
+ }
1896
+ get generatedImportSourceMap() {
1897
+ return createCodegenImportSourceMap({
1898
+ runtimeEntrySource: this.nestedRuntimeImportSource,
1899
+ rootRuntimeEntrySource: this.rootRuntimeImportSource
1900
+ });
1901
+ }
1902
+ /**
1903
+ * Flush all buffered streams with prettier formatting.
1904
+ */
1905
+ async flushBufferedStreams() {
1906
+ if (this.bufferedStreams.length === 0) return;
1907
+ console.log(`[typedgql] Formatting ${this.bufferedStreams.length} files with prettier...`);
1908
+ await Promise.all(this.bufferedStreams.map((stream) => stream.flush(this.usePrettier ? formatWithPrettier : void 0)));
1909
+ this.bufferedStreams = [];
1910
+ }
1673
1911
  async generate() {
1674
1912
  const schema = await this.options.schemaLoader();
1675
1913
  this.validateSchema(schema);
@@ -1679,6 +1917,7 @@ var Generator = class {
1679
1917
  force: true
1680
1918
  });
1681
1919
  await (0, fs_promises.mkdir)(this.targetDir, { recursive: true });
1920
+ await this.initializePrettier();
1682
1921
  const typeHierarchy = new TypeHierarchyGraph(schema);
1683
1922
  const selectionTypes = [];
1684
1923
  const inputTypes = [];
@@ -1756,10 +1995,11 @@ var Generator = class {
1756
1995
  if (this.hasScalarTypes()) promises.push(this.generateScalarTypes());
1757
1996
  promises.push(this.writeIndex(schema, ctx));
1758
1997
  await Promise.all(promises);
1998
+ await this.flushBufferedStreams();
1759
1999
  if (this.options.targetDir === void 0) await this.writePackageEntrypoint(schema, ctx);
1760
2000
  }
1761
2001
  createSelectionWriter(modelType, ctx, stream, options) {
1762
- return new SelectionWriter(modelType, ctx, stream, options);
2002
+ return new SelectionWriter(modelType, ctx, stream, options, this.generatedImportSourceMap);
1763
2003
  }
1764
2004
  additionalExportedTypeNamesForSelection(_modelType, _ctx) {
1765
2005
  return [];
@@ -1770,7 +2010,8 @@ var Generator = class {
1770
2010
  const defaultSelectionNameMap = /* @__PURE__ */ new Map();
1771
2011
  const suffix = this.options?.selectionSuffix ?? "Selection";
1772
2012
  const promises = ctx.selectionTypes.map(async (type) => {
1773
- const stream = createStream((0, path.join)(dir, `${toKebabCase(`${type.name}${suffix}`)}.ts`));
2013
+ const selectionTypeName = `${type.name}${suffix}`;
2014
+ const stream = this.createCodeStream((0, path.join)(dir, `${toKebabCase(selectionTypeName)}.ts`));
1774
2015
  const writer = this.createSelectionWriter(type, ctx, stream, this.options);
1775
2016
  emptySelectionNameMap.set(type, writer.emptySelectionName);
1776
2017
  if (writer.defaultSelectionName !== void 0) defaultSelectionNameMap.set(type, writer.defaultSelectionName);
@@ -1778,7 +2019,7 @@ var Generator = class {
1778
2019
  await endStream(stream);
1779
2020
  });
1780
2021
  await Promise.all([...promises, (async () => {
1781
- const stream = createStream((0, path.join)(dir, "index.ts"));
2022
+ const stream = this.createCodeStream((0, path.join)(dir, "index.ts"));
1782
2023
  for (const type of ctx.selectionTypes) {
1783
2024
  const selectionTypeName = `${type.name}${suffix}`;
1784
2025
  const selectionFileName = toKebabCase(selectionTypeName);
@@ -1798,7 +2039,7 @@ var Generator = class {
1798
2039
  async generateInputTypes(inputTypes) {
1799
2040
  const dir = (0, path.join)(this.targetDir, "inputs");
1800
2041
  const promises = inputTypes.map(async (type) => {
1801
- const stream = createStream((0, path.join)(dir, `${toKebabCase(type.name)}.ts`));
2042
+ const stream = this.createCodeStream((0, path.join)(dir, `${toKebabCase(type.name)}.ts`));
1802
2043
  new InputWriter(type, stream, this.options).write();
1803
2044
  await stream.end();
1804
2045
  });
@@ -1807,35 +2048,35 @@ var Generator = class {
1807
2048
  async generateEnumTypes(enumTypes) {
1808
2049
  const dir = (0, path.join)(this.targetDir, "enums");
1809
2050
  const promises = enumTypes.map(async (type) => {
1810
- const stream = createStream((0, path.join)(dir, `${toKebabCase(type.name)}.ts`));
2051
+ const stream = this.createCodeStream((0, path.join)(dir, `${toKebabCase(type.name)}.ts`));
1811
2052
  new EnumWriter(type, stream, this.options).write();
1812
2053
  await stream.end();
1813
2054
  });
1814
2055
  await Promise.all([...promises, this.writeSimpleIndex(dir, enumTypes, true)]);
1815
2056
  }
1816
2057
  async generateTypeHierarchy(schema, typeHierarchy) {
1817
- const stream = createStream((0, path.join)(this.targetDir, "type-hierarchy.ts"));
2058
+ const stream = this.createCodeStream((0, path.join)(this.targetDir, "type-hierarchy.ts"));
1818
2059
  new TypeHierarchyWriter(schema, typeHierarchy, stream, this.options).write();
1819
2060
  await endStream(stream);
1820
2061
  }
1821
2062
  async generateEnumInputMetadata(schema) {
1822
- const stream = createStream((0, path.join)(this.targetDir, "enum-input-metadata.ts"));
1823
- new EnumInputMetadataWriter(schema, stream, this.options).write();
2063
+ const stream = this.createCodeStream((0, path.join)(this.targetDir, "enum-input-metadata.ts"));
2064
+ new EnumInputMetadataWriter(schema, stream, this.options, this.generatedImportSourceMap).write();
1824
2065
  await endStream(stream);
1825
2066
  }
1826
2067
  async writeSimpleIndex(dir, types, typeOnly = true) {
1827
- const stream = createStream((0, path.join)(dir, "index.ts"));
2068
+ const stream = this.createCodeStream((0, path.join)(dir, "index.ts"));
1828
2069
  const keyword = typeOnly ? "export type" : "export";
1829
2070
  for (const type of types) stream.write(`${keyword} {${type.name}} from './${toKebabCase(type.name)}';\n`);
1830
2071
  await stream.end();
1831
2072
  }
1832
2073
  async generateAsyncRuntime() {
1833
- const stream = createStream((0, path.join)(this.targetDir, "client-runtime.ts"));
1834
- stream.write(async_runtime_default);
2074
+ const stream = this.createCodeStream((0, path.join)(this.targetDir, "client-runtime.ts"));
2075
+ stream.write(async_runtime_default.replaceAll("../dist/index.mjs", this.rootRuntimeImportSource));
1835
2076
  await endStream(stream);
1836
2077
  }
1837
2078
  async generateScalarTypes() {
1838
- const stream = createStream((0, path.join)(this.targetDir, "scalar-types.ts"));
2079
+ const stream = this.createCodeStream((0, path.join)(this.targetDir, "scalar-types.ts"));
1839
2080
  const analysis = analyzeScalarTypeDeclarations(this.options.scalarTypeDeclarations);
1840
2081
  const code = this.options.scalarTypeDeclarations?.trim();
1841
2082
  if (code && code.length !== 0) {
@@ -1864,10 +2105,10 @@ var Generator = class {
1864
2105
  }
1865
2106
  }
1866
2107
  async writeIndex(schema, ctx) {
1867
- const stream = createStream((0, path.join)(this.targetDir, "index.ts"));
2108
+ const stream = this.createCodeStream((0, path.join)(this.targetDir, "index.ts"));
1868
2109
  const selectionSuffix = this.options.selectionSuffix ?? "Selection";
1869
- stream.write(`import type { Selection, ExecutableSelection, SchemaType, ShapeOf, VariablesOf } from "../dist/index.mjs";\n`);
1870
- stream.write(`import { FragmentRef, createSelection, resolveRegisteredSchemaType } from "../dist/index.mjs";\n`);
2110
+ stream.write(`import type { Selection, ExecutableSelection, SchemaType, ShapeOf, VariablesOf } from "${this.rootRuntimeImportSource}";\n`);
2111
+ stream.write(`import { FragmentRef, createSelection, resolveRegisteredSchemaType } from "${this.rootRuntimeImportSource}";\n`);
1871
2112
  for (const type of ctx.selectionTypes) {
1872
2113
  const selectionTypeName = `${type.name}${selectionSuffix}`;
1873
2114
  stream.write(`import type { ${selectionTypeName} } from "./selections/${toKebabCase(selectionTypeName)}";\n`);
@@ -1916,6 +2157,7 @@ var Generator = class {
1916
2157
  async writePackageEntrypoint(schema, ctx) {
1917
2158
  await (0, fs_promises.mkdir)(PACKAGE_DIR, { recursive: true });
1918
2159
  const indexStream = createStream((0, path.join)(PACKAGE_DIR, "index.ts"));
2160
+ indexStream.write(GENERATED_FILE_BANNER);
1919
2161
  this.writePackageIndexCode(indexStream, schema, ctx);
1920
2162
  await endStream(indexStream);
1921
2163
  await this.patchPackageJsonForGeneratedEntrypoint();
@@ -2023,8 +2265,8 @@ var Generator = class {
2023
2265
  return (this.options.scalarTypeDeclarations?.trim().length ?? 0) !== 0 || Object.keys(this.options.scalarTypeMap ?? {}).length !== 0;
2024
2266
  }
2025
2267
  };
2026
- function createStream(path$1) {
2027
- return (0, fs.createWriteStream)(path$1);
2268
+ function createStream(path$2) {
2269
+ return (0, fs.createWriteStream)(path$2);
2028
2270
  }
2029
2271
  function endStream(stream) {
2030
2272
  return new Promise((resolve, reject) => {
@@ -2053,6 +2295,59 @@ async function loadLocalSchema(location) {
2053
2295
  return (0, graphql.buildSchema)(await (0, fs_promises.readFile)(location, { encoding: "utf8" }));
2054
2296
  }
2055
2297
 
2298
+ //#endregion
2299
+ //#region src/codegen/config-loader.ts
2300
+ /**
2301
+ * Validate that the output directory is not inside node_modules.
2302
+ * @throws Error if the path is inside node_modules
2303
+ */
2304
+ function validateOutputDir(outputDir) {
2305
+ if ((0, node_path.normalize)(outputDir).includes("node_modules")) throw new Error(`Invalid outputDir: "${outputDir}". Output directory cannot be inside node_modules. Please specify a path outside node_modules, such as './src/__generated' or './__generated'.`);
2306
+ }
2307
+ /**
2308
+ * Load configuration from .typedgqlrc.toml file.
2309
+ *
2310
+ * @param configPath - Path to the config file (defaults to .typedgqlrc.toml in cwd)
2311
+ * @returns Parsed configuration object or undefined if file doesn't exist
2312
+ */
2313
+ async function loadConfig(configPath) {
2314
+ const path = configPath ?? (0, node_path.resolve)(process.cwd(), ".typedgqlrc.toml");
2315
+ try {
2316
+ const config = (0, smol_toml.parse)(await (0, node_fs_promises.readFile)(path, "utf-8"));
2317
+ if (config.outputDir && !config.targetDir) config.targetDir = config.outputDir;
2318
+ const outputPath = config.outputDir || config.targetDir;
2319
+ if (outputPath) validateOutputDir(outputPath);
2320
+ return config;
2321
+ } catch (error) {
2322
+ if (error.code === "ENOENT") return;
2323
+ throw new Error(`Failed to load config from ${path}: ${error.message}`);
2324
+ }
2325
+ }
2326
+ /**
2327
+ * Merge configuration from file with programmatic options.
2328
+ * Programmatic options take precedence over file config.
2329
+ *
2330
+ * @param fileConfig - Configuration loaded from .typedgqlrc.toml
2331
+ * @param programmaticConfig - Configuration passed programmatically
2332
+ * @returns Merged configuration
2333
+ */
2334
+ function mergeConfig(fileConfig, programmaticConfig) {
2335
+ let merged;
2336
+ if (!fileConfig) merged = programmaticConfig;
2337
+ else merged = {
2338
+ ...fileConfig,
2339
+ ...programmaticConfig,
2340
+ schemaHeaders: {
2341
+ ...fileConfig.schemaHeaders,
2342
+ ...programmaticConfig.schemaHeaders
2343
+ }
2344
+ };
2345
+ if (merged.outputDir && !merged.targetDir) merged.targetDir = merged.outputDir;
2346
+ const outputPath = merged.outputDir || merged.targetDir;
2347
+ if (outputPath) validateOutputDir(outputPath);
2348
+ return merged;
2349
+ }
2350
+
2056
2351
  //#endregion
2057
2352
  Object.defineProperty(exports, 'Generator', {
2058
2353
  enumerable: true,
@@ -2066,6 +2361,12 @@ Object.defineProperty(exports, '__toESM', {
2066
2361
  return __toESM;
2067
2362
  }
2068
2363
  });
2364
+ Object.defineProperty(exports, 'loadConfig', {
2365
+ enumerable: true,
2366
+ get: function () {
2367
+ return loadConfig;
2368
+ }
2369
+ });
2069
2370
  Object.defineProperty(exports, 'loadLocalSchema', {
2070
2371
  enumerable: true,
2071
2372
  get: function () {
@@ -2077,4 +2378,10 @@ Object.defineProperty(exports, 'loadRemoteSchema', {
2077
2378
  get: function () {
2078
2379
  return loadRemoteSchema;
2079
2380
  }
2381
+ });
2382
+ Object.defineProperty(exports, 'mergeConfig', {
2383
+ enumerable: true,
2384
+ get: function () {
2385
+ return mergeConfig;
2386
+ }
2080
2387
  });