create-sonamu 0.2.1 → 0.2.3

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/catalog.json CHANGED
@@ -1,5 +1,4 @@
1
1
  {
2
- "@uiw/react-json-view": "2.0.0-alpha.41",
3
2
  "@adonisjs/ace": "^13.3.0",
4
3
  "@adonisjs/tsconfig": "^1.4.1",
5
4
  "@ai-sdk/anthropic": "^3.0.0",
@@ -43,11 +42,7 @@
43
42
  "@logtape/logtape": "2.0.0",
44
43
  "@logtape/pretty": "2.0.0",
45
44
  "@logtape/redaction": "2.0.0",
46
- "@storybook/addon-a11y": "^10.2.19",
47
- "@storybook/addon-docs": "^10.2.19",
48
- "@storybook/react-vite": "^10.2.19",
49
- "agentation": "^2.3.0",
50
- "storybook": "^10.2.19",
45
+ "@oxc-project/runtime": "^0.79.0",
51
46
  "@radix-ui/react-accordion": "^1.2.12",
52
47
  "@radix-ui/react-alert-dialog": "^1.1.15",
53
48
  "@radix-ui/react-aspect-ratio": "^1.1.8",
@@ -76,6 +71,9 @@
76
71
  "@radix-ui/react-toggle-group": "^1.1.11",
77
72
  "@radix-ui/react-tooltip": "^1.2.8",
78
73
  "@sheetkit/node": "^0.5.0",
74
+ "@storybook/addon-a11y": "^10.2.19",
75
+ "@storybook/addon-docs": "^10.2.19",
76
+ "@storybook/react-vite": "^10.2.19",
79
77
  "@svgr/core": "^8.1.0",
80
78
  "@svgr/plugin-jsx": "^8.1.0",
81
79
  "@svgr/plugin-svgo": "^8.1.0",
@@ -105,13 +103,14 @@
105
103
  "@types/react-syntax-highlighter": "^15.5.13",
106
104
  "@types/supertest": "^6.0.3",
107
105
  "@typescript/native-preview": "^7.0.0-dev.20251225.1",
108
- "@oxc-project/runtime": "^0.79.0",
106
+ "@uiw/react-json-view": "2.0.0-alpha.41",
109
107
  "@vitejs/plugin-react": "6.0.1",
110
108
  "@vitest/coverage-v8": "^4.1.2",
111
109
  "@xyflow/react": "^12.9.3",
110
+ "agentation": "^2.3.0",
112
111
  "ai": "^6.0.1",
113
112
  "autoprefixer": "^10.4.20",
114
- "axios": "^1.13.2",
113
+ "axios": "^1.15.0",
115
114
  "bcrypt": "^6.0.0",
116
115
  "bentocache": "^1.5.0",
117
116
  "better-auth": "~1.6.0",
@@ -147,7 +146,7 @@
147
146
  "ioredis": "^5.8.2",
148
147
  "jotai": "^2.14.0",
149
148
  "json5": "^2.2.3",
150
- "knex": "^3.1.0",
149
+ "knex": "^3.2.9",
151
150
  "lodash-es": "^4.17.21",
152
151
  "lucide-react": "^0.462.0",
153
152
  "luxon": "^3.0.3",
@@ -159,9 +158,9 @@
159
158
  "node-sql-parser": "^5.2.0",
160
159
  "nodemon": "^3.1.10",
161
160
  "npm-run-all": "^4.1.5",
161
+ "oxc-transform": "^0.123.0",
162
162
  "oxfmt": "^0.43.0",
163
163
  "oxlint": "^1.58.0",
164
- "oxc-transform": "^0.123.0",
165
164
  "p-event": "^6.0.1",
166
165
  "p-timeout": "^6.1.4",
167
166
  "parse-imports": "^2.2.1",
@@ -192,6 +191,7 @@
192
191
  "semantic-ui-react": "^2.1.3",
193
192
  "sharp": "^0.34.5",
194
193
  "sonner": "^2.0.7",
194
+ "storybook": "^10.2.19",
195
195
  "supertest": "^7.1.1",
196
196
  "supports-color": "^10.2.2",
197
197
  "swr": "^2.3.7",
@@ -205,7 +205,7 @@
205
205
  "unplugin-icons": "0.20.2",
206
206
  "uuid": "^13.0.0",
207
207
  "vaul": "^1.1.2",
208
- "vite": "8.0.3",
208
+ "vite": "8.0.5",
209
209
  "vite-plugin-dts": "4.5.4",
210
210
  "vite-tsconfig-paths": "^5.1.4",
211
211
  "vitest": "^4.1.2",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-sonamu",
3
- "version": "0.2.1",
3
+ "version": "0.2.3",
4
4
  "description": "Create a new Sonamu project",
5
5
  "keywords": [
6
6
  "cli",
@@ -19,8 +19,7 @@
19
19
  "seed": "pnpm seedOnly && sonamu fixture sync",
20
20
  "sync:dump": "pnpm seed && pnpm sonamu migrate run && pnpm dump",
21
21
  "docker:up": "docker compose --env-file .env -f database/docker-compose.yml up -d",
22
- "docker:down": "docker compose --env-file .env -f database/docker-compose.yml down",
23
- "cdd": "cdd"
22
+ "docker:down": "docker compose --env-file .env -f database/docker-compose.yml down"
24
23
  },
25
24
  "dependencies": {
26
25
  "@ai-sdk/anthropic": "^3.0.0",
@@ -37,11 +36,10 @@
37
36
  "chalk": "^4.1.2",
38
37
  "date-fns": "^4.1.0",
39
38
  "dotenv": "^16",
40
- "knex": "^3.1.0",
39
+ "knex": "^3.2.9",
41
40
  "pg": "^8.16.3",
42
41
  "radashi": "^12.2.0",
43
- "@sonamu-kit/cdd": "workspace:^",
44
- "sonamu": "^0.9.0",
42
+ "sonamu": "^0.9.4",
45
43
  "zod": "^4.3.6"
46
44
  },
47
45
  "devDependencies": {
@@ -53,7 +51,7 @@
53
51
  "ioredis": "^5.8.2",
54
52
  "tsdown": "^0.12.5",
55
53
  "typescript": "^6.0.0",
56
- "vite": "8.0.3",
54
+ "vite": "8.0.5",
57
55
  "vitest": "^4.1.2"
58
56
  }
59
57
  }
@@ -19,8 +19,7 @@
19
19
  "seed": "pnpm seedOnly && sonamu fixture sync",
20
20
  "sync:dump": "pnpm seed && pnpm sonamu migrate run && pnpm dump",
21
21
  "docker:up": "docker compose --env-file .env -f database/docker-compose.yml up -d",
22
- "docker:down": "docker compose --env-file .env -f database/docker-compose.yml down",
23
- "cdd":"cdd"
22
+ "docker:down": "docker compose --env-file .env -f database/docker-compose.yml down"
24
23
  },
25
24
  "dependencies": {
26
25
  "@ai-sdk/anthropic": "catalog:",
@@ -40,7 +39,6 @@
40
39
  "knex": "catalog:",
41
40
  "pg": "catalog:",
42
41
  "radashi": "catalog:",
43
- "@sonamu-kit/cdd": "workspace:^",
44
42
  "sonamu": "workspace:^",
45
43
  "zod": "catalog:"
46
44
  },
@@ -10,10 +10,10 @@
10
10
  "preview": "vite preview"
11
11
  },
12
12
  "dependencies": {
13
- "@sonamu-kit/react-components": "^0.3.1",
13
+ "@sonamu-kit/react-components": "^0.4.0",
14
14
  "@tanstack/react-query": "^5.90.12",
15
15
  "@tanstack/react-router": "1.143.11",
16
- "axios": "^1.13.2",
16
+ "axios": "^1.15.0",
17
17
  "better-auth": "~1.6.0",
18
18
  "clsx": "^2.1.1",
19
19
  "dotenv": "^16",
@@ -45,6 +45,6 @@
45
45
  "tailwindcss": "^4.0.0",
46
46
  "typescript": "^6.0.0",
47
47
  "unplugin-icons": "0.20.2",
48
- "vite": "8.0.3"
48
+ "vite": "8.0.5"
49
49
  }
50
50
  }
@@ -3,18 +3,19 @@
3
3
  * 최초 1회 생성되며, 이후에는 덮어쓰지 않습니다.
4
4
  * 필요시 직접 수정할 수 있습니다.
5
5
  */
6
+
6
7
  /* oxlint-disable react-hooks/exhaustive-deps */ // shared
7
- /* oxlint-disable @typescript-eslint/no-explicit-any */ // shared
8
8
 
9
9
  /*
10
10
  fetch
11
11
  */
12
- import type { AxiosRequestConfig } from "axios";
12
+ import { type AxiosRequestConfig } from "axios";
13
13
  import axios from "axios";
14
14
  import qs from "qs";
15
15
  import { type core, z } from "zod";
16
16
  import { EventSource } from "eventsource";
17
- import { getCurrentLocale } from "../i18n/sd.generated";
17
+ import { type InfiniteData } from "@tanstack/react-query";
18
+ import { getCurrentLocale } from "@/i18n/sd.generated";
18
19
 
19
20
  // ISO 8601 및 타임존 포맷의 날짜 문자열을 Date 객체로 변환하는 reviver
20
21
  export function dateReviver(_key: string, value: any): any {
@@ -327,7 +328,7 @@ export type EventHandlers<T> = {
327
328
  [K in keyof T]: (data: T[K]) => void;
328
329
  };
329
330
 
330
- import { useEffect, useRef, useState } from "react";
331
+ import { useCallback, useEffect, useRef, useState } from "react";
331
332
 
332
333
  export function useSSEStream<T extends Record<string, any>>(
333
334
  url: string,
@@ -581,3 +582,58 @@ export function josa(word: string, type: "은는" | "이가" | "을를" | "과
581
582
 
582
583
  return word + map[type];
583
584
  }
585
+
586
+ /*
587
+ Query helpers
588
+ */
589
+ type InfinitePage<TRow> = { rows: TRow[]; total: number };
590
+ type DedupedInfiniteData<TRow> = InfiniteData<InfinitePage<TRow>> & {
591
+ rows: TRow[];
592
+ total: number;
593
+ };
594
+
595
+ // useInfiniteQuery의 select에 꽂아 pages/pageParams 원본은 유지하면서
596
+ // 평탄화된 rows와 첫 페이지의 total을 data에 함께 노출합니다.
597
+ // 각 row가 id를 갖는 경우 id 기준으로 중복 제거합니다. id가 없으면 그대로 유지합니다.
598
+ export function dedupeAndFlatten<TRow extends { id?: unknown }>(
599
+ data: InfiniteData<InfinitePage<TRow>>,
600
+ ): DedupedInfiniteData<TRow> {
601
+ const seen = new Set<unknown>();
602
+ const rows: TRow[] = [];
603
+ for (const page of data.pages) {
604
+ for (const row of page?.rows ?? []) {
605
+ const id = row?.id;
606
+ if (id != null) {
607
+ if (seen.has(id)) {
608
+ continue;
609
+ }
610
+ seen.add(id);
611
+ }
612
+ rows.push(row);
613
+ }
614
+ }
615
+ const total = data.pages[0]?.total ?? 0;
616
+ return {
617
+ pages: data.pages,
618
+ pageParams: data.pageParams,
619
+ rows,
620
+ total,
621
+ };
622
+ }
623
+
624
+ // TanStack Query 결과에 수동 refresh 진입점과 새로고침 중 상태를 덧붙여 줍니다.
625
+ // isRefreshing은 query.isFetching과 독립적으로 이 함수 호출로 발생한 새로고침에 한정됩니다.
626
+ export function useRefreshable<T extends { refetch: () => Promise<unknown> }>(
627
+ query: T,
628
+ ): T & { refresh: () => Promise<void>; isRefreshing: boolean } {
629
+ const [isRefreshing, setIsRefreshing] = useState(false);
630
+ const refresh = useCallback(async () => {
631
+ setIsRefreshing(true);
632
+ try {
633
+ await query.refetch();
634
+ } finally {
635
+ setIsRefreshing(false);
636
+ }
637
+ }, [query]);
638
+ return { ...query, refresh, isRefreshing };
639
+ }