@octaviaflow/flow-rules 0.11.1 → 0.12.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/catalog/actions/console-log/config.d.ts +1 -0
- package/dist/catalog/actions/delay/config.d.ts +1 -0
- package/dist/catalog/actions/http-request/config.d.ts +4 -0
- package/dist/catalog/communication/email-send/config.d.ts +2 -0
- package/dist/catalog/communication/webhook-call/config.d.ts +1 -0
- package/dist/catalog/communication/whatsapp-send/config.d.ts +1 -0
- package/dist/catalog/general/query/config.d.ts +4 -0
- package/dist/catalog/general/transform/config.d.ts +15 -0
- package/dist/catalog/logic/condition/config.d.ts +1 -0
- package/dist/catalog/logic/for-each/config.d.ts +4 -0
- package/dist/catalog/storage/file-operation/config.d.ts +1 -0
- package/dist/catalog/transforms/format/config.d.ts +1 -0
- package/dist/catalog/triggers/schedule-trigger/config.d.ts +2 -0
- package/dist/catalog/triggers/webhook-trigger/config.d.ts +1 -0
- package/dist/catalog/utility/debug/config.d.ts +1 -0
- package/dist/index.cjs +86 -21
- package/dist/index.d.ts +2 -2
- package/dist/index.js +86 -21
- package/dist/rules/configContracts.d.ts +23 -0
- package/package.json +1 -1
|
@@ -72,6 +72,7 @@ export declare const HTTPRequestConfig: {
|
|
|
72
72
|
apiType: {
|
|
73
73
|
type: string;
|
|
74
74
|
required: boolean;
|
|
75
|
+
options: string[];
|
|
75
76
|
};
|
|
76
77
|
baseUrl: {
|
|
77
78
|
type: string;
|
|
@@ -84,6 +85,7 @@ export declare const HTTPRequestConfig: {
|
|
|
84
85
|
bodyType: {
|
|
85
86
|
type: string;
|
|
86
87
|
required: boolean;
|
|
88
|
+
options: string[];
|
|
87
89
|
};
|
|
88
90
|
formData: {
|
|
89
91
|
type: string;
|
|
@@ -124,6 +126,7 @@ export declare const HTTPRequestConfig: {
|
|
|
124
126
|
responseType: {
|
|
125
127
|
type: string;
|
|
126
128
|
required: boolean;
|
|
129
|
+
options: string[];
|
|
127
130
|
};
|
|
128
131
|
expectedContentTypes: {
|
|
129
132
|
type: string;
|
|
@@ -132,6 +135,7 @@ export declare const HTTPRequestConfig: {
|
|
|
132
135
|
method: {
|
|
133
136
|
type: string;
|
|
134
137
|
required: boolean;
|
|
138
|
+
options: string[];
|
|
135
139
|
description: string;
|
|
136
140
|
};
|
|
137
141
|
url: {
|
|
@@ -48,10 +48,14 @@ export declare const BuildQueryContractSchema: {
|
|
|
48
48
|
readonly mode: {
|
|
49
49
|
readonly type: "select";
|
|
50
50
|
readonly required: true;
|
|
51
|
+
readonly options: readonly ["visual", "sql"];
|
|
52
|
+
readonly description: "visual: the query is built from visualConfig; sql: the query is the text in sqlConfig.sql";
|
|
51
53
|
};
|
|
52
54
|
readonly queryType: {
|
|
53
55
|
readonly type: "select";
|
|
54
56
|
readonly required: true;
|
|
57
|
+
readonly options: readonly ["select", "insert", "update", "delete", "custom"];
|
|
58
|
+
readonly description: "Only select is a read; the write types exist for the SQL mode of database connectors";
|
|
55
59
|
};
|
|
56
60
|
readonly visualConfig: {
|
|
57
61
|
readonly type: "object";
|
|
@@ -26,6 +26,14 @@ export interface FieldMapping {
|
|
|
26
26
|
depth?: number;
|
|
27
27
|
}
|
|
28
28
|
export type TransformMode = 'visual' | 'expression';
|
|
29
|
+
/**
|
|
30
|
+
* The authoring modes. `visual` is the Field Mapper and the only mode the panel
|
|
31
|
+
* offers; `expression` is the retired JavaScript mode, kept so steps saved in it
|
|
32
|
+
* still run. Anything else is not a mode: the Engine fails the step with
|
|
33
|
+
* "Unknown transform mode" at run time, against the customer's live systems —
|
|
34
|
+
* which is how an agent's guess of `"append"` surfaced (DEV-421).
|
|
35
|
+
*/
|
|
36
|
+
export declare const TRANSFORM_MODES: readonly TransformMode[];
|
|
29
37
|
/** Data operation the user wants to perform */
|
|
30
38
|
export type TransformOperation = 'upsert' | 'insert' | 'update' | 'delete';
|
|
31
39
|
export declare const TRANSFORM_OPERATIONS: {
|
|
@@ -82,6 +90,8 @@ export declare const TransformConfig: {
|
|
|
82
90
|
operation: {
|
|
83
91
|
type: string;
|
|
84
92
|
required: boolean;
|
|
93
|
+
options: readonly TransformOperation[];
|
|
94
|
+
description: string;
|
|
85
95
|
};
|
|
86
96
|
connectorId: {
|
|
87
97
|
type: string;
|
|
@@ -90,14 +100,19 @@ export declare const TransformConfig: {
|
|
|
90
100
|
database: {
|
|
91
101
|
type: string;
|
|
92
102
|
required: boolean;
|
|
103
|
+
description: string;
|
|
93
104
|
};
|
|
94
105
|
objectName: {
|
|
95
106
|
type: string;
|
|
96
107
|
required: boolean;
|
|
108
|
+
dynamic: boolean;
|
|
109
|
+
description: string;
|
|
97
110
|
};
|
|
98
111
|
mode: {
|
|
99
112
|
type: string;
|
|
100
113
|
required: boolean;
|
|
114
|
+
options: readonly TransformMode[];
|
|
115
|
+
description: string;
|
|
101
116
|
};
|
|
102
117
|
mappings: {
|
|
103
118
|
type: string;
|
|
@@ -68,10 +68,14 @@ export declare const ForEachConfig: {
|
|
|
68
68
|
arrayPath: {
|
|
69
69
|
type: string;
|
|
70
70
|
required: boolean;
|
|
71
|
+
dynamic: boolean;
|
|
72
|
+
description: string;
|
|
71
73
|
};
|
|
72
74
|
iterationMode: {
|
|
73
75
|
type: string;
|
|
74
76
|
required: boolean;
|
|
77
|
+
options: string[];
|
|
78
|
+
description: string;
|
|
75
79
|
};
|
|
76
80
|
itemVariable: {
|
|
77
81
|
type: string;
|
|
@@ -14,6 +14,7 @@ export declare const ScheduleTriggerConfig: {
|
|
|
14
14
|
scheduleType: {
|
|
15
15
|
type: string;
|
|
16
16
|
required: boolean;
|
|
17
|
+
options: string[];
|
|
17
18
|
};
|
|
18
19
|
interval: {
|
|
19
20
|
type: string;
|
|
@@ -23,6 +24,7 @@ export declare const ScheduleTriggerConfig: {
|
|
|
23
24
|
intervalUnit: {
|
|
24
25
|
type: string;
|
|
25
26
|
required: boolean;
|
|
27
|
+
options: string[];
|
|
26
28
|
};
|
|
27
29
|
cronExpression: {
|
|
28
30
|
type: string;
|
package/dist/index.cjs
CHANGED
|
@@ -96,6 +96,7 @@ __export(exports_src, {
|
|
|
96
96
|
STORAGE_CONNECTOR_IDS: () => STORAGE_CONNECTOR_IDS,
|
|
97
97
|
SortDirection: () => SortDirection,
|
|
98
98
|
StorageActionConfig: () => StorageActionConfig,
|
|
99
|
+
TRANSFORM_MODES: () => TRANSFORM_MODES,
|
|
99
100
|
TRANSFORM_OPERATIONS: () => TRANSFORM_OPERATIONS,
|
|
100
101
|
TransformConfig: () => TransformConfig,
|
|
101
102
|
USER_FUNCTION_PREFIX: () => USER_FUNCTION_PREFIX,
|
|
@@ -137,6 +138,7 @@ __export(exports_src, {
|
|
|
137
138
|
mappingTransformFunctionName: () => mappingTransformFunctionName,
|
|
138
139
|
migrateDelayConfig: () => migrateDelayConfig,
|
|
139
140
|
queryDefinition: () => queryDefinition,
|
|
141
|
+
selectsWithoutValues: () => selectsWithoutValues,
|
|
140
142
|
storageConfigKeys: () => storageConfigKeys,
|
|
141
143
|
storageOperations: () => storageOperations,
|
|
142
144
|
summarizeConnectorTriggerEvents: () => summarizeConnectorTriggerEvents,
|
|
@@ -1411,8 +1413,18 @@ function isQueryableConnector(connector) {
|
|
|
1411
1413
|
}
|
|
1412
1414
|
var BuildQueryContractSchema = {
|
|
1413
1415
|
connectorId: { type: "connection", required: true },
|
|
1414
|
-
mode: {
|
|
1415
|
-
|
|
1416
|
+
mode: {
|
|
1417
|
+
type: "select",
|
|
1418
|
+
required: true,
|
|
1419
|
+
options: ["visual", "sql"],
|
|
1420
|
+
description: "visual: the query is built from visualConfig; sql: the query is the text in sqlConfig.sql"
|
|
1421
|
+
},
|
|
1422
|
+
queryType: {
|
|
1423
|
+
type: "select",
|
|
1424
|
+
required: true,
|
|
1425
|
+
options: ["select", "insert", "update", "delete", "custom"],
|
|
1426
|
+
description: "Only select is a read; the write types exist for the SQL mode of database connectors"
|
|
1427
|
+
},
|
|
1416
1428
|
visualConfig: { type: "object", required: false },
|
|
1417
1429
|
sqlConfig: { type: "object", required: false },
|
|
1418
1430
|
timeout: { type: "number", required: false },
|
|
@@ -3312,7 +3324,7 @@ var ConditionConfig = {
|
|
|
3312
3324
|
condition: ""
|
|
3313
3325
|
},
|
|
3314
3326
|
schema: {
|
|
3315
|
-
mode: { type: "select", required: true },
|
|
3327
|
+
mode: { type: "select", required: true, options: ["visual", "expression"] },
|
|
3316
3328
|
filters: { type: "array", required: false },
|
|
3317
3329
|
condition: { type: "expression", required: false }
|
|
3318
3330
|
},
|
|
@@ -3382,8 +3394,18 @@ var ForEachConfig = {
|
|
|
3382
3394
|
collect: "array"
|
|
3383
3395
|
},
|
|
3384
3396
|
schema: {
|
|
3385
|
-
arrayPath: {
|
|
3386
|
-
|
|
3397
|
+
arrayPath: {
|
|
3398
|
+
type: "select",
|
|
3399
|
+
required: false,
|
|
3400
|
+
dynamic: true,
|
|
3401
|
+
description: "A path to an array in the upstream step's output (the Query's object name, or a field holding a list) — the values come from that step's data, not from the catalog"
|
|
3402
|
+
},
|
|
3403
|
+
iterationMode: {
|
|
3404
|
+
type: "select",
|
|
3405
|
+
required: false,
|
|
3406
|
+
options: ["records", "fields", "range", "nested", "batch", "cursor", "while", "array"],
|
|
3407
|
+
description: "What one iteration is: records (one per record, the default; array is its legacy alias), fields, range, nested, batch, cursor or while"
|
|
3408
|
+
},
|
|
3387
3409
|
itemVariable: { type: "string", required: true },
|
|
3388
3410
|
indexVariable: { type: "string", required: false },
|
|
3389
3411
|
batchSize: { type: "number", required: false },
|
|
@@ -3587,7 +3609,7 @@ function fieldToJsonSchema(f) {
|
|
|
3587
3609
|
// src/catalog/utility/debug/config.ts
|
|
3588
3610
|
var DebugConfig = {
|
|
3589
3611
|
schema: {
|
|
3590
|
-
mode: { type: "select", required: true },
|
|
3612
|
+
mode: { type: "select", required: true, options: ["log", "snapshot", "watch", "assert", "profile"] },
|
|
3591
3613
|
label: { type: "string", required: false },
|
|
3592
3614
|
pinned: { type: "boolean", required: false },
|
|
3593
3615
|
condition: { type: "expression", required: false },
|
|
@@ -3702,7 +3724,12 @@ var EmailConfig = {
|
|
|
3702
3724
|
},
|
|
3703
3725
|
schema: {
|
|
3704
3726
|
connection: { type: "connection", required: true },
|
|
3705
|
-
operation: {
|
|
3727
|
+
operation: {
|
|
3728
|
+
type: "select",
|
|
3729
|
+
required: true,
|
|
3730
|
+
options: ["send", "read", "search", "delete", "move", "mark_read"],
|
|
3731
|
+
description: "Only send runs today (DEV-349); the other values are kept so older steps still parse, and validate() rejects them"
|
|
3732
|
+
},
|
|
3706
3733
|
to: { type: "string", required: false },
|
|
3707
3734
|
cc: { type: "string", required: false },
|
|
3708
3735
|
bcc: { type: "string", required: false },
|
|
@@ -3755,12 +3782,15 @@ var EmailConfig = {
|
|
|
3755
3782
|
}
|
|
3756
3783
|
};
|
|
3757
3784
|
// src/catalog/general/transform/config.ts
|
|
3785
|
+
var TRANSFORM_MODES = ["visual", "expression"];
|
|
3758
3786
|
var TRANSFORM_OPERATIONS = [
|
|
3759
3787
|
{ id: "upsert", label: "Upsert" },
|
|
3760
3788
|
{ id: "insert", label: "Insert" },
|
|
3761
3789
|
{ id: "update", label: "Update" },
|
|
3762
3790
|
{ id: "delete", label: "Delete" }
|
|
3763
3791
|
];
|
|
3792
|
+
var TRANSFORM_OPERATION_IDS = TRANSFORM_OPERATIONS.map((o) => o.id);
|
|
3793
|
+
var isOneOf = (set, value) => typeof value === "string" && set.includes(value);
|
|
3764
3794
|
var DATABASE_CONNECTOR_IDS = new Set(["mongodb", "postgresql", "mysql", "sqlite", "google_sheets"]);
|
|
3765
3795
|
var TransformConfig = {
|
|
3766
3796
|
defaults: {
|
|
@@ -3784,11 +3814,30 @@ var TransformConfig = {
|
|
|
3784
3814
|
},
|
|
3785
3815
|
schema: {
|
|
3786
3816
|
name: { type: "string", required: false },
|
|
3787
|
-
operation: {
|
|
3817
|
+
operation: {
|
|
3818
|
+
type: "select",
|
|
3819
|
+
required: true,
|
|
3820
|
+
options: TRANSFORM_OPERATION_IDS,
|
|
3821
|
+
description: "What to do with each mapped record at the target: upsert, insert, update or delete"
|
|
3822
|
+
},
|
|
3788
3823
|
connectorId: { type: "connection", required: true },
|
|
3789
|
-
database: {
|
|
3790
|
-
|
|
3791
|
-
|
|
3824
|
+
database: {
|
|
3825
|
+
type: "text",
|
|
3826
|
+
required: false,
|
|
3827
|
+
description: "Database name for MongoDB / PostgreSQL / MySQL / SQLite; the spreadsheet id for Google Sheets"
|
|
3828
|
+
},
|
|
3829
|
+
objectName: {
|
|
3830
|
+
type: "select",
|
|
3831
|
+
required: true,
|
|
3832
|
+
dynamic: true,
|
|
3833
|
+
description: "The table, entity, object or sheet tab to write to — the names come from the connected app (describe_connector_object)"
|
|
3834
|
+
},
|
|
3835
|
+
mode: {
|
|
3836
|
+
type: "select",
|
|
3837
|
+
required: true,
|
|
3838
|
+
options: TRANSFORM_MODES,
|
|
3839
|
+
description: "How the mappings are authored: visual (the Field Mapper — the only mode the editor offers) or expression (legacy JavaScript). This is not the write mode; that is `operation`."
|
|
3840
|
+
},
|
|
3792
3841
|
mappings: { type: "array", required: false },
|
|
3793
3842
|
expression: { type: "code", required: false }
|
|
3794
3843
|
},
|
|
@@ -3802,6 +3851,12 @@ var TransformConfig = {
|
|
|
3802
3851
|
const errors = [];
|
|
3803
3852
|
if (!config.operation) {
|
|
3804
3853
|
errors.push("Operation is required");
|
|
3854
|
+
} else if (!isOneOf(TRANSFORM_OPERATION_IDS, config.operation)) {
|
|
3855
|
+
errors.push(`Operation must be one of: ${TRANSFORM_OPERATION_IDS.join(", ")} (got "${String(config.operation)}")`);
|
|
3856
|
+
}
|
|
3857
|
+
const mode = config.mode;
|
|
3858
|
+
if (mode !== undefined && mode !== null && mode !== "" && !isOneOf(TRANSFORM_MODES, mode)) {
|
|
3859
|
+
errors.push(`Mode must be one of: ${TRANSFORM_MODES.join(", ")} (got "${String(mode)}"). ` + `Mode is how the mappings are authored, not how rows are written — for that, see operation.`);
|
|
3805
3860
|
}
|
|
3806
3861
|
if (!config.connectorId) {
|
|
3807
3862
|
errors.push("Target connector is required");
|
|
@@ -5005,6 +5060,7 @@ var ConsoleLogConfig = {
|
|
|
5005
5060
|
level: {
|
|
5006
5061
|
type: "select",
|
|
5007
5062
|
required: false,
|
|
5063
|
+
options: ["info", "warning", "error", "debug"],
|
|
5008
5064
|
description: "Log level for the message"
|
|
5009
5065
|
},
|
|
5010
5066
|
data: {
|
|
@@ -5055,6 +5111,7 @@ var DelayConfig = {
|
|
|
5055
5111
|
unit: {
|
|
5056
5112
|
type: "select",
|
|
5057
5113
|
required: false,
|
|
5114
|
+
options: ["milliseconds", "seconds", "minutes", "hours"],
|
|
5058
5115
|
description: "Time unit for the duration"
|
|
5059
5116
|
}
|
|
5060
5117
|
},
|
|
@@ -5119,10 +5176,10 @@ var HTTPRequestConfig = {
|
|
|
5119
5176
|
expectedContentTypes: []
|
|
5120
5177
|
},
|
|
5121
5178
|
schema: {
|
|
5122
|
-
apiType: { type: "select", required: false },
|
|
5179
|
+
apiType: { type: "select", required: false, options: ["rest", "graphql"] },
|
|
5123
5180
|
baseUrl: { type: "string", required: false },
|
|
5124
5181
|
queryParams: { type: "array", required: false },
|
|
5125
|
-
bodyType: { type: "select", required: false },
|
|
5182
|
+
bodyType: { type: "select", required: false, options: ["none", "json", "raw", "form-data", "xml"] },
|
|
5126
5183
|
formData: { type: "array", required: false },
|
|
5127
5184
|
graphqlQuery: { type: "code", required: false },
|
|
5128
5185
|
graphqlVariables: { type: "json", required: false },
|
|
@@ -5132,11 +5189,12 @@ var HTTPRequestConfig = {
|
|
|
5132
5189
|
retry: { type: "object", required: false },
|
|
5133
5190
|
pagination: { type: "object", required: false },
|
|
5134
5191
|
extract: { type: "object", required: false },
|
|
5135
|
-
responseType: { type: "select", required: false },
|
|
5192
|
+
responseType: { type: "select", required: false, options: ["json", "text", "binary"] },
|
|
5136
5193
|
expectedContentTypes: { type: "array", required: false },
|
|
5137
5194
|
method: {
|
|
5138
5195
|
type: "select",
|
|
5139
5196
|
required: true,
|
|
5197
|
+
options: ["GET", "POST", "PUT", "PATCH", "DELETE", "HEAD", "OPTIONS"],
|
|
5140
5198
|
description: "HTTP method to use"
|
|
5141
5199
|
},
|
|
5142
5200
|
url: {
|
|
@@ -5326,7 +5384,7 @@ var WebhookCallConfig = {
|
|
|
5326
5384
|
},
|
|
5327
5385
|
schema: {
|
|
5328
5386
|
url: { type: "url", required: true },
|
|
5329
|
-
method: { type: "select", required: true },
|
|
5387
|
+
method: { type: "select", required: true, options: ["POST", "PUT", "PATCH", "GET"] },
|
|
5330
5388
|
payload: { type: "json", required: false },
|
|
5331
5389
|
headers: { type: "json", required: false }
|
|
5332
5390
|
},
|
|
@@ -5351,7 +5409,7 @@ var WhatsappSendConfig = {
|
|
|
5351
5409
|
schema: {
|
|
5352
5410
|
connection: { type: "connection", required: true },
|
|
5353
5411
|
to: { type: "string", required: true },
|
|
5354
|
-
mode: { type: "select", required: true },
|
|
5412
|
+
mode: { type: "select", required: true, options: ["template", "text"] },
|
|
5355
5413
|
templateName: { type: "string", required: false },
|
|
5356
5414
|
templateLanguage: { type: "string", required: false },
|
|
5357
5415
|
templateVariables: { type: "array", required: false },
|
|
@@ -5398,7 +5456,7 @@ var FileOperationConfig = {
|
|
|
5398
5456
|
},
|
|
5399
5457
|
schema: {
|
|
5400
5458
|
connection: { type: "connection", required: true },
|
|
5401
|
-
operation: { type: "select", required: true },
|
|
5459
|
+
operation: { type: "select", required: true, options: ["upload", "download", "delete", "list", "copy", "move", "exists"] },
|
|
5402
5460
|
sourcePath: { type: "string", required: false },
|
|
5403
5461
|
destinationPath: { type: "string", required: true },
|
|
5404
5462
|
fileContent: { type: "string", required: false },
|
|
@@ -5432,7 +5490,7 @@ var FormatConfig = {
|
|
|
5432
5490
|
defaults: { input: "", format: "json" },
|
|
5433
5491
|
schema: {
|
|
5434
5492
|
input: { type: "expression", required: true },
|
|
5435
|
-
format: { type: "select", required: true }
|
|
5493
|
+
format: { type: "select", required: true, options: ["json", "csv", "xml", "yaml"] }
|
|
5436
5494
|
},
|
|
5437
5495
|
validate: (config) => {
|
|
5438
5496
|
const errors = [];
|
|
@@ -5457,9 +5515,9 @@ var ScheduleTriggerConfig = {
|
|
|
5457
5515
|
timezone: "UTC"
|
|
5458
5516
|
},
|
|
5459
5517
|
schema: {
|
|
5460
|
-
scheduleType: { type: "select", required: true },
|
|
5518
|
+
scheduleType: { type: "select", required: true, options: ["interval", "cron", "specific"] },
|
|
5461
5519
|
interval: { type: "number", required: false, min: 1 },
|
|
5462
|
-
intervalUnit: { type: "select", required: false },
|
|
5520
|
+
intervalUnit: { type: "select", required: false, options: ["minutes", "hours", "days", "weeks"] },
|
|
5463
5521
|
cronExpression: { type: "string", required: false },
|
|
5464
5522
|
timezone: { type: "string", required: false }
|
|
5465
5523
|
},
|
|
@@ -5497,7 +5555,7 @@ var WebhookTriggerConfig = {
|
|
|
5497
5555
|
},
|
|
5498
5556
|
schema: {
|
|
5499
5557
|
webhookPath: { type: "string", required: false },
|
|
5500
|
-
method: { type: "select", required: true },
|
|
5558
|
+
method: { type: "select", required: true, options: ["GET", "POST", "PUT", "PATCH", "DELETE"] },
|
|
5501
5559
|
requireAuth: { type: "boolean", required: false }
|
|
5502
5560
|
},
|
|
5503
5561
|
validate: (config) => {
|
|
@@ -5631,11 +5689,18 @@ function contractFieldsFor(definition) {
|
|
|
5631
5689
|
label: humanise(key),
|
|
5632
5690
|
type: CONTRACT_TYPE_TO_FIELD_TYPE[field.type] ?? "string" /* String */,
|
|
5633
5691
|
validation: { required: field.required === true },
|
|
5692
|
+
...typeof field.description === "string" && field.description ? { description: field.description } : {},
|
|
5634
5693
|
...field.options ? { options: field.options.map((v) => ({ label: String(v), value: v })) } : {}
|
|
5635
5694
|
});
|
|
5636
5695
|
}
|
|
5637
5696
|
return [...declared, ...derived];
|
|
5638
5697
|
}
|
|
5698
|
+
function selectsWithoutValues(actionId) {
|
|
5699
|
+
const contract = contractFor(actionId);
|
|
5700
|
+
if (!contract)
|
|
5701
|
+
return [];
|
|
5702
|
+
return Object.entries(contract.schema).filter(([, f]) => f.type === "select" && !(f.options && f.options.length > 0) && f.dynamic !== true).map(([key]) => key);
|
|
5703
|
+
}
|
|
5639
5704
|
function contractDrift(definition) {
|
|
5640
5705
|
const contract = contractFor(definition.id);
|
|
5641
5706
|
if (!contract)
|
package/dist/index.d.ts
CHANGED
|
@@ -36,7 +36,7 @@ export { EmailConfig, } from "./catalog/communication/email-send/config";
|
|
|
36
36
|
export { queryDefinition, } from "./catalog/general/query/index";
|
|
37
37
|
export { isQueryableConnector, } from "./catalog/general/query/config";
|
|
38
38
|
export { AggregateFunction, type BuildQueryConfig, type ColumnSchema, type ConnectorSchema, JoinType, LogicalOperator, type QueryExecutionResult, type QueryField, type QueryFilter, type QueryFilterGroup, type QueryJoin, type QuerySort, SortDirection, type VisualQueryConfig, } from "./catalog/general/query/types";
|
|
39
|
-
export { DATABASE_CONNECTOR_IDS, type FieldMapping, TRANSFORM_OPERATIONS, TransformConfig, type TransformConfigType, type TransformOperation, } from "./catalog/general/transform/config";
|
|
39
|
+
export { DATABASE_CONNECTOR_IDS, type FieldMapping, TRANSFORM_MODES, TRANSFORM_OPERATIONS, TransformConfig, type TransformConfigType, type TransformOperation, } from "./catalog/general/transform/config";
|
|
40
40
|
export { STORAGE_CONNECTOR_IDS, type StorageExtraField, type StoragePathField, getStorageProvider, storageConfigKeys, } from "./catalog/storage/storageCapabilities";
|
|
41
41
|
export { ManualTriggerConfig } from "./catalog/triggers/manual-trigger/index";
|
|
42
42
|
export { AiAgentConfig, type AiAgentConfigType, type AiAgentOverrides } from "./catalog/ai/ai-agent/config";
|
|
@@ -62,4 +62,4 @@ export { type FlowConnection, type FlowData, type FlowStep, generateConnectionsF
|
|
|
62
62
|
export { flattenNestedWorkflow } from "./rules/flattenNestedWorkflow";
|
|
63
63
|
export { configErrors, MAX_STEP_CONFIG_BYTES, validateStepConfig, PLATFORM_CONFIG_KEYS, validateStepConfigs, type ConfigIssue, type ConfigIssueCode, } from "./rules/configSafety";
|
|
64
64
|
export { isMappingFunction, MAPPING_FUNCTION_SPECS, MAPPING_FUNCTIONS, mappingTransformFunctionName, USER_FUNCTION_PREFIX, type MappingFunction, type MappingFunctionSpec, } from "./rules/mappingFunctions";
|
|
65
|
-
export { CONFIG_CONTRACTS, contractDerivedKeys, contractDrift, contractFieldsFor, contractVocabularyDrift, contractFor, declaredKeys, isEditorPrivateKey, type ConfigContract, type ContractField, type ContractFieldType, } from "./rules/configContracts";
|
|
65
|
+
export { CONFIG_CONTRACTS, contractDerivedKeys, contractDrift, contractFieldsFor, contractVocabularyDrift, contractFor, declaredKeys, isEditorPrivateKey, selectsWithoutValues, type ConfigContract, type ContractField, type ContractFieldType, } from "./rules/configContracts";
|
package/dist/index.js
CHANGED
|
@@ -1256,8 +1256,18 @@ function isQueryableConnector(connector) {
|
|
|
1256
1256
|
}
|
|
1257
1257
|
var BuildQueryContractSchema = {
|
|
1258
1258
|
connectorId: { type: "connection", required: true },
|
|
1259
|
-
mode: {
|
|
1260
|
-
|
|
1259
|
+
mode: {
|
|
1260
|
+
type: "select",
|
|
1261
|
+
required: true,
|
|
1262
|
+
options: ["visual", "sql"],
|
|
1263
|
+
description: "visual: the query is built from visualConfig; sql: the query is the text in sqlConfig.sql"
|
|
1264
|
+
},
|
|
1265
|
+
queryType: {
|
|
1266
|
+
type: "select",
|
|
1267
|
+
required: true,
|
|
1268
|
+
options: ["select", "insert", "update", "delete", "custom"],
|
|
1269
|
+
description: "Only select is a read; the write types exist for the SQL mode of database connectors"
|
|
1270
|
+
},
|
|
1261
1271
|
visualConfig: { type: "object", required: false },
|
|
1262
1272
|
sqlConfig: { type: "object", required: false },
|
|
1263
1273
|
timeout: { type: "number", required: false },
|
|
@@ -3157,7 +3167,7 @@ var ConditionConfig = {
|
|
|
3157
3167
|
condition: ""
|
|
3158
3168
|
},
|
|
3159
3169
|
schema: {
|
|
3160
|
-
mode: { type: "select", required: true },
|
|
3170
|
+
mode: { type: "select", required: true, options: ["visual", "expression"] },
|
|
3161
3171
|
filters: { type: "array", required: false },
|
|
3162
3172
|
condition: { type: "expression", required: false }
|
|
3163
3173
|
},
|
|
@@ -3227,8 +3237,18 @@ var ForEachConfig = {
|
|
|
3227
3237
|
collect: "array"
|
|
3228
3238
|
},
|
|
3229
3239
|
schema: {
|
|
3230
|
-
arrayPath: {
|
|
3231
|
-
|
|
3240
|
+
arrayPath: {
|
|
3241
|
+
type: "select",
|
|
3242
|
+
required: false,
|
|
3243
|
+
dynamic: true,
|
|
3244
|
+
description: "A path to an array in the upstream step's output (the Query's object name, or a field holding a list) — the values come from that step's data, not from the catalog"
|
|
3245
|
+
},
|
|
3246
|
+
iterationMode: {
|
|
3247
|
+
type: "select",
|
|
3248
|
+
required: false,
|
|
3249
|
+
options: ["records", "fields", "range", "nested", "batch", "cursor", "while", "array"],
|
|
3250
|
+
description: "What one iteration is: records (one per record, the default; array is its legacy alias), fields, range, nested, batch, cursor or while"
|
|
3251
|
+
},
|
|
3232
3252
|
itemVariable: { type: "string", required: true },
|
|
3233
3253
|
indexVariable: { type: "string", required: false },
|
|
3234
3254
|
batchSize: { type: "number", required: false },
|
|
@@ -3432,7 +3452,7 @@ function fieldToJsonSchema(f) {
|
|
|
3432
3452
|
// src/catalog/utility/debug/config.ts
|
|
3433
3453
|
var DebugConfig = {
|
|
3434
3454
|
schema: {
|
|
3435
|
-
mode: { type: "select", required: true },
|
|
3455
|
+
mode: { type: "select", required: true, options: ["log", "snapshot", "watch", "assert", "profile"] },
|
|
3436
3456
|
label: { type: "string", required: false },
|
|
3437
3457
|
pinned: { type: "boolean", required: false },
|
|
3438
3458
|
condition: { type: "expression", required: false },
|
|
@@ -3547,7 +3567,12 @@ var EmailConfig = {
|
|
|
3547
3567
|
},
|
|
3548
3568
|
schema: {
|
|
3549
3569
|
connection: { type: "connection", required: true },
|
|
3550
|
-
operation: {
|
|
3570
|
+
operation: {
|
|
3571
|
+
type: "select",
|
|
3572
|
+
required: true,
|
|
3573
|
+
options: ["send", "read", "search", "delete", "move", "mark_read"],
|
|
3574
|
+
description: "Only send runs today (DEV-349); the other values are kept so older steps still parse, and validate() rejects them"
|
|
3575
|
+
},
|
|
3551
3576
|
to: { type: "string", required: false },
|
|
3552
3577
|
cc: { type: "string", required: false },
|
|
3553
3578
|
bcc: { type: "string", required: false },
|
|
@@ -3600,12 +3625,15 @@ var EmailConfig = {
|
|
|
3600
3625
|
}
|
|
3601
3626
|
};
|
|
3602
3627
|
// src/catalog/general/transform/config.ts
|
|
3628
|
+
var TRANSFORM_MODES = ["visual", "expression"];
|
|
3603
3629
|
var TRANSFORM_OPERATIONS = [
|
|
3604
3630
|
{ id: "upsert", label: "Upsert" },
|
|
3605
3631
|
{ id: "insert", label: "Insert" },
|
|
3606
3632
|
{ id: "update", label: "Update" },
|
|
3607
3633
|
{ id: "delete", label: "Delete" }
|
|
3608
3634
|
];
|
|
3635
|
+
var TRANSFORM_OPERATION_IDS = TRANSFORM_OPERATIONS.map((o) => o.id);
|
|
3636
|
+
var isOneOf = (set, value) => typeof value === "string" && set.includes(value);
|
|
3609
3637
|
var DATABASE_CONNECTOR_IDS = new Set(["mongodb", "postgresql", "mysql", "sqlite", "google_sheets"]);
|
|
3610
3638
|
var TransformConfig = {
|
|
3611
3639
|
defaults: {
|
|
@@ -3629,11 +3657,30 @@ var TransformConfig = {
|
|
|
3629
3657
|
},
|
|
3630
3658
|
schema: {
|
|
3631
3659
|
name: { type: "string", required: false },
|
|
3632
|
-
operation: {
|
|
3660
|
+
operation: {
|
|
3661
|
+
type: "select",
|
|
3662
|
+
required: true,
|
|
3663
|
+
options: TRANSFORM_OPERATION_IDS,
|
|
3664
|
+
description: "What to do with each mapped record at the target: upsert, insert, update or delete"
|
|
3665
|
+
},
|
|
3633
3666
|
connectorId: { type: "connection", required: true },
|
|
3634
|
-
database: {
|
|
3635
|
-
|
|
3636
|
-
|
|
3667
|
+
database: {
|
|
3668
|
+
type: "text",
|
|
3669
|
+
required: false,
|
|
3670
|
+
description: "Database name for MongoDB / PostgreSQL / MySQL / SQLite; the spreadsheet id for Google Sheets"
|
|
3671
|
+
},
|
|
3672
|
+
objectName: {
|
|
3673
|
+
type: "select",
|
|
3674
|
+
required: true,
|
|
3675
|
+
dynamic: true,
|
|
3676
|
+
description: "The table, entity, object or sheet tab to write to — the names come from the connected app (describe_connector_object)"
|
|
3677
|
+
},
|
|
3678
|
+
mode: {
|
|
3679
|
+
type: "select",
|
|
3680
|
+
required: true,
|
|
3681
|
+
options: TRANSFORM_MODES,
|
|
3682
|
+
description: "How the mappings are authored: visual (the Field Mapper — the only mode the editor offers) or expression (legacy JavaScript). This is not the write mode; that is `operation`."
|
|
3683
|
+
},
|
|
3637
3684
|
mappings: { type: "array", required: false },
|
|
3638
3685
|
expression: { type: "code", required: false }
|
|
3639
3686
|
},
|
|
@@ -3647,6 +3694,12 @@ var TransformConfig = {
|
|
|
3647
3694
|
const errors = [];
|
|
3648
3695
|
if (!config.operation) {
|
|
3649
3696
|
errors.push("Operation is required");
|
|
3697
|
+
} else if (!isOneOf(TRANSFORM_OPERATION_IDS, config.operation)) {
|
|
3698
|
+
errors.push(`Operation must be one of: ${TRANSFORM_OPERATION_IDS.join(", ")} (got "${String(config.operation)}")`);
|
|
3699
|
+
}
|
|
3700
|
+
const mode = config.mode;
|
|
3701
|
+
if (mode !== undefined && mode !== null && mode !== "" && !isOneOf(TRANSFORM_MODES, mode)) {
|
|
3702
|
+
errors.push(`Mode must be one of: ${TRANSFORM_MODES.join(", ")} (got "${String(mode)}"). ` + `Mode is how the mappings are authored, not how rows are written — for that, see operation.`);
|
|
3650
3703
|
}
|
|
3651
3704
|
if (!config.connectorId) {
|
|
3652
3705
|
errors.push("Target connector is required");
|
|
@@ -4850,6 +4903,7 @@ var ConsoleLogConfig = {
|
|
|
4850
4903
|
level: {
|
|
4851
4904
|
type: "select",
|
|
4852
4905
|
required: false,
|
|
4906
|
+
options: ["info", "warning", "error", "debug"],
|
|
4853
4907
|
description: "Log level for the message"
|
|
4854
4908
|
},
|
|
4855
4909
|
data: {
|
|
@@ -4900,6 +4954,7 @@ var DelayConfig = {
|
|
|
4900
4954
|
unit: {
|
|
4901
4955
|
type: "select",
|
|
4902
4956
|
required: false,
|
|
4957
|
+
options: ["milliseconds", "seconds", "minutes", "hours"],
|
|
4903
4958
|
description: "Time unit for the duration"
|
|
4904
4959
|
}
|
|
4905
4960
|
},
|
|
@@ -4964,10 +5019,10 @@ var HTTPRequestConfig = {
|
|
|
4964
5019
|
expectedContentTypes: []
|
|
4965
5020
|
},
|
|
4966
5021
|
schema: {
|
|
4967
|
-
apiType: { type: "select", required: false },
|
|
5022
|
+
apiType: { type: "select", required: false, options: ["rest", "graphql"] },
|
|
4968
5023
|
baseUrl: { type: "string", required: false },
|
|
4969
5024
|
queryParams: { type: "array", required: false },
|
|
4970
|
-
bodyType: { type: "select", required: false },
|
|
5025
|
+
bodyType: { type: "select", required: false, options: ["none", "json", "raw", "form-data", "xml"] },
|
|
4971
5026
|
formData: { type: "array", required: false },
|
|
4972
5027
|
graphqlQuery: { type: "code", required: false },
|
|
4973
5028
|
graphqlVariables: { type: "json", required: false },
|
|
@@ -4977,11 +5032,12 @@ var HTTPRequestConfig = {
|
|
|
4977
5032
|
retry: { type: "object", required: false },
|
|
4978
5033
|
pagination: { type: "object", required: false },
|
|
4979
5034
|
extract: { type: "object", required: false },
|
|
4980
|
-
responseType: { type: "select", required: false },
|
|
5035
|
+
responseType: { type: "select", required: false, options: ["json", "text", "binary"] },
|
|
4981
5036
|
expectedContentTypes: { type: "array", required: false },
|
|
4982
5037
|
method: {
|
|
4983
5038
|
type: "select",
|
|
4984
5039
|
required: true,
|
|
5040
|
+
options: ["GET", "POST", "PUT", "PATCH", "DELETE", "HEAD", "OPTIONS"],
|
|
4985
5041
|
description: "HTTP method to use"
|
|
4986
5042
|
},
|
|
4987
5043
|
url: {
|
|
@@ -5171,7 +5227,7 @@ var WebhookCallConfig = {
|
|
|
5171
5227
|
},
|
|
5172
5228
|
schema: {
|
|
5173
5229
|
url: { type: "url", required: true },
|
|
5174
|
-
method: { type: "select", required: true },
|
|
5230
|
+
method: { type: "select", required: true, options: ["POST", "PUT", "PATCH", "GET"] },
|
|
5175
5231
|
payload: { type: "json", required: false },
|
|
5176
5232
|
headers: { type: "json", required: false }
|
|
5177
5233
|
},
|
|
@@ -5196,7 +5252,7 @@ var WhatsappSendConfig = {
|
|
|
5196
5252
|
schema: {
|
|
5197
5253
|
connection: { type: "connection", required: true },
|
|
5198
5254
|
to: { type: "string", required: true },
|
|
5199
|
-
mode: { type: "select", required: true },
|
|
5255
|
+
mode: { type: "select", required: true, options: ["template", "text"] },
|
|
5200
5256
|
templateName: { type: "string", required: false },
|
|
5201
5257
|
templateLanguage: { type: "string", required: false },
|
|
5202
5258
|
templateVariables: { type: "array", required: false },
|
|
@@ -5243,7 +5299,7 @@ var FileOperationConfig = {
|
|
|
5243
5299
|
},
|
|
5244
5300
|
schema: {
|
|
5245
5301
|
connection: { type: "connection", required: true },
|
|
5246
|
-
operation: { type: "select", required: true },
|
|
5302
|
+
operation: { type: "select", required: true, options: ["upload", "download", "delete", "list", "copy", "move", "exists"] },
|
|
5247
5303
|
sourcePath: { type: "string", required: false },
|
|
5248
5304
|
destinationPath: { type: "string", required: true },
|
|
5249
5305
|
fileContent: { type: "string", required: false },
|
|
@@ -5277,7 +5333,7 @@ var FormatConfig = {
|
|
|
5277
5333
|
defaults: { input: "", format: "json" },
|
|
5278
5334
|
schema: {
|
|
5279
5335
|
input: { type: "expression", required: true },
|
|
5280
|
-
format: { type: "select", required: true }
|
|
5336
|
+
format: { type: "select", required: true, options: ["json", "csv", "xml", "yaml"] }
|
|
5281
5337
|
},
|
|
5282
5338
|
validate: (config) => {
|
|
5283
5339
|
const errors = [];
|
|
@@ -5302,9 +5358,9 @@ var ScheduleTriggerConfig = {
|
|
|
5302
5358
|
timezone: "UTC"
|
|
5303
5359
|
},
|
|
5304
5360
|
schema: {
|
|
5305
|
-
scheduleType: { type: "select", required: true },
|
|
5361
|
+
scheduleType: { type: "select", required: true, options: ["interval", "cron", "specific"] },
|
|
5306
5362
|
interval: { type: "number", required: false, min: 1 },
|
|
5307
|
-
intervalUnit: { type: "select", required: false },
|
|
5363
|
+
intervalUnit: { type: "select", required: false, options: ["minutes", "hours", "days", "weeks"] },
|
|
5308
5364
|
cronExpression: { type: "string", required: false },
|
|
5309
5365
|
timezone: { type: "string", required: false }
|
|
5310
5366
|
},
|
|
@@ -5342,7 +5398,7 @@ var WebhookTriggerConfig = {
|
|
|
5342
5398
|
},
|
|
5343
5399
|
schema: {
|
|
5344
5400
|
webhookPath: { type: "string", required: false },
|
|
5345
|
-
method: { type: "select", required: true },
|
|
5401
|
+
method: { type: "select", required: true, options: ["GET", "POST", "PUT", "PATCH", "DELETE"] },
|
|
5346
5402
|
requireAuth: { type: "boolean", required: false }
|
|
5347
5403
|
},
|
|
5348
5404
|
validate: (config) => {
|
|
@@ -5476,11 +5532,18 @@ function contractFieldsFor(definition) {
|
|
|
5476
5532
|
label: humanise(key),
|
|
5477
5533
|
type: CONTRACT_TYPE_TO_FIELD_TYPE[field.type] ?? "string" /* String */,
|
|
5478
5534
|
validation: { required: field.required === true },
|
|
5535
|
+
...typeof field.description === "string" && field.description ? { description: field.description } : {},
|
|
5479
5536
|
...field.options ? { options: field.options.map((v) => ({ label: String(v), value: v })) } : {}
|
|
5480
5537
|
});
|
|
5481
5538
|
}
|
|
5482
5539
|
return [...declared, ...derived];
|
|
5483
5540
|
}
|
|
5541
|
+
function selectsWithoutValues(actionId) {
|
|
5542
|
+
const contract = contractFor(actionId);
|
|
5543
|
+
if (!contract)
|
|
5544
|
+
return [];
|
|
5545
|
+
return Object.entries(contract.schema).filter(([, f]) => f.type === "select" && !(f.options && f.options.length > 0) && f.dynamic !== true).map(([key]) => key);
|
|
5546
|
+
}
|
|
5484
5547
|
function contractDrift(definition) {
|
|
5485
5548
|
const contract = contractFor(definition.id);
|
|
5486
5549
|
if (!contract)
|
|
@@ -5807,6 +5870,7 @@ export {
|
|
|
5807
5870
|
STORAGE_CONNECTOR_IDS,
|
|
5808
5871
|
SortDirection,
|
|
5809
5872
|
StorageActionConfig,
|
|
5873
|
+
TRANSFORM_MODES,
|
|
5810
5874
|
TRANSFORM_OPERATIONS,
|
|
5811
5875
|
TransformConfig,
|
|
5812
5876
|
USER_FUNCTION_PREFIX,
|
|
@@ -5848,6 +5912,7 @@ export {
|
|
|
5848
5912
|
mappingTransformFunctionName,
|
|
5849
5913
|
migrateDelayConfig,
|
|
5850
5914
|
queryDefinition,
|
|
5915
|
+
selectsWithoutValues,
|
|
5851
5916
|
storageConfigKeys,
|
|
5852
5917
|
storageOperations,
|
|
5853
5918
|
summarizeConnectorTriggerEvents,
|
|
@@ -42,7 +42,23 @@ export type ContractFieldType = "string" | "text" | "select" | "json" | "connect
|
|
|
42
42
|
export interface ContractField {
|
|
43
43
|
type: string;
|
|
44
44
|
required?: boolean;
|
|
45
|
+
/**
|
|
46
|
+
* The values a `select` accepts, when the set is fixed. `describe_action_type`
|
|
47
|
+
* lists them and the fence warns on a value outside them (`FIELD_BAD_OPTION`).
|
|
48
|
+
* A select with no `options` must say `dynamic: true` instead — the catalog
|
|
49
|
+
* test fails on one that says neither, because a select an agent cannot see
|
|
50
|
+
* the values of is a guess waiting to fail at run time (`mode: "append"` on a
|
|
51
|
+
* Transform, DEV-421).
|
|
52
|
+
*/
|
|
45
53
|
options?: ReadonlyArray<string | number>;
|
|
54
|
+
/**
|
|
55
|
+
* The values come from the customer's own system or from the upstream data
|
|
56
|
+
* (an object name, a sheet tab, an array path) — not from the catalog. Say
|
|
57
|
+
* where in `description`; `describe_connector_object` is the usual answer.
|
|
58
|
+
*/
|
|
59
|
+
dynamic?: boolean;
|
|
60
|
+
/** Shown by the panel and by `describe_action_type`. */
|
|
61
|
+
description?: string;
|
|
46
62
|
[extra: string]: unknown;
|
|
47
63
|
}
|
|
48
64
|
export interface ConfigContract {
|
|
@@ -80,6 +96,13 @@ export declare function isEditorPrivateKey(key: string): boolean;
|
|
|
80
96
|
* editor should read.
|
|
81
97
|
*/
|
|
82
98
|
export declare function contractFieldsFor(definition: ActionDefinition): FieldConfig[];
|
|
99
|
+
/**
|
|
100
|
+
* Every `select` in a contract that names neither its `options` nor
|
|
101
|
+
* `dynamic: true`. A non-empty result is a bug: `describe_action_type` would
|
|
102
|
+
* show the field as a choice with nothing to choose from, and an agent would
|
|
103
|
+
* guess. The catalog test fails on any.
|
|
104
|
+
*/
|
|
105
|
+
export declare function selectsWithoutValues(actionId: string): string[];
|
|
83
106
|
/**
|
|
84
107
|
* `inputSchema` keys the contract does NOT know. A non-empty result is a bug:
|
|
85
108
|
* `describe_action_type` is advertising a key the platform does not store under
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@octaviaflow/flow-rules",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.12.0",
|
|
4
4
|
"description": "The flow action catalog and the rules engine behind Flow Doctor — one definition of what a step accepts and what makes a flow valid, shared by the editor and the server",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|