@websolutespa/bom-mixer-store 1.7.2 → 1.7.4

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,21 @@
1
1
  # @websolutespa/bom-mixer-store
2
2
 
3
+ ## 1.7.4
4
+
5
+ ### Patch Changes
6
+
7
+ - Added: varsHandler
8
+ - Updated dependencies
9
+ - @websolutespa/bom-core@1.7.7
10
+
11
+ ## 1.7.3
12
+
13
+ ### Patch Changes
14
+
15
+ - Updating: dependencies
16
+ - Updated dependencies
17
+ - @websolutespa/bom-core@1.7.3
18
+
3
19
  ## 1.7.2
4
20
 
5
21
  ### Patch Changes
package/dist/index.d.ts CHANGED
@@ -1,16 +1,17 @@
1
1
  import { FetchRequestOptions, ICategorized, IStore, QueryParams, ICategory, ISchema, IUndecoratedMenu, IMenu, IRoute, IEquatable, IEntity, JsonService, IMemoryStore, IQuerable, IPagedResult } from '@websolutespa/bom-core';
2
2
  import { NextApiRequest, NextApiResponse } from 'next';
3
3
  import { NextRequest } from 'next/server';
4
+ import * as _websolutespa_bom_mixer_store from '@websolutespa/bom-mixer-store';
4
5
 
5
6
  type ApiRequestOptions = FetchRequestOptions;
6
7
  declare const defaultApiRequestOptions: ApiRequestOptions;
7
8
  declare function getDefaultApiRequestOptions(): ApiRequestOptions;
8
9
 
9
10
  type ICrudMethod = 'get' | 'post' | 'put' | 'patch' | 'delete' | string;
10
- type IHandler = (request: NextApiRequest, response: NextApiResponse) => Promise<any>;
11
+ type IHandler<T = any> = (request: NextApiRequest, response: NextApiResponse<T>) => Promise<NextApiResponse<T> | void>;
11
12
  type IApiHandler = Record<ICrudMethod, IHandler>;
12
- declare function apiHandler(handler: IApiHandler): any;
13
- declare function errorHandler(error: any, response: NextApiResponse): Promise<any> | void;
13
+ declare function apiHandler<T = any>(handler: IApiHandler): IHandler<T>;
14
+ declare function errorHandler(error: any, response: NextApiResponse): NextApiResponse | void;
14
15
 
15
16
  declare function fromCache<T = unknown>(callback: () => Promise<T>, key?: string): Promise<T>;
16
17
 
@@ -117,7 +118,7 @@ declare function mockApiPut<T = unknown>(url: string, payload: unknown, options?
117
118
  declare function mockApiPatch<T = unknown>(url: string, payload: unknown, options?: ApiRequestOptions): Promise<T>;
118
119
  declare function mockApiDelete<T = unknown>(url: string, options?: ApiRequestOptions): Promise<T>;
119
120
 
120
- declare function mockHandler(): any;
121
+ declare function mockHandler(): IHandler<any>;
121
122
 
122
123
  declare function getMockStoreFromData_<T extends IStore>(data?: IMemoryStore): T;
123
124
  declare function getMockStore<T extends IStore = IStore>(): Promise<T>;
@@ -225,15 +226,17 @@ declare function storeApiPut<T = unknown>(url: string, payload: unknown, options
225
226
  declare function storeApiPatch<T = unknown>(url: string, payload: unknown, options?: ApiRequestOptions): Promise<T>;
226
227
  declare function storeApiDelete<T = unknown>(url: string, options?: ApiRequestOptions): Promise<T>;
227
228
 
228
- declare function storeHandler<T extends IStore>(storePromise?: () => Promise<T>): any;
229
+ declare function storeHandler<T extends IStore>(storePromise?: () => Promise<T>): IHandler<any>;
229
230
  declare function collectionGet<T extends IStore>(storePromise: () => Promise<T>): (request: NextApiRequest, response: NextApiResponse) => Promise<void>;
230
231
  declare function collectionPost<T extends IStore>(storePromise: () => Promise<T>): (request: NextApiRequest, response: NextApiResponse) => Promise<void>;
231
232
  declare function collectionPatch<T extends IStore>(storePromise: () => Promise<T>): (request: NextApiRequest, response: NextApiResponse) => Promise<void>;
232
233
  declare function collectionDelete<T extends IStore>(storePromise: () => Promise<T>): (request: NextApiRequest, response: NextApiResponse) => Promise<void>;
233
234
  declare function routePost(store: IStore, request: NextApiRequest, response: NextApiResponse): Promise<void>;
234
- declare function storeIndexHandler(): any;
235
+ declare function storeIndexHandler(): IHandler<any>;
235
236
  declare function findRoute(store: IStore, pathname: string, href: string, hrefBeforeRedirect: string | null): Promise<IRoute | undefined>;
236
237
 
237
238
  declare function getStore<T extends IStore>(): Promise<T>;
238
239
 
239
- 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_, defaultApiRequestOptions, errorHandler, findRoute, fromCache, getDefaultApiRequestOptions, getLocalApiUrl, getMockStore, getMockStoreFromData_, 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 };
240
+ declare function varsHandler(): _websolutespa_bom_mixer_store.IHandler<any>;
241
+
242
+ 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_, defaultApiRequestOptions, errorHandler, findRoute, fromCache, getDefaultApiRequestOptions, getLocalApiUrl, getMockStore, getMockStoreFromData_, 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
@@ -115,7 +115,8 @@ __export(src_exports, {
115
115
  storeCacheDuration: () => storeCacheDuration,
116
116
  storeHandler: () => storeHandler,
117
117
  storeIndexHandler: () => storeIndexHandler,
118
- storeStrategy: () => storeStrategy
118
+ storeStrategy: () => storeStrategy,
119
+ varsHandler: () => varsHandler
119
120
  });
120
121
  module.exports = __toCommonJS(src_exports);
121
122
 
@@ -1000,7 +1001,7 @@ var NextPhase = /* @__PURE__ */ ((NextPhase2) => {
1000
1001
  })(NextPhase || {});
1001
1002
  function getNextPhase() {
1002
1003
  let nextPhase2 = "phase-export" /* Export */;
1003
- if (process && process.env.NEXT_PHASE) {
1004
+ if (typeof process !== "undefined" && process.env.NEXT_PHASE) {
1004
1005
  nextPhase2 = process.env.NEXT_PHASE;
1005
1006
  }
1006
1007
  return nextPhase2;
@@ -1013,7 +1014,7 @@ var BuildStrategy = /* @__PURE__ */ ((BuildStrategy2) => {
1013
1014
  })(BuildStrategy || {});
1014
1015
  function getBuildStrategy() {
1015
1016
  let buildStrategy2 = "static" /* Static */;
1016
- if (process && process.env.BUILD_STRATEGY) {
1017
+ if (typeof process !== "undefined" && process.env.BUILD_STRATEGY) {
1017
1018
  buildStrategy2 = process.env.BUILD_STRATEGY;
1018
1019
  }
1019
1020
  return buildStrategy2;
@@ -1028,7 +1029,7 @@ var StoreStrategy = /* @__PURE__ */ ((StoreStrategy2) => {
1028
1029
  })(StoreStrategy || {});
1029
1030
  function getStoreStrategy() {
1030
1031
  let storeStrategy2 = "mock" /* Mock */;
1031
- if (process && process.env.STORE_STRATEGY) {
1032
+ if (typeof process !== "undefined" && process.env.STORE_STRATEGY) {
1032
1033
  storeStrategy2 = process.env.STORE_STRATEGY;
1033
1034
  }
1034
1035
  return storeStrategy2;
@@ -1036,7 +1037,7 @@ function getStoreStrategy() {
1036
1037
  var storeStrategy = getStoreStrategy();
1037
1038
  function getStoreCacheDuration() {
1038
1039
  let storeCacheDuration2 = 1 * 60 * 1e3;
1039
- if (process && process.env.STORE_CACHE_DURATION) {
1040
+ if (typeof process !== "undefined" && process.env.STORE_CACHE_DURATION) {
1040
1041
  storeCacheDuration2 = parseInt(process.env.STORE_CACHE_DURATION);
1041
1042
  }
1042
1043
  return storeCacheDuration2;
@@ -2028,6 +2029,271 @@ async function storeApiPatch(url, payload, options = {}) {
2028
2029
  async function storeApiDelete(url, options = {}) {
2029
2030
  return await storeApiFetch(url, { ...options, method: "DELETE" });
2030
2031
  }
2032
+
2033
+ // src/vars/vars.handler.ts
2034
+ var import_bom_core16 = require("@websolutespa/bom-core");
2035
+
2036
+ // ../models/src/route/route.service.ts
2037
+ var import_bom_core15 = require("@websolutespa/bom-core");
2038
+ async function getRouteLinkTree(market, locale) {
2039
+ const store = await getStore();
2040
+ const routes = await store.route.findMany({
2041
+ where: {
2042
+ market: {
2043
+ equals: market
2044
+ },
2045
+ locale: {
2046
+ equals: locale
2047
+ }
2048
+ }
2049
+ });
2050
+ const categories = await store.category.findMany();
2051
+ const rootCategory = (0, import_bom_core15.getRootCategory)(categories);
2052
+ if (rootCategory) {
2053
+ const root = categoryToRouteLink(routes, categories, rootCategory, locale);
2054
+ return root;
2055
+ }
2056
+ return void 0;
2057
+ }
2058
+ function categoryToRouteLink(routes, categories, category, locale) {
2059
+ const route = routes.find(
2060
+ (r) => r.category === category.id && r.isDefault
2061
+ );
2062
+ if (!route) {
2063
+ return void 0;
2064
+ }
2065
+ const rootCategory = (0, import_bom_core15.getRootCategory)(categories);
2066
+ const childCategories = categories.filter((x) => {
2067
+ const parentId = x.category ? (0, import_bom_core15.asCategoryId)(x.category) : null;
2068
+ return rootCategory && rootCategory.id === category.id ? x.id !== rootCategory.id && (parentId === category.id || !parentId) : parentId === category.id;
2069
+ });
2070
+ const routeLink = newRouteLink(category, route, locale);
2071
+ routeLink.items = childCategories.map((x) => categoryToRouteLink(routes, categories, x, locale)).filter((x) => x !== void 0);
2072
+ return routeLink;
2073
+ }
2074
+ function newRouteLink(category, route, locale) {
2075
+ const href = route && route.id ? route.id.toString() : "/";
2076
+ const id = route?.page || category.id;
2077
+ const media = category.media || route?.media;
2078
+ const schema = route?.schema || category?.schema || "unknown";
2079
+ const title = (0, import_bom_core15.localize)(category.title || route?.title || "untitled", locale);
2080
+ const routeLink = {
2081
+ category: category.id,
2082
+ href,
2083
+ id,
2084
+ items: [],
2085
+ media,
2086
+ schema,
2087
+ title
2088
+ };
2089
+ return routeLink;
2090
+ }
2091
+
2092
+ // ../models/src/label/label.service.ts
2093
+ async function getLabels(params = {}) {
2094
+ const store = await getStore();
2095
+ const items = await store.label.findMany(params);
2096
+ return items;
2097
+ }
2098
+
2099
+ // ../models/src/locale/locale.service.ts
2100
+ async function getLocales(params = {}) {
2101
+ const store = await getStore();
2102
+ const items = await store.locale.findMany(params);
2103
+ return items;
2104
+ }
2105
+
2106
+ // ../models/src/market/market.service.ts
2107
+ async function getMarkets(params = {}) {
2108
+ const store = await getStore();
2109
+ const items = await store.market.findMany(params);
2110
+ return items;
2111
+ }
2112
+
2113
+ // ../models/src/menu/menu.service.ts
2114
+ async function getMenus(params = {}) {
2115
+ const store = await getStore();
2116
+ const items = await store.menu.findMany(params);
2117
+ return items;
2118
+ }
2119
+
2120
+ // ../models/src/layout/layout.service.ts
2121
+ async function getLayout(market, locale) {
2122
+ const markets = await getMarkets({ locale });
2123
+ const locales = await getLocales({ locale });
2124
+ const labels = await getLabels({ locale });
2125
+ const tree = await getRouteLinkTree(market, locale);
2126
+ const firstLevelRoutes = tree?.items || [];
2127
+ const flatTopLevelRoutes = tree ? [tree, ...firstLevelRoutes] : [];
2128
+ const topLevelRoutes = flatTopLevelRoutes.reduce((object, routeLink) => {
2129
+ object[routeLink.schema] = routeLink;
2130
+ return object;
2131
+ }, {});
2132
+ const topLevelHrefs = flatTopLevelRoutes.reduce((object, routeLink) => {
2133
+ if (routeLink.href) {
2134
+ object[routeLink.schema] = routeLink.href;
2135
+ }
2136
+ return object;
2137
+ }, {});
2138
+ const menu = {};
2139
+ const menus = await getMenus({ market, locale });
2140
+ menus.forEach((x) => {
2141
+ menu[x.id] = x;
2142
+ });
2143
+ return {
2144
+ labels,
2145
+ locale,
2146
+ locales,
2147
+ market,
2148
+ markets,
2149
+ menu,
2150
+ topLevelHrefs,
2151
+ topLevelRoutes,
2152
+ tree
2153
+ };
2154
+ }
2155
+
2156
+ // src/vars/vars.handler.ts
2157
+ var DISALLOWED_KEYS = [
2158
+ "__NEXT_PRIVATE_STANDALONE_CONFIG"
2159
+ ];
2160
+ var getFilteredEnv = (env) => {
2161
+ const entries = Object.entries(env).filter(([k, v]) => !DISALLOWED_KEYS.includes(k) && typeof v === "string");
2162
+ entries.sort();
2163
+ return Object.fromEntries(entries);
2164
+ };
2165
+ var sortKeys = (object) => {
2166
+ const entries = Object.entries(object || {});
2167
+ entries.sort();
2168
+ return Object.fromEntries(entries);
2169
+ };
2170
+ function varsHandler() {
2171
+ return apiHandler({
2172
+ options: async (request, response) => {
2173
+ response.status(200).end();
2174
+ },
2175
+ get: async (request, response) => {
2176
+ try {
2177
+ const defaultLocale3 = process.env.DEFAULT_LOCALE || "it";
2178
+ const defaultMaket = process.env.DEFAULT_MARKET || "ww";
2179
+ const { locale = defaultLocale3, market = defaultMaket } = request.query || {};
2180
+ const layout = typeof locale === "string" && typeof market === "string" ? await getLayout(market, locale) : void 0;
2181
+ const info = {
2182
+ production: import_bom_core16.isProduction,
2183
+ development: import_bom_core16.isDevelopment,
2184
+ origin: (0, import_bom_core16.getOrigin)(request.headers),
2185
+ host: (0, import_bom_core16.getHost)(request.headers),
2186
+ headers: { ...sortKeys(request.headers) },
2187
+ env: { ...getFilteredEnv(process.env) },
2188
+ layout: { ...sortKeys(layout) }
2189
+ };
2190
+ if (!request.headers.accept?.includes("text/html")) {
2191
+ return response.status(200).json(info);
2192
+ }
2193
+ response.status(200).send(`<!DOCTYPE html>
2194
+ <html>
2195
+ <head>
2196
+ <meta charSet="utf-8"/>
2197
+ <style>
2198
+ html, body {
2199
+ background: #282828;
2200
+ color: #7cacf8;
2201
+ }
2202
+ body {
2203
+ padding: 0;
2204
+ margin: 0;
2205
+ font-family: monospace;
2206
+ font-size: 14px;
2207
+ line-height: 1.16;
2208
+ font-weight: 100;
2209
+ }
2210
+ json-viewer {
2211
+ padding: 20px;
2212
+ min-height: 100vh;
2213
+ box-sizing: border-box;
2214
+ line-height: 1.2;
2215
+ --background-color: #282828;
2216
+ --color: #e3e3e3;
2217
+ --property-color: #7cacf8;
2218
+ --string-color: #53d5fb;
2219
+ --number-color: #7b80ff;
2220
+ --boolean-color: #9980ff;
2221
+ --null-color: #6f6f6f;
2222
+ --preview-color: #8f8f8f;
2223
+ --highlight-color: #7b0000;
2224
+ --font-family: monospace;
2225
+ --font-size: 14px;
2226
+ --indent-size: 1em;
2227
+ --indentguide-size: 1px;
2228
+ --indentguide-style: solid;
2229
+ --indentguide-color: #333;
2230
+ --indentguide-color-active: #666;
2231
+ --indentguide: var(--indentguide-size) var(--indentguide-style) var(--indentguide-color);
2232
+ --indentguide-active: var(--indentguide-size) var(--indentguide-style) var(--indentguide-color-active);
2233
+ }
2234
+
2235
+ :root {
2236
+ --scrollbar-size: 8px;
2237
+ --scrollbar-border-radius: 2px;
2238
+ --scrollbar-track-color: transparent;
2239
+ --scrollbar-track-hover-color: transparent;
2240
+ --scrollbar-thumb-color: #888888;
2241
+ --scrollbar-thumb-hover-color: #aaaaaa;
2242
+ }
2243
+
2244
+ ::-webkit-scrollbar {
2245
+ width: var(--scrollbar-size);
2246
+ height: var(--scrollbar-size);
2247
+ border-radius: 0;
2248
+ }
2249
+
2250
+ ::-webkit-scrollbar-button {
2251
+ display: none;
2252
+ }
2253
+
2254
+ ::-webkit-scrollbar-button:hover {
2255
+ display: none;
2256
+ }
2257
+
2258
+ ::-webkit-scrollbar-thumb {
2259
+ background-color: var(--scrollbar-thumb-color);
2260
+ box-shadow: none;
2261
+ border-radius: calc(var(--scrollbar-size) * 0.5);
2262
+ }
2263
+
2264
+ ::-webkit-scrollbar-thumb:hover {
2265
+ background-color: var(--scrollbar-thumb-hover-color);
2266
+ }
2267
+
2268
+ ::-webkit-scrollbar-track {
2269
+ background-color: var(--scrollbar-track-color);
2270
+ border-radius: 0;
2271
+ }
2272
+
2273
+ ::-webkit-scrollbar-track:hover {
2274
+ background-color: var(--scrollbar-track-hover-color);
2275
+ }
2276
+
2277
+ </style>
2278
+ <script src="https://unpkg.com/@alenaksu/json-viewer@2.0.0/dist/json-viewer.bundle.js"></script>
2279
+ <script>
2280
+ document.addEventListener('DOMContentLoaded', () => {
2281
+ const viewer = document.querySelector('#json-viewer');
2282
+ viewer.data = ${JSON.stringify(info)};
2283
+ viewer.expand(/headers|env/);
2284
+ });
2285
+ </script>
2286
+ </head>
2287
+ <body>
2288
+ <json-viewer id="json-viewer"></json-viewer>
2289
+ </body>
2290
+ </html>`);
2291
+ } catch (error) {
2292
+ response.status(400).json(error);
2293
+ }
2294
+ }
2295
+ });
2296
+ }
2031
2297
  // Annotate the CommonJS export names for ESM import in node:
2032
2298
  0 && (module.exports = {
2033
2299
  BuildStrategy,
@@ -2115,5 +2381,6 @@ async function storeApiDelete(url, options = {}) {
2115
2381
  storeCacheDuration,
2116
2382
  storeHandler,
2117
2383
  storeIndexHandler,
2118
- storeStrategy
2384
+ storeStrategy,
2385
+ varsHandler
2119
2386
  });
package/dist/index.mjs CHANGED
@@ -891,7 +891,7 @@ var NextPhase = /* @__PURE__ */ ((NextPhase2) => {
891
891
  })(NextPhase || {});
892
892
  function getNextPhase() {
893
893
  let nextPhase2 = "phase-export" /* Export */;
894
- if (process && process.env.NEXT_PHASE) {
894
+ if (typeof process !== "undefined" && process.env.NEXT_PHASE) {
895
895
  nextPhase2 = process.env.NEXT_PHASE;
896
896
  }
897
897
  return nextPhase2;
@@ -904,7 +904,7 @@ var BuildStrategy = /* @__PURE__ */ ((BuildStrategy2) => {
904
904
  })(BuildStrategy || {});
905
905
  function getBuildStrategy() {
906
906
  let buildStrategy2 = "static" /* Static */;
907
- if (process && process.env.BUILD_STRATEGY) {
907
+ if (typeof process !== "undefined" && process.env.BUILD_STRATEGY) {
908
908
  buildStrategy2 = process.env.BUILD_STRATEGY;
909
909
  }
910
910
  return buildStrategy2;
@@ -919,7 +919,7 @@ var StoreStrategy = /* @__PURE__ */ ((StoreStrategy2) => {
919
919
  })(StoreStrategy || {});
920
920
  function getStoreStrategy() {
921
921
  let storeStrategy2 = "mock" /* Mock */;
922
- if (process && process.env.STORE_STRATEGY) {
922
+ if (typeof process !== "undefined" && process.env.STORE_STRATEGY) {
923
923
  storeStrategy2 = process.env.STORE_STRATEGY;
924
924
  }
925
925
  return storeStrategy2;
@@ -927,7 +927,7 @@ function getStoreStrategy() {
927
927
  var storeStrategy = getStoreStrategy();
928
928
  function getStoreCacheDuration() {
929
929
  let storeCacheDuration2 = 1 * 60 * 1e3;
930
- if (process && process.env.STORE_CACHE_DURATION) {
930
+ if (typeof process !== "undefined" && process.env.STORE_CACHE_DURATION) {
931
931
  storeCacheDuration2 = parseInt(process.env.STORE_CACHE_DURATION);
932
932
  }
933
933
  return storeCacheDuration2;
@@ -1919,6 +1919,271 @@ async function storeApiPatch(url, payload, options = {}) {
1919
1919
  async function storeApiDelete(url, options = {}) {
1920
1920
  return await storeApiFetch(url, { ...options, method: "DELETE" });
1921
1921
  }
1922
+
1923
+ // src/vars/vars.handler.ts
1924
+ import { getHost, getOrigin, isDevelopment as isDevelopment2, isProduction } from "@websolutespa/bom-core";
1925
+
1926
+ // ../models/src/route/route.service.ts
1927
+ import { asCategoryId, defaultLocale as defaultLocale2, defaultMarket as defaultMarket2, getRootCategory, localize } from "@websolutespa/bom-core";
1928
+ async function getRouteLinkTree(market, locale) {
1929
+ const store = await getStore();
1930
+ const routes = await store.route.findMany({
1931
+ where: {
1932
+ market: {
1933
+ equals: market
1934
+ },
1935
+ locale: {
1936
+ equals: locale
1937
+ }
1938
+ }
1939
+ });
1940
+ const categories = await store.category.findMany();
1941
+ const rootCategory = getRootCategory(categories);
1942
+ if (rootCategory) {
1943
+ const root = categoryToRouteLink(routes, categories, rootCategory, locale);
1944
+ return root;
1945
+ }
1946
+ return void 0;
1947
+ }
1948
+ function categoryToRouteLink(routes, categories, category, locale) {
1949
+ const route = routes.find(
1950
+ (r) => r.category === category.id && r.isDefault
1951
+ );
1952
+ if (!route) {
1953
+ return void 0;
1954
+ }
1955
+ const rootCategory = getRootCategory(categories);
1956
+ const childCategories = categories.filter((x) => {
1957
+ const parentId = x.category ? asCategoryId(x.category) : null;
1958
+ return rootCategory && rootCategory.id === category.id ? x.id !== rootCategory.id && (parentId === category.id || !parentId) : parentId === category.id;
1959
+ });
1960
+ const routeLink = newRouteLink(category, route, locale);
1961
+ routeLink.items = childCategories.map((x) => categoryToRouteLink(routes, categories, x, locale)).filter((x) => x !== void 0);
1962
+ return routeLink;
1963
+ }
1964
+ function newRouteLink(category, route, locale) {
1965
+ const href = route && route.id ? route.id.toString() : "/";
1966
+ const id = route?.page || category.id;
1967
+ const media = category.media || route?.media;
1968
+ const schema = route?.schema || category?.schema || "unknown";
1969
+ const title = localize(category.title || route?.title || "untitled", locale);
1970
+ const routeLink = {
1971
+ category: category.id,
1972
+ href,
1973
+ id,
1974
+ items: [],
1975
+ media,
1976
+ schema,
1977
+ title
1978
+ };
1979
+ return routeLink;
1980
+ }
1981
+
1982
+ // ../models/src/label/label.service.ts
1983
+ async function getLabels(params = {}) {
1984
+ const store = await getStore();
1985
+ const items = await store.label.findMany(params);
1986
+ return items;
1987
+ }
1988
+
1989
+ // ../models/src/locale/locale.service.ts
1990
+ async function getLocales(params = {}) {
1991
+ const store = await getStore();
1992
+ const items = await store.locale.findMany(params);
1993
+ return items;
1994
+ }
1995
+
1996
+ // ../models/src/market/market.service.ts
1997
+ async function getMarkets(params = {}) {
1998
+ const store = await getStore();
1999
+ const items = await store.market.findMany(params);
2000
+ return items;
2001
+ }
2002
+
2003
+ // ../models/src/menu/menu.service.ts
2004
+ async function getMenus(params = {}) {
2005
+ const store = await getStore();
2006
+ const items = await store.menu.findMany(params);
2007
+ return items;
2008
+ }
2009
+
2010
+ // ../models/src/layout/layout.service.ts
2011
+ async function getLayout(market, locale) {
2012
+ const markets = await getMarkets({ locale });
2013
+ const locales = await getLocales({ locale });
2014
+ const labels = await getLabels({ locale });
2015
+ const tree = await getRouteLinkTree(market, locale);
2016
+ const firstLevelRoutes = tree?.items || [];
2017
+ const flatTopLevelRoutes = tree ? [tree, ...firstLevelRoutes] : [];
2018
+ const topLevelRoutes = flatTopLevelRoutes.reduce((object, routeLink) => {
2019
+ object[routeLink.schema] = routeLink;
2020
+ return object;
2021
+ }, {});
2022
+ const topLevelHrefs = flatTopLevelRoutes.reduce((object, routeLink) => {
2023
+ if (routeLink.href) {
2024
+ object[routeLink.schema] = routeLink.href;
2025
+ }
2026
+ return object;
2027
+ }, {});
2028
+ const menu = {};
2029
+ const menus = await getMenus({ market, locale });
2030
+ menus.forEach((x) => {
2031
+ menu[x.id] = x;
2032
+ });
2033
+ return {
2034
+ labels,
2035
+ locale,
2036
+ locales,
2037
+ market,
2038
+ markets,
2039
+ menu,
2040
+ topLevelHrefs,
2041
+ topLevelRoutes,
2042
+ tree
2043
+ };
2044
+ }
2045
+
2046
+ // src/vars/vars.handler.ts
2047
+ var DISALLOWED_KEYS = [
2048
+ "__NEXT_PRIVATE_STANDALONE_CONFIG"
2049
+ ];
2050
+ var getFilteredEnv = (env) => {
2051
+ const entries = Object.entries(env).filter(([k, v]) => !DISALLOWED_KEYS.includes(k) && typeof v === "string");
2052
+ entries.sort();
2053
+ return Object.fromEntries(entries);
2054
+ };
2055
+ var sortKeys = (object) => {
2056
+ const entries = Object.entries(object || {});
2057
+ entries.sort();
2058
+ return Object.fromEntries(entries);
2059
+ };
2060
+ function varsHandler() {
2061
+ return apiHandler({
2062
+ options: async (request, response) => {
2063
+ response.status(200).end();
2064
+ },
2065
+ get: async (request, response) => {
2066
+ try {
2067
+ const defaultLocale3 = process.env.DEFAULT_LOCALE || "it";
2068
+ const defaultMaket = process.env.DEFAULT_MARKET || "ww";
2069
+ const { locale = defaultLocale3, market = defaultMaket } = request.query || {};
2070
+ const layout = typeof locale === "string" && typeof market === "string" ? await getLayout(market, locale) : void 0;
2071
+ const info = {
2072
+ production: isProduction,
2073
+ development: isDevelopment2,
2074
+ origin: getOrigin(request.headers),
2075
+ host: getHost(request.headers),
2076
+ headers: { ...sortKeys(request.headers) },
2077
+ env: { ...getFilteredEnv(process.env) },
2078
+ layout: { ...sortKeys(layout) }
2079
+ };
2080
+ if (!request.headers.accept?.includes("text/html")) {
2081
+ return response.status(200).json(info);
2082
+ }
2083
+ response.status(200).send(`<!DOCTYPE html>
2084
+ <html>
2085
+ <head>
2086
+ <meta charSet="utf-8"/>
2087
+ <style>
2088
+ html, body {
2089
+ background: #282828;
2090
+ color: #7cacf8;
2091
+ }
2092
+ body {
2093
+ padding: 0;
2094
+ margin: 0;
2095
+ font-family: monospace;
2096
+ font-size: 14px;
2097
+ line-height: 1.16;
2098
+ font-weight: 100;
2099
+ }
2100
+ json-viewer {
2101
+ padding: 20px;
2102
+ min-height: 100vh;
2103
+ box-sizing: border-box;
2104
+ line-height: 1.2;
2105
+ --background-color: #282828;
2106
+ --color: #e3e3e3;
2107
+ --property-color: #7cacf8;
2108
+ --string-color: #53d5fb;
2109
+ --number-color: #7b80ff;
2110
+ --boolean-color: #9980ff;
2111
+ --null-color: #6f6f6f;
2112
+ --preview-color: #8f8f8f;
2113
+ --highlight-color: #7b0000;
2114
+ --font-family: monospace;
2115
+ --font-size: 14px;
2116
+ --indent-size: 1em;
2117
+ --indentguide-size: 1px;
2118
+ --indentguide-style: solid;
2119
+ --indentguide-color: #333;
2120
+ --indentguide-color-active: #666;
2121
+ --indentguide: var(--indentguide-size) var(--indentguide-style) var(--indentguide-color);
2122
+ --indentguide-active: var(--indentguide-size) var(--indentguide-style) var(--indentguide-color-active);
2123
+ }
2124
+
2125
+ :root {
2126
+ --scrollbar-size: 8px;
2127
+ --scrollbar-border-radius: 2px;
2128
+ --scrollbar-track-color: transparent;
2129
+ --scrollbar-track-hover-color: transparent;
2130
+ --scrollbar-thumb-color: #888888;
2131
+ --scrollbar-thumb-hover-color: #aaaaaa;
2132
+ }
2133
+
2134
+ ::-webkit-scrollbar {
2135
+ width: var(--scrollbar-size);
2136
+ height: var(--scrollbar-size);
2137
+ border-radius: 0;
2138
+ }
2139
+
2140
+ ::-webkit-scrollbar-button {
2141
+ display: none;
2142
+ }
2143
+
2144
+ ::-webkit-scrollbar-button:hover {
2145
+ display: none;
2146
+ }
2147
+
2148
+ ::-webkit-scrollbar-thumb {
2149
+ background-color: var(--scrollbar-thumb-color);
2150
+ box-shadow: none;
2151
+ border-radius: calc(var(--scrollbar-size) * 0.5);
2152
+ }
2153
+
2154
+ ::-webkit-scrollbar-thumb:hover {
2155
+ background-color: var(--scrollbar-thumb-hover-color);
2156
+ }
2157
+
2158
+ ::-webkit-scrollbar-track {
2159
+ background-color: var(--scrollbar-track-color);
2160
+ border-radius: 0;
2161
+ }
2162
+
2163
+ ::-webkit-scrollbar-track:hover {
2164
+ background-color: var(--scrollbar-track-hover-color);
2165
+ }
2166
+
2167
+ </style>
2168
+ <script src="https://unpkg.com/@alenaksu/json-viewer@2.0.0/dist/json-viewer.bundle.js"></script>
2169
+ <script>
2170
+ document.addEventListener('DOMContentLoaded', () => {
2171
+ const viewer = document.querySelector('#json-viewer');
2172
+ viewer.data = ${JSON.stringify(info)};
2173
+ viewer.expand(/headers|env/);
2174
+ });
2175
+ </script>
2176
+ </head>
2177
+ <body>
2178
+ <json-viewer id="json-viewer"></json-viewer>
2179
+ </body>
2180
+ </html>`);
2181
+ } catch (error) {
2182
+ response.status(400).json(error);
2183
+ }
2184
+ }
2185
+ });
2186
+ }
1922
2187
  export {
1923
2188
  BuildStrategy,
1924
2189
  COLLECTIONS,
@@ -2005,5 +2270,6 @@ export {
2005
2270
  storeCacheDuration,
2006
2271
  storeHandler,
2007
2272
  storeIndexHandler,
2008
- storeStrategy
2273
+ storeStrategy,
2274
+ varsHandler
2009
2275
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@websolutespa/bom-mixer-store",
3
- "version": "1.7.2",
3
+ "version": "1.7.4",
4
4
  "description": "Mixer Store module of the BOM Repository",
5
5
  "keywords": [
6
6
  "bom",
@@ -28,19 +28,19 @@
28
28
  "peerDependencies": {
29
29
  "@websolutespa/bom-core": "*",
30
30
  "iron-session": ">= 6.2.1",
31
- "next": ">= 13.4.19"
31
+ "next": ">= 14.1.4"
32
32
  },
33
33
  "devDependencies": {
34
34
  "@types/mime": "^3.0.1",
35
35
  "@websolutespa/bom-cli": "*",
36
36
  "@websolutespa/test": "*",
37
37
  "@websolutespa/tsconfig": "*",
38
- "eslint": "^8.46.0",
38
+ "eslint": "^9.0.0",
39
39
  "eslint-config-websolute": "*",
40
40
  "npm-run-all": "^4.1.5",
41
- "ts-node": "^10.9.1",
41
+ "ts-node": "^10.9.2",
42
42
  "tsup": "^6.7.0",
43
- "typescript": "^5.1.6"
43
+ "typescript": "^5.4.5"
44
44
  },
45
45
  "publishConfig": {
46
46
  "access": "public"
@@ -1,13 +1,14 @@
1
+ // Next.js API route support: https://nextjs.org/docs/api-routes/introduction
1
2
  import { NextApiRequest, NextApiResponse } from 'next';
2
3
 
3
4
  export type ICrudMethod = 'get' | 'post' | 'put' | 'patch' | 'delete' | string;
4
5
 
5
- export type IHandler = (request: NextApiRequest, response: NextApiResponse) => Promise<any>;
6
+ export type IHandler<T = any> = (request: NextApiRequest, response: NextApiResponse<T>) => Promise<NextApiResponse<T> | void>;
6
7
 
7
8
  export type IApiHandler = Record<ICrudMethod, IHandler>;
8
9
 
9
- export function apiHandler(handler: IApiHandler): any {
10
- return async (request: NextApiRequest, response: NextApiResponse): Promise<any> => {
10
+ export function apiHandler<T = any>(handler: IApiHandler): IHandler<T> {
11
+ return async (request: NextApiRequest, response: NextApiResponse<T>): Promise<NextApiResponse<T> | void> => {
11
12
  const method: ICrudMethod = (request.method || 'GET').toLowerCase() as ICrudMethod;
12
13
  // check handler supports HTTP method
13
14
  if (!handler[method]) {
@@ -26,7 +27,7 @@ export function apiHandler(handler: IApiHandler): any {
26
27
  };
27
28
  }
28
29
 
29
- export function errorHandler(error: any, response: NextApiResponse): Promise<any> | void {
30
+ export function errorHandler(error: any, response: NextApiResponse): NextApiResponse | void {
30
31
  if (typeof (error) === 'string') {
31
32
  // custom application error
32
33
  const is404 = error.toLowerCase().endsWith('not found');
package/src/index.ts CHANGED
@@ -22,4 +22,5 @@ export * from './store/store';
22
22
  export * from './store/store.api';
23
23
  export * from './store/store.handler';
24
24
  export * from './store/store.service';
25
+ export * from './vars/vars.handler';
25
26
 
@@ -11,7 +11,7 @@ export enum NextPhase {
11
11
 
12
12
  function getNextPhase(): NextPhase {
13
13
  let nextPhase = NextPhase.Export;
14
- if (process && process.env.NEXT_PHASE) {
14
+ if (typeof process !== 'undefined' && process.env.NEXT_PHASE) {
15
15
  nextPhase = process.env.NEXT_PHASE as NextPhase;
16
16
  }
17
17
  return nextPhase;
@@ -27,7 +27,7 @@ export enum BuildStrategy {
27
27
 
28
28
  function getBuildStrategy(): BuildStrategy {
29
29
  let buildStrategy = BuildStrategy.Static;
30
- if (process && process.env.BUILD_STRATEGY) {
30
+ if (typeof process !== 'undefined' && process.env.BUILD_STRATEGY) {
31
31
  buildStrategy = process.env.BUILD_STRATEGY as BuildStrategy;
32
32
  }
33
33
  return buildStrategy;
@@ -45,7 +45,7 @@ export enum StoreStrategy {
45
45
 
46
46
  function getStoreStrategy(): StoreStrategy {
47
47
  let storeStrategy = StoreStrategy.Mock;
48
- if (process && process.env.STORE_STRATEGY) {
48
+ if (typeof process !== 'undefined' && process.env.STORE_STRATEGY) {
49
49
  storeStrategy = process.env.STORE_STRATEGY as StoreStrategy;
50
50
  }
51
51
  return storeStrategy;
@@ -56,7 +56,7 @@ export const storeStrategy: StoreStrategy = getStoreStrategy();
56
56
  // storeCacheDuration
57
57
  function getStoreCacheDuration(): number {
58
58
  let storeCacheDuration = (1 * 60 * 1000);
59
- if (process && process.env.STORE_CACHE_DURATION) {
59
+ if (typeof process !== 'undefined' && process.env.STORE_CACHE_DURATION) {
60
60
  storeCacheDuration = parseInt(process.env.STORE_CACHE_DURATION);
61
61
  }
62
62
  return storeCacheDuration;
@@ -0,0 +1,153 @@
1
+ import { getHost, getOrigin, isDevelopment, isProduction } from '@websolutespa/bom-core';
2
+ import { getLayout } from '@websolutespa/bom-mixer-models';
3
+ import { apiHandler } from '@websolutespa/bom-mixer-store';
4
+ import { NextApiRequest, NextApiResponse } from 'next';
5
+
6
+ const DISALLOWED_KEYS = [
7
+ '__NEXT_PRIVATE_STANDALONE_CONFIG',
8
+ ];
9
+
10
+ const getFilteredEnv = (env: Record<string, unknown>): Record<string, unknown> => {
11
+ const entries = Object.entries(env).filter(([k, v]) => (
12
+ !DISALLOWED_KEYS.includes(k) && typeof v === 'string'
13
+ ));
14
+ entries.sort();
15
+ return Object.fromEntries(entries);
16
+ }
17
+
18
+ const sortKeys = (object?: Record<string, unknown>): Record<string, unknown> => {
19
+ const entries = Object.entries(object || {});
20
+ entries.sort();
21
+ return Object.fromEntries(entries);
22
+ }
23
+
24
+ export function varsHandler() {
25
+ return apiHandler({
26
+ options: async (request: NextApiRequest, response: NextApiResponse) => {
27
+ response.status(200).end();
28
+ },
29
+ get: async (request: NextApiRequest, response: NextApiResponse) => {
30
+ try {
31
+ const defaultLocale = process.env.DEFAULT_LOCALE || 'it';
32
+ const defaultMaket = process.env.DEFAULT_MARKET || 'ww';
33
+ const { locale = defaultLocale, market = defaultMaket } = (request.query || {});
34
+ const layout =
35
+ typeof locale === 'string' && typeof market === 'string' ?
36
+ await getLayout(market, locale) :
37
+ undefined;
38
+ const info = {
39
+ production: isProduction,
40
+ development: isDevelopment,
41
+ origin: getOrigin(request.headers),
42
+ host: getHost(request.headers),
43
+ headers: { ...sortKeys(request.headers) },
44
+ env: { ...getFilteredEnv(process.env) },
45
+ layout: { ...sortKeys(layout) },
46
+ }
47
+ if (!(request.headers.accept?.includes('text/html'))) {
48
+ return response.status(200).json(info);
49
+ }
50
+ response.status(200).send(`<!DOCTYPE html>
51
+ <html>
52
+ <head>
53
+ <meta charSet="utf-8"/>
54
+ <style>
55
+ html, body {
56
+ background: #282828;
57
+ color: #7cacf8;
58
+ }
59
+ body {
60
+ padding: 0;
61
+ margin: 0;
62
+ font-family: monospace;
63
+ font-size: 14px;
64
+ line-height: 1.16;
65
+ font-weight: 100;
66
+ }
67
+ json-viewer {
68
+ padding: 20px;
69
+ min-height: 100vh;
70
+ box-sizing: border-box;
71
+ line-height: 1.2;
72
+ --background-color: #282828;
73
+ --color: #e3e3e3;
74
+ --property-color: #7cacf8;
75
+ --string-color: #53d5fb;
76
+ --number-color: #7b80ff;
77
+ --boolean-color: #9980ff;
78
+ --null-color: #6f6f6f;
79
+ --preview-color: #8f8f8f;
80
+ --highlight-color: #7b0000;
81
+ --font-family: monospace;
82
+ --font-size: 14px;
83
+ --indent-size: 1em;
84
+ --indentguide-size: 1px;
85
+ --indentguide-style: solid;
86
+ --indentguide-color: #333;
87
+ --indentguide-color-active: #666;
88
+ --indentguide: var(--indentguide-size) var(--indentguide-style) var(--indentguide-color);
89
+ --indentguide-active: var(--indentguide-size) var(--indentguide-style) var(--indentguide-color-active);
90
+ }
91
+
92
+ :root {
93
+ --scrollbar-size: 8px;
94
+ --scrollbar-border-radius: 2px;
95
+ --scrollbar-track-color: transparent;
96
+ --scrollbar-track-hover-color: transparent;
97
+ --scrollbar-thumb-color: #888888;
98
+ --scrollbar-thumb-hover-color: #aaaaaa;
99
+ }
100
+
101
+ ::-webkit-scrollbar {
102
+ width: var(--scrollbar-size);
103
+ height: var(--scrollbar-size);
104
+ border-radius: 0;
105
+ }
106
+
107
+ ::-webkit-scrollbar-button {
108
+ display: none;
109
+ }
110
+
111
+ ::-webkit-scrollbar-button:hover {
112
+ display: none;
113
+ }
114
+
115
+ ::-webkit-scrollbar-thumb {
116
+ background-color: var(--scrollbar-thumb-color);
117
+ box-shadow: none;
118
+ border-radius: calc(var(--scrollbar-size) * 0.5);
119
+ }
120
+
121
+ ::-webkit-scrollbar-thumb:hover {
122
+ background-color: var(--scrollbar-thumb-hover-color);
123
+ }
124
+
125
+ ::-webkit-scrollbar-track {
126
+ background-color: var(--scrollbar-track-color);
127
+ border-radius: 0;
128
+ }
129
+
130
+ ::-webkit-scrollbar-track:hover {
131
+ background-color: var(--scrollbar-track-hover-color);
132
+ }
133
+
134
+ </style>
135
+ <script src="https://unpkg.com/@alenaksu/json-viewer@2.0.0/dist/json-viewer.bundle.js"></script>
136
+ <script>
137
+ document.addEventListener('DOMContentLoaded', () => {
138
+ const viewer = document.querySelector('#json-viewer');
139
+ viewer.data = ${JSON.stringify(info)};
140
+ viewer.expand(/headers|env/);
141
+ });
142
+ </script>
143
+ </head>
144
+ <body>
145
+ <json-viewer id="json-viewer"></json-viewer>
146
+ </body>
147
+ </html>`);
148
+ } catch (error) {
149
+ response.status(400).json(error);
150
+ }
151
+ },
152
+ });
153
+ }