@constructive-io/graphql-codegen 4.41.0 → 4.41.1

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.
@@ -7,9 +7,5 @@ export interface MultiTargetExecutorInput {
7
7
  endpoint: string;
8
8
  ormImportPath: string;
9
9
  }
10
- export interface ExecutorOptions {
11
- /** Enable NodeHttpAdapter for *.localhost subdomain routing */
12
- nodeHttpAdapter?: boolean;
13
- }
14
- export declare function generateExecutorFile(toolName: string, options?: ExecutorOptions): GeneratedFile;
15
- export declare function generateMultiTargetExecutorFile(toolName: string, targets: MultiTargetExecutorInput[], options?: ExecutorOptions): GeneratedFile;
10
+ export declare function generateExecutorFile(toolName: string): GeneratedFile;
11
+ export declare function generateMultiTargetExecutorFile(toolName: string, targets: MultiTargetExecutorInput[]): GeneratedFile;
@@ -44,12 +44,8 @@ function createImportDeclaration(moduleSpecifier, namedImports, typeOnly = false
44
44
  decl.importKind = typeOnly ? 'type' : 'value';
45
45
  return decl;
46
46
  }
47
- function generateExecutorFile(toolName, options) {
47
+ function generateExecutorFile(toolName) {
48
48
  const statements = [];
49
- // Import NodeHttpAdapter for *.localhost subdomain routing
50
- if (options?.nodeHttpAdapter) {
51
- statements.push(createImportDeclaration('./node-fetch', ['NodeHttpAdapter']));
52
- }
53
49
  statements.push(createImportDeclaration('appstash', ['createConfigStore']));
54
50
  statements.push(createImportDeclaration('../orm', ['createClient']));
55
51
  statements.push(t.variableDeclaration('const', [
@@ -109,26 +105,12 @@ function generateExecutorFile(toolName, options) {
109
105
  ]))),
110
106
  ])),
111
107
  ])),
112
- // Build createClient config — use NodeHttpAdapter for *.localhost endpoints
113
- ...(options?.nodeHttpAdapter
114
- ? [
115
- t.returnStatement(t.callExpression(t.identifier('createClient'), [
116
- t.objectExpression([
117
- t.objectProperty(t.identifier('adapter'), t.newExpression(t.identifier('NodeHttpAdapter'), [
118
- t.memberExpression(t.identifier('ctx'), t.identifier('endpoint')),
119
- t.identifier('headers'),
120
- ])),
121
- ]),
122
- ])),
123
- ]
124
- : [
125
- t.returnStatement(t.callExpression(t.identifier('createClient'), [
126
- t.objectExpression([
127
- t.objectProperty(t.identifier('endpoint'), t.memberExpression(t.identifier('ctx'), t.identifier('endpoint'))),
128
- t.objectProperty(t.identifier('headers'), t.identifier('headers')),
129
- ]),
130
- ])),
108
+ t.returnStatement(t.callExpression(t.identifier('createClient'), [
109
+ t.objectExpression([
110
+ t.objectProperty(t.identifier('endpoint'), t.memberExpression(t.identifier('ctx'), t.identifier('endpoint'))),
111
+ t.objectProperty(t.identifier('headers'), t.identifier('headers')),
131
112
  ]),
113
+ ])),
132
114
  ]);
133
115
  const getClientFunc = t.functionDeclaration(t.identifier('getClient'), [contextNameParam], getClientBody);
134
116
  statements.push(t.exportNamedDeclaration(getClientFunc));
@@ -139,12 +121,8 @@ function generateExecutorFile(toolName, options) {
139
121
  content: header + '\n' + code,
140
122
  };
141
123
  }
142
- function generateMultiTargetExecutorFile(toolName, targets, options) {
124
+ function generateMultiTargetExecutorFile(toolName, targets) {
143
125
  const statements = [];
144
- // Import NodeHttpAdapter for *.localhost subdomain routing
145
- if (options?.nodeHttpAdapter) {
146
- statements.push(createImportDeclaration('./node-fetch', ['NodeHttpAdapter']));
147
- }
148
126
  statements.push(createImportDeclaration('appstash', ['createConfigStore']));
149
127
  for (const target of targets) {
150
128
  const aliasName = `create${target.name[0].toUpperCase()}${target.name.slice(1)}Client`;
@@ -235,26 +213,12 @@ function generateMultiTargetExecutorFile(toolName, targets, options) {
235
213
  ]), t.blockStatement([
236
214
  t.expressionStatement(t.assignmentExpression('=', t.identifier('endpoint'), t.logicalExpression('||', t.memberExpression(t.identifier('defaultEndpoints'), t.identifier('targetName'), true), t.stringLiteral('')))),
237
215
  ])),
238
- // Build createClient config — use NodeHttpAdapter for *.localhost endpoints
239
- ...(options?.nodeHttpAdapter
240
- ? [
241
- t.returnStatement(t.callExpression(t.identifier('createFn'), [
242
- t.objectExpression([
243
- t.objectProperty(t.identifier('adapter'), t.newExpression(t.identifier('NodeHttpAdapter'), [
244
- t.identifier('endpoint'),
245
- t.identifier('headers'),
246
- ])),
247
- ]),
248
- ])),
249
- ]
250
- : [
251
- t.returnStatement(t.callExpression(t.identifier('createFn'), [
252
- t.objectExpression([
253
- t.objectProperty(t.identifier('endpoint'), t.identifier('endpoint')),
254
- t.objectProperty(t.identifier('headers'), t.identifier('headers')),
255
- ]),
256
- ])),
216
+ t.returnStatement(t.callExpression(t.identifier('createFn'), [
217
+ t.objectExpression([
218
+ t.objectProperty(t.identifier('endpoint'), t.identifier('endpoint')),
219
+ t.objectProperty(t.identifier('headers'), t.identifier('headers')),
257
220
  ]),
221
+ ])),
258
222
  ]);
259
223
  const getClientFunc = t.functionDeclaration(t.identifier('getClient'), [targetNameParam, contextNameParam], getClientBody);
260
224
  statements.push(t.exportNamedDeclaration(getClientFunc));
@@ -39,8 +39,6 @@ export interface GenerateMultiTargetCliOptions {
39
39
  toolName: string;
40
40
  builtinNames?: BuiltinNames;
41
41
  targets: MultiTargetCliTarget[];
42
- /** Enable NodeHttpAdapter for *.localhost subdomain routing */
43
- nodeHttpAdapter?: boolean;
44
42
  /** Generate a runnable index.ts entry point */
45
43
  entryPoint?: boolean;
46
44
  }
@@ -19,11 +19,7 @@ function generateCli(options) {
19
19
  const toolName = typeof cliConfig === 'object' && cliConfig.toolName
20
20
  ? cliConfig.toolName
21
21
  : 'app';
22
- // Use top-level nodeHttpAdapter from config (auto-enabled for CLI by generate.ts)
23
- const useNodeHttpAdapter = !!config.nodeHttpAdapter;
24
- const executorFile = (0, executor_generator_1.generateExecutorFile)(toolName, {
25
- nodeHttpAdapter: useNodeHttpAdapter,
26
- });
22
+ const executorFile = (0, executor_generator_1.generateExecutorFile)(toolName);
27
23
  files.push(executorFile);
28
24
  const utilsFile = (0, utils_generator_1.generateUtilsFile)();
29
25
  files.push(utilsFile);
@@ -32,10 +28,6 @@ function generateCli(options) {
32
28
  if (hasAnyEmbeddings) {
33
29
  files.push((0, utils_generator_1.generateEmbedderFile)());
34
30
  }
35
- // Generate node HTTP adapter if configured (for *.localhost subdomain routing)
36
- if (useNodeHttpAdapter) {
37
- files.push((0, utils_generator_1.generateNodeFetchFile)());
38
- }
39
31
  const contextFile = (0, infra_generator_1.generateContextCommand)(toolName);
40
32
  files.push(contextFile);
41
33
  const authFile = (0, infra_generator_1.generateAuthCommand)(toolName);
@@ -97,9 +89,7 @@ function generateMultiTargetCli(options) {
97
89
  endpoint: t.endpoint,
98
90
  ormImportPath: t.ormImportPath,
99
91
  }));
100
- const executorFile = (0, executor_generator_1.generateMultiTargetExecutorFile)(toolName, executorInputs, {
101
- nodeHttpAdapter: !!options.nodeHttpAdapter,
102
- });
92
+ const executorFile = (0, executor_generator_1.generateMultiTargetExecutorFile)(toolName, executorInputs);
103
93
  files.push(executorFile);
104
94
  const utilsFile = (0, utils_generator_1.generateUtilsFile)();
105
95
  files.push(utilsFile);
@@ -108,10 +98,6 @@ function generateMultiTargetCli(options) {
108
98
  if (hasAnyMtEmbeddings) {
109
99
  files.push((0, utils_generator_1.generateEmbedderFile)());
110
100
  }
111
- // Generate node HTTP adapter if configured (for *.localhost subdomain routing)
112
- if (options.nodeHttpAdapter) {
113
- files.push((0, utils_generator_1.generateNodeFetchFile)());
114
- }
115
101
  const contextFile = (0, infra_generator_1.generateMultiTargetContextCommand)(toolName, builtinNames.context, targets.map((t) => ({ name: t.name, endpoint: t.endpoint })));
116
102
  files.push(contextFile);
117
103
  const authFile = (0, infra_generator_1.generateAuthCommandWithName)(toolName, builtinNames.auth);
@@ -8,14 +8,6 @@ import type { GeneratedFile } from './executor-generator';
8
8
  * and mutation input parsing.
9
9
  */
10
10
  export declare function generateUtilsFile(): GeneratedFile;
11
- /**
12
- * Generate a node-fetch.ts file with NodeHttpAdapter for CLI.
13
- *
14
- * Provides a GraphQLAdapter implementation using node:http/node:https
15
- * instead of the Fetch API. This cleanly handles *.localhost subdomain
16
- * routing (DNS resolution + Host header) without any global patching.
17
- */
18
- export declare function generateNodeFetchFile(): GeneratedFile;
19
11
  /**
20
12
  * Generate an index.ts entry point file for the CLI.
21
13
  *
@@ -34,7 +34,6 @@ var __importStar = (this && this.__importStar) || (function () {
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
36
  exports.generateUtilsFile = generateUtilsFile;
37
- exports.generateNodeFetchFile = generateNodeFetchFile;
38
37
  exports.generateEntryPointFile = generateEntryPointFile;
39
38
  exports.generateEmbedderFile = generateEmbedderFile;
40
39
  const fs = __importStar(require("fs"));
@@ -79,19 +78,6 @@ function generateUtilsFile() {
79
78
  content: readTemplateFile('cli-utils.ts', 'CLI utility functions for type coercion and input handling'),
80
79
  };
81
80
  }
82
- /**
83
- * Generate a node-fetch.ts file with NodeHttpAdapter for CLI.
84
- *
85
- * Provides a GraphQLAdapter implementation using node:http/node:https
86
- * instead of the Fetch API. This cleanly handles *.localhost subdomain
87
- * routing (DNS resolution + Host header) without any global patching.
88
- */
89
- function generateNodeFetchFile() {
90
- return {
91
- fileName: 'node-fetch.ts',
92
- content: readTemplateFile('node-fetch.ts', 'Node HTTP adapter for localhost subdomain routing'),
93
- };
94
- }
95
81
  /**
96
82
  * Generate an index.ts entry point file for the CLI.
97
83
  *
@@ -31,6 +31,4 @@ export declare function generateSelectTypesFile(): GeneratedClientFile;
31
31
  /**
32
32
  * Generate the main index.ts with createClient factory
33
33
  */
34
- export declare function generateCreateClientFile(tables: Table[], hasCustomQueries: boolean, hasCustomMutations: boolean, options?: {
35
- nodeHttpAdapter?: boolean;
36
- }): GeneratedClientFile;
34
+ export declare function generateCreateClientFile(tables: Table[], hasCustomQueries: boolean, hasCustomMutations: boolean): GeneratedClientFile;
@@ -126,7 +126,7 @@ function createImportDeclaration(moduleSpecifier, namedImports, typeOnly = false
126
126
  /**
127
127
  * Generate the main index.ts with createClient factory
128
128
  */
129
- function generateCreateClientFile(tables, hasCustomQueries, hasCustomMutations, options) {
129
+ function generateCreateClientFile(tables, hasCustomQueries, hasCustomMutations) {
130
130
  const statements = [];
131
131
  // Add imports
132
132
  // Import OrmClient (value) and OrmClientConfig (type) separately
@@ -94,7 +94,7 @@ function generateOrm(options) {
94
94
  const typesBarrel = (0, barrel_1.generateTypesBarrel)(useSharedTypes);
95
95
  files.push({ path: typesBarrel.fileName, content: typesBarrel.content });
96
96
  // 7. Generate main index.ts with createClient
97
- const indexFile = (0, client_generator_1.generateCreateClientFile)(tables, hasCustomQueries, hasCustomMutations, { nodeHttpAdapter: !!options.config.nodeHttpAdapter });
97
+ const indexFile = (0, client_generator_1.generateCreateClientFile)(tables, hasCustomQueries, hasCustomMutations);
98
98
  files.push({ path: indexFile.fileName, content: indexFile.content });
99
99
  return {
100
100
  files,
package/core/generate.js CHANGED
@@ -89,9 +89,6 @@ async function generate(options = {}, internalOptions) {
89
89
  const runReactQuery = config.reactQuery ?? false;
90
90
  const runCli = internalOptions?.skipCli ? false : !!config.cli;
91
91
  const runOrm = runReactQuery || !!config.cli || (options.orm !== undefined ? !!options.orm : false);
92
- // Auto-enable nodeHttpAdapter when CLI is enabled, unless explicitly set to false
93
- const useNodeHttpAdapter = options.nodeHttpAdapter === true ||
94
- (runCli && options.nodeHttpAdapter !== false);
95
92
  const schemaEnabled = !!options.schema?.enabled;
96
93
  if (!schemaEnabled && !runReactQuery && !runOrm && !runCli) {
97
94
  return {
@@ -226,22 +223,13 @@ async function generate(options = {}, internalOptions) {
226
223
  mutations: customOperations.mutations,
227
224
  typeRegistry: customOperations.typeRegistry,
228
225
  },
229
- config: { ...config, nodeHttpAdapter: useNodeHttpAdapter },
226
+ config,
230
227
  sharedTypesPath: bothEnabled ? '..' : undefined,
231
228
  });
232
229
  filesToWrite.push(...files.map((file) => ({
233
230
  ...file,
234
231
  path: node_path_1.default.posix.join('orm', file.path),
235
232
  })));
236
- // Generate NodeHttpAdapter in ORM output when enabled
237
- if (useNodeHttpAdapter) {
238
- const { generateNodeFetchFile } = await Promise.resolve().then(() => __importStar(require('./codegen/cli/utils-generator')));
239
- const nodeFetchFile = generateNodeFetchFile();
240
- filesToWrite.push({
241
- path: node_path_1.default.posix.join('orm', nodeFetchFile.fileName),
242
- content: nodeFetchFile.content,
243
- });
244
- }
245
233
  }
246
234
  // Generate CLI commands
247
235
  if (runCli) {
@@ -252,7 +240,7 @@ async function generate(options = {}, internalOptions) {
252
240
  queries: customOperations.queries,
253
241
  mutations: customOperations.mutations,
254
242
  },
255
- config: { ...config, nodeHttpAdapter: useNodeHttpAdapter },
243
+ config,
256
244
  typeRegistry: customOperations.typeRegistry,
257
245
  });
258
246
  filesToWrite.push(...files.map((file) => ({
@@ -582,16 +570,11 @@ async function generateMulti(options) {
582
570
  if (useUnifiedCli && cliTargets.length > 0 && !dryRun) {
583
571
  const cliConfig = typeof unifiedCli === 'object' ? unifiedCli : {};
584
572
  const toolName = cliConfig.toolName ?? 'app';
585
- // Auto-enable nodeHttpAdapter for unified CLI unless explicitly disabled
586
- // Check first target config for explicit nodeHttpAdapter setting
587
573
  const firstTargetConfig = configs[names[0]];
588
- const multiNodeHttpAdapter = firstTargetConfig?.nodeHttpAdapter === true ||
589
- (firstTargetConfig?.nodeHttpAdapter !== false);
590
574
  const { files } = (0, cli_1.generateMultiTargetCli)({
591
575
  toolName,
592
576
  builtinNames: cliConfig.builtinNames,
593
577
  targets: cliTargets,
594
- nodeHttpAdapter: multiNodeHttpAdapter,
595
578
  entryPoint: cliConfig.entryPoint,
596
579
  });
597
580
  const cliFilesToWrite = files.map((file) => ({
@@ -7,9 +7,5 @@ export interface MultiTargetExecutorInput {
7
7
  endpoint: string;
8
8
  ormImportPath: string;
9
9
  }
10
- export interface ExecutorOptions {
11
- /** Enable NodeHttpAdapter for *.localhost subdomain routing */
12
- nodeHttpAdapter?: boolean;
13
- }
14
- export declare function generateExecutorFile(toolName: string, options?: ExecutorOptions): GeneratedFile;
15
- export declare function generateMultiTargetExecutorFile(toolName: string, targets: MultiTargetExecutorInput[], options?: ExecutorOptions): GeneratedFile;
10
+ export declare function generateExecutorFile(toolName: string): GeneratedFile;
11
+ export declare function generateMultiTargetExecutorFile(toolName: string, targets: MultiTargetExecutorInput[]): GeneratedFile;
@@ -7,12 +7,8 @@ function createImportDeclaration(moduleSpecifier, namedImports, typeOnly = false
7
7
  decl.importKind = typeOnly ? 'type' : 'value';
8
8
  return decl;
9
9
  }
10
- export function generateExecutorFile(toolName, options) {
10
+ export function generateExecutorFile(toolName) {
11
11
  const statements = [];
12
- // Import NodeHttpAdapter for *.localhost subdomain routing
13
- if (options?.nodeHttpAdapter) {
14
- statements.push(createImportDeclaration('./node-fetch', ['NodeHttpAdapter']));
15
- }
16
12
  statements.push(createImportDeclaration('appstash', ['createConfigStore']));
17
13
  statements.push(createImportDeclaration('../orm', ['createClient']));
18
14
  statements.push(t.variableDeclaration('const', [
@@ -72,26 +68,12 @@ export function generateExecutorFile(toolName, options) {
72
68
  ]))),
73
69
  ])),
74
70
  ])),
75
- // Build createClient config — use NodeHttpAdapter for *.localhost endpoints
76
- ...(options?.nodeHttpAdapter
77
- ? [
78
- t.returnStatement(t.callExpression(t.identifier('createClient'), [
79
- t.objectExpression([
80
- t.objectProperty(t.identifier('adapter'), t.newExpression(t.identifier('NodeHttpAdapter'), [
81
- t.memberExpression(t.identifier('ctx'), t.identifier('endpoint')),
82
- t.identifier('headers'),
83
- ])),
84
- ]),
85
- ])),
86
- ]
87
- : [
88
- t.returnStatement(t.callExpression(t.identifier('createClient'), [
89
- t.objectExpression([
90
- t.objectProperty(t.identifier('endpoint'), t.memberExpression(t.identifier('ctx'), t.identifier('endpoint'))),
91
- t.objectProperty(t.identifier('headers'), t.identifier('headers')),
92
- ]),
93
- ])),
71
+ t.returnStatement(t.callExpression(t.identifier('createClient'), [
72
+ t.objectExpression([
73
+ t.objectProperty(t.identifier('endpoint'), t.memberExpression(t.identifier('ctx'), t.identifier('endpoint'))),
74
+ t.objectProperty(t.identifier('headers'), t.identifier('headers')),
94
75
  ]),
76
+ ])),
95
77
  ]);
96
78
  const getClientFunc = t.functionDeclaration(t.identifier('getClient'), [contextNameParam], getClientBody);
97
79
  statements.push(t.exportNamedDeclaration(getClientFunc));
@@ -102,12 +84,8 @@ export function generateExecutorFile(toolName, options) {
102
84
  content: header + '\n' + code,
103
85
  };
104
86
  }
105
- export function generateMultiTargetExecutorFile(toolName, targets, options) {
87
+ export function generateMultiTargetExecutorFile(toolName, targets) {
106
88
  const statements = [];
107
- // Import NodeHttpAdapter for *.localhost subdomain routing
108
- if (options?.nodeHttpAdapter) {
109
- statements.push(createImportDeclaration('./node-fetch', ['NodeHttpAdapter']));
110
- }
111
89
  statements.push(createImportDeclaration('appstash', ['createConfigStore']));
112
90
  for (const target of targets) {
113
91
  const aliasName = `create${target.name[0].toUpperCase()}${target.name.slice(1)}Client`;
@@ -198,26 +176,12 @@ export function generateMultiTargetExecutorFile(toolName, targets, options) {
198
176
  ]), t.blockStatement([
199
177
  t.expressionStatement(t.assignmentExpression('=', t.identifier('endpoint'), t.logicalExpression('||', t.memberExpression(t.identifier('defaultEndpoints'), t.identifier('targetName'), true), t.stringLiteral('')))),
200
178
  ])),
201
- // Build createClient config — use NodeHttpAdapter for *.localhost endpoints
202
- ...(options?.nodeHttpAdapter
203
- ? [
204
- t.returnStatement(t.callExpression(t.identifier('createFn'), [
205
- t.objectExpression([
206
- t.objectProperty(t.identifier('adapter'), t.newExpression(t.identifier('NodeHttpAdapter'), [
207
- t.identifier('endpoint'),
208
- t.identifier('headers'),
209
- ])),
210
- ]),
211
- ])),
212
- ]
213
- : [
214
- t.returnStatement(t.callExpression(t.identifier('createFn'), [
215
- t.objectExpression([
216
- t.objectProperty(t.identifier('endpoint'), t.identifier('endpoint')),
217
- t.objectProperty(t.identifier('headers'), t.identifier('headers')),
218
- ]),
219
- ])),
179
+ t.returnStatement(t.callExpression(t.identifier('createFn'), [
180
+ t.objectExpression([
181
+ t.objectProperty(t.identifier('endpoint'), t.identifier('endpoint')),
182
+ t.objectProperty(t.identifier('headers'), t.identifier('headers')),
220
183
  ]),
184
+ ])),
221
185
  ]);
222
186
  const getClientFunc = t.functionDeclaration(t.identifier('getClient'), [targetNameParam, contextNameParam], getClientBody);
223
187
  statements.push(t.exportNamedDeclaration(getClientFunc));
@@ -39,8 +39,6 @@ export interface GenerateMultiTargetCliOptions {
39
39
  toolName: string;
40
40
  builtinNames?: BuiltinNames;
41
41
  targets: MultiTargetCliTarget[];
42
- /** Enable NodeHttpAdapter for *.localhost subdomain routing */
43
- nodeHttpAdapter?: boolean;
44
42
  /** Generate a runnable index.ts entry point */
45
43
  entryPoint?: boolean;
46
44
  }
@@ -5,7 +5,7 @@ import { generateExecutorFile, generateMultiTargetExecutorFile } from './executo
5
5
  import { generateHelpersFile } from './helpers-generator';
6
6
  import { generateAuthCommand, generateAuthCommandWithName, generateContextCommand, generateMultiTargetContextCommand, } from './infra-generator';
7
7
  import { generateTableCommand } from './table-command-generator';
8
- import { generateUtilsFile, generateNodeFetchFile, generateEntryPointFile, generateEmbedderFile } from './utils-generator';
8
+ import { generateUtilsFile, generateEntryPointFile, generateEmbedderFile } from './utils-generator';
9
9
  export function generateCli(options) {
10
10
  const { tables, customOperations, config } = options;
11
11
  const files = [];
@@ -13,11 +13,7 @@ export function generateCli(options) {
13
13
  const toolName = typeof cliConfig === 'object' && cliConfig.toolName
14
14
  ? cliConfig.toolName
15
15
  : 'app';
16
- // Use top-level nodeHttpAdapter from config (auto-enabled for CLI by generate.ts)
17
- const useNodeHttpAdapter = !!config.nodeHttpAdapter;
18
- const executorFile = generateExecutorFile(toolName, {
19
- nodeHttpAdapter: useNodeHttpAdapter,
20
- });
16
+ const executorFile = generateExecutorFile(toolName);
21
17
  files.push(executorFile);
22
18
  const utilsFile = generateUtilsFile();
23
19
  files.push(utilsFile);
@@ -26,10 +22,6 @@ export function generateCli(options) {
26
22
  if (hasAnyEmbeddings) {
27
23
  files.push(generateEmbedderFile());
28
24
  }
29
- // Generate node HTTP adapter if configured (for *.localhost subdomain routing)
30
- if (useNodeHttpAdapter) {
31
- files.push(generateNodeFetchFile());
32
- }
33
25
  const contextFile = generateContextCommand(toolName);
34
26
  files.push(contextFile);
35
27
  const authFile = generateAuthCommand(toolName);
@@ -91,9 +83,7 @@ export function generateMultiTargetCli(options) {
91
83
  endpoint: t.endpoint,
92
84
  ormImportPath: t.ormImportPath,
93
85
  }));
94
- const executorFile = generateMultiTargetExecutorFile(toolName, executorInputs, {
95
- nodeHttpAdapter: !!options.nodeHttpAdapter,
96
- });
86
+ const executorFile = generateMultiTargetExecutorFile(toolName, executorInputs);
97
87
  files.push(executorFile);
98
88
  const utilsFile = generateUtilsFile();
99
89
  files.push(utilsFile);
@@ -102,10 +92,6 @@ export function generateMultiTargetCli(options) {
102
92
  if (hasAnyMtEmbeddings) {
103
93
  files.push(generateEmbedderFile());
104
94
  }
105
- // Generate node HTTP adapter if configured (for *.localhost subdomain routing)
106
- if (options.nodeHttpAdapter) {
107
- files.push(generateNodeFetchFile());
108
- }
109
95
  const contextFile = generateMultiTargetContextCommand(toolName, builtinNames.context, targets.map((t) => ({ name: t.name, endpoint: t.endpoint })));
110
96
  files.push(contextFile);
111
97
  const authFile = generateAuthCommandWithName(toolName, builtinNames.auth);
@@ -8,14 +8,6 @@ import type { GeneratedFile } from './executor-generator';
8
8
  * and mutation input parsing.
9
9
  */
10
10
  export declare function generateUtilsFile(): GeneratedFile;
11
- /**
12
- * Generate a node-fetch.ts file with NodeHttpAdapter for CLI.
13
- *
14
- * Provides a GraphQLAdapter implementation using node:http/node:https
15
- * instead of the Fetch API. This cleanly handles *.localhost subdomain
16
- * routing (DNS resolution + Host header) without any global patching.
17
- */
18
- export declare function generateNodeFetchFile(): GeneratedFile;
19
11
  /**
20
12
  * Generate an index.ts entry point file for the CLI.
21
13
  *
@@ -40,19 +40,6 @@ export function generateUtilsFile() {
40
40
  content: readTemplateFile('cli-utils.ts', 'CLI utility functions for type coercion and input handling'),
41
41
  };
42
42
  }
43
- /**
44
- * Generate a node-fetch.ts file with NodeHttpAdapter for CLI.
45
- *
46
- * Provides a GraphQLAdapter implementation using node:http/node:https
47
- * instead of the Fetch API. This cleanly handles *.localhost subdomain
48
- * routing (DNS resolution + Host header) without any global patching.
49
- */
50
- export function generateNodeFetchFile() {
51
- return {
52
- fileName: 'node-fetch.ts',
53
- content: readTemplateFile('node-fetch.ts', 'Node HTTP adapter for localhost subdomain routing'),
54
- };
55
- }
56
43
  /**
57
44
  * Generate an index.ts entry point file for the CLI.
58
45
  *
@@ -31,6 +31,4 @@ export declare function generateSelectTypesFile(): GeneratedClientFile;
31
31
  /**
32
32
  * Generate the main index.ts with createClient factory
33
33
  */
34
- export declare function generateCreateClientFile(tables: Table[], hasCustomQueries: boolean, hasCustomMutations: boolean, options?: {
35
- nodeHttpAdapter?: boolean;
36
- }): GeneratedClientFile;
34
+ export declare function generateCreateClientFile(tables: Table[], hasCustomQueries: boolean, hasCustomMutations: boolean): GeneratedClientFile;
@@ -86,7 +86,7 @@ function createImportDeclaration(moduleSpecifier, namedImports, typeOnly = false
86
86
  /**
87
87
  * Generate the main index.ts with createClient factory
88
88
  */
89
- export function generateCreateClientFile(tables, hasCustomQueries, hasCustomMutations, options) {
89
+ export function generateCreateClientFile(tables, hasCustomQueries, hasCustomMutations) {
90
90
  const statements = [];
91
91
  // Add imports
92
92
  // Import OrmClient (value) and OrmClientConfig (type) separately
@@ -90,7 +90,7 @@ export function generateOrm(options) {
90
90
  const typesBarrel = generateTypesBarrel(useSharedTypes);
91
91
  files.push({ path: typesBarrel.fileName, content: typesBarrel.content });
92
92
  // 7. Generate main index.ts with createClient
93
- const indexFile = generateCreateClientFile(tables, hasCustomQueries, hasCustomMutations, { nodeHttpAdapter: !!options.config.nodeHttpAdapter });
93
+ const indexFile = generateCreateClientFile(tables, hasCustomQueries, hasCustomMutations);
94
94
  files.push({ path: indexFile.fileName, content: indexFile.content });
95
95
  return {
96
96
  files,
@@ -47,9 +47,6 @@ export async function generate(options = {}, internalOptions) {
47
47
  const runReactQuery = config.reactQuery ?? false;
48
48
  const runCli = internalOptions?.skipCli ? false : !!config.cli;
49
49
  const runOrm = runReactQuery || !!config.cli || (options.orm !== undefined ? !!options.orm : false);
50
- // Auto-enable nodeHttpAdapter when CLI is enabled, unless explicitly set to false
51
- const useNodeHttpAdapter = options.nodeHttpAdapter === true ||
52
- (runCli && options.nodeHttpAdapter !== false);
53
50
  const schemaEnabled = !!options.schema?.enabled;
54
51
  if (!schemaEnabled && !runReactQuery && !runOrm && !runCli) {
55
52
  return {
@@ -184,22 +181,13 @@ export async function generate(options = {}, internalOptions) {
184
181
  mutations: customOperations.mutations,
185
182
  typeRegistry: customOperations.typeRegistry,
186
183
  },
187
- config: { ...config, nodeHttpAdapter: useNodeHttpAdapter },
184
+ config,
188
185
  sharedTypesPath: bothEnabled ? '..' : undefined,
189
186
  });
190
187
  filesToWrite.push(...files.map((file) => ({
191
188
  ...file,
192
189
  path: path.posix.join('orm', file.path),
193
190
  })));
194
- // Generate NodeHttpAdapter in ORM output when enabled
195
- if (useNodeHttpAdapter) {
196
- const { generateNodeFetchFile } = await import('./codegen/cli/utils-generator');
197
- const nodeFetchFile = generateNodeFetchFile();
198
- filesToWrite.push({
199
- path: path.posix.join('orm', nodeFetchFile.fileName),
200
- content: nodeFetchFile.content,
201
- });
202
- }
203
191
  }
204
192
  // Generate CLI commands
205
193
  if (runCli) {
@@ -210,7 +198,7 @@ export async function generate(options = {}, internalOptions) {
210
198
  queries: customOperations.queries,
211
199
  mutations: customOperations.mutations,
212
200
  },
213
- config: { ...config, nodeHttpAdapter: useNodeHttpAdapter },
201
+ config,
214
202
  typeRegistry: customOperations.typeRegistry,
215
203
  });
216
204
  filesToWrite.push(...files.map((file) => ({
@@ -540,16 +528,11 @@ export async function generateMulti(options) {
540
528
  if (useUnifiedCli && cliTargets.length > 0 && !dryRun) {
541
529
  const cliConfig = typeof unifiedCli === 'object' ? unifiedCli : {};
542
530
  const toolName = cliConfig.toolName ?? 'app';
543
- // Auto-enable nodeHttpAdapter for unified CLI unless explicitly disabled
544
- // Check first target config for explicit nodeHttpAdapter setting
545
531
  const firstTargetConfig = configs[names[0]];
546
- const multiNodeHttpAdapter = firstTargetConfig?.nodeHttpAdapter === true ||
547
- (firstTargetConfig?.nodeHttpAdapter !== false);
548
532
  const { files } = generateMultiTargetCli({
549
533
  toolName,
550
534
  builtinNames: cliConfig.builtinNames,
551
535
  targets: cliTargets,
552
- nodeHttpAdapter: multiNodeHttpAdapter,
553
536
  entryPoint: cliConfig.entryPoint,
554
537
  });
555
538
  const cliFilesToWrite = files.map((file) => ({
@@ -317,24 +317,6 @@ export interface GraphQLSDKConfigTarget {
317
317
  * @default false
318
318
  */
319
319
  orm?: boolean;
320
- /**
321
- * Enable NodeHttpAdapter generation for Node.js applications.
322
- * When true, generates a node-fetch.ts with NodeHttpAdapter (implements GraphQLAdapter)
323
- * using node:http/node:https for requests, enabling local development
324
- * with subdomain-based routing (e.g. auth.localhost:3000).
325
- * No global patching — the adapter is passed to createClient via the adapter option.
326
- *
327
- * When CLI generation is enabled (`cli: true`), this is auto-enabled unless
328
- * explicitly set to `false`.
329
- *
330
- * Can also be used standalone with the ORM client for any Node.js application:
331
- * ```ts
332
- * import { NodeHttpAdapter } from './orm/node-fetch';
333
- * const db = createClient({ adapter: new NodeHttpAdapter(endpoint, headers) });
334
- * ```
335
- * @default false
336
- */
337
- nodeHttpAdapter?: boolean;
338
320
  /**
339
321
  * Whether to generate React Query hooks
340
322
  * When enabled, generates React Query hooks to {output}/hooks
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@constructive-io/graphql-codegen",
3
- "version": "4.41.0",
3
+ "version": "4.41.1",
4
4
  "description": "GraphQL SDK generator for Constructive databases with React Query hooks",
5
5
  "keywords": [
6
6
  "graphql",
@@ -100,5 +100,5 @@
100
100
  "tsx": "^4.21.0",
101
101
  "typescript": "^5.9.3"
102
102
  },
103
- "gitHead": "70f9d2052fe9218c65b82e896d1660d4dc6a51c8"
103
+ "gitHead": "0b23c8c5c65e408576cd1fe3e21b20ae6db8f492"
104
104
  }
package/types/config.d.ts CHANGED
@@ -317,24 +317,6 @@ export interface GraphQLSDKConfigTarget {
317
317
  * @default false
318
318
  */
319
319
  orm?: boolean;
320
- /**
321
- * Enable NodeHttpAdapter generation for Node.js applications.
322
- * When true, generates a node-fetch.ts with NodeHttpAdapter (implements GraphQLAdapter)
323
- * using node:http/node:https for requests, enabling local development
324
- * with subdomain-based routing (e.g. auth.localhost:3000).
325
- * No global patching — the adapter is passed to createClient via the adapter option.
326
- *
327
- * When CLI generation is enabled (`cli: true`), this is auto-enabled unless
328
- * explicitly set to `false`.
329
- *
330
- * Can also be used standalone with the ORM client for any Node.js application:
331
- * ```ts
332
- * import { NodeHttpAdapter } from './orm/node-fetch';
333
- * const db = createClient({ adapter: new NodeHttpAdapter(endpoint, headers) });
334
- * ```
335
- * @default false
336
- */
337
- nodeHttpAdapter?: boolean;
338
320
  /**
339
321
  * Whether to generate React Query hooks
340
322
  * When enabled, generates React Query hooks to {output}/hooks
@@ -1,198 +0,0 @@
1
- /**
2
- * Node HTTP Adapter for Node.js applications
3
- *
4
- * Implements the GraphQLAdapter interface using node:http / node:https
5
- * instead of the Fetch API. This solves two Node.js limitations:
6
- *
7
- * 1. DNS: Node.js cannot resolve *.localhost subdomains (ENOTFOUND).
8
- * Browsers handle this automatically, but Node requires manual resolution.
9
- *
10
- * 2. Host header: The Fetch API treats "Host" as a forbidden request header
11
- * and silently drops it. The Constructive GraphQL server uses Host-header
12
- * subdomain routing (enableServicesApi), so this header must be preserved.
13
- *
14
- * By using node:http.request directly, both issues are bypassed cleanly
15
- * without any global patching.
16
- *
17
- * NOTE: This file is read at codegen time and written to output.
18
- * Any changes here will affect all generated CLI node adapters.
19
- */
20
-
21
- import http from 'node:http';
22
- import https from 'node:https';
23
-
24
- import type {
25
- GraphQLAdapter,
26
- GraphQLError,
27
- QueryResult,
28
- } from '@constructive-io/graphql-types';
29
-
30
- interface HttpResponse {
31
- statusCode: number;
32
- statusMessage: string;
33
- data: string;
34
- }
35
-
36
- /**
37
- * Check if a hostname is a localhost subdomain that needs special handling.
38
- * Returns true for *.localhost (e.g. auth.localhost) but not bare "localhost".
39
- */
40
- function isLocalhostSubdomain(hostname: string): boolean {
41
- return hostname.endsWith('.localhost') && hostname !== 'localhost';
42
- }
43
-
44
- /**
45
- * Make an HTTP/HTTPS request using native Node modules.
46
- * Supports optional AbortSignal for request cancellation.
47
- */
48
- function makeRequest(
49
- url: URL,
50
- options: http.RequestOptions,
51
- body: string,
52
- signal?: AbortSignal,
53
- ): Promise<HttpResponse> {
54
- return new Promise((resolve, reject) => {
55
- if (signal?.aborted) {
56
- reject(new Error('The operation was aborted'));
57
- return;
58
- }
59
-
60
- const protocol = url.protocol === 'https:' ? https : http;
61
-
62
- const req = protocol.request(url, options, (res) => {
63
- let data = '';
64
- res.setEncoding('utf8');
65
- res.on('data', (chunk: string) => {
66
- data += chunk;
67
- });
68
- res.on('end', () => {
69
- resolve({
70
- statusCode: res.statusCode || 0,
71
- statusMessage: res.statusMessage || '',
72
- data,
73
- });
74
- });
75
- });
76
-
77
- req.on('error', reject);
78
-
79
- if (signal) {
80
- const onAbort = () => {
81
- req.destroy(new Error('The operation was aborted'));
82
- };
83
- signal.addEventListener('abort', onAbort, { once: true });
84
- req.on('close', () => {
85
- signal.removeEventListener('abort', onAbort);
86
- });
87
- }
88
-
89
- req.write(body);
90
- req.end();
91
- });
92
- }
93
-
94
- /**
95
- * Options for individual execute calls.
96
- * Allows per-request header overrides and request cancellation.
97
- */
98
- export interface NodeHttpExecuteOptions {
99
- /** Additional headers to include in this request only */
100
- headers?: Record<string, string>;
101
- /** AbortSignal for request cancellation */
102
- signal?: AbortSignal;
103
- }
104
-
105
- /**
106
- * GraphQL adapter that uses node:http/node:https for requests.
107
- *
108
- * Handles *.localhost subdomains by rewriting the hostname to "localhost"
109
- * and injecting the original Host header for server-side subdomain routing.
110
- */
111
- export class NodeHttpAdapter implements GraphQLAdapter {
112
- private headers: Record<string, string>;
113
- private url: URL;
114
-
115
- constructor(
116
- private endpoint: string,
117
- headers?: Record<string, string>,
118
- ) {
119
- this.headers = headers ?? {};
120
- this.url = new URL(endpoint);
121
- }
122
-
123
- async execute<T>(
124
- document: string,
125
- variables?: Record<string, unknown>,
126
- options?: NodeHttpExecuteOptions,
127
- ): Promise<QueryResult<T>> {
128
- const requestUrl = new URL(this.url.href);
129
- const requestHeaders: Record<string, string> = {
130
- 'Content-Type': 'application/json',
131
- Accept: 'application/json',
132
- ...this.headers,
133
- ...options?.headers,
134
- };
135
-
136
- // For *.localhost subdomains, rewrite hostname and inject Host header
137
- if (isLocalhostSubdomain(requestUrl.hostname)) {
138
- requestHeaders['Host'] = requestUrl.host;
139
- requestUrl.hostname = 'localhost';
140
- }
141
-
142
- const body = JSON.stringify({
143
- query: document,
144
- variables: variables ?? {},
145
- });
146
-
147
- const requestOptions: http.RequestOptions = {
148
- method: 'POST',
149
- headers: requestHeaders,
150
- };
151
-
152
- const response = await makeRequest(
153
- requestUrl,
154
- requestOptions,
155
- body,
156
- options?.signal,
157
- );
158
-
159
- if (response.statusCode < 200 || response.statusCode >= 300) {
160
- return {
161
- ok: false,
162
- data: null,
163
- errors: [
164
- {
165
- message: `HTTP ${response.statusCode}: ${response.statusMessage}`,
166
- },
167
- ],
168
- };
169
- }
170
-
171
- const json = JSON.parse(response.data) as {
172
- data?: T;
173
- errors?: GraphQLError[];
174
- };
175
-
176
- if (json.errors && json.errors.length > 0) {
177
- return {
178
- ok: false,
179
- data: null,
180
- errors: json.errors,
181
- };
182
- }
183
-
184
- return {
185
- ok: true,
186
- data: json.data as T,
187
- errors: undefined,
188
- };
189
- }
190
-
191
- setHeaders(headers: Record<string, string>): void {
192
- this.headers = { ...this.headers, ...headers };
193
- }
194
-
195
- getEndpoint(): string {
196
- return this.endpoint;
197
- }
198
- }