@simplysm/sd-cli 14.0.44 → 14.0.45

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/dist/deps/server-externals/server-production-files.d.ts +10 -5
  2. package/dist/deps/server-externals/server-production-files.d.ts.map +1 -1
  3. package/dist/deps/server-externals/server-production-files.js +22 -26
  4. package/dist/deps/server-externals/server-production-files.js.map +1 -1
  5. package/dist/esbuild/esbuild-angular-compiler-plugin.d.ts +3 -8
  6. package/dist/esbuild/esbuild-angular-compiler-plugin.d.ts.map +1 -1
  7. package/dist/esbuild/esbuild-angular-compiler-plugin.js +57 -83
  8. package/dist/esbuild/esbuild-angular-compiler-plugin.js.map +1 -1
  9. package/dist/esbuild/esbuild-worker-plugin.d.ts +30 -0
  10. package/dist/esbuild/esbuild-worker-plugin.d.ts.map +1 -0
  11. package/dist/esbuild/esbuild-worker-plugin.js +197 -0
  12. package/dist/esbuild/esbuild-worker-plugin.js.map +1 -0
  13. package/dist/workers/server-build.worker.d.ts.map +1 -1
  14. package/dist/workers/server-build.worker.js +6 -5
  15. package/dist/workers/server-build.worker.js.map +1 -1
  16. package/dist/workers/server-esbuild-context.d.ts.map +1 -1
  17. package/dist/workers/server-esbuild-context.js +3 -1
  18. package/dist/workers/server-esbuild-context.js.map +1 -1
  19. package/dist/workers/server-watch-manager.js +1 -1
  20. package/dist/workers/server-watch-manager.js.map +1 -1
  21. package/package.json +5 -4
  22. package/src/deps/server-externals/server-production-files.ts +26 -28
  23. package/src/esbuild/esbuild-angular-compiler-plugin.ts +82 -123
  24. package/src/esbuild/esbuild-worker-plugin.ts +266 -0
  25. package/src/workers/server-build.worker.ts +6 -5
  26. package/src/workers/server-esbuild-context.ts +3 -1
  27. package/src/workers/server-watch-manager.ts +1 -1
  28. package/tests/esbuild/esbuild-angular-compiler-plugin-worker.verify.md +56 -28
  29. package/tests/esbuild/esbuild-worker-plugin-node.verify.md +11 -0
  30. package/tests/esbuild/esbuild-worker-plugin.acc.spec.ts +318 -0
  31. package/tests/esbuild/esbuild-worker-plugin.spec.ts +297 -0
  32. package/tests/esbuild/esbuild-worker-plugin.verify.md +7 -0
  33. package/tests/esbuild/fixtures/worker-plugin/node-worker.js +2 -0
  34. package/tests/esbuild/fixtures/worker-plugin/shared-worker.js +6 -0
  35. package/tests/esbuild/fixtures/worker-plugin/worker-error.js +1 -0
  36. package/tests/esbuild/fixtures/worker-plugin/worker.js +3 -0
  37. package/tests/esbuild/fixtures/worker-plugin/worker2.js +3 -0
  38. package/tests/workers/server-build-worker-plugin.verify.md +9 -0
  39. package/tests/workers/server-build-worker.spec.ts +26 -12
  40. package/tests/workers/server-esbuild-context.spec.ts +13 -5
  41. package/tests/workers/server-watch-manager.acc.spec.ts +2 -2
  42. package/tests/workers/server-watch-manager.spec.ts +2 -2
  43. package/dist/angular/web-worker-transformer.d.ts +0 -9
  44. package/dist/angular/web-worker-transformer.d.ts.map +0 -1
  45. package/dist/angular/web-worker-transformer.js +0 -73
  46. package/dist/angular/web-worker-transformer.js.map +0 -1
  47. package/src/angular/web-worker-transformer.ts +0 -117
  48. package/tests/angular/web-worker-transformer.spec.ts +0 -154
@@ -1,117 +0,0 @@
1
- import ts from "typescript";
2
-
3
- /**
4
- * Web Worker/SharedWorker의 `new Worker(new URL('path', import.meta.url))` 패턴을
5
- * 감지하여 fileProcessor로 번들된 경로로 치환하는 TypeScript transformer를 생성한다.
6
- *
7
- * @angular/build의 web-worker-transformer.js 원본을 이식한 구현.
8
- */
9
- export function createWorkerTransformer(
10
- fileProcessor: (workerFile: string, containingFile: string) => string,
11
- ): ts.TransformerFactory<ts.SourceFile> {
12
- return (context) => {
13
- const nodeFactory = context.factory;
14
-
15
- const visitNode = (node: ts.Node): ts.Node => {
16
- // new Worker(...) 또는 new SharedWorker(...) 감지
17
- if (
18
- !ts.isNewExpression(node) ||
19
- !ts.isIdentifier(node.expression) ||
20
- (node.expression.text !== "Worker" && node.expression.text !== "SharedWorker")
21
- ) {
22
- return ts.visitEachChild(node, visitNode, context);
23
- }
24
-
25
- // Worker 인자: 1개 또는 2개
26
- if (node.arguments == null || node.arguments.length < 1 || node.arguments.length > 2) {
27
- return node;
28
- }
29
-
30
- // 첫 인자: new URL(...)
31
- const workerUrlNode = node.arguments[0];
32
- if (
33
- !ts.isNewExpression(workerUrlNode) ||
34
- !ts.isIdentifier(workerUrlNode.expression) ||
35
- workerUrlNode.expression.text !== "URL"
36
- ) {
37
- return node;
38
- }
39
-
40
- // URL 인자: 정확히 2개
41
- if (workerUrlNode.arguments == null || workerUrlNode.arguments.length !== 2) {
42
- return node;
43
- }
44
-
45
- // URL 첫 인자: 문자열 리터럴
46
- if (!ts.isStringLiteralLike(workerUrlNode.arguments[0])) {
47
- return node;
48
- }
49
-
50
- // URL 둘째 인자: import.meta.url
51
- const secondArg = workerUrlNode.arguments[1];
52
- if (
53
- !ts.isPropertyAccessExpression(secondArg) ||
54
- !ts.isMetaProperty(secondArg.expression) ||
55
- secondArg.name.text !== "url"
56
- ) {
57
- return node;
58
- }
59
-
60
- const filePath = workerUrlNode.arguments[0].text;
61
- const importer = node.getSourceFile().fileName;
62
-
63
- // fileProcessor 호출
64
- const replacementPath = fileProcessor(filePath, importer);
65
-
66
- // 경로가 변경되지 않았으면 원본 유지
67
- if (replacementPath === filePath) {
68
- return node;
69
- }
70
-
71
- // AST 치환
72
- return nodeFactory.updateNewExpression(
73
- node,
74
- node.expression,
75
- node.typeArguments,
76
- ts.setTextRange(
77
- nodeFactory.createNodeArray(
78
- [
79
- // URL 인자 치환
80
- nodeFactory.updateNewExpression(
81
- workerUrlNode,
82
- workerUrlNode.expression,
83
- workerUrlNode.typeArguments,
84
- ts.setTextRange(
85
- nodeFactory.createNodeArray(
86
- [nodeFactory.createStringLiteral(replacementPath), workerUrlNode.arguments[1]],
87
- workerUrlNode.arguments.hasTrailingComma,
88
- ),
89
- workerUrlNode.arguments,
90
- ),
91
- ),
92
- // 두 번째 인자: 기존 options가 있으면 유지, 없으면 { type: 'module' } 추가
93
- node.arguments.length > 1
94
- ? node.arguments[1]
95
- : nodeFactory.createObjectLiteralExpression([
96
- nodeFactory.createPropertyAssignment(
97
- "type",
98
- nodeFactory.createStringLiteral("module"),
99
- ),
100
- ]),
101
- ],
102
- node.arguments.hasTrailingComma,
103
- ),
104
- node.arguments,
105
- ),
106
- );
107
- };
108
-
109
- return (sourceFile) => {
110
- // 'Worker' 문자열이 없으면 변환을 건너뛴다
111
- if (!sourceFile.text.includes("Worker")) {
112
- return sourceFile;
113
- }
114
- return ts.visitEachChild(sourceFile, visitNode, context);
115
- };
116
- };
117
- }
@@ -1,154 +0,0 @@
1
- import { describe, it, expect, vi } from "vitest";
2
- import ts from "typescript";
3
-
4
- const { createWorkerTransformer } = await import(
5
- "../../src/angular/web-worker-transformer.js"
6
- );
7
-
8
- //#region 헬퍼
9
-
10
- /**
11
- * TypeScript 소스 코드에 transformer를 적용하고 결과 코드를 반환한다.
12
- */
13
- function transformCode(
14
- code: string,
15
- fileProcessor: (workerFile: string, containingFile: string) => string,
16
- fileName = "test.ts",
17
- ): string {
18
- const sourceFile = ts.createSourceFile(fileName, code, ts.ScriptTarget.ES2022, true);
19
- const transformer = createWorkerTransformer(fileProcessor);
20
- const result = ts.transform(sourceFile, [transformer]);
21
- const printer = ts.createPrinter();
22
- const output = printer.printFile(result.transformed[0]);
23
- result.dispose();
24
- return output;
25
- }
26
-
27
- //#endregion
28
-
29
- describe("createWorkerTransformer", () => {
30
- // Acceptance: Worker 표준 패턴을 감지하여 번들된 경로로 치환한다
31
- it("Worker 표준 패턴 — URL 치환 + { type: 'module' } 자동 추가", () => {
32
- const fileProcessor = vi.fn().mockReturnValue("worker-ABCD1234.js");
33
- const code = `const w = new Worker(new URL('./my-worker.ts', import.meta.url));`;
34
-
35
- const output = transformCode(code, fileProcessor);
36
-
37
- expect(fileProcessor).toHaveBeenCalledWith("./my-worker.ts", "test.ts");
38
- expect(output).toContain('"worker-ABCD1234.js"');
39
- expect(output).toContain('type');
40
- expect(output).toContain('"module"');
41
- expect(output).not.toContain("./my-worker.ts");
42
- });
43
-
44
- // Acceptance: SharedWorker도 동일하게 처리한다
45
- it("SharedWorker도 동일하게 변환한다", () => {
46
- const fileProcessor = vi.fn().mockReturnValue("worker-SHARED01.js");
47
- const code = `const sw = new SharedWorker(new URL('./shared.ts', import.meta.url));`;
48
-
49
- const output = transformCode(code, fileProcessor);
50
-
51
- expect(fileProcessor).toHaveBeenCalledWith("./shared.ts", "test.ts");
52
- expect(output).toContain('"worker-SHARED01.js"');
53
- });
54
-
55
- // Acceptance: Worker의 기존 options 인자가 있으면 유지한다
56
- it("기존 options 인자가 있으면 유지한다", () => {
57
- const fileProcessor = vi.fn().mockReturnValue("worker-OPT00001.js");
58
- const code = `const w = new Worker(new URL('./w.ts', import.meta.url), { name: 'test' });`;
59
-
60
- const output = transformCode(code, fileProcessor);
61
-
62
- expect(output).toContain('"worker-OPT00001.js"');
63
- expect(output).toContain("name");
64
- // { type: 'module' } 자동 추가 없이 기존 options가 유지됨
65
- expect(output).not.toMatch(/type.*module.*name/);
66
- });
67
- });
68
-
69
- describe("createWorkerTransformer — 변환하지 않는 케이스", () => {
70
- const noopProcessor = vi.fn().mockReturnValue("should-not-appear.js");
71
-
72
- // URL 패턴이 아닌 Worker 생성
73
- it("URL 패턴 없이 문자열 인자만 있으면 변환하지 않는다", () => {
74
- const code = `const w = new Worker('./my-worker.ts');`;
75
- const output = transformCode(code, noopProcessor);
76
-
77
- expect(noopProcessor).not.toHaveBeenCalled();
78
- expect(output).toContain("./my-worker.ts");
79
- });
80
-
81
- // import.meta.url이 아닌 URL
82
- it("import.meta.url이 아닌 URL은 변환하지 않는다", () => {
83
- const code = `const w = new Worker(new URL('./w.ts', 'http://example.com'));`;
84
- const output = transformCode(code, noopProcessor);
85
-
86
- expect(noopProcessor).not.toHaveBeenCalled();
87
- expect(output).toContain("./w.ts");
88
- });
89
-
90
- // Worker 인자 없음
91
- it("Worker 인자가 없으면 변환하지 않는다", () => {
92
- const code = `const w = new Worker();`;
93
- transformCode(code, noopProcessor);
94
-
95
- expect(noopProcessor).not.toHaveBeenCalled();
96
- });
97
-
98
- // Worker 인자 3개 이상
99
- it("Worker 인자가 3개 이상이면 변환하지 않는다", () => {
100
- const code = `const w = new Worker(new URL('./w.ts', import.meta.url), {}, 'extra');`;
101
- transformCode(code, noopProcessor);
102
-
103
- expect(noopProcessor).not.toHaveBeenCalled();
104
- });
105
-
106
- // URL 인자가 1개
107
- it("URL 인자가 1개면 변환하지 않는다", () => {
108
- const code = `const w = new Worker(new URL('./w.ts'));`;
109
- transformCode(code, noopProcessor);
110
-
111
- expect(noopProcessor).not.toHaveBeenCalled();
112
- });
113
-
114
- // URL 인자가 3개
115
- it("URL 인자가 3개면 변환하지 않는다", () => {
116
- const code = `const w = new Worker(new URL('./w.ts', import.meta.url, 'extra'));`;
117
- transformCode(code, noopProcessor);
118
-
119
- expect(noopProcessor).not.toHaveBeenCalled();
120
- });
121
-
122
- // 'Worker' 문자열 없으면 skip
123
- it("소스에 'Worker' 문자열이 없으면 변환을 건너뛴다", () => {
124
- const code = `const x = 1 + 2;`;
125
- const output = transformCode(code, noopProcessor);
126
-
127
- expect(noopProcessor).not.toHaveBeenCalled();
128
- expect(output).toContain("1 + 2");
129
- });
130
- });
131
-
132
- describe("createWorkerTransformer — 추가 경계 케이스", () => {
133
- // fileProcessor가 원본과 동일한 경로를 반환하면 변환하지 않는다
134
- it("fileProcessor가 원본 경로를 그대로 반환하면 AST를 변경하지 않는다", () => {
135
- const fileProcessor = vi.fn().mockReturnValue("./my-worker.ts");
136
- const code = `const w = new Worker(new URL('./my-worker.ts', import.meta.url));`;
137
-
138
- const output = transformCode(code, fileProcessor);
139
-
140
- expect(fileProcessor).toHaveBeenCalledWith("./my-worker.ts", "test.ts");
141
- // 원본 경로가 그대로 유지 (변환 없음)
142
- expect(output).toContain("./my-worker.ts");
143
- });
144
-
145
- // 소스에 Worker 문자열은 있지만 new 표현이 아닌 경우
146
- it("Worker 문자열이 있지만 new 표현이 아니면 변환하지 않는다", () => {
147
- const fileProcessor = vi.fn();
148
- const code = `const WorkerName = "test";`;
149
-
150
- transformCode(code, fileProcessor);
151
-
152
- expect(fileProcessor).not.toHaveBeenCalled();
153
- });
154
- });