@simplysm/sd-cli 7.0.58 → 7.0.65

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 (34) hide show
  1. package/dist/SdCliBuildResultError.mjs +8 -0
  2. package/dist/bin/sd-cli.mjs +1 -1
  3. package/dist/builder/SdCliServerBuilder.mjs +7 -4
  4. package/dist/builder/SdCliTsLibBuilder.mjs +24 -1
  5. package/dist/entry-points/SdCliWorkspace.mjs +7 -4
  6. package/dist/index.mjs +28 -0
  7. package/dist/ng-tools/NgModuleGenerator.mjs +278 -0
  8. package/dist/ng-tools/babel/SdCliBbFileMetadata.mjs +331 -0
  9. package/dist/ng-tools/babel/SdCliBbRootMetadata.mjs +171 -0
  10. package/dist/ng-tools/babel/SdCliBbUtil.mjs +14 -0
  11. package/dist/ng-tools/babel/TSdCliBbNgMetadata.mjs +169 -0
  12. package/dist/ng-tools/babel/TSdCliBbTypeMetadata.mjs +127 -0
  13. package/dist/ng-tools/commons.mjs +2 -0
  14. package/dist/ng-tools/typescript/SdCliTsFileMetadata.mjs +325 -0
  15. package/dist/ng-tools/typescript/SdCliTsRootMetadata.mjs +28 -0
  16. package/dist/utils/SdCliNpmConfigUtil.mjs +3 -3
  17. package/package.json +11 -7
  18. package/src/SdCliBuildResultError.ts +9 -0
  19. package/src/builder/SdCliServerBuilder.ts +6 -3
  20. package/src/builder/SdCliTsLibBuilder.ts +28 -0
  21. package/src/entry-points/SdCliWorkspace.ts +7 -4
  22. package/src/index.ts +27 -0
  23. package/src/ng-tools/NgModuleGenerator.ts +361 -0
  24. package/src/ng-tools/babel/SdCliBbFileMetadata.ts +372 -0
  25. package/src/ng-tools/babel/SdCliBbRootMetadata.ts +207 -0
  26. package/src/ng-tools/babel/SdCliBbUtil.ts +15 -0
  27. package/src/ng-tools/babel/TSdCliBbNgMetadata.ts +220 -0
  28. package/src/ng-tools/babel/TSdCliBbTypeMetadata.ts +177 -0
  29. package/src/ng-tools/commons.ts +3 -0
  30. package/src/ng-tools/typescript/SdCliTsFileMetadata.ts +384 -0
  31. package/src/ng-tools/typescript/SdCliTsRootMetadata.ts +32 -0
  32. package/src/utils/SdCliNpmConfigUtil.ts +2 -2
  33. package/tsconfig-build.json +5 -1
  34. package/tsconfig.json +5 -1
@@ -0,0 +1,384 @@
1
+ import { FsUtil } from "@simplysm/sd-core-node";
2
+ import ts from "typescript";
3
+ import { NeverEntryError } from "@simplysm/sd-core-common";
4
+ import { TSdCliMetaRef } from "../commons";
5
+ import path from "path";
6
+
7
+ export class SdCliTsFileMetadata {
8
+ private readonly _sourceFile: ts.SourceFile;
9
+
10
+ public constructor(public readonly filePath: string) {
11
+ const fileContent = FsUtil.readFile(filePath);
12
+ this._sourceFile = ts.createSourceFile(filePath, fileContent, ts.ScriptTarget.ES2017);
13
+ }
14
+
15
+ private _directExportClassesCache?: { exportedName: string; target: SdCliTsClassMetadata }[];
16
+
17
+ public get directExportClasses(): { exportedName: string; target: SdCliTsClassMetadata }[] {
18
+ if (this._directExportClassesCache) return this._directExportClassesCache;
19
+
20
+ const result: { exportedName: string; target: SdCliTsClassMetadata }[] = [];
21
+ this._sourceFile.forEachChild((node) => {
22
+ if (!node.modifiers || !node.modifiers.some((item) => item.kind === ts.SyntaxKind.ExportKeyword)) return;
23
+ if (!ts.isClassDeclaration(node)) return;
24
+ if (node.name === undefined) {
25
+ throw new NeverEntryError();
26
+ }
27
+ result.push({ exportedName: node.name.text, target: new SdCliTsClassMetadata(this, node) });
28
+ });
29
+
30
+ this._directExportClassesCache = result;
31
+ return result;
32
+ }
33
+
34
+ public get imports(): TSdCliMetaRef[] {
35
+ const result: TSdCliMetaRef[] = [];
36
+
37
+ ts.forEachChild(this._sourceFile, (node) => {
38
+ if (ts.isImportDeclaration(node)) {
39
+ if (ts.isStringLiteral(node.moduleSpecifier)) {
40
+ if (node.importClause) {
41
+ if (node.moduleSpecifier.text.includes(".")) {
42
+ const moduleFilePath = path.resolve(path.dirname(this.filePath), node.moduleSpecifier.text);
43
+
44
+ if (node.importClause.namedBindings) {
45
+ if (ts.isNamedImports(node.importClause.namedBindings)) {
46
+ for (const el of node.importClause.namedBindings.elements) {
47
+ result.push({
48
+ filePath: moduleFilePath,
49
+ name: el.name.text,
50
+ __TDeclRef__: "__TDeclRef__" as const
51
+ });
52
+ }
53
+ }
54
+ else {
55
+ throw new NeverEntryError();
56
+ }
57
+ }
58
+ else {
59
+ result.push({
60
+ filePath: moduleFilePath,
61
+ name: "default",
62
+ __TDeclRef__: "__TDeclRef__" as const
63
+ });
64
+ }
65
+ }
66
+ else {
67
+ const moduleName = node.moduleSpecifier.text;
68
+ if (node.importClause.namedBindings) {
69
+ if (ts.isNamedImports(node.importClause.namedBindings)) {
70
+ for (const el of node.importClause.namedBindings.elements) {
71
+ result.push({
72
+ moduleName,
73
+ name: el.propertyName?.text ?? el.name.text,
74
+ __TDeclRef__: "__TDeclRef__" as const
75
+ });
76
+ }
77
+ }
78
+ else {
79
+ const nsUseList = this._findNamespaceUse(node.importClause.namedBindings.name.text);
80
+ for (const nsUse of nsUseList) {
81
+ result.push({
82
+ moduleName,
83
+ name: nsUse,
84
+ __TDeclRef__: "__TDeclRef__" as const
85
+ });
86
+ }
87
+ }
88
+ }
89
+ else if (node.importClause.name) {
90
+ const nsUseList = this._findNamespaceUse(node.importClause.name.text);
91
+ for (const nsUse of nsUseList) {
92
+ result.push({
93
+ moduleName: moduleName,
94
+ name: nsUse,
95
+ __TDeclRef__: "__TDeclRef__" as const
96
+ });
97
+ }
98
+ }
99
+ else {
100
+ throw new NeverEntryError();
101
+ }
102
+ }
103
+ }
104
+ else {
105
+ // 무시
106
+ }
107
+ }
108
+ else {
109
+ throw new NeverEntryError();
110
+ }
111
+ }
112
+ else if (ts.isExportDeclaration(node)) {
113
+ if (
114
+ node.exportClause &&
115
+ ts.isNamedExports(node.exportClause) &&
116
+ node.moduleSpecifier &&
117
+ ts.isStringLiteral(node.moduleSpecifier)
118
+ ) {
119
+ if (node.moduleSpecifier.text.includes(".")) {
120
+ const moduleFilePath = path.resolve(path.dirname(this.filePath), node.moduleSpecifier.text);
121
+ for (const el of node.exportClause.elements) {
122
+ if (el.propertyName && el.name.text !== el.propertyName.text) {
123
+ throw new NeverEntryError();
124
+ }
125
+
126
+ result.push({
127
+ filePath: moduleFilePath,
128
+ name: el.name.text,
129
+ __TDeclRef__: "__TDeclRef__" as const
130
+ });
131
+ }
132
+ }
133
+ else {
134
+ throw new NeverEntryError();
135
+ }
136
+ }
137
+ else {
138
+ throw new NeverEntryError();
139
+ }
140
+ }
141
+ });
142
+
143
+ return result;
144
+ }
145
+
146
+ private _findNamespaceUse(localName: string): string[] {
147
+ const fn = (parent: ts.Node): string[] => {
148
+ const result: string[] = [];
149
+ ts.forEachChild(parent, (node) => {
150
+ if (ts.isPropertyAccessExpression(node)) {
151
+ if (
152
+ ts.isIdentifier(node.expression) &&
153
+ node.expression.text === localName &&
154
+ ts.isIdentifier(node.name)
155
+ ) {
156
+ result.push(node.name.text);
157
+ }
158
+ }
159
+ else {
160
+ result.push(...fn(node));
161
+ }
162
+ });
163
+
164
+ return result;
165
+ };
166
+
167
+ return fn(this._sourceFile);
168
+ }
169
+
170
+ public getMetaFromNode(node: ts.Node): TSdCliTsMetadata {
171
+ if (ts.isClassDeclaration(node)) {
172
+ return new SdCliTsClassMetadata(this, node);
173
+ }
174
+ else if (ts.isStringLiteral(node)) {
175
+ return node.text;
176
+ }
177
+ else if (ts.isNoSubstitutionTemplateLiteral(node)) {
178
+ return node.text;
179
+ }
180
+ else if (node.kind === ts.SyntaxKind.NullKeyword) {
181
+ return null;
182
+ }
183
+
184
+ throw new NeverEntryError();
185
+ }
186
+ }
187
+
188
+ export class SdCliTsClassMetadata {
189
+ public constructor(private readonly _fileMeta: SdCliTsFileMetadata,
190
+ private readonly _node: ts.ClassDeclaration) {
191
+ }
192
+
193
+ private _ngDeclCache?: TSdCliTsNgMetadata;
194
+
195
+ public get ngDecl(): TSdCliTsNgMetadata | undefined {
196
+ if (this._ngDeclCache !== undefined) return this._ngDeclCache;
197
+
198
+ if (!this._node.decorators) return undefined;
199
+
200
+ for (const deco of this._node.decorators) {
201
+ if (!ts.isCallExpression(deco.expression)) continue;
202
+ if (!ts.isIdentifier(deco.expression.expression)) {
203
+ throw new NeverEntryError();
204
+ }
205
+
206
+ if (deco.expression.expression.text === "Injectable") {
207
+ this._ngDeclCache = new SdCliTsNgInjectableMetadata(this._fileMeta, deco);
208
+ return this._ngDeclCache;
209
+ }
210
+ else if (deco.expression.expression.text === "Directive") {
211
+ this._ngDeclCache = new SdCliTsNgDirectiveMetadata(this._fileMeta, deco);
212
+ return this._ngDeclCache;
213
+ }
214
+ else if (deco.expression.expression.text === "Component") {
215
+ this._ngDeclCache = new SdCliTsNgComponentMetadata(this._fileMeta, deco);
216
+ return this._ngDeclCache;
217
+ }
218
+ else if (deco.expression.expression.text === "Pipe") {
219
+ this._ngDeclCache = new SdCliTsNgPipeMetadata(this._fileMeta, deco);
220
+ return this._ngDeclCache;
221
+ }
222
+ }
223
+
224
+ return undefined;
225
+ }
226
+ }
227
+
228
+ export class SdCliTsObjectMetadata {
229
+ public constructor(private readonly _fileMeta: SdCliTsFileMetadata,
230
+ private readonly _node: ts.ObjectLiteralExpression) {
231
+ }
232
+
233
+ private readonly _getPropValueCache = new Map<string, TSdCliTsMetadata | undefined>();
234
+
235
+ public getPropValue(propName: string): TSdCliTsMetadata | undefined {
236
+ if (this._getPropValueCache.has(propName)) {
237
+ return this._getPropValueCache.get(propName);
238
+ }
239
+
240
+ const prop = this._node.properties.single((item) => (
241
+ ts.isPropertyAssignment(item) &&
242
+ ts.isIdentifier(item.name) &&
243
+ item.name.text === propName
244
+ )) as ts.PropertyAssignment | undefined;
245
+ if (!prop) {
246
+ this._getPropValueCache.set(propName, undefined);
247
+ return undefined;
248
+ }
249
+
250
+ const result = this._fileMeta.getMetaFromNode(prop.initializer);
251
+ this._getPropValueCache.set(propName, result);
252
+ return result;
253
+ }
254
+ }
255
+
256
+ export type TSdCliTsMetadata = SdCliTsClassMetadata
257
+ | SdCliTsObjectMetadata
258
+ | TSdCliMetaRef
259
+ | string
260
+ | null;
261
+
262
+ export class SdCliTsNgInjectableMetadata {
263
+ public constructor(private readonly _fileMeta: SdCliTsFileMetadata,
264
+ private readonly _node: ts.Decorator) {
265
+ }
266
+
267
+ private _providedInCache?: string;
268
+
269
+ public get providedIn(): string | undefined {
270
+ if (this._providedInCache !== undefined) return this._providedInCache;
271
+
272
+ if (!ts.isCallExpression(this._node.expression)) throw new NeverEntryError();
273
+
274
+ if (this._node.expression.arguments.length > 0 && ts.isObjectLiteralExpression(this._node.expression.arguments[0])) {
275
+ const decoArg = new SdCliTsObjectMetadata(this._fileMeta, this._node.expression.arguments[0]);
276
+ const decoArgSelectorVal = decoArg.getPropValue("providedIn");
277
+ if (typeof decoArgSelectorVal === "string") {
278
+ this._providedInCache = decoArgSelectorVal;
279
+ return decoArgSelectorVal;
280
+ }
281
+ }
282
+
283
+ return undefined;
284
+ }
285
+ }
286
+
287
+ export class SdCliTsNgDirectiveMetadata {
288
+ public constructor(private readonly _fileMeta: SdCliTsFileMetadata,
289
+ private readonly _node: ts.Decorator) {
290
+ }
291
+
292
+ private _selectorCache?: string;
293
+
294
+ public get selector(): string {
295
+ if (this._selectorCache !== undefined) return this._selectorCache;
296
+
297
+ if (!ts.isCallExpression(this._node.expression)) throw new NeverEntryError();
298
+
299
+ if (this._node.expression.arguments.length > 0 && ts.isObjectLiteralExpression(this._node.expression.arguments[0])) {
300
+ const decoArg = new SdCliTsObjectMetadata(this._fileMeta, this._node.expression.arguments[0]);
301
+ const decoArgSelectorVal = decoArg.getPropValue("selector");
302
+ if (typeof decoArgSelectorVal === "string") {
303
+ this._selectorCache = decoArgSelectorVal;
304
+ return decoArgSelectorVal;
305
+ }
306
+ }
307
+
308
+ throw new NeverEntryError();
309
+ }
310
+ }
311
+
312
+ export class SdCliTsNgComponentMetadata {
313
+ public constructor(private readonly _fileMeta: SdCliTsFileMetadata,
314
+ private readonly _node: ts.Decorator) {
315
+ }
316
+
317
+ private _selectorCache?: string;
318
+
319
+ public get selector(): string {
320
+ if (this._selectorCache !== undefined) return this._selectorCache;
321
+
322
+ if (!ts.isCallExpression(this._node.expression)) throw new NeverEntryError();
323
+
324
+ if (this._node.expression.arguments.length > 0 && ts.isObjectLiteralExpression(this._node.expression.arguments[0])) {
325
+ const decoArg = new SdCliTsObjectMetadata(this._fileMeta, this._node.expression.arguments[0]);
326
+ const decoArgSelectorVal = decoArg.getPropValue("selector");
327
+ if (typeof decoArgSelectorVal === "string") {
328
+ this._selectorCache = decoArgSelectorVal;
329
+ return decoArgSelectorVal;
330
+ }
331
+ }
332
+
333
+ throw new NeverEntryError();
334
+ }
335
+
336
+ private _templateCache?: string;
337
+
338
+ public get template(): string {
339
+ if (this._templateCache !== undefined) return this._templateCache;
340
+
341
+ if (!ts.isCallExpression(this._node.expression)) throw new NeverEntryError();
342
+
343
+ if (this._node.expression.arguments.length > 0 && ts.isObjectLiteralExpression(this._node.expression.arguments[0])) {
344
+ const decoArg = new SdCliTsObjectMetadata(this._fileMeta, this._node.expression.arguments[0]);
345
+ const decoArgSelectorVal = decoArg.getPropValue("template");
346
+ if (typeof decoArgSelectorVal === "string") {
347
+ this._templateCache = decoArgSelectorVal;
348
+ return decoArgSelectorVal;
349
+ }
350
+ }
351
+
352
+ throw new NeverEntryError();
353
+ }
354
+ }
355
+
356
+ export class SdCliTsNgPipeMetadata {
357
+ public constructor(private readonly _fileMeta: SdCliTsFileMetadata,
358
+ private readonly _node: ts.Decorator) {
359
+ }
360
+
361
+ private _pipeNameCache?: string;
362
+
363
+ public get pipeName(): string {
364
+ if (this._pipeNameCache !== undefined) return this._pipeNameCache;
365
+
366
+ if (!ts.isCallExpression(this._node.expression)) throw new NeverEntryError();
367
+
368
+ if (this._node.expression.arguments.length > 0 && ts.isObjectLiteralExpression(this._node.expression.arguments[0])) {
369
+ const decoArg = new SdCliTsObjectMetadata(this._fileMeta, this._node.expression.arguments[0]);
370
+ const decoArgSelectorVal = decoArg.getPropValue("name");
371
+ if (typeof decoArgSelectorVal === "string") {
372
+ this._pipeNameCache = decoArgSelectorVal;
373
+ return decoArgSelectorVal;
374
+ }
375
+ }
376
+
377
+ throw new NeverEntryError();
378
+ }
379
+ }
380
+
381
+ export type TSdCliTsNgMetadata = SdCliTsNgInjectableMetadata
382
+ | SdCliTsNgDirectiveMetadata
383
+ | SdCliTsNgComponentMetadata
384
+ | SdCliTsNgPipeMetadata;
@@ -0,0 +1,32 @@
1
+ import path from "path";
2
+ import ts from "typescript";
3
+ import { FsUtil } from "@simplysm/sd-core-node";
4
+ import { SdCliTsFileMetadata } from "./SdCliTsFileMetadata";
5
+
6
+ export class SdCliTsRootMetadata {
7
+ private readonly _fileMetaCache = new Map<string, SdCliTsFileMetadata>();
8
+
9
+ public constructor(private readonly _packagePath: string) {
10
+ }
11
+
12
+ public removeCaches(filePaths: string[]): void {
13
+ for (const filePath of filePaths) {
14
+ this._fileMetaCache.delete(filePath);
15
+ }
16
+ }
17
+
18
+ public getFileMetas(): SdCliTsFileMetadata[] {
19
+ const tsconfigPath = path.resolve(this._packagePath, "tsconfig-build.json");
20
+ const tsconfig = FsUtil.readJson(tsconfigPath);
21
+ const parsedTsconfig = ts.parseJsonConfigFileContent(tsconfig, ts.sys, this._packagePath, tsconfig.angularCompilerOptions);
22
+
23
+ const result: SdCliTsFileMetadata[] = [];
24
+ for (const fileName of parsedTsconfig.fileNames) {
25
+ const filePath = path.resolve(fileName);
26
+ const fileMeta = this._fileMetaCache.getOrCreate(filePath, () => new SdCliTsFileMetadata(filePath));
27
+ result.push(fileMeta);
28
+ }
29
+
30
+ return result;
31
+ }
32
+ }
@@ -5,11 +5,11 @@ export class SdCliNpmConfigUtil {
5
5
  return {
6
6
  defaults: [
7
7
  ...Object.keys(npmConfig.dependencies ?? {}),
8
- ...Object.keys(npmConfig.peerDependencies ?? {}).filter((item) => !npmConfig.peerDependenciesMeta?.[item].optional)
8
+ ...Object.keys(npmConfig.peerDependencies ?? {}).filter((item) => !npmConfig.peerDependenciesMeta?.[item]?.optional)
9
9
  ].distinct(),
10
10
  optionals: [
11
11
  ...Object.keys(npmConfig.optionalDependencies ?? {}),
12
- ...Object.keys(npmConfig.peerDependencies ?? {}).filter((item) => npmConfig.peerDependenciesMeta?.[item].optional)
12
+ ...Object.keys(npmConfig.peerDependencies ?? {}).filter((item) => npmConfig.peerDependenciesMeta?.[item]?.optional)
13
13
  ].distinct()
14
14
  };
15
15
  }
@@ -6,5 +6,9 @@
6
6
  ],
7
7
  "outDir": "./dist",
8
8
  "declaration": false
9
- }
9
+ },
10
+ "files": [
11
+ "src/bin/sd-cli.ts",
12
+ "src/index.ts"
13
+ ]
10
14
  }
package/tsconfig.json CHANGED
@@ -20,5 +20,9 @@
20
20
  "../sd-service-server/src/index.ts"
21
21
  ]
22
22
  }
23
- }
23
+ },
24
+ "files": [
25
+ "src/bin/sd-cli.ts",
26
+ "src/index.ts"
27
+ ]
24
28
  }