@websolutespa/bom-core 3.0.5 → 3.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,22 @@
1
1
  # @websolutespa/bom-core
2
2
 
3
+ ## 3.1.1
4
+
5
+ ## 3.1.0
6
+
7
+ ### Minor Changes
8
+
9
+ - 3f7c21b: - Payload 3.91.0 and Next.js 16.4.2 (React 19.2.9): peer dependencies are now ranges, `payload` / `@payloadcms/*` `^3.91.0`, `next` `^16.3.3`, `react` / `react-dom` `^19.2.1`
10
+ - payload-plugin-bowl: the mixer context is built only for reads by an authenticated user (payload 3.90+ resolves the jwt user with the request query, populating tenants before `req.user` is set); email options typed with payload `SendEmailOptions`, no direct nodemailer dependency
11
+ - payload-plugin-storage: `AZURE_STORAGE_CONTAINER_ACCESS` (`private` default since payload 3.90, `blob`, `container`) for containers created by the plugin
12
+ - mixer web: `images.qualities` includes `IMAGE_QUALITY` (next 16 defaults to `[75]`)
13
+
14
+ ### Patch Changes
15
+
16
+ - 12b6e2f: - test: replace the jest presets with shared vitest configurations, `@websolutespa/test/vitest` (`defineNodeConfig`, `defineDomConfig`, `definePayloadConfig`); drop jest dependencies
17
+ - declare every imported package and script binary in the package that uses it (no more reliance on hoisting), drop unused dependencies
18
+ - bom-mixer-checkout: `useCart.add` no longer mutates the previous cart state
19
+
3
20
  ## 3.0.5
4
21
 
5
22
  ### Patch Changes
package/dist/index.d.ts CHANGED
@@ -270,92 +270,6 @@ type IMeta = {
270
270
  image?: IMedia;
271
271
  };
272
272
 
273
- type ICategory = IEntity & {
274
- category?: IEquatable | ICategory;
275
- id: IEquatable;
276
- media?: IMedia;
277
- order?: number;
278
- slug: ILocalizable;
279
- title: ILocalizable;
280
- isHidden?: boolean;
281
- };
282
- type ICategoryItem = ICategory & {
283
- items: ICategory[];
284
- };
285
- type ICategorized = IEntity & {
286
- title: ILocalizable;
287
- abstract?: string;
288
- description?: string;
289
- media?: IMedia;
290
- meta?: IMeta;
291
- components?: IComponent[];
292
- category: IEquatable | ICategory;
293
- slug: ILocalizable;
294
- template?: string;
295
- isDefault?: boolean;
296
- useSplat?: boolean;
297
- order?: number;
298
- markets?: string[];
299
- createdAt?: Date;
300
- updatedAt?: Date;
301
- _status?: string;
302
- };
303
-
304
- type IClassNameValue = string | boolean | number | null | undefined;
305
- type IClassNameCollection = Record<string, IClassNameValue>;
306
- type IClassName = IClassNameCollection | IClassNameValue;
307
-
308
- type IEmailConfig = IEntity & {
309
- id: string;
310
- subject: string;
311
- fromAddress: string;
312
- to: [{
313
- address: string;
314
- }];
315
- cc: [{
316
- address: string;
317
- }];
318
- bcc: [{
319
- address: string;
320
- }];
321
- };
322
-
323
- type FetchRequestOptions = {
324
- method?: string;
325
- headers?: {
326
- [key: string]: string;
327
- };
328
- body?: Blob | BufferSource | FormData | URLSearchParams | string | ReadableStream;
329
- mode?: 'cors' | 'no-cors' | 'same-origin';
330
- credentials?: 'omit' | 'same-origin' | 'include';
331
- cache?: 'default' | 'no-store' | 'reload' | 'no-cache' | 'force-cache' | 'only-if-cached';
332
- redirect?: 'follow' | 'error' | 'manual';
333
- referrer?: string;
334
- referrerPolicy?: 'no-referrer, no-referrer-when-downgrade, same-origin, origin, strict-origin, origin-when-cross-origin, strict-origin-when-cross-origin, or unsafe-url';
335
- integrity?: string;
336
- keepalive?: boolean;
337
- signal?: AbortSignal;
338
- };
339
- type FetchService<T = unknown> = (url: string, options?: FetchRequestOptions, serviceOptions?: any) => Promise<T>;
340
- type FetchError = any;
341
-
342
- declare enum ImageStrategy {
343
- None = "none",
344
- Next = "next",
345
- Mixer = "mixer",
346
- Oven = "oven",
347
- Token = "token",
348
- Custom = "custom"
349
- }
350
- type IImageResize = {
351
- q: number;
352
- w: number;
353
- h?: number;
354
- x?: number;
355
- y?: number;
356
- src: string;
357
- };
358
-
359
273
  type ILabel = IEntity & {
360
274
  id: IEquatable;
361
275
  text?: ILocalizable;
@@ -380,111 +294,11 @@ type IMarket = IEntity & {
380
294
  isHidden?: boolean;
381
295
  };
382
296
 
383
- type IRoute = {
384
- category: IEquatable;
385
- id: string;
386
- isDefault?: boolean;
387
- isRoot?: boolean;
388
- locale: string;
389
- market: string;
390
- media?: IMedia;
391
- noindex?: boolean;
392
- order?: number;
393
- page: IEquatable;
394
- resolvedCategory: IEquatable;
395
- schema: string;
396
- template?: string;
397
- title: string;
398
- updatedAt?: Date;
399
- useSplat?: boolean;
400
- };
401
- type IRouteCanonical = IRoute & {
402
- alternates: IRoute[];
403
- };
404
- type IRouteLink = {
405
- category: IEquatable;
406
- href: string;
407
- id: IEquatable;
408
- items?: IRouteLink[];
409
- media?: IMedia;
410
- schema: string;
411
- title: string;
412
- };
413
- type IRouteParams = Record<string, any> & {
414
- id: IEquatable;
415
- locale: string;
416
- market: string;
417
- };
418
-
419
- /**
420
- * Represents a listing item returned from the findMany method of a page collection.
421
- * @template T - The type of the categorized item.
422
- */
423
- type IPageItem<T extends ICategorized = ICategorized> = ILocalized<T> & {
424
- schema: string;
425
- category: ILocalized<ICategory> & {
426
- href: string;
427
- };
428
- href: string;
429
- locale: string;
430
- market: string;
431
- };
432
- /**
433
- * Represents a detail item returned from the findOne method of a page collection.
434
- * @template T - The type of the categorized item.
435
- */
436
- type IPage<T extends ICategorized = ICategorized> = ILocalized<T> & {
437
- schema: string;
438
- alternates: IRoute[];
439
- breadcrumb: IRouteLink[];
440
- category: ILocalized<ICategory> & {
441
- href: string;
442
- };
443
- href: string;
444
- locale: string;
445
- market: string;
446
- parentRoute?: IRouteLink;
447
- slug: string;
448
- title: string;
449
- };
450
- /**
451
- * Represents the props for a page component.
452
- * @template T - The type of the categorized item.
453
- */
454
- type PageProps<T extends ICategorized = ICategorized> = {
455
- layout: ILayout;
456
- page: IPage<T>;
457
- params: IRouteParams;
458
- locales?: string[];
459
- locale?: string;
460
- defaultLocale?: string;
461
- };
462
- /**
463
- * Represents the result of a page relation.
464
- * @template T - The type of the categorized item.
465
- */
466
- type IPageRelationResult<T extends ICategorized = ICategorized> = {
467
- href: string;
468
- } & T;
469
- /**
470
- * Represents a page relation.
471
- * @template T - The type of the categorized item.
472
- */
473
- type IPageRelation<T extends ICategorized = ICategorized> = {
474
- relationTo: string;
475
- value: IPageRelationResult<T> | IPageRelationResult<T>[];
476
- };
477
- /**
478
- * Represents an unresolved page relation.
479
- */
480
- type IPageUnresolvedRelation = {
481
- relationTo: string;
482
- value: IEquatable | IEquatable[];
483
- };
484
-
485
297
  declare enum MenuCategoryStrategy {
486
298
  Default = "default",// show hidden categories recursively,
487
- ExcludeHidden = "exclude-hidden"
299
+ ExcludeHidden = "exclude-hidden",
300
+ ExcludeRoute = "exclude-route",
301
+ ExcludeHiddenAndRoute = "exclude-hidden-and-route"
488
302
  }
489
303
  type IMenuBase = {
490
304
  abstract?: ILocalizable;
@@ -587,6 +401,50 @@ type IUndecoratedMenu = IEntity & {
587
401
  items: IUndecoratedMenuItem[];
588
402
  };
589
403
 
404
+ type IRoute = {
405
+ category: IEquatable;
406
+ id: string;
407
+ locale: string;
408
+ market: string;
409
+ page: IEquatable;
410
+ resolvedCategory: IEquatable;
411
+ schema: string;
412
+ title: string;
413
+ _status?: 'published' | 'draft';
414
+ isDefault?: boolean;
415
+ isProtected?: boolean;
416
+ isRoot?: boolean;
417
+ media?: {
418
+ url: string;
419
+ src?: string;
420
+ type: string;
421
+ updatedAt?: Date | string;
422
+ };
423
+ noindex?: boolean;
424
+ order?: number;
425
+ publicRedirect?: string;
426
+ template?: string;
427
+ updatedAt?: Date | string;
428
+ useSplat?: boolean;
429
+ };
430
+ type IRouteCanonical = IRoute & {
431
+ alternates: IRoute[];
432
+ };
433
+ type IRouteLink = {
434
+ category: IEquatable;
435
+ href: string;
436
+ id: IEquatable;
437
+ items?: IRouteLink[];
438
+ media?: IMedia;
439
+ schema: string;
440
+ title: string;
441
+ };
442
+ type IRouteParams = Record<string, any> & {
443
+ id: IEquatable;
444
+ locale: string;
445
+ market: string;
446
+ };
447
+
590
448
  type ILayout<T extends IAppExtended = IAppExtended> = {
591
449
  labels: ILabel[];
592
450
  locale: string;
@@ -600,6 +458,160 @@ type ILayout<T extends IAppExtended = IAppExtended> = {
600
458
  tree?: IRouteLink;
601
459
  };
602
460
 
461
+ /**
462
+ * Represents a listing item returned from the findMany method of a page collection.
463
+ * @template T - The type of the categorized item.
464
+ */
465
+ type IPageItem<T extends ICategorized = ICategorized> = ILocalized<T> & {
466
+ schema: string;
467
+ category: ILocalized<ICategory> & {
468
+ href: string;
469
+ };
470
+ href: string;
471
+ locale: string;
472
+ market: string;
473
+ };
474
+ /**
475
+ * Represents a detail item returned from the findOne method of a page collection.
476
+ * @template T - The type of the categorized item.
477
+ */
478
+ type IPage<T extends ICategorized = ICategorized> = ILocalized<T> & {
479
+ schema: string;
480
+ alternates: IRoute[];
481
+ breadcrumb: IRouteLink[];
482
+ category: ILocalized<ICategory> & {
483
+ href: string;
484
+ };
485
+ href: string;
486
+ locale: string;
487
+ market: string;
488
+ parentRoute?: IRouteLink;
489
+ slug: string;
490
+ title: string;
491
+ };
492
+ /**
493
+ * Represents the props for a page component.
494
+ * @template T - The type of the categorized item.
495
+ */
496
+ type PageProps<T extends ICategorized = ICategorized> = {
497
+ layout: ILayout;
498
+ page: IPage<T>;
499
+ params: IRouteParams;
500
+ locales?: string[];
501
+ locale?: string;
502
+ defaultLocale?: string;
503
+ };
504
+ /**
505
+ * Represents the result of a page relation.
506
+ * @template T - The type of the categorized item.
507
+ */
508
+ type IPageRelationResult<T extends ICategorized = ICategorized> = {
509
+ href: string;
510
+ } & T;
511
+ /**
512
+ * Represents a page relation.
513
+ * @template T - The type of the categorized item.
514
+ */
515
+ type IPageRelation<T extends ICategorized = ICategorized> = {
516
+ relationTo: string;
517
+ value: IPageRelationResult<T> | IPageRelationResult<T>[];
518
+ };
519
+ /**
520
+ * Represents an unresolved page relation.
521
+ */
522
+ type IPageUnresolvedRelation = {
523
+ relationTo: string;
524
+ value: IEquatable | IEquatable[];
525
+ };
526
+
527
+ type ICategory = IEntity & {
528
+ category?: IEquatable | ICategory;
529
+ id: IEquatable;
530
+ media?: IMedia;
531
+ order?: number;
532
+ slug: ILocalizable;
533
+ title: ILocalizable;
534
+ isHidden?: boolean;
535
+ };
536
+ type ICategoryItem = ICategory & {
537
+ items: ICategory[];
538
+ };
539
+ type ICategorized = IEntity & {
540
+ category: IEquatable | ICategory;
541
+ slug: ILocalizable;
542
+ title: ILocalizable;
543
+ _status?: string;
544
+ abstract?: string;
545
+ components?: IComponent[];
546
+ createdAt?: Date;
547
+ description?: string;
548
+ isDefault?: boolean;
549
+ isProtected?: boolean;
550
+ markets?: string[];
551
+ media?: IMedia;
552
+ meta?: IMeta;
553
+ order?: number;
554
+ publicRedirect?: IEquatable | IEntity | IPageUnresolvedRelation;
555
+ template?: string;
556
+ updatedAt?: Date;
557
+ useSplat?: boolean;
558
+ };
559
+
560
+ type IClassNameValue = string | boolean | number | null | undefined;
561
+ type IClassNameCollection = Record<string, IClassNameValue>;
562
+ type IClassName = IClassNameCollection | IClassNameValue;
563
+
564
+ type IEmailConfig = IEntity & {
565
+ id: string;
566
+ subject: string;
567
+ fromAddress: string;
568
+ to: [{
569
+ address: string;
570
+ }];
571
+ cc: [{
572
+ address: string;
573
+ }];
574
+ bcc: [{
575
+ address: string;
576
+ }];
577
+ };
578
+
579
+ type FetchRequestOptions = {
580
+ method?: string;
581
+ headers?: {
582
+ [key: string]: string;
583
+ };
584
+ body?: Blob | BufferSource | FormData | URLSearchParams | string | ReadableStream;
585
+ mode?: 'cors' | 'no-cors' | 'same-origin';
586
+ credentials?: 'omit' | 'same-origin' | 'include';
587
+ cache?: 'default' | 'no-store' | 'reload' | 'no-cache' | 'force-cache' | 'only-if-cached';
588
+ redirect?: 'follow' | 'error' | 'manual';
589
+ referrer?: string;
590
+ referrerPolicy?: 'no-referrer, no-referrer-when-downgrade, same-origin, origin, strict-origin, origin-when-cross-origin, strict-origin-when-cross-origin, or unsafe-url';
591
+ integrity?: string;
592
+ keepalive?: boolean;
593
+ signal?: AbortSignal;
594
+ };
595
+ type FetchService<T = unknown> = (url: string, options?: FetchRequestOptions, serviceOptions?: any) => Promise<T>;
596
+ type FetchError = any;
597
+
598
+ declare enum ImageStrategy {
599
+ None = "none",
600
+ Next = "next",
601
+ Mixer = "mixer",
602
+ Oven = "oven",
603
+ Token = "token",
604
+ Custom = "custom"
605
+ }
606
+ type IImageResize = {
607
+ q: number;
608
+ w: number;
609
+ h?: number;
610
+ x?: number;
611
+ y?: number;
612
+ src: string;
613
+ };
614
+
603
615
  type IUndecoratedNav = IUndecoratedMenuPage;
604
616
  type IDecoratedNav = IMenuPage;
605
617
 
@@ -1568,4 +1580,5 @@ declare function asServerProps(props: any): any;
1568
1580
  declare function awaitAll(array: any, callback: (item: any, index: number) => Promise<any>): Promise<any[]>;
1569
1581
  declare function merge(target: any, source: any): any;
1570
1582
 
1571
- export { type DeepPartial, type DeepRequired, type DeepRequiredProps, type Dynamic, type FetchError, type FetchRequestOptions, type FetchService, type FindParams, type FindWhereParams, type GlobalQueryParams, type Headings, type IAction, type IActionEmailData, type IAnchor, type IApp, type IAppExtended, type ICategorized, type ICategory, type ICategoryItem, type IClassName, type IClassNameCollection, type IClassNameValue, type ICollectionDescription, type IComponent, type IConfig, type IConsentPreference, type IContextBaseParams, type IContextParams, type IDecoratedNav, type IEmailConfig, type IEndUser, type IEntity, type IEquatable, type IFeature, type IFeatureType, type IImageResize, type ILabel, type ILayout, type ILegalNotice, type ILetter, type ILocale, type ILocaleId, type ILocalizable, type ILocalized, type ILocalizedMenu, type ILocalizedString, type IMarket, type IMedia, type IMediaImage, type IMediaInfo, type IMediaJson, type IMediaPdf, type IMediaType, type IMediaVideo, type IMemoryStore, type IMenu, type IMenuBase, type IMenuCategory, type IMenuCustom, type IMenuGroup, type IMenuHref, type IMenuItem, type IMenuLink, type IMenuPage, type IMenuRoute, type IMockCategory, type IMockCollection, type IMockComponent, type IMockLabel, type IMockLocale, type IMockManyRelation, type IMockMarket, type IMockMedia, type IMockMenu, type IMockMenuBase, type IMockMenuCategory, type IMockMenuCustom, type IMockMenuExtra, type IMockMenuGroup, type IMockMenuItem, type IMockMenuLink, type IMockMenuPage, type IMockMeta, type IMockPage, type IMockRedirect, type IMockRelation, type IMockSingleRelation, type IMockStore, type IMockTemplate, type INamedEntity, type IOption, type IOverride, type IOverrideReturnValue, type IOverrideValue, type IPackages, type IPage, type IPageItem, type IPageRelation, type IPageRelationResult, type IPageUnresolvedRelation, type IPagedResult, type IPaginationResult, type IPartial, type IPreference, type IPrettify, type IQuerable, type IRedirect, type IRoute, type IRouteCanonical, type IRouteLink, type IRouteParams, type ISchema, type ISerializedCollection, type ISerializedStore, type IServerSideContext, type IServerSideSplatContext, type IStaticContext, type IStore, type ITemplate, type ITitledEntity, type IUndecoratedMenu, type IUndecoratedMenuBase, type IUndecoratedMenuCategory, type IUndecoratedMenuCustom, type IUndecoratedMenuGroup, type IUndecoratedMenuItem, type IUndecoratedMenuLink, type IUndecoratedMenuPage, type IUndecoratedNav, ImageStrategy, type Json, JsonService, type LiteralUnion, Logger, LoggerLevel, MenuCategoryStrategy, type NextApiRequestCookies, type Operator, type PageProps, type Pagination, type PreviewData, type Primitive, type QueryParams, RedirectReason, type RequireAtLeastOne, RouteStrategy, type SchemaType, type ServerSidePropsContext, type Shift, type ShiftUnion, type StaticPropsContext, type User, type UserRole, type UserWithRoles, type ValueOf, type Where, type WhereAndOr, type WhereBase, type WhereField, arrayShuffle, asCategoryId, asEntityId, asEquatable, asEquatableNumber, asEquatableString, asServerProps, asSortedOptions, awaitAll, base64ToString, camelToSnakeCase, cloneItem, collectFeatureTypes, collectFeatureTypes__, collectOptions, collectRoutes, consoleWarn, decryptImageResize, deepMerge, defaultLocale, defaultMarket, eachCategorized, eachMarketLocale, eachMedia, eachValue, encryptImageToken, enumToList, excludeComponent, findCategoryInCategories, findChildCategories, findRouteOfCategory, findRoutesOfCategory, getCategorySegments, getCategorySegmentsByCategory, getClassNames, getCollectionDescription, getEnv, getHost, getIsDevelopment, getIsProduction, getOrigin, getParentCategoriesById, getParentCategory, getProto, getRootCategory, getRouteHref, groupComponents, hasComponents, hasMarket, httpDelete, httpFetch, httpGet, httpPatch, httpPost, httpPut, isArray, isBrowser, isComponent, isComponentOfType, isDevelopment, isEntity, isEquatable, isHeaders, isIncomingHttpHeaders, isLocalizedString, isMedia, isMediaImage, isMediaJson, isMediaPdf, isMediaVideo, isMenuCategory, isMenuGroup, isMenuHref, isMenuLink, isMenuPage, isMenuRoute, isNonEmptyArray, isNotNullString, isNumber, isObject, isProduction, isPromise, isRelation, isReservedCollectionDescription, isStage, isString, isUndecoratedCategory, isUndecoratedMenuCategory, isUndecoratedMenuItem, isUndecoratedMenuPage, isUndecoratedNav, isUnresolvedCategory, isUnresolvedRelation, isValidCollectionDescription, isValidString, localize, localizeItem, localizeValue, localizedToString, merge, pascalCaseToCamelCase, pascalCaseToCharCase, pascalCaseToKebabCase, pascalCaseToSnakeCase, passwordStrategy, pickComponent, pickHero, prependHero, qsDeserialize, qsDeserializeRaw, qsSerialize, qsSerializeRaw, resolveMediaType, stringToBase64, toCamelCase, toCharCase, toDisplayName, toFindParams, toKebabCase, toPascalCase, toPluralName, toSnakeCase, toTitleCase, toValidCollectionName, unknownCaseToPascalCase, uuidv4, withSchema };
1583
+ export { ImageStrategy, JsonService, Logger, LoggerLevel, MenuCategoryStrategy, RedirectReason, RouteStrategy, arrayShuffle, asCategoryId, asEntityId, asEquatable, asEquatableNumber, asEquatableString, asServerProps, asSortedOptions, awaitAll, base64ToString, camelToSnakeCase, cloneItem, collectFeatureTypes, collectFeatureTypes__, collectOptions, collectRoutes, consoleWarn, decryptImageResize, deepMerge, defaultLocale, defaultMarket, eachCategorized, eachMarketLocale, eachMedia, eachValue, encryptImageToken, enumToList, excludeComponent, findCategoryInCategories, findChildCategories, findRouteOfCategory, findRoutesOfCategory, getCategorySegments, getCategorySegmentsByCategory, getClassNames, getCollectionDescription, getEnv, getHost, getIsDevelopment, getIsProduction, getOrigin, getParentCategoriesById, getParentCategory, getProto, getRootCategory, getRouteHref, groupComponents, hasComponents, hasMarket, httpDelete, httpFetch, httpGet, httpPatch, httpPost, httpPut, isArray, isBrowser, isComponent, isComponentOfType, isDevelopment, isEntity, isEquatable, isHeaders, isIncomingHttpHeaders, isLocalizedString, isMedia, isMediaImage, isMediaJson, isMediaPdf, isMediaVideo, isMenuCategory, isMenuGroup, isMenuHref, isMenuLink, isMenuPage, isMenuRoute, isNonEmptyArray, isNotNullString, isNumber, isObject, isProduction, isPromise, isRelation, isReservedCollectionDescription, isStage, isString, isUndecoratedCategory, isUndecoratedMenuCategory, isUndecoratedMenuItem, isUndecoratedMenuPage, isUndecoratedNav, isUnresolvedCategory, isUnresolvedRelation, isValidCollectionDescription, isValidString, localize, localizeItem, localizeValue, localizedToString, merge, pascalCaseToCamelCase, pascalCaseToCharCase, pascalCaseToKebabCase, pascalCaseToSnakeCase, passwordStrategy, pickComponent, pickHero, prependHero, qsDeserialize, qsDeserializeRaw, qsSerialize, qsSerializeRaw, resolveMediaType, stringToBase64, toCamelCase, toCharCase, toDisplayName, toFindParams, toKebabCase, toPascalCase, toPluralName, toSnakeCase, toTitleCase, toValidCollectionName, unknownCaseToPascalCase, uuidv4, withSchema };
1584
+ export type { DeepPartial, DeepRequired, DeepRequiredProps, Dynamic, FetchError, FetchRequestOptions, FetchService, FindParams, FindWhereParams, GlobalQueryParams, Headings, IAction, IActionEmailData, IAnchor, IApp, IAppExtended, ICategorized, ICategory, ICategoryItem, IClassName, IClassNameCollection, IClassNameValue, ICollectionDescription, IComponent, IConfig, IConsentPreference, IContextBaseParams, IContextParams, IDecoratedNav, IEmailConfig, IEndUser, IEntity, IEquatable, IFeature, IFeatureType, IImageResize, ILabel, ILayout, ILegalNotice, ILetter, ILocale, ILocaleId, ILocalizable, ILocalized, ILocalizedMenu, ILocalizedString, IMarket, IMedia, IMediaImage, IMediaInfo, IMediaJson, IMediaPdf, IMediaType, IMediaVideo, IMemoryStore, IMenu, IMenuBase, IMenuCategory, IMenuCustom, IMenuGroup, IMenuHref, IMenuItem, IMenuLink, IMenuPage, IMenuRoute, IMockCategory, IMockCollection, IMockComponent, IMockLabel, IMockLocale, IMockManyRelation, IMockMarket, IMockMedia, IMockMenu, IMockMenuBase, IMockMenuCategory, IMockMenuCustom, IMockMenuExtra, IMockMenuGroup, IMockMenuItem, IMockMenuLink, IMockMenuPage, IMockMeta, IMockPage, IMockRedirect, IMockRelation, IMockSingleRelation, IMockStore, IMockTemplate, INamedEntity, IOption, IOverride, IOverrideReturnValue, IOverrideValue, IPackages, IPage, IPageItem, IPageRelation, IPageRelationResult, IPageUnresolvedRelation, IPagedResult, IPaginationResult, IPartial, IPreference, IPrettify, IQuerable, IRedirect, IRoute, IRouteCanonical, IRouteLink, IRouteParams, ISchema, ISerializedCollection, ISerializedStore, IServerSideContext, IServerSideSplatContext, IStaticContext, IStore, ITemplate, ITitledEntity, IUndecoratedMenu, IUndecoratedMenuBase, IUndecoratedMenuCategory, IUndecoratedMenuCustom, IUndecoratedMenuGroup, IUndecoratedMenuItem, IUndecoratedMenuLink, IUndecoratedMenuPage, IUndecoratedNav, Json, LiteralUnion, NextApiRequestCookies, Operator, PageProps, Pagination, PreviewData, Primitive, QueryParams, RequireAtLeastOne, SchemaType, ServerSidePropsContext, Shift, ShiftUnion, StaticPropsContext, User, UserRole, UserWithRoles, ValueOf, Where, WhereAndOr, WhereBase, WhereField };
package/dist/index.js CHANGED
@@ -417,6 +417,8 @@ function isMedia(item) {
417
417
  var MenuCategoryStrategy = /* @__PURE__ */ ((MenuCategoryStrategy2) => {
418
418
  MenuCategoryStrategy2["Default"] = "default";
419
419
  MenuCategoryStrategy2["ExcludeHidden"] = "exclude-hidden";
420
+ MenuCategoryStrategy2["ExcludeRoute"] = "exclude-route";
421
+ MenuCategoryStrategy2["ExcludeHiddenAndRoute"] = "exclude-hidden-and-route";
420
422
  return MenuCategoryStrategy2;
421
423
  })(MenuCategoryStrategy || {});
422
424
  function isMenuHref(item) {
@@ -1439,8 +1441,7 @@ function qsDeserializeKey(value) {
1439
1441
  return value;
1440
1442
  }
1441
1443
  function qsDeserializeKeys(key) {
1442
- const keys = key.replace(/[\]]/g, "").split("[").map((x) => qsDeserializeKey(x));
1443
- return keys;
1444
+ return key.replace(/[\]]/g, "").split("[").map((value) => qsDeserializeKey(value)).filter((value) => value !== "");
1444
1445
  }
1445
1446
  function getNextKeyItem(key) {
1446
1447
  if (typeof key === "number") {
@@ -1534,12 +1535,49 @@ var RouteStrategy = /* @__PURE__ */ ((RouteStrategy2) => {
1534
1535
  return RouteStrategy2;
1535
1536
  })(RouteStrategy || {});
1536
1537
  var ROUTE_STRATEGY = process.env.ROUTE_STRATEGY || "manual" /* Manual */;
1538
+ function getPublicRedirectId(value) {
1539
+ if (value && typeof value === "object" && "relationTo" in value && "value" in value) {
1540
+ const relationValue = value.value;
1541
+ return Array.isArray(relationValue) ? void 0 : asEntityId(relationValue);
1542
+ }
1543
+ return asEntityId(value);
1544
+ }
1537
1545
  function collectRoutes(store, categories, markets, locales, medias) {
1538
1546
  const routes = [];
1547
+ const redirects = /* @__PURE__ */ new Map();
1539
1548
  if (locales.length > 0 && markets.length > 0) {
1540
1549
  const rootCategory = getRootCategory(categories);
1550
+ const activeLocales = locales.filter((locale) => locale.isActive !== false);
1551
+ const activeMarkets = markets.filter((market) => market.isActive !== false);
1552
+ const categoryById = new Map(categories.filter((category) => typeof category.id === "string").map((category) => [category.id, category]));
1553
+ const localeById = new Map(activeLocales.filter((locale) => typeof locale.id === "string").map((locale) => [locale.id, locale]));
1554
+ const mediaById = new Map((medias || []).filter((media) => typeof media.id === "string").map((media) => [media.id, media]));
1555
+ const marketLocales = activeMarkets.flatMap((market) => {
1556
+ const localesForMarket = market.languages && market.languages.length > 0 ? market.languages.map((language) => localeById.get(String(asEntityId(language)))).filter((locale) => locale !== void 0) : activeLocales;
1557
+ return localesForMarket.map((locale) => ({ market, locale }));
1558
+ });
1559
+ const getSegments = (item) => {
1560
+ const routeCategories = [];
1561
+ const segments = [];
1562
+ let parentId = asCategoryId(item.category);
1563
+ while (parentId != null) {
1564
+ const parentCategory = categoryById.get(parentId);
1565
+ if (parentCategory) {
1566
+ segments.unshift({ ...parentCategory });
1567
+ routeCategories.push(parentId);
1568
+ parentId = asCategoryId(parentCategory.category);
1569
+ if (parentId && routeCategories.includes(parentId)) {
1570
+ console.log("ICategory.getParentCategoriesById", "circular reference found", parentId);
1571
+ parentId = void 0;
1572
+ }
1573
+ } else {
1574
+ parentId = void 0;
1575
+ }
1576
+ }
1577
+ return segments;
1578
+ };
1541
1579
  eachCategorized(store, (item, key) => {
1542
- const segments = getCategorySegments(categories, item);
1580
+ const segments = getSegments(item);
1543
1581
  const visibleSegments = segments.filter((x) => x.id !== rootCategory?.id && Boolean(x.isHidden) === false);
1544
1582
  const visibleCategory = visibleSegments.length > 0 ? visibleSegments[visibleSegments.length - 1] : rootCategory;
1545
1583
  if (visibleCategory) {
@@ -1548,16 +1586,17 @@ function collectRoutes(store, categories, markets, locales, medias) {
1548
1586
  slugs.push({ slug: item.slug });
1549
1587
  }
1550
1588
  const isRootCategory = rootCategory && item.category === rootCategory.id && item.isDefault;
1551
- eachMarketLocale(markets, locales, (market, locale, markets2, locales2) => {
1589
+ marketLocales.forEach(({ market, locale }) => {
1552
1590
  if (hasMarket(item, market)) {
1553
1591
  const title = localize(item.title, locale.id);
1554
- const id = getRouteHref(slugs, market, locale, markets2, locales2);
1592
+ const id = getRouteHref(slugs, market, locale, activeMarkets, activeLocales);
1555
1593
  const {
1556
1594
  _status,
1557
1595
  category,
1558
1596
  isDefault,
1559
1597
  media,
1560
1598
  order,
1599
+ isProtected,
1561
1600
  template,
1562
1601
  updatedAt,
1563
1602
  useSplat
@@ -1565,11 +1604,10 @@ function collectRoutes(store, categories, markets, locales, medias) {
1565
1604
  const route = {
1566
1605
  _status,
1567
1606
  category,
1568
- // id: isDefaultRootCategory ? '/' : id,
1569
1607
  id,
1570
1608
  locale: locale.id,
1571
1609
  market: market.id,
1572
- media,
1610
+ media: routeMedia(media),
1573
1611
  page: item.id,
1574
1612
  resolvedCategory: visibleCategory.id,
1575
1613
  schema: key,
@@ -1580,6 +1618,13 @@ function collectRoutes(store, categories, markets, locales, medias) {
1580
1618
  if (isDefault) {
1581
1619
  route.isDefault = true;
1582
1620
  }
1621
+ if (isProtected) {
1622
+ route.isProtected = true;
1623
+ const publicRedirect = getPublicRedirectId(item.publicRedirect);
1624
+ if (publicRedirect != null) {
1625
+ redirects.set(item.id, publicRedirect);
1626
+ }
1627
+ }
1583
1628
  if (isRootCategory) {
1584
1629
  route.isRoot = true;
1585
1630
  }
@@ -1594,10 +1639,10 @@ function collectRoutes(store, categories, markets, locales, medias) {
1594
1639
  route.useSplat = true;
1595
1640
  }
1596
1641
  const mediaId = typeof item.media === "string" ? item.media : void 0;
1597
- if (Array.isArray(medias) && mediaId) {
1598
- const media2 = item.media && medias.find((x) => x.id === mediaId);
1642
+ if (mediaId) {
1643
+ const media2 = mediaById.get(mediaId);
1599
1644
  if (media2) {
1600
- route.media = media2;
1645
+ route.media = routeMedia(media2);
1601
1646
  }
1602
1647
  }
1603
1648
  routes.push(route);
@@ -1605,9 +1650,34 @@ function collectRoutes(store, categories, markets, locales, medias) {
1605
1650
  });
1606
1651
  }
1607
1652
  });
1653
+ const routeByPageContext = /* @__PURE__ */ new Map();
1654
+ for (const route of routes) {
1655
+ routeByPageContext.set(JSON.stringify([route.page, route.market, route.locale]), route);
1656
+ }
1657
+ for (const route of routes) {
1658
+ const targetPage = redirects.get(route.page);
1659
+ if (targetPage != null) {
1660
+ const target = routeByPageContext.get(JSON.stringify([targetPage, route.market, route.locale]));
1661
+ if (target) {
1662
+ route.publicRedirect = target.id;
1663
+ }
1664
+ }
1665
+ }
1608
1666
  }
1609
1667
  return routes;
1610
1668
  }
1669
+ function routeMedia(media) {
1670
+ const url = media?.url || media?.src;
1671
+ return media && url ? {
1672
+ // createdAt: media.createdAt,
1673
+ updatedAt: media.updatedAt,
1674
+ // filename: media.filename,
1675
+ // mimeType: media.mimeType,
1676
+ // id: media.id,
1677
+ url,
1678
+ type: media.type
1679
+ } : void 0;
1680
+ }
1611
1681
  function eachMarketLocale(markets, locales, callback) {
1612
1682
  locales = locales.filter((x) => x.isActive !== false);
1613
1683
  markets = markets.filter((x) => x.isActive !== false);
@@ -1628,7 +1698,7 @@ function eachCategorized(store, callback) {
1628
1698
  }
1629
1699
  }
1630
1700
  function findRouteOfCategory(routes, categoryId, market, locale) {
1631
- const findRoute = market && locale ? (route2) => route2.isDefault && route2.resolvedCategory === categoryId && route2.market === market && route2.locale === locale : (route2) => route2.isDefault && route2.resolvedCategory === categoryId;
1701
+ const findRoute = market && locale ? ((route2) => route2.isDefault && route2.resolvedCategory === categoryId && route2.market === market && route2.locale === locale) : ((route2) => route2.isDefault && route2.resolvedCategory === categoryId);
1632
1702
  const route = routes.find(findRoute);
1633
1703
  return route;
1634
1704
  }
@@ -1675,7 +1745,7 @@ function getRouteHref(segments, market, locale, markets, locales) {
1675
1745
  return `${prefix}${href}`;
1676
1746
  }
1677
1747
  function hasMarket(item, market) {
1678
- return !item.markets || item.markets.length === 0 || item.markets.includes(market.id);
1748
+ return !item.markets || item.markets.length === 0 || item.markets.map((x) => asEquatable(x)).includes(market.id);
1679
1749
  }
1680
1750
  export {
1681
1751
  ImageStrategy,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@websolutespa/bom-core",
3
- "version": "3.0.5",
3
+ "version": "3.1.1",
4
4
  "description": "Core module of the BOM Repository",
5
5
  "keywords": [
6
6
  "bom",
@@ -13,7 +13,7 @@
13
13
  "url": "git://github.com/websolutespa/bom.git"
14
14
  },
15
15
  "scripts": {
16
- "lint": "eslint *.ts*",
16
+ "lint": "eslint .",
17
17
  "test": "vitest run",
18
18
  "test-watch": "vitest",
19
19
  "coverage:integration": "npm run test -- --coverage.enabled --coverage.provider=istanbul --coverage.all",
@@ -29,17 +29,18 @@
29
29
  "peerDependencies": {},
30
30
  "devDependencies": {
31
31
  "@types/pluralize": "0.0.33",
32
- "@types/react": "19.2.10",
33
- "@websolutespa/eslint-config": "^3.0.0",
34
- "@websolutespa/test": "^3.0.1",
35
- "@websolutespa/tsconfig": "^3.0.0",
36
- "eslint": "9.31.0",
32
+ "@types/react": "19.2.18",
33
+ "@vitest/coverage-istanbul": "5.0.5",
34
+ "@websolutespa/eslint-config": "^3.1.1",
35
+ "@websolutespa/test": "^3.1.1",
36
+ "@websolutespa/tsconfig": "^3.1.1",
37
+ "eslint": "10.13.0",
37
38
  "npm-run-all": "4.1.5",
38
39
  "raw-loader": "4.0.2",
39
- "react": "19.2.3",
40
- "tsup": "8.5.0",
41
- "typescript": "5.8.3",
42
- "vitest": "3.2.3"
40
+ "react": "19.2.9",
41
+ "tsup": "9.0.0",
42
+ "typescript": "6.0.3",
43
+ "vitest": "5.0.5"
43
44
  },
44
45
  "publishConfig": {
45
46
  "access": "public"