@simplysm/sd-cli 12.8.22 → 12.9.1

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 (95) hide show
  1. package/dist/entry/sd-cli-ai-command.js +2 -1
  2. package/dist/entry/sd-cli-ai-command.js.map +1 -1
  3. package/dist/entry/sd-cli-cordova.d.ts +1 -1
  4. package/dist/entry/sd-cli-cordova.js +1 -1
  5. package/dist/entry/sd-cli-cordova.js.map +1 -1
  6. package/dist/entry/sd-cli-electron.d.ts +6 -6
  7. package/dist/entry/sd-cli-electron.js +15 -9
  8. package/dist/entry/sd-cli-electron.js.map +1 -1
  9. package/dist/entry/sd-cli-local-update.d.ts +5 -5
  10. package/dist/entry/sd-cli-local-update.js +8 -12
  11. package/dist/entry/sd-cli-local-update.js.map +1 -1
  12. package/dist/entry/sd-cli-project.d.ts +11 -11
  13. package/dist/entry/sd-cli-project.js +11 -14
  14. package/dist/entry/sd-cli-project.js.map +1 -1
  15. package/dist/entry/utils/loadProjConfAsync.d.ts +5 -0
  16. package/dist/entry/utils/loadProjConfAsync.js +8 -0
  17. package/dist/entry/utils/loadProjConfAsync.js.map +1 -0
  18. package/dist/pkg-builders/client/sd-client.build-runner.js +1 -1
  19. package/dist/pkg-builders/client/sd-client.build-runner.js.map +1 -1
  20. package/dist/pkg-builders/client/sd-ng.bundler-context.d.ts +6 -5
  21. package/dist/pkg-builders/client/sd-ng.bundler-context.js +6 -6
  22. package/dist/pkg-builders/client/sd-ng.bundler-context.js.map +1 -1
  23. package/dist/pkg-builders/client/sd-ng.bundler.d.ts +13 -13
  24. package/dist/pkg-builders/client/sd-ng.bundler.js.map +1 -1
  25. package/dist/pkg-builders/client/sd-ng.plugin-creator.js +4 -88
  26. package/dist/pkg-builders/client/sd-ng.plugin-creator.js.map +1 -1
  27. package/dist/pkg-builders/lib/sd-js-lib.build-runner.js.map +1 -1
  28. package/dist/pkg-builders/lib/sd-ts-lib.build-runner.d.ts +1 -1
  29. package/dist/pkg-builders/lib/sd-ts-lib.build-runner.js.map +1 -1
  30. package/dist/pkg-builders/lib/sd-ts-lib.builder.js.map +1 -1
  31. package/dist/pkg-builders/sd-multi.build-runner.d.ts +4 -0
  32. package/dist/pkg-builders/sd-multi.build-runner.js +33 -25
  33. package/dist/pkg-builders/sd-multi.build-runner.js.map +1 -1
  34. package/dist/pkg-builders/server/sd-server.build-runner.js.map +1 -1
  35. package/dist/pkg-builders/server/sd-server.bundler.d.ts +6 -2
  36. package/dist/pkg-builders/server/sd-server.bundler.js +18 -19
  37. package/dist/pkg-builders/server/sd-server.bundler.js.map +1 -1
  38. package/dist/sd-cli/vitest.config.d.ts +2 -0
  39. package/dist/sd-cli/vitest.config.js +15 -0
  40. package/dist/sd-cli/vitest.config.js.map +1 -0
  41. package/dist/sd-cli.js +7 -36
  42. package/dist/sd-cli.js.map +1 -1
  43. package/dist/ts-compiler/sd-dependency-analyzer.d.ts +8 -0
  44. package/dist/ts-compiler/sd-dependency-analyzer.js +244 -0
  45. package/dist/ts-compiler/sd-dependency-analyzer.js.map +1 -0
  46. package/dist/ts-compiler/sd-dependency-cache.d.ts +27 -0
  47. package/dist/ts-compiler/sd-dependency-cache.js +232 -0
  48. package/dist/ts-compiler/sd-dependency-cache.js.map +1 -0
  49. package/dist/ts-compiler/sd-ts-compiler.d.ts +7 -10
  50. package/dist/ts-compiler/sd-ts-compiler.js +102 -228
  51. package/dist/ts-compiler/sd-ts-compiler.js.map +1 -1
  52. package/dist/types/worker.types.d.ts +19 -0
  53. package/dist/utils/sd-cli-performance-time.d.ts +2 -1
  54. package/dist/utils/sd-cli-performance-time.js +9 -9
  55. package/dist/utils/sd-cli-performance-time.js.map +1 -1
  56. package/dist/workers/style-bundler.worker.d.ts +1 -0
  57. package/dist/workers/style-bundler.worker.js +56 -0
  58. package/dist/workers/style-bundler.worker.js.map +1 -0
  59. package/package.json +10 -10
  60. package/src/entry/sd-cli-ai-command.ts +2 -1
  61. package/src/entry/sd-cli-cordova.ts +5 -5
  62. package/src/entry/sd-cli-electron.ts +54 -23
  63. package/src/entry/sd-cli-local-update.ts +14 -29
  64. package/src/entry/sd-cli-project.ts +24 -41
  65. package/src/entry/utils/loadProjConfAsync.ts +12 -0
  66. package/src/pkg-builders/client/sd-client.build-runner.ts +7 -7
  67. package/src/pkg-builders/client/sd-ng.bundler-context.ts +15 -12
  68. package/src/pkg-builders/client/sd-ng.bundler.ts +16 -16
  69. package/src/pkg-builders/client/sd-ng.plugin-creator.ts +5 -94
  70. package/src/pkg-builders/lib/sd-js-lib.build-runner.ts +6 -6
  71. package/src/pkg-builders/lib/sd-ts-lib.build-runner.ts +7 -7
  72. package/src/pkg-builders/lib/sd-ts-lib.builder.ts +1 -1
  73. package/src/pkg-builders/sd-multi.build-runner.ts +54 -39
  74. package/src/pkg-builders/server/sd-server.build-runner.ts +6 -6
  75. package/src/pkg-builders/server/sd-server.bundler.ts +26 -28
  76. package/src/sd-cli.ts +7 -36
  77. package/src/ts-compiler/sd-dependency-analyzer.ts +312 -0
  78. package/src/ts-compiler/sd-dependency-cache.ts +328 -0
  79. package/src/ts-compiler/sd-ts-compiler.ts +161 -302
  80. package/src/types/worker.types.ts +17 -0
  81. package/src/utils/sd-cli-performance-time.ts +9 -9
  82. package/src/workers/style-bundler.worker.ts +70 -0
  83. package/tests/deps/sd-dependency-analyzer.spec.ts +272 -0
  84. package/tests/deps/sd-dependency-cache.spec.ts +144 -0
  85. package/tsconfig.json +1 -1
  86. package/tsconfig.test.json +8 -0
  87. package/vitest.config.ts +15 -0
  88. package/dist/index.d.ts +0 -34
  89. package/dist/index.js +0 -35
  90. package/dist/index.js.map +0 -1
  91. package/dist/ts-compiler/sd-ts-dependency-analyzer.d.ts +0 -6
  92. package/dist/ts-compiler/sd-ts-dependency-analyzer.js +0 -141
  93. package/dist/ts-compiler/sd-ts-dependency-analyzer.js.map +0 -1
  94. package/src/index.ts +0 -34
  95. package/src/ts-compiler/sd-ts-dependency-analyzer.ts +0 -185
@@ -13,24 +13,22 @@ import { convertOutputFile } from "@angular/build/src/tools/esbuild/utils";
13
13
  import { resolveAssets } from "@angular/build/src/utils/resolve-assets";
14
14
 
15
15
  export class SdServerBundler {
16
- readonly #logger = SdLogger.get(["simplysm", "sd-cli", "SdServerBundler"]);
16
+ private _logger = SdLogger.get(["simplysm", "sd-cli", "SdServerBundler"]);
17
17
 
18
- #context?: esbuild.BuildContext;
18
+ private _context?: esbuild.BuildContext;
19
19
 
20
- readonly #modifiedFileSet = new Set<TNormPath>();
21
- readonly #resultCache: ISdCliServerPluginResultCache = {};
20
+ private _modifiedFileSet = new Set<TNormPath>();
21
+ private _resultCache: ISdCliServerPluginResultCache = {};
22
22
 
23
- readonly #outputHashCache = new Map<TNormPath, string>();
23
+ private _outputHashCache = new Map<TNormPath, string>();
24
24
 
25
- constructor(
26
- private readonly _opt: {
27
- dev: boolean;
28
- pkgPath: TNormPath;
29
- entryPoints: string[];
30
- external?: string[];
31
- watchScopePaths: TNormPath[];
32
- },
33
- ) {
25
+ constructor(private _opt: {
26
+ dev: boolean;
27
+ pkgPath: TNormPath;
28
+ entryPoints: string[];
29
+ external?: string[];
30
+ watchScopePaths: TNormPath[];
31
+ }) {
34
32
  }
35
33
 
36
34
  async bundleAsync(modifiedFileSet?: Set<TNormPath>): Promise<{
@@ -39,13 +37,13 @@ export class SdServerBundler {
39
37
  results: ISdBuildMessage[];
40
38
  emitFileSet: Set<TNormPath>;
41
39
  }> {
42
- this.#modifiedFileSet.clear();
40
+ this._modifiedFileSet.clear();
43
41
  if (modifiedFileSet) {
44
- this.#modifiedFileSet.adds(...modifiedFileSet);
42
+ this._modifiedFileSet.adds(...modifiedFileSet);
45
43
  }
46
44
 
47
- if (!this.#context) {
48
- this.#context = await esbuild.context({
45
+ if (!this._context) {
46
+ this._context = await esbuild.context({
49
47
  entryPoints: this._opt.entryPoints,
50
48
  keepNames: true,
51
49
  bundle: true,
@@ -106,10 +104,10 @@ const __dirname = __path__.dirname(__filename);`.trim(),
106
104
  },
107
105
  plugins: [
108
106
  createSdServerPlugin({
109
- modifiedFileSet: this.#modifiedFileSet,
107
+ modifiedFileSet: this._modifiedFileSet,
110
108
  dev: this._opt.dev,
111
109
  pkgPath: this._opt.pkgPath,
112
- result: this.#resultCache,
110
+ result: this._resultCache,
113
111
  watchScopePaths: this._opt.watchScopePaths,
114
112
  }),
115
113
  ],
@@ -119,18 +117,18 @@ const __dirname = __path__.dirname(__filename);`.trim(),
119
117
  const emitFileSet = new Set<TNormPath>();
120
118
  let result: esbuild.BuildResult | esbuild.BuildFailure;
121
119
  try {
122
- result = await this.#context.rebuild();
120
+ result = await this._context.rebuild();
123
121
 
124
122
  const outputFiles: BuildOutputFile[] =
125
123
  result.outputFiles?.map((file) => convertOutputFile(file, BuildOutputFileType.Root)) ?? [];
126
124
 
127
125
  for (const outputFile of outputFiles) {
128
126
  const distFilePath = PathUtils.norm(this._opt.pkgPath, outputFile.path);
129
- const prevHash = this.#outputHashCache.get(distFilePath);
127
+ const prevHash = this._outputHashCache.get(distFilePath);
130
128
  const currHash = HashUtils.get(outputFile.contents);
131
129
  if (prevHash !== currHash) {
132
130
  FsUtils.writeFile(distFilePath, outputFile.contents);
133
- this.#outputHashCache.set(distFilePath, currHash);
131
+ this._outputHashCache.set(distFilePath, currHash);
134
132
  emitFileSet.add(distFilePath);
135
133
  }
136
134
  }
@@ -145,14 +143,14 @@ const __dirname = __path__.dirname(__filename);`.trim(),
145
143
  );
146
144
 
147
145
  for (const assetFile of assetFiles) {
148
- const prevHash = this.#outputHashCache.get(PathUtils.norm(assetFile.source));
146
+ const prevHash = this._outputHashCache.get(PathUtils.norm(assetFile.source));
149
147
  const currHash = FsUtils.hash(assetFile.source);
150
148
  if (prevHash !== currHash) {
151
149
  FsUtils.copy(
152
150
  assetFile.source,
153
151
  path.resolve(this._opt.pkgPath, "dist", assetFile.destination),
154
152
  );
155
- this.#outputHashCache.set(PathUtils.norm(assetFile.source), currHash);
153
+ this._outputHashCache.set(PathUtils.norm(assetFile.source), currHash);
156
154
  emitFileSet.add(PathUtils.norm(assetFile.destination));
157
155
  }
158
156
  }
@@ -161,14 +159,14 @@ const __dirname = __path__.dirname(__filename);`.trim(),
161
159
  result = err;
162
160
  for (const e of err.errors) {
163
161
  if (e.detail != null) {
164
- this.#logger.error(e.detail);
162
+ this._logger.error(e.detail);
165
163
  }
166
164
  }
167
165
  }
168
166
 
169
167
  return {
170
- watchFileSet: this.#resultCache.watchFileSet!,
171
- affectedFileSet: this.#resultCache.affectedFileSet!,
168
+ watchFileSet: this._resultCache.watchFileSet!,
169
+ affectedFileSet: this._resultCache.affectedFileSet!,
172
170
  results: SdCliConvertMessageUtils.convertToBuildMessagesFromEsbuild(
173
171
  result,
174
172
  this._opt.pkgPath,
package/src/sd-cli.ts CHANGED
@@ -201,54 +201,25 @@ else {
201
201
  }
202
202
 
203
203
  if (argv._[0] === "local-update") {
204
- await SdCliLocalUpdate.runAsync({
205
- confFileRelPath: argv.config ?? "simplysm.js",
206
- optNames: argv.options ?? [],
207
- });
204
+ await SdCliLocalUpdate.runAsync(argv);
208
205
  }
209
206
  else if (argv._[0] === "watch") {
210
- await SdCliProject.watchAsync({
211
- confFileRelPath: argv.config ?? "simplysm.js",
212
- optNames: argv.options ?? [],
213
- pkgNames: argv.packages ?? [],
214
- inspectNames: argv.inspects ?? [],
215
- });
207
+ await SdCliProject.watchAsync(argv);
216
208
  }
217
209
  else if (argv._[0] === "build") {
218
- await SdCliProject.buildAsync({
219
- confFileRelPath: argv.config ?? "simplysm.js",
220
- optNames: argv.options ?? [],
221
- pkgNames: argv.packages ?? [],
222
- });
210
+ await SdCliProject.buildAsync(argv);
223
211
  }
224
212
  else if (argv._[0] === "publish") {
225
- await SdCliProject.publishAsync({
226
- noBuild: argv.noBuild,
227
- confFileRelPath: argv.config ?? "simplysm.js",
228
- optNames: argv.options ?? [],
229
- pkgNames: argv.packages ?? [],
230
- });
213
+ await SdCliProject.publishAsync(argv);
231
214
  }
232
215
  else if (argv._[0] === "run-electron") {
233
- await SdCliElectron.runAsync({
234
- confFileRelPath: argv.config ?? "simplysm.js",
235
- optNames: argv.options ?? [],
236
- pkgName: argv.package,
237
- });
216
+ await SdCliElectron.runAsync(argv);
238
217
  }
239
218
  else if (argv._[0] === "build-electron-for-dev") {
240
- await SdCliElectron.buildForDevAsync({
241
- confFileRelPath: argv.config ?? "simplysm.js",
242
- optNames: argv.options ?? [],
243
- pkgName: argv.package,
244
- });
219
+ await SdCliElectron.buildForDevAsync(argv);
245
220
  }
246
221
  else if (argv._[0] === "run-cordova") {
247
- await SdCliCordova.runWebviewOnDeviceAsync({
248
- platform: argv.platform,
249
- pkgName: argv.package,
250
- url: argv.url,
251
- });
222
+ await SdCliCordova.runWebviewOnDeviceAsync(argv);
252
223
  }
253
224
  else if (argv._[0] === "commit") {
254
225
  await SdCliAiCommand.commitAsync();
@@ -0,0 +1,312 @@
1
+ import ts from "typescript";
2
+ import { SdDependencyCache } from "./sd-dependency-cache";
3
+ import { PathUtils, TNormPath } from "@simplysm/sd-core-node";
4
+ import path from "path";
5
+ import { NgtscProgram } from "@angular/compiler-cli";
6
+
7
+ export class SdDependencyAnalyzer {
8
+ static analyze(
9
+ program: ts.Program,
10
+ compilerHost: ts.CompilerHost,
11
+ scopePaths: TNormPath[],
12
+ depCache: SdDependencyCache,
13
+ ): void {
14
+ const compilerOpts = program.getCompilerOptions();
15
+ const typeChecker = program.getTypeChecker();
16
+
17
+ const inScope = (filePath: string): boolean => {
18
+ return scopePaths.some((scope) => PathUtils.isChildPath(filePath, scope));
19
+ };
20
+
21
+ const resolveModule = (text: string, base: string): TNormPath[] => {
22
+ const res = ts.resolveModuleName(
23
+ text,
24
+ base,
25
+ compilerOpts,
26
+ compilerHost,
27
+ );
28
+
29
+ if (res.resolvedModule) {
30
+ return [
31
+ PathUtils.norm(res.resolvedModule.resolvedFileName),
32
+ ];
33
+ }
34
+
35
+ const absPath = path.resolve(path.dirname(base), text);
36
+ if (!inScope(absPath)) {
37
+ return [];
38
+ }
39
+ else if (
40
+ // 지원되게할 .png등이면 그냥 가져오고 (bundling loader에 들어가는것들과 .ts, .json등)
41
+ // fallback일때는 absPath에 .ts, .d.ts, .js, .json 등 다붙여서 가져와야함
42
+ [
43
+ ".ts",
44
+ ".d.ts",
45
+ ".js",
46
+ ".json",
47
+
48
+ ".html",
49
+ ".scss",
50
+ ".css",
51
+
52
+ ".png",
53
+ ".jpeg",
54
+ ".jpg",
55
+ ".jfif",
56
+ ".gif",
57
+ ".svg",
58
+ ".woff",
59
+ ".woff2",
60
+ ".ttf",
61
+ ".ttc",
62
+ ".eot",
63
+ ".ico",
64
+ ".otf",
65
+ ".csv",
66
+ ".xlsx",
67
+ ".xls",
68
+ ".pptx",
69
+ ".ppt",
70
+ ".docx",
71
+ ".doc",
72
+ ".zip",
73
+ ".pfx",
74
+ ".pkl",
75
+ ".mp3",
76
+ ".ogg",
77
+ ].some(ext => absPath.endsWith(ext))
78
+ ) {
79
+ return [
80
+ PathUtils.norm(absPath),
81
+ ];
82
+ }
83
+ else {
84
+ return [
85
+ PathUtils.norm(absPath + ".ts"),
86
+ PathUtils.norm(absPath + ".js"),
87
+ PathUtils.norm(absPath + ".d.ts"),
88
+ PathUtils.norm(absPath + ".json"),
89
+ ];
90
+ }
91
+ };
92
+
93
+ const isInImportOrExport = (node: ts.Node) => {
94
+ let curr = node as ts.Node | undefined;
95
+ while (curr) {
96
+ if (
97
+ ts.isImportDeclaration(curr) ||
98
+ ts.isExportDeclaration(curr) ||
99
+ ts.isImportSpecifier(curr) ||
100
+ ts.isExportSpecifier(curr) ||
101
+ ts.isNamespaceImport(curr)
102
+ ) {
103
+ return true;
104
+ }
105
+ curr = curr.parent;
106
+ }
107
+ return false;
108
+ };
109
+
110
+ const typeCache = new WeakMap<ts.Node, ts.Type>();
111
+
112
+ const getCachedType = (node: ts.Node) => {
113
+ if (typeCache.has(node)) return typeCache.get(node);
114
+ const type = typeChecker.getTypeAtLocation(node) as ts.Type | undefined;
115
+ if (type) typeCache.set(node, type);
116
+ return type;
117
+ };
118
+
119
+ const collectDeps = (sf: ts.SourceFile) => {
120
+ const sfNPath = PathUtils.norm(sf.fileName);
121
+ if (depCache.hasCollected(sfNPath)) return;
122
+ depCache.addCollected(sfNPath);
123
+
124
+ const visit = (node: ts.Node) => {
125
+ // --- import ... from '...'
126
+ if (
127
+ ts.isImportDeclaration(node) &&
128
+ ts.isStringLiteral(node.moduleSpecifier)
129
+ ) {
130
+ const resolvedNPaths = resolveModule(node.moduleSpecifier.text, sf.fileName);
131
+ for (const resolvedNPath of resolvedNPaths) {
132
+ if (
133
+ node.importClause &&
134
+ node.importClause.namedBindings &&
135
+ ts.isNamedImports(node.importClause.namedBindings)
136
+ ) {
137
+ for (const element of node.importClause.namedBindings.elements) {
138
+ depCache.addImport(
139
+ sfNPath,
140
+ resolvedNPath,
141
+ element.propertyName?.text ?? element.name.text,
142
+ );
143
+ }
144
+ }
145
+ else {
146
+ depCache.addImport(sfNPath, resolvedNPath, 0);
147
+ }
148
+ }
149
+ }
150
+
151
+ // --- export * from '...'
152
+ else if (
153
+ ts.isExportDeclaration(node) &&
154
+ !node.exportClause &&
155
+ node.moduleSpecifier &&
156
+ ts.isStringLiteral(node.moduleSpecifier)
157
+ ) {
158
+ const resolvedNPaths = resolveModule(node.moduleSpecifier.text, sf.fileName);
159
+ for (const resolvedNPath of resolvedNPaths) {
160
+ depCache.addReexport(sfNPath, resolvedNPath, 0);
161
+ }
162
+ }
163
+
164
+ // --- export { A as B } from '...'
165
+ if (
166
+ ts.isExportDeclaration(node) &&
167
+ node.exportClause &&
168
+ ts.isNamedExports(node.exportClause) &&
169
+ node.moduleSpecifier &&
170
+ ts.isStringLiteral(node.moduleSpecifier)
171
+ ) {
172
+ const resolvedNPaths = resolveModule(node.moduleSpecifier.text, sf.fileName);
173
+ for (const resolvedNPath of resolvedNPaths) {
174
+ for (const element of node.exportClause.elements) {
175
+ const local = element.propertyName?.text ?? element.name.text;
176
+ const exported = element.name.text;
177
+ depCache.addReexport(sfNPath, resolvedNPath, {
178
+ importSymbol: local,
179
+ exportSymbol: exported,
180
+ });
181
+ }
182
+ }
183
+ }
184
+
185
+ // --- export const A = ...
186
+ else if (
187
+ ts.isVariableStatement(node) &&
188
+ node.modifiers?.some(mod => mod.kind === ts.SyntaxKind.ExportKeyword)
189
+ ) {
190
+ for (const decl of node.declarationList.declarations) {
191
+ if (ts.isIdentifier(decl.name)) {
192
+ depCache.addExport(sfNPath, decl.name.text);
193
+ }
194
+ }
195
+ }
196
+
197
+ // --- export function/class/interface A ...
198
+ else if (
199
+ (
200
+ ts.isFunctionDeclaration(node) ||
201
+ ts.isClassDeclaration(node) ||
202
+ ts.isInterfaceDeclaration(node) ||
203
+ ts.isTypeAliasDeclaration(node) ||
204
+ ts.isEnumDeclaration(node)
205
+ ) &&
206
+ node.modifiers?.some(mod => mod.kind === ts.SyntaxKind.ExportKeyword) &&
207
+ node.name
208
+ ) {
209
+ depCache.addExport(sfNPath, node.name.text);
210
+ }
211
+
212
+ else if (ts.isIdentifier(node) && !isInImportOrExport(node)) {
213
+ const orgValSymbol = typeChecker.getSymbolAtLocation(node);
214
+
215
+ // alias (import된 심볼)일 경우, 원본 심볼로 치환
216
+ const valSymbol = (orgValSymbol && (orgValSymbol.flags & ts.SymbolFlags.Alias))
217
+ ? typeChecker.getAliasedSymbol(orgValSymbol)
218
+ : undefined;
219
+
220
+ for (const decl of valSymbol?.getDeclarations() ?? []) {
221
+ const declFile = decl.getSourceFile();
222
+ const declNPath = PathUtils.norm(declFile.fileName);
223
+ if (declNPath !== sfNPath && inScope(declNPath)) {
224
+ depCache.addImport(sfNPath, declNPath, 0);
225
+ }
226
+ }
227
+ }
228
+ else if (
229
+ ts.isPropertyAccessExpression(node)
230
+ ) {
231
+ const type = getCachedType(node.expression);
232
+ const propSymbol = type?.getProperty(node.name.text);
233
+
234
+ if (propSymbol) {
235
+ for (const decl of propSymbol.getDeclarations() ?? []) {
236
+ const declFile = decl.getSourceFile();
237
+ const declNPath = PathUtils.norm(declFile.fileName);
238
+ if (declNPath !== sfNPath && inScope(declNPath)) {
239
+ depCache.addImport(sfNPath, declNPath, 0);
240
+ }
241
+ }
242
+ }
243
+ }
244
+ else if (
245
+ ts.isElementAccessExpression(node) &&
246
+ ts.isStringLiteral(node.argumentExpression)
247
+ ) {
248
+ const type = getCachedType(node.expression);
249
+ const propSymbol = type?.getProperty(node.argumentExpression.text);
250
+
251
+ if (propSymbol) {
252
+ for (const decl of propSymbol.getDeclarations() ?? []) {
253
+ const declFile = decl.getSourceFile();
254
+ const declNPath = PathUtils.norm(declFile.fileName);
255
+ if (declNPath !== sfNPath && inScope(declNPath)) {
256
+ depCache.addImport(sfNPath, declNPath, 0);
257
+ }
258
+ }
259
+ }
260
+ }
261
+
262
+ ts.forEachChild(node, visit);
263
+ };
264
+
265
+ ts.forEachChild(sf, visit);
266
+ };
267
+
268
+ const getOrgSourceFile = (sf: ts.SourceFile) => {
269
+ if (sf.fileName.endsWith(".ngtypecheck.ts")) {
270
+ const orgFileName = sf.fileName.slice(0, -15) + ".ts";
271
+ return program.getSourceFile(orgFileName);
272
+ }
273
+ return sf;
274
+ };
275
+
276
+ const sourceFileSet = new Set(
277
+ program.getSourceFiles()
278
+ .filter((sf) => inScope(sf.fileName))
279
+ .map((sf) => getOrgSourceFile(sf))
280
+ .filterExists(),
281
+ );
282
+
283
+ for (const sf of sourceFileSet) {
284
+ collectDeps(sf);
285
+ }
286
+ }
287
+
288
+
289
+ static analyzeAngularResources(
290
+ ngProgram: NgtscProgram,
291
+ scopePaths: TNormPath[],
292
+ depCache: SdDependencyCache,
293
+ ) {
294
+ const inScope = (filePath: string): boolean => {
295
+ return scopePaths.some((scope) => PathUtils.isChildPath(filePath, scope));
296
+ };
297
+
298
+ for (const sf of ngProgram.getTsProgram().getSourceFiles()) {
299
+ const fileNPath = PathUtils.norm(sf.fileName);
300
+ if (!inScope(fileNPath)) continue;
301
+
302
+ const dependencies = ngProgram.compiler.getResourceDependencies(sf);
303
+ for (const dep of dependencies) {
304
+ const depNPath = PathUtils.norm(dep);
305
+ if (!inScope(depNPath)) continue;
306
+
307
+ console.log(fileNPath, depNPath);
308
+ depCache.addImport(fileNPath, depNPath, 0);
309
+ }
310
+ }
311
+ }
312
+ }