@walkeros/cli 0.4.1 → 0.5.0
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 +26 -0
- package/README.md +247 -46
- package/dist/__tests__/bundle/bundler-helpers.test.js +0 -134
- package/dist/__tests__/bundle/bundler-helpers.test.js.map +1 -1
- package/dist/__tests__/bundle/bundler.test.js +253 -183
- package/dist/__tests__/bundle/bundler.test.js.map +1 -1
- package/dist/__tests__/bundle/programmatic.test.js +74 -53
- package/dist/__tests__/bundle/programmatic.test.js.map +1 -1
- package/dist/__tests__/cli.test.js +58 -46
- package/dist/__tests__/cli.test.js.map +1 -1
- package/dist/__tests__/config-loader.test.d.ts +1 -1
- package/dist/__tests__/config-loader.test.js +229 -212
- package/dist/__tests__/config-loader.test.js.map +1 -1
- package/dist/__tests__/core/build-cache.test.d.ts +2 -0
- package/dist/__tests__/core/build-cache.test.d.ts.map +1 -0
- package/dist/__tests__/core/build-cache.test.js +55 -0
- package/dist/__tests__/core/build-cache.test.js.map +1 -0
- package/dist/__tests__/core/cache-utils.test.d.ts +2 -0
- package/dist/__tests__/core/cache-utils.test.d.ts.map +1 -0
- package/dist/__tests__/core/cache-utils.test.js +70 -0
- package/dist/__tests__/core/cache-utils.test.js.map +1 -0
- package/dist/__tests__/integration/bundle-run.integration.test.js +8 -4
- package/dist/__tests__/integration/bundle-run.integration.test.js.map +1 -1
- package/dist/__tests__/simulate/node-executor.test.d.ts +5 -0
- package/dist/__tests__/simulate/node-executor.test.d.ts.map +1 -0
- package/dist/__tests__/simulate/node-executor.test.js +25 -0
- package/dist/__tests__/simulate/node-executor.test.js.map +1 -0
- package/dist/__tests__/simulate/server-simulate.integration.test.d.ts +5 -0
- package/dist/__tests__/simulate/server-simulate.integration.test.d.ts.map +1 -0
- package/dist/__tests__/simulate/server-simulate.integration.test.js +58 -0
- package/dist/__tests__/simulate/server-simulate.integration.test.js.map +1 -0
- package/dist/__tests__/smoke/production.smoke.test.js +9 -2
- package/dist/__tests__/smoke/production.smoke.test.js.map +1 -1
- package/dist/commands/bundle/bundler.d.ts +18 -0
- package/dist/commands/bundle/bundler.d.ts.map +1 -1
- package/dist/commands/bundle/bundler.js +286 -80
- package/dist/commands/bundle/bundler.js.map +1 -1
- package/dist/commands/bundle/index.d.ts +16 -10
- package/dist/commands/bundle/index.d.ts.map +1 -1
- package/dist/commands/bundle/index.js +44 -32
- package/dist/commands/bundle/index.js.map +1 -1
- package/dist/commands/bundle/package-manager.d.ts +2 -1
- package/dist/commands/bundle/package-manager.d.ts.map +1 -1
- package/dist/commands/bundle/package-manager.js +34 -7
- package/dist/commands/bundle/package-manager.js.map +1 -1
- package/dist/commands/cache.d.ts +3 -0
- package/dist/commands/cache.d.ts.map +1 -0
- package/dist/commands/cache.js +44 -0
- package/dist/commands/cache.js.map +1 -0
- package/dist/commands/push/index.d.ts.map +1 -1
- package/dist/commands/push/index.js +49 -44
- package/dist/commands/push/index.js.map +1 -1
- package/dist/commands/push/types.d.ts +1 -1
- package/dist/commands/push/types.d.ts.map +1 -1
- package/dist/commands/run/__tests__/run.integration.test.js +14 -15
- package/dist/commands/run/__tests__/run.integration.test.js.map +1 -1
- package/dist/commands/run/execution.d.ts.map +1 -1
- package/dist/commands/run/execution.js +6 -2
- package/dist/commands/run/execution.js.map +1 -1
- package/dist/commands/run/utils.d.ts +4 -1
- package/dist/commands/run/utils.d.ts.map +1 -1
- package/dist/commands/run/utils.js +18 -24
- package/dist/commands/run/utils.js.map +1 -1
- package/dist/commands/run/validators.d.ts +9 -5
- package/dist/commands/run/validators.d.ts.map +1 -1
- package/dist/commands/run/validators.js +14 -11
- package/dist/commands/run/validators.js.map +1 -1
- package/dist/commands/simulate/index.d.ts +1 -0
- package/dist/commands/simulate/index.d.ts.map +1 -1
- package/dist/commands/simulate/index.js +1 -0
- package/dist/commands/simulate/index.js.map +1 -1
- package/dist/commands/simulate/node-executor.d.ts +28 -0
- package/dist/commands/simulate/node-executor.d.ts.map +1 -0
- package/dist/commands/simulate/node-executor.js +94 -0
- package/dist/commands/simulate/node-executor.js.map +1 -0
- package/dist/commands/simulate/simulator.d.ts.map +1 -1
- package/dist/commands/simulate/simulator.js +36 -32
- package/dist/commands/simulate/simulator.js.map +1 -1
- package/dist/config/build-defaults.d.ts +49 -0
- package/dist/config/build-defaults.d.ts.map +1 -0
- package/dist/config/build-defaults.js +70 -0
- package/dist/config/build-defaults.js.map +1 -0
- package/dist/config/index.d.ts +6 -7
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/index.js +6 -7
- package/dist/config/index.js.map +1 -1
- package/dist/config/loader.d.ts +34 -27
- package/dist/config/loader.d.ts.map +1 -1
- package/dist/config/loader.js +107 -92
- package/dist/config/loader.js.map +1 -1
- package/dist/config/validators.d.ts +34 -8
- package/dist/config/validators.d.ts.map +1 -1
- package/dist/config/validators.js +59 -21
- package/dist/config/validators.js.map +1 -1
- package/dist/core/asset-resolver.d.ts +9 -16
- package/dist/core/asset-resolver.d.ts.map +1 -1
- package/dist/core/asset-resolver.js +30 -41
- package/dist/core/asset-resolver.js.map +1 -1
- package/dist/core/build-cache.d.ts +23 -0
- package/dist/core/build-cache.d.ts.map +1 -0
- package/dist/core/build-cache.js +43 -0
- package/dist/core/build-cache.js.map +1 -0
- package/dist/core/cache-utils.d.ts +27 -0
- package/dist/core/cache-utils.d.ts.map +1 -0
- package/dist/core/cache-utils.js +60 -0
- package/dist/core/cache-utils.js.map +1 -0
- package/dist/core/docker.d.ts.map +1 -1
- package/dist/core/docker.js +14 -27
- package/dist/core/docker.js.map +1 -1
- package/dist/core/index.d.ts +1 -0
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +1 -0
- package/dist/core/index.js.map +1 -1
- package/dist/core/local-packages.d.ts +19 -0
- package/dist/core/local-packages.d.ts.map +1 -0
- package/dist/core/local-packages.js +60 -0
- package/dist/core/local-packages.js.map +1 -0
- package/dist/examples/.npm-cache/content-v2/sha512/0d/2d/7581c288670eaf8538ddd9df145b78756ce3be0791c6e0b9cd33429b3bae894525b9bda287a3cedffbcdd2c7b3107bafc03f2b0367eea489eee1cc042abb +1 -0
- package/dist/examples/.npm-cache/content-v2/sha512/12/20/bc4f5acca143809f7e07da1fdafb38137d93243de4d5b403e6e10b92d0d3a6e51eab24fe9dbc9d3ed1cd72e8f7a406085e99c422bb2c7d1166cf9f1f564e +0 -0
- package/dist/examples/.npm-cache/content-v2/sha512/22/ee/fb2695b01871c1d36946bdcfb49f1b520a57200d0a0b221b1e7d5f047ab38a8b2ab0e5f0e25a00acde1f3f2f9d24430a18f1092d438bc1a9e9891cc45f75 +0 -0
- package/dist/examples/.npm-cache/content-v2/sha512/24/89/da1ce6a61bca6de7e132f241a675c01c83738bf6b78af25b5cce01d3030361332b3fe938571e2b721f1555da9ddf930fdcf8c02f0471556071590e68cc09 +0 -0
- package/dist/examples/.npm-cache/content-v2/sha512/47/fd/c6be997da99228c3e279b95d4a46d6913947078a178f54ac71795a159f3513b1483232f4c2d0a1f403178bf9f96bb19615de32a9e2133e949880c6bc15e2 +0 -0
- package/dist/examples/.npm-cache/content-v2/sha512/4b/1c/c1cb7f8b32102071a89fef97158daa32080ebaedfbbd596880d2213d84e305abc76d2a95a412ded55c1c3d487adcb1ceff87fc2c85d7e2856ebd9d3f16f3 +0 -0
- package/dist/examples/.npm-cache/content-v2/sha512/6e/53/ff864769671f44f39d8a3bf904cd646535b745cc4824a8bb3189193b474678049f43b5178ba15cad7f0289046105e70f1565afc84e907120b35a466690fd +1 -0
- package/dist/examples/.npm-cache/content-v2/sha512/70/4c/4c8837d446965c5551b4ea527e95fa011744fb727581d82cf35bb5599ea0b57d18baa490f7af93ef9a16e8e45e5c0802737da20575f4056a4a5c9a3cd288 +0 -0
- package/dist/examples/.npm-cache/content-v2/sha512/96/ad/05de3bbb12d7de8ea353f962bdaea7d2eb44f707f2973462a6635daf537c67b46cca7764fed7d464fe62152c3f783a07aba1ceb35e09ad446bff05a4b466 +1 -0
- package/dist/examples/.npm-cache/content-v2/sha512/b5/20/52dde94e6cef7170f6089c64a4843e57be18be450d956f4e455905aed047ae6a368451c93035e6ac3ee59576b600f03f815afba0836b3a16e10a9aaca4ba +1 -0
- package/dist/examples/.npm-cache/content-v2/sha512/c7/a9/d166a1c39f97df312c59261319ba1cf9aac178bda0a0cb697d5ddd78bd8dd38ef1bf40017bcc8633c2049896c2d70696d9bff9280851f270792ff38bb3a0 +1 -0
- package/dist/examples/.npm-cache/content-v2/sha512/e0/d0/8c14083b633e6adbd3c6a93da5fc0f6bbd456c5512ef276920bedd8d85d551052adff992de977aff326616a211aaa2d6ddcc801149e9b7f914f566359b6a +1 -0
- package/dist/examples/.npm-cache/content-v2/sha512/e7/c5/06ad3fd79ac4f1031fe0b16ea5e54e232ca397bbcd7592c679021cbfb027276099f8c848f3f7a7691f0102ad53aa64f9141e61d729b037a678bd60440d17 +1 -0
- package/dist/examples/.npm-cache/content-v2/sha512/f3/28/d5d32329604ed7d471a4949105daa2cc98858cf24f45b0b97c41d0eb0d5a9fe7bf1f69c792161cc6693e4fc1b52e886ac41875ebfb8fe47fafe417ca3e6e +0 -0
- package/dist/examples/.npm-cache/index-v5/04/5a/2b5d7a7c407d85d746baa0f5c9388a333e35a717a8a0a81943daa6cb1364 +3 -0
- package/dist/examples/.npm-cache/index-v5/12/9a/eba560cbace295d8ee04cf283015377bd77b379e70968fb6bc407c7fc410 +15 -0
- package/dist/examples/.npm-cache/index-v5/2f/a2/7b047564b0ee21ac835ec609e89153dd6549be554d098584d5bfd19fe043 +15 -0
- package/dist/examples/.npm-cache/index-v5/32/8e/322d58dd8d1e000be248ada51385bf96288e56039de9feec1a4c6a467653 +3 -0
- package/dist/examples/.npm-cache/index-v5/57/93/d1d7cd1402e3e26468db03f2870822bb2c9018a506cdfb3b405f38cd3e1c +3 -0
- package/dist/examples/.npm-cache/index-v5/5d/f8/0a1f4fa7149e4ff33e09eb6aea41ac8d1730c868a5d3ace91f762698acff +3 -0
- package/dist/examples/.npm-cache/index-v5/69/a4/a92c72d838259b051cdf8e0acfb2bc680b6d4cfc642314a7836c3f7b2c50 +15 -0
- package/dist/examples/.npm-cache/index-v5/71/31/6da3423bb203f3de5eb16c942431073f89be2cfcb40058ec91dcb5ce0abc +15 -0
- package/dist/examples/.npm-cache/index-v5/7b/94/72b6bffa050d9ef52a558dd220663695bc606f756be0dfa196ef4f3913ba +3 -0
- package/dist/examples/.npm-cache/index-v5/85/9e/99e97fdd562517e56285337db91d1a8f2f416b8d631cf4d7d754fa671299 +15 -0
- package/dist/examples/.npm-cache/index-v5/92/4c/9416ada81a9b3c679539fd1ab53f8de3d41ff268f35eba7a194389a85b06 +3 -0
- package/dist/examples/.npm-cache/index-v5/c1/5a/13df76b218deed8a6ef12961116af5183db98c53fad1b922fd9edc075247 +3 -0
- package/dist/examples/.npm-cache/index-v5/cb/11/253c55410a8ab7c4a9ea9d6e1bf8ef1450a581da64c478074dfd82c8bff6 +3 -0
- package/dist/examples/.npm-cache/index-v5/d5/ae/b57fad3a62b5ba2dbdf24b042a9e7b70820f3db00e5a630f02e1fea020dc +3 -0
- package/dist/examples/.npm-cache/index-v5/d6/32/2f620f83c7d14451de98de8298c2408e05a16cc0829bd16c891ac19d7a67 +3 -0
- package/dist/examples/.npm-cache/index-v5/dd/b5/01dc7a3cd8b6a03a69aee9af500d51ae19cb0aa12631a4aafd152148b8e5 +15 -0
- package/dist/examples/.npm-cache/index-v5/e0/cf/6b862c15d74630d3871cd813d305210ab741311deb10baf8813014e0bc30 +3 -0
- package/dist/examples/.npm-cache/index-v5/e2/be/e880ccd35950a814d3c1dded34d3938ac61b15a195321dc51357f801aad4 +15 -0
- package/dist/examples/.npm-cache/index-v5/e5/1f/f4affe0b392cd03288f23cc03abcb274ff11a2c8f8965299de681914abb2 +3 -0
- package/dist/examples/.npm-cache/index-v5/f3/5b/9ebe450958ff0d7cc44ab0a00080cb8a3ff1389744b5eab5f97b68a6a6af +3 -0
- package/dist/examples/.npm-cache/index-v5/fb/c1/0de405e902866d53e7c30cf36a97dc2578838622b261816f44dc377c9a80 +3 -0
- package/dist/examples/README.md +355 -0
- package/dist/examples/event.json +53 -0
- package/dist/examples/flow-order-complete.json +67 -0
- package/dist/examples/flow-simple.json +31 -0
- package/dist/examples/flow.json +82 -0
- package/dist/examples/server-collect.json +60 -0
- package/dist/examples/server-collect.mjs +13540 -0
- package/dist/examples/test.html +43 -0
- package/dist/examples/web-serve.js +25503 -0
- package/dist/examples/web-serve.json +74 -0
- package/dist/index.d.ts +80 -310
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +924 -736
- package/dist/index.js.map +1 -1
- package/dist/schemas/index.d.ts +9 -0
- package/dist/schemas/index.d.ts.map +1 -0
- package/dist/schemas/index.js +9 -0
- package/dist/schemas/index.js.map +1 -0
- package/dist/schemas/primitives.d.ts +37 -0
- package/dist/schemas/primitives.d.ts.map +1 -0
- package/dist/schemas/primitives.js +43 -0
- package/dist/schemas/primitives.js.map +1 -0
- package/dist/schemas/run.d.ts +23 -0
- package/dist/schemas/run.d.ts.map +1 -0
- package/dist/schemas/run.js +20 -0
- package/dist/schemas/run.js.map +1 -0
- package/dist/types/bundle.d.ts +64 -191
- package/dist/types/bundle.d.ts.map +1 -1
- package/dist/types/bundle.js +2 -2
- package/dist/walker.js +1 -0
- package/examples/README.md +55 -30
- package/examples/flow-order-complete.json +56 -57
- package/examples/flow-simple.json +24 -25
- package/examples/flow.json +69 -69
- package/examples/server-collect.json +51 -44
- package/examples/server-collect.mjs +1 -1
- package/examples/web-serve.json +62 -63
- package/package.json +2 -4
- package/dist/__tests__/bundle/serializer.test.d.ts +0 -2
- package/dist/__tests__/bundle/serializer.test.d.ts.map +0 -1
- package/dist/__tests__/bundle/serializer.test.js +0 -173
- package/dist/__tests__/bundle/serializer.test.js.map +0 -1
- package/dist/__tests__/bundle/template-engine.test.d.ts +0 -2
- package/dist/__tests__/bundle/template-engine.test.d.ts.map +0 -1
- package/dist/__tests__/bundle/template-engine.test.js +0 -107
- package/dist/__tests__/bundle/template-engine.test.js.map +0 -1
- package/dist/commands/bundle/serializer.d.ts +0 -23
- package/dist/commands/bundle/serializer.d.ts.map +0 -1
- package/dist/commands/bundle/serializer.js +0 -127
- package/dist/commands/bundle/serializer.js.map +0 -1
- package/dist/commands/bundle/template-engine.d.ts +0 -20
- package/dist/commands/bundle/template-engine.d.ts.map +0 -1
- package/dist/commands/bundle/template-engine.js +0 -54
- package/dist/commands/bundle/template-engine.js.map +0 -1
- package/dist/config/defaults.d.ts +0 -33
- package/dist/config/defaults.d.ts.map +0 -1
- package/dist/config/defaults.js +0 -69
- package/dist/config/defaults.js.map +0 -1
- package/dist/config/parser.d.ts +0 -128
- package/dist/config/parser.d.ts.map +0 -1
- package/dist/config/parser.js +0 -256
- package/dist/config/parser.js.map +0 -1
- package/dist/types/template.d.ts +0 -108
- package/dist/types/template.d.ts.map +0 -1
- package/dist/types/template.js +0 -10
- package/dist/types/template.js.map +0 -1
- package/templates/server.hbs +0 -29
- package/templates/web.hbs +0 -45
package/dist/index.js
CHANGED
|
@@ -2,9 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
// src/index.ts
|
|
4
4
|
import { Command } from "commander";
|
|
5
|
-
import { readFileSync
|
|
6
|
-
import { fileURLToPath as
|
|
5
|
+
import { readFileSync } from "fs";
|
|
6
|
+
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
7
7
|
import { dirname, join } from "path";
|
|
8
|
+
import { VERSION as DOCKER_VERSION2 } from "@walkeros/docker";
|
|
9
|
+
|
|
10
|
+
// src/commands/bundle/index.ts
|
|
11
|
+
import path9 from "path";
|
|
8
12
|
|
|
9
13
|
// src/core/logger.ts
|
|
10
14
|
import chalk from "chalk";
|
|
@@ -131,8 +135,6 @@ function formatBytes(bytes) {
|
|
|
131
135
|
// src/core/docker.ts
|
|
132
136
|
import { spawn } from "child_process";
|
|
133
137
|
import path2 from "path";
|
|
134
|
-
import { readFileSync } from "fs";
|
|
135
|
-
import { fileURLToPath } from "url";
|
|
136
138
|
import { VERSION as DOCKER_VERSION } from "@walkeros/docker";
|
|
137
139
|
|
|
138
140
|
// src/config/utils.ts
|
|
@@ -262,20 +264,7 @@ async function loadJsonFromSource(source, options) {
|
|
|
262
264
|
}
|
|
263
265
|
|
|
264
266
|
// src/core/docker.ts
|
|
265
|
-
|
|
266
|
-
const moduleFilename = fileURLToPath(import.meta.url);
|
|
267
|
-
const moduleDir = path2.dirname(moduleFilename);
|
|
268
|
-
const prodPath = path2.join(moduleDir, "../package.json");
|
|
269
|
-
try {
|
|
270
|
-
const pkg = JSON.parse(readFileSync(prodPath, "utf-8"));
|
|
271
|
-
return pkg.version;
|
|
272
|
-
} catch {
|
|
273
|
-
const devPath = path2.join(moduleDir, "../../package.json");
|
|
274
|
-
const pkg = JSON.parse(readFileSync(devPath, "utf-8"));
|
|
275
|
-
return pkg.version;
|
|
276
|
-
}
|
|
277
|
-
}
|
|
278
|
-
var CLI_VERSION = readPackageVersion();
|
|
267
|
+
var CLI_VERSION = true ? "0.5.0" : "0.0.0";
|
|
279
268
|
var CLI_DOCKER_IMAGE = process.env.WALKEROS_CLI_DOCKER_IMAGE || `walkeros/cli:${CLI_VERSION}`;
|
|
280
269
|
var RUNTIME_DOCKER_IMAGE = process.env.WALKEROS_RUNTIME_DOCKER_IMAGE || `walkeros/docker:${DOCKER_VERSION}`;
|
|
281
270
|
function buildCommonDockerArgs(options) {
|
|
@@ -335,7 +324,7 @@ async function executeInDocker(command, args, options = {}, configFile) {
|
|
|
335
324
|
if (code === 0) {
|
|
336
325
|
resolve();
|
|
337
326
|
} else {
|
|
338
|
-
|
|
327
|
+
process.exit(code || 1);
|
|
339
328
|
}
|
|
340
329
|
});
|
|
341
330
|
});
|
|
@@ -355,8 +344,10 @@ function buildDockerRunCommand(mode, flowPath, options = {}) {
|
|
|
355
344
|
cmd.push("-e", `MODE=${mode}`);
|
|
356
345
|
if (mode === "collect" && flowPath) {
|
|
357
346
|
const absoluteFlowPath = path2.resolve(cwd, flowPath);
|
|
358
|
-
|
|
359
|
-
|
|
347
|
+
const flowDir = path2.dirname(absoluteFlowPath);
|
|
348
|
+
const flowFile = path2.basename(absoluteFlowPath);
|
|
349
|
+
cmd.push("-v", `${flowDir}:/app/dist:ro`);
|
|
350
|
+
cmd.push("-e", `FLOW=/app/dist/${flowFile}`);
|
|
360
351
|
}
|
|
361
352
|
if (mode === "serve" && flowPath) {
|
|
362
353
|
const absoluteFilePath = path2.resolve(cwd, flowPath);
|
|
@@ -402,7 +393,7 @@ async function executeRunInDocker(mode, flowPath, options = {}) {
|
|
|
402
393
|
if (code === 0) {
|
|
403
394
|
resolve();
|
|
404
395
|
} else {
|
|
405
|
-
|
|
396
|
+
process.exit(code || 1);
|
|
406
397
|
}
|
|
407
398
|
});
|
|
408
399
|
});
|
|
@@ -415,22 +406,22 @@ function getExecutionMode(options) {
|
|
|
415
406
|
}
|
|
416
407
|
return "docker";
|
|
417
408
|
}
|
|
418
|
-
async function executeCommand(localHandler, dockerCommand, dockerArgs, options,
|
|
409
|
+
async function executeCommand(localHandler, dockerCommand, dockerArgs, options, logger2, configFile) {
|
|
419
410
|
const mode = getExecutionMode(options);
|
|
420
411
|
if (options.dryRun) {
|
|
421
412
|
if (mode === "docker") {
|
|
422
413
|
const cmd = `docker run walkeros/cli:latest ${dockerCommand} ${dockerArgs.join(" ")}`;
|
|
423
|
-
|
|
414
|
+
logger2?.info(`[DRY-RUN] Would execute: ${cmd}`);
|
|
424
415
|
} else {
|
|
425
|
-
|
|
416
|
+
logger2?.info(
|
|
426
417
|
`[DRY-RUN] Would execute locally: ${dockerCommand} ${dockerArgs.join(" ")}`
|
|
427
418
|
);
|
|
428
419
|
}
|
|
429
420
|
return;
|
|
430
421
|
}
|
|
431
422
|
if (mode === "local") {
|
|
432
|
-
if (
|
|
433
|
-
|
|
423
|
+
if (logger2 && !options.silent) {
|
|
424
|
+
logger2.info("\u{1F5A5}\uFE0F Executing locally...");
|
|
434
425
|
}
|
|
435
426
|
await localHandler();
|
|
436
427
|
} else {
|
|
@@ -440,8 +431,8 @@ async function executeCommand(localHandler, dockerCommand, dockerArgs, options,
|
|
|
440
431
|
"Docker is not available. Please install Docker or use --local flag to execute locally."
|
|
441
432
|
);
|
|
442
433
|
}
|
|
443
|
-
if (
|
|
444
|
-
|
|
434
|
+
if (logger2 && !options.silent) {
|
|
435
|
+
logger2.info("\u{1F433} Executing in Docker container...");
|
|
445
436
|
}
|
|
446
437
|
await executeInDocker(dockerCommand, dockerArgs, options, configFile);
|
|
447
438
|
}
|
|
@@ -452,33 +443,33 @@ import { getHashServer } from "@walkeros/server-core";
|
|
|
452
443
|
import fs2 from "fs-extra";
|
|
453
444
|
|
|
454
445
|
// src/core/asset-resolver.ts
|
|
455
|
-
import { fileURLToPath
|
|
446
|
+
import { fileURLToPath } from "url";
|
|
447
|
+
import { existsSync } from "fs";
|
|
456
448
|
import path3 from "path";
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
if (
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
449
|
+
var cachedAssetDir;
|
|
450
|
+
function getAssetDir() {
|
|
451
|
+
if (cachedAssetDir) return cachedAssetDir;
|
|
452
|
+
const currentFile = fileURLToPath(import.meta.url);
|
|
453
|
+
let dir = path3.dirname(currentFile);
|
|
454
|
+
while (dir !== path3.dirname(dir)) {
|
|
455
|
+
if (existsSync(path3.join(dir, "examples"))) {
|
|
456
|
+
cachedAssetDir = dir;
|
|
457
|
+
return dir;
|
|
458
|
+
}
|
|
459
|
+
dir = path3.dirname(dir);
|
|
466
460
|
}
|
|
467
|
-
|
|
461
|
+
cachedAssetDir = path3.dirname(currentFile);
|
|
462
|
+
return cachedAssetDir;
|
|
468
463
|
}
|
|
469
464
|
function resolveAsset(assetPath, assetType, baseDir) {
|
|
470
|
-
const packageRoot = getPackageRoot();
|
|
471
465
|
if (!assetPath.includes("/") && !assetPath.includes("\\")) {
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
}
|
|
475
|
-
return path3.join(packageRoot, "examples", assetPath);
|
|
466
|
+
const assetDir = getAssetDir();
|
|
467
|
+
return path3.join(assetDir, "examples", assetPath);
|
|
476
468
|
}
|
|
477
469
|
if (path3.isAbsolute(assetPath)) {
|
|
478
470
|
return assetPath;
|
|
479
471
|
}
|
|
480
|
-
|
|
481
|
-
return path3.resolve(resolveBase, assetPath);
|
|
472
|
+
return path3.resolve(baseDir || process.cwd(), assetPath);
|
|
482
473
|
}
|
|
483
474
|
|
|
484
475
|
// src/core/utils.ts
|
|
@@ -486,273 +477,256 @@ function getErrorMessage(error) {
|
|
|
486
477
|
return error instanceof Error ? error.message : String(error);
|
|
487
478
|
}
|
|
488
479
|
|
|
489
|
-
// src/
|
|
490
|
-
function isObject(value) {
|
|
491
|
-
return typeof value === "object" && value !== null && !Array.isArray(value) && Object.prototype.toString.call(value) === "[object Object]";
|
|
492
|
-
}
|
|
493
|
-
function validatePlatform(platform) {
|
|
494
|
-
return platform === "web" || platform === "server";
|
|
495
|
-
}
|
|
496
|
-
function isMultiEnvConfig(data) {
|
|
497
|
-
return isObject(data) && "version" in data && data.version === 1 && "environments" in data && isObject(data.environments);
|
|
498
|
-
}
|
|
499
|
-
function isSingleEnvConfig(data) {
|
|
500
|
-
return isObject(data) && "flow" in data && "build" in data && isObject(data.flow) && isObject(data.build) && "platform" in data.flow;
|
|
501
|
-
}
|
|
502
|
-
|
|
503
|
-
// src/config/parser.ts
|
|
480
|
+
// src/core/local-packages.ts
|
|
504
481
|
import path4 from "path";
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
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];
|
|
523
|
-
return {
|
|
524
|
-
flowConfig: envConfig.flow,
|
|
525
|
-
buildOptions: envConfig.build,
|
|
526
|
-
metadata: {
|
|
527
|
-
environment: selectedEnv,
|
|
528
|
-
isMultiEnvironment: true,
|
|
529
|
-
availableEnvironments
|
|
530
|
-
}
|
|
531
|
-
};
|
|
532
|
-
}
|
|
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
|
-
};
|
|
543
|
-
}
|
|
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}.
|
|
549
|
-
|
|
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)) {
|
|
482
|
+
import fs3 from "fs-extra";
|
|
483
|
+
async function resolveLocalPackage(packageName, localPath, configDir, logger2) {
|
|
484
|
+
const absolutePath = path4.isAbsolute(localPath) ? localPath : path4.resolve(configDir, localPath);
|
|
485
|
+
if (!await fs3.pathExists(absolutePath)) {
|
|
557
486
|
throw new Error(
|
|
558
|
-
`
|
|
487
|
+
`Local package path not found: ${localPath} (resolved to ${absolutePath})`
|
|
559
488
|
);
|
|
560
489
|
}
|
|
561
|
-
const
|
|
562
|
-
if (!
|
|
490
|
+
const pkgJsonPath = path4.join(absolutePath, "package.json");
|
|
491
|
+
if (!await fs3.pathExists(pkgJsonPath)) {
|
|
563
492
|
throw new Error(
|
|
564
|
-
`
|
|
493
|
+
`No package.json found at ${absolutePath}. Is this a valid package directory?`
|
|
565
494
|
);
|
|
566
495
|
}
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
496
|
+
const distPath = path4.join(absolutePath, "dist");
|
|
497
|
+
const hasDistFolder = await fs3.pathExists(distPath);
|
|
498
|
+
if (!hasDistFolder) {
|
|
499
|
+
logger2.warn(
|
|
500
|
+
`\u26A0\uFE0F ${packageName}: No dist/ folder found. Using package root.`
|
|
570
501
|
);
|
|
571
502
|
}
|
|
572
|
-
const platformDefaults = platform === "web" ? {
|
|
573
|
-
platform: "browser",
|
|
574
|
-
format: "iife",
|
|
575
|
-
target: "es2020",
|
|
576
|
-
minify: false,
|
|
577
|
-
sourcemap: false,
|
|
578
|
-
tempDir: ".tmp",
|
|
579
|
-
cache: true
|
|
580
|
-
} : {
|
|
581
|
-
platform: "node",
|
|
582
|
-
format: "esm",
|
|
583
|
-
target: "node20",
|
|
584
|
-
minify: false,
|
|
585
|
-
sourcemap: false,
|
|
586
|
-
tempDir: ".tmp",
|
|
587
|
-
cache: true
|
|
588
|
-
};
|
|
589
|
-
const merged = {
|
|
590
|
-
...platformDefaults,
|
|
591
|
-
...buildOptions
|
|
592
|
-
};
|
|
593
|
-
if (merged.template === void 0) {
|
|
594
|
-
merged.template = platform === "server" ? "server.hbs" : "web.hbs";
|
|
595
|
-
}
|
|
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";
|
|
602
|
-
}
|
|
603
|
-
}
|
|
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
|
-
}
|
|
621
503
|
return {
|
|
622
|
-
|
|
623
|
-
|
|
504
|
+
name: packageName,
|
|
505
|
+
absolutePath,
|
|
506
|
+
distPath: hasDistFolder ? distPath : absolutePath,
|
|
507
|
+
hasDistFolder
|
|
624
508
|
};
|
|
625
509
|
}
|
|
626
|
-
function
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
510
|
+
async function copyLocalPackage(localPkg, targetDir, logger2) {
|
|
511
|
+
const packageDir = path4.join(targetDir, "node_modules", localPkg.name);
|
|
512
|
+
await fs3.ensureDir(path4.dirname(packageDir));
|
|
513
|
+
await fs3.copy(
|
|
514
|
+
path4.join(localPkg.absolutePath, "package.json"),
|
|
515
|
+
path4.join(packageDir, "package.json")
|
|
516
|
+
);
|
|
517
|
+
if (localPkg.hasDistFolder) {
|
|
518
|
+
await fs3.copy(localPkg.distPath, path4.join(packageDir, "dist"));
|
|
519
|
+
} else {
|
|
520
|
+
const entries = await fs3.readdir(localPkg.absolutePath);
|
|
521
|
+
for (const entry of entries) {
|
|
522
|
+
if (!["node_modules", ".turbo", ".git"].includes(entry)) {
|
|
523
|
+
await fs3.copy(
|
|
524
|
+
path4.join(localPkg.absolutePath, entry),
|
|
525
|
+
path4.join(packageDir, entry)
|
|
526
|
+
);
|
|
527
|
+
}
|
|
528
|
+
}
|
|
639
529
|
}
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
530
|
+
logger2.info(`\u{1F4E6} Using local: ${localPkg.name} from ${localPkg.absolutePath}`);
|
|
531
|
+
return packageDir;
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
// src/config/validators.ts
|
|
535
|
+
import { schemas } from "@walkeros/core/dev";
|
|
536
|
+
var { safeParseSetup } = schemas;
|
|
537
|
+
function isObject(value) {
|
|
538
|
+
return typeof value === "object" && value !== null && !Array.isArray(value) && Object.prototype.toString.call(value) === "[object Object]";
|
|
539
|
+
}
|
|
540
|
+
function validateFlowSetup(data) {
|
|
541
|
+
const result = safeParseSetup(data);
|
|
542
|
+
if (!result.success) {
|
|
543
|
+
const errors = result.error.issues.map((issue) => {
|
|
544
|
+
const path15 = issue.path.length > 0 ? issue.path.map(String).join(".") : "root";
|
|
545
|
+
return ` - ${path15}: ${issue.message}`;
|
|
546
|
+
}).join("\n");
|
|
547
|
+
throw new Error(`Invalid configuration:
|
|
548
|
+
${errors}`);
|
|
645
549
|
}
|
|
646
|
-
return
|
|
550
|
+
return result.data;
|
|
551
|
+
}
|
|
552
|
+
function getAvailableFlows(setup) {
|
|
553
|
+
return Object.keys(setup.flows);
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
// src/config/build-defaults.ts
|
|
557
|
+
var WEB_BUILD_DEFAULTS = {
|
|
558
|
+
format: "iife",
|
|
559
|
+
platform: "browser",
|
|
560
|
+
target: "es2020",
|
|
561
|
+
minify: true,
|
|
562
|
+
sourcemap: false,
|
|
563
|
+
cache: true,
|
|
564
|
+
tempDir: ".tmp",
|
|
565
|
+
windowCollector: "collector",
|
|
566
|
+
windowElb: "elb"
|
|
567
|
+
};
|
|
568
|
+
var SERVER_BUILD_DEFAULTS = {
|
|
569
|
+
format: "esm",
|
|
570
|
+
platform: "node",
|
|
571
|
+
target: "node20",
|
|
572
|
+
minify: true,
|
|
573
|
+
sourcemap: false,
|
|
574
|
+
cache: true,
|
|
575
|
+
tempDir: ".tmp"
|
|
576
|
+
};
|
|
577
|
+
var DEFAULT_OUTPUT_PATHS = {
|
|
578
|
+
web: "./dist/walker.js",
|
|
579
|
+
server: "./dist/bundle.mjs"
|
|
580
|
+
};
|
|
581
|
+
function getBuildDefaults(platform) {
|
|
582
|
+
return platform === "web" ? WEB_BUILD_DEFAULTS : SERVER_BUILD_DEFAULTS;
|
|
647
583
|
}
|
|
648
|
-
function
|
|
649
|
-
return
|
|
584
|
+
function getDefaultOutput(platform) {
|
|
585
|
+
return DEFAULT_OUTPUT_PATHS[platform];
|
|
650
586
|
}
|
|
651
587
|
|
|
652
588
|
// src/config/loader.ts
|
|
589
|
+
import path5 from "path";
|
|
590
|
+
import fs4 from "fs-extra";
|
|
591
|
+
import { getFlowConfig, getPlatform } from "@walkeros/core";
|
|
592
|
+
var DEFAULT_INCLUDE_FOLDER = "./shared";
|
|
653
593
|
function loadBundleConfig(rawConfig, options) {
|
|
654
|
-
const
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
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
|
-
);
|
|
670
|
-
}
|
|
671
|
-
if (!metadata.isMultiEnvironment && options.environment && options.logger) {
|
|
672
|
-
options.logger.warn(
|
|
673
|
-
`--env flag specified but configuration is single-environment. Ignoring flag.`
|
|
674
|
-
);
|
|
675
|
-
}
|
|
676
|
-
return {
|
|
677
|
-
...normalized,
|
|
678
|
-
...metadata
|
|
679
|
-
};
|
|
680
|
-
}
|
|
681
|
-
function loadMultiEnvironmentConfig(setup, options) {
|
|
682
|
-
const availableEnvironments = Object.keys(setup.environments);
|
|
683
|
-
if (!options.environment) {
|
|
684
|
-
throw new Error(
|
|
685
|
-
`Multi-environment configuration detected. Please specify an environment using --env flag.
|
|
686
|
-
Available environments: ${availableEnvironments.join(", ")}`
|
|
687
|
-
);
|
|
688
|
-
}
|
|
689
|
-
const selectedEnv = options.environment;
|
|
690
|
-
if (!setup.environments[selectedEnv]) {
|
|
594
|
+
const setup = validateFlowSetup(rawConfig);
|
|
595
|
+
const availableFlows = getAvailableFlows(setup);
|
|
596
|
+
const flowName = resolveFlow(setup, options.flowName, availableFlows);
|
|
597
|
+
const flowConfig = getFlowConfig(setup, flowName);
|
|
598
|
+
const platform = getPlatform(flowConfig);
|
|
599
|
+
if (!platform) {
|
|
691
600
|
throw new Error(
|
|
692
|
-
`
|
|
693
|
-
Available environments: ${availableEnvironments.join(", ")}`
|
|
601
|
+
`Invalid configuration: flow "${flowName}" must have a "web" or "server" key.`
|
|
694
602
|
);
|
|
695
603
|
}
|
|
696
|
-
const
|
|
697
|
-
const
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
604
|
+
const buildDefaults = getBuildDefaults(platform);
|
|
605
|
+
const packages = flowConfig.packages || {};
|
|
606
|
+
let output = getDefaultOutput(platform);
|
|
607
|
+
if (options.buildOverrides?.output) {
|
|
608
|
+
output = options.buildOverrides.output;
|
|
609
|
+
}
|
|
610
|
+
const configDir = path5.dirname(options.configPath);
|
|
611
|
+
if (!path5.isAbsolute(output)) {
|
|
612
|
+
output = path5.resolve(configDir, output);
|
|
613
|
+
}
|
|
614
|
+
let includes = setup.include;
|
|
615
|
+
if (!includes) {
|
|
616
|
+
const defaultIncludePath = path5.resolve(configDir, DEFAULT_INCLUDE_FOLDER);
|
|
617
|
+
if (fs4.pathExistsSync(defaultIncludePath)) {
|
|
618
|
+
includes = [DEFAULT_INCLUDE_FOLDER];
|
|
619
|
+
}
|
|
620
|
+
}
|
|
621
|
+
const buildOptions = {
|
|
622
|
+
...buildDefaults,
|
|
623
|
+
packages,
|
|
624
|
+
output,
|
|
625
|
+
include: includes,
|
|
626
|
+
configDir,
|
|
627
|
+
...options.buildOverrides
|
|
628
|
+
};
|
|
629
|
+
const isMultiFlow = availableFlows.length > 1;
|
|
630
|
+
if (isMultiFlow && options.logger) {
|
|
702
631
|
options.logger.info(
|
|
703
|
-
`\u{1F4E6} Using
|
|
632
|
+
`\u{1F4E6} Using flow: ${flowName} (${availableFlows.length} total)`
|
|
704
633
|
);
|
|
705
634
|
}
|
|
706
635
|
return {
|
|
707
636
|
flowConfig,
|
|
708
637
|
buildOptions,
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
638
|
+
flowName,
|
|
639
|
+
isMultiFlow,
|
|
640
|
+
availableFlows
|
|
712
641
|
};
|
|
713
642
|
}
|
|
714
|
-
function
|
|
715
|
-
if (
|
|
643
|
+
function resolveFlow(setup, requestedFlow, available) {
|
|
644
|
+
if (available.length === 1) {
|
|
645
|
+
return available[0];
|
|
646
|
+
}
|
|
647
|
+
if (!requestedFlow) {
|
|
716
648
|
throw new Error(
|
|
717
|
-
|
|
718
|
-
|
|
649
|
+
`Multiple flows found. Please specify a flow using --flow flag.
|
|
650
|
+
Available flows: ${available.join(", ")}`
|
|
719
651
|
);
|
|
720
652
|
}
|
|
721
|
-
|
|
722
|
-
|
|
653
|
+
if (!available.includes(requestedFlow)) {
|
|
654
|
+
throw new Error(
|
|
655
|
+
`Flow "${requestedFlow}" not found in configuration.
|
|
656
|
+
Available flows: ${available.join(", ")}`
|
|
657
|
+
);
|
|
658
|
+
}
|
|
659
|
+
return requestedFlow;
|
|
660
|
+
}
|
|
661
|
+
function loadAllFlows(rawConfig, options) {
|
|
662
|
+
const setup = validateFlowSetup(rawConfig);
|
|
663
|
+
const flows = getAvailableFlows(setup);
|
|
723
664
|
if (options.logger) {
|
|
724
665
|
options.logger.info(
|
|
725
|
-
`\u{1F4E6} Loading all ${
|
|
666
|
+
`\u{1F4E6} Loading all ${flows.length} flows: ${flows.join(", ")}`
|
|
726
667
|
);
|
|
727
668
|
}
|
|
728
|
-
return
|
|
729
|
-
(
|
|
669
|
+
return flows.map(
|
|
670
|
+
(name) => loadBundleConfig(rawConfig, {
|
|
730
671
|
...options,
|
|
731
|
-
|
|
672
|
+
flowName: name
|
|
732
673
|
})
|
|
733
674
|
);
|
|
734
675
|
}
|
|
735
676
|
|
|
736
677
|
// src/commands/bundle/bundler.ts
|
|
737
678
|
import esbuild from "esbuild";
|
|
679
|
+
import path8 from "path";
|
|
680
|
+
import fs7 from "fs-extra";
|
|
681
|
+
import { packageNameToVariable } from "@walkeros/core";
|
|
682
|
+
|
|
683
|
+
// src/commands/bundle/package-manager.ts
|
|
684
|
+
import pacote from "pacote";
|
|
738
685
|
import path6 from "path";
|
|
739
686
|
import fs5 from "fs-extra";
|
|
740
687
|
|
|
688
|
+
// src/core/cache-utils.ts
|
|
689
|
+
import { getHashServer as getHashServer2 } from "@walkeros/server-core";
|
|
690
|
+
var HASH_LENGTH = 12;
|
|
691
|
+
function isMutableVersion(version) {
|
|
692
|
+
return version === "latest" || version.includes("^") || version.includes("~") || version.includes("*") || version.includes("x");
|
|
693
|
+
}
|
|
694
|
+
function getTodayDate() {
|
|
695
|
+
return (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
696
|
+
}
|
|
697
|
+
async function getPackageCacheKey(packageName, version, date) {
|
|
698
|
+
const safeName = packageName.replace(/\//g, "-").replace(/@/g, "");
|
|
699
|
+
if (isMutableVersion(version)) {
|
|
700
|
+
const dateStr = date ?? getTodayDate();
|
|
701
|
+
const input2 = `${safeName}@${version}:${dateStr}`;
|
|
702
|
+
return getHashServer2(input2, HASH_LENGTH);
|
|
703
|
+
}
|
|
704
|
+
const input = `${safeName}@${version}`;
|
|
705
|
+
return getHashServer2(input, HASH_LENGTH);
|
|
706
|
+
}
|
|
707
|
+
function normalizeJson(content) {
|
|
708
|
+
const parsed = JSON.parse(content);
|
|
709
|
+
return JSON.stringify(parsed);
|
|
710
|
+
}
|
|
711
|
+
async function getFlowConfigCacheKey(content, date) {
|
|
712
|
+
const dateStr = date ?? getTodayDate();
|
|
713
|
+
const normalized = normalizeJson(content);
|
|
714
|
+
const input = `${normalized}:${dateStr}`;
|
|
715
|
+
return getHashServer2(input, HASH_LENGTH);
|
|
716
|
+
}
|
|
717
|
+
|
|
741
718
|
// src/commands/bundle/package-manager.ts
|
|
742
|
-
import pacote from "pacote";
|
|
743
|
-
import path5 from "path";
|
|
744
|
-
import fs3 from "fs-extra";
|
|
745
719
|
function getPackageDirectory(baseDir, packageName, version) {
|
|
746
|
-
return
|
|
720
|
+
return path6.join(baseDir, "node_modules", packageName);
|
|
747
721
|
}
|
|
748
|
-
function getCachedPackagePath(pkg, tempDir) {
|
|
749
|
-
const cacheDir =
|
|
750
|
-
const
|
|
751
|
-
return
|
|
722
|
+
async function getCachedPackagePath(pkg, tempDir) {
|
|
723
|
+
const cacheDir = path6.join(".tmp", "cache", "packages");
|
|
724
|
+
const cacheKey = await getPackageCacheKey(pkg.name, pkg.version);
|
|
725
|
+
return path6.join(cacheDir, cacheKey);
|
|
752
726
|
}
|
|
753
727
|
async function isPackageCached(pkg, tempDir) {
|
|
754
|
-
const cachedPath = getCachedPackagePath(pkg, tempDir);
|
|
755
|
-
return
|
|
728
|
+
const cachedPath = await getCachedPackagePath(pkg, tempDir);
|
|
729
|
+
return fs5.pathExists(cachedPath);
|
|
756
730
|
}
|
|
757
731
|
function validateNoDuplicatePackages(packages) {
|
|
758
732
|
const packageMap = /* @__PURE__ */ new Map();
|
|
@@ -778,7 +752,7 @@ Each package must use the same version across all declarations. Please update yo
|
|
|
778
752
|
);
|
|
779
753
|
}
|
|
780
754
|
}
|
|
781
|
-
async function resolveDependencies(pkg, packageDir,
|
|
755
|
+
async function resolveDependencies(pkg, packageDir, logger2, visited = /* @__PURE__ */ new Set()) {
|
|
782
756
|
const dependencies = [];
|
|
783
757
|
const pkgKey = `${pkg.name}@${pkg.version}`;
|
|
784
758
|
if (visited.has(pkgKey)) {
|
|
@@ -786,9 +760,9 @@ async function resolveDependencies(pkg, packageDir, logger, visited = /* @__PURE
|
|
|
786
760
|
}
|
|
787
761
|
visited.add(pkgKey);
|
|
788
762
|
try {
|
|
789
|
-
const packageJsonPath =
|
|
790
|
-
if (await
|
|
791
|
-
const packageJson2 = await
|
|
763
|
+
const packageJsonPath = path6.join(packageDir, "package.json");
|
|
764
|
+
if (await fs5.pathExists(packageJsonPath)) {
|
|
765
|
+
const packageJson2 = await fs5.readJson(packageJsonPath);
|
|
792
766
|
const deps = {
|
|
793
767
|
...packageJson2.dependencies,
|
|
794
768
|
...packageJson2.peerDependencies
|
|
@@ -800,16 +774,22 @@ async function resolveDependencies(pkg, packageDir, logger, visited = /* @__PURE
|
|
|
800
774
|
}
|
|
801
775
|
}
|
|
802
776
|
} catch (error) {
|
|
803
|
-
|
|
777
|
+
logger2.debug(`Failed to read dependencies for ${pkgKey}: ${error}`);
|
|
804
778
|
}
|
|
805
779
|
return dependencies;
|
|
806
780
|
}
|
|
807
|
-
async function downloadPackages(packages, targetDir,
|
|
781
|
+
async function downloadPackages(packages, targetDir, logger2, useCache = true, configDir) {
|
|
808
782
|
const packagePaths = /* @__PURE__ */ new Map();
|
|
809
783
|
const downloadQueue = [...packages];
|
|
810
784
|
const processed = /* @__PURE__ */ new Set();
|
|
785
|
+
const localPackageMap = /* @__PURE__ */ new Map();
|
|
786
|
+
for (const pkg of packages) {
|
|
787
|
+
if (pkg.path) {
|
|
788
|
+
localPackageMap.set(pkg.name, pkg.path);
|
|
789
|
+
}
|
|
790
|
+
}
|
|
811
791
|
validateNoDuplicatePackages(packages);
|
|
812
|
-
await
|
|
792
|
+
await fs5.ensureDir(targetDir);
|
|
813
793
|
while (downloadQueue.length > 0) {
|
|
814
794
|
const pkg = downloadQueue.shift();
|
|
815
795
|
const pkgKey = `${pkg.name}@${pkg.version}`;
|
|
@@ -817,16 +797,37 @@ async function downloadPackages(packages, targetDir, logger, useCache = true) {
|
|
|
817
797
|
continue;
|
|
818
798
|
}
|
|
819
799
|
processed.add(pkgKey);
|
|
800
|
+
if (!pkg.path && localPackageMap.has(pkg.name)) {
|
|
801
|
+
pkg.path = localPackageMap.get(pkg.name);
|
|
802
|
+
}
|
|
803
|
+
if (pkg.path) {
|
|
804
|
+
const localPkg = await resolveLocalPackage(
|
|
805
|
+
pkg.name,
|
|
806
|
+
pkg.path,
|
|
807
|
+
configDir || process.cwd(),
|
|
808
|
+
logger2
|
|
809
|
+
);
|
|
810
|
+
const installedPath = await copyLocalPackage(localPkg, targetDir, logger2);
|
|
811
|
+
packagePaths.set(pkg.name, installedPath);
|
|
812
|
+
const deps = await resolveDependencies(pkg, installedPath, logger2);
|
|
813
|
+
for (const dep of deps) {
|
|
814
|
+
const depKey = `${dep.name}@${dep.version}`;
|
|
815
|
+
if (!processed.has(depKey)) {
|
|
816
|
+
downloadQueue.push(dep);
|
|
817
|
+
}
|
|
818
|
+
}
|
|
819
|
+
continue;
|
|
820
|
+
}
|
|
820
821
|
const packageSpec = `${pkg.name}@${pkg.version}`;
|
|
821
822
|
const packageDir = getPackageDirectory(targetDir, pkg.name, pkg.version);
|
|
822
|
-
const cachedPath = getCachedPackagePath(pkg, targetDir);
|
|
823
|
+
const cachedPath = await getCachedPackagePath(pkg, targetDir);
|
|
823
824
|
if (useCache && await isPackageCached(pkg, targetDir)) {
|
|
824
|
-
|
|
825
|
+
logger2.debug(`Using cached ${packageSpec}...`);
|
|
825
826
|
try {
|
|
826
|
-
await
|
|
827
|
-
await
|
|
827
|
+
await fs5.ensureDir(path6.dirname(packageDir));
|
|
828
|
+
await fs5.copy(cachedPath, packageDir);
|
|
828
829
|
packagePaths.set(pkg.name, packageDir);
|
|
829
|
-
const deps = await resolveDependencies(pkg, packageDir,
|
|
830
|
+
const deps = await resolveDependencies(pkg, packageDir, logger2);
|
|
830
831
|
for (const dep of deps) {
|
|
831
832
|
const depKey = `${dep.name}@${dep.version}`;
|
|
832
833
|
if (!processed.has(depKey)) {
|
|
@@ -835,15 +836,15 @@ async function downloadPackages(packages, targetDir, logger, useCache = true) {
|
|
|
835
836
|
}
|
|
836
837
|
continue;
|
|
837
838
|
} catch (error) {
|
|
838
|
-
|
|
839
|
+
logger2.debug(
|
|
839
840
|
`Failed to use cache for ${packageSpec}, downloading fresh: ${error}`
|
|
840
841
|
);
|
|
841
842
|
}
|
|
842
843
|
}
|
|
843
|
-
|
|
844
|
+
logger2.debug(`Downloading ${packageSpec}...`);
|
|
844
845
|
try {
|
|
845
|
-
await
|
|
846
|
-
const cacheDir = process.env.NPM_CACHE_DIR ||
|
|
846
|
+
await fs5.ensureDir(path6.dirname(packageDir));
|
|
847
|
+
const cacheDir = process.env.NPM_CACHE_DIR || path6.join(process.cwd(), ".npm-cache");
|
|
847
848
|
await pacote.extract(packageSpec, packageDir, {
|
|
848
849
|
// Force npm registry download, prevent workspace resolution
|
|
849
850
|
registry: "https://registry.npmjs.org",
|
|
@@ -856,15 +857,15 @@ async function downloadPackages(packages, targetDir, logger, useCache = true) {
|
|
|
856
857
|
});
|
|
857
858
|
if (useCache) {
|
|
858
859
|
try {
|
|
859
|
-
await
|
|
860
|
-
await
|
|
861
|
-
|
|
860
|
+
await fs5.ensureDir(path6.dirname(cachedPath));
|
|
861
|
+
await fs5.copy(packageDir, cachedPath);
|
|
862
|
+
logger2.debug(`Cached ${packageSpec} for future use`);
|
|
862
863
|
} catch (cacheError) {
|
|
863
|
-
|
|
864
|
+
logger2.debug(`Failed to cache ${packageSpec}: ${cacheError}`);
|
|
864
865
|
}
|
|
865
866
|
}
|
|
866
867
|
packagePaths.set(pkg.name, packageDir);
|
|
867
|
-
const deps = await resolveDependencies(pkg, packageDir,
|
|
868
|
+
const deps = await resolveDependencies(pkg, packageDir, logger2);
|
|
868
869
|
for (const dep of deps) {
|
|
869
870
|
const depKey = `${dep.name}@${dep.version}`;
|
|
870
871
|
if (!processed.has(depKey)) {
|
|
@@ -878,188 +879,118 @@ async function downloadPackages(packages, targetDir, logger, useCache = true) {
|
|
|
878
879
|
return packagePaths;
|
|
879
880
|
}
|
|
880
881
|
|
|
881
|
-
// src/
|
|
882
|
-
import
|
|
883
|
-
import
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
/^\s*\([^)]*\)\s*=>\s*\{/,
|
|
903
|
-
// (param) => {
|
|
904
|
-
/^\s*\w+\s*=>\s*\{/
|
|
905
|
-
// param => {
|
|
906
|
-
];
|
|
907
|
-
if (arrowPatterns.some((pattern) => pattern.test(val))) {
|
|
908
|
-
return val;
|
|
909
|
-
}
|
|
910
|
-
}
|
|
911
|
-
return quote + val.replace(/\\/g, "\\\\").replace(/'/g, "\\'").replace(/"/g, '\\"') + quote;
|
|
912
|
-
}
|
|
913
|
-
if (Array.isArray(val)) {
|
|
914
|
-
if (val.length === 0) return "[]";
|
|
915
|
-
const nextIndent = currentIndent + indent;
|
|
916
|
-
const spacing = " ".repeat(nextIndent);
|
|
917
|
-
const items = val.map((item) => spacing + serialize(item, nextIndent)).join(",\n");
|
|
918
|
-
return `[
|
|
919
|
-
${items}
|
|
920
|
-
${" ".repeat(currentIndent)}]`;
|
|
921
|
-
}
|
|
922
|
-
if (isObject(val)) {
|
|
923
|
-
const entries = Object.entries(val);
|
|
924
|
-
if (entries.length === 0) return "{}";
|
|
925
|
-
const nextIndent = currentIndent + indent;
|
|
926
|
-
const spacing = " ".repeat(nextIndent);
|
|
927
|
-
const props = entries.map(([key, value2]) => {
|
|
928
|
-
const needsQuotes = /[^a-zA-Z0-9_$]/.test(key) || /^[0-9]/.test(key);
|
|
929
|
-
const keyStr = needsQuotes ? quote + key + quote : key;
|
|
930
|
-
return spacing + keyStr + ": " + serialize(value2, nextIndent);
|
|
931
|
-
}).join(",\n");
|
|
932
|
-
return `{
|
|
933
|
-
${props}
|
|
934
|
-
${" ".repeat(currentIndent)}}`;
|
|
935
|
-
}
|
|
936
|
-
return String(val);
|
|
937
|
-
}
|
|
938
|
-
return serialize(value);
|
|
939
|
-
}
|
|
940
|
-
function serializeConfig(config) {
|
|
941
|
-
if (!config || Object.keys(config).length === 0) {
|
|
942
|
-
return "{}";
|
|
943
|
-
}
|
|
944
|
-
return serializeToJS(config, { indent: 2, singleQuotes: true });
|
|
945
|
-
}
|
|
946
|
-
function processTemplateVariables(variables) {
|
|
947
|
-
const processed = { ...variables };
|
|
948
|
-
if (isObject(processed.sources)) {
|
|
949
|
-
const sourcesObj = processed.sources;
|
|
950
|
-
const processedSources = {};
|
|
951
|
-
for (const [name, source] of Object.entries(sourcesObj)) {
|
|
952
|
-
const typedSource = source;
|
|
953
|
-
const { env: _, ...sourceWithoutEnv } = typedSource;
|
|
954
|
-
processedSources[name] = {
|
|
955
|
-
...sourceWithoutEnv,
|
|
956
|
-
config: isObject(typedSource.config) ? serializeConfig(typedSource.config) : typedSource.config,
|
|
957
|
-
// Pass through string configs unchanged
|
|
958
|
-
...typedSource.env !== void 0 && { env: typedSource.env }
|
|
959
|
-
};
|
|
960
|
-
}
|
|
961
|
-
processed.sources = processedSources;
|
|
962
|
-
}
|
|
963
|
-
if (isObject(processed.destinations)) {
|
|
964
|
-
const destinationsObj = processed.destinations;
|
|
965
|
-
const processedDestinations = {};
|
|
966
|
-
for (const [name, dest] of Object.entries(destinationsObj)) {
|
|
967
|
-
const typedDest = dest;
|
|
968
|
-
const { env: _, ...destWithoutEnv } = typedDest;
|
|
969
|
-
processedDestinations[name] = {
|
|
970
|
-
...destWithoutEnv,
|
|
971
|
-
config: isObject(typedDest.config) ? serializeConfig(typedDest.config) : typedDest.config,
|
|
972
|
-
...typedDest.env !== void 0 && { env: typedDest.env }
|
|
973
|
-
};
|
|
974
|
-
}
|
|
975
|
-
processed.destinations = processedDestinations;
|
|
976
|
-
}
|
|
977
|
-
if (isObject(processed.collector)) {
|
|
978
|
-
processed.collector = serializeConfig(
|
|
979
|
-
processed.collector
|
|
980
|
-
);
|
|
882
|
+
// src/core/build-cache.ts
|
|
883
|
+
import fs6 from "fs-extra";
|
|
884
|
+
import path7 from "path";
|
|
885
|
+
var BUILD_CACHE_DIR = path7.join(".tmp", "cache", "builds");
|
|
886
|
+
async function getBuildCachePath(configContent, cacheDir = BUILD_CACHE_DIR) {
|
|
887
|
+
const cacheKey = await getFlowConfigCacheKey(configContent);
|
|
888
|
+
return path7.join(cacheDir, `${cacheKey}.js`);
|
|
889
|
+
}
|
|
890
|
+
async function isBuildCached(configContent, cacheDir = BUILD_CACHE_DIR) {
|
|
891
|
+
const cachePath = await getBuildCachePath(configContent, cacheDir);
|
|
892
|
+
return fs6.pathExists(cachePath);
|
|
893
|
+
}
|
|
894
|
+
async function cacheBuild(configContent, buildOutput, cacheDir = BUILD_CACHE_DIR) {
|
|
895
|
+
const cachePath = await getBuildCachePath(configContent, cacheDir);
|
|
896
|
+
await fs6.ensureDir(path7.dirname(cachePath));
|
|
897
|
+
await fs6.writeFile(cachePath, buildOutput, "utf-8");
|
|
898
|
+
}
|
|
899
|
+
async function getCachedBuild(configContent, cacheDir = BUILD_CACHE_DIR) {
|
|
900
|
+
const cachePath = await getBuildCachePath(configContent, cacheDir);
|
|
901
|
+
if (await fs6.pathExists(cachePath)) {
|
|
902
|
+
return await fs6.readFile(cachePath, "utf-8");
|
|
981
903
|
}
|
|
982
|
-
return
|
|
904
|
+
return null;
|
|
983
905
|
}
|
|
984
906
|
|
|
985
|
-
// src/commands/bundle/
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
*/
|
|
997
|
-
async loadTemplate(templatePath) {
|
|
998
|
-
const resolvedPath = resolveAsset(templatePath, "template");
|
|
999
|
-
if (!await fs4.pathExists(resolvedPath)) {
|
|
1000
|
-
throw new Error(`Template file not found: ${resolvedPath}`);
|
|
907
|
+
// src/commands/bundle/bundler.ts
|
|
908
|
+
async function copyIncludes(includes, sourceDir, outputDir, logger2) {
|
|
909
|
+
for (const include of includes) {
|
|
910
|
+
const sourcePath = path8.resolve(sourceDir, include);
|
|
911
|
+
const folderName = path8.basename(include);
|
|
912
|
+
const destPath = path8.join(outputDir, folderName);
|
|
913
|
+
if (await fs7.pathExists(sourcePath)) {
|
|
914
|
+
await fs7.copy(sourcePath, destPath);
|
|
915
|
+
logger2.debug(`Copied ${include} to output`);
|
|
916
|
+
} else {
|
|
917
|
+
logger2.debug(`Include folder not found: ${include}`);
|
|
1001
918
|
}
|
|
1002
|
-
return await fs4.readFile(resolvedPath, "utf-8");
|
|
1003
|
-
}
|
|
1004
|
-
/**
|
|
1005
|
-
* Apply template with user code and variable substitution
|
|
1006
|
-
*/
|
|
1007
|
-
applyTemplate(template, userCode, sources, destinations, collector, build) {
|
|
1008
|
-
const processedVariables = processTemplateVariables({
|
|
1009
|
-
sources,
|
|
1010
|
-
destinations,
|
|
1011
|
-
collector
|
|
1012
|
-
});
|
|
1013
|
-
const templateData = {
|
|
1014
|
-
CODE: userCode,
|
|
1015
|
-
build: build || {},
|
|
1016
|
-
...processedVariables
|
|
1017
|
-
};
|
|
1018
|
-
const compiledTemplate = this.handlebars.compile(template);
|
|
1019
|
-
return compiledTemplate(templateData);
|
|
1020
|
-
}
|
|
1021
|
-
/**
|
|
1022
|
-
* Process template with user code
|
|
1023
|
-
*/
|
|
1024
|
-
async process(templatePath, userCode, sources, destinations, collector, build) {
|
|
1025
|
-
const template = await this.loadTemplate(templatePath);
|
|
1026
|
-
return this.applyTemplate(
|
|
1027
|
-
template,
|
|
1028
|
-
userCode,
|
|
1029
|
-
sources,
|
|
1030
|
-
destinations,
|
|
1031
|
-
collector,
|
|
1032
|
-
build
|
|
1033
|
-
);
|
|
1034
919
|
}
|
|
1035
|
-
}
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
920
|
+
}
|
|
921
|
+
function generateCacheKeyContent(flowConfig, buildOptions) {
|
|
922
|
+
const configForCache = {
|
|
923
|
+
flow: flowConfig,
|
|
924
|
+
build: {
|
|
925
|
+
...buildOptions,
|
|
926
|
+
// Exclude non-deterministic fields from cache key
|
|
927
|
+
tempDir: void 0,
|
|
928
|
+
output: void 0
|
|
929
|
+
}
|
|
930
|
+
};
|
|
931
|
+
return JSON.stringify(configForCache);
|
|
932
|
+
}
|
|
933
|
+
async function bundleCore(flowConfig, buildOptions, logger2, showStats = false) {
|
|
1039
934
|
const bundleStartTime = Date.now();
|
|
1040
|
-
const TEMP_DIR = buildOptions.tempDir ?
|
|
935
|
+
const TEMP_DIR = buildOptions.tempDir ? path8.isAbsolute(buildOptions.tempDir) ? buildOptions.tempDir : path8.resolve(buildOptions.tempDir) : getTempDir();
|
|
936
|
+
if (buildOptions.cache !== false) {
|
|
937
|
+
const configContent = generateCacheKeyContent(flowConfig, buildOptions);
|
|
938
|
+
const cached = await isBuildCached(configContent);
|
|
939
|
+
if (cached) {
|
|
940
|
+
const cachedBuild = await getCachedBuild(configContent);
|
|
941
|
+
if (cachedBuild) {
|
|
942
|
+
logger2.info("\u2728 Using cached build");
|
|
943
|
+
const outputPath = path8.resolve(buildOptions.output);
|
|
944
|
+
await fs7.ensureDir(path8.dirname(outputPath));
|
|
945
|
+
await fs7.writeFile(outputPath, cachedBuild);
|
|
946
|
+
logger2.gray(`Output: ${outputPath}`);
|
|
947
|
+
logger2.success("\u2705 Build completed (from cache)");
|
|
948
|
+
if (showStats) {
|
|
949
|
+
const stats = await fs7.stat(outputPath);
|
|
950
|
+
const packageStats = Object.entries(buildOptions.packages).map(
|
|
951
|
+
([name, pkg]) => ({
|
|
952
|
+
name: `${name}@${pkg.version || "latest"}`,
|
|
953
|
+
size: 0
|
|
954
|
+
// Size estimation not available for cached builds
|
|
955
|
+
})
|
|
956
|
+
);
|
|
957
|
+
return {
|
|
958
|
+
totalSize: stats.size,
|
|
959
|
+
packages: packageStats,
|
|
960
|
+
buildTime: Date.now() - bundleStartTime,
|
|
961
|
+
treeshakingEffective: true
|
|
962
|
+
};
|
|
963
|
+
}
|
|
964
|
+
return;
|
|
965
|
+
}
|
|
966
|
+
}
|
|
967
|
+
}
|
|
1041
968
|
try {
|
|
1042
969
|
if (!buildOptions.tempDir) {
|
|
1043
|
-
await
|
|
970
|
+
await fs7.emptyDir(TEMP_DIR);
|
|
1044
971
|
}
|
|
1045
|
-
|
|
1046
|
-
|
|
972
|
+
logger2.debug("Cleaned temporary directory");
|
|
973
|
+
logger2.info("\u{1F4E5} Downloading packages...");
|
|
1047
974
|
const packagesArray = Object.entries(buildOptions.packages).map(
|
|
1048
975
|
([name, packageConfig]) => ({
|
|
1049
976
|
name,
|
|
1050
|
-
version: packageConfig.version || "latest"
|
|
977
|
+
version: packageConfig.version || "latest",
|
|
978
|
+
path: packageConfig.path
|
|
979
|
+
// Pass local path if defined
|
|
1051
980
|
})
|
|
1052
981
|
);
|
|
1053
982
|
const packagePaths = await downloadPackages(
|
|
1054
983
|
packagesArray,
|
|
1055
984
|
TEMP_DIR,
|
|
1056
|
-
|
|
1057
|
-
buildOptions.cache
|
|
985
|
+
logger2,
|
|
986
|
+
buildOptions.cache,
|
|
987
|
+
buildOptions.configDir
|
|
988
|
+
// For resolving relative local paths
|
|
1058
989
|
);
|
|
1059
990
|
for (const [pkgName, pkgPath] of packagePaths.entries()) {
|
|
1060
991
|
if (pkgName.startsWith("@walkeros/")) {
|
|
1061
|
-
const pkgJsonPath =
|
|
1062
|
-
const pkgJson = await
|
|
992
|
+
const pkgJsonPath = path8.join(pkgPath, "package.json");
|
|
993
|
+
const pkgJson = await fs7.readJSON(pkgJsonPath);
|
|
1063
994
|
if (!pkgJson.exports && pkgJson.module) {
|
|
1064
995
|
pkgJson.exports = {
|
|
1065
996
|
".": {
|
|
@@ -1067,33 +998,33 @@ async function bundleCore(flowConfig, buildOptions, logger, showStats = false) {
|
|
|
1067
998
|
require: pkgJson.main
|
|
1068
999
|
}
|
|
1069
1000
|
};
|
|
1070
|
-
await
|
|
1001
|
+
await fs7.writeJSON(pkgJsonPath, pkgJson, { spaces: 2 });
|
|
1071
1002
|
}
|
|
1072
1003
|
}
|
|
1073
1004
|
}
|
|
1074
|
-
const packageJsonPath =
|
|
1075
|
-
await
|
|
1005
|
+
const packageJsonPath = path8.join(TEMP_DIR, "package.json");
|
|
1006
|
+
await fs7.writeFile(
|
|
1076
1007
|
packageJsonPath,
|
|
1077
1008
|
JSON.stringify({ type: "module" }, null, 2)
|
|
1078
1009
|
);
|
|
1079
|
-
|
|
1010
|
+
logger2.info("\u{1F4DD} Creating entry point...");
|
|
1080
1011
|
const entryContent = await createEntryPoint(
|
|
1081
1012
|
flowConfig,
|
|
1082
1013
|
buildOptions,
|
|
1083
1014
|
packagePaths
|
|
1084
1015
|
);
|
|
1085
|
-
const entryPath =
|
|
1086
|
-
await
|
|
1087
|
-
|
|
1088
|
-
const outputPath =
|
|
1089
|
-
await
|
|
1016
|
+
const entryPath = path8.join(TEMP_DIR, "entry.js");
|
|
1017
|
+
await fs7.writeFile(entryPath, entryContent);
|
|
1018
|
+
logger2.info("\u26A1 Bundling with esbuild...");
|
|
1019
|
+
const outputPath = path8.resolve(buildOptions.output);
|
|
1020
|
+
await fs7.ensureDir(path8.dirname(outputPath));
|
|
1090
1021
|
const esbuildOptions = createEsbuildOptions(
|
|
1091
1022
|
buildOptions,
|
|
1092
1023
|
entryPath,
|
|
1093
1024
|
outputPath,
|
|
1094
1025
|
TEMP_DIR,
|
|
1095
1026
|
packagePaths,
|
|
1096
|
-
|
|
1027
|
+
logger2
|
|
1097
1028
|
);
|
|
1098
1029
|
try {
|
|
1099
1030
|
await esbuild.build(esbuildOptions);
|
|
@@ -1103,7 +1034,13 @@ async function bundleCore(flowConfig, buildOptions, logger, showStats = false) {
|
|
|
1103
1034
|
buildOptions.code || ""
|
|
1104
1035
|
);
|
|
1105
1036
|
}
|
|
1106
|
-
|
|
1037
|
+
logger2.gray(`Output: ${outputPath}`);
|
|
1038
|
+
if (buildOptions.cache !== false) {
|
|
1039
|
+
const configContent = generateCacheKeyContent(flowConfig, buildOptions);
|
|
1040
|
+
const buildOutput = await fs7.readFile(outputPath, "utf-8");
|
|
1041
|
+
await cacheBuild(configContent, buildOutput);
|
|
1042
|
+
logger2.debug("Build cached for future use");
|
|
1043
|
+
}
|
|
1107
1044
|
let stats;
|
|
1108
1045
|
if (showStats) {
|
|
1109
1046
|
stats = await collectBundleStats(
|
|
@@ -1113,21 +1050,30 @@ async function bundleCore(flowConfig, buildOptions, logger, showStats = false) {
|
|
|
1113
1050
|
entryContent
|
|
1114
1051
|
);
|
|
1115
1052
|
}
|
|
1053
|
+
if (buildOptions.include && buildOptions.include.length > 0) {
|
|
1054
|
+
const outputDir = path8.dirname(outputPath);
|
|
1055
|
+
await copyIncludes(
|
|
1056
|
+
buildOptions.include,
|
|
1057
|
+
buildOptions.configDir || process.cwd(),
|
|
1058
|
+
outputDir,
|
|
1059
|
+
logger2
|
|
1060
|
+
);
|
|
1061
|
+
}
|
|
1116
1062
|
if (!buildOptions.tempDir) {
|
|
1117
|
-
await
|
|
1118
|
-
|
|
1063
|
+
await fs7.remove(TEMP_DIR);
|
|
1064
|
+
logger2.debug("Cleaned up temporary files");
|
|
1119
1065
|
}
|
|
1120
1066
|
return stats;
|
|
1121
1067
|
} catch (error) {
|
|
1122
1068
|
if (!buildOptions.tempDir) {
|
|
1123
|
-
await
|
|
1069
|
+
await fs7.remove(TEMP_DIR).catch(() => {
|
|
1124
1070
|
});
|
|
1125
1071
|
}
|
|
1126
1072
|
throw error;
|
|
1127
1073
|
}
|
|
1128
1074
|
}
|
|
1129
1075
|
async function collectBundleStats(outputPath, packages, startTime, entryContent) {
|
|
1130
|
-
const stats = await
|
|
1076
|
+
const stats = await fs7.stat(outputPath);
|
|
1131
1077
|
const totalSize = stats.size;
|
|
1132
1078
|
const buildTime = Date.now() - startTime;
|
|
1133
1079
|
const packageStats = Object.entries(packages).map(([name, pkg]) => {
|
|
@@ -1153,7 +1099,7 @@ async function collectBundleStats(outputPath, packages, startTime, entryContent)
|
|
|
1153
1099
|
treeshakingEffective
|
|
1154
1100
|
};
|
|
1155
1101
|
}
|
|
1156
|
-
function createEsbuildOptions(buildOptions, entryPath, outputPath, tempDir, packagePaths,
|
|
1102
|
+
function createEsbuildOptions(buildOptions, entryPath, outputPath, tempDir, packagePaths, logger2) {
|
|
1157
1103
|
const alias = {};
|
|
1158
1104
|
const baseOptions = {
|
|
1159
1105
|
entryPoints: [entryPath],
|
|
@@ -1206,6 +1152,11 @@ function createEsbuildOptions(buildOptions, entryPath, outputPath, tempDir, pack
|
|
|
1206
1152
|
];
|
|
1207
1153
|
const npmPackages = ["express", "express/*", "cors", "cors/*"];
|
|
1208
1154
|
baseOptions.external = buildOptions.external ? [...nodeBuiltins, ...npmPackages, ...buildOptions.external] : [...nodeBuiltins, ...npmPackages];
|
|
1155
|
+
if (buildOptions.format === "esm") {
|
|
1156
|
+
baseOptions.banner = {
|
|
1157
|
+
js: `import { createRequire } from 'module';const require = createRequire(import.meta.url);`
|
|
1158
|
+
};
|
|
1159
|
+
}
|
|
1209
1160
|
}
|
|
1210
1161
|
if (buildOptions.target) {
|
|
1211
1162
|
baseOptions.target = buildOptions.target;
|
|
@@ -1216,11 +1167,6 @@ function createEsbuildOptions(buildOptions, entryPath, outputPath, tempDir, pack
|
|
|
1216
1167
|
}
|
|
1217
1168
|
return baseOptions;
|
|
1218
1169
|
}
|
|
1219
|
-
function packageNameToVariable(packageName) {
|
|
1220
|
-
return packageName.replace("@", "_").replace(/[/-]/g, "_").split("_").map(
|
|
1221
|
-
(part, i) => i === 0 ? part : part.charAt(0).toUpperCase() + part.slice(1)
|
|
1222
|
-
).join("");
|
|
1223
|
-
}
|
|
1224
1170
|
function detectDestinationPackages(flowConfig) {
|
|
1225
1171
|
const destinationPackages = /* @__PURE__ */ new Set();
|
|
1226
1172
|
const destinations = flowConfig.destinations;
|
|
@@ -1233,10 +1179,57 @@ function detectDestinationPackages(flowConfig) {
|
|
|
1233
1179
|
}
|
|
1234
1180
|
return destinationPackages;
|
|
1235
1181
|
}
|
|
1236
|
-
function
|
|
1182
|
+
function detectSourcePackages(flowConfig) {
|
|
1183
|
+
const sourcePackages = /* @__PURE__ */ new Set();
|
|
1184
|
+
const sources = flowConfig.sources;
|
|
1185
|
+
if (sources) {
|
|
1186
|
+
for (const [sourceKey, sourceConfig] of Object.entries(sources)) {
|
|
1187
|
+
if (typeof sourceConfig === "object" && sourceConfig !== null && "package" in sourceConfig && typeof sourceConfig.package === "string") {
|
|
1188
|
+
sourcePackages.add(sourceConfig.package);
|
|
1189
|
+
}
|
|
1190
|
+
}
|
|
1191
|
+
}
|
|
1192
|
+
return sourcePackages;
|
|
1193
|
+
}
|
|
1194
|
+
function detectExplicitCodeImports(flowConfig) {
|
|
1195
|
+
const explicitCodeImports = /* @__PURE__ */ new Map();
|
|
1196
|
+
const destinations = flowConfig.destinations;
|
|
1197
|
+
if (destinations) {
|
|
1198
|
+
for (const [destKey, destConfig] of Object.entries(destinations)) {
|
|
1199
|
+
if (typeof destConfig === "object" && destConfig !== null && "package" in destConfig && typeof destConfig.package === "string" && "code" in destConfig && typeof destConfig.code === "string") {
|
|
1200
|
+
const isAutoGenerated = destConfig.code.startsWith("_");
|
|
1201
|
+
if (!isAutoGenerated) {
|
|
1202
|
+
if (!explicitCodeImports.has(destConfig.package)) {
|
|
1203
|
+
explicitCodeImports.set(destConfig.package, /* @__PURE__ */ new Set());
|
|
1204
|
+
}
|
|
1205
|
+
explicitCodeImports.get(destConfig.package).add(destConfig.code);
|
|
1206
|
+
}
|
|
1207
|
+
}
|
|
1208
|
+
}
|
|
1209
|
+
}
|
|
1210
|
+
const sources = flowConfig.sources;
|
|
1211
|
+
if (sources) {
|
|
1212
|
+
for (const [sourceKey, sourceConfig] of Object.entries(sources)) {
|
|
1213
|
+
if (typeof sourceConfig === "object" && sourceConfig !== null && "package" in sourceConfig && typeof sourceConfig.package === "string" && "code" in sourceConfig && typeof sourceConfig.code === "string") {
|
|
1214
|
+
const isAutoGenerated = sourceConfig.code.startsWith("_");
|
|
1215
|
+
if (!isAutoGenerated) {
|
|
1216
|
+
if (!explicitCodeImports.has(sourceConfig.package)) {
|
|
1217
|
+
explicitCodeImports.set(sourceConfig.package, /* @__PURE__ */ new Set());
|
|
1218
|
+
}
|
|
1219
|
+
explicitCodeImports.get(sourceConfig.package).add(sourceConfig.code);
|
|
1220
|
+
}
|
|
1221
|
+
}
|
|
1222
|
+
}
|
|
1223
|
+
}
|
|
1224
|
+
return explicitCodeImports;
|
|
1225
|
+
}
|
|
1226
|
+
function generateImportStatements(packages, destinationPackages, sourcePackages, explicitCodeImports) {
|
|
1237
1227
|
const importStatements = [];
|
|
1238
1228
|
const examplesMappings = [];
|
|
1229
|
+
const usedPackages = /* @__PURE__ */ new Set([...destinationPackages, ...sourcePackages]);
|
|
1239
1230
|
for (const [packageName, packageConfig] of Object.entries(packages)) {
|
|
1231
|
+
const isUsedByDestOrSource = usedPackages.has(packageName);
|
|
1232
|
+
const hasExplicitCode = explicitCodeImports.has(packageName);
|
|
1240
1233
|
if (packageConfig.imports && packageConfig.imports.length > 0) {
|
|
1241
1234
|
const uniqueImports = [...new Set(packageConfig.imports)];
|
|
1242
1235
|
const defaultImports = [];
|
|
@@ -1276,76 +1269,45 @@ function generateImportStatements(packages, destinationPackages) {
|
|
|
1276
1269
|
);
|
|
1277
1270
|
}
|
|
1278
1271
|
}
|
|
1279
|
-
} else {
|
|
1280
|
-
const
|
|
1272
|
+
} else if (hasExplicitCode) {
|
|
1273
|
+
const codes = Array.from(explicitCodeImports.get(packageName));
|
|
1281
1274
|
importStatements.push(
|
|
1282
|
-
`import
|
|
1275
|
+
`import { ${codes.join(", ")} } from '${packageName}';`
|
|
1283
1276
|
);
|
|
1277
|
+
} else if (isUsedByDestOrSource) {
|
|
1278
|
+
const varName = packageNameToVariable(packageName);
|
|
1279
|
+
importStatements.push(`import ${varName} from '${packageName}';`);
|
|
1284
1280
|
}
|
|
1285
1281
|
}
|
|
1286
1282
|
return { importStatements, examplesMappings };
|
|
1287
1283
|
}
|
|
1288
|
-
async function processTemplate(flowConfig, buildOptions) {
|
|
1289
|
-
if (buildOptions.template) {
|
|
1290
|
-
const templateEngine = new TemplateEngine();
|
|
1291
|
-
const flowWithProps = flowConfig;
|
|
1292
|
-
return await templateEngine.process(
|
|
1293
|
-
buildOptions.template,
|
|
1294
|
-
buildOptions.code || "",
|
|
1295
|
-
// Pass user code as parameter (empty if undefined)
|
|
1296
|
-
flowWithProps.sources || {},
|
|
1297
|
-
flowWithProps.destinations || {},
|
|
1298
|
-
flowWithProps.collector || {},
|
|
1299
|
-
buildOptions
|
|
1300
|
-
// Pass build config to template
|
|
1301
|
-
);
|
|
1302
|
-
} else {
|
|
1303
|
-
return buildOptions.code || "";
|
|
1304
|
-
}
|
|
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}`;
|
|
1314
|
-
}
|
|
1315
|
-
}
|
|
1316
|
-
return code;
|
|
1317
|
-
}
|
|
1318
|
-
function assembleFinalCode(importStatements, examplesObject, wrappedCode, format) {
|
|
1319
|
-
const importsCode = importStatements.join("\n");
|
|
1320
|
-
let finalCode = importsCode ? `${importsCode}
|
|
1321
|
-
|
|
1322
|
-
${examplesObject}${wrappedCode}` : `${examplesObject}${wrappedCode}`;
|
|
1323
|
-
if (examplesObject && format === "esm") {
|
|
1324
|
-
finalCode += `
|
|
1325
|
-
|
|
1326
|
-
export { examples };`;
|
|
1327
|
-
}
|
|
1328
|
-
return finalCode;
|
|
1329
|
-
}
|
|
1330
1284
|
async function createEntryPoint(flowConfig, buildOptions, packagePaths) {
|
|
1331
1285
|
const destinationPackages = detectDestinationPackages(flowConfig);
|
|
1286
|
+
const sourcePackages = detectSourcePackages(flowConfig);
|
|
1287
|
+
const explicitCodeImports = detectExplicitCodeImports(flowConfig);
|
|
1332
1288
|
const { importStatements } = generateImportStatements(
|
|
1333
1289
|
buildOptions.packages,
|
|
1334
|
-
destinationPackages
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
const templatedCode = await processTemplate(flowConfig, buildOptions);
|
|
1338
|
-
const wrappedCode = wrapCodeForFormat(
|
|
1339
|
-
templatedCode,
|
|
1340
|
-
buildOptions.format,
|
|
1341
|
-
!!buildOptions.template
|
|
1290
|
+
destinationPackages,
|
|
1291
|
+
sourcePackages,
|
|
1292
|
+
explicitCodeImports
|
|
1342
1293
|
);
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1294
|
+
const importsCode = importStatements.join("\n");
|
|
1295
|
+
const hasFlow = destinationPackages.size > 0 || sourcePackages.size > 0;
|
|
1296
|
+
if (!hasFlow) {
|
|
1297
|
+
const userCode = buildOptions.code || "";
|
|
1298
|
+
return importsCode ? `${importsCode}
|
|
1299
|
+
|
|
1300
|
+
${userCode}` : userCode;
|
|
1301
|
+
}
|
|
1302
|
+
const configObject = buildConfigObject(flowConfig, explicitCodeImports);
|
|
1303
|
+
const wrappedCode = generatePlatformWrapper(
|
|
1304
|
+
configObject,
|
|
1305
|
+
buildOptions.code || "",
|
|
1306
|
+
buildOptions
|
|
1348
1307
|
);
|
|
1308
|
+
return importsCode ? `${importsCode}
|
|
1309
|
+
|
|
1310
|
+
${wrappedCode}` : wrappedCode;
|
|
1349
1311
|
}
|
|
1350
1312
|
function createBuildError(buildError, code) {
|
|
1351
1313
|
if (!buildError.errors || buildError.errors.length === 0) {
|
|
@@ -1370,92 +1332,165 @@ ${firstError.text}`
|
|
|
1370
1332
|
` + (location ? ` at ${location.file}:${location.line}:${location.column}` : "")
|
|
1371
1333
|
);
|
|
1372
1334
|
}
|
|
1335
|
+
function buildConfigObject(flowConfig, explicitCodeImports) {
|
|
1336
|
+
const flowWithProps = flowConfig;
|
|
1337
|
+
const sources = flowWithProps.sources || {};
|
|
1338
|
+
const destinations = flowWithProps.destinations || {};
|
|
1339
|
+
const sourcesEntries = Object.entries(sources).map(([key, source]) => {
|
|
1340
|
+
const hasExplicitCode = source.code && explicitCodeImports.has(source.package);
|
|
1341
|
+
const codeVar = hasExplicitCode ? source.code : packageNameToVariable(source.package);
|
|
1342
|
+
const configStr = source.config ? processConfigValue(source.config) : "{}";
|
|
1343
|
+
const envStr = source.env ? `,
|
|
1344
|
+
env: ${processConfigValue(source.env)}` : "";
|
|
1345
|
+
return ` ${key}: {
|
|
1346
|
+
code: ${codeVar},
|
|
1347
|
+
config: ${configStr}${envStr}
|
|
1348
|
+
}`;
|
|
1349
|
+
});
|
|
1350
|
+
const destinationsEntries = Object.entries(destinations).map(
|
|
1351
|
+
([key, dest]) => {
|
|
1352
|
+
const hasExplicitCode = dest.code && explicitCodeImports.has(dest.package);
|
|
1353
|
+
const codeVar = hasExplicitCode ? dest.code : packageNameToVariable(dest.package);
|
|
1354
|
+
const configStr = dest.config ? processConfigValue(dest.config) : "{}";
|
|
1355
|
+
const envStr = dest.env ? `,
|
|
1356
|
+
env: ${processConfigValue(dest.env)}` : "";
|
|
1357
|
+
return ` ${key}: {
|
|
1358
|
+
code: ${codeVar},
|
|
1359
|
+
config: ${configStr}${envStr}
|
|
1360
|
+
}`;
|
|
1361
|
+
}
|
|
1362
|
+
);
|
|
1363
|
+
const collectorStr = flowWithProps.collector ? `,
|
|
1364
|
+
...${processConfigValue(flowWithProps.collector)}` : "";
|
|
1365
|
+
return `{
|
|
1366
|
+
sources: {
|
|
1367
|
+
${sourcesEntries.join(",\n")}
|
|
1368
|
+
},
|
|
1369
|
+
destinations: {
|
|
1370
|
+
${destinationsEntries.join(",\n")}
|
|
1371
|
+
}${collectorStr}
|
|
1372
|
+
}`;
|
|
1373
|
+
}
|
|
1374
|
+
function processConfigValue(value) {
|
|
1375
|
+
return JSON.stringify(value, null, 2);
|
|
1376
|
+
}
|
|
1377
|
+
function generatePlatformWrapper(configObject, userCode, buildOptions) {
|
|
1378
|
+
if (buildOptions.platform === "browser") {
|
|
1379
|
+
const windowAssignments = [];
|
|
1380
|
+
if (buildOptions.windowCollector) {
|
|
1381
|
+
windowAssignments.push(
|
|
1382
|
+
` if (typeof window !== 'undefined') window['${buildOptions.windowCollector}'] = collector;`
|
|
1383
|
+
);
|
|
1384
|
+
}
|
|
1385
|
+
if (buildOptions.windowElb) {
|
|
1386
|
+
windowAssignments.push(
|
|
1387
|
+
` if (typeof window !== 'undefined') window['${buildOptions.windowElb}'] = elb;`
|
|
1388
|
+
);
|
|
1389
|
+
}
|
|
1390
|
+
const assignments = windowAssignments.length > 0 ? "\n" + windowAssignments.join("\n") : "";
|
|
1391
|
+
return `(async () => {
|
|
1392
|
+
const config = ${configObject};
|
|
1393
|
+
|
|
1394
|
+
${userCode}
|
|
1395
|
+
|
|
1396
|
+
const { collector, elb } = await startFlow(config);${assignments}
|
|
1397
|
+
})();`;
|
|
1398
|
+
} else {
|
|
1399
|
+
const codeSection = userCode ? `
|
|
1400
|
+
${userCode}
|
|
1401
|
+
` : "";
|
|
1402
|
+
return `export default async function(context = {}) {
|
|
1403
|
+
const config = ${configObject};${codeSection}
|
|
1404
|
+
return await startFlow(config);
|
|
1405
|
+
}`;
|
|
1406
|
+
}
|
|
1407
|
+
}
|
|
1373
1408
|
|
|
1374
1409
|
// src/commands/bundle/stats.ts
|
|
1375
|
-
function displayStats(stats,
|
|
1376
|
-
|
|
1377
|
-
|
|
1410
|
+
function displayStats(stats, logger2) {
|
|
1411
|
+
logger2.info("\n\u{1F4CA} Bundle Statistics");
|
|
1412
|
+
logger2.info("\u2500".repeat(50));
|
|
1378
1413
|
const sizeKB = formatBytes(stats.totalSize);
|
|
1379
|
-
|
|
1414
|
+
logger2.info(`Total Size: ${sizeKB} KB`);
|
|
1380
1415
|
const timeSeconds = (stats.buildTime / 1e3).toFixed(2);
|
|
1381
|
-
|
|
1416
|
+
logger2.info(`Build Time: ${timeSeconds}s`);
|
|
1382
1417
|
const treeshakingStatus = stats.treeshakingEffective ? "\u2705 Effective" : "\u26A0\uFE0F Not optimal (consider using named imports)";
|
|
1383
|
-
|
|
1418
|
+
logger2.info(`Tree-shaking: ${treeshakingStatus}`);
|
|
1384
1419
|
if (stats.packages.length > 0) {
|
|
1385
|
-
|
|
1420
|
+
logger2.info(`
|
|
1386
1421
|
Package Breakdown:`);
|
|
1387
1422
|
stats.packages.forEach((pkg) => {
|
|
1388
1423
|
if (pkg.size > 0) {
|
|
1389
1424
|
const pkgSizeKB = formatBytes(pkg.size);
|
|
1390
|
-
|
|
1425
|
+
logger2.info(` \u2022 ${pkg.name}: ${pkgSizeKB} KB`);
|
|
1391
1426
|
}
|
|
1392
1427
|
});
|
|
1393
1428
|
}
|
|
1394
|
-
|
|
1429
|
+
logger2.info("\u2500".repeat(50));
|
|
1395
1430
|
}
|
|
1396
1431
|
|
|
1397
1432
|
// src/commands/bundle/index.ts
|
|
1398
1433
|
async function bundleCommand(options) {
|
|
1399
1434
|
const timer = createTimer();
|
|
1400
1435
|
timer.start();
|
|
1401
|
-
const
|
|
1436
|
+
const logger2 = createCommandLogger(options);
|
|
1402
1437
|
const dockerArgs = buildCommonDockerArgs(options);
|
|
1403
|
-
if (options.
|
|
1438
|
+
if (options.flow) dockerArgs.push("--flow", options.flow);
|
|
1404
1439
|
if (options.all) dockerArgs.push("--all");
|
|
1405
1440
|
if (options.stats) dockerArgs.push("--stats");
|
|
1406
1441
|
if (options.cache === false) dockerArgs.push("--no-cache");
|
|
1407
1442
|
await executeCommand(
|
|
1408
1443
|
async () => {
|
|
1409
1444
|
try {
|
|
1410
|
-
if (options.
|
|
1411
|
-
throw new Error("Cannot use both --
|
|
1445
|
+
if (options.flow && options.all) {
|
|
1446
|
+
throw new Error("Cannot use both --flow and --all flags together");
|
|
1412
1447
|
}
|
|
1413
|
-
|
|
1414
|
-
const configPath = options.config;
|
|
1448
|
+
logger2.info("\u{1F4E6} Reading configuration...");
|
|
1449
|
+
const configPath = resolveAsset(options.config, "config");
|
|
1415
1450
|
const rawConfig = await loadJsonConfig(configPath);
|
|
1416
|
-
const configsToBundle = options.all ?
|
|
1451
|
+
const configsToBundle = options.all ? loadAllFlows(rawConfig, { configPath, logger: logger2 }) : [
|
|
1417
1452
|
loadBundleConfig(rawConfig, {
|
|
1418
1453
|
configPath,
|
|
1419
|
-
|
|
1420
|
-
logger
|
|
1454
|
+
flowName: options.flow,
|
|
1455
|
+
logger: logger2
|
|
1421
1456
|
})
|
|
1422
1457
|
];
|
|
1423
1458
|
const results = [];
|
|
1424
1459
|
for (const {
|
|
1425
1460
|
flowConfig,
|
|
1426
1461
|
buildOptions,
|
|
1427
|
-
|
|
1428
|
-
|
|
1462
|
+
flowName,
|
|
1463
|
+
isMultiFlow
|
|
1429
1464
|
} of configsToBundle) {
|
|
1430
1465
|
try {
|
|
1431
1466
|
if (options.cache !== void 0) {
|
|
1432
1467
|
buildOptions.cache = options.cache;
|
|
1433
1468
|
}
|
|
1434
|
-
if (
|
|
1435
|
-
|
|
1436
|
-
\u{1F527} Building
|
|
1469
|
+
if (isMultiFlow || options.all) {
|
|
1470
|
+
logger2.info(`
|
|
1471
|
+
\u{1F527} Building flow: ${flowName}`);
|
|
1437
1472
|
} else {
|
|
1438
|
-
|
|
1473
|
+
logger2.info("\u{1F527} Starting bundle process...");
|
|
1439
1474
|
}
|
|
1440
1475
|
const shouldCollectStats = options.stats || options.json;
|
|
1441
1476
|
const stats = await bundleCore(
|
|
1442
1477
|
flowConfig,
|
|
1443
1478
|
buildOptions,
|
|
1444
|
-
|
|
1479
|
+
logger2,
|
|
1445
1480
|
shouldCollectStats
|
|
1446
1481
|
);
|
|
1447
1482
|
results.push({
|
|
1448
|
-
|
|
1483
|
+
flowName,
|
|
1449
1484
|
success: true,
|
|
1450
1485
|
stats
|
|
1451
1486
|
});
|
|
1452
1487
|
if (!options.json && !options.all && options.stats && stats) {
|
|
1453
|
-
displayStats(stats,
|
|
1488
|
+
displayStats(stats, logger2);
|
|
1454
1489
|
}
|
|
1455
1490
|
} catch (error) {
|
|
1456
1491
|
const errorMessage = getErrorMessage(error);
|
|
1457
1492
|
results.push({
|
|
1458
|
-
|
|
1493
|
+
flowName,
|
|
1459
1494
|
success: false,
|
|
1460
1495
|
error: errorMessage
|
|
1461
1496
|
});
|
|
@@ -1471,7 +1506,7 @@ async function bundleCommand(options) {
|
|
|
1471
1506
|
const outputLogger = createLogger({ silent: false, json: false });
|
|
1472
1507
|
const output = failureCount === 0 ? createSuccessOutput(
|
|
1473
1508
|
{
|
|
1474
|
-
|
|
1509
|
+
flows: results,
|
|
1475
1510
|
summary: {
|
|
1476
1511
|
total: results.length,
|
|
1477
1512
|
success: successCount,
|
|
@@ -1480,27 +1515,27 @@ async function bundleCommand(options) {
|
|
|
1480
1515
|
},
|
|
1481
1516
|
duration
|
|
1482
1517
|
) : createErrorOutput(
|
|
1483
|
-
`${failureCount}
|
|
1518
|
+
`${failureCount} flow(s) failed to build`,
|
|
1484
1519
|
duration
|
|
1485
1520
|
);
|
|
1486
1521
|
outputLogger.log("white", JSON.stringify(output, null, 2));
|
|
1487
1522
|
} else {
|
|
1488
1523
|
if (options.all) {
|
|
1489
|
-
|
|
1524
|
+
logger2.info(`
|
|
1490
1525
|
\u{1F4CA} Build Summary:`);
|
|
1491
|
-
|
|
1492
|
-
|
|
1526
|
+
logger2.info(` Total: ${results.length}`);
|
|
1527
|
+
logger2.success(` \u2705 Success: ${successCount}`);
|
|
1493
1528
|
if (failureCount > 0) {
|
|
1494
|
-
|
|
1529
|
+
logger2.error(` \u274C Failed: ${failureCount}`);
|
|
1495
1530
|
}
|
|
1496
1531
|
}
|
|
1497
1532
|
if (failureCount === 0) {
|
|
1498
|
-
|
|
1533
|
+
logger2.success(
|
|
1499
1534
|
`
|
|
1500
1535
|
\u2705 Bundle created successfully in ${timer.format()}`
|
|
1501
1536
|
);
|
|
1502
1537
|
} else {
|
|
1503
|
-
throw new Error(`${failureCount}
|
|
1538
|
+
throw new Error(`${failureCount} flow(s) failed to build`);
|
|
1504
1539
|
}
|
|
1505
1540
|
}
|
|
1506
1541
|
} catch (error) {
|
|
@@ -1511,8 +1546,8 @@ async function bundleCommand(options) {
|
|
|
1511
1546
|
const output = createErrorOutput(errorMessage, duration);
|
|
1512
1547
|
outputLogger.log("white", JSON.stringify(output, null, 2));
|
|
1513
1548
|
} else {
|
|
1514
|
-
|
|
1515
|
-
|
|
1549
|
+
logger2.error("\u274C Bundle failed:");
|
|
1550
|
+
logger2.error(errorMessage);
|
|
1516
1551
|
}
|
|
1517
1552
|
process.exit(1);
|
|
1518
1553
|
}
|
|
@@ -1520,33 +1555,40 @@ async function bundleCommand(options) {
|
|
|
1520
1555
|
"bundle",
|
|
1521
1556
|
dockerArgs,
|
|
1522
1557
|
options,
|
|
1523
|
-
|
|
1558
|
+
logger2,
|
|
1524
1559
|
options.config
|
|
1525
1560
|
);
|
|
1526
1561
|
}
|
|
1527
1562
|
async function bundle(configOrPath, options = {}) {
|
|
1528
1563
|
let rawConfig;
|
|
1564
|
+
let configPath = path9.resolve(process.cwd(), "walkeros.config.json");
|
|
1529
1565
|
if (typeof configOrPath === "string") {
|
|
1530
|
-
|
|
1566
|
+
configPath = resolveAsset(configOrPath, "config");
|
|
1567
|
+
rawConfig = await loadJsonConfig(configPath);
|
|
1531
1568
|
} else {
|
|
1532
1569
|
rawConfig = configOrPath;
|
|
1533
1570
|
}
|
|
1534
|
-
const { flowConfig, buildOptions } =
|
|
1571
|
+
const { flowConfig, buildOptions } = loadBundleConfig(rawConfig, {
|
|
1572
|
+
configPath,
|
|
1573
|
+
flowName: options.flowName,
|
|
1574
|
+
buildOverrides: options.buildOverrides
|
|
1575
|
+
});
|
|
1535
1576
|
if (options.cache !== void 0) {
|
|
1536
1577
|
buildOptions.cache = options.cache;
|
|
1537
1578
|
}
|
|
1538
|
-
const
|
|
1579
|
+
const logger2 = createCommandLogger(options);
|
|
1539
1580
|
return await bundleCore(
|
|
1540
1581
|
flowConfig,
|
|
1541
1582
|
buildOptions,
|
|
1542
|
-
|
|
1583
|
+
logger2,
|
|
1543
1584
|
options.stats ?? false
|
|
1544
1585
|
);
|
|
1545
1586
|
}
|
|
1546
1587
|
|
|
1547
1588
|
// src/commands/simulate/simulator.ts
|
|
1548
|
-
import
|
|
1549
|
-
import
|
|
1589
|
+
import path10 from "path";
|
|
1590
|
+
import fs9 from "fs-extra";
|
|
1591
|
+
import { getPlatform as getPlatform2 } from "@walkeros/core";
|
|
1550
1592
|
|
|
1551
1593
|
// src/commands/simulate/tracker.ts
|
|
1552
1594
|
var CallTracker = class {
|
|
@@ -1582,9 +1624,9 @@ var CallTracker = class {
|
|
|
1582
1624
|
}
|
|
1583
1625
|
for (const fullPath of paths) {
|
|
1584
1626
|
const [destKey, ...pathParts] = fullPath.split(":");
|
|
1585
|
-
const
|
|
1586
|
-
if (!
|
|
1587
|
-
const cleanPath =
|
|
1627
|
+
const path15 = pathParts.join(":");
|
|
1628
|
+
if (!path15) continue;
|
|
1629
|
+
const cleanPath = path15.replace(/^call:/, "");
|
|
1588
1630
|
const parts = cleanPath.split(".");
|
|
1589
1631
|
let current = wrapped;
|
|
1590
1632
|
let source = env;
|
|
@@ -1628,7 +1670,7 @@ var CallTracker = class {
|
|
|
1628
1670
|
|
|
1629
1671
|
// src/commands/simulate/jsdom-executor.ts
|
|
1630
1672
|
import { JSDOM, VirtualConsole } from "jsdom";
|
|
1631
|
-
import
|
|
1673
|
+
import fs8 from "fs-extra";
|
|
1632
1674
|
function buildSandboxFromEnvs(envs, destinations, tracker) {
|
|
1633
1675
|
const baseBrowserMocks = {
|
|
1634
1676
|
Image: class MockImage {
|
|
@@ -1697,7 +1739,7 @@ async function executeInJSDOM(bundlePath, destinations, event, tracker, envs, ti
|
|
|
1697
1739
|
const sandbox = buildSandboxFromEnvs(envs, destinations, tracker);
|
|
1698
1740
|
Object.assign(window, sandbox.window);
|
|
1699
1741
|
Object.assign(window.document, sandbox.document);
|
|
1700
|
-
const bundleCode = await
|
|
1742
|
+
const bundleCode = await fs8.readFile(bundlePath, "utf8");
|
|
1701
1743
|
try {
|
|
1702
1744
|
window.eval(bundleCode);
|
|
1703
1745
|
} catch (error) {
|
|
@@ -1735,6 +1777,85 @@ async function executeInJSDOM(bundlePath, destinations, event, tracker, envs, ti
|
|
|
1735
1777
|
};
|
|
1736
1778
|
}
|
|
1737
1779
|
|
|
1780
|
+
// src/commands/simulate/node-executor.ts
|
|
1781
|
+
import { pathToFileURL } from "url";
|
|
1782
|
+
function buildGlobalMocksFromEnvs(envs, destinations, tracker) {
|
|
1783
|
+
const globalMocks = {};
|
|
1784
|
+
for (const [destKey] of Object.entries(destinations)) {
|
|
1785
|
+
const destEnv = envs[destKey];
|
|
1786
|
+
if (!destEnv?.push) continue;
|
|
1787
|
+
const mockEnv = destEnv.push;
|
|
1788
|
+
const trackPaths = destEnv.simulation || [];
|
|
1789
|
+
const trackedEnv = tracker.wrapEnv(
|
|
1790
|
+
mockEnv,
|
|
1791
|
+
trackPaths.map((p) => `${destKey}:${p}`)
|
|
1792
|
+
);
|
|
1793
|
+
Object.assign(globalMocks, trackedEnv);
|
|
1794
|
+
}
|
|
1795
|
+
return globalMocks;
|
|
1796
|
+
}
|
|
1797
|
+
function injectGlobalMocks(mocks) {
|
|
1798
|
+
const originalValues = {};
|
|
1799
|
+
for (const [key, value] of Object.entries(mocks)) {
|
|
1800
|
+
originalValues[key] = globalThis[key];
|
|
1801
|
+
globalThis[key] = value;
|
|
1802
|
+
}
|
|
1803
|
+
return () => {
|
|
1804
|
+
for (const [key, value] of Object.entries(originalValues)) {
|
|
1805
|
+
if (value === void 0) {
|
|
1806
|
+
delete globalThis[key];
|
|
1807
|
+
} else {
|
|
1808
|
+
globalThis[key] = value;
|
|
1809
|
+
}
|
|
1810
|
+
}
|
|
1811
|
+
};
|
|
1812
|
+
}
|
|
1813
|
+
async function executeInNode(bundlePath, destinations, event, tracker, envs, timeout = 3e4) {
|
|
1814
|
+
const start = Date.now();
|
|
1815
|
+
const globalMocks = buildGlobalMocksFromEnvs(envs, destinations, tracker);
|
|
1816
|
+
const cleanupMocks = injectGlobalMocks(globalMocks);
|
|
1817
|
+
try {
|
|
1818
|
+
const executeWithTimeout = async () => {
|
|
1819
|
+
const importUrl = process.env.JEST_WORKER_ID ? bundlePath : `${pathToFileURL(bundlePath).href}?t=${Date.now()}`;
|
|
1820
|
+
const module = await import(importUrl);
|
|
1821
|
+
if (!module.default || typeof module.default !== "function") {
|
|
1822
|
+
throw new Error("Bundle does not export default factory function");
|
|
1823
|
+
}
|
|
1824
|
+
const result = await module.default();
|
|
1825
|
+
if (!result || !result.elb || typeof result.elb !== "function") {
|
|
1826
|
+
throw new Error(
|
|
1827
|
+
"Factory function did not return valid result with elb"
|
|
1828
|
+
);
|
|
1829
|
+
}
|
|
1830
|
+
const { collector, elb } = result;
|
|
1831
|
+
let elbResult;
|
|
1832
|
+
try {
|
|
1833
|
+
elbResult = await elb(event.name, event.data);
|
|
1834
|
+
} catch (error) {
|
|
1835
|
+
throw new Error(`Event execution failed: ${getErrorMessage(error)}`);
|
|
1836
|
+
}
|
|
1837
|
+
return {
|
|
1838
|
+
collector,
|
|
1839
|
+
elb,
|
|
1840
|
+
elbResult,
|
|
1841
|
+
usage: tracker.getCalls(),
|
|
1842
|
+
duration: Date.now() - start
|
|
1843
|
+
};
|
|
1844
|
+
};
|
|
1845
|
+
const timeoutPromise = new Promise((_, reject) => {
|
|
1846
|
+
setTimeout(
|
|
1847
|
+
() => reject(new Error(`Server simulation timeout after ${timeout}ms`)),
|
|
1848
|
+
timeout
|
|
1849
|
+
);
|
|
1850
|
+
});
|
|
1851
|
+
return await Promise.race([executeWithTimeout(), timeoutPromise]);
|
|
1852
|
+
} catch (error) {
|
|
1853
|
+
throw new Error(`Node execution failed: ${getErrorMessage(error)}`);
|
|
1854
|
+
} finally {
|
|
1855
|
+
cleanupMocks();
|
|
1856
|
+
}
|
|
1857
|
+
}
|
|
1858
|
+
|
|
1738
1859
|
// src/commands/simulate/env-loader.ts
|
|
1739
1860
|
async function loadDestinationEnvs(destinations) {
|
|
1740
1861
|
const envs = {};
|
|
@@ -1771,28 +1892,28 @@ function generateId() {
|
|
|
1771
1892
|
return `${Date.now()}-${Math.random().toString(36).substring(2, 11)}`;
|
|
1772
1893
|
}
|
|
1773
1894
|
async function simulateCore(configPath, event, options = {}) {
|
|
1774
|
-
const
|
|
1895
|
+
const logger2 = createLogger({
|
|
1775
1896
|
verbose: options.verbose || false,
|
|
1776
1897
|
silent: options.silent || false,
|
|
1777
1898
|
json: options.json || false
|
|
1778
1899
|
});
|
|
1779
1900
|
try {
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
const fullConfigPath =
|
|
1901
|
+
logger2.info("\u{1F3AF} Starting walkerOS simulation...");
|
|
1902
|
+
logger2.info("\u{1F4E6} Loading bundle configuration...");
|
|
1903
|
+
const fullConfigPath = path10.resolve(configPath);
|
|
1783
1904
|
const rawConfig = await loadJsonConfig(fullConfigPath);
|
|
1784
|
-
|
|
1785
|
-
|
|
1905
|
+
loadBundleConfig(rawConfig, { configPath: fullConfigPath });
|
|
1906
|
+
logger2.info(`\u{1F680} Executing simulation with event: ${JSON.stringify(event)}`);
|
|
1786
1907
|
const result = await executeSimulation(event, fullConfigPath);
|
|
1787
1908
|
if (result.success) {
|
|
1788
|
-
|
|
1909
|
+
logger2.info(`\u2705 Simulation completed successfully`);
|
|
1789
1910
|
} else {
|
|
1790
|
-
|
|
1911
|
+
logger2.error(`\u274C Simulation failed: ${result.error}`);
|
|
1791
1912
|
}
|
|
1792
1913
|
return result;
|
|
1793
1914
|
} catch (error) {
|
|
1794
1915
|
const errorMessage = getErrorMessage(error);
|
|
1795
|
-
|
|
1916
|
+
logger2.error(`\u{1F4A5} Simulation error: ${errorMessage}`);
|
|
1796
1917
|
return {
|
|
1797
1918
|
success: false,
|
|
1798
1919
|
error: errorMessage
|
|
@@ -1825,42 +1946,32 @@ async function executeSimulation(event, configPath) {
|
|
|
1825
1946
|
);
|
|
1826
1947
|
}
|
|
1827
1948
|
const typedEvent = event;
|
|
1828
|
-
await
|
|
1949
|
+
await fs9.ensureDir(tempDir);
|
|
1829
1950
|
const rawConfig = await loadJsonConfig(configPath);
|
|
1830
|
-
const { flowConfig, buildOptions } =
|
|
1831
|
-
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
version: (typeof packageConfig === "object" && packageConfig !== null && "version" in packageConfig && typeof packageConfig.version === "string" ? packageConfig.version : void 0) || "latest"
|
|
1835
|
-
})
|
|
1836
|
-
);
|
|
1837
|
-
const packagePaths = await downloadPackages(
|
|
1838
|
-
packagesArray,
|
|
1839
|
-
tempDir,
|
|
1840
|
-
// downloadPackages will add 'node_modules' subdirectory itself
|
|
1841
|
-
createLogger({ silent: true }),
|
|
1842
|
-
buildOptions.cache
|
|
1843
|
-
);
|
|
1951
|
+
const { flowConfig, buildOptions } = loadBundleConfig(rawConfig, {
|
|
1952
|
+
configPath
|
|
1953
|
+
});
|
|
1954
|
+
const platform = getPlatform2(flowConfig);
|
|
1844
1955
|
const tracker = new CallTracker();
|
|
1845
|
-
const tempOutput =
|
|
1956
|
+
const tempOutput = path10.join(
|
|
1846
1957
|
tempDir,
|
|
1847
|
-
`simulation-bundle-${generateId()}
|
|
1958
|
+
`simulation-bundle-${generateId()}.${platform === "web" ? "js" : "mjs"}`
|
|
1848
1959
|
);
|
|
1849
1960
|
const destinations = flowConfig.destinations;
|
|
1850
1961
|
const simulationBuildOptions = {
|
|
1851
1962
|
...buildOptions,
|
|
1852
1963
|
code: buildOptions.code || "",
|
|
1853
|
-
// No code modification - use original
|
|
1854
1964
|
output: tempOutput,
|
|
1855
1965
|
tempDir,
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
|
|
1966
|
+
...platform === "web" ? {
|
|
1967
|
+
format: "iife",
|
|
1968
|
+
platform: "browser",
|
|
1969
|
+
windowCollector: "collector",
|
|
1970
|
+
windowElb: "elb"
|
|
1971
|
+
} : {
|
|
1972
|
+
format: "esm",
|
|
1973
|
+
platform: "node"
|
|
1974
|
+
}
|
|
1864
1975
|
};
|
|
1865
1976
|
await bundleCore(
|
|
1866
1977
|
flowConfig,
|
|
@@ -1870,16 +1981,26 @@ async function executeSimulation(event, configPath) {
|
|
|
1870
1981
|
);
|
|
1871
1982
|
bundlePath = tempOutput;
|
|
1872
1983
|
const envs = await loadDestinationEnvs(destinations || {});
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
|
|
1984
|
+
let result;
|
|
1985
|
+
if (platform === "web") {
|
|
1986
|
+
result = await executeInJSDOM(
|
|
1987
|
+
tempOutput,
|
|
1988
|
+
destinations || {},
|
|
1989
|
+
typedEvent,
|
|
1990
|
+
tracker,
|
|
1991
|
+
envs,
|
|
1992
|
+
1e4
|
|
1993
|
+
);
|
|
1994
|
+
} else {
|
|
1995
|
+
result = await executeInNode(
|
|
1996
|
+
tempOutput,
|
|
1997
|
+
destinations || {},
|
|
1998
|
+
typedEvent,
|
|
1999
|
+
tracker,
|
|
2000
|
+
envs,
|
|
2001
|
+
3e4
|
|
2002
|
+
);
|
|
2003
|
+
}
|
|
1883
2004
|
const elbResult = result.elbResult;
|
|
1884
2005
|
const usage = result.usage;
|
|
1885
2006
|
const duration = Date.now() - startTime;
|
|
@@ -1899,7 +2020,7 @@ async function executeSimulation(event, configPath) {
|
|
|
1899
2020
|
};
|
|
1900
2021
|
} finally {
|
|
1901
2022
|
if (tempDir) {
|
|
1902
|
-
await
|
|
2023
|
+
await fs9.remove(tempDir).catch(() => {
|
|
1903
2024
|
});
|
|
1904
2025
|
}
|
|
1905
2026
|
}
|
|
@@ -1907,7 +2028,7 @@ async function executeSimulation(event, configPath) {
|
|
|
1907
2028
|
|
|
1908
2029
|
// src/commands/simulate/index.ts
|
|
1909
2030
|
async function simulateCommand(options) {
|
|
1910
|
-
const
|
|
2031
|
+
const logger2 = createCommandLogger(options);
|
|
1911
2032
|
const dockerArgs = buildCommonDockerArgs(options);
|
|
1912
2033
|
if (options.event) dockerArgs.push("--event", options.event);
|
|
1913
2034
|
await executeCommand(
|
|
@@ -1958,7 +2079,7 @@ async function simulateCommand(options) {
|
|
|
1958
2079
|
"simulate",
|
|
1959
2080
|
dockerArgs,
|
|
1960
2081
|
options,
|
|
1961
|
-
|
|
2082
|
+
logger2,
|
|
1962
2083
|
options.config
|
|
1963
2084
|
);
|
|
1964
2085
|
}
|
|
@@ -1975,74 +2096,83 @@ async function simulate(configOrPath, event, options = {}) {
|
|
|
1975
2096
|
}
|
|
1976
2097
|
|
|
1977
2098
|
// src/commands/push/index.ts
|
|
1978
|
-
import
|
|
1979
|
-
import os2 from "os";
|
|
2099
|
+
import path11 from "path";
|
|
1980
2100
|
import { JSDOM as JSDOM2, VirtualConsole as VirtualConsole2 } from "jsdom";
|
|
1981
|
-
import
|
|
2101
|
+
import fs10 from "fs-extra";
|
|
2102
|
+
import { getPlatform as getPlatform3 } from "@walkeros/core";
|
|
2103
|
+
import { schemas as schemas2 } from "@walkeros/core/dev";
|
|
1982
2104
|
async function pushCommand(options) {
|
|
1983
|
-
const
|
|
2105
|
+
const logger2 = createCommandLogger(options);
|
|
1984
2106
|
const dockerArgs = buildCommonDockerArgs(options);
|
|
1985
2107
|
dockerArgs.push("--event", options.event);
|
|
1986
|
-
if (options.
|
|
2108
|
+
if (options.flow) dockerArgs.push("--flow", options.flow);
|
|
1987
2109
|
await executeCommand(
|
|
1988
2110
|
async () => {
|
|
1989
2111
|
const startTime = Date.now();
|
|
1990
2112
|
try {
|
|
1991
|
-
|
|
2113
|
+
logger2.info("\u{1F4E5} Loading event...");
|
|
1992
2114
|
const event = await loadJsonFromSource(options.event, {
|
|
1993
2115
|
name: "event"
|
|
1994
2116
|
});
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
);
|
|
2117
|
+
const eventResult = schemas2.PartialEventSchema.safeParse(event);
|
|
2118
|
+
if (!eventResult.success) {
|
|
2119
|
+
const errors = eventResult.error.issues.map((issue) => `${String(issue.path.join("."))}: ${issue.message}`).join(", ");
|
|
2120
|
+
throw new Error(`Invalid event: ${errors}`);
|
|
2121
|
+
}
|
|
2122
|
+
const parsedEvent = eventResult.data;
|
|
2123
|
+
if (!parsedEvent.name) {
|
|
2124
|
+
throw new Error('Invalid event: Missing required "name" property');
|
|
1999
2125
|
}
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
|
|
2126
|
+
const validatedEvent = {
|
|
2127
|
+
name: parsedEvent.name,
|
|
2128
|
+
data: parsedEvent.data || {}
|
|
2129
|
+
};
|
|
2130
|
+
if (!validatedEvent.name.includes(" ")) {
|
|
2131
|
+
logger2.warn(
|
|
2132
|
+
`Event name "${validatedEvent.name}" should follow "ENTITY ACTION" format (e.g., "page view")`
|
|
2003
2133
|
);
|
|
2004
2134
|
}
|
|
2005
|
-
|
|
2006
|
-
const configPath =
|
|
2135
|
+
logger2.info("\u{1F4E6} Loading flow configuration...");
|
|
2136
|
+
const configPath = path11.resolve(options.config);
|
|
2007
2137
|
const rawConfig = await loadJsonConfig(configPath);
|
|
2008
|
-
const { flowConfig, buildOptions,
|
|
2138
|
+
const { flowConfig, buildOptions, flowName, isMultiFlow } = loadBundleConfig(rawConfig, {
|
|
2009
2139
|
configPath: options.config,
|
|
2010
|
-
|
|
2011
|
-
logger
|
|
2140
|
+
flowName: options.flow,
|
|
2141
|
+
logger: logger2
|
|
2012
2142
|
});
|
|
2013
|
-
const platform = flowConfig
|
|
2014
|
-
|
|
2015
|
-
const
|
|
2016
|
-
|
|
2017
|
-
|
|
2143
|
+
const platform = getPlatform3(flowConfig);
|
|
2144
|
+
logger2.info("\u{1F528} Bundling flow configuration...");
|
|
2145
|
+
const configDir = path11.dirname(configPath);
|
|
2146
|
+
const tempDir = path11.join(
|
|
2147
|
+
configDir,
|
|
2148
|
+
".tmp",
|
|
2149
|
+
`push-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`
|
|
2018
2150
|
);
|
|
2019
|
-
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
|
|
2151
|
+
await fs10.ensureDir(tempDir);
|
|
2152
|
+
const tempPath = path11.join(
|
|
2153
|
+
tempDir,
|
|
2154
|
+
`bundle.${platform === "web" ? "js" : "mjs"}`
|
|
2155
|
+
);
|
|
2156
|
+
const pushBuildOptions = {
|
|
2157
|
+
...buildOptions,
|
|
2158
|
+
output: tempPath,
|
|
2159
|
+
// Web uses IIFE for browser-like execution, server uses ESM
|
|
2160
|
+
format: platform === "web" ? "iife" : "esm",
|
|
2161
|
+
platform: platform === "web" ? "browser" : "node",
|
|
2162
|
+
...platform === "web" && {
|
|
2163
|
+
windowCollector: "collector",
|
|
2164
|
+
windowElb: "elb"
|
|
2031
2165
|
}
|
|
2032
2166
|
};
|
|
2033
|
-
await
|
|
2034
|
-
|
|
2035
|
-
verbose: options.verbose,
|
|
2036
|
-
silent: !options.verbose
|
|
2037
|
-
});
|
|
2038
|
-
logger.debug(`Bundle created: ${tempPath}`);
|
|
2167
|
+
await bundleCore(flowConfig, pushBuildOptions, logger2, false);
|
|
2168
|
+
logger2.debug(`Bundle created: ${tempPath}`);
|
|
2039
2169
|
let result;
|
|
2040
2170
|
if (platform === "web") {
|
|
2041
|
-
|
|
2042
|
-
result = await executeWebPush(tempPath,
|
|
2171
|
+
logger2.info("\u{1F310} Executing in web environment (JSDOM)...");
|
|
2172
|
+
result = await executeWebPush(tempPath, validatedEvent, logger2);
|
|
2043
2173
|
} else if (platform === "server") {
|
|
2044
|
-
|
|
2045
|
-
result = await executeServerPush(tempPath,
|
|
2174
|
+
logger2.info("\u{1F5A5}\uFE0F Executing in server environment (Node.js)...");
|
|
2175
|
+
result = await executeServerPush(tempPath, validatedEvent, logger2);
|
|
2046
2176
|
} else {
|
|
2047
2177
|
throw new Error(`Unsupported platform: ${platform}`);
|
|
2048
2178
|
}
|
|
@@ -2063,27 +2193,27 @@ async function pushCommand(options) {
|
|
|
2063
2193
|
);
|
|
2064
2194
|
} else {
|
|
2065
2195
|
if (result.success) {
|
|
2066
|
-
|
|
2196
|
+
logger2.success("\u2705 Event pushed successfully");
|
|
2067
2197
|
if (result.elbResult && typeof result.elbResult === "object") {
|
|
2068
2198
|
const pushResult = result.elbResult;
|
|
2069
2199
|
if ("id" in pushResult && pushResult.id) {
|
|
2070
|
-
|
|
2200
|
+
logger2.info(` Event ID: ${pushResult.id}`);
|
|
2071
2201
|
}
|
|
2072
2202
|
if ("entity" in pushResult && pushResult.entity) {
|
|
2073
|
-
|
|
2203
|
+
logger2.info(` Entity: ${pushResult.entity}`);
|
|
2074
2204
|
}
|
|
2075
2205
|
if ("action" in pushResult && pushResult.action) {
|
|
2076
|
-
|
|
2206
|
+
logger2.info(` Action: ${pushResult.action}`);
|
|
2077
2207
|
}
|
|
2078
2208
|
}
|
|
2079
|
-
|
|
2209
|
+
logger2.info(` Duration: ${duration}ms`);
|
|
2080
2210
|
} else {
|
|
2081
|
-
|
|
2211
|
+
logger2.error(`\u274C Push failed: ${result.error}`);
|
|
2082
2212
|
process.exit(1);
|
|
2083
2213
|
}
|
|
2084
2214
|
}
|
|
2085
2215
|
try {
|
|
2086
|
-
await
|
|
2216
|
+
await fs10.remove(tempDir);
|
|
2087
2217
|
} catch {
|
|
2088
2218
|
}
|
|
2089
2219
|
} catch (error) {
|
|
@@ -2104,7 +2234,7 @@ async function pushCommand(options) {
|
|
|
2104
2234
|
)
|
|
2105
2235
|
);
|
|
2106
2236
|
} else {
|
|
2107
|
-
|
|
2237
|
+
logger2.error(`\u274C Push command failed: ${errorMessage}`);
|
|
2108
2238
|
}
|
|
2109
2239
|
process.exit(1);
|
|
2110
2240
|
}
|
|
@@ -2112,11 +2242,11 @@ async function pushCommand(options) {
|
|
|
2112
2242
|
"push",
|
|
2113
2243
|
dockerArgs,
|
|
2114
2244
|
options,
|
|
2115
|
-
|
|
2245
|
+
logger2,
|
|
2116
2246
|
options.config
|
|
2117
2247
|
);
|
|
2118
2248
|
}
|
|
2119
|
-
async function executeWebPush(bundlePath, event,
|
|
2249
|
+
async function executeWebPush(bundlePath, event, logger2) {
|
|
2120
2250
|
const startTime = Date.now();
|
|
2121
2251
|
try {
|
|
2122
2252
|
const virtualConsole = new VirtualConsole2();
|
|
@@ -2127,10 +2257,10 @@ async function executeWebPush(bundlePath, event, logger) {
|
|
|
2127
2257
|
virtualConsole
|
|
2128
2258
|
});
|
|
2129
2259
|
const { window } = dom;
|
|
2130
|
-
|
|
2131
|
-
const bundleCode = await
|
|
2260
|
+
logger2.debug("Loading bundle...");
|
|
2261
|
+
const bundleCode = await fs10.readFile(bundlePath, "utf8");
|
|
2132
2262
|
window.eval(bundleCode);
|
|
2133
|
-
|
|
2263
|
+
logger2.debug("Waiting for elb...");
|
|
2134
2264
|
await waitForWindowProperty2(
|
|
2135
2265
|
window,
|
|
2136
2266
|
"elb",
|
|
@@ -2138,9 +2268,8 @@ async function executeWebPush(bundlePath, event, logger) {
|
|
|
2138
2268
|
);
|
|
2139
2269
|
const windowObj = window;
|
|
2140
2270
|
const elb = windowObj.elb;
|
|
2141
|
-
|
|
2142
|
-
const
|
|
2143
|
-
const elbResult = await elb(event.name, eventData);
|
|
2271
|
+
logger2.info(`Pushing event: ${event.name}`);
|
|
2272
|
+
const elbResult = await elb(event.name, event.data);
|
|
2144
2273
|
return {
|
|
2145
2274
|
success: true,
|
|
2146
2275
|
elbResult,
|
|
@@ -2154,7 +2283,7 @@ async function executeWebPush(bundlePath, event, logger) {
|
|
|
2154
2283
|
};
|
|
2155
2284
|
}
|
|
2156
2285
|
}
|
|
2157
|
-
async function executeServerPush(bundlePath, event,
|
|
2286
|
+
async function executeServerPush(bundlePath, event, logger2, timeout = 6e4) {
|
|
2158
2287
|
const startTime = Date.now();
|
|
2159
2288
|
try {
|
|
2160
2289
|
const timeoutPromise = new Promise((_, reject) => {
|
|
@@ -2164,12 +2293,12 @@ async function executeServerPush(bundlePath, event, logger, timeout = 6e4) {
|
|
|
2164
2293
|
);
|
|
2165
2294
|
});
|
|
2166
2295
|
const executePromise = (async () => {
|
|
2167
|
-
|
|
2296
|
+
logger2.debug("Importing bundle...");
|
|
2168
2297
|
const flowModule = await import(bundlePath);
|
|
2169
2298
|
if (!flowModule.default || typeof flowModule.default !== "function") {
|
|
2170
2299
|
throw new Error("Bundle does not export default factory function");
|
|
2171
2300
|
}
|
|
2172
|
-
|
|
2301
|
+
logger2.debug("Calling factory function...");
|
|
2173
2302
|
const result = await flowModule.default();
|
|
2174
2303
|
if (!result || !result.elb || typeof result.elb !== "function") {
|
|
2175
2304
|
throw new Error(
|
|
@@ -2177,9 +2306,8 @@ async function executeServerPush(bundlePath, event, logger, timeout = 6e4) {
|
|
|
2177
2306
|
);
|
|
2178
2307
|
}
|
|
2179
2308
|
const { elb } = result;
|
|
2180
|
-
|
|
2181
|
-
const
|
|
2182
|
-
const elbResult = await elb(event.name, eventData);
|
|
2309
|
+
logger2.info(`Pushing event: ${event.name}`);
|
|
2310
|
+
const elbResult = await elb(event.name, event.data);
|
|
2183
2311
|
return {
|
|
2184
2312
|
success: true,
|
|
2185
2313
|
elbResult,
|
|
@@ -2216,23 +2344,40 @@ function waitForWindowProperty2(window, prop, timeout = 5e3) {
|
|
|
2216
2344
|
}
|
|
2217
2345
|
|
|
2218
2346
|
// src/commands/run/index.ts
|
|
2219
|
-
import
|
|
2347
|
+
import path13 from "path";
|
|
2348
|
+
|
|
2349
|
+
// src/commands/run/validators.ts
|
|
2350
|
+
import { existsSync as existsSync2 } from "fs";
|
|
2351
|
+
|
|
2352
|
+
// src/schemas/primitives.ts
|
|
2353
|
+
import { z } from "@walkeros/core/dev";
|
|
2354
|
+
var RunModeSchema = z.enum(["collect", "serve"]).describe("CLI run mode: collect events or serve HTTP");
|
|
2355
|
+
var PortSchema = z.number().int("Port must be an integer").min(1, "Port must be at least 1").max(65535, "Port must be at most 65535").describe("HTTP server port number");
|
|
2356
|
+
var FilePathSchema = z.string().min(1, "File path cannot be empty").describe("Path to configuration file");
|
|
2357
|
+
|
|
2358
|
+
// src/schemas/run.ts
|
|
2359
|
+
import { z as z2 } from "@walkeros/core/dev";
|
|
2360
|
+
var RunOptionsSchema = z2.object({
|
|
2361
|
+
mode: RunModeSchema,
|
|
2362
|
+
flow: FilePathSchema,
|
|
2363
|
+
port: PortSchema.default(8080),
|
|
2364
|
+
flowName: z2.string().optional().describe("Specific flow name to run")
|
|
2365
|
+
});
|
|
2220
2366
|
|
|
2221
2367
|
// src/commands/run/validators.ts
|
|
2222
|
-
import { existsSync } from "fs";
|
|
2223
|
-
var VALID_MODES = ["collect", "serve"];
|
|
2224
2368
|
function validateMode(mode) {
|
|
2225
|
-
|
|
2369
|
+
const result = RunModeSchema.safeParse(mode);
|
|
2370
|
+
if (!result.success) {
|
|
2226
2371
|
throw new Error(
|
|
2227
2372
|
`Invalid mode: "${mode}"
|
|
2228
|
-
Valid modes:
|
|
2373
|
+
Valid modes: collect, serve
|
|
2229
2374
|
Example: walkeros run collect ./flow.json`
|
|
2230
2375
|
);
|
|
2231
2376
|
}
|
|
2232
2377
|
}
|
|
2233
2378
|
function validateFlowFile(filePath) {
|
|
2234
2379
|
const absolutePath = resolveAsset(filePath, "bundle");
|
|
2235
|
-
if (!
|
|
2380
|
+
if (!existsSync2(absolutePath)) {
|
|
2236
2381
|
throw new Error(
|
|
2237
2382
|
`Flow file not found: ${filePath}
|
|
2238
2383
|
Resolved path: ${absolutePath}
|
|
@@ -2242,7 +2387,8 @@ function validateFlowFile(filePath) {
|
|
|
2242
2387
|
return absolutePath;
|
|
2243
2388
|
}
|
|
2244
2389
|
function validatePort(port) {
|
|
2245
|
-
|
|
2390
|
+
const result = PortSchema.safeParse(port);
|
|
2391
|
+
if (!result.success) {
|
|
2246
2392
|
throw new Error(
|
|
2247
2393
|
`Invalid port: ${port}
|
|
2248
2394
|
Port must be an integer between 1 and 65535
|
|
@@ -2252,26 +2398,26 @@ function validatePort(port) {
|
|
|
2252
2398
|
}
|
|
2253
2399
|
|
|
2254
2400
|
// src/commands/run/utils.ts
|
|
2255
|
-
import
|
|
2256
|
-
import
|
|
2401
|
+
import path12 from "path";
|
|
2402
|
+
import fs11 from "fs-extra";
|
|
2257
2403
|
async function prepareBundleForRun(configPath, options) {
|
|
2258
|
-
const
|
|
2259
|
-
const
|
|
2260
|
-
|
|
2261
|
-
|
|
2404
|
+
const configDir = path12.dirname(path12.resolve(configPath));
|
|
2405
|
+
const tempDir = path12.join(
|
|
2406
|
+
configDir,
|
|
2407
|
+
".tmp",
|
|
2408
|
+
`run-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`
|
|
2262
2409
|
);
|
|
2263
|
-
|
|
2264
|
-
const
|
|
2265
|
-
|
|
2266
|
-
build: {
|
|
2267
|
-
...existingBuild,
|
|
2268
|
-
output: tempPath
|
|
2269
|
-
}
|
|
2270
|
-
};
|
|
2271
|
-
await bundle(configWithOutput, {
|
|
2410
|
+
await fs11.ensureDir(tempDir);
|
|
2411
|
+
const tempPath = path12.join(tempDir, "bundle.mjs");
|
|
2412
|
+
await bundle(configPath, {
|
|
2272
2413
|
cache: true,
|
|
2273
2414
|
verbose: options.verbose,
|
|
2274
|
-
silent: options.silent
|
|
2415
|
+
silent: options.silent,
|
|
2416
|
+
buildOverrides: {
|
|
2417
|
+
output: tempPath,
|
|
2418
|
+
format: "esm",
|
|
2419
|
+
platform: "node"
|
|
2420
|
+
}
|
|
2275
2421
|
});
|
|
2276
2422
|
return tempPath;
|
|
2277
2423
|
}
|
|
@@ -2280,7 +2426,10 @@ function isPreBuiltConfig(configPath) {
|
|
|
2280
2426
|
}
|
|
2281
2427
|
|
|
2282
2428
|
// src/commands/run/execution.ts
|
|
2429
|
+
import { createLogger as createLogger2, Level } from "@walkeros/core";
|
|
2283
2430
|
import { runFlow, runServeMode } from "@walkeros/docker";
|
|
2431
|
+
var logLevel = process.env.VERBOSE === "true" ? Level.DEBUG : Level.INFO;
|
|
2432
|
+
var logger = createLogger2({ level: logLevel });
|
|
2284
2433
|
async function executeRunLocal(mode, flowPath, options) {
|
|
2285
2434
|
switch (mode) {
|
|
2286
2435
|
case "collect": {
|
|
@@ -2291,7 +2440,7 @@ async function executeRunLocal(mode, flowPath, options) {
|
|
|
2291
2440
|
port: options.port,
|
|
2292
2441
|
host: options.host
|
|
2293
2442
|
};
|
|
2294
|
-
await runFlow(flowPath, config);
|
|
2443
|
+
await runFlow(flowPath, config, logger.scope("runner"));
|
|
2295
2444
|
break;
|
|
2296
2445
|
}
|
|
2297
2446
|
case "serve": {
|
|
@@ -2302,7 +2451,7 @@ async function executeRunLocal(mode, flowPath, options) {
|
|
|
2302
2451
|
servePath: options.servePath,
|
|
2303
2452
|
filePath: flowPath || void 0
|
|
2304
2453
|
};
|
|
2305
|
-
await runServeMode(config);
|
|
2454
|
+
await runServeMode(config, logger.scope("serve"));
|
|
2306
2455
|
break;
|
|
2307
2456
|
}
|
|
2308
2457
|
default:
|
|
@@ -2314,7 +2463,7 @@ async function executeRunLocal(mode, flowPath, options) {
|
|
|
2314
2463
|
async function runCommand(mode, options) {
|
|
2315
2464
|
const timer = createTimer();
|
|
2316
2465
|
timer.start();
|
|
2317
|
-
const
|
|
2466
|
+
const logger2 = createCommandLogger(options);
|
|
2318
2467
|
try {
|
|
2319
2468
|
validateMode(mode);
|
|
2320
2469
|
const configPath = validateFlowFile(options.config);
|
|
@@ -2325,31 +2474,31 @@ async function runCommand(mode, options) {
|
|
|
2325
2474
|
let flowPath = null;
|
|
2326
2475
|
if (mode === "collect") {
|
|
2327
2476
|
if (isPreBuilt) {
|
|
2328
|
-
flowPath =
|
|
2477
|
+
flowPath = path13.resolve(configPath);
|
|
2329
2478
|
if (!options.json && !options.silent) {
|
|
2330
|
-
|
|
2479
|
+
logger2.info(`\u{1F4E6} Using pre-built flow: ${path13.basename(flowPath)}`);
|
|
2331
2480
|
}
|
|
2332
2481
|
} else {
|
|
2333
2482
|
if (!options.json && !options.silent) {
|
|
2334
|
-
|
|
2483
|
+
logger2.info("\u{1F528} Building flow bundle...");
|
|
2335
2484
|
}
|
|
2336
2485
|
flowPath = await prepareBundleForRun(configPath, {
|
|
2337
2486
|
verbose: options.verbose,
|
|
2338
2487
|
silent: options.json || options.silent
|
|
2339
2488
|
});
|
|
2340
2489
|
if (!options.json && !options.silent) {
|
|
2341
|
-
|
|
2490
|
+
logger2.success("\u2705 Bundle ready");
|
|
2342
2491
|
}
|
|
2343
2492
|
}
|
|
2344
2493
|
}
|
|
2345
2494
|
const executionMode = getExecutionMode(options);
|
|
2346
2495
|
if (options.dryRun) {
|
|
2347
2496
|
if (executionMode === "docker") {
|
|
2348
|
-
|
|
2497
|
+
logger2.info(
|
|
2349
2498
|
`[DRY-RUN] Would execute in Docker: run ${mode} with runtime image`
|
|
2350
2499
|
);
|
|
2351
2500
|
} else {
|
|
2352
|
-
|
|
2501
|
+
logger2.info(`[DRY-RUN] Would execute locally: run ${mode}`);
|
|
2353
2502
|
}
|
|
2354
2503
|
return;
|
|
2355
2504
|
}
|
|
@@ -2361,7 +2510,7 @@ async function runCommand(mode, options) {
|
|
|
2361
2510
|
);
|
|
2362
2511
|
}
|
|
2363
2512
|
if (!options.json && !options.silent) {
|
|
2364
|
-
|
|
2513
|
+
logger2.info("\u{1F433} Executing in production runtime container...");
|
|
2365
2514
|
}
|
|
2366
2515
|
await executeRunInDocker(mode, flowPath, {
|
|
2367
2516
|
port: options.port,
|
|
@@ -2373,7 +2522,7 @@ async function runCommand(mode, options) {
|
|
|
2373
2522
|
} else {
|
|
2374
2523
|
if (!options.json && !options.silent) {
|
|
2375
2524
|
const modeLabel = mode === "collect" ? "Collector" : "Server";
|
|
2376
|
-
|
|
2525
|
+
logger2.info(`\u{1F5A5}\uFE0F Starting ${modeLabel} locally...`);
|
|
2377
2526
|
}
|
|
2378
2527
|
await executeRunLocal(mode, flowPath, {
|
|
2379
2528
|
port: options.port,
|
|
@@ -2394,8 +2543,8 @@ async function runCommand(mode, options) {
|
|
|
2394
2543
|
};
|
|
2395
2544
|
console.log(JSON.stringify(output, null, 2));
|
|
2396
2545
|
} else {
|
|
2397
|
-
|
|
2398
|
-
|
|
2546
|
+
logger2.error("\u274C Run failed:");
|
|
2547
|
+
logger2.error(errorMessage);
|
|
2399
2548
|
}
|
|
2400
2549
|
process.exit(1);
|
|
2401
2550
|
}
|
|
@@ -2416,7 +2565,7 @@ async function run(mode, options) {
|
|
|
2416
2565
|
const isPreBuilt = isPreBuiltConfig(flowFile);
|
|
2417
2566
|
let flowPath;
|
|
2418
2567
|
if (isPreBuilt) {
|
|
2419
|
-
flowPath =
|
|
2568
|
+
flowPath = path13.resolve(flowFile);
|
|
2420
2569
|
} else {
|
|
2421
2570
|
flowPath = await prepareBundleForRun(flowFile, {
|
|
2422
2571
|
verbose: options.verbose,
|
|
@@ -2444,22 +2593,60 @@ async function run(mode, options) {
|
|
|
2444
2593
|
}
|
|
2445
2594
|
}
|
|
2446
2595
|
|
|
2596
|
+
// src/commands/cache.ts
|
|
2597
|
+
import fs12 from "fs-extra";
|
|
2598
|
+
import path14 from "path";
|
|
2599
|
+
var CACHE_DIR = path14.join(".tmp", "cache");
|
|
2600
|
+
function registerCacheCommand(program2) {
|
|
2601
|
+
const cache = program2.command("cache").description("Manage the CLI cache");
|
|
2602
|
+
cache.command("clear").description("Clear all cached packages and builds").option("--packages", "Clear only package cache").option("--builds", "Clear only build cache").action(async (options) => {
|
|
2603
|
+
if (options.packages) {
|
|
2604
|
+
await fs12.remove(path14.join(CACHE_DIR, "packages"));
|
|
2605
|
+
console.log("Package cache cleared");
|
|
2606
|
+
} else if (options.builds) {
|
|
2607
|
+
await fs12.remove(path14.join(CACHE_DIR, "builds"));
|
|
2608
|
+
console.log("Build cache cleared");
|
|
2609
|
+
} else {
|
|
2610
|
+
await fs12.remove(CACHE_DIR);
|
|
2611
|
+
console.log("All caches cleared");
|
|
2612
|
+
}
|
|
2613
|
+
});
|
|
2614
|
+
cache.command("info").description("Show cache statistics").action(async () => {
|
|
2615
|
+
const packagesDir = path14.join(CACHE_DIR, "packages");
|
|
2616
|
+
const buildsDir = path14.join(CACHE_DIR, "builds");
|
|
2617
|
+
const packageCount = await countEntries(packagesDir);
|
|
2618
|
+
const buildCount = await countEntries(buildsDir);
|
|
2619
|
+
console.log(`Cache directory: ${CACHE_DIR}`);
|
|
2620
|
+
console.log(`Cached packages: ${packageCount}`);
|
|
2621
|
+
console.log(`Cached builds: ${buildCount}`);
|
|
2622
|
+
});
|
|
2623
|
+
}
|
|
2624
|
+
async function countEntries(dir) {
|
|
2625
|
+
if (!await fs12.pathExists(dir)) return 0;
|
|
2626
|
+
const entries = await fs12.readdir(dir);
|
|
2627
|
+
return entries.length;
|
|
2628
|
+
}
|
|
2629
|
+
|
|
2447
2630
|
// src/index.ts
|
|
2448
|
-
var __filename =
|
|
2631
|
+
var __filename = fileURLToPath2(import.meta.url);
|
|
2449
2632
|
var __dirname = dirname(__filename);
|
|
2450
2633
|
var packageJson = JSON.parse(
|
|
2451
|
-
|
|
2634
|
+
readFileSync(join(__dirname, "../package.json"), "utf-8")
|
|
2452
2635
|
);
|
|
2453
2636
|
var VERSION = packageJson.version;
|
|
2454
2637
|
var program = new Command();
|
|
2455
2638
|
program.name("walkeros").description("walkerOS CLI - Bundle and deploy walkerOS components").version(VERSION);
|
|
2456
|
-
program.
|
|
2457
|
-
|
|
2458
|
-
|
|
2459
|
-
|
|
2639
|
+
program.hook("preAction", (thisCommand, actionCommand) => {
|
|
2640
|
+
const options = actionCommand.opts();
|
|
2641
|
+
if (!options.silent && !options.json) {
|
|
2642
|
+
console.log(`\u{1F680} walkerOS CLI v${VERSION}`);
|
|
2643
|
+
console.log(`\u{1F433} Using Docker runtime: walkeros/docker:${DOCKER_VERSION2}`);
|
|
2644
|
+
}
|
|
2645
|
+
});
|
|
2646
|
+
program.command("bundle [file]").description("Bundle NPM packages with custom code").option("-f, --flow <name>", "flow to build (for multi-flow configs)").option("--all", "build all flows (for multi-flow configs)").option("-s, --stats", "show bundle statistics").option("--json", "output statistics in JSON format (implies --stats)").option("--no-cache", "disable package caching and download fresh packages").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) => {
|
|
2460
2647
|
await bundleCommand({
|
|
2461
2648
|
config: file || "bundle.config.json",
|
|
2462
|
-
|
|
2649
|
+
flow: options.flow,
|
|
2463
2650
|
all: options.all,
|
|
2464
2651
|
stats: options.stats,
|
|
2465
2652
|
json: options.json,
|
|
@@ -2487,11 +2674,11 @@ program.command("simulate [file]").description("Simulate event processing and ca
|
|
|
2487
2674
|
program.command("push [file]").description("Push an event through the flow with real API execution").requiredOption(
|
|
2488
2675
|
"-e, --event <source>",
|
|
2489
2676
|
"Event to push (JSON string, file path, or URL)"
|
|
2490
|
-
).option("--
|
|
2677
|
+
).option("--flow <name>", "Flow name (for multi-flow 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
2678
|
await pushCommand({
|
|
2492
2679
|
config: file || "bundle.config.json",
|
|
2493
2680
|
event: options.event,
|
|
2494
|
-
|
|
2681
|
+
flow: options.flow,
|
|
2495
2682
|
json: options.json,
|
|
2496
2683
|
verbose: options.verbose,
|
|
2497
2684
|
silent: options.silent,
|
|
@@ -2529,6 +2716,7 @@ runCmd.command("serve [file]").description(
|
|
|
2529
2716
|
silent: options.silent
|
|
2530
2717
|
});
|
|
2531
2718
|
});
|
|
2719
|
+
registerCacheCommand(program);
|
|
2532
2720
|
program.parse();
|
|
2533
2721
|
export {
|
|
2534
2722
|
bundle,
|