@soda-gql/tsc-transformer 0.1.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs ADDED
@@ -0,0 +1,598 @@
1
+ //#region rolldown:runtime
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __copyProps = (to, from, except, desc) => {
9
+ if (from && typeof from === "object" || typeof from === "function") {
10
+ for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
11
+ key = keys[i];
12
+ if (!__hasOwnProp.call(to, key) && key !== except) {
13
+ __defProp(to, key, {
14
+ get: ((k) => from[k]).bind(null, key),
15
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
16
+ });
17
+ }
18
+ }
19
+ }
20
+ return to;
21
+ };
22
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
23
+ value: mod,
24
+ enumerable: true
25
+ }) : target, mod));
26
+
27
+ //#endregion
28
+ let __soda_gql_builder = require("@soda-gql/builder");
29
+ let __soda_gql_plugin_common = require("@soda-gql/plugin-common");
30
+ let typescript = require("typescript");
31
+ typescript = __toESM(typescript);
32
+ let __soda_gql_common = require("@soda-gql/common");
33
+ let neverthrow = require("neverthrow");
34
+
35
+ //#region packages/tsc-transformer/src/ast/imports.ts
36
+ const RUNTIME_MODULE = "@soda-gql/runtime";
37
+ /**
38
+ * Ensure that the gqlRuntime require exists in the source file for CJS output.
39
+ * Injects: const __soda_gql_runtime = require("@soda-gql/runtime");
40
+ * Returns an updated source file with the require added if needed.
41
+ */
42
+ const ensureGqlRuntimeRequire = ({ sourceFile, factory }) => {
43
+ if (sourceFile.statements.find((statement) => typescript.default.isVariableStatement(statement) && statement.declarationList.declarations.some((decl) => {
44
+ if (!typescript.default.isIdentifier(decl.name) || decl.name.text !== "__soda_gql_runtime") return false;
45
+ if (!decl.initializer || !typescript.default.isCallExpression(decl.initializer)) return false;
46
+ const callExpr = decl.initializer;
47
+ if (!typescript.default.isIdentifier(callExpr.expression) || callExpr.expression.text !== "require") return false;
48
+ const arg = callExpr.arguments[0];
49
+ return arg && typescript.default.isStringLiteral(arg) && arg.text === RUNTIME_MODULE;
50
+ }))) return sourceFile;
51
+ const requireCall = factory.createCallExpression(factory.createIdentifier("require"), void 0, [factory.createStringLiteral(RUNTIME_MODULE)]);
52
+ const variableDeclaration = factory.createVariableDeclaration(factory.createIdentifier("__soda_gql_runtime"), void 0, void 0, requireCall);
53
+ const newStatements = [factory.createVariableStatement(void 0, factory.createVariableDeclarationList([variableDeclaration], typescript.default.NodeFlags.Const)), ...sourceFile.statements];
54
+ return factory.updateSourceFile(sourceFile, newStatements);
55
+ };
56
+ /**
57
+ * Ensure that the gqlRuntime import exists in the source file.
58
+ * gqlRuntime is always imported from @soda-gql/runtime.
59
+ * Returns an updated source file with the import added or merged.
60
+ */
61
+ const ensureGqlRuntimeImport = ({ sourceFile, factory }) => {
62
+ const existing = sourceFile.statements.find((statement) => typescript.default.isImportDeclaration(statement) && typescript.default.isStringLiteral(statement.moduleSpecifier) && statement.moduleSpecifier.text === RUNTIME_MODULE);
63
+ if (existing?.importClause?.namedBindings && typescript.default.isNamedImports(existing.importClause.namedBindings)) {
64
+ if (existing.importClause.namedBindings.elements.some((element) => typescript.default.isIdentifier(element.name) && element.name.text === "gqlRuntime")) return sourceFile;
65
+ const newElements = [...existing.importClause.namedBindings.elements, factory.createImportSpecifier(false, void 0, factory.createIdentifier("gqlRuntime"))];
66
+ const newNamedBindings = factory.createNamedImports(newElements);
67
+ const newImportClause = factory.createImportClause(false, void 0, newNamedBindings);
68
+ const newImportDeclaration = factory.createImportDeclaration(void 0, newImportClause, factory.createStringLiteral(RUNTIME_MODULE), void 0);
69
+ const newStatements$1 = sourceFile.statements.map((stmt) => stmt === existing ? newImportDeclaration : stmt);
70
+ return factory.updateSourceFile(sourceFile, newStatements$1);
71
+ }
72
+ const newStatements = [factory.createImportDeclaration(void 0, factory.createImportClause(false, void 0, factory.createNamedImports([factory.createImportSpecifier(false, void 0, factory.createIdentifier("gqlRuntime"))])), factory.createStringLiteral(RUNTIME_MODULE), void 0), ...sourceFile.statements];
73
+ return factory.updateSourceFile(sourceFile, newStatements);
74
+ };
75
+ /**
76
+ * Remove the graphql-system import (runtimeModule) and gql-related exports from the source file.
77
+ * After transformation, gqlRuntime is imported from @soda-gql/runtime instead,
78
+ * so the original graphql-system import should be completely removed.
79
+ *
80
+ * This handles both ESM imports and CommonJS require() statements (including interop helpers).
81
+ */
82
+ const removeGraphqlSystemImports = ({ sourceFile, factory, graphqlSystemIdentifyHelper }) => {
83
+ const updatedStatements = Array.from(sourceFile.statements).filter((statement) => {
84
+ if (typescript.default.isImportDeclaration(statement) && typescript.default.isStringLiteral(statement.moduleSpecifier)) return !graphqlSystemIdentifyHelper.isGraphqlSystemImportSpecifier({
85
+ filePath: sourceFile.fileName,
86
+ specifier: statement.moduleSpecifier.text
87
+ });
88
+ if (typescript.default.isVariableStatement(statement)) return !statement.declarationList.declarations.every((decl) => {
89
+ const specifier = extractRequireTargetSpecifier(decl.initializer);
90
+ if (!specifier) return false;
91
+ return graphqlSystemIdentifyHelper.isGraphqlSystemImportSpecifier({
92
+ filePath: sourceFile.fileName,
93
+ specifier
94
+ });
95
+ });
96
+ return true;
97
+ });
98
+ if (updatedStatements.length === sourceFile.statements.length) return sourceFile;
99
+ return factory.updateSourceFile(sourceFile, updatedStatements);
100
+ };
101
+ /**
102
+ * Create an "after" transformer that stubs out require() calls for the runtimeModule.
103
+ * This runs after TypeScript's own transformers (including CommonJS down-leveling),
104
+ * so we can replace `const X = require("@/graphql-system")` with a lightweight stub.
105
+ *
106
+ * This prevents the heavy graphql-system module from being loaded at runtime.
107
+ */
108
+ const createAfterStubTransformer = ({ sourceFile, graphqlSystemIdentifyHelper }) => {
109
+ return (context) => {
110
+ const factory = context.factory;
111
+ const visitor = (node) => {
112
+ if (typescript.default.isVariableStatement(node)) {
113
+ let transformed = false;
114
+ const newDeclarations = node.declarationList.declarations.map((decl) => {
115
+ const specifier = extractRequireTargetSpecifier(decl.initializer);
116
+ if (!specifier) return decl;
117
+ if (!graphqlSystemIdentifyHelper.isGraphqlSystemImportSpecifier({
118
+ filePath: sourceFile.fileName,
119
+ specifier
120
+ })) return decl;
121
+ const stub = factory.createCallExpression(factory.createPropertyAccessExpression(factory.createIdentifier("Object"), "create"), void 0, [factory.createNull()]);
122
+ typescript.default.addSyntheticLeadingComment(stub, typescript.default.SyntaxKind.MultiLineCommentTrivia, "#__PURE__", false);
123
+ transformed = true;
124
+ return factory.updateVariableDeclaration(decl, decl.name, decl.exclamationToken, decl.type, stub);
125
+ });
126
+ if (transformed) return factory.updateVariableStatement(node, node.modifiers, factory.updateVariableDeclarationList(node.declarationList, newDeclarations));
127
+ }
128
+ return typescript.default.visitEachChild(node, visitor, context);
129
+ };
130
+ return (sourceFile$1) => typescript.default.visitNode(sourceFile$1, visitor);
131
+ };
132
+ };
133
+ /**
134
+ * Check if an expression is a require() call for the runtimeModule.
135
+ * Handles multiple patterns:
136
+ * - require("@/graphql-system")
137
+ * - __importDefault(require("@/graphql-system"))
138
+ * - __importStar(require("@/graphql-system"))
139
+ */
140
+ const extractRequireTargetSpecifier = (expr) => {
141
+ if (!expr) return;
142
+ if (typescript.default.isCallExpression(expr)) {
143
+ if (typescript.default.isIdentifier(expr.expression) && expr.expression.text === "require") {
144
+ const arg = expr.arguments[0];
145
+ if (arg && typescript.default.isStringLiteral(arg)) return arg.text;
146
+ }
147
+ if (typescript.default.isIdentifier(expr.expression)) {
148
+ const helperName = expr.expression.text;
149
+ if (helperName === "__importDefault" || helperName === "__importStar") {
150
+ const arg = expr.arguments[0];
151
+ if (arg && typescript.default.isCallExpression(arg)) {
152
+ if (typescript.default.isIdentifier(arg.expression) && arg.expression.text === "require") {
153
+ const requireArg = arg.arguments[0];
154
+ if (requireArg && typescript.default.isStringLiteral(requireArg)) return requireArg.text;
155
+ }
156
+ }
157
+ }
158
+ }
159
+ }
160
+ };
161
+
162
+ //#endregion
163
+ //#region packages/tsc-transformer/src/ast/metadata.ts
164
+ const collectGqlDefinitionMetadata = ({ sourceFile, filename, createTracker }) => {
165
+ const exportBindings = collectExportBindings(sourceFile);
166
+ const tracker = (createTracker ?? __soda_gql_common.createCanonicalTracker)({
167
+ filePath: filename,
168
+ getExportName: (localName) => exportBindings.get(localName)
169
+ });
170
+ const getAnonymousName = createAnonymousNameFactory();
171
+ const scopeHandles = /* @__PURE__ */ new WeakMap();
172
+ const metadata = /* @__PURE__ */ new WeakMap();
173
+ const visit = (node) => {
174
+ if (typescript.isCallExpression(node) && isGqlDefinitionCall(node, typescript)) {
175
+ const depthBeforeRegister = tracker.currentDepth();
176
+ const { astPath } = tracker.registerDefinition();
177
+ const isTopLevel = depthBeforeRegister <= 1;
178
+ const exportInfo = isTopLevel ? resolveTopLevelExport(node, exportBindings, typescript) : null;
179
+ metadata.set(node, {
180
+ astPath,
181
+ isTopLevel,
182
+ isExported: exportInfo?.isExported ?? false,
183
+ exportBinding: exportInfo?.exportBinding
184
+ });
185
+ return;
186
+ }
187
+ const handle = maybeEnterScope(node, tracker, getAnonymousName, typescript);
188
+ if (handle) scopeHandles.set(node, handle);
189
+ typescript.forEachChild(node, visit);
190
+ const scopeHandle = scopeHandles.get(node);
191
+ if (scopeHandle) {
192
+ tracker.exitScope(scopeHandle);
193
+ scopeHandles.delete(node);
194
+ }
195
+ };
196
+ visit(sourceFile);
197
+ return metadata;
198
+ };
199
+ const collectExportBindings = (sourceFile) => {
200
+ const bindings = /* @__PURE__ */ new Map();
201
+ for (const statement of sourceFile.statements) {
202
+ if (typescript.isExportDeclaration(statement) && statement.exportClause && typescript.isNamedExports(statement.exportClause)) {
203
+ for (const element of statement.exportClause.elements) {
204
+ const name = element.name.text;
205
+ bindings.set(name, name);
206
+ }
207
+ continue;
208
+ }
209
+ if (typescript.isVariableStatement(statement) && statement.modifiers?.some((m) => m.kind === typescript.SyntaxKind.ExportKeyword)) {
210
+ for (const declaration of statement.declarationList.declarations) if (typescript.isIdentifier(declaration.name)) bindings.set(declaration.name.text, declaration.name.text);
211
+ continue;
212
+ }
213
+ if ((typescript.isFunctionDeclaration(statement) || typescript.isClassDeclaration(statement)) && statement.modifiers?.some((m) => m.kind === typescript.SyntaxKind.ExportKeyword) && statement.name) {
214
+ bindings.set(statement.name.text, statement.name.text);
215
+ continue;
216
+ }
217
+ if (typescript.isExpressionStatement(statement) && typescript.isBinaryExpression(statement.expression)) {
218
+ const exportName = getCommonJsExportName(statement.expression.left);
219
+ if (exportName) bindings.set(exportName, exportName);
220
+ }
221
+ }
222
+ return bindings;
223
+ };
224
+ const getCommonJsExportName = (node) => {
225
+ if (!typescript.isPropertyAccessExpression(node)) return null;
226
+ const isExports = typescript.isIdentifier(node.expression) && node.expression.text === "exports";
227
+ const isModuleExports = typescript.isPropertyAccessExpression(node.expression) && typescript.isIdentifier(node.expression.expression) && node.expression.expression.text === "module" && typescript.isIdentifier(node.expression.name) && node.expression.name.text === "exports";
228
+ if (!isExports && !isModuleExports) return null;
229
+ if (typescript.isIdentifier(node.name)) return node.name.text;
230
+ return null;
231
+ };
232
+ const createAnonymousNameFactory = () => {
233
+ const counters = /* @__PURE__ */ new Map();
234
+ return (kind) => {
235
+ const count = counters.get(kind) ?? 0;
236
+ counters.set(kind, count + 1);
237
+ return `${kind}#${count}`;
238
+ };
239
+ };
240
+ const isGqlDefinitionCall = (node, typescript$1) => {
241
+ if (!typescript$1.isCallExpression(node)) return false;
242
+ if (!typescript$1.isPropertyAccessExpression(node.expression)) return false;
243
+ if (!isGqlReference(node.expression.expression, typescript$1)) return false;
244
+ if (node.arguments.length === 0) return false;
245
+ const firstArg = node.arguments[0];
246
+ if (firstArg === void 0) return false;
247
+ return typescript$1.isArrowFunction(firstArg);
248
+ };
249
+ const isGqlReference = (expr, typescript$1) => {
250
+ if (typescript$1.isIdentifier(expr) && expr.text === "gql") return true;
251
+ if (!typescript$1.isPropertyAccessExpression(expr)) return false;
252
+ if (typescript$1.isIdentifier(expr.name) && expr.name.text === "gql") return true;
253
+ return isGqlReference(expr.expression, typescript$1);
254
+ };
255
+ const resolveTopLevelExport = (callNode, exportBindings, typescript$1) => {
256
+ const parent = callNode.parent;
257
+ if (!parent) return null;
258
+ if (typescript$1.isVariableDeclaration(parent)) {
259
+ const { name } = parent;
260
+ if (typescript$1.isIdentifier(name)) {
261
+ const exportBinding = exportBindings.get(name.text);
262
+ if (exportBinding) return {
263
+ isExported: true,
264
+ exportBinding
265
+ };
266
+ }
267
+ }
268
+ if (typescript$1.isBinaryExpression(parent)) {
269
+ const exportName = getCommonJsExportName(parent.left);
270
+ if (exportName && exportBindings.has(exportName)) return {
271
+ isExported: true,
272
+ exportBinding: exportName
273
+ };
274
+ }
275
+ return null;
276
+ };
277
+ const maybeEnterScope = (node, tracker, getAnonymousName, typescript$1) => {
278
+ if (typescript$1.isBinaryExpression(node)) {
279
+ const exportName = getCommonJsExportName(node.left);
280
+ if (exportName) return tracker.enterScope({
281
+ segment: exportName,
282
+ kind: "variable",
283
+ stableKey: `var:${exportName}`
284
+ });
285
+ }
286
+ if (typescript$1.isVariableDeclaration(node) && typescript$1.isIdentifier(node.name)) {
287
+ const name = node.name.text;
288
+ return tracker.enterScope({
289
+ segment: name,
290
+ kind: "variable",
291
+ stableKey: `var:${name}`
292
+ });
293
+ }
294
+ if (typescript$1.isArrowFunction(node)) {
295
+ const name = getAnonymousName("arrow");
296
+ return tracker.enterScope({
297
+ segment: name,
298
+ kind: "function",
299
+ stableKey: "arrow"
300
+ });
301
+ }
302
+ if (typescript$1.isFunctionDeclaration(node) || typescript$1.isFunctionExpression(node)) {
303
+ const name = node.name?.text ?? getAnonymousName("function");
304
+ return tracker.enterScope({
305
+ segment: name,
306
+ kind: "function",
307
+ stableKey: `func:${name}`
308
+ });
309
+ }
310
+ if (typescript$1.isClassDeclaration(node)) {
311
+ const name = node.name?.text ?? getAnonymousName("class");
312
+ return tracker.enterScope({
313
+ segment: name,
314
+ kind: "class",
315
+ stableKey: `class:${name}`
316
+ });
317
+ }
318
+ if (typescript$1.isMethodDeclaration(node) && typescript$1.isIdentifier(node.name)) {
319
+ const name = node.name.text;
320
+ return tracker.enterScope({
321
+ segment: name,
322
+ kind: "method",
323
+ stableKey: `member:${name}`
324
+ });
325
+ }
326
+ if (typescript$1.isPropertyDeclaration(node) && typescript$1.isIdentifier(node.name)) {
327
+ const name = node.name.text;
328
+ return tracker.enterScope({
329
+ segment: name,
330
+ kind: "property",
331
+ stableKey: `member:${name}`
332
+ });
333
+ }
334
+ if (typescript$1.isPropertyAssignment(node)) {
335
+ const key = node.name;
336
+ const name = typescript$1.isIdentifier(key) ? key.text : typescript$1.isStringLiteral(key) ? key.text : null;
337
+ if (name) return tracker.enterScope({
338
+ segment: name,
339
+ kind: "property",
340
+ stableKey: `prop:${name}`
341
+ });
342
+ }
343
+ return null;
344
+ };
345
+
346
+ //#endregion
347
+ //#region packages/tsc-transformer/src/ast/analysis.ts
348
+ const extractGqlCall = ({ callNode, filename, metadata, getArtifact }) => {
349
+ const meta = metadata.get(callNode);
350
+ if (!meta) return (0, neverthrow.err)(createMetadataMissingError({ filename }));
351
+ const canonicalId = (0, __soda_gql_plugin_common.resolveCanonicalId)(filename, meta.astPath);
352
+ const artifact = getArtifact(canonicalId);
353
+ if (!artifact) return (0, neverthrow.err)(createArtifactMissingError({
354
+ filename,
355
+ canonicalId
356
+ }));
357
+ if (artifact.type === "fragment") return (0, neverthrow.ok)({
358
+ callNode,
359
+ canonicalId,
360
+ type: "fragment",
361
+ artifact
362
+ });
363
+ if (artifact.type === "operation") return (0, neverthrow.ok)({
364
+ callNode,
365
+ canonicalId,
366
+ type: "operation",
367
+ artifact
368
+ });
369
+ return (0, neverthrow.err)(createUnsupportedArtifactTypeError({
370
+ filename,
371
+ canonicalId,
372
+ artifactType: artifact.type
373
+ }));
374
+ };
375
+ const createMetadataMissingError = ({ filename }) => ({
376
+ type: "PluginError",
377
+ stage: "analysis",
378
+ code: "SODA_GQL_METADATA_NOT_FOUND",
379
+ message: `No GraphQL metadata found for ${filename}`,
380
+ cause: { filename },
381
+ filename
382
+ });
383
+ const createArtifactMissingError = ({ filename, canonicalId }) => ({
384
+ type: "PluginError",
385
+ stage: "analysis",
386
+ code: "SODA_GQL_ANALYSIS_ARTIFACT_NOT_FOUND",
387
+ message: `No builder artifact found for canonical ID ${canonicalId}`,
388
+ cause: {
389
+ filename,
390
+ canonicalId
391
+ },
392
+ filename,
393
+ canonicalId
394
+ });
395
+ const createUnsupportedArtifactTypeError = ({ filename, canonicalId, artifactType }) => ({
396
+ type: "PluginError",
397
+ stage: "analysis",
398
+ code: "SODA_GQL_UNSUPPORTED_ARTIFACT_TYPE",
399
+ message: `Unsupported builder artifact type "${artifactType}" for canonical ID ${canonicalId}`,
400
+ cause: {
401
+ filename,
402
+ canonicalId,
403
+ artifactType
404
+ },
405
+ filename,
406
+ canonicalId,
407
+ artifactType
408
+ });
409
+
410
+ //#endregion
411
+ //#region packages/tsc-transformer/src/ast/ast.ts
412
+ /**
413
+ * Build an object literal expression from a record of properties.
414
+ */
415
+ const buildObjectExpression = (factory, properties) => {
416
+ const propertyAssignments = Object.entries(properties).map(([key, value]) => factory.createPropertyAssignment(factory.createIdentifier(key), value));
417
+ return factory.createObjectLiteralExpression(propertyAssignments);
418
+ };
419
+ /**
420
+ * Build a JSON.parse expression from an object value.
421
+ * This is used to emit large objects as JSON strings to reduce the calculation cost of both the compiler and the runtime.
422
+ */
423
+ const buildJsonParseExpression = (factory, value) => factory.createCallExpression(factory.createPropertyAccessExpression(factory.createIdentifier("JSON"), factory.createIdentifier("parse")), void 0, [factory.createStringLiteral(JSON.stringify(value))]);
424
+
425
+ //#endregion
426
+ //#region packages/tsc-transformer/src/ast/runtime.ts
427
+ const createRuntimeAccessor = ({ isCJS, factory }) => isCJS ? factory.createPropertyAccessExpression(factory.createIdentifier("__soda_gql_runtime"), factory.createIdentifier("gqlRuntime")) : factory.createIdentifier("gqlRuntime");
428
+ const buildFragmentRuntimeCall = ({ gqlCall, factory, isCJS }) => {
429
+ return (0, neverthrow.ok)(factory.createCallExpression(factory.createPropertyAccessExpression(createRuntimeAccessor({
430
+ isCJS,
431
+ factory
432
+ }), factory.createIdentifier("fragment")), void 0, [buildObjectExpression(factory, { prebuild: buildObjectExpression(factory, { typename: factory.createStringLiteral(gqlCall.artifact.prebuild.typename) }) })]));
433
+ };
434
+ const buildOperationRuntimeComponents = ({ gqlCall, factory, isCJS }) => {
435
+ const runtimeCall = factory.createCallExpression(factory.createPropertyAccessExpression(createRuntimeAccessor({
436
+ isCJS,
437
+ factory
438
+ }), factory.createIdentifier("operation")), void 0, [buildObjectExpression(factory, {
439
+ prebuild: buildJsonParseExpression(factory, gqlCall.artifact.prebuild),
440
+ runtime: buildObjectExpression(factory, {})
441
+ })]);
442
+ return (0, neverthrow.ok)({
443
+ referenceCall: factory.createCallExpression(factory.createPropertyAccessExpression(createRuntimeAccessor({
444
+ isCJS,
445
+ factory
446
+ }), factory.createIdentifier("getOperation")), void 0, [factory.createStringLiteral(gqlCall.artifact.prebuild.operationName)]),
447
+ runtimeCall
448
+ });
449
+ };
450
+
451
+ //#endregion
452
+ //#region packages/tsc-transformer/src/ast/transformer.ts
453
+ const transformCallExpression = ({ callNode, filename, metadata, getArtifact, factory, isCJS }) => {
454
+ if (!metadata.has(callNode)) return (0, neverthrow.ok)({ transformed: false });
455
+ const gqlCallResult = extractGqlCall({
456
+ callNode,
457
+ filename,
458
+ metadata,
459
+ getArtifact
460
+ });
461
+ if (gqlCallResult.isErr()) return (0, neverthrow.err)(gqlCallResult.error);
462
+ const gqlCall = gqlCallResult.value;
463
+ return replaceWithRuntimeCall({
464
+ gqlCall,
465
+ factory,
466
+ isCJS,
467
+ filename
468
+ });
469
+ };
470
+ const replaceWithRuntimeCall = ({ gqlCall, factory, isCJS, filename }) => {
471
+ if (gqlCall.type === "fragment") {
472
+ const result = buildFragmentRuntimeCall({
473
+ gqlCall,
474
+ factory,
475
+ isCJS,
476
+ filename
477
+ });
478
+ if (result.isErr()) return (0, neverthrow.err)(result.error);
479
+ return (0, neverthrow.ok)({
480
+ transformed: true,
481
+ replacement: result.value
482
+ });
483
+ }
484
+ if (gqlCall.type === "operation") {
485
+ const result = buildOperationRuntimeComponents({
486
+ gqlCall,
487
+ factory,
488
+ isCJS
489
+ });
490
+ if (result.isErr()) return (0, neverthrow.err)(result.error);
491
+ const { referenceCall, runtimeCall } = result.value;
492
+ return (0, neverthrow.ok)({
493
+ transformed: true,
494
+ replacement: referenceCall,
495
+ runtimeCall
496
+ });
497
+ }
498
+ return (0, neverthrow.ok)({ transformed: false });
499
+ };
500
+
501
+ //#endregion
502
+ //#region packages/tsc-transformer/src/transformer.ts
503
+ const findLastImportIndex = ({ sourceFile }) => {
504
+ let lastIndex = -1;
505
+ const statements = sourceFile.statements;
506
+ for (let i = 0; i < statements.length; i++) {
507
+ const statement = statements[i];
508
+ if (statement && typescript.isImportDeclaration(statement)) lastIndex = i;
509
+ }
510
+ return lastIndex;
511
+ };
512
+ const createTransformer = ({ compilerOptions, config, artifact }) => {
513
+ const isCJS = compilerOptions.module === typescript.ModuleKind.CommonJS || compilerOptions.target === typescript.ScriptTarget.ES5;
514
+ const graphqlSystemIdentifyHelper = (0, __soda_gql_builder.createGraphqlSystemIdentifyHelper)(config);
515
+ const makeSourceFileEmpty = ({ factory, sourceFile }) => {
516
+ return factory.updateSourceFile(sourceFile, [factory.createExportDeclaration(void 0, false, factory.createNamedExports([]), void 0)]);
517
+ };
518
+ const transformGqlCalls = ({ sourceFile, context }) => {
519
+ let transformed = false;
520
+ const metadata = collectGqlDefinitionMetadata({
521
+ sourceFile,
522
+ filename: sourceFile.fileName
523
+ });
524
+ const runtimeCallsFromLastTransform = [];
525
+ const visitor = (node) => {
526
+ if (typescript.isCallExpression(node)) {
527
+ const result = transformCallExpression({
528
+ callNode: node,
529
+ filename: sourceFile.fileName,
530
+ metadata,
531
+ getArtifact: (canonicalId) => artifact.elements[canonicalId],
532
+ factory: context.factory,
533
+ isCJS
534
+ });
535
+ if (result.isErr()) {
536
+ console.error(`[@soda-gql/tsc-plugin] ${(0, __soda_gql_plugin_common.formatPluginError)(result.error)}`);
537
+ return node;
538
+ }
539
+ const transformResult = result.value;
540
+ if (transformResult.transformed) {
541
+ transformed = true;
542
+ if (transformResult.runtimeCall) runtimeCallsFromLastTransform.push(transformResult.runtimeCall);
543
+ return transformResult.replacement;
544
+ }
545
+ }
546
+ return typescript.visitEachChild(node, visitor, context);
547
+ };
548
+ const visitedNode = typescript.visitNode(sourceFile, visitor);
549
+ if (!visitedNode || !typescript.isSourceFile(visitedNode)) {
550
+ console.error(`[@soda-gql/tsc-plugin] Failed to transform source file: ${sourceFile.fileName}`);
551
+ return sourceFile;
552
+ }
553
+ if (!transformed) return sourceFile;
554
+ if (runtimeCallsFromLastTransform.length === 0) return visitedNode;
555
+ const lastImportIndex = findLastImportIndex({ sourceFile });
556
+ return context.factory.updateSourceFile(visitedNode, [
557
+ ...visitedNode.statements.slice(0, lastImportIndex + 1),
558
+ ...runtimeCallsFromLastTransform.map((expr) => context.factory.createExpressionStatement(expr)),
559
+ ...visitedNode.statements.slice(lastImportIndex + 1)
560
+ ]);
561
+ };
562
+ return { transform: ({ sourceFile, context }) => {
563
+ if (graphqlSystemIdentifyHelper.isGraphqlSystemFile({ filePath: sourceFile.fileName })) return {
564
+ transformed: true,
565
+ sourceFile: makeSourceFileEmpty({
566
+ factory: context.factory,
567
+ sourceFile
568
+ })
569
+ };
570
+ const original = sourceFile;
571
+ let current = sourceFile;
572
+ current = transformGqlCalls({
573
+ sourceFile: current,
574
+ context
575
+ });
576
+ if (current !== sourceFile) current = isCJS ? ensureGqlRuntimeRequire({
577
+ sourceFile: current,
578
+ factory: context.factory
579
+ }) : ensureGqlRuntimeImport({
580
+ sourceFile: current,
581
+ factory: context.factory
582
+ });
583
+ current = removeGraphqlSystemImports({
584
+ sourceFile: current,
585
+ factory: context.factory,
586
+ graphqlSystemIdentifyHelper
587
+ });
588
+ return {
589
+ transformed: current !== original,
590
+ sourceFile: current
591
+ };
592
+ } };
593
+ };
594
+
595
+ //#endregion
596
+ exports.createAfterStubTransformer = createAfterStubTransformer;
597
+ exports.createTransformer = createTransformer;
598
+ //# sourceMappingURL=index.cjs.map