@soda-gql/babel-plugin 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 CHANGED
@@ -1,609 +1,7 @@
1
- Object.defineProperty(exports, '__esModule', { value: true });
2
- //#region rolldown:runtime
3
- var __create = Object.create;
4
- var __defProp = Object.defineProperty;
5
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
- var __getOwnPropNames = Object.getOwnPropertyNames;
7
- var __getProtoOf = Object.getPrototypeOf;
8
- var __hasOwnProp = Object.prototype.hasOwnProperty;
9
- var __copyProps = (to, from, except, desc) => {
10
- if (from && typeof from === "object" || typeof from === "function") {
11
- for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
12
- key = keys[i];
13
- if (!__hasOwnProp.call(to, key) && key !== except) {
14
- __defProp(to, key, {
15
- get: ((k) => from[k]).bind(null, key),
16
- enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
17
- });
18
- }
19
- }
20
- }
21
- return to;
22
- };
23
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
24
- value: mod,
25
- enumerable: true
26
- }) : target, mod));
27
-
28
- //#endregion
29
1
  let __babel_core = require("@babel/core");
2
+ let __soda_gql_babel_transformer = require("@soda-gql/babel-transformer");
30
3
  let __soda_gql_plugin_common = require("@soda-gql/plugin-common");
31
- let __soda_gql_builder = require("@soda-gql/builder");
32
- let neverthrow = require("neverthrow");
33
- let __babel_types = require("@babel/types");
34
- __babel_types = __toESM(__babel_types);
35
-
36
- //#region packages/babel-plugin/src/ast/imports.ts
37
- const RUNTIME_MODULE = "@soda-gql/runtime";
38
- /**
39
- * Ensure that the gqlRuntime import exists in the program.
40
- * gqlRuntime is always imported from @soda-gql/runtime.
41
- */
42
- const ensureGqlRuntimeImport = (programPath) => {
43
- const existing = programPath.node.body.find((statement) => statement.type === "ImportDeclaration" && statement.source.value === RUNTIME_MODULE);
44
- if (existing && __babel_core.types.isImportDeclaration(existing)) {
45
- if (!existing.specifiers.some((specifier) => specifier.type === "ImportSpecifier" && specifier.imported.type === "Identifier" && specifier.imported.name === "gqlRuntime")) existing.specifiers = [...existing.specifiers, __babel_core.types.importSpecifier(__babel_core.types.identifier("gqlRuntime"), __babel_core.types.identifier("gqlRuntime"))];
46
- return;
47
- }
48
- programPath.node.body.unshift(__babel_core.types.importDeclaration([__babel_core.types.importSpecifier(__babel_core.types.identifier("gqlRuntime"), __babel_core.types.identifier("gqlRuntime"))], __babel_core.types.stringLiteral(RUNTIME_MODULE)));
49
- };
50
- /**
51
- * Remove the graphql-system import (runtimeModule) and gql-related exports from the program.
52
- * After transformation, gqlRuntime is imported from @soda-gql/runtime instead,
53
- * so the original graphql-system import should be completely removed.
54
- *
55
- * This handles both ESM imports and CommonJS require() statements.
56
- */
57
- const removeGraphqlSystemImports = (programPath, graphqlSystemIdentifyHelper, filename) => {
58
- const toRemove = [];
59
- programPath.traverse({
60
- ImportDeclaration(path) {
61
- if (__babel_core.types.isStringLiteral(path.node.source)) {
62
- if (graphqlSystemIdentifyHelper.isGraphqlSystemImportSpecifier({
63
- filePath: filename,
64
- specifier: path.node.source.value
65
- })) toRemove.push(path);
66
- }
67
- },
68
- VariableDeclaration(path) {
69
- if (path.node.declarations.every((decl) => {
70
- const specifier = extractRequireTargetSpecifier(decl.init);
71
- if (!specifier) return false;
72
- return graphqlSystemIdentifyHelper.isGraphqlSystemImportSpecifier({
73
- filePath: filename,
74
- specifier
75
- });
76
- })) toRemove.push(path);
77
- }
78
- });
79
- for (const path of toRemove) path.remove();
80
- };
81
- /**
82
- * Check if an expression is a require() call and extract its target specifier.
83
- * Handles multiple patterns:
84
- * - require("@/graphql-system")
85
- * - Object(require("@/graphql-system")) (interop helper pattern)
86
- */
87
- const extractRequireTargetSpecifier = (expr) => {
88
- if (!expr) return;
89
- if (__babel_core.types.isCallExpression(expr)) {
90
- if (__babel_core.types.isIdentifier(expr.callee) && expr.callee.name === "require") {
91
- const arg = expr.arguments[0];
92
- if (arg && __babel_core.types.isStringLiteral(arg)) return arg.value;
93
- }
94
- if (__babel_core.types.isIdentifier(expr.callee) && (expr.callee.name === "Object" || expr.callee.name.startsWith("__import"))) {
95
- const arg = expr.arguments[0];
96
- if (arg && __babel_core.types.isCallExpression(arg)) {
97
- if (__babel_core.types.isIdentifier(arg.callee) && arg.callee.name === "require") {
98
- const requireArg = arg.arguments[0];
99
- if (requireArg && __babel_core.types.isStringLiteral(requireArg)) return requireArg.value;
100
- }
101
- }
102
- }
103
- }
104
- };
105
-
106
- //#endregion
107
- //#region packages/babel-plugin/src/ast/metadata.ts
108
- const collectGqlDefinitionMetadata = ({ programPath, filename, createTracker }) => {
109
- const exportBindings = collectExportBindings(programPath.node);
110
- const tracker = (createTracker ?? __soda_gql_builder.createCanonicalTracker)({
111
- filePath: filename,
112
- getExportName: (localName) => exportBindings.get(localName)
113
- });
114
- const getAnonymousName = createAnonymousNameFactory();
115
- const scopeHandles = /* @__PURE__ */ new WeakMap();
116
- const metadata = /* @__PURE__ */ new WeakMap();
117
- programPath.traverse({
118
- enter(path) {
119
- if (path.isCallExpression() && isGqlDefinitionCall(path.node)) {
120
- const depthBeforeRegister = tracker.currentDepth();
121
- const { astPath } = tracker.registerDefinition();
122
- const isTopLevel = depthBeforeRegister <= 1;
123
- const exportInfo = isTopLevel ? resolveTopLevelExport(path, exportBindings) : null;
124
- metadata.set(path.node, {
125
- astPath,
126
- isTopLevel,
127
- isExported: exportInfo?.isExported ?? false,
128
- exportBinding: exportInfo?.exportBinding
129
- });
130
- path.skip();
131
- return;
132
- }
133
- const handle = maybeEnterScope(path, tracker, getAnonymousName);
134
- if (handle) scopeHandles.set(path, handle);
135
- },
136
- exit(path) {
137
- const handle = scopeHandles.get(path);
138
- if (handle) {
139
- tracker.exitScope(handle);
140
- scopeHandles.delete(path);
141
- }
142
- }
143
- });
144
- return metadata;
145
- };
146
- const collectExportBindings = (program) => {
147
- const bindings = /* @__PURE__ */ new Map();
148
- for (const statement of program.body) {
149
- if (__babel_core.types.isExportNamedDeclaration(statement) && statement.declaration) {
150
- const { declaration } = statement;
151
- if (__babel_core.types.isVariableDeclaration(declaration)) {
152
- for (const declarator of declaration.declarations) if (__babel_core.types.isIdentifier(declarator.id)) bindings.set(declarator.id.name, declarator.id.name);
153
- continue;
154
- }
155
- if ((__babel_core.types.isFunctionDeclaration(declaration) || __babel_core.types.isClassDeclaration(declaration)) && declaration.id) bindings.set(declaration.id.name, declaration.id.name);
156
- continue;
157
- }
158
- if (__babel_core.types.isExpressionStatement(statement) && __babel_core.types.isAssignmentExpression(statement.expression)) {
159
- const exportName = getCommonJsExportName(statement.expression.left);
160
- if (exportName) bindings.set(exportName, exportName);
161
- }
162
- }
163
- return bindings;
164
- };
165
- const getCommonJsExportName = (node) => {
166
- if (!__babel_core.types.isMemberExpression(node) || node.computed) return null;
167
- const isExports = __babel_core.types.isIdentifier(node.object, { name: "exports" });
168
- const isModuleExports = __babel_core.types.isMemberExpression(node.object) && __babel_core.types.isIdentifier(node.object.object, { name: "module" }) && __babel_core.types.isIdentifier(node.object.property, { name: "exports" });
169
- if (!isExports && !isModuleExports) return null;
170
- if (__babel_core.types.isIdentifier(node.property)) return node.property.name;
171
- if (__babel_core.types.isStringLiteral(node.property)) return node.property.value;
172
- return null;
173
- };
174
- const createAnonymousNameFactory = () => {
175
- const counters = /* @__PURE__ */ new Map();
176
- return (kind) => {
177
- const count = counters.get(kind) ?? 0;
178
- counters.set(kind, count + 1);
179
- return `${kind}#${count}`;
180
- };
181
- };
182
- const isGqlDefinitionCall = (node) => __babel_core.types.isCallExpression(node) && __babel_core.types.isMemberExpression(node.callee) && isGqlReference$1(node.callee.object) && node.arguments.length > 0 && __babel_core.types.isArrowFunctionExpression(node.arguments[0]);
183
- const isGqlReference$1 = (expr) => {
184
- if (__babel_core.types.isIdentifier(expr, { name: "gql" })) return true;
185
- if (!__babel_core.types.isMemberExpression(expr) || expr.computed) return false;
186
- if (__babel_core.types.isIdentifier(expr.property) && expr.property.name === "gql" || __babel_core.types.isStringLiteral(expr.property) && expr.property.value === "gql") return true;
187
- return isGqlReference$1(expr.object);
188
- };
189
- const resolveTopLevelExport = (callPath, exportBindings) => {
190
- const declarator = callPath.parentPath;
191
- if (declarator?.isVariableDeclarator()) {
192
- const { id } = declarator.node;
193
- if (__babel_core.types.isIdentifier(id)) {
194
- const exportBinding = exportBindings.get(id.name);
195
- if (exportBinding) return {
196
- isExported: true,
197
- exportBinding
198
- };
199
- }
200
- }
201
- const assignment = callPath.parentPath;
202
- if (assignment?.isAssignmentExpression()) {
203
- const exportName = getCommonJsExportName(assignment.node.left);
204
- if (exportName && exportBindings.has(exportName)) return {
205
- isExported: true,
206
- exportBinding: exportName
207
- };
208
- }
209
- return null;
210
- };
211
- const maybeEnterScope = (path, tracker, getAnonymousName) => {
212
- if (path.isAssignmentExpression()) {
213
- const exportName = getCommonJsExportName(path.node.left);
214
- if (exportName) return tracker.enterScope({
215
- segment: exportName,
216
- kind: "variable",
217
- stableKey: `var:${exportName}`
218
- });
219
- }
220
- if (path.isVariableDeclarator() && __babel_core.types.isIdentifier(path.node.id)) {
221
- const name = path.node.id.name;
222
- return tracker.enterScope({
223
- segment: name,
224
- kind: "variable",
225
- stableKey: `var:${name}`
226
- });
227
- }
228
- if (path.isArrowFunctionExpression()) {
229
- const name = getAnonymousName("arrow");
230
- return tracker.enterScope({
231
- segment: name,
232
- kind: "function",
233
- stableKey: "arrow"
234
- });
235
- }
236
- if (path.isFunctionDeclaration() || path.isFunctionExpression()) {
237
- const name = path.node.id?.name ?? getAnonymousName("function");
238
- return tracker.enterScope({
239
- segment: name,
240
- kind: "function",
241
- stableKey: `func:${name}`
242
- });
243
- }
244
- if (path.isClassDeclaration()) {
245
- const name = path.node.id?.name ?? getAnonymousName("class");
246
- return tracker.enterScope({
247
- segment: name,
248
- kind: "class",
249
- stableKey: `class:${name}`
250
- });
251
- }
252
- if (path.isClassMethod() && __babel_core.types.isIdentifier(path.node.key)) {
253
- const name = path.node.key.name;
254
- return tracker.enterScope({
255
- segment: name,
256
- kind: "method",
257
- stableKey: `member:${name}`
258
- });
259
- }
260
- if (path.isClassProperty() && __babel_core.types.isIdentifier(path.node.key)) {
261
- const name = path.node.key.name;
262
- return tracker.enterScope({
263
- segment: name,
264
- kind: "property",
265
- stableKey: `member:${name}`
266
- });
267
- }
268
- if (path.isObjectProperty()) {
269
- const key = path.node.key;
270
- const name = __babel_core.types.isIdentifier(key) ? key.name : __babel_core.types.isStringLiteral(key) ? key.value : null;
271
- if (name) return tracker.enterScope({
272
- segment: name,
273
- kind: "property",
274
- stableKey: `prop:${name}`
275
- });
276
- }
277
- return null;
278
- };
279
-
280
- //#endregion
281
- //#region packages/babel-plugin/src/ast/analysis.ts
282
- const extractGqlCall = ({ nodePath, filename, metadata, builderCall, getArtifact }) => {
283
- const callExpression = nodePath.node;
284
- const meta = metadata.get(callExpression);
285
- if (!meta) return (0, neverthrow.err)(createMetadataMissingError({ filename }));
286
- const canonicalId = (0, __soda_gql_plugin_common.resolveCanonicalId)(filename, meta.astPath);
287
- const artifact = getArtifact(canonicalId);
288
- if (!artifact) return (0, neverthrow.err)(createArtifactMissingError({
289
- filename,
290
- canonicalId
291
- }));
292
- if (artifact.type === "model") return (0, neverthrow.ok)({
293
- nodePath,
294
- canonicalId,
295
- builderCall,
296
- type: "model",
297
- artifact
298
- });
299
- if (artifact.type === "slice") return (0, neverthrow.ok)({
300
- nodePath,
301
- canonicalId,
302
- builderCall,
303
- type: "slice",
304
- artifact
305
- });
306
- if (artifact.type === "operation") return (0, neverthrow.ok)({
307
- nodePath,
308
- canonicalId,
309
- builderCall,
310
- type: "operation",
311
- artifact
312
- });
313
- if (artifact.type === "inlineOperation") return (0, neverthrow.ok)({
314
- nodePath,
315
- canonicalId,
316
- builderCall,
317
- type: "inlineOperation",
318
- artifact
319
- });
320
- return (0, neverthrow.err)(createUnsupportedArtifactTypeError({
321
- filename,
322
- canonicalId,
323
- artifactType: artifact.type
324
- }));
325
- };
326
- const createMetadataMissingError = ({ filename }) => ({
327
- type: "PluginError",
328
- stage: "analysis",
329
- code: "SODA_GQL_METADATA_NOT_FOUND",
330
- message: `No GraphQL metadata found for ${filename}`,
331
- cause: { filename },
332
- filename
333
- });
334
- const createArtifactMissingError = ({ filename, canonicalId }) => ({
335
- type: "PluginError",
336
- stage: "analysis",
337
- code: "SODA_GQL_ANALYSIS_ARTIFACT_NOT_FOUND",
338
- message: `No builder artifact found for canonical ID ${canonicalId}`,
339
- cause: {
340
- filename,
341
- canonicalId
342
- },
343
- filename,
344
- canonicalId
345
- });
346
- const createUnsupportedArtifactTypeError = ({ filename, canonicalId, artifactType }) => ({
347
- type: "PluginError",
348
- stage: "analysis",
349
- code: "SODA_GQL_UNSUPPORTED_ARTIFACT_TYPE",
350
- message: `Unsupported builder artifact type "${artifactType}" for canonical ID ${canonicalId}`,
351
- cause: {
352
- filename,
353
- canonicalId,
354
- artifactType
355
- },
356
- filename,
357
- canonicalId,
358
- artifactType
359
- });
360
- const findGqlBuilderCall = (callPath) => resolveBuilderCall(callPath.node);
361
- const resolveBuilderCall = (call) => {
362
- if (!isGqlMemberExpression(call.callee)) return null;
363
- if (call.arguments.length !== 1) return null;
364
- const factoryArg = call.arguments[0];
365
- if (!__babel_core.types.isArrowFunctionExpression(factoryArg)) return null;
366
- return extractBuilderCall(factoryArg);
367
- };
368
- const isGqlMemberExpression = (callee) => {
369
- return __babel_core.types.isMemberExpression(callee) && isSimpleProperty(callee.property) && isGqlReference(callee.object);
370
- };
371
- const isSimpleProperty = (property) => __babel_core.types.isIdentifier(property) || __babel_core.types.isStringLiteral(property) && property.value.length > 0;
372
- const isGqlReference = (expr) => {
373
- if (__babel_core.types.isIdentifier(expr, { name: "gql" })) return true;
374
- if (!__babel_core.types.isMemberExpression(expr) || expr.computed) return false;
375
- if (__babel_core.types.isIdentifier(expr.property) && expr.property.name === "gql" || __babel_core.types.isStringLiteral(expr.property) && expr.property.value === "gql") return true;
376
- return isGqlReference(expr.object);
377
- };
378
- const extractBuilderCall = (factory) => {
379
- if (__babel_core.types.isCallExpression(factory.body)) return factory.body;
380
- if (!__babel_core.types.isBlockStatement(factory.body)) return null;
381
- for (const statement of factory.body.body) if (__babel_core.types.isReturnStatement(statement) && statement.argument && __babel_core.types.isCallExpression(statement.argument)) return statement.argument;
382
- return null;
383
- };
384
-
385
- //#endregion
386
- //#region packages/babel-plugin/src/ast/ast.ts
387
- const clone = (node) => __babel_types.cloneNode(node, true);
388
- const buildObjectExpression = (properties) => __babel_types.objectExpression(Object.entries(properties).map(([key, value]) => __babel_types.objectProperty(__babel_types.identifier(key), value)));
389
-
390
- //#endregion
391
- //#region packages/babel-plugin/src/ast/runtime.ts
392
- const createMissingBuilderArgError = ({ filename, builderType, argName }) => ({
393
- type: "PluginError",
394
- stage: "transform",
395
- code: "SODA_GQL_TRANSFORM_MISSING_BUILDER_ARG",
396
- message: `${builderType} requires a ${argName} argument`,
397
- cause: {
398
- filename,
399
- builderType,
400
- argName
401
- },
402
- filename,
403
- builderType,
404
- argName
405
- });
406
- const buildModelRuntimeCall = ({ artifact, builderCall, filename }) => {
407
- const [, , normalize] = builderCall.arguments;
408
- if (!normalize || !__babel_core.types.isExpression(normalize)) return (0, neverthrow.err)(createMissingBuilderArgError({
409
- filename,
410
- builderType: "model",
411
- argName: "normalize"
412
- }));
413
- return (0, neverthrow.ok)(__babel_core.types.callExpression(__babel_core.types.memberExpression(__babel_core.types.identifier("gqlRuntime"), __babel_core.types.identifier("model")), [buildObjectExpression({
414
- prebuild: buildObjectExpression({ typename: __babel_core.types.stringLiteral(artifact.prebuild.typename) }),
415
- runtime: buildObjectExpression({ normalize: clone(normalize) })
416
- })]));
417
- };
418
- const buildSliceRuntimeCall = ({ artifact, builderCall, filename }) => {
419
- const [, , projectionBuilder] = builderCall.arguments;
420
- if (!projectionBuilder || !__babel_core.types.isExpression(projectionBuilder)) return (0, neverthrow.err)(createMissingBuilderArgError({
421
- filename,
422
- builderType: "slice",
423
- argName: "projectionBuilder"
424
- }));
425
- return (0, neverthrow.ok)(__babel_core.types.callExpression(__babel_core.types.memberExpression(__babel_core.types.identifier("gqlRuntime"), __babel_core.types.identifier("slice")), [buildObjectExpression({
426
- prebuild: buildObjectExpression({ operationType: __babel_core.types.stringLiteral(artifact.prebuild.operationType) }),
427
- runtime: buildObjectExpression({ buildProjection: clone(projectionBuilder) })
428
- })]));
429
- };
430
- const buildComposedOperationRuntimeComponents = ({ artifact, builderCall, filename }) => {
431
- const [, slicesBuilder] = builderCall.arguments;
432
- if (!slicesBuilder || !__babel_core.types.isExpression(slicesBuilder)) return (0, neverthrow.err)(createMissingBuilderArgError({
433
- filename,
434
- builderType: "composed operation",
435
- argName: "slicesBuilder"
436
- }));
437
- const runtimeCall = __babel_core.types.callExpression(__babel_core.types.memberExpression(__babel_core.types.identifier("gqlRuntime"), __babel_core.types.identifier("composedOperation")), [buildObjectExpression({
438
- prebuild: __babel_core.types.callExpression(__babel_core.types.memberExpression(__babel_core.types.identifier("JSON"), __babel_core.types.identifier("parse")), [__babel_core.types.stringLiteral(JSON.stringify(artifact.prebuild))]),
439
- runtime: buildObjectExpression({ getSlices: clone(slicesBuilder) })
440
- })]);
441
- return (0, neverthrow.ok)({
442
- referenceCall: __babel_core.types.callExpression(__babel_core.types.memberExpression(__babel_core.types.identifier("gqlRuntime"), __babel_core.types.identifier("getComposedOperation")), [__babel_core.types.stringLiteral(artifact.prebuild.operationName)]),
443
- runtimeCall
444
- });
445
- };
446
- const buildInlineOperationRuntimeComponents = ({ artifact }) => {
447
- const runtimeCall = __babel_core.types.callExpression(__babel_core.types.memberExpression(__babel_core.types.identifier("gqlRuntime"), __babel_core.types.identifier("inlineOperation")), [buildObjectExpression({
448
- prebuild: __babel_core.types.callExpression(__babel_core.types.memberExpression(__babel_core.types.identifier("JSON"), __babel_core.types.identifier("parse")), [__babel_core.types.stringLiteral(JSON.stringify(artifact.prebuild))]),
449
- runtime: buildObjectExpression({})
450
- })]);
451
- return (0, neverthrow.ok)({
452
- referenceCall: __babel_core.types.callExpression(__babel_core.types.memberExpression(__babel_core.types.identifier("gqlRuntime"), __babel_core.types.identifier("getInlineOperation")), [__babel_core.types.stringLiteral(artifact.prebuild.operationName)]),
453
- runtimeCall
454
- });
455
- };
456
-
457
- //#endregion
458
- //#region packages/babel-plugin/src/ast/transformer.ts
459
- const transformCallExpression = ({ callPath, filename, metadata, getArtifact }) => {
460
- const builderCall = findGqlBuilderCall(callPath);
461
- if (!builderCall) return (0, neverthrow.ok)({ transformed: false });
462
- const gqlCallResult = extractGqlCall({
463
- nodePath: callPath,
464
- filename,
465
- metadata,
466
- builderCall,
467
- getArtifact
468
- });
469
- if (gqlCallResult.isErr()) return (0, neverthrow.err)(gqlCallResult.error);
470
- const gqlCall = gqlCallResult.value;
471
- return replaceWithRuntimeCall(callPath, gqlCall, filename);
472
- };
473
- const replaceWithRuntimeCall = (callPath, gqlCall, filename) => {
474
- if (gqlCall.type === "model") {
475
- const result = buildModelRuntimeCall({
476
- ...gqlCall,
477
- filename
478
- });
479
- if (result.isErr()) return (0, neverthrow.err)(result.error);
480
- callPath.replaceWith(result.value);
481
- return (0, neverthrow.ok)({ transformed: true });
482
- }
483
- if (gqlCall.type === "slice") {
484
- const result = buildSliceRuntimeCall({
485
- ...gqlCall,
486
- filename
487
- });
488
- if (result.isErr()) return (0, neverthrow.err)(result.error);
489
- callPath.replaceWith(result.value);
490
- return (0, neverthrow.ok)({ transformed: true });
491
- }
492
- if (gqlCall.type === "operation") {
493
- const result = buildComposedOperationRuntimeComponents({
494
- ...gqlCall,
495
- filename
496
- });
497
- if (result.isErr()) return (0, neverthrow.err)(result.error);
498
- const { referenceCall, runtimeCall } = result.value;
499
- callPath.replaceWith(referenceCall);
500
- return (0, neverthrow.ok)({
501
- transformed: true,
502
- runtimeCall
503
- });
504
- }
505
- if (gqlCall.type === "inlineOperation") {
506
- const result = buildInlineOperationRuntimeComponents({
507
- ...gqlCall,
508
- filename
509
- });
510
- if (result.isErr()) return (0, neverthrow.err)(result.error);
511
- const { referenceCall, runtimeCall } = result.value;
512
- callPath.replaceWith(referenceCall);
513
- return (0, neverthrow.ok)({
514
- transformed: true,
515
- runtimeCall
516
- });
517
- }
518
- return (0, neverthrow.ok)({ transformed: false });
519
- };
520
-
521
- //#endregion
522
- //#region packages/babel-plugin/src/transformer.ts
523
- /**
524
- * Creates a Babel transformer with a single transform() method.
525
- * This matches the pattern used in the TypeScript plugin.
526
- */
527
- const createTransformer = ({ programPath, types, config }) => {
528
- const graphqlSystemIdentifyHelper = (0, __soda_gql_builder.createGraphqlSystemIdentifyHelper)(config);
529
- /**
530
- * Check if a node is a require() or __webpack_require__() call.
531
- */
532
- const isRequireCall = (node) => {
533
- if (!types.isCallExpression(node)) return false;
534
- const callee = node.callee;
535
- return types.isIdentifier(callee) && (callee.name === "require" || callee.name === "__webpack_require__");
536
- };
537
- /**
538
- * Find the last statement that loads a module (import or require).
539
- * Handles both ESM imports and CommonJS require() calls.
540
- */
541
- const findLastModuleLoader = () => {
542
- const bodyPaths = programPath.get("body");
543
- let lastLoader = null;
544
- for (const path of bodyPaths) {
545
- if (path.isImportDeclaration()) {
546
- lastLoader = path;
547
- continue;
548
- }
549
- if (path.isVariableDeclaration()) {
550
- for (const declarator of path.node.declarations) if (declarator.init && isRequireCall(declarator.init)) {
551
- lastLoader = path;
552
- break;
553
- }
554
- continue;
555
- }
556
- if (path.isExpressionStatement()) {
557
- if (isRequireCall(path.node.expression)) lastLoader = path;
558
- }
559
- }
560
- return lastLoader;
561
- };
562
- return { transform: (context) => {
563
- const metadata = collectGqlDefinitionMetadata({
564
- programPath,
565
- filename: context.filename
566
- });
567
- const runtimeCalls = [];
568
- let transformed = false;
569
- programPath.traverse({ CallExpression: (callPath) => {
570
- const result = transformCallExpression({
571
- callPath,
572
- filename: context.filename,
573
- metadata,
574
- getArtifact: context.artifactLookup
575
- });
576
- if (result.isErr()) {
577
- console.error(`[@soda-gql/babel-plugin] ${(0, __soda_gql_plugin_common.formatPluginError)(result.error)}`);
578
- return;
579
- }
580
- const transformResult = result.value;
581
- if (transformResult.transformed) {
582
- transformed = true;
583
- if (transformResult.runtimeCall) runtimeCalls.push(transformResult.runtimeCall);
584
- }
585
- } });
586
- if (!transformed) return {
587
- transformed: false,
588
- runtimeArtifacts: void 0
589
- };
590
- ensureGqlRuntimeImport(programPath);
591
- if (runtimeCalls.length > 0) {
592
- const statements = runtimeCalls.map((expr) => types.expressionStatement(expr));
593
- const lastLoaderPath = findLastModuleLoader();
594
- if (lastLoaderPath) lastLoaderPath.insertAfter(statements);
595
- else programPath.unshiftContainer("body", statements);
596
- }
597
- programPath.scope.crawl();
598
- removeGraphqlSystemImports(programPath, graphqlSystemIdentifyHelper, context.filename);
599
- return {
600
- transformed: true,
601
- runtimeArtifacts: void 0
602
- };
603
- } };
604
- };
605
4
 
606
- //#endregion
607
5
  //#region packages/babel-plugin/src/plugin.ts
608
6
  const fallbackPlugin = () => ({
609
7
  name: "@soda-gql/babel-plugin",
@@ -619,7 +17,7 @@ const createPlugin = ({ pluginSession }) => ({
619
17
  if (!filename) return;
620
18
  const artifact = state._artifact;
621
19
  if (!artifact) return;
622
- createTransformer({
20
+ (0, __soda_gql_babel_transformer.createTransformer)({
623
21
  programPath,
624
22
  types: __babel_core.types,
625
23
  config: pluginSession.config
@@ -642,7 +40,7 @@ const createPluginWithArtifact = ({ artifact, config }) => ({
642
40
  visitor: { Program(programPath, state) {
643
41
  const filename = state.file?.opts?.filename;
644
42
  if (!filename) return;
645
- createTransformer({
43
+ (0, __soda_gql_babel_transformer.createTransformer)({
646
44
  programPath,
647
45
  types: __babel_core.types,
648
46
  config
@@ -653,12 +51,8 @@ const createPluginWithArtifact = ({ artifact, config }) => ({
653
51
  } }
654
52
  });
655
53
 
656
- //#endregion
657
- //#region packages/babel-plugin/src/index.ts
658
- var src_default = createSodaGqlPlugin;
659
-
660
54
  //#endregion
661
55
  exports.createPlugin = createPlugin;
662
56
  exports.createPluginWithArtifact = createPluginWithArtifact;
663
57
  exports.createSodaGqlPlugin = createSodaGqlPlugin;
664
- exports.default = src_default;
58
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.cjs","names":["t"],"sources":["../src/plugin.ts"],"sourcesContent":["import type { PluginObj, PluginPass } from \"@babel/core\";\nimport { types as t } from \"@babel/core\";\nimport type { NodePath } from \"@babel/traverse\";\nimport { createTransformer } from \"@soda-gql/babel-transformer\";\nimport type { BuilderArtifact } from \"@soda-gql/builder\";\nimport type { CanonicalId } from \"@soda-gql/common\";\nimport type { ResolvedSodaGqlConfig } from \"@soda-gql/config\";\nimport { createPluginSession, type PluginOptions, type PluginSession } from \"@soda-gql/plugin-common\";\n\ntype PluginPassState = PluginPass & {\n _artifact?: BuilderArtifact | null;\n};\n\nconst fallbackPlugin = (): PluginObj => ({\n name: \"@soda-gql/babel-plugin\",\n visitor: {\n Program() {\n // No-op fallback\n },\n },\n});\n\nexport const createPlugin = ({ pluginSession }: { pluginSession: PluginSession }): PluginObj<PluginPassState> => ({\n name: \"@soda-gql/babel-plugin\",\n\n async pre() {\n this._artifact = await pluginSession.getArtifactAsync();\n },\n\n visitor: {\n Program(programPath: NodePath<t.Program>, state) {\n const filename = state.file?.opts?.filename;\n if (!filename) {\n return;\n }\n\n const artifact = state._artifact;\n if (!artifact) {\n return;\n }\n\n // Create Babel transformer instance\n const transformer = createTransformer({\n programPath,\n types: t,\n config: pluginSession.config,\n });\n\n // Transform using single method call (matches TypeScript plugin pattern)\n transformer.transform({\n filename,\n artifactLookup: (canonicalId: CanonicalId) => artifact.elements[canonicalId],\n });\n },\n },\n});\n\nexport const createSodaGqlPlugin = (_babel: unknown, options: PluginOptions = {}): PluginObj => {\n // Create plugin session synchronously (no async pre())\n const pluginSession = createPluginSession(options, \"@soda-gql/babel-plugin\");\n\n return pluginSession ? createPlugin({ pluginSession }) : fallbackPlugin();\n};\n\n/**\n * Create a Babel plugin with an already-built artifact.\n * Use this when the artifact is pre-built (e.g., by a bundler plugin).\n */\nexport const createPluginWithArtifact = ({\n artifact,\n config,\n}: {\n artifact: BuilderArtifact;\n config: ResolvedSodaGqlConfig;\n}): PluginObj => ({\n name: \"@soda-gql/babel-plugin\",\n\n visitor: {\n Program(programPath: NodePath<t.Program>, state) {\n const filename = state.file?.opts?.filename;\n if (!filename) {\n return;\n }\n\n // Create Babel transformer instance\n const transformer = createTransformer({\n programPath,\n types: t,\n config,\n });\n\n // Transform using single method call (matches TypeScript plugin pattern)\n transformer.transform({\n filename,\n artifactLookup: (canonicalId: CanonicalId) => artifact.elements[canonicalId],\n });\n },\n },\n});\n"],"mappings":";;;;;AAaA,MAAM,wBAAmC;CACvC,MAAM;CACN,SAAS,EACP,UAAU,IAGX;CACF;AAED,MAAa,gBAAgB,EAAE,qBAAmF;CAChH,MAAM;CAEN,MAAM,MAAM;AACV,OAAK,YAAY,MAAM,cAAc,kBAAkB;;CAGzD,SAAS,EACP,QAAQ,aAAkC,OAAO;EAC/C,MAAM,WAAW,MAAM,MAAM,MAAM;AACnC,MAAI,CAAC,SACH;EAGF,MAAM,WAAW,MAAM;AACvB,MAAI,CAAC,SACH;AAWF,sDAPsC;GACpC;GACA,OAAOA;GACP,QAAQ,cAAc;GACvB,CAAC,CAGU,UAAU;GACpB;GACA,iBAAiB,gBAA6B,SAAS,SAAS;GACjE,CAAC;IAEL;CACF;AAED,MAAa,uBAAuB,QAAiB,UAAyB,EAAE,KAAgB;CAE9F,MAAM,kEAAoC,SAAS,yBAAyB;AAE5E,QAAO,gBAAgB,aAAa,EAAE,eAAe,CAAC,GAAG,gBAAgB;;;;;;AAO3E,MAAa,4BAA4B,EACvC,UACA,cAIgB;CAChB,MAAM;CAEN,SAAS,EACP,QAAQ,aAAkC,OAAO;EAC/C,MAAM,WAAW,MAAM,MAAM,MAAM;AACnC,MAAI,CAAC,SACH;AAWF,sDAPsC;GACpC;GACA,OAAOA;GACP;GACD,CAAC,CAGU,UAAU;GACpB;GACA,iBAAiB,gBAA6B,SAAS,SAAS;GACjE,CAAC;IAEL;CACF"}
package/dist/index.d.cts CHANGED
@@ -25,5 +25,5 @@ declare const createPluginWithArtifact: ({
25
25
  config: ResolvedSodaGqlConfig;
26
26
  }) => PluginObj;
27
27
  //#endregion
28
- export { createPlugin, createPluginWithArtifact, createSodaGqlPlugin, createSodaGqlPlugin as default };
28
+ export { createPlugin, createPluginWithArtifact, createSodaGqlPlugin };
29
29
  //# sourceMappingURL=index.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.cts","names":[],"sources":["../src/plugin.ts"],"sourcesContent":[],"mappings":";;;;;;KAQK,eAAA,GAAkB;cACT;AAJwF,CAAA;AAgBzF,cAAA,YAiCX,EAAA,CAAA;EAAA;CAAA,EAAA;EAjC2B,aAAA,EAAoC,aAApC;CAAoC,EAAA,GAAkB,SAAlB,CAA4B,eAA5B,CAAA;AAA4B,cAmChF,mBAnCgF,EAAA,CAAA,MAAA,EAAA,OAAA,EAAA,OAAA,CAAA,EAmC/B,aAnC+B,EAAA,GAmCV,SAnCU;;;AAmC7F;AAWA;AAAyC,cAA5B,wBAA4B,EAAA,CAAA;EAAA,QAAA;EAAA;CAAA,EAAA;EAAA,QAAA,EAI7B,eAJ6B;EAI7B,MAAA,EACF,qBADE;CACF,EAAA,GACN,SADM"}
1
+ {"version":3,"file":"index.d.cts","names":[],"sources":["../src/plugin.ts"],"sourcesContent":[],"mappings":";;;;;;KASK,eAAA,GAAkB;cACT;AAHwF,CAAA;AAezF,cAAA,YAiCX,EAAA,CAAA;EAAA;CAAA,EAAA;EAjC2B,aAAA,EAAoC,aAApC;CAAoC,EAAA,GAAkB,SAAlB,CAA4B,eAA5B,CAAA;AAA4B,cAmChF,mBAnCgF,EAAA,CAAA,MAAA,EAAA,OAAA,EAAA,OAAA,CAAA,EAmC/B,aAnC+B,EAAA,GAmCV,SAnCU;;;AAmC7F;AAWA;AAAyC,cAA5B,wBAA4B,EAAA,CAAA;EAAA,QAAA;EAAA;CAAA,EAAA;EAAA,QAAA,EAI7B,eAJ6B;EAI7B,MAAA,EACF,qBADE;CACF,EAAA,GACN,SADM"}
package/dist/index.d.mts CHANGED
@@ -25,5 +25,5 @@ declare const createPluginWithArtifact: ({
25
25
  config: ResolvedSodaGqlConfig;
26
26
  }) => PluginObj;
27
27
  //#endregion
28
- export { createPlugin, createPluginWithArtifact, createSodaGqlPlugin, createSodaGqlPlugin as default };
28
+ export { createPlugin, createPluginWithArtifact, createSodaGqlPlugin };
29
29
  //# sourceMappingURL=index.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../src/plugin.ts"],"sourcesContent":[],"mappings":";;;;;;KAQK,eAAA,GAAkB;cACT;AAJwF,CAAA;AAgBzF,cAAA,YAiCX,EAAA,CAAA;EAAA;CAAA,EAAA;EAjC2B,aAAA,EAAoC,aAApC;CAAoC,EAAA,GAAkB,SAAlB,CAA4B,eAA5B,CAAA;AAA4B,cAmChF,mBAnCgF,EAAA,CAAA,MAAA,EAAA,OAAA,EAAA,OAAA,CAAA,EAmC/B,aAnC+B,EAAA,GAmCV,SAnCU;;;AAmC7F;AAWA;AAAyC,cAA5B,wBAA4B,EAAA,CAAA;EAAA,QAAA;EAAA;CAAA,EAAA;EAAA,QAAA,EAI7B,eAJ6B;EAI7B,MAAA,EACF,qBADE;CACF,EAAA,GACN,SADM"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../src/plugin.ts"],"sourcesContent":[],"mappings":";;;;;;KASK,eAAA,GAAkB;cACT;AAHwF,CAAA;AAezF,cAAA,YAiCX,EAAA,CAAA;EAAA;CAAA,EAAA;EAjC2B,aAAA,EAAoC,aAApC;CAAoC,EAAA,GAAkB,SAAlB,CAA4B,eAA5B,CAAA;AAA4B,cAmChF,mBAnCgF,EAAA,CAAA,MAAA,EAAA,OAAA,EAAA,OAAA,CAAA,EAmC/B,aAnC+B,EAAA,GAmCV,SAnCU;;;AAmC7F;AAWA;AAAyC,cAA5B,wBAA4B,EAAA,CAAA;EAAA,QAAA;EAAA;CAAA,EAAA;EAAA,QAAA,EAI7B,eAJ6B;EAI7B,MAAA,EACF,qBADE;CACF,EAAA,GACN,SADM"}