sonamu 0.10.7 → 0.10.9

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 (79) hide show
  1. package/dist/api/decorators.d.ts.map +1 -1
  2. package/dist/api/decorators.js +5 -12
  3. package/dist/bin/cli.js +10 -253
  4. package/dist/database/base-model.d.ts +1 -0
  5. package/dist/database/base-model.d.ts.map +1 -1
  6. package/dist/database/base-model.js +14 -8
  7. package/dist/database/db.d.ts +2 -1
  8. package/dist/database/db.d.ts.map +1 -1
  9. package/dist/database/db.js +13 -3
  10. package/dist/database/puri-wrapper.d.ts.map +1 -1
  11. package/dist/database/puri-wrapper.js +4 -11
  12. package/dist/database/transaction-context.d.ts +8 -3
  13. package/dist/database/transaction-context.d.ts.map +1 -1
  14. package/dist/database/transaction-context.js +12 -7
  15. package/dist/migration/code-generation.js +2 -2
  16. package/dist/naite/naite-reporter.d.ts +8 -3
  17. package/dist/naite/naite-reporter.d.ts.map +1 -1
  18. package/dist/naite/naite-reporter.js +9 -4
  19. package/dist/ui-web/assets/{index-D0MHYbxl.js → index-CJf8uJYf.js} +47 -41
  20. package/dist/ui-web/assets/index-GMMIVGja.css +1 -0
  21. package/dist/ui-web/index.html +2 -2
  22. package/package.json +3 -3
  23. package/src/api/decorators.ts +11 -22
  24. package/src/bin/cli.ts +12 -375
  25. package/src/database/__tests__/transaction-scope.test.ts +227 -0
  26. package/src/database/base-model.ts +31 -6
  27. package/src/database/db.ts +17 -2
  28. package/src/database/puri-wrapper.ts +5 -22
  29. package/src/database/transaction-context.ts +14 -6
  30. package/src/migration/code-generation.ts +1 -1
  31. package/src/naite/naite-reporter.ts +8 -3
  32. package/dist/ui-web/assets/index-Dx_JX4aQ.css +0 -1
  33. package/src/skills/AGENTS.md +0 -108
  34. package/src/skills/sonamu/SKILL.md +0 -75
  35. package/src/skills/sonamu-ai-agents/SKILL.md +0 -205
  36. package/src/skills/sonamu-api/SKILL.md +0 -480
  37. package/src/skills/sonamu-auth/SKILL.md +0 -327
  38. package/src/skills/sonamu-auth/references/plugins.md +0 -310
  39. package/src/skills/sonamu-auth/references/user-id-migration-followups.md +0 -192
  40. package/src/skills/sonamu-auth/references/user-id-migration.md +0 -455
  41. package/src/skills/sonamu-config/SKILL.md +0 -203
  42. package/src/skills/sonamu-config/references/database.md +0 -452
  43. package/src/skills/sonamu-config/references/environments.md +0 -178
  44. package/src/skills/sonamu-config/references/server-options.md +0 -400
  45. package/src/skills/sonamu-entity/SKILL.md +0 -180
  46. package/src/skills/sonamu-entity/references/creation-workflow.md +0 -581
  47. package/src/skills/sonamu-entity/references/design-guides.md +0 -243
  48. package/src/skills/sonamu-entity/references/field-types.md +0 -170
  49. package/src/skills/sonamu-entity/references/relations-detail.md +0 -245
  50. package/src/skills/sonamu-entity/references/relations.md +0 -463
  51. package/src/skills/sonamu-entity/references/subset.md +0 -156
  52. package/src/skills/sonamu-fixture/SKILL.md +0 -180
  53. package/src/skills/sonamu-fixture/references/cli-usage.md +0 -439
  54. package/src/skills/sonamu-fixture/references/cone.md +0 -298
  55. package/src/skills/sonamu-frontend/SKILL.md +0 -142
  56. package/src/skills/sonamu-frontend/references/components.md +0 -323
  57. package/src/skills/sonamu-frontend/references/examples.md +0 -64
  58. package/src/skills/sonamu-frontend/references/hooks.md +0 -273
  59. package/src/skills/sonamu-frontend/references/runtime.md +0 -165
  60. package/src/skills/sonamu-frontend/references/scaffolding.md +0 -439
  61. package/src/skills/sonamu-i18n/SKILL.md +0 -287
  62. package/src/skills/sonamu-migration/SKILL.md +0 -316
  63. package/src/skills/sonamu-naite/SKILL.md +0 -266
  64. package/src/skills/sonamu-query/SKILL.md +0 -48
  65. package/src/skills/sonamu-query/references/model-patterns.md +0 -390
  66. package/src/skills/sonamu-query/references/model.md +0 -366
  67. package/src/skills/sonamu-query/references/puri.md +0 -413
  68. package/src/skills/sonamu-query/references/search.md +0 -238
  69. package/src/skills/sonamu-query/references/upsert.md +0 -324
  70. package/src/skills/sonamu-tasks/SKILL.md +0 -236
  71. package/src/skills/sonamu-testing/SKILL.md +0 -251
  72. package/src/skills/sonamu-testing/references/devrunner.md +0 -405
  73. package/src/skills/sonamu-testing/references/helpers.md +0 -185
  74. package/src/skills/sonamu-testing/references/patterns.md +0 -263
  75. package/src/skills/sonamu-testing/references/pitfalls.md +0 -588
  76. package/src/skills/sonamu-testing/references/quick-start.md +0 -285
  77. package/src/skills/sonamu-testing/references/type-safety.md +0 -172
  78. package/src/skills/sonamu-testing/references/writing-plan.md +0 -375
  79. package/src/skills/sonamu-vector/SKILL.md +0 -222
@@ -1,165 +0,0 @@
1
- # Provider, Utilities, Error Handling, SSR
2
-
3
- ## SonamuProvider
4
-
5
- Global configuration used across react-components
6
-
7
- ```typescript
8
- // App.tsx or root component
9
- import { SonamuProvider } from "@sonamu-kit/react-components/contexts";
10
- import type { SonamuFile } from "@sonamu-kit/react-components/contexts";
11
-
12
- function App() {
13
- // File uploader function (used by FileInput, useTypeForm)
14
- const uploader = async (files: File[]): Promise<SonamuFile[]> => {
15
- const formData = new FormData();
16
- files.forEach(file => formData.append("files", file));
17
-
18
- const response = await fetch("/api/upload", {
19
- method: "POST",
20
- body: formData,
21
- });
22
-
23
- return response.json();
24
- };
25
-
26
- // Authentication state (optional)
27
- const auth = {
28
- user: currentUser,
29
- loading: isLoading,
30
- login: async (params) => { /* ... */ },
31
- logout: async () => { /* ... */ },
32
- refetch: async () => { /* ... */ },
33
- };
34
-
35
- // Internationalization function (optional)
36
- const SD = (key: string) => dictionary[key] ?? key;
37
-
38
- return (
39
- <SonamuProvider uploader={uploader} auth={auth} SD={SD}>
40
- {children}
41
- </SonamuProvider>
42
- );
43
- }
44
- ```
45
-
46
- **Required Props:**
47
-
48
- - `uploader`: `(files: File[]) => Promise<SonamuFile[]>` - Used by FileInput
49
- - `auth`: Authentication state and functions (optional)
50
- - `SD`: Internationalization function (optional)
51
-
52
- ## Utility Functions
53
-
54
- ```typescript
55
- import {
56
- dateF,
57
- datetimeF,
58
- numF,
59
- hidden,
60
- arrayableToArray,
61
- sqlDateToDateString,
62
- } from "@sonamu-kit/react-components/lib";
63
-
64
- // Date formatting
65
- dateF(new Date()); // "2024-01-15"
66
- dateF("2024-01-15T10:30:00"); // "2024-01-15"
67
- datetimeF(new Date()); // "2024-01-15 10:30:00"
68
-
69
- // Number formatting
70
- numF(1234567); // "1,234,567"
71
-
72
- // Conditional hidden class
73
- <div className={hidden(isHidden)}>...</div>
74
-
75
- // SQL date → date string
76
- sqlDateToDateString("2024-01-15T10:30:00.000Z"); // "2024-01-15"
77
-
78
- // Convert to array
79
- arrayableToArray("single"); // ["single"]
80
- arrayableToArray(["a", "b"]); // ["a", "b"]
81
- arrayableToArray(undefined); // []
82
- ```
83
-
84
- ## Error Handling
85
-
86
- ```typescript
87
- import { isSonamuError } from "@/lib/sonamu.shared";
88
-
89
- try {
90
- await UserService.save([
91
- {
92
- /* ... */
93
- },
94
- ]);
95
- } catch (error) {
96
- if (isSonamuError(error)) {
97
- console.log("Status:", error.code);
98
- console.log("Message:", error.message);
99
- error.issues.forEach((issue) => {
100
- console.log(`${issue.path.join(".")}: ${issue.message}`);
101
- });
102
- }
103
- }
104
- ```
105
-
106
- ## SSR
107
-
108
- ```typescript
109
- // api/src/ssr/routes.ts
110
- import { registerSSR } from "sonamu/ssr";
111
-
112
- registerSSR({
113
- path: "/companies/:companyId",
114
- preload: (params) => [UserService.me(), CompanyService.findById("A", Number(params.companyId))],
115
- });
116
- ```
117
-
118
- ## Project Name Change
119
-
120
- After generating the project, you need to replace the "Sonamu" text in the frontend with your project name.
121
-
122
- **4 files to update:**
123
-
124
- 1. **`packages/web/index.html`** - Browser tab title
125
-
126
- ```html
127
- <title>{project-name}</title>
128
- ```
129
-
130
- 2. **`packages/web/src/routes/__root.tsx`** - TanStack Router head configuration (most important!)
131
-
132
- ```typescript
133
- head: () => ({
134
- meta: [{ title: "{project-name}" }],
135
- }),
136
- ```
137
-
138
- **Important:** If you don't update `__root.tsx`, the title will revert to "Sonamu" on HMR!
139
-
140
- 3. **`packages/web/src/routes/index.tsx`** - Main page title
141
-
142
- ```tsx
143
- <h1 className="text-2xl font-bold mb-4">Welcome to {project - name}</h1>
144
- ```
145
-
146
- 4. **`packages/web/src/components/Sidebar.tsx`** - Sidebar app name
147
-
148
- ```typescript
149
- const title = isAdmin ? "Admin" : "{project-name}";
150
- ```
151
-
152
- **How to verify:**
153
-
154
- - Check that the project name is shown in the browser tab
155
- - Confirm that the tab title does not change on file save via HMR (if it does, `__root.tsx` is missing)
156
-
157
- ---
158
-
159
- ## Rules
160
-
161
- - NEVER manually modify `services.generated.ts`
162
- - MUST specify Subset parameter when calling APIs
163
- - Use `Promise.all([...])` for parallel requests
164
-
165
- ---
@@ -1,439 +0,0 @@
1
- # Scaffolding
2
-
3
- ## CRITICAL: Required Scaffolding Items
4
-
5
- **The following 5 items must all be scaffolded for every entity:**
6
-
7
- | Item | Description |
8
- | ------------------- | ---------------------------------- |
9
- | `model` | CRUD model based on BaseModelClass |
10
- | `model_test` | Model test file |
11
- | `view_list` | List view component |
12
- | `view_search_input` | Search input component |
13
- | `view_form` | Create/edit form component |
14
-
15
- **DO NOT:** scaffold only model and model_test and skip the view-related items
16
-
17
- ## CLI Scaffold Commands
18
-
19
- All scaffold types can be generated via CLI (in addition to Sonamu UI):
20
-
21
- ```bash
22
- pnpm sonamu scaffold model <entityId>
23
- pnpm sonamu scaffold model_test <entityId>
24
- pnpm sonamu scaffold view_list <entityId>
25
- pnpm sonamu scaffold view_form <entityId>
26
- ```
27
-
28
- `model_test` generates the test file skeleton (`{entity}.model.test.ts`) with the correct imports and `bootstrap(vi)` setup. Run it from `packages/api` after the entity's types.ts and migration are ready.
29
-
30
- ---
31
-
32
- ## Pre-Scaffolding Checklist
33
-
34
- Run from the **`packages/api`** directory:
35
-
36
- 1. **Wait for entity change detection**: After creating an entity, wait for the syncer to auto-generate `types.ts` (2-3 seconds)
37
- 2. **Check types.ts file**: If not auto-generated, create it manually
38
- 3. **Create and run migration**: Create migration from Sonamu UI → `pnpm sonamu migrate run`
39
- 4. **Complete TypeScript build**: Run `pnpm build` to generate `.js` files in `dist/`
40
- 5. **Restart dev server**: `pnpm dev` (restart required after build)
41
-
42
- ## Post-Scaffolding Required Checklist
43
-
44
- **CRITICAL: After scaffolding is complete, you must perform the following steps.**
45
-
46
- ### 1. Build Test
47
-
48
- ```bash
49
- cd packages/api
50
- pnpm build
51
-
52
- cd packages/web
53
- pnpm build
54
- ```
55
-
56
- - [ ] API build succeeds
57
- - [ ] Web build succeeds
58
-
59
- ### 2. Restart Dev Server
60
-
61
- ```bash
62
- cd packages/api
63
- pnpm dev
64
- ```
65
-
66
- - [ ] Server running normally
67
-
68
- ### 3. If Relations Exist (Add i18n Keys)
69
-
70
- **Required**: Must be done if the entity has a BelongsToOne or any relation
71
-
72
- ```typescript
73
- // packages/api/src/i18n/ko.ts
74
- export default {
75
- // ... existing keys
76
-
77
- // Add for each entity with relations
78
- "entity.Post.author_id": "Author",
79
- "entity.Question.collection_id": "Collection",
80
- "entity.Question.parent_id": "Parent Question",
81
- "entity.Employee.department_id": "Department",
82
- "entity.Task.principal_investigator_id": "Principal Investigator",
83
-
84
- // ...
85
- } as const;
86
- ```
87
-
88
- **Pattern**: `entity.{EntityId}.{relation}_id`
89
-
90
- - Add `_id` suffix to the relation name
91
- - Example: `author` relation → `author_id` key
92
-
93
- - [ ] i18n keys added for all entities with relations
94
-
95
- ### 4. Add OrderBy Cases (When values other than id-desc are used)
96
-
97
- **Optional**: Perform if the OrderBy enum in entity.json has values other than `id-desc`
98
-
99
- ```typescript
100
- // packages/api/src/application/{entity}/{entity}.model.ts
101
-
102
- // Generated code
103
- if (params.orderBy === "id-desc") {
104
- qb.orderBy("posts.id", "desc");
105
- } else {
106
- exhaustive(params.orderBy); // type error!
107
- }
108
-
109
- // Fix: add the remaining cases
110
- if (params.orderBy === "id-desc") {
111
- qb.orderBy("posts.id", "desc");
112
- } else if (params.orderBy === "created_at-desc") {
113
- qb.orderBy("posts.created_at", "desc");
114
- } else if (params.orderBy === "name-asc") {
115
- qb.orderBy("posts.name", "asc");
116
- } else {
117
- exhaustive(params.orderBy); // no more type errors
118
- }
119
- ```
120
-
121
- - [ ] OrderBy cases added
122
-
123
- ### 5. Handle Nullable Fields in types.ts (Required Before Testing!)
124
-
125
- **Required**: Handle nullable fields in types.ts for all entities
126
-
127
- ```typescript
128
- // packages/api/src/application/{entity}/{entity}.types.ts
129
-
130
- // Generated code
131
- export const PostSaveParams = PostBaseSchema.partial({
132
- id: true,
133
- created_at: true,
134
- });
135
-
136
- // Fix: add nullable fields
137
- export const PostSaveParams = PostBaseSchema.partial({
138
- id: true,
139
- created_at: true,
140
- updated_at: true, // nullable field
141
- category: true, // nullable field
142
- description: true, // nullable field
143
- }).extend({
144
- updated_at: z.date().nullish(),
145
- category: z.string().nullish(),
146
- description: z.string().nullish(),
147
- });
148
- ```
149
-
150
- **Detailed guide**: See "Tasks to Do Immediately After Entity Creation" in `sonamu-testing`
151
-
152
- - [ ] Nullable fields handled in types.ts for all entities
153
-
154
- ### Completion Confirmation
155
-
156
- ```
157
- Post-scaffolding required checklist complete
158
- → Next step: write tests (`sonamu-testing`)
159
-
160
- ⚠️ If nullable fields in types.ts are not handled,
161
- type errors will occur when writing tests!
162
- ```
163
-
164
- ---
165
-
166
- ## Common Errors
167
-
168
- | Error | Cause | Fix |
169
- | ------------------------------------------- | ----------------------------------------------------- | ------------------------------------------ |
170
- | "Non-existent module path requested {Type}" | types.ts not created or not compiled | Wait/create manually → build → restart dev |
171
- | exhaustive() type error | Only the first OrderBy value is handled automatically | See "4. Add OrderBy Cases" above |
172
- | Missing i18n key (relation) | `author_id` vs `author` | See "3. If Relations Exist" above |
173
- | IdAsyncSelect API mismatch | Old scaffolding template used | See "IdAsyncSelect API Migration" below |
174
-
175
- ## Detailed Explanations
176
-
177
- ### "Non-existent module path requested" Error
178
-
179
- Scaffolding reads types exported from `dist/application/{entity}/{entity}.types.js` to register module paths.
180
-
181
- ```typescript
182
- // modules/sonamu/src/entity/entity.ts
183
- const typesFilePath = path.join(
184
- Sonamu.apiRootPath,
185
- runtimePath(`dist/application/${typesModulePath}.js`),
186
- );
187
- if (await exists(typesFilePath)) {
188
- // register type
189
- }
190
- ```
191
-
192
- ### Automatic types.ts Generation Mechanism
193
-
194
- When an entity is created, the syncer's `handleTruthSourceChanges` automatically runs the `init_types` template:
195
-
196
- ```typescript
197
- // modules/sonamu/src/syncer/syncer.ts - handleTruthSourceChanges function
198
- if (entityId) {
199
- const entity = EntityManager.get(entityId);
200
- const typeFilePath = path.join(...);
201
- if (entity.parentId === undefined && !(await exists(typeFilePath))) {
202
- await generateTemplate("init_types", { entityId });
203
- }
204
- }
205
- ```
206
-
207
- **Auto-generation conditions**:
208
-
209
- - When `parentId` is absent (top-level entity)
210
- - When the `types.ts` file does not yet exist
211
-
212
- **Causes of errors**:
213
-
214
- - Attempting scaffolding immediately after entity creation before the syncer has run
215
- - types.ts was created but the build has not completed so the `.js` file is missing
216
-
217
- **Resolution order** (run from `packages/api`):
218
-
219
- 1. Wait briefly after entity creation for the syncer to generate types.ts (2-3 seconds)
220
- 2. If types.ts is missing, create it manually (see template below)
221
- 3. Create migration (Sonamu UI) and run it (`pnpm sonamu migrate run`)
222
- 4. Compile TypeScript with `pnpm build`
223
- 5. Restart `pnpm dev`
224
- 6. Retry scaffolding
225
-
226
- ### Manual types.ts Creation (If Needed)
227
-
228
- For cases where auto-generation did not occur due to a syncer timing issue:
229
-
230
- ```typescript
231
- // {entity}.types.ts
232
- import type { z } from "zod";
233
- import { {Entity}BaseListParams, {Entity}BaseSchema } from "../sonamu.generated";
234
-
235
- // {Entity} - ListParams
236
- export const {Entity}ListParams = {Entity}BaseListParams;
237
- export type {Entity}ListParams = z.infer<typeof {Entity}ListParams>;
238
-
239
- // {Entity} - SaveParams
240
- export const {Entity}SaveParams = {Entity}BaseSchema.partial({ id: true, created_at: true });
241
- export type {Entity}SaveParams = z.infer<typeof {Entity}SaveParams>;
242
- ```
243
-
244
- **IMPORTANT: Entity with `updated_at` field**:
245
-
246
- If the entity has an `updated_at` field defined, it must also be included in the partial of SaveParams.
247
- Since the form does not accept `updated_at` as direct input, it must be optional to avoid type errors.
248
-
249
- ```typescript
250
- // For entities with updated_at
251
- export const {Entity}SaveParams = {Entity}BaseSchema.partial({
252
- id: true,
253
- created_at: true,
254
- updated_at: true // ← add this
255
- });
256
- ```
257
-
258
- ### exhaustive() Type Error
259
-
260
- `exhaustive` is a utility function provided by sonamu.
261
-
262
- ```typescript
263
- import { exhaustive } from "sonamu";
264
- ```
265
-
266
- The scaffolding template only handles the **first value** of the `OrderBy` enum automatically.
267
-
268
- ```typescript
269
- // Generated code
270
- if (params.orderBy === "id-desc") {
271
- qb.orderBy("posts.id", "desc");
272
- } else {
273
- exhaustive(params.orderBy); // remaining cases unhandled → type error
274
- }
275
- ```
276
-
277
- **Fix**: Manually add all OrderBy cases
278
-
279
- ```typescript
280
- if (params.orderBy === "id-desc") {
281
- qb.orderBy("posts.id", "desc");
282
- } else if (params.orderBy === "created_at-desc") {
283
- qb.orderBy("posts.created_at", "desc");
284
- } else {
285
- exhaustive(params.orderBy);
286
- }
287
- ```
288
-
289
- ### i18n Key Error (relation prop)
290
-
291
- An entity's relation prop is defined as `author`, and the i18n label in `sd.generated.ts` is generated as `entity.Post.author`.
292
- **However**, the scaffolded form.tsx template uses the FK column name `author_id`.
293
-
294
- ```typescript
295
- // Scaffolded form.tsx (actually generated code)
296
- {SD("entity.Post.author_id")} // ← uses _id suffix
297
-
298
- // sd.generated.ts (auto-generated keys)
299
- "entity.Post.author": "Author" // ← no _id
300
- ```
301
-
302
- **Fix (choose one)**:
303
-
304
- 1. **Manually add `_id` key to ko.ts** (recommended):
305
-
306
- ```typescript
307
- // packages/api/src/i18n/ko.ts
308
- export default {
309
- // ... existing keys
310
- "entity.Post.author_id": "Author",
311
- "entity.Question.collection_id": "Collection",
312
- "entity.Question.parent_id": "Parent Question",
313
- // ...
314
- } as const;
315
- ```
316
-
317
- 2. **Remove `_id` from form.tsx** (requires manual edit):
318
-
319
- ```typescript
320
- // Manual edit after scaffolding
321
- {
322
- SD("entity.Post.author");
323
- } // remove _id
324
- ```
325
-
326
- **Recommended**: First option - add the `_id` key to ko.ts. It is preserved during sync and can be reused across multiple forms.
327
-
328
- ### IdAsyncSelect API Migration
329
-
330
- #### Background
331
-
332
- When the `@sonamu-kit/react-components` package was updated, the IdAsyncSelect API changed, but the scaffolding generation code (`scaffolding/react-components.ts`) still generates code based on the old API.
333
-
334
- Therefore, running `pnpm sonamu scaffold` generates wrapper components based on the old API, causing build errors in projects using the latest package.
335
-
336
- #### Specific API Changes
337
-
338
- **Old API (code generated by scaffolding):**
339
-
340
- ```typescript
341
- export function UserIdAsyncSelect<T extends UserSubsetKey>({
342
- subset,
343
- value,
344
- onValueChange,
345
- listParams, // ← old API
346
- textField = "name", // ← old API
347
- pageField, // ← old API
348
- ...
349
- }: UserIdAsyncSelectProps<T>) {
350
- // manual state management
351
- const [searchText, setSearchText] = useState("");
352
-
353
- const handleSearch = useCallback((text: string) => {
354
- setSearchText(text);
355
- }, []);
356
-
357
- return (
358
- <AsyncSelect // ← old component
359
- config={UserAsyncIdConfig}
360
- subset={subset}
361
- listParams={{ ...listParams, [textField]: searchText }}
362
- textField={textField}
363
- pageField={pageField}
364
- onSearch={handleSearch}
365
- ...
366
- />
367
- );
368
- }
369
- ```
370
-
371
- **New API (actual package API):**
372
-
373
- ```typescript
374
- export function UserIdAsyncSelect<T extends UserSubsetKey>({
375
- subset,
376
- value,
377
- onValueChange,
378
- baseListParams, // ← new API
379
- displayField = "name", // ← new API
380
- // pageField removed // ← removed
381
- ...
382
- }: UserIdAsyncSelectProps<T>) {
383
- // no state management (handled internally)
384
-
385
- return (
386
- <IdAsyncSelect<number> // ← new component + generic
387
- config={UserAsyncIdConfig}
388
- subset={subset}
389
- baseListParams={baseListParams}
390
- displayField={displayField}
391
- // search handled internally
392
- ...
393
- />
394
- );
395
- }
396
- ```
397
-
398
- #### Key Changes
399
-
400
- 1. **Component name**: `AsyncSelect` → `IdAsyncSelect<T>` (generic added)
401
- 2. **Prop names**:
402
- - `listParams` → `baseListParams`
403
- - `textField` → `displayField`
404
- - `pageField` removed
405
- 3. **Search logic**: external state management → internal handling (useState, useCallback, onSearch no longer needed)
406
- 4. **Generic type**: PK type must be specified explicitly (`<number>` or `<string>`)
407
-
408
- #### Files That Need Updating
409
-
410
- ```
411
- src/components/
412
- ├── user/UserIdAsyncSelect.tsx
413
- ├── account/AccountIdAsyncSelect.tsx
414
- ├── announcement/AnnouncementIdAsyncSelect.tsx
415
- └── ... (all *IdAsyncSelect.tsx files)
416
- ```
417
-
418
- #### Migration Checklist
419
-
420
- - [ ] Change component import: `AsyncSelect` → `IdAsyncSelect`
421
- - [ ] Add generic type parameter: `<number>` or `<string>` (depending on PK type)
422
- - [ ] Update Props type definitions:
423
- - [ ] `listParams` → `baseListParams`
424
- - [ ] `textField` → `displayField`
425
- - [ ] Remove `pageField`
426
- - [ ] Remove manual state management:
427
- - [ ] Remove `useState`, `useCallback`
428
- - [ ] Remove `onSearch` handler
429
- - [ ] Update prop names in JSX:
430
- - [ ] `listParams={...}` → `baseListParams={...}`
431
- - [ ] `textField={...}` → `displayField={...}`
432
- - [ ] Remove `pageField`
433
- - [ ] Remove `onSearch`
434
-
435
- #### Why does this happen?
436
-
437
- This occurs when the scaffolding generation code in Sonamu has not been updated to reflect the latest package API, while the user has modified the local Sonamu source and the package has been updated but the scaffolding template has not.
438
-
439
- **Fix**: Manually update the generated components according to the checklist above, or update the scaffolding template in the Sonamu core to use the latest API.