@mohasinac/appkit 4.30.19 → 4.31.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_internal/client/features/layout/useSidebarSearch.d.ts +21 -5
- package/dist/_internal/client/features/layout/useSidebarSearch.js +27 -6
- package/dist/_internal/client/features/lottery/LotteryAdminEditView.d.ts +23 -3
- package/dist/_internal/client/features/lottery/LotteryAdminEditView.js +106 -87
- package/dist/_internal/client/features/lottery/LotteryPullForm.d.ts +16 -5
- package/dist/_internal/client/features/lottery/LotteryPullForm.js +65 -40
- package/dist/_internal/server/features/auth/permissions.d.ts +2 -0
- package/dist/_internal/server/features/auth/permissions.js +3 -2
- package/dist/_internal/server/features/categories/data.js +15 -4
- package/dist/_internal/server/features/classified/index.d.ts +0 -1
- package/dist/_internal/server/features/classified/index.js +0 -1
- package/dist/_internal/server/features/digital-code/index.d.ts +0 -1
- package/dist/_internal/server/features/digital-code/index.js +0 -1
- package/dist/_internal/server/features/live/index.d.ts +0 -1
- package/dist/_internal/server/features/live/index.js +0 -1
- package/dist/_internal/server/features/products/data.js +15 -5
- package/dist/_internal/server/features/products/list-public.d.ts +9 -0
- package/dist/_internal/server/features/products/list-public.js +95 -7
- package/dist/_internal/server/features/site-settings/adapters.d.ts +2 -2
- package/dist/_internal/server/features/site-settings/adapters.js +8 -5
- package/dist/_internal/server/features/tester/visibility.d.ts +2 -1
- package/dist/_internal/server/features/tester/visibility.js +2 -2
- package/dist/_internal/server/functions/scheduled.d.ts +3 -1
- package/dist/_internal/server/functions/scheduled.js +27 -1
- package/dist/_internal/server/jobs/core/hardBanCascade.js +4 -0
- package/dist/_internal/server/jobs/core/index.d.ts +2 -0
- package/dist/_internal/server/jobs/core/index.js +2 -0
- package/dist/_internal/server/jobs/core/pageViewPrune.d.ts +10 -0
- package/dist/_internal/server/jobs/core/pageViewPrune.js +44 -0
- package/dist/_internal/server/jobs/core/pageViewRollup.d.ts +2 -0
- package/dist/_internal/server/jobs/core/pageViewRollup.js +87 -0
- package/dist/_internal/server/jobs/handlers/index.d.ts +2 -0
- package/dist/_internal/server/jobs/handlers/index.js +2 -0
- package/dist/_internal/server/jobs/handlers/pageViewPrune.d.ts +2 -0
- package/dist/_internal/server/jobs/handlers/pageViewPrune.js +2 -0
- package/dist/_internal/server/jobs/handlers/pageViewRollup.d.ts +2 -0
- package/dist/_internal/server/jobs/handlers/pageViewRollup.js +2 -0
- package/dist/_internal/shared/actions/action-registry.d.ts +1 -1
- package/dist/_internal/shared/actions/action-registry.js +69 -22
- package/dist/_internal/shared/checkout/rules/classified.rule.d.ts +9 -4
- package/dist/_internal/shared/checkout/rules/classified.rule.js +7 -2
- package/dist/_internal/shared/features/layout/matchesNavQuery.d.ts +14 -0
- package/dist/_internal/shared/features/layout/matchesNavQuery.js +72 -0
- package/dist/_internal/shared/features/layout/types.d.ts +37 -1
- package/dist/_internal/shared/features/layout/types.js +19 -1
- package/dist/_internal/shared/features/notifications/action-url.d.ts +9 -1
- package/dist/_internal/shared/features/notifications/action-url.js +47 -0
- package/dist/_internal/shared/features/offers/config.d.ts +65 -0
- package/dist/_internal/shared/features/offers/config.js +73 -2
- package/dist/_internal/shared/features/orders/schema.d.ts +19 -1
- package/dist/_internal/shared/features/orders/schema.js +22 -2
- package/dist/_internal/shared/features/site-settings/types.d.ts +12 -3
- package/dist/_internal/shared/listing-types/capabilities.d.ts +8 -2
- package/dist/_internal/shared/listing-types/capabilities.js +6 -1
- package/dist/_internal/shared/listing-types/classified/ctas.js +6 -1
- package/dist/_internal/shared/listing-types/feature-flags.d.ts +10 -5
- package/dist/_internal/shared/listing-types/feature-flags.js +11 -6
- package/dist/client.d.ts +37 -20
- package/dist/client.js +36 -14
- package/dist/configs/next.js +10 -2
- package/dist/constants/api-endpoints.d.ts +18 -54
- package/dist/constants/api-endpoints.js +6 -26
- package/dist/constants/field-names.d.ts +6 -24
- package/dist/constants/field-names.js +10 -27
- package/dist/constants/geo/countries.d.ts +50 -0
- package/dist/constants/geo/countries.js +129 -0
- package/dist/constants/geo/subdivisions.d.ts +13 -0
- package/dist/constants/geo/subdivisions.js +104 -0
- package/dist/constants/index.d.ts +2 -2
- package/dist/constants/index.js +2 -2
- package/dist/constants/table-keys.d.ts +24 -0
- package/dist/constants/table-keys.js +28 -0
- package/dist/contracts/extend.d.ts +0 -9
- package/dist/contracts/index.d.ts +1 -1
- package/dist/contracts/realtime-session.js +7 -0
- package/dist/core/browser.d.ts +1 -1
- package/dist/core/browser.js +1 -1
- package/dist/core/index.d.ts +1 -1
- package/dist/core/index.js +1 -1
- package/dist/core/site-config.d.ts +0 -3
- package/dist/core/site-config.js +0 -3
- package/dist/errors/messages.d.ts +0 -8
- package/dist/errors/messages.js +0 -9
- package/dist/features/about/schemas/index.d.ts +8 -8
- package/dist/features/account/components/AddressFilters.js +32 -11
- package/dist/features/account/components/AddressForm.d.ts +26 -25
- package/dist/features/account/components/AddressForm.js +81 -103
- package/dist/features/account/components/AddressesIndexListing.js +8 -4
- package/dist/features/account/components/UserSidebar.d.ts +3 -4
- package/dist/features/account/components/UserSupportView.js +89 -58
- package/dist/features/account/components/index.d.ts +1 -7
- package/dist/features/account/components/index.js +0 -3
- package/dist/features/account/hooks/useAddresses.d.ts +4 -3
- package/dist/features/account/hooks/useAddresses.js +4 -6
- package/dist/features/account/hooks/useCollapsedSections.d.ts +51 -10
- package/dist/features/account/hooks/useCollapsedSections.js +211 -38
- package/dist/features/account/hooks/useProfile.d.ts +8 -0
- package/dist/features/account/index.d.ts +0 -3
- package/dist/features/account/index.js +0 -3
- package/dist/features/account/schemas/index.d.ts +0 -92
- package/dist/features/account/schemas/index.js +42 -20
- package/dist/features/addresses/components/AddressLocationFields.d.ts +13 -0
- package/dist/features/addresses/components/AddressLocationFields.js +41 -0
- package/dist/features/addresses/hooks/usePostalLookup.d.ts +17 -0
- package/dist/features/addresses/hooks/usePostalLookup.js +133 -0
- package/dist/features/addresses/schemas/address-form.d.ts +423 -0
- package/dist/features/addresses/schemas/address-form.js +212 -0
- package/dist/features/addresses/schemas/index.d.ts +1 -0
- package/dist/features/addresses/schemas/index.js +8 -0
- package/dist/features/admin/actions/admin-read-actions.d.ts +1 -1
- package/dist/features/admin/actions/index.d.ts +0 -1
- package/dist/features/admin/actions/index.js +0 -1
- package/dist/features/admin/actions/notification-actions.js +1 -41
- package/dist/features/admin/components/AdminActionIndexView.d.ts +32 -0
- package/dist/features/admin/components/AdminActionIndexView.js +128 -0
- package/dist/features/admin/components/AdminAdEditorView.js +159 -163
- package/dist/features/admin/components/AdminAddressEditorView.js +97 -55
- package/dist/features/admin/components/AdminBrandEditorView.d.ts +15 -0
- package/dist/features/admin/components/AdminBrandEditorView.js +113 -77
- package/dist/features/admin/components/AdminBundleEditorView.d.ts +19 -9
- package/dist/features/admin/components/AdminBundleEditorView.js +136 -168
- package/dist/features/admin/components/AdminCategoryEditorView.js +120 -43
- package/dist/features/admin/components/AdminCouponEditorView.js +145 -109
- package/dist/features/admin/components/AdminEmployeeEditorView.js +125 -56
- package/dist/features/admin/components/AdminFaqEditorView.js +112 -58
- package/dist/features/admin/components/AdminFeatureEditorView.js +108 -68
- package/dist/features/admin/components/AdminNavEditorView.js +69 -44
- package/dist/features/admin/components/AdminOrderEditorView.js +47 -10
- package/dist/features/admin/components/AdminPrizeDrawsView.js +16 -2
- package/dist/features/admin/components/AdminSidebar.d.ts +11 -7
- package/dist/features/admin/components/AdminSiteSettingsView.js +37 -37
- package/dist/features/admin/components/AdminStoreEditorView.js +75 -52
- package/dist/features/admin/components/AdminSublistingCategoryEditorView.js +71 -30
- package/dist/features/admin/components/AdminTesterChecklistItemEditorView.js +95 -65
- package/dist/features/admin/components/BrandQuickCreateForm.d.ts +10 -0
- package/dist/features/admin/components/BrandQuickCreateForm.js +49 -26
- package/dist/features/admin/components/CategoryQuickCreateForm.d.ts +11 -0
- package/dist/features/admin/components/CategoryQuickCreateForm.js +48 -26
- package/dist/features/admin/components/index.d.ts +2 -2
- package/dist/features/admin/components/index.js +1 -1
- package/dist/features/admin/constants/site-settings-tabs.d.ts +120 -0
- package/dist/features/admin/constants/site-settings-tabs.js +152 -0
- package/dist/features/admin/index.d.ts +0 -3
- package/dist/features/admin/index.js +0 -2
- package/dist/features/admin/repository/analytics-rollup.repository.d.ts +35 -0
- package/dist/features/admin/repository/analytics-rollup.repository.js +30 -0
- package/dist/features/admin/schemas/admin-editor-forms.d.ts +56 -57
- package/dist/features/admin/schemas/admin-editor-forms.js +97 -54
- package/dist/features/admin/schemas/admin-ops-forms.d.ts +57 -5
- package/dist/features/admin/schemas/admin-ops-forms.js +104 -20
- package/dist/features/admin/schemas/admin-user-form.js +7 -0
- package/dist/features/admin/schemas/firestore.d.ts +48 -95
- package/dist/features/admin/schemas/firestore.js +15 -151
- package/dist/features/admin/schemas/nav-item-form.js +9 -2
- package/dist/features/admin/server.d.ts +0 -4
- package/dist/features/admin/server.js +0 -2
- package/dist/features/admin/types/index.d.ts +0 -7
- package/dist/features/analytics/repository/page-views.repository.d.ts +14 -0
- package/dist/features/analytics/repository/page-views.repository.js +24 -0
- package/dist/features/auth/actions/index.d.ts +0 -1
- package/dist/features/auth/actions/index.js +0 -1
- package/dist/features/auth/actions/realtime-token-actions.js +1 -12
- package/dist/features/auth/auth-helpers.js +5 -7
- package/dist/features/auth/components/Guards.js +2 -1
- package/dist/features/auth/components/LoginForm.d.ts +0 -2
- package/dist/features/auth/components/LoginForm.js +1 -3
- package/dist/features/auth/components/RegisterForm.js +62 -19
- package/dist/features/auth/permissions/constants.d.ts +27 -1
- package/dist/features/auth/role-predicates.d.ts +75 -7
- package/dist/features/auth/role-predicates.js +28 -2
- package/dist/features/auth/schemas/firestore.d.ts +22 -0
- package/dist/features/auth/schemas/index.d.ts +1 -1
- package/dist/features/auth/schemas/index.js +44 -8
- package/dist/features/auth/types/index.d.ts +14 -1
- package/dist/features/blog/api/route.js +10 -2
- package/dist/features/blog/components/BlogIndexListing.js +1 -1
- package/dist/features/blog/hooks/useBlog.js +2 -2
- package/dist/features/blog/schemas/index.d.ts +4 -0
- package/dist/features/blog/schemas/index.js +2 -0
- package/dist/features/blog/types/index.d.ts +1 -1
- package/dist/features/catalogue/components/CatalogueItemEditorView.d.ts +22 -0
- package/dist/features/catalogue/components/CatalogueItemEditorView.js +112 -52
- package/dist/features/catalogue/schemas/validation.d.ts +4 -4
- package/dist/features/catalogue/schemas/validation.js +47 -10
- package/dist/features/categories/schemas/bundle-form.d.ts +142 -0
- package/dist/features/categories/schemas/bundle-form.js +149 -0
- package/dist/features/classified/components/ClassifiedDetailPageView.d.ts +5 -4
- package/dist/features/classified/components/ClassifiedDetailPageView.js +37 -16
- package/dist/features/consultation/components/ConsultationForm.js +1 -1
- package/dist/features/consultation/schemas/index.js +34 -10
- package/dist/features/corporate/schemas/index.js +36 -15
- package/dist/features/filters/FilterPanel.js +3 -3
- package/dist/features/filters/RangeFilter.d.ts +10 -0
- package/dist/features/filters/RangeFilter.js +41 -4
- package/dist/features/homepage/components/MarketplaceHomepageView.js +24 -5
- package/dist/features/homepage/hooks/useBlogArticles.js +1 -1
- package/dist/features/layout/BottomActions.js +84 -11
- package/dist/features/layout/BottomActionsContext.d.ts +1 -6
- package/dist/features/layout/BottomActionsContext.js +1 -1
- package/dist/features/layout/hooks/useBottomActions.js +2 -2
- package/dist/features/layout/hooks/useFormBottomActions.d.ts +12 -1
- package/dist/features/layout/hooks/useFormBottomActions.js +12 -6
- package/dist/features/lottery/schemas/config-write.d.ts +9 -5
- package/dist/features/lottery/schemas/config-write.js +69 -9
- package/dist/features/orders/schemas/buyer-forms.d.ts +6 -3
- package/dist/features/orders/schemas/buyer-forms.js +31 -3
- package/dist/features/orders/schemas/index.d.ts +2 -2
- package/dist/features/products/components/GroupSettingsPanel.js +3 -1
- package/dist/features/products/components/MakeOfferButton.d.ts +13 -2
- package/dist/features/products/components/MakeOfferButton.js +33 -11
- package/dist/features/products/components/ProductDetailActions.js +0 -1
- package/dist/features/products/components/ProductDetailPageView.d.ts +7 -3
- package/dist/features/products/components/ProductDetailPageView.js +8 -5
- package/dist/features/products/constants/action-defs.d.ts +1 -2
- package/dist/features/products/constants/action-defs.js +40 -43
- package/dist/features/products/repository/products.repository.d.ts +5 -1
- package/dist/features/products/repository/products.repository.js +23 -1
- package/dist/features/products/schemas/firestore.d.ts +7 -3
- package/dist/features/products/schemas/product-features.validators.js +3 -0
- package/dist/features/promotions/components/CouponCard.js +8 -7
- package/dist/features/scams/schemas/firestore.d.ts +15 -1
- package/dist/features/scams/schemas/report-form.d.ts +5 -5
- package/dist/features/scams/schemas/report-form.js +18 -3
- package/dist/features/search/action-index/derive.d.ts +49 -0
- package/dist/features/search/action-index/derive.js +121 -0
- package/dist/features/search/action-index/repository.d.ts +42 -0
- package/dist/features/search/action-index/repository.js +100 -0
- package/dist/features/search/action-index/settings-entries.d.ts +41 -0
- package/dist/features/search/action-index/settings-entries.js +268 -0
- package/dist/features/search/action-index/types.d.ts +81 -0
- package/dist/features/search/action-index/types.js +102 -0
- package/dist/features/search/action-index/validate-entry.d.ts +34 -0
- package/dist/features/search/action-index/validate-entry.js +114 -0
- package/dist/features/search/hooks/useNavSuggestions.d.ts +5 -1
- package/dist/features/search/hooks/useNavSuggestions.js +23 -3
- package/dist/features/search/repository/search.repository.js +3 -1
- package/dist/features/seller/actions/offer-actions.js +43 -24
- package/dist/features/seller/actions/seller-actions.js +29 -5
- package/dist/features/seller/components/CategoryChipPicker.d.ts +9 -0
- package/dist/features/seller/components/CategoryChipPicker.js +12 -0
- package/dist/features/seller/components/SellerAddressesView.js +5 -1
- package/dist/features/seller/components/SellerAnalyticsAlertsView.js +83 -43
- package/dist/features/seller/components/SellerArtView.d.ts +14 -7
- package/dist/features/seller/components/SellerArtView.js +4 -119
- package/dist/features/seller/components/SellerClassifiedView.d.ts +14 -7
- package/dist/features/seller/components/SellerClassifiedView.js +4 -124
- package/dist/features/seller/components/SellerCouponEditorView.d.ts +22 -1
- package/dist/features/seller/components/SellerCouponEditorView.js +91 -45
- package/dist/features/seller/components/SellerDigitalCodesView.d.ts +14 -7
- package/dist/features/seller/components/SellerDigitalCodesView.js +4 -126
- package/dist/features/seller/components/SellerListingTypeView.d.ts +66 -0
- package/dist/features/seller/components/SellerListingTypeView.js +277 -0
- package/dist/features/seller/components/SellerLiveView.d.ts +14 -7
- package/dist/features/seller/components/SellerLiveView.js +4 -126
- package/dist/features/seller/components/SellerSidebar.d.ts +3 -6
- package/dist/features/seller/components/SellerStickersView.d.ts +14 -7
- package/dist/features/seller/components/SellerStickersView.js +4 -119
- package/dist/features/seller/components/SellerSupportView.d.ts +31 -0
- package/dist/features/seller/components/SellerSupportView.js +100 -0
- package/dist/features/seller/components/index.d.ts +4 -8
- package/dist/features/seller/components/index.js +2 -4
- package/dist/features/seller/index.d.ts +0 -1
- package/dist/features/seller/index.js +0 -1
- package/dist/features/seller/schemas/coupon-form.d.ts +214 -0
- package/dist/features/seller/schemas/coupon-form.js +155 -23
- package/dist/features/seller/schemas/offer-forms.d.ts +16 -7
- package/dist/features/seller/schemas/offer-forms.js +28 -12
- package/dist/features/shell/FormShell.js +2 -2
- package/dist/features/shell/QuickFormDrawer.js +2 -2
- package/dist/features/shell/SectionForm.d.ts +19 -1
- package/dist/features/shell/SectionForm.js +104 -17
- package/dist/features/shell/build-sections.d.ts +23 -0
- package/dist/features/shell/build-sections.js +106 -8
- package/dist/features/shell/field-ui-meta.d.ts +44 -0
- package/dist/features/shell/field-ui-meta.js +14 -7
- package/dist/features/shell/form-sections.d.ts +46 -0
- package/dist/features/shell/form-sections.js +114 -0
- package/dist/features/shipments/components/AdminShipmentEditorView.js +87 -64
- package/dist/features/shipments/schemas/validation.d.ts +2 -2
- package/dist/features/shipments/schemas/validation.js +44 -13
- package/dist/features/store-extensions/schemas/custom-role-form.js +6 -2
- package/dist/features/store-extensions/schemas/listing-template-form.d.ts +7 -7
- package/dist/features/store-extensions/schemas/payout-method-form.js +14 -0
- package/dist/features/stores/actions/store-query-actions.js +3 -2
- package/dist/features/stores/api/[storeSlug]/auctions/route.js +3 -1
- package/dist/features/stores/api/[storeSlug]/products/route.js +3 -1
- package/dist/features/support/repository/support.repository.d.ts +21 -0
- package/dist/features/support/repository/support.repository.js +63 -0
- package/dist/features/support/schemas/firestore.d.ts +27 -2
- package/dist/features/support/schemas/firestore.js +2 -0
- package/dist/features/support/schemas/ticket-create-form.js +7 -0
- package/dist/features/tester/schemas/checklist-item-form.d.ts +43 -0
- package/dist/features/tester/schemas/checklist-item-form.js +109 -0
- package/dist/features/tester/seed-data/blog-tester-seed-data.js +2 -2
- package/dist/features/tester/seed-data/categories-tester-seed-data.js +2 -2
- package/dist/features/tester/seed-data/events-tester-seed-data.js +5 -5
- package/dist/features/tester/seed-data/orders-tester-seed-data.js +2 -2
- package/dist/features/tester/seed-data/products-tester-seed-data.js +48 -49
- package/dist/features/tester/seed-data/stores-tester-seed-data.js +3 -3
- package/dist/features/tester/seed-data/tester-checklist-seed-data.js +275 -29
- package/dist/features/whatsapp-bot/components/SellerWhatsAppSettingsView.js +48 -12
- package/dist/http/api-handler.js +2 -1
- package/dist/index.d.ts +24 -103
- package/dist/index.js +33 -141
- package/dist/jobs.d.ts +1 -1
- package/dist/jobs.js +1 -1
- package/dist/monitoring/browser.d.ts +0 -2
- package/dist/monitoring/browser.js +12 -1
- package/dist/monitoring/index.d.ts +0 -2
- package/dist/monitoring/index.js +0 -1
- package/dist/next/api/routeHandler.js +6 -3
- package/dist/next/index.d.ts +1 -2
- package/dist/next/index.js +0 -1
- package/dist/next/middleware/index.d.ts +0 -2
- package/dist/next/middleware/index.js +0 -1
- package/dist/next/routing/route-map.d.ts +8 -7
- package/dist/next/routing/route-map.js +10 -3
- package/dist/providers/db-firebase/admin.js +15 -1
- package/dist/providers/db-firebase/sieve.d.ts +22 -0
- package/dist/react/hooks/useListingTypeFlags.d.ts +1 -1
- package/dist/react/hooks/useListingTypeFlags.js +1 -1
- package/dist/react/hooks/usePendingFilters.js +5 -3
- package/dist/react/hooks/usePendingTable.js +15 -3
- package/dist/repositories/index.d.ts +0 -1
- package/dist/repositories/index.js +0 -1
- package/dist/schemas/registry.d.ts +197 -232
- package/dist/schemas/registry.js +5 -6
- package/dist/schemas/webhooks/razorpay.d.ts +50 -50
- package/dist/security/authorization.d.ts +9 -0
- package/dist/security/authorization.js +16 -2
- package/dist/security/browser.d.ts +1 -3
- package/dist/security/browser.js +5 -2
- package/dist/security/index.d.ts +1 -3
- package/dist/security/index.js +19 -2
- package/dist/security/pii-encrypt.js +16 -0
- package/dist/security/pii-schemas.d.ts +0 -14
- package/dist/security/pii-schemas.js +7 -15
- package/dist/seed/_helpers/category-forest.js +2 -2
- package/dist/seed/_helpers/media.d.ts +19 -0
- package/dist/seed/_helpers/media.js +75 -0
- package/dist/seed/blog-posts-seed-data.js +17 -17
- package/dist/seed/carousel-slides-seed-data.js +7 -7
- package/dist/seed/cart-seed-data.js +13 -13
- package/dist/seed/categories-seed-data.js +10 -10
- package/dist/seed/events-seed-data.js +24 -24
- package/dist/seed/factories/product.factory.js +4 -4
- package/dist/seed/factories/store.factory.js +3 -3
- package/dist/seed/factories/user.factory.js +2 -2
- package/dist/seed/grouped-listings-seed-data.js +11 -11
- package/dist/seed/homepage-sections-seed-data.js +2 -2
- package/dist/seed/index.d.ts +0 -1
- package/dist/seed/index.js +0 -1
- package/dist/seed/manifest.d.ts +1 -1
- package/dist/seed/manifest.js +0 -5
- package/dist/seed/notifications-seed-data.js +20 -1
- package/dist/seed/orders-seed-data.js +2 -2
- package/dist/seed/products-art-seed-data.js +16 -16
- package/dist/seed/products-auctions-seed-data.js +34 -34
- package/dist/seed/products-classifieds-seed-data.js +35 -37
- package/dist/seed/products-digital-codes-seed-data.js +20 -20
- package/dist/seed/products-live-items-seed-data.js +11 -11
- package/dist/seed/products-preorders-seed-data.js +13 -13
- package/dist/seed/products-prize-draws-seed-data.js +43 -43
- package/dist/seed/products-standard-seed-data.js +54 -54
- package/dist/seed/products-stickers-seed-data.js +15 -15
- package/dist/seed/reviews-seed-data.js +4 -4
- package/dist/seed/scammers-seed-data.js +3 -3
- package/dist/seed/site-settings-seed-data.js +11 -24
- package/dist/seed/store-extensions-seed-data.js +10 -10
- package/dist/seed/stores-seed-data.js +11 -11
- package/dist/seed/support-tickets-seed-data.d.ts +14 -0
- package/dist/seed/support-tickets-seed-data.js +20 -1
- package/dist/seed/users-seed-data.js +20 -20
- package/dist/server-entry.d.ts +0 -1
- package/dist/server-entry.js +0 -1
- package/dist/server.d.ts +9 -6
- package/dist/server.js +7 -13
- package/dist/styles.css +248 -68
- package/dist/tailwind-utilities.css +1 -1
- package/dist/tokens/themes/default-dark.js +2 -2
- package/dist/tokens/themes/default-light.js +2 -2
- package/dist/tokens/tokens.css +24 -4
- package/dist/ui/components/ActionRow.d.ts +50 -0
- package/dist/ui/components/ActionRow.js +53 -0
- package/dist/ui/components/ActionRow.style.css +145 -0
- package/dist/ui/components/Drawer.d.ts +10 -0
- package/dist/ui/components/Drawer.js +2 -1
- package/dist/ui/components/FilterDrawer.js +4 -1
- package/dist/ui/components/FilterDrawer.style.css +6 -12
- package/dist/ui/components/FormActionBar.js +14 -1
- package/dist/ui/components/FormActionBar.style.css +12 -11
- package/dist/ui/components/ListingLayout.js +8 -1
- package/dist/ui/components/ListingLayout.style.css +6 -13
- package/dist/ui/components/Modal.d.ts +15 -1
- package/dist/ui/components/Modal.js +17 -3
- package/dist/ui/components/QuickCreateModal.js +2 -2
- package/dist/ui/components/QuickCreateModal.style.css +78 -84
- package/dist/ui/components/RecordDetailModal.js +2 -2
- package/dist/ui/components/SideDrawer.d.ts +8 -0
- package/dist/ui/components/SideDrawer.js +2 -1
- package/dist/ui/components/SideDrawer.style.css +6 -3
- package/dist/ui/components/SideModal.d.ts +11 -1
- package/dist/ui/components/SideModal.js +3 -2
- package/dist/ui/components/SideModal.style.css +14 -0
- package/dist/ui/components/Typography.style.css +33 -24
- package/dist/ui/components/index.style.css +1 -0
- package/dist/ui/forms/FormShell.style.css +260 -311
- package/dist/ui/index.d.ts +2 -0
- package/dist/ui/index.js +1 -0
- package/dist/utils/index.d.ts +0 -1
- package/dist/utils/index.js +0 -1
- package/dist/validation/index.d.ts +1 -1
- package/dist/validation/index.js +1 -1
- package/dist/validation/schemas.d.ts +0 -19
- package/dist/validation/schemas.js +8 -19
- package/package.json +1 -1
- package/scripts/seed-cli.mjs +3 -6
package/dist/security/index.d.ts
CHANGED
|
@@ -6,7 +6,5 @@ export type { UserRole } from "./authorization";
|
|
|
6
6
|
export { redactPii, safeDisplayName, safeDisplayEmail, maskIp } from "./pii-redact";
|
|
7
7
|
export { encryptValue, decryptValue, hmacBlindIndex, encryptPiiFields, decryptPiiFields, encryptPii, decryptPii, piiBlindIndex, piiIndicesFor, getPiiConfigError, encryptPayoutDetails, decryptPayoutDetails, encryptShippingConfig, decryptShippingConfig, encryptPayoutBankAccount, decryptPayoutBankAccount, } from "./pii-encrypt";
|
|
8
8
|
export { isPiiEncrypted, maskName, maskEmail, maskPublicReview, maskPublicBid, maskPublicEventEntry, maskOfferForSeller, ENC_PREFIX, HMAC_PREFIX, } from "./pii-mask";
|
|
9
|
-
export { USER_PII_FIELDS, USER_PII_INDEX_MAP, ADDRESS_PII_FIELDS, ORDER_PII_FIELDS, PAYOUT_PII_FIELDS, PAYOUT_PII_INDEX_MAP, BID_PII_FIELDS, TOKEN_PII_FIELDS, TOKEN_PII_INDEX_MAP, REVIEW_PII_FIELDS, REVIEW_PII_INDEX_MAP, OFFER_PII_FIELDS,
|
|
9
|
+
export { USER_PII_FIELDS, USER_PII_INDEX_MAP, ADDRESS_PII_FIELDS, ORDER_PII_FIELDS, PAYOUT_PII_FIELDS, PAYOUT_PII_INDEX_MAP, BID_PII_FIELDS, TOKEN_PII_FIELDS, TOKEN_PII_INDEX_MAP, REVIEW_PII_FIELDS, REVIEW_PII_INDEX_MAP, OFFER_PII_FIELDS, EVENT_ENTRY_PII_FIELDS, LOTTERY_ENTRY_PII_FIELDS, PAYMENT_METHOD_PII_FIELDS, } from "./pii-schemas";
|
|
10
10
|
export { encryptSecret, decryptSecret, isSecretEncrypted, maskSecret, } from "./settings-encryption";
|
|
11
|
-
export type { Permission, RoleDefinition, RbacConfig, ResolvedUser, RbacHookReturn, } from "./rbac";
|
|
12
|
-
export { DEFAULT_ROLES, resolvePermissions, hasPermission, hasAllPermissions, hasAnyPermission, createRbacHook, Can, createRequirePermission, createRequirePermissionSync, createRbacMiddleware, } from "./rbac";
|
package/dist/security/index.js
CHANGED
|
@@ -7,6 +7,23 @@ export { encryptValue, decryptValue, hmacBlindIndex, encryptPiiFields, decryptPi
|
|
|
7
7
|
// pii-encrypt.ts) so this barrel stays safe to re-export from the
|
|
8
8
|
// universal client+server index.ts. See pii-mask.ts's header comment.
|
|
9
9
|
export { isPiiEncrypted, maskName, maskEmail, maskPublicReview, maskPublicBid, maskPublicEventEntry, maskOfferForSeller, ENC_PREFIX, HMAC_PREFIX, } from "./pii-mask";
|
|
10
|
-
export { USER_PII_FIELDS, USER_PII_INDEX_MAP, ADDRESS_PII_FIELDS, ORDER_PII_FIELDS, PAYOUT_PII_FIELDS, PAYOUT_PII_INDEX_MAP, BID_PII_FIELDS, TOKEN_PII_FIELDS, TOKEN_PII_INDEX_MAP, REVIEW_PII_FIELDS, REVIEW_PII_INDEX_MAP, OFFER_PII_FIELDS,
|
|
10
|
+
export { USER_PII_FIELDS, USER_PII_INDEX_MAP, ADDRESS_PII_FIELDS, ORDER_PII_FIELDS, PAYOUT_PII_FIELDS, PAYOUT_PII_INDEX_MAP, BID_PII_FIELDS, TOKEN_PII_FIELDS, TOKEN_PII_INDEX_MAP, REVIEW_PII_FIELDS, REVIEW_PII_INDEX_MAP, OFFER_PII_FIELDS, EVENT_ENTRY_PII_FIELDS, LOTTERY_ENTRY_PII_FIELDS, PAYMENT_METHOD_PII_FIELDS, } from "./pii-schemas";
|
|
11
11
|
export { encryptSecret, decryptSecret, isSecretEncrypted, maskSecret, } from "./settings-encryption";
|
|
12
|
-
|
|
12
|
+
// RBAC system — DELETED 2026-08-29.
|
|
13
|
+
//
|
|
14
|
+
// `security/rbac/**` was a complete second permission system: DEFAULT_ROLES,
|
|
15
|
+
// resolvePermissions, createRbacHook, createRequirePermission(Sync),
|
|
16
|
+
// createRbacMiddleware, <Can>, and its own `Permission` type. It had ZERO
|
|
17
|
+
// consumers outside its own directory and these barrels, and it looked alive on
|
|
18
|
+
// a grep only because its permission strings coincidentally overlapped the real
|
|
19
|
+
// union (a hazard action-defs.ts:129 already warned about).
|
|
20
|
+
//
|
|
21
|
+
// It was worse than inert. `appkit/src/index.ts` re-exported ITS `Permission`
|
|
22
|
+
// and ITS `hasPermission` — so a consumer importing either from the package
|
|
23
|
+
// root silently got the dead 6-role model instead of the live 130-member union
|
|
24
|
+
// and its helpers. Root Cause #53's exact shape, one module over.
|
|
25
|
+
//
|
|
26
|
+
// The live system is `features/auth/permissions/constants.ts` (the union,
|
|
27
|
+
// PERMISSION_GROUPS, hasPermission/hasAny/hasAll) plus
|
|
28
|
+
// `_internal/server/features/auth/permissions.ts` (getServerPermissions,
|
|
29
|
+
// checkPermission). Import from there.
|
|
@@ -222,6 +222,22 @@ export function encryptPiiFields(doc, piiFields) {
|
|
|
222
222
|
}
|
|
223
223
|
else {
|
|
224
224
|
result[field] = encryptValue(value);
|
|
225
|
+
/*
|
|
226
|
+
* 🛑 The derived name is not always the name readers query.
|
|
227
|
+
*
|
|
228
|
+
* `phoneNumber` yields `phoneNumberIndex`, and NOTHING in this codebase
|
|
229
|
+
* reads that — every lookup uses `phoneIndex` (`USER_PII_INDEX_MAP`,
|
|
230
|
+
* `byPhoneIndex`, `USER_FIELDS.PHONE_INDEX`). `BaseRepository` patches
|
|
231
|
+
* around it by *additionally* spreading `piiIndicesFor(data,
|
|
232
|
+
* piiIndexMap)`, so a user document has carried BOTH the correct
|
|
233
|
+
* `phoneIndex` and a dead `phoneNumberIndex` on every write.
|
|
234
|
+
*
|
|
235
|
+
* The derivation stays, because `email` -> `emailIndex` is right and
|
|
236
|
+
* several callers depend on it, and because removing it would silently
|
|
237
|
+
* drop indices for every field whose repository has no `piiIndexMap`
|
|
238
|
+
* entry. Where a field's index name differs, the MAP is the authority —
|
|
239
|
+
* which is why `scripts/lib/pii-seed.mjs` indexes only from the map.
|
|
240
|
+
*/
|
|
225
241
|
result[`${field}Index`] = hmacBlindIndex(value);
|
|
226
242
|
}
|
|
227
243
|
}
|
|
@@ -56,26 +56,12 @@ export declare const BID_PII_FIELDS: readonly ["userEmail"];
|
|
|
56
56
|
export declare const TOKEN_PII_FIELDS: readonly ["email"];
|
|
57
57
|
/** Blind-index mapping for token email queries */
|
|
58
58
|
export declare const TOKEN_PII_INDEX_MAP: Record<string, string>;
|
|
59
|
-
/**
|
|
60
|
-
* PII fields in conversations — buyer↔seller message bodies.
|
|
61
|
-
*
|
|
62
|
-
* `messages[].body` uses the array-path form, and `lastMessage` is the
|
|
63
|
-
* denormalised copy of the newest body: encrypting one without the other would
|
|
64
|
-
* leave every conversation's latest message readable at rest, which is most of
|
|
65
|
-
* the exposure.
|
|
66
|
-
*
|
|
67
|
-
* Participant display names are deliberately NOT here — decision D1 keeps names
|
|
68
|
-
* searchable, and both sides already know who they are talking to.
|
|
69
|
-
*/
|
|
70
|
-
export declare const CONVERSATION_PII_FIELDS: readonly ["lastMessage", "messages[].body"];
|
|
71
59
|
/** PII fields in reviews */
|
|
72
60
|
export declare const REVIEW_PII_FIELDS: readonly ["userName"];
|
|
73
61
|
/** Blind-index mapping for queryable review PII */
|
|
74
62
|
export declare const REVIEW_PII_INDEX_MAP: Record<string, string>;
|
|
75
63
|
/** PII fields in offers (buyer + seller data) */
|
|
76
64
|
export declare const OFFER_PII_FIELDS: readonly ["buyerName", "buyerEmail", "sellerName"];
|
|
77
|
-
/** PII fields in chat rooms */
|
|
78
|
-
export declare const CHAT_PII_FIELDS: readonly ["buyerName", "sellerName"];
|
|
79
65
|
/** PII fields in event entries */
|
|
80
66
|
export declare const EVENT_ENTRY_PII_FIELDS: readonly ["userDisplayName", "userEmail", "ipAddress"];
|
|
81
67
|
/** PII fields in lottery entries */
|
|
@@ -85,21 +85,15 @@ export const TOKEN_PII_FIELDS = ["email"];
|
|
|
85
85
|
export const TOKEN_PII_INDEX_MAP = {
|
|
86
86
|
email: "emailIndex",
|
|
87
87
|
};
|
|
88
|
-
|
|
89
|
-
*
|
|
90
|
-
*
|
|
91
|
-
* `messages[].body` uses the array-path form, and `lastMessage` is the
|
|
92
|
-
* denormalised copy of the newest body: encrypting one without the other would
|
|
93
|
-
* leave every conversation's latest message readable at rest, which is most of
|
|
94
|
-
* the exposure.
|
|
88
|
+
/*
|
|
89
|
+
* `CONVERSATION_PII_FIELDS` (`lastMessage`, `messages[].body`) was removed with
|
|
90
|
+
* the conversations feature on 2026-08-31.
|
|
95
91
|
*
|
|
96
|
-
*
|
|
97
|
-
*
|
|
92
|
+
* 🛑 Its array-path form was the ONLY user of `encryptPiiFields`' `[]` syntax
|
|
93
|
+
* outside status history. If a future schema needs to encrypt a field inside an
|
|
94
|
+
* array, check that machinery still works before relying on it — a path that no
|
|
95
|
+
* caller exercises is a path nothing proves.
|
|
98
96
|
*/
|
|
99
|
-
export const CONVERSATION_PII_FIELDS = [
|
|
100
|
-
"lastMessage",
|
|
101
|
-
"messages[].body",
|
|
102
|
-
];
|
|
103
97
|
/** PII fields in reviews */
|
|
104
98
|
export const REVIEW_PII_FIELDS = ["userName"];
|
|
105
99
|
/** Blind-index mapping for queryable review PII */
|
|
@@ -112,8 +106,6 @@ export const OFFER_PII_FIELDS = [
|
|
|
112
106
|
"buyerEmail",
|
|
113
107
|
"sellerName",
|
|
114
108
|
];
|
|
115
|
-
/** PII fields in chat rooms */
|
|
116
|
-
export const CHAT_PII_FIELDS = ["buyerName", "sellerName"];
|
|
117
109
|
/** PII fields in event entries */
|
|
118
110
|
export const EVENT_ENTRY_PII_FIELDS = [
|
|
119
111
|
"userDisplayName",
|
|
@@ -18,8 +18,8 @@
|
|
|
18
18
|
* @tag consumers:seed/categories-seed-data.ts
|
|
19
19
|
* @tag sideEffects:none
|
|
20
20
|
*/
|
|
21
|
-
import {
|
|
22
|
-
const cover = (slug) =>
|
|
21
|
+
import { seedPhoto } from "../_helpers/media";
|
|
22
|
+
const cover = (slug) => seedPhoto(`category-image-${slug}-20260101`, 1200, 600);
|
|
23
23
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
24
24
|
// Root 1 — Spinning Tops. The Beyblade catalogue, four generations deep:
|
|
25
25
|
// generation -> part-family -> specific line
|
|
@@ -1 +1,20 @@
|
|
|
1
1
|
export declare function seedExtMedia(url: string): string;
|
|
2
|
+
/**
|
|
3
|
+
* Turn a seed key into something a person would read.
|
|
4
|
+
*
|
|
5
|
+
* `art-image-dranzer-phoenix-2-20260817` → `Dranzer Phoenix`
|
|
6
|
+
*
|
|
7
|
+
* Strips the trailing `-YYYYMMDD` stamp, a trailing image index, and the
|
|
8
|
+
* leading `<kind>-image-` prefix that every seed key carries — all of which are
|
|
9
|
+
* bookkeeping, not the name of the thing.
|
|
10
|
+
*/
|
|
11
|
+
export declare function seedPhotoLabel(seed: string): string;
|
|
12
|
+
/**
|
|
13
|
+
* A deterministic, labelled placeholder image for seed data, already wrapped in
|
|
14
|
+
* the media proxy.
|
|
15
|
+
*
|
|
16
|
+
* Deterministic on purpose — Root Cause #25: a seed file is re-executed on every
|
|
17
|
+
* `appkit-seed` invocation, so anything non-stable here would give the same
|
|
18
|
+
* fixture a different URL on every run.
|
|
19
|
+
*/
|
|
20
|
+
export declare function seedPhoto(seed: string, width: number, height: number): string;
|
|
@@ -25,3 +25,78 @@ export function seedExtMedia(url) {
|
|
|
25
25
|
return url;
|
|
26
26
|
return MEDIA_ENDPOINTS.EXT_URL(url);
|
|
27
27
|
}
|
|
28
|
+
/* ── Seed photography ────────────────────────────────────────────────────── */
|
|
29
|
+
/*
|
|
30
|
+
* WHY THIS EXISTS
|
|
31
|
+
*
|
|
32
|
+
* The seed catalogue used to name its image host **409 times**, in 30 files, as
|
|
33
|
+
* `https://picsum.photos/seed/<seed>/<w>/<h>` literals. On 2026-08-31 picsum
|
|
34
|
+
* went down — 503 from its origin AND its Fastly CDN — and because the host was
|
|
35
|
+
* written into every URL rather than referenced from one place, virtually every
|
|
36
|
+
* image on the production site broke at once and there was no single edit that
|
|
37
|
+
* could move them.
|
|
38
|
+
*
|
|
39
|
+
* That is the actual defect. A third party going down is not preventable; being
|
|
40
|
+
* unable to react to it in one line is.
|
|
41
|
+
*
|
|
42
|
+
* Measured the same day, direct: picsum 503 · fastly.picsum 503 (10.5s) ·
|
|
43
|
+
* placekitten 521 · loremflickr 200 but 5.4s, which exceeds the proxy's own 4s
|
|
44
|
+
* fetch timeout · placehold.co 200 in 0.58s. Hence placehold.co.
|
|
45
|
+
*
|
|
46
|
+
* It renders the item's own NAME on the tile, which is a real gain over random
|
|
47
|
+
* photography for a demo catalogue: every card now says what it is, and nobody
|
|
48
|
+
* can mistake seeded data for real inventory.
|
|
49
|
+
*/
|
|
50
|
+
/** The one place a seed image host is named. Changing it is a one-line edit. */
|
|
51
|
+
const SEED_PHOTO_HOST = "https://placehold.co";
|
|
52
|
+
/**
|
|
53
|
+
* Muted backgrounds, all dark enough for the same light foreground.
|
|
54
|
+
*
|
|
55
|
+
* Raw hex rather than theme tokens because these are baked into a URL that a
|
|
56
|
+
* third party renders — no stylesheet and no CSS custom property is in scope.
|
|
57
|
+
*/
|
|
58
|
+
const SEED_PHOTO_COLOURS = ["1e293b", "334155", "3f3f46", "44403c", "312e81", "164e63"];
|
|
59
|
+
const SEED_PHOTO_FG = "f8fafc";
|
|
60
|
+
/** Deterministic 32-bit hash. Same seed, same colour, every reseed. */
|
|
61
|
+
function seedHash(input) {
|
|
62
|
+
let h = 2166136261;
|
|
63
|
+
for (let i = 0; i < input.length; i += 1) {
|
|
64
|
+
h ^= input.charCodeAt(i);
|
|
65
|
+
h = Math.imul(h, 16777619);
|
|
66
|
+
}
|
|
67
|
+
return h >>> 0;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Turn a seed key into something a person would read.
|
|
71
|
+
*
|
|
72
|
+
* `art-image-dranzer-phoenix-2-20260817` → `Dranzer Phoenix`
|
|
73
|
+
*
|
|
74
|
+
* Strips the trailing `-YYYYMMDD` stamp, a trailing image index, and the
|
|
75
|
+
* leading `<kind>-image-` prefix that every seed key carries — all of which are
|
|
76
|
+
* bookkeeping, not the name of the thing.
|
|
77
|
+
*/
|
|
78
|
+
export function seedPhotoLabel(seed) {
|
|
79
|
+
const cleaned = seed
|
|
80
|
+
.replace(/-\d{8}$/, "")
|
|
81
|
+
.replace(/-\d+$/, "")
|
|
82
|
+
.replace(/^(?:product|art|sticker|stickers|auction|preorder|prizedraw|classified|digitalcode|live|blog|event|store|user|category|brand|bundle|group|review|ad|carousel|slide)-(?:image|cover|banner|logo|avatar|photo)-/, "")
|
|
83
|
+
.replace(/^(?:image|cover|banner|logo|avatar|photo)-/, "")
|
|
84
|
+
.replace(/-/g, " ")
|
|
85
|
+
.trim();
|
|
86
|
+
if (!cleaned)
|
|
87
|
+
return "LetItRip";
|
|
88
|
+
return cleaned.replace(/\b[a-z]/g, (c) => c.toUpperCase());
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* A deterministic, labelled placeholder image for seed data, already wrapped in
|
|
92
|
+
* the media proxy.
|
|
93
|
+
*
|
|
94
|
+
* Deterministic on purpose — Root Cause #25: a seed file is re-executed on every
|
|
95
|
+
* `appkit-seed` invocation, so anything non-stable here would give the same
|
|
96
|
+
* fixture a different URL on every run.
|
|
97
|
+
*/
|
|
98
|
+
export function seedPhoto(seed, width, height) {
|
|
99
|
+
const bg = SEED_PHOTO_COLOURS[seedHash(seed) % SEED_PHOTO_COLOURS.length];
|
|
100
|
+
const text = encodeURIComponent(seedPhotoLabel(seed));
|
|
101
|
+
return seedExtMedia(`${SEED_PHOTO_HOST}/${width}x${height}/${bg}/${SEED_PHOTO_FG}/png?text=${text}`);
|
|
102
|
+
}
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
* @tag sideEffects:none
|
|
15
15
|
*/
|
|
16
16
|
import { withBlogSearchTxt } from "./_helpers/search-txt-wrappers";
|
|
17
|
-
import {
|
|
17
|
+
import { seedPhoto } from "./_helpers/media";
|
|
18
18
|
const NOW = new Date();
|
|
19
19
|
const daysAgo = (n) => new Date(NOW.getTime() - n * 86400000);
|
|
20
20
|
const _rawblogPostsSeedData = [
|
|
@@ -24,8 +24,8 @@ const _rawblogPostsSeedData = [
|
|
|
24
24
|
title: "How to Spot a Genuine Takara-Tomy Beyblade (vs. Counterfeit Clones)",
|
|
25
25
|
slug: "spot-genuine-takara-tomy-beyblade",
|
|
26
26
|
excerpt: "Learn the telltale signs that distinguish a genuine Takara-Tomy Beyblade from a cheap clone — from the laser-etched logo to the weight of the metal driver.",
|
|
27
|
-
content: `<h2>The Laser-Etched Logo</h2><p>Genuine Takara-Tomy Beyblades have a crisp, laser-etched "TAKARA TOMY" logo on the underside of the layer or base. Clones use a shallow, blurry stamp that smudges under a fingernail scratch test.</p><img src="${
|
|
28
|
-
coverImage: { type: "image", url:
|
|
27
|
+
content: `<h2>The Laser-Etched Logo</h2><p>Genuine Takara-Tomy Beyblades have a crisp, laser-etched "TAKARA TOMY" logo on the underside of the layer or base. Clones use a shallow, blurry stamp that smudges under a fingernail scratch test.</p><img src="${seedPhoto("blog-content-image-genuine-beyblade-logo-1-20260101", 1000, 600)}" alt="Close-up of the genuine Takara-Tomy laser-etched logo" /><h2>Weight and Balance</h2><p>A genuine metal-fusion driver has a consistent, dense weight — clones often use lighter zinc alloy that feels noticeably hollow. Spin the beyblade on a flat glass surface: a genuine driver spins true with almost no wobble.</p><img src="${seedPhoto("blog-content-image-genuine-beyblade-weight-2-20260101", 1000, 600)}" alt="Weighing a genuine metal-fusion driver on a digital scale" /><h2>Sticker Print Quality</h2><p>Compare the face-bolt sticker under bright light. Genuine stickers have sharp gradient printing and a slightly raised clear-coat finish. Clone stickers are flat-printed and peel at the edges within weeks.</p>`,
|
|
28
|
+
coverImage: { type: "image", url: seedPhoto("blog-cover-genuine-beyblade-20260101", 1200, 630), alt: "Genuine Takara-Tomy Beyblade close-up" },
|
|
29
29
|
category: "guides",
|
|
30
30
|
tags: ["authentication", "takara-tomy", "beyblade", "counterfeit"],
|
|
31
31
|
isFeatured: true,
|
|
@@ -33,7 +33,7 @@ const _rawblogPostsSeedData = [
|
|
|
33
33
|
publishedAt: daysAgo(30),
|
|
34
34
|
authorId: "user-admin-letitrip",
|
|
35
35
|
authorName: "Mock User 1",
|
|
36
|
-
authorAvatar:
|
|
36
|
+
authorAvatar: seedPhoto("user-avatar-letitrip-admin-20260101", 400, 400),
|
|
37
37
|
readTimeMinutes: 5,
|
|
38
38
|
views: 4200,
|
|
39
39
|
metaTitle: "How to Spot a Genuine Takara-Tomy Beyblade | LetItRip",
|
|
@@ -46,8 +46,8 @@ const _rawblogPostsSeedData = [
|
|
|
46
46
|
title: "Sealed vs. Opened — How Condition Affects Beyblade Resale Value",
|
|
47
47
|
slug: "sealed-vs-opened-beyblade-value",
|
|
48
48
|
excerpt: "A head-to-head look at what actually moves the needle on Beyblade resale price — sealed box premiums, tip wear, and launcher grip condition.",
|
|
49
|
-
content: `<h2>Sealed Box — The Investment Grade</h2><p>A factory-sealed box with an unbroken shrink-wrap seal commands the highest resale premiums, especially for discontinued original-series and Metal Fight releases. Collectors treat sealed stock the way trading-card collectors treat unopened booster boxes.</p><img src="${
|
|
50
|
-
coverImage: { type: "image", url:
|
|
49
|
+
content: `<h2>Sealed Box — The Investment Grade</h2><p>A factory-sealed box with an unbroken shrink-wrap seal commands the highest resale premiums, especially for discontinued original-series and Metal Fight releases. Collectors treat sealed stock the way trading-card collectors treat unopened booster boxes.</p><img src="${seedPhoto("blog-content-image-sealed-beyblade-box-1-20260101", 1000, 600)}" alt="Factory-sealed Beyblade box with intact shrink wrap" /><h2>Tip Wear — The Sub-Grade That Matters</h2><p>For opened, battled beyblades, tip wear is the single biggest value factor. A sharp, unrounded tip with visible factory grooves grades far higher than a rounded, "sanded" tip from heavy stadium use.</p><h2>Launcher Grip Condition</h2><p>Ripcord launchers with clean, unfrayed grip tape and a tight ratchet mechanism add real value to a bundle. A stripped ratchet or fraying cord is an instant discount flag.</p><h2>Our Recommendation</h2><p>For investment: chase sealed, unopened stock. For a battle-ready collection: prioritize tip sharpness and launcher condition over cosmetic sticker wear.</p>`,
|
|
50
|
+
coverImage: { type: "image", url: seedPhoto("blog-cover-sealed-vs-opened-beyblade-20260101", 1200, 630), alt: "Sealed and opened Beyblade boxes side by side" },
|
|
51
51
|
category: "guides",
|
|
52
52
|
tags: ["condition", "sealed", "tip-wear", "beyblade", "investment"],
|
|
53
53
|
isFeatured: true,
|
|
@@ -55,7 +55,7 @@ const _rawblogPostsSeedData = [
|
|
|
55
55
|
publishedAt: daysAgo(25),
|
|
56
56
|
authorId: "user-admin-letitrip",
|
|
57
57
|
authorName: "Mock User 1",
|
|
58
|
-
authorAvatar:
|
|
58
|
+
authorAvatar: seedPhoto("user-avatar-letitrip-admin-20260101", 400, 400),
|
|
59
59
|
readTimeMinutes: 7,
|
|
60
60
|
views: 3800,
|
|
61
61
|
metaTitle: "Sealed vs. Opened — Beyblade Condition & Resale Value | LetItRip",
|
|
@@ -68,15 +68,15 @@ const _rawblogPostsSeedData = [
|
|
|
68
68
|
title: "Complete Beyblade X Series Guide — Every Wave and Value",
|
|
69
69
|
slug: "complete-beyblade-x-series-guide",
|
|
70
70
|
excerpt: "Every Beyblade X wave released so far — from the BX-01 starter line to the latest BX-08 wave — with current market values.",
|
|
71
|
-
content: `<h2>The Starter Waves</h2><p>BX-01 through BX-04 introduced the core X-series parts — Blade, Ratchet, and Bit — replacing the old layer/disk/driver system entirely. Sealed starters from these early waves are already appreciating.</p><img src="${
|
|
72
|
-
coverImage: { type: "image", url:
|
|
71
|
+
content: `<h2>The Starter Waves</h2><p>BX-01 through BX-04 introduced the core X-series parts — Blade, Ratchet, and Bit — replacing the old layer/disk/driver system entirely. Sealed starters from these early waves are already appreciating.</p><img src="${seedPhoto("blog-content-image-beyblade-x-waves-1-20260101", 1000, 600)}" alt="Beyblade X starter wave lineup" /><h2>BX-05 through BX-08 (2025-2026)</h2><p>The current generation. Each piece in sealed condition ranges from ₹500-₹1,200. A complete wave set? Over ₹8,000.</p><h2>Later Waves</h2><p>Limited convention exclusives, gold-finish promos, and various starter-set reprints. Values range from ₹300 for common reprints to ₹5,000+ for rare promotional versions.</p>`,
|
|
72
|
+
coverImage: { type: "image", url: seedPhoto("blog-cover-beyblade-x-guide-20260101", 1200, 630), alt: "Beyblade X series wave lineup" },
|
|
73
73
|
category: "guides",
|
|
74
74
|
tags: ["beyblade-x", "guide", "waves", "values"],
|
|
75
75
|
isFeatured: false,
|
|
76
76
|
status: "draft",
|
|
77
77
|
authorId: "user-admin-letitrip",
|
|
78
78
|
authorName: "Mock User 1",
|
|
79
|
-
authorAvatar:
|
|
79
|
+
authorAvatar: seedPhoto("user-avatar-letitrip-admin-20260101", 400, 400),
|
|
80
80
|
readTimeMinutes: 10,
|
|
81
81
|
views: 0,
|
|
82
82
|
metaTitle: "Complete Beyblade X Series Guide — Every Wave & Value | LetItRip",
|
|
@@ -151,8 +151,8 @@ const _rawblogPostsSeedData = [
|
|
|
151
151
|
title: "Top 10 Most Valuable Vintage Beyblades",
|
|
152
152
|
slug: "top-10-most-valuable-vintage-beyblades",
|
|
153
153
|
excerpt: "From the legendary original-series Dragoon Storm to the elusive tournament-only L-Drago variants — these are the beyblades every collector dreams of.",
|
|
154
|
-
content: `<h2>1. Tournament-Exclusive Gold Dragoon (2000)</h2><p>The rarest original-series beyblade ever distributed. Only handed out at the Japan national finals. Estimated value: over ₹4 lakh.</p><img src="${
|
|
155
|
-
coverImage: { type: "image", url:
|
|
154
|
+
content: `<h2>1. Tournament-Exclusive Gold Dragoon (2000)</h2><p>The rarest original-series beyblade ever distributed. Only handed out at the Japan national finals. Estimated value: over ₹4 lakh.</p><img src="${seedPhoto("blog-content-image-top10-tournament-gold-1-20260101", 1000, 600)}" alt="Tournament-exclusive gold Dragoon beyblade" /><h2>2. Beyblade Original Dragoon Storm, Sealed</h2><p>Tyson's signature spinner in sealed, factory condition. Sealed copies sell for ₹1.5-2.5 lakh.</p><h2>3. Beyblade Metal Lightning L-Drago, Sealed</h2><p>Kai's iconic rival spinner. A sealed Metal Lightning L-Drago commands ₹80,000-1.2 lakh.</p><h2>4. Complete Original-Series Starter Set (all 5 pieces, sealed)</h2><p>All five original-series starter beyblades still sealed — virtually impossible to assemble. Set value: over ₹6 lakh.</p><img src="${seedPhoto("blog-content-image-top10-starter-set-2-20260101", 1000, 600)}" alt="Complete original-series Beyblade starter set" /><h2>5-10</h2><p>Metal Fusion Storm Pegasus (sealed), Metal Fight Flame Sagittario (sealed), Burst Valkyrie tournament promo, Burst Regalia Genesis limited run, original-series Dranzer S first-print, and Driger V arena-exclusive gold edition.</p>`,
|
|
155
|
+
coverImage: { type: "image", url: seedPhoto("blog-cover-top10-vintage-beyblade-20260101", 1200, 630), alt: "Vintage Beyblade collection" },
|
|
156
156
|
category: "news",
|
|
157
157
|
tags: ["top-10", "vintage", "investment", "rare-beyblades"],
|
|
158
158
|
isFeatured: false,
|
|
@@ -160,7 +160,7 @@ const _rawblogPostsSeedData = [
|
|
|
160
160
|
publishedAt: daysAgo(20),
|
|
161
161
|
authorId: "user-admin-letitrip",
|
|
162
162
|
authorName: "Mock User 1",
|
|
163
|
-
authorAvatar:
|
|
163
|
+
authorAvatar: seedPhoto("user-avatar-letitrip-admin-20260101", 400, 400),
|
|
164
164
|
readTimeMinutes: 8,
|
|
165
165
|
views: 6100,
|
|
166
166
|
metaTitle: "Top 10 Most Valuable Vintage Beyblades | LetItRip",
|
|
@@ -234,8 +234,8 @@ const _rawblogPostsSeedData = [
|
|
|
234
234
|
title: "Metal Fight Hidden Gems: Undervalued Beyblades from the 2009-2012 Era",
|
|
235
235
|
slug: "metal-fight-hidden-gems",
|
|
236
236
|
excerpt: "The Metal Fight era produced some of the most undervalued beyblades in collecting history. Here are the picks smart collectors are buying now.",
|
|
237
|
-
content: `<h2>Why Metal Fight Beyblades Are Undervalued</h2><p>The Metal Fight era (2009-2012) coincided with peak Beyblade anime popularity but many collectors focus exclusively on the original 1999-2003 series. This creates a pricing gap.</p><img src="${
|
|
238
|
-
coverImage: { type: "image", url:
|
|
237
|
+
content: `<h2>Why Metal Fight Beyblades Are Undervalued</h2><p>The Metal Fight era (2009-2012) coincided with peak Beyblade anime popularity but many collectors focus exclusively on the original 1999-2003 series. This creates a pricing gap.</p><img src="${seedPhoto("blog-content-image-metal-fight-gems-1-20260101", 1000, 600)}" alt="Metal Fight era Beyblade lineup" /><h2>Metal Fight Picks</h2><p><strong>Metal Storm Pegasus</strong> — the fan-favorite protagonist spinner. Sealed copies are still affordable at ₹1,500-₹2,500.</p><p><strong>Metal Flame Sagittario</strong> — one of the most competitively impactful attack types ever. Sealed condition commands ₹3,500-₹5,000.</p><p><strong>Rare 4D System variants</strong> — low print run makes these a sleeper investment.</p>`,
|
|
238
|
+
coverImage: { type: "image", url: seedPhoto("blog-cover-metal-fight-gems-20260101", 1200, 630), alt: "Metal Fight Beyblade collection" },
|
|
239
239
|
category: "tips",
|
|
240
240
|
tags: ["metal-fight", "hidden-gems", "investment", "beyblade"],
|
|
241
241
|
isFeatured: false,
|
|
@@ -243,7 +243,7 @@ const _rawblogPostsSeedData = [
|
|
|
243
243
|
publishedAt: daysAgo(15),
|
|
244
244
|
authorId: "user-admin-letitrip",
|
|
245
245
|
authorName: "Mock User 1",
|
|
246
|
-
authorAvatar:
|
|
246
|
+
authorAvatar: seedPhoto("user-avatar-letitrip-admin-20260101", 400, 400),
|
|
247
247
|
readTimeMinutes: 6,
|
|
248
248
|
views: 2900,
|
|
249
249
|
metaTitle: "Metal Fight Hidden Gems — Undervalued Beyblades | LetItRip",
|
|
@@ -318,7 +318,7 @@ const _rawblogPostsSeedData = [
|
|
|
318
318
|
slug: "authenticating-beyblades",
|
|
319
319
|
excerpt: "A behind-the-scenes look at how verified sellers on LetItRip check every beyblade before listing — logo tests, weight checks, and spin-balance inspection.",
|
|
320
320
|
content: `<h2>The 5-Point Authentication Process</h2><p>Every beyblade listed by top verified stores goes through a rigorous 5-point check:</p><ol><li><strong>Logo Test</strong> — Genuine Takara-Tomy pieces have a specific laser-etched depth and clarity when checked under raking light.</li><li><strong>Weight Check</strong> — A genuine metal-fusion driver weighs within a tight factory tolerance verified on a digital scale.</li><li><strong>Spin-Balance Test</strong> — Each layer/driver combo is spin-tested on a flat glass surface; genuine parts spin true with minimal wobble.</li><li><strong>Sticker Print Inspection</strong> — Under 10x magnification, genuine face-bolt stickers show sharp gradient printing and a raised clear-coat.</li><li><strong>Ratchet & Grip Inspection</strong> — Check the launcher for a tight ratchet mechanism and unfrayed grip tape.</li></ol>`,
|
|
321
|
-
coverImage: { type: "image", url:
|
|
321
|
+
coverImage: { type: "image", url: seedPhoto("blog-cover-authenticating-beyblades-20260101", 1200, 630), alt: "Beyblade authentication process" },
|
|
322
322
|
category: "community",
|
|
323
323
|
tags: ["authentication", "verification", "counterfeit", "beyblade"],
|
|
324
324
|
isFeatured: false,
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
* @tag consumers:seed/index.ts,seed/runner.ts
|
|
18
18
|
* @tag sideEffects:none
|
|
19
19
|
*/
|
|
20
|
-
import {
|
|
20
|
+
import { seedPhoto } from "./_helpers/media";
|
|
21
21
|
import { ROUTES } from "../next/routing/route-map";
|
|
22
22
|
const NOW = new Date();
|
|
23
23
|
const daysAgo = (n) => new Date(NOW.getTime() - n * 86400000);
|
|
@@ -29,7 +29,7 @@ const _rawSlides = [
|
|
|
29
29
|
active: true,
|
|
30
30
|
background: {
|
|
31
31
|
type: "image",
|
|
32
|
-
url:
|
|
32
|
+
url: seedPhoto("carousel-hero-homepage-20260101", 1600, 700),
|
|
33
33
|
dimOverlay: { enabled: true, opacity: 0.5 },
|
|
34
34
|
},
|
|
35
35
|
settings: { autoplayDelayMs: 5000, height: "tall" },
|
|
@@ -49,7 +49,7 @@ const _rawSlides = [
|
|
|
49
49
|
// (rejects non-image content-type with 400). MediaVideo watermarks
|
|
50
50
|
// video client-side instead, so the raw external URL is correct here.
|
|
51
51
|
url: "https://storage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4", // audit-seed-external-url-ok: raw <video> src, /api/media/ext is image-only (Root Cause #27)
|
|
52
|
-
thumbnail:
|
|
52
|
+
thumbnail: seedPhoto("carousel-auctions-live-20260101", 1600, 700),
|
|
53
53
|
dimOverlay: { enabled: true, opacity: 0.4 },
|
|
54
54
|
},
|
|
55
55
|
link: { url: String(ROUTES.PUBLIC.AUCTIONS), openInNewTab: false },
|
|
@@ -65,7 +65,7 @@ const _rawSlides = [
|
|
|
65
65
|
active: true,
|
|
66
66
|
background: {
|
|
67
67
|
type: "image",
|
|
68
|
-
url:
|
|
68
|
+
url: seedPhoto("carousel-complete-collection-20260101", 1600, 700),
|
|
69
69
|
dimOverlay: { enabled: true, opacity: 0.45 },
|
|
70
70
|
},
|
|
71
71
|
link: { url: String(ROUTES.PUBLIC.PRODUCTS), openInNewTab: false },
|
|
@@ -81,7 +81,7 @@ const _rawSlides = [
|
|
|
81
81
|
active: true,
|
|
82
82
|
background: {
|
|
83
83
|
type: "image",
|
|
84
|
-
url:
|
|
84
|
+
url: seedPhoto("carousel-preorders-open-20260101", 1600, 700),
|
|
85
85
|
dimOverlay: { enabled: true, opacity: 0.4 },
|
|
86
86
|
},
|
|
87
87
|
link: { url: String(ROUTES.PUBLIC.PRE_ORDERS), openInNewTab: false },
|
|
@@ -97,7 +97,7 @@ const _rawSlides = [
|
|
|
97
97
|
active: true,
|
|
98
98
|
background: {
|
|
99
99
|
type: "image",
|
|
100
|
-
url:
|
|
100
|
+
url: seedPhoto("carousel-authenticated-originals-20260101", 1600, 700),
|
|
101
101
|
dimOverlay: { enabled: true, opacity: 0.5 },
|
|
102
102
|
},
|
|
103
103
|
link: { url: String(ROUTES.PUBLIC.CATEGORY_DETAIL("category-spinning-tops")), openInNewTab: false },
|
|
@@ -113,7 +113,7 @@ const _rawSlides = [
|
|
|
113
113
|
active: false,
|
|
114
114
|
background: {
|
|
115
115
|
type: "image",
|
|
116
|
-
url:
|
|
116
|
+
url: seedPhoto("carousel-tournament-promo-20260101", 1600, 700),
|
|
117
117
|
dimOverlay: { enabled: true, opacity: 0.5 },
|
|
118
118
|
},
|
|
119
119
|
settings: { autoplayDelayMs: 5000, height: "tall" },
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
* @tag sideEffects:none
|
|
14
14
|
*/
|
|
15
15
|
import { getDefaultCurrency } from "./seed-market-config";
|
|
16
|
-
import {
|
|
16
|
+
import { seedPhoto } from "./_helpers/media";
|
|
17
17
|
const _CURRENCY = getDefaultCurrency();
|
|
18
18
|
const NOW = new Date();
|
|
19
19
|
const daysAgo = (n) => new Date(NOW.getTime() - n * 86400000);
|
|
@@ -27,7 +27,7 @@ export const cartsSeedData = [
|
|
|
27
27
|
itemId: "cartitem-yugi-original-dranzer-s",
|
|
28
28
|
productId: "product-beyblade-original-dranzer-s",
|
|
29
29
|
productTitle: "Beyblade Original Dranzer S",
|
|
30
|
-
productImage:
|
|
30
|
+
productImage: seedPhoto("product-image-original-dranzer-s-1-20260101", 600, 600),
|
|
31
31
|
price: 1799,
|
|
32
32
|
currency: _CURRENCY,
|
|
33
33
|
quantity: 1,
|
|
@@ -41,7 +41,7 @@ export const cartsSeedData = [
|
|
|
41
41
|
itemId: "cartitem-yugi-x-bx08-preorder-deposit",
|
|
42
42
|
productId: "preorder-beyblade-x-bx-08-wave",
|
|
43
43
|
productTitle: "Beyblade X BX-08 Wave — Pre-Order",
|
|
44
|
-
productImage:
|
|
44
|
+
productImage: seedPhoto("preorder-image-x-bx08-wave-1-20260101", 600, 600),
|
|
45
45
|
price: 899,
|
|
46
46
|
currency: _CURRENCY,
|
|
47
47
|
quantity: 2,
|
|
@@ -55,7 +55,7 @@ export const cartsSeedData = [
|
|
|
55
55
|
itemId: "cartitem-yugi-stadium-set",
|
|
56
56
|
productId: "classified-beyblade-stadium-set",
|
|
57
57
|
productTitle: "Beyblade Stadium Set",
|
|
58
|
-
productImage:
|
|
58
|
+
productImage: seedPhoto("classified-image-stadium-set-1-20260101", 600, 600),
|
|
59
59
|
price: 1299,
|
|
60
60
|
currency: _CURRENCY,
|
|
61
61
|
quantity: 1,
|
|
@@ -69,7 +69,7 @@ export const cartsSeedData = [
|
|
|
69
69
|
itemId: "cartitem-yugi-dragoon-storm-auction-won",
|
|
70
70
|
productId: "auction-beyblade-original-dragoon-storm",
|
|
71
71
|
productTitle: "Beyblade Original Dragoon Storm — Won Auction",
|
|
72
|
-
productImage:
|
|
72
|
+
productImage: seedPhoto("auction-image-dragoon-storm-1-20260101", 600, 600),
|
|
73
73
|
price: 3499,
|
|
74
74
|
currency: _CURRENCY,
|
|
75
75
|
quantity: 1,
|
|
@@ -84,7 +84,7 @@ export const cartsSeedData = [
|
|
|
84
84
|
itemId: "cartitem-yugi-dranzer-offer-accepted",
|
|
85
85
|
productId: "product-beyblade-original-dranzer-s",
|
|
86
86
|
productTitle: "Beyblade Original Dranzer S — Offer Accepted",
|
|
87
|
-
productImage:
|
|
87
|
+
productImage: seedPhoto("product-image-original-dranzer-s-2-20260101", 600, 600),
|
|
88
88
|
price: 1799,
|
|
89
89
|
currency: _CURRENCY,
|
|
90
90
|
quantity: 1,
|
|
@@ -111,7 +111,7 @@ export const cartsSeedData = [
|
|
|
111
111
|
itemId: "cartitem-kaiba-metal-flame-sagittario",
|
|
112
112
|
productId: "product-beyblade-metal-flame-sagittario",
|
|
113
113
|
productTitle: "Beyblade Metal Flame Sagittario",
|
|
114
|
-
productImage:
|
|
114
|
+
productImage: seedPhoto("product-image-metal-flame-sagittario-1-20260101", 600, 600),
|
|
115
115
|
price: 2299,
|
|
116
116
|
currency: _CURRENCY,
|
|
117
117
|
quantity: 1,
|
|
@@ -125,7 +125,7 @@ export const cartsSeedData = [
|
|
|
125
125
|
itemId: "cartitem-kaiba-x-app-unlock",
|
|
126
126
|
productId: "digitalcode-beyblade-x-app-unlock",
|
|
127
127
|
productTitle: "Beyblade X App Unlock Code",
|
|
128
|
-
productImage:
|
|
128
|
+
productImage: seedPhoto("digitalcode-image-x-app-unlock-1-20260101", 600, 600),
|
|
129
129
|
price: 199,
|
|
130
130
|
currency: _CURRENCY,
|
|
131
131
|
quantity: 1,
|
|
@@ -139,7 +139,7 @@ export const cartsSeedData = [
|
|
|
139
139
|
itemId: "cartitem-kaiba-x-bx08-preorder",
|
|
140
140
|
productId: "preorder-beyblade-x-bx-08-wave",
|
|
141
141
|
productTitle: "Beyblade X BX-08 Wave — Pre-Order",
|
|
142
|
-
productImage:
|
|
142
|
+
productImage: seedPhoto("preorder-image-x-bx08-wave-2-20260101", 600, 600),
|
|
143
143
|
price: 899,
|
|
144
144
|
currency: _CURRENCY,
|
|
145
145
|
quantity: 1,
|
|
@@ -162,7 +162,7 @@ export const cartsSeedData = [
|
|
|
162
162
|
itemId: "cartitem-admin-x-knife-shinobi",
|
|
163
163
|
productId: "product-beyblade-x-knife-shinobi",
|
|
164
164
|
productTitle: "Beyblade X Knife Shinobi",
|
|
165
|
-
productImage:
|
|
165
|
+
productImage: seedPhoto("product-image-x-knife-shinobi-1-20260101", 600, 600),
|
|
166
166
|
price: 2999,
|
|
167
167
|
currency: _CURRENCY,
|
|
168
168
|
quantity: 1,
|
|
@@ -176,7 +176,7 @@ export const cartsSeedData = [
|
|
|
176
176
|
itemId: "cartitem-admin-mystery-box",
|
|
177
177
|
productId: "prizedraw-beyblade-mystery-box",
|
|
178
178
|
productTitle: "Beyblade Mystery Box",
|
|
179
|
-
productImage:
|
|
179
|
+
productImage: seedPhoto("prizedraw-image-mystery-box-1-20260101", 600, 600),
|
|
180
180
|
price: 499,
|
|
181
181
|
currency: _CURRENCY,
|
|
182
182
|
quantity: 1,
|
|
@@ -199,7 +199,7 @@ export const cartsSeedData = [
|
|
|
199
199
|
itemId: "cartitem-guest-metal-storm-pegasus",
|
|
200
200
|
productId: "product-beyblade-metal-storm-pegasus",
|
|
201
201
|
productTitle: "Beyblade Metal Storm Pegasus",
|
|
202
|
-
productImage:
|
|
202
|
+
productImage: seedPhoto("product-image-metal-storm-pegasus-1-20260101", 600, 600),
|
|
203
203
|
price: 2499,
|
|
204
204
|
currency: _CURRENCY,
|
|
205
205
|
quantity: 1,
|
|
@@ -213,7 +213,7 @@ export const cartsSeedData = [
|
|
|
213
213
|
itemId: "cartitem-guest-burst-valkyrie",
|
|
214
214
|
productId: "product-beyblade-burst-valkyrie",
|
|
215
215
|
productTitle: "Beyblade Burst Valkyrie",
|
|
216
|
-
productImage:
|
|
216
|
+
productImage: seedPhoto("product-image-burst-valkyrie-1-20260101", 600, 600),
|
|
217
217
|
price: 1899,
|
|
218
218
|
currency: _CURRENCY,
|
|
219
219
|
quantity: 1,
|