@oomol-lab/open-flow 0.1.0-beta.85 → 0.1.0-beta.87

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 (102) hide show
  1. package/dist/browser/{FlowCanvas-CZoHhB1y.js → FlowCanvas-SqPUBqze.js} +3 -3
  2. package/dist/browser/{createResourceDialog-Bi4fUnbD.js → createResourceDialog-CB3eiK7e.js} +3 -3
  3. package/dist/browser/{dialog-BzoSxhXQ.js → dialog-Bi-MVTGj.js} +291 -143
  4. package/dist/browser/{exportPng-CXVWVlLc.js → exportPng-CLZKdNzR.js} +2 -2
  5. package/dist/browser/{flowChanges-C567g-Pc.js → flowChanges-azhepfr-.js} +375 -83
  6. package/dist/browser/{flowWorkspace-BNdBKtla.js → flowWorkspace-Cs2ZGBYK.js} +1619 -475
  7. package/dist/browser/fr-CNTSedYU.js +593 -0
  8. package/dist/browser/ja-CxQBHr2J.js +593 -0
  9. package/dist/browser/ko-D1Exiv1h.js +593 -0
  10. package/dist/browser/licenses.md +1 -1
  11. package/dist/browser/{markdownContent-DF39sd9T.js → markdownContent-D0BBrFcF.js} +1 -1
  12. package/dist/browser/preview.css +193 -191
  13. package/dist/browser/preview.js +1997 -624
  14. package/dist/browser/ru-BzLZv0B7.js +593 -0
  15. package/dist/browser/theme.css +3 -1
  16. package/dist/browser/{tooltip-DGj5pudg.js → tooltip-BZ6tpqnr.js} +58 -24
  17. package/dist/browser/ui.css +12 -10
  18. package/dist/browser/ui.d.ts +1 -0
  19. package/dist/browser/ui.js +110 -63
  20. package/dist/browser/workbench.css +193 -191
  21. package/dist/browser/workbench.js +86 -17
  22. package/dist/browser/{workbenchSelect-BIaEVTx6.js → workbenchSelect-CHOeceKA.js} +2 -2
  23. package/dist/browser/{wrapLayout-C4moMKgb.js → wrapLayout-BB_qwy3k.js} +1 -1
  24. package/dist/browser/zh-CN-Dg_xSGde.js +593 -0
  25. package/dist/browser/zh-TW-oxuLwsV0.js +593 -0
  26. package/dist/command/index.js +61 -57
  27. package/dist/command/licenses.md +28 -4
  28. package/dist/common/authoring.d.ts +5 -5
  29. package/dist/common/authoringExamples.d.ts +3 -2
  30. package/dist/common/authoringSchema.d.ts +41 -4
  31. package/dist/common/catalogCache.d.ts +46 -0
  32. package/dist/common/connector-action.js +13 -10
  33. package/dist/common/connector-proxy.d.ts +96 -0
  34. package/dist/common/connector-proxy.js +5209 -0
  35. package/dist/common/control-api-conformance.js +312 -46
  36. package/dist/common/control-api.d.ts +12 -1
  37. package/dist/common/control-api.js +303 -41
  38. package/dist/common/control-requests.d.ts +4 -3
  39. package/dist/common/control-requests.js +14111 -171
  40. package/dist/common/engine-contract.d.ts +3 -2
  41. package/dist/common/event-source.js +55 -23
  42. package/dist/common/flow-authoring-node.d.ts +2 -0
  43. package/dist/common/flow-authoring.js +6936 -6781
  44. package/dist/common/flow-change-schema.d.ts +1 -1
  45. package/dist/common/flow-change.d.ts +2 -2
  46. package/dist/common/flow-change.js +91 -36
  47. package/dist/common/flow-connectionUsage.d.ts +1 -1
  48. package/dist/common/flow-encoding.js +93 -38
  49. package/dist/common/flow-requestParameters.d.ts +34 -0
  50. package/dist/common/flow-semantics.js +9429 -9236
  51. package/dist/common/flow-state.js +55 -23
  52. package/dist/common/flow-workflowFile.d.ts +3 -1
  53. package/dist/common/http-request.d.ts +6 -11
  54. package/dist/common/http-request.js +192 -141
  55. package/dist/common/licenses.md +1 -1
  56. package/dist/common/mcp.d.ts +3 -3
  57. package/dist/common/mcp.js +303 -41
  58. package/dist/common/run-events.js +1 -0
  59. package/dist/common/runtime-contract.js +10 -4
  60. package/dist/common/runtime-nodejs-compat.js +55 -23
  61. package/dist/common/scheduler-checkpoint.d.ts +3 -3
  62. package/dist/common/scheduler-dependencies.d.ts +22 -28
  63. package/dist/common/scheduler-node-execution.d.ts +1 -0
  64. package/dist/common/scheduler.d.ts +8 -2
  65. package/dist/common/scheduler.js +274 -95
  66. package/dist/common/workflow.js +51 -19
  67. package/dist/common/workflowAuthoring.d.ts +411 -0
  68. package/dist/render/browser/licenses.md +1 -1
  69. package/dist/render/browser/runtime.css +12 -10
  70. package/dist/render/browser/runtime.js +183 -49
  71. package/dist/render/node/index.js +85 -30
  72. package/dist/render/node/licenses.md +1 -1
  73. package/package.json +1 -1
  74. package/skills/open-flow/references/flow-authoring.md +14 -13
  75. package/src/base/common/jsonSchema.ts +11 -0
  76. package/src/connector/common/actionSchema.ts +4 -11
  77. package/src/connector/common/proxy.ts +152 -0
  78. package/src/control/common/api.ts +99 -3
  79. package/src/control/common/authoring.ts +23 -9
  80. package/src/control/common/authoringExamples.ts +9 -0
  81. package/src/control/common/authoringSchema.ts +21 -12
  82. package/src/control/common/catalogCache.ts +145 -0
  83. package/src/control/common/conformance.ts +9 -3
  84. package/src/control/common/connectorQueries.ts +17 -2
  85. package/src/control/common/requests.ts +1 -0
  86. package/src/control/common/workflowAuthoring.ts +120 -0
  87. package/src/execution/common/checkpoint.ts +18 -12
  88. package/src/execution/common/dependencies.ts +132 -15
  89. package/src/execution/common/events.ts +3 -0
  90. package/src/execution/common/node-execution.ts +22 -15
  91. package/src/execution/common/scheduler.ts +20 -31
  92. package/src/flow/common/change.ts +2 -1
  93. package/src/flow/common/changeSchema.ts +11 -1
  94. package/src/flow/common/connectionUsage.ts +4 -2
  95. package/src/flow/common/errorHandling.ts +3 -1
  96. package/src/flow/common/nodeChanges.ts +35 -18
  97. package/src/flow/common/requestParameters.ts +120 -0
  98. package/src/flow/common/semantics.ts +51 -1
  99. package/src/flow/common/sourceField.ts +3 -2
  100. package/src/flow/common/workflowFile.ts +2 -2
  101. package/src/http/common/httpRequest.ts +28 -78
  102. package/src/runtime/common/engineContract.ts +6 -3
@@ -26,7 +26,7 @@ function dequal(foo, bar) {
26
26
  return foo !== foo && bar !== bar;
27
27
  }
28
28
  //#endregion
29
- //#region ../../node_modules/.bun/zod@4.6.5/node_modules/zod/v4/core/util.js
29
+ //#region ../../node_modules/.bun/zod@4.6.7/node_modules/zod/v4/core/util.js
30
30
  function getEnumValues(entries) {
31
31
  const numericValues = Object.values(entries).filter((v) => typeof v === "number");
32
32
  return Object.entries(entries).filter(([k, _]) => numericValues.indexOf(+k) === -1).map(([_, v]) => v);
@@ -351,6 +351,17 @@ function prefixIssues(path, issues) {
351
351
  function unwrapMessage(message) {
352
352
  return typeof message === "string" ? message : message?.message;
353
353
  }
354
+ /** The leading size checks of `defChecks` that set an upper bound, each paired with it. */
355
+ function sizeCaps(defChecks) {
356
+ const caps = [];
357
+ for (const ch of defChecks ?? []) {
358
+ const d = ch._zod.def;
359
+ if (!/_(length|size)$|_equals$/.test(d.check)) break;
360
+ const max = d.maximum ?? d.length ?? d.size;
361
+ if (max >= 0) caps.push([max, ch]);
362
+ }
363
+ return caps;
364
+ }
354
365
  function attachSchema(issues, start, inst) {
355
366
  var _a;
356
367
  for (let i = start; i < issues.length; i++) (_a = issues[i]).schema ?? (_a.schema = inst);
@@ -567,7 +578,7 @@ function constantCatch(value) {
567
578
  return fn;
568
579
  }
569
580
  //#endregion
570
- //#region ../../node_modules/.bun/zod@4.6.5/node_modules/zod/v4/core/core.js
581
+ //#region ../../node_modules/.bun/zod@4.6.7/node_modules/zod/v4/core/core.js
571
582
  var _a$1;
572
583
  var _zodDesc = {
573
584
  value: void 0,
@@ -673,7 +684,7 @@ function config(newConfig) {
673
684
  return globalConfig;
674
685
  }
675
686
  //#endregion
676
- //#region ../../node_modules/.bun/zod@4.6.5/node_modules/zod/v4/core/errors.js
687
+ //#region ../../node_modules/.bun/zod@4.6.7/node_modules/zod/v4/core/errors.js
677
688
  function _getMessage() {
678
689
  const internals = this._zod;
679
690
  internals.message ?? (internals.message = JSON.stringify(internals.def, jsonStringifyReplacer, 2));
@@ -789,7 +800,7 @@ function formatError(error, mapper = (issue) => issue.message) {
789
800
  return fieldErrors;
790
801
  }
791
802
  //#endregion
792
- //#region ../../node_modules/.bun/zod@4.6.5/node_modules/zod/v4/core/parse.js
803
+ //#region ../../node_modules/.bun/zod@4.6.7/node_modules/zod/v4/core/parse.js
793
804
  function finalizeParams(callee, params) {
794
805
  return {
795
806
  callee: params?.callee ?? callee,
@@ -992,7 +1003,7 @@ var _safeDecodeAsync = (_Err) => async (schema, value, _ctx) => {
992
1003
  return _safeParseAsync(_Err)(schema, value, _ctx);
993
1004
  };
994
1005
  //#endregion
995
- //#region ../../node_modules/.bun/zod@4.6.5/node_modules/zod/v4/core/regexes.js
1006
+ //#region ../../node_modules/.bun/zod@4.6.7/node_modules/zod/v4/core/regexes.js
996
1007
  /**
997
1008
  * @deprecated CUID v1 is deprecated by its authors due to information leakage
998
1009
  * (timestamps embedded in the id). Use {@link cuid2} instead.
@@ -1065,7 +1076,7 @@ var _null$2 = /^null$/i;
1065
1076
  var lowercase = /^[^A-Z]*$/;
1066
1077
  var uppercase = /^[^a-z]*$/;
1067
1078
  //#endregion
1068
- //#region ../../node_modules/.bun/zod@4.6.5/node_modules/zod/v4/core/checks.js
1079
+ //#region ../../node_modules/.bun/zod@4.6.7/node_modules/zod/v4/core/checks.js
1069
1080
  var $ZodCheck = /*@__PURE__*/ $constructor("$ZodCheck", (inst, def) => {
1070
1081
  var _a;
1071
1082
  inst._zod ?? (inst._zod = {});
@@ -1361,7 +1372,7 @@ var $ZodCheckOverwrite = /*@__PURE__*/ $constructor("$ZodCheckOverwrite", (inst,
1361
1372
  };
1362
1373
  });
1363
1374
  //#endregion
1364
- //#region ../../node_modules/.bun/zod@4.6.5/node_modules/zod/v4/core/doc.js
1375
+ //#region ../../node_modules/.bun/zod@4.6.7/node_modules/zod/v4/core/doc.js
1365
1376
  var Doc = class {
1366
1377
  constructor(args = [], closed = {}) {
1367
1378
  this.content = [];
@@ -1395,14 +1406,14 @@ var Doc = class {
1395
1406
  }
1396
1407
  };
1397
1408
  //#endregion
1398
- //#region ../../node_modules/.bun/zod@4.6.5/node_modules/zod/v4/core/versions.js
1409
+ //#region ../../node_modules/.bun/zod@4.6.7/node_modules/zod/v4/core/versions.js
1399
1410
  var version = {
1400
1411
  major: 4,
1401
1412
  minor: 6,
1402
- patch: 5
1413
+ patch: 7
1403
1414
  };
1404
1415
  //#endregion
1405
- //#region ../../node_modules/.bun/zod@4.6.5/node_modules/zod/v4/core/schemas.js
1416
+ //#region ../../node_modules/.bun/zod@4.6.7/node_modules/zod/v4/core/schemas.js
1406
1417
  var $ZodType = /*@__PURE__*/ $constructor("$ZodType", (inst, def) => {
1407
1418
  var _a;
1408
1419
  inst ?? (inst = {});
@@ -1915,6 +1926,26 @@ var $ZodNever = /*@__PURE__*/ $constructor("$ZodNever", (inst, def) => {
1915
1926
  return payload;
1916
1927
  };
1917
1928
  });
1929
+ function capSize(inst, size) {
1930
+ const caps = sizeCaps(inst._zod.def.checks);
1931
+ if (!caps.length) return;
1932
+ const cap = Math.min(...caps.map((c) => c[0]));
1933
+ const parse = inst._zod.parse;
1934
+ inst._zod.parse = (payload, ctx) => {
1935
+ const n = size(payload.value);
1936
+ if (n > cap && !ctx?.skipChecks && ctx?.direction !== "backward") {
1937
+ for (const [max, ch] of sizeCaps(inst._zod.def.checks)) if (n > max && ch._zod.def.when(payload)) {
1938
+ const start = payload.issues.length;
1939
+ ch._zod.check(payload);
1940
+ payload.issues[start].continue = false;
1941
+ attachSchema(payload.issues, start, inst);
1942
+ return payload;
1943
+ }
1944
+ }
1945
+ return parse(payload, ctx);
1946
+ };
1947
+ }
1948
+ var arraySize = (input) => Array.isArray(input) ? input.length : -1;
1918
1949
  function handleArrayResult(result, final, index) {
1919
1950
  if (result.issues.length) final.issues.push(...prefixIssues(index, result.issues));
1920
1951
  final.value[index] = result.value;
@@ -1952,6 +1983,7 @@ var $ZodArray = /*@__PURE__*/ $constructor("$ZodArray", (inst, def) => {
1952
1983
  if (proms.length) return Promise.all(proms).then(() => payload);
1953
1984
  return payload;
1954
1985
  };
1986
+ capSize(inst, arraySize);
1955
1987
  });
1956
1988
  function handlePropertyResult(result, final, key, input, optin, optout) {
1957
1989
  const isPresent = key in input;
@@ -2870,7 +2902,7 @@ function handleRefineResult(result, payload, input, inst) {
2870
2902
  }
2871
2903
  }
2872
2904
  //#endregion
2873
- //#region ../../node_modules/.bun/zod@4.6.5/node_modules/zod/v4/core/memoizer.js
2905
+ //#region ../../node_modules/.bun/zod@4.6.7/node_modules/zod/v4/core/memoizer.js
2874
2906
  var $ZodCyclicError = class extends Error {
2875
2907
  constructor() {
2876
2908
  super(`Cannot parse a reference cycle that closes through a transform`);
@@ -3123,7 +3155,7 @@ function isBackEdge(ctx, value) {
3123
3155
  return backEdges !== void 0 && isRef(value) && backEdges.has(value);
3124
3156
  }
3125
3157
  //#endregion
3126
- //#region ../../node_modules/.bun/zod@4.6.5/node_modules/zod/v4/locales/en.js
3158
+ //#region ../../node_modules/.bun/zod@4.6.7/node_modules/zod/v4/locales/en.js
3127
3159
  var error = () => {
3128
3160
  const Sizable = {
3129
3161
  string: {
@@ -3231,7 +3263,7 @@ function en_default() {
3231
3263
  return { localeError: error() };
3232
3264
  }
3233
3265
  //#endregion
3234
- //#region ../../node_modules/.bun/zod@4.6.5/node_modules/zod/v4/core/registries.js
3266
+ //#region ../../node_modules/.bun/zod@4.6.7/node_modules/zod/v4/core/registries.js
3235
3267
  var _a;
3236
3268
  var $ZodRegistry = class {
3237
3269
  constructor() {
@@ -3278,7 +3310,7 @@ function registry() {
3278
3310
  (_a = globalThis).__zod_globalRegistry ?? (_a.__zod_globalRegistry = registry());
3279
3311
  var globalRegistry = globalThis.__zod_globalRegistry;
3280
3312
  //#endregion
3281
- //#region ../../node_modules/.bun/zod@4.6.5/node_modules/zod/v4/core/api.js
3313
+ //#region ../../node_modules/.bun/zod@4.6.7/node_modules/zod/v4/core/api.js
3282
3314
  function snapshotChecks(def) {
3283
3315
  if (def.checks) def.checks = [...def.checks];
3284
3316
  return def;
@@ -3794,7 +3826,7 @@ function _check(fn, params) {
3794
3826
  return ch;
3795
3827
  }
3796
3828
  //#endregion
3797
- //#region ../../node_modules/.bun/zod@4.6.5/node_modules/zod/v4/core/to-json-schema.js
3829
+ //#region ../../node_modules/.bun/zod@4.6.7/node_modules/zod/v4/core/to-json-schema.js
3798
3830
  function assignProps(target, ...sources) {
3799
3831
  for (const source of sources) for (const key of Reflect.ownKeys(source)) if (Object.prototype.propertyIsEnumerable.call(source, key)) assignProp(target, key, source[key]);
3800
3832
  return target;
@@ -4238,7 +4270,7 @@ var createStandardJSONSchemaMethod = (schema, io, processors = {}) => (params) =
4238
4270
  return finalize(ctx, schema);
4239
4271
  };
4240
4272
  //#endregion
4241
- //#region ../../node_modules/.bun/zod@4.6.5/node_modules/zod/v4/core/json-schema-processors.js
4273
+ //#region ../../node_modules/.bun/zod@4.6.7/node_modules/zod/v4/core/json-schema-processors.js
4242
4274
  var narrowMin = (agg, key, value) => {
4243
4275
  if (agg[key] === void 0 || value > agg[key]) agg[key] = value;
4244
4276
  };
@@ -4699,7 +4731,7 @@ var lazyProcessor = (schema, ctx, _json, params) => {
4699
4731
  seen.ref = innerType;
4700
4732
  };
4701
4733
  //#endregion
4702
- //#region ../../node_modules/.bun/zod@4.6.5/node_modules/zod/v4/classic/errors.js
4734
+ //#region ../../node_modules/.bun/zod@4.6.7/node_modules/zod/v4/classic/errors.js
4703
4735
  var _installedErrorProtos = /* @__PURE__ */ new WeakSet([Object.prototype, Error.prototype]);
4704
4736
  function _lazyMethod(proto, key, make) {
4705
4737
  Object.defineProperty(proto, key, {
@@ -4749,7 +4781,7 @@ var initializer = (inst, issues) => {
4749
4781
  };
4750
4782
  var ZodRealError = /*@__PURE__*/ $constructor("ZodError", initializer, void 0, { Parent: Error });
4751
4783
  //#endregion
4752
- //#region ../../node_modules/.bun/zod@4.6.5/node_modules/zod/v4/classic/parse.js
4784
+ //#region ../../node_modules/.bun/zod@4.6.7/node_modules/zod/v4/classic/parse.js
4753
4785
  var parse = /* @__PURE__ */ _parse(ZodRealError);
4754
4786
  var parseAsync = /* @__PURE__ */ _parseAsync(ZodRealError);
4755
4787
  var safeParse = /* @__PURE__ */ _safeParse(ZodRealError);
@@ -4763,7 +4795,7 @@ var safeDecode = /* @__PURE__ */ _safeDecode(ZodRealError);
4763
4795
  var safeEncodeAsync = /* @__PURE__ */ _safeEncodeAsync(ZodRealError);
4764
4796
  var safeDecodeAsync = /* @__PURE__ */ _safeDecodeAsync(ZodRealError);
4765
4797
  //#endregion
4766
- //#region ../../node_modules/.bun/zod@4.6.5/node_modules/zod/v4/classic/schemas.js
4798
+ //#region ../../node_modules/.bun/zod@4.6.7/node_modules/zod/v4/classic/schemas.js
4767
4799
  function _ensureDefaultLocale() {
4768
4800
  if (!globalConfig.localeError) config(en_default());
4769
4801
  }
@@ -5695,7 +5727,7 @@ function preprocess(fn, schema) {
5695
5727
  });
5696
5728
  }
5697
5729
  //#endregion
5698
- //#region ../../node_modules/.bun/zod@4.6.5/node_modules/zod/v4/classic/iso.js
5730
+ //#region ../../node_modules/.bun/zod@4.6.7/node_modules/zod/v4/classic/iso.js
5699
5731
  function datetime(params) {
5700
5732
  return /* @__PURE__ */ _isoDateTime(ZodISODateTime, params);
5701
5733
  }
@@ -8456,6 +8488,32 @@ function createSchemaComparer() {
8456
8488
  }
8457
8489
  createSchemaComparer();
8458
8490
  //#endregion
8491
+ //#region src/flow/common/requestParameters.ts
8492
+ var requestParameterSchema = strictObject({
8493
+ mode: _enum(["fields", "object"]).default("fields"),
8494
+ names: array(string()).default([])
8495
+ });
8496
+ var connectorProxyExecutorSchema = strictObject({
8497
+ providerId: string().min(1),
8498
+ connectionId: string().optional(),
8499
+ method: _enum([
8500
+ "GET",
8501
+ "POST",
8502
+ "PUT",
8503
+ "PATCH",
8504
+ "DELETE"
8505
+ ]).default("GET"),
8506
+ query: requestParameterSchema.default({
8507
+ mode: "fields",
8508
+ names: []
8509
+ }),
8510
+ headers: requestParameterSchema.default({
8511
+ mode: "fields",
8512
+ names: []
8513
+ }),
8514
+ bodyFormat: _enum(["none", "json"]).default("none")
8515
+ }).extend({ kind: literal("connector-proxy") });
8516
+ //#endregion
8459
8517
  //#region src/decision/common/decision.ts
8460
8518
  function isDecisionExecutor(executor) {
8461
8519
  return executor.kind === "decision";
@@ -8562,12 +8620,6 @@ var httpHostPattern = /^(?:\*\.)?(?=.{1,253}$)(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0
8562
8620
  function isHttpHost(value) {
8563
8621
  return httpHostPattern.test(value) && (!value.startsWith("*.") || value.slice(2).includes("."));
8564
8622
  }
8565
- //#endregion
8566
- //#region src/http/common/httpRequest.ts
8567
- var parameterSchema = strictObject({
8568
- mode: _enum(["fields", "object"]).default("fields"),
8569
- names: array(string()).default([])
8570
- });
8571
8623
  var httpRequestExecutorSchema = strictObject({
8572
8624
  method: _enum([
8573
8625
  "GET",
@@ -8578,11 +8630,11 @@ var httpRequestExecutorSchema = strictObject({
8578
8630
  "HEAD",
8579
8631
  "OPTIONS"
8580
8632
  ]).default("GET"),
8581
- query: parameterSchema.default({
8633
+ query: requestParameterSchema.default({
8582
8634
  mode: "fields",
8583
8635
  names: []
8584
8636
  }),
8585
- headers: parameterSchema.default({
8637
+ headers: requestParameterSchema.default({
8586
8638
  mode: "fields",
8587
8639
  names: []
8588
8640
  }),
@@ -8954,7 +9006,8 @@ var managedFields = object({
8954
9006
  revisionId: text
8955
9007
  }),
8956
9008
  httpRequestExecutorSchema,
8957
- skipDuplicatesExecutorSchema
9009
+ skipDuplicatesExecutorSchema,
9010
+ connectorProxyExecutorSchema
8958
9011
  ])
8959
9012
  });
8960
9013
  var managed = managedFields.transform(limitDecisionTask);
@@ -9209,7 +9262,8 @@ var revision = object({
9209
9262
  literal(10),
9210
9263
  literal(11),
9211
9264
  literal(12),
9212
- literal(13)
9265
+ literal(13),
9266
+ literal(14)
9213
9267
  ]),
9214
9268
  document,
9215
9269
  modules: record$1(text, module)
@@ -9410,6 +9464,7 @@ array(union([...new Map(Object.entries(shapes).map(([kind, shape]) => [kind, sha
9410
9464
  ...shape
9411
9465
  })])).values()])).min(1);
9412
9466
  function checkModelVersion(content) {
9467
+ if (content.modelVersion < 14 && Object.values(content.document.graph.nodes).some((candidateNode) => candidateNode.kind === "task" && "executor" in candidateNode.task && candidateNode.task.executor.kind === "connector-proxy")) throw new TypeError("Custom API Request requires Flow model v14.");
9413
9468
  if (content.modelVersion < 13 && Object.values(content.document.graph.nodes).some((candidateNode) => candidateNode.kind === "task" && "executor" in candidateNode.task && candidateNode.task.executor.kind === "skip-duplicates")) throw new Error("Skip Duplicates requires Flow model v13.");
9414
9469
  if (content.modelVersion < 12 && Object.values(content.document.graph.nodes).some((candidateNode) => candidateNode.kind == "task" && "moduleId" in candidateNode.task && candidateNode.task.capabilities?.some((item) => item.kind == "http"))) throw new TypeError("Code HTTP access requires Flow model version 12.");
9415
9470
  if (content.modelVersion < 11 && Object.values(content.document.graph.nodes).some((candidateNode) => candidateNode.kind == "task" && "executor" in candidateNode.task && candidateNode.task.executor.kind == "http-request")) throw new TypeError("HTTP Request requires Flow model version 11.");
@@ -50,7 +50,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
50
50
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
51
51
  THE SOFTWARE.
52
52
 
53
- ## zod - 4.6.5 (MIT)
53
+ ## zod - 4.6.7 (MIT)
54
54
 
55
55
  MIT License
56
56
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oomol-lab/open-flow",
3
- "version": "0.1.0-beta.85",
3
+ "version": "0.1.0-beta.87",
4
4
  "description": "TypeScript contracts and Browser runtime for Open Flow.",
5
5
  "license": "SEE LICENSE IN LICENSE",
6
6
  "repository": {
@@ -289,19 +289,20 @@ unavailable action and an action lacking an active Connection are different
289
289
  problems. Actions marked `authenticated: false` need no account. Connection
290
290
  selection rules come from the selected node contract.
291
291
 
292
- For Connector Tasks, independent Code Actions, Agent tools and notifications, an omitted `connectionId` means unconfigured; `connectionId: ""` explicitly defers account configuration. Deferred selections pass account readiness checks but fail with `connector.connection-required` if invoked. Deferred Agent tools are excluded from the callable tool set. Provider Triggers still require a nonempty account ID. Public edits and portable exports preserve the empty string; clear the field to return to the unconfigured state.
293
-
294
- | Capability | Relevant schema and configuration |
295
- | ------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
296
- | Provider read or write | `connector`: discovered `action`, optional `connectionId`, named input bindings. |
297
- | Provider event | `poll` or `integration`: discovered `key`, Connection and any static inputs; polling also has a schedule. |
298
- | Manual, HTTP or scheduled entry | `start`, `webhook`, `cron`: workflow `inputDefs`, HTTP body fields, or schedule. |
299
- | Workflow failure handler | `error`: published upstream Flows' automatic Run failures; not a node-level catch or a handler for manual Run failures. |
300
- | Call another workflow | `workflow`: select an owned published Flow ID; inputs and outputs derive from its saved contract. Use `node.refresh` to update it. |
301
- | Single HTTP request | `http-request`: method, parameter modes, authentication, body and response configuration; URL and request values use public inputs. |
302
- | Fixed HTTP operation | `openapi`: an OpenAPI source, path and method; resolved authentication choices and ports appear in node details. |
303
- | Reusable constants | `value`: named JSON values and optional output constraints. |
304
- | Durable interaction | `wait`, `approval`: prompt and named inputs; resume through the Run's Wait ID. Wait additionally supports optional `config.autoContinue` with `{kind:"after",durationMs:86400000}` or `{kind:"at",at:"2026-10-25T10:00:00+08:00"}`. |
292
+ For Connector Tasks, Provider API requests, independent Code Actions, Agent tools and notifications, an omitted `connectionId` means unconfigured; `connectionId: ""` explicitly defers account configuration. Deferred selections pass account readiness checks but fail with `connector.connection-required` if invoked. Deferred Agent tools are excluded from the callable tool set. Provider Triggers still require a nonempty account ID. Public edits and portable exports preserve the empty string; clear the field to return to the unconfigured state.
293
+
294
+ | Capability | Relevant schema and configuration |
295
+ | ------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
296
+ | Provider read or write | `connector`: discovered `action`, optional `connectionId`, named input bindings. |
297
+ | Unlisted Provider API | `connector-proxy`: `providerId`, optional `connectionId`, method, Query/Header modes and none/JSON body. Bind required `endpoint` and request data through inputs. Query accepts scalar values without arrays. Outputs are complete `body`, `statusCode`, `headers` and nullable `bodyEncoding`. Upstream 4xx/5xx remains output; Proxy permission is independent of Action grants. |
298
+ | Provider event | `poll` or `integration`: discovered `key`, Connection and any static inputs; polling also has a schedule. |
299
+ | Manual, HTTP or scheduled entry | `start`, `webhook`, `cron`: workflow `inputDefs`, HTTP body fields, or schedule. |
300
+ | Workflow failure handler | `error`: published upstream Flows' automatic Run failures; not a node-level catch or a handler for manual Run failures. |
301
+ | Call another workflow | `workflow`: select an owned published Flow ID; inputs and outputs derive from its saved contract. Use `node.refresh` to update it. |
302
+ | Single HTTP request | `http-request`: method, parameter modes, authentication, body and response configuration; URL and request values use public inputs. |
303
+ | Fixed HTTP operation | `openapi`: an OpenAPI source, path and method; resolved authentication choices and ports appear in node details. |
304
+ | Reusable constants | `value`: named JSON values and optional output constraints. |
305
+ | Durable interaction | `wait`, `approval`: prompt and named inputs; resume through the Run's Wait ID. Wait additionally supports optional `config.autoContinue` with `{kind:"after",durationMs:86400000}` or `{kind:"at",at:"2026-10-25T10:00:00+08:00"}`. |
305
306
 
306
307
  Connector and LLM services are configured on the Server. Missing capabilities
307
308
  should be described in terms of the required operation or event, without silently
@@ -0,0 +1,11 @@
1
+ import { toPlainObject } from '@wopjs/cast'
2
+
3
+ /** Keep local definition references usable when a property becomes a standalone schema. */
4
+ export function propertySchemaWithDefinitions(root: Readonly<Record<string, unknown>>, schema: unknown): unknown {
5
+ const property = toPlainObject(schema)
6
+ if (property == null) return schema
7
+ const result: Record<string, unknown> = Object.assign({}, property)
8
+ if (result.$defs == null && root.$defs != null) result.$defs = root.$defs
9
+ if (result.definitions == null && root.definitions != null) result.definitions = root.definitions
10
+ return result
11
+ }
@@ -1,4 +1,5 @@
1
1
  import { toPlainObject } from '@wopjs/cast'
2
+ import { propertySchemaWithDefinitions } from '../../base/common/jsonSchema.ts'
2
3
 
3
4
  export interface ConnectorActionPorts {
4
5
  readonly inputs: readonly {
@@ -69,8 +70,9 @@ function inputPorts(schema: unknown): ConnectorActionPorts['inputs'] {
69
70
 
70
71
  export function connectorOutputMode(schema: unknown): 'fields' | 'value' {
71
72
  const root = toPlainObject(schema)
72
- const properties = toPlainObject(root?.properties)
73
- return (properties != null && Object.keys(properties).length > 0) || (root?.type == 'object' && root.additionalProperties === false) ? 'fields' : 'value'
73
+ const patterns = toPlainObject(root?.patternProperties)
74
+ // Only closed objects without dynamic keys can be represented completely by named ports.
75
+ return root?.type == 'object' && root.additionalProperties === false && (patterns == null || Object.keys(patterns).length == 0) ? 'fields' : 'value'
74
76
  }
75
77
 
76
78
  function outputPorts(schema: unknown): ConnectorActionPorts['outputs'] {
@@ -88,15 +90,6 @@ function outputPorts(schema: unknown): ConnectorActionPorts['outputs'] {
88
90
  }))
89
91
  }
90
92
 
91
- function propertySchemaWithDefinitions(root: Record<string, unknown>, schema: unknown): unknown {
92
- const property = toPlainObject(schema)
93
- if (property == null) return schema
94
- const result: Record<string, unknown> = Object.assign({}, property)
95
- if (result.$defs == null && root.$defs != null) result.$defs = root.$defs
96
- if (result.definitions == null && root.definitions != null) result.definitions = root.definitions
97
- return result
98
- }
99
-
100
93
  function schemaDescription(root: unknown, schema: unknown): string | undefined {
101
94
  for (const object of referencedSchemas(root, schema)) {
102
95
  if (typeof object.description == 'string') return object.description
@@ -1,5 +1,19 @@
1
1
  import type { SourceOperation, SourceReferenceOperation } from '../../event-source/common/definition.ts'
2
+ import type { InputMapping, InputPort, ManagedTaskDefinitionOf, TaskDefinitionBase } from '../../flow/common/model.ts'
3
+ import type { RequestTaskNode } from '../../flow/common/requestParameters.ts'
2
4
  import type { JsonValue } from '../../types/index.ts'
5
+
6
+ import { z } from 'zod'
7
+ import {
8
+ requestParameterSchema,
9
+ requestParameterHandle,
10
+ requestParameterIssues,
11
+ requestParameterPorts,
12
+ requestInputMappings,
13
+ retainRequestPorts,
14
+ withRequestParameterFields,
15
+ withRequestParameterSource,
16
+ } from '../../flow/common/requestParameters.ts'
3
17
  export type TriggerOperationRequest =
4
18
  | { readonly operation: 'sourceReference'; readonly request: SourceReferenceOperation }
5
19
  | { readonly operation: 'source'; readonly request: SourceOperation }
@@ -36,9 +50,147 @@ export interface ConnectorProxyRequest {
36
50
  export interface ConnectorProxyResult {
37
51
  readonly data: unknown
38
52
  readonly status: number
53
+ readonly headers?: Readonly<Record<string, string>>
54
+ readonly bodyEncoding?: 'base64'
39
55
  }
40
56
 
41
57
  export interface ConnectorProxy {
42
58
  trigger?(request: TriggerOperationRequest, signal?: AbortSignal): Promise<unknown>
43
59
  execute(request: ConnectorProxyRequest, signal?: AbortSignal): Promise<ConnectorProxyResult>
44
60
  }
61
+
62
+ export const connectorProxyConfigSchema = z.strictObject({
63
+ providerId: z.string().min(1),
64
+ connectionId: z.string().optional(),
65
+ method: z.enum(['GET', 'POST', 'PUT', 'PATCH', 'DELETE']).default('GET'),
66
+ query: requestParameterSchema.default({ mode: 'fields', names: [] }),
67
+ headers: requestParameterSchema.default({ mode: 'fields', names: [] }),
68
+ bodyFormat: z.enum(['none', 'json']).default('none'),
69
+ })
70
+ export type ConnectorProxyConfig = z.infer<typeof connectorProxyConfigSchema>
71
+ export interface ConnectorProxyExecutor extends ConnectorProxyConfig {
72
+ readonly kind: 'connector-proxy'
73
+ }
74
+ export const connectorProxyExecutorSchema = connectorProxyConfigSchema.extend({ kind: z.literal('connector-proxy') })
75
+ export const connectorProxyQueryValueSchema = { type: ['string', 'number', 'boolean', 'null'] }
76
+ export const connectorProxyQuerySchema = { type: 'object', additionalProperties: connectorProxyQueryValueSchema }
77
+ export const connectorProxyHeaderSchema = { type: 'object', additionalProperties: { type: 'string' } }
78
+ export const connectorProxyBodyInput: InputPort = { handle: 'body', jsonSchema: {}, nullable: true }
79
+
80
+ export function connectorProxySupportsBody(method: ConnectorProxyRequest['method']): boolean {
81
+ return method !== 'GET'
82
+ }
83
+
84
+ export function connectorProxyHasBody(mapping: InputMapping | undefined, defaultValue?: JsonValue): boolean {
85
+ if (mapping?.kind === 'unset') return false
86
+ return mapping == null ? defaultValue !== undefined : mapping.kind === 'value' || mapping.sources.length > 0
87
+ }
88
+
89
+ export function connectorProxyTask(
90
+ config: ConnectorProxyConfig,
91
+ name = 'Custom API Request',
92
+ previous?: TaskDefinitionBase,
93
+ ): ManagedTaskDefinitionOf<ConnectorProxyExecutor> {
94
+ const { connectionId, ...settings } = config
95
+ const inputs: InputPort[] = [
96
+ { handle: 'endpoint', jsonSchema: { type: 'string' }, nullable: false },
97
+ ...requestParameterPorts(config, connectorProxyQuerySchema, connectorProxyQueryValueSchema, connectorProxyHeaderSchema),
98
+ ...(config.bodyFormat === 'none' ? [] : [connectorProxyBodyInput]),
99
+ ]
100
+ const outputs: InputPort[] = [
101
+ { handle: 'body', jsonSchema: {}, nullable: true },
102
+ { handle: 'statusCode', jsonSchema: { type: 'integer' }, nullable: false },
103
+ { handle: 'headers', jsonSchema: connectorProxyHeaderSchema, nullable: false },
104
+ { handle: 'bodyEncoding', jsonSchema: { const: 'base64' }, nullable: true },
105
+ ]
106
+ return {
107
+ name,
108
+ executor: { ...settings, ...(connectionId === undefined ? {} : { connectionId }), kind: 'connector-proxy' },
109
+ inputs: retainRequestPorts(inputs, previous?.inputs),
110
+ outputs: retainRequestPorts(outputs, previous?.outputs),
111
+ }
112
+ }
113
+
114
+ export function connectorProxyInputs(
115
+ mappings: Readonly<Record<string, InputMapping>>,
116
+ previous: RequestTaskNode['task'],
117
+ next: RequestTaskNode['task'],
118
+ ): Record<string, InputMapping> {
119
+ const inputs = requestInputMappings(mappings, previous, next)
120
+ const before = previous.executor?.kind === 'connector-proxy' ? (previous.executor as ConnectorProxyExecutor) : undefined
121
+ const after = next.executor?.kind === 'connector-proxy' ? (next.executor as ConnectorProxyExecutor) : undefined
122
+ if (before != null && after != null && connectorProxySupportsBody(before.method) && !connectorProxySupportsBody(after.method)) {
123
+ const bodyPort = next.inputs.find((port): port is InputPort => 'handle' in port && port.handle === 'body')
124
+ if (connectorProxyHasBody(inputs.body, bodyPort?.value)) inputs.body = { kind: 'unset' }
125
+ }
126
+ return inputs
127
+ }
128
+
129
+ export function connectorProxyIssues(config: ConnectorProxyConfig, hasBody = config.bodyFormat !== 'none') {
130
+ return [
131
+ ...requestParameterIssues(config),
132
+ ...(!connectorProxySupportsBody(config.method) && hasBody
133
+ ? [{ field: 'bodyFormat' as const, code: 'bodyUnsupported' as const, message: 'GET does not support a request body.' }]
134
+ : []),
135
+ ]
136
+ }
137
+
138
+ export function buildConnectorProxyRequest(
139
+ config: ConnectorProxyConfig,
140
+ input: Readonly<Record<string, JsonValue>>,
141
+ mappings?: Readonly<Record<string, InputMapping>>,
142
+ bodyDefault?: JsonValue,
143
+ ): ConnectorProxyRequest {
144
+ const hasBody = mappings == null ? input.body !== undefined : connectorProxyHasBody(mappings.body, bodyDefault)
145
+ if (connectorProxyIssues(config, hasBody).length > 0) throw new Error('Invalid Provider API request configuration.')
146
+ const endpoint = input.endpoint
147
+ if (typeof endpoint !== 'string' || !endpoint.trim()) throw new Error('An endpoint is required.')
148
+ const parameters = (group: 'query' | 'headers'): Record<string, JsonValue> => {
149
+ if (config[group].mode === 'object') {
150
+ const value = input[group]
151
+ if (value == null) return {}
152
+ if (typeof value !== 'object' || Array.isArray(value)) throw new Error('Expected a parameter object.')
153
+ return { ...(value as Readonly<Record<string, JsonValue>>) }
154
+ }
155
+ return Object.fromEntries(
156
+ config[group].names.flatMap((name) => {
157
+ const handle = requestParameterHandle(group, name)
158
+ if (mappings != null && (mappings[handle] == null || mappings[handle]?.kind === 'unset')) return []
159
+ const value = input[handle]
160
+ return value === undefined || (group === 'headers' && value === null) ? [] : [[name, value]]
161
+ }),
162
+ )
163
+ }
164
+ const query = parameters('query')
165
+ const headers = parameters('headers')
166
+ if (Object.values(query).some((value) => value !== null && !['string', 'number', 'boolean'].includes(typeof value)))
167
+ throw new Error('Query parameters require scalar values.')
168
+ if (Object.values(headers).some((value) => typeof value !== 'string')) throw new Error('Headers require text values.')
169
+ return {
170
+ endpoint,
171
+ method: config.method,
172
+ query: query as NonNullable<ConnectorProxyRequest['query']>,
173
+ headers: headers as Readonly<Record<string, string>>,
174
+ ...(hasBody ? { body: input.body ?? null } : {}),
175
+ }
176
+ }
177
+
178
+ export function withConnectorProxyParameterFields<Node extends RequestTaskNode>(
179
+ node: Node,
180
+ group: 'query' | 'headers',
181
+ values: Record<string, JsonValue>,
182
+ ): Node {
183
+ const executor = node.task.executor
184
+ if (executor?.kind !== 'connector-proxy') return node
185
+ const config = executor as ConnectorProxyExecutor
186
+ return withRequestParameterFields(node, group, values, config[group], (parameters) =>
187
+ connectorProxyTask({ ...config, [group]: parameters }, node.task.name, node.task),
188
+ )
189
+ }
190
+
191
+ export function withConnectorProxyParameterSource<Node extends RequestTaskNode>(node: Node, group: 'query' | 'headers', mapping?: InputMapping): Node {
192
+ const executor = node.task.executor
193
+ if (executor?.kind !== 'connector-proxy') return node
194
+ const config = executor as ConnectorProxyExecutor
195
+ return withRequestParameterSource(node, group, mapping, (parameters) => connectorProxyTask({ ...config, [group]: parameters }, node.task.name, node.task))
196
+ }