@ai0x0/utils 0.0.40 → 0.0.42

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 (27) hide show
  1. package/.agents/skills/ai0x0-utils/backend/SKILL.md +15 -11
  2. package/SKILL.md +15 -11
  3. package/es/backend/route-operation/delete-operation.js +1 -1
  4. package/es/backend/route-operation/get-list-operation.js +1 -1
  5. package/es/backend/route-operation/get-operation.js +1 -1
  6. package/es/backend/route-operation/post-operation.d.ts +6 -2
  7. package/es/backend/route-operation/post-operation.js +68 -22
  8. package/es/backend/route-operation/put-operation.js +1 -1
  9. package/es/backend/sqlite/route-operation/delete-operation.js +1 -1
  10. package/es/backend/sqlite/route-operation/get-list-operation.js +1 -1
  11. package/es/backend/sqlite/route-operation/get-operation.js +1 -1
  12. package/es/backend/sqlite/route-operation/post-operation.d.ts +6 -2
  13. package/es/backend/sqlite/route-operation/post-operation.js +68 -22
  14. package/es/backend/sqlite/route-operation/put-operation.js +1 -1
  15. package/lib/backend/route-operation/delete-operation.js +1 -1
  16. package/lib/backend/route-operation/get-list-operation.js +1 -1
  17. package/lib/backend/route-operation/get-operation.js +1 -1
  18. package/lib/backend/route-operation/post-operation.d.ts +6 -2
  19. package/lib/backend/route-operation/post-operation.js +22 -7
  20. package/lib/backend/route-operation/put-operation.js +1 -1
  21. package/lib/backend/sqlite/route-operation/delete-operation.js +1 -1
  22. package/lib/backend/sqlite/route-operation/get-list-operation.js +1 -1
  23. package/lib/backend/sqlite/route-operation/get-operation.js +1 -1
  24. package/lib/backend/sqlite/route-operation/post-operation.d.ts +6 -2
  25. package/lib/backend/sqlite/route-operation/post-operation.js +22 -7
  26. package/lib/backend/sqlite/route-operation/put-operation.js +1 -1
  27. package/package.json +1 -1
@@ -81,22 +81,26 @@ export const getOperation = createGetOperation({ db, getSession });
81
81
  export const getListOperation = createGetListOperation({ db, getSession });
82
82
  ```
83
83
 
84
+ `db` may be omitted for operation-only endpoints that should not touch the database even when `table` is supplied for OpenAPI tags.
85
+
84
86
  `getSession(req)` **must** return `{ userId?: string } | undefined` (a Promise is fine). Throwing rejects the request; returning `undefined` disables ownership checks for that call.
85
87
 
86
88
  ## Factory Catalog
87
89
 
88
- | Export | Purpose | Required options | Notable optional options |
89
- | ------------------- | -------------------------- | --------------------------- | ------------------------------------------------------------------------------------------------------------ |
90
- | `createTableSchema` | pg `Table` + 5 zod schemas | `name`, `columns` | `refineSchema`, `extraConfig` |
91
- | `getOperation` | GET one by filters | `bodySchema`, `querySchema` | `table`, `setParams`, `relations`, `jsonArrayFields`, `byCreator`, `onSuccess`, `onError`, `summary`, `tags` |
92
- | `getListOperation` | GET paginated list | `bodySchema`, `querySchema` | `table`, `setParams`, `relations`, `jsonArrayFields`, `onSuccess`, `onError`, `summary`, `tags` |
93
- | `postOperation` | POST create | `bodySchema` | `table`, `outputBodySchema`, `setBody`, `onSuccess`, `onError`, `summary`, `tags` |
94
- | `putOperation` | PUT update | `bodySchema` | `table`, `outputBodySchema`, `setBody`, `byCreator`, `onSuccess`, `onError`, `summary`, `tags` |
95
- | `deleteOperation` | DELETE | — | `table`, `byCreator`, `onSuccess`, `onError`, `summary`, `tags` |
90
+ | Export | Purpose | Required options | Notable optional options |
91
+ | ------------------- | -------------------------- | --------------------------- | ------------------------------------------------------------------------------------------------------------- |
92
+ | `createTableSchema` | pg `Table` + 5 zod schemas | `name`, `columns` | `refineSchema`, `extraConfig` |
93
+ | `getOperation` | GET one by filters | `bodySchema`, `querySchema` | `table`, `setParams`, `relations`, `jsonArrayFields`, `byCreator`, `onSuccess`, `onError`, `summary`, `tags` |
94
+ | `getListOperation` | GET paginated list | `bodySchema`, `querySchema` | `table`, `setParams`, `relations`, `jsonArrayFields`, `onSuccess`, `onError`, `summary`, `tags` |
95
+ | `postOperation` | POST create | `bodySchema` | `table`, `contentType`, `parseBody`, `outputBodySchema`, `setBody`, `onSuccess`, `onError`, `summary`, `tags` |
96
+ | `putOperation` | PUT update | `bodySchema` | `table`, `outputBodySchema`, `setBody`, `byCreator`, `onSuccess`, `onError`, `summary`, `tags` |
97
+ | `deleteOperation` | DELETE | — | `table`, `byCreator`, `onSuccess`, `onError`, `summary`, `tags` |
96
98
 
97
99
  `tags` can be passed manually to override the default OpenAPI tag inferred from `table`.
98
100
 
99
- `table` is optional for route operations. When omitted, the operation still parses input, applies `setParams` / `setBody`, session-derived fields, and `onSuccess`, but skips the built-in table action (`select` / `insert` / `update` / `delete`). Use this for custom endpoints that want the same OpenAPI and response wiring without a direct table operation.
101
+ `postOperation` defaults to `contentType: "application/json"`. Pass `contentType: "multipart/form-data"` to read `await req.formData()` as body, or pass both a custom `contentType` and `parseBody(req)` for custom payload parsing.
102
+
103
+ `table` and factory-level `db` are optional for route operations. When `table` is omitted or `db` is not provided, the operation still parses input, applies `setParams` / `setBody`, session-derived fields, and `onSuccess`, but skips the built-in table action (`select` / `insert` / `update` / `delete`). Use this for custom endpoints that want the same OpenAPI and response wiring without a direct table operation.
100
104
 
101
105
  ## Canonical Examples
102
106
 
@@ -340,13 +344,13 @@ export const { GET } = route({
340
344
  - Do not inline `{ db, getSession }` into individual route files — always import the pre-bound `postOperation` / `getListOperation` / … from `@backend/utils/route-operation` so session/DB swaps are one-file changes.
341
345
  - `jsonb` columns declared with `jsonb(...)` carry no zod info — extend the matching insert/select schema with `.merge(z.object({ field: z.array(z.string()).optional() }))` to keep typing accurate.
342
346
  - Swallowing errors: an unhandled throw in a handler propagates to next-rest-framework as a 500. Provide `onError` for any operation exposed to untrusted clients.
343
- - For non-CRUD behavior (middleware chains, streaming, multipart, `TypedNextResponse` unions, RPC) stop using these factories and switch to the `create-next-rest-framework-api` skill.
347
+ - For non-CRUD behavior (middleware chains, streaming, custom `TypedNextResponse` unions, RPC) stop using these factories and switch to the `create-next-rest-framework-api` skill.
344
348
 
345
349
  ## Escape Hatches
346
350
 
347
351
  - Extra server-side filters — `setParams(req) => Promise<Record<string, unknown>>` on GET/GET_LIST; returned keys are merged into the filter.
348
352
  - Extra columns on write — `setBody(req) => Promise<Partial<infer<IB>>>` on POST/PUT; returned fields are merged into the body before validation runs against `bodySchema`.
349
- - Post-processing output — `onSuccess({ params, data }) => Promise<data>`; on GET_LIST `data` is `{ data, total }`.
353
+ - Post-processing output — `onSuccess({ params, data, req }) => Promise<data>`; on GET_LIST `data` is `{ data, total }`.
350
354
  - Error rewriting — `onError(err) => Promise<Response | undefined>`. Return `undefined` to rethrow.
351
355
 
352
356
  ## Imports
package/SKILL.md CHANGED
@@ -60,22 +60,26 @@ export const getOperation = createGetOperation({ db, getSession });
60
60
  export const getListOperation = createGetListOperation({ db, getSession });
61
61
  ```
62
62
 
63
+ `db` may be omitted for operation-only endpoints that should not touch the database even when `table` is supplied for OpenAPI tags.
64
+
63
65
  `getSession(req)` **must** return `{ userId?: string } | undefined` (a Promise is fine). Throwing rejects the request; returning `undefined` disables ownership checks for that call.
64
66
 
65
67
  ## Factory Catalog
66
68
 
67
- | Export | Purpose | Required options | Notable optional options |
68
- | ------------------- | -------------------------- | --------------------------- | ------------------------------------------------------------------------------------------------------------ |
69
- | `createTableSchema` | pg `Table` + 5 zod schemas | `name`, `columns` | `refineSchema`, `extraConfig` |
70
- | `getOperation` | GET one by filters | `bodySchema`, `querySchema` | `table`, `setParams`, `relations`, `jsonArrayFields`, `byCreator`, `onSuccess`, `onError`, `summary`, `tags` |
71
- | `getListOperation` | GET paginated list | `bodySchema`, `querySchema` | `table`, `setParams`, `relations`, `jsonArrayFields`, `onSuccess`, `onError`, `summary`, `tags` |
72
- | `postOperation` | POST create | `bodySchema` | `table`, `outputBodySchema`, `setBody`, `onSuccess`, `onError`, `summary`, `tags` |
73
- | `putOperation` | PUT update | `bodySchema` | `table`, `outputBodySchema`, `setBody`, `byCreator`, `onSuccess`, `onError`, `summary`, `tags` |
74
- | `deleteOperation` | DELETE | — | `table`, `byCreator`, `onSuccess`, `onError`, `summary`, `tags` |
69
+ | Export | Purpose | Required options | Notable optional options |
70
+ | ------------------- | -------------------------- | --------------------------- | ------------------------------------------------------------------------------------------------------------- |
71
+ | `createTableSchema` | pg `Table` + 5 zod schemas | `name`, `columns` | `refineSchema`, `extraConfig` |
72
+ | `getOperation` | GET one by filters | `bodySchema`, `querySchema` | `table`, `setParams`, `relations`, `jsonArrayFields`, `byCreator`, `onSuccess`, `onError`, `summary`, `tags` |
73
+ | `getListOperation` | GET paginated list | `bodySchema`, `querySchema` | `table`, `setParams`, `relations`, `jsonArrayFields`, `onSuccess`, `onError`, `summary`, `tags` |
74
+ | `postOperation` | POST create | `bodySchema` | `table`, `contentType`, `parseBody`, `outputBodySchema`, `setBody`, `onSuccess`, `onError`, `summary`, `tags` |
75
+ | `putOperation` | PUT update | `bodySchema` | `table`, `outputBodySchema`, `setBody`, `byCreator`, `onSuccess`, `onError`, `summary`, `tags` |
76
+ | `deleteOperation` | DELETE | — | `table`, `byCreator`, `onSuccess`, `onError`, `summary`, `tags` |
75
77
 
76
78
  `tags` can be passed manually to override the default OpenAPI tag inferred from `table`.
77
79
 
78
- `table` is optional for route operations. When omitted, the operation still parses input, applies `setParams` / `setBody`, session-derived fields, and `onSuccess`, but skips the built-in table action (`select` / `insert` / `update` / `delete`). Use this for custom endpoints that want the same OpenAPI and response wiring without a direct table operation.
80
+ `postOperation` defaults to `contentType: "application/json"`. Pass `contentType: "multipart/form-data"` to read `await req.formData()` as body, or pass both a custom `contentType` and `parseBody(req)` for custom payload parsing.
81
+
82
+ `table` and factory-level `db` are optional for route operations. When `table` is omitted or `db` is not provided, the operation still parses input, applies `setParams` / `setBody`, session-derived fields, and `onSuccess`, but skips the built-in table action (`select` / `insert` / `update` / `delete`). Use this for custom endpoints that want the same OpenAPI and response wiring without a direct table operation.
79
83
 
80
84
  ## Canonical Examples
81
85
 
@@ -319,13 +323,13 @@ export const { GET } = route({
319
323
  - Do not inline `{ db, getSession }` into individual route files — always import the pre-bound `postOperation` / `getListOperation` / … from `@backend/utils/route-operation` so session/DB swaps are one-file changes.
320
324
  - `jsonb` columns declared with `jsonb(...)` carry no zod info — extend the matching insert/select schema with `.merge(z.object({ field: z.array(z.string()).optional() }))` to keep typing accurate.
321
325
  - Swallowing errors: an unhandled throw in a handler propagates to next-rest-framework as a 500. Provide `onError` for any operation exposed to untrusted clients.
322
- - For non-CRUD behavior (middleware chains, streaming, multipart, `TypedNextResponse` unions, RPC) stop using these factories and switch to the `create-next-rest-framework-api` skill.
326
+ - For non-CRUD behavior (middleware chains, streaming, custom `TypedNextResponse` unions, RPC) stop using these factories and switch to the `create-next-rest-framework-api` skill.
323
327
 
324
328
  ## Escape Hatches
325
329
 
326
330
  - Extra server-side filters — `setParams(req) => Promise<Record<string, unknown>>` on GET/GET_LIST; returned keys are merged into the filter.
327
331
  - Extra columns on write — `setBody(req) => Promise<Partial<infer<IB>>>` on POST/PUT; returned fields are merged into the body before validation runs against `bodySchema`.
328
- - Post-processing output — `onSuccess({ params, data }) => Promise<data>`; on GET_LIST `data` is `{ data, total }`.
332
+ - Post-processing output — `onSuccess({ params, data, req }) => Promise<data>`; on GET_LIST `data` is `{ data, total }`.
329
333
  - Error rewriting — `onError(err) => Promise<Response | undefined>`. Return `undefined` to rethrow.
330
334
 
331
335
  ## Imports
@@ -58,7 +58,7 @@ export var createDeleteOperation = function createDeleteOperation(_ref) {
58
58
  userId = _ref4.userId;
59
59
  body.creatorId = userId;
60
60
  case 13:
61
- if (!table) {
61
+ if (!(table && db)) {
62
62
  _context.next = 19;
63
63
  break;
64
64
  }
@@ -71,7 +71,7 @@ export var createGetListOperation = function createGetListOperation(_ref) {
71
71
  params.creatorId = userId;
72
72
  case 16:
73
73
  mergedParams = Object.assign(Object.fromEntries(new URL(req.url).searchParams), params);
74
- if (!table) {
74
+ if (!(table && db)) {
75
75
  _context.next = 23;
76
76
  break;
77
77
  }
@@ -70,7 +70,7 @@ export var createGetOperation = function createGetOperation(_ref) {
70
70
  params.creatorId = userId;
71
71
  case 16:
72
72
  mergedParams = Object.assign(Object.fromEntries(new URL(req.url).searchParams), params);
73
- if (!table) {
73
+ if (!(table && db)) {
74
74
  _context.next = 23;
75
75
  break;
76
76
  }
@@ -1,15 +1,19 @@
1
1
  import { z, ZodSchema } from "zod";
2
2
  import { PgTable } from "drizzle-orm/pg-core";
3
- import { TypedNextRequest, TypedNextResponse } from "next-rest-framework";
3
+ import { NextRequest } from "next/server";
4
+ import { TypedNextResponse } from "next-rest-framework";
4
5
  export interface PostOperationOptions<IB extends ZodSchema, OB extends ZodSchema, TTable extends PgTable> {
5
6
  bodySchema: IB;
7
+ contentType?: string;
6
8
  outputBodySchema?: IB;
7
- setBody?(req: TypedNextRequest<"POST", "application/json", z.infer<IB>>): Promise<Partial<z.infer<IB>>>;
9
+ parseBody?(req: NextRequest): Promise<Record<string, unknown>>;
10
+ setBody?(req: NextRequest): Promise<Partial<z.infer<IB>>>;
8
11
  summary?: string;
9
12
  tags?: string[];
10
13
  onSuccess?(payload: {
11
14
  params: Record<string, unknown>;
12
15
  data: z.infer<OB>;
16
+ req: NextRequest;
13
17
  }): Promise<z.infer<OB>>;
14
18
  onError?(error: Error): Promise<ReturnType<(typeof TypedNextResponse)["json"]> | undefined>;
15
19
  table?: TTable;
@@ -11,18 +11,60 @@ import { z } from "zod";
11
11
  import { routeOperation, TypedNextResponse } from "next-rest-framework";
12
12
  import getTableName from "./get-table-name.js";
13
13
  import { createPostAction } from "../actions/index.js";
14
- export var createPostOperation = function createPostOperation(_ref) {
15
- var getSession = _ref.getSession,
16
- db = _ref.db;
17
- return function (_ref2) {
18
- var bodySchema = _ref2.bodySchema,
19
- outputBodySchema = _ref2.outputBodySchema,
20
- setBody = _ref2.setBody,
21
- summary = _ref2.summary,
22
- tags = _ref2.tags,
23
- table = _ref2.table,
24
- onSuccess = _ref2.onSuccess,
25
- onError = _ref2.onError;
14
+ function readPostBody(_x, _x2) {
15
+ return _readPostBody.apply(this, arguments);
16
+ }
17
+ function _readPostBody() {
18
+ _readPostBody = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee2(req, _ref) {
19
+ var contentType, parseBody;
20
+ return _regeneratorRuntime().wrap(function _callee2$(_context2) {
21
+ while (1) switch (_context2.prev = _context2.next) {
22
+ case 0:
23
+ contentType = _ref.contentType, parseBody = _ref.parseBody;
24
+ if (!parseBody) {
25
+ _context2.next = 3;
26
+ break;
27
+ }
28
+ return _context2.abrupt("return", parseBody(req));
29
+ case 3:
30
+ if (!(contentType === "multipart/form-data")) {
31
+ _context2.next = 9;
32
+ break;
33
+ }
34
+ _context2.t0 = Object;
35
+ _context2.next = 7;
36
+ return req.formData();
37
+ case 7:
38
+ _context2.t1 = _context2.sent;
39
+ return _context2.abrupt("return", _context2.t0.fromEntries.call(_context2.t0, _context2.t1));
40
+ case 9:
41
+ _context2.next = 11;
42
+ return req.json();
43
+ case 11:
44
+ return _context2.abrupt("return", _context2.sent);
45
+ case 12:
46
+ case "end":
47
+ return _context2.stop();
48
+ }
49
+ }, _callee2);
50
+ }));
51
+ return _readPostBody.apply(this, arguments);
52
+ }
53
+ export var createPostOperation = function createPostOperation(_ref2) {
54
+ var getSession = _ref2.getSession,
55
+ db = _ref2.db;
56
+ return function (_ref3) {
57
+ var bodySchema = _ref3.bodySchema,
58
+ _ref3$contentType = _ref3.contentType,
59
+ contentType = _ref3$contentType === void 0 ? "application/json" : _ref3$contentType,
60
+ outputBodySchema = _ref3.outputBodySchema,
61
+ parseBody = _ref3.parseBody,
62
+ setBody = _ref3.setBody,
63
+ summary = _ref3.summary,
64
+ tags = _ref3.tags,
65
+ table = _ref3.table,
66
+ onSuccess = _ref3.onSuccess,
67
+ onError = _ref3.onError;
26
68
  return routeOperation({
27
69
  method: "POST",
28
70
  openApiOperation: {
@@ -31,7 +73,7 @@ export var createPostOperation = function createPostOperation(_ref) {
31
73
  }
32
74
  }).input({
33
75
  body: bodySchema,
34
- contentType: "application/json"
76
+ contentType: contentType
35
77
  }).outputs([{
36
78
  body: outputBodySchema || z.object({
37
79
  id: z.string()
@@ -39,8 +81,8 @@ export var createPostOperation = function createPostOperation(_ref) {
39
81
  contentType: "application/json",
40
82
  status: 200
41
83
  }]).handler( /*#__PURE__*/function () {
42
- var _ref3 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(req) {
43
- var _ref4, userId, body, extraBody, mergedBody, params, raw, data, response;
84
+ var _ref4 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(req) {
85
+ var _ref5, userId, body, extraBody, mergedBody, params, raw, data, response;
44
86
  return _regeneratorRuntime().wrap(function _callee$(_context) {
45
87
  while (1) switch (_context.prev = _context.next) {
46
88
  case 0:
@@ -55,10 +97,13 @@ export var createPostOperation = function createPostOperation(_ref) {
55
97
  }
56
98
  _context.t0 = {};
57
99
  case 6:
58
- _ref4 = _context.t0;
59
- userId = _ref4.userId;
100
+ _ref5 = _context.t0;
101
+ userId = _ref5.userId;
60
102
  _context.next = 10;
61
- return req.json();
103
+ return readPostBody(req, {
104
+ contentType: contentType,
105
+ parseBody: parseBody
106
+ });
62
107
  case 10:
63
108
  body = _context.sent;
64
109
  _context.next = 13;
@@ -76,7 +121,7 @@ export var createPostOperation = function createPostOperation(_ref) {
76
121
  params = _objectSpread({
77
122
  creatorId: userId
78
123
  }, mergedBody);
79
- if (!table) {
124
+ if (!(table && db)) {
80
125
  _context.next = 25;
81
126
  break;
82
127
  }
@@ -101,7 +146,8 @@ export var createPostOperation = function createPostOperation(_ref) {
101
146
  _context.next = 30;
102
147
  return onSuccess({
103
148
  data: raw,
104
- params: params
149
+ params: params,
150
+ req: req
105
151
  });
106
152
  case 30:
107
153
  _context.t3 = _context.sent;
@@ -135,8 +181,8 @@ export var createPostOperation = function createPostOperation(_ref) {
135
181
  }
136
182
  }, _callee, null, [[0, 38]]);
137
183
  }));
138
- return function (_x) {
139
- return _ref3.apply(this, arguments);
184
+ return function (_x3) {
185
+ return _ref4.apply(this, arguments);
140
186
  };
141
187
  }());
142
188
  };
@@ -77,7 +77,7 @@ export var createPutOperation = function createPutOperation(_ref) {
77
77
  params = _objectSpread({
78
78
  editorId: userId
79
79
  }, mergedBody);
80
- if (!table) {
80
+ if (!(table && db)) {
81
81
  _context.next = 25;
82
82
  break;
83
83
  }
@@ -58,7 +58,7 @@ export var createDeleteOperation = function createDeleteOperation(_ref) {
58
58
  userId = _ref4.userId;
59
59
  body.creatorId = userId;
60
60
  case 13:
61
- if (!table) {
61
+ if (!(table && db)) {
62
62
  _context.next = 19;
63
63
  break;
64
64
  }
@@ -71,7 +71,7 @@ export var createGetListOperation = function createGetListOperation(_ref) {
71
71
  params.creatorId = userId;
72
72
  case 16:
73
73
  mergedParams = Object.assign(Object.fromEntries(new URL(req.url).searchParams), params);
74
- if (!table) {
74
+ if (!(table && db)) {
75
75
  _context.next = 23;
76
76
  break;
77
77
  }
@@ -70,7 +70,7 @@ export var createGetOperation = function createGetOperation(_ref) {
70
70
  params.creatorId = userId;
71
71
  case 16:
72
72
  mergedParams = Object.assign(Object.fromEntries(new URL(req.url).searchParams), params);
73
- if (!table) {
73
+ if (!(table && db)) {
74
74
  _context.next = 23;
75
75
  break;
76
76
  }
@@ -1,15 +1,19 @@
1
1
  import { z, ZodSchema } from "zod";
2
2
  import { SQLiteTable } from "drizzle-orm/sqlite-core";
3
- import { TypedNextRequest, TypedNextResponse } from "next-rest-framework";
3
+ import { NextRequest } from "next/server";
4
+ import { TypedNextResponse } from "next-rest-framework";
4
5
  export interface PostOperationOptions<IB extends ZodSchema, OB extends ZodSchema, TTable extends SQLiteTable> {
5
6
  bodySchema: IB;
7
+ contentType?: string;
6
8
  outputBodySchema?: IB;
7
- setBody?: (_req: TypedNextRequest<"POST", "application/json", z.infer<IB>>) => Promise<Partial<z.infer<IB>>>;
9
+ parseBody?: (_req: NextRequest) => Promise<Record<string, unknown>>;
10
+ setBody?: (_req: NextRequest) => Promise<Partial<z.infer<IB>>>;
8
11
  summary?: string;
9
12
  tags?: string[];
10
13
  onSuccess?: (_payload: {
11
14
  params: Record<string, unknown>;
12
15
  data: z.infer<OB>;
16
+ req: NextRequest;
13
17
  }) => Promise<z.infer<OB>>;
14
18
  onError?: (_error: Error) => Promise<ReturnType<(typeof TypedNextResponse)["json"]> | undefined>;
15
19
  table?: TTable;
@@ -11,18 +11,60 @@ import { z } from "zod";
11
11
  import { routeOperation, TypedNextResponse } from "next-rest-framework";
12
12
  import getTableName from "./get-table-name.js";
13
13
  import { createPostAction } from "../actions/index.js";
14
- export var createPostOperation = function createPostOperation(_ref) {
15
- var getSession = _ref.getSession,
16
- db = _ref.db;
17
- return function (_ref2) {
18
- var bodySchema = _ref2.bodySchema,
19
- outputBodySchema = _ref2.outputBodySchema,
20
- setBody = _ref2.setBody,
21
- summary = _ref2.summary,
22
- tags = _ref2.tags,
23
- table = _ref2.table,
24
- onSuccess = _ref2.onSuccess,
25
- onError = _ref2.onError;
14
+ function readPostBody(_x, _x2) {
15
+ return _readPostBody.apply(this, arguments);
16
+ }
17
+ function _readPostBody() {
18
+ _readPostBody = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee2(req, _ref) {
19
+ var contentType, parseBody;
20
+ return _regeneratorRuntime().wrap(function _callee2$(_context2) {
21
+ while (1) switch (_context2.prev = _context2.next) {
22
+ case 0:
23
+ contentType = _ref.contentType, parseBody = _ref.parseBody;
24
+ if (!parseBody) {
25
+ _context2.next = 3;
26
+ break;
27
+ }
28
+ return _context2.abrupt("return", parseBody(req));
29
+ case 3:
30
+ if (!(contentType === "multipart/form-data")) {
31
+ _context2.next = 9;
32
+ break;
33
+ }
34
+ _context2.t0 = Object;
35
+ _context2.next = 7;
36
+ return req.formData();
37
+ case 7:
38
+ _context2.t1 = _context2.sent;
39
+ return _context2.abrupt("return", _context2.t0.fromEntries.call(_context2.t0, _context2.t1));
40
+ case 9:
41
+ _context2.next = 11;
42
+ return req.json();
43
+ case 11:
44
+ return _context2.abrupt("return", _context2.sent);
45
+ case 12:
46
+ case "end":
47
+ return _context2.stop();
48
+ }
49
+ }, _callee2);
50
+ }));
51
+ return _readPostBody.apply(this, arguments);
52
+ }
53
+ export var createPostOperation = function createPostOperation(_ref2) {
54
+ var getSession = _ref2.getSession,
55
+ db = _ref2.db;
56
+ return function (_ref3) {
57
+ var bodySchema = _ref3.bodySchema,
58
+ _ref3$contentType = _ref3.contentType,
59
+ contentType = _ref3$contentType === void 0 ? "application/json" : _ref3$contentType,
60
+ outputBodySchema = _ref3.outputBodySchema,
61
+ parseBody = _ref3.parseBody,
62
+ setBody = _ref3.setBody,
63
+ summary = _ref3.summary,
64
+ tags = _ref3.tags,
65
+ table = _ref3.table,
66
+ onSuccess = _ref3.onSuccess,
67
+ onError = _ref3.onError;
26
68
  return routeOperation({
27
69
  method: "POST",
28
70
  openApiOperation: {
@@ -31,7 +73,7 @@ export var createPostOperation = function createPostOperation(_ref) {
31
73
  }
32
74
  }).input({
33
75
  body: bodySchema,
34
- contentType: "application/json"
76
+ contentType: contentType
35
77
  }).outputs([{
36
78
  body: outputBodySchema || z.object({
37
79
  id: z.string()
@@ -39,8 +81,8 @@ export var createPostOperation = function createPostOperation(_ref) {
39
81
  contentType: "application/json",
40
82
  status: 200
41
83
  }]).handler( /*#__PURE__*/function () {
42
- var _ref3 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(req) {
43
- var _ref4, userId, body, extraBody, mergedBody, params, raw, data, response;
84
+ var _ref4 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(req) {
85
+ var _ref5, userId, body, extraBody, mergedBody, params, raw, data, response;
44
86
  return _regeneratorRuntime().wrap(function _callee$(_context) {
45
87
  while (1) switch (_context.prev = _context.next) {
46
88
  case 0:
@@ -55,10 +97,13 @@ export var createPostOperation = function createPostOperation(_ref) {
55
97
  }
56
98
  _context.t0 = {};
57
99
  case 6:
58
- _ref4 = _context.t0;
59
- userId = _ref4.userId;
100
+ _ref5 = _context.t0;
101
+ userId = _ref5.userId;
60
102
  _context.next = 10;
61
- return req.json();
103
+ return readPostBody(req, {
104
+ contentType: contentType,
105
+ parseBody: parseBody
106
+ });
62
107
  case 10:
63
108
  body = _context.sent;
64
109
  _context.next = 13;
@@ -76,7 +121,7 @@ export var createPostOperation = function createPostOperation(_ref) {
76
121
  params = _objectSpread({
77
122
  creatorId: userId
78
123
  }, mergedBody);
79
- if (!table) {
124
+ if (!(table && db)) {
80
125
  _context.next = 25;
81
126
  break;
82
127
  }
@@ -101,7 +146,8 @@ export var createPostOperation = function createPostOperation(_ref) {
101
146
  _context.next = 30;
102
147
  return onSuccess({
103
148
  data: raw,
104
- params: params
149
+ params: params,
150
+ req: req
105
151
  });
106
152
  case 30:
107
153
  _context.t3 = _context.sent;
@@ -135,8 +181,8 @@ export var createPostOperation = function createPostOperation(_ref) {
135
181
  }
136
182
  }, _callee, null, [[0, 38]]);
137
183
  }));
138
- return function (_x) {
139
- return _ref3.apply(this, arguments);
184
+ return function (_x3) {
185
+ return _ref4.apply(this, arguments);
140
186
  };
141
187
  }());
142
188
  };
@@ -77,7 +77,7 @@ export var createPutOperation = function createPutOperation(_ref) {
77
77
  params = _objectSpread({
78
78
  editorId: userId
79
79
  }, mergedBody);
80
- if (!table) {
80
+ if (!(table && db)) {
81
81
  _context.next = 25;
82
82
  break;
83
83
  }
@@ -65,7 +65,7 @@ var createDeleteOperation = ({
65
65
  const { userId } = await getSession(req) || {};
66
66
  body.creatorId = userId;
67
67
  }
68
- const data = table ? await (0, import_actions.createDeleteAction)({ table, db })(body) : body;
68
+ const data = table && db ? await (0, import_actions.createDeleteAction)({ table, db })(body) : body;
69
69
  await (onSuccess == null ? void 0 : onSuccess({ data, params: body }));
70
70
  return import_next_rest_framework.TypedNextResponse.json(data, {
71
71
  status: 200
@@ -78,7 +78,7 @@ var createGetListOperation = ({
78
78
  Object.fromEntries(new URL(req.url).searchParams),
79
79
  params
80
80
  );
81
- let result = table ? await (0, import_actions.createGetListAction)({
81
+ let result = table && db ? await (0, import_actions.createGetListAction)({
82
82
  bodySchema,
83
83
  db,
84
84
  jsonArrayFields,
@@ -77,7 +77,7 @@ var createGetOperation = ({
77
77
  Object.fromEntries(new URL(req.url).searchParams),
78
78
  params
79
79
  );
80
- const rawResult = table ? await (0, import_actions.createGetAction)({
80
+ const rawResult = table && db ? await (0, import_actions.createGetAction)({
81
81
  bodySchema,
82
82
  db,
83
83
  jsonArrayFields,
@@ -1,15 +1,19 @@
1
1
  import { z, ZodSchema } from "zod";
2
2
  import { PgTable } from "drizzle-orm/pg-core";
3
- import { TypedNextRequest, TypedNextResponse } from "next-rest-framework";
3
+ import { NextRequest } from "next/server";
4
+ import { TypedNextResponse } from "next-rest-framework";
4
5
  export interface PostOperationOptions<IB extends ZodSchema, OB extends ZodSchema, TTable extends PgTable> {
5
6
  bodySchema: IB;
7
+ contentType?: string;
6
8
  outputBodySchema?: IB;
7
- setBody?(req: TypedNextRequest<"POST", "application/json", z.infer<IB>>): Promise<Partial<z.infer<IB>>>;
9
+ parseBody?(req: NextRequest): Promise<Record<string, unknown>>;
10
+ setBody?(req: NextRequest): Promise<Partial<z.infer<IB>>>;
8
11
  summary?: string;
9
12
  tags?: string[];
10
13
  onSuccess?(payload: {
11
14
  params: Record<string, unknown>;
12
15
  data: z.infer<OB>;
16
+ req: NextRequest;
13
17
  }): Promise<z.infer<OB>>;
14
18
  onError?(error: Error): Promise<ReturnType<(typeof TypedNextResponse)["json"]> | undefined>;
15
19
  table?: TTable;
@@ -36,12 +36,26 @@ var import_zod = require("zod");
36
36
  var import_next_rest_framework = require("next-rest-framework");
37
37
  var import_get_table_name = __toESM(require("./get-table-name"));
38
38
  var import_actions = require("../actions");
39
+ async function readPostBody(req, {
40
+ contentType,
41
+ parseBody
42
+ }) {
43
+ if (parseBody) {
44
+ return parseBody(req);
45
+ }
46
+ if (contentType === "multipart/form-data") {
47
+ return Object.fromEntries(await req.formData());
48
+ }
49
+ return await req.json();
50
+ }
39
51
  var createPostOperation = ({
40
52
  getSession,
41
53
  db
42
54
  }) => ({
43
55
  bodySchema,
56
+ contentType = "application/json",
44
57
  outputBodySchema,
58
+ parseBody,
45
59
  setBody,
46
60
  summary,
47
61
  tags,
@@ -56,7 +70,7 @@ var createPostOperation = ({
56
70
  }
57
71
  }).input({
58
72
  body: bodySchema,
59
- contentType: "application/json"
73
+ contentType
60
74
  }).outputs([
61
75
  {
62
76
  body: outputBodySchema || import_zod.z.object({ id: import_zod.z.string() }),
@@ -66,16 +80,17 @@ var createPostOperation = ({
66
80
  ]).handler(async (req) => {
67
81
  try {
68
82
  const { userId } = await getSession(req) || {};
69
- const body = await req.json();
70
- const extraBody = await (setBody == null ? void 0 : setBody(
71
- req
72
- )) || {};
83
+ const body = await readPostBody(req, { contentType, parseBody });
84
+ const extraBody = await (setBody == null ? void 0 : setBody(req)) || {};
73
85
  const mergedBody = { ...body, ...extraBody };
74
86
  const params = { creatorId: userId, ...mergedBody };
75
- const raw = table ? (await (0, import_actions.createPostAction)({ bodySchema, db, table })(params))[0] : params;
87
+ const raw = table && db ? (await (0, import_actions.createPostAction)({ bodySchema, db, table })(
88
+ params
89
+ ))[0] : params;
76
90
  const data = onSuccess ? await onSuccess({
77
91
  data: raw,
78
- params
92
+ params,
93
+ req
79
94
  }) : raw;
80
95
  return import_next_rest_framework.TypedNextResponse.json(data, {
81
96
  status: 200
@@ -74,7 +74,7 @@ var createPutOperation = ({
74
74
  )) || {};
75
75
  const mergedBody = { ...body, ...extraBody };
76
76
  const params = { editorId: userId, ...mergedBody };
77
- const raw = table ? await (0, import_actions.createPutAction)({
77
+ const raw = table && db ? await (0, import_actions.createPutAction)({
78
78
  bodySchema,
79
79
  table,
80
80
  db
@@ -65,7 +65,7 @@ var createDeleteOperation = ({
65
65
  const { userId } = await getSession(req) || {};
66
66
  body.creatorId = userId;
67
67
  }
68
- const data = table ? await (0, import_actions.createDeleteAction)({ table, db })(body) : body;
68
+ const data = table && db ? await (0, import_actions.createDeleteAction)({ table, db })(body) : body;
69
69
  await (onSuccess == null ? void 0 : onSuccess({ data, params: body }));
70
70
  return import_next_rest_framework.TypedNextResponse.json(data, {
71
71
  status: 200
@@ -78,7 +78,7 @@ var createGetListOperation = ({
78
78
  Object.fromEntries(new URL(req.url).searchParams),
79
79
  params
80
80
  );
81
- let result = table ? await (0, import_actions.createGetListAction)({
81
+ let result = table && db ? await (0, import_actions.createGetListAction)({
82
82
  bodySchema,
83
83
  db,
84
84
  jsonArrayFields,
@@ -77,7 +77,7 @@ var createGetOperation = ({
77
77
  Object.fromEntries(new URL(req.url).searchParams),
78
78
  params
79
79
  );
80
- const rawResult = table ? await (0, import_actions.createGetAction)({
80
+ const rawResult = table && db ? await (0, import_actions.createGetAction)({
81
81
  bodySchema,
82
82
  db,
83
83
  jsonArrayFields,
@@ -1,15 +1,19 @@
1
1
  import { z, ZodSchema } from "zod";
2
2
  import { SQLiteTable } from "drizzle-orm/sqlite-core";
3
- import { TypedNextRequest, TypedNextResponse } from "next-rest-framework";
3
+ import { NextRequest } from "next/server";
4
+ import { TypedNextResponse } from "next-rest-framework";
4
5
  export interface PostOperationOptions<IB extends ZodSchema, OB extends ZodSchema, TTable extends SQLiteTable> {
5
6
  bodySchema: IB;
7
+ contentType?: string;
6
8
  outputBodySchema?: IB;
7
- setBody?: (_req: TypedNextRequest<"POST", "application/json", z.infer<IB>>) => Promise<Partial<z.infer<IB>>>;
9
+ parseBody?: (_req: NextRequest) => Promise<Record<string, unknown>>;
10
+ setBody?: (_req: NextRequest) => Promise<Partial<z.infer<IB>>>;
8
11
  summary?: string;
9
12
  tags?: string[];
10
13
  onSuccess?: (_payload: {
11
14
  params: Record<string, unknown>;
12
15
  data: z.infer<OB>;
16
+ req: NextRequest;
13
17
  }) => Promise<z.infer<OB>>;
14
18
  onError?: (_error: Error) => Promise<ReturnType<(typeof TypedNextResponse)["json"]> | undefined>;
15
19
  table?: TTable;
@@ -36,12 +36,26 @@ var import_zod = require("zod");
36
36
  var import_next_rest_framework = require("next-rest-framework");
37
37
  var import_get_table_name = __toESM(require("./get-table-name"));
38
38
  var import_actions = require("../actions");
39
+ async function readPostBody(req, {
40
+ contentType,
41
+ parseBody
42
+ }) {
43
+ if (parseBody) {
44
+ return parseBody(req);
45
+ }
46
+ if (contentType === "multipart/form-data") {
47
+ return Object.fromEntries(await req.formData());
48
+ }
49
+ return await req.json();
50
+ }
39
51
  var createPostOperation = ({
40
52
  getSession,
41
53
  db
42
54
  }) => ({
43
55
  bodySchema,
56
+ contentType = "application/json",
44
57
  outputBodySchema,
58
+ parseBody,
45
59
  setBody,
46
60
  summary,
47
61
  tags,
@@ -56,7 +70,7 @@ var createPostOperation = ({
56
70
  }
57
71
  }).input({
58
72
  body: bodySchema,
59
- contentType: "application/json"
73
+ contentType
60
74
  }).outputs([
61
75
  {
62
76
  body: outputBodySchema || import_zod.z.object({ id: import_zod.z.string() }),
@@ -66,16 +80,17 @@ var createPostOperation = ({
66
80
  ]).handler(async (req) => {
67
81
  try {
68
82
  const { userId } = await getSession(req) || {};
69
- const body = await req.json();
70
- const extraBody = await (setBody == null ? void 0 : setBody(
71
- req
72
- )) || {};
83
+ const body = await readPostBody(req, { contentType, parseBody });
84
+ const extraBody = await (setBody == null ? void 0 : setBody(req)) || {};
73
85
  const mergedBody = { ...body, ...extraBody };
74
86
  const params = { creatorId: userId, ...mergedBody };
75
- const raw = table ? (await (0, import_actions.createPostAction)({ bodySchema, db, table })(params))[0] : params;
87
+ const raw = table && db ? (await (0, import_actions.createPostAction)({ bodySchema, db, table })(
88
+ params
89
+ ))[0] : params;
76
90
  const data = onSuccess ? await onSuccess({
77
91
  data: raw,
78
- params
92
+ params,
93
+ req
79
94
  }) : raw;
80
95
  return import_next_rest_framework.TypedNextResponse.json(data, {
81
96
  status: 200
@@ -74,7 +74,7 @@ var createPutOperation = ({
74
74
  )) || {};
75
75
  const mergedBody = { ...body, ...extraBody };
76
76
  const params = { editorId: userId, ...mergedBody };
77
- const raw = table ? await (0, import_actions.createPutAction)({
77
+ const raw = table && db ? await (0, import_actions.createPutAction)({
78
78
  bodySchema,
79
79
  table,
80
80
  db
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai0x0/utils",
3
- "version": "0.0.40",
3
+ "version": "0.0.42",
4
4
  "description": "AI0x0 utils",
5
5
  "keywords": [
6
6
  "ai0x0"