@protobase/schema 0.67.11 → 0.68.0
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/built-in-field-types.d.ts +5 -2
- package/dist/built-in-field-types.js +6 -3
- package/dist/internal.d.ts +2 -2
- package/dist/internal.js +2 -2
- package/dist/workflows/workflow-resources.d.ts +26 -0
- package/dist/workflows/workflow-resources.js +109 -5
- package/dist/workflows/workflow-types-path.d.ts +22 -0
- package/dist/workflows/workflow-types-path.js +5 -0
- package/package.json +1 -1
- package/dist/workflows/step-types.d.ts +0 -30
- package/dist/workflows/step-types.js +0 -70
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
//#region src/built-in-field-types.d.ts
|
|
2
2
|
/**
|
|
3
3
|
* The field types Protobase brings, which a view chooses with `.widget(name)` like a plugin's, by the storage types
|
|
4
|
-
* each shows: `members`, a JSON array of the user ids of an organization's members,
|
|
5
|
-
* definition drawn as a graph to edit
|
|
4
|
+
* each shows: `json`, any JSON value edited as JSON text, `members`, a JSON array of the user ids of an organization's members, `workflow`, a workflow's
|
|
5
|
+
* definition drawn as a graph to edit, and `workflow_run`, a run's id, drawn as its steps on its workflow's graph. A
|
|
6
|
+
* plugin's of the same name wins.
|
|
6
7
|
*/
|
|
7
8
|
export declare const builtInFieldTypes: {
|
|
9
|
+
readonly json: readonly ["json"];
|
|
8
10
|
readonly members: readonly ["json"];
|
|
9
11
|
readonly workflow: readonly ["json"];
|
|
12
|
+
readonly workflow_run: readonly ["uuid"];
|
|
10
13
|
};
|
|
11
14
|
//#endregion
|
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
//#region src/built-in-field-types.ts
|
|
2
2
|
/**
|
|
3
3
|
* The field types Protobase brings, which a view chooses with `.widget(name)` like a plugin's, by the storage types
|
|
4
|
-
* each shows: `members`, a JSON array of the user ids of an organization's members,
|
|
5
|
-
* definition drawn as a graph to edit
|
|
4
|
+
* each shows: `json`, any JSON value edited as JSON text, `members`, a JSON array of the user ids of an organization's members, `workflow`, a workflow's
|
|
5
|
+
* definition drawn as a graph to edit, and `workflow_run`, a run's id, drawn as its steps on its workflow's graph. A
|
|
6
|
+
* plugin's of the same name wins.
|
|
6
7
|
*/
|
|
7
8
|
const builtInFieldTypes = {
|
|
9
|
+
json: ["json"],
|
|
8
10
|
members: ["json"],
|
|
9
|
-
workflow: ["json"]
|
|
11
|
+
workflow: ["json"],
|
|
12
|
+
workflow_run: ["uuid"]
|
|
10
13
|
};
|
|
11
14
|
//#endregion
|
|
12
15
|
export { builtInFieldTypes };
|
package/dist/internal.d.ts
CHANGED
|
@@ -11,7 +11,7 @@ import { parseCapability } from "./access/capability.js";
|
|
|
11
11
|
import { checkEventFilter } from "./events/event-models.js";
|
|
12
12
|
import { webhookResources } from "./webhooks/webhook-resources.js";
|
|
13
13
|
import { workflowResources } from "./workflows/workflow-resources.js";
|
|
14
|
-
import {
|
|
14
|
+
import { WorkflowTypeEntry, WorkflowTypeList, workflowTypesPath } from "./workflows/workflow-types-path.js";
|
|
15
15
|
import { PropShapes, RefShape, pruneByShape, shapes } from "./ref-shape.js";
|
|
16
16
|
import { SearchTerm, matchedSearchField, matchesSearch, searchTerms, termMatches } from "./search-match.js";
|
|
17
17
|
import { defaultRecentLimit, navRecentErrors, statusTones } from "./nav-recent.js";
|
|
@@ -45,4 +45,4 @@ import { builtInFieldTypes } from "./built-in-field-types.js";
|
|
|
45
45
|
import { CallCandidate, CallClientMessage, CallDescription, CallGuestLink, CallGuestRefusal, CallGuestState, CallLeftReason, CallLobbyGuest, CallMode, CallRemoteTrack, CallResume, CallRosterMember, CallServerMessage, CallTrackRequest, CallTrackSource, CallVideoLayer } from "./calls/call-protocol.js";
|
|
46
46
|
import { guestCallsPath } from "./calls/call-guests.js";
|
|
47
47
|
import { CallRing, callsChannelEvent, declineWord, ringNotice, ringsPath } from "./calls/call-rings.js";
|
|
48
|
-
export { type AddressCheck, type Availability, type CallCandidate, type CallClientMessage, type CallDescription, type CallGuestLink, type CallGuestRefusal, type CallGuestState, type CallLeftReason, type CallLobbyGuest, type CallMode, type CallRemoteTrack, type CallResume, type CallRing, type CallRosterMember, type CallServerMessage, type CallTrackRequest, type CallTrackSource, type CallVideoLayer, type FormulaNode, type Locale, type MobileReleaseAnswer, type PersonStatus, type PluginHost, type PluginRequirement, type PropShapes, type RefShape, type ReleaseBinding, type SearchTerm, type StatusInput, type
|
|
48
|
+
export { type AddressCheck, type Availability, type CallCandidate, type CallClientMessage, type CallDescription, type CallGuestLink, type CallGuestRefusal, type CallGuestState, type CallLeftReason, type CallLobbyGuest, type CallMode, type CallRemoteTrack, type CallResume, type CallRing, type CallRosterMember, type CallServerMessage, type CallTrackRequest, type CallTrackSource, type CallVideoLayer, type FormulaNode, type Locale, type MobileReleaseAnswer, type PersonStatus, type PluginHost, type PluginRequirement, type PropShapes, type RefShape, type ReleaseBinding, type SearchTerm, type StatusInput, type WorkflowTypeEntry, type WorkflowTypeList, actionConditionError, actionInputErrors, addressErrors, addressPlaceholders, apiOriginMeta, appHrefError, applyAssistantEvent, authBasePath, availabilities, boardErrors, bottomBarFor, builtInFieldTypes, callsChannelEvent, capacitorOrigin, cardPhotoLimit, chartFields, checkEventFilter, checkedAccept, checkedProvider, confirmationMinutes, datesErrors, declineWord, decodeKey, defaultRecentLimit, deviceIdParam, devicesPath, displayFields, emailCodeMinutes, emptyAssistantState, encodeKey, fieldRefsIn, fillAddress, firstPartyCodeKey, guestCallsPath, heldStatus, historyIdParam, historyIdPattern, historyPath, hrefField, hrefPlaceholders, humanize, inRange, isFieldRef, isGroupChart, isLocale, labelFieldOf, layoutItems, leavesApp, linkActionError, listColumnNames, locales, markFieldRefs, matchedSearchField, matchesSearch, maxStatusText, mobileReleaseBasePath, mobileReleaseParams, mobileReleasePath, mobileReleaseQuery, mobileReleasesPath, navRecentErrors, parseCapability, parseFormula, parseSize, parseTable, pickLocale, pluginProblem, promptError, promptFields, pruneByShape, pushRecord, readEventStream, recordTitle, recordTitleField, redactSecrets, releaseManifestFile, releaseStatementContext, releaseStatementFile, renderPrompt, ringNotice, ringsPath, searchTerms, serviceWorkerFile, shapes, shownInputs, statusPath, statusTextProblem, statusTones, tableDisplay, termMatches, unmarkFieldRefs, updateSetErrors, updateValues, viewOfList, webhookResources, workflowResources, workflowTypesPath };
|
package/dist/internal.js
CHANGED
|
@@ -19,7 +19,7 @@ import { bottomBarFor } from "./bottom-bar.js";
|
|
|
19
19
|
import { decodeKey, encodeKey } from "./keys.js";
|
|
20
20
|
import { webhookResources } from "./webhooks/webhook-resources.js";
|
|
21
21
|
import { workflowResources } from "./workflows/workflow-resources.js";
|
|
22
|
-
import {
|
|
22
|
+
import { workflowTypesPath } from "./workflows/workflow-types-path.js";
|
|
23
23
|
import { pruneByShape, shapes } from "./ref-shape.js";
|
|
24
24
|
import { inRange, pluginProblem } from "./plugin-version.js";
|
|
25
25
|
import { redactSecrets } from "./redact-secrets.js";
|
|
@@ -44,4 +44,4 @@ import { listColumnNames } from "./list-columns.js";
|
|
|
44
44
|
import { builtInFieldTypes } from "./built-in-field-types.js";
|
|
45
45
|
import { guestCallsPath } from "./calls/call-guests.js";
|
|
46
46
|
import { callsChannelEvent, declineWord, ringNotice, ringsPath } from "./calls/call-rings.js";
|
|
47
|
-
export { actionConditionError, actionInputErrors, addressErrors, addressPlaceholders, apiOriginMeta, appHrefError, applyAssistantEvent, authBasePath, availabilities, boardErrors, bottomBarFor, builtInFieldTypes, callsChannelEvent, capacitorOrigin, cardPhotoLimit, chartFields, checkEventFilter, checkedAccept, checkedProvider, confirmationMinutes, datesErrors, declineWord, decodeKey, defaultRecentLimit, deviceIdParam, devicesPath, displayFields, emailCodeMinutes, emptyAssistantState, encodeKey, fieldRefsIn, fillAddress, firstPartyCodeKey, guestCallsPath, heldStatus, historyIdParam, historyIdPattern, historyPath, hrefField, hrefPlaceholders, humanize, inRange, isFieldRef, isGroupChart, isLocale, labelFieldOf, layoutItems, leavesApp, linkActionError, listColumnNames, locales, markFieldRefs, matchedSearchField, matchesSearch, maxStatusText, mobileReleaseBasePath, mobileReleaseParams, mobileReleasePath, mobileReleaseQuery, mobileReleasesPath, navRecentErrors, parseCapability, parseFormula, parseSize, parseTable, pickLocale, pluginProblem, promptError, promptFields, pruneByShape, pushRecord, readEventStream, recordTitle, recordTitleField, redactSecrets, releaseManifestFile, releaseStatementContext, releaseStatementFile, renderPrompt,
|
|
47
|
+
export { actionConditionError, actionInputErrors, addressErrors, addressPlaceholders, apiOriginMeta, appHrefError, applyAssistantEvent, authBasePath, availabilities, boardErrors, bottomBarFor, builtInFieldTypes, callsChannelEvent, capacitorOrigin, cardPhotoLimit, chartFields, checkEventFilter, checkedAccept, checkedProvider, confirmationMinutes, datesErrors, declineWord, decodeKey, defaultRecentLimit, deviceIdParam, devicesPath, displayFields, emailCodeMinutes, emptyAssistantState, encodeKey, fieldRefsIn, fillAddress, firstPartyCodeKey, guestCallsPath, heldStatus, historyIdParam, historyIdPattern, historyPath, hrefField, hrefPlaceholders, humanize, inRange, isFieldRef, isGroupChart, isLocale, labelFieldOf, layoutItems, leavesApp, linkActionError, listColumnNames, locales, markFieldRefs, matchedSearchField, matchesSearch, maxStatusText, mobileReleaseBasePath, mobileReleaseParams, mobileReleasePath, mobileReleaseQuery, mobileReleasesPath, navRecentErrors, parseCapability, parseFormula, parseSize, parseTable, pickLocale, pluginProblem, promptError, promptFields, pruneByShape, pushRecord, readEventStream, recordTitle, recordTitleField, redactSecrets, releaseManifestFile, releaseStatementContext, releaseStatementFile, renderPrompt, ringNotice, ringsPath, searchTerms, serviceWorkerFile, shapes, shownInputs, statusPath, statusTextProblem, statusTones, tableDisplay, termMatches, unmarkFieldRefs, updateSetErrors, updateValues, viewOfList, webhookResources, workflowResources, workflowTypesPath };
|
|
@@ -15,6 +15,7 @@ export declare const workflowResources: (schema: string) => {
|
|
|
15
15
|
readonly description: Field<string | null>;
|
|
16
16
|
readonly definition: Field<import("zod").JSONType>;
|
|
17
17
|
readonly version: Field<number | null>;
|
|
18
|
+
readonly enabled_version: Field<number | null>;
|
|
18
19
|
readonly tenant_id: Field<string | null>;
|
|
19
20
|
readonly created_at: Field<string>;
|
|
20
21
|
readonly updated_at: Field<string>;
|
|
@@ -25,6 +26,7 @@ export declare const workflowResources: (schema: string) => {
|
|
|
25
26
|
readonly description: Field<string | null>;
|
|
26
27
|
readonly definition: Field<import("zod").JSONType>;
|
|
27
28
|
readonly version: Field<number | null>;
|
|
29
|
+
readonly enabled_version: Field<number | null>;
|
|
28
30
|
readonly tenant_id: Field<string | null>;
|
|
29
31
|
readonly created_at: Field<string>;
|
|
30
32
|
readonly updated_at: Field<string>;
|
|
@@ -57,6 +59,7 @@ export declare const workflowResources: (schema: string) => {
|
|
|
57
59
|
readonly cause: Field<string | null>;
|
|
58
60
|
readonly resume_at: Field<string | null>;
|
|
59
61
|
readonly started_by: Field<string | null>;
|
|
62
|
+
readonly rerun_of: Field<string | number | null>;
|
|
60
63
|
readonly tenant_id: Field<string | null>;
|
|
61
64
|
readonly created_at: Field<string>;
|
|
62
65
|
readonly finished_at: Field<string | null>;
|
|
@@ -74,6 +77,7 @@ export declare const workflowResources: (schema: string) => {
|
|
|
74
77
|
readonly cause: Field<string | null>;
|
|
75
78
|
readonly resume_at: Field<string | null>;
|
|
76
79
|
readonly started_by: Field<string | null>;
|
|
80
|
+
readonly rerun_of: Field<string | number | null>;
|
|
77
81
|
readonly tenant_id: Field<string | null>;
|
|
78
82
|
readonly created_at: Field<string>;
|
|
79
83
|
readonly finished_at: Field<string | null>;
|
|
@@ -123,5 +127,27 @@ export declare const workflowResources: (schema: string) => {
|
|
|
123
127
|
readonly finished_at: Field<string>;
|
|
124
128
|
readonly duration_ms: Field<string | null>;
|
|
125
129
|
}, Ref<"id", string>>>;
|
|
130
|
+
workflowTriggers: ResourceBuilder<{
|
|
131
|
+
readonly id: Field<string>;
|
|
132
|
+
readonly workflow_id: Field<string | number>;
|
|
133
|
+
readonly version: Field<number>;
|
|
134
|
+
readonly type: Field<string>;
|
|
135
|
+
readonly status: Field<"active" | "failing" | "needs_sign_in" | "stopping">;
|
|
136
|
+
readonly last_error: Field<import("zod").JSONType>;
|
|
137
|
+
readonly next_poll_at: Field<string | null>;
|
|
138
|
+
readonly tenant_id: Field<string | null>;
|
|
139
|
+
readonly updated_at: Field<string>;
|
|
140
|
+
}, Ref<"id", string>>;
|
|
141
|
+
workflowTriggersView: ViewBuilder<ResourceBuilder<{
|
|
142
|
+
readonly id: Field<string>;
|
|
143
|
+
readonly workflow_id: Field<string | number>;
|
|
144
|
+
readonly version: Field<number>;
|
|
145
|
+
readonly type: Field<string>;
|
|
146
|
+
readonly status: Field<"active" | "failing" | "needs_sign_in" | "stopping">;
|
|
147
|
+
readonly last_error: Field<import("zod").JSONType>;
|
|
148
|
+
readonly next_poll_at: Field<string | null>;
|
|
149
|
+
readonly tenant_id: Field<string | null>;
|
|
150
|
+
readonly updated_at: Field<string>;
|
|
151
|
+
}, Ref<"id", string>>>;
|
|
126
152
|
};
|
|
127
153
|
//#endregion
|
|
@@ -27,6 +27,7 @@ const workflowsResource = (schema) => resource("workflows").table(`${schema}.wor
|
|
|
27
27
|
description: f.text().optional().max(2e3),
|
|
28
28
|
definition: f.json(),
|
|
29
29
|
version: f.integer().optional().readOnly(),
|
|
30
|
+
enabled_version: f.integer().optional(),
|
|
30
31
|
tenant_id: f.text().optional().readOnly(),
|
|
31
32
|
created_at: f.timestamp().readOnly().dbDefault(),
|
|
32
33
|
updated_at: f.timestamp().readOnly().dbDefault().sortable()
|
|
@@ -35,6 +36,7 @@ const workflowsView = view("workflows").names({
|
|
|
35
36
|
singular: "Workflow",
|
|
36
37
|
plural: "Workflows"
|
|
37
38
|
}).icon("workflow").title((r) => r.name).help("Steps that run one after another along their edges, written in the States Language with JSONata expressions. Each save that changes its definition is a new version; a run keeps the version it started on.").fields((r) => ({
|
|
39
|
+
enabled_version: r.enabled_version.label("Enabled version").help("The version whose trigger starts runs; set it to the current version to turn the trigger on, and clear it to turn it off. A save keeps an enabled workflow enabled on its new version."),
|
|
38
40
|
definition: r.definition.help("Its trigger and its steps, drawn as a graph that lays itself out. Every value is read by name: the run's input as $states.context.Execution.Input, an earlier result by the variable a state assigned").widget("workflow"),
|
|
39
41
|
updated_at: r.updated_at.label("Updated")
|
|
40
42
|
})).list((r) => ({
|
|
@@ -44,10 +46,19 @@ const workflowsView = view("workflows").names({
|
|
|
44
46
|
r.updated_at
|
|
45
47
|
],
|
|
46
48
|
sort: [[r.updated_at, "desc"]]
|
|
47
|
-
})).
|
|
49
|
+
})).actions((a) => [a.link("test_run", {
|
|
50
|
+
label: "Test run",
|
|
51
|
+
icon: "play",
|
|
52
|
+
to: {
|
|
53
|
+
kind: "create",
|
|
54
|
+
resource: "workflow_runs",
|
|
55
|
+
values: { workflow_id: "{id}" }
|
|
56
|
+
}
|
|
57
|
+
})]).layout((r) => [
|
|
48
58
|
layout.section("Workflow", [
|
|
49
59
|
r.name,
|
|
50
60
|
r.description,
|
|
61
|
+
r.enabled_version,
|
|
51
62
|
r.definition
|
|
52
63
|
]),
|
|
53
64
|
layout.sidebar([
|
|
@@ -55,14 +66,26 @@ const workflowsView = view("workflows").names({
|
|
|
55
66
|
r.created_at,
|
|
56
67
|
r.updated_at
|
|
57
68
|
]),
|
|
69
|
+
layout.related("Trigger", {
|
|
70
|
+
resource: "workflow_triggers",
|
|
71
|
+
field: "workflow_id",
|
|
72
|
+
columns: [
|
|
73
|
+
"type",
|
|
74
|
+
"status",
|
|
75
|
+
"version",
|
|
76
|
+
"last_error",
|
|
77
|
+
"updated_at"
|
|
78
|
+
]
|
|
79
|
+
}),
|
|
58
80
|
layout.related("Runs", {
|
|
59
81
|
resource: "workflow_runs",
|
|
60
82
|
field: "workflow_id",
|
|
61
83
|
columns: [
|
|
62
84
|
"status",
|
|
63
|
-
"
|
|
85
|
+
"started_by",
|
|
64
86
|
"created_at",
|
|
65
87
|
"duration_ms",
|
|
88
|
+
"version",
|
|
66
89
|
"error"
|
|
67
90
|
]
|
|
68
91
|
}),
|
|
@@ -117,6 +140,7 @@ const runsResource = (schema) => resource("workflow_runs").table(`${schema}.runs
|
|
|
117
140
|
cause: f.text().optional().readOnly(),
|
|
118
141
|
resume_at: f.timestamp().optional().readOnly(),
|
|
119
142
|
started_by: f.text().optional().readOnly(),
|
|
143
|
+
rerun_of: f.relation("workflow_runs").optional().filterable(),
|
|
120
144
|
tenant_id: f.text().optional().readOnly(),
|
|
121
145
|
created_at: f.timestamp().readOnly().dbDefault().sortable(),
|
|
122
146
|
finished_at: f.timestamp().optional().readOnly(),
|
|
@@ -129,8 +153,10 @@ const runsView = view("workflow_runs").names({
|
|
|
129
153
|
singular: "Workflow run",
|
|
130
154
|
plural: "Workflow runs"
|
|
131
155
|
}).icon("play").title((r) => r.created_at).help("A run of a workflow with its input. It takes up where it stands after a restart; each of its steps is listed with what it read, gave and logged.").fields((r) => ({
|
|
156
|
+
id: r.id.label("Steps").widget("workflow_run"),
|
|
132
157
|
workflow_id: r.workflow_id.label("Workflow"),
|
|
133
|
-
input: r.input.help("Read by every state as $states.context.Execution.Input"),
|
|
158
|
+
input: r.input.widget("json").help("Read by every state as $states.context.Execution.Input; a re-run takes the input of the run it re-runs"),
|
|
159
|
+
rerun_of: r.rerun_of.label("Re-run of").help("A failed run of the workflow: the re-run keeps its steps before the one that failed, and goes on from there on the workflow as it is now"),
|
|
134
160
|
key: r.key.help("A workflow runs once per key, such as the record a trigger found ready"),
|
|
135
161
|
status: r.status.valueLabels({
|
|
136
162
|
queued: "Queued",
|
|
@@ -142,6 +168,7 @@ const runsView = view("workflow_runs").names({
|
|
|
142
168
|
succeeded: "green",
|
|
143
169
|
failed: "red"
|
|
144
170
|
}),
|
|
171
|
+
output: r.output.widget("json"),
|
|
145
172
|
resume_at: r.resume_at.label("Goes on at"),
|
|
146
173
|
started_by: r.started_by.label("Started by"),
|
|
147
174
|
created_at: r.created_at.label("Started"),
|
|
@@ -152,11 +179,25 @@ const runsView = view("workflow_runs").names({
|
|
|
152
179
|
r.created_at,
|
|
153
180
|
r.workflow_id,
|
|
154
181
|
r.status,
|
|
182
|
+
r.started_by,
|
|
155
183
|
r.duration_ms,
|
|
156
184
|
r.error
|
|
157
185
|
],
|
|
158
186
|
sort: [[r.created_at, "desc"]]
|
|
159
|
-
})).
|
|
187
|
+
})).actions((a) => [a.link("rerun", {
|
|
188
|
+
label: "Re-run from the failed step",
|
|
189
|
+
icon: "restart",
|
|
190
|
+
to: {
|
|
191
|
+
kind: "create",
|
|
192
|
+
resource: "workflow_runs",
|
|
193
|
+
values: {
|
|
194
|
+
workflow_id: "{workflow_id}",
|
|
195
|
+
rerun_of: "{id}"
|
|
196
|
+
}
|
|
197
|
+
},
|
|
198
|
+
when: "status = \"failed\""
|
|
199
|
+
})]).layout((r) => [
|
|
200
|
+
layout.section("Trace", [r.id]),
|
|
160
201
|
layout.section("Run", [
|
|
161
202
|
r.workflow_id,
|
|
162
203
|
r.input,
|
|
@@ -168,6 +209,7 @@ const runsView = view("workflow_runs").names({
|
|
|
168
209
|
r.status,
|
|
169
210
|
r.version,
|
|
170
211
|
r.started_by,
|
|
212
|
+
r.rerun_of,
|
|
171
213
|
r.created_at,
|
|
172
214
|
r.resume_at,
|
|
173
215
|
r.finished_at,
|
|
@@ -185,6 +227,17 @@ const runsView = view("workflow_runs").names({
|
|
|
185
227
|
"duration_ms",
|
|
186
228
|
"error"
|
|
187
229
|
]
|
|
230
|
+
}),
|
|
231
|
+
layout.related("Re-runs", {
|
|
232
|
+
resource: "workflow_runs",
|
|
233
|
+
field: "rerun_of",
|
|
234
|
+
columns: [
|
|
235
|
+
"status",
|
|
236
|
+
"started_by",
|
|
237
|
+
"created_at",
|
|
238
|
+
"duration_ms",
|
|
239
|
+
"error"
|
|
240
|
+
]
|
|
188
241
|
})
|
|
189
242
|
]);
|
|
190
243
|
/** Every step of every run: its input with secrets redacted, output, variables, logs, timing, try and error. */
|
|
@@ -269,6 +322,55 @@ const stepsView = view("workflow_steps").names({
|
|
|
269
322
|
r.finished_at,
|
|
270
323
|
r.duration_ms
|
|
271
324
|
])]);
|
|
325
|
+
const triggerStatuses = [
|
|
326
|
+
"active",
|
|
327
|
+
"failing",
|
|
328
|
+
"needs_sign_in",
|
|
329
|
+
"stopping"
|
|
330
|
+
];
|
|
331
|
+
/** The trigger of each enabled workflow, as the engine keeps it: its type, status and last error, never its state. */
|
|
332
|
+
const triggersResource = (schema) => resource("workflow_triggers").table(`${schema}.triggers`).fields({
|
|
333
|
+
id: f.uuid().readOnly().dbDefault(),
|
|
334
|
+
workflow_id: f.relation("workflows").readOnly().filterable(),
|
|
335
|
+
version: f.integer().readOnly(),
|
|
336
|
+
type: f.text().readOnly(),
|
|
337
|
+
status: f.enum(triggerStatuses).readOnly().filterable(),
|
|
338
|
+
last_error: f.json().optional().readOnly(),
|
|
339
|
+
next_poll_at: f.timestamp().optional().readOnly(),
|
|
340
|
+
tenant_id: f.text().optional().readOnly(),
|
|
341
|
+
updated_at: f.timestamp().readOnly().dbDefault().sortable()
|
|
342
|
+
}).primaryKey((r) => r.id).tenant((r) => r.tenant_id).explicitGrants().access({
|
|
343
|
+
create: () => false,
|
|
344
|
+
update: () => false,
|
|
345
|
+
delete: () => false
|
|
346
|
+
});
|
|
347
|
+
const triggersView = view("workflow_triggers").names({
|
|
348
|
+
singular: "Workflow trigger",
|
|
349
|
+
plural: "Workflow triggers"
|
|
350
|
+
}).icon("zap").title((r) => r.type).fields((r) => ({
|
|
351
|
+
workflow_id: r.workflow_id.label("Workflow"),
|
|
352
|
+
status: r.status.valueLabels({
|
|
353
|
+
active: "Active",
|
|
354
|
+
failing: "Failing",
|
|
355
|
+
needs_sign_in: "Needs sign-in",
|
|
356
|
+
stopping: "Stopping"
|
|
357
|
+
}).valueColors({
|
|
358
|
+
active: "green",
|
|
359
|
+
failing: "red",
|
|
360
|
+
needs_sign_in: "amber"
|
|
361
|
+
}),
|
|
362
|
+
last_error: r.last_error.label("Last error"),
|
|
363
|
+
next_poll_at: r.next_poll_at.label("Next poll"),
|
|
364
|
+
updated_at: r.updated_at.label("Updated")
|
|
365
|
+
})).list((r) => ({
|
|
366
|
+
columns: [
|
|
367
|
+
r.workflow_id,
|
|
368
|
+
r.type,
|
|
369
|
+
r.status,
|
|
370
|
+
r.updated_at
|
|
371
|
+
],
|
|
372
|
+
sort: [[r.updated_at, "desc"]]
|
|
373
|
+
}));
|
|
272
374
|
/**
|
|
273
375
|
* The resources and views `workflows` adds to an app, over the tables of `schema`: Workflows with their versions, runs
|
|
274
376
|
* and steps. Config only; the server checks and runs them.
|
|
@@ -281,7 +383,9 @@ const workflowResources = (schema) => ({
|
|
|
281
383
|
workflowRuns: runsResource(schema),
|
|
282
384
|
workflowRunsView: runsView,
|
|
283
385
|
workflowSteps: stepsResource(schema),
|
|
284
|
-
workflowStepsView: stepsView
|
|
386
|
+
workflowStepsView: stepsView,
|
|
387
|
+
workflowTriggers: triggersResource(schema),
|
|
388
|
+
workflowTriggersView: triggersView
|
|
285
389
|
});
|
|
286
390
|
//#endregion
|
|
287
391
|
export { workflowResources };
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
//#region src/workflows/workflow-types-path.d.ts
|
|
2
|
+
/** The path of the app's workflow trigger and step types under the API's system path (`/api`), as the editor reads them. */
|
|
3
|
+
export declare const workflowTypesPath: (systemPath: string) => string;
|
|
4
|
+
/**
|
|
5
|
+
* A trigger or step type as the server lists it: `id` is a Task's `Resource` or the key of a definition's `trigger`,
|
|
6
|
+
* `input` the JSON Schema of its input, and `available` false, with the `reason`, when this app cannot run it.
|
|
7
|
+
*/
|
|
8
|
+
export type WorkflowTypeEntry = {
|
|
9
|
+
id: string;
|
|
10
|
+
kind: string;
|
|
11
|
+
label: string;
|
|
12
|
+
description: string;
|
|
13
|
+
input: Record<string, unknown>;
|
|
14
|
+
available: boolean;
|
|
15
|
+
reason?: string;
|
|
16
|
+
};
|
|
17
|
+
/** The app's step types and triggers, `manual` among them, built-in and plugin types alike. */
|
|
18
|
+
export type WorkflowTypeList = {
|
|
19
|
+
step_types: WorkflowTypeEntry[];
|
|
20
|
+
triggers: WorkflowTypeEntry[];
|
|
21
|
+
};
|
|
22
|
+
//#endregion
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
//#region src/workflows/workflow-types-path.ts
|
|
2
|
+
/** The path of the app's workflow trigger and step types under the API's system path (`/api`), as the editor reads them. */
|
|
3
|
+
const workflowTypesPath = (systemPath) => `${systemPath}/workflows/types`;
|
|
4
|
+
//#endregion
|
|
5
|
+
export { workflowTypesPath };
|
package/package.json
CHANGED
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
//#region src/workflows/step-types.d.ts
|
|
2
|
-
/**
|
|
3
|
-
* How a step type's argument is written: `text`, one line, which may be an expression; `choice`, one of `options`;
|
|
4
|
-
* `json`, any JSON value or an expression, such as an object of field values.
|
|
5
|
-
*/
|
|
6
|
-
export type StepInputKind = 'text' | 'choice' | 'json';
|
|
7
|
-
/** An argument of a step type: its name in `Arguments`, how it is written, and whether a save needs it. */
|
|
8
|
-
export type StepInput = {
|
|
9
|
-
name: string;
|
|
10
|
-
kind: StepInputKind;
|
|
11
|
-
required?: boolean;
|
|
12
|
-
options?: readonly string[];
|
|
13
|
-
};
|
|
14
|
-
/**
|
|
15
|
-
* The step types a workflow's Task names as its `Resource`, each with its arguments: the server runs them, a save
|
|
16
|
-
* refuses a Task without a required one, and the editor draws a form of them.
|
|
17
|
-
*/
|
|
18
|
-
export declare const workflowStepTypes: {
|
|
19
|
-
readonly 'app:http': readonly [StepInput, StepInput, StepInput, StepInput, StepInput, StepInput];
|
|
20
|
-
readonly 'app:records.create': readonly [StepInput, StepInput];
|
|
21
|
-
readonly 'app:records.update': readonly [StepInput, StepInput, StepInput];
|
|
22
|
-
readonly 'app:records.get': readonly [StepInput, StepInput];
|
|
23
|
-
readonly 'app:records.list': readonly [StepInput, StepInput, StepInput, StepInput];
|
|
24
|
-
readonly 'app:mail.send': readonly [StepInput, StepInput, StepInput, StepInput, StepInput];
|
|
25
|
-
readonly 'app:piece': readonly [StepInput, StepInput, StepInput, StepInput];
|
|
26
|
-
};
|
|
27
|
-
export type WorkflowStepType = keyof typeof workflowStepTypes;
|
|
28
|
-
/** The names of the arguments each step type needs, as the definition check takes them. */
|
|
29
|
-
export declare const requiredStepInputs: Record<WorkflowStepType, string[]>;
|
|
30
|
-
//#endregion
|
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
//#region src/workflows/step-types.ts
|
|
2
|
-
const text = (name, required = false) => ({
|
|
3
|
-
name,
|
|
4
|
-
kind: "text",
|
|
5
|
-
...required && { required }
|
|
6
|
-
});
|
|
7
|
-
const json = (name, required = false) => ({
|
|
8
|
-
name,
|
|
9
|
-
kind: "json",
|
|
10
|
-
...required && { required }
|
|
11
|
-
});
|
|
12
|
-
const choice = (name, options) => ({
|
|
13
|
-
name,
|
|
14
|
-
kind: "choice",
|
|
15
|
-
options
|
|
16
|
-
});
|
|
17
|
-
/**
|
|
18
|
-
* The step types a workflow's Task names as its `Resource`, each with its arguments: the server runs them, a save
|
|
19
|
-
* refuses a Task without a required one, and the editor draws a form of them.
|
|
20
|
-
*/
|
|
21
|
-
const workflowStepTypes = {
|
|
22
|
-
"app:http": [
|
|
23
|
-
text("url", true),
|
|
24
|
-
choice("method", [
|
|
25
|
-
"GET",
|
|
26
|
-
"POST",
|
|
27
|
-
"PUT",
|
|
28
|
-
"PATCH",
|
|
29
|
-
"DELETE"
|
|
30
|
-
]),
|
|
31
|
-
json("headers"),
|
|
32
|
-
json("query"),
|
|
33
|
-
json("body"),
|
|
34
|
-
choice("response", [
|
|
35
|
-
"json",
|
|
36
|
-
"text",
|
|
37
|
-
"file"
|
|
38
|
-
])
|
|
39
|
-
],
|
|
40
|
-
"app:records.create": [text("resource", true), json("data", true)],
|
|
41
|
-
"app:records.update": [
|
|
42
|
-
text("resource", true),
|
|
43
|
-
json("key", true),
|
|
44
|
-
json("data", true)
|
|
45
|
-
],
|
|
46
|
-
"app:records.get": [text("resource", true), json("key", true)],
|
|
47
|
-
"app:records.list": [
|
|
48
|
-
text("resource", true),
|
|
49
|
-
text("filter"),
|
|
50
|
-
text("order_by"),
|
|
51
|
-
json("limit")
|
|
52
|
-
],
|
|
53
|
-
"app:mail.send": [
|
|
54
|
-
json("to", true),
|
|
55
|
-
text("subject", true),
|
|
56
|
-
text("text", true),
|
|
57
|
-
text("html"),
|
|
58
|
-
json("attachments")
|
|
59
|
-
],
|
|
60
|
-
"app:piece": [
|
|
61
|
-
text("piece", true),
|
|
62
|
-
text("action", true),
|
|
63
|
-
text("connection"),
|
|
64
|
-
json("props")
|
|
65
|
-
]
|
|
66
|
-
};
|
|
67
|
-
/** The names of the arguments each step type needs, as the definition check takes them. */
|
|
68
|
-
const requiredStepInputs = Object.fromEntries(Object.entries(workflowStepTypes).map(([type, inputs]) => [type, inputs.filter((input) => input.required).map((input) => input.name)]));
|
|
69
|
-
//#endregion
|
|
70
|
-
export { requiredStepInputs, workflowStepTypes };
|