@mohasinac/appkit 4.49.1 → 4.51.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/.build-stamp.json +3 -3
- package/dist/_internal/server/features/franchises/data.d.ts +32 -0
- package/dist/_internal/server/features/franchises/data.js +33 -0
- package/dist/_internal/server/features/franchises/index.d.ts +2 -0
- package/dist/_internal/server/features/franchises/index.js +2 -0
- package/dist/_internal/server/features/franchises/og.d.ts +31 -0
- package/dist/_internal/server/features/franchises/og.js +11 -0
- package/dist/_internal/server/features/products/list-public.d.ts +9 -0
- package/dist/_internal/server/features/products/list-public.js +3 -0
- package/dist/constants/field-names.d.ts +3 -0
- package/dist/constants/field-names.js +11 -0
- package/dist/features/categories/components/FranchiseDetailPageView.d.ts +25 -0
- package/dist/features/categories/components/FranchiseDetailPageView.js +43 -0
- package/dist/features/categories/components/FranchisesIndexView.d.ts +14 -0
- package/dist/features/categories/components/FranchisesIndexView.js +33 -0
- package/dist/features/categories/repository/categories.repository.d.ts +15 -0
- package/dist/features/categories/repository/categories.repository.js +23 -0
- package/dist/features/categories/types/index.d.ts +1 -1
- package/dist/features/collections/schemas/index.d.ts +2 -2
- package/dist/features/pre-orders/schemas/index.d.ts +2 -2
- package/dist/features/products/repository/products.repository.d.ts +4 -0
- package/dist/features/products/repository/products.repository.js +5 -0
- package/dist/features/products/schemas/firestore.d.ts +13 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +3 -0
- package/dist/next/routing/route-map.d.ts +4 -0
- package/dist/next/routing/route-map.js +9 -0
- package/dist/seed/_helpers/category-images-generated.d.ts +21 -1
- package/dist/seed/_helpers/category-images-generated.js +330 -1
- package/dist/seed/_helpers/franchise-rows.d.ts +43 -0
- package/dist/seed/_helpers/franchise-rows.js +181 -0
- package/dist/seed/_helpers/part-colours-generated.d.ts +18 -0
- package/dist/seed/_helpers/part-colours-generated.js +273 -0
- package/dist/seed/categories-seed-data.js +13 -0
- package/dist/seed/index.d.ts +2 -0
- package/dist/seed/index.js +2 -0
- package/dist/seed/media-assets-seed-data.d.ts +1 -1
- package/dist/seed/media-assets-seed-data.js +3091 -1
- package/dist/seed/products-catalogue-seed-data.d.ts +4 -4
- package/dist/seed/products-catalogue-seed-data.js +16796 -8776
- package/dist/server.d.ts +1 -0
- package/dist/server.js +1 -0
- package/package.json +1 -1
- package/scripts/seed-cli.mjs +32 -2
|
@@ -7,10 +7,30 @@
|
|
|
7
7
|
* a third-party URL (Root Cause #104 — that adds an upstream fetch to every
|
|
8
8
|
* single render).
|
|
9
9
|
*
|
|
10
|
+
* Covers BOTH complete-model leaves and PART leaves — they share one id space
|
|
11
|
+
* (`category-*`), so one map serves the category cover and, through
|
|
12
|
+
* `gen-catalogue-listings.mjs`, that leaf's product listing image too.
|
|
13
|
+
*
|
|
10
14
|
* A hand-authored `display.coverImage` always wins over this map; a row absent
|
|
11
15
|
* from it keeps no image rather than being given a placeholder. See
|
|
12
16
|
* `withGeneratedCoverImage` in `categories-seed-data.ts`.
|
|
13
17
|
*
|
|
18
|
+
* ── Replacing one of these with your own photograph ───────────────────────
|
|
19
|
+
*
|
|
20
|
+
* `CategoryForm` already edits `display.coverImage` (upload -> `/media/<id>`),
|
|
21
|
+
* so any of these can be swapped for an original at runtime.
|
|
22
|
+
*
|
|
23
|
+
* 🛑 But a RUNTIME edit does not survive `appkit-seed load` — the loader
|
|
24
|
+
* merge-writes `display`, so the generated value comes back. To replace one
|
|
25
|
+
* permanently, set `display.coverImage` in the category SOURCE (the forest or
|
|
26
|
+
* the seed row); the hand-authored value then wins here forever. That is the
|
|
27
|
+
* deliberate trade for "the seed can always rebuild the database".
|
|
28
|
+
*
|
|
29
|
+
* Deleting them entirely: remove the `media/categories/` Storage prefix, delete
|
|
30
|
+
* this file and `media-assets-seed-data.ts`, re-run the category seed. Bucket
|
|
31
|
+
* versioning and soft-delete are both OFF, so a deleted object leaves no
|
|
32
|
+
* recoverable copy and no residual billing.
|
|
33
|
+
*
|
|
14
34
|
* Source and licensing for every file:
|
|
15
35
|
* `docs/research/bey-corpus-2026-10/image-provenance.json`.
|
|
16
36
|
*/
|
|
@@ -210,5 +230,314 @@ export const GENERATED_CATEGORY_IMAGES = {
|
|
|
210
230
|
"category-wyvern-dj": "/media/category-wyvern-dj-image",
|
|
211
231
|
"category-z-achilles-11-xtend": "/media/category-z-achilles-11-xtend-image",
|
|
212
232
|
"category-zeus": "/media/category-zeus-image",
|
|
233
|
+
"category-circle-upper": "/media/category-circle-upper-image",
|
|
234
|
+
"category-cross-attacker": "/media/category-cross-attacker-image",
|
|
235
|
+
"category-cross-dranzer": "/media/category-cross-dranzer-image",
|
|
236
|
+
"category-cross-fang": "/media/category-cross-fang-image",
|
|
237
|
+
"category-cross-griffon": "/media/category-cross-griffon-image",
|
|
238
|
+
"category-cross-spike": "/media/category-cross-spike-image",
|
|
239
|
+
"category-cross-spiker": "/media/category-cross-spiker-image",
|
|
240
|
+
"category-cybernetic-dragon": "/media/category-cybernetic-dragon-image",
|
|
241
|
+
"category-devil-crusher": "/media/category-devil-crusher-image",
|
|
242
|
+
"category-double-horn": "/media/category-double-horn-image",
|
|
243
|
+
"category-double-wing": "/media/category-double-wing-image",
|
|
244
|
+
"category-dragon-breaker": "/media/category-dragon-breaker-image",
|
|
245
|
+
"category-dragon-saucer": "/media/category-dragon-saucer-image",
|
|
246
|
+
"category-eight-attacker": "/media/category-eight-attacker-image",
|
|
247
|
+
"category-eight-spike": "/media/category-eight-spike-image",
|
|
248
|
+
"category-flame-wing": "/media/category-flame-wing-image",
|
|
249
|
+
"category-g-upper": "/media/category-g-upper-image",
|
|
250
|
+
"category-genocide-circle": "/media/category-genocide-circle-image",
|
|
251
|
+
"category-gigantic-claw": "/media/category-gigantic-claw-image",
|
|
252
|
+
"category-great-dragon": "/media/category-great-dragon-image",
|
|
253
|
+
"category-hammer-tusk": "/media/category-hammer-tusk-image",
|
|
254
|
+
"category-howling-leo": "/media/category-howling-leo-image",
|
|
255
|
+
"category-jiraiya-blade": "/media/category-jiraiya-blade-image",
|
|
256
|
+
"category-metal-ape": "/media/category-metal-ape-image",
|
|
257
|
+
"category-metal-attacker": "/media/category-metal-attacker-image",
|
|
258
|
+
"category-metal-defense": "/media/category-metal-defense-image",
|
|
259
|
+
"category-metal-saucer": "/media/category-metal-saucer-image",
|
|
260
|
+
"category-mountain-hammer": "/media/category-mountain-hammer-image",
|
|
261
|
+
"category-panther-claw": "/media/category-panther-claw-image",
|
|
262
|
+
"category-panther-head": "/media/category-panther-head-image",
|
|
263
|
+
"category-penta-wing": "/media/category-penta-wing-image",
|
|
264
|
+
"category-reverse-dragon": "/media/category-reverse-dragon-image",
|
|
265
|
+
"category-attack-ring-sharkrash": "/media/category-attack-ring-sharkrash-image",
|
|
266
|
+
"category-shield-hammer": "/media/category-shield-hammer-image",
|
|
267
|
+
"category-sonic-tiger": "/media/category-sonic-tiger-image",
|
|
268
|
+
"category-spike-dragon": "/media/category-spike-dragon-image",
|
|
269
|
+
"category-spiral-upper": "/media/category-spiral-upper-image",
|
|
270
|
+
"category-star-wolf": "/media/category-star-wolf-image",
|
|
271
|
+
"category-strike-turtle": "/media/category-strike-turtle-image",
|
|
272
|
+
"category-ten-spike": "/media/category-ten-spike-image",
|
|
273
|
+
"category-tiger-defenser": "/media/category-tiger-defenser-image",
|
|
274
|
+
"category-triangle-wing": "/media/category-triangle-wing-image",
|
|
275
|
+
"category-triple-beak": "/media/category-triple-beak-image",
|
|
276
|
+
"category-turtle-survivor": "/media/category-turtle-survivor-image",
|
|
277
|
+
"category-ultimate-attacker": "/media/category-ultimate-attacker-image",
|
|
278
|
+
"category-upper-claw": "/media/category-upper-claw-image",
|
|
279
|
+
"category-upper-dragon": "/media/category-upper-dragon-image",
|
|
280
|
+
"category-attack-ring-vanishing-moot": "/media/category-attack-ring-vanishing-moot-image",
|
|
281
|
+
"category-war-lion": "/media/category-war-lion-image",
|
|
282
|
+
"category-war-monkey": "/media/category-war-monkey-image",
|
|
283
|
+
"category-wing-survivor": "/media/category-wing-survivor-image",
|
|
284
|
+
"category-wing-upper": "/media/category-wing-upper-image",
|
|
285
|
+
"category-wolf-crusher": "/media/category-wolf-crusher-image",
|
|
286
|
+
"category-accel": "/media/category-accel-image",
|
|
287
|
+
"category-disk-ball": "/media/category-disk-ball-image",
|
|
288
|
+
"category-flat": "/media/category-flat-image",
|
|
289
|
+
"category-free-ball": "/media/category-free-ball-image",
|
|
290
|
+
"category-gear-ball": "/media/category-gear-ball-image",
|
|
291
|
+
"category-hexa": "/media/category-hexa-image",
|
|
292
|
+
"category-point": "/media/category-point-image",
|
|
293
|
+
"category-taper": "/media/category-taper-image",
|
|
294
|
+
"category-trans-point": "/media/category-trans-point-image",
|
|
295
|
+
"category-vortex": "/media/category-vortex-image",
|
|
296
|
+
"category-bit-chip-apollon": "/media/category-bit-chip-apollon-image",
|
|
297
|
+
"category-black-dranzer": "/media/category-black-dranzer-image",
|
|
298
|
+
"category-cyber-draciel": "/media/category-cyber-draciel-image",
|
|
299
|
+
"category-cyber-dragoon": "/media/category-cyber-dragoon-image",
|
|
300
|
+
"category-cyber-dranzer": "/media/category-cyber-dranzer-image",
|
|
301
|
+
"category-cyber-driger": "/media/category-cyber-driger-image",
|
|
302
|
+
"category-dark-gargoyle": "/media/category-dark-gargoyle-image",
|
|
303
|
+
"category-draciel": "/media/category-draciel-image",
|
|
304
|
+
"category-bit-chip-dragoon": "/media/category-bit-chip-dragoon-image",
|
|
305
|
+
"category-dranzer": "/media/category-dranzer-image",
|
|
306
|
+
"category-driger": "/media/category-driger-image",
|
|
307
|
+
"category-bit-chip-flash-leopard": "/media/category-bit-chip-flash-leopard-image",
|
|
308
|
+
"category-bit-chip-galeon": "/media/category-bit-chip-galeon-image",
|
|
309
|
+
"category-bit-chip-galman": "/media/category-bit-chip-galman-image",
|
|
310
|
+
"category-bit-chip-galzzly": "/media/category-bit-chip-galzzly-image",
|
|
311
|
+
"category-bit-chip-gigars": "/media/category-bit-chip-gigars-image",
|
|
312
|
+
"category-bit-chip-griffolyon": "/media/category-bit-chip-griffolyon-image",
|
|
313
|
+
"category-hopper": "/media/category-hopper-image",
|
|
314
|
+
"category-master-dranzer": "/media/category-master-dranzer-image",
|
|
315
|
+
"category-bit-chip-metal-draciel": "/media/category-bit-chip-metal-draciel-image",
|
|
316
|
+
"category-bit-chip-metal-driger": "/media/category-bit-chip-metal-driger-image",
|
|
317
|
+
"category-rapid-eagle": "/media/category-rapid-eagle-image",
|
|
318
|
+
"category-bit-chip-rock-bison": "/media/category-bit-chip-rock-bison-image",
|
|
319
|
+
"category-rushing-boar": "/media/category-rushing-boar-image",
|
|
320
|
+
"category-bit-chip-salamalyon": "/media/category-bit-chip-salamalyon-image",
|
|
321
|
+
"category-seaborg": "/media/category-seaborg-image",
|
|
322
|
+
"category-bit-chip-shadow-driger": "/media/category-bit-chip-shadow-driger-image",
|
|
323
|
+
"category-bit-chip-sharkrash": "/media/category-bit-chip-sharkrash-image",
|
|
324
|
+
"category-bit-chip-strata-dragoon": "/media/category-bit-chip-strata-dragoon-image",
|
|
325
|
+
"category-bit-chip-thunder-pegasus": "/media/category-bit-chip-thunder-pegasus-image",
|
|
326
|
+
"category-bit-chip-torch-pegasus": "/media/category-bit-chip-torch-pegasus-image",
|
|
327
|
+
"category-bit-chip-trygle": "/media/category-bit-chip-trygle-image",
|
|
328
|
+
"category-tryhorn": "/media/category-tryhorn-image",
|
|
329
|
+
"category-bit-chip-trypio": "/media/category-bit-chip-trypio-image",
|
|
330
|
+
"category-bit-chip-vanishing-moot": "/media/category-bit-chip-vanishing-moot-image",
|
|
331
|
+
"category-bit-chip-vortex-ape": "/media/category-bit-chip-vortex-ape-image",
|
|
332
|
+
"category-bit-chip-wolborg": "/media/category-bit-chip-wolborg-image",
|
|
333
|
+
"category-bit-chip-wyborg": "/media/category-bit-chip-wyborg-image",
|
|
334
|
+
"category-bit-chip-zeus": "/media/category-bit-chip-zeus-image",
|
|
335
|
+
"category-aeropegasus": "/media/category-aeropegasus-image",
|
|
336
|
+
"category-cobaltdragoon": "/media/category-cobaltdragoon-image",
|
|
337
|
+
"category-cobaltdrake": "/media/category-cobaltdrake-image",
|
|
338
|
+
"category-crimsongaruda": "/media/category-crimsongaruda-image",
|
|
339
|
+
"category-dranbuster": "/media/category-dranbuster-image",
|
|
340
|
+
"category-drandagger": "/media/category-drandagger-image",
|
|
341
|
+
"category-dransword": "/media/category-dransword-image",
|
|
342
|
+
"category-dranzerspiral": "/media/category-dranzerspiral-image",
|
|
343
|
+
"category-drigerslash": "/media/category-drigerslash-image",
|
|
344
|
+
"category-ghostcircle": "/media/category-ghostcircle-image",
|
|
345
|
+
"category-hellshammer": "/media/category-hellshammer-image",
|
|
346
|
+
"category-hellsscythe": "/media/category-hellsscythe-image",
|
|
347
|
+
"category-knightshield": "/media/category-knightshield-image",
|
|
348
|
+
"category-leonclaw": "/media/category-leonclaw-image",
|
|
349
|
+
"category-phoenixwing": "/media/category-phoenixwing-image",
|
|
350
|
+
"category-savior": "/media/category-savior-image",
|
|
351
|
+
"category-sharkedge": "/media/category-sharkedge-image",
|
|
352
|
+
"category-silverwolf": "/media/category-silverwolf-image",
|
|
353
|
+
"category-tyrannobeat": "/media/category-tyrannobeat-image",
|
|
354
|
+
"category-unicornsting": "/media/category-unicornsting-image",
|
|
355
|
+
"category-vipertail": "/media/category-vipertail-image",
|
|
356
|
+
"category-wizardarrow": "/media/category-wizardarrow-image",
|
|
357
|
+
"category-wizardrod": "/media/category-wizardrod-image",
|
|
358
|
+
"category-customize-clutch-base": "/media/category-customize-clutch-base-image",
|
|
359
|
+
"category-customize-grip-base": "/media/category-customize-grip-base-image",
|
|
360
|
+
"category-customize-metal-sharp": "/media/category-customize-metal-sharp-image",
|
|
361
|
+
"category-engine-stopper-base": "/media/category-engine-stopper-base-image",
|
|
362
|
+
"category-first-clutch-base": "/media/category-first-clutch-base-image",
|
|
363
|
+
"category-flame-change-base": "/media/category-flame-change-base-image",
|
|
364
|
+
"category-fortress-base": "/media/category-fortress-base-image",
|
|
365
|
+
"category-full-auto-clutch-base": "/media/category-full-auto-clutch-base-image",
|
|
366
|
+
"category-griffolyon-base": "/media/category-griffolyon-base-image",
|
|
367
|
+
"category-instant-release": "/media/category-instant-release-image",
|
|
368
|
+
"category-jumping-base": "/media/category-jumping-base-image",
|
|
369
|
+
"category-magne-flat-base": "/media/category-magne-flat-base-image",
|
|
370
|
+
"category-metal-change-base": "/media/category-metal-change-base-image",
|
|
371
|
+
"category-metal-sharp-base": "/media/category-metal-sharp-base-image",
|
|
372
|
+
"category-sg-flat-base": "/media/category-sg-flat-base-image",
|
|
373
|
+
"category-sg-flat": "/media/category-sg-flat-image",
|
|
374
|
+
"category-sg-jumping-base-2": "/media/category-sg-jumping-base-2-image",
|
|
375
|
+
"category-sg-metal-ball": "/media/category-sg-metal-ball-image",
|
|
376
|
+
"category-sg-metal-flat-2": "/media/category-sg-metal-flat-2-image",
|
|
377
|
+
"category-sg-metal-flat-base": "/media/category-sg-metal-flat-base-image",
|
|
378
|
+
"category-viper-metal-ball-base": "/media/category-viper-metal-ball-base-image",
|
|
379
|
+
"category-volcano-change-base": "/media/category-volcano-change-base-image",
|
|
380
|
+
"category-chrome-wheel-dragoon": "/media/category-chrome-wheel-dragoon-image",
|
|
381
|
+
"category-0": "/media/category-0-image",
|
|
382
|
+
"category-00": "/media/category-00-image",
|
|
383
|
+
"category-disc-1": "/media/category-disc-1-image",
|
|
384
|
+
"category-10": "/media/category-10-image",
|
|
385
|
+
"category-11": "/media/category-11-image",
|
|
386
|
+
"category-disc-7": "/media/category-disc-7-image",
|
|
387
|
+
"category-8": "/media/category-8-image",
|
|
388
|
+
"category-aquilon-q": "/media/category-aquilon-q-image",
|
|
389
|
+
"category-around": "/media/category-around-image",
|
|
390
|
+
"category-blitz": "/media/category-blitz-image",
|
|
391
|
+
"category-boost": "/media/category-boost-image",
|
|
392
|
+
"category-drake": "/media/category-drake-image",
|
|
393
|
+
"category-force": "/media/category-force-image",
|
|
394
|
+
"category-karma": "/media/category-karma-image",
|
|
395
|
+
"category-knuckle": "/media/category-knuckle-image",
|
|
396
|
+
"category-legacy": "/media/category-legacy-image",
|
|
397
|
+
"category-limited": "/media/category-limited-image",
|
|
398
|
+
"category-nexus": "/media/category-nexus-image",
|
|
399
|
+
"category-nine": "/media/category-nine-image",
|
|
400
|
+
"category-over": "/media/category-over-image",
|
|
401
|
+
"category-sting": "/media/category-sting-image",
|
|
402
|
+
"category-tapered": "/media/category-tapered-image",
|
|
403
|
+
"category-triple": "/media/category-triple-image",
|
|
404
|
+
"category-vanguard": "/media/category-vanguard-image",
|
|
405
|
+
"category-vertical": "/media/category-vertical-image",
|
|
406
|
+
"category-disc-yell": "/media/category-disc-yell-image",
|
|
407
|
+
"category-zenith": "/media/category-zenith-image",
|
|
408
|
+
"category-driver-atomic": "/media/category-driver-atomic-image",
|
|
409
|
+
"category-driver-bullet": "/media/category-driver-bullet-image",
|
|
410
|
+
"category-driver-charge": "/media/category-driver-charge-image",
|
|
411
|
+
"category-destroy-dash": "/media/category-destroy-dash-image",
|
|
412
|
+
"category-driver-dimension-dash": "/media/category-driver-dimension-dash-image",
|
|
413
|
+
"category-dimension": "/media/category-dimension-image",
|
|
414
|
+
"category-drift": "/media/category-drift-image",
|
|
415
|
+
"category-evolution-dash": "/media/category-evolution-dash-image",
|
|
416
|
+
"category-iron": "/media/category-iron-image",
|
|
417
|
+
"category-jaggy": "/media/category-jaggy-image",
|
|
418
|
+
"category-loop": "/media/category-loop-image",
|
|
419
|
+
"category-merge": "/media/category-merge-image",
|
|
420
|
+
"category-driver-mobius": "/media/category-driver-mobius-image",
|
|
421
|
+
"category-nothing": "/media/category-nothing-image",
|
|
422
|
+
"category-press": "/media/category-press-image",
|
|
423
|
+
"category-reboot": "/media/category-reboot-image",
|
|
424
|
+
"category-revolve-q": "/media/category-revolve-q-image",
|
|
425
|
+
"category-driver-spiral": "/media/category-driver-spiral-image",
|
|
426
|
+
"category-unite-dash": "/media/category-unite-dash-image",
|
|
427
|
+
"category-unite": "/media/category-unite-image",
|
|
428
|
+
"category-variable-dash": "/media/category-variable-dash-image",
|
|
429
|
+
"category-variable": "/media/category-variable-image",
|
|
430
|
+
"category-xceed-x": "/media/category-xceed-x-image",
|
|
431
|
+
"category-xtend": "/media/category-xtend-image",
|
|
432
|
+
"category-zone-z": "/media/category-zone-z-image",
|
|
433
|
+
"category-energy-ring-4d-clear-wheel-orion": "/media/category-energy-ring-4d-clear-wheel-orion-image",
|
|
434
|
+
"category-energy-ring-blaze": "/media/category-energy-ring-blaze-image",
|
|
435
|
+
"category-energy-ring-bull": "/media/category-energy-ring-bull-image",
|
|
436
|
+
"category-capricorn": "/media/category-capricorn-image",
|
|
437
|
+
"category-energy-ring-capricorne": "/media/category-energy-ring-capricorne-image",
|
|
438
|
+
"category-clear-wheel-wolf": "/media/category-clear-wheel-wolf-image",
|
|
439
|
+
"category-nemesis-x": "/media/category-nemesis-x-image",
|
|
440
|
+
"category-energy-ring-sagittario-i": "/media/category-energy-ring-sagittario-i-image",
|
|
441
|
+
"category-energy-ring-sagittario": "/media/category-energy-ring-sagittario-image",
|
|
442
|
+
"category-energy-ring-striker-ii": "/media/category-energy-ring-striker-ii-image",
|
|
443
|
+
"category-energy-ring-wolf": "/media/category-energy-ring-wolf-image",
|
|
444
|
+
"category-energy-ring-zurafa": "/media/category-energy-ring-zurafa-image",
|
|
445
|
+
"category-left-engine-gear": "/media/category-left-engine-gear-image",
|
|
446
|
+
"category-face-bolt-aquario": "/media/category-face-bolt-aquario-image",
|
|
447
|
+
"category-face-bolt-aries": "/media/category-face-bolt-aries-image",
|
|
448
|
+
"category-face-bolt-befall": "/media/category-face-bolt-befall-image",
|
|
449
|
+
"category-face-bolt-blaze": "/media/category-face-bolt-blaze-image",
|
|
450
|
+
"category-face-bolt-bull": "/media/category-face-bolt-bull-image",
|
|
451
|
+
"category-face-bolt-byxis": "/media/category-face-bolt-byxis-image",
|
|
452
|
+
"category-face-bolt-cygnus": "/media/category-face-bolt-cygnus-image",
|
|
453
|
+
"category-face-bolt-dragoon": "/media/category-face-bolt-dragoon-image",
|
|
454
|
+
"category-face-bolt-eagle": "/media/category-face-bolt-eagle-image",
|
|
455
|
+
"category-face-bolt-jupiter": "/media/category-face-bolt-jupiter-image",
|
|
456
|
+
"category-face-bolt-l-drago": "/media/category-face-bolt-l-drago-image",
|
|
457
|
+
"category-orochi": "/media/category-orochi-image",
|
|
458
|
+
"category-face-bolt-pegasus": "/media/category-face-bolt-pegasus-image",
|
|
459
|
+
"category-face-bolt-striker-ii": "/media/category-face-bolt-striker-ii-image",
|
|
460
|
+
"category-variares": "/media/category-variares-image",
|
|
461
|
+
"category-face-bolt-zurafa": "/media/category-face-bolt-zurafa-image",
|
|
462
|
+
"category-4d-metal-wheel-phantom": "/media/category-4d-metal-wheel-phantom-image",
|
|
463
|
+
"category-burn": "/media/category-burn-image",
|
|
464
|
+
"category-earth": "/media/category-earth-image",
|
|
465
|
+
"category-flame": "/media/category-flame-image",
|
|
466
|
+
"category-forbidden": "/media/category-forbidden-image",
|
|
467
|
+
"category-metal-wheel-mercury": "/media/category-metal-wheel-mercury-image",
|
|
468
|
+
"category-proto": "/media/category-proto-image",
|
|
469
|
+
"category-rock": "/media/category-rock-image",
|
|
470
|
+
"category-dark-deathscyther": "/media/category-dark-deathscyther-image",
|
|
471
|
+
"category-layer-draciel-fortress": "/media/category-layer-draciel-fortress-image",
|
|
472
|
+
"category-drain-fafnir": "/media/category-drain-fafnir-image",
|
|
473
|
+
"category-dranzer-flame": "/media/category-dranzer-flame-image",
|
|
474
|
+
"category-engine-gear": "/media/category-engine-gear-image",
|
|
475
|
+
"category-gaia-dragoon": "/media/category-gaia-dragoon-image",
|
|
476
|
+
"category-genesis-valtryek-v3": "/media/category-genesis-valtryek-v3-image",
|
|
477
|
+
"category-god-valkyrie": "/media/category-god-valkyrie-image",
|
|
478
|
+
"category-kaiser-kerbeus": "/media/category-kaiser-kerbeus-image",
|
|
479
|
+
"category-king-kerbeus-k2": "/media/category-king-kerbeus-k2-image",
|
|
480
|
+
"category-legend-spriggan": "/media/category-legend-spriggan-image",
|
|
481
|
+
"category-maximum-garuda": "/media/category-maximum-garuda-image",
|
|
482
|
+
"category-obelisk-odin": "/media/category-obelisk-odin-image",
|
|
483
|
+
"category-sieg-xcalibur": "/media/category-sieg-xcalibur-image",
|
|
484
|
+
"category-spryzen-requiem-s3": "/media/category-spryzen-requiem-s3-image",
|
|
485
|
+
"category-storm-spriggan": "/media/category-storm-spriggan-image",
|
|
486
|
+
"category-victory-valkyrie": "/media/category-victory-valkyrie-image",
|
|
487
|
+
"category-wild-wyvern": "/media/category-wild-wyvern-image",
|
|
488
|
+
"category-layer-wolborg": "/media/category-layer-wolborg-image",
|
|
489
|
+
"category-xeno-xcalibur": "/media/category-xeno-xcalibur-image",
|
|
490
|
+
"category-as": "/media/category-as-image",
|
|
491
|
+
"category-bs": "/media/category-bs-image",
|
|
492
|
+
"category-cf": "/media/category-cf-image",
|
|
493
|
+
"category-cs": "/media/category-cs-image",
|
|
494
|
+
"category-evolution": "/media/category-evolution-image",
|
|
495
|
+
"category-ewd": "/media/category-ewd-image",
|
|
496
|
+
"category-f-d": "/media/category-f-d-image",
|
|
497
|
+
"category-performance-tip-f": "/media/category-performance-tip-f-image",
|
|
498
|
+
"category-performance-tip-gf": "/media/category-performance-tip-gf-image",
|
|
499
|
+
"category-ms": "/media/category-ms-image",
|
|
500
|
+
"category-r-f": "/media/category-r-f-image",
|
|
501
|
+
"category-rb": "/media/category-rb-image",
|
|
502
|
+
"category-rf": "/media/category-rf-image",
|
|
503
|
+
"category-sf": "/media/category-sf-image",
|
|
504
|
+
"category-tb": "/media/category-tb-image",
|
|
505
|
+
"category-wb": "/media/category-wb-image",
|
|
506
|
+
"category-wsf": "/media/category-wsf-image",
|
|
507
|
+
"category-0-80": "/media/category-0-80-image",
|
|
508
|
+
"category-1-60": "/media/category-1-60-image",
|
|
509
|
+
"category-3-60": "/media/category-3-60-image",
|
|
510
|
+
"category-3-70": "/media/category-3-70-image",
|
|
511
|
+
"category-3-80": "/media/category-3-80-image",
|
|
512
|
+
"category-4-60": "/media/category-4-60-image",
|
|
513
|
+
"category-4-70": "/media/category-4-70-image",
|
|
514
|
+
"category-4-80": "/media/category-4-80-image",
|
|
515
|
+
"category-5-60": "/media/category-5-60-image",
|
|
516
|
+
"category-5-70": "/media/category-5-70-image",
|
|
517
|
+
"category-5-80": "/media/category-5-80-image",
|
|
518
|
+
"category-9-60": "/media/category-9-60-image",
|
|
519
|
+
"category-flat-core": "/media/category-flat-core-image",
|
|
520
|
+
"category-grip-flat-core": "/media/category-grip-flat-core-image",
|
|
521
|
+
"category-manual-change-core": "/media/category-manual-change-core-image",
|
|
522
|
+
"category-semi-flat-core": "/media/category-semi-flat-core-image",
|
|
523
|
+
"category-sharp-core": "/media/category-sharp-core-image",
|
|
524
|
+
"category-heavy-metal-core": "/media/category-heavy-metal-core-image",
|
|
525
|
+
"category-neo-right-sg": "/media/category-neo-right-sg-image",
|
|
526
|
+
"category-135": "/media/category-135-image",
|
|
527
|
+
"category-a230": "/media/category-a230-image",
|
|
528
|
+
"category-sa165": "/media/category-sa165-image",
|
|
529
|
+
"category-sp230": "/media/category-sp230-image",
|
|
530
|
+
"category-t125": "/media/category-t125-image",
|
|
531
|
+
"category-v145": "/media/category-v145-image",
|
|
532
|
+
"category-w105": "/media/category-w105-image",
|
|
533
|
+
"category-circle-balance": "/media/category-circle-balance-image",
|
|
534
|
+
"category-eight-heavy": "/media/category-eight-heavy-image",
|
|
535
|
+
"category-heavy-attack": "/media/category-heavy-attack-image",
|
|
536
|
+
"category-magne-weight-disk": "/media/category-magne-weight-disk-image",
|
|
537
|
+
"category-star-attack": "/media/category-star-attack-image",
|
|
538
|
+
"category-ten-balance": "/media/category-ten-balance-image",
|
|
539
|
+
"category-ten-heavy": "/media/category-ten-heavy-image",
|
|
540
|
+
"category-ten-wide": "/media/category-ten-wide-image",
|
|
541
|
+
"category-wing-attacker": "/media/category-wing-attacker-image",
|
|
213
542
|
};
|
|
214
|
-
export const GENERATED_CATEGORY_IMAGE_COUNT =
|
|
543
|
+
export const GENERATED_CATEGORY_IMAGE_COUNT = 504;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { CategoryDocument } from "../../features/categories/schemas";
|
|
2
|
+
export interface FranchiseSeedInput {
|
|
3
|
+
/** Without the `franchise-` prefix. Products match on this, never the name. */
|
|
4
|
+
slug: string;
|
|
5
|
+
name: string;
|
|
6
|
+
description: string;
|
|
7
|
+
/** Live only when real stock exists — see the dead-facet rule above. */
|
|
8
|
+
active: boolean;
|
|
9
|
+
featured?: boolean;
|
|
10
|
+
keywords: string[];
|
|
11
|
+
seoDescription: string;
|
|
12
|
+
}
|
|
13
|
+
export declare function franchiseRow(input: FranchiseSeedInput, order: number, stamps: {
|
|
14
|
+
createdBy: string;
|
|
15
|
+
createdAt: Date;
|
|
16
|
+
updatedAt: Date;
|
|
17
|
+
}): Partial<CategoryDocument>;
|
|
18
|
+
export declare function buildFranchiseRows(stamps: {
|
|
19
|
+
createdBy: string;
|
|
20
|
+
createdAt: Date;
|
|
21
|
+
updatedAt: Date;
|
|
22
|
+
}): Partial<CategoryDocument>[];
|
|
23
|
+
export declare const FRANCHISE_ROW_COUNT: number;
|
|
24
|
+
/** The slugs a product's `franchiseSlug` may point at. */
|
|
25
|
+
export declare const FRANCHISE_SLUGS: readonly string[];
|
|
26
|
+
/**
|
|
27
|
+
* Category ROOT -> the franchise everything beneath it belongs to.
|
|
28
|
+
*
|
|
29
|
+
* Derived rather than stamped per product: a product already carries its full
|
|
30
|
+
* ancestor chain, so the root is free and cannot drift from the taxonomy the
|
|
31
|
+
* way a hand-written field would (Root Cause #42).
|
|
32
|
+
*
|
|
33
|
+
* 🛑 Deliberately PARTIAL. `category-living-collectibles` is absent because a
|
|
34
|
+
* juniper bonsai and a leucistic axolotl are not from an IP — they are living
|
|
35
|
+
* things. Mapping every root for completeness' sake would assert a franchise
|
|
36
|
+
* that does not exist, and "no franchise" is the correct answer for 4 of the
|
|
37
|
+
* 1,308 seeded products. A root with no entry yields no franchise, not a
|
|
38
|
+
* fallback.
|
|
39
|
+
*/
|
|
40
|
+
export declare const FRANCHISE_BY_CATEGORY_ROOT: Readonly<Record<string, {
|
|
41
|
+
slug: string;
|
|
42
|
+
name: string;
|
|
43
|
+
}>>;
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* WHY: a product's BRAND is who made it (Takara-Tomy); its FRANCHISE is what
|
|
3
|
+
* it is from (Beyblade). The site had no way to express the second, while
|
|
4
|
+
* `CharacterHotspot` shipped eighteen `/franchise/*` links to a route that
|
|
5
|
+
* did not exist. This is that unit, modelled on brands per the explicit
|
|
6
|
+
* instruction — "like brands make franchise its own separate unit".
|
|
7
|
+
*
|
|
8
|
+
* WHAT: one factory plus eight declarations.
|
|
9
|
+
*
|
|
10
|
+
* EXPORTS:
|
|
11
|
+
* FRANCHISE_ROWS — Partial<CategoryDocument>[], categoryType:"franchise"
|
|
12
|
+
* FRANCHISE_ROW_COUNT — asserted by the seed so a silent drop is loud
|
|
13
|
+
*
|
|
14
|
+
* ── 🛑 THE DEAD-FACET RULE, AND HOW THESE OBEY IT ─────────────────────────
|
|
15
|
+
*
|
|
16
|
+
* `brand-rows.ts` trap 3 states it exactly: *"A brand row with no product is a
|
|
17
|
+
* DEAD FACET, and worse than absent — it renders as a card in the grid that
|
|
18
|
+
* opens an empty page."* Seven of the eight rows below have no stock today,
|
|
19
|
+
* because this catalogue sells Beyblade.
|
|
20
|
+
*
|
|
21
|
+
* So they are seeded **`isActive: false`**. That is not a soft delete — the row
|
|
22
|
+
* exists, it is editable in the admin category editor, its page resolves, and
|
|
23
|
+
* `/franchise/marvel` stops being a 404. It is excluded from the grid and from
|
|
24
|
+
* search until it has something to sell, at which point one flag flips.
|
|
25
|
+
*
|
|
26
|
+
* The alternative readings were both worse: omitting them leaves eighteen links
|
|
27
|
+
* broken, and seeding them active puts seven empty shopfronts on a live grid.
|
|
28
|
+
*
|
|
29
|
+
* 🛑 `isActive` is therefore load-bearing here, not boilerplate. A future
|
|
30
|
+
* franchise row should be `false` until a product carries its `franchiseSlug`.
|
|
31
|
+
*
|
|
32
|
+
* ── Why tier-0 and outside the forest ─────────────────────────────────────
|
|
33
|
+
*
|
|
34
|
+
* Same as brands: `position` is NOT set, because these live outside the
|
|
35
|
+
* category forest's DFS numbering and a position inside it would corrupt the
|
|
36
|
+
* ranges `onCategoryWrite` shifts on insert.
|
|
37
|
+
*
|
|
38
|
+
* @tag domain:categories
|
|
39
|
+
* @tag layer:seed
|
|
40
|
+
* @tag pattern:shared-literal
|
|
41
|
+
* @tag access:server-only
|
|
42
|
+
* @tag consumers:seed/categories-seed-data.ts
|
|
43
|
+
* @tag sideEffects:none
|
|
44
|
+
*/
|
|
45
|
+
/* 🛑 `constants/field-names`, NOT the schema copy — there are two
|
|
46
|
+
* `CATEGORY_FIELDS` and only this one carries `CATEGORY_TYPE_VALUES`.
|
|
47
|
+
* `categories-seed-data.ts` imports this one; matching it is what keeps the
|
|
48
|
+
* discriminator a single spelling. Same reasoning as `brand-rows.ts`. */
|
|
49
|
+
import { CATEGORY_FIELDS } from "../../constants/field-names.js";
|
|
50
|
+
import { seedPhoto } from "./media.js";
|
|
51
|
+
export function franchiseRow(input, order, stamps) {
|
|
52
|
+
const id = `franchise-${input.slug}`;
|
|
53
|
+
return {
|
|
54
|
+
id,
|
|
55
|
+
slug: id,
|
|
56
|
+
name: input.name,
|
|
57
|
+
categoryType: CATEGORY_FIELDS.CATEGORY_TYPE_VALUES.FRANCHISE,
|
|
58
|
+
description: input.description,
|
|
59
|
+
rootId: id,
|
|
60
|
+
parentIds: [],
|
|
61
|
+
childrenIds: [],
|
|
62
|
+
ancestors: [],
|
|
63
|
+
tier: 0,
|
|
64
|
+
path: id,
|
|
65
|
+
isLeaf: true,
|
|
66
|
+
order,
|
|
67
|
+
/* `icon` deliberately unset — the brands grid reads `display.icon` first
|
|
68
|
+
* and an emoji there would beat a real cover image (brand-rows trap 2). */
|
|
69
|
+
display: {
|
|
70
|
+
coverImage: seedPhoto(`franchise-cover-${input.slug}-20261014`, 800, 800),
|
|
71
|
+
showInMenu: false,
|
|
72
|
+
showInFooter: false,
|
|
73
|
+
},
|
|
74
|
+
isFeatured: input.featured ?? false,
|
|
75
|
+
isActive: input.active,
|
|
76
|
+
isSearchable: input.active,
|
|
77
|
+
createdBy: stamps.createdBy,
|
|
78
|
+
createdAt: stamps.createdAt,
|
|
79
|
+
updatedAt: stamps.updatedAt,
|
|
80
|
+
seo: {
|
|
81
|
+
title: `${input.name} | LetItRip`,
|
|
82
|
+
description: input.seoDescription,
|
|
83
|
+
keywords: input.keywords,
|
|
84
|
+
},
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
/*
|
|
88
|
+
* The eight. Beyblade is the catalogue; the other seven are the IPs
|
|
89
|
+
* `CharacterHotspot` already links to, seeded inactive so those links resolve
|
|
90
|
+
* without advertising an empty shop.
|
|
91
|
+
*/
|
|
92
|
+
const INPUTS = [
|
|
93
|
+
{
|
|
94
|
+
slug: "beyblade",
|
|
95
|
+
name: "Beyblade",
|
|
96
|
+
description: "The spinning-top battling franchise — every generation from the original Spin Gear tops through Metal Fight, Burst and Beyblade X. Complete tops, loose parts, stadiums and accessories.",
|
|
97
|
+
active: true,
|
|
98
|
+
featured: true,
|
|
99
|
+
keywords: ["beyblade", "spinning tops", "burst", "metal fight", "beyblade x"],
|
|
100
|
+
seoDescription: "Shop Beyblade across every generation — tops, parts, stadiums and spares, new and pre-owned.",
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
slug: "marvel",
|
|
104
|
+
name: "Marvel",
|
|
105
|
+
description: "Figures, collectibles and merchandise from the Marvel universe.",
|
|
106
|
+
active: false,
|
|
107
|
+
keywords: ["marvel", "comics", "superhero", "figures"],
|
|
108
|
+
seoDescription: "Marvel collectibles and figures.",
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
slug: "dc-comics",
|
|
112
|
+
name: "DC Comics",
|
|
113
|
+
description: "Figures, collectibles and merchandise from the DC universe.",
|
|
114
|
+
active: false,
|
|
115
|
+
keywords: ["dc", "dc comics", "superhero", "figures"],
|
|
116
|
+
seoDescription: "DC Comics collectibles and figures.",
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
slug: "dragon-ball",
|
|
120
|
+
name: "Dragon Ball",
|
|
121
|
+
description: "Figures and collectibles from the Dragon Ball series.",
|
|
122
|
+
active: false,
|
|
123
|
+
keywords: ["dragon ball", "anime", "figures", "shonen"],
|
|
124
|
+
seoDescription: "Dragon Ball collectibles and figures.",
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
slug: "naruto",
|
|
128
|
+
name: "Naruto",
|
|
129
|
+
description: "Figures and collectibles from the Naruto series.",
|
|
130
|
+
active: false,
|
|
131
|
+
keywords: ["naruto", "anime", "figures", "shonen"],
|
|
132
|
+
seoDescription: "Naruto collectibles and figures.",
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
slug: "bleach",
|
|
136
|
+
name: "Bleach",
|
|
137
|
+
description: "Figures and collectibles from the Bleach series.",
|
|
138
|
+
active: false,
|
|
139
|
+
keywords: ["bleach", "anime", "figures", "shonen"],
|
|
140
|
+
seoDescription: "Bleach collectibles and figures.",
|
|
141
|
+
},
|
|
142
|
+
{
|
|
143
|
+
slug: "one-piece",
|
|
144
|
+
name: "One Piece",
|
|
145
|
+
description: "Figures and collectibles from the One Piece series.",
|
|
146
|
+
active: false,
|
|
147
|
+
keywords: ["one piece", "anime", "figures", "shonen"],
|
|
148
|
+
seoDescription: "One Piece collectibles and figures.",
|
|
149
|
+
},
|
|
150
|
+
{
|
|
151
|
+
slug: "one-punch-man",
|
|
152
|
+
name: "One Punch Man",
|
|
153
|
+
description: "Figures and collectibles from the One Punch Man series.",
|
|
154
|
+
active: false,
|
|
155
|
+
keywords: ["one punch man", "anime", "figures"],
|
|
156
|
+
seoDescription: "One Punch Man collectibles and figures.",
|
|
157
|
+
},
|
|
158
|
+
];
|
|
159
|
+
export function buildFranchiseRows(stamps) {
|
|
160
|
+
return INPUTS.map((input, i) => franchiseRow(input, i + 1, stamps));
|
|
161
|
+
}
|
|
162
|
+
export const FRANCHISE_ROW_COUNT = INPUTS.length;
|
|
163
|
+
/** The slugs a product's `franchiseSlug` may point at. */
|
|
164
|
+
export const FRANCHISE_SLUGS = INPUTS.map((i) => `franchise-${i.slug}`);
|
|
165
|
+
/**
|
|
166
|
+
* Category ROOT -> the franchise everything beneath it belongs to.
|
|
167
|
+
*
|
|
168
|
+
* Derived rather than stamped per product: a product already carries its full
|
|
169
|
+
* ancestor chain, so the root is free and cannot drift from the taxonomy the
|
|
170
|
+
* way a hand-written field would (Root Cause #42).
|
|
171
|
+
*
|
|
172
|
+
* 🛑 Deliberately PARTIAL. `category-living-collectibles` is absent because a
|
|
173
|
+
* juniper bonsai and a leucistic axolotl are not from an IP — they are living
|
|
174
|
+
* things. Mapping every root for completeness' sake would assert a franchise
|
|
175
|
+
* that does not exist, and "no franchise" is the correct answer for 4 of the
|
|
176
|
+
* 1,308 seeded products. A root with no entry yields no franchise, not a
|
|
177
|
+
* fallback.
|
|
178
|
+
*/
|
|
179
|
+
export const FRANCHISE_BY_CATEGORY_ROOT = {
|
|
180
|
+
"category-spinning-tops": { slug: "franchise-beyblade", name: "Beyblade" },
|
|
181
|
+
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GENERATED by scripts/derive-part-colours.mjs — do not edit by hand.
|
|
3
|
+
*
|
|
4
|
+
* Part glossary id -> the dominant colour MEASURED from that part's cached
|
|
5
|
+
* reference photograph. Not invented: the pixels are the evidence.
|
|
6
|
+
*
|
|
7
|
+
* 🛑 The wiki exposes ONE photo per part, so for a part released in several
|
|
8
|
+
* models this is the colour of the photographed release — exact for that one,
|
|
9
|
+
* indicative for the others. The MODEL half of a colourway is always exact
|
|
10
|
+
* (it comes from `usedBy`); this half carries that caveat. Replacing these
|
|
11
|
+
* with real per-release photography is the intended fix.
|
|
12
|
+
*
|
|
13
|
+
* White is excluded before counting, because the fetcher flattens transparent
|
|
14
|
+
* PNGs onto white and a naive dominant-colour read returns White for almost
|
|
15
|
+
* everything.
|
|
16
|
+
*/
|
|
17
|
+
export declare const GENERATED_PART_COLOURS: Readonly<Record<string, string>>;
|
|
18
|
+
export declare const GENERATED_PART_COLOUR_COUNT = 254;
|