@visulima/crud 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.
Files changed (53) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/LICENSE.md +21 -0
  3. package/README.md +101 -0
  4. package/dist/chunk-FJWRITBO.js +52 -0
  5. package/dist/chunk-FJWRITBO.js.map +1 -0
  6. package/dist/chunk-UBXIGP5H.mjs +52 -0
  7. package/dist/chunk-UBXIGP5H.mjs.map +1 -0
  8. package/dist/index.d.ts +155 -0
  9. package/dist/index.js +1101 -0
  10. package/dist/index.js.map +1 -0
  11. package/dist/index.mjs +1101 -0
  12. package/dist/index.mjs.map +1 -0
  13. package/dist/next/index.d.ts +8 -0
  14. package/dist/next/index.js +729 -0
  15. package/dist/next/index.js.map +1 -0
  16. package/dist/next/index.mjs +729 -0
  17. package/dist/next/index.mjs.map +1 -0
  18. package/dist/types.d-6817d247.d.ts +155 -0
  19. package/package.json +136 -0
  20. package/src/adapter/prisma/index.ts +241 -0
  21. package/src/adapter/prisma/types.d.ts +46 -0
  22. package/src/adapter/prisma/utils/models-to-route-names.ts +12 -0
  23. package/src/adapter/prisma/utils/parse-cursor.ts +26 -0
  24. package/src/adapter/prisma/utils/parse-order-by.ts +21 -0
  25. package/src/adapter/prisma/utils/parse-recursive.ts +26 -0
  26. package/src/adapter/prisma/utils/parse-where.ts +197 -0
  27. package/src/base-crud-handler.ts +181 -0
  28. package/src/handler/create.ts +21 -0
  29. package/src/handler/delete.ts +27 -0
  30. package/src/handler/list.ts +62 -0
  31. package/src/handler/read.ts +27 -0
  32. package/src/handler/update.ts +29 -0
  33. package/src/index.ts +27 -0
  34. package/src/next/api/edge/index.ts +23 -0
  35. package/src/next/api/node/index.ts +27 -0
  36. package/src/next/index.ts +2 -0
  37. package/src/query-parser.ts +94 -0
  38. package/src/swagger/adapter/prisma/index.ts +95 -0
  39. package/src/swagger/json-schema-parser.ts +456 -0
  40. package/src/swagger/parameters.ts +83 -0
  41. package/src/swagger/types.d.ts +53 -0
  42. package/src/swagger/utils/format-example-ref.ts +4 -0
  43. package/src/swagger/utils/format-schema-ref.ts +4 -0
  44. package/src/swagger/utils/get-models-accessible-routes.ts +23 -0
  45. package/src/swagger/utils/get-swagger-paths.ts +244 -0
  46. package/src/swagger/utils/get-swagger-tags.ts +13 -0
  47. package/src/types.d.ts +124 -0
  48. package/src/utils/format-resource-id.ts +3 -0
  49. package/src/utils/get-accessible-routes.ts +18 -0
  50. package/src/utils/get-resource-name-from-url.ts +23 -0
  51. package/src/utils/get-route-type.ts +99 -0
  52. package/src/utils/is-primitive.ts +5 -0
  53. package/src/utils/validate-adapter-methods.ts +15 -0
@@ -0,0 +1,729 @@
1
+ import {
2
+ __commonJS,
3
+ __toESM,
4
+ get_accessible_routes_default
5
+ } from "../chunk-UBXIGP5H.mjs";
6
+
7
+ // ../../node_modules/.pnpm/next@12.3.1/node_modules/next/dist/compiled/cookie/index.js
8
+ var require_cookie = __commonJS({
9
+ "../../node_modules/.pnpm/next@12.3.1/node_modules/next/dist/compiled/cookie/index.js"(exports, module) {
10
+ (() => {
11
+ "use strict";
12
+ if (typeof __nccwpck_require__ !== "undefined")
13
+ __nccwpck_require__.ab = __dirname + "/";
14
+ var e = {};
15
+ (() => {
16
+ var r = e;
17
+ r.parse = parse2;
18
+ r.serialize = serialize;
19
+ var i = decodeURIComponent;
20
+ var t = encodeURIComponent;
21
+ var a = /; */;
22
+ var n = /^[\u0009\u0020-\u007e\u0080-\u00ff]+$/;
23
+ function parse2(e2, r2) {
24
+ if (typeof e2 !== "string") {
25
+ throw new TypeError("argument str must be a string");
26
+ }
27
+ var t2 = {};
28
+ var n2 = r2 || {};
29
+ var o = e2.split(a);
30
+ var s = n2.decode || i;
31
+ for (var p = 0; p < o.length; p++) {
32
+ var f = o[p];
33
+ var u = f.indexOf("=");
34
+ if (u < 0) {
35
+ continue;
36
+ }
37
+ var v = f.substr(0, u).trim();
38
+ var c = f.substr(++u, f.length).trim();
39
+ if ('"' == c[0]) {
40
+ c = c.slice(1, -1);
41
+ }
42
+ if (void 0 == t2[v]) {
43
+ t2[v] = tryDecode(c, s);
44
+ }
45
+ }
46
+ return t2;
47
+ }
48
+ function serialize(e2, r2, i2) {
49
+ var a2 = i2 || {};
50
+ var o = a2.encode || t;
51
+ if (typeof o !== "function") {
52
+ throw new TypeError("option encode is invalid");
53
+ }
54
+ if (!n.test(e2)) {
55
+ throw new TypeError("argument name is invalid");
56
+ }
57
+ var s = o(r2);
58
+ if (s && !n.test(s)) {
59
+ throw new TypeError("argument val is invalid");
60
+ }
61
+ var p = e2 + "=" + s;
62
+ if (null != a2.maxAge) {
63
+ var f = a2.maxAge - 0;
64
+ if (isNaN(f) || !isFinite(f)) {
65
+ throw new TypeError("option maxAge is invalid");
66
+ }
67
+ p += "; Max-Age=" + Math.floor(f);
68
+ }
69
+ if (a2.domain) {
70
+ if (!n.test(a2.domain)) {
71
+ throw new TypeError("option domain is invalid");
72
+ }
73
+ p += "; Domain=" + a2.domain;
74
+ }
75
+ if (a2.path) {
76
+ if (!n.test(a2.path)) {
77
+ throw new TypeError("option path is invalid");
78
+ }
79
+ p += "; Path=" + a2.path;
80
+ }
81
+ if (a2.expires) {
82
+ if (typeof a2.expires.toUTCString !== "function") {
83
+ throw new TypeError("option expires is invalid");
84
+ }
85
+ p += "; Expires=" + a2.expires.toUTCString();
86
+ }
87
+ if (a2.httpOnly) {
88
+ p += "; HttpOnly";
89
+ }
90
+ if (a2.secure) {
91
+ p += "; Secure";
92
+ }
93
+ if (a2.sameSite) {
94
+ var u = typeof a2.sameSite === "string" ? a2.sameSite.toLowerCase() : a2.sameSite;
95
+ switch (u) {
96
+ case true:
97
+ p += "; SameSite=Strict";
98
+ break;
99
+ case "lax":
100
+ p += "; SameSite=Lax";
101
+ break;
102
+ case "strict":
103
+ p += "; SameSite=Strict";
104
+ break;
105
+ case "none":
106
+ p += "; SameSite=None";
107
+ break;
108
+ default:
109
+ throw new TypeError("option sameSite is invalid");
110
+ }
111
+ }
112
+ return p;
113
+ }
114
+ function tryDecode(e2, r2) {
115
+ try {
116
+ return r2(e2);
117
+ } catch (r3) {
118
+ return e2;
119
+ }
120
+ }
121
+ })();
122
+ module.exports = e;
123
+ })();
124
+ }
125
+ });
126
+
127
+ // ../../node_modules/.pnpm/next@12.3.1/node_modules/next/dist/server/api-utils/index.js
128
+ var require_api_utils = __commonJS({
129
+ "../../node_modules/.pnpm/next@12.3.1/node_modules/next/dist/server/api-utils/index.js"(exports) {
130
+ "use strict";
131
+ Object.defineProperty(exports, "__esModule", {
132
+ value: true
133
+ });
134
+ exports.getCookieParser = getCookieParser;
135
+ exports.sendStatusCode = sendStatusCode;
136
+ exports.redirect = redirect;
137
+ exports.checkIsManualRevalidate = checkIsManualRevalidate;
138
+ exports.clearPreviewData = clearPreviewData;
139
+ exports.sendError = sendError;
140
+ exports.setLazyProp = setLazyProp;
141
+ exports.SYMBOL_CLEARED_COOKIES = exports.SYMBOL_PREVIEW_DATA = exports.RESPONSE_LIMIT_DEFAULT = exports.COOKIE_NAME_PRERENDER_DATA = exports.COOKIE_NAME_PRERENDER_BYPASS = exports.PRERENDER_REVALIDATE_ONLY_GENERATED_HEADER = exports.PRERENDER_REVALIDATE_HEADER = void 0;
142
+ function getCookieParser(headers) {
143
+ return function parseCookie() {
144
+ const header = headers.cookie;
145
+ if (!header) {
146
+ return {};
147
+ }
148
+ const { parse: parseCookieFn } = require_cookie();
149
+ return parseCookieFn(Array.isArray(header) ? header.join(";") : header);
150
+ };
151
+ }
152
+ function sendStatusCode(res, statusCode) {
153
+ res.statusCode = statusCode;
154
+ return res;
155
+ }
156
+ function redirect(res, statusOrUrl, url) {
157
+ if (typeof statusOrUrl === "string") {
158
+ url = statusOrUrl;
159
+ statusOrUrl = 307;
160
+ }
161
+ if (typeof statusOrUrl !== "number" || typeof url !== "string") {
162
+ throw new Error(`Invalid redirect arguments. Please use a single argument URL, e.g. res.redirect('/destination') or use a status code and URL, e.g. res.redirect(307, '/destination').`);
163
+ }
164
+ res.writeHead(statusOrUrl, {
165
+ Location: url
166
+ });
167
+ res.write(url);
168
+ res.end();
169
+ return res;
170
+ }
171
+ var PRERENDER_REVALIDATE_HEADER = "x-prerender-revalidate";
172
+ exports.PRERENDER_REVALIDATE_HEADER = PRERENDER_REVALIDATE_HEADER;
173
+ var PRERENDER_REVALIDATE_ONLY_GENERATED_HEADER = "x-prerender-revalidate-if-generated";
174
+ exports.PRERENDER_REVALIDATE_ONLY_GENERATED_HEADER = PRERENDER_REVALIDATE_ONLY_GENERATED_HEADER;
175
+ function checkIsManualRevalidate(req, previewProps) {
176
+ return {
177
+ isManualRevalidate: req.headers[PRERENDER_REVALIDATE_HEADER] === previewProps.previewModeId,
178
+ revalidateOnlyGenerated: !!req.headers[PRERENDER_REVALIDATE_ONLY_GENERATED_HEADER]
179
+ };
180
+ }
181
+ var COOKIE_NAME_PRERENDER_BYPASS = `__prerender_bypass`;
182
+ exports.COOKIE_NAME_PRERENDER_BYPASS = COOKIE_NAME_PRERENDER_BYPASS;
183
+ var COOKIE_NAME_PRERENDER_DATA = `__next_preview_data`;
184
+ exports.COOKIE_NAME_PRERENDER_DATA = COOKIE_NAME_PRERENDER_DATA;
185
+ var RESPONSE_LIMIT_DEFAULT = 4 * 1024 * 1024;
186
+ exports.RESPONSE_LIMIT_DEFAULT = RESPONSE_LIMIT_DEFAULT;
187
+ var SYMBOL_PREVIEW_DATA = Symbol(COOKIE_NAME_PRERENDER_DATA);
188
+ exports.SYMBOL_PREVIEW_DATA = SYMBOL_PREVIEW_DATA;
189
+ var SYMBOL_CLEARED_COOKIES = Symbol(COOKIE_NAME_PRERENDER_BYPASS);
190
+ exports.SYMBOL_CLEARED_COOKIES = SYMBOL_CLEARED_COOKIES;
191
+ function clearPreviewData(res, options = {}) {
192
+ if (SYMBOL_CLEARED_COOKIES in res) {
193
+ return res;
194
+ }
195
+ const { serialize } = require_cookie();
196
+ const previous = res.getHeader("Set-Cookie");
197
+ res.setHeader(`Set-Cookie`, [
198
+ ...typeof previous === "string" ? [
199
+ previous
200
+ ] : Array.isArray(previous) ? previous : [],
201
+ serialize(COOKIE_NAME_PRERENDER_BYPASS, "", {
202
+ expires: new Date(0),
203
+ httpOnly: true,
204
+ sameSite: false ? "none" : "lax",
205
+ secure: false,
206
+ path: "/",
207
+ ...options.path !== void 0 ? {
208
+ path: options.path
209
+ } : void 0
210
+ }),
211
+ serialize(COOKIE_NAME_PRERENDER_DATA, "", {
212
+ expires: new Date(0),
213
+ httpOnly: true,
214
+ sameSite: false ? "none" : "lax",
215
+ secure: false,
216
+ path: "/",
217
+ ...options.path !== void 0 ? {
218
+ path: options.path
219
+ } : void 0
220
+ })
221
+ ]);
222
+ Object.defineProperty(res, SYMBOL_CLEARED_COOKIES, {
223
+ value: true,
224
+ enumerable: false
225
+ });
226
+ return res;
227
+ }
228
+ var ApiError2 = class extends Error {
229
+ constructor(statusCode, message) {
230
+ super(message);
231
+ this.statusCode = statusCode;
232
+ }
233
+ };
234
+ exports.ApiError = ApiError2;
235
+ function sendError(res, statusCode, message) {
236
+ res.statusCode = statusCode;
237
+ res.statusMessage = message;
238
+ res.end(message);
239
+ }
240
+ function setLazyProp({ req }, prop, getter) {
241
+ const opts = {
242
+ configurable: true,
243
+ enumerable: true
244
+ };
245
+ const optsReset = {
246
+ ...opts,
247
+ writable: true
248
+ };
249
+ Object.defineProperty(req, prop, {
250
+ ...opts,
251
+ get: () => {
252
+ const value = getter();
253
+ Object.defineProperty(req, prop, {
254
+ ...optsReset,
255
+ value
256
+ });
257
+ return value;
258
+ },
259
+ set: (value) => {
260
+ Object.defineProperty(req, prop, {
261
+ ...optsReset,
262
+ value
263
+ });
264
+ }
265
+ });
266
+ }
267
+ }
268
+ });
269
+
270
+ // src/base-crud-handler.ts
271
+ var import_api_utils = __toESM(require_api_utils());
272
+ import createHttpError5 from "http-errors";
273
+
274
+ // src/handler/create.ts
275
+ var createHandler = async ({
276
+ adapter,
277
+ query,
278
+ resourceName,
279
+ request
280
+ }) => {
281
+ const resources = await adapter.create(resourceName, request.body, query);
282
+ return {
283
+ data: resources,
284
+ status: 201
285
+ };
286
+ };
287
+ var create_default = createHandler;
288
+
289
+ // src/handler/delete.ts
290
+ import createHttpError from "http-errors";
291
+ var deleteHandler = async ({
292
+ adapter,
293
+ query,
294
+ resourceName,
295
+ resourceId
296
+ }) => {
297
+ const resource = await adapter.getOne(resourceName, resourceId, query);
298
+ if (resource) {
299
+ const deletedResource = await adapter.delete(resourceName, resourceId, query);
300
+ return {
301
+ data: deletedResource,
302
+ status: 200
303
+ };
304
+ }
305
+ throw createHttpError(404, `${resourceName} ${resourceId} not found`);
306
+ };
307
+ var delete_default = deleteHandler;
308
+
309
+ // src/handler/list.ts
310
+ import { paginate } from "@visulima/pagination";
311
+ var listHandler = async ({
312
+ adapter,
313
+ query,
314
+ resourceName,
315
+ pagination
316
+ }) => {
317
+ let isPaginated = false;
318
+ let paginationOptions;
319
+ if (typeof (query == null ? void 0 : query.page) !== "undefined") {
320
+ if ((query == null ? void 0 : query.page) <= 0) {
321
+ throw new Error("page query must be a strictly positive number");
322
+ }
323
+ paginationOptions = {
324
+ page: query == null ? void 0 : query.page,
325
+ perPage: (query == null ? void 0 : query.limit) || pagination.perPage
326
+ };
327
+ }
328
+ if (paginationOptions) {
329
+ isPaginated = true;
330
+ query.skip = (paginationOptions.page - 1) * paginationOptions.perPage;
331
+ query.limit = paginationOptions.perPage;
332
+ }
333
+ const resources = await adapter.getAll(resourceName, query);
334
+ if (isPaginated) {
335
+ const { page, total } = await adapter.getPaginationData(resourceName, query);
336
+ const paginator = paginate(page, paginationOptions.perPage, total, resources);
337
+ return {
338
+ data: paginator.toJSON(),
339
+ status: 200
340
+ };
341
+ }
342
+ return {
343
+ data: resources,
344
+ status: 200
345
+ };
346
+ };
347
+ var list_default = listHandler;
348
+
349
+ // src/handler/read.ts
350
+ import createHttpError2 from "http-errors";
351
+ var readHandler = async ({
352
+ adapter,
353
+ query,
354
+ resourceName,
355
+ resourceId
356
+ }) => {
357
+ const resource = await adapter.getOne(resourceName, resourceId, query);
358
+ if (!resource) {
359
+ throw createHttpError2(404, `${resourceName} ${resourceId} not found`);
360
+ }
361
+ return {
362
+ data: resource,
363
+ status: 200
364
+ };
365
+ };
366
+ var read_default = readHandler;
367
+
368
+ // src/handler/update.ts
369
+ import createHttpError3 from "http-errors";
370
+ var updateHandler = async ({
371
+ adapter,
372
+ query,
373
+ resourceName,
374
+ resourceId,
375
+ request
376
+ }) => {
377
+ const resource = await adapter.getOne(resourceName, resourceId, query);
378
+ if (resource) {
379
+ const updatedResource = await adapter.update(resourceName, resourceId, request.body, query);
380
+ return {
381
+ status: 201,
382
+ data: updatedResource
383
+ };
384
+ }
385
+ throw createHttpError3(404, `${resourceName} ${resourceId} not found`);
386
+ };
387
+ var update_default = updateHandler;
388
+
389
+ // src/query-parser.ts
390
+ import set from "lodash.set";
391
+ import { parse } from "qs";
392
+ var parseRecursive = (select) => {
393
+ if (typeof select === "string") {
394
+ const selectFields = {};
395
+ const fields = select.split(",");
396
+ fields.forEach((field) => {
397
+ set(selectFields, field, true);
398
+ });
399
+ return selectFields;
400
+ }
401
+ throw new Error("select query param must be a string");
402
+ };
403
+ var parseWhere = (where) => {
404
+ const whereObject = JSON.parse(where);
405
+ const parsed = {};
406
+ Object.keys(whereObject).forEach((key) => {
407
+ set(parsed, key, whereObject[key]);
408
+ });
409
+ return parsed;
410
+ };
411
+ var parseOrderBy = (orderBy) => {
412
+ const parsed = {};
413
+ const orderByObject = JSON.parse(orderBy);
414
+ if (Object.keys(orderByObject).length > 0) {
415
+ const key = Object.keys(orderByObject)[0];
416
+ if (orderByObject[key] === "$asc" || orderByObject[key] === "$desc") {
417
+ parsed[key] = orderByObject[key];
418
+ }
419
+ }
420
+ if (Object.keys(parsed).length !== 1) {
421
+ throw new Error("orderBy needs to be an object with exactly 1 property with either $asc or $desc value");
422
+ }
423
+ return parsed;
424
+ };
425
+ var parseQuery = (queryString) => {
426
+ if (queryString) {
427
+ const query = parse(queryString);
428
+ const parsedQuery = {};
429
+ if (query.select) {
430
+ parsedQuery.select = parseRecursive(query.select);
431
+ }
432
+ if (query.include) {
433
+ parsedQuery.include = parseRecursive(query.include);
434
+ }
435
+ if (query.where) {
436
+ parsedQuery.where = parseWhere(query.where);
437
+ }
438
+ if (query.orderBy) {
439
+ parsedQuery.orderBy = parseOrderBy(query.orderBy);
440
+ }
441
+ if (typeof query.limit !== "undefined") {
442
+ parsedQuery.limit = Number.isFinite(+query.limit) ? +query.limit : void 0;
443
+ }
444
+ if (typeof query.skip !== "undefined") {
445
+ parsedQuery.skip = Number.isFinite(+query.skip) ? +query.skip : void 0;
446
+ }
447
+ if (query.distinct) {
448
+ parsedQuery.distinct = query.distinct;
449
+ }
450
+ if (query.page) {
451
+ parsedQuery.page = Number.isFinite(+query.page) ? +query.page : void 0;
452
+ }
453
+ return {
454
+ originalQuery: query,
455
+ ...parsedQuery
456
+ };
457
+ }
458
+ return {};
459
+ };
460
+ var query_parser_default = parseQuery;
461
+
462
+ // src/utils/format-resource-id.ts
463
+ var formatResourceId = (resourceId) => Number.isSafeInteger(+resourceId) ? +resourceId : resourceId;
464
+ var format_resource_id_default = formatResourceId;
465
+
466
+ // src/utils/get-resource-name-from-url.ts
467
+ var ensureCamelCase = (string_) => `${string_.charAt(0).toLowerCase()}${string_.slice(1)}`;
468
+ var getResourceNameFromUrl = (url, models) => {
469
+ const realPath = url.split("?")[0];
470
+ if (typeof realPath === "undefined") {
471
+ throw new TypeError("Path is undefined");
472
+ }
473
+ const modelName = Object.keys(models).find((name) => {
474
+ const routeName = models[name];
475
+ const camelCaseModel = ensureCamelCase(routeName);
476
+ return new RegExp(`(${routeName}|${camelCaseModel}$)|(${routeName}|${camelCaseModel}/)`, "g").test(realPath);
477
+ });
478
+ return {
479
+ modelName,
480
+ resourceName: models[modelName]
481
+ };
482
+ };
483
+
484
+ // src/utils/get-route-type.ts
485
+ import { match } from "path-to-regexp";
486
+ var getRouteType = (method, url, resourceName) => {
487
+ const realPath = url.split("?")[0];
488
+ if (typeof realPath === "undefined") {
489
+ throw new TypeError("Path is undefined");
490
+ }
491
+ if (!realPath.includes(`/${resourceName}`)) {
492
+ throw new Error(`invalid resource name '${resourceName}' for route '${realPath}'`);
493
+ }
494
+ const entityMatcher = match([`/(.*)/${resourceName}`, `/(.*)/${resourceName}/:id`], { decode: decodeURIComponent });
495
+ const simpleMatcher = match(`/(.*)/${resourceName}`, {
496
+ decode: decodeURIComponent
497
+ });
498
+ switch (method) {
499
+ case "GET": {
500
+ const pathMatch = entityMatcher(realPath);
501
+ if (pathMatch && pathMatch.params.id) {
502
+ return {
503
+ routeType: "READ_ONE" /* READ_ONE */,
504
+ resourceId: pathMatch.params.id
505
+ };
506
+ }
507
+ return {
508
+ routeType: "READ_ALL" /* READ_ALL */
509
+ };
510
+ }
511
+ case "POST": {
512
+ const pathMatch = simpleMatcher(realPath);
513
+ if (pathMatch) {
514
+ return {
515
+ routeType: "CREATE" /* CREATE */
516
+ };
517
+ }
518
+ return {
519
+ routeType: null
520
+ };
521
+ }
522
+ case "PUT":
523
+ case "PATCH": {
524
+ const pathMatch = entityMatcher(realPath);
525
+ if (pathMatch && pathMatch.params.id) {
526
+ return {
527
+ routeType: "UPDATE" /* UPDATE */,
528
+ resourceId: pathMatch.params.id
529
+ };
530
+ }
531
+ return {
532
+ routeType: null
533
+ };
534
+ }
535
+ case "DELETE": {
536
+ const pathMatch = entityMatcher(realPath);
537
+ if (pathMatch && pathMatch.params.id) {
538
+ return {
539
+ routeType: "DELETE" /* DELETE */,
540
+ resourceId: pathMatch.params.id
541
+ };
542
+ }
543
+ return {
544
+ routeType: null
545
+ };
546
+ }
547
+ default: {
548
+ return {
549
+ routeType: null
550
+ };
551
+ }
552
+ }
553
+ };
554
+ var get_route_type_default = getRouteType;
555
+
556
+ // src/utils/validate-adapter-methods.ts
557
+ import createHttpError4 from "http-errors";
558
+ var adapterMethods = ["create"];
559
+ var validateAdapterMethods = (adapter) => {
560
+ adapterMethods.forEach((method) => {
561
+ if (!adapter[method]) {
562
+ throw createHttpError4(500, `Adapter must implement the "${method}" method.`);
563
+ }
564
+ });
565
+ };
566
+ var validate_adapter_methods_default = validateAdapterMethods;
567
+
568
+ // src/base-crud-handler.ts
569
+ async function baseHandler(responseExecutor, finalExecutor, adapter, options) {
570
+ var _a, _b;
571
+ try {
572
+ validate_adapter_methods_default(adapter);
573
+ } catch (error_) {
574
+ const error = error_;
575
+ throw new import_api_utils.ApiError(error.statusCode, error.message);
576
+ }
577
+ await ((_a = adapter.init) == null ? void 0 : _a.call(adapter));
578
+ const config = {
579
+ formatResourceId: format_resource_id_default,
580
+ pagination: {
581
+ perPage: 20
582
+ },
583
+ ...options
584
+ };
585
+ const routeNames = await ((_b = adapter.mapModelsToRouteNames) == null ? void 0 : _b.call(adapter));
586
+ const modelRoutes = {};
587
+ adapter.getModels().forEach((modelName) => {
588
+ var _a2, _b2;
589
+ modelRoutes[modelName] = ((_b2 = (_a2 = config == null ? void 0 : config.models) == null ? void 0 : _a2[modelName]) == null ? void 0 : _b2.name) || (routeNames == null ? void 0 : routeNames[modelName]) || modelName;
590
+ });
591
+ return async (request, responseOrContext) => {
592
+ var _a2, _b2, _c, _d, _e, _f, _g, _h, _i, _j;
593
+ const { resourceName, modelName } = getResourceNameFromUrl(request.url, modelRoutes);
594
+ if (!resourceName) {
595
+ if (true) {
596
+ const mappedModels = await ((_a2 = adapter.mapModelsToRouteNames) == null ? void 0 : _a2.call(adapter));
597
+ if (typeof mappedModels === "object") {
598
+ throw createHttpError5(404, `Resource not found, possible models: ${Object.values(mappedModels).join(", ")}`);
599
+ }
600
+ }
601
+ throw createHttpError5(404, `Resource not found: ${request.url}`);
602
+ }
603
+ const { routeType, resourceId } = get_route_type_default(request.method, request.url, resourceName);
604
+ if (routeType === null) {
605
+ throw createHttpError5(404, `Route not found: ${request.url}`);
606
+ }
607
+ const modelConfig = (_b2 = options == null ? void 0 : options.models) == null ? void 0 : _b2[modelName];
608
+ const accessibleRoutes = get_accessible_routes_default(modelConfig == null ? void 0 : modelConfig.only, modelConfig == null ? void 0 : modelConfig.exclude, (options == null ? void 0 : options.exposeStrategy) || "all");
609
+ if (!accessibleRoutes.includes(routeType)) {
610
+ throw createHttpError5(404, `Route not found: ${request.url}`);
611
+ }
612
+ try {
613
+ const resourceIdFormatted = ((_c = modelConfig == null ? void 0 : modelConfig.formatResourceId) == null ? void 0 : _c.call(modelConfig, resourceId)) ?? config.formatResourceId(resourceId);
614
+ await ((_d = adapter.connect) == null ? void 0 : _d.call(adapter));
615
+ const parsedQuery = query_parser_default(request.url.split("?")[1]);
616
+ const parameters = {
617
+ adapter,
618
+ query: adapter.parseQuery(modelName, parsedQuery),
619
+ resourceName: modelName
620
+ };
621
+ try {
622
+ let responseConfig;
623
+ switch (routeType) {
624
+ case "READ_ONE" /* READ_ONE */: {
625
+ responseConfig = await (((_e = config == null ? void 0 : config.handlers) == null ? void 0 : _e.get) || read_default)({
626
+ ...parameters,
627
+ resourceId: resourceIdFormatted
628
+ });
629
+ break;
630
+ }
631
+ case "READ_ALL" /* READ_ALL */: {
632
+ responseConfig = await (((_f = config == null ? void 0 : config.handlers) == null ? void 0 : _f.list) || list_default)({
633
+ ...parameters,
634
+ query: {
635
+ ...parameters.query,
636
+ page: parsedQuery.page ? Number(parsedQuery.page) : void 0,
637
+ limit: parsedQuery.limit ? Number(parsedQuery.limit) : void 0
638
+ },
639
+ pagination: config.pagination
640
+ });
641
+ break;
642
+ }
643
+ case "CREATE" /* CREATE */: {
644
+ responseConfig = await (((_g = config == null ? void 0 : config.handlers) == null ? void 0 : _g.create) || create_default)({
645
+ ...parameters,
646
+ request
647
+ });
648
+ break;
649
+ }
650
+ case "UPDATE" /* UPDATE */: {
651
+ responseConfig = await (((_h = config == null ? void 0 : config.handlers) == null ? void 0 : _h.update) || update_default)({
652
+ ...parameters,
653
+ resourceId: resourceIdFormatted,
654
+ request
655
+ });
656
+ break;
657
+ }
658
+ case "DELETE" /* DELETE */: {
659
+ responseConfig = await (((_i = config == null ? void 0 : config.handlers) == null ? void 0 : _i.delete) || delete_default)({
660
+ ...parameters,
661
+ resourceId: resourceIdFormatted
662
+ });
663
+ break;
664
+ }
665
+ default: {
666
+ responseConfig = {
667
+ status: 404,
668
+ data: "Method not found"
669
+ };
670
+ }
671
+ }
672
+ await responseExecutor(responseOrContext, responseConfig);
673
+ } catch (error) {
674
+ if (adapter.handleError && !(error instanceof import_api_utils.ApiError)) {
675
+ adapter.handleError(error);
676
+ } else {
677
+ throw error;
678
+ }
679
+ }
680
+ } finally {
681
+ await ((_j = adapter.disconnect) == null ? void 0 : _j.call(adapter));
682
+ await finalExecutor(responseOrContext);
683
+ }
684
+ };
685
+ }
686
+ var base_crud_handler_default = baseHandler;
687
+
688
+ // src/next/api/edge/index.ts
689
+ async function handler(adapter, options) {
690
+ return base_crud_handler_default(
691
+ async (_, responseConfig) => new Response(JSON.stringify(responseConfig.data), {
692
+ status: responseConfig.status,
693
+ headers: {
694
+ "content-type": "application/json; charset=utf-8"
695
+ }
696
+ }),
697
+ async () => {
698
+ },
699
+ adapter,
700
+ options
701
+ );
702
+ }
703
+ var edge_default = handler;
704
+
705
+ // src/next/api/node/index.ts
706
+ async function handler2(adapter, options) {
707
+ return base_crud_handler_default(
708
+ async (response, responseConfig) => {
709
+ response.status(responseConfig.status).send(responseConfig.data);
710
+ },
711
+ async (response) => {
712
+ response.end();
713
+ },
714
+ adapter,
715
+ options
716
+ );
717
+ }
718
+ var node_default = handler2;
719
+ export {
720
+ edge_default as edgeHandler,
721
+ node_default as nodeHandler
722
+ };
723
+ /*!
724
+ * cookie
725
+ * Copyright(c) 2012-2014 Roman Shtylman
726
+ * Copyright(c) 2015 Douglas Christopher Wilson
727
+ * MIT Licensed
728
+ */
729
+ //# sourceMappingURL=index.mjs.map