@soda-gql/swc-transformer 0.4.1 → 0.4.2

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@soda-gql/swc-transformer",
3
- "version": "0.4.1",
3
+ "version": "0.4.2",
4
4
  "description": "SWC-based native transformer for soda-gql",
5
5
  "type": "module",
6
6
  "private": false,
@@ -57,25 +57,25 @@
57
57
  },
58
58
  "dependencies": {
59
59
  "@ampproject/remapping": "^2.3.0",
60
- "@soda-gql/builder": "0.4.1",
61
- "@soda-gql/common": "0.4.1",
62
- "@soda-gql/config": "0.4.1",
63
- "@soda-gql/core": "0.4.1",
64
- "@soda-gql/plugin-common": "0.4.1"
60
+ "@soda-gql/builder": "0.4.2",
61
+ "@soda-gql/common": "0.4.2",
62
+ "@soda-gql/config": "0.4.2",
63
+ "@soda-gql/core": "0.4.2",
64
+ "@soda-gql/plugin-common": "0.4.2"
65
65
  },
66
66
  "devDependencies": {
67
67
  "@napi-rs/cli": "^2.18.4",
68
- "@soda-gql/tsc-transformer": "0.4.1",
68
+ "@soda-gql/tsc-transformer": "0.4.2",
69
69
  "prettier": "^3.4.2"
70
70
  },
71
71
  "peerDependencies": {
72
72
  "@swc/core": "^1.0.0"
73
73
  },
74
74
  "optionalDependencies": {
75
- "@soda-gql/swc-transformer-darwin-x64": "0.4.1",
76
- "@soda-gql/swc-transformer-darwin-arm64": "0.4.1",
77
- "@soda-gql/swc-transformer-linux-x64-musl": "0.4.1",
78
- "@soda-gql/swc-transformer-win32-x64-msvc": "0.4.1",
79
- "@soda-gql/swc-transformer-linux-x64-gnu": "0.4.1"
75
+ "@soda-gql/swc-transformer-darwin-x64": "0.4.2",
76
+ "@soda-gql/swc-transformer-darwin-arm64": "0.4.2",
77
+ "@soda-gql/swc-transformer-linux-x64-musl": "0.4.2",
78
+ "@soda-gql/swc-transformer-win32-x64-msvc": "0.4.2",
79
+ "@soda-gql/swc-transformer-linux-x64-gnu": "0.4.2"
80
80
  }
81
81
  }
@@ -0,0 +1,203 @@
1
+ /**
2
+ * Conformance tests for swc-transformer.
3
+ *
4
+ * These tests verify that the swc-transformer produces the same output as
5
+ * tsc-transformer, ensuring behavioral equivalence between the two implementations.
6
+ */
7
+
8
+ import { describe, expect, it } from "bun:test";
9
+ import { loadTestCases, normalizeCode, type TransformTestCase } from "@soda-gql/tsc-transformer/test";
10
+
11
+ // Check if native module is available before running tests
12
+ // This needs to be evaluated synchronously at module load time
13
+ // because it.skipIf() evaluates its condition at test registration time
14
+ let nativeModuleAvailable = false;
15
+ let createTransformer: typeof import("./index").createTransformer;
16
+ let initError: string | null = null;
17
+
18
+ // Synchronously check if native module can be loaded
19
+ // We use a top-level await to ensure this runs before test registration
20
+ try {
21
+ const mod = await import("../src/index");
22
+ createTransformer = mod.createTransformer;
23
+ // Actually try to create a transformer - this will fail if native module is missing
24
+ await createTransformer({
25
+ config: {
26
+ analyzer: "ts",
27
+ outdir: "/tmp",
28
+ graphqlSystemAliases: [],
29
+ include: [],
30
+ exclude: [],
31
+ schemas: {},
32
+ styles: { importExtension: false },
33
+ plugins: {},
34
+ },
35
+ artifact: {
36
+ elements: {},
37
+ report: { durationMs: 0, warnings: [], stats: { hits: 0, misses: 0, skips: 0 } },
38
+ },
39
+ });
40
+ nativeModuleAvailable = true;
41
+ } catch (e) {
42
+ initError = e instanceof Error ? e.message : String(e);
43
+ console.warn("[swc-transformer] Native module not available - tests will be skipped:", initError);
44
+ }
45
+
46
+ /**
47
+ * Transform source code using swc-transformer.
48
+ */
49
+ const transformWithSwc = async ({
50
+ sourceCode,
51
+ sourcePath,
52
+ artifact,
53
+ config,
54
+ moduleFormat,
55
+ }: {
56
+ readonly sourceCode: string;
57
+ readonly sourcePath: string;
58
+ readonly artifact: TransformTestCase["input"]["artifact"];
59
+ readonly config: Parameters<typeof createTransformer>[0]["config"];
60
+ readonly moduleFormat: "esm" | "cjs";
61
+ }): Promise<string> => {
62
+ if (!createTransformer) {
63
+ throw new Error("createTransformer not available");
64
+ }
65
+ const transformer = await createTransformer({
66
+ compilerOptions: {
67
+ module: moduleFormat === "esm" ? "ESNext" : "CommonJS",
68
+ },
69
+ config,
70
+ artifact,
71
+ });
72
+
73
+ const result = transformer.transform({ sourceCode, sourcePath });
74
+ return result.sourceCode;
75
+ };
76
+
77
+ describe("swc-transformer", async () => {
78
+ // Explicit check that fails when running in the swc-transformer-specific CI job
79
+ // The SWC_TRANSFORMER_CI env var is set by the dedicated swc-transformer workflow job
80
+ // This prevents that job from silently passing when native module build is broken
81
+ it("should have native module available when SWC_TRANSFORMER_CI is set", () => {
82
+ const isSwcTransformerCi = process.env.SWC_TRANSFORMER_CI === "true" || process.env.SWC_TRANSFORMER_CI === "1";
83
+
84
+ if (isSwcTransformerCi && !nativeModuleAvailable) {
85
+ throw new Error(
86
+ `Native module required in swc-transformer CI job but not available. ` +
87
+ `Run 'bun run build' in packages/swc-transformer. ` +
88
+ `Error: ${initError}`,
89
+ );
90
+ }
91
+
92
+ // In main test suite or local dev, just pass (other tests will be skipped if needed)
93
+ expect(true).toBe(true);
94
+ });
95
+
96
+ const testCases = await loadTestCases();
97
+
98
+ for (const testCase of testCases) {
99
+ describe(testCase.id, () => {
100
+ if (testCase.expectations.shouldTransform) {
101
+ it.skipIf(!nativeModuleAvailable)("should transform to ESM correctly", async () => {
102
+ const result = await transformWithSwc({
103
+ sourceCode: testCase.input.sourceCode,
104
+ sourcePath: testCase.input.sourcePath,
105
+ artifact: testCase.input.artifact,
106
+ config: {
107
+ analyzer: "ts",
108
+ outdir: "/tmp",
109
+ graphqlSystemAliases: ["@/graphql-system"],
110
+ include: [],
111
+ exclude: [],
112
+ schemas: {
113
+ default: {
114
+ schema: "/tmp/schema.graphql",
115
+ inject: { scalars: "/tmp/scalars.ts" },
116
+ },
117
+ },
118
+ styles: { importExtension: false },
119
+ plugins: {},
120
+ },
121
+ moduleFormat: "esm",
122
+ });
123
+ const normalized = await normalizeCode(result);
124
+
125
+ // Verify expected runtime calls are present
126
+ for (const call of testCase.expectations.runtimeCalls) {
127
+ expect(normalized).toContain(call);
128
+ }
129
+
130
+ // Verify runtime import is added when expected
131
+ if (testCase.expectations.shouldAddRuntimeImport) {
132
+ expect(normalized).toContain("@soda-gql/runtime");
133
+ }
134
+
135
+ // Verify gql.default import is removed
136
+ expect(normalized).not.toContain("gql.default");
137
+ });
138
+
139
+ it.skipIf(!nativeModuleAvailable)("should transform to CJS correctly", async () => {
140
+ const result = await transformWithSwc({
141
+ sourceCode: testCase.input.sourceCode,
142
+ sourcePath: testCase.input.sourcePath,
143
+ artifact: testCase.input.artifact,
144
+ config: {
145
+ analyzer: "ts",
146
+ outdir: "/tmp",
147
+ graphqlSystemAliases: ["@/graphql-system"],
148
+ include: [],
149
+ exclude: [],
150
+ schemas: {
151
+ default: {
152
+ schema: "/tmp/schema.graphql",
153
+ inject: { scalars: "/tmp/scalars.ts" },
154
+ },
155
+ },
156
+ styles: { importExtension: false },
157
+ plugins: {},
158
+ },
159
+ moduleFormat: "cjs",
160
+ });
161
+ const normalized = await normalizeCode(result);
162
+
163
+ // Verify expected runtime calls are present
164
+ for (const call of testCase.expectations.runtimeCalls) {
165
+ expect(normalized).toContain(call);
166
+ }
167
+
168
+ // Verify gql.default call is removed
169
+ expect(normalized).not.toContain("gql.default");
170
+ });
171
+ } else {
172
+ it.skipIf(!nativeModuleAvailable)("should not transform the source", async () => {
173
+ const result = await transformWithSwc({
174
+ sourceCode: testCase.input.sourceCode,
175
+ sourcePath: testCase.input.sourcePath,
176
+ artifact: testCase.input.artifact,
177
+ config: {
178
+ analyzer: "ts",
179
+ outdir: "/tmp",
180
+ graphqlSystemAliases: ["@/graphql-system"],
181
+ include: [],
182
+ exclude: [],
183
+ schemas: {
184
+ default: {
185
+ schema: "/tmp/schema.graphql",
186
+ inject: { scalars: "/tmp/scalars.ts" },
187
+ },
188
+ },
189
+ styles: { importExtension: false },
190
+ plugins: {},
191
+ },
192
+ moduleFormat: "esm",
193
+ });
194
+
195
+ // Verify no runtime calls are added
196
+ expect(result).not.toContain("gqlRuntime.");
197
+ // Verify no runtime import is added
198
+ expect(result).not.toContain("@soda-gql/runtime");
199
+ });
200
+ }
201
+ });
202
+ }
203
+ });