@websolutespa/bom-core 1.7.10 → 1.7.12

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/index.js CHANGED
@@ -37,6 +37,8 @@ __export(src_exports, {
37
37
  RouteStrategy: () => RouteStrategy,
38
38
  asCategoryId: () => asCategoryId,
39
39
  asEquatable: () => asEquatable,
40
+ asEquatableNumber: () => asEquatableNumber,
41
+ asEquatableString: () => asEquatableString,
40
42
  asServerProps: () => asServerProps,
41
43
  asSortedOptions: () => asSortedOptions,
42
44
  awaitAll: () => awaitAll,
@@ -52,6 +54,10 @@ __export(src_exports, {
52
54
  eachCategorized: () => eachCategorized,
53
55
  eachMarketLocale: () => eachMarketLocale,
54
56
  enumToList: () => enumToList,
57
+ findCategoryInCategories: () => findCategoryInCategories,
58
+ findChildCategories: () => findChildCategories,
59
+ findRouteOfCategory: () => findRouteOfCategory,
60
+ findRoutesOfCategory: () => findRoutesOfCategory,
55
61
  getCategorySegments: () => getCategorySegments,
56
62
  getCategorySegmentsByCategory: () => getCategorySegmentsByCategory,
57
63
  getClassNames: () => getClassNames,
@@ -62,6 +68,7 @@ __export(src_exports, {
62
68
  getIsProduction: () => getIsProduction,
63
69
  getOrigin: () => getOrigin,
64
70
  getParentCategoriesById: () => getParentCategoriesById,
71
+ getParentCategory: () => getParentCategory,
65
72
  getProto: () => getProto,
66
73
  getRootCategory: () => getRootCategory,
67
74
  getRouteHref: () => getRouteHref,
@@ -73,7 +80,6 @@ __export(src_exports, {
73
80
  httpPut: () => httpPut,
74
81
  isArray: () => isArray,
75
82
  isBrowser: () => isBrowser,
76
- isCategory: () => isCategory,
77
83
  isDevelopment: () => isDevelopment,
78
84
  isEntity: () => isEntity,
79
85
  isEquatable: () => isEquatable,
@@ -115,7 +121,6 @@ __export(src_exports, {
115
121
  qsSerialize: () => qsSerialize,
116
122
  qsSerializeRaw: () => qsSerializeRaw,
117
123
  resolveMediaType: () => resolveMediaType,
118
- textToSlug: () => textToSlug,
119
124
  toCamelCase: () => toCamelCase,
120
125
  toCharCase: () => toCharCase,
121
126
  toDisplayName: () => toDisplayName,
@@ -127,181 +132,85 @@ __export(src_exports, {
127
132
  toTitleCase: () => toTitleCase,
128
133
  toValidCollectionName: () => toValidCollectionName,
129
134
  unknownCaseToPascalCase: () => unknownCaseToPascalCase,
135
+ uuidv4: () => uuidv4,
130
136
  withSchema: () => withSchema
131
137
  });
132
138
  module.exports = __toCommonJS(src_exports);
133
139
 
134
- // src/category/category.ts
135
- function isCategory(value) {
136
- return Boolean(value) && typeof value === "object";
137
- }
138
- function asCategoryId(value) {
139
- return isCategory(value) ? value.id : value;
140
- }
141
- var ROOT_CATEGORY = process.env.ROOT_CATEGORY || "";
142
- function getRootCategory(categories) {
143
- const rootCategory = ROOT_CATEGORY && categories.find((x) => x.id == ROOT_CATEGORY);
144
- if (rootCategory) {
145
- return rootCategory;
146
- } else {
147
- return categories.find((x) => x.category == null);
148
- }
140
+ // src/utils/typeGuards.ts
141
+ function isNumber(item) {
142
+ return typeof item === "number";
149
143
  }
150
- function getParentCategoriesById(id, categories) {
151
- const rootCategory = getRootCategory(categories);
152
- const routeCategories = [];
153
- const segments = [];
154
- let parentId = id || null;
155
- while (parentId != null) {
156
- const parentCategory = categories.find((c) => c.id === parentId);
157
- if (parentCategory) {
158
- if (parentCategory.slug || parentCategory.id === rootCategory?.id) {
159
- const segment = { ...parentCategory };
160
- segments.unshift(segment);
161
- }
162
- parentId = parentCategory.category ? asCategoryId(parentCategory.category) : null;
163
- if (parentId) {
164
- if (routeCategories.includes(parentId)) {
165
- console.log("ICategory.getParentCategoriesById", "circular reference found", parentId);
166
- parentId = null;
167
- } else {
168
- routeCategories.push(parentId);
169
- }
170
- }
171
- } else {
172
- parentId = null;
173
- }
174
- }
175
- return segments;
144
+ function isString(item) {
145
+ return typeof item === "string";
176
146
  }
177
- function getCategorySegments(item, categories) {
178
- const categoryId = asCategoryId(item.category);
179
- const segments = getParentCategoriesById(categoryId, categories);
180
- return segments;
147
+ function isValidString(item) {
148
+ return typeof item === "string" && item.length > 0;
181
149
  }
182
- function getCategorySegmentsByCategory(item, categories) {
183
- const categoryId = item.category ? asCategoryId(item.category) : null;
184
- const segments = categoryId ? getParentCategoriesById(categoryId, categories) : [];
185
- segments.push(item);
186
- return segments;
150
+ function isArray(item) {
151
+ return Array.isArray(item);
187
152
  }
188
-
189
- // src/classNames/classNames.ts
190
- function isClassNameCollection(value) {
191
- return typeof value === "object" && !Array.isArray(value);
153
+ function isObject(item) {
154
+ return item != null && typeof item === "object" && !isArray(item);
192
155
  }
193
- function classNameCollectionToString(className) {
194
- const keys = Object.keys(className);
195
- const total = keys.length;
196
- let classNames = "";
197
- for (let i = 0; i < total; i++) {
198
- const key = keys[i];
199
- const value = className[keys[i]];
200
- if (!value) {
201
- continue;
202
- }
203
- classNames = classNames ? `${classNames} ${String(key)}` : String(key);
204
- }
205
- return classNames;
156
+ function isPromise(result) {
157
+ return isObject(result) && typeof result.then === "function";
206
158
  }
207
- function getClassNames(...props) {
208
- const total = props.length;
209
- let classNames = "";
210
- if (total === 0) {
211
- return classNames;
212
- }
213
- for (let i = 0; i < total; i++) {
214
- const value = props[i];
215
- if (!value) {
216
- continue;
217
- }
218
- if (isClassNameCollection(value)) {
219
- classNames += ` ${classNameCollectionToString(value)}`;
220
- } else {
221
- classNames += ` ${String(value).trim()}`;
222
- }
223
- }
224
- return classNames.trim();
159
+ function isNotNullString(item) {
160
+ return typeof item === "string" && Boolean(item);
225
161
  }
226
-
227
- // src/collection/collection.ts
228
- var import_pluralize = __toESM(require("pluralize"));
229
- function getCollectionDescription(text) {
230
- text = toValidCollectionName(text);
231
- const displayName = toDisplayName(text);
232
- const pluralName = toPluralName(text);
233
- const pluralDisplayName = toDisplayName(pluralName);
234
- const singularName = text;
235
- const title = toTitleCase(text);
236
- return {
237
- displayName,
238
- pluralName,
239
- pluralDisplayName,
240
- singularName,
241
- title
242
- };
162
+ function isEquatable(item) {
163
+ return typeof item === "number" || isNotNullString(item);
243
164
  }
244
- function camelToSnakeCase(text) {
245
- return text.replace(/[A-Z]/g, (letter, index) => {
246
- return index > 0 ? `_${letter.toLowerCase()}` : letter.toLowerCase();
247
- });
165
+ function isEntity(item) {
166
+ return isObject(item) && isEquatable(item.id);
248
167
  }
249
- function isValidCollectionDescription(description) {
250
- return description.singularName !== description.pluralName;
168
+ function isUnresolvedRelation(item) {
169
+ return isObject(item) && isNotNullString(item.relationTo) && (isEquatable(item.value) || isArray(item.value));
251
170
  }
252
- function isReservedCollectionDescription(description) {
253
- return [
254
- "category",
255
- "label",
256
- "locale",
257
- "market",
258
- "menu",
259
- "redirect",
260
- "route",
261
- "template"
262
- ].includes(description.singularName);
171
+ function isRelation(item) {
172
+ return isObject(item) && isNotNullString(item.relationTo) && isEntity(item.value);
263
173
  }
264
- function toDisplayName(text) {
265
- return toTitleCase(text).replace(/\s/g, "");
174
+ function isUndecoratedMenuItem(item) {
175
+ return isObject(item) && (item.type === "category" && isEquatable(item.category) || item.type === "page" && isEquatable(item.page.value));
266
176
  }
267
- function toPluralName(text) {
268
- const plural = import_pluralize.default.plural(text);
269
- return plural === text ? `${plural}es` : plural;
177
+ function isUndecoratedNav(item) {
178
+ return isObject(item) && isUndecoratedMenuPage(item.nav);
270
179
  }
271
- function toTitleCase(text) {
272
- return text.replace(/^[-_]*(.)/, (_, c) => c.toUpperCase()).replace(/[-_]+(.)/g, (_, c) => " " + c.toUpperCase());
180
+ function isUndecoratedMenuCategory(item) {
181
+ return isObject(item) && item.type === "category" && isNotNullString(item.category) && item.id === void 0 && item.href === void 0;
273
182
  }
274
- function toValidCollectionName(text) {
275
- text = text.trim().replace(/\W/g, "_").replace(/^[_]*(.)/, (_, c) => c);
276
- text = camelToSnakeCase(text);
277
- text = text.replace(/__/g, "_");
278
- return text.toLowerCase();
183
+ function isUndecoratedMenuPage(item) {
184
+ return isObject(item) && item.type === "page" && isObject(item.page) && isNotNullString(item.page.relationTo) && isEquatable(item.page.value);
279
185
  }
280
186
 
281
- // src/consoleWarn/consoleWarn.ts
282
- var warningStack = {};
283
- function consoleWarn(message, component) {
284
- if (typeof console === "undefined") {
285
- return;
286
- }
287
- const tag = component ? ` [${component}]` : " ";
288
- const log = `[DesignSystem]${tag}: ${message}`;
289
- if (warningStack[log]) {
290
- return;
187
+ // src/utils/asEquatable.ts
188
+ function asEquatable(value) {
189
+ const id = isEntity(value) ? value.id : value;
190
+ if (typeof id === "string") {
191
+ if (String(parseInt(id)) === id) {
192
+ return Number(id);
193
+ }
291
194
  }
292
- warningStack[log] = true;
293
- if (process.env.NODE_ENV !== "production") {
294
- return console.error(log);
195
+ return id;
196
+ }
197
+ function asEquatableString(value) {
198
+ const id = isEntity(value) ? value.id : value;
199
+ if (typeof id !== "undefined") {
200
+ return String(id);
295
201
  }
296
- console.warn(log);
202
+ return id;
297
203
  }
298
-
299
- // src/utils/asEquatable.ts
300
- function asEquatable(value) {
301
- if (String(parseInt(value)) === value) {
302
- return Number(value);
204
+ function asEquatableNumber(value) {
205
+ const id = isEntity(value) ? value.id : value;
206
+ if (typeof id === "string") {
207
+ if (String(parseInt(id)) === id) {
208
+ return Number(id);
209
+ } else {
210
+ return void 0;
211
+ }
303
212
  }
304
- return value;
213
+ return id;
305
214
  }
306
215
 
307
216
  // src/utils/asSortedOptions.ts
@@ -364,53 +273,6 @@ function toSnakeCase(unknownCase) {
364
273
  return snakeCase;
365
274
  }
366
275
 
367
- // src/utils/typeGuards.ts
368
- function isNumber(item) {
369
- return typeof item === "number";
370
- }
371
- function isString(item) {
372
- return typeof item === "string";
373
- }
374
- function isValidString(item) {
375
- return typeof item === "string" && item.length > 0;
376
- }
377
- function isArray(item) {
378
- return Array.isArray(item);
379
- }
380
- function isObject(item) {
381
- return item != null && typeof item === "object" && !isArray(item);
382
- }
383
- function isPromise(result) {
384
- return isObject(result) && typeof result.then === "function";
385
- }
386
- function isNotNullString(item) {
387
- return typeof item === "string" && Boolean(item);
388
- }
389
- function isEquatable(item) {
390
- return typeof item === "number" || isNotNullString(item);
391
- }
392
- function isEntity(item) {
393
- return isObject(item) && isEquatable(item.id);
394
- }
395
- function isUnresolvedRelation(item) {
396
- return isObject(item) && isNotNullString(item.relationTo) && (isEquatable(item.value) || isArray(item.value));
397
- }
398
- function isRelation(item) {
399
- return isObject(item) && isNotNullString(item.relationTo) && isEntity(item.value);
400
- }
401
- function isUndecoratedMenuItem(item) {
402
- return isObject(item) && (item.type === "category" && isEquatable(item.category) || item.type === "page" && isEquatable(item.page.value));
403
- }
404
- function isUndecoratedNav(item) {
405
- return isObject(item) && isUndecoratedMenuPage(item.nav);
406
- }
407
- function isUndecoratedMenuCategory(item) {
408
- return isObject(item) && item.type === "category" && isNotNullString(item.category) && item.id === void 0 && item.href === void 0;
409
- }
410
- function isUndecoratedMenuPage(item) {
411
- return isObject(item) && item.type === "page" && isObject(item.page) && isNotNullString(item.page.relationTo) && isEquatable(item.page.value);
412
- }
413
-
414
276
  // src/utils/cloneItem.ts
415
277
  function cloneItem(item) {
416
278
  if (isArray(item)) {
@@ -511,6 +373,14 @@ function enumToList(enumeration, separatorRegex = /_/g) {
511
373
  }));
512
374
  }
513
375
 
376
+ // src/utils/uuid.ts
377
+ function uuidv4() {
378
+ return "10000000-1000-4000-8000-100000000000".replace(
379
+ /[018]/g,
380
+ (c) => (+c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> +c / 4).toString(16)
381
+ );
382
+ }
383
+
514
384
  // src/utils/index.ts
515
385
  function getIsDevelopment() {
516
386
  return process && (!process.env.NODE_ENV || process.env.NODE_ENV === "development");
@@ -564,6 +434,177 @@ function merge(target, source) {
564
434
  return target;
565
435
  }
566
436
 
437
+ // src/category/category.ts
438
+ var ROOT_CATEGORY = process.env.ROOT_CATEGORY || "";
439
+ function getRootCategory(categories) {
440
+ const rootCategory = ROOT_CATEGORY && categories.find((x) => x.id == ROOT_CATEGORY);
441
+ if (rootCategory) {
442
+ return rootCategory;
443
+ } else {
444
+ return categories.find((x) => x.category == null);
445
+ }
446
+ }
447
+ function getParentCategory(categories, item) {
448
+ const parentCategoryId = asCategoryId(item.category);
449
+ const parentCategory = parentCategoryId ? categories.find((x) => x.id === parentCategoryId) : void 0;
450
+ return parentCategory;
451
+ }
452
+ function getParentCategoriesById(categories, id) {
453
+ const routeCategories = [];
454
+ const segments = [];
455
+ let parentId = id;
456
+ while (parentId != null) {
457
+ const parentCategory = categories.find((c) => c.id === parentId);
458
+ if (parentCategory) {
459
+ const segment = { ...parentCategory };
460
+ segments.unshift(segment);
461
+ routeCategories.push(parentId);
462
+ parentId = asCategoryId(parentCategory.category);
463
+ if (parentId) {
464
+ if (routeCategories.includes(parentId)) {
465
+ console.log("ICategory.getParentCategoriesById", "circular reference found", parentId);
466
+ parentId = void 0;
467
+ }
468
+ }
469
+ } else {
470
+ parentId = void 0;
471
+ }
472
+ }
473
+ return segments;
474
+ }
475
+ function getCategorySegments(categories, item) {
476
+ const parentCategoryId = asCategoryId(item.category);
477
+ const segments = getParentCategoriesById(categories, parentCategoryId);
478
+ return segments;
479
+ }
480
+ function getCategorySegmentsByCategory(categories, item) {
481
+ const parentCategoryId = asCategoryId(item.category);
482
+ const segments = parentCategoryId ? getParentCategoriesById(categories, parentCategoryId) : [];
483
+ segments.push(item);
484
+ return segments;
485
+ }
486
+ function asCategoryId(value) {
487
+ return isEntity(value) ? String(value.id) : value ? String(value) : void 0;
488
+ }
489
+ function findCategoryInCategories(categories, item) {
490
+ const categoryId = asCategoryId(item);
491
+ return categoryId ? categories.find((x) => x.id === categoryId) : void 0;
492
+ }
493
+ function findChildCategories(categories, item) {
494
+ const categoryId = asCategoryId(item);
495
+ return categoryId ? categories.filter((x) => asCategoryId(x.category) === categoryId) : [];
496
+ }
497
+
498
+ // src/classNames/classNames.ts
499
+ function isClassNameCollection(value) {
500
+ return typeof value === "object" && !Array.isArray(value);
501
+ }
502
+ function classNameCollectionToString(className) {
503
+ const keys = Object.keys(className);
504
+ const total = keys.length;
505
+ let classNames = "";
506
+ for (let i = 0; i < total; i++) {
507
+ const key = keys[i];
508
+ const value = className[keys[i]];
509
+ if (!value) {
510
+ continue;
511
+ }
512
+ classNames = classNames ? `${classNames} ${String(key)}` : String(key);
513
+ }
514
+ return classNames;
515
+ }
516
+ function getClassNames(...props) {
517
+ const total = props.length;
518
+ let classNames = "";
519
+ if (total === 0) {
520
+ return classNames;
521
+ }
522
+ for (let i = 0; i < total; i++) {
523
+ const value = props[i];
524
+ if (!value) {
525
+ continue;
526
+ }
527
+ if (isClassNameCollection(value)) {
528
+ classNames += ` ${classNameCollectionToString(value)}`;
529
+ } else {
530
+ classNames += ` ${String(value).trim()}`;
531
+ }
532
+ }
533
+ return classNames.trim();
534
+ }
535
+
536
+ // src/collection/collection.ts
537
+ var import_pluralize = __toESM(require("pluralize"));
538
+ function getCollectionDescription(text) {
539
+ text = toValidCollectionName(text);
540
+ const displayName = toDisplayName(text);
541
+ const pluralName = toPluralName(text);
542
+ const pluralDisplayName = toDisplayName(pluralName);
543
+ const singularName = text;
544
+ const title = toTitleCase(text);
545
+ return {
546
+ displayName,
547
+ pluralName,
548
+ pluralDisplayName,
549
+ singularName,
550
+ title
551
+ };
552
+ }
553
+ function camelToSnakeCase(text) {
554
+ return text.replace(/[A-Z]/g, (letter, index) => {
555
+ return index > 0 ? `_${letter.toLowerCase()}` : letter.toLowerCase();
556
+ });
557
+ }
558
+ function isValidCollectionDescription(description) {
559
+ return description.singularName !== description.pluralName;
560
+ }
561
+ function isReservedCollectionDescription(description) {
562
+ return [
563
+ "category",
564
+ "label",
565
+ "locale",
566
+ "market",
567
+ "menu",
568
+ "redirect",
569
+ "route",
570
+ "template"
571
+ ].includes(description.singularName);
572
+ }
573
+ function toDisplayName(text) {
574
+ return toTitleCase(text).replace(/\s/g, "");
575
+ }
576
+ function toPluralName(text) {
577
+ const plural = import_pluralize.default.plural(text);
578
+ return plural === text ? `${plural}es` : plural;
579
+ }
580
+ function toTitleCase(text) {
581
+ return text.replace(/^[-_]*(.)/, (_, c) => c.toUpperCase()).replace(/[-_]+(.)/g, (_, c) => " " + c.toUpperCase());
582
+ }
583
+ function toValidCollectionName(text) {
584
+ text = text.trim().replace(/\W/g, "_").replace(/^[_]*(.)/, (_, c) => c);
585
+ text = camelToSnakeCase(text);
586
+ text = text.replace(/__/g, "_");
587
+ return text.toLowerCase();
588
+ }
589
+
590
+ // src/consoleWarn/consoleWarn.ts
591
+ var warningStack = {};
592
+ function consoleWarn(message, component) {
593
+ if (typeof console === "undefined") {
594
+ return;
595
+ }
596
+ const tag = component ? ` [${component}]` : " ";
597
+ const log = `[DesignSystem]${tag}: ${message}`;
598
+ if (warningStack[log]) {
599
+ return;
600
+ }
601
+ warningStack[log] = true;
602
+ if (process.env.NODE_ENV !== "production") {
603
+ return console.error(log);
604
+ }
605
+ console.warn(log);
606
+ }
607
+
567
608
  // src/http/http.service.ts
568
609
  var defaultOptions = {
569
610
  // method: 'POST', // *GET, POST, PUT, DELETE, etc.
@@ -636,11 +677,14 @@ var JsonService = class {
636
677
  params.pagination = false;
637
678
  let items = await this.getItems();
638
679
  if (params.where) {
639
- items = this.whereItems_(items, params.where);
680
+ items = this.whereItems_(items, params.where, params.limit);
640
681
  }
641
682
  if (params.sort) {
642
683
  items = this.sortCollection_(items, params.sort);
643
684
  }
685
+ if (params.limit && !params.where) {
686
+ items = this.limitCollection_(items, params.limit);
687
+ }
644
688
  return await this.decorateMany_(items, params);
645
689
  }
646
690
  async findPaged(params = {}) {
@@ -700,49 +744,45 @@ var JsonService = class {
700
744
  return (/* @__PURE__ */ new Date()).getTime();
701
745
  }
702
746
  // where
703
- evaluateValue_(value) {
704
- if (typeof value === "object" && value) {
705
- return value.id;
706
- } else {
707
- return value;
747
+ equalsClause_(value, equals) {
748
+ if (typeof equals !== "undefined") {
749
+ return value === equals;
708
750
  }
751
+ return true;
752
+ }
753
+ notEqualsClause_(value, not_equals) {
754
+ if (typeof not_equals !== "undefined") {
755
+ return value != not_equals;
756
+ }
757
+ return true;
709
758
  }
710
- /**
711
- equals The value must be exactly equal.
712
- not_equals The query will return all documents where the value is not equal.
713
- greater_than For numeric or date-based fields.
714
- greater_than_equal For numeric or date-based fields.
715
- less_than For numeric or date-based fields.
716
- less_than_equal For numeric or date-based fields.
717
- like Case-insensitive string must be present. If string of words, all words must be present, in any order.
718
- contains Must contain the value entered, case-insensitive.
719
- in The value must be found within the provided comma-delimited list of values.
720
- not_in The value must NOT be within the provided comma-delimited list of values.
721
- all The value must contain all values provided in the comma-delimited list.
722
- exists Only return documents where the value either exists (true) or does not exist (false).
723
- near For distance related to a point field comma separated as <longitude>, <latitude>, <maxDistance in meters (nullable)>, <minDistance in meters (nullable)>.
724
- */
725
759
  existsClause_(value, exists) {
726
760
  if (typeof exists === "boolean") {
727
761
  return value != null === exists;
728
762
  }
729
763
  return true;
730
764
  }
731
- equalsClause_(value, equals) {
732
- if (typeof equals !== "undefined") {
733
- return this.evaluateValue_(value) === equals;
765
+ greaterThanClause_(value, greater_than) {
766
+ if (typeof greater_than === "number") {
767
+ return typeof value === "number" && value > greater_than;
734
768
  }
735
769
  return true;
736
770
  }
737
- inClause_(value, values) {
738
- if (Array.isArray(values)) {
739
- return values.indexOf(this.evaluateValue_(value)) !== -1;
771
+ greaterThanEqualClause_(value, greater_than_equal) {
772
+ if (typeof greater_than_equal === "number") {
773
+ return typeof value === "number" && value >= greater_than_equal;
740
774
  }
741
775
  return true;
742
776
  }
743
- notInClause_(value, values) {
744
- if (Array.isArray(values)) {
745
- return values.indexOf(this.evaluateValue_(value)) === -1;
777
+ lessThanClause_(value, less_than) {
778
+ if (typeof less_than === "number") {
779
+ return typeof value === "number" && value < less_than;
780
+ }
781
+ return true;
782
+ }
783
+ lessThanEqualClause_(value, less_than_equal) {
784
+ if (typeof less_than_equal === "number") {
785
+ return typeof value === "number" && value <= less_than_equal;
746
786
  }
747
787
  return true;
748
788
  }
@@ -765,6 +805,49 @@ var JsonService = class {
765
805
  }
766
806
  return true;
767
807
  }
808
+ inClause_(value, values) {
809
+ if (Array.isArray(values) && values.length > 0) {
810
+ return values.indexOf(value) !== -1;
811
+ }
812
+ return true;
813
+ }
814
+ notInClause_(value, values) {
815
+ if (Array.isArray(values) && values.length > 0) {
816
+ return values.indexOf(value) === -1;
817
+ }
818
+ return true;
819
+ }
820
+ allClause_(value, values) {
821
+ if (Array.isArray(values) && values.length > 0) {
822
+ return Array.isArray(value) ? values.reduce((p, c) => p && value.includes(c), true) : false;
823
+ }
824
+ return true;
825
+ }
826
+ nearClause_(value, near) {
827
+ if (Array.isArray(near) && near.reduce((p, c) => p && typeof c === "number", true)) {
828
+ if (!Array.isArray(value)) {
829
+ return false;
830
+ }
831
+ const itemLongitude = value[0];
832
+ if (typeof itemLongitude !== "number") {
833
+ return false;
834
+ }
835
+ const itemLatitude = value[1];
836
+ if (typeof itemLatitude !== "number") {
837
+ return false;
838
+ }
839
+ const [longitude, latitude, maxDistance, minDistance] = near;
840
+ const distance = calculateDistanceInMeters_(itemLongitude, itemLatitude, longitude, latitude);
841
+ if (typeof maxDistance === "number" && typeof minDistance === "number") {
842
+ return distance <= maxDistance && distance >= minDistance;
843
+ } else if (typeof maxDistance === "number") {
844
+ return distance <= maxDistance;
845
+ } else if (typeof minDistance === "number") {
846
+ return distance >= minDistance;
847
+ }
848
+ }
849
+ return true;
850
+ }
768
851
  whereItem_(item, where) {
769
852
  let has = true;
770
853
  if (typeof where === "object") {
@@ -787,22 +870,53 @@ var JsonService = class {
787
870
  default:
788
871
  if (Array.isArray(v)) {
789
872
  } else if (typeof v === "object") {
790
- const value = item[k];
791
- has = has && this.existsClause_(value, v.exists);
873
+ const value = getValue(item, k);
792
874
  has = has && this.equalsClause_(value, v.equals);
793
- has = has && this.inClause_(value, v.in);
794
- has = has && this.notInClause_(value, v.not_in);
875
+ has = has && this.notEqualsClause_(value, v.not_equals);
876
+ has = has && this.existsClause_(value, v.exists);
877
+ has = has && this.greaterThanClause_(value, v.greater_than);
878
+ has = has && this.greaterThanEqualClause_(value, v.greater_than_equal);
879
+ has = has && this.lessThanClause_(value, v.less_than);
880
+ has = has && this.lessThanEqualClause_(value, v.less_than_equal);
795
881
  has = has && this.likeClause_(value, v.like);
796
882
  has = has && this.containsClause_(value, v.contains);
883
+ has = has && this.inClause_(value, v.in);
884
+ has = has && this.notInClause_(value, v.not_in);
885
+ has = has && this.allClause_(value, v.all);
886
+ has = has && this.nearClause_(value, v.near);
797
887
  }
798
888
  }
799
889
  });
800
890
  }
801
891
  return has;
802
892
  }
803
- whereItems_(items, where) {
893
+ /**
894
+ equals The value must be exactly equal.
895
+ not_equals The query will return all documents where the value is not equal.
896
+ exists Only return documents where the value either exists (true) or does not exist (false).
897
+ greater_than For numeric or date-based fields.
898
+ greater_than_equal For numeric or date-based fields.
899
+ less_than For numeric or date-based fields.
900
+ less_than_equal For numeric or date-based fields.
901
+ like Case-insensitive string must be present. If string of words, all words must be present, in any order.
902
+ contains Must contain the value entered, case-insensitive.
903
+ in The value must be found within the provided comma-delimited list of values.
904
+ not_in The value must NOT be within the provided comma-delimited list of values.
905
+ all The value must contain all values provided in the comma-delimited list.
906
+ near For distance related to a point field comma separated as <longitude>, <latitude>, <maxDistance in meters (nullable)>, <minDistance in meters (nullable)>.
907
+ */
908
+ whereItems_(items, where, limit = -1) {
804
909
  if (typeof where === "object") {
805
- items = items.filter((item) => this.whereItem_(item, where));
910
+ const whereItems = [];
911
+ for (const item of items) {
912
+ if (limit > -1 && whereItems.length >= limit) {
913
+ return whereItems;
914
+ }
915
+ if (this.whereItem_(item, where)) {
916
+ whereItems.push(item);
917
+ }
918
+ }
919
+ return whereItems;
806
920
  }
807
921
  return items;
808
922
  }
@@ -828,14 +942,12 @@ var JsonService = class {
828
942
  }
829
943
  // ^ sort
830
944
  // limit
831
- /*
832
- protected limitCollection_<B extends T = T>(items: B[], limit?: number): B[] {
945
+ limitCollection_(items, limit) {
833
946
  if (limit) {
834
947
  items = items.slice(0, Math.min(limit, items.length));
835
948
  }
836
949
  return items;
837
950
  }
838
- */
839
951
  // ^ limit
840
952
  // pagination
841
953
  paginatedItems_(items, page = 1, limit = 10) {
@@ -865,6 +977,29 @@ var JsonService = class {
865
977
  }
866
978
  // ^ sort
867
979
  };
980
+ function getValue(item, key) {
981
+ const keys = key.split(".");
982
+ const value = keys.reduce((p, c) => {
983
+ if (isObject(p)) {
984
+ return p[c];
985
+ } else {
986
+ return void 0;
987
+ }
988
+ }, item);
989
+ return value;
990
+ }
991
+ function calculateDistanceInMeters_(lon1, lat1, lon2, lat2) {
992
+ const R = 6371;
993
+ const dLat = deg2rad_(lat2 - lat1);
994
+ const dLon = deg2rad_(lon2 - lon1);
995
+ const a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + Math.cos(deg2rad_(lat1)) * Math.cos(deg2rad_(lat2)) * Math.sin(dLon / 2) * Math.sin(dLon / 2);
996
+ const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
997
+ const distance = R * c * 1e3;
998
+ return distance;
999
+ }
1000
+ function deg2rad_(deg) {
1001
+ return deg * (Math.PI / 180);
1002
+ }
868
1003
 
869
1004
  // src/locale/locale.ts
870
1005
  function getDefaultLocale() {
@@ -1118,58 +1253,74 @@ function getOrigin(headers) {
1118
1253
  }
1119
1254
 
1120
1255
  // src/route/route.ts
1256
+ var RouteStrategy = /* @__PURE__ */ ((RouteStrategy2) => {
1257
+ RouteStrategy2["Auto"] = "auto";
1258
+ RouteStrategy2["Default"] = "default";
1259
+ RouteStrategy2["Manual"] = "manual";
1260
+ return RouteStrategy2;
1261
+ })(RouteStrategy || {});
1262
+ var ROUTE_STRATEGY = process.env.ROUTE_STRATEGY || "auto" /* Auto */;
1263
+ function getPickedProps(item) {
1264
+ const pickedProps = Object.fromEntries(Object.entries(item).filter(([k, v]) => [
1265
+ "category",
1266
+ "isDefault",
1267
+ "media",
1268
+ "order",
1269
+ "template",
1270
+ "updatedAt",
1271
+ "useSplat"
1272
+ ].includes(k)));
1273
+ return pickedProps;
1274
+ }
1121
1275
  function collectRoutes(store, categories, markets, locales) {
1122
1276
  const routes = [];
1123
1277
  if (locales.length > 0 && markets.length > 0) {
1124
1278
  const rootCategory = getRootCategory(categories);
1125
1279
  eachCategorized(store, (item, key) => {
1126
- const segments = getCategorySegments(item, categories);
1127
- const slugs = segments.map((x) => ({ slug: x.slug }));
1128
- if (!item.isDefault) {
1129
- slugs.push({ slug: item.slug });
1130
- }
1131
- eachMarketLocale(markets, locales, (market, locale, markets2, locales2) => {
1132
- if (!item.markets || item.markets.includes(market.id)) {
1133
- const title = localize(item.title, locale.id);
1134
- const id = getRouteHref(slugs, market, locale, markets2, locales2);
1280
+ const segments = getCategorySegments(categories, item);
1281
+ const visibleSegments = segments.filter((x) => Boolean(x.isHidden) === false);
1282
+ const visibleCategory = visibleSegments.length > 0 ? visibleSegments[visibleSegments.length - 1] : rootCategory;
1283
+ if (visibleCategory) {
1284
+ const slugs = visibleSegments.map((x) => ({ slug: x.slug }));
1285
+ if (Boolean(item.isDefault) === false) {
1286
+ slugs.push({ slug: item.slug });
1287
+ }
1288
+ if (rootCategory && item.category === rootCategory.id) {
1289
+ const defaultLocale2 = locales.find((x) => x.isDefault) || locales[0];
1290
+ const defaultMarket2 = markets.find((x) => x.isDefault) || markets[0];
1291
+ const defaultMarketLocale = defaultMarket2 && defaultMarket2.defaultLanguage ? defaultMarket2.defaultLanguage : defaultLocale2.id;
1292
+ const title = localize(item.title, defaultMarketLocale);
1293
+ const pickedProps = getPickedProps(item);
1135
1294
  const route = {
1136
- category: item.category,
1137
- id,
1138
- isDefault: item.isDefault,
1139
- locale: locale.id,
1140
- market: market.id,
1141
- media: item.media,
1142
- order: item.order,
1295
+ ...pickedProps,
1296
+ resolvedCategory: rootCategory.id,
1297
+ id: "/",
1298
+ market: defaultMarket2.id,
1299
+ locale: defaultMarketLocale,
1143
1300
  page: item.id,
1144
1301
  schema: key,
1145
- template: item.template,
1146
- title,
1147
- updatedAt: item.updatedAt,
1148
- useSplat: item.useSplat
1302
+ title
1149
1303
  };
1150
1304
  routes.push(route);
1151
1305
  }
1152
- });
1153
- if (rootCategory && item.category === rootCategory.id) {
1154
- const defaultLocale2 = locales.find((x) => x.isDefault) || locales[0];
1155
- const defaultMarket2 = markets.find((x) => x.isDefault) || markets[0];
1156
- const defaultMarketLocale = defaultMarket2 && defaultMarket2.defaultLanguage ? defaultMarket2.defaultLanguage : defaultLocale2.id;
1157
- const title = localize(item.title, defaultMarketLocale);
1158
- const route = {
1159
- id: "/",
1160
- market: defaultMarket2.id,
1161
- locale: defaultMarketLocale,
1162
- category: item.category,
1163
- page: item.id,
1164
- schema: key,
1165
- template: item.template,
1166
- title,
1167
- isDefault: item.isDefault,
1168
- order: item.order,
1169
- useSplat: item.useSplat,
1170
- updatedAt: item.updatedAt
1171
- };
1172
- routes.push(route);
1306
+ eachMarketLocale(markets, locales, (market, locale, markets2, locales2) => {
1307
+ if (!item.markets || item.markets.includes(market.id)) {
1308
+ const title = localize(item.title, locale.id);
1309
+ const id = getRouteHref(slugs, market, locale, markets2, locales2);
1310
+ const pickedProps = getPickedProps(item);
1311
+ const route = {
1312
+ ...pickedProps,
1313
+ resolvedCategory: visibleCategory.id,
1314
+ id,
1315
+ locale: locale.id,
1316
+ market: market.id,
1317
+ page: item.id,
1318
+ schema: key,
1319
+ title
1320
+ };
1321
+ routes.push(route);
1322
+ }
1323
+ });
1173
1324
  }
1174
1325
  });
1175
1326
  }
@@ -1194,13 +1345,17 @@ function eachCategorized(store, callback) {
1194
1345
  }
1195
1346
  }
1196
1347
  }
1197
- var RouteStrategy = /* @__PURE__ */ ((RouteStrategy2) => {
1198
- RouteStrategy2["Auto"] = "auto";
1199
- RouteStrategy2["Default"] = "default";
1200
- RouteStrategy2["Manual"] = "manual";
1201
- return RouteStrategy2;
1202
- })(RouteStrategy || {});
1203
- var ROUTE_STRATEGY = process.env.ROUTE_STRATEGY || "auto" /* Auto */;
1348
+ function findRouteOfCategory(routes, categoryId, market, locale) {
1349
+ const findRoute = market && locale ? (route2) => route2.isDefault && route2.resolvedCategory === categoryId && route2.market === market && route2.locale === locale : (route2) => route2.isDefault && route2.resolvedCategory === categoryId;
1350
+ const route = routes.find(findRoute);
1351
+ return route;
1352
+ }
1353
+ function findRoutesOfCategory(routes, categoryId, isDefault = true) {
1354
+ const filteredRoutes = routes.filter(
1355
+ (route) => route.resolvedCategory === categoryId && Boolean(route.isDefault) === isDefault
1356
+ );
1357
+ return filteredRoutes;
1358
+ }
1204
1359
  function getRouteHref(segments, market, locale, markets, locales) {
1205
1360
  const href = segments.reduce((p, c, i) => {
1206
1361
  let slug = localize(c.slug || "", locale.id);
@@ -1238,11 +1393,6 @@ function getRouteHref(segments, market, locale, markets, locales) {
1238
1393
  return `${prefix}${href}`;
1239
1394
  }
1240
1395
 
1241
- // src/slug/slug.ts
1242
- function textToSlug(title) {
1243
- return title.toString().normalize("NFD").replace(/[\u0300-\u036f]/g, "").toLowerCase().replace(/\s+/g, "-").replace(/&/g, "-and-").replace(/[^\w-]+/g, "").replace(/--+/g, "-").replace(/^-+/, "").replace(/-+$/, "");
1244
- }
1245
-
1246
1396
  // src/types/media.ts
1247
1397
  function resolveMediaType(media) {
1248
1398
  if (typeof media.type === "string" && media.type.length > 0) {
@@ -1319,6 +1469,8 @@ var RedirectReason = /* @__PURE__ */ ((RedirectReason2) => {
1319
1469
  RouteStrategy,
1320
1470
  asCategoryId,
1321
1471
  asEquatable,
1472
+ asEquatableNumber,
1473
+ asEquatableString,
1322
1474
  asServerProps,
1323
1475
  asSortedOptions,
1324
1476
  awaitAll,
@@ -1334,6 +1486,10 @@ var RedirectReason = /* @__PURE__ */ ((RedirectReason2) => {
1334
1486
  eachCategorized,
1335
1487
  eachMarketLocale,
1336
1488
  enumToList,
1489
+ findCategoryInCategories,
1490
+ findChildCategories,
1491
+ findRouteOfCategory,
1492
+ findRoutesOfCategory,
1337
1493
  getCategorySegments,
1338
1494
  getCategorySegmentsByCategory,
1339
1495
  getClassNames,
@@ -1344,6 +1500,7 @@ var RedirectReason = /* @__PURE__ */ ((RedirectReason2) => {
1344
1500
  getIsProduction,
1345
1501
  getOrigin,
1346
1502
  getParentCategoriesById,
1503
+ getParentCategory,
1347
1504
  getProto,
1348
1505
  getRootCategory,
1349
1506
  getRouteHref,
@@ -1355,7 +1512,6 @@ var RedirectReason = /* @__PURE__ */ ((RedirectReason2) => {
1355
1512
  httpPut,
1356
1513
  isArray,
1357
1514
  isBrowser,
1358
- isCategory,
1359
1515
  isDevelopment,
1360
1516
  isEntity,
1361
1517
  isEquatable,
@@ -1397,7 +1553,6 @@ var RedirectReason = /* @__PURE__ */ ((RedirectReason2) => {
1397
1553
  qsSerialize,
1398
1554
  qsSerializeRaw,
1399
1555
  resolveMediaType,
1400
- textToSlug,
1401
1556
  toCamelCase,
1402
1557
  toCharCase,
1403
1558
  toDisplayName,
@@ -1409,5 +1564,6 @@ var RedirectReason = /* @__PURE__ */ ((RedirectReason2) => {
1409
1564
  toTitleCase,
1410
1565
  toValidCollectionName,
1411
1566
  unknownCaseToPascalCase,
1567
+ uuidv4,
1412
1568
  withSchema
1413
1569
  });