@websolutespa/bom-core 4.0.0-next.0 → 4.0.0-next.6

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,11 +1,41 @@
1
1
  # @websolutespa/bom-core
2
2
 
3
+ ## 4.0.0-next.6
4
+
5
+ ## 4.0.0-next.1
6
+
7
+ ### Patch Changes
8
+
9
+ - `getMetaRobots` reads `meta.robots` or `meta.robot` (the `@payloadcms/plugin-seo` field); `IMeta.robot` is added and route `noindex` uses it.
10
+ - `ILayout.homeHref` is added.
11
+ - `ROOT_CATEGORY` is read when `getRootCategory` is called instead of once at module load.
12
+ - `httpFetch` logs 4xx responses in development only; server errors and network errors are always logged.
13
+
3
14
  ## 4.0.0-next.0
4
15
 
5
16
  ### Major Changes
6
17
 
7
18
  - Next: support of the bom-next app package
8
19
 
20
+ ## 3.1.2
21
+
22
+ ## 3.1.1
23
+
24
+ ## 3.1.0
25
+
26
+ ### Minor Changes
27
+
28
+ - 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`
29
+ - 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
30
+ - payload-plugin-storage: `AZURE_STORAGE_CONTAINER_ACCESS` (`private` default since payload 3.90, `blob`, `container`) for containers created by the plugin
31
+ - mixer web: `images.qualities` includes `IMAGE_QUALITY` (next 16 defaults to `[75]`)
32
+
33
+ ### Patch Changes
34
+
35
+ - 12b6e2f: - test: replace the jest presets with shared vitest configurations, `@websolutespa/test/vitest` (`defineNodeConfig`, `defineDomConfig`, `definePayloadConfig`); drop jest dependencies
36
+ - declare every imported package and script binary in the package that uses it (no more reliance on hoisting), drop unused dependencies
37
+ - bom-mixer-checkout: `useCart.add` no longer mutates the previous cart state
38
+
9
39
  ## 3.0.5
10
40
 
11
41
  ### Patch Changes
package/README.md CHANGED
@@ -1,11 +1,11 @@
1
- # @websolutespa/bom-core
2
-
3
- [![npm version](https://badge.fury.io/js/%40websolutespa%2Fbom-core.svg)](https://badge.fury.io/js/%40websolutespa%2Fbom-core)
4
-
5
- [![status alpha](https://img.shields.io/badge/status-alpha-red.svg)](https://shields.io/)
6
-
7
- Core module of the [BOM Repository](https://github.com/websolutespa/bom) by [websolute](https://www.websolute.com/).
8
-
9
- ---
10
-
11
- ##### *this library is for internal usage and not production ready*
1
+ # @websolutespa/bom-core
2
+
3
+ [![npm version](https://badge.fury.io/js/%40websolutespa%2Fbom-core.svg)](https://badge.fury.io/js/%40websolutespa%2Fbom-core)
4
+
5
+ [![status alpha](https://img.shields.io/badge/status-alpha-red.svg)](https://shields.io/)
6
+
7
+ Core module of the [BOM Repository](https://github.com/websolutespa/bom) by [websolute](https://www.websolute.com/).
8
+
9
+ ---
10
+
11
+ ##### _this library is for internal usage and not production ready_
package/dist/index.d.ts CHANGED
@@ -60,18 +60,18 @@ type IPrettify<T> = {
60
60
  [K in keyof T]: T[K];
61
61
  } & {};
62
62
  type IOverrideReturnValue<T, FromType, ToType> = T extends Record<string, unknown> ? IPrettify<IOverride<T, FromType, ToType>> : T;
63
- type IOverrideValue<T, FromType, ToType> = T extends FromType ? (keyof T extends keyof FromType ? ToType : IOverrideReturnValue<T, FromType, ToType>) : IOverrideReturnValue<T, FromType, ToType>;
63
+ type IOverrideValue<T, FromType, ToType> = T extends FromType ? keyof T extends keyof FromType ? ToType : IOverrideReturnValue<T, FromType, ToType> : IOverrideReturnValue<T, FromType, ToType>;
64
64
  type IOverride<T, FromType, ToType> = {
65
65
  [Property in keyof T]: IOverrideValue<T[Property], FromType, ToType>;
66
66
  };
67
67
  type RequireAtLeastOne<T> = {
68
68
  [K in keyof T]-?: Required<Pick<T, K>> & Partial<Pick<T, Exclude<keyof T, K>>>;
69
69
  }[keyof T];
70
- type Shift<T extends any[]> = ((...t: T) => any) extends ((first: any, ...rest: infer Rest) => any) ? Rest : never;
70
+ type Shift<T extends any[]> = ((...t: T) => any) extends (first: any, ...rest: infer Rest) => any ? Rest : never;
71
71
  type ShiftUnion<P extends PropertyKey, T extends any[]> = T extends any[] ? T[0] extends P ? Shift<T> : never : never;
72
- type DeepRequiredProps<T, P extends string[]> = T extends object ? (Omit<T, Extract<keyof T, P[0]>> & Required<{
72
+ type DeepRequiredProps<T, P extends string[]> = T extends object ? Omit<T, Extract<keyof T, P[0]>> & Required<{
73
73
  [K in Extract<keyof T, P[0]>]: NonNullable<DeepRequiredProps<T[K], ShiftUnion<K, P>>>;
74
- }>) : T;
74
+ }> : T;
75
75
  type DeepRequired<T> = {
76
76
  [K in keyof T]: Required<DeepRequired<T[K]>>;
77
77
  };
@@ -267,6 +267,8 @@ type IMeta = {
267
267
  description?: string;
268
268
  keywords?: string;
269
269
  robots?: string;
270
+ /** Robots directive as stored by `@payloadcms/plugin-seo` setups. Read through `getMetaRobots`. */
271
+ robot?: string;
270
272
  image?: IMedia;
271
273
  };
272
274
 
@@ -453,9 +455,17 @@ type ILayout<T extends IAppExtended = IAppExtended> = {
453
455
  markets: IMarket[];
454
456
  app: IPrettify<IApp<T>>;
455
457
  menu: Record<string, ILocalizedMenu>;
458
+ /**
459
+ * Root and first-level hrefs keyed by route schema (template or collection
460
+ * slug), so renaming a collection changes the key. Use `homeHref` for the
461
+ * home page.
462
+ */
456
463
  topLevelHrefs: Record<string, string>;
464
+ /** Root and first-level routes, keyed like `topLevelHrefs`. */
457
465
  topLevelRoutes: Record<string, IRouteLink>;
458
466
  tree?: IRouteLink;
467
+ /** Href of the root page for the current market and locale (`tree.href`). */
468
+ homeHref?: string;
459
469
  };
460
470
 
461
471
  /**
@@ -757,7 +767,10 @@ type ITemplate = {
757
767
  };
758
768
 
759
769
  /**
760
- * Retrieves the root category from the given list of categories.
770
+ * Retrieves the root category from the given list of categories: the one with
771
+ * id `ROOT_CATEGORY` when set and present, otherwise the first category
772
+ * without a parent. The root and hidden categories (`isHidden`) do not add a
773
+ * segment to page URLs.
761
774
  * @param categories - The list of categories.
762
775
  * @returns The root category, if found; otherwise undefined.
763
776
  */
@@ -984,9 +997,9 @@ declare class JsonService<T extends IEntity = IEntity> implements IQuerable<T> {
984
997
  protected whereItems_<B extends T = T>(items: B[], where?: Where, limit?: number): B[];
985
998
  protected sortCollection_<B extends T = T>(items: B[], sort?: string): B[];
986
999
  protected limitCollection_<B extends T = T>(items: B[], limit?: number): B[];
987
- protected paginatedItems_<B extends T = T>(items: B[], page?: number, limit?: number): ({
1000
+ protected paginatedItems_<B extends T = T>(items: B[], page?: number, limit?: number): {
988
1001
  docs: B[];
989
- } & Pagination);
1002
+ } & Pagination;
990
1003
  }
991
1004
 
992
1005
  declare const defaultLocale: string;
@@ -1050,6 +1063,13 @@ declare class Logger {
1050
1063
 
1051
1064
  declare const defaultMarket: string;
1052
1065
 
1066
+ /**
1067
+ * Returns the robots directive of a page's meta. Bowl's SEO rules write
1068
+ * `meta.robots`, while `@payloadcms/plugin-seo` setups store the editor value
1069
+ * in `meta.robot`; `robots` wins when both are set.
1070
+ */
1071
+ declare function getMetaRobots(meta?: Pick<IMeta, 'robots' | 'robot'> | null): string | undefined;
1072
+
1053
1073
  /**
1054
1074
  * STORE
1055
1075
  */
@@ -1390,7 +1410,7 @@ declare function asSortedOptions<T extends INamedEntity = INamedEntity>(items: T
1390
1410
  * kebab-case
1391
1411
  * snake_case
1392
1412
  * char*case
1393
- **/
1413
+ **/
1394
1414
  declare function unknownCaseToPascalCase(unknownCase: string): string;
1395
1415
  declare function pascalCaseToCamelCase(pascalCase: string): string;
1396
1416
  declare function pascalCaseToCharCase(pascalCase: string, char?: string): string;
@@ -1452,10 +1472,10 @@ type ListItem<T> = {
1452
1472
  };
1453
1473
  }[keyof T];
1454
1474
  /**
1455
- * Helper to produce an array of enum descriptors.
1456
- * @param enumeration Enumeration object.
1457
- * @param separatorRegex Regex that would catch the separator in your enum key.
1458
- */
1475
+ * Helper to produce an array of enum descriptors.
1476
+ * @param enumeration Enumeration object.
1477
+ * @param separatorRegex Regex that would catch the separator in your enum key.
1478
+ */
1459
1479
  declare function enumToList<T extends Record<string, number | string>>(enumeration: T, separatorRegex?: RegExp): ListItem<T>[];
1460
1480
 
1461
1481
  /**
@@ -1580,4 +1600,5 @@ declare function asServerProps(props: any): any;
1580
1600
  declare function awaitAll(array: any, callback: (item: any, index: number) => Promise<any>): Promise<any[]>;
1581
1601
  declare function merge(target: any, source: any): any;
1582
1602
 
1583
- 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 };
1603
+ 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, getMetaRobots, 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 };
1604
+ 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
@@ -117,10 +117,7 @@ function pascalCaseToCamelCase(pascalCase) {
117
117
  return camelCase;
118
118
  }
119
119
  function pascalCaseToCharCase(pascalCase, char = "-") {
120
- const charCase = pascalCase.replace(
121
- /([A-Z]+)/g,
122
- (m, g1, index) => (index > 0 ? char : "") + m
123
- ).toLowerCase();
120
+ const charCase = pascalCase.replace(/([A-Z]+)/g, (m, g1, index) => (index > 0 ? char : "") + m).toLowerCase();
124
121
  return charCase;
125
122
  }
126
123
  function pascalCaseToKebabCase(pascalCase) {
@@ -556,9 +553,12 @@ function stringToBase64(text) {
556
553
  }
557
554
 
558
555
  // src/category/category.ts
559
- var ROOT_CATEGORY = process.env.ROOT_CATEGORY || "";
556
+ function getRootCategoryId() {
557
+ return (typeof process !== "undefined" ? process.env?.ROOT_CATEGORY : void 0) || "";
558
+ }
560
559
  function getRootCategory(categories) {
561
- const rootCategory = ROOT_CATEGORY && categories.find((x) => x.id == ROOT_CATEGORY);
560
+ const rootCategoryId = getRootCategoryId();
561
+ const rootCategory = rootCategoryId && categories.find((x) => x.id == rootCategoryId);
562
562
  if (rootCategory) {
563
563
  return rootCategory;
564
564
  } else {
@@ -756,9 +756,11 @@ async function httpFetch(url, options = {}, serviceOptions) {
756
756
  return response;
757
757
  } catch (error) {
758
758
  if (typeof error === "object" && error.status) {
759
- console.log("httpFetch.error", options.method, url, error.status, error.statusText);
759
+ if (error.status >= 500 || isDevelopment) {
760
+ console.warn("httpFetch.error", options.method, url, error.status, error.statusText);
761
+ }
760
762
  } else {
761
- console.log("httpFetch.error", options.method, url, error);
763
+ console.warn("httpFetch.error", options.method, url, error);
762
764
  }
763
765
  throw error;
764
766
  }
@@ -1286,7 +1288,10 @@ function isLocalizedString(value) {
1286
1288
  let isLocalizedString2 = false;
1287
1289
  if (value && !Array.isArray(value) && typeof value === "object") {
1288
1290
  const matchKeys = Object.keys(value).reduce((p, c) => p && /^(\w{2})(-\w{2})?$/.test(c), true);
1289
- const matchValues = Object.values(value).reduce((p, c) => p && (typeof c === "string" || !c), true);
1291
+ const matchValues = Object.values(value).reduce(
1292
+ (p, c) => p && (typeof c === "string" || !c),
1293
+ true
1294
+ );
1290
1295
  isLocalizedString2 = Boolean(matchKeys && matchValues);
1291
1296
  }
1292
1297
  return isLocalizedString2;
@@ -1374,6 +1379,11 @@ function getDefaultMarket() {
1374
1379
  }
1375
1380
  var defaultMarket = getDefaultMarket();
1376
1381
 
1382
+ // src/meta/meta.ts
1383
+ function getMetaRobots(meta) {
1384
+ return meta?.robots || meta?.robot || void 0;
1385
+ }
1386
+
1377
1387
  // src/password/password.ts
1378
1388
  function getPasswordStrategy() {
1379
1389
  const passwordStrategy2 = typeof process !== "undefined" && process.env.NEXT_PUBLIC_PASSWORD_STRATEGY ? process.env.NEXT_PUBLIC_PASSWORD_STRATEGY : "^(?=.*[0-9])(?=.*[A-Z])(?=.*[a-z])[a-zA-Z0-9._\\-\\W]{8,}$";
@@ -1549,9 +1559,15 @@ function collectRoutes(store, categories, markets, locales, medias) {
1549
1559
  const rootCategory = getRootCategory(categories);
1550
1560
  const activeLocales = locales.filter((locale) => locale.isActive !== false);
1551
1561
  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]));
1562
+ const categoryById = new Map(
1563
+ categories.filter((category) => typeof category.id === "string").map((category) => [category.id, category])
1564
+ );
1565
+ const localeById = new Map(
1566
+ activeLocales.filter((locale) => typeof locale.id === "string").map((locale) => [locale.id, locale])
1567
+ );
1568
+ const mediaById = new Map(
1569
+ (medias || []).filter((media) => typeof media.id === "string").map((media) => [media.id, media])
1570
+ );
1555
1571
  const marketLocales = activeMarkets.flatMap((market) => {
1556
1572
  const localesForMarket = market.languages && market.languages.length > 0 ? market.languages.map((language) => localeById.get(String(asEntityId(language)))).filter((locale) => locale !== void 0) : activeLocales;
1557
1573
  return localesForMarket.map((locale) => ({ market, locale }));
@@ -1578,7 +1594,9 @@ function collectRoutes(store, categories, markets, locales, medias) {
1578
1594
  };
1579
1595
  eachCategorized(store, (item, key) => {
1580
1596
  const segments = getSegments(item);
1581
- const visibleSegments = segments.filter((x) => x.id !== rootCategory?.id && Boolean(x.isHidden) === false);
1597
+ const visibleSegments = segments.filter(
1598
+ (x) => x.id !== rootCategory?.id && Boolean(x.isHidden) === false
1599
+ );
1582
1600
  const visibleCategory = visibleSegments.length > 0 ? visibleSegments[visibleSegments.length - 1] : rootCategory;
1583
1601
  if (visibleCategory) {
1584
1602
  const slugs = visibleSegments.map((x) => ({ slug: x.slug }));
@@ -1628,7 +1646,7 @@ function collectRoutes(store, categories, markets, locales, medias) {
1628
1646
  if (isRootCategory) {
1629
1647
  route.isRoot = true;
1630
1648
  }
1631
- const noindex = (item.meta?.robots || "").includes("noindex");
1649
+ const noindex = (getMetaRobots(item.meta) || "").includes("noindex");
1632
1650
  if (noindex) {
1633
1651
  route.noindex = true;
1634
1652
  }
@@ -1657,7 +1675,9 @@ function collectRoutes(store, categories, markets, locales, medias) {
1657
1675
  for (const route of routes) {
1658
1676
  const targetPage = redirects.get(route.page);
1659
1677
  if (targetPage != null) {
1660
- const target = routeByPageContext.get(JSON.stringify([targetPage, route.market, route.locale]));
1678
+ const target = routeByPageContext.get(
1679
+ JSON.stringify([targetPage, route.market, route.locale])
1680
+ );
1661
1681
  if (target) {
1662
1682
  route.publicRedirect = target.id;
1663
1683
  }
@@ -1795,6 +1815,7 @@ export {
1795
1815
  getHost,
1796
1816
  getIsDevelopment,
1797
1817
  getIsProduction,
1818
+ getMetaRobots,
1798
1819
  getOrigin,
1799
1820
  getParentCategoriesById,
1800
1821
  getParentCategory,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@websolutespa/bom-core",
3
- "version": "4.0.0-next.0",
3
+ "version": "4.0.0-next.6",
4
4
  "description": "Core module of the BOM Repository",
5
5
  "keywords": [
6
6
  "bom",
@@ -12,34 +12,26 @@
12
12
  "type": "git",
13
13
  "url": "git://github.com/websolutespa/bom.git"
14
14
  },
15
- "scripts": {
16
- "lint": "eslint *.ts*",
17
- "test": "vitest run",
18
- "test-watch": "vitest",
19
- "coverage:integration": "npm run test -- --coverage.enabled --coverage.provider=istanbul --coverage.all",
20
- "coverage": "run-s -c --silent coverage:*",
21
- "compile": "tsup ./src/index.ts --format esm --dts --external react",
22
- "prepack": "bom prepack",
23
- "postpack": "bom postpack",
24
- "types": "tsc --noemit"
25
- },
26
15
  "dependencies": {
27
16
  "pluralize": "8.0.0"
28
17
  },
29
18
  "peerDependencies": {},
30
19
  "devDependencies": {
20
+ "@types/node": "24.19.2",
31
21
  "@types/pluralize": "0.0.33",
32
- "@types/react": "19.2.10",
33
- "@websolutespa/eslint-config": "^3.0.0",
34
- "@websolutespa/test": "^4.0.0-next.0",
35
- "@websolutespa/tsconfig": "^3.0.0",
36
- "eslint": "9.31.0",
22
+ "@types/react": "19.2.18",
23
+ "@vitest/coverage-istanbul": "5.0.5",
24
+ "@websolutespa/eslint-config": "^4.0.0-next.6",
25
+ "@websolutespa/test": "^4.0.0-next.6",
26
+ "@websolutespa/tsconfig": "^4.0.0-next.6",
37
27
  "npm-run-all": "4.1.5",
28
+ "oxlint": "1.89.0",
29
+ "oxlint-tsgolint": "7.0.2005",
38
30
  "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"
31
+ "react": "19.2.9",
32
+ "tsup": "9.0.0",
33
+ "typescript": "6.0.3",
34
+ "vitest": "5.0.5"
43
35
  },
44
36
  "publishConfig": {
45
37
  "access": "public"
@@ -57,5 +49,14 @@
57
49
  },
58
50
  "types": "./dist/index.d.ts",
59
51
  "main": "./dist/index.js",
60
- "module": "./dist/index.js"
52
+ "module": "./dist/index.js",
53
+ "scripts": {
54
+ "lint": "oxlint --type-aware",
55
+ "test": "vitest run",
56
+ "test-watch": "vitest",
57
+ "coverage:integration": "vitest run --coverage.enabled --coverage.provider=istanbul --coverage.all",
58
+ "coverage": "run-s -c --silent coverage:*",
59
+ "compile": "tsup ./src/index.ts --format esm --dts --external react",
60
+ "types": "tsc --noemit"
61
+ }
61
62
  }