@simplysm/sd-cli 12.13.37 → 12.13.39

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 (121) hide show
  1. package/dist/pkg-builders/SdBuildRunnerBase.d.ts +14 -0
  2. package/dist/pkg-builders/SdBuildRunnerBase.js +23 -0
  3. package/dist/pkg-builders/SdBuildRunnerBase.js.map +1 -0
  4. package/dist/pkg-builders/SdProjectBuildRunner.js +18 -14
  5. package/dist/pkg-builders/SdProjectBuildRunner.js.map +1 -1
  6. package/dist/pkg-builders/client/SdClientBuildRunner.d.ts +1 -1
  7. package/dist/pkg-builders/client/SdClientBuildRunner.js +17 -36
  8. package/dist/pkg-builders/client/SdClientBuildRunner.js.map +1 -1
  9. package/dist/pkg-builders/client/SdNgBundler.d.ts +10 -16
  10. package/dist/pkg-builders/client/SdNgBundler.js +59 -54
  11. package/dist/pkg-builders/client/SdNgBundler.js.map +1 -1
  12. package/dist/pkg-builders/client/createSdNgPlugin.d.ts +2 -11
  13. package/dist/pkg-builders/client/createSdNgPlugin.js +16 -25
  14. package/dist/pkg-builders/client/createSdNgPlugin.js.map +1 -1
  15. package/dist/pkg-builders/lib/SdJsLibBuildRunner.d.ts +1 -1
  16. package/dist/pkg-builders/lib/SdJsLibBuildRunner.js +5 -5
  17. package/dist/pkg-builders/lib/SdJsLibBuildRunner.js.map +1 -1
  18. package/dist/pkg-builders/lib/SdTsLibBuildRunner.d.ts +1 -1
  19. package/dist/pkg-builders/lib/SdTsLibBuildRunner.js +6 -6
  20. package/dist/pkg-builders/lib/SdTsLibBuildRunner.js.map +1 -1
  21. package/dist/pkg-builders/lib/SdTsLibBuilder.d.ts +3 -3
  22. package/dist/pkg-builders/lib/SdTsLibBuilder.js +6 -15
  23. package/dist/pkg-builders/lib/SdTsLibBuilder.js.map +1 -1
  24. package/dist/pkg-builders/server/SdServerBuildRunner.d.ts +1 -1
  25. package/dist/pkg-builders/server/SdServerBuildRunner.js +25 -42
  26. package/dist/pkg-builders/server/SdServerBuildRunner.js.map +1 -1
  27. package/dist/pkg-builders/server/SdServerBundler.d.ts +4 -10
  28. package/dist/pkg-builders/server/SdServerBundler.js +15 -22
  29. package/dist/pkg-builders/server/SdServerBundler.js.map +1 -1
  30. package/dist/pkg-builders/server/createSdServerPlugin.d.ts +2 -11
  31. package/dist/pkg-builders/server/createSdServerPlugin.js +10 -19
  32. package/dist/pkg-builders/server/createSdServerPlugin.js.map +1 -1
  33. package/dist/sd-cli-entry.js +1 -1
  34. package/dist/sd-cli-entry.js.map +1 -1
  35. package/dist/ts-compiler/ScopePathSet.js.map +1 -0
  36. package/dist/ts-compiler/SdDepAnalyzer.d.ts +1 -1
  37. package/dist/ts-compiler/SdStyleBundler.d.ts +8 -5
  38. package/dist/ts-compiler/SdStyleBundler.js +30 -15
  39. package/dist/ts-compiler/SdStyleBundler.js.map +1 -1
  40. package/dist/ts-compiler/SdTsCompiler.d.ts +2 -1
  41. package/dist/ts-compiler/SdTsCompiler.js +68 -53
  42. package/dist/ts-compiler/SdTsCompiler.js.map +1 -1
  43. package/dist/types/build/ISdTsCompilerOptions.d.ts +6 -9
  44. package/dist/types/worker/ISdBuildRunnerWorkerType.d.ts +4 -7
  45. package/dist/workers/build-runner.worker.js +4 -5
  46. package/dist/workers/build-runner.worker.js.map +1 -1
  47. package/package.json +5 -5
  48. package/src/pkg-builders/SdBuildRunnerBase.ts +36 -0
  49. package/src/pkg-builders/SdProjectBuildRunner.ts +24 -16
  50. package/src/pkg-builders/client/SdClientBuildRunner.ts +25 -46
  51. package/src/pkg-builders/client/SdNgBundler.ts +69 -73
  52. package/src/pkg-builders/client/createSdNgPlugin.ts +21 -35
  53. package/src/pkg-builders/lib/SdJsLibBuildRunner.ts +5 -5
  54. package/src/pkg-builders/lib/SdTsLibBuildRunner.ts +9 -13
  55. package/src/pkg-builders/lib/SdTsLibBuilder.ts +7 -23
  56. package/src/pkg-builders/server/SdServerBuildRunner.ts +32 -50
  57. package/src/pkg-builders/server/SdServerBundler.ts +16 -32
  58. package/src/pkg-builders/server/createSdServerPlugin.ts +15 -29
  59. package/src/sd-cli-entry.ts +1 -1
  60. package/src/ts-compiler/SdDepAnalyzer.ts +1 -1
  61. package/src/ts-compiler/SdStyleBundler.ts +34 -15
  62. package/src/ts-compiler/SdTsCompiler.ts +75 -63
  63. package/src/types/build/ISdTsCompilerOptions.ts +6 -9
  64. package/src/types/worker/ISdBuildRunnerWorkerType.ts +4 -9
  65. package/src/workers/build-runner.worker.ts +7 -16
  66. package/dist/fix/convert-extends-sd-modal-base-to-interface.d.ts +0 -1
  67. package/dist/fix/convert-extends-sd-modal-base-to-interface.js +0 -289
  68. package/dist/fix/convert-extends-sd-modal-base-to-interface.js.map +0 -1
  69. package/dist/fix/convert-extends-sd-print-template-base-to-interface.d.ts +0 -1
  70. package/dist/fix/convert-extends-sd-print-template-base-to-interface.js +0 -179
  71. package/dist/fix/convert-extends-sd-print-template-base-to-interface.js.map +0 -1
  72. package/dist/fix/convert-flat-pages-to-flat-menus.d.ts +0 -1
  73. package/dist/fix/convert-flat-pages-to-flat-menus.js +0 -68
  74. package/dist/fix/convert-flat-pages-to-flat-menus.js.map +0 -1
  75. package/dist/fix/convert-get-menus-to-usable-menus.d.ts +0 -1
  76. package/dist/fix/convert-get-menus-to-usable-menus.js +0 -48
  77. package/dist/fix/convert-get-menus-to-usable-menus.js.map +0 -1
  78. package/dist/fix/convert-modal-show-params.d.ts +0 -1
  79. package/dist/fix/convert-modal-show-params.js +0 -29
  80. package/dist/fix/convert-modal-show-params.js.map +0 -1
  81. package/dist/fix/convert-print-params.d.ts +0 -1
  82. package/dist/fix/convert-print-params.js +0 -37
  83. package/dist/fix/convert-print-params.js.map +0 -1
  84. package/dist/fix/convert-sd-icon-to-fa-icon.d.ts +0 -1
  85. package/dist/fix/convert-sd-icon-to-fa-icon.js +0 -80
  86. package/dist/fix/convert-sd-icon-to-fa-icon.js.map +0 -1
  87. package/dist/fix/convert-sd-sheet-bindings-safety.d.ts +0 -1
  88. package/dist/fix/convert-sd-sheet-bindings-safety.js +0 -57
  89. package/dist/fix/convert-sd-sheet-bindings-safety.js.map +0 -1
  90. package/dist/fix/convert-select-modal-button-to-select-button.d.ts +0 -1
  91. package/dist/fix/convert-select-modal-button-to-select-button.js +0 -64
  92. package/dist/fix/convert-select-modal-button-to-select-button.js.map +0 -1
  93. package/dist/fix/convert-setup-cumulate-selected-keys-to-object-param.d.ts +0 -1
  94. package/dist/fix/convert-setup-cumulate-selected-keys-to-object-param.js +0 -38
  95. package/dist/fix/convert-setup-cumulate-selected-keys-to-object-param.js.map +0 -1
  96. package/dist/fix/convert-to-use-perms-signal.d.ts +0 -1
  97. package/dist/fix/convert-to-use-perms-signal.js +0 -99
  98. package/dist/fix/convert-to-use-perms-signal.js.map +0 -1
  99. package/dist/fix/core/remove-named-import.d.ts +0 -1
  100. package/dist/fix/core/remove-named-import.js +0 -14
  101. package/dist/fix/core/remove-named-import.js.map +0 -1
  102. package/dist/pkg-builders/commons/ScopePathSet.js.map +0 -1
  103. package/dist/pkg-builders/commons/SdBuildRunnerBase.d.ts +0 -20
  104. package/dist/pkg-builders/commons/SdBuildRunnerBase.js +0 -30
  105. package/dist/pkg-builders/commons/SdBuildRunnerBase.js.map +0 -1
  106. package/src/fix/convert-extends-sd-modal-base-to-interface.ts +0 -324
  107. package/src/fix/convert-extends-sd-print-template-base-to-interface.ts +0 -201
  108. package/src/fix/convert-flat-pages-to-flat-menus.ts +0 -83
  109. package/src/fix/convert-get-menus-to-usable-menus.ts +0 -60
  110. package/src/fix/convert-modal-show-params.ts +0 -37
  111. package/src/fix/convert-print-params.ts +0 -51
  112. package/src/fix/convert-sd-icon-to-fa-icon.ts +0 -95
  113. package/src/fix/convert-sd-sheet-bindings-safety.ts +0 -73
  114. package/src/fix/convert-select-modal-button-to-select-button.ts +0 -91
  115. package/src/fix/convert-setup-cumulate-selected-keys-to-object-param.ts +0 -44
  116. package/src/fix/convert-to-use-perms-signal.ts +0 -133
  117. package/src/fix/core/remove-named-import.ts +0 -14
  118. package/src/pkg-builders/commons/SdBuildRunnerBase.ts +0 -47
  119. /package/dist/{pkg-builders/commons → ts-compiler}/ScopePathSet.d.ts +0 -0
  120. /package/dist/{pkg-builders/commons → ts-compiler}/ScopePathSet.js +0 -0
  121. /package/src/{pkg-builders/commons → ts-compiler}/ScopePathSet.ts +0 -0
@@ -1,324 +0,0 @@
1
- /* eslint-disable no-console */
2
- import * as path from "path";
3
- import { SyntaxKind } from "ts-morph";
4
- import getTsMorphSourceFiles from "./core/get-ts-morph-source-files";
5
- import removeNamedImport from "./core/remove-named-import";
6
-
7
- export function convertExtendsSdModalBaseToInterface() {
8
- const sourceFiles = getTsMorphSourceFiles();
9
-
10
- let totalChanged = 0;
11
-
12
- for (const sourceFile of sourceFiles) {
13
- let changed = false;
14
- const relPath = path.basename(sourceFile.getFilePath());
15
-
16
- const modalClass = sourceFile.getClasses().find((classDecl) => {
17
- const extendsClause = classDecl
18
- .getHeritageClauses()
19
- .find((h) => h.getToken() === SyntaxKind.ExtendsKeyword);
20
- if (!extendsClause) return false;
21
- const typeNodes = extendsClause.getTypeNodes();
22
- return typeNodes.some((typeNode) =>
23
- /^SdModalBase\s*<[^,>]+,\s*[^>]+\s*>$/.test(typeNode.getText()),
24
- );
25
- });
26
-
27
- if (!modalClass) continue;
28
-
29
- const extendsClause = modalClass
30
- .getHeritageClauses()
31
- .find((h) => h.getToken() === SyntaxKind.ExtendsKeyword);
32
- if (!extendsClause) continue;
33
- const typeNodes = extendsClause.getTypeNodes();
34
- const match = typeNodes[0]?.getText().match(/^SdModalBase\s*<([^,>]+),\s*([^>]+)\s*>$/);
35
- if (!match) continue;
36
- const paramTypeName = match[1].trim();
37
- const modalOutputTypeText = match[2].trim();
38
- const paramInterface = sourceFile.getInterface(paramTypeName);
39
- if (!paramInterface) continue;
40
- let props = paramInterface.getProperties();
41
- let paramNames = props.map((p) => p.getName());
42
-
43
- const onlyISharedData =
44
- props.length === 0 &&
45
- paramInterface.getExtends().some(e =>
46
- e.getText().includes("ISharedDataModalInputParam")
47
- );
48
-
49
- if (onlyISharedData) {
50
- props = [
51
- {
52
- getName: () => "selectedItemKeys",
53
- hasQuestionToken: () => false,
54
- getTypeNode: () => ({ getText: () => "any[]" })
55
- },
56
- {
57
- getName: () => "selectMode",
58
- hasQuestionToken: () => true,
59
- getTypeNode: () => ({ getText: () => `"single" | "multi"` })
60
- }
61
- ] as any;
62
- paramNames = ["selectedItemKeys", "selectMode"];
63
- }
64
-
65
- // 1. property/class 필드/close 추가
66
- let lastPropIdx = 0;
67
- for (const prop of props) {
68
- const propName = prop.getName();
69
- const isOptional = prop.hasQuestionToken();
70
- const propType = prop.getTypeNode()?.getText() ?? "any";
71
- const initializer = `input${isOptional ? "" : ".required"}<${propType}>()`;
72
- if (!modalClass.getProperty(propName)) {
73
- modalClass.insertProperty(lastPropIdx, { name: propName, initializer });
74
- lastPropIdx++;
75
- changed = true;
76
- }
77
- }
78
- if (!modalClass.getProperty("close")) {
79
- modalClass.insertProperty(lastPropIdx, { name: "close", initializer: `output<${modalOutputTypeText}>()` });
80
- changed = true;
81
- }
82
-
83
- // 2. extends → implements 변환
84
- let implementsText: string;
85
- if (modalOutputTypeText === "ISharedDataModalOutputResult") {
86
- implementsText = "ISdSelectModal";
87
- } else {
88
- implementsText = `ISdModal<${modalOutputTypeText}>`;
89
- }
90
- if (!modalClass.getImplements().some(i => i.getText() === implementsText)) {
91
- modalClass.addImplements(implementsText);
92
- changed = true;
93
- }
94
-
95
- // 3. super() 삭제(생성자)
96
- const ctor = modalClass.getConstructors().first();
97
- if (ctor) {
98
- ctor.getStatements().forEach((stmt) => {
99
- if (stmt.getKind() === SyntaxKind.ExpressionStatement) {
100
- const expr = stmt.asKind(SyntaxKind.ExpressionStatement)?.getExpression();
101
- if (expr && expr.getKind() === SyntaxKind.CallExpression) {
102
- const callExpr = expr.asKind(SyntaxKind.CallExpression);
103
- if (
104
- callExpr?.getExpression().getText() === "super" &&
105
- callExpr.getArguments().length === 0
106
- ) {
107
- stmt.remove();
108
- changed = true;
109
- }
110
- }
111
- }
112
- });
113
- }
114
-
115
- // 4. this.open() 전체 삭제(클래스 전체)
116
- modalClass
117
- .getDescendantsOfKind(SyntaxKind.CallExpression)
118
- .filter(
119
- (expr) =>
120
- expr.getExpression().getKind() === SyntaxKind.PropertyAccessExpression &&
121
- expr.getExpression().getText() === "this.open",
122
- )
123
- .forEach((expr) => {
124
- const parentStmt = expr.getFirstAncestorByKind(SyntaxKind.ExpressionStatement);
125
- if (parentStmt) {
126
- parentStmt.remove();
127
- changed = true;
128
- }
129
- });
130
-
131
- // 5. params().xxx → xxx() 및 this.params().xxx → this.xxx() AST 치환
132
- modalClass.forEachDescendant((node) => {
133
- if (node.getKind() === SyntaxKind.PropertyAccessExpression) {
134
- const propAccess = node.asKind(SyntaxKind.PropertyAccessExpression)!;
135
- const propName = propAccess.getName();
136
- if (!paramNames.includes(propName)) return;
137
- const expr = propAccess.getExpression();
138
-
139
- // params().xxx
140
- if (expr.getKind() === SyntaxKind.CallExpression) {
141
- const callExpr = expr.asKind(SyntaxKind.CallExpression)!;
142
- const innerExpr = callExpr.getExpression();
143
-
144
- // a) 단독 params()
145
- if (innerExpr.getKind() === SyntaxKind.Identifier && innerExpr.getText() === "params") {
146
- propAccess.replaceWithText(`${propName}()`);
147
- changed = true;
148
- }
149
- // b) this.params()
150
- else if (innerExpr.getKind() === SyntaxKind.PropertyAccessExpression) {
151
- const propExpr = innerExpr.asKind(SyntaxKind.PropertyAccessExpression)!;
152
- if (
153
- propExpr.getExpression().getKind() === SyntaxKind.ThisKeyword &&
154
- propExpr.getName() === "params"
155
- ) {
156
- propAccess.replaceWithText(`this.${propName}()`);
157
- changed = true;
158
- }
159
- }
160
- }
161
- }
162
- });
163
-
164
- // 6. this.close(...) → this.close.emit(...)
165
- modalClass.forEachDescendant((node) => {
166
- if (node.getKind() === SyntaxKind.CallExpression) {
167
- const callExpr = node.asKind(SyntaxKind.CallExpression)!;
168
- const expr = callExpr.getExpression();
169
- if (
170
- expr.getKind() === SyntaxKind.PropertyAccessExpression &&
171
- expr.asKind(SyntaxKind.PropertyAccessExpression)!.getExpression().getKind() ===
172
- SyntaxKind.ThisKeyword
173
- ) {
174
- const methodName = expr.asKind(SyntaxKind.PropertyAccessExpression)!.getName();
175
- if (methodName === "close") {
176
- expr.asKind(SyntaxKind.PropertyAccessExpression)!.replaceWithText(`this.close.emit`);
177
- changed = true;
178
- }
179
- }
180
- }
181
- });
182
-
183
- // 7. @Component template: params().xxx → xxx() 치환
184
- const componentDecorator = modalClass.getDecorator("Component");
185
- if (componentDecorator) {
186
- const arg = componentDecorator.getArguments().first();
187
- if (arg && arg.getKind() === SyntaxKind.ObjectLiteralExpression) {
188
- const objLit = arg.asKind(SyntaxKind.ObjectLiteralExpression)!;
189
- const tplProp = objLit.getProperty("template");
190
- if (
191
- tplProp &&
192
- tplProp.getKind() === SyntaxKind.PropertyAssignment &&
193
- tplProp.asKind(SyntaxKind.PropertyAssignment)!.getInitializer()
194
- ) {
195
- const propAssign = tplProp.asKind(SyntaxKind.PropertyAssignment)!;
196
- const init = propAssign.getInitializerOrThrow();
197
- let tplText = init.getText();
198
- let tplTextRaw = tplText;
199
- for (const paramName of paramNames) {
200
- const paramsPattern = new RegExp(`params\\(\\)\\.${paramName}\\b`, "g");
201
- tplTextRaw = tplTextRaw.replace(paramsPattern, `${paramName}()`);
202
- }
203
- if (tplTextRaw !== tplText) {
204
- propAssign.setInitializer(tplTextRaw);
205
- changed = true;
206
- }
207
- }
208
- }
209
- }
210
-
211
- // 8. import 관리
212
- const sdAngularImport = sourceFile.getImportDeclaration(
213
- d => d.getModuleSpecifierValue() === "@simplysm/sd-angular"
214
- );
215
- if (modalOutputTypeText === "ISharedDataModalOutputResult") {
216
- // ISdSelectModal 추가
217
- if (sdAngularImport) {
218
- const namedImports = sdAngularImport.getNamedImports();
219
- // ISdSelectModal 없으면 추가
220
- if (!namedImports.some(n => n.getName() === "ISdSelectModal")) {
221
- sdAngularImport.addNamedImport("ISdSelectModal");
222
- }
223
- // ISdModal 제거
224
- namedImports
225
- .filter(n => n.getName() === "ISdModal")
226
- .forEach(n => n.remove());
227
- } else {
228
- sourceFile.addImportDeclaration({
229
- namedImports: ["ISdSelectModal"],
230
- moduleSpecifier: "@simplysm/sd-angular"
231
- });
232
- }
233
- } else {
234
- // ISdModal 추가
235
- if (sdAngularImport) {
236
- const namedImports = sdAngularImport.getNamedImports();
237
- // ISdModal 없으면 추가
238
- if (!namedImports.some(n => n.getName() === "ISdModal")) {
239
- sdAngularImport.addNamedImport("ISdModal");
240
- }
241
- // ISdSelectModal 제거
242
- namedImports
243
- .filter(n => n.getName() === "ISdSelectModal")
244
- .forEach(n => n.remove());
245
- } else {
246
- sourceFile.addImportDeclaration({
247
- namedImports: ["ISdModal"],
248
- moduleSpecifier: "@simplysm/sd-angular"
249
- });
250
- }
251
- }
252
-
253
- const ngCoreImport = sourceFile.getImportDeclaration(
254
- (d) => d.getModuleSpecifierValue() === "@angular/core",
255
- );
256
- if (ngCoreImport) {
257
- const imports = ngCoreImport.getNamedImports().map((n) => n.getName());
258
- if (!imports.includes("input")) {
259
- ngCoreImport.addNamedImport("input");
260
- changed = true;
261
- }
262
- if (!imports.includes("output")) {
263
- ngCoreImport.addNamedImport("output");
264
- changed = true;
265
- }
266
- } else {
267
- sourceFile.addImportDeclaration({
268
- namedImports: ["input", "output"],
269
- moduleSpecifier: "@angular/core",
270
- });
271
- changed = true;
272
- }
273
-
274
- // 9. $effect([this.params], ...) → $effect([], ...) (생성자)
275
- if (ctor) {
276
- ctor.forEachDescendant((node) => {
277
- if (node.getKind() === SyntaxKind.CallExpression) {
278
- const callExpr = node.asKind(SyntaxKind.CallExpression)!;
279
- const expr = callExpr.getExpression();
280
- if (expr.getKind() === SyntaxKind.Identifier && expr.getText() === "$effect") {
281
- const args = callExpr.getArguments();
282
- if (
283
- args.length >= 1 &&
284
- args[0].getKind() === SyntaxKind.ArrayLiteralExpression &&
285
- args[0].asKind(SyntaxKind.ArrayLiteralExpression)!.getElements().length === 1
286
- ) {
287
- const arrElem = args[0].asKind(SyntaxKind.ArrayLiteralExpression)!.getElements()[0];
288
- if (
289
- arrElem.getKind() === SyntaxKind.PropertyAccessExpression &&
290
- arrElem.getText() === "this.params"
291
- ) {
292
- args[0].replaceWithText("[]");
293
- changed = true;
294
- }
295
- }
296
- }
297
- }
298
- });
299
- }
300
-
301
- // 10. interface 선언 삭제
302
- paramInterface.remove();
303
-
304
- // 11. extends 삭제 (항상 마지막)
305
- modalClass.removeExtends();
306
-
307
- // 11. import 삭제
308
- removeNamedImport(sourceFile, "@simplysm/sd-angular", "SdModalBase");
309
- removeNamedImport(sourceFile, "@simplysm/sd-angular", "ISharedDataModalInputParam");
310
- // removeNamedImport(sourceFile, "@simplysm/sd-angular", "ISharedDataModalOutputResult");
311
-
312
- // 12. 저장 및 간결 로그 출력
313
- if (changed) {
314
- sourceFile.saveSync();
315
- totalChanged++;
316
- console.log(`[modal-updated] ${relPath} :: 모달기반 변경 완료`);
317
- }
318
- }
319
- if (totalChanged > 0) {
320
- console.log(`\n[완료] 모달변환 완료 (총 ${totalChanged}개)`);
321
- } else {
322
- console.log(`[완료] 변환 대상 없음`);
323
- }
324
- }
@@ -1,201 +0,0 @@
1
- /* eslint-disable no-console */
2
- import * as path from "path";
3
- import { SyntaxKind } from "ts-morph";
4
- import getTsMorphSourceFiles from "./core/get-ts-morph-source-files";
5
- import removeNamedImport from "./core/remove-named-import";
6
-
7
- export function convertExtendsSdPrintTemplateBaseToInterface() {
8
- const sourceFiles = getTsMorphSourceFiles();
9
-
10
- let totalChanged = 0;
11
-
12
- for (const sourceFile of sourceFiles) {
13
- let changed = false;
14
- const relPath = path.basename(sourceFile.getFilePath());
15
-
16
- const printClass = sourceFile.getClasses().find((classDecl) => {
17
- const extendsClause = classDecl
18
- .getHeritageClauses()
19
- .find((h) => h.getToken() === SyntaxKind.ExtendsKeyword);
20
- if (!extendsClause) return false;
21
- const typeNodes = extendsClause.getTypeNodes();
22
- return typeNodes.some((typeNode) =>
23
- /^SdPrintTemplateBase\s*<[^>]+>$/.test(typeNode.getText()),
24
- );
25
- });
26
-
27
- if (!printClass) continue;
28
-
29
- const extendsClause = printClass
30
- .getHeritageClauses()
31
- .find((h) => h.getToken() === SyntaxKind.ExtendsKeyword);
32
- if (!extendsClause) continue;
33
- const typeNodes = extendsClause.getTypeNodes();
34
- const match = typeNodes[0]?.getText().match(/^SdPrintTemplateBase\s*<([^>]+)>$/);
35
- if (!match) continue;
36
- const paramTypeName = match[1].trim();
37
- const paramInterface = sourceFile.getInterface(paramTypeName);
38
- if (!paramInterface) continue;
39
- const props = paramInterface.getProperties();
40
- const paramNames = props.map((p) => p.getName());
41
-
42
- // 1. property/class 필드 추가
43
- let lastPropIdx = 0;
44
- for (const prop of props) {
45
- const propName = prop.getName();
46
- const isOptional = prop.hasQuestionToken();
47
- const propType = prop.getTypeNode()?.getText() ?? "any";
48
- const initializer = `input${isOptional ? "" : ".required"}<${propType}>()`;
49
- if (!printClass.getProperty(propName)) {
50
- printClass.insertProperty(lastPropIdx, { name: propName, initializer });
51
- lastPropIdx++;
52
- changed = true;
53
- }
54
- }
55
-
56
- // 2. implements 추가
57
- if (!printClass.getImplements().some(i => i.getText() === "ISdPrint")) {
58
- printClass.addImplements("ISdPrint");
59
- changed = true;
60
- }
61
-
62
- // 3. super() 삭제 (생성자)
63
- const ctor = printClass.getConstructors().first();
64
- if (ctor) {
65
- ctor.getStatements().forEach((stmt) => {
66
- if (stmt.getKind() === SyntaxKind.ExpressionStatement) {
67
- const expr = stmt.asKind(SyntaxKind.ExpressionStatement)?.getExpression();
68
- if (expr?.asKind(SyntaxKind.CallExpression)?.getExpression().getText() === "super") {
69
- stmt.remove();
70
- changed = true;
71
- }
72
- }
73
- });
74
- }
75
-
76
- // 4. this.print() 전체 삭제
77
- printClass
78
- .getDescendantsOfKind(SyntaxKind.CallExpression)
79
- .filter((expr) =>
80
- expr.getExpression().getKind() === SyntaxKind.PropertyAccessExpression &&
81
- expr.getExpression().getText() === "this.print",
82
- )
83
- .forEach((expr) => {
84
- const parentStmt = expr.getFirstAncestorByKind(SyntaxKind.ExpressionStatement);
85
- if (parentStmt) {
86
- parentStmt.remove();
87
- changed = true;
88
- }
89
- });
90
-
91
- // 5. params().xxx → xxx() 및 this.params().xxx → this.xxx() AST 치환
92
- printClass.forEachDescendant((node) => {
93
- if (node.getKind() === SyntaxKind.PropertyAccessExpression) {
94
- const propAccess = node.asKind(SyntaxKind.PropertyAccessExpression)!;
95
- const propName = propAccess.getName();
96
- if (!paramNames.includes(propName)) return;
97
- const expr = propAccess.getExpression();
98
-
99
- if (expr.getKind() === SyntaxKind.CallExpression) {
100
- const callExpr = expr.asKind(SyntaxKind.CallExpression)!;
101
- const innerExpr = callExpr.getExpression();
102
-
103
- if (innerExpr.getKind() === SyntaxKind.Identifier && innerExpr.getText() === "params") {
104
- propAccess.replaceWithText(`${propName}()`);
105
- changed = true;
106
- } else if (
107
- innerExpr.getKind() === SyntaxKind.PropertyAccessExpression &&
108
- innerExpr.asKind(SyntaxKind.PropertyAccessExpression)!.getExpression().getKind() === SyntaxKind.ThisKeyword &&
109
- innerExpr.asKind(SyntaxKind.PropertyAccessExpression)!.getName() === "params"
110
- ) {
111
- propAccess.replaceWithText(`this.${propName}()`);
112
- changed = true;
113
- }
114
- }
115
- }
116
- });
117
-
118
- // 6. @Component template: params().xxx → xxx() 치환
119
- const componentDecorator = printClass.getDecorator("Component");
120
- if (componentDecorator) {
121
- const arg = componentDecorator.getArguments().first();
122
- if (arg?.getKind() === SyntaxKind.ObjectLiteralExpression) {
123
- const tplProp = arg.asKind(SyntaxKind.ObjectLiteralExpression)!.getProperty("template");
124
- if (
125
- tplProp?.getKind() === SyntaxKind.PropertyAssignment &&
126
- tplProp.asKind(SyntaxKind.PropertyAssignment)!.getInitializer()
127
- ) {
128
- const propAssign = tplProp.asKind(SyntaxKind.PropertyAssignment)!;
129
- const init = propAssign.getInitializerOrThrow();
130
- let tplText = init.getText();
131
- let tplTextRaw = tplText;
132
- for (const paramName of paramNames) {
133
- const paramsPattern = new RegExp(`params\\(\\)\\.${paramName}\\b`, "g");
134
- tplTextRaw = tplTextRaw.replace(paramsPattern, `${paramName}()`);
135
- }
136
- if (tplTextRaw !== tplText) {
137
- propAssign.setInitializer(tplTextRaw);
138
- changed = true;
139
- }
140
- }
141
- }
142
- }
143
-
144
- // 7. import 정리
145
- const sdAngularImport = sourceFile.getImportDeclaration(
146
- d => d.getModuleSpecifierValue() === "@simplysm/sd-angular"
147
- );
148
- if (sdAngularImport) {
149
- const namedImports = sdAngularImport.getNamedImports();
150
- if (!namedImports.some(n => n.getName() === "ISdPrint")) {
151
- sdAngularImport.addNamedImport("ISdPrint");
152
- changed = true;
153
- }
154
- } else {
155
- sourceFile.addImportDeclaration({
156
- namedImports: ["ISdPrint"],
157
- moduleSpecifier: "@simplysm/sd-angular"
158
- });
159
- changed = true;
160
- }
161
-
162
- const ngCoreImport = sourceFile.getImportDeclaration(
163
- (d) => d.getModuleSpecifierValue() === "@angular/core",
164
- );
165
- if (ngCoreImport) {
166
- const imports = ngCoreImport.getNamedImports().map((n) => n.getName());
167
- if (!imports.includes("input")) {
168
- ngCoreImport.addNamedImport("input");
169
- changed = true;
170
- }
171
- } else {
172
- sourceFile.addImportDeclaration({
173
- namedImports: ["input"],
174
- moduleSpecifier: "@angular/core",
175
- });
176
- changed = true;
177
- }
178
-
179
- // 8. interface 선언 삭제
180
- paramInterface.remove();
181
-
182
- // 9. extends 삭제
183
- printClass.removeExtends();
184
-
185
- // 10. 불필요한 import 제거
186
- removeNamedImport(sourceFile, "@simplysm/sd-angular", "SdPrintTemplateBase");
187
-
188
- // 11. 저장 및 로그 출력
189
- if (changed) {
190
- sourceFile.saveSync();
191
- totalChanged++;
192
- console.log(`[print-updated] ${relPath} :: 프린트 기반 변경 완료`);
193
- }
194
- }
195
-
196
- if (totalChanged > 0) {
197
- console.log(`\n[완료] 프린트 변환 완료 (총 ${totalChanged}개)`);
198
- } else {
199
- console.log(`[완료] 변환 대상 없음`);
200
- }
201
- }
@@ -1,83 +0,0 @@
1
- /* eslint-disable no-console */
2
- import { SyntaxKind } from "ts-morph";
3
- import getTsMorphSourceFiles from "./core/get-ts-morph-source-files";
4
-
5
- export function convertFlatPagesToUsableFlatMenus() {
6
- const sourceFiles = getTsMorphSourceFiles();
7
- let totalChanged = 0;
8
-
9
- for (const sourceFile of sourceFiles) {
10
- let changed = false;
11
-
12
- for (const cls of sourceFile.getClasses()) {
13
- // 1. flatPages property 선언 확인
14
- const prop = cls.getInstanceProperty("flatPages")?.asKind(SyntaxKind.PropertyDeclaration);
15
- if (!prop) continue;
16
-
17
- const initializer = prop.getInitializer();
18
- if (!initializer) continue;
19
-
20
- const callExpr = initializer.asKind(SyntaxKind.CallExpression);
21
- if (!callExpr) continue;
22
-
23
- const expr = callExpr.getExpression();
24
- if (
25
- expr.getKind() === SyntaxKind.PropertyAccessExpression &&
26
- expr.getText() === "this._sdAppStructure.getFlatPages"
27
- ) {
28
- // 2. 선언 변경
29
- prop.rename("flatMenus");
30
- prop.setInitializer("this._sdAppStructure.usableFlatMenus()");
31
- changed = true;
32
- console.log(`[변환됨] ${sourceFile.getBaseName()} → flatPages 선언 → flatMenus`);
33
- }
34
-
35
- // 3. 클래스 내 this.flatPages → this.flatMenus 치환
36
- cls.forEachDescendant((node) => {
37
- if (node.getKind() === SyntaxKind.PropertyAccessExpression) {
38
- const propAccess = node.asKind(SyntaxKind.PropertyAccessExpression)!;
39
- if (
40
- propAccess.getExpression().getKind() === SyntaxKind.ThisKeyword &&
41
- propAccess.getName() === "flatPages"
42
- ) {
43
- propAccess.replaceWithText("this.flatMenus");
44
- changed = true;
45
- }
46
- }
47
- });
48
-
49
- // 4. @Component의 template 내 문자열 치환
50
- const componentDecorator = cls.getDecorator("Component");
51
- const arg = componentDecorator?.getArguments()[0]?.asKind(SyntaxKind.ObjectLiteralExpression);
52
- const templateProp = arg?.getProperty("template")?.asKind(SyntaxKind.PropertyAssignment);
53
- const templateInit = templateProp?.getInitializer();
54
- if (
55
- templateInit &&
56
- (templateInit.getKind() === SyntaxKind.NoSubstitutionTemplateLiteral ||
57
- templateInit.getKind() === SyntaxKind.StringLiteral ||
58
- templateInit.getKind() === SyntaxKind.TemplateExpression)
59
- ) {
60
- const originalText = templateInit.getText();
61
- const newText = originalText.replace(/\bflatPages\b/g, "flatMenus");
62
-
63
- if (newText !== originalText) {
64
- templateInit.replaceWithText(newText);
65
- changed = true;
66
- console.log(`[변환됨] ${sourceFile.getBaseName()} → 템플릿 내 flatPages → flatMenus`);
67
- }
68
- }
69
- }
70
-
71
- if (changed) {
72
- sourceFile.saveSync();
73
- totalChanged++;
74
- console.log(`[updated] ${sourceFile.getBaseName()} :: flatMenus 변환 완료`);
75
- }
76
- }
77
-
78
- console.log(
79
- totalChanged > 0
80
- ? `\n[완료] flatPages → flatMenus 전체 변환 완료 (총 ${totalChanged}개)`
81
- : `[완료] 변환 대상 없음`,
82
- );
83
- }
@@ -1,60 +0,0 @@
1
- /* eslint-disable no-console */
2
- import { SyntaxKind } from "ts-morph";
3
- import getTsMorphSourceFiles from "./core/get-ts-morph-source-files";
4
-
5
- export function convertGetMenusToUsableMenus() {
6
- const sourceFiles = getTsMorphSourceFiles();
7
- let totalChanged = 0;
8
-
9
- for (const sourceFile of sourceFiles) {
10
- let changed = false;
11
-
12
- for (const cls of sourceFile.getClasses()) {
13
- const menusProp = cls.getInstanceProperty("menus")?.asKind(SyntaxKind.PropertyDeclaration);
14
- if (!menusProp) continue;
15
-
16
- const initializer = menusProp.getInitializer()?.asKind(SyntaxKind.CallExpression);
17
- if (
18
- !initializer ||
19
- initializer.getFirstChildByKind(SyntaxKind.Identifier)?.getText() !== "$computed"
20
- ) {
21
- continue;
22
- }
23
-
24
- const arrowFn = initializer
25
- .asKind(SyntaxKind.CallExpression)
26
- ?.getArguments()
27
- .first()
28
- ?.asKind(SyntaxKind.ArrowFunction);
29
- if (!arrowFn) continue;
30
-
31
- const body = arrowFn.getBody().asKind(SyntaxKind.CallExpression);
32
- if (!body || !body.getText().includes("this._sdAppStructure.getMenus")) {
33
- continue;
34
- }
35
-
36
- const callExpr = body.asKind(SyntaxKind.CallExpression)!;
37
- const calleeExpr = callExpr.getExpression();
38
- if (
39
- calleeExpr.getKind() === SyntaxKind.PropertyAccessExpression &&
40
- calleeExpr.getText() === "this._sdAppStructure.getMenus"
41
- ) {
42
- // 수정 실행: getMenus → usableMenus
43
- calleeExpr.replaceWithText("this._sdAppStructure.usableMenus");
44
- changed = true;
45
- }
46
- }
47
-
48
- if (changed) {
49
- sourceFile.saveSync();
50
- totalChanged++;
51
- console.log(`[updated] ${sourceFile.getBaseName()} :: menus → usableMenus 변경 완료`);
52
- }
53
- }
54
-
55
- console.log(
56
- totalChanged > 0
57
- ? `\n[완료] usableMenus 변경 완료 (총 ${totalChanged}개)`
58
- : `[완료] 변환 대상 없음`,
59
- );
60
- }