@visulima/crud 2.0.46 → 3.0.0-alpha.10

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.
Files changed (137) hide show
  1. package/CHANGELOG.md +162 -0
  2. package/LICENSE.md +22 -1
  3. package/README.md +29 -18
  4. package/dist/adapter/prisma/index.d.cts +39 -0
  5. package/dist/adapter/prisma/index.d.mts +39 -0
  6. package/dist/adapter/prisma/index.d.ts +39 -0
  7. package/dist/adapter/prisma/types.d.cts +31 -0
  8. package/dist/adapter/prisma/types.d.mts +31 -0
  9. package/dist/adapter/prisma/types.d.ts +31 -0
  10. package/dist/adapter/prisma/utils/models-to-route-names.d.cts +5 -0
  11. package/dist/adapter/prisma/utils/models-to-route-names.d.mts +5 -0
  12. package/dist/adapter/prisma/utils/models-to-route-names.d.ts +5 -0
  13. package/dist/adapter/prisma/utils/parse-cursor.d.cts +3 -0
  14. package/dist/adapter/prisma/utils/parse-cursor.d.mts +3 -0
  15. package/dist/adapter/prisma/utils/parse-cursor.d.ts +3 -0
  16. package/dist/adapter/prisma/utils/parse-order-by.d.cts +4 -0
  17. package/dist/adapter/prisma/utils/parse-order-by.d.mts +4 -0
  18. package/dist/adapter/prisma/utils/parse-order-by.d.ts +4 -0
  19. package/dist/adapter/prisma/utils/parse-recursive.d.cts +4 -0
  20. package/dist/adapter/prisma/utils/parse-recursive.d.mts +4 -0
  21. package/dist/adapter/prisma/utils/parse-recursive.d.ts +4 -0
  22. package/dist/adapter/prisma/utils/parse-where.d.cts +4 -0
  23. package/dist/adapter/prisma/utils/parse-where.d.mts +4 -0
  24. package/dist/adapter/prisma/utils/parse-where.d.ts +4 -0
  25. package/dist/base-crud-handler.d.cts +9 -0
  26. package/dist/base-crud-handler.d.mts +9 -0
  27. package/dist/base-crud-handler.d.ts +9 -0
  28. package/dist/handler/create.d.cts +11 -0
  29. package/dist/handler/create.d.mts +11 -0
  30. package/dist/handler/create.d.ts +11 -0
  31. package/dist/handler/delete.d.cts +7 -0
  32. package/dist/handler/delete.d.mts +7 -0
  33. package/dist/handler/delete.d.ts +7 -0
  34. package/dist/handler/list.d.cts +9 -0
  35. package/dist/handler/list.d.mts +9 -0
  36. package/dist/handler/list.d.ts +9 -0
  37. package/dist/handler/read.d.cts +7 -0
  38. package/dist/handler/read.d.mts +7 -0
  39. package/dist/handler/read.d.ts +7 -0
  40. package/dist/handler/update.d.cts +11 -0
  41. package/dist/handler/update.d.mts +11 -0
  42. package/dist/handler/update.d.ts +11 -0
  43. package/dist/index.cjs +13 -0
  44. package/dist/index.d.cts +6 -0
  45. package/dist/index.d.mts +6 -127
  46. package/dist/index.d.ts +6 -127
  47. package/dist/index.mjs +3 -1085
  48. package/dist/next/api/edge/index.d.cts +3 -0
  49. package/dist/next/api/edge/index.d.mts +3 -0
  50. package/dist/next/api/edge/index.d.ts +3 -0
  51. package/dist/next/api/node/index.d.cts +4 -0
  52. package/dist/next/api/node/index.d.mts +4 -0
  53. package/dist/next/api/node/index.d.ts +4 -0
  54. package/dist/next/index.cjs +11 -0
  55. package/dist/next/index.d.cts +2 -0
  56. package/dist/next/index.d.mts +2 -8
  57. package/dist/next/index.d.ts +2 -8
  58. package/dist/next/index.mjs +2 -4832
  59. package/dist/packem_shared/PrismaAdapter-BTCwgMow.cjs +324 -0
  60. package/dist/packem_shared/PrismaAdapter-dVBZvBOv.mjs +318 -0
  61. package/dist/packem_shared/RouteType-Bk3uAK0x.cjs +14 -0
  62. package/dist/packem_shared/RouteType-CB2xrWdf.mjs +10 -0
  63. package/dist/packem_shared/base-crud-handler-B3eCO4up.cjs +572 -0
  64. package/dist/packem_shared/base-crud-handler-DgrOMhoH.mjs +587 -0
  65. package/dist/packem_shared/edgeHandler-B4JJXPUI.mjs +16 -0
  66. package/dist/packem_shared/edgeHandler-CDFgDdrG.cjs +18 -0
  67. package/dist/packem_shared/get-accessible-routes-C6NF9Iry.cjs +16 -0
  68. package/dist/packem_shared/get-accessible-routes-sV5SDdFn.mjs +14 -0
  69. package/dist/packem_shared/models-to-route-names-CdwsK0V1.mjs +9 -0
  70. package/dist/packem_shared/models-to-route-names-Dv94PzhE.cjs +11 -0
  71. package/dist/{index.js → packem_shared/modelsToOpenApi-BuGL_l3R.cjs} +66 -453
  72. package/dist/packem_shared/modelsToOpenApi-Bux3khmh.mjs +706 -0
  73. package/dist/packem_shared/nodeHandler-BUWSKNyo.cjs +16 -0
  74. package/dist/packem_shared/nodeHandler-DSq7vHzv.mjs +14 -0
  75. package/dist/query-parser.d.cts +3 -0
  76. package/dist/query-parser.d.mts +3 -0
  77. package/dist/query-parser.d.ts +3 -0
  78. package/dist/swagger/adapter/prisma/index.d.cts +22 -0
  79. package/dist/swagger/adapter/prisma/index.d.mts +22 -0
  80. package/dist/swagger/adapter/prisma/index.d.ts +22 -0
  81. package/dist/swagger/json-schema-parser.d.cts +18 -0
  82. package/dist/swagger/json-schema-parser.d.mts +18 -0
  83. package/dist/swagger/json-schema-parser.d.ts +18 -0
  84. package/dist/swagger/parameters.d.cts +5 -0
  85. package/dist/swagger/parameters.d.mts +5 -0
  86. package/dist/swagger/parameters.d.ts +5 -0
  87. package/dist/swagger/types.d.cts +39 -0
  88. package/dist/swagger/types.d.mts +39 -0
  89. package/dist/swagger/types.d.ts +39 -0
  90. package/dist/swagger/utils/format-example-ref.d.cts +2 -0
  91. package/dist/swagger/utils/format-example-ref.d.mts +2 -0
  92. package/dist/swagger/utils/format-example-ref.d.ts +2 -0
  93. package/dist/swagger/utils/format-schema-ref.d.cts +2 -0
  94. package/dist/swagger/utils/format-schema-ref.d.mts +2 -0
  95. package/dist/swagger/utils/format-schema-ref.d.ts +2 -0
  96. package/dist/swagger/utils/get-models-accessible-routes.d.cts +4 -0
  97. package/dist/swagger/utils/get-models-accessible-routes.d.mts +4 -0
  98. package/dist/swagger/utils/get-models-accessible-routes.d.ts +4 -0
  99. package/dist/swagger/utils/get-swagger-paths.d.cts +12 -0
  100. package/dist/swagger/utils/get-swagger-paths.d.mts +12 -0
  101. package/dist/swagger/utils/get-swagger-paths.d.ts +12 -0
  102. package/dist/swagger/utils/get-swagger-tags.d.cts +4 -0
  103. package/dist/swagger/utils/get-swagger-tags.d.mts +4 -0
  104. package/dist/swagger/utils/get-swagger-tags.d.ts +4 -0
  105. package/dist/types.d.cts +106 -0
  106. package/dist/types.d.mts +106 -0
  107. package/dist/types.d.ts +106 -0
  108. package/dist/utils/format-resource-id.d.cts +2 -0
  109. package/dist/utils/format-resource-id.d.mts +2 -0
  110. package/dist/utils/format-resource-id.d.ts +2 -0
  111. package/dist/utils/get-accessible-routes.d.cts +3 -0
  112. package/dist/utils/get-accessible-routes.d.mts +3 -0
  113. package/dist/utils/get-accessible-routes.d.ts +3 -0
  114. package/dist/utils/get-resource-name-from-url.d.cts +5 -0
  115. package/dist/utils/get-resource-name-from-url.d.mts +5 -0
  116. package/dist/utils/get-resource-name-from-url.d.ts +5 -0
  117. package/dist/utils/get-route-type.d.cts +7 -0
  118. package/dist/utils/get-route-type.d.mts +7 -0
  119. package/dist/utils/get-route-type.d.ts +7 -0
  120. package/dist/utils/is-primitive.d.cts +2 -0
  121. package/dist/utils/is-primitive.d.mts +2 -0
  122. package/dist/utils/is-primitive.d.ts +2 -0
  123. package/dist/utils/validate-adapter-methods.d.cts +3 -0
  124. package/dist/utils/validate-adapter-methods.d.mts +3 -0
  125. package/dist/utils/validate-adapter-methods.d.ts +3 -0
  126. package/package.json +38 -19
  127. package/dist/chunk-5I2B5KQG.js +0 -77
  128. package/dist/chunk-5I2B5KQG.js.map +0 -1
  129. package/dist/chunk-LBXJKEOF.mjs +0 -73
  130. package/dist/chunk-LBXJKEOF.mjs.map +0 -1
  131. package/dist/index.js.map +0 -1
  132. package/dist/index.mjs.map +0 -1
  133. package/dist/next/index.js +0 -4839
  134. package/dist/next/index.js.map +0 -1
  135. package/dist/next/index.mjs.map +0 -1
  136. package/dist/types-C5c2M01-.d.mts +0 -138
  137. package/dist/types-C5c2M01-.d.ts +0 -138
@@ -0,0 +1,572 @@
1
+ 'use strict';
2
+
3
+ const createHttpError = require('http-errors');
4
+ const index_js = require('next/dist/server/api-utils/index.js');
5
+ const pagination = require('@visulima/pagination');
6
+ const node_url = require('node:url');
7
+ const RouteType = require('./RouteType-Bk3uAK0x.cjs');
8
+ const getAccessibleRoutes = require('./get-accessible-routes-C6NF9Iry.cjs');
9
+ const pathToRegexp = require('path-to-regexp');
10
+
11
+ const _interopDefaultCompat = e => e && typeof e === 'object' && 'default' in e ? e.default : e;
12
+
13
+ const createHttpError__default = /*#__PURE__*/_interopDefaultCompat(createHttpError);
14
+
15
+ const createHandler = async ({ adapter, query, request, resourceName }) => {
16
+ const resources = await adapter.create(resourceName, request.body, query);
17
+ return {
18
+ data: resources,
19
+ status: 201
20
+ };
21
+ };
22
+
23
+ const deleteHandler = async ({ adapter, query, resourceId, resourceName }) => {
24
+ const resource = await adapter.getOne(resourceName, resourceId, query);
25
+ if (typeof resource === "object") {
26
+ const deletedResource = await adapter.delete(resourceName, resourceId, query);
27
+ return {
28
+ data: deletedResource,
29
+ status: 200
30
+ };
31
+ }
32
+ throw createHttpError__default(404, `${resourceName} ${resourceId} not found`);
33
+ };
34
+
35
+ const listHandler = async ({ adapter, pagination: pagination$1, query, resourceName }) => {
36
+ let isPaginated = false;
37
+ let paginationOptions;
38
+ if (query.page !== void 0) {
39
+ if (query.page <= 0) {
40
+ throw new Error("page query must be a strictly positive number");
41
+ }
42
+ paginationOptions = {
43
+ page: query.page,
44
+ perPage: query.limit ?? pagination$1.perPage
45
+ };
46
+ }
47
+ if (paginationOptions) {
48
+ isPaginated = true;
49
+ query.skip = (paginationOptions.page - 1) * paginationOptions.perPage;
50
+ query.limit = paginationOptions.perPage;
51
+ }
52
+ const resources = await adapter.getAll(resourceName, query);
53
+ if (isPaginated) {
54
+ const { page, total } = await adapter.getPaginationData(resourceName, query);
55
+ const paginator = pagination.paginate(page, paginationOptions.perPage, total, resources);
56
+ return {
57
+ data: paginator.toJSON(),
58
+ status: 200
59
+ };
60
+ }
61
+ return {
62
+ data: resources,
63
+ status: 200
64
+ };
65
+ };
66
+
67
+ const readHandler = async ({ adapter, query, resourceId, resourceName }) => {
68
+ const resource = await adapter.getOne(resourceName, resourceId, query);
69
+ if (typeof resource !== "object") {
70
+ throw createHttpError__default(404, `${resourceName} ${resourceId} not found`);
71
+ }
72
+ return {
73
+ data: resource,
74
+ status: 200
75
+ };
76
+ };
77
+
78
+ const updateHandler = async ({ adapter, query, request, resourceId, resourceName }) => {
79
+ const resource = await adapter.getOne(resourceName, resourceId, query);
80
+ if (typeof resource === "object") {
81
+ const updatedResource = await adapter.update(resourceName, resourceId, request.body, query);
82
+ return {
83
+ data: updatedResource,
84
+ status: 201
85
+ };
86
+ }
87
+ throw createHttpError__default(404, `${resourceName} ${resourceId} not found`);
88
+ };
89
+
90
+ const isObject = (value) => {
91
+ const type = typeof value;
92
+ return value !== null && (type === "object" || type === "function");
93
+ };
94
+ const disallowedKeys = /* @__PURE__ */ new Set([
95
+ "__proto__",
96
+ "prototype",
97
+ "constructor"
98
+ ]);
99
+ const MAX_ARRAY_INDEX = 1e6;
100
+ const isDigit = (character) => character >= "0" && character <= "9";
101
+ function shouldCoerceToNumber(segment) {
102
+ if (segment === "0") {
103
+ return true;
104
+ }
105
+ if (/^[1-9]\d*$/.test(segment)) {
106
+ const parsedNumber = Number.parseInt(segment, 10);
107
+ return parsedNumber <= Number.MAX_SAFE_INTEGER && parsedNumber <= MAX_ARRAY_INDEX;
108
+ }
109
+ return false;
110
+ }
111
+ function processSegment(segment, parts) {
112
+ if (disallowedKeys.has(segment)) {
113
+ return false;
114
+ }
115
+ if (segment && shouldCoerceToNumber(segment)) {
116
+ parts.push(Number.parseInt(segment, 10));
117
+ } else {
118
+ parts.push(segment);
119
+ }
120
+ return true;
121
+ }
122
+ function parsePath(path) {
123
+ if (typeof path !== "string") {
124
+ throw new TypeError(`Expected a string, got ${typeof path}`);
125
+ }
126
+ const parts = [];
127
+ let currentSegment = "";
128
+ let currentPart = "start";
129
+ let isEscaping = false;
130
+ let position = 0;
131
+ for (const character of path) {
132
+ position++;
133
+ if (isEscaping) {
134
+ currentSegment += character;
135
+ isEscaping = false;
136
+ continue;
137
+ }
138
+ if (character === "\\") {
139
+ if (currentPart === "index") {
140
+ throw new Error(`Invalid character '${character}' in an index at position ${position}`);
141
+ }
142
+ if (currentPart === "indexEnd") {
143
+ throw new Error(`Invalid character '${character}' after an index at position ${position}`);
144
+ }
145
+ isEscaping = true;
146
+ currentPart = currentPart === "start" ? "property" : currentPart;
147
+ continue;
148
+ }
149
+ switch (character) {
150
+ case ".": {
151
+ if (currentPart === "index") {
152
+ throw new Error(`Invalid character '${character}' in an index at position ${position}`);
153
+ }
154
+ if (currentPart === "indexEnd") {
155
+ currentPart = "property";
156
+ break;
157
+ }
158
+ if (!processSegment(currentSegment, parts)) {
159
+ return [];
160
+ }
161
+ currentSegment = "";
162
+ currentPart = "property";
163
+ break;
164
+ }
165
+ case "[": {
166
+ if (currentPart === "index") {
167
+ throw new Error(`Invalid character '${character}' in an index at position ${position}`);
168
+ }
169
+ if (currentPart === "indexEnd") {
170
+ currentPart = "index";
171
+ break;
172
+ }
173
+ if (currentPart === "property" || currentPart === "start") {
174
+ if ((currentSegment || currentPart === "property") && !processSegment(currentSegment, parts)) {
175
+ return [];
176
+ }
177
+ currentSegment = "";
178
+ }
179
+ currentPart = "index";
180
+ break;
181
+ }
182
+ case "]": {
183
+ if (currentPart === "index") {
184
+ if (currentSegment === "") {
185
+ const lastSegment = parts.pop() || "";
186
+ currentSegment = lastSegment + "[]";
187
+ currentPart = "property";
188
+ } else {
189
+ const parsedNumber = Number.parseInt(currentSegment, 10);
190
+ const isValidInteger = !Number.isNaN(parsedNumber) && Number.isFinite(parsedNumber) && parsedNumber >= 0 && parsedNumber <= Number.MAX_SAFE_INTEGER && parsedNumber <= MAX_ARRAY_INDEX && currentSegment === String(parsedNumber);
191
+ if (isValidInteger) {
192
+ parts.push(parsedNumber);
193
+ } else {
194
+ parts.push(currentSegment);
195
+ }
196
+ currentSegment = "";
197
+ currentPart = "indexEnd";
198
+ }
199
+ break;
200
+ }
201
+ if (currentPart === "indexEnd") {
202
+ throw new Error(`Invalid character '${character}' after an index at position ${position}`);
203
+ }
204
+ currentSegment += character;
205
+ break;
206
+ }
207
+ default: {
208
+ if (currentPart === "index" && !isDigit(character)) {
209
+ throw new Error(`Invalid character '${character}' in an index at position ${position}`);
210
+ }
211
+ if (currentPart === "indexEnd") {
212
+ throw new Error(`Invalid character '${character}' after an index at position ${position}`);
213
+ }
214
+ if (currentPart === "start") {
215
+ currentPart = "property";
216
+ }
217
+ currentSegment += character;
218
+ }
219
+ }
220
+ }
221
+ if (isEscaping) {
222
+ currentSegment += "\\";
223
+ }
224
+ switch (currentPart) {
225
+ case "property": {
226
+ if (!processSegment(currentSegment, parts)) {
227
+ return [];
228
+ }
229
+ break;
230
+ }
231
+ case "index": {
232
+ throw new Error("Index was not closed");
233
+ }
234
+ case "start": {
235
+ parts.push("");
236
+ break;
237
+ }
238
+ }
239
+ return parts;
240
+ }
241
+ function normalizePath(path) {
242
+ if (typeof path === "string") {
243
+ return parsePath(path);
244
+ }
245
+ if (Array.isArray(path)) {
246
+ const normalized = [];
247
+ for (const [index, segment] of path.entries()) {
248
+ if (typeof segment !== "string" && typeof segment !== "number") {
249
+ throw new TypeError(`Expected a string or number for path segment at index ${index}, got ${typeof segment}`);
250
+ }
251
+ if (typeof segment === "number" && !Number.isFinite(segment)) {
252
+ throw new TypeError(`Path segment at index ${index} must be a finite number, got ${segment}`);
253
+ }
254
+ if (disallowedKeys.has(segment)) {
255
+ return [];
256
+ }
257
+ if (typeof segment === "string" && shouldCoerceToNumber(segment)) {
258
+ normalized.push(Number.parseInt(segment, 10));
259
+ } else {
260
+ normalized.push(segment);
261
+ }
262
+ }
263
+ return normalized;
264
+ }
265
+ return [];
266
+ }
267
+ function setProperty(object, path, value) {
268
+ if (!isObject(object) || typeof path !== "string" && !Array.isArray(path)) {
269
+ return object;
270
+ }
271
+ const root = object;
272
+ const pathArray = normalizePath(path);
273
+ if (pathArray.length === 0) {
274
+ return object;
275
+ }
276
+ for (let index = 0; index < pathArray.length; index++) {
277
+ const key = pathArray[index];
278
+ if (index === pathArray.length - 1) {
279
+ object[key] = value;
280
+ } else if (!isObject(object[key])) {
281
+ const nextKey = pathArray[index + 1];
282
+ const shouldCreateArray = typeof nextKey === "number";
283
+ object[key] = shouldCreateArray ? [] : {};
284
+ }
285
+ object = object[key];
286
+ }
287
+ return root;
288
+ }
289
+
290
+ const parseRecursive = (select) => {
291
+ const selectFields = {};
292
+ const fields = select.split(",");
293
+ fields.forEach((field) => {
294
+ setProperty(selectFields, field, true);
295
+ });
296
+ return selectFields;
297
+ };
298
+ const parseWhere = (where) => {
299
+ const whereObject = JSON.parse(where);
300
+ const parsed = {};
301
+ Object.keys(whereObject).forEach((key) => {
302
+ setProperty(parsed, key, whereObject[key]);
303
+ });
304
+ return parsed;
305
+ };
306
+ const parseOrderBy = (orderBy) => {
307
+ const parsed = {};
308
+ const orderByObject = JSON.parse(orderBy);
309
+ if (Object.keys(orderByObject).length > 0) {
310
+ const key = Object.keys(orderByObject)[0];
311
+ if (orderByObject[key] === "$asc" || orderByObject[key] === "$desc") {
312
+ parsed[key] = orderByObject[key];
313
+ }
314
+ }
315
+ if (Object.keys(parsed).length !== 1) {
316
+ throw new Error("orderBy needs to be an object with exactly 1 property with either $asc or $desc value");
317
+ }
318
+ return parsed;
319
+ };
320
+ const parseQuery = (url) => {
321
+ if (url) {
322
+ const { searchParams } = new node_url.URL(url);
323
+ const parsedQuery = {};
324
+ if (searchParams.get("select")) {
325
+ parsedQuery.select = parseRecursive(searchParams.get("select"));
326
+ }
327
+ if (searchParams.get("include")) {
328
+ parsedQuery.include = parseRecursive(searchParams.get("include"));
329
+ }
330
+ if (searchParams.get("where")) {
331
+ parsedQuery.where = parseWhere(searchParams.get("where"));
332
+ }
333
+ if (searchParams.get("orderBy")) {
334
+ parsedQuery.orderBy = parseOrderBy(searchParams.get("orderBy"));
335
+ }
336
+ if (searchParams.has("limit")) {
337
+ parsedQuery.limit = Number.isFinite(+searchParams.get("limit")) ? +searchParams.get("limit") : void 0;
338
+ }
339
+ if (searchParams.has("skip")) {
340
+ parsedQuery.skip = Number.isFinite(+searchParams.get("skip")) ? +searchParams.get("skip") : void 0;
341
+ }
342
+ if (searchParams.get("distinct")) {
343
+ parsedQuery.distinct = searchParams.get("distinct");
344
+ }
345
+ if (searchParams.get("page")) {
346
+ parsedQuery.page = Number.isFinite(+searchParams.get("page")) ? +searchParams.get("page") : void 0;
347
+ }
348
+ return {
349
+ originalQuery: Object.fromEntries(searchParams.entries()),
350
+ ...parsedQuery
351
+ };
352
+ }
353
+ return {};
354
+ };
355
+
356
+ const formatResourceId = (resourceId) => Number.isSafeInteger(+resourceId) ? +resourceId : resourceId;
357
+
358
+ const ensureCamelCase = (string_) => `${string_.charAt(0).toLowerCase()}${string_.slice(1)}`;
359
+ const getResourceNameFromUrl = (url, models) => {
360
+ const realPath = url.split("?")[0];
361
+ if (realPath === void 0) {
362
+ throw new TypeError("Path is undefined");
363
+ }
364
+ const modelName = Object.keys(models).find((name) => {
365
+ const routeName = models[name];
366
+ const camelCaseModel = ensureCamelCase(routeName);
367
+ return new RegExp(`(${routeName}|${camelCaseModel}$)|(${routeName}|${camelCaseModel}/)`, "g").test(realPath);
368
+ });
369
+ if (modelName === void 0) {
370
+ throw new Error(`Couldn't find model ${modelName} name for url ${url}`);
371
+ }
372
+ return {
373
+ modelName,
374
+ resourceName: models[modelName]
375
+ };
376
+ };
377
+
378
+ const getRouteType = (method, url, resourceName) => {
379
+ const realPath = url.split("?")[0];
380
+ if (realPath === void 0) {
381
+ throw new TypeError("Path is undefined");
382
+ }
383
+ if (!realPath.includes(`/${resourceName}`)) {
384
+ throw new Error(`invalid resource name '${resourceName}' for route '${realPath}'`);
385
+ }
386
+ const entityMatcher = pathToRegexp.match(`/*placeholder/${resourceName}{/:id}`, { decode: decodeURIComponent });
387
+ const simpleMatcher = pathToRegexp.match(`/*placeholder/${resourceName}`, {
388
+ decode: decodeURIComponent
389
+ });
390
+ switch (method) {
391
+ case "DELETE": {
392
+ const pathMatch = entityMatcher(realPath);
393
+ if (typeof pathMatch === "object" && pathMatch.params.id) {
394
+ return {
395
+ resourceId: pathMatch.params.id,
396
+ routeType: RouteType.RouteType.DELETE
397
+ };
398
+ }
399
+ return {
400
+ routeType: null
401
+ };
402
+ }
403
+ case "GET": {
404
+ const pathMatch = entityMatcher(realPath);
405
+ console.log(pathMatch);
406
+ if (typeof pathMatch === "object" && pathMatch.params?.id) {
407
+ return {
408
+ resourceId: pathMatch.params.id,
409
+ routeType: RouteType.RouteType.READ_ONE
410
+ };
411
+ }
412
+ return {
413
+ routeType: RouteType.RouteType.READ_ALL
414
+ };
415
+ }
416
+ case "PATCH":
417
+ case "PUT": {
418
+ const pathMatch = entityMatcher(realPath);
419
+ if (typeof pathMatch === "object" && pathMatch.params.id) {
420
+ return {
421
+ resourceId: pathMatch.params.id,
422
+ routeType: RouteType.RouteType.UPDATE
423
+ };
424
+ }
425
+ return {
426
+ routeType: null
427
+ };
428
+ }
429
+ case "POST": {
430
+ const pathMatch = simpleMatcher(realPath);
431
+ if (pathMatch) {
432
+ return {
433
+ routeType: RouteType.RouteType.CREATE
434
+ };
435
+ }
436
+ return {
437
+ routeType: null
438
+ };
439
+ }
440
+ default: {
441
+ return {
442
+ routeType: null
443
+ };
444
+ }
445
+ }
446
+ };
447
+
448
+ const adapterMethods = ["create", "delete", "getAll", "getOne", "parseQuery", "update", "getPaginationData", "getModels"];
449
+ const validateAdapterMethods = (adapter) => {
450
+ adapterMethods.forEach((method) => {
451
+ if (!adapter[method]) {
452
+ throw createHttpError__default(500, `Adapter must implement the "${method}" method.`);
453
+ }
454
+ });
455
+ };
456
+
457
+ async function baseHandler(responseExecutor, finalExecutor, adapter, options) {
458
+ try {
459
+ validateAdapterMethods(adapter);
460
+ } catch (error_) {
461
+ const error = error_;
462
+ throw new index_js.ApiError(error.statusCode, error.message);
463
+ }
464
+ await adapter.init?.();
465
+ const config = {
466
+ formatResourceId,
467
+ pagination: {
468
+ perPage: 20
469
+ },
470
+ ...options
471
+ };
472
+ const routeNames = await adapter.mapModelsToRouteNames?.();
473
+ const modelRoutes = {};
474
+ adapter.getModels().forEach((modelName) => {
475
+ modelRoutes[modelName] = config.models?.[modelName]?.name ?? routeNames?.[modelName] ?? modelName;
476
+ });
477
+ return async (request, responseOrContext) => {
478
+ const { modelName, resourceName } = getResourceNameFromUrl(request.url, modelRoutes);
479
+ if (!resourceName) {
480
+ {
481
+ const mappedModels = await adapter.mapModelsToRouteNames?.();
482
+ if (typeof mappedModels === "object") {
483
+ throw createHttpError__default(404, `Resource not found, possible models: ${Object.values(mappedModels).join(", ")}`);
484
+ }
485
+ }
486
+ throw createHttpError__default(404, `Resource not found: ${request.url}`);
487
+ }
488
+ const { resourceId, routeType } = getRouteType(request.method, request.url, resourceName);
489
+ if (routeType === null) {
490
+ throw createHttpError__default(404, `Route not found: ${request.url}`);
491
+ }
492
+ const modelConfig = options?.models?.[modelName];
493
+ const accessibleRoutes = getAccessibleRoutes.getAccessibleRoutes(modelConfig?.only, modelConfig?.exclude, options?.exposeStrategy ?? "all");
494
+ if (!accessibleRoutes.includes(routeType)) {
495
+ throw createHttpError__default(404, `Route not found: ${request.url}`);
496
+ }
497
+ try {
498
+ const resourceIdFormatted = modelConfig?.formatResourceId?.(resourceId) ?? config.formatResourceId(resourceId);
499
+ await adapter.connect?.();
500
+ const parsedQuery = parseQuery(`https://${request.headers.host?.replace(/\/$/u, "")}/${request.url}`);
501
+ const parameters = {
502
+ adapter,
503
+ query: adapter.parseQuery(modelName, parsedQuery),
504
+ resourceName: modelName
505
+ };
506
+ try {
507
+ let responseConfig;
508
+ switch (routeType) {
509
+ case RouteType.RouteType.CREATE: {
510
+ responseConfig = await (config.handlers?.create ?? createHandler)({
511
+ ...parameters,
512
+ request
513
+ });
514
+ break;
515
+ }
516
+ case RouteType.RouteType.DELETE: {
517
+ responseConfig = await (config.handlers?.delete ?? deleteHandler)({
518
+ ...parameters,
519
+ resourceId: resourceIdFormatted
520
+ });
521
+ break;
522
+ }
523
+ case RouteType.RouteType.READ_ALL: {
524
+ responseConfig = await (config.handlers?.list ?? listHandler)({
525
+ ...parameters,
526
+ pagination: config.pagination,
527
+ query: {
528
+ ...parameters.query,
529
+ limit: parsedQuery.limit ? Number(parsedQuery.limit) : void 0,
530
+ page: parsedQuery.page ? Number(parsedQuery.page) : void 0
531
+ }
532
+ });
533
+ break;
534
+ }
535
+ case RouteType.RouteType.READ_ONE: {
536
+ responseConfig = await (config.handlers?.get ?? readHandler)({
537
+ ...parameters,
538
+ resourceId: resourceIdFormatted
539
+ });
540
+ break;
541
+ }
542
+ case RouteType.RouteType.UPDATE: {
543
+ responseConfig = await (config.handlers?.update ?? updateHandler)({
544
+ ...parameters,
545
+ request,
546
+ resourceId: resourceIdFormatted
547
+ });
548
+ break;
549
+ }
550
+ default: {
551
+ responseConfig = {
552
+ data: "Method not found",
553
+ status: 404
554
+ };
555
+ }
556
+ }
557
+ await responseExecutor(responseOrContext, responseConfig);
558
+ } catch (error) {
559
+ if (adapter.handleError && !(error instanceof index_js.ApiError)) {
560
+ adapter.handleError(error);
561
+ } else {
562
+ throw error;
563
+ }
564
+ }
565
+ } finally {
566
+ await adapter.disconnect?.();
567
+ await finalExecutor(responseOrContext);
568
+ }
569
+ };
570
+ }
571
+
572
+ exports.baseHandler = baseHandler;