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