@walkeros/cli 0.3.6 → 0.4.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.
- package/CHANGELOG.md +22 -0
- package/dist/__tests__/bundle/bundler-helpers.test.d.ts +2 -0
- package/dist/__tests__/bundle/bundler-helpers.test.d.ts.map +1 -0
- package/dist/__tests__/bundle/bundler-helpers.test.js +285 -0
- package/dist/__tests__/bundle/bundler-helpers.test.js.map +1 -0
- package/dist/__tests__/bundle/bundler.test.js +9 -3
- package/dist/__tests__/bundle/bundler.test.js.map +1 -1
- package/dist/__tests__/bundle/programmatic.test.js +5 -1
- package/dist/__tests__/bundle/programmatic.test.js.map +1 -1
- package/dist/__tests__/bundle/serializer.test.js +1 -1
- package/dist/__tests__/bundle/serializer.test.js.map +1 -1
- package/dist/__tests__/bundle/template-engine.test.js +1 -1
- package/dist/__tests__/bundle/template-engine.test.js.map +1 -1
- package/dist/__tests__/cli.test.js +6 -71
- package/dist/__tests__/cli.test.js.map +1 -1
- package/dist/__tests__/config-loader.test.js +8 -5
- package/dist/__tests__/config-loader.test.js.map +1 -1
- package/dist/__tests__/core/config.test.js +1 -1
- package/dist/__tests__/core/config.test.js.map +1 -1
- package/dist/__tests__/core/logger.test.js +1 -1
- package/dist/__tests__/core/logger.test.js.map +1 -1
- package/dist/__tests__/integration/bundle-run.integration.test.d.ts +8 -0
- package/dist/__tests__/integration/bundle-run.integration.test.d.ts.map +1 -0
- package/dist/__tests__/integration/bundle-run.integration.test.js +50 -0
- package/dist/__tests__/integration/bundle-run.integration.test.js.map +1 -0
- package/dist/__tests__/push/push.test.d.ts +7 -0
- package/dist/__tests__/push/push.test.d.ts.map +1 -0
- package/dist/__tests__/push/push.test.js +197 -0
- package/dist/__tests__/push/push.test.js.map +1 -0
- package/dist/__tests__/simulate/env-loader.test.d.ts +2 -0
- package/dist/__tests__/simulate/env-loader.test.d.ts.map +1 -0
- package/dist/__tests__/simulate/env-loader.test.js +47 -0
- package/dist/__tests__/simulate/env-loader.test.js.map +1 -0
- package/dist/__tests__/smoke/production.smoke.test.d.ts +8 -0
- package/dist/__tests__/smoke/production.smoke.test.d.ts.map +1 -0
- package/dist/__tests__/smoke/production.smoke.test.js +58 -0
- package/dist/__tests__/smoke/production.smoke.test.js.map +1 -0
- package/dist/commands/bundle/bundler.d.ts +2 -2
- package/dist/commands/bundle/bundler.d.ts.map +1 -1
- package/dist/commands/bundle/bundler.js +70 -58
- package/dist/commands/bundle/bundler.js.map +1 -1
- package/dist/commands/bundle/index.d.ts +1 -1
- package/dist/commands/bundle/index.d.ts.map +1 -1
- package/dist/commands/bundle/index.js +11 -23
- package/dist/commands/bundle/index.js.map +1 -1
- package/dist/commands/bundle/package-manager.d.ts +1 -1
- package/dist/commands/bundle/package-manager.d.ts.map +1 -1
- package/dist/commands/bundle/serializer.d.ts +1 -1
- package/dist/commands/bundle/serializer.d.ts.map +1 -1
- package/dist/commands/bundle/serializer.js +1 -1
- package/dist/commands/bundle/serializer.js.map +1 -1
- package/dist/commands/bundle/stats.d.ts +2 -2
- package/dist/commands/bundle/stats.d.ts.map +1 -1
- package/dist/commands/bundle/stats.js +1 -1
- package/dist/commands/bundle/stats.js.map +1 -1
- package/dist/commands/bundle/template-engine.d.ts +1 -1
- package/dist/commands/bundle/template-engine.d.ts.map +1 -1
- package/dist/commands/bundle/template-engine.js +4 -2
- package/dist/commands/bundle/template-engine.js.map +1 -1
- package/dist/commands/push/index.d.ts +7 -0
- package/dist/commands/push/index.d.ts.map +1 -0
- package/dist/commands/push/index.js +252 -0
- package/dist/commands/push/index.js.map +1 -0
- package/dist/commands/push/types.d.ts +21 -0
- package/dist/commands/push/types.d.ts.map +1 -0
- package/dist/commands/push/types.js +2 -0
- package/dist/commands/push/types.js.map +1 -0
- package/dist/commands/run/__tests__/run.integration.test.js +1 -1
- package/dist/commands/run/__tests__/run.integration.test.js.map +1 -1
- package/dist/commands/run/__tests__/validators.test.js +1 -1
- package/dist/commands/run/__tests__/validators.test.js.map +1 -1
- package/dist/commands/run/execution.d.ts +14 -0
- package/dist/commands/run/execution.d.ts.map +1 -0
- package/dist/commands/run/execution.js +37 -0
- package/dist/commands/run/execution.js.map +1 -0
- package/dist/commands/run/index.d.ts +1 -1
- package/dist/commands/run/index.d.ts.map +1 -1
- package/dist/commands/run/index.js +33 -107
- package/dist/commands/run/index.js.map +1 -1
- package/dist/commands/run/types.d.ts +1 -1
- package/dist/commands/run/types.d.ts.map +1 -1
- package/dist/commands/run/utils.d.ts +26 -0
- package/dist/commands/run/utils.d.ts.map +1 -0
- package/dist/commands/run/utils.js +58 -0
- package/dist/commands/run/utils.js.map +1 -0
- package/dist/commands/run/validators.d.ts +1 -1
- package/dist/commands/run/validators.d.ts.map +1 -1
- package/dist/commands/run/validators.js +1 -1
- package/dist/commands/run/validators.js.map +1 -1
- package/dist/commands/simulate/env-loader.d.ts +19 -0
- package/dist/commands/simulate/env-loader.d.ts.map +1 -0
- package/dist/commands/simulate/env-loader.js +46 -0
- package/dist/commands/simulate/env-loader.js.map +1 -0
- package/dist/commands/simulate/index.d.ts +3 -3
- package/dist/commands/simulate/index.d.ts.map +1 -1
- package/dist/commands/simulate/index.js +14 -20
- package/dist/commands/simulate/index.js.map +1 -1
- package/dist/commands/simulate/jsdom-executor.d.ts +37 -0
- package/dist/commands/simulate/jsdom-executor.d.ts.map +1 -0
- package/dist/commands/simulate/jsdom-executor.js +137 -0
- package/dist/commands/simulate/jsdom-executor.js.map +1 -0
- package/dist/commands/simulate/simulator.d.ts +1 -5
- package/dist/commands/simulate/simulator.d.ts.map +1 -1
- package/dist/commands/simulate/simulator.js +33 -111
- package/dist/commands/simulate/simulator.js.map +1 -1
- package/dist/commands/simulate/types.d.ts +2 -2
- package/dist/commands/simulate/types.d.ts.map +1 -1
- package/dist/config/defaults.d.ts +1 -1
- package/dist/config/defaults.d.ts.map +1 -1
- package/dist/config/defaults.js +0 -1
- package/dist/config/defaults.js.map +1 -1
- package/dist/config/index.d.ts +8 -8
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/index.js +5 -5
- package/dist/config/index.js.map +1 -1
- package/dist/config/loader.d.ts +1 -1
- package/dist/config/loader.d.ts.map +1 -1
- package/dist/config/loader.js +23 -19
- package/dist/config/loader.js.map +1 -1
- package/dist/config/parser.d.ts +65 -1
- package/dist/config/parser.d.ts.map +1 -1
- package/dist/config/parser.js +176 -62
- package/dist/config/parser.js.map +1 -1
- package/dist/config/utils.d.ts +46 -0
- package/dist/config/utils.d.ts.map +1 -1
- package/dist/config/utils.js +103 -0
- package/dist/config/utils.js.map +1 -1
- package/dist/config/validators.d.ts +4 -1
- package/dist/config/validators.d.ts.map +1 -1
- package/dist/config/validators.js +4 -2
- package/dist/config/validators.js.map +1 -1
- package/dist/core/asset-resolver.d.ts.map +1 -1
- package/dist/core/asset-resolver.js +10 -3
- package/dist/core/asset-resolver.js.map +1 -1
- package/dist/core/docker.d.ts +17 -1
- package/dist/core/docker.d.ts.map +1 -1
- package/dist/core/docker.js +22 -1
- package/dist/core/docker.js.map +1 -1
- package/dist/core/execution.d.ts +2 -2
- package/dist/core/execution.d.ts.map +1 -1
- package/dist/core/execution.js +1 -1
- package/dist/core/execution.js.map +1 -1
- package/dist/core/index.d.ts +8 -6
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +8 -6
- package/dist/core/index.js.map +1 -1
- package/dist/core/logger.d.ts +11 -0
- package/dist/core/logger.d.ts.map +1 -1
- package/dist/core/logger.js +14 -0
- package/dist/core/logger.js.map +1 -1
- package/dist/core/temp-manager.d.ts +51 -0
- package/dist/core/temp-manager.d.ts.map +1 -0
- package/dist/core/temp-manager.js +73 -0
- package/dist/core/temp-manager.js.map +1 -0
- package/dist/core/utils.d.ts +10 -0
- package/dist/core/utils.d.ts.map +1 -0
- package/dist/core/utils.js +12 -0
- package/dist/core/utils.js.map +1 -0
- package/dist/index.d.ts +42 -13
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +827 -397
- package/dist/index.js.map +1 -1
- package/dist/types/bundle.d.ts +26 -12
- package/dist/types/bundle.d.ts.map +1 -1
- package/dist/types/index.d.ts +2 -2
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +2 -2
- package/dist/types/index.js.map +1 -1
- package/examples/.npm-cache/content-v2/sha512/0d/2d/7581c288670eaf8538ddd9df145b78756ce3be0791c6e0b9cd33429b3bae894525b9bda287a3cedffbcdd2c7b3107bafc03f2b0367eea489eee1cc042abb +1 -0
- package/examples/.npm-cache/content-v2/sha512/12/20/bc4f5acca143809f7e07da1fdafb38137d93243de4d5b403e6e10b92d0d3a6e51eab24fe9dbc9d3ed1cd72e8f7a406085e99c422bb2c7d1166cf9f1f564e +0 -0
- package/examples/.npm-cache/content-v2/sha512/22/ee/fb2695b01871c1d36946bdcfb49f1b520a57200d0a0b221b1e7d5f047ab38a8b2ab0e5f0e25a00acde1f3f2f9d24430a18f1092d438bc1a9e9891cc45f75 +0 -0
- package/examples/.npm-cache/content-v2/sha512/24/89/da1ce6a61bca6de7e132f241a675c01c83738bf6b78af25b5cce01d3030361332b3fe938571e2b721f1555da9ddf930fdcf8c02f0471556071590e68cc09 +0 -0
- package/examples/.npm-cache/content-v2/sha512/47/fd/c6be997da99228c3e279b95d4a46d6913947078a178f54ac71795a159f3513b1483232f4c2d0a1f403178bf9f96bb19615de32a9e2133e949880c6bc15e2 +0 -0
- package/examples/.npm-cache/content-v2/sha512/4b/1c/c1cb7f8b32102071a89fef97158daa32080ebaedfbbd596880d2213d84e305abc76d2a95a412ded55c1c3d487adcb1ceff87fc2c85d7e2856ebd9d3f16f3 +0 -0
- package/examples/.npm-cache/content-v2/sha512/6e/53/ff864769671f44f39d8a3bf904cd646535b745cc4824a8bb3189193b474678049f43b5178ba15cad7f0289046105e70f1565afc84e907120b35a466690fd +1 -0
- package/examples/.npm-cache/content-v2/sha512/70/4c/4c8837d446965c5551b4ea527e95fa011744fb727581d82cf35bb5599ea0b57d18baa490f7af93ef9a16e8e45e5c0802737da20575f4056a4a5c9a3cd288 +0 -0
- package/examples/.npm-cache/content-v2/sha512/96/ad/05de3bbb12d7de8ea353f962bdaea7d2eb44f707f2973462a6635daf537c67b46cca7764fed7d464fe62152c3f783a07aba1ceb35e09ad446bff05a4b466 +1 -0
- package/examples/.npm-cache/content-v2/sha512/b5/20/52dde94e6cef7170f6089c64a4843e57be18be450d956f4e455905aed047ae6a368451c93035e6ac3ee59576b600f03f815afba0836b3a16e10a9aaca4ba +1 -0
- package/examples/.npm-cache/content-v2/sha512/c7/a9/d166a1c39f97df312c59261319ba1cf9aac178bda0a0cb697d5ddd78bd8dd38ef1bf40017bcc8633c2049896c2d70696d9bff9280851f270792ff38bb3a0 +1 -0
- package/examples/.npm-cache/content-v2/sha512/e0/d0/8c14083b633e6adbd3c6a93da5fc0f6bbd456c5512ef276920bedd8d85d551052adff992de977aff326616a211aaa2d6ddcc801149e9b7f914f566359b6a +1 -0
- package/examples/.npm-cache/content-v2/sha512/e7/c5/06ad3fd79ac4f1031fe0b16ea5e54e232ca397bbcd7592c679021cbfb027276099f8c848f3f7a7691f0102ad53aa64f9141e61d729b037a678bd60440d17 +1 -0
- package/examples/.npm-cache/content-v2/sha512/f3/28/d5d32329604ed7d471a4949105daa2cc98858cf24f45b0b97c41d0eb0d5a9fe7bf1f69c792161cc6693e4fc1b52e886ac41875ebfb8fe47fafe417ca3e6e +0 -0
- package/examples/.npm-cache/index-v5/04/5a/2b5d7a7c407d85d746baa0f5c9388a333e35a717a8a0a81943daa6cb1364 +3 -0
- package/examples/.npm-cache/index-v5/12/9a/eba560cbace295d8ee04cf283015377bd77b379e70968fb6bc407c7fc410 +15 -0
- package/examples/.npm-cache/index-v5/2f/a2/7b047564b0ee21ac835ec609e89153dd6549be554d098584d5bfd19fe043 +15 -0
- package/examples/.npm-cache/index-v5/32/8e/322d58dd8d1e000be248ada51385bf96288e56039de9feec1a4c6a467653 +3 -0
- package/examples/.npm-cache/index-v5/57/93/d1d7cd1402e3e26468db03f2870822bb2c9018a506cdfb3b405f38cd3e1c +3 -0
- package/examples/.npm-cache/index-v5/5d/f8/0a1f4fa7149e4ff33e09eb6aea41ac8d1730c868a5d3ace91f762698acff +3 -0
- package/examples/.npm-cache/index-v5/69/a4/a92c72d838259b051cdf8e0acfb2bc680b6d4cfc642314a7836c3f7b2c50 +15 -0
- package/examples/.npm-cache/index-v5/71/31/6da3423bb203f3de5eb16c942431073f89be2cfcb40058ec91dcb5ce0abc +15 -0
- package/examples/.npm-cache/index-v5/7b/94/72b6bffa050d9ef52a558dd220663695bc606f756be0dfa196ef4f3913ba +3 -0
- package/examples/.npm-cache/index-v5/85/9e/99e97fdd562517e56285337db91d1a8f2f416b8d631cf4d7d754fa671299 +15 -0
- package/examples/.npm-cache/index-v5/92/4c/9416ada81a9b3c679539fd1ab53f8de3d41ff268f35eba7a194389a85b06 +3 -0
- package/examples/.npm-cache/index-v5/c1/5a/13df76b218deed8a6ef12961116af5183db98c53fad1b922fd9edc075247 +3 -0
- package/examples/.npm-cache/index-v5/cb/11/253c55410a8ab7c4a9ea9d6e1bf8ef1450a581da64c478074dfd82c8bff6 +3 -0
- package/examples/.npm-cache/index-v5/d5/ae/b57fad3a62b5ba2dbdf24b042a9e7b70820f3db00e5a630f02e1fea020dc +3 -0
- package/examples/.npm-cache/index-v5/d6/32/2f620f83c7d14451de98de8298c2408e05a16cc0829bd16c891ac19d7a67 +3 -0
- package/examples/.npm-cache/index-v5/dd/b5/01dc7a3cd8b6a03a69aee9af500d51ae19cb0aa12631a4aafd152148b8e5 +15 -0
- package/examples/.npm-cache/index-v5/e0/cf/6b862c15d74630d3871cd813d305210ab741311deb10baf8813014e0bc30 +3 -0
- package/examples/.npm-cache/index-v5/e2/be/e880ccd35950a814d3c1dded34d3938ac61b15a195321dc51357f801aad4 +15 -0
- package/examples/.npm-cache/index-v5/e5/1f/f4affe0b392cd03288f23cc03abcb274ff11a2c8f8965299de681914abb2 +3 -0
- package/examples/.npm-cache/index-v5/f3/5b/9ebe450958ff0d7cc44ab0a00080cb8a3ff1389744b5eab5f97b68a6a6af +3 -0
- package/examples/.npm-cache/index-v5/fb/c1/0de405e902866d53e7c30cf36a97dc2578838622b261816f44dc377c9a80 +3 -0
- package/examples/README.md +4 -4
- package/examples/event.json +53 -0
- package/examples/flow-order-complete.json +68 -0
- package/examples/flow-simple.json +32 -0
- package/examples/flow.json +82 -0
- package/examples/server-collect.mjs +1360 -1190
- package/examples/test.html +43 -0
- package/examples/web-serve.js +25503 -0
- package/examples/web-serve.json +4 -3
- package/package.json +3 -2
- package/templates/server.hbs +2 -2
- package/templates/web.hbs +12 -11
- package/dist/__tests__/bundle/bundler-integration.test.d.ts +0 -2
- package/dist/__tests__/bundle/bundler-integration.test.d.ts.map +0 -1
- package/dist/__tests__/bundle/bundler-integration.test.js +0 -106
- package/dist/__tests__/bundle/bundler-integration.test.js.map +0 -1
- package/dist/__tests__/simulate/programmatic.test.d.ts +0 -2
- package/dist/__tests__/simulate/programmatic.test.d.ts.map +0 -1
- package/dist/__tests__/simulate/programmatic.test.js +0 -51
- package/dist/__tests__/simulate/programmatic.test.js.map +0 -1
- package/dist/__tests__/simulate/simulator.test.d.ts +0 -2
- package/dist/__tests__/simulate/simulator.test.d.ts.map +0 -1
- package/dist/__tests__/simulate/simulator.test.js +0 -29
- package/dist/__tests__/simulate/simulator.test.js.map +0 -1
- package/examples/web-serve.mjs +0 -19456
package/dist/index.js
CHANGED
|
@@ -77,6 +77,13 @@ function createLogger(options = {}) {
|
|
|
77
77
|
}
|
|
78
78
|
};
|
|
79
79
|
}
|
|
80
|
+
function createCommandLogger(options) {
|
|
81
|
+
return createLogger({
|
|
82
|
+
verbose: options.verbose,
|
|
83
|
+
silent: options.silent ?? false,
|
|
84
|
+
json: options.json
|
|
85
|
+
});
|
|
86
|
+
}
|
|
80
87
|
|
|
81
88
|
// src/core/timer.ts
|
|
82
89
|
function createTimer() {
|
|
@@ -200,6 +207,59 @@ function getTempDir(tempDir = ".tmp") {
|
|
|
200
207
|
const basePath = path.isAbsolute(tempDir) ? tempDir : path.join(process.cwd(), tempDir);
|
|
201
208
|
return path.join(basePath, `cli-${Date.now()}-${randomId}`);
|
|
202
209
|
}
|
|
210
|
+
async function loadJsonFromSource(source, options) {
|
|
211
|
+
const paramName = options?.name || "input";
|
|
212
|
+
if (!source || source.trim() === "") {
|
|
213
|
+
if (options?.required) {
|
|
214
|
+
throw new Error(`${paramName} is required`);
|
|
215
|
+
}
|
|
216
|
+
if (options?.fallback !== void 0) {
|
|
217
|
+
return options.fallback;
|
|
218
|
+
}
|
|
219
|
+
return {};
|
|
220
|
+
}
|
|
221
|
+
const trimmedSource = source.trim();
|
|
222
|
+
if (isUrl(trimmedSource)) {
|
|
223
|
+
try {
|
|
224
|
+
const tempPath = await downloadFromUrl(trimmedSource);
|
|
225
|
+
try {
|
|
226
|
+
const data = await fs.readJson(tempPath);
|
|
227
|
+
return data;
|
|
228
|
+
} finally {
|
|
229
|
+
try {
|
|
230
|
+
await fs.remove(tempPath);
|
|
231
|
+
} catch {
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
} catch (error) {
|
|
235
|
+
throw new Error(
|
|
236
|
+
`Failed to load ${paramName} from URL ${trimmedSource}: ${getErrorMessage(error)}`
|
|
237
|
+
);
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
const resolvedPath = path.resolve(trimmedSource);
|
|
241
|
+
if (await fs.pathExists(resolvedPath)) {
|
|
242
|
+
try {
|
|
243
|
+
const data = await fs.readJson(resolvedPath);
|
|
244
|
+
return data;
|
|
245
|
+
} catch (error) {
|
|
246
|
+
throw new Error(
|
|
247
|
+
`Failed to parse ${paramName} from file ${trimmedSource}: ${getErrorMessage(error)}`
|
|
248
|
+
);
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
try {
|
|
252
|
+
const parsed = JSON.parse(trimmedSource);
|
|
253
|
+
return parsed;
|
|
254
|
+
} catch (jsonError) {
|
|
255
|
+
if (!trimmedSource.startsWith("{") && !trimmedSource.startsWith("[")) {
|
|
256
|
+
return { name: trimmedSource };
|
|
257
|
+
}
|
|
258
|
+
throw new Error(
|
|
259
|
+
`Failed to parse ${paramName}. Input appears to be JSON but contains errors: ${jsonError instanceof Error ? jsonError.message : String(jsonError)}`
|
|
260
|
+
);
|
|
261
|
+
}
|
|
262
|
+
}
|
|
203
263
|
|
|
204
264
|
// src/core/docker.ts
|
|
205
265
|
function readPackageVersion() {
|
|
@@ -218,6 +278,13 @@ function readPackageVersion() {
|
|
|
218
278
|
var CLI_VERSION = readPackageVersion();
|
|
219
279
|
var CLI_DOCKER_IMAGE = process.env.WALKEROS_CLI_DOCKER_IMAGE || `walkeros/cli:${CLI_VERSION}`;
|
|
220
280
|
var RUNTIME_DOCKER_IMAGE = process.env.WALKEROS_RUNTIME_DOCKER_IMAGE || `walkeros/docker:${DOCKER_VERSION}`;
|
|
281
|
+
function buildCommonDockerArgs(options) {
|
|
282
|
+
const args = [options.config];
|
|
283
|
+
if (options.json) args.push("--json");
|
|
284
|
+
if (options.verbose) args.push("--verbose");
|
|
285
|
+
if (options.silent) args.push("--silent");
|
|
286
|
+
return args;
|
|
287
|
+
}
|
|
221
288
|
function buildDockerCommand(command, args, options = {}, configFile) {
|
|
222
289
|
const cwd = process.cwd();
|
|
223
290
|
const cmd = ["docker", "run", "--rm"];
|
|
@@ -380,6 +447,10 @@ async function executeCommand(localHandler, dockerCommand, dockerArgs, options,
|
|
|
380
447
|
}
|
|
381
448
|
}
|
|
382
449
|
|
|
450
|
+
// src/core/temp-manager.ts
|
|
451
|
+
import { getHashServer } from "@walkeros/server-core";
|
|
452
|
+
import fs2 from "fs-extra";
|
|
453
|
+
|
|
383
454
|
// src/core/asset-resolver.ts
|
|
384
455
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
385
456
|
import path3 from "path";
|
|
@@ -389,6 +460,10 @@ function getPackageRoot() {
|
|
|
389
460
|
const srcIndex = currentFile.indexOf("/src/");
|
|
390
461
|
return currentFile.substring(0, srcIndex);
|
|
391
462
|
}
|
|
463
|
+
if (currentFile.includes("/dist/")) {
|
|
464
|
+
const distIndex = currentFile.indexOf("/dist/");
|
|
465
|
+
return currentFile.substring(0, distIndex);
|
|
466
|
+
}
|
|
392
467
|
return path3.resolve(currentFile, "../..");
|
|
393
468
|
}
|
|
394
469
|
function resolveAsset(assetPath, assetType, baseDir) {
|
|
@@ -406,6 +481,11 @@ function resolveAsset(assetPath, assetType, baseDir) {
|
|
|
406
481
|
return path3.resolve(resolveBase, assetPath);
|
|
407
482
|
}
|
|
408
483
|
|
|
484
|
+
// src/core/utils.ts
|
|
485
|
+
function getErrorMessage(error) {
|
|
486
|
+
return error instanceof Error ? error.message : String(error);
|
|
487
|
+
}
|
|
488
|
+
|
|
409
489
|
// src/config/validators.ts
|
|
410
490
|
function isObject(value) {
|
|
411
491
|
return typeof value === "object" && value !== null && !Array.isArray(value) && Object.prototype.toString.call(value) === "[object Object]";
|
|
@@ -417,94 +497,79 @@ function isMultiEnvConfig(data) {
|
|
|
417
497
|
return isObject(data) && "version" in data && data.version === 1 && "environments" in data && isObject(data.environments);
|
|
418
498
|
}
|
|
419
499
|
function isSingleEnvConfig(data) {
|
|
420
|
-
return isObject(data) && "flow" in data && "build" in data && isObject(data.flow) && isObject(data.build) && "platform" in data.flow
|
|
500
|
+
return isObject(data) && "flow" in data && "build" in data && isObject(data.flow) && isObject(data.build) && "platform" in data.flow;
|
|
421
501
|
}
|
|
422
502
|
|
|
423
|
-
// src/config/
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
503
|
+
// src/config/parser.ts
|
|
504
|
+
import path4 from "path";
|
|
505
|
+
function parseConfigStructure(rawConfig, options = {}) {
|
|
506
|
+
if (isMultiEnvConfig(rawConfig)) {
|
|
507
|
+
const setup = rawConfig;
|
|
508
|
+
const availableEnvironments = Object.keys(setup.environments);
|
|
509
|
+
if (!options.environment) {
|
|
510
|
+
throw new Error(
|
|
511
|
+
`Multi-environment configuration detected. Please specify an environment using --env flag.
|
|
512
|
+
Available environments: ${availableEnvironments.join(", ")}`
|
|
513
|
+
);
|
|
514
|
+
}
|
|
515
|
+
const selectedEnv = options.environment;
|
|
516
|
+
if (!setup.environments[selectedEnv]) {
|
|
517
|
+
throw new Error(
|
|
518
|
+
`Environment "${selectedEnv}" not found in configuration.
|
|
519
|
+
Available environments: ${availableEnvironments.join(", ")}`
|
|
520
|
+
);
|
|
521
|
+
}
|
|
522
|
+
const envConfig = setup.environments[selectedEnv];
|
|
433
523
|
return {
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
524
|
+
flowConfig: envConfig.flow,
|
|
525
|
+
buildOptions: envConfig.build,
|
|
526
|
+
metadata: {
|
|
527
|
+
environment: selectedEnv,
|
|
528
|
+
isMultiEnvironment: true,
|
|
529
|
+
availableEnvironments
|
|
530
|
+
}
|
|
440
531
|
};
|
|
441
532
|
}
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
flowPlatform,
|
|
453
|
-
buildOptions.code || "",
|
|
454
|
-
buildOptions.output
|
|
455
|
-
);
|
|
456
|
-
if (!buildOptions.output && !defaults.output) {
|
|
457
|
-
throw new Error("BuildOptions.output is required");
|
|
533
|
+
if (isSingleEnvConfig(rawConfig)) {
|
|
534
|
+
const config = rawConfig;
|
|
535
|
+
return {
|
|
536
|
+
flowConfig: config.flow,
|
|
537
|
+
buildOptions: config.build,
|
|
538
|
+
metadata: {
|
|
539
|
+
environment: "default",
|
|
540
|
+
isMultiEnvironment: false
|
|
541
|
+
}
|
|
542
|
+
};
|
|
458
543
|
}
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
packages: buildOptions.packages || defaults.packages
|
|
465
|
-
};
|
|
466
|
-
}
|
|
544
|
+
const configPath = options.configPath || "configuration";
|
|
545
|
+
const configType = isObject(rawConfig) ? "platform" in rawConfig ? `invalid platform value: "${rawConfig.platform}"` : 'missing "flow" and "build" fields' : `not an object (got ${typeof rawConfig})`;
|
|
546
|
+
throw new Error(
|
|
547
|
+
`Invalid configuration format at ${configPath}.
|
|
548
|
+
Configuration ${configType}.
|
|
467
549
|
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
if (!(
|
|
475
|
-
throw new Error(
|
|
476
|
-
`Invalid config: missing "flow" field. Expected format: { flow: { platform: "web" | "server", ... }, build: { ... } }`
|
|
477
|
-
);
|
|
478
|
-
}
|
|
479
|
-
if (!("build" in data) || !isObject(data.build)) {
|
|
480
|
-
throw new Error(
|
|
481
|
-
`Invalid config: missing "build" field. Expected format: { flow: { platform: "web" | "server", ... }, build: { ... } }`
|
|
482
|
-
);
|
|
483
|
-
}
|
|
484
|
-
const flowData = data.flow;
|
|
485
|
-
if (!("platform" in flowData) || flowData.platform !== "web" && flowData.platform !== "server") {
|
|
486
|
-
throw new Error(
|
|
487
|
-
`Invalid config: flow.platform must be "web" or "server", got "${flowData.platform}"`
|
|
488
|
-
);
|
|
489
|
-
}
|
|
490
|
-
const buildData = data.build;
|
|
491
|
-
if ("packages" in buildData && !isObject(buildData.packages)) {
|
|
550
|
+
Expected either:
|
|
551
|
+
1. Multi-environment: { version: 1, environments: { prod: { flow: {...}, build: {...} } } }
|
|
552
|
+
2. Single-environment: { flow: { platform: "web" | "server", ... }, build: { packages: {...}, ... } }`
|
|
553
|
+
);
|
|
554
|
+
}
|
|
555
|
+
function normalizeAndValidate(flowConfig, buildOptions, configPath) {
|
|
556
|
+
if (!isObject(flowConfig) || !("platform" in flowConfig)) {
|
|
492
557
|
throw new Error(
|
|
493
|
-
`Invalid config:
|
|
558
|
+
`Invalid flow config: missing "platform" field. Expected "web" or "server".`
|
|
494
559
|
);
|
|
495
560
|
}
|
|
496
|
-
const config = data;
|
|
497
|
-
return normalizeConfigs(config, "/unknown/path");
|
|
498
|
-
}
|
|
499
|
-
function normalizeConfigs(config, configPath) {
|
|
500
|
-
const flowConfig = config.flow;
|
|
501
561
|
const platform = flowConfig.platform;
|
|
502
562
|
if (!validatePlatform(platform)) {
|
|
503
563
|
throw new Error(
|
|
504
564
|
`Invalid platform "${platform}". Must be "web" or "server".`
|
|
505
565
|
);
|
|
506
566
|
}
|
|
507
|
-
|
|
567
|
+
if (!isObject(buildOptions)) {
|
|
568
|
+
throw new Error(
|
|
569
|
+
`Invalid build options: expected object, got ${typeof buildOptions}`
|
|
570
|
+
);
|
|
571
|
+
}
|
|
572
|
+
const platformDefaults = platform === "web" ? {
|
|
508
573
|
platform: "browser",
|
|
509
574
|
format: "iife",
|
|
510
575
|
target: "es2020",
|
|
@@ -521,43 +586,97 @@ function normalizeConfigs(config, configPath) {
|
|
|
521
586
|
tempDir: ".tmp",
|
|
522
587
|
cache: true
|
|
523
588
|
};
|
|
524
|
-
const
|
|
525
|
-
...
|
|
526
|
-
...
|
|
589
|
+
const merged = {
|
|
590
|
+
...platformDefaults,
|
|
591
|
+
...buildOptions
|
|
527
592
|
};
|
|
528
|
-
if (
|
|
529
|
-
|
|
593
|
+
if (merged.template === void 0) {
|
|
594
|
+
merged.template = platform === "server" ? "server.hbs" : "web.hbs";
|
|
530
595
|
}
|
|
531
|
-
if (
|
|
532
|
-
if (
|
|
533
|
-
|
|
534
|
-
|
|
596
|
+
if (merged.format === "iife" && merged.platform === "browser") {
|
|
597
|
+
if (merged.windowCollector === void 0) {
|
|
598
|
+
merged.windowCollector = "collector";
|
|
599
|
+
}
|
|
600
|
+
if (merged.windowElb === void 0) {
|
|
601
|
+
merged.windowElb = "elb";
|
|
535
602
|
}
|
|
536
603
|
}
|
|
537
|
-
|
|
604
|
+
if (configPath && merged.template && !path4.isAbsolute(merged.template) && (merged.template.startsWith("./") || merged.template.startsWith("../"))) {
|
|
605
|
+
const configDir = path4.dirname(configPath);
|
|
606
|
+
merged.template = path4.resolve(configDir, merged.template);
|
|
607
|
+
}
|
|
608
|
+
if (!merged.output || merged.output === "") {
|
|
609
|
+
merged.output = platform === "web" ? "./dist/walker.js" : "./dist/bundle.js";
|
|
610
|
+
}
|
|
611
|
+
if (configPath && configPath !== "/unknown/path" && merged.output && !path4.isAbsolute(merged.output)) {
|
|
612
|
+
const configDir = path4.dirname(configPath);
|
|
613
|
+
merged.output = path4.resolve(configDir, merged.output);
|
|
614
|
+
}
|
|
615
|
+
if (!merged.packages) {
|
|
616
|
+
merged.packages = {};
|
|
617
|
+
}
|
|
618
|
+
if (merged.code === void 0 || merged.code === "") {
|
|
619
|
+
merged.code = "";
|
|
620
|
+
}
|
|
538
621
|
return {
|
|
539
622
|
flowConfig,
|
|
540
|
-
buildOptions
|
|
623
|
+
buildOptions: merged
|
|
541
624
|
};
|
|
542
625
|
}
|
|
626
|
+
function parseBundleConfig(data) {
|
|
627
|
+
if (!isObject(data)) {
|
|
628
|
+
throw new Error(`Invalid config: expected object, got ${typeof data}`);
|
|
629
|
+
}
|
|
630
|
+
if (!("flow" in data) || !isObject(data.flow)) {
|
|
631
|
+
throw new Error(
|
|
632
|
+
`Invalid config: missing "flow" field. Expected format: { flow: { platform: "web" | "server", ... }, build: { ... } }`
|
|
633
|
+
);
|
|
634
|
+
}
|
|
635
|
+
if (!("build" in data) || !isObject(data.build)) {
|
|
636
|
+
throw new Error(
|
|
637
|
+
`Invalid config: missing "build" field. Expected format: { flow: { platform: "web" | "server", ... }, build: { ... } }`
|
|
638
|
+
);
|
|
639
|
+
}
|
|
640
|
+
const buildData = data.build;
|
|
641
|
+
if ("packages" in buildData && !isObject(buildData.packages)) {
|
|
642
|
+
throw new Error(
|
|
643
|
+
`Invalid config: build.packages must be an object, got ${typeof buildData.packages}`
|
|
644
|
+
);
|
|
645
|
+
}
|
|
646
|
+
return normalizeAndValidate(data.flow, data.build, "/unknown/path");
|
|
647
|
+
}
|
|
648
|
+
function normalizeConfigs(config, configPath) {
|
|
649
|
+
return normalizeAndValidate(config.flow, config.build, configPath);
|
|
650
|
+
}
|
|
543
651
|
|
|
544
652
|
// src/config/loader.ts
|
|
545
653
|
function loadBundleConfig(rawConfig, options) {
|
|
546
|
-
|
|
547
|
-
|
|
654
|
+
const { flowConfig, buildOptions, metadata } = parseConfigStructure(
|
|
655
|
+
rawConfig,
|
|
656
|
+
{
|
|
657
|
+
configPath: options.configPath,
|
|
658
|
+
environment: options.environment
|
|
659
|
+
}
|
|
660
|
+
);
|
|
661
|
+
const normalized = normalizeAndValidate(
|
|
662
|
+
flowConfig,
|
|
663
|
+
buildOptions,
|
|
664
|
+
options.configPath
|
|
665
|
+
);
|
|
666
|
+
if (metadata.isMultiEnvironment && options.logger) {
|
|
667
|
+
options.logger.info(
|
|
668
|
+
`\u{1F4E6} Using environment: ${metadata.environment} (${metadata.availableEnvironments?.length || 0} total)`
|
|
669
|
+
);
|
|
548
670
|
}
|
|
549
|
-
if (
|
|
550
|
-
|
|
671
|
+
if (!metadata.isMultiEnvironment && options.environment && options.logger) {
|
|
672
|
+
options.logger.warn(
|
|
673
|
+
`--env flag specified but configuration is single-environment. Ignoring flag.`
|
|
674
|
+
);
|
|
551
675
|
}
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
Expected either:
|
|
558
|
-
1. Multi-environment: { version: 1, environments: { prod: { flow: {...}, build: {...} } } }
|
|
559
|
-
2. Single-environment: { flow: { platform: "web" | "server", ... }, build: { packages: {...}, ... } }`
|
|
560
|
-
);
|
|
676
|
+
return {
|
|
677
|
+
...normalized,
|
|
678
|
+
...metadata
|
|
679
|
+
};
|
|
561
680
|
}
|
|
562
681
|
function loadMultiEnvironmentConfig(setup, options) {
|
|
563
682
|
const availableEnvironments = Object.keys(setup.environments);
|
|
@@ -592,23 +711,6 @@ Available environments: ${availableEnvironments.join(", ")}`
|
|
|
592
711
|
availableEnvironments
|
|
593
712
|
};
|
|
594
713
|
}
|
|
595
|
-
function loadSingleEnvironmentConfig(config, options) {
|
|
596
|
-
const { flowConfig, buildOptions } = normalizeConfigs(
|
|
597
|
-
config,
|
|
598
|
-
options.configPath
|
|
599
|
-
);
|
|
600
|
-
if (options.logger && options.environment) {
|
|
601
|
-
options.logger.warn(
|
|
602
|
-
`--env flag specified but configuration is single-environment. Ignoring flag.`
|
|
603
|
-
);
|
|
604
|
-
}
|
|
605
|
-
return {
|
|
606
|
-
flowConfig,
|
|
607
|
-
buildOptions,
|
|
608
|
-
environment: "default",
|
|
609
|
-
isMultiEnvironment: false
|
|
610
|
-
};
|
|
611
|
-
}
|
|
612
714
|
function loadAllEnvironments(rawConfig, options) {
|
|
613
715
|
if (!isMultiEnvConfig(rawConfig)) {
|
|
614
716
|
throw new Error(
|
|
@@ -634,12 +736,12 @@ Your configuration appears to be single-environment.`
|
|
|
634
736
|
// src/commands/bundle/bundler.ts
|
|
635
737
|
import esbuild from "esbuild";
|
|
636
738
|
import path6 from "path";
|
|
637
|
-
import
|
|
739
|
+
import fs5 from "fs-extra";
|
|
638
740
|
|
|
639
741
|
// src/commands/bundle/package-manager.ts
|
|
640
742
|
import pacote from "pacote";
|
|
641
743
|
import path5 from "path";
|
|
642
|
-
import
|
|
744
|
+
import fs3 from "fs-extra";
|
|
643
745
|
function getPackageDirectory(baseDir, packageName, version) {
|
|
644
746
|
return path5.join(baseDir, "node_modules", packageName);
|
|
645
747
|
}
|
|
@@ -650,7 +752,7 @@ function getCachedPackagePath(pkg, tempDir) {
|
|
|
650
752
|
}
|
|
651
753
|
async function isPackageCached(pkg, tempDir) {
|
|
652
754
|
const cachedPath = getCachedPackagePath(pkg, tempDir);
|
|
653
|
-
return
|
|
755
|
+
return fs3.pathExists(cachedPath);
|
|
654
756
|
}
|
|
655
757
|
function validateNoDuplicatePackages(packages) {
|
|
656
758
|
const packageMap = /* @__PURE__ */ new Map();
|
|
@@ -685,8 +787,8 @@ async function resolveDependencies(pkg, packageDir, logger, visited = /* @__PURE
|
|
|
685
787
|
visited.add(pkgKey);
|
|
686
788
|
try {
|
|
687
789
|
const packageJsonPath = path5.join(packageDir, "package.json");
|
|
688
|
-
if (await
|
|
689
|
-
const packageJson2 = await
|
|
790
|
+
if (await fs3.pathExists(packageJsonPath)) {
|
|
791
|
+
const packageJson2 = await fs3.readJson(packageJsonPath);
|
|
690
792
|
const deps = {
|
|
691
793
|
...packageJson2.dependencies,
|
|
692
794
|
...packageJson2.peerDependencies
|
|
@@ -707,7 +809,7 @@ async function downloadPackages(packages, targetDir, logger, useCache = true) {
|
|
|
707
809
|
const downloadQueue = [...packages];
|
|
708
810
|
const processed = /* @__PURE__ */ new Set();
|
|
709
811
|
validateNoDuplicatePackages(packages);
|
|
710
|
-
await
|
|
812
|
+
await fs3.ensureDir(targetDir);
|
|
711
813
|
while (downloadQueue.length > 0) {
|
|
712
814
|
const pkg = downloadQueue.shift();
|
|
713
815
|
const pkgKey = `${pkg.name}@${pkg.version}`;
|
|
@@ -721,8 +823,8 @@ async function downloadPackages(packages, targetDir, logger, useCache = true) {
|
|
|
721
823
|
if (useCache && await isPackageCached(pkg, targetDir)) {
|
|
722
824
|
logger.debug(`Using cached ${packageSpec}...`);
|
|
723
825
|
try {
|
|
724
|
-
await
|
|
725
|
-
await
|
|
826
|
+
await fs3.ensureDir(path5.dirname(packageDir));
|
|
827
|
+
await fs3.copy(cachedPath, packageDir);
|
|
726
828
|
packagePaths.set(pkg.name, packageDir);
|
|
727
829
|
const deps = await resolveDependencies(pkg, packageDir, logger);
|
|
728
830
|
for (const dep of deps) {
|
|
@@ -740,7 +842,7 @@ async function downloadPackages(packages, targetDir, logger, useCache = true) {
|
|
|
740
842
|
}
|
|
741
843
|
logger.debug(`Downloading ${packageSpec}...`);
|
|
742
844
|
try {
|
|
743
|
-
await
|
|
845
|
+
await fs3.ensureDir(path5.dirname(packageDir));
|
|
744
846
|
const cacheDir = process.env.NPM_CACHE_DIR || path5.join(process.cwd(), ".npm-cache");
|
|
745
847
|
await pacote.extract(packageSpec, packageDir, {
|
|
746
848
|
// Force npm registry download, prevent workspace resolution
|
|
@@ -754,8 +856,8 @@ async function downloadPackages(packages, targetDir, logger, useCache = true) {
|
|
|
754
856
|
});
|
|
755
857
|
if (useCache) {
|
|
756
858
|
try {
|
|
757
|
-
await
|
|
758
|
-
await
|
|
859
|
+
await fs3.ensureDir(path5.dirname(cachedPath));
|
|
860
|
+
await fs3.copy(packageDir, cachedPath);
|
|
759
861
|
logger.debug(`Cached ${packageSpec} for future use`);
|
|
760
862
|
} catch (cacheError) {
|
|
761
863
|
logger.debug(`Failed to cache ${packageSpec}: ${cacheError}`);
|
|
@@ -777,7 +879,7 @@ async function downloadPackages(packages, targetDir, logger, useCache = true) {
|
|
|
777
879
|
}
|
|
778
880
|
|
|
779
881
|
// src/commands/bundle/template-engine.ts
|
|
780
|
-
import
|
|
882
|
+
import fs4 from "fs-extra";
|
|
781
883
|
import Handlebars from "handlebars";
|
|
782
884
|
|
|
783
885
|
// src/commands/bundle/serializer.ts
|
|
@@ -885,6 +987,7 @@ var TemplateEngine = class {
|
|
|
885
987
|
handlebars;
|
|
886
988
|
constructor() {
|
|
887
989
|
this.handlebars = Handlebars.create();
|
|
990
|
+
this.handlebars.registerHelper("eq", (a, b) => a === b);
|
|
888
991
|
}
|
|
889
992
|
/**
|
|
890
993
|
* Load template content from file path
|
|
@@ -893,10 +996,10 @@ var TemplateEngine = class {
|
|
|
893
996
|
*/
|
|
894
997
|
async loadTemplate(templatePath) {
|
|
895
998
|
const resolvedPath = resolveAsset(templatePath, "template");
|
|
896
|
-
if (!await
|
|
999
|
+
if (!await fs4.pathExists(resolvedPath)) {
|
|
897
1000
|
throw new Error(`Template file not found: ${resolvedPath}`);
|
|
898
1001
|
}
|
|
899
|
-
return await
|
|
1002
|
+
return await fs4.readFile(resolvedPath, "utf-8");
|
|
900
1003
|
}
|
|
901
1004
|
/**
|
|
902
1005
|
* Apply template with user code and variable substitution
|
|
@@ -937,7 +1040,7 @@ async function bundleCore(flowConfig, buildOptions, logger, showStats = false) {
|
|
|
937
1040
|
const TEMP_DIR = buildOptions.tempDir ? path6.isAbsolute(buildOptions.tempDir) ? buildOptions.tempDir : path6.resolve(buildOptions.tempDir) : getTempDir();
|
|
938
1041
|
try {
|
|
939
1042
|
if (!buildOptions.tempDir) {
|
|
940
|
-
await
|
|
1043
|
+
await fs5.emptyDir(TEMP_DIR);
|
|
941
1044
|
}
|
|
942
1045
|
logger.debug("Cleaned temporary directory");
|
|
943
1046
|
logger.info("\u{1F4E5} Downloading packages...");
|
|
@@ -956,7 +1059,7 @@ async function bundleCore(flowConfig, buildOptions, logger, showStats = false) {
|
|
|
956
1059
|
for (const [pkgName, pkgPath] of packagePaths.entries()) {
|
|
957
1060
|
if (pkgName.startsWith("@walkeros/")) {
|
|
958
1061
|
const pkgJsonPath = path6.join(pkgPath, "package.json");
|
|
959
|
-
const pkgJson = await
|
|
1062
|
+
const pkgJson = await fs5.readJSON(pkgJsonPath);
|
|
960
1063
|
if (!pkgJson.exports && pkgJson.module) {
|
|
961
1064
|
pkgJson.exports = {
|
|
962
1065
|
".": {
|
|
@@ -964,12 +1067,12 @@ async function bundleCore(flowConfig, buildOptions, logger, showStats = false) {
|
|
|
964
1067
|
require: pkgJson.main
|
|
965
1068
|
}
|
|
966
1069
|
};
|
|
967
|
-
await
|
|
1070
|
+
await fs5.writeJSON(pkgJsonPath, pkgJson, { spaces: 2 });
|
|
968
1071
|
}
|
|
969
1072
|
}
|
|
970
1073
|
}
|
|
971
1074
|
const packageJsonPath = path6.join(TEMP_DIR, "package.json");
|
|
972
|
-
await
|
|
1075
|
+
await fs5.writeFile(
|
|
973
1076
|
packageJsonPath,
|
|
974
1077
|
JSON.stringify({ type: "module" }, null, 2)
|
|
975
1078
|
);
|
|
@@ -980,10 +1083,10 @@ async function bundleCore(flowConfig, buildOptions, logger, showStats = false) {
|
|
|
980
1083
|
packagePaths
|
|
981
1084
|
);
|
|
982
1085
|
const entryPath = path6.join(TEMP_DIR, "entry.js");
|
|
983
|
-
await
|
|
1086
|
+
await fs5.writeFile(entryPath, entryContent);
|
|
984
1087
|
logger.info("\u26A1 Bundling with esbuild...");
|
|
985
1088
|
const outputPath = path6.resolve(buildOptions.output);
|
|
986
|
-
await
|
|
1089
|
+
await fs5.ensureDir(path6.dirname(outputPath));
|
|
987
1090
|
const esbuildOptions = createEsbuildOptions(
|
|
988
1091
|
buildOptions,
|
|
989
1092
|
entryPath,
|
|
@@ -1011,20 +1114,20 @@ async function bundleCore(flowConfig, buildOptions, logger, showStats = false) {
|
|
|
1011
1114
|
);
|
|
1012
1115
|
}
|
|
1013
1116
|
if (!buildOptions.tempDir) {
|
|
1014
|
-
await
|
|
1117
|
+
await fs5.remove(TEMP_DIR);
|
|
1015
1118
|
logger.debug("Cleaned up temporary files");
|
|
1016
1119
|
}
|
|
1017
1120
|
return stats;
|
|
1018
1121
|
} catch (error) {
|
|
1019
1122
|
if (!buildOptions.tempDir) {
|
|
1020
|
-
await
|
|
1123
|
+
await fs5.remove(TEMP_DIR).catch(() => {
|
|
1021
1124
|
});
|
|
1022
1125
|
}
|
|
1023
1126
|
throw error;
|
|
1024
1127
|
}
|
|
1025
1128
|
}
|
|
1026
1129
|
async function collectBundleStats(outputPath, packages, startTime, entryContent) {
|
|
1027
|
-
const stats = await
|
|
1130
|
+
const stats = await fs5.stat(outputPath);
|
|
1028
1131
|
const totalSize = stats.size;
|
|
1029
1132
|
const buildTime = Date.now() - startTime;
|
|
1030
1133
|
const packageStats = Object.entries(packages).map(([name, pkg]) => {
|
|
@@ -1111,9 +1214,6 @@ function createEsbuildOptions(buildOptions, entryPath, outputPath, tempDir, pack
|
|
|
1111
1214
|
} else {
|
|
1112
1215
|
baseOptions.target = "es2018";
|
|
1113
1216
|
}
|
|
1114
|
-
if (buildOptions.globalName && buildOptions.format === "iife") {
|
|
1115
|
-
baseOptions.globalName = buildOptions.globalName;
|
|
1116
|
-
}
|
|
1117
1217
|
return baseOptions;
|
|
1118
1218
|
}
|
|
1119
1219
|
function packageNameToVariable(packageName) {
|
|
@@ -1121,9 +1221,7 @@ function packageNameToVariable(packageName) {
|
|
|
1121
1221
|
(part, i) => i === 0 ? part : part.charAt(0).toUpperCase() + part.slice(1)
|
|
1122
1222
|
).join("");
|
|
1123
1223
|
}
|
|
1124
|
-
|
|
1125
|
-
const importStatements = [];
|
|
1126
|
-
const examplesMappings = [];
|
|
1224
|
+
function detectDestinationPackages(flowConfig) {
|
|
1127
1225
|
const destinationPackages = /* @__PURE__ */ new Set();
|
|
1128
1226
|
const destinations = flowConfig.destinations;
|
|
1129
1227
|
if (destinations) {
|
|
@@ -1133,9 +1231,12 @@ async function createEntryPoint(flowConfig, buildOptions, packagePaths) {
|
|
|
1133
1231
|
}
|
|
1134
1232
|
}
|
|
1135
1233
|
}
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1234
|
+
return destinationPackages;
|
|
1235
|
+
}
|
|
1236
|
+
function generateImportStatements(packages, destinationPackages) {
|
|
1237
|
+
const importStatements = [];
|
|
1238
|
+
const examplesMappings = [];
|
|
1239
|
+
for (const [packageName, packageConfig] of Object.entries(packages)) {
|
|
1139
1240
|
if (packageConfig.imports && packageConfig.imports.length > 0) {
|
|
1140
1241
|
const uniqueImports = [...new Set(packageConfig.imports)];
|
|
1141
1242
|
const defaultImports = [];
|
|
@@ -1181,38 +1282,14 @@ async function createEntryPoint(flowConfig, buildOptions, packagePaths) {
|
|
|
1181
1282
|
`import * as ${varName} from '${packageName}'; // Consider specifying explicit imports`
|
|
1182
1283
|
);
|
|
1183
1284
|
}
|
|
1184
|
-
if (destinationPackages.has(packageName)) {
|
|
1185
|
-
const destinationMatch = packageName.match(
|
|
1186
|
-
/@walkeros\/(?:(?:web|server)-)?destination-(.+)$/
|
|
1187
|
-
);
|
|
1188
|
-
if (destinationMatch) {
|
|
1189
|
-
const destinationName = destinationMatch[1];
|
|
1190
|
-
const examplesVarName = `${destinationName.replace(/-/g, "_")}_examples`;
|
|
1191
|
-
const isDemoPackage = packageName.includes("-demo");
|
|
1192
|
-
if (isDemoPackage) {
|
|
1193
|
-
importStatements.push(
|
|
1194
|
-
`import { examples as ${examplesVarName} } from '${packageName}';`
|
|
1195
|
-
);
|
|
1196
|
-
} else {
|
|
1197
|
-
importStatements.push(
|
|
1198
|
-
`import * as ${examplesVarName} from '${packageName}/examples';`
|
|
1199
|
-
);
|
|
1200
|
-
}
|
|
1201
|
-
examplesMappings.push(` ${destinationName}: ${examplesVarName}`);
|
|
1202
|
-
}
|
|
1203
|
-
}
|
|
1204
1285
|
}
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
` : "";
|
|
1210
|
-
const importsCode = importStatements.join("\n");
|
|
1211
|
-
let templatedCode;
|
|
1286
|
+
return { importStatements, examplesMappings };
|
|
1287
|
+
}
|
|
1288
|
+
async function processTemplate(flowConfig, buildOptions) {
|
|
1212
1289
|
if (buildOptions.template) {
|
|
1213
1290
|
const templateEngine = new TemplateEngine();
|
|
1214
1291
|
const flowWithProps = flowConfig;
|
|
1215
|
-
|
|
1292
|
+
return await templateEngine.process(
|
|
1216
1293
|
buildOptions.template,
|
|
1217
1294
|
buildOptions.code || "",
|
|
1218
1295
|
// Pass user code as parameter (empty if undefined)
|
|
@@ -1223,27 +1300,53 @@ ${examplesMappings.join(",\n")}
|
|
|
1223
1300
|
// Pass build config to template
|
|
1224
1301
|
);
|
|
1225
1302
|
} else {
|
|
1226
|
-
|
|
1303
|
+
return buildOptions.code || "";
|
|
1227
1304
|
}
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
if (
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1305
|
+
}
|
|
1306
|
+
function wrapCodeForFormat(code, format, hasTemplate) {
|
|
1307
|
+
if (hasTemplate) {
|
|
1308
|
+
return code;
|
|
1309
|
+
}
|
|
1310
|
+
if (format === "esm") {
|
|
1311
|
+
const hasExport = /^\s*export\s/m.test(code);
|
|
1312
|
+
if (!hasExport) {
|
|
1313
|
+
return `export default ${code}`;
|
|
1235
1314
|
}
|
|
1236
1315
|
}
|
|
1316
|
+
return code;
|
|
1317
|
+
}
|
|
1318
|
+
function assembleFinalCode(importStatements, examplesObject, wrappedCode, format) {
|
|
1319
|
+
const importsCode = importStatements.join("\n");
|
|
1237
1320
|
let finalCode = importsCode ? `${importsCode}
|
|
1238
1321
|
|
|
1239
1322
|
${examplesObject}${wrappedCode}` : `${examplesObject}${wrappedCode}`;
|
|
1240
|
-
if (examplesObject &&
|
|
1323
|
+
if (examplesObject && format === "esm") {
|
|
1241
1324
|
finalCode += `
|
|
1242
1325
|
|
|
1243
1326
|
export { examples };`;
|
|
1244
1327
|
}
|
|
1245
1328
|
return finalCode;
|
|
1246
1329
|
}
|
|
1330
|
+
async function createEntryPoint(flowConfig, buildOptions, packagePaths) {
|
|
1331
|
+
const destinationPackages = detectDestinationPackages(flowConfig);
|
|
1332
|
+
const { importStatements } = generateImportStatements(
|
|
1333
|
+
buildOptions.packages,
|
|
1334
|
+
destinationPackages
|
|
1335
|
+
);
|
|
1336
|
+
const examplesObject = "";
|
|
1337
|
+
const templatedCode = await processTemplate(flowConfig, buildOptions);
|
|
1338
|
+
const wrappedCode = wrapCodeForFormat(
|
|
1339
|
+
templatedCode,
|
|
1340
|
+
buildOptions.format,
|
|
1341
|
+
!!buildOptions.template
|
|
1342
|
+
);
|
|
1343
|
+
return assembleFinalCode(
|
|
1344
|
+
importStatements,
|
|
1345
|
+
examplesObject,
|
|
1346
|
+
wrappedCode,
|
|
1347
|
+
buildOptions.format
|
|
1348
|
+
);
|
|
1349
|
+
}
|
|
1247
1350
|
function createBuildError(buildError, code) {
|
|
1248
1351
|
if (!buildError.errors || buildError.errors.length === 0) {
|
|
1249
1352
|
return new Error(`Build failed: ${buildError.message || buildError}`);
|
|
@@ -1295,19 +1398,12 @@ Package Breakdown:`);
|
|
|
1295
1398
|
async function bundleCommand(options) {
|
|
1296
1399
|
const timer = createTimer();
|
|
1297
1400
|
timer.start();
|
|
1298
|
-
const logger =
|
|
1299
|
-
|
|
1300
|
-
silent: options.silent ?? false,
|
|
1301
|
-
json: options.json
|
|
1302
|
-
});
|
|
1303
|
-
const dockerArgs = [options.config];
|
|
1401
|
+
const logger = createCommandLogger(options);
|
|
1402
|
+
const dockerArgs = buildCommonDockerArgs(options);
|
|
1304
1403
|
if (options.env) dockerArgs.push("--env", options.env);
|
|
1305
1404
|
if (options.all) dockerArgs.push("--all");
|
|
1306
1405
|
if (options.stats) dockerArgs.push("--stats");
|
|
1307
|
-
if (options.json) dockerArgs.push("--json");
|
|
1308
1406
|
if (options.cache === false) dockerArgs.push("--no-cache");
|
|
1309
|
-
if (options.verbose) dockerArgs.push("--verbose");
|
|
1310
|
-
if (options.silent) dockerArgs.push("--silent");
|
|
1311
1407
|
await executeCommand(
|
|
1312
1408
|
async () => {
|
|
1313
1409
|
try {
|
|
@@ -1357,7 +1453,7 @@ async function bundleCommand(options) {
|
|
|
1357
1453
|
displayStats(stats, logger);
|
|
1358
1454
|
}
|
|
1359
1455
|
} catch (error) {
|
|
1360
|
-
const errorMessage =
|
|
1456
|
+
const errorMessage = getErrorMessage(error);
|
|
1361
1457
|
results.push({
|
|
1362
1458
|
environment,
|
|
1363
1459
|
success: false,
|
|
@@ -1409,7 +1505,7 @@ async function bundleCommand(options) {
|
|
|
1409
1505
|
}
|
|
1410
1506
|
} catch (error) {
|
|
1411
1507
|
const duration = timer.getElapsed() / 1e3;
|
|
1412
|
-
const errorMessage =
|
|
1508
|
+
const errorMessage = getErrorMessage(error);
|
|
1413
1509
|
if (options.json) {
|
|
1414
1510
|
const outputLogger = createLogger({ silent: false, json: false });
|
|
1415
1511
|
const output = createErrorOutput(errorMessage, duration);
|
|
@@ -1439,10 +1535,7 @@ async function bundle(configOrPath, options = {}) {
|
|
|
1439
1535
|
if (options.cache !== void 0) {
|
|
1440
1536
|
buildOptions.cache = options.cache;
|
|
1441
1537
|
}
|
|
1442
|
-
const logger =
|
|
1443
|
-
silent: options.silent ?? false,
|
|
1444
|
-
verbose: options.verbose ?? false
|
|
1445
|
-
});
|
|
1538
|
+
const logger = createCommandLogger(options);
|
|
1446
1539
|
return await bundleCore(
|
|
1447
1540
|
flowConfig,
|
|
1448
1541
|
buildOptions,
|
|
@@ -1453,7 +1546,7 @@ async function bundle(configOrPath, options = {}) {
|
|
|
1453
1546
|
|
|
1454
1547
|
// src/commands/simulate/simulator.ts
|
|
1455
1548
|
import path7 from "path";
|
|
1456
|
-
import
|
|
1549
|
+
import fs7 from "fs-extra";
|
|
1457
1550
|
|
|
1458
1551
|
// src/commands/simulate/tracker.ts
|
|
1459
1552
|
var CallTracker = class {
|
|
@@ -1489,9 +1582,9 @@ var CallTracker = class {
|
|
|
1489
1582
|
}
|
|
1490
1583
|
for (const fullPath of paths) {
|
|
1491
1584
|
const [destKey, ...pathParts] = fullPath.split(":");
|
|
1492
|
-
const
|
|
1493
|
-
if (!
|
|
1494
|
-
const cleanPath =
|
|
1585
|
+
const path11 = pathParts.join(":");
|
|
1586
|
+
if (!path11) continue;
|
|
1587
|
+
const cleanPath = path11.replace(/^call:/, "");
|
|
1495
1588
|
const parts = cleanPath.split(".");
|
|
1496
1589
|
let current = wrapped;
|
|
1497
1590
|
let source = env;
|
|
@@ -1533,6 +1626,146 @@ var CallTracker = class {
|
|
|
1533
1626
|
}
|
|
1534
1627
|
};
|
|
1535
1628
|
|
|
1629
|
+
// src/commands/simulate/jsdom-executor.ts
|
|
1630
|
+
import { JSDOM, VirtualConsole } from "jsdom";
|
|
1631
|
+
import fs6 from "fs-extra";
|
|
1632
|
+
function buildSandboxFromEnvs(envs, destinations, tracker) {
|
|
1633
|
+
const baseBrowserMocks = {
|
|
1634
|
+
Image: class MockImage {
|
|
1635
|
+
src = "";
|
|
1636
|
+
onload = (() => {
|
|
1637
|
+
});
|
|
1638
|
+
onerror = (() => {
|
|
1639
|
+
});
|
|
1640
|
+
},
|
|
1641
|
+
fetch: async () => ({ ok: true, json: async () => ({}) }),
|
|
1642
|
+
location: { href: "http://localhost" },
|
|
1643
|
+
navigator: { userAgent: "Mozilla/5.0 (walkerOS Simulation)" }
|
|
1644
|
+
};
|
|
1645
|
+
const sandbox = {
|
|
1646
|
+
window: { ...baseBrowserMocks },
|
|
1647
|
+
document: {}
|
|
1648
|
+
};
|
|
1649
|
+
for (const [destKey, destConfig] of Object.entries(destinations)) {
|
|
1650
|
+
const destEnv = envs[destKey];
|
|
1651
|
+
if (!destEnv?.push) continue;
|
|
1652
|
+
const mockEnv = destEnv.push;
|
|
1653
|
+
const trackPaths = destEnv.simulation || [];
|
|
1654
|
+
const trackedEnv = tracker.wrapEnv(
|
|
1655
|
+
mockEnv,
|
|
1656
|
+
trackPaths.map((p) => `${destKey}:${p}`)
|
|
1657
|
+
);
|
|
1658
|
+
if (trackedEnv.window && typeof trackedEnv.window === "object") {
|
|
1659
|
+
Object.assign(sandbox.window, trackedEnv.window);
|
|
1660
|
+
}
|
|
1661
|
+
if (trackedEnv.document && typeof trackedEnv.document === "object") {
|
|
1662
|
+
Object.assign(sandbox.document, trackedEnv.document);
|
|
1663
|
+
}
|
|
1664
|
+
}
|
|
1665
|
+
return sandbox;
|
|
1666
|
+
}
|
|
1667
|
+
function waitForWindowProperty(window, prop, timeout = 5e3) {
|
|
1668
|
+
return new Promise((resolve, reject) => {
|
|
1669
|
+
const start = Date.now();
|
|
1670
|
+
const check = () => {
|
|
1671
|
+
if (window[prop] !== void 0) {
|
|
1672
|
+
resolve();
|
|
1673
|
+
} else if (Date.now() - start > timeout) {
|
|
1674
|
+
reject(
|
|
1675
|
+
new Error(
|
|
1676
|
+
`Timeout waiting for window.${prop}. IIFE may have failed to execute or assign to window.`
|
|
1677
|
+
)
|
|
1678
|
+
);
|
|
1679
|
+
} else {
|
|
1680
|
+
setImmediate(check);
|
|
1681
|
+
}
|
|
1682
|
+
};
|
|
1683
|
+
check();
|
|
1684
|
+
});
|
|
1685
|
+
}
|
|
1686
|
+
async function executeInJSDOM(bundlePath, destinations, event, tracker, envs, timeout = 1e4) {
|
|
1687
|
+
const start = Date.now();
|
|
1688
|
+
const virtualConsole = new VirtualConsole();
|
|
1689
|
+
const dom = new JSDOM("<!DOCTYPE html><html><body></body></html>", {
|
|
1690
|
+
url: "http://localhost",
|
|
1691
|
+
runScripts: "dangerously",
|
|
1692
|
+
// Allow script execution
|
|
1693
|
+
resources: "usable",
|
|
1694
|
+
virtualConsole
|
|
1695
|
+
});
|
|
1696
|
+
const { window } = dom;
|
|
1697
|
+
const sandbox = buildSandboxFromEnvs(envs, destinations, tracker);
|
|
1698
|
+
Object.assign(window, sandbox.window);
|
|
1699
|
+
Object.assign(window.document, sandbox.document);
|
|
1700
|
+
const bundleCode = await fs6.readFile(bundlePath, "utf8");
|
|
1701
|
+
try {
|
|
1702
|
+
window.eval(bundleCode);
|
|
1703
|
+
} catch (error) {
|
|
1704
|
+
throw new Error(`Bundle execution failed: ${getErrorMessage(error)}`);
|
|
1705
|
+
}
|
|
1706
|
+
try {
|
|
1707
|
+
await waitForWindowProperty(
|
|
1708
|
+
window,
|
|
1709
|
+
"collector",
|
|
1710
|
+
timeout
|
|
1711
|
+
);
|
|
1712
|
+
await waitForWindowProperty(
|
|
1713
|
+
window,
|
|
1714
|
+
"elb",
|
|
1715
|
+
timeout
|
|
1716
|
+
);
|
|
1717
|
+
} catch (error) {
|
|
1718
|
+
throw new Error(
|
|
1719
|
+
`Window property assignment failed: ${getErrorMessage(error)}`
|
|
1720
|
+
);
|
|
1721
|
+
}
|
|
1722
|
+
const { collector, elb } = window;
|
|
1723
|
+
let elbResult;
|
|
1724
|
+
try {
|
|
1725
|
+
elbResult = await elb(event.name, event.data);
|
|
1726
|
+
} catch (error) {
|
|
1727
|
+
throw new Error(`Event execution failed: ${getErrorMessage(error)}`);
|
|
1728
|
+
}
|
|
1729
|
+
return {
|
|
1730
|
+
collector,
|
|
1731
|
+
elb,
|
|
1732
|
+
elbResult,
|
|
1733
|
+
usage: tracker.getCalls(),
|
|
1734
|
+
duration: Date.now() - start
|
|
1735
|
+
};
|
|
1736
|
+
}
|
|
1737
|
+
|
|
1738
|
+
// src/commands/simulate/env-loader.ts
|
|
1739
|
+
async function loadDestinationEnvs(destinations) {
|
|
1740
|
+
const envs = {};
|
|
1741
|
+
for (const [destKey, destConfig] of Object.entries(destinations)) {
|
|
1742
|
+
const typedConfig = destConfig;
|
|
1743
|
+
if (!typedConfig.package) {
|
|
1744
|
+
continue;
|
|
1745
|
+
}
|
|
1746
|
+
try {
|
|
1747
|
+
const packageName = typedConfig.package;
|
|
1748
|
+
const isDemoPackage = packageName.includes("-demo");
|
|
1749
|
+
const importPath = isDemoPackage ? packageName : `${packageName}/dev`;
|
|
1750
|
+
const module = await import(importPath);
|
|
1751
|
+
const examplesModule = module.examples || module.default?.examples;
|
|
1752
|
+
const envModule = examplesModule?.env;
|
|
1753
|
+
if (envModule?.push) {
|
|
1754
|
+
envs[destKey] = {
|
|
1755
|
+
init: envModule.init,
|
|
1756
|
+
push: envModule.push,
|
|
1757
|
+
simulation: envModule.simulation || []
|
|
1758
|
+
};
|
|
1759
|
+
}
|
|
1760
|
+
} catch (error) {
|
|
1761
|
+
console.warn(
|
|
1762
|
+
`Warning: Could not load env for destination "${destKey}": ${error instanceof Error ? error.message : String(error)}`
|
|
1763
|
+
);
|
|
1764
|
+
}
|
|
1765
|
+
}
|
|
1766
|
+
return envs;
|
|
1767
|
+
}
|
|
1768
|
+
|
|
1536
1769
|
// src/commands/simulate/simulator.ts
|
|
1537
1770
|
function generateId() {
|
|
1538
1771
|
return `${Date.now()}-${Math.random().toString(36).substring(2, 11)}`;
|
|
@@ -1558,7 +1791,7 @@ async function simulateCore(configPath, event, options = {}) {
|
|
|
1558
1791
|
}
|
|
1559
1792
|
return result;
|
|
1560
1793
|
} catch (error) {
|
|
1561
|
-
const errorMessage =
|
|
1794
|
+
const errorMessage = getErrorMessage(error);
|
|
1562
1795
|
logger.error(`\u{1F4A5} Simulation error: ${errorMessage}`);
|
|
1563
1796
|
return {
|
|
1564
1797
|
success: false,
|
|
@@ -1566,17 +1799,6 @@ async function simulateCore(configPath, event, options = {}) {
|
|
|
1566
1799
|
};
|
|
1567
1800
|
}
|
|
1568
1801
|
}
|
|
1569
|
-
function parseEventInput(eventString = "") {
|
|
1570
|
-
if (!eventString) {
|
|
1571
|
-
return {};
|
|
1572
|
-
}
|
|
1573
|
-
try {
|
|
1574
|
-
const parsed = JSON.parse(eventString);
|
|
1575
|
-
return isObject(parsed) ? parsed : {};
|
|
1576
|
-
} catch {
|
|
1577
|
-
return { name: eventString };
|
|
1578
|
-
}
|
|
1579
|
-
}
|
|
1580
1802
|
function formatSimulationResult(result, options = {}) {
|
|
1581
1803
|
if (options.json) {
|
|
1582
1804
|
const output = {
|
|
@@ -1597,7 +1819,13 @@ async function executeSimulation(event, configPath) {
|
|
|
1597
1819
|
let bundlePath;
|
|
1598
1820
|
const tempDir = getTempDir();
|
|
1599
1821
|
try {
|
|
1600
|
-
|
|
1822
|
+
if (!isObject(event) || !("name" in event) || typeof event.name !== "string") {
|
|
1823
|
+
throw new Error(
|
|
1824
|
+
'Event must be an object with a "name" property of type string'
|
|
1825
|
+
);
|
|
1826
|
+
}
|
|
1827
|
+
const typedEvent = event;
|
|
1828
|
+
await fs7.ensureDir(tempDir);
|
|
1601
1829
|
const rawConfig = await loadJsonConfig(configPath);
|
|
1602
1830
|
const { flowConfig, buildOptions } = parseBundleConfig(rawConfig);
|
|
1603
1831
|
const packagesArray = Object.entries(buildOptions.packages).map(
|
|
@@ -1614,46 +1842,25 @@ async function executeSimulation(event, configPath) {
|
|
|
1614
1842
|
buildOptions.cache
|
|
1615
1843
|
);
|
|
1616
1844
|
const tracker = new CallTracker();
|
|
1617
|
-
const envSetupCode = [];
|
|
1618
|
-
const destinations = flowConfig.destinations;
|
|
1619
|
-
if (destinations) {
|
|
1620
|
-
for (const [key, dest] of Object.entries(destinations)) {
|
|
1621
|
-
const destName = key.replace(/-/g, "_");
|
|
1622
|
-
envSetupCode.push(`
|
|
1623
|
-
// Inject tracked env for destination '${key}' using examples from bundle
|
|
1624
|
-
if (examples && examples['${key}'] && examples['${key}'].env) {
|
|
1625
|
-
const mockEnv = examples['${key}'].env.push;
|
|
1626
|
-
const trackPaths = examples['${key}'].env.simulation || [];
|
|
1627
|
-
if (mockEnv) {
|
|
1628
|
-
const wrappedPaths = trackPaths.map((p) => '${key}:' + p);
|
|
1629
|
-
const trackedEnv = __simulationTracker.wrapEnv(mockEnv, wrappedPaths);
|
|
1630
|
-
if (config.destinations && config.destinations['${key}']) {
|
|
1631
|
-
config.destinations['${key}'].env = trackedEnv;
|
|
1632
|
-
}
|
|
1633
|
-
}
|
|
1634
|
-
}
|
|
1635
|
-
`);
|
|
1636
|
-
}
|
|
1637
|
-
}
|
|
1638
|
-
const modifiedCode = `
|
|
1639
|
-
// Inject tracked envs into destination configs
|
|
1640
|
-
${envSetupCode.join("\n")}
|
|
1641
|
-
|
|
1642
|
-
${buildOptions.code || ""}
|
|
1643
|
-
`;
|
|
1644
1845
|
const tempOutput = path7.join(
|
|
1645
1846
|
tempDir,
|
|
1646
|
-
`simulation-bundle-${generateId()}.
|
|
1847
|
+
`simulation-bundle-${generateId()}.js`
|
|
1647
1848
|
);
|
|
1849
|
+
const destinations = flowConfig.destinations;
|
|
1648
1850
|
const simulationBuildOptions = {
|
|
1649
1851
|
...buildOptions,
|
|
1650
|
-
code:
|
|
1852
|
+
code: buildOptions.code || "",
|
|
1853
|
+
// No code modification - use original
|
|
1651
1854
|
output: tempOutput,
|
|
1652
1855
|
tempDir,
|
|
1653
1856
|
// Use same temp dir for bundle
|
|
1654
|
-
format: "
|
|
1655
|
-
//
|
|
1656
|
-
platform: "
|
|
1857
|
+
format: "iife",
|
|
1858
|
+
// ← Test actual production format!
|
|
1859
|
+
platform: "browser",
|
|
1860
|
+
// ← Browser platform for IIFE
|
|
1861
|
+
windowCollector: "collector",
|
|
1862
|
+
// ← Ensure window assignment
|
|
1863
|
+
windowElb: "elb"
|
|
1657
1864
|
};
|
|
1658
1865
|
await bundleCore(
|
|
1659
1866
|
flowConfig,
|
|
@@ -1662,40 +1869,19 @@ ${buildOptions.code || ""}
|
|
|
1662
1869
|
false
|
|
1663
1870
|
);
|
|
1664
1871
|
bundlePath = tempOutput;
|
|
1665
|
-
const
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
const
|
|
1677
|
-
|
|
1678
|
-
for (const [key, dest] of Object.entries(destinations2)) {
|
|
1679
|
-
const destEnv = importedExamples[key]?.env?.push;
|
|
1680
|
-
if (destEnv) {
|
|
1681
|
-
if (destEnv.window && typeof globalWithSim.window === "object" && globalWithSim.window !== null) {
|
|
1682
|
-
Object.assign(globalWithSim.window, destEnv.window);
|
|
1683
|
-
}
|
|
1684
|
-
if (destEnv.document && typeof globalWithSim.document === "object" && globalWithSim.document !== null) {
|
|
1685
|
-
Object.assign(globalWithSim.document, destEnv.document);
|
|
1686
|
-
}
|
|
1687
|
-
}
|
|
1688
|
-
}
|
|
1689
|
-
}
|
|
1690
|
-
const flowResult = await module.default({ tracker });
|
|
1691
|
-
if (!flowResult || typeof flowResult.elb !== "function") {
|
|
1692
|
-
throw new Error(
|
|
1693
|
-
"Bundle did not export valid flow object with elb function"
|
|
1694
|
-
);
|
|
1695
|
-
}
|
|
1696
|
-
const { elb } = flowResult;
|
|
1697
|
-
const elbResult = await elb(event);
|
|
1698
|
-
const usage = tracker.getCalls();
|
|
1872
|
+
const envs = await loadDestinationEnvs(destinations || {});
|
|
1873
|
+
const result = await executeInJSDOM(
|
|
1874
|
+
tempOutput,
|
|
1875
|
+
destinations || {},
|
|
1876
|
+
typedEvent,
|
|
1877
|
+
tracker,
|
|
1878
|
+
envs,
|
|
1879
|
+
// Pass dynamically loaded envs
|
|
1880
|
+
1e4
|
|
1881
|
+
// 10s timeout
|
|
1882
|
+
);
|
|
1883
|
+
const elbResult = result.elbResult;
|
|
1884
|
+
const usage = result.usage;
|
|
1699
1885
|
const duration = Date.now() - startTime;
|
|
1700
1886
|
return {
|
|
1701
1887
|
success: true,
|
|
@@ -1708,37 +1894,29 @@ ${buildOptions.code || ""}
|
|
|
1708
1894
|
const duration = Date.now() - startTime;
|
|
1709
1895
|
return {
|
|
1710
1896
|
success: false,
|
|
1711
|
-
error:
|
|
1897
|
+
error: getErrorMessage(error),
|
|
1712
1898
|
duration
|
|
1713
1899
|
};
|
|
1714
1900
|
} finally {
|
|
1715
1901
|
if (tempDir) {
|
|
1716
|
-
await
|
|
1902
|
+
await fs7.remove(tempDir).catch(() => {
|
|
1717
1903
|
});
|
|
1718
1904
|
}
|
|
1719
|
-
const globalWithSim = globalThis;
|
|
1720
|
-
delete globalWithSim.window;
|
|
1721
|
-
delete globalWithSim.document;
|
|
1722
1905
|
}
|
|
1723
1906
|
}
|
|
1724
1907
|
|
|
1725
1908
|
// src/commands/simulate/index.ts
|
|
1726
1909
|
async function simulateCommand(options) {
|
|
1727
|
-
const logger =
|
|
1728
|
-
|
|
1729
|
-
silent: options.silent ?? false,
|
|
1730
|
-
json: options.json
|
|
1731
|
-
});
|
|
1732
|
-
const dockerArgs = [options.config];
|
|
1910
|
+
const logger = createCommandLogger(options);
|
|
1911
|
+
const dockerArgs = buildCommonDockerArgs(options);
|
|
1733
1912
|
if (options.event) dockerArgs.push("--event", options.event);
|
|
1734
|
-
if (options.json) dockerArgs.push("--json");
|
|
1735
|
-
if (options.verbose) dockerArgs.push("--verbose");
|
|
1736
|
-
if (options.silent) dockerArgs.push("--silent");
|
|
1737
1913
|
await executeCommand(
|
|
1738
1914
|
async () => {
|
|
1739
1915
|
const startTime = Date.now();
|
|
1740
1916
|
try {
|
|
1741
|
-
const event =
|
|
1917
|
+
const event = await loadJsonFromSource(options.event, {
|
|
1918
|
+
name: "event"
|
|
1919
|
+
});
|
|
1742
1920
|
const result = await simulateCore(options.config, event, {
|
|
1743
1921
|
json: options.json,
|
|
1744
1922
|
verbose: options.verbose,
|
|
@@ -1757,7 +1935,7 @@ async function simulateCommand(options) {
|
|
|
1757
1935
|
process.exit(1);
|
|
1758
1936
|
}
|
|
1759
1937
|
} catch (error) {
|
|
1760
|
-
const errorMessage =
|
|
1938
|
+
const errorMessage = getErrorMessage(error);
|
|
1761
1939
|
if (options.json) {
|
|
1762
1940
|
const outputLogger = createLogger({ silent: false, json: false });
|
|
1763
1941
|
const errorOutput = JSON.stringify(
|
|
@@ -1796,13 +1974,249 @@ async function simulate(configOrPath, event, options = {}) {
|
|
|
1796
1974
|
});
|
|
1797
1975
|
}
|
|
1798
1976
|
|
|
1799
|
-
// src/commands/
|
|
1977
|
+
// src/commands/push/index.ts
|
|
1800
1978
|
import path8 from "path";
|
|
1801
1979
|
import os2 from "os";
|
|
1802
|
-
import {
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
1980
|
+
import { JSDOM as JSDOM2, VirtualConsole as VirtualConsole2 } from "jsdom";
|
|
1981
|
+
import fs8 from "fs-extra";
|
|
1982
|
+
async function pushCommand(options) {
|
|
1983
|
+
const logger = createCommandLogger(options);
|
|
1984
|
+
const dockerArgs = buildCommonDockerArgs(options);
|
|
1985
|
+
dockerArgs.push("--event", options.event);
|
|
1986
|
+
if (options.env) dockerArgs.push("--env", options.env);
|
|
1987
|
+
await executeCommand(
|
|
1988
|
+
async () => {
|
|
1989
|
+
const startTime = Date.now();
|
|
1990
|
+
try {
|
|
1991
|
+
logger.info("\u{1F4E5} Loading event...");
|
|
1992
|
+
const event = await loadJsonFromSource(options.event, {
|
|
1993
|
+
name: "event"
|
|
1994
|
+
});
|
|
1995
|
+
if (!event || typeof event !== "object" || !("name" in event) || typeof event.name !== "string") {
|
|
1996
|
+
throw new Error(
|
|
1997
|
+
'Event must be an object with a "name" property (string)'
|
|
1998
|
+
);
|
|
1999
|
+
}
|
|
2000
|
+
if (!event.name.includes(" ")) {
|
|
2001
|
+
logger.warn(
|
|
2002
|
+
`Event name "${event.name}" should follow "ENTITY ACTION" format (e.g., "page view")`
|
|
2003
|
+
);
|
|
2004
|
+
}
|
|
2005
|
+
logger.info("\u{1F4E6} Loading flow configuration...");
|
|
2006
|
+
const configPath = path8.resolve(options.config);
|
|
2007
|
+
const rawConfig = await loadJsonConfig(configPath);
|
|
2008
|
+
const { flowConfig, buildOptions, environment, isMultiEnvironment } = loadBundleConfig(rawConfig, {
|
|
2009
|
+
configPath: options.config,
|
|
2010
|
+
environment: options.env,
|
|
2011
|
+
logger
|
|
2012
|
+
});
|
|
2013
|
+
const platform = flowConfig.platform;
|
|
2014
|
+
logger.info("\u{1F528} Bundling flow configuration...");
|
|
2015
|
+
const tempPath = path8.join(
|
|
2016
|
+
os2.tmpdir(),
|
|
2017
|
+
`walkeros-push-${Date.now()}-${Math.random().toString(36).slice(2, 9)}.${platform === "web" ? "js" : "mjs"}`
|
|
2018
|
+
);
|
|
2019
|
+
const configWithOutput = {
|
|
2020
|
+
flow: flowConfig,
|
|
2021
|
+
build: {
|
|
2022
|
+
...buildOptions,
|
|
2023
|
+
output: tempPath,
|
|
2024
|
+
// Web uses IIFE for browser-like execution, server uses ESM
|
|
2025
|
+
format: platform === "web" ? "iife" : "esm",
|
|
2026
|
+
platform: platform === "web" ? "browser" : "node",
|
|
2027
|
+
...platform === "web" && {
|
|
2028
|
+
windowCollector: "collector",
|
|
2029
|
+
windowElb: "elb"
|
|
2030
|
+
}
|
|
2031
|
+
}
|
|
2032
|
+
};
|
|
2033
|
+
await bundle(configWithOutput, {
|
|
2034
|
+
cache: true,
|
|
2035
|
+
verbose: options.verbose,
|
|
2036
|
+
silent: !options.verbose
|
|
2037
|
+
});
|
|
2038
|
+
logger.debug(`Bundle created: ${tempPath}`);
|
|
2039
|
+
let result;
|
|
2040
|
+
if (platform === "web") {
|
|
2041
|
+
logger.info("\u{1F310} Executing in web environment (JSDOM)...");
|
|
2042
|
+
result = await executeWebPush(tempPath, event, logger);
|
|
2043
|
+
} else if (platform === "server") {
|
|
2044
|
+
logger.info("\u{1F5A5}\uFE0F Executing in server environment (Node.js)...");
|
|
2045
|
+
result = await executeServerPush(tempPath, event, logger);
|
|
2046
|
+
} else {
|
|
2047
|
+
throw new Error(`Unsupported platform: ${platform}`);
|
|
2048
|
+
}
|
|
2049
|
+
const duration = Date.now() - startTime;
|
|
2050
|
+
if (options.json) {
|
|
2051
|
+
const outputLogger = createLogger({ silent: false, json: false });
|
|
2052
|
+
outputLogger.log(
|
|
2053
|
+
"white",
|
|
2054
|
+
JSON.stringify(
|
|
2055
|
+
{
|
|
2056
|
+
success: result.success,
|
|
2057
|
+
event: result.elbResult,
|
|
2058
|
+
duration
|
|
2059
|
+
},
|
|
2060
|
+
null,
|
|
2061
|
+
2
|
|
2062
|
+
)
|
|
2063
|
+
);
|
|
2064
|
+
} else {
|
|
2065
|
+
if (result.success) {
|
|
2066
|
+
logger.success("\u2705 Event pushed successfully");
|
|
2067
|
+
if (result.elbResult && typeof result.elbResult === "object") {
|
|
2068
|
+
const pushResult = result.elbResult;
|
|
2069
|
+
if ("id" in pushResult && pushResult.id) {
|
|
2070
|
+
logger.info(` Event ID: ${pushResult.id}`);
|
|
2071
|
+
}
|
|
2072
|
+
if ("entity" in pushResult && pushResult.entity) {
|
|
2073
|
+
logger.info(` Entity: ${pushResult.entity}`);
|
|
2074
|
+
}
|
|
2075
|
+
if ("action" in pushResult && pushResult.action) {
|
|
2076
|
+
logger.info(` Action: ${pushResult.action}`);
|
|
2077
|
+
}
|
|
2078
|
+
}
|
|
2079
|
+
logger.info(` Duration: ${duration}ms`);
|
|
2080
|
+
} else {
|
|
2081
|
+
logger.error(`\u274C Push failed: ${result.error}`);
|
|
2082
|
+
process.exit(1);
|
|
2083
|
+
}
|
|
2084
|
+
}
|
|
2085
|
+
try {
|
|
2086
|
+
await fs8.remove(tempPath);
|
|
2087
|
+
} catch {
|
|
2088
|
+
}
|
|
2089
|
+
} catch (error) {
|
|
2090
|
+
const duration = Date.now() - startTime;
|
|
2091
|
+
const errorMessage = getErrorMessage(error);
|
|
2092
|
+
if (options.json) {
|
|
2093
|
+
const outputLogger = createLogger({ silent: false, json: false });
|
|
2094
|
+
outputLogger.log(
|
|
2095
|
+
"white",
|
|
2096
|
+
JSON.stringify(
|
|
2097
|
+
{
|
|
2098
|
+
success: false,
|
|
2099
|
+
error: errorMessage,
|
|
2100
|
+
duration
|
|
2101
|
+
},
|
|
2102
|
+
null,
|
|
2103
|
+
2
|
|
2104
|
+
)
|
|
2105
|
+
);
|
|
2106
|
+
} else {
|
|
2107
|
+
logger.error(`\u274C Push command failed: ${errorMessage}`);
|
|
2108
|
+
}
|
|
2109
|
+
process.exit(1);
|
|
2110
|
+
}
|
|
2111
|
+
},
|
|
2112
|
+
"push",
|
|
2113
|
+
dockerArgs,
|
|
2114
|
+
options,
|
|
2115
|
+
logger,
|
|
2116
|
+
options.config
|
|
2117
|
+
);
|
|
2118
|
+
}
|
|
2119
|
+
async function executeWebPush(bundlePath, event, logger) {
|
|
2120
|
+
const startTime = Date.now();
|
|
2121
|
+
try {
|
|
2122
|
+
const virtualConsole = new VirtualConsole2();
|
|
2123
|
+
const dom = new JSDOM2("<!DOCTYPE html><html><body></body></html>", {
|
|
2124
|
+
url: "http://localhost",
|
|
2125
|
+
runScripts: "dangerously",
|
|
2126
|
+
resources: "usable",
|
|
2127
|
+
virtualConsole
|
|
2128
|
+
});
|
|
2129
|
+
const { window } = dom;
|
|
2130
|
+
logger.debug("Loading bundle...");
|
|
2131
|
+
const bundleCode = await fs8.readFile(bundlePath, "utf8");
|
|
2132
|
+
window.eval(bundleCode);
|
|
2133
|
+
logger.debug("Waiting for elb...");
|
|
2134
|
+
await waitForWindowProperty2(
|
|
2135
|
+
window,
|
|
2136
|
+
"elb",
|
|
2137
|
+
5e3
|
|
2138
|
+
);
|
|
2139
|
+
const windowObj = window;
|
|
2140
|
+
const elb = windowObj.elb;
|
|
2141
|
+
logger.info(`Pushing event: ${event.name}`);
|
|
2142
|
+
const eventData = event.data || {};
|
|
2143
|
+
const elbResult = await elb(event.name, eventData);
|
|
2144
|
+
return {
|
|
2145
|
+
success: true,
|
|
2146
|
+
elbResult,
|
|
2147
|
+
duration: Date.now() - startTime
|
|
2148
|
+
};
|
|
2149
|
+
} catch (error) {
|
|
2150
|
+
return {
|
|
2151
|
+
success: false,
|
|
2152
|
+
duration: Date.now() - startTime,
|
|
2153
|
+
error: getErrorMessage(error)
|
|
2154
|
+
};
|
|
2155
|
+
}
|
|
2156
|
+
}
|
|
2157
|
+
async function executeServerPush(bundlePath, event, logger, timeout = 6e4) {
|
|
2158
|
+
const startTime = Date.now();
|
|
2159
|
+
try {
|
|
2160
|
+
const timeoutPromise = new Promise((_, reject) => {
|
|
2161
|
+
setTimeout(
|
|
2162
|
+
() => reject(new Error(`Server push timeout after ${timeout}ms`)),
|
|
2163
|
+
timeout
|
|
2164
|
+
);
|
|
2165
|
+
});
|
|
2166
|
+
const executePromise = (async () => {
|
|
2167
|
+
logger.debug("Importing bundle...");
|
|
2168
|
+
const flowModule = await import(bundlePath);
|
|
2169
|
+
if (!flowModule.default || typeof flowModule.default !== "function") {
|
|
2170
|
+
throw new Error("Bundle does not export default factory function");
|
|
2171
|
+
}
|
|
2172
|
+
logger.debug("Calling factory function...");
|
|
2173
|
+
const result = await flowModule.default();
|
|
2174
|
+
if (!result || !result.elb || typeof result.elb !== "function") {
|
|
2175
|
+
throw new Error(
|
|
2176
|
+
"Factory function did not return valid result with elb"
|
|
2177
|
+
);
|
|
2178
|
+
}
|
|
2179
|
+
const { elb } = result;
|
|
2180
|
+
logger.info(`Pushing event: ${event.name}`);
|
|
2181
|
+
const eventData = event.data || {};
|
|
2182
|
+
const elbResult = await elb(event.name, eventData);
|
|
2183
|
+
return {
|
|
2184
|
+
success: true,
|
|
2185
|
+
elbResult,
|
|
2186
|
+
duration: Date.now() - startTime
|
|
2187
|
+
};
|
|
2188
|
+
})();
|
|
2189
|
+
return await Promise.race([executePromise, timeoutPromise]);
|
|
2190
|
+
} catch (error) {
|
|
2191
|
+
return {
|
|
2192
|
+
success: false,
|
|
2193
|
+
duration: Date.now() - startTime,
|
|
2194
|
+
error: getErrorMessage(error)
|
|
2195
|
+
};
|
|
2196
|
+
}
|
|
2197
|
+
}
|
|
2198
|
+
function waitForWindowProperty2(window, prop, timeout = 5e3) {
|
|
2199
|
+
return new Promise((resolve, reject) => {
|
|
2200
|
+
const start = Date.now();
|
|
2201
|
+
const check = () => {
|
|
2202
|
+
if (window[prop] !== void 0) {
|
|
2203
|
+
resolve();
|
|
2204
|
+
} else if (Date.now() - start > timeout) {
|
|
2205
|
+
reject(
|
|
2206
|
+
new Error(
|
|
2207
|
+
`Timeout waiting for window.${prop}. IIFE may have failed to execute.`
|
|
2208
|
+
)
|
|
2209
|
+
);
|
|
2210
|
+
} else {
|
|
2211
|
+
setImmediate(check);
|
|
2212
|
+
}
|
|
2213
|
+
};
|
|
2214
|
+
check();
|
|
2215
|
+
});
|
|
2216
|
+
}
|
|
2217
|
+
|
|
2218
|
+
// src/commands/run/index.ts
|
|
2219
|
+
import path10 from "path";
|
|
1806
2220
|
|
|
1807
2221
|
// src/commands/run/validators.ts
|
|
1808
2222
|
import { existsSync } from "fs";
|
|
@@ -1837,58 +2251,108 @@ function validatePort(port) {
|
|
|
1837
2251
|
}
|
|
1838
2252
|
}
|
|
1839
2253
|
|
|
2254
|
+
// src/commands/run/utils.ts
|
|
2255
|
+
import path9 from "path";
|
|
2256
|
+
import os3 from "os";
|
|
2257
|
+
async function prepareBundleForRun(configPath, options) {
|
|
2258
|
+
const rawConfig = await loadJsonConfig(configPath);
|
|
2259
|
+
const tempPath = path9.join(
|
|
2260
|
+
os3.tmpdir(),
|
|
2261
|
+
`walkeros-${Date.now()}-${Math.random().toString(36).slice(2, 9)}.mjs`
|
|
2262
|
+
);
|
|
2263
|
+
const existingBuild = typeof rawConfig === "object" && rawConfig !== null && "build" in rawConfig && typeof rawConfig.build === "object" ? rawConfig.build : {};
|
|
2264
|
+
const configWithOutput = {
|
|
2265
|
+
...rawConfig,
|
|
2266
|
+
build: {
|
|
2267
|
+
...existingBuild,
|
|
2268
|
+
output: tempPath
|
|
2269
|
+
}
|
|
2270
|
+
};
|
|
2271
|
+
await bundle(configWithOutput, {
|
|
2272
|
+
cache: true,
|
|
2273
|
+
verbose: options.verbose,
|
|
2274
|
+
silent: options.silent
|
|
2275
|
+
});
|
|
2276
|
+
return tempPath;
|
|
2277
|
+
}
|
|
2278
|
+
function isPreBuiltConfig(configPath) {
|
|
2279
|
+
return configPath.endsWith(".mjs") || configPath.endsWith(".js") || configPath.endsWith(".cjs");
|
|
2280
|
+
}
|
|
2281
|
+
|
|
2282
|
+
// src/commands/run/execution.ts
|
|
2283
|
+
import { runFlow, runServeMode } from "@walkeros/docker";
|
|
2284
|
+
async function executeRunLocal(mode, flowPath, options) {
|
|
2285
|
+
switch (mode) {
|
|
2286
|
+
case "collect": {
|
|
2287
|
+
if (!flowPath) {
|
|
2288
|
+
throw new Error("Flow path is required for collect mode");
|
|
2289
|
+
}
|
|
2290
|
+
const config = {
|
|
2291
|
+
port: options.port,
|
|
2292
|
+
host: options.host
|
|
2293
|
+
};
|
|
2294
|
+
await runFlow(flowPath, config);
|
|
2295
|
+
break;
|
|
2296
|
+
}
|
|
2297
|
+
case "serve": {
|
|
2298
|
+
const config = {
|
|
2299
|
+
port: options.port,
|
|
2300
|
+
host: options.host,
|
|
2301
|
+
serveName: options.serveName,
|
|
2302
|
+
servePath: options.servePath,
|
|
2303
|
+
filePath: flowPath || void 0
|
|
2304
|
+
};
|
|
2305
|
+
await runServeMode(config);
|
|
2306
|
+
break;
|
|
2307
|
+
}
|
|
2308
|
+
default:
|
|
2309
|
+
throw new Error(`Unknown mode: ${mode}`);
|
|
2310
|
+
}
|
|
2311
|
+
}
|
|
2312
|
+
|
|
1840
2313
|
// src/commands/run/index.ts
|
|
1841
2314
|
async function runCommand(mode, options) {
|
|
1842
2315
|
const timer = createTimer();
|
|
1843
2316
|
timer.start();
|
|
1844
|
-
const logger =
|
|
1845
|
-
verbose: options.verbose,
|
|
1846
|
-
silent: options.silent ?? false,
|
|
1847
|
-
json: options.json
|
|
1848
|
-
});
|
|
2317
|
+
const logger = createCommandLogger(options);
|
|
1849
2318
|
try {
|
|
1850
2319
|
validateMode(mode);
|
|
1851
2320
|
const configPath = validateFlowFile(options.config);
|
|
1852
2321
|
if (options.port !== void 0) {
|
|
1853
2322
|
validatePort(options.port);
|
|
1854
2323
|
}
|
|
1855
|
-
const isPreBuilt =
|
|
2324
|
+
const isPreBuilt = isPreBuiltConfig(configPath);
|
|
1856
2325
|
let flowPath = null;
|
|
1857
2326
|
if (mode === "collect") {
|
|
1858
2327
|
if (isPreBuilt) {
|
|
1859
|
-
flowPath =
|
|
2328
|
+
flowPath = path10.resolve(configPath);
|
|
1860
2329
|
if (!options.json && !options.silent) {
|
|
1861
|
-
logger.info(`\u{1F4E6} Using pre-built flow: ${
|
|
2330
|
+
logger.info(`\u{1F4E6} Using pre-built flow: ${path10.basename(flowPath)}`);
|
|
1862
2331
|
}
|
|
1863
2332
|
} else {
|
|
1864
2333
|
if (!options.json && !options.silent) {
|
|
1865
2334
|
logger.info("\u{1F528} Building flow bundle...");
|
|
1866
2335
|
}
|
|
1867
|
-
|
|
1868
|
-
const tempPath = path8.join(
|
|
1869
|
-
os2.tmpdir(),
|
|
1870
|
-
`walkeros-${Date.now()}-${Math.random().toString(36).slice(2, 9)}.mjs`
|
|
1871
|
-
);
|
|
1872
|
-
const existingBuild = typeof rawConfig === "object" && rawConfig !== null && "build" in rawConfig && typeof rawConfig.build === "object" ? rawConfig.build : {};
|
|
1873
|
-
const configWithOutput = {
|
|
1874
|
-
...rawConfig,
|
|
1875
|
-
build: {
|
|
1876
|
-
...existingBuild,
|
|
1877
|
-
output: tempPath
|
|
1878
|
-
}
|
|
1879
|
-
};
|
|
1880
|
-
await bundle(configWithOutput, {
|
|
1881
|
-
cache: true,
|
|
2336
|
+
flowPath = await prepareBundleForRun(configPath, {
|
|
1882
2337
|
verbose: options.verbose,
|
|
1883
2338
|
silent: options.json || options.silent
|
|
1884
2339
|
});
|
|
1885
|
-
flowPath = tempPath;
|
|
1886
2340
|
if (!options.json && !options.silent) {
|
|
1887
2341
|
logger.success("\u2705 Bundle ready");
|
|
1888
2342
|
}
|
|
1889
2343
|
}
|
|
1890
2344
|
}
|
|
1891
2345
|
const executionMode = getExecutionMode(options);
|
|
2346
|
+
if (options.dryRun) {
|
|
2347
|
+
if (executionMode === "docker") {
|
|
2348
|
+
logger.info(
|
|
2349
|
+
`[DRY-RUN] Would execute in Docker: run ${mode} with runtime image`
|
|
2350
|
+
);
|
|
2351
|
+
} else {
|
|
2352
|
+
logger.info(`[DRY-RUN] Would execute locally: run ${mode}`);
|
|
2353
|
+
}
|
|
2354
|
+
return;
|
|
2355
|
+
}
|
|
1892
2356
|
if (executionMode === "docker") {
|
|
1893
2357
|
const dockerAvailable = await isDockerAvailable();
|
|
1894
2358
|
if (!dockerAvailable) {
|
|
@@ -1911,36 +2375,16 @@ async function runCommand(mode, options) {
|
|
|
1911
2375
|
const modeLabel = mode === "collect" ? "Collector" : "Server";
|
|
1912
2376
|
logger.info(`\u{1F5A5}\uFE0F Starting ${modeLabel} locally...`);
|
|
1913
2377
|
}
|
|
1914
|
-
|
|
1915
|
-
|
|
1916
|
-
|
|
1917
|
-
|
|
1918
|
-
|
|
1919
|
-
|
|
1920
|
-
port: options.port,
|
|
1921
|
-
host: options.host
|
|
1922
|
-
};
|
|
1923
|
-
await runFlow(flowPath, config);
|
|
1924
|
-
break;
|
|
1925
|
-
}
|
|
1926
|
-
case "serve": {
|
|
1927
|
-
const config = {
|
|
1928
|
-
port: options.port,
|
|
1929
|
-
host: options.host,
|
|
1930
|
-
serveName: options.serveName,
|
|
1931
|
-
servePath: options.servePath,
|
|
1932
|
-
filePath: flowPath || void 0
|
|
1933
|
-
};
|
|
1934
|
-
await runServeMode(config);
|
|
1935
|
-
break;
|
|
1936
|
-
}
|
|
1937
|
-
default:
|
|
1938
|
-
throw new Error(`Unknown mode: ${mode}`);
|
|
1939
|
-
}
|
|
2378
|
+
await executeRunLocal(mode, flowPath, {
|
|
2379
|
+
port: options.port,
|
|
2380
|
+
host: options.host,
|
|
2381
|
+
serveName: options.serveName,
|
|
2382
|
+
servePath: options.servePath
|
|
2383
|
+
});
|
|
1940
2384
|
}
|
|
1941
2385
|
} catch (error) {
|
|
1942
2386
|
const duration = timer.getElapsed() / 1e3;
|
|
1943
|
-
const errorMessage =
|
|
2387
|
+
const errorMessage = getErrorMessage(error);
|
|
1944
2388
|
if (options.json) {
|
|
1945
2389
|
const output = {
|
|
1946
2390
|
success: false,
|
|
@@ -1969,54 +2413,22 @@ async function run(mode, options) {
|
|
|
1969
2413
|
if (options.port !== void 0) {
|
|
1970
2414
|
validatePort(options.port);
|
|
1971
2415
|
}
|
|
1972
|
-
const isPreBuilt =
|
|
2416
|
+
const isPreBuilt = isPreBuiltConfig(flowFile);
|
|
1973
2417
|
let flowPath;
|
|
1974
2418
|
if (isPreBuilt) {
|
|
1975
|
-
flowPath =
|
|
2419
|
+
flowPath = path10.resolve(flowFile);
|
|
1976
2420
|
} else {
|
|
1977
|
-
|
|
1978
|
-
const tempPath = path8.join(
|
|
1979
|
-
os2.tmpdir(),
|
|
1980
|
-
`walkeros-${Date.now()}-${Math.random().toString(36).slice(2, 9)}.mjs`
|
|
1981
|
-
);
|
|
1982
|
-
const existingBuild = typeof rawConfig === "object" && rawConfig !== null && "build" in rawConfig && typeof rawConfig.build === "object" ? rawConfig.build : {};
|
|
1983
|
-
const configWithOutput = {
|
|
1984
|
-
...rawConfig,
|
|
1985
|
-
build: {
|
|
1986
|
-
...existingBuild,
|
|
1987
|
-
output: tempPath
|
|
1988
|
-
}
|
|
1989
|
-
};
|
|
1990
|
-
await bundle(configWithOutput, {
|
|
1991
|
-
cache: true,
|
|
2421
|
+
flowPath = await prepareBundleForRun(flowFile, {
|
|
1992
2422
|
verbose: options.verbose,
|
|
1993
2423
|
silent: true
|
|
1994
2424
|
});
|
|
1995
|
-
flowPath = tempPath;
|
|
1996
|
-
}
|
|
1997
|
-
switch (mode) {
|
|
1998
|
-
case "collect": {
|
|
1999
|
-
const config = {
|
|
2000
|
-
port: options.port,
|
|
2001
|
-
host: options.host
|
|
2002
|
-
};
|
|
2003
|
-
await runFlow(flowPath, config);
|
|
2004
|
-
break;
|
|
2005
|
-
}
|
|
2006
|
-
case "serve": {
|
|
2007
|
-
const config = {
|
|
2008
|
-
port: options.port,
|
|
2009
|
-
host: options.host,
|
|
2010
|
-
serveName: options.serveName,
|
|
2011
|
-
servePath: options.servePath,
|
|
2012
|
-
filePath: flowPath
|
|
2013
|
-
};
|
|
2014
|
-
await runServeMode(config);
|
|
2015
|
-
break;
|
|
2016
|
-
}
|
|
2017
|
-
default:
|
|
2018
|
-
throw new Error(`Unknown mode: ${mode}`);
|
|
2019
2425
|
}
|
|
2426
|
+
await executeRunLocal(mode, flowPath, {
|
|
2427
|
+
port: options.port,
|
|
2428
|
+
host: options.host,
|
|
2429
|
+
serveName: options.serveName,
|
|
2430
|
+
servePath: options.servePath
|
|
2431
|
+
});
|
|
2020
2432
|
return {
|
|
2021
2433
|
success: true,
|
|
2022
2434
|
exitCode: 0,
|
|
@@ -2027,7 +2439,7 @@ async function run(mode, options) {
|
|
|
2027
2439
|
success: false,
|
|
2028
2440
|
exitCode: 1,
|
|
2029
2441
|
duration: Date.now() - startTime,
|
|
2030
|
-
error:
|
|
2442
|
+
error: getErrorMessage(error)
|
|
2031
2443
|
};
|
|
2032
2444
|
}
|
|
2033
2445
|
}
|
|
@@ -2058,7 +2470,10 @@ program.command("bundle [file]").description("Bundle NPM packages with custom co
|
|
|
2058
2470
|
silent: options.silent
|
|
2059
2471
|
});
|
|
2060
2472
|
});
|
|
2061
|
-
program.command("simulate [file]").description("Simulate event processing and capture API calls").option(
|
|
2473
|
+
program.command("simulate [file]").description("Simulate event processing and capture API calls").option(
|
|
2474
|
+
"-e, --event <source>",
|
|
2475
|
+
"Event to simulate (JSON string, file path, or URL)"
|
|
2476
|
+
).option("--json", "Output results as JSON").option("-v, --verbose", "Verbose output").option("--local", "execute in local Node.js instead of Docker").option("--dry-run", "preview command without executing").option("--silent", "suppress output").action(async (file, options) => {
|
|
2062
2477
|
await simulateCommand({
|
|
2063
2478
|
config: file || "bundle.config.json",
|
|
2064
2479
|
event: options.event,
|
|
@@ -2069,6 +2484,20 @@ program.command("simulate [file]").description("Simulate event processing and ca
|
|
|
2069
2484
|
silent: options.silent
|
|
2070
2485
|
});
|
|
2071
2486
|
});
|
|
2487
|
+
program.command("push [file]").description("Push an event through the flow with real API execution").requiredOption(
|
|
2488
|
+
"-e, --event <source>",
|
|
2489
|
+
"Event to push (JSON string, file path, or URL)"
|
|
2490
|
+
).option("--env <name>", "Environment name (for multi-environment configs)").option("--json", "Output results as JSON").option("-v, --verbose", "Verbose output").option("-s, --silent", "Suppress output").option("--local", "Execute in local Node.js instead of Docker").action(async (file, options) => {
|
|
2491
|
+
await pushCommand({
|
|
2492
|
+
config: file || "bundle.config.json",
|
|
2493
|
+
event: options.event,
|
|
2494
|
+
env: options.env,
|
|
2495
|
+
json: options.json,
|
|
2496
|
+
verbose: options.verbose,
|
|
2497
|
+
silent: options.silent,
|
|
2498
|
+
local: options.local
|
|
2499
|
+
});
|
|
2500
|
+
});
|
|
2072
2501
|
var runCmd = program.command("run").description("Run walkerOS flows in collect or serve mode");
|
|
2073
2502
|
runCmd.command("collect [file]").description(
|
|
2074
2503
|
"Run collector mode (event collection endpoint). Defaults to server-collect.mjs if no file specified."
|
|
@@ -2085,10 +2514,10 @@ runCmd.command("collect [file]").description(
|
|
|
2085
2514
|
});
|
|
2086
2515
|
});
|
|
2087
2516
|
runCmd.command("serve [file]").description(
|
|
2088
|
-
"Run serve mode (single-file server for browser bundles). Defaults to baked-in web-serve.
|
|
2517
|
+
"Run serve mode (single-file server for browser bundles). Defaults to baked-in web-serve.js if no file specified."
|
|
2089
2518
|
).option("-p, --port <number>", "Port to listen on (default: 8080)", parseInt).option("-h, --host <address>", "Host address (default: 0.0.0.0)").option("--name <filename>", "Filename in URL (default: walker.js)").option("--path <directory>", "URL directory path (e.g., libs/v1)").option("--json", "Output results as JSON").option("-v, --verbose", "Verbose output").option("--local", "execute in local Node.js instead of Docker").option("--dry-run", "preview command without executing").option("--silent", "suppress output").action(async (file, options) => {
|
|
2090
2519
|
await runCommand("serve", {
|
|
2091
|
-
config: file || "web-serve.
|
|
2520
|
+
config: file || "web-serve.js",
|
|
2092
2521
|
port: options.port,
|
|
2093
2522
|
host: options.host,
|
|
2094
2523
|
serveName: options.name,
|
|
@@ -2104,6 +2533,7 @@ program.parse();
|
|
|
2104
2533
|
export {
|
|
2105
2534
|
bundle,
|
|
2106
2535
|
bundleCommand,
|
|
2536
|
+
pushCommand,
|
|
2107
2537
|
run,
|
|
2108
2538
|
runCommand,
|
|
2109
2539
|
simulate,
|