@aglyn/plugins-workflows 1.0.0-beta.143
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 +201 -0
- package/README.md +52 -0
- package/package.json +53 -0
- package/src/index.d.ts +18 -0
- package/src/index.js +19 -0
- package/src/index.js.map +1 -0
- package/src/lib/components/automation-step-fields.component.d.ts +74 -0
- package/src/lib/components/automation-step-fields.component.js +1210 -0
- package/src/lib/components/automation-step-fields.component.js.map +1 -0
- package/src/lib/components/host-actions-card.component.d.ts +15 -0
- package/src/lib/components/host-actions-card.component.js +1229 -0
- package/src/lib/components/host-actions-card.component.js.map +1 -0
- package/src/lib/components/host-activity-card.component.d.ts +84 -0
- package/src/lib/components/host-activity-card.component.js +280 -0
- package/src/lib/components/host-activity-card.component.js.map +1 -0
- package/src/lib/components/host-run-history-card.component.d.ts +40 -0
- package/src/lib/components/host-run-history-card.component.js +284 -0
- package/src/lib/components/host-run-history-card.component.js.map +1 -0
- package/src/lib/components/host-webhooks-card.component.d.ts +15 -0
- package/src/lib/components/host-webhooks-card.component.js +421 -0
- package/src/lib/components/host-webhooks-card.component.js.map +1 -0
- package/src/lib/components/host-workflows-card.component.d.ts +18 -0
- package/src/lib/components/host-workflows-card.component.js +952 -0
- package/src/lib/components/host-workflows-card.component.js.map +1 -0
- package/src/lib/components/run-quota-line.component.d.ts +27 -0
- package/src/lib/components/run-quota-line.component.js +72 -0
- package/src/lib/components/run-quota-line.component.js.map +1 -0
- package/src/lib/components/use-automation-step-pickers.d.ts +27 -0
- package/src/lib/components/use-automation-step-pickers.js +205 -0
- package/src/lib/components/use-automation-step-pickers.js.map +1 -0
- package/src/lib/components/workflow-zones.d.ts +36 -0
- package/src/lib/components/workflow-zones.js +19 -0
- package/src/lib/components/workflow-zones.js.map +1 -0
- package/src/lib/components/workflows-console-page.d.ts +25 -0
- package/src/lib/components/workflows-console-page.js +112 -0
- package/src/lib/components/workflows-console-page.js.map +1 -0
- package/src/lib/components/workflows-console-sections.d.ts +34 -0
- package/src/lib/components/workflows-console-sections.js +50 -0
- package/src/lib/components/workflows-console-sections.js.map +1 -0
- package/src/lib/constants/bundle-common.d.ts +8 -0
- package/src/lib/constants/bundle-common.js +9 -0
- package/src/lib/constants/bundle-common.js.map +1 -0
- package/src/lib/declarations.server.d.ts +41 -0
- package/src/lib/declarations.server.js +54 -0
- package/src/lib/declarations.server.js.map +1 -0
- package/src/lib/engine/crm-action-steps.d.ts +129 -0
- package/src/lib/engine/crm-action-steps.js +432 -0
- package/src/lib/engine/crm-action-steps.js.map +1 -0
- package/src/lib/engine/flow-enrollments.d.ts +264 -0
- package/src/lib/engine/flow-enrollments.js +386 -0
- package/src/lib/engine/flow-enrollments.js.map +1 -0
- package/src/lib/engine/run-event-actions.d.ts +232 -0
- package/src/lib/engine/run-event-actions.js +1392 -0
- package/src/lib/engine/run-event-actions.js.map +1 -0
- package/src/lib/engine/run-event-automations.d.ts +28 -0
- package/src/lib/engine/run-event-automations.js +37 -0
- package/src/lib/engine/run-event-automations.js.map +1 -0
- package/src/lib/engine/run-event-workflows.d.ts +75 -0
- package/src/lib/engine/run-event-workflows.js +311 -0
- package/src/lib/engine/run-event-workflows.js.map +1 -0
- package/src/lib/engine/workflow-steps.d.ts +107 -0
- package/src/lib/engine/workflow-steps.js +124 -0
- package/src/lib/engine/workflow-steps.js.map +1 -0
- package/src/lib/plugin.d.ts +33 -0
- package/src/lib/plugin.js +94 -0
- package/src/lib/plugin.js.map +1 -0
- package/src/lib/server-automation-drafts.d.ts +90 -0
- package/src/lib/server-automation-drafts.js +429 -0
- package/src/lib/server-automation-drafts.js.map +1 -0
- package/src/lib/server-console.d.ts +27 -0
- package/src/lib/server-console.js +35 -0
- package/src/lib/server-console.js.map +1 -0
- package/src/lib/server.d.ts +29 -0
- package/src/lib/server.js +298 -0
- package/src/lib/server.js.map +1 -0
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { ConsolePluginPageProps } from '@aglyn/aglyn';
|
|
2
|
+
/**
|
|
3
|
+
* Automation page (AGL-101/148/149 → AGL-395): the automation surface —
|
|
4
|
+
* workflow builder, event-triggered actions, and webhooks — owned by the
|
|
5
|
+
* workflows plugin and rendered by the shell's generic plugin route. Each card
|
|
6
|
+
* runs its own entitlement check (workflows / actions / webhooks are distinct
|
|
7
|
+
* plan flags), so the shell's resolved `org` doc flows into all three.
|
|
8
|
+
*
|
|
9
|
+
* Sections are ROUTES (AGL-2501). `HubTabs lazy` already mounted one panel, so
|
|
10
|
+
* this is not a read saving — `workflows-console-read-cost.spec.tsx` was
|
|
11
|
+
* written BEFORE the conversion precisely to hold that line, and reports the
|
|
12
|
+
* same counts after. What routing adds is that the URL names the section: it is
|
|
13
|
+
* linkable, the back button walks sections, the breadcrumb says where you are,
|
|
14
|
+
* and "mount only what is open" is structural rather than a `lazy` flag.
|
|
15
|
+
*
|
|
16
|
+
* The section ids are unchanged by the Automation rename: they are the
|
|
17
|
+
* addresses people bookmark and the docs link to. A workflow belongs to the
|
|
18
|
+
* site and an ACTION belongs to the site too; an interaction belongs to the
|
|
19
|
+
* document that holds it and is edited on the element, not here.
|
|
20
|
+
*/
|
|
21
|
+
export declare function WorkflowsConsolePage(props: ConsolePluginPageProps): import("react").JSX.Element;
|
|
22
|
+
export declare namespace WorkflowsConsolePage {
|
|
23
|
+
var displayName: string;
|
|
24
|
+
}
|
|
25
|
+
export default WorkflowsConsolePage;
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Aglyn LLC
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/ 'use client';
|
|
17
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
18
|
+
import { HubSections } from "@aglyn/shared-ui-next";
|
|
19
|
+
import { Stack } from "@mui/material";
|
|
20
|
+
import HostActionsCard from "./host-actions-card.component.js";
|
|
21
|
+
import HostWebhooksCard from "./host-webhooks-card.component.js";
|
|
22
|
+
import HostWorkflowsCard from "./host-workflows-card.component.js";
|
|
23
|
+
import RunQuotaLine from "./run-quota-line.component.js";
|
|
24
|
+
/**
|
|
25
|
+
* The body of one workflows section, built only when that section is the one
|
|
26
|
+
* being read (AGL-2501).
|
|
27
|
+
*
|
|
28
|
+
* A function rather than a map of nodes on purpose: a `Record<id, ReactNode>`
|
|
29
|
+
* would CONSTRUCT all three every render, and each card opens its Firestore
|
|
30
|
+
* listens on mount — which is the entire cost this page exists to stop paying.
|
|
31
|
+
* Only the returned branch is ever built.
|
|
32
|
+
*/ function sectionBody(section, hostId, org) {
|
|
33
|
+
switch(section){
|
|
34
|
+
case 'workflows':
|
|
35
|
+
return(/*
|
|
36
|
+
* `N runs this month · M included` (AGL-2171), which the run-history
|
|
37
|
+
* mockup puts opposite the heading. The quota silently stops
|
|
38
|
+
* automations running once it is reached, and the only place it was
|
|
39
|
+
* reported was the Billing page.
|
|
40
|
+
*/ /*#__PURE__*/ _jsxs(Stack, {
|
|
41
|
+
spacing: 1,
|
|
42
|
+
children: [
|
|
43
|
+
/*#__PURE__*/ _jsx(RunQuotaLine, {
|
|
44
|
+
hostId: hostId,
|
|
45
|
+
org: org,
|
|
46
|
+
counter: "workflowRuns"
|
|
47
|
+
}),
|
|
48
|
+
/*#__PURE__*/ _jsx(HostWorkflowsCard, {
|
|
49
|
+
hostId: hostId,
|
|
50
|
+
org: org
|
|
51
|
+
})
|
|
52
|
+
]
|
|
53
|
+
}));
|
|
54
|
+
case 'actions':
|
|
55
|
+
return /*#__PURE__*/ _jsxs(Stack, {
|
|
56
|
+
spacing: 1,
|
|
57
|
+
children: [
|
|
58
|
+
/*#__PURE__*/ _jsx(RunQuotaLine, {
|
|
59
|
+
hostId: hostId,
|
|
60
|
+
org: org,
|
|
61
|
+
counter: "actionRuns"
|
|
62
|
+
}),
|
|
63
|
+
/*#__PURE__*/ _jsx(HostActionsCard, {
|
|
64
|
+
hostId: hostId,
|
|
65
|
+
org: org
|
|
66
|
+
})
|
|
67
|
+
]
|
|
68
|
+
});
|
|
69
|
+
case 'webhooks':
|
|
70
|
+
return /*#__PURE__*/ _jsx(HostWebhooksCard, {
|
|
71
|
+
hostId: hostId,
|
|
72
|
+
org: org
|
|
73
|
+
});
|
|
74
|
+
default:
|
|
75
|
+
return null;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Automation page (AGL-101/148/149 → AGL-395): the automation surface —
|
|
80
|
+
* workflow builder, event-triggered actions, and webhooks — owned by the
|
|
81
|
+
* workflows plugin and rendered by the shell's generic plugin route. Each card
|
|
82
|
+
* runs its own entitlement check (workflows / actions / webhooks are distinct
|
|
83
|
+
* plan flags), so the shell's resolved `org` doc flows into all three.
|
|
84
|
+
*
|
|
85
|
+
* Sections are ROUTES (AGL-2501). `HubTabs lazy` already mounted one panel, so
|
|
86
|
+
* this is not a read saving — `workflows-console-read-cost.spec.tsx` was
|
|
87
|
+
* written BEFORE the conversion precisely to hold that line, and reports the
|
|
88
|
+
* same counts after. What routing adds is that the URL names the section: it is
|
|
89
|
+
* linkable, the back button walks sections, the breadcrumb says where you are,
|
|
90
|
+
* and "mount only what is open" is structural rather than a `lazy` flag.
|
|
91
|
+
*
|
|
92
|
+
* The section ids are unchanged by the Automation rename: they are the
|
|
93
|
+
* addresses people bookmark and the docs link to. A workflow belongs to the
|
|
94
|
+
* site and an ACTION belongs to the site too; an interaction belongs to the
|
|
95
|
+
* document that holds it and is edited on the element, not here.
|
|
96
|
+
*/ export function WorkflowsConsolePage(props) {
|
|
97
|
+
const { hostId, org, section, sections, basePath } = props;
|
|
98
|
+
/*
|
|
99
|
+
* Nothing until the URL names a section. The shell redirects a bare hub URL
|
|
100
|
+
* to the landing section and holds a spinner while it does, so this state is
|
|
101
|
+
* transient — and rendering a default section here instead would pay for its
|
|
102
|
+
* listens on a URL that is already being replaced.
|
|
103
|
+
*/ if (!section || !(sections == null ? void 0 : sections.length) || !basePath) return null;
|
|
104
|
+
return /*#__PURE__*/ _jsx(HubSections, {
|
|
105
|
+
sections: sections,
|
|
106
|
+
children: sectionBody(section, hostId, org)
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
WorkflowsConsolePage.displayName = 'WorkflowsConsolePage';
|
|
110
|
+
export default WorkflowsConsolePage;
|
|
111
|
+
|
|
112
|
+
//# sourceMappingURL=workflows-console-page.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../../libs/plugins/workflows/src/lib/components/workflows-console-page.tsx"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n'use client'\n\nimport type { AglynOrgBilling, ConsolePluginPageProps } from '@aglyn/aglyn'\nimport { HubSections } from '@aglyn/shared-ui-next'\nimport { Stack } from '@mui/material'\nimport type { ReactNode } from 'react'\nimport HostActionsCard from './host-actions-card.component'\nimport HostWebhooksCard from './host-webhooks-card.component'\nimport HostWorkflowsCard from './host-workflows-card.component'\nimport RunQuotaLine from './run-quota-line.component'\nimport type { WorkflowsConsoleSectionId } from './workflows-console-sections'\n\n/**\n * The body of one workflows section, built only when that section is the one\n * being read (AGL-2501).\n *\n * A function rather than a map of nodes on purpose: a `Record<id, ReactNode>`\n * would CONSTRUCT all three every render, and each card opens its Firestore\n * listens on mount — which is the entire cost this page exists to stop paying.\n * Only the returned branch is ever built.\n */\nfunction sectionBody(\n section: WorkflowsConsoleSectionId,\n hostId: string,\n org: Partial<AglynOrgBilling> | undefined,\n): ReactNode {\n switch (section) {\n case 'workflows':\n return (\n /*\n * `N runs this month · M included` (AGL-2171), which the run-history\n * mockup puts opposite the heading. The quota silently stops\n * automations running once it is reached, and the only place it was\n * reported was the Billing page.\n */\n <Stack spacing={1}>\n <RunQuotaLine hostId={hostId} org={org} counter=\"workflowRuns\" />\n <HostWorkflowsCard hostId={hostId} org={org} />\n </Stack>\n )\n case 'actions':\n return (\n <Stack spacing={1}>\n {/* `actionRunsPerMonth` had NO customer-facing surface at all\n before this — staff panel and usage-alerts only. */}\n <RunQuotaLine hostId={hostId} org={org} counter=\"actionRuns\" />\n <HostActionsCard hostId={hostId} org={org} />\n </Stack>\n )\n case 'webhooks':\n return <HostWebhooksCard hostId={hostId} org={org} />\n default:\n return null\n }\n}\n\n/**\n * Automation page (AGL-101/148/149 → AGL-395): the automation surface —\n * workflow builder, event-triggered actions, and webhooks — owned by the\n * workflows plugin and rendered by the shell's generic plugin route. Each card\n * runs its own entitlement check (workflows / actions / webhooks are distinct\n * plan flags), so the shell's resolved `org` doc flows into all three.\n *\n * Sections are ROUTES (AGL-2501). `HubTabs lazy` already mounted one panel, so\n * this is not a read saving — `workflows-console-read-cost.spec.tsx` was\n * written BEFORE the conversion precisely to hold that line, and reports the\n * same counts after. What routing adds is that the URL names the section: it is\n * linkable, the back button walks sections, the breadcrumb says where you are,\n * and \"mount only what is open\" is structural rather than a `lazy` flag.\n *\n * The section ids are unchanged by the Automation rename: they are the\n * addresses people bookmark and the docs link to. A workflow belongs to the\n * site and an ACTION belongs to the site too; an interaction belongs to the\n * document that holds it and is edited on the element, not here.\n */\nexport function WorkflowsConsolePage(props: ConsolePluginPageProps) {\n const { hostId, org, section, sections, basePath } = props\n\n /*\n * Nothing until the URL names a section. The shell redirects a bare hub URL\n * to the landing section and holds a spinner while it does, so this state is\n * transient — and rendering a default section here instead would pay for its\n * listens on a URL that is already being replaced.\n */\n if (!section || !sections?.length || !basePath) return null\n\n return (\n <HubSections sections={sections}>\n {sectionBody(section as WorkflowsConsoleSectionId, hostId, org)}\n </HubSections>\n )\n}\nWorkflowsConsolePage.displayName = 'WorkflowsConsolePage'\n\nexport default WorkflowsConsolePage\n"],"names":["HubSections","Stack","HostActionsCard","HostWebhooksCard","HostWorkflowsCard","RunQuotaLine","sectionBody","section","hostId","org","spacing","counter","WorkflowsConsolePage","props","sections","basePath","length","displayName"],"mappings":"AAAA;;;;;;;;;;;;;;;CAeC,GACD;;AAGA,SAASA,WAAW,QAAQ,wBAAuB;AACnD,SAASC,KAAK,QAAQ,gBAAe;AAErC,OAAOC,qBAAqB,mCAA+B;AAC3D,OAAOC,sBAAsB,oCAAgC;AAC7D,OAAOC,uBAAuB,qCAAiC;AAC/D,OAAOC,kBAAkB,gCAA4B;AAGrD;;;;;;;;CAQC,GACD,SAASC,YACPC,OAAkC,EAClCC,MAAc,EACdC,GAAyC;IAEzC,OAAQF;QACN,KAAK;YACH,OACE;;;;;SAKC,iBACD,MAACN;gBAAMS,SAAS;;kCACd,KAACL;wBAAaG,QAAQA;wBAAQC,KAAKA;wBAAKE,SAAQ;;kCAChD,KAACP;wBAAkBI,QAAQA;wBAAQC,KAAKA;;;;QAG9C,KAAK;YACH,qBACE,MAACR;gBAAMS,SAAS;;kCAGd,KAACL;wBAAaG,QAAQA;wBAAQC,KAAKA;wBAAKE,SAAQ;;kCAChD,KAACT;wBAAgBM,QAAQA;wBAAQC,KAAKA;;;;QAG5C,KAAK;YACH,qBAAO,KAACN;gBAAiBK,QAAQA;gBAAQC,KAAKA;;QAChD;YACE,OAAO;IACX;AACF;AAEA;;;;;;;;;;;;;;;;;;CAkBC,GACD,OAAO,SAASG,qBAAqBC,KAA6B;IAChE,MAAM,EAAEL,MAAM,EAAEC,GAAG,EAAEF,OAAO,EAAEO,QAAQ,EAAEC,QAAQ,EAAE,GAAGF;IAErD;;;;;GAKC,GACD,IAAI,CAACN,WAAW,EAACO,4BAAAA,SAAUE,MAAM,KAAI,CAACD,UAAU,OAAO;IAEvD,qBACE,KAACf;QAAYc,UAAUA;kBACpBR,YAAYC,SAAsCC,QAAQC;;AAGjE;AACAG,qBAAqBK,WAAW,GAAG;AAEnC,eAAeL,qBAAoB"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Aglyn LLC
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/
|
|
17
|
+
import type { ConsoleNavSection } from '@aglyn/aglyn';
|
|
18
|
+
export type WorkflowsConsoleSectionId = 'workflows' | 'actions' | 'webhooks';
|
|
19
|
+
/**
|
|
20
|
+
* The workflows console's sections, in rail order (AGL-2501).
|
|
21
|
+
*
|
|
22
|
+
* One list, read twice and never copied: `plugin.ts` registers it on the nav
|
|
23
|
+
* item so the shell can route and gate each section, and the page switches its
|
|
24
|
+
* body on the id the shell resolves back.
|
|
25
|
+
*
|
|
26
|
+
* Ids are the `?tab=` ids this page already deep-linked by, kept deliberately
|
|
27
|
+
* so a bookmark that named a tab names the same section as a route.
|
|
28
|
+
*
|
|
29
|
+
* No `navTabId` on any of them: they inherit the Workflows nav item's gate,
|
|
30
|
+
* which is `nav-tab-workflows`. The per-card ENTITLEMENT checks are unchanged
|
|
31
|
+
* and still live in the cards — workflows, actions and webhooks are distinct
|
|
32
|
+
* plan flags, and a plan is not a release flag.
|
|
33
|
+
*/
|
|
34
|
+
export declare const WORKFLOWS_CONSOLE_SECTIONS: readonly ConsoleNavSection[];
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Aglyn LLC
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/ /**
|
|
17
|
+
* The workflows console's sections, in rail order (AGL-2501).
|
|
18
|
+
*
|
|
19
|
+
* One list, read twice and never copied: `plugin.ts` registers it on the nav
|
|
20
|
+
* item so the shell can route and gate each section, and the page switches its
|
|
21
|
+
* body on the id the shell resolves back.
|
|
22
|
+
*
|
|
23
|
+
* Ids are the `?tab=` ids this page already deep-linked by, kept deliberately
|
|
24
|
+
* so a bookmark that named a tab names the same section as a route.
|
|
25
|
+
*
|
|
26
|
+
* No `navTabId` on any of them: they inherit the Workflows nav item's gate,
|
|
27
|
+
* which is `nav-tab-workflows`. The per-card ENTITLEMENT checks are unchanged
|
|
28
|
+
* and still live in the cards — workflows, actions and webhooks are distinct
|
|
29
|
+
* plan flags, and a plan is not a release flag.
|
|
30
|
+
*/ export const WORKFLOWS_CONSOLE_SECTIONS = [
|
|
31
|
+
{
|
|
32
|
+
id: 'workflows',
|
|
33
|
+
label: 'Workflows'
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
id: 'actions',
|
|
37
|
+
label: 'Actions'
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
id: 'webhooks',
|
|
41
|
+
label: 'Webhooks'
|
|
42
|
+
}
|
|
43
|
+
] /*
|
|
44
|
+
* Rail ORDER decides where `/workflows` lands: the shell redirects a bare hub
|
|
45
|
+
* URL to the first section in this list the reader may open (AGL-2501). There
|
|
46
|
+
* is deliberately no separate default constant — a second place to say which
|
|
47
|
+
* section is first is a second place for it to disagree with the rail.
|
|
48
|
+
*/ ;
|
|
49
|
+
|
|
50
|
+
//# sourceMappingURL=workflows-console-sections.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../../libs/plugins/workflows/src/lib/components/workflows-console-sections.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport type { ConsoleNavSection } from '@aglyn/aglyn'\n\nexport type WorkflowsConsoleSectionId = 'workflows' | 'actions' | 'webhooks'\n\n/**\n * The workflows console's sections, in rail order (AGL-2501).\n *\n * One list, read twice and never copied: `plugin.ts` registers it on the nav\n * item so the shell can route and gate each section, and the page switches its\n * body on the id the shell resolves back.\n *\n * Ids are the `?tab=` ids this page already deep-linked by, kept deliberately\n * so a bookmark that named a tab names the same section as a route.\n *\n * No `navTabId` on any of them: they inherit the Workflows nav item's gate,\n * which is `nav-tab-workflows`. The per-card ENTITLEMENT checks are unchanged\n * and still live in the cards — workflows, actions and webhooks are distinct\n * plan flags, and a plan is not a release flag.\n */\nexport const WORKFLOWS_CONSOLE_SECTIONS: readonly ConsoleNavSection[] = [\n { id: 'workflows', label: 'Workflows' },\n { id: 'actions', label: 'Actions' },\n { id: 'webhooks', label: 'Webhooks' },\n]\n\n/*\n * Rail ORDER decides where `/workflows` lands: the shell redirects a bare hub\n * URL to the first section in this list the reader may open (AGL-2501). There\n * is deliberately no separate default constant — a second place to say which\n * section is first is a second place for it to disagree with the rail.\n */\n"],"names":["WORKFLOWS_CONSOLE_SECTIONS","id","label"],"mappings":"AAAA;;;;;;;;;;;;;;;CAeC,GAMD;;;;;;;;;;;;;;CAcC,GACD,OAAO,MAAMA,6BAA2D;IACtE;QAAEC,IAAI;QAAaC,OAAO;IAAY;IACtC;QAAED,IAAI;QAAWC,OAAO;IAAU;IAClC;QAAED,IAAI;QAAYC,OAAO;IAAW;CACrC,CAED;;;;;CAKC,IAPA"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Aglyn LLC
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
*/ export const BUNDLE_ID = 'workflows';
|
|
8
|
+
|
|
9
|
+
//# sourceMappingURL=bundle-common.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../../libs/plugins/workflows/src/lib/constants/bundle-common.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n */\n\nexport const BUNDLE_ID = 'workflows'\n"],"names":["BUNDLE_ID"],"mappings":"AAAA;;;;;;CAMC,GAED,OAAO,MAAMA,YAAY,YAAW"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Aglyn LLC
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/
|
|
17
|
+
import { type HostEventListener } from '@aglyn/tenant-runtime/host-event-listeners';
|
|
18
|
+
/**
|
|
19
|
+
* The automation engine, as the runtime hears it.
|
|
20
|
+
*
|
|
21
|
+
* Light by construction: the engine is imported when the first event
|
|
22
|
+
* arrives, not when the process starts, so a process that never sees an
|
|
23
|
+
* event pays for this object and nothing else.
|
|
24
|
+
*/
|
|
25
|
+
export declare const workflowsHostEventListener: HostEventListener;
|
|
26
|
+
/**
|
|
27
|
+
* The plugin's SERVER declarations: what the server must know at boot,
|
|
28
|
+
* before any door of the plugin has been called.
|
|
29
|
+
*
|
|
30
|
+
* The engine's host-event listener, because the doors that raise the events
|
|
31
|
+
* mostly never load this plugin. A form submission and a page view are core
|
|
32
|
+
* routes; a contact captured by a Stripe webhook is a core capture door. Each
|
|
33
|
+
* calls `emitHostEvent`, and the listener has to be registered before the
|
|
34
|
+
* first of them arrives — which is what running this from both apps'
|
|
35
|
+
* `instrumentation.ts` gives.
|
|
36
|
+
*
|
|
37
|
+
* Also called from the plugin's own API register functions, so a process
|
|
38
|
+
* whose boot did not run it still registers the listener the first time a
|
|
39
|
+
* plugin door loads. Registering twice replaces in place.
|
|
40
|
+
*/
|
|
41
|
+
export declare function registerWorkflowsServerDeclarations(): void;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Aglyn LLC
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/ // The registry from its own module, not the runtime barrel: boot needs the
|
|
17
|
+
// registry and nothing else, and the barrel reaches the data layer.
|
|
18
|
+
import { registerHostEventListener } from "@aglyn/tenant-runtime/host-event-listeners";
|
|
19
|
+
import { BUNDLE_ID } from "./constants/bundle-common.js";
|
|
20
|
+
/**
|
|
21
|
+
* The automation engine, as the runtime hears it.
|
|
22
|
+
*
|
|
23
|
+
* Light by construction: the engine is imported when the first event
|
|
24
|
+
* arrives, not when the process starts, so a process that never sees an
|
|
25
|
+
* event pays for this object and nothing else.
|
|
26
|
+
*/ export const workflowsHostEventListener = {
|
|
27
|
+
async onEvent (hostId, event, payload) {
|
|
28
|
+
const { runEventAutomations } = await import("./engine/run-event-automations.js");
|
|
29
|
+
return await runEventAutomations(hostId, event, payload);
|
|
30
|
+
},
|
|
31
|
+
async onDispatch (hostId, automationId, event, payload) {
|
|
32
|
+
const { runSingleAction } = await import("./engine/run-event-actions.js");
|
|
33
|
+
return await runSingleAction(hostId, automationId, event, payload);
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
/**
|
|
37
|
+
* The plugin's SERVER declarations: what the server must know at boot,
|
|
38
|
+
* before any door of the plugin has been called.
|
|
39
|
+
*
|
|
40
|
+
* The engine's host-event listener, because the doors that raise the events
|
|
41
|
+
* mostly never load this plugin. A form submission and a page view are core
|
|
42
|
+
* routes; a contact captured by a Stripe webhook is a core capture door. Each
|
|
43
|
+
* calls `emitHostEvent`, and the listener has to be registered before the
|
|
44
|
+
* first of them arrives — which is what running this from both apps'
|
|
45
|
+
* `instrumentation.ts` gives.
|
|
46
|
+
*
|
|
47
|
+
* Also called from the plugin's own API register functions, so a process
|
|
48
|
+
* whose boot did not run it still registers the listener the first time a
|
|
49
|
+
* plugin door loads. Registering twice replaces in place.
|
|
50
|
+
*/ export function registerWorkflowsServerDeclarations() {
|
|
51
|
+
registerHostEventListener(BUNDLE_ID, workflowsHostEventListener);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
//# sourceMappingURL=declarations.server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../libs/plugins/workflows/src/lib/declarations.server.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// The registry from its own module, not the runtime barrel: boot needs the\n// registry and nothing else, and the barrel reaches the data layer.\nimport {\n type HostEventListener,\n registerHostEventListener,\n} from '@aglyn/tenant-runtime/host-event-listeners'\nimport { BUNDLE_ID } from './constants/bundle-common'\n\n/**\n * The automation engine, as the runtime hears it.\n *\n * Light by construction: the engine is imported when the first event\n * arrives, not when the process starts, so a process that never sees an\n * event pays for this object and nothing else.\n */\nexport const workflowsHostEventListener: HostEventListener = {\n async onEvent(hostId, event, payload) {\n const { runEventAutomations } = await import('./engine/run-event-automations')\n return await runEventAutomations(hostId, event, payload)\n },\n async onDispatch(hostId, automationId, event, payload) {\n const { runSingleAction } = await import('./engine/run-event-actions')\n return await runSingleAction(hostId, automationId, event, payload)\n },\n}\n\n/**\n * The plugin's SERVER declarations: what the server must know at boot,\n * before any door of the plugin has been called.\n *\n * The engine's host-event listener, because the doors that raise the events\n * mostly never load this plugin. A form submission and a page view are core\n * routes; a contact captured by a Stripe webhook is a core capture door. Each\n * calls `emitHostEvent`, and the listener has to be registered before the\n * first of them arrives — which is what running this from both apps'\n * `instrumentation.ts` gives.\n *\n * Also called from the plugin's own API register functions, so a process\n * whose boot did not run it still registers the listener the first time a\n * plugin door loads. Registering twice replaces in place.\n */\nexport function registerWorkflowsServerDeclarations(): void {\n registerHostEventListener(BUNDLE_ID, workflowsHostEventListener)\n}\n"],"names":["registerHostEventListener","BUNDLE_ID","workflowsHostEventListener","onEvent","hostId","event","payload","runEventAutomations","onDispatch","automationId","runSingleAction","registerWorkflowsServerDeclarations"],"mappings":"AAAA;;;;;;;;;;;;;;;CAeC,GAED,2EAA2E;AAC3E,oEAAoE;AACpE,SAEEA,yBAAyB,QACpB,6CAA4C;AACnD,SAASC,SAAS,QAAQ,+BAA2B;AAErD;;;;;;CAMC,GACD,OAAO,MAAMC,6BAAgD;IAC3D,MAAMC,SAAQC,MAAM,EAAEC,KAAK,EAAEC,OAAO;QAClC,MAAM,EAAEC,mBAAmB,EAAE,GAAG,MAAM,MAAM,CAAC;QAC7C,OAAO,MAAMA,oBAAoBH,QAAQC,OAAOC;IAClD;IACA,MAAME,YAAWJ,MAAM,EAAEK,YAAY,EAAEJ,KAAK,EAAEC,OAAO;QACnD,MAAM,EAAEI,eAAe,EAAE,GAAG,MAAM,MAAM,CAAC;QACzC,OAAO,MAAMA,gBAAgBN,QAAQK,cAAcJ,OAAOC;IAC5D;AACF,EAAC;AAED;;;;;;;;;;;;;;CAcC,GACD,OAAO,SAASK;IACdX,0BAA0BC,WAAWC;AACvC"}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Aglyn LLC
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/
|
|
17
|
+
import { type CrmActionStep, type CrmActivityLink } from '@aglyn/aglyn/server';
|
|
18
|
+
import type { HostEventPayload } from '@aglyn/tenant-runtime/host-event-listeners';
|
|
19
|
+
/**
|
|
20
|
+
* The CRM steps of an action run (AGL-2605): what `setContactStage`,
|
|
21
|
+
* `addContactTag`, `assignContactOwner`, `createCrmTask` and
|
|
22
|
+
* `logCrmActivity` actually write.
|
|
23
|
+
*
|
|
24
|
+
* Split out of `run-event-actions.ts` because the five share one shape the
|
|
25
|
+
* other server steps do not: each begins by finding THE PERSON the event is
|
|
26
|
+
* about, and each writes either inside the site's facet on that person or a
|
|
27
|
+
* record stamped with the site's scope. One resolver and one scope
|
|
28
|
+
* expression, used five times, rather than five copies drifting apart.
|
|
29
|
+
*
|
|
30
|
+
* ## The person is the event's, never the step's
|
|
31
|
+
*
|
|
32
|
+
* A step carries no contact reference. The contact is whoever the event
|
|
33
|
+
* names — by `contactId` when the emitting door knew the document, and by
|
|
34
|
+
* `email` otherwise, which is what every pre-CRM event carries. Both
|
|
35
|
+
* lookups are scoped to what THIS site may see: a document the id names
|
|
36
|
+
* but the site cannot read is treated as absent, exactly as the scoped
|
|
37
|
+
* query would have treated it, so an event replayed against the wrong site
|
|
38
|
+
* reaches nobody.
|
|
39
|
+
*
|
|
40
|
+
* ## A missing person is a reported no-op
|
|
41
|
+
*
|
|
42
|
+
* Nothing is written and the step's error names the reason, which lands in
|
|
43
|
+
* the run summary beside the trigger — the same place "why didn't it
|
|
44
|
+
* fire?" is answered for every other step. Silence here would make a
|
|
45
|
+
* mis-wired trigger (a form with no email field) indistinguishable from a
|
|
46
|
+
* working one.
|
|
47
|
+
*/
|
|
48
|
+
export interface CrmStepEnv {
|
|
49
|
+
hostId: string;
|
|
50
|
+
/** The owning org's billing doc, already read by the run's gate. */
|
|
51
|
+
org: unknown;
|
|
52
|
+
orgId: string | null;
|
|
53
|
+
}
|
|
54
|
+
export interface CrmStepOutcome {
|
|
55
|
+
/** The reason nothing was written, when nothing was. */
|
|
56
|
+
error?: string;
|
|
57
|
+
/** The one fact worth carrying into the run summary. */
|
|
58
|
+
detail?: string;
|
|
59
|
+
/**
|
|
60
|
+
* An event this step's write earned, for the CALLER to fan out under its
|
|
61
|
+
* own depth guard. Not emitted from here: a stage set by an automation is
|
|
62
|
+
* itself a stage change, and the action listening for it must run — but
|
|
63
|
+
* through the same nesting cap a `customEvent` chain has, or an action
|
|
64
|
+
* that sets the stage it listens for would run until the meter ran dry.
|
|
65
|
+
*/
|
|
66
|
+
emit?: {
|
|
67
|
+
event: 'contactStageChanged';
|
|
68
|
+
payload: HostEventPayload;
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Runs one CRM step for the person the event names. Never throws for a
|
|
73
|
+
* missing person, an unknown owner or a site with no org — those are
|
|
74
|
+
* answered as `error` so the run records them; a Firestore failure
|
|
75
|
+
* propagates to the executor's catch like every other step's would.
|
|
76
|
+
*/
|
|
77
|
+
export declare function runCrmActionStep(env: CrmStepEnv, actionId: string, step: CrmActionStep, payload: HostEventPayload, nowMs?: number): Promise<CrmStepOutcome>;
|
|
78
|
+
/**
|
|
79
|
+
* The activity row a `sendEmail` step's message will be logged as, prepared
|
|
80
|
+
* BEFORE the send (AGL-2615): the minted reference whose id rides the
|
|
81
|
+
* message as a tag, the links it files under, and the scope it is stamped
|
|
82
|
+
* with. `null` when the message earns no row.
|
|
83
|
+
*/
|
|
84
|
+
export interface PreparedCrmEmailActivity {
|
|
85
|
+
ref: FirebaseFirestore.DocumentReference;
|
|
86
|
+
/** The provider tags the delivery webhook finds the row by. */
|
|
87
|
+
tags: {
|
|
88
|
+
name: string;
|
|
89
|
+
value: string;
|
|
90
|
+
}[];
|
|
91
|
+
link: CrmActivityLink;
|
|
92
|
+
visibleTo: string[];
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Whether — and where — an automation's email lands on a timeline.
|
|
96
|
+
*
|
|
97
|
+
* A `sendEmail` step is not a CRM step: it mails whatever address the event
|
|
98
|
+
* carries, to a person who may be nobody the CRM knows. It earns a row on
|
|
99
|
+
* exactly one condition, that the message is ADDRESSED TO THE CONTACT the
|
|
100
|
+
* event is about — the person `resolveEventContact` finds, at the address
|
|
101
|
+
* the row holds. A welcome sequence to a new contact is that; an internal
|
|
102
|
+
* alert routed to a merchant's own address through `toField` is not, and a
|
|
103
|
+
* row for it would put the merchant's inbox on a customer's history.
|
|
104
|
+
*
|
|
105
|
+
* Prepared ahead of the send, for the reason the console route mints its
|
|
106
|
+
* id first: the webhook has nothing but the tags on the message to find
|
|
107
|
+
* the row with. Nothing is written here. A record at the activity ceiling
|
|
108
|
+
* earns no row — the message still goes, because the ceiling bounds the
|
|
109
|
+
* log and not the mail — and neither does a site with no org to hold one.
|
|
110
|
+
*
|
|
111
|
+
* **Never throws.** The row is bookkeeping beside a send, and a lookup that
|
|
112
|
+
* fails must not become a message that never left — the posture every
|
|
113
|
+
* meter beside `sendEmail` takes. A failure here is logged and the message
|
|
114
|
+
* goes out untagged.
|
|
115
|
+
*/
|
|
116
|
+
export declare function prepareCrmEmailActivity(env: CrmStepEnv, to: string, payload: HostEventPayload): Promise<PreparedCrmEmailActivity | null>;
|
|
117
|
+
/**
|
|
118
|
+
* Writes the prepared row, once the provider has accepted the message.
|
|
119
|
+
*
|
|
120
|
+
* The same shape the console route logs — `buildCrmEmailActivity` is the
|
|
121
|
+
* one builder — with the automation as its source and nobody as its
|
|
122
|
+
* author. **Never throws**: the message has left, and a row that could not
|
|
123
|
+
* be written is a gap on the timeline rather than a failed step.
|
|
124
|
+
*/
|
|
125
|
+
export declare function logCrmEmailActivity(env: CrmStepEnv, prepared: PreparedCrmEmailActivity, message: {
|
|
126
|
+
subject: string;
|
|
127
|
+
body: string;
|
|
128
|
+
to: string;
|
|
129
|
+
}, actionId: string, nowMs?: number): Promise<void>;
|