@oomol-lab/open-flow 0.1.0-beta.72 → 0.1.0-beta.74
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +36 -0
- package/NOTICE +7 -0
- package/README.md +40 -0
- package/dist/browser/{createResourceDialog-BWJkjiOO.js → createResourceDialog-DI9pL-Yr.js} +2 -2
- package/dist/browser/{dialog-CUy_fwx9.js → dialog-BYJGvItc.js} +54 -19
- package/dist/browser/{flowChanges-CgSnSqqP.js → flowChanges-RL-H4CjD.js} +306 -48
- package/dist/browser/{flowWorkspace-Bf7H-r0t.js → flowWorkspace-BkDsETj0.js} +20745 -20186
- package/dist/browser/preview.css +73 -3
- package/dist/browser/preview.js +21410 -20607
- package/dist/browser/{typeScriptSession-B0hC-C8y.js → typeScriptSession-CSRwWmZm.js} +1 -1
- package/dist/browser/ui.css +72 -2
- package/dist/browser/workbench.css +73 -3
- package/dist/browser/workbench.js +14 -76
- package/dist/browser/{workbenchSelect-C3e4J93X.js → workbenchSelect-BcWPWGzw.js} +1 -1
- package/dist/command/index.js +34 -34
- package/dist/common/authoring.d.ts +1 -1
- package/dist/common/authoringFields.d.ts +1 -1
- package/dist/common/authoringSchema.d.ts +28 -4
- package/dist/common/connector-proxy.d.ts +1 -1
- package/dist/common/control-api-conformance.d.ts +1 -1
- package/dist/common/control-api-conformance.js +61 -24
- package/dist/common/control-api.d.ts +4 -3
- package/dist/common/control-api.js +90 -42
- package/dist/common/control-requests.d.ts +2 -1
- package/dist/common/control-requests.js +204 -42
- package/dist/common/cron-trigger.d.ts +1 -1
- package/dist/common/decision.d.ts +1 -1
- package/dist/common/draftOperations.d.ts +1 -1
- package/dist/common/engine-contract.d.ts +3 -2
- package/dist/common/event-source-definition.d.ts +1 -1
- package/dist/common/flow-agent.d.ts +1 -1
- package/dist/{browser → common}/flow-authoring-node.d.ts +3 -3
- package/dist/{browser → common}/flow-authoring.js +75 -23
- package/dist/{browser → common}/flow-change-schema.d.ts +177 -6
- package/dist/{browser → common}/flow-change.d.ts +35 -15
- package/dist/{browser → common}/flow-change.js +77 -25
- package/dist/common/flow-connectionUsage.d.ts +1 -1
- package/dist/common/flow-encoding.d.ts +1 -1
- package/dist/common/flow-encoding.js +34 -16
- package/dist/common/flow-errorHandling.d.ts +1 -1
- package/dist/common/flow-graph.d.ts +1 -1
- package/dist/common/flow-modules.d.ts +1 -1
- package/dist/common/flow-promptTemplate.d.ts +1 -1
- package/dist/common/flow-retry.d.ts +1 -1
- package/dist/common/flow-semantics.d.ts +1 -1
- package/dist/common/flow-semantics.js +151 -32
- package/dist/common/flow-workflowFile.d.ts +1 -1
- package/dist/common/flowInspection.d.ts +3 -3
- package/dist/common/integration-trigger.d.ts +1 -1
- package/dist/common/licenses.md +118 -1
- package/dist/common/liveDetails.d.ts +1 -1
- package/dist/common/mcp.d.ts +2 -1
- package/dist/common/mcp.js +59 -22
- package/dist/common/openapi.d.ts +1 -1
- package/dist/common/poll-trigger.d.ts +1 -1
- package/dist/common/run-results.d.ts +8 -1
- package/dist/common/runtime-contract.d.ts +8 -2
- package/dist/common/runtime-contract.js +22 -5
- package/dist/common/scheduler-checkpoint.d.ts +1 -1
- package/dist/common/scheduler-dependencies.d.ts +1 -1
- package/dist/common/scheduler-node-execution.d.ts +1 -1
- package/dist/common/scheduler.d.ts +2 -2
- package/dist/common/scheduler.js +31 -12
- package/dist/common/trigger-catalog.d.ts +1 -1
- package/dist/common/trigger-config-options.d.ts +1 -1
- package/dist/common/trigger-config.d.ts +1 -1
- package/dist/common/trigger-contract.d.ts +2 -2
- package/dist/common/trigger-localization.d.ts +1 -1
- package/dist/common/webhook-response.d.ts +1 -1
- package/dist/common/webhook-trigger.d.ts +1 -1
- package/dist/common/workflow.d.ts +17 -1
- package/dist/common/workflow.js +68 -22
- package/dist/index.d.ts +6 -3
- package/package.json +7 -6
- package/src/base/common/json.ts +90 -0
- package/src/canvas/common/commands.ts +15 -0
- package/src/connector/common/actionSchema.ts +168 -0
- package/src/connector/common/proxy.ts +44 -0
- package/src/control/common/api.ts +1505 -0
- package/src/control/common/authoring.ts +912 -0
- package/src/control/common/authoringCondition.ts +110 -0
- package/src/control/common/authoringDiagnosticFields.ts +136 -0
- package/src/control/common/authoringExamples.ts +192 -0
- package/src/control/common/authoringFields.ts +53 -0
- package/src/control/common/authoringLlm.ts +70 -0
- package/src/control/common/authoringOpenApi.ts +129 -0
- package/src/control/common/authoringSchema.ts +404 -0
- package/src/control/common/authoringTools.ts +123 -0
- package/src/control/common/authoringTriggers.ts +26 -0
- package/src/control/common/checkDecoders.ts +65 -0
- package/src/control/common/conformance.ts +1989 -0
- package/src/control/common/connectorDecoders.ts +370 -0
- package/src/control/common/connectorQueries.ts +61 -0
- package/src/control/common/decoding.ts +60 -0
- package/src/control/common/draftOperations.ts +61 -0
- package/src/control/common/errors.ts +114 -0
- package/src/control/common/eventSourceSchemas.ts +13 -0
- package/src/control/common/eventSources.ts +186 -0
- package/src/control/common/flowDecoders.ts +153 -0
- package/src/control/common/flowInspection.ts +181 -0
- package/src/control/common/flowNotifications.ts +37 -0
- package/src/control/common/liveDetails.ts +124 -0
- package/src/control/common/mcp.ts +241 -0
- package/src/control/common/mcpConformance.ts +142 -0
- package/src/control/common/providerAccess.ts +28 -0
- package/src/control/common/providerIconSprite.ts +42 -0
- package/src/control/common/publicationDecoders.ts +98 -0
- package/src/control/common/random.ts +16 -0
- package/src/control/common/requests.ts +112 -0
- package/src/control/common/resultQuery.ts +8 -0
- package/src/control/common/results.ts +176 -0
- package/src/control/common/revisionDecoders.ts +52 -0
- package/src/control/common/runDecoders.ts +240 -0
- package/src/control/common/triggerCatalog.ts +89 -0
- package/src/control/common/triggerDecoders.ts +175 -0
- package/src/decision/common/decision.ts +168 -0
- package/src/event-source/common/catalog.generated.json +65 -0
- package/src/event-source/common/definition.ts +66 -0
- package/src/event-source/common/index.ts +99 -0
- package/src/execution/common/checkpoint.ts +311 -0
- package/src/execution/common/dependencies.ts +440 -0
- package/src/execution/common/engineContract.ts +80 -0
- package/src/execution/common/events.ts +328 -0
- package/src/execution/common/node-execution.ts +467 -0
- package/src/execution/common/runLifecycle.ts +250 -0
- package/src/execution/common/runtime.ts +563 -0
- package/src/execution/common/scheduler.ts +696 -0
- package/src/execution/common/wait.ts +36 -0
- package/src/flow/common/agent.ts +305 -0
- package/src/flow/common/authoring.ts +30 -0
- package/src/flow/common/change.ts +1036 -0
- package/src/flow/common/changeSchema.ts +783 -0
- package/src/flow/common/codePermissions.ts +2 -0
- package/src/flow/common/condition.ts +265 -0
- package/src/flow/common/connectionUsage.ts +131 -0
- package/src/flow/common/edgeChanges.ts +35 -0
- package/src/flow/common/encoding.ts +437 -0
- package/src/flow/common/errorHandling.ts +34 -0
- package/src/flow/common/graph.ts +892 -0
- package/src/flow/common/inputValue.ts +16 -0
- package/src/flow/common/json.ts +8 -0
- package/src/flow/common/moduleChanges.ts +31 -0
- package/src/flow/common/modules.ts +292 -0
- package/src/flow/common/nodeChanges.ts +762 -0
- package/src/flow/common/portChanges.ts +36 -0
- package/src/flow/common/promptTemplate.ts +15 -0
- package/src/flow/common/retry.ts +20 -0
- package/src/flow/common/schema.ts +162 -0
- package/src/flow/common/schemaCompare.ts +176 -0
- package/src/flow/common/schemaComparer.ts +178 -0
- package/src/flow/common/schemaKeywords.ts +53 -0
- package/src/flow/common/semantics.ts +474 -0
- package/src/flow/common/sourceField.ts +35 -0
- package/src/flow/common/triggerScheduleSchema.ts +8 -0
- package/src/flow/common/wait.ts +30 -0
- package/src/flow/common/webhookMethod.ts +7 -0
- package/src/flow/common/webhookResponse.ts +75 -0
- package/src/flow/common/workflowFile.ts +97 -0
- package/src/json-schema-subset/checker/array.ts +142 -0
- package/src/json-schema-subset/checker/cache.ts +57 -0
- package/src/json-schema-subset/checker/checker.ts +230 -0
- package/src/json-schema-subset/checker/enumAndConst.ts +113 -0
- package/src/json-schema-subset/checker/equals.ts +93 -0
- package/src/json-schema-subset/checker/numeric/checker.ts +50 -0
- package/src/json-schema-subset/checker/numeric/float.ts +121 -0
- package/src/json-schema-subset/checker/numeric/index.ts +1 -0
- package/src/json-schema-subset/checker/numeric/integer.ts +119 -0
- package/src/json-schema-subset/checker/numeric/integerNormalizer.ts +72 -0
- package/src/json-schema-subset/checker/object.ts +354 -0
- package/src/json-schema-subset/checker/range.ts +91 -0
- package/src/json-schema-subset/checker/string.ts +60 -0
- package/src/json-schema-subset/checker/tools/index.ts +3 -0
- package/src/json-schema-subset/checker/tools/mark.ts +82 -0
- package/src/json-schema-subset/checker/tools/quantum.ts +106 -0
- package/src/json-schema-subset/checker/tools/range.ts +210 -0
- package/src/json-schema-subset/checker/validator.ts +23 -0
- package/src/json-schema-subset/compiler/array.ts +163 -0
- package/src/json-schema-subset/compiler/combination.ts +109 -0
- package/src/json-schema-subset/compiler/common.ts +99 -0
- package/src/json-schema-subset/compiler/compiler.ts +188 -0
- package/src/json-schema-subset/compiler/enumAndConst.ts +75 -0
- package/src/json-schema-subset/compiler/index.ts +11 -0
- package/src/json-schema-subset/compiler/object.ts +411 -0
- package/src/json-schema-subset/compiler/primitive.ts +144 -0
- package/src/json-schema-subset/compiler/utils.ts +24 -0
- package/src/json-schema-subset/compiler/wrapper.ts +192 -0
- package/src/json-schema-subset/error.ts +55 -0
- package/src/json-schema-subset/expression/calculator.ts +442 -0
- package/src/json-schema-subset/expression/combination.ts +49 -0
- package/src/json-schema-subset/expression/expression.ts +191 -0
- package/src/json-schema-subset/expression/index.ts +25 -0
- package/src/json-schema-subset/expression/result.ts +88 -0
- package/src/json-schema-subset/expression/types.ts +36 -0
- package/src/json-schema-subset/extends/extendsContext.ts +89 -0
- package/src/json-schema-subset/extends/index.ts +2 -0
- package/src/json-schema-subset/extends/types.ts +12 -0
- package/src/json-schema-subset/global.ts +60 -0
- package/src/json-schema-subset/index.ts +8 -0
- package/src/json-schema-subset/preprocessing.ts +74 -0
- package/src/json-schema-subset/types.ts +8 -0
- package/src/json-schema-subset/utils.ts +95 -0
- package/src/localization/common/languages.ts +118 -0
- package/src/localization/common/timeZone.ts +25 -0
- package/src/openapi/common/authBindings.ts +12 -0
- package/src/openapi/common/openapi.ts +459 -0
- package/src/trigger/common/config.ts +56 -0
- package/src/trigger/common/configOptions.ts +15 -0
- package/src/trigger/common/configSchema.ts +8 -0
- package/src/trigger/common/contract.ts +132 -0
- package/src/trigger/common/cron.ts +151 -0
- package/src/trigger/common/integration.ts +498 -0
- package/src/trigger/common/poll.ts +187 -0
- package/src/trigger/common/webhook.ts +412 -0
- package/src/trigger/providers/airtable/locales/fr.json +18 -0
- package/src/trigger/providers/airtable/locales/ja.json +18 -0
- package/src/trigger/providers/airtable/locales/ko.json +18 -0
- package/src/trigger/providers/airtable/locales/ru.json +18 -0
- package/src/trigger/providers/airtable/locales/zh-CN.json +18 -0
- package/src/trigger/providers/airtable/locales/zh-TW.json +18 -0
- package/src/trigger/providers/asana/locales/fr.json +15 -0
- package/src/trigger/providers/asana/locales/ja.json +15 -0
- package/src/trigger/providers/asana/locales/ko.json +15 -0
- package/src/trigger/providers/asana/locales/ru.json +15 -0
- package/src/trigger/providers/asana/locales/zh-CN.json +15 -0
- package/src/trigger/providers/asana/locales/zh-TW.json +15 -0
- package/src/trigger/providers/calendly/locales/fr.json +16 -0
- package/src/trigger/providers/calendly/locales/ja.json +16 -0
- package/src/trigger/providers/calendly/locales/ko.json +16 -0
- package/src/trigger/providers/calendly/locales/ru.json +16 -0
- package/src/trigger/providers/calendly/locales/zh-CN.json +16 -0
- package/src/trigger/providers/calendly/locales/zh-TW.json +16 -0
- package/src/trigger/providers/catalog.generated.json +4996 -0
- package/src/trigger/providers/clickup/locales/fr.json +16 -0
- package/src/trigger/providers/clickup/locales/ja.json +16 -0
- package/src/trigger/providers/clickup/locales/ko.json +16 -0
- package/src/trigger/providers/clickup/locales/ru.json +16 -0
- package/src/trigger/providers/clickup/locales/zh-CN.json +16 -0
- package/src/trigger/providers/clickup/locales/zh-TW.json +16 -0
- package/src/trigger/providers/definitions.ts +19 -0
- package/src/trigger/providers/feishu/locales/fr.json +20 -0
- package/src/trigger/providers/feishu/locales/ja.json +20 -0
- package/src/trigger/providers/feishu/locales/ko.json +20 -0
- package/src/trigger/providers/feishu/locales/ru.json +20 -0
- package/src/trigger/providers/feishu/locales/zh-CN.json +20 -0
- package/src/trigger/providers/feishu/locales/zh-TW.json +20 -0
- package/src/trigger/providers/fieldDescriptions.ts +392 -0
- package/src/trigger/providers/fieldLabels.ts +256 -0
- package/src/trigger/providers/fireflies/locales/fr.json +17 -0
- package/src/trigger/providers/fireflies/locales/ja.json +17 -0
- package/src/trigger/providers/fireflies/locales/ko.json +17 -0
- package/src/trigger/providers/fireflies/locales/ru.json +17 -0
- package/src/trigger/providers/fireflies/locales/zh-CN.json +17 -0
- package/src/trigger/providers/fireflies/locales/zh-TW.json +17 -0
- package/src/trigger/providers/github/locales/fr.json +30 -0
- package/src/trigger/providers/github/locales/ja.json +30 -0
- package/src/trigger/providers/github/locales/ko.json +30 -0
- package/src/trigger/providers/github/locales/ru.json +30 -0
- package/src/trigger/providers/github/locales/zh-CN.json +30 -0
- package/src/trigger/providers/github/locales/zh-TW.json +30 -0
- package/src/trigger/providers/gitlab/locales/fr.json +18 -0
- package/src/trigger/providers/gitlab/locales/ja.json +18 -0
- package/src/trigger/providers/gitlab/locales/ko.json +18 -0
- package/src/trigger/providers/gitlab/locales/ru.json +18 -0
- package/src/trigger/providers/gitlab/locales/zh-CN.json +18 -0
- package/src/trigger/providers/gitlab/locales/zh-TW.json +18 -0
- package/src/trigger/providers/gmail/locales/fr.json +18 -0
- package/src/trigger/providers/gmail/locales/ja.json +18 -0
- package/src/trigger/providers/gmail/locales/ko.json +18 -0
- package/src/trigger/providers/gmail/locales/ru.json +18 -0
- package/src/trigger/providers/gmail/locales/zh-CN.json +18 -0
- package/src/trigger/providers/gmail/locales/zh-TW.json +18 -0
- package/src/trigger/providers/google-calendar/locales/fr.json +15 -0
- package/src/trigger/providers/google-calendar/locales/ja.json +15 -0
- package/src/trigger/providers/google-calendar/locales/ko.json +15 -0
- package/src/trigger/providers/google-calendar/locales/ru.json +15 -0
- package/src/trigger/providers/google-calendar/locales/zh-CN.json +15 -0
- package/src/trigger/providers/google-calendar/locales/zh-TW.json +15 -0
- package/src/trigger/providers/google-drive/locales/fr.json +48 -0
- package/src/trigger/providers/google-drive/locales/ja.json +48 -0
- package/src/trigger/providers/google-drive/locales/ko.json +48 -0
- package/src/trigger/providers/google-drive/locales/ru.json +48 -0
- package/src/trigger/providers/google-drive/locales/zh-CN.json +48 -0
- package/src/trigger/providers/google-drive/locales/zh-TW.json +48 -0
- package/src/trigger/providers/google-sheets/locales/fr.json +19 -0
- package/src/trigger/providers/google-sheets/locales/ja.json +19 -0
- package/src/trigger/providers/google-sheets/locales/ko.json +19 -0
- package/src/trigger/providers/google-sheets/locales/ru.json +19 -0
- package/src/trigger/providers/google-sheets/locales/zh-CN.json +19 -0
- package/src/trigger/providers/google-sheets/locales/zh-TW.json +19 -0
- package/src/trigger/providers/intercom/locales/fr.json +17 -0
- package/src/trigger/providers/intercom/locales/ja.json +17 -0
- package/src/trigger/providers/intercom/locales/ko.json +17 -0
- package/src/trigger/providers/intercom/locales/ru.json +17 -0
- package/src/trigger/providers/intercom/locales/zh-CN.json +17 -0
- package/src/trigger/providers/intercom/locales/zh-TW.json +17 -0
- package/src/trigger/providers/jira/locales/fr.json +17 -0
- package/src/trigger/providers/jira/locales/ja.json +17 -0
- package/src/trigger/providers/jira/locales/ko.json +17 -0
- package/src/trigger/providers/jira/locales/ru.json +17 -0
- package/src/trigger/providers/jira/locales/zh-CN.json +17 -0
- package/src/trigger/providers/jira/locales/zh-TW.json +17 -0
- package/src/trigger/providers/linear/locales/fr.json +13 -0
- package/src/trigger/providers/linear/locales/ja.json +13 -0
- package/src/trigger/providers/linear/locales/ko.json +13 -0
- package/src/trigger/providers/linear/locales/ru.json +13 -0
- package/src/trigger/providers/linear/locales/zh-CN.json +13 -0
- package/src/trigger/providers/linear/locales/zh-TW.json +13 -0
- package/src/trigger/providers/locales/fr.ts +71 -0
- package/src/trigger/providers/locales/ja.ts +71 -0
- package/src/trigger/providers/locales/ko.ts +71 -0
- package/src/trigger/providers/locales/ru.ts +71 -0
- package/src/trigger/providers/locales/zh-CN.ts +71 -0
- package/src/trigger/providers/locales/zh-TW.ts +71 -0
- package/src/trigger/providers/localization.ts +59 -0
- package/src/trigger/providers/notion/locales/fr.json +16 -0
- package/src/trigger/providers/notion/locales/ja.json +16 -0
- package/src/trigger/providers/notion/locales/ko.json +16 -0
- package/src/trigger/providers/notion/locales/ru.json +16 -0
- package/src/trigger/providers/notion/locales/zh-CN.json +16 -0
- package/src/trigger/providers/notion/locales/zh-TW.json +16 -0
- package/src/trigger/providers/one-drive/locales/fr.json +16 -0
- package/src/trigger/providers/one-drive/locales/ja.json +16 -0
- package/src/trigger/providers/one-drive/locales/ko.json +16 -0
- package/src/trigger/providers/one-drive/locales/ru.json +16 -0
- package/src/trigger/providers/one-drive/locales/zh-CN.json +16 -0
- package/src/trigger/providers/one-drive/locales/zh-TW.json +16 -0
- package/src/trigger/providers/outlook/locales/fr.json +18 -0
- package/src/trigger/providers/outlook/locales/ja.json +18 -0
- package/src/trigger/providers/outlook/locales/ko.json +18 -0
- package/src/trigger/providers/outlook/locales/ru.json +18 -0
- package/src/trigger/providers/outlook/locales/zh-CN.json +18 -0
- package/src/trigger/providers/outlook/locales/zh-TW.json +18 -0
- package/src/trigger/providers/pandadoc/locales/fr.json +12 -0
- package/src/trigger/providers/pandadoc/locales/ja.json +12 -0
- package/src/trigger/providers/pandadoc/locales/ko.json +12 -0
- package/src/trigger/providers/pandadoc/locales/ru.json +12 -0
- package/src/trigger/providers/pandadoc/locales/zh-CN.json +12 -0
- package/src/trigger/providers/pandadoc/locales/zh-TW.json +12 -0
- package/src/trigger/providers/pipedrive/locales/fr.json +15 -0
- package/src/trigger/providers/pipedrive/locales/ja.json +15 -0
- package/src/trigger/providers/pipedrive/locales/ko.json +15 -0
- package/src/trigger/providers/pipedrive/locales/ru.json +15 -0
- package/src/trigger/providers/pipedrive/locales/zh-CN.json +15 -0
- package/src/trigger/providers/pipedrive/locales/zh-TW.json +15 -0
- package/src/trigger/providers/remote.ts +163 -0
- package/src/trigger/providers/resend/locales/fr.json +16 -0
- package/src/trigger/providers/resend/locales/ja.json +16 -0
- package/src/trigger/providers/resend/locales/ko.json +16 -0
- package/src/trigger/providers/resend/locales/ru.json +16 -0
- package/src/trigger/providers/resend/locales/zh-CN.json +16 -0
- package/src/trigger/providers/resend/locales/zh-TW.json +16 -0
- package/src/trigger/providers/sentry/locales/fr.json +19 -0
- package/src/trigger/providers/sentry/locales/ja.json +19 -0
- package/src/trigger/providers/sentry/locales/ko.json +19 -0
- package/src/trigger/providers/sentry/locales/ru.json +19 -0
- package/src/trigger/providers/sentry/locales/zh-CN.json +19 -0
- package/src/trigger/providers/sentry/locales/zh-TW.json +19 -0
- package/src/trigger/providers/shopify/locales/fr.json +18 -0
- package/src/trigger/providers/shopify/locales/ja.json +18 -0
- package/src/trigger/providers/shopify/locales/ko.json +18 -0
- package/src/trigger/providers/shopify/locales/ru.json +18 -0
- package/src/trigger/providers/shopify/locales/zh-CN.json +18 -0
- package/src/trigger/providers/shopify/locales/zh-TW.json +18 -0
- package/src/trigger/providers/slack/locales/fr.json +18 -0
- package/src/trigger/providers/slack/locales/ja.json +18 -0
- package/src/trigger/providers/slack/locales/ko.json +18 -0
- package/src/trigger/providers/slack/locales/ru.json +18 -0
- package/src/trigger/providers/slack/locales/zh-CN.json +18 -0
- package/src/trigger/providers/slack/locales/zh-TW.json +18 -0
- package/src/trigger/providers/slackbot/locales/fr.json +23 -0
- package/src/trigger/providers/slackbot/locales/ja.json +23 -0
- package/src/trigger/providers/slackbot/locales/ko.json +23 -0
- package/src/trigger/providers/slackbot/locales/ru.json +23 -0
- package/src/trigger/providers/slackbot/locales/zh-CN.json +23 -0
- package/src/trigger/providers/slackbot/locales/zh-TW.json +23 -0
- package/src/trigger/providers/source-events.ts +25 -0
- package/src/trigger/providers/stripe/locales/fr.json +17 -0
- package/src/trigger/providers/stripe/locales/ja.json +17 -0
- package/src/trigger/providers/stripe/locales/ko.json +17 -0
- package/src/trigger/providers/stripe/locales/ru.json +17 -0
- package/src/trigger/providers/stripe/locales/zh-CN.json +17 -0
- package/src/trigger/providers/stripe/locales/zh-TW.json +17 -0
- package/src/trigger/providers/tally/locales/fr.json +12 -0
- package/src/trigger/providers/tally/locales/ja.json +12 -0
- package/src/trigger/providers/tally/locales/ko.json +12 -0
- package/src/trigger/providers/tally/locales/ru.json +12 -0
- package/src/trigger/providers/tally/locales/zh-CN.json +12 -0
- package/src/trigger/providers/tally/locales/zh-TW.json +12 -0
- package/src/trigger/providers/telegram/locales/fr.json +17 -0
- package/src/trigger/providers/telegram/locales/ja.json +17 -0
- package/src/trigger/providers/telegram/locales/ko.json +17 -0
- package/src/trigger/providers/telegram/locales/ru.json +17 -0
- package/src/trigger/providers/telegram/locales/zh-CN.json +17 -0
- package/src/trigger/providers/telegram/locales/zh-TW.json +17 -0
- package/src/trigger/providers/typeform/locales/fr.json +12 -0
- package/src/trigger/providers/typeform/locales/ja.json +12 -0
- package/src/trigger/providers/typeform/locales/ko.json +12 -0
- package/src/trigger/providers/typeform/locales/ru.json +12 -0
- package/src/trigger/providers/typeform/locales/zh-CN.json +12 -0
- package/src/trigger/providers/typeform/locales/zh-TW.json +12 -0
- package/src/trigger/providers/vercel/locales/fr.json +18 -0
- package/src/trigger/providers/vercel/locales/ja.json +18 -0
- package/src/trigger/providers/vercel/locales/ko.json +18 -0
- package/src/trigger/providers/vercel/locales/ru.json +18 -0
- package/src/trigger/providers/vercel/locales/zh-CN.json +18 -0
- package/src/trigger/providers/vercel/locales/zh-TW.json +18 -0
- package/src/trigger/providers/woocommerce/locales/fr.json +19 -0
- package/src/trigger/providers/woocommerce/locales/ja.json +19 -0
- package/src/trigger/providers/woocommerce/locales/ko.json +19 -0
- package/src/trigger/providers/woocommerce/locales/ru.json +19 -0
- package/src/trigger/providers/woocommerce/locales/zh-CN.json +19 -0
- package/src/trigger/providers/woocommerce/locales/zh-TW.json +19 -0
- package/src/trigger/providers/zendesk/locales/fr.json +15 -0
- package/src/trigger/providers/zendesk/locales/ja.json +15 -0
- package/src/trigger/providers/zendesk/locales/ko.json +15 -0
- package/src/trigger/providers/zendesk/locales/ru.json +15 -0
- package/src/trigger/providers/zendesk/locales/zh-CN.json +15 -0
- package/src/trigger/providers/zendesk/locales/zh-TW.json +15 -0
- package/src/trigger/providers/zoom/locales/fr.json +17 -0
- package/src/trigger/providers/zoom/locales/ja.json +17 -0
- package/src/trigger/providers/zoom/locales/ko.json +17 -0
- package/src/trigger/providers/zoom/locales/ru.json +17 -0
- package/src/trigger/providers/zoom/locales/zh-CN.json +17 -0
- package/src/trigger/providers/zoom/locales/zh-TW.json +17 -0
- package/src/types/index.ts +112 -0
- package/src/workflow/common/workflow.ts +273 -0
- package/dist/browser/lib-DrKav3HG.js +0 -11403
- /package/dist/{browser → common}/flow-authoring-edge.d.ts +0 -0
- /package/dist/{browser → common}/flow-authoring-module.d.ts +0 -0
- /package/dist/{browser → common}/flow-authoring.d.ts +0 -0
- /package/dist/{browser → common}/flow-input-value.d.ts +0 -0
- /package/dist/{browser → common}/webhook-method.d.ts +0 -0
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { InputMapping } from './change.ts'
|
|
2
|
+
|
|
3
|
+
export function renamedPort(
|
|
4
|
+
previous: readonly ({ readonly handle: string } | { readonly group: string })[],
|
|
5
|
+
next: readonly ({ readonly handle: string } | { readonly group: string })[],
|
|
6
|
+
): readonly [oldName: string, newName: string] | undefined {
|
|
7
|
+
const previousNames = new Set(previous.flatMap((port) => ('handle' in port ? [port.handle] : [])))
|
|
8
|
+
const nextNames = new Set(next.flatMap((port) => ('handle' in port ? [port.handle] : [])))
|
|
9
|
+
const removed = [...previousNames].filter((name) => !nextNames.has(name))
|
|
10
|
+
const added = [...nextNames].filter((name) => !previousNames.has(name))
|
|
11
|
+
return removed.length == 1 && added.length == 1 ? [removed[0]!, added[0]!] : undefined
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export function renameOutputMapping(mapping: InputMapping, nodeIds: ReadonlySet<string>, rename: readonly [string, string] | undefined): InputMapping {
|
|
15
|
+
if (rename == null || mapping.kind != 'sources') return mapping
|
|
16
|
+
const sources = mapping.sources.map((source) =>
|
|
17
|
+
source.kind == 'node' && !source.system && nodeIds.has(source.nodeId) && source.output == rename[0] ? { ...source, output: rename[1] } : source,
|
|
18
|
+
)
|
|
19
|
+
return sources.every((source, index) => source === mapping.sources[index]) ? mapping : { kind: 'sources', sources }
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/** Carry saved mappings through a field rename and remove only fields absent from the new contract. */
|
|
23
|
+
export function remapInputMappings(
|
|
24
|
+
mappings: Readonly<Record<string, InputMapping>>,
|
|
25
|
+
ports: readonly ({ readonly handle: string } | { readonly group: string })[],
|
|
26
|
+
rename: readonly [string, string] | undefined,
|
|
27
|
+
): Record<string, InputMapping> {
|
|
28
|
+
const inputs = { ...mappings }
|
|
29
|
+
if (rename != null && Object.hasOwn(inputs, rename[0])) {
|
|
30
|
+
Object.defineProperty(inputs, rename[1], { value: inputs[rename[0]], enumerable: true, configurable: true, writable: true })
|
|
31
|
+
delete inputs[rename[0]]
|
|
32
|
+
}
|
|
33
|
+
const names = new Set(ports.flatMap((port) => ('handle' in port ? [port.handle] : [])))
|
|
34
|
+
for (const name of Object.keys(inputs)) if (!names.has(name)) delete inputs[name]
|
|
35
|
+
return inputs
|
|
36
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { JsonValue } from './change.ts'
|
|
2
|
+
|
|
3
|
+
export const promptReferencePattern = /\{\{\s*([^{}\s]+)\s*\}\}/g
|
|
4
|
+
|
|
5
|
+
export function renderPrompt(template: string, input: Readonly<Record<string, JsonValue>>): string {
|
|
6
|
+
return template.replace(promptReferencePattern, (match, name: string) => {
|
|
7
|
+
if (!Object.hasOwn(input, name)) return match
|
|
8
|
+
const value = input[name]!
|
|
9
|
+
return typeof value == 'string' ? value : JSON.stringify(value)
|
|
10
|
+
})
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function renamePromptInput(template: string, before: string, after: string): string {
|
|
14
|
+
return template.replace(promptReferencePattern, (match, name: string) => (name == before ? '{{' + after + '}}' : match))
|
|
15
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { GraphNode } from './change.ts'
|
|
2
|
+
|
|
3
|
+
import { z } from 'zod'
|
|
4
|
+
|
|
5
|
+
export interface RetryConfiguration {
|
|
6
|
+
readonly maxRetries: number
|
|
7
|
+
readonly intervalMs: number
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export const retryNodeTypes = ['code', 'connector', 'openapi', 'llm', 'decision'] as const
|
|
11
|
+
export const nodeRetryLimits = { maxRetries: 5, minIntervalMs: 1000, maxIntervalMs: 60000, intervalStepMs: 1000 } as const
|
|
12
|
+
export const defaultNodeRetry: RetryConfiguration = { maxRetries: 2, intervalMs: 2000 }
|
|
13
|
+
export const retryConfigurationSchema = z.strictObject({
|
|
14
|
+
maxRetries: z.number().int().min(0).max(nodeRetryLimits.maxRetries),
|
|
15
|
+
intervalMs: z.number().int().min(nodeRetryLimits.minIntervalMs).max(nodeRetryLimits.maxIntervalMs).multipleOf(nodeRetryLimits.intervalStepMs),
|
|
16
|
+
})
|
|
17
|
+
|
|
18
|
+
export function supportsNodeRetry(node: GraphNode): boolean {
|
|
19
|
+
return node.kind == 'task' && retryNodeTypes.some((type) => type == ('moduleId' in node.task ? 'code' : node.task.executor.kind))
|
|
20
|
+
}
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
import type { Schema, SchemaDraft } from '@cfworker/json-schema'
|
|
2
|
+
import type { JsonValue, PortDefinition } from '../../types/index.ts'
|
|
3
|
+
import type { SchemaKeyword, SchemaMismatch } from './schemaKeywords.ts'
|
|
4
|
+
|
|
5
|
+
import { Validator } from '@cfworker/json-schema'
|
|
6
|
+
import { compareJSONSchema, normalizeNullableSchemaPath } from './schemaCompare.ts'
|
|
7
|
+
import { isSchemaKeyword } from './schemaKeywords.ts'
|
|
8
|
+
|
|
9
|
+
function jsonEqual(left: JsonValue, right: JsonValue): boolean {
|
|
10
|
+
if (left === right) return true
|
|
11
|
+
if (left == null || right == null || typeof left != 'object' || typeof right != 'object') return false
|
|
12
|
+
if (Array.isArray(left) || Array.isArray(right)) {
|
|
13
|
+
return Array.isArray(left) && Array.isArray(right) && left.length == right.length && left.every((value, index) => jsonEqual(value, right[index]!))
|
|
14
|
+
}
|
|
15
|
+
const leftEntries = Object.entries(left)
|
|
16
|
+
const rightRecord = right as Readonly<Record<string, JsonValue>>
|
|
17
|
+
return (
|
|
18
|
+
leftEntries.length == Object.keys(rightRecord).length &&
|
|
19
|
+
leftEntries.every(([key, value]) => Object.hasOwn(rightRecord, key) && jsonEqual(value, rightRecord[key]!))
|
|
20
|
+
)
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function schemaObject(schema: JsonValue): Readonly<Record<string, JsonValue>> | undefined {
|
|
24
|
+
return schema != null && typeof schema == 'object' && !Array.isArray(schema) ? (schema as Readonly<Record<string, JsonValue>>) : undefined
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export function schemaList(value: JsonValue | undefined): readonly JsonValue[] | undefined {
|
|
28
|
+
return Array.isArray(value) ? value : undefined
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const validators = new WeakMap<object, Validator>()
|
|
32
|
+
|
|
33
|
+
export function matchesSchema(value: JsonValue, schema: JsonValue): boolean {
|
|
34
|
+
return schemaValidationErrors(value, schema).length == 0
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export function schemaValidationErrors(value: JsonValue, schema: JsonValue): readonly string[] {
|
|
38
|
+
if (typeof schema == 'boolean') return schema ? [] : ['The schema does not allow any value.']
|
|
39
|
+
const source = schemaObject(schema)
|
|
40
|
+
if (source == null || (source.properties != null && schemaObject(source.properties) == null)) return ['Invalid output schema.']
|
|
41
|
+
try {
|
|
42
|
+
let validator = validators.get(source)
|
|
43
|
+
if (validator == null) {
|
|
44
|
+
const declaration = typeof source.$schema == 'string' ? source.$schema : ''
|
|
45
|
+
const draft: SchemaDraft = declaration.includes('draft-04')
|
|
46
|
+
? '4'
|
|
47
|
+
: declaration.includes('draft-07')
|
|
48
|
+
? '7'
|
|
49
|
+
: declaration.includes('2020-12')
|
|
50
|
+
? '2020-12'
|
|
51
|
+
: '2019-09'
|
|
52
|
+
// The validator attaches reference metadata, so it must not receive the Revision object.
|
|
53
|
+
validator = new Validator(structuredClone(source) as Schema, draft)
|
|
54
|
+
validators.set(source, validator)
|
|
55
|
+
}
|
|
56
|
+
const result = validator.validate(value)
|
|
57
|
+
return result.valid ? [] : result.errors.map((issue) => `${issue.instanceLocation || '/'}: ${issue.error}`)
|
|
58
|
+
} catch {
|
|
59
|
+
return ['Output schema validation failed.']
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
interface IncompatibleCompareResult {
|
|
64
|
+
readonly kind: 'incompatible'
|
|
65
|
+
readonly error?: string
|
|
66
|
+
readonly errorPath?: readonly (string | number)[]
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
type SchemaCompareResult = { readonly kind: 'compatible' } | { readonly kind: 'compare-error'; readonly message: string } | IncompatibleCompareResult
|
|
70
|
+
|
|
71
|
+
export type PortCompareResult =
|
|
72
|
+
| { readonly kind: 'compatible' }
|
|
73
|
+
| { readonly kind: 'compare-error'; readonly message: string }
|
|
74
|
+
| { readonly kind: 'incompatible'; readonly mismatch: SchemaMismatch }
|
|
75
|
+
|
|
76
|
+
function compareSchemas(sourceSchema: JsonValue, targetSchema: JsonValue, sourceNullable = false, targetNullable = false): SchemaCompareResult {
|
|
77
|
+
if (targetSchema === true) return { kind: 'compatible' }
|
|
78
|
+
if (sourceSchema === false || targetSchema === false) return { kind: 'incompatible' }
|
|
79
|
+
const source = sourceSchema === true ? {} : schemaObject(sourceSchema)
|
|
80
|
+
const target = schemaObject(targetSchema)
|
|
81
|
+
if (source == null || target == null) return { kind: 'compare-error', message: 'Port schema must be an object or boolean.' }
|
|
82
|
+
const result = compareJSONSchema(
|
|
83
|
+
{ nullable: sourceNullable, packageId: undefined, schema: source },
|
|
84
|
+
{ nullable: targetNullable, packageId: undefined, schema: target },
|
|
85
|
+
)
|
|
86
|
+
return result.kind == 'incompatible' ? { ...result, errorPath: normalizeNullableSchemaPath(result.errorPath, targetNullable) } : result
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function schemaValue(schema: JsonValue, path: readonly (string | number)[]): JsonValue | undefined {
|
|
90
|
+
let value: JsonValue | undefined = schema
|
|
91
|
+
for (const part of path) {
|
|
92
|
+
if (value == null || typeof value != 'object') return
|
|
93
|
+
value = Array.isArray(value) ? value[Number(part)] : schemaObject(value)?.[String(part)]
|
|
94
|
+
}
|
|
95
|
+
return value
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
function schemaMismatch(source: PortDefinition, target: PortDefinition, result: IncompatibleCompareResult): SchemaMismatch {
|
|
99
|
+
if (source.nullable && !target.nullable) return { kind: 'nullable' }
|
|
100
|
+
if (result.error == 'edgeError.binDiffType') return { kind: 'binary' }
|
|
101
|
+
if (result.error == 'edgeError.artifactDiffType') return { kind: 'artifact' }
|
|
102
|
+
const sourceSchema = schemaObject(source.jsonSchema)
|
|
103
|
+
const targetSchema = schemaObject(target.jsonSchema)
|
|
104
|
+
const fallbackKeyword = result.errorPath == null && sourceSchema != null && targetSchema != null ? rootMismatchKeyword(sourceSchema, targetSchema) : undefined
|
|
105
|
+
const path = fallbackKeyword == null ? result.errorPath : [fallbackKeyword]
|
|
106
|
+
const keyword = path?.at(-1)
|
|
107
|
+
if (typeof keyword != 'string' || !isSchemaKeyword(keyword)) return { kind: 'schema', path }
|
|
108
|
+
const ownerPath = path!.slice(0, -1)
|
|
109
|
+
return {
|
|
110
|
+
kind: 'keyword',
|
|
111
|
+
keyword,
|
|
112
|
+
path: ownerPath,
|
|
113
|
+
source: schemaValue(source.jsonSchema, [...ownerPath, keyword]),
|
|
114
|
+
target: schemaValue(target.jsonSchema, [...ownerPath, keyword]),
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
function rootMismatchKeyword(source: Readonly<Record<string, JsonValue>>, target: Readonly<Record<string, JsonValue>>): SchemaKeyword | undefined {
|
|
119
|
+
if (!jsonEqual(source.type, target.type)) return 'type'
|
|
120
|
+
if (target.const !== undefined && !jsonEqual(source.const, target.const)) return 'const'
|
|
121
|
+
if (target.enum !== undefined && !jsonEqual(source.enum, target.enum)) return 'enum'
|
|
122
|
+
const sourceRequired = new Set(Array.isArray(source.required) ? source.required : [])
|
|
123
|
+
if (Array.isArray(target.required) && target.required.some((name) => typeof name == 'string' && !sourceRequired.has(name))) return 'required'
|
|
124
|
+
for (const keyword of schemaConstraintKeywords) if (target[keyword] !== undefined && !jsonEqual(source[keyword], target[keyword])) return keyword
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
const schemaConstraintKeywords: readonly SchemaKeyword[] = [
|
|
128
|
+
'minLength',
|
|
129
|
+
'maxLength',
|
|
130
|
+
'pattern',
|
|
131
|
+
'minimum',
|
|
132
|
+
'exclusiveMinimum',
|
|
133
|
+
'maximum',
|
|
134
|
+
'exclusiveMaximum',
|
|
135
|
+
'multipleOf',
|
|
136
|
+
'minItems',
|
|
137
|
+
'maxItems',
|
|
138
|
+
'minProperties',
|
|
139
|
+
'maxProperties',
|
|
140
|
+
]
|
|
141
|
+
|
|
142
|
+
export function comparePorts(source: PortDefinition, target: PortDefinition): PortCompareResult {
|
|
143
|
+
const result = compareSchemas(source.jsonSchema, target.jsonSchema, source.nullable, target.nullable)
|
|
144
|
+
return result.kind == 'incompatible' ? { kind: 'incompatible', mismatch: schemaMismatch(source, target, result) } : result
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
export function portsAssignable(source: PortDefinition, target: PortDefinition): boolean {
|
|
148
|
+
return comparePorts(source, target).kind == 'compatible'
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
export function variableInputCompatible(jsonSchema: JsonValue): boolean {
|
|
152
|
+
const schema = schemaObject(jsonSchema)
|
|
153
|
+
const types = schemaList(schema?.type)
|
|
154
|
+
if (schema != null && types?.includes('string')) return compareSchemas({ type: 'string' }, { ...schema, type: 'string' }).kind == 'compatible'
|
|
155
|
+
return compareSchemas({ type: 'string' }, jsonSchema).kind == 'compatible'
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
export function hasRetiredRef(value: unknown): boolean {
|
|
159
|
+
if (value == null || typeof value != 'object') return false
|
|
160
|
+
const source = value as Readonly<Record<string, unknown>>
|
|
161
|
+
return source.contentMediaType == 'oomol/ref' || Object.values(source).some(hasRetiredRef)
|
|
162
|
+
}
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
import { SubsetCompareResult } from '../../json-schema-subset/index.ts'
|
|
2
|
+
import { createSchemaComparer } from './schemaComparer.ts'
|
|
3
|
+
|
|
4
|
+
export interface CompareSchemaInfo {
|
|
5
|
+
readonly nullable?: boolean
|
|
6
|
+
readonly schema: object
|
|
7
|
+
readonly packageId: string | undefined
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export interface CompatibleCompareResult {
|
|
11
|
+
readonly kind: 'compatible'
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export interface IncompatibleCompareResult {
|
|
15
|
+
readonly kind: 'incompatible'
|
|
16
|
+
readonly error?: string
|
|
17
|
+
readonly errorPath?: readonly (string | number)[]
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export interface CompareErrorResult {
|
|
21
|
+
readonly kind: 'compare-error'
|
|
22
|
+
readonly message: string
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export type CompareResult = CompatibleCompareResult | IncompatibleCompareResult | CompareErrorResult
|
|
26
|
+
|
|
27
|
+
const comparer = createSchemaComparer()
|
|
28
|
+
|
|
29
|
+
function nullableSchema(schema: object, nullable: boolean | undefined): object {
|
|
30
|
+
return nullable ? { anyOf: [schema, { type: 'null' }] } : schema
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export function normalizeNullableSchemaPath(
|
|
34
|
+
path: readonly (string | number)[] | undefined,
|
|
35
|
+
nullable: boolean | undefined,
|
|
36
|
+
): readonly (string | number)[] | undefined {
|
|
37
|
+
if (path == null || !nullable || path.length === 0 || path[0] !== 'anyOf') return path
|
|
38
|
+
return path[1] === 0 ? path.slice(2) : undefined
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export function compareJSONSchema(fromSchema: CompareSchemaInfo, toSchema: CompareSchemaInfo): CompareResult {
|
|
42
|
+
try {
|
|
43
|
+
const error: { message?: string } = {}
|
|
44
|
+
const fromResolved = resolveLocalRefs(fromSchema.schema)
|
|
45
|
+
const toResolved = resolveLocalRefs(toSchema.schema)
|
|
46
|
+
assertComparableSchema(fromResolved)
|
|
47
|
+
assertComparableSchema(toResolved)
|
|
48
|
+
const from = comparer.compile(nullableSchema(fromResolved, fromSchema.nullable), { ...fromSchema, error })
|
|
49
|
+
const to = comparer.compile(nullableSchema(toResolved, toSchema.nullable), { ...toSchema, error })
|
|
50
|
+
const { result, errorPath } = comparer.isSubset(from, to)
|
|
51
|
+
if (result == SubsetCompareResult.True) {
|
|
52
|
+
return { kind: 'compatible' }
|
|
53
|
+
} else {
|
|
54
|
+
return { kind: 'incompatible', error: error.message, errorPath }
|
|
55
|
+
}
|
|
56
|
+
} catch (error) {
|
|
57
|
+
return { kind: 'compare-error', message: error instanceof Error ? error.message : String(error) }
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const unsupportedComparisonKeywords: ReadonlySet<string> = new Set([
|
|
62
|
+
'contains',
|
|
63
|
+
'dependencies',
|
|
64
|
+
'dependentRequired',
|
|
65
|
+
'dependentSchemas',
|
|
66
|
+
'else',
|
|
67
|
+
'if',
|
|
68
|
+
'maxContains',
|
|
69
|
+
'minContains',
|
|
70
|
+
'prefixItems',
|
|
71
|
+
'then',
|
|
72
|
+
'unevaluatedItems',
|
|
73
|
+
'unevaluatedProperties',
|
|
74
|
+
])
|
|
75
|
+
|
|
76
|
+
function assertComparableSchema(schema: object): void {
|
|
77
|
+
function visit(value: unknown, path: readonly (string | number)[]): void {
|
|
78
|
+
if (value == null || typeof value != 'object' || Array.isArray(value)) return
|
|
79
|
+
const source = value as Readonly<Record<string, unknown>>
|
|
80
|
+
for (const keyword of unsupportedComparisonKeywords) {
|
|
81
|
+
if (Object.hasOwn(source, keyword)) throw new TypeError(`Unsupported schema comparison keyword at ${schemaPath([...path, keyword])}.`)
|
|
82
|
+
}
|
|
83
|
+
for (const keyword of ['additionalItems', 'additionalProperties', 'not', 'propertyNames'] as const) visit(source[keyword], [...path, keyword])
|
|
84
|
+
const items = source.items
|
|
85
|
+
if (Array.isArray(items)) items.forEach((item, index) => visit(item, [...path, 'items', index]))
|
|
86
|
+
else visit(items, [...path, 'items'])
|
|
87
|
+
for (const keyword of ['allOf', 'anyOf', 'oneOf'] as const) {
|
|
88
|
+
const variants = source[keyword]
|
|
89
|
+
if (Array.isArray(variants)) variants.forEach((item, index) => visit(item, [...path, keyword, index]))
|
|
90
|
+
}
|
|
91
|
+
for (const keyword of ['patternProperties', 'properties'] as const) {
|
|
92
|
+
const entries = source[keyword]
|
|
93
|
+
if (entries == null || typeof entries != 'object' || Array.isArray(entries)) continue
|
|
94
|
+
for (const [name, child] of Object.entries(entries)) visit(child, [...path, keyword, name])
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
visit(schema, [])
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
function schemaPath(path: readonly (string | number)[]): string {
|
|
101
|
+
return path.length == 0 ? '#' : `#/${path.map((part) => String(part).replaceAll('~', '~0').replaceAll('/', '~1')).join('/')}`
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
function resolveLocalRefs(schema: object): object {
|
|
105
|
+
function target(reference: string): unknown {
|
|
106
|
+
if (!reference.startsWith('#')) return
|
|
107
|
+
const pointer = decodeURIComponent(reference.slice(1))
|
|
108
|
+
if (pointer == '') return schema
|
|
109
|
+
if (!pointer.startsWith('/')) return
|
|
110
|
+
let value: unknown = schema
|
|
111
|
+
for (const encoded of pointer.slice(1).split('/')) {
|
|
112
|
+
if (value == null || typeof value != 'object' || Array.isArray(value)) return
|
|
113
|
+
const token = encoded.replaceAll('~1', '/').replaceAll('~0', '~')
|
|
114
|
+
if (!Object.hasOwn(value, token)) return
|
|
115
|
+
value = (value as Readonly<Record<string, unknown>>)[token]
|
|
116
|
+
}
|
|
117
|
+
return value
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
function visit(value: unknown, references: ReadonlySet<string>): unknown {
|
|
121
|
+
if (Array.isArray(value)) return value.map((item) => visit(item, references))
|
|
122
|
+
if (value == null || typeof value != 'object') return value
|
|
123
|
+
const source = value as Readonly<Record<string, unknown>>
|
|
124
|
+
const reference = typeof source.$ref == 'string' && source.$ref.startsWith('#') ? source.$ref : undefined
|
|
125
|
+
if (reference != null) {
|
|
126
|
+
if (references.has(reference)) throw new TypeError(`Cyclic local JSON Schema reference "${reference}".`)
|
|
127
|
+
const resolved = target(reference)
|
|
128
|
+
if (resolved === undefined) throw new TypeError(`Local JSON Schema reference "${reference}" does not exist.`)
|
|
129
|
+
const nextReferences = new Set(references)
|
|
130
|
+
nextReferences.add(reference)
|
|
131
|
+
const siblings = Object.fromEntries(Object.entries(source).filter(([key]) => key != '$ref' && key != '$defs' && key != 'definitions'))
|
|
132
|
+
const result = visit(resolved, nextReferences)
|
|
133
|
+
return Object.keys(siblings).length == 0 ? result : { allOf: [result, visit(siblings, references)] }
|
|
134
|
+
}
|
|
135
|
+
return Object.fromEntries(
|
|
136
|
+
Object.entries(source)
|
|
137
|
+
.filter(([key]) => key != '$defs' && key != 'definitions')
|
|
138
|
+
.map(([key, item]) => {
|
|
139
|
+
switch (key) {
|
|
140
|
+
case 'additionalItems':
|
|
141
|
+
case 'additionalProperties':
|
|
142
|
+
case 'contains':
|
|
143
|
+
case 'else':
|
|
144
|
+
case 'if':
|
|
145
|
+
case 'not':
|
|
146
|
+
case 'propertyNames':
|
|
147
|
+
case 'then': {
|
|
148
|
+
return [key, visit(item, references)]
|
|
149
|
+
}
|
|
150
|
+
case 'items': {
|
|
151
|
+
return [key, Array.isArray(item) ? item.map((entry) => visit(entry, references)) : visit(item, references)]
|
|
152
|
+
}
|
|
153
|
+
case 'allOf':
|
|
154
|
+
case 'anyOf':
|
|
155
|
+
case 'oneOf': {
|
|
156
|
+
return [key, Array.isArray(item) ? item.map((entry) => visit(entry, references)) : item]
|
|
157
|
+
}
|
|
158
|
+
case 'patternProperties':
|
|
159
|
+
case 'properties': {
|
|
160
|
+
if (item == null || typeof item != 'object' || Array.isArray(item)) return [key, item]
|
|
161
|
+
return [key, Object.fromEntries(Object.entries(item).map(([name, entry]) => [name, visit(entry, references)]))]
|
|
162
|
+
}
|
|
163
|
+
case 'dependencies': {
|
|
164
|
+
if (item == null || typeof item != 'object' || Array.isArray(item)) return [key, item]
|
|
165
|
+
return [key, Object.fromEntries(Object.entries(item).map(([name, entry]) => [name, Array.isArray(entry) ? entry : visit(entry, references)]))]
|
|
166
|
+
}
|
|
167
|
+
default: {
|
|
168
|
+
return [key, item]
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}),
|
|
172
|
+
)
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
return visit(schema, new Set()) as object
|
|
176
|
+
}
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
import type { ExtendsSchema, SubsetCompare } from '../../json-schema-subset/index.ts'
|
|
2
|
+
|
|
3
|
+
import { isString, toPlainObject } from '@wopjs/cast'
|
|
4
|
+
import { CompiledKind, getKind, isCompiledSchema } from '../../json-schema-subset/compiler/index.ts'
|
|
5
|
+
import { ExpressionSingleResult, makeSubsetCompare } from '../../json-schema-subset/index.ts'
|
|
6
|
+
|
|
7
|
+
export interface SchemaCompareContext {
|
|
8
|
+
readonly packageId?: string
|
|
9
|
+
readonly error: { message?: string }
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
interface StringSchemaValue {
|
|
13
|
+
readonly type: 'string'
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function isStringLikeSchema(value: unknown): value is StringSchemaValue {
|
|
17
|
+
return toPlainObject(value)?.type === 'string'
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function assertSchemaCompareContext(value: unknown): asserts value is SchemaCompareContext {
|
|
21
|
+
const context = toPlainObject(value)
|
|
22
|
+
const error = toPlainObject(context?.error)
|
|
23
|
+
if (context == null || error == null || (context.packageId != null && !isString(context.packageId)) || (error.message != null && !isString(error.message))) {
|
|
24
|
+
throw new TypeError('Invalid schema comparison context.')
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function parseSchemaCompareContext(value: unknown): SchemaCompareContext {
|
|
29
|
+
if (value == null) return { error: {} }
|
|
30
|
+
assertSchemaCompareContext(value)
|
|
31
|
+
return value
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
abstract class SpecialSchema<T = unknown> implements ExtendsSchema {
|
|
35
|
+
public static setError(fromSchema: unknown, toSchema: unknown, message: string): void {
|
|
36
|
+
if (fromSchema instanceof SpecialSchema) {
|
|
37
|
+
fromSchema.context.error.message = message
|
|
38
|
+
} else if (toSchema instanceof SpecialSchema) {
|
|
39
|
+
toSchema.context.error.message = message
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
public readonly id: number
|
|
44
|
+
public readonly value: T
|
|
45
|
+
public readonly context: SchemaCompareContext
|
|
46
|
+
|
|
47
|
+
protected constructor(id: number, value: T, context?: unknown) {
|
|
48
|
+
this.id = id
|
|
49
|
+
this.value = value
|
|
50
|
+
this.context = parseSchemaCompareContext(context)
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
public compare(other: unknown): readonly ExpressionSingleResult[] {
|
|
54
|
+
if (isCompiledSchema(other) && getKind(other) === CompiledKind.Any) return [ExpressionSingleResult.ContainedBy]
|
|
55
|
+
return this.compareImpl(other)
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
protected abstract compareImpl(other: unknown): readonly ExpressionSingleResult[]
|
|
59
|
+
|
|
60
|
+
public abstract equals(other: unknown): boolean
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
interface SingleSelectSchemaValue {
|
|
64
|
+
readonly enum: readonly string[]
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
class SingleSelectSchema extends SpecialSchema<SingleSelectSchemaValue> {
|
|
68
|
+
public static isMatch(value: unknown): value is SingleSelectSchemaValue {
|
|
69
|
+
const enumValues = toPlainObject(value)?.enum
|
|
70
|
+
return Array.isArray(enumValues) && enumValues.every((v) => isString(v))
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
public constructor(id: number, value: unknown, context?: unknown) {
|
|
74
|
+
if (!SingleSelectSchema.isMatch(value)) throw new TypeError('Invalid single-select schema.')
|
|
75
|
+
super(id, value, context)
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
protected compareImpl(other: unknown): readonly ExpressionSingleResult[] {
|
|
79
|
+
if (isStringLikeSchema(other)) {
|
|
80
|
+
return [ExpressionSingleResult.ContainedBy]
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
if (other instanceof SingleSelectSchema) {
|
|
84
|
+
const f = new Set(this.value.enum)
|
|
85
|
+
let result: ExpressionSingleResult = ExpressionSingleResult.Equals
|
|
86
|
+
for (const v of other.value.enum) {
|
|
87
|
+
if (!f.has(v)) {
|
|
88
|
+
result = ExpressionSingleResult.ContainedBy
|
|
89
|
+
}
|
|
90
|
+
f.delete(v)
|
|
91
|
+
}
|
|
92
|
+
if (f.size === 0) {
|
|
93
|
+
return [result]
|
|
94
|
+
}
|
|
95
|
+
if (f.size === this.value.enum.length) {
|
|
96
|
+
return [ExpressionSingleResult.Rejection]
|
|
97
|
+
}
|
|
98
|
+
return [ExpressionSingleResult.Intersection]
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
return [ExpressionSingleResult.Rejection]
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
public equals(other: unknown): boolean {
|
|
105
|
+
if (other instanceof SingleSelectSchema) {
|
|
106
|
+
const f = new Set(this.value.enum)
|
|
107
|
+
for (const v of other.value.enum) {
|
|
108
|
+
if (!f.has(v)) {
|
|
109
|
+
return false
|
|
110
|
+
}
|
|
111
|
+
f.delete(v)
|
|
112
|
+
}
|
|
113
|
+
return f.size === 0
|
|
114
|
+
}
|
|
115
|
+
return false
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
interface BinarySchemaValue {
|
|
120
|
+
readonly contentMediaType: 'oomol/bin'
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
class BinarySchema extends SpecialSchema<BinarySchemaValue> {
|
|
124
|
+
public static isMatch(value: unknown): value is BinarySchemaValue {
|
|
125
|
+
return toPlainObject(value)?.contentMediaType === 'oomol/bin'
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
public constructor(id: number, value: unknown, context?: unknown) {
|
|
129
|
+
if (!BinarySchema.isMatch(value)) throw new TypeError('Invalid binary schema.')
|
|
130
|
+
super(id, value, context)
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
protected compareImpl(other: unknown): readonly ExpressionSingleResult[] {
|
|
134
|
+
if (other instanceof BinarySchema) {
|
|
135
|
+
return [ExpressionSingleResult.Equals]
|
|
136
|
+
} else {
|
|
137
|
+
SpecialSchema.setError(this, other, 'edgeError.binDiffType')
|
|
138
|
+
return [ExpressionSingleResult.Rejection]
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
public equals(other: unknown): boolean {
|
|
143
|
+
return other instanceof BinarySchema
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
interface ArtifactSchemaValue {
|
|
148
|
+
readonly contentMediaType: 'oomol/artifact'
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
class ArtifactSchema extends SpecialSchema<ArtifactSchemaValue> {
|
|
152
|
+
public static isMatch(value: unknown): value is ArtifactSchemaValue {
|
|
153
|
+
return toPlainObject(value)?.contentMediaType === 'oomol/artifact'
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
public constructor(id: number, value: unknown, context?: unknown) {
|
|
157
|
+
if (!ArtifactSchema.isMatch(value)) throw new TypeError('Invalid Artifact schema.')
|
|
158
|
+
super(id, value, context)
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
protected compareImpl(other: unknown): readonly ExpressionSingleResult[] {
|
|
162
|
+
if (other instanceof ArtifactSchema) return [ExpressionSingleResult.Equals]
|
|
163
|
+
SpecialSchema.setError(this, other, 'edgeError.artifactDiffType')
|
|
164
|
+
return [ExpressionSingleResult.Rejection]
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
public equals(other: unknown): boolean {
|
|
168
|
+
return other instanceof ArtifactSchema
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
export function createSchemaComparer(): SubsetCompare<unknown> {
|
|
173
|
+
const comparer = makeSubsetCompare({
|
|
174
|
+
extendsSchemaClasses: [SingleSelectSchema, BinarySchema, ArtifactSchema],
|
|
175
|
+
})
|
|
176
|
+
|
|
177
|
+
return comparer
|
|
178
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import type { JsonValue } from '../../types/index.ts'
|
|
2
|
+
|
|
3
|
+
export type SchemaKeyword =
|
|
4
|
+
| 'const'
|
|
5
|
+
| 'enum'
|
|
6
|
+
| 'exclusiveMaximum'
|
|
7
|
+
| 'exclusiveMinimum'
|
|
8
|
+
| 'maximum'
|
|
9
|
+
| 'maxItems'
|
|
10
|
+
| 'maxLength'
|
|
11
|
+
| 'maxProperties'
|
|
12
|
+
| 'minimum'
|
|
13
|
+
| 'minItems'
|
|
14
|
+
| 'minLength'
|
|
15
|
+
| 'minProperties'
|
|
16
|
+
| 'multipleOf'
|
|
17
|
+
| 'pattern'
|
|
18
|
+
| 'required'
|
|
19
|
+
| 'type'
|
|
20
|
+
|
|
21
|
+
export type SchemaMismatch =
|
|
22
|
+
| { readonly kind: 'artifact' | 'binary' | 'nullable' }
|
|
23
|
+
| {
|
|
24
|
+
readonly kind: 'keyword'
|
|
25
|
+
readonly keyword: SchemaKeyword
|
|
26
|
+
readonly path: readonly (string | number)[]
|
|
27
|
+
readonly source: JsonValue | undefined
|
|
28
|
+
readonly target: JsonValue | undefined
|
|
29
|
+
}
|
|
30
|
+
| { readonly kind: 'schema'; readonly path?: readonly (string | number)[] }
|
|
31
|
+
|
|
32
|
+
const schemaKeywords: ReadonlySet<string> = new Set<SchemaKeyword>([
|
|
33
|
+
'const',
|
|
34
|
+
'enum',
|
|
35
|
+
'exclusiveMaximum',
|
|
36
|
+
'exclusiveMinimum',
|
|
37
|
+
'maximum',
|
|
38
|
+
'maxItems',
|
|
39
|
+
'maxLength',
|
|
40
|
+
'maxProperties',
|
|
41
|
+
'minimum',
|
|
42
|
+
'minItems',
|
|
43
|
+
'minLength',
|
|
44
|
+
'minProperties',
|
|
45
|
+
'multipleOf',
|
|
46
|
+
'pattern',
|
|
47
|
+
'required',
|
|
48
|
+
'type',
|
|
49
|
+
])
|
|
50
|
+
|
|
51
|
+
export function isSchemaKeyword(value: string): value is SchemaKeyword {
|
|
52
|
+
return schemaKeywords.has(value)
|
|
53
|
+
}
|