dn-react-router-toolkit 0.8.1 → 0.9.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.
- package/dist/crud/index.d.mts +0 -20
- package/dist/crud/index.d.ts +0 -20
- package/dist/crud/index.js +12 -8587
- package/dist/crud/index.mjs +0 -8596
- package/dist/post/index.js +67 -7705
- package/dist/post/index.mjs +54 -7718
- package/dist/post/post_form_page.js +67 -7705
- package/dist/post/post_form_page.mjs +54 -7718
- package/dist/table/index.d.mts +0 -2
- package/dist/table/index.d.ts +0 -2
- package/dist/table/index.js +12 -79
- package/dist/table/index.mjs +12 -77
- package/dist/table/load_table.d.mts +1 -1
- package/dist/table/load_table.d.ts +1 -1
- package/dist/table/load_table.js +2 -2
- package/dist/table/load_table.mjs +2 -2
- package/dist/table/loader.js +2 -2
- package/dist/table/loader.mjs +2 -2
- package/dist/table/table.d.mts +2 -2
- package/dist/table/table.d.ts +2 -2
- package/dist/table/table.js +6 -23
- package/dist/table/table.mjs +6 -23
- package/dist/table/table_form.js +6 -23
- package/dist/table/table_form.mjs +6 -23
- package/package.json +2 -2
- package/dist/crud/crud_loader.d.mts +0 -26
- package/dist/crud/crud_loader.d.ts +0 -26
- package/dist/crud/crud_loader.js +0 -351
- package/dist/crud/crud_loader.mjs +0 -337
- package/dist/crud/crud_page.d.mts +0 -32
- package/dist/crud/crud_page.d.ts +0 -32
- package/dist/crud/crud_page.js +0 -776
- package/dist/crud/crud_page.mjs +0 -758
- package/dist/crud/generate_handlers.d.mts +0 -16
- package/dist/crud/generate_handlers.d.ts +0 -16
- package/dist/crud/generate_handlers.js +0 -39
- package/dist/crud/generate_handlers.mjs +0 -14
- package/dist/crud/generate_pages.d.mts +0 -19
- package/dist/crud/generate_pages.d.ts +0 -19
- package/dist/crud/generate_pages.js +0 -55
- package/dist/crud/generate_pages.mjs +0 -30
- package/dist/crud/generate_routes.d.mts +0 -5
- package/dist/crud/generate_routes.d.ts +0 -5
- package/dist/crud/generate_routes.js +0 -7639
- package/dist/crud/generate_routes.mjs +0 -7627
- package/dist/table/item_loader.d.mts +0 -14
- package/dist/table/item_loader.d.ts +0 -14
- package/dist/table/item_loader.js +0 -43
- package/dist/table/item_loader.mjs +0 -18
- package/dist/table/page.d.mts +0 -16
- package/dist/table/page.d.ts +0 -16
- package/dist/table/page.js +0 -375
- package/dist/table/page.mjs +0 -350
|
@@ -1,337 +0,0 @@
|
|
|
1
|
-
// src/table/load_table.tsx
|
|
2
|
-
import {
|
|
3
|
-
and,
|
|
4
|
-
eq,
|
|
5
|
-
ilike
|
|
6
|
-
} from "drizzle-orm";
|
|
7
|
-
async function loadTable({
|
|
8
|
-
request,
|
|
9
|
-
repository,
|
|
10
|
-
options
|
|
11
|
-
}) {
|
|
12
|
-
const searchParams = new URL(request.url).searchParams;
|
|
13
|
-
const { where, searchKey, defaultOrderBy, defaultDirection } = options;
|
|
14
|
-
const query = searchParams.get("query") ?? void 0;
|
|
15
|
-
const limit = Number(searchParams.get("limit") ?? "20");
|
|
16
|
-
const offset = Number(searchParams.get("offset") ?? "0");
|
|
17
|
-
const orderBy = searchParams.get("orderBy") ?? defaultOrderBy;
|
|
18
|
-
const direction = searchParams.get("direction") ?? defaultDirection;
|
|
19
|
-
const filterWhere = Object.entries(options.filters ?? {}).map(([key, value]) => {
|
|
20
|
-
const param = searchParams.get(key);
|
|
21
|
-
if (param) {
|
|
22
|
-
return eq(
|
|
23
|
-
repository.schema[key],
|
|
24
|
-
decodeURIComponent(param)
|
|
25
|
-
);
|
|
26
|
-
}
|
|
27
|
-
return void 0;
|
|
28
|
-
}).filter(Boolean);
|
|
29
|
-
const whereClauses = and(
|
|
30
|
-
searchKey && query ? ilike(
|
|
31
|
-
repository.schema[searchKey],
|
|
32
|
-
`%${query}%`
|
|
33
|
-
) : void 0,
|
|
34
|
-
...filterWhere,
|
|
35
|
-
...where ?? []
|
|
36
|
-
);
|
|
37
|
-
const total = await repository.countTotal({ where: whereClauses });
|
|
38
|
-
const items = await repository.findAll({
|
|
39
|
-
orderBy,
|
|
40
|
-
direction,
|
|
41
|
-
limit,
|
|
42
|
-
offset,
|
|
43
|
-
where: whereClauses
|
|
44
|
-
});
|
|
45
|
-
const filters = Object.fromEntries(
|
|
46
|
-
await Promise.all(
|
|
47
|
-
Object.keys(options.filters ?? {}).map(async (key) => {
|
|
48
|
-
const values = await repository.select(key);
|
|
49
|
-
return [key, values.filter(Boolean)];
|
|
50
|
-
})
|
|
51
|
-
)
|
|
52
|
-
);
|
|
53
|
-
return {
|
|
54
|
-
items,
|
|
55
|
-
total,
|
|
56
|
-
limit,
|
|
57
|
-
offset,
|
|
58
|
-
orderBy,
|
|
59
|
-
direction,
|
|
60
|
-
searchKey,
|
|
61
|
-
filters
|
|
62
|
-
};
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
// src/table/loader.tsx
|
|
66
|
-
function tableLoader({
|
|
67
|
-
repository,
|
|
68
|
-
options
|
|
69
|
-
}) {
|
|
70
|
-
return async ({ request }) => {
|
|
71
|
-
const table = await loadTable({
|
|
72
|
-
request,
|
|
73
|
-
repository,
|
|
74
|
-
options
|
|
75
|
-
});
|
|
76
|
-
return {
|
|
77
|
-
table
|
|
78
|
-
};
|
|
79
|
-
};
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
// src/table/item_loader.tsx
|
|
83
|
-
var tableItemloader = ({
|
|
84
|
-
repository
|
|
85
|
-
}) => {
|
|
86
|
-
return async (args) => {
|
|
87
|
-
const { params } = args;
|
|
88
|
-
if (params["itemId"] === "new") {
|
|
89
|
-
return { item: void 0 };
|
|
90
|
-
}
|
|
91
|
-
const item = params["itemId"] ? await repository.find(params["itemId"]) : void 0;
|
|
92
|
-
return {
|
|
93
|
-
item
|
|
94
|
-
};
|
|
95
|
-
};
|
|
96
|
-
};
|
|
97
|
-
|
|
98
|
-
// src/api/create_api_handler.ts
|
|
99
|
-
import {
|
|
100
|
-
BAD_REQUEST,
|
|
101
|
-
CONFLICT,
|
|
102
|
-
CREATED,
|
|
103
|
-
INTERNAL_SERVER_ERROR,
|
|
104
|
-
METHOD_NOT_ALLOWED,
|
|
105
|
-
UNAUTHORIZED
|
|
106
|
-
} from "dn-react-toolkit/http";
|
|
107
|
-
import {
|
|
108
|
-
and as and2
|
|
109
|
-
} from "drizzle-orm";
|
|
110
|
-
import { v4 } from "uuid";
|
|
111
|
-
|
|
112
|
-
// src/crud/serialize.ts
|
|
113
|
-
function deserialize(data) {
|
|
114
|
-
if (data === void 0) {
|
|
115
|
-
return void 0;
|
|
116
|
-
}
|
|
117
|
-
if (typeof data === "object" && data !== null && "type" in data && "value" in data) {
|
|
118
|
-
const { type, value } = data;
|
|
119
|
-
switch (type) {
|
|
120
|
-
case "null":
|
|
121
|
-
return null;
|
|
122
|
-
case "string":
|
|
123
|
-
return value;
|
|
124
|
-
case "number":
|
|
125
|
-
return value;
|
|
126
|
-
case "boolean":
|
|
127
|
-
return value;
|
|
128
|
-
case "date":
|
|
129
|
-
return new Date(value);
|
|
130
|
-
case "array":
|
|
131
|
-
return value.map((item) => deserialize(item));
|
|
132
|
-
case "object":
|
|
133
|
-
return Object.entries(value).reduce(
|
|
134
|
-
(acc, [key, value2]) => {
|
|
135
|
-
return {
|
|
136
|
-
...acc,
|
|
137
|
-
[key]: deserialize(value2)
|
|
138
|
-
};
|
|
139
|
-
},
|
|
140
|
-
{}
|
|
141
|
-
);
|
|
142
|
-
default:
|
|
143
|
-
return void 0;
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
return void 0;
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
// src/api/create_api_handler.ts
|
|
150
|
-
function apiHandler({
|
|
151
|
-
withAuthAction,
|
|
152
|
-
repository,
|
|
153
|
-
validators,
|
|
154
|
-
existingConditions,
|
|
155
|
-
injectUserId,
|
|
156
|
-
roles
|
|
157
|
-
}) {
|
|
158
|
-
const loader = async ({ request }) => {
|
|
159
|
-
return {};
|
|
160
|
-
};
|
|
161
|
-
const action = withAuthAction((auth) => async ({ request }) => {
|
|
162
|
-
if (roles && roles.length > 0 && (!auth || !roles.includes(auth.role))) {
|
|
163
|
-
throw UNAUTHORIZED();
|
|
164
|
-
}
|
|
165
|
-
switch (request.method) {
|
|
166
|
-
case "POST":
|
|
167
|
-
case "PUT": {
|
|
168
|
-
try {
|
|
169
|
-
const serilaizedParams = await request.json();
|
|
170
|
-
const params = deserialize(serilaizedParams);
|
|
171
|
-
if (validators) {
|
|
172
|
-
const paramsForValidation = Object.keys(validators).filter(
|
|
173
|
-
(key) => Object.prototype.hasOwnProperty.call(validators, key)
|
|
174
|
-
);
|
|
175
|
-
for (const paramKey of paramsForValidation) {
|
|
176
|
-
const value = params[paramKey];
|
|
177
|
-
const validator = validators[paramKey];
|
|
178
|
-
if (validator?.validate && !validator.validate(value)) {
|
|
179
|
-
throw BAD_REQUEST(
|
|
180
|
-
validator.message ? validator.message(value) : void 0
|
|
181
|
-
);
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
const itemId = params.id || v4();
|
|
186
|
-
if (!params.id && existingConditions) {
|
|
187
|
-
const paramsForExistenceCheck = Object.keys(
|
|
188
|
-
existingConditions
|
|
189
|
-
).filter(
|
|
190
|
-
(key) => Object.prototype.hasOwnProperty.call(params, key)
|
|
191
|
-
);
|
|
192
|
-
if (paramsForExistenceCheck.length > 0) {
|
|
193
|
-
const where = and2(
|
|
194
|
-
...paramsForExistenceCheck.reduce((acc, key) => {
|
|
195
|
-
const condition = existingConditions[key];
|
|
196
|
-
if (condition) {
|
|
197
|
-
acc.push(condition(params[key]));
|
|
198
|
-
}
|
|
199
|
-
return acc;
|
|
200
|
-
}, [])
|
|
201
|
-
);
|
|
202
|
-
const existing = await repository.findAll({
|
|
203
|
-
limit: 1,
|
|
204
|
-
where
|
|
205
|
-
});
|
|
206
|
-
if (existing.length > 0) {
|
|
207
|
-
throw CONFLICT("\uC790\uB8CC\uAC00 \uC774\uBBF8 \uC874\uC7AC\uD569\uB2C8\uB2E4.");
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
const values = {
|
|
212
|
-
id: itemId,
|
|
213
|
-
userId: injectUserId ? auth?.userId : void 0,
|
|
214
|
-
...params
|
|
215
|
-
};
|
|
216
|
-
const item = await repository.save(values);
|
|
217
|
-
return CREATED(item);
|
|
218
|
-
} catch (error) {
|
|
219
|
-
if (error instanceof Error) {
|
|
220
|
-
throw INTERNAL_SERVER_ERROR(error.message);
|
|
221
|
-
}
|
|
222
|
-
throw error;
|
|
223
|
-
}
|
|
224
|
-
}
|
|
225
|
-
default:
|
|
226
|
-
throw METHOD_NOT_ALLOWED();
|
|
227
|
-
}
|
|
228
|
-
});
|
|
229
|
-
return {
|
|
230
|
-
loader,
|
|
231
|
-
action
|
|
232
|
-
};
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
// src/api/item_api_handler.ts
|
|
236
|
-
import { FORBIDDEN, NOT_FOUND, UNAUTHORIZED as UNAUTHORIZED2 } from "dn-react-toolkit/http";
|
|
237
|
-
function itemApiHandler({
|
|
238
|
-
withAuthAction,
|
|
239
|
-
repository,
|
|
240
|
-
isOwnedBy,
|
|
241
|
-
roles
|
|
242
|
-
}) {
|
|
243
|
-
const loader = async ({ request }) => {
|
|
244
|
-
return {};
|
|
245
|
-
};
|
|
246
|
-
const action = withAuthAction((auth) => async ({ params, request }) => {
|
|
247
|
-
if (roles && roles.length > 0 && (!auth || !roles.includes(auth.role))) {
|
|
248
|
-
throw UNAUTHORIZED2();
|
|
249
|
-
}
|
|
250
|
-
const itemId = params.itemId;
|
|
251
|
-
const existing = await repository.find(itemId);
|
|
252
|
-
if (!existing) {
|
|
253
|
-
throw NOT_FOUND();
|
|
254
|
-
}
|
|
255
|
-
if (isOwnedBy && !isOwnedBy(existing, auth)) {
|
|
256
|
-
throw FORBIDDEN();
|
|
257
|
-
}
|
|
258
|
-
switch (request.method) {
|
|
259
|
-
case "DELETE": {
|
|
260
|
-
await repository.delete(itemId);
|
|
261
|
-
return {};
|
|
262
|
-
}
|
|
263
|
-
}
|
|
264
|
-
});
|
|
265
|
-
return {
|
|
266
|
-
loader,
|
|
267
|
-
action
|
|
268
|
-
};
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
// src/crud/crud_loader.tsx
|
|
272
|
-
function crudHandler({
|
|
273
|
-
repository,
|
|
274
|
-
apiHandlerOptions,
|
|
275
|
-
loaderOptions,
|
|
276
|
-
itemLoaderOptions
|
|
277
|
-
}) {
|
|
278
|
-
return (prefix) => async (args) => {
|
|
279
|
-
const pattern = args.unstable_pattern;
|
|
280
|
-
if (pattern === `/api${prefix}`) {
|
|
281
|
-
const { loader, action } = apiHandler({
|
|
282
|
-
repository,
|
|
283
|
-
...apiHandlerOptions
|
|
284
|
-
});
|
|
285
|
-
if (args.request.method === "GET") {
|
|
286
|
-
return loader(args);
|
|
287
|
-
} else {
|
|
288
|
-
return action(args);
|
|
289
|
-
}
|
|
290
|
-
}
|
|
291
|
-
if (pattern.startsWith(`/api${prefix}`)) {
|
|
292
|
-
const { loader, action } = itemApiHandler({
|
|
293
|
-
repository,
|
|
294
|
-
...apiHandlerOptions
|
|
295
|
-
});
|
|
296
|
-
if (args.request.method === "GET") {
|
|
297
|
-
return loader(args);
|
|
298
|
-
} else {
|
|
299
|
-
return action(args);
|
|
300
|
-
}
|
|
301
|
-
}
|
|
302
|
-
if (pattern === prefix) {
|
|
303
|
-
const body = await tableLoader({
|
|
304
|
-
...loaderOptions,
|
|
305
|
-
repository
|
|
306
|
-
})(args);
|
|
307
|
-
if (loaderOptions.loader) {
|
|
308
|
-
const result = await loaderOptions.loader(args);
|
|
309
|
-
if (typeof result === "object") {
|
|
310
|
-
return {
|
|
311
|
-
...result,
|
|
312
|
-
...body
|
|
313
|
-
};
|
|
314
|
-
}
|
|
315
|
-
}
|
|
316
|
-
return body;
|
|
317
|
-
}
|
|
318
|
-
if (pattern.startsWith(prefix)) {
|
|
319
|
-
const body = await tableItemloader({ ...itemLoaderOptions, repository })(
|
|
320
|
-
args
|
|
321
|
-
);
|
|
322
|
-
if (itemLoaderOptions.loader) {
|
|
323
|
-
const result = await itemLoaderOptions.loader(args);
|
|
324
|
-
if (typeof result === "object") {
|
|
325
|
-
return {
|
|
326
|
-
...result,
|
|
327
|
-
...body
|
|
328
|
-
};
|
|
329
|
-
}
|
|
330
|
-
}
|
|
331
|
-
return body;
|
|
332
|
-
}
|
|
333
|
-
};
|
|
334
|
-
}
|
|
335
|
-
export {
|
|
336
|
-
crudHandler
|
|
337
|
-
};
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import { FormContextProps, CrudFormProps } from './crud_form_provider.mjs';
|
|
2
|
-
import { FC, ReactNode } from 'react';
|
|
3
|
-
import { TablePageOptions } from '../table/table_form.mjs';
|
|
4
|
-
import 'react/jsx-runtime';
|
|
5
|
-
import 'react-store-input';
|
|
6
|
-
import '../table/table.mjs';
|
|
7
|
-
import '../table/use_table.mjs';
|
|
8
|
-
|
|
9
|
-
type CrudPageOptions<TModel> = {
|
|
10
|
-
name: string;
|
|
11
|
-
primaryKey: keyof TModel;
|
|
12
|
-
tablePageOptions: TablePageOptions<TModel>;
|
|
13
|
-
formOptions: {
|
|
14
|
-
form?: FC<{
|
|
15
|
-
form: FormContextProps<TModel>;
|
|
16
|
-
}>;
|
|
17
|
-
columns?: CrudFormProps<TModel>["columns"];
|
|
18
|
-
};
|
|
19
|
-
header: FC<{
|
|
20
|
-
title: string;
|
|
21
|
-
actions?: ReactNode;
|
|
22
|
-
className?: string;
|
|
23
|
-
children?: ReactNode;
|
|
24
|
-
}>;
|
|
25
|
-
};
|
|
26
|
-
type CrudPage = {
|
|
27
|
-
name: string;
|
|
28
|
-
create: (prefix: string) => FC;
|
|
29
|
-
};
|
|
30
|
-
declare function crudPage<TModel>({ name, primaryKey, tablePageOptions, formOptions, header: header, }: CrudPageOptions<TModel>): CrudPage;
|
|
31
|
-
|
|
32
|
-
export { type CrudPage, type CrudPageOptions, crudPage };
|
package/dist/crud/crud_page.d.ts
DELETED
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import { FormContextProps, CrudFormProps } from './crud_form_provider.js';
|
|
2
|
-
import { FC, ReactNode } from 'react';
|
|
3
|
-
import { TablePageOptions } from '../table/table_form.js';
|
|
4
|
-
import 'react/jsx-runtime';
|
|
5
|
-
import 'react-store-input';
|
|
6
|
-
import '../table/table.js';
|
|
7
|
-
import '../table/use_table.js';
|
|
8
|
-
|
|
9
|
-
type CrudPageOptions<TModel> = {
|
|
10
|
-
name: string;
|
|
11
|
-
primaryKey: keyof TModel;
|
|
12
|
-
tablePageOptions: TablePageOptions<TModel>;
|
|
13
|
-
formOptions: {
|
|
14
|
-
form?: FC<{
|
|
15
|
-
form: FormContextProps<TModel>;
|
|
16
|
-
}>;
|
|
17
|
-
columns?: CrudFormProps<TModel>["columns"];
|
|
18
|
-
};
|
|
19
|
-
header: FC<{
|
|
20
|
-
title: string;
|
|
21
|
-
actions?: ReactNode;
|
|
22
|
-
className?: string;
|
|
23
|
-
children?: ReactNode;
|
|
24
|
-
}>;
|
|
25
|
-
};
|
|
26
|
-
type CrudPage = {
|
|
27
|
-
name: string;
|
|
28
|
-
create: (prefix: string) => FC;
|
|
29
|
-
};
|
|
30
|
-
declare function crudPage<TModel>({ name, primaryKey, tablePageOptions, formOptions, header: header, }: CrudPageOptions<TModel>): CrudPage;
|
|
31
|
-
|
|
32
|
-
export { type CrudPage, type CrudPageOptions, crudPage };
|