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.
Files changed (53) hide show
  1. package/dist/crud/index.d.mts +0 -20
  2. package/dist/crud/index.d.ts +0 -20
  3. package/dist/crud/index.js +12 -8587
  4. package/dist/crud/index.mjs +0 -8596
  5. package/dist/post/index.js +67 -7705
  6. package/dist/post/index.mjs +54 -7718
  7. package/dist/post/post_form_page.js +67 -7705
  8. package/dist/post/post_form_page.mjs +54 -7718
  9. package/dist/table/index.d.mts +0 -2
  10. package/dist/table/index.d.ts +0 -2
  11. package/dist/table/index.js +12 -79
  12. package/dist/table/index.mjs +12 -77
  13. package/dist/table/load_table.d.mts +1 -1
  14. package/dist/table/load_table.d.ts +1 -1
  15. package/dist/table/load_table.js +2 -2
  16. package/dist/table/load_table.mjs +2 -2
  17. package/dist/table/loader.js +2 -2
  18. package/dist/table/loader.mjs +2 -2
  19. package/dist/table/table.d.mts +2 -2
  20. package/dist/table/table.d.ts +2 -2
  21. package/dist/table/table.js +6 -23
  22. package/dist/table/table.mjs +6 -23
  23. package/dist/table/table_form.js +6 -23
  24. package/dist/table/table_form.mjs +6 -23
  25. package/package.json +2 -2
  26. package/dist/crud/crud_loader.d.mts +0 -26
  27. package/dist/crud/crud_loader.d.ts +0 -26
  28. package/dist/crud/crud_loader.js +0 -351
  29. package/dist/crud/crud_loader.mjs +0 -337
  30. package/dist/crud/crud_page.d.mts +0 -32
  31. package/dist/crud/crud_page.d.ts +0 -32
  32. package/dist/crud/crud_page.js +0 -776
  33. package/dist/crud/crud_page.mjs +0 -758
  34. package/dist/crud/generate_handlers.d.mts +0 -16
  35. package/dist/crud/generate_handlers.d.ts +0 -16
  36. package/dist/crud/generate_handlers.js +0 -39
  37. package/dist/crud/generate_handlers.mjs +0 -14
  38. package/dist/crud/generate_pages.d.mts +0 -19
  39. package/dist/crud/generate_pages.d.ts +0 -19
  40. package/dist/crud/generate_pages.js +0 -55
  41. package/dist/crud/generate_pages.mjs +0 -30
  42. package/dist/crud/generate_routes.d.mts +0 -5
  43. package/dist/crud/generate_routes.d.ts +0 -5
  44. package/dist/crud/generate_routes.js +0 -7639
  45. package/dist/crud/generate_routes.mjs +0 -7627
  46. package/dist/table/item_loader.d.mts +0 -14
  47. package/dist/table/item_loader.d.ts +0 -14
  48. package/dist/table/item_loader.js +0 -43
  49. package/dist/table/item_loader.mjs +0 -18
  50. package/dist/table/page.d.mts +0 -16
  51. package/dist/table/page.d.ts +0 -16
  52. package/dist/table/page.js +0 -375
  53. 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 };
@@ -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 };