@walkeros/cli 0.3.1 → 0.3.3
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 +14 -0
- package/README.md +17 -17
- package/dist/__tests__/cli-e2e.test.js +4 -18
- package/dist/__tests__/cli-e2e.test.js.map +1 -1
- package/dist/__tests__/cli.test.js +5 -31
- package/dist/__tests__/cli.test.js.map +1 -1
- package/dist/commands/bundle/bundler.js +3 -10
- package/dist/commands/bundle/bundler.js.map +1 -1
- package/dist/commands/bundle/index.d.ts.map +1 -1
- package/dist/commands/bundle/index.js +2 -2
- package/dist/commands/bundle/index.js.map +1 -1
- package/dist/commands/run/index.d.ts.map +1 -1
- package/dist/commands/run/index.js +64 -55
- package/dist/commands/run/index.js.map +1 -1
- package/dist/commands/simulate/index.d.ts.map +1 -1
- package/dist/commands/simulate/index.js +2 -2
- package/dist/commands/simulate/index.js.map +1 -1
- package/dist/core/docker.d.ts +40 -3
- package/dist/core/docker.d.ts.map +1 -1
- package/dist/core/docker.js +114 -18
- package/dist/core/docker.js.map +1 -1
- package/dist/core/execution.d.ts +2 -1
- package/dist/core/execution.d.ts.map +1 -1
- package/dist/core/execution.js +11 -4
- package/dist/core/execution.js.map +1 -1
- package/dist/index.js +225 -168
- package/dist/index.js.map +1 -1
- package/package.json +2 -3
package/dist/index.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
import { Command } from "commander";
|
|
5
5
|
|
|
6
6
|
// src/commands/bundle/index.ts
|
|
7
|
-
import
|
|
7
|
+
import path7 from "path";
|
|
8
8
|
|
|
9
9
|
// src/core/logger.ts
|
|
10
10
|
import chalk from "chalk";
|
|
@@ -123,19 +123,19 @@ function formatBytes(bytes) {
|
|
|
123
123
|
|
|
124
124
|
// src/core/docker.ts
|
|
125
125
|
import { spawn } from "child_process";
|
|
126
|
-
|
|
127
|
-
|
|
126
|
+
import path from "path";
|
|
127
|
+
var CLI_DOCKER_IMAGE = process.env.WALKEROS_CLI_DOCKER_IMAGE || "walkeros/cli:latest";
|
|
128
|
+
var RUNTIME_DOCKER_IMAGE = process.env.WALKEROS_RUNTIME_DOCKER_IMAGE || "walkeros/docker:latest";
|
|
129
|
+
function buildDockerCommand(command, args, options = {}, configFile) {
|
|
128
130
|
const cwd = process.cwd();
|
|
129
|
-
const cmd = [
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
"
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
"/workspace"
|
|
138
|
-
];
|
|
131
|
+
const cmd = ["docker", "run", "--rm"];
|
|
132
|
+
if (configFile) {
|
|
133
|
+
const configPath = path.resolve(cwd, configFile);
|
|
134
|
+
cmd.push("-v", `${configPath}:/config/flow.json:ro`);
|
|
135
|
+
args = args.map((arg) => arg === configFile ? "/config/flow.json" : arg);
|
|
136
|
+
}
|
|
137
|
+
cmd.push("-v", `${cwd}:/workspace`);
|
|
138
|
+
cmd.push("-w", "/workspace");
|
|
139
139
|
if (process.platform !== "win32") {
|
|
140
140
|
try {
|
|
141
141
|
const uid = process.getuid?.();
|
|
@@ -152,12 +152,18 @@ function buildDockerCommand(command, args, options = {}) {
|
|
|
152
152
|
if (options.silent) {
|
|
153
153
|
cmd.push("-e", "SILENT=true");
|
|
154
154
|
}
|
|
155
|
-
cmd.push(
|
|
155
|
+
cmd.push(CLI_DOCKER_IMAGE);
|
|
156
156
|
cmd.push(command, ...args);
|
|
157
157
|
return cmd;
|
|
158
158
|
}
|
|
159
|
-
async function executeInDocker(command, args, options = {}) {
|
|
160
|
-
const
|
|
159
|
+
async function executeInDocker(command, args, options = {}, configFile) {
|
|
160
|
+
const containerArgs = [...args, "--local"];
|
|
161
|
+
const dockerCmd = buildDockerCommand(
|
|
162
|
+
command,
|
|
163
|
+
containerArgs,
|
|
164
|
+
options,
|
|
165
|
+
configFile
|
|
166
|
+
);
|
|
161
167
|
return new Promise((resolve2, reject) => {
|
|
162
168
|
const proc = spawn(dockerCmd[0], dockerCmd.slice(1), {
|
|
163
169
|
stdio: options.silent ? "ignore" : "inherit",
|
|
@@ -184,12 +190,68 @@ async function isDockerAvailable() {
|
|
|
184
190
|
proc.on("exit", (code) => resolve2(code === 0));
|
|
185
191
|
});
|
|
186
192
|
}
|
|
193
|
+
function buildDockerRunCommand(mode, flowPath, options = {}) {
|
|
194
|
+
const cwd = process.cwd();
|
|
195
|
+
const cmd = ["docker", "run", "--rm"];
|
|
196
|
+
cmd.push("-e", `MODE=${mode}`);
|
|
197
|
+
if (mode === "collect" && flowPath) {
|
|
198
|
+
const absoluteFlowPath = path.resolve(cwd, flowPath);
|
|
199
|
+
cmd.push("-v", `${absoluteFlowPath}:/app/flow.mjs:ro`);
|
|
200
|
+
cmd.push("-e", "FLOW=/app/flow.mjs");
|
|
201
|
+
}
|
|
202
|
+
if (options.port !== void 0) {
|
|
203
|
+
cmd.push("-p", `${options.port}:${options.port}`);
|
|
204
|
+
cmd.push("-e", `PORT=${options.port}`);
|
|
205
|
+
}
|
|
206
|
+
if (options.host) {
|
|
207
|
+
cmd.push("-e", `HOST=${options.host}`);
|
|
208
|
+
}
|
|
209
|
+
if (mode === "serve" && options.staticDir) {
|
|
210
|
+
const absoluteStaticDir = path.resolve(cwd, options.staticDir);
|
|
211
|
+
cmd.push("-v", `${absoluteStaticDir}:/app/dist:ro`);
|
|
212
|
+
cmd.push("-e", "STATIC_DIR=/app/dist");
|
|
213
|
+
}
|
|
214
|
+
if (process.platform !== "win32") {
|
|
215
|
+
try {
|
|
216
|
+
const uid = process.getuid?.();
|
|
217
|
+
const gid = process.getgid?.();
|
|
218
|
+
if (uid !== void 0 && gid !== void 0) {
|
|
219
|
+
cmd.push("--user", `${uid}:${gid}`);
|
|
220
|
+
}
|
|
221
|
+
} catch {
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
cmd.push(RUNTIME_DOCKER_IMAGE);
|
|
225
|
+
return cmd;
|
|
226
|
+
}
|
|
227
|
+
async function executeRunInDocker(mode, flowPath, options = {}) {
|
|
228
|
+
const dockerCmd = buildDockerRunCommand(mode, flowPath, options);
|
|
229
|
+
return new Promise((resolve2, reject) => {
|
|
230
|
+
const proc = spawn(dockerCmd[0], dockerCmd.slice(1), {
|
|
231
|
+
stdio: options.silent ? "ignore" : "inherit",
|
|
232
|
+
shell: false
|
|
233
|
+
});
|
|
234
|
+
proc.on("error", (error) => {
|
|
235
|
+
reject(new Error(`Docker execution failed: ${error.message}`));
|
|
236
|
+
});
|
|
237
|
+
proc.on("exit", (code) => {
|
|
238
|
+
if (code === 0) {
|
|
239
|
+
resolve2();
|
|
240
|
+
} else {
|
|
241
|
+
reject(new Error(`Docker command exited with code ${code}`));
|
|
242
|
+
}
|
|
243
|
+
});
|
|
244
|
+
});
|
|
245
|
+
}
|
|
187
246
|
|
|
188
247
|
// src/core/execution.ts
|
|
189
248
|
function getExecutionMode(options) {
|
|
190
|
-
|
|
249
|
+
if (options.local || process.env.WALKEROS_CONTAINER === "true") {
|
|
250
|
+
return "local";
|
|
251
|
+
}
|
|
252
|
+
return "docker";
|
|
191
253
|
}
|
|
192
|
-
async function executeCommand(localHandler, dockerCommand, dockerArgs, options, logger) {
|
|
254
|
+
async function executeCommand(localHandler, dockerCommand, dockerArgs, options, logger, configFile) {
|
|
193
255
|
const mode = getExecutionMode(options);
|
|
194
256
|
if (options.dryRun) {
|
|
195
257
|
if (mode === "docker") {
|
|
@@ -217,7 +279,7 @@ async function executeCommand(localHandler, dockerCommand, dockerArgs, options,
|
|
|
217
279
|
if (logger && !options.silent) {
|
|
218
280
|
logger.info("\u{1F433} Executing in Docker container...");
|
|
219
281
|
}
|
|
220
|
-
await executeInDocker(dockerCommand, dockerArgs, options);
|
|
282
|
+
await executeInDocker(dockerCommand, dockerArgs, options, configFile);
|
|
221
283
|
}
|
|
222
284
|
}
|
|
223
285
|
|
|
@@ -237,9 +299,9 @@ function isSingleEnvConfig(data) {
|
|
|
237
299
|
|
|
238
300
|
// src/config/utils.ts
|
|
239
301
|
import fs from "fs-extra";
|
|
240
|
-
import
|
|
302
|
+
import path2 from "path";
|
|
241
303
|
async function loadJsonConfig(configPath) {
|
|
242
|
-
const absolutePath =
|
|
304
|
+
const absolutePath = path2.resolve(configPath);
|
|
243
305
|
if (!await fs.pathExists(absolutePath)) {
|
|
244
306
|
throw new Error(`Configuration file not found: ${absolutePath}`);
|
|
245
307
|
}
|
|
@@ -254,8 +316,8 @@ async function loadJsonConfig(configPath) {
|
|
|
254
316
|
}
|
|
255
317
|
function getTempDir(tempDir = ".tmp") {
|
|
256
318
|
const randomId = Math.random().toString(36).substring(2, 11);
|
|
257
|
-
const basePath =
|
|
258
|
-
return
|
|
319
|
+
const basePath = path2.isAbsolute(tempDir) ? tempDir : path2.join(process.cwd(), tempDir);
|
|
320
|
+
return path2.join(basePath, `cli-${Date.now()}-${randomId}`);
|
|
259
321
|
}
|
|
260
322
|
|
|
261
323
|
// src/config/defaults.ts
|
|
@@ -307,7 +369,7 @@ function ensureBuildOptions(buildOptions, flowPlatform) {
|
|
|
307
369
|
}
|
|
308
370
|
|
|
309
371
|
// src/config/parser.ts
|
|
310
|
-
import
|
|
372
|
+
import path3 from "path";
|
|
311
373
|
function parseBundleConfig(data) {
|
|
312
374
|
if (!isObject(data)) {
|
|
313
375
|
throw new Error(`Invalid config: expected object, got ${typeof data}`);
|
|
@@ -366,10 +428,10 @@ function normalizeConfigs(config, configPath) {
|
|
|
366
428
|
...buildDefaults,
|
|
367
429
|
...config.build
|
|
368
430
|
};
|
|
369
|
-
if (configPath && buildConfig.template && !
|
|
431
|
+
if (configPath && buildConfig.template && !path3.isAbsolute(buildConfig.template)) {
|
|
370
432
|
if (buildConfig.template.startsWith("./") || buildConfig.template.startsWith("../")) {
|
|
371
|
-
const configDir =
|
|
372
|
-
buildConfig.template =
|
|
433
|
+
const configDir = path3.dirname(configPath);
|
|
434
|
+
buildConfig.template = path3.resolve(configDir, buildConfig.template);
|
|
373
435
|
}
|
|
374
436
|
}
|
|
375
437
|
const buildOptions = ensureBuildOptions(buildConfig, platform);
|
|
@@ -471,20 +533,20 @@ Your configuration appears to be single-environment.`
|
|
|
471
533
|
|
|
472
534
|
// src/commands/bundle/bundler.ts
|
|
473
535
|
import esbuild from "esbuild";
|
|
474
|
-
import
|
|
536
|
+
import path6 from "path";
|
|
475
537
|
import fs4 from "fs-extra";
|
|
476
538
|
|
|
477
539
|
// src/commands/bundle/package-manager.ts
|
|
478
540
|
import pacote from "pacote";
|
|
479
|
-
import
|
|
541
|
+
import path4 from "path";
|
|
480
542
|
import fs2 from "fs-extra";
|
|
481
543
|
function getPackageDirectory(baseDir, packageName, version) {
|
|
482
|
-
return
|
|
544
|
+
return path4.join(baseDir, "node_modules", packageName);
|
|
483
545
|
}
|
|
484
546
|
function getCachedPackagePath(pkg, tempDir) {
|
|
485
|
-
const cacheDir =
|
|
547
|
+
const cacheDir = path4.join(".tmp", "cache", "packages");
|
|
486
548
|
const safeName = pkg.name.replace(/\//g, "-").replace(/@/g, "");
|
|
487
|
-
return
|
|
549
|
+
return path4.join(cacheDir, `${safeName}-${pkg.version}`);
|
|
488
550
|
}
|
|
489
551
|
async function isPackageCached(pkg, tempDir) {
|
|
490
552
|
const cachedPath = getCachedPackagePath(pkg, tempDir);
|
|
@@ -522,7 +584,7 @@ async function resolveDependencies(pkg, packageDir, logger, visited = /* @__PURE
|
|
|
522
584
|
}
|
|
523
585
|
visited.add(pkgKey);
|
|
524
586
|
try {
|
|
525
|
-
const packageJsonPath =
|
|
587
|
+
const packageJsonPath = path4.join(packageDir, "package.json");
|
|
526
588
|
if (await fs2.pathExists(packageJsonPath)) {
|
|
527
589
|
const packageJson = await fs2.readJson(packageJsonPath);
|
|
528
590
|
const deps = {
|
|
@@ -559,7 +621,7 @@ async function downloadPackages(packages, targetDir, logger, useCache = true) {
|
|
|
559
621
|
if (useCache && await isPackageCached(pkg, targetDir)) {
|
|
560
622
|
logger.debug(`Using cached ${packageSpec}...`);
|
|
561
623
|
try {
|
|
562
|
-
await fs2.ensureDir(
|
|
624
|
+
await fs2.ensureDir(path4.dirname(packageDir));
|
|
563
625
|
await fs2.copy(cachedPath, packageDir);
|
|
564
626
|
packagePaths.set(pkg.name, packageDir);
|
|
565
627
|
const deps = await resolveDependencies(pkg, packageDir, logger);
|
|
@@ -578,8 +640,8 @@ async function downloadPackages(packages, targetDir, logger, useCache = true) {
|
|
|
578
640
|
}
|
|
579
641
|
logger.debug(`Downloading ${packageSpec}...`);
|
|
580
642
|
try {
|
|
581
|
-
await fs2.ensureDir(
|
|
582
|
-
const cacheDir = process.env.NPM_CACHE_DIR ||
|
|
643
|
+
await fs2.ensureDir(path4.dirname(packageDir));
|
|
644
|
+
const cacheDir = process.env.NPM_CACHE_DIR || path4.join(process.cwd(), ".npm-cache");
|
|
583
645
|
await pacote.extract(packageSpec, packageDir, {
|
|
584
646
|
// Force npm registry download, prevent workspace resolution
|
|
585
647
|
registry: "https://registry.npmjs.org",
|
|
@@ -592,7 +654,7 @@ async function downloadPackages(packages, targetDir, logger, useCache = true) {
|
|
|
592
654
|
});
|
|
593
655
|
if (useCache) {
|
|
594
656
|
try {
|
|
595
|
-
await fs2.ensureDir(
|
|
657
|
+
await fs2.ensureDir(path4.dirname(cachedPath));
|
|
596
658
|
await fs2.copy(packageDir, cachedPath);
|
|
597
659
|
logger.debug(`Cached ${packageSpec} for future use`);
|
|
598
660
|
} catch (cacheError) {
|
|
@@ -616,7 +678,7 @@ async function downloadPackages(packages, targetDir, logger, useCache = true) {
|
|
|
616
678
|
|
|
617
679
|
// src/commands/bundle/template-engine.ts
|
|
618
680
|
import fs3 from "fs-extra";
|
|
619
|
-
import
|
|
681
|
+
import path5 from "path";
|
|
620
682
|
import Handlebars from "handlebars";
|
|
621
683
|
|
|
622
684
|
// src/commands/bundle/serializer.ts
|
|
@@ -729,7 +791,7 @@ var TemplateEngine = class {
|
|
|
729
791
|
* Load template content from file path
|
|
730
792
|
*/
|
|
731
793
|
async loadTemplate(templatePath) {
|
|
732
|
-
const resolvedPath =
|
|
794
|
+
const resolvedPath = path5.resolve(templatePath);
|
|
733
795
|
if (!await fs3.pathExists(resolvedPath)) {
|
|
734
796
|
throw new Error(`Template file not found: ${resolvedPath}`);
|
|
735
797
|
}
|
|
@@ -771,7 +833,7 @@ var TemplateEngine = class {
|
|
|
771
833
|
// src/commands/bundle/bundler.ts
|
|
772
834
|
async function bundleCore(flowConfig, buildOptions, logger, showStats = false) {
|
|
773
835
|
const bundleStartTime = Date.now();
|
|
774
|
-
const TEMP_DIR = buildOptions.tempDir ?
|
|
836
|
+
const TEMP_DIR = buildOptions.tempDir ? path6.isAbsolute(buildOptions.tempDir) ? buildOptions.tempDir : path6.resolve(buildOptions.tempDir) : getTempDir();
|
|
775
837
|
try {
|
|
776
838
|
if (!buildOptions.tempDir) {
|
|
777
839
|
await fs4.emptyDir(TEMP_DIR);
|
|
@@ -792,7 +854,7 @@ async function bundleCore(flowConfig, buildOptions, logger, showStats = false) {
|
|
|
792
854
|
);
|
|
793
855
|
for (const [pkgName, pkgPath] of packagePaths.entries()) {
|
|
794
856
|
if (pkgName.startsWith("@walkeros/")) {
|
|
795
|
-
const pkgJsonPath =
|
|
857
|
+
const pkgJsonPath = path6.join(pkgPath, "package.json");
|
|
796
858
|
const pkgJson = await fs4.readJSON(pkgJsonPath);
|
|
797
859
|
if (!pkgJson.exports && pkgJson.module) {
|
|
798
860
|
pkgJson.exports = {
|
|
@@ -805,7 +867,7 @@ async function bundleCore(flowConfig, buildOptions, logger, showStats = false) {
|
|
|
805
867
|
}
|
|
806
868
|
}
|
|
807
869
|
}
|
|
808
|
-
const packageJsonPath =
|
|
870
|
+
const packageJsonPath = path6.join(TEMP_DIR, "package.json");
|
|
809
871
|
await fs4.writeFile(
|
|
810
872
|
packageJsonPath,
|
|
811
873
|
JSON.stringify({ type: "module" }, null, 2)
|
|
@@ -816,11 +878,11 @@ async function bundleCore(flowConfig, buildOptions, logger, showStats = false) {
|
|
|
816
878
|
buildOptions,
|
|
817
879
|
packagePaths
|
|
818
880
|
);
|
|
819
|
-
const entryPath =
|
|
881
|
+
const entryPath = path6.join(TEMP_DIR, "entry.js");
|
|
820
882
|
await fs4.writeFile(entryPath, entryContent);
|
|
821
883
|
logger.info("\u26A1 Bundling with esbuild...");
|
|
822
|
-
const outputPath =
|
|
823
|
-
await fs4.ensureDir(
|
|
884
|
+
const outputPath = path6.resolve(buildOptions.output);
|
|
885
|
+
await fs4.ensureDir(path6.dirname(outputPath));
|
|
824
886
|
const esbuildOptions = createEsbuildOptions(
|
|
825
887
|
buildOptions,
|
|
826
888
|
entryPath,
|
|
@@ -935,14 +997,7 @@ function createEsbuildOptions(buildOptions, entryPath, outputPath, tempDir, pack
|
|
|
935
997
|
"querystring",
|
|
936
998
|
"zlib"
|
|
937
999
|
];
|
|
938
|
-
const npmPackages = [
|
|
939
|
-
"zod",
|
|
940
|
-
"zod/*",
|
|
941
|
-
"express",
|
|
942
|
-
"express/*",
|
|
943
|
-
"cors",
|
|
944
|
-
"cors/*"
|
|
945
|
-
];
|
|
1000
|
+
const npmPackages = ["express", "express/*", "cors", "cors/*"];
|
|
946
1001
|
baseOptions.external = buildOptions.external ? [...nodeBuiltins, ...npmPackages, ...buildOptions.external] : [...nodeBuiltins, ...npmPackages];
|
|
947
1002
|
}
|
|
948
1003
|
if (buildOptions.target) {
|
|
@@ -1156,7 +1211,7 @@ async function bundleCommand(options) {
|
|
|
1156
1211
|
throw new Error("Cannot use both --env and --all flags together");
|
|
1157
1212
|
}
|
|
1158
1213
|
logger.info("\u{1F4E6} Reading configuration...");
|
|
1159
|
-
const configPath =
|
|
1214
|
+
const configPath = path7.resolve(options.config);
|
|
1160
1215
|
const rawConfig = await loadJsonConfig(configPath);
|
|
1161
1216
|
const configsToBundle = options.all ? loadAllEnvironments(rawConfig, { configPath, logger }) : [
|
|
1162
1217
|
loadBundleConfig(rawConfig, {
|
|
@@ -1265,7 +1320,8 @@ async function bundleCommand(options) {
|
|
|
1265
1320
|
"bundle",
|
|
1266
1321
|
dockerArgs,
|
|
1267
1322
|
options,
|
|
1268
|
-
logger
|
|
1323
|
+
logger,
|
|
1324
|
+
options.config
|
|
1269
1325
|
);
|
|
1270
1326
|
}
|
|
1271
1327
|
async function bundle(configOrPath, options = {}) {
|
|
@@ -1292,7 +1348,7 @@ async function bundle(configOrPath, options = {}) {
|
|
|
1292
1348
|
}
|
|
1293
1349
|
|
|
1294
1350
|
// src/commands/simulate/simulator.ts
|
|
1295
|
-
import
|
|
1351
|
+
import path8 from "path";
|
|
1296
1352
|
import fs5 from "fs-extra";
|
|
1297
1353
|
|
|
1298
1354
|
// src/commands/simulate/tracker.ts
|
|
@@ -1329,9 +1385,9 @@ var CallTracker = class {
|
|
|
1329
1385
|
}
|
|
1330
1386
|
for (const fullPath of paths) {
|
|
1331
1387
|
const [destKey, ...pathParts] = fullPath.split(":");
|
|
1332
|
-
const
|
|
1333
|
-
if (!
|
|
1334
|
-
const cleanPath =
|
|
1388
|
+
const path10 = pathParts.join(":");
|
|
1389
|
+
if (!path10) continue;
|
|
1390
|
+
const cleanPath = path10.replace(/^call:/, "");
|
|
1335
1391
|
const parts = cleanPath.split(".");
|
|
1336
1392
|
let current = wrapped;
|
|
1337
1393
|
let source = env;
|
|
@@ -1386,7 +1442,7 @@ async function simulateCore(configPath, event, options = {}) {
|
|
|
1386
1442
|
try {
|
|
1387
1443
|
logger.info("\u{1F3AF} Starting walkerOS simulation...");
|
|
1388
1444
|
logger.info("\u{1F4E6} Loading bundle configuration...");
|
|
1389
|
-
const fullConfigPath =
|
|
1445
|
+
const fullConfigPath = path8.resolve(configPath);
|
|
1390
1446
|
const rawConfig = await loadJsonConfig(fullConfigPath);
|
|
1391
1447
|
parseBundleConfig(rawConfig);
|
|
1392
1448
|
logger.info(`\u{1F680} Executing simulation with event: ${JSON.stringify(event)}`);
|
|
@@ -1481,7 +1537,7 @@ ${envSetupCode.join("\n")}
|
|
|
1481
1537
|
|
|
1482
1538
|
${buildOptions.code || ""}
|
|
1483
1539
|
`;
|
|
1484
|
-
const tempOutput =
|
|
1540
|
+
const tempOutput = path8.join(
|
|
1485
1541
|
tempDir,
|
|
1486
1542
|
`simulation-bundle-${generateId()}.mjs`
|
|
1487
1543
|
);
|
|
@@ -1620,7 +1676,8 @@ async function simulateCommand(options) {
|
|
|
1620
1676
|
"simulate",
|
|
1621
1677
|
dockerArgs,
|
|
1622
1678
|
options,
|
|
1623
|
-
logger
|
|
1679
|
+
logger,
|
|
1680
|
+
options.config
|
|
1624
1681
|
);
|
|
1625
1682
|
}
|
|
1626
1683
|
async function simulate(configOrPath, event, options = {}) {
|
|
@@ -1636,7 +1693,7 @@ async function simulate(configOrPath, event, options = {}) {
|
|
|
1636
1693
|
}
|
|
1637
1694
|
|
|
1638
1695
|
// src/commands/run/index.ts
|
|
1639
|
-
import
|
|
1696
|
+
import path9 from "path";
|
|
1640
1697
|
import os from "os";
|
|
1641
1698
|
import {
|
|
1642
1699
|
runFlow,
|
|
@@ -1686,104 +1743,112 @@ async function runCommand(mode, options) {
|
|
|
1686
1743
|
silent: options.silent ?? false,
|
|
1687
1744
|
json: options.json
|
|
1688
1745
|
});
|
|
1689
|
-
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
if (options.port !== void 0) {
|
|
1703
|
-
validatePort(options.port);
|
|
1704
|
-
}
|
|
1705
|
-
const isPreBuilt = configPath.endsWith(".mjs") || configPath.endsWith(".js") || configPath.endsWith(".cjs");
|
|
1706
|
-
let flowPath;
|
|
1707
|
-
if (isPreBuilt) {
|
|
1708
|
-
flowPath = path8.resolve(configPath);
|
|
1709
|
-
if (!options.json) {
|
|
1710
|
-
logger.info(`\u{1F4E6} Using pre-built flow: ${path8.basename(flowPath)}`);
|
|
1711
|
-
}
|
|
1712
|
-
} else {
|
|
1713
|
-
if (!options.json) {
|
|
1714
|
-
logger.info("\u{1F528} Building flow bundle...");
|
|
1715
|
-
}
|
|
1716
|
-
const rawConfig = await loadJsonConfig(configPath);
|
|
1717
|
-
const tempPath = path8.join(
|
|
1718
|
-
os.tmpdir(),
|
|
1719
|
-
`walkeros-${Date.now()}-${Math.random().toString(36).slice(2, 9)}.mjs`
|
|
1720
|
-
);
|
|
1721
|
-
const existingBuild = typeof rawConfig === "object" && rawConfig !== null && "build" in rawConfig && typeof rawConfig.build === "object" ? rawConfig.build : {};
|
|
1722
|
-
const configWithOutput = {
|
|
1723
|
-
...rawConfig,
|
|
1724
|
-
build: {
|
|
1725
|
-
...existingBuild,
|
|
1726
|
-
output: tempPath
|
|
1727
|
-
}
|
|
1728
|
-
};
|
|
1729
|
-
await bundle(configWithOutput, {
|
|
1730
|
-
cache: true,
|
|
1731
|
-
verbose: options.verbose,
|
|
1732
|
-
silent: options.json
|
|
1733
|
-
});
|
|
1734
|
-
flowPath = tempPath;
|
|
1735
|
-
if (!options.json) {
|
|
1736
|
-
logger.success("\u2705 Bundle ready");
|
|
1737
|
-
}
|
|
1746
|
+
try {
|
|
1747
|
+
validateMode(mode);
|
|
1748
|
+
const configPath = validateFlowFile(options.config);
|
|
1749
|
+
if (options.port !== void 0) {
|
|
1750
|
+
validatePort(options.port);
|
|
1751
|
+
}
|
|
1752
|
+
const isPreBuilt = configPath.endsWith(".mjs") || configPath.endsWith(".js") || configPath.endsWith(".cjs");
|
|
1753
|
+
let flowPath = null;
|
|
1754
|
+
if (mode === "collect") {
|
|
1755
|
+
if (isPreBuilt) {
|
|
1756
|
+
flowPath = path9.resolve(configPath);
|
|
1757
|
+
if (!options.json && !options.silent) {
|
|
1758
|
+
logger.info(`\u{1F4E6} Using pre-built flow: ${path9.basename(flowPath)}`);
|
|
1738
1759
|
}
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
logger.info(
|
|
1760
|
+
} else {
|
|
1761
|
+
if (!options.json && !options.silent) {
|
|
1762
|
+
logger.info("\u{1F528} Building flow bundle...");
|
|
1742
1763
|
}
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1764
|
+
const rawConfig = await loadJsonConfig(configPath);
|
|
1765
|
+
const tempPath = path9.join(
|
|
1766
|
+
os.tmpdir(),
|
|
1767
|
+
`walkeros-${Date.now()}-${Math.random().toString(36).slice(2, 9)}.mjs`
|
|
1768
|
+
);
|
|
1769
|
+
const existingBuild = typeof rawConfig === "object" && rawConfig !== null && "build" in rawConfig && typeof rawConfig.build === "object" ? rawConfig.build : {};
|
|
1770
|
+
const configWithOutput = {
|
|
1771
|
+
...rawConfig,
|
|
1772
|
+
build: {
|
|
1773
|
+
...existingBuild,
|
|
1774
|
+
output: tempPath
|
|
1751
1775
|
}
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
|
|
1776
|
+
};
|
|
1777
|
+
await bundle(configWithOutput, {
|
|
1778
|
+
cache: true,
|
|
1779
|
+
verbose: options.verbose,
|
|
1780
|
+
silent: options.json || options.silent
|
|
1781
|
+
});
|
|
1782
|
+
flowPath = tempPath;
|
|
1783
|
+
if (!options.json && !options.silent) {
|
|
1784
|
+
logger.success("\u2705 Bundle ready");
|
|
1785
|
+
}
|
|
1786
|
+
}
|
|
1787
|
+
}
|
|
1788
|
+
const executionMode = getExecutionMode(options);
|
|
1789
|
+
if (executionMode === "docker") {
|
|
1790
|
+
const dockerAvailable = await isDockerAvailable();
|
|
1791
|
+
if (!dockerAvailable) {
|
|
1792
|
+
throw new Error(
|
|
1793
|
+
"Docker is not available. Please install Docker or use --local flag to execute locally."
|
|
1794
|
+
);
|
|
1795
|
+
}
|
|
1796
|
+
if (!options.json && !options.silent) {
|
|
1797
|
+
logger.info("\u{1F433} Executing in production runtime container...");
|
|
1798
|
+
}
|
|
1799
|
+
await executeRunInDocker(mode, flowPath, {
|
|
1800
|
+
port: options.port,
|
|
1801
|
+
host: options.host,
|
|
1802
|
+
staticDir: options.staticDir,
|
|
1803
|
+
silent: options.silent
|
|
1804
|
+
});
|
|
1805
|
+
} else {
|
|
1806
|
+
if (!options.json && !options.silent) {
|
|
1807
|
+
const modeLabel = mode === "collect" ? "Collector" : "Server";
|
|
1808
|
+
logger.info(`\u{1F5A5}\uFE0F Starting ${modeLabel} locally...`);
|
|
1809
|
+
}
|
|
1810
|
+
switch (mode) {
|
|
1811
|
+
case "collect": {
|
|
1812
|
+
if (!flowPath) {
|
|
1813
|
+
throw new Error("Flow path is required for collect mode");
|
|
1760
1814
|
}
|
|
1761
|
-
|
|
1762
|
-
|
|
1815
|
+
const config = {
|
|
1816
|
+
port: options.port,
|
|
1817
|
+
host: options.host
|
|
1818
|
+
};
|
|
1819
|
+
await runFlow(flowPath, config);
|
|
1820
|
+
break;
|
|
1763
1821
|
}
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
success: false,
|
|
1770
|
-
mode,
|
|
1771
|
-
error: errorMessage,
|
|
1772
|
-
duration
|
|
1822
|
+
case "serve": {
|
|
1823
|
+
const config = {
|
|
1824
|
+
port: options.port,
|
|
1825
|
+
host: options.host,
|
|
1826
|
+
staticDir: options.staticDir
|
|
1773
1827
|
};
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
logger.error("\u274C Run failed:");
|
|
1777
|
-
logger.error(errorMessage);
|
|
1828
|
+
await runServeMode(config);
|
|
1829
|
+
break;
|
|
1778
1830
|
}
|
|
1779
|
-
|
|
1831
|
+
default:
|
|
1832
|
+
throw new Error(`Unknown mode: ${mode}`);
|
|
1780
1833
|
}
|
|
1781
|
-
}
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1834
|
+
}
|
|
1835
|
+
} catch (error) {
|
|
1836
|
+
const duration = timer.getElapsed() / 1e3;
|
|
1837
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
1838
|
+
if (options.json) {
|
|
1839
|
+
const output = {
|
|
1840
|
+
success: false,
|
|
1841
|
+
mode,
|
|
1842
|
+
error: errorMessage,
|
|
1843
|
+
duration
|
|
1844
|
+
};
|
|
1845
|
+
console.log(JSON.stringify(output, null, 2));
|
|
1846
|
+
} else {
|
|
1847
|
+
logger.error("\u274C Run failed:");
|
|
1848
|
+
logger.error(errorMessage);
|
|
1849
|
+
}
|
|
1850
|
+
process.exit(1);
|
|
1851
|
+
}
|
|
1787
1852
|
}
|
|
1788
1853
|
async function run(mode, options) {
|
|
1789
1854
|
const startTime = Date.now();
|
|
@@ -1801,10 +1866,10 @@ async function run(mode, options) {
|
|
|
1801
1866
|
const isPreBuilt = flowFile.endsWith(".mjs") || flowFile.endsWith(".js") || flowFile.endsWith(".cjs");
|
|
1802
1867
|
let flowPath;
|
|
1803
1868
|
if (isPreBuilt) {
|
|
1804
|
-
flowPath =
|
|
1869
|
+
flowPath = path9.resolve(flowFile);
|
|
1805
1870
|
} else {
|
|
1806
1871
|
const rawConfig = await loadJsonConfig(flowFile);
|
|
1807
|
-
const tempPath =
|
|
1872
|
+
const tempPath = path9.join(
|
|
1808
1873
|
os.tmpdir(),
|
|
1809
1874
|
`walkeros-${Date.now()}-${Math.random().toString(36).slice(2, 9)}.mjs`
|
|
1810
1875
|
);
|
|
@@ -1863,16 +1928,12 @@ async function run(mode, options) {
|
|
|
1863
1928
|
import { fileURLToPath } from "url";
|
|
1864
1929
|
var program = new Command();
|
|
1865
1930
|
program.name("walkeros").description("walkerOS CLI - Bundle and deploy walkerOS components").version("0.1.0");
|
|
1866
|
-
program.command("bundle").description("Bundle NPM packages with custom code").option(
|
|
1867
|
-
"-c, --config <path>",
|
|
1868
|
-
"configuration file path",
|
|
1869
|
-
"bundle.config.json"
|
|
1870
|
-
).option(
|
|
1931
|
+
program.command("bundle [file]").description("Bundle NPM packages with custom code").option(
|
|
1871
1932
|
"-e, --env <name>",
|
|
1872
1933
|
"environment to build (for multi-environment configs)"
|
|
1873
|
-
).option("--all", "build all environments (for multi-environment configs)").option("-s, --stats", "show bundle statistics").option("--json", "output statistics in JSON format (implies --stats)").option("--no-cache", "disable package caching and download fresh packages").option("-v, --verbose", "verbose output").option("--local", "execute in local Node.js instead of Docker").option("--dry-run", "preview command without executing").option("--silent", "suppress output").action(async (options) => {
|
|
1934
|
+
).option("--all", "build all environments (for multi-environment configs)").option("-s, --stats", "show bundle statistics").option("--json", "output statistics in JSON format (implies --stats)").option("--no-cache", "disable package caching and download fresh packages").option("-v, --verbose", "verbose output").option("--local", "execute in local Node.js instead of Docker").option("--dry-run", "preview command without executing").option("--silent", "suppress output").action(async (file, options) => {
|
|
1874
1935
|
await bundleCommand({
|
|
1875
|
-
config:
|
|
1936
|
+
config: file || "bundle.config.json",
|
|
1876
1937
|
env: options.env,
|
|
1877
1938
|
all: options.all,
|
|
1878
1939
|
stats: options.stats,
|
|
@@ -1884,13 +1945,9 @@ program.command("bundle").description("Bundle NPM packages with custom code").op
|
|
|
1884
1945
|
silent: options.silent
|
|
1885
1946
|
});
|
|
1886
1947
|
});
|
|
1887
|
-
program.command("simulate").description("Simulate event processing and capture API calls").option(
|
|
1888
|
-
"-c, --config <path>",
|
|
1889
|
-
"Bundle configuration file",
|
|
1890
|
-
"bundle.config.json"
|
|
1891
|
-
).option("-e, --event <json>", "Event to simulate (JSON string)").option("--json", "Output results as JSON").option("-v, --verbose", "Verbose output").option("--local", "execute in local Node.js instead of Docker").option("--dry-run", "preview command without executing").option("--silent", "suppress output").action(async (options) => {
|
|
1948
|
+
program.command("simulate [file]").description("Simulate event processing and capture API calls").option("-e, --event <json>", "Event to simulate (JSON string)").option("--json", "Output results as JSON").option("-v, --verbose", "Verbose output").option("--local", "execute in local Node.js instead of Docker").option("--dry-run", "preview command without executing").option("--silent", "suppress output").action(async (file, options) => {
|
|
1892
1949
|
await simulateCommand({
|
|
1893
|
-
config:
|
|
1950
|
+
config: file || "bundle.config.json",
|
|
1894
1951
|
event: options.event,
|
|
1895
1952
|
json: options.json,
|
|
1896
1953
|
verbose: options.verbose,
|