@celigo/api-specs 0.2.126 → 0.2.128

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/import.yml CHANGED
@@ -3841,7 +3841,11 @@ components:
3841
3841
  field mapped to `internalid` is overridden by it. When the incoming record
3842
3842
  already carries the NetSuite internal ID, point the lookup at that field with
3843
3843
  the expression form — `["internalid","is","{{{id}}}"]` — rather than removing
3844
- the lookup.
3844
+ the lookup. Only when every record carries it: on `restletVersion:
3845
+ suiteapp2.0` a record whose field is empty does not fall through to
3846
+ "create" on `addupdate` — the empty value is searched as `isempty` and
3847
+ can match an existing record (see `expression`; SuiteBundle and SuiteApp
3848
+ 1.0 create in that case).
3845
3849
  properties:
3846
3850
  extract:
3847
3851
  type: string
@@ -3967,6 +3971,21 @@ components:
3967
3971
  - DO NOT use `jsonSerialize` here — search expressions take
3968
3972
  scalar literals, not serialized JSON. Use `{{{id}}}` or
3969
3973
  `{{{[Field Name]}}}` directly.
3974
+ - |-
3975
+ ## A substitution that renders empty is not "no match"
3976
+
3977
+ When the source field is absent or empty, `["internalid","is","{{{id}}}"]`
3978
+ renders `["internalid","is",""]`, and the SuiteApp rewrites an empty
3979
+ `is` / `equalto` / `internalid anyof` value to `isempty` before the
3980
+ search. On `restletVersion: suiteapp2.0` that search is not treated as
3981
+ "no match": it can return existing records, and `addupdate` then
3982
+ updates one of them — an unrelated record receives the mapping (seen
3983
+ in production as `cant_modify_sub` on a customer the record never
3984
+ named). SuiteBundle and SuiteApp 1.0 discard a blank `internalid`
3985
+ match and create. Design so the operational lookup never renders
3986
+ empty: key it on a value every record carries (the source id stored
3987
+ as `externalid`), or route records without a destination id to a
3988
+ separate `add` import.
3970
3989
  - |-
3971
3990
  ## Body-level only
3972
3991
 
@@ -4229,6 +4248,22 @@ components:
4229
4248
  existing record: on an `add`-only operation every record fails with
4230
4249
  `The mapping condition:"record_updated" not supported for the
4231
4250
  operation`. It works on `addupdate` and `update`.
4251
+ - |-
4252
+ The condition is one of the fixed `when` values — there is no
4253
+ predicate over a source field ("when `customer.id` is not empty",
4254
+ "when `channel.name` is Point of Sale" cannot be written here).
4255
+ `extract_not_empty` is the only source-driven gate: on a lookup row
4256
+ it reads the row's `extract`, and when that is empty the row is
4257
+ skipped and the field is left unset — nothing substitutes a value.
4258
+ Value-dependent behaviour (a fallback record when the key is
4259
+ missing) belongs inside the lookup's `expression` (see
4260
+ `lookups[].expression`).
4261
+ - |-
4262
+ Two rows with the same `generate` are not a fallback pair: the
4263
+ last row for a destination decides it alone — when its condition
4264
+ skips it the field stays empty even if an earlier row produced a
4265
+ value, and when it applies it overwrites the earlier row's value
4266
+ (`ignore_if_set` reads the target record, not an earlier row).
4232
4267
  properties:
4233
4268
  lookupName:
4234
4269
  type: string
@@ -4484,6 +4519,18 @@ components:
4484
4519
  rows in live verification. Do not rely on that tolerance — use
4485
4520
  `when: record_updated` only on operations that can update
4486
4521
  records (`addupdate` / `update`).
4522
+ - |-
4523
+ The condition is one of the fixed `when` values — the same
4524
+ closed set as body rows, with no predicate over a source
4525
+ field; `extract_not_empty` skips the row on the lines whose
4526
+ extract is empty and leaves that line's field unset. Two
4527
+ sublist rows with the same `generate` are not a fallback
4528
+ pair either, and the order rule is not the body rows': among
4529
+ extract rows the last row decides each line alone (a skipped
4530
+ last row leaves the line's field unset even when an earlier
4531
+ row produced a value), while a hard-coded row's value lands
4532
+ on every line whatever its position — a later conditional
4533
+ extract row does not override it.
4487
4534
  properties:
4488
4535
  lookupName:
4489
4536
  type: string
@@ -4610,6 +4657,32 @@ components:
4610
4657
  shows what the expression produced for that line. With
4611
4658
  `allowFailures: true` the `default` value is used instead
4612
4659
  and no error is raised. Give every branch an output.
4660
+ - |-
4661
+ ## An empty substitution searches `isempty`
4662
+
4663
+ When the source path a criterion reads is null or absent
4664
+ (`["custentity_celigo_etail_cust_id","is","{{{customer.id}}}"]`
4665
+ on an order with no customer), the engine does not fail on
4666
+ the missing input: it searches the field with an `isempty`
4667
+ criterion, so the lookup now matches every target record
4668
+ whose field is BLANK. Two or more such records fail the
4669
+ record with `VALUE_LOOKUP_FAILED` — `More than one match
4670
+ for "[<field>,"isempty"]" for the record type "<recordType>"`
4671
+ (the message quotes the search field, never the empty
4672
+ source path); none fail it as `Could not find a match`;
4673
+ exactly one silently resolves to that record. Keep an empty
4674
+ key out of the search inside the expression — branch on
4675
+ the key: `{{#if customer.id}}[["custentity_celigo_etail_cust_id",
4676
+ "is","{{{customer.id}}}"]]{{else}}[["internalid","anyof",
4677
+ "<fallback internal id>"]]{{/if}}` routes records without a
4678
+ key to a fallback record while records with a key keep
4679
+ fail-on-miss; or render a value that can never match in the
4680
+ else branch and set `allowFailures: true` with `default`.
4681
+ A `searchField` / `operator` lookup (no `expression`) never
4682
+ reaches this state: an empty extract fails the record with
4683
+ `STATIC_MAPPING_ERROR` — `Exported value is empty/undefined
4684
+ for the field: $.<path>` — and resolves to `default` when
4685
+ `allowFailures` is true.
4613
4686
  - |-
4614
4687
  ## The mapping preview cannot evaluate `[*]` inside a block-helper argument
4615
4688
 
@@ -4643,19 +4716,34 @@ components:
4643
4716
  useDefaultOnMultipleMatches:
4644
4717
  type: boolean
4645
4718
  description: |-
4646
- Controls behaviour when the search matches more than one
4647
- record. When true, the `default` value is returned instead
4648
- of raising an ambiguous-match error. When false (default),
4649
- multiple matches are treated as a failure.
4719
+ When true and `allowFailures` is also true, a search that
4720
+ matches more than one record resolves to `default` instead
4721
+ of failing the record. Has no effect while `allowFailures`
4722
+ is false — an ambiguous match then fails the record whatever
4723
+ this flag says.
4724
+ x-celigo-ai-guidance:
4725
+ - |-
4726
+ Set it together with `allowFailures: true` whenever the
4727
+ search value can be empty or duplicated: with
4728
+ `allowFailures: true` alone an ambiguous match resolves to
4729
+ ONE of the matching records with no error, and with this
4730
+ flag alone the record still fails `More than one match`.
4731
+ Every ambiguous match then becomes `default`, a genuinely
4732
+ duplicated key included — when that must still fail, keep
4733
+ `allowFailures` false and handle the empty key in the
4734
+ `expression` instead (see `expression`).
4650
4735
  allowFailures:
4651
4736
  type:
4652
4737
  - boolean
4653
4738
  - 'null'
4654
4739
  description: |-
4655
4740
  When true, a lookup miss (no matching record and no
4656
- `default`) resolves to `null` and the import continues.
4657
- When false (default), a miss halts the record. May be
4658
- stored as null (treated as unset).
4741
+ `default`) resolves to `null` and the import continues, and
4742
+ a search matching more than one record resolves to one of
4743
+ them unless `useDefaultOnMultipleMatches` routes it to
4744
+ `default`. When false (default), a miss and an ambiguous
4745
+ match both halt the record. May be stored as null (treated
4746
+ as unset).
4659
4747
  map:
4660
4748
  type:
4661
4749
  - object
package/dist/tool.yml CHANGED
@@ -15422,7 +15422,11 @@ components:
15422
15422
  field mapped to `internalid` is overridden by it. When the incoming record
15423
15423
  already carries the NetSuite internal ID, point the lookup at that field with
15424
15424
  the expression form — `["internalid","is","{{{id}}}"]` — rather than removing
15425
- the lookup.
15425
+ the lookup. Only when every record carries it: on `restletVersion:
15426
+ suiteapp2.0` a record whose field is empty does not fall through to
15427
+ "create" on `addupdate` — the empty value is searched as `isempty` and
15428
+ can match an existing record (see `expression`; SuiteBundle and SuiteApp
15429
+ 1.0 create in that case).
15426
15430
  properties:
15427
15431
  extract:
15428
15432
  type: string
@@ -15548,6 +15552,21 @@ components:
15548
15552
  - DO NOT use `jsonSerialize` here — search expressions take
15549
15553
  scalar literals, not serialized JSON. Use `{{{id}}}` or
15550
15554
  `{{{[Field Name]}}}` directly.
15555
+ - |-
15556
+ ## A substitution that renders empty is not "no match"
15557
+
15558
+ When the source field is absent or empty, `["internalid","is","{{{id}}}"]`
15559
+ renders `["internalid","is",""]`, and the SuiteApp rewrites an empty
15560
+ `is` / `equalto` / `internalid anyof` value to `isempty` before the
15561
+ search. On `restletVersion: suiteapp2.0` that search is not treated as
15562
+ "no match": it can return existing records, and `addupdate` then
15563
+ updates one of them — an unrelated record receives the mapping (seen
15564
+ in production as `cant_modify_sub` on a customer the record never
15565
+ named). SuiteBundle and SuiteApp 1.0 discard a blank `internalid`
15566
+ match and create. Design so the operational lookup never renders
15567
+ empty: key it on a value every record carries (the source id stored
15568
+ as `externalid`), or route records without a destination id to a
15569
+ separate `add` import.
15551
15570
  - |-
15552
15571
  ## Body-level only
15553
15572
 
@@ -15810,6 +15829,22 @@ components:
15810
15829
  existing record: on an `add`-only operation every record fails with
15811
15830
  `The mapping condition:"record_updated" not supported for the
15812
15831
  operation`. It works on `addupdate` and `update`.
15832
+ - |-
15833
+ The condition is one of the fixed `when` values — there is no
15834
+ predicate over a source field ("when `customer.id` is not empty",
15835
+ "when `channel.name` is Point of Sale" cannot be written here).
15836
+ `extract_not_empty` is the only source-driven gate: on a lookup row
15837
+ it reads the row's `extract`, and when that is empty the row is
15838
+ skipped and the field is left unset — nothing substitutes a value.
15839
+ Value-dependent behaviour (a fallback record when the key is
15840
+ missing) belongs inside the lookup's `expression` (see
15841
+ `lookups[].expression`).
15842
+ - |-
15843
+ Two rows with the same `generate` are not a fallback pair: the
15844
+ last row for a destination decides it alone — when its condition
15845
+ skips it the field stays empty even if an earlier row produced a
15846
+ value, and when it applies it overwrites the earlier row's value
15847
+ (`ignore_if_set` reads the target record, not an earlier row).
15813
15848
  properties:
15814
15849
  lookupName:
15815
15850
  type: string
@@ -16065,6 +16100,18 @@ components:
16065
16100
  rows in live verification. Do not rely on that tolerance — use
16066
16101
  `when: record_updated` only on operations that can update
16067
16102
  records (`addupdate` / `update`).
16103
+ - |-
16104
+ The condition is one of the fixed `when` values — the same
16105
+ closed set as body rows, with no predicate over a source
16106
+ field; `extract_not_empty` skips the row on the lines whose
16107
+ extract is empty and leaves that line's field unset. Two
16108
+ sublist rows with the same `generate` are not a fallback
16109
+ pair either, and the order rule is not the body rows': among
16110
+ extract rows the last row decides each line alone (a skipped
16111
+ last row leaves the line's field unset even when an earlier
16112
+ row produced a value), while a hard-coded row's value lands
16113
+ on every line whatever its position — a later conditional
16114
+ extract row does not override it.
16068
16115
  properties:
16069
16116
  lookupName:
16070
16117
  type: string
@@ -16191,6 +16238,32 @@ components:
16191
16238
  shows what the expression produced for that line. With
16192
16239
  `allowFailures: true` the `default` value is used instead
16193
16240
  and no error is raised. Give every branch an output.
16241
+ - |-
16242
+ ## An empty substitution searches `isempty`
16243
+
16244
+ When the source path a criterion reads is null or absent
16245
+ (`["custentity_celigo_etail_cust_id","is","{{{customer.id}}}"]`
16246
+ on an order with no customer), the engine does not fail on
16247
+ the missing input: it searches the field with an `isempty`
16248
+ criterion, so the lookup now matches every target record
16249
+ whose field is BLANK. Two or more such records fail the
16250
+ record with `VALUE_LOOKUP_FAILED` — `More than one match
16251
+ for "[<field>,"isempty"]" for the record type "<recordType>"`
16252
+ (the message quotes the search field, never the empty
16253
+ source path); none fail it as `Could not find a match`;
16254
+ exactly one silently resolves to that record. Keep an empty
16255
+ key out of the search inside the expression — branch on
16256
+ the key: `{{#if customer.id}}[["custentity_celigo_etail_cust_id",
16257
+ "is","{{{customer.id}}}"]]{{else}}[["internalid","anyof",
16258
+ "<fallback internal id>"]]{{/if}}` routes records without a
16259
+ key to a fallback record while records with a key keep
16260
+ fail-on-miss; or render a value that can never match in the
16261
+ else branch and set `allowFailures: true` with `default`.
16262
+ A `searchField` / `operator` lookup (no `expression`) never
16263
+ reaches this state: an empty extract fails the record with
16264
+ `STATIC_MAPPING_ERROR` — `Exported value is empty/undefined
16265
+ for the field: $.<path>` — and resolves to `default` when
16266
+ `allowFailures` is true.
16194
16267
  - |-
16195
16268
  ## The mapping preview cannot evaluate `[*]` inside a block-helper argument
16196
16269
 
@@ -16224,19 +16297,34 @@ components:
16224
16297
  useDefaultOnMultipleMatches:
16225
16298
  type: boolean
16226
16299
  description: |-
16227
- Controls behaviour when the search matches more than one
16228
- record. When true, the `default` value is returned instead
16229
- of raising an ambiguous-match error. When false (default),
16230
- multiple matches are treated as a failure.
16300
+ When true and `allowFailures` is also true, a search that
16301
+ matches more than one record resolves to `default` instead
16302
+ of failing the record. Has no effect while `allowFailures`
16303
+ is false — an ambiguous match then fails the record whatever
16304
+ this flag says.
16305
+ x-celigo-ai-guidance:
16306
+ - |-
16307
+ Set it together with `allowFailures: true` whenever the
16308
+ search value can be empty or duplicated: with
16309
+ `allowFailures: true` alone an ambiguous match resolves to
16310
+ ONE of the matching records with no error, and with this
16311
+ flag alone the record still fails `More than one match`.
16312
+ Every ambiguous match then becomes `default`, a genuinely
16313
+ duplicated key included — when that must still fail, keep
16314
+ `allowFailures` false and handle the empty key in the
16315
+ `expression` instead (see `expression`).
16231
16316
  allowFailures:
16232
16317
  type:
16233
16318
  - boolean
16234
16319
  - 'null'
16235
16320
  description: |-
16236
16321
  When true, a lookup miss (no matching record and no
16237
- `default`) resolves to `null` and the import continues.
16238
- When false (default), a miss halts the record. May be
16239
- stored as null (treated as unset).
16322
+ `default`) resolves to `null` and the import continues, and
16323
+ a search matching more than one record resolves to one of
16324
+ them unless `useDefaultOnMultipleMatches` routes it to
16325
+ `default`. When false (default), a miss and an ambiguous
16326
+ match both halt the record. May be stored as null (treated
16327
+ as unset).
16240
16328
  map:
16241
16329
  type:
16242
16330
  - object
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@celigo/api-specs",
3
- "version": "0.2.126",
3
+ "version": "0.2.128",
4
4
  "private": false,
5
5
  "description": "Public OpenAPI bundles (dist/) and the celigo-cli lint schema pack (schemas.json).",
6
6
  "keywords": [
package/schemas.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "provenance": {
3
3
  "repo": "celigo/integrator-api-specs",
4
- "iasCommit": "0d0dde72",
4
+ "iasCommit": "4974f60c",
5
5
  "generatedAt": "2026-10-20"
6
6
  },
7
7
  "roots": {