@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.
Files changed (139) hide show
  1. package/README.md +3 -1
  2. package/dist/browser/{ContentIcon-CUQHjQIw.js → ContentIcon-Cm1hbVzW.js} +4 -3
  3. package/dist/browser/{FlowCanvas-Dtf8_cQp.js → FlowCanvas-NzKtla_c.js} +62 -62
  4. package/dist/browser/{createResourceDialog-DI9pL-Yr.js → createResourceDialog-BgdedQqu.js} +3 -3
  5. package/dist/browser/{dialog-BYJGvItc.js → dialog-aSElFFw2.js} +322 -26
  6. package/dist/browser/{exportSvg-BOoy7-Db.js → exportSvg-Dcz4HTo_.js} +2 -2
  7. package/dist/browser/{flowChanges-RL-H4CjD.js → flowChanges-NZyS7HSp.js} +490 -438
  8. package/dist/browser/{flowWorkspace-BkDsETj0.js → flowWorkspace-Bl0SDehy.js} +499 -61
  9. package/dist/browser/preview.css +696 -825
  10. package/dist/browser/preview.js +1399 -717
  11. package/dist/browser/theme.css +114 -262
  12. package/dist/browser/{tooltip-wZJRB9oP.js → tooltip-3XMK9jkr.js} +1 -1
  13. package/dist/browser/{typeScriptSession-CSRwWmZm.js → typeScriptSession-C9sBGOKZ.js} +1 -1
  14. package/dist/browser/ui.css +354 -460
  15. package/dist/browser/ui.js +1 -1
  16. package/dist/browser/workbench.css +696 -825
  17. package/dist/browser/workbench.js +13 -7
  18. package/dist/browser/{workbenchSelect-BcWPWGzw.js → workbenchSelect-DBGP7Y4Z.js} +2 -2
  19. package/dist/command/index.js +41 -43
  20. package/dist/common/authoring.d.ts +5 -5
  21. package/dist/common/authoringExamples.d.ts +3 -2
  22. package/dist/common/authoringSchema.d.ts +70 -4
  23. package/dist/common/connector-proxy.d.ts +1 -1
  24. package/dist/common/control-api-conformance.js +250 -138
  25. package/dist/common/control-api.d.ts +3 -2
  26. package/dist/common/control-api.js +246 -134
  27. package/dist/common/control-requests.d.ts +3 -3
  28. package/dist/common/control-requests.js +353 -79
  29. package/dist/common/cron-trigger.d.ts +2 -1
  30. package/dist/common/decision.d.ts +4 -4
  31. package/dist/common/decision.js +5 -2
  32. package/dist/common/engine-contract.d.ts +6 -1
  33. package/dist/common/event-source-definition.d.ts +1 -1
  34. package/dist/common/event-source-view.d.ts +22 -0
  35. package/dist/common/event-source.d.ts +1 -1
  36. package/dist/common/event-source.js +24 -65
  37. package/dist/common/event-sources.d.ts +0 -21
  38. package/dist/common/flow-authoring.js +90 -19
  39. package/dist/common/flow-change-schema.d.ts +9 -1
  40. package/dist/common/flow-change.d.ts +7 -201
  41. package/dist/common/flow-change.js +96 -23
  42. package/dist/common/flow-encoding.js +89 -21
  43. package/dist/common/flow-graph.d.ts +2 -1
  44. package/dist/common/flow-input-value.d.ts +1 -1
  45. package/dist/common/flow-model.d.ts +121 -0
  46. package/dist/common/flow-notifications.d.ts +1 -1
  47. package/dist/common/flow-retry.d.ts +3 -5
  48. package/dist/common/flow-semantics.js +816 -586
  49. package/dist/common/flow-workflowReferences.d.ts +8 -0
  50. package/dist/common/flowInspection.d.ts +1 -1
  51. package/dist/common/http-hosts.d.ts +6 -0
  52. package/dist/common/http-request.d.ts +164 -0
  53. package/dist/common/http-request.js +5272 -0
  54. package/dist/common/integration-trigger.d.ts +2 -1
  55. package/dist/common/mcp.d.ts +3 -3
  56. package/dist/common/mcp.js +248 -136
  57. package/dist/common/openapi.d.ts +4 -4
  58. package/dist/common/openapi.js +4 -1
  59. package/dist/common/poll-trigger.d.ts +2 -1
  60. package/dist/common/run-events.js +11 -9
  61. package/dist/common/runtime-contract.d.ts +23 -1
  62. package/dist/common/runtime-contract.js +607 -72
  63. package/dist/common/runtime-nodejs-compat.d.ts +44 -0
  64. package/dist/common/runtime-nodejs-compat.js +5870 -0
  65. package/dist/common/scheduler-checkpoint.d.ts +1 -1
  66. package/dist/common/scheduler-node-execution.d.ts +1 -1
  67. package/dist/common/scheduler.d.ts +2 -2
  68. package/dist/common/scheduler.js +95 -25
  69. package/dist/common/trigger-catalog.d.ts +1 -7
  70. package/dist/common/trigger-config-options.d.ts +1 -1
  71. package/dist/common/trigger-config.d.ts +1 -1
  72. package/dist/common/trigger-contract.d.ts +2 -1
  73. package/dist/common/trigger-localization.d.ts +8 -2
  74. package/dist/common/trigger-model.d.ts +101 -0
  75. package/dist/common/webhook-response.d.ts +1 -3
  76. package/dist/common/webhook-trigger.d.ts +3 -1
  77. package/dist/common/webhook-trigger.js +12 -11
  78. package/dist/common/workflow.d.ts +3 -12
  79. package/dist/common/workflow.js +25 -23
  80. package/dist/index.d.ts +41 -14
  81. package/package.json +9 -1
  82. package/skills/open-flow/references/flow-authoring.md +1 -0
  83. package/skills/open-flow/references/flow-n8n-conversion.md +19 -15
  84. package/src/base/common/json.ts +1 -1
  85. package/src/connector/common/proxy.ts +1 -1
  86. package/src/control/common/api.ts +7 -5
  87. package/src/control/common/authoring.ts +14 -3
  88. package/src/control/common/authoringExamples.ts +8 -0
  89. package/src/control/common/authoringSchema.ts +38 -25
  90. package/src/control/common/authoringTools.ts +1 -1
  91. package/src/control/common/conformance.ts +1 -1
  92. package/src/control/common/connectorDecoders.ts +1 -1
  93. package/src/control/common/eventSources.ts +2 -29
  94. package/src/control/common/triggerCatalog.ts +1 -8
  95. package/src/decision/common/decision.ts +15 -7
  96. package/src/event-source/common/definition.ts +1 -1
  97. package/src/event-source/common/index.ts +1 -1
  98. package/src/event-source/common/view.ts +20 -0
  99. package/src/execution/common/checkpoint.ts +1 -1
  100. package/src/execution/common/events.ts +3 -0
  101. package/src/execution/common/node-execution.ts +5 -3
  102. package/src/execution/common/scheduler.ts +2 -1
  103. package/src/flow/common/change.ts +59 -192
  104. package/src/flow/common/changeSchema.ts +39 -5
  105. package/src/flow/common/connectionUsage.ts +1 -1
  106. package/src/flow/common/graph.ts +10 -4
  107. package/src/flow/common/inputValue.ts +1 -1
  108. package/src/flow/common/model.ts +130 -0
  109. package/src/flow/common/modules.ts +1 -1
  110. package/src/flow/common/portChanges.ts +1 -1
  111. package/src/flow/common/retry.ts +3 -5
  112. package/src/flow/common/semantics.ts +71 -7
  113. package/src/flow/common/webhookResponse.ts +4 -8
  114. package/src/flow/common/workflowReferences.ts +31 -0
  115. package/src/http/common/authBindings.ts +9 -0
  116. package/src/http/common/headers.ts +5 -0
  117. package/src/http/common/hosts.ts +13 -0
  118. package/src/http/common/httpRequest.ts +266 -0
  119. package/src/openapi/common/openapi.ts +9 -5
  120. package/src/{execution → runtime}/common/engineContract.ts +24 -15
  121. package/src/runtime/common/nodejsCompat.ts +275 -0
  122. package/src/runtime/common/nodejsGuest.generated.json +47 -0
  123. package/src/runtime/common/runtime.ts +1138 -0
  124. package/src/trigger/common/config.ts +1 -1
  125. package/src/trigger/common/configOptions.ts +1 -1
  126. package/src/trigger/common/contract.ts +2 -1
  127. package/src/trigger/common/cron.ts +2 -1
  128. package/src/trigger/common/integration.ts +2 -1
  129. package/src/trigger/common/model.ts +87 -0
  130. package/src/trigger/common/poll.ts +2 -1
  131. package/src/trigger/common/webhook.ts +7 -4
  132. package/src/trigger/providers/fieldDescriptions.ts +1 -1
  133. package/src/trigger/providers/localization.ts +9 -2
  134. package/src/trigger/providers/remote.ts +1 -1
  135. package/src/types/index.ts +44 -15
  136. package/src/workflow/common/workflow.ts +3 -44
  137. package/src/execution/common/runtime.ts +0 -563
  138. package/src/openapi/common/authBindings.ts +0 -12
  139. /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.kind !== "decision") return task;
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.kind !== "decision") return [];
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 src/openapi/common/openapi.ts
4132
- var methods = [
4133
- "get",
4134
- "put",
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 parseOpenApi(value) {
4152
- const doc = object$1(value);
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 pointer(doc, ref) {
4158
- if (!ref.startsWith("#/")) throw new Error("External OpenAPI references are not supported.");
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
- function resolved(doc, value) {
4168
- let result = object$1(value);
4169
- const seen = /* @__PURE__ */ new Set();
4170
- while (typeof result.$ref == "string") {
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
- function visit(value) {
4229
- if (value == null || typeof value != "object") return;
4230
- if (Array.isArray(value)) {
4231
- value.forEach(visit);
4232
- return;
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
- if (typeof object$1(value).$ref == "string") copy(object$1(value).$ref);
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
- visit(result);
4242
- for (const entry of security) for (const name of Object.keys(object$1(entry))) copy(`#/components/securitySchemes/${name.replace(/~/g, "~0").replace(/\//g, "~1")}`);
4243
- return structuredClone(result);
4159
+ };
4160
+ function cached(getter) {
4161
+ return new Cached(getter);
4244
4162
  }
4245
- function schema$1(doc, schemaValue) {
4246
- const defs = {};
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 parameters(config) {
4327
- const doc = parseOpenApi(config.document);
4328
- const { item, op } = operation(doc, config.path, config.method);
4329
- const entries = /* @__PURE__ */ new Map();
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 jsonContent(doc, value) {
4344
- const content = resolved(doc, value);
4345
- const media = object$1(content.content);
4346
- const mediaType = media["application/json"] != null ? "application/json" : Object.keys(media).find((key) => /^application\/.+\+json$/.test(key));
4347
- const json = mediaType == null ? void 0 : media[mediaType];
4348
- if (json == null) throw new Error("Only JSON request and response bodies are supported.");
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
- function authHandles(auth) {
4356
- return auth.flatMap((scheme) => scheme.type == "basic" ? [`auth.${scheme.id}.username`, `auth.${scheme.id}.password`] : [`auth.${scheme.id}.token`]);
4357
- }
4358
- function openApiTask(config, name = "OpenAPI") {
4359
- if (!config.path) return {
4360
- name,
4361
- executor: config,
4362
- inputs: [],
4363
- outputs: []
4364
- };
4365
- const doc = parseOpenApi(config.document);
4366
- const { op } = operation(doc, config.path, config.method);
4367
- const params = parameters(config);
4368
- const inputs = params.map((p) => {
4369
- const jsonSchema = schema$1(doc, p.schema ?? {});
4370
- const defaultValue = typeof jsonSchema == "boolean" ? void 0 : object$1(jsonSchema).default;
4371
- return {
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 superRefine(fn, params) {
10132
- return /* @__PURE__ */ _superRefine(fn, params);
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 json$1(params) {
10135
- const jsonSchema = lazy(() => {
10136
- return union([
10137
- string(params),
10138
- number(),
10139
- boolean(),
10140
- _null(),
10141
- array(jsonSchema),
10142
- record$1(string(), jsonSchema)
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
- return jsonSchema;
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 preprocess(fn, schema) {
10148
- return new ZodPreprocess({
10149
- type: "pipe",
10150
- in: transform(fn),
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
- //#endregion
10155
- //#region ../../node_modules/.bun/zod@4.6.5/node_modules/zod/v4/classic/iso.js
10156
- function datetime(params) {
10157
- return /* @__PURE__ */ _isoDateTime(ZodISODateTime, params);
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
- //#endregion
10160
- //#region src/workflow/common/workflow.ts
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 (webhookHeaderNameIssue(name, names) != null) return;
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([connectorCapabilitySchema, workflowCapabilitySchema]);
10480
- var inline = object({
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/execution/common/engineContract.ts
11703
- var currentEngineContract = "open-flow-engine/v8";
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 currentContract = {
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: `export const engineContract = ${JSON.stringify(currentEngineContract)}
11712
- export function identity(value) { return value }
11713
- `
11897
+ platformSource: platformSource("open-flow-engine/v8")
11714
11898
  };
11715
11899
  var nodejsContract = {
11716
- ...currentContract,
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: `export const engineContract = ${JSON.stringify(nodejsEngineContract)}
11744
- export function identity(value) { return value }
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/v8") return currentContract;
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 : currentContract,
11939
+ ...contract.endsWith("/nodejs-compat-v1") ? nodejsContract : v8Contract,
11752
11940
  workflowTools: false,
11753
- platformSource: `export const engineContract = ${JSON.stringify(contract)}\nexport function identity(value) { return value }\n`
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" ? currentContract : nodejsContract,
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: `export const engineContract = ${JSON.stringify(contract)}
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 (webhookHeaderNameIssue(name, names) != null) diagnostics.push(graphDiagnostic("trigger.webhook-response-header-name", "Use valid, unique HTTP header names.", location));
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 == "openapi") {
24750
- const handles = authHandles(task.executor.auth);
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: "openapi.auth-source",
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];