@mohasinac/appkit 4.33.1 → 4.34.1

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.
Files changed (104) hide show
  1. package/dist/_internal/server/features/checkout/actions.js +9 -1
  2. package/dist/_internal/server/features/checkout/expand-order-items.js +9 -0
  3. package/dist/_internal/server/features/media/contextGuards.d.ts +3 -3
  4. package/dist/_internal/server/features/media/contextGuards.js +19 -5
  5. package/dist/_internal/server/features/orders/actions.d.ts +9 -0
  6. package/dist/_internal/server/features/orders/actions.js +47 -4
  7. package/dist/_internal/server/features/orders/adapters.js +10 -0
  8. package/dist/_internal/server/features/refunds/actions.d.ts +9 -1
  9. package/dist/_internal/server/features/refunds/actions.js +36 -3
  10. package/dist/_internal/server/features/seo/sitemap.js +2 -2
  11. package/dist/_internal/server/features/site-settings/adapters.js +1 -1
  12. package/dist/_internal/server/functions/scheduled.d.ts +1 -2
  13. package/dist/_internal/server/functions/scheduled.js +8 -9
  14. package/dist/_internal/server/jobs/core/testerSandboxCleanup.d.ts +15 -0
  15. package/dist/_internal/server/jobs/core/testerSandboxCleanup.js +15 -6
  16. package/dist/_internal/server/jobs/handlers/index.d.ts +0 -1
  17. package/dist/_internal/server/jobs/handlers/index.js +0 -1
  18. package/dist/_internal/shared/features/orders/refund-copy.d.ts +12 -0
  19. package/dist/_internal/shared/features/orders/refund-copy.js +12 -0
  20. package/dist/_internal/shared/features/orders/return-reasons.d.ts +59 -0
  21. package/dist/_internal/shared/features/orders/return-reasons.js +96 -0
  22. package/dist/_internal/shared/features/orders/schema.d.ts +30 -0
  23. package/dist/_internal/shared/features/orders/schema.js +20 -0
  24. package/dist/_internal/shared/features/products/schema.d.ts +12 -0
  25. package/dist/_internal/shared/features/products/schema.js +4 -1
  26. package/dist/_internal/shared/media/limits.d.ts +14 -0
  27. package/dist/_internal/shared/media/limits.js +29 -0
  28. package/dist/client.d.ts +9 -1
  29. package/dist/client.js +19 -1
  30. package/dist/features/admin/components/AdminProductEditorView.js +6 -1
  31. package/dist/features/admin/components/AdminSiteSettingsView.js +2 -6
  32. package/dist/features/admin/components/index.d.ts +0 -2
  33. package/dist/features/admin/components/index.js +0 -1
  34. package/dist/features/admin/schemas/admin-editor-forms.js +1 -1
  35. package/dist/features/admin/schemas/firestore.d.ts +0 -2
  36. package/dist/features/auctions/components/AuctionDetailPageView.js +4 -3
  37. package/dist/features/auth/schemas/firestore.d.ts +1 -0
  38. package/dist/features/contact/components/ContactForm.js +46 -31
  39. package/dist/features/media/upload/MediaUploadList.d.ts +16 -1
  40. package/dist/features/media/upload/MediaUploadList.js +58 -8
  41. package/dist/features/orders/components/RefundRequestView.d.ts +26 -10
  42. package/dist/features/orders/components/RefundRequestView.js +108 -24
  43. package/dist/features/orders/schemas/firestore.d.ts +42 -0
  44. package/dist/features/orders/types/index.d.ts +24 -0
  45. package/dist/features/pre-orders/components/PreOrderDetailPageView.js +5 -3
  46. package/dist/features/products/components/ProductDetailPageView.js +14 -2
  47. package/dist/features/products/components/ProductFeatureBadges.d.ts +9 -1
  48. package/dist/features/products/components/ProductFeatureBadges.js +17 -1
  49. package/dist/features/products/components/ProductForm.js +46 -10
  50. package/dist/features/products/components/ProductGrid.js +10 -1
  51. package/dist/features/products/constants/final-sale.d.ts +40 -0
  52. package/dist/features/products/constants/final-sale.js +40 -0
  53. package/dist/features/products/index.d.ts +1 -0
  54. package/dist/features/products/index.js +1 -0
  55. package/dist/features/products/schemas/firestore.d.ts +19 -2
  56. package/dist/features/products/schemas/firestore.js +4 -0
  57. package/dist/features/products/types/index.d.ts +2 -0
  58. package/dist/features/seller/components/SellerProductShell.d.ts +7 -0
  59. package/dist/features/seller/components/SellerProductShell.js +82 -11
  60. package/dist/features/seller/index.d.ts +1 -0
  61. package/dist/features/seller/index.js +1 -0
  62. package/dist/features/seller/schemas/product-form.d.ts +304 -0
  63. package/dist/features/seller/schemas/product-form.js +132 -0
  64. package/dist/features/seller/utils/product-draft-mapping.d.ts +117 -0
  65. package/dist/features/seller/utils/product-draft-mapping.js +147 -0
  66. package/dist/features/shell/SectionForm.js +62 -7
  67. package/dist/features/shell/form-sections.js +4 -0
  68. package/dist/features/tester/repository/tester-checklist-item.repository.d.ts +16 -1
  69. package/dist/features/tester/repository/tester-checklist-item.repository.js +32 -6
  70. package/dist/features/tester/seed-data/events-tester-seed-data.js +77 -5
  71. package/dist/features/tester/seed-data/offers-tester-seed-data.js +23 -9
  72. package/dist/features/tester/seed-data/products-tester-seed-data.js +65 -49
  73. package/dist/features/tester/seed-data/tester-checklist-seed-data.js +182 -0
  74. package/dist/features/tester/seed-data/tester-window.d.ts +25 -0
  75. package/dist/features/tester/seed-data/tester-window.js +66 -0
  76. package/dist/index.d.ts +6 -3
  77. package/dist/index.js +12 -3
  78. package/dist/next/routing/route-map.d.ts +2 -0
  79. package/dist/next/routing/route-map.js +1 -0
  80. package/dist/schemas/registry.d.ts +271 -0
  81. package/dist/schemas/registry.js +9 -0
  82. package/dist/seed/_helpers/final-sale-fixtures.d.ts +35 -0
  83. package/dist/seed/_helpers/final-sale-fixtures.js +61 -0
  84. package/dist/seed/products-art-seed-data.js +9 -1
  85. package/dist/seed/products-auctions-seed-data.js +2 -1
  86. package/dist/seed/products-classifieds-seed-data.js +2 -1
  87. package/dist/seed/products-digital-codes-seed-data.js +2 -1
  88. package/dist/seed/products-live-items-seed-data.js +2 -1
  89. package/dist/seed/products-preorders-seed-data.d.ts +2 -138
  90. package/dist/seed/products-preorders-seed-data.js +2 -1
  91. package/dist/seed/products-prize-draws-seed-data.js +2 -1
  92. package/dist/seed/products-standard-seed-data.js +2 -1
  93. package/dist/seed/products-stickers-seed-data.js +9 -1
  94. package/dist/seed/users-seed-data.js +107 -4
  95. package/dist/server.d.ts +6 -2
  96. package/dist/server.js +15 -2
  97. package/dist/styles.css +1 -1
  98. package/dist/tailwind-utilities.css +1 -1
  99. package/dist/tokens/motion.d.ts +12 -0
  100. package/dist/tokens/motion.js +12 -0
  101. package/dist/ui/components/CollapsibleSection.d.ts +18 -1
  102. package/dist/ui/components/CollapsibleSection.js +20 -3
  103. package/dist/ui/components/Motion.js +17 -1
  104. package/package.json +1 -1
@@ -22,6 +22,7 @@
22
22
  import { PRODUCT_FIELDS } from "../constants/field-names";
23
23
  import { buildSearchTxt } from "../utils/search-txt";
24
24
  import { seedPhoto } from "./_helpers/media";
25
+ import { withFinalSale } from "./_helpers/final-sale-fixtures";
25
26
  const _rawPreordersSeedData = [
26
27
  {
27
28
  id: "preorder-beyblade-x-bx-08-wave",
@@ -296,7 +297,7 @@ const _rawPreordersSeedData = [
296
297
  updatedAt: new Date("2026-08-24"),
297
298
  },
298
299
  ];
299
- export const productsPreordersSeedData = _rawPreordersSeedData.map((p) => ({
300
+ export const productsPreordersSeedData = _rawPreordersSeedData.map((p) => withFinalSale({
300
301
  tags: [],
301
302
  stockQuantity: p.availableQuantity ?? 1,
302
303
  mainImage: p.images?.[0] ?? "",
@@ -22,6 +22,7 @@ import { withProductSearchTxt } from "./_helpers/product-search-txt";
22
22
  import { PRODUCT_FIELDS } from "../constants/field-names";
23
23
  import { buildSearchTxt } from "../utils/search-txt";
24
24
  import { seedPhoto } from "./_helpers/media";
25
+ import { withFinalSale } from "./_helpers/final-sale-fixtures";
25
26
  const _rawproductsPrizeDrawsSeedData = [
26
27
  {
27
28
  id: "prizedraw-beyblade-mystery-box",
@@ -408,4 +409,4 @@ const _rawproductsPrizeDrawsSeedData = [
408
409
  * the bottom of the array cannot ship without it — which is exactly how the
409
410
  * sold/depleted fixture in this file ended up unsearchable.
410
411
  */
411
- export const productsPrizeDrawsSeedData = _rawproductsPrizeDrawsSeedData.map(withProductSearchTxt);
412
+ export const productsPrizeDrawsSeedData = _rawproductsPrizeDrawsSeedData.map(withProductSearchTxt).map(withFinalSale);
@@ -25,6 +25,7 @@
25
25
  import { PRODUCT_FIELDS } from "../constants/field-names";
26
26
  import { buildSearchTxt } from "../utils/search-txt";
27
27
  import { seedPhoto } from "./_helpers/media";
28
+ import { withFinalSale } from "./_helpers/final-sale-fixtures";
28
29
  /*
29
30
  * Real Beyblade attributes per fixture — Root Cause #6 (standard was the
30
31
  * "richest" seed file by fixture count but never exercised customFields/
@@ -648,4 +649,4 @@ export const productsStandardSeedData = [
648
649
  ...(p.id ? SPEC_OVERRIDES[p.id] : undefined),
649
650
  listingType: PRODUCT_FIELDS.LISTING_TYPE_VALUES.STANDARD,
650
651
  })),
651
- ];
652
+ ].map(withFinalSale);
@@ -19,7 +19,8 @@
19
19
  import { PRODUCT_FIELDS } from "../constants/field-names";
20
20
  import { buildSearchTxt } from "../utils/search-txt";
21
21
  import { seedPhoto } from "./_helpers/media";
22
- export const productsStickersSeedData = [
22
+ import { withFinalSale } from "./_helpers/final-sale-fixtures";
23
+ const _rawProductsStickersSeedData = [
23
24
  {
24
25
  id: "stickers-beyblade-original-classic-sheet",
25
26
  slug: "stickers-beyblade-original-classic-sheet",
@@ -264,3 +265,10 @@ export const productsStickersSeedData = [
264
265
  ]),
265
266
  },
266
267
  ];
268
+ /*
269
+ * This file had no export wrapper at all — every other product seed file maps
270
+ * its raw array through one, and these two were the exception. Adding it here
271
+ * so the final-sale opt-outs are applied the same way everywhere rather than
272
+ * being hand-written into two records that reviewers would have to find.
273
+ */
274
+ export const productsStickersSeedData = _rawProductsStickersSeedData.map(withFinalSale);
@@ -1,11 +1,16 @@
1
1
  /*
2
- * WHY: Provides 18 seed user accounts covering all marketplace roles and demographics.
3
- * WHAT: Exports 18 UserDocument partials — 1 admin, 2 sellers (store owners, one of which
4
- * is also the dedicated isTester QA account), 15 buyers.
2
+ * WHY: Provides 21 seed user accounts covering all marketplace roles and demographics.
3
+ * WHAT: Exports 21 UserDocument partials — 1 admin, 2 sellers (store owners, one of which
4
+ * is also the dedicated isTester QA account), 15 buyers, 1 automated tester
5
+ * (`user-claude-tester`, isBot), and 2 employees on contrasting permission presets.
5
6
  * All passwords are TempPass123! in the Firebase Auth emulator. UIDs match slugs.
6
7
  *
8
+ * 🛑 seed-cli sets that password ONLY when it creates the Auth record. A re-seed
9
+ * never resets an existing password, so an account whose password was changed
10
+ * stays changed and must be reset explicitly.
11
+ *
7
12
  * EXPORTS:
8
- * usersSeedData — array of 18 Partial<UserDocument> objects for the seed runner
13
+ * usersSeedData — array of 21 Partial<UserDocument> objects for the seed runner
9
14
  *
10
15
  * @tag domain:users,auth
11
16
  * @tag layer:seed
@@ -15,6 +20,7 @@
15
20
  * @tag sideEffects:none
16
21
  */
17
22
  import { getDefaultPhonePrefix } from "./seed-market-config";
23
+ import { PERMISSION_GROUPS } from "../features/auth/permissions/constants";
18
24
  import { USER_FIELDS } from "../constants/field-names";
19
25
  import { seedPhoto } from "./_helpers/media";
20
26
  const _ph = getDefaultPhonePrefix();
@@ -522,4 +528,101 @@ export const usersSeedData = [
522
528
  createdAt: daysAgo(1),
523
529
  updatedAt: daysAgo(1),
524
530
  },
531
+ // ── Automated tester (the Claude-driven checklist runner answers as this account) ──
532
+ // `canTestAdmin` is REQUIRED, not decorative: 116 checklist cases are adminOnly and
533
+ // GET/PUT /api/user/tester-checklist 404s them for a caller without it, so the runner
534
+ // would silently see a shorter catalog than a human tester does.
535
+ // `isBot` keeps it off the public Bug Hunters leaderboard — see getBugHunterLeaderboard().
536
+ {
537
+ uid: "user-claude-tester",
538
+ email: "claude-tester@letitrip.in",
539
+ phoneNumber: `${_ph}9999900019`,
540
+ phoneVerified: true,
541
+ displayName: "Claude (automated)",
542
+ photoURL: seedPhoto("user-avatar-claude-tester-20260101", 400, 400),
543
+ role: USER_FIELDS.ROLE_VALUES.SELLER,
544
+ isTester: true,
545
+ canTestAdmin: true,
546
+ isBot: true,
547
+ emailVerified: true,
548
+ disabled: false,
549
+ storeId: "store-tester-qa-seller",
550
+ storeSlug: "store-tester-qa-seller",
551
+ storeStatus: "approved",
552
+ publicProfile: {
553
+ isPublic: false,
554
+ showEmail: false,
555
+ showPhone: false,
556
+ showOrders: false,
557
+ showWishlist: false,
558
+ bio: "Automated tester. Works the tester checklist against a freshly seeded catalog and records a verdict per case.",
559
+ location: "Bengaluru, Karnataka",
560
+ },
561
+ stats: { totalOrders: 0, auctionsWon: 0, itemsSold: 0, reviewsCount: 0 },
562
+ metadata: { lastSignInTime: daysAgo(1), creationTime: daysAgo(1).toISOString(), loginCount: 1 },
563
+ createdAt: daysAgo(1),
564
+ updatedAt: daysAgo(1),
565
+ },
566
+ // ── Employees: two contrasting permission presets ───────────────────────────
567
+ // These exist so the sidebar-scoping checklist cases can be tested AT ALL. Before
568
+ // this the seed had no `role: "employee"` account anywhere, so the case the
569
+ // checklist itself marks "🛑 THE BIG ONE" — an employee must see only what their
570
+ // permissions allow, not all 91 admin entries — had nothing to sign in as.
571
+ //
572
+ // `permissions` is the load-bearing field (it is what the RBAC checks read);
573
+ // `permissionGroup` is display-only. Both are set from the same preset so they
574
+ // cannot disagree. Two presets on purpose: one narrow, one broad — a scoping bug
575
+ // that happens to produce the right count for one group is caught by the other.
576
+ {
577
+ uid: "user-employee-blog",
578
+ email: "employee-blog@letitrip.in",
579
+ phoneNumber: `${_ph}9999900020`,
580
+ phoneVerified: true,
581
+ displayName: "Mock Employee 1",
582
+ photoURL: seedPhoto("user-avatar-employee-blog-20260101", 400, 400),
583
+ role: USER_FIELDS.ROLE_VALUES.EMPLOYEE,
584
+ permissionGroup: "blog_poster",
585
+ permissions: [...PERMISSION_GROUPS.blog_poster],
586
+ emailVerified: true,
587
+ disabled: false,
588
+ publicProfile: {
589
+ isPublic: false,
590
+ showEmail: false,
591
+ showPhone: false,
592
+ showOrders: false,
593
+ showWishlist: false,
594
+ bio: "Content employee — blog and media only.",
595
+ location: "Pune, Maharashtra",
596
+ },
597
+ stats: { totalOrders: 0, auctionsWon: 0, itemsSold: 0, reviewsCount: 0 },
598
+ metadata: { lastSignInTime: daysAgo(2), creationTime: daysAgo(30).toISOString(), loginCount: 12 },
599
+ createdAt: daysAgo(30),
600
+ updatedAt: daysAgo(2),
601
+ },
602
+ {
603
+ uid: "user-employee-trust",
604
+ email: "employee-trust@letitrip.in",
605
+ phoneNumber: `${_ph}9999900021`,
606
+ phoneVerified: true,
607
+ displayName: "Mock Employee 2",
608
+ photoURL: seedPhoto("user-avatar-employee-trust-20260101", 400, 400),
609
+ role: USER_FIELDS.ROLE_VALUES.EMPLOYEE,
610
+ permissionGroup: "trust_and_safety",
611
+ permissions: [...PERMISSION_GROUPS.trust_and_safety],
612
+ emailVerified: true,
613
+ disabled: false,
614
+ publicProfile: {
615
+ isPublic: false,
616
+ showEmail: false,
617
+ showPhone: false,
618
+ showOrders: false,
619
+ showWishlist: false,
620
+ bio: "Trust & Safety employee — users, bans, reviews and reports.",
621
+ location: "Chennai, Tamil Nadu",
622
+ },
623
+ stats: { totalOrders: 0, auctionsWon: 0, itemsSold: 0, reviewsCount: 0 },
624
+ metadata: { lastSignInTime: daysAgo(2), creationTime: daysAgo(60).toISOString(), loginCount: 40 },
625
+ createdAt: daysAgo(60),
626
+ updatedAt: daysAgo(2),
627
+ },
525
628
  ];
package/dist/server.d.ts CHANGED
@@ -8,7 +8,7 @@ export { wrapAction, isOk, unwrap, } from "./_internal/shared/types/action-resul
8
8
  export type { ActionResult } from "./_internal/shared/types/action-result";
9
9
  export { setActionErrorReporter, hasActionErrorReporter, } from "./_internal/shared/types/action-error-reporter";
10
10
  export type { ActionErrorReport, ActionErrorReporter, } from "./_internal/shared/types/action-error-reporter";
11
- export { attachPaymentProofAction, adminVerifyPaymentAction, adminRequestProofReuploadAction, adminRejectPaymentAsFraudAction, raiseOrderDisputeAction, } from "./_internal/server/features/orders/actions";
11
+ export { attachPaymentProofAction, adminVerifyPaymentAction, adminRequestProofReuploadAction, adminRejectPaymentAsFraudAction, raiseOrderDisputeAction, requestReturnAction, } from "./_internal/server/features/orders/actions";
12
12
  export { wrapJobHandler, wrapScheduleHandler, wrapTriggerHandler, wrapCallableHandler, } from "./_internal/server/jobs/core/wrapJobHandler";
13
13
  export { analyzeLogs } from "./_internal/server/features/maintenance/analyze";
14
14
  export type { AnalyzeOptions, AnalyzeReport, } from "./_internal/server/features/maintenance/analyze";
@@ -530,7 +530,7 @@ export { LISTING_TYPE_REGISTRY, pluginFor, detectListingTypeFromSlug } from "./_
530
530
  export type { ListingTypePlugin } from "./_internal/shared/listing-types/_registry";
531
531
  export { applyMediaContextGuards, CONTEXT_LIMITS, } from "./_internal/server/features/media/contextGuards";
532
532
  export type { GuardResult, GuardError, GuardSuccess } from "./_internal/server/features/media/contextGuards";
533
- export { MEGABYTE, MAX_IMAGE_BYTES, MAX_PDF_BYTES, MAX_VIDEO_BYTES, MAX_LABEL, MAX_BYTES, ALLOWED_IMAGE_MIMES, ALLOWED_VIDEO_MIMES, ALLOWED_DOC_MIMES, ALLOWED_MIMES, ALLOWED_TYPES_LABEL, MIME_TO_EXT, PDF_MAGIC, VIDEO_CONVERSION_HINTS, classifyMime, isAllowedMime, maxBytesFor, getConversionHint, } from "./_internal/shared/media/limits";
533
+ export { MEGABYTE, MAX_IMAGE_BYTES, MAX_PDF_BYTES, MAX_VIDEO_BYTES, MAX_LABEL, MAX_BYTES, ALLOWED_IMAGE_MIMES, ALLOWED_VIDEO_MIMES, ALLOWED_DOC_MIMES, ALLOWED_MIMES, ALLOWED_TYPES_LABEL, MIME_TO_EXT, PDF_MAGIC, VIDEO_CONVERSION_HINTS, classifyMime, isAllowedMime, maxBytesFor, getConversionHint, PRODUCT_MAX_IMAGES, PRODUCT_MAX_VIDEOS, PRODUCT_IMAGE_INDEX_MAX, } from "./_internal/shared/media/limits";
534
534
  export type { MediaKind, AllowedImageMime, AllowedVideoMime, AllowedDocMime, AllowedMime, } from "./_internal/shared/media/limits";
535
535
  export { getServerPermissions, checkPermission, checkAnyPermission, makeAdminSectionLayout, } from "./_internal/server/features/auth/permissions";
536
536
  export type { ResolvedPermissions, AdminSectionLayoutOpts, } from "./_internal/server/features/auth/permissions";
@@ -581,3 +581,7 @@ export { validateActionIndexEntry, normaliseRoute, } from "./features/search/act
581
581
  export type { ActionIndexValidationContext, ActionIndexValidationIssue, } from "./features/search/action-index/validate-entry";
582
582
  export { ActionIndexRepository, actionIndexRepository, } from "./features/search/action-index/repository";
583
583
  export type { ActionIndexDocument } from "./features/search/action-index/repository";
584
+ export { REFUND_COPY } from "./_internal/shared/features/orders/refund-copy";
585
+ export { RETURN_REASON, FINAL_SALE_EXEMPT_REASONS, RETURN_REASON_LABEL, RETURN_REASON_GROUP_LABEL, isFinalSaleExempt, isReturnReason, selectableReturnReasons, } from "./_internal/shared/features/orders/return-reasons";
586
+ export type { ReturnReason } from "./_internal/shared/features/orders/return-reasons";
587
+ export { draftToProductInput, productToDraft, } from "./features/seller/utils/product-draft-mapping";
package/dist/server.js CHANGED
@@ -17,7 +17,11 @@ export { wrapAction, isOk, unwrap, } from "./_internal/shared/types/action-resul
17
17
  // server-side rather than from a client bootstrap.
18
18
  export { setActionErrorReporter, hasActionErrorReporter, } from "./_internal/shared/types/action-error-reporter";
19
19
  // [SERVER-ONLY] P-1 manual payment proof server actions.
20
- export { attachPaymentProofAction, adminVerifyPaymentAction, adminRequestProofReuploadAction, adminRejectPaymentAsFraudAction, raiseOrderDisputeAction, } from "./_internal/server/features/orders/actions";
20
+ export { attachPaymentProofAction, adminVerifyPaymentAction, adminRequestProofReuploadAction, adminRejectPaymentAsFraudAction, raiseOrderDisputeAction,
21
+ // Buyer return request. Was reachable only through `server-entry.ts`, which
22
+ // is the bare `@mohasinac/appkit` specifier — not `/server`, where every
23
+ // other order action lives and where a consumer would look for it.
24
+ requestReturnAction, } from "./_internal/server/features/orders/actions";
21
25
  // [SERVER-ONLY] Cloud Function handler wrappers — persist exceptions to
22
26
  // serverErrors (source: "function") before re-throwing so retry semantics
23
27
  // are preserved. Apply at the consumer's runtime adapter boundary.
@@ -1389,7 +1393,7 @@ export { LISTING_TYPE_REGISTRY, pluginFor, detectListingTypeFromSlug } from "./_
1389
1393
  // Media context guards — shared by /api/media/sign + legacy /api/media/upload.
1390
1394
  export { applyMediaContextGuards, CONTEXT_LIMITS, } from "./_internal/server/features/media/contextGuards";
1391
1395
  // Media upload limits — shared by /api/media/sign + /api/media/finalize + /api/media/upload.
1392
- export { MEGABYTE, MAX_IMAGE_BYTES, MAX_PDF_BYTES, MAX_VIDEO_BYTES, MAX_LABEL, MAX_BYTES, ALLOWED_IMAGE_MIMES, ALLOWED_VIDEO_MIMES, ALLOWED_DOC_MIMES, ALLOWED_MIMES, ALLOWED_TYPES_LABEL, MIME_TO_EXT, PDF_MAGIC, VIDEO_CONVERSION_HINTS, classifyMime, isAllowedMime, maxBytesFor, getConversionHint, } from "./_internal/shared/media/limits";
1396
+ export { MEGABYTE, MAX_IMAGE_BYTES, MAX_PDF_BYTES, MAX_VIDEO_BYTES, MAX_LABEL, MAX_BYTES, ALLOWED_IMAGE_MIMES, ALLOWED_VIDEO_MIMES, ALLOWED_DOC_MIMES, ALLOWED_MIMES, ALLOWED_TYPES_LABEL, MIME_TO_EXT, PDF_MAGIC, VIDEO_CONVERSION_HINTS, classifyMime, isAllowedMime, maxBytesFor, getConversionHint, PRODUCT_MAX_IMAGES, PRODUCT_MAX_VIDEOS, PRODUCT_IMAGE_INDEX_MAX, } from "./_internal/shared/media/limits";
1393
1397
  // ── RBAC server helpers ───────────────────────────────────────────────────────
1394
1398
  // getServerPermissions, checkPermission, makeAdminSectionLayout
1395
1399
  export { getServerPermissions, checkPermission, checkAnyPermission, makeAdminSectionLayout, } from "./_internal/server/features/auth/permissions";
@@ -1452,3 +1456,12 @@ export { COUNTRIES, COUNTRY_CODES, DEFAULT_COUNTRY, countryFor, postalPatternFor
1452
1456
  export { SUBDIVISIONS, subdivisionsFor } from "./constants/geo/subdivisions";
1453
1457
  export { validateActionIndexEntry, normaliseRoute, } from "./features/search/action-index/validate-entry";
1454
1458
  export { ActionIndexRepository, actionIndexRepository, } from "./features/search/action-index/repository";
1459
+ export { REFUND_COPY } from "./_internal/shared/features/orders/refund-copy";
1460
+ // Return / refund reasons — the closed enum the final-sale gate branches on.
1461
+ // See the module docstring for why the exempt set is "seller or carrier fault"
1462
+ // rather than "serious reasons".
1463
+ export { RETURN_REASON, FINAL_SALE_EXEMPT_REASONS, RETURN_REASON_LABEL, RETURN_REASON_GROUP_LABEL, isFinalSaleExempt, isReturnReason, selectableReturnReasons, } from "./_internal/shared/features/orders/return-reasons";
1464
+ // Seller listing form draft <-> product write payload. The flat form keys and
1465
+ // the nested document blocks are different shapes, and nothing translated
1466
+ // between them — see the module docstring.
1467
+ export { draftToProductInput, productToDraft, } from "./features/seller/utils/product-draft-mapping";