@mohasinac/appkit 4.42.18 → 4.44.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/lottery/LotteryDetailView.js +22 -1
- package/dist/_internal/server/features/categories/adapters.d.ts +47 -0
- package/dist/_internal/server/features/categories/adapters.js +235 -0
- package/dist/_internal/server/features/checkout/actions.js +161 -22
- package/dist/_internal/server/features/checkout/expand-order-items.js +34 -0
- package/dist/_internal/server/features/orders/adapters.js +21 -0
- package/dist/_internal/server/features/products/list-public.d.ts +24 -0
- package/dist/_internal/server/features/products/list-public.js +10 -2
- package/dist/_internal/server/features/refunds/actions.js +1 -1
- package/dist/_internal/server/features/seo/sitemap.js +54 -15
- package/dist/_internal/server/features/stores/adapters.d.ts +1 -1
- package/dist/_internal/server/features/stores/adapters.js +6 -0
- package/dist/_internal/server/functions/scheduled.d.ts +4 -2
- package/dist/_internal/server/functions/scheduled.js +64 -6
- package/dist/_internal/server/jobs/core/adminAnalytics.d.ts +0 -1
- package/dist/_internal/server/jobs/core/adminAnalytics.js +9 -1
- package/dist/_internal/server/jobs/core/analyticsAlertEvaluate.d.ts +47 -0
- package/dist/_internal/server/jobs/core/analyticsAlertEvaluate.js +468 -0
- package/dist/_internal/server/jobs/core/autoPayoutEligibility.js +14 -1
- package/dist/_internal/server/jobs/core/countersReconcile.js +24 -8
- package/dist/_internal/server/jobs/core/onCategoryWrite.js +59 -0
- package/dist/_internal/server/jobs/core/onProductWrite.js +31 -0
- package/dist/_internal/server/jobs/core/onReviewWrite.js +8 -0
- package/dist/_internal/server/jobs/core/onStoreWrite.d.ts +1 -1
- package/dist/_internal/server/jobs/core/onStoreWrite.js +8 -2
- package/dist/_internal/server/jobs/core/priceIndexRollup.d.ts +47 -0
- package/dist/_internal/server/jobs/core/priceIndexRollup.js +234 -0
- package/dist/_internal/server/jobs/core/revalidateNotify.d.ts +28 -0
- package/dist/_internal/server/jobs/core/revalidateNotify.js +125 -0
- package/dist/_internal/server/jobs/core/{testerSandboxCleanup.d.ts → testDataCleanup.d.ts} +3 -3
- package/dist/_internal/server/jobs/core/{testerSandboxCleanup.js → testDataCleanup.js} +3 -3
- package/dist/_internal/server/jobs/core/weeklyPayoutEligibility.js +5 -1
- package/dist/_internal/server/jobs/handlers/analyticsAlertEvaluate.d.ts +2 -0
- package/dist/_internal/server/jobs/handlers/analyticsAlertEvaluate.js +2 -0
- package/dist/_internal/server/jobs/handlers/index.d.ts +3 -1
- package/dist/_internal/server/jobs/handlers/index.js +3 -1
- package/dist/_internal/server/jobs/handlers/messages.d.ts +5 -2
- package/dist/_internal/server/jobs/handlers/messages.js +5 -2
- package/dist/_internal/server/jobs/handlers/priceIndexRollup.d.ts +2 -0
- package/dist/_internal/server/jobs/handlers/priceIndexRollup.js +2 -0
- package/dist/_internal/server/jobs/handlers/testDataCleanup.d.ts +2 -0
- package/dist/_internal/server/jobs/handlers/testDataCleanup.js +2 -0
- package/dist/_internal/shared/actions/action-registry.js +34 -0
- package/dist/_internal/shared/cache/revalidate-targets.d.ts +49 -0
- package/dist/_internal/shared/cache/revalidate-targets.js +157 -0
- package/dist/_internal/shared/checkout/order-math.d.ts +113 -3
- package/dist/_internal/shared/checkout/order-math.js +194 -7
- package/dist/_internal/shared/features/categories/price-guidance.d.ts +110 -0
- package/dist/_internal/shared/features/categories/price-guidance.js +136 -0
- package/dist/_internal/shared/features/site-settings/gst-registration.d.ts +90 -0
- package/dist/_internal/shared/features/site-settings/gst-registration.js +126 -0
- package/dist/_internal/shared/fees/calculator.d.ts +105 -0
- package/dist/_internal/shared/fees/calculator.js +143 -0
- package/dist/_internal/shared/listing-types/art/config.d.ts +0 -6
- package/dist/_internal/shared/listing-types/classified/config.d.ts +0 -6
- package/dist/_internal/shared/listing-types/digital-code/config.d.ts +0 -6
- package/dist/_internal/shared/listing-types/live/config.d.ts +0 -6
- package/dist/_internal/shared/listing-types/standard/config.d.ts +0 -6
- package/dist/_internal/shared/listing-types/stickers/config.d.ts +0 -6
- package/dist/_internal/shared/templating/placeholders.d.ts +70 -0
- package/dist/_internal/shared/templating/placeholders.js +73 -0
- package/dist/client.d.ts +2 -0
- package/dist/client.js +1 -0
- package/dist/constants/api-endpoints.d.ts +42 -0
- package/dist/constants/api-endpoints.js +14 -0
- package/dist/features/admin/actions/admin-actions.d.ts +1 -1
- package/dist/features/admin/actions/admin-actions.js +1 -1
- package/dist/features/admin/components/AdminCategoryEditorView.js +269 -3
- package/dist/features/admin/components/AdminProductEditorView.js +8 -1
- package/dist/features/admin/components/AdminProductsView.js +78 -7
- package/dist/features/admin/components/AdminSiteSettingsView.js +20 -1
- package/dist/features/admin/components/AdminTaxCodeEditorView.d.ts +10 -0
- package/dist/features/admin/components/AdminTaxCodeEditorView.js +160 -0
- package/dist/features/admin/components/AdminTaxCodesView.d.ts +13 -0
- package/dist/features/admin/components/AdminTaxCodesView.js +86 -0
- package/dist/features/admin/components/AdminTesterChecklistView.js +1 -1
- package/dist/features/admin/components/analytics/AdminTopProductsTable.js +1 -1
- package/dist/features/auctions/components/AuctionBottomActions.js +10 -1
- package/dist/features/auctions/components/AuctionDetailPageView.js +2 -1
- package/dist/features/auctions/components/AuctionLiveStatusBadge.d.ts +20 -0
- package/dist/features/auctions/components/AuctionLiveStatusBadge.js +21 -0
- package/dist/features/auctions/components/PlaceBidFormClient.d.ts +1 -1
- package/dist/features/auctions/components/PlaceBidFormClient.js +20 -2
- package/dist/features/auctions/hooks/useIsAuctionEnded.d.ts +41 -0
- package/dist/features/auctions/hooks/useIsAuctionEnded.js +76 -0
- package/dist/features/auth/schemas/firestore.d.ts +0 -1
- package/dist/features/blog/api/route.js +16 -1
- package/dist/features/blog/schemas/firestore.d.ts +2 -2
- package/dist/features/catalogue/components/CatalogueItemEditorView.js +14 -3
- package/dist/features/categories/actions/category-actions.d.ts +2 -2
- package/dist/features/categories/actions/category-actions.js +22 -10
- package/dist/features/categories/api/[id]/description-template/route.d.ts +45 -0
- package/dist/features/categories/api/[id]/description-template/route.js +252 -0
- package/dist/features/categories/api/route.js +156 -11
- package/dist/features/categories/components/CategoriesIndexListing.d.ts +1 -3
- package/dist/features/categories/components/CategoriesIndexListing.js +1 -1
- package/dist/features/categories/components/CategoriesIndexPageView.d.ts +27 -1
- package/dist/features/categories/components/CategoriesIndexPageView.js +24 -33
- package/dist/features/categories/components/CategoryDetailPageView.js +43 -10
- package/dist/features/categories/components/CategoryTemplatePicker.d.ts +65 -0
- package/dist/features/categories/components/CategoryTemplatePicker.js +170 -0
- package/dist/features/categories/constants/listing-categories.d.ts +17 -0
- package/dist/features/categories/constants/listing-categories.js +53 -0
- package/dist/features/categories/hooks/useCategoryTree.js +28 -2
- package/dist/features/categories/repository/categories.repository.d.ts +73 -12
- package/dist/features/categories/repository/categories.repository.js +203 -42
- package/dist/features/categories/repository/price-index.repository.d.ts +115 -0
- package/dist/features/categories/repository/price-index.repository.js +85 -0
- package/dist/features/categories/schemas/category-content.d.ts +206 -0
- package/dist/features/categories/schemas/category-content.js +28 -0
- package/dist/features/categories/schemas/firestore.d.ts +74 -5
- package/dist/features/categories/schemas/firestore.js +74 -3
- package/dist/features/categories/schemas/index.d.ts +1047 -0
- package/dist/features/categories/schemas/index.js +96 -0
- package/dist/features/categories/server.d.ts +1 -0
- package/dist/features/categories/server.js +7 -0
- package/dist/features/categories/types/index.d.ts +9 -0
- package/dist/features/events/schemas/firestore.d.ts +2 -2
- package/dist/features/faq/schemas/firestore.d.ts +2 -1
- package/dist/features/faq/schemas/firestore.js +20 -8
- package/dist/features/faq/utils/getHomepageFaqsCached.d.ts +20 -0
- package/dist/features/faq/utils/getHomepageFaqsCached.js +22 -0
- package/dist/features/homepage/components/MarketplaceHomepageView.js +13 -3
- package/dist/features/homepage/lib/live-stats.js +18 -8
- package/dist/features/media/MediaImage.js +19 -2
- package/dist/features/orders/schemas/firestore.d.ts +70 -0
- package/dist/features/orders/types/index.d.ts +55 -0
- package/dist/features/products/actions/product-actions.d.ts +0 -9
- package/dist/features/products/actions/product-actions.js +25 -0
- package/dist/features/products/columns/index.d.ts +0 -1
- package/dist/features/products/columns/index.js +5 -1
- package/dist/features/products/components/ArtStickersListView.js +7 -1
- package/dist/features/products/components/PrizeDrawsSection.js +5 -0
- package/dist/features/products/components/ProductFilters.d.ts +0 -9
- package/dist/features/products/components/ProductForm.d.ts +27 -1
- package/dist/features/products/components/ProductForm.js +26 -12
- package/dist/features/products/components/ProductsIndexPageView.js +1 -1
- package/dist/features/products/constants/sieve.d.ts +0 -6
- package/dist/features/products/constants/sieve.js +35 -2
- package/dist/features/products/repository/products.repository.d.ts +115 -1
- package/dist/features/products/repository/products.repository.js +491 -39
- package/dist/features/products/schemas/firestore.d.ts +65 -5
- package/dist/features/products/schemas/firestore.js +9 -0
- package/dist/features/products/schemas/product-features.d.ts +140 -2
- package/dist/features/products/schemas/product-features.js +62 -1
- package/dist/features/promotions/repository/coupons.repository.js +6 -1
- package/dist/features/promotions/schemas/firestore.d.ts +44 -1
- package/dist/features/promotions/schemas/firestore.js +76 -2
- package/dist/features/reviews/repository/reviews.repository.d.ts +22 -0
- package/dist/features/reviews/repository/reviews.repository.js +35 -0
- package/dist/features/seller/actions/seller-actions.js +17 -2
- package/dist/features/seller/components/PrintCenterView.d.ts +3 -2
- package/dist/features/seller/components/PrintCenterView.js +3 -2
- package/dist/features/seller/components/SellerAnalyticsAlertsView.js +21 -11
- package/dist/features/seller/components/SellerOrdersView.js +6 -1
- package/dist/features/seller/components/SellerPayoutSettingsView.js +19 -3
- package/dist/features/seller/components/SellerProductShell.d.ts +50 -2
- package/dist/features/seller/components/SellerProductShell.js +101 -9
- package/dist/features/seller/components/SellerProductsFilterDrawer.d.ts +13 -1
- package/dist/features/seller/components/SellerProductsFilterDrawer.js +2 -2
- package/dist/features/seller/components/SellerProductsView.js +108 -3
- package/dist/features/seller/types/index.d.ts +17 -0
- package/dist/features/seller/utils/product-draft-mapping.d.ts +13 -0
- package/dist/features/seller/utils/product-draft-mapping.js +17 -0
- package/dist/features/store-extensions/constants/alert-metrics.d.ts +86 -0
- package/dist/features/store-extensions/constants/alert-metrics.js +142 -0
- package/dist/features/store-extensions/schemas/firestore.d.ts +19 -1
- package/dist/features/stores/schemas/firestore.d.ts +31 -2
- package/dist/features/tax-codes/repository/tax-codes.repository.d.ts +55 -0
- package/dist/features/tax-codes/repository/tax-codes.repository.js +131 -0
- package/dist/features/tax-codes/schemas/firestore.d.ts +125 -0
- package/dist/features/tax-codes/schemas/firestore.js +82 -0
- package/dist/features/tax-codes/schemas/tax-code-form.d.ts +63 -0
- package/dist/features/tax-codes/schemas/tax-code-form.js +152 -0
- package/dist/features/tax-codes/schemas/tax-codes.validators.d.ts +107 -0
- package/dist/features/tax-codes/schemas/tax-codes.validators.js +85 -0
- package/dist/features/tester/actions/index.d.ts +0 -1
- package/dist/features/tester/actions/index.js +0 -1
- package/dist/features/tester/components/AdminTesterFeedbackIssuesView.js +1 -1
- package/dist/features/tester/components/AdminTesterFeedbackListView.js +1 -1
- package/dist/features/tester/components/index.d.ts +0 -4
- package/dist/features/tester/components/index.js +0 -2
- package/dist/features/tester/repository/tester-checklist-item.repository.d.ts +1 -20
- package/dist/features/tester/repository/tester-checklist-item.repository.js +0 -52
- package/dist/features/tester/schemas/firestore.d.ts +0 -6
- package/dist/features/tester/seed-data/authored/admin__admin-detail-round-trips.js +3 -3
- package/dist/features/tester/seed-data/authored/admin__site-system.js +4 -5
- package/dist/features/tester/seed-data/authored/content-discovery__category-counts-and-rollup.js +2 -2
- package/dist/features/tester/seed-data/authored/index.js +0 -2
- package/dist/features/tester/seed-data/authored/page-wiring__reachability.js +0 -19
- package/dist/features/tester/seed-data/tester-checklist-seed-data.js +10 -29
- package/dist/index.d.ts +21 -7
- package/dist/index.js +53 -7
- package/dist/next/routing/route-map.d.ts +2 -4
- package/dist/next/routing/route-map.js +1 -2
- package/dist/repositories/index.d.ts +1 -0
- package/dist/repositories/index.js +1 -0
- package/dist/schemas/registry.d.ts +506 -0
- package/dist/seed/_helpers/brand-rows.d.ts +35 -0
- package/dist/seed/_helpers/brand-rows.js +576 -0
- package/dist/seed/_helpers/category-content.d.ts +39 -0
- package/dist/seed/_helpers/category-content.js +634 -0
- package/dist/seed/_helpers/category-forest.d.ts +2 -0
- package/dist/seed/_helpers/category-forest.js +585 -243
- package/dist/seed/_helpers/category-models.d.ts +5 -0
- package/dist/seed/_helpers/category-models.js +1364 -0
- package/dist/seed/_helpers/category-tree.js +17 -1
- package/dist/seed/_helpers/character-features.d.ts +10 -0
- package/dist/seed/_helpers/character-features.js +118 -0
- package/dist/seed/_helpers/media.d.ts +1 -1
- package/dist/seed/_helpers/media.js +44 -8
- package/dist/seed/_helpers/search-txt-wrappers.d.ts +10 -0
- package/dist/seed/_helpers/search-txt-wrappers.js +12 -1
- package/dist/seed/categories-seed-data.js +147 -169
- package/dist/seed/index.d.ts +1 -0
- package/dist/seed/index.js +1 -0
- package/dist/seed/manifest.d.ts +1 -1
- package/dist/seed/manifest.js +5 -0
- package/dist/seed/orders-seed-data.js +5 -3
- package/dist/seed/product-features-seed-data.d.ts +1 -8
- package/dist/seed/product-features-seed-data.js +358 -154
- package/dist/seed/products-art-seed-data.js +16 -4
- package/dist/seed/products-auctions-seed-data.js +6 -6
- package/dist/seed/products-classifieds-seed-data.js +17 -7
- package/dist/seed/products-digital-codes-seed-data.js +12 -12
- package/dist/seed/products-preorders-seed-data.js +8 -8
- package/dist/seed/products-prize-draws-seed-data.js +25 -8
- package/dist/seed/products-standard-seed-data.js +10 -60
- package/dist/seed/products-stickers-seed-data.js +6 -6
- package/dist/seed/site-settings-seed-data.js +24 -0
- package/dist/seed/store-extensions-seed-data.js +10 -4
- package/dist/seed/tax-codes-seed-data.d.ts +34 -0
- package/dist/seed/tax-codes-seed-data.js +100 -0
- package/dist/seed/test-data-ttl.d.ts +29 -0
- package/dist/seed/test-data-ttl.js +31 -0
- package/dist/server-entry.d.ts +1 -1
- package/dist/server-entry.js +6 -1
- package/dist/server.d.ts +4 -1
- package/dist/server.js +11 -2
- package/dist/styles.css +40 -0
- package/dist/ui/components/PaginatedSelect.d.ts +14 -0
- package/dist/ui/components/PaginatedSelect.js +0 -0
- package/dist/ui/components/PaginatedSelect.style.css +40 -0
- package/dist/utils/media-url.d.ts +26 -0
- package/dist/utils/media-url.js +144 -0
- package/dist/utils/physical-location.d.ts +23 -0
- package/dist/utils/physical-location.js +52 -0
- package/dist/utils/search-txt-builders.d.ts +20 -0
- package/dist/utils/search-txt-builders.js +36 -0
- package/package.json +1 -1
- package/scripts/seed-cli.mjs +4 -1
- package/dist/_internal/server/jobs/handlers/testerSandboxCleanup.d.ts +0 -2
- package/dist/_internal/server/jobs/handlers/testerSandboxCleanup.js +0 -2
- package/dist/features/tester/actions/leaderboard-actions.d.ts +0 -3
- package/dist/features/tester/actions/leaderboard-actions.js +0 -5
- package/dist/features/tester/components/BugHunterLeaderboardView.d.ts +0 -23
- package/dist/features/tester/components/BugHunterLeaderboardView.js +0 -18
- package/dist/features/tester/components/TesterHubView.d.ts +0 -5
- package/dist/features/tester/components/TesterHubView.js +0 -110
- package/dist/features/tester/seed-data/authored/public-pages__bug-hunters.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/public-pages__bug-hunters.js +0 -78
- package/dist/features/tester/seed-data/tester-ttl.d.ts +0 -4
- package/dist/features/tester/seed-data/tester-ttl.js +0 -6
|
@@ -36,7 +36,23 @@
|
|
|
36
36
|
*/
|
|
37
37
|
export function buildCategoryTree(roots, opts) {
|
|
38
38
|
const rows = [];
|
|
39
|
-
|
|
39
|
+
/*
|
|
40
|
+
* 🛑 1-BASED, and that is not cosmetic — it must match `positionsReconcile`,
|
|
41
|
+
* which starts its own DFS at `let counter = 1`.
|
|
42
|
+
*
|
|
43
|
+
* This counter started at 0 until 2026-10-10. The nightly reconcile then
|
|
44
|
+
* found every row off by one (`current.position !== position`) and rewrote
|
|
45
|
+
* the entire collection on the first run after any reseed — 58 writes then,
|
|
46
|
+
* ~330 once the catalogue grows, each re-entering `onCategoryWrite` as a
|
|
47
|
+
* no-op invocation. Measured in production before the change: seed emits
|
|
48
|
+
* 0..57, live data reads 1..58, i.e. the reconcile had already corrected
|
|
49
|
+
* all of it.
|
|
50
|
+
*
|
|
51
|
+
* It also makes position 0 UNAMBIGUOUS, which `handleCategoryWrite` now
|
|
52
|
+
* relies on: a document arriving with `position >= 1` was numbered by this
|
|
53
|
+
* builder, and one with 0/absent was not.
|
|
54
|
+
*/
|
|
55
|
+
let position = 1;
|
|
40
56
|
function visit(node, rootId,
|
|
41
57
|
/** Ancestors nearest-last, matching how `parentIds` is read elsewhere. */
|
|
42
58
|
ancestors, tier, parentPath, order) {
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/** A blader, and how many canonical beys the corpus attributes to them. */
|
|
2
|
+
export interface CharacterSeed {
|
|
3
|
+
/** Without the `feature-` prefix — the factory prepends it. */
|
|
4
|
+
slug: string;
|
|
5
|
+
name: string;
|
|
6
|
+
/** Canonical beys owned. Drives display order; not stored on the row. */
|
|
7
|
+
beyCount: number;
|
|
8
|
+
}
|
|
9
|
+
export declare const CHARACTER_SEEDS: CharacterSeed[];
|
|
10
|
+
export declare const CHARACTER_SEED_COUNT = 93;
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* GENERATED by scripts/gen-category-models.mjs — do not edit by hand.
|
|
3
|
+
*
|
|
4
|
+
* WHY: the clickable owner linkage. `Owner (Anime)` is 100% populated in the
|
|
5
|
+
* corpus but it is a SENTENCE — "Tyson Granger (Tyson's 9th and final
|
|
6
|
+
* bey)" — so it renders as prose and filters nothing. These are the
|
|
7
|
+
* normalised names as `character`-group features, which makes
|
|
8
|
+
* "show me every Tyson Granger bey" one click from any listing page.
|
|
9
|
+
*
|
|
10
|
+
* 🛑 A FEATURE and never a category node. A blader crosses every generation —
|
|
11
|
+
* Tyson owns nine beys spanning Spin Gear, Magnacore, Engine Gear and HMS —
|
|
12
|
+
* so a tree node would duplicate all nine under a second parent and break
|
|
13
|
+
* the one-chain-per-product invariant. As a feature it COMPOSES with the
|
|
14
|
+
* generation tree instead of competing with it: browse Beyblade Original,
|
|
15
|
+
* then narrow to Tyson's.
|
|
16
|
+
*
|
|
17
|
+
* @tag domain:products
|
|
18
|
+
* @tag layer:seed
|
|
19
|
+
* @tag pattern:generated
|
|
20
|
+
* @tag access:server-only
|
|
21
|
+
* @tag sideEffects:none
|
|
22
|
+
*/
|
|
23
|
+
export const CHARACTER_SEEDS = [
|
|
24
|
+
{ slug: "blader-tyson-granger", name: "Tyson Granger", beyCount: 9 },
|
|
25
|
+
{ slug: "blader-kai-hiwatari", name: "Kai Hiwatari", beyCount: 7 },
|
|
26
|
+
{ slug: "blader-daichi-sumeragi", name: "Daichi Sumeragi", beyCount: 6 },
|
|
27
|
+
{ slug: "blader-max-tate", name: "Max Tate", beyCount: 6 },
|
|
28
|
+
{ slug: "blader-ray-kon", name: "Ray Kon", beyCount: 6 },
|
|
29
|
+
{ slug: "blader-shu-kurenai", name: "Shu Kurenai", beyCount: 6 },
|
|
30
|
+
{ slug: "blader-gingka-hagane", name: "Gingka Hagane", beyCount: 5 },
|
|
31
|
+
{ slug: "blader-lui-shirosagi", name: "Lui Shirosagi", beyCount: 5 },
|
|
32
|
+
{ slug: "blader-tala", name: "Tala", beyCount: 5 },
|
|
33
|
+
{ slug: "blader-valt-aoi", name: "Valt Aoi", beyCount: 5 },
|
|
34
|
+
{ slug: "blader-free-de-la-hoya", name: "Free De La Hoya", beyCount: 4 },
|
|
35
|
+
{ slug: "blader-aiger-akabane", name: "Aiger Akabane", beyCount: 3 },
|
|
36
|
+
{ slug: "blader-dante-koryu", name: "Dante Koryu", beyCount: 3 },
|
|
37
|
+
{ slug: "blader-jaxon-cross", name: "Jaxon Cross", beyCount: 3 },
|
|
38
|
+
{ slug: "blader-kenta-yumiya", name: "Kenta Yumiya", beyCount: 3 },
|
|
39
|
+
{ slug: "blader-kyoya-tategami", name: "Kyoya Tategami", beyCount: 3 },
|
|
40
|
+
{ slug: "blader-multi-nana-iro", name: "Multi Nana-iro", beyCount: 3 },
|
|
41
|
+
{ slug: "blader-ryuga", name: "Ryuga", beyCount: 3 },
|
|
42
|
+
{ slug: "blader-benkei-hanawa", name: "Benkei Hanawa", beyCount: 2 },
|
|
43
|
+
{ slug: "blader-daigo-kurogami", name: "Daigo Kurogami", beyCount: 2 },
|
|
44
|
+
{ slug: "blader-damian-hart", name: "Damian Hart", beyCount: 2 },
|
|
45
|
+
{ slug: "blader-dashan-wang", name: "Dashan Wang", beyCount: 2 },
|
|
46
|
+
{ slug: "blader-delta-zakuro", name: "Delta Zakuro", beyCount: 2 },
|
|
47
|
+
{ slug: "blader-dunga", name: "Dunga", beyCount: 2 },
|
|
48
|
+
{ slug: "blader-eddy", name: "Eddy", beyCount: 2 },
|
|
49
|
+
{ slug: "blader-fumiya-kindo", name: "Fumiya Kindo", beyCount: 2 },
|
|
50
|
+
{ slug: "blader-hikaru-hizashi", name: "Hikaru Hizashi", beyCount: 2 },
|
|
51
|
+
{ slug: "blader-hyde", name: "Hyde", beyCount: 2 },
|
|
52
|
+
{ slug: "blader-jin-of-the-gale", name: "Jin of the Gale", beyCount: 2 },
|
|
53
|
+
{ slug: "blader-kira-hayama", name: "Kira Hayama", beyCount: 2 },
|
|
54
|
+
{ slug: "blader-lee", name: "Lee", beyCount: 2 },
|
|
55
|
+
{ slug: "blader-masamune-kadoya", name: "Masamune Kadoya", beyCount: 2 },
|
|
56
|
+
{ slug: "blader-michael-summers", name: "Michael Summers", beyCount: 2 },
|
|
57
|
+
{ slug: "blader-miguel", name: "Miguel", beyCount: 2 },
|
|
58
|
+
{ slug: "blader-ozuma", name: "Ozuma", beyCount: 2 },
|
|
59
|
+
{ slug: "blader-robin-kazami", name: "Robin Kazami", beyCount: 2 },
|
|
60
|
+
{ slug: "blader-tsubasa-otori", name: "Tsubasa Otori", beyCount: 2 },
|
|
61
|
+
{ slug: "blader-wakiya-murasaki", name: "Wakiya Murasaki", beyCount: 2 },
|
|
62
|
+
{ slug: "blader-xander-shakadera", name: "Xander Shakadera", beyCount: 2 },
|
|
63
|
+
{ slug: "blader-yu-tendo", name: "Yu Tendo", beyCount: 2 },
|
|
64
|
+
{ slug: "blader-aguma", name: "Aguma", beyCount: 1 },
|
|
65
|
+
{ slug: "blader-akuya-onizaki", name: "Akuya Onizaki", beyCount: 1 },
|
|
66
|
+
{ slug: "blader-anime", name: "Anime", beyCount: 1 },
|
|
67
|
+
{ slug: "blader-anime-secondary", name: "Anime-secondary", beyCount: 1 },
|
|
68
|
+
{ slug: "blader-blader-dj", name: "Blader DJ", beyCount: 1 },
|
|
69
|
+
{ slug: "blader-brooklyn", name: "Brooklyn", beyCount: 1 },
|
|
70
|
+
{ slug: "blader-chris", name: "Chris", beyCount: 1 },
|
|
71
|
+
{ slug: "blader-claude", name: "Claude", beyCount: 1 },
|
|
72
|
+
{ slug: "blader-clio-delon", name: "Clio Delon", beyCount: 1 },
|
|
73
|
+
{ slug: "blader-crusher", name: "Crusher", beyCount: 1 },
|
|
74
|
+
{ slug: "blader-cycnus", name: "Cycnus", beyCount: 1 },
|
|
75
|
+
{ slug: "blader-dan-sodo-and-reiki-sodo", name: "Dan Sodo and Reiki Sodo", beyCount: 1 },
|
|
76
|
+
{ slug: "blader-doji", name: "Doji", beyCount: 1 },
|
|
77
|
+
{ slug: "blader-faust", name: "Faust", beyCount: 1 },
|
|
78
|
+
{ slug: "blader-garland-siebald", name: "Garland Siebald", beyCount: 1 },
|
|
79
|
+
{ slug: "blader-gary", name: "Gary", beyCount: 1 },
|
|
80
|
+
{ slug: "blader-ginro", name: "Ginro", beyCount: 1 },
|
|
81
|
+
{ slug: "blader-hikaru-hasama", name: "Hikaru Hasama", beyCount: 1 },
|
|
82
|
+
{ slug: "blader-hokuto", name: "Hokuto", beyCount: 1 },
|
|
83
|
+
{ slug: "blader-hyoma", name: "Hyoma", beyCount: 1 },
|
|
84
|
+
{ slug: "blader-hyuga-hizashi", name: "Hyuga Hizashi", beyCount: 1 },
|
|
85
|
+
{ slug: "blader-ian-papov", name: "Ian Papov", beyCount: 1 },
|
|
86
|
+
{ slug: "blader-johnny-mcgregor", name: "Johnny McGregor", beyCount: 1 },
|
|
87
|
+
{ slug: "blader-joseph-burton", name: "Joseph Burton", beyCount: 1 },
|
|
88
|
+
{ slug: "blader-julia-fernandez", name: "Julia Fernandez", beyCount: 1 },
|
|
89
|
+
{ slug: "blader-julian-konzern", name: "Julian Konzern", beyCount: 1 },
|
|
90
|
+
{ slug: "blader-karla-konjiki", name: "Karla Konjiki", beyCount: 1 },
|
|
91
|
+
{ slug: "blader-ken-midori", name: "Ken Midori", beyCount: 1 },
|
|
92
|
+
{ slug: "blader-kenny", name: "Kenny", beyCount: 1 },
|
|
93
|
+
{ slug: "blader-kevin", name: "Kevin", beyCount: 1 },
|
|
94
|
+
{ slug: "blader-kite-unabara", name: "Kite Unabara", beyCount: 1 },
|
|
95
|
+
{ slug: "blader-lain-valhalla", name: "Lain Valhalla", beyCount: 1 },
|
|
96
|
+
{ slug: "blader-meiko-myoden", name: "Meiko Myoden", beyCount: 1 },
|
|
97
|
+
{ slug: "blader-nile", name: "Nile", beyCount: 1 },
|
|
98
|
+
{ slug: "blader-nine-kurosu", name: "Nine Kurosu", beyCount: 1 },
|
|
99
|
+
{ slug: "blader-omega-shiroboshi", name: "Omega Shiroboshi", beyCount: 1 },
|
|
100
|
+
{ slug: "blader-phi", name: "Phi", beyCount: 1 },
|
|
101
|
+
{ slug: "blader-rago", name: "Rago", beyCount: 1 },
|
|
102
|
+
{ slug: "blader-reiji-mizuchi", name: "Reiji Mizuchi", beyCount: 1 },
|
|
103
|
+
{ slug: "blader-reiyu-kuwabara", name: "Reiyu Kuwabara", beyCount: 1 },
|
|
104
|
+
{ slug: "blader-rex-jura", name: "Rex Jura", beyCount: 1 },
|
|
105
|
+
{ slug: "blader-rick-anderson", name: "Rick Anderson", beyCount: 1 },
|
|
106
|
+
{ slug: "blader-robert-jurgens", name: "Robert Jurgens", beyCount: 1 },
|
|
107
|
+
{ slug: "blader-sakyo-kurayami", name: "Sakyo Kurayami", beyCount: 1 },
|
|
108
|
+
{ slug: "blader-silas-karlisle", name: "Silas Karlisle", beyCount: 1 },
|
|
109
|
+
{ slug: "blader-spencer", name: "Spencer", beyCount: 1 },
|
|
110
|
+
{ slug: "blader-teru-saotome", name: "Teru Saotome", beyCount: 1 },
|
|
111
|
+
{ slug: "blader-tobio-oike", name: "Tobio Oike", beyCount: 1 },
|
|
112
|
+
{ slug: "blader-toby", name: "Toby", beyCount: 1 },
|
|
113
|
+
{ slug: "blader-toguro-okunaga", name: "Toguro Okunaga", beyCount: 1 },
|
|
114
|
+
{ slug: "blader-yuki-mizusawa", name: "Yuki Mizusawa", beyCount: 1 },
|
|
115
|
+
{ slug: "blader-yuni-naniwa", name: "Yuni Naniwa", beyCount: 1 },
|
|
116
|
+
{ slug: "blader-zyro-kurogane", name: "Zyro Kurogane", beyCount: 1 },
|
|
117
|
+
];
|
|
118
|
+
export const CHARACTER_SEED_COUNT = 93;
|
|
@@ -17,4 +17,4 @@ export declare function seedPhotoLabel(seed: string): string;
|
|
|
17
17
|
* `appkit-seed` invocation, so anything non-stable here would give the same
|
|
18
18
|
* fixture a different URL on every run.
|
|
19
19
|
*/
|
|
20
|
-
export declare function seedPhoto(seed: string,
|
|
20
|
+
export declare function seedPhoto(seed: string, _width?: number, _height?: number): string;
|
|
@@ -47,16 +47,49 @@ export function seedExtMedia(url) {
|
|
|
47
47
|
* photography for a demo catalogue: every card now says what it is, and nobody
|
|
48
48
|
* can mistake seeded data for real inventory.
|
|
49
49
|
*/
|
|
50
|
-
|
|
51
|
-
|
|
50
|
+
/*
|
|
51
|
+
* 🛑 SUPERSEDED 2026-10-09 — seed photography is now LOCAL and costs nothing.
|
|
52
|
+
*
|
|
53
|
+
* The reasoning above is still correct about third-party fragility, and the
|
|
54
|
+
* one-line-to-move property is still the goal. What it missed is the cost: every
|
|
55
|
+
* one of these URLs was persisted as `/api/media/ext?url=…`, so every render of
|
|
56
|
+
* every card was a Node lambda doing a third-party fetch (up to 2 × 4 s) plus a
|
|
57
|
+
* full sharp decode/watermark/encode — ONE INVOCATION PER IMAGE. The homepage
|
|
58
|
+
* alone referenced 160 of them at ~49.5 KB; `52.52 GB of origin transfer ÷
|
|
59
|
+
* 49.5 KB ≈ 1.06 M` proxy responses in a week, which suspended the project
|
|
60
|
+
* (HTTP 402).
|
|
61
|
+
*
|
|
62
|
+
* A placeholder is synthetic by definition, so there was never anything to
|
|
63
|
+
* fetch. Six static tiles ship in `public/images/seed-tiles/`, chosen by the
|
|
64
|
+
* same deterministic hash, and the homepage goes 160 images → 6.
|
|
65
|
+
*
|
|
66
|
+
* The trade accepted: the tile no longer renders the item's NAME. That text was
|
|
67
|
+
* a genuine gain and it is lost here — but it cost a function invocation per
|
|
68
|
+
* card to render text the card already displays beside the image, and `alt` still
|
|
69
|
+
* carries it for assistive tech. `seedPhotoLabel` is kept and still exported for
|
|
70
|
+
* exactly that use.
|
|
71
|
+
*
|
|
72
|
+
* 🛑 Do NOT reintroduce a third-party host here, and do NOT encode width/height
|
|
73
|
+
* into the path — a per-size URL is a per-size CDN cache key, which is how 6
|
|
74
|
+
* files become 400 again. `audit-media-proxy-hosts` blocks the first; this
|
|
75
|
+
* comment is the only thing guarding the second.
|
|
76
|
+
*/
|
|
77
|
+
const SEED_TILE_PREFIX = "/images/seed-tiles/";
|
|
52
78
|
/**
|
|
53
79
|
* Muted backgrounds, all dark enough for the same light foreground.
|
|
54
80
|
*
|
|
55
|
-
* Raw hex rather than theme tokens because
|
|
56
|
-
*
|
|
81
|
+
* Raw hex rather than theme tokens because an SVG served as the body of an
|
|
82
|
+
* `<img>` has no stylesheet and no `var(--appkit-color-*)` in scope — the same
|
|
83
|
+
* reason `_placeholder.ts` keeps its artwork in an asset file.
|
|
84
|
+
*
|
|
85
|
+
* 🛑 These six values ARE the filenames in `public/images/seed-tiles/`, and they
|
|
86
|
+
* are mirrored a third time in `PLACEHOLDER_MEDIA_HOSTS`' sibling
|
|
87
|
+
* `SEED_TILE_COLOURS` (`appkit/src/utils/media-url.ts`), which maps a legacy
|
|
88
|
+
* stored `placehold.co` URL back to the same tile. Add a colour and all three
|
|
89
|
+
* must move together; a missing one degrades to a deterministic fallback tile
|
|
90
|
+
* rather than a broken image, so the failure mode is "less variety", never a 404.
|
|
57
91
|
*/
|
|
58
92
|
const SEED_PHOTO_COLOURS = ["1e293b", "334155", "3f3f46", "44403c", "312e81", "164e63"];
|
|
59
|
-
const SEED_PHOTO_FG = "f8fafc";
|
|
60
93
|
/** Deterministic 32-bit hash. Same seed, same colour, every reseed. */
|
|
61
94
|
function seedHash(input) {
|
|
62
95
|
let h = 2166136261;
|
|
@@ -95,8 +128,11 @@ export function seedPhotoLabel(seed) {
|
|
|
95
128
|
* `appkit-seed` invocation, so anything non-stable here would give the same
|
|
96
129
|
* fixture a different URL on every run.
|
|
97
130
|
*/
|
|
98
|
-
export function seedPhoto(seed,
|
|
131
|
+
export function seedPhoto(seed, _width, _height) {
|
|
99
132
|
const bg = SEED_PHOTO_COLOURS[seedHash(seed) % SEED_PHOTO_COLOURS.length];
|
|
100
|
-
|
|
101
|
-
|
|
133
|
+
// Width/height are accepted and ignored. All 366 call sites pass them, and the
|
|
134
|
+
// tiles carry `preserveAspectRatio="xMidYMid slice"` so one file fits every
|
|
135
|
+
// aspect — baking the dimensions into the path would mint a separate cache
|
|
136
|
+
// entry per size, which is the thing this change removes.
|
|
137
|
+
return `${SEED_TILE_PREFIX}${bg}.svg`;
|
|
102
138
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { CategoryDocument } from "../../features/categories/schemas/firestore";
|
|
1
2
|
import type { StoreDocument } from "../../features/stores/schemas/firestore";
|
|
2
3
|
import type { ScammerDocument } from "../../features/scams/schemas/firestore";
|
|
3
4
|
import type { EventDocument } from "../../features/events/schemas/firestore";
|
|
@@ -6,6 +7,15 @@ import type { ReviewDocument } from "../../features/reviews/schemas/firestore";
|
|
|
6
7
|
import type { OrderDocument } from "../../features/orders/schemas/firestore";
|
|
7
8
|
import type { CouponDocument } from "../../features/promotions/schemas/firestore";
|
|
8
9
|
import type { OfferDocument } from "../../features/seller/schemas/firestore";
|
|
10
|
+
/**
|
|
11
|
+
* 🛑 Apply AFTER `buildCategoryTree`, never before.
|
|
12
|
+
*
|
|
13
|
+
* `buildCategorySearchTxt` indexes `path` and `ancestors[].name`, and both are
|
|
14
|
+
* DERIVED by the tree builder — a row wrapped before derivation gets tokens
|
|
15
|
+
* from `name`/`slug`/`description` only, and silently loses the lineage search
|
|
16
|
+
* that is the whole reason ancestors are indexed.
|
|
17
|
+
*/
|
|
18
|
+
export declare function withCategorySearchTxt<T extends Partial<CategoryDocument>>(p: T): T;
|
|
9
19
|
export declare function withStoreSearchTxt<T extends Partial<StoreDocument>>(p: T): T;
|
|
10
20
|
export declare function withEventSearchTxt<T extends Partial<EventDocument>>(p: T): T;
|
|
11
21
|
export declare function withBlogSearchTxt<T extends Partial<BlogPostDocument>>(p: T): T;
|
|
@@ -1,4 +1,15 @@
|
|
|
1
|
-
import { buildStoreSearchTxt, buildEventSearchTxt, buildBlogSearchTxt, buildReviewSearchTxt, buildOrderSearchTxt, buildCouponSearchTxt, buildOfferSearchTxt, buildScammerSearchTxt, } from "../../utils/search-txt-builders";
|
|
1
|
+
import { buildCategorySearchTxt, buildStoreSearchTxt, buildEventSearchTxt, buildBlogSearchTxt, buildReviewSearchTxt, buildOrderSearchTxt, buildCouponSearchTxt, buildOfferSearchTxt, buildScammerSearchTxt, } from "../../utils/search-txt-builders";
|
|
2
|
+
/**
|
|
3
|
+
* 🛑 Apply AFTER `buildCategoryTree`, never before.
|
|
4
|
+
*
|
|
5
|
+
* `buildCategorySearchTxt` indexes `path` and `ancestors[].name`, and both are
|
|
6
|
+
* DERIVED by the tree builder — a row wrapped before derivation gets tokens
|
|
7
|
+
* from `name`/`slug`/`description` only, and silently loses the lineage search
|
|
8
|
+
* that is the whole reason ancestors are indexed.
|
|
9
|
+
*/
|
|
10
|
+
export function withCategorySearchTxt(p) {
|
|
11
|
+
return { ...p, searchTxt: buildCategorySearchTxt(p) };
|
|
12
|
+
}
|
|
2
13
|
export function withStoreSearchTxt(p) {
|
|
3
14
|
return { ...p, searchTxt: buildStoreSearchTxt(p) };
|
|
4
15
|
}
|