@walkeros/cli 1.3.0 → 1.4.0-next-1771257332985
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +13 -0
- package/dist/dev.d.ts +6 -6
- package/dist/dev.js +6 -1
- package/dist/dev.js.map +1 -1
- package/dist/examples/flow-complete.json +2 -0
- package/dist/examples/flow-complete.md +16 -14
- package/dist/index.d.ts +2334 -21
- package/dist/index.js +372 -824
- package/dist/index.js.map +1 -1
- package/examples/flow-complete.json +2 -0
- package/examples/flow-complete.md +16 -14
- package/package.json +14 -5
- package/dist/walker.js +0 -1
package/dist/index.js
CHANGED
|
@@ -1,608 +1,4 @@
|
|
|
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
|
-
});
|
|
606
2
|
|
|
607
3
|
// src/index.ts
|
|
608
4
|
import { Command } from "commander";
|
|
@@ -783,6 +179,7 @@ async function writeResult(content, options) {
|
|
|
783
179
|
await fs.writeFile(outputPath, content);
|
|
784
180
|
} else {
|
|
785
181
|
process.stdout.write(content);
|
|
182
|
+
process.stdout.write("\n");
|
|
786
183
|
}
|
|
787
184
|
}
|
|
788
185
|
function createJsonOutput(success, data, error, duration) {
|
|
@@ -903,38 +300,6 @@ function requireProjectId() {
|
|
|
903
300
|
if (!projectId) throw new Error("WALKEROS_PROJECT_ID not set.");
|
|
904
301
|
return projectId;
|
|
905
302
|
}
|
|
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
303
|
|
|
939
304
|
// src/config/utils.ts
|
|
940
305
|
function isUrl(str) {
|
|
@@ -1148,8 +513,8 @@ async function detectInput(inputPath, platformOverride) {
|
|
|
1148
513
|
JSON.parse(content);
|
|
1149
514
|
return { type: "config", content };
|
|
1150
515
|
} catch {
|
|
1151
|
-
const
|
|
1152
|
-
return { type: "bundle", content, platform
|
|
516
|
+
const platform = platformOverride ?? detectPlatformFromPath(inputPath);
|
|
517
|
+
return { type: "bundle", content, platform };
|
|
1153
518
|
}
|
|
1154
519
|
}
|
|
1155
520
|
function detectPlatformFromPath(inputPath) {
|
|
@@ -1193,8 +558,8 @@ function validateFlowSetup(data) {
|
|
|
1193
558
|
const result = safeParseSetup(data);
|
|
1194
559
|
if (!result.success) {
|
|
1195
560
|
const errors = result.error.issues.map((issue) => {
|
|
1196
|
-
const
|
|
1197
|
-
return ` - ${
|
|
561
|
+
const path15 = issue.path.length > 0 ? issue.path.map(String).join(".") : "root";
|
|
562
|
+
return ` - ${path15}: ${issue.message}`;
|
|
1198
563
|
}).join("\n");
|
|
1199
564
|
throw new Error(`Invalid configuration:
|
|
1200
565
|
${errors}`);
|
|
@@ -1228,11 +593,11 @@ var DEFAULT_OUTPUT_PATHS = {
|
|
|
1228
593
|
web: "./dist/walker.js",
|
|
1229
594
|
server: "./dist/bundle.mjs"
|
|
1230
595
|
};
|
|
1231
|
-
function getBuildDefaults(
|
|
1232
|
-
return
|
|
596
|
+
function getBuildDefaults(platform) {
|
|
597
|
+
return platform === "web" ? WEB_BUILD_DEFAULTS : SERVER_BUILD_DEFAULTS;
|
|
1233
598
|
}
|
|
1234
|
-
function getDefaultOutput(
|
|
1235
|
-
return DEFAULT_OUTPUT_PATHS[
|
|
599
|
+
function getDefaultOutput(platform) {
|
|
600
|
+
return DEFAULT_OUTPUT_PATHS[platform];
|
|
1236
601
|
}
|
|
1237
602
|
|
|
1238
603
|
// src/config/loader.ts
|
|
@@ -1245,15 +610,15 @@ function loadBundleConfig(rawConfig, options) {
|
|
|
1245
610
|
const availableFlows = getAvailableFlows(setup);
|
|
1246
611
|
const flowName = resolveFlow(setup, options.flowName, availableFlows);
|
|
1247
612
|
const flowConfig = getFlowConfig(setup, flowName);
|
|
1248
|
-
const
|
|
1249
|
-
if (!
|
|
613
|
+
const platform = getPlatform(flowConfig);
|
|
614
|
+
if (!platform) {
|
|
1250
615
|
throw new Error(
|
|
1251
616
|
`Invalid configuration: flow "${flowName}" must have a "web" or "server" key.`
|
|
1252
617
|
);
|
|
1253
618
|
}
|
|
1254
|
-
const buildDefaults = getBuildDefaults(
|
|
619
|
+
const buildDefaults = getBuildDefaults(platform);
|
|
1255
620
|
const packages = flowConfig.packages || {};
|
|
1256
|
-
const output = options.buildOverrides?.output || getDefaultOutput(
|
|
621
|
+
const output = options.buildOverrides?.output || getDefaultOutput(platform);
|
|
1257
622
|
const configDir = isUrl(options.configPath) ? process.cwd() : path6.dirname(options.configPath);
|
|
1258
623
|
let includes = setup.include;
|
|
1259
624
|
if (!includes) {
|
|
@@ -2339,6 +1704,20 @@ Package Breakdown:`);
|
|
|
2339
1704
|
logger2.info("\u2500".repeat(50));
|
|
2340
1705
|
}
|
|
2341
1706
|
|
|
1707
|
+
// src/core/api-client.ts
|
|
1708
|
+
import createClient from "openapi-fetch";
|
|
1709
|
+
function createApiClient() {
|
|
1710
|
+
const token = getToken();
|
|
1711
|
+
if (!token) throw new Error("WALKEROS_TOKEN not set.");
|
|
1712
|
+
return createClient({
|
|
1713
|
+
baseUrl: resolveBaseUrl(),
|
|
1714
|
+
headers: {
|
|
1715
|
+
Authorization: `Bearer ${token}`,
|
|
1716
|
+
"Content-Type": "application/json"
|
|
1717
|
+
}
|
|
1718
|
+
});
|
|
1719
|
+
}
|
|
1720
|
+
|
|
2342
1721
|
// src/commands/bundle/index.ts
|
|
2343
1722
|
function resolveOutputPath(output, buildOptions) {
|
|
2344
1723
|
const resolved = path10.resolve(output);
|
|
@@ -2426,11 +1805,11 @@ async function bundleCommand(options) {
|
|
|
2426
1805
|
await writeResult(bundleContent, {});
|
|
2427
1806
|
}
|
|
2428
1807
|
if (options.dockerfile && options.output) {
|
|
2429
|
-
const
|
|
2430
|
-
if (
|
|
1808
|
+
const platform = getPlatform2(flowConfig);
|
|
1809
|
+
if (platform) {
|
|
2431
1810
|
const outputDir = path10.dirname(buildOptions.output);
|
|
2432
1811
|
const customFile = typeof options.dockerfile === "string" ? options.dockerfile : void 0;
|
|
2433
|
-
await generateDockerfile(outputDir,
|
|
1812
|
+
await generateDockerfile(outputDir, platform, logger2, customFile);
|
|
2434
1813
|
}
|
|
2435
1814
|
}
|
|
2436
1815
|
} catch (error) {
|
|
@@ -2516,14 +1895,14 @@ async function bundle(configOrPath, options = {}) {
|
|
|
2516
1895
|
options.stats ?? false
|
|
2517
1896
|
);
|
|
2518
1897
|
}
|
|
2519
|
-
async function generateDockerfile(outputDir,
|
|
1898
|
+
async function generateDockerfile(outputDir, platform, logger2, customFile) {
|
|
2520
1899
|
const destPath = path10.join(outputDir, "Dockerfile");
|
|
2521
1900
|
if (customFile && await fs9.pathExists(customFile)) {
|
|
2522
1901
|
await fs9.copy(customFile, destPath);
|
|
2523
1902
|
logger2.log(`Dockerfile: ${destPath} (copied from ${customFile})`);
|
|
2524
1903
|
return;
|
|
2525
1904
|
}
|
|
2526
|
-
const isWeb =
|
|
1905
|
+
const isWeb = platform === "web";
|
|
2527
1906
|
const bundleFile = isWeb ? "walker.js" : "bundle.mjs";
|
|
2528
1907
|
const mode = isWeb ? "serve" : "collect";
|
|
2529
1908
|
const dockerfile = `# Generated by walkeros CLI
|
|
@@ -2539,6 +1918,22 @@ EXPOSE 8080
|
|
|
2539
1918
|
await fs9.writeFile(destPath, dockerfile);
|
|
2540
1919
|
logger2.log(`Dockerfile: ${destPath}`);
|
|
2541
1920
|
}
|
|
1921
|
+
async function bundleRemote(options) {
|
|
1922
|
+
const client = createApiClient();
|
|
1923
|
+
const { data, error, response } = await client.POST("/api/bundle", {
|
|
1924
|
+
body: { flow: options.content },
|
|
1925
|
+
parseAs: "text"
|
|
1926
|
+
});
|
|
1927
|
+
if (error)
|
|
1928
|
+
throw new Error(typeof error === "string" ? error : "Bundle failed");
|
|
1929
|
+
const js = data;
|
|
1930
|
+
const statsHeader = response.headers.get("X-Bundle-Stats");
|
|
1931
|
+
return {
|
|
1932
|
+
bundle: js,
|
|
1933
|
+
size: js.length,
|
|
1934
|
+
stats: statsHeader ? JSON.parse(statsHeader) : void 0
|
|
1935
|
+
};
|
|
1936
|
+
}
|
|
2542
1937
|
|
|
2543
1938
|
// src/commands/simulate/simulator.ts
|
|
2544
1939
|
import path11 from "path";
|
|
@@ -2579,9 +1974,9 @@ var CallTracker = class {
|
|
|
2579
1974
|
}
|
|
2580
1975
|
for (const fullPath of paths) {
|
|
2581
1976
|
const [destKey, ...pathParts] = fullPath.split(":");
|
|
2582
|
-
const
|
|
2583
|
-
if (!
|
|
2584
|
-
const cleanPath =
|
|
1977
|
+
const path15 = pathParts.join(":");
|
|
1978
|
+
if (!path15) continue;
|
|
1979
|
+
const cleanPath = path15.replace(/^call:/, "");
|
|
2585
1980
|
const parts = cleanPath.split(".");
|
|
2586
1981
|
let current = wrapped;
|
|
2587
1982
|
let source = env;
|
|
@@ -2934,11 +2329,11 @@ async function executeConfigSimulation(_content, configPath, typedEvent, tempDir
|
|
|
2934
2329
|
const { flowConfig, buildOptions } = await loadFlowConfig(configPath, {
|
|
2935
2330
|
flowName
|
|
2936
2331
|
});
|
|
2937
|
-
const
|
|
2332
|
+
const platform = getPlatform3(flowConfig);
|
|
2938
2333
|
const tracker = new CallTracker();
|
|
2939
2334
|
const tempOutput = path11.join(
|
|
2940
2335
|
tempDir,
|
|
2941
|
-
`simulation-bundle-${generateId()}.${
|
|
2336
|
+
`simulation-bundle-${generateId()}.${platform === "web" ? "js" : "mjs"}`
|
|
2942
2337
|
);
|
|
2943
2338
|
const destinations = flowConfig.destinations;
|
|
2944
2339
|
const simulationBuildOptions = {
|
|
@@ -2946,7 +2341,7 @@ async function executeConfigSimulation(_content, configPath, typedEvent, tempDir
|
|
|
2946
2341
|
code: buildOptions.code || "",
|
|
2947
2342
|
output: tempOutput,
|
|
2948
2343
|
tempDir,
|
|
2949
|
-
...
|
|
2344
|
+
...platform === "web" ? {
|
|
2950
2345
|
format: "iife",
|
|
2951
2346
|
platform: "browser",
|
|
2952
2347
|
windowCollector: "collector",
|
|
@@ -2964,7 +2359,7 @@ async function executeConfigSimulation(_content, configPath, typedEvent, tempDir
|
|
|
2964
2359
|
);
|
|
2965
2360
|
const envs = await loadDestinationEnvs(destinations || {});
|
|
2966
2361
|
let result;
|
|
2967
|
-
if (
|
|
2362
|
+
if (platform === "web") {
|
|
2968
2363
|
result = await executeInJSDOM(
|
|
2969
2364
|
tempOutput,
|
|
2970
2365
|
destinations || {},
|
|
@@ -2993,15 +2388,15 @@ async function executeConfigSimulation(_content, configPath, typedEvent, tempDir
|
|
|
2993
2388
|
logs: []
|
|
2994
2389
|
};
|
|
2995
2390
|
}
|
|
2996
|
-
async function executeBundleSimulation(bundleContent,
|
|
2391
|
+
async function executeBundleSimulation(bundleContent, platform, typedEvent, tempDir, startTime, loggerConfig2) {
|
|
2997
2392
|
const tempOutput = path11.join(
|
|
2998
2393
|
tempDir,
|
|
2999
|
-
`bundle-${generateId()}.${
|
|
2394
|
+
`bundle-${generateId()}.${platform === "server" ? "mjs" : "js"}`
|
|
3000
2395
|
);
|
|
3001
2396
|
await fs11.writeFile(tempOutput, bundleContent, "utf8");
|
|
3002
2397
|
const tracker = new CallTracker();
|
|
3003
2398
|
let result;
|
|
3004
|
-
if (
|
|
2399
|
+
if (platform === "web") {
|
|
3005
2400
|
result = await executeInJSDOM(
|
|
3006
2401
|
tempOutput,
|
|
3007
2402
|
{},
|
|
@@ -3039,11 +2434,11 @@ async function simulateCommand(options) {
|
|
|
3039
2434
|
let config;
|
|
3040
2435
|
if (isStdinPiped() && !options.config) {
|
|
3041
2436
|
const stdinContent = await readStdin();
|
|
3042
|
-
const
|
|
3043
|
-
const
|
|
3044
|
-
const tmpPath =
|
|
3045
|
-
await
|
|
3046
|
-
await
|
|
2437
|
+
const fs15 = await import("fs-extra");
|
|
2438
|
+
const path15 = await import("path");
|
|
2439
|
+
const tmpPath = path15.default.resolve(".tmp", "stdin-simulate.json");
|
|
2440
|
+
await fs15.default.ensureDir(path15.default.dirname(tmpPath));
|
|
2441
|
+
await fs15.default.writeFile(tmpPath, stdinContent, "utf-8");
|
|
3047
2442
|
config = tmpPath;
|
|
3048
2443
|
} else {
|
|
3049
2444
|
config = options.config || "bundle.config.json";
|
|
@@ -3276,7 +2671,7 @@ async function executeConfigPush(options, validatedEvent, logger2, setTempDir) {
|
|
|
3276
2671
|
flowName: options.flow,
|
|
3277
2672
|
logger: logger2
|
|
3278
2673
|
});
|
|
3279
|
-
const
|
|
2674
|
+
const platform = getPlatform4(flowConfig);
|
|
3280
2675
|
logger2.debug("Bundling flow configuration");
|
|
3281
2676
|
const configDir = buildOptions.configDir || process.cwd();
|
|
3282
2677
|
const tempDir = path12.join(
|
|
@@ -3288,24 +2683,24 @@ async function executeConfigPush(options, validatedEvent, logger2, setTempDir) {
|
|
|
3288
2683
|
await fs12.ensureDir(tempDir);
|
|
3289
2684
|
const tempPath = path12.join(
|
|
3290
2685
|
tempDir,
|
|
3291
|
-
`bundle.${
|
|
2686
|
+
`bundle.${platform === "web" ? "js" : "mjs"}`
|
|
3292
2687
|
);
|
|
3293
2688
|
const pushBuildOptions = {
|
|
3294
2689
|
...buildOptions,
|
|
3295
2690
|
output: tempPath,
|
|
3296
|
-
format:
|
|
3297
|
-
platform:
|
|
3298
|
-
...
|
|
2691
|
+
format: platform === "web" ? "iife" : "esm",
|
|
2692
|
+
platform: platform === "web" ? "browser" : "node",
|
|
2693
|
+
...platform === "web" && {
|
|
3299
2694
|
windowCollector: "collector",
|
|
3300
2695
|
windowElb: "elb"
|
|
3301
2696
|
}
|
|
3302
2697
|
};
|
|
3303
2698
|
await bundleCore(flowConfig, pushBuildOptions, logger2, false);
|
|
3304
2699
|
logger2.debug(`Bundle created: ${tempPath}`);
|
|
3305
|
-
if (
|
|
2700
|
+
if (platform === "web") {
|
|
3306
2701
|
logger2.debug("Executing in web environment (JSDOM)");
|
|
3307
2702
|
return executeWebPush(tempPath, validatedEvent, logger2);
|
|
3308
|
-
} else if (
|
|
2703
|
+
} else if (platform === "server") {
|
|
3309
2704
|
logger2.debug("Executing in server environment (Node.js)");
|
|
3310
2705
|
const collectorLoggerConfig = createCollectorLoggerConfig(
|
|
3311
2706
|
logger2,
|
|
@@ -3315,10 +2710,10 @@ async function executeConfigPush(options, validatedEvent, logger2, setTempDir) {
|
|
|
3315
2710
|
logger: collectorLoggerConfig
|
|
3316
2711
|
});
|
|
3317
2712
|
} else {
|
|
3318
|
-
throw new Error(`Unsupported platform: ${
|
|
2713
|
+
throw new Error(`Unsupported platform: ${platform}`);
|
|
3319
2714
|
}
|
|
3320
2715
|
}
|
|
3321
|
-
async function executeBundlePush(bundleContent,
|
|
2716
|
+
async function executeBundlePush(bundleContent, platform, validatedEvent, logger2, setTempDir, context = {}) {
|
|
3322
2717
|
const tempDir = path12.join(
|
|
3323
2718
|
process.cwd(),
|
|
3324
2719
|
".tmp",
|
|
@@ -3328,11 +2723,11 @@ async function executeBundlePush(bundleContent, platform2, validatedEvent, logge
|
|
|
3328
2723
|
await fs12.ensureDir(tempDir);
|
|
3329
2724
|
const tempPath = path12.join(
|
|
3330
2725
|
tempDir,
|
|
3331
|
-
`bundle.${
|
|
2726
|
+
`bundle.${platform === "server" ? "mjs" : "js"}`
|
|
3332
2727
|
);
|
|
3333
2728
|
await fs12.writeFile(tempPath, bundleContent, "utf8");
|
|
3334
2729
|
logger2.debug(`Bundle written to: ${tempPath}`);
|
|
3335
|
-
if (
|
|
2730
|
+
if (platform === "web") {
|
|
3336
2731
|
logger2.debug("Executing in web environment (JSDOM)");
|
|
3337
2732
|
return executeWebPush(tempPath, validatedEvent, logger2);
|
|
3338
2733
|
} else {
|
|
@@ -3466,7 +2861,12 @@ var RunOptionsSchema = z2.object({
|
|
|
3466
2861
|
|
|
3467
2862
|
// src/schemas/validate.ts
|
|
3468
2863
|
import { z as z3 } from "@walkeros/core/dev";
|
|
3469
|
-
var ValidationTypeSchema = z3.
|
|
2864
|
+
var ValidationTypeSchema = z3.union([
|
|
2865
|
+
z3.enum(["event", "flow", "mapping"]),
|
|
2866
|
+
z3.string().regex(/^(destinations|sources|transformers)\.\w+$|^\w+$/)
|
|
2867
|
+
]).describe(
|
|
2868
|
+
'Validation type: "event", "flow", "mapping", or dot-notation path (e.g., "destinations.snowplow") to validate a specific entry against its package schema'
|
|
2869
|
+
);
|
|
3470
2870
|
var ValidateOptionsSchema = z3.object({
|
|
3471
2871
|
flow: z3.string().optional().describe("Flow name for multi-flow configs")
|
|
3472
2872
|
});
|
|
@@ -3887,10 +3287,10 @@ function validateEvent(input) {
|
|
|
3887
3287
|
const zodResult = PartialEventSchema.safeParse(input);
|
|
3888
3288
|
if (!zodResult.success) {
|
|
3889
3289
|
for (const issue of zodResult.error.issues) {
|
|
3890
|
-
const
|
|
3891
|
-
if (
|
|
3290
|
+
const path15 = issue.path.join(".");
|
|
3291
|
+
if (path15 === "name") continue;
|
|
3892
3292
|
errors.push({
|
|
3893
|
-
path:
|
|
3293
|
+
path: path15 || "root",
|
|
3894
3294
|
message: issue.message,
|
|
3895
3295
|
code: "SCHEMA_VALIDATION"
|
|
3896
3296
|
});
|
|
@@ -3926,9 +3326,9 @@ function validateFlow(input, options = {}) {
|
|
|
3926
3326
|
const zodResult = SetupSchema.safeParse(input);
|
|
3927
3327
|
if (!zodResult.success) {
|
|
3928
3328
|
for (const issue of zodResult.error.issues) {
|
|
3929
|
-
const
|
|
3329
|
+
const path15 = issue.path.join(".");
|
|
3930
3330
|
errors.push({
|
|
3931
|
-
path:
|
|
3331
|
+
path: path15 || "root",
|
|
3932
3332
|
message: issue.message,
|
|
3933
3333
|
code: "SCHEMA_VALIDATION"
|
|
3934
3334
|
});
|
|
@@ -4033,8 +3433,144 @@ function validateMapping(input) {
|
|
|
4033
3433
|
};
|
|
4034
3434
|
}
|
|
4035
3435
|
|
|
3436
|
+
// src/commands/validate/validators/entry.ts
|
|
3437
|
+
import Ajv from "ajv";
|
|
3438
|
+
import { fetchPackageSchema } from "@walkeros/core";
|
|
3439
|
+
var SECTIONS = ["destinations", "sources", "transformers"];
|
|
3440
|
+
function resolveEntry(path15, flowConfig) {
|
|
3441
|
+
const flows = flowConfig.flows;
|
|
3442
|
+
if (!flows || typeof flows !== "object") return "No flows found in config";
|
|
3443
|
+
const flowName = Object.keys(flows)[0];
|
|
3444
|
+
const flow = flows[flowName];
|
|
3445
|
+
if (!flow) return `Flow "${flowName}" is empty`;
|
|
3446
|
+
const parts = path15.split(".");
|
|
3447
|
+
if (parts.length === 2) {
|
|
3448
|
+
const [section, key] = parts;
|
|
3449
|
+
if (!SECTIONS.includes(section)) {
|
|
3450
|
+
return `Unknown section "${section}". Must be one of: ${SECTIONS.join(", ")}`;
|
|
3451
|
+
}
|
|
3452
|
+
const sectionData = flow[section];
|
|
3453
|
+
if (!sectionData || !(key in sectionData)) {
|
|
3454
|
+
return `Entry "${key}" not found in ${section}`;
|
|
3455
|
+
}
|
|
3456
|
+
return {
|
|
3457
|
+
section,
|
|
3458
|
+
key,
|
|
3459
|
+
entry: sectionData[key]
|
|
3460
|
+
};
|
|
3461
|
+
}
|
|
3462
|
+
if (parts.length === 1) {
|
|
3463
|
+
const key = parts[0];
|
|
3464
|
+
const matches = [];
|
|
3465
|
+
for (const section of SECTIONS) {
|
|
3466
|
+
const sectionData = flow[section];
|
|
3467
|
+
if (sectionData && key in sectionData) {
|
|
3468
|
+
matches.push({
|
|
3469
|
+
section,
|
|
3470
|
+
entry: sectionData[key]
|
|
3471
|
+
});
|
|
3472
|
+
}
|
|
3473
|
+
}
|
|
3474
|
+
if (matches.length === 0) {
|
|
3475
|
+
return `Entry "${key}" not found in any section`;
|
|
3476
|
+
}
|
|
3477
|
+
if (matches.length > 1) {
|
|
3478
|
+
const sections = matches.map((m) => m.section).join(", ");
|
|
3479
|
+
return `Ambiguous key "${key}" found in multiple sections: ${sections}. Use dot-notation (e.g., destinations.${key})`;
|
|
3480
|
+
}
|
|
3481
|
+
return { section: matches[0].section, key, entry: matches[0].entry };
|
|
3482
|
+
}
|
|
3483
|
+
return `Invalid path "${path15}". Use "section.key" or just "key"`;
|
|
3484
|
+
}
|
|
3485
|
+
async function validateEntry(path15, flowConfig) {
|
|
3486
|
+
const resolved = resolveEntry(path15, flowConfig);
|
|
3487
|
+
if (typeof resolved === "string") {
|
|
3488
|
+
return {
|
|
3489
|
+
valid: false,
|
|
3490
|
+
type: "entry",
|
|
3491
|
+
errors: [{ path: path15, message: resolved, code: "ENTRY_VALIDATION" }],
|
|
3492
|
+
warnings: [],
|
|
3493
|
+
details: {}
|
|
3494
|
+
};
|
|
3495
|
+
}
|
|
3496
|
+
const { section, key, entry } = resolved;
|
|
3497
|
+
const packageName = entry.package;
|
|
3498
|
+
if (!packageName) {
|
|
3499
|
+
return {
|
|
3500
|
+
valid: true,
|
|
3501
|
+
type: "entry",
|
|
3502
|
+
errors: [],
|
|
3503
|
+
warnings: [],
|
|
3504
|
+
details: {
|
|
3505
|
+
section,
|
|
3506
|
+
key,
|
|
3507
|
+
skipped: true,
|
|
3508
|
+
reason: "No package field \u2014 skipping remote schema validation"
|
|
3509
|
+
}
|
|
3510
|
+
};
|
|
3511
|
+
}
|
|
3512
|
+
let schemas5;
|
|
3513
|
+
try {
|
|
3514
|
+
const info = await fetchPackageSchema(packageName);
|
|
3515
|
+
schemas5 = info.schemas;
|
|
3516
|
+
} catch (error) {
|
|
3517
|
+
return {
|
|
3518
|
+
valid: false,
|
|
3519
|
+
type: "entry",
|
|
3520
|
+
errors: [
|
|
3521
|
+
{
|
|
3522
|
+
path: path15,
|
|
3523
|
+
message: error instanceof Error ? error.message : "Unknown error",
|
|
3524
|
+
code: "ENTRY_VALIDATION"
|
|
3525
|
+
}
|
|
3526
|
+
],
|
|
3527
|
+
warnings: [],
|
|
3528
|
+
details: { section, key, package: packageName }
|
|
3529
|
+
};
|
|
3530
|
+
}
|
|
3531
|
+
const settingsSchema = schemas5?.settings;
|
|
3532
|
+
if (!settingsSchema) {
|
|
3533
|
+
return {
|
|
3534
|
+
valid: true,
|
|
3535
|
+
type: "entry",
|
|
3536
|
+
errors: [],
|
|
3537
|
+
warnings: [],
|
|
3538
|
+
details: { section, key, note: "Package has no settings schema" }
|
|
3539
|
+
};
|
|
3540
|
+
}
|
|
3541
|
+
const config = entry.config;
|
|
3542
|
+
const settings = config?.settings;
|
|
3543
|
+
const ajv = new Ajv({ allErrors: true });
|
|
3544
|
+
const validate2 = ajv.compile(settingsSchema);
|
|
3545
|
+
const isValid = validate2(settings || {});
|
|
3546
|
+
if (!isValid) {
|
|
3547
|
+
const errors = (validate2.errors || []).map((e) => ({
|
|
3548
|
+
path: e.instancePath || "/",
|
|
3549
|
+
message: e.message || "Unknown error",
|
|
3550
|
+
code: e.keyword
|
|
3551
|
+
}));
|
|
3552
|
+
return {
|
|
3553
|
+
valid: false,
|
|
3554
|
+
type: "entry",
|
|
3555
|
+
errors,
|
|
3556
|
+
warnings: [],
|
|
3557
|
+
details: { section, key, package: packageName }
|
|
3558
|
+
};
|
|
3559
|
+
}
|
|
3560
|
+
return {
|
|
3561
|
+
valid: true,
|
|
3562
|
+
type: "entry",
|
|
3563
|
+
errors: [],
|
|
3564
|
+
warnings: [],
|
|
3565
|
+
details: { section, key, package: packageName }
|
|
3566
|
+
};
|
|
3567
|
+
}
|
|
3568
|
+
|
|
4036
3569
|
// src/commands/validate/index.ts
|
|
4037
3570
|
async function validate(type, input, options = {}) {
|
|
3571
|
+
if (type.includes(".") || !["event", "flow", "mapping"].includes(type)) {
|
|
3572
|
+
return validateEntry(type, input);
|
|
3573
|
+
}
|
|
4038
3574
|
switch (type) {
|
|
4039
3575
|
case "event":
|
|
4040
3576
|
return validateEvent(input);
|
|
@@ -4174,11 +3710,11 @@ async function countEntries(dir) {
|
|
|
4174
3710
|
}
|
|
4175
3711
|
|
|
4176
3712
|
// src/commands/login/index.ts
|
|
4177
|
-
import {
|
|
4178
|
-
|
|
4179
|
-
|
|
4180
|
-
|
|
4181
|
-
|
|
3713
|
+
import { hostname } from "os";
|
|
3714
|
+
var POLL_TIMEOUT_BUFFER_MS = 5e3;
|
|
3715
|
+
async function openInBrowser(url) {
|
|
3716
|
+
const { default: open } = await import("open");
|
|
3717
|
+
await open(url);
|
|
4182
3718
|
}
|
|
4183
3719
|
async function loginCommand(options) {
|
|
4184
3720
|
const logger2 = createLogger({
|
|
@@ -4207,107 +3743,57 @@ async function loginCommand(options) {
|
|
|
4207
3743
|
}
|
|
4208
3744
|
async function login(options = {}) {
|
|
4209
3745
|
const appUrl = options.url || resolveAppUrl();
|
|
4210
|
-
const
|
|
4211
|
-
const
|
|
4212
|
-
|
|
4213
|
-
|
|
4214
|
-
|
|
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
|
-
});
|
|
3746
|
+
const f = options.fetch ?? globalThis.fetch;
|
|
3747
|
+
const codeResponse = await f(`${appUrl}/api/auth/device/code`, {
|
|
3748
|
+
method: "POST",
|
|
3749
|
+
headers: { "Content-Type": "application/json" },
|
|
3750
|
+
body: JSON.stringify({})
|
|
4310
3751
|
});
|
|
3752
|
+
if (!codeResponse.ok) {
|
|
3753
|
+
return { success: false, error: "Failed to request device code" };
|
|
3754
|
+
}
|
|
3755
|
+
const { deviceCode, userCode, verificationUri, expiresIn, interval } = await codeResponse.json();
|
|
3756
|
+
console.error(`
|
|
3757
|
+
! Your one-time code: ${userCode}`);
|
|
3758
|
+
console.error(` Authorize here: ${verificationUri}
|
|
3759
|
+
`);
|
|
3760
|
+
const opener = options.openUrl ?? openInBrowser;
|
|
3761
|
+
try {
|
|
3762
|
+
await opener(verificationUri);
|
|
3763
|
+
console.error(" Opening browser...");
|
|
3764
|
+
} catch {
|
|
3765
|
+
console.error(" Could not open browser. Visit the URL manually.");
|
|
3766
|
+
}
|
|
3767
|
+
console.error(" Waiting for authorization... (press Ctrl+C to cancel)\n");
|
|
3768
|
+
const deadline = Date.now() + expiresIn * 1e3 + POLL_TIMEOUT_BUFFER_MS;
|
|
3769
|
+
let pollInterval = (interval ?? 5) * 1e3;
|
|
3770
|
+
const maxAttempts = options.maxPollAttempts ?? Infinity;
|
|
3771
|
+
let attempts = 0;
|
|
3772
|
+
while (Date.now() < deadline && attempts < maxAttempts) {
|
|
3773
|
+
attempts++;
|
|
3774
|
+
await new Promise((r) => setTimeout(r, pollInterval));
|
|
3775
|
+
const tokenResponse = await f(`${appUrl}/api/auth/device/token`, {
|
|
3776
|
+
method: "POST",
|
|
3777
|
+
headers: { "Content-Type": "application/json" },
|
|
3778
|
+
body: JSON.stringify({ deviceCode, hostname: hostname() })
|
|
3779
|
+
});
|
|
3780
|
+
const data = await tokenResponse.json();
|
|
3781
|
+
if (tokenResponse.ok && data.token) {
|
|
3782
|
+
writeConfig({ token: data.token, email: data.email, appUrl });
|
|
3783
|
+
const configPath = getConfigPath();
|
|
3784
|
+
return { success: true, email: data.email, configPath };
|
|
3785
|
+
}
|
|
3786
|
+
if (data.error === "authorization_pending") continue;
|
|
3787
|
+
if (data.error === "slow_down") {
|
|
3788
|
+
pollInterval += 5e3;
|
|
3789
|
+
continue;
|
|
3790
|
+
}
|
|
3791
|
+
return { success: false, error: data.error || "Authorization failed" };
|
|
3792
|
+
}
|
|
3793
|
+
return {
|
|
3794
|
+
success: false,
|
|
3795
|
+
error: "Authorization timed out. Please try again."
|
|
3796
|
+
};
|
|
4311
3797
|
}
|
|
4312
3798
|
|
|
4313
3799
|
// src/commands/logout/index.ts
|
|
@@ -4331,7 +3817,10 @@ async function logoutCommand(options) {
|
|
|
4331
3817
|
|
|
4332
3818
|
// src/commands/auth/index.ts
|
|
4333
3819
|
async function whoami() {
|
|
4334
|
-
|
|
3820
|
+
const client = createApiClient();
|
|
3821
|
+
const { data, error } = await client.GET("/api/auth/whoami");
|
|
3822
|
+
if (error) throw new Error(error.error?.message || "Not authenticated");
|
|
3823
|
+
return data;
|
|
4335
3824
|
}
|
|
4336
3825
|
async function whoamiCommand(options) {
|
|
4337
3826
|
const logger2 = createCommandLogger(options);
|
|
@@ -4353,28 +3842,49 @@ async function whoamiCommand(options) {
|
|
|
4353
3842
|
|
|
4354
3843
|
// src/commands/projects/index.ts
|
|
4355
3844
|
async function listProjects() {
|
|
4356
|
-
|
|
3845
|
+
const client = createApiClient();
|
|
3846
|
+
const { data, error } = await client.GET("/api/projects");
|
|
3847
|
+
if (error) throw new Error(error.error?.message || "Failed to list projects");
|
|
3848
|
+
return data;
|
|
4357
3849
|
}
|
|
4358
3850
|
async function getProject(options = {}) {
|
|
4359
3851
|
const id = options.projectId ?? requireProjectId();
|
|
4360
|
-
|
|
3852
|
+
const client = createApiClient();
|
|
3853
|
+
const { data, error } = await client.GET("/api/projects/{projectId}", {
|
|
3854
|
+
params: { path: { projectId: id } }
|
|
3855
|
+
});
|
|
3856
|
+
if (error) throw new Error(error.error?.message || "Failed to get project");
|
|
3857
|
+
return data;
|
|
4361
3858
|
}
|
|
4362
3859
|
async function createProject(options) {
|
|
4363
|
-
|
|
4364
|
-
|
|
4365
|
-
body:
|
|
3860
|
+
const client = createApiClient();
|
|
3861
|
+
const { data, error } = await client.POST("/api/projects", {
|
|
3862
|
+
body: { name: options.name }
|
|
4366
3863
|
});
|
|
3864
|
+
if (error)
|
|
3865
|
+
throw new Error(error.error?.message || "Failed to create project");
|
|
3866
|
+
return data;
|
|
4367
3867
|
}
|
|
4368
3868
|
async function updateProject(options) {
|
|
4369
3869
|
const id = options.projectId ?? requireProjectId();
|
|
4370
|
-
|
|
4371
|
-
|
|
4372
|
-
|
|
3870
|
+
const client = createApiClient();
|
|
3871
|
+
const { data, error } = await client.PATCH("/api/projects/{projectId}", {
|
|
3872
|
+
params: { path: { projectId: id } },
|
|
3873
|
+
body: { name: options.name }
|
|
4373
3874
|
});
|
|
3875
|
+
if (error)
|
|
3876
|
+
throw new Error(error.error?.message || "Failed to update project");
|
|
3877
|
+
return data;
|
|
4374
3878
|
}
|
|
4375
3879
|
async function deleteProject(options = {}) {
|
|
4376
3880
|
const id = options.projectId ?? requireProjectId();
|
|
4377
|
-
|
|
3881
|
+
const client = createApiClient();
|
|
3882
|
+
const { data, error } = await client.DELETE("/api/projects/{projectId}", {
|
|
3883
|
+
params: { path: { projectId: id } }
|
|
3884
|
+
});
|
|
3885
|
+
if (error)
|
|
3886
|
+
throw new Error(error.error?.message || "Failed to delete project");
|
|
3887
|
+
return data ?? { success: true };
|
|
4378
3888
|
}
|
|
4379
3889
|
async function handleResult(fn, options) {
|
|
4380
3890
|
const logger2 = createCommandLogger(options);
|
|
@@ -4421,47 +3931,85 @@ async function deleteProjectCommand(projectId, options) {
|
|
|
4421
3931
|
// src/commands/flows/index.ts
|
|
4422
3932
|
async function listFlows(options = {}) {
|
|
4423
3933
|
const id = options.projectId ?? requireProjectId();
|
|
4424
|
-
const
|
|
4425
|
-
|
|
4426
|
-
|
|
4427
|
-
|
|
4428
|
-
|
|
4429
|
-
|
|
3934
|
+
const client = createApiClient();
|
|
3935
|
+
const { data, error } = await client.GET("/api/projects/{projectId}/flows", {
|
|
3936
|
+
params: {
|
|
3937
|
+
path: { projectId: id },
|
|
3938
|
+
query: {
|
|
3939
|
+
sort: options.sort,
|
|
3940
|
+
order: options.order,
|
|
3941
|
+
include_deleted: options.includeDeleted ? "true" : void 0
|
|
3942
|
+
}
|
|
3943
|
+
}
|
|
3944
|
+
});
|
|
3945
|
+
if (error) throw new Error(error.error?.message || "Failed to list flows");
|
|
3946
|
+
return data;
|
|
4430
3947
|
}
|
|
4431
3948
|
async function getFlow(options) {
|
|
4432
3949
|
const id = options.projectId ?? requireProjectId();
|
|
4433
|
-
|
|
3950
|
+
const client = createApiClient();
|
|
3951
|
+
const { data, error } = await client.GET(
|
|
3952
|
+
"/api/projects/{projectId}/flows/{flowId}",
|
|
3953
|
+
{
|
|
3954
|
+
params: { path: { projectId: id, flowId: options.flowId } }
|
|
3955
|
+
}
|
|
3956
|
+
);
|
|
3957
|
+
if (error) throw new Error(error.error?.message || "Failed to get flow");
|
|
3958
|
+
return data;
|
|
4434
3959
|
}
|
|
4435
3960
|
async function createFlow(options) {
|
|
4436
3961
|
const id = options.projectId ?? requireProjectId();
|
|
4437
|
-
|
|
4438
|
-
|
|
4439
|
-
|
|
3962
|
+
const client = createApiClient();
|
|
3963
|
+
const { data, error } = await client.POST("/api/projects/{projectId}/flows", {
|
|
3964
|
+
params: { path: { projectId: id } },
|
|
3965
|
+
// Content is user-provided JSON; server validates the full schema
|
|
3966
|
+
body: { name: options.name, content: options.content }
|
|
4440
3967
|
});
|
|
3968
|
+
if (error) throw new Error(error.error?.message || "Failed to create flow");
|
|
3969
|
+
return data;
|
|
4441
3970
|
}
|
|
4442
3971
|
async function updateFlow(options) {
|
|
4443
3972
|
const id = options.projectId ?? requireProjectId();
|
|
3973
|
+
const client = createApiClient();
|
|
4444
3974
|
const body = {};
|
|
4445
3975
|
if (options.name !== void 0) body.name = options.name;
|
|
4446
3976
|
if (options.content !== void 0) body.content = options.content;
|
|
4447
|
-
|
|
4448
|
-
|
|
4449
|
-
|
|
4450
|
-
|
|
3977
|
+
const { data, error } = await client.PATCH(
|
|
3978
|
+
"/api/projects/{projectId}/flows/{flowId}",
|
|
3979
|
+
{
|
|
3980
|
+
params: { path: { projectId: id, flowId: options.flowId } },
|
|
3981
|
+
// Dynamically constructed body; server validates the full schema
|
|
3982
|
+
body
|
|
3983
|
+
}
|
|
3984
|
+
);
|
|
3985
|
+
if (error) throw new Error(error.error?.message || "Failed to update flow");
|
|
3986
|
+
return data;
|
|
4451
3987
|
}
|
|
4452
3988
|
async function deleteFlow(options) {
|
|
4453
3989
|
const id = options.projectId ?? requireProjectId();
|
|
4454
|
-
|
|
4455
|
-
|
|
4456
|
-
|
|
3990
|
+
const client = createApiClient();
|
|
3991
|
+
const { data, error } = await client.DELETE(
|
|
3992
|
+
"/api/projects/{projectId}/flows/{flowId}",
|
|
3993
|
+
{
|
|
3994
|
+
params: { path: { projectId: id, flowId: options.flowId } }
|
|
3995
|
+
}
|
|
3996
|
+
);
|
|
3997
|
+
if (error) throw new Error(error.error?.message || "Failed to delete flow");
|
|
3998
|
+
return data ?? { success: true };
|
|
4457
3999
|
}
|
|
4458
4000
|
async function duplicateFlow(options) {
|
|
4459
4001
|
const id = options.projectId ?? requireProjectId();
|
|
4460
|
-
const
|
|
4461
|
-
|
|
4462
|
-
|
|
4463
|
-
|
|
4464
|
-
|
|
4002
|
+
const client = createApiClient();
|
|
4003
|
+
const { data, error } = await client.POST(
|
|
4004
|
+
"/api/projects/{projectId}/flows/{flowId}/duplicate",
|
|
4005
|
+
{
|
|
4006
|
+
params: { path: { projectId: id, flowId: options.flowId } },
|
|
4007
|
+
body: { name: options.name }
|
|
4008
|
+
}
|
|
4009
|
+
);
|
|
4010
|
+
if (error)
|
|
4011
|
+
throw new Error(error.error?.message || "Failed to duplicate flow");
|
|
4012
|
+
return data;
|
|
4465
4013
|
}
|
|
4466
4014
|
async function handleResult2(fn, options) {
|
|
4467
4015
|
const logger2 = createCommandLogger(options);
|
|
@@ -4685,10 +4233,10 @@ runCmd.command("serve [file]").description(
|
|
|
4685
4233
|
registerCacheCommand(program);
|
|
4686
4234
|
program.parse();
|
|
4687
4235
|
export {
|
|
4688
|
-
apiRequest,
|
|
4689
|
-
authenticatedFetch,
|
|
4690
4236
|
bundle,
|
|
4691
4237
|
bundleCommand,
|
|
4238
|
+
bundleRemote,
|
|
4239
|
+
createApiClient,
|
|
4692
4240
|
createFlow,
|
|
4693
4241
|
createProject,
|
|
4694
4242
|
deleteFlow,
|