@oomol-lab/open-flow 0.1.0-beta.3 → 0.1.0-beta.30
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/dist/browser/{_virtual_open-flow-twemoji-DJwKsM_w.js → _virtual_open-flow-twemoji-CpHJOEsk.js} +4028 -2
- package/dist/browser/carbon-Cn-DTyjG.js +54 -0
- package/dist/browser/createResourceDialog-_y2xHaUA.js +110 -0
- package/dist/browser/{dist-DWADUsVB.js → dist-By46o5UV.js} +47 -47
- package/dist/browser/dist-CoszrK7m.js +4 -0
- package/dist/browser/{dist-CPuF50D9.js → dist-D1VYgicl.js} +426 -305
- package/dist/browser/dist-DSe6KRsr.js +1224 -0
- package/dist/browser/dist-DYjIVIZC.js +795 -0
- package/dist/browser/{dist-3Mj8q8Pr.js → dist-DmuE3M0R.js} +53 -54
- package/dist/browser/{dist-BN4ZCyOB.js → dist-DpDLsYtO.js} +14 -15
- package/dist/browser/{dist-CJpzJrLM.js → dist-DwvhuMxw.js} +894 -895
- package/dist/browser/dist-DxahK_I8.js +2688 -0
- package/dist/browser/{dist-C46JByB-.js → dist-Dz6Nglsd.js} +61 -61
- package/dist/browser/{dist-DUzA0Ukh.js → dist-TJfrvoIQ.js} +141 -142
- package/dist/browser/editorComponent-Dq4IKp5R.js +14790 -0
- package/dist/browser/{esm-C2UUqIUP.js → esm-B7A42FzW.js} +68 -59
- package/dist/browser/event-sources.d.ts +30 -0
- package/dist/browser/flow-authoring-module.d.ts +2 -2
- package/dist/browser/flow-authoring-node.d.ts +26 -8
- package/dist/browser/flow-authoring.d.ts +1 -1
- package/dist/browser/flow-authoring.js +5282 -313
- package/dist/browser/flow-change-schema.d.ts +11 -0
- package/dist/browser/flow-change.d.ts +193 -18
- package/dist/browser/flow-change.js +5192 -137
- package/dist/browser/flow-notifications.d.ts +11 -2
- package/dist/browser/flowChanges-AdN0Iqma.js +12304 -0
- package/dist/browser/{flowRunInputEditorStore-CwvOiIiU.js → flowRunInputEditorStore-CTORQcA2.js} +864 -4000
- package/dist/browser/flowWorkspace-BrtzLKWB.js +153066 -0
- package/dist/browser/host-conformance.d.ts +7 -0
- package/dist/browser/host-conformance.js +39 -0
- package/dist/browser/inputValues-DJfFraxG.js +43 -0
- package/dist/browser/licenses.md +195 -662
- package/dist/browser/lite-BuKZ8joP.js +8545 -0
- package/dist/browser/main-BDnNHhkU.js +50 -0
- package/dist/browser/{markdownContent-DUfLdnUt.js → markdownContent-D2oHGWc6.js} +53 -53
- package/dist/browser/theme.css +527 -34
- package/dist/browser/{typeScriptSession-mPCiA9sV.js → typeScriptSession-DnAmJCzu.js} +70 -71
- package/dist/browser/ui-input.d.ts +5 -0
- package/dist/browser/ui-label.d.ts +3 -0
- package/dist/browser/ui-textarea.d.ts +3 -0
- package/dist/browser/ui.css +2 -0
- package/dist/browser/ui.css.d.ts +1 -0
- package/dist/browser/ui.d.ts +34 -0
- package/dist/browser/ui.js +2632 -0
- package/dist/browser/value-DPg_9yXB.js +93 -0
- package/dist/browser/warmCodeTheme-DVv4-rDO.js +35 -0
- package/dist/browser/workbench-contract.d.ts +27 -2
- package/dist/browser/workbench.css +1 -1
- package/dist/browser/workbench.d.ts +2 -0
- package/dist/browser/workbench.js +2767 -1406
- package/dist/browser/workbenchSelect-BDPIQxYK.js +5967 -0
- package/dist/common/authoringExamples.d.ts +28 -0
- package/dist/common/control-api-conformance.d.ts +7 -0
- package/dist/common/control-api-conformance.js +5568 -171
- package/dist/common/control-api-errors.d.ts +37 -0
- package/dist/common/control-api.d.ts +394 -47
- package/dist/common/control-api.js +6066 -569
- package/dist/common/control-requests.d.ts +98 -0
- package/dist/common/control-requests.js +5412 -0
- package/dist/common/cron-trigger.d.ts +2 -1
- package/dist/common/cron-trigger.js +27 -24
- package/dist/common/draftOperations.d.ts +14 -0
- package/dist/common/engine-contract.d.ts +3 -1
- package/dist/common/event-sources.d.ts +50 -0
- package/dist/common/feishu-events.d.ts +20 -0
- package/dist/common/feishu-subscriptions.d.ts +10 -0
- package/dist/common/flow-agent.d.ts +10 -0
- package/dist/common/flow-encoding.d.ts +16 -2
- package/dist/common/flow-encoding.js +5092 -68
- package/dist/common/flow-graph.d.ts +52 -0
- package/dist/common/flow-json.d.ts +2 -0
- package/dist/common/flow-modules.d.ts +20 -0
- package/dist/common/flow-notifications.d.ts +11 -2
- package/dist/common/flow-schema.d.ts +17 -0
- package/dist/common/flow-semantics.d.ts +12 -6
- package/dist/common/flow-semantics.js +15870 -9668
- package/dist/common/flowInspection.d.ts +16 -0
- package/dist/common/fr-iv1541dF.js +93 -0
- package/dist/common/integration-trigger.d.ts +29 -2
- package/dist/common/integration-trigger.js +192 -56
- package/dist/common/ja-Bq-ZDOD4.js +93 -0
- package/dist/common/ko-Z-k9R2c6.js +93 -0
- package/dist/common/localization.d.ts +2 -0
- package/dist/common/localization.js +37 -1
- package/dist/common/mcp-conformance.d.ts +2 -0
- package/dist/common/mcp.d.ts +767 -0
- package/dist/common/mcp.js +6733 -0
- package/dist/common/poll-trigger.d.ts +5 -0
- package/dist/common/poll-trigger.js +26 -22
- package/dist/common/provider-triggers.d.ts +4 -0
- package/dist/common/provider-triggers.js +7310 -1736
- package/dist/common/ru-B4gFecYZ.js +93 -0
- package/dist/common/run-events.d.ts +2 -2
- package/dist/common/run-events.js +13 -17
- package/dist/common/run-lifecycle.d.ts +21 -2
- package/dist/common/run-lifecycle.js +83 -2
- package/dist/common/run-results.d.ts +57 -0
- package/dist/common/runtime-contract.d.ts +38 -3
- package/dist/common/runtime-contract.js +291 -19
- package/dist/common/scheduler.d.ts +97 -19
- package/dist/common/scheduler.js +8234 -261
- package/dist/common/trigger-catalog.d.ts +17 -0
- package/dist/common/trigger-config-options.d.ts +13 -0
- package/dist/common/trigger-contract.d.ts +5 -0
- package/dist/common/trigger-localization.d.ts +7 -0
- package/dist/common/webhook-trigger.d.ts +3 -3
- package/dist/common/webhook-trigger.js +64 -18
- package/dist/common/zh-CN-ByQ6nYam.js +93 -0
- package/dist/common/zh-TW-QjIarvX9.js +93 -0
- package/dist/index.d.ts +6 -5
- package/package.json +21 -1
- package/dist/browser/carbon-DMCVsjHo.js +0 -53
- package/dist/browser/createResourceDialog-BkZns-oZ.js +0 -504
- package/dist/browser/diagnostics-SDCyFuxm.js +0 -11634
- package/dist/browser/dist-BMqL-qR5.js +0 -1894
- package/dist/browser/dist-BpopSHwP.js +0 -1543
- package/dist/browser/dist-CP0883sY.js +0 -4
- package/dist/browser/dist-CUSrALSX.js +0 -1620
- package/dist/browser/flowWorkspace-BZ_eiQNR.js +0 -45393
- package/dist/browser/getPseudoElementBounds-ESJExRFX.js +0 -7642
- package/dist/browser/languages-DgJehE1g.js +0 -62
- package/dist/browser/main-DmjVyuWr.js +0 -76
- package/dist/browser/workbenchSelect-B2s1HV-Y.js +0 -1374
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { Draft, Flow } from './control-api.js';
|
|
2
|
+
export declare function inspectFlowDraft(flow: Flow, readDraft: () => Draft | Promise<Draft>): Promise<{
|
|
3
|
+
flow: Flow;
|
|
4
|
+
draft: Draft;
|
|
5
|
+
version: 1;
|
|
6
|
+
draftIssue?: undefined;
|
|
7
|
+
} | {
|
|
8
|
+
flow: Flow;
|
|
9
|
+
draft: null;
|
|
10
|
+
draftIssue: {
|
|
11
|
+
code: unknown;
|
|
12
|
+
message: string;
|
|
13
|
+
revisionId: string;
|
|
14
|
+
};
|
|
15
|
+
version: 1;
|
|
16
|
+
}>;
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
//#region src/trigger/providers/airtable/locales/fr.json
|
|
2
|
+
var e = { "airtable.on_record_changed": {
|
|
3
|
+
displayName: "Création ou mise à jour d’un enregistrement",
|
|
4
|
+
description: "Interroge périodiquement une table Airtable et se déclenche à la création ou à la mise à jour d’un enregistrement, dans l’ordre d’un champ temporel."
|
|
5
|
+
} }, t = { "feishu_app_bot.on_event": {
|
|
6
|
+
displayName: "Événement d’application",
|
|
7
|
+
description: "Reçoit les événements Feishu sélectionnés via une source partagée."
|
|
8
|
+
} }, n = {
|
|
9
|
+
"github.on_repo_event": {
|
|
10
|
+
displayName: "Événement de dépôt",
|
|
11
|
+
description: "Se déclenche lors des événements webhook GitHub sélectionnés dans un dépôt."
|
|
12
|
+
},
|
|
13
|
+
"github.watch_pull_request": {
|
|
14
|
+
displayName: "Suivi d’une pull request",
|
|
15
|
+
description: "Suit une pull request grâce aux notifications et à des vérifications périodiques. Part de son état actuel et signale les changements observés, sans garantir chaque transition intermédiaire ou événement de revue."
|
|
16
|
+
}
|
|
17
|
+
}, r = { "gitlab.on_project_event": {
|
|
18
|
+
displayName: "Événement de projet",
|
|
19
|
+
description: "Se déclenche lors des événements webhook GitLab sélectionnés dans un projet."
|
|
20
|
+
} }, i = { "gmail.on_message_received": {
|
|
21
|
+
displayName: "Nouveau message reçu",
|
|
22
|
+
description: "Interroge périodiquement la boîte Gmail et se déclenche à la réception d’un nouveau message."
|
|
23
|
+
} }, a = { "googlecalendar.on_event_changed": {
|
|
24
|
+
displayName: "Modification d’un événement",
|
|
25
|
+
description: "Interroge périodiquement un agenda Google et se déclenche à la création, à la modification ou à l’annulation d’un événement."
|
|
26
|
+
} }, o = {
|
|
27
|
+
"googledrive.changes_detected": {
|
|
28
|
+
displayName: "Modifications détectées",
|
|
29
|
+
description: "Utilise un canal Google Drive changes.watch et se déclenche lorsque des modifications Drive sont disponibles."
|
|
30
|
+
},
|
|
31
|
+
"googledrive.watch_changes": {
|
|
32
|
+
displayName: "Suivi des modifications",
|
|
33
|
+
description: "Surveille les modifications Drive grâce aux notifications et à des analyses périodiques du même flux de modifications."
|
|
34
|
+
},
|
|
35
|
+
"googledrive.on_file_change": {
|
|
36
|
+
displayName: "Modification d’un fichier ou dossier dans un dossier",
|
|
37
|
+
description: "Interroge périodiquement un dossier Google Drive et se déclenche à la création ou à la modification d’un fichier ou dossier directement à l’intérieur."
|
|
38
|
+
}
|
|
39
|
+
}, s = { "googlesheets.on_row_added": {
|
|
40
|
+
displayName: "Nouvelle ligne ajoutée",
|
|
41
|
+
description: "Interroge périodiquement une feuille et se déclenche une fois pour chaque nouvelle ligne ajoutée après la dernière ligne déjà observée."
|
|
42
|
+
} }, c = { "linear.on_issue_changed": {
|
|
43
|
+
displayName: "Création ou mise à jour d’un ticket",
|
|
44
|
+
description: "Vérifie périodiquement les tickets nouveaux et modifiés d’une équipe Linear. Commence maintenant, sans déclencher les tickets existants. Signale les états actuels observés, sans couvrir les suppressions ni chaque changement de statut intermédiaire."
|
|
45
|
+
} }, l = { "notion.on_database_page_event": {
|
|
46
|
+
displayName: "Ajout ou mise à jour d’une page de base de données",
|
|
47
|
+
description: "Interroge périodiquement une base Notion et se déclenche à l’ajout d’une page ou à la modification d’une page existante."
|
|
48
|
+
} }, u = { "one_drive.on_item_changed": {
|
|
49
|
+
displayName: "Modification d’un fichier ou dossier",
|
|
50
|
+
description: "Interroge périodiquement le flux de modifications OneDrive et se déclenche à la création, à la modification ou à la suppression d’un fichier ou dossier."
|
|
51
|
+
} }, d = { "outlook.on_message_received": {
|
|
52
|
+
displayName: "Nouveau message reçu",
|
|
53
|
+
description: "Interroge périodiquement un dossier de courrier Microsoft Outlook et se déclenche à l’arrivée d’un nouveau message."
|
|
54
|
+
} }, f = { "shopify.on_shop_event": {
|
|
55
|
+
displayName: "Événement de boutique",
|
|
56
|
+
description: "Se déclenche lors des événements correspondant aux sujets webhook Shopify sélectionnés dans la boutique connectée."
|
|
57
|
+
} }, p = { "slack.on_message_posted": {
|
|
58
|
+
displayName: "Nouveau message de canal",
|
|
59
|
+
description: "Interroge périodiquement une conversation Slack et se déclenche à la publication d’un nouveau message."
|
|
60
|
+
} }, m = { "stripe.on_event": {
|
|
61
|
+
displayName: "Événement de compte",
|
|
62
|
+
description: "Se déclenche lors des événements Stripe sélectionnés sur le compte connecté."
|
|
63
|
+
} }, h = { "telegram.on_update": {
|
|
64
|
+
displayName: "Mise à jour du bot",
|
|
65
|
+
description: "Se déclenche lorsque le bot Telegram connecté reçoit une mise à jour sélectionnée."
|
|
66
|
+
} }, g = { "woocommerce.on_store_event": {
|
|
67
|
+
displayName: "Événement de boutique",
|
|
68
|
+
description: "Se déclenche lors des événements de boutique WooCommerce sélectionnés."
|
|
69
|
+
} }, _ = { "zendesk.on_event": {
|
|
70
|
+
displayName: "Abonnement aux événements",
|
|
71
|
+
description: "Se déclenche lorsque l’un des événements de compte Zendesk sélectionnés se produit."
|
|
72
|
+
} }, v = {
|
|
73
|
+
...e,
|
|
74
|
+
...t,
|
|
75
|
+
...n,
|
|
76
|
+
...r,
|
|
77
|
+
...i,
|
|
78
|
+
...a,
|
|
79
|
+
...o,
|
|
80
|
+
...s,
|
|
81
|
+
...c,
|
|
82
|
+
...l,
|
|
83
|
+
...u,
|
|
84
|
+
...d,
|
|
85
|
+
...f,
|
|
86
|
+
...p,
|
|
87
|
+
...m,
|
|
88
|
+
...h,
|
|
89
|
+
...g,
|
|
90
|
+
..._
|
|
91
|
+
};
|
|
92
|
+
//#endregion
|
|
93
|
+
export { v as default };
|
|
@@ -1,13 +1,34 @@
|
|
|
1
1
|
import type { ConnectorProxy } from './connector-proxy.js';
|
|
2
2
|
import type { IntegrationEndpointMethod, JsonValue, TriggerKeySnapshot } from '../browser/flow-change.js';
|
|
3
|
+
import type { TriggerConfigOption, TriggerConfigOptionsContext } from './trigger-config-options.js';
|
|
3
4
|
export declare const maximumIntegrationBodyBytes: number;
|
|
4
5
|
export declare const maximumIntegrationDeliveryPages = 5;
|
|
6
|
+
export interface ListenerReadContext {
|
|
7
|
+
readonly checkpoint: JsonValue;
|
|
8
|
+
readonly config: Readonly<Record<string, JsonValue>>;
|
|
9
|
+
readonly connector: ConnectorProxy;
|
|
10
|
+
readonly now: Date;
|
|
11
|
+
readonly signal?: AbortSignal;
|
|
12
|
+
}
|
|
13
|
+
export interface ListenerPage {
|
|
14
|
+
readonly checkpoint: JsonValue;
|
|
15
|
+
readonly dedupeKey: string;
|
|
16
|
+
readonly hasMore: boolean;
|
|
17
|
+
readonly outputs: Readonly<Record<string, JsonValue>> | null;
|
|
18
|
+
}
|
|
19
|
+
export interface ListenerSource {
|
|
20
|
+
readonly intervalMs: number;
|
|
21
|
+
readonly read: (context: ListenerReadContext) => Promise<ListenerPage>;
|
|
22
|
+
}
|
|
23
|
+
export declare function validateListenerPage(value: unknown): asserts value is ListenerPage;
|
|
5
24
|
export type IntegrationReceiveResult = {
|
|
25
|
+
readonly outcome: 'wake';
|
|
26
|
+
} | {
|
|
6
27
|
readonly checkpoint?: JsonValue;
|
|
7
28
|
readonly continue?: boolean;
|
|
8
29
|
readonly dedupeKey?: string;
|
|
9
30
|
readonly outcome: 'event';
|
|
10
|
-
readonly
|
|
31
|
+
readonly outputs: Readonly<Record<string, JsonValue>>;
|
|
11
32
|
} | {
|
|
12
33
|
readonly checkpoint?: JsonValue;
|
|
13
34
|
readonly continue?: boolean;
|
|
@@ -27,6 +48,8 @@ export interface IntegrationStateContext {
|
|
|
27
48
|
readonly saveSubscription: (subscription: Readonly<Record<string, JsonValue>>, reconcileAt: Date) => Promise<void>;
|
|
28
49
|
}
|
|
29
50
|
export interface IntegrationReceiveContext {
|
|
51
|
+
readonly eventSourceId?: string;
|
|
52
|
+
readonly signal?: AbortSignal;
|
|
30
53
|
readonly admit: boolean;
|
|
31
54
|
readonly allow?: () => Promise<boolean>;
|
|
32
55
|
readonly bindingId: string;
|
|
@@ -57,6 +80,9 @@ export interface IntegrationReconcileResult {
|
|
|
57
80
|
readonly outcome: 'pending' | 'ready';
|
|
58
81
|
}
|
|
59
82
|
export interface IntegrationDefinition {
|
|
83
|
+
readonly eventSource?: 'feishu';
|
|
84
|
+
readonly configOptions?: (context: TriggerConfigOptionsContext) => Promise<readonly TriggerConfigOption[]>;
|
|
85
|
+
readonly listener?: ListenerSource;
|
|
60
86
|
readonly initialState?: {
|
|
61
87
|
readonly checkpoint: JsonValue;
|
|
62
88
|
readonly subscription: Readonly<Record<string, JsonValue>>;
|
|
@@ -82,7 +108,7 @@ export declare function integrationOccurrenceId(bindingId: string, runtimeVersio
|
|
|
82
108
|
export interface IntegrationConformanceFixture {
|
|
83
109
|
readonly config: Readonly<Record<string, JsonValue>>;
|
|
84
110
|
readonly connectionId: string;
|
|
85
|
-
readonly definition: Pick<IntegrationDefinition, 'initialState' | 'receive' | 'reconcile'>;
|
|
111
|
+
readonly definition: Pick<IntegrationDefinition, 'initialState' | 'listener' | 'receive' | 'reconcile'>;
|
|
86
112
|
readonly publishedAt: string;
|
|
87
113
|
}
|
|
88
114
|
export interface IntegrationConformanceState {
|
|
@@ -111,3 +137,4 @@ export interface IntegrationConformanceCase {
|
|
|
111
137
|
verify(harness: IntegrationConformanceHarness): Promise<void>;
|
|
112
138
|
}
|
|
113
139
|
export declare const integrationConformanceCases: readonly IntegrationConformanceCase[];
|
|
140
|
+
export declare const listenerConformanceCases: readonly IntegrationConformanceCase[];
|
|
@@ -18,32 +18,106 @@ function t(n, r) {
|
|
|
18
18
|
return n !== n && r !== r;
|
|
19
19
|
}
|
|
20
20
|
//#endregion
|
|
21
|
+
//#region src/base/common/json.ts
|
|
22
|
+
function n(e) {
|
|
23
|
+
if (e === null || typeof e == "boolean" || typeof e == "string") return !0;
|
|
24
|
+
if (typeof e == "number") return Number.isFinite(e);
|
|
25
|
+
if (typeof e != "object") return !1;
|
|
26
|
+
let t = /* @__PURE__ */ new Set(), n = [], r = e;
|
|
27
|
+
traversal: for (;;) {
|
|
28
|
+
let e, i;
|
|
29
|
+
if (Array.isArray(r)) {
|
|
30
|
+
if (i = r.length, e = Reflect.ownKeys(r), e.length != i + 1) return !1;
|
|
31
|
+
} else {
|
|
32
|
+
let t = Reflect.getPrototypeOf(r);
|
|
33
|
+
if (t != Object.prototype && t != null) return !1;
|
|
34
|
+
e = Reflect.ownKeys(r), i = void 0;
|
|
35
|
+
}
|
|
36
|
+
t.add(r);
|
|
37
|
+
let a = 0;
|
|
38
|
+
for (;;) {
|
|
39
|
+
if (a >= e.length) {
|
|
40
|
+
t.delete(r);
|
|
41
|
+
let o = n.pop();
|
|
42
|
+
if (o === void 0) return !0;
|
|
43
|
+
r = o.value, e = o.keys, i = o.arrayLength, a = o.index;
|
|
44
|
+
continue;
|
|
45
|
+
}
|
|
46
|
+
let o = e[a++];
|
|
47
|
+
if (i !== void 0) {
|
|
48
|
+
if (o == "length") continue;
|
|
49
|
+
if (typeof o != "string") return !1;
|
|
50
|
+
let e = Number(o);
|
|
51
|
+
if (!Number.isSafeInteger(e) || e < 0 || e >= i || String(e) != o) return !1;
|
|
52
|
+
} else if (typeof o != "string") return !1;
|
|
53
|
+
let s = Reflect.getOwnPropertyDescriptor(r, o);
|
|
54
|
+
if (s?.enumerable != 1 || !Object.hasOwn(s, "value")) return !1;
|
|
55
|
+
let c = s.value;
|
|
56
|
+
if (c !== null && typeof c != "boolean" && typeof c != "string") {
|
|
57
|
+
if (typeof c == "number") {
|
|
58
|
+
if (!Number.isFinite(c)) return !1;
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
61
|
+
if (typeof c != "object" || t.has(c)) return !1;
|
|
62
|
+
n.push({
|
|
63
|
+
value: r,
|
|
64
|
+
keys: e,
|
|
65
|
+
arrayLength: i,
|
|
66
|
+
index: a
|
|
67
|
+
}), r = c;
|
|
68
|
+
continue traversal;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
function r(e) {
|
|
74
|
+
try {
|
|
75
|
+
return n(e);
|
|
76
|
+
} catch {
|
|
77
|
+
return !1;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
function i(e) {
|
|
81
|
+
try {
|
|
82
|
+
return typeof e == "object" && !!e && !Array.isArray(e) && n(e);
|
|
83
|
+
} catch {
|
|
84
|
+
return !1;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
//#endregion
|
|
21
88
|
//#region src/trigger/common/integration.ts
|
|
22
|
-
var
|
|
89
|
+
var a = 65536, o = 5, s = /^\/v1\/integrations\/(endpoint_[0-9a-f]{32})$/, c = new TextEncoder();
|
|
90
|
+
function l(e) {
|
|
91
|
+
if (!i(e) || e.checkpoint == null || !r(e.checkpoint) || typeof e.hasMore != "boolean") throw TypeError("Listener page must contain a JSON checkpoint and a boolean hasMore.");
|
|
92
|
+
if (typeof e.dedupeKey != "string" || e.dedupeKey.length == 0 || c.encode(e.dedupeKey).byteLength > 1024) throw TypeError("Listener page identity must contain between 1 and 1024 bytes.");
|
|
93
|
+
if (e.outputs !== null && !i(e.outputs)) throw TypeError("Listener page outputs must be an object or null.");
|
|
94
|
+
if (c.encode(JSON.stringify(e.checkpoint)).byteLength > 65536) throw TypeError("Listener checkpoint exceeds 64 KiB.");
|
|
95
|
+
}
|
|
96
|
+
var u = class extends Error {
|
|
23
97
|
constructor(...e) {
|
|
24
98
|
super(...e), this.name = "IntegrationConnectionError";
|
|
25
99
|
}
|
|
26
|
-
},
|
|
100
|
+
}, d = class extends Error {
|
|
27
101
|
constructor(...e) {
|
|
28
102
|
super(...e), this.name = "PermanentIntegrationError";
|
|
29
103
|
}
|
|
30
|
-
},
|
|
104
|
+
}, f = class extends Error {
|
|
31
105
|
constructor(...e) {
|
|
32
106
|
super(...e), this.name = "TransientIntegrationError";
|
|
33
107
|
}
|
|
34
108
|
};
|
|
35
|
-
function
|
|
36
|
-
return
|
|
109
|
+
function p(e) {
|
|
110
|
+
return s.exec(e.pathname)?.[1];
|
|
37
111
|
}
|
|
38
|
-
async function
|
|
112
|
+
async function m(e, t) {
|
|
39
113
|
if (e == null || e.length == 0) throw TypeError("Integration callback key is required.");
|
|
40
|
-
let n = await crypto.subtle.importKey("raw",
|
|
114
|
+
let n = await crypto.subtle.importKey("raw", c.encode(e), {
|
|
41
115
|
hash: "SHA-256",
|
|
42
116
|
name: "HMAC"
|
|
43
|
-
}, !1, ["sign"]), r = new Uint8Array(await crypto.subtle.sign("HMAC", n,
|
|
117
|
+
}, !1, ["sign"]), r = new Uint8Array(await crypto.subtle.sign("HMAC", n, c.encode(`open-flow-integration/v1/${t}`)));
|
|
44
118
|
return btoa(String.fromCharCode(...r)).replaceAll("+", "-").replaceAll("/", "_").replaceAll("=", "");
|
|
45
119
|
}
|
|
46
|
-
async function
|
|
120
|
+
async function h(e, t, n, r) {
|
|
47
121
|
if (r == null) return `integration_${crypto.randomUUID().replaceAll("-", "")}`;
|
|
48
122
|
let i = JSON.stringify([
|
|
49
123
|
1,
|
|
@@ -53,9 +127,9 @@ async function d(e, t, n, r) {
|
|
|
53
127
|
n,
|
|
54
128
|
r
|
|
55
129
|
]);
|
|
56
|
-
return [...new Uint8Array(await crypto.subtle.digest("SHA-256",
|
|
130
|
+
return [...new Uint8Array(await crypto.subtle.digest("SHA-256", c.encode(i)))].map((e) => e.toString(16).padStart(2, "0")).join("");
|
|
57
131
|
}
|
|
58
|
-
var
|
|
132
|
+
var g = {
|
|
59
133
|
config: { source: "primary" },
|
|
60
134
|
connectionId: "connection-primary",
|
|
61
135
|
definition: {
|
|
@@ -70,7 +144,7 @@ var f = {
|
|
|
70
144
|
outcome: "respond",
|
|
71
145
|
status: 404
|
|
72
146
|
};
|
|
73
|
-
let t =
|
|
147
|
+
let t = C(e.payload);
|
|
74
148
|
if (t?.action == "handshake") return {
|
|
75
149
|
body: "accepted",
|
|
76
150
|
contentType: "text/plain",
|
|
@@ -83,50 +157,50 @@ var f = {
|
|
|
83
157
|
reason: "Conformance delivery was ignored."
|
|
84
158
|
};
|
|
85
159
|
if (t?.action == "pages") {
|
|
86
|
-
let n =
|
|
160
|
+
let n = C(e.state?.checkpoint), r = typeof n?.page == "number" ? n.page + 1 : 1, i = typeof t.pages == "number" ? t.pages : 1, a = typeof t.deliveryId == "string" ? t.deliveryId : "pages";
|
|
87
161
|
return {
|
|
88
162
|
checkpoint: { page: r },
|
|
89
163
|
continue: r < i,
|
|
90
164
|
dedupeKey: `${a}:${r}`,
|
|
91
165
|
outcome: "event",
|
|
92
|
-
payload: {
|
|
166
|
+
outputs: { payload: {
|
|
93
167
|
body: { page: r },
|
|
94
168
|
deliveryId: a,
|
|
95
169
|
event: "conformance"
|
|
96
|
-
}
|
|
170
|
+
} }
|
|
97
171
|
};
|
|
98
172
|
}
|
|
99
|
-
let n = typeof t?.deliveryId == "string" ? t.deliveryId : "delivery", r =
|
|
173
|
+
let n = typeof t?.deliveryId == "string" ? t.deliveryId : "delivery", r = C(t?.body) ?? {};
|
|
100
174
|
return {
|
|
101
175
|
checkpoint: { deliveryId: n },
|
|
102
176
|
dedupeKey: n,
|
|
103
177
|
outcome: "event",
|
|
104
|
-
payload: {
|
|
178
|
+
outputs: { payload: {
|
|
105
179
|
body: r,
|
|
106
180
|
deliveryId: n,
|
|
107
181
|
event: "conformance"
|
|
108
|
-
}
|
|
182
|
+
} }
|
|
109
183
|
};
|
|
110
184
|
},
|
|
111
185
|
async reconcile(e) {
|
|
112
|
-
if (e.state == null) throw new
|
|
186
|
+
if (e.state == null) throw new d("Conformance Integration state is missing.");
|
|
113
187
|
return await e.state.saveSubscription(e.active ? { endpointUrl: e.endpointUrl } : {}, new Date(e.now.getTime() + 6e4)), { outcome: "ready" };
|
|
114
188
|
}
|
|
115
189
|
},
|
|
116
190
|
publishedAt: "2026-08-21T00:00:30.000Z"
|
|
117
|
-
},
|
|
191
|
+
}, _ = [
|
|
118
192
|
{
|
|
119
|
-
fixture:
|
|
193
|
+
fixture: g,
|
|
120
194
|
name: "enforces callback routing, method, body, and handshake boundaries",
|
|
121
195
|
async verify(e) {
|
|
122
196
|
let t = new URL(e.endpointUrl);
|
|
123
|
-
await
|
|
197
|
+
await w(await b(e, { url: new URL("/v1/integrations/not-an-endpoint", t).href }), { status: 404 }, "Malformed endpoint"), await w(await b(e, { url: new URL("/v1/integrations/endpoint_00000000000000000000000000000000", t).href }), { status: 404 }, "Unknown endpoint"), await w(await b(e, { method: "GET" }), {
|
|
124
198
|
headers: { allow: "POST" },
|
|
125
199
|
status: 405
|
|
126
|
-
}, "Method"), await
|
|
200
|
+
}, "Method"), await w(await b(e, { body: "{" }), { status: 400 }, "Invalid JSON"), await w(await b(e, {
|
|
127
201
|
body: "a=1",
|
|
128
202
|
headers: { "content-type": "application/x-www-form-urlencoded" }
|
|
129
|
-
}), { status: 400 }, "Unsupported body format"), await
|
|
203
|
+
}), { status: 400 }, "Unsupported body format"), await w(await b(e, { body: "x".repeat(65537) }), { status: 413 }, "Oversized body"), await w(await x(e, { action: "handshake" }), {
|
|
130
204
|
body: "accepted",
|
|
131
205
|
headers: {
|
|
132
206
|
"content-type": "text/plain",
|
|
@@ -137,18 +211,18 @@ var f = {
|
|
|
137
211
|
}
|
|
138
212
|
},
|
|
139
213
|
{
|
|
140
|
-
fixture:
|
|
214
|
+
fixture: g,
|
|
141
215
|
name: "verifies initializing callbacks before activating the subscription",
|
|
142
216
|
async verify(e) {
|
|
143
|
-
await
|
|
217
|
+
await w(await x(e, {
|
|
144
218
|
action: "event",
|
|
145
219
|
body: { value: "before" },
|
|
146
220
|
deliveryId: "before"
|
|
147
|
-
}, !1), { status: 404 }, "Secret"), await
|
|
221
|
+
}, !1), { status: 404 }, "Secret"), await w(await x(e, {
|
|
148
222
|
action: "event",
|
|
149
223
|
body: { value: "before" },
|
|
150
224
|
deliveryId: "before"
|
|
151
|
-
}), { status: 202 }, "Initializing delivery"),
|
|
225
|
+
}), { status: 202 }, "Initializing delivery"), S(await e.state(), {
|
|
152
226
|
checkpoint: null,
|
|
153
227
|
health: "initializing",
|
|
154
228
|
payloads: [],
|
|
@@ -156,7 +230,7 @@ var f = {
|
|
|
156
230
|
reconcileCalls: 0,
|
|
157
231
|
runtimeVersion: 1,
|
|
158
232
|
subscription: {}
|
|
159
|
-
}, "Initializing state"), await e.reconcile("2026-08-21T00:00:31.000Z"),
|
|
233
|
+
}, "Initializing state"), await e.reconcile("2026-08-21T00:00:31.000Z"), S(await e.state(), {
|
|
160
234
|
checkpoint: null,
|
|
161
235
|
health: "healthy",
|
|
162
236
|
payloads: [],
|
|
@@ -168,7 +242,7 @@ var f = {
|
|
|
168
242
|
}
|
|
169
243
|
},
|
|
170
244
|
{
|
|
171
|
-
fixture:
|
|
245
|
+
fixture: g,
|
|
172
246
|
name: "deduplicates keyed events and rejects conflicting payloads",
|
|
173
247
|
async verify(e) {
|
|
174
248
|
await e.reconcile("2026-08-21T00:00:31.000Z");
|
|
@@ -177,12 +251,12 @@ var f = {
|
|
|
177
251
|
body: { value: "first" },
|
|
178
252
|
deliveryId: "delivery-1"
|
|
179
253
|
};
|
|
180
|
-
await
|
|
254
|
+
await w(await x(e, t), { status: 202 }, "Initial event"), await w(await x(e, t), { status: 202 }, "Repeated event"), await w(await x(e, {
|
|
181
255
|
...t,
|
|
182
256
|
body: { value: "changed" }
|
|
183
257
|
}), { status: 409 }, "Conflicting event");
|
|
184
258
|
let n = await e.state();
|
|
185
|
-
|
|
259
|
+
S(n.checkpoint, { deliveryId: "delivery-1" }, "Event checkpoint"), S(n.payloads, [{
|
|
186
260
|
body: { value: "first" },
|
|
187
261
|
deliveryId: "delivery-1",
|
|
188
262
|
event: "conformance"
|
|
@@ -190,7 +264,7 @@ var f = {
|
|
|
190
264
|
}
|
|
191
265
|
},
|
|
192
266
|
{
|
|
193
|
-
fixture:
|
|
267
|
+
fixture: g,
|
|
194
268
|
name: "bounds callback pages and resumes from the durable checkpoint",
|
|
195
269
|
async verify(e) {
|
|
196
270
|
await e.reconcile("2026-08-21T00:00:31.000Z");
|
|
@@ -199,26 +273,26 @@ var f = {
|
|
|
199
273
|
deliveryId: "delivery-pages",
|
|
200
274
|
pages: 7
|
|
201
275
|
};
|
|
202
|
-
await
|
|
276
|
+
await w(await x(e, t), { status: 202 }, "First page batch");
|
|
203
277
|
let n = await e.state();
|
|
204
|
-
|
|
278
|
+
S(n.checkpoint, { page: 5 }, "Bounded checkpoint"), S(n.payloads.length, 5, "Bounded payload count"), await w(await x(e, t), { status: 202 }, "Resumed page batch"), n = await e.state(), S(n.checkpoint, { page: 7 }, "Resumed checkpoint"), S(n.payloads.length, 7, "Resumed payload count");
|
|
205
279
|
}
|
|
206
280
|
},
|
|
207
281
|
{
|
|
208
|
-
fixture:
|
|
282
|
+
fixture: g,
|
|
209
283
|
name: "restores subscription state and callback admission after restart",
|
|
210
284
|
async verify(e) {
|
|
211
|
-
await e.reconcile("2026-08-21T00:00:31.000Z"), await
|
|
285
|
+
await e.reconcile("2026-08-21T00:00:31.000Z"), await x(e, {
|
|
212
286
|
action: "event",
|
|
213
287
|
body: { value: "before" },
|
|
214
288
|
deliveryId: "before"
|
|
215
|
-
}), await e.restart(), await
|
|
289
|
+
}), await e.restart(), await x(e, {
|
|
216
290
|
action: "event",
|
|
217
291
|
body: { value: "after" },
|
|
218
292
|
deliveryId: "after"
|
|
219
293
|
});
|
|
220
294
|
let t = await e.state();
|
|
221
|
-
|
|
295
|
+
S(t.checkpoint, { deliveryId: "after" }, "Restart checkpoint"), S(t.payloads, [{
|
|
222
296
|
body: { value: "before" },
|
|
223
297
|
deliveryId: "before",
|
|
224
298
|
event: "conformance"
|
|
@@ -230,7 +304,7 @@ var f = {
|
|
|
230
304
|
}
|
|
231
305
|
},
|
|
232
306
|
{
|
|
233
|
-
fixture:
|
|
307
|
+
fixture: g,
|
|
234
308
|
name: "retires the old runtime before activating a republished target",
|
|
235
309
|
async verify(e) {
|
|
236
310
|
await e.reconcile("2026-08-21T00:00:31.000Z");
|
|
@@ -239,28 +313,90 @@ var f = {
|
|
|
239
313
|
body: { value: "event" },
|
|
240
314
|
deliveryId: "same-delivery"
|
|
241
315
|
};
|
|
242
|
-
await
|
|
316
|
+
await x(e, t);
|
|
243
317
|
let n = e.endpointUrl;
|
|
244
|
-
await e.republish("2026-08-21T00:00:40.000Z"),
|
|
318
|
+
await e.republish("2026-08-21T00:00:40.000Z"), S(e.endpointUrl, n, "Republished endpoint"), await w(await x(e, t), { status: 202 }, "Old runtime delivery"), S((await e.state()).payloads.length, 1, "Old runtime payload count"), await e.reconcile("2026-08-21T00:00:41.000Z"), await w(await x(e, t), { status: 202 }, "New runtime delivery");
|
|
245
319
|
let r = await e.state();
|
|
246
|
-
|
|
320
|
+
S(r.runtimeVersion, 2, "Republished runtime"), S(r.health, "healthy", "Republished health"), S(r.payloads.length, 2, "Republished payload count");
|
|
247
321
|
}
|
|
248
322
|
},
|
|
249
323
|
{
|
|
250
|
-
fixture:
|
|
324
|
+
fixture: g,
|
|
251
325
|
name: "retires the remote subscription and rejects later callbacks",
|
|
252
326
|
async verify(e) {
|
|
253
|
-
await e.reconcile("2026-08-21T00:00:31.000Z"), await e.retire("2026-08-21T00:00:40.000Z"), await
|
|
327
|
+
await e.reconcile("2026-08-21T00:00:31.000Z"), await e.retire("2026-08-21T00:00:40.000Z"), await w(await x(e, {
|
|
254
328
|
action: "event",
|
|
255
329
|
deliveryId: "retired"
|
|
256
|
-
}), { status: 404 }, "Retired callback"), await e.reconcile("2026-08-21T00:00:41.000Z"), await
|
|
330
|
+
}), { status: 404 }, "Retired callback"), await e.reconcile("2026-08-21T00:00:41.000Z"), await w(await x(e, {
|
|
257
331
|
action: "event",
|
|
258
332
|
deliveryId: "retired"
|
|
259
|
-
}), { status: 404 }, "Reconciled retirement"),
|
|
333
|
+
}), { status: 404 }, "Reconciled retirement"), S((await e.state()).payloads, [], "Retired payloads");
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
], v = {
|
|
337
|
+
...g,
|
|
338
|
+
definition: {
|
|
339
|
+
initialState: {
|
|
340
|
+
checkpoint: null,
|
|
341
|
+
subscription: {}
|
|
342
|
+
},
|
|
343
|
+
async reconcile({ active: e, state: t, now: n }) {
|
|
344
|
+
return e && t?.checkpoint == null && await t.saveCheckpoint(0), e && await t.saveSubscription({}, new Date(n.getTime() + 36e5)), { outcome: "ready" };
|
|
345
|
+
},
|
|
346
|
+
receive(e) {
|
|
347
|
+
return e.header("x-integration-secret") == e.callbackSecret ? { outcome: "wake" } : {
|
|
348
|
+
outcome: "respond",
|
|
349
|
+
status: 404,
|
|
350
|
+
body: "",
|
|
351
|
+
contentType: "text/plain"
|
|
352
|
+
};
|
|
353
|
+
},
|
|
354
|
+
listener: {
|
|
355
|
+
intervalMs: 6e4,
|
|
356
|
+
async read({ checkpoint: e, now: t }) {
|
|
357
|
+
let n = Number(e), r = t.getTime() >= Date.parse("2026-08-21T00:01:31.000Z") ? 8 : 7;
|
|
358
|
+
return n < r ? {
|
|
359
|
+
checkpoint: n + 1,
|
|
360
|
+
dedupeKey: String(n),
|
|
361
|
+
hasMore: n + 1 < r,
|
|
362
|
+
outputs: { payload: {
|
|
363
|
+
body: {},
|
|
364
|
+
deliveryId: String(n),
|
|
365
|
+
event: "change"
|
|
366
|
+
} }
|
|
367
|
+
} : {
|
|
368
|
+
checkpoint: e,
|
|
369
|
+
dedupeKey: String(n),
|
|
370
|
+
hasMore: !1,
|
|
371
|
+
outputs: null
|
|
372
|
+
};
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
}, y = [
|
|
377
|
+
{
|
|
378
|
+
fixture: v,
|
|
379
|
+
name: "drains listener pages without a callback and resumes periodic scanning after restart",
|
|
380
|
+
async verify(e) {
|
|
381
|
+
await e.reconcile("2026-08-21T00:00:31.000Z"), S((await e.state()).checkpoint, 7, "Drained cursor"), S((await e.state()).payloads.length, 7, "Drained pages"), await e.restart(), await e.reconcile("2026-08-21T00:01:31.000Z"), S((await e.state()).checkpoint, 8, "Periodic cursor"), S((await e.state()).payloads.length, 8, "Periodic pages");
|
|
382
|
+
}
|
|
383
|
+
},
|
|
384
|
+
{
|
|
385
|
+
fixture: v,
|
|
386
|
+
name: "persists verified listener wakes across restart without duplicating accepted pages",
|
|
387
|
+
async verify(e) {
|
|
388
|
+
await e.reconcile("2026-08-21T00:00:31.000Z"), await w(await x(e, {}, !1), { status: 404 }, "Invalid wake"), await w(await x(e, {}), { status: 202 }, "First wake"), await w(await x(e, {}), { status: 202 }, "Duplicate wake"), await e.restart(), await e.reconcile("2026-08-21T00:00:32.000Z"), S((await e.state()).checkpoint, 7, "Retained cursor"), S((await e.state()).payloads.length, 7, "Deduplicated pages");
|
|
389
|
+
}
|
|
390
|
+
},
|
|
391
|
+
{
|
|
392
|
+
fixture: v,
|
|
393
|
+
name: "preserves a listener cursor on unchanged publication and fences retirement",
|
|
394
|
+
async verify(e) {
|
|
395
|
+
await e.reconcile("2026-08-21T00:00:31.000Z"), await e.republish("2026-08-21T00:00:40.000Z"), S((await e.state()).checkpoint, 7, "Republished cursor"), await e.reconcile("2026-08-21T00:01:31.000Z"), S((await e.state()).payloads.length, 8, "Republished pages"), await e.retire("2026-08-21T00:01:40.000Z"), await w(await x(e, {}), { status: 404 }, "Retired wake"), await e.reconcile("2026-08-21T00:02:40.000Z"), S((await e.state()).payloads.length, 8, "Retired pages");
|
|
260
396
|
}
|
|
261
397
|
}
|
|
262
398
|
];
|
|
263
|
-
function
|
|
399
|
+
function b(e, t = {}) {
|
|
264
400
|
return e.request(new Request(t.url ?? e.endpointUrl, {
|
|
265
401
|
...t.body == null ? {} : { body: t.body },
|
|
266
402
|
headers: {
|
|
@@ -270,21 +406,21 @@ function m(e, t = {}) {
|
|
|
270
406
|
method: t.method ?? "POST"
|
|
271
407
|
}));
|
|
272
408
|
}
|
|
273
|
-
function
|
|
274
|
-
return
|
|
409
|
+
function x(e, t, n = !0) {
|
|
410
|
+
return b(e, {
|
|
275
411
|
body: JSON.stringify(t),
|
|
276
412
|
headers: n ? { "x-integration-secret": e.callbackSecret } : {}
|
|
277
413
|
});
|
|
278
414
|
}
|
|
279
|
-
function
|
|
415
|
+
function S(e, n, r) {
|
|
280
416
|
if (!t(e, n)) throw Error(`${r}: expected ${JSON.stringify(n)}, received ${JSON.stringify(e)}.`);
|
|
281
417
|
}
|
|
282
|
-
function
|
|
418
|
+
function C(e) {
|
|
283
419
|
return typeof e == "object" && e && !Array.isArray(e) ? e : void 0;
|
|
284
420
|
}
|
|
285
|
-
async function
|
|
286
|
-
|
|
287
|
-
for (let [r, i] of Object.entries(t.headers ?? {}))
|
|
421
|
+
async function w(e, t, n) {
|
|
422
|
+
S(e.status, t.status, `${n} status`), t.body != null && S(await e.text(), t.body, `${n} body`);
|
|
423
|
+
for (let [r, i] of Object.entries(t.headers ?? {})) S(e.headers.get(r), i, `${n} header ${r}`);
|
|
288
424
|
}
|
|
289
425
|
//#endregion
|
|
290
|
-
export {
|
|
426
|
+
export { u as IntegrationConnectionError, d as PermanentIntegrationError, f as TransientIntegrationError, m as integrationCallbackSecret, _ as integrationConformanceCases, p as integrationEndpointId, h as integrationOccurrenceId, y as listenerConformanceCases, a as maximumIntegrationBodyBytes, o as maximumIntegrationDeliveryPages, l as validateListenerPage };
|