@celigo/api-specs 0.2.138 → 0.2.140

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.
@@ -1249,7 +1249,7 @@ components:
1249
1249
 
1250
1250
  **Common filter patterns**
1251
1251
 
1252
- 1. **Pattern matching**: Using wildcards like `*` and `?`
1252
+ 1. **Pattern matching**: Regular expressions with `matches`
1253
1253
  2. **Value range filtering**: Numbers between min and max values
1254
1254
  3. **Date range filtering**: Items created/modified within specific time ranges
1255
1255
  4. **Status checking**: Items with specific status values or properties
@@ -1299,9 +1299,12 @@ components:
1299
1299
  - `"endswith"`: String ends with specified suffix (ends with)
1300
1300
  - `"contains"`: String contains specified substring (contains)
1301
1301
  - `"doesnotcontain"`: String does not contain specified substring (does not contain)
1302
- - `"isempty"`: Field is empty or null (is empty)
1303
- - `"isnotempty"`: Field contains a value (is not empty)
1304
- - `"matches"`: Matches specified pattern (matches)
1302
+ - `"empty"`: Field is missing or empty (is empty)
1303
+ - `"notempty"`: Field contains a value (is not empty)
1304
+ - `"matches"`: Matches a regular expression (matches)
1305
+
1306
+ `isempty`, `isnotempty` and `anyof` are not operators: they are refused with 422
1307
+ "Invalid operation: <name>".
1305
1308
 
1306
1309
  **Logical Operators**
1307
1310
  - `"and"`: All conditions must be true
@@ -1321,7 +1324,11 @@ components:
1321
1324
  **Using `extract` to access record fields:**
1322
1325
  - Retrieves values from the current record being processed
1323
1326
  - Can access nested properties using dot notation (e.g., `"customer.email"`)
1324
- - Returns the raw field value which may need type conversion
1327
+ - In a record filter, must be wrapped in a type conversion (`string`, `number`,
1328
+ `boolean` or `epochtime`): a bare `["extract", ...]` operand is refused with 422
1329
+ "Field operation extract must be called by a Type Conversion Operation but was called
1330
+ by <operator>", both when an import's filter is saved and by
1331
+ `POST /v1/processors/filter`
1325
1332
 
1326
1333
  **Using `settings` to access configuration values:**
1327
1334
  - Retrieves values from the integration's configuration settings
@@ -1339,7 +1346,20 @@ components:
1339
1346
  - `"floor"`: Round number down to the nearest integer
1340
1347
  - `"abs"`: Get absolute value of a number
1341
1348
 
1342
- Type conversion operators are often necessary when comparing extracted field values against literals or when the field type doesn't match the comparison operator's expected type. For example:
1349
+ **Handlebars operands**
1350
+ - An operand can also be a string holding exactly one Handlebars expression, such as
1351
+ `"{{record.status}}"` or `"{{lowercase record.code}}"`, on either side of the
1352
+ operator. It renders against the record (`record.<field>`; an unprefixed
1353
+ `{{status}}` renders empty) before the comparison.
1354
+ - The rendered value is a string: wrap it in `["number", ...]` to compare it with a
1355
+ number, or the rule is refused with 422.
1356
+ - `epochtime` does not render Handlebars: `["epochtime", "{{timestamp}}"]` is refused
1357
+ with 422 "invalid datetime format".
1358
+ - A string with text around the expression, or with more than one expression, is
1359
+ compared as a literal.
1360
+
1361
+ Choose the type conversion that matches the comparison — `number` for numeric
1362
+ comparisons, `epochtime` for dates, `string` for text. For example:
1343
1363
 
1344
1364
  ```json
1345
1365
  [
@@ -1430,8 +1450,11 @@ components:
1430
1450
  [
1431
1451
  "notequals",
1432
1452
  [
1433
- "extract",
1434
- "status"
1453
+ "string",
1454
+ [
1455
+ "extract",
1456
+ "status"
1457
+ ]
1435
1458
  ],
1436
1459
  "cancelled"
1437
1460
  ]
@@ -1442,8 +1465,11 @@ components:
1442
1465
  [
1443
1466
  "startswith",
1444
1467
  [
1445
- "extract",
1446
- "filename"
1468
+ "string",
1469
+ [
1470
+ "extract",
1471
+ "filename"
1472
+ ]
1447
1473
  ],
1448
1474
  "HC"
1449
1475
  ]
@@ -1464,29 +1490,26 @@ components:
1464
1490
  ]
1465
1491
  ```
1466
1492
 
1467
- Example 4: Order date is after January 1, 2023
1493
+ Example 4: Order date is after January 1, 2023 (UTC). Compare dates as `epochtime`
1494
+ against epoch milliseconds: a `string` comparison of ISO timestamps orders values with
1495
+ different UTC offsets wrongly.
1468
1496
  ```json
1469
1497
  [
1470
1498
  "greaterthan",
1471
1499
  [
1472
- "extract",
1473
- "orderDate"
1474
- ],
1475
- "2023-01-01T00:00:00Z"
1476
- ]
1477
- ```
1478
-
1479
- Example 5: Category contains any of ["Urgent", "High Priority"]
1480
- ```json
1481
- [
1482
- "anyof",
1483
- [
1484
- "extract",
1485
- "category"
1500
+ "epochtime",
1501
+ [
1502
+ "extract",
1503
+ "orderDate"
1504
+ ]
1486
1505
  ],
1487
- ["Urgent", "High Priority"]
1506
+ 1672531200000
1488
1507
  ]
1489
1508
  ```
1509
+ x-celigo-ai-guidance:
1510
+ - |-
1511
+ To test whether a field has a value, use `notempty` on the wrapped extract, not a
1512
+ `matches` pattern: a record without the field matches `.*\S.*`.
1490
1513
  items:
1491
1514
  oneOf:
1492
1515
  - title: String
@@ -695,7 +695,7 @@ components:
695
695
 
696
696
  **Common filter patterns**
697
697
 
698
- 1. **Pattern matching**: Using wildcards like `*` and `?`
698
+ 1. **Pattern matching**: Regular expressions with `matches`
699
699
  2. **Value range filtering**: Numbers between min and max values
700
700
  3. **Date range filtering**: Items created/modified within specific time ranges
701
701
  4. **Status checking**: Items with specific status values or properties
@@ -745,9 +745,12 @@ components:
745
745
  - `"endswith"`: String ends with specified suffix (ends with)
746
746
  - `"contains"`: String contains specified substring (contains)
747
747
  - `"doesnotcontain"`: String does not contain specified substring (does not contain)
748
- - `"isempty"`: Field is empty or null (is empty)
749
- - `"isnotempty"`: Field contains a value (is not empty)
750
- - `"matches"`: Matches specified pattern (matches)
748
+ - `"empty"`: Field is missing or empty (is empty)
749
+ - `"notempty"`: Field contains a value (is not empty)
750
+ - `"matches"`: Matches a regular expression (matches)
751
+
752
+ `isempty`, `isnotempty` and `anyof` are not operators: they are refused with 422
753
+ "Invalid operation: <name>".
751
754
 
752
755
  **Logical Operators**
753
756
  - `"and"`: All conditions must be true
@@ -767,7 +770,11 @@ components:
767
770
  **Using `extract` to access record fields:**
768
771
  - Retrieves values from the current record being processed
769
772
  - Can access nested properties using dot notation (e.g., `"customer.email"`)
770
- - Returns the raw field value which may need type conversion
773
+ - In a record filter, must be wrapped in a type conversion (`string`, `number`,
774
+ `boolean` or `epochtime`): a bare `["extract", ...]` operand is refused with 422
775
+ "Field operation extract must be called by a Type Conversion Operation but was called
776
+ by <operator>", both when an import's filter is saved and by
777
+ `POST /v1/processors/filter`
771
778
 
772
779
  **Using `settings` to access configuration values:**
773
780
  - Retrieves values from the integration's configuration settings
@@ -785,7 +792,20 @@ components:
785
792
  - `"floor"`: Round number down to the nearest integer
786
793
  - `"abs"`: Get absolute value of a number
787
794
 
788
- Type conversion operators are often necessary when comparing extracted field values against literals or when the field type doesn't match the comparison operator's expected type. For example:
795
+ **Handlebars operands**
796
+ - An operand can also be a string holding exactly one Handlebars expression, such as
797
+ `"{{record.status}}"` or `"{{lowercase record.code}}"`, on either side of the
798
+ operator. It renders against the record (`record.<field>`; an unprefixed
799
+ `{{status}}` renders empty) before the comparison.
800
+ - The rendered value is a string: wrap it in `["number", ...]` to compare it with a
801
+ number, or the rule is refused with 422.
802
+ - `epochtime` does not render Handlebars: `["epochtime", "{{timestamp}}"]` is refused
803
+ with 422 "invalid datetime format".
804
+ - A string with text around the expression, or with more than one expression, is
805
+ compared as a literal.
806
+
807
+ Choose the type conversion that matches the comparison — `number` for numeric
808
+ comparisons, `epochtime` for dates, `string` for text. For example:
789
809
 
790
810
  ```json
791
811
  [
@@ -876,8 +896,11 @@ components:
876
896
  [
877
897
  "notequals",
878
898
  [
879
- "extract",
880
- "status"
899
+ "string",
900
+ [
901
+ "extract",
902
+ "status"
903
+ ]
881
904
  ],
882
905
  "cancelled"
883
906
  ]
@@ -888,8 +911,11 @@ components:
888
911
  [
889
912
  "startswith",
890
913
  [
891
- "extract",
892
- "filename"
914
+ "string",
915
+ [
916
+ "extract",
917
+ "filename"
918
+ ]
893
919
  ],
894
920
  "HC"
895
921
  ]
@@ -910,29 +936,26 @@ components:
910
936
  ]
911
937
  ```
912
938
 
913
- Example 4: Order date is after January 1, 2023
939
+ Example 4: Order date is after January 1, 2023 (UTC). Compare dates as `epochtime`
940
+ against epoch milliseconds: a `string` comparison of ISO timestamps orders values with
941
+ different UTC offsets wrongly.
914
942
  ```json
915
943
  [
916
944
  "greaterthan",
917
945
  [
918
- "extract",
919
- "orderDate"
920
- ],
921
- "2023-01-01T00:00:00Z"
922
- ]
923
- ```
924
-
925
- Example 5: Category contains any of ["Urgent", "High Priority"]
926
- ```json
927
- [
928
- "anyof",
929
- [
930
- "extract",
931
- "category"
946
+ "epochtime",
947
+ [
948
+ "extract",
949
+ "orderDate"
950
+ ]
932
951
  ],
933
- ["Urgent", "High Priority"]
952
+ 1672531200000
934
953
  ]
935
954
  ```
955
+ x-celigo-ai-guidance:
956
+ - |-
957
+ To test whether a field has a value, use `notempty` on the wrapped extract, not a
958
+ `matches` pattern: a record without the field matches `.*\S.*`.
936
959
  items:
937
960
  oneOf:
938
961
  - title: String
package/dist/import.yml CHANGED
@@ -8496,7 +8496,7 @@ components:
8496
8496
  without the array); a mapping reshapes the message instead.
8497
8497
  - |-
8498
8498
  Publishing is not limited to flows. Verified surfaces: a flow step; an API step (the API
8499
- invoked at `POST /apis/{version}/{relativeURI}`); a Tool reached through a `ToolImport`
8499
+ invoked at `POST /apis/{version}{relativeURI}`); a Tool reached through a `ToolImport`
8500
8500
  step in a flow; and `POST /v1/imports/{_id}/invoke` with `{"data": [record, ...]}`. A flow
8501
8501
  or API test run (`/test/run`) publishes nothing — import steps are mocked there.
8502
8502
  properties:
@@ -12130,7 +12130,7 @@ components:
12130
12130
 
12131
12131
  **Common filter patterns**
12132
12132
 
12133
- 1. **Pattern matching**: Using wildcards like `*` and `?`
12133
+ 1. **Pattern matching**: Regular expressions with `matches`
12134
12134
  2. **Value range filtering**: Numbers between min and max values
12135
12135
  3. **Date range filtering**: Items created/modified within specific time ranges
12136
12136
  4. **Status checking**: Items with specific status values or properties
@@ -12180,9 +12180,12 @@ components:
12180
12180
  - `"endswith"`: String ends with specified suffix (ends with)
12181
12181
  - `"contains"`: String contains specified substring (contains)
12182
12182
  - `"doesnotcontain"`: String does not contain specified substring (does not contain)
12183
- - `"isempty"`: Field is empty or null (is empty)
12184
- - `"isnotempty"`: Field contains a value (is not empty)
12185
- - `"matches"`: Matches specified pattern (matches)
12183
+ - `"empty"`: Field is missing or empty (is empty)
12184
+ - `"notempty"`: Field contains a value (is not empty)
12185
+ - `"matches"`: Matches a regular expression (matches)
12186
+
12187
+ `isempty`, `isnotempty` and `anyof` are not operators: they are refused with 422
12188
+ "Invalid operation: <name>".
12186
12189
 
12187
12190
  **Logical Operators**
12188
12191
  - `"and"`: All conditions must be true
@@ -12202,7 +12205,11 @@ components:
12202
12205
  **Using `extract` to access record fields:**
12203
12206
  - Retrieves values from the current record being processed
12204
12207
  - Can access nested properties using dot notation (e.g., `"customer.email"`)
12205
- - Returns the raw field value which may need type conversion
12208
+ - In a record filter, must be wrapped in a type conversion (`string`, `number`,
12209
+ `boolean` or `epochtime`): a bare `["extract", ...]` operand is refused with 422
12210
+ "Field operation extract must be called by a Type Conversion Operation but was called
12211
+ by <operator>", both when an import's filter is saved and by
12212
+ `POST /v1/processors/filter`
12206
12213
 
12207
12214
  **Using `settings` to access configuration values:**
12208
12215
  - Retrieves values from the integration's configuration settings
@@ -12220,7 +12227,20 @@ components:
12220
12227
  - `"floor"`: Round number down to the nearest integer
12221
12228
  - `"abs"`: Get absolute value of a number
12222
12229
 
12223
- Type conversion operators are often necessary when comparing extracted field values against literals or when the field type doesn't match the comparison operator's expected type. For example:
12230
+ **Handlebars operands**
12231
+ - An operand can also be a string holding exactly one Handlebars expression, such as
12232
+ `"{{record.status}}"` or `"{{lowercase record.code}}"`, on either side of the
12233
+ operator. It renders against the record (`record.<field>`; an unprefixed
12234
+ `{{status}}` renders empty) before the comparison.
12235
+ - The rendered value is a string: wrap it in `["number", ...]` to compare it with a
12236
+ number, or the rule is refused with 422.
12237
+ - `epochtime` does not render Handlebars: `["epochtime", "{{timestamp}}"]` is refused
12238
+ with 422 "invalid datetime format".
12239
+ - A string with text around the expression, or with more than one expression, is
12240
+ compared as a literal.
12241
+
12242
+ Choose the type conversion that matches the comparison — `number` for numeric
12243
+ comparisons, `epochtime` for dates, `string` for text. For example:
12224
12244
 
12225
12245
  ```json
12226
12246
  [
@@ -12311,8 +12331,11 @@ components:
12311
12331
  [
12312
12332
  "notequals",
12313
12333
  [
12314
- "extract",
12315
- "status"
12334
+ "string",
12335
+ [
12336
+ "extract",
12337
+ "status"
12338
+ ]
12316
12339
  ],
12317
12340
  "cancelled"
12318
12341
  ]
@@ -12323,8 +12346,11 @@ components:
12323
12346
  [
12324
12347
  "startswith",
12325
12348
  [
12326
- "extract",
12327
- "filename"
12349
+ "string",
12350
+ [
12351
+ "extract",
12352
+ "filename"
12353
+ ]
12328
12354
  ],
12329
12355
  "HC"
12330
12356
  ]
@@ -12345,29 +12371,26 @@ components:
12345
12371
  ]
12346
12372
  ```
12347
12373
 
12348
- Example 4: Order date is after January 1, 2023
12374
+ Example 4: Order date is after January 1, 2023 (UTC). Compare dates as `epochtime`
12375
+ against epoch milliseconds: a `string` comparison of ISO timestamps orders values with
12376
+ different UTC offsets wrongly.
12349
12377
  ```json
12350
12378
  [
12351
12379
  "greaterthan",
12352
12380
  [
12353
- "extract",
12354
- "orderDate"
12355
- ],
12356
- "2023-01-01T00:00:00Z"
12357
- ]
12358
- ```
12359
-
12360
- Example 5: Category contains any of ["Urgent", "High Priority"]
12361
- ```json
12362
- [
12363
- "anyof",
12364
- [
12365
- "extract",
12366
- "category"
12381
+ "epochtime",
12382
+ [
12383
+ "extract",
12384
+ "orderDate"
12385
+ ]
12367
12386
  ],
12368
- ["Urgent", "High Priority"]
12387
+ 1672531200000
12369
12388
  ]
12370
12389
  ```
12390
+ x-celigo-ai-guidance:
12391
+ - |-
12392
+ To test whether a field has a value, use `notempty` on the wrapped extract, not a
12393
+ `matches` pattern: a record without the field matches `.*\S.*`.
12371
12394
  items:
12372
12395
  oneOf:
12373
12396
  - title: String
@@ -12558,14 +12581,15 @@ components:
12558
12581
  - `objectarray`: Array of objects (most common array type)
12559
12582
  - `arrayarray`: Array of arrays (for matrix/table structures)
12560
12583
 
12561
- Array dataTypes can be populated two ways: pass a source array through
12562
- unchanged via `extract` alone (when the source is already an array of
12563
- the right shape), or construct/iterate via `buildArrayHelper`.
12584
+ Array dataTypes can be populated three ways: pass a source array
12585
+ through unchanged via a JSONPath `extract` alone (when the source is
12586
+ already an array of the right shape), construct/iterate via
12587
+ `buildArrayHelper`, or set a constant with `hardCodedValue`.
12564
12588
 
12565
12589
  IMPORTANT: The dataType controls which additional fields are relevant:
12566
12590
  - For date-like string fields: extractDateFormat, generateDateFormat, etc. become relevant
12567
12591
  - For object types: 'mappings' array becomes relevant
12568
- - For array types: `buildArrayHelper` is one option (see above)
12592
+ - For array types: a JSONPath `extract` alone, `buildArrayHelper`, or `hardCodedValue` (see above)
12569
12593
 
12570
12594
  When analyzing existing mappings or generating new ones, always check dataType first
12571
12595
  to understand what additional fields should be present.
@@ -12628,9 +12652,12 @@ components:
12628
12652
  - Access input record fields with {{record.fieldName}} notation; a grouped
12629
12653
  (array) record binds as `rows` instead — {{rows.0.fieldName}} / {{#each rows}}
12630
12654
  - Examples: "{{record.firstName}} {{record.lastName}}", "{{#if record.isActive}}Active{{else}}Inactive{{/if}}"
12631
- - Valid on `object`, `objectarray`, and primitive-array dataTypes as
12632
- well as scalars — the rendered template output must parse into the
12633
- declared shape
12655
+ - Valid on scalars and on `object` rows, where the rendered output must
12656
+ parse into an object. On an array row the template goes in a
12657
+ `buildArrayHelper` entry instead: on an `objectarray` row's own
12658
+ `extract` it is refused with 422 ("buildArrayHelper" must be present
12659
+ for object array datatype), and on a primitive-array row's own
12660
+ `extract` it renders null without an error
12634
12661
 
12635
12662
  ```json
12636
12663
  "extract": "{{record.price}} {{record.currency}}" // Combines two fields
@@ -12829,6 +12856,19 @@ components:
12829
12856
  - countryCodeToName
12830
12857
  - statusMapping
12831
12858
  - departmentCodes
12859
+ hardCodedValue:
12860
+ type: string
12861
+ description: |
12862
+ Constant written to the destination instead of an extracted value. On a primitive
12863
+ array (`stringarray`, `numberarray`, `booleanarray`) the string is split on commas,
12864
+ verbatim and untrimmed, into elements of the array's type (`"A,B"` gives `["A", "B"]`).
12865
+ On an `object` it must be a JSON object string and on an `objectarray` a JSON array
12866
+ string (an object string becomes one element); the save parses it and refuses non-JSON
12867
+ or the wrong shape with 422, and an array row with a constant needs no `buildArrayHelper`.
12868
+ examples:
12869
+ - USD
12870
+ - A,B
12871
+ - '[{"code": "A"}, {"code": "B"}]'
12832
12872
  description:
12833
12873
  type: string
12834
12874
  description: |
@@ -12964,15 +13004,25 @@ components:
12964
13004
  processor renders the entire destination array as null with no
12965
13005
  validation error. To emit a fixed number of static elements, add
12966
13006
  that many sibling constructed entries — never index the extract.
13007
+ - |-
13008
+ An entry's `extract` can be a Handlebars template. On an
13009
+ `objectarray` it must render a JSON object (one element) or a JSON
13010
+ array (one element per item). On a primitive array each entry
13011
+ renders one element, so a serialized array becomes one string
13012
+ element. A bare literal entry extract is refused with 422 ("extract
13013
+ only supports json path or handlebars expression"); set a constant
13014
+ with the row's `hardCodedValue` instead.
12967
13015
  description: |
12968
13016
  **Purpose**
12969
13017
  Configures how to construct arrays in the output record, handling various array types and inputs.
12970
13018
 
12971
13019
  **Guidance**
12972
- This is the REQUIRED mechanism for ALL array data types:
13020
+ This is the mechanism for building array data types:
12973
13021
 
12974
13022
  **When to Use**
12975
- - REQUIRED when dataType ends with "array" (stringarray, objectarray, etc.)
13023
+ - REQUIRED when dataType ends with "array" (stringarray, objectarray, etc.), unless the
13024
+ row passes a source array through with a JSONPath `extract` alone or sets
13025
+ `hardCodedValue`
12976
13026
  - Each entry in this array contributes elements to the output array
12977
13027
  - Multiple entries allow combining data from different input arrays
12978
13028
 
@@ -13597,14 +13647,15 @@ components:
13597
13647
  - `objectarray`: Array of objects (most common array type)
13598
13648
  - `arrayarray`: Array of arrays (for matrix/table structures)
13599
13649
 
13600
- Array dataTypes can be populated two ways: pass a source array through
13601
- unchanged via `extract` alone (when the source is already an array of
13602
- the right shape), or construct/iterate via `buildArrayHelper`.
13650
+ Array dataTypes can be populated three ways: pass a source array
13651
+ through unchanged via a JSONPath `extract` alone (when the source is
13652
+ already an array of the right shape), construct/iterate via
13653
+ `buildArrayHelper`, or set a constant with `hardCodedValue`.
13603
13654
 
13604
13655
  IMPORTANT: The dataType controls which additional fields are relevant:
13605
13656
  - For date-like string fields: extractDateFormat, generateDateFormat, etc. become relevant
13606
13657
  - For object types: 'mappings' array becomes relevant
13607
- - For array types: `buildArrayHelper` is one option (see above)
13658
+ - For array types: a JSONPath `extract` alone, `buildArrayHelper`, or `hardCodedValue` (see above)
13608
13659
 
13609
13660
  When analyzing existing mappings or generating new ones, always check dataType first
13610
13661
  to understand what additional fields should be present.
@@ -13667,9 +13718,12 @@ components:
13667
13718
  - Access input record fields with {{record.fieldName}} notation; a grouped
13668
13719
  (array) record binds as `rows` instead — {{rows.0.fieldName}} / {{#each rows}}
13669
13720
  - Examples: "{{record.firstName}} {{record.lastName}}", "{{#if record.isActive}}Active{{else}}Inactive{{/if}}"
13670
- - Valid on `object`, `objectarray`, and primitive-array dataTypes as
13671
- well as scalars — the rendered template output must parse into the
13672
- declared shape
13721
+ - Valid on scalars and on `object` rows, where the rendered output must
13722
+ parse into an object. On an array row the template goes in a
13723
+ `buildArrayHelper` entry instead: on an `objectarray` row's own
13724
+ `extract` it is refused with 422 ("buildArrayHelper" must be present
13725
+ for object array datatype), and on a primitive-array row's own
13726
+ `extract` it renders null without an error
13673
13727
 
13674
13728
  ```json
13675
13729
  "extract": "{{record.price}} {{record.currency}}" // Combines two fields
@@ -13868,6 +13922,19 @@ components:
13868
13922
  - countryCodeToName
13869
13923
  - statusMapping
13870
13924
  - departmentCodes
13925
+ hardCodedValue:
13926
+ type: string
13927
+ description: |
13928
+ Constant written to the destination instead of an extracted value. On a primitive
13929
+ array (`stringarray`, `numberarray`, `booleanarray`) the string is split on commas,
13930
+ verbatim and untrimmed, into elements of the array's type (`"A,B"` gives `["A", "B"]`).
13931
+ On an `object` it must be a JSON object string and on an `objectarray` a JSON array
13932
+ string (an object string becomes one element); the save parses it and refuses non-JSON
13933
+ or the wrong shape with 422, and an array row with a constant needs no `buildArrayHelper`.
13934
+ examples:
13935
+ - USD
13936
+ - A,B
13937
+ - '[{"code": "A"}, {"code": "B"}]'
13871
13938
  description:
13872
13939
  type: string
13873
13940
  description: |
@@ -14003,15 +14070,25 @@ components:
14003
14070
  processor renders the entire destination array as null with no
14004
14071
  validation error. To emit a fixed number of static elements, add
14005
14072
  that many sibling constructed entries — never index the extract.
14073
+ - |-
14074
+ An entry's `extract` can be a Handlebars template. On an
14075
+ `objectarray` it must render a JSON object (one element) or a JSON
14076
+ array (one element per item). On a primitive array each entry
14077
+ renders one element, so a serialized array becomes one string
14078
+ element. A bare literal entry extract is refused with 422 ("extract
14079
+ only supports json path or handlebars expression"); set a constant
14080
+ with the row's `hardCodedValue` instead.
14006
14081
  description: |
14007
14082
  **Purpose**
14008
14083
  Configures how to construct arrays in the output record, handling various array types and inputs.
14009
14084
 
14010
14085
  **Guidance**
14011
- This is the REQUIRED mechanism for ALL array data types:
14086
+ This is the mechanism for building array data types:
14012
14087
 
14013
14088
  **When to Use**
14014
- - REQUIRED when dataType ends with "array" (stringarray, objectarray, etc.)
14089
+ - REQUIRED when dataType ends with "array" (stringarray, objectarray, etc.), unless the
14090
+ row passes a source array through with a JSONPath `extract` alone or sets
14091
+ `hardCodedValue`
14015
14092
  - Each entry in this array contributes elements to the output array
14016
14093
  - Multiple entries allow combining data from different input arrays
14017
14094
 
@@ -14773,7 +14850,7 @@ components:
14773
14850
  - envelope
14774
14851
  x-enumDescriptions:
14775
14852
  record: The transform processor evaluates `mappings[].extract` JSONPath against the flat record itself (`$.field`, no `record.` segment) — the default when absent.
14776
- envelope: The transform processor evaluates JSONPath against the wrapped runtime envelope `{record, settings, job, …}` (file-provider steps also carry `fileMeta`) — extracts must include the `record.` segment (`$.record.field`).
14853
+ envelope: The transform processor evaluates JSONPath against the wrapped runtime envelope `{record, job, testMode, settings, headers, queryParams}` (file-provider steps also carry `fileMeta`) — record fields need the `record.` segment (`$.record.field`), while `headers` and `queryParams` sit beside `record` (`$.headers['X-Id']`, `$.queryParams.src`).
14777
14854
  description: |
14778
14855
  Controls the JSON shape the transformTwoDotZero processor
14779
14856
  evaluates `mappings[].extract` JSONPath values against at
@@ -14793,10 +14870,12 @@ components:
14793
14870
  `"$.PLACEHOLDER_<field>"`.
14794
14871
  This is the dominant Celigo idiom and the right choice for new transforms.
14795
14872
  - `envelope`: the processor sees a wrapped object
14796
- `{record: {...}, settings: ..., job: ...}` (plus
14797
- `fileMeta` on file-provider steps).
14873
+ `{record: {...}, job, testMode, settings, headers,
14874
+ queryParams}` (plus `fileMeta` on file-provider steps).
14798
14875
  `mappings[].extract` JSONPath MUST include the
14799
- `record.` segment — e.g. `"$.record.orderId"`;
14876
+ `record.` segment for record fields — e.g.
14877
+ `"$.record.orderId"` — and reads `headers` and
14878
+ `queryParams` beside it (`$.headers['X-Id']`);
14800
14879
  PLACEHOLDER extracts use `"$.record.PLACEHOLDER_<field>"`.
14801
14880
  Pick this only when the transform was authored against
14802
14881
  the envelope shape on purpose.
@@ -14805,6 +14884,11 @@ components:
14805
14884
  (`{{record.field}}`, `{{dateFormat ... record.field}}`)
14806
14885
  ALWAYS reference the `record` root regardless of
14807
14886
  `inputContext` — only JSONPath anchoring flips.
14887
+ - |-
14888
+ In `envelope` mode a `modify` transform merges its mapped
14889
+ fields into `record` and keeps the rest of the envelope
14890
+ around it; a `create` transform returns only the mapped
14891
+ fields, as a bare record.
14808
14892
  - |-
14809
14893
  Emit `inputContext` explicitly on new v2 transforms:
14810
14894
  unset is read as `record`, but stating it makes the
@@ -14825,13 +14909,17 @@ components:
14825
14909
 
14826
14910
  - ``envelope``: the transform processor sees a wrapped
14827
14911
  object of the shape
14828
- ``{record: {...}, settings: ..., job: ...}`` (plus
14829
- ``fileMeta`` on file-provider steps) — the
14912
+ ``{record: {...}, job, testMode, settings, headers,
14913
+ queryParams}`` (plus ``fileMeta`` on file-provider
14914
+ steps; ``headers`` and ``queryParams`` sit beside
14915
+ ``record``) — the
14830
14916
  same runtime-context envelope Handlebars / SQL /
14831
14917
  GraphQL templates render against. ``mappings[].extract``
14832
- JSONPath values MUST include the ``record.`` segment
14833
- — for example ``"$.record.orderId"`` or
14834
- ``"$.record.customer.email"``. PLACEHOLDER extracts
14918
+ JSONPath values for record fields MUST include the
14919
+ ``record.`` segment — for example ``"$.record.orderId"``
14920
+ or ``"$.record.customer.email"`` — while ``headers`` and
14921
+ ``queryParams`` are read beside it
14922
+ (``"$.headers['X-Id']"``). PLACEHOLDER extracts
14835
14923
  use ``"$.record.PLACEHOLDER_<field>"``. Pick this
14836
14924
  mode only when the export was authored against the
14837
14925
  envelope shape on purpose (typically because an