dn-react-router-toolkit 0.9.3 → 0.9.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api/index.js +52 -9
- package/dist/api/index.mjs +45 -2
- package/dist/api/patch_resource_handler.d.mts +22 -0
- package/dist/api/patch_resource_handler.d.ts +22 -0
- package/dist/api/patch_resource_handler.js +175 -0
- package/dist/api/patch_resource_handler.mjs +147 -0
- package/dist/api/put_resource_handler.d.mts +3 -3
- package/dist/api/put_resource_handler.d.ts +3 -3
- package/dist/api/resource_handler.d.mts +4 -3
- package/dist/api/resource_handler.d.ts +4 -3
- package/dist/api/resource_handler.js +52 -9
- package/dist/api/resource_handler.mjs +45 -2
- package/dist/table/index.js +6 -2
- package/dist/table/index.mjs +6 -2
- package/dist/table/repository.d.mts +8 -6
- package/dist/table/repository.d.ts +8 -6
- package/dist/table/repository.js +6 -2
- package/dist/table/repository.mjs +6 -2
- package/package.json +2 -2
package/dist/api/index.js
CHANGED
|
@@ -255,7 +255,7 @@ var defaultAPIHandler = ({
|
|
|
255
255
|
};
|
|
256
256
|
|
|
257
257
|
// src/api/resource_handler.ts
|
|
258
|
-
var
|
|
258
|
+
var import_gw_response4 = require("gw-response");
|
|
259
259
|
var import_gw_result = require("gw-result");
|
|
260
260
|
|
|
261
261
|
// src/api/put_resource_handler.ts
|
|
@@ -435,6 +435,39 @@ function putResourceHandler({
|
|
|
435
435
|
};
|
|
436
436
|
}
|
|
437
437
|
|
|
438
|
+
// src/api/patch_resource_handler.ts
|
|
439
|
+
var import_gw_response3 = require("gw-response");
|
|
440
|
+
var import_drizzle_orm2 = require("drizzle-orm");
|
|
441
|
+
function patchResourceHandler({
|
|
442
|
+
repository,
|
|
443
|
+
validators,
|
|
444
|
+
primaryKey
|
|
445
|
+
}) {
|
|
446
|
+
return async (existing, request) => {
|
|
447
|
+
const serilaizedParams = await request.json();
|
|
448
|
+
const params = deserialize(serilaizedParams) || {};
|
|
449
|
+
if (validators) {
|
|
450
|
+
const paramsForValidation = Object.keys(validators).filter(
|
|
451
|
+
(key) => Object.prototype.hasOwnProperty.call(validators, key)
|
|
452
|
+
);
|
|
453
|
+
for (const paramKey of paramsForValidation) {
|
|
454
|
+
const value = params[paramKey];
|
|
455
|
+
const validator = validators[paramKey];
|
|
456
|
+
if (validator?.validate && !validator.validate(value)) {
|
|
457
|
+
return (0, import_gw_response3.httpBadRequest)({
|
|
458
|
+
code: "BAD_REQUEST",
|
|
459
|
+
message: validator.message ? validator.message(value) : "\uC798\uBABB\uB41C \uC694\uCCAD\uC785\uB2C8\uB2E4."
|
|
460
|
+
});
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
const item = await repository.update(existing[primaryKey], {
|
|
465
|
+
...params
|
|
466
|
+
});
|
|
467
|
+
return (0, import_gw_response3.httpCreated)(item);
|
|
468
|
+
};
|
|
469
|
+
}
|
|
470
|
+
|
|
438
471
|
// src/api/resource_handler.ts
|
|
439
472
|
function resourceHandler({
|
|
440
473
|
withAuthAction,
|
|
@@ -443,34 +476,44 @@ function resourceHandler({
|
|
|
443
476
|
existingConditions,
|
|
444
477
|
injectUserId,
|
|
445
478
|
roles,
|
|
446
|
-
isOwnedBy
|
|
479
|
+
isOwnedBy,
|
|
480
|
+
primaryKey
|
|
447
481
|
}) {
|
|
448
482
|
const loader = async ({ request }) => {
|
|
449
483
|
return (0, import_gw_result.ok)({});
|
|
450
484
|
};
|
|
451
485
|
const action = withAuthAction((auth) => async ({ request, params }) => {
|
|
452
486
|
if (roles && roles.length > 0 && (!auth || !roles.includes(auth.role))) {
|
|
453
|
-
return (0,
|
|
487
|
+
return (0, import_gw_response4.httpForbidden)({
|
|
454
488
|
code: "FORBIDDEN",
|
|
455
489
|
message: "\uAD8C\uD55C\uC774 \uC5C6\uC2B5\uB2C8\uB2E4."
|
|
456
490
|
});
|
|
457
491
|
}
|
|
458
|
-
const
|
|
492
|
+
const pathname = new URL(request.url).pathname;
|
|
493
|
+
const itemId = pathname.split("/").filter(Boolean).at(-1);
|
|
459
494
|
if (itemId) {
|
|
460
495
|
const existing = await repository.find(itemId);
|
|
461
496
|
if (!existing) {
|
|
462
|
-
return (0,
|
|
497
|
+
return (0, import_gw_response4.httpNotFound)();
|
|
463
498
|
}
|
|
464
499
|
if (isOwnedBy && (!auth || !isOwnedBy(auth, existing))) {
|
|
465
|
-
return (0,
|
|
500
|
+
return (0, import_gw_response4.httpForbidden)();
|
|
466
501
|
}
|
|
467
502
|
switch (request.method) {
|
|
503
|
+
case "PATCH": {
|
|
504
|
+
const handler = patchResourceHandler({
|
|
505
|
+
repository,
|
|
506
|
+
validators,
|
|
507
|
+
primaryKey
|
|
508
|
+
});
|
|
509
|
+
return handler(existing, request);
|
|
510
|
+
}
|
|
468
511
|
case "DELETE": {
|
|
469
512
|
await repository.delete(itemId);
|
|
470
|
-
return (0,
|
|
513
|
+
return (0, import_gw_response4.httpNoContent)();
|
|
471
514
|
}
|
|
472
515
|
default: {
|
|
473
|
-
return (0,
|
|
516
|
+
return (0, import_gw_response4.httpMethodNotAllowed)();
|
|
474
517
|
}
|
|
475
518
|
}
|
|
476
519
|
}
|
|
@@ -487,7 +530,7 @@ function resourceHandler({
|
|
|
487
530
|
return handler(auth, request);
|
|
488
531
|
}
|
|
489
532
|
default: {
|
|
490
|
-
return (0,
|
|
533
|
+
return (0, import_gw_response4.httpMethodNotAllowed)();
|
|
491
534
|
}
|
|
492
535
|
}
|
|
493
536
|
});
|
package/dist/api/index.mjs
CHANGED
|
@@ -431,6 +431,39 @@ function putResourceHandler({
|
|
|
431
431
|
};
|
|
432
432
|
}
|
|
433
433
|
|
|
434
|
+
// src/api/patch_resource_handler.ts
|
|
435
|
+
import { httpBadRequest as httpBadRequest2, httpCreated as httpCreated2 } from "gw-response";
|
|
436
|
+
import "drizzle-orm";
|
|
437
|
+
function patchResourceHandler({
|
|
438
|
+
repository,
|
|
439
|
+
validators,
|
|
440
|
+
primaryKey
|
|
441
|
+
}) {
|
|
442
|
+
return async (existing, request) => {
|
|
443
|
+
const serilaizedParams = await request.json();
|
|
444
|
+
const params = deserialize(serilaizedParams) || {};
|
|
445
|
+
if (validators) {
|
|
446
|
+
const paramsForValidation = Object.keys(validators).filter(
|
|
447
|
+
(key) => Object.prototype.hasOwnProperty.call(validators, key)
|
|
448
|
+
);
|
|
449
|
+
for (const paramKey of paramsForValidation) {
|
|
450
|
+
const value = params[paramKey];
|
|
451
|
+
const validator = validators[paramKey];
|
|
452
|
+
if (validator?.validate && !validator.validate(value)) {
|
|
453
|
+
return httpBadRequest2({
|
|
454
|
+
code: "BAD_REQUEST",
|
|
455
|
+
message: validator.message ? validator.message(value) : "\uC798\uBABB\uB41C \uC694\uCCAD\uC785\uB2C8\uB2E4."
|
|
456
|
+
});
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
const item = await repository.update(existing[primaryKey], {
|
|
461
|
+
...params
|
|
462
|
+
});
|
|
463
|
+
return httpCreated2(item);
|
|
464
|
+
};
|
|
465
|
+
}
|
|
466
|
+
|
|
434
467
|
// src/api/resource_handler.ts
|
|
435
468
|
function resourceHandler({
|
|
436
469
|
withAuthAction,
|
|
@@ -439,7 +472,8 @@ function resourceHandler({
|
|
|
439
472
|
existingConditions,
|
|
440
473
|
injectUserId,
|
|
441
474
|
roles,
|
|
442
|
-
isOwnedBy
|
|
475
|
+
isOwnedBy,
|
|
476
|
+
primaryKey
|
|
443
477
|
}) {
|
|
444
478
|
const loader = async ({ request }) => {
|
|
445
479
|
return ok({});
|
|
@@ -451,7 +485,8 @@ function resourceHandler({
|
|
|
451
485
|
message: "\uAD8C\uD55C\uC774 \uC5C6\uC2B5\uB2C8\uB2E4."
|
|
452
486
|
});
|
|
453
487
|
}
|
|
454
|
-
const
|
|
488
|
+
const pathname = new URL(request.url).pathname;
|
|
489
|
+
const itemId = pathname.split("/").filter(Boolean).at(-1);
|
|
455
490
|
if (itemId) {
|
|
456
491
|
const existing = await repository.find(itemId);
|
|
457
492
|
if (!existing) {
|
|
@@ -461,6 +496,14 @@ function resourceHandler({
|
|
|
461
496
|
return httpForbidden2();
|
|
462
497
|
}
|
|
463
498
|
switch (request.method) {
|
|
499
|
+
case "PATCH": {
|
|
500
|
+
const handler = patchResourceHandler({
|
|
501
|
+
repository,
|
|
502
|
+
validators,
|
|
503
|
+
primaryKey
|
|
504
|
+
});
|
|
505
|
+
return handler(existing, request);
|
|
506
|
+
}
|
|
464
507
|
case "DELETE": {
|
|
465
508
|
await repository.delete(itemId);
|
|
466
509
|
return httpNoContent();
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { InferSelectModel, SQLWrapper } from 'drizzle-orm';
|
|
2
|
+
import { PgTableWithColumns } from 'drizzle-orm/pg-core';
|
|
3
|
+
import { TableRepository } from '../table/repository.mjs';
|
|
4
|
+
import 'drizzle-orm/node-postgres';
|
|
5
|
+
|
|
6
|
+
type PatchResourceValidators<T extends PgTableWithColumns<any>> = {
|
|
7
|
+
[K in keyof InferSelectModel<T>]?: {
|
|
8
|
+
validate?: (value?: InferSelectModel<T>[K]) => boolean;
|
|
9
|
+
message?: (value?: InferSelectModel<T>[K]) => string;
|
|
10
|
+
};
|
|
11
|
+
};
|
|
12
|
+
type PatchResourceExistingConditions<T extends PgTableWithColumns<any>> = {
|
|
13
|
+
[K in keyof InferSelectModel<T>]?: (value: InferSelectModel<T>[K]) => SQLWrapper;
|
|
14
|
+
};
|
|
15
|
+
type PatchResourceHandlerOptions<T extends PgTableWithColumns<any>, TSelect, TPrimaryKey extends keyof TSelect = "id" extends keyof TSelect ? "id" : never> = {
|
|
16
|
+
repository: TableRepository<T, TSelect, TPrimaryKey>;
|
|
17
|
+
validators?: PatchResourceValidators<T>;
|
|
18
|
+
primaryKey: TPrimaryKey;
|
|
19
|
+
};
|
|
20
|
+
declare function patchResourceHandler<T extends PgTableWithColumns<any>, TSelect, TPrimaryKey extends keyof TSelect = "id" extends keyof TSelect ? "id" : never>({ repository, validators, primaryKey, }: PatchResourceHandlerOptions<T, TSelect, TPrimaryKey>): (existing: TSelect, request: Request) => Promise<Response>;
|
|
21
|
+
|
|
22
|
+
export { type PatchResourceExistingConditions, type PatchResourceHandlerOptions, type PatchResourceValidators, patchResourceHandler };
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { InferSelectModel, SQLWrapper } from 'drizzle-orm';
|
|
2
|
+
import { PgTableWithColumns } from 'drizzle-orm/pg-core';
|
|
3
|
+
import { TableRepository } from '../table/repository.js';
|
|
4
|
+
import 'drizzle-orm/node-postgres';
|
|
5
|
+
|
|
6
|
+
type PatchResourceValidators<T extends PgTableWithColumns<any>> = {
|
|
7
|
+
[K in keyof InferSelectModel<T>]?: {
|
|
8
|
+
validate?: (value?: InferSelectModel<T>[K]) => boolean;
|
|
9
|
+
message?: (value?: InferSelectModel<T>[K]) => string;
|
|
10
|
+
};
|
|
11
|
+
};
|
|
12
|
+
type PatchResourceExistingConditions<T extends PgTableWithColumns<any>> = {
|
|
13
|
+
[K in keyof InferSelectModel<T>]?: (value: InferSelectModel<T>[K]) => SQLWrapper;
|
|
14
|
+
};
|
|
15
|
+
type PatchResourceHandlerOptions<T extends PgTableWithColumns<any>, TSelect, TPrimaryKey extends keyof TSelect = "id" extends keyof TSelect ? "id" : never> = {
|
|
16
|
+
repository: TableRepository<T, TSelect, TPrimaryKey>;
|
|
17
|
+
validators?: PatchResourceValidators<T>;
|
|
18
|
+
primaryKey: TPrimaryKey;
|
|
19
|
+
};
|
|
20
|
+
declare function patchResourceHandler<T extends PgTableWithColumns<any>, TSelect, TPrimaryKey extends keyof TSelect = "id" extends keyof TSelect ? "id" : never>({ repository, validators, primaryKey, }: PatchResourceHandlerOptions<T, TSelect, TPrimaryKey>): (existing: TSelect, request: Request) => Promise<Response>;
|
|
21
|
+
|
|
22
|
+
export { type PatchResourceExistingConditions, type PatchResourceHandlerOptions, type PatchResourceValidators, patchResourceHandler };
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
|
|
30
|
+
// src/api/patch_resource_handler.ts
|
|
31
|
+
var patch_resource_handler_exports = {};
|
|
32
|
+
__export(patch_resource_handler_exports, {
|
|
33
|
+
patchResourceHandler: () => patchResourceHandler
|
|
34
|
+
});
|
|
35
|
+
module.exports = __toCommonJS(patch_resource_handler_exports);
|
|
36
|
+
var import_gw_response = require("gw-response");
|
|
37
|
+
|
|
38
|
+
// src/crud/crud_form_provider.tsx
|
|
39
|
+
var import_react_router = require("react-router");
|
|
40
|
+
var import_react_store_input = require("react-store-input");
|
|
41
|
+
var import_react = require("react");
|
|
42
|
+
|
|
43
|
+
// src/crud/serialize.ts
|
|
44
|
+
function deserialize(data) {
|
|
45
|
+
if (data === void 0) {
|
|
46
|
+
return void 0;
|
|
47
|
+
}
|
|
48
|
+
if (typeof data === "object" && data !== null && "type" in data && "value" in data) {
|
|
49
|
+
const { type, value } = data;
|
|
50
|
+
switch (type) {
|
|
51
|
+
case "null":
|
|
52
|
+
return null;
|
|
53
|
+
case "string":
|
|
54
|
+
return value;
|
|
55
|
+
case "number":
|
|
56
|
+
return value;
|
|
57
|
+
case "boolean":
|
|
58
|
+
return value;
|
|
59
|
+
case "date":
|
|
60
|
+
return new Date(value);
|
|
61
|
+
case "array":
|
|
62
|
+
return value.map((item) => deserialize(item));
|
|
63
|
+
case "object":
|
|
64
|
+
return Object.entries(value).reduce(
|
|
65
|
+
(acc, [key, value2]) => {
|
|
66
|
+
return {
|
|
67
|
+
...acc,
|
|
68
|
+
[key]: deserialize(value2)
|
|
69
|
+
};
|
|
70
|
+
},
|
|
71
|
+
{}
|
|
72
|
+
);
|
|
73
|
+
default:
|
|
74
|
+
return void 0;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
return void 0;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// src/crud/crud_form_provider.tsx
|
|
81
|
+
var import_jsx_runtime = require("react/jsx-runtime");
|
|
82
|
+
var FormContext = (0, import_react.createContext)({});
|
|
83
|
+
|
|
84
|
+
// src/form/create_form_component.tsx
|
|
85
|
+
var import_react2 = require("react");
|
|
86
|
+
|
|
87
|
+
// src/utils/cn.ts
|
|
88
|
+
function cn(...classes) {
|
|
89
|
+
return classes.filter(Boolean).join(" ").trim();
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// src/utils/date.ts
|
|
93
|
+
var import_moment_timezone = __toESM(require("moment-timezone"));
|
|
94
|
+
|
|
95
|
+
// src/form/create_form_component.tsx
|
|
96
|
+
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
97
|
+
function createComponent(tag, options) {
|
|
98
|
+
return function FormComponent({ className, ...props }) {
|
|
99
|
+
const Tag = tag;
|
|
100
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Tag, { ...props, className: cn(options.className, className) });
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// src/form/form_components.tsx
|
|
105
|
+
var FormEntry = createComponent("div", {
|
|
106
|
+
className: "flex-1"
|
|
107
|
+
});
|
|
108
|
+
var FormRow = createComponent("div", {
|
|
109
|
+
className: "flex-1 flex gap-4 mb-6"
|
|
110
|
+
});
|
|
111
|
+
var FormLabel = createComponent("label", {
|
|
112
|
+
className: "flex-1 font-semibold mb-2.5 block"
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
// src/crud/crud_form.tsx
|
|
116
|
+
var import_react_store_input3 = require("react-store-input");
|
|
117
|
+
|
|
118
|
+
// src/client/env_loader.tsx
|
|
119
|
+
var import_react_router2 = require("react-router");
|
|
120
|
+
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
121
|
+
|
|
122
|
+
// src/client/file_input.tsx
|
|
123
|
+
var import_react3 = require("react");
|
|
124
|
+
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
125
|
+
|
|
126
|
+
// src/client/use_user_agent.tsx
|
|
127
|
+
var import_react_router3 = require("react-router");
|
|
128
|
+
|
|
129
|
+
// src/client/store_text_editor.tsx
|
|
130
|
+
var import_dn_react_text_editor = require("dn-react-text-editor");
|
|
131
|
+
var import_react_store_input2 = require("react-store-input");
|
|
132
|
+
var import_react4 = require("react");
|
|
133
|
+
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
134
|
+
|
|
135
|
+
// src/client/editor.tsx
|
|
136
|
+
var import_client = require("gw-file/client");
|
|
137
|
+
|
|
138
|
+
// src/crud/crud_form.tsx
|
|
139
|
+
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
140
|
+
|
|
141
|
+
// src/api/patch_resource_handler.ts
|
|
142
|
+
var import_drizzle_orm = require("drizzle-orm");
|
|
143
|
+
function patchResourceHandler({
|
|
144
|
+
repository,
|
|
145
|
+
validators,
|
|
146
|
+
primaryKey
|
|
147
|
+
}) {
|
|
148
|
+
return async (existing, request) => {
|
|
149
|
+
const serilaizedParams = await request.json();
|
|
150
|
+
const params = deserialize(serilaizedParams) || {};
|
|
151
|
+
if (validators) {
|
|
152
|
+
const paramsForValidation = Object.keys(validators).filter(
|
|
153
|
+
(key) => Object.prototype.hasOwnProperty.call(validators, key)
|
|
154
|
+
);
|
|
155
|
+
for (const paramKey of paramsForValidation) {
|
|
156
|
+
const value = params[paramKey];
|
|
157
|
+
const validator = validators[paramKey];
|
|
158
|
+
if (validator?.validate && !validator.validate(value)) {
|
|
159
|
+
return (0, import_gw_response.httpBadRequest)({
|
|
160
|
+
code: "BAD_REQUEST",
|
|
161
|
+
message: validator.message ? validator.message(value) : "\uC798\uBABB\uB41C \uC694\uCCAD\uC785\uB2C8\uB2E4."
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
const item = await repository.update(existing[primaryKey], {
|
|
167
|
+
...params
|
|
168
|
+
});
|
|
169
|
+
return (0, import_gw_response.httpCreated)(item);
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
173
|
+
0 && (module.exports = {
|
|
174
|
+
patchResourceHandler
|
|
175
|
+
});
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
// src/api/patch_resource_handler.ts
|
|
2
|
+
import { httpBadRequest, httpCreated } from "gw-response";
|
|
3
|
+
|
|
4
|
+
// src/crud/crud_form_provider.tsx
|
|
5
|
+
import { useNavigate } from "react-router";
|
|
6
|
+
import { useStore } from "react-store-input";
|
|
7
|
+
import {
|
|
8
|
+
createContext,
|
|
9
|
+
useContext
|
|
10
|
+
} from "react";
|
|
11
|
+
|
|
12
|
+
// src/crud/serialize.ts
|
|
13
|
+
function deserialize(data) {
|
|
14
|
+
if (data === void 0) {
|
|
15
|
+
return void 0;
|
|
16
|
+
}
|
|
17
|
+
if (typeof data === "object" && data !== null && "type" in data && "value" in data) {
|
|
18
|
+
const { type, value } = data;
|
|
19
|
+
switch (type) {
|
|
20
|
+
case "null":
|
|
21
|
+
return null;
|
|
22
|
+
case "string":
|
|
23
|
+
return value;
|
|
24
|
+
case "number":
|
|
25
|
+
return value;
|
|
26
|
+
case "boolean":
|
|
27
|
+
return value;
|
|
28
|
+
case "date":
|
|
29
|
+
return new Date(value);
|
|
30
|
+
case "array":
|
|
31
|
+
return value.map((item) => deserialize(item));
|
|
32
|
+
case "object":
|
|
33
|
+
return Object.entries(value).reduce(
|
|
34
|
+
(acc, [key, value2]) => {
|
|
35
|
+
return {
|
|
36
|
+
...acc,
|
|
37
|
+
[key]: deserialize(value2)
|
|
38
|
+
};
|
|
39
|
+
},
|
|
40
|
+
{}
|
|
41
|
+
);
|
|
42
|
+
default:
|
|
43
|
+
return void 0;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return void 0;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// src/crud/crud_form_provider.tsx
|
|
50
|
+
import { jsx } from "react/jsx-runtime";
|
|
51
|
+
var FormContext = createContext({});
|
|
52
|
+
|
|
53
|
+
// src/form/create_form_component.tsx
|
|
54
|
+
import "react";
|
|
55
|
+
|
|
56
|
+
// src/utils/cn.ts
|
|
57
|
+
function cn(...classes) {
|
|
58
|
+
return classes.filter(Boolean).join(" ").trim();
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// src/utils/date.ts
|
|
62
|
+
import moment from "moment-timezone";
|
|
63
|
+
|
|
64
|
+
// src/form/create_form_component.tsx
|
|
65
|
+
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
66
|
+
function createComponent(tag, options) {
|
|
67
|
+
return function FormComponent({ className, ...props }) {
|
|
68
|
+
const Tag = tag;
|
|
69
|
+
return /* @__PURE__ */ jsx2(Tag, { ...props, className: cn(options.className, className) });
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// src/form/form_components.tsx
|
|
74
|
+
var FormEntry = createComponent("div", {
|
|
75
|
+
className: "flex-1"
|
|
76
|
+
});
|
|
77
|
+
var FormRow = createComponent("div", {
|
|
78
|
+
className: "flex-1 flex gap-4 mb-6"
|
|
79
|
+
});
|
|
80
|
+
var FormLabel = createComponent("label", {
|
|
81
|
+
className: "flex-1 font-semibold mb-2.5 block"
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
// src/crud/crud_form.tsx
|
|
85
|
+
import { useStoreComponent } from "react-store-input";
|
|
86
|
+
|
|
87
|
+
// src/client/env_loader.tsx
|
|
88
|
+
import { useRouteLoaderData } from "react-router";
|
|
89
|
+
import { jsx as jsx3 } from "react/jsx-runtime";
|
|
90
|
+
|
|
91
|
+
// src/client/file_input.tsx
|
|
92
|
+
import {
|
|
93
|
+
useRef
|
|
94
|
+
} from "react";
|
|
95
|
+
import { Fragment, jsx as jsx4, jsxs } from "react/jsx-runtime";
|
|
96
|
+
|
|
97
|
+
// src/client/use_user_agent.tsx
|
|
98
|
+
import { useRouteLoaderData as useRouteLoaderData2 } from "react-router";
|
|
99
|
+
|
|
100
|
+
// src/client/store_text_editor.tsx
|
|
101
|
+
import {
|
|
102
|
+
TextEditor
|
|
103
|
+
} from "dn-react-text-editor";
|
|
104
|
+
import { useStoreController } from "react-store-input";
|
|
105
|
+
import { useImperativeHandle, useRef as useRef2 } from "react";
|
|
106
|
+
import { jsx as jsx5 } from "react/jsx-runtime";
|
|
107
|
+
|
|
108
|
+
// src/client/editor.tsx
|
|
109
|
+
import { generateMetadata } from "gw-file/client";
|
|
110
|
+
|
|
111
|
+
// src/crud/crud_form.tsx
|
|
112
|
+
import { Fragment as Fragment2, jsx as jsx6, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
113
|
+
|
|
114
|
+
// src/api/patch_resource_handler.ts
|
|
115
|
+
import "drizzle-orm";
|
|
116
|
+
function patchResourceHandler({
|
|
117
|
+
repository,
|
|
118
|
+
validators,
|
|
119
|
+
primaryKey
|
|
120
|
+
}) {
|
|
121
|
+
return async (existing, request) => {
|
|
122
|
+
const serilaizedParams = await request.json();
|
|
123
|
+
const params = deserialize(serilaizedParams) || {};
|
|
124
|
+
if (validators) {
|
|
125
|
+
const paramsForValidation = Object.keys(validators).filter(
|
|
126
|
+
(key) => Object.prototype.hasOwnProperty.call(validators, key)
|
|
127
|
+
);
|
|
128
|
+
for (const paramKey of paramsForValidation) {
|
|
129
|
+
const value = params[paramKey];
|
|
130
|
+
const validator = validators[paramKey];
|
|
131
|
+
if (validator?.validate && !validator.validate(value)) {
|
|
132
|
+
return httpBadRequest({
|
|
133
|
+
code: "BAD_REQUEST",
|
|
134
|
+
message: validator.message ? validator.message(value) : "\uC798\uBABB\uB41C \uC694\uCCAD\uC785\uB2C8\uB2E4."
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
const item = await repository.update(existing[primaryKey], {
|
|
140
|
+
...params
|
|
141
|
+
});
|
|
142
|
+
return httpCreated(item);
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
export {
|
|
146
|
+
patchResourceHandler
|
|
147
|
+
};
|
|
@@ -13,13 +13,13 @@ type PutResourceValidators<T extends PgTableWithColumns<any>> = {
|
|
|
13
13
|
type PutResourceExistingConditions<T extends PgTableWithColumns<any>> = {
|
|
14
14
|
[K in keyof InferSelectModel<T>]?: (value: InferSelectModel<T>[K]) => SQLWrapper;
|
|
15
15
|
};
|
|
16
|
-
type PutResourceHandlerOptions<T extends PgTableWithColumns<any>, TSelect> = {
|
|
17
|
-
repository: TableRepository<T, TSelect>;
|
|
16
|
+
type PutResourceHandlerOptions<T extends PgTableWithColumns<any>, TSelect, TPrimaryKey extends keyof TSelect = "id" extends keyof TSelect ? "id" : never> = {
|
|
17
|
+
repository: TableRepository<T, TSelect, TPrimaryKey>;
|
|
18
18
|
validators?: PutResourceValidators<T>;
|
|
19
19
|
existingConditions?: PutResourceExistingConditions<T>;
|
|
20
20
|
injectUserId?: boolean;
|
|
21
21
|
isOwnedBy?: (auth: AccessTokenPayload, item: TSelect) => boolean;
|
|
22
22
|
};
|
|
23
|
-
declare function putResourceHandler<T extends PgTableWithColumns<any>, TSelect>({ repository, validators, existingConditions, injectUserId, isOwnedBy, }: PutResourceHandlerOptions<T, TSelect>): (auth: AccessTokenPayload | undefined, request: Request) => Promise<Response>;
|
|
23
|
+
declare function putResourceHandler<T extends PgTableWithColumns<any>, TSelect, TPrimaryKey extends keyof TSelect = "id" extends keyof TSelect ? "id" : never>({ repository, validators, existingConditions, injectUserId, isOwnedBy, }: PutResourceHandlerOptions<T, TSelect, TPrimaryKey>): (auth: AccessTokenPayload | undefined, request: Request) => Promise<Response>;
|
|
24
24
|
|
|
25
25
|
export { type PutResourceExistingConditions, type PutResourceHandlerOptions, type PutResourceValidators, putResourceHandler };
|
|
@@ -13,13 +13,13 @@ type PutResourceValidators<T extends PgTableWithColumns<any>> = {
|
|
|
13
13
|
type PutResourceExistingConditions<T extends PgTableWithColumns<any>> = {
|
|
14
14
|
[K in keyof InferSelectModel<T>]?: (value: InferSelectModel<T>[K]) => SQLWrapper;
|
|
15
15
|
};
|
|
16
|
-
type PutResourceHandlerOptions<T extends PgTableWithColumns<any>, TSelect> = {
|
|
17
|
-
repository: TableRepository<T, TSelect>;
|
|
16
|
+
type PutResourceHandlerOptions<T extends PgTableWithColumns<any>, TSelect, TPrimaryKey extends keyof TSelect = "id" extends keyof TSelect ? "id" : never> = {
|
|
17
|
+
repository: TableRepository<T, TSelect, TPrimaryKey>;
|
|
18
18
|
validators?: PutResourceValidators<T>;
|
|
19
19
|
existingConditions?: PutResourceExistingConditions<T>;
|
|
20
20
|
injectUserId?: boolean;
|
|
21
21
|
isOwnedBy?: (auth: AccessTokenPayload, item: TSelect) => boolean;
|
|
22
22
|
};
|
|
23
|
-
declare function putResourceHandler<T extends PgTableWithColumns<any>, TSelect>({ repository, validators, existingConditions, injectUserId, isOwnedBy, }: PutResourceHandlerOptions<T, TSelect>): (auth: AccessTokenPayload | undefined, request: Request) => Promise<Response>;
|
|
23
|
+
declare function putResourceHandler<T extends PgTableWithColumns<any>, TSelect, TPrimaryKey extends keyof TSelect = "id" extends keyof TSelect ? "id" : never>({ repository, validators, existingConditions, injectUserId, isOwnedBy, }: PutResourceHandlerOptions<T, TSelect, TPrimaryKey>): (auth: AccessTokenPayload | undefined, request: Request) => Promise<Response>;
|
|
24
24
|
|
|
25
25
|
export { type PutResourceExistingConditions, type PutResourceHandlerOptions, type PutResourceValidators, putResourceHandler };
|
|
@@ -9,16 +9,17 @@ import 'drizzle-orm';
|
|
|
9
9
|
import 'drizzle-orm/node-postgres';
|
|
10
10
|
import 'gw-auth/server';
|
|
11
11
|
|
|
12
|
-
type APIHandlerOptions<T extends PgTableWithColumns<any>, TSelect> = {
|
|
12
|
+
type APIHandlerOptions<T extends PgTableWithColumns<any>, TSelect, TPrimaryKey extends keyof TSelect = "id" extends keyof TSelect ? "id" : never> = {
|
|
13
13
|
withAuthAction: WithAuthHandler<ActionFunctionArgs>;
|
|
14
|
-
repository: TableRepository<T, TSelect>;
|
|
14
|
+
repository: TableRepository<T, TSelect, TPrimaryKey>;
|
|
15
|
+
primaryKey: TPrimaryKey;
|
|
15
16
|
validators?: PutResourceValidators<T>;
|
|
16
17
|
existingConditions?: PutResourceExistingConditions<T>;
|
|
17
18
|
injectUserId?: boolean;
|
|
18
19
|
roles?: string[];
|
|
19
20
|
isOwnedBy?: (auth: AccessTokenPayload, item: TSelect) => boolean;
|
|
20
21
|
};
|
|
21
|
-
declare function resourceHandler<T extends PgTableWithColumns<any>, TSelect>({ withAuthAction, repository, validators, existingConditions, injectUserId, roles, isOwnedBy, }: APIHandlerOptions<T, TSelect>): {
|
|
22
|
+
declare function resourceHandler<T extends PgTableWithColumns<any>, TSelect, TPrimaryKey extends keyof TSelect = "id" extends keyof TSelect ? "id" : never>({ withAuthAction, repository, validators, existingConditions, injectUserId, roles, isOwnedBy, primaryKey, }: APIHandlerOptions<T, TSelect, TPrimaryKey>): {
|
|
22
23
|
loader: ({ request }: LoaderFunctionArgs) => Promise<gw_result.Ok<{}>>;
|
|
23
24
|
action: (arg: ActionFunctionArgs<any>) => Promise<unknown> | unknown;
|
|
24
25
|
};
|
|
@@ -9,16 +9,17 @@ import 'drizzle-orm';
|
|
|
9
9
|
import 'drizzle-orm/node-postgres';
|
|
10
10
|
import 'gw-auth/server';
|
|
11
11
|
|
|
12
|
-
type APIHandlerOptions<T extends PgTableWithColumns<any>, TSelect> = {
|
|
12
|
+
type APIHandlerOptions<T extends PgTableWithColumns<any>, TSelect, TPrimaryKey extends keyof TSelect = "id" extends keyof TSelect ? "id" : never> = {
|
|
13
13
|
withAuthAction: WithAuthHandler<ActionFunctionArgs>;
|
|
14
|
-
repository: TableRepository<T, TSelect>;
|
|
14
|
+
repository: TableRepository<T, TSelect, TPrimaryKey>;
|
|
15
|
+
primaryKey: TPrimaryKey;
|
|
15
16
|
validators?: PutResourceValidators<T>;
|
|
16
17
|
existingConditions?: PutResourceExistingConditions<T>;
|
|
17
18
|
injectUserId?: boolean;
|
|
18
19
|
roles?: string[];
|
|
19
20
|
isOwnedBy?: (auth: AccessTokenPayload, item: TSelect) => boolean;
|
|
20
21
|
};
|
|
21
|
-
declare function resourceHandler<T extends PgTableWithColumns<any>, TSelect>({ withAuthAction, repository, validators, existingConditions, injectUserId, roles, isOwnedBy, }: APIHandlerOptions<T, TSelect>): {
|
|
22
|
+
declare function resourceHandler<T extends PgTableWithColumns<any>, TSelect, TPrimaryKey extends keyof TSelect = "id" extends keyof TSelect ? "id" : never>({ withAuthAction, repository, validators, existingConditions, injectUserId, roles, isOwnedBy, primaryKey, }: APIHandlerOptions<T, TSelect, TPrimaryKey>): {
|
|
22
23
|
loader: ({ request }: LoaderFunctionArgs) => Promise<gw_result.Ok<{}>>;
|
|
23
24
|
action: (arg: ActionFunctionArgs<any>) => Promise<unknown> | unknown;
|
|
24
25
|
};
|
|
@@ -33,7 +33,7 @@ __export(resource_handler_exports, {
|
|
|
33
33
|
resourceHandler: () => resourceHandler
|
|
34
34
|
});
|
|
35
35
|
module.exports = __toCommonJS(resource_handler_exports);
|
|
36
|
-
var
|
|
36
|
+
var import_gw_response3 = require("gw-response");
|
|
37
37
|
var import_gw_result = require("gw-result");
|
|
38
38
|
|
|
39
39
|
// src/api/put_resource_handler.ts
|
|
@@ -213,6 +213,39 @@ function putResourceHandler({
|
|
|
213
213
|
};
|
|
214
214
|
}
|
|
215
215
|
|
|
216
|
+
// src/api/patch_resource_handler.ts
|
|
217
|
+
var import_gw_response2 = require("gw-response");
|
|
218
|
+
var import_drizzle_orm2 = require("drizzle-orm");
|
|
219
|
+
function patchResourceHandler({
|
|
220
|
+
repository,
|
|
221
|
+
validators,
|
|
222
|
+
primaryKey
|
|
223
|
+
}) {
|
|
224
|
+
return async (existing, request) => {
|
|
225
|
+
const serilaizedParams = await request.json();
|
|
226
|
+
const params = deserialize(serilaizedParams) || {};
|
|
227
|
+
if (validators) {
|
|
228
|
+
const paramsForValidation = Object.keys(validators).filter(
|
|
229
|
+
(key) => Object.prototype.hasOwnProperty.call(validators, key)
|
|
230
|
+
);
|
|
231
|
+
for (const paramKey of paramsForValidation) {
|
|
232
|
+
const value = params[paramKey];
|
|
233
|
+
const validator = validators[paramKey];
|
|
234
|
+
if (validator?.validate && !validator.validate(value)) {
|
|
235
|
+
return (0, import_gw_response2.httpBadRequest)({
|
|
236
|
+
code: "BAD_REQUEST",
|
|
237
|
+
message: validator.message ? validator.message(value) : "\uC798\uBABB\uB41C \uC694\uCCAD\uC785\uB2C8\uB2E4."
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
const item = await repository.update(existing[primaryKey], {
|
|
243
|
+
...params
|
|
244
|
+
});
|
|
245
|
+
return (0, import_gw_response2.httpCreated)(item);
|
|
246
|
+
};
|
|
247
|
+
}
|
|
248
|
+
|
|
216
249
|
// src/api/resource_handler.ts
|
|
217
250
|
function resourceHandler({
|
|
218
251
|
withAuthAction,
|
|
@@ -221,34 +254,44 @@ function resourceHandler({
|
|
|
221
254
|
existingConditions,
|
|
222
255
|
injectUserId,
|
|
223
256
|
roles,
|
|
224
|
-
isOwnedBy
|
|
257
|
+
isOwnedBy,
|
|
258
|
+
primaryKey
|
|
225
259
|
}) {
|
|
226
260
|
const loader = async ({ request }) => {
|
|
227
261
|
return (0, import_gw_result.ok)({});
|
|
228
262
|
};
|
|
229
263
|
const action = withAuthAction((auth) => async ({ request, params }) => {
|
|
230
264
|
if (roles && roles.length > 0 && (!auth || !roles.includes(auth.role))) {
|
|
231
|
-
return (0,
|
|
265
|
+
return (0, import_gw_response3.httpForbidden)({
|
|
232
266
|
code: "FORBIDDEN",
|
|
233
267
|
message: "\uAD8C\uD55C\uC774 \uC5C6\uC2B5\uB2C8\uB2E4."
|
|
234
268
|
});
|
|
235
269
|
}
|
|
236
|
-
const
|
|
270
|
+
const pathname = new URL(request.url).pathname;
|
|
271
|
+
const itemId = pathname.split("/").filter(Boolean).at(-1);
|
|
237
272
|
if (itemId) {
|
|
238
273
|
const existing = await repository.find(itemId);
|
|
239
274
|
if (!existing) {
|
|
240
|
-
return (0,
|
|
275
|
+
return (0, import_gw_response3.httpNotFound)();
|
|
241
276
|
}
|
|
242
277
|
if (isOwnedBy && (!auth || !isOwnedBy(auth, existing))) {
|
|
243
|
-
return (0,
|
|
278
|
+
return (0, import_gw_response3.httpForbidden)();
|
|
244
279
|
}
|
|
245
280
|
switch (request.method) {
|
|
281
|
+
case "PATCH": {
|
|
282
|
+
const handler = patchResourceHandler({
|
|
283
|
+
repository,
|
|
284
|
+
validators,
|
|
285
|
+
primaryKey
|
|
286
|
+
});
|
|
287
|
+
return handler(existing, request);
|
|
288
|
+
}
|
|
246
289
|
case "DELETE": {
|
|
247
290
|
await repository.delete(itemId);
|
|
248
|
-
return (0,
|
|
291
|
+
return (0, import_gw_response3.httpNoContent)();
|
|
249
292
|
}
|
|
250
293
|
default: {
|
|
251
|
-
return (0,
|
|
294
|
+
return (0, import_gw_response3.httpMethodNotAllowed)();
|
|
252
295
|
}
|
|
253
296
|
}
|
|
254
297
|
}
|
|
@@ -265,7 +308,7 @@ function resourceHandler({
|
|
|
265
308
|
return handler(auth, request);
|
|
266
309
|
}
|
|
267
310
|
default: {
|
|
268
|
-
return (0,
|
|
311
|
+
return (0, import_gw_response3.httpMethodNotAllowed)();
|
|
269
312
|
}
|
|
270
313
|
}
|
|
271
314
|
});
|
|
@@ -199,6 +199,39 @@ function putResourceHandler({
|
|
|
199
199
|
};
|
|
200
200
|
}
|
|
201
201
|
|
|
202
|
+
// src/api/patch_resource_handler.ts
|
|
203
|
+
import { httpBadRequest as httpBadRequest2, httpCreated as httpCreated2 } from "gw-response";
|
|
204
|
+
import "drizzle-orm";
|
|
205
|
+
function patchResourceHandler({
|
|
206
|
+
repository,
|
|
207
|
+
validators,
|
|
208
|
+
primaryKey
|
|
209
|
+
}) {
|
|
210
|
+
return async (existing, request) => {
|
|
211
|
+
const serilaizedParams = await request.json();
|
|
212
|
+
const params = deserialize(serilaizedParams) || {};
|
|
213
|
+
if (validators) {
|
|
214
|
+
const paramsForValidation = Object.keys(validators).filter(
|
|
215
|
+
(key) => Object.prototype.hasOwnProperty.call(validators, key)
|
|
216
|
+
);
|
|
217
|
+
for (const paramKey of paramsForValidation) {
|
|
218
|
+
const value = params[paramKey];
|
|
219
|
+
const validator = validators[paramKey];
|
|
220
|
+
if (validator?.validate && !validator.validate(value)) {
|
|
221
|
+
return httpBadRequest2({
|
|
222
|
+
code: "BAD_REQUEST",
|
|
223
|
+
message: validator.message ? validator.message(value) : "\uC798\uBABB\uB41C \uC694\uCCAD\uC785\uB2C8\uB2E4."
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
const item = await repository.update(existing[primaryKey], {
|
|
229
|
+
...params
|
|
230
|
+
});
|
|
231
|
+
return httpCreated2(item);
|
|
232
|
+
};
|
|
233
|
+
}
|
|
234
|
+
|
|
202
235
|
// src/api/resource_handler.ts
|
|
203
236
|
function resourceHandler({
|
|
204
237
|
withAuthAction,
|
|
@@ -207,7 +240,8 @@ function resourceHandler({
|
|
|
207
240
|
existingConditions,
|
|
208
241
|
injectUserId,
|
|
209
242
|
roles,
|
|
210
|
-
isOwnedBy
|
|
243
|
+
isOwnedBy,
|
|
244
|
+
primaryKey
|
|
211
245
|
}) {
|
|
212
246
|
const loader = async ({ request }) => {
|
|
213
247
|
return ok({});
|
|
@@ -219,7 +253,8 @@ function resourceHandler({
|
|
|
219
253
|
message: "\uAD8C\uD55C\uC774 \uC5C6\uC2B5\uB2C8\uB2E4."
|
|
220
254
|
});
|
|
221
255
|
}
|
|
222
|
-
const
|
|
256
|
+
const pathname = new URL(request.url).pathname;
|
|
257
|
+
const itemId = pathname.split("/").filter(Boolean).at(-1);
|
|
223
258
|
if (itemId) {
|
|
224
259
|
const existing = await repository.find(itemId);
|
|
225
260
|
if (!existing) {
|
|
@@ -229,6 +264,14 @@ function resourceHandler({
|
|
|
229
264
|
return httpForbidden2();
|
|
230
265
|
}
|
|
231
266
|
switch (request.method) {
|
|
267
|
+
case "PATCH": {
|
|
268
|
+
const handler = patchResourceHandler({
|
|
269
|
+
repository,
|
|
270
|
+
validators,
|
|
271
|
+
primaryKey
|
|
272
|
+
});
|
|
273
|
+
return handler(existing, request);
|
|
274
|
+
}
|
|
232
275
|
case "DELETE": {
|
|
233
276
|
await repository.delete(itemId);
|
|
234
277
|
return httpNoContent();
|
package/dist/table/index.js
CHANGED
|
@@ -41,8 +41,8 @@ var BaseTableRepository = class {
|
|
|
41
41
|
this.schema = db._.fullSchema[schema];
|
|
42
42
|
this.pk = pk;
|
|
43
43
|
}
|
|
44
|
-
async find(
|
|
45
|
-
return await this.db.select().from(this.schema).where((0, import_drizzle_orm.eq)(this.schema[this.pk],
|
|
44
|
+
async find(pk) {
|
|
45
|
+
return await this.db.select().from(this.schema).where((0, import_drizzle_orm.eq)(this.schema[this.pk], pk)).limit(1).then((res) => res[0]);
|
|
46
46
|
}
|
|
47
47
|
async countTotal({ where }) {
|
|
48
48
|
const [{ total }] = await this.db.select({ total: (0, import_drizzle_orm.count)() }).from(this.schema).where(where);
|
|
@@ -77,6 +77,10 @@ var BaseTableRepository = class {
|
|
|
77
77
|
async delete(pk) {
|
|
78
78
|
await this.db.delete(this.schema).where((0, import_drizzle_orm.eq)(this.schema[this.pk], pk));
|
|
79
79
|
}
|
|
80
|
+
async update(pk, values) {
|
|
81
|
+
const [item] = await this.db.update(this.schema).set(values).where((0, import_drizzle_orm.eq)(this.schema[this.pk], pk)).returning();
|
|
82
|
+
return item;
|
|
83
|
+
}
|
|
80
84
|
async select(key) {
|
|
81
85
|
const rows = await this.db.select({ value: this.schema[key] }).from(this.schema).groupBy(this.schema[key]);
|
|
82
86
|
return rows.map((row) => row.value);
|
package/dist/table/index.mjs
CHANGED
|
@@ -14,8 +14,8 @@ var BaseTableRepository = class {
|
|
|
14
14
|
this.schema = db._.fullSchema[schema];
|
|
15
15
|
this.pk = pk;
|
|
16
16
|
}
|
|
17
|
-
async find(
|
|
18
|
-
return await this.db.select().from(this.schema).where(eq(this.schema[this.pk],
|
|
17
|
+
async find(pk) {
|
|
18
|
+
return await this.db.select().from(this.schema).where(eq(this.schema[this.pk], pk)).limit(1).then((res) => res[0]);
|
|
19
19
|
}
|
|
20
20
|
async countTotal({ where }) {
|
|
21
21
|
const [{ total }] = await this.db.select({ total: count() }).from(this.schema).where(where);
|
|
@@ -50,6 +50,10 @@ var BaseTableRepository = class {
|
|
|
50
50
|
async delete(pk) {
|
|
51
51
|
await this.db.delete(this.schema).where(eq(this.schema[this.pk], pk));
|
|
52
52
|
}
|
|
53
|
+
async update(pk, values) {
|
|
54
|
+
const [item] = await this.db.update(this.schema).set(values).where(eq(this.schema[this.pk], pk)).returning();
|
|
55
|
+
return item;
|
|
56
|
+
}
|
|
53
57
|
async select(key) {
|
|
54
58
|
const rows = await this.db.select({ value: this.schema[key] }).from(this.schema).groupBy(this.schema[key]);
|
|
55
59
|
return rows.map((row) => row.value);
|
|
@@ -12,30 +12,32 @@ type FindAllOptions<T extends PgTableWithColumns<any>> = {
|
|
|
12
12
|
type ColumnOf<T> = T extends PgTableWithColumns<infer TConfig> ? keyof TConfig["columns"] : never;
|
|
13
13
|
type SelectModelOf<T> = T extends TableRepository<infer TSelect, any> ? TSelect : never;
|
|
14
14
|
type InsertModelOf<T> = T extends TableRepository<any, infer TInsert> ? TInsert : never;
|
|
15
|
-
interface TableRepository<T extends PgTableWithColumns<any>, TSelect = InferSelectModel<T
|
|
15
|
+
interface TableRepository<T extends PgTableWithColumns<any>, TSelect = InferSelectModel<T>, TPrimaryKey extends keyof TSelect = "id" extends keyof TSelect ? "id" : never> {
|
|
16
16
|
schema: T;
|
|
17
|
-
find: (
|
|
17
|
+
find: (pk: TSelect[TPrimaryKey]) => Promise<TSelect | undefined>;
|
|
18
18
|
countTotal: (options: {
|
|
19
19
|
where?: SQL<unknown>;
|
|
20
20
|
}) => Promise<number>;
|
|
21
21
|
findAll: (options: FindAllOptions<T>) => Promise<TSelect[]>;
|
|
22
22
|
save: (values: InferInsertModel<T>) => Promise<TSelect>;
|
|
23
|
-
|
|
23
|
+
update: (pk: TSelect[TPrimaryKey], values: Partial<InferInsertModel<T>>) => Promise<TSelect>;
|
|
24
|
+
delete: (pk: TSelect[TPrimaryKey]) => Promise<void>;
|
|
24
25
|
select(key: keyof InferSelectModel<T>): Promise<InferSelectModel<T>[typeof key][]>;
|
|
25
26
|
}
|
|
26
27
|
type SchemaOf<TDatabase extends NodePgDatabase<any>, TSchemaKey extends keyof TDatabase["_"]["fullSchema"]> = TDatabase["_"]["fullSchema"][TSchemaKey];
|
|
27
|
-
declare class BaseTableRepository<TDatabase extends NodePgDatabase<any>, TSchemaKey extends keyof TDatabase["_"]["fullSchema"], TSelect = InferSelectModel<SchemaOf<TDatabase, TSchemaKey>>, TPrimaryKey extends keyof TSelect = "id" extends keyof TSelect ? "id" : never> implements TableRepository<SchemaOf<TDatabase, TSchemaKey
|
|
28
|
+
declare class BaseTableRepository<TDatabase extends NodePgDatabase<any>, TSchemaKey extends keyof TDatabase["_"]["fullSchema"], TSelect = InferSelectModel<SchemaOf<TDatabase, TSchemaKey>>, TPrimaryKey extends keyof TSelect = "id" extends keyof TSelect ? "id" : never> implements TableRepository<SchemaOf<TDatabase, TSchemaKey>, TSelect, TPrimaryKey> {
|
|
28
29
|
db: TDatabase;
|
|
29
30
|
schema: SchemaOf<TDatabase, TSchemaKey>;
|
|
30
31
|
pk: TPrimaryKey;
|
|
31
32
|
constructor(db: TDatabase, schema: TSchemaKey, pk?: TPrimaryKey);
|
|
32
|
-
find(
|
|
33
|
+
find(pk: TSelect[TPrimaryKey]): Promise<TSelect | undefined>;
|
|
33
34
|
countTotal({ where }: {
|
|
34
35
|
where?: SQL<unknown>;
|
|
35
36
|
}): Promise<number>;
|
|
36
37
|
findAll(options: FindAllOptions<SchemaOf<TDatabase, TSchemaKey>>): Promise<TSelect[]>;
|
|
37
38
|
save(values: InferInsertModel<SchemaOf<TDatabase, TSchemaKey>>): Promise<TSelect>;
|
|
38
|
-
delete(pk:
|
|
39
|
+
delete(pk: TSelect[TPrimaryKey]): Promise<void>;
|
|
40
|
+
update(pk: TSelect[TPrimaryKey], values: Partial<InferInsertModel<SchemaOf<TDatabase, TSchemaKey>>>): Promise<TSelect>;
|
|
39
41
|
select(key: keyof InferSelectModel<SchemaOf<TDatabase, TSchemaKey>>): Promise<InferSelectModel<SchemaOf<TDatabase, TSchemaKey>>[typeof key][]>;
|
|
40
42
|
}
|
|
41
43
|
|
|
@@ -12,30 +12,32 @@ type FindAllOptions<T extends PgTableWithColumns<any>> = {
|
|
|
12
12
|
type ColumnOf<T> = T extends PgTableWithColumns<infer TConfig> ? keyof TConfig["columns"] : never;
|
|
13
13
|
type SelectModelOf<T> = T extends TableRepository<infer TSelect, any> ? TSelect : never;
|
|
14
14
|
type InsertModelOf<T> = T extends TableRepository<any, infer TInsert> ? TInsert : never;
|
|
15
|
-
interface TableRepository<T extends PgTableWithColumns<any>, TSelect = InferSelectModel<T
|
|
15
|
+
interface TableRepository<T extends PgTableWithColumns<any>, TSelect = InferSelectModel<T>, TPrimaryKey extends keyof TSelect = "id" extends keyof TSelect ? "id" : never> {
|
|
16
16
|
schema: T;
|
|
17
|
-
find: (
|
|
17
|
+
find: (pk: TSelect[TPrimaryKey]) => Promise<TSelect | undefined>;
|
|
18
18
|
countTotal: (options: {
|
|
19
19
|
where?: SQL<unknown>;
|
|
20
20
|
}) => Promise<number>;
|
|
21
21
|
findAll: (options: FindAllOptions<T>) => Promise<TSelect[]>;
|
|
22
22
|
save: (values: InferInsertModel<T>) => Promise<TSelect>;
|
|
23
|
-
|
|
23
|
+
update: (pk: TSelect[TPrimaryKey], values: Partial<InferInsertModel<T>>) => Promise<TSelect>;
|
|
24
|
+
delete: (pk: TSelect[TPrimaryKey]) => Promise<void>;
|
|
24
25
|
select(key: keyof InferSelectModel<T>): Promise<InferSelectModel<T>[typeof key][]>;
|
|
25
26
|
}
|
|
26
27
|
type SchemaOf<TDatabase extends NodePgDatabase<any>, TSchemaKey extends keyof TDatabase["_"]["fullSchema"]> = TDatabase["_"]["fullSchema"][TSchemaKey];
|
|
27
|
-
declare class BaseTableRepository<TDatabase extends NodePgDatabase<any>, TSchemaKey extends keyof TDatabase["_"]["fullSchema"], TSelect = InferSelectModel<SchemaOf<TDatabase, TSchemaKey>>, TPrimaryKey extends keyof TSelect = "id" extends keyof TSelect ? "id" : never> implements TableRepository<SchemaOf<TDatabase, TSchemaKey
|
|
28
|
+
declare class BaseTableRepository<TDatabase extends NodePgDatabase<any>, TSchemaKey extends keyof TDatabase["_"]["fullSchema"], TSelect = InferSelectModel<SchemaOf<TDatabase, TSchemaKey>>, TPrimaryKey extends keyof TSelect = "id" extends keyof TSelect ? "id" : never> implements TableRepository<SchemaOf<TDatabase, TSchemaKey>, TSelect, TPrimaryKey> {
|
|
28
29
|
db: TDatabase;
|
|
29
30
|
schema: SchemaOf<TDatabase, TSchemaKey>;
|
|
30
31
|
pk: TPrimaryKey;
|
|
31
32
|
constructor(db: TDatabase, schema: TSchemaKey, pk?: TPrimaryKey);
|
|
32
|
-
find(
|
|
33
|
+
find(pk: TSelect[TPrimaryKey]): Promise<TSelect | undefined>;
|
|
33
34
|
countTotal({ where }: {
|
|
34
35
|
where?: SQL<unknown>;
|
|
35
36
|
}): Promise<number>;
|
|
36
37
|
findAll(options: FindAllOptions<SchemaOf<TDatabase, TSchemaKey>>): Promise<TSelect[]>;
|
|
37
38
|
save(values: InferInsertModel<SchemaOf<TDatabase, TSchemaKey>>): Promise<TSelect>;
|
|
38
|
-
delete(pk:
|
|
39
|
+
delete(pk: TSelect[TPrimaryKey]): Promise<void>;
|
|
40
|
+
update(pk: TSelect[TPrimaryKey], values: Partial<InferInsertModel<SchemaOf<TDatabase, TSchemaKey>>>): Promise<TSelect>;
|
|
39
41
|
select(key: keyof InferSelectModel<SchemaOf<TDatabase, TSchemaKey>>): Promise<InferSelectModel<SchemaOf<TDatabase, TSchemaKey>>[typeof key][]>;
|
|
40
42
|
}
|
|
41
43
|
|
package/dist/table/repository.js
CHANGED
|
@@ -33,8 +33,8 @@ var BaseTableRepository = class {
|
|
|
33
33
|
this.schema = db._.fullSchema[schema];
|
|
34
34
|
this.pk = pk;
|
|
35
35
|
}
|
|
36
|
-
async find(
|
|
37
|
-
return await this.db.select().from(this.schema).where((0, import_drizzle_orm.eq)(this.schema[this.pk],
|
|
36
|
+
async find(pk) {
|
|
37
|
+
return await this.db.select().from(this.schema).where((0, import_drizzle_orm.eq)(this.schema[this.pk], pk)).limit(1).then((res) => res[0]);
|
|
38
38
|
}
|
|
39
39
|
async countTotal({ where }) {
|
|
40
40
|
const [{ total }] = await this.db.select({ total: (0, import_drizzle_orm.count)() }).from(this.schema).where(where);
|
|
@@ -69,6 +69,10 @@ var BaseTableRepository = class {
|
|
|
69
69
|
async delete(pk) {
|
|
70
70
|
await this.db.delete(this.schema).where((0, import_drizzle_orm.eq)(this.schema[this.pk], pk));
|
|
71
71
|
}
|
|
72
|
+
async update(pk, values) {
|
|
73
|
+
const [item] = await this.db.update(this.schema).set(values).where((0, import_drizzle_orm.eq)(this.schema[this.pk], pk)).returning();
|
|
74
|
+
return item;
|
|
75
|
+
}
|
|
72
76
|
async select(key) {
|
|
73
77
|
const rows = await this.db.select({ value: this.schema[key] }).from(this.schema).groupBy(this.schema[key]);
|
|
74
78
|
return rows.map((row) => row.value);
|
|
@@ -14,8 +14,8 @@ var BaseTableRepository = class {
|
|
|
14
14
|
this.schema = db._.fullSchema[schema];
|
|
15
15
|
this.pk = pk;
|
|
16
16
|
}
|
|
17
|
-
async find(
|
|
18
|
-
return await this.db.select().from(this.schema).where(eq(this.schema[this.pk],
|
|
17
|
+
async find(pk) {
|
|
18
|
+
return await this.db.select().from(this.schema).where(eq(this.schema[this.pk], pk)).limit(1).then((res) => res[0]);
|
|
19
19
|
}
|
|
20
20
|
async countTotal({ where }) {
|
|
21
21
|
const [{ total }] = await this.db.select({ total: count() }).from(this.schema).where(where);
|
|
@@ -50,6 +50,10 @@ var BaseTableRepository = class {
|
|
|
50
50
|
async delete(pk) {
|
|
51
51
|
await this.db.delete(this.schema).where(eq(this.schema[this.pk], pk));
|
|
52
52
|
}
|
|
53
|
+
async update(pk, values) {
|
|
54
|
+
const [item] = await this.db.update(this.schema).set(values).where(eq(this.schema[this.pk], pk)).returning();
|
|
55
|
+
return item;
|
|
56
|
+
}
|
|
53
57
|
async select(key) {
|
|
54
58
|
const rows = await this.db.select({ value: this.schema[key] }).from(this.schema).groupBy(this.schema[key]);
|
|
55
59
|
return rows.map((row) => row.value);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dn-react-router-toolkit",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.5",
|
|
4
4
|
"types": "./dist/index.d.ts",
|
|
5
5
|
"main": "./dist/index.mjs",
|
|
6
6
|
"module": "./dist/index.js",
|
|
@@ -91,7 +91,7 @@
|
|
|
91
91
|
"gw-auth": "^0.1.2",
|
|
92
92
|
"gw-file": "^0.1.1",
|
|
93
93
|
"gw-response": "^0.1.8",
|
|
94
|
-
"gw-result": "^0.1.
|
|
94
|
+
"gw-result": "^0.1.8",
|
|
95
95
|
"moment-timezone": "^0.6.1",
|
|
96
96
|
"pg": "^8.19.0",
|
|
97
97
|
"react-icons": "^5.5.0",
|