@proveanything/smartlinks 1.10.1 → 1.10.3

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.
@@ -432,7 +432,7 @@ const productComments = await app.threads.list(collectionId, appId, {
432
432
 
433
433
  ## Records
434
434
 
435
- **Records** are the most flexible object type — use them for structured data with time-based lifecycles, hierarchies, or custom schemas. Records also support **structured scoping** — each record can declare which products, variants, batches, proofs, or facet values it applies to, and the platform can match records against a runtime context.
435
+ **Records** are the most flexible object type — use them for structured data with time-based lifecycles, hierarchies, or custom schemas. Records also support **structured targeting** — each record can declare which products, variants, batches, or proofs it applies to (via anchor fields), or which product attributes match (via `facetRule`), and the platform can match records against a runtime context.
436
436
 
437
437
  ### When to Use Records
438
438
 
@@ -450,64 +450,102 @@ const productComments = await app.threads.list(collectionId, appId, {
450
450
 
451
451
  - **Record types** — `recordType` field for categorization (required)
452
452
  - **Time windows** — `startsAt` and `expiresAt` for time-based data
453
- - **Scoped targeting** — `scope` object restricts which products/variants/facets the record applies to
454
- - **Specificity scoring** — `specificity` enables "best match" resolution across multiple scoped records
453
+ - **Anchor fields** — `productId`, `variantId`, `batchId`, `proofId` restrict which context the record applies to
454
+ - **Facet rules** — `facetRule` matches records to products based on attribute values
455
+ - **Specificity scoring** — `specificity` enables "best match" resolution across multiple targeted records
455
456
  - **Parent linking** — attach to products, proofs, contacts, etc.
456
457
  - **Author tracking** — `authorId` + `authorType`
457
458
  - **Status lifecycle** — custom statuses (default `'active'`)
458
- - **References** — optional `ref` field for external IDs; auto-derived from scope if omitted
459
+ - **References** — optional `ref` field for external IDs; auto-derived from anchor fields if omitted
459
460
 
460
- ### Scoped Records
461
+ ### Targeted Records
461
462
 
462
- Every record has a `scope` object. An empty scope (`{}`) means the record is universal — it applies everywhere. A populated scope restricts which context the record applies to.
463
+ Records use flat anchor fields to declare what context they apply to. A record with no anchor fields is universal — it applies everywhere. Populated anchor fields restrict the context to a specific product, variant, batch, or proof.
463
464
 
464
465
  ```typescript
465
466
  import { app } from '@proveanything/smartlinks';
466
467
 
467
- // A nutrition record scoped to a specific product
468
+ // A nutrition record anchored to a specific product
468
469
  await app.records.create(collectionId, appId, {
469
470
  recordType: 'nutrition',
470
- scope: { productId: 'prod_abc' },
471
+ productId: 'prod_abc',
471
472
  data: { calories: 250, protein: 12.5 },
472
473
  }, true);
473
474
 
474
475
  // A nutrition record for a specific variant, overriding the product-level record
475
476
  await app.records.create(collectionId, appId, {
476
477
  recordType: 'nutrition',
477
- scope: { productId: 'prod_abc', variantId: 'var_500ml' },
478
+ productId: 'prod_abc',
479
+ variantId: 'var_500ml',
478
480
  data: { calories: 260, protein: 12.5 },
479
481
  }, true);
480
482
 
481
- // A record scoped to a facet value (applies to all products with tier=gold)
483
+ // A record matching products by facet rule (applies to all products with tier=gold)
482
484
  await app.records.create(collectionId, appId, {
483
485
  recordType: 'loyalty_promo',
484
- scope: {
485
- facets: [{ key: 'tier', valueKeys: ['gold', 'platinum'] }]
486
+ facetRule: {
487
+ all: [{ facetKey: 'tier', anyOf: ['gold', 'platinum'] }],
486
488
  },
487
489
  data: { discountPercent: 15 },
488
490
  }, true);
489
491
  ```
490
492
 
491
- The `ref` field is derived automatically when `scope` is provided and `ref` is omitted:
493
+ The `ref` field is derived automatically from anchor fields when omitted:
492
494
 
493
495
  ```
494
- scope: { productId: 'prod_abc' } → ref: 'product:prod_abc'
495
- scope: { productId: 'prod_abc', variantId: 'var_x' } → ref: 'product:prod_abc/variant:var_x'
496
- scope: {} → ref: '' (universal)
496
+ productId: 'prod_abc' → ref: 'product:prod_abc'
497
+ productId: 'prod_abc', variantId: 'var_x' → ref: 'product:prod_abc/variant:var_x'
498
+ (no anchor fields) → ref: '' (universal)
499
+ facetRule: { ... } → ref: 'rule:<ulid>'
497
500
  ```
498
501
 
499
502
  #### Specificity scores
500
503
 
501
504
  When multiple scoped records match a context, they are ordered by `specificity`. Higher = more specific:
502
505
 
503
- | Scope element | Points |
504
- |---------------|--------|
506
+ | Field / element | Points |
507
+ |-----------------|--------|
505
508
  | `proofId` | +1000 |
506
509
  | `batchId` | +500 |
507
510
  | `variantId` | +250 |
508
511
  | `productId` | +100 |
509
- | Per facet clause | +10 |
510
- | Per facet value key | +1 |
512
+ | Per `facetRule` clause | +50 |
513
+ | Per `anyOf` value | +1 |
514
+ | No anchors / no rule | 0 |
515
+
516
+ ### Singleton Cardinality
517
+
518
+ By default, `create` always inserts a new row — calling it twice produces two records with identical anchor fields. **Singleton cardinality** changes that: pass `singletonPer` on creation and the server will **upsert** instead, ensuring at most one record of a given `recordType` exists per scope boundary.
519
+
520
+ ```typescript
521
+ // Ensure only one active registration record per product per contact
522
+ await app.records.create(collectionId, appId, {
523
+ recordType: 'product_registration',
524
+ visibility: 'owner',
525
+ contactId: user.contactId,
526
+ productId: product.id,
527
+ singletonPer: 'product', // one per (appId + recordType + contactId + productId)
528
+ data: { registeredAt: new Date().toISOString() },
529
+ });
530
+ ```
531
+
532
+ `singletonPer` values and the scope they enforce:
533
+
534
+ | Value | De-duplicates across |
535
+ |-------|---------------------|
536
+ | `'collection'` | entire app (one record of this type per app) |
537
+ | `'product'` | `productId` |
538
+ | `'variant'` | `variantId` |
539
+ | `'batch'` | `batchId` |
540
+ | `'proof'` | `proofId` |
541
+
542
+ The server assigns a **`singletonKey`** to each record that is governed by this rule — an opaque, stable string that acts as the upsert key. If a record with the same key already exists the server updates it in place (clearing `deletedAt` if it was soft-deleted) and returns the existing `id`. `singletonKey` is read-only and exposed on `AppRecord` for debugging but has no meaning to clients.
543
+
544
+ **When to use `singletonPer`:**
545
+ - One loyalty card per contact per product
546
+ - One registration per proof scan
547
+ - One active subscription record per variant
548
+ - Any "find-or-create" pattern where calling `create` twice should be idempotent
511
549
 
512
550
  ### Matching Records Against a Context
513
551
 
@@ -515,22 +553,22 @@ Use `app.records.match()` to find records whose scope is satisfied by a runtime
515
553
 
516
554
  ```typescript
517
555
  // Find all nutrition records that apply for this product + facet context
518
- const { records } = await app.records.match(collectionId, appId, {
556
+ const { data } = await app.records.match(collectionId, appId, {
519
557
  target: {
520
558
  productId: 'prod_abc',
521
559
  facets: { tier: ['gold'] },
522
560
  },
523
561
  recordType: 'nutrition',
524
562
  }, true);
525
- // records is ordered by specificity descending — most specific first
526
- // each record carries a `matchedAt` field indicating which scope dimension matched
563
+ // data is ordered by specificity descending — most specific first
564
+ // each entry carries a `matchedAt` field indicating which dimension matched
527
565
 
528
- // Or use strategy: 'best' to get the single winner per recordType
529
- const { best } = await app.records.match(collectionId, appId, {
566
+ // Use strategy: 'best' to get only the single winner per recordType
567
+ const { data: best } = await app.records.match(collectionId, appId, {
530
568
  target: { productId: 'prod_abc', variantId: 'var_500ml' },
531
569
  strategy: 'best',
532
570
  }, true);
533
- // best.nutrition → the highest-specificity nutrition record for this context
571
+ // best[0] → the highest-specificity record for this context
534
572
  ```
535
573
 
536
574
  Facet matching rules:
@@ -540,18 +578,18 @@ Facet matching rules:
540
578
 
541
579
  #### `matchedAt` — match attribution
542
580
 
543
- Every record in the response includes a `matchedAt` field indicating **which scope dimension caused the match**. Use it to render attribution labels without inspecting scope fields:
581
+ Every record in the response includes a `matchedAt` field indicating **which matching dimension caused the match**. Use it to render attribution labels:
544
582
 
545
583
  ```typescript
546
- const { records } = await app.records.match(collectionId, appId, { target, recordType: 'nutrition' }, true);
584
+ const { data } = await app.records.match(collectionId, appId, { target, recordType: 'nutrition' }, true);
547
585
 
548
- for (const entry of records) {
586
+ for (const entry of data) {
549
587
  switch (entry.matchedAt) {
588
+ case 'rule': /* "Matches rule" */ break;
550
589
  case 'proof': /* "Scan-specific" */ break;
551
590
  case 'batch': /* "Batch-specific" */ break;
552
591
  case 'variant': /* "Size-specific" */ break;
553
592
  case 'product': /* "Inherited from product" */ break;
554
- case 'rule': /* "Matches rule" */ break;
555
593
  case 'facet': /* "Tier-specific" */ break;
556
594
  case 'collection': /* "Collection default" */ break;
557
595
  case 'universal': /* "Default" */ break;
@@ -559,7 +597,7 @@ for (const entry of records) {
559
597
  }
560
598
  ```
561
599
 
562
- Precedence follows: `proof > batch > variant > product > rule > facet > collection > universal`.
600
+ Precedence follows: `rule > proof > batch > variant > product > facet > collection > universal`.
563
601
 
564
602
  #### React — `useResolvedRecord`
565
603
 
@@ -583,19 +621,19 @@ await app.records.create(collectionId, appId, {
583
621
  }, true);
584
622
  ```
585
623
 
586
- `facetRule` is **mutually exclusive with `scope`**. A record has either a structured scope or a facetRule, never both. The server assigns `ref: 'rule:<ulid>'` automatically.
624
+ `facetRule` and anchor fields (`productId`, `variantId`, etc.) are mutually exclusive. A record uses either anchor-based targeting or a facetRule, never both. The server assigns `ref: 'rule:<ulid>'` automatically.
587
625
 
588
626
  Specificity for rule records: `Σ (50 + clause.anyOf.length)` across all clauses. A 2-clause rule with 1 value each scores `(50+1)+(50+1) = 102`, which ranks above a plain product-scoped record (100) in `resolveAll()` results.
589
627
 
590
628
  Use `records.previewRule()` to see which products a rule would match before creating it:
591
629
 
592
630
  ```typescript
593
- const { sampleProductIds, totalMatches } = await app.records.previewRule(collectionId, appId, {
631
+ const { matchingProducts, total } = await app.records.previewRule(collectionId, appId, {
594
632
  facetRule: {
595
633
  all: [{ facetKey: 'brand', anyOf: ['samsung'] }],
596
634
  },
597
635
  });
598
- // totalMatches: 42, sampleProductIds: ['prod_001', 'prod_002', ...]
636
+ // total: 42, matchingProducts: [{ productId: 'prod_001', facets: {...} }, ...]
599
637
  ```
600
638
 
601
639
  ### Resolve All
@@ -604,7 +642,7 @@ Use `app.records.resolveAll()` to fetch **every applicable record for a product
604
642
 
605
643
  ```typescript
606
644
  // All records that apply to this product context (admin)
607
- const { records, truncated } = await app.records.resolveAll(collectionId, appId, {
645
+ const { records, total, truncated } = await app.records.resolveAll(collectionId, appId, {
608
646
  context: {
609
647
  productId: 'prod_001',
610
648
  facets: { brand: 'samsung', type: 'tv' },
@@ -641,7 +679,7 @@ Create-or-update a record by `ref` in a single call:
641
679
  const { created } = await app.records.upsert(collectionId, appId, {
642
680
  ref: 'product:prod_abc',
643
681
  recordType: 'nutrition',
644
- scope: { productId: 'prod_abc' },
682
+ productId: 'prod_abc',
645
683
  data: { calories: 250, protein: 12.5 },
646
684
  });
647
685
  // created: true if new, false if updated
@@ -654,8 +692,8 @@ Upsert or delete large sets of records efficiently:
654
692
  ```typescript
655
693
  // Bulk upsert up to 500 records in one transaction
656
694
  const result = await app.records.bulkUpsert(collectionId, appId, [
657
- { ref: 'product:prod_abc', recordType: 'nutrition', scope: { productId: 'prod_abc' }, data: { calories: 250 } },
658
- { ref: 'product:prod_xyz', recordType: 'nutrition', scope: { productId: 'prod_xyz' }, data: { calories: 180 } },
695
+ { ref: 'product:prod_abc', recordType: 'nutrition', productId: 'prod_abc', data: { calories: 250 } },
696
+ { ref: 'product:prod_xyz', recordType: 'nutrition', productId: 'prod_xyz', data: { calories: 180 } },
659
697
  ]);
660
698
  // result: { saved: 2, failed: 0, results: [...] }
661
699
 
@@ -665,7 +703,7 @@ await app.records.bulkDelete(collectionId, appId, {
665
703
  recordType: 'nutrition',
666
704
  });
667
705
 
668
- // Bulk delete by scope anchor (all records under a product)
706
+ // Bulk delete by anchor (all records under a product)
669
707
  await app.records.bulkDelete(collectionId, appId, {
670
708
  scope: { productId: 'prod_abc' },
671
709
  });
@@ -719,7 +757,7 @@ await app.records.upsert(collectionId, appId, {
719
757
  customId: slug,
720
758
  sourceSystem: 'contentful',
721
759
  recordType: 'content_page',
722
- scope: { productId },
760
+ productId,
723
761
  data: { title, body },
724
762
  });
725
763
  // upsert finds-or-creates by ref deterministically,
@@ -754,21 +792,21 @@ await app.records.aggregate(collectionId, appId, {
754
792
 
755
793
  ### Canonical Ref Format
756
794
 
757
- The `ref` field is **server-derived** when you provide a `scope` and omit `ref`. Clients should never construct ref strings manually. The authoritative grammar is slash-joined:
795
+ The `ref` field is **server-derived** when anchor fields are provided and `ref` is omitted. Clients should never construct ref strings manually. The authoritative grammar is slash-joined:
758
796
 
759
797
  ```
760
- [facet:{key}={val1}+{val2}/][product:{productId}/][variant:{variantId}/][batch:{batchId}/][proof:{proofId}]
798
+ [product:{productId}/][variant:{variantId}/][batch:{batchId}/][proof:{proofId}]
761
799
  ```
762
800
 
763
801
  Examples:
764
802
 
765
- | Scope | Derived ref |
766
- |-------|-------------|
767
- | `{ productId: 'prod_abc' }` | `product:prod_abc` |
768
- | `{ productId: 'prod_abc', variantId: 'var_500ml' }` | `product:prod_abc/variant:var_500ml` |
769
- | `{ batchId: 'batch_q1' }` | `batch:batch_q1` |
770
- | `{ facets: [{ key: 'tier', valueKeys: ['gold'] }] }` | `facet:tier=gold` |
771
- | `{}` | `''` (universal) |
803
+ | Anchor fields | Derived ref |
804
+ |---------------|-------------|
805
+ | `productId: 'prod_abc'` | `product:prod_abc` |
806
+ | `productId: 'prod_abc', variantId: 'var_500ml'` | `product:prod_abc/variant:var_500ml` |
807
+ | `batchId: 'batch_q1'` | `batch:batch_q1` |
808
+ | `facetRule: { ... }` | `rule:<ulid>` |
809
+ | *(no anchor fields)* | `''` (universal) |
772
810
 
773
811
  `parseRef` / `buildRef` in `data/refs.ts` should be used for **display and URL round-tripping only**, never as upsert keys. For ETL use cases, set an explicit `ref` using a stable external key (see [External ID / ETL Workflow](#external-id--etl-workflow)).
774
812
 
package/openapi.yaml CHANGED
@@ -15619,33 +15619,6 @@ components:
15619
15619
  $ref: "#/components/schemas/FacetRuleClause"
15620
15620
  required:
15621
15621
  - all
15622
- ScopeFacetClause:
15623
- type: object
15624
- properties:
15625
- key:
15626
- type: string
15627
- valueKeys:
15628
- type: array
15629
- items:
15630
- type: string
15631
- required:
15632
- - key
15633
- - valueKeys
15634
- RecordScope:
15635
- type: object
15636
- properties:
15637
- productId:
15638
- type: string
15639
- variantId:
15640
- type: string
15641
- proofId:
15642
- type: string
15643
- batchId:
15644
- type: string
15645
- facets:
15646
- type: array
15647
- items:
15648
- $ref: "#/components/schemas/ScopeFacetClause"
15649
15622
  RecordTarget:
15650
15623
  type: object
15651
15624
  properties:
@@ -15670,6 +15643,14 @@ components:
15670
15643
  type: string
15671
15644
  recordType:
15672
15645
  type: string
15646
+ productId:
15647
+ type: string
15648
+ variantId:
15649
+ type: string
15650
+ batchId:
15651
+ type: string
15652
+ proofId:
15653
+ type: string
15673
15654
  customId:
15674
15655
  type: string
15675
15656
  sourceSystem:
@@ -15680,8 +15661,6 @@ components:
15680
15661
  type: string
15681
15662
  status:
15682
15663
  type: string
15683
- scope:
15684
- $ref: "#/components/schemas/RecordScope"
15685
15664
  data:
15686
15665
  type: object
15687
15666
  additionalProperties: true
@@ -15713,43 +15692,35 @@ components:
15713
15692
  type: number
15714
15693
  required:
15715
15694
  - deleted
15716
- MatchedRecord:
15717
- type: object
15718
- properties:
15719
- matchedAt:
15720
- $ref: "#/components/schemas/MatchedAt"
15721
- required:
15722
- - matchedAt
15723
15695
  MatchEntry:
15724
15696
  type: object
15725
15697
  properties:
15726
- record:
15727
- $ref: "#/components/schemas/AppRecord"
15728
15698
  matchedAt:
15729
15699
  $ref: "#/components/schemas/MatchedAt"
15730
15700
  matchedRule:
15731
15701
  $ref: "#/components/schemas/FacetRule"
15732
15702
  matchedClauseCount:
15733
15703
  type: number
15734
- specificity:
15735
- type: number
15736
15704
  required:
15737
- - record
15738
15705
  - matchedAt
15739
- - specificity
15740
15706
  MatchResult:
15741
15707
  type: object
15742
15708
  properties:
15743
- records:
15709
+ data:
15744
15710
  type: array
15745
15711
  items:
15746
15712
  $ref: "#/components/schemas/MatchEntry"
15747
- best:
15748
- type: object
15749
- additionalProperties:
15750
- $ref: "#/components/schemas/MatchEntry"
15713
+ total:
15714
+ type: number
15715
+ strategy:
15716
+ type: string
15717
+ enum:
15718
+ - all
15719
+ - best
15751
15720
  required:
15752
- - records
15721
+ - data
15722
+ - total
15723
+ - strategy
15753
15724
  UpsertRecordInput:
15754
15725
  type: object
15755
15726
  properties:
@@ -15757,6 +15728,14 @@ components:
15757
15728
  type: string
15758
15729
  recordType:
15759
15730
  type: string
15731
+ productId:
15732
+ type: string
15733
+ variantId:
15734
+ type: string
15735
+ batchId:
15736
+ type: string
15737
+ proofId:
15738
+ type: string
15760
15739
  customId:
15761
15740
  type: string
15762
15741
  sourceSystem:
@@ -15767,8 +15746,6 @@ components:
15767
15746
  type: string
15768
15747
  status:
15769
15748
  type: string
15770
- scope:
15771
- $ref: "#/components/schemas/RecordScope"
15772
15749
  data:
15773
15750
  type: object
15774
15751
  additionalProperties: true
@@ -15825,14 +15802,24 @@ components:
15825
15802
  type: string
15826
15803
  ref:
15827
15804
  type: string
15805
+ scopeType:
15806
+ type: string
15807
+ scopeId:
15808
+ type: string
15828
15809
  customId:
15829
15810
  type: string
15811
+ customIdNormalized:
15812
+ type: string
15830
15813
  sourceSystem:
15831
15814
  type: string
15832
15815
  status:
15833
15816
  type: string
15834
15817
  productId:
15835
15818
  type: string
15819
+ variantId:
15820
+ type: string
15821
+ batchId:
15822
+ type: string
15836
15823
  proofId:
15837
15824
  type: string
15838
15825
  contactId:
@@ -15855,12 +15842,12 @@ components:
15855
15842
  type: string
15856
15843
  deletedAt:
15857
15844
  type: string
15858
- scope:
15859
- $ref: "#/components/schemas/RecordScope"
15860
15845
  specificity:
15861
15846
  type: number
15862
15847
  facetRule:
15863
15848
  $ref: "#/components/schemas/FacetRule"
15849
+ singletonKey:
15850
+ type: string
15864
15851
  data:
15865
15852
  type: object
15866
15853
  additionalProperties: true
@@ -15881,10 +15868,15 @@ components:
15881
15868
  - visibility
15882
15869
  - recordType
15883
15870
  - ref
15871
+ - scopeType
15872
+ - scopeId
15884
15873
  - customId
15874
+ - customIdNormalized
15885
15875
  - sourceSystem
15886
15876
  - status
15887
15877
  - productId
15878
+ - variantId
15879
+ - batchId
15888
15880
  - proofId
15889
15881
  - contactId
15890
15882
  - authorId
@@ -15896,9 +15888,9 @@ components:
15896
15888
  - startsAt
15897
15889
  - expiresAt
15898
15890
  - deletedAt
15899
- - scope
15900
15891
  - specificity
15901
15892
  - facetRule
15893
+ - singletonKey
15902
15894
  - data
15903
15895
  - owner
15904
15896
  - admin
@@ -15916,6 +15908,10 @@ components:
15916
15908
  type: string
15917
15909
  productId:
15918
15910
  type: string
15911
+ variantId:
15912
+ type: string
15913
+ batchId:
15914
+ type: string
15919
15915
  proofId:
15920
15916
  type: string
15921
15917
  contactId:
@@ -15932,12 +15928,16 @@ components:
15932
15928
  type: string
15933
15929
  expiresAt:
15934
15930
  type: string
15935
- scope:
15936
- $ref: "#/components/schemas/RecordScope"
15931
+ scopeType:
15932
+ type: string
15933
+ scopeId:
15934
+ type: string
15937
15935
  customId:
15938
15936
  type: string
15939
15937
  sourceSystem:
15940
15938
  type: string
15939
+ singletonPer:
15940
+ type: string
15941
15941
  data:
15942
15942
  type: object
15943
15943
  additionalProperties: true
@@ -15952,8 +15952,6 @@ components:
15952
15952
  additionalProperties: true
15953
15953
  facetRule:
15954
15954
  $ref: "#/components/schemas/FacetRule"
15955
- required:
15956
- - recordType
15957
15955
  UpdateRecordInput:
15958
15956
  type: object
15959
15957
  properties:
@@ -15974,12 +15972,22 @@ components:
15974
15972
  type: string
15975
15973
  recordType:
15976
15974
  type: string
15975
+ productId:
15976
+ type: string
15977
+ variantId:
15978
+ type: string
15979
+ batchId:
15980
+ type: string
15981
+ proofId:
15982
+ type: string
15977
15983
  startsAt:
15978
15984
  type: string
15979
15985
  expiresAt:
15980
15986
  type: string
15981
- scope:
15982
- $ref: "#/components/schemas/RecordScope"
15987
+ scopeType:
15988
+ type: string
15989
+ scopeId:
15990
+ type: string
15983
15991
  customId:
15984
15992
  type: string
15985
15993
  sourceSystem:
@@ -16081,16 +16089,59 @@ components:
16081
16089
  records:
16082
16090
  type: array
16083
16091
  items:
16084
- $ref: "#/components/schemas/MatchEntry"
16092
+ $ref: "#/components/schemas/ResolveAllEntry"
16093
+ total:
16094
+ type: number
16095
+ context:
16096
+ $ref: "#/components/schemas/ResolveAllContext"
16085
16097
  truncated:
16086
16098
  type: boolean
16087
16099
  required:
16088
16100
  - records
16101
+ - total
16102
+ - context
16103
+ - truncated
16104
+ ResolveAllEntry:
16105
+ type: object
16106
+ properties:
16107
+ record:
16108
+ $ref: "#/components/schemas/AppRecord"
16109
+ matchedAt:
16110
+ $ref: "#/components/schemas/MatchedAt"
16111
+ specificity:
16112
+ type: number
16113
+ matchedRule:
16114
+ $ref: "#/components/schemas/FacetRule"
16115
+ matchedClauseCount:
16116
+ type: number
16117
+ required:
16118
+ - record
16119
+ - matchedAt
16120
+ - specificity
16121
+ ResolveAllContext:
16122
+ type: object
16123
+ properties:
16124
+ productId:
16125
+ type: string
16126
+ variantId:
16127
+ type: string
16128
+ batchId:
16129
+ type: string
16130
+ proofId:
16131
+ type: string
16132
+ facets:
16133
+ type: object
16134
+ additionalProperties:
16135
+ type: array
16136
+ items:
16137
+ type: string
16089
16138
  PreviewRuleParams:
16090
16139
  type: object
16091
16140
  properties:
16092
16141
  facetRule:
16093
16142
  $ref: "#/components/schemas/FacetRule"
16143
+ recordType:
16144
+ type: string
16094
16145
  limit:
16095
16146
  type: number
16096
16147
  required:
@@ -16098,15 +16149,19 @@ components:
16098
16149
  PreviewRuleResult:
16099
16150
  type: object
16100
16151
  properties:
16101
- sampleProductIds:
16152
+ matchingProducts:
16102
16153
  type: array
16103
16154
  items:
16104
- type: string
16105
- totalMatches:
16155
+ type: object
16156
+ additionalProperties: true
16157
+ total:
16106
16158
  type: number
16159
+ rule:
16160
+ $ref: "#/components/schemas/FacetRule"
16107
16161
  required:
16108
- - sampleProductIds
16109
- - totalMatches
16162
+ - matchingProducts
16163
+ - total
16164
+ - rule
16110
16165
  RelatedResponse:
16111
16166
  type: object
16112
16167
  properties:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@proveanything/smartlinks",
3
- "version": "1.10.1",
3
+ "version": "1.10.3",
4
4
  "description": "Official JavaScript/TypeScript SDK for the Smartlinks API",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",