@websolutespa/bom-core 0.6.3 → 0.6.5

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,88 +1,102 @@
1
- # @websolutespa/bom-core
2
-
3
- ## 0.6.3
4
-
5
- ### Patch Changes
6
-
7
- - Added: isReservedCollectionDescription
8
-
9
- ## 0.6.2
10
-
11
- ### Patch Changes
12
-
13
- - Modified: IMedia.
14
-
15
- ## 0.6.1
16
-
17
- ### Patch Changes
18
-
19
- - Added: defaultMarket, defaultLocale
20
-
21
- ## 0.6.0
22
-
23
- ### Minor Changes
24
-
25
- - Added Logger, IPaginationResult.
26
-
27
- ## 0.5.0
28
-
29
- ### Minor Changes
30
-
31
- - Modified: JsonService, qs.
32
- - Added: asEquatable, cloneItem, typeGuards.
33
-
34
- ## 0.4.1
35
-
36
- ### Patch Changes
37
-
38
- - Added: IAnchor, babelCase.
39
- - Modified: IApplication, IPageRelation.
40
-
41
- ## 0.4.0
42
-
43
- ### Minor Changes
44
-
45
- - Updating: next 13.
46
-
47
- ## 0.3.0
48
-
49
- ### Minor Changes
50
-
51
- - Modified: HttpService.
52
-
53
- ## 0.2.1
54
-
55
- ### Patch Changes
56
-
57
- - Added: env ROOT_CATEGORY.
58
-
59
- ## 0.2.0
60
-
61
- ### Minor Changes
62
-
63
- - Modified routes, added redirects.
64
-
65
- ## 0.1.2
66
-
67
- ### Patch Changes
68
-
69
- - Modified: MockMenuService.
70
-
71
- ## 0.1.1
72
-
73
- ### Patch Changes
74
-
75
- - Modified: ILocalizable.
76
-
77
- ## 0.1.0
78
-
79
- ### Minor Changes
80
-
81
- - Added: splat routes.
82
- - Added: variants.
83
-
84
- ## 0.0.1
85
-
86
- ### Patch Changes
87
-
88
- - Added: first release.
1
+ # @websolutespa/bom-core
2
+
3
+ ## 0.6.5
4
+
5
+ ### Patch Changes
6
+
7
+ - Added: collectFeatureTypes, collectOptions
8
+ - Modified: Category, collectRoutes, getRouteHref, entity
9
+
10
+ ## 0.6.4
11
+
12
+ ### Patch Changes
13
+
14
+ - Added: typeGuards, IPagedResult
15
+ - Modified: IUndecoratedMenuCustom
16
+
17
+ ## 0.6.3
18
+
19
+ ### Patch Changes
20
+
21
+ - Added: isReservedCollectionDescription
22
+
23
+ ## 0.6.2
24
+
25
+ ### Patch Changes
26
+
27
+ - Modified: IMedia
28
+
29
+ ## 0.6.1
30
+
31
+ ### Patch Changes
32
+
33
+ - Added: defaultMarket, defaultLocale
34
+
35
+ ## 0.6.0
36
+
37
+ ### Minor Changes
38
+
39
+ - Added Logger, IPaginationResult
40
+
41
+ ## 0.5.0
42
+
43
+ ### Minor Changes
44
+
45
+ - Modified: JsonService, qs
46
+ - Added: asEquatable, cloneItem, typeGuards
47
+
48
+ ## 0.4.1
49
+
50
+ ### Patch Changes
51
+
52
+ - Added: IAnchor, babelCase
53
+ - Modified: IApplication, IPageRelation
54
+
55
+ ## 0.4.0
56
+
57
+ ### Minor Changes
58
+
59
+ - Updating: next 13
60
+
61
+ ## 0.3.0
62
+
63
+ ### Minor Changes
64
+
65
+ - Modified: HttpService
66
+
67
+ ## 0.2.1
68
+
69
+ ### Patch Changes
70
+
71
+ - Added: env ROOT_CATEGORY
72
+
73
+ ## 0.2.0
74
+
75
+ ### Minor Changes
76
+
77
+ - Modified routes, added redirects
78
+
79
+ ## 0.1.2
80
+
81
+ ### Patch Changes
82
+
83
+ - Modified: MockMenuService
84
+
85
+ ## 0.1.1
86
+
87
+ ### Patch Changes
88
+
89
+ - Modified: ILocalizable
90
+
91
+ ## 0.1.0
92
+
93
+ ### Minor Changes
94
+
95
+ - Added: splat routes
96
+ - Added: variants
97
+
98
+ ## 0.0.1
99
+
100
+ ### Patch Changes
101
+
102
+ - Added: first release
package/dist/index.d.ts CHANGED
@@ -66,21 +66,32 @@ type IAnchor = {
66
66
 
67
67
  type IEquatable = number | string;
68
68
  type SchemaType = string;
69
- type IOption = Record<string, any> & {
70
- id: IEquatable;
71
- name: string;
72
- };
73
69
  type ISchema = {
74
70
  id: IEquatable;
75
71
  schema?: string;
76
72
  };
77
- type IEntity = Record<string, unknown> & ISchema;
73
+ type IEntity = ISchema & Record<string, unknown>;
78
74
  type INamedEntity = IEntity & {
79
75
  name: ILocalizable;
80
76
  };
81
77
  type ITitledEntity = IEntity & {
82
78
  title: ILocalizable;
83
79
  };
80
+ type IOption = Record<string, any> & {
81
+ id: IEquatable;
82
+ name: string;
83
+ };
84
+ type IFeature = Record<string, any> & {
85
+ id: IEquatable;
86
+ title: string;
87
+ };
88
+ type IFeatureType = {
89
+ id: string;
90
+ schema?: string;
91
+ title: string;
92
+ mode: string;
93
+ features?: IFeature[];
94
+ };
84
95
 
85
96
  type IMediaType = 'image' | 'video' | string;
86
97
  type IMedia = {
@@ -324,13 +335,12 @@ type IUndecoratedMenuPage = Omit<IUndecoratedMenuBase, 'type'> & {
324
335
  page: IPageRelation;
325
336
  title?: ILocalizable;
326
337
  };
327
- type IUndecoratedMenuCustom = Record<string, unknown> & {
328
- id: IEquatable;
338
+ type IUndecoratedMenuCustom = Omit<IUndecoratedMenuBase, 'type'> & {
329
339
  type: 'custom';
330
340
  blockType: string;
331
341
  };
332
342
  type IUndecoratedMenuItem = IUndecoratedMenuCategory | IUndecoratedMenuGroup | IUndecoratedMenuLink | IUndecoratedMenuPage | IUndecoratedMenuCustom;
333
- type IUndecoratedMenu = {
343
+ type IUndecoratedMenu = IEntity & {
334
344
  id: string;
335
345
  items: IUndecoratedMenuItem[];
336
346
  };
@@ -394,12 +404,13 @@ type QueryParams = {
394
404
  richText?: boolean;
395
405
  };
396
406
 
407
+ type IPagedResult<T extends IEntity = IEntity> = {
408
+ docs: T[];
409
+ } & Pagination;
397
410
  type IQuerable<T extends IEntity = IEntity> = {
398
411
  findOne<B extends T = T>(id: IEquatable, params?: QueryParams): Promise<B | undefined>;
399
412
  findMany<B extends T = T>(params?: QueryParams): Promise<B[]>;
400
- findPaged<B extends T = T>(params?: QueryParams): Promise<{
401
- docs: B[];
402
- } & Pagination>;
413
+ findPaged<B extends T = T>(params?: QueryParams): Promise<IPagedResult<B>>;
403
414
  create<B extends T = T>(payload: Omit<B, 'id'>): Promise<B>;
404
415
  update<B extends T = T>(payload: Partial<B>): Promise<B>;
405
416
  delete<B extends T = T>(id: IEquatable): Promise<B | undefined>;
@@ -468,9 +479,9 @@ type ITemplate = {
468
479
  };
469
480
 
470
481
  declare function isCategory(value?: ICategory | IEquatable): value is ICategory;
471
- declare function asCategoryId(value?: ICategory | IEquatable): string | undefined;
482
+ declare function asCategoryId(value: ICategory | IEquatable): string;
472
483
  declare function getRootCategory(categories: ICategory[]): ICategory | undefined;
473
- declare function getParentCategoriesById(id: string | undefined, categories: ICategory[]): ICategory[];
484
+ declare function getParentCategoriesById(id: string, categories: ICategory[]): ICategory[];
474
485
  declare function getCategorySegments(item: ICategorized, categories: ICategory[]): ICategory[];
475
486
  declare function getCategorySegmentsByCategory(item: ICategory, categories: ICategory[]): ICategory[];
476
487
 
@@ -500,9 +511,7 @@ declare class JsonService<T extends IEntity = IEntity> implements IQuerable<T> {
500
511
  getItems<B extends T = T>(): Promise<B[]>;
501
512
  findOne<B extends T = T>(id: IEquatable, params?: QueryParams): Promise<B | undefined>;
502
513
  findMany<B extends T = T>(params?: QueryParams): Promise<B[]>;
503
- findPaged<B extends T = T>(params?: QueryParams): Promise<{
504
- docs: B[];
505
- } & Pagination>;
514
+ findPaged<B extends T = T>(params?: QueryParams): Promise<IPagedResult<B>>;
506
515
  create<B extends T = T>(payload: Omit<B, 'id'>): Promise<B>;
507
516
  update<B extends T = T>(payload: Partial<B>): Promise<B>;
508
517
  delete<B extends T = T>(id: IEquatable): Promise<B | undefined>;
@@ -564,7 +573,9 @@ declare enum RouteStrategy {
564
573
  Default = "default",
565
574
  Manual = "manual"
566
575
  }
567
- declare function getRouteHref(segments: ICategory[], market: IMarket, locale: ILocale, markets: IMarket[], locales: ILocale[]): string;
576
+ declare function getRouteHref(segments: {
577
+ slug: ILocalizable;
578
+ }[], market: IMarket, locale: ILocale, markets: IMarket[], locales: ILocale[]): string;
568
579
 
569
580
  declare function textToSlug(title: string): string;
570
581
 
@@ -590,6 +601,10 @@ declare function toSnakeCase(unknownCase: string): string;
590
601
 
591
602
  declare function cloneItem<T = unknown>(item: T): T;
592
603
 
604
+ declare function collectFeatureTypes<T extends IEntity = IEntity>(items: T[], ...keys: string[]): Promise<IFeatureType[]>;
605
+
606
+ declare function collectOptions<T extends IEntity = IEntity>(items: T[], ...keys: string[]): Promise<Partial<Record<keyof T, IOption[]>>>;
607
+
593
608
  type ListItem<T> = {
594
609
  [K in keyof T]: {
595
610
  readonly key: string;
@@ -612,6 +627,7 @@ declare function isUnresolvedRelation(item: unknown): item is IPageUnresolvedRel
612
627
  declare function isRelation(item: unknown): item is IPageRelation;
613
628
  declare function isUndecoratedMenuItem(item: unknown): item is IUndecoratedMenuItem;
614
629
  declare function isUndecoratedNav<T>(item: unknown): item is IUndecoratedNav<T>;
630
+ declare function isUndecoratedMenuCategory(item: unknown): item is IUndecoratedMenuCategory;
615
631
  declare function isUndecoratedMenuPage(item: unknown): item is IUndecoratedMenuPage;
616
632
 
617
633
  declare function getIsDevelopment(): boolean;
@@ -626,4 +642,4 @@ declare function asServerProps(props: any): any;
626
642
  declare function awaitAll(array: any, callback: (item: any, index: number) => Promise<any>): Promise<any[]>;
627
643
  declare function merge(target: any, source: any): any;
628
644
 
629
- export { FetchError, FetchRequestOptions, FetchService, FindParams, FindWhereParams, IAnchor, ICategorized, ICategory, ICategoryItem, IClassName, IClassNameCollection, IClassNameValue, ICollectionDescription, IConfig, IContextBaseParams, IContextParams, IDecoratedNav, IEntity, IEquatable, ILabel, ILayout, ILocale, ILocalizable, ILocalized, ILocalizedString, IMarket, IMedia, IMediaType, IMemoryStore, IMenu, IMenuBase, IMenuCategory, IMenuCustom, IMenuGroup, IMenuItem, IMenuLink, IMenuPage, IMenuRoute, INamedEntity, IOption, IOverride, IPackages, IPage, IPageRelation, IPageRelationResult, IPageResult, IPageUnresolvedRelation, IPaginationResult, IPartial, 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, JsonService, LiteralUnion, Logger, LoggerLevel, NextApiRequestCookies, Operator, PageProps, Pagination, PreviewData, QueryParams, RedirectReason, RouteStrategy, SchemaType, ServerSidePropsContext, StateValue, StaticPropsContext, ValueOf, Where, WhereAndOr, WhereBase, WhereField, asCategoryId, asEquatable, asServerProps, awaitAll, camelToSnakeCase, cloneItem, collectRoutes, consoleWarn, defaultLocale, defaultMarket, eachCategorized, eachMarketLocale, enumToList, getCategorySegments, getCategorySegmentsByCategory, getClassNames, getCollectionDescription, getEnv, getIsDevelopment, getIsProduction, getParentCategoriesById, getRootCategory, getRouteHref, httpDelete, httpFetch, httpGet, httpPatch, httpPost, httpPut, isArray, isBrowser, isCategory, isDevelopment, isEntity, isEquatable, isLocalizedString, isNotNullString, isObject, isProduction, isRelation, isReservedCollectionDescription, isStage, isUndecoratedMenuItem, isUndecoratedMenuPage, isUndecoratedNav, isUnresolvedRelation, isValidCollectionDescription, localize, localizeItem, localizeValue, localizedToString, merge, pascalCaseToCamelCase, pascalCaseToCharCase, pascalCaseToKebabCase, pascalCaseToSnakeCase, qsDeserialize, qsDeserializeRaw, qsSerialize, qsSerializeRaw, resolveMediaType, textToSlug, toCamelCase, toCharCase, toDisplayName, toFindParams, toKebabCase, toPascalCase, toPluralName, toSnakeCase, toTitleCase, toValidCollectionName, unknownCaseToPascalCase, withSchema };
645
+ export { FetchError, FetchRequestOptions, FetchService, FindParams, FindWhereParams, IAnchor, ICategorized, ICategory, ICategoryItem, IClassName, IClassNameCollection, IClassNameValue, ICollectionDescription, IConfig, IContextBaseParams, IContextParams, IDecoratedNav, IEntity, IEquatable, IFeature, IFeatureType, ILabel, ILayout, ILocale, ILocalizable, ILocalized, ILocalizedString, IMarket, IMedia, IMediaType, IMemoryStore, IMenu, IMenuBase, IMenuCategory, IMenuCustom, IMenuGroup, IMenuItem, IMenuLink, IMenuPage, IMenuRoute, INamedEntity, IOption, IOverride, IPackages, IPage, IPageRelation, IPageRelationResult, IPageResult, IPageUnresolvedRelation, IPagedResult, IPaginationResult, IPartial, 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, JsonService, LiteralUnion, Logger, LoggerLevel, NextApiRequestCookies, Operator, PageProps, Pagination, PreviewData, QueryParams, RedirectReason, RouteStrategy, SchemaType, ServerSidePropsContext, StateValue, StaticPropsContext, ValueOf, Where, WhereAndOr, WhereBase, WhereField, asCategoryId, asEquatable, asServerProps, awaitAll, camelToSnakeCase, cloneItem, collectFeatureTypes, collectOptions, collectRoutes, consoleWarn, defaultLocale, defaultMarket, eachCategorized, eachMarketLocale, enumToList, getCategorySegments, getCategorySegmentsByCategory, getClassNames, getCollectionDescription, getEnv, getIsDevelopment, getIsProduction, getParentCategoriesById, getRootCategory, getRouteHref, httpDelete, httpFetch, httpGet, httpPatch, httpPost, httpPut, isArray, isBrowser, isCategory, isDevelopment, isEntity, isEquatable, isLocalizedString, isNotNullString, isObject, isProduction, isRelation, isReservedCollectionDescription, isStage, isUndecoratedMenuCategory, isUndecoratedMenuItem, isUndecoratedMenuPage, isUndecoratedNav, isUnresolvedRelation, isValidCollectionDescription, localize, localizeItem, localizeValue, localizedToString, merge, pascalCaseToCamelCase, pascalCaseToCharCase, pascalCaseToKebabCase, pascalCaseToSnakeCase, qsDeserialize, qsDeserializeRaw, qsSerialize, qsSerializeRaw, resolveMediaType, textToSlug, toCamelCase, toCharCase, toDisplayName, toFindParams, toKebabCase, toPascalCase, toPluralName, toSnakeCase, toTitleCase, toValidCollectionName, unknownCaseToPascalCase, withSchema };
package/dist/index.js CHANGED
@@ -41,6 +41,8 @@ __export(src_exports, {
41
41
  awaitAll: () => awaitAll,
42
42
  camelToSnakeCase: () => camelToSnakeCase,
43
43
  cloneItem: () => cloneItem,
44
+ collectFeatureTypes: () => collectFeatureTypes,
45
+ collectOptions: () => collectOptions,
44
46
  collectRoutes: () => collectRoutes,
45
47
  consoleWarn: () => consoleWarn,
46
48
  defaultLocale: () => defaultLocale,
@@ -77,6 +79,7 @@ __export(src_exports, {
77
79
  isRelation: () => isRelation,
78
80
  isReservedCollectionDescription: () => isReservedCollectionDescription,
79
81
  isStage: () => isStage,
82
+ isUndecoratedMenuCategory: () => isUndecoratedMenuCategory,
80
83
  isUndecoratedMenuItem: () => isUndecoratedMenuItem,
81
84
  isUndecoratedMenuPage: () => isUndecoratedMenuPage,
82
85
  isUndecoratedNav: () => isUndecoratedNav,
@@ -140,7 +143,7 @@ function getParentCategoriesById(id, categories) {
140
143
  const segment = { ...parentCategory };
141
144
  segments.unshift(segment);
142
145
  }
143
- parentId = asCategoryId(parentCategory.category) || null;
146
+ parentId = parentCategory.category ? asCategoryId(parentCategory.category) : null;
144
147
  if (parentId) {
145
148
  if (routeCategories.includes(parentId)) {
146
149
  console.log("ICategory.getParentCategoriesById", "circular reference found", parentId);
@@ -158,24 +161,11 @@ function getParentCategoriesById(id, categories) {
158
161
  function getCategorySegments(item, categories) {
159
162
  const categoryId = asCategoryId(item.category);
160
163
  const segments = getParentCategoriesById(categoryId, categories);
161
- if (item.isDefault !== true) {
162
- const category = categories.find((x) => x.id === item.category);
163
- if (category) {
164
- const segment = {
165
- id: item.id,
166
- title: item.title,
167
- slug: item.slug,
168
- media: item.media || category.media,
169
- category
170
- };
171
- segments.push(segment);
172
- }
173
- }
174
164
  return segments;
175
165
  }
176
166
  function getCategorySegmentsByCategory(item, categories) {
177
- const categoryId = asCategoryId(item.category);
178
- const segments = getParentCategoriesById(categoryId, categories);
167
+ const categoryId = item.category ? asCategoryId(item.category) : null;
168
+ const segments = categoryId ? getParentCategoriesById(categoryId, categories) : [];
179
169
  segments.push(item);
180
170
  return segments;
181
171
  }
@@ -376,8 +366,11 @@ function isUndecoratedMenuItem(item) {
376
366
  function isUndecoratedNav(item) {
377
367
  return isObject(item) && isUndecoratedMenuPage(item.nav);
378
368
  }
369
+ function isUndecoratedMenuCategory(item) {
370
+ return isObject(item) && item.type === "category" && isNotNullString(item.category) && item.id === void 0 && item.href === void 0;
371
+ }
379
372
  function isUndecoratedMenuPage(item) {
380
- return isObject(item) && item.type === "page" && isNotNullString(item.page.relationTo) && isEquatable(item.page.value);
373
+ return isObject(item) && item.type === "page" && isObject(item.page) && isNotNullString(item.page.relationTo) && isEquatable(item.page.value);
381
374
  }
382
375
 
383
376
  // src/utils/cloneItem.ts
@@ -394,6 +387,65 @@ function cloneItem(item) {
394
387
  return item;
395
388
  }
396
389
 
390
+ // src/utils/collectFeatureTypes.ts
391
+ async function collectFeatureTypes(items, ...keys) {
392
+ const featureTypes = [];
393
+ if (keys.length > 0) {
394
+ items.forEach((item) => {
395
+ keys.forEach((key) => {
396
+ const value = item[key];
397
+ if (value) {
398
+ let featureType = featureTypes.find((x) => x.id === key);
399
+ if (!featureType) {
400
+ featureType = {
401
+ id: key,
402
+ schema: "featureType",
403
+ title: key,
404
+ mode: "or",
405
+ features: []
406
+ };
407
+ featureTypes.push(featureType);
408
+ }
409
+ const features = featureType.features;
410
+ if (features && !features.find((x) => x.id === value)) {
411
+ features.push({
412
+ id: value,
413
+ title: String(value)
414
+ });
415
+ }
416
+ }
417
+ });
418
+ });
419
+ }
420
+ return featureTypes;
421
+ }
422
+
423
+ // src/utils/collectOptions.ts
424
+ async function collectOptions(items, ...keys) {
425
+ const optionsGroup = {};
426
+ if (keys.length > 0) {
427
+ items.forEach((item) => {
428
+ keys.forEach((key) => {
429
+ const value = item[key];
430
+ if (value) {
431
+ let options = optionsGroup[key];
432
+ if (!options) {
433
+ options = [];
434
+ optionsGroup[key] = options;
435
+ }
436
+ if (!options.find((x) => x.id === value)) {
437
+ options.push({
438
+ id: value,
439
+ name: String(value)
440
+ });
441
+ }
442
+ }
443
+ });
444
+ });
445
+ }
446
+ return optionsGroup;
447
+ }
448
+
397
449
  // src/utils/enumToList.ts
398
450
  function enumToList(enumeration, separatorRegex = /_/g) {
399
451
  const array = Object.keys(enumeration);
@@ -956,7 +1008,7 @@ function collectRoutes(store, categories, markets, locales) {
956
1008
  eachMarketLocale(markets, locales, (market, locale, markets2, locales2) => {
957
1009
  if (!item.markets || item.markets.includes(market.id)) {
958
1010
  const title = localize(item.title, locale.id);
959
- const id = getRouteHref(segments, market, locale, markets2, locales2);
1011
+ const id = getRouteHref([...segments, { slug: item.slug }], market, locale, markets2, locales2);
960
1012
  const route = {
961
1013
  category: item.category,
962
1014
  id,
@@ -1104,6 +1156,8 @@ var RedirectReason = /* @__PURE__ */ ((RedirectReason2) => {
1104
1156
  awaitAll,
1105
1157
  camelToSnakeCase,
1106
1158
  cloneItem,
1159
+ collectFeatureTypes,
1160
+ collectOptions,
1107
1161
  collectRoutes,
1108
1162
  consoleWarn,
1109
1163
  defaultLocale,
@@ -1140,6 +1194,7 @@ var RedirectReason = /* @__PURE__ */ ((RedirectReason2) => {
1140
1194
  isRelation,
1141
1195
  isReservedCollectionDescription,
1142
1196
  isStage,
1197
+ isUndecoratedMenuCategory,
1143
1198
  isUndecoratedMenuItem,
1144
1199
  isUndecoratedMenuPage,
1145
1200
  isUndecoratedNav,
package/dist/index.mjs CHANGED
@@ -26,7 +26,7 @@ function getParentCategoriesById(id, categories) {
26
26
  const segment = { ...parentCategory };
27
27
  segments.unshift(segment);
28
28
  }
29
- parentId = asCategoryId(parentCategory.category) || null;
29
+ parentId = parentCategory.category ? asCategoryId(parentCategory.category) : null;
30
30
  if (parentId) {
31
31
  if (routeCategories.includes(parentId)) {
32
32
  console.log("ICategory.getParentCategoriesById", "circular reference found", parentId);
@@ -44,24 +44,11 @@ function getParentCategoriesById(id, categories) {
44
44
  function getCategorySegments(item, categories) {
45
45
  const categoryId = asCategoryId(item.category);
46
46
  const segments = getParentCategoriesById(categoryId, categories);
47
- if (item.isDefault !== true) {
48
- const category = categories.find((x) => x.id === item.category);
49
- if (category) {
50
- const segment = {
51
- id: item.id,
52
- title: item.title,
53
- slug: item.slug,
54
- media: item.media || category.media,
55
- category
56
- };
57
- segments.push(segment);
58
- }
59
- }
60
47
  return segments;
61
48
  }
62
49
  function getCategorySegmentsByCategory(item, categories) {
63
- const categoryId = asCategoryId(item.category);
64
- const segments = getParentCategoriesById(categoryId, categories);
50
+ const categoryId = item.category ? asCategoryId(item.category) : null;
51
+ const segments = categoryId ? getParentCategoriesById(categoryId, categories) : [];
65
52
  segments.push(item);
66
53
  return segments;
67
54
  }
@@ -262,8 +249,11 @@ function isUndecoratedMenuItem(item) {
262
249
  function isUndecoratedNav(item) {
263
250
  return isObject(item) && isUndecoratedMenuPage(item.nav);
264
251
  }
252
+ function isUndecoratedMenuCategory(item) {
253
+ return isObject(item) && item.type === "category" && isNotNullString(item.category) && item.id === void 0 && item.href === void 0;
254
+ }
265
255
  function isUndecoratedMenuPage(item) {
266
- return isObject(item) && item.type === "page" && isNotNullString(item.page.relationTo) && isEquatable(item.page.value);
256
+ return isObject(item) && item.type === "page" && isObject(item.page) && isNotNullString(item.page.relationTo) && isEquatable(item.page.value);
267
257
  }
268
258
 
269
259
  // src/utils/cloneItem.ts
@@ -280,6 +270,65 @@ function cloneItem(item) {
280
270
  return item;
281
271
  }
282
272
 
273
+ // src/utils/collectFeatureTypes.ts
274
+ async function collectFeatureTypes(items, ...keys) {
275
+ const featureTypes = [];
276
+ if (keys.length > 0) {
277
+ items.forEach((item) => {
278
+ keys.forEach((key) => {
279
+ const value = item[key];
280
+ if (value) {
281
+ let featureType = featureTypes.find((x) => x.id === key);
282
+ if (!featureType) {
283
+ featureType = {
284
+ id: key,
285
+ schema: "featureType",
286
+ title: key,
287
+ mode: "or",
288
+ features: []
289
+ };
290
+ featureTypes.push(featureType);
291
+ }
292
+ const features = featureType.features;
293
+ if (features && !features.find((x) => x.id === value)) {
294
+ features.push({
295
+ id: value,
296
+ title: String(value)
297
+ });
298
+ }
299
+ }
300
+ });
301
+ });
302
+ }
303
+ return featureTypes;
304
+ }
305
+
306
+ // src/utils/collectOptions.ts
307
+ async function collectOptions(items, ...keys) {
308
+ const optionsGroup = {};
309
+ if (keys.length > 0) {
310
+ items.forEach((item) => {
311
+ keys.forEach((key) => {
312
+ const value = item[key];
313
+ if (value) {
314
+ let options = optionsGroup[key];
315
+ if (!options) {
316
+ options = [];
317
+ optionsGroup[key] = options;
318
+ }
319
+ if (!options.find((x) => x.id === value)) {
320
+ options.push({
321
+ id: value,
322
+ name: String(value)
323
+ });
324
+ }
325
+ }
326
+ });
327
+ });
328
+ }
329
+ return optionsGroup;
330
+ }
331
+
283
332
  // src/utils/enumToList.ts
284
333
  function enumToList(enumeration, separatorRegex = /_/g) {
285
334
  const array = Object.keys(enumeration);
@@ -842,7 +891,7 @@ function collectRoutes(store, categories, markets, locales) {
842
891
  eachMarketLocale(markets, locales, (market, locale, markets2, locales2) => {
843
892
  if (!item.markets || item.markets.includes(market.id)) {
844
893
  const title = localize(item.title, locale.id);
845
- const id = getRouteHref(segments, market, locale, markets2, locales2);
894
+ const id = getRouteHref([...segments, { slug: item.slug }], market, locale, markets2, locales2);
846
895
  const route = {
847
896
  category: item.category,
848
897
  id,
@@ -989,6 +1038,8 @@ export {
989
1038
  awaitAll,
990
1039
  camelToSnakeCase,
991
1040
  cloneItem,
1041
+ collectFeatureTypes,
1042
+ collectOptions,
992
1043
  collectRoutes,
993
1044
  consoleWarn,
994
1045
  defaultLocale,
@@ -1025,6 +1076,7 @@ export {
1025
1076
  isRelation,
1026
1077
  isReservedCollectionDescription,
1027
1078
  isStage,
1079
+ isUndecoratedMenuCategory,
1028
1080
  isUndecoratedMenuItem,
1029
1081
  isUndecoratedMenuPage,
1030
1082
  isUndecoratedNav,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@websolutespa/bom-core",
3
- "version": "0.6.3",
3
+ "version": "0.6.5",
4
4
  "description": "Core module of the BOM Repository",
5
5
  "keywords": [
6
6
  "bom",