@octaviaflow/flow-rules 0.11.1 → 0.13.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.
@@ -36,6 +36,7 @@ export declare const ConsoleLogConfig: {
36
36
  level: {
37
37
  type: string;
38
38
  required: boolean;
39
+ options: string[];
39
40
  description: string;
40
41
  };
41
42
  data: {
@@ -25,6 +25,7 @@ export declare const DelayConfig: {
25
25
  unit: {
26
26
  type: string;
27
27
  required: boolean;
28
+ options: string[];
28
29
  description: string;
29
30
  };
30
31
  };
@@ -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: {
@@ -29,6 +29,8 @@ export declare const EmailConfig: {
29
29
  operation: {
30
30
  type: string;
31
31
  required: boolean;
32
+ options: string[];
33
+ description: string;
32
34
  };
33
35
  to: {
34
36
  type: string;
@@ -17,6 +17,7 @@ export declare const WebhookCallConfig: {
17
17
  method: {
18
18
  type: string;
19
19
  required: boolean;
20
+ options: string[];
20
21
  };
21
22
  payload: {
22
23
  type: string;
@@ -25,6 +25,7 @@ export declare const WhatsappSendConfig: {
25
25
  mode: {
26
26
  type: string;
27
27
  required: boolean;
28
+ options: string[];
28
29
  };
29
30
  templateName: {
30
31
  type: string;
@@ -0,0 +1,126 @@
1
+ /**
2
+ * Aggregate Action — Config Contract
3
+ *
4
+ * Fold the upstream records into ONE row — or one row per group — of computed
5
+ * values. It exists because nothing else could total a column (DEV-422): a
6
+ * Transform maps one record at a time and cannot see the others, and the only
7
+ * built-in sum was ForEach's `collect: 'reduce'`, which reduces loop-body
8
+ * results and is reachable from nowhere an author, or an agent reading
9
+ * `describe_action_type`, would look.
10
+ *
11
+ * Output: `{ data: [ { ...groupKeys, ...metrics } ], _meta }` — the same
12
+ * `data: row[]` envelope Query, Transform and Variables emit, so the Transform
13
+ * after it maps `{{totals[].TotalAmount}}` exactly as it maps a Query's rows.
14
+ *
15
+ * The Engine's `aggregateExecutor.ts` reads this shape; the two stay in step.
16
+ */
17
+ /** The functions a metric can apply. `describe_action_type` lists them. */
18
+ export declare const AGGREGATE_FUNCTIONS: readonly ["sum", "count", "avg", "min", "max", "count_distinct", "first", "last"];
19
+ export type AggregateFn = (typeof AGGREGATE_FUNCTIONS)[number];
20
+ /** What each function computes — the panel's help text and the contract's description. */
21
+ export declare const AGGREGATE_FUNCTION_DESCRIPTIONS: Readonly<Record<AggregateFn, string>>;
22
+ export interface AggregateMetric {
23
+ /** One of `AGGREGATE_FUNCTIONS`. */
24
+ fn: AggregateFn;
25
+ /**
26
+ * The record field it reads — a dot-path such as "Balance" or
27
+ * "CustomerRef.name". `count` may omit it to count records.
28
+ */
29
+ field?: string;
30
+ /** The key the value lands under on the output row. An identifier, unique within the step. */
31
+ as: string;
32
+ /** Round a sum or avg to this many decimal places (0–10). Omit to keep the value as computed. */
33
+ decimals?: number;
34
+ }
35
+ export interface AggregateConfigType {
36
+ /**
37
+ * Which upstream records: a path to an array in the upstream step's output.
38
+ * Empty means the records the previous step produced (its `data`). Resolved
39
+ * exactly as ForEach's `arrayPath`.
40
+ */
41
+ arrayPath?: string;
42
+ /**
43
+ * Record fields (dot-paths) to group by. Empty: one row for all records.
44
+ * Each key lands on the output row under its last segment
45
+ * ("CustomerRef.name" → "name").
46
+ */
47
+ groupBy?: string[];
48
+ /** The values to compute. At least one. */
49
+ metrics: AggregateMetric[];
50
+ /**
51
+ * The name later steps use for this result, e.g. `totals` →
52
+ * `{{totals[].TotalAmount}}`. Defaults to the step's name.
53
+ */
54
+ outputAs?: string;
55
+ /**
56
+ * The output ROW's schema, written by the panel at save time so the picker
57
+ * shows the keys before a run. The Backend contributor derives the same
58
+ * thing from the config with `computeOutputSchema`.
59
+ */
60
+ _outputSchema?: {
61
+ type: 'object';
62
+ properties: Record<string, unknown>;
63
+ };
64
+ }
65
+ /** A JSON-schema-like node, as the DataStream and `_outputSchema` carry it. */
66
+ export interface AggregateSchemaNode {
67
+ type?: string;
68
+ properties?: Record<string, AggregateSchemaNode>;
69
+ items?: AggregateSchemaNode;
70
+ description?: string;
71
+ }
72
+ /**
73
+ * The output key a group-by field lands under: its last path segment, with a
74
+ * trailing `[]` removed. "CustomerRef.name" → "name"; "Region" → "Region".
75
+ * The Engine names the group keys the same way.
76
+ */
77
+ export declare function groupKeyName(path: string): string;
78
+ export declare const AggregateConfig: {
79
+ schema: {
80
+ arrayPath: {
81
+ type: string;
82
+ required: boolean;
83
+ dynamic: boolean;
84
+ description: string;
85
+ };
86
+ groupBy: {
87
+ type: string;
88
+ required: boolean;
89
+ description: string;
90
+ };
91
+ metrics: {
92
+ type: string;
93
+ required: boolean;
94
+ description: string;
95
+ };
96
+ outputAs: {
97
+ type: string;
98
+ required: boolean;
99
+ description: string;
100
+ };
101
+ };
102
+ defaults: AggregateConfigType;
103
+ /**
104
+ * What blocks execution, refused before the run (a 409 on an active flow
105
+ * over MCP, a warning on a draft): no metrics, an unknown function, a
106
+ * function with nothing to read, an output key that is not an identifier or
107
+ * is taken, decimals outside 0–10, an outputAs that is not a single name.
108
+ */
109
+ validate(config: Partial<AggregateConfigType>): {
110
+ valid: boolean;
111
+ errors: string[];
112
+ };
113
+ /**
114
+ * The schema of ONE output row: the group keys (typed from the source record
115
+ * when `source` is known) and each metric under its `as`. The panel writes
116
+ * it to `_outputSchema`; the Backend contributor wraps it as `array<row>` at
117
+ * the step's output path. One implementation, two callers.
118
+ */
119
+ computeOutputSchema(config: Partial<AggregateConfigType>, source?: AggregateSchemaNode): {
120
+ type: "object";
121
+ properties: Record<string, unknown>;
122
+ };
123
+ merge(userConfig: Partial<AggregateConfigType>): AggregateConfigType;
124
+ /** "sum(Balance), count by name" — the node's auto label. */
125
+ getLabel(config: Partial<AggregateConfigType>): string;
126
+ };
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Aggregate Action
3
+ *
4
+ * Totals, counts, averages, min/max, distinct counts and first/last over the
5
+ * upstream records — one output row, or one per group. Sits after the step
6
+ * that produces the rows and before the step that writes the result (the
7
+ * "TOTAL row" case: Query → Transform (insert rows) → Aggregate → Transform
8
+ * (insert one row)). The config contract is `./config.ts` (DEV-422).
9
+ */
10
+ import { ActionDefinition } from '../../types';
11
+ export declare const aggregateDefinition: ActionDefinition;
@@ -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;
@@ -16,6 +16,7 @@ import { forEachDefinition } from './logic/for-each';
16
16
  import { groupDefinition } from './logic/group';
17
17
  import { queryDefinition } from './general/query';
18
18
  import { transformDefinition } from './general/transform';
19
+ import { aggregateDefinition } from './general/aggregate';
19
20
  import { csvActionDefinition } from './storage/csv-action';
20
21
  import { jsonActionDefinition } from './storage/json-action';
21
22
  import { xmlActionDefinition } from './storage/xml-action';
@@ -54,4 +55,4 @@ export declare const getActionById: (id: string) => ActionDefinition | undefined
54
55
  * Get actions by category
55
56
  */
56
57
  export declare const getActionsByCategory: (category: ActionCategory) => ActionDefinition[];
57
- export { csvActionDefinition, jsonActionDefinition, xmlActionDefinition, excelActionDefinition, s3ActionDefinition, ftpActionDefinition, googleDriveActionDefinition, dropboxActionDefinition, onedriveActionDefinition, manualTriggerDefinition, scheduleTriggerDefinition, webhookTriggerDefinition, httpRequestDefinition, consoleLogDefinition, delayDefinition, conditionDefinition, forEachDefinition, groupDefinition, queryDefinition, transformDefinition, debugDefinition, errorDefinition, variablesDefinition, graphqlQueryDefinition, emailDefinition, slackMessageDefinition, whatsappSendDefinition, teamsMessageDefinition, googleChatDefinition, webhookCallDefinition, aiAgentDefinition, idpExtractDefinition, };
58
+ export { csvActionDefinition, jsonActionDefinition, xmlActionDefinition, excelActionDefinition, s3ActionDefinition, ftpActionDefinition, googleDriveActionDefinition, dropboxActionDefinition, onedriveActionDefinition, manualTriggerDefinition, scheduleTriggerDefinition, webhookTriggerDefinition, httpRequestDefinition, consoleLogDefinition, delayDefinition, conditionDefinition, forEachDefinition, groupDefinition, queryDefinition, transformDefinition, aggregateDefinition, debugDefinition, errorDefinition, variablesDefinition, graphqlQueryDefinition, emailDefinition, slackMessageDefinition, whatsappSendDefinition, teamsMessageDefinition, googleChatDefinition, webhookCallDefinition, aiAgentDefinition, idpExtractDefinition, };
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Membership test for a readonly string tuple, narrowing the value to the
3
+ * tuple's union. Shared by the contracts that refuse a value outside a fixed
4
+ * set (Transform's mode/operation, Aggregate's function) so each names the
5
+ * allowed values in its message instead of failing at run time.
6
+ */
7
+ export declare const isOneOf: <T extends string>(set: readonly T[], value: unknown) => value is T;
@@ -32,6 +32,7 @@ export declare const ConditionConfig: {
32
32
  mode: {
33
33
  type: string;
34
34
  required: boolean;
35
+ options: string[];
35
36
  };
36
37
  filters: {
37
38
  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;
@@ -0,0 +1,26 @@
1
+ /**
2
+ * The shape of ONE record at a path in an upstream step's output — what a
3
+ * step that reads those records sees per row — and the field names it
4
+ * carries. Pure and framework-free, so a panel that picks a record field
5
+ * (Aggregate's group-by and metric fields, DEV-422) offers the fields the
6
+ * Engine's `resolveArrayPath` will actually hand the step.
7
+ *
8
+ * Resolution order mirrors the ForEach panel's source resolution: the
9
+ * upstream node's static schema (`outputSchema`, else the editor's
10
+ * `config._outputSchema`) walked along the path; then the last run's sample
11
+ * output; then the static schema as a whole. Only the first upstream node is
12
+ * consulted — it is the one the step is wired from.
13
+ */
14
+ import { type UpstreamNodeRef } from './pathOptions';
15
+ export interface RecordSchemaLike {
16
+ type?: string;
17
+ properties?: Record<string, any>;
18
+ items?: any;
19
+ }
20
+ export declare function resolveRecordSchema(upstreamNodes: UpstreamNodeRef[] | undefined, arrayPath: string): RecordSchemaLike | undefined;
21
+ /**
22
+ * The field names a record at `arrayPath` carries: the resolved schema's
23
+ * keys, unioned with the ACTUAL keys of the last run's records — live rows
24
+ * can be sparse or carry system fields a describe-derived schema omits.
25
+ */
26
+ export declare function detectRecordFields(upstreamNodes: UpstreamNodeRef[] | undefined, arrayPath: string): string[];
@@ -21,6 +21,7 @@ export declare const FileOperationConfig: {
21
21
  operation: {
22
22
  type: string;
23
23
  required: boolean;
24
+ options: string[];
24
25
  };
25
26
  sourcePath: {
26
27
  type: string;
@@ -12,6 +12,7 @@ export declare const FormatConfig: {
12
12
  format: {
13
13
  type: string;
14
14
  required: boolean;
15
+ options: string[];
15
16
  };
16
17
  };
17
18
  validate: (config: Partial<FormatConfigType>) => {
@@ -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;
@@ -16,6 +16,7 @@ export declare const WebhookTriggerConfig: {
16
16
  method: {
17
17
  type: string;
18
18
  required: boolean;
19
+ options: string[];
19
20
  };
20
21
  requireAuth: {
21
22
  type: string;
@@ -47,6 +47,7 @@ export declare enum ActionType {
47
47
  SpeechToText = "speech_to_text",
48
48
  TextToSpeech = "text_to_speech",
49
49
  Transform = "transform",
50
+ Aggregate = "aggregate",
50
51
  FileOperation = "file_operation",
51
52
  FileAction = "file_action",
52
53
  CsvAction = "csv_action",
@@ -55,6 +55,7 @@ export declare const DebugConfig: {
55
55
  mode: {
56
56
  type: string;
57
57
  required: boolean;
58
+ options: string[];
58
59
  };
59
60
  label: {
60
61
  type: string;