@famgia/omnify-typescript 0.0.1 → 0.0.4
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/dist/chunk-J46F3EBS.js +638 -0
- package/dist/chunk-J46F3EBS.js.map +1 -0
- package/dist/index.cjs +315 -155
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +43 -36
- package/dist/index.d.ts +43 -36
- package/dist/index.js +2 -7
- package/dist/plugin.cjs +324 -186
- package/dist/plugin.cjs.map +1 -1
- package/dist/plugin.d.cts +10 -20
- package/dist/plugin.d.ts +10 -20
- package/dist/plugin.js +11 -40
- package/dist/plugin.js.map +1 -1
- package/package.json +6 -4
- package/scripts/postinstall.js +276 -0
- package/dist/chunk-2BXDNKIN.js +0 -477
- package/dist/chunk-2BXDNKIN.js.map +0 -1
|
@@ -0,0 +1,276 @@
|
|
|
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
|
+
// npm/pnpm set INIT_CWD to the directory where the install was run
|
|
230
|
+
let dir = process.env.INIT_CWD || process.cwd();
|
|
231
|
+
const nodeModulesIndex = dir.indexOf('node_modules');
|
|
232
|
+
if (nodeModulesIndex !== -1) {
|
|
233
|
+
dir = dir.substring(0, nodeModulesIndex - 1);
|
|
234
|
+
}
|
|
235
|
+
const packageJsonPath = path.join(dir, 'package.json');
|
|
236
|
+
if (fs.existsSync(packageJsonPath)) {
|
|
237
|
+
return dir;
|
|
238
|
+
}
|
|
239
|
+
return null;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
function createTypescriptSkillFile(projectRoot) {
|
|
243
|
+
const omnifyDir = path.join(projectRoot, '.claude', 'omnify');
|
|
244
|
+
|
|
245
|
+
try {
|
|
246
|
+
if (!fs.existsSync(omnifyDir)) {
|
|
247
|
+
fs.mkdirSync(omnifyDir, { recursive: true });
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
const guidePath = path.join(omnifyDir, 'typescript-guide.md');
|
|
251
|
+
fs.writeFileSync(guidePath, TYPESCRIPT_GUIDE_CONTENT, 'utf-8');
|
|
252
|
+
console.log(' Created .claude/omnify/typescript-guide.md');
|
|
253
|
+
return true;
|
|
254
|
+
} catch {
|
|
255
|
+
return false;
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
function main() {
|
|
260
|
+
if (process.env.CI || process.env.CONTINUOUS_INTEGRATION) {
|
|
261
|
+
return;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
// Skip if in omnify-ts monorepo (source code), but allow examples/
|
|
265
|
+
const projectDir = process.env.INIT_CWD || process.cwd();
|
|
266
|
+
if (projectDir.includes('omnify-ts') && !projectDir.includes('omnify-ts/examples')) {
|
|
267
|
+
return;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
const projectRoot = findProjectRoot();
|
|
271
|
+
if (projectRoot) {
|
|
272
|
+
createTypescriptSkillFile(projectRoot);
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
main();
|