@simplysm/sd-cli 13.0.95 → 13.0.97
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/orchestrators/DevOrchestrator.d.ts.map +1 -1
- package/dist/orchestrators/DevOrchestrator.js +6 -4
- package/dist/orchestrators/DevOrchestrator.js.map +1 -1
- package/dist/orchestrators/WatchOrchestrator.d.ts +7 -0
- package/dist/orchestrators/WatchOrchestrator.d.ts.map +1 -1
- package/dist/orchestrators/WatchOrchestrator.js +93 -49
- package/dist/orchestrators/WatchOrchestrator.js.map +1 -1
- package/dist/sd-config.types.d.ts +14 -1
- package/dist/sd-config.types.d.ts.map +1 -1
- package/dist/utils/package-utils.js +1 -1
- package/dist/utils/package-utils.js.map +1 -1
- package/dist/utils/vite-config.d.ts +4 -0
- package/dist/utils/vite-config.d.ts.map +1 -1
- package/dist/utils/vite-config.js +4 -1
- package/dist/utils/vite-config.js.map +1 -1
- package/dist/workers/client.worker.d.ts.map +1 -1
- package/dist/workers/client.worker.js +7 -2
- package/dist/workers/client.worker.js.map +1 -1
- package/dist/workers/server-runtime.worker.d.ts +1 -0
- package/dist/workers/server-runtime.worker.d.ts.map +1 -1
- package/dist/workers/server-runtime.worker.js +5 -0
- package/dist/workers/server-runtime.worker.js.map +1 -1
- package/package.json +6 -6
- package/src/orchestrators/DevOrchestrator.ts +4 -1
- package/src/orchestrators/WatchOrchestrator.ts +124 -67
- package/src/sd-config.types.ts +15 -1
- package/src/utils/package-utils.ts +2 -2
- package/src/utils/vite-config.ts +9 -1
- package/src/workers/client.worker.ts +9 -1
- package/src/workers/server-runtime.worker.ts +8 -0
- package/templates/init/.gitignore.hbs +1 -2
- package/templates/init/package.json.hbs +5 -6
- package/templates/init/packages/client-admin/package.json.hbs +7 -7
- package/templates/init/packages/db-main/package.json.hbs +2 -2
- package/templates/init/packages/server/package.json.hbs +5 -5
- package/templates/init/tests-e2e/package.json.hbs +1 -1
- package/tests/run-watch.spec.ts +35 -0
- package/tests/vite-config-outdir.spec.ts +38 -0
- package/README.md +0 -337
- package/docs/architecture.md +0 -311
- package/docs/config-types.md +0 -253
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/workers/server-runtime.worker.ts"],
|
|
4
|
-
"mappings": "AAAA,OAAO,WAAW;AAClB,SAAS,oBAAoB;AAC7B,SAAS,OAAO,aAAa;AAC7B,SAAS,eAAe;AACxB,OAAO,SAAS;AAChB,SAAS,qBAAqB;AAC9B,SAAS,yBAAyB,uBAAuB;
|
|
4
|
+
"mappings": "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",
|
|
5
5
|
"names": []
|
|
6
6
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@simplysm/sd-cli",
|
|
3
|
-
"version": "13.0.
|
|
3
|
+
"version": "13.0.97",
|
|
4
4
|
"description": "Simplysm package - CLI tool",
|
|
5
5
|
"author": "simplysm",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -21,8 +21,8 @@
|
|
|
21
21
|
],
|
|
22
22
|
"sideEffects": false,
|
|
23
23
|
"dependencies": {
|
|
24
|
-
"@fastify/http-proxy": "^11.4.
|
|
25
|
-
"@inquirer/prompts": "^8.3.
|
|
24
|
+
"@fastify/http-proxy": "^11.4.2",
|
|
25
|
+
"@inquirer/prompts": "^8.3.2",
|
|
26
26
|
"consola": "^3.4.2",
|
|
27
27
|
"esbuild": "^0.27.4",
|
|
28
28
|
"esbuild-plugin-solid": "^0.6.0",
|
|
@@ -43,9 +43,9 @@
|
|
|
43
43
|
"vite-plugin-solid": "^2.11.11",
|
|
44
44
|
"vite-tsconfig-paths": "^6.1.1",
|
|
45
45
|
"yargs": "^18.0.0",
|
|
46
|
-
"@simplysm/core-
|
|
47
|
-
"@simplysm/core-
|
|
48
|
-
"@simplysm/storage": "13.0.
|
|
46
|
+
"@simplysm/core-node": "13.0.97",
|
|
47
|
+
"@simplysm/core-common": "13.0.97",
|
|
48
|
+
"@simplysm/storage": "13.0.97"
|
|
49
49
|
},
|
|
50
50
|
"devDependencies": {
|
|
51
51
|
"@types/semver": "^7.7.1",
|
|
@@ -498,7 +498,7 @@ export class DevOrchestrator {
|
|
|
498
498
|
};
|
|
499
499
|
|
|
500
500
|
// Register Server Build Worker event handlers
|
|
501
|
-
for (const { name } of this._serverPackages) {
|
|
501
|
+
for (const { name, config } of this._serverPackages) {
|
|
502
502
|
const serverBuild = this._serverBuildWorkers.get(name)!;
|
|
503
503
|
|
|
504
504
|
serverBuild.worker.on("buildStart", () => {
|
|
@@ -540,6 +540,7 @@ export class DevOrchestrator {
|
|
|
540
540
|
serverRuntimePromises,
|
|
541
541
|
resolveServerStep,
|
|
542
542
|
viteClientReadyPromises,
|
|
543
|
+
{ ...this._baseEnv, ...config.env },
|
|
543
544
|
).catch((err: unknown) => {
|
|
544
545
|
const message = errNs.message(err);
|
|
545
546
|
this._logger.error(`[${name}] Error starting Server Runtime:`, message);
|
|
@@ -610,6 +611,7 @@ export class DevOrchestrator {
|
|
|
610
611
|
serverRuntimePromises: Map<string, { promise: Promise<void>; resolver: () => void }>,
|
|
611
612
|
resolveServerStep: (serverName: string, resultKey: string, result: BuildResult) => void,
|
|
612
613
|
viteClientReadyPromises: Map<string, { promise: Promise<void>; resolver: () => void }>,
|
|
614
|
+
env?: Record<string, string>,
|
|
613
615
|
): Promise<void> {
|
|
614
616
|
const runtimeStartTime = performance.now();
|
|
615
617
|
this._logger.debug(`[${serverName}] _startServerRuntime: ${mainJsPath}`);
|
|
@@ -692,6 +694,7 @@ export class DevOrchestrator {
|
|
|
692
694
|
.start({
|
|
693
695
|
mainJsPath,
|
|
694
696
|
clientPorts: serverClientPorts,
|
|
697
|
+
env,
|
|
695
698
|
})
|
|
696
699
|
.catch((err: unknown) => {
|
|
697
700
|
const message = errNs.message(err);
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import path from "path";
|
|
2
|
+
import { spawn } from "child_process";
|
|
2
3
|
import { consola } from "consola";
|
|
3
|
-
import type { BuildTarget, SdBuildPackageConfig, SdConfig } from "../sd-config.types";
|
|
4
|
+
import type { BuildTarget, SdBuildPackageConfig, SdConfig, SdScriptsPackageConfig } from "../sd-config.types";
|
|
4
5
|
import { loadSdConfig } from "../utils/sd-config";
|
|
5
6
|
import { filterPackagesByTargets } from "../utils/package-utils";
|
|
6
7
|
import { watchReplaceDeps, type WatchReplaceDepResult } from "../utils/replace-deps";
|
|
@@ -12,7 +13,7 @@ import { LibraryBuilder } from "../builders/LibraryBuilder";
|
|
|
12
13
|
import { DtsBuilder } from "../builders/DtsBuilder";
|
|
13
14
|
import type { BuildPackageInfo } from "../builders/types";
|
|
14
15
|
import { watchCopySrcFiles } from "../utils/copy-src";
|
|
15
|
-
import
|
|
16
|
+
import { FsWatcher } from "@simplysm/core-node";
|
|
16
17
|
|
|
17
18
|
/**
|
|
18
19
|
* Watch command options
|
|
@@ -42,6 +43,8 @@ export class WatchOrchestrator {
|
|
|
42
43
|
private _packages: BuildPackageInfo[] = [];
|
|
43
44
|
private _copySrcWatchers: FsWatcher[] = [];
|
|
44
45
|
private _replaceDepWatcher: WatchReplaceDepResult | undefined;
|
|
46
|
+
private readonly _watchHookPackages: Array<{ name: string; dir: string; config: SdScriptsPackageConfig }> = [];
|
|
47
|
+
private readonly _watchHookWatchers: FsWatcher[] = [];
|
|
45
48
|
|
|
46
49
|
constructor(options: WatchOrchestratorOptions) {
|
|
47
50
|
this._cwd = process.cwd();
|
|
@@ -80,7 +83,7 @@ export class WatchOrchestrator {
|
|
|
80
83
|
// Filter by targets
|
|
81
84
|
const allPackages = filterPackagesByTargets(sdConfig.packages, this._options.targets);
|
|
82
85
|
|
|
83
|
-
//
|
|
86
|
+
// Classify packages: library (node/browser/neutral) vs scripts+watch
|
|
84
87
|
const isLibraryTarget = (target: string): target is BuildTarget =>
|
|
85
88
|
target === "node" || target === "browser" || target === "neutral";
|
|
86
89
|
|
|
@@ -88,15 +91,21 @@ export class WatchOrchestrator {
|
|
|
88
91
|
for (const [name, config] of Object.entries(allPackages)) {
|
|
89
92
|
if (isLibraryTarget(config.target)) {
|
|
90
93
|
libraryConfigs[name] = config as SdBuildPackageConfig;
|
|
94
|
+
} else if (config.target === "scripts" && config.watch != null) {
|
|
95
|
+
this._watchHookPackages.push({
|
|
96
|
+
name,
|
|
97
|
+
dir: path.join(this._cwd, "packages", name),
|
|
98
|
+
config: config,
|
|
99
|
+
});
|
|
91
100
|
}
|
|
92
101
|
}
|
|
93
102
|
|
|
94
|
-
if (Object.keys(libraryConfigs).length === 0) {
|
|
95
|
-
process.stdout.write("⚠ No
|
|
103
|
+
if (Object.keys(libraryConfigs).length === 0 && this._watchHookPackages.length === 0) {
|
|
104
|
+
process.stdout.write("⚠ No packages to watch.\n");
|
|
96
105
|
return;
|
|
97
106
|
}
|
|
98
107
|
|
|
99
|
-
// Create PackageInfo array
|
|
108
|
+
// Create PackageInfo array for library packages
|
|
100
109
|
this._packages = Object.entries(libraryConfigs).map(([name, config]) => ({
|
|
101
110
|
name,
|
|
102
111
|
dir: path.join(this._cwd, "packages", name),
|
|
@@ -104,94 +113,135 @@ export class WatchOrchestrator {
|
|
|
104
113
|
}));
|
|
105
114
|
|
|
106
115
|
// Initialize infrastructure
|
|
107
|
-
this._resultCollector = new ResultCollector();
|
|
108
116
|
this._signalHandler = new SignalHandler();
|
|
109
|
-
this._rebuildManager = new RebuildManager(this._logger);
|
|
110
117
|
|
|
111
|
-
//
|
|
112
|
-
this.
|
|
113
|
-
|
|
114
|
-
|
|
118
|
+
// Initialize library builders only if there are library packages
|
|
119
|
+
if (this._packages.length > 0) {
|
|
120
|
+
this._resultCollector = new ResultCollector();
|
|
121
|
+
this._rebuildManager = new RebuildManager(this._logger);
|
|
122
|
+
|
|
123
|
+
// Print errors on batch completion
|
|
124
|
+
this._rebuildManager.on("batchComplete", () => {
|
|
125
|
+
printErrors(this._resultCollector.toMap());
|
|
126
|
+
});
|
|
115
127
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
128
|
+
// Create builders
|
|
129
|
+
const builderOptions = {
|
|
130
|
+
cwd: this._cwd,
|
|
131
|
+
packages: this._packages,
|
|
132
|
+
resultCollector: this._resultCollector,
|
|
133
|
+
rebuildManager: this._rebuildManager,
|
|
134
|
+
};
|
|
123
135
|
|
|
124
|
-
|
|
125
|
-
|
|
136
|
+
this._libraryBuilder = new LibraryBuilder(builderOptions);
|
|
137
|
+
this._dtsBuilder = new DtsBuilder(builderOptions);
|
|
126
138
|
|
|
127
|
-
|
|
128
|
-
|
|
139
|
+
// Initialize builders
|
|
140
|
+
await Promise.all([this._libraryBuilder.initialize(), this._dtsBuilder.initialize()]);
|
|
141
|
+
}
|
|
129
142
|
}
|
|
130
143
|
|
|
131
144
|
/**
|
|
132
145
|
* Start watch mode
|
|
133
146
|
* - Run initial build
|
|
147
|
+
* - Start watch hook watchers
|
|
134
148
|
* - Output results
|
|
135
149
|
*/
|
|
136
150
|
async start(): Promise<void> {
|
|
137
|
-
if (this._packages.length === 0) {
|
|
151
|
+
if (this._packages.length === 0 && this._watchHookPackages.length === 0) {
|
|
138
152
|
return;
|
|
139
153
|
}
|
|
140
154
|
|
|
141
|
-
//
|
|
142
|
-
|
|
143
|
-
|
|
155
|
+
// Start library build if there are library packages
|
|
156
|
+
if (this._packages.length > 0) {
|
|
157
|
+
// Set up initial build promises
|
|
158
|
+
const buildPromises = this._libraryBuilder.getInitialBuildPromises();
|
|
159
|
+
const dtsPromises = this._dtsBuilder.getInitialBuildPromises();
|
|
160
|
+
|
|
161
|
+
// Start copySrc watch
|
|
162
|
+
for (const pkg of this._packages) {
|
|
163
|
+
if (pkg.config.copySrc != null && pkg.config.copySrc.length > 0) {
|
|
164
|
+
const watcher = await watchCopySrcFiles(pkg.dir, pkg.config.copySrc);
|
|
165
|
+
this._copySrcWatchers.push(watcher);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// Start watch (run in background)
|
|
170
|
+
void this._libraryBuilder.startWatch();
|
|
171
|
+
void this._dtsBuilder.startWatch();
|
|
144
172
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
173
|
+
// Start initial build
|
|
174
|
+
this._logger.start("Running initial build...");
|
|
175
|
+
|
|
176
|
+
// Set up complete promise array for library build and DTS build
|
|
177
|
+
const allBuildTasks: Array<{ name: string; promise: Promise<void> }> = [];
|
|
178
|
+
|
|
179
|
+
// Library build tasks
|
|
180
|
+
for (const pkg of this._packages) {
|
|
181
|
+
const promise = buildPromises.get(`${pkg.name}:build`) ?? Promise.resolve();
|
|
182
|
+
allBuildTasks.push({
|
|
183
|
+
name: `${pkg.name}:build`,
|
|
184
|
+
promise,
|
|
185
|
+
});
|
|
150
186
|
}
|
|
151
|
-
}
|
|
152
187
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
188
|
+
// DTS tasks
|
|
189
|
+
for (const pkg of this._packages) {
|
|
190
|
+
const promise = dtsPromises.get(`${pkg.name}:dts`) ?? Promise.resolve();
|
|
191
|
+
allBuildTasks.push({
|
|
192
|
+
name: `${pkg.name}:dts`,
|
|
193
|
+
promise,
|
|
194
|
+
});
|
|
195
|
+
}
|
|
156
196
|
|
|
157
|
-
|
|
158
|
-
|
|
197
|
+
// Run all build tasks concurrently (wait until initial build completes)
|
|
198
|
+
await Promise.allSettled(allBuildTasks.map((task) => task.promise));
|
|
159
199
|
|
|
160
|
-
|
|
161
|
-
const allBuildTasks: Array<{ name: string; promise: Promise<void> }> = [];
|
|
200
|
+
this._logger.success("Initial build completed");
|
|
162
201
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
const promise = buildPromises.get(`${pkg.name}:build`) ?? Promise.resolve();
|
|
166
|
-
allBuildTasks.push({
|
|
167
|
-
name: `${pkg.name}:build`,
|
|
168
|
-
promise,
|
|
169
|
-
});
|
|
202
|
+
// Output initial build results
|
|
203
|
+
printErrors(this._resultCollector.toMap());
|
|
170
204
|
}
|
|
171
205
|
|
|
172
|
-
//
|
|
173
|
-
for (const pkg of this.
|
|
174
|
-
const
|
|
175
|
-
|
|
176
|
-
name: `${pkg.name}:dts`,
|
|
177
|
-
promise,
|
|
178
|
-
});
|
|
179
|
-
}
|
|
206
|
+
// Start watch hook watchers for scripts+watch packages
|
|
207
|
+
for (const pkg of this._watchHookPackages) {
|
|
208
|
+
const watchConfig = pkg.config.watch!;
|
|
209
|
+
const watchTargets = watchConfig.target.map((t) => path.resolve(pkg.dir, t));
|
|
180
210
|
|
|
181
|
-
|
|
182
|
-
|
|
211
|
+
// Run initial hook
|
|
212
|
+
this._runWatchHookCmd(pkg.name, pkg.dir, watchConfig.cmd, watchConfig.args);
|
|
183
213
|
|
|
184
|
-
|
|
214
|
+
// Start watching
|
|
215
|
+
const watcher = await FsWatcher.watch(watchTargets);
|
|
216
|
+
watcher.onChange({ delay: 300 }, () => {
|
|
217
|
+
this._runWatchHookCmd(pkg.name, pkg.dir, watchConfig.cmd, watchConfig.args);
|
|
218
|
+
});
|
|
219
|
+
this._watchHookWatchers.push(watcher);
|
|
185
220
|
|
|
186
|
-
|
|
187
|
-
|
|
221
|
+
this._logger.success(`Watch hook started: ${pkg.name}`);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
/**
|
|
226
|
+
* Run watch hook command
|
|
227
|
+
*/
|
|
228
|
+
private _runWatchHookCmd(pkgName: string, cwd: string, cmd: string, args?: string[]): void {
|
|
229
|
+
const child = spawn(cmd, args ?? [], { cwd, stdio: "inherit", shell: true });
|
|
230
|
+
child.on("error", (err) => {
|
|
231
|
+
this._logger.error(`Watch hook error (${pkgName}): ${err.message}`);
|
|
232
|
+
});
|
|
233
|
+
child.on("close", (code) => {
|
|
234
|
+
if (code !== 0 && code !== null) {
|
|
235
|
+
this._logger.warn(`Watch hook (${pkgName}) exited with code ${String(code)}`);
|
|
236
|
+
}
|
|
237
|
+
});
|
|
188
238
|
}
|
|
189
239
|
|
|
190
240
|
/**
|
|
191
241
|
* Wait for termination signal
|
|
192
242
|
*/
|
|
193
243
|
async awaitTermination(): Promise<void> {
|
|
194
|
-
if (this._packages.length === 0) {
|
|
244
|
+
if (this._packages.length === 0 && this._watchHookPackages.length === 0) {
|
|
195
245
|
return;
|
|
196
246
|
}
|
|
197
247
|
await this._signalHandler.waitForTermination();
|
|
@@ -201,18 +251,25 @@ export class WatchOrchestrator {
|
|
|
201
251
|
* Shutdown Orchestrator
|
|
202
252
|
*/
|
|
203
253
|
async shutdown(): Promise<void> {
|
|
204
|
-
if (this._packages.length === 0) {
|
|
254
|
+
if (this._packages.length === 0 && this._watchHookPackages.length === 0) {
|
|
205
255
|
return;
|
|
206
256
|
}
|
|
207
257
|
|
|
208
258
|
process.stdout.write("⏳ Shutting down...\n");
|
|
209
259
|
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
260
|
+
const shutdownTasks: Array<Promise<void>> = [];
|
|
261
|
+
|
|
262
|
+
if (this._packages.length > 0) {
|
|
263
|
+
shutdownTasks.push(this._libraryBuilder.shutdown());
|
|
264
|
+
shutdownTasks.push(this._dtsBuilder.shutdown());
|
|
265
|
+
shutdownTasks.push(...this._copySrcWatchers.map((w) => w.close()));
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
shutdownTasks.push(...this._watchHookWatchers.map((w) => w.close()));
|
|
269
|
+
|
|
270
|
+
await Promise.all(shutdownTasks);
|
|
215
271
|
this._copySrcWatchers = [];
|
|
272
|
+
this._watchHookWatchers.length = 0;
|
|
216
273
|
this._replaceDepWatcher?.dispose();
|
|
217
274
|
|
|
218
275
|
process.stdout.write("✔ Done\n");
|
package/src/sd-config.types.ts
CHANGED
|
@@ -214,13 +214,27 @@ export interface SdServerPackageConfig {
|
|
|
214
214
|
}
|
|
215
215
|
|
|
216
216
|
/**
|
|
217
|
-
*
|
|
217
|
+
* Watch hook configuration for scripts packages
|
|
218
|
+
*/
|
|
219
|
+
export interface SdWatchHookConfig {
|
|
220
|
+
/** glob patterns to watch (relative to package directory) */
|
|
221
|
+
target: string[];
|
|
222
|
+
/** command to execute on change */
|
|
223
|
+
cmd: string;
|
|
224
|
+
/** command arguments */
|
|
225
|
+
args?: string[];
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
/**
|
|
229
|
+
* Scripts-only package configuration (excluded from watch/typecheck unless watch hook is configured)
|
|
218
230
|
*/
|
|
219
231
|
export interface SdScriptsPackageConfig {
|
|
220
232
|
/** build target */
|
|
221
233
|
target: "scripts";
|
|
222
234
|
/** publish configuration */
|
|
223
235
|
publish?: SdPublishConfig;
|
|
236
|
+
/** watch hook configuration (when set, package is included in watch mode) */
|
|
237
|
+
watch?: SdWatchHookConfig;
|
|
224
238
|
}
|
|
225
239
|
|
|
226
240
|
/**
|
|
@@ -107,8 +107,8 @@ export function filterPackagesByTargets(
|
|
|
107
107
|
for (const [name, config] of Object.entries(packages)) {
|
|
108
108
|
if (config == null) continue;
|
|
109
109
|
|
|
110
|
-
// Exclude scripts target
|
|
111
|
-
if (config.target === "scripts") continue;
|
|
110
|
+
// Exclude scripts target unless watch hook is configured
|
|
111
|
+
if (config.target === "scripts" && config.watch == null) continue;
|
|
112
112
|
|
|
113
113
|
// If targets is empty, include all packages
|
|
114
114
|
if (targets.length === 0) {
|
package/src/utils/vite-config.ts
CHANGED
|
@@ -293,6 +293,10 @@ export interface ViteConfigOptions {
|
|
|
293
293
|
replaceDeps?: string[];
|
|
294
294
|
/** Callback when replaceDeps package dist changes */
|
|
295
295
|
onScopeRebuild?: () => void;
|
|
296
|
+
/** Override build.outDir (e.g. ".capacitor/www" for Capacitor builds) */
|
|
297
|
+
outDir?: string;
|
|
298
|
+
/** Override base path (e.g. "./" for Capacitor builds) */
|
|
299
|
+
base?: string;
|
|
296
300
|
}
|
|
297
301
|
|
|
298
302
|
/**
|
|
@@ -319,7 +323,7 @@ export function createViteConfig(options: ViteConfigOptions): ViteUserConfig {
|
|
|
319
323
|
|
|
320
324
|
const config: ViteUserConfig = {
|
|
321
325
|
root: pkgDir,
|
|
322
|
-
base: `/${name}/`,
|
|
326
|
+
base: options.base ?? `/${name}/`,
|
|
323
327
|
plugins: [
|
|
324
328
|
tsconfigPaths({ projects: [tsconfigPath] }),
|
|
325
329
|
solidPlugin(),
|
|
@@ -358,6 +362,10 @@ export function createViteConfig(options: ViteConfigOptions): ViteUserConfig {
|
|
|
358
362
|
// Process.env substitution (applied to both build and dev modes)
|
|
359
363
|
config.define = envDefine;
|
|
360
364
|
|
|
365
|
+
if (options.outDir != null) {
|
|
366
|
+
config.build = { outDir: options.outDir };
|
|
367
|
+
}
|
|
368
|
+
|
|
361
369
|
if (mode === "build") {
|
|
362
370
|
config.logLevel = "silent";
|
|
363
371
|
} else {
|
|
@@ -126,6 +126,11 @@ async function build(info: ClientBuildInfo): Promise<ClientBuildResult> {
|
|
|
126
126
|
);
|
|
127
127
|
|
|
128
128
|
// Create Vite configuration and build
|
|
129
|
+
const isCapacitor = info.config.capacitor != null;
|
|
130
|
+
const outDir = isCapacitor
|
|
131
|
+
? path.join(info.pkgDir, ".capacitor", "www")
|
|
132
|
+
: undefined;
|
|
133
|
+
|
|
129
134
|
const viteConfig = createViteConfig({
|
|
130
135
|
pkgDir: info.pkgDir,
|
|
131
136
|
name: info.name,
|
|
@@ -133,12 +138,15 @@ async function build(info: ClientBuildInfo): Promise<ClientBuildResult> {
|
|
|
133
138
|
compilerOptions,
|
|
134
139
|
env: info.config.env,
|
|
135
140
|
mode: "build",
|
|
141
|
+
outDir,
|
|
142
|
+
base: isCapacitor ? "./" : undefined,
|
|
136
143
|
});
|
|
137
144
|
|
|
138
145
|
await viteBuild(viteConfig);
|
|
139
146
|
|
|
140
147
|
// Generate .config.json
|
|
141
|
-
const
|
|
148
|
+
const confDistDir = outDir ?? path.join(info.pkgDir, "dist");
|
|
149
|
+
const confDistPath = path.join(confDistDir, ".config.json");
|
|
142
150
|
fs.writeFileSync(confDistPath, JSON.stringify(info.config.configs ?? {}, undefined, 2));
|
|
143
151
|
|
|
144
152
|
return { success: true };
|
|
@@ -14,6 +14,7 @@ import { registerCleanupHandlers, applyDebugLevel } from "../utils/worker-utils"
|
|
|
14
14
|
export interface ServerRuntimeStartInfo {
|
|
15
15
|
mainJsPath: string;
|
|
16
16
|
clientPorts: Record<string, number>;
|
|
17
|
+
env?: Record<string, string>;
|
|
17
18
|
}
|
|
18
19
|
|
|
19
20
|
/**
|
|
@@ -113,6 +114,13 @@ async function start(info: ServerRuntimeStartInfo): Promise<void> {
|
|
|
113
114
|
try {
|
|
114
115
|
const startTime = performance.now();
|
|
115
116
|
|
|
117
|
+
// Inject environment variables into process.env before importing main.js
|
|
118
|
+
if (info.env != null) {
|
|
119
|
+
for (const [key, value] of Object.entries(info.env)) {
|
|
120
|
+
process.env[key] = value;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
116
124
|
// Import main.js (must export a server instance)
|
|
117
125
|
logger.debug("[start] Importing main.js...");
|
|
118
126
|
let stepStart = performance.now();
|
|
@@ -16,19 +16,18 @@
|
|
|
16
16
|
"check": "sd-cli check",
|
|
17
17
|
"test": "vitest run",
|
|
18
18
|
"test:e2e": "vitest run -c vitest-e2e.config.ts",
|
|
19
|
-
"postinstall": "playwright
|
|
19
|
+
"postinstall": "playwright-cli install --skills"
|
|
20
20
|
},
|
|
21
21
|
"devDependencies": {
|
|
22
|
-
"@simplysm/lint": "~13.0.
|
|
23
|
-
"@simplysm/sd-cli": "~13.0.
|
|
24
|
-
"@simplysm/sd-claude": "~13.0.
|
|
22
|
+
"@simplysm/lint": "~13.0.97",
|
|
23
|
+
"@simplysm/sd-cli": "~13.0.97",
|
|
24
|
+
"@simplysm/sd-claude": "~13.0.97",
|
|
25
|
+
"@playwright/cli": "^0.1.1",
|
|
25
26
|
"@types/node": "^20.19.37",
|
|
26
27
|
"eslint": "^9.39.4",
|
|
27
28
|
"prettier": "^3.8.1",
|
|
28
29
|
"typescript": "^5.9.3",
|
|
29
30
|
"vite-tsconfig-paths": "^6.1.1",
|
|
30
31
|
"vitest": "^4.1.0",
|
|
31
|
-
"@playwright/cli": "^0.1.1",
|
|
32
|
-
"playwright": "^1.58.2"
|
|
33
32
|
}
|
|
34
33
|
}
|
|
@@ -6,13 +6,13 @@
|
|
|
6
6
|
"private": true,
|
|
7
7
|
"dependencies": {
|
|
8
8
|
"@{{projectName}}/db-main": "workspace:*",
|
|
9
|
-
"@simplysm/core-browser": "~13.0.
|
|
10
|
-
"@simplysm/core-common": "~13.0.
|
|
11
|
-
"@simplysm/excel": "~13.0.
|
|
12
|
-
"@simplysm/orm-common": "~13.0.
|
|
13
|
-
"@simplysm/service-client": "~13.0.
|
|
14
|
-
"@simplysm/service-common": "~13.0.
|
|
15
|
-
"@simplysm/solid": "~13.0.
|
|
9
|
+
"@simplysm/core-browser": "~13.0.97",
|
|
10
|
+
"@simplysm/core-common": "~13.0.97",
|
|
11
|
+
"@simplysm/excel": "~13.0.97",
|
|
12
|
+
"@simplysm/orm-common": "~13.0.97",
|
|
13
|
+
"@simplysm/service-client": "~13.0.97",
|
|
14
|
+
"@simplysm/service-common": "~13.0.97",
|
|
15
|
+
"@simplysm/solid": "~13.0.97",
|
|
16
16
|
"@solid-primitives/event-listener": "^2.4.5",
|
|
17
17
|
"@solidjs/router": "^0.15.4",
|
|
18
18
|
"@tabler/icons-solidjs": "^3.40.0",
|
|
@@ -5,11 +5,11 @@
|
|
|
5
5
|
"private": true,
|
|
6
6
|
"dependencies": {
|
|
7
7
|
"@{{projectName}}/db-main": "workspace:*",
|
|
8
|
-
"@simplysm/core-common": "~13.0.
|
|
9
|
-
"@simplysm/excel": "~13.0.
|
|
10
|
-
"@simplysm/orm-common": "~13.0.
|
|
11
|
-
"@simplysm/orm-node": "~13.0.
|
|
12
|
-
"@simplysm/service-server": "~13.0.
|
|
8
|
+
"@simplysm/core-common": "~13.0.97",
|
|
9
|
+
"@simplysm/excel": "~13.0.97",
|
|
10
|
+
"@simplysm/orm-common": "~13.0.97",
|
|
11
|
+
"@simplysm/orm-node": "~13.0.97",
|
|
12
|
+
"@simplysm/service-server": "~13.0.97",
|
|
13
13
|
"bcrypt": "^6.0.0",
|
|
14
14
|
"pg": "^8.20.0",
|
|
15
15
|
"pg-copy-streams": "^7.0.0"
|
package/tests/run-watch.spec.ts
CHANGED
|
@@ -38,4 +38,39 @@ describe("filterPackagesByTargets", () => {
|
|
|
38
38
|
expect(result["core-node"]).toEqual({ target: "node" });
|
|
39
39
|
});
|
|
40
40
|
|
|
41
|
+
it("includes scripts target when watch option is present", () => {
|
|
42
|
+
const packagesWithWatch: Record<string, SdPackageConfig | undefined> = {
|
|
43
|
+
...mockPackages,
|
|
44
|
+
"claude-with-watch": {
|
|
45
|
+
target: "scripts",
|
|
46
|
+
watch: {
|
|
47
|
+
target: ["../../.claude/rules/sd-*"],
|
|
48
|
+
cmd: "node",
|
|
49
|
+
args: ["scripts/sync.mjs"],
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
};
|
|
53
|
+
const result = filterPackagesByTargets(packagesWithWatch, []);
|
|
54
|
+
|
|
55
|
+
expect(result["claude-with-watch"]).toBeDefined();
|
|
56
|
+
expect(result["claude"]).toBeUndefined(); // scripts without watch still excluded
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
it("includes scripts+watch target when specified in targets", () => {
|
|
60
|
+
const packagesWithWatch: Record<string, SdPackageConfig | undefined> = {
|
|
61
|
+
...mockPackages,
|
|
62
|
+
"claude-with-watch": {
|
|
63
|
+
target: "scripts",
|
|
64
|
+
watch: {
|
|
65
|
+
target: ["../../.claude/rules/sd-*"],
|
|
66
|
+
cmd: "node",
|
|
67
|
+
},
|
|
68
|
+
},
|
|
69
|
+
};
|
|
70
|
+
const result = filterPackagesByTargets(packagesWithWatch, ["claude-with-watch"]);
|
|
71
|
+
|
|
72
|
+
expect(Object.keys(result)).toHaveLength(1);
|
|
73
|
+
expect(result["claude-with-watch"]).toBeDefined();
|
|
74
|
+
});
|
|
75
|
+
|
|
41
76
|
});
|