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.
package/build/index.js CHANGED
@@ -2213,6 +2213,140 @@ var ImageGenerationsRepository = class {
2213
2213
  }
2214
2214
  };
2215
2215
 
2216
+ // src/feeef/repositories/template_components.ts
2217
+ function normalizeFilterator(value) {
2218
+ if (value === void 0 || value === null) return void 0;
2219
+ if (typeof value === "string") return value;
2220
+ return JSON.stringify(value);
2221
+ }
2222
+ function toListResponse2(value) {
2223
+ if (Array.isArray(value)) {
2224
+ return { data: value };
2225
+ }
2226
+ const record = value && typeof value === "object" ? value : {};
2227
+ const meta = record.meta && typeof record.meta === "object" ? record.meta : {};
2228
+ return {
2229
+ data: Array.isArray(record.data) ? record.data : [],
2230
+ total: Number(meta.total ?? 0) || void 0,
2231
+ page: Number(meta.current_page ?? meta.currentPage ?? 0) || void 0,
2232
+ limit: Number(meta.per_page ?? meta.perPage ?? 0) || void 0
2233
+ };
2234
+ }
2235
+ var TemplateComponentsRepository = class extends ModelRepository {
2236
+ constructor(client) {
2237
+ super("template_components", client);
2238
+ }
2239
+ /**
2240
+ * Override `list` to expose the full search/filter surface and accept
2241
+ * either the structured options or a raw `filterator` payload.
2242
+ */
2243
+ async list(options) {
2244
+ const { page, offset, limit, params, filterator, ...filters } = options || {};
2245
+ const res = await this.client.get(`/${this.resource}`, {
2246
+ params: {
2247
+ page,
2248
+ offset,
2249
+ limit,
2250
+ ...filters.storeId ? { storeId: filters.storeId } : {},
2251
+ ...filters.q ? { q: filters.q } : {},
2252
+ ...filters.search ? { search: filters.search } : {},
2253
+ ...filters.policy ? { policy: filters.policy } : {},
2254
+ ...filters.category ? { category: filters.category } : {},
2255
+ ...filters.tags ? { tags: filters.tags } : {},
2256
+ ...filters.parentId ? { parentId: filters.parentId } : {},
2257
+ ...filters.orderBy ? { orderBy: filters.orderBy } : {},
2258
+ ...filterator ? { filterator: normalizeFilterator(filterator) } : {},
2259
+ ...params
2260
+ }
2261
+ });
2262
+ return toListResponse2(res.data);
2263
+ }
2264
+ /**
2265
+ * Fork an existing entry into a target store.
2266
+ *
2267
+ * Always called against the **source** entry's id (`fromId`). The
2268
+ * destination store must be one the caller can `create` in. The new
2269
+ * entry starts in `private` — surfacing it requires a follow-up
2270
+ * `update`. `parentId` of the fork points at `fromId`, preserving the
2271
+ * fork tree for analytics/audit.
2272
+ *
2273
+ * Optional `title` lets the caller rename at fork time so multiple
2274
+ * forks of the same source can coexist in the destination library
2275
+ * without collision in the picker.
2276
+ */
2277
+ async fork(options) {
2278
+ const res = await this.client.post(`/${this.resource}/${options.fromId}/fork`, {
2279
+ storeId: options.storeId,
2280
+ ...options.title ? { title: options.title } : {}
2281
+ });
2282
+ return res.data;
2283
+ }
2284
+ };
2285
+
2286
+ // src/feeef/repositories/store_templates.ts
2287
+ function normalizeFilterator2(value) {
2288
+ if (value === void 0 || value === null) return void 0;
2289
+ if (typeof value === "string") return value;
2290
+ return JSON.stringify(value);
2291
+ }
2292
+ function toListResponse3(value) {
2293
+ if (Array.isArray(value)) {
2294
+ return { data: value };
2295
+ }
2296
+ const record = value && typeof value === "object" ? value : {};
2297
+ const meta = record.meta && typeof record.meta === "object" ? record.meta : {};
2298
+ return {
2299
+ data: Array.isArray(record.data) ? record.data : [],
2300
+ total: Number(meta.total ?? 0) || void 0,
2301
+ page: Number(meta.current_page ?? meta.currentPage ?? 0) || void 0,
2302
+ limit: Number(meta.per_page ?? meta.perPage ?? 0) || void 0
2303
+ };
2304
+ }
2305
+ var StoreTemplatesRepository = class extends ModelRepository {
2306
+ constructor(client) {
2307
+ super("store_templates", client);
2308
+ }
2309
+ async list(options) {
2310
+ const { page, offset, limit, params, filterator, ...filters } = options || {};
2311
+ const res = await this.client.get(`/${this.resource}`, {
2312
+ params: {
2313
+ page,
2314
+ offset,
2315
+ limit,
2316
+ ...filters.storeId ? { storeId: filters.storeId } : {},
2317
+ ...filters.q ? { q: filters.q } : {},
2318
+ ...filters.search ? { search: filters.search } : {},
2319
+ ...filters.policy ? { policy: filters.policy } : {},
2320
+ ...filters.category ? { category: filters.category } : {},
2321
+ ...filters.tags ? { tags: filters.tags } : {},
2322
+ ...filters.parentId ? { parentId: filters.parentId } : {},
2323
+ ...filters.orderBy ? { orderBy: filters.orderBy } : {},
2324
+ ...filterator ? { filterator: normalizeFilterator2(filterator) } : {},
2325
+ ...params
2326
+ }
2327
+ });
2328
+ return toListResponse3(res.data);
2329
+ }
2330
+ async fork(options) {
2331
+ const res = await this.client.post(`/${this.resource}/${options.fromId}/fork`, {
2332
+ storeId: options.storeId,
2333
+ ...options.title ? { title: options.title } : {}
2334
+ });
2335
+ return res.data;
2336
+ }
2337
+ /**
2338
+ * Set `stores.template_id` to this template (same row in `store_templates`)
2339
+ * and copy `data` into `store.metadata.templateData`. Does not create a new
2340
+ * `store_templates` row — use [fork] to duplicate a template into a store.
2341
+ */
2342
+ async install(options) {
2343
+ const res = await this.client.post(`/${this.resource}/${options.fromId}/install`, {
2344
+ storeId: options.storeId
2345
+ });
2346
+ return res.data;
2347
+ }
2348
+ };
2349
+
2216
2350
  // src/core/entities/order.ts
2217
2351
  var OrderStatus = /* @__PURE__ */ ((OrderStatus2) => {
2218
2352
  OrderStatus2["draft"] = "draft";
@@ -2378,6 +2512,25 @@ var CartService = class extends NotifiableService {
2378
2512
  cachedSubtotal = null;
2379
2513
  // Cache for subtotal to avoid redundant calculations
2380
2514
  currentItem = null;
2515
+ /**
2516
+ * Monotonic counter bumped in {@link CartService.notify} for React
2517
+ * `useSyncExternalStore` — lets storefront UI subscribe to cart changes
2518
+ * without re-rendering unrelated provider subtrees (see Lithium FeeefCartProvider).
2519
+ */
2520
+ _reactSnapshotVersion = 0;
2521
+ /**
2522
+ * @override
2523
+ */
2524
+ notify() {
2525
+ this._reactSnapshotVersion++;
2526
+ super.notify();
2527
+ }
2528
+ /**
2529
+ * Snapshot for React `useSyncExternalStore` (increments on every cart mutation).
2530
+ */
2531
+ getReactSnapshot() {
2532
+ return this._reactSnapshotVersion;
2533
+ }
2381
2534
  /**
2382
2535
  * Generates a unique key for a cart item based on product ID, variant path, offer code, and addons
2383
2536
  * @param item - The cart item to generate a key for
@@ -3155,6 +3308,39 @@ var ActionsService = class {
3155
3308
  storeId: response.data.storeId
3156
3309
  };
3157
3310
  }
3311
+ /**
3312
+ * Resolve a batch of library `template_components` by id for the
3313
+ * storefront / editor renderer.
3314
+ *
3315
+ * Used by SSR pages that walk the template tree, gather every
3316
+ * `reference`-typed placement's `refId`, and need the renderable
3317
+ * `{ code, propsSchema, slotsSchema, defaults }` payload before the
3318
+ * page can be rendered.
3319
+ *
3320
+ * Authorization is per-id and happens server-side: same-store entries
3321
+ * are always returned; cross-store entries must be `policy in
3322
+ * (public, deprecated)`. Anything else is silently dropped into
3323
+ * `missing` so the page can render with a fallback (typically a
3324
+ * no-op or a "This component is unavailable" placeholder).
3325
+ *
3326
+ * The response is cached server-side per `(storeId, version)` for 24h
3327
+ * and the cache is invalidated automatically on any
3328
+ * `template_components` mutation or `Store` update — clients can call
3329
+ * this as often as they like without extra coordination.
3330
+ *
3331
+ * @param storeId - The store identifying the rendering context.
3332
+ * @param ids - Library entry ids to resolve. Deduplicated server-side.
3333
+ */
3334
+ async resolveComponents({
3335
+ storeId,
3336
+ ids
3337
+ }) {
3338
+ const response = await this.client.post(
3339
+ "/actions/resolveComponents",
3340
+ { storeId, ids }
3341
+ );
3342
+ return response.data;
3343
+ }
3158
3344
  };
3159
3345
 
3160
3346
  // src/feeef/services/notifications.ts
@@ -3697,6 +3883,19 @@ var FeeeF = class {
3697
3883
  * The repository for managing async image generations.
3698
3884
  */
3699
3885
  imageGenerations;
3886
+ /**
3887
+ * The repository for the per-store **library of reusable custom
3888
+ * components** + the cross-store **marketplace**. Components live in
3889
+ * `template_components` and are referenced from store templateData by
3890
+ * `refId` so a single source can power many placements.
3891
+ *
3892
+ * @see ResolveComponentsResponse for the storefront resolver path.
3893
+ */
3894
+ templateComponents;
3895
+ /**
3896
+ * Full-site template library rows (`store_templates`) + marketplace.
3897
+ */
3898
+ storeTemplates;
3700
3899
  /**
3701
3900
  * The repository for managing users.
3702
3901
  */
@@ -3798,6 +3997,8 @@ var FeeeF = class {
3798
3997
  this.productLandingPageTemplates = new ProductLandingPageTemplatesRepository(this.client);
3799
3998
  this.imagePromptTemplates = new ImagePromptTemplatesRepository(this.client);
3800
3999
  this.imageGenerations = new ImageGenerationsRepository(this.client);
4000
+ this.templateComponents = new TemplateComponentsRepository(this.client);
4001
+ this.storeTemplates = new StoreTemplatesRepository(this.client);
3801
4002
  this.users = new UserRepository(this.client);
3802
4003
  this.apps = new AppRepository(this.client);
3803
4004
  this.oauth = new OAuthRepository(this.client);
@@ -3844,6 +4045,7 @@ var generatePublicStoreIntegrations = (integrations) => {
3844
4045
  tiktokPixel,
3845
4046
  googleAnalytics,
3846
4047
  googleTags,
4048
+ clarity,
3847
4049
  orderdz,
3848
4050
  webhooks,
3849
4051
  ai,
@@ -3856,6 +4058,7 @@ var generatePublicStoreIntegrations = (integrations) => {
3856
4058
  tiktokPixel: generatePublicStoreIntegrationTiktokPixel(tiktokPixel) || null,
3857
4059
  googleAnalytics: generatePublicStoreIntegrationGoogleAnalytics(googleAnalytics) || null,
3858
4060
  googleTags: generatePublicStoreIntegrationGoogleTags(googleTags) || null,
4061
+ clarity: generatePublicStoreIntegrationClarity(clarity) || null,
3859
4062
  googleSheet: null,
3860
4063
  ai: generatePublicStoreIntegrationAi(ai) || null,
3861
4064
  orderdz: generatePublicStoreIntegrationOrderdz(orderdz) || null,
@@ -3929,6 +4132,16 @@ var generatePublicStoreIntegrationGoogleTags = (googleTags) => {
3929
4132
  active
3930
4133
  };
3931
4134
  };
4135
+ var generatePublicStoreIntegrationClarity = (clarity) => {
4136
+ if (!clarity) return null;
4137
+ if (!clarity.active) return null;
4138
+ const code = typeof clarity.trackingCode === "string" ? clarity.trackingCode.trim() : "";
4139
+ if (!code) return null;
4140
+ return {
4141
+ active: true,
4142
+ trackingCode: code
4143
+ };
4144
+ };
3932
4145
  var generatePublicStoreIntegrationAi = (ai) => {
3933
4146
  if (!ai) return null;
3934
4147
  return {
@@ -4127,6 +4340,15 @@ function formatProductLandingPageOrderReference(landingPageId) {
4127
4340
  return `product_landing_page:${landingPageId}`;
4128
4341
  }
4129
4342
 
4343
+ // src/core/entities/template_component.ts
4344
+ var TemplateComponentPolicy = /* @__PURE__ */ ((TemplateComponentPolicy2) => {
4345
+ TemplateComponentPolicy2["private"] = "private";
4346
+ TemplateComponentPolicy2["unlisted"] = "unlisted";
4347
+ TemplateComponentPolicy2["public"] = "public";
4348
+ TemplateComponentPolicy2["deprecated"] = "deprecated";
4349
+ return TemplateComponentPolicy2;
4350
+ })(TemplateComponentPolicy || {});
4351
+
4130
4352
  // src/core/entities/feedback.ts
4131
4353
  var FeedbackStatus = /* @__PURE__ */ ((FeedbackStatus2) => {
4132
4354
  FeedbackStatus2["open"] = "open";
@@ -4783,7 +5005,11 @@ export {
4783
5005
  StoreRepository,
4784
5006
  StoreSubscriptionStatus,
4785
5007
  StoreSubscriptionType,
5008
+ TemplateComponentPolicy as StoreTemplatePolicy,
5009
+ StoreTemplatesRepository,
4786
5010
  Subscription,
5011
+ TemplateComponentPolicy,
5012
+ TemplateComponentsRepository,
4787
5013
  TiktokPixelEvent,
4788
5014
  TransferRepository,
4789
5015
  Transmit2 as Transmit,
@@ -4811,6 +5037,7 @@ export {
4811
5037
  generatePublicIntegrationsDataPaymentMethod,
4812
5038
  generatePublicIntegrationsDataTiktokPixel,
4813
5039
  generatePublicStoreIntegrationAi,
5040
+ generatePublicStoreIntegrationClarity,
4814
5041
  generatePublicStoreIntegrationCustomFields,
4815
5042
  generatePublicStoreIntegrationGoogleAnalytics,
4816
5043
  generatePublicStoreIntegrationGoogleSheet,