@octaviaflow/flow-rules 0.16.0 → 0.18.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/general/transform/config.d.ts +27 -4
- package/dist/catalog/logic/for-each/config.d.ts +7 -1
- package/dist/catalog/storage/csv-action/config.d.ts +2 -2
- package/dist/catalog/storage/excel-action/config.d.ts +2 -2
- package/dist/catalog/storage/fileEditContract.d.ts +2 -2
- package/dist/catalog/storage/fileHelp.d.ts +51 -0
- package/dist/catalog/storage/json-action/config.d.ts +2 -2
- package/dist/catalog/storage/xml-action/config.d.ts +2 -2
- package/dist/index.cjs +94 -32
- package/dist/index.d.ts +2 -1
- package/dist/index.js +94 -32
- package/package.json +1 -1
|
@@ -29,7 +29,7 @@ export interface FieldMapping {
|
|
|
29
29
|
/**
|
|
30
30
|
* "Find by" (DEV-480): the mapped value names a record in the target app —
|
|
31
31
|
* the write uses the id of the `object` record whose `matchField` equals it.
|
|
32
|
-
* Root level only; on a line field it applies to each line. Odoo
|
|
32
|
+
* Root level only; on a line field it applies to each line. Odoo and QuickBooks (DEV-487).
|
|
33
33
|
*/
|
|
34
34
|
lookup?: TransformLookup;
|
|
35
35
|
}
|
|
@@ -46,10 +46,26 @@ export interface TransformLookup {
|
|
|
46
46
|
* `lineField` become a list of line objects under `into`, in row order.
|
|
47
47
|
*/
|
|
48
48
|
export interface TransformGroupBy {
|
|
49
|
-
/** Source expression of the key, written like a sourceField: `{{orders[].number}}`. */
|
|
50
|
-
key
|
|
49
|
+
/** Source expression of the key, written like a sourceField: `{{orders[].number}}`. Optional with `linesFrom`. */
|
|
50
|
+
key?: string;
|
|
51
51
|
/** Target field holding the list of lines: `line_items` (Shopify), `Line` (QuickBooks), `order_line` (Odoo). */
|
|
52
52
|
into: string;
|
|
53
|
+
/**
|
|
54
|
+
* A list on each row that supplies its lines (DEV-484): `{{orders[].line_items}}`.
|
|
55
|
+
* Each element makes one line; a line field under the list
|
|
56
|
+
* (`{{orders[].line_items[].quantity}}`) reads the element, any other reads the row.
|
|
57
|
+
*/
|
|
58
|
+
linesFrom?: string;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* One row per element of a list on each row (DEV-484): an order becomes one
|
|
62
|
+
* row per line item, each carrying the order's fields.
|
|
63
|
+
*/
|
|
64
|
+
export interface TransformUnwind {
|
|
65
|
+
/** The list: `{{orders[].line_items}}`. */
|
|
66
|
+
path: string;
|
|
67
|
+
/** Keep a row whose list is empty, as one row with no element. Default false. */
|
|
68
|
+
keepEmpty?: boolean;
|
|
53
69
|
}
|
|
54
70
|
export type TransformMode = 'visual' | 'expression';
|
|
55
71
|
/**
|
|
@@ -91,8 +107,10 @@ export interface TransformConfigType {
|
|
|
91
107
|
/** Explicit upsert/update match field (legacy externalid/pkey). Empty =
|
|
92
108
|
* per-connector auto-detection (Mongo _id, SF Id, SQL primary key). */
|
|
93
109
|
upsertMatchKey?: string;
|
|
94
|
-
/** One record per key, with the `lineField` mappings collected into a list (DEV-478). */
|
|
110
|
+
/** One record per key, or per row with lines from a list on it — the `lineField` mappings collected into a list (DEV-478, DEV-484). */
|
|
95
111
|
groupBy?: TransformGroupBy;
|
|
112
|
+
/** One row per element of a list on each row, before mapping (DEV-484). */
|
|
113
|
+
unwind?: TransformUnwind;
|
|
96
114
|
/** Ordered column header names — the exact columns + header text written. */
|
|
97
115
|
sheetHeaders?: string[];
|
|
98
116
|
/** Create the target tab on first write if it doesn't exist (default true). */
|
|
@@ -152,6 +170,11 @@ export declare const TransformConfig: {
|
|
|
152
170
|
required: boolean;
|
|
153
171
|
description: string;
|
|
154
172
|
};
|
|
173
|
+
unwind: {
|
|
174
|
+
type: string;
|
|
175
|
+
required: boolean;
|
|
176
|
+
description: string;
|
|
177
|
+
};
|
|
155
178
|
expression: {
|
|
156
179
|
type: string;
|
|
157
180
|
required: boolean;
|
|
@@ -50,7 +50,7 @@ export interface ForEachConfigType {
|
|
|
50
50
|
/** dot-path on each item; items whose key was already seen are skipped. */
|
|
51
51
|
idempotencyKeyPath?: string;
|
|
52
52
|
/** how per-item results are collected (default 'array'). */
|
|
53
|
-
collect?: 'array' | 'none' | 'groupBy' | 'reduce';
|
|
53
|
+
collect?: 'array' | 'none' | 'groupBy' | 'reduce' | 'rows';
|
|
54
54
|
/** groupBy — dot-path on each result used as the group key. */
|
|
55
55
|
groupByPath?: string;
|
|
56
56
|
/** reduce — built-in reduction over successful results. */
|
|
@@ -93,6 +93,12 @@ export declare const ForEachConfig: {
|
|
|
93
93
|
type: string;
|
|
94
94
|
required: boolean;
|
|
95
95
|
};
|
|
96
|
+
collect: {
|
|
97
|
+
type: string;
|
|
98
|
+
required: boolean;
|
|
99
|
+
options: string[];
|
|
100
|
+
description: string;
|
|
101
|
+
};
|
|
96
102
|
};
|
|
97
103
|
validate: (config: Partial<ForEachConfigType>) => {
|
|
98
104
|
valid: boolean;
|
|
@@ -66,7 +66,7 @@ export declare const CsvActionConfig: {
|
|
|
66
66
|
readonly type: "select";
|
|
67
67
|
readonly required: false;
|
|
68
68
|
readonly options: readonly import("../fileEditContract").FileEditDestination[];
|
|
69
|
-
readonly description: "\"new\" writes an edited copy (default); \"in_place\" overwrites
|
|
69
|
+
readonly description: "\"new\" writes an edited copy (default); \"in_place\" overwrites the source file";
|
|
70
70
|
};
|
|
71
71
|
outputFileName: {
|
|
72
72
|
readonly type: "string";
|
|
@@ -82,7 +82,7 @@ export declare const CsvActionConfig: {
|
|
|
82
82
|
s3Key: {
|
|
83
83
|
readonly type: "string";
|
|
84
84
|
readonly required: false;
|
|
85
|
-
readonly description: "source \"s3\":
|
|
85
|
+
readonly description: "source \"s3\": an earlier step's file (its s3Key output) to edit";
|
|
86
86
|
};
|
|
87
87
|
url: {
|
|
88
88
|
readonly type: "url";
|
|
@@ -67,7 +67,7 @@ export declare const ExcelActionConfig: {
|
|
|
67
67
|
readonly type: "select";
|
|
68
68
|
readonly required: false;
|
|
69
69
|
readonly options: readonly import("../fileEditContract").FileEditDestination[];
|
|
70
|
-
readonly description: "\"new\" writes an edited copy (default); \"in_place\" overwrites
|
|
70
|
+
readonly description: "\"new\" writes an edited copy (default); \"in_place\" overwrites the source file";
|
|
71
71
|
};
|
|
72
72
|
outputFileName: {
|
|
73
73
|
readonly type: "string";
|
|
@@ -83,7 +83,7 @@ export declare const ExcelActionConfig: {
|
|
|
83
83
|
s3Key: {
|
|
84
84
|
readonly type: "string";
|
|
85
85
|
readonly required: false;
|
|
86
|
-
readonly description: "source \"s3\":
|
|
86
|
+
readonly description: "source \"s3\": an earlier step's file (its s3Key output) to edit";
|
|
87
87
|
};
|
|
88
88
|
url: {
|
|
89
89
|
readonly type: "url";
|
|
@@ -90,7 +90,7 @@ export declare const FILE_EDIT_SCHEMA: {
|
|
|
90
90
|
readonly type: "select";
|
|
91
91
|
readonly required: false;
|
|
92
92
|
readonly options: readonly FileEditDestination[];
|
|
93
|
-
readonly description: "\"new\" writes an edited copy (default); \"in_place\" overwrites
|
|
93
|
+
readonly description: "\"new\" writes an edited copy (default); \"in_place\" overwrites the source file";
|
|
94
94
|
};
|
|
95
95
|
readonly outputFileName: {
|
|
96
96
|
readonly type: "string";
|
|
@@ -106,7 +106,7 @@ export declare const FILE_EDIT_SCHEMA: {
|
|
|
106
106
|
readonly s3Key: {
|
|
107
107
|
readonly type: "string";
|
|
108
108
|
readonly required: false;
|
|
109
|
-
readonly description: "source \"s3\":
|
|
109
|
+
readonly description: "source \"s3\": an earlier step's file (its s3Key output) to edit";
|
|
110
110
|
};
|
|
111
111
|
readonly url: {
|
|
112
112
|
readonly type: "url";
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/** Help for the fields a file step outputs, keyed by field name. */
|
|
2
|
+
export declare const FILE_OUTPUT_HELP: {
|
|
3
|
+
readonly operation: "The operation that ran";
|
|
4
|
+
readonly data: "File contents, for text files such as CSV, JSON or TXT";
|
|
5
|
+
readonly s3Key: "The file itself, for PDF, Excel, images and other non-text files. Pass it to Excel, CSV, IDP or an Upload step.";
|
|
6
|
+
readonly fileName: "File name";
|
|
7
|
+
readonly mimeType: "File type, e.g. text/csv or application/pdf";
|
|
8
|
+
readonly path: "Where the file was read from";
|
|
9
|
+
};
|
|
10
|
+
/** Help for an input that takes text or a file from an earlier step. */
|
|
11
|
+
export declare const FILE_INPUT_HELP: {
|
|
12
|
+
/** Upload content: blank takes the file the step before produced. */
|
|
13
|
+
readonly uploadContent: "Leave blank to upload the file from the step before, or pick a value from an earlier step, or type the content.";
|
|
14
|
+
/** A format action's input (CSV / JSON / XML). */
|
|
15
|
+
readonly formatContent: (format: string) => string;
|
|
16
|
+
/** The Excel action's input. */
|
|
17
|
+
readonly excelContent: "The Excel file from an earlier step (a download or a generated file).";
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* The output of a Storage `download`, as a JSON Schema. The editor stores it on
|
|
21
|
+
* the step so Data References shows bindable fields before the first run.
|
|
22
|
+
*/
|
|
23
|
+
export declare const STORAGE_DOWNLOAD_OUTPUT_SCHEMA: {
|
|
24
|
+
readonly type: "object";
|
|
25
|
+
readonly properties: {
|
|
26
|
+
readonly operation: {
|
|
27
|
+
readonly type: "string";
|
|
28
|
+
readonly description: "The operation that ran";
|
|
29
|
+
};
|
|
30
|
+
readonly data: {
|
|
31
|
+
readonly type: "string";
|
|
32
|
+
readonly description: "File contents, for text files such as CSV, JSON or TXT";
|
|
33
|
+
};
|
|
34
|
+
readonly s3Key: {
|
|
35
|
+
readonly type: "string";
|
|
36
|
+
readonly description: "The file itself, for PDF, Excel, images and other non-text files. Pass it to Excel, CSV, IDP or an Upload step.";
|
|
37
|
+
};
|
|
38
|
+
readonly fileName: {
|
|
39
|
+
readonly type: "string";
|
|
40
|
+
readonly description: "File name";
|
|
41
|
+
};
|
|
42
|
+
readonly mimeType: {
|
|
43
|
+
readonly type: "string";
|
|
44
|
+
readonly description: "File type, e.g. text/csv or application/pdf";
|
|
45
|
+
};
|
|
46
|
+
readonly path: {
|
|
47
|
+
readonly type: "string";
|
|
48
|
+
readonly description: "Where the file was read from";
|
|
49
|
+
};
|
|
50
|
+
};
|
|
51
|
+
};
|
|
@@ -66,7 +66,7 @@ export declare const JsonActionConfig: {
|
|
|
66
66
|
readonly type: "select";
|
|
67
67
|
readonly required: false;
|
|
68
68
|
readonly options: readonly import("../fileEditContract").FileEditDestination[];
|
|
69
|
-
readonly description: "\"new\" writes an edited copy (default); \"in_place\" overwrites
|
|
69
|
+
readonly description: "\"new\" writes an edited copy (default); \"in_place\" overwrites the source file";
|
|
70
70
|
};
|
|
71
71
|
outputFileName: {
|
|
72
72
|
readonly type: "string";
|
|
@@ -82,7 +82,7 @@ export declare const JsonActionConfig: {
|
|
|
82
82
|
s3Key: {
|
|
83
83
|
readonly type: "string";
|
|
84
84
|
readonly required: false;
|
|
85
|
-
readonly description: "source \"s3\":
|
|
85
|
+
readonly description: "source \"s3\": an earlier step's file (its s3Key output) to edit";
|
|
86
86
|
};
|
|
87
87
|
url: {
|
|
88
88
|
readonly type: "url";
|
|
@@ -64,7 +64,7 @@ export declare const XmlActionConfig: {
|
|
|
64
64
|
readonly type: "select";
|
|
65
65
|
readonly required: false;
|
|
66
66
|
readonly options: readonly import("../fileEditContract").FileEditDestination[];
|
|
67
|
-
readonly description: "\"new\" writes an edited copy (default); \"in_place\" overwrites
|
|
67
|
+
readonly description: "\"new\" writes an edited copy (default); \"in_place\" overwrites the source file";
|
|
68
68
|
};
|
|
69
69
|
outputFileName: {
|
|
70
70
|
readonly type: "string";
|
|
@@ -80,7 +80,7 @@ export declare const XmlActionConfig: {
|
|
|
80
80
|
s3Key: {
|
|
81
81
|
readonly type: "string";
|
|
82
82
|
readonly required: false;
|
|
83
|
-
readonly description: "source \"s3\":
|
|
83
|
+
readonly description: "source \"s3\": an earlier step's file (its s3Key output) to edit";
|
|
84
84
|
};
|
|
85
85
|
url: {
|
|
86
86
|
readonly type: "url";
|
package/dist/index.cjs
CHANGED
|
@@ -67,6 +67,8 @@ __export(exports_src, {
|
|
|
67
67
|
FILE_EDIT_SCHEMA: () => FILE_EDIT_SCHEMA,
|
|
68
68
|
FILE_EDIT_SOURCES: () => FILE_EDIT_SOURCES,
|
|
69
69
|
FILE_FORMAT_OPERATIONS: () => FILE_FORMAT_OPERATIONS,
|
|
70
|
+
FILE_INPUT_HELP: () => FILE_INPUT_HELP,
|
|
71
|
+
FILE_OUTPUT_HELP: () => FILE_OUTPUT_HELP,
|
|
70
72
|
FTP_OPERATIONS: () => FTP_OPERATIONS,
|
|
71
73
|
FieldType: () => FieldType,
|
|
72
74
|
ForEachConfig: () => ForEachConfig,
|
|
@@ -92,6 +94,7 @@ __export(exports_src, {
|
|
|
92
94
|
S3ActionConfig: () => S3ActionConfig,
|
|
93
95
|
S3_OPERATIONS: () => S3_OPERATIONS,
|
|
94
96
|
STORAGE_CONNECTOR_IDS: () => STORAGE_CONNECTOR_IDS,
|
|
97
|
+
STORAGE_DOWNLOAD_OUTPUT_SCHEMA: () => STORAGE_DOWNLOAD_OUTPUT_SCHEMA,
|
|
95
98
|
SortDirection: () => SortDirection,
|
|
96
99
|
StorageActionConfig: () => StorageActionConfig,
|
|
97
100
|
TRANSFORM_MODES: () => TRANSFORM_MODES,
|
|
@@ -1784,6 +1787,32 @@ var aggregateDefinition = {
|
|
|
1784
1787
|
testable: false
|
|
1785
1788
|
};
|
|
1786
1789
|
|
|
1790
|
+
// src/catalog/storage/fileHelp.ts
|
|
1791
|
+
var FILE_OUTPUT_HELP = {
|
|
1792
|
+
operation: "The operation that ran",
|
|
1793
|
+
data: "File contents, for text files such as CSV, JSON or TXT",
|
|
1794
|
+
s3Key: "The file itself, for PDF, Excel, images and other non-text files. Pass it to Excel, CSV, IDP or an Upload step.",
|
|
1795
|
+
fileName: "File name",
|
|
1796
|
+
mimeType: "File type, e.g. text/csv or application/pdf",
|
|
1797
|
+
path: "Where the file was read from"
|
|
1798
|
+
};
|
|
1799
|
+
var FILE_INPUT_HELP = {
|
|
1800
|
+
uploadContent: "Leave blank to upload the file from the step before, or pick a value from an earlier step, or type the content.",
|
|
1801
|
+
formatContent: (format) => `The ${format} from an earlier step (a download or a generated file), or paste the ${format} here.`,
|
|
1802
|
+
excelContent: "The Excel file from an earlier step (a download or a generated file)."
|
|
1803
|
+
};
|
|
1804
|
+
var STORAGE_DOWNLOAD_OUTPUT_SCHEMA = {
|
|
1805
|
+
type: "object",
|
|
1806
|
+
properties: {
|
|
1807
|
+
operation: { type: "string", description: FILE_OUTPUT_HELP.operation },
|
|
1808
|
+
data: { type: "string", description: FILE_OUTPUT_HELP.data },
|
|
1809
|
+
s3Key: { type: "string", description: FILE_OUTPUT_HELP.s3Key },
|
|
1810
|
+
fileName: { type: "string", description: FILE_OUTPUT_HELP.fileName },
|
|
1811
|
+
mimeType: { type: "string", description: FILE_OUTPUT_HELP.mimeType },
|
|
1812
|
+
path: { type: "string", description: FILE_OUTPUT_HELP.path }
|
|
1813
|
+
}
|
|
1814
|
+
};
|
|
1815
|
+
|
|
1787
1816
|
// src/catalog/storage/csv-action/index.ts
|
|
1788
1817
|
var csvActionDefinition = {
|
|
1789
1818
|
id: "csv_action",
|
|
@@ -1798,7 +1827,7 @@ var csvActionDefinition = {
|
|
|
1798
1827
|
inputSchema: {
|
|
1799
1828
|
fields: [
|
|
1800
1829
|
{ key: "operation", label: "Operation", type: "select" /* Select */, options: [{ label: "Parse (CSV → Records)", value: "parse" }, { label: "Generate (Records → CSV)", value: "generate" }, { label: "Edit existing file", value: "edit" }], defaultValue: "parse", validation: { required: true } },
|
|
1801
|
-
{ key: "content", label: "CSV Content", type: "string" /* String */, description: "
|
|
1830
|
+
{ key: "content", label: "CSV Content", type: "string" /* String */, description: FILE_INPUT_HELP.formatContent("CSV") },
|
|
1802
1831
|
{ key: "delimiter", label: "Delimiter", type: "select" /* Select */, options: [{ label: "Comma (,)", value: "," }, { label: "Semicolon (;)", value: ";" }, { label: "Tab", value: "\t" }, { label: "Pipe (|)", value: "|" }], defaultValue: "," },
|
|
1803
1832
|
{ key: "headerRow", label: "Header Row", type: "number" /* Number */, description: "Row number containing column headers (default: 1)", defaultValue: 1 },
|
|
1804
1833
|
{ key: "encoding", label: "Encoding", type: "select" /* Select */, options: [{ label: "UTF-8", value: "utf-8" }, { label: "Latin-1", value: "latin1" }, { label: "ASCII", value: "ascii" }], defaultValue: "utf-8" },
|
|
@@ -1838,7 +1867,7 @@ var jsonActionDefinition = {
|
|
|
1838
1867
|
fields: [
|
|
1839
1868
|
{ key: "operation", label: "Operation", type: "select" /* Select */, options: [{ label: "Parse (JSON → Records)", value: "parse" }, { label: "Generate (Records → JSON)", value: "generate" }, { label: "Edit existing file", value: "edit" }], defaultValue: "parse", validation: { required: true } },
|
|
1840
1869
|
{ key: "format", label: "Format", type: "select" /* Select */, options: [{ label: "JSON (array)", value: "json" }, { label: "JSONL (one object per line)", value: "jsonl" }], defaultValue: "json" },
|
|
1841
|
-
{ key: "content", label: "JSON Content", type: "string" /* String */, description: "
|
|
1870
|
+
{ key: "content", label: "JSON Content", type: "string" /* String */, description: FILE_INPUT_HELP.formatContent("JSON") },
|
|
1842
1871
|
{ key: "prettyPrint", label: "Pretty Print", type: "boolean" /* Boolean */, description: "Format output with indentation", defaultValue: true },
|
|
1843
1872
|
{ key: "fileName", label: "Output File Name", type: "string" /* String */, defaultValue: "export.json" }
|
|
1844
1873
|
]
|
|
@@ -1874,7 +1903,7 @@ var xmlActionDefinition = {
|
|
|
1874
1903
|
inputSchema: {
|
|
1875
1904
|
fields: [
|
|
1876
1905
|
{ key: "operation", label: "Operation", type: "select" /* Select */, options: [{ label: "Parse (XML → Records)", value: "parse" }, { label: "Generate (Records → XML)", value: "generate" }, { label: "Edit existing file", value: "edit" }], defaultValue: "parse", validation: { required: true } },
|
|
1877
|
-
{ key: "content", label: "XML Content", type: "string" /* String */, description: "
|
|
1906
|
+
{ key: "content", label: "XML Content", type: "string" /* String */, description: FILE_INPUT_HELP.formatContent("XML") },
|
|
1878
1907
|
{ key: "rootElement", label: "Root Element", type: "string" /* String */, description: "Root XML element name (for generate)", defaultValue: "data" },
|
|
1879
1908
|
{ key: "rowElement", label: "Row Element", type: "string" /* String */, description: "Element name per record (for generate)", defaultValue: "row" },
|
|
1880
1909
|
{ key: "fileName", label: "Output File Name", type: "string" /* String */, defaultValue: "export.xml" }
|
|
@@ -1911,7 +1940,7 @@ var excelActionDefinition = {
|
|
|
1911
1940
|
inputSchema: {
|
|
1912
1941
|
fields: [
|
|
1913
1942
|
{ key: "operation", label: "Operation", type: "select" /* Select */, options: [{ label: "Parse (Excel → Records)", value: "parse" }, { label: "Generate (Records → Excel)", value: "generate" }, { label: "Edit existing file", value: "edit" }], defaultValue: "parse", validation: { required: true } },
|
|
1914
|
-
{ key: "content", label: "Excel File", type: "string" /* String */, description:
|
|
1943
|
+
{ key: "content", label: "Excel File", type: "string" /* String */, description: FILE_INPUT_HELP.excelContent },
|
|
1915
1944
|
{ key: "sheetName", label: "Sheet Name", type: "string" /* String */, description: "Name of sheet to read (default: first sheet)" },
|
|
1916
1945
|
{ key: "headerRow", label: "Header Row", type: "number" /* Number */, description: "Row number containing headers", defaultValue: 1 },
|
|
1917
1946
|
{ key: "fileName", label: "Output File Name", type: "string" /* String */, defaultValue: "export.xlsx" }
|
|
@@ -1923,7 +1952,7 @@ var excelActionDefinition = {
|
|
|
1923
1952
|
{ key: "data", type: "array" /* Array */, description: "Parsed records (parse mode) — loop these with a ForEach. File metadata in generate mode." },
|
|
1924
1953
|
{ key: "columns", type: "json" /* JSON */, description: "Column names" },
|
|
1925
1954
|
{ key: "rowCount", type: "number" /* Number */, description: "Number of records" },
|
|
1926
|
-
{ key: "s3Key", type: "string" /* String */, description: "
|
|
1955
|
+
{ key: "s3Key", type: "string" /* String */, description: "The generated Excel file. Pass it to an Upload step to save it." }
|
|
1927
1956
|
],
|
|
1928
1957
|
sampleOutput: { data: [{ id: 1, name: "Widget" }], columns: ["id", "name"], rowCount: 1 }
|
|
1929
1958
|
},
|
|
@@ -1953,7 +1982,7 @@ var s3ActionDefinition = {
|
|
|
1953
1982
|
{ key: "bucket", label: "Bucket Name", type: "string" /* String */, description: "S3 bucket name (defaults to the connector’s bucket)" },
|
|
1954
1983
|
{ key: "key", label: "Object Key (Path)", type: "string" /* String */, description: "S3 object key, e.g. data/reports/monthly.csv" },
|
|
1955
1984
|
{ key: "prefix", label: "Prefix (for List)", type: "string" /* String */, description: "Filter objects by prefix (folder path)" },
|
|
1956
|
-
{ key: "content", label: "File Content (for Upload)", type: "string" /* String */, description:
|
|
1985
|
+
{ key: "content", label: "File Content (for Upload)", type: "string" /* String */, description: FILE_INPUT_HELP.uploadContent },
|
|
1957
1986
|
{ key: "contentType", label: "Content Type", type: "string" /* String */, description: "MIME type (e.g. text/csv, application/json)", defaultValue: "application/octet-stream" },
|
|
1958
1987
|
{ key: "destBucket", label: "Destination Bucket (for Copy)", type: "string" /* String */ },
|
|
1959
1988
|
{ key: "destKey", label: "Destination Key (for Copy)", type: "string" /* String */ },
|
|
@@ -1994,7 +2023,7 @@ var ftpActionDefinition = {
|
|
|
1994
2023
|
{ key: "connector", label: "FTP / SFTP Connection", type: "connection" /* Connection */, description: "Select a configured FTP/SFTP connector from Integrations", validation: { required: true } },
|
|
1995
2024
|
{ key: "operation", label: "Operation", type: "select" /* Select */, options: [{ label: "Download File", value: "download" }, { label: "Upload File", value: "upload" }, { label: "List Files", value: "list" }, { label: "Delete File", value: "delete" }, { label: "Move / Rename", value: "move" }], defaultValue: "download", validation: { required: true } },
|
|
1996
2025
|
{ key: "remotePath", label: "Remote Path", type: "string" /* String */, description: "File or folder path on the server (use file explorer to browse)" },
|
|
1997
|
-
{ key: "content", label: "File Content (Upload)", type: "string" /* String */, description:
|
|
2026
|
+
{ key: "content", label: "File Content (Upload)", type: "string" /* String */, description: FILE_INPUT_HELP.uploadContent },
|
|
1998
2027
|
{ key: "fileName", label: "File Name (Upload)", type: "string" /* String */, description: "Name for the uploaded file" },
|
|
1999
2028
|
{ key: "destPath", label: "Destination Path (Move)", type: "string" /* String */, description: "New path for moved/renamed file" },
|
|
2000
2029
|
{ key: "ifExists", label: "If File Exists", type: "select" /* Select */, options: [{ label: "Overwrite", value: "overwrite" }, { label: "Skip", value: "skip" }], defaultValue: "overwrite" }
|
|
@@ -2035,7 +2064,7 @@ var googleDriveActionDefinition = {
|
|
|
2035
2064
|
{ key: "fileId", label: "File ID / Path", type: "string" /* String */, description: "Google Drive file ID (use file explorer to browse)" },
|
|
2036
2065
|
{ key: "folderId", label: "Folder ID", type: "string" /* String */, description: "Target folder (root if empty)" },
|
|
2037
2066
|
{ key: "fileName", label: "File Name", type: "string" /* String */ },
|
|
2038
|
-
{ key: "content", label: "File Content (Upload)", type: "string" /* String */, description:
|
|
2067
|
+
{ key: "content", label: "File Content (Upload)", type: "string" /* String */, description: FILE_INPUT_HELP.uploadContent },
|
|
2039
2068
|
{ key: "mimeType", label: "MIME Type", type: "string" /* String */, defaultValue: "application/octet-stream" },
|
|
2040
2069
|
{ key: "destFolderId", label: "Destination Folder (Move/Copy)", type: "string" /* String */ },
|
|
2041
2070
|
{ key: "shareEmail", label: "Share With Email", type: "string" /* String */ },
|
|
@@ -2077,7 +2106,7 @@ var dropboxActionDefinition = {
|
|
|
2077
2106
|
{ key: "connector", label: "Dropbox Account", type: "connection" /* Connection */, description: "Select a connected Dropbox account", validation: { required: true } },
|
|
2078
2107
|
{ key: "operation", label: "Operation", type: "select" /* Select */, options: [{ label: "Download File", value: "download" }, { label: "Upload File", value: "upload" }, { label: "List Files", value: "list" }, { label: "Delete", value: "delete" }, { label: "Move", value: "move" }, { label: "Copy", value: "copy" }, { label: "Create Folder", value: "create_folder" }, { label: "Get Shared Link", value: "shared_link" }], defaultValue: "download", validation: { required: true } },
|
|
2079
2108
|
{ key: "path", label: "File / Folder Path", type: "string" /* String */, description: "Path on Dropbox (use file explorer to browse)" },
|
|
2080
|
-
{ key: "content", label: "File Content (Upload)", type: "string" /* String */, description:
|
|
2109
|
+
{ key: "content", label: "File Content (Upload)", type: "string" /* String */, description: FILE_INPUT_HELP.uploadContent },
|
|
2081
2110
|
{ key: "fileName", label: "File Name (Upload)", type: "string" /* String */ },
|
|
2082
2111
|
{ key: "destPath", label: "Destination Path (Move/Copy)", type: "string" /* String */ },
|
|
2083
2112
|
{ key: "mode", label: "Upload Mode", type: "select" /* Select */, options: [{ label: "Add (fail if exists)", value: "add" }, { label: "Overwrite", value: "overwrite" }], defaultValue: "overwrite" }
|
|
@@ -2117,7 +2146,7 @@ var onedriveActionDefinition = {
|
|
|
2117
2146
|
{ key: "operation", label: "Operation", type: "select" /* Select */, options: [{ label: "Download File", value: "download" }, { label: "Upload File", value: "upload" }, { label: "List Files", value: "list" }, { label: "Delete", value: "delete" }, { label: "Move", value: "move" }, { label: "Copy", value: "copy" }], defaultValue: "download", validation: { required: true } },
|
|
2118
2147
|
{ key: "path", label: "File / Folder Path", type: "string" /* String */, description: "Path on OneDrive (use file explorer to browse)" },
|
|
2119
2148
|
{ key: "itemId", label: "Item ID", type: "string" /* String */, description: "OneDrive item ID (alternative to path)" },
|
|
2120
|
-
{ key: "content", label: "File Content (Upload)", type: "string" /* String */, description:
|
|
2149
|
+
{ key: "content", label: "File Content (Upload)", type: "string" /* String */, description: FILE_INPUT_HELP.uploadContent },
|
|
2121
2150
|
{ key: "fileName", label: "File Name (Upload)", type: "string" /* String */ },
|
|
2122
2151
|
{ key: "destPath", label: "Destination Path (Move/Copy)", type: "string" /* String */ }
|
|
2123
2152
|
]
|
|
@@ -2175,14 +2204,17 @@ var storageActionDefinition = {
|
|
|
2175
2204
|
},
|
|
2176
2205
|
{ key: "path", label: "Path", type: "string" /* String */, description: "File or folder path — use the file browser in the panel." },
|
|
2177
2206
|
{ key: "destPath", label: "Destination path", type: "string" /* String */, description: "Target for copy / move." },
|
|
2178
|
-
{ key: "content", label: "File content (for Upload)", type: "string" /* String */, description:
|
|
2207
|
+
{ key: "content", label: "File content (for Upload)", type: "string" /* String */, description: FILE_INPUT_HELP.uploadContent }
|
|
2179
2208
|
]
|
|
2180
2209
|
},
|
|
2181
2210
|
outputSchema: {
|
|
2182
2211
|
type: "object",
|
|
2183
2212
|
properties: [
|
|
2184
2213
|
{ key: "operation", type: "string" /* String */, description: "The operation that ran" },
|
|
2185
|
-
{ key: "data", type: "json" /* JSON */, description:
|
|
2214
|
+
{ key: "data", type: "json" /* JSON */, description: `Download: ${FILE_OUTPUT_HELP.data}. Other operations: their result.` },
|
|
2215
|
+
{ key: "s3Key", type: "string" /* String */, description: `Download: ${FILE_OUTPUT_HELP.s3Key}` },
|
|
2216
|
+
{ key: "fileName", type: "string" /* String */, description: `Download: ${FILE_OUTPUT_HELP.fileName}` },
|
|
2217
|
+
{ key: "mimeType", type: "string" /* String */, description: `Download: ${FILE_OUTPUT_HELP.mimeType}` },
|
|
2186
2218
|
{ key: "files", type: "json" /* JSON */, description: "Listing (for the List operation)" },
|
|
2187
2219
|
{ key: "path", type: "string" /* String */, description: "Affected file/folder path" },
|
|
2188
2220
|
{ key: "url", type: "string" /* String */, description: "Signed URL (for the Get signed URL operation)" }
|
|
@@ -3340,7 +3372,13 @@ var ForEachConfig = {
|
|
|
3340
3372
|
itemVariable: { type: "string", required: true },
|
|
3341
3373
|
indexVariable: { type: "string", required: false },
|
|
3342
3374
|
batchSize: { type: "number", required: false },
|
|
3343
|
-
continueOnError: { type: "boolean", required: false }
|
|
3375
|
+
continueOnError: { type: "boolean", required: false },
|
|
3376
|
+
collect: {
|
|
3377
|
+
type: "select",
|
|
3378
|
+
required: false,
|
|
3379
|
+
options: ["array", "none", "groupBy", "reduce", "rows"],
|
|
3380
|
+
description: "What the Done port carries besides the counts: array (each iteration's result in `results`, the default), none, groupBy (by groupByPath), " + "reduce (reduceOp over reducePath), or rows — also `data`: every row the body produced (each iteration's Query/Transform rows, else its result), " + "so ONE step on the Done port maps and writes them all instead of a write per iteration."
|
|
3381
|
+
}
|
|
3344
3382
|
},
|
|
3345
3383
|
validate: (config) => {
|
|
3346
3384
|
const errors = [];
|
|
@@ -3725,6 +3763,34 @@ var TRANSFORM_OPERATIONS = [
|
|
|
3725
3763
|
];
|
|
3726
3764
|
var TRANSFORM_OPERATION_IDS = TRANSFORM_OPERATIONS.map((o) => o.id);
|
|
3727
3765
|
var DATABASE_CONNECTOR_IDS = new Set(["mongodb", "postgresql", "mysql", "google_sheets"]);
|
|
3766
|
+
function groupByErrors(config) {
|
|
3767
|
+
const groupBy = config.groupBy;
|
|
3768
|
+
if (!groupBy || !(groupBy.key || groupBy.into || groupBy.linesFrom))
|
|
3769
|
+
return [];
|
|
3770
|
+
const errors = [];
|
|
3771
|
+
if (!groupBy.key && !groupBy.linesFrom) {
|
|
3772
|
+
errors.push("One record per key: choose the key field (groupBy.key)");
|
|
3773
|
+
}
|
|
3774
|
+
if (!groupBy.into)
|
|
3775
|
+
errors.push("One record per key: name the field that holds the lines (groupBy.into)");
|
|
3776
|
+
if ((groupBy.key || groupBy.linesFrom) && groupBy.into && !(config.mappings ?? []).some((m) => m.lineField)) {
|
|
3777
|
+
errors.push("One record per key: mark at least one mapping as a line field (lineField: true)");
|
|
3778
|
+
}
|
|
3779
|
+
return errors;
|
|
3780
|
+
}
|
|
3781
|
+
function unwindErrors(config) {
|
|
3782
|
+
const unwind = config.unwind;
|
|
3783
|
+
if (!unwind)
|
|
3784
|
+
return [];
|
|
3785
|
+
if (!unwind.path?.trim()) {
|
|
3786
|
+
return unwind.keepEmpty !== undefined ? ["One row per item: choose the list (unwind.path)"] : [];
|
|
3787
|
+
}
|
|
3788
|
+
const linesFrom = config.groupBy?.linesFrom;
|
|
3789
|
+
if (linesFrom && linesFrom.trim() === unwind.path.trim()) {
|
|
3790
|
+
return ["One row per item and Lines come from name the same list — use one of them (unwind.path, groupBy.linesFrom)"];
|
|
3791
|
+
}
|
|
3792
|
+
return [];
|
|
3793
|
+
}
|
|
3728
3794
|
var TransformConfig = {
|
|
3729
3795
|
defaults: {
|
|
3730
3796
|
name: "Transform",
|
|
@@ -3774,12 +3840,17 @@ var TransformConfig = {
|
|
|
3774
3840
|
mappings: {
|
|
3775
3841
|
type: "array",
|
|
3776
3842
|
required: false,
|
|
3777
|
-
description: "Field mappings: [{ id, sourceField, targetField, targetType, transform? }]. sourceField is a token like {{orders[].email}}; " + "an index picks one list element ({{products[].variants[0].price}}). With groupBy, set lineField: true on the mappings that make each line. " + 'When the target field holds a record id but you have a reference (an email, SHOP-123), add lookup: { "object": "product.product", "matchField": "default_code" } — ' + "the write uses the id of the one record whose matchField equals the value; no match, or more than one, fails that row. Odoo
|
|
3843
|
+
description: "Field mappings: [{ id, sourceField, targetField, targetType, transform? }]. sourceField is a token like {{orders[].email}}; " + "an index picks one list element ({{products[].variants[0].price}}). With groupBy, set lineField: true on the mappings that make each line. " + 'When the target field holds a record id but you have a reference (an email, SHOP-123), add lookup: { "object": "product.product", "matchField": "default_code" } — ' + "the write uses the id of the one record whose matchField equals the value; no match, or more than one, fails that row. Odoo and QuickBooks Online (e.g. CustomerRef.value → Customer by DisplayName; " + "Line.SalesItemLineDetail.ItemRef.value → Item by Name). A QuickBooks transaction upsert matches on DocNumber unless upsertMatchKey says otherwise."
|
|
3778
3844
|
},
|
|
3779
3845
|
groupBy: {
|
|
3780
3846
|
type: "json",
|
|
3781
3847
|
required: false,
|
|
3782
|
-
description:
|
|
3848
|
+
description: "Records with line items; mappings with lineField: true become a list of lines under `into` (Shopify line_items, QuickBooks Line, Odoo order_line). " + 'Two ways, combinable: (1) the lines are flat rows — { "key": "{{orders[].number}}", "into": "order_line" }: rows with the same key become ONE record ' + '(its fields from the first row), one line per row; (2) the lines are a list INSIDE each row — { "into": "order_line", "linesFrom": "{{orders[].line_items}}" }: ' + "each row is one record and each element of the list one line; a line field under the list ({{orders[].line_items[].quantity}}) reads the element, " + "any other path reads the row. Dotted line fields nest inside each line (SalesItemLineDetail.ItemRef.value)."
|
|
3849
|
+
},
|
|
3850
|
+
unwind: {
|
|
3851
|
+
type: "json",
|
|
3852
|
+
required: false,
|
|
3853
|
+
description: 'One row per element of a list on each row: { "path": "{{orders[].line_items}}", "keepEmpty": false }. Every mapping then reads the element under the ' + "list path ({{orders[].line_items[].sku}}) and the row everywhere else ({{orders[].name}}) — an order becomes one row per line, for targets that take " + "flat rows (Sheets, SQL). A row whose list is empty is dropped unless keepEmpty is true."
|
|
3783
3854
|
},
|
|
3784
3855
|
expression: { type: "code", required: false }
|
|
3785
3856
|
},
|
|
@@ -3825,16 +3896,7 @@ var TransformConfig = {
|
|
|
3825
3896
|
});
|
|
3826
3897
|
}
|
|
3827
3898
|
}
|
|
3828
|
-
|
|
3829
|
-
if (groupBy && (groupBy.key || groupBy.into)) {
|
|
3830
|
-
if (!groupBy.key)
|
|
3831
|
-
errors.push("One record per key: choose the key field (groupBy.key)");
|
|
3832
|
-
if (!groupBy.into)
|
|
3833
|
-
errors.push("One record per key: name the field that holds the lines (groupBy.into)");
|
|
3834
|
-
if (groupBy.key && groupBy.into && !(config.mappings ?? []).some((m) => m.lineField)) {
|
|
3835
|
-
errors.push("One record per key: mark at least one mapping as a line field (lineField: true)");
|
|
3836
|
-
}
|
|
3837
|
-
}
|
|
3899
|
+
errors.push(...groupByErrors(config), ...unwindErrors(config));
|
|
3838
3900
|
return { valid: errors.length === 0, errors };
|
|
3839
3901
|
},
|
|
3840
3902
|
merge: (userConfig) => {
|
|
@@ -4598,10 +4660,10 @@ var FILE_EDIT_SCHEMA = {
|
|
|
4598
4660
|
matchOp: { type: "select", required: false, options: FILE_EDIT_MATCH_OPS, description: 'set_fields: comparison; "=" by default' },
|
|
4599
4661
|
matchValue: { type: "string", required: false, description: "set_fields: value compared against" },
|
|
4600
4662
|
setFields: { type: "object", required: false, description: "set_fields: { column: newValue } applied to matching rows" },
|
|
4601
|
-
destination: { type: "select", required: false, options: FILE_EDIT_DESTINATIONS, description: '"new" writes an edited copy (default); "in_place" overwrites
|
|
4663
|
+
destination: { type: "select", required: false, options: FILE_EDIT_DESTINATIONS, description: '"new" writes an edited copy (default); "in_place" overwrites the source file' },
|
|
4602
4664
|
outputFileName: { type: "string", required: false, description: 'Name of the edited copy when destination is "new"' },
|
|
4603
4665
|
source: { type: "select", required: false, options: FILE_EDIT_SOURCES, description: "Where the file to edit comes from; inferred from content when absent" },
|
|
4604
|
-
s3Key: { type: "string", required: false, description:
|
|
4666
|
+
s3Key: { type: "string", required: false, description: `source "s3": an earlier step's file (its s3Key output) to edit` },
|
|
4605
4667
|
url: { type: "url", required: false, description: 'source "url": the file to edit is fetched from here' }
|
|
4606
4668
|
};
|
|
4607
4669
|
function fileEditErrors(config) {
|
|
@@ -4633,7 +4695,7 @@ var CsvActionConfig = {
|
|
|
4633
4695
|
},
|
|
4634
4696
|
schema: {
|
|
4635
4697
|
operation: { type: "select", required: true, options: FILE_FORMAT_OPERATIONS, description: "parse (CSV → records), generate (records → CSV) or edit an existing file" },
|
|
4636
|
-
content: { type: "text", required: false, description: "CSV text, or
|
|
4698
|
+
content: { type: "text", required: false, description: "CSV text, or a reference to an earlier step's file content" },
|
|
4637
4699
|
delimiter: { type: "select", required: false, options: [",", ";", "\t", "|"] },
|
|
4638
4700
|
headerRow: { type: "number", required: false, min: 1, description: "1-based row that holds the column headers" },
|
|
4639
4701
|
encoding: { type: "string", required: false, description: "Text encoding (utf-8 by default)" },
|
|
@@ -4659,7 +4721,7 @@ var JsonActionConfig = {
|
|
|
4659
4721
|
schema: {
|
|
4660
4722
|
operation: { type: "select", required: true, options: FILE_FORMAT_OPERATIONS, description: "parse (JSON → records), generate (records → JSON) or edit an existing file" },
|
|
4661
4723
|
format: { type: "select", required: false, options: ["json", "jsonl"], description: "json (array) or jsonl (one object per line)" },
|
|
4662
|
-
content: { type: "text", required: false, description: "JSON text, or
|
|
4724
|
+
content: { type: "text", required: false, description: "JSON text, or a reference to an earlier step's file content" },
|
|
4663
4725
|
prettyPrint: { type: "boolean", required: false, description: "generate: indent the output" },
|
|
4664
4726
|
fileName: { type: "string", required: false, description: "generate: name of the produced file" },
|
|
4665
4727
|
jsonl: { type: "boolean", required: false, description: "edit: treat the file as JSONL" },
|
|
@@ -4686,7 +4748,7 @@ var XmlActionConfig = {
|
|
|
4686
4748
|
},
|
|
4687
4749
|
schema: {
|
|
4688
4750
|
operation: { type: "select", required: true, options: FILE_FORMAT_OPERATIONS, description: "parse (XML → records), generate (records → XML) or edit an existing file" },
|
|
4689
|
-
content: { type: "text", required: false, description: "XML text, or
|
|
4751
|
+
content: { type: "text", required: false, description: "XML text, or a reference to an earlier step's file content" },
|
|
4690
4752
|
rootElement: { type: "string", required: false, description: "generate: root element name" },
|
|
4691
4753
|
rowElement: { type: "string", required: false, description: "Element that holds one record" },
|
|
4692
4754
|
fileName: { type: "string", required: false, description: "generate: name of the produced file" },
|
|
@@ -4708,7 +4770,7 @@ var ExcelActionConfig = {
|
|
|
4708
4770
|
},
|
|
4709
4771
|
schema: {
|
|
4710
4772
|
operation: { type: "select", required: true, options: FILE_FORMAT_OPERATIONS, description: "parse (Excel → records), generate (records → Excel) or edit an existing file" },
|
|
4711
|
-
content: { type: "text", required: false, description: "
|
|
4773
|
+
content: { type: "text", required: false, description: "A reference to an earlier step's Excel file (its s3Key output), or base64 bytes" },
|
|
4712
4774
|
sheetName: { type: "string", required: false, description: "Sheet to read; the first sheet when absent" },
|
|
4713
4775
|
headerRow: { type: "number", required: false, min: 1, description: "1-based row that holds the column headers" },
|
|
4714
4776
|
fileName: { type: "string", required: false, description: "generate: name of the produced file" },
|
|
@@ -4726,7 +4788,7 @@ var FIXED_SCHEMA = {
|
|
|
4726
4788
|
connector: { type: "connection", required: true, description: "Storage connector instance; its provider decides the operations" },
|
|
4727
4789
|
operation: { type: "select", required: true, description: "Per provider: list, download, upload, delete, copy, move, presign, share, create_folder, transfer, sync" },
|
|
4728
4790
|
outputAs: { type: "string", required: false, description: "Name of this step's output in the run's data bag" },
|
|
4729
|
-
content: { type: "text", required: false, description: "upload: the
|
|
4791
|
+
content: { type: "text", required: false, description: "upload: the file content; blank uploads the file the step before produced" },
|
|
4730
4792
|
destConnector: { type: "connection", required: false, description: "transfer / sync: destination connector instance" },
|
|
4731
4793
|
destPath: { type: "string", required: false, description: "transfer / sync: destination path; also move / copy destination on path-based providers" },
|
|
4732
4794
|
sourceIsDirectory: { type: "boolean", required: false, description: "transfer: copy a folder recursively" },
|
package/dist/index.d.ts
CHANGED
|
@@ -36,10 +36,11 @@ 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_MODES, TRANSFORM_OPERATIONS, TransformConfig, type TransformConfigType, type TransformGroupBy, type TransformLookup, type TransformOperation, } from "./catalog/general/transform/config";
|
|
39
|
+
export { DATABASE_CONNECTOR_IDS, type FieldMapping, TRANSFORM_MODES, TRANSFORM_OPERATIONS, TransformConfig, type TransformConfigType, type TransformGroupBy, type TransformLookup, type TransformUnwind, type TransformOperation, } from "./catalog/general/transform/config";
|
|
40
40
|
export { AGGREGATE_FUNCTIONS, AGGREGATE_FUNCTION_DESCRIPTIONS, AggregateConfig, type AggregateConfigType, type AggregateFn, type AggregateMetric, type AggregateSchemaNode, groupKeyName, } from "./catalog/general/aggregate/config";
|
|
41
41
|
export { detectRecordFields, resolveRecordSchema, type RecordSchemaLike, } from "./catalog/logic/for-each/recordSchema";
|
|
42
42
|
export { STORAGE_CONNECTOR_IDS, type StorageExtraField, type StoragePathField, getStorageProvider, storageConfigKeys, } from "./catalog/storage/storageCapabilities";
|
|
43
|
+
export { FILE_OUTPUT_HELP, FILE_INPUT_HELP, STORAGE_DOWNLOAD_OUTPUT_SCHEMA, } from "./catalog/storage/fileHelp";
|
|
43
44
|
export { ManualTriggerConfig } from "./catalog/triggers/manual-trigger/index";
|
|
44
45
|
export { AiAgentConfig, type AiAgentConfigType, type AiAgentOverrides } from "./catalog/ai/ai-agent/config";
|
|
45
46
|
export { IdpExtractConfig, IDP_EXTRACT_STRATEGIES, type IdpExtractConfigType } from "./catalog/ai/idp-extract/config";
|
package/dist/index.js
CHANGED
|
@@ -1626,6 +1626,32 @@ var aggregateDefinition = {
|
|
|
1626
1626
|
testable: false
|
|
1627
1627
|
};
|
|
1628
1628
|
|
|
1629
|
+
// src/catalog/storage/fileHelp.ts
|
|
1630
|
+
var FILE_OUTPUT_HELP = {
|
|
1631
|
+
operation: "The operation that ran",
|
|
1632
|
+
data: "File contents, for text files such as CSV, JSON or TXT",
|
|
1633
|
+
s3Key: "The file itself, for PDF, Excel, images and other non-text files. Pass it to Excel, CSV, IDP or an Upload step.",
|
|
1634
|
+
fileName: "File name",
|
|
1635
|
+
mimeType: "File type, e.g. text/csv or application/pdf",
|
|
1636
|
+
path: "Where the file was read from"
|
|
1637
|
+
};
|
|
1638
|
+
var FILE_INPUT_HELP = {
|
|
1639
|
+
uploadContent: "Leave blank to upload the file from the step before, or pick a value from an earlier step, or type the content.",
|
|
1640
|
+
formatContent: (format) => `The ${format} from an earlier step (a download or a generated file), or paste the ${format} here.`,
|
|
1641
|
+
excelContent: "The Excel file from an earlier step (a download or a generated file)."
|
|
1642
|
+
};
|
|
1643
|
+
var STORAGE_DOWNLOAD_OUTPUT_SCHEMA = {
|
|
1644
|
+
type: "object",
|
|
1645
|
+
properties: {
|
|
1646
|
+
operation: { type: "string", description: FILE_OUTPUT_HELP.operation },
|
|
1647
|
+
data: { type: "string", description: FILE_OUTPUT_HELP.data },
|
|
1648
|
+
s3Key: { type: "string", description: FILE_OUTPUT_HELP.s3Key },
|
|
1649
|
+
fileName: { type: "string", description: FILE_OUTPUT_HELP.fileName },
|
|
1650
|
+
mimeType: { type: "string", description: FILE_OUTPUT_HELP.mimeType },
|
|
1651
|
+
path: { type: "string", description: FILE_OUTPUT_HELP.path }
|
|
1652
|
+
}
|
|
1653
|
+
};
|
|
1654
|
+
|
|
1629
1655
|
// src/catalog/storage/csv-action/index.ts
|
|
1630
1656
|
var csvActionDefinition = {
|
|
1631
1657
|
id: "csv_action",
|
|
@@ -1640,7 +1666,7 @@ var csvActionDefinition = {
|
|
|
1640
1666
|
inputSchema: {
|
|
1641
1667
|
fields: [
|
|
1642
1668
|
{ key: "operation", label: "Operation", type: "select" /* Select */, options: [{ label: "Parse (CSV → Records)", value: "parse" }, { label: "Generate (Records → CSV)", value: "generate" }, { label: "Edit existing file", value: "edit" }], defaultValue: "parse", validation: { required: true } },
|
|
1643
|
-
{ key: "content", label: "CSV Content", type: "string" /* String */, description: "
|
|
1669
|
+
{ key: "content", label: "CSV Content", type: "string" /* String */, description: FILE_INPUT_HELP.formatContent("CSV") },
|
|
1644
1670
|
{ key: "delimiter", label: "Delimiter", type: "select" /* Select */, options: [{ label: "Comma (,)", value: "," }, { label: "Semicolon (;)", value: ";" }, { label: "Tab", value: "\t" }, { label: "Pipe (|)", value: "|" }], defaultValue: "," },
|
|
1645
1671
|
{ key: "headerRow", label: "Header Row", type: "number" /* Number */, description: "Row number containing column headers (default: 1)", defaultValue: 1 },
|
|
1646
1672
|
{ key: "encoding", label: "Encoding", type: "select" /* Select */, options: [{ label: "UTF-8", value: "utf-8" }, { label: "Latin-1", value: "latin1" }, { label: "ASCII", value: "ascii" }], defaultValue: "utf-8" },
|
|
@@ -1680,7 +1706,7 @@ var jsonActionDefinition = {
|
|
|
1680
1706
|
fields: [
|
|
1681
1707
|
{ key: "operation", label: "Operation", type: "select" /* Select */, options: [{ label: "Parse (JSON → Records)", value: "parse" }, { label: "Generate (Records → JSON)", value: "generate" }, { label: "Edit existing file", value: "edit" }], defaultValue: "parse", validation: { required: true } },
|
|
1682
1708
|
{ key: "format", label: "Format", type: "select" /* Select */, options: [{ label: "JSON (array)", value: "json" }, { label: "JSONL (one object per line)", value: "jsonl" }], defaultValue: "json" },
|
|
1683
|
-
{ key: "content", label: "JSON Content", type: "string" /* String */, description: "
|
|
1709
|
+
{ key: "content", label: "JSON Content", type: "string" /* String */, description: FILE_INPUT_HELP.formatContent("JSON") },
|
|
1684
1710
|
{ key: "prettyPrint", label: "Pretty Print", type: "boolean" /* Boolean */, description: "Format output with indentation", defaultValue: true },
|
|
1685
1711
|
{ key: "fileName", label: "Output File Name", type: "string" /* String */, defaultValue: "export.json" }
|
|
1686
1712
|
]
|
|
@@ -1716,7 +1742,7 @@ var xmlActionDefinition = {
|
|
|
1716
1742
|
inputSchema: {
|
|
1717
1743
|
fields: [
|
|
1718
1744
|
{ key: "operation", label: "Operation", type: "select" /* Select */, options: [{ label: "Parse (XML → Records)", value: "parse" }, { label: "Generate (Records → XML)", value: "generate" }, { label: "Edit existing file", value: "edit" }], defaultValue: "parse", validation: { required: true } },
|
|
1719
|
-
{ key: "content", label: "XML Content", type: "string" /* String */, description: "
|
|
1745
|
+
{ key: "content", label: "XML Content", type: "string" /* String */, description: FILE_INPUT_HELP.formatContent("XML") },
|
|
1720
1746
|
{ key: "rootElement", label: "Root Element", type: "string" /* String */, description: "Root XML element name (for generate)", defaultValue: "data" },
|
|
1721
1747
|
{ key: "rowElement", label: "Row Element", type: "string" /* String */, description: "Element name per record (for generate)", defaultValue: "row" },
|
|
1722
1748
|
{ key: "fileName", label: "Output File Name", type: "string" /* String */, defaultValue: "export.xml" }
|
|
@@ -1753,7 +1779,7 @@ var excelActionDefinition = {
|
|
|
1753
1779
|
inputSchema: {
|
|
1754
1780
|
fields: [
|
|
1755
1781
|
{ key: "operation", label: "Operation", type: "select" /* Select */, options: [{ label: "Parse (Excel → Records)", value: "parse" }, { label: "Generate (Records → Excel)", value: "generate" }, { label: "Edit existing file", value: "edit" }], defaultValue: "parse", validation: { required: true } },
|
|
1756
|
-
{ key: "content", label: "Excel File", type: "string" /* String */, description:
|
|
1782
|
+
{ key: "content", label: "Excel File", type: "string" /* String */, description: FILE_INPUT_HELP.excelContent },
|
|
1757
1783
|
{ key: "sheetName", label: "Sheet Name", type: "string" /* String */, description: "Name of sheet to read (default: first sheet)" },
|
|
1758
1784
|
{ key: "headerRow", label: "Header Row", type: "number" /* Number */, description: "Row number containing headers", defaultValue: 1 },
|
|
1759
1785
|
{ key: "fileName", label: "Output File Name", type: "string" /* String */, defaultValue: "export.xlsx" }
|
|
@@ -1765,7 +1791,7 @@ var excelActionDefinition = {
|
|
|
1765
1791
|
{ key: "data", type: "array" /* Array */, description: "Parsed records (parse mode) — loop these with a ForEach. File metadata in generate mode." },
|
|
1766
1792
|
{ key: "columns", type: "json" /* JSON */, description: "Column names" },
|
|
1767
1793
|
{ key: "rowCount", type: "number" /* Number */, description: "Number of records" },
|
|
1768
|
-
{ key: "s3Key", type: "string" /* String */, description: "
|
|
1794
|
+
{ key: "s3Key", type: "string" /* String */, description: "The generated Excel file. Pass it to an Upload step to save it." }
|
|
1769
1795
|
],
|
|
1770
1796
|
sampleOutput: { data: [{ id: 1, name: "Widget" }], columns: ["id", "name"], rowCount: 1 }
|
|
1771
1797
|
},
|
|
@@ -1795,7 +1821,7 @@ var s3ActionDefinition = {
|
|
|
1795
1821
|
{ key: "bucket", label: "Bucket Name", type: "string" /* String */, description: "S3 bucket name (defaults to the connector’s bucket)" },
|
|
1796
1822
|
{ key: "key", label: "Object Key (Path)", type: "string" /* String */, description: "S3 object key, e.g. data/reports/monthly.csv" },
|
|
1797
1823
|
{ key: "prefix", label: "Prefix (for List)", type: "string" /* String */, description: "Filter objects by prefix (folder path)" },
|
|
1798
|
-
{ key: "content", label: "File Content (for Upload)", type: "string" /* String */, description:
|
|
1824
|
+
{ key: "content", label: "File Content (for Upload)", type: "string" /* String */, description: FILE_INPUT_HELP.uploadContent },
|
|
1799
1825
|
{ key: "contentType", label: "Content Type", type: "string" /* String */, description: "MIME type (e.g. text/csv, application/json)", defaultValue: "application/octet-stream" },
|
|
1800
1826
|
{ key: "destBucket", label: "Destination Bucket (for Copy)", type: "string" /* String */ },
|
|
1801
1827
|
{ key: "destKey", label: "Destination Key (for Copy)", type: "string" /* String */ },
|
|
@@ -1836,7 +1862,7 @@ var ftpActionDefinition = {
|
|
|
1836
1862
|
{ key: "connector", label: "FTP / SFTP Connection", type: "connection" /* Connection */, description: "Select a configured FTP/SFTP connector from Integrations", validation: { required: true } },
|
|
1837
1863
|
{ key: "operation", label: "Operation", type: "select" /* Select */, options: [{ label: "Download File", value: "download" }, { label: "Upload File", value: "upload" }, { label: "List Files", value: "list" }, { label: "Delete File", value: "delete" }, { label: "Move / Rename", value: "move" }], defaultValue: "download", validation: { required: true } },
|
|
1838
1864
|
{ key: "remotePath", label: "Remote Path", type: "string" /* String */, description: "File or folder path on the server (use file explorer to browse)" },
|
|
1839
|
-
{ key: "content", label: "File Content (Upload)", type: "string" /* String */, description:
|
|
1865
|
+
{ key: "content", label: "File Content (Upload)", type: "string" /* String */, description: FILE_INPUT_HELP.uploadContent },
|
|
1840
1866
|
{ key: "fileName", label: "File Name (Upload)", type: "string" /* String */, description: "Name for the uploaded file" },
|
|
1841
1867
|
{ key: "destPath", label: "Destination Path (Move)", type: "string" /* String */, description: "New path for moved/renamed file" },
|
|
1842
1868
|
{ key: "ifExists", label: "If File Exists", type: "select" /* Select */, options: [{ label: "Overwrite", value: "overwrite" }, { label: "Skip", value: "skip" }], defaultValue: "overwrite" }
|
|
@@ -1877,7 +1903,7 @@ var googleDriveActionDefinition = {
|
|
|
1877
1903
|
{ key: "fileId", label: "File ID / Path", type: "string" /* String */, description: "Google Drive file ID (use file explorer to browse)" },
|
|
1878
1904
|
{ key: "folderId", label: "Folder ID", type: "string" /* String */, description: "Target folder (root if empty)" },
|
|
1879
1905
|
{ key: "fileName", label: "File Name", type: "string" /* String */ },
|
|
1880
|
-
{ key: "content", label: "File Content (Upload)", type: "string" /* String */, description:
|
|
1906
|
+
{ key: "content", label: "File Content (Upload)", type: "string" /* String */, description: FILE_INPUT_HELP.uploadContent },
|
|
1881
1907
|
{ key: "mimeType", label: "MIME Type", type: "string" /* String */, defaultValue: "application/octet-stream" },
|
|
1882
1908
|
{ key: "destFolderId", label: "Destination Folder (Move/Copy)", type: "string" /* String */ },
|
|
1883
1909
|
{ key: "shareEmail", label: "Share With Email", type: "string" /* String */ },
|
|
@@ -1919,7 +1945,7 @@ var dropboxActionDefinition = {
|
|
|
1919
1945
|
{ key: "connector", label: "Dropbox Account", type: "connection" /* Connection */, description: "Select a connected Dropbox account", validation: { required: true } },
|
|
1920
1946
|
{ key: "operation", label: "Operation", type: "select" /* Select */, options: [{ label: "Download File", value: "download" }, { label: "Upload File", value: "upload" }, { label: "List Files", value: "list" }, { label: "Delete", value: "delete" }, { label: "Move", value: "move" }, { label: "Copy", value: "copy" }, { label: "Create Folder", value: "create_folder" }, { label: "Get Shared Link", value: "shared_link" }], defaultValue: "download", validation: { required: true } },
|
|
1921
1947
|
{ key: "path", label: "File / Folder Path", type: "string" /* String */, description: "Path on Dropbox (use file explorer to browse)" },
|
|
1922
|
-
{ key: "content", label: "File Content (Upload)", type: "string" /* String */, description:
|
|
1948
|
+
{ key: "content", label: "File Content (Upload)", type: "string" /* String */, description: FILE_INPUT_HELP.uploadContent },
|
|
1923
1949
|
{ key: "fileName", label: "File Name (Upload)", type: "string" /* String */ },
|
|
1924
1950
|
{ key: "destPath", label: "Destination Path (Move/Copy)", type: "string" /* String */ },
|
|
1925
1951
|
{ key: "mode", label: "Upload Mode", type: "select" /* Select */, options: [{ label: "Add (fail if exists)", value: "add" }, { label: "Overwrite", value: "overwrite" }], defaultValue: "overwrite" }
|
|
@@ -1959,7 +1985,7 @@ var onedriveActionDefinition = {
|
|
|
1959
1985
|
{ key: "operation", label: "Operation", type: "select" /* Select */, options: [{ label: "Download File", value: "download" }, { label: "Upload File", value: "upload" }, { label: "List Files", value: "list" }, { label: "Delete", value: "delete" }, { label: "Move", value: "move" }, { label: "Copy", value: "copy" }], defaultValue: "download", validation: { required: true } },
|
|
1960
1986
|
{ key: "path", label: "File / Folder Path", type: "string" /* String */, description: "Path on OneDrive (use file explorer to browse)" },
|
|
1961
1987
|
{ key: "itemId", label: "Item ID", type: "string" /* String */, description: "OneDrive item ID (alternative to path)" },
|
|
1962
|
-
{ key: "content", label: "File Content (Upload)", type: "string" /* String */, description:
|
|
1988
|
+
{ key: "content", label: "File Content (Upload)", type: "string" /* String */, description: FILE_INPUT_HELP.uploadContent },
|
|
1963
1989
|
{ key: "fileName", label: "File Name (Upload)", type: "string" /* String */ },
|
|
1964
1990
|
{ key: "destPath", label: "Destination Path (Move/Copy)", type: "string" /* String */ }
|
|
1965
1991
|
]
|
|
@@ -2017,14 +2043,17 @@ var storageActionDefinition = {
|
|
|
2017
2043
|
},
|
|
2018
2044
|
{ key: "path", label: "Path", type: "string" /* String */, description: "File or folder path — use the file browser in the panel." },
|
|
2019
2045
|
{ key: "destPath", label: "Destination path", type: "string" /* String */, description: "Target for copy / move." },
|
|
2020
|
-
{ key: "content", label: "File content (for Upload)", type: "string" /* String */, description:
|
|
2046
|
+
{ key: "content", label: "File content (for Upload)", type: "string" /* String */, description: FILE_INPUT_HELP.uploadContent }
|
|
2021
2047
|
]
|
|
2022
2048
|
},
|
|
2023
2049
|
outputSchema: {
|
|
2024
2050
|
type: "object",
|
|
2025
2051
|
properties: [
|
|
2026
2052
|
{ key: "operation", type: "string" /* String */, description: "The operation that ran" },
|
|
2027
|
-
{ key: "data", type: "json" /* JSON */, description:
|
|
2053
|
+
{ key: "data", type: "json" /* JSON */, description: `Download: ${FILE_OUTPUT_HELP.data}. Other operations: their result.` },
|
|
2054
|
+
{ key: "s3Key", type: "string" /* String */, description: `Download: ${FILE_OUTPUT_HELP.s3Key}` },
|
|
2055
|
+
{ key: "fileName", type: "string" /* String */, description: `Download: ${FILE_OUTPUT_HELP.fileName}` },
|
|
2056
|
+
{ key: "mimeType", type: "string" /* String */, description: `Download: ${FILE_OUTPUT_HELP.mimeType}` },
|
|
2028
2057
|
{ key: "files", type: "json" /* JSON */, description: "Listing (for the List operation)" },
|
|
2029
2058
|
{ key: "path", type: "string" /* String */, description: "Affected file/folder path" },
|
|
2030
2059
|
{ key: "url", type: "string" /* String */, description: "Signed URL (for the Get signed URL operation)" }
|
|
@@ -3182,7 +3211,13 @@ var ForEachConfig = {
|
|
|
3182
3211
|
itemVariable: { type: "string", required: true },
|
|
3183
3212
|
indexVariable: { type: "string", required: false },
|
|
3184
3213
|
batchSize: { type: "number", required: false },
|
|
3185
|
-
continueOnError: { type: "boolean", required: false }
|
|
3214
|
+
continueOnError: { type: "boolean", required: false },
|
|
3215
|
+
collect: {
|
|
3216
|
+
type: "select",
|
|
3217
|
+
required: false,
|
|
3218
|
+
options: ["array", "none", "groupBy", "reduce", "rows"],
|
|
3219
|
+
description: "What the Done port carries besides the counts: array (each iteration's result in `results`, the default), none, groupBy (by groupByPath), " + "reduce (reduceOp over reducePath), or rows — also `data`: every row the body produced (each iteration's Query/Transform rows, else its result), " + "so ONE step on the Done port maps and writes them all instead of a write per iteration."
|
|
3220
|
+
}
|
|
3186
3221
|
},
|
|
3187
3222
|
validate: (config) => {
|
|
3188
3223
|
const errors = [];
|
|
@@ -3567,6 +3602,34 @@ var TRANSFORM_OPERATIONS = [
|
|
|
3567
3602
|
];
|
|
3568
3603
|
var TRANSFORM_OPERATION_IDS = TRANSFORM_OPERATIONS.map((o) => o.id);
|
|
3569
3604
|
var DATABASE_CONNECTOR_IDS = new Set(["mongodb", "postgresql", "mysql", "google_sheets"]);
|
|
3605
|
+
function groupByErrors(config) {
|
|
3606
|
+
const groupBy = config.groupBy;
|
|
3607
|
+
if (!groupBy || !(groupBy.key || groupBy.into || groupBy.linesFrom))
|
|
3608
|
+
return [];
|
|
3609
|
+
const errors = [];
|
|
3610
|
+
if (!groupBy.key && !groupBy.linesFrom) {
|
|
3611
|
+
errors.push("One record per key: choose the key field (groupBy.key)");
|
|
3612
|
+
}
|
|
3613
|
+
if (!groupBy.into)
|
|
3614
|
+
errors.push("One record per key: name the field that holds the lines (groupBy.into)");
|
|
3615
|
+
if ((groupBy.key || groupBy.linesFrom) && groupBy.into && !(config.mappings ?? []).some((m) => m.lineField)) {
|
|
3616
|
+
errors.push("One record per key: mark at least one mapping as a line field (lineField: true)");
|
|
3617
|
+
}
|
|
3618
|
+
return errors;
|
|
3619
|
+
}
|
|
3620
|
+
function unwindErrors(config) {
|
|
3621
|
+
const unwind = config.unwind;
|
|
3622
|
+
if (!unwind)
|
|
3623
|
+
return [];
|
|
3624
|
+
if (!unwind.path?.trim()) {
|
|
3625
|
+
return unwind.keepEmpty !== undefined ? ["One row per item: choose the list (unwind.path)"] : [];
|
|
3626
|
+
}
|
|
3627
|
+
const linesFrom = config.groupBy?.linesFrom;
|
|
3628
|
+
if (linesFrom && linesFrom.trim() === unwind.path.trim()) {
|
|
3629
|
+
return ["One row per item and Lines come from name the same list — use one of them (unwind.path, groupBy.linesFrom)"];
|
|
3630
|
+
}
|
|
3631
|
+
return [];
|
|
3632
|
+
}
|
|
3570
3633
|
var TransformConfig = {
|
|
3571
3634
|
defaults: {
|
|
3572
3635
|
name: "Transform",
|
|
@@ -3616,12 +3679,17 @@ var TransformConfig = {
|
|
|
3616
3679
|
mappings: {
|
|
3617
3680
|
type: "array",
|
|
3618
3681
|
required: false,
|
|
3619
|
-
description: "Field mappings: [{ id, sourceField, targetField, targetType, transform? }]. sourceField is a token like {{orders[].email}}; " + "an index picks one list element ({{products[].variants[0].price}}). With groupBy, set lineField: true on the mappings that make each line. " + 'When the target field holds a record id but you have a reference (an email, SHOP-123), add lookup: { "object": "product.product", "matchField": "default_code" } — ' + "the write uses the id of the one record whose matchField equals the value; no match, or more than one, fails that row. Odoo
|
|
3682
|
+
description: "Field mappings: [{ id, sourceField, targetField, targetType, transform? }]. sourceField is a token like {{orders[].email}}; " + "an index picks one list element ({{products[].variants[0].price}}). With groupBy, set lineField: true on the mappings that make each line. " + 'When the target field holds a record id but you have a reference (an email, SHOP-123), add lookup: { "object": "product.product", "matchField": "default_code" } — ' + "the write uses the id of the one record whose matchField equals the value; no match, or more than one, fails that row. Odoo and QuickBooks Online (e.g. CustomerRef.value → Customer by DisplayName; " + "Line.SalesItemLineDetail.ItemRef.value → Item by Name). A QuickBooks transaction upsert matches on DocNumber unless upsertMatchKey says otherwise."
|
|
3620
3683
|
},
|
|
3621
3684
|
groupBy: {
|
|
3622
3685
|
type: "json",
|
|
3623
3686
|
required: false,
|
|
3624
|
-
description:
|
|
3687
|
+
description: "Records with line items; mappings with lineField: true become a list of lines under `into` (Shopify line_items, QuickBooks Line, Odoo order_line). " + 'Two ways, combinable: (1) the lines are flat rows — { "key": "{{orders[].number}}", "into": "order_line" }: rows with the same key become ONE record ' + '(its fields from the first row), one line per row; (2) the lines are a list INSIDE each row — { "into": "order_line", "linesFrom": "{{orders[].line_items}}" }: ' + "each row is one record and each element of the list one line; a line field under the list ({{orders[].line_items[].quantity}}) reads the element, " + "any other path reads the row. Dotted line fields nest inside each line (SalesItemLineDetail.ItemRef.value)."
|
|
3688
|
+
},
|
|
3689
|
+
unwind: {
|
|
3690
|
+
type: "json",
|
|
3691
|
+
required: false,
|
|
3692
|
+
description: 'One row per element of a list on each row: { "path": "{{orders[].line_items}}", "keepEmpty": false }. Every mapping then reads the element under the ' + "list path ({{orders[].line_items[].sku}}) and the row everywhere else ({{orders[].name}}) — an order becomes one row per line, for targets that take " + "flat rows (Sheets, SQL). A row whose list is empty is dropped unless keepEmpty is true."
|
|
3625
3693
|
},
|
|
3626
3694
|
expression: { type: "code", required: false }
|
|
3627
3695
|
},
|
|
@@ -3667,16 +3735,7 @@ var TransformConfig = {
|
|
|
3667
3735
|
});
|
|
3668
3736
|
}
|
|
3669
3737
|
}
|
|
3670
|
-
|
|
3671
|
-
if (groupBy && (groupBy.key || groupBy.into)) {
|
|
3672
|
-
if (!groupBy.key)
|
|
3673
|
-
errors.push("One record per key: choose the key field (groupBy.key)");
|
|
3674
|
-
if (!groupBy.into)
|
|
3675
|
-
errors.push("One record per key: name the field that holds the lines (groupBy.into)");
|
|
3676
|
-
if (groupBy.key && groupBy.into && !(config.mappings ?? []).some((m) => m.lineField)) {
|
|
3677
|
-
errors.push("One record per key: mark at least one mapping as a line field (lineField: true)");
|
|
3678
|
-
}
|
|
3679
|
-
}
|
|
3738
|
+
errors.push(...groupByErrors(config), ...unwindErrors(config));
|
|
3680
3739
|
return { valid: errors.length === 0, errors };
|
|
3681
3740
|
},
|
|
3682
3741
|
merge: (userConfig) => {
|
|
@@ -4440,10 +4499,10 @@ var FILE_EDIT_SCHEMA = {
|
|
|
4440
4499
|
matchOp: { type: "select", required: false, options: FILE_EDIT_MATCH_OPS, description: 'set_fields: comparison; "=" by default' },
|
|
4441
4500
|
matchValue: { type: "string", required: false, description: "set_fields: value compared against" },
|
|
4442
4501
|
setFields: { type: "object", required: false, description: "set_fields: { column: newValue } applied to matching rows" },
|
|
4443
|
-
destination: { type: "select", required: false, options: FILE_EDIT_DESTINATIONS, description: '"new" writes an edited copy (default); "in_place" overwrites
|
|
4502
|
+
destination: { type: "select", required: false, options: FILE_EDIT_DESTINATIONS, description: '"new" writes an edited copy (default); "in_place" overwrites the source file' },
|
|
4444
4503
|
outputFileName: { type: "string", required: false, description: 'Name of the edited copy when destination is "new"' },
|
|
4445
4504
|
source: { type: "select", required: false, options: FILE_EDIT_SOURCES, description: "Where the file to edit comes from; inferred from content when absent" },
|
|
4446
|
-
s3Key: { type: "string", required: false, description:
|
|
4505
|
+
s3Key: { type: "string", required: false, description: `source "s3": an earlier step's file (its s3Key output) to edit` },
|
|
4447
4506
|
url: { type: "url", required: false, description: 'source "url": the file to edit is fetched from here' }
|
|
4448
4507
|
};
|
|
4449
4508
|
function fileEditErrors(config) {
|
|
@@ -4475,7 +4534,7 @@ var CsvActionConfig = {
|
|
|
4475
4534
|
},
|
|
4476
4535
|
schema: {
|
|
4477
4536
|
operation: { type: "select", required: true, options: FILE_FORMAT_OPERATIONS, description: "parse (CSV → records), generate (records → CSV) or edit an existing file" },
|
|
4478
|
-
content: { type: "text", required: false, description: "CSV text, or
|
|
4537
|
+
content: { type: "text", required: false, description: "CSV text, or a reference to an earlier step's file content" },
|
|
4479
4538
|
delimiter: { type: "select", required: false, options: [",", ";", "\t", "|"] },
|
|
4480
4539
|
headerRow: { type: "number", required: false, min: 1, description: "1-based row that holds the column headers" },
|
|
4481
4540
|
encoding: { type: "string", required: false, description: "Text encoding (utf-8 by default)" },
|
|
@@ -4501,7 +4560,7 @@ var JsonActionConfig = {
|
|
|
4501
4560
|
schema: {
|
|
4502
4561
|
operation: { type: "select", required: true, options: FILE_FORMAT_OPERATIONS, description: "parse (JSON → records), generate (records → JSON) or edit an existing file" },
|
|
4503
4562
|
format: { type: "select", required: false, options: ["json", "jsonl"], description: "json (array) or jsonl (one object per line)" },
|
|
4504
|
-
content: { type: "text", required: false, description: "JSON text, or
|
|
4563
|
+
content: { type: "text", required: false, description: "JSON text, or a reference to an earlier step's file content" },
|
|
4505
4564
|
prettyPrint: { type: "boolean", required: false, description: "generate: indent the output" },
|
|
4506
4565
|
fileName: { type: "string", required: false, description: "generate: name of the produced file" },
|
|
4507
4566
|
jsonl: { type: "boolean", required: false, description: "edit: treat the file as JSONL" },
|
|
@@ -4528,7 +4587,7 @@ var XmlActionConfig = {
|
|
|
4528
4587
|
},
|
|
4529
4588
|
schema: {
|
|
4530
4589
|
operation: { type: "select", required: true, options: FILE_FORMAT_OPERATIONS, description: "parse (XML → records), generate (records → XML) or edit an existing file" },
|
|
4531
|
-
content: { type: "text", required: false, description: "XML text, or
|
|
4590
|
+
content: { type: "text", required: false, description: "XML text, or a reference to an earlier step's file content" },
|
|
4532
4591
|
rootElement: { type: "string", required: false, description: "generate: root element name" },
|
|
4533
4592
|
rowElement: { type: "string", required: false, description: "Element that holds one record" },
|
|
4534
4593
|
fileName: { type: "string", required: false, description: "generate: name of the produced file" },
|
|
@@ -4550,7 +4609,7 @@ var ExcelActionConfig = {
|
|
|
4550
4609
|
},
|
|
4551
4610
|
schema: {
|
|
4552
4611
|
operation: { type: "select", required: true, options: FILE_FORMAT_OPERATIONS, description: "parse (Excel → records), generate (records → Excel) or edit an existing file" },
|
|
4553
|
-
content: { type: "text", required: false, description: "
|
|
4612
|
+
content: { type: "text", required: false, description: "A reference to an earlier step's Excel file (its s3Key output), or base64 bytes" },
|
|
4554
4613
|
sheetName: { type: "string", required: false, description: "Sheet to read; the first sheet when absent" },
|
|
4555
4614
|
headerRow: { type: "number", required: false, min: 1, description: "1-based row that holds the column headers" },
|
|
4556
4615
|
fileName: { type: "string", required: false, description: "generate: name of the produced file" },
|
|
@@ -4568,7 +4627,7 @@ var FIXED_SCHEMA = {
|
|
|
4568
4627
|
connector: { type: "connection", required: true, description: "Storage connector instance; its provider decides the operations" },
|
|
4569
4628
|
operation: { type: "select", required: true, description: "Per provider: list, download, upload, delete, copy, move, presign, share, create_folder, transfer, sync" },
|
|
4570
4629
|
outputAs: { type: "string", required: false, description: "Name of this step's output in the run's data bag" },
|
|
4571
|
-
content: { type: "text", required: false, description: "upload: the
|
|
4630
|
+
content: { type: "text", required: false, description: "upload: the file content; blank uploads the file the step before produced" },
|
|
4572
4631
|
destConnector: { type: "connection", required: false, description: "transfer / sync: destination connector instance" },
|
|
4573
4632
|
destPath: { type: "string", required: false, description: "transfer / sync: destination path; also move / copy destination on path-based providers" },
|
|
4574
4633
|
sourceIsDirectory: { type: "boolean", required: false, description: "transfer: copy a folder recursively" },
|
|
@@ -5972,6 +6031,8 @@ export {
|
|
|
5972
6031
|
FILE_EDIT_SCHEMA,
|
|
5973
6032
|
FILE_EDIT_SOURCES,
|
|
5974
6033
|
FILE_FORMAT_OPERATIONS,
|
|
6034
|
+
FILE_INPUT_HELP,
|
|
6035
|
+
FILE_OUTPUT_HELP,
|
|
5975
6036
|
FTP_OPERATIONS,
|
|
5976
6037
|
FieldType,
|
|
5977
6038
|
ForEachConfig,
|
|
@@ -5997,6 +6058,7 @@ export {
|
|
|
5997
6058
|
S3ActionConfig,
|
|
5998
6059
|
S3_OPERATIONS,
|
|
5999
6060
|
STORAGE_CONNECTOR_IDS,
|
|
6061
|
+
STORAGE_DOWNLOAD_OUTPUT_SCHEMA,
|
|
6000
6062
|
SortDirection,
|
|
6001
6063
|
StorageActionConfig,
|
|
6002
6064
|
TRANSFORM_MODES,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@octaviaflow/flow-rules",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.18.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",
|