@oomol-lab/open-flow 0.1.0-beta.74 → 0.1.0-beta.76
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/README.md +3 -1
- package/dist/browser/{ContentIcon-CUQHjQIw.js → ContentIcon-Cm1hbVzW.js} +4 -3
- package/dist/browser/{FlowCanvas-Dtf8_cQp.js → FlowCanvas-NzKtla_c.js} +62 -62
- package/dist/browser/{createResourceDialog-DI9pL-Yr.js → createResourceDialog-BgdedQqu.js} +3 -3
- package/dist/browser/{dialog-BYJGvItc.js → dialog-aSElFFw2.js} +322 -26
- package/dist/browser/{exportSvg-BOoy7-Db.js → exportSvg-Dcz4HTo_.js} +2 -2
- package/dist/browser/{flowChanges-RL-H4CjD.js → flowChanges-NZyS7HSp.js} +490 -438
- package/dist/browser/{flowWorkspace-BkDsETj0.js → flowWorkspace-Bl0SDehy.js} +499 -61
- package/dist/browser/preview.css +696 -825
- package/dist/browser/preview.js +1399 -717
- package/dist/browser/theme.css +114 -262
- package/dist/browser/{tooltip-wZJRB9oP.js → tooltip-3XMK9jkr.js} +1 -1
- package/dist/browser/{typeScriptSession-CSRwWmZm.js → typeScriptSession-C9sBGOKZ.js} +1 -1
- package/dist/browser/ui.css +354 -460
- package/dist/browser/ui.js +1 -1
- package/dist/browser/workbench.css +696 -825
- package/dist/browser/workbench.js +13 -7
- package/dist/browser/{workbenchSelect-BcWPWGzw.js → workbenchSelect-DBGP7Y4Z.js} +2 -2
- package/dist/command/index.js +41 -43
- package/dist/common/authoring.d.ts +5 -5
- package/dist/common/authoringExamples.d.ts +3 -2
- package/dist/common/authoringSchema.d.ts +70 -4
- package/dist/common/connector-proxy.d.ts +1 -1
- package/dist/common/control-api-conformance.js +250 -138
- package/dist/common/control-api.d.ts +3 -2
- package/dist/common/control-api.js +246 -134
- package/dist/common/control-requests.d.ts +3 -3
- package/dist/common/control-requests.js +353 -79
- package/dist/common/cron-trigger.d.ts +2 -1
- package/dist/common/decision.d.ts +4 -4
- package/dist/common/decision.js +5 -2
- package/dist/common/engine-contract.d.ts +6 -1
- package/dist/common/event-source-definition.d.ts +1 -1
- package/dist/common/event-source-view.d.ts +22 -0
- package/dist/common/event-source.d.ts +1 -1
- package/dist/common/event-source.js +24 -65
- package/dist/common/event-sources.d.ts +0 -21
- package/dist/common/flow-authoring.js +90 -19
- package/dist/common/flow-change-schema.d.ts +9 -1
- package/dist/common/flow-change.d.ts +7 -201
- package/dist/common/flow-change.js +96 -23
- package/dist/common/flow-encoding.js +89 -21
- package/dist/common/flow-graph.d.ts +2 -1
- package/dist/common/flow-input-value.d.ts +1 -1
- package/dist/common/flow-model.d.ts +121 -0
- package/dist/common/flow-notifications.d.ts +1 -1
- package/dist/common/flow-retry.d.ts +3 -5
- package/dist/common/flow-semantics.js +816 -586
- package/dist/common/flow-workflowReferences.d.ts +8 -0
- package/dist/common/flowInspection.d.ts +1 -1
- package/dist/common/http-hosts.d.ts +6 -0
- package/dist/common/http-request.d.ts +164 -0
- package/dist/common/http-request.js +5272 -0
- package/dist/common/integration-trigger.d.ts +2 -1
- package/dist/common/mcp.d.ts +3 -3
- package/dist/common/mcp.js +248 -136
- package/dist/common/openapi.d.ts +4 -4
- package/dist/common/openapi.js +4 -1
- package/dist/common/poll-trigger.d.ts +2 -1
- package/dist/common/run-events.js +11 -9
- package/dist/common/runtime-contract.d.ts +23 -1
- package/dist/common/runtime-contract.js +607 -72
- package/dist/common/runtime-nodejs-compat.d.ts +44 -0
- package/dist/common/runtime-nodejs-compat.js +5870 -0
- package/dist/common/scheduler-checkpoint.d.ts +1 -1
- package/dist/common/scheduler-node-execution.d.ts +1 -1
- package/dist/common/scheduler.d.ts +2 -2
- package/dist/common/scheduler.js +95 -25
- package/dist/common/trigger-catalog.d.ts +1 -7
- package/dist/common/trigger-config-options.d.ts +1 -1
- package/dist/common/trigger-config.d.ts +1 -1
- package/dist/common/trigger-contract.d.ts +2 -1
- package/dist/common/trigger-localization.d.ts +8 -2
- package/dist/common/trigger-model.d.ts +101 -0
- package/dist/common/webhook-response.d.ts +1 -3
- package/dist/common/webhook-trigger.d.ts +3 -1
- package/dist/common/webhook-trigger.js +12 -11
- package/dist/common/workflow.d.ts +3 -12
- package/dist/common/workflow.js +25 -23
- package/dist/index.d.ts +41 -14
- package/package.json +9 -1
- package/skills/open-flow/references/flow-authoring.md +1 -0
- package/skills/open-flow/references/flow-n8n-conversion.md +19 -15
- package/src/base/common/json.ts +1 -1
- package/src/connector/common/proxy.ts +1 -1
- package/src/control/common/api.ts +7 -5
- package/src/control/common/authoring.ts +14 -3
- package/src/control/common/authoringExamples.ts +8 -0
- package/src/control/common/authoringSchema.ts +38 -25
- package/src/control/common/authoringTools.ts +1 -1
- package/src/control/common/conformance.ts +1 -1
- package/src/control/common/connectorDecoders.ts +1 -1
- package/src/control/common/eventSources.ts +2 -29
- package/src/control/common/triggerCatalog.ts +1 -8
- package/src/decision/common/decision.ts +15 -7
- package/src/event-source/common/definition.ts +1 -1
- package/src/event-source/common/index.ts +1 -1
- package/src/event-source/common/view.ts +20 -0
- package/src/execution/common/checkpoint.ts +1 -1
- package/src/execution/common/events.ts +3 -0
- package/src/execution/common/node-execution.ts +5 -3
- package/src/execution/common/scheduler.ts +2 -1
- package/src/flow/common/change.ts +59 -192
- package/src/flow/common/changeSchema.ts +39 -5
- package/src/flow/common/connectionUsage.ts +1 -1
- package/src/flow/common/graph.ts +10 -4
- package/src/flow/common/inputValue.ts +1 -1
- package/src/flow/common/model.ts +130 -0
- package/src/flow/common/modules.ts +1 -1
- package/src/flow/common/portChanges.ts +1 -1
- package/src/flow/common/retry.ts +3 -5
- package/src/flow/common/semantics.ts +71 -7
- package/src/flow/common/webhookResponse.ts +4 -8
- package/src/flow/common/workflowReferences.ts +31 -0
- package/src/http/common/authBindings.ts +9 -0
- package/src/http/common/headers.ts +5 -0
- package/src/http/common/hosts.ts +13 -0
- package/src/http/common/httpRequest.ts +266 -0
- package/src/openapi/common/openapi.ts +9 -5
- package/src/{execution → runtime}/common/engineContract.ts +24 -15
- package/src/runtime/common/nodejsCompat.ts +275 -0
- package/src/runtime/common/nodejsGuest.generated.json +47 -0
- package/src/runtime/common/runtime.ts +1138 -0
- package/src/trigger/common/config.ts +1 -1
- package/src/trigger/common/configOptions.ts +1 -1
- package/src/trigger/common/contract.ts +2 -1
- package/src/trigger/common/cron.ts +2 -1
- package/src/trigger/common/integration.ts +2 -1
- package/src/trigger/common/model.ts +87 -0
- package/src/trigger/common/poll.ts +2 -1
- package/src/trigger/common/webhook.ts +7 -4
- package/src/trigger/providers/fieldDescriptions.ts +1 -1
- package/src/trigger/providers/localization.ts +9 -2
- package/src/trigger/providers/remote.ts +1 -1
- package/src/types/index.ts +44 -15
- package/src/workflow/common/workflow.ts +3 -44
- package/src/execution/common/runtime.ts +0 -563
- package/src/openapi/common/authBindings.ts +0 -12
- /package/src/{control → connector}/common/providerIconSprite.ts +0 -0
|
@@ -3973,6 +3973,9 @@ function hasRetiredRef(value) {
|
|
|
3973
3973
|
}
|
|
3974
3974
|
//#endregion
|
|
3975
3975
|
//#region src/decision/common/decision.ts
|
|
3976
|
+
function isDecisionExecutor(executor) {
|
|
3977
|
+
return executor.kind === "decision";
|
|
3978
|
+
}
|
|
3976
3979
|
var decisionLimits = {
|
|
3977
3980
|
choice: 255,
|
|
3978
3981
|
score: 10
|
|
@@ -3995,7 +3998,7 @@ function limitDecisionQuestions(questions) {
|
|
|
3995
3998
|
}
|
|
3996
3999
|
/** Loading an oversized task also updates its previously generated output schemas. */
|
|
3997
4000
|
function limitDecisionTask(task) {
|
|
3998
|
-
if (task.executor
|
|
4001
|
+
if (!isDecisionExecutor(task.executor)) return task;
|
|
3999
4002
|
const original = task.executor.questions;
|
|
4000
4003
|
const questions = limitDecisionQuestions(original);
|
|
4001
4004
|
if (questions === original) return task;
|
|
@@ -4120,7 +4123,7 @@ function decisionTask(questions = [defaultDecisionQuestion()], name = "AI Decisi
|
|
|
4120
4123
|
}
|
|
4121
4124
|
function decisionTaskIssues(task) {
|
|
4122
4125
|
task = limitDecisionTask(task);
|
|
4123
|
-
if (task.executor
|
|
4126
|
+
if (!isDecisionExecutor(task.executor)) return [];
|
|
4124
4127
|
const expected = decisionTask(task.executor.questions, task.name);
|
|
4125
4128
|
return [...decisionQuestionIssues(task.executor.questions), ...!dequal(task.inputs, expected.inputs) || !dequal(task.outputs, expected.outputs) ? [{
|
|
4126
4129
|
field: "ports",
|
|
@@ -4128,422 +4131,67 @@ function decisionTaskIssues(task) {
|
|
|
4128
4131
|
}] : []];
|
|
4129
4132
|
}
|
|
4130
4133
|
//#endregion
|
|
4131
|
-
//#region
|
|
4132
|
-
|
|
4133
|
-
"
|
|
4134
|
-
|
|
4135
|
-
"post",
|
|
4136
|
-
"delete",
|
|
4137
|
-
"options",
|
|
4138
|
-
"head",
|
|
4139
|
-
"patch",
|
|
4140
|
-
"trace"
|
|
4141
|
-
];
|
|
4142
|
-
function object$1(value) {
|
|
4143
|
-
if (value == null || typeof value != "object" || Array.isArray(value)) throw new Error("Expected an OpenAPI object.");
|
|
4144
|
-
return value;
|
|
4145
|
-
}
|
|
4146
|
-
function httpUrl(value, base) {
|
|
4147
|
-
const url = new URL(value, base);
|
|
4148
|
-
if (!["http:", "https:"].includes(url.protocol) || url.username || url.password || url.hash) throw new Error("An HTTP(S) URL without credentials or fragment is required.");
|
|
4149
|
-
return url.href;
|
|
4134
|
+
//#region ../../node_modules/.bun/zod@4.6.5/node_modules/zod/v4/core/util.js
|
|
4135
|
+
function getEnumValues(entries) {
|
|
4136
|
+
const numericValues = Object.values(entries).filter((v) => typeof v === "number");
|
|
4137
|
+
return Object.entries(entries).filter(([k, _]) => numericValues.indexOf(+k) === -1).map(([_, v]) => v);
|
|
4150
4138
|
}
|
|
4151
|
-
function
|
|
4152
|
-
|
|
4153
|
-
if (typeof doc.openapi != "string" || !/^3\.[01]\.\d+$/.test(doc.openapi)) throw new Error("Only OpenAPI 3.0 and 3.1 JSON documents are supported.");
|
|
4154
|
-
object$1(doc.paths);
|
|
4155
|
-
return doc;
|
|
4139
|
+
function joinValues(array, separator = "|") {
|
|
4140
|
+
return array.map((val) => stringifyPrimitive(val)).join(separator);
|
|
4156
4141
|
}
|
|
4157
|
-
function
|
|
4158
|
-
if (
|
|
4159
|
-
let value = doc;
|
|
4160
|
-
for (const key of decodeURIComponent(ref.slice(2)).split("/").map((part) => part.replace(/~1/g, "/").replace(/~0/g, "~"))) {
|
|
4161
|
-
const source = object$1(value);
|
|
4162
|
-
if (!Object.hasOwn(source, key)) throw new Error("An OpenAPI reference is missing.");
|
|
4163
|
-
value = source[key];
|
|
4164
|
-
}
|
|
4142
|
+
function jsonStringifyReplacer(_, value) {
|
|
4143
|
+
if (typeof value === "bigint") return value.toString();
|
|
4165
4144
|
return value;
|
|
4166
4145
|
}
|
|
4167
|
-
|
|
4168
|
-
|
|
4169
|
-
|
|
4170
|
-
|
|
4171
|
-
if (seen.has(result.$ref)) throw new Error("Circular non-schema reference is unsupported.");
|
|
4172
|
-
seen.add(result.$ref);
|
|
4173
|
-
const { $ref, ...siblings } = result;
|
|
4174
|
-
result = {
|
|
4175
|
-
...object$1(pointer(doc, $ref)),
|
|
4176
|
-
...siblings
|
|
4177
|
-
};
|
|
4178
|
-
}
|
|
4179
|
-
return result;
|
|
4180
|
-
}
|
|
4181
|
-
function operation(doc, path, method) {
|
|
4182
|
-
const item = resolved(doc, object$1(doc.paths)[path]);
|
|
4183
|
-
if (!methods.includes(method) || item[method] == null) throw new Error("The selected operation is no longer available.");
|
|
4184
|
-
return {
|
|
4185
|
-
item,
|
|
4186
|
-
op: object$1(item[method])
|
|
4187
|
-
};
|
|
4188
|
-
}
|
|
4189
|
-
function servers(value, path, method) {
|
|
4190
|
-
const doc = parseOpenApi(value);
|
|
4191
|
-
const { item, op } = operation(doc, path, method);
|
|
4192
|
-
const entries = op.servers ?? item.servers ?? doc.servers;
|
|
4193
|
-
if (!Array.isArray(entries) || entries.length == 0) return [{ url: "/" }];
|
|
4194
|
-
return entries.map(object$1);
|
|
4195
|
-
}
|
|
4196
|
-
function snapshot(documentValue, path, method) {
|
|
4197
|
-
const doc = parseOpenApi(documentValue);
|
|
4198
|
-
const { item, op } = operation(doc, path, method);
|
|
4199
|
-
const security = op.security ?? doc.security ?? [];
|
|
4200
|
-
const result = {
|
|
4201
|
-
openapi: doc.openapi,
|
|
4202
|
-
paths: { [path]: {
|
|
4203
|
-
[method]: op,
|
|
4204
|
-
...item.parameters == null ? {} : { parameters: item.parameters }
|
|
4205
|
-
} },
|
|
4206
|
-
servers: servers(doc, path, method),
|
|
4207
|
-
security
|
|
4208
|
-
};
|
|
4209
|
-
const visited = /* @__PURE__ */ new Set();
|
|
4210
|
-
function copy(ref) {
|
|
4211
|
-
if (visited.has(ref)) return;
|
|
4212
|
-
visited.add(ref);
|
|
4213
|
-
const value = pointer(doc, ref);
|
|
4214
|
-
const keys = decodeURIComponent(ref.slice(2)).split("/").map((part) => part.replace(/~1/g, "/").replace(/~0/g, "~"));
|
|
4215
|
-
if (keys.some((key) => [
|
|
4216
|
-
"__proto__",
|
|
4217
|
-
"constructor",
|
|
4218
|
-
"prototype"
|
|
4219
|
-
].includes(key))) throw new Error("Unsupported reference key.");
|
|
4220
|
-
let target = result;
|
|
4221
|
-
for (const key of keys.slice(0, -1)) {
|
|
4222
|
-
if (!Object.hasOwn(target, key)) target[key] = {};
|
|
4223
|
-
target = object$1(target[key]);
|
|
4224
|
-
}
|
|
4225
|
-
target[keys.at(-1)] = structuredClone(value);
|
|
4226
|
-
visit(value);
|
|
4146
|
+
var Cached = class {
|
|
4147
|
+
constructor(getter) {
|
|
4148
|
+
this._getter = getter;
|
|
4149
|
+
this._value = void 0;
|
|
4227
4150
|
}
|
|
4228
|
-
|
|
4229
|
-
|
|
4230
|
-
if (
|
|
4231
|
-
|
|
4232
|
-
|
|
4151
|
+
get value() {
|
|
4152
|
+
const getter = this._getter;
|
|
4153
|
+
if (getter !== void 0) {
|
|
4154
|
+
this._value = getter();
|
|
4155
|
+
this._getter = void 0;
|
|
4233
4156
|
}
|
|
4234
|
-
|
|
4235
|
-
for (const [key, child] of Object.entries(value)) if (![
|
|
4236
|
-
"example",
|
|
4237
|
-
"examples",
|
|
4238
|
-
"default"
|
|
4239
|
-
].includes(key)) visit(child);
|
|
4157
|
+
return this._value;
|
|
4240
4158
|
}
|
|
4241
|
-
|
|
4242
|
-
|
|
4243
|
-
return
|
|
4159
|
+
};
|
|
4160
|
+
function cached(getter) {
|
|
4161
|
+
return new Cached(getter);
|
|
4244
4162
|
}
|
|
4245
|
-
function
|
|
4246
|
-
|
|
4247
|
-
const ids = /* @__PURE__ */ new Map();
|
|
4248
|
-
function convert(value) {
|
|
4249
|
-
if (typeof value == "boolean") return value;
|
|
4250
|
-
const source = object$1(value);
|
|
4251
|
-
if (source.format == "binary" || source.$dynamicRef != null || source.$id != null) throw new Error("Binary and dynamically scoped schemas are unsupported.");
|
|
4252
|
-
const result = {};
|
|
4253
|
-
for (const [key, child] of Object.entries(source)) {
|
|
4254
|
-
if ([
|
|
4255
|
-
"nullable",
|
|
4256
|
-
"example",
|
|
4257
|
-
"xml",
|
|
4258
|
-
"discriminator",
|
|
4259
|
-
"__proto__"
|
|
4260
|
-
].includes(key)) continue;
|
|
4261
|
-
if (key == "$ref") {
|
|
4262
|
-
if (typeof child != "string") throw new Error("Invalid schema reference.");
|
|
4263
|
-
let id = ids.get(child);
|
|
4264
|
-
if (id == null) {
|
|
4265
|
-
id = `s${ids.size}`;
|
|
4266
|
-
ids.set(child, id);
|
|
4267
|
-
defs[id] = convert(pointer(doc, child));
|
|
4268
|
-
}
|
|
4269
|
-
result.$ref = `#/$defs/${id}`;
|
|
4270
|
-
} else if ([
|
|
4271
|
-
"properties",
|
|
4272
|
-
"patternProperties",
|
|
4273
|
-
"$defs",
|
|
4274
|
-
"definitions",
|
|
4275
|
-
"dependentSchemas"
|
|
4276
|
-
].includes(key)) result[key] = Object.fromEntries(Object.entries(object$1(child)).map(([name, childSchema]) => [name, convert(childSchema)]));
|
|
4277
|
-
else if ([
|
|
4278
|
-
"allOf",
|
|
4279
|
-
"anyOf",
|
|
4280
|
-
"oneOf",
|
|
4281
|
-
"prefixItems"
|
|
4282
|
-
].includes(key)) {
|
|
4283
|
-
if (!Array.isArray(child)) throw new Error("Invalid schema composition.");
|
|
4284
|
-
result[key] = child.map(convert);
|
|
4285
|
-
} else if ([
|
|
4286
|
-
"items",
|
|
4287
|
-
"additionalProperties",
|
|
4288
|
-
"not",
|
|
4289
|
-
"if",
|
|
4290
|
-
"then",
|
|
4291
|
-
"else",
|
|
4292
|
-
"contains",
|
|
4293
|
-
"propertyNames",
|
|
4294
|
-
"unevaluatedProperties"
|
|
4295
|
-
].includes(key)) result[key] = convert(child);
|
|
4296
|
-
else result[key] = child;
|
|
4297
|
-
}
|
|
4298
|
-
if (source.nullable === true) return { anyOf: [result, { type: "null" }] };
|
|
4299
|
-
for (const key of ["minimum", "maximum"]) {
|
|
4300
|
-
const exclusive = key == "minimum" ? "exclusiveMinimum" : "exclusiveMaximum";
|
|
4301
|
-
if (typeof result[exclusive] == "boolean") {
|
|
4302
|
-
if (result[exclusive] && typeof result[key] == "number") {
|
|
4303
|
-
result[exclusive] = result[key];
|
|
4304
|
-
delete result[key];
|
|
4305
|
-
} else delete result[exclusive];
|
|
4306
|
-
}
|
|
4307
|
-
}
|
|
4308
|
-
return result;
|
|
4309
|
-
}
|
|
4310
|
-
let converted = convert(schemaValue);
|
|
4311
|
-
if (typeof converted == "object" && converted != null && typeof object$1(converted).$ref == "string") {
|
|
4312
|
-
const id = String(object$1(converted).$ref).slice(8);
|
|
4313
|
-
const { $ref: _ref, ...siblings } = object$1(converted);
|
|
4314
|
-
converted = {
|
|
4315
|
-
...object$1(defs[id]),
|
|
4316
|
-
...siblings
|
|
4317
|
-
};
|
|
4318
|
-
}
|
|
4319
|
-
if (typeof converted == "boolean") return converted;
|
|
4320
|
-
return {
|
|
4321
|
-
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
4322
|
-
...object$1(converted),
|
|
4323
|
-
...Object.keys(defs).length ? { $defs: defs } : {}
|
|
4324
|
-
};
|
|
4163
|
+
function nullish(input) {
|
|
4164
|
+
return input === null || input === void 0;
|
|
4325
4165
|
}
|
|
4326
|
-
function
|
|
4327
|
-
const
|
|
4328
|
-
const
|
|
4329
|
-
|
|
4330
|
-
for (const value of [...item.parameters ?? [], ...op.parameters ?? []]) {
|
|
4331
|
-
const p = resolved(doc, value);
|
|
4332
|
-
if (![
|
|
4333
|
-
"path",
|
|
4334
|
-
"query",
|
|
4335
|
-
"header"
|
|
4336
|
-
].includes(String(p.in)) || typeof p.name != "string" || p.content != null) throw new Error("Only schema-based path, query and header parameters are supported.");
|
|
4337
|
-
if (p.allowReserved === true) throw new Error("allowReserved parameters are unsupported.");
|
|
4338
|
-
if ((p.style ?? (p.in == "query" ? "form" : "simple")) != (p.in == "query" ? "form" : "simple")) throw new Error("Only form query and simple path/header serialization are supported.");
|
|
4339
|
-
entries.set(`${p.in}.${p.in == "header" ? p.name.toLowerCase() : p.name}`, p);
|
|
4340
|
-
}
|
|
4341
|
-
return [...entries.values()];
|
|
4166
|
+
function cleanRegex(source) {
|
|
4167
|
+
const start = source.startsWith("^") ? 1 : 0;
|
|
4168
|
+
const end = source.endsWith("$") ? source.length - 1 : source.length;
|
|
4169
|
+
return source.slice(start, end);
|
|
4342
4170
|
}
|
|
4343
|
-
function
|
|
4344
|
-
const
|
|
4345
|
-
const
|
|
4346
|
-
const
|
|
4347
|
-
|
|
4348
|
-
|
|
4349
|
-
return {
|
|
4350
|
-
schema: schema$1(doc, object$1(json).schema ?? {}),
|
|
4351
|
-
required: content.required === true,
|
|
4352
|
-
mediaType
|
|
4353
|
-
};
|
|
4171
|
+
function floatSafeRemainder(val, step) {
|
|
4172
|
+
const ratio = val / step;
|
|
4173
|
+
const roundedRatio = Math.round(ratio);
|
|
4174
|
+
const tolerance = 4 * Number.EPSILON * Math.max(Math.abs(ratio), 1);
|
|
4175
|
+
if (Math.abs(ratio - roundedRatio) < tolerance) return 0;
|
|
4176
|
+
return ratio - roundedRatio;
|
|
4354
4177
|
}
|
|
4355
|
-
|
|
4356
|
-
|
|
4357
|
-
|
|
4358
|
-
|
|
4359
|
-
|
|
4360
|
-
|
|
4361
|
-
|
|
4362
|
-
|
|
4363
|
-
|
|
4364
|
-
|
|
4365
|
-
|
|
4366
|
-
|
|
4367
|
-
|
|
4368
|
-
|
|
4369
|
-
|
|
4370
|
-
|
|
4371
|
-
|
|
4372
|
-
handle: `${p.in}.${p.name}`,
|
|
4373
|
-
jsonSchema,
|
|
4374
|
-
nullable: p.required !== true && p.in != "path" || matchesSchema(null, jsonSchema),
|
|
4375
|
-
...typeof p.description == "string" ? { description: p.description } : {},
|
|
4376
|
-
...defaultValue === void 0 ? {} : { value: defaultValue }
|
|
4377
|
-
};
|
|
4378
|
-
});
|
|
4379
|
-
if (op.requestBody != null) {
|
|
4380
|
-
if (config.method == "get" || config.method == "head") throw new Error("GET and HEAD request bodies are unsupported.");
|
|
4381
|
-
const body = jsonContent(doc, op.requestBody);
|
|
4382
|
-
inputs.push({
|
|
4383
|
-
handle: "body",
|
|
4384
|
-
jsonSchema: body.schema,
|
|
4385
|
-
nullable: !body.required || matchesSchema(null, body.schema)
|
|
4386
|
-
});
|
|
4387
|
-
}
|
|
4388
|
-
const occupied = new Set(params.map((p) => `${p.in}.${p.in == "header" ? String(p.name).toLowerCase() : p.name}`));
|
|
4389
|
-
for (const auth of config.auth) {
|
|
4390
|
-
const location = auth.type == "apiKey" ? `${auth.in}.${auth.in == "header" ? auth.name?.toLowerCase() : auth.name}` : "header.authorization";
|
|
4391
|
-
if (occupied.has(location)) throw new Error("Authentication conflicts with a parameter or another security scheme.");
|
|
4392
|
-
if (auth.type == "apiKey" && (!auth.name || !["header", "query"].includes(auth.in ?? ""))) throw new Error("API Key requires a name and location.");
|
|
4393
|
-
occupied.add(location);
|
|
4394
|
-
}
|
|
4395
|
-
inputs.push(...authHandles(config.auth).map((handle) => ({
|
|
4396
|
-
handle,
|
|
4397
|
-
jsonSchema: { type: "string" },
|
|
4398
|
-
nullable: false
|
|
4399
|
-
})));
|
|
4400
|
-
const responses = object$1(op.responses);
|
|
4401
|
-
const schemas = [];
|
|
4402
|
-
for (const [status, response] of Object.entries(responses)) if (/^2\d\d$|^2XX$/.test(status) || status == "default") {
|
|
4403
|
-
const r = resolved(doc, response);
|
|
4404
|
-
if (r.content == null) schemas.push({ type: "null" });
|
|
4405
|
-
else {
|
|
4406
|
-
jsonContent(doc, r);
|
|
4407
|
-
for (const [mediaType, media] of Object.entries(object$1(r.content))) if (/^application\/(json|.+\+json)$/.test(mediaType)) schemas.push(schema$1(doc, object$1(media).schema ?? {}));
|
|
4408
|
-
}
|
|
4409
|
-
}
|
|
4410
|
-
if (!schemas.length) throw new Error("A successful JSON response definition is required.");
|
|
4411
|
-
return {
|
|
4412
|
-
name,
|
|
4413
|
-
executor: config,
|
|
4414
|
-
inputs,
|
|
4415
|
-
outputs: [
|
|
4416
|
-
{
|
|
4417
|
-
handle: "body",
|
|
4418
|
-
jsonSchema: schemas.length == 1 ? schemas[0] : {
|
|
4419
|
-
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
4420
|
-
anyOf: schemas.map((s, index) => inlineSchema(s, index))
|
|
4421
|
-
},
|
|
4422
|
-
nullable: config.method == "head" || schemas.some((item) => matchesSchema(null, item))
|
|
4423
|
-
},
|
|
4424
|
-
{
|
|
4425
|
-
handle: "statusCode",
|
|
4426
|
-
jsonSchema: { type: "integer" },
|
|
4427
|
-
nullable: false
|
|
4428
|
-
},
|
|
4429
|
-
{
|
|
4430
|
-
handle: "headers",
|
|
4431
|
-
jsonSchema: {
|
|
4432
|
-
type: "object",
|
|
4433
|
-
additionalProperties: { type: "string" }
|
|
4434
|
-
},
|
|
4435
|
-
nullable: false
|
|
4436
|
-
}
|
|
4437
|
-
]
|
|
4438
|
-
};
|
|
4439
|
-
}
|
|
4440
|
-
function inlineSchema(value, index) {
|
|
4441
|
-
if (Array.isArray(value)) return value.map((item) => inlineSchema(item, index));
|
|
4442
|
-
if (value == null || typeof value != "object") return value;
|
|
4443
|
-
return Object.fromEntries(Object.entries(value).map(([key, child]) => [key, key == "$ref" && typeof child == "string" && child.startsWith("#/") ? `#/anyOf/${index}/${child.slice(2)}` : inlineSchema(child, index)]));
|
|
4444
|
-
}
|
|
4445
|
-
/** The canvas validator and property panel share the same configuration contract. */
|
|
4446
|
-
function openApiFieldIssues(task) {
|
|
4447
|
-
if (task.executor.kind != "openapi") return [];
|
|
4448
|
-
const config = task.executor;
|
|
4449
|
-
let field = "sourceUrl";
|
|
4450
|
-
try {
|
|
4451
|
-
if (!config.sourceUrl.trim()) return [{
|
|
4452
|
-
field,
|
|
4453
|
-
message: "Enter an OpenAPI JSON document URL."
|
|
4454
|
-
}];
|
|
4455
|
-
httpUrl(config.sourceUrl);
|
|
4456
|
-
field = "operation";
|
|
4457
|
-
if (!config.path) return [{
|
|
4458
|
-
field,
|
|
4459
|
-
message: "Select an OpenAPI operation."
|
|
4460
|
-
}];
|
|
4461
|
-
field = "serverUrl";
|
|
4462
|
-
httpUrl(config.serverUrl);
|
|
4463
|
-
if (new URL(config.serverUrl).search) throw new Error("Server URLs must not contain a query string.");
|
|
4464
|
-
field = "operation";
|
|
4465
|
-
if (!dequal(config.document, snapshot(config.document, config.path, config.method))) return [{
|
|
4466
|
-
field,
|
|
4467
|
-
message: "Save only the selected operation and its dependencies."
|
|
4468
|
-
}];
|
|
4469
|
-
const expected = openApiTask(config, task.name);
|
|
4470
|
-
if (!dequal(expected.inputs, task.inputs) || !dequal(expected.outputs, task.outputs)) return [{
|
|
4471
|
-
field,
|
|
4472
|
-
message: "OpenAPI ports must match the saved operation."
|
|
4473
|
-
}];
|
|
4474
|
-
return [];
|
|
4475
|
-
} catch (error) {
|
|
4476
|
-
return [{
|
|
4477
|
-
field,
|
|
4478
|
-
message: error.message
|
|
4479
|
-
}];
|
|
4480
|
-
}
|
|
4481
|
-
}
|
|
4482
|
-
function openApiIssues(task) {
|
|
4483
|
-
return openApiFieldIssues(task).map((issue) => issue.message);
|
|
4484
|
-
}
|
|
4485
|
-
//#endregion
|
|
4486
|
-
//#region ../../node_modules/.bun/zod@4.6.5/node_modules/zod/v4/core/util.js
|
|
4487
|
-
function getEnumValues(entries) {
|
|
4488
|
-
const numericValues = Object.values(entries).filter((v) => typeof v === "number");
|
|
4489
|
-
return Object.entries(entries).filter(([k, _]) => numericValues.indexOf(+k) === -1).map(([_, v]) => v);
|
|
4490
|
-
}
|
|
4491
|
-
function joinValues(array, separator = "|") {
|
|
4492
|
-
return array.map((val) => stringifyPrimitive(val)).join(separator);
|
|
4493
|
-
}
|
|
4494
|
-
function jsonStringifyReplacer(_, value) {
|
|
4495
|
-
if (typeof value === "bigint") return value.toString();
|
|
4496
|
-
return value;
|
|
4497
|
-
}
|
|
4498
|
-
var Cached = class {
|
|
4499
|
-
constructor(getter) {
|
|
4500
|
-
this._getter = getter;
|
|
4501
|
-
this._value = void 0;
|
|
4502
|
-
}
|
|
4503
|
-
get value() {
|
|
4504
|
-
const getter = this._getter;
|
|
4505
|
-
if (getter !== void 0) {
|
|
4506
|
-
this._value = getter();
|
|
4507
|
-
this._getter = void 0;
|
|
4508
|
-
}
|
|
4509
|
-
return this._value;
|
|
4510
|
-
}
|
|
4511
|
-
};
|
|
4512
|
-
function cached(getter) {
|
|
4513
|
-
return new Cached(getter);
|
|
4514
|
-
}
|
|
4515
|
-
function nullish(input) {
|
|
4516
|
-
return input === null || input === void 0;
|
|
4517
|
-
}
|
|
4518
|
-
function cleanRegex(source) {
|
|
4519
|
-
const start = source.startsWith("^") ? 1 : 0;
|
|
4520
|
-
const end = source.endsWith("$") ? source.length - 1 : source.length;
|
|
4521
|
-
return source.slice(start, end);
|
|
4522
|
-
}
|
|
4523
|
-
function floatSafeRemainder(val, step) {
|
|
4524
|
-
const ratio = val / step;
|
|
4525
|
-
const roundedRatio = Math.round(ratio);
|
|
4526
|
-
const tolerance = 4 * Number.EPSILON * Math.max(Math.abs(ratio), 1);
|
|
4527
|
-
if (Math.abs(ratio - roundedRatio) < tolerance) return 0;
|
|
4528
|
-
return ratio - roundedRatio;
|
|
4529
|
-
}
|
|
4530
|
-
var EVALUATING = /* @__PURE__*/ Symbol("evaluating");
|
|
4531
|
-
function defineLazy(object, key, getter) {
|
|
4532
|
-
let value = void 0;
|
|
4533
|
-
Object.defineProperty(object, key, {
|
|
4534
|
-
get() {
|
|
4535
|
-
if (value === EVALUATING) return;
|
|
4536
|
-
if (value === void 0) {
|
|
4537
|
-
value = EVALUATING;
|
|
4538
|
-
value = getter();
|
|
4539
|
-
}
|
|
4540
|
-
return value;
|
|
4541
|
-
},
|
|
4542
|
-
set(v) {
|
|
4543
|
-
Object.defineProperty(object, key, { value: v });
|
|
4544
|
-
},
|
|
4545
|
-
configurable: true
|
|
4546
|
-
});
|
|
4178
|
+
var EVALUATING = /* @__PURE__*/ Symbol("evaluating");
|
|
4179
|
+
function defineLazy(object, key, getter) {
|
|
4180
|
+
let value = void 0;
|
|
4181
|
+
Object.defineProperty(object, key, {
|
|
4182
|
+
get() {
|
|
4183
|
+
if (value === EVALUATING) return;
|
|
4184
|
+
if (value === void 0) {
|
|
4185
|
+
value = EVALUATING;
|
|
4186
|
+
value = getter();
|
|
4187
|
+
}
|
|
4188
|
+
return value;
|
|
4189
|
+
},
|
|
4190
|
+
set(v) {
|
|
4191
|
+
Object.defineProperty(object, key, { value: v });
|
|
4192
|
+
},
|
|
4193
|
+
configurable: true
|
|
4194
|
+
});
|
|
4547
4195
|
}
|
|
4548
4196
|
function assignProp(target, prop, value) {
|
|
4549
4197
|
Object.defineProperty(target, prop, {
|
|
@@ -9823,7 +9471,7 @@ var ZodObject = /*@__PURE__*/ $constructor("ZodObject", (inst, def) => {
|
|
|
9823
9471
|
return required(ZodNonOptional, this, args[0]);
|
|
9824
9472
|
}
|
|
9825
9473
|
});
|
|
9826
|
-
function object(shape, params) {
|
|
9474
|
+
function object$1(shape, params) {
|
|
9827
9475
|
return new ZodObject({
|
|
9828
9476
|
type: "object",
|
|
9829
9477
|
shape: shape ?? {},
|
|
@@ -10120,101 +9768,599 @@ function lazy(getter) {
|
|
|
10120
9768
|
getter
|
|
10121
9769
|
});
|
|
10122
9770
|
}
|
|
10123
|
-
var ZodCustom = /*@__PURE__*/ $constructor("ZodCustom", (inst, def) => {
|
|
10124
|
-
$ZodCustom.init(inst, def);
|
|
10125
|
-
ZodType.init(inst, def);
|
|
10126
|
-
inst._zod.processJSONSchema = (ctx, json, params) => customProcessor(inst, ctx, json, params);
|
|
10127
|
-
});
|
|
10128
|
-
function refine(fn, _params = {}) {
|
|
10129
|
-
return /* @__PURE__ */ _refine(ZodCustom, fn, _params);
|
|
9771
|
+
var ZodCustom = /*@__PURE__*/ $constructor("ZodCustom", (inst, def) => {
|
|
9772
|
+
$ZodCustom.init(inst, def);
|
|
9773
|
+
ZodType.init(inst, def);
|
|
9774
|
+
inst._zod.processJSONSchema = (ctx, json, params) => customProcessor(inst, ctx, json, params);
|
|
9775
|
+
});
|
|
9776
|
+
function refine(fn, _params = {}) {
|
|
9777
|
+
return /* @__PURE__ */ _refine(ZodCustom, fn, _params);
|
|
9778
|
+
}
|
|
9779
|
+
function superRefine(fn, params) {
|
|
9780
|
+
return /* @__PURE__ */ _superRefine(fn, params);
|
|
9781
|
+
}
|
|
9782
|
+
function json$1(params) {
|
|
9783
|
+
const jsonSchema = lazy(() => {
|
|
9784
|
+
return union([
|
|
9785
|
+
string(params),
|
|
9786
|
+
number(),
|
|
9787
|
+
boolean(),
|
|
9788
|
+
_null(),
|
|
9789
|
+
array(jsonSchema),
|
|
9790
|
+
record$1(string(), jsonSchema)
|
|
9791
|
+
]);
|
|
9792
|
+
});
|
|
9793
|
+
return jsonSchema;
|
|
9794
|
+
}
|
|
9795
|
+
function preprocess(fn, schema) {
|
|
9796
|
+
return new ZodPreprocess({
|
|
9797
|
+
type: "pipe",
|
|
9798
|
+
in: transform(fn),
|
|
9799
|
+
out: schema
|
|
9800
|
+
});
|
|
9801
|
+
}
|
|
9802
|
+
//#endregion
|
|
9803
|
+
//#region ../../node_modules/.bun/zod@4.6.5/node_modules/zod/v4/classic/iso.js
|
|
9804
|
+
function datetime(params) {
|
|
9805
|
+
return /* @__PURE__ */ _isoDateTime(ZodISODateTime, params);
|
|
9806
|
+
}
|
|
9807
|
+
//#endregion
|
|
9808
|
+
//#region src/http/common/headers.ts
|
|
9809
|
+
/** Header names are case-insensitive; never silently combine duplicate business fields. */
|
|
9810
|
+
function httpHeaderNameIssue(name, names) {
|
|
9811
|
+
if (!/^[!#$%&'*+.^_`|~0-9A-Za-z-]+$/.test(name)) return "invalid";
|
|
9812
|
+
if (names.some((candidate) => candidate.toLowerCase() === name.toLowerCase())) return "duplicate";
|
|
9813
|
+
}
|
|
9814
|
+
//#endregion
|
|
9815
|
+
//#region src/http/common/hosts.ts
|
|
9816
|
+
/** Hosts of a Code `http` Capability: lowercase DNS names or IPv4 addresses; `*.example.com` matches subdomains only. */
|
|
9817
|
+
var httpHostPattern = /^(?:\*\.)?(?=.{1,253}$)(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)*[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$/;
|
|
9818
|
+
/** Wildcards must name a registrable suffix, so `*.com` is rejected. */
|
|
9819
|
+
function isHttpHost(value) {
|
|
9820
|
+
return httpHostPattern.test(value) && (!value.startsWith("*.") || value.slice(2).includes("."));
|
|
9821
|
+
}
|
|
9822
|
+
//#endregion
|
|
9823
|
+
//#region src/http/common/httpRequest.ts
|
|
9824
|
+
var parameterSchema = strictObject({
|
|
9825
|
+
mode: _enum(["fields", "object"]).default("fields"),
|
|
9826
|
+
names: array(string()).default([])
|
|
9827
|
+
});
|
|
9828
|
+
var httpRequestConfigSchema = strictObject({
|
|
9829
|
+
method: _enum([
|
|
9830
|
+
"GET",
|
|
9831
|
+
"POST",
|
|
9832
|
+
"PUT",
|
|
9833
|
+
"PATCH",
|
|
9834
|
+
"DELETE",
|
|
9835
|
+
"HEAD",
|
|
9836
|
+
"OPTIONS"
|
|
9837
|
+
]).default("GET"),
|
|
9838
|
+
query: parameterSchema.default({
|
|
9839
|
+
mode: "fields",
|
|
9840
|
+
names: []
|
|
9841
|
+
}),
|
|
9842
|
+
headers: parameterSchema.default({
|
|
9843
|
+
mode: "fields",
|
|
9844
|
+
names: []
|
|
9845
|
+
}),
|
|
9846
|
+
bodyFormat: _enum([
|
|
9847
|
+
"none",
|
|
9848
|
+
"json",
|
|
9849
|
+
"text",
|
|
9850
|
+
"form"
|
|
9851
|
+
]).default("none"),
|
|
9852
|
+
authentication: union([
|
|
9853
|
+
strictObject({ type: literal("none") }),
|
|
9854
|
+
strictObject({ type: _enum(["bearer", "basic"]) }),
|
|
9855
|
+
strictObject({
|
|
9856
|
+
type: literal("apiKey"),
|
|
9857
|
+
name: string(),
|
|
9858
|
+
in: _enum(["header", "query"])
|
|
9859
|
+
})
|
|
9860
|
+
]).default({ type: "none" }),
|
|
9861
|
+
responseFormat: _enum([
|
|
9862
|
+
"auto",
|
|
9863
|
+
"json",
|
|
9864
|
+
"text"
|
|
9865
|
+
]).default("auto"),
|
|
9866
|
+
statusPolicy: _enum(["success", "all"]).default("success")
|
|
9867
|
+
});
|
|
9868
|
+
var httpRequestExecutorSchema = httpRequestConfigSchema.extend({ kind: literal("http-request") });
|
|
9869
|
+
var scalarSchema = { type: [
|
|
9870
|
+
"string",
|
|
9871
|
+
"number",
|
|
9872
|
+
"boolean"
|
|
9873
|
+
] };
|
|
9874
|
+
var queryValueSchema = { anyOf: [scalarSchema, {
|
|
9875
|
+
type: "array",
|
|
9876
|
+
items: scalarSchema
|
|
9877
|
+
}] };
|
|
9878
|
+
var httpHeaderSchema = {
|
|
9879
|
+
type: "object",
|
|
9880
|
+
additionalProperties: { type: "string" }
|
|
9881
|
+
};
|
|
9882
|
+
var httpQuerySchema = {
|
|
9883
|
+
type: "object",
|
|
9884
|
+
additionalProperties: queryValueSchema
|
|
9885
|
+
};
|
|
9886
|
+
function httpAuthHandles(config) {
|
|
9887
|
+
return config.authentication.type == "none" ? [] : config.authentication.type == "basic" ? ["auth.username", "auth.password"] : ["auth.token"];
|
|
9888
|
+
}
|
|
9889
|
+
function retain(ports, old) {
|
|
9890
|
+
const remaining = new Map(ports.map((port) => [port.handle, port]));
|
|
9891
|
+
return [...old.flatMap((item) => {
|
|
9892
|
+
if ("group" in item) return [item];
|
|
9893
|
+
const next = remaining.get(item.handle);
|
|
9894
|
+
if (next == null) return [];
|
|
9895
|
+
remaining.delete(item.handle);
|
|
9896
|
+
return [dequal(item.jsonSchema, next.jsonSchema) && item.nullable == next.nullable ? item : next];
|
|
9897
|
+
}), ...remaining.values()];
|
|
9898
|
+
}
|
|
9899
|
+
function httpRequestTask(config = httpRequestConfigSchema.parse({}), name = "HTTP Request", previous) {
|
|
9900
|
+
const inputs = [{
|
|
9901
|
+
handle: "url",
|
|
9902
|
+
jsonSchema: { type: "string" },
|
|
9903
|
+
nullable: false
|
|
9904
|
+
}];
|
|
9905
|
+
for (const group of ["query", "headers"]) if (config[group].mode == "object") inputs.push({
|
|
9906
|
+
handle: group,
|
|
9907
|
+
jsonSchema: group == "query" ? httpQuerySchema : httpHeaderSchema,
|
|
9908
|
+
nullable: true
|
|
9909
|
+
});
|
|
9910
|
+
else for (const parameterName of config[group].names.filter((value) => value.trim())) inputs.push({
|
|
9911
|
+
handle: `${group == "query" ? "query" : "header"}.${parameterName}`,
|
|
9912
|
+
jsonSchema: group == "query" ? queryValueSchema : { type: "string" },
|
|
9913
|
+
nullable: true
|
|
9914
|
+
});
|
|
9915
|
+
if (config.bodyFormat != "none") inputs.push({
|
|
9916
|
+
handle: "body",
|
|
9917
|
+
jsonSchema: config.bodyFormat == "json" ? {} : config.bodyFormat == "text" ? { type: "string" } : httpQuerySchema,
|
|
9918
|
+
nullable: config.bodyFormat == "json"
|
|
9919
|
+
});
|
|
9920
|
+
inputs.push(...httpAuthHandles(config).map((handle) => ({
|
|
9921
|
+
handle,
|
|
9922
|
+
jsonSchema: { type: "string" },
|
|
9923
|
+
nullable: false
|
|
9924
|
+
})));
|
|
9925
|
+
const outputs = [
|
|
9926
|
+
{
|
|
9927
|
+
handle: "body",
|
|
9928
|
+
jsonSchema: config.responseFormat == "text" ? { type: "string" } : {},
|
|
9929
|
+
nullable: true
|
|
9930
|
+
},
|
|
9931
|
+
{
|
|
9932
|
+
handle: "statusCode",
|
|
9933
|
+
jsonSchema: { type: "integer" },
|
|
9934
|
+
nullable: false
|
|
9935
|
+
},
|
|
9936
|
+
{
|
|
9937
|
+
handle: "headers",
|
|
9938
|
+
jsonSchema: httpHeaderSchema,
|
|
9939
|
+
nullable: false
|
|
9940
|
+
}
|
|
9941
|
+
];
|
|
9942
|
+
return {
|
|
9943
|
+
name,
|
|
9944
|
+
executor: {
|
|
9945
|
+
...config,
|
|
9946
|
+
kind: "http-request"
|
|
9947
|
+
},
|
|
9948
|
+
inputs: retain(inputs, previous?.inputs ?? []),
|
|
9949
|
+
outputs: retain(outputs, previous?.outputs ?? [])
|
|
9950
|
+
};
|
|
9951
|
+
}
|
|
9952
|
+
function httpRequestIssues(config) {
|
|
9953
|
+
const issues = [];
|
|
9954
|
+
if (["GET", "HEAD"].includes(config.method) && config.bodyFormat != "none") issues.push({
|
|
9955
|
+
field: "bodyFormat",
|
|
9956
|
+
code: "bodyUnsupported",
|
|
9957
|
+
message: "GET and HEAD do not support a request body."
|
|
9958
|
+
});
|
|
9959
|
+
for (const group of ["query", "headers"]) {
|
|
9960
|
+
if (config[group].mode != "fields") continue;
|
|
9961
|
+
const seen = /* @__PURE__ */ new Set();
|
|
9962
|
+
for (const [index, name] of config[group].names.entries()) {
|
|
9963
|
+
const key = group == "headers" ? name.toLowerCase() : name;
|
|
9964
|
+
if (!name.trim() || seen.has(key)) issues.push({
|
|
9965
|
+
field: group,
|
|
9966
|
+
index,
|
|
9967
|
+
code: "parameterNamesInvalid",
|
|
9968
|
+
message: "Parameter names must be nonempty and unique."
|
|
9969
|
+
});
|
|
9970
|
+
seen.add(key);
|
|
9971
|
+
if (group == "headers" && httpHeaderNameIssue(name, []) === "invalid") issues.push({
|
|
9972
|
+
field: group,
|
|
9973
|
+
index,
|
|
9974
|
+
code: "headerNameInvalid",
|
|
9975
|
+
message: "Invalid HTTP header name."
|
|
9976
|
+
});
|
|
9977
|
+
}
|
|
9978
|
+
}
|
|
9979
|
+
const auth = config.authentication;
|
|
9980
|
+
if (auth.type != "none") {
|
|
9981
|
+
const group = auth.type == "apiKey" && auth.in == "query" ? "query" : "headers";
|
|
9982
|
+
const name = auth.type == "apiKey" ? auth.name : "authorization";
|
|
9983
|
+
if (!name.trim()) issues.push({
|
|
9984
|
+
field: "authentication",
|
|
9985
|
+
code: "keyNameRequired",
|
|
9986
|
+
message: "API Key requires a name."
|
|
9987
|
+
});
|
|
9988
|
+
if (group == "headers" && name.trim() && httpHeaderNameIssue(name, []) === "invalid") issues.push({
|
|
9989
|
+
field: "authentication",
|
|
9990
|
+
code: "headerNameInvalid",
|
|
9991
|
+
message: "Invalid authentication header name."
|
|
9992
|
+
});
|
|
9993
|
+
if (config[group].mode == "fields" && config[group].names.some((item) => group == "headers" ? item.toLowerCase() == name.toLowerCase() : item == name)) issues.push({
|
|
9994
|
+
field: "authentication",
|
|
9995
|
+
code: "authConflict",
|
|
9996
|
+
message: "Authentication conflicts with a request parameter."
|
|
9997
|
+
});
|
|
9998
|
+
}
|
|
9999
|
+
return issues;
|
|
10000
|
+
}
|
|
10001
|
+
function httpRequestUrl(value) {
|
|
10002
|
+
if (typeof value != "string" || !value.trim()) throw new Error("A URL is required.");
|
|
10003
|
+
const url = new URL(value);
|
|
10004
|
+
if (!["http:", "https:"].includes(url.protocol) || url.username || url.password) throw new Error("An HTTP(S) URL without credentials is required.");
|
|
10005
|
+
return url;
|
|
10006
|
+
}
|
|
10007
|
+
//#endregion
|
|
10008
|
+
//#region src/openapi/common/openapi.ts
|
|
10009
|
+
var methods = [
|
|
10010
|
+
"get",
|
|
10011
|
+
"put",
|
|
10012
|
+
"post",
|
|
10013
|
+
"delete",
|
|
10014
|
+
"options",
|
|
10015
|
+
"head",
|
|
10016
|
+
"patch",
|
|
10017
|
+
"trace"
|
|
10018
|
+
];
|
|
10019
|
+
function object(value) {
|
|
10020
|
+
if (value == null || typeof value != "object" || Array.isArray(value)) throw new Error("Expected an OpenAPI object.");
|
|
10021
|
+
return value;
|
|
10022
|
+
}
|
|
10023
|
+
function httpUrl(value, base) {
|
|
10024
|
+
const url = new URL(value, base);
|
|
10025
|
+
if (!["http:", "https:"].includes(url.protocol) || url.username || url.password || url.hash) throw new Error("An HTTP(S) URL without credentials or fragment is required.");
|
|
10026
|
+
return url.href;
|
|
10027
|
+
}
|
|
10028
|
+
function parseOpenApi(value) {
|
|
10029
|
+
const doc = object(value);
|
|
10030
|
+
if (typeof doc.openapi != "string" || !/^3\.[01]\.\d+$/.test(doc.openapi)) throw new Error("Only OpenAPI 3.0 and 3.1 JSON documents are supported.");
|
|
10031
|
+
object(doc.paths);
|
|
10032
|
+
return doc;
|
|
10033
|
+
}
|
|
10034
|
+
function pointer(doc, ref) {
|
|
10035
|
+
if (!ref.startsWith("#/")) throw new Error("External OpenAPI references are not supported.");
|
|
10036
|
+
let value = doc;
|
|
10037
|
+
for (const key of decodeURIComponent(ref.slice(2)).split("/").map((part) => part.replace(/~1/g, "/").replace(/~0/g, "~"))) {
|
|
10038
|
+
const source = object(value);
|
|
10039
|
+
if (!Object.hasOwn(source, key)) throw new Error("An OpenAPI reference is missing.");
|
|
10040
|
+
value = source[key];
|
|
10041
|
+
}
|
|
10042
|
+
return value;
|
|
10043
|
+
}
|
|
10044
|
+
function resolved(doc, value) {
|
|
10045
|
+
let result = object(value);
|
|
10046
|
+
const seen = /* @__PURE__ */ new Set();
|
|
10047
|
+
while (typeof result.$ref == "string") {
|
|
10048
|
+
if (seen.has(result.$ref)) throw new Error("Circular non-schema reference is unsupported.");
|
|
10049
|
+
seen.add(result.$ref);
|
|
10050
|
+
const { $ref, ...siblings } = result;
|
|
10051
|
+
result = {
|
|
10052
|
+
...object(pointer(doc, $ref)),
|
|
10053
|
+
...siblings
|
|
10054
|
+
};
|
|
10055
|
+
}
|
|
10056
|
+
return result;
|
|
10057
|
+
}
|
|
10058
|
+
function operation(doc, path, method) {
|
|
10059
|
+
const item = resolved(doc, object(doc.paths)[path]);
|
|
10060
|
+
if (!methods.includes(method) || item[method] == null) throw new Error("The selected operation is no longer available.");
|
|
10061
|
+
return {
|
|
10062
|
+
item,
|
|
10063
|
+
op: object(item[method])
|
|
10064
|
+
};
|
|
10065
|
+
}
|
|
10066
|
+
function servers(value, path, method) {
|
|
10067
|
+
const doc = parseOpenApi(value);
|
|
10068
|
+
const { item, op } = operation(doc, path, method);
|
|
10069
|
+
const entries = op.servers ?? item.servers ?? doc.servers;
|
|
10070
|
+
if (!Array.isArray(entries) || entries.length == 0) return [{ url: "/" }];
|
|
10071
|
+
return entries.map(object);
|
|
10072
|
+
}
|
|
10073
|
+
function snapshot(documentValue, path, method) {
|
|
10074
|
+
const doc = parseOpenApi(documentValue);
|
|
10075
|
+
const { item, op } = operation(doc, path, method);
|
|
10076
|
+
const security = op.security ?? doc.security ?? [];
|
|
10077
|
+
const result = {
|
|
10078
|
+
openapi: doc.openapi,
|
|
10079
|
+
paths: { [path]: {
|
|
10080
|
+
[method]: op,
|
|
10081
|
+
...item.parameters == null ? {} : { parameters: item.parameters }
|
|
10082
|
+
} },
|
|
10083
|
+
servers: servers(doc, path, method),
|
|
10084
|
+
security
|
|
10085
|
+
};
|
|
10086
|
+
const visited = /* @__PURE__ */ new Set();
|
|
10087
|
+
function copy(ref) {
|
|
10088
|
+
if (visited.has(ref)) return;
|
|
10089
|
+
visited.add(ref);
|
|
10090
|
+
const value = pointer(doc, ref);
|
|
10091
|
+
const keys = decodeURIComponent(ref.slice(2)).split("/").map((part) => part.replace(/~1/g, "/").replace(/~0/g, "~"));
|
|
10092
|
+
if (keys.some((key) => [
|
|
10093
|
+
"__proto__",
|
|
10094
|
+
"constructor",
|
|
10095
|
+
"prototype"
|
|
10096
|
+
].includes(key))) throw new Error("Unsupported reference key.");
|
|
10097
|
+
let target = result;
|
|
10098
|
+
for (const key of keys.slice(0, -1)) {
|
|
10099
|
+
if (!Object.hasOwn(target, key)) target[key] = {};
|
|
10100
|
+
target = object(target[key]);
|
|
10101
|
+
}
|
|
10102
|
+
target[keys.at(-1)] = structuredClone(value);
|
|
10103
|
+
visit(value);
|
|
10104
|
+
}
|
|
10105
|
+
function visit(value) {
|
|
10106
|
+
if (value == null || typeof value != "object") return;
|
|
10107
|
+
if (Array.isArray(value)) {
|
|
10108
|
+
value.forEach(visit);
|
|
10109
|
+
return;
|
|
10110
|
+
}
|
|
10111
|
+
if (typeof object(value).$ref == "string") copy(object(value).$ref);
|
|
10112
|
+
for (const [key, child] of Object.entries(value)) if (![
|
|
10113
|
+
"example",
|
|
10114
|
+
"examples",
|
|
10115
|
+
"default"
|
|
10116
|
+
].includes(key)) visit(child);
|
|
10117
|
+
}
|
|
10118
|
+
visit(result);
|
|
10119
|
+
for (const entry of security) for (const name of Object.keys(object(entry))) copy(`#/components/securitySchemes/${name.replace(/~/g, "~0").replace(/\//g, "~1")}`);
|
|
10120
|
+
return structuredClone(result);
|
|
10121
|
+
}
|
|
10122
|
+
function schema$1(doc, schemaValue) {
|
|
10123
|
+
const defs = {};
|
|
10124
|
+
const ids = /* @__PURE__ */ new Map();
|
|
10125
|
+
function convert(value) {
|
|
10126
|
+
if (typeof value == "boolean") return value;
|
|
10127
|
+
const source = object(value);
|
|
10128
|
+
if (source.format == "binary" || source.$dynamicRef != null || source.$id != null) throw new Error("Binary and dynamically scoped schemas are unsupported.");
|
|
10129
|
+
const result = {};
|
|
10130
|
+
for (const [key, child] of Object.entries(source)) {
|
|
10131
|
+
if ([
|
|
10132
|
+
"nullable",
|
|
10133
|
+
"example",
|
|
10134
|
+
"xml",
|
|
10135
|
+
"discriminator",
|
|
10136
|
+
"__proto__"
|
|
10137
|
+
].includes(key)) continue;
|
|
10138
|
+
if (key == "$ref") {
|
|
10139
|
+
if (typeof child != "string") throw new Error("Invalid schema reference.");
|
|
10140
|
+
let id = ids.get(child);
|
|
10141
|
+
if (id == null) {
|
|
10142
|
+
id = `s${ids.size}`;
|
|
10143
|
+
ids.set(child, id);
|
|
10144
|
+
defs[id] = convert(pointer(doc, child));
|
|
10145
|
+
}
|
|
10146
|
+
result.$ref = `#/$defs/${id}`;
|
|
10147
|
+
} else if ([
|
|
10148
|
+
"properties",
|
|
10149
|
+
"patternProperties",
|
|
10150
|
+
"$defs",
|
|
10151
|
+
"definitions",
|
|
10152
|
+
"dependentSchemas"
|
|
10153
|
+
].includes(key)) result[key] = Object.fromEntries(Object.entries(object(child)).map(([name, childSchema]) => [name, convert(childSchema)]));
|
|
10154
|
+
else if ([
|
|
10155
|
+
"allOf",
|
|
10156
|
+
"anyOf",
|
|
10157
|
+
"oneOf",
|
|
10158
|
+
"prefixItems"
|
|
10159
|
+
].includes(key)) {
|
|
10160
|
+
if (!Array.isArray(child)) throw new Error("Invalid schema composition.");
|
|
10161
|
+
result[key] = child.map(convert);
|
|
10162
|
+
} else if ([
|
|
10163
|
+
"items",
|
|
10164
|
+
"additionalProperties",
|
|
10165
|
+
"not",
|
|
10166
|
+
"if",
|
|
10167
|
+
"then",
|
|
10168
|
+
"else",
|
|
10169
|
+
"contains",
|
|
10170
|
+
"propertyNames",
|
|
10171
|
+
"unevaluatedProperties"
|
|
10172
|
+
].includes(key)) result[key] = convert(child);
|
|
10173
|
+
else result[key] = child;
|
|
10174
|
+
}
|
|
10175
|
+
if (source.nullable === true) return { anyOf: [result, { type: "null" }] };
|
|
10176
|
+
for (const key of ["minimum", "maximum"]) {
|
|
10177
|
+
const exclusive = key == "minimum" ? "exclusiveMinimum" : "exclusiveMaximum";
|
|
10178
|
+
if (typeof result[exclusive] == "boolean") {
|
|
10179
|
+
if (result[exclusive] && typeof result[key] == "number") {
|
|
10180
|
+
result[exclusive] = result[key];
|
|
10181
|
+
delete result[key];
|
|
10182
|
+
} else delete result[exclusive];
|
|
10183
|
+
}
|
|
10184
|
+
}
|
|
10185
|
+
return result;
|
|
10186
|
+
}
|
|
10187
|
+
let converted = convert(schemaValue);
|
|
10188
|
+
if (typeof converted == "object" && converted != null && typeof object(converted).$ref == "string") {
|
|
10189
|
+
const id = String(object(converted).$ref).slice(8);
|
|
10190
|
+
const { $ref: _ref, ...siblings } = object(converted);
|
|
10191
|
+
converted = {
|
|
10192
|
+
...object(defs[id]),
|
|
10193
|
+
...siblings
|
|
10194
|
+
};
|
|
10195
|
+
}
|
|
10196
|
+
if (typeof converted == "boolean") return converted;
|
|
10197
|
+
return {
|
|
10198
|
+
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
10199
|
+
...object(converted),
|
|
10200
|
+
...Object.keys(defs).length ? { $defs: defs } : {}
|
|
10201
|
+
};
|
|
10202
|
+
}
|
|
10203
|
+
function isOpenApiExecutor(executor) {
|
|
10204
|
+
return executor.kind == "openapi";
|
|
10205
|
+
}
|
|
10206
|
+
function parameters(config) {
|
|
10207
|
+
const doc = parseOpenApi(config.document);
|
|
10208
|
+
const { item, op } = operation(doc, config.path, config.method);
|
|
10209
|
+
const entries = /* @__PURE__ */ new Map();
|
|
10210
|
+
for (const value of [...item.parameters ?? [], ...op.parameters ?? []]) {
|
|
10211
|
+
const p = resolved(doc, value);
|
|
10212
|
+
if (![
|
|
10213
|
+
"path",
|
|
10214
|
+
"query",
|
|
10215
|
+
"header"
|
|
10216
|
+
].includes(String(p.in)) || typeof p.name != "string" || p.content != null) throw new Error("Only schema-based path, query and header parameters are supported.");
|
|
10217
|
+
if (p.allowReserved === true) throw new Error("allowReserved parameters are unsupported.");
|
|
10218
|
+
if ((p.style ?? (p.in == "query" ? "form" : "simple")) != (p.in == "query" ? "form" : "simple")) throw new Error("Only form query and simple path/header serialization are supported.");
|
|
10219
|
+
entries.set(`${p.in}.${p.in == "header" ? p.name.toLowerCase() : p.name}`, p);
|
|
10220
|
+
}
|
|
10221
|
+
return [...entries.values()];
|
|
10222
|
+
}
|
|
10223
|
+
function jsonContent(doc, value) {
|
|
10224
|
+
const content = resolved(doc, value);
|
|
10225
|
+
const media = object(content.content);
|
|
10226
|
+
const mediaType = media["application/json"] != null ? "application/json" : Object.keys(media).find((key) => /^application\/.+\+json$/.test(key));
|
|
10227
|
+
const json = mediaType == null ? void 0 : media[mediaType];
|
|
10228
|
+
if (json == null) throw new Error("Only JSON request and response bodies are supported.");
|
|
10229
|
+
return {
|
|
10230
|
+
schema: schema$1(doc, object(json).schema ?? {}),
|
|
10231
|
+
required: content.required === true,
|
|
10232
|
+
mediaType
|
|
10233
|
+
};
|
|
10130
10234
|
}
|
|
10131
|
-
function
|
|
10132
|
-
return
|
|
10235
|
+
function authHandles(auth) {
|
|
10236
|
+
return auth.flatMap((scheme) => scheme.type == "basic" ? [`auth.${scheme.id}.username`, `auth.${scheme.id}.password`] : [`auth.${scheme.id}.token`]);
|
|
10133
10237
|
}
|
|
10134
|
-
function
|
|
10135
|
-
|
|
10136
|
-
|
|
10137
|
-
|
|
10138
|
-
|
|
10139
|
-
|
|
10140
|
-
|
|
10141
|
-
|
|
10142
|
-
|
|
10143
|
-
|
|
10238
|
+
function openApiTask(config, name = "OpenAPI") {
|
|
10239
|
+
if (!config.path) return {
|
|
10240
|
+
name,
|
|
10241
|
+
executor: config,
|
|
10242
|
+
inputs: [],
|
|
10243
|
+
outputs: []
|
|
10244
|
+
};
|
|
10245
|
+
const doc = parseOpenApi(config.document);
|
|
10246
|
+
const { op } = operation(doc, config.path, config.method);
|
|
10247
|
+
const params = parameters(config);
|
|
10248
|
+
const inputs = params.map((p) => {
|
|
10249
|
+
const jsonSchema = schema$1(doc, p.schema ?? {});
|
|
10250
|
+
const defaultValue = typeof jsonSchema == "boolean" ? void 0 : object(jsonSchema).default;
|
|
10251
|
+
return {
|
|
10252
|
+
handle: `${p.in}.${p.name}`,
|
|
10253
|
+
jsonSchema,
|
|
10254
|
+
nullable: p.required !== true && p.in != "path" || matchesSchema(null, jsonSchema),
|
|
10255
|
+
...typeof p.description == "string" ? { description: p.description } : {},
|
|
10256
|
+
...defaultValue === void 0 ? {} : { value: defaultValue }
|
|
10257
|
+
};
|
|
10144
10258
|
});
|
|
10145
|
-
|
|
10259
|
+
if (op.requestBody != null) {
|
|
10260
|
+
if (config.method == "get" || config.method == "head") throw new Error("GET and HEAD request bodies are unsupported.");
|
|
10261
|
+
const body = jsonContent(doc, op.requestBody);
|
|
10262
|
+
inputs.push({
|
|
10263
|
+
handle: "body",
|
|
10264
|
+
jsonSchema: body.schema,
|
|
10265
|
+
nullable: !body.required || matchesSchema(null, body.schema)
|
|
10266
|
+
});
|
|
10267
|
+
}
|
|
10268
|
+
const occupied = new Set(params.map((p) => `${p.in}.${p.in == "header" ? String(p.name).toLowerCase() : p.name}`));
|
|
10269
|
+
for (const auth of config.auth) {
|
|
10270
|
+
const location = auth.type == "apiKey" ? `${auth.in}.${auth.in == "header" ? auth.name?.toLowerCase() : auth.name}` : "header.authorization";
|
|
10271
|
+
if (occupied.has(location)) throw new Error("Authentication conflicts with a parameter or another security scheme.");
|
|
10272
|
+
if (auth.type == "apiKey" && (!auth.name || !["header", "query"].includes(auth.in ?? ""))) throw new Error("API Key requires a name and location.");
|
|
10273
|
+
occupied.add(location);
|
|
10274
|
+
}
|
|
10275
|
+
inputs.push(...authHandles(config.auth).map((handle) => ({
|
|
10276
|
+
handle,
|
|
10277
|
+
jsonSchema: { type: "string" },
|
|
10278
|
+
nullable: false
|
|
10279
|
+
})));
|
|
10280
|
+
const responses = object(op.responses);
|
|
10281
|
+
const schemas = [];
|
|
10282
|
+
for (const [status, response] of Object.entries(responses)) if (/^2\d\d$|^2XX$/.test(status) || status == "default") {
|
|
10283
|
+
const r = resolved(doc, response);
|
|
10284
|
+
if (r.content == null) schemas.push({ type: "null" });
|
|
10285
|
+
else {
|
|
10286
|
+
jsonContent(doc, r);
|
|
10287
|
+
for (const [mediaType, media] of Object.entries(object(r.content))) if (/^application\/(json|.+\+json)$/.test(mediaType)) schemas.push(schema$1(doc, object(media).schema ?? {}));
|
|
10288
|
+
}
|
|
10289
|
+
}
|
|
10290
|
+
if (!schemas.length) throw new Error("A successful JSON response definition is required.");
|
|
10291
|
+
return {
|
|
10292
|
+
name,
|
|
10293
|
+
executor: config,
|
|
10294
|
+
inputs,
|
|
10295
|
+
outputs: [
|
|
10296
|
+
{
|
|
10297
|
+
handle: "body",
|
|
10298
|
+
jsonSchema: schemas.length == 1 ? schemas[0] : {
|
|
10299
|
+
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
10300
|
+
anyOf: schemas.map((s, index) => inlineSchema(s, index))
|
|
10301
|
+
},
|
|
10302
|
+
nullable: config.method == "head" || schemas.some((item) => matchesSchema(null, item))
|
|
10303
|
+
},
|
|
10304
|
+
{
|
|
10305
|
+
handle: "statusCode",
|
|
10306
|
+
jsonSchema: { type: "integer" },
|
|
10307
|
+
nullable: false
|
|
10308
|
+
},
|
|
10309
|
+
{
|
|
10310
|
+
handle: "headers",
|
|
10311
|
+
jsonSchema: {
|
|
10312
|
+
type: "object",
|
|
10313
|
+
additionalProperties: { type: "string" }
|
|
10314
|
+
},
|
|
10315
|
+
nullable: false
|
|
10316
|
+
}
|
|
10317
|
+
]
|
|
10318
|
+
};
|
|
10146
10319
|
}
|
|
10147
|
-
function
|
|
10148
|
-
return
|
|
10149
|
-
|
|
10150
|
-
|
|
10151
|
-
out: schema
|
|
10152
|
-
});
|
|
10320
|
+
function inlineSchema(value, index) {
|
|
10321
|
+
if (Array.isArray(value)) return value.map((item) => inlineSchema(item, index));
|
|
10322
|
+
if (value == null || typeof value != "object") return value;
|
|
10323
|
+
return Object.fromEntries(Object.entries(value).map(([key, child]) => [key, key == "$ref" && typeof child == "string" && child.startsWith("#/") ? `#/anyOf/${index}/${child.slice(2)}` : inlineSchema(child, index)]));
|
|
10153
10324
|
}
|
|
10154
|
-
|
|
10155
|
-
|
|
10156
|
-
|
|
10157
|
-
|
|
10325
|
+
/** The canvas validator and property panel share the same configuration contract. */
|
|
10326
|
+
function openApiFieldIssues(task) {
|
|
10327
|
+
if (!isOpenApiExecutor(task.executor)) return [];
|
|
10328
|
+
const config = task.executor;
|
|
10329
|
+
let field = "sourceUrl";
|
|
10330
|
+
try {
|
|
10331
|
+
if (!config.sourceUrl.trim()) return [{
|
|
10332
|
+
field,
|
|
10333
|
+
message: "Enter an OpenAPI JSON document URL."
|
|
10334
|
+
}];
|
|
10335
|
+
httpUrl(config.sourceUrl);
|
|
10336
|
+
field = "operation";
|
|
10337
|
+
if (!config.path) return [{
|
|
10338
|
+
field,
|
|
10339
|
+
message: "Select an OpenAPI operation."
|
|
10340
|
+
}];
|
|
10341
|
+
field = "serverUrl";
|
|
10342
|
+
httpUrl(config.serverUrl);
|
|
10343
|
+
if (new URL(config.serverUrl).search) throw new Error("Server URLs must not contain a query string.");
|
|
10344
|
+
field = "operation";
|
|
10345
|
+
if (!dequal(config.document, snapshot(config.document, config.path, config.method))) return [{
|
|
10346
|
+
field,
|
|
10347
|
+
message: "Save only the selected operation and its dependencies."
|
|
10348
|
+
}];
|
|
10349
|
+
const expected = openApiTask(config, task.name);
|
|
10350
|
+
if (!dequal(expected.inputs, task.inputs) || !dequal(expected.outputs, task.outputs)) return [{
|
|
10351
|
+
field,
|
|
10352
|
+
message: "OpenAPI ports must match the saved operation."
|
|
10353
|
+
}];
|
|
10354
|
+
return [];
|
|
10355
|
+
} catch (error) {
|
|
10356
|
+
return [{
|
|
10357
|
+
field,
|
|
10358
|
+
message: error.message
|
|
10359
|
+
}];
|
|
10360
|
+
}
|
|
10158
10361
|
}
|
|
10159
|
-
|
|
10160
|
-
|
|
10161
|
-
var portSchema = object({
|
|
10162
|
-
handle: string().min(1),
|
|
10163
|
-
jsonSchema: json$1(),
|
|
10164
|
-
nullable: boolean(),
|
|
10165
|
-
description: string().optional()
|
|
10166
|
-
});
|
|
10167
|
-
strictObject({
|
|
10168
|
-
inputs: array(portSchema).nullable(),
|
|
10169
|
-
outputs: array(portSchema).nullable()
|
|
10170
|
-
});
|
|
10171
|
-
object({
|
|
10172
|
-
version: literal(1),
|
|
10173
|
-
flowId: string().min(1),
|
|
10174
|
-
name: string(),
|
|
10175
|
-
revisionId: string().min(1),
|
|
10176
|
-
publicationId: string().min(1),
|
|
10177
|
-
inputs: array(portSchema),
|
|
10178
|
-
outputs: array(portSchema).nullable()
|
|
10179
|
-
});
|
|
10180
|
-
object({
|
|
10181
|
-
version: literal(1),
|
|
10182
|
-
direction: _enum(["incoming", "outgoing"]),
|
|
10183
|
-
total: int().nonnegative(),
|
|
10184
|
-
nextOffset: int().nonnegative().optional(),
|
|
10185
|
-
references: array(object({
|
|
10186
|
-
flowId: string(),
|
|
10187
|
-
name: string().nullable(),
|
|
10188
|
-
available: boolean(),
|
|
10189
|
-
draft: boolean(),
|
|
10190
|
-
live: object({
|
|
10191
|
-
publicationId: string(),
|
|
10192
|
-
enabled: boolean()
|
|
10193
|
-
}).nullable()
|
|
10194
|
-
}))
|
|
10195
|
-
});
|
|
10196
|
-
/** Workflow declarations share discovery across authoring, admission and resource indexing. */
|
|
10197
|
-
function nodeWorkflowReferences(node) {
|
|
10198
|
-
if (node.kind != "task") return [];
|
|
10199
|
-
if ("moduleId" in node.task) return (node.task.capabilities ?? []).flatMap((item, index) => item.kind == "workflow" ? [{
|
|
10200
|
-
target: item,
|
|
10201
|
-
path: `task/capabilities/${index}`,
|
|
10202
|
-
tool: item.name
|
|
10203
|
-
}] : []);
|
|
10204
|
-
if (node.task.executor.kind == "workflow") return [{
|
|
10205
|
-
target: {
|
|
10206
|
-
...node.task.executor,
|
|
10207
|
-
inputs: node.task.inputs.filter((port) => "handle" in port),
|
|
10208
|
-
outputs: node.task.outputs.filter((port) => "handle" in port)
|
|
10209
|
-
},
|
|
10210
|
-
path: "task/executor"
|
|
10211
|
-
}];
|
|
10212
|
-
if (node.task.executor.kind == "agent") return node.task.executor.tools.flatMap((item, index) => item.kind == "workflow" ? [{
|
|
10213
|
-
target: item,
|
|
10214
|
-
path: `task/executor/tools/${index}`,
|
|
10215
|
-
tool: item.name
|
|
10216
|
-
}] : []);
|
|
10217
|
-
return [];
|
|
10362
|
+
function openApiIssues(task) {
|
|
10363
|
+
return openApiFieldIssues(task).map((issue) => issue.message);
|
|
10218
10364
|
}
|
|
10219
10365
|
//#endregion
|
|
10220
10366
|
//#region src/flow/common/inputValue.ts
|
|
@@ -10233,6 +10379,7 @@ var retryNodeTypes = [
|
|
|
10233
10379
|
"code",
|
|
10234
10380
|
"connector",
|
|
10235
10381
|
"openapi",
|
|
10382
|
+
"http-request",
|
|
10236
10383
|
"llm",
|
|
10237
10384
|
"decision"
|
|
10238
10385
|
];
|
|
@@ -10251,11 +10398,11 @@ function supportsNodeRetry(node) {
|
|
|
10251
10398
|
}
|
|
10252
10399
|
//#endregion
|
|
10253
10400
|
//#region src/flow/common/triggerScheduleSchema.ts
|
|
10254
|
-
var triggerScheduleSchema = array(union([object({
|
|
10401
|
+
var triggerScheduleSchema = array(union([object$1({
|
|
10255
10402
|
type: literal("cron"),
|
|
10256
10403
|
expression: string(),
|
|
10257
10404
|
timezone: string()
|
|
10258
|
-
}), object({
|
|
10405
|
+
}), object$1({
|
|
10259
10406
|
type: literal("every"),
|
|
10260
10407
|
unit: _enum([
|
|
10261
10408
|
"day",
|
|
@@ -10349,11 +10496,6 @@ function workflowOutputsPort(outputs) {
|
|
|
10349
10496
|
nullable: false
|
|
10350
10497
|
};
|
|
10351
10498
|
}
|
|
10352
|
-
/** Header names are case-insensitive; never silently combine duplicate business fields. */
|
|
10353
|
-
function webhookHeaderNameIssue(name, names) {
|
|
10354
|
-
if (!/^[!#$%&'*+.^_`|~0-9A-Za-z-]+$/.test(name)) return "invalid";
|
|
10355
|
-
if (names.some((candidate) => candidate.toLowerCase() === name.toLowerCase())) return "duplicate";
|
|
10356
|
-
}
|
|
10357
10499
|
/** Fixed inputs belong to the node, not author-supplied definitions. */
|
|
10358
10500
|
var webhookResponseInputs = [
|
|
10359
10501
|
{
|
|
@@ -10384,7 +10526,7 @@ function webhookHeaderValues(source) {
|
|
|
10384
10526
|
const headers = {};
|
|
10385
10527
|
const names = [];
|
|
10386
10528
|
for (const [name, value] of Object.entries(source)) {
|
|
10387
|
-
if (
|
|
10529
|
+
if (httpHeaderNameIssue(name, names) != null) return;
|
|
10388
10530
|
if (typeof value !== "string" && typeof value !== "boolean" && !(typeof value === "number" && Number.isFinite(value))) return;
|
|
10389
10531
|
const text = String(value);
|
|
10390
10532
|
if ([...text].some((character) => character.charCodeAt(0) > 255 || /[\0\r\n]/.test(character))) return;
|
|
@@ -10401,7 +10543,7 @@ var text = string();
|
|
|
10401
10543
|
var actionConnection = text.describe("Account selection: omit while unconfigured; use an account ID to select it; use \"\" to explicitly defer configuration. Deferred Actions fail if called; deferred Agent tools are excluded from the callable tool set. Not supported by Triggers.");
|
|
10402
10544
|
var json = json$1();
|
|
10403
10545
|
var strings = array(text);
|
|
10404
|
-
var port = object({
|
|
10546
|
+
var port = object$1({
|
|
10405
10547
|
description: text.optional(),
|
|
10406
10548
|
jsonSchema: json,
|
|
10407
10549
|
nullable: boolean(),
|
|
@@ -10409,25 +10551,25 @@ var port = object({
|
|
|
10409
10551
|
});
|
|
10410
10552
|
var workflowInputDefs = array(port.strict());
|
|
10411
10553
|
var input = port.extend({ value: json.optional() });
|
|
10412
|
-
var group = object({
|
|
10554
|
+
var group = object$1({
|
|
10413
10555
|
collapsed: boolean().optional(),
|
|
10414
10556
|
group: text
|
|
10415
10557
|
});
|
|
10416
|
-
var source = union([object({
|
|
10558
|
+
var source = union([object$1({
|
|
10417
10559
|
kind: literal("node"),
|
|
10418
10560
|
nodeId: text,
|
|
10419
10561
|
output: text,
|
|
10420
10562
|
system: literal(true).optional(),
|
|
10421
10563
|
field: text.optional()
|
|
10422
|
-
}), object({
|
|
10564
|
+
}), object$1({
|
|
10423
10565
|
kind: literal("binding"),
|
|
10424
10566
|
bindingId: text
|
|
10425
10567
|
})]);
|
|
10426
|
-
var fixedInput = union([object({ kind: literal("unset") }), object({
|
|
10568
|
+
var fixedInput = union([object$1({ kind: literal("unset") }), object$1({
|
|
10427
10569
|
kind: literal("value"),
|
|
10428
10570
|
value: json
|
|
10429
10571
|
})]);
|
|
10430
|
-
var mapping = union([fixedInput, object({
|
|
10572
|
+
var mapping = union([fixedInput, object$1({
|
|
10431
10573
|
kind: literal("sources"),
|
|
10432
10574
|
sources: array(source)
|
|
10433
10575
|
})]);
|
|
@@ -10476,21 +10618,28 @@ var workflowCapabilitySchema = strictObject({
|
|
|
10476
10618
|
inputs: array(port),
|
|
10477
10619
|
outputs: array(port).nullable()
|
|
10478
10620
|
});
|
|
10479
|
-
var capability = union([
|
|
10480
|
-
|
|
10621
|
+
var capability = union([
|
|
10622
|
+
connectorCapabilitySchema,
|
|
10623
|
+
workflowCapabilitySchema,
|
|
10624
|
+
strictObject({
|
|
10625
|
+
kind: literal("http"),
|
|
10626
|
+
hosts: array(text.refine(isHttpHost, "Use a lowercase host name or IPv4 address, optionally prefixed by \"*.\" for subdomains.")).min(1).max(20).describe("Hosts Code may call with context.fetch. \"*.example.com\" matches subdomains only.")
|
|
10627
|
+
})
|
|
10628
|
+
]);
|
|
10629
|
+
var inline = object$1({
|
|
10481
10630
|
...ports,
|
|
10482
10631
|
name: text,
|
|
10483
10632
|
moduleId: text,
|
|
10484
10633
|
capabilities: array(capability).optional()
|
|
10485
10634
|
});
|
|
10486
|
-
var agentValue = union([object({
|
|
10635
|
+
var agentValue = union([object$1({
|
|
10487
10636
|
kind: literal("value"),
|
|
10488
10637
|
value: json
|
|
10489
|
-
}), object({
|
|
10638
|
+
}), object$1({
|
|
10490
10639
|
kind: literal("input"),
|
|
10491
10640
|
input: text
|
|
10492
10641
|
})]);
|
|
10493
|
-
var agentInput$1 = union([agentValue, object({ kind: literal("model") })]);
|
|
10642
|
+
var agentInput$1 = union([agentValue, object$1({ kind: literal("model") })]);
|
|
10494
10643
|
var agentToolFields = {
|
|
10495
10644
|
id: text,
|
|
10496
10645
|
name: text,
|
|
@@ -10498,7 +10647,7 @@ var agentToolFields = {
|
|
|
10498
10647
|
approval: boolean(),
|
|
10499
10648
|
inputs: array(input.extend({ source: agentInput$1 }))
|
|
10500
10649
|
};
|
|
10501
|
-
var connectorAgentToolSchema = object({
|
|
10650
|
+
var connectorAgentToolSchema = object$1({
|
|
10502
10651
|
...agentToolFields,
|
|
10503
10652
|
kind: literal("connector").optional(),
|
|
10504
10653
|
action: text,
|
|
@@ -10531,24 +10680,24 @@ var decisionQuestion = discriminatedUnion("type", [
|
|
|
10531
10680
|
criteria: strings
|
|
10532
10681
|
})
|
|
10533
10682
|
]);
|
|
10534
|
-
var managedFields = object({
|
|
10683
|
+
var managedFields = object$1({
|
|
10535
10684
|
...ports,
|
|
10536
10685
|
name: text,
|
|
10537
10686
|
executor: union([
|
|
10538
|
-
object({
|
|
10687
|
+
object$1({
|
|
10539
10688
|
kind: literal("connector"),
|
|
10540
10689
|
action: text,
|
|
10541
10690
|
connectionId: actionConnection.optional(),
|
|
10542
10691
|
outputMode: literal("value").optional()
|
|
10543
10692
|
}),
|
|
10544
|
-
object({
|
|
10693
|
+
object$1({
|
|
10545
10694
|
kind: literal("openapi"),
|
|
10546
10695
|
sourceUrl: text,
|
|
10547
10696
|
method: text,
|
|
10548
10697
|
path: text,
|
|
10549
10698
|
serverUrl: text,
|
|
10550
10699
|
document: json,
|
|
10551
|
-
auth: array(object({
|
|
10700
|
+
auth: array(object$1({
|
|
10552
10701
|
id: text,
|
|
10553
10702
|
type: _enum([
|
|
10554
10703
|
"bearer",
|
|
@@ -10563,18 +10712,18 @@ var managedFields = object({
|
|
|
10563
10712
|
kind: literal("decision"),
|
|
10564
10713
|
questions: array(decisionQuestion)
|
|
10565
10714
|
}),
|
|
10566
|
-
object({
|
|
10715
|
+
object$1({
|
|
10567
10716
|
kind: literal("llm"),
|
|
10568
10717
|
mode: _enum(["chat", "json"])
|
|
10569
10718
|
}),
|
|
10570
|
-
object({
|
|
10719
|
+
object$1({
|
|
10571
10720
|
kind: literal("agent"),
|
|
10572
10721
|
code: boolean().optional(),
|
|
10573
10722
|
model: text,
|
|
10574
10723
|
prompt: text,
|
|
10575
10724
|
maxRounds: number(),
|
|
10576
10725
|
tools: array(union([workflowAgentToolSchema, connectorAgentToolSchema])),
|
|
10577
|
-
notification: object({
|
|
10726
|
+
notification: object$1({
|
|
10578
10727
|
action: text,
|
|
10579
10728
|
connectionId: actionConnection.optional(),
|
|
10580
10729
|
inputDefinitions: array(input),
|
|
@@ -10586,24 +10735,25 @@ var managedFields = object({
|
|
|
10586
10735
|
kind: literal("workflow"),
|
|
10587
10736
|
flowId: text,
|
|
10588
10737
|
revisionId: text
|
|
10589
|
-
})
|
|
10738
|
+
}),
|
|
10739
|
+
httpRequestExecutorSchema
|
|
10590
10740
|
])
|
|
10591
10741
|
});
|
|
10592
10742
|
var managed = managedFields.transform(limitDecisionTask);
|
|
10593
|
-
var operand = union([object({
|
|
10743
|
+
var operand = union([object$1({
|
|
10594
10744
|
kind: literal("value"),
|
|
10595
10745
|
value: json.optional(),
|
|
10596
10746
|
jsonSchema: json.optional()
|
|
10597
|
-
}), object({
|
|
10747
|
+
}), object$1({
|
|
10598
10748
|
kind: literal("source"),
|
|
10599
10749
|
source
|
|
10600
10750
|
})]);
|
|
10601
10751
|
var condition = {
|
|
10602
10752
|
matchMode: _enum(["first", "all"]),
|
|
10603
|
-
cases: array(object({
|
|
10753
|
+
cases: array(object$1({
|
|
10604
10754
|
description: text.optional(),
|
|
10605
10755
|
output: text,
|
|
10606
|
-
groups: array(object({ expressions: array(object({
|
|
10756
|
+
groups: array(object$1({ expressions: array(object$1({
|
|
10607
10757
|
left: operand,
|
|
10608
10758
|
operator: _enum([
|
|
10609
10759
|
"!=",
|
|
@@ -10635,7 +10785,7 @@ var wait = {
|
|
|
10635
10785
|
inputDefinitions: array(input),
|
|
10636
10786
|
prompt: text
|
|
10637
10787
|
};
|
|
10638
|
-
var webhookOptions = object({
|
|
10788
|
+
var webhookOptions = object$1({
|
|
10639
10789
|
allowedMethods: never().optional(),
|
|
10640
10790
|
allowedOrigins: strings.optional(),
|
|
10641
10791
|
noResponseBody: never().optional(),
|
|
@@ -10673,8 +10823,8 @@ var definition = {
|
|
|
10673
10823
|
outputs: array(port).refine((definitions) => new Set(definitions.map((output) => output.handle)).size === definitions.length, "Duplicate Trigger output handle."),
|
|
10674
10824
|
provider: text
|
|
10675
10825
|
};
|
|
10676
|
-
var endpoint = object({
|
|
10677
|
-
body: object({
|
|
10826
|
+
var endpoint = object$1({
|
|
10827
|
+
body: object$1({
|
|
10678
10828
|
allowArray: boolean(),
|
|
10679
10829
|
allowEmpty: boolean(),
|
|
10680
10830
|
formats: array(_enum([
|
|
@@ -10723,19 +10873,19 @@ var node = union([
|
|
|
10723
10873
|
outputDefs: array(port.strict()),
|
|
10724
10874
|
outputMappings: inputs
|
|
10725
10875
|
}).omit({ inputs: true }),
|
|
10726
|
-
object({
|
|
10876
|
+
object$1({
|
|
10727
10877
|
...base,
|
|
10728
10878
|
inputs: record$1(text, never()),
|
|
10729
10879
|
kind: literal("condition"),
|
|
10730
10880
|
...condition
|
|
10731
10881
|
}),
|
|
10732
|
-
object({
|
|
10882
|
+
object$1({
|
|
10733
10883
|
...base,
|
|
10734
10884
|
inputs: unknown().transform(() => ({})).default({}),
|
|
10735
10885
|
kind: literal("value"),
|
|
10736
10886
|
values: array(input)
|
|
10737
10887
|
}),
|
|
10738
|
-
object({
|
|
10888
|
+
object$1({
|
|
10739
10889
|
...base,
|
|
10740
10890
|
kind: literal("task"),
|
|
10741
10891
|
task: union([inline, managed]),
|
|
@@ -10752,7 +10902,7 @@ var node = union([
|
|
|
10752
10902
|
...wait,
|
|
10753
10903
|
autoContinue: waitAutoContinueDraftSchema.optional()
|
|
10754
10904
|
}).omit({ timeoutMs: true }),
|
|
10755
|
-
object({
|
|
10905
|
+
object$1({
|
|
10756
10906
|
...trigger,
|
|
10757
10907
|
kind: literal("manual")
|
|
10758
10908
|
}),
|
|
@@ -10766,33 +10916,33 @@ var node = union([
|
|
|
10766
10916
|
kind: literal("error"),
|
|
10767
10917
|
sourceFlowIds: sourceFlowIds.optional()
|
|
10768
10918
|
}),
|
|
10769
|
-
object({
|
|
10919
|
+
object$1({
|
|
10770
10920
|
...trigger,
|
|
10771
10921
|
kind: literal("webhook"),
|
|
10772
10922
|
...webhook
|
|
10773
10923
|
}),
|
|
10774
|
-
object({
|
|
10924
|
+
object$1({
|
|
10775
10925
|
...trigger,
|
|
10776
10926
|
kind: literal("cron"),
|
|
10777
10927
|
cronTimes: triggerScheduleSchema
|
|
10778
10928
|
}),
|
|
10779
|
-
object({
|
|
10929
|
+
object$1({
|
|
10780
10930
|
...trigger,
|
|
10781
10931
|
kind: literal("poll"),
|
|
10782
10932
|
connectionId: text.min(1).optional(),
|
|
10783
10933
|
config: record$1(text, fixedInput),
|
|
10784
|
-
definition: object({
|
|
10934
|
+
definition: object$1({
|
|
10785
10935
|
...definition,
|
|
10786
10936
|
type: literal("poll")
|
|
10787
10937
|
}),
|
|
10788
10938
|
pollTimes: triggerScheduleSchema
|
|
10789
10939
|
}),
|
|
10790
|
-
object({
|
|
10940
|
+
object$1({
|
|
10791
10941
|
...trigger,
|
|
10792
10942
|
kind: literal("integration"),
|
|
10793
10943
|
connectionId: text.min(1).optional(),
|
|
10794
10944
|
config: record$1(text, fixedInput),
|
|
10795
|
-
definition: object({
|
|
10945
|
+
definition: object$1({
|
|
10796
10946
|
...definition,
|
|
10797
10947
|
type: literal("integration"),
|
|
10798
10948
|
endpoint
|
|
@@ -10819,7 +10969,7 @@ var authoringDefinitionSchemas = {
|
|
|
10819
10969
|
notification: true
|
|
10820
10970
|
}).strict()
|
|
10821
10971
|
};
|
|
10822
|
-
var edge = object({
|
|
10972
|
+
var edge = object$1({
|
|
10823
10973
|
source: text,
|
|
10824
10974
|
target: text,
|
|
10825
10975
|
sourceHandle: text.optional()
|
|
@@ -10828,24 +10978,24 @@ var at = {
|
|
|
10828
10978
|
nodeId: text,
|
|
10829
10979
|
target: never().optional()
|
|
10830
10980
|
};
|
|
10831
|
-
var graph = object({
|
|
10981
|
+
var graph = object$1({
|
|
10832
10982
|
nodes: record$1(text, node),
|
|
10833
10983
|
edges: array(edge).default([])
|
|
10834
10984
|
});
|
|
10835
|
-
var binding = object({
|
|
10985
|
+
var binding = object$1({
|
|
10836
10986
|
kind: literal("variable"),
|
|
10837
10987
|
target: text
|
|
10838
10988
|
});
|
|
10839
|
-
var module = object({
|
|
10989
|
+
var module = object$1({
|
|
10840
10990
|
name: text,
|
|
10841
10991
|
imports: strings,
|
|
10842
10992
|
source: text
|
|
10843
10993
|
});
|
|
10844
|
-
var document = preprocess(normalizeDocument, object({
|
|
10994
|
+
var document = preprocess(normalizeDocument, object$1({
|
|
10845
10995
|
bindings: record$1(text, binding),
|
|
10846
10996
|
graph
|
|
10847
10997
|
}));
|
|
10848
|
-
object({
|
|
10998
|
+
object$1({
|
|
10849
10999
|
modelVersion: union([
|
|
10850
11000
|
literal(2),
|
|
10851
11001
|
literal(4),
|
|
@@ -10855,7 +11005,8 @@ object({
|
|
|
10855
11005
|
literal(8),
|
|
10856
11006
|
literal(9),
|
|
10857
11007
|
literal(10),
|
|
10858
|
-
literal(11)
|
|
11008
|
+
literal(11),
|
|
11009
|
+
literal(12)
|
|
10859
11010
|
]),
|
|
10860
11011
|
document,
|
|
10861
11012
|
modules: record$1(text, module)
|
|
@@ -10916,21 +11067,21 @@ var shapes = {
|
|
|
10916
11067
|
},
|
|
10917
11068
|
"graph.node.delete": at,
|
|
10918
11069
|
"graph.node.field.set": union([
|
|
10919
|
-
object({
|
|
11070
|
+
object$1({
|
|
10920
11071
|
...at,
|
|
10921
11072
|
kind: literal("graph.node.field.set"),
|
|
10922
11073
|
field: literal("retry"),
|
|
10923
11074
|
before: retryConfigurationSchema.optional(),
|
|
10924
11075
|
value: retryConfigurationSchema.optional()
|
|
10925
11076
|
}),
|
|
10926
|
-
object({
|
|
11077
|
+
object$1({
|
|
10927
11078
|
...at,
|
|
10928
11079
|
kind: literal("graph.node.field.set"),
|
|
10929
11080
|
field: literal("connectionId"),
|
|
10930
11081
|
before: text.min(1).optional(),
|
|
10931
11082
|
value: text.min(1).optional()
|
|
10932
11083
|
}),
|
|
10933
|
-
object({
|
|
11084
|
+
object$1({
|
|
10934
11085
|
...at,
|
|
10935
11086
|
kind: literal("graph.node.field.set"),
|
|
10936
11087
|
field: _enum([
|
|
@@ -10942,14 +11093,14 @@ var shapes = {
|
|
|
10942
11093
|
before: text.optional(),
|
|
10943
11094
|
value: text.optional()
|
|
10944
11095
|
}),
|
|
10945
|
-
object({
|
|
11096
|
+
object$1({
|
|
10946
11097
|
...at,
|
|
10947
11098
|
kind: literal("graph.node.field.set"),
|
|
10948
11099
|
field: literal("maxExecutions"),
|
|
10949
11100
|
before: number().int().positive().max(Number.MAX_SAFE_INTEGER).optional(),
|
|
10950
11101
|
value: number().int().positive().max(Number.MAX_SAFE_INTEGER).optional()
|
|
10951
11102
|
}),
|
|
10952
|
-
object({
|
|
11103
|
+
object$1({
|
|
10953
11104
|
...at,
|
|
10954
11105
|
kind: literal("graph.node.field.set"),
|
|
10955
11106
|
field: literal("timeoutMs"),
|
|
@@ -10970,8 +11121,8 @@ var shapes = {
|
|
|
10970
11121
|
},
|
|
10971
11122
|
"graph.node.condition.set": {
|
|
10972
11123
|
...at,
|
|
10973
|
-
before: object(condition),
|
|
10974
|
-
value: object(condition)
|
|
11124
|
+
before: object$1(condition),
|
|
11125
|
+
value: object$1(condition)
|
|
10975
11126
|
},
|
|
10976
11127
|
"graph.node.values.set": {
|
|
10977
11128
|
...at,
|
|
@@ -10991,13 +11142,13 @@ var shapes = {
|
|
|
10991
11142
|
},
|
|
10992
11143
|
"graph.node.webhook.set": {
|
|
10993
11144
|
...at,
|
|
10994
|
-
before: object(webhook),
|
|
10995
|
-
value: object(webhook)
|
|
11145
|
+
before: object$1(webhook),
|
|
11146
|
+
value: object$1(webhook)
|
|
10996
11147
|
},
|
|
10997
11148
|
"graph.node.task.ports.set": {
|
|
10998
11149
|
...at,
|
|
10999
|
-
before: object(ports),
|
|
11000
|
-
value: object(ports)
|
|
11150
|
+
before: object$1(ports),
|
|
11151
|
+
value: object$1(ports)
|
|
11001
11152
|
},
|
|
11002
11153
|
"graph.node.task.name.set": {
|
|
11003
11154
|
...at,
|
|
@@ -11043,7 +11194,7 @@ var shapes = {
|
|
|
11043
11194
|
value: union([inline, managed])
|
|
11044
11195
|
}
|
|
11045
11196
|
};
|
|
11046
|
-
array(union([...new Map(Object.entries(shapes).map(([kind, shape]) => [kind, shape instanceof ZodType ? shape : object({
|
|
11197
|
+
array(union([...new Map(Object.entries(shapes).map(([kind, shape]) => [kind, shape instanceof ZodType ? shape : object$1({
|
|
11047
11198
|
kind: literal(kind),
|
|
11048
11199
|
...shape
|
|
11049
11200
|
})])).values()])).min(1);
|
|
@@ -11210,13 +11361,15 @@ function nodeSystemOutputPorts(node) {
|
|
|
11210
11361
|
} } : {};
|
|
11211
11362
|
}
|
|
11212
11363
|
//#endregion
|
|
11364
|
+
//#region src/flow/common/model.ts
|
|
11365
|
+
function portsByHandle(ports) {
|
|
11366
|
+
return Object.fromEntries(ports.flatMap((port) => "handle" in port ? [[port.handle, port]] : []));
|
|
11367
|
+
}
|
|
11368
|
+
//#endregion
|
|
11213
11369
|
//#region src/flow/common/change.ts
|
|
11214
11370
|
function validVariableName(value) {
|
|
11215
11371
|
return value.length <= 256 && /^[A-Za-z_][A-Za-z0-9_]*$/.test(value) && value.slice(0, 3).toUpperCase() != "OO_";
|
|
11216
11372
|
}
|
|
11217
|
-
function portsByHandle(ports) {
|
|
11218
|
-
return Object.fromEntries(ports.flatMap((port) => "handle" in port ? [[port.handle, port]] : []));
|
|
11219
|
-
}
|
|
11220
11373
|
var workflowToolNamePattern = /^[A-Za-z][A-Za-z0-9_-]{0,63}$/;
|
|
11221
11374
|
function workflowToolNameIssue(name, otherNames = []) {
|
|
11222
11375
|
if (!workflowToolNamePattern.test(name)) return "invalid";
|
|
@@ -11232,6 +11385,8 @@ function decodeTaskCapabilities(value) {
|
|
|
11232
11385
|
if (workflowToolNameIssue(item.name, names)) throw new TypeError("Workflow tool names must be unique provider-compatible names.");
|
|
11233
11386
|
names.add(item.name);
|
|
11234
11387
|
}
|
|
11388
|
+
const http = parsed.filter((item) => item.kind == "http");
|
|
11389
|
+
if (http.length > 1 || http.some((item) => new Set(item.hosts).size != item.hosts.length)) throw new TypeError("Code declares HTTP hosts once, without duplicates.");
|
|
11235
11390
|
let connectorIndex = 0;
|
|
11236
11391
|
return parsed.map((item) => item.kind == "connector" ? connectors[connectorIndex++] : item);
|
|
11237
11392
|
}
|
|
@@ -11360,6 +11515,31 @@ function isTriggerNode(node) {
|
|
|
11360
11515
|
].includes(node.kind);
|
|
11361
11516
|
}
|
|
11362
11517
|
//#endregion
|
|
11518
|
+
//#region src/flow/common/workflowReferences.ts
|
|
11519
|
+
/** Workflow declarations share discovery across authoring, admission and resource indexing. */
|
|
11520
|
+
function nodeWorkflowReferences(node) {
|
|
11521
|
+
if (node.kind != "task") return [];
|
|
11522
|
+
if ("moduleId" in node.task) return (node.task.capabilities ?? []).flatMap((item, index) => item.kind == "workflow" ? [{
|
|
11523
|
+
target: item,
|
|
11524
|
+
path: `task/capabilities/${index}`,
|
|
11525
|
+
tool: item.name
|
|
11526
|
+
}] : []);
|
|
11527
|
+
if (node.task.executor.kind == "workflow") return [{
|
|
11528
|
+
target: {
|
|
11529
|
+
...node.task.executor,
|
|
11530
|
+
inputs: node.task.inputs.filter((port) => "handle" in port),
|
|
11531
|
+
outputs: node.task.outputs.filter((port) => "handle" in port)
|
|
11532
|
+
},
|
|
11533
|
+
path: "task/executor"
|
|
11534
|
+
}];
|
|
11535
|
+
if (node.task.executor.kind == "agent") return node.task.executor.tools.flatMap((item, index) => item.kind == "workflow" ? [{
|
|
11536
|
+
target: item,
|
|
11537
|
+
path: `task/executor/tools/${index}`,
|
|
11538
|
+
tool: item.name
|
|
11539
|
+
}] : []);
|
|
11540
|
+
return [];
|
|
11541
|
+
}
|
|
11542
|
+
//#endregion
|
|
11363
11543
|
//#region src/flow/common/promptTemplate.ts
|
|
11364
11544
|
var promptReferencePattern = /\{\{\s*([^{}\s]+)\s*\}\}/g;
|
|
11365
11545
|
function renderPrompt(template, input) {
|
|
@@ -11454,7 +11634,7 @@ function clearNodeConnections(graph, connectionId) {
|
|
|
11454
11634
|
return [id, node];
|
|
11455
11635
|
}
|
|
11456
11636
|
const capabilities = node.task.capabilities?.map((capability) => {
|
|
11457
|
-
if (capability.kind == "workflow") return capability;
|
|
11637
|
+
if (capability.kind == "workflow" || capability.kind == "http") return capability;
|
|
11458
11638
|
if (!("mode" in capability)) {
|
|
11459
11639
|
if ("action" in capability) {
|
|
11460
11640
|
const { connectionId: selected, ...rest } = capability;
|
|
@@ -11699,21 +11879,25 @@ function normalizeTriggerOutputs(trigger, outputs) {
|
|
|
11699
11879
|
return matchesTriggerOutputs(trigger, normalized) ? normalized : void 0;
|
|
11700
11880
|
}
|
|
11701
11881
|
//#endregion
|
|
11702
|
-
//#region src/
|
|
11703
|
-
|
|
11882
|
+
//#region src/runtime/common/engineContract.ts
|
|
11883
|
+
/** v9 is a single contract: the Node compatibility builtins, `context.fetch`, and no `context.egress`. */
|
|
11884
|
+
var currentEngineContract = "open-flow-engine/v9";
|
|
11885
|
+
/** The published v8 Node compatibility contract, retained for existing Publications and Runs. */
|
|
11704
11886
|
var nodejsEngineContract = "open-flow-engine/v8/nodejs-compat-v1";
|
|
11705
|
-
var
|
|
11887
|
+
var platformSource = (contract) => `export const engineContract = ${JSON.stringify(contract)}
|
|
11888
|
+
export function identity(value) { return value }
|
|
11889
|
+
`;
|
|
11890
|
+
var v8Contract = {
|
|
11706
11891
|
workflowTools: true,
|
|
11892
|
+
httpRequests: true,
|
|
11707
11893
|
waitAutoContinue: true,
|
|
11708
11894
|
webhookResponses: true,
|
|
11709
11895
|
platformExports: /* @__PURE__ */ new Set(["engineContract", "identity"]),
|
|
11710
11896
|
platformModule: "open-flow:platform",
|
|
11711
|
-
platformSource:
|
|
11712
|
-
export function identity(value) { return value }
|
|
11713
|
-
`
|
|
11897
|
+
platformSource: platformSource("open-flow-engine/v8")
|
|
11714
11898
|
};
|
|
11715
11899
|
var nodejsContract = {
|
|
11716
|
-
...
|
|
11900
|
+
...v8Contract,
|
|
11717
11901
|
builtinModules: new Set([
|
|
11718
11902
|
"assert",
|
|
11719
11903
|
"assert/strict",
|
|
@@ -11740,26 +11924,30 @@ var nodejsContract = {
|
|
|
11740
11924
|
"util",
|
|
11741
11925
|
"zlib"
|
|
11742
11926
|
].flatMap((name) => [name, `node:${name}`])),
|
|
11743
|
-
platformSource:
|
|
11744
|
-
|
|
11745
|
-
|
|
11927
|
+
platformSource: platformSource(nodejsEngineContract)
|
|
11928
|
+
};
|
|
11929
|
+
var currentContract = {
|
|
11930
|
+
...nodejsContract,
|
|
11931
|
+
codeFetch: true,
|
|
11932
|
+
platformSource: platformSource(currentEngineContract)
|
|
11746
11933
|
};
|
|
11747
11934
|
function findEngineContract(contract) {
|
|
11748
|
-
if (contract == "open-flow-engine/
|
|
11935
|
+
if (contract == "open-flow-engine/v9") return currentContract;
|
|
11936
|
+
if (contract == "open-flow-engine/v8") return v8Contract;
|
|
11749
11937
|
if (contract == "open-flow-engine/v8/nodejs-compat-v1") return nodejsContract;
|
|
11750
11938
|
if (contract == "open-flow-engine/v7" || contract == "open-flow-engine/v7/nodejs-compat-v1") return {
|
|
11751
|
-
...contract.endsWith("/nodejs-compat-v1") ? nodejsContract :
|
|
11939
|
+
...contract.endsWith("/nodejs-compat-v1") ? nodejsContract : v8Contract,
|
|
11752
11940
|
workflowTools: false,
|
|
11753
|
-
|
|
11941
|
+
httpRequests: false,
|
|
11942
|
+
platformSource: platformSource(contract)
|
|
11754
11943
|
};
|
|
11755
11944
|
if (contract == "open-flow-engine/v6" || contract == "open-flow-engine/v6/nodejs-compat-v1") return {
|
|
11756
|
-
...contract == "open-flow-engine/v6" ?
|
|
11945
|
+
...contract == "open-flow-engine/v6" ? v8Contract : nodejsContract,
|
|
11757
11946
|
workflowTools: false,
|
|
11947
|
+
httpRequests: false,
|
|
11758
11948
|
waitAutoContinue: false,
|
|
11759
11949
|
webhookResponses: false,
|
|
11760
|
-
platformSource:
|
|
11761
|
-
export function identity(value) { return value }
|
|
11762
|
-
`
|
|
11950
|
+
platformSource: platformSource(contract)
|
|
11763
11951
|
};
|
|
11764
11952
|
}
|
|
11765
11953
|
//#endregion
|
|
@@ -12442,7 +12630,7 @@ function webhookResponseDiagnostics(graph, triggerId, path = `/document/graph/no
|
|
|
12442
12630
|
if (headersSource == null) for (const [headers, location] of [[options.responseHeaders, `${path}/options/responseHeaders`], [headerOutputs, headersPath]]) {
|
|
12443
12631
|
const names = [];
|
|
12444
12632
|
for (const name of Object.keys(headers ?? {})) {
|
|
12445
|
-
if (
|
|
12633
|
+
if (httpHeaderNameIssue(name, names) != null) diagnostics.push(graphDiagnostic("trigger.webhook-response-header-name", "Use valid, unique HTTP header names.", location));
|
|
12446
12634
|
names.push(name);
|
|
12447
12635
|
}
|
|
12448
12636
|
}
|
|
@@ -24746,12 +24934,47 @@ async function validateFlow(revision, engine) {
|
|
|
24746
24934
|
message,
|
|
24747
24935
|
path: `/document/graph/nodes/${nodeId}/task/executor`
|
|
24748
24936
|
});
|
|
24749
|
-
if (task.executor.kind == "
|
|
24750
|
-
const
|
|
24937
|
+
if (task.executor.kind == "http-request") {
|
|
24938
|
+
for (const issue of httpRequestIssues(task.executor)) checked.diagnostics.push({
|
|
24939
|
+
code: "http-request.config-invalid",
|
|
24940
|
+
column: 0,
|
|
24941
|
+
line: 1,
|
|
24942
|
+
message: issue.message,
|
|
24943
|
+
path: `/document/graph/nodes/${nodeId}/task/executor/${issue.field}`
|
|
24944
|
+
});
|
|
24945
|
+
if (node.inputs.url?.kind == "value") try {
|
|
24946
|
+
httpRequestUrl(node.inputs.url.value);
|
|
24947
|
+
} catch {
|
|
24948
|
+
checked.diagnostics.push({
|
|
24949
|
+
code: "http-request.url-invalid",
|
|
24950
|
+
column: 0,
|
|
24951
|
+
line: 1,
|
|
24952
|
+
message: "Enter an HTTP(S) URL without embedded credentials.",
|
|
24953
|
+
path: `/document/graph/nodes/${nodeId}/inputs/url`
|
|
24954
|
+
});
|
|
24955
|
+
}
|
|
24956
|
+
if (task.executor.bodyFormat != "none" && (node.inputs.body == null || node.inputs.body.kind == "unset")) checked.diagnostics.push({
|
|
24957
|
+
code: "http-request.body-required",
|
|
24958
|
+
column: 0,
|
|
24959
|
+
line: 1,
|
|
24960
|
+
message: "Set or bind the request body; JSON null is an explicit value.",
|
|
24961
|
+
path: `/document/graph/nodes/${nodeId}/inputs/body`
|
|
24962
|
+
});
|
|
24963
|
+
const expected = httpRequestTask(task.executor);
|
|
24964
|
+
if (!dequal(httpPortContracts(task.inputs), httpPortContracts(expected.inputs)) || !dequal(httpPortContracts(task.outputs), httpPortContracts(expected.outputs))) checked.diagnostics.push({
|
|
24965
|
+
code: "http-request.ports-invalid",
|
|
24966
|
+
column: 0,
|
|
24967
|
+
line: 1,
|
|
24968
|
+
message: "HTTP Request ports must match its configuration.",
|
|
24969
|
+
path: `/document/graph/nodes/${nodeId}/task`
|
|
24970
|
+
});
|
|
24971
|
+
}
|
|
24972
|
+
if (task.executor.kind == "openapi" || task.executor.kind == "http-request") {
|
|
24973
|
+
const handles = task.executor.kind == "openapi" ? authHandles(task.executor.auth) : httpAuthHandles(task.executor);
|
|
24751
24974
|
for (const handle of handles) {
|
|
24752
24975
|
const mapping = node.inputs[handle];
|
|
24753
24976
|
if (mapping?.kind != "sources" || mapping.sources.length == 0) checked.diagnostics.push({
|
|
24754
|
-
code:
|
|
24977
|
+
code: `${task.executor.kind}.auth-source`,
|
|
24755
24978
|
column: 0,
|
|
24756
24979
|
line: 1,
|
|
24757
24980
|
message: "Authentication requires a deployment variable or upstream output.",
|
|
@@ -24837,9 +25060,16 @@ function runRevision(revision, triggerId) {
|
|
|
24837
25060
|
}
|
|
24838
25061
|
};
|
|
24839
25062
|
}
|
|
25063
|
+
var httpPortContracts = (ports) => ports.filter((port) => "handle" in port).map(({ handle, jsonSchema, nullable }) => ({
|
|
25064
|
+
handle,
|
|
25065
|
+
jsonSchema,
|
|
25066
|
+
nullable
|
|
25067
|
+
})).toSorted((a, b) => a.handle.localeCompare(b.handle));
|
|
24840
25068
|
async function prepareFlow(revision, engineContract, triggerId) {
|
|
24841
25069
|
const engine = findEngineContract(engineContract);
|
|
24842
25070
|
if (engine == null) return { kind: "engine-unsupported" };
|
|
25071
|
+
if (!engine.httpRequests && Object.values(revision.document.graph.nodes).some((node) => node.kind == "task" && "executor" in node.task && node.task.executor.kind == "http-request")) return { kind: "engine-unsupported" };
|
|
25072
|
+
if (!engine.codeFetch && Object.values(revision.document.graph.nodes).some((node) => node.kind == "task" && "moduleId" in node.task && node.task.capabilities?.some((item) => item.kind == "http"))) return { kind: "engine-unsupported" };
|
|
24843
25073
|
if (!engine.workflowTools && Object.values(revision.document.graph.nodes).some((node) => nodeWorkflowReferences(node).some((ref) => ref.tool != null))) return { kind: "engine-unsupported" };
|
|
24844
25074
|
if (triggerId != null) {
|
|
24845
25075
|
const trigger = revision.document.graph.nodes[triggerId];
|