@proveanything/smartlinks 1.8.11 → 1.9.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.
@@ -0,0 +1,126 @@
1
+ import type { JsonValue, ProductQueryRequest } from "./product";
2
+ export interface FacetDefinition {
3
+ id?: string;
4
+ orgId?: string;
5
+ collectionId?: string | null;
6
+ key: string;
7
+ name: string;
8
+ description?: string | null;
9
+ cardinality?: "single" | "multi";
10
+ kind?: "system" | "custom";
11
+ hierarchical?: boolean;
12
+ reserved?: boolean;
13
+ enabled?: boolean;
14
+ sortOrder?: number | null;
15
+ config?: Record<string, JsonValue>;
16
+ createdAt?: string;
17
+ updatedAt?: string;
18
+ deletedAt?: string | null;
19
+ values?: FacetValue[];
20
+ }
21
+ export interface FacetValue {
22
+ id?: string;
23
+ orgId?: string;
24
+ collectionId?: string | null;
25
+ facetDefinitionId?: string;
26
+ facetKey: string;
27
+ key: string;
28
+ slug?: string | null;
29
+ name: string;
30
+ shortName?: string | null;
31
+ description?: string | null;
32
+ color?: string | null;
33
+ icon?: string | null;
34
+ image?: Record<string, JsonValue> | null;
35
+ metadata?: Record<string, JsonValue>;
36
+ sortOrder?: number | null;
37
+ parentValueId?: string | null;
38
+ parentValueKey?: string | null;
39
+ enabled?: boolean;
40
+ createdAt?: string;
41
+ updatedAt?: string;
42
+ deletedAt?: string | null;
43
+ count?: number;
44
+ }
45
+ export interface FacetDefinitionWriteInput {
46
+ key?: string;
47
+ name: string;
48
+ description?: string | null;
49
+ cardinality?: "single" | "multi";
50
+ kind?: "system" | "custom";
51
+ hierarchical?: boolean;
52
+ reserved?: boolean;
53
+ enabled?: boolean;
54
+ sortOrder?: number | null;
55
+ config?: Record<string, JsonValue>;
56
+ }
57
+ export interface FacetValueWriteInput {
58
+ key?: string;
59
+ slug?: string | null;
60
+ name: string;
61
+ shortName?: string | null;
62
+ description?: string | null;
63
+ color?: string | null;
64
+ icon?: string | null;
65
+ image?: Record<string, JsonValue> | null;
66
+ metadata?: Record<string, JsonValue>;
67
+ sortOrder?: number | null;
68
+ parentValueKey?: string | null;
69
+ enabled?: boolean;
70
+ }
71
+ export interface FacetListResponse {
72
+ items: FacetDefinition[];
73
+ }
74
+ export interface FacetValueListResponse {
75
+ facet: FacetDefinition;
76
+ items: FacetValue[];
77
+ }
78
+ export interface FacetValueResponse {
79
+ facet: FacetDefinition;
80
+ item: FacetValue;
81
+ }
82
+ export interface FacetQueryRequest {
83
+ facetKeys?: string[];
84
+ includeEmpty?: boolean;
85
+ includeDeleted?: boolean;
86
+ query?: ProductQueryRequest["query"] & {
87
+ facetEquals?: Record<string, JsonValue | JsonValue[]>;
88
+ };
89
+ }
90
+ export interface FacetBucket {
91
+ facetKey: string;
92
+ valueKey: string;
93
+ name?: string;
94
+ count: number;
95
+ }
96
+ export interface FacetQueryResponse {
97
+ items: Array<{
98
+ facet: FacetDefinition;
99
+ values: FacetValue[];
100
+ }>;
101
+ buckets: FacetBucket[];
102
+ meta?: {
103
+ source?: "postgres";
104
+ matchedProducts?: number;
105
+ };
106
+ }
107
+ export interface FacetListParams {
108
+ includeValues?: boolean;
109
+ includeDeleted?: boolean;
110
+ kind?: "system" | "custom";
111
+ reserved?: boolean;
112
+ }
113
+ export interface PublicFacetListParams {
114
+ includeValues?: boolean;
115
+ }
116
+ export interface FacetGetParams {
117
+ includeValues?: boolean;
118
+ includeDeleted?: boolean;
119
+ }
120
+ export interface FacetValueListParams {
121
+ includeDeleted?: boolean;
122
+ }
123
+ export interface FacetValueGetParams {
124
+ includeDeleted?: boolean;
125
+ }
126
+ export type FacetValueDefinition = FacetValue;
@@ -0,0 +1 @@
1
+ export {};
@@ -1,4 +1,5 @@
1
1
  export * from "./collection";
2
+ export * from "./facets";
2
3
  export * from "./product";
3
4
  export * from "./proof";
4
5
  export * from "./appConfiguration";
@@ -30,3 +31,4 @@ export * from "./iframeResponder";
30
31
  export * from "./ai";
31
32
  export * from "./appManifest";
32
33
  export * from "./appObjects";
34
+ export * from "./loyalty";
@@ -1,6 +1,7 @@
1
1
  // src/types/index.ts
2
2
  // Re-export all type modules so consumers can import types directly
3
3
  export * from "./collection";
4
+ export * from "./facets";
4
5
  export * from "./product";
5
6
  export * from "./proof";
6
7
  export * from "./appConfiguration";
@@ -32,3 +33,4 @@ export * from "./iframeResponder";
32
33
  export * from "./ai";
33
34
  export * from "./appManifest";
34
35
  export * from "./appObjects";
36
+ export * from "./loyalty";
@@ -0,0 +1,145 @@
1
+ export type DataBlock = Record<string, unknown>;
2
+ export interface LoyaltyScheme {
3
+ id: string;
4
+ orgId: string;
5
+ collectionId: string;
6
+ name: string;
7
+ /** Open string — e.g. "points" | "stamps" */
8
+ type: string;
9
+ active: boolean;
10
+ createdAt: string;
11
+ updatedAt: string;
12
+ deletedAt: string | null;
13
+ data: DataBlock;
14
+ /** Admin responses only */
15
+ owner?: DataBlock;
16
+ /** Admin responses only */
17
+ admin?: DataBlock;
18
+ }
19
+ export interface LoyaltyMember {
20
+ id: string;
21
+ orgId: string;
22
+ collectionId: string;
23
+ schemeId: string;
24
+ contactId: string;
25
+ userId: string | null;
26
+ /** Current redeemable balance */
27
+ balance: number;
28
+ /** Total ever earned — never decremented, used for tier calculations */
29
+ lifetimePoints: number;
30
+ createdAt: string;
31
+ updatedAt: string;
32
+ data: DataBlock;
33
+ /** Admin responses only */
34
+ owner?: DataBlock;
35
+ /** Admin responses only */
36
+ admin?: DataBlock;
37
+ }
38
+ export interface LoyaltyTransaction {
39
+ id: string;
40
+ orgId: string;
41
+ collectionId: string;
42
+ schemeId: string;
43
+ memberId: string;
44
+ /** Signed: positive = earn, negative = spend/deduct */
45
+ points: number;
46
+ reason: string | null;
47
+ /** Caller-supplied key — prevents double-credit on retries */
48
+ idempotencyKey: string | null;
49
+ metadata: DataBlock;
50
+ createdAt: string;
51
+ }
52
+ export interface LoyaltyEarningRule {
53
+ id: string;
54
+ orgId: string;
55
+ collectionId: string;
56
+ schemeId: string;
57
+ /** ID of the Interaction definition that triggers this rule */
58
+ interactionId: string;
59
+ /** Points awarded when this rule matches — always server-controlled */
60
+ points: number;
61
+ /**
62
+ * Key-value conditions matched against the interaction event before awarding.
63
+ * Supports top-level event fields (outcome, scope, status, eventType, etc.)
64
+ * and dot-path into metadata (e.g. `"metadata.tier": "gold"`).
65
+ * Empty object = always fires for any event on this interaction.
66
+ */
67
+ conditions: Record<string, string>;
68
+ /** Maximum lifetime triggers per contact. null = unlimited */
69
+ maxPerContact: number | null;
70
+ /** Minimum hours between triggers for the same contact. null = no cooldown */
71
+ cooldownHours: number | null;
72
+ active: boolean;
73
+ createdAt: string;
74
+ updatedAt: string;
75
+ data: DataBlock;
76
+ }
77
+ /**
78
+ * Returned by loyalty.getMe() — each active scheme with the caller's
79
+ * membership embedded. member is null if the caller has never earned
80
+ * points in that scheme.
81
+ */
82
+ export interface LoyaltySchemeWithMembership extends Omit<LoyaltyScheme, 'owner' | 'admin'> {
83
+ member: Omit<LoyaltyMember, 'owner' | 'admin'> | null;
84
+ }
85
+ /** Returned by loyalty.admin.recordTransaction() */
86
+ export interface LoyaltyTransactionResult {
87
+ member: LoyaltyMember;
88
+ transaction: LoyaltyTransaction;
89
+ }
90
+ export interface LoyaltyPaginationParams {
91
+ limit?: number;
92
+ offset?: number;
93
+ }
94
+ export interface LoyaltyPaginatedResult<T> {
95
+ items: T[];
96
+ limit: number;
97
+ offset: number;
98
+ }
99
+ export interface CreateLoyaltySchemeBody {
100
+ name: string;
101
+ type: string;
102
+ active?: boolean;
103
+ data?: DataBlock;
104
+ owner?: DataBlock;
105
+ admin?: DataBlock;
106
+ }
107
+ export interface UpdateLoyaltySchemeBody {
108
+ name?: string;
109
+ type?: string;
110
+ active?: boolean;
111
+ data?: DataBlock;
112
+ owner?: DataBlock;
113
+ admin?: DataBlock;
114
+ }
115
+ export interface CreateLoyaltyEarningRuleBody {
116
+ interactionId: string;
117
+ points: number;
118
+ conditions?: Record<string, string>;
119
+ maxPerContact?: number | null;
120
+ cooldownHours?: number | null;
121
+ active?: boolean;
122
+ data?: DataBlock;
123
+ }
124
+ export interface UpdateLoyaltyEarningRuleBody {
125
+ points?: number;
126
+ conditions?: Record<string, string>;
127
+ maxPerContact?: number | null;
128
+ cooldownHours?: number | null;
129
+ active?: boolean;
130
+ data?: DataBlock;
131
+ }
132
+ export interface RecordLoyaltyTransactionBody {
133
+ /** Non-zero signed integer. Positive = earn, negative = spend/deduct */
134
+ points: number;
135
+ reason?: string;
136
+ /**
137
+ * Optional caller-supplied key scoped to the scheme.
138
+ * If a transaction with this key already exists the server returns 409.
139
+ * Use to safely retry without double-crediting points.
140
+ */
141
+ idempotencyKey?: string;
142
+ metadata?: DataBlock;
143
+ /** Links the auto-created member to a Firebase UID if not yet associated */
144
+ userId?: string;
145
+ }
@@ -0,0 +1,2 @@
1
+ // src/types/loyalty.ts
2
+ export {};
@@ -1,56 +1,169 @@
1
- /**
2
- * Product domain model.
3
- */
4
- export interface Product {
5
- /** Unique identifier for the product */
6
- id: string;
7
- /** Name of the product */
8
- name: string;
9
- /** Unique identifier for the product's collection */
1
+ export type JsonPrimitive = string | number | boolean | null;
2
+ export type JsonValue = JsonPrimitive | JsonValue[] | {
3
+ [key: string]: JsonValue;
4
+ };
5
+ export type ISODateString = string;
6
+ export interface ProductKey {
10
7
  collectionId: string;
11
- /** Detailed description of the product */
12
- description: string;
13
- /** A product GTIN (Global Trade Item Number) */
14
- gtin?: string;
15
- /** An optional product type from the standard smartlinks types */
8
+ id: string;
9
+ }
10
+ export interface ProductImageThumbnails {
11
+ x100?: string;
12
+ x200?: string;
13
+ x512?: string;
14
+ }
15
+ export interface ProductImage {
16
+ id?: string;
17
+ collectionId?: string;
18
+ productId?: string;
19
+ site?: string;
20
+ name?: string;
21
+ cleanName?: string;
22
+ assetType?: string;
16
23
  type?: string;
17
- /**
18
- * Hero image asset object.
19
- * When creating/updating, you can pass either:
20
- * - A full asset object with url and thumbnails
21
- * - A string URL - the system will automatically fetch and store the image
22
- */
23
- heroImage: {
24
- /** URL to the asset */
25
- url: string;
26
- /** Thumbnail URLs in different sizes */
27
- thumbnails: {
28
- x100: string;
29
- x200: string;
30
- x512: string;
31
- };
24
+ url?: string;
25
+ thumbnails?: ProductImageThumbnails;
26
+ contentType?: string;
27
+ size?: string | number;
28
+ hash?: string;
29
+ createdAt?: ISODateString | null;
30
+ updatedAt?: ISODateString | null;
31
+ deletedAt?: ISODateString | null;
32
+ }
33
+ export interface ProductImageUrlInput {
34
+ url: string;
35
+ }
36
+ export interface AdditionalGtin {
37
+ gtin: string;
38
+ owner?: boolean | null;
39
+ }
40
+ export interface ProductFacetValue {
41
+ id?: string;
42
+ key: string;
43
+ slug?: string;
44
+ name: string;
45
+ shortName?: string;
46
+ description?: string;
47
+ color?: string;
48
+ icon?: string;
49
+ }
50
+ export interface ProductFacetMap {
51
+ [facetKey: string]: ProductFacetValue[];
52
+ }
53
+ export interface ProductQueryRequest {
54
+ query?: {
55
+ search?: string;
56
+ status?: string[];
57
+ category?: string[];
58
+ type?: string[];
59
+ schemaType?: string[];
60
+ tags?: string[];
61
+ productIds?: string[];
62
+ sku?: string;
63
+ gtin?: string;
64
+ updatedAfter?: ISODateString;
65
+ updatedBefore?: ISODateString;
66
+ createdAfter?: ISODateString;
67
+ createdBefore?: ISODateString;
68
+ facetEquals?: Record<string, JsonValue>;
32
69
  };
33
- /** Flexible map of tags with true/false values */
34
- tags: {
35
- [tagName: string]: boolean;
70
+ sort?: Array<{
71
+ field: string;
72
+ direction: 'asc' | 'desc';
73
+ }>;
74
+ page?: {
75
+ limit?: number;
76
+ offset?: number;
77
+ cursor?: string | null;
36
78
  };
37
- /** Flexible key/value data map */
38
- data: {
39
- [key: string]: any;
79
+ includeDeleted?: boolean;
80
+ }
81
+ export interface ProductAdminData extends Record<string, JsonValue | undefined> {
82
+ allowAutoGenerateClaims?: boolean;
83
+ lastSerialId?: number;
84
+ }
85
+ export interface Product extends ProductKey {
86
+ orgId?: string | null;
87
+ name: string;
88
+ description?: string | null;
89
+ gtin?: string | null;
90
+ ownGtin?: boolean | null;
91
+ additionalGtins?: AdditionalGtin[];
92
+ sku?: string | null;
93
+ schemaType?: string | null;
94
+ type?: string | null;
95
+ category?: string | null;
96
+ label?: string | null;
97
+ status?: string | null;
98
+ sortOrder?: number | null;
99
+ heroImage?: ProductImage | null;
100
+ facets?: ProductFacetMap;
101
+ tags?: Record<string, boolean>;
102
+ data?: Record<string, JsonValue>;
103
+ admin?: ProductAdminData;
104
+ extra?: Record<string, JsonValue>;
105
+ validCollections?: string[];
106
+ group?: boolean | null;
107
+ createdAt?: ISODateString | null;
108
+ updatedAt?: ISODateString | null;
109
+ deletedAt?: ISODateString | null;
110
+ }
111
+ export interface PublicProduct extends Omit<Product, 'admin'> {
112
+ admin?: never;
113
+ }
114
+ export interface ProductWriteInput {
115
+ id?: string;
116
+ name: string;
117
+ description?: string | null;
118
+ gtin?: string | null;
119
+ ownGtin?: boolean | null;
120
+ additionalGtins?: AdditionalGtin[];
121
+ sku?: string | null;
122
+ schemaType?: string | null;
123
+ type?: string | null;
124
+ category?: string | null;
125
+ label?: string | null;
126
+ status?: string | null;
127
+ sortOrder?: number | null;
128
+ heroImage?: ProductImage | ProductImageUrlInput | string | null;
129
+ facets?: ProductFacetMap;
130
+ tags?: Record<string, boolean>;
131
+ data?: Record<string, JsonValue>;
132
+ admin?: ProductAdminData;
133
+ extra?: Record<string, JsonValue>;
134
+ validCollections?: string[];
135
+ }
136
+ export interface ProductQueryResponse {
137
+ items: Product[];
138
+ page?: {
139
+ limit?: number;
140
+ offset?: number;
141
+ returned?: number;
142
+ total?: number;
143
+ hasMore?: boolean;
144
+ nextCursor?: string | null;
40
145
  };
41
- /** Admin-only configuration */
42
- admin?: {
43
- /** Allow users to claim this product without providing a proof ID (overrides collection setting) */
44
- allowAutoGenerateClaims?: boolean;
45
- /** Last generated serial ID for auto-claim functionality */
46
- lastSerialId?: number;
47
- [key: string]: any;
146
+ meta?: {
147
+ apiVersion?: 'v1';
148
+ mode?: 'canonical-products' | 'legacy-product-compatibility';
149
+ source?: 'postgres' | 'firestore' | 'compatibility-layer';
150
+ queryMode?: 'canonical' | 'compatibility';
151
+ unsupportedFilters?: string[];
152
+ supportedSortFields?: string[];
48
153
  };
49
154
  }
155
+ export interface ProductClaimLookupInput extends ProductKey {
156
+ claimId: string;
157
+ }
158
+ export interface ProductClaimCreateInput extends ProductKey {
159
+ claimId: string;
160
+ email?: string;
161
+ name?: string;
162
+ emailConfirmation?: boolean;
163
+ data?: Record<string, JsonValue>;
164
+ options?: Record<string, JsonValue>;
165
+ }
166
+ export type ProductClaimCreateRequestBody = Omit<ProductClaimCreateInput, 'collectionId' | 'id'>;
50
167
  export type ProductResponse = Product;
51
- export type ProductCreateRequest = Omit<Product, 'id' | 'collectionId'> & {
52
- heroImage?: Product['heroImage'] | string;
53
- };
54
- export type ProductUpdateRequest = Partial<Omit<Product, 'id' | 'collectionId'>> & {
55
- heroImage?: Product['heroImage'] | string;
56
- };
168
+ export type ProductCreateRequest = ProductWriteInput;
169
+ export type ProductUpdateRequest = Partial<Omit<ProductWriteInput, 'id'>>;
@@ -60,6 +60,7 @@
60
60
  * ```
61
61
  */
62
62
  export function buildPortalPath(params) {
63
+ var _a, _b;
63
64
  const { collection, product, productId, batch, batchId, variant, proof, queryParams = {}, pathOnly = false } = params;
64
65
  // Extract values from collection
65
66
  const shortId = collection.shortId;
@@ -70,9 +71,9 @@ export function buildPortalPath(params) {
70
71
  let extractedProductId;
71
72
  if (product) {
72
73
  extractedProductId = product.id;
73
- gtin = product.gtin;
74
+ gtin = (_a = product.gtin) !== null && _a !== void 0 ? _a : undefined;
74
75
  // ownGtin is a critical product setting - only read from product, never override
75
- ownGtin = 'ownGtin' in product ? product.ownGtin : undefined;
76
+ ownGtin = 'ownGtin' in product ? (_b = product.ownGtin) !== null && _b !== void 0 ? _b : undefined : undefined;
76
77
  }
77
78
  else if (productId) {
78
79
  extractedProductId = productId;