@walkeros/cli 0.5.1-next.1 → 0.6.1-next-1766186076625
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 +40 -0
- package/README.md +104 -36
- package/dist/index.d.ts +22 -13
- package/dist/index.js +852 -813
- package/dist/index.js.map +1 -1
- package/dist/runtime/main.d.ts +2 -0
- package/dist/runtime/main.js +269 -0
- package/dist/runtime/main.js.map +1 -0
- package/package.json +8 -5
- package/dist/__tests__/bundle/bundler-helpers.test.d.ts +0 -2
- package/dist/__tests__/bundle/bundler-helpers.test.d.ts.map +0 -1
- package/dist/__tests__/bundle/bundler-helpers.test.js +0 -151
- package/dist/__tests__/bundle/bundler-helpers.test.js.map +0 -1
- package/dist/__tests__/bundle/bundler.test.d.ts +0 -2
- package/dist/__tests__/bundle/bundler.test.d.ts.map +0 -1
- package/dist/__tests__/bundle/bundler.test.js +0 -353
- package/dist/__tests__/bundle/bundler.test.js.map +0 -1
- package/dist/__tests__/bundle/programmatic.test.d.ts +0 -2
- package/dist/__tests__/bundle/programmatic.test.d.ts.map +0 -1
- package/dist/__tests__/bundle/programmatic.test.js +0 -148
- package/dist/__tests__/bundle/programmatic.test.js.map +0 -1
- package/dist/__tests__/cli-e2e.test.d.ts +0 -8
- package/dist/__tests__/cli-e2e.test.d.ts.map +0 -1
- package/dist/__tests__/cli-e2e.test.js +0 -130
- package/dist/__tests__/cli-e2e.test.js.map +0 -1
- package/dist/__tests__/cli.test.d.ts +0 -2
- package/dist/__tests__/cli.test.d.ts.map +0 -1
- package/dist/__tests__/cli.test.js +0 -180
- package/dist/__tests__/cli.test.js.map +0 -1
- package/dist/__tests__/config-loader.test.d.ts +0 -7
- package/dist/__tests__/config-loader.test.d.ts.map +0 -1
- package/dist/__tests__/config-loader.test.js +0 -414
- package/dist/__tests__/config-loader.test.js.map +0 -1
- package/dist/__tests__/core/asset-resolver.test.d.ts +0 -2
- package/dist/__tests__/core/asset-resolver.test.d.ts.map +0 -1
- package/dist/__tests__/core/asset-resolver.test.js +0 -14
- package/dist/__tests__/core/asset-resolver.test.js.map +0 -1
- package/dist/__tests__/core/build-cache.test.d.ts +0 -2
- package/dist/__tests__/core/build-cache.test.d.ts.map +0 -1
- package/dist/__tests__/core/build-cache.test.js +0 -55
- package/dist/__tests__/core/build-cache.test.js.map +0 -1
- package/dist/__tests__/core/cache-utils.test.d.ts +0 -2
- package/dist/__tests__/core/cache-utils.test.d.ts.map +0 -1
- package/dist/__tests__/core/cache-utils.test.js +0 -70
- package/dist/__tests__/core/cache-utils.test.js.map +0 -1
- package/dist/__tests__/core/config.test.d.ts +0 -2
- package/dist/__tests__/core/config.test.d.ts.map +0 -1
- package/dist/__tests__/core/config.test.js +0 -72
- package/dist/__tests__/core/config.test.js.map +0 -1
- package/dist/__tests__/core/logger.test.d.ts +0 -2
- package/dist/__tests__/core/logger.test.d.ts.map +0 -1
- package/dist/__tests__/core/logger.test.js +0 -53
- package/dist/__tests__/core/logger.test.js.map +0 -1
- package/dist/__tests__/integration/bundle-run.integration.test.d.ts +0 -8
- package/dist/__tests__/integration/bundle-run.integration.test.d.ts.map +0 -1
- package/dist/__tests__/integration/bundle-run.integration.test.js +0 -54
- package/dist/__tests__/integration/bundle-run.integration.test.js.map +0 -1
- package/dist/__tests__/push/push.test.d.ts +0 -7
- package/dist/__tests__/push/push.test.d.ts.map +0 -1
- package/dist/__tests__/push/push.test.js +0 -197
- package/dist/__tests__/push/push.test.js.map +0 -1
- package/dist/__tests__/simulate/env-loader.test.d.ts +0 -2
- package/dist/__tests__/simulate/env-loader.test.d.ts.map +0 -1
- package/dist/__tests__/simulate/env-loader.test.js +0 -47
- package/dist/__tests__/simulate/env-loader.test.js.map +0 -1
- package/dist/__tests__/simulate/node-executor.test.d.ts +0 -5
- package/dist/__tests__/simulate/node-executor.test.d.ts.map +0 -1
- package/dist/__tests__/simulate/node-executor.test.js +0 -25
- package/dist/__tests__/simulate/node-executor.test.js.map +0 -1
- package/dist/__tests__/simulate/server-simulate.integration.test.d.ts +0 -5
- package/dist/__tests__/simulate/server-simulate.integration.test.d.ts.map +0 -1
- package/dist/__tests__/simulate/server-simulate.integration.test.js +0 -58
- package/dist/__tests__/simulate/server-simulate.integration.test.js.map +0 -1
- package/dist/__tests__/smoke/production.smoke.test.d.ts +0 -8
- package/dist/__tests__/smoke/production.smoke.test.d.ts.map +0 -1
- package/dist/__tests__/smoke/production.smoke.test.js +0 -65
- package/dist/__tests__/smoke/production.smoke.test.js.map +0 -1
- package/dist/commands/bundle/bundler.d.ts +0 -32
- package/dist/commands/bundle/bundler.d.ts.map +0 -1
- package/dist/commands/bundle/bundler.js +0 -583
- package/dist/commands/bundle/bundler.js.map +0 -1
- package/dist/commands/bundle/index.d.ts +0 -57
- package/dist/commands/bundle/index.d.ts.map +0 -1
- package/dist/commands/bundle/index.js +0 -200
- package/dist/commands/bundle/index.js.map +0 -1
- package/dist/commands/bundle/package-manager.d.ts +0 -8
- package/dist/commands/bundle/package-manager.d.ts.map +0 -1
- package/dist/commands/bundle/package-manager.js +0 -197
- package/dist/commands/bundle/package-manager.js.map +0 -1
- package/dist/commands/bundle/stats.d.ts +0 -23
- package/dist/commands/bundle/stats.d.ts.map +0 -1
- package/dist/commands/bundle/stats.js +0 -52
- package/dist/commands/bundle/stats.js.map +0 -1
- package/dist/commands/cache.d.ts +0 -3
- package/dist/commands/cache.d.ts.map +0 -1
- package/dist/commands/cache.js +0 -44
- package/dist/commands/cache.js.map +0 -1
- package/dist/commands/push/index.d.ts +0 -7
- package/dist/commands/push/index.d.ts.map +0 -1
- package/dist/commands/push/index.js +0 -257
- package/dist/commands/push/index.js.map +0 -1
- package/dist/commands/push/types.d.ts +0 -21
- package/dist/commands/push/types.d.ts.map +0 -1
- package/dist/commands/push/types.js +0 -2
- package/dist/commands/push/types.js.map +0 -1
- package/dist/commands/run/__tests__/run.integration.test.d.ts +0 -8
- package/dist/commands/run/__tests__/run.integration.test.d.ts.map +0 -1
- package/dist/commands/run/__tests__/run.integration.test.js +0 -52
- package/dist/commands/run/__tests__/run.integration.test.js.map +0 -1
- package/dist/commands/run/__tests__/validators.test.d.ts +0 -2
- package/dist/commands/run/__tests__/validators.test.d.ts.map +0 -1
- package/dist/commands/run/__tests__/validators.test.js +0 -80
- package/dist/commands/run/__tests__/validators.test.js.map +0 -1
- package/dist/commands/run/execution.d.ts +0 -14
- package/dist/commands/run/execution.d.ts.map +0 -1
- package/dist/commands/run/execution.js +0 -41
- package/dist/commands/run/execution.js.map +0 -1
- package/dist/commands/run/index.d.ts +0 -39
- package/dist/commands/run/index.d.ts.map +0 -1
- package/dist/commands/run/index.js +0 -191
- package/dist/commands/run/index.js.map +0 -1
- package/dist/commands/run/types.d.ts +0 -60
- package/dist/commands/run/types.d.ts.map +0 -1
- package/dist/commands/run/types.js +0 -7
- package/dist/commands/run/types.js.map +0 -1
- package/dist/commands/run/utils.d.ts +0 -29
- package/dist/commands/run/utils.d.ts.map +0 -1
- package/dist/commands/run/utils.js +0 -52
- package/dist/commands/run/utils.js.map +0 -1
- package/dist/commands/run/validators.d.ts +0 -33
- package/dist/commands/run/validators.d.ts.map +0 -1
- package/dist/commands/run/validators.js +0 -58
- package/dist/commands/run/validators.js.map +0 -1
- package/dist/commands/simulate/env-loader.d.ts +0 -19
- package/dist/commands/simulate/env-loader.d.ts.map +0 -1
- package/dist/commands/simulate/env-loader.js +0 -46
- package/dist/commands/simulate/env-loader.js.map +0 -1
- package/dist/commands/simulate/index.d.ts +0 -48
- package/dist/commands/simulate/index.d.ts.map +0 -1
- package/dist/commands/simulate/index.js +0 -116
- package/dist/commands/simulate/index.js.map +0 -1
- package/dist/commands/simulate/jsdom-executor.d.ts +0 -37
- package/dist/commands/simulate/jsdom-executor.d.ts.map +0 -1
- package/dist/commands/simulate/jsdom-executor.js +0 -137
- package/dist/commands/simulate/jsdom-executor.js.map +0 -1
- package/dist/commands/simulate/node-executor.d.ts +0 -28
- package/dist/commands/simulate/node-executor.d.ts.map +0 -1
- package/dist/commands/simulate/node-executor.js +0 -94
- package/dist/commands/simulate/node-executor.js.map +0 -1
- package/dist/commands/simulate/simulator.d.ts +0 -14
- package/dist/commands/simulate/simulator.d.ts.map +0 -1
- package/dist/commands/simulate/simulator.js +0 -162
- package/dist/commands/simulate/simulator.js.map +0 -1
- package/dist/commands/simulate/tracker.d.ts +0 -30
- package/dist/commands/simulate/tracker.d.ts.map +0 -1
- package/dist/commands/simulate/tracker.js +0 -96
- package/dist/commands/simulate/tracker.js.map +0 -1
- package/dist/commands/simulate/types.d.ts +0 -18
- package/dist/commands/simulate/types.d.ts.map +0 -1
- package/dist/commands/simulate/types.js +0 -2
- package/dist/commands/simulate/types.js.map +0 -1
- package/dist/config/build-defaults.d.ts +0 -49
- package/dist/config/build-defaults.d.ts.map +0 -1
- package/dist/config/build-defaults.js +0 -70
- package/dist/config/build-defaults.js.map +0 -1
- package/dist/config/index.d.ts +0 -13
- package/dist/config/index.d.ts.map +0 -1
- package/dist/config/index.js +0 -15
- package/dist/config/index.js.map +0 -1
- package/dist/config/loader.d.ts +0 -81
- package/dist/config/loader.d.ts.map +0 -1
- package/dist/config/loader.js +0 -155
- package/dist/config/loader.js.map +0 -1
- package/dist/config/utils.d.ts +0 -114
- package/dist/config/utils.d.ts.map +0 -1
- package/dist/config/utils.js +0 -257
- package/dist/config/utils.js.map +0 -1
- package/dist/config/validators.d.ts +0 -52
- package/dist/config/validators.d.ts.map +0 -1
- package/dist/config/validators.js +0 -85
- package/dist/config/validators.js.map +0 -1
- package/dist/core/asset-resolver.d.ts +0 -34
- package/dist/core/asset-resolver.d.ts.map +0 -1
- package/dist/core/asset-resolver.js +0 -70
- package/dist/core/asset-resolver.js.map +0 -1
- package/dist/core/build-cache.d.ts +0 -23
- package/dist/core/build-cache.d.ts.map +0 -1
- package/dist/core/build-cache.js +0 -43
- package/dist/core/build-cache.js.map +0 -1
- package/dist/core/cache-utils.d.ts +0 -27
- package/dist/core/cache-utils.d.ts.map +0 -1
- package/dist/core/cache-utils.js +0 -60
- package/dist/core/cache-utils.js.map +0 -1
- package/dist/core/docker.d.ts +0 -99
- package/dist/core/docker.d.ts.map +0 -1
- package/dist/core/docker.js +0 -253
- package/dist/core/docker.js.map +0 -1
- package/dist/core/execution.d.ts +0 -34
- package/dist/core/execution.d.ts.map +0 -1
- package/dist/core/execution.js +0 -64
- package/dist/core/execution.js.map +0 -1
- package/dist/core/index.d.ts +0 -10
- package/dist/core/index.d.ts.map +0 -1
- package/dist/core/index.js +0 -10
- package/dist/core/index.js.map +0 -1
- package/dist/core/local-packages.d.ts +0 -19
- package/dist/core/local-packages.d.ts.map +0 -1
- package/dist/core/local-packages.js +0 -60
- package/dist/core/local-packages.js.map +0 -1
- package/dist/core/logger.d.ts +0 -28
- package/dist/core/logger.d.ts.map +0 -1
- package/dist/core/logger.js +0 -88
- package/dist/core/logger.js.map +0 -1
- package/dist/core/output.d.ts +0 -30
- package/dist/core/output.d.ts.map +0 -1
- package/dist/core/output.js +0 -46
- package/dist/core/output.js.map +0 -1
- package/dist/core/temp-manager.d.ts +0 -51
- package/dist/core/temp-manager.d.ts.map +0 -1
- package/dist/core/temp-manager.js +0 -73
- package/dist/core/temp-manager.js.map +0 -1
- package/dist/core/timer.d.ts +0 -14
- package/dist/core/timer.d.ts.map +0 -1
- package/dist/core/timer.js +0 -29
- package/dist/core/timer.js.map +0 -1
- package/dist/core/utils.d.ts +0 -10
- package/dist/core/utils.d.ts.map +0 -1
- package/dist/core/utils.js +0 -12
- package/dist/core/utils.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/schemas/index.d.ts +0 -9
- package/dist/schemas/index.d.ts.map +0 -1
- package/dist/schemas/index.js +0 -9
- package/dist/schemas/index.js.map +0 -1
- package/dist/schemas/primitives.d.ts +0 -37
- package/dist/schemas/primitives.d.ts.map +0 -1
- package/dist/schemas/primitives.js +0 -43
- package/dist/schemas/primitives.js.map +0 -1
- package/dist/schemas/run.d.ts +0 -23
- package/dist/schemas/run.d.ts.map +0 -1
- package/dist/schemas/run.js +0 -20
- package/dist/schemas/run.js.map +0 -1
- package/dist/types/bundle.d.ts +0 -141
- package/dist/types/bundle.d.ts.map +0 -1
- package/dist/types/bundle.js +0 -10
- package/dist/types/bundle.js.map +0 -1
- package/dist/types/global.d.ts +0 -51
- package/dist/types/global.d.ts.map +0 -1
- package/dist/types/global.js +0 -30
- package/dist/types/global.js.map +0 -1
- package/dist/types/index.d.ts +0 -8
- package/dist/types/index.d.ts.map +0 -1
- package/dist/types/index.js +0 -8
- package/dist/types/index.js.map +0 -1
- package/dist/walker.js +0 -1
package/dist/index.js
CHANGED
|
@@ -2,81 +2,100 @@
|
|
|
2
2
|
|
|
3
3
|
// src/index.ts
|
|
4
4
|
import { Command } from "commander";
|
|
5
|
+
import chalk2 from "chalk";
|
|
6
|
+
|
|
7
|
+
// src/version.ts
|
|
5
8
|
import { readFileSync } from "fs";
|
|
6
|
-
import { fileURLToPath
|
|
9
|
+
import { fileURLToPath } from "url";
|
|
7
10
|
import { dirname, join } from "path";
|
|
8
|
-
|
|
11
|
+
var versionFilename = fileURLToPath(import.meta.url);
|
|
12
|
+
var versionDirname = dirname(versionFilename);
|
|
13
|
+
function findPackageJson() {
|
|
14
|
+
const paths = [
|
|
15
|
+
join(versionDirname, "../package.json"),
|
|
16
|
+
// dist/ or src/
|
|
17
|
+
join(versionDirname, "../../package.json")
|
|
18
|
+
// src/core/ (not used, but safe)
|
|
19
|
+
];
|
|
20
|
+
for (const p of paths) {
|
|
21
|
+
try {
|
|
22
|
+
return readFileSync(p, "utf-8");
|
|
23
|
+
} catch {
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
return JSON.stringify({ version: "0.0.0" });
|
|
27
|
+
}
|
|
28
|
+
var VERSION = JSON.parse(findPackageJson()).version;
|
|
9
29
|
|
|
10
30
|
// src/commands/bundle/index.ts
|
|
11
31
|
import path9 from "path";
|
|
12
32
|
|
|
13
33
|
// src/core/logger.ts
|
|
14
34
|
import chalk from "chalk";
|
|
35
|
+
var BRAND_COLOR = "#01b5e2";
|
|
15
36
|
function createLogger(options = {}) {
|
|
16
37
|
const { verbose = false, silent = false, json = false } = options;
|
|
17
38
|
const shouldLog = !silent && !json;
|
|
18
39
|
const shouldDebug = verbose && !silent && !json;
|
|
19
40
|
return {
|
|
20
|
-
log: (
|
|
41
|
+
log: (...args) => {
|
|
21
42
|
if (shouldLog) {
|
|
22
43
|
const message = args.map((arg) => String(arg)).join(" ");
|
|
23
|
-
|
|
24
|
-
red: chalk.red,
|
|
25
|
-
green: chalk.green,
|
|
26
|
-
blue: chalk.blue,
|
|
27
|
-
yellow: chalk.yellow,
|
|
28
|
-
gray: chalk.gray,
|
|
29
|
-
grey: chalk.gray,
|
|
30
|
-
cyan: chalk.cyan,
|
|
31
|
-
magenta: chalk.magenta,
|
|
32
|
-
white: chalk.white,
|
|
33
|
-
black: chalk.black
|
|
34
|
-
};
|
|
35
|
-
const colorFn = colorMap[color];
|
|
36
|
-
const coloredMessage = colorFn ? colorFn(message) : message;
|
|
37
|
-
console.log(coloredMessage);
|
|
44
|
+
console.log(message);
|
|
38
45
|
}
|
|
39
46
|
},
|
|
40
|
-
|
|
47
|
+
brand: (...args) => {
|
|
41
48
|
if (shouldLog) {
|
|
42
49
|
const message = args.map((arg) => String(arg)).join(" ");
|
|
43
|
-
console.log(chalk.
|
|
50
|
+
console.log(chalk.hex(BRAND_COLOR)(message));
|
|
44
51
|
}
|
|
45
52
|
},
|
|
46
|
-
|
|
47
|
-
if (
|
|
53
|
+
error: (...args) => {
|
|
54
|
+
if (!json) {
|
|
48
55
|
const message = args.map((arg) => String(arg)).join(" ");
|
|
49
|
-
console.
|
|
56
|
+
console.error(chalk.red(message));
|
|
50
57
|
}
|
|
51
58
|
},
|
|
52
|
-
|
|
59
|
+
debug: (...args) => {
|
|
60
|
+
if (shouldDebug) {
|
|
61
|
+
const message = args.map((arg) => String(arg)).join(" ");
|
|
62
|
+
console.log(` ${message}`);
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
json: (data) => {
|
|
66
|
+
if (!silent) {
|
|
67
|
+
console.log(JSON.stringify(data, null, 2));
|
|
68
|
+
}
|
|
69
|
+
},
|
|
70
|
+
// Backward-compatible methods (all use default terminal color per design)
|
|
71
|
+
info: (...args) => {
|
|
53
72
|
if (shouldLog) {
|
|
54
73
|
const message = args.map((arg) => String(arg)).join(" ");
|
|
55
|
-
console.log(
|
|
74
|
+
console.log(message);
|
|
56
75
|
}
|
|
57
76
|
},
|
|
58
|
-
|
|
77
|
+
success: (...args) => {
|
|
59
78
|
if (shouldLog) {
|
|
60
79
|
const message = args.map((arg) => String(arg)).join(" ");
|
|
61
|
-
console.log(
|
|
80
|
+
console.log(message);
|
|
62
81
|
}
|
|
63
82
|
},
|
|
64
|
-
|
|
65
|
-
if (
|
|
83
|
+
warning: (...args) => {
|
|
84
|
+
if (shouldLog) {
|
|
66
85
|
const message = args.map((arg) => String(arg)).join(" ");
|
|
67
|
-
console.
|
|
86
|
+
console.log(message);
|
|
68
87
|
}
|
|
69
88
|
},
|
|
70
|
-
|
|
71
|
-
if (
|
|
89
|
+
warn: (...args) => {
|
|
90
|
+
if (shouldLog) {
|
|
72
91
|
const message = args.map((arg) => String(arg)).join(" ");
|
|
73
|
-
console.log(
|
|
92
|
+
console.log(message);
|
|
74
93
|
}
|
|
75
94
|
},
|
|
76
95
|
gray: (...args) => {
|
|
77
96
|
if (shouldLog) {
|
|
78
97
|
const message = args.map((arg) => String(arg)).join(" ");
|
|
79
|
-
console.log(
|
|
98
|
+
console.log(message);
|
|
80
99
|
}
|
|
81
100
|
}
|
|
82
101
|
};
|
|
@@ -89,6 +108,23 @@ function createCommandLogger(options) {
|
|
|
89
108
|
});
|
|
90
109
|
}
|
|
91
110
|
|
|
111
|
+
// src/core/collector-logger.ts
|
|
112
|
+
function createCollectorLoggerConfig(cliLogger, verbose) {
|
|
113
|
+
return {
|
|
114
|
+
level: verbose ? "DEBUG" : "ERROR",
|
|
115
|
+
handler: (level, message, context, scope) => {
|
|
116
|
+
const scopePath = scope.length > 0 ? `[${scope.join(":")}] ` : "";
|
|
117
|
+
const hasContext = Object.keys(context).length > 0;
|
|
118
|
+
const contextStr = hasContext ? ` ${JSON.stringify(context)}` : "";
|
|
119
|
+
if (level === 0) {
|
|
120
|
+
cliLogger.error(`${scopePath}${message}${contextStr}`);
|
|
121
|
+
} else if (verbose) {
|
|
122
|
+
cliLogger.debug(`${scopePath}${message}${contextStr}`);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
|
|
92
128
|
// src/core/timer.ts
|
|
93
129
|
function createTimer() {
|
|
94
130
|
let startTime = 0;
|
|
@@ -132,15 +168,26 @@ function formatBytes(bytes) {
|
|
|
132
168
|
return (bytes / 1024).toFixed(2);
|
|
133
169
|
}
|
|
134
170
|
|
|
135
|
-
// src/core/
|
|
136
|
-
import
|
|
137
|
-
|
|
138
|
-
|
|
171
|
+
// src/core/tmp.ts
|
|
172
|
+
import path from "path";
|
|
173
|
+
var DEFAULT_TMP_ROOT = ".tmp";
|
|
174
|
+
function getTmpPath(tmpDir, ...segments) {
|
|
175
|
+
const root = tmpDir || DEFAULT_TMP_ROOT;
|
|
176
|
+
const absoluteRoot = path.isAbsolute(root) ? root : path.resolve(root);
|
|
177
|
+
return path.join(absoluteRoot, ...segments);
|
|
178
|
+
}
|
|
179
|
+
function getDefaultTmpRoot() {
|
|
180
|
+
return DEFAULT_TMP_ROOT;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// src/core/asset-resolver.ts
|
|
184
|
+
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
185
|
+
import { existsSync } from "fs";
|
|
186
|
+
import path3 from "path";
|
|
139
187
|
|
|
140
188
|
// src/config/utils.ts
|
|
141
189
|
import fs from "fs-extra";
|
|
142
|
-
import
|
|
143
|
-
import os from "os";
|
|
190
|
+
import path2 from "path";
|
|
144
191
|
function isUrl(str) {
|
|
145
192
|
try {
|
|
146
193
|
const url = new URL(str);
|
|
@@ -161,12 +208,9 @@ async function downloadFromUrl(url) {
|
|
|
161
208
|
);
|
|
162
209
|
}
|
|
163
210
|
const content = await response.text();
|
|
164
|
-
const
|
|
165
|
-
|
|
166
|
-
const
|
|
167
|
-
const randomId = Math.random().toString(36).substring(2, 11);
|
|
168
|
-
const filename = `walkeros-download-${Date.now()}-${randomId}${extension}`;
|
|
169
|
-
const tempPath = path.join(os.tmpdir(), filename);
|
|
211
|
+
const downloadsDir = getTmpPath(void 0, "downloads");
|
|
212
|
+
await fs.ensureDir(downloadsDir);
|
|
213
|
+
const tempPath = path2.join(downloadsDir, "flow.json");
|
|
170
214
|
await fs.writeFile(tempPath, content, "utf-8");
|
|
171
215
|
return tempPath;
|
|
172
216
|
} catch (error) {
|
|
@@ -183,7 +227,7 @@ async function loadJsonConfig(configPath) {
|
|
|
183
227
|
absolutePath = await downloadFromUrl(configPath);
|
|
184
228
|
isTemporary = true;
|
|
185
229
|
} else {
|
|
186
|
-
absolutePath =
|
|
230
|
+
absolutePath = path2.resolve(configPath);
|
|
187
231
|
if (!await fs.pathExists(absolutePath)) {
|
|
188
232
|
throw new Error(`Configuration file not found: ${absolutePath}`);
|
|
189
233
|
}
|
|
@@ -204,11 +248,6 @@ async function loadJsonConfig(configPath) {
|
|
|
204
248
|
}
|
|
205
249
|
}
|
|
206
250
|
}
|
|
207
|
-
function getTempDir(tempDir = ".tmp") {
|
|
208
|
-
const randomId = Math.random().toString(36).substring(2, 11);
|
|
209
|
-
const basePath = path.isAbsolute(tempDir) ? tempDir : path.join(process.cwd(), tempDir);
|
|
210
|
-
return path.join(basePath, `cli-${Date.now()}-${randomId}`);
|
|
211
|
-
}
|
|
212
251
|
async function loadJsonFromSource(source, options) {
|
|
213
252
|
const paramName = options?.name || "input";
|
|
214
253
|
if (!source || source.trim() === "") {
|
|
@@ -239,7 +278,7 @@ async function loadJsonFromSource(source, options) {
|
|
|
239
278
|
);
|
|
240
279
|
}
|
|
241
280
|
}
|
|
242
|
-
const resolvedPath =
|
|
281
|
+
const resolvedPath = path2.resolve(trimmedSource);
|
|
243
282
|
if (await fs.pathExists(resolvedPath)) {
|
|
244
283
|
try {
|
|
245
284
|
const data = await fs.readJson(resolvedPath);
|
|
@@ -263,193 +302,11 @@ async function loadJsonFromSource(source, options) {
|
|
|
263
302
|
}
|
|
264
303
|
}
|
|
265
304
|
|
|
266
|
-
// src/core/docker.ts
|
|
267
|
-
var CLI_VERSION = true ? "0.5.1-next.0" : "0.0.0";
|
|
268
|
-
var CLI_DOCKER_IMAGE = process.env.WALKEROS_CLI_DOCKER_IMAGE || `walkeros/cli:${CLI_VERSION}`;
|
|
269
|
-
var RUNTIME_DOCKER_IMAGE = process.env.WALKEROS_RUNTIME_DOCKER_IMAGE || `walkeros/docker:${DOCKER_VERSION}`;
|
|
270
|
-
function buildCommonDockerArgs(options) {
|
|
271
|
-
const args = [options.config];
|
|
272
|
-
if (options.json) args.push("--json");
|
|
273
|
-
if (options.verbose) args.push("--verbose");
|
|
274
|
-
if (options.silent) args.push("--silent");
|
|
275
|
-
return args;
|
|
276
|
-
}
|
|
277
|
-
function buildDockerCommand(command, args, options = {}, configFile) {
|
|
278
|
-
const cwd = process.cwd();
|
|
279
|
-
const cmd = ["docker", "run", "--rm"];
|
|
280
|
-
if (configFile && !isUrl(configFile)) {
|
|
281
|
-
const configPath = path2.resolve(cwd, configFile);
|
|
282
|
-
cmd.push("-v", `${configPath}:/config/flow.json:ro`);
|
|
283
|
-
args = args.map((arg) => arg === configFile ? "/config/flow.json" : arg);
|
|
284
|
-
}
|
|
285
|
-
cmd.push("-v", `${cwd}:/workspace`);
|
|
286
|
-
cmd.push("-w", "/workspace");
|
|
287
|
-
if (process.platform !== "win32") {
|
|
288
|
-
try {
|
|
289
|
-
const uid = process.getuid?.();
|
|
290
|
-
const gid = process.getgid?.();
|
|
291
|
-
if (uid !== void 0 && gid !== void 0) {
|
|
292
|
-
cmd.push("--user", `${uid}:${gid}`);
|
|
293
|
-
}
|
|
294
|
-
} catch {
|
|
295
|
-
}
|
|
296
|
-
}
|
|
297
|
-
if (options.verbose) {
|
|
298
|
-
cmd.push("-e", "VERBOSE=true");
|
|
299
|
-
}
|
|
300
|
-
if (options.silent) {
|
|
301
|
-
cmd.push("-e", "SILENT=true");
|
|
302
|
-
}
|
|
303
|
-
cmd.push(CLI_DOCKER_IMAGE);
|
|
304
|
-
cmd.push(command, ...args);
|
|
305
|
-
return cmd;
|
|
306
|
-
}
|
|
307
|
-
async function executeInDocker(command, args, options = {}, configFile) {
|
|
308
|
-
const containerArgs = [...args, "--local"];
|
|
309
|
-
const dockerCmd = buildDockerCommand(
|
|
310
|
-
command,
|
|
311
|
-
containerArgs,
|
|
312
|
-
options,
|
|
313
|
-
configFile
|
|
314
|
-
);
|
|
315
|
-
return new Promise((resolve, reject) => {
|
|
316
|
-
const proc = spawn(dockerCmd[0], dockerCmd.slice(1), {
|
|
317
|
-
stdio: options.silent ? "ignore" : "inherit",
|
|
318
|
-
shell: false
|
|
319
|
-
});
|
|
320
|
-
proc.on("error", (error) => {
|
|
321
|
-
reject(new Error(`Docker execution failed: ${error.message}`));
|
|
322
|
-
});
|
|
323
|
-
proc.on("exit", (code) => {
|
|
324
|
-
if (code === 0) {
|
|
325
|
-
resolve();
|
|
326
|
-
} else {
|
|
327
|
-
process.exit(code || 1);
|
|
328
|
-
}
|
|
329
|
-
});
|
|
330
|
-
});
|
|
331
|
-
}
|
|
332
|
-
async function isDockerAvailable() {
|
|
333
|
-
return new Promise((resolve) => {
|
|
334
|
-
const proc = spawn("docker", ["--version"], {
|
|
335
|
-
stdio: "ignore"
|
|
336
|
-
});
|
|
337
|
-
proc.on("error", () => resolve(false));
|
|
338
|
-
proc.on("exit", (code) => resolve(code === 0));
|
|
339
|
-
});
|
|
340
|
-
}
|
|
341
|
-
function buildDockerRunCommand(mode, flowPath, options = {}) {
|
|
342
|
-
const cwd = process.cwd();
|
|
343
|
-
const cmd = ["docker", "run", "--rm"];
|
|
344
|
-
cmd.push("-e", `MODE=${mode}`);
|
|
345
|
-
if (mode === "collect" && flowPath) {
|
|
346
|
-
const absoluteFlowPath = path2.resolve(cwd, flowPath);
|
|
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}`);
|
|
351
|
-
}
|
|
352
|
-
if (mode === "serve" && flowPath) {
|
|
353
|
-
const absoluteFilePath = path2.resolve(cwd, flowPath);
|
|
354
|
-
cmd.push("-v", `${absoluteFilePath}:/app/bundle.mjs:ro`);
|
|
355
|
-
cmd.push("-e", "FILE_PATH=/app/bundle.mjs");
|
|
356
|
-
}
|
|
357
|
-
const port = options.port !== void 0 ? options.port : 8080;
|
|
358
|
-
cmd.push("-p", `${port}:${port}`);
|
|
359
|
-
cmd.push("-e", `PORT=${port}`);
|
|
360
|
-
if (options.host) {
|
|
361
|
-
cmd.push("-e", `HOST=${options.host}`);
|
|
362
|
-
}
|
|
363
|
-
if (options.serveName) {
|
|
364
|
-
cmd.push("-e", `SERVE_NAME=${options.serveName}`);
|
|
365
|
-
}
|
|
366
|
-
if (options.servePath) {
|
|
367
|
-
cmd.push("-e", `SERVE_PATH=${options.servePath}`);
|
|
368
|
-
}
|
|
369
|
-
if (process.platform !== "win32") {
|
|
370
|
-
try {
|
|
371
|
-
const uid = process.getuid?.();
|
|
372
|
-
const gid = process.getgid?.();
|
|
373
|
-
if (uid !== void 0 && gid !== void 0) {
|
|
374
|
-
cmd.push("--user", `${uid}:${gid}`);
|
|
375
|
-
}
|
|
376
|
-
} catch {
|
|
377
|
-
}
|
|
378
|
-
}
|
|
379
|
-
cmd.push(RUNTIME_DOCKER_IMAGE);
|
|
380
|
-
return cmd;
|
|
381
|
-
}
|
|
382
|
-
async function executeRunInDocker(mode, flowPath, options = {}) {
|
|
383
|
-
const dockerCmd = buildDockerRunCommand(mode, flowPath, options);
|
|
384
|
-
return new Promise((resolve, reject) => {
|
|
385
|
-
const proc = spawn(dockerCmd[0], dockerCmd.slice(1), {
|
|
386
|
-
stdio: options.silent ? "ignore" : "inherit",
|
|
387
|
-
shell: false
|
|
388
|
-
});
|
|
389
|
-
proc.on("error", (error) => {
|
|
390
|
-
reject(new Error(`Docker execution failed: ${error.message}`));
|
|
391
|
-
});
|
|
392
|
-
proc.on("exit", (code) => {
|
|
393
|
-
if (code === 0) {
|
|
394
|
-
resolve();
|
|
395
|
-
} else {
|
|
396
|
-
process.exit(code || 1);
|
|
397
|
-
}
|
|
398
|
-
});
|
|
399
|
-
});
|
|
400
|
-
}
|
|
401
|
-
|
|
402
|
-
// src/core/execution.ts
|
|
403
|
-
function getExecutionMode(options) {
|
|
404
|
-
if (options.local || process.env.WALKEROS_CONTAINER === "true") {
|
|
405
|
-
return "local";
|
|
406
|
-
}
|
|
407
|
-
return "docker";
|
|
408
|
-
}
|
|
409
|
-
async function executeCommand(localHandler, dockerCommand, dockerArgs, options, logger2, configFile) {
|
|
410
|
-
const mode = getExecutionMode(options);
|
|
411
|
-
if (options.dryRun) {
|
|
412
|
-
if (mode === "docker") {
|
|
413
|
-
const cmd = `docker run walkeros/cli:latest ${dockerCommand} ${dockerArgs.join(" ")}`;
|
|
414
|
-
logger2?.info(`[DRY-RUN] Would execute: ${cmd}`);
|
|
415
|
-
} else {
|
|
416
|
-
logger2?.info(
|
|
417
|
-
`[DRY-RUN] Would execute locally: ${dockerCommand} ${dockerArgs.join(" ")}`
|
|
418
|
-
);
|
|
419
|
-
}
|
|
420
|
-
return;
|
|
421
|
-
}
|
|
422
|
-
if (mode === "local") {
|
|
423
|
-
if (logger2 && !options.silent) {
|
|
424
|
-
logger2.info("\u{1F5A5}\uFE0F Executing locally...");
|
|
425
|
-
}
|
|
426
|
-
await localHandler();
|
|
427
|
-
} else {
|
|
428
|
-
const dockerAvailable = await isDockerAvailable();
|
|
429
|
-
if (!dockerAvailable) {
|
|
430
|
-
throw new Error(
|
|
431
|
-
"Docker is not available. Please install Docker or use --local flag to execute locally."
|
|
432
|
-
);
|
|
433
|
-
}
|
|
434
|
-
if (logger2 && !options.silent) {
|
|
435
|
-
logger2.info("\u{1F433} Executing in Docker container...");
|
|
436
|
-
}
|
|
437
|
-
await executeInDocker(dockerCommand, dockerArgs, options, configFile);
|
|
438
|
-
}
|
|
439
|
-
}
|
|
440
|
-
|
|
441
|
-
// src/core/temp-manager.ts
|
|
442
|
-
import { getHashServer } from "@walkeros/server-core";
|
|
443
|
-
import fs2 from "fs-extra";
|
|
444
|
-
|
|
445
305
|
// src/core/asset-resolver.ts
|
|
446
|
-
import { fileURLToPath } from "url";
|
|
447
|
-
import { existsSync } from "fs";
|
|
448
|
-
import path3 from "path";
|
|
449
306
|
var cachedAssetDir;
|
|
450
307
|
function getAssetDir() {
|
|
451
308
|
if (cachedAssetDir) return cachedAssetDir;
|
|
452
|
-
const currentFile =
|
|
309
|
+
const currentFile = fileURLToPath2(import.meta.url);
|
|
453
310
|
let dir = path3.dirname(currentFile);
|
|
454
311
|
while (dir !== path3.dirname(dir)) {
|
|
455
312
|
if (existsSync(path3.join(dir, "examples"))) {
|
|
@@ -482,22 +339,22 @@ function getErrorMessage(error) {
|
|
|
482
339
|
|
|
483
340
|
// src/core/local-packages.ts
|
|
484
341
|
import path4 from "path";
|
|
485
|
-
import
|
|
342
|
+
import fs2 from "fs-extra";
|
|
486
343
|
async function resolveLocalPackage(packageName, localPath, configDir, logger2) {
|
|
487
344
|
const absolutePath = path4.isAbsolute(localPath) ? localPath : path4.resolve(configDir, localPath);
|
|
488
|
-
if (!await
|
|
345
|
+
if (!await fs2.pathExists(absolutePath)) {
|
|
489
346
|
throw new Error(
|
|
490
347
|
`Local package path not found: ${localPath} (resolved to ${absolutePath})`
|
|
491
348
|
);
|
|
492
349
|
}
|
|
493
350
|
const pkgJsonPath = path4.join(absolutePath, "package.json");
|
|
494
|
-
if (!await
|
|
351
|
+
if (!await fs2.pathExists(pkgJsonPath)) {
|
|
495
352
|
throw new Error(
|
|
496
353
|
`No package.json found at ${absolutePath}. Is this a valid package directory?`
|
|
497
354
|
);
|
|
498
355
|
}
|
|
499
356
|
const distPath = path4.join(absolutePath, "dist");
|
|
500
|
-
const hasDistFolder = await
|
|
357
|
+
const hasDistFolder = await fs2.pathExists(distPath);
|
|
501
358
|
if (!hasDistFolder) {
|
|
502
359
|
logger2.warn(
|
|
503
360
|
`\u26A0\uFE0F ${packageName}: No dist/ folder found. Using package root.`
|
|
@@ -512,18 +369,18 @@ async function resolveLocalPackage(packageName, localPath, configDir, logger2) {
|
|
|
512
369
|
}
|
|
513
370
|
async function copyLocalPackage(localPkg, targetDir, logger2) {
|
|
514
371
|
const packageDir = path4.join(targetDir, "node_modules", localPkg.name);
|
|
515
|
-
await
|
|
516
|
-
await
|
|
372
|
+
await fs2.ensureDir(path4.dirname(packageDir));
|
|
373
|
+
await fs2.copy(
|
|
517
374
|
path4.join(localPkg.absolutePath, "package.json"),
|
|
518
375
|
path4.join(packageDir, "package.json")
|
|
519
376
|
);
|
|
520
377
|
if (localPkg.hasDistFolder) {
|
|
521
|
-
await
|
|
378
|
+
await fs2.copy(localPkg.distPath, path4.join(packageDir, "dist"));
|
|
522
379
|
} else {
|
|
523
|
-
const entries = await
|
|
380
|
+
const entries = await fs2.readdir(localPkg.absolutePath);
|
|
524
381
|
for (const entry of entries) {
|
|
525
382
|
if (!["node_modules", ".turbo", ".git"].includes(entry)) {
|
|
526
|
-
await
|
|
383
|
+
await fs2.copy(
|
|
527
384
|
path4.join(localPkg.absolutePath, entry),
|
|
528
385
|
path4.join(packageDir, entry)
|
|
529
386
|
);
|
|
@@ -534,6 +391,33 @@ async function copyLocalPackage(localPkg, targetDir, logger2) {
|
|
|
534
391
|
return packageDir;
|
|
535
392
|
}
|
|
536
393
|
|
|
394
|
+
// src/core/input-detector.ts
|
|
395
|
+
import fs3 from "fs-extra";
|
|
396
|
+
async function detectInput(inputPath, platformOverride) {
|
|
397
|
+
const content = await loadContent(inputPath);
|
|
398
|
+
try {
|
|
399
|
+
JSON.parse(content);
|
|
400
|
+
return { type: "config", content };
|
|
401
|
+
} catch {
|
|
402
|
+
const platform = platformOverride ?? detectPlatformFromPath(inputPath);
|
|
403
|
+
return { type: "bundle", content, platform };
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
function detectPlatformFromPath(inputPath) {
|
|
407
|
+
const cleanPath = inputPath.split("?")[0];
|
|
408
|
+
return cleanPath.endsWith(".mjs") ? "server" : "web";
|
|
409
|
+
}
|
|
410
|
+
async function loadContent(inputPath) {
|
|
411
|
+
if (isUrl(inputPath)) {
|
|
412
|
+
const response = await fetch(inputPath);
|
|
413
|
+
if (!response.ok) {
|
|
414
|
+
throw new Error(`Failed to fetch ${inputPath}: ${response.status}`);
|
|
415
|
+
}
|
|
416
|
+
return response.text();
|
|
417
|
+
}
|
|
418
|
+
return fs3.readFile(inputPath, "utf8");
|
|
419
|
+
}
|
|
420
|
+
|
|
537
421
|
// src/config/validators.ts
|
|
538
422
|
import { schemas } from "@walkeros/core/dev";
|
|
539
423
|
var { safeParseSetup } = schemas;
|
|
@@ -544,8 +428,8 @@ function validateFlowSetup(data) {
|
|
|
544
428
|
const result = safeParseSetup(data);
|
|
545
429
|
if (!result.success) {
|
|
546
430
|
const errors = result.error.issues.map((issue) => {
|
|
547
|
-
const
|
|
548
|
-
return ` - ${
|
|
431
|
+
const path14 = issue.path.length > 0 ? issue.path.map(String).join(".") : "root";
|
|
432
|
+
return ` - ${path14}: ${issue.message}`;
|
|
549
433
|
}).join("\n");
|
|
550
434
|
throw new Error(`Invalid configuration:
|
|
551
435
|
${errors}`);
|
|
@@ -564,7 +448,6 @@ var WEB_BUILD_DEFAULTS = {
|
|
|
564
448
|
minify: true,
|
|
565
449
|
sourcemap: false,
|
|
566
450
|
cache: true,
|
|
567
|
-
tempDir: ".tmp",
|
|
568
451
|
windowCollector: "collector",
|
|
569
452
|
windowElb: "elb"
|
|
570
453
|
};
|
|
@@ -574,8 +457,7 @@ var SERVER_BUILD_DEFAULTS = {
|
|
|
574
457
|
target: "node20",
|
|
575
458
|
minify: true,
|
|
576
459
|
sourcemap: false,
|
|
577
|
-
cache: true
|
|
578
|
-
tempDir: ".tmp"
|
|
460
|
+
cache: true
|
|
579
461
|
};
|
|
580
462
|
var DEFAULT_OUTPUT_PATHS = {
|
|
581
463
|
web: "./dist/walker.js",
|
|
@@ -606,14 +488,8 @@ function loadBundleConfig(rawConfig, options) {
|
|
|
606
488
|
}
|
|
607
489
|
const buildDefaults = getBuildDefaults(platform);
|
|
608
490
|
const packages = flowConfig.packages || {};
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
output = options.buildOverrides.output;
|
|
612
|
-
}
|
|
613
|
-
const configDir = path5.dirname(options.configPath);
|
|
614
|
-
if (!path5.isAbsolute(output)) {
|
|
615
|
-
output = path5.resolve(configDir, output);
|
|
616
|
-
}
|
|
491
|
+
const output = options.buildOverrides?.output || getDefaultOutput(platform);
|
|
492
|
+
const configDir = isUrl(options.configPath) ? process.cwd() : path5.dirname(options.configPath);
|
|
617
493
|
let includes = setup.include;
|
|
618
494
|
if (!includes) {
|
|
619
495
|
const defaultIncludePath = path5.resolve(configDir, DEFAULT_INCLUDE_FOLDER);
|
|
@@ -676,6 +552,10 @@ function loadAllFlows(rawConfig, options) {
|
|
|
676
552
|
})
|
|
677
553
|
);
|
|
678
554
|
}
|
|
555
|
+
async function loadFlowConfig(configPath, options) {
|
|
556
|
+
const rawConfig = await loadJsonConfig(configPath);
|
|
557
|
+
return loadBundleConfig(rawConfig, { configPath, ...options });
|
|
558
|
+
}
|
|
679
559
|
|
|
680
560
|
// src/commands/bundle/bundler.ts
|
|
681
561
|
import esbuild from "esbuild";
|
|
@@ -689,7 +569,7 @@ import path6 from "path";
|
|
|
689
569
|
import fs5 from "fs-extra";
|
|
690
570
|
|
|
691
571
|
// src/core/cache-utils.ts
|
|
692
|
-
import { getHashServer
|
|
572
|
+
import { getHashServer } from "@walkeros/server-core";
|
|
693
573
|
var HASH_LENGTH = 12;
|
|
694
574
|
function isMutableVersion(version) {
|
|
695
575
|
return version === "latest" || version.includes("^") || version.includes("~") || version.includes("*") || version.includes("x");
|
|
@@ -702,10 +582,10 @@ async function getPackageCacheKey(packageName, version, date) {
|
|
|
702
582
|
if (isMutableVersion(version)) {
|
|
703
583
|
const dateStr = date ?? getTodayDate();
|
|
704
584
|
const input2 = `${safeName}@${version}:${dateStr}`;
|
|
705
|
-
return
|
|
585
|
+
return getHashServer(input2, HASH_LENGTH);
|
|
706
586
|
}
|
|
707
587
|
const input = `${safeName}@${version}`;
|
|
708
|
-
return
|
|
588
|
+
return getHashServer(input, HASH_LENGTH);
|
|
709
589
|
}
|
|
710
590
|
function normalizeJson(content) {
|
|
711
591
|
const parsed = JSON.parse(content);
|
|
@@ -715,20 +595,27 @@ async function getFlowConfigCacheKey(content, date) {
|
|
|
715
595
|
const dateStr = date ?? getTodayDate();
|
|
716
596
|
const normalized = normalizeJson(content);
|
|
717
597
|
const input = `${normalized}:${dateStr}`;
|
|
718
|
-
return
|
|
598
|
+
return getHashServer(input, HASH_LENGTH);
|
|
719
599
|
}
|
|
720
600
|
|
|
721
601
|
// src/commands/bundle/package-manager.ts
|
|
602
|
+
var PACKAGE_DOWNLOAD_TIMEOUT_MS = 6e4;
|
|
603
|
+
async function withTimeout(promise, ms, errorMessage) {
|
|
604
|
+
const timeout = new Promise(
|
|
605
|
+
(_, reject) => setTimeout(() => reject(new Error(errorMessage)), ms)
|
|
606
|
+
);
|
|
607
|
+
return Promise.race([promise, timeout]);
|
|
608
|
+
}
|
|
722
609
|
function getPackageDirectory(baseDir, packageName, version) {
|
|
723
610
|
return path6.join(baseDir, "node_modules", packageName);
|
|
724
611
|
}
|
|
725
|
-
async function getCachedPackagePath(pkg,
|
|
726
|
-
const cacheDir =
|
|
612
|
+
async function getCachedPackagePath(pkg, tmpDir) {
|
|
613
|
+
const cacheDir = getTmpPath(tmpDir, "cache", "packages");
|
|
727
614
|
const cacheKey = await getPackageCacheKey(pkg.name, pkg.version);
|
|
728
615
|
return path6.join(cacheDir, cacheKey);
|
|
729
616
|
}
|
|
730
|
-
async function isPackageCached(pkg,
|
|
731
|
-
const cachedPath = await getCachedPackagePath(pkg,
|
|
617
|
+
async function isPackageCached(pkg, tmpDir) {
|
|
618
|
+
const cachedPath = await getCachedPackagePath(pkg, tmpDir);
|
|
732
619
|
return fs5.pathExists(cachedPath);
|
|
733
620
|
}
|
|
734
621
|
function validateNoDuplicatePackages(packages) {
|
|
@@ -765,10 +652,10 @@ async function resolveDependencies(pkg, packageDir, logger2, visited = /* @__PUR
|
|
|
765
652
|
try {
|
|
766
653
|
const packageJsonPath = path6.join(packageDir, "package.json");
|
|
767
654
|
if (await fs5.pathExists(packageJsonPath)) {
|
|
768
|
-
const
|
|
655
|
+
const packageJson = await fs5.readJson(packageJsonPath);
|
|
769
656
|
const deps = {
|
|
770
|
-
...
|
|
771
|
-
...
|
|
657
|
+
...packageJson.dependencies,
|
|
658
|
+
...packageJson.peerDependencies
|
|
772
659
|
};
|
|
773
660
|
for (const [name, versionSpec] of Object.entries(deps)) {
|
|
774
661
|
if (typeof versionSpec === "string") {
|
|
@@ -785,6 +672,7 @@ async function downloadPackages(packages, targetDir, logger2, useCache = true, c
|
|
|
785
672
|
const packagePaths = /* @__PURE__ */ new Map();
|
|
786
673
|
const downloadQueue = [...packages];
|
|
787
674
|
const processed = /* @__PURE__ */ new Set();
|
|
675
|
+
const userSpecifiedPackages = new Set(packages.map((p) => p.name));
|
|
788
676
|
const localPackageMap = /* @__PURE__ */ new Map();
|
|
789
677
|
for (const pkg of packages) {
|
|
790
678
|
if (pkg.path) {
|
|
@@ -823,9 +711,11 @@ async function downloadPackages(packages, targetDir, logger2, useCache = true, c
|
|
|
823
711
|
}
|
|
824
712
|
const packageSpec = `${pkg.name}@${pkg.version}`;
|
|
825
713
|
const packageDir = getPackageDirectory(targetDir, pkg.name, pkg.version);
|
|
826
|
-
const cachedPath = await getCachedPackagePath(pkg
|
|
827
|
-
if (useCache && await isPackageCached(pkg
|
|
828
|
-
|
|
714
|
+
const cachedPath = await getCachedPackagePath(pkg);
|
|
715
|
+
if (useCache && await isPackageCached(pkg)) {
|
|
716
|
+
if (userSpecifiedPackages.has(pkg.name)) {
|
|
717
|
+
logger2.debug(`Downloading ${packageSpec} (cached)`);
|
|
718
|
+
}
|
|
829
719
|
try {
|
|
830
720
|
await fs5.ensureDir(path6.dirname(packageDir));
|
|
831
721
|
await fs5.copy(cachedPath, packageDir);
|
|
@@ -844,27 +734,34 @@ async function downloadPackages(packages, targetDir, logger2, useCache = true, c
|
|
|
844
734
|
);
|
|
845
735
|
}
|
|
846
736
|
}
|
|
847
|
-
logger2.debug(`Downloading ${packageSpec}...`);
|
|
848
737
|
try {
|
|
849
738
|
await fs5.ensureDir(path6.dirname(packageDir));
|
|
850
|
-
const cacheDir = process.env.NPM_CACHE_DIR ||
|
|
851
|
-
await
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
739
|
+
const cacheDir = process.env.NPM_CACHE_DIR || getTmpPath(void 0, "cache", "npm");
|
|
740
|
+
await withTimeout(
|
|
741
|
+
pacote.extract(packageSpec, packageDir, {
|
|
742
|
+
// Force npm registry download, prevent workspace resolution
|
|
743
|
+
registry: "https://registry.npmjs.org",
|
|
744
|
+
// Force online fetching from registry (don't use cached workspace packages)
|
|
745
|
+
preferOnline: true,
|
|
746
|
+
// Cache for performance
|
|
747
|
+
cache: cacheDir,
|
|
748
|
+
// Don't resolve relative to workspace context
|
|
749
|
+
where: void 0
|
|
750
|
+
}),
|
|
751
|
+
PACKAGE_DOWNLOAD_TIMEOUT_MS,
|
|
752
|
+
`Package download timed out after ${PACKAGE_DOWNLOAD_TIMEOUT_MS / 1e3}s: ${packageSpec}`
|
|
753
|
+
);
|
|
754
|
+
if (userSpecifiedPackages.has(pkg.name)) {
|
|
755
|
+
const pkgStats = await fs5.stat(path6.join(packageDir, "package.json"));
|
|
756
|
+
const pkgJsonSize = pkgStats.size;
|
|
757
|
+
const sizeKB = (pkgJsonSize / 1024).toFixed(1);
|
|
758
|
+
logger2.debug(`Downloading ${packageSpec} (${sizeKB} KB)`);
|
|
759
|
+
}
|
|
861
760
|
if (useCache) {
|
|
862
761
|
try {
|
|
863
762
|
await fs5.ensureDir(path6.dirname(cachedPath));
|
|
864
763
|
await fs5.copy(packageDir, cachedPath);
|
|
865
|
-
logger2.debug(`Cached ${packageSpec} for future use`);
|
|
866
764
|
} catch (cacheError) {
|
|
867
|
-
logger2.debug(`Failed to cache ${packageSpec}: ${cacheError}`);
|
|
868
765
|
}
|
|
869
766
|
}
|
|
870
767
|
packagePaths.set(pkg.name, packageDir);
|
|
@@ -885,22 +782,22 @@ async function downloadPackages(packages, targetDir, logger2, useCache = true, c
|
|
|
885
782
|
// src/core/build-cache.ts
|
|
886
783
|
import fs6 from "fs-extra";
|
|
887
784
|
import path7 from "path";
|
|
888
|
-
|
|
889
|
-
|
|
785
|
+
async function getBuildCachePath(configContent, tmpDir) {
|
|
786
|
+
const cacheDir = getTmpPath(tmpDir, "cache", "builds");
|
|
890
787
|
const cacheKey = await getFlowConfigCacheKey(configContent);
|
|
891
788
|
return path7.join(cacheDir, `${cacheKey}.js`);
|
|
892
789
|
}
|
|
893
|
-
async function isBuildCached(configContent,
|
|
894
|
-
const cachePath = await getBuildCachePath(configContent,
|
|
790
|
+
async function isBuildCached(configContent, tmpDir) {
|
|
791
|
+
const cachePath = await getBuildCachePath(configContent, tmpDir);
|
|
895
792
|
return fs6.pathExists(cachePath);
|
|
896
793
|
}
|
|
897
|
-
async function cacheBuild(configContent, buildOutput,
|
|
898
|
-
const cachePath = await getBuildCachePath(configContent,
|
|
794
|
+
async function cacheBuild(configContent, buildOutput, tmpDir) {
|
|
795
|
+
const cachePath = await getBuildCachePath(configContent, tmpDir);
|
|
899
796
|
await fs6.ensureDir(path7.dirname(cachePath));
|
|
900
797
|
await fs6.writeFile(cachePath, buildOutput, "utf-8");
|
|
901
798
|
}
|
|
902
|
-
async function getCachedBuild(configContent,
|
|
903
|
-
const cachePath = await getBuildCachePath(configContent,
|
|
799
|
+
async function getCachedBuild(configContent, tmpDir) {
|
|
800
|
+
const cachePath = await getBuildCachePath(configContent, tmpDir);
|
|
904
801
|
if (await fs6.pathExists(cachePath)) {
|
|
905
802
|
return await fs6.readFile(cachePath, "utf-8");
|
|
906
803
|
}
|
|
@@ -935,21 +832,22 @@ function generateCacheKeyContent(flowConfig, buildOptions) {
|
|
|
935
832
|
}
|
|
936
833
|
async function bundleCore(flowConfig, buildOptions, logger2, showStats = false) {
|
|
937
834
|
const bundleStartTime = Date.now();
|
|
938
|
-
const TEMP_DIR = buildOptions.tempDir
|
|
835
|
+
const TEMP_DIR = buildOptions.tempDir || getTmpPath();
|
|
939
836
|
if (buildOptions.cache !== false) {
|
|
940
837
|
const configContent = generateCacheKeyContent(flowConfig, buildOptions);
|
|
941
838
|
const cached = await isBuildCached(configContent);
|
|
942
839
|
if (cached) {
|
|
943
840
|
const cachedBuild = await getCachedBuild(configContent);
|
|
944
841
|
if (cachedBuild) {
|
|
945
|
-
logger2.
|
|
842
|
+
logger2.debug("Using cached build");
|
|
946
843
|
const outputPath = path8.resolve(buildOptions.output);
|
|
947
844
|
await fs7.ensureDir(path8.dirname(outputPath));
|
|
948
845
|
await fs7.writeFile(outputPath, cachedBuild);
|
|
949
|
-
|
|
950
|
-
|
|
846
|
+
const stats = await fs7.stat(outputPath);
|
|
847
|
+
const sizeKB = (stats.size / 1024).toFixed(1);
|
|
848
|
+
logger2.log(`Output: ${outputPath} (${sizeKB} KB, cached)`);
|
|
951
849
|
if (showStats) {
|
|
952
|
-
const
|
|
850
|
+
const stats2 = await fs7.stat(outputPath);
|
|
953
851
|
const packageStats = Object.entries(buildOptions.packages).map(
|
|
954
852
|
([name, pkg]) => ({
|
|
955
853
|
name: `${name}@${pkg.version || "latest"}`,
|
|
@@ -958,7 +856,7 @@ async function bundleCore(flowConfig, buildOptions, logger2, showStats = false)
|
|
|
958
856
|
})
|
|
959
857
|
);
|
|
960
858
|
return {
|
|
961
|
-
totalSize:
|
|
859
|
+
totalSize: stats2.size,
|
|
962
860
|
packages: packageStats,
|
|
963
861
|
buildTime: Date.now() - bundleStartTime,
|
|
964
862
|
treeshakingEffective: true
|
|
@@ -969,11 +867,8 @@ async function bundleCore(flowConfig, buildOptions, logger2, showStats = false)
|
|
|
969
867
|
}
|
|
970
868
|
}
|
|
971
869
|
try {
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
}
|
|
975
|
-
logger2.debug("Cleaned temporary directory");
|
|
976
|
-
logger2.info("\u{1F4E5} Downloading packages...");
|
|
870
|
+
await fs7.ensureDir(TEMP_DIR);
|
|
871
|
+
logger2.debug("Downloading packages");
|
|
977
872
|
const packagesArray = Object.entries(buildOptions.packages).map(
|
|
978
873
|
([name, packageConfig]) => ({
|
|
979
874
|
name,
|
|
@@ -1010,7 +905,7 @@ async function bundleCore(flowConfig, buildOptions, logger2, showStats = false)
|
|
|
1010
905
|
packageJsonPath,
|
|
1011
906
|
JSON.stringify({ type: "module" }, null, 2)
|
|
1012
907
|
);
|
|
1013
|
-
logger2.
|
|
908
|
+
logger2.debug("Creating entry point");
|
|
1014
909
|
const entryContent = await createEntryPoint(
|
|
1015
910
|
flowConfig,
|
|
1016
911
|
buildOptions,
|
|
@@ -1018,7 +913,9 @@ async function bundleCore(flowConfig, buildOptions, logger2, showStats = false)
|
|
|
1018
913
|
);
|
|
1019
914
|
const entryPath = path8.join(TEMP_DIR, "entry.js");
|
|
1020
915
|
await fs7.writeFile(entryPath, entryContent);
|
|
1021
|
-
logger2.
|
|
916
|
+
logger2.debug(
|
|
917
|
+
`Running esbuild (target: ${buildOptions.target || "es2018"}, format: ${buildOptions.format})`
|
|
918
|
+
);
|
|
1022
919
|
const outputPath = path8.resolve(buildOptions.output);
|
|
1023
920
|
await fs7.ensureDir(path8.dirname(outputPath));
|
|
1024
921
|
const esbuildOptions = createEsbuildOptions(
|
|
@@ -1037,7 +934,10 @@ async function bundleCore(flowConfig, buildOptions, logger2, showStats = false)
|
|
|
1037
934
|
buildOptions.code || ""
|
|
1038
935
|
);
|
|
1039
936
|
}
|
|
1040
|
-
|
|
937
|
+
const outputStats = await fs7.stat(outputPath);
|
|
938
|
+
const sizeKB = (outputStats.size / 1024).toFixed(1);
|
|
939
|
+
const buildTime = ((Date.now() - bundleStartTime) / 1e3).toFixed(1);
|
|
940
|
+
logger2.log(`Output: ${outputPath} (${sizeKB} KB, ${buildTime}s)`);
|
|
1041
941
|
if (buildOptions.cache !== false) {
|
|
1042
942
|
const configContent = generateCacheKeyContent(flowConfig, buildOptions);
|
|
1043
943
|
const buildOutput = await fs7.readFile(outputPath, "utf-8");
|
|
@@ -1062,16 +962,8 @@ async function bundleCore(flowConfig, buildOptions, logger2, showStats = false)
|
|
|
1062
962
|
logger2
|
|
1063
963
|
);
|
|
1064
964
|
}
|
|
1065
|
-
if (!buildOptions.tempDir) {
|
|
1066
|
-
await fs7.remove(TEMP_DIR);
|
|
1067
|
-
logger2.debug("Cleaned up temporary files");
|
|
1068
|
-
}
|
|
1069
965
|
return stats;
|
|
1070
966
|
} catch (error) {
|
|
1071
|
-
if (!buildOptions.tempDir) {
|
|
1072
|
-
await fs7.remove(TEMP_DIR).catch(() => {
|
|
1073
|
-
});
|
|
1074
|
-
}
|
|
1075
967
|
throw error;
|
|
1076
968
|
}
|
|
1077
969
|
}
|
|
@@ -1404,6 +1296,11 @@ function generatePlatformWrapper(configObject, userCode, buildOptions) {
|
|
|
1404
1296
|
` : "";
|
|
1405
1297
|
return `export default async function(context = {}) {
|
|
1406
1298
|
const config = ${configObject};${codeSection}
|
|
1299
|
+
// Apply context overrides (e.g., logger config from CLI)
|
|
1300
|
+
if (context.logger) {
|
|
1301
|
+
config.logger = { ...config.logger, ...context.logger };
|
|
1302
|
+
}
|
|
1303
|
+
|
|
1407
1304
|
return await startFlow(config);
|
|
1408
1305
|
}`;
|
|
1409
1306
|
}
|
|
@@ -1437,130 +1334,111 @@ async function bundleCommand(options) {
|
|
|
1437
1334
|
const timer = createTimer();
|
|
1438
1335
|
timer.start();
|
|
1439
1336
|
const logger2 = createCommandLogger(options);
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1337
|
+
if (options.dryRun) {
|
|
1338
|
+
logger2.log(`[DRY-RUN] Would execute bundle with config: ${options.config}`);
|
|
1339
|
+
return;
|
|
1340
|
+
}
|
|
1341
|
+
try {
|
|
1342
|
+
if (options.flow && options.all) {
|
|
1343
|
+
throw new Error("Cannot use both --flow and --all flags together");
|
|
1344
|
+
}
|
|
1345
|
+
const configPath = resolveAsset(options.config, "config");
|
|
1346
|
+
const rawConfig = await loadJsonConfig(configPath);
|
|
1347
|
+
const configsToBundle = options.all ? loadAllFlows(rawConfig, { configPath, logger: logger2 }) : [
|
|
1348
|
+
loadBundleConfig(rawConfig, {
|
|
1349
|
+
configPath,
|
|
1350
|
+
flowName: options.flow,
|
|
1351
|
+
logger: logger2
|
|
1352
|
+
})
|
|
1353
|
+
];
|
|
1354
|
+
const results = [];
|
|
1355
|
+
for (const {
|
|
1356
|
+
flowConfig,
|
|
1357
|
+
buildOptions,
|
|
1358
|
+
flowName,
|
|
1359
|
+
isMultiFlow
|
|
1360
|
+
} of configsToBundle) {
|
|
1447
1361
|
try {
|
|
1448
|
-
if (options.
|
|
1449
|
-
|
|
1362
|
+
if (options.cache !== void 0) {
|
|
1363
|
+
buildOptions.cache = options.cache;
|
|
1450
1364
|
}
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
})
|
|
1460
|
-
];
|
|
1461
|
-
const results = [];
|
|
1462
|
-
for (const {
|
|
1365
|
+
const configBasename = path9.basename(configPath);
|
|
1366
|
+
if (isMultiFlow || options.all) {
|
|
1367
|
+
logger2.log(`Bundling ${configBasename} (flow: ${flowName})...`);
|
|
1368
|
+
} else {
|
|
1369
|
+
logger2.log(`Bundling ${configBasename}...`);
|
|
1370
|
+
}
|
|
1371
|
+
const shouldCollectStats = options.stats || options.json;
|
|
1372
|
+
const stats = await bundleCore(
|
|
1463
1373
|
flowConfig,
|
|
1464
1374
|
buildOptions,
|
|
1375
|
+
logger2,
|
|
1376
|
+
shouldCollectStats
|
|
1377
|
+
);
|
|
1378
|
+
results.push({
|
|
1465
1379
|
flowName,
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
}
|
|
1472
|
-
if (isMultiFlow || options.all) {
|
|
1473
|
-
logger2.info(`
|
|
1474
|
-
\u{1F527} Building flow: ${flowName}`);
|
|
1475
|
-
} else {
|
|
1476
|
-
logger2.info("\u{1F527} Starting bundle process...");
|
|
1477
|
-
}
|
|
1478
|
-
const shouldCollectStats = options.stats || options.json;
|
|
1479
|
-
const stats = await bundleCore(
|
|
1480
|
-
flowConfig,
|
|
1481
|
-
buildOptions,
|
|
1482
|
-
logger2,
|
|
1483
|
-
shouldCollectStats
|
|
1484
|
-
);
|
|
1485
|
-
results.push({
|
|
1486
|
-
flowName,
|
|
1487
|
-
success: true,
|
|
1488
|
-
stats
|
|
1489
|
-
});
|
|
1490
|
-
if (!options.json && !options.all && options.stats && stats) {
|
|
1491
|
-
displayStats(stats, logger2);
|
|
1492
|
-
}
|
|
1493
|
-
} catch (error) {
|
|
1494
|
-
const errorMessage = getErrorMessage(error);
|
|
1495
|
-
results.push({
|
|
1496
|
-
flowName,
|
|
1497
|
-
success: false,
|
|
1498
|
-
error: errorMessage
|
|
1499
|
-
});
|
|
1500
|
-
if (!options.all) {
|
|
1501
|
-
throw error;
|
|
1502
|
-
}
|
|
1503
|
-
}
|
|
1504
|
-
}
|
|
1505
|
-
const duration = timer.end() / 1e3;
|
|
1506
|
-
const successCount = results.filter((r) => r.success).length;
|
|
1507
|
-
const failureCount = results.filter((r) => !r.success).length;
|
|
1508
|
-
if (options.json) {
|
|
1509
|
-
const outputLogger = createLogger({ silent: false, json: false });
|
|
1510
|
-
const output = failureCount === 0 ? createSuccessOutput(
|
|
1511
|
-
{
|
|
1512
|
-
flows: results,
|
|
1513
|
-
summary: {
|
|
1514
|
-
total: results.length,
|
|
1515
|
-
success: successCount,
|
|
1516
|
-
failed: failureCount
|
|
1517
|
-
}
|
|
1518
|
-
},
|
|
1519
|
-
duration
|
|
1520
|
-
) : createErrorOutput(
|
|
1521
|
-
`${failureCount} flow(s) failed to build`,
|
|
1522
|
-
duration
|
|
1523
|
-
);
|
|
1524
|
-
outputLogger.log("white", JSON.stringify(output, null, 2));
|
|
1525
|
-
} else {
|
|
1526
|
-
if (options.all) {
|
|
1527
|
-
logger2.info(`
|
|
1528
|
-
\u{1F4CA} Build Summary:`);
|
|
1529
|
-
logger2.info(` Total: ${results.length}`);
|
|
1530
|
-
logger2.success(` \u2705 Success: ${successCount}`);
|
|
1531
|
-
if (failureCount > 0) {
|
|
1532
|
-
logger2.error(` \u274C Failed: ${failureCount}`);
|
|
1533
|
-
}
|
|
1534
|
-
}
|
|
1535
|
-
if (failureCount === 0) {
|
|
1536
|
-
logger2.success(
|
|
1537
|
-
`
|
|
1538
|
-
\u2705 Bundle created successfully in ${timer.format()}`
|
|
1539
|
-
);
|
|
1540
|
-
} else {
|
|
1541
|
-
throw new Error(`${failureCount} flow(s) failed to build`);
|
|
1542
|
-
}
|
|
1380
|
+
success: true,
|
|
1381
|
+
stats
|
|
1382
|
+
});
|
|
1383
|
+
if (!options.json && !options.all && options.stats && stats) {
|
|
1384
|
+
displayStats(stats, logger2);
|
|
1543
1385
|
}
|
|
1544
1386
|
} catch (error) {
|
|
1545
|
-
const duration = timer.getElapsed() / 1e3;
|
|
1546
1387
|
const errorMessage = getErrorMessage(error);
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
}
|
|
1552
|
-
|
|
1553
|
-
|
|
1388
|
+
results.push({
|
|
1389
|
+
flowName,
|
|
1390
|
+
success: false,
|
|
1391
|
+
error: errorMessage
|
|
1392
|
+
});
|
|
1393
|
+
if (!options.all) {
|
|
1394
|
+
throw error;
|
|
1554
1395
|
}
|
|
1555
|
-
process.exit(1);
|
|
1556
1396
|
}
|
|
1557
|
-
}
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1397
|
+
}
|
|
1398
|
+
const duration = timer.end() / 1e3;
|
|
1399
|
+
const successCount = results.filter((r) => r.success).length;
|
|
1400
|
+
const failureCount = results.filter((r) => !r.success).length;
|
|
1401
|
+
if (options.json) {
|
|
1402
|
+
const output = failureCount === 0 ? createSuccessOutput(
|
|
1403
|
+
{
|
|
1404
|
+
flows: results,
|
|
1405
|
+
summary: {
|
|
1406
|
+
total: results.length,
|
|
1407
|
+
success: successCount,
|
|
1408
|
+
failed: failureCount
|
|
1409
|
+
}
|
|
1410
|
+
},
|
|
1411
|
+
duration
|
|
1412
|
+
) : createErrorOutput(
|
|
1413
|
+
`${failureCount} flow(s) failed to build`,
|
|
1414
|
+
duration
|
|
1415
|
+
);
|
|
1416
|
+
logger2.json(output);
|
|
1417
|
+
} else {
|
|
1418
|
+
if (options.all) {
|
|
1419
|
+
logger2.log(
|
|
1420
|
+
`
|
|
1421
|
+
Build Summary: ${successCount}/${results.length} succeeded`
|
|
1422
|
+
);
|
|
1423
|
+
if (failureCount > 0) {
|
|
1424
|
+
logger2.error(`Failed: ${failureCount}`);
|
|
1425
|
+
}
|
|
1426
|
+
}
|
|
1427
|
+
if (failureCount > 0) {
|
|
1428
|
+
throw new Error(`${failureCount} flow(s) failed to build`);
|
|
1429
|
+
}
|
|
1430
|
+
}
|
|
1431
|
+
} catch (error) {
|
|
1432
|
+
const duration = timer.getElapsed() / 1e3;
|
|
1433
|
+
const errorMessage = getErrorMessage(error);
|
|
1434
|
+
if (options.json) {
|
|
1435
|
+
const output = createErrorOutput(errorMessage, duration);
|
|
1436
|
+
logger2.json(output);
|
|
1437
|
+
} else {
|
|
1438
|
+
logger2.error(`Error: ${errorMessage}`);
|
|
1439
|
+
}
|
|
1440
|
+
process.exit(1);
|
|
1441
|
+
}
|
|
1564
1442
|
}
|
|
1565
1443
|
async function bundle(configOrPath, options = {}) {
|
|
1566
1444
|
let rawConfig;
|
|
@@ -1627,9 +1505,9 @@ var CallTracker = class {
|
|
|
1627
1505
|
}
|
|
1628
1506
|
for (const fullPath of paths) {
|
|
1629
1507
|
const [destKey, ...pathParts] = fullPath.split(":");
|
|
1630
|
-
const
|
|
1631
|
-
if (!
|
|
1632
|
-
const cleanPath =
|
|
1508
|
+
const path14 = pathParts.join(":");
|
|
1509
|
+
if (!path14) continue;
|
|
1510
|
+
const cleanPath = path14.replace(/^call:/, "");
|
|
1633
1511
|
const parts = cleanPath.split(".");
|
|
1634
1512
|
let current = wrapped;
|
|
1635
1513
|
let source = env;
|
|
@@ -1710,11 +1588,11 @@ function buildSandboxFromEnvs(envs, destinations, tracker) {
|
|
|
1710
1588
|
return sandbox;
|
|
1711
1589
|
}
|
|
1712
1590
|
function waitForWindowProperty(window, prop, timeout = 5e3) {
|
|
1713
|
-
return new Promise((
|
|
1591
|
+
return new Promise((resolve3, reject) => {
|
|
1714
1592
|
const start = Date.now();
|
|
1715
1593
|
const check = () => {
|
|
1716
1594
|
if (window[prop] !== void 0) {
|
|
1717
|
-
|
|
1595
|
+
resolve3();
|
|
1718
1596
|
} else if (Date.now() - start > timeout) {
|
|
1719
1597
|
reject(
|
|
1720
1598
|
new Error(
|
|
@@ -1813,7 +1691,7 @@ function injectGlobalMocks(mocks) {
|
|
|
1813
1691
|
}
|
|
1814
1692
|
};
|
|
1815
1693
|
}
|
|
1816
|
-
async function executeInNode(bundlePath, destinations, event, tracker, envs, timeout = 3e4) {
|
|
1694
|
+
async function executeInNode(bundlePath, destinations, event, tracker, envs, timeout = 3e4, context = {}) {
|
|
1817
1695
|
const start = Date.now();
|
|
1818
1696
|
const globalMocks = buildGlobalMocksFromEnvs(envs, destinations, tracker);
|
|
1819
1697
|
const cleanupMocks = injectGlobalMocks(globalMocks);
|
|
@@ -1824,16 +1702,19 @@ async function executeInNode(bundlePath, destinations, event, tracker, envs, tim
|
|
|
1824
1702
|
if (!module.default || typeof module.default !== "function") {
|
|
1825
1703
|
throw new Error("Bundle does not export default factory function");
|
|
1826
1704
|
}
|
|
1827
|
-
const result = await module.default();
|
|
1828
|
-
if (!result || !result.
|
|
1705
|
+
const result = await module.default(context);
|
|
1706
|
+
if (!result || !result.collector || typeof result.collector.push !== "function") {
|
|
1829
1707
|
throw new Error(
|
|
1830
|
-
"Factory function did not return valid result with
|
|
1708
|
+
"Factory function did not return valid result with collector"
|
|
1831
1709
|
);
|
|
1832
1710
|
}
|
|
1833
1711
|
const { collector, elb } = result;
|
|
1834
1712
|
let elbResult;
|
|
1835
1713
|
try {
|
|
1836
|
-
elbResult = await
|
|
1714
|
+
elbResult = await collector.push({
|
|
1715
|
+
name: event.name,
|
|
1716
|
+
data: event.data
|
|
1717
|
+
});
|
|
1837
1718
|
} catch (error) {
|
|
1838
1719
|
throw new Error(`Event execution failed: ${getErrorMessage(error)}`);
|
|
1839
1720
|
}
|
|
@@ -1881,10 +1762,7 @@ async function loadDestinationEnvs(destinations) {
|
|
|
1881
1762
|
simulation: envModule.simulation || []
|
|
1882
1763
|
};
|
|
1883
1764
|
}
|
|
1884
|
-
} catch
|
|
1885
|
-
console.warn(
|
|
1886
|
-
`Warning: Could not load env for destination "${destKey}": ${error instanceof Error ? error.message : String(error)}`
|
|
1887
|
-
);
|
|
1765
|
+
} catch {
|
|
1888
1766
|
}
|
|
1889
1767
|
}
|
|
1890
1768
|
return envs;
|
|
@@ -1894,29 +1772,21 @@ async function loadDestinationEnvs(destinations) {
|
|
|
1894
1772
|
function generateId() {
|
|
1895
1773
|
return `${Date.now()}-${Math.random().toString(36).substring(2, 11)}`;
|
|
1896
1774
|
}
|
|
1897
|
-
async function simulateCore(
|
|
1775
|
+
async function simulateCore(inputPath, event, options = {}) {
|
|
1898
1776
|
const logger2 = createLogger({
|
|
1899
1777
|
verbose: options.verbose || false,
|
|
1900
1778
|
silent: options.silent || false,
|
|
1901
1779
|
json: options.json || false
|
|
1902
1780
|
});
|
|
1903
1781
|
try {
|
|
1904
|
-
logger2.
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
logger2.info(`\u{1F680} Executing simulation with event: ${JSON.stringify(event)}`);
|
|
1910
|
-
const result = await executeSimulation(event, fullConfigPath);
|
|
1911
|
-
if (result.success) {
|
|
1912
|
-
logger2.info(`\u2705 Simulation completed successfully`);
|
|
1913
|
-
} else {
|
|
1914
|
-
logger2.error(`\u274C Simulation failed: ${result.error}`);
|
|
1915
|
-
}
|
|
1782
|
+
logger2.debug(`Simulating event: ${JSON.stringify(event)}`);
|
|
1783
|
+
const result = await executeSimulation(event, inputPath, options.platform, {
|
|
1784
|
+
logger: logger2,
|
|
1785
|
+
verbose: options.verbose
|
|
1786
|
+
});
|
|
1916
1787
|
return result;
|
|
1917
1788
|
} catch (error) {
|
|
1918
1789
|
const errorMessage = getErrorMessage(error);
|
|
1919
|
-
logger2.error(`\u{1F4A5} Simulation error: ${errorMessage}`);
|
|
1920
1790
|
return {
|
|
1921
1791
|
success: false,
|
|
1922
1792
|
error: errorMessage
|
|
@@ -1933,87 +1803,43 @@ function formatSimulationResult(result, options = {}) {
|
|
|
1933
1803
|
return JSON.stringify(output, null, 2);
|
|
1934
1804
|
}
|
|
1935
1805
|
if (result.success) {
|
|
1936
|
-
return "
|
|
1806
|
+
return "Simulation completed";
|
|
1937
1807
|
} else {
|
|
1938
|
-
return
|
|
1808
|
+
return `Simulation failed: ${result.error}`;
|
|
1939
1809
|
}
|
|
1940
1810
|
}
|
|
1941
|
-
async function executeSimulation(event,
|
|
1811
|
+
async function executeSimulation(event, inputPath, platformOverride, options = {}) {
|
|
1942
1812
|
const startTime = Date.now();
|
|
1943
|
-
|
|
1944
|
-
const
|
|
1813
|
+
const tempDir = getTmpPath();
|
|
1814
|
+
const collectorLoggerConfig = options.logger ? createCollectorLoggerConfig(options.logger, options.verbose) : void 0;
|
|
1945
1815
|
try {
|
|
1816
|
+
await fs9.ensureDir(tempDir);
|
|
1817
|
+
const detected = await detectInput(inputPath, platformOverride);
|
|
1946
1818
|
if (!isObject(event) || !("name" in event) || typeof event.name !== "string") {
|
|
1947
1819
|
throw new Error(
|
|
1948
1820
|
'Event must be an object with a "name" property of type string'
|
|
1949
1821
|
);
|
|
1950
1822
|
}
|
|
1951
1823
|
const typedEvent = event;
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
|
|
1955
|
-
|
|
1956
|
-
});
|
|
1957
|
-
const platform = getPlatform2(flowConfig);
|
|
1958
|
-
const tracker = new CallTracker();
|
|
1959
|
-
const tempOutput = path10.join(
|
|
1960
|
-
tempDir,
|
|
1961
|
-
`simulation-bundle-${generateId()}.${platform === "web" ? "js" : "mjs"}`
|
|
1962
|
-
);
|
|
1963
|
-
const destinations = flowConfig.destinations;
|
|
1964
|
-
const simulationBuildOptions = {
|
|
1965
|
-
...buildOptions,
|
|
1966
|
-
code: buildOptions.code || "",
|
|
1967
|
-
output: tempOutput,
|
|
1968
|
-
tempDir,
|
|
1969
|
-
...platform === "web" ? {
|
|
1970
|
-
format: "iife",
|
|
1971
|
-
platform: "browser",
|
|
1972
|
-
windowCollector: "collector",
|
|
1973
|
-
windowElb: "elb"
|
|
1974
|
-
} : {
|
|
1975
|
-
format: "esm",
|
|
1976
|
-
platform: "node"
|
|
1977
|
-
}
|
|
1978
|
-
};
|
|
1979
|
-
await bundleCore(
|
|
1980
|
-
flowConfig,
|
|
1981
|
-
simulationBuildOptions,
|
|
1982
|
-
createLogger({ silent: true }),
|
|
1983
|
-
false
|
|
1984
|
-
);
|
|
1985
|
-
bundlePath = tempOutput;
|
|
1986
|
-
const envs = await loadDestinationEnvs(destinations || {});
|
|
1987
|
-
let result;
|
|
1988
|
-
if (platform === "web") {
|
|
1989
|
-
result = await executeInJSDOM(
|
|
1990
|
-
tempOutput,
|
|
1991
|
-
destinations || {},
|
|
1824
|
+
if (detected.type === "config") {
|
|
1825
|
+
return await executeConfigSimulation(
|
|
1826
|
+
detected.content,
|
|
1827
|
+
inputPath,
|
|
1992
1828
|
typedEvent,
|
|
1993
|
-
|
|
1994
|
-
|
|
1995
|
-
|
|
1829
|
+
tempDir,
|
|
1830
|
+
startTime,
|
|
1831
|
+
collectorLoggerConfig
|
|
1996
1832
|
);
|
|
1997
1833
|
} else {
|
|
1998
|
-
|
|
1999
|
-
|
|
2000
|
-
|
|
1834
|
+
return await executeBundleSimulation(
|
|
1835
|
+
detected.content,
|
|
1836
|
+
detected.platform,
|
|
2001
1837
|
typedEvent,
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
|
|
1838
|
+
tempDir,
|
|
1839
|
+
startTime,
|
|
1840
|
+
collectorLoggerConfig
|
|
2005
1841
|
);
|
|
2006
1842
|
}
|
|
2007
|
-
const elbResult = result.elbResult;
|
|
2008
|
-
const usage = result.usage;
|
|
2009
|
-
const duration = Date.now() - startTime;
|
|
2010
|
-
return {
|
|
2011
|
-
success: true,
|
|
2012
|
-
elbResult,
|
|
2013
|
-
usage,
|
|
2014
|
-
duration,
|
|
2015
|
-
logs: []
|
|
2016
|
-
};
|
|
2017
1843
|
} catch (error) {
|
|
2018
1844
|
const duration = Date.now() - startTime;
|
|
2019
1845
|
return {
|
|
@@ -2028,63 +1854,152 @@ async function executeSimulation(event, configPath) {
|
|
|
2028
1854
|
}
|
|
2029
1855
|
}
|
|
2030
1856
|
}
|
|
1857
|
+
async function executeConfigSimulation(_content, configPath, typedEvent, tempDir, startTime, loggerConfig2) {
|
|
1858
|
+
const { flowConfig, buildOptions } = await loadFlowConfig(configPath);
|
|
1859
|
+
const platform = getPlatform2(flowConfig);
|
|
1860
|
+
const tracker = new CallTracker();
|
|
1861
|
+
const tempOutput = path10.join(
|
|
1862
|
+
tempDir,
|
|
1863
|
+
`simulation-bundle-${generateId()}.${platform === "web" ? "js" : "mjs"}`
|
|
1864
|
+
);
|
|
1865
|
+
const destinations = flowConfig.destinations;
|
|
1866
|
+
const simulationBuildOptions = {
|
|
1867
|
+
...buildOptions,
|
|
1868
|
+
code: buildOptions.code || "",
|
|
1869
|
+
output: tempOutput,
|
|
1870
|
+
tempDir,
|
|
1871
|
+
...platform === "web" ? {
|
|
1872
|
+
format: "iife",
|
|
1873
|
+
platform: "browser",
|
|
1874
|
+
windowCollector: "collector",
|
|
1875
|
+
windowElb: "elb"
|
|
1876
|
+
} : {
|
|
1877
|
+
format: "esm",
|
|
1878
|
+
platform: "node"
|
|
1879
|
+
}
|
|
1880
|
+
};
|
|
1881
|
+
await bundleCore(
|
|
1882
|
+
flowConfig,
|
|
1883
|
+
simulationBuildOptions,
|
|
1884
|
+
createLogger({ silent: true }),
|
|
1885
|
+
false
|
|
1886
|
+
);
|
|
1887
|
+
const envs = await loadDestinationEnvs(destinations || {});
|
|
1888
|
+
let result;
|
|
1889
|
+
if (platform === "web") {
|
|
1890
|
+
result = await executeInJSDOM(
|
|
1891
|
+
tempOutput,
|
|
1892
|
+
destinations || {},
|
|
1893
|
+
typedEvent,
|
|
1894
|
+
tracker,
|
|
1895
|
+
envs,
|
|
1896
|
+
1e4
|
|
1897
|
+
);
|
|
1898
|
+
} else {
|
|
1899
|
+
result = await executeInNode(
|
|
1900
|
+
tempOutput,
|
|
1901
|
+
destinations || {},
|
|
1902
|
+
typedEvent,
|
|
1903
|
+
tracker,
|
|
1904
|
+
envs,
|
|
1905
|
+
3e4,
|
|
1906
|
+
loggerConfig2 ? { logger: loggerConfig2 } : {}
|
|
1907
|
+
);
|
|
1908
|
+
}
|
|
1909
|
+
const duration = Date.now() - startTime;
|
|
1910
|
+
return {
|
|
1911
|
+
success: true,
|
|
1912
|
+
elbResult: result.elbResult,
|
|
1913
|
+
usage: result.usage,
|
|
1914
|
+
duration,
|
|
1915
|
+
logs: []
|
|
1916
|
+
};
|
|
1917
|
+
}
|
|
1918
|
+
async function executeBundleSimulation(bundleContent, platform, typedEvent, tempDir, startTime, loggerConfig2) {
|
|
1919
|
+
const tempOutput = path10.join(
|
|
1920
|
+
tempDir,
|
|
1921
|
+
`bundle-${generateId()}.${platform === "server" ? "mjs" : "js"}`
|
|
1922
|
+
);
|
|
1923
|
+
await fs9.writeFile(tempOutput, bundleContent, "utf8");
|
|
1924
|
+
const tracker = new CallTracker();
|
|
1925
|
+
let result;
|
|
1926
|
+
if (platform === "web") {
|
|
1927
|
+
result = await executeInJSDOM(
|
|
1928
|
+
tempOutput,
|
|
1929
|
+
{},
|
|
1930
|
+
typedEvent,
|
|
1931
|
+
tracker,
|
|
1932
|
+
{},
|
|
1933
|
+
1e4
|
|
1934
|
+
);
|
|
1935
|
+
} else {
|
|
1936
|
+
result = await executeInNode(
|
|
1937
|
+
tempOutput,
|
|
1938
|
+
{},
|
|
1939
|
+
typedEvent,
|
|
1940
|
+
tracker,
|
|
1941
|
+
{},
|
|
1942
|
+
3e4,
|
|
1943
|
+
loggerConfig2 ? { logger: loggerConfig2 } : {}
|
|
1944
|
+
);
|
|
1945
|
+
}
|
|
1946
|
+
const duration = Date.now() - startTime;
|
|
1947
|
+
return {
|
|
1948
|
+
success: true,
|
|
1949
|
+
elbResult: result.elbResult,
|
|
1950
|
+
usage: result.usage,
|
|
1951
|
+
duration,
|
|
1952
|
+
logs: []
|
|
1953
|
+
};
|
|
1954
|
+
}
|
|
2031
1955
|
|
|
2032
1956
|
// src/commands/simulate/index.ts
|
|
2033
1957
|
async function simulateCommand(options) {
|
|
2034
1958
|
const logger2 = createCommandLogger(options);
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
|
|
2043
|
-
|
|
2044
|
-
|
|
2045
|
-
|
|
2046
|
-
|
|
2047
|
-
|
|
2048
|
-
|
|
2049
|
-
|
|
2050
|
-
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
|
|
2055
|
-
|
|
2056
|
-
|
|
2057
|
-
|
|
2058
|
-
|
|
2059
|
-
|
|
2060
|
-
|
|
2061
|
-
|
|
2062
|
-
|
|
2063
|
-
|
|
2064
|
-
|
|
2065
|
-
|
|
2066
|
-
|
|
2067
|
-
|
|
2068
|
-
|
|
2069
|
-
|
|
2070
|
-
|
|
2071
|
-
|
|
2072
|
-
|
|
2073
|
-
|
|
2074
|
-
|
|
2075
|
-
|
|
2076
|
-
|
|
2077
|
-
|
|
2078
|
-
|
|
2079
|
-
process.exit(1);
|
|
2080
|
-
}
|
|
2081
|
-
},
|
|
2082
|
-
"simulate",
|
|
2083
|
-
dockerArgs,
|
|
2084
|
-
options,
|
|
2085
|
-
logger2,
|
|
2086
|
-
options.config
|
|
2087
|
-
);
|
|
1959
|
+
if (options.dryRun) {
|
|
1960
|
+
logger2.log(
|
|
1961
|
+
`[DRY-RUN] Would execute simulate with config: ${options.config}`
|
|
1962
|
+
);
|
|
1963
|
+
return;
|
|
1964
|
+
}
|
|
1965
|
+
const startTime = Date.now();
|
|
1966
|
+
try {
|
|
1967
|
+
const event = await loadJsonFromSource(options.event, {
|
|
1968
|
+
name: "event"
|
|
1969
|
+
});
|
|
1970
|
+
const result = await simulateCore(options.config, event, {
|
|
1971
|
+
json: options.json,
|
|
1972
|
+
verbose: options.verbose,
|
|
1973
|
+
silent: options.silent
|
|
1974
|
+
});
|
|
1975
|
+
const resultWithDuration = {
|
|
1976
|
+
...result,
|
|
1977
|
+
duration: (Date.now() - startTime) / 1e3
|
|
1978
|
+
};
|
|
1979
|
+
if (options.json) {
|
|
1980
|
+
logger2.json(resultWithDuration);
|
|
1981
|
+
} else {
|
|
1982
|
+
const output = formatSimulationResult(resultWithDuration, {
|
|
1983
|
+
json: false
|
|
1984
|
+
});
|
|
1985
|
+
logger2.log(output);
|
|
1986
|
+
}
|
|
1987
|
+
if (!result.success) {
|
|
1988
|
+
process.exit(1);
|
|
1989
|
+
}
|
|
1990
|
+
} catch (error) {
|
|
1991
|
+
const errorMessage = getErrorMessage(error);
|
|
1992
|
+
if (options.json) {
|
|
1993
|
+
logger2.json({
|
|
1994
|
+
success: false,
|
|
1995
|
+
error: errorMessage,
|
|
1996
|
+
duration: (Date.now() - startTime) / 1e3
|
|
1997
|
+
});
|
|
1998
|
+
} else {
|
|
1999
|
+
logger2.error(`Error: ${errorMessage}`);
|
|
2000
|
+
}
|
|
2001
|
+
process.exit(1);
|
|
2002
|
+
}
|
|
2088
2003
|
}
|
|
2089
2004
|
async function simulate(configOrPath, event, options = {}) {
|
|
2090
2005
|
if (typeof configOrPath !== "string") {
|
|
@@ -2102,152 +2017,182 @@ async function simulate(configOrPath, event, options = {}) {
|
|
|
2102
2017
|
import path11 from "path";
|
|
2103
2018
|
import { JSDOM as JSDOM2, VirtualConsole as VirtualConsole2 } from "jsdom";
|
|
2104
2019
|
import fs10 from "fs-extra";
|
|
2105
|
-
import {
|
|
2020
|
+
import {
|
|
2021
|
+
getPlatform as getPlatform3
|
|
2022
|
+
} from "@walkeros/core";
|
|
2106
2023
|
import { schemas as schemas2 } from "@walkeros/core/dev";
|
|
2107
2024
|
async function pushCommand(options) {
|
|
2108
2025
|
const logger2 = createCommandLogger(options);
|
|
2109
|
-
const
|
|
2110
|
-
|
|
2111
|
-
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
-
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
|
|
2122
|
-
|
|
2123
|
-
|
|
2124
|
-
|
|
2125
|
-
|
|
2126
|
-
|
|
2127
|
-
|
|
2128
|
-
|
|
2129
|
-
|
|
2130
|
-
|
|
2131
|
-
|
|
2132
|
-
|
|
2133
|
-
|
|
2134
|
-
|
|
2135
|
-
|
|
2136
|
-
|
|
2026
|
+
const startTime = Date.now();
|
|
2027
|
+
let tempDir;
|
|
2028
|
+
try {
|
|
2029
|
+
logger2.debug("Loading event");
|
|
2030
|
+
const event = await loadJsonFromSource(options.event, {
|
|
2031
|
+
name: "event"
|
|
2032
|
+
});
|
|
2033
|
+
const eventResult = schemas2.PartialEventSchema.safeParse(event);
|
|
2034
|
+
if (!eventResult.success) {
|
|
2035
|
+
const errors = eventResult.error.issues.map((issue) => `${String(issue.path.join("."))}: ${issue.message}`).join(", ");
|
|
2036
|
+
throw new Error(`Invalid event: ${errors}`);
|
|
2037
|
+
}
|
|
2038
|
+
const parsedEvent = eventResult.data;
|
|
2039
|
+
if (!parsedEvent.name) {
|
|
2040
|
+
throw new Error('Invalid event: Missing required "name" property');
|
|
2041
|
+
}
|
|
2042
|
+
const validatedEvent = {
|
|
2043
|
+
name: parsedEvent.name,
|
|
2044
|
+
data: parsedEvent.data || {}
|
|
2045
|
+
};
|
|
2046
|
+
if (!validatedEvent.name.includes(" ")) {
|
|
2047
|
+
logger2.log(
|
|
2048
|
+
`Warning: Event name "${validatedEvent.name}" should follow "ENTITY ACTION" format (e.g., "page view")`
|
|
2049
|
+
);
|
|
2050
|
+
}
|
|
2051
|
+
logger2.debug("Detecting input type");
|
|
2052
|
+
const detected = await detectInput(options.config, options.platform);
|
|
2053
|
+
let result;
|
|
2054
|
+
if (detected.type === "config") {
|
|
2055
|
+
result = await executeConfigPush(
|
|
2056
|
+
options,
|
|
2057
|
+
validatedEvent,
|
|
2058
|
+
logger2,
|
|
2059
|
+
(dir) => {
|
|
2060
|
+
tempDir = dir;
|
|
2137
2061
|
}
|
|
2138
|
-
|
|
2139
|
-
|
|
2140
|
-
|
|
2141
|
-
|
|
2142
|
-
|
|
2143
|
-
|
|
2144
|
-
|
|
2145
|
-
|
|
2146
|
-
|
|
2147
|
-
|
|
2148
|
-
|
|
2149
|
-
|
|
2150
|
-
|
|
2151
|
-
|
|
2152
|
-
|
|
2153
|
-
|
|
2154
|
-
|
|
2155
|
-
|
|
2156
|
-
|
|
2157
|
-
|
|
2158
|
-
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
|
|
2062
|
+
);
|
|
2063
|
+
} else {
|
|
2064
|
+
const collectorLoggerConfig = createCollectorLoggerConfig(
|
|
2065
|
+
logger2,
|
|
2066
|
+
options.verbose
|
|
2067
|
+
);
|
|
2068
|
+
result = await executeBundlePush(
|
|
2069
|
+
detected.content,
|
|
2070
|
+
detected.platform,
|
|
2071
|
+
validatedEvent,
|
|
2072
|
+
logger2,
|
|
2073
|
+
(dir) => {
|
|
2074
|
+
tempDir = dir;
|
|
2075
|
+
},
|
|
2076
|
+
{ logger: collectorLoggerConfig }
|
|
2077
|
+
);
|
|
2078
|
+
}
|
|
2079
|
+
const duration = Date.now() - startTime;
|
|
2080
|
+
if (options.json) {
|
|
2081
|
+
logger2.json({
|
|
2082
|
+
success: result.success,
|
|
2083
|
+
event: result.elbResult,
|
|
2084
|
+
duration
|
|
2085
|
+
});
|
|
2086
|
+
} else {
|
|
2087
|
+
if (result.success) {
|
|
2088
|
+
logger2.log("Event pushed successfully");
|
|
2089
|
+
if (result.elbResult && typeof result.elbResult === "object") {
|
|
2090
|
+
const pushResult = result.elbResult;
|
|
2091
|
+
if ("id" in pushResult && pushResult.id) {
|
|
2092
|
+
logger2.log(` Event ID: ${pushResult.id}`);
|
|
2168
2093
|
}
|
|
2169
|
-
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
|
|
2173
|
-
|
|
2174
|
-
logger2.info("\u{1F310} Executing in web environment (JSDOM)...");
|
|
2175
|
-
result = await executeWebPush(tempPath, validatedEvent, logger2);
|
|
2176
|
-
} else if (platform === "server") {
|
|
2177
|
-
logger2.info("\u{1F5A5}\uFE0F Executing in server environment (Node.js)...");
|
|
2178
|
-
result = await executeServerPush(tempPath, validatedEvent, logger2);
|
|
2179
|
-
} else {
|
|
2180
|
-
throw new Error(`Unsupported platform: ${platform}`);
|
|
2181
|
-
}
|
|
2182
|
-
const duration = Date.now() - startTime;
|
|
2183
|
-
if (options.json) {
|
|
2184
|
-
const outputLogger = createLogger({ silent: false, json: false });
|
|
2185
|
-
outputLogger.log(
|
|
2186
|
-
"white",
|
|
2187
|
-
JSON.stringify(
|
|
2188
|
-
{
|
|
2189
|
-
success: result.success,
|
|
2190
|
-
event: result.elbResult,
|
|
2191
|
-
duration
|
|
2192
|
-
},
|
|
2193
|
-
null,
|
|
2194
|
-
2
|
|
2195
|
-
)
|
|
2196
|
-
);
|
|
2197
|
-
} else {
|
|
2198
|
-
if (result.success) {
|
|
2199
|
-
logger2.success("\u2705 Event pushed successfully");
|
|
2200
|
-
if (result.elbResult && typeof result.elbResult === "object") {
|
|
2201
|
-
const pushResult = result.elbResult;
|
|
2202
|
-
if ("id" in pushResult && pushResult.id) {
|
|
2203
|
-
logger2.info(` Event ID: ${pushResult.id}`);
|
|
2204
|
-
}
|
|
2205
|
-
if ("entity" in pushResult && pushResult.entity) {
|
|
2206
|
-
logger2.info(` Entity: ${pushResult.entity}`);
|
|
2207
|
-
}
|
|
2208
|
-
if ("action" in pushResult && pushResult.action) {
|
|
2209
|
-
logger2.info(` Action: ${pushResult.action}`);
|
|
2210
|
-
}
|
|
2211
|
-
}
|
|
2212
|
-
logger2.info(` Duration: ${duration}ms`);
|
|
2213
|
-
} else {
|
|
2214
|
-
logger2.error(`\u274C Push failed: ${result.error}`);
|
|
2215
|
-
process.exit(1);
|
|
2094
|
+
if ("entity" in pushResult && pushResult.entity) {
|
|
2095
|
+
logger2.log(` Entity: ${pushResult.entity}`);
|
|
2096
|
+
}
|
|
2097
|
+
if ("action" in pushResult && pushResult.action) {
|
|
2098
|
+
logger2.log(` Action: ${pushResult.action}`);
|
|
2216
2099
|
}
|
|
2217
2100
|
}
|
|
2218
|
-
|
|
2219
|
-
|
|
2220
|
-
|
|
2221
|
-
}
|
|
2222
|
-
} catch (error) {
|
|
2223
|
-
const duration = Date.now() - startTime;
|
|
2224
|
-
const errorMessage = getErrorMessage(error);
|
|
2225
|
-
if (options.json) {
|
|
2226
|
-
const outputLogger = createLogger({ silent: false, json: false });
|
|
2227
|
-
outputLogger.log(
|
|
2228
|
-
"white",
|
|
2229
|
-
JSON.stringify(
|
|
2230
|
-
{
|
|
2231
|
-
success: false,
|
|
2232
|
-
error: errorMessage,
|
|
2233
|
-
duration
|
|
2234
|
-
},
|
|
2235
|
-
null,
|
|
2236
|
-
2
|
|
2237
|
-
)
|
|
2238
|
-
);
|
|
2239
|
-
} else {
|
|
2240
|
-
logger2.error(`\u274C Push command failed: ${errorMessage}`);
|
|
2241
|
-
}
|
|
2101
|
+
logger2.log(` Duration: ${duration}ms`);
|
|
2102
|
+
} else {
|
|
2103
|
+
logger2.error(`Error: ${result.error}`);
|
|
2242
2104
|
process.exit(1);
|
|
2243
2105
|
}
|
|
2244
|
-
}
|
|
2245
|
-
|
|
2246
|
-
|
|
2247
|
-
|
|
2248
|
-
|
|
2249
|
-
|
|
2106
|
+
}
|
|
2107
|
+
} catch (error) {
|
|
2108
|
+
const duration = Date.now() - startTime;
|
|
2109
|
+
const errorMessage = getErrorMessage(error);
|
|
2110
|
+
if (options.json) {
|
|
2111
|
+
logger2.json({
|
|
2112
|
+
success: false,
|
|
2113
|
+
error: errorMessage,
|
|
2114
|
+
duration
|
|
2115
|
+
});
|
|
2116
|
+
} else {
|
|
2117
|
+
logger2.error(`Error: ${errorMessage}`);
|
|
2118
|
+
}
|
|
2119
|
+
process.exit(1);
|
|
2120
|
+
} finally {
|
|
2121
|
+
if (tempDir) {
|
|
2122
|
+
await fs10.remove(tempDir).catch(() => {
|
|
2123
|
+
});
|
|
2124
|
+
}
|
|
2125
|
+
}
|
|
2126
|
+
}
|
|
2127
|
+
async function executeConfigPush(options, validatedEvent, logger2, setTempDir) {
|
|
2128
|
+
logger2.debug("Loading flow configuration");
|
|
2129
|
+
const { flowConfig, buildOptions } = await loadFlowConfig(options.config, {
|
|
2130
|
+
flowName: options.flow,
|
|
2131
|
+
logger: logger2
|
|
2132
|
+
});
|
|
2133
|
+
const platform = getPlatform3(flowConfig);
|
|
2134
|
+
logger2.debug("Bundling flow configuration");
|
|
2135
|
+
const configDir = buildOptions.configDir || process.cwd();
|
|
2136
|
+
const tempDir = path11.join(
|
|
2137
|
+
configDir,
|
|
2138
|
+
".tmp",
|
|
2139
|
+
`push-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`
|
|
2140
|
+
);
|
|
2141
|
+
setTempDir(tempDir);
|
|
2142
|
+
await fs10.ensureDir(tempDir);
|
|
2143
|
+
const tempPath = path11.join(
|
|
2144
|
+
tempDir,
|
|
2145
|
+
`bundle.${platform === "web" ? "js" : "mjs"}`
|
|
2250
2146
|
);
|
|
2147
|
+
const pushBuildOptions = {
|
|
2148
|
+
...buildOptions,
|
|
2149
|
+
output: tempPath,
|
|
2150
|
+
format: platform === "web" ? "iife" : "esm",
|
|
2151
|
+
platform: platform === "web" ? "browser" : "node",
|
|
2152
|
+
...platform === "web" && {
|
|
2153
|
+
windowCollector: "collector",
|
|
2154
|
+
windowElb: "elb"
|
|
2155
|
+
}
|
|
2156
|
+
};
|
|
2157
|
+
await bundleCore(flowConfig, pushBuildOptions, logger2, false);
|
|
2158
|
+
logger2.debug(`Bundle created: ${tempPath}`);
|
|
2159
|
+
if (platform === "web") {
|
|
2160
|
+
logger2.debug("Executing in web environment (JSDOM)");
|
|
2161
|
+
return executeWebPush(tempPath, validatedEvent, logger2);
|
|
2162
|
+
} else if (platform === "server") {
|
|
2163
|
+
logger2.debug("Executing in server environment (Node.js)");
|
|
2164
|
+
const collectorLoggerConfig = createCollectorLoggerConfig(
|
|
2165
|
+
logger2,
|
|
2166
|
+
options.verbose
|
|
2167
|
+
);
|
|
2168
|
+
return executeServerPush(tempPath, validatedEvent, logger2, 6e4, {
|
|
2169
|
+
logger: collectorLoggerConfig
|
|
2170
|
+
});
|
|
2171
|
+
} else {
|
|
2172
|
+
throw new Error(`Unsupported platform: ${platform}`);
|
|
2173
|
+
}
|
|
2174
|
+
}
|
|
2175
|
+
async function executeBundlePush(bundleContent, platform, validatedEvent, logger2, setTempDir, context = {}) {
|
|
2176
|
+
const tempDir = path11.join(
|
|
2177
|
+
process.cwd(),
|
|
2178
|
+
".tmp",
|
|
2179
|
+
`push-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`
|
|
2180
|
+
);
|
|
2181
|
+
setTempDir(tempDir);
|
|
2182
|
+
await fs10.ensureDir(tempDir);
|
|
2183
|
+
const tempPath = path11.join(
|
|
2184
|
+
tempDir,
|
|
2185
|
+
`bundle.${platform === "server" ? "mjs" : "js"}`
|
|
2186
|
+
);
|
|
2187
|
+
await fs10.writeFile(tempPath, bundleContent, "utf8");
|
|
2188
|
+
logger2.debug(`Bundle written to: ${tempPath}`);
|
|
2189
|
+
if (platform === "web") {
|
|
2190
|
+
logger2.debug("Executing in web environment (JSDOM)");
|
|
2191
|
+
return executeWebPush(tempPath, validatedEvent, logger2);
|
|
2192
|
+
} else {
|
|
2193
|
+
logger2.debug("Executing in server environment (Node.js)");
|
|
2194
|
+
return executeServerPush(tempPath, validatedEvent, logger2, 6e4, context);
|
|
2195
|
+
}
|
|
2251
2196
|
}
|
|
2252
2197
|
async function executeWebPush(bundlePath, event, logger2) {
|
|
2253
2198
|
const startTime = Date.now();
|
|
@@ -2263,16 +2208,19 @@ async function executeWebPush(bundlePath, event, logger2) {
|
|
|
2263
2208
|
logger2.debug("Loading bundle...");
|
|
2264
2209
|
const bundleCode = await fs10.readFile(bundlePath, "utf8");
|
|
2265
2210
|
window.eval(bundleCode);
|
|
2266
|
-
logger2.debug("Waiting for
|
|
2211
|
+
logger2.debug("Waiting for collector...");
|
|
2267
2212
|
await waitForWindowProperty2(
|
|
2268
2213
|
window,
|
|
2269
|
-
"
|
|
2214
|
+
"collector",
|
|
2270
2215
|
5e3
|
|
2271
2216
|
);
|
|
2272
2217
|
const windowObj = window;
|
|
2273
|
-
const
|
|
2274
|
-
logger2.
|
|
2275
|
-
const elbResult = await
|
|
2218
|
+
const collector = windowObj.collector;
|
|
2219
|
+
logger2.log(`Pushing event: ${event.name}`);
|
|
2220
|
+
const elbResult = await collector.push({
|
|
2221
|
+
name: event.name,
|
|
2222
|
+
data: event.data
|
|
2223
|
+
});
|
|
2276
2224
|
return {
|
|
2277
2225
|
success: true,
|
|
2278
2226
|
elbResult,
|
|
@@ -2286,7 +2234,7 @@ async function executeWebPush(bundlePath, event, logger2) {
|
|
|
2286
2234
|
};
|
|
2287
2235
|
}
|
|
2288
2236
|
}
|
|
2289
|
-
async function executeServerPush(bundlePath, event, logger2, timeout = 6e4) {
|
|
2237
|
+
async function executeServerPush(bundlePath, event, logger2, timeout = 6e4, context = {}) {
|
|
2290
2238
|
const startTime = Date.now();
|
|
2291
2239
|
try {
|
|
2292
2240
|
const timeoutPromise = new Promise((_, reject) => {
|
|
@@ -2302,15 +2250,18 @@ async function executeServerPush(bundlePath, event, logger2, timeout = 6e4) {
|
|
|
2302
2250
|
throw new Error("Bundle does not export default factory function");
|
|
2303
2251
|
}
|
|
2304
2252
|
logger2.debug("Calling factory function...");
|
|
2305
|
-
const result = await flowModule.default();
|
|
2306
|
-
if (!result || !result.
|
|
2253
|
+
const result = await flowModule.default(context);
|
|
2254
|
+
if (!result || !result.collector || typeof result.collector.push !== "function") {
|
|
2307
2255
|
throw new Error(
|
|
2308
|
-
"Factory function did not return valid result with
|
|
2256
|
+
"Factory function did not return valid result with collector"
|
|
2309
2257
|
);
|
|
2310
2258
|
}
|
|
2311
|
-
const {
|
|
2312
|
-
logger2.
|
|
2313
|
-
const elbResult = await
|
|
2259
|
+
const { collector } = result;
|
|
2260
|
+
logger2.log(`Pushing event: ${event.name}`);
|
|
2261
|
+
const elbResult = await collector.push({
|
|
2262
|
+
name: event.name,
|
|
2263
|
+
data: event.data
|
|
2264
|
+
});
|
|
2314
2265
|
return {
|
|
2315
2266
|
success: true,
|
|
2316
2267
|
elbResult,
|
|
@@ -2327,11 +2278,11 @@ async function executeServerPush(bundlePath, event, logger2, timeout = 6e4) {
|
|
|
2327
2278
|
}
|
|
2328
2279
|
}
|
|
2329
2280
|
function waitForWindowProperty2(window, prop, timeout = 5e3) {
|
|
2330
|
-
return new Promise((
|
|
2281
|
+
return new Promise((resolve3, reject) => {
|
|
2331
2282
|
const start = Date.now();
|
|
2332
2283
|
const check = () => {
|
|
2333
2284
|
if (window[prop] !== void 0) {
|
|
2334
|
-
|
|
2285
|
+
resolve3();
|
|
2335
2286
|
} else if (Date.now() - start > timeout) {
|
|
2336
2287
|
reject(
|
|
2337
2288
|
new Error(
|
|
@@ -2430,9 +2381,132 @@ function isPreBuiltConfig(configPath) {
|
|
|
2430
2381
|
|
|
2431
2382
|
// src/commands/run/execution.ts
|
|
2432
2383
|
import { createLogger as createLogger2, Level } from "@walkeros/core";
|
|
2433
|
-
|
|
2384
|
+
|
|
2385
|
+
// src/runtime/runner.ts
|
|
2386
|
+
import { pathToFileURL as pathToFileURL2 } from "url";
|
|
2387
|
+
import { resolve, dirname as dirname2 } from "path";
|
|
2388
|
+
async function runFlow(file, config, logger2, loggerConfig2) {
|
|
2389
|
+
logger2.info(`Loading flow from ${file}`);
|
|
2390
|
+
try {
|
|
2391
|
+
const absolutePath = resolve(file);
|
|
2392
|
+
const flowDir = dirname2(absolutePath);
|
|
2393
|
+
process.chdir(flowDir);
|
|
2394
|
+
const fileUrl = pathToFileURL2(absolutePath).href;
|
|
2395
|
+
const module = await import(fileUrl);
|
|
2396
|
+
if (!module.default || typeof module.default !== "function") {
|
|
2397
|
+
logger2.throw(
|
|
2398
|
+
`Invalid flow bundle: ${file} must export a default function`
|
|
2399
|
+
);
|
|
2400
|
+
}
|
|
2401
|
+
const flowContext = loggerConfig2 ? { ...config, logger: loggerConfig2 } : config;
|
|
2402
|
+
const result = await module.default(flowContext);
|
|
2403
|
+
if (!result || !result.collector) {
|
|
2404
|
+
logger2.throw(`Invalid flow bundle: ${file} must return { collector }`);
|
|
2405
|
+
}
|
|
2406
|
+
const { collector } = result;
|
|
2407
|
+
logger2.info("Flow running");
|
|
2408
|
+
if (config?.port) {
|
|
2409
|
+
logger2.info(`Port: ${config.port}`);
|
|
2410
|
+
}
|
|
2411
|
+
const shutdown = async (signal) => {
|
|
2412
|
+
logger2.info(`Received ${signal}, shutting down gracefully...`);
|
|
2413
|
+
try {
|
|
2414
|
+
if (collector.command) {
|
|
2415
|
+
await collector.command("shutdown");
|
|
2416
|
+
}
|
|
2417
|
+
logger2.info("Shutdown complete");
|
|
2418
|
+
process.exit(0);
|
|
2419
|
+
} catch (error) {
|
|
2420
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
2421
|
+
logger2.error(`Error during shutdown: ${message}`);
|
|
2422
|
+
process.exit(1);
|
|
2423
|
+
}
|
|
2424
|
+
};
|
|
2425
|
+
process.on("SIGTERM", () => shutdown("SIGTERM"));
|
|
2426
|
+
process.on("SIGINT", () => shutdown("SIGINT"));
|
|
2427
|
+
await new Promise(() => {
|
|
2428
|
+
});
|
|
2429
|
+
} catch (error) {
|
|
2430
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
2431
|
+
logger2.error(`Failed to run flow: ${message}`);
|
|
2432
|
+
if (error instanceof Error && error.stack) {
|
|
2433
|
+
logger2.debug("Stack trace:", { stack: error.stack });
|
|
2434
|
+
}
|
|
2435
|
+
throw error;
|
|
2436
|
+
}
|
|
2437
|
+
}
|
|
2438
|
+
|
|
2439
|
+
// src/runtime/serve.ts
|
|
2440
|
+
import express from "express";
|
|
2441
|
+
import { resolve as resolve2 } from "path";
|
|
2442
|
+
async function runServeMode(config, logger2) {
|
|
2443
|
+
const port = process.env.PORT ? parseInt(process.env.PORT, 10) : config?.port || 8080;
|
|
2444
|
+
const host = process.env.HOST || config?.host || "0.0.0.0";
|
|
2445
|
+
const file = resolve2(process.env.FILE || config?.file || "./dist/walker.js");
|
|
2446
|
+
const serveName = process.env.SERVE_NAME || config?.serveName || "walker.js";
|
|
2447
|
+
const servePath = process.env.SERVE_PATH || config?.servePath || "";
|
|
2448
|
+
const urlPath = servePath ? `/${servePath}/${serveName}` : `/${serveName}`;
|
|
2449
|
+
logger2.info("Starting single-file server...");
|
|
2450
|
+
logger2.info(`File: ${file}`);
|
|
2451
|
+
logger2.info(`URL: http://${host}:${port}${urlPath}`);
|
|
2452
|
+
try {
|
|
2453
|
+
const app = express();
|
|
2454
|
+
app.get("/health", (req, res) => {
|
|
2455
|
+
res.json({
|
|
2456
|
+
status: "ok",
|
|
2457
|
+
version: VERSION,
|
|
2458
|
+
timestamp: Date.now(),
|
|
2459
|
+
mode: "serve",
|
|
2460
|
+
file,
|
|
2461
|
+
url: urlPath
|
|
2462
|
+
});
|
|
2463
|
+
});
|
|
2464
|
+
app.get(urlPath, (req, res) => {
|
|
2465
|
+
res.type("application/javascript");
|
|
2466
|
+
res.sendFile(file, { dotfiles: "allow" }, (err) => {
|
|
2467
|
+
if (err && !res.headersSent) {
|
|
2468
|
+
const errCode = err.code;
|
|
2469
|
+
const errStatus = err.status || err.statusCode;
|
|
2470
|
+
if (errCode !== "ECONNABORTED") {
|
|
2471
|
+
logger2.error(
|
|
2472
|
+
`sendFile error for ${file}: ${err.message} (code: ${errCode}, status: ${errStatus})`
|
|
2473
|
+
);
|
|
2474
|
+
}
|
|
2475
|
+
if (errStatus === 404 || errCode === "ENOENT" || errCode === "EISDIR" || errCode === "ENOTDIR") {
|
|
2476
|
+
res.status(404).send("File not found");
|
|
2477
|
+
} else if (errCode !== "ECONNABORTED") {
|
|
2478
|
+
res.status(500).send("Internal server error");
|
|
2479
|
+
}
|
|
2480
|
+
}
|
|
2481
|
+
});
|
|
2482
|
+
});
|
|
2483
|
+
const server = app.listen(port, host, () => {
|
|
2484
|
+
logger2.info(`Server listening on http://${host}:${port}`);
|
|
2485
|
+
logger2.info(`GET ${urlPath} - Bundle file`);
|
|
2486
|
+
logger2.info(`GET /health - Health check`);
|
|
2487
|
+
});
|
|
2488
|
+
const shutdownHandler = (signal) => {
|
|
2489
|
+
logger2.info(`Received ${signal}, shutting down...`);
|
|
2490
|
+
server.close(() => {
|
|
2491
|
+
logger2.info("Server closed");
|
|
2492
|
+
process.exit(0);
|
|
2493
|
+
});
|
|
2494
|
+
};
|
|
2495
|
+
process.on("SIGTERM", () => shutdownHandler("SIGTERM"));
|
|
2496
|
+
process.on("SIGINT", () => shutdownHandler("SIGINT"));
|
|
2497
|
+
await new Promise(() => {
|
|
2498
|
+
});
|
|
2499
|
+
} catch (error) {
|
|
2500
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
2501
|
+
logger2.error(`Server failed: ${message}`);
|
|
2502
|
+
process.exit(1);
|
|
2503
|
+
}
|
|
2504
|
+
}
|
|
2505
|
+
|
|
2506
|
+
// src/commands/run/execution.ts
|
|
2434
2507
|
var logLevel = process.env.VERBOSE === "true" ? Level.DEBUG : Level.INFO;
|
|
2435
|
-
var
|
|
2508
|
+
var loggerConfig = { level: logLevel };
|
|
2509
|
+
var logger = createLogger2(loggerConfig);
|
|
2436
2510
|
async function executeRunLocal(mode, flowPath, options) {
|
|
2437
2511
|
switch (mode) {
|
|
2438
2512
|
case "collect": {
|
|
@@ -2443,7 +2517,7 @@ async function executeRunLocal(mode, flowPath, options) {
|
|
|
2443
2517
|
port: options.port,
|
|
2444
2518
|
host: options.host
|
|
2445
2519
|
};
|
|
2446
|
-
await runFlow(flowPath, config, logger.scope("runner"));
|
|
2520
|
+
await runFlow(flowPath, config, logger.scope("runner"), loggerConfig);
|
|
2447
2521
|
break;
|
|
2448
2522
|
}
|
|
2449
2523
|
case "serve": {
|
|
@@ -2478,76 +2552,40 @@ async function runCommand(mode, options) {
|
|
|
2478
2552
|
if (mode === "collect") {
|
|
2479
2553
|
if (isPreBuilt) {
|
|
2480
2554
|
flowPath = path13.resolve(configPath);
|
|
2481
|
-
|
|
2482
|
-
logger2.info(`\u{1F4E6} Using pre-built flow: ${path13.basename(flowPath)}`);
|
|
2483
|
-
}
|
|
2555
|
+
logger2.debug(`Using pre-built flow: ${path13.basename(flowPath)}`);
|
|
2484
2556
|
} else {
|
|
2485
|
-
|
|
2486
|
-
logger2.info("\u{1F528} Building flow bundle...");
|
|
2487
|
-
}
|
|
2557
|
+
logger2.debug("Building flow bundle");
|
|
2488
2558
|
flowPath = await prepareBundleForRun(configPath, {
|
|
2489
2559
|
verbose: options.verbose,
|
|
2490
2560
|
silent: options.json || options.silent
|
|
2491
2561
|
});
|
|
2492
|
-
|
|
2493
|
-
logger2.success("\u2705 Bundle ready");
|
|
2494
|
-
}
|
|
2562
|
+
logger2.debug("Bundle ready");
|
|
2495
2563
|
}
|
|
2496
2564
|
}
|
|
2497
|
-
const executionMode = getExecutionMode(options);
|
|
2498
2565
|
if (options.dryRun) {
|
|
2499
|
-
|
|
2500
|
-
logger2.info(
|
|
2501
|
-
`[DRY-RUN] Would execute in Docker: run ${mode} with runtime image`
|
|
2502
|
-
);
|
|
2503
|
-
} else {
|
|
2504
|
-
logger2.info(`[DRY-RUN] Would execute locally: run ${mode}`);
|
|
2505
|
-
}
|
|
2566
|
+
logger2.log(`[DRY-RUN] Would execute locally: run ${mode}`);
|
|
2506
2567
|
return;
|
|
2507
2568
|
}
|
|
2508
|
-
|
|
2509
|
-
|
|
2510
|
-
|
|
2511
|
-
|
|
2512
|
-
|
|
2513
|
-
|
|
2514
|
-
|
|
2515
|
-
|
|
2516
|
-
logger2.info("\u{1F433} Executing in production runtime container...");
|
|
2517
|
-
}
|
|
2518
|
-
await executeRunInDocker(mode, flowPath, {
|
|
2519
|
-
port: options.port,
|
|
2520
|
-
host: options.host,
|
|
2521
|
-
serveName: options.serveName,
|
|
2522
|
-
servePath: options.servePath,
|
|
2523
|
-
silent: options.silent
|
|
2524
|
-
});
|
|
2525
|
-
} else {
|
|
2526
|
-
if (!options.json && !options.silent) {
|
|
2527
|
-
const modeLabel = mode === "collect" ? "Collector" : "Server";
|
|
2528
|
-
logger2.info(`\u{1F5A5}\uFE0F Starting ${modeLabel} locally...`);
|
|
2529
|
-
}
|
|
2530
|
-
await executeRunLocal(mode, flowPath, {
|
|
2531
|
-
port: options.port,
|
|
2532
|
-
host: options.host,
|
|
2533
|
-
serveName: options.serveName,
|
|
2534
|
-
servePath: options.servePath
|
|
2535
|
-
});
|
|
2536
|
-
}
|
|
2569
|
+
const modeLabel = mode === "collect" ? "Collector" : "Server";
|
|
2570
|
+
logger2.log(`Starting ${modeLabel}...`);
|
|
2571
|
+
await executeRunLocal(mode, flowPath, {
|
|
2572
|
+
port: options.port,
|
|
2573
|
+
host: options.host,
|
|
2574
|
+
serveName: options.serveName,
|
|
2575
|
+
servePath: options.servePath
|
|
2576
|
+
});
|
|
2537
2577
|
} catch (error) {
|
|
2538
2578
|
const duration = timer.getElapsed() / 1e3;
|
|
2539
2579
|
const errorMessage = getErrorMessage(error);
|
|
2540
2580
|
if (options.json) {
|
|
2541
|
-
|
|
2581
|
+
logger2.json({
|
|
2542
2582
|
success: false,
|
|
2543
2583
|
mode,
|
|
2544
2584
|
error: errorMessage,
|
|
2545
2585
|
duration
|
|
2546
|
-
};
|
|
2547
|
-
console.log(JSON.stringify(output, null, 2));
|
|
2586
|
+
});
|
|
2548
2587
|
} else {
|
|
2549
|
-
logger2.error(
|
|
2550
|
-
logger2.error(errorMessage);
|
|
2588
|
+
logger2.error(`Error: ${errorMessage}`);
|
|
2551
2589
|
}
|
|
2552
2590
|
process.exit(1);
|
|
2553
2591
|
}
|
|
@@ -2598,30 +2636,40 @@ async function run(mode, options) {
|
|
|
2598
2636
|
|
|
2599
2637
|
// src/commands/cache.ts
|
|
2600
2638
|
import fs12 from "fs-extra";
|
|
2601
|
-
import path14 from "path";
|
|
2602
|
-
var CACHE_DIR = path14.join(".tmp", "cache");
|
|
2603
2639
|
function registerCacheCommand(program2) {
|
|
2604
2640
|
const cache = program2.command("cache").description("Manage the CLI cache");
|
|
2605
|
-
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) => {
|
|
2641
|
+
cache.command("clear").description("Clear all cached packages and builds").option("--packages", "Clear only package cache").option("--builds", "Clear only build cache").option("--tmp-dir <dir>", "Custom temp directory").option("--silent", "Suppress output").action(async (options) => {
|
|
2642
|
+
const logger2 = createLogger({ silent: options.silent });
|
|
2643
|
+
const tmpDir = options.tmpDir;
|
|
2606
2644
|
if (options.packages) {
|
|
2607
|
-
await fs12.remove(
|
|
2608
|
-
|
|
2645
|
+
await fs12.remove(getTmpPath(tmpDir, "cache", "packages"));
|
|
2646
|
+
logger2.log("Package cache cleared");
|
|
2609
2647
|
} else if (options.builds) {
|
|
2610
|
-
await fs12.remove(
|
|
2611
|
-
|
|
2648
|
+
await fs12.remove(getTmpPath(tmpDir, "cache", "builds"));
|
|
2649
|
+
logger2.log("Build cache cleared");
|
|
2612
2650
|
} else {
|
|
2613
|
-
await fs12.remove(
|
|
2614
|
-
|
|
2651
|
+
await fs12.remove(getTmpPath(tmpDir, "cache"));
|
|
2652
|
+
logger2.log("All caches cleared");
|
|
2615
2653
|
}
|
|
2616
2654
|
});
|
|
2617
|
-
cache.command("info").description("Show cache statistics").action(async () => {
|
|
2618
|
-
const
|
|
2619
|
-
const
|
|
2655
|
+
cache.command("info").description("Show cache statistics").option("--tmp-dir <dir>", "Custom temp directory").option("--silent", "Suppress output").action(async (options) => {
|
|
2656
|
+
const logger2 = createLogger({ silent: options.silent });
|
|
2657
|
+
const tmpDir = options.tmpDir;
|
|
2658
|
+
const packagesDir = getTmpPath(tmpDir, "cache", "packages");
|
|
2659
|
+
const buildsDir = getTmpPath(tmpDir, "cache", "builds");
|
|
2620
2660
|
const packageCount = await countEntries(packagesDir);
|
|
2621
2661
|
const buildCount = await countEntries(buildsDir);
|
|
2622
|
-
|
|
2623
|
-
|
|
2624
|
-
|
|
2662
|
+
logger2.log(`Cache directory: ${getTmpPath(tmpDir, "cache")}`);
|
|
2663
|
+
logger2.log(`Cached packages: ${packageCount}`);
|
|
2664
|
+
logger2.log(`Cached builds: ${buildCount}`);
|
|
2665
|
+
});
|
|
2666
|
+
}
|
|
2667
|
+
function registerCleanCommand(program2) {
|
|
2668
|
+
program2.command("clean").description("Clear the entire temp directory (.tmp/)").option("--tmp-dir <dir>", "Custom temp directory").option("--silent", "Suppress output").action(async (options) => {
|
|
2669
|
+
const logger2 = createLogger({ silent: options.silent });
|
|
2670
|
+
const tmpDir = options.tmpDir || getDefaultTmpRoot();
|
|
2671
|
+
await fs12.remove(tmpDir);
|
|
2672
|
+
logger2.log(`Temp directory cleared: ${tmpDir}`);
|
|
2625
2673
|
});
|
|
2626
2674
|
}
|
|
2627
2675
|
async function countEntries(dir) {
|
|
@@ -2631,22 +2679,15 @@ async function countEntries(dir) {
|
|
|
2631
2679
|
}
|
|
2632
2680
|
|
|
2633
2681
|
// src/index.ts
|
|
2634
|
-
var __filename = fileURLToPath2(import.meta.url);
|
|
2635
|
-
var __dirname = dirname(__filename);
|
|
2636
|
-
var packageJson = JSON.parse(
|
|
2637
|
-
readFileSync(join(__dirname, "../package.json"), "utf-8")
|
|
2638
|
-
);
|
|
2639
|
-
var VERSION = packageJson.version;
|
|
2640
2682
|
var program = new Command();
|
|
2641
2683
|
program.name("walkeros").description("walkerOS CLI - Bundle and deploy walkerOS components").version(VERSION);
|
|
2642
2684
|
program.hook("preAction", (thisCommand, actionCommand) => {
|
|
2643
2685
|
const options = actionCommand.opts();
|
|
2644
2686
|
if (!options.silent && !options.json) {
|
|
2645
|
-
console.log(
|
|
2646
|
-
console.log(`\u{1F433} Using Docker runtime: walkeros/docker:${DOCKER_VERSION2}`);
|
|
2687
|
+
console.log(chalk2.hex("#01b5e2")(`walkerOS v${VERSION}`));
|
|
2647
2688
|
}
|
|
2648
2689
|
});
|
|
2649
|
-
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("--
|
|
2690
|
+
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("--dry-run", "preview command without executing").option("--silent", "suppress output").action(async (file, options) => {
|
|
2650
2691
|
await bundleCommand({
|
|
2651
2692
|
config: file || "bundle.config.json",
|
|
2652
2693
|
flow: options.flow,
|
|
@@ -2655,7 +2696,6 @@ program.command("bundle [file]").description("Bundle NPM packages with custom co
|
|
|
2655
2696
|
json: options.json,
|
|
2656
2697
|
cache: options.cache,
|
|
2657
2698
|
verbose: options.verbose,
|
|
2658
|
-
local: options.local,
|
|
2659
2699
|
dryRun: options.dryRun,
|
|
2660
2700
|
silent: options.silent
|
|
2661
2701
|
});
|
|
@@ -2663,13 +2703,13 @@ program.command("bundle [file]").description("Bundle NPM packages with custom co
|
|
|
2663
2703
|
program.command("simulate [file]").description("Simulate event processing and capture API calls").option(
|
|
2664
2704
|
"-e, --event <source>",
|
|
2665
2705
|
"Event to simulate (JSON string, file path, or URL)"
|
|
2666
|
-
).option("--json", "Output results as JSON").option("-v, --verbose", "Verbose output").option("--
|
|
2706
|
+
).option("-p, --platform <platform>", "Platform override (web or server)").option("--json", "Output results as JSON").option("-v, --verbose", "Verbose output").option("--dry-run", "preview command without executing").option("--silent", "suppress output").action(async (file, options) => {
|
|
2667
2707
|
await simulateCommand({
|
|
2668
2708
|
config: file || "bundle.config.json",
|
|
2669
2709
|
event: options.event,
|
|
2710
|
+
platform: options.platform,
|
|
2670
2711
|
json: options.json,
|
|
2671
2712
|
verbose: options.verbose,
|
|
2672
|
-
local: options.local,
|
|
2673
2713
|
dryRun: options.dryRun,
|
|
2674
2714
|
silent: options.silent
|
|
2675
2715
|
});
|
|
@@ -2677,35 +2717,34 @@ program.command("simulate [file]").description("Simulate event processing and ca
|
|
|
2677
2717
|
program.command("push [file]").description("Push an event through the flow with real API execution").requiredOption(
|
|
2678
2718
|
"-e, --event <source>",
|
|
2679
2719
|
"Event to push (JSON string, file path, or URL)"
|
|
2680
|
-
).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").
|
|
2720
|
+
).option("--flow <name>", "Flow name (for multi-flow configs)").option("-p, --platform <platform>", "Platform override (web or server)").option("--json", "Output results as JSON").option("-v, --verbose", "Verbose output").option("-s, --silent", "Suppress output").action(async (file, options) => {
|
|
2681
2721
|
await pushCommand({
|
|
2682
2722
|
config: file || "bundle.config.json",
|
|
2683
2723
|
event: options.event,
|
|
2684
2724
|
flow: options.flow,
|
|
2725
|
+
platform: options.platform,
|
|
2685
2726
|
json: options.json,
|
|
2686
2727
|
verbose: options.verbose,
|
|
2687
|
-
silent: options.silent
|
|
2688
|
-
local: options.local
|
|
2728
|
+
silent: options.silent
|
|
2689
2729
|
});
|
|
2690
2730
|
});
|
|
2691
2731
|
var runCmd = program.command("run").description("Run walkerOS flows in collect or serve mode");
|
|
2692
2732
|
runCmd.command("collect [file]").description(
|
|
2693
2733
|
"Run collector mode (event collection endpoint). Defaults to server-collect.mjs if no file specified."
|
|
2694
|
-
).option("-p, --port <number>", "Port to listen on (default: 8080)", parseInt).option("-h, --host <address>", "Host address (default: 0.0.0.0)").option("--json", "Output results as JSON").option("-v, --verbose", "Verbose output").option("--
|
|
2734
|
+
).option("-p, --port <number>", "Port to listen on (default: 8080)", parseInt).option("-h, --host <address>", "Host address (default: 0.0.0.0)").option("--json", "Output results as JSON").option("-v, --verbose", "Verbose output").option("--dry-run", "preview command without executing").option("--silent", "suppress output").action(async (file, options) => {
|
|
2695
2735
|
await runCommand("collect", {
|
|
2696
2736
|
config: file || "server-collect.mjs",
|
|
2697
2737
|
port: options.port,
|
|
2698
2738
|
host: options.host,
|
|
2699
2739
|
json: options.json,
|
|
2700
2740
|
verbose: options.verbose,
|
|
2701
|
-
local: options.local,
|
|
2702
2741
|
dryRun: options.dryRun,
|
|
2703
2742
|
silent: options.silent
|
|
2704
2743
|
});
|
|
2705
2744
|
});
|
|
2706
2745
|
runCmd.command("serve [file]").description(
|
|
2707
2746
|
"Run serve mode (single-file server for browser bundles). Defaults to baked-in web-serve.js if no file specified."
|
|
2708
|
-
).option("-p, --port <number>", "Port to listen on (default: 8080)", parseInt).option("-h, --host <address>", "Host address (default: 0.0.0.0)").option("--name <filename>", "Filename in URL (default: walker.js)").option("--path <directory>", "URL directory path (e.g., libs/v1)").option("--json", "Output results as JSON").option("-v, --verbose", "Verbose output").option("--
|
|
2747
|
+
).option("-p, --port <number>", "Port to listen on (default: 8080)", parseInt).option("-h, --host <address>", "Host address (default: 0.0.0.0)").option("--name <filename>", "Filename in URL (default: walker.js)").option("--path <directory>", "URL directory path (e.g., libs/v1)").option("--json", "Output results as JSON").option("-v, --verbose", "Verbose output").option("--dry-run", "preview command without executing").option("--silent", "suppress output").action(async (file, options) => {
|
|
2709
2748
|
await runCommand("serve", {
|
|
2710
2749
|
config: file || "web-serve.js",
|
|
2711
2750
|
port: options.port,
|
|
@@ -2714,12 +2753,12 @@ runCmd.command("serve [file]").description(
|
|
|
2714
2753
|
servePath: options.path,
|
|
2715
2754
|
json: options.json,
|
|
2716
2755
|
verbose: options.verbose,
|
|
2717
|
-
local: options.local,
|
|
2718
2756
|
dryRun: options.dryRun,
|
|
2719
2757
|
silent: options.silent
|
|
2720
2758
|
});
|
|
2721
2759
|
});
|
|
2722
2760
|
registerCacheCommand(program);
|
|
2761
|
+
registerCleanCommand(program);
|
|
2723
2762
|
program.parse();
|
|
2724
2763
|
export {
|
|
2725
2764
|
bundle,
|