@simplysm/sd-cli 7.0.61 → 7.0.62
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/SdCliBuildResultError.mjs +8 -0
- package/dist/builder/SdCliTsLibBuilder.mjs +24 -1
- package/dist/index.mjs +28 -0
- package/dist/ng-tools/NgModuleGenerator.mjs +278 -0
- package/dist/ng-tools/babel/SdCliBbFileMetadata.mjs +331 -0
- package/dist/ng-tools/babel/SdCliBbRootMetadata.mjs +171 -0
- package/dist/ng-tools/babel/SdCliBbUtil.mjs +14 -0
- package/dist/ng-tools/babel/TSdCliBbNgMetadata.mjs +169 -0
- package/dist/ng-tools/babel/TSdCliBbTypeMetadata.mjs +127 -0
- package/dist/ng-tools/commons.mjs +2 -0
- package/dist/ng-tools/typescript/SdCliTsFileMetadata.mjs +325 -0
- package/dist/ng-tools/typescript/SdCliTsRootMetadata.mjs +28 -0
- package/dist/utils/SdCliNpmConfigUtil.mjs +3 -3
- package/package.json +11 -7
- package/src/SdCliBuildResultError.ts +9 -0
- package/src/builder/SdCliTsLibBuilder.ts +28 -0
- package/src/index.ts +27 -0
- package/src/ng-tools/NgModuleGenerator.ts +361 -0
- package/src/ng-tools/babel/SdCliBbFileMetadata.ts +372 -0
- package/src/ng-tools/babel/SdCliBbRootMetadata.ts +207 -0
- package/src/ng-tools/babel/SdCliBbUtil.ts +15 -0
- package/src/ng-tools/babel/TSdCliBbNgMetadata.ts +220 -0
- package/src/ng-tools/babel/TSdCliBbTypeMetadata.ts +177 -0
- package/src/ng-tools/commons.ts +3 -0
- package/src/ng-tools/typescript/SdCliTsFileMetadata.ts +384 -0
- package/src/ng-tools/typescript/SdCliTsRootMetadata.ts +32 -0
- package/src/utils/SdCliNpmConfigUtil.ts +2 -2
- package/tsconfig-build.json +5 -1
- package/tsconfig.json +5 -1
|
@@ -0,0 +1,372 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Declaration,
|
|
3
|
+
Expression,
|
|
4
|
+
isArrayExpression,
|
|
5
|
+
isClassDeclaration,
|
|
6
|
+
isExportDeclaration,
|
|
7
|
+
isExportDefaultDeclaration,
|
|
8
|
+
isExportNamedDeclaration,
|
|
9
|
+
isExportSpecifier,
|
|
10
|
+
isFunctionDeclaration,
|
|
11
|
+
isIdentifier,
|
|
12
|
+
isImportDeclaration,
|
|
13
|
+
isImportSpecifier,
|
|
14
|
+
isObjectExpression,
|
|
15
|
+
isSpreadElement,
|
|
16
|
+
isStringLiteral,
|
|
17
|
+
isVariableDeclaration,
|
|
18
|
+
PatternLike,
|
|
19
|
+
SpreadElement,
|
|
20
|
+
Statement
|
|
21
|
+
} from "@babel/types";
|
|
22
|
+
import babelParser from "@babel/parser";
|
|
23
|
+
import { FsUtil } from "@simplysm/sd-core-node";
|
|
24
|
+
import path from "path";
|
|
25
|
+
import { TSdCliBbMetadata } from "./SdCliBbRootMetadata";
|
|
26
|
+
import {
|
|
27
|
+
SdCliBbArrayMetadata,
|
|
28
|
+
SdCliBbClassMetadata,
|
|
29
|
+
SdCliBbFunctionMetadata,
|
|
30
|
+
SdCliBbObjectMetadata,
|
|
31
|
+
SdCliBbVariableMetadata
|
|
32
|
+
} from "./TSdCliBbTypeMetadata";
|
|
33
|
+
import { SdCliBbUtil } from "./SdCliBbUtil";
|
|
34
|
+
|
|
35
|
+
export class SdCliBbFileMetadata {
|
|
36
|
+
public readonly rawMetas: Statement[] = [];
|
|
37
|
+
|
|
38
|
+
public constructor(public readonly filePath: string) {
|
|
39
|
+
let realFilePath: string | undefined;
|
|
40
|
+
for (const ext of ["", ".mjs", ".cjs", ".js"]) {
|
|
41
|
+
if (FsUtil.exists(filePath + ext) && !FsUtil.isDirectory(filePath + ext)) {
|
|
42
|
+
realFilePath = filePath + ext;
|
|
43
|
+
break;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
if (realFilePath === undefined) {
|
|
47
|
+
throw SdCliBbUtil.error("파일을 찾을 수 없습니다.", filePath);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const fileContent = FsUtil.readFile(realFilePath);
|
|
51
|
+
this.rawMetas = babelParser.parse(fileContent, { sourceType: "module" }).program.body;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
private _exportsCache?: { exportedName: string; target: TSdCliBbMetadata }[];
|
|
55
|
+
|
|
56
|
+
public get exports(): { exportedName: string; target: TSdCliBbMetadata }[] {
|
|
57
|
+
if (this._exportsCache) return this._exportsCache;
|
|
58
|
+
|
|
59
|
+
const result: { exportedName: string; target: TSdCliBbMetadata }[] = [];
|
|
60
|
+
for (const rawMeta of this.rawMetas) {
|
|
61
|
+
if (!isExportDeclaration(rawMeta)) continue;
|
|
62
|
+
|
|
63
|
+
if (isExportNamedDeclaration(rawMeta)) {
|
|
64
|
+
for (const specifier of rawMeta.specifiers) {
|
|
65
|
+
if (isExportSpecifier(specifier)) {
|
|
66
|
+
const exportedName = isIdentifier(specifier.exported) ? specifier.exported.name : undefined;
|
|
67
|
+
if (exportedName === undefined) {
|
|
68
|
+
throw SdCliBbUtil.error("예상치 못한 방식의 코드가 발견되었습니다.", this.filePath, rawMeta);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
if (rawMeta.source) {
|
|
72
|
+
if (rawMeta.source.value.includes(".")) {
|
|
73
|
+
const moduleFilePath = path.resolve(path.dirname(this.filePath), rawMeta.source.value);
|
|
74
|
+
result.push({
|
|
75
|
+
exportedName,
|
|
76
|
+
target: {
|
|
77
|
+
filePath: moduleFilePath,
|
|
78
|
+
name: specifier.local.name,
|
|
79
|
+
__TDeclRef__: "__TDeclRef__"
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
else {
|
|
84
|
+
const moduleName = rawMeta.source.value;
|
|
85
|
+
result.push({
|
|
86
|
+
exportedName,
|
|
87
|
+
target: { moduleName, name: specifier.local.name, __TDeclRef__: "__TDeclRef__" }
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
result.push({
|
|
93
|
+
exportedName,
|
|
94
|
+
target: this._findMetaFromInside(specifier.local.name)
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
else {
|
|
99
|
+
throw SdCliBbUtil.error("예상치 못한 방식의 코드가 발견되었습니다.", this.filePath, rawMeta);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
else if (isExportDefaultDeclaration(rawMeta)) {
|
|
104
|
+
result.push({
|
|
105
|
+
exportedName: "default",
|
|
106
|
+
target: this.getMetaFromRaw(rawMeta.declaration)
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
else {
|
|
110
|
+
if (rawMeta.source.value.includes(".")) {
|
|
111
|
+
const moduleFilePath = path.resolve(path.dirname(this.filePath), rawMeta.source.value);
|
|
112
|
+
result.push({
|
|
113
|
+
exportedName: "*",
|
|
114
|
+
target: {
|
|
115
|
+
filePath: moduleFilePath,
|
|
116
|
+
name: "*",
|
|
117
|
+
__TDeclRef__: "__TDeclRef__"
|
|
118
|
+
}
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
else {
|
|
122
|
+
throw SdCliBbUtil.error("예상치 못한 방식의 코드가 발견되었습니다.", this.filePath, rawMeta);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
this._exportsCache = result;
|
|
128
|
+
return result;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
private readonly _findMetaFromOutsideCache = new Map<string, TSdCliBbMetadata>();
|
|
132
|
+
|
|
133
|
+
public findMetaFromOutside(name: string): TSdCliBbMetadata {
|
|
134
|
+
const cache = this._findMetaFromOutsideCache.get(name);
|
|
135
|
+
if (cache !== undefined) return cache;
|
|
136
|
+
|
|
137
|
+
for (const rawMeta of this.rawMetas) {
|
|
138
|
+
if (isExportNamedDeclaration(rawMeta)) {
|
|
139
|
+
if (rawMeta.declaration) {
|
|
140
|
+
if (isVariableDeclaration(rawMeta.declaration)) {
|
|
141
|
+
for (const decl of rawMeta.declaration.declarations) {
|
|
142
|
+
if (isIdentifier(decl.id)) {
|
|
143
|
+
if (decl.id.name === name) {
|
|
144
|
+
const result = new SdCliBbVariableMetadata(this, decl);
|
|
145
|
+
this._findMetaFromOutsideCache.set(name, result);
|
|
146
|
+
return result;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
else {
|
|
150
|
+
throw SdCliBbUtil.error("예상치 못한 방식의 코드가 발견되었습니다.", this.filePath, rawMeta);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
else if (isClassDeclaration(rawMeta.declaration)) {
|
|
155
|
+
if (rawMeta.declaration.id.name === name) {
|
|
156
|
+
const result = new SdCliBbClassMetadata(this, rawMeta.declaration);
|
|
157
|
+
this._findMetaFromOutsideCache.set(name, result);
|
|
158
|
+
return result;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
else if (isFunctionDeclaration(rawMeta.declaration)) {
|
|
162
|
+
if (rawMeta.declaration.id) {
|
|
163
|
+
if (rawMeta.declaration.id.name === name) {
|
|
164
|
+
const result = new SdCliBbFunctionMetadata(this, rawMeta.declaration);
|
|
165
|
+
this._findMetaFromOutsideCache.set(name, result);
|
|
166
|
+
return result;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
else {
|
|
170
|
+
throw SdCliBbUtil.error("예상치 못한 방식의 코드가 발견되었습니다.", this.filePath, rawMeta);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
else {
|
|
174
|
+
throw SdCliBbUtil.error("예상치 못한 방식의 코드가 발견되었습니다.", this.filePath, rawMeta);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
else {
|
|
178
|
+
for (const specifier of rawMeta.specifiers) {
|
|
179
|
+
if (isExportSpecifier(specifier)) {
|
|
180
|
+
const exportedName = isIdentifier(specifier.exported) ? specifier.exported.name : undefined;
|
|
181
|
+
if (exportedName === undefined) {
|
|
182
|
+
throw SdCliBbUtil.error("예상치 못한 방식의 코드가 발견되었습니다.", this.filePath, rawMeta);
|
|
183
|
+
}
|
|
184
|
+
else if (exportedName === name) {
|
|
185
|
+
if (rawMeta.source) {
|
|
186
|
+
if (rawMeta.source.value.includes(".")) {
|
|
187
|
+
const moduleFilePath = path.resolve(path.dirname(this.filePath), rawMeta.source.value);
|
|
188
|
+
const result = {
|
|
189
|
+
filePath: moduleFilePath,
|
|
190
|
+
name: specifier.local.name,
|
|
191
|
+
__TDeclRef__: "__TDeclRef__" as const
|
|
192
|
+
};
|
|
193
|
+
this._findMetaFromOutsideCache.set(name, result);
|
|
194
|
+
return result;
|
|
195
|
+
}
|
|
196
|
+
else {
|
|
197
|
+
const moduleName = rawMeta.source.value;
|
|
198
|
+
const result = {
|
|
199
|
+
moduleName,
|
|
200
|
+
name: specifier.local.name,
|
|
201
|
+
__TDeclRef__: "__TDeclRef__" as const
|
|
202
|
+
};
|
|
203
|
+
this._findMetaFromOutsideCache.set(name, result);
|
|
204
|
+
return result;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
else {
|
|
208
|
+
const result = this._findMetaFromInside(specifier.local.name);
|
|
209
|
+
this._findMetaFromOutsideCache.set(name, result);
|
|
210
|
+
return result;
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
else if (isExportDefaultDeclaration(rawMeta) && name === "default") {
|
|
218
|
+
const result = this.getMetaFromRaw(rawMeta.declaration);
|
|
219
|
+
if (Array.isArray(result)) {
|
|
220
|
+
throw SdCliBbUtil.error("예상치 못한 방식의 코드가 발견되었습니다.", this.filePath, rawMeta);
|
|
221
|
+
}
|
|
222
|
+
this._findMetaFromOutsideCache.set(name, result);
|
|
223
|
+
return result;
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
throw SdCliBbUtil.error(`'${name}'에 대한 'export'를 찾을 수 없습니다.`, this.filePath);
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
private readonly _findMetaFromInsideCache = new Map<string, TSdCliBbMetadata>();
|
|
231
|
+
|
|
232
|
+
private _findMetaFromInside(localName: string): TSdCliBbMetadata {
|
|
233
|
+
const cache = this._findMetaFromInsideCache.get(localName);
|
|
234
|
+
if (cache !== undefined) return cache;
|
|
235
|
+
|
|
236
|
+
for (const rawMeta of this.rawMetas) {
|
|
237
|
+
if (isClassDeclaration(rawMeta) && rawMeta.id.name === localName) {
|
|
238
|
+
return new SdCliBbClassMetadata(this, rawMeta);
|
|
239
|
+
}
|
|
240
|
+
else if (isExportNamedDeclaration(rawMeta)) {
|
|
241
|
+
for (const specifier of rawMeta.specifiers) {
|
|
242
|
+
if (isExportSpecifier(specifier)) {
|
|
243
|
+
const exportedName = isIdentifier(specifier.exported) ? specifier.exported.name : undefined;
|
|
244
|
+
if (exportedName === undefined) {
|
|
245
|
+
throw SdCliBbUtil.error("예상치 못한 방식의 코드가 발견되었습니다.", this.filePath, rawMeta);
|
|
246
|
+
}
|
|
247
|
+
else if (exportedName === localName) {
|
|
248
|
+
if (rawMeta.source) {
|
|
249
|
+
if (rawMeta.source.value.includes(".")) {
|
|
250
|
+
const moduleFilePath = path.resolve(path.dirname(this.filePath), rawMeta.source.value);
|
|
251
|
+
const result = {
|
|
252
|
+
filePath: moduleFilePath,
|
|
253
|
+
name: specifier.local.name,
|
|
254
|
+
__TDeclRef__: "__TDeclRef__" as const
|
|
255
|
+
};
|
|
256
|
+
this._findMetaFromInsideCache.set(localName, result);
|
|
257
|
+
return result;
|
|
258
|
+
}
|
|
259
|
+
else {
|
|
260
|
+
const moduleName = rawMeta.source.value;
|
|
261
|
+
const result = {
|
|
262
|
+
moduleName,
|
|
263
|
+
name: specifier.local.name,
|
|
264
|
+
__TDeclRef__: "__TDeclRef__" as const
|
|
265
|
+
};
|
|
266
|
+
this._findMetaFromInsideCache.set(localName, result);
|
|
267
|
+
return result;
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
/*else if (isExportDefaultDeclaration(rawMeta) && localName === "default") {
|
|
275
|
+
const result = this.getMetaFromRaw(rawMeta.declaration);
|
|
276
|
+
if (Array.isArray(result)) {
|
|
277
|
+
throw new NeverEntryError();
|
|
278
|
+
}
|
|
279
|
+
this._findMetaFromInsideCache.set(localName, result);
|
|
280
|
+
return result;
|
|
281
|
+
}*/
|
|
282
|
+
else if (isImportDeclaration(rawMeta)) {
|
|
283
|
+
for (const specifier of rawMeta.specifiers) {
|
|
284
|
+
if (isImportSpecifier(specifier)) {
|
|
285
|
+
const impLocalName = isIdentifier(specifier.local) ? specifier.local.name : undefined;
|
|
286
|
+
if (impLocalName === undefined) {
|
|
287
|
+
throw SdCliBbUtil.error("예상치 못한 방식의 코드가 발견되었습니다.", this.filePath, rawMeta);
|
|
288
|
+
}
|
|
289
|
+
else if (impLocalName === localName) {
|
|
290
|
+
if (isIdentifier(specifier.imported)) {
|
|
291
|
+
if (rawMeta.source.value.includes(".")) {
|
|
292
|
+
const moduleFilePath = path.resolve(path.dirname(this.filePath), rawMeta.source.value);
|
|
293
|
+
const result = {
|
|
294
|
+
filePath: moduleFilePath,
|
|
295
|
+
name: specifier.imported.name,
|
|
296
|
+
__TDeclRef__: "__TDeclRef__" as const
|
|
297
|
+
};
|
|
298
|
+
this._findMetaFromInsideCache.set(localName, result);
|
|
299
|
+
return result;
|
|
300
|
+
}
|
|
301
|
+
else {
|
|
302
|
+
const moduleName = rawMeta.source.value;
|
|
303
|
+
const result = {
|
|
304
|
+
moduleName,
|
|
305
|
+
name: specifier.imported.name,
|
|
306
|
+
__TDeclRef__: "__TDeclRef__" as const
|
|
307
|
+
};
|
|
308
|
+
this._findMetaFromInsideCache.set(localName, result);
|
|
309
|
+
return result;
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
else {
|
|
313
|
+
throw SdCliBbUtil.error("예상치 못한 방식의 코드가 발견되었습니다.", this.filePath, rawMeta);
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
else if (isVariableDeclaration(rawMeta)) {
|
|
320
|
+
for (const decl of rawMeta.declarations) {
|
|
321
|
+
if (isIdentifier(decl.id)) {
|
|
322
|
+
if (decl.id.name === localName) {
|
|
323
|
+
const result = new SdCliBbVariableMetadata(this, decl);
|
|
324
|
+
this._findMetaFromInsideCache.set(localName, result);
|
|
325
|
+
return result;
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
else {
|
|
329
|
+
throw SdCliBbUtil.error("예상치 못한 방식의 코드가 발견되었습니다.", this.filePath, rawMeta);
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
else if (isFunctionDeclaration(rawMeta)) {
|
|
334
|
+
if (rawMeta.id) {
|
|
335
|
+
if (rawMeta.id.name === localName) {
|
|
336
|
+
const result = new SdCliBbFunctionMetadata(this, rawMeta);
|
|
337
|
+
this._findMetaFromInsideCache.set(localName, result);
|
|
338
|
+
return result;
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
else {
|
|
342
|
+
throw SdCliBbUtil.error("예상치 못한 방식의 코드가 발견되었습니다.", this.filePath, rawMeta);
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
throw SdCliBbUtil.error(`'${localName}'에 대한 내부선언을 찾을 수 없습니다.`, this.filePath);
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
public getMetaFromRaw(rawMeta: Declaration | Expression | PatternLike | SpreadElement): TSdCliBbMetadata {
|
|
351
|
+
if (isIdentifier(rawMeta)) {
|
|
352
|
+
return this._findMetaFromInside(rawMeta.name);
|
|
353
|
+
}
|
|
354
|
+
else if (isClassDeclaration(rawMeta)) {
|
|
355
|
+
return new SdCliBbClassMetadata(this, rawMeta);
|
|
356
|
+
}
|
|
357
|
+
else if (isArrayExpression(rawMeta)) {
|
|
358
|
+
return new SdCliBbArrayMetadata(this, rawMeta);
|
|
359
|
+
}
|
|
360
|
+
else if (isObjectExpression(rawMeta)) {
|
|
361
|
+
return new SdCliBbObjectMetadata(this, rawMeta);
|
|
362
|
+
}
|
|
363
|
+
else if (isStringLiteral(rawMeta)) {
|
|
364
|
+
return rawMeta.value;
|
|
365
|
+
}
|
|
366
|
+
else if (isSpreadElement(rawMeta)) {
|
|
367
|
+
return this.getMetaFromRaw(rawMeta.argument);
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
throw SdCliBbUtil.error("예상치 못한 방식의 코드가 발견되었습니다.", this.filePath, rawMeta);
|
|
371
|
+
}
|
|
372
|
+
}
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
import { SdCliBbFileMetadata } from "./SdCliBbFileMetadata";
|
|
2
|
+
import path from "path";
|
|
3
|
+
import { INpmConfig } from "../../commons";
|
|
4
|
+
import { SdCliNpmConfigUtil } from "../../utils/SdCliNpmConfigUtil";
|
|
5
|
+
import { NeverEntryError, StringUtil } from "@simplysm/sd-core-common";
|
|
6
|
+
import { FsUtil, PathUtil } from "@simplysm/sd-core-node";
|
|
7
|
+
import { TSdCliBbTypeMetadata } from "./TSdCliBbTypeMetadata";
|
|
8
|
+
import { TSdCliMetaRef } from "../commons";
|
|
9
|
+
|
|
10
|
+
export class SdCliBbRootMetadata {
|
|
11
|
+
private readonly _entryMap: Map<string, string>;
|
|
12
|
+
private readonly _fileMetaCache = new Map<string, SdCliBbFileMetadata>();
|
|
13
|
+
|
|
14
|
+
public constructor(packagePath: string) {
|
|
15
|
+
const allDepPaths = this._getAllDepPaths(packagePath);
|
|
16
|
+
this._entryMap = this._getEntryMap(allDepPaths);
|
|
17
|
+
// const ngDepPaths = this._getNgDepPaths(allDepPaths);
|
|
18
|
+
// this._entryMap = this._getEntryMap(ngDepPaths);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
public removeCaches(filePaths: string[]): void {
|
|
22
|
+
for (const filePath of filePaths) {
|
|
23
|
+
this._fileMetaCache.delete(filePath);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
public getEntryFileMetaRecord(): Record<string, SdCliBbFileMetadata> {
|
|
28
|
+
const result: Record<string, SdCliBbFileMetadata> = {};
|
|
29
|
+
for (const moduleName of this._entryMap.keys()) {
|
|
30
|
+
const entryFilePath = this._entryMap.get(moduleName)!;
|
|
31
|
+
result[moduleName] = this._fileMetaCache.getOrCreate(entryFilePath, () => new SdCliBbFileMetadata(entryFilePath))!;
|
|
32
|
+
}
|
|
33
|
+
return result;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
public findMeta(ref: TSdCliMetaRef): TSdCliBbMetadata | TSdCliBbMetadata[] {
|
|
37
|
+
const filePath = "moduleName" in ref ? this._entryMap.get(ref.moduleName) : ref.filePath;
|
|
38
|
+
if (filePath === undefined) {
|
|
39
|
+
throw new NeverEntryError();
|
|
40
|
+
}
|
|
41
|
+
const fileMeta = this._fileMetaCache.getOrCreate(filePath, () => new SdCliBbFileMetadata(filePath));
|
|
42
|
+
if (ref.name === "*") {
|
|
43
|
+
const result: TSdCliBbMetadata[] = [];
|
|
44
|
+
for (const exp of fileMeta.exports) {
|
|
45
|
+
const meta = exp.target;
|
|
46
|
+
if (typeof meta !== "string" && "__TDeclRef__" in meta) {
|
|
47
|
+
const resultMeta = this.findMeta(meta);
|
|
48
|
+
if (resultMeta instanceof Array) {
|
|
49
|
+
result.push(...resultMeta);
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
result.push(resultMeta);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
result.push(meta);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return result;
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
const meta = fileMeta.findMetaFromOutside(ref.name);
|
|
63
|
+
if (typeof meta !== "string" && "__TDeclRef__" in meta) {
|
|
64
|
+
return this.findMeta(meta);
|
|
65
|
+
}
|
|
66
|
+
return meta;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
public findExportRef(localRef: { filePath: string; name: string }): { moduleName: string; name: string } | undefined {
|
|
71
|
+
const record = this.getEntryFileMetaRecord();
|
|
72
|
+
for (const moduleName of Object.keys(record)) {
|
|
73
|
+
const entryFileMeta = record[moduleName];
|
|
74
|
+
for (const exp of entryFileMeta.exports) {
|
|
75
|
+
if (
|
|
76
|
+
typeof exp.target !== "string" &&
|
|
77
|
+
"filePath" in exp.target &&
|
|
78
|
+
exp.target.filePath === localRef.filePath
|
|
79
|
+
) {
|
|
80
|
+
if (exp.target.name === "*") {
|
|
81
|
+
throw new NeverEntryError();
|
|
82
|
+
}
|
|
83
|
+
else if (exp.target.name === localRef.name) {
|
|
84
|
+
return { moduleName, name: exp.exportedName };
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
return undefined;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
private _getAllDepPaths(packagePath: string): string[] {
|
|
94
|
+
const loadedModuleNames: string[] = [];
|
|
95
|
+
const results: string[] = [];
|
|
96
|
+
|
|
97
|
+
const fn = (currPath: string): void => {
|
|
98
|
+
const npmConfig = FsUtil.readJson(path.resolve(currPath, "package.json")) as INpmConfig;
|
|
99
|
+
|
|
100
|
+
const deps = SdCliNpmConfigUtil.getDependencies(npmConfig);
|
|
101
|
+
|
|
102
|
+
for (const moduleName of deps.defaults) {
|
|
103
|
+
if (loadedModuleNames.includes(moduleName)) continue;
|
|
104
|
+
loadedModuleNames.push(moduleName);
|
|
105
|
+
|
|
106
|
+
const modulePath = FsUtil.findAllParentChildDirPaths("node_modules/" + moduleName, currPath, process.cwd()).first();
|
|
107
|
+
if (StringUtil.isNullOrEmpty(modulePath)) {
|
|
108
|
+
continue;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
results.push(modulePath);
|
|
112
|
+
|
|
113
|
+
fn(modulePath);
|
|
114
|
+
}
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
fn(packagePath);
|
|
118
|
+
|
|
119
|
+
return results;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// private _getNgDepPaths(allDepPaths: string[]): string[] {
|
|
123
|
+
// const results: string[] = [];
|
|
124
|
+
//
|
|
125
|
+
// for (const depPath of allDepPaths) {
|
|
126
|
+
// const npmConfig = FsUtil.readJson(path.resolve(depPath, "package.json")) as INpmConfig;
|
|
127
|
+
// const defaultDeps = SdCliNpmConfigUtil.getDependencies(npmConfig).defaults;
|
|
128
|
+
// if (npmConfig.name === "@angular/core" || defaultDeps.includes("@angular/core")) {
|
|
129
|
+
// results.push(depPath);
|
|
130
|
+
// }
|
|
131
|
+
// }
|
|
132
|
+
//
|
|
133
|
+
// return results;
|
|
134
|
+
// }
|
|
135
|
+
|
|
136
|
+
private _getEntryMap(ngDepPaths: string[]): Map<string, string> {
|
|
137
|
+
const entryMap = new Map<string, string>();
|
|
138
|
+
for (const ngDepPath of ngDepPaths) {
|
|
139
|
+
const npmConfig = FsUtil.readJson(path.resolve(ngDepPath, "package.json")) as INpmConfig;
|
|
140
|
+
|
|
141
|
+
const entryFilePath = npmConfig["es2015"] ?? npmConfig["browser"] ?? npmConfig["module"] ?? npmConfig["main"] ?? npmConfig["default"];
|
|
142
|
+
if (entryFilePath !== undefined) {
|
|
143
|
+
entryMap.set(npmConfig.name, path.resolve(ngDepPath, entryFilePath));
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
if (npmConfig.exports) {
|
|
147
|
+
const exportKeys = Object.keys(npmConfig.exports);
|
|
148
|
+
for (const exportKey of exportKeys) {
|
|
149
|
+
if (
|
|
150
|
+
exportKey.includes("/locales") ||
|
|
151
|
+
exportKey.endsWith("/package.json") ||
|
|
152
|
+
exportKey.endsWith("/testing") ||
|
|
153
|
+
exportKey.endsWith("/upgrade")
|
|
154
|
+
) {
|
|
155
|
+
continue;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
const expEntryFilePath = npmConfig.exports[exportKey]["es2015"] ??
|
|
159
|
+
npmConfig.exports[exportKey]["browser"] ??
|
|
160
|
+
npmConfig.exports[exportKey]["module"] ??
|
|
161
|
+
npmConfig.exports[exportKey]["main"] ??
|
|
162
|
+
npmConfig.exports[exportKey]["default"];
|
|
163
|
+
if (expEntryFilePath !== undefined) {
|
|
164
|
+
const exportPath = path.resolve(ngDepPath, expEntryFilePath);
|
|
165
|
+
const exportResult = this._getGlobExportResult(PathUtil.posix(npmConfig.name, exportKey), exportPath);
|
|
166
|
+
for (const exportResultItem of exportResult) {
|
|
167
|
+
entryMap.set(exportResultItem.name, exportResultItem.target);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
return entryMap;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
private _getGlobExportResult(globName: string, globTarget: string): { name: string; target: string }[] {
|
|
178
|
+
if (globName.includes("*") && globTarget.includes("*")) {
|
|
179
|
+
const result: { name: string; target: string }[] = [];
|
|
180
|
+
|
|
181
|
+
const regexpText = globTarget.replace(/[\\/.*]/g, (item) => (
|
|
182
|
+
item === "/" || item === "\\" ? "[\\\\/]"
|
|
183
|
+
: item === "." ? "\\."
|
|
184
|
+
: item === "*" ? "(.*)"
|
|
185
|
+
: item
|
|
186
|
+
));
|
|
187
|
+
|
|
188
|
+
const targets = FsUtil.glob(globTarget);
|
|
189
|
+
for (const target of targets) {
|
|
190
|
+
const targetNameMatch = new RegExp(regexpText).exec(target);
|
|
191
|
+
if (!targetNameMatch || typeof targetNameMatch[1] === "undefined") {
|
|
192
|
+
throw new NeverEntryError();
|
|
193
|
+
}
|
|
194
|
+
const targetName = targetNameMatch[1];
|
|
195
|
+
const name = globName.replace("*", targetName);
|
|
196
|
+
result.push({ name, target });
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
return result;
|
|
200
|
+
}
|
|
201
|
+
else {
|
|
202
|
+
return [{ name: globName, target: globTarget }];
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
export type TSdCliBbMetadata = TSdCliBbTypeMetadata | TSdCliMetaRef | string;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Node } from "@babel/types";
|
|
2
|
+
import { SdCliBuildResultError } from "../../SdCliBuildResultError";
|
|
3
|
+
|
|
4
|
+
export class SdCliBbUtil {
|
|
5
|
+
public static error(message: string, filePath?: string, meta?: Node): SdCliBuildResultError {
|
|
6
|
+
return new SdCliBuildResultError({
|
|
7
|
+
filePath,
|
|
8
|
+
line: meta?.loc?.start.line,
|
|
9
|
+
char: meta?.loc?.start.column,
|
|
10
|
+
code: undefined,
|
|
11
|
+
severity: "error",
|
|
12
|
+
message: "예상치 못한 방식의 코드가 발견되었습니다."
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
}
|