dn-react-router-toolkit 0.7.15 → 0.8.1

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 (67) hide show
  1. package/dist/api/create_api_handler.d.mts +5 -4
  2. package/dist/api/create_api_handler.d.ts +5 -4
  3. package/dist/api/create_api_handler.js +0 -1
  4. package/dist/api/create_api_handler.mjs +0 -1
  5. package/dist/api/index.d.mts +1 -0
  6. package/dist/api/index.d.ts +1 -0
  7. package/dist/api/index.js +13 -6
  8. package/dist/api/index.mjs +14 -7
  9. package/dist/api/item_api_handler.d.mts +8 -5
  10. package/dist/api/item_api_handler.d.ts +8 -5
  11. package/dist/api/item_api_handler.js +13 -5
  12. package/dist/api/item_api_handler.mjs +14 -6
  13. package/dist/crud/crud_loader.d.mts +6 -5
  14. package/dist/crud/crud_loader.d.ts +6 -5
  15. package/dist/crud/crud_loader.js +79 -38
  16. package/dist/crud/crud_loader.mjs +81 -39
  17. package/dist/crud/crud_page.d.mts +3 -2
  18. package/dist/crud/crud_page.d.ts +3 -2
  19. package/dist/crud/crud_page.js +279 -201
  20. package/dist/crud/crud_page.mjs +277 -205
  21. package/dist/crud/generate_handlers.d.mts +3 -2
  22. package/dist/crud/generate_handlers.d.ts +3 -2
  23. package/dist/crud/generate_pages.d.mts +2 -1
  24. package/dist/crud/generate_pages.d.ts +2 -1
  25. package/dist/crud/index.d.mts +5 -3
  26. package/dist/crud/index.d.ts +5 -3
  27. package/dist/crud/index.js +338 -219
  28. package/dist/crud/index.mjs +346 -232
  29. package/dist/post/index.js +71 -64
  30. package/dist/post/index.mjs +76 -74
  31. package/dist/post/post_form_page.js +71 -64
  32. package/dist/post/post_form_page.mjs +76 -74
  33. package/dist/table/index.d.mts +7 -3
  34. package/dist/table/index.d.ts +7 -3
  35. package/dist/table/index.js +233 -111
  36. package/dist/table/index.mjs +230 -116
  37. package/dist/table/item_loader.d.mts +5 -4
  38. package/dist/table/item_loader.d.ts +5 -4
  39. package/dist/table/load_table.d.mts +36 -0
  40. package/dist/table/load_table.d.ts +36 -0
  41. package/dist/table/load_table.js +87 -0
  42. package/dist/table/load_table.mjs +66 -0
  43. package/dist/table/loader.d.mts +10 -15
  44. package/dist/table/loader.d.ts +10 -15
  45. package/dist/table/loader.js +67 -31
  46. package/dist/table/loader.mjs +67 -32
  47. package/dist/table/page.d.mts +6 -16
  48. package/dist/table/page.d.ts +6 -16
  49. package/dist/table/page.js +247 -169
  50. package/dist/table/page.mjs +248 -176
  51. package/dist/table/repository.d.mts +14 -10
  52. package/dist/table/repository.d.ts +14 -10
  53. package/dist/table/repository.js +5 -1
  54. package/dist/table/repository.mjs +5 -1
  55. package/dist/table/table.d.mts +4 -1
  56. package/dist/table/table.d.ts +4 -1
  57. package/dist/table/table.js +55 -6
  58. package/dist/table/table.mjs +55 -6
  59. package/dist/table/table_form.d.mts +13 -0
  60. package/dist/table/table_form.d.ts +13 -0
  61. package/dist/table/table_form.js +345 -0
  62. package/dist/table/table_form.mjs +320 -0
  63. package/dist/table/use_table.d.mts +4 -0
  64. package/dist/table/use_table.d.ts +4 -0
  65. package/dist/table/use_table.js +34 -0
  66. package/dist/table/use_table.mjs +9 -0
  67. package/package.json +2 -2
@@ -11,7 +11,7 @@ var BaseTableRepository = class {
11
11
  pk;
12
12
  constructor(db, schema, pk = "id") {
13
13
  this.db = db;
14
- this.schema = schema;
14
+ this.schema = db._.fullSchema[schema];
15
15
  this.pk = pk;
16
16
  }
17
17
  async find(id) {
@@ -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 select(key) {
54
+ const rows = await this.db.select({ value: this.schema[key] }).from(this.schema).groupBy(this.schema[key]);
55
+ return rows.map((row) => row.value);
56
+ }
53
57
  };
54
58
 
55
59
  // src/table/buttons.tsx
@@ -141,60 +145,92 @@ var tableItemloader = ({
141
145
  };
142
146
  };
143
147
 
144
- // src/table/loader.tsx
148
+ // src/table/load_table.tsx
145
149
  import {
146
150
  and,
151
+ eq as eq2,
147
152
  ilike
148
153
  } from "drizzle-orm";
154
+ async function loadTable({
155
+ request,
156
+ repository,
157
+ options
158
+ }) {
159
+ const searchParams = new URL(request.url).searchParams;
160
+ const { where, searchKey, defaultOrderBy, defaultDirection } = options;
161
+ const query = searchParams.get("query") ?? void 0;
162
+ const limit = Number(searchParams.get("limit") ?? "20");
163
+ const offset = Number(searchParams.get("offset") ?? "0");
164
+ const orderBy = searchParams.get("orderBy") ?? defaultOrderBy;
165
+ const direction = searchParams.get("direction") ?? defaultDirection;
166
+ const filterWhere = Object.entries(options.filters ?? {}).map(([key, value]) => {
167
+ const param = searchParams.get(key);
168
+ if (param) {
169
+ return eq2(
170
+ repository.schema[key],
171
+ decodeURIComponent(param)
172
+ );
173
+ }
174
+ return void 0;
175
+ }).filter(Boolean);
176
+ const whereClauses = and(
177
+ searchKey && query ? ilike(
178
+ repository.schema[searchKey],
179
+ `%${query}%`
180
+ ) : void 0,
181
+ ...filterWhere,
182
+ ...where ?? []
183
+ );
184
+ const total = await repository.countTotal({ where: whereClauses });
185
+ const items = await repository.findAll({
186
+ orderBy,
187
+ direction,
188
+ limit,
189
+ offset,
190
+ where: whereClauses
191
+ });
192
+ const filters = Object.fromEntries(
193
+ await Promise.all(
194
+ Object.keys(options.filters ?? {}).map(async (key) => {
195
+ const values = await repository.select(key);
196
+ return [key, values.filter(Boolean)];
197
+ })
198
+ )
199
+ );
200
+ return {
201
+ items,
202
+ total,
203
+ limit,
204
+ offset,
205
+ orderBy,
206
+ direction,
207
+ searchKey,
208
+ filters
209
+ };
210
+ }
211
+
212
+ // src/table/loader.tsx
149
213
  function tableLoader({
150
214
  repository,
151
- tableOptions
215
+ options
152
216
  }) {
153
217
  return async ({ request }) => {
154
- const searchParams = new URL(request.url).searchParams;
155
- const { where, searchKey, defaultOrderBy, defaultDirection } = tableOptions;
156
- const query = searchParams.get("query") ?? void 0;
157
- const limit = Number(searchParams.get("limit") ?? "10");
158
- const offset = Number(searchParams.get("offset") ?? "0");
159
- const orderBy = searchParams.get("orderBy") ?? defaultOrderBy;
160
- const direction = searchParams.get("direction") ?? defaultDirection;
161
- const whereClauses = and(
162
- searchKey && query ? ilike(
163
- repository.schema[searchKey],
164
- `%${query}%`
165
- ) : void 0,
166
- ...where ?? []
167
- );
168
- const total = await repository.countTotal({ where: whereClauses });
169
- const items = await repository.findAll({
170
- orderBy,
171
- direction,
172
- limit,
173
- offset,
174
- where: whereClauses
218
+ const table = await loadTable({
219
+ request,
220
+ repository,
221
+ options
175
222
  });
176
223
  return {
177
- table: {
178
- items,
179
- total,
180
- limit,
181
- offset,
182
- orderBy,
183
- direction,
184
- searchKey
185
- }
224
+ table
186
225
  };
187
226
  };
188
227
  }
189
228
 
190
229
  // src/table/page.tsx
191
- import {
192
- Link as Link3,
193
- useLoaderData,
194
- useLocation as useLocation2,
195
- useNavigate,
196
- useSearchParams as useSearchParams3
197
- } from "react-router";
230
+ import { Link as Link3, useLocation as useLocation3 } from "react-router";
231
+
232
+ // src/table/table_form.tsx
233
+ import { useLocation as useLocation2, useNavigate, useSearchParams as useSearchParams3 } from "react-router";
198
234
  import { GoSearch } from "react-icons/go";
199
235
 
200
236
  // src/table/table.tsx
@@ -211,7 +247,8 @@ function Table({
211
247
  limit,
212
248
  offset,
213
249
  orderBy,
214
- direction
250
+ direction,
251
+ filters
215
252
  }) {
216
253
  const keys = Object.entries(columns).filter((entry) => entry[1]).map(([key]) => key);
217
254
  const sortedArray = [...data];
@@ -219,7 +256,10 @@ function Table({
219
256
  return /* @__PURE__ */ jsxs2(
220
257
  "table",
221
258
  {
222
- className: cn2(className, "text-[15px] border-separate border-spacing-0"),
259
+ className: cn2(
260
+ className,
261
+ "text-[15px] border-separate border-spacing-0"
262
+ ),
223
263
  children: [
224
264
  /* @__PURE__ */ jsx2("thead", { children: /* @__PURE__ */ jsx2("tr", { children: keys.map((key) => {
225
265
  const value = columns[key];
@@ -236,8 +276,8 @@ function Table({
236
276
  "button",
237
277
  {
238
278
  className: cn2(
239
- orderBy === key ? "text-neutral-900 font-medium" : "text-neutral-500",
240
- "px-4 h-14 flex items-center w-full"
279
+ orderBy === key ? "text-gray-900 font-medium" : "text-gray-500 font-medium",
280
+ "px-4 flex items-center w-full"
241
281
  ),
242
282
  onClick: () => {
243
283
  let newDirection = "asc";
@@ -258,14 +298,59 @@ function Table({
258
298
  }
259
299
  return /* @__PURE__ */ jsx2(Fragment2, { children: reactNode });
260
300
  }
261
- return /* @__PURE__ */ jsx2("th", { className: cn2("border-y font-normal"), children: /* @__PURE__ */ jsx2(Head, {}) }, key);
301
+ const filter = filters[key];
302
+ return /* @__PURE__ */ jsxs2(
303
+ "th",
304
+ {
305
+ className: cn2(
306
+ "py-4 border-y font-normal align-top"
307
+ ),
308
+ children: [
309
+ /* @__PURE__ */ jsx2(Head, {}),
310
+ filter && /* @__PURE__ */ jsx2("div", { className: "px-3 mt-4", children: /* @__PURE__ */ jsxs2(
311
+ "select",
312
+ {
313
+ className: "w-full h-10 px-1.5 border rounded-full outline-none",
314
+ onChange: (e) => {
315
+ const value2 = e.target.value;
316
+ setSearchParams((prev) => {
317
+ if (value2) {
318
+ prev.set(
319
+ key,
320
+ encodeURIComponent(
321
+ value2
322
+ )
323
+ );
324
+ } else {
325
+ prev.delete(key);
326
+ }
327
+ return prev;
328
+ });
329
+ },
330
+ children: [
331
+ /* @__PURE__ */ jsx2("option", { value: "", children: "\uC804\uCCB4" }),
332
+ filter.map((option) => /* @__PURE__ */ jsx2(
333
+ "option",
334
+ {
335
+ value: option,
336
+ children: option
337
+ },
338
+ option
339
+ ))
340
+ ]
341
+ }
342
+ ) })
343
+ ]
344
+ },
345
+ key
346
+ );
262
347
  }) }) }),
263
348
  /* @__PURE__ */ jsxs2("tbody", { children: [
264
349
  sortedArray.length === 0 && /* @__PURE__ */ jsx2("tr", { children: /* @__PURE__ */ jsx2(
265
350
  "td",
266
351
  {
267
352
  colSpan: keys.length,
268
- className: "px-4 h-14 text-neutral-400 text-center",
353
+ className: "px-4 h-20 text-gray-400 text-center",
269
354
  children: "\uB370\uC774\uD130\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4."
270
355
  }
271
356
  ) }),
@@ -300,8 +385,97 @@ function Table({
300
385
  );
301
386
  }
302
387
 
303
- // src/table/page.tsx
388
+ // src/table/use_table.tsx
389
+ import { useLoaderData } from "react-router";
390
+ function useTable() {
391
+ const { table } = useLoaderData();
392
+ return table;
393
+ }
394
+
395
+ // src/table/table_form.tsx
304
396
  import { Fragment as Fragment3, jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
397
+ function TableForm({
398
+ columns,
399
+ primaryKey = "id"
400
+ }) {
401
+ const { pathname } = useLocation2();
402
+ const {
403
+ items,
404
+ total,
405
+ limit,
406
+ offset,
407
+ orderBy,
408
+ direction,
409
+ searchKey,
410
+ filters
411
+ } = useTable();
412
+ const navigate = useNavigate();
413
+ const search = (query) => {
414
+ const searchParams2 = new URLSearchParams(window.location.search);
415
+ searchParams2.set("query", query);
416
+ searchParams2.set("offset", "0");
417
+ navigate(`${pathname}?${searchParams2.toString()}`);
418
+ };
419
+ const [searchParams] = useSearchParams3();
420
+ return /* @__PURE__ */ jsxs3(Fragment3, { children: [
421
+ searchKey && /* @__PURE__ */ jsxs3(
422
+ "form",
423
+ {
424
+ className: "h-20 px-4 flex items-center border-t",
425
+ onSubmit: (e) => {
426
+ e.preventDefault();
427
+ const formData = new FormData(e.currentTarget);
428
+ const query = formData.get("query");
429
+ search(query);
430
+ },
431
+ children: [
432
+ /* @__PURE__ */ jsx3(
433
+ "button",
434
+ {
435
+ type: "submit",
436
+ className: "w-10 h-10 flex justify-center items-center",
437
+ children: /* @__PURE__ */ jsx3(GoSearch, { className: "text-xl mr-4" })
438
+ }
439
+ ),
440
+ /* @__PURE__ */ jsx3(
441
+ "input",
442
+ {
443
+ className: "outline-none h-full flex-1",
444
+ placeholder: "\uC5EC\uAE30\uC5D0 \uAC80\uC0C9\uD558\uC138\uC694...",
445
+ name: "query",
446
+ defaultValue: searchParams.get("query") ?? ""
447
+ }
448
+ )
449
+ ]
450
+ }
451
+ ),
452
+ /* @__PURE__ */ jsx3(
453
+ Table,
454
+ {
455
+ data: items,
456
+ columns,
457
+ getLink: primaryKey ? (item) => `${pathname}/${item[primaryKey]}` : void 0,
458
+ limit,
459
+ offset,
460
+ orderBy,
461
+ direction,
462
+ filters
463
+ }
464
+ ),
465
+ /* @__PURE__ */ jsx3(
466
+ TablePageButtons,
467
+ {
468
+ total,
469
+ limit,
470
+ offset,
471
+ MAX_PAGES_TO_SHOW: 10
472
+ }
473
+ )
474
+ ] });
475
+ }
476
+
477
+ // src/table/page.tsx
478
+ import { Fragment as Fragment4, jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
305
479
  function createTablePage({
306
480
  name,
307
481
  columns,
@@ -310,90 +484,30 @@ function createTablePage({
310
484
  return function TablePage({
311
485
  header: Header
312
486
  }) {
313
- const { pathname } = useLocation2();
314
- const { table } = useLoaderData();
315
- const { items, total, limit, offset, orderBy, direction, searchKey } = table;
316
- const navigate = useNavigate();
317
- const search = (query) => {
318
- const searchParams2 = new URLSearchParams(window.location.search);
319
- searchParams2.set("query", query);
320
- searchParams2.set("offset", "0");
321
- navigate(`${pathname}?${searchParams2.toString()}`);
322
- };
323
- const [searchParams] = useSearchParams3();
324
- return /* @__PURE__ */ jsxs3(Fragment3, { children: [
325
- /* @__PURE__ */ jsx3(
487
+ const { pathname } = useLocation3();
488
+ return /* @__PURE__ */ jsxs4(Fragment4, { children: [
489
+ /* @__PURE__ */ jsx4(
326
490
  Header,
327
491
  {
328
492
  title: name,
329
- actions: /* @__PURE__ */ jsxs3(Link3, { to: `${pathname}/new`, className: "button-primary", children: [
493
+ actions: /* @__PURE__ */ jsxs4(Link3, { to: `${pathname}/new`, className: "button-primary", children: [
330
494
  name,
331
495
  " \uCD94\uAC00"
332
496
  ] })
333
497
  }
334
498
  ),
335
- /* @__PURE__ */ jsxs3("div", { className: "max-w-7xl mx-auto w-full overflow-auto", children: [
336
- searchKey && /* @__PURE__ */ jsxs3(
337
- "form",
338
- {
339
- className: "h-18 px-4 flex items-center border-t",
340
- onSubmit: (e) => {
341
- e.preventDefault();
342
- const formData = new FormData(e.currentTarget);
343
- const query = formData.get("query");
344
- search(query);
345
- },
346
- children: [
347
- /* @__PURE__ */ jsx3(
348
- "button",
349
- {
350
- type: "submit",
351
- className: "w-10 h-10 flex justify-center items-center",
352
- children: /* @__PURE__ */ jsx3(GoSearch, { className: "text-xl mr-4" })
353
- }
354
- ),
355
- /* @__PURE__ */ jsx3(
356
- "input",
357
- {
358
- className: "outline-none h-full flex-1",
359
- placeholder: "\uC5EC\uAE30\uC5D0 \uAC80\uC0C9\uD558\uC138\uC694...",
360
- name: "query",
361
- defaultValue: searchParams.get("query") ?? ""
362
- }
363
- )
364
- ]
365
- }
366
- ),
367
- /* @__PURE__ */ jsx3(
368
- Table,
369
- {
370
- data: items,
371
- columns,
372
- getLink: primaryKey ? (item) => `${pathname}/${item[primaryKey]}` : void 0,
373
- limit,
374
- offset,
375
- orderBy,
376
- direction
377
- }
378
- ),
379
- /* @__PURE__ */ jsx3(
380
- TablePageButtons,
381
- {
382
- total,
383
- limit,
384
- offset,
385
- MAX_PAGES_TO_SHOW: 10
386
- }
387
- )
388
- ] })
499
+ /* @__PURE__ */ jsx4("div", { className: "max-w-7xl mx-auto w-full overflow-auto", children: /* @__PURE__ */ jsx4(TableForm, { columns, primaryKey }) })
389
500
  ] });
390
501
  };
391
502
  }
392
503
  export {
393
504
  BaseTableRepository,
394
505
  Table,
506
+ TableForm,
395
507
  TablePageButtons,
396
508
  createTablePage,
509
+ loadTable,
397
510
  tableItemloader,
398
- tableLoader
511
+ tableLoader,
512
+ useTable
399
513
  };
@@ -1,12 +1,13 @@
1
- import { Table } from 'drizzle-orm';
2
1
  import { TableRepository } from './repository.mjs';
3
2
  import { LoaderFunctionArgs } from 'react-router';
4
- import 'drizzle-orm/pg-core';
3
+ import { PgTableWithColumns } from 'drizzle-orm/pg-core';
4
+ import 'drizzle-orm';
5
+ import 'drizzle-orm/node-postgres';
5
6
 
6
- type TableItemLoaderOptions<T extends Table, TSelect> = {
7
+ type TableItemLoaderOptions<T extends PgTableWithColumns<any>, TSelect> = {
7
8
  repository: TableRepository<T, TSelect>;
8
9
  };
9
- declare const tableItemloader: <T extends Table, TSelect>({ repository, }: TableItemLoaderOptions<T, TSelect>) => (args: LoaderFunctionArgs) => Promise<{
10
+ declare const tableItemloader: <T extends PgTableWithColumns<any>, TSelect>({ repository, }: TableItemLoaderOptions<T, TSelect>) => (args: LoaderFunctionArgs) => Promise<{
10
11
  item: Awaited<TSelect> | undefined;
11
12
  }>;
12
13
 
@@ -1,12 +1,13 @@
1
- import { Table } from 'drizzle-orm';
2
1
  import { TableRepository } from './repository.js';
3
2
  import { LoaderFunctionArgs } from 'react-router';
4
- import 'drizzle-orm/pg-core';
3
+ import { PgTableWithColumns } from 'drizzle-orm/pg-core';
4
+ import 'drizzle-orm';
5
+ import 'drizzle-orm/node-postgres';
5
6
 
6
- type TableItemLoaderOptions<T extends Table, TSelect> = {
7
+ type TableItemLoaderOptions<T extends PgTableWithColumns<any>, TSelect> = {
7
8
  repository: TableRepository<T, TSelect>;
8
9
  };
9
- declare const tableItemloader: <T extends Table, TSelect>({ repository, }: TableItemLoaderOptions<T, TSelect>) => (args: LoaderFunctionArgs) => Promise<{
10
+ declare const tableItemloader: <T extends PgTableWithColumns<any>, TSelect>({ repository, }: TableItemLoaderOptions<T, TSelect>) => (args: LoaderFunctionArgs) => Promise<{
10
11
  item: Awaited<TSelect> | undefined;
11
12
  }>;
12
13
 
@@ -0,0 +1,36 @@
1
+ import { SQLWrapper, InferSelectModel } from 'drizzle-orm';
2
+ import { PgTableWithColumns } from 'drizzle-orm/pg-core';
3
+ import { TableRepository, ColumnOf } from './repository.mjs';
4
+ import 'drizzle-orm/node-postgres';
5
+
6
+ type TableOptions<T extends PgTableWithColumns<any>> = {
7
+ where?: SQLWrapper[];
8
+ searchKey?: ColumnOf<T>;
9
+ defaultOrderBy: keyof InferSelectModel<T>;
10
+ defaultDirection: "asc" | "desc";
11
+ filters?: {
12
+ [key in keyof InferSelectModel<T>]?: "auto";
13
+ };
14
+ };
15
+ type TableLoaderOptions<T extends PgTableWithColumns<any>, TSelect> = {
16
+ repository: TableRepository<T, TSelect>;
17
+ options: TableOptions<T>;
18
+ };
19
+ declare function loadTable<T extends PgTableWithColumns<any>, TSelect>({ request, repository, options, }: {
20
+ request: Request;
21
+ repository: TableRepository<T, TSelect>;
22
+ options: TableOptions<T>;
23
+ }): Promise<{
24
+ items: TSelect[];
25
+ total: number;
26
+ limit: number;
27
+ offset: number;
28
+ orderBy: keyof T["_"]["columns"] & string;
29
+ direction: "asc" | "desc";
30
+ searchKey: ColumnOf<T> | undefined;
31
+ filters: {
32
+ [k: string]: unknown[];
33
+ };
34
+ }>;
35
+
36
+ export { type TableLoaderOptions, loadTable };
@@ -0,0 +1,36 @@
1
+ import { SQLWrapper, InferSelectModel } from 'drizzle-orm';
2
+ import { PgTableWithColumns } from 'drizzle-orm/pg-core';
3
+ import { TableRepository, ColumnOf } from './repository.js';
4
+ import 'drizzle-orm/node-postgres';
5
+
6
+ type TableOptions<T extends PgTableWithColumns<any>> = {
7
+ where?: SQLWrapper[];
8
+ searchKey?: ColumnOf<T>;
9
+ defaultOrderBy: keyof InferSelectModel<T>;
10
+ defaultDirection: "asc" | "desc";
11
+ filters?: {
12
+ [key in keyof InferSelectModel<T>]?: "auto";
13
+ };
14
+ };
15
+ type TableLoaderOptions<T extends PgTableWithColumns<any>, TSelect> = {
16
+ repository: TableRepository<T, TSelect>;
17
+ options: TableOptions<T>;
18
+ };
19
+ declare function loadTable<T extends PgTableWithColumns<any>, TSelect>({ request, repository, options, }: {
20
+ request: Request;
21
+ repository: TableRepository<T, TSelect>;
22
+ options: TableOptions<T>;
23
+ }): Promise<{
24
+ items: TSelect[];
25
+ total: number;
26
+ limit: number;
27
+ offset: number;
28
+ orderBy: keyof T["_"]["columns"] & string;
29
+ direction: "asc" | "desc";
30
+ searchKey: ColumnOf<T> | undefined;
31
+ filters: {
32
+ [k: string]: unknown[];
33
+ };
34
+ }>;
35
+
36
+ export { type TableLoaderOptions, loadTable };
@@ -0,0 +1,87 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/table/load_table.tsx
21
+ var load_table_exports = {};
22
+ __export(load_table_exports, {
23
+ loadTable: () => loadTable
24
+ });
25
+ module.exports = __toCommonJS(load_table_exports);
26
+ var import_drizzle_orm = require("drizzle-orm");
27
+ async function loadTable({
28
+ request,
29
+ repository,
30
+ options
31
+ }) {
32
+ const searchParams = new URL(request.url).searchParams;
33
+ const { where, searchKey, defaultOrderBy, defaultDirection } = options;
34
+ const query = searchParams.get("query") ?? void 0;
35
+ const limit = Number(searchParams.get("limit") ?? "20");
36
+ const offset = Number(searchParams.get("offset") ?? "0");
37
+ const orderBy = searchParams.get("orderBy") ?? defaultOrderBy;
38
+ const direction = searchParams.get("direction") ?? defaultDirection;
39
+ const filterWhere = Object.entries(options.filters ?? {}).map(([key, value]) => {
40
+ const param = searchParams.get(key);
41
+ if (param) {
42
+ return (0, import_drizzle_orm.eq)(
43
+ repository.schema[key],
44
+ decodeURIComponent(param)
45
+ );
46
+ }
47
+ return void 0;
48
+ }).filter(Boolean);
49
+ const whereClauses = (0, import_drizzle_orm.and)(
50
+ searchKey && query ? (0, import_drizzle_orm.ilike)(
51
+ repository.schema[searchKey],
52
+ `%${query}%`
53
+ ) : void 0,
54
+ ...filterWhere,
55
+ ...where ?? []
56
+ );
57
+ const total = await repository.countTotal({ where: whereClauses });
58
+ const items = await repository.findAll({
59
+ orderBy,
60
+ direction,
61
+ limit,
62
+ offset,
63
+ where: whereClauses
64
+ });
65
+ const filters = Object.fromEntries(
66
+ await Promise.all(
67
+ Object.keys(options.filters ?? {}).map(async (key) => {
68
+ const values = await repository.select(key);
69
+ return [key, values.filter(Boolean)];
70
+ })
71
+ )
72
+ );
73
+ return {
74
+ items,
75
+ total,
76
+ limit,
77
+ offset,
78
+ orderBy,
79
+ direction,
80
+ searchKey,
81
+ filters
82
+ };
83
+ }
84
+ // Annotate the CommonJS export names for ESM import in node:
85
+ 0 && (module.exports = {
86
+ loadTable
87
+ });