@infuro/cms-core 1.0.42 → 1.0.44

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/dist/api.cjs CHANGED
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var chunkGINYYPXK_cjs = require('./chunk-GINYYPXK.cjs');
3
+ var chunkP2IWWBJV_cjs = require('./chunk-P2IWWBJV.cjs');
4
4
  require('./chunk-22FFHLTO.cjs');
5
5
  require('./chunk-UCKN4BBY.cjs');
6
6
  require('./chunk-7NMT3GBR.cjs');
@@ -20,127 +20,127 @@ require('./chunk-USNT2KNT.cjs');
20
20
 
21
21
  Object.defineProperty(exports, "createAnalyticsHandlers", {
22
22
  enumerable: true,
23
- get: function () { return chunkGINYYPXK_cjs.createAnalyticsHandlers; }
23
+ get: function () { return chunkP2IWWBJV_cjs.createAnalyticsHandlers; }
24
24
  });
25
25
  Object.defineProperty(exports, "createBlogBySlugHandler", {
26
26
  enumerable: true,
27
- get: function () { return chunkGINYYPXK_cjs.createBlogBySlugHandler; }
27
+ get: function () { return chunkP2IWWBJV_cjs.createBlogBySlugHandler; }
28
28
  });
29
29
  Object.defineProperty(exports, "createChangePasswordHandler", {
30
30
  enumerable: true,
31
- get: function () { return chunkGINYYPXK_cjs.createChangePasswordHandler; }
31
+ get: function () { return chunkP2IWWBJV_cjs.createChangePasswordHandler; }
32
32
  });
33
33
  Object.defineProperty(exports, "createCmsApiHandler", {
34
34
  enumerable: true,
35
- get: function () { return chunkGINYYPXK_cjs.createCmsApiHandler; }
35
+ get: function () { return chunkP2IWWBJV_cjs.createCmsApiHandler; }
36
36
  });
37
37
  Object.defineProperty(exports, "createCrudByIdHandler", {
38
38
  enumerable: true,
39
- get: function () { return chunkGINYYPXK_cjs.createCrudByIdHandler; }
39
+ get: function () { return chunkP2IWWBJV_cjs.createCrudByIdHandler; }
40
40
  });
41
41
  Object.defineProperty(exports, "createCrudHandler", {
42
42
  enumerable: true,
43
- get: function () { return chunkGINYYPXK_cjs.createCrudHandler; }
43
+ get: function () { return chunkP2IWWBJV_cjs.createCrudHandler; }
44
44
  });
45
45
  Object.defineProperty(exports, "createDashboardStatsHandler", {
46
46
  enumerable: true,
47
- get: function () { return chunkGINYYPXK_cjs.createDashboardStatsHandler; }
47
+ get: function () { return chunkP2IWWBJV_cjs.createDashboardStatsHandler; }
48
48
  });
49
49
  Object.defineProperty(exports, "createEcommerceAnalyticsHandler", {
50
50
  enumerable: true,
51
- get: function () { return chunkGINYYPXK_cjs.createEcommerceAnalyticsHandler; }
51
+ get: function () { return chunkP2IWWBJV_cjs.createEcommerceAnalyticsHandler; }
52
52
  });
53
53
  Object.defineProperty(exports, "createForgotPasswordHandler", {
54
54
  enumerable: true,
55
- get: function () { return chunkGINYYPXK_cjs.createForgotPasswordHandler; }
55
+ get: function () { return chunkP2IWWBJV_cjs.createForgotPasswordHandler; }
56
56
  });
57
57
  Object.defineProperty(exports, "createFormBySlugHandler", {
58
58
  enumerable: true,
59
- get: function () { return chunkGINYYPXK_cjs.createFormBySlugHandler; }
59
+ get: function () { return chunkP2IWWBJV_cjs.createFormBySlugHandler; }
60
60
  });
61
61
  Object.defineProperty(exports, "createInviteAcceptHandler", {
62
62
  enumerable: true,
63
- get: function () { return chunkGINYYPXK_cjs.createInviteAcceptHandler; }
63
+ get: function () { return chunkP2IWWBJV_cjs.createInviteAcceptHandler; }
64
64
  });
65
65
  Object.defineProperty(exports, "createJobScheduleHandlers", {
66
66
  enumerable: true,
67
- get: function () { return chunkGINYYPXK_cjs.createJobScheduleHandlers; }
67
+ get: function () { return chunkP2IWWBJV_cjs.createJobScheduleHandlers; }
68
68
  });
69
69
  Object.defineProperty(exports, "createLlmAgentKnowledgeHandlers", {
70
70
  enumerable: true,
71
- get: function () { return chunkGINYYPXK_cjs.createLlmAgentKnowledgeHandlers; }
71
+ get: function () { return chunkP2IWWBJV_cjs.createLlmAgentKnowledgeHandlers; }
72
72
  });
73
73
  Object.defineProperty(exports, "createMediaZipExtractHandler", {
74
74
  enumerable: true,
75
- get: function () { return chunkGINYYPXK_cjs.createMediaZipExtractHandler; }
75
+ get: function () { return chunkP2IWWBJV_cjs.createMediaZipExtractHandler; }
76
76
  });
77
77
  Object.defineProperty(exports, "createSetPasswordHandler", {
78
78
  enumerable: true,
79
- get: function () { return chunkGINYYPXK_cjs.createSetPasswordHandler; }
79
+ get: function () { return chunkP2IWWBJV_cjs.createSetPasswordHandler; }
80
80
  });
81
81
  Object.defineProperty(exports, "createSettingsApiHandlers", {
82
82
  enumerable: true,
83
- get: function () { return chunkGINYYPXK_cjs.createSettingsApiHandlers; }
83
+ get: function () { return chunkP2IWWBJV_cjs.createSettingsApiHandlers; }
84
84
  });
85
85
  Object.defineProperty(exports, "createStorefrontApiHandler", {
86
86
  enumerable: true,
87
- get: function () { return chunkGINYYPXK_cjs.createStorefrontApiHandler; }
87
+ get: function () { return chunkP2IWWBJV_cjs.createStorefrontApiHandler; }
88
88
  });
89
89
  Object.defineProperty(exports, "createUploadHandler", {
90
90
  enumerable: true,
91
- get: function () { return chunkGINYYPXK_cjs.createUploadHandler; }
91
+ get: function () { return chunkP2IWWBJV_cjs.createUploadHandler; }
92
92
  });
93
93
  Object.defineProperty(exports, "createUserAuthApiRouter", {
94
94
  enumerable: true,
95
- get: function () { return chunkGINYYPXK_cjs.createUserAuthApiRouter; }
95
+ get: function () { return chunkP2IWWBJV_cjs.createUserAuthApiRouter; }
96
96
  });
97
97
  Object.defineProperty(exports, "createUserAvatarHandler", {
98
98
  enumerable: true,
99
- get: function () { return chunkGINYYPXK_cjs.createUserAvatarHandler; }
99
+ get: function () { return chunkP2IWWBJV_cjs.createUserAvatarHandler; }
100
100
  });
101
101
  Object.defineProperty(exports, "createUserProfileHandler", {
102
102
  enumerable: true,
103
- get: function () { return chunkGINYYPXK_cjs.createUserProfileHandler; }
103
+ get: function () { return chunkP2IWWBJV_cjs.createUserProfileHandler; }
104
104
  });
105
105
  Object.defineProperty(exports, "createUsersApiHandlers", {
106
106
  enumerable: true,
107
- get: function () { return chunkGINYYPXK_cjs.createUsersApiHandlers; }
107
+ get: function () { return chunkP2IWWBJV_cjs.createUsersApiHandlers; }
108
108
  });
109
109
  Object.defineProperty(exports, "createVendorDashboardHandler", {
110
110
  enumerable: true,
111
- get: function () { return chunkGINYYPXK_cjs.createVendorDashboardHandler; }
111
+ get: function () { return chunkP2IWWBJV_cjs.createVendorDashboardHandler; }
112
112
  });
113
113
  Object.defineProperty(exports, "createVendorOnboardHandlers", {
114
114
  enumerable: true,
115
- get: function () { return chunkGINYYPXK_cjs.createVendorOnboardHandlers; }
115
+ get: function () { return chunkP2IWWBJV_cjs.createVendorOnboardHandlers; }
116
116
  });
117
117
  Object.defineProperty(exports, "getPublicSettingsGroup", {
118
118
  enumerable: true,
119
- get: function () { return chunkGINYYPXK_cjs.getPublicSettingsGroup; }
119
+ get: function () { return chunkP2IWWBJV_cjs.getPublicSettingsGroup; }
120
120
  });
121
121
  Object.defineProperty(exports, "mergeGuardrailsIntoSystemPrompt", {
122
122
  enumerable: true,
123
- get: function () { return chunkGINYYPXK_cjs.mergeGuardrailsIntoSystemPrompt; }
123
+ get: function () { return chunkP2IWWBJV_cjs.mergeGuardrailsIntoSystemPrompt; }
124
124
  });
125
125
  Object.defineProperty(exports, "parseLlmAgentValidationRules", {
126
126
  enumerable: true,
127
- get: function () { return chunkGINYYPXK_cjs.parseLlmAgentValidationRules; }
127
+ get: function () { return chunkP2IWWBJV_cjs.parseLlmAgentValidationRules; }
128
128
  });
129
129
  Object.defineProperty(exports, "simpleDecrypt", {
130
130
  enumerable: true,
131
- get: function () { return chunkGINYYPXK_cjs.simpleDecrypt; }
131
+ get: function () { return chunkP2IWWBJV_cjs.simpleDecrypt; }
132
132
  });
133
133
  Object.defineProperty(exports, "simpleEncrypt", {
134
134
  enumerable: true,
135
- get: function () { return chunkGINYYPXK_cjs.simpleEncrypt; }
135
+ get: function () { return chunkP2IWWBJV_cjs.simpleEncrypt; }
136
136
  });
137
137
  Object.defineProperty(exports, "validateUserMessageAgainstAgentRules", {
138
138
  enumerable: true,
139
- get: function () { return chunkGINYYPXK_cjs.validateUserMessageAgainstAgentRules; }
139
+ get: function () { return chunkP2IWWBJV_cjs.validateUserMessageAgainstAgentRules; }
140
140
  });
141
141
  Object.defineProperty(exports, "validateUserMessageAgainstStructuredRules", {
142
142
  enumerable: true,
143
- get: function () { return chunkGINYYPXK_cjs.validateUserMessageAgainstStructuredRules; }
143
+ get: function () { return chunkP2IWWBJV_cjs.validateUserMessageAgainstStructuredRules; }
144
144
  });
145
145
  Object.defineProperty(exports, "createCmsAuthBundle", {
146
146
  enumerable: true,
package/dist/api.js CHANGED
@@ -1,4 +1,4 @@
1
- export { createAnalyticsHandlers, createBlogBySlugHandler, createChangePasswordHandler, createCmsApiHandler, createCrudByIdHandler, createCrudHandler, createDashboardStatsHandler, createEcommerceAnalyticsHandler, createForgotPasswordHandler, createFormBySlugHandler, createInviteAcceptHandler, createJobScheduleHandlers, createLlmAgentKnowledgeHandlers, createMediaZipExtractHandler, createSetPasswordHandler, createSettingsApiHandlers, createStorefrontApiHandler, createUploadHandler, createUserAuthApiRouter, createUserAvatarHandler, createUserProfileHandler, createUsersApiHandlers, createVendorDashboardHandler, createVendorOnboardHandlers, getPublicSettingsGroup, mergeGuardrailsIntoSystemPrompt, parseLlmAgentValidationRules, simpleDecrypt, simpleEncrypt, validateUserMessageAgainstAgentRules, validateUserMessageAgainstStructuredRules } from './chunk-W2NL365N.js';
1
+ export { createAnalyticsHandlers, createBlogBySlugHandler, createChangePasswordHandler, createCmsApiHandler, createCrudByIdHandler, createCrudHandler, createDashboardStatsHandler, createEcommerceAnalyticsHandler, createForgotPasswordHandler, createFormBySlugHandler, createInviteAcceptHandler, createJobScheduleHandlers, createLlmAgentKnowledgeHandlers, createMediaZipExtractHandler, createSetPasswordHandler, createSettingsApiHandlers, createStorefrontApiHandler, createUploadHandler, createUserAuthApiRouter, createUserAvatarHandler, createUserProfileHandler, createUsersApiHandlers, createVendorDashboardHandler, createVendorOnboardHandlers, getPublicSettingsGroup, mergeGuardrailsIntoSystemPrompt, parseLlmAgentValidationRules, simpleDecrypt, simpleEncrypt, validateUserMessageAgainstAgentRules, validateUserMessageAgainstStructuredRules } from './chunk-SQGBHYJF.js';
2
2
  import './chunk-NNQBWDCI.js';
3
3
  import './chunk-HCIRL37O.js';
4
4
  import './chunk-JXF23MPG.js';
@@ -462,6 +462,41 @@ function applyApprovalStatusSideEffects(updatePayload, opts) {
462
462
  }
463
463
  }
464
464
  chunkUSNT2KNT_cjs.__name(applyApprovalStatusSideEffects, "applyApprovalStatusSideEffects");
465
+ async function syncProductVariantsStatusWithProduct(dataSource, entityMap, productId, productStatus) {
466
+ if (!entityMap.product_variants || !Number.isFinite(productId) || productId < 1) return;
467
+ const status = String(productStatus || "draft");
468
+ const repo = dataSource.getRepository(entityMap.product_variants);
469
+ if (status === "available") {
470
+ await repo.createQueryBuilder().update().set({
471
+ status: "available"
472
+ }).where('"productId" = :productId', {
473
+ productId
474
+ }).andWhere("status = :from", {
475
+ from: "draft"
476
+ }).execute();
477
+ return;
478
+ }
479
+ if (status === "draft") {
480
+ await repo.createQueryBuilder().update().set({
481
+ status: "draft"
482
+ }).where('"productId" = :productId', {
483
+ productId
484
+ }).andWhere("status = :from", {
485
+ from: "available"
486
+ }).execute();
487
+ }
488
+ }
489
+ chunkUSNT2KNT_cjs.__name(syncProductVariantsStatusWithProduct, "syncProductVariantsStatusWithProduct");
490
+ function coerceVariantStatusForProduct(variantStatus, productStatus, opts) {
491
+ const next = String(variantStatus ?? "draft").trim() || "draft";
492
+ const productLive = String(productStatus ?? "draft") === "available";
493
+ const approvalOk = !opts?.requireApproval || String(opts?.approvalStatus ?? "") === "approved";
494
+ if (!productLive || !approvalOk) {
495
+ return "draft";
496
+ }
497
+ return next;
498
+ }
499
+ chunkUSNT2KNT_cjs.__name(coerceVariantStatusForProduct, "coerceVariantStatusForProduct");
465
500
 
466
501
  // src/lib/event-approval.ts
467
502
  var EVENT_APPROVAL_STATUSES = [
@@ -4604,6 +4639,26 @@ function createCrudHandler(dataSource, entityMap, options) {
4604
4639
  }
4605
4640
  }
4606
4641
  }
4642
+ if (resource === "product_variants" && entityMap.products) {
4643
+ const productIdRaw = persistBody.productId;
4644
+ const productId = typeof productIdRaw === "number" ? productIdRaw : typeof productIdRaw === "string" && /^\d+$/.test(productIdRaw) ? parseInt(productIdRaw, 10) : NaN;
4645
+ if (Number.isFinite(productId)) {
4646
+ const parent = await dataSource.getRepository(entityMap.products).findOne({
4647
+ where: {
4648
+ id: productId
4649
+ }
4650
+ });
4651
+ const parentStatus = parent?.status;
4652
+ const parentApproval = parent?.approvalStatus;
4653
+ const requireApproval = await getRequireProductApproval(dataSource);
4654
+ persistBody.status = coerceVariantStatusForProduct(persistBody.status, parentStatus, {
4655
+ approvalStatus: parentApproval,
4656
+ requireApproval
4657
+ });
4658
+ } else if (!("status" in persistBody)) {
4659
+ persistBody.status = "draft";
4660
+ }
4661
+ }
4607
4662
  if (resource === "products") {
4608
4663
  const scopeForProduct = await resolveScope();
4609
4664
  const productFlags = await getVendorCatalogCreateFlags(dataSource);
@@ -6243,6 +6298,34 @@ function createCrudByIdHandler(dataSource, entityMap, options) {
6243
6298
  delete u.parentId;
6244
6299
  }
6245
6300
  }
6301
+ if (resource === "product_variants" && entityMap.products) {
6302
+ const currentVariant = await repo.findOne({
6303
+ where: {
6304
+ id: numericId
6305
+ }
6306
+ });
6307
+ if (!currentVariant) return json({
6308
+ message: "Not found"
6309
+ }, {
6310
+ status: 404
6311
+ });
6312
+ const productId = "productId" in updatePayload && updatePayload.productId != null ? Number(updatePayload.productId) : Number(currentVariant.productId);
6313
+ if (Number.isFinite(productId)) {
6314
+ const parent = await dataSource.getRepository(entityMap.products).findOne({
6315
+ where: {
6316
+ id: productId
6317
+ }
6318
+ });
6319
+ const parentStatus = parent?.status;
6320
+ const parentApproval = parent?.approvalStatus;
6321
+ const requireApproval = await getRequireProductApproval(dataSource);
6322
+ const nextStatus = "status" in updatePayload ? updatePayload.status : currentVariant.status;
6323
+ updatePayload.status = coerceVariantStatusForProduct(nextStatus, parentStatus, {
6324
+ approvalStatus: parentApproval,
6325
+ requireApproval
6326
+ });
6327
+ }
6328
+ }
6246
6329
  if (resource === "products") {
6247
6330
  const currentRow = await repo.findOne({
6248
6331
  where: {
@@ -6598,6 +6681,10 @@ function createCrudByIdHandler(dataSource, entityMap, options) {
6598
6681
  if (reloaded) updated = reloaded;
6599
6682
  }
6600
6683
  updated = hydrateProductDisplayName(updated);
6684
+ const productStatus = String(updated.status ?? "draft");
6685
+ if (Number.isFinite(updatedId) && updatedId > 0) {
6686
+ await syncProductVariantsStatusWithProduct(dataSource, entityMap, updatedId, productStatus);
6687
+ }
6601
6688
  if (getCms) {
6602
6689
  const cms = await getCms();
6603
6690
  await queueErpProductUpsertIfEnabled(cms, dataSource, entityMap, updated);
@@ -8635,6 +8722,12 @@ function createUploadHandler(config) {
8635
8722
  parentId
8636
8723
  });
8637
8724
  } catch (err) {
8725
+ console.error("[upload] File upload failed", {
8726
+ error: err instanceof Error ? err.message : String(err),
8727
+ stack: err instanceof Error ? err.stack : void 0,
8728
+ name: err instanceof Error ? err.name : void 0,
8729
+ metadata: err && typeof err === "object" && "$metadata" in err ? err.$metadata : void 0
8730
+ });
8638
8731
  return json({
8639
8732
  error: "File upload failed"
8640
8733
  }, {
@@ -9340,41 +9433,68 @@ function createUsersApiHandlers(config) {
9340
9433
  const page = Math.max(1, parseInt(url.searchParams.get("page") || "1", 10));
9341
9434
  const limit = Math.min(100, parseInt(url.searchParams.get("limit") || "10", 10));
9342
9435
  const skip = (page - 1) * limit;
9343
- const sortField = url.searchParams.get("sortField") || "createdAt";
9436
+ const sortFieldRaw = url.searchParams.get("sortField") || "createdAt";
9437
+ const allowedSort = /* @__PURE__ */ new Set([
9438
+ "createdAt",
9439
+ "updatedAt",
9440
+ "name",
9441
+ "email",
9442
+ "id",
9443
+ "blocked"
9444
+ ]);
9445
+ const sortField = allowedSort.has(sortFieldRaw) ? sortFieldRaw : "createdAt";
9344
9446
  const sortOrder = url.searchParams.get("sortOrder") === "desc" ? "DESC" : "ASC";
9345
- const search = url.searchParams.get("search");
9346
- const where = search ? [
9347
- {
9348
- name: typeorm.ILike(`%${search}%`),
9349
- deleted: false
9350
- },
9351
- {
9352
- email: typeorm.ILike(`%${search}%`),
9353
- deleted: false
9354
- }
9355
- ] : {
9447
+ const search = url.searchParams.get("search")?.trim() || "";
9448
+ const groupName = url.searchParams.get("groupName")?.trim() || "";
9449
+ const qb = userRepo().createQueryBuilder("u").leftJoinAndSelect("u.group", "g").where("u.deleted = :deleted", {
9356
9450
  deleted: false
9357
- };
9358
- const [data, total] = await userRepo().findAndCount({
9359
- skip,
9360
- take: limit,
9361
- order: {
9362
- [sortField]: sortOrder
9363
- },
9364
- where,
9365
- relations: [
9366
- "group"
9367
- ],
9368
- select: [
9369
- "id",
9370
- "name",
9371
- "email",
9372
- "blocked",
9373
- "createdAt",
9374
- "updatedAt",
9375
- "groupId"
9376
- ]
9377
- });
9451
+ }).orderBy(`u.${sortField}`, sortOrder).skip(skip).take(limit).select([
9452
+ "u.id",
9453
+ "u.name",
9454
+ "u.email",
9455
+ "u.blocked",
9456
+ "u.createdAt",
9457
+ "u.updatedAt",
9458
+ "u.groupId",
9459
+ "g.id",
9460
+ "g.name"
9461
+ ]);
9462
+ if (search) {
9463
+ qb.andWhere("(u.name ILIKE :search OR u.email ILIKE :search)", {
9464
+ search: `%${search}%`
9465
+ });
9466
+ }
9467
+ if (groupName) {
9468
+ if (!entityMap.user_groups) {
9469
+ return json({
9470
+ total: 0,
9471
+ page,
9472
+ limit,
9473
+ totalPages: 0,
9474
+ data: []
9475
+ });
9476
+ }
9477
+ const groupRepo = dataSource.getRepository(entityMap.user_groups);
9478
+ const group = await groupRepo.findOne({
9479
+ where: {
9480
+ name: groupName,
9481
+ deleted: false
9482
+ }
9483
+ });
9484
+ if (!group) {
9485
+ return json({
9486
+ total: 0,
9487
+ page,
9488
+ limit,
9489
+ totalPages: 0,
9490
+ data: []
9491
+ });
9492
+ }
9493
+ qb.andWhere("u.groupId = :groupId", {
9494
+ groupId: Number(group.id)
9495
+ });
9496
+ }
9497
+ const [data, total] = await qb.getManyAndCount();
9378
9498
  return json({
9379
9499
  total,
9380
9500
  page,
@@ -29782,7 +29902,8 @@ function createStorefrontApiHandler(config) {
29782
29902
  const repo = dataSource.getRepository(entityMap.product_variants);
29783
29903
  const rows = await repo.find({
29784
29904
  where: {
29785
- productId
29905
+ productId,
29906
+ status: "available"
29786
29907
  },
29787
29908
  order: {
29788
29909
  id: "ASC"
@@ -29815,6 +29936,52 @@ function createStorefrontApiHandler(config) {
29815
29936
  return result;
29816
29937
  }
29817
29938
  chunkUSNT2KNT_cjs.__name(loadProductVariantsWithPricing, "loadProductVariantsWithPricing");
29939
+ async function loadApplicableVendorPolicies(productId, vendorId) {
29940
+ if (!entityMap.refund_policies) return [];
29941
+ const policyRepo = dataSource.getRepository(entityMap.refund_policies);
29942
+ const format = /* @__PURE__ */ chunkUSNT2KNT_cjs.__name((row) => ({
29943
+ id: Number(row.id),
29944
+ name: String(row.name ?? "").trim(),
29945
+ desc: row.desc != null ? String(row.desc) : null,
29946
+ refundWindowDays: Number(row.refundWindowDays) || 0,
29947
+ type: String(row.type ?? "percentage"),
29948
+ value: Number(row.value) || 0
29949
+ }), "format");
29950
+ const linkedIds = /* @__PURE__ */ new Set();
29951
+ if (entityMap.product_config) {
29952
+ const configs = await dataSource.getRepository(entityMap.product_config).find({
29953
+ where: {
29954
+ productId
29955
+ }
29956
+ });
29957
+ for (const c of configs) {
29958
+ const id = Number(c.refundPolicyId);
29959
+ if (Number.isFinite(id) && id > 0) linkedIds.add(id);
29960
+ }
29961
+ }
29962
+ if (linkedIds.size > 0) {
29963
+ const rows = await policyRepo.find({
29964
+ where: {
29965
+ id: typeorm.In([
29966
+ ...linkedIds
29967
+ ])
29968
+ }
29969
+ });
29970
+ return rows.map((r) => format(r)).filter((p) => p.name).sort((a, b) => a.id - b.id);
29971
+ }
29972
+ if (vendorId == null || !Number.isFinite(Number(vendorId))) return [];
29973
+ const vendorRows = await policyRepo.find({
29974
+ where: {
29975
+ vendorId: Number(vendorId),
29976
+ status: "active"
29977
+ },
29978
+ order: {
29979
+ id: "ASC"
29980
+ }
29981
+ });
29982
+ return vendorRows.map((r) => format(r)).filter((p) => p.name);
29983
+ }
29984
+ chunkUSNT2KNT_cjs.__name(loadApplicableVendorPolicies, "loadApplicableVendorPolicies");
29818
29985
  return {
29819
29986
  async handle(method, path2, req) {
29820
29987
  try {
@@ -29882,13 +30049,11 @@ function createStorefrontApiHandler(config) {
29882
30049
  const url = new URL(req.url || "", "http://localhost");
29883
30050
  const collectionSlug = url.searchParams.get("collection")?.trim();
29884
30051
  const collectionId = url.searchParams.get("collectionId");
30052
+ const q = url.searchParams.get("q")?.trim() ?? "";
29885
30053
  const limit = Math.min(100, Math.max(1, parseInt(url.searchParams.get("limit") || "20", 10)));
29886
30054
  const offset = Math.max(0, parseInt(url.searchParams.get("offset") || "0", 10));
29887
- const where = {
29888
- status: "available",
29889
- deleted: false
29890
- };
29891
30055
  let collectionFilter = null;
30056
+ let collectionIdFilter = null;
29892
30057
  if (collectionSlug) {
29893
30058
  let col = null;
29894
30059
  if (/^\d+$/.test(collectionSlug)) {
@@ -29915,30 +30080,59 @@ function createStorefrontApiHandler(config) {
29915
30080
  collection: null
29916
30081
  });
29917
30082
  }
29918
- where.collectionId = col.id;
30083
+ collectionIdFilter = Number(col.id);
29919
30084
  collectionFilter = {
29920
30085
  name: col.name,
29921
30086
  slug: col.slug
29922
30087
  };
29923
30088
  } else if (collectionId) {
29924
30089
  const cid = parseInt(collectionId, 10);
29925
- if (Number.isFinite(cid)) where.collectionId = cid;
30090
+ if (Number.isFinite(cid)) collectionIdFilter = cid;
30091
+ }
30092
+ let items = [];
30093
+ let total = 0;
30094
+ if (q) {
30095
+ const like = `%${q.replace(/[%_]/g, "\\$&")}%`;
30096
+ const qb = productRepo().createQueryBuilder("p").where("p.status = :status", {
30097
+ status: "available"
30098
+ }).andWhere("p.deleted = :del", {
30099
+ del: false
30100
+ }).andWhere(`(p.name ILIKE :like OR p.slug ILIKE :like OR COALESCE(p.sku, '') ILIKE :like OR COALESCE(p.title, '') ILIKE :like OR COALESCE(p.metadata->>'description', '') ILIKE :like)`, {
30101
+ like
30102
+ }).orderBy("p.id", "ASC").take(limit).skip(offset);
30103
+ if (collectionIdFilter != null) {
30104
+ qb.andWhere("p.collectionId = :cid", {
30105
+ cid: collectionIdFilter
30106
+ });
30107
+ }
30108
+ [items, total] = await qb.getManyAndCount();
30109
+ } else {
30110
+ const where = {
30111
+ status: "available",
30112
+ deleted: false
30113
+ };
30114
+ if (collectionIdFilter != null) where.collectionId = collectionIdFilter;
30115
+ const result = await productRepo().findAndCount({
30116
+ where,
30117
+ order: {
30118
+ id: "ASC"
30119
+ },
30120
+ take: limit,
30121
+ skip: offset
30122
+ });
30123
+ items = result[0];
30124
+ total = result[1];
29926
30125
  }
29927
- const [items, total] = await productRepo().findAndCount({
29928
- where,
29929
- order: {
29930
- id: "ASC"
29931
- },
29932
- take: limit,
29933
- skip: offset
29934
- });
29935
30126
  const products = await Promise.all(items.map((item) => enrichProductPricing(item)));
29936
30127
  return json({
29937
30128
  products,
29938
30129
  total,
29939
30130
  ...collectionFilter && {
29940
30131
  collection: collectionFilter
29941
- }
30132
+ },
30133
+ ...q ? {
30134
+ q
30135
+ } : {}
29942
30136
  });
29943
30137
  }
29944
30138
  if (path2[0] === "products" && path2.length === 2 && method === "GET") {
@@ -29974,12 +30168,14 @@ function createStorefrontApiHandler(config) {
29974
30168
  const pricing = await resolveProductEventPricing(Number(p.id));
29975
30169
  const enriched = await enrichProductPricing(p, pricing);
29976
30170
  const variants = await loadProductVariantsWithPricing(Number(p.id), pricing);
30171
+ const policies = await loadApplicableVendorPolicies(Number(p.id), p.vendorId != null ? Number(p.vendorId) : null);
29977
30172
  return json({
29978
30173
  ...enriched,
29979
30174
  attributes: attributeTags,
29980
30175
  ...variants.length ? {
29981
30176
  variants
29982
- } : {}
30177
+ } : {},
30178
+ policies
29983
30179
  });
29984
30180
  }
29985
30181
  if (path2[0] === "collections" && path2.length === 1 && method === "GET") {
@@ -30791,24 +30987,61 @@ function createStorefrontApiHandler(config) {
30791
30987
  }, {
30792
30988
  status: 404
30793
30989
  });
30990
+ const rawVariantId = body.variantId ?? body.variant_id;
30991
+ const variantIdNum = rawVariantId != null && String(rawVariantId).trim() !== "" ? Number(rawVariantId) : NaN;
30992
+ const hasVariantId = Number.isFinite(variantIdNum) && variantIdNum > 0;
30993
+ const bodyMeta = body.metadata && typeof body.metadata === "object" && !Array.isArray(body.metadata) ? body.metadata : {};
30994
+ const optionsRaw = body.options && typeof body.options === "object" && !Array.isArray(body.options) ? body.options : bodyMeta.options && typeof bodyMeta.options === "object" && !Array.isArray(bodyMeta.options) ? bodyMeta.options : null;
30995
+ const options = optionsRaw && Object.fromEntries(Object.entries(optionsRaw).map(([k, v]) => [
30996
+ String(k),
30997
+ String(v ?? "").trim()
30998
+ ]).filter(([, v]) => v.length > 0));
30999
+ const lineMetadata = {
31000
+ ...bodyMeta,
31001
+ ...hasVariantId ? {
31002
+ variantId: variantIdNum
31003
+ } : {},
31004
+ ...options && Object.keys(options).length ? {
31005
+ options
31006
+ } : {}
31007
+ };
31008
+ if (typeof bodyMeta.imageUrl === "string" && bodyMeta.imageUrl.trim()) {
31009
+ lineMetadata.imageUrl = bodyMeta.imageUrl.trim();
31010
+ }
31011
+ if (typeof bodyMeta.title === "string" && bodyMeta.title.trim()) {
31012
+ lineMetadata.title = bodyMeta.title.trim();
31013
+ }
31014
+ const metadataPayload = Object.keys(lineMetadata).length ? lineMetadata : null;
30794
31015
  const { cart, setCookie, err } = await getOrCreateCart(req);
30795
31016
  if (err) return err;
30796
31017
  const cartId = cart.id;
30797
- const existing = await cartItemRepo().findOne({
31018
+ const sameProductLines = await cartItemRepo().find({
30798
31019
  where: {
30799
31020
  cartId,
30800
31021
  productId
30801
31022
  }
30802
31023
  });
31024
+ const existing = sameProductLines.find((row) => {
31025
+ const m = row.metadata;
31026
+ const existingVid = m?.variantId ?? m?.variant_id;
31027
+ if (hasVariantId) {
31028
+ return Number(existingVid) === variantIdNum;
31029
+ }
31030
+ return existingVid == null || existingVid === "";
31031
+ });
30803
31032
  if (existing) {
30804
31033
  await cartItemRepo().update(existing.id, {
30805
- quantity: existing.quantity + quantity
31034
+ quantity: existing.quantity + quantity,
31035
+ ...metadataPayload ? {
31036
+ metadata: metadataPayload
31037
+ } : {}
30806
31038
  });
30807
31039
  } else {
30808
31040
  await cartItemRepo().save(cartItemRepo().create({
30809
31041
  cartId,
30810
31042
  productId,
30811
- quantity
31043
+ quantity,
31044
+ metadata: metadataPayload
30812
31045
  }));
30813
31046
  }
30814
31047
  await cartRepo().update(cartId, {