@websolutespa/bom-mixer-store 1.7.9 → 1.8.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-mixer-store
2
2
 
3
+ ## 1.8.1
4
+
5
+ ### Patch Changes
6
+
7
+ - 15ad595: Modified: getRemoteApiRequestOptions added user Bearer
8
+
9
+ ## 1.8.0
10
+
11
+ ### Minor Changes
12
+
13
+ - f8a1d97: Modified: extracted all website sample components & features
14
+
15
+ ### Patch Changes
16
+
17
+ - Updated dependencies [f8a1d97]
18
+ - @websolutespa/bom-core@1.8.0
19
+
3
20
  ## 1.7.9
4
21
 
5
22
  ### Patch Changes
package/dist/index.d.ts CHANGED
@@ -4,10 +4,10 @@ import { NextRequest } from 'next/server';
4
4
  import * as _websolutespa_bom_mixer_store from '@websolutespa/bom-mixer-store';
5
5
 
6
6
  type ApiRequestOptions = FetchRequestOptions;
7
- /**
8
- * !!! todo: evaluate authenticated end user bearer
9
- */
10
7
  declare function getLocalApiRequestOptions(): ApiRequestOptions;
8
+ declare const REMOTE_API_SESSION: {
9
+ token: string | null;
10
+ };
11
11
  declare function getRemoteApiRequestOptions(): ApiRequestOptions;
12
12
 
13
13
  type ICrudMethod = 'get' | 'post' | 'put' | 'patch' | 'delete' | string;
@@ -242,4 +242,4 @@ declare function getStore<T extends IStore>(): Promise<T>;
242
242
 
243
243
  declare function varsHandler(): _websolutespa_bom_mixer_store.IHandler<any>;
244
244
 
245
- export { ApiRequestOptions, BuildStrategy, COLLECTIONS, IApiHandler, ICrudMethod, IField, IHandler, IPageResolvedRelation, KNOWN_COLLECTIONS, MAX_INT, MOCK_COLLECTIONS, MapTo, MockMenuService, MockPageService, MockService, NextPhase, RemoteMenuService, RemotePageService, RemoteService, RemoteServiceStrategy, SERVICE_DEFAULT_DEPTH, STATIC_COLLECTIONS, StaticService, StaticServiceConfig, StaticServiceSrc, StoreStrategy, apiHandler, buildStrategy, collectionDelete, collectionGet, collectionPatch, collectionPost, decorateCategories_, decorateCategory_, decorateHref_, decorateHrefs_, decorateLocalizable_, decorateLocalizables_, decorateMenu_, decorateMenus_, decorateNav_, decorateNavs_, decorateRelation_, decorateRelations_, decorateSchema_, decorateSchemas_, decorateStaticRelation_, decorateStaticRelations_, errorHandler, findRoute, fromCache, getLocalApiRequestOptions, getLocalApiUrl, getMockStore, getMockStoreFromData_, getRemoteApiRequestOptions, getRemoteApiUrl, getRemoteStore, getStore, isApiRequest, isNextRequest, isStaticRequest, localApiDelete, localApiFetch, localApiGet, localApiPatch, localApiPost, localApiPut, mockApiDelete, mockApiFetch, mockApiGet, mockApiPatch, mockApiPost, mockApiPut, mockHandler, nextPhase, optimizeMany_, optimizeOne_, remoteApiDelete, remoteApiFetch, remoteApiGet, remoteApiPatch, remoteApiPost, remoteApiPut, routePost, staticCollections, storeApiDelete, storeApiGet, storeApiPatch, storeApiPost, storeApiPut, storeCacheDuration, storeHandler, storeIndexHandler, storeStrategy, varsHandler };
245
+ export { ApiRequestOptions, BuildStrategy, COLLECTIONS, IApiHandler, ICrudMethod, IField, IHandler, IPageResolvedRelation, KNOWN_COLLECTIONS, MAX_INT, MOCK_COLLECTIONS, MapTo, MockMenuService, MockPageService, MockService, NextPhase, REMOTE_API_SESSION, RemoteMenuService, RemotePageService, RemoteService, RemoteServiceStrategy, SERVICE_DEFAULT_DEPTH, STATIC_COLLECTIONS, StaticService, StaticServiceConfig, StaticServiceSrc, StoreStrategy, apiHandler, buildStrategy, collectionDelete, collectionGet, collectionPatch, collectionPost, decorateCategories_, decorateCategory_, decorateHref_, decorateHrefs_, decorateLocalizable_, decorateLocalizables_, decorateMenu_, decorateMenus_, decorateNav_, decorateNavs_, decorateRelation_, decorateRelations_, decorateSchema_, decorateSchemas_, decorateStaticRelation_, decorateStaticRelations_, errorHandler, findRoute, fromCache, getLocalApiRequestOptions, getLocalApiUrl, getMockStore, getMockStoreFromData_, getRemoteApiRequestOptions, getRemoteApiUrl, getRemoteStore, getStore, isApiRequest, isNextRequest, isStaticRequest, localApiDelete, localApiFetch, localApiGet, localApiPatch, localApiPost, localApiPut, mockApiDelete, mockApiFetch, mockApiGet, mockApiPatch, mockApiPost, mockApiPut, mockHandler, nextPhase, optimizeMany_, optimizeOne_, remoteApiDelete, remoteApiFetch, remoteApiGet, remoteApiPatch, remoteApiPost, remoteApiPut, routePost, staticCollections, storeApiDelete, storeApiGet, storeApiPatch, storeApiPost, storeApiPut, storeCacheDuration, storeHandler, storeIndexHandler, storeStrategy, varsHandler };
package/dist/index.js CHANGED
@@ -39,6 +39,7 @@ __export(src_exports, {
39
39
  MockPageService: () => MockPageService,
40
40
  MockService: () => MockService,
41
41
  NextPhase: () => NextPhase,
42
+ REMOTE_API_SESSION: () => REMOTE_API_SESSION,
42
43
  RemoteMenuService: () => RemoteMenuService,
43
44
  RemotePageService: () => RemotePageService,
44
45
  RemoteService: () => RemoteService,
@@ -126,20 +127,26 @@ function getLocalApiRequestOptions() {
126
127
  headers: {}
127
128
  };
128
129
  }
130
+ var REMOTE_API_SESSION = {
131
+ token: null
132
+ };
129
133
  function getRemoteApiRequestOptions() {
130
- return {
131
- // mode: 'cors',
132
- headers: {
133
- /**
134
- * guest user api key (users)
135
- */
136
- Authorization: `users API-Key ${process.env.STORE_API_KEY}`
137
- /**
138
- * authenticated end user bearer (end_users)
139
- */
140
- // Authorization: `Bearer ${bearer}`,
141
- }
142
- };
134
+ if (REMOTE_API_SESSION.token) {
135
+ return {
136
+ // mode: 'cors',
137
+ headers: {
138
+ Authorization: `Bearer ${REMOTE_API_SESSION.token}`
139
+ // Authorization: `JWT ${REMOTE_API_SESSION.token}`,
140
+ }
141
+ };
142
+ } else {
143
+ return {
144
+ // mode: 'cors',
145
+ headers: {
146
+ Authorization: `users API-Key ${process.env.STORE_API_KEY}`
147
+ }
148
+ };
149
+ }
143
150
  }
144
151
 
145
152
  // src/api/api.handler.ts
@@ -476,7 +483,9 @@ function decorateMenuRoute_(item) {
476
483
  return decoratedItem;
477
484
  }
478
485
  async function decorateMenuPage_(item, routes, store, params = {}) {
479
- const id = (0, import_bom_core3.isEquatable)(item.page.value) ? item.page.value : item.page.value.id;
486
+ const values = Array.isArray(item.page.value) ? item.page.value : [item.page.value];
487
+ const value = values[0];
488
+ const id = (0, import_bom_core3.isEquatable)(value) ? value : value.id;
480
489
  const route = routes.find(
481
490
  (x) => x.schema === item.page.relationTo && x.page === id
482
491
  );
@@ -510,7 +519,7 @@ async function decorateNav_(store, item, params = {}, routes) {
510
519
  const navs = collectNavs_(item);
511
520
  for (const nav of navs) {
512
521
  const decoratedNav = decorateNav__(nav, routes);
513
- nav.nav = decoratedNav.nav;
522
+ Object.assign(nav, decoratedNav);
514
523
  }
515
524
  return item;
516
525
  }
@@ -540,14 +549,13 @@ function collectNavs_(item, navs = []) {
540
549
  return navs;
541
550
  }
542
551
  function decorateNav__(item, routes) {
543
- const { nav, ...undecorated } = item;
544
- if (nav !== void 0) {
545
- const decorated = { ...undecorated };
552
+ let decoratedNav = item;
553
+ if (item !== void 0) {
546
554
  const route = routes.find(
547
- (x) => x.page === nav.page.value && x.schema === nav.page.relationTo
555
+ (x) => x.page === item.page.value && x.schema === item.page.relationTo
548
556
  );
549
557
  if (route) {
550
- decorated.nav = {
558
+ decoratedNav = {
551
559
  type: "page",
552
560
  id: route.page,
553
561
  href: route.id,
@@ -556,23 +564,17 @@ function decorateNav__(item, routes) {
556
564
  schema: route.schema
557
565
  };
558
566
  }
559
- return decorated;
560
567
  }
561
- return undecorated;
568
+ return decoratedNav;
562
569
  }
563
570
 
564
571
  // src/decorators/optimize.ts
565
- var import_bom_core5 = require("@websolutespa/bom-core");
566
572
  async function optimizeOne_(item) {
567
573
  const validEntries = Object.entries(item).filter(([key, value]) => {
568
574
  switch (key) {
569
575
  case "components":
570
576
  case "meta":
571
577
  return false;
572
- default:
573
- if ((0, import_bom_core5.isUnresolvedRelation)(value) || Array.isArray(value) && value.reduce((p, c) => p && (0, import_bom_core5.isUnresolvedRelation)(c), true)) {
574
- return false;
575
- }
576
578
  }
577
579
  return true;
578
580
  });
@@ -588,7 +590,7 @@ async function optimizeMany_(items) {
588
590
  }
589
591
 
590
592
  // src/decorators/relation.ts
591
- var import_bom_core6 = require("@websolutespa/bom-core");
593
+ var import_bom_core5 = require("@websolutespa/bom-core");
592
594
  var SERVICE_DEFAULT_DEPTH = 3;
593
595
  async function decorateRelation_(store, item, params = {}) {
594
596
  const depth = params.depth != null ? params.depth : SERVICE_DEFAULT_DEPTH;
@@ -605,7 +607,7 @@ async function decorateRelations_(store, items, params = {}) {
605
607
  return items;
606
608
  }
607
609
  async function collectRelations_(context, item, relations = []) {
608
- if ((0, import_bom_core6.isUnresolvedRelation)(item)) {
610
+ if ((0, import_bom_core5.isUnresolvedRelation)(item)) {
609
611
  const index = relations.findIndex(
610
612
  (x) => x.relationTo === item.relationTo && x.value === item.value
611
613
  );
@@ -634,13 +636,13 @@ async function collectRelations_(context, item, relations = []) {
634
636
  } else {
635
637
  return relations[index].resolvedValue;
636
638
  }
637
- } else if ((0, import_bom_core6.isArray)(item)) {
639
+ } else if ((0, import_bom_core5.isArray)(item)) {
638
640
  const items = [];
639
641
  for (let i = 0; i < item.length; i++) {
640
642
  items[i] = await collectRelations_(context, item[i], relations);
641
643
  }
642
644
  return items;
643
- } else if ((0, import_bom_core6.isObject)(item)) {
645
+ } else if ((0, import_bom_core5.isObject)(item)) {
644
646
  for (const [key, value] of Object.entries(item)) {
645
647
  item[key] = await collectRelations_(context, value, relations);
646
648
  }
@@ -659,12 +661,12 @@ async function decorateSchemas_(store, items, schema) {
659
661
  }
660
662
 
661
663
  // src/local/local.api.ts
662
- var import_bom_core7 = require("@websolutespa/bom-core");
664
+ var import_bom_core6 = require("@websolutespa/bom-core");
663
665
  var API_URL = process.env.NEXT_PUBLIC_URL === "https://" ? process.env.NEXT_PUBLIC_MOCK_FALLBACK_URL : process.env.NEXT_PUBLIC_URL;
664
666
  var API_BASE = process.env.NEXT_PUBLIC_API || "/api";
665
667
  function getLocalApiUrl(pathname) {
666
- let url = `${import_bom_core7.isBrowser ? window.location.origin : API_URL}${API_BASE}${pathname}`;
667
- url = import_bom_core7.isBrowser ? url : url.replace("://localhost", "://127.0.0.1");
668
+ let url = `${import_bom_core6.isBrowser ? window.location.origin : API_URL}${API_BASE}${pathname}`;
669
+ url = import_bom_core6.isBrowser ? url : url.replace("://localhost", "://127.0.0.1");
668
670
  return url;
669
671
  }
670
672
  async function localApiFetch(pathname, options = {}, serviceOptions) {
@@ -673,9 +675,9 @@ async function localApiFetch(pathname, options = {}, serviceOptions) {
673
675
  url.searchParams.append("locale", serviceOptions.locale);
674
676
  url.searchParams.append("market", serviceOptions.market);
675
677
  }
676
- const apiOptions = (0, import_bom_core7.merge)({ ...getLocalApiRequestOptions() }, options);
678
+ const apiOptions = (0, import_bom_core6.merge)({ ...getLocalApiRequestOptions() }, options);
677
679
  console.log("localApiFetch", apiOptions.method, url.href);
678
- const apiResponse = await (0, import_bom_core7.httpFetch)(url.href, apiOptions);
680
+ const apiResponse = await (0, import_bom_core6.httpFetch)(url.href, apiOptions);
679
681
  return apiResponse;
680
682
  }
681
683
  async function localApiGet(url, options = {}, serviceOptions) {
@@ -714,8 +716,8 @@ function isApiRequest(request) {
714
716
  }
715
717
 
716
718
  // src/mock/mock.service.ts
717
- var import_bom_core8 = require("@websolutespa/bom-core");
718
- var MockService = class extends import_bom_core8.JsonService {
719
+ var import_bom_core7 = require("@websolutespa/bom-core");
720
+ var MockService = class extends import_bom_core7.JsonService {
719
721
  constructor(items, store) {
720
722
  super(items);
721
723
  this.store = store;
@@ -795,24 +797,29 @@ var MockPageService = class extends MockService {
795
797
  decoratedItems = await decorateCategories_(store, decoratedItems, params);
796
798
  decoratedItems = await decorateLocalizables_(decoratedItems, params);
797
799
  decoratedItems = await decorateHrefs_(store, decoratedItems, params);
800
+ decoratedItems = await decorateRelations_(store, decoratedItems, {
801
+ market: params.market,
802
+ locale: params.locale,
803
+ depth: params.depth
804
+ });
798
805
  return decoratedItems;
799
806
  }
800
807
  };
801
808
 
802
809
  // src/mock/mock.api.ts
803
- var import_bom_core9 = require("@websolutespa/bom-core");
810
+ var import_bom_core8 = require("@websolutespa/bom-core");
804
811
  var API_URL2 = process.env.NEXT_PUBLIC_URL;
805
812
  var API_BASE3 = process.env.NEXT_PUBLIC_API || "/api";
806
813
  function getMockApiUrl(pathname) {
807
814
  let url = `${API_URL2}${API_BASE3}/_mock${pathname}`;
808
- url = import_bom_core9.isBrowser ? url : url.replace("://localhost", "://127.0.0.1");
815
+ url = import_bom_core8.isBrowser ? url : url.replace("://localhost", "://127.0.0.1");
809
816
  return url;
810
817
  }
811
818
  async function mockApiFetch(pathname, options = {}) {
812
819
  const url = getMockApiUrl(pathname);
813
- const apiOptions = (0, import_bom_core9.merge)({ ...getLocalApiRequestOptions() }, options);
820
+ const apiOptions = (0, import_bom_core8.merge)({ ...getLocalApiRequestOptions() }, options);
814
821
  console.log("mockApiFetch", apiOptions.method, url);
815
- const apiResponse = await (0, import_bom_core9.httpFetch)(url, apiOptions);
822
+ const apiResponse = await (0, import_bom_core8.httpFetch)(url, apiOptions);
816
823
  return apiResponse;
817
824
  }
818
825
  async function mockApiGet(url, options = {}) {
@@ -832,7 +839,7 @@ async function mockApiDelete(url, options = {}) {
832
839
  }
833
840
 
834
841
  // src/store/store.handler.ts
835
- var import_bom_core15 = require("@websolutespa/bom-core");
842
+ var import_bom_core14 = require("@websolutespa/bom-core");
836
843
 
837
844
  // src/static/static.ts
838
845
  var staticCollections = [{
@@ -905,6 +912,28 @@ var staticCollections = [{
905
912
  type: "text"
906
913
  }
907
914
  ]
915
+ }, {
916
+ src: "https://actarian.github.io/cms-i18n-react/api/language.json",
917
+ slug: "i18n_country_zone",
918
+ fields: [
919
+ {
920
+ name: "id",
921
+ type: "text"
922
+ },
923
+ {
924
+ name: "name",
925
+ type: "text",
926
+ localized: true
927
+ },
928
+ {
929
+ name: "englishName",
930
+ type: "text"
931
+ },
932
+ {
933
+ name: "nativeName",
934
+ type: "text"
935
+ }
936
+ ]
908
937
  }, {
909
938
  src: "https://actarian.github.io/cms-i18n-react/api/municipality.json",
910
939
  slug: "i18n_municipality",
@@ -1107,7 +1136,7 @@ var KNOWN_COLLECTIONS = [
1107
1136
  var COLLECTIONS = [...ENV_COLLECTIONS, ...KNOWN_COLLECTIONS];
1108
1137
 
1109
1138
  // src/mock/mock.store.ts
1110
- var import_bom_core11 = require("@websolutespa/bom-core");
1139
+ var import_bom_core10 = require("@websolutespa/bom-core");
1111
1140
 
1112
1141
  // src/fs/fs.service.ts
1113
1142
  var fs = __toESM(require("fs"));
@@ -1135,8 +1164,8 @@ async function fsReadJson(pathname) {
1135
1164
  }
1136
1165
 
1137
1166
  // src/static/static.service.ts
1138
- var import_bom_core10 = require("@websolutespa/bom-core");
1139
- var StaticService = class extends import_bom_core10.JsonService {
1167
+ var import_bom_core9 = require("@websolutespa/bom-core");
1168
+ var StaticService = class extends import_bom_core9.JsonService {
1140
1169
  constructor(config, store) {
1141
1170
  super([]);
1142
1171
  this.loaded = false;
@@ -1164,7 +1193,7 @@ var StaticService = class extends import_bom_core10.JsonService {
1164
1193
  const config = this.config;
1165
1194
  const src = config.src;
1166
1195
  if (typeof src === "string") {
1167
- const response = await (0, import_bom_core10.httpGet)(src, {});
1196
+ const response = await (0, import_bom_core9.httpGet)(src, {});
1168
1197
  items = response.items;
1169
1198
  } else if (typeof src === "function") {
1170
1199
  if (src instanceof Promise) {
@@ -1280,7 +1309,7 @@ function getMockStoreFromData_(data) {
1280
1309
  return store;
1281
1310
  }
1282
1311
  async function getStoreData_() {
1283
- if (import_bom_core11.isDevelopment) {
1312
+ if (import_bom_core10.isDevelopment) {
1284
1313
  const path = require("path");
1285
1314
  const pathname = path.join(process.cwd(), ".mixer", "store.json");
1286
1315
  return await fsReadJson(pathname) || {};
@@ -1296,17 +1325,17 @@ async function getMockStore_() {
1296
1325
  }
1297
1326
  async function getMockStore() {
1298
1327
  return fromCache(async () => {
1299
- if (!import_bom_core11.isDevelopment) {
1328
+ if (!import_bom_core10.isDevelopment) {
1300
1329
  console.warn("getMockStore");
1301
1330
  }
1302
1331
  const store = await getMockStore_();
1303
1332
  return store;
1304
- }, import_bom_core11.isDevelopment ? void 0 : "STORE_MOCK_");
1333
+ }, import_bom_core10.isDevelopment ? void 0 : "STORE_MOCK_");
1305
1334
  }
1306
1335
 
1307
1336
  // src/cached/cached.service.ts
1308
- var import_bom_core12 = require("@websolutespa/bom-core");
1309
- var CachedService = class extends import_bom_core12.JsonService {
1337
+ var import_bom_core11 = require("@websolutespa/bom-core");
1338
+ var CachedService = class extends import_bom_core11.JsonService {
1310
1339
  constructor(service, options = {}) {
1311
1340
  super([]);
1312
1341
  this.cache_ = /* @__PURE__ */ new Map();
@@ -1345,7 +1374,7 @@ var CachedService = class extends import_bom_core12.JsonService {
1345
1374
  });
1346
1375
  }
1347
1376
  async findOne(id, params = {}) {
1348
- const serializedParams = (0, import_bom_core12.qsSerialize)(params);
1377
+ const serializedParams = (0, import_bom_core11.qsSerialize)(params);
1349
1378
  const key = `findOne[${id}]?${serializedParams}`;
1350
1379
  return await this.fromCache_(async () => {
1351
1380
  return await this.service_.findOne(id, params);
@@ -1354,7 +1383,7 @@ var CachedService = class extends import_bom_core12.JsonService {
1354
1383
  async findMany(params = {}) {
1355
1384
  if (storeStrategy === "decoratedApi" /* DecoratedApi */) {
1356
1385
  const { market, locale, ...otherParams } = params;
1357
- const serializedParams = (0, import_bom_core12.qsSerialize)({ market, locale });
1386
+ const serializedParams = (0, import_bom_core11.qsSerialize)({ market, locale });
1358
1387
  const key = `findMany?${serializedParams}`;
1359
1388
  let items = await this.fromCache_(async () => {
1360
1389
  return await this.service_.findMany({ market, locale });
@@ -1367,7 +1396,7 @@ var CachedService = class extends import_bom_core12.JsonService {
1367
1396
  }
1368
1397
  return items;
1369
1398
  } else {
1370
- const serializedParams = (0, import_bom_core12.qsSerialize)(params);
1399
+ const serializedParams = (0, import_bom_core11.qsSerialize)(params);
1371
1400
  const key = `findMany?${serializedParams}`;
1372
1401
  return await this.fromCache_(async () => {
1373
1402
  return await this.service_.findMany(params);
@@ -1375,7 +1404,7 @@ var CachedService = class extends import_bom_core12.JsonService {
1375
1404
  }
1376
1405
  }
1377
1406
  async findPaged(params = {}) {
1378
- const serializedParams = (0, import_bom_core12.qsSerialize)(params);
1407
+ const serializedParams = (0, import_bom_core11.qsSerialize)(params);
1379
1408
  const key = `findPaged?${serializedParams}`;
1380
1409
  return await this.fromCache_(async () => {
1381
1410
  return await this.service_.findPaged(params);
@@ -1393,22 +1422,25 @@ var CachedService = class extends import_bom_core12.JsonService {
1393
1422
  };
1394
1423
 
1395
1424
  // src/remote/remote.service.ts
1396
- var import_bom_core14 = require("@websolutespa/bom-core");
1425
+ var import_bom_core13 = require("@websolutespa/bom-core");
1397
1426
 
1398
1427
  // src/remote/remote.api.ts
1399
- var import_bom_core13 = require("@websolutespa/bom-core");
1428
+ var import_bom_core12 = require("@websolutespa/bom-core");
1400
1429
  var API_URL3 = process.env.STORE_URL;
1401
1430
  var API_BASE4 = process.env.STORE_API || "/api";
1402
1431
  function getRemoteApiUrl(pathname) {
1403
1432
  let url = `${API_URL3}${API_BASE4}${pathname}`;
1404
- url = import_bom_core13.isBrowser ? url : url.replace("://localhost", "://127.0.0.1");
1433
+ url = import_bom_core12.isBrowser ? url : url.replace("://localhost", "://127.0.0.1");
1405
1434
  return url;
1406
1435
  }
1407
1436
  async function remoteApiFetch(pathname, options = {}) {
1437
+ if (import_bom_core12.isBrowser) {
1438
+ throw "Unauthorized: remote api cannot be fetched client side";
1439
+ }
1408
1440
  const url = getRemoteApiUrl(pathname);
1409
- const apiOptions = (0, import_bom_core13.merge)({ ...getRemoteApiRequestOptions() }, options);
1441
+ const apiOptions = (0, import_bom_core12.merge)({ ...getRemoteApiRequestOptions() }, options);
1410
1442
  console.log("remoteApiFetch", apiOptions.method, url);
1411
- const apiResponse = await (0, import_bom_core13.httpFetch)(url, apiOptions);
1443
+ const apiResponse = await (0, import_bom_core12.httpFetch)(url, apiOptions);
1412
1444
  return apiResponse;
1413
1445
  }
1414
1446
  async function remoteApiGet(url, options = {}) {
@@ -1445,12 +1477,16 @@ var RemoteService = class {
1445
1477
  async findOne(id, params = {}) {
1446
1478
  params.richText = String(params.richText) === "true" ? true : false;
1447
1479
  params.draft = RemoteServiceStrategy.draft;
1448
- const query = (0, import_bom_core14.qsSerialize)(params);
1480
+ const query = (0, import_bom_core13.qsSerialize)(params);
1449
1481
  const search = query ? `?${query}` : "";
1450
1482
  const url = `/${this.key}/${encodeURIComponent(id)}${search}`;
1451
- const item = await remoteApiGet(url);
1452
- if (item) {
1453
- return await this.decorateOne_(item, params);
1483
+ try {
1484
+ const item = await remoteApiGet(url);
1485
+ if (item) {
1486
+ return await this.decorateOne_(item, params);
1487
+ }
1488
+ } catch (error) {
1489
+ console.log("RemoteService", this.key, "findOne.error");
1454
1490
  }
1455
1491
  return;
1456
1492
  }
@@ -1458,7 +1494,7 @@ var RemoteService = class {
1458
1494
  params.richText = String(params.richText) === "true" ? true : false;
1459
1495
  params.draft = RemoteServiceStrategy.draft;
1460
1496
  params.pagination = false;
1461
- const query = (0, import_bom_core14.qsSerialize)(params);
1497
+ const query = (0, import_bom_core13.qsSerialize)(params);
1462
1498
  const search = query ? `?${query}` : "";
1463
1499
  const url = `/${this.key}${search}`;
1464
1500
  const response = await remoteApiGet(url);
@@ -1469,7 +1505,7 @@ var RemoteService = class {
1469
1505
  params.richText = String(params.richText) === "true" ? true : false;
1470
1506
  params.draft = RemoteServiceStrategy.draft;
1471
1507
  params.pagination = true;
1472
- const query = (0, import_bom_core14.qsSerialize)(params);
1508
+ const query = (0, import_bom_core13.qsSerialize)(params);
1473
1509
  const search = query ? `?${query}` : "";
1474
1510
  const url = `/${this.key}${search}`;
1475
1511
  const response = await remoteApiGet(url);
@@ -1480,13 +1516,15 @@ var RemoteService = class {
1480
1516
  // !!! todo params
1481
1517
  async create(payload) {
1482
1518
  const url = `/${this.key}`;
1483
- const item = await remoteApiPost(url, payload);
1519
+ const result = await remoteApiPost(url, payload);
1520
+ const item = result.doc ? result.doc : result;
1484
1521
  return await this.decorateOne_(item, {});
1485
1522
  }
1486
1523
  // !!! todo params
1487
1524
  async update(payload) {
1488
1525
  const url = `/${this.key}`;
1489
- const item = await remoteApiPut(url, payload);
1526
+ const result = await remoteApiPut(url, payload);
1527
+ const item = result.doc ? result.doc : result;
1490
1528
  return await this.decorateOne_(item, {});
1491
1529
  }
1492
1530
  // !!! todo params
@@ -1498,7 +1536,7 @@ var RemoteService = class {
1498
1536
  }
1499
1537
  }
1500
1538
  };
1501
- const query = (0, import_bom_core14.qsSerialize)(params);
1539
+ const query = (0, import_bom_core13.qsSerialize)(params);
1502
1540
  const search = query ? `?${query}` : "";
1503
1541
  const url = `/${this.key}${search}`;
1504
1542
  const item = await remoteApiDelete(url);
@@ -1678,7 +1716,7 @@ function collectionGet(storePromise) {
1678
1716
  const collection = collections[0];
1679
1717
  const id = collections[1];
1680
1718
  const qs = Object.entries(query).map((kv) => kv.join("=")).join("&");
1681
- const params = (0, import_bom_core15.qsDeserialize)(qs);
1719
+ const params = (0, import_bom_core14.qsDeserialize)(qs);
1682
1720
  if (!COLLECTIONS.includes(collection)) {
1683
1721
  console.error("storeHandler.collectionGet", "method not allowed", collection);
1684
1722
  return response.status(405).send("method not allowed");
@@ -1690,7 +1728,7 @@ function collectionGet(storePromise) {
1690
1728
  return response.status(405).send("method not allowed");
1691
1729
  }
1692
1730
  if (id) {
1693
- const item = await service.findOne((0, import_bom_core15.asEquatable)(id), params);
1731
+ const item = await service.findOne((0, import_bom_core14.asEquatable)(id), params);
1694
1732
  if (item) {
1695
1733
  return response.status(200).json(item);
1696
1734
  } else {
@@ -1810,8 +1848,8 @@ function storeIndexHandler() {
1810
1848
  return apiHandler({
1811
1849
  get: async (request, response) => {
1812
1850
  try {
1813
- const market = import_bom_core15.defaultMarket;
1814
- const locale = import_bom_core15.defaultLocale;
1851
+ const market = import_bom_core14.defaultMarket;
1852
+ const locale = import_bom_core14.defaultLocale;
1815
1853
  if (!Array.isArray(COLLECTIONS) || COLLECTIONS?.length === 0) {
1816
1854
  console.error("apiHome.collectionGet", "collections not found", COLLECTIONS);
1817
1855
  return response.status(405).send("method not allowed");
@@ -2078,10 +2116,38 @@ async function storeApiDelete(url, options = {}) {
2078
2116
  }
2079
2117
 
2080
2118
  // src/vars/vars.handler.ts
2081
- var import_bom_core17 = require("@websolutespa/bom-core");
2119
+ var import_bom_core16 = require("@websolutespa/bom-core");
2120
+
2121
+ // ../models/src/label/label.service.ts
2122
+ async function getLabels(params = {}) {
2123
+ const store = await getStore();
2124
+ const items = await store.label.findMany(params);
2125
+ return items;
2126
+ }
2127
+
2128
+ // ../models/src/locale/locale.service.ts
2129
+ async function getLocales(params = {}) {
2130
+ const store = await getStore();
2131
+ const items = await store.locale.findMany(params);
2132
+ return items;
2133
+ }
2134
+
2135
+ // ../models/src/market/market.service.ts
2136
+ async function getMarkets(params = {}) {
2137
+ const store = await getStore();
2138
+ const items = await store.market.findMany(params);
2139
+ return items;
2140
+ }
2141
+
2142
+ // ../models/src/menu/menu.service.ts
2143
+ async function getMenus(params = {}) {
2144
+ const store = await getStore();
2145
+ const items = await store.menu.findMany(params);
2146
+ return items;
2147
+ }
2082
2148
 
2083
2149
  // ../models/src/route/route.service.ts
2084
- var import_bom_core16 = require("@websolutespa/bom-core");
2150
+ var import_bom_core15 = require("@websolutespa/bom-core");
2085
2151
  async function getRouteLinkTree(market, locale) {
2086
2152
  const store = await getStore();
2087
2153
  const routes = await store.route.findMany({
@@ -2095,7 +2161,7 @@ async function getRouteLinkTree(market, locale) {
2095
2161
  }
2096
2162
  });
2097
2163
  const categories = await store.category.findMany({ market, locale });
2098
- const rootCategory = (0, import_bom_core16.getRootCategory)(categories);
2164
+ const rootCategory = (0, import_bom_core15.getRootCategory)(categories);
2099
2165
  if (rootCategory) {
2100
2166
  const root = categoryToRouteLink(routes, categories, rootCategory, locale);
2101
2167
  return root;
@@ -2103,13 +2169,13 @@ async function getRouteLinkTree(market, locale) {
2103
2169
  return void 0;
2104
2170
  }
2105
2171
  function categoryToRouteLink(routes, categories, category, locale) {
2106
- const route = (0, import_bom_core16.findRouteOfCategory)(routes, category.id);
2172
+ const route = (0, import_bom_core15.findRouteOfCategory)(routes, category.id);
2107
2173
  if (!route) {
2108
2174
  return void 0;
2109
2175
  }
2110
- const rootCategory = (0, import_bom_core16.getRootCategory)(categories);
2176
+ const rootCategory = (0, import_bom_core15.getRootCategory)(categories);
2111
2177
  const childCategories = categories.filter((x) => {
2112
- const parentId = (0, import_bom_core16.asCategoryId)(x.category);
2178
+ const parentId = (0, import_bom_core15.asCategoryId)(x.category);
2113
2179
  return rootCategory && rootCategory.id === category.id ? x.id !== rootCategory.id && (parentId === category.id || !parentId) : parentId === category.id;
2114
2180
  });
2115
2181
  const routeLink = newRouteLink(category, route, locale);
@@ -2121,7 +2187,7 @@ function newRouteLink(category, route, locale) {
2121
2187
  const id = route?.page || category.id;
2122
2188
  const media = category.media || route?.media;
2123
2189
  const schema = route?.schema || category?.schema || "unknown";
2124
- const title = (0, import_bom_core16.localize)(category.title || route?.title || "untitled", locale);
2190
+ const title = (0, import_bom_core15.localize)(category.title || route?.title || "untitled", locale);
2125
2191
  const routeLink = {
2126
2192
  category: category.id,
2127
2193
  href,
@@ -2134,34 +2200,6 @@ function newRouteLink(category, route, locale) {
2134
2200
  return routeLink;
2135
2201
  }
2136
2202
 
2137
- // ../models/src/label/label.service.ts
2138
- async function getLabels(params = {}) {
2139
- const store = await getStore();
2140
- const items = await store.label.findMany(params);
2141
- return items;
2142
- }
2143
-
2144
- // ../models/src/locale/locale.service.ts
2145
- async function getLocales(params = {}) {
2146
- const store = await getStore();
2147
- const items = await store.locale.findMany(params);
2148
- return items;
2149
- }
2150
-
2151
- // ../models/src/market/market.service.ts
2152
- async function getMarkets(params = {}) {
2153
- const store = await getStore();
2154
- const items = await store.market.findMany(params);
2155
- return items;
2156
- }
2157
-
2158
- // ../models/src/menu/menu.service.ts
2159
- async function getMenus(params = {}) {
2160
- const store = await getStore();
2161
- const items = await store.menu.findMany(params);
2162
- return items;
2163
- }
2164
-
2165
2203
  // ../models/src/layout/layout.service.ts
2166
2204
  async function getLayout(market, locale) {
2167
2205
  const markets = await getMarkets({ locale });
@@ -2171,11 +2209,13 @@ async function getLayout(market, locale) {
2171
2209
  const firstLevelRoutes = tree?.items || [];
2172
2210
  const flatTopLevelRoutes = tree ? [tree, ...firstLevelRoutes] : [];
2173
2211
  const topLevelRoutes = flatTopLevelRoutes.reduce((object, routeLink) => {
2174
- object[routeLink.schema] = routeLink;
2212
+ if (!object[routeLink.schema] || routeLink.schema === routeLink.category) {
2213
+ object[routeLink.schema] = routeLink;
2214
+ }
2175
2215
  return object;
2176
2216
  }, {});
2177
2217
  const topLevelHrefs = flatTopLevelRoutes.reduce((object, routeLink) => {
2178
- if (routeLink.href) {
2218
+ if (routeLink.href && !object[routeLink.schema] || routeLink.schema === routeLink.category) {
2179
2219
  object[routeLink.schema] = routeLink.href;
2180
2220
  }
2181
2221
  return object;
@@ -2224,10 +2264,10 @@ function varsHandler() {
2224
2264
  const { locale = defaultLocale3, market = defaultMaket } = request.query || {};
2225
2265
  const layout = typeof locale === "string" && typeof market === "string" ? await getLayout(market, locale) : void 0;
2226
2266
  const info = {
2227
- production: import_bom_core17.isProduction,
2228
- development: import_bom_core17.isDevelopment,
2229
- origin: (0, import_bom_core17.getOrigin)(request.headers),
2230
- host: (0, import_bom_core17.getHost)(request.headers),
2267
+ production: import_bom_core16.isProduction,
2268
+ development: import_bom_core16.isDevelopment,
2269
+ origin: (0, import_bom_core16.getOrigin)(request.headers),
2270
+ host: (0, import_bom_core16.getHost)(request.headers),
2231
2271
  headers: { ...sortKeys(request.headers) },
2232
2272
  env: { ...getFilteredEnv(process.env) },
2233
2273
  layout: { ...sortKeys(layout) }
@@ -2350,6 +2390,7 @@ function varsHandler() {
2350
2390
  MockPageService,
2351
2391
  MockService,
2352
2392
  NextPhase,
2393
+ REMOTE_API_SESSION,
2353
2394
  RemoteMenuService,
2354
2395
  RemotePageService,
2355
2396
  RemoteService,
package/dist/index.mjs CHANGED
@@ -12,20 +12,26 @@ function getLocalApiRequestOptions() {
12
12
  headers: {}
13
13
  };
14
14
  }
15
+ var REMOTE_API_SESSION = {
16
+ token: null
17
+ };
15
18
  function getRemoteApiRequestOptions() {
16
- return {
17
- // mode: 'cors',
18
- headers: {
19
- /**
20
- * guest user api key (users)
21
- */
22
- Authorization: `users API-Key ${process.env.STORE_API_KEY}`
23
- /**
24
- * authenticated end user bearer (end_users)
25
- */
26
- // Authorization: `Bearer ${bearer}`,
27
- }
28
- };
19
+ if (REMOTE_API_SESSION.token) {
20
+ return {
21
+ // mode: 'cors',
22
+ headers: {
23
+ Authorization: `Bearer ${REMOTE_API_SESSION.token}`
24
+ // Authorization: `JWT ${REMOTE_API_SESSION.token}`,
25
+ }
26
+ };
27
+ } else {
28
+ return {
29
+ // mode: 'cors',
30
+ headers: {
31
+ Authorization: `users API-Key ${process.env.STORE_API_KEY}`
32
+ }
33
+ };
34
+ }
29
35
  }
30
36
 
31
37
  // src/api/api.handler.ts
@@ -372,7 +378,9 @@ function decorateMenuRoute_(item) {
372
378
  return decoratedItem;
373
379
  }
374
380
  async function decorateMenuPage_(item, routes, store, params = {}) {
375
- const id = isEquatable(item.page.value) ? item.page.value : item.page.value.id;
381
+ const values = Array.isArray(item.page.value) ? item.page.value : [item.page.value];
382
+ const value = values[0];
383
+ const id = isEquatable(value) ? value : value.id;
376
384
  const route = routes.find(
377
385
  (x) => x.schema === item.page.relationTo && x.page === id
378
386
  );
@@ -406,7 +414,7 @@ async function decorateNav_(store, item, params = {}, routes) {
406
414
  const navs = collectNavs_(item);
407
415
  for (const nav of navs) {
408
416
  const decoratedNav = decorateNav__(nav, routes);
409
- nav.nav = decoratedNav.nav;
417
+ Object.assign(nav, decoratedNav);
410
418
  }
411
419
  return item;
412
420
  }
@@ -436,14 +444,13 @@ function collectNavs_(item, navs = []) {
436
444
  return navs;
437
445
  }
438
446
  function decorateNav__(item, routes) {
439
- const { nav, ...undecorated } = item;
440
- if (nav !== void 0) {
441
- const decorated = { ...undecorated };
447
+ let decoratedNav = item;
448
+ if (item !== void 0) {
442
449
  const route = routes.find(
443
- (x) => x.page === nav.page.value && x.schema === nav.page.relationTo
450
+ (x) => x.page === item.page.value && x.schema === item.page.relationTo
444
451
  );
445
452
  if (route) {
446
- decorated.nav = {
453
+ decoratedNav = {
447
454
  type: "page",
448
455
  id: route.page,
449
456
  href: route.id,
@@ -452,23 +459,17 @@ function decorateNav__(item, routes) {
452
459
  schema: route.schema
453
460
  };
454
461
  }
455
- return decorated;
456
462
  }
457
- return undecorated;
463
+ return decoratedNav;
458
464
  }
459
465
 
460
466
  // src/decorators/optimize.ts
461
- import { isUnresolvedRelation } from "@websolutespa/bom-core";
462
467
  async function optimizeOne_(item) {
463
468
  const validEntries = Object.entries(item).filter(([key, value]) => {
464
469
  switch (key) {
465
470
  case "components":
466
471
  case "meta":
467
472
  return false;
468
- default:
469
- if (isUnresolvedRelation(value) || Array.isArray(value) && value.reduce((p, c) => p && isUnresolvedRelation(c), true)) {
470
- return false;
471
- }
472
473
  }
473
474
  return true;
474
475
  });
@@ -484,7 +485,7 @@ async function optimizeMany_(items) {
484
485
  }
485
486
 
486
487
  // src/decorators/relation.ts
487
- import { isArray as isArray2, isObject as isObject2, isUnresolvedRelation as isUnresolvedRelation2 } from "@websolutespa/bom-core";
488
+ import { isArray as isArray2, isObject as isObject2, isUnresolvedRelation } from "@websolutespa/bom-core";
488
489
  var SERVICE_DEFAULT_DEPTH = 3;
489
490
  async function decorateRelation_(store, item, params = {}) {
490
491
  const depth = params.depth != null ? params.depth : SERVICE_DEFAULT_DEPTH;
@@ -501,7 +502,7 @@ async function decorateRelations_(store, items, params = {}) {
501
502
  return items;
502
503
  }
503
504
  async function collectRelations_(context, item, relations = []) {
504
- if (isUnresolvedRelation2(item)) {
505
+ if (isUnresolvedRelation(item)) {
505
506
  const index = relations.findIndex(
506
507
  (x) => x.relationTo === item.relationTo && x.value === item.value
507
508
  );
@@ -691,6 +692,11 @@ var MockPageService = class extends MockService {
691
692
  decoratedItems = await decorateCategories_(store, decoratedItems, params);
692
693
  decoratedItems = await decorateLocalizables_(decoratedItems, params);
693
694
  decoratedItems = await decorateHrefs_(store, decoratedItems, params);
695
+ decoratedItems = await decorateRelations_(store, decoratedItems, {
696
+ market: params.market,
697
+ locale: params.locale,
698
+ depth: params.depth
699
+ });
694
700
  return decoratedItems;
695
701
  }
696
702
  };
@@ -801,6 +807,28 @@ var staticCollections = [{
801
807
  type: "text"
802
808
  }
803
809
  ]
810
+ }, {
811
+ src: "https://actarian.github.io/cms-i18n-react/api/language.json",
812
+ slug: "i18n_country_zone",
813
+ fields: [
814
+ {
815
+ name: "id",
816
+ type: "text"
817
+ },
818
+ {
819
+ name: "name",
820
+ type: "text",
821
+ localized: true
822
+ },
823
+ {
824
+ name: "englishName",
825
+ type: "text"
826
+ },
827
+ {
828
+ name: "nativeName",
829
+ type: "text"
830
+ }
831
+ ]
804
832
  }, {
805
833
  src: "https://actarian.github.io/cms-i18n-react/api/municipality.json",
806
834
  slug: "i18n_municipality",
@@ -1301,6 +1329,9 @@ function getRemoteApiUrl(pathname) {
1301
1329
  return url;
1302
1330
  }
1303
1331
  async function remoteApiFetch(pathname, options = {}) {
1332
+ if (isBrowser3) {
1333
+ throw "Unauthorized: remote api cannot be fetched client side";
1334
+ }
1304
1335
  const url = getRemoteApiUrl(pathname);
1305
1336
  const apiOptions = merge3({ ...getRemoteApiRequestOptions() }, options);
1306
1337
  console.log("remoteApiFetch", apiOptions.method, url);
@@ -1344,9 +1375,13 @@ var RemoteService = class {
1344
1375
  const query = qsSerialize2(params);
1345
1376
  const search = query ? `?${query}` : "";
1346
1377
  const url = `/${this.key}/${encodeURIComponent(id)}${search}`;
1347
- const item = await remoteApiGet(url);
1348
- if (item) {
1349
- return await this.decorateOne_(item, params);
1378
+ try {
1379
+ const item = await remoteApiGet(url);
1380
+ if (item) {
1381
+ return await this.decorateOne_(item, params);
1382
+ }
1383
+ } catch (error) {
1384
+ console.log("RemoteService", this.key, "findOne.error");
1350
1385
  }
1351
1386
  return;
1352
1387
  }
@@ -1376,13 +1411,15 @@ var RemoteService = class {
1376
1411
  // !!! todo params
1377
1412
  async create(payload) {
1378
1413
  const url = `/${this.key}`;
1379
- const item = await remoteApiPost(url, payload);
1414
+ const result = await remoteApiPost(url, payload);
1415
+ const item = result.doc ? result.doc : result;
1380
1416
  return await this.decorateOne_(item, {});
1381
1417
  }
1382
1418
  // !!! todo params
1383
1419
  async update(payload) {
1384
1420
  const url = `/${this.key}`;
1385
- const item = await remoteApiPut(url, payload);
1421
+ const result = await remoteApiPut(url, payload);
1422
+ const item = result.doc ? result.doc : result;
1386
1423
  return await this.decorateOne_(item, {});
1387
1424
  }
1388
1425
  // !!! todo params
@@ -1976,6 +2013,34 @@ async function storeApiDelete(url, options = {}) {
1976
2013
  // src/vars/vars.handler.ts
1977
2014
  import { getHost, getOrigin, isDevelopment as isDevelopment2, isProduction } from "@websolutespa/bom-core";
1978
2015
 
2016
+ // ../models/src/label/label.service.ts
2017
+ async function getLabels(params = {}) {
2018
+ const store = await getStore();
2019
+ const items = await store.label.findMany(params);
2020
+ return items;
2021
+ }
2022
+
2023
+ // ../models/src/locale/locale.service.ts
2024
+ async function getLocales(params = {}) {
2025
+ const store = await getStore();
2026
+ const items = await store.locale.findMany(params);
2027
+ return items;
2028
+ }
2029
+
2030
+ // ../models/src/market/market.service.ts
2031
+ async function getMarkets(params = {}) {
2032
+ const store = await getStore();
2033
+ const items = await store.market.findMany(params);
2034
+ return items;
2035
+ }
2036
+
2037
+ // ../models/src/menu/menu.service.ts
2038
+ async function getMenus(params = {}) {
2039
+ const store = await getStore();
2040
+ const items = await store.menu.findMany(params);
2041
+ return items;
2042
+ }
2043
+
1979
2044
  // ../models/src/route/route.service.ts
1980
2045
  import { asCategoryId as asCategoryId2, defaultLocale as defaultLocale2, defaultMarket as defaultMarket2, findRouteOfCategory as findRouteOfCategory3, getRootCategory, localize } from "@websolutespa/bom-core";
1981
2046
  async function getRouteLinkTree(market, locale) {
@@ -2030,34 +2095,6 @@ function newRouteLink(category, route, locale) {
2030
2095
  return routeLink;
2031
2096
  }
2032
2097
 
2033
- // ../models/src/label/label.service.ts
2034
- async function getLabels(params = {}) {
2035
- const store = await getStore();
2036
- const items = await store.label.findMany(params);
2037
- return items;
2038
- }
2039
-
2040
- // ../models/src/locale/locale.service.ts
2041
- async function getLocales(params = {}) {
2042
- const store = await getStore();
2043
- const items = await store.locale.findMany(params);
2044
- return items;
2045
- }
2046
-
2047
- // ../models/src/market/market.service.ts
2048
- async function getMarkets(params = {}) {
2049
- const store = await getStore();
2050
- const items = await store.market.findMany(params);
2051
- return items;
2052
- }
2053
-
2054
- // ../models/src/menu/menu.service.ts
2055
- async function getMenus(params = {}) {
2056
- const store = await getStore();
2057
- const items = await store.menu.findMany(params);
2058
- return items;
2059
- }
2060
-
2061
2098
  // ../models/src/layout/layout.service.ts
2062
2099
  async function getLayout(market, locale) {
2063
2100
  const markets = await getMarkets({ locale });
@@ -2067,11 +2104,13 @@ async function getLayout(market, locale) {
2067
2104
  const firstLevelRoutes = tree?.items || [];
2068
2105
  const flatTopLevelRoutes = tree ? [tree, ...firstLevelRoutes] : [];
2069
2106
  const topLevelRoutes = flatTopLevelRoutes.reduce((object, routeLink) => {
2070
- object[routeLink.schema] = routeLink;
2107
+ if (!object[routeLink.schema] || routeLink.schema === routeLink.category) {
2108
+ object[routeLink.schema] = routeLink;
2109
+ }
2071
2110
  return object;
2072
2111
  }, {});
2073
2112
  const topLevelHrefs = flatTopLevelRoutes.reduce((object, routeLink) => {
2074
- if (routeLink.href) {
2113
+ if (routeLink.href && !object[routeLink.schema] || routeLink.schema === routeLink.category) {
2075
2114
  object[routeLink.schema] = routeLink.href;
2076
2115
  }
2077
2116
  return object;
@@ -2245,6 +2284,7 @@ export {
2245
2284
  MockPageService,
2246
2285
  MockService,
2247
2286
  NextPhase,
2287
+ REMOTE_API_SESSION,
2248
2288
  RemoteMenuService,
2249
2289
  RemotePageService,
2250
2290
  RemoteService,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@websolutespa/bom-mixer-store",
3
- "version": "1.7.9",
3
+ "version": "1.8.1",
4
4
  "description": "Mixer Store module of the BOM Repository",
5
5
  "keywords": [
6
6
  "bom",
@@ -27,7 +27,7 @@
27
27
  },
28
28
  "peerDependencies": {
29
29
  "@websolutespa/bom-core": "*",
30
- "iron-session": ">= 6.2.1",
30
+ "iron-session": ">= 8.0.3",
31
31
  "next": ">= 14.1.4"
32
32
  },
33
33
  "devDependencies": {
package/src/api/api.ts CHANGED
@@ -2,10 +2,6 @@ import { FetchRequestOptions } from '@websolutespa/bom-core';
2
2
 
3
3
  export type ApiRequestOptions = FetchRequestOptions;
4
4
 
5
- /**
6
- * !!! todo: evaluate authenticated end user bearer
7
- */
8
-
9
5
  export function getLocalApiRequestOptions(): ApiRequestOptions {
10
6
  return {
11
7
  headers: {
@@ -13,18 +9,31 @@ export function getLocalApiRequestOptions(): ApiRequestOptions {
13
9
  };
14
10
  }
15
11
 
12
+ export const REMOTE_API_SESSION: { token: string | null } = {
13
+ token: null,
14
+ };
15
+
16
16
  export function getRemoteApiRequestOptions(): ApiRequestOptions {
17
- return {
18
- // mode: 'cors',
19
- headers: {
20
- /**
21
- * guest user api key (users)
22
- */
23
- Authorization: `users API-Key ${process.env.STORE_API_KEY}`,
24
- /**
25
- * authenticated end user bearer (end_users)
26
- */
27
- // Authorization: `Bearer ${bearer}`,
28
- },
29
- };
17
+ if (REMOTE_API_SESSION.token) {
18
+ /**
19
+ * authenticated end user JWT token bearer (end_users)
20
+ */
21
+ return {
22
+ // mode: 'cors',
23
+ headers: {
24
+ Authorization: `Bearer ${REMOTE_API_SESSION.token}`,
25
+ // Authorization: `JWT ${REMOTE_API_SESSION.token}`,
26
+ },
27
+ };
28
+ } else {
29
+ /**
30
+ * guest user api key (users)
31
+ */
32
+ return {
33
+ // mode: 'cors',
34
+ headers: {
35
+ Authorization: `users API-Key ${process.env.STORE_API_KEY}`,
36
+ },
37
+ };
38
+ }
30
39
  }
@@ -341,7 +341,9 @@ async function decorateMenuPage_(
341
341
  store: IStore,
342
342
  params: QueryParams = {}
343
343
  ): Promise<IMenuItem> {
344
- const id = (isEquatable(item.page.value) ? item.page.value : item.page.value.id);
344
+ const values = Array.isArray(item.page.value) ? item.page.value : [item.page.value];
345
+ const value = values[0]; // !!!
346
+ const id = isEquatable(value) ? value : value.id;
345
347
  const route = routes.find(x =>
346
348
  x.schema === item.page.relationTo &&
347
349
  x.page === id
@@ -1,4 +1,4 @@
1
- import { IDecoratedNav, IEquatable, IMenuPage, IRoute, ISchema, IStore, IUndecoratedNav, QueryParams, isArray, isObject, isUndecoratedNav } from '@websolutespa/bom-core';
1
+ import { IDecoratedNav, IEquatable, IRoute, ISchema, IStore, IUndecoratedNav, QueryParams, isArray, isObject, isUndecoratedNav } from '@websolutespa/bom-core';
2
2
 
3
3
  export async function decorateNav_<T extends ISchema = ISchema>(store: IStore, item: T, params: QueryParams = {}, routes?: IRoute[]): Promise<T> {
4
4
  if (!routes) {
@@ -12,7 +12,8 @@ export async function decorateNav_<T extends ISchema = ISchema>(store: IStore, i
12
12
  const navs = collectNavs_(item);
13
13
  for (const nav of navs) {
14
14
  const decoratedNav = decorateNav__(nav, routes);
15
- (nav as IDecoratedNav<T>).nav = decoratedNav.nav;
15
+ Object.assign(nav, decoratedNav);
16
+ // (nav as IDecoratedNav<T>).nav = decoratedNav.nav;
16
17
  }
17
18
  return item;
18
19
  }
@@ -31,8 +32,8 @@ export async function decorateNavs_<T extends ISchema = ISchema>(store: IStore,
31
32
  }
32
33
 
33
34
  // collecting navs recursively
34
- function collectNavs_<T>(item: unknown, navs: IUndecoratedNav<T>[] = []): IUndecoratedNav<T>[] {
35
- if (isUndecoratedNav<T>(item)) {
35
+ function collectNavs_(item: unknown, navs: IUndecoratedNav[] = []): IUndecoratedNav[] {
36
+ if (isUndecoratedNav(item)) {
36
37
  navs.push(item);
37
38
  }
38
39
  // console.log(item, isUndecoratedNav<T>(item));
@@ -46,16 +47,15 @@ function collectNavs_<T>(item: unknown, navs: IUndecoratedNav<T>[] = []): IUndec
46
47
  return navs;
47
48
  }
48
49
 
49
- function decorateNav__<T>(item: IUndecoratedNav<T>, routes: IRoute[]): IDecoratedNav<T> {
50
- const { nav, ...undecorated } = item;
51
- if (nav !== undefined) {
52
- const decorated = { ...undecorated } as { nav?: IMenuPage };
50
+ function decorateNav__(item: IUndecoratedNav, routes: IRoute[]): IDecoratedNav {
51
+ let decoratedNav = item as unknown as IDecoratedNav;
52
+ if (item !== undefined) {
53
53
  const route = routes.find(x =>
54
- x.page === (nav.page.value as unknown as IEquatable) &&
55
- x.schema === nav.page.relationTo
54
+ x.page === (item.page.value as unknown as IEquatable) &&
55
+ x.schema === item.page.relationTo
56
56
  );
57
57
  if (route) {
58
- decorated.nav = {
58
+ decoratedNav = {
59
59
  type: 'page',
60
60
  id: route.page,
61
61
  href: route.id,
@@ -64,7 +64,6 @@ function decorateNav__<T>(item: IUndecoratedNav<T>, routes: IRoute[]): IDecorate
64
64
  schema: route.schema,
65
65
  };
66
66
  }
67
- return decorated as IDecoratedNav<T>;
68
67
  }
69
- return undecorated as IDecoratedNav<T>;
68
+ return decoratedNav;
70
69
  }
@@ -1,4 +1,4 @@
1
- import { ICategorized, isUnresolvedRelation } from '@websolutespa/bom-core';
1
+ import { ICategorized } from '@websolutespa/bom-core';
2
2
 
3
3
  export async function optimizeOne_<T extends ICategorized = ICategorized>(item: T): Promise<T> {
4
4
  const validEntries = Object.entries(item).filter(([key, value]) => {
@@ -6,6 +6,7 @@ export async function optimizeOne_<T extends ICategorized = ICategorized>(item:
6
6
  case 'components':
7
7
  case 'meta':
8
8
  return false;
9
+ /*
9
10
  default:
10
11
  if (
11
12
  isUnresolvedRelation(value) ||
@@ -16,6 +17,7 @@ export async function optimizeOne_<T extends ICategorized = ICategorized>(item:
16
17
  ) {
17
18
  return false;
18
19
  }
20
+ */
19
21
  }
20
22
  return true;
21
23
  });
package/src/index.ts CHANGED
@@ -10,7 +10,6 @@ export * from './mock/mock.api';
10
10
  export * from './mock/mock.handler';
11
11
  export * from './mock/mock.service';
12
12
  export * from './mock/mock.store';
13
- // export * from './session/session.handler';
14
13
  export * from './remote/remote-menu.service';
15
14
  export * from './remote/remote-page.service';
16
15
  export * from './remote/remote.api';
@@ -1,5 +1,5 @@
1
1
  import { ICategorized, QueryParams } from '@websolutespa/bom-core';
2
- import { decorateCategories_, decorateCategory_, decorateHref_, decorateHrefs_, decorateLocalizable_, decorateLocalizables_, decorateNav_, decorateRelation_, optimizeMany_ } from '../decorators';
2
+ import { decorateCategories_, decorateCategory_, decorateHref_, decorateHrefs_, decorateLocalizable_, decorateLocalizables_, decorateNav_, decorateRelation_, decorateRelations_, optimizeMany_ } from '../decorators';
3
3
  import { MockService } from './mock.service';
4
4
 
5
5
  export class MockPageService<T extends ICategorized = ICategorized> extends MockService<T> {
@@ -26,14 +26,14 @@ export class MockPageService<T extends ICategorized = ICategorized> extends Mock
26
26
  decoratedItems = await decorateCategories_<B>(store, decoratedItems, params);
27
27
  decoratedItems = await decorateLocalizables_<B>(decoratedItems, params);
28
28
  decoratedItems = await decorateHrefs_<B>(store, decoratedItems, params);
29
- /*
30
- // !!! optimization for index listing
31
- decoratedItems = await decorateNavs_<B>(store, decoratedItems, params);
32
29
  decoratedItems = await decorateRelations_<B>(store, decoratedItems, {
33
30
  market: params.market,
34
31
  locale: params.locale,
35
32
  depth: params.depth,
36
33
  });
34
+ /*
35
+ // !!! optimization for index listing
36
+ decoratedItems = await decorateNavs_<B>(store, decoratedItems, params);
37
37
  */
38
38
  return decoratedItems;
39
39
  }
@@ -17,9 +17,13 @@ export function getRemoteApiUrl(pathname: string): string {
17
17
  }
18
18
 
19
19
  export async function remoteApiFetch<T = unknown>(pathname: string, options: ApiRequestOptions = {}): Promise<T> {
20
+ if (isBrowser) {
21
+ throw 'Unauthorized: remote api cannot be fetched client side';
22
+ }
20
23
  const url = getRemoteApiUrl(pathname);
21
24
  const apiOptions = merge({ ...getRemoteApiRequestOptions() }, options);
22
25
  console.log('remoteApiFetch', apiOptions.method, url);
26
+ // console.log('remoteApiFetch', 'Authorization', apiOptions.headers?.Authorization);
23
27
  const apiResponse = await httpFetch(url, apiOptions);
24
28
  return apiResponse;
25
29
  }
@@ -32,9 +32,13 @@ export class RemoteService<T extends IEntity = IEntity> implements IQuerable<T>
32
32
  const search = query ? `?${query}` : '';
33
33
  const url = `/${this.key}/${encodeURIComponent(id)}${search}`;
34
34
  // console.log('RemoteService', this.key, 'findOne', url);
35
- const item = await remoteApiGet<B>(url);
36
- if (item) {
37
- return await this.decorateOne_(item, params);
35
+ try {
36
+ const item = await remoteApiGet<B>(url);
37
+ if (item) {
38
+ return await this.decorateOne_(item, params);
39
+ }
40
+ } catch (error) {
41
+ console.log('RemoteService', this.key, 'findOne.error');
38
42
  }
39
43
  return;
40
44
  }
@@ -70,7 +74,8 @@ export class RemoteService<T extends IEntity = IEntity> implements IQuerable<T>
70
74
  async create<B extends T = T>(payload: Omit<B, 'id'>): Promise<B> {
71
75
  const url = `/${this.key}`;
72
76
  // console.log('RemoteService', this.key, 'create', url);
73
- const item = await remoteApiPost<B>(url, payload);
77
+ const result = await remoteApiPost<B | { doc: B }>(url, payload);
78
+ const item = (result.doc ? result.doc : result) as B;
74
79
  return await this.decorateOne_(item, {});
75
80
  }
76
81
 
@@ -78,7 +83,8 @@ export class RemoteService<T extends IEntity = IEntity> implements IQuerable<T>
78
83
  async update<B extends T = T>(payload: Partial<B>): Promise<B> {
79
84
  const url = `/${this.key}`;
80
85
  // console.log('RemoteService', this.key, 'update', url);
81
- const item = await remoteApiPut<B>(url, payload);
86
+ const result = await remoteApiPut<B | { doc: B }>(url, payload);
87
+ const item = (result.doc ? result.doc : result) as B;
82
88
  return await this.decorateOne_(item, {});
83
89
  }
84
90
 
@@ -90,6 +90,28 @@ export const staticCollections: StaticServiceConfig[] = [{
90
90
  type: 'text',
91
91
  },
92
92
  ],
93
+ }, {
94
+ src: 'https://actarian.github.io/cms-i18n-react/api/language.json',
95
+ slug: 'i18n_country_zone',
96
+ fields: [
97
+ {
98
+ name: 'id',
99
+ type: 'text',
100
+ },
101
+ {
102
+ name: 'name',
103
+ type: 'text',
104
+ localized: true,
105
+ },
106
+ {
107
+ name: 'englishName',
108
+ type: 'text',
109
+ },
110
+ {
111
+ name: 'nativeName',
112
+ type: 'text',
113
+ },
114
+ ],
93
115
  }, {
94
116
  src: 'https://actarian.github.io/cms-i18n-react/api/municipality.json',
95
117
  slug: 'i18n_municipality',
@@ -13,13 +13,13 @@ const getFilteredEnv = (env: Record<string, unknown>): Record<string, unknown> =
13
13
  ));
14
14
  entries.sort();
15
15
  return Object.fromEntries(entries);
16
- }
16
+ };
17
17
 
18
18
  const sortKeys = (object?: Record<string, unknown>): Record<string, unknown> => {
19
19
  const entries = Object.entries(object || {});
20
20
  entries.sort();
21
21
  return Object.fromEntries(entries);
22
- }
22
+ };
23
23
 
24
24
  export function varsHandler() {
25
25
  return apiHandler({
@@ -43,7 +43,7 @@ export function varsHandler() {
43
43
  headers: { ...sortKeys(request.headers) },
44
44
  env: { ...getFilteredEnv(process.env) },
45
45
  layout: { ...sortKeys(layout) },
46
- }
46
+ };
47
47
  if (!(request.headers.accept?.includes('text/html'))) {
48
48
  return response.status(200).json(info);
49
49
  }
@@ -1,61 +0,0 @@
1
- import { httpDelete, httpGet, httpPost } from '@websolutespa/bom-core';
2
- import { apiHandler } from '@websolutespa/bom-mixer-store';
3
- import { IronSessionOptions } from 'iron-session/edge';
4
- import { withIronSessionApiRoute } from 'iron-session/next';
5
- import { NextApiRequest, NextApiResponse } from 'next';
6
- import { StateStorage } from 'zustand/middleware';
7
-
8
- function sessionGet(request: NextApiRequest, response: NextApiResponse<string | null>) {
9
- const { key } = request.query;
10
- const session: { [key: string]: string | null } = request.session as any;
11
- if (session[key as string]) {
12
- response.status(200).json(session[key as string]);
13
- } else {
14
- response.status(200).json(null);
15
- }
16
- }
17
-
18
- async function sessionPost(request: NextApiRequest, response: NextApiResponse<null>) {
19
- const { key } = request.query;
20
- const body = request.body;
21
- const session: { [key: string]: string | null } = request.session as any;
22
- // console.log('body', body);
23
- session[key as string] = body.value;
24
- // console.log('session', session);
25
- await request.session.save();
26
- response.status(200).json(null);
27
- }
28
-
29
- async function sessionDelete(request: NextApiRequest, response: NextApiResponse<null>) {
30
- const { key } = request.query;
31
- const session: { [key: string]: string | null } = request.session as any;
32
- session[key as string] = null;
33
- await request.session.save();
34
- response.status(200).json(null);
35
- }
36
-
37
- export type ISessionHandler = (request: NextApiRequest, response: NextApiResponse) => Promise<void>;
38
-
39
- export function sessionHandler<T extends {}>(sessionOptions: IronSessionOptions) {
40
- return apiHandler({
41
- get: withIronSessionApiRoute(sessionGet, sessionOptions) as ISessionHandler,
42
- post: withIronSessionApiRoute(sessionPost, sessionOptions) as ISessionHandler,
43
- delete: withIronSessionApiRoute(sessionDelete, sessionOptions) as ISessionHandler,
44
- });
45
- }
46
-
47
- export const IronSessionStorage: StateStorage = {
48
- getItem: async (name: string) => {
49
- const value = await httpGet(`/api/__session/${name}`);
50
- // console.log('IronSessionStorage.getItem', name, value);
51
- return value;
52
- },
53
- setItem: async (name: string, value: string) => {
54
- // console.log('IronSessionStorage.setItem', name, { cart: value });
55
- await httpPost(`/api/__session/${name}`, { value });
56
- },
57
- removeItem: async (name: string) => {
58
- // console.log('IronSessionStorage.removeItem', name);
59
- await httpDelete(`/api/__session/${name}`);
60
- },
61
- };