@simplysm/sd-cli 12.8.18 → 12.8.21

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 (37) hide show
  1. package/dist/entry/sd-cli-cordova.d.ts +30 -0
  2. package/dist/entry/sd-cli-cordova.js +309 -249
  3. package/dist/entry/sd-cli-cordova.js.map +1 -1
  4. package/dist/entry/sd-cli-project.d.ts +1 -1
  5. package/dist/entry/sd-cli-project.js +8 -9
  6. package/dist/entry/sd-cli-project.js.map +1 -1
  7. package/dist/index.d.ts +1 -0
  8. package/dist/index.js +1 -0
  9. package/dist/index.js.map +1 -1
  10. package/dist/pkg-builders/client/sd-ng.bundler.d.ts +15 -1
  11. package/dist/pkg-builders/client/sd-ng.bundler.js +60 -70
  12. package/dist/pkg-builders/client/sd-ng.bundler.js.map +1 -1
  13. package/dist/pkg-builders/client/sd-ng.plugin-creator.js +49 -29
  14. package/dist/pkg-builders/client/sd-ng.plugin-creator.js.map +1 -1
  15. package/dist/pkg-builders/lib/sd-ts-lib.builder.js +7 -4
  16. package/dist/pkg-builders/lib/sd-ts-lib.builder.js.map +1 -1
  17. package/dist/ts-compiler/sd-ts-compiler.d.ts +24 -2
  18. package/dist/ts-compiler/sd-ts-compiler.js +267 -575
  19. package/dist/ts-compiler/sd-ts-compiler.js.map +1 -1
  20. package/dist/ts-compiler/sd-ts-dependency-analyzer.d.ts +10 -0
  21. package/dist/ts-compiler/sd-ts-dependency-analyzer.js +140 -0
  22. package/dist/ts-compiler/sd-ts-dependency-analyzer.js.map +1 -0
  23. package/dist/types/ts-compiler.types.d.ts +12 -7
  24. package/dist/types/worker.types.d.ts +13 -0
  25. package/dist/utils/sd-cli-performance-time.js +1 -1
  26. package/package.json +10 -12
  27. package/src/entry/sd-cli-cordova.ts +394 -281
  28. package/src/entry/sd-cli-project.ts +11 -23
  29. package/src/index.ts +1 -0
  30. package/src/pkg-builders/client/sd-ng.bundler.ts +70 -69
  31. package/src/pkg-builders/client/sd-ng.plugin-creator.ts +47 -27
  32. package/src/pkg-builders/lib/sd-ts-lib.builder.ts +14 -7
  33. package/src/ts-compiler/sd-ts-compiler.ts +334 -705
  34. package/src/ts-compiler/sd-ts-dependency-analyzer.ts +176 -0
  35. package/src/types/ts-compiler.types.ts +11 -6
  36. package/src/types/worker.types.ts +7 -6
  37. package/src/utils/sd-cli-performance-time.ts +1 -1
@@ -0,0 +1,176 @@
1
+ import * as ts from "typescript";
2
+ import { PathUtils, TNormPath } from "@simplysm/sd-core-node";
3
+ import { ISdBuildMessage } from "../types/build.types";
4
+ import * as module from "node:module";
5
+ import path from "path";
6
+
7
+ export class SdTsDependencyAnalyzer {
8
+ static analyze(
9
+ program: ts.Program,
10
+ compilerHost: ts.CompilerHost,
11
+ scopePaths: TNormPath[],
12
+ ) {
13
+ const compilerOpts = program.getCompilerOptions();
14
+ const allDepMap = new Map<TNormPath, Set<TNormPath>>();
15
+ const visited = new Set<TNormPath>();
16
+ const messages: ISdBuildMessage[] = [];
17
+
18
+ const getOrgSourceFile = (sf: ts.SourceFile) => {
19
+ if (sf.fileName.endsWith(".ngtypecheck.ts")) {
20
+ const orgFileName = sf.fileName.slice(0, -15) + ".ts";
21
+ return program.getSourceFile(orgFileName);
22
+ }
23
+
24
+ return sf;
25
+ };
26
+
27
+ const inScope = (filePath: string): boolean => {
28
+ return scopePaths.some((scope) => PathUtils.isChildPath(filePath, scope));
29
+ };
30
+
31
+ const resolveModule = (text: string, base: string): {
32
+ resolvedFileName: string,
33
+ isFallback: boolean
34
+ } | undefined => {
35
+ const res = ts.resolveModuleName(text, base, compilerOpts, compilerHost);
36
+ if (res.resolvedModule) {
37
+ return { resolvedFileName: res.resolvedModule.resolvedFileName, isFallback: false };
38
+ }
39
+
40
+ const absPath = path.resolve(path.dirname(base), text);
41
+ if (compilerHost.fileExists(absPath)) {
42
+ return { resolvedFileName: absPath, isFallback: true };
43
+ }
44
+
45
+ return undefined;
46
+ };
47
+
48
+ const error = (sf: ts.SourceFile, node: ts.Node, msg: string) => {
49
+ try {
50
+ const pos = ts.getLineAndCharacterOfPosition(sf, node.getStart());
51
+ messages.push({
52
+ filePath: PathUtils.norm(sf.fileName),
53
+ line: pos.line,
54
+ char: pos.character,
55
+ code: undefined,
56
+ severity: "error",
57
+ message: msg,
58
+ type: "deps",
59
+ });
60
+ }
61
+ catch {
62
+ messages.push({
63
+ filePath: PathUtils.norm(sf.fileName),
64
+ line: 0,
65
+ char: 0,
66
+ code: undefined,
67
+ severity: "error",
68
+ message: `${msg} (pos unknown)`,
69
+ type: "deps",
70
+ });
71
+ }
72
+ };
73
+
74
+ const collectDeps = (sf: ts.SourceFile, fromFile: TNormPath) => {
75
+ if (allDepMap.has(fromFile)) return;
76
+ const deps = new Set<TNormPath>();
77
+
78
+ const pushDep = (raw: string, node: ts.Node) => {
79
+ if (module.builtinModules.includes(raw.replace(/^node:/, ""))) return;
80
+
81
+ const resolved = resolveModule(raw, sf.fileName);
82
+ if (!resolved) {
83
+ error(sf, node, `파일 "${sf.fileName}"에서 "${raw}" 모듈을 해석할 수 없습니다.`);
84
+ return;
85
+ }
86
+
87
+ if (!inScope(resolved.resolvedFileName)) return;
88
+
89
+ const norm = PathUtils.norm(resolved.resolvedFileName);
90
+ deps.add(norm);
91
+
92
+ if (!visited.has(norm) && !resolved.isFallback) {
93
+ visited.add(norm);
94
+ const targetSf = program.getSourceFile(norm);
95
+ if (!targetSf) {
96
+ error(
97
+ sf,
98
+ node,
99
+ `모듈 "${raw}"은(는) "${resolved}" 파일로 해석되었으나, 해당 파일의 ts.SourceFile이 없습니다.`,
100
+ );
101
+ return;
102
+ }
103
+
104
+ collectDeps(targetSf, norm);
105
+ }
106
+ };
107
+
108
+ const visit = (node: ts.Node) => {
109
+ if (ts.isImportDeclaration(node) || ts.isExportDeclaration(node)) {
110
+ const spec = node.moduleSpecifier;
111
+ if (spec && ts.isStringLiteral(spec)) pushDep(spec.text, node);
112
+ }
113
+ else if (
114
+ ts.isCallExpression(node) &&
115
+ node.expression.kind === ts.SyntaxKind.ImportKeyword &&
116
+ ts.isStringLiteral(node.arguments[0])
117
+ ) {
118
+ pushDep(node.arguments[0].text, node);
119
+ }
120
+ else if (
121
+ ts.isCallExpression(node) &&
122
+ ts.isIdentifier(node.expression) &&
123
+ node.expression.text === "require" &&
124
+ node.arguments.length === 1 &&
125
+ ts.isStringLiteral(node.arguments[0])
126
+ ) {
127
+ pushDep(node.arguments[0].text, node);
128
+ }
129
+ else if (
130
+ ts.isCallExpression(node) &&
131
+ ts.isPropertyAccessExpression(node.expression) &&
132
+ ts.isIdentifier(node.expression.expression) &&
133
+ node.expression.expression.text === "require" &&
134
+ node.expression.name.text === "resolve" &&
135
+ node.arguments.length === 1 &&
136
+ ts.isStringLiteral(node.arguments[0])
137
+ ) {
138
+ pushDep(node.arguments[0].text, node);
139
+ }
140
+ else if (
141
+ ts.isCallExpression(node) &&
142
+ ts.isPropertyAccessExpression(node.expression) &&
143
+ ts.isMetaProperty(node.expression.expression) &&
144
+ node.expression.expression.keywordToken === ts.SyntaxKind.ImportKeyword &&
145
+ node.expression.name.text === "meta" &&
146
+ node.arguments.length === 1 &&
147
+ ts.isStringLiteral(node.arguments[0])
148
+ ) {
149
+ pushDep(node.arguments[0].text, node);
150
+ }
151
+ ts.forEachChild(node, visit);
152
+ };
153
+
154
+ ts.forEachChild(sf, visit);
155
+ allDepMap.set(fromFile, deps);
156
+ };
157
+
158
+ const sourceFileSet = new Set(
159
+ program.getSourceFiles()
160
+ .map((sf) => getOrgSourceFile(sf))
161
+ .filterExists()
162
+ );
163
+
164
+ for (const sf of sourceFileSet) {
165
+ if (!inScope(sf.fileName)) continue;
166
+ const normFile = PathUtils.norm(sf.fileName);
167
+ collectDeps(sf, normFile);
168
+ }
169
+
170
+ return {
171
+ allDepMap,
172
+ sourceFileSet,
173
+ messages,
174
+ };
175
+ }
176
+ }
@@ -18,16 +18,21 @@ export interface SdTsCompilerOptions {
18
18
 
19
19
  export interface ISdTsCompilerResult {
20
20
  messages: ISdBuildMessage[];
21
- stylesheetBundlingResultMap: Map<TNormPath, IStylesheetBundlingResult>;
21
+ stylesheetBundlingResultMap: Map<TNormPath, TStylesheetBundlingResult>;
22
22
  emittedFilesCacheMap: Map<TNormPath, { outAbsPath?: TNormPath; text: string }[]>;
23
23
  emitFileSet: Set<TNormPath>;
24
24
  watchFileSet: Set<TNormPath>;
25
25
  affectedFileSet: Set<TNormPath>;
26
26
  }
27
27
 
28
- export interface IStylesheetBundlingResult {
29
- outputFiles?: esbuild.OutputFile[];
30
- metafile?: esbuild.Metafile;
31
- errors?: esbuild.Message[];
32
- warnings?: esbuild.Message[];
28
+ export type TStylesheetBundlingResult = {
29
+ errors: esbuild.PartialMessage[];
30
+ warnings: esbuild.PartialMessage[];
31
+ contents?: string;
32
+ } | {
33
+ errors: undefined;
34
+ warnings: esbuild.PartialMessage[];
35
+ metafile: esbuild.Metafile;
36
+ outputFiles: esbuild.OutputFile[];
37
+ contents: string;
33
38
  }
@@ -1,5 +1,6 @@
1
1
  import { ISdBuildRunnerWorkerRequest } from "./build-runner.types";
2
2
  import { ISdBuildMessage, ISdBuildRunnerResult } from "./build.types";
3
+ import { ESLint } from "eslint";
3
4
 
4
5
  export interface TServerWorkerType {
5
6
  methods: {
@@ -10,12 +11,12 @@ export interface TServerWorkerType {
10
11
  events: {};
11
12
  }
12
13
 
13
- // export interface TSdLintWorkerType {
14
- // methods: {
15
- // lint: { params: [{ cwd: string; fileSet: Set<string> }]; returnType: ESLint.LintResult[] };
16
- // };
17
- // events: {};
18
- // }
14
+ export interface TSdLintWorkerType {
15
+ methods: {
16
+ lint: { params: [{ cwd: string; fileSet: Set<string> }]; returnType: ESLint.LintResult[] };
17
+ };
18
+ events: {};
19
+ }
19
20
 
20
21
  // export interface TSdTsCompileWorkerType {
21
22
  // methods: {
@@ -32,7 +32,7 @@ export class SdCliPerformanceTimer {
32
32
  }
33
33
 
34
34
  toString() {
35
- return `${this._name} performance report
35
+ return `${this._name} 성능 보고서
36
36
  ------------------------------------
37
37
  ${Array.from(this.#resultMap.entries())
38
38
  .map((en) => `${en[0]}: ${en[1].toLocaleString()}ms`)