@walkeros/cli 1.2.0 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +15 -0
- package/README.md +2 -1
- package/dist/dev.d.ts +328 -0
- package/dist/dev.js +110 -0
- package/dist/dev.js.map +1 -0
- package/dist/index.d.ts +163 -8
- package/dist/index.js +1701 -323
- package/dist/index.js.map +1 -1
- package/dist/runtime/main.js +134 -12
- package/dist/runtime/main.js.map +1 -1
- package/dist/walker.js +1 -0
- package/package.json +7 -3
package/dist/index.js
CHANGED
|
@@ -1,8 +1,611 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
+
var __esm = (fn, res) => function __init() {
|
|
5
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
6
|
+
};
|
|
7
|
+
var __export = (target, all) => {
|
|
8
|
+
for (var name in all)
|
|
9
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
// ../../node_modules/is-docker/index.js
|
|
13
|
+
import fs15 from "fs";
|
|
14
|
+
function hasDockerEnv() {
|
|
15
|
+
try {
|
|
16
|
+
fs15.statSync("/.dockerenv");
|
|
17
|
+
return true;
|
|
18
|
+
} catch {
|
|
19
|
+
return false;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
function hasDockerCGroup() {
|
|
23
|
+
try {
|
|
24
|
+
return fs15.readFileSync("/proc/self/cgroup", "utf8").includes("docker");
|
|
25
|
+
} catch {
|
|
26
|
+
return false;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
function isDocker() {
|
|
30
|
+
if (isDockerCached === void 0) {
|
|
31
|
+
isDockerCached = hasDockerEnv() || hasDockerCGroup();
|
|
32
|
+
}
|
|
33
|
+
return isDockerCached;
|
|
34
|
+
}
|
|
35
|
+
var isDockerCached;
|
|
36
|
+
var init_is_docker = __esm({
|
|
37
|
+
"../../node_modules/is-docker/index.js"() {
|
|
38
|
+
"use strict";
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
// ../../node_modules/is-inside-container/index.js
|
|
43
|
+
import fs16 from "fs";
|
|
44
|
+
function isInsideContainer() {
|
|
45
|
+
if (cachedResult === void 0) {
|
|
46
|
+
cachedResult = hasContainerEnv() || isDocker();
|
|
47
|
+
}
|
|
48
|
+
return cachedResult;
|
|
49
|
+
}
|
|
50
|
+
var cachedResult, hasContainerEnv;
|
|
51
|
+
var init_is_inside_container = __esm({
|
|
52
|
+
"../../node_modules/is-inside-container/index.js"() {
|
|
53
|
+
"use strict";
|
|
54
|
+
init_is_docker();
|
|
55
|
+
hasContainerEnv = () => {
|
|
56
|
+
try {
|
|
57
|
+
fs16.statSync("/run/.containerenv");
|
|
58
|
+
return true;
|
|
59
|
+
} catch {
|
|
60
|
+
return false;
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
// ../../node_modules/is-wsl/index.js
|
|
67
|
+
import process2 from "process";
|
|
68
|
+
import os from "os";
|
|
69
|
+
import fs17 from "fs";
|
|
70
|
+
var isWsl, is_wsl_default;
|
|
71
|
+
var init_is_wsl = __esm({
|
|
72
|
+
"../../node_modules/is-wsl/index.js"() {
|
|
73
|
+
"use strict";
|
|
74
|
+
init_is_inside_container();
|
|
75
|
+
isWsl = () => {
|
|
76
|
+
if (process2.platform !== "linux") {
|
|
77
|
+
return false;
|
|
78
|
+
}
|
|
79
|
+
if (os.release().toLowerCase().includes("microsoft")) {
|
|
80
|
+
if (isInsideContainer()) {
|
|
81
|
+
return false;
|
|
82
|
+
}
|
|
83
|
+
return true;
|
|
84
|
+
}
|
|
85
|
+
try {
|
|
86
|
+
return fs17.readFileSync("/proc/version", "utf8").toLowerCase().includes("microsoft") ? !isInsideContainer() : false;
|
|
87
|
+
} catch {
|
|
88
|
+
return false;
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
is_wsl_default = process2.env.__IS_WSL_TEST__ ? isWsl : isWsl();
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
// ../../node_modules/wsl-utils/index.js
|
|
96
|
+
import process3 from "process";
|
|
97
|
+
import fs18, { constants as fsConstants } from "fs/promises";
|
|
98
|
+
var wslDrivesMountPoint, powerShellPathFromWsl, powerShellPath;
|
|
99
|
+
var init_wsl_utils = __esm({
|
|
100
|
+
"../../node_modules/wsl-utils/index.js"() {
|
|
101
|
+
"use strict";
|
|
102
|
+
init_is_wsl();
|
|
103
|
+
init_is_wsl();
|
|
104
|
+
wslDrivesMountPoint = /* @__PURE__ */ (() => {
|
|
105
|
+
const defaultMountPoint = "/mnt/";
|
|
106
|
+
let mountPoint;
|
|
107
|
+
return async function() {
|
|
108
|
+
if (mountPoint) {
|
|
109
|
+
return mountPoint;
|
|
110
|
+
}
|
|
111
|
+
const configFilePath = "/etc/wsl.conf";
|
|
112
|
+
let isConfigFileExists = false;
|
|
113
|
+
try {
|
|
114
|
+
await fs18.access(configFilePath, fsConstants.F_OK);
|
|
115
|
+
isConfigFileExists = true;
|
|
116
|
+
} catch {
|
|
117
|
+
}
|
|
118
|
+
if (!isConfigFileExists) {
|
|
119
|
+
return defaultMountPoint;
|
|
120
|
+
}
|
|
121
|
+
const configContent = await fs18.readFile(configFilePath, { encoding: "utf8" });
|
|
122
|
+
const configMountPoint = /(?<!#.*)root\s*=\s*(?<mountPoint>.*)/g.exec(configContent);
|
|
123
|
+
if (!configMountPoint) {
|
|
124
|
+
return defaultMountPoint;
|
|
125
|
+
}
|
|
126
|
+
mountPoint = configMountPoint.groups.mountPoint.trim();
|
|
127
|
+
mountPoint = mountPoint.endsWith("/") ? mountPoint : `${mountPoint}/`;
|
|
128
|
+
return mountPoint;
|
|
129
|
+
};
|
|
130
|
+
})();
|
|
131
|
+
powerShellPathFromWsl = async () => {
|
|
132
|
+
const mountPoint = await wslDrivesMountPoint();
|
|
133
|
+
return `${mountPoint}c/Windows/System32/WindowsPowerShell/v1.0/powershell.exe`;
|
|
134
|
+
};
|
|
135
|
+
powerShellPath = async () => {
|
|
136
|
+
if (is_wsl_default) {
|
|
137
|
+
return powerShellPathFromWsl();
|
|
138
|
+
}
|
|
139
|
+
return `${process3.env.SYSTEMROOT || process3.env.windir || String.raw`C:\Windows`}\\System32\\WindowsPowerShell\\v1.0\\powershell.exe`;
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
// ../../node_modules/define-lazy-prop/index.js
|
|
145
|
+
function defineLazyProperty(object, propertyName, valueGetter) {
|
|
146
|
+
const define = (value) => Object.defineProperty(object, propertyName, { value, enumerable: true, writable: true });
|
|
147
|
+
Object.defineProperty(object, propertyName, {
|
|
148
|
+
configurable: true,
|
|
149
|
+
enumerable: true,
|
|
150
|
+
get() {
|
|
151
|
+
const result = valueGetter();
|
|
152
|
+
define(result);
|
|
153
|
+
return result;
|
|
154
|
+
},
|
|
155
|
+
set(value) {
|
|
156
|
+
define(value);
|
|
157
|
+
}
|
|
158
|
+
});
|
|
159
|
+
return object;
|
|
160
|
+
}
|
|
161
|
+
var init_define_lazy_prop = __esm({
|
|
162
|
+
"../../node_modules/define-lazy-prop/index.js"() {
|
|
163
|
+
"use strict";
|
|
164
|
+
}
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
// ../../node_modules/default-browser-id/index.js
|
|
168
|
+
import { promisify } from "util";
|
|
169
|
+
import process4 from "process";
|
|
170
|
+
import { execFile } from "child_process";
|
|
171
|
+
async function defaultBrowserId() {
|
|
172
|
+
if (process4.platform !== "darwin") {
|
|
173
|
+
throw new Error("macOS only");
|
|
174
|
+
}
|
|
175
|
+
const { stdout } = await execFileAsync("defaults", ["read", "com.apple.LaunchServices/com.apple.launchservices.secure", "LSHandlers"]);
|
|
176
|
+
const match = /LSHandlerRoleAll = "(?!-)(?<id>[^"]+?)";\s+?LSHandlerURLScheme = (?:http|https);/.exec(stdout);
|
|
177
|
+
const browserId = match?.groups.id ?? "com.apple.Safari";
|
|
178
|
+
if (browserId === "com.apple.safari") {
|
|
179
|
+
return "com.apple.Safari";
|
|
180
|
+
}
|
|
181
|
+
return browserId;
|
|
182
|
+
}
|
|
183
|
+
var execFileAsync;
|
|
184
|
+
var init_default_browser_id = __esm({
|
|
185
|
+
"../../node_modules/default-browser-id/index.js"() {
|
|
186
|
+
"use strict";
|
|
187
|
+
execFileAsync = promisify(execFile);
|
|
188
|
+
}
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
// ../../node_modules/run-applescript/index.js
|
|
192
|
+
import process5 from "process";
|
|
193
|
+
import { promisify as promisify2 } from "util";
|
|
194
|
+
import { execFile as execFile2, execFileSync } from "child_process";
|
|
195
|
+
async function runAppleScript(script, { humanReadableOutput = true, signal } = {}) {
|
|
196
|
+
if (process5.platform !== "darwin") {
|
|
197
|
+
throw new Error("macOS only");
|
|
198
|
+
}
|
|
199
|
+
const outputArguments = humanReadableOutput ? [] : ["-ss"];
|
|
200
|
+
const execOptions = {};
|
|
201
|
+
if (signal) {
|
|
202
|
+
execOptions.signal = signal;
|
|
203
|
+
}
|
|
204
|
+
const { stdout } = await execFileAsync2("osascript", ["-e", script, outputArguments], execOptions);
|
|
205
|
+
return stdout.trim();
|
|
206
|
+
}
|
|
207
|
+
var execFileAsync2;
|
|
208
|
+
var init_run_applescript = __esm({
|
|
209
|
+
"../../node_modules/run-applescript/index.js"() {
|
|
210
|
+
"use strict";
|
|
211
|
+
execFileAsync2 = promisify2(execFile2);
|
|
212
|
+
}
|
|
213
|
+
});
|
|
214
|
+
|
|
215
|
+
// ../../node_modules/bundle-name/index.js
|
|
216
|
+
async function bundleName(bundleId) {
|
|
217
|
+
return runAppleScript(`tell application "Finder" to set app_path to application file id "${bundleId}" as string
|
|
218
|
+
tell application "System Events" to get value of property list item "CFBundleName" of property list file (app_path & ":Contents:Info.plist")`);
|
|
219
|
+
}
|
|
220
|
+
var init_bundle_name = __esm({
|
|
221
|
+
"../../node_modules/bundle-name/index.js"() {
|
|
222
|
+
"use strict";
|
|
223
|
+
init_run_applescript();
|
|
224
|
+
}
|
|
225
|
+
});
|
|
226
|
+
|
|
227
|
+
// ../../node_modules/default-browser/windows.js
|
|
228
|
+
import { promisify as promisify3 } from "util";
|
|
229
|
+
import { execFile as execFile3 } from "child_process";
|
|
230
|
+
async function defaultBrowser(_execFileAsync = execFileAsync3) {
|
|
231
|
+
const { stdout } = await _execFileAsync("reg", [
|
|
232
|
+
"QUERY",
|
|
233
|
+
" HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\Shell\\Associations\\UrlAssociations\\http\\UserChoice",
|
|
234
|
+
"/v",
|
|
235
|
+
"ProgId"
|
|
236
|
+
]);
|
|
237
|
+
const match = /ProgId\s*REG_SZ\s*(?<id>\S+)/.exec(stdout);
|
|
238
|
+
if (!match) {
|
|
239
|
+
throw new UnknownBrowserError(`Cannot find Windows browser in stdout: ${JSON.stringify(stdout)}`);
|
|
240
|
+
}
|
|
241
|
+
const { id } = match.groups;
|
|
242
|
+
const browser = windowsBrowserProgIds[id];
|
|
243
|
+
if (!browser) {
|
|
244
|
+
throw new UnknownBrowserError(`Unknown browser ID: ${id}`);
|
|
245
|
+
}
|
|
246
|
+
return browser;
|
|
247
|
+
}
|
|
248
|
+
var execFileAsync3, windowsBrowserProgIds, _windowsBrowserProgIdMap, UnknownBrowserError;
|
|
249
|
+
var init_windows = __esm({
|
|
250
|
+
"../../node_modules/default-browser/windows.js"() {
|
|
251
|
+
"use strict";
|
|
252
|
+
execFileAsync3 = promisify3(execFile3);
|
|
253
|
+
windowsBrowserProgIds = {
|
|
254
|
+
MSEdgeHTM: { name: "Edge", id: "com.microsoft.edge" },
|
|
255
|
+
// The missing `L` is correct.
|
|
256
|
+
MSEdgeBHTML: { name: "Edge Beta", id: "com.microsoft.edge.beta" },
|
|
257
|
+
MSEdgeDHTML: { name: "Edge Dev", id: "com.microsoft.edge.dev" },
|
|
258
|
+
AppXq0fevzme2pys62n3e0fbqa7peapykr8v: { name: "Edge", id: "com.microsoft.edge.old" },
|
|
259
|
+
ChromeHTML: { name: "Chrome", id: "com.google.chrome" },
|
|
260
|
+
ChromeBHTML: { name: "Chrome Beta", id: "com.google.chrome.beta" },
|
|
261
|
+
ChromeDHTML: { name: "Chrome Dev", id: "com.google.chrome.dev" },
|
|
262
|
+
ChromiumHTM: { name: "Chromium", id: "org.chromium.Chromium" },
|
|
263
|
+
BraveHTML: { name: "Brave", id: "com.brave.Browser" },
|
|
264
|
+
BraveBHTML: { name: "Brave Beta", id: "com.brave.Browser.beta" },
|
|
265
|
+
BraveDHTML: { name: "Brave Dev", id: "com.brave.Browser.dev" },
|
|
266
|
+
BraveSSHTM: { name: "Brave Nightly", id: "com.brave.Browser.nightly" },
|
|
267
|
+
FirefoxURL: { name: "Firefox", id: "org.mozilla.firefox" },
|
|
268
|
+
OperaStable: { name: "Opera", id: "com.operasoftware.Opera" },
|
|
269
|
+
VivaldiHTM: { name: "Vivaldi", id: "com.vivaldi.Vivaldi" },
|
|
270
|
+
"IE.HTTP": { name: "Internet Explorer", id: "com.microsoft.ie" }
|
|
271
|
+
};
|
|
272
|
+
_windowsBrowserProgIdMap = new Map(Object.entries(windowsBrowserProgIds));
|
|
273
|
+
UnknownBrowserError = class extends Error {
|
|
274
|
+
};
|
|
275
|
+
}
|
|
276
|
+
});
|
|
277
|
+
|
|
278
|
+
// ../../node_modules/default-browser/index.js
|
|
279
|
+
import { promisify as promisify4 } from "util";
|
|
280
|
+
import process6 from "process";
|
|
281
|
+
import { execFile as execFile4 } from "child_process";
|
|
282
|
+
async function defaultBrowser2() {
|
|
283
|
+
if (process6.platform === "darwin") {
|
|
284
|
+
const id = await defaultBrowserId();
|
|
285
|
+
const name = await bundleName(id);
|
|
286
|
+
return { name, id };
|
|
287
|
+
}
|
|
288
|
+
if (process6.platform === "linux") {
|
|
289
|
+
const { stdout } = await execFileAsync4("xdg-mime", ["query", "default", "x-scheme-handler/http"]);
|
|
290
|
+
const id = stdout.trim();
|
|
291
|
+
const name = titleize(id.replace(/.desktop$/, "").replace("-", " "));
|
|
292
|
+
return { name, id };
|
|
293
|
+
}
|
|
294
|
+
if (process6.platform === "win32") {
|
|
295
|
+
return defaultBrowser();
|
|
296
|
+
}
|
|
297
|
+
throw new Error("Only macOS, Linux, and Windows are supported");
|
|
298
|
+
}
|
|
299
|
+
var execFileAsync4, titleize;
|
|
300
|
+
var init_default_browser = __esm({
|
|
301
|
+
"../../node_modules/default-browser/index.js"() {
|
|
302
|
+
"use strict";
|
|
303
|
+
init_default_browser_id();
|
|
304
|
+
init_bundle_name();
|
|
305
|
+
init_windows();
|
|
306
|
+
execFileAsync4 = promisify4(execFile4);
|
|
307
|
+
titleize = (string) => string.toLowerCase().replaceAll(/(?:^|\s|-)\S/g, (x) => x.toUpperCase());
|
|
308
|
+
}
|
|
309
|
+
});
|
|
310
|
+
|
|
311
|
+
// ../../node_modules/open/index.js
|
|
312
|
+
var open_exports = {};
|
|
313
|
+
__export(open_exports, {
|
|
314
|
+
apps: () => apps,
|
|
315
|
+
default: () => open_default,
|
|
316
|
+
openApp: () => openApp
|
|
317
|
+
});
|
|
318
|
+
import process7 from "process";
|
|
319
|
+
import { Buffer as Buffer2 } from "buffer";
|
|
320
|
+
import path15 from "path";
|
|
321
|
+
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
322
|
+
import { promisify as promisify5 } from "util";
|
|
323
|
+
import childProcess from "child_process";
|
|
324
|
+
import fs19, { constants as fsConstants2 } from "fs/promises";
|
|
325
|
+
async function getWindowsDefaultBrowserFromWsl() {
|
|
326
|
+
const powershellPath = await powerShellPath();
|
|
327
|
+
const rawCommand = String.raw`(Get-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\Shell\Associations\UrlAssociations\http\UserChoice").ProgId`;
|
|
328
|
+
const encodedCommand = Buffer2.from(rawCommand, "utf16le").toString("base64");
|
|
329
|
+
const { stdout } = await execFile5(
|
|
330
|
+
powershellPath,
|
|
331
|
+
[
|
|
332
|
+
"-NoProfile",
|
|
333
|
+
"-NonInteractive",
|
|
334
|
+
"-ExecutionPolicy",
|
|
335
|
+
"Bypass",
|
|
336
|
+
"-EncodedCommand",
|
|
337
|
+
encodedCommand
|
|
338
|
+
],
|
|
339
|
+
{ encoding: "utf8" }
|
|
340
|
+
);
|
|
341
|
+
const progId = stdout.trim();
|
|
342
|
+
const browserMap = {
|
|
343
|
+
ChromeHTML: "com.google.chrome",
|
|
344
|
+
BraveHTML: "com.brave.Browser",
|
|
345
|
+
MSEdgeHTM: "com.microsoft.edge",
|
|
346
|
+
FirefoxURL: "org.mozilla.firefox"
|
|
347
|
+
};
|
|
348
|
+
return browserMap[progId] ? { id: browserMap[progId] } : {};
|
|
349
|
+
}
|
|
350
|
+
function detectArchBinary(binary) {
|
|
351
|
+
if (typeof binary === "string" || Array.isArray(binary)) {
|
|
352
|
+
return binary;
|
|
353
|
+
}
|
|
354
|
+
const { [arch]: archBinary } = binary;
|
|
355
|
+
if (!archBinary) {
|
|
356
|
+
throw new Error(`${arch} is not supported`);
|
|
357
|
+
}
|
|
358
|
+
return archBinary;
|
|
359
|
+
}
|
|
360
|
+
function detectPlatformBinary({ [platform]: platformBinary }, { wsl }) {
|
|
361
|
+
if (wsl && is_wsl_default) {
|
|
362
|
+
return detectArchBinary(wsl);
|
|
363
|
+
}
|
|
364
|
+
if (!platformBinary) {
|
|
365
|
+
throw new Error(`${platform} is not supported`);
|
|
366
|
+
}
|
|
367
|
+
return detectArchBinary(platformBinary);
|
|
368
|
+
}
|
|
369
|
+
var execFile5, __dirname, localXdgOpenPath, platform, arch, pTryEach, baseOpen, open, openApp, apps, open_default;
|
|
370
|
+
var init_open = __esm({
|
|
371
|
+
"../../node_modules/open/index.js"() {
|
|
372
|
+
"use strict";
|
|
373
|
+
init_wsl_utils();
|
|
374
|
+
init_define_lazy_prop();
|
|
375
|
+
init_default_browser();
|
|
376
|
+
init_is_inside_container();
|
|
377
|
+
execFile5 = promisify5(childProcess.execFile);
|
|
378
|
+
__dirname = path15.dirname(fileURLToPath3(import.meta.url));
|
|
379
|
+
localXdgOpenPath = path15.join(__dirname, "xdg-open");
|
|
380
|
+
({ platform, arch } = process7);
|
|
381
|
+
pTryEach = async (array, mapper) => {
|
|
382
|
+
let latestError;
|
|
383
|
+
for (const item of array) {
|
|
384
|
+
try {
|
|
385
|
+
return await mapper(item);
|
|
386
|
+
} catch (error) {
|
|
387
|
+
latestError = error;
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
throw latestError;
|
|
391
|
+
};
|
|
392
|
+
baseOpen = async (options) => {
|
|
393
|
+
options = {
|
|
394
|
+
wait: false,
|
|
395
|
+
background: false,
|
|
396
|
+
newInstance: false,
|
|
397
|
+
allowNonzeroExitCode: false,
|
|
398
|
+
...options
|
|
399
|
+
};
|
|
400
|
+
if (Array.isArray(options.app)) {
|
|
401
|
+
return pTryEach(options.app, (singleApp) => baseOpen({
|
|
402
|
+
...options,
|
|
403
|
+
app: singleApp
|
|
404
|
+
}));
|
|
405
|
+
}
|
|
406
|
+
let { name: app, arguments: appArguments = [] } = options.app ?? {};
|
|
407
|
+
appArguments = [...appArguments];
|
|
408
|
+
if (Array.isArray(app)) {
|
|
409
|
+
return pTryEach(app, (appName) => baseOpen({
|
|
410
|
+
...options,
|
|
411
|
+
app: {
|
|
412
|
+
name: appName,
|
|
413
|
+
arguments: appArguments
|
|
414
|
+
}
|
|
415
|
+
}));
|
|
416
|
+
}
|
|
417
|
+
if (app === "browser" || app === "browserPrivate") {
|
|
418
|
+
const ids = {
|
|
419
|
+
"com.google.chrome": "chrome",
|
|
420
|
+
"google-chrome.desktop": "chrome",
|
|
421
|
+
"com.brave.Browser": "brave",
|
|
422
|
+
"org.mozilla.firefox": "firefox",
|
|
423
|
+
"firefox.desktop": "firefox",
|
|
424
|
+
"com.microsoft.msedge": "edge",
|
|
425
|
+
"com.microsoft.edge": "edge",
|
|
426
|
+
"com.microsoft.edgemac": "edge",
|
|
427
|
+
"microsoft-edge.desktop": "edge"
|
|
428
|
+
};
|
|
429
|
+
const flags = {
|
|
430
|
+
chrome: "--incognito",
|
|
431
|
+
brave: "--incognito",
|
|
432
|
+
firefox: "--private-window",
|
|
433
|
+
edge: "--inPrivate"
|
|
434
|
+
};
|
|
435
|
+
const browser = is_wsl_default ? await getWindowsDefaultBrowserFromWsl() : await defaultBrowser2();
|
|
436
|
+
if (browser.id in ids) {
|
|
437
|
+
const browserName = ids[browser.id];
|
|
438
|
+
if (app === "browserPrivate") {
|
|
439
|
+
appArguments.push(flags[browserName]);
|
|
440
|
+
}
|
|
441
|
+
return baseOpen({
|
|
442
|
+
...options,
|
|
443
|
+
app: {
|
|
444
|
+
name: apps[browserName],
|
|
445
|
+
arguments: appArguments
|
|
446
|
+
}
|
|
447
|
+
});
|
|
448
|
+
}
|
|
449
|
+
throw new Error(`${browser.name} is not supported as a default browser`);
|
|
450
|
+
}
|
|
451
|
+
let command;
|
|
452
|
+
const cliArguments = [];
|
|
453
|
+
const childProcessOptions = {};
|
|
454
|
+
if (platform === "darwin") {
|
|
455
|
+
command = "open";
|
|
456
|
+
if (options.wait) {
|
|
457
|
+
cliArguments.push("--wait-apps");
|
|
458
|
+
}
|
|
459
|
+
if (options.background) {
|
|
460
|
+
cliArguments.push("--background");
|
|
461
|
+
}
|
|
462
|
+
if (options.newInstance) {
|
|
463
|
+
cliArguments.push("--new");
|
|
464
|
+
}
|
|
465
|
+
if (app) {
|
|
466
|
+
cliArguments.push("-a", app);
|
|
467
|
+
}
|
|
468
|
+
} else if (platform === "win32" || is_wsl_default && !isInsideContainer() && !app) {
|
|
469
|
+
command = await powerShellPath();
|
|
470
|
+
cliArguments.push(
|
|
471
|
+
"-NoProfile",
|
|
472
|
+
"-NonInteractive",
|
|
473
|
+
"-ExecutionPolicy",
|
|
474
|
+
"Bypass",
|
|
475
|
+
"-EncodedCommand"
|
|
476
|
+
);
|
|
477
|
+
if (!is_wsl_default) {
|
|
478
|
+
childProcessOptions.windowsVerbatimArguments = true;
|
|
479
|
+
}
|
|
480
|
+
const encodedArguments = ["Start"];
|
|
481
|
+
if (options.wait) {
|
|
482
|
+
encodedArguments.push("-Wait");
|
|
483
|
+
}
|
|
484
|
+
if (app) {
|
|
485
|
+
encodedArguments.push(`"\`"${app}\`""`);
|
|
486
|
+
if (options.target) {
|
|
487
|
+
appArguments.push(options.target);
|
|
488
|
+
}
|
|
489
|
+
} else if (options.target) {
|
|
490
|
+
encodedArguments.push(`"${options.target}"`);
|
|
491
|
+
}
|
|
492
|
+
if (appArguments.length > 0) {
|
|
493
|
+
appArguments = appArguments.map((argument) => `"\`"${argument}\`""`);
|
|
494
|
+
encodedArguments.push("-ArgumentList", appArguments.join(","));
|
|
495
|
+
}
|
|
496
|
+
options.target = Buffer2.from(encodedArguments.join(" "), "utf16le").toString("base64");
|
|
497
|
+
} else {
|
|
498
|
+
if (app) {
|
|
499
|
+
command = app;
|
|
500
|
+
} else {
|
|
501
|
+
const isBundled = !__dirname || __dirname === "/";
|
|
502
|
+
let exeLocalXdgOpen = false;
|
|
503
|
+
try {
|
|
504
|
+
await fs19.access(localXdgOpenPath, fsConstants2.X_OK);
|
|
505
|
+
exeLocalXdgOpen = true;
|
|
506
|
+
} catch {
|
|
507
|
+
}
|
|
508
|
+
const useSystemXdgOpen = process7.versions.electron ?? (platform === "android" || isBundled || !exeLocalXdgOpen);
|
|
509
|
+
command = useSystemXdgOpen ? "xdg-open" : localXdgOpenPath;
|
|
510
|
+
}
|
|
511
|
+
if (appArguments.length > 0) {
|
|
512
|
+
cliArguments.push(...appArguments);
|
|
513
|
+
}
|
|
514
|
+
if (!options.wait) {
|
|
515
|
+
childProcessOptions.stdio = "ignore";
|
|
516
|
+
childProcessOptions.detached = true;
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
if (platform === "darwin" && appArguments.length > 0) {
|
|
520
|
+
cliArguments.push("--args", ...appArguments);
|
|
521
|
+
}
|
|
522
|
+
if (options.target) {
|
|
523
|
+
cliArguments.push(options.target);
|
|
524
|
+
}
|
|
525
|
+
const subprocess = childProcess.spawn(command, cliArguments, childProcessOptions);
|
|
526
|
+
if (options.wait) {
|
|
527
|
+
return new Promise((resolve3, reject) => {
|
|
528
|
+
subprocess.once("error", reject);
|
|
529
|
+
subprocess.once("close", (exitCode) => {
|
|
530
|
+
if (!options.allowNonzeroExitCode && exitCode > 0) {
|
|
531
|
+
reject(new Error(`Exited with code ${exitCode}`));
|
|
532
|
+
return;
|
|
533
|
+
}
|
|
534
|
+
resolve3(subprocess);
|
|
535
|
+
});
|
|
536
|
+
});
|
|
537
|
+
}
|
|
538
|
+
subprocess.unref();
|
|
539
|
+
return subprocess;
|
|
540
|
+
};
|
|
541
|
+
open = (target, options) => {
|
|
542
|
+
if (typeof target !== "string") {
|
|
543
|
+
throw new TypeError("Expected a `target`");
|
|
544
|
+
}
|
|
545
|
+
return baseOpen({
|
|
546
|
+
...options,
|
|
547
|
+
target
|
|
548
|
+
});
|
|
549
|
+
};
|
|
550
|
+
openApp = (name, options) => {
|
|
551
|
+
if (typeof name !== "string" && !Array.isArray(name)) {
|
|
552
|
+
throw new TypeError("Expected a valid `name`");
|
|
553
|
+
}
|
|
554
|
+
const { arguments: appArguments = [] } = options ?? {};
|
|
555
|
+
if (appArguments !== void 0 && appArguments !== null && !Array.isArray(appArguments)) {
|
|
556
|
+
throw new TypeError("Expected `appArguments` as Array type");
|
|
557
|
+
}
|
|
558
|
+
return baseOpen({
|
|
559
|
+
...options,
|
|
560
|
+
app: {
|
|
561
|
+
name,
|
|
562
|
+
arguments: appArguments
|
|
563
|
+
}
|
|
564
|
+
});
|
|
565
|
+
};
|
|
566
|
+
apps = {};
|
|
567
|
+
defineLazyProperty(apps, "chrome", () => detectPlatformBinary({
|
|
568
|
+
darwin: "google chrome",
|
|
569
|
+
win32: "chrome",
|
|
570
|
+
linux: ["google-chrome", "google-chrome-stable", "chromium"]
|
|
571
|
+
}, {
|
|
572
|
+
wsl: {
|
|
573
|
+
ia32: "/mnt/c/Program Files (x86)/Google/Chrome/Application/chrome.exe",
|
|
574
|
+
x64: ["/mnt/c/Program Files/Google/Chrome/Application/chrome.exe", "/mnt/c/Program Files (x86)/Google/Chrome/Application/chrome.exe"]
|
|
575
|
+
}
|
|
576
|
+
}));
|
|
577
|
+
defineLazyProperty(apps, "brave", () => detectPlatformBinary({
|
|
578
|
+
darwin: "brave browser",
|
|
579
|
+
win32: "brave",
|
|
580
|
+
linux: ["brave-browser", "brave"]
|
|
581
|
+
}, {
|
|
582
|
+
wsl: {
|
|
583
|
+
ia32: "/mnt/c/Program Files (x86)/BraveSoftware/Brave-Browser/Application/brave.exe",
|
|
584
|
+
x64: ["/mnt/c/Program Files/BraveSoftware/Brave-Browser/Application/brave.exe", "/mnt/c/Program Files (x86)/BraveSoftware/Brave-Browser/Application/brave.exe"]
|
|
585
|
+
}
|
|
586
|
+
}));
|
|
587
|
+
defineLazyProperty(apps, "firefox", () => detectPlatformBinary({
|
|
588
|
+
darwin: "firefox",
|
|
589
|
+
win32: String.raw`C:\Program Files\Mozilla Firefox\firefox.exe`,
|
|
590
|
+
linux: "firefox"
|
|
591
|
+
}, {
|
|
592
|
+
wsl: "/mnt/c/Program Files/Mozilla Firefox/firefox.exe"
|
|
593
|
+
}));
|
|
594
|
+
defineLazyProperty(apps, "edge", () => detectPlatformBinary({
|
|
595
|
+
darwin: "microsoft edge",
|
|
596
|
+
win32: "msedge",
|
|
597
|
+
linux: ["microsoft-edge", "microsoft-edge-dev"]
|
|
598
|
+
}, {
|
|
599
|
+
wsl: "/mnt/c/Program Files (x86)/Microsoft/Edge/Application/msedge.exe"
|
|
600
|
+
}));
|
|
601
|
+
defineLazyProperty(apps, "browser", () => "browser");
|
|
602
|
+
defineLazyProperty(apps, "browserPrivate", () => "browserPrivate");
|
|
603
|
+
open_default = open;
|
|
604
|
+
}
|
|
605
|
+
});
|
|
2
606
|
|
|
3
607
|
// src/index.ts
|
|
4
608
|
import { Command } from "commander";
|
|
5
|
-
import chalk3 from "chalk";
|
|
6
609
|
|
|
7
610
|
// src/version.ts
|
|
8
611
|
import { readFileSync } from "fs";
|
|
@@ -27,29 +630,33 @@ function findPackageJson() {
|
|
|
27
630
|
}
|
|
28
631
|
var VERSION = JSON.parse(findPackageJson()).version;
|
|
29
632
|
|
|
30
|
-
// src/
|
|
31
|
-
import
|
|
32
|
-
import fs8 from "fs-extra";
|
|
33
|
-
import { getPlatform as getPlatform2 } from "@walkeros/core";
|
|
633
|
+
// src/core/banner.ts
|
|
634
|
+
import chalk2 from "chalk";
|
|
34
635
|
|
|
35
636
|
// src/core/logger.ts
|
|
36
637
|
import chalk from "chalk";
|
|
37
638
|
var BRAND_COLOR = "#01b5e2";
|
|
38
639
|
function createLogger(options = {}) {
|
|
39
|
-
const {
|
|
640
|
+
const {
|
|
641
|
+
verbose = false,
|
|
642
|
+
silent = false,
|
|
643
|
+
json = false,
|
|
644
|
+
stderr = false
|
|
645
|
+
} = options;
|
|
40
646
|
const shouldLog = !silent && !json;
|
|
41
647
|
const shouldDebug = verbose && !silent && !json;
|
|
648
|
+
const out = stderr ? console.error : console.log;
|
|
42
649
|
return {
|
|
43
650
|
log: (...args) => {
|
|
44
651
|
if (shouldLog) {
|
|
45
652
|
const message = args.map((arg) => String(arg)).join(" ");
|
|
46
|
-
|
|
653
|
+
out(message);
|
|
47
654
|
}
|
|
48
655
|
},
|
|
49
656
|
brand: (...args) => {
|
|
50
657
|
if (shouldLog) {
|
|
51
658
|
const message = args.map((arg) => String(arg)).join(" ");
|
|
52
|
-
|
|
659
|
+
out(chalk.hex(BRAND_COLOR)(message));
|
|
53
660
|
}
|
|
54
661
|
},
|
|
55
662
|
error: (...args) => {
|
|
@@ -61,43 +668,43 @@ function createLogger(options = {}) {
|
|
|
61
668
|
debug: (...args) => {
|
|
62
669
|
if (shouldDebug) {
|
|
63
670
|
const message = args.map((arg) => String(arg)).join(" ");
|
|
64
|
-
|
|
671
|
+
out(` ${message}`);
|
|
65
672
|
}
|
|
66
673
|
},
|
|
67
674
|
json: (data) => {
|
|
68
675
|
if (!silent) {
|
|
69
|
-
|
|
676
|
+
out(JSON.stringify(data, null, 2));
|
|
70
677
|
}
|
|
71
678
|
},
|
|
72
679
|
// Backward-compatible methods (all use default terminal color per design)
|
|
73
680
|
info: (...args) => {
|
|
74
681
|
if (shouldLog) {
|
|
75
682
|
const message = args.map((arg) => String(arg)).join(" ");
|
|
76
|
-
|
|
683
|
+
out(message);
|
|
77
684
|
}
|
|
78
685
|
},
|
|
79
686
|
success: (...args) => {
|
|
80
687
|
if (shouldLog) {
|
|
81
688
|
const message = args.map((arg) => String(arg)).join(" ");
|
|
82
|
-
|
|
689
|
+
out(message);
|
|
83
690
|
}
|
|
84
691
|
},
|
|
85
692
|
warning: (...args) => {
|
|
86
693
|
if (shouldLog) {
|
|
87
694
|
const message = args.map((arg) => String(arg)).join(" ");
|
|
88
|
-
|
|
695
|
+
out(message);
|
|
89
696
|
}
|
|
90
697
|
},
|
|
91
698
|
warn: (...args) => {
|
|
92
699
|
if (shouldLog) {
|
|
93
700
|
const message = args.map((arg) => String(arg)).join(" ");
|
|
94
|
-
|
|
701
|
+
out(message);
|
|
95
702
|
}
|
|
96
703
|
},
|
|
97
704
|
gray: (...args) => {
|
|
98
705
|
if (shouldLog) {
|
|
99
706
|
const message = args.map((arg) => String(arg)).join(" ");
|
|
100
|
-
|
|
707
|
+
out(message);
|
|
101
708
|
}
|
|
102
709
|
}
|
|
103
710
|
};
|
|
@@ -106,10 +713,25 @@ function createCommandLogger(options) {
|
|
|
106
713
|
return createLogger({
|
|
107
714
|
verbose: options.verbose,
|
|
108
715
|
silent: options.silent ?? false,
|
|
109
|
-
json: options.json
|
|
716
|
+
json: options.json,
|
|
717
|
+
stderr: options.stderr
|
|
110
718
|
});
|
|
111
719
|
}
|
|
112
720
|
|
|
721
|
+
// src/core/banner.ts
|
|
722
|
+
function printBanner(version) {
|
|
723
|
+
const b = chalk2.hex(BRAND_COLOR);
|
|
724
|
+
console.error(`${b(" \u2571\u2571")}`);
|
|
725
|
+
console.error(`${b(" \u2571\u2571 \u2571\u2571")} ${b("walkerOS")}`);
|
|
726
|
+
console.error(`${b("\u2571\u2571 \u2571\u2571 \u2571\u2571")} v${version}`);
|
|
727
|
+
console.error("");
|
|
728
|
+
}
|
|
729
|
+
|
|
730
|
+
// src/commands/bundle/index.ts
|
|
731
|
+
import path10 from "path";
|
|
732
|
+
import fs9 from "fs-extra";
|
|
733
|
+
import { getPlatform as getPlatform2 } from "@walkeros/core";
|
|
734
|
+
|
|
113
735
|
// src/core/collector-logger.ts
|
|
114
736
|
function createCollectorLoggerConfig(cliLogger, verbose) {
|
|
115
737
|
return {
|
|
@@ -152,6 +774,17 @@ function createTimer() {
|
|
|
152
774
|
}
|
|
153
775
|
|
|
154
776
|
// src/core/output.ts
|
|
777
|
+
import fs from "fs-extra";
|
|
778
|
+
import path from "path";
|
|
779
|
+
async function writeResult(content, options) {
|
|
780
|
+
if (options.output) {
|
|
781
|
+
const outputPath = path.resolve(options.output);
|
|
782
|
+
await fs.ensureDir(path.dirname(outputPath));
|
|
783
|
+
await fs.writeFile(outputPath, content);
|
|
784
|
+
} else {
|
|
785
|
+
process.stdout.write(content);
|
|
786
|
+
}
|
|
787
|
+
}
|
|
155
788
|
function createJsonOutput(success, data, error, duration) {
|
|
156
789
|
return {
|
|
157
790
|
success,
|
|
@@ -171,25 +804,139 @@ function formatBytes(bytes) {
|
|
|
171
804
|
}
|
|
172
805
|
|
|
173
806
|
// src/core/tmp.ts
|
|
174
|
-
import
|
|
807
|
+
import path2 from "path";
|
|
175
808
|
var DEFAULT_TMP_ROOT = ".tmp";
|
|
176
809
|
function getTmpPath(tmpDir, ...segments) {
|
|
177
810
|
const root = tmpDir || DEFAULT_TMP_ROOT;
|
|
178
|
-
const absoluteRoot =
|
|
179
|
-
return
|
|
180
|
-
}
|
|
181
|
-
function getDefaultTmpRoot() {
|
|
182
|
-
return DEFAULT_TMP_ROOT;
|
|
811
|
+
const absoluteRoot = path2.isAbsolute(root) ? root : path2.resolve(root);
|
|
812
|
+
return path2.join(absoluteRoot, ...segments);
|
|
183
813
|
}
|
|
184
814
|
|
|
185
815
|
// src/core/asset-resolver.ts
|
|
186
816
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
187
|
-
import { existsSync } from "fs";
|
|
817
|
+
import { existsSync as existsSync2 } from "fs";
|
|
818
|
+
import path4 from "path";
|
|
819
|
+
|
|
820
|
+
// src/config/utils.ts
|
|
821
|
+
import fs2 from "fs-extra";
|
|
188
822
|
import path3 from "path";
|
|
189
823
|
|
|
824
|
+
// src/lib/config-file.ts
|
|
825
|
+
import {
|
|
826
|
+
readFileSync as readFileSync2,
|
|
827
|
+
writeFileSync,
|
|
828
|
+
mkdirSync,
|
|
829
|
+
unlinkSync,
|
|
830
|
+
existsSync
|
|
831
|
+
} from "fs";
|
|
832
|
+
import { join as join2 } from "path";
|
|
833
|
+
import { homedir } from "os";
|
|
834
|
+
function getConfigDir() {
|
|
835
|
+
const xdgConfig = process.env.XDG_CONFIG_HOME;
|
|
836
|
+
const base = xdgConfig || join2(homedir(), ".config");
|
|
837
|
+
return join2(base, "walkeros");
|
|
838
|
+
}
|
|
839
|
+
function getConfigPath() {
|
|
840
|
+
return join2(getConfigDir(), "config.json");
|
|
841
|
+
}
|
|
842
|
+
function readConfig() {
|
|
843
|
+
const configPath = getConfigPath();
|
|
844
|
+
try {
|
|
845
|
+
const content = readFileSync2(configPath, "utf-8");
|
|
846
|
+
return JSON.parse(content);
|
|
847
|
+
} catch {
|
|
848
|
+
return null;
|
|
849
|
+
}
|
|
850
|
+
}
|
|
851
|
+
function writeConfig(config) {
|
|
852
|
+
const dir = getConfigDir();
|
|
853
|
+
mkdirSync(dir, { recursive: true });
|
|
854
|
+
const configPath = getConfigPath();
|
|
855
|
+
writeFileSync(configPath, JSON.stringify(config, null, 2), { mode: 384 });
|
|
856
|
+
}
|
|
857
|
+
function deleteConfig() {
|
|
858
|
+
const configPath = getConfigPath();
|
|
859
|
+
if (existsSync(configPath)) {
|
|
860
|
+
unlinkSync(configPath);
|
|
861
|
+
return true;
|
|
862
|
+
}
|
|
863
|
+
return false;
|
|
864
|
+
}
|
|
865
|
+
function resolveToken() {
|
|
866
|
+
const envToken = process.env.WALKEROS_TOKEN;
|
|
867
|
+
if (envToken) return { token: envToken, source: "env" };
|
|
868
|
+
const config = readConfig();
|
|
869
|
+
if (config?.token) return { token: config.token, source: "config" };
|
|
870
|
+
return null;
|
|
871
|
+
}
|
|
872
|
+
function resolveAppUrl() {
|
|
873
|
+
const envUrl = process.env.WALKEROS_APP_URL;
|
|
874
|
+
if (envUrl) return envUrl;
|
|
875
|
+
const config = readConfig();
|
|
876
|
+
if (config?.appUrl) return config.appUrl;
|
|
877
|
+
return "https://app.walkeros.io";
|
|
878
|
+
}
|
|
879
|
+
|
|
880
|
+
// src/core/auth.ts
|
|
881
|
+
function getToken() {
|
|
882
|
+
const result = resolveToken();
|
|
883
|
+
return result?.token;
|
|
884
|
+
}
|
|
885
|
+
function getAuthHeaders() {
|
|
886
|
+
const token = getToken();
|
|
887
|
+
if (!token) return {};
|
|
888
|
+
return { Authorization: `Bearer ${token}` };
|
|
889
|
+
}
|
|
890
|
+
async function authenticatedFetch(url, init) {
|
|
891
|
+
const authHeaders = getAuthHeaders();
|
|
892
|
+
const existingHeaders = init?.headers instanceof Headers ? Object.fromEntries(init.headers.entries()) : Array.isArray(init?.headers) ? Object.fromEntries(init.headers) : init?.headers ?? {};
|
|
893
|
+
return fetch(url, {
|
|
894
|
+
...init,
|
|
895
|
+
headers: { ...existingHeaders, ...authHeaders }
|
|
896
|
+
});
|
|
897
|
+
}
|
|
898
|
+
function resolveBaseUrl() {
|
|
899
|
+
return resolveAppUrl();
|
|
900
|
+
}
|
|
901
|
+
function requireProjectId() {
|
|
902
|
+
const projectId = process.env.WALKEROS_PROJECT_ID;
|
|
903
|
+
if (!projectId) throw new Error("WALKEROS_PROJECT_ID not set.");
|
|
904
|
+
return projectId;
|
|
905
|
+
}
|
|
906
|
+
async function apiRequest(path16, options) {
|
|
907
|
+
const token = getToken();
|
|
908
|
+
if (!token) throw new Error("WALKEROS_TOKEN not set.");
|
|
909
|
+
const baseUrl = resolveBaseUrl();
|
|
910
|
+
const { responseFormat, timeout = 3e4, ...fetchOptions } = options || {};
|
|
911
|
+
const response = await fetch(`${baseUrl}${path16}`, {
|
|
912
|
+
...fetchOptions,
|
|
913
|
+
signal: AbortSignal.timeout(timeout),
|
|
914
|
+
headers: {
|
|
915
|
+
...fetchOptions?.headers,
|
|
916
|
+
Authorization: `Bearer ${token}`,
|
|
917
|
+
"Content-Type": "application/json"
|
|
918
|
+
}
|
|
919
|
+
});
|
|
920
|
+
if (responseFormat === "raw") {
|
|
921
|
+
if (!response.ok) {
|
|
922
|
+
const body = await response.json().catch(() => ({}));
|
|
923
|
+
throw new Error(
|
|
924
|
+
body?.error?.message || `HTTP ${response.status}`
|
|
925
|
+
);
|
|
926
|
+
}
|
|
927
|
+
return response;
|
|
928
|
+
}
|
|
929
|
+
if (!response.ok) {
|
|
930
|
+
const body = await response.json().catch(() => ({}));
|
|
931
|
+
throw new Error(
|
|
932
|
+
body?.error?.message || `HTTP ${response.status}`
|
|
933
|
+
);
|
|
934
|
+
}
|
|
935
|
+
if (response.status === 204) return { success: true };
|
|
936
|
+
return response.json();
|
|
937
|
+
}
|
|
938
|
+
|
|
190
939
|
// src/config/utils.ts
|
|
191
|
-
import fs from "fs-extra";
|
|
192
|
-
import path2 from "path";
|
|
193
940
|
function isUrl(str) {
|
|
194
941
|
try {
|
|
195
942
|
const url = new URL(str);
|
|
@@ -203,7 +950,7 @@ async function downloadFromUrl(url) {
|
|
|
203
950
|
throw new Error(`Invalid URL: ${url}`);
|
|
204
951
|
}
|
|
205
952
|
try {
|
|
206
|
-
const response = await
|
|
953
|
+
const response = await authenticatedFetch(url);
|
|
207
954
|
if (!response.ok) {
|
|
208
955
|
throw new Error(
|
|
209
956
|
`Failed to download ${url}: ${response.status} ${response.statusText}`
|
|
@@ -211,9 +958,9 @@ async function downloadFromUrl(url) {
|
|
|
211
958
|
}
|
|
212
959
|
const content = await response.text();
|
|
213
960
|
const downloadsDir = getTmpPath(void 0, "downloads");
|
|
214
|
-
await
|
|
215
|
-
const tempPath =
|
|
216
|
-
await
|
|
961
|
+
await fs2.ensureDir(downloadsDir);
|
|
962
|
+
const tempPath = path3.join(downloadsDir, "flow.json");
|
|
963
|
+
await fs2.writeFile(tempPath, content, "utf-8");
|
|
217
964
|
return tempPath;
|
|
218
965
|
} catch (error) {
|
|
219
966
|
if (error instanceof Error) {
|
|
@@ -229,13 +976,13 @@ async function loadJsonConfig(configPath) {
|
|
|
229
976
|
absolutePath = await downloadFromUrl(configPath);
|
|
230
977
|
isTemporary = true;
|
|
231
978
|
} else {
|
|
232
|
-
absolutePath =
|
|
233
|
-
if (!await
|
|
979
|
+
absolutePath = path3.resolve(configPath);
|
|
980
|
+
if (!await fs2.pathExists(absolutePath)) {
|
|
234
981
|
throw new Error(`Configuration file not found: ${absolutePath}`);
|
|
235
982
|
}
|
|
236
983
|
}
|
|
237
984
|
try {
|
|
238
|
-
const rawConfig = await
|
|
985
|
+
const rawConfig = await fs2.readJson(absolutePath);
|
|
239
986
|
return rawConfig;
|
|
240
987
|
} catch (error) {
|
|
241
988
|
throw new Error(
|
|
@@ -244,7 +991,7 @@ async function loadJsonConfig(configPath) {
|
|
|
244
991
|
} finally {
|
|
245
992
|
if (isTemporary) {
|
|
246
993
|
try {
|
|
247
|
-
await
|
|
994
|
+
await fs2.remove(absolutePath);
|
|
248
995
|
} catch {
|
|
249
996
|
}
|
|
250
997
|
}
|
|
@@ -266,11 +1013,11 @@ async function loadJsonFromSource(source, options) {
|
|
|
266
1013
|
try {
|
|
267
1014
|
const tempPath = await downloadFromUrl(trimmedSource);
|
|
268
1015
|
try {
|
|
269
|
-
const data = await
|
|
1016
|
+
const data = await fs2.readJson(tempPath);
|
|
270
1017
|
return data;
|
|
271
1018
|
} finally {
|
|
272
1019
|
try {
|
|
273
|
-
await
|
|
1020
|
+
await fs2.remove(tempPath);
|
|
274
1021
|
} catch {
|
|
275
1022
|
}
|
|
276
1023
|
}
|
|
@@ -280,10 +1027,10 @@ async function loadJsonFromSource(source, options) {
|
|
|
280
1027
|
);
|
|
281
1028
|
}
|
|
282
1029
|
}
|
|
283
|
-
const resolvedPath =
|
|
284
|
-
if (await
|
|
1030
|
+
const resolvedPath = path3.resolve(trimmedSource);
|
|
1031
|
+
if (await fs2.pathExists(resolvedPath)) {
|
|
285
1032
|
try {
|
|
286
|
-
const data = await
|
|
1033
|
+
const data = await fs2.readJson(resolvedPath);
|
|
287
1034
|
return data;
|
|
288
1035
|
} catch (error) {
|
|
289
1036
|
throw new Error(
|
|
@@ -309,15 +1056,15 @@ var cachedAssetDir;
|
|
|
309
1056
|
function getAssetDir() {
|
|
310
1057
|
if (cachedAssetDir) return cachedAssetDir;
|
|
311
1058
|
const currentFile = fileURLToPath2(import.meta.url);
|
|
312
|
-
let dir =
|
|
313
|
-
while (dir !==
|
|
314
|
-
if (
|
|
1059
|
+
let dir = path4.dirname(currentFile);
|
|
1060
|
+
while (dir !== path4.dirname(dir)) {
|
|
1061
|
+
if (existsSync2(path4.join(dir, "examples"))) {
|
|
315
1062
|
cachedAssetDir = dir;
|
|
316
1063
|
return dir;
|
|
317
1064
|
}
|
|
318
|
-
dir =
|
|
1065
|
+
dir = path4.dirname(dir);
|
|
319
1066
|
}
|
|
320
|
-
cachedAssetDir =
|
|
1067
|
+
cachedAssetDir = path4.dirname(currentFile);
|
|
321
1068
|
return cachedAssetDir;
|
|
322
1069
|
}
|
|
323
1070
|
function resolveAsset(assetPath, assetType, baseDir) {
|
|
@@ -326,12 +1073,12 @@ function resolveAsset(assetPath, assetType, baseDir) {
|
|
|
326
1073
|
}
|
|
327
1074
|
if (!assetPath.includes("/") && !assetPath.includes("\\")) {
|
|
328
1075
|
const assetDir = getAssetDir();
|
|
329
|
-
return
|
|
1076
|
+
return path4.join(assetDir, "examples", assetPath);
|
|
330
1077
|
}
|
|
331
|
-
if (
|
|
1078
|
+
if (path4.isAbsolute(assetPath)) {
|
|
332
1079
|
return assetPath;
|
|
333
1080
|
}
|
|
334
|
-
return
|
|
1081
|
+
return path4.resolve(baseDir || process.cwd(), assetPath);
|
|
335
1082
|
}
|
|
336
1083
|
|
|
337
1084
|
// src/core/utils.ts
|
|
@@ -340,23 +1087,23 @@ function getErrorMessage(error) {
|
|
|
340
1087
|
}
|
|
341
1088
|
|
|
342
1089
|
// src/core/local-packages.ts
|
|
343
|
-
import
|
|
344
|
-
import
|
|
1090
|
+
import path5 from "path";
|
|
1091
|
+
import fs3 from "fs-extra";
|
|
345
1092
|
async function resolveLocalPackage(packageName, localPath, configDir, logger2) {
|
|
346
|
-
const absolutePath =
|
|
347
|
-
if (!await
|
|
1093
|
+
const absolutePath = path5.isAbsolute(localPath) ? localPath : path5.resolve(configDir, localPath);
|
|
1094
|
+
if (!await fs3.pathExists(absolutePath)) {
|
|
348
1095
|
throw new Error(
|
|
349
1096
|
`Local package path not found: ${localPath} (resolved to ${absolutePath})`
|
|
350
1097
|
);
|
|
351
1098
|
}
|
|
352
|
-
const pkgJsonPath =
|
|
353
|
-
if (!await
|
|
1099
|
+
const pkgJsonPath = path5.join(absolutePath, "package.json");
|
|
1100
|
+
if (!await fs3.pathExists(pkgJsonPath)) {
|
|
354
1101
|
throw new Error(
|
|
355
1102
|
`No package.json found at ${absolutePath}. Is this a valid package directory?`
|
|
356
1103
|
);
|
|
357
1104
|
}
|
|
358
|
-
const distPath =
|
|
359
|
-
const hasDistFolder = await
|
|
1105
|
+
const distPath = path5.join(absolutePath, "dist");
|
|
1106
|
+
const hasDistFolder = await fs3.pathExists(distPath);
|
|
360
1107
|
if (!hasDistFolder) {
|
|
361
1108
|
logger2.warn(
|
|
362
1109
|
`\u26A0\uFE0F ${packageName}: No dist/ folder found. Using package root.`
|
|
@@ -370,21 +1117,21 @@ async function resolveLocalPackage(packageName, localPath, configDir, logger2) {
|
|
|
370
1117
|
};
|
|
371
1118
|
}
|
|
372
1119
|
async function copyLocalPackage(localPkg, targetDir, logger2) {
|
|
373
|
-
const packageDir =
|
|
374
|
-
await
|
|
375
|
-
await
|
|
376
|
-
|
|
377
|
-
|
|
1120
|
+
const packageDir = path5.join(targetDir, "node_modules", localPkg.name);
|
|
1121
|
+
await fs3.ensureDir(path5.dirname(packageDir));
|
|
1122
|
+
await fs3.copy(
|
|
1123
|
+
path5.join(localPkg.absolutePath, "package.json"),
|
|
1124
|
+
path5.join(packageDir, "package.json")
|
|
378
1125
|
);
|
|
379
1126
|
if (localPkg.hasDistFolder) {
|
|
380
|
-
await
|
|
1127
|
+
await fs3.copy(localPkg.distPath, path5.join(packageDir, "dist"));
|
|
381
1128
|
} else {
|
|
382
|
-
const entries = await
|
|
1129
|
+
const entries = await fs3.readdir(localPkg.absolutePath);
|
|
383
1130
|
for (const entry of entries) {
|
|
384
1131
|
if (!["node_modules", ".turbo", ".git"].includes(entry)) {
|
|
385
|
-
await
|
|
386
|
-
|
|
387
|
-
|
|
1132
|
+
await fs3.copy(
|
|
1133
|
+
path5.join(localPkg.absolutePath, entry),
|
|
1134
|
+
path5.join(packageDir, entry)
|
|
388
1135
|
);
|
|
389
1136
|
}
|
|
390
1137
|
}
|
|
@@ -394,15 +1141,15 @@ async function copyLocalPackage(localPkg, targetDir, logger2) {
|
|
|
394
1141
|
}
|
|
395
1142
|
|
|
396
1143
|
// src/core/input-detector.ts
|
|
397
|
-
import
|
|
1144
|
+
import fs4 from "fs-extra";
|
|
398
1145
|
async function detectInput(inputPath, platformOverride) {
|
|
399
1146
|
const content = await loadContent(inputPath);
|
|
400
1147
|
try {
|
|
401
1148
|
JSON.parse(content);
|
|
402
1149
|
return { type: "config", content };
|
|
403
1150
|
} catch {
|
|
404
|
-
const
|
|
405
|
-
return { type: "bundle", content, platform };
|
|
1151
|
+
const platform2 = platformOverride ?? detectPlatformFromPath(inputPath);
|
|
1152
|
+
return { type: "bundle", content, platform: platform2 };
|
|
406
1153
|
}
|
|
407
1154
|
}
|
|
408
1155
|
function detectPlatformFromPath(inputPath) {
|
|
@@ -411,13 +1158,29 @@ function detectPlatformFromPath(inputPath) {
|
|
|
411
1158
|
}
|
|
412
1159
|
async function loadContent(inputPath) {
|
|
413
1160
|
if (isUrl(inputPath)) {
|
|
414
|
-
const response = await
|
|
1161
|
+
const response = await authenticatedFetch(inputPath);
|
|
415
1162
|
if (!response.ok) {
|
|
416
1163
|
throw new Error(`Failed to fetch ${inputPath}: ${response.status}`);
|
|
417
1164
|
}
|
|
418
1165
|
return response.text();
|
|
419
1166
|
}
|
|
420
|
-
return
|
|
1167
|
+
return fs4.readFile(inputPath, "utf8");
|
|
1168
|
+
}
|
|
1169
|
+
|
|
1170
|
+
// src/core/stdin.ts
|
|
1171
|
+
function isStdinPiped() {
|
|
1172
|
+
return !process.stdin.isTTY;
|
|
1173
|
+
}
|
|
1174
|
+
async function readStdin() {
|
|
1175
|
+
const chunks = [];
|
|
1176
|
+
for await (const chunk of process.stdin) {
|
|
1177
|
+
chunks.push(chunk);
|
|
1178
|
+
}
|
|
1179
|
+
const content = Buffer.concat(chunks).toString("utf-8");
|
|
1180
|
+
if (!content.trim()) {
|
|
1181
|
+
throw new Error("No input received on stdin");
|
|
1182
|
+
}
|
|
1183
|
+
return content;
|
|
421
1184
|
}
|
|
422
1185
|
|
|
423
1186
|
// src/config/validators.ts
|
|
@@ -430,8 +1193,8 @@ function validateFlowSetup(data) {
|
|
|
430
1193
|
const result = safeParseSetup(data);
|
|
431
1194
|
if (!result.success) {
|
|
432
1195
|
const errors = result.error.issues.map((issue) => {
|
|
433
|
-
const
|
|
434
|
-
return ` - ${
|
|
1196
|
+
const path16 = issue.path.length > 0 ? issue.path.map(String).join(".") : "root";
|
|
1197
|
+
return ` - ${path16}: ${issue.message}`;
|
|
435
1198
|
}).join("\n");
|
|
436
1199
|
throw new Error(`Invalid configuration:
|
|
437
1200
|
${errors}`);
|
|
@@ -465,16 +1228,16 @@ var DEFAULT_OUTPUT_PATHS = {
|
|
|
465
1228
|
web: "./dist/walker.js",
|
|
466
1229
|
server: "./dist/bundle.mjs"
|
|
467
1230
|
};
|
|
468
|
-
function getBuildDefaults(
|
|
469
|
-
return
|
|
1231
|
+
function getBuildDefaults(platform2) {
|
|
1232
|
+
return platform2 === "web" ? WEB_BUILD_DEFAULTS : SERVER_BUILD_DEFAULTS;
|
|
470
1233
|
}
|
|
471
|
-
function getDefaultOutput(
|
|
472
|
-
return DEFAULT_OUTPUT_PATHS[
|
|
1234
|
+
function getDefaultOutput(platform2) {
|
|
1235
|
+
return DEFAULT_OUTPUT_PATHS[platform2];
|
|
473
1236
|
}
|
|
474
1237
|
|
|
475
1238
|
// src/config/loader.ts
|
|
476
|
-
import
|
|
477
|
-
import
|
|
1239
|
+
import path6 from "path";
|
|
1240
|
+
import fs5 from "fs-extra";
|
|
478
1241
|
import { getFlowConfig, getPlatform } from "@walkeros/core";
|
|
479
1242
|
var DEFAULT_INCLUDE_FOLDER = "./shared";
|
|
480
1243
|
function loadBundleConfig(rawConfig, options) {
|
|
@@ -482,20 +1245,20 @@ function loadBundleConfig(rawConfig, options) {
|
|
|
482
1245
|
const availableFlows = getAvailableFlows(setup);
|
|
483
1246
|
const flowName = resolveFlow(setup, options.flowName, availableFlows);
|
|
484
1247
|
const flowConfig = getFlowConfig(setup, flowName);
|
|
485
|
-
const
|
|
486
|
-
if (!
|
|
1248
|
+
const platform2 = getPlatform(flowConfig);
|
|
1249
|
+
if (!platform2) {
|
|
487
1250
|
throw new Error(
|
|
488
1251
|
`Invalid configuration: flow "${flowName}" must have a "web" or "server" key.`
|
|
489
1252
|
);
|
|
490
1253
|
}
|
|
491
|
-
const buildDefaults = getBuildDefaults(
|
|
1254
|
+
const buildDefaults = getBuildDefaults(platform2);
|
|
492
1255
|
const packages = flowConfig.packages || {};
|
|
493
|
-
const output = options.buildOverrides?.output || getDefaultOutput(
|
|
494
|
-
const configDir = isUrl(options.configPath) ? process.cwd() :
|
|
1256
|
+
const output = options.buildOverrides?.output || getDefaultOutput(platform2);
|
|
1257
|
+
const configDir = isUrl(options.configPath) ? process.cwd() : path6.dirname(options.configPath);
|
|
495
1258
|
let includes = setup.include;
|
|
496
1259
|
if (!includes) {
|
|
497
|
-
const defaultIncludePath =
|
|
498
|
-
if (
|
|
1260
|
+
const defaultIncludePath = path6.resolve(configDir, DEFAULT_INCLUDE_FOLDER);
|
|
1261
|
+
if (fs5.pathExistsSync(defaultIncludePath)) {
|
|
499
1262
|
includes = [DEFAULT_INCLUDE_FOLDER];
|
|
500
1263
|
}
|
|
501
1264
|
}
|
|
@@ -561,14 +1324,14 @@ async function loadFlowConfig(configPath, options) {
|
|
|
561
1324
|
|
|
562
1325
|
// src/commands/bundle/bundler.ts
|
|
563
1326
|
import esbuild from "esbuild";
|
|
564
|
-
import
|
|
565
|
-
import
|
|
1327
|
+
import path9 from "path";
|
|
1328
|
+
import fs8 from "fs-extra";
|
|
566
1329
|
import { packageNameToVariable } from "@walkeros/core";
|
|
567
1330
|
|
|
568
1331
|
// src/commands/bundle/package-manager.ts
|
|
569
1332
|
import pacote from "pacote";
|
|
570
|
-
import
|
|
571
|
-
import
|
|
1333
|
+
import path7 from "path";
|
|
1334
|
+
import fs6 from "fs-extra";
|
|
572
1335
|
|
|
573
1336
|
// src/core/cache-utils.ts
|
|
574
1337
|
import { getHashServer } from "@walkeros/server-core";
|
|
@@ -609,16 +1372,16 @@ async function withTimeout(promise, ms, errorMessage) {
|
|
|
609
1372
|
return Promise.race([promise, timeout]);
|
|
610
1373
|
}
|
|
611
1374
|
function getPackageDirectory(baseDir, packageName, version) {
|
|
612
|
-
return
|
|
1375
|
+
return path7.join(baseDir, "node_modules", packageName);
|
|
613
1376
|
}
|
|
614
1377
|
async function getCachedPackagePath(pkg, tmpDir) {
|
|
615
1378
|
const cacheDir = getTmpPath(tmpDir, "cache", "packages");
|
|
616
1379
|
const cacheKey = await getPackageCacheKey(pkg.name, pkg.version);
|
|
617
|
-
return
|
|
1380
|
+
return path7.join(cacheDir, cacheKey);
|
|
618
1381
|
}
|
|
619
1382
|
async function isPackageCached(pkg, tmpDir) {
|
|
620
1383
|
const cachedPath = await getCachedPackagePath(pkg, tmpDir);
|
|
621
|
-
return
|
|
1384
|
+
return fs6.pathExists(cachedPath);
|
|
622
1385
|
}
|
|
623
1386
|
function validateNoDuplicatePackages(packages) {
|
|
624
1387
|
const packageMap = /* @__PURE__ */ new Map();
|
|
@@ -652,9 +1415,9 @@ async function resolveDependencies(pkg, packageDir, logger2, visited = /* @__PUR
|
|
|
652
1415
|
}
|
|
653
1416
|
visited.add(pkgKey);
|
|
654
1417
|
try {
|
|
655
|
-
const packageJsonPath =
|
|
656
|
-
if (await
|
|
657
|
-
const packageJson = await
|
|
1418
|
+
const packageJsonPath = path7.join(packageDir, "package.json");
|
|
1419
|
+
if (await fs6.pathExists(packageJsonPath)) {
|
|
1420
|
+
const packageJson = await fs6.readJson(packageJsonPath);
|
|
658
1421
|
const deps = {
|
|
659
1422
|
...packageJson.dependencies,
|
|
660
1423
|
...packageJson.peerDependencies
|
|
@@ -682,7 +1445,7 @@ async function downloadPackages(packages, targetDir, logger2, useCache = true, c
|
|
|
682
1445
|
}
|
|
683
1446
|
}
|
|
684
1447
|
validateNoDuplicatePackages(packages);
|
|
685
|
-
await
|
|
1448
|
+
await fs6.ensureDir(targetDir);
|
|
686
1449
|
while (downloadQueue.length > 0) {
|
|
687
1450
|
const pkg = downloadQueue.shift();
|
|
688
1451
|
const pkgKey = `${pkg.name}@${pkg.version}`;
|
|
@@ -719,8 +1482,8 @@ async function downloadPackages(packages, targetDir, logger2, useCache = true, c
|
|
|
719
1482
|
logger2.debug(`Downloading ${packageSpec} (cached)`);
|
|
720
1483
|
}
|
|
721
1484
|
try {
|
|
722
|
-
await
|
|
723
|
-
await
|
|
1485
|
+
await fs6.ensureDir(path7.dirname(packageDir));
|
|
1486
|
+
await fs6.copy(cachedPath, packageDir);
|
|
724
1487
|
packagePaths.set(pkg.name, packageDir);
|
|
725
1488
|
const deps = await resolveDependencies(pkg, packageDir, logger2);
|
|
726
1489
|
for (const dep of deps) {
|
|
@@ -737,7 +1500,7 @@ async function downloadPackages(packages, targetDir, logger2, useCache = true, c
|
|
|
737
1500
|
}
|
|
738
1501
|
}
|
|
739
1502
|
try {
|
|
740
|
-
await
|
|
1503
|
+
await fs6.ensureDir(path7.dirname(packageDir));
|
|
741
1504
|
const cacheDir = process.env.NPM_CACHE_DIR || getTmpPath(void 0, "cache", "npm");
|
|
742
1505
|
await withTimeout(
|
|
743
1506
|
pacote.extract(packageSpec, packageDir, {
|
|
@@ -754,15 +1517,15 @@ async function downloadPackages(packages, targetDir, logger2, useCache = true, c
|
|
|
754
1517
|
`Package download timed out after ${PACKAGE_DOWNLOAD_TIMEOUT_MS / 1e3}s: ${packageSpec}`
|
|
755
1518
|
);
|
|
756
1519
|
if (userSpecifiedPackages.has(pkg.name)) {
|
|
757
|
-
const pkgStats = await
|
|
1520
|
+
const pkgStats = await fs6.stat(path7.join(packageDir, "package.json"));
|
|
758
1521
|
const pkgJsonSize = pkgStats.size;
|
|
759
1522
|
const sizeKB = (pkgJsonSize / 1024).toFixed(1);
|
|
760
1523
|
logger2.debug(`Downloading ${packageSpec} (${sizeKB} KB)`);
|
|
761
1524
|
}
|
|
762
1525
|
if (useCache) {
|
|
763
1526
|
try {
|
|
764
|
-
await
|
|
765
|
-
await
|
|
1527
|
+
await fs6.ensureDir(path7.dirname(cachedPath));
|
|
1528
|
+
await fs6.copy(packageDir, cachedPath);
|
|
766
1529
|
} catch (cacheError) {
|
|
767
1530
|
}
|
|
768
1531
|
}
|
|
@@ -782,26 +1545,26 @@ async function downloadPackages(packages, targetDir, logger2, useCache = true, c
|
|
|
782
1545
|
}
|
|
783
1546
|
|
|
784
1547
|
// src/core/build-cache.ts
|
|
785
|
-
import
|
|
786
|
-
import
|
|
1548
|
+
import fs7 from "fs-extra";
|
|
1549
|
+
import path8 from "path";
|
|
787
1550
|
async function getBuildCachePath(configContent, tmpDir) {
|
|
788
1551
|
const cacheDir = getTmpPath(tmpDir, "cache", "builds");
|
|
789
1552
|
const cacheKey = await getFlowConfigCacheKey(configContent);
|
|
790
|
-
return
|
|
1553
|
+
return path8.join(cacheDir, `${cacheKey}.js`);
|
|
791
1554
|
}
|
|
792
1555
|
async function isBuildCached(configContent, tmpDir) {
|
|
793
1556
|
const cachePath = await getBuildCachePath(configContent, tmpDir);
|
|
794
|
-
return
|
|
1557
|
+
return fs7.pathExists(cachePath);
|
|
795
1558
|
}
|
|
796
1559
|
async function cacheBuild(configContent, buildOutput, tmpDir) {
|
|
797
1560
|
const cachePath = await getBuildCachePath(configContent, tmpDir);
|
|
798
|
-
await
|
|
799
|
-
await
|
|
1561
|
+
await fs7.ensureDir(path8.dirname(cachePath));
|
|
1562
|
+
await fs7.writeFile(cachePath, buildOutput, "utf-8");
|
|
800
1563
|
}
|
|
801
1564
|
async function getCachedBuild(configContent, tmpDir) {
|
|
802
1565
|
const cachePath = await getBuildCachePath(configContent, tmpDir);
|
|
803
|
-
if (await
|
|
804
|
-
return await
|
|
1566
|
+
if (await fs7.pathExists(cachePath)) {
|
|
1567
|
+
return await fs7.readFile(cachePath, "utf-8");
|
|
805
1568
|
}
|
|
806
1569
|
return null;
|
|
807
1570
|
}
|
|
@@ -854,11 +1617,11 @@ function generateInlineCode(inline, config, env, chain, chainPropertyName, isDes
|
|
|
854
1617
|
}
|
|
855
1618
|
async function copyIncludes(includes, sourceDir, outputDir, logger2) {
|
|
856
1619
|
for (const include of includes) {
|
|
857
|
-
const sourcePath =
|
|
858
|
-
const folderName =
|
|
859
|
-
const destPath =
|
|
860
|
-
if (await
|
|
861
|
-
await
|
|
1620
|
+
const sourcePath = path9.resolve(sourceDir, include);
|
|
1621
|
+
const folderName = path9.basename(include);
|
|
1622
|
+
const destPath = path9.join(outputDir, folderName);
|
|
1623
|
+
if (await fs8.pathExists(sourcePath)) {
|
|
1624
|
+
await fs8.copy(sourcePath, destPath);
|
|
862
1625
|
logger2.debug(`Copied ${include} to output`);
|
|
863
1626
|
} else {
|
|
864
1627
|
logger2.debug(`Include folder not found: ${include}`);
|
|
@@ -927,14 +1690,14 @@ async function bundleCore(flowConfig, buildOptions, logger2, showStats = false)
|
|
|
927
1690
|
const cachedBuild = await getCachedBuild(configContent);
|
|
928
1691
|
if (cachedBuild) {
|
|
929
1692
|
logger2.debug("Using cached build");
|
|
930
|
-
const outputPath =
|
|
931
|
-
await
|
|
932
|
-
await
|
|
933
|
-
const stats = await
|
|
1693
|
+
const outputPath = path9.resolve(buildOptions.output);
|
|
1694
|
+
await fs8.ensureDir(path9.dirname(outputPath));
|
|
1695
|
+
await fs8.writeFile(outputPath, cachedBuild);
|
|
1696
|
+
const stats = await fs8.stat(outputPath);
|
|
934
1697
|
const sizeKB = (stats.size / 1024).toFixed(1);
|
|
935
1698
|
logger2.log(`Output: ${outputPath} (${sizeKB} KB, cached)`);
|
|
936
1699
|
if (showStats) {
|
|
937
|
-
const stats2 = await
|
|
1700
|
+
const stats2 = await fs8.stat(outputPath);
|
|
938
1701
|
const packageStats = Object.entries(buildOptions.packages).map(
|
|
939
1702
|
([name, pkg]) => ({
|
|
940
1703
|
name: `${name}@${pkg.version || "latest"}`,
|
|
@@ -954,7 +1717,7 @@ async function bundleCore(flowConfig, buildOptions, logger2, showStats = false)
|
|
|
954
1717
|
}
|
|
955
1718
|
}
|
|
956
1719
|
try {
|
|
957
|
-
await
|
|
1720
|
+
await fs8.ensureDir(TEMP_DIR);
|
|
958
1721
|
const hasSourcesOrDests = Object.keys(
|
|
959
1722
|
flowConfig.sources || {}
|
|
960
1723
|
).length > 0 || Object.keys(
|
|
@@ -982,8 +1745,8 @@ async function bundleCore(flowConfig, buildOptions, logger2, showStats = false)
|
|
|
982
1745
|
);
|
|
983
1746
|
for (const [pkgName, pkgPath] of packagePaths.entries()) {
|
|
984
1747
|
if (pkgName.startsWith("@walkeros/")) {
|
|
985
|
-
const pkgJsonPath =
|
|
986
|
-
const pkgJson = await
|
|
1748
|
+
const pkgJsonPath = path9.join(pkgPath, "package.json");
|
|
1749
|
+
const pkgJson = await fs8.readJSON(pkgJsonPath);
|
|
987
1750
|
if (!pkgJson.exports && pkgJson.module) {
|
|
988
1751
|
pkgJson.exports = {
|
|
989
1752
|
".": {
|
|
@@ -991,12 +1754,12 @@ async function bundleCore(flowConfig, buildOptions, logger2, showStats = false)
|
|
|
991
1754
|
require: pkgJson.main
|
|
992
1755
|
}
|
|
993
1756
|
};
|
|
994
|
-
await
|
|
1757
|
+
await fs8.writeJSON(pkgJsonPath, pkgJson, { spaces: 2 });
|
|
995
1758
|
}
|
|
996
1759
|
}
|
|
997
1760
|
}
|
|
998
|
-
const packageJsonPath =
|
|
999
|
-
await
|
|
1761
|
+
const packageJsonPath = path9.join(TEMP_DIR, "package.json");
|
|
1762
|
+
await fs8.writeFile(
|
|
1000
1763
|
packageJsonPath,
|
|
1001
1764
|
JSON.stringify({ type: "module" }, null, 2)
|
|
1002
1765
|
);
|
|
@@ -1006,13 +1769,13 @@ async function bundleCore(flowConfig, buildOptions, logger2, showStats = false)
|
|
|
1006
1769
|
buildOptions,
|
|
1007
1770
|
packagePaths
|
|
1008
1771
|
);
|
|
1009
|
-
const entryPath =
|
|
1010
|
-
await
|
|
1772
|
+
const entryPath = path9.join(TEMP_DIR, "entry.js");
|
|
1773
|
+
await fs8.writeFile(entryPath, entryContent);
|
|
1011
1774
|
logger2.debug(
|
|
1012
1775
|
`Running esbuild (target: ${buildOptions.target || "es2018"}, format: ${buildOptions.format})`
|
|
1013
1776
|
);
|
|
1014
|
-
const outputPath =
|
|
1015
|
-
await
|
|
1777
|
+
const outputPath = path9.resolve(buildOptions.output);
|
|
1778
|
+
await fs8.ensureDir(path9.dirname(outputPath));
|
|
1016
1779
|
const esbuildOptions = createEsbuildOptions(
|
|
1017
1780
|
buildOptions,
|
|
1018
1781
|
entryPath,
|
|
@@ -1031,13 +1794,13 @@ async function bundleCore(flowConfig, buildOptions, logger2, showStats = false)
|
|
|
1031
1794
|
} finally {
|
|
1032
1795
|
await esbuild.stop();
|
|
1033
1796
|
}
|
|
1034
|
-
const outputStats = await
|
|
1797
|
+
const outputStats = await fs8.stat(outputPath);
|
|
1035
1798
|
const sizeKB = (outputStats.size / 1024).toFixed(1);
|
|
1036
1799
|
const buildTime = ((Date.now() - bundleStartTime) / 1e3).toFixed(1);
|
|
1037
1800
|
logger2.log(`Output: ${outputPath} (${sizeKB} KB, ${buildTime}s)`);
|
|
1038
1801
|
if (buildOptions.cache !== false) {
|
|
1039
1802
|
const configContent = generateCacheKeyContent(flowConfig, buildOptions);
|
|
1040
|
-
const buildOutput = await
|
|
1803
|
+
const buildOutput = await fs8.readFile(outputPath, "utf-8");
|
|
1041
1804
|
await cacheBuild(configContent, buildOutput);
|
|
1042
1805
|
logger2.debug("Build cached for future use");
|
|
1043
1806
|
}
|
|
@@ -1051,7 +1814,7 @@ async function bundleCore(flowConfig, buildOptions, logger2, showStats = false)
|
|
|
1051
1814
|
);
|
|
1052
1815
|
}
|
|
1053
1816
|
if (buildOptions.include && buildOptions.include.length > 0) {
|
|
1054
|
-
const outputDir =
|
|
1817
|
+
const outputDir = path9.dirname(outputPath);
|
|
1055
1818
|
await copyIncludes(
|
|
1056
1819
|
buildOptions.include,
|
|
1057
1820
|
buildOptions.configDir || process.cwd(),
|
|
@@ -1065,7 +1828,7 @@ async function bundleCore(flowConfig, buildOptions, logger2, showStats = false)
|
|
|
1065
1828
|
}
|
|
1066
1829
|
}
|
|
1067
1830
|
async function collectBundleStats(outputPath, packages, startTime, entryContent) {
|
|
1068
|
-
const stats = await
|
|
1831
|
+
const stats = await fs8.stat(outputPath);
|
|
1069
1832
|
const totalSize = stats.size;
|
|
1070
1833
|
const buildTime = Date.now() - startTime;
|
|
1071
1834
|
const packageStats = Object.entries(packages).map(([name, pkg]) => {
|
|
@@ -1577,16 +2340,47 @@ Package Breakdown:`);
|
|
|
1577
2340
|
}
|
|
1578
2341
|
|
|
1579
2342
|
// src/commands/bundle/index.ts
|
|
2343
|
+
function resolveOutputPath(output, buildOptions) {
|
|
2344
|
+
const resolved = path10.resolve(output);
|
|
2345
|
+
const ext = path10.extname(resolved);
|
|
2346
|
+
if (output.endsWith("/") || output.endsWith(path10.sep) || !ext) {
|
|
2347
|
+
const filename = buildOptions.platform === "browser" ? "walker.js" : "bundle.mjs";
|
|
2348
|
+
return path10.join(resolved, filename);
|
|
2349
|
+
}
|
|
2350
|
+
return resolved;
|
|
2351
|
+
}
|
|
1580
2352
|
async function bundleCommand(options) {
|
|
1581
2353
|
const timer = createTimer();
|
|
1582
2354
|
timer.start();
|
|
1583
|
-
const
|
|
2355
|
+
const writingToStdout = !options.output;
|
|
2356
|
+
const logger2 = createCommandLogger({
|
|
2357
|
+
...options,
|
|
2358
|
+
stderr: writingToStdout
|
|
2359
|
+
});
|
|
1584
2360
|
try {
|
|
1585
2361
|
if (options.flow && options.all) {
|
|
1586
2362
|
throw new Error("Cannot use both --flow and --all flags together");
|
|
1587
2363
|
}
|
|
1588
|
-
|
|
1589
|
-
|
|
2364
|
+
if (options.all && writingToStdout) {
|
|
2365
|
+
throw new Error(
|
|
2366
|
+
"Cannot use --all without --output (multiple bundles need file output)"
|
|
2367
|
+
);
|
|
2368
|
+
}
|
|
2369
|
+
let rawConfig;
|
|
2370
|
+
let configPath;
|
|
2371
|
+
if (isStdinPiped() && !options.config) {
|
|
2372
|
+
const stdinContent = await readStdin();
|
|
2373
|
+
try {
|
|
2374
|
+
rawConfig = JSON.parse(stdinContent);
|
|
2375
|
+
} catch {
|
|
2376
|
+
throw new Error("Invalid JSON received on stdin");
|
|
2377
|
+
}
|
|
2378
|
+
configPath = path10.resolve(process.cwd(), "stdin.config.json");
|
|
2379
|
+
} else {
|
|
2380
|
+
const file = options.config || "bundle.config.json";
|
|
2381
|
+
configPath = resolveAsset(file, "config");
|
|
2382
|
+
rawConfig = await loadJsonConfig(configPath);
|
|
2383
|
+
}
|
|
1590
2384
|
const configsToBundle = options.all ? loadAllFlows(rawConfig, { configPath, logger: logger2 }) : [
|
|
1591
2385
|
loadBundleConfig(rawConfig, {
|
|
1592
2386
|
configPath,
|
|
@@ -1605,11 +2399,16 @@ async function bundleCommand(options) {
|
|
|
1605
2399
|
if (options.cache !== void 0) {
|
|
1606
2400
|
buildOptions.cache = options.cache;
|
|
1607
2401
|
}
|
|
1608
|
-
|
|
2402
|
+
if (options.output) {
|
|
2403
|
+
buildOptions.output = resolveOutputPath(options.output, buildOptions);
|
|
2404
|
+
} else {
|
|
2405
|
+
const ext = buildOptions.platform === "browser" ? ".js" : ".mjs";
|
|
2406
|
+
buildOptions.output = getTmpPath(void 0, "stdout-bundle" + ext);
|
|
2407
|
+
}
|
|
1609
2408
|
if (isMultiFlow || options.all) {
|
|
1610
|
-
logger2.log(`Bundling
|
|
2409
|
+
logger2.log(`Bundling flow: ${flowName}...`);
|
|
1611
2410
|
} else {
|
|
1612
|
-
logger2.log(
|
|
2411
|
+
logger2.log("Bundling...");
|
|
1613
2412
|
}
|
|
1614
2413
|
const shouldCollectStats = options.stats || options.json;
|
|
1615
2414
|
const stats = await bundleCore(
|
|
@@ -1618,29 +2417,25 @@ async function bundleCommand(options) {
|
|
|
1618
2417
|
logger2,
|
|
1619
2418
|
shouldCollectStats
|
|
1620
2419
|
);
|
|
1621
|
-
results.push({
|
|
1622
|
-
flowName,
|
|
1623
|
-
success: true,
|
|
1624
|
-
stats
|
|
1625
|
-
});
|
|
2420
|
+
results.push({ flowName, success: true, stats });
|
|
1626
2421
|
if (!options.json && !options.all && options.stats && stats) {
|
|
1627
2422
|
displayStats(stats, logger2);
|
|
1628
2423
|
}
|
|
1629
|
-
if (
|
|
1630
|
-
const
|
|
1631
|
-
|
|
1632
|
-
|
|
2424
|
+
if (writingToStdout && !options.json) {
|
|
2425
|
+
const bundleContent = await fs9.readFile(buildOptions.output);
|
|
2426
|
+
await writeResult(bundleContent, {});
|
|
2427
|
+
}
|
|
2428
|
+
if (options.dockerfile && options.output) {
|
|
2429
|
+
const platform2 = getPlatform2(flowConfig);
|
|
2430
|
+
if (platform2) {
|
|
2431
|
+
const outputDir = path10.dirname(buildOptions.output);
|
|
1633
2432
|
const customFile = typeof options.dockerfile === "string" ? options.dockerfile : void 0;
|
|
1634
|
-
await generateDockerfile(outputDir,
|
|
2433
|
+
await generateDockerfile(outputDir, platform2, logger2, customFile);
|
|
1635
2434
|
}
|
|
1636
2435
|
}
|
|
1637
2436
|
} catch (error) {
|
|
1638
2437
|
const errorMessage = getErrorMessage(error);
|
|
1639
|
-
results.push({
|
|
1640
|
-
flowName,
|
|
1641
|
-
success: false,
|
|
1642
|
-
error: errorMessage
|
|
1643
|
-
});
|
|
2438
|
+
results.push({ flowName, success: false, error: errorMessage });
|
|
1644
2439
|
if (!options.all) {
|
|
1645
2440
|
throw error;
|
|
1646
2441
|
}
|
|
@@ -1650,7 +2445,7 @@ async function bundleCommand(options) {
|
|
|
1650
2445
|
const successCount = results.filter((r) => r.success).length;
|
|
1651
2446
|
const failureCount = results.filter((r) => !r.success).length;
|
|
1652
2447
|
if (options.json) {
|
|
1653
|
-
const
|
|
2448
|
+
const jsonResult = failureCount === 0 ? createSuccessOutput(
|
|
1654
2449
|
{
|
|
1655
2450
|
flows: results,
|
|
1656
2451
|
summary: {
|
|
@@ -1664,7 +2459,9 @@ async function bundleCommand(options) {
|
|
|
1664
2459
|
`${failureCount} flow(s) failed to build`,
|
|
1665
2460
|
duration
|
|
1666
2461
|
);
|
|
1667
|
-
|
|
2462
|
+
await writeResult(JSON.stringify(jsonResult, null, 2) + "\n", {
|
|
2463
|
+
output: options.output
|
|
2464
|
+
});
|
|
1668
2465
|
} else {
|
|
1669
2466
|
if (options.all) {
|
|
1670
2467
|
logger2.log(
|
|
@@ -1684,8 +2481,10 @@ Build Summary: ${successCount}/${results.length} succeeded`
|
|
|
1684
2481
|
const duration = timer.getElapsed() / 1e3;
|
|
1685
2482
|
const errorMessage = getErrorMessage(error);
|
|
1686
2483
|
if (options.json) {
|
|
1687
|
-
const
|
|
1688
|
-
|
|
2484
|
+
const jsonError = createErrorOutput(errorMessage, duration);
|
|
2485
|
+
await writeResult(JSON.stringify(jsonError, null, 2) + "\n", {
|
|
2486
|
+
output: options.output
|
|
2487
|
+
});
|
|
1689
2488
|
} else {
|
|
1690
2489
|
logger2.error(`Error: ${errorMessage}`);
|
|
1691
2490
|
}
|
|
@@ -1694,7 +2493,7 @@ Build Summary: ${successCount}/${results.length} succeeded`
|
|
|
1694
2493
|
}
|
|
1695
2494
|
async function bundle(configOrPath, options = {}) {
|
|
1696
2495
|
let rawConfig;
|
|
1697
|
-
let configPath =
|
|
2496
|
+
let configPath = path10.resolve(process.cwd(), "walkeros.config.json");
|
|
1698
2497
|
if (typeof configOrPath === "string") {
|
|
1699
2498
|
configPath = resolveAsset(configOrPath, "config");
|
|
1700
2499
|
rawConfig = await loadJsonConfig(configPath);
|
|
@@ -1717,14 +2516,14 @@ async function bundle(configOrPath, options = {}) {
|
|
|
1717
2516
|
options.stats ?? false
|
|
1718
2517
|
);
|
|
1719
2518
|
}
|
|
1720
|
-
async function generateDockerfile(outputDir,
|
|
1721
|
-
const destPath =
|
|
1722
|
-
if (customFile && await
|
|
1723
|
-
await
|
|
2519
|
+
async function generateDockerfile(outputDir, platform2, logger2, customFile) {
|
|
2520
|
+
const destPath = path10.join(outputDir, "Dockerfile");
|
|
2521
|
+
if (customFile && await fs9.pathExists(customFile)) {
|
|
2522
|
+
await fs9.copy(customFile, destPath);
|
|
1724
2523
|
logger2.log(`Dockerfile: ${destPath} (copied from ${customFile})`);
|
|
1725
2524
|
return;
|
|
1726
2525
|
}
|
|
1727
|
-
const isWeb =
|
|
2526
|
+
const isWeb = platform2 === "web";
|
|
1728
2527
|
const bundleFile = isWeb ? "walker.js" : "bundle.mjs";
|
|
1729
2528
|
const mode = isWeb ? "serve" : "collect";
|
|
1730
2529
|
const dockerfile = `# Generated by walkeros CLI
|
|
@@ -1737,13 +2536,13 @@ ENV BUNDLE=/app/flow/${bundleFile}
|
|
|
1737
2536
|
|
|
1738
2537
|
EXPOSE 8080
|
|
1739
2538
|
`;
|
|
1740
|
-
await
|
|
2539
|
+
await fs9.writeFile(destPath, dockerfile);
|
|
1741
2540
|
logger2.log(`Dockerfile: ${destPath}`);
|
|
1742
2541
|
}
|
|
1743
2542
|
|
|
1744
2543
|
// src/commands/simulate/simulator.ts
|
|
1745
|
-
import
|
|
1746
|
-
import
|
|
2544
|
+
import path11 from "path";
|
|
2545
|
+
import fs11 from "fs-extra";
|
|
1747
2546
|
import { getPlatform as getPlatform3 } from "@walkeros/core";
|
|
1748
2547
|
|
|
1749
2548
|
// src/commands/simulate/tracker.ts
|
|
@@ -1780,9 +2579,9 @@ var CallTracker = class {
|
|
|
1780
2579
|
}
|
|
1781
2580
|
for (const fullPath of paths) {
|
|
1782
2581
|
const [destKey, ...pathParts] = fullPath.split(":");
|
|
1783
|
-
const
|
|
1784
|
-
if (!
|
|
1785
|
-
const cleanPath =
|
|
2582
|
+
const path16 = pathParts.join(":");
|
|
2583
|
+
if (!path16) continue;
|
|
2584
|
+
const cleanPath = path16.replace(/^call:/, "");
|
|
1786
2585
|
const parts = cleanPath.split(".");
|
|
1787
2586
|
let current = wrapped;
|
|
1788
2587
|
let source = env;
|
|
@@ -1826,7 +2625,7 @@ var CallTracker = class {
|
|
|
1826
2625
|
|
|
1827
2626
|
// src/commands/simulate/jsdom-executor.ts
|
|
1828
2627
|
import { JSDOM, VirtualConsole } from "jsdom";
|
|
1829
|
-
import
|
|
2628
|
+
import fs10 from "fs-extra";
|
|
1830
2629
|
function buildSandboxFromEnvs(envs, destinations, tracker) {
|
|
1831
2630
|
const baseBrowserMocks = {
|
|
1832
2631
|
Image: class MockImage {
|
|
@@ -1895,7 +2694,7 @@ async function executeInJSDOM(bundlePath, destinations, event, tracker, envs, ti
|
|
|
1895
2694
|
const sandbox = buildSandboxFromEnvs(envs, destinations, tracker);
|
|
1896
2695
|
Object.assign(window, sandbox.window);
|
|
1897
2696
|
Object.assign(window.document, sandbox.document);
|
|
1898
|
-
const bundleCode = await
|
|
2697
|
+
const bundleCode = await fs10.readFile(bundlePath, "utf8");
|
|
1899
2698
|
try {
|
|
1900
2699
|
window.eval(bundleCode);
|
|
1901
2700
|
} catch (error) {
|
|
@@ -2089,7 +2888,7 @@ async function executeSimulation(event, inputPath, platformOverride, options = {
|
|
|
2089
2888
|
const tempDir = getTmpPath();
|
|
2090
2889
|
const collectorLoggerConfig = options.logger ? createCollectorLoggerConfig(options.logger, options.verbose) : void 0;
|
|
2091
2890
|
try {
|
|
2092
|
-
await
|
|
2891
|
+
await fs11.ensureDir(tempDir);
|
|
2093
2892
|
const detected = await detectInput(inputPath, platformOverride);
|
|
2094
2893
|
if (!isObject(event) || !("name" in event) || typeof event.name !== "string") {
|
|
2095
2894
|
throw new Error(
|
|
@@ -2126,7 +2925,7 @@ async function executeSimulation(event, inputPath, platformOverride, options = {
|
|
|
2126
2925
|
};
|
|
2127
2926
|
} finally {
|
|
2128
2927
|
if (tempDir) {
|
|
2129
|
-
await
|
|
2928
|
+
await fs11.remove(tempDir).catch(() => {
|
|
2130
2929
|
});
|
|
2131
2930
|
}
|
|
2132
2931
|
}
|
|
@@ -2135,11 +2934,11 @@ async function executeConfigSimulation(_content, configPath, typedEvent, tempDir
|
|
|
2135
2934
|
const { flowConfig, buildOptions } = await loadFlowConfig(configPath, {
|
|
2136
2935
|
flowName
|
|
2137
2936
|
});
|
|
2138
|
-
const
|
|
2937
|
+
const platform2 = getPlatform3(flowConfig);
|
|
2139
2938
|
const tracker = new CallTracker();
|
|
2140
|
-
const tempOutput =
|
|
2939
|
+
const tempOutput = path11.join(
|
|
2141
2940
|
tempDir,
|
|
2142
|
-
`simulation-bundle-${generateId()}.${
|
|
2941
|
+
`simulation-bundle-${generateId()}.${platform2 === "web" ? "js" : "mjs"}`
|
|
2143
2942
|
);
|
|
2144
2943
|
const destinations = flowConfig.destinations;
|
|
2145
2944
|
const simulationBuildOptions = {
|
|
@@ -2147,7 +2946,7 @@ async function executeConfigSimulation(_content, configPath, typedEvent, tempDir
|
|
|
2147
2946
|
code: buildOptions.code || "",
|
|
2148
2947
|
output: tempOutput,
|
|
2149
2948
|
tempDir,
|
|
2150
|
-
...
|
|
2949
|
+
...platform2 === "web" ? {
|
|
2151
2950
|
format: "iife",
|
|
2152
2951
|
platform: "browser",
|
|
2153
2952
|
windowCollector: "collector",
|
|
@@ -2165,7 +2964,7 @@ async function executeConfigSimulation(_content, configPath, typedEvent, tempDir
|
|
|
2165
2964
|
);
|
|
2166
2965
|
const envs = await loadDestinationEnvs(destinations || {});
|
|
2167
2966
|
let result;
|
|
2168
|
-
if (
|
|
2967
|
+
if (platform2 === "web") {
|
|
2169
2968
|
result = await executeInJSDOM(
|
|
2170
2969
|
tempOutput,
|
|
2171
2970
|
destinations || {},
|
|
@@ -2194,15 +2993,15 @@ async function executeConfigSimulation(_content, configPath, typedEvent, tempDir
|
|
|
2194
2993
|
logs: []
|
|
2195
2994
|
};
|
|
2196
2995
|
}
|
|
2197
|
-
async function executeBundleSimulation(bundleContent,
|
|
2198
|
-
const tempOutput =
|
|
2996
|
+
async function executeBundleSimulation(bundleContent, platform2, typedEvent, tempDir, startTime, loggerConfig2) {
|
|
2997
|
+
const tempOutput = path11.join(
|
|
2199
2998
|
tempDir,
|
|
2200
|
-
`bundle-${generateId()}.${
|
|
2999
|
+
`bundle-${generateId()}.${platform2 === "server" ? "mjs" : "js"}`
|
|
2201
3000
|
);
|
|
2202
|
-
await
|
|
3001
|
+
await fs11.writeFile(tempOutput, bundleContent, "utf8");
|
|
2203
3002
|
const tracker = new CallTracker();
|
|
2204
3003
|
let result;
|
|
2205
|
-
if (
|
|
3004
|
+
if (platform2 === "web") {
|
|
2206
3005
|
result = await executeInJSDOM(
|
|
2207
3006
|
tempOutput,
|
|
2208
3007
|
{},
|
|
@@ -2234,13 +3033,25 @@ async function executeBundleSimulation(bundleContent, platform, typedEvent, temp
|
|
|
2234
3033
|
|
|
2235
3034
|
// src/commands/simulate/index.ts
|
|
2236
3035
|
async function simulateCommand(options) {
|
|
2237
|
-
const logger2 = createCommandLogger(options);
|
|
3036
|
+
const logger2 = createCommandLogger({ ...options, stderr: true });
|
|
2238
3037
|
const startTime = Date.now();
|
|
2239
3038
|
try {
|
|
3039
|
+
let config;
|
|
3040
|
+
if (isStdinPiped() && !options.config) {
|
|
3041
|
+
const stdinContent = await readStdin();
|
|
3042
|
+
const fs20 = await import("fs-extra");
|
|
3043
|
+
const path16 = await import("path");
|
|
3044
|
+
const tmpPath = path16.default.resolve(".tmp", "stdin-simulate.json");
|
|
3045
|
+
await fs20.default.ensureDir(path16.default.dirname(tmpPath));
|
|
3046
|
+
await fs20.default.writeFile(tmpPath, stdinContent, "utf-8");
|
|
3047
|
+
config = tmpPath;
|
|
3048
|
+
} else {
|
|
3049
|
+
config = options.config || "bundle.config.json";
|
|
3050
|
+
}
|
|
2240
3051
|
const event = await loadJsonFromSource(options.event, {
|
|
2241
3052
|
name: "event"
|
|
2242
3053
|
});
|
|
2243
|
-
const result = await simulateCore(
|
|
3054
|
+
const result = await simulateCore(config, event, {
|
|
2244
3055
|
flow: options.flow,
|
|
2245
3056
|
json: options.json,
|
|
2246
3057
|
verbose: options.verbose,
|
|
@@ -2250,23 +3061,24 @@ async function simulateCommand(options) {
|
|
|
2250
3061
|
...result,
|
|
2251
3062
|
duration: (Date.now() - startTime) / 1e3
|
|
2252
3063
|
};
|
|
2253
|
-
const
|
|
3064
|
+
const formatted = formatSimulationResult(resultWithDuration, {
|
|
2254
3065
|
json: options.json
|
|
2255
3066
|
});
|
|
2256
|
-
|
|
2257
|
-
console.log(output);
|
|
2258
|
-
} else {
|
|
2259
|
-
logger2.log(output);
|
|
2260
|
-
}
|
|
3067
|
+
await writeResult(formatted + "\n", { output: options.output });
|
|
2261
3068
|
process.exit(result.success ? 0 : 1);
|
|
2262
3069
|
} catch (error) {
|
|
2263
3070
|
const errorMessage = getErrorMessage(error);
|
|
2264
3071
|
if (options.json) {
|
|
2265
|
-
|
|
2266
|
-
|
|
2267
|
-
|
|
2268
|
-
|
|
2269
|
-
|
|
3072
|
+
const errorOutput = JSON.stringify(
|
|
3073
|
+
{
|
|
3074
|
+
success: false,
|
|
3075
|
+
error: errorMessage,
|
|
3076
|
+
duration: (Date.now() - startTime) / 1e3
|
|
3077
|
+
},
|
|
3078
|
+
null,
|
|
3079
|
+
2
|
|
3080
|
+
);
|
|
3081
|
+
await writeResult(errorOutput + "\n", { output: options.output });
|
|
2270
3082
|
} else {
|
|
2271
3083
|
logger2.error(`Error: ${errorMessage}`);
|
|
2272
3084
|
}
|
|
@@ -2281,28 +3093,33 @@ async function simulate(configOrPath, event, options = {}) {
|
|
|
2281
3093
|
}
|
|
2282
3094
|
return await simulateCore(configOrPath, event, {
|
|
2283
3095
|
json: options.json ?? false,
|
|
2284
|
-
verbose: options.verbose ?? false
|
|
3096
|
+
verbose: options.verbose ?? false,
|
|
3097
|
+
flow: options.flow,
|
|
3098
|
+
platform: options.platform
|
|
2285
3099
|
});
|
|
2286
3100
|
}
|
|
2287
3101
|
|
|
2288
3102
|
// src/commands/push/index.ts
|
|
2289
|
-
import
|
|
3103
|
+
import path12 from "path";
|
|
2290
3104
|
import { JSDOM as JSDOM2, VirtualConsole as VirtualConsole2 } from "jsdom";
|
|
2291
|
-
import
|
|
3105
|
+
import fs12 from "fs-extra";
|
|
2292
3106
|
import {
|
|
2293
3107
|
getPlatform as getPlatform4
|
|
2294
3108
|
} from "@walkeros/core";
|
|
2295
3109
|
import { schemas as schemas2 } from "@walkeros/core/dev";
|
|
2296
|
-
async function
|
|
2297
|
-
const logger2 = createCommandLogger(
|
|
3110
|
+
async function pushCore(inputPath, event, options = {}) {
|
|
3111
|
+
const logger2 = createCommandLogger({
|
|
3112
|
+
silent: options.silent,
|
|
3113
|
+
verbose: options.verbose
|
|
3114
|
+
});
|
|
2298
3115
|
const startTime = Date.now();
|
|
2299
3116
|
let tempDir;
|
|
2300
3117
|
try {
|
|
2301
|
-
|
|
2302
|
-
|
|
2303
|
-
name: "event"
|
|
2304
|
-
}
|
|
2305
|
-
const eventResult = schemas2.PartialEventSchema.safeParse(
|
|
3118
|
+
let loadedEvent = event;
|
|
3119
|
+
if (typeof event === "string") {
|
|
3120
|
+
loadedEvent = await loadJsonFromSource(event, { name: "event" });
|
|
3121
|
+
}
|
|
3122
|
+
const eventResult = schemas2.PartialEventSchema.safeParse(loadedEvent);
|
|
2306
3123
|
if (!eventResult.success) {
|
|
2307
3124
|
const errors = eventResult.error.issues.map((issue) => `${String(issue.path.join("."))}: ${issue.message}`).join(", ");
|
|
2308
3125
|
throw new Error(`Invalid event: ${errors}`);
|
|
@@ -2321,11 +3138,18 @@ async function pushCommand(options) {
|
|
|
2321
3138
|
);
|
|
2322
3139
|
}
|
|
2323
3140
|
logger2.debug("Detecting input type");
|
|
2324
|
-
const detected = await detectInput(
|
|
3141
|
+
const detected = await detectInput(
|
|
3142
|
+
inputPath,
|
|
3143
|
+
options.platform
|
|
3144
|
+
);
|
|
2325
3145
|
let result;
|
|
2326
3146
|
if (detected.type === "config") {
|
|
2327
3147
|
result = await executeConfigPush(
|
|
2328
|
-
|
|
3148
|
+
{
|
|
3149
|
+
config: inputPath,
|
|
3150
|
+
flow: options.flow,
|
|
3151
|
+
verbose: options.verbose
|
|
3152
|
+
},
|
|
2329
3153
|
validatedEvent,
|
|
2330
3154
|
logger2,
|
|
2331
3155
|
(dir) => {
|
|
@@ -2348,91 +3172,140 @@ async function pushCommand(options) {
|
|
|
2348
3172
|
{ logger: collectorLoggerConfig }
|
|
2349
3173
|
);
|
|
2350
3174
|
}
|
|
3175
|
+
return result;
|
|
3176
|
+
} catch (error) {
|
|
3177
|
+
return {
|
|
3178
|
+
success: false,
|
|
3179
|
+
duration: Date.now() - startTime,
|
|
3180
|
+
error: getErrorMessage(error)
|
|
3181
|
+
};
|
|
3182
|
+
} finally {
|
|
3183
|
+
if (tempDir) {
|
|
3184
|
+
await fs12.remove(tempDir).catch(() => {
|
|
3185
|
+
});
|
|
3186
|
+
}
|
|
3187
|
+
}
|
|
3188
|
+
}
|
|
3189
|
+
async function pushCommand(options) {
|
|
3190
|
+
const logger2 = createCommandLogger({ ...options, stderr: true });
|
|
3191
|
+
const startTime = Date.now();
|
|
3192
|
+
try {
|
|
3193
|
+
let config;
|
|
3194
|
+
if (isStdinPiped() && !options.config) {
|
|
3195
|
+
const stdinContent = await readStdin();
|
|
3196
|
+
const tmpPath = path12.resolve(".tmp", "stdin-push.json");
|
|
3197
|
+
await fs12.ensureDir(path12.dirname(tmpPath));
|
|
3198
|
+
await fs12.writeFile(tmpPath, stdinContent, "utf-8");
|
|
3199
|
+
config = tmpPath;
|
|
3200
|
+
} else {
|
|
3201
|
+
config = options.config || "bundle.config.json";
|
|
3202
|
+
}
|
|
3203
|
+
const event = await loadJsonFromSource(options.event, { name: "event" });
|
|
3204
|
+
const result = await pushCore(config, event, {
|
|
3205
|
+
flow: options.flow,
|
|
3206
|
+
json: options.json,
|
|
3207
|
+
verbose: options.verbose,
|
|
3208
|
+
silent: options.silent,
|
|
3209
|
+
platform: options.platform
|
|
3210
|
+
});
|
|
2351
3211
|
const duration = Date.now() - startTime;
|
|
3212
|
+
let output;
|
|
2352
3213
|
if (options.json) {
|
|
2353
|
-
|
|
2354
|
-
|
|
2355
|
-
|
|
2356
|
-
|
|
2357
|
-
|
|
3214
|
+
output = JSON.stringify(
|
|
3215
|
+
{
|
|
3216
|
+
success: result.success,
|
|
3217
|
+
event: result.elbResult,
|
|
3218
|
+
duration
|
|
3219
|
+
},
|
|
3220
|
+
null,
|
|
3221
|
+
2
|
|
3222
|
+
);
|
|
2358
3223
|
} else {
|
|
3224
|
+
const lines = [];
|
|
2359
3225
|
if (result.success) {
|
|
2360
|
-
|
|
3226
|
+
lines.push("Event pushed successfully");
|
|
2361
3227
|
if (result.elbResult && typeof result.elbResult === "object") {
|
|
2362
3228
|
const pushResult = result.elbResult;
|
|
2363
|
-
if ("id" in pushResult && pushResult.id)
|
|
2364
|
-
|
|
2365
|
-
|
|
2366
|
-
|
|
2367
|
-
|
|
2368
|
-
|
|
2369
|
-
if ("action" in pushResult && pushResult.action) {
|
|
2370
|
-
logger2.log(` Action: ${pushResult.action}`);
|
|
2371
|
-
}
|
|
3229
|
+
if ("id" in pushResult && pushResult.id)
|
|
3230
|
+
lines.push(` Event ID: ${pushResult.id}`);
|
|
3231
|
+
if ("entity" in pushResult && pushResult.entity)
|
|
3232
|
+
lines.push(` Entity: ${pushResult.entity}`);
|
|
3233
|
+
if ("action" in pushResult && pushResult.action)
|
|
3234
|
+
lines.push(` Action: ${pushResult.action}`);
|
|
2372
3235
|
}
|
|
2373
|
-
|
|
3236
|
+
lines.push(` Duration: ${duration}ms`);
|
|
2374
3237
|
} else {
|
|
2375
|
-
|
|
2376
|
-
process.exit(1);
|
|
3238
|
+
lines.push(`Error: ${result.error}`);
|
|
2377
3239
|
}
|
|
3240
|
+
output = lines.join("\n");
|
|
2378
3241
|
}
|
|
2379
|
-
|
|
3242
|
+
await writeResult(output + "\n", { output: options.output });
|
|
3243
|
+
process.exit(result.success ? 0 : 1);
|
|
2380
3244
|
} catch (error) {
|
|
2381
3245
|
const duration = Date.now() - startTime;
|
|
2382
3246
|
const errorMessage = getErrorMessage(error);
|
|
2383
3247
|
if (options.json) {
|
|
2384
|
-
|
|
2385
|
-
success: false,
|
|
2386
|
-
|
|
2387
|
-
|
|
2388
|
-
|
|
3248
|
+
const errorOutput = JSON.stringify(
|
|
3249
|
+
{ success: false, error: errorMessage, duration },
|
|
3250
|
+
null,
|
|
3251
|
+
2
|
|
3252
|
+
);
|
|
3253
|
+
await writeResult(errorOutput + "\n", { output: options.output });
|
|
2389
3254
|
} else {
|
|
2390
3255
|
logger2.error(`Error: ${errorMessage}`);
|
|
2391
3256
|
}
|
|
2392
3257
|
process.exit(1);
|
|
2393
|
-
} finally {
|
|
2394
|
-
if (tempDir) {
|
|
2395
|
-
await fs11.remove(tempDir).catch(() => {
|
|
2396
|
-
});
|
|
2397
|
-
}
|
|
2398
3258
|
}
|
|
2399
3259
|
}
|
|
3260
|
+
async function push(configOrPath, event, options = {}) {
|
|
3261
|
+
if (typeof configOrPath !== "string") {
|
|
3262
|
+
throw new Error(
|
|
3263
|
+
"push() currently only supports config file paths. Config object support will be added in a future version. Please provide a path to a configuration file."
|
|
3264
|
+
);
|
|
3265
|
+
}
|
|
3266
|
+
return await pushCore(configOrPath, event, {
|
|
3267
|
+
json: options.json ?? false,
|
|
3268
|
+
verbose: options.verbose ?? false,
|
|
3269
|
+
flow: options.flow,
|
|
3270
|
+
platform: options.platform
|
|
3271
|
+
});
|
|
3272
|
+
}
|
|
2400
3273
|
async function executeConfigPush(options, validatedEvent, logger2, setTempDir) {
|
|
2401
3274
|
logger2.debug("Loading flow configuration");
|
|
2402
3275
|
const { flowConfig, buildOptions } = await loadFlowConfig(options.config, {
|
|
2403
3276
|
flowName: options.flow,
|
|
2404
3277
|
logger: logger2
|
|
2405
3278
|
});
|
|
2406
|
-
const
|
|
3279
|
+
const platform2 = getPlatform4(flowConfig);
|
|
2407
3280
|
logger2.debug("Bundling flow configuration");
|
|
2408
3281
|
const configDir = buildOptions.configDir || process.cwd();
|
|
2409
|
-
const tempDir =
|
|
3282
|
+
const tempDir = path12.join(
|
|
2410
3283
|
configDir,
|
|
2411
3284
|
".tmp",
|
|
2412
3285
|
`push-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`
|
|
2413
3286
|
);
|
|
2414
3287
|
setTempDir(tempDir);
|
|
2415
|
-
await
|
|
2416
|
-
const tempPath =
|
|
3288
|
+
await fs12.ensureDir(tempDir);
|
|
3289
|
+
const tempPath = path12.join(
|
|
2417
3290
|
tempDir,
|
|
2418
|
-
`bundle.${
|
|
3291
|
+
`bundle.${platform2 === "web" ? "js" : "mjs"}`
|
|
2419
3292
|
);
|
|
2420
3293
|
const pushBuildOptions = {
|
|
2421
3294
|
...buildOptions,
|
|
2422
3295
|
output: tempPath,
|
|
2423
|
-
format:
|
|
2424
|
-
platform:
|
|
2425
|
-
...
|
|
3296
|
+
format: platform2 === "web" ? "iife" : "esm",
|
|
3297
|
+
platform: platform2 === "web" ? "browser" : "node",
|
|
3298
|
+
...platform2 === "web" && {
|
|
2426
3299
|
windowCollector: "collector",
|
|
2427
3300
|
windowElb: "elb"
|
|
2428
3301
|
}
|
|
2429
3302
|
};
|
|
2430
3303
|
await bundleCore(flowConfig, pushBuildOptions, logger2, false);
|
|
2431
3304
|
logger2.debug(`Bundle created: ${tempPath}`);
|
|
2432
|
-
if (
|
|
3305
|
+
if (platform2 === "web") {
|
|
2433
3306
|
logger2.debug("Executing in web environment (JSDOM)");
|
|
2434
3307
|
return executeWebPush(tempPath, validatedEvent, logger2);
|
|
2435
|
-
} else if (
|
|
3308
|
+
} else if (platform2 === "server") {
|
|
2436
3309
|
logger2.debug("Executing in server environment (Node.js)");
|
|
2437
3310
|
const collectorLoggerConfig = createCollectorLoggerConfig(
|
|
2438
3311
|
logger2,
|
|
@@ -2442,24 +3315,24 @@ async function executeConfigPush(options, validatedEvent, logger2, setTempDir) {
|
|
|
2442
3315
|
logger: collectorLoggerConfig
|
|
2443
3316
|
});
|
|
2444
3317
|
} else {
|
|
2445
|
-
throw new Error(`Unsupported platform: ${
|
|
3318
|
+
throw new Error(`Unsupported platform: ${platform2}`);
|
|
2446
3319
|
}
|
|
2447
3320
|
}
|
|
2448
|
-
async function executeBundlePush(bundleContent,
|
|
2449
|
-
const tempDir =
|
|
3321
|
+
async function executeBundlePush(bundleContent, platform2, validatedEvent, logger2, setTempDir, context = {}) {
|
|
3322
|
+
const tempDir = path12.join(
|
|
2450
3323
|
process.cwd(),
|
|
2451
3324
|
".tmp",
|
|
2452
3325
|
`push-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`
|
|
2453
3326
|
);
|
|
2454
3327
|
setTempDir(tempDir);
|
|
2455
|
-
await
|
|
2456
|
-
const tempPath =
|
|
3328
|
+
await fs12.ensureDir(tempDir);
|
|
3329
|
+
const tempPath = path12.join(
|
|
2457
3330
|
tempDir,
|
|
2458
|
-
`bundle.${
|
|
3331
|
+
`bundle.${platform2 === "server" ? "mjs" : "js"}`
|
|
2459
3332
|
);
|
|
2460
|
-
await
|
|
3333
|
+
await fs12.writeFile(tempPath, bundleContent, "utf8");
|
|
2461
3334
|
logger2.debug(`Bundle written to: ${tempPath}`);
|
|
2462
|
-
if (
|
|
3335
|
+
if (platform2 === "web") {
|
|
2463
3336
|
logger2.debug("Executing in web environment (JSDOM)");
|
|
2464
3337
|
return executeWebPush(tempPath, validatedEvent, logger2);
|
|
2465
3338
|
} else {
|
|
@@ -2479,7 +3352,7 @@ async function executeWebPush(bundlePath, event, logger2) {
|
|
|
2479
3352
|
});
|
|
2480
3353
|
const { window } = dom;
|
|
2481
3354
|
logger2.debug("Loading bundle...");
|
|
2482
|
-
const bundleCode = await
|
|
3355
|
+
const bundleCode = await fs12.readFile(bundlePath, "utf8");
|
|
2483
3356
|
window.eval(bundleCode);
|
|
2484
3357
|
logger2.debug("Waiting for collector...");
|
|
2485
3358
|
await waitForWindowProperty2(
|
|
@@ -2571,10 +3444,10 @@ function waitForWindowProperty2(window, prop, timeout = 5e3) {
|
|
|
2571
3444
|
}
|
|
2572
3445
|
|
|
2573
3446
|
// src/commands/run/index.ts
|
|
2574
|
-
import
|
|
3447
|
+
import path14 from "path";
|
|
2575
3448
|
|
|
2576
3449
|
// src/commands/run/validators.ts
|
|
2577
|
-
import { existsSync as
|
|
3450
|
+
import { existsSync as existsSync3 } from "fs";
|
|
2578
3451
|
|
|
2579
3452
|
// src/schemas/primitives.ts
|
|
2580
3453
|
import { z } from "@walkeros/core/dev";
|
|
@@ -2591,6 +3464,69 @@ var RunOptionsSchema = z2.object({
|
|
|
2591
3464
|
flowName: z2.string().optional().describe("Specific flow name to run")
|
|
2592
3465
|
});
|
|
2593
3466
|
|
|
3467
|
+
// src/schemas/validate.ts
|
|
3468
|
+
import { z as z3 } from "@walkeros/core/dev";
|
|
3469
|
+
var ValidationTypeSchema = z3.enum(["event", "flow", "mapping"]).describe("Type of validation to perform");
|
|
3470
|
+
var ValidateOptionsSchema = z3.object({
|
|
3471
|
+
flow: z3.string().optional().describe("Flow name for multi-flow configs")
|
|
3472
|
+
});
|
|
3473
|
+
var ValidateInputShape = {
|
|
3474
|
+
type: ValidationTypeSchema,
|
|
3475
|
+
input: z3.string().min(1).describe("JSON string, file path, or URL to validate"),
|
|
3476
|
+
flow: z3.string().optional().describe("Flow name for multi-flow configs")
|
|
3477
|
+
};
|
|
3478
|
+
var ValidateInputSchema = z3.object(ValidateInputShape);
|
|
3479
|
+
|
|
3480
|
+
// src/schemas/bundle.ts
|
|
3481
|
+
import { z as z4 } from "@walkeros/core/dev";
|
|
3482
|
+
var BundleOptionsSchema = z4.object({
|
|
3483
|
+
silent: z4.boolean().optional().describe("Suppress all output"),
|
|
3484
|
+
verbose: z4.boolean().optional().describe("Enable verbose logging"),
|
|
3485
|
+
stats: z4.boolean().optional().default(true).describe("Return bundle statistics"),
|
|
3486
|
+
cache: z4.boolean().optional().default(true).describe("Enable package caching"),
|
|
3487
|
+
flowName: z4.string().optional().describe("Flow name for multi-flow configs")
|
|
3488
|
+
});
|
|
3489
|
+
var BundleInputShape = {
|
|
3490
|
+
configPath: FilePathSchema.describe(
|
|
3491
|
+
"Path to flow configuration file (JSON or JavaScript)"
|
|
3492
|
+
),
|
|
3493
|
+
flow: z4.string().optional().describe("Flow name for multi-flow configs"),
|
|
3494
|
+
stats: z4.boolean().optional().default(true).describe("Return bundle statistics"),
|
|
3495
|
+
output: z4.string().optional().describe("Output file path (defaults to config-defined)")
|
|
3496
|
+
};
|
|
3497
|
+
var BundleInputSchema = z4.object(BundleInputShape);
|
|
3498
|
+
|
|
3499
|
+
// src/schemas/simulate.ts
|
|
3500
|
+
import { z as z5 } from "@walkeros/core/dev";
|
|
3501
|
+
var PlatformSchema = z5.enum(["web", "server"]).describe("Platform type for event processing");
|
|
3502
|
+
var SimulateOptionsSchema = z5.object({
|
|
3503
|
+
silent: z5.boolean().optional().describe("Suppress all output"),
|
|
3504
|
+
verbose: z5.boolean().optional().describe("Enable verbose logging"),
|
|
3505
|
+
json: z5.boolean().optional().describe("Format output as JSON")
|
|
3506
|
+
});
|
|
3507
|
+
var SimulateInputShape = {
|
|
3508
|
+
configPath: FilePathSchema.describe("Path to flow configuration file"),
|
|
3509
|
+
event: z5.string().min(1).describe("Event as JSON string, file path, or URL"),
|
|
3510
|
+
flow: z5.string().optional().describe("Flow name for multi-flow configs"),
|
|
3511
|
+
platform: PlatformSchema.optional().describe("Override platform detection")
|
|
3512
|
+
};
|
|
3513
|
+
var SimulateInputSchema = z5.object(SimulateInputShape);
|
|
3514
|
+
|
|
3515
|
+
// src/schemas/push.ts
|
|
3516
|
+
import { z as z6 } from "@walkeros/core/dev";
|
|
3517
|
+
var PushOptionsSchema = z6.object({
|
|
3518
|
+
silent: z6.boolean().optional().describe("Suppress all output"),
|
|
3519
|
+
verbose: z6.boolean().optional().describe("Enable verbose logging"),
|
|
3520
|
+
json: z6.boolean().optional().describe("Format output as JSON")
|
|
3521
|
+
});
|
|
3522
|
+
var PushInputShape = {
|
|
3523
|
+
configPath: FilePathSchema.describe("Path to flow configuration file"),
|
|
3524
|
+
event: z6.string().min(1).describe("Event as JSON string, file path, or URL"),
|
|
3525
|
+
flow: z6.string().optional().describe("Flow name for multi-flow configs"),
|
|
3526
|
+
platform: PlatformSchema.optional().describe("Override platform detection")
|
|
3527
|
+
};
|
|
3528
|
+
var PushInputSchema = z6.object(PushInputShape);
|
|
3529
|
+
|
|
2594
3530
|
// src/commands/run/validators.ts
|
|
2595
3531
|
function validateMode(mode) {
|
|
2596
3532
|
const result = RunModeSchema.safeParse(mode);
|
|
@@ -2604,7 +3540,7 @@ function validateMode(mode) {
|
|
|
2604
3540
|
}
|
|
2605
3541
|
function validateFlowFile(filePath) {
|
|
2606
3542
|
const absolutePath = resolveAsset(filePath, "bundle");
|
|
2607
|
-
if (!
|
|
3543
|
+
if (!existsSync3(absolutePath)) {
|
|
2608
3544
|
throw new Error(
|
|
2609
3545
|
`Flow file not found: ${filePath}
|
|
2610
3546
|
Resolved path: ${absolutePath}
|
|
@@ -2625,17 +3561,17 @@ function validatePort(port) {
|
|
|
2625
3561
|
}
|
|
2626
3562
|
|
|
2627
3563
|
// src/commands/run/utils.ts
|
|
2628
|
-
import
|
|
2629
|
-
import
|
|
3564
|
+
import path13 from "path";
|
|
3565
|
+
import fs13 from "fs-extra";
|
|
2630
3566
|
async function prepareBundleForRun(configPath, options) {
|
|
2631
|
-
const configDir =
|
|
2632
|
-
const tempDir =
|
|
3567
|
+
const configDir = path13.dirname(path13.resolve(configPath));
|
|
3568
|
+
const tempDir = path13.join(
|
|
2633
3569
|
configDir,
|
|
2634
3570
|
".tmp",
|
|
2635
3571
|
`run-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`
|
|
2636
3572
|
);
|
|
2637
|
-
await
|
|
2638
|
-
const tempPath =
|
|
3573
|
+
await fs13.ensureDir(tempDir);
|
|
3574
|
+
const tempPath = path13.join(tempDir, "bundle.mjs");
|
|
2639
3575
|
await bundle(configPath, {
|
|
2640
3576
|
cache: true,
|
|
2641
3577
|
verbose: options.verbose,
|
|
@@ -2826,8 +3762,8 @@ async function runCommand(mode, options) {
|
|
|
2826
3762
|
let flowPath = null;
|
|
2827
3763
|
if (mode === "collect") {
|
|
2828
3764
|
if (isPreBuilt) {
|
|
2829
|
-
flowPath =
|
|
2830
|
-
logger2.debug(`Using pre-built flow: ${
|
|
3765
|
+
flowPath = path14.resolve(configPath);
|
|
3766
|
+
logger2.debug(`Using pre-built flow: ${path14.basename(flowPath)}`);
|
|
2831
3767
|
} else {
|
|
2832
3768
|
logger2.debug("Building flow bundle");
|
|
2833
3769
|
flowPath = await prepareBundleForRun(configPath, {
|
|
@@ -2877,7 +3813,7 @@ async function run(mode, options) {
|
|
|
2877
3813
|
const isPreBuilt = isPreBuiltConfig(flowFile);
|
|
2878
3814
|
let flowPath;
|
|
2879
3815
|
if (isPreBuilt) {
|
|
2880
|
-
flowPath =
|
|
3816
|
+
flowPath = path14.resolve(flowFile);
|
|
2881
3817
|
} else {
|
|
2882
3818
|
flowPath = await prepareBundleForRun(flowFile, {
|
|
2883
3819
|
verbose: options.verbose,
|
|
@@ -2906,7 +3842,7 @@ async function run(mode, options) {
|
|
|
2906
3842
|
}
|
|
2907
3843
|
|
|
2908
3844
|
// src/commands/validate/index.ts
|
|
2909
|
-
import
|
|
3845
|
+
import chalk3 from "chalk";
|
|
2910
3846
|
|
|
2911
3847
|
// src/commands/validate/validators/event.ts
|
|
2912
3848
|
import { schemas as schemas3 } from "@walkeros/core/dev";
|
|
@@ -2951,10 +3887,10 @@ function validateEvent(input) {
|
|
|
2951
3887
|
const zodResult = PartialEventSchema.safeParse(input);
|
|
2952
3888
|
if (!zodResult.success) {
|
|
2953
3889
|
for (const issue of zodResult.error.issues) {
|
|
2954
|
-
const
|
|
2955
|
-
if (
|
|
3890
|
+
const path16 = issue.path.join(".");
|
|
3891
|
+
if (path16 === "name") continue;
|
|
2956
3892
|
errors.push({
|
|
2957
|
-
path:
|
|
3893
|
+
path: path16 || "root",
|
|
2958
3894
|
message: issue.message,
|
|
2959
3895
|
code: "SCHEMA_VALIDATION"
|
|
2960
3896
|
});
|
|
@@ -2990,9 +3926,9 @@ function validateFlow(input, options = {}) {
|
|
|
2990
3926
|
const zodResult = SetupSchema.safeParse(input);
|
|
2991
3927
|
if (!zodResult.success) {
|
|
2992
3928
|
for (const issue of zodResult.error.issues) {
|
|
2993
|
-
const
|
|
3929
|
+
const path16 = issue.path.join(".");
|
|
2994
3930
|
errors.push({
|
|
2995
|
-
path:
|
|
3931
|
+
path: path16 || "root",
|
|
2996
3932
|
message: issue.message,
|
|
2997
3933
|
code: "SCHEMA_VALIDATION"
|
|
2998
3934
|
});
|
|
@@ -3127,16 +4063,16 @@ function formatResult(result, options) {
|
|
|
3127
4063
|
}
|
|
3128
4064
|
lines.push("Validation Results:");
|
|
3129
4065
|
for (const error of result.errors) {
|
|
3130
|
-
lines.push(
|
|
4066
|
+
lines.push(chalk3.red(` \u2717 ${error.path}: ${error.message}`));
|
|
3131
4067
|
}
|
|
3132
4068
|
for (const warning of result.warnings) {
|
|
3133
|
-
lines.push(
|
|
4069
|
+
lines.push(chalk3.yellow(` \u26A0 ${warning.path}: ${warning.message}`));
|
|
3134
4070
|
if (warning.suggestion) {
|
|
3135
|
-
lines.push(
|
|
4071
|
+
lines.push(chalk3.gray(` \u2192 ${warning.suggestion}`));
|
|
3136
4072
|
}
|
|
3137
4073
|
}
|
|
3138
4074
|
if (result.valid) {
|
|
3139
|
-
lines.push(
|
|
4075
|
+
lines.push(chalk3.green(` \u2713 All checks passed`));
|
|
3140
4076
|
}
|
|
3141
4077
|
lines.push("");
|
|
3142
4078
|
lines.push(
|
|
@@ -3145,24 +4081,30 @@ function formatResult(result, options) {
|
|
|
3145
4081
|
return lines.join("\n");
|
|
3146
4082
|
}
|
|
3147
4083
|
async function validateCommand(options) {
|
|
3148
|
-
const logger2 = createCommandLogger(options);
|
|
4084
|
+
const logger2 = createCommandLogger({ ...options, stderr: true });
|
|
3149
4085
|
try {
|
|
3150
|
-
|
|
3151
|
-
|
|
3152
|
-
|
|
3153
|
-
|
|
4086
|
+
let input;
|
|
4087
|
+
if (isStdinPiped() && !options.input) {
|
|
4088
|
+
const stdinContent = await readStdin();
|
|
4089
|
+
try {
|
|
4090
|
+
input = JSON.parse(stdinContent);
|
|
4091
|
+
} catch {
|
|
4092
|
+
throw new Error("Invalid JSON received on stdin");
|
|
4093
|
+
}
|
|
4094
|
+
} else {
|
|
4095
|
+
input = await loadJsonFromSource(options.input, {
|
|
4096
|
+
name: options.type,
|
|
4097
|
+
required: true
|
|
4098
|
+
});
|
|
4099
|
+
}
|
|
3154
4100
|
const result = await validate(options.type, input, {
|
|
3155
4101
|
flow: options.flow
|
|
3156
4102
|
});
|
|
3157
|
-
const
|
|
4103
|
+
const formatted = formatResult(result, {
|
|
3158
4104
|
json: options.json,
|
|
3159
4105
|
verbose: options.verbose
|
|
3160
4106
|
});
|
|
3161
|
-
|
|
3162
|
-
console.log(output);
|
|
3163
|
-
} else {
|
|
3164
|
-
logger2.log(output);
|
|
3165
|
-
}
|
|
4107
|
+
await writeResult(formatted + "\n", { output: options.output });
|
|
3166
4108
|
if (!result.valid) {
|
|
3167
4109
|
process.exit(1);
|
|
3168
4110
|
}
|
|
@@ -3173,13 +4115,20 @@ async function validateCommand(options) {
|
|
|
3173
4115
|
} catch (error) {
|
|
3174
4116
|
const errorMessage = getErrorMessage(error);
|
|
3175
4117
|
if (options.json) {
|
|
3176
|
-
|
|
3177
|
-
|
|
3178
|
-
|
|
3179
|
-
|
|
3180
|
-
|
|
3181
|
-
|
|
3182
|
-
|
|
4118
|
+
const errorOutput = JSON.stringify(
|
|
4119
|
+
{
|
|
4120
|
+
valid: false,
|
|
4121
|
+
type: options.type,
|
|
4122
|
+
errors: [
|
|
4123
|
+
{ path: "input", message: errorMessage, code: "INPUT_ERROR" }
|
|
4124
|
+
],
|
|
4125
|
+
warnings: [],
|
|
4126
|
+
details: {}
|
|
4127
|
+
},
|
|
4128
|
+
null,
|
|
4129
|
+
2
|
|
4130
|
+
);
|
|
4131
|
+
await writeResult(errorOutput + "\n", { output: options.output });
|
|
3183
4132
|
} else {
|
|
3184
4133
|
logger2.error(`Error: ${errorMessage}`);
|
|
3185
4134
|
}
|
|
@@ -3188,21 +4137,22 @@ async function validateCommand(options) {
|
|
|
3188
4137
|
}
|
|
3189
4138
|
|
|
3190
4139
|
// src/commands/cache.ts
|
|
3191
|
-
import
|
|
4140
|
+
import fs14 from "fs-extra";
|
|
3192
4141
|
function registerCacheCommand(program2) {
|
|
3193
4142
|
const cache = program2.command("cache").description("Manage the CLI cache");
|
|
3194
4143
|
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) => {
|
|
3195
4144
|
const logger2 = createLogger({ silent: options.silent });
|
|
3196
4145
|
const tmpDir = options.tmpDir;
|
|
3197
4146
|
if (options.packages) {
|
|
3198
|
-
await
|
|
4147
|
+
await fs14.remove(getTmpPath(tmpDir, "cache", "packages"));
|
|
3199
4148
|
logger2.log("Package cache cleared");
|
|
3200
4149
|
} else if (options.builds) {
|
|
3201
|
-
await
|
|
4150
|
+
await fs14.remove(getTmpPath(tmpDir, "cache", "builds"));
|
|
3202
4151
|
logger2.log("Build cache cleared");
|
|
3203
4152
|
} else {
|
|
3204
|
-
|
|
3205
|
-
|
|
4153
|
+
const cacheDir = getTmpPath(tmpDir, "cache");
|
|
4154
|
+
await fs14.remove(cacheDir);
|
|
4155
|
+
logger2.log(`Cache cleared: ${cacheDir}`);
|
|
3206
4156
|
}
|
|
3207
4157
|
});
|
|
3208
4158
|
cache.command("info").description("Show cache statistics").option("--tmp-dir <dir>", "Custom temp directory").option("--silent", "Suppress output").action(async (options) => {
|
|
@@ -3217,35 +4167,383 @@ function registerCacheCommand(program2) {
|
|
|
3217
4167
|
logger2.log(`Cached builds: ${buildCount}`);
|
|
3218
4168
|
});
|
|
3219
4169
|
}
|
|
3220
|
-
function registerCleanCommand(program2) {
|
|
3221
|
-
program2.command("clean").description("Clear the entire temp directory (.tmp/)").option("--tmp-dir <dir>", "Custom temp directory").option("--silent", "Suppress output").action(async (options) => {
|
|
3222
|
-
const logger2 = createLogger({ silent: options.silent });
|
|
3223
|
-
const tmpDir = options.tmpDir || getDefaultTmpRoot();
|
|
3224
|
-
await fs13.remove(tmpDir);
|
|
3225
|
-
logger2.log(`Temp directory cleared: ${tmpDir}`);
|
|
3226
|
-
});
|
|
3227
|
-
}
|
|
3228
4170
|
async function countEntries(dir) {
|
|
3229
|
-
if (!await
|
|
3230
|
-
const entries = await
|
|
4171
|
+
if (!await fs14.pathExists(dir)) return 0;
|
|
4172
|
+
const entries = await fs14.readdir(dir);
|
|
3231
4173
|
return entries.length;
|
|
3232
4174
|
}
|
|
3233
4175
|
|
|
4176
|
+
// src/commands/login/index.ts
|
|
4177
|
+
import { createServer } from "http";
|
|
4178
|
+
import { randomBytes } from "crypto";
|
|
4179
|
+
var LOGIN_TIMEOUT_MS = 2 * 60 * 1e3;
|
|
4180
|
+
function escapeHtml(str) {
|
|
4181
|
+
return str.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
4182
|
+
}
|
|
4183
|
+
async function loginCommand(options) {
|
|
4184
|
+
const logger2 = createLogger({
|
|
4185
|
+
verbose: options.verbose,
|
|
4186
|
+
silent: options.silent,
|
|
4187
|
+
json: options.json
|
|
4188
|
+
});
|
|
4189
|
+
try {
|
|
4190
|
+
const result = await login({ url: options.url });
|
|
4191
|
+
if (options.json) {
|
|
4192
|
+
console.log(JSON.stringify(result, null, 2));
|
|
4193
|
+
} else if (result.success) {
|
|
4194
|
+
logger2.success(`Logged in as ${result.email}`);
|
|
4195
|
+
logger2.log(`Token stored in ${result.configPath}`);
|
|
4196
|
+
}
|
|
4197
|
+
process.exit(result.success ? 0 : 1);
|
|
4198
|
+
} catch (error) {
|
|
4199
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
4200
|
+
if (options.json) {
|
|
4201
|
+
console.log(JSON.stringify({ success: false, error: message }, null, 2));
|
|
4202
|
+
} else {
|
|
4203
|
+
logger2.error(message);
|
|
4204
|
+
}
|
|
4205
|
+
process.exit(1);
|
|
4206
|
+
}
|
|
4207
|
+
}
|
|
4208
|
+
async function login(options = {}) {
|
|
4209
|
+
const appUrl = options.url || resolveAppUrl();
|
|
4210
|
+
const state = randomBytes(32).toString("hex");
|
|
4211
|
+
const { default: open2 } = await Promise.resolve().then(() => (init_open(), open_exports));
|
|
4212
|
+
return new Promise((resolve3, reject) => {
|
|
4213
|
+
const server = createServer(async (req, res) => {
|
|
4214
|
+
const url = new URL(req.url || "", `http://localhost`);
|
|
4215
|
+
if (url.pathname !== "/callback") {
|
|
4216
|
+
res.writeHead(404);
|
|
4217
|
+
res.end("Not found");
|
|
4218
|
+
return;
|
|
4219
|
+
}
|
|
4220
|
+
const code = url.searchParams.get("code");
|
|
4221
|
+
const returnedState = url.searchParams.get("state");
|
|
4222
|
+
if (returnedState !== state) {
|
|
4223
|
+
res.writeHead(200, { "Content-Type": "text/html" });
|
|
4224
|
+
res.end(
|
|
4225
|
+
"<html><body><h1>Authorization failed</h1><p>State mismatch. Please try again.</p></body></html>"
|
|
4226
|
+
);
|
|
4227
|
+
cleanup();
|
|
4228
|
+
reject(new Error("Authorization failed: state mismatch"));
|
|
4229
|
+
return;
|
|
4230
|
+
}
|
|
4231
|
+
if (!code) {
|
|
4232
|
+
res.writeHead(200, { "Content-Type": "text/html" });
|
|
4233
|
+
res.end(
|
|
4234
|
+
"<html><body><h1>Authorization failed</h1><p>No authorization code received.</p></body></html>"
|
|
4235
|
+
);
|
|
4236
|
+
cleanup();
|
|
4237
|
+
reject(new Error("Authorization failed: no code received"));
|
|
4238
|
+
return;
|
|
4239
|
+
}
|
|
4240
|
+
try {
|
|
4241
|
+
const exchangeResponse = await fetch(
|
|
4242
|
+
`${appUrl}/api/auth/cli/exchange`,
|
|
4243
|
+
{
|
|
4244
|
+
method: "POST",
|
|
4245
|
+
headers: { "Content-Type": "application/json" },
|
|
4246
|
+
body: JSON.stringify({ code })
|
|
4247
|
+
}
|
|
4248
|
+
);
|
|
4249
|
+
if (!exchangeResponse.ok) {
|
|
4250
|
+
const error = await exchangeResponse.json();
|
|
4251
|
+
res.writeHead(200, { "Content-Type": "text/html" });
|
|
4252
|
+
const safeMessage = escapeHtml(
|
|
4253
|
+
error.error?.message || "Unknown error"
|
|
4254
|
+
);
|
|
4255
|
+
res.end(
|
|
4256
|
+
`<html><body><h1>Authorization failed</h1><p>${safeMessage}</p></body></html>`
|
|
4257
|
+
);
|
|
4258
|
+
cleanup();
|
|
4259
|
+
reject(new Error(error.error?.message || "Token exchange failed"));
|
|
4260
|
+
return;
|
|
4261
|
+
}
|
|
4262
|
+
const data = await exchangeResponse.json();
|
|
4263
|
+
writeConfig({
|
|
4264
|
+
token: data.token,
|
|
4265
|
+
email: data.email,
|
|
4266
|
+
appUrl
|
|
4267
|
+
});
|
|
4268
|
+
const configPath = getConfigPath();
|
|
4269
|
+
res.writeHead(200, { "Content-Type": "text/html" });
|
|
4270
|
+
res.end(
|
|
4271
|
+
"<html><body><h1>Authorized!</h1><p>You can close this tab and return to the terminal.</p></body></html>"
|
|
4272
|
+
);
|
|
4273
|
+
cleanup();
|
|
4274
|
+
resolve3({ success: true, email: data.email, configPath });
|
|
4275
|
+
} catch {
|
|
4276
|
+
res.writeHead(200, { "Content-Type": "text/html" });
|
|
4277
|
+
res.end(
|
|
4278
|
+
"<html><body><h1>Authorization failed</h1><p>Could not exchange authorization code.</p></body></html>"
|
|
4279
|
+
);
|
|
4280
|
+
cleanup();
|
|
4281
|
+
reject(new Error("Token exchange failed"));
|
|
4282
|
+
}
|
|
4283
|
+
});
|
|
4284
|
+
const timeout = setTimeout(() => {
|
|
4285
|
+
cleanup();
|
|
4286
|
+
reject(new Error("Authorization timed out. Please try again."));
|
|
4287
|
+
}, LOGIN_TIMEOUT_MS);
|
|
4288
|
+
function cleanup() {
|
|
4289
|
+
clearTimeout(timeout);
|
|
4290
|
+
server.close();
|
|
4291
|
+
}
|
|
4292
|
+
server.listen(0, () => {
|
|
4293
|
+
const address = server.address();
|
|
4294
|
+
if (!address || typeof address === "string") {
|
|
4295
|
+
cleanup();
|
|
4296
|
+
reject(new Error("Failed to start callback server"));
|
|
4297
|
+
return;
|
|
4298
|
+
}
|
|
4299
|
+
const port = address.port;
|
|
4300
|
+
const authUrl = `${appUrl}/auth/cli?port=${port}&state=${state}`;
|
|
4301
|
+
open2(authUrl).catch(() => {
|
|
4302
|
+
console.error(
|
|
4303
|
+
`Could not open browser. Visit this URL manually:
|
|
4304
|
+
|
|
4305
|
+
${authUrl}
|
|
4306
|
+
`
|
|
4307
|
+
);
|
|
4308
|
+
});
|
|
4309
|
+
});
|
|
4310
|
+
});
|
|
4311
|
+
}
|
|
4312
|
+
|
|
4313
|
+
// src/commands/logout/index.ts
|
|
4314
|
+
async function logoutCommand(options) {
|
|
4315
|
+
const logger2 = createLogger({
|
|
4316
|
+
verbose: options.verbose,
|
|
4317
|
+
silent: options.silent,
|
|
4318
|
+
json: options.json
|
|
4319
|
+
});
|
|
4320
|
+
const deleted = deleteConfig();
|
|
4321
|
+
const configPath = getConfigPath();
|
|
4322
|
+
if (options.json) {
|
|
4323
|
+
console.log(JSON.stringify({ success: true, deleted }));
|
|
4324
|
+
} else if (deleted) {
|
|
4325
|
+
logger2.success(`Logged out. Token removed from ${configPath}`);
|
|
4326
|
+
} else {
|
|
4327
|
+
logger2.log("No stored credentials found.");
|
|
4328
|
+
}
|
|
4329
|
+
process.exit(0);
|
|
4330
|
+
}
|
|
4331
|
+
|
|
4332
|
+
// src/commands/auth/index.ts
|
|
4333
|
+
async function whoami() {
|
|
4334
|
+
return apiRequest("/api/auth/whoami");
|
|
4335
|
+
}
|
|
4336
|
+
async function whoamiCommand(options) {
|
|
4337
|
+
const logger2 = createCommandLogger(options);
|
|
4338
|
+
try {
|
|
4339
|
+
const result = await whoami();
|
|
4340
|
+
if (options.json) {
|
|
4341
|
+
await writeResult(JSON.stringify(result, null, 2), options);
|
|
4342
|
+
} else {
|
|
4343
|
+
const data = result;
|
|
4344
|
+
if (data.email) logger2.log(`${data.email}`);
|
|
4345
|
+
if (data.userId) logger2.log(`User: ${data.userId}`);
|
|
4346
|
+
if (data.projectId) logger2.log(`Project: ${data.projectId}`);
|
|
4347
|
+
}
|
|
4348
|
+
} catch (error) {
|
|
4349
|
+
logger2.error(error instanceof Error ? error.message : String(error));
|
|
4350
|
+
process.exit(1);
|
|
4351
|
+
}
|
|
4352
|
+
}
|
|
4353
|
+
|
|
4354
|
+
// src/commands/projects/index.ts
|
|
4355
|
+
async function listProjects() {
|
|
4356
|
+
return apiRequest("/api/projects");
|
|
4357
|
+
}
|
|
4358
|
+
async function getProject(options = {}) {
|
|
4359
|
+
const id = options.projectId ?? requireProjectId();
|
|
4360
|
+
return apiRequest(`/api/projects/${id}`);
|
|
4361
|
+
}
|
|
4362
|
+
async function createProject(options) {
|
|
4363
|
+
return apiRequest("/api/projects", {
|
|
4364
|
+
method: "POST",
|
|
4365
|
+
body: JSON.stringify({ name: options.name })
|
|
4366
|
+
});
|
|
4367
|
+
}
|
|
4368
|
+
async function updateProject(options) {
|
|
4369
|
+
const id = options.projectId ?? requireProjectId();
|
|
4370
|
+
return apiRequest(`/api/projects/${id}`, {
|
|
4371
|
+
method: "PATCH",
|
|
4372
|
+
body: JSON.stringify({ name: options.name })
|
|
4373
|
+
});
|
|
4374
|
+
}
|
|
4375
|
+
async function deleteProject(options = {}) {
|
|
4376
|
+
const id = options.projectId ?? requireProjectId();
|
|
4377
|
+
return apiRequest(`/api/projects/${id}`, { method: "DELETE" });
|
|
4378
|
+
}
|
|
4379
|
+
async function handleResult(fn, options) {
|
|
4380
|
+
const logger2 = createCommandLogger(options);
|
|
4381
|
+
try {
|
|
4382
|
+
const result = await fn();
|
|
4383
|
+
await writeResult(JSON.stringify(result, null, 2), options);
|
|
4384
|
+
} catch (error) {
|
|
4385
|
+
logger2.error(error instanceof Error ? error.message : String(error));
|
|
4386
|
+
process.exit(1);
|
|
4387
|
+
}
|
|
4388
|
+
}
|
|
4389
|
+
async function listProjectsCommand(options) {
|
|
4390
|
+
await handleResult(() => listProjects(), options);
|
|
4391
|
+
}
|
|
4392
|
+
async function getProjectCommand(projectId, options) {
|
|
4393
|
+
await handleResult(
|
|
4394
|
+
() => getProject({ projectId: projectId ?? options.project }),
|
|
4395
|
+
options
|
|
4396
|
+
);
|
|
4397
|
+
}
|
|
4398
|
+
async function createProjectCommand(name, options) {
|
|
4399
|
+
await handleResult(() => createProject({ name }), options);
|
|
4400
|
+
}
|
|
4401
|
+
async function updateProjectCommand(projectId, options) {
|
|
4402
|
+
const name = options.name;
|
|
4403
|
+
if (!name) {
|
|
4404
|
+
throw new Error("Missing required option: --name <name>");
|
|
4405
|
+
}
|
|
4406
|
+
await handleResult(
|
|
4407
|
+
() => updateProject({
|
|
4408
|
+
projectId: projectId ?? options.project,
|
|
4409
|
+
name
|
|
4410
|
+
}),
|
|
4411
|
+
options
|
|
4412
|
+
);
|
|
4413
|
+
}
|
|
4414
|
+
async function deleteProjectCommand(projectId, options) {
|
|
4415
|
+
await handleResult(
|
|
4416
|
+
() => deleteProject({ projectId: projectId ?? options.project }),
|
|
4417
|
+
options
|
|
4418
|
+
);
|
|
4419
|
+
}
|
|
4420
|
+
|
|
4421
|
+
// src/commands/flows/index.ts
|
|
4422
|
+
async function listFlows(options = {}) {
|
|
4423
|
+
const id = options.projectId ?? requireProjectId();
|
|
4424
|
+
const params = new URLSearchParams();
|
|
4425
|
+
if (options.sort) params.set("sort", options.sort);
|
|
4426
|
+
if (options.order) params.set("order", options.order);
|
|
4427
|
+
if (options.includeDeleted) params.set("include_deleted", "true");
|
|
4428
|
+
const qs = params.toString();
|
|
4429
|
+
return apiRequest(`/api/projects/${id}/flows${qs ? `?${qs}` : ""}`);
|
|
4430
|
+
}
|
|
4431
|
+
async function getFlow(options) {
|
|
4432
|
+
const id = options.projectId ?? requireProjectId();
|
|
4433
|
+
return apiRequest(`/api/projects/${id}/flows/${options.flowId}`);
|
|
4434
|
+
}
|
|
4435
|
+
async function createFlow(options) {
|
|
4436
|
+
const id = options.projectId ?? requireProjectId();
|
|
4437
|
+
return apiRequest(`/api/projects/${id}/flows`, {
|
|
4438
|
+
method: "POST",
|
|
4439
|
+
body: JSON.stringify({ name: options.name, content: options.content })
|
|
4440
|
+
});
|
|
4441
|
+
}
|
|
4442
|
+
async function updateFlow(options) {
|
|
4443
|
+
const id = options.projectId ?? requireProjectId();
|
|
4444
|
+
const body = {};
|
|
4445
|
+
if (options.name !== void 0) body.name = options.name;
|
|
4446
|
+
if (options.content !== void 0) body.content = options.content;
|
|
4447
|
+
return apiRequest(`/api/projects/${id}/flows/${options.flowId}`, {
|
|
4448
|
+
method: "PATCH",
|
|
4449
|
+
body: JSON.stringify(body)
|
|
4450
|
+
});
|
|
4451
|
+
}
|
|
4452
|
+
async function deleteFlow(options) {
|
|
4453
|
+
const id = options.projectId ?? requireProjectId();
|
|
4454
|
+
return apiRequest(`/api/projects/${id}/flows/${options.flowId}`, {
|
|
4455
|
+
method: "DELETE"
|
|
4456
|
+
});
|
|
4457
|
+
}
|
|
4458
|
+
async function duplicateFlow(options) {
|
|
4459
|
+
const id = options.projectId ?? requireProjectId();
|
|
4460
|
+
const body = options.name ? { name: options.name } : {};
|
|
4461
|
+
return apiRequest(`/api/projects/${id}/flows/${options.flowId}/duplicate`, {
|
|
4462
|
+
method: "POST",
|
|
4463
|
+
body: JSON.stringify(body)
|
|
4464
|
+
});
|
|
4465
|
+
}
|
|
4466
|
+
async function handleResult2(fn, options) {
|
|
4467
|
+
const logger2 = createCommandLogger(options);
|
|
4468
|
+
try {
|
|
4469
|
+
const result = await fn();
|
|
4470
|
+
await writeResult(JSON.stringify(result, null, 2), options);
|
|
4471
|
+
} catch (error) {
|
|
4472
|
+
logger2.error(error instanceof Error ? error.message : String(error));
|
|
4473
|
+
process.exit(1);
|
|
4474
|
+
}
|
|
4475
|
+
}
|
|
4476
|
+
async function listFlowsCommand(options) {
|
|
4477
|
+
await handleResult2(
|
|
4478
|
+
() => listFlows({
|
|
4479
|
+
projectId: options.project,
|
|
4480
|
+
sort: options.sort,
|
|
4481
|
+
order: options.order,
|
|
4482
|
+
includeDeleted: options.includeDeleted
|
|
4483
|
+
}),
|
|
4484
|
+
options
|
|
4485
|
+
);
|
|
4486
|
+
}
|
|
4487
|
+
async function getFlowCommand(flowId, options) {
|
|
4488
|
+
await handleResult2(
|
|
4489
|
+
() => getFlow({ flowId, projectId: options.project }),
|
|
4490
|
+
options
|
|
4491
|
+
);
|
|
4492
|
+
}
|
|
4493
|
+
async function createFlowCommand(name, options) {
|
|
4494
|
+
const content = options.content ? JSON.parse(options.content) : JSON.parse(await readFlowStdin());
|
|
4495
|
+
await handleResult2(
|
|
4496
|
+
() => createFlow({ name, content, projectId: options.project }),
|
|
4497
|
+
options
|
|
4498
|
+
);
|
|
4499
|
+
}
|
|
4500
|
+
async function updateFlowCommand(flowId, options) {
|
|
4501
|
+
const content = options.content ? JSON.parse(options.content) : void 0;
|
|
4502
|
+
await handleResult2(
|
|
4503
|
+
() => updateFlow({
|
|
4504
|
+
flowId,
|
|
4505
|
+
name: options.name,
|
|
4506
|
+
content,
|
|
4507
|
+
projectId: options.project
|
|
4508
|
+
}),
|
|
4509
|
+
options
|
|
4510
|
+
);
|
|
4511
|
+
}
|
|
4512
|
+
async function deleteFlowCommand(flowId, options) {
|
|
4513
|
+
await handleResult2(
|
|
4514
|
+
() => deleteFlow({ flowId, projectId: options.project }),
|
|
4515
|
+
options
|
|
4516
|
+
);
|
|
4517
|
+
}
|
|
4518
|
+
async function duplicateFlowCommand(flowId, options) {
|
|
4519
|
+
await handleResult2(
|
|
4520
|
+
() => duplicateFlow({ flowId, name: options.name, projectId: options.project }),
|
|
4521
|
+
options
|
|
4522
|
+
);
|
|
4523
|
+
}
|
|
4524
|
+
async function readFlowStdin() {
|
|
4525
|
+
if (!isStdinPiped()) {
|
|
4526
|
+
throw new Error("Content required: use --content or pipe via stdin");
|
|
4527
|
+
}
|
|
4528
|
+
return readStdin();
|
|
4529
|
+
}
|
|
4530
|
+
|
|
3234
4531
|
// src/index.ts
|
|
3235
4532
|
var program = new Command();
|
|
3236
4533
|
program.name("walkeros").description("walkerOS CLI - Bundle and deploy walkerOS components").version(VERSION);
|
|
3237
4534
|
program.hook("preAction", (thisCommand, actionCommand) => {
|
|
3238
4535
|
const options = actionCommand.opts();
|
|
3239
|
-
if (!options.silent && !options.json) {
|
|
3240
|
-
|
|
4536
|
+
if (!options.silent && !options.json && process.stdout.isTTY) {
|
|
4537
|
+
printBanner(VERSION);
|
|
3241
4538
|
}
|
|
3242
4539
|
});
|
|
3243
|
-
program.command("bundle [file]").description("Bundle NPM packages with custom code").option("--flow <name>", "flow name for multi-flow configs").option("--all", "build all flows for multi-flow configs").option("--stats", "show bundle statistics").option("--json", "output as JSON (implies --stats)").option("--no-cache", "disable package caching").option("-v, --verbose", "verbose output").option("-s, --silent", "suppress output").option(
|
|
4540
|
+
program.command("bundle [file]").description("Bundle NPM packages with custom code").option("-o, --output <path>", "write bundle to file or directory").option("--flow <name>", "flow name for multi-flow configs").option("--all", "build all flows for multi-flow configs").option("--stats", "show bundle statistics").option("--json", "output as JSON (implies --stats)").option("--no-cache", "disable package caching").option("-v, --verbose", "verbose output").option("-s, --silent", "suppress output").option(
|
|
3244
4541
|
"--dockerfile [file]",
|
|
3245
4542
|
"generate Dockerfile (or copy custom file) to dist/"
|
|
3246
4543
|
).action(async (file, options) => {
|
|
3247
4544
|
await bundleCommand({
|
|
3248
|
-
config: file
|
|
4545
|
+
config: file,
|
|
4546
|
+
output: options.output,
|
|
3249
4547
|
flow: options.flow,
|
|
3250
4548
|
all: options.all,
|
|
3251
4549
|
stats: options.stats,
|
|
@@ -3256,12 +4554,13 @@ program.command("bundle [file]").description("Bundle NPM packages with custom co
|
|
|
3256
4554
|
dockerfile: options.dockerfile
|
|
3257
4555
|
});
|
|
3258
4556
|
});
|
|
3259
|
-
program.command("simulate [file]").description("Simulate event processing and capture API calls").option(
|
|
4557
|
+
program.command("simulate [file]").description("Simulate event processing and capture API calls").option("-o, --output <path>", "write result to file").option(
|
|
3260
4558
|
"-e, --event <source>",
|
|
3261
4559
|
"event to simulate (JSON string, file path, or URL)"
|
|
3262
4560
|
).option("--flow <name>", "flow name for multi-flow configs").option("-p, --platform <platform>", "platform override (web or server)").option("--json", "output as JSON").option("-v, --verbose", "verbose output").option("-s, --silent", "suppress output").action(async (file, options) => {
|
|
3263
4561
|
await simulateCommand({
|
|
3264
|
-
config: file
|
|
4562
|
+
config: file,
|
|
4563
|
+
output: options.output,
|
|
3265
4564
|
event: options.event,
|
|
3266
4565
|
flow: options.flow,
|
|
3267
4566
|
platform: options.platform,
|
|
@@ -3273,9 +4572,10 @@ program.command("simulate [file]").description("Simulate event processing and ca
|
|
|
3273
4572
|
program.command("push [file]").description("Push an event through the flow with real API execution").requiredOption(
|
|
3274
4573
|
"-e, --event <source>",
|
|
3275
4574
|
"event to push (JSON string, file path, or URL)"
|
|
3276
|
-
).option("--flow <name>", "flow name for multi-flow configs").option("-p, --platform <platform>", "platform override (web or server)").option("--json", "output as JSON").option("-v, --verbose", "verbose output").option("-s, --silent", "suppress output").action(async (file, options) => {
|
|
4575
|
+
).option("-o, --output <path>", "write result to file").option("--flow <name>", "flow name for multi-flow configs").option("-p, --platform <platform>", "platform override (web or server)").option("--json", "output as JSON").option("-v, --verbose", "verbose output").option("-s, --silent", "suppress output").action(async (file, options) => {
|
|
3277
4576
|
await pushCommand({
|
|
3278
|
-
config: file
|
|
4577
|
+
config: file,
|
|
4578
|
+
output: options.output,
|
|
3279
4579
|
event: options.event,
|
|
3280
4580
|
flow: options.flow,
|
|
3281
4581
|
platform: options.platform,
|
|
@@ -3284,10 +4584,11 @@ program.command("push [file]").description("Push an event through the flow with
|
|
|
3284
4584
|
silent: options.silent
|
|
3285
4585
|
});
|
|
3286
4586
|
});
|
|
3287
|
-
program.command("validate <type> [input]").description("Validate event, flow, or mapping configuration").option("--flow <name>", "flow name for multi-flow configs").option("--json", "output as JSON").option("-v, --verbose", "verbose output").option("-s, --silent", "suppress output").option("--strict", "fail on warnings").action(async (type, input, options) => {
|
|
4587
|
+
program.command("validate <type> [input]").description("Validate event, flow, or mapping configuration").option("-o, --output <path>", "write result to file").option("--flow <name>", "flow name for multi-flow configs").option("--json", "output as JSON").option("-v, --verbose", "verbose output").option("-s, --silent", "suppress output").option("--strict", "fail on warnings").action(async (type, input, options) => {
|
|
3288
4588
|
await validateCommand({
|
|
3289
4589
|
type,
|
|
3290
4590
|
input,
|
|
4591
|
+
output: options.output,
|
|
3291
4592
|
flow: options.flow,
|
|
3292
4593
|
json: options.json,
|
|
3293
4594
|
verbose: options.verbose,
|
|
@@ -3295,6 +4596,65 @@ program.command("validate <type> [input]").description("Validate event, flow, or
|
|
|
3295
4596
|
strict: options.strict
|
|
3296
4597
|
});
|
|
3297
4598
|
});
|
|
4599
|
+
var authCmd = program.command("auth").description("Authentication and identity");
|
|
4600
|
+
authCmd.command("login").description("Log in to walkerOS via browser").option("--url <url>", "custom app URL").option("--json", "output as JSON").option("-v, --verbose", "verbose output").option("-s, --silent", "suppress output").action(async (options) => {
|
|
4601
|
+
await loginCommand({
|
|
4602
|
+
url: options.url,
|
|
4603
|
+
json: options.json,
|
|
4604
|
+
verbose: options.verbose,
|
|
4605
|
+
silent: options.silent
|
|
4606
|
+
});
|
|
4607
|
+
});
|
|
4608
|
+
authCmd.command("logout").description("Remove stored credentials").option("--json", "output as JSON").option("-v, --verbose", "verbose output").option("-s, --silent", "suppress output").action(async (options) => {
|
|
4609
|
+
await logoutCommand({
|
|
4610
|
+
json: options.json,
|
|
4611
|
+
verbose: options.verbose,
|
|
4612
|
+
silent: options.silent
|
|
4613
|
+
});
|
|
4614
|
+
});
|
|
4615
|
+
authCmd.command("whoami").description("Show current user identity").option("-o, --output <path>", "output file path").option("--json", "output as JSON").option("-v, --verbose", "verbose output").option("-s, --silent", "suppress output").action(async (options) => {
|
|
4616
|
+
await whoamiCommand({
|
|
4617
|
+
output: options.output,
|
|
4618
|
+
json: options.json,
|
|
4619
|
+
verbose: options.verbose,
|
|
4620
|
+
silent: options.silent
|
|
4621
|
+
});
|
|
4622
|
+
});
|
|
4623
|
+
var projectsCmd = program.command("projects").description("Manage walkerOS projects");
|
|
4624
|
+
projectsCmd.command("list").description("List all projects").option("-o, --output <path>", "output file path").option("--json", "output as JSON").option("-v, --verbose", "verbose output").option("-s, --silent", "suppress output").action(async (options) => {
|
|
4625
|
+
await listProjectsCommand(options);
|
|
4626
|
+
});
|
|
4627
|
+
projectsCmd.command("get [projectId]").description("Get project details").option("-o, --output <path>", "output file path").option("--json", "output as JSON").option("-v, --verbose", "verbose output").option("-s, --silent", "suppress output").action(async (projectId, options) => {
|
|
4628
|
+
await getProjectCommand(projectId, options);
|
|
4629
|
+
});
|
|
4630
|
+
projectsCmd.command("create <name>").description("Create a new project").option("-o, --output <path>", "output file path").option("--json", "output as JSON").option("-v, --verbose", "verbose output").option("-s, --silent", "suppress output").action(async (name, options) => {
|
|
4631
|
+
await createProjectCommand(name, options);
|
|
4632
|
+
});
|
|
4633
|
+
projectsCmd.command("update [projectId]").description("Update a project").requiredOption("--name <name>", "new project name").option("-o, --output <path>", "output file path").option("--json", "output as JSON").option("-v, --verbose", "verbose output").option("-s, --silent", "suppress output").action(async (projectId, options) => {
|
|
4634
|
+
await updateProjectCommand(projectId, options);
|
|
4635
|
+
});
|
|
4636
|
+
projectsCmd.command("delete [projectId]").description("Delete a project").option("-o, --output <path>", "output file path").option("--json", "output as JSON").option("-v, --verbose", "verbose output").option("-s, --silent", "suppress output").action(async (projectId, options) => {
|
|
4637
|
+
await deleteProjectCommand(projectId, options);
|
|
4638
|
+
});
|
|
4639
|
+
var flowsCmd = program.command("flows").description("Manage walkerOS flows");
|
|
4640
|
+
flowsCmd.command("list").description("List all flows in a project").option("--project <id>", "project ID (defaults to WALKEROS_PROJECT_ID)").option("--sort <field>", "sort by: name, updated_at, created_at").option("--order <dir>", "sort order: asc, desc").option("--include-deleted", "include soft-deleted flows").option("-o, --output <path>", "output file path").option("--json", "output as JSON").option("-v, --verbose", "verbose output").option("-s, --silent", "suppress output").action(async (options) => {
|
|
4641
|
+
await listFlowsCommand(options);
|
|
4642
|
+
});
|
|
4643
|
+
flowsCmd.command("get <flowId>").description("Get a flow with its full content").option("--project <id>", "project ID (defaults to WALKEROS_PROJECT_ID)").option("-o, --output <path>", "output file path").option("--json", "output as JSON").option("-v, --verbose", "verbose output").option("-s, --silent", "suppress output").action(async (flowId, options) => {
|
|
4644
|
+
await getFlowCommand(flowId, options);
|
|
4645
|
+
});
|
|
4646
|
+
flowsCmd.command("create <name>").description("Create a new flow").option("--project <id>", "project ID (defaults to WALKEROS_PROJECT_ID)").option("-c, --content <json>", "Flow.Setup JSON string or file path").option("-o, --output <path>", "output file path").option("--json", "output as JSON").option("-v, --verbose", "verbose output").option("-s, --silent", "suppress output").action(async (name, options) => {
|
|
4647
|
+
await createFlowCommand(name, options);
|
|
4648
|
+
});
|
|
4649
|
+
flowsCmd.command("update <flowId>").description("Update a flow").option("--project <id>", "project ID (defaults to WALKEROS_PROJECT_ID)").option("--name <name>", "new flow name").option("-c, --content <json>", "new Flow.Setup JSON string or file path").option("-o, --output <path>", "output file path").option("--json", "output as JSON").option("-v, --verbose", "verbose output").option("-s, --silent", "suppress output").action(async (flowId, options) => {
|
|
4650
|
+
await updateFlowCommand(flowId, options);
|
|
4651
|
+
});
|
|
4652
|
+
flowsCmd.command("delete <flowId>").description("Delete a flow").option("--project <id>", "project ID (defaults to WALKEROS_PROJECT_ID)").option("-o, --output <path>", "output file path").option("--json", "output as JSON").option("-v, --verbose", "verbose output").option("-s, --silent", "suppress output").action(async (flowId, options) => {
|
|
4653
|
+
await deleteFlowCommand(flowId, options);
|
|
4654
|
+
});
|
|
4655
|
+
flowsCmd.command("duplicate <flowId>").description("Duplicate a flow").option("--project <id>", "project ID (defaults to WALKEROS_PROJECT_ID)").option("--name <name>", "name for the copy").option("-o, --output <path>", "output file path").option("--json", "output as JSON").option("-v, --verbose", "verbose output").option("-s, --silent", "suppress output").action(async (flowId, options) => {
|
|
4656
|
+
await duplicateFlowCommand(flowId, options);
|
|
4657
|
+
});
|
|
3298
4658
|
var runCmd = program.command("run").description("Run walkerOS flows in collect or serve mode");
|
|
3299
4659
|
runCmd.command("collect [file]").description(
|
|
3300
4660
|
"Run collector mode (event collection endpoint). Defaults to server-collect.mjs if no file specified."
|
|
@@ -3323,16 +4683,34 @@ runCmd.command("serve [file]").description(
|
|
|
3323
4683
|
});
|
|
3324
4684
|
});
|
|
3325
4685
|
registerCacheCommand(program);
|
|
3326
|
-
registerCleanCommand(program);
|
|
3327
4686
|
program.parse();
|
|
3328
4687
|
export {
|
|
4688
|
+
apiRequest,
|
|
4689
|
+
authenticatedFetch,
|
|
3329
4690
|
bundle,
|
|
3330
4691
|
bundleCommand,
|
|
4692
|
+
createFlow,
|
|
4693
|
+
createProject,
|
|
4694
|
+
deleteFlow,
|
|
4695
|
+
deleteProject,
|
|
4696
|
+
duplicateFlow,
|
|
4697
|
+
getAuthHeaders,
|
|
4698
|
+
getFlow,
|
|
4699
|
+
getProject,
|
|
4700
|
+
getToken,
|
|
4701
|
+
listFlows,
|
|
4702
|
+
listProjects,
|
|
4703
|
+
push,
|
|
3331
4704
|
pushCommand,
|
|
4705
|
+
requireProjectId,
|
|
4706
|
+
resolveBaseUrl,
|
|
3332
4707
|
run,
|
|
3333
4708
|
runCommand,
|
|
3334
4709
|
simulate,
|
|
3335
4710
|
simulateCommand,
|
|
3336
|
-
|
|
4711
|
+
updateFlow,
|
|
4712
|
+
updateProject,
|
|
4713
|
+
validate,
|
|
4714
|
+
whoami
|
|
3337
4715
|
};
|
|
3338
4716
|
//# sourceMappingURL=index.js.map
|