@famgia/omnify-typescript 0.0.1 → 0.0.2

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.
@@ -0,0 +1,274 @@
1
+ #!/usr/bin/env node
2
+
3
+ import fs from 'fs';
4
+ import path from 'path';
5
+
6
+ const TYPESCRIPT_GUIDE_CONTENT = `# Omnify TypeScript Generator Guide
7
+
8
+ This guide covers TypeScript-specific features and generated code patterns for Omnify.
9
+
10
+ ## Generated Files
11
+
12
+ When you run \`npx omnify generate\`, the following TypeScript files are generated:
13
+
14
+ - \`types/omnify-types.ts\` - All type definitions
15
+ - \`types/enums.ts\` - Enum types and helpers
16
+
17
+ ## Type Generation
18
+
19
+ ### Object Schema → Interface
20
+
21
+ \`\`\`yaml
22
+ # schemas/User.yaml
23
+ name: User
24
+ properties:
25
+ id:
26
+ type: BigInt
27
+ required: true
28
+ name:
29
+ type: String
30
+ required: true
31
+ maxLength: 255
32
+ email:
33
+ type: String
34
+ required: true
35
+ unique: true
36
+ profile:
37
+ type: Json
38
+ createdAt:
39
+ type: DateTime
40
+ \`\`\`
41
+
42
+ Generated:
43
+ \`\`\`typescript
44
+ export interface User {
45
+ id: number;
46
+ name: string;
47
+ email: string;
48
+ profile: Record<string, unknown> | null;
49
+ createdAt: Date | null;
50
+ }
51
+ \`\`\`
52
+
53
+ ## Type Mapping
54
+
55
+ | Schema Type | TypeScript Type |
56
+ |-------------|-----------------|
57
+ | \`String\` | \`string\` |
58
+ | \`LongText\` | \`string\` |
59
+ | \`Int\` | \`number\` |
60
+ | \`BigInt\` | \`number\` |
61
+ | \`Float\` | \`number\` |
62
+ | \`Boolean\` | \`boolean\` |
63
+ | \`Date\` | \`Date\` |
64
+ | \`DateTime\` | \`Date\` |
65
+ | \`Json\` | \`Record<string, unknown>\` |
66
+ | \`EnumRef\` | Generated enum type |
67
+ | \`Association\` | Related model type / array |
68
+
69
+ ## Enum Generation
70
+
71
+ \`\`\`yaml
72
+ # schemas/PostStatus.yaml
73
+ name: PostStatus
74
+ kind: enum
75
+ values:
76
+ draft: 下書き
77
+ published: 公開済み
78
+ archived: アーカイブ
79
+ \`\`\`
80
+
81
+ Generated:
82
+ \`\`\`typescript
83
+ export const PostStatus = {
84
+ draft: 'draft',
85
+ published: 'published',
86
+ archived: 'archived',
87
+ } as const;
88
+
89
+ export type PostStatus = typeof PostStatus[keyof typeof PostStatus];
90
+
91
+ // Helper functions
92
+ export const PostStatusValues = Object.values(PostStatus);
93
+ export const PostStatusKeys = Object.keys(PostStatus) as (keyof typeof PostStatus)[];
94
+
95
+ export function isPostStatus(value: unknown): value is PostStatus {
96
+ return PostStatusValues.includes(value as PostStatus);
97
+ }
98
+
99
+ // Display names for UI
100
+ export const PostStatusDisplayNames: Record<PostStatus, string> = {
101
+ draft: '下書き',
102
+ published: '公開済み',
103
+ archived: 'アーカイブ',
104
+ };
105
+
106
+ export function getPostStatusDisplayName(value: PostStatus): string {
107
+ return PostStatusDisplayNames[value];
108
+ }
109
+ \`\`\`
110
+
111
+ ## Association Types
112
+
113
+ ### ManyToOne
114
+ \`\`\`yaml
115
+ author:
116
+ type: Association
117
+ relation: ManyToOne
118
+ target: User
119
+ \`\`\`
120
+
121
+ Generated:
122
+ \`\`\`typescript
123
+ export interface Post {
124
+ authorId: number;
125
+ author?: User; // Optional: loaded relation
126
+ }
127
+ \`\`\`
128
+
129
+ ### OneToMany
130
+ \`\`\`yaml
131
+ posts:
132
+ type: Association
133
+ relation: OneToMany
134
+ target: Post
135
+ \`\`\`
136
+
137
+ Generated:
138
+ \`\`\`typescript
139
+ export interface User {
140
+ posts?: Post[]; // Optional: loaded relation array
141
+ }
142
+ \`\`\`
143
+
144
+ ### ManyToMany
145
+ \`\`\`yaml
146
+ tags:
147
+ type: Association
148
+ relation: ManyToMany
149
+ target: Tag
150
+ \`\`\`
151
+
152
+ Generated:
153
+ \`\`\`typescript
154
+ export interface Post {
155
+ tags?: Tag[]; // Optional: loaded relation array
156
+ }
157
+ \`\`\`
158
+
159
+ ## Nullable Fields
160
+
161
+ Fields without \`required: true\` are nullable:
162
+
163
+ \`\`\`yaml
164
+ description:
165
+ type: LongText # No required: true
166
+ \`\`\`
167
+
168
+ Generated:
169
+ \`\`\`typescript
170
+ description: string | null;
171
+ \`\`\`
172
+
173
+ ## Using Generated Types
174
+
175
+ \`\`\`typescript
176
+ import { User, Post, PostStatus, isPostStatus } from './types/omnify-types';
177
+
178
+ // Type-safe object creation
179
+ const user: User = {
180
+ id: 1,
181
+ name: 'John',
182
+ email: 'john@example.com',
183
+ profile: null,
184
+ createdAt: new Date(),
185
+ };
186
+
187
+ // Enum usage
188
+ const status: PostStatus = PostStatus.draft;
189
+
190
+ // Type guard
191
+ function handleStatus(value: unknown) {
192
+ if (isPostStatus(value)) {
193
+ console.log('Valid status:', value);
194
+ }
195
+ }
196
+ \`\`\`
197
+
198
+ ## Commands
199
+
200
+ \`\`\`bash
201
+ # Generate TypeScript types
202
+ npx omnify generate --typescript
203
+
204
+ # Generate to specific output
205
+ npx omnify generate --typescript --output ./src/types
206
+
207
+ # Watch for changes
208
+ npx omnify watch --typescript
209
+ \`\`\`
210
+
211
+ ## Configuration
212
+
213
+ \`\`\`javascript
214
+ // omnify.config.js
215
+ export default {
216
+ schemasDir: './schemas',
217
+ typescript: {
218
+ outputDir: './types',
219
+ outputFile: 'omnify-types.ts',
220
+ enumsFile: 'enums.ts',
221
+ generateHelpers: true, // Generate enum helpers
222
+ strictNullChecks: true // Use | null for optional
223
+ }
224
+ };
225
+ \`\`\`
226
+ `;
227
+
228
+ function findProjectRoot() {
229
+ let dir = process.cwd();
230
+ const nodeModulesIndex = dir.indexOf('node_modules');
231
+ if (nodeModulesIndex !== -1) {
232
+ dir = dir.substring(0, nodeModulesIndex - 1);
233
+ }
234
+ const packageJsonPath = path.join(dir, 'package.json');
235
+ if (fs.existsSync(packageJsonPath)) {
236
+ return dir;
237
+ }
238
+ return null;
239
+ }
240
+
241
+ function createTypescriptSkillFile(projectRoot) {
242
+ const omnifyDir = path.join(projectRoot, '.claude', 'omnify');
243
+
244
+ try {
245
+ if (!fs.existsSync(omnifyDir)) {
246
+ fs.mkdirSync(omnifyDir, { recursive: true });
247
+ }
248
+
249
+ const guidePath = path.join(omnifyDir, 'typescript-guide.md');
250
+ fs.writeFileSync(guidePath, TYPESCRIPT_GUIDE_CONTENT, 'utf-8');
251
+ console.log(' Created .claude/omnify/typescript-guide.md');
252
+ return true;
253
+ } catch {
254
+ return false;
255
+ }
256
+ }
257
+
258
+ function main() {
259
+ if (process.env.CI || process.env.CONTINUOUS_INTEGRATION) {
260
+ return;
261
+ }
262
+
263
+ const cwd = process.cwd();
264
+ if (cwd.includes('omnify-ts') && !cwd.includes('node_modules')) {
265
+ return;
266
+ }
267
+
268
+ const projectRoot = findProjectRoot();
269
+ if (projectRoot) {
270
+ createTypescriptSkillFile(projectRoot);
271
+ }
272
+ }
273
+
274
+ main();