@akanjs/cli 0.9.60-canary.8 → 1.0.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 (26) hide show
  1. package/cjs/index.js +16 -47
  2. package/cjs/src/guidelines/scalarConstant/scalarConstant.generate.json +24 -20
  3. package/cjs/src/guidelines/scalarConstant/scalarConstant.instruction.md +284 -326
  4. package/cjs/src/guidelines/scalarDictionary/scalarDictionary.generate.json +32 -32
  5. package/cjs/src/guidelines/scalarDictionary/scalarDictionary.instruction.md +175 -249
  6. package/cjs/src/templates/app/app/[lang]/page.js +19 -36
  7. package/cjs/src/templates/workspaceRoot/package.json.template +5 -5
  8. package/esm/index.js +16 -47
  9. package/esm/src/guidelines/scalarConstant/scalarConstant.generate.json +24 -20
  10. package/esm/src/guidelines/scalarConstant/scalarConstant.instruction.md +284 -326
  11. package/esm/src/guidelines/scalarDictionary/scalarDictionary.generate.json +32 -32
  12. package/esm/src/guidelines/scalarDictionary/scalarDictionary.instruction.md +175 -249
  13. package/esm/src/templates/app/app/[lang]/page.js +19 -36
  14. package/esm/src/templates/workspaceRoot/package.json.template +5 -5
  15. package/package.json +5 -4
  16. package/src/guidelines/scalarConstant/scalarConstant.instruction.md +284 -326
  17. package/src/guidelines/scalarDictionary/scalarDictionary.instruction.md +175 -249
  18. package/src/library/library.command.d.ts +0 -2
  19. package/src/library/library.runner.d.ts +0 -2
  20. package/src/library/library.script.d.ts +0 -2
  21. package/src/scalar/scalar.command.d.ts +1 -1
  22. package/cjs/src/guidelines/fieldDecorator/fieldDecorator.generate.json +0 -135
  23. package/cjs/src/guidelines/fieldDecorator/fieldDecorator.instruction.md +0 -606
  24. package/esm/src/guidelines/fieldDecorator/fieldDecorator.generate.json +0 -135
  25. package/esm/src/guidelines/fieldDecorator/fieldDecorator.instruction.md +0 -606
  26. package/src/guidelines/fieldDecorator/fieldDecorator.instruction.md +0 -606
@@ -2,6 +2,11 @@
2
2
  "title": "Scalar Dictionary",
3
3
  "description": "How to create and maintain scalar.dictionary.ts files in Akan.js",
4
4
  "scans": [
5
+ {
6
+ "type": "source",
7
+ "description": "scalarDictionary builder function implementation",
8
+ "path": "pkgs/@akanjs/dictionary/src/scalarDictionary.ts"
9
+ },
5
10
  {
6
11
  "type": "source",
7
12
  "description": "Translation types and interfaces",
@@ -9,7 +14,7 @@
9
14
  },
10
15
  {
11
16
  "type": "source",
12
- "description": "ModelDictionary type definition",
17
+ "description": "Dictionary exports and types",
13
18
  "path": "pkgs/@akanjs/dictionary/src/index.ts"
14
19
  },
15
20
  {
@@ -23,16 +28,9 @@
23
28
  "type": "example",
24
29
  "description": "Scalar dictionaries with enum translations",
25
30
  "path": "{apps,libs}/**/lib/__scalar/*/*.dictionary.ts",
26
- "query": "/enum-.*:/",
31
+ "query": "/\\.enum</",
27
32
  "sample": 3
28
33
  },
29
- {
30
- "type": "example",
31
- "description": "Scalar dictionaries with section separators",
32
- "path": "{apps,libs}/**/lib/__scalar/*/*.dictionary.ts",
33
- "query": "/={10,}/",
34
- "sample": 2
35
- },
36
34
  {
37
35
  "type": "example",
38
36
  "description": "Complete scalar dictionary with field and enum translations",
@@ -42,9 +40,9 @@
42
40
  },
43
41
  {
44
42
  "type": "example",
45
- "description": "Best practice examples with organized structure",
43
+ "description": "Scalar dictionaries with multiple enums",
46
44
  "path": "{apps,libs}/**/lib/__scalar/*/*.dictionary.ts",
47
- "query": "/\\*\\s+=+\\s+Model\\s+=+\\s+\\*/",
45
+ "query": "/\\.enum<.*\\.enum</",
48
46
  "sample": 2
49
47
  }
50
48
  ],
@@ -52,31 +50,33 @@
52
50
  "filePath": "./scalarDictionary.instruction.md",
53
51
  "contents": [
54
52
  "Purpose of scalar dictionary files",
55
- "Structure and naming conventions",
56
- "Required model metadata translations",
57
- "Field translation patterns",
58
- "Enum translation patterns",
59
- "Custom translation patterns",
60
- "Section organization with comment separators",
61
- "Type safety with satisfies ModelDictionary",
62
- "Validation rules and checklist",
53
+ "File structure and naming conventions",
54
+ "Required imports from @akanjs/dictionary",
55
+ "scalarDictionary() builder pattern",
56
+ "Builder methods: .of(), .model<T>(), .enum<T>()",
57
+ "Translation format with t() function and .desc() method",
58
+ "Type imports from constant file using import type",
59
+ "Enum name matching with enumOf() name",
60
+ "Type safety through generic parameters",
63
61
  "Common mistakes and fixes",
64
- "Best practices for organization",
65
- "Full example with all translation types"
62
+ "Best practices for translations",
63
+ "Implementation checklist",
64
+ "Full examples with multiple enums"
66
65
  ],
67
66
  "rules": [
68
- "Do not remove or change comment separator lines using asterisks and equals signs (e.g., /* ==================== Model ==================== */)",
69
- "Always add field descriptions immediately after the field translations using the desc- prefix",
70
- "Always add enum descriptions immediately after enum translations using the enumdesc- prefix",
67
+ "Import scalarDictionary from '@akanjs/dictionary'",
68
+ "Import types from constant file using 'import type' syntax",
69
+ "Initialize with language order array: scalarDictionary(['en', 'ko'])",
70
+ "Use .of() method to define scalar name and description",
71
+ "Use .model<Type>() method with generic to define field translations",
72
+ "Use .enum<Type>('enumName', ...) method to define enum translations",
73
+ "The enum name string in .enum() must exactly match the first argument of enumOf() in constant file",
74
+ "Always chain .desc() after t() to provide descriptions: t([...]).desc([...])",
71
75
  "Use exactly two string elements in translation arrays: [English, Korean]",
72
- "Always include modelName and modelDesc as the first translations in the file",
73
- "Keep field translations grouped together, followed by enum translations",
74
- "Scalar dictionaries should only contain model field and enum translations, not query filters or API arguments",
75
- "Use the satisfies ModelDictionary<YourType> syntax to ensure type safety",
76
- "Always use camelCase for field names, exactly matching the constant file",
77
- "Follow the exact format enum-fieldName-enumValue for enum translations",
78
- "Group translations by sections with comment separators for better readability",
79
- "Use proper naming: myScalarDictionary for the exported constant (matching the model name)"
76
+ "Export as 'dictionary': export const dictionary = scalarDictionary(...)...",
77
+ "Use type generics (.model<Type>, .enum<Type>) for TypeScript validation",
78
+ "Provide meaningful descriptions that explain purpose, not just repeat labels",
79
+ "Match language order consistently across all dictionaries in the project"
80
80
  ]
81
81
  },
82
82
  "page": "/[lang]/akanjs/(docs)/docs/scalar/dictionary/page.tsx"
@@ -4,7 +4,7 @@
4
4
 
5
5
  Scalar dictionary files in Akan.js provide internationalization (i18n) support by:
6
6
 
7
- - Defining translations for model names, fields, and enum values
7
+ - Defining translations for scalar names, fields, and enum values
8
8
  - Supporting multiple languages (primarily English and Korean)
9
9
  - Enabling consistent terminology across the application
10
10
  - Providing field descriptions for documentation and tooltips
@@ -18,330 +18,256 @@ Scalar dictionary files in Akan.js provide internationalization (i18n) support b
18
18
  ```
19
19
  {app,lib}/
20
20
  └── */lib/__scalar/
21
- └── <scalarName>/ // camelCase directory
22
- ├── <scalarName>.constant.ts // model definition
23
- └── <scalarName>.dictionary.ts // translations
21
+ └── <scalarName>/ # camelCase directory
22
+ ├── <scalarName>.constant.ts # scalar definition
23
+ └── <scalarName>.dictionary.ts # translations
24
24
  ```
25
25
 
26
- ### Basic Structure
26
+ ### Key Benefits
27
27
 
28
- ```typescript
29
- import { ModelDictionary } from "@akanjs/dictionary";
30
- import type { YourModel } from "./your-model.constant";
31
-
32
- const modelDictionary = {
33
- // Required model metadata
34
- modelName: ["Model Name", "모델 이름"],
35
- modelDesc: ["Model description", "모델 설명"],
36
-
37
- // Field translations with descriptions
38
- fieldName: ["Field Label", "필드 라벨"],
39
- "desc-fieldName": ["Field description", "필드 설명"],
40
-
41
- // Enum translations with descriptions
42
- "enum-status-active": ["Active", "활성"],
43
- "enumdesc-status-active": ["Active status", "활성 상태"],
44
- } satisfies ModelDictionary<YourModel>;
45
-
46
- export const yourModelDictionary = modelDictionary;
47
- ```
28
+ - End-to-end type safety
29
+ - Fluent builder pattern
30
+ - Automatic validation via generics
31
+ - Multi-language support
48
32
 
49
33
  ## Required Imports
50
34
 
51
35
  ```typescript
52
- import { ModelDictionary } from "@akanjs/dictionary";
53
- import type { YourModel } from "./your-model.constant";
54
- ```
55
-
56
- ## Translation Patterns
36
+ import { scalarDictionary } from "@akanjs/dictionary";
57
37
 
58
- ### 1. Model Metadata (Required)
59
-
60
- Every scalar dictionary must include these two translations at the beginning:
61
-
62
- ```typescript
63
- modelName: ["User", "사용자"], // Short display name
64
- modelDesc: ["User account", "사용자 계정"], // Longer description
38
+ // Import types using "import type" for cleaner code
39
+ import type { YourScalar, YourEnum } from "./yourScalar.constant";
65
40
  ```
66
41
 
67
- ### 2. Field Translations
42
+ ## Scalar Dictionary Builder
68
43
 
69
- Each field from the constant file must have both a label and description:
44
+ The `scalarDictionary()` function creates a type-safe dictionary using a fluent builder pattern.
70
45
 
71
- ```typescript
72
- // Field label
73
- username: ["Username", "사용자명"],
46
+ ### Builder Methods
74
47
 
75
- // Field description (must follow immediately after the field)
76
- "desc-username": ["User's login name", "로그인에 사용하는 이름"],
77
- ```
48
+ | Method | Description | Example |
49
+ | ---------------------------- | -------------------------------- | -------------------------------------------------------------------------- |
50
+ | `.of((t) => ...)` | Define scalar name & description | `.of((t) => t(["Scalar Name", "스칼라 이름"]).desc(["Desc", "설명"]))` |
51
+ | `.model<T>((t) => ...)` | Define field translations | `.model<YourScalar>((t) => ({ fieldName: t(["Label", "레이블"]) }))` |
52
+ | `.enum<T>(name, (t) => ...)` | Define enum value translations | `.enum<YourEnum>("enumName", (t) => ({ value1: t(["Label", "레이블"]) }))` |
78
53
 
79
- ### 3. Enum Value Translations
54
+ ## Translation Format
80
55
 
81
- Each enum value must have both a label and description:
56
+ Each translation uses the `t()` function with an array of values. The array order matches the language order defined in `scalarDictionary()`.
82
57
 
83
58
  ```typescript
84
- // Enum value label
85
- "enum-status-active": ["Active", "활성"],
59
+ // Language order: ["en", "ko"]
60
+ // Index 0 = English, Index 1 = Korean
86
61
 
87
- // Enum value description (must follow immediately)
88
- "enumdesc-status-active": ["Account is active", "계정이 활성화됨"],
62
+ t(["English Label", "한국어 레이블"]).desc(["English description", "한국어 설명"]);
89
63
  ```
90
64
 
91
- ### 4. Custom Translations (Optional)
92
-
93
- Additional translations specific to this model but not tied to fields:
65
+ ### Translation Methods
94
66
 
95
- ```typescript
96
- userProfileTitle: ["User Profile", "사용자 프로필"],
97
- ```
67
+ | Method | Purpose | Example |
68
+ | -------------- | ---------------------- | ---------------------------------------- |
69
+ | `t([...])` | Define the label/name | `t(["Status", "상태"])` |
70
+ | `.desc([...])` | Define the description | `.desc(["Current status", "현재 상태"])` |
98
71
 
99
- ## Section Organization
72
+ > **Note**: Both label and description are required for complete internationalization support.
100
73
 
101
- Use comment separators to organize your translations:
74
+ ## Basic Structure
102
75
 
103
76
  ```typescript
104
- // * ==================== Model ==================== * //
105
- username: ["Username", "사용자명"],
106
- "desc-username": ["User's login name", "로그인에 사용하는 이름"],
107
- // * ==================== Model ==================== * //
108
-
109
- // * ==================== Enums ==================== * //
110
- "enum-status-active": ["Active", "활성"],
111
- "enumdesc-status-active": ["Account is active", "계정이 활성화됨"],
112
- // * ==================== Enums ==================== * //
113
-
114
- // * ==================== Custom ==================== * //
115
- userProfileTitle: ["User Profile", "사용자 프로필"],
116
- // * ==================== Custom ==================== * //
77
+ import { scalarDictionary } from "@akanjs/dictionary";
78
+ import type { YourScalar, YourEnum } from "./yourScalar.constant";
79
+
80
+ export const dictionary = scalarDictionary(["en", "ko"])
81
+ .of((t) => t(["Scalar Name", "스칼라 이름"]).desc(["Scalar description", "스칼라 설명"]))
82
+ .model<YourScalar>((t) => ({
83
+ fieldName: t(["Field Label", "필드 레이블"]).desc(["Field description", "필드 설명"]),
84
+ }))
85
+ .enum<YourEnum>("enumName", (t) => ({
86
+ value1: t(["Value Label", "값 레이블"]).desc(["Value description", "값 설명"]),
87
+ }));
117
88
  ```
118
89
 
119
- ## Type Safety
120
-
121
- Always use the `satisfies` operator with `ModelDictionary<YourModel>` to ensure:
122
-
123
- 1. All required fields from the model are translated
124
- 2. Field names match exactly
125
- 3. Typescript will catch typos and missing fields
90
+ ## Complete Example
126
91
 
127
92
  ```typescript
128
- } satisfies ModelDictionary<YourModel>; // Type safety check
93
+ // File: libs/payment/lib/__scalar/price/price.dictionary.ts
94
+ import { scalarDictionary } from "@akanjs/dictionary";
95
+ import type { Currency, Price } from "./price.constant";
96
+
97
+ export const dictionary = scalarDictionary(["en", "ko"])
98
+ .of((t) => t(["Price", "가격"]).desc(["Price information", "가격 정보"]))
99
+ .model<Price>((t) => ({
100
+ amount: t(["Amount", "금액"]).desc(["Price amount", "가격 금액"]),
101
+ currency: t(["Currency", "통화"]).desc(["Currency type", "통화 유형"]),
102
+ }))
103
+ .enum<Currency>("currency", (t) => ({
104
+ usd: t(["USD", "달러"]).desc(["US Dollar", "미국 달러"]),
105
+ krw: t(["KRW", "원"]).desc(["Korean Won", "한국 원"]),
106
+ eur: t(["EUR", "유로"]).desc(["Euro", "유로"]),
107
+ }));
129
108
  ```
130
109
 
131
- ## Validation Rules and Checklist
132
-
133
- ### Required Elements
134
-
135
- - [ ] Import `ModelDictionary` from `@akanjs/dictionary`
136
- - [ ] Import the model type from the constant file
137
- - [ ] Include `modelName` and `modelDesc` translations
138
- - [ ] Translate all fields from the model
139
- - [ ] Add descriptions for all fields with `desc-` prefix
140
- - [ ] Translate all enum values with `enum-field-value` pattern
141
- - [ ] Add descriptions for all enum values with `enumdesc-` prefix
142
- - [ ] Use `satisfies ModelDictionary<YourModel>` for type checking
143
- - [ ] Export with the correct naming convention
144
-
145
- ### Translation Arrays
146
-
147
- - [ ] Each translation is a tuple with exactly two elements
148
- - [ ] First element is English translation
149
- - [ ] Second element is Korean translation
150
- - [ ] No trailing punctuation in translations
151
- - [ ] First letter capitalized in English
152
-
153
- ### Organization
110
+ ## Enum Name Matching
154
111
 
155
- - [ ] Group fields with their descriptions
156
- - [ ] Group enum values with their descriptions
157
- - [ ] Use standard comment separators
158
- - [ ] Place model metadata first, then fields, then enums
112
+ The first argument to `.enum()` must match the name used in `enumOf()` from the constant file. This ensures proper type checking and runtime resolution.
159
113
 
160
- ## Common Mistakes and Fixes
114
+ ### Example
161
115
 
162
- ### 1. Missing Field Description
116
+ **constant.ts**:
163
117
 
164
118
  ```typescript
165
- // Wrong (missing description)
166
- username: ["Username", "사용자명"],
167
-
168
- // ✅ Correct
169
- username: ["Username", "사용자명"],
170
- "desc-username": ["User's login name", "로그인에 사용하는 이름"],
119
+ export class Currency extends enumOf("currency", ["usd", "krw", "eur"]) {}
171
120
  ```
172
121
 
173
- ### 2. Incorrect Enum Naming Pattern
122
+ **dictionary.ts**:
174
123
 
175
124
  ```typescript
176
- // Wrong (incorrect format)
177
- "enum_status_active": ["Active", "활성"],
178
- // or
179
- "enumStatus-active": ["Active", "활성"],
180
-
181
- // ✅ Correct
182
- "enum-status-active": ["Active", "활성"],
183
- "enumdesc-status-active": ["Account is active", "계정이 활성화됨"],
125
+ // Must match: "currency"
126
+ .enum<Currency>("currency", (t) => ({
127
+ usd: t(["USD", "달러"]).desc(["US Dollar", "미국 달러"]),
128
+ krw: t(["KRW", "원"]).desc(["Korean Won", "한국 원"]),
129
+ eur: t(["EUR", "유로"]).desc(["Euro", "유로"]),
130
+ }))
184
131
  ```
185
132
 
186
- ### 3. Missing Model Metadata
187
-
188
- ```typescript
189
- // ❌ Wrong (missing required metadata)
190
- const modelDictionary = {
191
- username: ["Username", "사용자명"],
192
- // ...
133
+ > **Important**: The enum name string must exactly match the first argument of `enumOf()`. For example, `enumOf("journey", [...])` requires `.enum<Journey>("journey", ...)`.
193
134
 
194
- // Correct
195
- const modelDictionary = {
196
- modelName: ["User", "사용자"],
197
- modelDesc: ["User account", "사용자 계정"],
198
- username: ["Username", "사용자명"],
199
- // ...
200
- ```
135
+ ## Type Imports
201
136
 
202
- ### 4. Incorrect Translation Array Format
137
+ Always import types from the constant file to ensure type safety. The generic parameters enforce that all fields and enum values have translations.
203
138
 
204
139
  ```typescript
205
- // Wrong (single string, not a tuple)
206
- username: "Username",
207
- // or
208
- username: ["Username"],
209
-
210
- // Correct
211
- username: ["Username", "사용자명"],
140
+ import { scalarDictionary } from "@akanjs/dictionary";
141
+
142
+ // Import types using "import type" for cleaner code
143
+ import type { EncourageInfo, Inquiry, Journey } from "./encourageInfo.constant";
144
+
145
+ export const dictionary = scalarDictionary(["en", "ko"])
146
+ .of((t) => t(["Encourage Info", "격려 정보"]).desc(["Encouragement information", "격려 정보"]))
147
+ .model<EncourageInfo>((t) => ({
148
+ // TypeScript ensures all fields of EncourageInfo are defined
149
+ }))
150
+ .enum<Journey>("journey", (t) => ({
151
+ // TypeScript ensures all values of Journey enum are defined
152
+ }))
153
+ .enum<Inquiry>("inquiry", (t) => ({
154
+ // TypeScript ensures all values of Inquiry enum are defined
155
+ }));
212
156
  ```
213
157
 
214
- ### 5. Missing Type Safety
158
+ ### Type Safety Benefits
215
159
 
216
- ```typescript
217
- // Wrong (no type checking)
218
- export const userDictionary = modelDictionary;
160
+ - **`import type`**: Use `import type` for type-only imports. This ensures no runtime code is included.
161
+ - **`.model<Type>`**: Provides autocomplete for field names and validates that all fields are translated.
162
+ - **`.enum<Type>`**: Provides autocomplete for enum values and validates that all values are translated.
219
163
 
220
- // Correct
221
- const modelDictionary = {
222
- // ...
223
- } satisfies ModelDictionary<User>;
164
+ ## Common Mistakes and Fixes
224
165
 
225
- export const userDictionary = modelDictionary;
226
- ```
166
+ | Issue | Wrong ❌ | Correct ✅ |
167
+ | ----------------- | -------------------------------- | ----------------------------------------------- |
168
+ | Missing .desc() | `t(["Label", "레이블"])` | `t(["Label", "레이블"]).desc(["Desc", "설명"])` |
169
+ | Wrong enum name | `.enum<Journey>("Journey", ...)` | `.enum<Journey>("journey", ...)` |
170
+ | Missing export | `const dictionary = ...` | `export const dictionary = ...` |
171
+ | Wrong array order | `t(["한국어", "English"])` | `t(["English", "한국어"])` |
172
+ | Missing field | (TypeScript error) | All fields defined |
227
173
 
228
174
  ## Best Practices
229
175
 
230
- ### 1. Order Translations Logically
176
+ ### 1. Always Use Type Generics
231
177
 
232
- ```typescript
233
- // First: model metadata
234
- modelName: ["User", "사용자"],
235
- modelDesc: ["User account", "사용자 계정"],
178
+ Use `.model<Type>` and `.enum<Type>` to ensure TypeScript validates all fields and values are translated.
236
179
 
237
- // Second: fields with descriptions
238
- username: ["Username", "사용자명"],
239
- "desc-username": ["User's login name", "로그인에 사용하는 이름"],
180
+ ### 2. Consistent Language Order
240
181
 
241
- // Third: enum values with descriptions
242
- "enum-status-active": ["Active", "활성"],
243
- "enumdesc-status-active": ["Account is active", "계정이 활성화됨"],
182
+ Always use the same language order (e.g., `["en", "ko"]`) across all dictionaries in your project.
244
183
 
245
- // Last: custom translations
246
- profileHeading: ["Profile Details", "프로필 상세정보"],
247
- ```
184
+ ### 3. Meaningful Descriptions
248
185
 
249
- ### 2. Use Clear Comment Separators
186
+ Provide helpful descriptions that explain the field's purpose, not just repeat the label.
250
187
 
251
188
  ```typescript
252
- // * ==================== Model ==================== * //
253
- // Fields go here
254
- // * ==================== Model ==================== * //
255
-
256
- // * ==================== Enums ==================== * //
257
- // Enum translations go here
258
- // * ==================== Enums ==================== * //
189
+ // Bad - description just repeats the label
190
+ amount: t(["Amount", "금액"]).desc(["Amount", "금액"]),
259
191
 
260
- // * ==================== Custom ==================== * //
261
- // Custom translations go here
262
- // * ==================== Custom ==================== * //
192
+ // Good - description explains the purpose
193
+ amount: t(["Amount", "금액"]).desc(["Price amount in selected currency", "선택된 통화의 가격 금액"]),
263
194
  ```
264
195
 
265
- ### 3. Match Constant File Structure
266
-
267
- Follow the same field order as in the constant file for easier maintenance.
268
-
269
- ### 4. Naming Conventions
196
+ ### 4. Export as 'dictionary'
270
197
 
271
- - Export name should match model name: `userDictionary` for `User` model
272
- - Field names must exactly match the constant file
273
- - Use kebab-case for prefix separators: `desc-`, `enum-`, `enumdesc-`
274
-
275
- ### 5. Consistent Translation Style
276
-
277
- - First letter capitalized for English
278
- - No trailing punctuation
279
- - Keep translations concise but clear
280
- - Be consistent in terminology
281
-
282
- ## Full Example
198
+ Use the standard export name `dictionary` for consistency with the framework's auto-import system.
283
199
 
284
200
  ```typescript
285
- // File: apps/example/lib/__scalar/user/user.dictionary.ts
286
- import { ModelDictionary } from "@akanjs/dictionary";
287
- import type { User } from "./user.constant";
288
-
289
- const modelDictionary = {
290
- modelName: ["User", "사용자"],
291
- modelDesc: ["System user account", "시스템 사용자 계정"],
292
-
293
- // * ==================== Model ==================== * //
294
- username: ["Username", "사용자명"],
295
- "desc-username": ["Unique login identifier", "고유 로그인 식별자"],
296
-
297
- email: ["Email", "이메일"],
298
- "desc-email": ["Contact email address", "연락용 이메일 주소"],
201
+ // Correct
202
+ export const dictionary = scalarDictionary(["en", "ko"])...
203
+ ```
299
204
 
300
- displayName: ["Display Name", "표시 이름"],
301
- "desc-displayName": ["Public name shown to others", "다른 사용자에게 표시되는 이름"],
205
+ ## Implementation Checklist
302
206
 
303
- status: ["Status", "상태"],
304
- "desc-status": ["Account status", "계정 상태"],
207
+ ### Required Elements
305
208
 
306
- lastLoginAt: ["Last Login", "마지막 로그인"],
307
- "desc-lastLoginAt": ["Most recent login time", "가장 최근 로그인 시간"],
308
- // * ==================== Model ==================== * //
209
+ - [ ] File location: `__scalar/<name>/<name>.dictionary.ts`
210
+ - [ ] Import `scalarDictionary` from `@akanjs/dictionary`
211
+ - [ ] Import types from constant file using `import type`
212
+ - [ ] Initialize with correct language order: `["en", "ko"]`
213
+ - [ ] Define scalar name/description with `.of()`
214
+ - [ ] Define all field translations with `.model<Type>()`
215
+ - [ ] Define all enum translations with `.enum<Type>(name)`
216
+ - [ ] Ensure enum name matches `enumOf()` name
217
+ - [ ] Include both label and description for all entries
218
+ - [ ] Export as `dictionary`
309
219
 
310
- // * ==================== Enums ==================== * //
311
- "enum-status-active": ["Active", "활성"],
312
- "enumdesc-status-active": ["Account is enabled and usable", "계정이 활성화되어 사용 가능함"],
220
+ ### Translation Format
313
221
 
314
- "enum-status-inactive": ["Inactive", "비활성"],
315
- "enumdesc-status-inactive": ["Account is temporarily disabled", "계정이 일시적으로 비활성화됨"],
222
+ - [ ] Each translation uses `t([...]).desc([...])`
223
+ - [ ] First element is English translation
224
+ - [ ] Second element is Korean translation
225
+ - [ ] No trailing punctuation in translations
226
+ - [ ] First letter capitalized in English
316
227
 
317
- "enum-status-banned": ["Banned", "차단됨"],
318
- "enumdesc-status-banned": ["Account is permanently disabled", "계정이 영구적으로 비활성화됨"],
228
+ ## Full Example with Multiple Enums
319
229
 
320
- "enum-status-pending": ["Pending", "대기 중"],
321
- "enumdesc-status-pending": ["Account awaiting verification", "계정 인증 대기 중"],
322
- // * ==================== Enums ==================== * //
230
+ ```typescript
231
+ // File: apps/example/lib/__scalar/encourageInfo/encourageInfo.dictionary.ts
232
+ import { scalarDictionary } from "@akanjs/dictionary";
233
+ import type { EncourageInfo, Inquiry, Journey } from "./encourageInfo.constant";
234
+
235
+ export const dictionary = scalarDictionary(["en", "ko"])
236
+ .of((t) => t(["Encourage Info", "격려 정보"]).desc(["User encouragement settings", "사용자 격려 설정"]))
237
+ .model<EncourageInfo>((t) => ({
238
+ journey: t(["Journey", "여정"]).desc(["User journey stage", "사용자 여정 단계"]),
239
+ inquiry: t(["Inquiry", "문의"]).desc(["Inquiry type", "문의 유형"]),
240
+ message: t(["Message", "메시지"]).desc(["Encouragement message", "격려 메시지"]),
241
+ showAt: t(["Show At", "표시 시간"]).desc(["When to show encouragement", "격려 표시 시점"]),
242
+ }))
243
+ .enum<Journey>("journey", (t) => ({
244
+ firstJoin: t(["First Join", "첫 가입"]).desc(["User just joined", "사용자가 방금 가입함"]),
245
+ waitPay: t(["Waiting Payment", "결제 대기"]).desc(["Awaiting payment", "결제 대기 중"]),
246
+ onProgress: t(["In Progress", "진행 중"]).desc(["Currently active", "현재 진행 중"]),
247
+ completed: t(["Completed", "완료됨"]).desc(["Journey completed", "여정 완료"]),
248
+ }))
249
+ .enum<Inquiry>("inquiry", (t) => ({
250
+ general: t(["General", "일반"]).desc(["General inquiry", "일반 문의"]),
251
+ support: t(["Support", "지원"]).desc(["Technical support", "기술 지원"]),
252
+ billing: t(["Billing", "청구"]).desc(["Billing inquiry", "청구 문의"]),
253
+ }));
254
+ ```
323
255
 
324
- // * ==================== Custom ==================== * //
325
- profileHeading: ["User Profile", "사용자 프로필"],
326
- accountSettings: ["Account Settings", "계정 설정"],
327
- loginHistory: ["Login History", "로그인 기록"],
328
- // * ==================== Custom ==================== * //
329
- } satisfies ModelDictionary<User>;
256
+ ## Pro Tips
330
257
 
331
- export const userDictionary = modelDictionary;
332
- ```
258
+ - **TypeScript Errors**: TypeScript will show errors if you miss any fields or enum values - use this to your advantage!
259
+ - **Usage**: The dictionary is used for UI labels, form validation messages, and API documentation
260
+ - **Descriptions**: Keep descriptions concise but informative - they appear in tooltips and help text
261
+ - **Consistency**: Match the field order in dictionary with the constant file for easier maintenance
333
262
 
334
- ## Summary Checklist
263
+ ## Summary
335
264
 
336
- 1. **Imports**: Import `ModelDictionary` and model type
337
- 2. **Metadata**: Include `modelName` and `modelDesc`
338
- 3. **Fields**: Translate all model fields with descriptions
339
- 4. **Enums**: Translate all enum values with descriptions
340
- 5. **Format**: Use proper prefix patterns (`desc-`, `enum-`, `enumdesc-`)
341
- 6. **Arrays**: Use two-element arrays for all translations
342
- 7. **Organization**: Group related translations with comment separators
343
- 8. **Type Safety**: Use `satisfies ModelDictionary<YourModel>`
344
- 9. **Export**: Name the export to match the model name
345
- 10. **Completeness**: Ensure all fields and enums from the constant file are translated
265
+ 1. **Import**: `scalarDictionary` from `@akanjs/dictionary`, types from constant file
266
+ 2. **Initialize**: `scalarDictionary(["en", "ko"])`
267
+ 3. **Scalar Info**: `.of((t) => t([...]).desc([...]))`
268
+ 4. **Fields**: `.model<Type>((t) => ({ field: t([...]).desc([...]) }))`
269
+ 5. **Enums**: `.enum<Type>("enumName", (t) => ({ value: t([...]).desc([...]) }))`
270
+ 6. **Export**: `export const dictionary = ...`
271
+ 7. **Format**: `t(["English", "Korean"]).desc(["English desc", "Korean desc"])`
346
272
 
347
- Following these guidelines will ensure your scalar dictionary files are complete, consistent, and maintainable across the Akan.js framework.
273
+ Following these guidelines ensures your scalar dictionary files are complete, type-safe, and maintainable across the Akan.js framework.