@simplysm/sd-cli 13.0.75 → 13.0.77
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/README.md +341 -16
- package/dist/builders/DtsBuilder.js +2 -2
- package/dist/builders/DtsBuilder.js.map +1 -1
- package/dist/builders/LibraryBuilder.d.ts +3 -3
- package/dist/builders/LibraryBuilder.d.ts.map +1 -1
- package/dist/builders/LibraryBuilder.js +2 -2
- package/dist/builders/LibraryBuilder.js.map +1 -1
- package/dist/builders/types.d.ts +7 -1
- package/dist/builders/types.d.ts.map +1 -1
- package/dist/capacitor/capacitor.d.ts +5 -0
- package/dist/capacitor/capacitor.d.ts.map +1 -1
- package/dist/capacitor/capacitor.js +59 -59
- package/dist/capacitor/capacitor.js.map +1 -1
- package/dist/commands/check.js +4 -4
- package/dist/commands/check.js.map +1 -1
- package/dist/commands/device.js +3 -3
- package/dist/commands/device.js.map +1 -1
- package/dist/commands/lint.d.ts +2 -2
- package/dist/commands/lint.d.ts.map +1 -1
- package/dist/commands/lint.js +4 -98
- package/dist/commands/lint.js.map +1 -1
- package/dist/commands/publish.js +20 -20
- package/dist/commands/publish.js.map +1 -1
- package/dist/commands/replace-deps.js +1 -1
- package/dist/commands/replace-deps.js.map +1 -1
- package/dist/commands/typecheck.js +9 -9
- package/dist/commands/typecheck.js.map +1 -1
- package/dist/electron/electron.js +16 -16
- package/dist/electron/electron.js.map +1 -1
- package/dist/orchestrators/BuildOrchestrator.js +6 -6
- package/dist/orchestrators/BuildOrchestrator.js.map +1 -1
- package/dist/orchestrators/DevOrchestrator.d.ts +7 -6
- package/dist/orchestrators/DevOrchestrator.d.ts.map +1 -1
- package/dist/orchestrators/DevOrchestrator.js +157 -203
- package/dist/orchestrators/DevOrchestrator.js.map +1 -1
- package/dist/orchestrators/WatchOrchestrator.d.ts.map +1 -1
- package/dist/orchestrators/WatchOrchestrator.js +3 -4
- package/dist/orchestrators/WatchOrchestrator.js.map +1 -1
- package/dist/sd-cli.js +1 -1
- package/dist/sd-cli.js.map +1 -1
- package/dist/sd-config.types.d.ts +9 -3
- package/dist/sd-config.types.d.ts.map +1 -1
- package/dist/utils/copy-public.d.ts.map +1 -1
- package/dist/utils/copy-public.js +23 -27
- package/dist/utils/copy-public.js.map +1 -1
- package/dist/utils/copy-src.d.ts.map +1 -1
- package/dist/utils/copy-src.js +7 -7
- package/dist/utils/copy-src.js.map +1 -1
- package/dist/utils/esbuild-config.d.ts.map +1 -1
- package/dist/utils/esbuild-config.js +36 -42
- package/dist/utils/esbuild-config.js.map +1 -1
- package/dist/utils/replace-deps.js +7 -7
- package/dist/utils/replace-deps.js.map +1 -1
- package/dist/utils/sd-config.js +2 -2
- package/dist/utils/sd-config.js.map +1 -1
- package/dist/utils/template.js +7 -7
- package/dist/utils/template.js.map +1 -1
- package/dist/utils/tsconfig.d.ts +1 -2
- package/dist/utils/tsconfig.d.ts.map +1 -1
- package/dist/utils/tsconfig.js +5 -8
- package/dist/utils/tsconfig.js.map +1 -1
- package/dist/utils/typecheck-serialization.js +2 -2
- package/dist/utils/typecheck-serialization.js.map +1 -1
- package/dist/utils/vite-config.d.ts +2 -0
- package/dist/utils/vite-config.d.ts.map +1 -1
- package/dist/utils/vite-config.js +36 -3
- package/dist/utils/vite-config.js.map +1 -1
- package/dist/utils/worker-events.d.ts +11 -1
- package/dist/utils/worker-events.d.ts.map +1 -1
- package/dist/utils/worker-events.js +3 -5
- package/dist/utils/worker-events.js.map +1 -1
- package/dist/utils/worker-utils.d.ts +2 -2
- package/dist/utils/worker-utils.d.ts.map +1 -1
- package/dist/utils/worker-utils.js +1 -1
- package/dist/utils/worker-utils.js.map +1 -1
- package/dist/workers/client.worker.d.ts +1 -1
- package/dist/workers/client.worker.js +3 -3
- package/dist/workers/client.worker.js.map +1 -1
- package/dist/workers/dts.worker.d.ts +1 -1
- package/dist/workers/dts.worker.d.ts.map +1 -1
- package/dist/workers/dts.worker.js +13 -28
- package/dist/workers/dts.worker.js.map +1 -1
- package/dist/workers/library.worker.d.ts +1 -1
- package/dist/workers/library.worker.js +4 -4
- package/dist/workers/library.worker.js.map +1 -1
- package/dist/workers/lint.worker.d.ts +1 -1
- package/dist/workers/server-runtime.worker.d.ts +1 -1
- package/dist/workers/server-runtime.worker.js +4 -4
- package/dist/workers/server-runtime.worker.js.map +1 -1
- package/dist/workers/server.worker.d.ts +1 -1
- package/dist/workers/server.worker.js +6 -6
- package/dist/workers/server.worker.js.map +1 -1
- package/package.json +4 -5
- package/src/builders/DtsBuilder.ts +2 -2
- package/src/builders/LibraryBuilder.ts +7 -10
- package/src/builders/types.ts +6 -1
- package/src/capacitor/capacitor.ts +61 -60
- package/src/commands/check.ts +4 -4
- package/src/commands/device.ts +3 -3
- package/src/commands/lint.ts +6 -117
- package/src/commands/publish.ts +20 -20
- package/src/commands/replace-deps.ts +1 -1
- package/src/commands/typecheck.ts +9 -9
- package/src/electron/electron.ts +16 -16
- package/src/orchestrators/BuildOrchestrator.ts +6 -6
- package/src/orchestrators/DevOrchestrator.ts +210 -256
- package/src/orchestrators/WatchOrchestrator.ts +8 -10
- package/src/sd-cli.ts +1 -1
- package/src/sd-config.types.ts +10 -3
- package/src/utils/copy-public.ts +22 -26
- package/src/utils/copy-src.ts +7 -7
- package/src/utils/esbuild-config.ts +51 -63
- package/src/utils/replace-deps.ts +7 -7
- package/src/utils/sd-config.ts +2 -2
- package/src/utils/template.ts +7 -7
- package/src/utils/tsconfig.ts +6 -10
- package/src/utils/typecheck-serialization.ts +2 -2
- package/src/utils/vite-config.ts +376 -341
- package/src/utils/worker-events.ts +13 -10
- package/src/utils/worker-utils.ts +45 -45
- package/src/workers/client.worker.ts +3 -3
- package/src/workers/dts.worker.ts +451 -467
- package/src/workers/library.worker.ts +4 -4
- package/src/workers/server-runtime.worker.ts +4 -4
- package/src/workers/server.worker.ts +572 -572
- package/templates/init/package.json.hbs +2 -3
- package/templates/init/packages/client-admin/package.json.hbs +5 -5
- package/templates/init/packages/client-admin/src/views/auth/LoginView.tsx +2 -2
- package/templates/init/packages/client-admin/src/views/home/base/employee/EmployeeDetail.tsx.hbs +86 -105
- package/templates/init/packages/client-admin/src/views/home/base/employee/EmployeeSheet.tsx.hbs +1 -1
- package/templates/init/packages/client-admin/src/views/home/base/role-permission/RoleDetail.tsx.hbs +4 -12
- package/templates/init/packages/client-admin/src/views/home/base/role-permission/RolePermissionDetail.tsx.hbs +0 -2
- package/templates/init/packages/client-admin/src/views/home/base/role-permission/RolePermissionView.tsx +1 -1
- package/templates/init/packages/client-admin/src/views/home/base/role-permission/RoleSheet.tsx.hbs +1 -1
- package/templates/init/packages/client-admin/src/views/home/my-info/MyInfoDetail.tsx.hbs +36 -43
- package/templates/init/packages/db-main/package.json.hbs +2 -2
- package/templates/init/packages/server/package.json.hbs +4 -4
- package/templates/init/tests/e2e/package.json.hbs +1 -1
- package/tests/get-compiler-options-for-package.spec.ts +13 -72
- package/tests/get-package-source-files.spec.ts +0 -42
- package/tests/get-types-from-package-json.spec.ts +15 -30
- package/tests/infra/ResultCollector.spec.ts +0 -9
- package/tests/infra/WorkerManager.spec.ts +0 -34
- package/tests/load-ignore-patterns.spec.ts +15 -40
- package/tests/load-sd-config.spec.ts +16 -53
- package/tests/publish-config-narrowing.spec.ts +20 -0
- package/tests/run-lint.spec.ts +38 -87
- package/tests/run-typecheck.spec.ts +194 -303
- package/tests/run-watch.spec.ts +0 -34
- package/tests/sd-cli.spec.ts +0 -88
- package/tests/sd-public-dev-plugin-mime.spec.ts +19 -0
- package/dist/builders/index.d.ts +0 -5
- package/dist/builders/index.d.ts.map +0 -1
- package/dist/builders/index.js +0 -5
- package/dist/builders/index.js.map +0 -6
- package/dist/infra/index.d.ts +0 -4
- package/dist/infra/index.d.ts.map +0 -1
- package/dist/infra/index.js +0 -4
- package/dist/infra/index.js.map +0 -6
- package/dist/orchestrators/index.d.ts +0 -4
- package/dist/orchestrators/index.d.ts.map +0 -1
- package/dist/orchestrators/index.js +0 -4
- package/dist/orchestrators/index.js.map +0 -6
- package/src/builders/index.ts +0 -4
- package/src/infra/index.ts +0 -3
- package/src/orchestrators/index.ts +0 -3
- package/templates/init/stylelint.config.ts +0 -1
package/src/sd-config.types.ts
CHANGED
|
@@ -8,13 +8,20 @@ export type BuildTarget = "node" | "browser" | "neutral";
|
|
|
8
8
|
|
|
9
9
|
//#region Publish configuration types
|
|
10
10
|
|
|
11
|
+
/**
|
|
12
|
+
* npm registry publish configuration
|
|
13
|
+
*/
|
|
14
|
+
export interface SdNpmPublishConfig {
|
|
15
|
+
type: "npm";
|
|
16
|
+
}
|
|
17
|
+
|
|
11
18
|
/**
|
|
12
19
|
* Package publish configuration
|
|
13
|
-
* -
|
|
20
|
+
* - SdNpmPublishConfig: deploy to npm registry
|
|
14
21
|
* - SdLocalDirectoryPublishConfig: copy to local directory
|
|
15
22
|
* - SdStoragePublishConfig: upload to FTP/FTPS/SFTP server
|
|
16
23
|
*/
|
|
17
|
-
export type SdPublishConfig =
|
|
24
|
+
export type SdPublishConfig = SdNpmPublishConfig | SdLocalDirectoryPublishConfig | SdStoragePublishConfig;
|
|
18
25
|
|
|
19
26
|
/**
|
|
20
27
|
* Local directory publish configuration
|
|
@@ -249,7 +256,7 @@ export interface SdConfigParams {
|
|
|
249
256
|
/** development mode flag */
|
|
250
257
|
dev: boolean;
|
|
251
258
|
/** additional options (from CLI's -o flag) */
|
|
252
|
-
|
|
259
|
+
options: string[];
|
|
253
260
|
}
|
|
254
261
|
|
|
255
262
|
/**
|
package/src/utils/copy-public.ts
CHANGED
|
@@ -1,12 +1,8 @@
|
|
|
1
1
|
import path from "path";
|
|
2
2
|
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
fsRm,
|
|
6
|
-
fsGlob,
|
|
3
|
+
fsx,
|
|
4
|
+
pathx,
|
|
7
5
|
FsWatcher,
|
|
8
|
-
fsExists,
|
|
9
|
-
pathIsChildPath,
|
|
10
6
|
} from "@simplysm/core-node";
|
|
11
7
|
|
|
12
8
|
/**
|
|
@@ -18,30 +14,30 @@ import {
|
|
|
18
14
|
*/
|
|
19
15
|
export async function copyPublicFiles(pkgDir: string, includeDev: boolean): Promise<void> {
|
|
20
16
|
const distDir = path.join(pkgDir, "dist");
|
|
21
|
-
await
|
|
17
|
+
await fsx.mkdir(distDir);
|
|
22
18
|
|
|
23
19
|
// Copy public/
|
|
24
20
|
const publicDir = path.join(pkgDir, "public");
|
|
25
|
-
if (await
|
|
26
|
-
const files = await
|
|
21
|
+
if (await fsx.exists(publicDir)) {
|
|
22
|
+
const files = await fsx.glob("**/*", { cwd: publicDir, absolute: true });
|
|
27
23
|
for (const file of files) {
|
|
28
24
|
const relativePath = path.relative(publicDir, file);
|
|
29
25
|
const distPath = path.join(distDir, relativePath);
|
|
30
|
-
await
|
|
31
|
-
await
|
|
26
|
+
await fsx.mkdir(path.dirname(distPath));
|
|
27
|
+
await fsx.copy(file, distPath);
|
|
32
28
|
}
|
|
33
29
|
}
|
|
34
30
|
|
|
35
31
|
// Copy public-dev/ (overlay: overwrites public/)
|
|
36
32
|
if (includeDev) {
|
|
37
33
|
const publicDevDir = path.join(pkgDir, "public-dev");
|
|
38
|
-
if (await
|
|
39
|
-
const files = await
|
|
34
|
+
if (await fsx.exists(publicDevDir)) {
|
|
35
|
+
const files = await fsx.glob("**/*", { cwd: publicDevDir, absolute: true });
|
|
40
36
|
for (const file of files) {
|
|
41
37
|
const relativePath = path.relative(publicDevDir, file);
|
|
42
38
|
const distPath = path.join(distDir, relativePath);
|
|
43
|
-
await
|
|
44
|
-
await
|
|
39
|
+
await fsx.mkdir(path.dirname(distPath));
|
|
40
|
+
await fsx.copy(file, distPath);
|
|
45
41
|
}
|
|
46
42
|
}
|
|
47
43
|
}
|
|
@@ -68,10 +64,10 @@ export async function watchPublicFiles(
|
|
|
68
64
|
|
|
69
65
|
// Collect watch target paths
|
|
70
66
|
const watchPaths: string[] = [];
|
|
71
|
-
if (await
|
|
67
|
+
if (await fsx.exists(publicDir)) {
|
|
72
68
|
watchPaths.push(path.join(publicDir, "**/*"));
|
|
73
69
|
}
|
|
74
|
-
if (includeDev && (await
|
|
70
|
+
if (includeDev && (await fsx.exists(publicDevDir))) {
|
|
75
71
|
watchPaths.push(path.join(publicDevDir, "**/*"));
|
|
76
72
|
}
|
|
77
73
|
|
|
@@ -85,7 +81,7 @@ export async function watchPublicFiles(
|
|
|
85
81
|
for (const { event, path: filePath } of changes) {
|
|
86
82
|
// Determine which source directory the change came from
|
|
87
83
|
let sourceDir: string;
|
|
88
|
-
if (
|
|
84
|
+
if (pathx.isChildPath(filePath, publicDevDir)) {
|
|
89
85
|
sourceDir = publicDevDir;
|
|
90
86
|
} else {
|
|
91
87
|
sourceDir = publicDir;
|
|
@@ -98,30 +94,30 @@ export async function watchPublicFiles(
|
|
|
98
94
|
// If deleted from public, don't delete if same file exists in public-dev
|
|
99
95
|
if (sourceDir === publicDir && includeDev) {
|
|
100
96
|
const devOverride = path.join(publicDevDir, relPath);
|
|
101
|
-
if (await
|
|
97
|
+
if (await fsx.exists(devOverride)) {
|
|
102
98
|
continue;
|
|
103
99
|
}
|
|
104
100
|
}
|
|
105
101
|
// If deleted from public-dev, restore from public if it exists (fallback restore)
|
|
106
102
|
if (sourceDir === publicDevDir && includeDev) {
|
|
107
103
|
const publicFallback = path.join(publicDir, relPath);
|
|
108
|
-
if (await
|
|
109
|
-
await
|
|
110
|
-
await
|
|
104
|
+
if (await fsx.exists(publicFallback)) {
|
|
105
|
+
await fsx.mkdir(path.dirname(distPath));
|
|
106
|
+
await fsx.copy(publicFallback, distPath);
|
|
111
107
|
continue;
|
|
112
108
|
}
|
|
113
109
|
}
|
|
114
|
-
await
|
|
110
|
+
await fsx.rm(distPath);
|
|
115
111
|
} else if (event === "add" || event === "change") {
|
|
116
112
|
// If changed in public, skip if same file exists in public-dev (overlay takes priority)
|
|
117
113
|
if (sourceDir === publicDir && includeDev) {
|
|
118
114
|
const devOverride = path.join(publicDevDir, relPath);
|
|
119
|
-
if (await
|
|
115
|
+
if (await fsx.exists(devOverride)) {
|
|
120
116
|
continue;
|
|
121
117
|
}
|
|
122
118
|
}
|
|
123
|
-
await
|
|
124
|
-
await
|
|
119
|
+
await fsx.mkdir(path.dirname(distPath));
|
|
120
|
+
await fsx.copy(filePath, distPath);
|
|
125
121
|
}
|
|
126
122
|
}
|
|
127
123
|
});
|
package/src/utils/copy-src.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import path from "path";
|
|
2
|
-
import {
|
|
2
|
+
import { fsx, FsWatcher } from "@simplysm/core-node";
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Copy files matching glob patterns from src/ to dist/
|
|
@@ -13,12 +13,12 @@ export async function copySrcFiles(pkgDir: string, patterns: string[]): Promise<
|
|
|
13
13
|
const distDir = path.join(pkgDir, "dist");
|
|
14
14
|
|
|
15
15
|
for (const pattern of patterns) {
|
|
16
|
-
const files = await
|
|
16
|
+
const files = await fsx.glob(pattern, { cwd: srcDir, absolute: true });
|
|
17
17
|
for (const file of files) {
|
|
18
18
|
const relativePath = path.relative(srcDir, file);
|
|
19
19
|
const distPath = path.join(distDir, relativePath);
|
|
20
|
-
await
|
|
21
|
-
await
|
|
20
|
+
await fsx.mkdir(path.dirname(distPath));
|
|
21
|
+
await fsx.copy(file, distPath);
|
|
22
22
|
}
|
|
23
23
|
}
|
|
24
24
|
}
|
|
@@ -48,10 +48,10 @@ export async function watchCopySrcFiles(pkgDir: string, patterns: string[]): Pro
|
|
|
48
48
|
const distPath = path.join(distDir, relPath);
|
|
49
49
|
|
|
50
50
|
if (event === "unlink") {
|
|
51
|
-
await
|
|
51
|
+
await fsx.rm(distPath);
|
|
52
52
|
} else if (event === "add" || event === "change") {
|
|
53
|
-
await
|
|
54
|
-
await
|
|
53
|
+
await fsx.mkdir(path.dirname(distPath));
|
|
54
|
+
await fsx.copy(filePath, distPath);
|
|
55
55
|
}
|
|
56
56
|
}
|
|
57
57
|
});
|
|
@@ -165,28 +165,14 @@ interface PkgJson {
|
|
|
165
165
|
}
|
|
166
166
|
|
|
167
167
|
/**
|
|
168
|
-
*
|
|
169
|
-
*
|
|
170
|
-
* For server builds (bundle: true), specify uninstalled optional peer dependencies
|
|
171
|
-
* as esbuild externals to prevent build failures
|
|
168
|
+
* Recursively scan dependency tree and collect externals based on predicate
|
|
172
169
|
*/
|
|
173
|
-
|
|
174
|
-
const external = new Set<string>();
|
|
175
|
-
const visited = new Set<string>();
|
|
176
|
-
|
|
177
|
-
const pkgJson = JSON.parse(readFileSync(path.join(pkgDir, "package.json"), "utf-8")) as PkgJson;
|
|
178
|
-
for (const dep of Object.keys(pkgJson.dependencies ?? {})) {
|
|
179
|
-
scanOptionalPeerDeps(dep, pkgDir, external, visited);
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
return [...external];
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
function scanOptionalPeerDeps(
|
|
170
|
+
function scanDependencyTree(
|
|
186
171
|
pkgName: string,
|
|
187
172
|
resolveDir: string,
|
|
188
173
|
external: Set<string>,
|
|
189
174
|
visited: Set<string>,
|
|
175
|
+
collector: (pkgName: string, depDir: string, pkgJson: PkgJson) => string[],
|
|
190
176
|
): void {
|
|
191
177
|
if (visited.has(pkgName)) return;
|
|
192
178
|
visited.add(pkgName);
|
|
@@ -203,23 +189,50 @@ function scanOptionalPeerDeps(
|
|
|
203
189
|
const depDir = path.dirname(pkgJsonPath);
|
|
204
190
|
const pkgJson = JSON.parse(readFileSync(pkgJsonPath, "utf-8")) as PkgJson;
|
|
205
191
|
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
}
|
|
192
|
+
// Collect packages marked as external by predicate
|
|
193
|
+
const toExternal = collector(pkgName, depDir, pkgJson);
|
|
194
|
+
for (const name of toExternal) {
|
|
195
|
+
external.add(name);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
// Recursively traverse sub-dependencies
|
|
199
|
+
for (const dep of Object.keys(pkgJson.dependencies ?? {})) {
|
|
200
|
+
scanDependencyTree(dep, depDir, external, visited, collector);
|
|
218
201
|
}
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* Collect uninstalled optional peer deps from dependency tree
|
|
206
|
+
*
|
|
207
|
+
* For server builds (bundle: true), specify uninstalled optional peer dependencies
|
|
208
|
+
* as esbuild externals to prevent build failures
|
|
209
|
+
*/
|
|
210
|
+
export function collectUninstalledOptionalPeerDeps(pkgDir: string): string[] {
|
|
211
|
+
const external = new Set<string>();
|
|
212
|
+
const visited = new Set<string>();
|
|
219
213
|
|
|
214
|
+
const pkgJson = JSON.parse(readFileSync(path.join(pkgDir, "package.json"), "utf-8")) as PkgJson;
|
|
220
215
|
for (const dep of Object.keys(pkgJson.dependencies ?? {})) {
|
|
221
|
-
|
|
216
|
+
scanDependencyTree(dep, pkgDir, external, visited, (_pkgName, depDir, depPkgJson) => {
|
|
217
|
+
const found: string[] = [];
|
|
218
|
+
if (depPkgJson.peerDependenciesMeta != null) {
|
|
219
|
+
const peerDeps = depPkgJson.peerDependencies ?? {};
|
|
220
|
+
const depReq = createRequire(path.join(depDir, "noop.js"));
|
|
221
|
+
for (const [name, meta] of Object.entries(depPkgJson.peerDependenciesMeta)) {
|
|
222
|
+
if (meta.optional === true && name in peerDeps) {
|
|
223
|
+
try {
|
|
224
|
+
depReq.resolve(name);
|
|
225
|
+
} catch {
|
|
226
|
+
found.push(name);
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
return found;
|
|
232
|
+
});
|
|
222
233
|
}
|
|
234
|
+
|
|
235
|
+
return [...external];
|
|
223
236
|
}
|
|
224
237
|
|
|
225
238
|
//#endregion
|
|
@@ -238,42 +251,17 @@ export function collectNativeModuleExternals(pkgDir: string): string[] {
|
|
|
238
251
|
|
|
239
252
|
const pkgJson = JSON.parse(readFileSync(path.join(pkgDir, "package.json"), "utf-8")) as PkgJson;
|
|
240
253
|
for (const dep of Object.keys(pkgJson.dependencies ?? {})) {
|
|
241
|
-
|
|
254
|
+
scanDependencyTree(dep, pkgDir, external, visited, (pkgName, depDir, _pkgJson) => {
|
|
255
|
+
const found: string[] = [];
|
|
256
|
+
// Detect native modules by checking for binding.gyp
|
|
257
|
+
if (existsSync(path.join(depDir, "binding.gyp"))) {
|
|
258
|
+
found.push(pkgName);
|
|
259
|
+
}
|
|
260
|
+
return found;
|
|
261
|
+
});
|
|
242
262
|
}
|
|
243
263
|
|
|
244
264
|
return [...external];
|
|
245
265
|
}
|
|
246
266
|
|
|
247
|
-
function scanNativeModules(
|
|
248
|
-
pkgName: string,
|
|
249
|
-
resolveDir: string,
|
|
250
|
-
external: Set<string>,
|
|
251
|
-
visited: Set<string>,
|
|
252
|
-
): void {
|
|
253
|
-
if (visited.has(pkgName)) return;
|
|
254
|
-
visited.add(pkgName);
|
|
255
|
-
|
|
256
|
-
const req = createRequire(path.join(resolveDir, "noop.js"));
|
|
257
|
-
|
|
258
|
-
let pkgJsonPath: string;
|
|
259
|
-
try {
|
|
260
|
-
pkgJsonPath = req.resolve(`${pkgName}/package.json`);
|
|
261
|
-
} catch {
|
|
262
|
-
return;
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
const depDir = path.dirname(pkgJsonPath);
|
|
266
|
-
|
|
267
|
-
// Detect native modules by checking for binding.gyp
|
|
268
|
-
if (existsSync(path.join(depDir, "binding.gyp"))) {
|
|
269
|
-
external.add(pkgName);
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
// Recursively traverse sub-dependencies
|
|
273
|
-
const depPkgJson = JSON.parse(readFileSync(pkgJsonPath, "utf-8")) as PkgJson;
|
|
274
|
-
for (const dep of Object.keys(depPkgJson.dependencies ?? {})) {
|
|
275
|
-
scanNativeModules(dep, depDir, external, visited);
|
|
276
|
-
}
|
|
277
|
-
}
|
|
278
|
-
|
|
279
267
|
//#endregion
|
|
@@ -2,7 +2,7 @@ import fs from "fs";
|
|
|
2
2
|
import path from "path";
|
|
3
3
|
import { glob } from "glob";
|
|
4
4
|
import { consola } from "consola";
|
|
5
|
-
import {
|
|
5
|
+
import { fsx, pathx, FsWatcher } from "@simplysm/core-node";
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* Match glob patterns from replaceDeps config with target package list
|
|
@@ -249,7 +249,7 @@ export async function setupReplaceDeps(
|
|
|
249
249
|
for (const { targetName, resolvedSourcePath, actualTargetPath } of entries) {
|
|
250
250
|
try {
|
|
251
251
|
// Overwrite-copy source files to actualTargetPath (maintain existing directory, preserve symlinks)
|
|
252
|
-
await
|
|
252
|
+
await fsx.copy(resolvedSourcePath, actualTargetPath, replaceDepsCopyFilter);
|
|
253
253
|
|
|
254
254
|
setupCount += 1;
|
|
255
255
|
} catch (err) {
|
|
@@ -300,7 +300,7 @@ export async function watchReplaceDeps(
|
|
|
300
300
|
// Filter excluded items: basename match or path within excluded directory
|
|
301
301
|
if (
|
|
302
302
|
EXCLUDED_NAMES.has(path.basename(changedPath)) ||
|
|
303
|
-
excludedPaths.some((ep) =>
|
|
303
|
+
excludedPaths.some((ep) => pathx.isChildPath(changedPath, ep))
|
|
304
304
|
) {
|
|
305
305
|
continue;
|
|
306
306
|
}
|
|
@@ -327,14 +327,14 @@ export async function watchReplaceDeps(
|
|
|
327
327
|
// Check if source is directory or file
|
|
328
328
|
const stat = await fs.promises.stat(changedPath);
|
|
329
329
|
if (stat.isDirectory()) {
|
|
330
|
-
await
|
|
330
|
+
await fsx.mkdir(destPath);
|
|
331
331
|
} else {
|
|
332
|
-
await
|
|
333
|
-
await
|
|
332
|
+
await fsx.mkdir(path.dirname(destPath));
|
|
333
|
+
await fsx.copy(changedPath, destPath, replaceDepsCopyFilter);
|
|
334
334
|
}
|
|
335
335
|
} else {
|
|
336
336
|
// Source was deleted → delete target
|
|
337
|
-
await
|
|
337
|
+
await fsx.rm(destPath);
|
|
338
338
|
}
|
|
339
339
|
} catch (err) {
|
|
340
340
|
logger.error(
|
package/src/utils/sd-config.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import path from "path";
|
|
2
2
|
import { createJiti } from "jiti";
|
|
3
3
|
import { SdError } from "@simplysm/core-common";
|
|
4
|
-
import {
|
|
4
|
+
import { fsx } from "@simplysm/core-node";
|
|
5
5
|
import type { SdConfig, SdConfigParams } from "../sd-config.types";
|
|
6
6
|
|
|
7
7
|
/**
|
|
@@ -12,7 +12,7 @@ import type { SdConfig, SdConfigParams } from "../sd-config.types";
|
|
|
12
12
|
export async function loadSdConfig(params: SdConfigParams): Promise<SdConfig> {
|
|
13
13
|
const sdConfigPath = path.resolve(params.cwd, "sd.config.ts");
|
|
14
14
|
|
|
15
|
-
if (!(await
|
|
15
|
+
if (!(await fsx.exists(sdConfigPath))) {
|
|
16
16
|
throw new SdError(`sd.config.ts file not found: ${sdConfigPath}`);
|
|
17
17
|
}
|
|
18
18
|
|
package/src/utils/template.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import path from "path";
|
|
2
2
|
import Handlebars from "handlebars";
|
|
3
|
-
import {
|
|
3
|
+
import { fsx } from "@simplysm/core-node";
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Recursively traverse template directory, render with Handlebars, and generate files
|
|
@@ -20,13 +20,13 @@ export async function renderTemplateDir(
|
|
|
20
20
|
context: Record<string, unknown>,
|
|
21
21
|
dirReplacements?: Record<string, string>,
|
|
22
22
|
): Promise<void> {
|
|
23
|
-
await
|
|
23
|
+
await fsx.mkdir(destDir);
|
|
24
24
|
|
|
25
|
-
const entries = await
|
|
25
|
+
const entries = await fsx.readdir(srcDir);
|
|
26
26
|
|
|
27
27
|
for (const entry of entries) {
|
|
28
28
|
const srcPath = path.join(srcDir, entry);
|
|
29
|
-
const stat = await
|
|
29
|
+
const stat = await fsx.stat(srcPath);
|
|
30
30
|
|
|
31
31
|
if (stat.isDirectory()) {
|
|
32
32
|
// Apply directory name substitution
|
|
@@ -39,7 +39,7 @@ export async function renderTemplateDir(
|
|
|
39
39
|
);
|
|
40
40
|
} else if (entry.endsWith(".hbs")) {
|
|
41
41
|
// Render Handlebars template
|
|
42
|
-
const source = await
|
|
42
|
+
const source = await fsx.read(srcPath);
|
|
43
43
|
const template = Handlebars.compile(source, { noEscape: true });
|
|
44
44
|
const result = template(context);
|
|
45
45
|
|
|
@@ -47,10 +47,10 @@ export async function renderTemplateDir(
|
|
|
47
47
|
if (result.trim().length === 0) continue;
|
|
48
48
|
|
|
49
49
|
const destFileName = entry.slice(0, -4); // Remove .hbs
|
|
50
|
-
await
|
|
50
|
+
await fsx.write(path.join(destDir, destFileName), result);
|
|
51
51
|
} else {
|
|
52
52
|
// Copy binary files as-is
|
|
53
|
-
await
|
|
53
|
+
await fsx.copy(srcPath, path.join(destDir, entry));
|
|
54
54
|
}
|
|
55
55
|
}
|
|
56
56
|
}
|
package/src/utils/tsconfig.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import ts from "typescript";
|
|
2
2
|
import path from "path";
|
|
3
|
-
import {
|
|
3
|
+
import { fsx, pathx } from "@simplysm/core-node";
|
|
4
4
|
import { SdError } from "@simplysm/core-common";
|
|
5
5
|
|
|
6
6
|
/**
|
|
@@ -14,11 +14,11 @@ const DOM_LIB_PATTERNS = ["dom", "webworker"] as const;
|
|
|
14
14
|
*/
|
|
15
15
|
export async function getTypesFromPackageJson(packageDir: string): Promise<string[]> {
|
|
16
16
|
const packageJsonPath = path.join(packageDir, "package.json");
|
|
17
|
-
if (!(await
|
|
17
|
+
if (!(await fsx.exists(packageJsonPath))) {
|
|
18
18
|
return [];
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
const packageJson = await
|
|
21
|
+
const packageJson = await fsx.readJson<{ devDependencies?: Record<string, string> }>(
|
|
22
22
|
packageJsonPath,
|
|
23
23
|
);
|
|
24
24
|
const devDeps = packageJson.devDependencies ?? {};
|
|
@@ -32,9 +32,8 @@ export async function getTypesFromPackageJson(packageDir: string): Promise<strin
|
|
|
32
32
|
* Type check environment
|
|
33
33
|
* - node: remove DOM lib + add node types
|
|
34
34
|
* - browser: remove node types
|
|
35
|
-
* - neutral: keep DOM lib + add node types (for Node/browser shared packages)
|
|
36
35
|
*/
|
|
37
|
-
export type TypecheckEnv = "node" | "browser"
|
|
36
|
+
export type TypecheckEnv = "node" | "browser";
|
|
38
37
|
|
|
39
38
|
/**
|
|
40
39
|
* Create compiler options for package
|
|
@@ -72,9 +71,6 @@ export async function getCompilerOptionsForPackage(
|
|
|
72
71
|
case "browser":
|
|
73
72
|
options.types = packageTypes.filter((t) => t !== "node");
|
|
74
73
|
break;
|
|
75
|
-
case "neutral":
|
|
76
|
-
options.types = [...new Set([...packageTypes, "node"])];
|
|
77
|
-
break;
|
|
78
74
|
}
|
|
79
75
|
|
|
80
76
|
return options;
|
|
@@ -111,7 +107,7 @@ export function getPackageSourceFiles(
|
|
|
111
107
|
parsedConfig: ts.ParsedCommandLine,
|
|
112
108
|
): string[] {
|
|
113
109
|
const pkgSrcDir = path.join(pkgDir, "src");
|
|
114
|
-
return parsedConfig.fileNames.filter((f) =>
|
|
110
|
+
return parsedConfig.fileNames.filter((f) => pathx.isChildPath(f, pkgSrcDir));
|
|
115
111
|
}
|
|
116
112
|
|
|
117
113
|
/**
|
|
@@ -119,7 +115,7 @@ export function getPackageSourceFiles(
|
|
|
119
115
|
*/
|
|
120
116
|
export function getPackageFiles(pkgDir: string, parsedConfig: ts.ParsedCommandLine): string[] {
|
|
121
117
|
return parsedConfig.fileNames.filter((f) => {
|
|
122
|
-
if (!
|
|
118
|
+
if (!pathx.isChildPath(f, pkgDir)) return false;
|
|
123
119
|
// Exclude files directly in package root (config files) — treated same as project root files in other tasks
|
|
124
120
|
const relative = path.relative(pkgDir, f);
|
|
125
121
|
return path.dirname(relative) !== ".";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import ts from "typescript";
|
|
2
|
-
import {
|
|
2
|
+
import { fsx } from "@simplysm/core-node";
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Serialized Diagnostic that can be passed to Worker
|
|
@@ -67,7 +67,7 @@ export function deserializeDiagnostic(
|
|
|
67
67
|
// If file was deleted or inaccessible, treat as empty content
|
|
68
68
|
// (source code context won't be displayed but diagnostic message is shown normally)
|
|
69
69
|
if (!fileCache.has(fileName)) {
|
|
70
|
-
fileCache.set(fileName,
|
|
70
|
+
fileCache.set(fileName, fsx.existsSync(fileName) ? fsx.readSync(fileName) : "");
|
|
71
71
|
}
|
|
72
72
|
const content = fileCache.get(fileName)!;
|
|
73
73
|
|