@proveanything/smartlinks 1.9.22 → 1.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -284,6 +284,181 @@ export interface ThreadListQueryParams extends ListQueryParams {
284
284
  tag?: string;
285
285
  contactId?: string;
286
286
  }
287
+ /**
288
+ * Facet clause within a RecordScope.
289
+ * Values within a single clause are ORed; multiple clauses are ANDed.
290
+ */
291
+ export interface ScopeFacetClause {
292
+ /** Facet key, e.g. "tier", "region" */
293
+ key: string;
294
+ /** One or more values that satisfy this clause (OR semantics) */
295
+ valueKeys: string[];
296
+ }
297
+ /**
298
+ * Structured scope definition for a record.
299
+ * Describes the audience/context the record applies to.
300
+ * An empty object `{}` means universal (no restrictions).
301
+ */
302
+ export interface RecordScope {
303
+ productId?: string;
304
+ variantId?: string;
305
+ proofId?: string;
306
+ batchId?: string;
307
+ /**
308
+ * Arbitrary facet clauses.
309
+ * Clauses are ANDed together; valueKeys within a clause are ORed.
310
+ */
311
+ facets?: ScopeFacetClause[];
312
+ }
313
+ /**
314
+ * Runtime context passed to the match endpoint.
315
+ * Describes the caller or item being evaluated against record scopes.
316
+ */
317
+ export interface RecordTarget {
318
+ productId?: string;
319
+ variantId?: string;
320
+ proofId?: string;
321
+ batchId?: string;
322
+ /**
323
+ * Facet values the caller possesses, keyed by facet key.
324
+ * A scope clause is satisfied if ANY of the clause's valueKeys appears here.
325
+ */
326
+ facets?: Record<string, string[]>;
327
+ }
328
+ /**
329
+ * Request body for the bulk-upsert endpoint.
330
+ */
331
+ export interface BulkUpsertItem {
332
+ /** Required — logical identifier used as the upsert key */
333
+ ref: string;
334
+ recordType?: string;
335
+ customId?: string;
336
+ sourceSystem?: string;
337
+ startsAt?: string | null;
338
+ expiresAt?: string | null;
339
+ status?: string | null;
340
+ scope?: RecordScope;
341
+ data?: Record<string, unknown> | null;
342
+ metadata?: Record<string, unknown> | null;
343
+ }
344
+ /**
345
+ * Response from the bulk-upsert endpoint.
346
+ */
347
+ export interface BulkUpsertResult {
348
+ saved: number;
349
+ failed: number;
350
+ results: Array<{
351
+ index: number;
352
+ status: 'created';
353
+ id: string;
354
+ ref: string;
355
+ created: true;
356
+ } | {
357
+ index: number;
358
+ status: 'updated';
359
+ id: string;
360
+ ref: string;
361
+ created: false;
362
+ } | {
363
+ index: number;
364
+ status: 'error';
365
+ error: string;
366
+ }>;
367
+ }
368
+ /**
369
+ * Response from the bulk-delete endpoint.
370
+ */
371
+ export interface BulkDeleteResult {
372
+ deleted: number;
373
+ }
374
+ /**
375
+ * Input for the bulk-delete endpoint.
376
+ * Use **refs mode** to delete explicit records by ref,
377
+ * or **scope mode** to delete all records anchored to a scope.
378
+ */
379
+ export type BulkDeleteInput = {
380
+ refs: string[];
381
+ recordType?: string;
382
+ scope?: never;
383
+ } | {
384
+ scope: Omit<RecordScope, 'facets'>;
385
+ recordType?: string;
386
+ refs?: never;
387
+ };
388
+ /**
389
+ * Indicates which scope dimension caused a record to match during `match()`.
390
+ * Follows specificity order: proof > batch > variant > product > facet > universal.
391
+ */
392
+ export type MatchedAtLevel = 'proof' | 'batch' | 'variant' | 'product' | 'facet' | 'universal';
393
+ /**
394
+ * An AppRecord augmented with `matchedAt` — present only on records returned
395
+ * by the `match` endpoint. Use this to display attribution such as
396
+ * "Inherited from product" or "Batch-specific" without inspecting scope fields.
397
+ */
398
+ export interface MatchedRecord extends AppRecord {
399
+ /**
400
+ * The most specific scope dimension that caused this record to match.
401
+ * 'universal' means the record has an empty scope and matches all contexts.
402
+ */
403
+ matchedAt: MatchedAtLevel;
404
+ }
405
+ /**
406
+ * Response from the match endpoint.
407
+ */
408
+ export interface MatchResult {
409
+ /** Matched records ordered by specificity descending (most specific first) */
410
+ records: MatchedRecord[];
411
+ /**
412
+ * Only present when strategy is 'best'.
413
+ * The single highest-specificity record per recordType.
414
+ */
415
+ best?: Record<string, MatchedRecord>;
416
+ }
417
+ /**
418
+ * Request body for the upsert endpoint.
419
+ */
420
+ export interface UpsertRecordInput {
421
+ /** Required — used as the lookup key */
422
+ ref: string;
423
+ recordType?: string;
424
+ customId?: string;
425
+ sourceSystem?: string;
426
+ startsAt?: string | null;
427
+ expiresAt?: string | null;
428
+ status?: string | null;
429
+ scope?: RecordScope;
430
+ data?: Record<string, unknown> | null;
431
+ metadata?: Record<string, unknown> | null;
432
+ }
433
+ /**
434
+ * Response from the upsert endpoint — includes AppRecord plus a created flag.
435
+ */
436
+ export interface UpsertRecordResponse extends AppRecord {
437
+ /** true if the record was newly created, false if updated */
438
+ created: boolean;
439
+ }
440
+ /**
441
+ * Request body for the match endpoint.
442
+ */
443
+ export interface MatchRecordsInput {
444
+ /** Required — describes the runtime context to match against */
445
+ target: RecordTarget;
446
+ /**
447
+ * 'all' — return all matching records (default)
448
+ * 'best' — return the highest-specificity record per recordType
449
+ */
450
+ strategy?: 'all' | 'best';
451
+ /** Limit to a specific recordType */
452
+ recordType?: string;
453
+ /** Maximum records to return. Default 100, max 1000. */
454
+ limit?: number;
455
+ /** Include records whose startsAt is in the future. Default false. */
456
+ includeScheduled?: boolean;
457
+ /** Include records whose expiresAt is in the past. Default false. */
458
+ includeExpired?: boolean;
459
+ /** Evaluate scheduling relative to this ISO 8601 timestamp. Defaults to now. */
460
+ at?: string;
461
+ }
287
462
  /**
288
463
  * App Record object
289
464
  */
@@ -293,10 +468,14 @@ export interface AppRecord {
293
468
  collectionId: string;
294
469
  appId: string;
295
470
  visibility: Visibility;
296
- recordType: string;
471
+ recordType: string | null;
297
472
  ref: string | null;
298
- status: string;
473
+ customId: string | null;
474
+ sourceSystem: string | null;
475
+ status: string | null;
476
+ /** @deprecated use scope.productId instead */
299
477
  productId: string | null;
478
+ /** @deprecated use scope.proofId instead */
300
479
  proofId: string | null;
301
480
  contactId: string | null;
302
481
  authorId: string | null;
@@ -308,9 +487,20 @@ export interface AppRecord {
308
487
  startsAt: string | null;
309
488
  expiresAt: string | null;
310
489
  deletedAt: string | null;
490
+ /**
491
+ * Structured scope definition. Empty object means universal.
492
+ * Platform-canonicalized on write (keys sorted, valueKeys deduplicated).
493
+ */
494
+ scope: RecordScope;
495
+ /**
496
+ * Numeric specificity score computed from scope.
497
+ * Higher = more specific. 0 = universal scope.
498
+ */
499
+ specificity: number;
311
500
  data: Record<string, unknown>;
312
501
  owner: Record<string, unknown>;
313
502
  admin: Record<string, unknown>;
503
+ metadata: Record<string, unknown> | null;
314
504
  }
315
505
  /**
316
506
  * Input for creating a new record
@@ -329,9 +519,14 @@ export interface CreateRecordInput {
329
519
  parentId?: string;
330
520
  startsAt?: string;
331
521
  expiresAt?: string;
522
+ /** Structured scope. Canonicalized on write; ref derived if not supplied. */
523
+ scope?: RecordScope;
524
+ customId?: string;
525
+ sourceSystem?: string;
332
526
  data?: Record<string, unknown>;
333
527
  owner?: Record<string, unknown>;
334
528
  admin?: Record<string, unknown>;
529
+ metadata?: Record<string, unknown>;
335
530
  }
336
531
  /**
337
532
  * Input for updating a record
@@ -346,6 +541,11 @@ export interface UpdateRecordInput {
346
541
  recordType?: string;
347
542
  startsAt?: string;
348
543
  expiresAt?: string;
544
+ /** Updating scope recomputes specificity and ref. */
545
+ scope?: RecordScope;
546
+ customId?: string;
547
+ sourceSystem?: string;
548
+ metadata?: Record<string, unknown>;
349
549
  }
350
550
  /**
351
551
  * Query parameters for listing records
@@ -353,13 +553,34 @@ export interface UpdateRecordInput {
353
553
  export interface RecordListQueryParams extends ListQueryParams {
354
554
  recordType?: string;
355
555
  ref?: string;
556
+ /** Filter records whose ref starts with this value */
557
+ refPrefix?: string;
558
+ customId?: string;
559
+ sourceSystem?: string;
356
560
  proofId?: string;
561
+ /** Filter by scope.variantId (JSONB lookup) */
562
+ variantId?: string;
563
+ /** Filter by scope.batchId (JSONB lookup) */
564
+ batchId?: string;
565
+ /** Full-text filter on data.label (case-insensitive substring) */
566
+ q?: string;
357
567
  authorId?: string;
358
568
  parentType?: string;
359
569
  parentId?: string;
360
570
  startsAt?: string;
361
571
  expiresAt?: string;
572
+ /** Include records where startsAt is in the future. Default false. */
573
+ includeScheduled?: boolean;
574
+ /** Include records where expiresAt is in the past. Default false. */
575
+ includeExpired?: boolean;
576
+ /**
577
+ * Evaluate scheduling relative to this ISO 8601 timestamp.
578
+ * Defaults to now.
579
+ */
580
+ at?: string;
362
581
  contactId?: string;
582
+ /** Include soft-deleted records (non-null deletedAt). Admin only. Default false. */
583
+ includeDeleted?: boolean;
363
584
  }
364
585
  /**
365
586
  * Response from case related endpoint
@@ -1,6 +1,6 @@
1
1
  # Smartlinks API Summary
2
2
 
3
- Version: 1.9.22 | Generated: 2026-04-25T11:11:00.344Z
3
+ Version: 1.10.0 | Generated: 2026-04-25T13:26:09.113Z
4
4
 
5
5
  This is a concise summary of all available API functions and types.
6
6
 
@@ -1880,6 +1880,117 @@ interface ReplyInput {
1880
1880
  }
1881
1881
  ```
1882
1882
 
1883
+ **ScopeFacetClause** (interface)
1884
+ ```typescript
1885
+ interface ScopeFacetClause {
1886
+ key: string
1887
+ valueKeys: string[]
1888
+ }
1889
+ ```
1890
+
1891
+ **RecordScope** (interface)
1892
+ ```typescript
1893
+ interface RecordScope {
1894
+ productId?: string
1895
+ variantId?: string
1896
+ proofId?: string
1897
+ batchId?: string
1898
+ * Arbitrary facet clauses.
1899
+ * Clauses are ANDed together; valueKeys within a clause are ORed.
1900
+ facets?: ScopeFacetClause[]
1901
+ }
1902
+ ```
1903
+
1904
+ **RecordTarget** (interface)
1905
+ ```typescript
1906
+ interface RecordTarget {
1907
+ productId?: string
1908
+ variantId?: string
1909
+ proofId?: string
1910
+ batchId?: string
1911
+ * Facet values the caller possesses, keyed by facet key.
1912
+ * A scope clause is satisfied if ANY of the clause's valueKeys appears here.
1913
+ facets?: Record<string, string[]>
1914
+ }
1915
+ ```
1916
+
1917
+ **BulkUpsertItem** (interface)
1918
+ ```typescript
1919
+ interface BulkUpsertItem {
1920
+ ref: string
1921
+ recordType?: string
1922
+ customId?: string
1923
+ sourceSystem?: string
1924
+ startsAt?: string | null
1925
+ expiresAt?: string | null
1926
+ status?: string | null
1927
+ scope?: RecordScope
1928
+ data?: Record<string, unknown> | null
1929
+ metadata?: Record<string, unknown> | null
1930
+ }
1931
+ ```
1932
+
1933
+ **BulkUpsertResult** (interface)
1934
+ ```typescript
1935
+ interface BulkUpsertResult {
1936
+ saved: number
1937
+ failed: number
1938
+ results: Array<
1939
+ | { index: number; status: 'created'; id: string; ref: string; created: true }
1940
+ | { index: number; status: 'updated'; id: string; ref: string; created: false }
1941
+ | { index: number; status: 'error'; error: string }
1942
+ >
1943
+ }
1944
+ ```
1945
+
1946
+ **BulkDeleteResult** (interface)
1947
+ ```typescript
1948
+ interface BulkDeleteResult {
1949
+ deleted: number
1950
+ }
1951
+ ```
1952
+
1953
+ **MatchResult** (interface)
1954
+ ```typescript
1955
+ interface MatchResult {
1956
+ records: MatchedRecord[]
1957
+ * Only present when strategy is 'best'.
1958
+ * The single highest-specificity record per recordType.
1959
+ best?: Record<string, MatchedRecord>
1960
+ }
1961
+ ```
1962
+
1963
+ **UpsertRecordInput** (interface)
1964
+ ```typescript
1965
+ interface UpsertRecordInput {
1966
+ ref: string
1967
+ recordType?: string
1968
+ customId?: string
1969
+ sourceSystem?: string
1970
+ startsAt?: string | null
1971
+ expiresAt?: string | null
1972
+ status?: string | null
1973
+ scope?: RecordScope
1974
+ data?: Record<string, unknown> | null
1975
+ metadata?: Record<string, unknown> | null
1976
+ }
1977
+ ```
1978
+
1979
+ **MatchRecordsInput** (interface)
1980
+ ```typescript
1981
+ interface MatchRecordsInput {
1982
+ target: RecordTarget
1983
+ * 'all' — return all matching records (default)
1984
+ * 'best' — return the highest-specificity record per recordType
1985
+ strategy?: 'all' | 'best'
1986
+ recordType?: string
1987
+ limit?: number
1988
+ includeScheduled?: boolean
1989
+ includeExpired?: boolean
1990
+ at?: string
1991
+ }
1992
+ ```
1993
+
1883
1994
  **AppRecord** (interface)
1884
1995
  ```typescript
1885
1996
  interface AppRecord {
@@ -1888,9 +1999,11 @@ interface AppRecord {
1888
1999
  collectionId: string
1889
2000
  appId: string
1890
2001
  visibility: Visibility
1891
- recordType: string
2002
+ recordType: string | null
1892
2003
  ref: string | null
1893
- status: string // default 'active'
2004
+ customId: string | null
2005
+ sourceSystem: string | null
2006
+ status: string | null
1894
2007
  productId: string | null
1895
2008
  proofId: string | null
1896
2009
  contactId: string | null
@@ -1903,9 +2016,16 @@ interface AppRecord {
1903
2016
  startsAt: string | null
1904
2017
  expiresAt: string | null
1905
2018
  deletedAt: string | null // admin only
2019
+ * Structured scope definition. Empty object means universal.
2020
+ * Platform-canonicalized on write (keys sorted, valueKeys deduplicated).
2021
+ scope: RecordScope
2022
+ * Numeric specificity score computed from scope.
2023
+ * Higher = more specific. 0 = universal scope.
2024
+ specificity: number
1906
2025
  data: Record<string, unknown>
1907
2026
  owner: Record<string, unknown>
1908
2027
  admin: Record<string, unknown> // admin only
2028
+ metadata: Record<string, unknown> | null
1909
2029
  }
1910
2030
  ```
1911
2031
 
@@ -1914,7 +2034,7 @@ interface AppRecord {
1914
2034
  interface CreateRecordInput {
1915
2035
  recordType: string
1916
2036
  visibility?: Visibility // default 'owner'
1917
- ref?: string
2037
+ ref?: string // derived from scope if omitted and scope provided
1918
2038
  status?: string // default 'active'
1919
2039
  productId?: string
1920
2040
  proofId?: string
@@ -1925,9 +2045,13 @@ interface CreateRecordInput {
1925
2045
  parentId?: string
1926
2046
  startsAt?: string // ISO 8601
1927
2047
  expiresAt?: string
2048
+ scope?: RecordScope
2049
+ customId?: string
2050
+ sourceSystem?: string
1928
2051
  data?: Record<string, unknown>
1929
2052
  owner?: Record<string, unknown>
1930
2053
  admin?: Record<string, unknown> // admin only
2054
+ metadata?: Record<string, unknown>
1931
2055
  }
1932
2056
  ```
1933
2057
 
@@ -1943,6 +2067,10 @@ interface UpdateRecordInput {
1943
2067
  recordType?: string
1944
2068
  startsAt?: string
1945
2069
  expiresAt?: string
2070
+ scope?: RecordScope
2071
+ customId?: string
2072
+ sourceSystem?: string
2073
+ metadata?: Record<string, unknown>
1946
2074
  }
1947
2075
  ```
1948
2076
 
@@ -2010,6 +2138,10 @@ interface PublicCreateBranch {
2010
2138
 
2011
2139
  **CallerRole** = `'admin' | 'owner' | 'public'`
2012
2140
 
2141
+ **BulkDeleteInput** = ``
2142
+
2143
+ **MatchedAtLevel** = ``
2144
+
2013
2145
  ### asset
2014
2146
 
2015
2147
  **Asset** (interface)
@@ -7148,6 +7280,32 @@ Soft delete a record DELETE /records/:recordId
7148
7280
  admin: boolean = false) → `Promise<AggregateResponse>`
7149
7281
  Get aggregate statistics for records POST /records/aggregate
7150
7282
 
7283
+ **restore**(collectionId: string,
7284
+ appId: string,
7285
+ recordId: string) → `Promise<AppRecord>`
7286
+ Restore a soft-deleted record. POST /records/:recordId/restore (admin only)
7287
+
7288
+ **upsert**(collectionId: string,
7289
+ appId: string,
7290
+ input: UpsertRecordInput) → `Promise<UpsertRecordResponse>`
7291
+ Upsert a record by ref — creates if no record with that ref exists, otherwise updates. Scope, specificity, and ref are canonicalized on write. POST /records/upsert (admin only)
7292
+
7293
+ **match**(collectionId: string,
7294
+ appId: string,
7295
+ input: MatchRecordsInput,
7296
+ admin: boolean = false) → `Promise<MatchResult>`
7297
+ Match records against a runtime target scope. Returns records whose scope is satisfied by the target, ordered by specificity descending (most specific first). POST /records/match ```ts const { records, best } = await app.records.match(collectionId, appId, { target: { productId: 'prod_abc', facets: { tier: ['gold'] } }, strategy: 'best', recordType: 'nutrition', }, true); // best.nutrition → the single highest-specificity nutrition record ```
7298
+
7299
+ **bulkUpsert**(collectionId: string,
7300
+ appId: string,
7301
+ records: BulkUpsertItem[]) → `Promise<BulkUpsertResult>`
7302
+ Upsert up to 500 records in a single transaction. Each row is individually error-isolated — a failure on one row does not abort the others. POST /records/bulk-upsert (admin only)
7303
+
7304
+ **bulkDelete**(collectionId: string,
7305
+ appId: string,
7306
+ input: BulkDeleteInput) → `Promise<BulkDeleteResult>`
7307
+ Soft-delete records in bulk. Supports two modes: - **refs mode**: explicit list of refs (max 1000) - **scope mode**: delete by scope anchor (productId / variantId / etc.) POST /records/bulk-delete (admin only) ```ts // Refs mode await app.records.bulkDelete(collectionId, appId, { refs: ['product:prod_abc', 'product:prod_xyz'], recordType: 'nutrition', }); // Scope mode await app.records.bulkDelete(collectionId, appId, { scope: { productId: 'prod_abc' }, }); ```
7308
+
7151
7309
  ### app.threads
7152
7310
 
7153
7311
  Conversation-oriented app objects for comments, discussions, Q&A, and reply-driven experiences.