feeef 0.9.1 → 0.9.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.
@@ -1,18 +1,24 @@
1
1
  /**
2
2
  * City Entity
3
3
  *
4
- * Represents a city with composite key (countryCode + stateCode + name).
4
+ * No separate `id` or `code`: identity is **countryCode + stateCode + name**.
5
+ * Use **`name`** (English-normalized) for stored values, shipping payloads, and
6
+ * `<option value>` — not a translated string from `locales`.
5
7
  */
6
8
  export interface CityEntity {
7
9
  /** Country code (part of composite primary key) */
8
10
  countryCode: string;
9
11
  /** State code (part of composite primary key) */
10
12
  stateCode: string;
11
- /** City name (part of composite primary key) */
13
+ /**
14
+ * Canonical English-normalized city name (part of composite primary key).
15
+ * This is the value to persist (`shippingCity`, cart address) and to use as
16
+ * the select value — not `locales.ar` etc.
17
+ */
12
18
  name: string;
13
19
  /** Additional metadata as key-value pairs */
14
20
  metadata: Record<string, any>;
15
- /** Localized names by language code (e.g., { en: "New York", ar: "نيويورك" }) */
21
+ /** Display-only translations keyed by language code (`ar`, `en`, `fr`, ). */
16
22
  locales?: Record<string, string>;
17
23
  /** Creation timestamp */
18
24
  createdAt: any;
@@ -43,6 +43,8 @@ export interface StoreEntity {
43
43
  googleAnalyticsId?: string | null;
44
44
  googleTagsId?: string | null;
45
45
  members?: Record<string, StoreMember>;
46
+ /** Active full-site template (`store_templates.id`) when set. */
47
+ templateId?: string | null;
46
48
  }
47
49
  export declare const generatePublicStoreIntegrations: (integrations: StoreIntegrations | null | undefined) => PublicStoreIntegrations | null;
48
50
  export declare const generatePublicStoreIntegrationCustomFields: (customFields: any | null | undefined) => PublicCustomFieldsIntegration | null | undefined;
@@ -56,6 +58,11 @@ export declare const generatePublicStoreIntegrationTiktokPixel: (tiktokPixel: Ti
56
58
  export declare const generatePublicStoreIntegrationGoogleAnalytics: (googleAnalytics: GoogleAnalyticsIntegration | null | undefined) => PublicGoogleAnalyticsIntegration | null | undefined;
57
59
  export declare const generatePublicStoreIntegrationGoogleSheet: (googleSheet: GoogleSheetsIntegration | null | undefined) => PublicGoogleSheetsIntegration | null | undefined;
58
60
  export declare const generatePublicStoreIntegrationGoogleTags: (googleTags: GoogleTagsIntegration | null | undefined) => PublicGoogleTagsIntegration | null | undefined;
61
+ /**
62
+ * Microsoft Clarity: only the project / tracking id is public (injected in storefront script).
63
+ * Optional apiKey is for Clarity APIs and is never exposed to the public store JSON.
64
+ */
65
+ export declare const generatePublicStoreIntegrationClarity: (clarity: ClarityIntegration | null | undefined) => PublicClarityIntegration | null | undefined;
59
66
  /**
60
67
  * Generates public AI integration data from private integration data.
61
68
  * Only exposes non-sensitive information, keeping the API key private for security.
@@ -134,6 +141,11 @@ export interface PublicGoogleTagsIntegration {
134
141
  id: string;
135
142
  active: boolean;
136
143
  }
144
+ /** Public Clarity data: project id for the tag script only */
145
+ export interface PublicClarityIntegration {
146
+ active: boolean;
147
+ trackingCode: string;
148
+ }
137
149
  export interface PublicAiIntegration {
138
150
  active: boolean;
139
151
  textModel: string;
@@ -180,6 +192,8 @@ export interface PublicStoreIntegrations {
180
192
  googleAnalytics: PublicGoogleAnalyticsIntegration | null;
181
193
  googleSheet: PublicGoogleSheetsIntegration | null;
182
194
  googleTags: PublicGoogleTagsIntegration | null;
195
+ /** Clarity project id for client script only; apiKey is never public */
196
+ clarity: PublicClarityIntegration | null;
183
197
  ai: PublicAiIntegration | null;
184
198
  orderdz: PublicOrderdzIntegration | null;
185
199
  webhooks: PublicWebhooksIntegration | null;
@@ -393,6 +407,18 @@ export interface GoogleTagsIntegration {
393
407
  active: boolean;
394
408
  metadata: Record<string, any>;
395
409
  }
410
+ /**
411
+ * Microsoft Clarity session analytics.
412
+ * trackingCode is the project id (public, used in storefront script).
413
+ * apiKey is optional and used for server-side Clarity APIs only — never sent in publicIntegrations.
414
+ */
415
+ export interface ClarityIntegration {
416
+ active: boolean;
417
+ /** Clarity project id (e.g. wi0wntig7s) */
418
+ trackingCode: string;
419
+ apiKey?: string | null;
420
+ metadata?: Record<string, any>;
421
+ }
396
422
  /**
397
423
  * AI integration configuration for Google AI Studio.
398
424
  */
@@ -615,6 +641,7 @@ export interface StoreIntegrations {
615
641
  googleAnalytics?: GoogleAnalyticsIntegration;
616
642
  googleSheet?: GoogleSheetsIntegration;
617
643
  googleTags?: GoogleTagsIntegration;
644
+ clarity?: ClarityIntegration;
618
645
  ai?: AiIntegration;
619
646
  orderdz?: OrderdzIntegration;
620
647
  webhooks?: WebhooksIntegration;
@@ -0,0 +1,68 @@
1
+ /**
2
+ * Full-site template package (per-store `store_templates` row).
3
+ *
4
+ * Multi-page `data` (TemplateData-shaped) plus `schema` (TemplateSchema-shaped).
5
+ * Same policy/version/catalog patterns as template components, without component `code`.
6
+ */
7
+ import { TemplateComponentPolicy } from './template_component.js';
8
+ /** Reuse the same wire values as `template_components` (`store_templates_policy` matches). */
9
+ export { TemplateComponentPolicy as StoreTemplatePolicy } from './template_component.js';
10
+ export interface StoreTemplateEntity {
11
+ id: string;
12
+ storeId: string;
13
+ userId: string;
14
+ title: string;
15
+ subtitle: string | null;
16
+ body: string | null;
17
+ category: string | null;
18
+ tags: string[];
19
+ imageUrl: string | null;
20
+ screenshots: string[];
21
+ demoUrl: string | null;
22
+ price: number;
23
+ discount: number | null;
24
+ license: string | null;
25
+ /** TemplateSchema-shaped editor/storefront contract. */
26
+ schema: Record<string, unknown>;
27
+ /** TemplateData-shaped site instance data (mirrors `Store.metadata.templateData` when active). */
28
+ data: Record<string, unknown>;
29
+ policy: TemplateComponentPolicy;
30
+ parentId: string | null;
31
+ version: number;
32
+ createdAt: any;
33
+ updatedAt: any | null;
34
+ deletedAt: any | null;
35
+ }
36
+ export interface StoreTemplateCreateInput {
37
+ title: string;
38
+ schema?: Record<string, unknown>;
39
+ data?: Record<string, unknown>;
40
+ policy?: TemplateComponentPolicy;
41
+ subtitle?: string | null;
42
+ body?: string | null;
43
+ category?: string | null;
44
+ tags?: string[];
45
+ imageUrl?: string | null;
46
+ screenshots?: string[];
47
+ demoUrl?: string | null;
48
+ price?: number;
49
+ discount?: number | null;
50
+ license?: string | null;
51
+ parentId?: string | null;
52
+ }
53
+ export interface StoreTemplateUpdateInput {
54
+ title?: string;
55
+ subtitle?: string | null;
56
+ body?: string | null;
57
+ category?: string | null;
58
+ tags?: string[];
59
+ imageUrl?: string | null;
60
+ screenshots?: string[];
61
+ demoUrl?: string | null;
62
+ price?: number;
63
+ discount?: number | null;
64
+ license?: string | null;
65
+ schema?: Record<string, unknown>;
66
+ data?: Record<string, unknown>;
67
+ policy?: TemplateComponentPolicy;
68
+ }
@@ -0,0 +1,153 @@
1
+ /**
2
+ * Template-component library entry.
3
+ *
4
+ * One row in the per-store **library of reusable custom components** that
5
+ * the template editor can drop in by reference instead of inlining
6
+ * `code` + `propsSchema` per instance.
7
+ *
8
+ * Conceptual split:
9
+ * - This entity holds the **identity** of a custom component: the JSX
10
+ * `code`, its `propsSchema` / `slotsSchema`, and seed defaults.
11
+ * - Each placement of the component in a store's `templateData` carries
12
+ * only its instance-level `props` / `slots` and a reference back to
13
+ * this entry by `id`. Editing this entry's `code` therefore updates
14
+ * every reference in one shot.
15
+ *
16
+ * Backed by the Postgres table `template_components`
17
+ * (`backend/database/migrations/.../create_template_components_table.ts`).
18
+ */
19
+ export interface TemplateComponentEntity {
20
+ /** Surrogate primary key (24-char cuid2 from backend `genid()`). */
21
+ id: string;
22
+ /** Owner store. References cascade-delete with the store. */
23
+ storeId: string;
24
+ /** Creator user. Audit field; never null. */
25
+ userId: string;
26
+ title: string;
27
+ /** Short one-liner shown in cards and pickers. */
28
+ subtitle: string | null;
29
+ /** Long markdown body for the entry's detail page. */
30
+ body: string | null;
31
+ /** Free-form taxonomy ('hero' | 'cta' | 'product' | …). */
32
+ category: string | null;
33
+ tags: string[];
34
+ /** Primary preview image (square-ish, 1:1 or 4:3). */
35
+ imageUrl: string | null;
36
+ /** Additional preview images for the marketplace gallery. */
37
+ screenshots: string[];
38
+ /** Optional public demo URL (e.g. a Lithium playground page). */
39
+ demoUrl: string | null;
40
+ /** One-time price in the platform default currency (DZD today). */
41
+ price: number;
42
+ /** Absolute discount in the same currency. Nullable; defaults to 0. */
43
+ discount: number | null;
44
+ /** Free-text license identifier (e.g. 'MIT', 'proprietary'). */
45
+ license: string | null;
46
+ /** JSX source executed by `react-live` in the storefront. */
47
+ code: string;
48
+ /** Editor schema for instance-editable props. */
49
+ propsSchema: Record<string, unknown>;
50
+ /** Editor schema for named slots, when the component supports children. */
51
+ slotsSchema: Record<string, unknown> | null;
52
+ /** Seed values for new instances — instances may override freely. */
53
+ propsDefault: Record<string, unknown>;
54
+ /** Seed slot children for new instances. */
55
+ slotsDefault: Record<string, unknown> | null;
56
+ /** Editor-only responsive layout hint for slots (sm/md/lg). */
57
+ slotsLayout: Record<string, unknown> | null;
58
+ /**
59
+ * Combined audience + lifecycle in a single dimension.
60
+ * See {@link TemplateComponentPolicy} for the precise semantics of
61
+ * each value.
62
+ */
63
+ policy: TemplateComponentPolicy;
64
+ /** Fork tree: id of the entry this one was copied from, if any. */
65
+ parentId: string | null;
66
+ /**
67
+ * Monotonic counter bumped on every meaningful edit.
68
+ * Used as a cache-key suffix and (later) as the pinning target.
69
+ */
70
+ version: number;
71
+ createdAt: any;
72
+ updatedAt: any | null;
73
+ /** Soft-delete marker. Resolver treats deleted entries as missing. */
74
+ deletedAt: any | null;
75
+ }
76
+ /**
77
+ * Combined audience + lifecycle dimension for a library entry.
78
+ *
79
+ * - `private` Owner-only (default). Not shareable, hidden from
80
+ * marketplace and direct-link installs.
81
+ * - `unlisted` Accessible by direct link / install token only;
82
+ * not surfaced in marketplace search.
83
+ * - `public` Discoverable and installable from the marketplace.
84
+ * - `deprecated` Still resolves for existing followers and remains
85
+ * visible in the marketplace with a "deprecated" badge,
86
+ * but new installs are discouraged.
87
+ */
88
+ export declare enum TemplateComponentPolicy {
89
+ private = "private",
90
+ unlisted = "unlisted",
91
+ public = "public",
92
+ deprecated = "deprecated"
93
+ }
94
+ /**
95
+ * Input for creating a new library entry.
96
+ *
97
+ * `storeId` and `userId` are derived server-side from the authenticated
98
+ * request; they are intentionally absent here.
99
+ */
100
+ export interface TemplateComponentCreateInput {
101
+ title: string;
102
+ code: string;
103
+ /** Defaults to `'private'` server-side when omitted. */
104
+ policy?: TemplateComponentPolicy;
105
+ subtitle?: string | null;
106
+ body?: string | null;
107
+ category?: string | null;
108
+ tags?: string[];
109
+ imageUrl?: string | null;
110
+ screenshots?: string[];
111
+ demoUrl?: string | null;
112
+ price?: number;
113
+ discount?: number | null;
114
+ license?: string | null;
115
+ propsSchema?: Record<string, unknown>;
116
+ slotsSchema?: Record<string, unknown> | null;
117
+ propsDefault?: Record<string, unknown>;
118
+ slotsDefault?: Record<string, unknown> | null;
119
+ slotsLayout?: Record<string, unknown> | null;
120
+ /** When forking an existing entry, point back at it for the fork tree. */
121
+ parentId?: string | null;
122
+ }
123
+ /**
124
+ * Input for updating an existing library entry.
125
+ *
126
+ * Per the Node SDK nullability convention:
127
+ * - `undefined` = field unchanged
128
+ * - `null` = clear the nullable field
129
+ *
130
+ * The server bumps `version` automatically when any of `code`,
131
+ * `propsSchema`, `slotsSchema`, `propsDefault`, `slotsDefault`,
132
+ * or `slotsLayout` changes; clients do not send `version`.
133
+ */
134
+ export interface TemplateComponentUpdateInput {
135
+ title?: string;
136
+ subtitle?: string | null;
137
+ body?: string | null;
138
+ category?: string | null;
139
+ tags?: string[];
140
+ imageUrl?: string | null;
141
+ screenshots?: string[];
142
+ demoUrl?: string | null;
143
+ price?: number;
144
+ discount?: number | null;
145
+ license?: string | null;
146
+ code?: string;
147
+ propsSchema?: Record<string, unknown>;
148
+ slotsSchema?: Record<string, unknown> | null;
149
+ propsDefault?: Record<string, unknown>;
150
+ slotsDefault?: Record<string, unknown> | null;
151
+ slotsLayout?: Record<string, unknown> | null;
152
+ policy?: TemplateComponentPolicy;
153
+ }
@@ -20,6 +20,8 @@ import { ProductLandingPageTemplatesRepository } from './repositories/product_la
20
20
  import { ProductLandingPagesRepository } from './repositories/product_landing_pages.js';
21
21
  import { ImagePromptTemplatesRepository } from './repositories/image_prompt_templates.js';
22
22
  import { ImageGenerationsRepository } from './repositories/image_generations.js';
23
+ import { TemplateComponentsRepository } from './repositories/template_components.js';
24
+ import { StoreTemplatesRepository } from './repositories/store_templates.js';
23
25
  import { CartService } from './services/cart.js';
24
26
  import { ActionsService } from './services/actions.js';
25
27
  import { NotificationsService } from './services/notifications.js';
@@ -85,6 +87,19 @@ export declare class FeeeF {
85
87
  * The repository for managing async image generations.
86
88
  */
87
89
  imageGenerations: ImageGenerationsRepository;
90
+ /**
91
+ * The repository for the per-store **library of reusable custom
92
+ * components** + the cross-store **marketplace**. Components live in
93
+ * `template_components` and are referenced from store templateData by
94
+ * `refId` so a single source can power many placements.
95
+ *
96
+ * @see ResolveComponentsResponse for the storefront resolver path.
97
+ */
98
+ templateComponents: TemplateComponentsRepository;
99
+ /**
100
+ * Full-site template library rows (`store_templates`) + marketplace.
101
+ */
102
+ storeTemplates: StoreTemplatesRepository;
88
103
  /**
89
104
  * The repository for managing users.
90
105
  */
@@ -9,7 +9,10 @@ export interface OrderModelTrackOptions {
9
9
  params?: Record<string, any>;
10
10
  }
11
11
  /**
12
- * Schema for sending an order from an anonymous user
12
+ * Body for `POST .../orders/send` (matches backend `SendOrderSchema`).
13
+ *
14
+ * **Do not** use `stateCode`, `cityCode`, or `address` — the API ignores them.
15
+ * Use `shippingState`, `shippingCity`, `shippingAddress` respectively.
13
16
  */
14
17
  export interface SendOrderSchema {
15
18
  id?: string;
@@ -18,8 +21,11 @@ export interface SendOrderSchema {
18
21
  customerPhone: string;
19
22
  customerEmail?: string;
20
23
  source?: string;
24
+ /** Street / address line (not `address`). */
21
25
  shippingAddress?: string;
26
+ /** English-normalized city name (not `cityCode`). */
22
27
  shippingCity?: string;
28
+ /** State wilaya code string, e.g. `"05"` (not `stateCode`). */
23
29
  shippingState?: string;
24
30
  shippingCountry?: string;
25
31
  shippingType: ShippingType;
@@ -0,0 +1,40 @@
1
+ import { AxiosInstance } from 'axios';
2
+ import { ListResponse, ModelRepository } from './repository.js';
3
+ import { StoreTemplateEntity, StoreTemplateCreateInput, StoreTemplateUpdateInput } from '../../core/entities/store_template.js';
4
+ import { TemplateComponentPolicy } from '../../core/entities/template_component.js';
5
+ export interface StoreTemplateListOptions {
6
+ page?: number;
7
+ offset?: number;
8
+ limit?: number;
9
+ storeId?: string;
10
+ q?: string;
11
+ search?: string;
12
+ policy?: TemplateComponentPolicy | TemplateComponentPolicy[];
13
+ category?: string | string[];
14
+ tags?: string | string[];
15
+ parentId?: string;
16
+ filterator?: string | object;
17
+ orderBy?: 'created_at' | 'updated_at' | 'title' | 'price';
18
+ params?: Record<string, unknown>;
19
+ }
20
+ export declare class StoreTemplatesRepository extends ModelRepository<StoreTemplateEntity, StoreTemplateCreateInput, StoreTemplateUpdateInput> {
21
+ constructor(client: AxiosInstance);
22
+ list(options?: StoreTemplateListOptions): Promise<ListResponse<StoreTemplateEntity>>;
23
+ fork(options: {
24
+ fromId: string;
25
+ storeId: string;
26
+ title?: string;
27
+ }): Promise<StoreTemplateEntity>;
28
+ /**
29
+ * Set `stores.template_id` to this template (same row in `store_templates`)
30
+ * and copy `data` into `store.metadata.templateData`. Does not create a new
31
+ * `store_templates` row — use [fork] to duplicate a template into a store.
32
+ */
33
+ install(options: {
34
+ fromId: string;
35
+ storeId: string;
36
+ }): Promise<{
37
+ storeTemplate: StoreTemplateEntity;
38
+ store: Record<string, unknown>;
39
+ }>;
40
+ }
@@ -0,0 +1,86 @@
1
+ import { AxiosInstance } from 'axios';
2
+ import { ListResponse, ModelRepository } from './repository.js';
3
+ import { TemplateComponentEntity, TemplateComponentCreateInput, TemplateComponentUpdateInput, TemplateComponentPolicy } from '../../core/entities/template_component.js';
4
+ /**
5
+ * Filters accepted by `GET /api/v1/template_components`.
6
+ *
7
+ * Two surfaces share the same endpoint:
8
+ * - **Library** — pass `storeId`. Returns all entries the caller has
9
+ * access to under that store (private + unlisted + public + deprecated
10
+ * when authenticated; only the discoverable subset for guests).
11
+ * - **Marketplace** — omit `storeId`. Returns only `policy in
12
+ * (public, deprecated)` across the whole platform.
13
+ *
14
+ * Free-text search and `filterator` are forwarded to the backend's
15
+ * filterator pipeline (`backend/app/models/filters/template_component_filter.ts`).
16
+ * The shape mirrors `ProductsListOptions` so this feels consistent
17
+ * for callers already using other repositories.
18
+ */
19
+ export interface TemplateComponentListOptions {
20
+ page?: number;
21
+ offset?: number;
22
+ limit?: number;
23
+ /** Library mode — scope to one store. Omit for marketplace mode. */
24
+ storeId?: string;
25
+ /** Free-text search across title/subtitle/body/category/tags. */
26
+ q?: string;
27
+ search?: string;
28
+ /** Inclusive policy filter (defaults to all visible). */
29
+ policy?: TemplateComponentPolicy | TemplateComponentPolicy[];
30
+ /** Inclusive category filter. */
31
+ category?: string | string[];
32
+ /** Inclusive tag filter (any-of). */
33
+ tags?: string | string[];
34
+ /** Filter by fork ancestry. */
35
+ parentId?: string;
36
+ /**
37
+ * Raw `filterator` JSON payload. When set, the simple shorthand
38
+ * filters above are merged in so callers can mix-and-match. See
39
+ * the filterator README in the backend for grammar.
40
+ */
41
+ filterator?: string | object;
42
+ orderBy?: 'created_at' | 'updated_at' | 'title' | 'price';
43
+ /** Catch-all for filters this repo doesn't enumerate yet. */
44
+ params?: Record<string, unknown>;
45
+ }
46
+ /**
47
+ * Repository for the per-store **library of reusable custom components**
48
+ * and the cross-store **marketplace** of public ones.
49
+ *
50
+ * On top of the standard CRUD inherited from {@link ModelRepository}, this
51
+ * exposes a {@link fork} action that copies a (typically marketplace) entry
52
+ * into the caller's store with a fresh id and a `parentId` pointing at the
53
+ * source — the "I want full control of this component" escape hatch from
54
+ * the reference model.
55
+ *
56
+ * Note on `version`: never sent on create/update. The server bumps it
57
+ * automatically when one of the meaningful columns (`code`,
58
+ * `propsSchema`, `slotsSchema`, `propsDefault`, `slotsDefault`,
59
+ * `slotsLayout`) changes.
60
+ */
61
+ export declare class TemplateComponentsRepository extends ModelRepository<TemplateComponentEntity, TemplateComponentCreateInput, TemplateComponentUpdateInput> {
62
+ constructor(client: AxiosInstance);
63
+ /**
64
+ * Override `list` to expose the full search/filter surface and accept
65
+ * either the structured options or a raw `filterator` payload.
66
+ */
67
+ list(options?: TemplateComponentListOptions): Promise<ListResponse<TemplateComponentEntity>>;
68
+ /**
69
+ * Fork an existing entry into a target store.
70
+ *
71
+ * Always called against the **source** entry's id (`fromId`). The
72
+ * destination store must be one the caller can `create` in. The new
73
+ * entry starts in `private` — surfacing it requires a follow-up
74
+ * `update`. `parentId` of the fork points at `fromId`, preserving the
75
+ * fork tree for analytics/audit.
76
+ *
77
+ * Optional `title` lets the caller rename at fork time so multiple
78
+ * forks of the same source can coexist in the destination library
79
+ * without collision in the picker.
80
+ */
81
+ fork(options: {
82
+ fromId: string;
83
+ storeId: string;
84
+ title?: string;
85
+ }): Promise<TemplateComponentEntity>;
86
+ }
@@ -1,4 +1,45 @@
1
1
  import { AxiosInstance } from 'axios';
2
+ import { TemplateComponentPolicy } from '../../core/entities/template_component.js';
3
+ /**
4
+ * Slim, render-ready shape returned by `actions/resolveComponents` for a
5
+ * single library entry. The storefront merges these into the template's
6
+ * `reference`-typed placements before rendering.
7
+ *
8
+ * Catalog metadata (subtitle, body, tags, screenshots, …) is intentionally
9
+ * excluded — the resolve endpoint optimizes for cache size and wire weight,
10
+ * and the marketplace UI uses the regular `template_components` REST
11
+ * resource for browsing.
12
+ */
13
+ export interface ResolvedTemplateComponent {
14
+ id: string;
15
+ storeId: string;
16
+ /**
17
+ * Monotonic version (server-managed). Storefronts can use this as a
18
+ * pinning target to detect drift between resolve calls.
19
+ */
20
+ version: number;
21
+ policy: TemplateComponentPolicy;
22
+ title: string;
23
+ /** JSX source consumed by `react-live`. */
24
+ code: string;
25
+ propsSchema: Record<string, unknown>;
26
+ slotsSchema: Record<string, unknown> | null;
27
+ propsDefault: Record<string, unknown>;
28
+ slotsDefault: Record<string, unknown> | null;
29
+ slotsLayout: Record<string, unknown> | null;
30
+ /** Mirror of `policy === 'deprecated'` for cheap rendering hints. */
31
+ deprecated: boolean;
32
+ }
33
+ /**
34
+ * Response shape for `actions/resolveComponents`. `resolved` is keyed by
35
+ * library entry id so the renderer can do an O(1) lookup; `missing` lists
36
+ * ids that did not exist or weren't visible to the caller (the renderer
37
+ * should fall back to a no-op for these).
38
+ */
39
+ export interface ResolveComponentsResponse {
40
+ resolved: Record<string, ResolvedTemplateComponent>;
41
+ missing: string[];
42
+ }
2
43
  /**
3
44
  * Actions service for performing various actions on the Feeef API.
4
45
  * Similar to the Dart Actions class, this provides methods for file uploads,
@@ -28,4 +69,31 @@ export declare class ActionsService {
28
69
  fieldId: string;
29
70
  storeId: string;
30
71
  }>;
72
+ /**
73
+ * Resolve a batch of library `template_components` by id for the
74
+ * storefront / editor renderer.
75
+ *
76
+ * Used by SSR pages that walk the template tree, gather every
77
+ * `reference`-typed placement's `refId`, and need the renderable
78
+ * `{ code, propsSchema, slotsSchema, defaults }` payload before the
79
+ * page can be rendered.
80
+ *
81
+ * Authorization is per-id and happens server-side: same-store entries
82
+ * are always returned; cross-store entries must be `policy in
83
+ * (public, deprecated)`. Anything else is silently dropped into
84
+ * `missing` so the page can render with a fallback (typically a
85
+ * no-op or a "This component is unavailable" placeholder).
86
+ *
87
+ * The response is cached server-side per `(storeId, version)` for 24h
88
+ * and the cache is invalidated automatically on any
89
+ * `template_components` mutation or `Store` update — clients can call
90
+ * this as often as they like without extra coordination.
91
+ *
92
+ * @param storeId - The store identifying the rendering context.
93
+ * @param ids - Library entry ids to resolve. Deduplicated server-side.
94
+ */
95
+ resolveComponents({ storeId, ids, }: {
96
+ storeId: string;
97
+ ids: string[];
98
+ }): Promise<ResolveComponentsResponse>;
31
99
  }
@@ -43,6 +43,20 @@ export declare class CartService extends NotifiableService {
43
43
  private shippingAddress;
44
44
  private cachedSubtotal;
45
45
  private currentItem;
46
+ /**
47
+ * Monotonic counter bumped in {@link CartService.notify} for React
48
+ * `useSyncExternalStore` — lets storefront UI subscribe to cart changes
49
+ * without re-rendering unrelated provider subtrees (see Lithium FeeefCartProvider).
50
+ */
51
+ private _reactSnapshotVersion;
52
+ /**
53
+ * @override
54
+ */
55
+ notify(): void;
56
+ /**
57
+ * Snapshot for React `useSyncExternalStore` (increments on every cart mutation).
58
+ */
59
+ getReactSnapshot(): number;
46
60
  /**
47
61
  * Generates a unique key for a cart item based on product ID, variant path, offer code, and addons
48
62
  * @param item - The cart item to generate a key for
@@ -8,6 +8,8 @@ export * from './core/entities/product_landing_page.js';
8
8
  export * from './core/entities/product_landing_page_template.js';
9
9
  export * from './core/entities/attachment.js';
10
10
  export * from './core/entities/image_prompt_template.js';
11
+ export * from './core/entities/template_component.js';
12
+ export * from './core/entities/store_template.js';
11
13
  export * from './core/entities/image_generation.js';
12
14
  export * from './core/entities/user.js';
13
15
  export * from './core/entities/shipping_method.js';
@@ -33,6 +35,8 @@ export * from './feeef/repositories/products.js';
33
35
  export * from './feeef/repositories/orders.js';
34
36
  export * from './feeef/repositories/image_prompt_templates.js';
35
37
  export * from './feeef/repositories/image_generations.js';
38
+ export * from './feeef/repositories/template_components.js';
39
+ export * from './feeef/repositories/store_templates.js';
36
40
  export * from './feeef/repositories/categories.js';
37
41
  export * from './feeef/repositories/feedbacks.js';
38
42
  export * from './feeef/repositories/countries.js';
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "feeef",
3
3
  "description": "feeef sdk for javascript",
4
- "version": "0.9.1",
4
+ "version": "0.9.3",
5
5
  "main": "build/index.js",
6
6
  "type": "module",
7
7
  "files": [