@walkeros/cli 4.7.0 → 4.7.1-next-1791015692826
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 +27 -0
- package/dist/cli.js +2425 -1379
- package/dist/examples/flow-complete.json +22 -22
- package/dist/examples/index.js +22 -22
- package/dist/examples/index.js.map +1 -1
- package/dist/index.d.ts +1397 -10258
- package/dist/index.js +1209 -453
- package/dist/index.js.map +1 -1
- package/examples/flow-complete.json +22 -22
- package/openapi/client-operations.json +250 -0
- package/openapi/spec.json +4743 -16593
- package/package.json +33 -31
package/dist/index.js
CHANGED
|
@@ -4,6 +4,9 @@ var __export = (target, all) => {
|
|
|
4
4
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
5
5
|
};
|
|
6
6
|
|
|
7
|
+
// <define:__CLIENT_OPERATION_DIGESTS__>
|
|
8
|
+
var define_CLIENT_OPERATION_DIGESTS_default = [{ op: "GET /api/auth/whoami", usedBy: ["mcp auth", "walkeros auth login", "walkeros auth whoami"], digest: "f8287550f3ac65aa5b290875220f06dd3f48d607ed489b9f0a8f704d3f8f5cfd" }, { op: "POST /api/feedback", usedBy: ["mcp feedback", "walkeros feedback"], digest: "7417108c6ea8d60904b715dfedc1d8b9b597834f7d427df6b9226b36e5eef963" }, { op: "GET /api/health", usedBy: ["mcp diagnostics", "walkeros diagnostics"], digest: "2b3c0883edf4048aca77f4222247929b9045db33d06729502cb5021929d04156" }, { op: "POST /api/oauth/device_authorization", usedBy: ["mcp auth", "walkeros auth login"], digest: "a3e744775b93e7f50ea4021f8a027e656bb90e6f2358c65a35e4c45e16ac3fdd" }, { op: "POST /api/oauth/revoke", usedBy: ["mcp auth", "walkeros auth logout"], digest: "dbc453faaaa748d1129473ccda7b26a4e3267d67c25a8a9fc1da0068837fe154" }, { op: "POST /api/oauth/token", usedBy: ["@walkeros/cli resolveAccessToken", "mcp auth", "walkeros auth login"], digest: "16f5a3146c0a3fff703122a5ff25446bad07a6c37069a9e9a6db6925daa036a0" }, { op: "GET /api/openapi.json", usedBy: ["mcp diagnostics", "mcp resource walkeros://reference/openapi", "walkeros diagnostics"], digest: "dbf34e575af8f757d9a0f967c4565968d1a2d64b57a717fc65c8f81692099f0a" }, { op: "GET /api/packages", usedBy: ["mcp package_search", "mcp resource walkeros://reference/packages", "mcp resource walkeros://schema/{packageName}"], digest: "d9c713eea791e8bae3c606bcd1f0209db2c7050a39b18e96f7d913b7d0752e19" }, { op: "GET /api/projects", usedBy: ["mcp flow_manage", "mcp project_manage", "walkeros projects list"], digest: "1e65fca4cb31ccfc10b9835595ac4ee1f69bd6da14127bcc31d62616dfba7281" }, { op: "POST /api/projects", usedBy: ["mcp project_manage", "walkeros projects create"], digest: "3ab6d76c78d4433f0e0ab85a0a23753c7065bc232bfb30b7cee616a3aef8bec5" }, { op: "DELETE /api/projects/{projectId}", usedBy: ["mcp project_manage", "walkeros projects delete"], digest: "9f725b18812327c57cfbf8d8ed0139353c60ed2eb34024618e1760c2765889ca" }, { op: "GET /api/projects/{projectId}", usedBy: ["mcp project_manage", "walkeros projects get"], digest: "535d11026c7b7ff3b59512c0f68ddeb4e73104d4adab143351c7f9fa1ece6e78" }, { op: "PATCH /api/projects/{projectId}", usedBy: ["mcp project_manage", "walkeros projects update"], digest: "d15d7756dae06372328b43891a89dc839e6eb8587896d19999ff49ec8aa1d19b" }, { op: "GET /api/projects/{projectId}/deployments", usedBy: ["mcp deploy_manage", "walkeros deploy list"], digest: "2b3cc07e4cf1f739f7321b5bf157b91ac300205286a48c4f29dd11269d00f2c0" }, { op: "POST /api/projects/{projectId}/deployments", usedBy: ["walkeros deploy create"], digest: "fa0bcad018a21213f473bd058ef90975b50fd3f978340e36c61acf1d609bab95" }, { op: "DELETE /api/projects/{projectId}/deployments/{deploymentId}", usedBy: ["mcp deploy_manage", "walkeros deploy delete"], digest: "ce119e1743ecfdda590f7fae6bfc5a094c387efcbdaac6eaf9b2b7b0fffac58e" }, { op: "GET /api/projects/{projectId}/deployments/{deploymentId}", usedBy: ["mcp deploy_manage", "walkeros deploy status"], digest: "089bd54697005003c9fb256f853dad2e4431d62cbaa2805d311c6837e498ba2b" }, { op: "GET /api/projects/{projectId}/deployments/{deploymentId}/stream", usedBy: ["mcp deploy_manage", "walkeros deploy start"], digest: "cf27b0c148cfeb3b772f150a9de0359540643b3eeaff8dc373cb865557e24a82" }, { op: "GET /api/projects/{projectId}/flows", usedBy: ["mcp flow_manage", "walkeros flows list"], digest: "ecb58ddbde3808a161bee04d333d4e976e86f46505bacc6d571050a45c6c9ee8" }, { op: "POST /api/projects/{projectId}/flows", usedBy: ["mcp flow_manage", "walkeros flows create"], digest: "bcae723b986165cab63933eda1814a9da984cdfada8fe1a0c9cc01d4554d8372" }, { op: "DELETE /api/projects/{projectId}/flows/{flowId}", usedBy: ["mcp flow_manage", "walkeros flows delete"], digest: "1f164466f6b6058b79e787b0234b42d61274431dd6e29cb8acc23c2706218278" }, { op: "GET /api/projects/{projectId}/flows/{flowId}", usedBy: ["mcp deploy_manage", "mcp flow_bundle", "mcp flow_load", "mcp flow_manage", "mcp flow_simulate", "mcp observe_session", "walkeros deploy create", "walkeros deploy start", "walkeros flows get", "walkeros observe start", "walkeros previews create"], digest: "a8fc246e9b179a7becce56221be27aae649f471aebb639eda34b215c926f21dd" }, { op: "PATCH /api/projects/{projectId}/flows/{flowId}", usedBy: ["mcp flow_manage", "walkeros flows update"], digest: "f9e59060ab31184a3b5906c3346479616101f7793c7a00c35649f08d2f5d6a32" }, { op: "GET /api/projects/{projectId}/flows/{flowId}/deploy", usedBy: ["@walkeros/cli getDeployment"], digest: "8d9229fc0d884a75b1faf06877494e4dd5fa8c77affc7a7bb58d559fbd0c8646" }, { op: "POST /api/projects/{projectId}/flows/{flowId}/deploy", usedBy: ["mcp deploy_manage", "walkeros deploy start"], digest: "ea6922423f14dde427cf37f13f07e3f5f783358ff23fd7464925da068838068e" }, { op: "POST /api/projects/{projectId}/flows/{flowId}/duplicate", usedBy: ["mcp flow_manage", "walkeros flows duplicate"], digest: "b9111138d427419eea46ed590a301373a4c641b19d90ab1566891f5aaaadc231" }, { op: "GET /api/projects/{projectId}/flows/{flowId}/journeys", usedBy: ["mcp flow_manage", "mcp observe_journeys", "mcp observe_session"], digest: "78377e4a5b4b1e4dce9f94813bd3484e78b9520e57c712f963ef98c42516b01c" }, { op: "POST /api/projects/{projectId}/flows/{flowId}/observe-sessions", usedBy: ["mcp observe_session", "walkeros observe start"], digest: "5620b4826736b3aff1c80412d9861d5286304957df59d241e9adff6d101bb032" }, { op: "DELETE /api/projects/{projectId}/flows/{flowId}/observe-sessions/{sessionId}", usedBy: ["mcp observe_session"], digest: "9bdc90811f98a22030ee33bb24e2f270b64733b81e3e4dd3d16cd00620dafb44" }, { op: "GET /api/projects/{projectId}/flows/{flowId}/observe-sessions/{sessionId}", usedBy: ["mcp observe_session", "walkeros observe start"], digest: "ab5e8a2b908391c701c9e0b73813f1eb3bfa5b2a82e82b7009b2559467352491" }, { op: "POST /api/projects/{projectId}/flows/{flowId}/observe-sessions/{sessionId}/heartbeat", usedBy: ["walkeros observe start"], digest: "2b0b74a466c643aac87226c8154a530ce55deb5409a4fb65a4ef9b8aa182cbc7" }, { op: "GET /api/projects/{projectId}/flows/{flowId}/previews", usedBy: ["mcp flow_manage", "walkeros previews list"], digest: "ef72ef8b90676c59c626763f120d6a81910b29e4384f0ac8174f7e12420007c2" }, { op: "POST /api/projects/{projectId}/flows/{flowId}/previews", usedBy: ["mcp flow_manage", "walkeros previews create"], digest: "7239dc554d11983386108825087aa45eb4d0bd38eae87dbac376e68e724c6a8f" }, { op: "DELETE /api/projects/{projectId}/flows/{flowId}/previews/{previewId}", usedBy: ["mcp flow_manage", "walkeros previews delete"], digest: "de9be2358920517321c4e2c59c9ce59f174be0382596037ce36f987233689e51" }, { op: "GET /api/projects/{projectId}/flows/{flowId}/previews/{previewId}", usedBy: ["mcp flow_manage", "walkeros previews get"], digest: "4dbaa7000600aa12d45388511192dabdcd910fad9acedd802fdc68efea4e7bc7" }, { op: "POST /api/projects/{projectId}/flows/{flowId}/previews/{previewId}/grant", usedBy: ["mcp flow_manage", "walkeros previews create"], digest: "4cf5c7ea9363935bd978f858e4bb058c6dd64bb2763cefac9ce07da248605e7f" }, { op: "GET /api/projects/{projectId}/flows/{flowId}/releases", usedBy: ["mcp hub_manage"], digest: "c6ac90c93e07429b53c506292ceda03bfb8873686db76e422f5eed4638f4bee7" }, { op: "PUT /api/projects/{projectId}/flows/{flowId}/releases/annotations", usedBy: ["mcp hub_manage"], digest: "084f638f024a578ab2f401839f10f9554e6d2100ba7d67f1ab2be560616bd044" }, { op: "GET /api/projects/{projectId}/flows/{flowId}/releases/step-history", usedBy: ["mcp hub_manage"], digest: "a0d051814f7e8cc39e00592c16bc92a1afae0b58cd71b9b98ab6c85da4dd04e4" }, { op: "GET /api/projects/{projectId}/flows/{flowId}/releases/{versionId}", usedBy: ["mcp hub_manage"], digest: "d429b1564ca64148c5844e799c5dafc5d864fcf94df62f51174c3825db6a3463" }, { op: "GET /api/projects/{projectId}/flows/{flowId}/secrets", usedBy: ["mcp secret_manage"], digest: "19629983472c4e46b6c97fc8700b35549f38725fd4d7a5f59ddacd6a7bcfc8f2" }, { op: "POST /api/projects/{projectId}/flows/{flowId}/secrets", usedBy: ["mcp secret_manage"], digest: "b9407ce8584d147f84acf2562f1eb7c63c35e7ed93bd275d8c3c2ba3c4a1a8e3" }, { op: "GET /api/projects/{projectId}/flows/{flowId}/secrets/values", usedBy: ["runner"], digest: "0c02c86b0576047e8d986c2829212fef4e7eea5791250188619244bfbcdfb4aa" }, { op: "DELETE /api/projects/{projectId}/flows/{flowId}/secrets/{secretId}", usedBy: ["mcp secret_manage"], digest: "b744bcdb73b204d9aa4e4d3f846552a4154601df27c4fe18045bdb8a09624b84" }, { op: "PUT /api/projects/{projectId}/flows/{flowId}/secrets/{secretId}", usedBy: ["mcp secret_manage"], digest: "5b94004e066746ee7a83b90477db9d2a343361705c2e158df85d74e47085a46a" }, { op: "GET /api/projects/{projectId}/flows/{flowId}/settings/{settingsId}/deploy", usedBy: ["@walkeros/cli getDeployment"], digest: "0ad85a2494f22e9863362a7137d721d970b87ff60fdb41727a76cb4f590c83bc" }, { op: "POST /api/projects/{projectId}/flows/{flowId}/settings/{settingsId}/deploy", usedBy: ["mcp deploy_manage", "walkeros deploy start"], digest: "b6506c543c7e755592b5a6671016c4bae3b3e41cd76c28852297413e1a412e46" }, { op: "GET /api/projects/{projectId}/flows/{flowId}/threads", usedBy: ["mcp hub_manage"], digest: "ae0b8185fa74ba12d99eedacedb53e5801d7485cdf7b1c382334371454f8c323" }, { op: "POST /api/projects/{projectId}/flows/{flowId}/threads", usedBy: ["mcp hub_manage"], digest: "0ee52914274f52641a08b4c2d9da774c971d214929b43abee85d5e657b209144" }, { op: "POST /api/projects/{projectId}/flows/{flowId}/threads/{threadId}/messages", usedBy: ["mcp hub_manage"], digest: "28d8e964962b03c016c909111be0ce570df9bf43f89f0ab1c74b6dd65503eec1" }, { op: "GET /api/projects/{projectId}/frames", usedBy: ["mcp frame_manage"], digest: "c1cecd6354a7071418e709ecbf925a6ae14bb0099459bac786f35877108e29fd" }, { op: "GET /api/projects/{projectId}/frames/{frameId}", usedBy: ["mcp frame_manage"], digest: "98e3373cb23c9851280c505239ff960088d89bea9d922787da812bd7a59d104e" }, { op: "GET /api/projects/{projectId}/knowledge", usedBy: ["mcp hub_manage"], digest: "ca52e4593757c4fede25c41c3bb95e9a3b7476106549752b756860fc35abd1f1" }, { op: "POST /api/projects/{projectId}/runners/heartbeat", usedBy: ["runner"], digest: "96546fffffb32b66db7c5238daa2ba8f549d976f5ffcab2befa639e2eb1df0e1" }, { op: "POST /api/telemetry", usedBy: ["@walkeros/cli telemetry"], digest: "d119e16315ff9df09160d8b36ebc78dec089cb2a726f4a8fd77ff5b693999667" }];
|
|
9
|
+
|
|
7
10
|
// src/commands/bundle/index.ts
|
|
8
11
|
import path15 from "path";
|
|
9
12
|
import fs16 from "fs-extra";
|
|
@@ -265,16 +268,425 @@ async function withConfigLock(fn) {
|
|
|
265
268
|
|
|
266
269
|
// src/core/oauth-client.ts
|
|
267
270
|
import { z } from "zod";
|
|
271
|
+
|
|
272
|
+
// src/core/client-context.ts
|
|
273
|
+
var context;
|
|
274
|
+
function setClientContext(input) {
|
|
275
|
+
const envType = process.env.WALKEROS_CLIENT_TYPE;
|
|
276
|
+
const type = envType ?? input.type ?? "cli";
|
|
277
|
+
context = { type, version: input.version };
|
|
278
|
+
}
|
|
279
|
+
function getClientContext() {
|
|
280
|
+
return context;
|
|
281
|
+
}
|
|
282
|
+
function resetClientContext() {
|
|
283
|
+
context = void 0;
|
|
284
|
+
}
|
|
285
|
+
function clientContextHeaders() {
|
|
286
|
+
if (!context) return {};
|
|
287
|
+
return {
|
|
288
|
+
"User-Agent": `walkeros-${context.type}/${context.version}`,
|
|
289
|
+
"X-WalkerOS-Client": context.type,
|
|
290
|
+
"X-WalkerOS-Client-Version": context.version
|
|
291
|
+
};
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
// src/core/openapi-subset.ts
|
|
295
|
+
import { createHash } from "crypto";
|
|
296
|
+
var HTTP_METHODS = /* @__PURE__ */ new Set([
|
|
297
|
+
"get",
|
|
298
|
+
"put",
|
|
299
|
+
"post",
|
|
300
|
+
"delete",
|
|
301
|
+
"options",
|
|
302
|
+
"head",
|
|
303
|
+
"patch",
|
|
304
|
+
"trace"
|
|
305
|
+
]);
|
|
306
|
+
var DOC_KEYWORDS = /* @__PURE__ */ new Set([
|
|
307
|
+
"description",
|
|
308
|
+
"summary",
|
|
309
|
+
"title",
|
|
310
|
+
"example",
|
|
311
|
+
"examples",
|
|
312
|
+
"externalDocs",
|
|
313
|
+
"tags"
|
|
314
|
+
]);
|
|
315
|
+
var VERBATIM_KEYWORDS = /* @__PURE__ */ new Set([
|
|
316
|
+
"enum",
|
|
317
|
+
"const",
|
|
318
|
+
"default",
|
|
319
|
+
"required",
|
|
320
|
+
"security",
|
|
321
|
+
"mapping",
|
|
322
|
+
"scopes"
|
|
323
|
+
]);
|
|
324
|
+
var NAME_MAPS = /* @__PURE__ */ new Set([
|
|
325
|
+
"properties",
|
|
326
|
+
"patternProperties",
|
|
327
|
+
"dependentSchemas",
|
|
328
|
+
"$defs",
|
|
329
|
+
"definitions",
|
|
330
|
+
"paths",
|
|
331
|
+
"webhooks",
|
|
332
|
+
"schemas",
|
|
333
|
+
"responses",
|
|
334
|
+
"parameters",
|
|
335
|
+
"requestBodies",
|
|
336
|
+
"headers",
|
|
337
|
+
"securitySchemes",
|
|
338
|
+
"links",
|
|
339
|
+
"callbacks",
|
|
340
|
+
"pathItems",
|
|
341
|
+
"content",
|
|
342
|
+
"encoding",
|
|
343
|
+
"variables"
|
|
344
|
+
]);
|
|
345
|
+
var DROPPED_TOP_LEVEL = /* @__PURE__ */ new Set([
|
|
346
|
+
"tags",
|
|
347
|
+
"webhooks",
|
|
348
|
+
"externalDocs"
|
|
349
|
+
]);
|
|
350
|
+
var NOTHING_KEPT = /* @__PURE__ */ new Set();
|
|
351
|
+
function isRecord(value) {
|
|
352
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
353
|
+
}
|
|
354
|
+
function isVerbatim(key) {
|
|
355
|
+
return VERBATIM_KEYWORDS.has(key) || key.startsWith("x-");
|
|
356
|
+
}
|
|
357
|
+
function canonicalize(value) {
|
|
358
|
+
if (Array.isArray(value)) return value.map(canonicalize);
|
|
359
|
+
if (isRecord(value)) {
|
|
360
|
+
const result = {};
|
|
361
|
+
for (const key of Object.keys(value).sort()) {
|
|
362
|
+
result[key] = canonicalize(value[key]);
|
|
363
|
+
}
|
|
364
|
+
return result;
|
|
365
|
+
}
|
|
366
|
+
return value;
|
|
367
|
+
}
|
|
368
|
+
function parseOperation(op) {
|
|
369
|
+
const space = op.indexOf(" ");
|
|
370
|
+
const method = space > 0 ? op.slice(0, space).toLowerCase() : "";
|
|
371
|
+
const path23 = op.slice(space + 1);
|
|
372
|
+
if (!HTTP_METHODS.has(method) || !path23.startsWith("/")) {
|
|
373
|
+
throw new Error(`invalid operation: ${op}`);
|
|
374
|
+
}
|
|
375
|
+
return { method, path: path23 };
|
|
376
|
+
}
|
|
377
|
+
function hasOperation(doc, op) {
|
|
378
|
+
const { method, path: path23 } = parseOperation(op);
|
|
379
|
+
if (!isRecord(doc) || !isRecord(doc.paths)) return false;
|
|
380
|
+
const item = doc.paths[path23];
|
|
381
|
+
return isRecord(item) && isRecord(item[method]);
|
|
382
|
+
}
|
|
383
|
+
function stripNode(node) {
|
|
384
|
+
if (Array.isArray(node)) return node.map(stripNode);
|
|
385
|
+
if (!isRecord(node)) return node;
|
|
386
|
+
return stripObject(node, NOTHING_KEPT);
|
|
387
|
+
}
|
|
388
|
+
function stripObject(node, kept) {
|
|
389
|
+
const out = {};
|
|
390
|
+
for (const [key, value] of Object.entries(node)) {
|
|
391
|
+
if (kept.has(key) || isVerbatim(key)) out[key] = value;
|
|
392
|
+
else if (DOC_KEYWORDS.has(key)) continue;
|
|
393
|
+
else if (NAME_MAPS.has(key) && isRecord(value)) {
|
|
394
|
+
out[key] = stripNameMap(value, key === "responses");
|
|
395
|
+
} else out[key] = stripNode(value);
|
|
396
|
+
}
|
|
397
|
+
return out;
|
|
398
|
+
}
|
|
399
|
+
function stripNameMap(map, responses) {
|
|
400
|
+
const out = {};
|
|
401
|
+
for (const [name, node] of Object.entries(map)) {
|
|
402
|
+
out[name] = responses ? stripResponse(node) : stripNode(node);
|
|
403
|
+
}
|
|
404
|
+
return out;
|
|
405
|
+
}
|
|
406
|
+
function stripResponse(node) {
|
|
407
|
+
if (!isRecord(node) || typeof node.$ref === "string") return stripNode(node);
|
|
408
|
+
return { description: "", ...stripObject(node, NOTHING_KEPT) };
|
|
409
|
+
}
|
|
410
|
+
function stripDocument(doc) {
|
|
411
|
+
const out = {};
|
|
412
|
+
for (const [key, value] of Object.entries(doc)) {
|
|
413
|
+
if (DROPPED_TOP_LEVEL.has(key)) continue;
|
|
414
|
+
if (key === "info" && isRecord(value)) {
|
|
415
|
+
out.info = stripObject(value, /* @__PURE__ */ new Set(["title", "version"]));
|
|
416
|
+
} else if (isVerbatim(key)) out[key] = value;
|
|
417
|
+
else if (NAME_MAPS.has(key) && isRecord(value)) {
|
|
418
|
+
out[key] = stripNameMap(value, false);
|
|
419
|
+
} else out[key] = stripNode(value);
|
|
420
|
+
}
|
|
421
|
+
return out;
|
|
422
|
+
}
|
|
423
|
+
function collectRefs(node, refs) {
|
|
424
|
+
if (Array.isArray(node)) {
|
|
425
|
+
for (const item of node) collectRefs(item, refs);
|
|
426
|
+
return;
|
|
427
|
+
}
|
|
428
|
+
if (!isRecord(node)) return;
|
|
429
|
+
for (const [key, value] of Object.entries(node)) {
|
|
430
|
+
if (key === "$ref" && typeof value === "string") refs.add(value);
|
|
431
|
+
else if (NAME_MAPS.has(key) && isRecord(value)) {
|
|
432
|
+
for (const named of Object.values(value)) collectRefs(named, refs);
|
|
433
|
+
} else if (key === "discriminator" && isRecord(value)) {
|
|
434
|
+
const mapping = isRecord(value.mapping) ? value.mapping : {};
|
|
435
|
+
for (const target of Object.values(mapping)) {
|
|
436
|
+
if (typeof target === "string") refs.add(target);
|
|
437
|
+
}
|
|
438
|
+
} else if (!isVerbatim(key)) collectRefs(value, refs);
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
function componentOf(ref) {
|
|
442
|
+
const parts = ref.startsWith("#/") ? ref.slice(2).split("/").map((part) => part.replace(/~1/g, "/").replace(/~0/g, "~")) : [];
|
|
443
|
+
if (parts.length < 3 || parts[0] !== "components") {
|
|
444
|
+
throw new Error(`unsupported $ref: ${ref}`);
|
|
445
|
+
}
|
|
446
|
+
return { section: parts[1], name: parts[2] };
|
|
447
|
+
}
|
|
448
|
+
function pruneComponents(components, roots) {
|
|
449
|
+
const referenced = /* @__PURE__ */ new Map();
|
|
450
|
+
const pending = [];
|
|
451
|
+
const queue = (node) => {
|
|
452
|
+
const refs = /* @__PURE__ */ new Set();
|
|
453
|
+
collectRefs(node, refs);
|
|
454
|
+
pending.push(...refs);
|
|
455
|
+
};
|
|
456
|
+
for (const root of roots) queue(root);
|
|
457
|
+
if (isRecord(components.securitySchemes)) queue(components.securitySchemes);
|
|
458
|
+
for (let ref = pending.pop(); ref !== void 0; ref = pending.pop()) {
|
|
459
|
+
const { section, name } = componentOf(ref);
|
|
460
|
+
const names = referenced.get(section) ?? /* @__PURE__ */ new Set();
|
|
461
|
+
if (names.has(name)) continue;
|
|
462
|
+
const entries = components[section];
|
|
463
|
+
if (!isRecord(entries) || !(name in entries)) {
|
|
464
|
+
throw new Error(`$ref target not in input: ${ref}`);
|
|
465
|
+
}
|
|
466
|
+
names.add(name);
|
|
467
|
+
referenced.set(section, names);
|
|
468
|
+
queue(entries[name]);
|
|
469
|
+
}
|
|
470
|
+
const out = {};
|
|
471
|
+
for (const [section, entries] of Object.entries(components)) {
|
|
472
|
+
if (!isRecord(entries)) continue;
|
|
473
|
+
if (section === "securitySchemes") {
|
|
474
|
+
out[section] = entries;
|
|
475
|
+
continue;
|
|
476
|
+
}
|
|
477
|
+
const names = referenced.get(section);
|
|
478
|
+
if (!names) continue;
|
|
479
|
+
const kept = {};
|
|
480
|
+
for (const [name, node] of Object.entries(entries)) {
|
|
481
|
+
if (names.has(name)) kept[name] = node;
|
|
482
|
+
}
|
|
483
|
+
out[section] = kept;
|
|
484
|
+
}
|
|
485
|
+
return Object.keys(out).length > 0 ? out : void 0;
|
|
486
|
+
}
|
|
487
|
+
function pruneToOperations(doc, ops) {
|
|
488
|
+
if (!isRecord(doc) || !isRecord(doc.paths)) {
|
|
489
|
+
throw new Error("input is not an OpenAPI document with paths");
|
|
490
|
+
}
|
|
491
|
+
for (const op of ops) {
|
|
492
|
+
if (!hasOperation(doc, op)) {
|
|
493
|
+
throw new Error(`manifest operation not in input: ${op}`);
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
const listed = new Set(
|
|
497
|
+
ops.map((op) => {
|
|
498
|
+
const { method, path: path23 } = parseOperation(op);
|
|
499
|
+
return `${method} ${path23}`;
|
|
500
|
+
})
|
|
501
|
+
);
|
|
502
|
+
const stripped = stripDocument(doc);
|
|
503
|
+
const allPaths = isRecord(stripped.paths) ? stripped.paths : {};
|
|
504
|
+
const paths = {};
|
|
505
|
+
for (const [path23, item] of Object.entries(allPaths)) {
|
|
506
|
+
if (!isRecord(item)) continue;
|
|
507
|
+
const kept = {};
|
|
508
|
+
let operations = 0;
|
|
509
|
+
for (const [key, value] of Object.entries(item)) {
|
|
510
|
+
if (!HTTP_METHODS.has(key)) kept[key] = value;
|
|
511
|
+
else if (listed.has(`${key} ${path23}`)) {
|
|
512
|
+
kept[key] = value;
|
|
513
|
+
operations += 1;
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
if (operations > 0) paths[path23] = kept;
|
|
517
|
+
}
|
|
518
|
+
const out = {};
|
|
519
|
+
const roots = [];
|
|
520
|
+
for (const [key, value] of Object.entries(stripped)) {
|
|
521
|
+
if (key === "components") continue;
|
|
522
|
+
out[key] = key === "paths" ? paths : value;
|
|
523
|
+
roots.push(out[key]);
|
|
524
|
+
}
|
|
525
|
+
if (isRecord(stripped.components)) {
|
|
526
|
+
const components = pruneComponents(stripped.components, roots);
|
|
527
|
+
if (components) out.components = components;
|
|
528
|
+
}
|
|
529
|
+
return out;
|
|
530
|
+
}
|
|
531
|
+
function resolveRef(doc, ref) {
|
|
532
|
+
const { section, name } = componentOf(ref);
|
|
533
|
+
const components = isRecord(doc.components) ? doc.components : {};
|
|
534
|
+
const entries = components[section];
|
|
535
|
+
return isRecord(entries) ? entries[name] : void 0;
|
|
536
|
+
}
|
|
537
|
+
function inlineRefs(node, doc, stack) {
|
|
538
|
+
if (Array.isArray(node)) {
|
|
539
|
+
return node.map((item) => inlineRefs(item, doc, stack));
|
|
540
|
+
}
|
|
541
|
+
if (!isRecord(node)) return node;
|
|
542
|
+
const out = {};
|
|
543
|
+
for (const [key, value] of Object.entries(node)) {
|
|
544
|
+
if (key === "$ref" && typeof value === "string" && !stack.includes(value)) {
|
|
545
|
+
out[key] = inlineRefs(resolveRef(doc, value), doc, [...stack, value]);
|
|
546
|
+
} else if (key === "$ref") out[key] = value;
|
|
547
|
+
else if (NAME_MAPS.has(key) && isRecord(value)) {
|
|
548
|
+
const named = {};
|
|
549
|
+
for (const [name, child] of Object.entries(value)) {
|
|
550
|
+
named[name] = inlineRefs(child, doc, stack);
|
|
551
|
+
}
|
|
552
|
+
out[key] = named;
|
|
553
|
+
} else if (isVerbatim(key)) out[key] = value;
|
|
554
|
+
else out[key] = inlineRefs(value, doc, stack);
|
|
555
|
+
}
|
|
556
|
+
return out;
|
|
557
|
+
}
|
|
558
|
+
function operationDigests(doc, ops) {
|
|
559
|
+
const present = ops.filter((op) => hasOperation(doc, op));
|
|
560
|
+
const pruned = pruneToOperations(doc, present);
|
|
561
|
+
const paths = isRecord(pruned.paths) ? pruned.paths : {};
|
|
562
|
+
const digests = {};
|
|
563
|
+
for (const op of present) {
|
|
564
|
+
const { method, path: path23 } = parseOperation(op);
|
|
565
|
+
const item = paths[path23];
|
|
566
|
+
if (!isRecord(item)) continue;
|
|
567
|
+
const subtree = inlineRefs(
|
|
568
|
+
{ pathParameters: item.parameters ?? [], operation: item[method] },
|
|
569
|
+
pruned,
|
|
570
|
+
[]
|
|
571
|
+
);
|
|
572
|
+
digests[op] = createHash("sha256").update(JSON.stringify(canonicalize(subtree))).digest("hex");
|
|
573
|
+
}
|
|
574
|
+
return digests;
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
// src/core/api-request.ts
|
|
578
|
+
var DEPLOY_TOKEN_MISSING = "No authentication token available. Set WALKEROS_DEPLOY_TOKEN or run walkeros auth login.";
|
|
579
|
+
function operationTarget(op, path23, query) {
|
|
580
|
+
const template = parseOperation(op).path;
|
|
581
|
+
const filled = template.replace(/\{([^}]+)\}/g, (_match, name) => {
|
|
582
|
+
const value = path23?.[name];
|
|
583
|
+
if (value === void 0) {
|
|
584
|
+
throw new Error(`${op}: path parameter ${name} is missing`);
|
|
585
|
+
}
|
|
586
|
+
return encodeURIComponent(String(value));
|
|
587
|
+
});
|
|
588
|
+
const search = new URLSearchParams();
|
|
589
|
+
for (const [key, value] of Object.entries(query ?? {})) {
|
|
590
|
+
if (value === void 0 || value === null) continue;
|
|
591
|
+
for (const item of Array.isArray(value) ? value : [value]) {
|
|
592
|
+
search.append(key, String(item));
|
|
593
|
+
}
|
|
594
|
+
}
|
|
595
|
+
const serialized = search.toString();
|
|
596
|
+
return serialized ? `${filled}?${serialized}` : filled;
|
|
597
|
+
}
|
|
598
|
+
function hasHeader(headers, name) {
|
|
599
|
+
const lower = name.toLowerCase();
|
|
600
|
+
return Object.keys(headers).some((key) => key.toLowerCase() === lower);
|
|
601
|
+
}
|
|
602
|
+
function mergeHeaders(...layers) {
|
|
603
|
+
const merged = {};
|
|
604
|
+
for (const layer of layers) {
|
|
605
|
+
for (const [name, value] of Object.entries(layer)) {
|
|
606
|
+
const lower = name.toLowerCase();
|
|
607
|
+
for (const existing of Object.keys(merged)) {
|
|
608
|
+
if (existing.toLowerCase() === lower) delete merged[existing];
|
|
609
|
+
}
|
|
610
|
+
merged[name] = value;
|
|
611
|
+
}
|
|
612
|
+
}
|
|
613
|
+
return merged;
|
|
614
|
+
}
|
|
615
|
+
function formBody(form) {
|
|
616
|
+
const params = new URLSearchParams();
|
|
617
|
+
for (const [key, value] of Object.entries(form)) {
|
|
618
|
+
if (value !== void 0 && value !== null)
|
|
619
|
+
params.append(key, String(value));
|
|
620
|
+
}
|
|
621
|
+
return params.toString();
|
|
622
|
+
}
|
|
623
|
+
function requestParts(op, init) {
|
|
624
|
+
const method = parseOperation(op).method.toUpperCase();
|
|
625
|
+
const headers = { ...init.headers };
|
|
626
|
+
if (init.form !== void 0) {
|
|
627
|
+
if (!hasHeader(headers, "Content-Type")) {
|
|
628
|
+
headers["Content-Type"] = "application/x-www-form-urlencoded";
|
|
629
|
+
}
|
|
630
|
+
return { method, headers, body: formBody(init.form) };
|
|
631
|
+
}
|
|
632
|
+
if (init.body !== void 0) {
|
|
633
|
+
if (!hasHeader(headers, "Content-Type")) {
|
|
634
|
+
headers["Content-Type"] = "application/json";
|
|
635
|
+
}
|
|
636
|
+
return { method, headers, body: JSON.stringify(init.body) };
|
|
637
|
+
}
|
|
638
|
+
return { method, headers };
|
|
639
|
+
}
|
|
640
|
+
function requestInit(parts, init, headers) {
|
|
641
|
+
const request = {};
|
|
642
|
+
if (parts.method !== "GET") request.method = parts.method;
|
|
643
|
+
if (Object.keys(headers).length > 0) request.headers = headers;
|
|
644
|
+
if (parts.body !== void 0) request.body = parts.body;
|
|
645
|
+
if (init.signal) request.signal = init.signal;
|
|
646
|
+
if (init.redirect) request.redirect = init.redirect;
|
|
647
|
+
return request;
|
|
648
|
+
}
|
|
649
|
+
async function credential(auth) {
|
|
650
|
+
if (auth === "none") return null;
|
|
651
|
+
if (auth === "user") return resolveAccessToken();
|
|
652
|
+
if (auth === "deploy") {
|
|
653
|
+
const token = resolveDeployToken() ?? await resolveAccessToken();
|
|
654
|
+
if (!token) throw new Error(DEPLOY_TOKEN_MISSING);
|
|
655
|
+
return token;
|
|
656
|
+
}
|
|
657
|
+
return auth.token;
|
|
658
|
+
}
|
|
659
|
+
async function apiRequest(op, init = {}) {
|
|
660
|
+
const target = operationTarget(op, init.path, init.query);
|
|
661
|
+
const parts = requestParts(op, init);
|
|
662
|
+
const auth = init.auth ?? "user";
|
|
663
|
+
if (init.baseUrl === void 0 && init.fetch === void 0 && typeof auth === "string") {
|
|
664
|
+
const request = requestInit(parts, init, parts.headers);
|
|
665
|
+
const send2 = auth === "user" ? apiFetch : auth === "deploy" ? deployFetch : publicFetch;
|
|
666
|
+
return Object.keys(request).length > 0 ? send2(target, request) : send2(target);
|
|
667
|
+
}
|
|
668
|
+
const url = `${init.baseUrl ?? resolveAppUrl()}${target}`;
|
|
669
|
+
const token = await credential(auth);
|
|
670
|
+
if (token) requireSecureUrl(url);
|
|
671
|
+
const headers = mergeHeaders(
|
|
672
|
+
clientContextHeaders(),
|
|
673
|
+
parts.headers,
|
|
674
|
+
token ? { Authorization: `Bearer ${token}` } : {}
|
|
675
|
+
);
|
|
676
|
+
const send = init.fetch ?? fetch;
|
|
677
|
+
return send(url, requestInit(parts, init, headers));
|
|
678
|
+
}
|
|
679
|
+
function operationUrl(op, init) {
|
|
680
|
+
return `${init.baseUrl}${operationTarget(op, init.path, init.query)}`;
|
|
681
|
+
}
|
|
682
|
+
|
|
683
|
+
// src/core/oauth-client.ts
|
|
268
684
|
var CLI_CLIENT_ID = "walkeros-cli";
|
|
269
685
|
var CLI_SCOPE = "read write offline_access";
|
|
270
686
|
var DEVICE_CODE_GRANT = "urn:ietf:params:oauth:grant-type:device_code";
|
|
271
687
|
var REFRESH_TIMEOUT_MS = 1e4;
|
|
272
688
|
var REVOKE_TIMEOUT_MS = 5e3;
|
|
273
689
|
var DEVICE_AUTHORIZATION_TIMEOUT_MS = 1e4;
|
|
274
|
-
var FORM_HEADERS = {
|
|
275
|
-
"Content-Type": "application/x-www-form-urlencoded",
|
|
276
|
-
Accept: "application/json"
|
|
277
|
-
};
|
|
278
690
|
var DeviceAuthorizationSchema = z.object({
|
|
279
691
|
device_code: z.string().min(1),
|
|
280
692
|
user_code: z.string().min(1),
|
|
@@ -310,14 +722,15 @@ function describe(response, body) {
|
|
|
310
722
|
}
|
|
311
723
|
return `HTTP ${response.status}`;
|
|
312
724
|
}
|
|
313
|
-
function
|
|
314
|
-
return
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
725
|
+
function credentialTransport(appUrl, fetchFn, signal) {
|
|
726
|
+
return {
|
|
727
|
+
auth: "none",
|
|
728
|
+
baseUrl: requireSecureUrl(appUrl),
|
|
729
|
+
fetch: fetchFn,
|
|
730
|
+
headers: { Accept: "application/json" },
|
|
318
731
|
redirect: "error",
|
|
319
732
|
...signal ? { signal } : {}
|
|
320
|
-
}
|
|
733
|
+
};
|
|
321
734
|
}
|
|
322
735
|
function toTokenSet(body) {
|
|
323
736
|
const parsed = TokenSchema.safeParse(body);
|
|
@@ -331,18 +744,20 @@ function toTokenSet(body) {
|
|
|
331
744
|
};
|
|
332
745
|
}
|
|
333
746
|
async function startDeviceAuthorization(appUrl, fetchFn = globalThis.fetch) {
|
|
334
|
-
const response = await
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
747
|
+
const response = await apiRequest("POST /api/oauth/device_authorization", {
|
|
748
|
+
...credentialTransport(
|
|
749
|
+
appUrl,
|
|
750
|
+
fetchFn,
|
|
751
|
+
AbortSignal.timeout(DEVICE_AUTHORIZATION_TIMEOUT_MS)
|
|
752
|
+
),
|
|
753
|
+
form: {
|
|
338
754
|
client_id: CLI_CLIENT_ID,
|
|
339
755
|
scope: CLI_SCOPE,
|
|
340
756
|
// RFC 8707. The token comes back bound to the API, so a leaked CLI token
|
|
341
757
|
// cannot be replayed against the MCP resource.
|
|
342
758
|
resource: `${appUrl}/api`
|
|
343
|
-
}
|
|
344
|
-
|
|
345
|
-
);
|
|
759
|
+
}
|
|
760
|
+
});
|
|
346
761
|
const body = await readJson(response);
|
|
347
762
|
if (!response.ok) throw new Error(describe(response, body));
|
|
348
763
|
const parsed = DeviceAuthorizationSchema.safeParse(body);
|
|
@@ -360,16 +775,14 @@ async function startDeviceAuthorization(appUrl, fetchFn = globalThis.fetch) {
|
|
|
360
775
|
async function pollDeviceToken(appUrl, deviceCode, fetchFn = globalThis.fetch, signal) {
|
|
361
776
|
let response;
|
|
362
777
|
try {
|
|
363
|
-
response = await
|
|
364
|
-
fetchFn,
|
|
365
|
-
|
|
366
|
-
{
|
|
778
|
+
response = await apiRequest("POST /api/oauth/token", {
|
|
779
|
+
...credentialTransport(appUrl, fetchFn, signal),
|
|
780
|
+
form: {
|
|
367
781
|
grant_type: DEVICE_CODE_GRANT,
|
|
368
782
|
device_code: deviceCode,
|
|
369
783
|
client_id: CLI_CLIENT_ID
|
|
370
|
-
}
|
|
371
|
-
|
|
372
|
-
);
|
|
784
|
+
}
|
|
785
|
+
});
|
|
373
786
|
} catch (error) {
|
|
374
787
|
if (signal?.aborted) return { status: "pending" };
|
|
375
788
|
throw error;
|
|
@@ -399,16 +812,18 @@ async function pollDeviceToken(appUrl, deviceCode, fetchFn = globalThis.fetch, s
|
|
|
399
812
|
}
|
|
400
813
|
}
|
|
401
814
|
async function refreshTokens(appUrl, refreshToken, fetchFn = globalThis.fetch) {
|
|
402
|
-
const response = await
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
815
|
+
const response = await apiRequest("POST /api/oauth/token", {
|
|
816
|
+
...credentialTransport(
|
|
817
|
+
appUrl,
|
|
818
|
+
fetchFn,
|
|
819
|
+
AbortSignal.timeout(REFRESH_TIMEOUT_MS)
|
|
820
|
+
),
|
|
821
|
+
form: {
|
|
406
822
|
grant_type: "refresh_token",
|
|
407
823
|
refresh_token: refreshToken,
|
|
408
824
|
client_id: CLI_CLIENT_ID
|
|
409
|
-
}
|
|
410
|
-
|
|
411
|
-
);
|
|
825
|
+
}
|
|
826
|
+
});
|
|
412
827
|
const body = await readJson(response);
|
|
413
828
|
if (!response.ok) {
|
|
414
829
|
if (errorCode(body) === "invalid_grant") return null;
|
|
@@ -418,16 +833,18 @@ async function refreshTokens(appUrl, refreshToken, fetchFn = globalThis.fetch) {
|
|
|
418
833
|
}
|
|
419
834
|
async function revokeRefreshToken(appUrl, refreshToken, fetchFn = globalThis.fetch) {
|
|
420
835
|
try {
|
|
421
|
-
await
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
836
|
+
await apiRequest("POST /api/oauth/revoke", {
|
|
837
|
+
...credentialTransport(
|
|
838
|
+
appUrl,
|
|
839
|
+
fetchFn,
|
|
840
|
+
AbortSignal.timeout(REVOKE_TIMEOUT_MS)
|
|
841
|
+
),
|
|
842
|
+
form: {
|
|
425
843
|
token: refreshToken,
|
|
426
844
|
token_type_hint: "refresh_token",
|
|
427
845
|
client_id: CLI_CLIENT_ID
|
|
428
|
-
}
|
|
429
|
-
|
|
430
|
-
);
|
|
846
|
+
}
|
|
847
|
+
});
|
|
431
848
|
} catch {
|
|
432
849
|
}
|
|
433
850
|
}
|
|
@@ -513,28 +930,6 @@ function requireProjectId() {
|
|
|
513
930
|
return projectId;
|
|
514
931
|
}
|
|
515
932
|
|
|
516
|
-
// src/core/client-context.ts
|
|
517
|
-
var context;
|
|
518
|
-
function setClientContext(input) {
|
|
519
|
-
const envType = process.env.WALKEROS_CLIENT_TYPE;
|
|
520
|
-
const type = envType ?? input.type ?? "cli";
|
|
521
|
-
context = { type, version: input.version };
|
|
522
|
-
}
|
|
523
|
-
function getClientContext() {
|
|
524
|
-
return context;
|
|
525
|
-
}
|
|
526
|
-
function resetClientContext() {
|
|
527
|
-
context = void 0;
|
|
528
|
-
}
|
|
529
|
-
function clientContextHeaders() {
|
|
530
|
-
if (!context) return {};
|
|
531
|
-
return {
|
|
532
|
-
"User-Agent": `walkeros-${context.type}/${context.version}`,
|
|
533
|
-
"X-WalkerOS-Client": context.type,
|
|
534
|
-
"X-WalkerOS-Client-Version": context.version
|
|
535
|
-
};
|
|
536
|
-
}
|
|
537
|
-
|
|
538
933
|
// src/core/http.ts
|
|
539
934
|
function normalizeHeaders(headers) {
|
|
540
935
|
if (!headers) return {};
|
|
@@ -1060,16 +1455,16 @@ import fs8 from "fs-extra";
|
|
|
1060
1455
|
import { getFlowSettings, getPlatform } from "@walkeros/core";
|
|
1061
1456
|
|
|
1062
1457
|
// src/core/content-digest.ts
|
|
1063
|
-
import { createHash } from "crypto";
|
|
1458
|
+
import { createHash as createHash2 } from "crypto";
|
|
1064
1459
|
import path7 from "path";
|
|
1065
1460
|
import fs7 from "fs-extra";
|
|
1066
1461
|
var DIGEST_LENGTH = 12;
|
|
1067
|
-
function
|
|
1462
|
+
function isRecord2(value) {
|
|
1068
1463
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
1069
1464
|
}
|
|
1070
1465
|
function canonicalJson(value) {
|
|
1071
1466
|
return JSON.stringify(value, (_key, inner) => {
|
|
1072
|
-
if (!
|
|
1467
|
+
if (!isRecord2(inner)) return inner;
|
|
1073
1468
|
const sorted = {};
|
|
1074
1469
|
for (const key of Object.keys(inner).sort()) sorted[key] = inner[key];
|
|
1075
1470
|
return sorted;
|
|
@@ -1087,10 +1482,10 @@ function configDigest(flowSettings, flowName) {
|
|
|
1087
1482
|
...config,
|
|
1088
1483
|
bundle: { ...config.bundle, env: Object.keys(declaredEnv).sort() }
|
|
1089
1484
|
} : config;
|
|
1090
|
-
return
|
|
1485
|
+
return createHash2("sha256").update(canonicalJson({ ...flowSettings, config: hashedConfig, collector })).digest("hex");
|
|
1091
1486
|
}
|
|
1092
1487
|
async function hashInstalledDir(dir) {
|
|
1093
|
-
const hash =
|
|
1488
|
+
const hash = createHash2("sha256");
|
|
1094
1489
|
for (const rel of await listFiles(dir, "")) {
|
|
1095
1490
|
const abs = path7.join(dir, rel);
|
|
1096
1491
|
const stat2 = await fs7.lstat(abs);
|
|
@@ -1115,7 +1510,7 @@ async function listFiles(root, rel) {
|
|
|
1115
1510
|
return files.sort();
|
|
1116
1511
|
}
|
|
1117
1512
|
function releaseDigest(input) {
|
|
1118
|
-
return
|
|
1513
|
+
return createHash2("sha256").update(
|
|
1119
1514
|
canonicalJson({
|
|
1120
1515
|
config: input.configDigest,
|
|
1121
1516
|
versions: input.versions,
|
|
@@ -1300,7 +1695,7 @@ import {
|
|
|
1300
1695
|
ENV_MARKER_PREFIX,
|
|
1301
1696
|
SECRET_MARKER_PREFIX as SECRET_MARKER_PREFIX2,
|
|
1302
1697
|
isPathStepEntry,
|
|
1303
|
-
isObject as
|
|
1698
|
+
isObject as isObject3
|
|
1304
1699
|
} from "@walkeros/core";
|
|
1305
1700
|
|
|
1306
1701
|
// src/commands/bundle/config-classifier.ts
|
|
@@ -2475,6 +2870,63 @@ async function resolveSiblingOrAncestor(consumerDir, depName, root) {
|
|
|
2475
2870
|
}
|
|
2476
2871
|
}
|
|
2477
2872
|
|
|
2873
|
+
// src/commands/bundle/build-flags.ts
|
|
2874
|
+
import { isObject as isObject2 } from "@walkeros/core";
|
|
2875
|
+
function carriesState(step) {
|
|
2876
|
+
if (step.state !== void 0) return true;
|
|
2877
|
+
if (step.config === void 0) return false;
|
|
2878
|
+
return !isObject2(step.config) || step.config.state !== void 0;
|
|
2879
|
+
}
|
|
2880
|
+
function flowNeeds(flow) {
|
|
2881
|
+
const steps = [
|
|
2882
|
+
...Object.values(flow.sources ?? {}),
|
|
2883
|
+
...Object.values(flow.transformers ?? {}),
|
|
2884
|
+
...Object.values(flow.destinations ?? {})
|
|
2885
|
+
];
|
|
2886
|
+
return {
|
|
2887
|
+
observe: flow.config?.observe !== void 0 || flow.collector?.observe !== void 0,
|
|
2888
|
+
stores: Object.keys(flow.stores ?? {}).length > 0,
|
|
2889
|
+
state: steps.some(carriesState)
|
|
2890
|
+
};
|
|
2891
|
+
}
|
|
2892
|
+
function buildFlagDefines(needs) {
|
|
2893
|
+
if (!needs) {
|
|
2894
|
+
return {
|
|
2895
|
+
__WALKEROS_OBSERVE__: "true",
|
|
2896
|
+
__WALKEROS_STORES__: "true",
|
|
2897
|
+
__WALKEROS_STATE__: "true",
|
|
2898
|
+
__WALKEROS_VALIDATE__: "true"
|
|
2899
|
+
};
|
|
2900
|
+
}
|
|
2901
|
+
return {
|
|
2902
|
+
__WALKEROS_OBSERVE__: String(needs.observe),
|
|
2903
|
+
__WALKEROS_STORES__: String(needs.stores),
|
|
2904
|
+
__WALKEROS_STATE__: String(needs.state),
|
|
2905
|
+
__WALKEROS_VALIDATE__: "false"
|
|
2906
|
+
};
|
|
2907
|
+
}
|
|
2908
|
+
var NEEDS_MARKER = "walkeros:needs";
|
|
2909
|
+
function needsMarker(needs) {
|
|
2910
|
+
return `/* ${NEEDS_MARKER} ${JSON.stringify(needs)} */`;
|
|
2911
|
+
}
|
|
2912
|
+
function readNeedsMarker(skeleton) {
|
|
2913
|
+
const match = new RegExp(`/\\* ${NEEDS_MARKER} (\\{[^}]*\\}) \\*/\\s*$`).exec(
|
|
2914
|
+
skeleton
|
|
2915
|
+
);
|
|
2916
|
+
if (!match) return void 0;
|
|
2917
|
+
let parsed;
|
|
2918
|
+
try {
|
|
2919
|
+
parsed = JSON.parse(match[1]);
|
|
2920
|
+
} catch {
|
|
2921
|
+
return void 0;
|
|
2922
|
+
}
|
|
2923
|
+
if (!isObject2(parsed)) return void 0;
|
|
2924
|
+
const { observe, stores, state } = parsed;
|
|
2925
|
+
if (typeof observe !== "boolean" || typeof stores !== "boolean" || typeof state !== "boolean")
|
|
2926
|
+
return void 0;
|
|
2927
|
+
return { observe, stores, state };
|
|
2928
|
+
}
|
|
2929
|
+
|
|
2478
2930
|
// src/commands/bundle/bundler.ts
|
|
2479
2931
|
import { getHashServer as getHashServer3 } from "@walkeros/server-core";
|
|
2480
2932
|
|
|
@@ -2887,9 +3339,12 @@ async function bundleCore(flowSettings, buildOptions, logger, showStats = false,
|
|
|
2887
3339
|
const dataDeclaration = `const __configData = ${dataPayload};
|
|
2888
3340
|
export { __configData };`;
|
|
2889
3341
|
const banner = buildOptions.platform === "node" ? `import { createRequire } from 'module';const require = createRequire(import.meta.url);
|
|
3342
|
+
` : "";
|
|
3343
|
+
const needs = buildOptions.platform === "browser" ? `
|
|
3344
|
+
${needsMarker(flowNeeds(flowSettings))}
|
|
2890
3345
|
` : "";
|
|
2891
3346
|
const esmOutput = `${banner}${compiledCode}
|
|
2892
|
-
${dataDeclaration}`;
|
|
3347
|
+
${dataDeclaration}${needs}`;
|
|
2893
3348
|
await fs14.writeFile(outputPath, esmOutput);
|
|
2894
3349
|
} else {
|
|
2895
3350
|
const stage2Entry = (buildOptions.platform || "node") === "browser" ? generateWebEntry(stage1Path, dataPayload, {
|
|
@@ -2921,7 +3376,8 @@ ${dataDeclaration}`;
|
|
|
2921
3376
|
stage2Options.format = "iife";
|
|
2922
3377
|
stage2Options.define = {
|
|
2923
3378
|
"process.env.NODE_ENV": '"production"',
|
|
2924
|
-
global: "globalThis"
|
|
3379
|
+
global: "globalThis",
|
|
3380
|
+
...buildFlagDefines(flowNeeds(flowSettings))
|
|
2925
3381
|
};
|
|
2926
3382
|
stage2Options.target = resolveTarget(buildOptions);
|
|
2927
3383
|
} else {
|
|
@@ -3259,9 +3715,9 @@ function packageSpecName(spec) {
|
|
|
3259
3715
|
return parsePackageSpec(spec).name;
|
|
3260
3716
|
}
|
|
3261
3717
|
function readSourceElb(source) {
|
|
3262
|
-
if (!
|
|
3718
|
+
if (!isObject3(source.config)) return void 0;
|
|
3263
3719
|
const settings = source.config.settings;
|
|
3264
|
-
if (!
|
|
3720
|
+
if (!isObject3(settings)) return void 0;
|
|
3265
3721
|
return typeof settings.elb === "string" ? settings.elb : void 0;
|
|
3266
3722
|
}
|
|
3267
3723
|
function bridgeWindowElb(flow, logger) {
|
|
@@ -3289,8 +3745,8 @@ function bridgeWindowElb(flow, logger) {
|
|
|
3289
3745
|
}
|
|
3290
3746
|
const nextSources = { ...sources };
|
|
3291
3747
|
for (const [id, source] of toForward) {
|
|
3292
|
-
const config =
|
|
3293
|
-
const settings =
|
|
3748
|
+
const config = isObject3(source.config) ? source.config : {};
|
|
3749
|
+
const settings = isObject3(config.settings) ? config.settings : {};
|
|
3294
3750
|
nextSources[id] = {
|
|
3295
3751
|
...source,
|
|
3296
3752
|
config: { ...config, settings: { ...settings, elb: windowElb } }
|
|
@@ -4404,7 +4860,11 @@ function applyOverrides(config, overrides) {
|
|
|
4404
4860
|
// src/commands/push/flow-context.ts
|
|
4405
4861
|
import path16 from "path";
|
|
4406
4862
|
import { pathToFileURL } from "url";
|
|
4407
|
-
import {
|
|
4863
|
+
import {
|
|
4864
|
+
JSDOM,
|
|
4865
|
+
VirtualConsole,
|
|
4866
|
+
requestInterceptor
|
|
4867
|
+
} from "jsdom";
|
|
4408
4868
|
|
|
4409
4869
|
// src/commands/push/async-drain.ts
|
|
4410
4870
|
function installTimerInterception(options = {}) {
|
|
@@ -4561,7 +5021,10 @@ var DOM_GLOBALS = [
|
|
|
4561
5021
|
"Element",
|
|
4562
5022
|
"HTMLElement",
|
|
4563
5023
|
"Document",
|
|
4564
|
-
"ShadowRoot"
|
|
5024
|
+
"ShadowRoot",
|
|
5025
|
+
"XMLHttpRequest",
|
|
5026
|
+
"location",
|
|
5027
|
+
"self"
|
|
4565
5028
|
];
|
|
4566
5029
|
function exposeDomGlobals(domWindow) {
|
|
4567
5030
|
const saved = DOM_GLOBALS.map(
|
|
@@ -4601,7 +5064,8 @@ async function withFlowContext(options, fn, onError) {
|
|
|
4601
5064
|
networkCalls,
|
|
4602
5065
|
asyncDrain,
|
|
4603
5066
|
drainPump,
|
|
4604
|
-
pageUrl
|
|
5067
|
+
pageUrl,
|
|
5068
|
+
offline
|
|
4605
5069
|
} = options;
|
|
4606
5070
|
const startTime = Date.now();
|
|
4607
5071
|
const g = global;
|
|
@@ -4615,7 +5079,7 @@ async function withFlowContext(options, fn, onError) {
|
|
|
4615
5079
|
dom = new JSDOM("<!DOCTYPE html><html><body></body></html>", {
|
|
4616
5080
|
url: pageUrl ?? "http://localhost",
|
|
4617
5081
|
runScripts: "dangerously",
|
|
4618
|
-
resources: "usable",
|
|
5082
|
+
resources: offline ? offlineResources() : "usable",
|
|
4619
5083
|
virtualConsole
|
|
4620
5084
|
});
|
|
4621
5085
|
savedWindow = g.window;
|
|
@@ -4745,6 +5209,111 @@ function applyNetworkPolyfills(dom, networkCalls) {
|
|
|
4745
5209
|
networkCalls.push({ type: "beacon", url, body, timestamp: Date.now() });
|
|
4746
5210
|
return true;
|
|
4747
5211
|
};
|
|
5212
|
+
Object.defineProperty(dom.window, "XMLHttpRequest", {
|
|
5213
|
+
value: createRecordingXhr(dom, networkCalls),
|
|
5214
|
+
configurable: true,
|
|
5215
|
+
writable: true
|
|
5216
|
+
});
|
|
5217
|
+
}
|
|
5218
|
+
function createRecordingXhr(dom, networkCalls) {
|
|
5219
|
+
const PageEvent = dom.window.Event;
|
|
5220
|
+
return class XMLHttpRequest extends dom.window.EventTarget {
|
|
5221
|
+
static UNSENT = 0;
|
|
5222
|
+
static OPENED = 1;
|
|
5223
|
+
static HEADERS_RECEIVED = 2;
|
|
5224
|
+
static LOADING = 3;
|
|
5225
|
+
static DONE = 4;
|
|
5226
|
+
UNSENT = 0;
|
|
5227
|
+
OPENED = 1;
|
|
5228
|
+
HEADERS_RECEIVED = 2;
|
|
5229
|
+
LOADING = 3;
|
|
5230
|
+
DONE = 4;
|
|
5231
|
+
readyState = 0;
|
|
5232
|
+
status = 0;
|
|
5233
|
+
statusText = "";
|
|
5234
|
+
responseType = "";
|
|
5235
|
+
response = "";
|
|
5236
|
+
responseText = "";
|
|
5237
|
+
responseURL = "";
|
|
5238
|
+
timeout = 0;
|
|
5239
|
+
withCredentials = false;
|
|
5240
|
+
onreadystatechange = null;
|
|
5241
|
+
onload = null;
|
|
5242
|
+
onabort = null;
|
|
5243
|
+
onloadend = null;
|
|
5244
|
+
#method = "GET";
|
|
5245
|
+
#url = "";
|
|
5246
|
+
#async = true;
|
|
5247
|
+
#headers = {};
|
|
5248
|
+
#pending = false;
|
|
5249
|
+
open(method, url, async = true) {
|
|
5250
|
+
this.#method = method.toUpperCase();
|
|
5251
|
+
this.#url = String(url);
|
|
5252
|
+
this.#async = async;
|
|
5253
|
+
this.#headers = {};
|
|
5254
|
+
this.#pending = false;
|
|
5255
|
+
this.readyState = 1;
|
|
5256
|
+
}
|
|
5257
|
+
setRequestHeader(name, value) {
|
|
5258
|
+
this.#headers[name] = value;
|
|
5259
|
+
}
|
|
5260
|
+
getResponseHeader() {
|
|
5261
|
+
return null;
|
|
5262
|
+
}
|
|
5263
|
+
getAllResponseHeaders() {
|
|
5264
|
+
return "";
|
|
5265
|
+
}
|
|
5266
|
+
overrideMimeType() {
|
|
5267
|
+
}
|
|
5268
|
+
abort() {
|
|
5269
|
+
const pending = this.#pending;
|
|
5270
|
+
this.#pending = false;
|
|
5271
|
+
if (!pending && this.readyState !== 4) return;
|
|
5272
|
+
this.status = 0;
|
|
5273
|
+
this.statusText = "";
|
|
5274
|
+
if (pending) this.#finish("abort", this.onabort);
|
|
5275
|
+
this.readyState = 0;
|
|
5276
|
+
}
|
|
5277
|
+
send(body) {
|
|
5278
|
+
networkCalls.push({
|
|
5279
|
+
type: "xhr",
|
|
5280
|
+
url: this.#url,
|
|
5281
|
+
method: this.#method,
|
|
5282
|
+
body: body !== void 0 && body !== null ? String(body) : null,
|
|
5283
|
+
headers: { ...this.#headers },
|
|
5284
|
+
timestamp: Date.now()
|
|
5285
|
+
});
|
|
5286
|
+
this.#pending = true;
|
|
5287
|
+
if (this.#async) queueMicrotask(() => this.#complete());
|
|
5288
|
+
else this.#complete();
|
|
5289
|
+
}
|
|
5290
|
+
#complete() {
|
|
5291
|
+
if (!this.#pending) return;
|
|
5292
|
+
this.#pending = false;
|
|
5293
|
+
this.status = 200;
|
|
5294
|
+
this.statusText = "OK";
|
|
5295
|
+
this.responseURL = this.#url;
|
|
5296
|
+
this.#finish("load", this.onload);
|
|
5297
|
+
}
|
|
5298
|
+
#finish(outcome, onOutcome) {
|
|
5299
|
+
this.readyState = 4;
|
|
5300
|
+
const handlers = [
|
|
5301
|
+
["readystatechange", this.onreadystatechange],
|
|
5302
|
+
[outcome, onOutcome],
|
|
5303
|
+
["loadend", this.onloadend]
|
|
5304
|
+
];
|
|
5305
|
+
for (const [type, handler] of handlers) {
|
|
5306
|
+
const event = new PageEvent(type);
|
|
5307
|
+
this.dispatchEvent(event);
|
|
5308
|
+
handler?.call(this, event);
|
|
5309
|
+
}
|
|
5310
|
+
}
|
|
5311
|
+
};
|
|
5312
|
+
}
|
|
5313
|
+
function offlineResources() {
|
|
5314
|
+
return {
|
|
5315
|
+
interceptors: [requestInterceptor(() => new Response("", { status: 200 }))]
|
|
5316
|
+
};
|
|
4748
5317
|
}
|
|
4749
5318
|
function cleanupNetworkPolyfills(savedFetch) {
|
|
4750
5319
|
global.fetch = savedFetch;
|
|
@@ -4897,7 +5466,7 @@ function dispatchSimulate(flags) {
|
|
|
4897
5466
|
}
|
|
4898
5467
|
|
|
4899
5468
|
// src/commands/push/run.ts
|
|
4900
|
-
import { isObject as
|
|
5469
|
+
import { isObject as isObject4 } from "@walkeros/core";
|
|
4901
5470
|
function simulationToPushResult(result) {
|
|
4902
5471
|
return {
|
|
4903
5472
|
success: !result.error,
|
|
@@ -4911,7 +5480,7 @@ var CONSENT_SCOPE_ERROR = "--consent sets the collector's starting consent for a
|
|
|
4911
5480
|
var CONSENT_SHAPE_ERROR = "--consent must be a JSON object of booleans";
|
|
4912
5481
|
var COMMAND_SCOPE_ERROR = "--command applies to destination simulation only.";
|
|
4913
5482
|
function isConsent(value) {
|
|
4914
|
-
return
|
|
5483
|
+
return isObject4(value) && Object.values(value).every((granted) => typeof granted === "boolean");
|
|
4915
5484
|
}
|
|
4916
5485
|
async function resolveConsent(options) {
|
|
4917
5486
|
if (options.consentSource === void 0) return options.consent;
|
|
@@ -4934,7 +5503,7 @@ async function resolveIngest(options) {
|
|
|
4934
5503
|
const loaded = await loadJsonFromSource(options.ingestSource, {
|
|
4935
5504
|
name: "ingest"
|
|
4936
5505
|
});
|
|
4937
|
-
if (!
|
|
5506
|
+
if (!isObject4(loaded)) throw new Error("--ingest must be a JSON object");
|
|
4938
5507
|
return loaded;
|
|
4939
5508
|
}
|
|
4940
5509
|
async function runPushCommandWithSecrets(options) {
|
|
@@ -5092,22 +5661,22 @@ async function runDestinationSimulationLoop(config, event, destinationIds, optio
|
|
|
5092
5661
|
}
|
|
5093
5662
|
|
|
5094
5663
|
// src/commands/push/dev-examples.ts
|
|
5095
|
-
function
|
|
5664
|
+
function isRecord3(value) {
|
|
5096
5665
|
return value !== null && typeof value === "object";
|
|
5097
5666
|
}
|
|
5098
5667
|
function selectDevExamples(devModule, exportName) {
|
|
5099
|
-
if (!
|
|
5668
|
+
if (!isRecord3(devModule)) return void 0;
|
|
5100
5669
|
const map = devModule.exportExamples;
|
|
5101
|
-
if (
|
|
5670
|
+
if (isRecord3(map) && exportName !== void 0) {
|
|
5102
5671
|
const selected = map[exportName];
|
|
5103
|
-
return
|
|
5672
|
+
return isRecord3(selected) ? selected : void 0;
|
|
5104
5673
|
}
|
|
5105
5674
|
const examples = devModule.examples;
|
|
5106
|
-
return
|
|
5675
|
+
return isRecord3(examples) ? examples : void 0;
|
|
5107
5676
|
}
|
|
5108
5677
|
function legacyExportRefusal(devModule, packageExports, packageName, exportName) {
|
|
5109
5678
|
if (exportName === void 0) return void 0;
|
|
5110
|
-
if (
|
|
5679
|
+
if (isRecord3(devModule) && isRecord3(devModule.exportExamples))
|
|
5111
5680
|
return void 0;
|
|
5112
5681
|
if (packageExports) {
|
|
5113
5682
|
const declared = packageExports[packageName];
|
|
@@ -5155,11 +5724,11 @@ function resolveExportName(flow, kind, id) {
|
|
|
5155
5724
|
}
|
|
5156
5725
|
|
|
5157
5726
|
// src/commands/push/index.ts
|
|
5158
|
-
function
|
|
5727
|
+
function isRecord4(value) {
|
|
5159
5728
|
return value !== null && typeof value === "object";
|
|
5160
5729
|
}
|
|
5161
5730
|
function isFlowJson(value) {
|
|
5162
|
-
return
|
|
5731
|
+
return isRecord4(value) && isRecord4(value.flows);
|
|
5163
5732
|
}
|
|
5164
5733
|
function isString(value) {
|
|
5165
5734
|
return typeof value === "string";
|
|
@@ -5177,9 +5746,9 @@ function getDevEnv(devModule, exportName) {
|
|
|
5177
5746
|
const examples = selectDevExamples(devModule, exportName);
|
|
5178
5747
|
if (!examples || !("env" in examples)) return void 0;
|
|
5179
5748
|
const env = examples.env;
|
|
5180
|
-
if (!
|
|
5749
|
+
if (!isRecord4(env)) return void 0;
|
|
5181
5750
|
const result = {};
|
|
5182
|
-
if ("push" in env &&
|
|
5751
|
+
if ("push" in env && isRecord4(env.push)) result.push = env.push;
|
|
5183
5752
|
if ("simulation" in env && isStringArray(env.simulation))
|
|
5184
5753
|
result.simulation = env.simulation;
|
|
5185
5754
|
return result;
|
|
@@ -5187,14 +5756,14 @@ function getDevEnv(devModule, exportName) {
|
|
|
5187
5756
|
async function applyStoreMockEnvs(flowConfig, flowSettings, devExports) {
|
|
5188
5757
|
const unmocked = [];
|
|
5189
5758
|
const stores = flowConfig.stores;
|
|
5190
|
-
if (!
|
|
5759
|
+
if (!isRecord4(stores)) return unmocked;
|
|
5191
5760
|
for (const [storeId, storeDef] of Object.entries(stores)) {
|
|
5192
5761
|
const packageName = flowSettings.stores?.[storeId]?.package;
|
|
5193
5762
|
const loadDev = packageName ? devExports?.[packageName] : void 0;
|
|
5194
5763
|
const devModule = typeof loadDev === "function" ? await loadDev() : void 0;
|
|
5195
5764
|
const { exportName } = resolveExportName(flowSettings, "store", storeId);
|
|
5196
5765
|
const push2 = getDevEnv(devModule, exportName)?.push;
|
|
5197
|
-
if (!push2 || !
|
|
5766
|
+
if (!push2 || !isRecord4(storeDef)) {
|
|
5198
5767
|
unmocked.push(storeId);
|
|
5199
5768
|
continue;
|
|
5200
5769
|
}
|
|
@@ -5345,7 +5914,7 @@ function formatPushResult(result, options = {}) {
|
|
|
5345
5914
|
const lines = [];
|
|
5346
5915
|
lines.push(`success: ${result.success}`);
|
|
5347
5916
|
if (result.success) {
|
|
5348
|
-
const elbResult =
|
|
5917
|
+
const elbResult = isRecord4(result.elbResult) ? result.elbResult : void 0;
|
|
5349
5918
|
if (elbResult) {
|
|
5350
5919
|
if (typeof elbResult.id === "string")
|
|
5351
5920
|
lines.push(` Event ID: ${elbResult.id}`);
|
|
@@ -5538,9 +6107,9 @@ function resolvePageUrl(input, pageUrl) {
|
|
|
5538
6107
|
return parsed.href;
|
|
5539
6108
|
}
|
|
5540
6109
|
function triggerUrl(input) {
|
|
5541
|
-
if (!
|
|
6110
|
+
if (!isRecord4(input) || !isRecord4(input.trigger)) return void 0;
|
|
5542
6111
|
const { options } = input.trigger;
|
|
5543
|
-
return
|
|
6112
|
+
return isRecord4(options) && isString(options.url) ? options.url : void 0;
|
|
5544
6113
|
}
|
|
5545
6114
|
function isSourceInit(value) {
|
|
5546
6115
|
return typeof value === "function";
|
|
@@ -5628,6 +6197,7 @@ async function simulateSource(configOrPath, input, options) {
|
|
|
5628
6197
|
logger,
|
|
5629
6198
|
snapshotCode,
|
|
5630
6199
|
networkCalls,
|
|
6200
|
+
offline: true,
|
|
5631
6201
|
pageUrl
|
|
5632
6202
|
},
|
|
5633
6203
|
async (module) => {
|
|
@@ -5666,14 +6236,15 @@ async function simulateSource(configOrPath, input, options) {
|
|
|
5666
6236
|
`Stores without a mock env run as configured: ${unmockedStores.join(", ")}`
|
|
5667
6237
|
);
|
|
5668
6238
|
const wiredSources = flowConfig.sources;
|
|
5669
|
-
const wiredSource =
|
|
5670
|
-
const source =
|
|
6239
|
+
const wiredSource = isRecord4(wiredSources) ? wiredSources[options.sourceId] : void 0;
|
|
6240
|
+
const source = isRecord4(
|
|
5671
6241
|
wiredSource
|
|
5672
6242
|
) ? {
|
|
5673
6243
|
...wiredSource,
|
|
5674
|
-
...
|
|
6244
|
+
...isRecord4(wiredSource.config) ? { config: { ...wiredSource.config } } : {}
|
|
5675
6245
|
} : void 0;
|
|
5676
6246
|
flowConfig.sources = source ? { [options.sourceId]: source } : {};
|
|
6247
|
+
if (flowConfig.destinations) flowConfig.destinations = {};
|
|
5677
6248
|
const commandCalls = [];
|
|
5678
6249
|
if (source && isSourceInit(source.code))
|
|
5679
6250
|
source.code = recordSourceCommands(source.code, commandCalls);
|
|
@@ -5685,7 +6256,7 @@ async function simulateSource(configOrPath, input, options) {
|
|
|
5685
6256
|
simulation: devEnv.simulation
|
|
5686
6257
|
});
|
|
5687
6258
|
source.env = {
|
|
5688
|
-
...
|
|
6259
|
+
...isRecord4(source.env) ? source.env : {},
|
|
5689
6260
|
...wrappedEnv
|
|
5690
6261
|
};
|
|
5691
6262
|
trackedCalls = calls;
|
|
@@ -5820,7 +6391,8 @@ async function simulateTransformer(configOrPath, event, options) {
|
|
|
5820
6391
|
platform: prepared.platform,
|
|
5821
6392
|
logger,
|
|
5822
6393
|
snapshotCode,
|
|
5823
|
-
networkCalls
|
|
6394
|
+
networkCalls,
|
|
6395
|
+
offline: true
|
|
5824
6396
|
},
|
|
5825
6397
|
async (module) => {
|
|
5826
6398
|
const flowConfig = module.wireConfig(
|
|
@@ -5967,7 +6539,8 @@ async function simulateCollector(configOrPath, event, options) {
|
|
|
5967
6539
|
platform: prepared.platform,
|
|
5968
6540
|
logger,
|
|
5969
6541
|
snapshotCode,
|
|
5970
|
-
networkCalls
|
|
6542
|
+
networkCalls,
|
|
6543
|
+
offline: true
|
|
5971
6544
|
},
|
|
5972
6545
|
async (module) => {
|
|
5973
6546
|
const flowConfig = module.wireConfig(
|
|
@@ -6036,10 +6609,10 @@ async function simulateCollector(configOrPath, event, options) {
|
|
|
6036
6609
|
}
|
|
6037
6610
|
}
|
|
6038
6611
|
function isConsentRecord(value) {
|
|
6039
|
-
return
|
|
6612
|
+
return isRecord4(value) && Object.values(value).every((granted) => typeof granted === "boolean");
|
|
6040
6613
|
}
|
|
6041
6614
|
function pendingRequire(definition) {
|
|
6042
|
-
if (!
|
|
6615
|
+
if (!isRecord4(definition) || !isRecord4(definition.config)) return [];
|
|
6043
6616
|
const { require: require2 } = definition.config;
|
|
6044
6617
|
return isStringArray(require2) ? require2 : [];
|
|
6045
6618
|
}
|
|
@@ -6102,23 +6675,24 @@ async function simulateDestination(configOrPath, event, options) {
|
|
|
6102
6675
|
platform: prepared.platform,
|
|
6103
6676
|
logger,
|
|
6104
6677
|
snapshotCode,
|
|
6105
|
-
networkCalls
|
|
6678
|
+
networkCalls,
|
|
6679
|
+
offline: true
|
|
6106
6680
|
},
|
|
6107
6681
|
async (module) => {
|
|
6108
6682
|
const flowConfig = module.wireConfig(
|
|
6109
6683
|
options.data ?? module.__configData ?? void 0
|
|
6110
6684
|
);
|
|
6111
6685
|
const wiredDestinations = flowConfig.destinations;
|
|
6112
|
-
const wiredTarget =
|
|
6113
|
-
if (!
|
|
6114
|
-
const available =
|
|
6686
|
+
const wiredTarget = isRecord4(wiredDestinations) ? wiredDestinations[options.destinationId] : void 0;
|
|
6687
|
+
if (!isRecord4(wiredTarget)) {
|
|
6688
|
+
const available = isRecord4(wiredDestinations) ? Object.keys(wiredDestinations).join(", ") : "";
|
|
6115
6689
|
throw new Error(
|
|
6116
6690
|
`Destination "${options.destinationId}" not found in collector. Available: ${available || "none"}`
|
|
6117
6691
|
);
|
|
6118
6692
|
}
|
|
6119
6693
|
const target = {
|
|
6120
6694
|
...wiredTarget,
|
|
6121
|
-
config:
|
|
6695
|
+
config: isRecord4(wiredTarget.config) ? { ...wiredTarget.config } : {}
|
|
6122
6696
|
};
|
|
6123
6697
|
flowConfig.destinations = { [options.destinationId]: target };
|
|
6124
6698
|
if (flowConfig.sources) flowConfig.sources = {};
|
|
@@ -6158,7 +6732,7 @@ async function simulateDestination(configOrPath, event, options) {
|
|
|
6158
6732
|
);
|
|
6159
6733
|
}
|
|
6160
6734
|
const destConfig = target.config;
|
|
6161
|
-
if (
|
|
6735
|
+
if (isRecord4(destConfig)) {
|
|
6162
6736
|
destConfig.env = devEnv.push;
|
|
6163
6737
|
}
|
|
6164
6738
|
if (devEnv.simulation?.length) {
|
|
@@ -6167,7 +6741,7 @@ async function simulateDestination(configOrPath, event, options) {
|
|
|
6167
6741
|
simulation: devEnv.simulation
|
|
6168
6742
|
};
|
|
6169
6743
|
const { wrappedEnv, calls } = wrapEnv(combined);
|
|
6170
|
-
if (
|
|
6744
|
+
if (isRecord4(destConfig)) destConfig.env = wrappedEnv;
|
|
6171
6745
|
trackedCalls = calls;
|
|
6172
6746
|
}
|
|
6173
6747
|
}
|
|
@@ -6257,10 +6831,10 @@ async function simulateDestination(configOrPath, event, options) {
|
|
|
6257
6831
|
import * as fs20 from "fs";
|
|
6258
6832
|
import * as path20 from "path";
|
|
6259
6833
|
import chalk2 from "chalk";
|
|
6260
|
-
import { isObject as
|
|
6834
|
+
import { isObject as isObject10 } from "@walkeros/core";
|
|
6261
6835
|
|
|
6262
6836
|
// src/commands/validate/validators/contract.ts
|
|
6263
|
-
import { isObject as
|
|
6837
|
+
import { isObject as isObject5 } from "@walkeros/core";
|
|
6264
6838
|
var SECTION_KEYS = ["globals", "context", "custom", "user", "consent"];
|
|
6265
6839
|
var KNOWN_KEYS = /* @__PURE__ */ new Set([
|
|
6266
6840
|
"extend",
|
|
@@ -6310,7 +6884,7 @@ function validateContract(input) {
|
|
|
6310
6884
|
const keys = Object.keys(obj);
|
|
6311
6885
|
const unknownKeys = keys.filter((k) => !KNOWN_KEYS.has(k));
|
|
6312
6886
|
const hasKnownKey = keys.some((k) => KNOWN_KEYS.has(k));
|
|
6313
|
-
const objectValuedUnknown = unknownKeys.filter((k) =>
|
|
6887
|
+
const objectValuedUnknown = unknownKeys.filter((k) => isObject5(obj[k]));
|
|
6314
6888
|
if (!hasKnownKey && objectValuedUnknown.length > 0) {
|
|
6315
6889
|
errors.push({
|
|
6316
6890
|
path: name,
|
|
@@ -6333,7 +6907,7 @@ function validateContract(input) {
|
|
|
6333
6907
|
code: "INVALID_TAGGING"
|
|
6334
6908
|
});
|
|
6335
6909
|
}
|
|
6336
|
-
if (obj.schema !== void 0 && !
|
|
6910
|
+
if (obj.schema !== void 0 && !isObject5(obj.schema)) {
|
|
6337
6911
|
errors.push({
|
|
6338
6912
|
path: `${name}.schema`,
|
|
6339
6913
|
message: "schema must be a JSON Schema object",
|
|
@@ -6405,7 +6979,7 @@ function validateContract(input) {
|
|
|
6405
6979
|
}
|
|
6406
6980
|
chain.push(current);
|
|
6407
6981
|
const entry = contracts[current];
|
|
6408
|
-
current =
|
|
6982
|
+
current = isObject5(entry) && typeof entry.extend === "string" ? entry.extend : "";
|
|
6409
6983
|
}
|
|
6410
6984
|
}
|
|
6411
6985
|
return {
|
|
@@ -6476,7 +7050,7 @@ import {
|
|
|
6476
7050
|
ENV_MARKER_PREFIX as ENV_MARKER_PREFIX3,
|
|
6477
7051
|
getByPath,
|
|
6478
7052
|
getRouteGraph,
|
|
6479
|
-
isObject as
|
|
7053
|
+
isObject as isObject8,
|
|
6480
7054
|
REF_CONTRACT,
|
|
6481
7055
|
resolveContracts,
|
|
6482
7056
|
validateStepEntry
|
|
@@ -6487,9 +7061,9 @@ import {
|
|
|
6487
7061
|
} from "@walkeros/transformer-validate";
|
|
6488
7062
|
|
|
6489
7063
|
// src/commands/validate/scope.ts
|
|
6490
|
-
import { isObject as
|
|
7064
|
+
import { isObject as isObject6 } from "@walkeros/core";
|
|
6491
7065
|
function isFlowJson2(value) {
|
|
6492
|
-
return
|
|
7066
|
+
return isObject6(value) && "version" in value && isObject6(value.flows);
|
|
6493
7067
|
}
|
|
6494
7068
|
var ENTRY_SECTIONS = [
|
|
6495
7069
|
"sources",
|
|
@@ -6501,8 +7075,8 @@ function isEntrySection(value) {
|
|
|
6501
7075
|
return ENTRY_SECTIONS.some((section) => section === value);
|
|
6502
7076
|
}
|
|
6503
7077
|
function resolveScope(config, options = {}) {
|
|
6504
|
-
const flowsValue =
|
|
6505
|
-
const flowMap =
|
|
7078
|
+
const flowsValue = isObject6(config) ? config.flows : void 0;
|
|
7079
|
+
const flowMap = isObject6(flowsValue) ? flowsValue : {};
|
|
6506
7080
|
const allFlows = Object.keys(flowMap);
|
|
6507
7081
|
let flows = allFlows;
|
|
6508
7082
|
if (options.flow !== void 0) {
|
|
@@ -6570,12 +7144,12 @@ function resolveScope(config, options = {}) {
|
|
|
6570
7144
|
const entries = [];
|
|
6571
7145
|
for (const flow of flows) {
|
|
6572
7146
|
const flowValue = flowMap[flow];
|
|
6573
|
-
if (!
|
|
7147
|
+
if (!isObject6(flowValue)) continue;
|
|
6574
7148
|
for (const candidate of sections) {
|
|
6575
7149
|
const sectionValue = flowValue[candidate];
|
|
6576
|
-
if (!
|
|
7150
|
+
if (!isObject6(sectionValue)) continue;
|
|
6577
7151
|
const entry = sectionValue[key];
|
|
6578
|
-
if (
|
|
7152
|
+
if (isObject6(entry))
|
|
6579
7153
|
entries.push({ flow, section: candidate, key, entry });
|
|
6580
7154
|
}
|
|
6581
7155
|
}
|
|
@@ -6677,12 +7251,12 @@ import {
|
|
|
6677
7251
|
ENV_MARKER_PREFIX as ENV_MARKER_PREFIX2,
|
|
6678
7252
|
fetchPackage,
|
|
6679
7253
|
getErrorMessage as getErrorMessage3,
|
|
6680
|
-
isObject as
|
|
7254
|
+
isObject as isObject7,
|
|
6681
7255
|
REF_CODE_PREFIX,
|
|
6682
7256
|
REF_STORE,
|
|
6683
7257
|
SECRET_MARKER_PREFIX as SECRET_MARKER_PREFIX3
|
|
6684
7258
|
} from "@walkeros/core";
|
|
6685
|
-
var CLIENT_HEADER = "walkeros-cli/4.7.
|
|
7259
|
+
var CLIENT_HEADER = "walkeros-cli/4.7.1-next-1791015692826";
|
|
6686
7260
|
function createSettingsContext(configDir) {
|
|
6687
7261
|
return { configDir, cache: /* @__PURE__ */ new Map(), compiled: /* @__PURE__ */ new Map() };
|
|
6688
7262
|
}
|
|
@@ -6693,7 +7267,7 @@ function selectSettingsSchema(pkg, packageLabel, exportName) {
|
|
|
6693
7267
|
pkg.exportSchemas,
|
|
6694
7268
|
exportName
|
|
6695
7269
|
) ? pkg.exportSchemas[exportName] : void 0;
|
|
6696
|
-
if (!
|
|
7270
|
+
if (!isObject7(entry))
|
|
6697
7271
|
return {
|
|
6698
7272
|
ok: false,
|
|
6699
7273
|
reason: `${packageLabel} has no export "${exportName}"`
|
|
@@ -6721,7 +7295,7 @@ function valueAt(root, segments) {
|
|
|
6721
7295
|
let current = root;
|
|
6722
7296
|
for (const segment of segments) {
|
|
6723
7297
|
if (Array.isArray(current)) current = current[Number(segment)];
|
|
6724
|
-
else if (
|
|
7298
|
+
else if (isObject7(current)) current = current[segment];
|
|
6725
7299
|
else return void 0;
|
|
6726
7300
|
}
|
|
6727
7301
|
return current;
|
|
@@ -6736,7 +7310,7 @@ function prepareSettings(settings) {
|
|
|
6736
7310
|
const walk = (value, segments) => {
|
|
6737
7311
|
if (Array.isArray(value))
|
|
6738
7312
|
return value.map((item, index) => walk(item, [...segments, `${index}`]));
|
|
6739
|
-
if (
|
|
7313
|
+
if (isObject7(value))
|
|
6740
7314
|
return Object.fromEntries(
|
|
6741
7315
|
Object.entries(value).map(([key, item]) => [
|
|
6742
7316
|
key,
|
|
@@ -6781,11 +7355,11 @@ function isUnder(segments, prefix) {
|
|
|
6781
7355
|
return prefix.every((segment, index) => segments[index] === segment);
|
|
6782
7356
|
}
|
|
6783
7357
|
function bundlePin(rawFlow, name) {
|
|
6784
|
-
const config =
|
|
6785
|
-
const bundle2 =
|
|
6786
|
-
const packages =
|
|
6787
|
-
const pin =
|
|
6788
|
-
if (!
|
|
7358
|
+
const config = isObject7(rawFlow) ? rawFlow.config : void 0;
|
|
7359
|
+
const bundle2 = isObject7(config) ? config.bundle : void 0;
|
|
7360
|
+
const packages = isObject7(bundle2) ? bundle2.packages : void 0;
|
|
7361
|
+
const pin = isObject7(packages) ? packages[name] : void 0;
|
|
7362
|
+
if (!isObject7(pin)) return {};
|
|
6789
7363
|
return {
|
|
6790
7364
|
...typeof pin.version === "string" ? { version: pin.version } : {},
|
|
6791
7365
|
...typeof pin.path === "string" ? { path: pin.path } : {}
|
|
@@ -6814,15 +7388,15 @@ function readLocalSchema(source, configDir) {
|
|
|
6814
7388
|
const meta = readJson2(file);
|
|
6815
7389
|
const pkgFile = path19.join(root, "package.json");
|
|
6816
7390
|
const pkg = fs19.existsSync(pkgFile) ? readJson2(pkgFile) : void 0;
|
|
6817
|
-
const schemas6 =
|
|
6818
|
-
const exportSchemas =
|
|
6819
|
-
const declared =
|
|
6820
|
-
const version =
|
|
7391
|
+
const schemas6 = isObject7(meta) ? meta.schemas : void 0;
|
|
7392
|
+
const exportSchemas = isObject7(meta) ? meta.exportSchemas : void 0;
|
|
7393
|
+
const declared = isObject7(meta) && isObject7(meta.$meta) ? meta.$meta.exports : void 0;
|
|
7394
|
+
const version = isObject7(pkg) && typeof pkg.version === "string" ? pkg.version : void 0;
|
|
6821
7395
|
return {
|
|
6822
7396
|
...version ? { version } : {},
|
|
6823
|
-
settings:
|
|
6824
|
-
...
|
|
6825
|
-
...
|
|
7397
|
+
settings: isObject7(schemas6) ? schemas6.settings : void 0,
|
|
7398
|
+
...isObject7(exportSchemas) ? { exportSchemas } : {},
|
|
7399
|
+
...isObject7(declared) ? { exports: Object.keys(declared) } : {}
|
|
6826
7400
|
};
|
|
6827
7401
|
}
|
|
6828
7402
|
async function loadSchema(source, context2) {
|
|
@@ -6846,7 +7420,7 @@ async function loadSchema(source, context2) {
|
|
|
6846
7420
|
};
|
|
6847
7421
|
}
|
|
6848
7422
|
function compileSettings(settings) {
|
|
6849
|
-
if (!
|
|
7423
|
+
if (!isObject7(settings)) return void 0;
|
|
6850
7424
|
const ajv = new Ajv({ allErrors: true, validateFormats: false });
|
|
6851
7425
|
try {
|
|
6852
7426
|
return { ok: true, validate: ajv.compile(settings) };
|
|
@@ -6950,7 +7524,7 @@ async function checkStepSettings(target, resolvedFlow, rawFlow, check, context2)
|
|
|
6950
7524
|
}
|
|
6951
7525
|
const validate2 = compiled.validate;
|
|
6952
7526
|
const step = stepOf(resolvedFlow, target.section, target.key);
|
|
6953
|
-
const config =
|
|
7527
|
+
const config = isObject7(step?.config) ? step.config : {};
|
|
6954
7528
|
const prepared = prepareSettings(config.settings ?? {});
|
|
6955
7529
|
const base = `${at}.config.settings`;
|
|
6956
7530
|
for (const { segments, reference } of prepared.deferred) {
|
|
@@ -7029,9 +7603,9 @@ async function validateFlowWithPackages(input, options = {}) {
|
|
|
7029
7603
|
continue;
|
|
7030
7604
|
}
|
|
7031
7605
|
for (const section of ENTRY_SECTIONS) {
|
|
7032
|
-
const steps =
|
|
7606
|
+
const steps = isObject8(rawFlow[section]) ? rawFlow[section] : {};
|
|
7033
7607
|
for (const [key, entry] of Object.entries(steps)) {
|
|
7034
|
-
if (!
|
|
7608
|
+
if (!isObject8(entry) || entry.package === void 0) continue;
|
|
7035
7609
|
const target = { flow: name, section, key, entry };
|
|
7036
7610
|
pending.push(
|
|
7037
7611
|
checkStepSettings(
|
|
@@ -7090,9 +7664,9 @@ function runFlowChecks(input, options) {
|
|
|
7090
7664
|
};
|
|
7091
7665
|
}
|
|
7092
7666
|
errors.push(...scope.errors);
|
|
7093
|
-
const config =
|
|
7667
|
+
const config = isObject8(input) ? input : {};
|
|
7094
7668
|
const flowsValue = config.flows;
|
|
7095
|
-
const flows =
|
|
7669
|
+
const flows = isObject8(flowsValue) ? flowsValue : void 0;
|
|
7096
7670
|
const allFlows = scope.allFlows;
|
|
7097
7671
|
const inScope = (path23) => {
|
|
7098
7672
|
const flow = flowOfPath(path23, allFlows);
|
|
@@ -7130,13 +7704,13 @@ function runFlowChecks(input, options) {
|
|
|
7130
7704
|
checks.push("flow:steps");
|
|
7131
7705
|
for (const flowName of scope.flows) {
|
|
7132
7706
|
const flowValue = flows?.[flowName];
|
|
7133
|
-
if (!
|
|
7707
|
+
if (!isObject8(flowValue)) continue;
|
|
7134
7708
|
const transformersValue = flowValue.transformers;
|
|
7135
|
-
if (
|
|
7709
|
+
if (isObject8(transformersValue)) {
|
|
7136
7710
|
for (const [name, transformerValue] of Object.entries(
|
|
7137
7711
|
transformersValue
|
|
7138
7712
|
)) {
|
|
7139
|
-
if (!
|
|
7713
|
+
if (!isObject8(transformerValue)) continue;
|
|
7140
7714
|
const result2 = validateStepEntry(transformerValue, "Transformer");
|
|
7141
7715
|
if (!result2.ok) {
|
|
7142
7716
|
errors.push({
|
|
@@ -7149,9 +7723,9 @@ function runFlowChecks(input, options) {
|
|
|
7149
7723
|
}
|
|
7150
7724
|
for (const [section, kind] of OPEN_STEP_KINDS) {
|
|
7151
7725
|
const steps = flowValue[section];
|
|
7152
|
-
if (!
|
|
7726
|
+
if (!isObject8(steps)) continue;
|
|
7153
7727
|
for (const [name, step] of Object.entries(steps)) {
|
|
7154
|
-
if (!
|
|
7728
|
+
if (!isObject8(step)) continue;
|
|
7155
7729
|
const at = `flows.${flowName}.${section}.${name}`;
|
|
7156
7730
|
for (const key of unknownStepKeys(step, kind)) {
|
|
7157
7731
|
warnings.push({
|
|
@@ -7180,15 +7754,15 @@ function runFlowChecks(input, options) {
|
|
|
7180
7754
|
let totalPackageCount = 0;
|
|
7181
7755
|
for (const flowName of scope.flows) {
|
|
7182
7756
|
const flowValue = flows?.[flowName];
|
|
7183
|
-
if (!
|
|
7757
|
+
if (!isObject8(flowValue)) continue;
|
|
7184
7758
|
const flowConfig = flowValue.config;
|
|
7185
|
-
if (!
|
|
7759
|
+
if (!isObject8(flowConfig)) continue;
|
|
7186
7760
|
const bundle2 = flowConfig.bundle;
|
|
7187
|
-
if (!
|
|
7761
|
+
if (!isObject8(bundle2)) continue;
|
|
7188
7762
|
const packages = bundle2.packages;
|
|
7189
|
-
if (!
|
|
7763
|
+
if (!isObject8(packages)) continue;
|
|
7190
7764
|
for (const [pkgName, pkgConfigValue] of Object.entries(packages)) {
|
|
7191
|
-
if (!
|
|
7765
|
+
if (!isObject8(pkgConfigValue)) continue;
|
|
7192
7766
|
if (!pkgConfigValue.version && !pkgConfigValue.path) {
|
|
7193
7767
|
warnings.push({
|
|
7194
7768
|
path: `flows.${flowName}.config.bundle.packages.${pkgName}`,
|
|
@@ -7275,13 +7849,13 @@ function runFlowChecks(input, options) {
|
|
|
7275
7849
|
warnings,
|
|
7276
7850
|
options.strict === true,
|
|
7277
7851
|
skipped,
|
|
7278
|
-
|
|
7852
|
+
isObject8(resolvedConfig) && isObject8(resolvedConfig.settings) ? resolvedConfig.settings : void 0
|
|
7279
7853
|
);
|
|
7280
7854
|
}
|
|
7281
7855
|
for (const [destName, dest] of Object.entries(flow.destinations || {})) {
|
|
7282
|
-
if (!
|
|
7856
|
+
if (!isObject8(dest.config)) continue;
|
|
7283
7857
|
const mapping = dest.config.mapping;
|
|
7284
|
-
if (!
|
|
7858
|
+
if (!isObject8(mapping)) continue;
|
|
7285
7859
|
for (const key of Object.keys(mapping)) {
|
|
7286
7860
|
if (key.includes(".") && !key.includes(" ")) {
|
|
7287
7861
|
const parts = key.split(".");
|
|
@@ -7449,21 +8023,21 @@ function isStepOut(value) {
|
|
|
7449
8023
|
return Array.isArray(value) && value.every((entry) => Array.isArray(entry) && typeof entry[0] === "string");
|
|
7450
8024
|
}
|
|
7451
8025
|
function returnedEvents(value) {
|
|
7452
|
-
if (
|
|
8026
|
+
if (isObject8(value)) return [isObject8(value.event) ? value.event : value];
|
|
7453
8027
|
if (Array.isArray(value)) return value.flatMap(returnedEvents);
|
|
7454
8028
|
return [];
|
|
7455
8029
|
}
|
|
7456
8030
|
function outEvents(out) {
|
|
7457
8031
|
if (isStepOut(out)) {
|
|
7458
8032
|
return out.flatMap(([head, first]) => {
|
|
7459
|
-
if (head === "elb") return
|
|
8033
|
+
if (head === "elb") return isObject8(first) ? [first] : [];
|
|
7460
8034
|
if (head === "return") return returnedEvents(first);
|
|
7461
8035
|
return [];
|
|
7462
8036
|
});
|
|
7463
8037
|
}
|
|
7464
8038
|
if (Array.isArray(out) || typeof out === "string")
|
|
7465
8039
|
return out.length > 0 ? [out] : [];
|
|
7466
|
-
return
|
|
8040
|
+
return isObject8(out) && Object.keys(out).length > 0 ? [out] : [];
|
|
7467
8041
|
}
|
|
7468
8042
|
function hasComparableOut(out) {
|
|
7469
8043
|
return outEvents(out).length > 0;
|
|
@@ -7505,7 +8079,7 @@ function routeAt(spec, path23) {
|
|
|
7505
8079
|
for (const key of path23) {
|
|
7506
8080
|
if (typeof key === "number")
|
|
7507
8081
|
current = Array.isArray(current) ? current[key] : void 0;
|
|
7508
|
-
else current =
|
|
8082
|
+
else current = isObject8(current) ? current[key] : void 0;
|
|
7509
8083
|
}
|
|
7510
8084
|
return current;
|
|
7511
8085
|
}
|
|
@@ -7530,7 +8104,7 @@ function lintRoute(spec, position, known, errors, warnings) {
|
|
|
7530
8104
|
if (node.stop && !node.match && node.kind !== "many") {
|
|
7531
8105
|
const self = routeAt(spec, node.path);
|
|
7532
8106
|
const list = routeAt(spec, node.path.slice(0, -1));
|
|
7533
|
-
if (
|
|
8107
|
+
if (isObject8(self) && self.stop === true && typeof last === "number" && Array.isArray(list) && last < list.length - 1 && once(`stop:${where(node.path)}`)) {
|
|
7534
8108
|
const at = where(node.path);
|
|
7535
8109
|
warnings.push({
|
|
7536
8110
|
path: at,
|
|
@@ -7596,7 +8170,7 @@ function resolveStepContracts(entries, contract) {
|
|
|
7596
8170
|
}
|
|
7597
8171
|
const sources = [];
|
|
7598
8172
|
for (const [index, entry] of entries.entries()) {
|
|
7599
|
-
if (
|
|
8173
|
+
if (isObject8(entry)) {
|
|
7600
8174
|
sources.push(entry);
|
|
7601
8175
|
continue;
|
|
7602
8176
|
}
|
|
@@ -7614,7 +8188,7 @@ function resolveStepContracts(entries, contract) {
|
|
|
7614
8188
|
message: `contract "${match[1]}" is not defined in the root contract (defined: ${Object.keys(resolved).join(", ") || "none"})`
|
|
7615
8189
|
};
|
|
7616
8190
|
const rule = match[2] ? getByPath(resolved[match[1]], match[2]) : resolved[match[1]];
|
|
7617
|
-
if (!
|
|
8191
|
+
if (!isObject8(rule))
|
|
7618
8192
|
return {
|
|
7619
8193
|
ok: false,
|
|
7620
8194
|
index,
|
|
@@ -7625,7 +8199,7 @@ function resolveStepContracts(entries, contract) {
|
|
|
7625
8199
|
return { ok: true, sources };
|
|
7626
8200
|
}
|
|
7627
8201
|
function checkValidateStepExamples(stepPath, step, contract, errors, warnings, strict, skipped, resolvedSettings) {
|
|
7628
|
-
const settings = resolvedSettings ?? (
|
|
8202
|
+
const settings = resolvedSettings ?? (isObject8(step.config) && isObject8(step.config.settings) ? step.config.settings : {});
|
|
7629
8203
|
const contractPath = `${stepPath}.config.settings.contract`;
|
|
7630
8204
|
if (settings.contract !== void 0 && !Array.isArray(settings.contract)) {
|
|
7631
8205
|
if (step.examples)
|
|
@@ -7650,10 +8224,10 @@ function checkValidateStepExamples(stepPath, step, contract, errors, warnings, s
|
|
|
7650
8224
|
const contracts = resolution.sources;
|
|
7651
8225
|
const mode = settings.mode === "strict" ? "strict" : "pass";
|
|
7652
8226
|
const format = settings.format === true;
|
|
7653
|
-
const output =
|
|
8227
|
+
const output = isObject8(settings.output) ? settings.output : {};
|
|
7654
8228
|
const isValidPath = typeof output.isValid === "string" ? output.isValid : "source.valid";
|
|
7655
8229
|
for (const [exName, example] of Object.entries(step.examples)) {
|
|
7656
|
-
if (example.command || !
|
|
8230
|
+
if (example.command || !isObject8(example.in)) continue;
|
|
7657
8231
|
if (example.out === void 0) continue;
|
|
7658
8232
|
const event = example.in;
|
|
7659
8233
|
const verdict = validateEventAgainstContract(event, void 0, {
|
|
@@ -7691,14 +8265,14 @@ function checkValidateStepExamples(stepPath, step, contract, errors, warnings, s
|
|
|
7691
8265
|
}
|
|
7692
8266
|
|
|
7693
8267
|
// src/commands/validate/validators/mapping.ts
|
|
7694
|
-
import { isObject as
|
|
8268
|
+
import { isObject as isObject9 } from "@walkeros/core";
|
|
7695
8269
|
import { schemas as schemas5 } from "@walkeros/core/dev";
|
|
7696
8270
|
var { RuleSchema } = schemas5.MappingSchemas;
|
|
7697
8271
|
function isRule(value) {
|
|
7698
|
-
return
|
|
8272
|
+
return isObject9(value) && RuleSchema.safeParse(value).success;
|
|
7699
8273
|
}
|
|
7700
8274
|
function isNestedActions(key, value) {
|
|
7701
|
-
if (key.includes(" ") || !
|
|
8275
|
+
if (key.includes(" ") || !isObject9(value)) return false;
|
|
7702
8276
|
const rules = Object.values(value);
|
|
7703
8277
|
return rules.length > 0 && rules.every(
|
|
7704
8278
|
(rule) => Array.isArray(rule) ? rule.length > 0 && rule.every(isRule) : isRule(rule)
|
|
@@ -7708,7 +8282,7 @@ function validateMapping(input) {
|
|
|
7708
8282
|
const errors = [];
|
|
7709
8283
|
const warnings = [];
|
|
7710
8284
|
const details = {};
|
|
7711
|
-
if (!
|
|
8285
|
+
if (!isObject9(input)) {
|
|
7712
8286
|
errors.push({
|
|
7713
8287
|
path: "root",
|
|
7714
8288
|
message: "Mapping must be an object with event patterns as keys",
|
|
@@ -7931,7 +8505,7 @@ function inapplicableOptions(type, options) {
|
|
|
7931
8505
|
}
|
|
7932
8506
|
function validateContractInput(input) {
|
|
7933
8507
|
if (!isFlowJson2(input)) return validateContract(input);
|
|
7934
|
-
const contract =
|
|
8508
|
+
const contract = isObject10(input) ? input.contract : void 0;
|
|
7935
8509
|
if (contract === void 0) {
|
|
7936
8510
|
return {
|
|
7937
8511
|
valid: false,
|
|
@@ -8194,8 +8768,10 @@ async function loginCommand(options) {
|
|
|
8194
8768
|
}
|
|
8195
8769
|
async function fetchEmail(appUrl, accessToken, fetchFn) {
|
|
8196
8770
|
try {
|
|
8197
|
-
const response = await
|
|
8198
|
-
|
|
8771
|
+
const response = await apiRequest("GET /api/auth/whoami", {
|
|
8772
|
+
auth: { token: accessToken },
|
|
8773
|
+
baseUrl: appUrl,
|
|
8774
|
+
fetch: fetchFn,
|
|
8199
8775
|
signal: AbortSignal.timeout(WHOAMI_TIMEOUT_MS)
|
|
8200
8776
|
});
|
|
8201
8777
|
if (!response.ok) return void 0;
|
|
@@ -8334,121 +8910,6 @@ async function logout() {
|
|
|
8334
8910
|
|
|
8335
8911
|
// src/core/api-client.ts
|
|
8336
8912
|
import createClient from "openapi-fetch";
|
|
8337
|
-
|
|
8338
|
-
// src/core/contract.ts
|
|
8339
|
-
import { createHash as createHash2 } from "crypto";
|
|
8340
|
-
import semver4 from "semver";
|
|
8341
|
-
var bakedContractVersion = true ? "4.7.0" : PLACEHOLDER;
|
|
8342
|
-
var bakedContractHash = true ? "1758bf6b37ad72eb37dd8176f240ae64b16c5b1f9da376cab6357027c835a833" : "";
|
|
8343
|
-
function isRecord4(value) {
|
|
8344
|
-
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
8345
|
-
}
|
|
8346
|
-
function canonicalize(value) {
|
|
8347
|
-
if (Array.isArray(value)) {
|
|
8348
|
-
return value.map(canonicalize);
|
|
8349
|
-
}
|
|
8350
|
-
if (isRecord4(value)) {
|
|
8351
|
-
const result = {};
|
|
8352
|
-
for (const key of Object.keys(value).sort()) {
|
|
8353
|
-
result[key] = canonicalize(value[key]);
|
|
8354
|
-
}
|
|
8355
|
-
return result;
|
|
8356
|
-
}
|
|
8357
|
-
return value;
|
|
8358
|
-
}
|
|
8359
|
-
function stripInfoVersion(doc) {
|
|
8360
|
-
if (!isRecord4(doc) || !isRecord4(doc.info)) {
|
|
8361
|
-
return doc;
|
|
8362
|
-
}
|
|
8363
|
-
const restInfo = {};
|
|
8364
|
-
for (const [key, value] of Object.entries(doc.info)) {
|
|
8365
|
-
if (key !== "version") restInfo[key] = value;
|
|
8366
|
-
}
|
|
8367
|
-
return { ...doc, info: restInfo };
|
|
8368
|
-
}
|
|
8369
|
-
function canonicalContractHash(doc) {
|
|
8370
|
-
const canonical = canonicalize(stripInfoVersion(doc));
|
|
8371
|
-
return createHash2("sha256").update(JSON.stringify(canonical)).digest("hex");
|
|
8372
|
-
}
|
|
8373
|
-
var HEALTH_TIMEOUT_MS = 5e3;
|
|
8374
|
-
async function fetchHealth(baseUrl) {
|
|
8375
|
-
try {
|
|
8376
|
-
const res = await fetch(`${baseUrl ?? resolveAppUrl()}/api/health`, {
|
|
8377
|
-
signal: AbortSignal.timeout(HEALTH_TIMEOUT_MS)
|
|
8378
|
-
});
|
|
8379
|
-
const body = await res.json().catch(() => void 0);
|
|
8380
|
-
const result = { reachable: true };
|
|
8381
|
-
if (isRecord4(body)) {
|
|
8382
|
-
const record = body;
|
|
8383
|
-
if (typeof record.status === "string") result.status = record.status;
|
|
8384
|
-
if (typeof record.appVersion === "string")
|
|
8385
|
-
result.appVersion = record.appVersion;
|
|
8386
|
-
if (typeof record.contractVersion === "string")
|
|
8387
|
-
result.contractVersion = record.contractVersion;
|
|
8388
|
-
if (typeof record.contractHash === "string")
|
|
8389
|
-
result.contractHash = record.contractHash;
|
|
8390
|
-
}
|
|
8391
|
-
return result;
|
|
8392
|
-
} catch {
|
|
8393
|
-
return { reachable: false };
|
|
8394
|
-
}
|
|
8395
|
-
}
|
|
8396
|
-
async function compareContract(input = {}) {
|
|
8397
|
-
const bakedVersion = input.bakedVersion ?? bakedContractVersion;
|
|
8398
|
-
const bakedHash = input.bakedHash ?? bakedContractHash;
|
|
8399
|
-
const health = await fetchHealth(input.baseUrl);
|
|
8400
|
-
if (!health.reachable || health.contractVersion === void 0 || health.contractHash === void 0) {
|
|
8401
|
-
return { verdict: "unknown", bakedVersion };
|
|
8402
|
-
}
|
|
8403
|
-
const liveVersion = health.contractVersion;
|
|
8404
|
-
if (health.contractHash === bakedHash) {
|
|
8405
|
-
return { verdict: "in-sync", bakedVersion, liveVersion };
|
|
8406
|
-
}
|
|
8407
|
-
const liveNewer = semver4.valid(liveVersion) && semver4.valid(bakedVersion) ? semver4.gt(liveVersion, bakedVersion) : liveVersion > bakedVersion;
|
|
8408
|
-
if (liveNewer) {
|
|
8409
|
-
return {
|
|
8410
|
-
verdict: "client-older",
|
|
8411
|
-
bakedVersion,
|
|
8412
|
-
liveVersion,
|
|
8413
|
-
action: `upgrade @walkeros/cli to >= ${liveVersion}`
|
|
8414
|
-
};
|
|
8415
|
-
}
|
|
8416
|
-
return { verdict: "client-newer", bakedVersion, liveVersion };
|
|
8417
|
-
}
|
|
8418
|
-
async function annotateErrorWithDrift(error, input = {}) {
|
|
8419
|
-
const comparison = await compareContract(input).catch(
|
|
8420
|
-
() => ({
|
|
8421
|
-
verdict: "unknown",
|
|
8422
|
-
bakedVersion: input.bakedVersion ?? bakedContractVersion
|
|
8423
|
-
})
|
|
8424
|
-
);
|
|
8425
|
-
if (comparison.verdict !== "client-older" || !comparison.action) {
|
|
8426
|
-
return error;
|
|
8427
|
-
}
|
|
8428
|
-
const annotated = new Error(
|
|
8429
|
-
`${error.message}
|
|
8430
|
-
|
|
8431
|
-
The server runs contract ${comparison.liveVersion}, this client was built against ${comparison.bakedVersion}. This may be the cause: ${comparison.action}.`
|
|
8432
|
-
);
|
|
8433
|
-
annotated.stack = error.stack;
|
|
8434
|
-
return annotated;
|
|
8435
|
-
}
|
|
8436
|
-
|
|
8437
|
-
// src/core/api-client.ts
|
|
8438
|
-
var driftWarned = false;
|
|
8439
|
-
function emitDriftWarning(responseHeaders) {
|
|
8440
|
-
if (driftWarned) return;
|
|
8441
|
-
const serverVersion = responseHeaders.get("X-WalkerOS-Server-Version");
|
|
8442
|
-
if (!serverVersion) return;
|
|
8443
|
-
if (serverVersion === bakedContractVersion) return;
|
|
8444
|
-
driftWarned = true;
|
|
8445
|
-
const minClient = responseHeaders.get("X-WalkerOS-Min-Client");
|
|
8446
|
-
const minNote = minClient ? ` (min client ${minClient})` : "";
|
|
8447
|
-
process.stderr.write(
|
|
8448
|
-
`walkerOS: server contract version is ${serverVersion}${minNote}, this client was built against ${bakedContractVersion}. Run \`walkeros diagnostics\` or upgrade @walkeros/cli if commands misbehave.
|
|
8449
|
-
`
|
|
8450
|
-
);
|
|
8451
|
-
}
|
|
8452
8913
|
function createApiClient() {
|
|
8453
8914
|
const client = createClient({
|
|
8454
8915
|
baseUrl: resolveAppUrl(),
|
|
@@ -8468,12 +8929,6 @@ function createApiClient() {
|
|
|
8468
8929
|
requireSecureUrl(request.url);
|
|
8469
8930
|
request.headers.set("Authorization", `Bearer ${token}`);
|
|
8470
8931
|
return request;
|
|
8471
|
-
},
|
|
8472
|
-
// Surface contract drift once per process from any response's version
|
|
8473
|
-
// headers. openapi-fetch ^0.17 supports `use({ onResponse })`.
|
|
8474
|
-
onResponse({ response }) {
|
|
8475
|
-
emitDriftWarning(response.headers);
|
|
8476
|
-
return void 0;
|
|
8477
8932
|
}
|
|
8478
8933
|
});
|
|
8479
8934
|
return client;
|
|
@@ -8896,9 +9351,10 @@ async function getAvailableFlowNames(options) {
|
|
|
8896
9351
|
var DEFAULT_DEPLOY_WAIT_MS = 12 * 60 * 1e3;
|
|
8897
9352
|
async function streamDeploymentStatus(projectId, deploymentId, options) {
|
|
8898
9353
|
const timeoutMs = options.timeout ?? DEFAULT_DEPLOY_WAIT_MS;
|
|
8899
|
-
const response = await
|
|
8900
|
-
|
|
9354
|
+
const response = await apiRequest(
|
|
9355
|
+
"GET /api/projects/{projectId}/deployments/{deploymentId}/stream",
|
|
8901
9356
|
{
|
|
9357
|
+
path: { projectId, deploymentId },
|
|
8902
9358
|
headers: { Accept: "text/event-stream" },
|
|
8903
9359
|
signal: options.signal ?? AbortSignal.timeout(timeoutMs)
|
|
8904
9360
|
}
|
|
@@ -8987,9 +9443,12 @@ Available: ${names.join(", ")}`,
|
|
|
8987
9443
|
}
|
|
8988
9444
|
async function deploySettings(options) {
|
|
8989
9445
|
const { flowId, projectId, settingsId } = options;
|
|
8990
|
-
const triggerDeploy = () =>
|
|
8991
|
-
|
|
8992
|
-
{
|
|
9446
|
+
const triggerDeploy = () => apiRequest(
|
|
9447
|
+
"POST /api/projects/{projectId}/flows/{flowId}/settings/{settingsId}/deploy",
|
|
9448
|
+
{
|
|
9449
|
+
path: { projectId, flowId, settingsId },
|
|
9450
|
+
headers: { "Idempotency-Key": randomUUID() }
|
|
9451
|
+
}
|
|
8993
9452
|
);
|
|
8994
9453
|
let response = await triggerDeploy();
|
|
8995
9454
|
if (!response.ok && options.wait) {
|
|
@@ -9037,8 +9496,9 @@ async function getDeployment(options) {
|
|
|
9037
9496
|
projectId,
|
|
9038
9497
|
flowName: options.flowName
|
|
9039
9498
|
});
|
|
9040
|
-
const response = await
|
|
9041
|
-
|
|
9499
|
+
const response = await apiRequest(
|
|
9500
|
+
"GET /api/projects/{projectId}/flows/{flowId}/settings/{settingsId}/deploy",
|
|
9501
|
+
{ path: { projectId, flowId: options.flowId, settingsId } }
|
|
9042
9502
|
);
|
|
9043
9503
|
if (!response.ok) {
|
|
9044
9504
|
const body = await response.json().catch(() => ({}));
|
|
@@ -9133,18 +9593,39 @@ async function getDeploymentCommand(flowId, options) {
|
|
|
9133
9593
|
}
|
|
9134
9594
|
|
|
9135
9595
|
// src/commands/deployments/index.ts
|
|
9136
|
-
import { getPlatform as getPlatform4, isObject as
|
|
9596
|
+
import { getPlatform as getPlatform4, isObject as isObject11 } from "@walkeros/core";
|
|
9597
|
+
var DEPLOYMENT_STATUSES = {
|
|
9598
|
+
idle: true,
|
|
9599
|
+
deploying: true,
|
|
9600
|
+
published: true,
|
|
9601
|
+
active: true,
|
|
9602
|
+
stopped: true,
|
|
9603
|
+
failed: true
|
|
9604
|
+
};
|
|
9605
|
+
var DEPLOYMENT_TYPES = {
|
|
9606
|
+
web: true,
|
|
9607
|
+
server: true
|
|
9608
|
+
};
|
|
9609
|
+
function isMember(members, value) {
|
|
9610
|
+
return Object.hasOwn(members, value);
|
|
9611
|
+
}
|
|
9612
|
+
function isDeploymentStatus(value) {
|
|
9613
|
+
return isMember(DEPLOYMENT_STATUSES, value);
|
|
9614
|
+
}
|
|
9137
9615
|
async function listDeployments(options = {}) {
|
|
9138
9616
|
const id = options.projectId ?? requireProjectId();
|
|
9139
|
-
const
|
|
9140
|
-
|
|
9141
|
-
|
|
9142
|
-
|
|
9143
|
-
|
|
9144
|
-
|
|
9145
|
-
|
|
9146
|
-
|
|
9147
|
-
|
|
9617
|
+
const response = await apiRequest(
|
|
9618
|
+
"GET /api/projects/{projectId}/deployments",
|
|
9619
|
+
{
|
|
9620
|
+
path: { projectId: id },
|
|
9621
|
+
query: {
|
|
9622
|
+
type: options.type,
|
|
9623
|
+
status: options.status,
|
|
9624
|
+
flowId: options.flowId || void 0,
|
|
9625
|
+
cursor: options.cursor || void 0,
|
|
9626
|
+
limit: options.limit
|
|
9627
|
+
}
|
|
9628
|
+
}
|
|
9148
9629
|
);
|
|
9149
9630
|
if (!response.ok) {
|
|
9150
9631
|
const body = await response.json().catch(() => ({}));
|
|
@@ -9191,8 +9672,9 @@ async function deleteDeploymentByFlowId(options) {
|
|
|
9191
9672
|
}
|
|
9192
9673
|
async function getDeploymentBySlug(options) {
|
|
9193
9674
|
const id = options.projectId ?? requireProjectId();
|
|
9194
|
-
const response = await
|
|
9195
|
-
|
|
9675
|
+
const response = await apiRequest(
|
|
9676
|
+
"GET /api/projects/{projectId}/deployments/{deploymentId}",
|
|
9677
|
+
{ path: { projectId: id, deploymentId: options.slug } }
|
|
9196
9678
|
);
|
|
9197
9679
|
if (!response.ok) {
|
|
9198
9680
|
const body = await response.json().catch(() => ({}));
|
|
@@ -9202,11 +9684,13 @@ async function getDeploymentBySlug(options) {
|
|
|
9202
9684
|
}
|
|
9203
9685
|
async function createDeployment(options) {
|
|
9204
9686
|
const id = options.projectId ?? requireProjectId();
|
|
9205
|
-
const response = await
|
|
9206
|
-
|
|
9207
|
-
|
|
9208
|
-
|
|
9209
|
-
|
|
9687
|
+
const response = await apiRequest(
|
|
9688
|
+
"POST /api/projects/{projectId}/deployments",
|
|
9689
|
+
{
|
|
9690
|
+
path: { projectId: id },
|
|
9691
|
+
body: { type: options.type, label: options.label }
|
|
9692
|
+
}
|
|
9693
|
+
);
|
|
9210
9694
|
if (!response.ok) {
|
|
9211
9695
|
const body = await response.json().catch(() => ({}));
|
|
9212
9696
|
throwApiError(body, "Failed to create deployment");
|
|
@@ -9215,9 +9699,9 @@ async function createDeployment(options) {
|
|
|
9215
9699
|
}
|
|
9216
9700
|
async function deleteDeployment(options) {
|
|
9217
9701
|
const id = options.projectId ?? requireProjectId();
|
|
9218
|
-
const response = await
|
|
9219
|
-
|
|
9220
|
-
{
|
|
9702
|
+
const response = await apiRequest(
|
|
9703
|
+
"DELETE /api/projects/{projectId}/deployments/{deploymentId}",
|
|
9704
|
+
{ path: { projectId: id, deploymentId: options.slug } }
|
|
9221
9705
|
);
|
|
9222
9706
|
if (!response.ok) {
|
|
9223
9707
|
const body = await response.json().catch(() => ({}));
|
|
@@ -9226,6 +9710,11 @@ async function deleteDeployment(options) {
|
|
|
9226
9710
|
const data = await response.json().catch(() => null);
|
|
9227
9711
|
return data ?? { success: true };
|
|
9228
9712
|
}
|
|
9713
|
+
function flagValue(flag, value, members) {
|
|
9714
|
+
if (value === void 0) return void 0;
|
|
9715
|
+
if (isMember(members, value)) return value;
|
|
9716
|
+
throw new Error(`${flag} must be one of: ${Object.keys(members).join(", ")}`);
|
|
9717
|
+
}
|
|
9229
9718
|
async function handleResult3(fn, options) {
|
|
9230
9719
|
try {
|
|
9231
9720
|
const result = await fn();
|
|
@@ -9238,8 +9727,8 @@ async function listDeploymentsCommand(options) {
|
|
|
9238
9727
|
await handleResult3(
|
|
9239
9728
|
() => listDeployments({
|
|
9240
9729
|
projectId: options.project,
|
|
9241
|
-
type: options.type,
|
|
9242
|
-
status: options.status,
|
|
9730
|
+
type: flagValue("--type", options.type, DEPLOYMENT_TYPES),
|
|
9731
|
+
status: flagValue("--status", options.status, DEPLOYMENT_STATUSES),
|
|
9243
9732
|
cursor: options.cursor,
|
|
9244
9733
|
limit: options.limit
|
|
9245
9734
|
}),
|
|
@@ -9281,21 +9770,23 @@ async function createDeployCommand(config, options) {
|
|
|
9281
9770
|
const isRemoteFlow = config.startsWith("cfg_");
|
|
9282
9771
|
if (isRemoteFlow) {
|
|
9283
9772
|
const id = options.project ?? requireProjectId();
|
|
9284
|
-
const resp = await
|
|
9773
|
+
const resp = await apiRequest(
|
|
9774
|
+
"GET /api/projects/{projectId}/flows/{flowId}",
|
|
9775
|
+
{ path: { projectId: id, flowId: config } }
|
|
9776
|
+
);
|
|
9285
9777
|
if (!resp.ok) {
|
|
9286
9778
|
const body = await resp.json().catch(() => ({}));
|
|
9287
9779
|
throwApiError(body, `Failed to fetch flow ${config}`);
|
|
9288
9780
|
}
|
|
9289
9781
|
const flow = await resp.json();
|
|
9290
9782
|
if (!flow.config) throw new Error("Flow has no config");
|
|
9291
|
-
const
|
|
9292
|
-
const flows = flowConfig.flows;
|
|
9783
|
+
const flows = flow.config.flows;
|
|
9293
9784
|
if (!flows) throw new Error("Invalid flow config: missing flows");
|
|
9294
9785
|
const flowName = options.flow ?? Object.keys(flows)[0];
|
|
9295
9786
|
if (!flowName) throw new Error("No flows found in config");
|
|
9296
9787
|
const flowSettings = flows[flowName];
|
|
9297
|
-
if (!
|
|
9298
|
-
const platform =
|
|
9788
|
+
if (!isObject11(flowSettings)) throw new Error("Invalid flow config");
|
|
9789
|
+
const platform = isObject11(flowSettings.config) ? flowSettings.config.platform : void 0;
|
|
9299
9790
|
if (platform !== "web" && platform !== "server")
|
|
9300
9791
|
throw new Error(
|
|
9301
9792
|
`Flow "${flowName}" must have config.platform set to "web" or "server"`
|
|
@@ -9375,10 +9866,9 @@ async function feedback(text, options) {
|
|
|
9375
9866
|
payload.projectId = projectId;
|
|
9376
9867
|
}
|
|
9377
9868
|
}
|
|
9378
|
-
const response = await
|
|
9379
|
-
|
|
9380
|
-
|
|
9381
|
-
body: JSON.stringify(payload)
|
|
9869
|
+
const response = await apiRequest("POST /api/feedback", {
|
|
9870
|
+
auth: "none",
|
|
9871
|
+
body: payload
|
|
9382
9872
|
});
|
|
9383
9873
|
if (!response.ok) {
|
|
9384
9874
|
throw new Error(
|
|
@@ -9591,9 +10081,16 @@ async function wrapSkeleton(options) {
|
|
|
9591
10081
|
};
|
|
9592
10082
|
if (platform === "browser") {
|
|
9593
10083
|
esbuildOptions.format = "iife";
|
|
10084
|
+
const needs = readNeedsMarker(skeletonText);
|
|
9594
10085
|
esbuildOptions.define = {
|
|
9595
10086
|
"process.env.NODE_ENV": '"production"',
|
|
9596
|
-
global: "globalThis"
|
|
10087
|
+
global: "globalThis",
|
|
10088
|
+
...buildFlagDefines(
|
|
10089
|
+
needs && {
|
|
10090
|
+
...needs,
|
|
10091
|
+
observe: needs.observe || options.observe !== void 0
|
|
10092
|
+
}
|
|
10093
|
+
)
|
|
9597
10094
|
};
|
|
9598
10095
|
esbuildOptions.external = devExternals;
|
|
9599
10096
|
esbuildOptions.target = target ?? "es2018";
|
|
@@ -10094,11 +10591,219 @@ function resolveManifestSource(manifest, env = process.env) {
|
|
|
10094
10591
|
return fromEnv;
|
|
10095
10592
|
}
|
|
10096
10593
|
|
|
10594
|
+
// src/core/contract.ts
|
|
10595
|
+
import { createHash as createHash3 } from "crypto";
|
|
10596
|
+
import semver4 from "semver";
|
|
10597
|
+
var bakedContractVersion = true ? "4.7.0+80fb4d79" : PLACEHOLDER;
|
|
10598
|
+
var bakedContractHash = true ? "7096fd745fbe3993fe5f1f90d87aec45b20ff8d15adce2c3b0f871f99b0183de" : "";
|
|
10599
|
+
var bakedClientOperations = typeof define_CLIENT_OPERATION_DIGESTS_default === "object" ? define_CLIENT_OPERATION_DIGESTS_default : [];
|
|
10600
|
+
function isRecord5(value) {
|
|
10601
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
10602
|
+
}
|
|
10603
|
+
function stripInfoVersion(doc) {
|
|
10604
|
+
if (!isRecord5(doc) || !isRecord5(doc.info)) {
|
|
10605
|
+
return doc;
|
|
10606
|
+
}
|
|
10607
|
+
const restInfo = {};
|
|
10608
|
+
for (const [key, value] of Object.entries(doc.info)) {
|
|
10609
|
+
if (key !== "version") restInfo[key] = value;
|
|
10610
|
+
}
|
|
10611
|
+
return { ...doc, info: restInfo };
|
|
10612
|
+
}
|
|
10613
|
+
function canonicalContractHash(doc) {
|
|
10614
|
+
const canonical = canonicalize(stripInfoVersion(doc));
|
|
10615
|
+
return createHash3("sha256").update(JSON.stringify(canonical)).digest("hex");
|
|
10616
|
+
}
|
|
10617
|
+
var HEALTH_TIMEOUT_MS = 5e3;
|
|
10618
|
+
var OPENAPI_TIMEOUT_MS = 1e4;
|
|
10619
|
+
function trimTrailingSlashes(url) {
|
|
10620
|
+
return url.replace(/\/+$/, "");
|
|
10621
|
+
}
|
|
10622
|
+
function failureReason(error, timeoutMs) {
|
|
10623
|
+
if (!isRecord5(error)) return String(error);
|
|
10624
|
+
if (error.name === "TimeoutError") return `timeout after ${timeoutMs} ms`;
|
|
10625
|
+
const message = typeof error.message === "string" ? error.message : String(error);
|
|
10626
|
+
const cause = error.cause;
|
|
10627
|
+
const code = isRecord5(cause) && typeof cause.code === "string" ? cause.code : void 0;
|
|
10628
|
+
return code ? `${message} (${code})` : message;
|
|
10629
|
+
}
|
|
10630
|
+
async function fetchHealth(baseUrl) {
|
|
10631
|
+
try {
|
|
10632
|
+
const res = await apiRequest("GET /api/health", {
|
|
10633
|
+
auth: "none",
|
|
10634
|
+
signal: AbortSignal.timeout(HEALTH_TIMEOUT_MS),
|
|
10635
|
+
...baseUrl === void 0 ? {} : { baseUrl }
|
|
10636
|
+
});
|
|
10637
|
+
const body = await res.json().catch(() => void 0);
|
|
10638
|
+
const result = { reachable: true };
|
|
10639
|
+
if (!res.ok) result.httpStatus = res.status;
|
|
10640
|
+
if (isRecord5(body)) {
|
|
10641
|
+
if (typeof body.status === "string") result.status = body.status;
|
|
10642
|
+
if (typeof body.appVersion === "string")
|
|
10643
|
+
result.appVersion = body.appVersion;
|
|
10644
|
+
if (typeof body.contractVersion === "string")
|
|
10645
|
+
result.contractVersion = body.contractVersion;
|
|
10646
|
+
if (typeof body.contractHash === "string")
|
|
10647
|
+
result.contractHash = body.contractHash;
|
|
10648
|
+
if (typeof body.minSupportedClient === "string")
|
|
10649
|
+
result.minSupportedClient = body.minSupportedClient;
|
|
10650
|
+
}
|
|
10651
|
+
return result;
|
|
10652
|
+
} catch (error) {
|
|
10653
|
+
return {
|
|
10654
|
+
reachable: false,
|
|
10655
|
+
error: failureReason(error, HEALTH_TIMEOUT_MS)
|
|
10656
|
+
};
|
|
10657
|
+
}
|
|
10658
|
+
}
|
|
10659
|
+
async function fetchOpenApi(baseUrl) {
|
|
10660
|
+
const base = baseUrl ?? trimTrailingSlashes(resolveAppUrl());
|
|
10661
|
+
const url = operationUrl("GET /api/openapi.json", { baseUrl: base });
|
|
10662
|
+
let res;
|
|
10663
|
+
try {
|
|
10664
|
+
res = await apiRequest("GET /api/openapi.json", {
|
|
10665
|
+
auth: "none",
|
|
10666
|
+
baseUrl: base,
|
|
10667
|
+
signal: AbortSignal.timeout(OPENAPI_TIMEOUT_MS)
|
|
10668
|
+
});
|
|
10669
|
+
} catch (error) {
|
|
10670
|
+
return { ok: false, url, error: failureReason(error, OPENAPI_TIMEOUT_MS) };
|
|
10671
|
+
}
|
|
10672
|
+
if (!res.ok) return { ok: false, url, error: `HTTP ${res.status}` };
|
|
10673
|
+
const document = await res.json().catch(() => void 0);
|
|
10674
|
+
if (!isRecord5(document)) {
|
|
10675
|
+
return { ok: false, url, error: "response is not JSON" };
|
|
10676
|
+
}
|
|
10677
|
+
if (!isRecord5(document.paths)) return { ok: false, url, error: "no paths" };
|
|
10678
|
+
return { ok: true, url, document };
|
|
10679
|
+
}
|
|
10680
|
+
function isBelow(version, floor) {
|
|
10681
|
+
return semver4.valid(version) !== null && semver4.valid(floor) !== null && semver4.lt(version, floor);
|
|
10682
|
+
}
|
|
10683
|
+
function serverFloorBelow(server, client) {
|
|
10684
|
+
if (server === void 0 || !server.includes("+")) return true;
|
|
10685
|
+
if (semver4.valid(server) === null) return true;
|
|
10686
|
+
return isBelow(server, client);
|
|
10687
|
+
}
|
|
10688
|
+
function documentLabel(document) {
|
|
10689
|
+
const info = document.info;
|
|
10690
|
+
return isRecord5(info) && typeof info.version === "string" ? info.version : void 0;
|
|
10691
|
+
}
|
|
10692
|
+
async function compareContract(input = {}) {
|
|
10693
|
+
const appUrl = trimTrailingSlashes(input.baseUrl ?? resolveAppUrl());
|
|
10694
|
+
const context2 = input.client ?? getClientContext() ?? { type: "cli", version: VERSION };
|
|
10695
|
+
const client = {
|
|
10696
|
+
package: `@walkeros/${context2.type}`,
|
|
10697
|
+
version: context2.version,
|
|
10698
|
+
contract: input.bakedVersion ?? bakedContractVersion
|
|
10699
|
+
};
|
|
10700
|
+
const operations = input.operations ?? bakedClientOperations;
|
|
10701
|
+
const health = await fetchHealth(appUrl);
|
|
10702
|
+
if (!health.reachable) {
|
|
10703
|
+
const url = operationUrl("GET /api/health", { baseUrl: appUrl });
|
|
10704
|
+
return {
|
|
10705
|
+
verdict: "unknown",
|
|
10706
|
+
appUrl,
|
|
10707
|
+
client,
|
|
10708
|
+
reason: `GET ${url}: ${health.error ?? "no response"}`
|
|
10709
|
+
};
|
|
10710
|
+
}
|
|
10711
|
+
const known = {
|
|
10712
|
+
verdict: "unknown",
|
|
10713
|
+
appUrl,
|
|
10714
|
+
client,
|
|
10715
|
+
...health.contractVersion !== void 0 && {
|
|
10716
|
+
server: health.contractVersion
|
|
10717
|
+
},
|
|
10718
|
+
...health.minSupportedClient !== void 0 && {
|
|
10719
|
+
minSupportedClient: health.minSupportedClient
|
|
10720
|
+
}
|
|
10721
|
+
};
|
|
10722
|
+
if (health.minSupportedClient !== void 0 && isBelow(client.version, health.minSupportedClient)) {
|
|
10723
|
+
return {
|
|
10724
|
+
...known,
|
|
10725
|
+
verdict: "client-outdated",
|
|
10726
|
+
requires: { package: client.package, version: health.minSupportedClient }
|
|
10727
|
+
};
|
|
10728
|
+
}
|
|
10729
|
+
if (operations.length === 0) {
|
|
10730
|
+
return { ...known, reason: "no baked client operations" };
|
|
10731
|
+
}
|
|
10732
|
+
const live = await fetchOpenApi(appUrl);
|
|
10733
|
+
if (!live.ok) {
|
|
10734
|
+
return { ...known, reason: `GET ${live.url}: ${live.error}` };
|
|
10735
|
+
}
|
|
10736
|
+
let liveDigests;
|
|
10737
|
+
try {
|
|
10738
|
+
liveDigests = operationDigests(
|
|
10739
|
+
live.document,
|
|
10740
|
+
operations.map(({ op }) => op)
|
|
10741
|
+
);
|
|
10742
|
+
} catch (error) {
|
|
10743
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
10744
|
+
return { ...known, reason: `GET ${live.url}: ${message}` };
|
|
10745
|
+
}
|
|
10746
|
+
const missing = operations.filter(({ op }) => !Object.hasOwn(liveDigests, op)).map(({ op, usedBy }) => ({ op, usedBy }));
|
|
10747
|
+
const changed = operations.filter(({ op, digest }) => {
|
|
10748
|
+
return Object.hasOwn(liveDigests, op) && liveDigests[op] !== digest;
|
|
10749
|
+
}).map(({ op }) => op);
|
|
10750
|
+
const server = known.server ?? documentLabel(live.document);
|
|
10751
|
+
const compared = {
|
|
10752
|
+
...known,
|
|
10753
|
+
...server !== void 0 && { server },
|
|
10754
|
+
operations: operations.length,
|
|
10755
|
+
missing,
|
|
10756
|
+
changed
|
|
10757
|
+
};
|
|
10758
|
+
if (missing.length > 0) return { ...compared, verdict: "server-older" };
|
|
10759
|
+
if (changed.length > 0) {
|
|
10760
|
+
const older = serverFloorBelow(server, client.contract);
|
|
10761
|
+
return { ...compared, verdict: older ? "server-older" : "changed" };
|
|
10762
|
+
}
|
|
10763
|
+
return { ...compared, verdict: "in-sync" };
|
|
10764
|
+
}
|
|
10765
|
+
function missingList(missing) {
|
|
10766
|
+
return missing.map(
|
|
10767
|
+
({ op, usedBy }) => usedBy.length > 0 ? `${op} (${usedBy.join(", ")})` : op
|
|
10768
|
+
).join(", ");
|
|
10769
|
+
}
|
|
10770
|
+
function formatContract(c) {
|
|
10771
|
+
const server = c.server ?? "without a label";
|
|
10772
|
+
const labels = `server ${server}, client ${c.client.contract}`;
|
|
10773
|
+
const missing = c.missing ?? [];
|
|
10774
|
+
const changed = c.changed ?? [];
|
|
10775
|
+
switch (c.verdict) {
|
|
10776
|
+
case "in-sync":
|
|
10777
|
+
return `contract: in-sync (${labels}, ${c.operations ?? 0} operations)`;
|
|
10778
|
+
case "changed":
|
|
10779
|
+
return `contract: changed (${labels}); changed: ${changed.join(", ")}`;
|
|
10780
|
+
case "server-older": {
|
|
10781
|
+
const parts = [`contract: server-older (${labels})`];
|
|
10782
|
+
if (missing.length > 0) {
|
|
10783
|
+
parts.push(`not offered (${missing.length}): ${missingList(missing)}`);
|
|
10784
|
+
}
|
|
10785
|
+
if (changed.length > 0) parts.push(`changed: ${changed.length}`);
|
|
10786
|
+
return parts.join("; ");
|
|
10787
|
+
}
|
|
10788
|
+
case "client-outdated": {
|
|
10789
|
+
const pkg = c.requires?.package ?? c.client.package;
|
|
10790
|
+
const floor = c.requires?.version ?? c.minSupportedClient;
|
|
10791
|
+
const requires = floor === void 0 ? "" : ` requires ${pkg} >= ${floor}`;
|
|
10792
|
+
return `contract: client-outdated (${c.appUrl}${requires}; this is ${c.client.version})`;
|
|
10793
|
+
}
|
|
10794
|
+
case "unknown":
|
|
10795
|
+
return `contract: unknown (${c.reason ?? "no reason given"})`;
|
|
10796
|
+
case "in-process":
|
|
10797
|
+
return `contract: in-process (server ${server})`;
|
|
10798
|
+
}
|
|
10799
|
+
}
|
|
10800
|
+
|
|
10097
10801
|
// src/commands/previews/index.ts
|
|
10098
10802
|
async function listPreviews(options) {
|
|
10099
10803
|
const pid = options.projectId ?? requireProjectId();
|
|
10100
|
-
const response = await
|
|
10101
|
-
|
|
10804
|
+
const response = await apiRequest(
|
|
10805
|
+
"GET /api/projects/{projectId}/flows/{flowId}/previews",
|
|
10806
|
+
{ path: { projectId: pid, flowId: options.flowId } }
|
|
10102
10807
|
);
|
|
10103
10808
|
if (!response.ok) {
|
|
10104
10809
|
const body = await response.json().catch(() => ({}));
|
|
@@ -10108,8 +10813,15 @@ async function listPreviews(options) {
|
|
|
10108
10813
|
}
|
|
10109
10814
|
async function getPreview(options) {
|
|
10110
10815
|
const pid = options.projectId ?? requireProjectId();
|
|
10111
|
-
const response = await
|
|
10112
|
-
|
|
10816
|
+
const response = await apiRequest(
|
|
10817
|
+
"GET /api/projects/{projectId}/flows/{flowId}/previews/{previewId}",
|
|
10818
|
+
{
|
|
10819
|
+
path: {
|
|
10820
|
+
projectId: pid,
|
|
10821
|
+
flowId: options.flowId,
|
|
10822
|
+
previewId: options.previewId
|
|
10823
|
+
}
|
|
10824
|
+
}
|
|
10113
10825
|
);
|
|
10114
10826
|
if (!response.ok) {
|
|
10115
10827
|
const body = await response.json().catch(() => ({}));
|
|
@@ -10142,15 +10854,14 @@ async function createPreview(options) {
|
|
|
10142
10854
|
}
|
|
10143
10855
|
settingsId = match.id;
|
|
10144
10856
|
}
|
|
10145
|
-
const response = await
|
|
10146
|
-
|
|
10857
|
+
const response = await apiRequest(
|
|
10858
|
+
"POST /api/projects/{projectId}/flows/{flowId}/previews",
|
|
10147
10859
|
{
|
|
10148
|
-
|
|
10149
|
-
|
|
10150
|
-
body: JSON.stringify({
|
|
10860
|
+
path: { projectId: pid, flowId: options.flowId },
|
|
10861
|
+
body: {
|
|
10151
10862
|
flowSettingsId: settingsId,
|
|
10152
10863
|
...options.source ? { source: options.source } : {}
|
|
10153
|
-
}
|
|
10864
|
+
}
|
|
10154
10865
|
}
|
|
10155
10866
|
);
|
|
10156
10867
|
if (!response.ok) {
|
|
@@ -10159,12 +10870,11 @@ async function createPreview(options) {
|
|
|
10159
10870
|
}
|
|
10160
10871
|
const created = await response.json();
|
|
10161
10872
|
if (origin === void 0) return created;
|
|
10162
|
-
const grantResponse = await
|
|
10163
|
-
|
|
10873
|
+
const grantResponse = await apiRequest(
|
|
10874
|
+
"POST /api/projects/{projectId}/flows/{flowId}/previews/{previewId}/grant",
|
|
10164
10875
|
{
|
|
10165
|
-
|
|
10166
|
-
|
|
10167
|
-
body: JSON.stringify({ origins: [origin] })
|
|
10876
|
+
path: { projectId: pid, flowId: options.flowId, previewId: created.id },
|
|
10877
|
+
body: { origins: [origin] }
|
|
10168
10878
|
}
|
|
10169
10879
|
);
|
|
10170
10880
|
if (!grantResponse.ok) {
|
|
@@ -10183,15 +10893,18 @@ async function createPreview(options) {
|
|
|
10183
10893
|
}
|
|
10184
10894
|
async function regrantPreview(options) {
|
|
10185
10895
|
const pid = options.projectId ?? requireProjectId();
|
|
10186
|
-
const response = await
|
|
10187
|
-
|
|
10896
|
+
const response = await apiRequest(
|
|
10897
|
+
"POST /api/projects/{projectId}/flows/{flowId}/previews/{previewId}/grant",
|
|
10188
10898
|
{
|
|
10189
|
-
|
|
10190
|
-
|
|
10191
|
-
|
|
10899
|
+
path: {
|
|
10900
|
+
projectId: pid,
|
|
10901
|
+
flowId: options.flowId,
|
|
10902
|
+
previewId: options.previewId
|
|
10903
|
+
},
|
|
10904
|
+
body: {
|
|
10192
10905
|
origins: options.origins,
|
|
10193
10906
|
...options.sessionId ? { sessionId: options.sessionId } : {}
|
|
10194
|
-
}
|
|
10907
|
+
}
|
|
10195
10908
|
}
|
|
10196
10909
|
);
|
|
10197
10910
|
if (!response.ok) {
|
|
@@ -10202,9 +10915,15 @@ async function regrantPreview(options) {
|
|
|
10202
10915
|
}
|
|
10203
10916
|
async function deletePreview(options) {
|
|
10204
10917
|
const pid = options.projectId ?? requireProjectId();
|
|
10205
|
-
const response = await
|
|
10206
|
-
|
|
10207
|
-
{
|
|
10918
|
+
const response = await apiRequest(
|
|
10919
|
+
"DELETE /api/projects/{projectId}/flows/{flowId}/previews/{previewId}",
|
|
10920
|
+
{
|
|
10921
|
+
path: {
|
|
10922
|
+
projectId: pid,
|
|
10923
|
+
flowId: options.flowId,
|
|
10924
|
+
previewId: options.previewId
|
|
10925
|
+
}
|
|
10926
|
+
}
|
|
10208
10927
|
);
|
|
10209
10928
|
if (!response.ok) {
|
|
10210
10929
|
const body = await response.json().catch(() => ({}));
|
|
@@ -10218,12 +10937,12 @@ async function deletePreview(options) {
|
|
|
10218
10937
|
// src/commands/journeys/index.ts
|
|
10219
10938
|
async function listJourneys(options) {
|
|
10220
10939
|
const id = options.projectId ?? requireProjectId();
|
|
10221
|
-
const
|
|
10222
|
-
|
|
10223
|
-
|
|
10224
|
-
|
|
10225
|
-
|
|
10226
|
-
|
|
10940
|
+
const response = await apiRequest(
|
|
10941
|
+
"GET /api/projects/{projectId}/flows/{flowId}/journeys",
|
|
10942
|
+
{
|
|
10943
|
+
path: { projectId: id, flowId: options.flowId },
|
|
10944
|
+
query: { traceId: options.traceId || void 0, limit: options.limit }
|
|
10945
|
+
}
|
|
10227
10946
|
);
|
|
10228
10947
|
if (!response.ok) {
|
|
10229
10948
|
const body = await response.json().catch(() => ({}));
|
|
@@ -10243,13 +10962,9 @@ async function startObserveSession(options) {
|
|
|
10243
10962
|
// omitted rather than sent as a bare [] the app would have to interpret.
|
|
10244
10963
|
...options.origins?.length ? { origins: options.origins } : {}
|
|
10245
10964
|
};
|
|
10246
|
-
const response = await
|
|
10247
|
-
|
|
10248
|
-
{
|
|
10249
|
-
method: "POST",
|
|
10250
|
-
headers: { "Content-Type": "application/json" },
|
|
10251
|
-
body: JSON.stringify(body)
|
|
10252
|
-
}
|
|
10965
|
+
const response = await apiRequest(
|
|
10966
|
+
"POST /api/projects/{projectId}/flows/{flowId}/observe-sessions",
|
|
10967
|
+
{ path: { projectId: pid, flowId: options.flowId }, body }
|
|
10253
10968
|
);
|
|
10254
10969
|
if (!response.ok) {
|
|
10255
10970
|
const errorBody = await response.json().catch(() => ({}));
|
|
@@ -10263,8 +10978,15 @@ async function startObserveSession(options) {
|
|
|
10263
10978
|
}
|
|
10264
10979
|
async function getObserveSession(options) {
|
|
10265
10980
|
const pid = options.projectId ?? requireProjectId();
|
|
10266
|
-
const response = await
|
|
10267
|
-
|
|
10981
|
+
const response = await apiRequest(
|
|
10982
|
+
"GET /api/projects/{projectId}/flows/{flowId}/observe-sessions/{sessionId}",
|
|
10983
|
+
{
|
|
10984
|
+
path: {
|
|
10985
|
+
projectId: pid,
|
|
10986
|
+
flowId: options.flowId,
|
|
10987
|
+
sessionId: options.sessionId
|
|
10988
|
+
}
|
|
10989
|
+
}
|
|
10268
10990
|
);
|
|
10269
10991
|
if (!response.ok) {
|
|
10270
10992
|
const errorBody = await response.json().catch(() => ({}));
|
|
@@ -10274,9 +10996,15 @@ async function getObserveSession(options) {
|
|
|
10274
10996
|
}
|
|
10275
10997
|
async function endObserveSession(options) {
|
|
10276
10998
|
const pid = options.projectId ?? requireProjectId();
|
|
10277
|
-
const response = await
|
|
10278
|
-
|
|
10279
|
-
{
|
|
10999
|
+
const response = await apiRequest(
|
|
11000
|
+
"DELETE /api/projects/{projectId}/flows/{flowId}/observe-sessions/{sessionId}",
|
|
11001
|
+
{
|
|
11002
|
+
path: {
|
|
11003
|
+
projectId: pid,
|
|
11004
|
+
flowId: options.flowId,
|
|
11005
|
+
sessionId: options.sessionId
|
|
11006
|
+
}
|
|
11007
|
+
}
|
|
10280
11008
|
);
|
|
10281
11009
|
if (!response.ok) {
|
|
10282
11010
|
const errorBody = await response.json().catch(() => ({}));
|
|
@@ -10294,103 +11022,110 @@ async function readJson3(response, fallback) {
|
|
|
10294
11022
|
}
|
|
10295
11023
|
async function listReleases(options) {
|
|
10296
11024
|
const pid = options.projectId ?? requireProjectId();
|
|
10297
|
-
const
|
|
10298
|
-
|
|
10299
|
-
|
|
10300
|
-
|
|
10301
|
-
|
|
10302
|
-
|
|
11025
|
+
const response = await apiRequest(
|
|
11026
|
+
"GET /api/projects/{projectId}/flows/{flowId}/releases",
|
|
11027
|
+
{
|
|
11028
|
+
path: { projectId: pid, flowId: options.flowId },
|
|
11029
|
+
query: {
|
|
11030
|
+
rationale: "true",
|
|
11031
|
+
limit: options.limit,
|
|
11032
|
+
offset: options.offset
|
|
11033
|
+
}
|
|
11034
|
+
}
|
|
10303
11035
|
);
|
|
10304
11036
|
return readJson3(response, "Failed to list releases");
|
|
10305
11037
|
}
|
|
10306
11038
|
async function getRelease(options) {
|
|
10307
11039
|
const pid = options.projectId ?? requireProjectId();
|
|
10308
11040
|
const segment = "versionId" in options.ref ? options.ref.versionId : String(options.ref.versionNumber);
|
|
10309
|
-
const response = await
|
|
10310
|
-
|
|
11041
|
+
const response = await apiRequest(
|
|
11042
|
+
"GET /api/projects/{projectId}/flows/{flowId}/releases/{versionId}",
|
|
11043
|
+
{ path: { projectId: pid, flowId: options.flowId, versionId: segment } }
|
|
10311
11044
|
);
|
|
10312
11045
|
return readJson3(response, "Failed to read release");
|
|
10313
11046
|
}
|
|
10314
11047
|
async function listStepHistory(options) {
|
|
10315
11048
|
const pid = options.projectId ?? requireProjectId();
|
|
10316
|
-
const
|
|
10317
|
-
|
|
10318
|
-
|
|
10319
|
-
|
|
10320
|
-
|
|
11049
|
+
const response = await apiRequest(
|
|
11050
|
+
"GET /api/projects/{projectId}/flows/{flowId}/releases/step-history",
|
|
11051
|
+
{
|
|
11052
|
+
path: { projectId: pid, flowId: options.flowId },
|
|
11053
|
+
query: { step: options.step, flow: options.flow, limit: options.limit }
|
|
11054
|
+
}
|
|
10321
11055
|
);
|
|
10322
11056
|
return readJson3(response, "Failed to read step history");
|
|
10323
11057
|
}
|
|
10324
11058
|
async function setReleaseRationale(options) {
|
|
10325
11059
|
const pid = options.projectId ?? requireProjectId();
|
|
10326
|
-
const response = await
|
|
10327
|
-
|
|
11060
|
+
const response = await apiRequest(
|
|
11061
|
+
"PUT /api/projects/{projectId}/flows/{flowId}/releases/annotations",
|
|
10328
11062
|
{
|
|
10329
|
-
|
|
10330
|
-
|
|
10331
|
-
body: JSON.stringify({
|
|
10332
|
-
versionId: options.versionId,
|
|
10333
|
-
humanText: options.text
|
|
10334
|
-
})
|
|
11063
|
+
path: { projectId: pid, flowId: options.flowId },
|
|
11064
|
+
body: { versionId: options.versionId, humanText: options.text }
|
|
10335
11065
|
}
|
|
10336
11066
|
);
|
|
10337
11067
|
return readJson3(response, "Failed to write release rationale");
|
|
10338
11068
|
}
|
|
10339
11069
|
async function listThreads(options) {
|
|
10340
11070
|
const pid = options.projectId ?? requireProjectId();
|
|
10341
|
-
const
|
|
10342
|
-
|
|
10343
|
-
|
|
10344
|
-
|
|
10345
|
-
|
|
10346
|
-
|
|
10347
|
-
|
|
10348
|
-
|
|
10349
|
-
|
|
10350
|
-
|
|
11071
|
+
const response = await apiRequest(
|
|
11072
|
+
"GET /api/projects/{projectId}/flows/{flowId}/threads",
|
|
11073
|
+
{
|
|
11074
|
+
path: { projectId: pid, flowId: options.flowId },
|
|
11075
|
+
query: {
|
|
11076
|
+
anchorType: options.anchorType,
|
|
11077
|
+
anchorKey: options.anchorKey,
|
|
11078
|
+
status: options.status,
|
|
11079
|
+
includeMessages: options.includeMessages ? "true" : "false",
|
|
11080
|
+
limit: options.limit
|
|
11081
|
+
}
|
|
11082
|
+
}
|
|
10351
11083
|
);
|
|
10352
11084
|
return readJson3(response, "Failed to list threads");
|
|
10353
11085
|
}
|
|
10354
11086
|
async function createThread(options) {
|
|
10355
11087
|
const pid = options.projectId ?? requireProjectId();
|
|
10356
|
-
const response = await
|
|
10357
|
-
|
|
11088
|
+
const response = await apiRequest(
|
|
11089
|
+
"POST /api/projects/{projectId}/flows/{flowId}/threads",
|
|
10358
11090
|
{
|
|
10359
|
-
|
|
10360
|
-
|
|
10361
|
-
body: JSON.stringify({
|
|
11091
|
+
path: { projectId: pid, flowId: options.flowId },
|
|
11092
|
+
body: {
|
|
10362
11093
|
anchorType: options.anchorType,
|
|
10363
11094
|
anchorKey: options.anchorKey,
|
|
10364
11095
|
...options.anchorLabel !== void 0 ? { anchorLabel: options.anchorLabel } : {},
|
|
10365
11096
|
text: options.text
|
|
10366
|
-
}
|
|
11097
|
+
}
|
|
10367
11098
|
}
|
|
10368
11099
|
);
|
|
10369
11100
|
return readJson3(response, "Failed to open thread");
|
|
10370
11101
|
}
|
|
10371
11102
|
async function addThreadMessage(options) {
|
|
10372
11103
|
const pid = options.projectId ?? requireProjectId();
|
|
10373
|
-
const response = await
|
|
10374
|
-
|
|
11104
|
+
const response = await apiRequest(
|
|
11105
|
+
"POST /api/projects/{projectId}/flows/{flowId}/threads/{threadId}/messages",
|
|
10375
11106
|
{
|
|
10376
|
-
|
|
10377
|
-
|
|
10378
|
-
|
|
11107
|
+
path: {
|
|
11108
|
+
projectId: pid,
|
|
11109
|
+
flowId: options.flowId,
|
|
11110
|
+
threadId: options.threadId
|
|
11111
|
+
},
|
|
11112
|
+
body: { text: options.text }
|
|
10379
11113
|
}
|
|
10380
11114
|
);
|
|
10381
11115
|
return readJson3(response, "Failed to add message");
|
|
10382
11116
|
}
|
|
10383
11117
|
async function listKnowledge(options) {
|
|
10384
11118
|
const pid = options.projectId ?? requireProjectId();
|
|
10385
|
-
const
|
|
10386
|
-
|
|
10387
|
-
|
|
10388
|
-
|
|
10389
|
-
|
|
10390
|
-
|
|
10391
|
-
|
|
10392
|
-
|
|
10393
|
-
|
|
11119
|
+
const response = await apiRequest("GET /api/projects/{projectId}/knowledge", {
|
|
11120
|
+
path: { projectId: pid },
|
|
11121
|
+
query: {
|
|
11122
|
+
pageKey: options.pageKey,
|
|
11123
|
+
frameId: options.frameId,
|
|
11124
|
+
markId: options.markId,
|
|
11125
|
+
includeMessages: options.includeMessages ? "true" : "false",
|
|
11126
|
+
limit: options.limit
|
|
11127
|
+
}
|
|
11128
|
+
});
|
|
10394
11129
|
return readJson3(response, "Failed to read knowledge");
|
|
10395
11130
|
}
|
|
10396
11131
|
|
|
@@ -10404,21 +11139,24 @@ async function readJson4(response, fallback) {
|
|
|
10404
11139
|
}
|
|
10405
11140
|
async function listFrames(options = {}) {
|
|
10406
11141
|
const pid = options.projectId ?? requireProjectId();
|
|
10407
|
-
const response = await
|
|
11142
|
+
const response = await apiRequest("GET /api/projects/{projectId}/frames", {
|
|
11143
|
+
path: { projectId: pid }
|
|
11144
|
+
});
|
|
10408
11145
|
return readJson4(response, "Failed to list frames");
|
|
10409
11146
|
}
|
|
10410
11147
|
async function listPageFrames(options) {
|
|
10411
11148
|
const pid = options.projectId ?? requireProjectId();
|
|
10412
|
-
const
|
|
10413
|
-
|
|
10414
|
-
|
|
10415
|
-
);
|
|
11149
|
+
const response = await apiRequest("GET /api/projects/{projectId}/frames", {
|
|
11150
|
+
path: { projectId: pid },
|
|
11151
|
+
query: { pageKey: options.pageKey }
|
|
11152
|
+
});
|
|
10416
11153
|
return readJson4(response, "Failed to list page frames");
|
|
10417
11154
|
}
|
|
10418
11155
|
async function getFrame(options) {
|
|
10419
11156
|
const pid = options.projectId ?? requireProjectId();
|
|
10420
|
-
const response = await
|
|
10421
|
-
|
|
11157
|
+
const response = await apiRequest(
|
|
11158
|
+
"GET /api/projects/{projectId}/frames/{frameId}",
|
|
11159
|
+
{ path: { projectId: pid, frameId: options.frameId } }
|
|
10422
11160
|
);
|
|
10423
11161
|
return readJson4(response, "Failed to read frame");
|
|
10424
11162
|
}
|
|
@@ -10426,8 +11164,9 @@ async function getFrame(options) {
|
|
|
10426
11164
|
// src/commands/secrets/index.ts
|
|
10427
11165
|
async function listSecrets(options) {
|
|
10428
11166
|
const pid = options.projectId ?? requireProjectId();
|
|
10429
|
-
const response = await
|
|
10430
|
-
|
|
11167
|
+
const response = await apiRequest(
|
|
11168
|
+
"GET /api/projects/{projectId}/flows/{flowId}/secrets",
|
|
11169
|
+
{ path: { projectId: pid, flowId: options.flowId } }
|
|
10431
11170
|
);
|
|
10432
11171
|
if (!response.ok) {
|
|
10433
11172
|
const body = await response.json().catch(() => ({}));
|
|
@@ -10437,12 +11176,11 @@ async function listSecrets(options) {
|
|
|
10437
11176
|
}
|
|
10438
11177
|
async function createSecret(options) {
|
|
10439
11178
|
const pid = options.projectId ?? requireProjectId();
|
|
10440
|
-
const response = await
|
|
10441
|
-
|
|
11179
|
+
const response = await apiRequest(
|
|
11180
|
+
"POST /api/projects/{projectId}/flows/{flowId}/secrets",
|
|
10442
11181
|
{
|
|
10443
|
-
|
|
10444
|
-
|
|
10445
|
-
body: JSON.stringify({ name: options.name, value: options.value })
|
|
11182
|
+
path: { projectId: pid, flowId: options.flowId },
|
|
11183
|
+
body: { name: options.name, value: options.value }
|
|
10446
11184
|
}
|
|
10447
11185
|
);
|
|
10448
11186
|
if (!response.ok) {
|
|
@@ -10453,12 +11191,15 @@ async function createSecret(options) {
|
|
|
10453
11191
|
}
|
|
10454
11192
|
async function updateSecret(options) {
|
|
10455
11193
|
const pid = options.projectId ?? requireProjectId();
|
|
10456
|
-
const response = await
|
|
10457
|
-
|
|
11194
|
+
const response = await apiRequest(
|
|
11195
|
+
"PUT /api/projects/{projectId}/flows/{flowId}/secrets/{secretId}",
|
|
10458
11196
|
{
|
|
10459
|
-
|
|
10460
|
-
|
|
10461
|
-
|
|
11197
|
+
path: {
|
|
11198
|
+
projectId: pid,
|
|
11199
|
+
flowId: options.flowId,
|
|
11200
|
+
secretId: options.secretId
|
|
11201
|
+
},
|
|
11202
|
+
body: { value: options.value }
|
|
10462
11203
|
}
|
|
10463
11204
|
);
|
|
10464
11205
|
if (!response.ok) {
|
|
@@ -10469,9 +11210,15 @@ async function updateSecret(options) {
|
|
|
10469
11210
|
}
|
|
10470
11211
|
async function deleteSecret(options) {
|
|
10471
11212
|
const pid = options.projectId ?? requireProjectId();
|
|
10472
|
-
const response = await
|
|
10473
|
-
|
|
10474
|
-
{
|
|
11213
|
+
const response = await apiRequest(
|
|
11214
|
+
"DELETE /api/projects/{projectId}/flows/{flowId}/secrets/{secretId}",
|
|
11215
|
+
{
|
|
11216
|
+
path: {
|
|
11217
|
+
projectId: pid,
|
|
11218
|
+
flowId: options.flowId,
|
|
11219
|
+
secretId: options.secretId
|
|
11220
|
+
}
|
|
11221
|
+
}
|
|
10475
11222
|
);
|
|
10476
11223
|
if (!response.ok) {
|
|
10477
11224
|
const body = await response.json().catch(() => ({}));
|
|
@@ -10658,7 +11405,9 @@ async function createEmitter(opts) {
|
|
|
10658
11405
|
function resolveTelemetryEndpoint() {
|
|
10659
11406
|
const appUrl = resolveAppUrl();
|
|
10660
11407
|
if (!appUrl) return void 0;
|
|
10661
|
-
return
|
|
11408
|
+
return operationUrl("POST /api/telemetry", {
|
|
11409
|
+
baseUrl: appUrl.replace(/\/$/, "")
|
|
11410
|
+
});
|
|
10662
11411
|
}
|
|
10663
11412
|
async function withTimeout(p, ms) {
|
|
10664
11413
|
return Promise.race([
|
|
@@ -10689,12 +11438,15 @@ export {
|
|
|
10689
11438
|
BuildResultSchema,
|
|
10690
11439
|
BuildWrapArtifactSchema,
|
|
10691
11440
|
BuildWrapOptionsSchema,
|
|
11441
|
+
DEPLOYMENT_STATUSES,
|
|
11442
|
+
DEPLOYMENT_TYPES,
|
|
10692
11443
|
DeploymentAmbiguityError,
|
|
10693
11444
|
VALIDATE_CODES,
|
|
10694
11445
|
VERSION,
|
|
10695
11446
|
addThreadMessage,
|
|
10696
|
-
annotateErrorWithDrift,
|
|
10697
11447
|
apiFetch,
|
|
11448
|
+
apiRequest,
|
|
11449
|
+
bakedClientOperations,
|
|
10698
11450
|
bakedContractHash,
|
|
10699
11451
|
bakedContractVersion,
|
|
10700
11452
|
buildDataPayload,
|
|
@@ -10739,6 +11491,8 @@ export {
|
|
|
10739
11491
|
feedback,
|
|
10740
11492
|
feedbackCommand,
|
|
10741
11493
|
fetchHealth,
|
|
11494
|
+
fetchOpenApi,
|
|
11495
|
+
formatContract,
|
|
10742
11496
|
formatPushResult,
|
|
10743
11497
|
getAuthHeaders,
|
|
10744
11498
|
getClientContext,
|
|
@@ -10756,6 +11510,7 @@ export {
|
|
|
10756
11510
|
getProject,
|
|
10757
11511
|
getProjectCommand,
|
|
10758
11512
|
getRelease,
|
|
11513
|
+
isDeploymentStatus,
|
|
10759
11514
|
listAllFlows,
|
|
10760
11515
|
listDeployments,
|
|
10761
11516
|
listDeploymentsCommand,
|
|
@@ -10779,6 +11534,7 @@ export {
|
|
|
10779
11534
|
logout,
|
|
10780
11535
|
logoutCommand,
|
|
10781
11536
|
mergeAuthHeaders,
|
|
11537
|
+
operationUrl,
|
|
10782
11538
|
parseSSEEvents,
|
|
10783
11539
|
publicFetch,
|
|
10784
11540
|
push,
|