@walkeros/cli 0.4.1 → 0.4.2
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 +13 -0
- package/README.md +112 -42
- package/dist/__tests__/bundle/bundler.test.js +174 -164
- package/dist/__tests__/bundle/bundler.test.js.map +1 -1
- package/dist/__tests__/bundle/programmatic.test.js +76 -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 +231 -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 +59 -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.map +1 -1
- package/dist/commands/bundle/bundler.js +93 -3
- 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/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 +72 -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 +8 -15
- package/dist/core/asset-resolver.d.ts.map +1 -1
- package/dist/core/asset-resolver.js +30 -37
- 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 +8 -25
- 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 +343 -0
- package/dist/examples/event.json +53 -0
- package/dist/examples/flow-order-complete.json +68 -0
- package/dist/examples/flow-simple.json +32 -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 +84 -201
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +675 -422
- 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/templates/server.hbs +29 -0
- package/dist/templates/web.hbs +45 -0
- package/dist/types/bundle.d.ts +68 -190
- 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 +42 -29
- package/examples/flow-order-complete.json +57 -57
- package/examples/flow-simple.json +25 -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 -2
- 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/index.js
CHANGED
|
@@ -2,10 +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
8
|
|
|
9
|
+
// src/commands/bundle/index.ts
|
|
10
|
+
import path9 from "path";
|
|
11
|
+
|
|
9
12
|
// src/core/logger.ts
|
|
10
13
|
import chalk from "chalk";
|
|
11
14
|
function createLogger(options = {}) {
|
|
@@ -131,8 +134,6 @@ function formatBytes(bytes) {
|
|
|
131
134
|
// src/core/docker.ts
|
|
132
135
|
import { spawn } from "child_process";
|
|
133
136
|
import path2 from "path";
|
|
134
|
-
import { readFileSync } from "fs";
|
|
135
|
-
import { fileURLToPath } from "url";
|
|
136
137
|
import { VERSION as DOCKER_VERSION } from "@walkeros/docker";
|
|
137
138
|
|
|
138
139
|
// src/config/utils.ts
|
|
@@ -262,20 +263,7 @@ async function loadJsonFromSource(source, options) {
|
|
|
262
263
|
}
|
|
263
264
|
|
|
264
265
|
// 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();
|
|
266
|
+
var CLI_VERSION = true ? "0.4.2" : "0.0.0";
|
|
279
267
|
var CLI_DOCKER_IMAGE = process.env.WALKEROS_CLI_DOCKER_IMAGE || `walkeros/cli:${CLI_VERSION}`;
|
|
280
268
|
var RUNTIME_DOCKER_IMAGE = process.env.WALKEROS_RUNTIME_DOCKER_IMAGE || `walkeros/docker:${DOCKER_VERSION}`;
|
|
281
269
|
function buildCommonDockerArgs(options) {
|
|
@@ -355,8 +343,10 @@ function buildDockerRunCommand(mode, flowPath, options = {}) {
|
|
|
355
343
|
cmd.push("-e", `MODE=${mode}`);
|
|
356
344
|
if (mode === "collect" && flowPath) {
|
|
357
345
|
const absoluteFlowPath = path2.resolve(cwd, flowPath);
|
|
358
|
-
|
|
359
|
-
|
|
346
|
+
const flowDir = path2.dirname(absoluteFlowPath);
|
|
347
|
+
const flowFile = path2.basename(absoluteFlowPath);
|
|
348
|
+
cmd.push("-v", `${flowDir}:/app/dist:ro`);
|
|
349
|
+
cmd.push("-e", `FLOW=/app/dist/${flowFile}`);
|
|
360
350
|
}
|
|
361
351
|
if (mode === "serve" && flowPath) {
|
|
362
352
|
const absoluteFilePath = path2.resolve(cwd, flowPath);
|
|
@@ -452,33 +442,36 @@ import { getHashServer } from "@walkeros/server-core";
|
|
|
452
442
|
import fs2 from "fs-extra";
|
|
453
443
|
|
|
454
444
|
// src/core/asset-resolver.ts
|
|
455
|
-
import { fileURLToPath
|
|
445
|
+
import { fileURLToPath } from "url";
|
|
446
|
+
import { existsSync } from "fs";
|
|
456
447
|
import path3 from "path";
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
if (
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
448
|
+
var cachedAssetDir;
|
|
449
|
+
function getAssetDir() {
|
|
450
|
+
if (cachedAssetDir) return cachedAssetDir;
|
|
451
|
+
const currentFile = fileURLToPath(import.meta.url);
|
|
452
|
+
let dir = path3.dirname(currentFile);
|
|
453
|
+
while (dir !== path3.dirname(dir)) {
|
|
454
|
+
if (existsSync(path3.join(dir, "templates"))) {
|
|
455
|
+
cachedAssetDir = dir;
|
|
456
|
+
return dir;
|
|
457
|
+
}
|
|
458
|
+
dir = path3.dirname(dir);
|
|
466
459
|
}
|
|
467
|
-
|
|
460
|
+
cachedAssetDir = path3.dirname(currentFile);
|
|
461
|
+
return cachedAssetDir;
|
|
468
462
|
}
|
|
469
463
|
function resolveAsset(assetPath, assetType, baseDir) {
|
|
470
|
-
const packageRoot = getPackageRoot();
|
|
471
464
|
if (!assetPath.includes("/") && !assetPath.includes("\\")) {
|
|
465
|
+
const assetDir = getAssetDir();
|
|
472
466
|
if (assetType === "template") {
|
|
473
|
-
return path3.join(
|
|
467
|
+
return path3.join(assetDir, "templates", assetPath);
|
|
474
468
|
}
|
|
475
|
-
return path3.join(
|
|
469
|
+
return path3.join(assetDir, "examples", assetPath);
|
|
476
470
|
}
|
|
477
471
|
if (path3.isAbsolute(assetPath)) {
|
|
478
472
|
return assetPath;
|
|
479
473
|
}
|
|
480
|
-
|
|
481
|
-
return path3.resolve(resolveBase, assetPath);
|
|
474
|
+
return path3.resolve(baseDir || process.cwd(), assetPath);
|
|
482
475
|
}
|
|
483
476
|
|
|
484
477
|
// src/core/utils.ts
|
|
@@ -486,273 +479,257 @@ function getErrorMessage(error) {
|
|
|
486
479
|
return error instanceof Error ? error.message : String(error);
|
|
487
480
|
}
|
|
488
481
|
|
|
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
|
|
482
|
+
// src/core/local-packages.ts
|
|
504
483
|
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)) {
|
|
484
|
+
import fs3 from "fs-extra";
|
|
485
|
+
async function resolveLocalPackage(packageName, localPath, configDir, logger) {
|
|
486
|
+
const absolutePath = path4.isAbsolute(localPath) ? localPath : path4.resolve(configDir, localPath);
|
|
487
|
+
if (!await fs3.pathExists(absolutePath)) {
|
|
557
488
|
throw new Error(
|
|
558
|
-
`
|
|
489
|
+
`Local package path not found: ${localPath} (resolved to ${absolutePath})`
|
|
559
490
|
);
|
|
560
491
|
}
|
|
561
|
-
const
|
|
562
|
-
if (!
|
|
492
|
+
const pkgJsonPath = path4.join(absolutePath, "package.json");
|
|
493
|
+
if (!await fs3.pathExists(pkgJsonPath)) {
|
|
563
494
|
throw new Error(
|
|
564
|
-
`
|
|
495
|
+
`No package.json found at ${absolutePath}. Is this a valid package directory?`
|
|
565
496
|
);
|
|
566
497
|
}
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
498
|
+
const distPath = path4.join(absolutePath, "dist");
|
|
499
|
+
const hasDistFolder = await fs3.pathExists(distPath);
|
|
500
|
+
if (!hasDistFolder) {
|
|
501
|
+
logger.warn(
|
|
502
|
+
`\u26A0\uFE0F ${packageName}: No dist/ folder found. Using package root.`
|
|
570
503
|
);
|
|
571
504
|
}
|
|
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
505
|
return {
|
|
622
|
-
|
|
623
|
-
|
|
506
|
+
name: packageName,
|
|
507
|
+
absolutePath,
|
|
508
|
+
distPath: hasDistFolder ? distPath : absolutePath,
|
|
509
|
+
hasDistFolder
|
|
624
510
|
};
|
|
625
511
|
}
|
|
626
|
-
function
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
512
|
+
async function copyLocalPackage(localPkg, targetDir, logger) {
|
|
513
|
+
const packageDir = path4.join(targetDir, "node_modules", localPkg.name);
|
|
514
|
+
await fs3.ensureDir(path4.dirname(packageDir));
|
|
515
|
+
await fs3.copy(
|
|
516
|
+
path4.join(localPkg.absolutePath, "package.json"),
|
|
517
|
+
path4.join(packageDir, "package.json")
|
|
518
|
+
);
|
|
519
|
+
if (localPkg.hasDistFolder) {
|
|
520
|
+
await fs3.copy(localPkg.distPath, path4.join(packageDir, "dist"));
|
|
521
|
+
} else {
|
|
522
|
+
const entries = await fs3.readdir(localPkg.absolutePath);
|
|
523
|
+
for (const entry of entries) {
|
|
524
|
+
if (!["node_modules", ".turbo", ".git"].includes(entry)) {
|
|
525
|
+
await fs3.copy(
|
|
526
|
+
path4.join(localPkg.absolutePath, entry),
|
|
527
|
+
path4.join(packageDir, entry)
|
|
528
|
+
);
|
|
529
|
+
}
|
|
530
|
+
}
|
|
639
531
|
}
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
532
|
+
logger.info(`\u{1F4E6} Using local: ${localPkg.name} from ${localPkg.absolutePath}`);
|
|
533
|
+
return packageDir;
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
// src/config/validators.ts
|
|
537
|
+
import { schemas } from "@walkeros/core/dev";
|
|
538
|
+
var { safeParseSetup } = schemas;
|
|
539
|
+
function isObject(value) {
|
|
540
|
+
return typeof value === "object" && value !== null && !Array.isArray(value) && Object.prototype.toString.call(value) === "[object Object]";
|
|
541
|
+
}
|
|
542
|
+
function validateFlowSetup(data) {
|
|
543
|
+
const result = safeParseSetup(data);
|
|
544
|
+
if (!result.success) {
|
|
545
|
+
const errors = result.error.issues.map((issue) => {
|
|
546
|
+
const path15 = issue.path.length > 0 ? issue.path.map(String).join(".") : "root";
|
|
547
|
+
return ` - ${path15}: ${issue.message}`;
|
|
548
|
+
}).join("\n");
|
|
549
|
+
throw new Error(`Invalid configuration:
|
|
550
|
+
${errors}`);
|
|
645
551
|
}
|
|
646
|
-
return
|
|
552
|
+
return result.data;
|
|
553
|
+
}
|
|
554
|
+
function getAvailableFlows(setup) {
|
|
555
|
+
return Object.keys(setup.flows);
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
// src/config/build-defaults.ts
|
|
559
|
+
var WEB_BUILD_DEFAULTS = {
|
|
560
|
+
format: "iife",
|
|
561
|
+
platform: "browser",
|
|
562
|
+
target: "es2020",
|
|
563
|
+
template: "web.hbs",
|
|
564
|
+
minify: true,
|
|
565
|
+
sourcemap: false,
|
|
566
|
+
cache: true,
|
|
567
|
+
tempDir: ".tmp",
|
|
568
|
+
windowCollector: "collector",
|
|
569
|
+
windowElb: "elb"
|
|
570
|
+
};
|
|
571
|
+
var SERVER_BUILD_DEFAULTS = {
|
|
572
|
+
format: "esm",
|
|
573
|
+
platform: "node",
|
|
574
|
+
target: "node20",
|
|
575
|
+
template: "server.hbs",
|
|
576
|
+
minify: true,
|
|
577
|
+
sourcemap: false,
|
|
578
|
+
cache: true,
|
|
579
|
+
tempDir: ".tmp"
|
|
580
|
+
};
|
|
581
|
+
var DEFAULT_OUTPUT_PATHS = {
|
|
582
|
+
web: "./dist/walker.js",
|
|
583
|
+
server: "./dist/bundle.mjs"
|
|
584
|
+
};
|
|
585
|
+
function getBuildDefaults(platform) {
|
|
586
|
+
return platform === "web" ? WEB_BUILD_DEFAULTS : SERVER_BUILD_DEFAULTS;
|
|
647
587
|
}
|
|
648
|
-
function
|
|
649
|
-
return
|
|
588
|
+
function getDefaultOutput(platform) {
|
|
589
|
+
return DEFAULT_OUTPUT_PATHS[platform];
|
|
650
590
|
}
|
|
651
591
|
|
|
652
592
|
// src/config/loader.ts
|
|
593
|
+
import path5 from "path";
|
|
594
|
+
import fs4 from "fs-extra";
|
|
595
|
+
import { getFlowConfig, getPlatform } from "@walkeros/core";
|
|
596
|
+
var DEFAULT_INCLUDE_FOLDER = "./shared";
|
|
653
597
|
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) {
|
|
598
|
+
const setup = validateFlowSetup(rawConfig);
|
|
599
|
+
const availableFlows = getAvailableFlows(setup);
|
|
600
|
+
const flowName = resolveFlow(setup, options.flowName, availableFlows);
|
|
601
|
+
const flowConfig = getFlowConfig(setup, flowName);
|
|
602
|
+
const platform = getPlatform(flowConfig);
|
|
603
|
+
if (!platform) {
|
|
684
604
|
throw new Error(
|
|
685
|
-
`
|
|
686
|
-
Available environments: ${availableEnvironments.join(", ")}`
|
|
605
|
+
`Invalid configuration: flow "${flowName}" must have a "web" or "server" key.`
|
|
687
606
|
);
|
|
688
607
|
}
|
|
689
|
-
const
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
)
|
|
701
|
-
|
|
608
|
+
const buildDefaults = getBuildDefaults(platform);
|
|
609
|
+
const packages = flowConfig.packages || {};
|
|
610
|
+
let output = getDefaultOutput(platform);
|
|
611
|
+
if (options.buildOverrides?.output) {
|
|
612
|
+
output = options.buildOverrides.output;
|
|
613
|
+
}
|
|
614
|
+
const configDir = path5.dirname(options.configPath);
|
|
615
|
+
if (!path5.isAbsolute(output)) {
|
|
616
|
+
output = path5.resolve(configDir, output);
|
|
617
|
+
}
|
|
618
|
+
let includes = setup.include;
|
|
619
|
+
if (!includes) {
|
|
620
|
+
const defaultIncludePath = path5.resolve(configDir, DEFAULT_INCLUDE_FOLDER);
|
|
621
|
+
if (fs4.pathExistsSync(defaultIncludePath)) {
|
|
622
|
+
includes = [DEFAULT_INCLUDE_FOLDER];
|
|
623
|
+
}
|
|
624
|
+
}
|
|
625
|
+
const buildOptions = {
|
|
626
|
+
...buildDefaults,
|
|
627
|
+
packages,
|
|
628
|
+
output,
|
|
629
|
+
include: includes,
|
|
630
|
+
configDir,
|
|
631
|
+
...options.buildOverrides
|
|
632
|
+
};
|
|
633
|
+
const isMultiFlow = availableFlows.length > 1;
|
|
634
|
+
if (isMultiFlow && options.logger) {
|
|
702
635
|
options.logger.info(
|
|
703
|
-
`\u{1F4E6} Using
|
|
636
|
+
`\u{1F4E6} Using flow: ${flowName} (${availableFlows.length} total)`
|
|
704
637
|
);
|
|
705
638
|
}
|
|
706
639
|
return {
|
|
707
640
|
flowConfig,
|
|
708
641
|
buildOptions,
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
642
|
+
flowName,
|
|
643
|
+
isMultiFlow,
|
|
644
|
+
availableFlows
|
|
712
645
|
};
|
|
713
646
|
}
|
|
714
|
-
function
|
|
715
|
-
if (
|
|
647
|
+
function resolveFlow(setup, requestedFlow, available) {
|
|
648
|
+
if (available.length === 1) {
|
|
649
|
+
return available[0];
|
|
650
|
+
}
|
|
651
|
+
if (!requestedFlow) {
|
|
652
|
+
throw new Error(
|
|
653
|
+
`Multiple flows found. Please specify a flow using --flow flag.
|
|
654
|
+
Available flows: ${available.join(", ")}`
|
|
655
|
+
);
|
|
656
|
+
}
|
|
657
|
+
if (!available.includes(requestedFlow)) {
|
|
716
658
|
throw new Error(
|
|
717
|
-
|
|
718
|
-
|
|
659
|
+
`Flow "${requestedFlow}" not found in configuration.
|
|
660
|
+
Available flows: ${available.join(", ")}`
|
|
719
661
|
);
|
|
720
662
|
}
|
|
721
|
-
|
|
722
|
-
|
|
663
|
+
return requestedFlow;
|
|
664
|
+
}
|
|
665
|
+
function loadAllFlows(rawConfig, options) {
|
|
666
|
+
const setup = validateFlowSetup(rawConfig);
|
|
667
|
+
const flows = getAvailableFlows(setup);
|
|
723
668
|
if (options.logger) {
|
|
724
669
|
options.logger.info(
|
|
725
|
-
`\u{1F4E6} Loading all ${
|
|
670
|
+
`\u{1F4E6} Loading all ${flows.length} flows: ${flows.join(", ")}`
|
|
726
671
|
);
|
|
727
672
|
}
|
|
728
|
-
return
|
|
729
|
-
(
|
|
673
|
+
return flows.map(
|
|
674
|
+
(name) => loadBundleConfig(rawConfig, {
|
|
730
675
|
...options,
|
|
731
|
-
|
|
676
|
+
flowName: name
|
|
732
677
|
})
|
|
733
678
|
);
|
|
734
679
|
}
|
|
735
680
|
|
|
736
681
|
// src/commands/bundle/bundler.ts
|
|
737
682
|
import esbuild from "esbuild";
|
|
683
|
+
import path8 from "path";
|
|
684
|
+
import fs8 from "fs-extra";
|
|
685
|
+
|
|
686
|
+
// src/commands/bundle/package-manager.ts
|
|
687
|
+
import pacote from "pacote";
|
|
738
688
|
import path6 from "path";
|
|
739
689
|
import fs5 from "fs-extra";
|
|
740
690
|
|
|
691
|
+
// src/core/cache-utils.ts
|
|
692
|
+
import { getHashServer as getHashServer2 } from "@walkeros/server-core";
|
|
693
|
+
var HASH_LENGTH = 12;
|
|
694
|
+
function isMutableVersion(version) {
|
|
695
|
+
return version === "latest" || version.includes("^") || version.includes("~") || version.includes("*") || version.includes("x");
|
|
696
|
+
}
|
|
697
|
+
function getTodayDate() {
|
|
698
|
+
return (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
699
|
+
}
|
|
700
|
+
async function getPackageCacheKey(packageName, version, date) {
|
|
701
|
+
const safeName = packageName.replace(/\//g, "-").replace(/@/g, "");
|
|
702
|
+
if (isMutableVersion(version)) {
|
|
703
|
+
const dateStr = date ?? getTodayDate();
|
|
704
|
+
const input2 = `${safeName}@${version}:${dateStr}`;
|
|
705
|
+
return getHashServer2(input2, HASH_LENGTH);
|
|
706
|
+
}
|
|
707
|
+
const input = `${safeName}@${version}`;
|
|
708
|
+
return getHashServer2(input, HASH_LENGTH);
|
|
709
|
+
}
|
|
710
|
+
function normalizeJson(content) {
|
|
711
|
+
const parsed = JSON.parse(content);
|
|
712
|
+
return JSON.stringify(parsed);
|
|
713
|
+
}
|
|
714
|
+
async function getFlowConfigCacheKey(content, date) {
|
|
715
|
+
const dateStr = date ?? getTodayDate();
|
|
716
|
+
const normalized = normalizeJson(content);
|
|
717
|
+
const input = `${normalized}:${dateStr}`;
|
|
718
|
+
return getHashServer2(input, HASH_LENGTH);
|
|
719
|
+
}
|
|
720
|
+
|
|
741
721
|
// src/commands/bundle/package-manager.ts
|
|
742
|
-
import pacote from "pacote";
|
|
743
|
-
import path5 from "path";
|
|
744
|
-
import fs3 from "fs-extra";
|
|
745
722
|
function getPackageDirectory(baseDir, packageName, version) {
|
|
746
|
-
return
|
|
723
|
+
return path6.join(baseDir, "node_modules", packageName);
|
|
747
724
|
}
|
|
748
|
-
function getCachedPackagePath(pkg, tempDir) {
|
|
749
|
-
const cacheDir =
|
|
750
|
-
const
|
|
751
|
-
return
|
|
725
|
+
async function getCachedPackagePath(pkg, tempDir) {
|
|
726
|
+
const cacheDir = path6.join(".tmp", "cache", "packages");
|
|
727
|
+
const cacheKey = await getPackageCacheKey(pkg.name, pkg.version);
|
|
728
|
+
return path6.join(cacheDir, cacheKey);
|
|
752
729
|
}
|
|
753
730
|
async function isPackageCached(pkg, tempDir) {
|
|
754
|
-
const cachedPath = getCachedPackagePath(pkg, tempDir);
|
|
755
|
-
return
|
|
731
|
+
const cachedPath = await getCachedPackagePath(pkg, tempDir);
|
|
732
|
+
return fs5.pathExists(cachedPath);
|
|
756
733
|
}
|
|
757
734
|
function validateNoDuplicatePackages(packages) {
|
|
758
735
|
const packageMap = /* @__PURE__ */ new Map();
|
|
@@ -786,9 +763,9 @@ async function resolveDependencies(pkg, packageDir, logger, visited = /* @__PURE
|
|
|
786
763
|
}
|
|
787
764
|
visited.add(pkgKey);
|
|
788
765
|
try {
|
|
789
|
-
const packageJsonPath =
|
|
790
|
-
if (await
|
|
791
|
-
const packageJson2 = await
|
|
766
|
+
const packageJsonPath = path6.join(packageDir, "package.json");
|
|
767
|
+
if (await fs5.pathExists(packageJsonPath)) {
|
|
768
|
+
const packageJson2 = await fs5.readJson(packageJsonPath);
|
|
792
769
|
const deps = {
|
|
793
770
|
...packageJson2.dependencies,
|
|
794
771
|
...packageJson2.peerDependencies
|
|
@@ -804,12 +781,18 @@ async function resolveDependencies(pkg, packageDir, logger, visited = /* @__PURE
|
|
|
804
781
|
}
|
|
805
782
|
return dependencies;
|
|
806
783
|
}
|
|
807
|
-
async function downloadPackages(packages, targetDir, logger, useCache = true) {
|
|
784
|
+
async function downloadPackages(packages, targetDir, logger, useCache = true, configDir) {
|
|
808
785
|
const packagePaths = /* @__PURE__ */ new Map();
|
|
809
786
|
const downloadQueue = [...packages];
|
|
810
787
|
const processed = /* @__PURE__ */ new Set();
|
|
788
|
+
const localPackageMap = /* @__PURE__ */ new Map();
|
|
789
|
+
for (const pkg of packages) {
|
|
790
|
+
if (pkg.path) {
|
|
791
|
+
localPackageMap.set(pkg.name, pkg.path);
|
|
792
|
+
}
|
|
793
|
+
}
|
|
811
794
|
validateNoDuplicatePackages(packages);
|
|
812
|
-
await
|
|
795
|
+
await fs5.ensureDir(targetDir);
|
|
813
796
|
while (downloadQueue.length > 0) {
|
|
814
797
|
const pkg = downloadQueue.shift();
|
|
815
798
|
const pkgKey = `${pkg.name}@${pkg.version}`;
|
|
@@ -817,14 +800,35 @@ async function downloadPackages(packages, targetDir, logger, useCache = true) {
|
|
|
817
800
|
continue;
|
|
818
801
|
}
|
|
819
802
|
processed.add(pkgKey);
|
|
803
|
+
if (!pkg.path && localPackageMap.has(pkg.name)) {
|
|
804
|
+
pkg.path = localPackageMap.get(pkg.name);
|
|
805
|
+
}
|
|
806
|
+
if (pkg.path) {
|
|
807
|
+
const localPkg = await resolveLocalPackage(
|
|
808
|
+
pkg.name,
|
|
809
|
+
pkg.path,
|
|
810
|
+
configDir || process.cwd(),
|
|
811
|
+
logger
|
|
812
|
+
);
|
|
813
|
+
const installedPath = await copyLocalPackage(localPkg, targetDir, logger);
|
|
814
|
+
packagePaths.set(pkg.name, installedPath);
|
|
815
|
+
const deps = await resolveDependencies(pkg, installedPath, logger);
|
|
816
|
+
for (const dep of deps) {
|
|
817
|
+
const depKey = `${dep.name}@${dep.version}`;
|
|
818
|
+
if (!processed.has(depKey)) {
|
|
819
|
+
downloadQueue.push(dep);
|
|
820
|
+
}
|
|
821
|
+
}
|
|
822
|
+
continue;
|
|
823
|
+
}
|
|
820
824
|
const packageSpec = `${pkg.name}@${pkg.version}`;
|
|
821
825
|
const packageDir = getPackageDirectory(targetDir, pkg.name, pkg.version);
|
|
822
|
-
const cachedPath = getCachedPackagePath(pkg, targetDir);
|
|
826
|
+
const cachedPath = await getCachedPackagePath(pkg, targetDir);
|
|
823
827
|
if (useCache && await isPackageCached(pkg, targetDir)) {
|
|
824
828
|
logger.debug(`Using cached ${packageSpec}...`);
|
|
825
829
|
try {
|
|
826
|
-
await
|
|
827
|
-
await
|
|
830
|
+
await fs5.ensureDir(path6.dirname(packageDir));
|
|
831
|
+
await fs5.copy(cachedPath, packageDir);
|
|
828
832
|
packagePaths.set(pkg.name, packageDir);
|
|
829
833
|
const deps = await resolveDependencies(pkg, packageDir, logger);
|
|
830
834
|
for (const dep of deps) {
|
|
@@ -842,8 +846,8 @@ async function downloadPackages(packages, targetDir, logger, useCache = true) {
|
|
|
842
846
|
}
|
|
843
847
|
logger.debug(`Downloading ${packageSpec}...`);
|
|
844
848
|
try {
|
|
845
|
-
await
|
|
846
|
-
const cacheDir = process.env.NPM_CACHE_DIR ||
|
|
849
|
+
await fs5.ensureDir(path6.dirname(packageDir));
|
|
850
|
+
const cacheDir = process.env.NPM_CACHE_DIR || path6.join(process.cwd(), ".npm-cache");
|
|
847
851
|
await pacote.extract(packageSpec, packageDir, {
|
|
848
852
|
// Force npm registry download, prevent workspace resolution
|
|
849
853
|
registry: "https://registry.npmjs.org",
|
|
@@ -856,8 +860,8 @@ async function downloadPackages(packages, targetDir, logger, useCache = true) {
|
|
|
856
860
|
});
|
|
857
861
|
if (useCache) {
|
|
858
862
|
try {
|
|
859
|
-
await
|
|
860
|
-
await
|
|
863
|
+
await fs5.ensureDir(path6.dirname(cachedPath));
|
|
864
|
+
await fs5.copy(packageDir, cachedPath);
|
|
861
865
|
logger.debug(`Cached ${packageSpec} for future use`);
|
|
862
866
|
} catch (cacheError) {
|
|
863
867
|
logger.debug(`Failed to cache ${packageSpec}: ${cacheError}`);
|
|
@@ -879,7 +883,7 @@ async function downloadPackages(packages, targetDir, logger, useCache = true) {
|
|
|
879
883
|
}
|
|
880
884
|
|
|
881
885
|
// src/commands/bundle/template-engine.ts
|
|
882
|
-
import
|
|
886
|
+
import fs6 from "fs-extra";
|
|
883
887
|
import Handlebars from "handlebars";
|
|
884
888
|
|
|
885
889
|
// src/commands/bundle/serializer.ts
|
|
@@ -996,10 +1000,10 @@ var TemplateEngine = class {
|
|
|
996
1000
|
*/
|
|
997
1001
|
async loadTemplate(templatePath) {
|
|
998
1002
|
const resolvedPath = resolveAsset(templatePath, "template");
|
|
999
|
-
if (!await
|
|
1003
|
+
if (!await fs6.pathExists(resolvedPath)) {
|
|
1000
1004
|
throw new Error(`Template file not found: ${resolvedPath}`);
|
|
1001
1005
|
}
|
|
1002
|
-
return await
|
|
1006
|
+
return await fs6.readFile(resolvedPath, "utf-8");
|
|
1003
1007
|
}
|
|
1004
1008
|
/**
|
|
1005
1009
|
* Apply template with user code and variable substitution
|
|
@@ -1034,32 +1038,118 @@ var TemplateEngine = class {
|
|
|
1034
1038
|
}
|
|
1035
1039
|
};
|
|
1036
1040
|
|
|
1041
|
+
// src/core/build-cache.ts
|
|
1042
|
+
import fs7 from "fs-extra";
|
|
1043
|
+
import path7 from "path";
|
|
1044
|
+
var BUILD_CACHE_DIR = path7.join(".tmp", "cache", "builds");
|
|
1045
|
+
async function getBuildCachePath(configContent, cacheDir = BUILD_CACHE_DIR) {
|
|
1046
|
+
const cacheKey = await getFlowConfigCacheKey(configContent);
|
|
1047
|
+
return path7.join(cacheDir, `${cacheKey}.js`);
|
|
1048
|
+
}
|
|
1049
|
+
async function isBuildCached(configContent, cacheDir = BUILD_CACHE_DIR) {
|
|
1050
|
+
const cachePath = await getBuildCachePath(configContent, cacheDir);
|
|
1051
|
+
return fs7.pathExists(cachePath);
|
|
1052
|
+
}
|
|
1053
|
+
async function cacheBuild(configContent, buildOutput, cacheDir = BUILD_CACHE_DIR) {
|
|
1054
|
+
const cachePath = await getBuildCachePath(configContent, cacheDir);
|
|
1055
|
+
await fs7.ensureDir(path7.dirname(cachePath));
|
|
1056
|
+
await fs7.writeFile(cachePath, buildOutput, "utf-8");
|
|
1057
|
+
}
|
|
1058
|
+
async function getCachedBuild(configContent, cacheDir = BUILD_CACHE_DIR) {
|
|
1059
|
+
const cachePath = await getBuildCachePath(configContent, cacheDir);
|
|
1060
|
+
if (await fs7.pathExists(cachePath)) {
|
|
1061
|
+
return await fs7.readFile(cachePath, "utf-8");
|
|
1062
|
+
}
|
|
1063
|
+
return null;
|
|
1064
|
+
}
|
|
1065
|
+
|
|
1037
1066
|
// src/commands/bundle/bundler.ts
|
|
1067
|
+
async function copyIncludes(includes, sourceDir, outputDir, logger) {
|
|
1068
|
+
for (const include of includes) {
|
|
1069
|
+
const sourcePath = path8.resolve(sourceDir, include);
|
|
1070
|
+
const folderName = path8.basename(include);
|
|
1071
|
+
const destPath = path8.join(outputDir, folderName);
|
|
1072
|
+
if (await fs8.pathExists(sourcePath)) {
|
|
1073
|
+
await fs8.copy(sourcePath, destPath);
|
|
1074
|
+
logger.debug(`Copied ${include} to output`);
|
|
1075
|
+
} else {
|
|
1076
|
+
logger.debug(`Include folder not found: ${include}`);
|
|
1077
|
+
}
|
|
1078
|
+
}
|
|
1079
|
+
}
|
|
1080
|
+
function generateCacheKeyContent(flowConfig, buildOptions) {
|
|
1081
|
+
const configForCache = {
|
|
1082
|
+
flow: flowConfig,
|
|
1083
|
+
build: {
|
|
1084
|
+
...buildOptions,
|
|
1085
|
+
// Exclude non-deterministic fields from cache key
|
|
1086
|
+
tempDir: void 0,
|
|
1087
|
+
output: void 0
|
|
1088
|
+
}
|
|
1089
|
+
};
|
|
1090
|
+
return JSON.stringify(configForCache);
|
|
1091
|
+
}
|
|
1038
1092
|
async function bundleCore(flowConfig, buildOptions, logger, showStats = false) {
|
|
1039
1093
|
const bundleStartTime = Date.now();
|
|
1040
|
-
const TEMP_DIR = buildOptions.tempDir ?
|
|
1094
|
+
const TEMP_DIR = buildOptions.tempDir ? path8.isAbsolute(buildOptions.tempDir) ? buildOptions.tempDir : path8.resolve(buildOptions.tempDir) : getTempDir();
|
|
1095
|
+
if (buildOptions.cache !== false) {
|
|
1096
|
+
const configContent = generateCacheKeyContent(flowConfig, buildOptions);
|
|
1097
|
+
const cached = await isBuildCached(configContent);
|
|
1098
|
+
if (cached) {
|
|
1099
|
+
const cachedBuild = await getCachedBuild(configContent);
|
|
1100
|
+
if (cachedBuild) {
|
|
1101
|
+
logger.info("\u2728 Using cached build");
|
|
1102
|
+
const outputPath = path8.resolve(buildOptions.output);
|
|
1103
|
+
await fs8.ensureDir(path8.dirname(outputPath));
|
|
1104
|
+
await fs8.writeFile(outputPath, cachedBuild);
|
|
1105
|
+
logger.gray(`Output: ${outputPath}`);
|
|
1106
|
+
logger.success("\u2705 Build completed (from cache)");
|
|
1107
|
+
if (showStats) {
|
|
1108
|
+
const stats = await fs8.stat(outputPath);
|
|
1109
|
+
const packageStats = Object.entries(buildOptions.packages).map(
|
|
1110
|
+
([name, pkg]) => ({
|
|
1111
|
+
name: `${name}@${pkg.version || "latest"}`,
|
|
1112
|
+
size: 0
|
|
1113
|
+
// Size estimation not available for cached builds
|
|
1114
|
+
})
|
|
1115
|
+
);
|
|
1116
|
+
return {
|
|
1117
|
+
totalSize: stats.size,
|
|
1118
|
+
packages: packageStats,
|
|
1119
|
+
buildTime: Date.now() - bundleStartTime,
|
|
1120
|
+
treeshakingEffective: true
|
|
1121
|
+
};
|
|
1122
|
+
}
|
|
1123
|
+
return;
|
|
1124
|
+
}
|
|
1125
|
+
}
|
|
1126
|
+
}
|
|
1041
1127
|
try {
|
|
1042
1128
|
if (!buildOptions.tempDir) {
|
|
1043
|
-
await
|
|
1129
|
+
await fs8.emptyDir(TEMP_DIR);
|
|
1044
1130
|
}
|
|
1045
1131
|
logger.debug("Cleaned temporary directory");
|
|
1046
1132
|
logger.info("\u{1F4E5} Downloading packages...");
|
|
1047
1133
|
const packagesArray = Object.entries(buildOptions.packages).map(
|
|
1048
1134
|
([name, packageConfig]) => ({
|
|
1049
1135
|
name,
|
|
1050
|
-
version: packageConfig.version || "latest"
|
|
1136
|
+
version: packageConfig.version || "latest",
|
|
1137
|
+
path: packageConfig.path
|
|
1138
|
+
// Pass local path if defined
|
|
1051
1139
|
})
|
|
1052
1140
|
);
|
|
1053
1141
|
const packagePaths = await downloadPackages(
|
|
1054
1142
|
packagesArray,
|
|
1055
1143
|
TEMP_DIR,
|
|
1056
1144
|
logger,
|
|
1057
|
-
buildOptions.cache
|
|
1145
|
+
buildOptions.cache,
|
|
1146
|
+
buildOptions.configDir
|
|
1147
|
+
// For resolving relative local paths
|
|
1058
1148
|
);
|
|
1059
1149
|
for (const [pkgName, pkgPath] of packagePaths.entries()) {
|
|
1060
1150
|
if (pkgName.startsWith("@walkeros/")) {
|
|
1061
|
-
const pkgJsonPath =
|
|
1062
|
-
const pkgJson = await
|
|
1151
|
+
const pkgJsonPath = path8.join(pkgPath, "package.json");
|
|
1152
|
+
const pkgJson = await fs8.readJSON(pkgJsonPath);
|
|
1063
1153
|
if (!pkgJson.exports && pkgJson.module) {
|
|
1064
1154
|
pkgJson.exports = {
|
|
1065
1155
|
".": {
|
|
@@ -1067,12 +1157,12 @@ async function bundleCore(flowConfig, buildOptions, logger, showStats = false) {
|
|
|
1067
1157
|
require: pkgJson.main
|
|
1068
1158
|
}
|
|
1069
1159
|
};
|
|
1070
|
-
await
|
|
1160
|
+
await fs8.writeJSON(pkgJsonPath, pkgJson, { spaces: 2 });
|
|
1071
1161
|
}
|
|
1072
1162
|
}
|
|
1073
1163
|
}
|
|
1074
|
-
const packageJsonPath =
|
|
1075
|
-
await
|
|
1164
|
+
const packageJsonPath = path8.join(TEMP_DIR, "package.json");
|
|
1165
|
+
await fs8.writeFile(
|
|
1076
1166
|
packageJsonPath,
|
|
1077
1167
|
JSON.stringify({ type: "module" }, null, 2)
|
|
1078
1168
|
);
|
|
@@ -1082,11 +1172,11 @@ async function bundleCore(flowConfig, buildOptions, logger, showStats = false) {
|
|
|
1082
1172
|
buildOptions,
|
|
1083
1173
|
packagePaths
|
|
1084
1174
|
);
|
|
1085
|
-
const entryPath =
|
|
1086
|
-
await
|
|
1175
|
+
const entryPath = path8.join(TEMP_DIR, "entry.js");
|
|
1176
|
+
await fs8.writeFile(entryPath, entryContent);
|
|
1087
1177
|
logger.info("\u26A1 Bundling with esbuild...");
|
|
1088
|
-
const outputPath =
|
|
1089
|
-
await
|
|
1178
|
+
const outputPath = path8.resolve(buildOptions.output);
|
|
1179
|
+
await fs8.ensureDir(path8.dirname(outputPath));
|
|
1090
1180
|
const esbuildOptions = createEsbuildOptions(
|
|
1091
1181
|
buildOptions,
|
|
1092
1182
|
entryPath,
|
|
@@ -1104,6 +1194,12 @@ async function bundleCore(flowConfig, buildOptions, logger, showStats = false) {
|
|
|
1104
1194
|
);
|
|
1105
1195
|
}
|
|
1106
1196
|
logger.gray(`Output: ${outputPath}`);
|
|
1197
|
+
if (buildOptions.cache !== false) {
|
|
1198
|
+
const configContent = generateCacheKeyContent(flowConfig, buildOptions);
|
|
1199
|
+
const buildOutput = await fs8.readFile(outputPath, "utf-8");
|
|
1200
|
+
await cacheBuild(configContent, buildOutput);
|
|
1201
|
+
logger.debug("Build cached for future use");
|
|
1202
|
+
}
|
|
1107
1203
|
let stats;
|
|
1108
1204
|
if (showStats) {
|
|
1109
1205
|
stats = await collectBundleStats(
|
|
@@ -1113,21 +1209,30 @@ async function bundleCore(flowConfig, buildOptions, logger, showStats = false) {
|
|
|
1113
1209
|
entryContent
|
|
1114
1210
|
);
|
|
1115
1211
|
}
|
|
1212
|
+
if (buildOptions.include && buildOptions.include.length > 0) {
|
|
1213
|
+
const outputDir = path8.dirname(outputPath);
|
|
1214
|
+
await copyIncludes(
|
|
1215
|
+
buildOptions.include,
|
|
1216
|
+
buildOptions.configDir || process.cwd(),
|
|
1217
|
+
outputDir,
|
|
1218
|
+
logger
|
|
1219
|
+
);
|
|
1220
|
+
}
|
|
1116
1221
|
if (!buildOptions.tempDir) {
|
|
1117
|
-
await
|
|
1222
|
+
await fs8.remove(TEMP_DIR);
|
|
1118
1223
|
logger.debug("Cleaned up temporary files");
|
|
1119
1224
|
}
|
|
1120
1225
|
return stats;
|
|
1121
1226
|
} catch (error) {
|
|
1122
1227
|
if (!buildOptions.tempDir) {
|
|
1123
|
-
await
|
|
1228
|
+
await fs8.remove(TEMP_DIR).catch(() => {
|
|
1124
1229
|
});
|
|
1125
1230
|
}
|
|
1126
1231
|
throw error;
|
|
1127
1232
|
}
|
|
1128
1233
|
}
|
|
1129
1234
|
async function collectBundleStats(outputPath, packages, startTime, entryContent) {
|
|
1130
|
-
const stats = await
|
|
1235
|
+
const stats = await fs8.stat(outputPath);
|
|
1131
1236
|
const totalSize = stats.size;
|
|
1132
1237
|
const buildTime = Date.now() - startTime;
|
|
1133
1238
|
const packageStats = Object.entries(packages).map(([name, pkg]) => {
|
|
@@ -1206,6 +1311,11 @@ function createEsbuildOptions(buildOptions, entryPath, outputPath, tempDir, pack
|
|
|
1206
1311
|
];
|
|
1207
1312
|
const npmPackages = ["express", "express/*", "cors", "cors/*"];
|
|
1208
1313
|
baseOptions.external = buildOptions.external ? [...nodeBuiltins, ...npmPackages, ...buildOptions.external] : [...nodeBuiltins, ...npmPackages];
|
|
1314
|
+
if (buildOptions.format === "esm") {
|
|
1315
|
+
baseOptions.banner = {
|
|
1316
|
+
js: `import { createRequire } from 'module';const require = createRequire(import.meta.url);`
|
|
1317
|
+
};
|
|
1318
|
+
}
|
|
1209
1319
|
}
|
|
1210
1320
|
if (buildOptions.target) {
|
|
1211
1321
|
baseOptions.target = buildOptions.target;
|
|
@@ -1400,23 +1510,23 @@ async function bundleCommand(options) {
|
|
|
1400
1510
|
timer.start();
|
|
1401
1511
|
const logger = createCommandLogger(options);
|
|
1402
1512
|
const dockerArgs = buildCommonDockerArgs(options);
|
|
1403
|
-
if (options.
|
|
1513
|
+
if (options.flow) dockerArgs.push("--flow", options.flow);
|
|
1404
1514
|
if (options.all) dockerArgs.push("--all");
|
|
1405
1515
|
if (options.stats) dockerArgs.push("--stats");
|
|
1406
1516
|
if (options.cache === false) dockerArgs.push("--no-cache");
|
|
1407
1517
|
await executeCommand(
|
|
1408
1518
|
async () => {
|
|
1409
1519
|
try {
|
|
1410
|
-
if (options.
|
|
1411
|
-
throw new Error("Cannot use both --
|
|
1520
|
+
if (options.flow && options.all) {
|
|
1521
|
+
throw new Error("Cannot use both --flow and --all flags together");
|
|
1412
1522
|
}
|
|
1413
1523
|
logger.info("\u{1F4E6} Reading configuration...");
|
|
1414
|
-
const configPath = options.config;
|
|
1524
|
+
const configPath = resolveAsset(options.config, "config");
|
|
1415
1525
|
const rawConfig = await loadJsonConfig(configPath);
|
|
1416
|
-
const configsToBundle = options.all ?
|
|
1526
|
+
const configsToBundle = options.all ? loadAllFlows(rawConfig, { configPath, logger }) : [
|
|
1417
1527
|
loadBundleConfig(rawConfig, {
|
|
1418
1528
|
configPath,
|
|
1419
|
-
|
|
1529
|
+
flowName: options.flow,
|
|
1420
1530
|
logger
|
|
1421
1531
|
})
|
|
1422
1532
|
];
|
|
@@ -1424,16 +1534,16 @@ async function bundleCommand(options) {
|
|
|
1424
1534
|
for (const {
|
|
1425
1535
|
flowConfig,
|
|
1426
1536
|
buildOptions,
|
|
1427
|
-
|
|
1428
|
-
|
|
1537
|
+
flowName,
|
|
1538
|
+
isMultiFlow
|
|
1429
1539
|
} of configsToBundle) {
|
|
1430
1540
|
try {
|
|
1431
1541
|
if (options.cache !== void 0) {
|
|
1432
1542
|
buildOptions.cache = options.cache;
|
|
1433
1543
|
}
|
|
1434
|
-
if (
|
|
1544
|
+
if (isMultiFlow || options.all) {
|
|
1435
1545
|
logger.info(`
|
|
1436
|
-
\u{1F527} Building
|
|
1546
|
+
\u{1F527} Building flow: ${flowName}`);
|
|
1437
1547
|
} else {
|
|
1438
1548
|
logger.info("\u{1F527} Starting bundle process...");
|
|
1439
1549
|
}
|
|
@@ -1445,7 +1555,7 @@ async function bundleCommand(options) {
|
|
|
1445
1555
|
shouldCollectStats
|
|
1446
1556
|
);
|
|
1447
1557
|
results.push({
|
|
1448
|
-
|
|
1558
|
+
flowName,
|
|
1449
1559
|
success: true,
|
|
1450
1560
|
stats
|
|
1451
1561
|
});
|
|
@@ -1455,7 +1565,7 @@ async function bundleCommand(options) {
|
|
|
1455
1565
|
} catch (error) {
|
|
1456
1566
|
const errorMessage = getErrorMessage(error);
|
|
1457
1567
|
results.push({
|
|
1458
|
-
|
|
1568
|
+
flowName,
|
|
1459
1569
|
success: false,
|
|
1460
1570
|
error: errorMessage
|
|
1461
1571
|
});
|
|
@@ -1471,7 +1581,7 @@ async function bundleCommand(options) {
|
|
|
1471
1581
|
const outputLogger = createLogger({ silent: false, json: false });
|
|
1472
1582
|
const output = failureCount === 0 ? createSuccessOutput(
|
|
1473
1583
|
{
|
|
1474
|
-
|
|
1584
|
+
flows: results,
|
|
1475
1585
|
summary: {
|
|
1476
1586
|
total: results.length,
|
|
1477
1587
|
success: successCount,
|
|
@@ -1480,7 +1590,7 @@ async function bundleCommand(options) {
|
|
|
1480
1590
|
},
|
|
1481
1591
|
duration
|
|
1482
1592
|
) : createErrorOutput(
|
|
1483
|
-
`${failureCount}
|
|
1593
|
+
`${failureCount} flow(s) failed to build`,
|
|
1484
1594
|
duration
|
|
1485
1595
|
);
|
|
1486
1596
|
outputLogger.log("white", JSON.stringify(output, null, 2));
|
|
@@ -1500,7 +1610,7 @@ async function bundleCommand(options) {
|
|
|
1500
1610
|
\u2705 Bundle created successfully in ${timer.format()}`
|
|
1501
1611
|
);
|
|
1502
1612
|
} else {
|
|
1503
|
-
throw new Error(`${failureCount}
|
|
1613
|
+
throw new Error(`${failureCount} flow(s) failed to build`);
|
|
1504
1614
|
}
|
|
1505
1615
|
}
|
|
1506
1616
|
} catch (error) {
|
|
@@ -1526,12 +1636,18 @@ async function bundleCommand(options) {
|
|
|
1526
1636
|
}
|
|
1527
1637
|
async function bundle(configOrPath, options = {}) {
|
|
1528
1638
|
let rawConfig;
|
|
1639
|
+
let configPath = path9.resolve(process.cwd(), "walkeros.config.json");
|
|
1529
1640
|
if (typeof configOrPath === "string") {
|
|
1530
|
-
|
|
1641
|
+
configPath = resolveAsset(configOrPath, "config");
|
|
1642
|
+
rawConfig = await loadJsonConfig(configPath);
|
|
1531
1643
|
} else {
|
|
1532
1644
|
rawConfig = configOrPath;
|
|
1533
1645
|
}
|
|
1534
|
-
const { flowConfig, buildOptions } =
|
|
1646
|
+
const { flowConfig, buildOptions } = loadBundleConfig(rawConfig, {
|
|
1647
|
+
configPath,
|
|
1648
|
+
flowName: options.flowName,
|
|
1649
|
+
buildOverrides: options.buildOverrides
|
|
1650
|
+
});
|
|
1535
1651
|
if (options.cache !== void 0) {
|
|
1536
1652
|
buildOptions.cache = options.cache;
|
|
1537
1653
|
}
|
|
@@ -1545,8 +1661,9 @@ async function bundle(configOrPath, options = {}) {
|
|
|
1545
1661
|
}
|
|
1546
1662
|
|
|
1547
1663
|
// src/commands/simulate/simulator.ts
|
|
1548
|
-
import
|
|
1549
|
-
import
|
|
1664
|
+
import path10 from "path";
|
|
1665
|
+
import fs10 from "fs-extra";
|
|
1666
|
+
import { getPlatform as getPlatform2 } from "@walkeros/core";
|
|
1550
1667
|
|
|
1551
1668
|
// src/commands/simulate/tracker.ts
|
|
1552
1669
|
var CallTracker = class {
|
|
@@ -1582,9 +1699,9 @@ var CallTracker = class {
|
|
|
1582
1699
|
}
|
|
1583
1700
|
for (const fullPath of paths) {
|
|
1584
1701
|
const [destKey, ...pathParts] = fullPath.split(":");
|
|
1585
|
-
const
|
|
1586
|
-
if (!
|
|
1587
|
-
const cleanPath =
|
|
1702
|
+
const path15 = pathParts.join(":");
|
|
1703
|
+
if (!path15) continue;
|
|
1704
|
+
const cleanPath = path15.replace(/^call:/, "");
|
|
1588
1705
|
const parts = cleanPath.split(".");
|
|
1589
1706
|
let current = wrapped;
|
|
1590
1707
|
let source = env;
|
|
@@ -1628,7 +1745,7 @@ var CallTracker = class {
|
|
|
1628
1745
|
|
|
1629
1746
|
// src/commands/simulate/jsdom-executor.ts
|
|
1630
1747
|
import { JSDOM, VirtualConsole } from "jsdom";
|
|
1631
|
-
import
|
|
1748
|
+
import fs9 from "fs-extra";
|
|
1632
1749
|
function buildSandboxFromEnvs(envs, destinations, tracker) {
|
|
1633
1750
|
const baseBrowserMocks = {
|
|
1634
1751
|
Image: class MockImage {
|
|
@@ -1697,7 +1814,7 @@ async function executeInJSDOM(bundlePath, destinations, event, tracker, envs, ti
|
|
|
1697
1814
|
const sandbox = buildSandboxFromEnvs(envs, destinations, tracker);
|
|
1698
1815
|
Object.assign(window, sandbox.window);
|
|
1699
1816
|
Object.assign(window.document, sandbox.document);
|
|
1700
|
-
const bundleCode = await
|
|
1817
|
+
const bundleCode = await fs9.readFile(bundlePath, "utf8");
|
|
1701
1818
|
try {
|
|
1702
1819
|
window.eval(bundleCode);
|
|
1703
1820
|
} catch (error) {
|
|
@@ -1735,6 +1852,85 @@ async function executeInJSDOM(bundlePath, destinations, event, tracker, envs, ti
|
|
|
1735
1852
|
};
|
|
1736
1853
|
}
|
|
1737
1854
|
|
|
1855
|
+
// src/commands/simulate/node-executor.ts
|
|
1856
|
+
import { pathToFileURL } from "url";
|
|
1857
|
+
function buildGlobalMocksFromEnvs(envs, destinations, tracker) {
|
|
1858
|
+
const globalMocks = {};
|
|
1859
|
+
for (const [destKey] of Object.entries(destinations)) {
|
|
1860
|
+
const destEnv = envs[destKey];
|
|
1861
|
+
if (!destEnv?.push) continue;
|
|
1862
|
+
const mockEnv = destEnv.push;
|
|
1863
|
+
const trackPaths = destEnv.simulation || [];
|
|
1864
|
+
const trackedEnv = tracker.wrapEnv(
|
|
1865
|
+
mockEnv,
|
|
1866
|
+
trackPaths.map((p) => `${destKey}:${p}`)
|
|
1867
|
+
);
|
|
1868
|
+
Object.assign(globalMocks, trackedEnv);
|
|
1869
|
+
}
|
|
1870
|
+
return globalMocks;
|
|
1871
|
+
}
|
|
1872
|
+
function injectGlobalMocks(mocks) {
|
|
1873
|
+
const originalValues = {};
|
|
1874
|
+
for (const [key, value] of Object.entries(mocks)) {
|
|
1875
|
+
originalValues[key] = globalThis[key];
|
|
1876
|
+
globalThis[key] = value;
|
|
1877
|
+
}
|
|
1878
|
+
return () => {
|
|
1879
|
+
for (const [key, value] of Object.entries(originalValues)) {
|
|
1880
|
+
if (value === void 0) {
|
|
1881
|
+
delete globalThis[key];
|
|
1882
|
+
} else {
|
|
1883
|
+
globalThis[key] = value;
|
|
1884
|
+
}
|
|
1885
|
+
}
|
|
1886
|
+
};
|
|
1887
|
+
}
|
|
1888
|
+
async function executeInNode(bundlePath, destinations, event, tracker, envs, timeout = 3e4) {
|
|
1889
|
+
const start = Date.now();
|
|
1890
|
+
const globalMocks = buildGlobalMocksFromEnvs(envs, destinations, tracker);
|
|
1891
|
+
const cleanupMocks = injectGlobalMocks(globalMocks);
|
|
1892
|
+
try {
|
|
1893
|
+
const executeWithTimeout = async () => {
|
|
1894
|
+
const importUrl = process.env.JEST_WORKER_ID ? bundlePath : `${pathToFileURL(bundlePath).href}?t=${Date.now()}`;
|
|
1895
|
+
const module = await import(importUrl);
|
|
1896
|
+
if (!module.default || typeof module.default !== "function") {
|
|
1897
|
+
throw new Error("Bundle does not export default factory function");
|
|
1898
|
+
}
|
|
1899
|
+
const result = await module.default();
|
|
1900
|
+
if (!result || !result.elb || typeof result.elb !== "function") {
|
|
1901
|
+
throw new Error(
|
|
1902
|
+
"Factory function did not return valid result with elb"
|
|
1903
|
+
);
|
|
1904
|
+
}
|
|
1905
|
+
const { collector, elb } = result;
|
|
1906
|
+
let elbResult;
|
|
1907
|
+
try {
|
|
1908
|
+
elbResult = await elb(event.name, event.data);
|
|
1909
|
+
} catch (error) {
|
|
1910
|
+
throw new Error(`Event execution failed: ${getErrorMessage(error)}`);
|
|
1911
|
+
}
|
|
1912
|
+
return {
|
|
1913
|
+
collector,
|
|
1914
|
+
elb,
|
|
1915
|
+
elbResult,
|
|
1916
|
+
usage: tracker.getCalls(),
|
|
1917
|
+
duration: Date.now() - start
|
|
1918
|
+
};
|
|
1919
|
+
};
|
|
1920
|
+
const timeoutPromise = new Promise((_, reject) => {
|
|
1921
|
+
setTimeout(
|
|
1922
|
+
() => reject(new Error(`Server simulation timeout after ${timeout}ms`)),
|
|
1923
|
+
timeout
|
|
1924
|
+
);
|
|
1925
|
+
});
|
|
1926
|
+
return await Promise.race([executeWithTimeout(), timeoutPromise]);
|
|
1927
|
+
} catch (error) {
|
|
1928
|
+
throw new Error(`Node execution failed: ${getErrorMessage(error)}`);
|
|
1929
|
+
} finally {
|
|
1930
|
+
cleanupMocks();
|
|
1931
|
+
}
|
|
1932
|
+
}
|
|
1933
|
+
|
|
1738
1934
|
// src/commands/simulate/env-loader.ts
|
|
1739
1935
|
async function loadDestinationEnvs(destinations) {
|
|
1740
1936
|
const envs = {};
|
|
@@ -1779,9 +1975,9 @@ async function simulateCore(configPath, event, options = {}) {
|
|
|
1779
1975
|
try {
|
|
1780
1976
|
logger.info("\u{1F3AF} Starting walkerOS simulation...");
|
|
1781
1977
|
logger.info("\u{1F4E6} Loading bundle configuration...");
|
|
1782
|
-
const fullConfigPath =
|
|
1978
|
+
const fullConfigPath = path10.resolve(configPath);
|
|
1783
1979
|
const rawConfig = await loadJsonConfig(fullConfigPath);
|
|
1784
|
-
|
|
1980
|
+
loadBundleConfig(rawConfig, { configPath: fullConfigPath });
|
|
1785
1981
|
logger.info(`\u{1F680} Executing simulation with event: ${JSON.stringify(event)}`);
|
|
1786
1982
|
const result = await executeSimulation(event, fullConfigPath);
|
|
1787
1983
|
if (result.success) {
|
|
@@ -1825,42 +2021,32 @@ async function executeSimulation(event, configPath) {
|
|
|
1825
2021
|
);
|
|
1826
2022
|
}
|
|
1827
2023
|
const typedEvent = event;
|
|
1828
|
-
await
|
|
2024
|
+
await fs10.ensureDir(tempDir);
|
|
1829
2025
|
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
|
-
);
|
|
2026
|
+
const { flowConfig, buildOptions } = loadBundleConfig(rawConfig, {
|
|
2027
|
+
configPath
|
|
2028
|
+
});
|
|
2029
|
+
const platform = getPlatform2(flowConfig);
|
|
1844
2030
|
const tracker = new CallTracker();
|
|
1845
|
-
const tempOutput =
|
|
2031
|
+
const tempOutput = path10.join(
|
|
1846
2032
|
tempDir,
|
|
1847
|
-
`simulation-bundle-${generateId()}
|
|
2033
|
+
`simulation-bundle-${generateId()}.${platform === "web" ? "js" : "mjs"}`
|
|
1848
2034
|
);
|
|
1849
2035
|
const destinations = flowConfig.destinations;
|
|
1850
2036
|
const simulationBuildOptions = {
|
|
1851
2037
|
...buildOptions,
|
|
1852
2038
|
code: buildOptions.code || "",
|
|
1853
|
-
// No code modification - use original
|
|
1854
2039
|
output: tempOutput,
|
|
1855
2040
|
tempDir,
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
|
|
2041
|
+
...platform === "web" ? {
|
|
2042
|
+
format: "iife",
|
|
2043
|
+
platform: "browser",
|
|
2044
|
+
windowCollector: "collector",
|
|
2045
|
+
windowElb: "elb"
|
|
2046
|
+
} : {
|
|
2047
|
+
format: "esm",
|
|
2048
|
+
platform: "node"
|
|
2049
|
+
}
|
|
1864
2050
|
};
|
|
1865
2051
|
await bundleCore(
|
|
1866
2052
|
flowConfig,
|
|
@@ -1870,16 +2056,26 @@ async function executeSimulation(event, configPath) {
|
|
|
1870
2056
|
);
|
|
1871
2057
|
bundlePath = tempOutput;
|
|
1872
2058
|
const envs = await loadDestinationEnvs(destinations || {});
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
|
|
2059
|
+
let result;
|
|
2060
|
+
if (platform === "web") {
|
|
2061
|
+
result = await executeInJSDOM(
|
|
2062
|
+
tempOutput,
|
|
2063
|
+
destinations || {},
|
|
2064
|
+
typedEvent,
|
|
2065
|
+
tracker,
|
|
2066
|
+
envs,
|
|
2067
|
+
1e4
|
|
2068
|
+
);
|
|
2069
|
+
} else {
|
|
2070
|
+
result = await executeInNode(
|
|
2071
|
+
tempOutput,
|
|
2072
|
+
destinations || {},
|
|
2073
|
+
typedEvent,
|
|
2074
|
+
tracker,
|
|
2075
|
+
envs,
|
|
2076
|
+
3e4
|
|
2077
|
+
);
|
|
2078
|
+
}
|
|
1883
2079
|
const elbResult = result.elbResult;
|
|
1884
2080
|
const usage = result.usage;
|
|
1885
2081
|
const duration = Date.now() - startTime;
|
|
@@ -1899,7 +2095,7 @@ async function executeSimulation(event, configPath) {
|
|
|
1899
2095
|
};
|
|
1900
2096
|
} finally {
|
|
1901
2097
|
if (tempDir) {
|
|
1902
|
-
await
|
|
2098
|
+
await fs10.remove(tempDir).catch(() => {
|
|
1903
2099
|
});
|
|
1904
2100
|
}
|
|
1905
2101
|
}
|
|
@@ -1975,15 +2171,16 @@ async function simulate(configOrPath, event, options = {}) {
|
|
|
1975
2171
|
}
|
|
1976
2172
|
|
|
1977
2173
|
// src/commands/push/index.ts
|
|
1978
|
-
import
|
|
1979
|
-
import os2 from "os";
|
|
2174
|
+
import path11 from "path";
|
|
1980
2175
|
import { JSDOM as JSDOM2, VirtualConsole as VirtualConsole2 } from "jsdom";
|
|
1981
|
-
import
|
|
2176
|
+
import fs11 from "fs-extra";
|
|
2177
|
+
import { getPlatform as getPlatform3 } from "@walkeros/core";
|
|
2178
|
+
import { schemas as schemas2 } from "@walkeros/core/dev";
|
|
1982
2179
|
async function pushCommand(options) {
|
|
1983
2180
|
const logger = createCommandLogger(options);
|
|
1984
2181
|
const dockerArgs = buildCommonDockerArgs(options);
|
|
1985
2182
|
dockerArgs.push("--event", options.event);
|
|
1986
|
-
if (options.
|
|
2183
|
+
if (options.flow) dockerArgs.push("--flow", options.flow);
|
|
1987
2184
|
await executeCommand(
|
|
1988
2185
|
async () => {
|
|
1989
2186
|
const startTime = Date.now();
|
|
@@ -1992,57 +2189,65 @@ async function pushCommand(options) {
|
|
|
1992
2189
|
const event = await loadJsonFromSource(options.event, {
|
|
1993
2190
|
name: "event"
|
|
1994
2191
|
});
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
);
|
|
2192
|
+
const eventResult = schemas2.PartialEventSchema.safeParse(event);
|
|
2193
|
+
if (!eventResult.success) {
|
|
2194
|
+
const errors = eventResult.error.issues.map((issue) => `${String(issue.path.join("."))}: ${issue.message}`).join(", ");
|
|
2195
|
+
throw new Error(`Invalid event: ${errors}`);
|
|
1999
2196
|
}
|
|
2000
|
-
|
|
2197
|
+
const parsedEvent = eventResult.data;
|
|
2198
|
+
if (!parsedEvent.name) {
|
|
2199
|
+
throw new Error('Invalid event: Missing required "name" property');
|
|
2200
|
+
}
|
|
2201
|
+
const validatedEvent = {
|
|
2202
|
+
name: parsedEvent.name,
|
|
2203
|
+
data: parsedEvent.data || {}
|
|
2204
|
+
};
|
|
2205
|
+
if (!validatedEvent.name.includes(" ")) {
|
|
2001
2206
|
logger.warn(
|
|
2002
|
-
`Event name "${
|
|
2207
|
+
`Event name "${validatedEvent.name}" should follow "ENTITY ACTION" format (e.g., "page view")`
|
|
2003
2208
|
);
|
|
2004
2209
|
}
|
|
2005
2210
|
logger.info("\u{1F4E6} Loading flow configuration...");
|
|
2006
|
-
const configPath =
|
|
2211
|
+
const configPath = path11.resolve(options.config);
|
|
2007
2212
|
const rawConfig = await loadJsonConfig(configPath);
|
|
2008
|
-
const { flowConfig, buildOptions,
|
|
2213
|
+
const { flowConfig, buildOptions, flowName, isMultiFlow } = loadBundleConfig(rawConfig, {
|
|
2009
2214
|
configPath: options.config,
|
|
2010
|
-
|
|
2215
|
+
flowName: options.flow,
|
|
2011
2216
|
logger
|
|
2012
2217
|
});
|
|
2013
|
-
const platform = flowConfig
|
|
2218
|
+
const platform = getPlatform3(flowConfig);
|
|
2014
2219
|
logger.info("\u{1F528} Bundling flow configuration...");
|
|
2015
|
-
const
|
|
2016
|
-
|
|
2017
|
-
|
|
2220
|
+
const configDir = path11.dirname(configPath);
|
|
2221
|
+
const tempDir = path11.join(
|
|
2222
|
+
configDir,
|
|
2223
|
+
".tmp",
|
|
2224
|
+
`push-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`
|
|
2018
2225
|
);
|
|
2019
|
-
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
|
|
2226
|
+
await fs11.ensureDir(tempDir);
|
|
2227
|
+
const tempPath = path11.join(
|
|
2228
|
+
tempDir,
|
|
2229
|
+
`bundle.${platform === "web" ? "js" : "mjs"}`
|
|
2230
|
+
);
|
|
2231
|
+
const pushBuildOptions = {
|
|
2232
|
+
...buildOptions,
|
|
2233
|
+
output: tempPath,
|
|
2234
|
+
// Web uses IIFE for browser-like execution, server uses ESM
|
|
2235
|
+
format: platform === "web" ? "iife" : "esm",
|
|
2236
|
+
platform: platform === "web" ? "browser" : "node",
|
|
2237
|
+
...platform === "web" && {
|
|
2238
|
+
windowCollector: "collector",
|
|
2239
|
+
windowElb: "elb"
|
|
2031
2240
|
}
|
|
2032
2241
|
};
|
|
2033
|
-
await
|
|
2034
|
-
cache: true,
|
|
2035
|
-
verbose: options.verbose,
|
|
2036
|
-
silent: !options.verbose
|
|
2037
|
-
});
|
|
2242
|
+
await bundleCore(flowConfig, pushBuildOptions, logger, false);
|
|
2038
2243
|
logger.debug(`Bundle created: ${tempPath}`);
|
|
2039
2244
|
let result;
|
|
2040
2245
|
if (platform === "web") {
|
|
2041
2246
|
logger.info("\u{1F310} Executing in web environment (JSDOM)...");
|
|
2042
|
-
result = await executeWebPush(tempPath,
|
|
2247
|
+
result = await executeWebPush(tempPath, validatedEvent, logger);
|
|
2043
2248
|
} else if (platform === "server") {
|
|
2044
2249
|
logger.info("\u{1F5A5}\uFE0F Executing in server environment (Node.js)...");
|
|
2045
|
-
result = await executeServerPush(tempPath,
|
|
2250
|
+
result = await executeServerPush(tempPath, validatedEvent, logger);
|
|
2046
2251
|
} else {
|
|
2047
2252
|
throw new Error(`Unsupported platform: ${platform}`);
|
|
2048
2253
|
}
|
|
@@ -2083,7 +2288,7 @@ async function pushCommand(options) {
|
|
|
2083
2288
|
}
|
|
2084
2289
|
}
|
|
2085
2290
|
try {
|
|
2086
|
-
await
|
|
2291
|
+
await fs11.remove(tempDir);
|
|
2087
2292
|
} catch {
|
|
2088
2293
|
}
|
|
2089
2294
|
} catch (error) {
|
|
@@ -2128,7 +2333,7 @@ async function executeWebPush(bundlePath, event, logger) {
|
|
|
2128
2333
|
});
|
|
2129
2334
|
const { window } = dom;
|
|
2130
2335
|
logger.debug("Loading bundle...");
|
|
2131
|
-
const bundleCode = await
|
|
2336
|
+
const bundleCode = await fs11.readFile(bundlePath, "utf8");
|
|
2132
2337
|
window.eval(bundleCode);
|
|
2133
2338
|
logger.debug("Waiting for elb...");
|
|
2134
2339
|
await waitForWindowProperty2(
|
|
@@ -2139,8 +2344,7 @@ async function executeWebPush(bundlePath, event, logger) {
|
|
|
2139
2344
|
const windowObj = window;
|
|
2140
2345
|
const elb = windowObj.elb;
|
|
2141
2346
|
logger.info(`Pushing event: ${event.name}`);
|
|
2142
|
-
const
|
|
2143
|
-
const elbResult = await elb(event.name, eventData);
|
|
2347
|
+
const elbResult = await elb(event.name, event.data);
|
|
2144
2348
|
return {
|
|
2145
2349
|
success: true,
|
|
2146
2350
|
elbResult,
|
|
@@ -2178,8 +2382,7 @@ async function executeServerPush(bundlePath, event, logger, timeout = 6e4) {
|
|
|
2178
2382
|
}
|
|
2179
2383
|
const { elb } = result;
|
|
2180
2384
|
logger.info(`Pushing event: ${event.name}`);
|
|
2181
|
-
const
|
|
2182
|
-
const elbResult = await elb(event.name, eventData);
|
|
2385
|
+
const elbResult = await elb(event.name, event.data);
|
|
2183
2386
|
return {
|
|
2184
2387
|
success: true,
|
|
2185
2388
|
elbResult,
|
|
@@ -2216,23 +2419,40 @@ function waitForWindowProperty2(window, prop, timeout = 5e3) {
|
|
|
2216
2419
|
}
|
|
2217
2420
|
|
|
2218
2421
|
// src/commands/run/index.ts
|
|
2219
|
-
import
|
|
2422
|
+
import path13 from "path";
|
|
2423
|
+
|
|
2424
|
+
// src/commands/run/validators.ts
|
|
2425
|
+
import { existsSync as existsSync2 } from "fs";
|
|
2426
|
+
|
|
2427
|
+
// src/schemas/primitives.ts
|
|
2428
|
+
import { z } from "@walkeros/core/dev";
|
|
2429
|
+
var RunModeSchema = z.enum(["collect", "serve"]).describe("CLI run mode: collect events or serve HTTP");
|
|
2430
|
+
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");
|
|
2431
|
+
var FilePathSchema = z.string().min(1, "File path cannot be empty").describe("Path to configuration file");
|
|
2432
|
+
|
|
2433
|
+
// src/schemas/run.ts
|
|
2434
|
+
import { z as z2 } from "@walkeros/core/dev";
|
|
2435
|
+
var RunOptionsSchema = z2.object({
|
|
2436
|
+
mode: RunModeSchema,
|
|
2437
|
+
flow: FilePathSchema,
|
|
2438
|
+
port: PortSchema.default(8080),
|
|
2439
|
+
flowName: z2.string().optional().describe("Specific flow name to run")
|
|
2440
|
+
});
|
|
2220
2441
|
|
|
2221
2442
|
// src/commands/run/validators.ts
|
|
2222
|
-
import { existsSync } from "fs";
|
|
2223
|
-
var VALID_MODES = ["collect", "serve"];
|
|
2224
2443
|
function validateMode(mode) {
|
|
2225
|
-
|
|
2444
|
+
const result = RunModeSchema.safeParse(mode);
|
|
2445
|
+
if (!result.success) {
|
|
2226
2446
|
throw new Error(
|
|
2227
2447
|
`Invalid mode: "${mode}"
|
|
2228
|
-
Valid modes:
|
|
2448
|
+
Valid modes: collect, serve
|
|
2229
2449
|
Example: walkeros run collect ./flow.json`
|
|
2230
2450
|
);
|
|
2231
2451
|
}
|
|
2232
2452
|
}
|
|
2233
2453
|
function validateFlowFile(filePath) {
|
|
2234
2454
|
const absolutePath = resolveAsset(filePath, "bundle");
|
|
2235
|
-
if (!
|
|
2455
|
+
if (!existsSync2(absolutePath)) {
|
|
2236
2456
|
throw new Error(
|
|
2237
2457
|
`Flow file not found: ${filePath}
|
|
2238
2458
|
Resolved path: ${absolutePath}
|
|
@@ -2242,7 +2462,8 @@ function validateFlowFile(filePath) {
|
|
|
2242
2462
|
return absolutePath;
|
|
2243
2463
|
}
|
|
2244
2464
|
function validatePort(port) {
|
|
2245
|
-
|
|
2465
|
+
const result = PortSchema.safeParse(port);
|
|
2466
|
+
if (!result.success) {
|
|
2246
2467
|
throw new Error(
|
|
2247
2468
|
`Invalid port: ${port}
|
|
2248
2469
|
Port must be an integer between 1 and 65535
|
|
@@ -2252,26 +2473,26 @@ function validatePort(port) {
|
|
|
2252
2473
|
}
|
|
2253
2474
|
|
|
2254
2475
|
// src/commands/run/utils.ts
|
|
2255
|
-
import
|
|
2256
|
-
import
|
|
2476
|
+
import path12 from "path";
|
|
2477
|
+
import fs12 from "fs-extra";
|
|
2257
2478
|
async function prepareBundleForRun(configPath, options) {
|
|
2258
|
-
const
|
|
2259
|
-
const
|
|
2260
|
-
|
|
2261
|
-
|
|
2479
|
+
const configDir = path12.dirname(path12.resolve(configPath));
|
|
2480
|
+
const tempDir = path12.join(
|
|
2481
|
+
configDir,
|
|
2482
|
+
".tmp",
|
|
2483
|
+
`run-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`
|
|
2262
2484
|
);
|
|
2263
|
-
|
|
2264
|
-
const
|
|
2265
|
-
|
|
2266
|
-
build: {
|
|
2267
|
-
...existingBuild,
|
|
2268
|
-
output: tempPath
|
|
2269
|
-
}
|
|
2270
|
-
};
|
|
2271
|
-
await bundle(configWithOutput, {
|
|
2485
|
+
await fs12.ensureDir(tempDir);
|
|
2486
|
+
const tempPath = path12.join(tempDir, "bundle.mjs");
|
|
2487
|
+
await bundle(configPath, {
|
|
2272
2488
|
cache: true,
|
|
2273
2489
|
verbose: options.verbose,
|
|
2274
|
-
silent: options.silent
|
|
2490
|
+
silent: options.silent,
|
|
2491
|
+
buildOverrides: {
|
|
2492
|
+
output: tempPath,
|
|
2493
|
+
format: "esm",
|
|
2494
|
+
platform: "node"
|
|
2495
|
+
}
|
|
2275
2496
|
});
|
|
2276
2497
|
return tempPath;
|
|
2277
2498
|
}
|
|
@@ -2325,9 +2546,9 @@ async function runCommand(mode, options) {
|
|
|
2325
2546
|
let flowPath = null;
|
|
2326
2547
|
if (mode === "collect") {
|
|
2327
2548
|
if (isPreBuilt) {
|
|
2328
|
-
flowPath =
|
|
2549
|
+
flowPath = path13.resolve(configPath);
|
|
2329
2550
|
if (!options.json && !options.silent) {
|
|
2330
|
-
logger.info(`\u{1F4E6} Using pre-built flow: ${
|
|
2551
|
+
logger.info(`\u{1F4E6} Using pre-built flow: ${path13.basename(flowPath)}`);
|
|
2331
2552
|
}
|
|
2332
2553
|
} else {
|
|
2333
2554
|
if (!options.json && !options.silent) {
|
|
@@ -2416,7 +2637,7 @@ async function run(mode, options) {
|
|
|
2416
2637
|
const isPreBuilt = isPreBuiltConfig(flowFile);
|
|
2417
2638
|
let flowPath;
|
|
2418
2639
|
if (isPreBuilt) {
|
|
2419
|
-
flowPath =
|
|
2640
|
+
flowPath = path13.resolve(flowFile);
|
|
2420
2641
|
} else {
|
|
2421
2642
|
flowPath = await prepareBundleForRun(flowFile, {
|
|
2422
2643
|
verbose: options.verbose,
|
|
@@ -2444,22 +2665,53 @@ async function run(mode, options) {
|
|
|
2444
2665
|
}
|
|
2445
2666
|
}
|
|
2446
2667
|
|
|
2668
|
+
// src/commands/cache.ts
|
|
2669
|
+
import fs13 from "fs-extra";
|
|
2670
|
+
import path14 from "path";
|
|
2671
|
+
var CACHE_DIR = path14.join(".tmp", "cache");
|
|
2672
|
+
function registerCacheCommand(program2) {
|
|
2673
|
+
const cache = program2.command("cache").description("Manage the CLI cache");
|
|
2674
|
+
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) => {
|
|
2675
|
+
if (options.packages) {
|
|
2676
|
+
await fs13.remove(path14.join(CACHE_DIR, "packages"));
|
|
2677
|
+
console.log("Package cache cleared");
|
|
2678
|
+
} else if (options.builds) {
|
|
2679
|
+
await fs13.remove(path14.join(CACHE_DIR, "builds"));
|
|
2680
|
+
console.log("Build cache cleared");
|
|
2681
|
+
} else {
|
|
2682
|
+
await fs13.remove(CACHE_DIR);
|
|
2683
|
+
console.log("All caches cleared");
|
|
2684
|
+
}
|
|
2685
|
+
});
|
|
2686
|
+
cache.command("info").description("Show cache statistics").action(async () => {
|
|
2687
|
+
const packagesDir = path14.join(CACHE_DIR, "packages");
|
|
2688
|
+
const buildsDir = path14.join(CACHE_DIR, "builds");
|
|
2689
|
+
const packageCount = await countEntries(packagesDir);
|
|
2690
|
+
const buildCount = await countEntries(buildsDir);
|
|
2691
|
+
console.log(`Cache directory: ${CACHE_DIR}`);
|
|
2692
|
+
console.log(`Cached packages: ${packageCount}`);
|
|
2693
|
+
console.log(`Cached builds: ${buildCount}`);
|
|
2694
|
+
});
|
|
2695
|
+
}
|
|
2696
|
+
async function countEntries(dir) {
|
|
2697
|
+
if (!await fs13.pathExists(dir)) return 0;
|
|
2698
|
+
const entries = await fs13.readdir(dir);
|
|
2699
|
+
return entries.length;
|
|
2700
|
+
}
|
|
2701
|
+
|
|
2447
2702
|
// src/index.ts
|
|
2448
|
-
var __filename =
|
|
2703
|
+
var __filename = fileURLToPath2(import.meta.url);
|
|
2449
2704
|
var __dirname = dirname(__filename);
|
|
2450
2705
|
var packageJson = JSON.parse(
|
|
2451
|
-
|
|
2706
|
+
readFileSync(join(__dirname, "../package.json"), "utf-8")
|
|
2452
2707
|
);
|
|
2453
2708
|
var VERSION = packageJson.version;
|
|
2454
2709
|
var program = new Command();
|
|
2455
2710
|
program.name("walkeros").description("walkerOS CLI - Bundle and deploy walkerOS components").version(VERSION);
|
|
2456
|
-
program.command("bundle [file]").description("Bundle NPM packages with custom code").option(
|
|
2457
|
-
"-e, --env <name>",
|
|
2458
|
-
"environment to build (for multi-environment configs)"
|
|
2459
|
-
).option("--all", "build all environments (for multi-environment 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) => {
|
|
2711
|
+
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
2712
|
await bundleCommand({
|
|
2461
2713
|
config: file || "bundle.config.json",
|
|
2462
|
-
|
|
2714
|
+
flow: options.flow,
|
|
2463
2715
|
all: options.all,
|
|
2464
2716
|
stats: options.stats,
|
|
2465
2717
|
json: options.json,
|
|
@@ -2487,11 +2739,11 @@ program.command("simulate [file]").description("Simulate event processing and ca
|
|
|
2487
2739
|
program.command("push [file]").description("Push an event through the flow with real API execution").requiredOption(
|
|
2488
2740
|
"-e, --event <source>",
|
|
2489
2741
|
"Event to push (JSON string, file path, or URL)"
|
|
2490
|
-
).option("--
|
|
2742
|
+
).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
2743
|
await pushCommand({
|
|
2492
2744
|
config: file || "bundle.config.json",
|
|
2493
2745
|
event: options.event,
|
|
2494
|
-
|
|
2746
|
+
flow: options.flow,
|
|
2495
2747
|
json: options.json,
|
|
2496
2748
|
verbose: options.verbose,
|
|
2497
2749
|
silent: options.silent,
|
|
@@ -2529,6 +2781,7 @@ runCmd.command("serve [file]").description(
|
|
|
2529
2781
|
silent: options.silent
|
|
2530
2782
|
});
|
|
2531
2783
|
});
|
|
2784
|
+
registerCacheCommand(program);
|
|
2532
2785
|
program.parse();
|
|
2533
2786
|
export {
|
|
2534
2787
|
bundle,
|