@websolutespa/bom-mixer-store 0.3.2 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -103,10 +103,10 @@ var fs = __require("fs");
103
103
  async function fsRead(pathname, encoding = "utf8") {
104
104
  try {
105
105
  const data = await fs.promises.readFile(pathname, encoding);
106
- return data || null;
106
+ return data || void 0;
107
107
  } catch (error) {
108
108
  console.log("fsRead", error, pathname);
109
- return null;
109
+ return;
110
110
  }
111
111
  }
112
112
  async function fsReadJson(pathname) {
@@ -115,11 +115,11 @@ async function fsReadJson(pathname) {
115
115
  if (data) {
116
116
  return JSON.parse(data);
117
117
  } else {
118
- return null;
118
+ return;
119
119
  }
120
120
  } catch (error) {
121
121
  console.log("fsReadJson", error, pathname);
122
- return null;
122
+ return;
123
123
  }
124
124
  }
125
125
 
@@ -796,28 +796,32 @@ async function getMockStore(getJson) {
796
796
  }
797
797
  function getMockStoreFromData(data) {
798
798
  const store = {};
799
- for (const key in data) {
800
- if (!PAGES.includes(key)) {
801
- const service = new MockService(data[key], store);
802
- store[key] = service;
799
+ if (data) {
800
+ for (const key in data) {
801
+ if (!PAGES.includes(key)) {
802
+ const service = new MockService(data[key], store);
803
+ store[key] = service;
804
+ }
803
805
  }
804
- }
805
- const category = store.category;
806
- const route = store.route;
807
- const menu = data.menu;
808
- if (category && route && menu) {
809
- store.menu = new MockMenuService(menu, store);
810
- }
811
- for (const key in data) {
812
- if (PAGES.includes(key)) {
813
- let service;
814
- if (route) {
815
- service = new MockPageService(data[key], store);
816
- } else {
817
- service = new MockService(data[key], store);
806
+ const category = store.category;
807
+ const route = store.route;
808
+ const menu = data.menu;
809
+ if (category && route && menu) {
810
+ store.menu = new MockMenuService(menu, store);
811
+ }
812
+ for (const key in data) {
813
+ if (PAGES.includes(key)) {
814
+ let service;
815
+ if (route) {
816
+ service = new MockPageService(data[key], store);
817
+ } else {
818
+ service = new MockService(data[key], store);
819
+ }
820
+ store[key] = service;
818
821
  }
819
- store[key] = service;
820
822
  }
823
+ } else {
824
+ console.log("mock store not found");
821
825
  }
822
826
  staticCollections.forEach((config) => {
823
827
  store[config.slug] = new StaticService(config, store);
@@ -1067,6 +1071,7 @@ var KNOWN_COLLECTIONS = [
1067
1071
  "menu",
1068
1072
  "template",
1069
1073
  "page",
1074
+ "redirect",
1070
1075
  "route",
1071
1076
  ...STATIC_COLLECTIONS
1072
1077
  ];
@@ -1087,157 +1092,216 @@ async function getStore() {
1087
1092
  // src/store/store.handler.ts
1088
1093
  function storeHandler(storePromise = async () => await getStore()) {
1089
1094
  return apiHandler({
1090
- // find a specific document by id or
1091
- // find paginated documents
1092
- get: async (request, response) => {
1093
- try {
1094
- const { collections, ...query } = request.query;
1095
- if (!Array.isArray(collections) || collections?.length === 0) {
1096
- console.error("method not allowed", collections);
1097
- return response.status(405).send("method not allowed");
1098
- }
1099
- const collection = collections[0];
1100
- const id = collections[1];
1101
- const qs = Object.entries(query).map((kv) => kv.join("=")).join("&");
1102
- const params = qsDeserialize(qs);
1103
- if (!COLLECTIONS.includes(collection)) {
1104
- console.error("method not allowed", collection);
1105
- return response.status(405).send("method not allowed");
1106
- }
1107
- const store = await storePromise();
1108
- const service = store[collection];
1109
- if (!service) {
1110
- console.error("method not allowed", collection);
1111
- return response.status(405).send("method not allowed");
1112
- }
1113
- if (id) {
1114
- const item = await service.findOne(asEquatable(id), params);
1115
- if (item) {
1116
- return response.status(200).json(item);
1117
- } else {
1118
- return response.status(404).send("not found");
1119
- }
1120
- } else if (String(params.pagination) === "true") {
1121
- const pagination = await service.findPaged(params);
1122
- return response.status(200).json(pagination);
1095
+ get: collectionGet(storePromise),
1096
+ post: collectionPost(storePromise),
1097
+ patch: collectionPatch(storePromise),
1098
+ delete: collectionDelete(storePromise)
1099
+ });
1100
+ }
1101
+ function collectionGet(storePromise) {
1102
+ return async (request, response) => {
1103
+ try {
1104
+ const { collections, ...query } = request.query;
1105
+ if (!Array.isArray(collections) || collections?.length === 0) {
1106
+ console.error("storeHandler.collectionGet", "method not allowed", collections);
1107
+ return response.status(405).send("method not allowed");
1108
+ }
1109
+ const collection = collections[0];
1110
+ const id = collections[1];
1111
+ const qs = Object.entries(query).map((kv) => kv.join("=")).join("&");
1112
+ const params = qsDeserialize(qs);
1113
+ if (!COLLECTIONS.includes(collection)) {
1114
+ console.error("storeHandler.collectionGet", "method not allowed", collection);
1115
+ return response.status(405).send("method not allowed");
1116
+ }
1117
+ const store = await storePromise();
1118
+ const service = store[collection];
1119
+ if (!service) {
1120
+ console.error("storeHandler.collectionGet", "method not allowed", collection);
1121
+ return response.status(405).send("method not allowed");
1122
+ }
1123
+ if (id) {
1124
+ const item = await service.findOne(asEquatable(id), params);
1125
+ if (item) {
1126
+ return response.status(200).json(item);
1123
1127
  } else {
1124
- const items = await service.findMany(params);
1125
- return response.status(200).json(items);
1128
+ return response.status(404).send("not found");
1126
1129
  }
1127
- } catch (error) {
1128
- console.error("storeHandler.error.500", error);
1129
- throw error;
1130
+ } else if (String(params.pagination) === "true") {
1131
+ const pagination = await service.findPaged(params);
1132
+ return response.status(200).json(pagination);
1133
+ } else {
1134
+ const items = await service.findMany(params);
1135
+ return response.status(200).json(items);
1130
1136
  }
1131
- },
1132
- // create a new document
1133
- post: async (request, response) => {
1134
- try {
1135
- const { collections, ...query } = request.query;
1136
- if (!Array.isArray(collections) || collections.length !== 1) {
1137
- console.error("method not allowed", collections);
1138
- return response.status(405).send("method not allowed");
1139
- }
1140
- const collection = collections[0];
1141
- const store = await storePromise();
1142
- const service = store[collection];
1143
- if (!service) {
1144
- console.error("method not allowed", collection);
1145
- return response.status(405).send("method not allowed");
1137
+ } catch (error) {
1138
+ console.error("storeHandler.collectionGet.error", "500", error);
1139
+ throw error;
1140
+ }
1141
+ };
1142
+ }
1143
+ function collectionPost(storePromise) {
1144
+ return async (request, response) => {
1145
+ try {
1146
+ const { collections, ...query } = request.query;
1147
+ if (!Array.isArray(collections) || collections.length !== 1) {
1148
+ console.error("method not allowed", collections);
1149
+ return response.status(405).send("method not allowed");
1150
+ }
1151
+ const collection = collections[0];
1152
+ const store = await storePromise();
1153
+ const service = store[collection];
1154
+ if (!service) {
1155
+ console.error("method not allowed", collection);
1156
+ return response.status(405).send("method not allowed");
1157
+ }
1158
+ if (collection === "route") {
1159
+ return routePost(store, request, response);
1160
+ }
1161
+ } catch (error) {
1162
+ console.error("storeHandler.error.500", error);
1163
+ throw error;
1164
+ }
1165
+ };
1166
+ }
1167
+ function collectionPatch(storePromise) {
1168
+ return async (request, response) => {
1169
+ try {
1170
+ const params = request.query;
1171
+ const { collections, ...query } = params;
1172
+ if (!Array.isArray(collections) || collections.length !== 2) {
1173
+ console.error("method not allowed", collections);
1174
+ return response.status(405).send("method not allowed");
1175
+ }
1176
+ const collection = collections[0];
1177
+ const id = collections[1];
1178
+ const store = await storePromise();
1179
+ const service = store[collection];
1180
+ if (!service) {
1181
+ console.error("method not allowed", collection);
1182
+ return response.status(405).send("method not allowed");
1183
+ }
1184
+ } catch (error) {
1185
+ console.error("storeHandler.error.500", error);
1186
+ throw error;
1187
+ }
1188
+ };
1189
+ }
1190
+ function collectionDelete(storePromise) {
1191
+ return async (request, response) => {
1192
+ try {
1193
+ const params = request.query;
1194
+ const { collections, ...query } = params;
1195
+ if (!Array.isArray(collections) || collections.length !== 2) {
1196
+ console.error("method not allowed", collections);
1197
+ return response.status(405).send("method not allowed");
1198
+ }
1199
+ const collection = collections[0];
1200
+ const id = collections[1];
1201
+ const store = await storePromise();
1202
+ const service = store[collection];
1203
+ if (!service) {
1204
+ console.error("method not allowed", collection);
1205
+ return response.status(405).send("method not allowed");
1206
+ }
1207
+ } catch (error) {
1208
+ console.error("storeHandler.error.500", error);
1209
+ throw error;
1210
+ }
1211
+ };
1212
+ }
1213
+ async function routePost(store, request, response) {
1214
+ if (request.body.pathname && request.body.href) {
1215
+ try {
1216
+ const { pathname, href } = request.body;
1217
+ const routes = await store.route.findMany({
1218
+ where: {
1219
+ id: {
1220
+ equals: pathname
1221
+ }
1146
1222
  }
1147
- if (collection === "route" && request.body.pathname) {
1148
- try {
1149
- const { pathname } = request.body;
1150
- const routes = await store.route.findMany({
1151
- where: {
1152
- id: {
1153
- equals: pathname
1154
- }
1155
- }
1156
- });
1157
- if (routes.length === 0) {
1158
- const splatRoutes = await store.route.findMany({
1159
- where: {
1160
- useSplat: {
1161
- equals: true
1162
- }
1163
- }
1164
- });
1165
- const route = splatRoutes.reduce((p, c) => {
1166
- const match = pathname.indexOf(c.id) === 0;
1167
- if (match && (!p || p.id.length < c.id.length)) {
1168
- return { ...c, splat: pathname.substring(c.id.length, pathname.length) };
1169
- } else {
1170
- return p;
1171
- }
1172
- }, void 0);
1173
- if (route) {
1174
- return response.status(200).json(route);
1175
- }
1176
- }
1177
- if (routes.length > 0) {
1178
- return response.status(200).json(routes[0]);
1179
- } else {
1180
- return response.status(404).send("not found");
1181
- }
1182
- } catch (error) {
1183
- if (error.status === 404) {
1184
- return response.status(404).send("not found");
1185
- } else {
1186
- console.error("storeHandler.error.500", error);
1187
- throw error;
1223
+ });
1224
+ if (routes.length > 0) {
1225
+ return response.status(200).json(routes[0]);
1226
+ } else {
1227
+ const splatRoutes = await store.route.findMany({
1228
+ where: {
1229
+ useSplat: {
1230
+ equals: true
1188
1231
  }
1189
1232
  }
1233
+ });
1234
+ const splatRoute = splatRoutes.reduce((p, c) => {
1235
+ const match = pathname.indexOf(c.id) === 0;
1236
+ if (match && (!p || p.id.length < c.id.length)) {
1237
+ return { ...c, splat: pathname.substring(c.id.length, pathname.length) };
1238
+ } else {
1239
+ return p;
1240
+ }
1241
+ }, void 0);
1242
+ if (splatRoute) {
1243
+ return response.status(200).json(splatRoute);
1190
1244
  }
1191
- } catch (error) {
1192
- console.error("storeHandler.error.500", error);
1193
- throw error;
1194
- }
1195
- },
1196
- // update a document by id
1197
- patch: async (request, response) => {
1198
- try {
1199
- const params = request.query;
1200
- const { collections, ...query } = params;
1201
- if (!Array.isArray(collections) || collections.length !== 2) {
1202
- console.error("method not allowed", collections);
1203
- return response.status(405).send("method not allowed");
1245
+ const redirects = await store.redirect.findMany({
1246
+ where: {
1247
+ isActive: {
1248
+ equals: true
1249
+ }
1250
+ }
1251
+ });
1252
+ const exactMatchResolver = (redirect) => {
1253
+ const status = parseInt(redirect.status) || 307;
1254
+ if (status < 400) {
1255
+ const redirectUrl = redirect.to;
1256
+ return response.status(status).send({
1257
+ redirectUrl
1258
+ });
1259
+ } else {
1260
+ return response.status(status).send("gone");
1261
+ }
1262
+ };
1263
+ const exactMatchRedirect = redirects.find((x) => x.from === href);
1264
+ if (exactMatchRedirect !== void 0) {
1265
+ return exactMatchResolver(exactMatchRedirect);
1204
1266
  }
1205
- const collection = collections[0];
1206
- const id = collections[1];
1207
- const store = await storePromise();
1208
- const service = store[collection];
1209
- if (!service) {
1210
- console.error("method not allowed", collection);
1211
- return response.status(405).send("method not allowed");
1267
+ const patternMatchResolver = (redirect) => {
1268
+ const status = parseInt(redirect.status) || 307;
1269
+ if (status < 400) {
1270
+ const regexp = new RegExp(redirect.from);
1271
+ let i = 0;
1272
+ let redirectUrl = redirect.to.replace(/\*/g, (...rest) => {
1273
+ return `$${++i}`;
1274
+ });
1275
+ redirectUrl = href.replace(regexp, redirectUrl);
1276
+ return response.status(status).send({
1277
+ redirectUrl
1278
+ });
1279
+ } else {
1280
+ return response.status(status).send("gone");
1281
+ }
1282
+ };
1283
+ redirects.forEach((x) => {
1284
+ x.from = x.from.replace(/\*/g, (...rest) => {
1285
+ return "(.*)";
1286
+ });
1287
+ });
1288
+ const firstMatch = redirects.find((x) => href.match(x.from));
1289
+ if (firstMatch) {
1290
+ return patternMatchResolver(firstMatch);
1212
1291
  }
1213
- } catch (error) {
1214
- console.error("storeHandler.error.500", error);
1215
- throw error;
1292
+ return response.status(404).send("not found");
1216
1293
  }
1217
- },
1218
- // delete an existing document by id
1219
- delete: async (request, response) => {
1220
- try {
1221
- const params = request.query;
1222
- const { collections, ...query } = params;
1223
- if (!Array.isArray(collections) || collections.length !== 2) {
1224
- console.error("method not allowed", collections);
1225
- return response.status(405).send("method not allowed");
1226
- }
1227
- const collection = collections[0];
1228
- const id = collections[1];
1229
- const store = await storePromise();
1230
- const service = store[collection];
1231
- if (!service) {
1232
- console.error("method not allowed", collection);
1233
- return response.status(405).send("method not allowed");
1234
- }
1235
- } catch (error) {
1294
+ } catch (error) {
1295
+ if (error.status === 404) {
1296
+ return response.status(404).send("not found");
1297
+ } else {
1236
1298
  console.error("storeHandler.error.500", error);
1237
1299
  throw error;
1238
1300
  }
1239
1301
  }
1240
- });
1302
+ } else {
1303
+ return response.status(400).send("bad request");
1304
+ }
1241
1305
  }
1242
1306
 
1243
1307
  // src/mock/mock.handler.ts
@@ -1260,6 +1324,10 @@ export {
1260
1324
  apiPatch,
1261
1325
  apiPost,
1262
1326
  apiPut,
1327
+ collectionDelete,
1328
+ collectionGet,
1329
+ collectionPatch,
1330
+ collectionPost,
1263
1331
  errorHandler,
1264
1332
  getApiBuildStore,
1265
1333
  getApiRuntimeStore,
@@ -1275,6 +1343,7 @@ export {
1275
1343
  isRelation,
1276
1344
  isStaticRequest,
1277
1345
  mockHandler,
1346
+ routePost,
1278
1347
  staticCollections,
1279
1348
  storeApiDelete,
1280
1349
  storeApiFetch,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@websolutespa/bom-mixer-store",
3
- "version": "0.3.2",
3
+ "version": "1.0.0",
4
4
  "description": "Mixer Store module of the BOM Repository",
5
5
  "keywords": [
6
6
  "bom",
@@ -16,6 +16,16 @@ export function getApiUrl(pathname: string): string {
16
16
  process.env.NEXT_PUBLIC_URL;
17
17
  const apiBase = process.env.NEXT_PUBLIC_API || '/api';
18
18
  const url = `${localUrl}${apiBase}${pathname}`;
19
+ /*
20
+ console.log(
21
+ 'getApiUrl',
22
+ 'NEXT_PUBLIC_URL', process.env.NEXT_PUBLIC_URL,
23
+ 'NEXT_PUBLIC_MOCK_FALLBACK_URL', process.env.NEXT_PUBLIC_MOCK_FALLBACK_URL,
24
+ 'localUrl', localUrl,
25
+ 'apiBase', apiBase,
26
+ 'url', url,
27
+ );
28
+ */
19
29
  return url;
20
30
  }
21
31
 
@@ -11,28 +11,28 @@ export async function fsExists(pathname: string): Promise<boolean> {
11
11
  }
12
12
  }
13
13
 
14
- export async function fsRead(pathname: string, encoding = 'utf8'): Promise<any> {
14
+ export async function fsRead(pathname: string, encoding = 'utf8'): Promise<string | undefined> {
15
15
  try {
16
16
  const data = await fs.promises.readFile(pathname, encoding);
17
- return data || null;
17
+ return data || undefined;
18
18
  } catch (error) {
19
19
  console.log('fsRead', error, pathname);
20
- return null;
20
+ return;
21
21
  }
22
22
  }
23
23
 
24
- export async function fsReadJson(pathname: string): Promise<any> {
24
+ export async function fsReadJson<T = {}>(pathname: string): Promise<T | undefined> {
25
25
  try {
26
26
  const data = await fsRead(pathname);
27
27
  if (data) {
28
- return JSON.parse(data);
28
+ return JSON.parse(data) as T;
29
29
  } else {
30
- return null;
30
+ return;
31
31
  }
32
32
  } catch (error) {
33
33
  console.log('fsReadJson', error, pathname);
34
34
  // throw (error);
35
- return null;
35
+ return;
36
36
  }
37
37
  }
38
38
 
@@ -21,7 +21,7 @@ export async function getMockStoreServer<T extends IStore>(): Promise<T> {
21
21
  }
22
22
  const pathname = path.join(process.cwd(), '.mixer', 'store.json');
23
23
  // console.log('getMockStore.pathname', pathname);
24
- const data: IMemoryStore = await fsReadJson(pathname);
24
+ const data = await fsReadJson<IMemoryStore>(pathname);
25
25
  const store = getMockStoreFromData(data);
26
26
  if (!isDevelopment) {
27
27
  STORE_ = store;
@@ -44,33 +44,37 @@ export async function getMockStore<T extends IStore>(getJson: () => Promise<stri
44
44
  return store as T;
45
45
  }
46
46
 
47
- export function getMockStoreFromData<T extends IStore>(data: IMemoryStore): T {
47
+ export function getMockStoreFromData<T extends IStore>(data?: IMemoryStore): T {
48
48
  const store: IStore = {};
49
- for (const key in data) {
50
- if (!PAGES.includes(key)) {
51
- // new collection
52
- const service = new MockService(data[key], store);
53
- store[key] = service;
49
+ if (data) {
50
+ for (const key in data) {
51
+ if (!PAGES.includes(key)) {
52
+ // new collection
53
+ const service = new MockService(data[key], store);
54
+ store[key] = service;
55
+ }
54
56
  }
55
- }
56
- const category = store.category;
57
- const route = store.route;
58
- const menu = data.menu;
59
- if (category && route && menu) {
60
- store.menu = new MockMenuService(menu, store);
61
- }
62
- for (const key in data) {
63
- if (PAGES.includes(key)) {
64
- let service;
65
- if (route) {
66
- // new page
67
- service = new MockPageService(data[key], store);
68
- } else {
69
- // !!! new collection should throw
70
- service = new MockService(data[key], store);
57
+ const category = store.category;
58
+ const route = store.route;
59
+ const menu = data.menu;
60
+ if (category && route && menu) {
61
+ store.menu = new MockMenuService(menu, store);
62
+ }
63
+ for (const key in data) {
64
+ if (PAGES.includes(key)) {
65
+ let service;
66
+ if (route) {
67
+ // new page
68
+ service = new MockPageService(data[key], store);
69
+ } else {
70
+ // !!! new collection should throw
71
+ service = new MockService(data[key], store);
72
+ }
73
+ store[key] = service;
71
74
  }
72
- store[key] = service;
73
75
  }
76
+ } else {
77
+ console.log('mock store not found');
74
78
  }
75
79
  staticCollections.forEach(config => {
76
80
  store[config.slug] = new StaticService(config, store);