@celigo/api-specs 0.2.214 → 0.2.215

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/flow.yml CHANGED
@@ -2153,12 +2153,14 @@ paths:
2153
2153
 
2154
2154
  The `data` field is the record as the failing stage held it: for an import-stage error
2155
2155
  (`page_processor_import`) on an HTTP import, the record before the import's mappings, not the
2156
- request the import sent; for a postResponseMap hook's error (`post_response_mapping`), the record
2156
+ request the import sent; for a lookup's error (`page_processor_export`), the record as it reached
2157
+ the lookup; for a postResponseMap hook's error (`post_response_mapping`), the record
2157
2158
  after the step's response mapping. Use `PUT .../{retryDataKey}/data` to mutate
2158
2159
  the snapshot before retrying. Only errors with a `retryDataKey` expose this endpoint;
2159
2160
  connection-class errors are rejected with `no_retrydata_found`. The `stage` field indicates
2160
2161
  where the retry will resume: `page_processor_import` re-runs the import (most common, and where a
2161
- postSubmit hook's errors are stored, so their retry writes the records again),
2162
+ postSubmit hook's errors are stored — a retry writes again a record the destination accepted,
2163
+ and resends one whose refusal the hook reworded), `page_processor_export` re-runs the lookup,
2162
2164
  `post_response_mapping` (a postResponseMap hook's error) resumes after the import from the stored
2163
2165
  reply in `adaptorResponse`, sending nothing to the destination again and carrying the record on
2164
2166
  to the flow's next steps, and `page_generator` means the error was upstream of the processor.
@@ -4342,6 +4344,10 @@ paths:
4342
4344
 
4343
4345
  An empty object `{}` means no other resources depend on the target — this is also returned for a
4344
4346
  well-formatted but nonexistent id.
4347
+
4348
+ A `flows` entry whose `paths` holds `_runNextFlowIds` is an upstream flow: its own
4349
+ `_runNextFlowIds` lists this flow, so this flow starts when a run of that one completes. The
4350
+ flows this flow starts are in its own `_runNextFlowIds`, not in this response.
4345
4351
  parameters:
4346
4352
  - name: _id
4347
4353
  in: path
@@ -4364,7 +4370,7 @@ paths:
4364
4370
  summary: No dependents (also returned for a nonexistent id)
4365
4371
  value: {}
4366
4372
  populated:
4367
- summary: Another flow is configured to run after this one
4373
+ summary: Another flow starts this one when its run completes
4368
4374
  value:
4369
4375
  flows:
4370
4376
  - id: 69f4b2cb95ec28be9ca1a88d
@@ -5847,9 +5853,11 @@ components:
5847
5853
  - string
5848
5854
  - 'null'
5849
5855
  description: |-
5850
- IANA timezone for the schedule (e.g. `America/New_York`). Defaults to UTC. The flow's
5851
- `schedule` and each page generator's own `schedule` are read in this timezone; a page
5852
- generator has no timezone of its own.
5856
+ IANA timezone for the schedule (e.g. `America/New_York`). The flow's `schedule` and each
5857
+ page generator's own `schedule` are read in this timezone; a page generator has no
5858
+ timezone of its own. A flow saved without one stores none, and its schedule then runs in
5859
+ UTC when the account owner's profile has no time zone; per the Help Center's time zone
5860
+ precedence, it runs in the owner's profile time zone when the profile sets one.
5853
5861
  examples:
5854
5862
  - America/New_York
5855
5863
  - Europe/London
@@ -6935,8 +6943,10 @@ components:
6935
6943
  `application` covers the step's whole call to the external system, not only its answer:
6936
6944
  besides errors the destination returned, it marks a request that never got an answer,
6937
6945
  such as a URL template that failed to render (`handlebars_template_parse_error`) or a
6938
- refused connection, so read `code` and `message` with it. `GET /v1/errors/filterMetadata`
6939
- lists the source values the errors filter accepts.
6946
+ refused connection, so read `code` and `message` with it. `post_submit_hook` marks an error
6947
+ a postSubmit hook added or reworded — a destination refusal included — while one the hook
6948
+ passes along unchanged keeps `application`, so it does not mean the destination accepted the
6949
+ record. `GET /v1/errors/filterMetadata` lists the source values the errors filter accepts.
6940
6950
  examples:
6941
6951
  - application
6942
6952
  code:
@@ -7831,7 +7841,8 @@ components:
7831
7841
  (an import's errors, a postSubmit hook's included) it is the incoming record, before the
7832
7842
  import's mappings — not the request body the import sent or the response it got back — and a
7833
7843
  retry maps it again with the import's current mappings, so a mapping fix reaches the retried
7834
- record. At `post_response_mapping` (a postResponseMap hook's error) it is the record after the
7844
+ record. At `page_processor_export` (a lookup's errors) it is the record as it reached the
7845
+ lookup. At `post_response_mapping` (a postResponseMap hook's error) it is the record after the
7835
7846
  step's response mapping, with the mapped fields: a retry neither maps nor sends it again, and
7836
7847
  the destination's reply is in `adaptorResponse`. Shape varies by adaptor.
7837
7848
  additionalProperties: true
@@ -7840,14 +7851,25 @@ components:
7840
7851
  description: |-
7841
7852
  Pipeline stage where the record was when the error occurred, which is where a retry resumes.
7842
7853
  `page_processor_import` is the record as it entered the import, so a retry sends it to the
7843
- destination again; a postSubmit hook's errors are stored here, so retrying them writes records
7844
- the destination already accepted a second time (live, 2026-10-22). `post_response_mapping` is a
7845
- postResponseMap hook's error, raised after the destination answered: a retry runs the hook from
7846
- the stored reply and carries the record on to the flow's next steps, sending nothing to that
7847
- destination again (live, 2026-10-23 and 2026-10-25: the import's request count didn't change,
7848
- and the next import received the retried records).
7854
+ destination again. A postSubmit hook's errors are stored here whether the destination accepted
7855
+ the record or refused it and the hook reworded the refusal (live, 2026-10-30), so neither the
7856
+ stage nor the error's `post_submit_hook` source says whether the record was written: retrying
7857
+ an error the hook raised after the destination accepted the record writes it a second time
7858
+ (live, 2026-10-22), while a reworded refusal is a record the destination did not take.
7859
+ `page_processor_export` is a lookup's error: a retry runs the lookup again as it is configured
7860
+ now (live, 2026-10-30: after the lookup's template was fixed, the retried records succeeded).
7861
+ `post_response_mapping` is a postResponseMap hook's error, raised after the destination
7862
+ answered: a retry runs the hook from the stored reply and carries the record on to the flow's
7863
+ next steps, sending nothing to that destination again (live, 2026-10-23 and 2026-10-25: the
7864
+ import's request count didn't change, and the next import received the retried records).
7865
+ x-celigo-ai-guidance:
7866
+ - |-
7867
+ Before retrying `post_submit_hook` errors, find out whether the destination took each
7868
+ record — the hook's message, or a lookup of the record in the destination — and retry the
7869
+ refusals. A hook error on a record the destination accepted is written again by the retry.
7849
7870
  examples:
7850
7871
  - page_processor_import
7872
+ - page_processor_export
7851
7873
  - post_response_mapping
7852
7874
  - importMappingExtract
7853
7875
  pgExportId:
package/dist/import.yml CHANGED
@@ -15442,12 +15442,16 @@ components:
15442
15442
  - |-
15443
15443
  On a grouped record (the export groups rows, so the record is an
15444
15444
  array) only `create` can author output — build it from the rows with
15445
- `$[0].field`, `$[*].field`, or a `buildArrayHelper` over `$[*]`.
15445
+ `$[0].field`, `$[*].field`, or a `buildArrayHelper` over `$[*]`
15446
+ (`$.rows[0].field` and `$.rows[*]` with `inputContext: envelope`).
15446
15447
  `modify` has no object to overlay onto an array: the record passes
15447
- through untouched and the processor reports success. Either mode
15448
- reshapes the inside of one record; neither changes how many records
15449
- the page carries (that is the export's `preSavePage` hook) or whether
15450
- the export groups at all (that is its grouping setting).
15448
+ through untouched and the processor reports success. Paths written
15449
+ for one object record (`$.field`, an entry `$.lines[*]`) resolve
15450
+ nothing there, so `create` returns `{}` for each record, also with
15451
+ no error (live, 2026-10-30). Either mode reshapes the inside of one
15452
+ record; neither changes how many records the page carries (that is
15453
+ the export's `preSavePage` hook) or whether the export groups at all
15454
+ (that is its grouping setting).
15451
15455
  examples:
15452
15456
  - create
15453
15457
  - modify
@@ -15512,8 +15516,8 @@ components:
15512
15516
  - record
15513
15517
  - envelope
15514
15518
  x-enumDescriptions:
15515
- record: The transform processor evaluates `mappings[].extract` JSONPath against the flat record itself (`$.field`, no `record.` segment) — the default when absent.
15516
- 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`).
15519
+ record: The transform processor evaluates `mappings[].extract` JSONPath against the flat record itself (`$.field`, no `record.` segment; a grouped record is the array of rows, `$[0].field`) — the default when absent.
15520
+ 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`), and a grouped record sits under `rows` instead (`$.rows[0].field`), while `headers` and `queryParams` sit beside `record` (`$.headers['X-Id']`, `$.queryParams.src`).
15517
15521
  description: |
15518
15522
  Controls the JSON shape the transformTwoDotZero processor
15519
15523
  evaluates `mappings[].extract` JSONPath values against at
@@ -15529,24 +15533,38 @@ components:
15529
15533
  processor sees the FLAT record as its evaluation root.
15530
15534
  `mappings[].extract` JSONPath MUST anchor directly at
15531
15535
  `$` with NO `record.` segment — e.g. `"$.orderId"`,
15532
- `"$.customer.email"`; PLACEHOLDER extracts use
15536
+ `"$.customer.email"` on an object record, `"$[0].orderId"`
15537
+ on a grouped one; PLACEHOLDER extracts use
15533
15538
  `"$.PLACEHOLDER_<field>"`.
15534
15539
  This is the dominant Celigo idiom and the right choice for new transforms.
15535
15540
  - `envelope`: the processor sees a wrapped object
15536
15541
  `{record: {...}, job, testMode, settings, headers,
15537
15542
  queryParams}` (plus `fileMeta` on file-provider steps).
15538
15543
  `mappings[].extract` JSONPath MUST include the
15539
- `record.` segment for record fields — e.g.
15540
- `"$.record.orderId"` — and reads `headers` and
15544
+ `record.` segment for an object record's fields — e.g.
15545
+ `"$.record.orderId"`; a grouped record sits under `rows`
15546
+ instead (`"$.rows[0].orderId"`) — and reads `headers` and
15541
15547
  `queryParams` beside it (`$.headers['X-Id']`);
15542
15548
  PLACEHOLDER extracts use `"$.record.PLACEHOLDER_<field>"`.
15543
15549
  Pick this only when the transform was authored against
15544
15550
  the envelope shape on purpose.
15545
15551
  - |-
15546
- Handlebars expressions inside `extract`
15547
- (`{{record.field}}`, `{{dateFormat ... record.field}}`)
15548
- ALWAYS reference the `record` root regardless of
15552
+ Handlebars expressions inside `extract` reference the
15553
+ `record` root on an object record (`{{record.field}}`,
15554
+ `{{dateFormat ... record.field}}`) and `rows` on a
15555
+ grouped one (`{{rows.0.field}}`), regardless of
15549
15556
  `inputContext` — only JSONPath anchoring flips.
15557
+ - |-
15558
+ ## Grouped records
15559
+
15560
+ When the export groups rows, each record is an array of
15561
+ rows. In `record` mode JSONPath roots at that array
15562
+ (`$[0].field`, `$[*]`); `envelope` binds it as `rows`,
15563
+ not `record` — `$.rows[0].field`, and an entry
15564
+ `$.rows[*]` whose children read `$.rows.field` — while
15565
+ `$.record[0].field` and `$.record[*]` resolve nothing,
15566
+ with no error (live, 2026-10-30). Handlebars extracts
15567
+ read it as `rows` in both modes (`{{rows.0.field}}`).
15550
15568
  - |-
15551
15569
  In `envelope` mode the output is still a bare record: a
15552
15570
  `modify` transform returns the record with its mapped
@@ -15567,7 +15585,8 @@ components:
15567
15585
  ``mappings[].extract`` JSONPath values MUST anchor
15568
15586
  directly at ``$`` with NO ``record.`` segment — for
15569
15587
  example ``"$.orderId"`` or
15570
- ``"$.customer.email"``. PLACEHOLDER extracts use
15588
+ ``"$.customer.email"`` on an object record, and
15589
+ ``"$[0].orderId"`` on a grouped one. PLACEHOLDER extracts use
15571
15590
  ``"$.PLACEHOLDER_<field>"``. This is the dominant
15572
15591
  Celigo idiom and the right choice for new transforms.
15573
15592
 
@@ -15579,9 +15598,10 @@ components:
15579
15598
  ``record``) — the
15580
15599
  same runtime-context envelope Handlebars / SQL /
15581
15600
  GraphQL templates render against. ``mappings[].extract``
15582
- JSONPath values for record fields MUST include the
15601
+ JSONPath values for an object record's fields MUST include the
15583
15602
  ``record.`` segment — for example ``"$.record.orderId"``
15584
- or ``"$.record.customer.email"`` — while ``headers`` and
15603
+ or ``"$.record.customer.email"``; a grouped record's rows
15604
+ sit under ``rows`` instead (``"$.rows[0].orderId"``) — while ``headers`` and
15585
15605
  ``queryParams`` are read beside it
15586
15606
  (``"$.headers['X-Id']"``). PLACEHOLDER extracts
15587
15607
  use ``"$.record.PLACEHOLDER_<field>"``. Pick this
@@ -15594,8 +15614,9 @@ components:
15594
15614
 
15595
15615
  Handlebars expressions inside ``extract``
15596
15616
  (``{{record.field}}``,
15597
- ``{{dateFormat ... record.field}}``, etc.) ALWAYS
15598
- reference the runtime context's ``record`` root
15617
+ ``{{dateFormat ... record.field}}``, etc.) reference the
15618
+ runtime context's ``record`` root on an object record,
15619
+ and ``rows`` (``{{rows.0.field}}``) on a grouped one,
15599
15620
  regardless of ``inputContext`` — the Handlebars runtime
15600
15621
  always sees the wrapped envelope. Only JSONPath
15601
15622
  behavior flips with this field.
@@ -1179,8 +1179,10 @@ paths:
1179
1179
  `http.relativeURI`; triple braces insert it unchanged. A `timestamp` with no time zone
1180
1180
  renders in UTC.
1181
1181
 
1182
- A null value, or a field under an object that is null, renders empty here. An HTTP import
1183
- escapes values its own way, at run time and in the import preview: in its JSON body a
1182
+ By default a null value, a field under an object that is null, and a path the data doesn't
1183
+ carry all render empty here. With `rules.strict` true, a path the data doesn't carry or one
1184
+ through a null object fails with 422, while a null or empty value still renders empty. An
1185
+ HTTP import escapes values its own way, at run time and in the import preview: in its JSON body a
1184
1186
  double-brace value that is null, or under a null object, is written as the text `null`
1185
1187
  (triple braces rendered `{{{record.customer.name}}}` empty, whether `customer` or its `name`
1186
1188
  was null); in its relative URI a null field is sent as the text
@@ -1221,6 +1223,21 @@ paths:
1221
1223
  description: Form of the result; `text` returns the rendered string.
1222
1224
  examples:
1223
1225
  - text
1226
+ strict:
1227
+ type: boolean
1228
+ default: false
1229
+ description: |-
1230
+ When true, a path the data doesn't carry, or one through a missing or null
1231
+ object, fails the render with 422 instead of rendering empty: `"poNumber" not
1232
+ defined in the model`, or `not defined in undefined` / `not defined in null`
1233
+ when the object above it is missing or null — the detail a step's
1234
+ `handlebars_template_parse_error` carries. A null or empty value still renders
1235
+ empty.
1236
+ x-celigo-ai-guidance:
1237
+ - |-
1238
+ Render with `strict: true` to check a template's paths against a sample
1239
+ record: by default a misspelled or wrongly rooted path (`{{record.poNumber}}`
1240
+ on a record that carries `po_number`) renders empty with 200.
1224
1241
  options:
1225
1242
  type: object
1226
1243
  description: |-
@@ -1292,6 +1309,16 @@ paths:
1292
1309
  data:
1293
1310
  record:
1294
1311
  name: Smith & Sons
1312
+ strict:
1313
+ summary: Fail on a path the record doesn't carry
1314
+ value:
1315
+ rules:
1316
+ template: '{{record.poNumber}}'
1317
+ resultMode: text
1318
+ strict: true
1319
+ data:
1320
+ record:
1321
+ po_number: '10482'
1295
1322
  static_lookup:
1296
1323
  summary: Resolve an HTTP import's static lookup
1297
1324
  value:
@@ -1352,7 +1379,8 @@ paths:
1352
1379
  '422':
1353
1380
  description: |-
1354
1381
  The template could not be rendered, for example because it calls a helper that does not
1355
- exist ('Missing helper: "first"').
1382
+ exist ('Missing helper: "first"') or, with `rules.strict`, reads a path the data doesn't
1383
+ carry ('"poNumber" not defined in the model').
1356
1384
  content:
1357
1385
  application/json:
1358
1386
  schema:
@@ -518,7 +518,8 @@ components:
518
518
  description: |-
519
519
  Base number of endpoints (distinct connected applications) included with the plan, per
520
520
  environment. Whether the count is taken from endpoints in use or from endpoints invoked
521
- in the billing period depends on the account's pricing model.
521
+ in the billing period depends on the account's pricing model, which the license's `type`
522
+ names.
522
523
  example: 600
523
524
  numAddOnEndpoints:
524
525
  type: integer
@@ -529,7 +530,7 @@ components:
529
530
  description: |-
530
531
  Base flow entitlement included with the plan, per environment. Whether it caps enabled
531
532
  flows or the distinct flows run in a billing period — and whether reaching it blocks or
532
- only notifies — depends on the account's pricing model.
533
+ only notifies — depends on the account's pricing model, which the license's `type` names.
533
534
  example: 80
534
535
  numAddOnFlows:
535
536
  type: integer
@@ -581,9 +582,14 @@ components:
581
582
  the number of environments, prepaid AI balances, and the other non-resource fields —
582
583
  belong to the parent license and are not repeated per environment.
583
584
  - |-
584
- What a flow or endpoint entitlement METERS depends on the account's pricing model
585
- (`type` plus tier generation). Interpret the counts for the plan this account is on
586
- only; do not infer the rule from field names.
585
+ No field names what a flow or endpoint entitlement METERS; the account-level license's
586
+ `type` tells it. A `platform` license meters runs: on `GET /v1/licenseEntitlementUsage`,
587
+ `flowUsage.numEnabled` counts the distinct flows that ran in the billing period and
588
+ `endpointUsage.numConsumed` the endpoints they used, and `GET /v1/historicalMonthlyUsage`
589
+ returns its monthly rows. An `endpoint` license meters enabled resources: its endpoints are
590
+ counted across enabled flows. Neither `endpoint` nor `integrator` licenses store monthly
591
+ usage (that route fails with 500 for them). Interpret the counts for the plan this account
592
+ is on only; do not infer the rule from field names such as `numEnabled`.
587
593
  properties:
588
594
  _id:
589
595
  type: string
@@ -632,8 +638,8 @@ components:
632
638
  - integrationAppChild
633
639
  x-enumDescriptions:
634
640
  integrator: Account-level subscription (legacy integrator pricing model).
635
- platform: Account-level subscription (platform pricing model; the tier name carries the plan generation).
636
- endpoint: Account-level subscription (endpoint pricing model, metered on distinct endpoints).
641
+ platform: Account-level subscription (platform pricing model, metered on flow runs in the billing period; the tier name carries the plan generation).
642
+ endpoint: Account-level subscription (endpoint pricing model, metered on the distinct endpoints enabled flows use).
637
643
  connector: Connector-specific license for an Integration App.
638
644
  integrationApp: Integration App license (parent).
639
645
  integrationAppChild: Integration App child license (inherits from a parent via `_parentId`).
package/dist/tool.yml CHANGED
@@ -6276,12 +6276,16 @@ components:
6276
6276
  - |-
6277
6277
  On a grouped record (the export groups rows, so the record is an
6278
6278
  array) only `create` can author output — build it from the rows with
6279
- `$[0].field`, `$[*].field`, or a `buildArrayHelper` over `$[*]`.
6279
+ `$[0].field`, `$[*].field`, or a `buildArrayHelper` over `$[*]`
6280
+ (`$.rows[0].field` and `$.rows[*]` with `inputContext: envelope`).
6280
6281
  `modify` has no object to overlay onto an array: the record passes
6281
- through untouched and the processor reports success. Either mode
6282
- reshapes the inside of one record; neither changes how many records
6283
- the page carries (that is the export's `preSavePage` hook) or whether
6284
- the export groups at all (that is its grouping setting).
6282
+ through untouched and the processor reports success. Paths written
6283
+ for one object record (`$.field`, an entry `$.lines[*]`) resolve
6284
+ nothing there, so `create` returns `{}` for each record, also with
6285
+ no error (live, 2026-10-30). Either mode reshapes the inside of one
6286
+ record; neither changes how many records the page carries (that is
6287
+ the export's `preSavePage` hook) or whether the export groups at all
6288
+ (that is its grouping setting).
6285
6289
  examples:
6286
6290
  - create
6287
6291
  - modify
@@ -6346,8 +6350,8 @@ components:
6346
6350
  - record
6347
6351
  - envelope
6348
6352
  x-enumDescriptions:
6349
- record: The transform processor evaluates `mappings[].extract` JSONPath against the flat record itself (`$.field`, no `record.` segment) — the default when absent.
6350
- 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`).
6353
+ record: The transform processor evaluates `mappings[].extract` JSONPath against the flat record itself (`$.field`, no `record.` segment; a grouped record is the array of rows, `$[0].field`) — the default when absent.
6354
+ 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`), and a grouped record sits under `rows` instead (`$.rows[0].field`), while `headers` and `queryParams` sit beside `record` (`$.headers['X-Id']`, `$.queryParams.src`).
6351
6355
  description: |
6352
6356
  Controls the JSON shape the transformTwoDotZero processor
6353
6357
  evaluates `mappings[].extract` JSONPath values against at
@@ -6363,24 +6367,38 @@ components:
6363
6367
  processor sees the FLAT record as its evaluation root.
6364
6368
  `mappings[].extract` JSONPath MUST anchor directly at
6365
6369
  `$` with NO `record.` segment — e.g. `"$.orderId"`,
6366
- `"$.customer.email"`; PLACEHOLDER extracts use
6370
+ `"$.customer.email"` on an object record, `"$[0].orderId"`
6371
+ on a grouped one; PLACEHOLDER extracts use
6367
6372
  `"$.PLACEHOLDER_<field>"`.
6368
6373
  This is the dominant Celigo idiom and the right choice for new transforms.
6369
6374
  - `envelope`: the processor sees a wrapped object
6370
6375
  `{record: {...}, job, testMode, settings, headers,
6371
6376
  queryParams}` (plus `fileMeta` on file-provider steps).
6372
6377
  `mappings[].extract` JSONPath MUST include the
6373
- `record.` segment for record fields — e.g.
6374
- `"$.record.orderId"` — and reads `headers` and
6378
+ `record.` segment for an object record's fields — e.g.
6379
+ `"$.record.orderId"`; a grouped record sits under `rows`
6380
+ instead (`"$.rows[0].orderId"`) — and reads `headers` and
6375
6381
  `queryParams` beside it (`$.headers['X-Id']`);
6376
6382
  PLACEHOLDER extracts use `"$.record.PLACEHOLDER_<field>"`.
6377
6383
  Pick this only when the transform was authored against
6378
6384
  the envelope shape on purpose.
6379
6385
  - |-
6380
- Handlebars expressions inside `extract`
6381
- (`{{record.field}}`, `{{dateFormat ... record.field}}`)
6382
- ALWAYS reference the `record` root regardless of
6386
+ Handlebars expressions inside `extract` reference the
6387
+ `record` root on an object record (`{{record.field}}`,
6388
+ `{{dateFormat ... record.field}}`) and `rows` on a
6389
+ grouped one (`{{rows.0.field}}`), regardless of
6383
6390
  `inputContext` — only JSONPath anchoring flips.
6391
+ - |-
6392
+ ## Grouped records
6393
+
6394
+ When the export groups rows, each record is an array of
6395
+ rows. In `record` mode JSONPath roots at that array
6396
+ (`$[0].field`, `$[*]`); `envelope` binds it as `rows`,
6397
+ not `record` — `$.rows[0].field`, and an entry
6398
+ `$.rows[*]` whose children read `$.rows.field` — while
6399
+ `$.record[0].field` and `$.record[*]` resolve nothing,
6400
+ with no error (live, 2026-10-30). Handlebars extracts
6401
+ read it as `rows` in both modes (`{{rows.0.field}}`).
6384
6402
  - |-
6385
6403
  In `envelope` mode the output is still a bare record: a
6386
6404
  `modify` transform returns the record with its mapped
@@ -6401,7 +6419,8 @@ components:
6401
6419
  ``mappings[].extract`` JSONPath values MUST anchor
6402
6420
  directly at ``$`` with NO ``record.`` segment — for
6403
6421
  example ``"$.orderId"`` or
6404
- ``"$.customer.email"``. PLACEHOLDER extracts use
6422
+ ``"$.customer.email"`` on an object record, and
6423
+ ``"$[0].orderId"`` on a grouped one. PLACEHOLDER extracts use
6405
6424
  ``"$.PLACEHOLDER_<field>"``. This is the dominant
6406
6425
  Celigo idiom and the right choice for new transforms.
6407
6426
 
@@ -6413,9 +6432,10 @@ components:
6413
6432
  ``record``) — the
6414
6433
  same runtime-context envelope Handlebars / SQL /
6415
6434
  GraphQL templates render against. ``mappings[].extract``
6416
- JSONPath values for record fields MUST include the
6435
+ JSONPath values for an object record's fields MUST include the
6417
6436
  ``record.`` segment — for example ``"$.record.orderId"``
6418
- or ``"$.record.customer.email"`` — while ``headers`` and
6437
+ or ``"$.record.customer.email"``; a grouped record's rows
6438
+ sit under ``rows`` instead (``"$.rows[0].orderId"``) — while ``headers`` and
6419
6439
  ``queryParams`` are read beside it
6420
6440
  (``"$.headers['X-Id']"``). PLACEHOLDER extracts
6421
6441
  use ``"$.record.PLACEHOLDER_<field>"``. Pick this
@@ -6428,8 +6448,9 @@ components:
6428
6448
 
6429
6449
  Handlebars expressions inside ``extract``
6430
6450
  (``{{record.field}}``,
6431
- ``{{dateFormat ... record.field}}``, etc.) ALWAYS
6432
- reference the runtime context's ``record`` root
6451
+ ``{{dateFormat ... record.field}}``, etc.) reference the
6452
+ runtime context's ``record`` root on an object record,
6453
+ and ``rows`` (``{{rows.0.field}}``) on a grouped one,
6433
6454
  regardless of ``inputContext`` — the Handlebars runtime
6434
6455
  always sees the wrapped envelope. Only JSONPath
6435
6456
  behavior flips with this field.
@@ -38512,8 +38533,8 @@ components:
38512
38533
  **Structure**
38513
38534
 
38514
38535
  The mock output must follow the integrator.io canonical format, which consists of a
38515
- `page_of_records` array containing record objects. Each record object has a `record`
38516
- property that contains the actual data fields.
38536
+ `page_of_records` array of items. On an export that does not group rows, each item has a
38537
+ `record` property that contains the actual data fields:
38517
38538
 
38518
38539
  ```json
38519
38540
  {
@@ -38530,6 +38551,19 @@ components:
38530
38551
  }
38531
38552
  ```
38532
38553
 
38554
+ An export that groups rows (`groupByFields`) produces records that are arrays of rows, and
38555
+ each item then carries `rows` instead of `record`, holding the rows of one grouped record. A
38556
+ flow test run saves a grouped export's records in this form:
38557
+
38558
+ ```json
38559
+ {
38560
+ "page_of_records": [
38561
+ { "rows": [ { "field1": "value1" }, { "field1": "value2" } ] },
38562
+ ...
38563
+ ]
38564
+ }
38565
+ ```
38566
+
38533
38567
  **Usage**
38534
38568
 
38535
38569
  In a flow test run, and for an upstream lookup during a page-processor preview
@@ -38562,7 +38596,8 @@ components:
38562
38596
 
38563
38597
  - Maximum of 10 records
38564
38598
  - Maximum size of 1 MB
38565
- - Must follow the canonical format shown above
38599
+ - Must follow one of the canonical formats shown above: every item `{"record": {...}}`, or
38600
+ on a grouped export every item `{"rows": [...]}`
38566
38601
 
38567
38602
  Mock output can be populated automatically from preview data (which is the parsed response,
38568
38603
  before `transform` / `filter`) or entered manually.
@@ -38604,6 +38639,22 @@ components:
38604
38639
  categories:
38605
38640
  - Electronics
38606
38641
  - Accessories
38642
+ rows:
38643
+ type: array
38644
+ description: |
38645
+ The rows of one grouped record, present instead of `record` when the export
38646
+ groups rows (`groupByFields`). Every item of a grouped export's mock carries
38647
+ `rows`.
38648
+ items:
38649
+ type: object
38650
+ additionalProperties: true
38651
+ example:
38652
+ - orderId: SO-1001
38653
+ sku: SKU-100
38654
+ quantity: 2
38655
+ - orderId: SO-1001
38656
+ sku: SKU-200
38657
+ quantity: 1
38607
38658
  example:
38608
38659
  page_of_records:
38609
38660
  - record:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@celigo/api-specs",
3
- "version": "0.2.214",
3
+ "version": "0.2.215",
4
4
  "private": false,
5
5
  "description": "Public OpenAPI bundles (dist/) and the celigo-cli lint schema pack (schemas.json).",
6
6
  "keywords": [