@simplysm/sd-cli 6.0.28 → 6.0.38
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-node/bin/sd-cli.js +19 -4
- package/dist-node/bin/sd-cli.js.map +1 -1
- package/dist-node/build-tools/SdCliNgModuleFilesGenerator.js +106 -57
- package/dist-node/build-tools/SdCliNgModuleFilesGenerator.js.map +1 -1
- package/dist-node/build-tools/metadata/SdAotMetadataReader.js +13 -11
- package/dist-node/build-tools/metadata/SdAotMetadataReader.js.map +1 -1
- package/dist-node/build-tools/metadata/SdIvyMetadataReader.js +23 -6
- package/dist-node/build-tools/metadata/SdIvyMetadataReader.js.map +1 -1
- package/dist-node/build-tools/metadata/SdMetadataError.js +13 -0
- package/dist-node/build-tools/metadata/SdMetadataError.js.map +1 -0
- package/dist-node/build-tools/metadata/SdMyMetadataReader.js +22 -5
- package/dist-node/build-tools/metadata/SdMyMetadataReader.js.map +1 -1
- package/dist-node/builders/SdCliNgClientBuilder.js +74 -74
- package/dist-node/builders/SdCliNgClientBuilder.js.map +1 -1
- package/dist-node/builders/SdCliNgLibraryBuilder.js +49 -45
- package/dist-node/builders/SdCliNgLibraryBuilder.js.map +1 -1
- package/dist-node/builders/SdCliServerBuilder.js +33 -23
- package/dist-node/builders/SdCliServerBuilder.js.map +1 -1
- package/dist-node/builders/SdCliTypescriptBuilder.js +75 -65
- package/dist-node/builders/SdCliTypescriptBuilder.js.map +1 -1
- package/dist-node/entry-points/SdCliProject.js +17 -17
- package/dist-node/entry-points/SdCliProject.js.map +1 -1
- package/dist-node/packages/SdCliClientPackage.js +6 -4
- package/dist-node/packages/SdCliClientPackage.js.map +1 -1
- package/dist-node/packages/SdCliLibraryPackage.js +5 -3
- package/dist-node/packages/SdCliLibraryPackage.js.map +1 -1
- package/dist-node/packages/SdCliServerPackage.js +4 -3
- package/dist-node/packages/SdCliServerPackage.js.map +1 -1
- package/dist-node/utils/SdWebpackUtil.js +33 -13
- package/dist-node/utils/SdWebpackUtil.js.map +1 -1
- package/dist-node/workers/client-ng-gen-worker.js +54 -0
- package/dist-node/workers/client-ng-gen-worker.js.map +1 -0
- package/dist-node/workers/lib-build-worker.js +7 -6
- package/dist-node/workers/lib-build-worker.js.map +1 -1
- package/dist-types/build-tools/metadata/SdIvyMetadataReader.d.ts +1 -0
- package/dist-types/build-tools/metadata/SdMetadataError.d.ts +6 -0
- package/dist-types/build-tools/metadata/SdMyMetadataReader.d.ts +1 -0
- package/dist-types/builders/SdCliNgClientBuilder.d.ts +6 -2
- package/dist-types/builders/SdCliNgLibraryBuilder.d.ts +3 -2
- package/dist-types/builders/SdCliServerBuilder.d.ts +2 -1
- package/dist-types/builders/SdCliTypescriptBuilder.d.ts +5 -5
- package/dist-types/commons.d.ts +4 -1
- package/dist-types/entry-points/SdCliProject.d.ts +5 -1
- package/dist-types/packages/SdCliClientPackage.d.ts +2 -1
- package/dist-types/packages/SdCliLibraryPackage.d.ts +2 -1
- package/dist-types/packages/SdCliServerPackage.d.ts +2 -1
- package/dist-types/utils/SdWebpackUtil.d.ts +1 -1
- package/dist-types/workers/client-ng-gen-worker.d.ts +1 -0
- package/package.json +7 -7
- package/schema/schema.json +72 -1
- package/sd-tsconfig.node.json +2 -1
- package/src/bin/sd-cli.ts +19 -4
- package/src/build-tools/SdCliNgModuleFilesGenerator.ts +122 -70
- package/src/build-tools/metadata/SdAotMetadataReader.ts +4 -1
- package/src/build-tools/metadata/SdIvyMetadataReader.ts +27 -4
- package/src/build-tools/metadata/SdMetadataError.ts +7 -0
- package/src/build-tools/metadata/SdMyMetadataReader.ts +25 -3
- package/src/builders/SdCliNgClientBuilder.ts +123 -66
- package/src/builders/SdCliNgLibraryBuilder.ts +79 -42
- package/src/builders/SdCliServerBuilder.ts +48 -19
- package/src/builders/SdCliTypescriptBuilder.ts +102 -78
- package/src/commons.ts +2 -1
- package/src/entry-points/SdCliProject.ts +22 -14
- package/src/packages/SdCliClientPackage.ts +5 -3
- package/src/packages/SdCliLibraryPackage.ts +4 -2
- package/src/packages/SdCliServerPackage.ts +4 -3
- package/src/utils/SdWebpackUtil.ts +42 -22
- package/src/workers/client-ng-gen-worker.ts +60 -0
- package/src/workers/lib-build-worker.ts +7 -6
- package/tsconfig.json +2 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ISdPackageBuildResult } from "../commons";
|
|
2
|
-
import { NeverEntryError, ObjectUtil, StringUtil } from "@simplysm/sd-core-common";
|
|
2
|
+
import { NeverEntryError, ObjectUtil, SdError, StringUtil } from "@simplysm/sd-core-common";
|
|
3
3
|
import * as ts from "typescript";
|
|
4
4
|
import { FsUtil, PathUtil } from "@simplysm/sd-core-node";
|
|
5
5
|
import * as path from "path";
|
|
@@ -25,7 +25,9 @@ import {
|
|
|
25
25
|
} from "./metadata/SdAotMetadataReader";
|
|
26
26
|
import { IIvyNgModuleMetadata, SdIvyMetadataReader, TIvyNgMetadata } from "./metadata/SdIvyMetadataReader";
|
|
27
27
|
import { NgtscProgram } from "@angular/compiler-cli";
|
|
28
|
+
import { SdMetadataError } from "./metadata/SdMetadataError";
|
|
28
29
|
|
|
30
|
+
// TODO: LazyPage??
|
|
29
31
|
export class SdCliNgModuleFilesGenerator {
|
|
30
32
|
private readonly _fileCache = new Map<string, TFileCache>();
|
|
31
33
|
|
|
@@ -57,61 +59,86 @@ export class SdCliNgModuleFilesGenerator {
|
|
|
57
59
|
|
|
58
60
|
let changed = false;
|
|
59
61
|
for (const dirtyFilePath of dirtyFilePaths) {
|
|
60
|
-
|
|
62
|
+
try {
|
|
63
|
+
if (PathUtil.isChildPath(dirtyFilePath, this._moduleDistDirPath)) continue;
|
|
61
64
|
|
|
62
|
-
|
|
65
|
+
this._fileCache.delete(dirtyFilePath);
|
|
63
66
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
sourceFile,
|
|
72
|
-
metadata: new SdMyMetadataReader(sourceFile, this._program).getMetadatas()
|
|
73
|
-
});
|
|
74
|
-
changed = true;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
// AOT 라이브러리
|
|
78
|
-
else if (dirtyFilePath.endsWith(".d.ts")) {
|
|
79
|
-
const sourceFile = this._program.getSourceFile(dirtyFilePath);
|
|
80
|
-
if (!sourceFile) throw new NeverEntryError();
|
|
81
|
-
|
|
82
|
-
// from METADATA
|
|
83
|
-
const metadataFilePath = dirtyFilePath.replace(/\.d\.ts$/, ".metadata.json");
|
|
84
|
-
const sdMetadataFilePath = dirtyFilePath.replace(/\.d\.ts$/, ".sd-metadata.json");
|
|
85
|
-
|
|
86
|
-
if (FsUtil.exists(metadataFilePath)) {
|
|
87
|
-
const metadataRoot = await FsUtil.readJsonAsync(metadataFilePath);
|
|
67
|
+
// 내 소스코드
|
|
68
|
+
if (dirtyFilePath.endsWith(".ts") && !dirtyFilePath.endsWith(".d.ts")) {
|
|
69
|
+
const sourceFile = this._program.getSourceFile(dirtyFilePath);
|
|
70
|
+
if (!sourceFile) { // 삭제된 파일
|
|
71
|
+
changed = true;
|
|
72
|
+
continue;
|
|
73
|
+
}
|
|
88
74
|
|
|
89
75
|
this._fileCache.set(dirtyFilePath, {
|
|
90
|
-
type: "
|
|
76
|
+
type: "my",
|
|
91
77
|
sourceFile,
|
|
92
|
-
|
|
78
|
+
metadata: new SdMyMetadataReader(sourceFile, this._program).getMetadatas()
|
|
93
79
|
});
|
|
94
80
|
changed = true;
|
|
95
81
|
}
|
|
96
|
-
else if (FsUtil.exists(sdMetadataFilePath)) {
|
|
97
|
-
const metadataRoot = await FsUtil.readJsonAsync(sdMetadataFilePath);
|
|
98
82
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
83
|
+
// AOT 라이브러리
|
|
84
|
+
else if (dirtyFilePath.endsWith(".d.ts")) {
|
|
85
|
+
const sourceFile = this._program.getSourceFile(dirtyFilePath);
|
|
86
|
+
if (!sourceFile) { // 삭제된 파일
|
|
87
|
+
changed = true;
|
|
88
|
+
continue;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// from METADATA
|
|
92
|
+
const metadataFilePath = dirtyFilePath.replace(/\.d\.ts$/, ".metadata.json");
|
|
93
|
+
const sdMetadataFilePath = dirtyFilePath.replace(/\.d\.ts$/, ".sd-metadata.json");
|
|
94
|
+
|
|
95
|
+
if (FsUtil.exists(metadataFilePath)) {
|
|
96
|
+
const metadataRoot = await FsUtil.readJsonAsync(metadataFilePath);
|
|
97
|
+
|
|
98
|
+
this._fileCache.set(dirtyFilePath, {
|
|
99
|
+
type: "aot",
|
|
100
|
+
sourceFile,
|
|
101
|
+
...new SdAotMetadataReader(metadataRoot).getMetadatas()
|
|
102
|
+
});
|
|
103
|
+
changed = true;
|
|
104
|
+
}
|
|
105
|
+
else if (FsUtil.exists(sdMetadataFilePath)) {
|
|
106
|
+
const metadataRoot = await FsUtil.readJsonAsync(sdMetadataFilePath);
|
|
107
|
+
|
|
108
|
+
this._fileCache.set(dirtyFilePath, {
|
|
109
|
+
type: "aot",
|
|
110
|
+
sourceFile,
|
|
111
|
+
...new SdAotMetadataReader(metadataRoot).getMetadatas()
|
|
112
|
+
});
|
|
113
|
+
changed = true;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// from IVY
|
|
117
|
+
else {
|
|
118
|
+
this._fileCache.set(dirtyFilePath, {
|
|
119
|
+
type: "ivy",
|
|
120
|
+
sourceFile,
|
|
121
|
+
...new SdIvyMetadataReader(sourceFile, ngProgram).getMetadatas()
|
|
122
|
+
});
|
|
123
|
+
changed = true;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
catch (err) {
|
|
128
|
+
if (err instanceof SdMetadataError) {
|
|
129
|
+
result.push({
|
|
130
|
+
filePath: err.fileName,
|
|
131
|
+
severity: "error",
|
|
132
|
+
message: err.message
|
|
103
133
|
});
|
|
104
|
-
changed = true;
|
|
105
134
|
}
|
|
106
|
-
|
|
107
|
-
// from IVY
|
|
108
135
|
else {
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
136
|
+
if (err instanceof Error) {
|
|
137
|
+
throw new SdError(err, "'" + dirtyFilePath + "' 메타데이터 로딩중 에러");
|
|
138
|
+
}
|
|
139
|
+
else {
|
|
140
|
+
throw err;
|
|
141
|
+
}
|
|
115
142
|
}
|
|
116
143
|
}
|
|
117
144
|
}
|
|
@@ -120,29 +147,49 @@ export class SdCliNgModuleFilesGenerator {
|
|
|
120
147
|
}
|
|
121
148
|
|
|
122
149
|
public async generateAsync(): Promise<{ result: ISdPackageBuildResult[]; changedFilePaths: string[] }> {
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
.
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
150
|
+
try {
|
|
151
|
+
let moduleInfoMap = this._getModuleInfoMap();
|
|
152
|
+
moduleInfoMap = this._mergeCircularModuleInfoMap(moduleInfoMap);
|
|
153
|
+
|
|
154
|
+
const routingModuleMap = await this._getRoutingModuleInfoMapAsync();
|
|
155
|
+
|
|
156
|
+
const changedFilePaths = [
|
|
157
|
+
...await this._writeNgModuleFileAsync(moduleInfoMap),
|
|
158
|
+
...await this._writeRoutingModuleFileAsync(moduleInfoMap, routingModuleMap)
|
|
159
|
+
];
|
|
160
|
+
|
|
161
|
+
const genFilePaths = [...moduleInfoMap.keys(), ...routingModuleMap.keys()].distinct();
|
|
162
|
+
const delFilePaths = (await FsUtil.globAsync(path.resolve(this._moduleDistDirPath, "**", "*")))
|
|
163
|
+
.filter((item) => (
|
|
164
|
+
!genFilePaths.includes(PathUtil.posix(item))
|
|
165
|
+
&& !genFilePaths.some((item1) => PathUtil.isChildPath(item1, item))
|
|
166
|
+
))
|
|
167
|
+
.map((item) => PathUtil.posix(item));
|
|
168
|
+
for (const delFilePath of delFilePaths) {
|
|
169
|
+
changedFilePaths.push(delFilePath);
|
|
170
|
+
await FsUtil.removeAsync(delFilePath);
|
|
171
|
+
}
|
|
144
172
|
|
|
145
|
-
|
|
173
|
+
return { result: [], changedFilePaths: changedFilePaths.distinct() };
|
|
174
|
+
}
|
|
175
|
+
catch (err) {
|
|
176
|
+
if (err instanceof SdMetadataError) {
|
|
177
|
+
return {
|
|
178
|
+
result: [{
|
|
179
|
+
filePath: err.fileName,
|
|
180
|
+
severity: "error",
|
|
181
|
+
message: err.message
|
|
182
|
+
}],
|
|
183
|
+
changedFilePaths: []
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
else if (err instanceof Error) {
|
|
187
|
+
throw new SdError(err, "메타데이터 생성중 에러");
|
|
188
|
+
}
|
|
189
|
+
else {
|
|
190
|
+
throw err;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
146
193
|
}
|
|
147
194
|
|
|
148
195
|
// region NgModule
|
|
@@ -512,7 +559,10 @@ export class ${moduleInfo.className} {
|
|
|
512
559
|
const expFilePath = this._getResolvedFilePath(filePath, moduleName);
|
|
513
560
|
if (StringUtil.isNullOrEmpty(expFilePath)) throw new NeverEntryError();
|
|
514
561
|
const expFileCache = this._fileCache.get(expFilePath);
|
|
515
|
-
if (!expFileCache
|
|
562
|
+
if (!expFileCache) {
|
|
563
|
+
throw new SdMetadataError(filePath, `'${filePath}'에서 '${moduleName}'에 대한 파일 '${expFilePath}'을 찾을 수 없습니다.`);
|
|
564
|
+
}
|
|
565
|
+
if (expFileCache.type !== "aot") throw new NeverEntryError();
|
|
516
566
|
const newExp = expFileCache.exports.single((item) => (item.as ?? item.name) === targetName);
|
|
517
567
|
if (!newExp) throw new NeverEntryError();
|
|
518
568
|
|
|
@@ -612,7 +662,7 @@ export class ${moduleInfo.className} {
|
|
|
612
662
|
if (fileCache.type !== "my") continue;
|
|
613
663
|
|
|
614
664
|
for (const metadata of fileCache.metadata) {
|
|
615
|
-
if (
|
|
665
|
+
if (!metadata.className.endsWith("Page")) continue;
|
|
616
666
|
|
|
617
667
|
const newRoutingModuleInfo: IGenRoutingModuleInfo = {
|
|
618
668
|
path: "",
|
|
@@ -681,7 +731,6 @@ export class ${moduleInfo.className} {
|
|
|
681
731
|
const moduleImportTexts: string[] = [];
|
|
682
732
|
|
|
683
733
|
const pageFilePath = this._getModuleModuleImportName(path.dirname(distFilePath), routingModuleInfo.page.moduleFilePath);
|
|
684
|
-
moduleImportTexts.push(`import { ${routingModuleInfo.page.name} } from "${pageFilePath}";`);
|
|
685
734
|
|
|
686
735
|
let content: string;
|
|
687
736
|
if (path.basename(distFilePath) === "_routes.ts") {
|
|
@@ -697,6 +746,7 @@ export const routes: Routes = [
|
|
|
697
746
|
else {
|
|
698
747
|
moduleImportTexts.push(`import { NgModule } from "@angular/core";`);
|
|
699
748
|
moduleImportTexts.push(`import { RouterModule } from "@angular/router";`);
|
|
749
|
+
moduleImportTexts.push(`import { ${routingModuleInfo.page.name} } from "${pageFilePath}";`);
|
|
700
750
|
|
|
701
751
|
const thisPageModuleInfoEntry = Array.from(moduleInfoMap.entries())
|
|
702
752
|
.single((item) => item[1].exports.some((exp) => exp.moduleFilePath === routingModuleInfo.page.moduleFilePath && exp.name === routingModuleInfo.page.name));
|
|
@@ -745,7 +795,9 @@ export class ${routingModuleInfo.page.name}RoutingModule {
|
|
|
745
795
|
private _getRoutingModuleText(routingModuleInfo: IGenRoutingModuleInfo, distFilePath: string): string {
|
|
746
796
|
let content = "{\r\n";
|
|
747
797
|
content += ` path: "${routingModuleInfo.path}",\r\n`;
|
|
748
|
-
|
|
798
|
+
if (path.basename(distFilePath) !== "_routes.ts") {
|
|
799
|
+
content += ` component: ${routingModuleInfo.page.name},\r\n`;
|
|
800
|
+
}
|
|
749
801
|
if (routingModuleInfo.children.length > 0) {
|
|
750
802
|
content += ` children: [\r\n`;
|
|
751
803
|
for (const child of routingModuleInfo.children) {
|
|
@@ -4,6 +4,7 @@ import {
|
|
|
4
4
|
isMetadataGlobalReferenceExpression,
|
|
5
5
|
isMetadataImportedSymbolReferenceExpression,
|
|
6
6
|
isMetadataSymbolicCallExpression,
|
|
7
|
+
isMetadataSymbolicIfExpression,
|
|
7
8
|
isMetadataSymbolicReferenceExpression,
|
|
8
9
|
MetadataEntry,
|
|
9
10
|
MetadataObject,
|
|
@@ -18,7 +19,6 @@ export class SdAotMetadataReader {
|
|
|
18
19
|
|
|
19
20
|
public getMetadatas(): IAotModuleDefMetadata {
|
|
20
21
|
if (StringUtil.isNullOrEmpty(this._metadataRoot.importAs)) {
|
|
21
|
-
console.log(this._metadataRoot);
|
|
22
22
|
throw new NeverEntryError();
|
|
23
23
|
}
|
|
24
24
|
|
|
@@ -258,6 +258,9 @@ export class SdAotMetadataReader {
|
|
|
258
258
|
);
|
|
259
259
|
result.push(...subProvRefTargets);
|
|
260
260
|
}
|
|
261
|
+
else if (isMetadataSymbolicIfExpression(refTarget.metadata)) {
|
|
262
|
+
result.push(...this._getProviderReferenceTargets([refTarget.metadata.thenExpression, refTarget.metadata.elseExpression]));
|
|
263
|
+
}
|
|
261
264
|
else {
|
|
262
265
|
throw new NeverEntryError();
|
|
263
266
|
}
|
|
@@ -7,6 +7,8 @@ import { Reference } from "@angular/compiler-cli/src/ngtsc/imports";
|
|
|
7
7
|
import { NgtscProgram } from "@angular/compiler-cli";
|
|
8
8
|
import * as path from "path";
|
|
9
9
|
import { INpmConfig } from "../../commons";
|
|
10
|
+
import { IMyModuleImport } from "./SdMyMetadataReader";
|
|
11
|
+
import { SdMetadataError } from "./SdMetadataError";
|
|
10
12
|
|
|
11
13
|
export class SdIvyMetadataReader {
|
|
12
14
|
private readonly _typeChecker: ts.TypeChecker;
|
|
@@ -76,7 +78,7 @@ export class SdIvyMetadataReader {
|
|
|
76
78
|
return result;
|
|
77
79
|
}
|
|
78
80
|
|
|
79
|
-
private _getAliasedModuleImportInfo(identifier: ts.Identifier):
|
|
81
|
+
private _getAliasedModuleImportInfo(identifier: ts.Identifier): IMyModuleImport {
|
|
80
82
|
const moduleSymbol = this._typeChecker.getSymbolAtLocation(identifier);
|
|
81
83
|
if (!moduleSymbol) throw new NeverEntryError();
|
|
82
84
|
if (moduleSymbol.valueDeclaration) {
|
|
@@ -86,9 +88,18 @@ export class SdIvyMetadataReader {
|
|
|
86
88
|
else {
|
|
87
89
|
const aliasedTargetSymbol = this._typeChecker.getAliasedSymbol(moduleSymbol);
|
|
88
90
|
const declarations = aliasedTargetSymbol.getDeclarations();
|
|
89
|
-
if (!declarations
|
|
90
|
-
|
|
91
|
-
|
|
91
|
+
if (!declarations || declarations.length < 1) {
|
|
92
|
+
throw new SdMetadataError(this._sourceFile.fileName, `'${identifier.text}'를 찾을 수 없습니다.`);
|
|
93
|
+
}
|
|
94
|
+
const moduleFilePaths = declarations
|
|
95
|
+
.filter((item) => (
|
|
96
|
+
this._hasParentsOrMe(item, (item1) => Boolean(item1.modifiers?.some((mod) => mod.kind === ts.SyntaxKind.ExportKeyword)))
|
|
97
|
+
))
|
|
98
|
+
.map((item) => PathUtil.posix(item.getSourceFile().fileName))
|
|
99
|
+
.distinct();
|
|
100
|
+
if (moduleFilePaths.length !== 1) {
|
|
101
|
+
throw new SdMetadataError(this._sourceFile.fileName, `'${identifier.text}'의 경로가 중복되었습니다.\n${moduleFilePaths.join("\n")}`);
|
|
102
|
+
}
|
|
92
103
|
|
|
93
104
|
const moduleFilePath = moduleFilePaths[0];
|
|
94
105
|
|
|
@@ -96,6 +107,18 @@ export class SdIvyMetadataReader {
|
|
|
96
107
|
}
|
|
97
108
|
}
|
|
98
109
|
|
|
110
|
+
private _hasParentsOrMe(node: ts.Node, fn: (node1: ts.Node) => boolean): boolean {
|
|
111
|
+
let currNode = node as ts.Node | undefined;
|
|
112
|
+
while (true) {
|
|
113
|
+
if (!currNode) return false;
|
|
114
|
+
|
|
115
|
+
const result = fn(currNode);
|
|
116
|
+
if (result) return true;
|
|
117
|
+
|
|
118
|
+
currNode = currNode.parent as ts.Node | undefined;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
99
122
|
private getPackageName(): string {
|
|
100
123
|
let cursorDirPath = path.dirname(this._sourceFile.fileName);
|
|
101
124
|
while (true) {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import * as ts from "typescript";
|
|
2
2
|
import { NeverEntryError } from "@simplysm/sd-core-common";
|
|
3
3
|
import { PathUtil } from "@simplysm/sd-core-node";
|
|
4
|
+
import { SdMetadataError } from "./SdMetadataError";
|
|
4
5
|
|
|
5
6
|
export class SdMyMetadataReader {
|
|
6
7
|
private readonly _typeChecker: ts.TypeChecker;
|
|
@@ -150,9 +151,18 @@ export class SdMyMetadataReader {
|
|
|
150
151
|
else {
|
|
151
152
|
const aliasedTargetSymbol = this._typeChecker.getAliasedSymbol(moduleSymbol);
|
|
152
153
|
const declarations = aliasedTargetSymbol.getDeclarations();
|
|
153
|
-
if (!declarations
|
|
154
|
-
|
|
155
|
-
|
|
154
|
+
if (!declarations || declarations.length < 1) {
|
|
155
|
+
throw new SdMetadataError(this._sourceFile.fileName, `'${identifier.text}'를 찾을 수 없습니다.`);
|
|
156
|
+
}
|
|
157
|
+
const moduleFilePaths = declarations
|
|
158
|
+
.filter((item) => (
|
|
159
|
+
this._hasParentsOrMe(item, (item1) => Boolean(item1.modifiers?.some((mod) => mod.kind === ts.SyntaxKind.ExportKeyword)))
|
|
160
|
+
))
|
|
161
|
+
.map((item) => PathUtil.posix(item.getSourceFile().fileName))
|
|
162
|
+
.distinct();
|
|
163
|
+
if (moduleFilePaths.length !== 1) {
|
|
164
|
+
throw new SdMetadataError(this._sourceFile.fileName, `'${identifier.text}'의 경로가 중복되었습니다.\n${moduleFilePaths.join("\n")}`);
|
|
165
|
+
}
|
|
156
166
|
|
|
157
167
|
const moduleFilePath = moduleFilePaths[0];
|
|
158
168
|
|
|
@@ -160,6 +170,18 @@ export class SdMyMetadataReader {
|
|
|
160
170
|
}
|
|
161
171
|
}
|
|
162
172
|
|
|
173
|
+
private _hasParentsOrMe(node: ts.Node, fn: (node1: ts.Node) => boolean): boolean {
|
|
174
|
+
let currNode = node as ts.Node | undefined;
|
|
175
|
+
while (true) {
|
|
176
|
+
if (!currNode) return false;
|
|
177
|
+
|
|
178
|
+
const result = fn(currNode);
|
|
179
|
+
if (result) return true;
|
|
180
|
+
|
|
181
|
+
currNode = currNode.parent as ts.Node | undefined;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
163
185
|
private _getNgModuleDecoratorParam(decExp: ts.CallExpression): { exports: IMyModuleImport[]; providers: IMyModuleImport[] } {
|
|
164
186
|
const result: { exports: IMyModuleImport[]; providers: IMyModuleImport[] } = {
|
|
165
187
|
exports: [],
|