@masaori/zod-to-entity-definitions 1.1.7
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/README.md +413 -0
- package/dist/index.d.mts +101 -0
- package/dist/index.d.ts +101 -0
- package/dist/index.js +267 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +262 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +67 -0
package/README.md
ADDED
|
@@ -0,0 +1,413 @@
|
|
|
1
|
+
# zod-to-entity-definitions
|
|
2
|
+
|
|
3
|
+
A TypeScript library that allows you to define data models using Zod with extended metadata (Primary Key, Foreign Key, Unique) and convert them into framework-agnostic Entity Definitions (ER models).
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- 🔧 **Zod Extensions**: Add `.pk()`, `.unique()`, and `.ref()` methods to Zod schemas
|
|
8
|
+
- 🏗️ **Entity & Struct Factories**: Define entities and reusable struct types
|
|
9
|
+
- 🔄 **Automatic Generation**: Convert Zod schemas to entity definitions and relations
|
|
10
|
+
- 🔒 **Type-Safe**: Full TypeScript support with strict typing
|
|
11
|
+
- 📦 **Framework Agnostic**: Generate generic entity definitions usable by any framework
|
|
12
|
+
- ✅ **Validation**: Built-in validation for entity nesting and reference integrity
|
|
13
|
+
|
|
14
|
+
## Installation
|
|
15
|
+
|
|
16
|
+
### Installation
|
|
17
|
+
|
|
18
|
+
Install the package from npm:
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
npm install @masaori/zod-to-entity-definitions zod
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Quick Start
|
|
25
|
+
|
|
26
|
+
```typescript
|
|
27
|
+
import { z } from 'zod';
|
|
28
|
+
import {
|
|
29
|
+
entity,
|
|
30
|
+
struct,
|
|
31
|
+
generateEntities,
|
|
32
|
+
generateRelations,
|
|
33
|
+
} from '@masaori/zod-to-entity-definitions';
|
|
34
|
+
|
|
35
|
+
// 1. Define a Struct (reusable component)
|
|
36
|
+
const Address = struct({
|
|
37
|
+
name: 'AddressStruct',
|
|
38
|
+
description: 'Common address',
|
|
39
|
+
columns: {
|
|
40
|
+
city: z.string(),
|
|
41
|
+
street: z.string(),
|
|
42
|
+
},
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
// 2. Define Entities
|
|
46
|
+
const Company = entity({
|
|
47
|
+
name: 'Company',
|
|
48
|
+
columns: {
|
|
49
|
+
id: z.string().pk(),
|
|
50
|
+
name: z.string(),
|
|
51
|
+
address: Address, // Using struct is OK
|
|
52
|
+
},
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
const User = entity({
|
|
56
|
+
name: 'User',
|
|
57
|
+
columns: {
|
|
58
|
+
id: z.string().pk(),
|
|
59
|
+
email: z.string().email().unique(),
|
|
60
|
+
companyId: z.string().ref(Company), // Reference to Company entity
|
|
61
|
+
},
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
// 3. Generate Entity Definitions
|
|
65
|
+
const definitions = generateEntities([Company, User]);
|
|
66
|
+
|
|
67
|
+
// 4. Generate Relations
|
|
68
|
+
const relations = generateRelations(definitions);
|
|
69
|
+
|
|
70
|
+
console.log(JSON.stringify(definitions, null, 2));
|
|
71
|
+
console.log(JSON.stringify(relations, null, 2));
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
> 📝 **See the [examples](./examples) directory for complete working examples with generated JSON output.**
|
|
75
|
+
|
|
76
|
+
## API Reference
|
|
77
|
+
|
|
78
|
+
### Zod Extensions
|
|
79
|
+
|
|
80
|
+
The library extends Zod schemas with the following methods:
|
|
81
|
+
|
|
82
|
+
#### `.pk()`
|
|
83
|
+
|
|
84
|
+
Marks a field as the Primary Key.
|
|
85
|
+
|
|
86
|
+
```typescript
|
|
87
|
+
id: z.string().pk();
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
#### `.unique()`
|
|
91
|
+
|
|
92
|
+
Marks a field as Unique.
|
|
93
|
+
|
|
94
|
+
```typescript
|
|
95
|
+
email: z.string().email().unique();
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
#### `.ref(targetEntity, targetColumn?)`
|
|
99
|
+
|
|
100
|
+
Marks a field as a Foreign Key reference to another entity.
|
|
101
|
+
|
|
102
|
+
- `targetEntity`: Must be a schema created with `entity()`
|
|
103
|
+
- `targetColumn`: Optional, defaults to "id"
|
|
104
|
+
|
|
105
|
+
```typescript
|
|
106
|
+
companyId: z.string().ref(Company);
|
|
107
|
+
managerId: z.string().ref(User, 'userId');
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### Factory Functions
|
|
111
|
+
|
|
112
|
+
#### `entity(config)`
|
|
113
|
+
|
|
114
|
+
Creates an entity schema with metadata.
|
|
115
|
+
|
|
116
|
+
```typescript
|
|
117
|
+
type EntityConfig<T extends z.ZodRawShape> = {
|
|
118
|
+
name: string;
|
|
119
|
+
description?: string;
|
|
120
|
+
columns: T;
|
|
121
|
+
};
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
#### `struct(config)`
|
|
125
|
+
|
|
126
|
+
Creates a struct schema for reusable components.
|
|
127
|
+
|
|
128
|
+
```typescript
|
|
129
|
+
type StructConfig<T extends z.ZodRawShape> = {
|
|
130
|
+
name: string;
|
|
131
|
+
description?: string;
|
|
132
|
+
columns: T;
|
|
133
|
+
};
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### Generator Functions
|
|
137
|
+
|
|
138
|
+
#### `generateEntities(schemas)`
|
|
139
|
+
|
|
140
|
+
Parses Zod schemas and returns an array of `EntityDefinition`.
|
|
141
|
+
|
|
142
|
+
**Validation Rules:**
|
|
143
|
+
|
|
144
|
+
1. Entities cannot directly embed other entities (must use `.ref()`)
|
|
145
|
+
2. `.ref()` must point to valid entity schemas
|
|
146
|
+
|
|
147
|
+
```typescript
|
|
148
|
+
const definitions = generateEntities([Company, User]);
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
#### `generateRelations(definitions)`
|
|
152
|
+
|
|
153
|
+
Analyzes entity definitions to construct relation maps.
|
|
154
|
+
|
|
155
|
+
```typescript
|
|
156
|
+
const relations = generateRelations(definitions);
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
## Type Definitions
|
|
160
|
+
|
|
161
|
+
### EntityDefinition
|
|
162
|
+
|
|
163
|
+
```typescript
|
|
164
|
+
type EntityDefinition = {
|
|
165
|
+
name: string;
|
|
166
|
+
description?: string;
|
|
167
|
+
properties: EntityPropertyDefinition[];
|
|
168
|
+
};
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
### EntityPropertyDefinition
|
|
172
|
+
|
|
173
|
+
Union type representing different property types:
|
|
174
|
+
|
|
175
|
+
- `EntityPropertyDefinitionPrimaryKey`: Primary key field
|
|
176
|
+
- `EntityPropertyDefinitionPrimitive`: boolean, number, string, Date
|
|
177
|
+
- `EntityPropertyDefinitionTypedStruct`: Reference to a struct type
|
|
178
|
+
- `EntityPropertyDefinitionReferencedObject`: Foreign key reference
|
|
179
|
+
|
|
180
|
+
### EntityRelation
|
|
181
|
+
|
|
182
|
+
```typescript
|
|
183
|
+
type EntityRelation = {
|
|
184
|
+
entityName: string;
|
|
185
|
+
referTos: EntityRelationReferTo[];
|
|
186
|
+
referredBys: EntityRelationReferredBy[];
|
|
187
|
+
};
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
## Advanced Usage
|
|
191
|
+
|
|
192
|
+
### Nullable and Optional Fields
|
|
193
|
+
|
|
194
|
+
```typescript
|
|
195
|
+
const User = entity({
|
|
196
|
+
name: 'User',
|
|
197
|
+
columns: {
|
|
198
|
+
id: z.string().pk(),
|
|
199
|
+
nickname: z.string().optional(), // Optional field
|
|
200
|
+
bio: z.string().nullable(), // Nullable field
|
|
201
|
+
},
|
|
202
|
+
});
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
### Array Fields
|
|
206
|
+
|
|
207
|
+
```typescript
|
|
208
|
+
const User = entity({
|
|
209
|
+
name: 'User',
|
|
210
|
+
columns: {
|
|
211
|
+
id: z.string().pk(),
|
|
212
|
+
tags: z.array(z.string()),
|
|
213
|
+
scores: z.array(z.number()).optional(),
|
|
214
|
+
},
|
|
215
|
+
});
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
### Enum Fields
|
|
219
|
+
|
|
220
|
+
```typescript
|
|
221
|
+
const User = entity({
|
|
222
|
+
name: 'User',
|
|
223
|
+
columns: {
|
|
224
|
+
id: z.string().pk(),
|
|
225
|
+
role: z.enum(['admin', 'user', 'guest']),
|
|
226
|
+
},
|
|
227
|
+
});
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
### Complex Relations
|
|
231
|
+
|
|
232
|
+
```typescript
|
|
233
|
+
const Department = entity({
|
|
234
|
+
name: 'Department',
|
|
235
|
+
columns: {
|
|
236
|
+
id: z.string().pk(),
|
|
237
|
+
name: z.string(),
|
|
238
|
+
},
|
|
239
|
+
});
|
|
240
|
+
|
|
241
|
+
const Employee = entity({
|
|
242
|
+
name: 'Employee',
|
|
243
|
+
columns: {
|
|
244
|
+
id: z.string().pk(),
|
|
245
|
+
name: z.string(),
|
|
246
|
+
departmentId: z.string().ref(Department),
|
|
247
|
+
},
|
|
248
|
+
});
|
|
249
|
+
|
|
250
|
+
const Project = entity({
|
|
251
|
+
name: 'Project',
|
|
252
|
+
columns: {
|
|
253
|
+
id: z.string().pk(),
|
|
254
|
+
name: z.string(),
|
|
255
|
+
leadId: z.string().ref(Employee),
|
|
256
|
+
departmentId: z.string().ref(Department),
|
|
257
|
+
},
|
|
258
|
+
});
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
## Validation Rules
|
|
262
|
+
|
|
263
|
+
### ❌ Entity Nesting (Not Allowed)
|
|
264
|
+
|
|
265
|
+
```typescript
|
|
266
|
+
const User = entity({
|
|
267
|
+
name: 'User',
|
|
268
|
+
columns: {
|
|
269
|
+
id: z.string().pk(),
|
|
270
|
+
company: Company, // ❌ Error: Direct entity embedding not allowed
|
|
271
|
+
},
|
|
272
|
+
});
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
### ✅ Use References Instead
|
|
276
|
+
|
|
277
|
+
```typescript
|
|
278
|
+
const User = entity({
|
|
279
|
+
name: 'User',
|
|
280
|
+
columns: {
|
|
281
|
+
id: z.string().pk(),
|
|
282
|
+
companyId: z.string().ref(Company), // ✅ Correct: Use .ref()
|
|
283
|
+
},
|
|
284
|
+
});
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
### ❌ Invalid References
|
|
288
|
+
|
|
289
|
+
```typescript
|
|
290
|
+
const Address = struct({
|
|
291
|
+
name: 'Address',
|
|
292
|
+
columns: { city: z.string() },
|
|
293
|
+
});
|
|
294
|
+
|
|
295
|
+
const User = entity({
|
|
296
|
+
name: 'User',
|
|
297
|
+
columns: {
|
|
298
|
+
id: z.string().pk(),
|
|
299
|
+
addressId: z.string().ref(Address), // ❌ Error: Can't reference struct
|
|
300
|
+
},
|
|
301
|
+
});
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
## Development
|
|
305
|
+
|
|
306
|
+
```bash
|
|
307
|
+
# Install dependencies
|
|
308
|
+
pnpm install
|
|
309
|
+
|
|
310
|
+
# Run tests
|
|
311
|
+
pnpm test
|
|
312
|
+
|
|
313
|
+
# Run tests in watch mode
|
|
314
|
+
pnpm test:watch
|
|
315
|
+
|
|
316
|
+
# Type checking
|
|
317
|
+
pnpm check-types
|
|
318
|
+
|
|
319
|
+
# Linting
|
|
320
|
+
pnpm lint
|
|
321
|
+
|
|
322
|
+
# Auto-fix lint issues
|
|
323
|
+
pnpm lint:fix
|
|
324
|
+
|
|
325
|
+
# Format code
|
|
326
|
+
pnpm format
|
|
327
|
+
|
|
328
|
+
# Build
|
|
329
|
+
pnpm build
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
## CI/CD
|
|
333
|
+
|
|
334
|
+
This project uses GitHub Actions for continuous integration and deployment.
|
|
335
|
+
|
|
336
|
+
### Workflows
|
|
337
|
+
|
|
338
|
+
1. **Commit Message Validation** (`.github/workflows/commit-check.yml`)
|
|
339
|
+
- Runs on all PRs
|
|
340
|
+
- Validates commit messages using [Conventional Commits](https://www.conventionalcommits.org/)
|
|
341
|
+
- Ensures all commits are linear (no merge commits)
|
|
342
|
+
|
|
343
|
+
2. **Lint and Test** (`.github/workflows/lint-test.yml`)
|
|
344
|
+
- Runs on all PRs and pushes to main
|
|
345
|
+
- Executes linting, type checking, and tests
|
|
346
|
+
- Must pass before merging
|
|
347
|
+
|
|
348
|
+
3. **Publish to GitHub Packages** (`.github/workflows/publish.yml`)
|
|
349
|
+
- Manual workflow trigger only (workflow_dispatch)
|
|
350
|
+
- Automatically determines version bump using semantic versioning
|
|
351
|
+
- Publishes to GitHub Packages with automatic changelog generation
|
|
352
|
+
- Version bumps follow Conventional Commits:
|
|
353
|
+
- `feat:` → minor version bump
|
|
354
|
+
- `fix:`, `docs:`, `style:`, `refactor:`, `test:`, `build:`, `ci:`, `chore:` → patch version bump
|
|
355
|
+
- `BREAKING CHANGE:` → major version bump
|
|
356
|
+
|
|
357
|
+
### Publishing to GitHub Packages
|
|
358
|
+
|
|
359
|
+
Publishing is automated via GitHub Actions. To publish a new version:
|
|
360
|
+
|
|
361
|
+
1. **Required tokens**: No additional tokens needed!
|
|
362
|
+
- The workflow uses the built-in `GITHUB_TOKEN` which is automatically provided by GitHub Actions
|
|
363
|
+
- The `GITHUB_TOKEN` has the necessary permissions to:
|
|
364
|
+
- Write to the repository (create tags, update files)
|
|
365
|
+
- Publish to GitHub Packages
|
|
366
|
+
- Create GitHub releases
|
|
367
|
+
- **No manual token configuration required** - it works out of the box
|
|
368
|
+
|
|
369
|
+
2. **Trigger the publish workflow**:
|
|
370
|
+
- Go to the Actions tab in GitHub
|
|
371
|
+
- Select "Publish to GitHub Packages" workflow
|
|
372
|
+
- Click "Run workflow" on the main branch
|
|
373
|
+
|
|
374
|
+
3. **Automated process**:
|
|
375
|
+
- The workflow will analyze commit messages since the last release
|
|
376
|
+
- Automatically determine the version bump (major/minor/patch)
|
|
377
|
+
- Update `package.json` and `CHANGELOG.md`
|
|
378
|
+
- Create a git tag and GitHub release
|
|
379
|
+
- Publish to GitHub Packages
|
|
380
|
+
|
|
381
|
+
### Commit Message Format
|
|
382
|
+
|
|
383
|
+
All commits must follow the [Conventional Commits](https://www.conventionalcommits.org/) specification:
|
|
384
|
+
|
|
385
|
+
```
|
|
386
|
+
<type>[optional scope]: <description>
|
|
387
|
+
|
|
388
|
+
[optional body]
|
|
389
|
+
|
|
390
|
+
[optional footer(s)]
|
|
391
|
+
```
|
|
392
|
+
|
|
393
|
+
Examples:
|
|
394
|
+
|
|
395
|
+
- `feat: add new entity validation`
|
|
396
|
+
- `fix: correct reference resolution`
|
|
397
|
+
- `docs: update README with examples`
|
|
398
|
+
- `feat!: remove deprecated API` (breaking change)
|
|
399
|
+
|
|
400
|
+
### Pre-publish Checklist
|
|
401
|
+
|
|
402
|
+
The package includes a `prepublishOnly` script that automatically runs before publishing:
|
|
403
|
+
|
|
404
|
+
- Type checking (`pnpm check-types`)
|
|
405
|
+
- Linting (`pnpm lint`)
|
|
406
|
+
- Tests (`pnpm test`)
|
|
407
|
+
- Build (`pnpm build`)
|
|
408
|
+
|
|
409
|
+
All these checks must pass before the package can be published.
|
|
410
|
+
|
|
411
|
+
## License
|
|
412
|
+
|
|
413
|
+
MIT
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
|
|
3
|
+
declare const PK_SYMBOL: unique symbol;
|
|
4
|
+
declare const UNIQUE_SYMBOL: unique symbol;
|
|
5
|
+
declare const REF_SYMBOL: unique symbol;
|
|
6
|
+
type RefMetadata = {
|
|
7
|
+
targetEntity: z.ZodTypeAny;
|
|
8
|
+
targetColumn: string;
|
|
9
|
+
};
|
|
10
|
+
declare module 'zod' {
|
|
11
|
+
interface ZodType {
|
|
12
|
+
[PK_SYMBOL]?: boolean;
|
|
13
|
+
[UNIQUE_SYMBOL]?: boolean;
|
|
14
|
+
[REF_SYMBOL]?: RefMetadata;
|
|
15
|
+
pk(): this;
|
|
16
|
+
unique(): this;
|
|
17
|
+
ref(targetEntity: z.ZodTypeAny, targetColumn?: string): this;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
type EntityConfig<T extends z.ZodRawShape> = {
|
|
22
|
+
name: string;
|
|
23
|
+
description?: string;
|
|
24
|
+
columns: T;
|
|
25
|
+
};
|
|
26
|
+
type StructConfig<T extends z.ZodRawShape> = {
|
|
27
|
+
name: string;
|
|
28
|
+
description?: string;
|
|
29
|
+
columns: T;
|
|
30
|
+
};
|
|
31
|
+
declare const ENTITY_NAME_BRAND: unique symbol;
|
|
32
|
+
type EntitySchema<TName extends string, TShape extends z.ZodRawShape> = z.ZodObject<TShape> & {
|
|
33
|
+
readonly [ENTITY_NAME_BRAND]: TName;
|
|
34
|
+
};
|
|
35
|
+
declare function entity<const TConfig extends EntityConfig<z.ZodRawShape>>(config: TConfig): EntitySchema<TConfig['name'], TConfig['columns']>;
|
|
36
|
+
declare function struct<T extends z.ZodRawShape>(config: StructConfig<T>): z.ZodObject<T>;
|
|
37
|
+
|
|
38
|
+
type EntityDefinition<TEntityNames = string> = {
|
|
39
|
+
name: TEntityNames;
|
|
40
|
+
description?: string;
|
|
41
|
+
properties: EntityPropertyDefinition[];
|
|
42
|
+
};
|
|
43
|
+
type EntityPropertyDefinition = EntityPropertyDefinitionPrimaryKey | EntityPropertyDefinitionPrimitive | EntityPropertyDefinitionTypedStruct | EntityPropertyDefinitionReferencedObject;
|
|
44
|
+
type EntityPropertyDefinitionPrimaryKey = {
|
|
45
|
+
isReference: false;
|
|
46
|
+
propertyType: 'PrimaryKey';
|
|
47
|
+
name: string;
|
|
48
|
+
description?: string;
|
|
49
|
+
};
|
|
50
|
+
type EntityPropertyDefinitionPrimitive = {
|
|
51
|
+
isReference: false;
|
|
52
|
+
propertyType: 'boolean' | 'number' | 'string' | 'Date' | 'struct';
|
|
53
|
+
name: string;
|
|
54
|
+
isUnique: boolean;
|
|
55
|
+
isNullable: boolean;
|
|
56
|
+
isArray: boolean;
|
|
57
|
+
acceptableValues: string[] | null;
|
|
58
|
+
description?: string;
|
|
59
|
+
};
|
|
60
|
+
type EntityPropertyDefinitionTypedStruct = {
|
|
61
|
+
isReference: false;
|
|
62
|
+
propertyType: 'typedStruct';
|
|
63
|
+
name: string;
|
|
64
|
+
structTypeName: string;
|
|
65
|
+
isUnique: boolean;
|
|
66
|
+
isNullable: boolean;
|
|
67
|
+
isArray: boolean;
|
|
68
|
+
description?: string;
|
|
69
|
+
};
|
|
70
|
+
type EntityPropertyDefinitionReferencedObject = {
|
|
71
|
+
isReference: true;
|
|
72
|
+
name: string;
|
|
73
|
+
targetEntityDefinitionName: string;
|
|
74
|
+
isUnique: boolean;
|
|
75
|
+
isNullable: boolean;
|
|
76
|
+
description?: string;
|
|
77
|
+
};
|
|
78
|
+
type EntityRelationReferTo<T = string> = {
|
|
79
|
+
entityName: T;
|
|
80
|
+
propertyName: string;
|
|
81
|
+
isUnique: boolean;
|
|
82
|
+
};
|
|
83
|
+
type EntityRelationReferredBy<T = string> = {
|
|
84
|
+
entityName: T;
|
|
85
|
+
propertyName: string;
|
|
86
|
+
isUnique: boolean;
|
|
87
|
+
};
|
|
88
|
+
type EntityRelation<T = string> = {
|
|
89
|
+
entityName: T;
|
|
90
|
+
referTos: EntityRelationReferTo<T>[];
|
|
91
|
+
referredBys: EntityRelationReferredBy<T>[];
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
type ExtractEntityName<T> = T extends EntitySchema<infer TName, z.ZodRawShape> ? TName : never;
|
|
95
|
+
type ExtractEntityNames<T extends readonly z.ZodTypeAny[]> = {
|
|
96
|
+
[K in keyof T]: ExtractEntityName<T[K]>;
|
|
97
|
+
}[number];
|
|
98
|
+
declare function generateEntities<const T extends readonly z.ZodTypeAny[]>(schemas: T): EntityDefinition<ExtractEntityNames<T>>[];
|
|
99
|
+
declare function generateRelations(definitions: EntityDefinition[]): EntityRelation[];
|
|
100
|
+
|
|
101
|
+
export { type EntityConfig, type EntityDefinition, type EntityPropertyDefinition, type EntityPropertyDefinitionPrimaryKey, type EntityPropertyDefinitionPrimitive, type EntityPropertyDefinitionReferencedObject, type EntityPropertyDefinitionTypedStruct, type EntityRelation, type EntityRelationReferTo, type EntityRelationReferredBy, type EntitySchema, type StructConfig, entity, generateEntities, generateRelations, struct };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
|
|
3
|
+
declare const PK_SYMBOL: unique symbol;
|
|
4
|
+
declare const UNIQUE_SYMBOL: unique symbol;
|
|
5
|
+
declare const REF_SYMBOL: unique symbol;
|
|
6
|
+
type RefMetadata = {
|
|
7
|
+
targetEntity: z.ZodTypeAny;
|
|
8
|
+
targetColumn: string;
|
|
9
|
+
};
|
|
10
|
+
declare module 'zod' {
|
|
11
|
+
interface ZodType {
|
|
12
|
+
[PK_SYMBOL]?: boolean;
|
|
13
|
+
[UNIQUE_SYMBOL]?: boolean;
|
|
14
|
+
[REF_SYMBOL]?: RefMetadata;
|
|
15
|
+
pk(): this;
|
|
16
|
+
unique(): this;
|
|
17
|
+
ref(targetEntity: z.ZodTypeAny, targetColumn?: string): this;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
type EntityConfig<T extends z.ZodRawShape> = {
|
|
22
|
+
name: string;
|
|
23
|
+
description?: string;
|
|
24
|
+
columns: T;
|
|
25
|
+
};
|
|
26
|
+
type StructConfig<T extends z.ZodRawShape> = {
|
|
27
|
+
name: string;
|
|
28
|
+
description?: string;
|
|
29
|
+
columns: T;
|
|
30
|
+
};
|
|
31
|
+
declare const ENTITY_NAME_BRAND: unique symbol;
|
|
32
|
+
type EntitySchema<TName extends string, TShape extends z.ZodRawShape> = z.ZodObject<TShape> & {
|
|
33
|
+
readonly [ENTITY_NAME_BRAND]: TName;
|
|
34
|
+
};
|
|
35
|
+
declare function entity<const TConfig extends EntityConfig<z.ZodRawShape>>(config: TConfig): EntitySchema<TConfig['name'], TConfig['columns']>;
|
|
36
|
+
declare function struct<T extends z.ZodRawShape>(config: StructConfig<T>): z.ZodObject<T>;
|
|
37
|
+
|
|
38
|
+
type EntityDefinition<TEntityNames = string> = {
|
|
39
|
+
name: TEntityNames;
|
|
40
|
+
description?: string;
|
|
41
|
+
properties: EntityPropertyDefinition[];
|
|
42
|
+
};
|
|
43
|
+
type EntityPropertyDefinition = EntityPropertyDefinitionPrimaryKey | EntityPropertyDefinitionPrimitive | EntityPropertyDefinitionTypedStruct | EntityPropertyDefinitionReferencedObject;
|
|
44
|
+
type EntityPropertyDefinitionPrimaryKey = {
|
|
45
|
+
isReference: false;
|
|
46
|
+
propertyType: 'PrimaryKey';
|
|
47
|
+
name: string;
|
|
48
|
+
description?: string;
|
|
49
|
+
};
|
|
50
|
+
type EntityPropertyDefinitionPrimitive = {
|
|
51
|
+
isReference: false;
|
|
52
|
+
propertyType: 'boolean' | 'number' | 'string' | 'Date' | 'struct';
|
|
53
|
+
name: string;
|
|
54
|
+
isUnique: boolean;
|
|
55
|
+
isNullable: boolean;
|
|
56
|
+
isArray: boolean;
|
|
57
|
+
acceptableValues: string[] | null;
|
|
58
|
+
description?: string;
|
|
59
|
+
};
|
|
60
|
+
type EntityPropertyDefinitionTypedStruct = {
|
|
61
|
+
isReference: false;
|
|
62
|
+
propertyType: 'typedStruct';
|
|
63
|
+
name: string;
|
|
64
|
+
structTypeName: string;
|
|
65
|
+
isUnique: boolean;
|
|
66
|
+
isNullable: boolean;
|
|
67
|
+
isArray: boolean;
|
|
68
|
+
description?: string;
|
|
69
|
+
};
|
|
70
|
+
type EntityPropertyDefinitionReferencedObject = {
|
|
71
|
+
isReference: true;
|
|
72
|
+
name: string;
|
|
73
|
+
targetEntityDefinitionName: string;
|
|
74
|
+
isUnique: boolean;
|
|
75
|
+
isNullable: boolean;
|
|
76
|
+
description?: string;
|
|
77
|
+
};
|
|
78
|
+
type EntityRelationReferTo<T = string> = {
|
|
79
|
+
entityName: T;
|
|
80
|
+
propertyName: string;
|
|
81
|
+
isUnique: boolean;
|
|
82
|
+
};
|
|
83
|
+
type EntityRelationReferredBy<T = string> = {
|
|
84
|
+
entityName: T;
|
|
85
|
+
propertyName: string;
|
|
86
|
+
isUnique: boolean;
|
|
87
|
+
};
|
|
88
|
+
type EntityRelation<T = string> = {
|
|
89
|
+
entityName: T;
|
|
90
|
+
referTos: EntityRelationReferTo<T>[];
|
|
91
|
+
referredBys: EntityRelationReferredBy<T>[];
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
type ExtractEntityName<T> = T extends EntitySchema<infer TName, z.ZodRawShape> ? TName : never;
|
|
95
|
+
type ExtractEntityNames<T extends readonly z.ZodTypeAny[]> = {
|
|
96
|
+
[K in keyof T]: ExtractEntityName<T[K]>;
|
|
97
|
+
}[number];
|
|
98
|
+
declare function generateEntities<const T extends readonly z.ZodTypeAny[]>(schemas: T): EntityDefinition<ExtractEntityNames<T>>[];
|
|
99
|
+
declare function generateRelations(definitions: EntityDefinition[]): EntityRelation[];
|
|
100
|
+
|
|
101
|
+
export { type EntityConfig, type EntityDefinition, type EntityPropertyDefinition, type EntityPropertyDefinitionPrimaryKey, type EntityPropertyDefinitionPrimitive, type EntityPropertyDefinitionReferencedObject, type EntityPropertyDefinitionTypedStruct, type EntityRelation, type EntityRelationReferTo, type EntityRelationReferredBy, type EntitySchema, type StructConfig, entity, generateEntities, generateRelations, struct };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var zod = require('zod');
|
|
4
|
+
|
|
5
|
+
// src/setupZod.ts
|
|
6
|
+
var PK_SYMBOL = Symbol("zod-entity-pk");
|
|
7
|
+
var UNIQUE_SYMBOL = Symbol("zod-entity-unique");
|
|
8
|
+
var REF_SYMBOL = Symbol("zod-entity-ref");
|
|
9
|
+
zod.z.ZodType.prototype.pk = function() {
|
|
10
|
+
this[PK_SYMBOL] = true;
|
|
11
|
+
return this;
|
|
12
|
+
};
|
|
13
|
+
zod.z.ZodType.prototype.unique = function() {
|
|
14
|
+
this[UNIQUE_SYMBOL] = true;
|
|
15
|
+
return this;
|
|
16
|
+
};
|
|
17
|
+
zod.z.ZodType.prototype.ref = function(targetEntity, targetColumn = "id") {
|
|
18
|
+
this[REF_SYMBOL] = { targetEntity, targetColumn };
|
|
19
|
+
return this;
|
|
20
|
+
};
|
|
21
|
+
function isPrimaryKey(schema) {
|
|
22
|
+
return schema[PK_SYMBOL] === true;
|
|
23
|
+
}
|
|
24
|
+
function isUnique(schema) {
|
|
25
|
+
return schema[UNIQUE_SYMBOL] === true;
|
|
26
|
+
}
|
|
27
|
+
function getRefMetadata(schema) {
|
|
28
|
+
return schema[REF_SYMBOL];
|
|
29
|
+
}
|
|
30
|
+
var SCHEMA_TYPE_SYMBOL = Symbol("zod-schema-type");
|
|
31
|
+
var SCHEMA_NAME_SYMBOL = Symbol("zod-schema-name");
|
|
32
|
+
var SCHEMA_DESCRIPTION_SYMBOL = Symbol("zod-schema-description");
|
|
33
|
+
function entity(config) {
|
|
34
|
+
const schema = zod.z.object(config.columns);
|
|
35
|
+
schema[SCHEMA_TYPE_SYMBOL] = "entity";
|
|
36
|
+
schema[SCHEMA_NAME_SYMBOL] = config.name;
|
|
37
|
+
if (config.description !== void 0) {
|
|
38
|
+
schema[SCHEMA_DESCRIPTION_SYMBOL] = config.description;
|
|
39
|
+
}
|
|
40
|
+
return schema;
|
|
41
|
+
}
|
|
42
|
+
function struct(config) {
|
|
43
|
+
const schema = zod.z.object(config.columns);
|
|
44
|
+
schema[SCHEMA_TYPE_SYMBOL] = "struct";
|
|
45
|
+
schema[SCHEMA_NAME_SYMBOL] = config.name;
|
|
46
|
+
if (config.description !== void 0) {
|
|
47
|
+
schema[SCHEMA_DESCRIPTION_SYMBOL] = config.description;
|
|
48
|
+
}
|
|
49
|
+
return schema;
|
|
50
|
+
}
|
|
51
|
+
function getSchemaType(schema) {
|
|
52
|
+
if (schema instanceof zod.z.ZodObject) {
|
|
53
|
+
return schema[SCHEMA_TYPE_SYMBOL];
|
|
54
|
+
}
|
|
55
|
+
return void 0;
|
|
56
|
+
}
|
|
57
|
+
function getSchemaName(schema) {
|
|
58
|
+
if (schema instanceof zod.z.ZodObject) {
|
|
59
|
+
return schema[SCHEMA_NAME_SYMBOL];
|
|
60
|
+
}
|
|
61
|
+
return void 0;
|
|
62
|
+
}
|
|
63
|
+
function getSchemaDescription(schema) {
|
|
64
|
+
if (schema instanceof zod.z.ZodObject) {
|
|
65
|
+
return schema[SCHEMA_DESCRIPTION_SYMBOL];
|
|
66
|
+
}
|
|
67
|
+
return void 0;
|
|
68
|
+
}
|
|
69
|
+
function unwrapSchema(schema) {
|
|
70
|
+
let current = schema;
|
|
71
|
+
let isNullable = false;
|
|
72
|
+
let isArray = false;
|
|
73
|
+
while (true) {
|
|
74
|
+
if (current instanceof zod.z.ZodOptional) {
|
|
75
|
+
isNullable = true;
|
|
76
|
+
current = current.unwrap();
|
|
77
|
+
} else if (current instanceof zod.z.ZodNullable) {
|
|
78
|
+
isNullable = true;
|
|
79
|
+
current = current.unwrap();
|
|
80
|
+
} else if (current instanceof zod.z.ZodArray) {
|
|
81
|
+
isArray = true;
|
|
82
|
+
current = current.element;
|
|
83
|
+
} else {
|
|
84
|
+
break;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
return { innerSchema: current, isNullable, isArray };
|
|
88
|
+
}
|
|
89
|
+
function generateEntities(schemas) {
|
|
90
|
+
const definitions = [];
|
|
91
|
+
for (const schema of schemas) {
|
|
92
|
+
const schemaType = getSchemaType(schema);
|
|
93
|
+
if (schemaType !== "entity") {
|
|
94
|
+
continue;
|
|
95
|
+
}
|
|
96
|
+
const name = getSchemaName(schema);
|
|
97
|
+
if (name === void 0) {
|
|
98
|
+
throw new Error("Entity schema must have a name");
|
|
99
|
+
}
|
|
100
|
+
const description = getSchemaDescription(schema);
|
|
101
|
+
if (!(schema instanceof zod.z.ZodObject)) {
|
|
102
|
+
throw new Error(`Entity "${name}" must be a ZodObject`);
|
|
103
|
+
}
|
|
104
|
+
const properties = [];
|
|
105
|
+
const shape = schema.shape;
|
|
106
|
+
for (const [fieldName, fieldSchema] of Object.entries(shape)) {
|
|
107
|
+
if (!(fieldSchema instanceof zod.z.ZodType)) {
|
|
108
|
+
continue;
|
|
109
|
+
}
|
|
110
|
+
const property = parseProperty(fieldName, fieldSchema);
|
|
111
|
+
properties.push(property);
|
|
112
|
+
}
|
|
113
|
+
const entityDefinition = {
|
|
114
|
+
name,
|
|
115
|
+
properties
|
|
116
|
+
};
|
|
117
|
+
if (description !== void 0) {
|
|
118
|
+
entityDefinition.description = description;
|
|
119
|
+
}
|
|
120
|
+
definitions.push(entityDefinition);
|
|
121
|
+
}
|
|
122
|
+
return definitions;
|
|
123
|
+
}
|
|
124
|
+
function parseProperty(fieldName, fieldSchema) {
|
|
125
|
+
const isPk = isPrimaryKey(fieldSchema);
|
|
126
|
+
const isUniqueField = isUnique(fieldSchema);
|
|
127
|
+
const refMetadata = getRefMetadata(fieldSchema);
|
|
128
|
+
if (isPk) {
|
|
129
|
+
const property = {
|
|
130
|
+
isReference: false,
|
|
131
|
+
propertyType: "PrimaryKey",
|
|
132
|
+
name: fieldName
|
|
133
|
+
};
|
|
134
|
+
return property;
|
|
135
|
+
}
|
|
136
|
+
if (refMetadata !== void 0) {
|
|
137
|
+
const { targetEntity } = refMetadata;
|
|
138
|
+
const targetSchemaType = getSchemaType(targetEntity);
|
|
139
|
+
if (targetSchemaType !== "entity") {
|
|
140
|
+
throw new Error(
|
|
141
|
+
`Field "${fieldName}" has .ref() pointing to a non-entity schema. Only entity schemas created with entity() can be referenced.`
|
|
142
|
+
);
|
|
143
|
+
}
|
|
144
|
+
const targetEntityName = getSchemaName(targetEntity);
|
|
145
|
+
if (targetEntityName === void 0) {
|
|
146
|
+
throw new Error(`Referenced entity for field "${fieldName}" must have a name`);
|
|
147
|
+
}
|
|
148
|
+
const { isNullable: isNullable2 } = unwrapSchema(fieldSchema);
|
|
149
|
+
const property = {
|
|
150
|
+
isReference: true,
|
|
151
|
+
name: fieldName,
|
|
152
|
+
targetEntityDefinitionName: targetEntityName,
|
|
153
|
+
isUnique: isUniqueField,
|
|
154
|
+
isNullable: isNullable2
|
|
155
|
+
};
|
|
156
|
+
return property;
|
|
157
|
+
}
|
|
158
|
+
const { innerSchema, isNullable, isArray } = unwrapSchema(fieldSchema);
|
|
159
|
+
const innerSchemaType = getSchemaType(innerSchema);
|
|
160
|
+
if (innerSchemaType === "entity") {
|
|
161
|
+
throw new Error(
|
|
162
|
+
`Field "${fieldName}" contains a direct entity embedding. Entities cannot be directly nested. Use .ref() instead.`
|
|
163
|
+
);
|
|
164
|
+
}
|
|
165
|
+
if (innerSchemaType === "struct") {
|
|
166
|
+
const structName = getSchemaName(innerSchema);
|
|
167
|
+
if (structName === void 0) {
|
|
168
|
+
throw new Error(`Struct schema for field "${fieldName}" must have a name`);
|
|
169
|
+
}
|
|
170
|
+
const property = {
|
|
171
|
+
isReference: false,
|
|
172
|
+
propertyType: "typedStruct",
|
|
173
|
+
name: fieldName,
|
|
174
|
+
structTypeName: structName,
|
|
175
|
+
isUnique: isUniqueField,
|
|
176
|
+
isNullable,
|
|
177
|
+
isArray
|
|
178
|
+
};
|
|
179
|
+
return property;
|
|
180
|
+
}
|
|
181
|
+
const primitiveType = getPrimitiveType(innerSchema);
|
|
182
|
+
if (primitiveType !== null) {
|
|
183
|
+
const acceptableValues = getAcceptableValues(innerSchema);
|
|
184
|
+
const property = {
|
|
185
|
+
isReference: false,
|
|
186
|
+
propertyType: primitiveType,
|
|
187
|
+
name: fieldName,
|
|
188
|
+
isUnique: isUniqueField,
|
|
189
|
+
isNullable,
|
|
190
|
+
isArray,
|
|
191
|
+
acceptableValues
|
|
192
|
+
};
|
|
193
|
+
return property;
|
|
194
|
+
}
|
|
195
|
+
throw new Error(`Unsupported schema type for field "${fieldName}"`);
|
|
196
|
+
}
|
|
197
|
+
function getPrimitiveType(schema) {
|
|
198
|
+
if (schema instanceof zod.z.ZodString) {
|
|
199
|
+
return "string";
|
|
200
|
+
}
|
|
201
|
+
if (schema instanceof zod.z.ZodNumber) {
|
|
202
|
+
return "number";
|
|
203
|
+
}
|
|
204
|
+
if (schema instanceof zod.z.ZodBoolean) {
|
|
205
|
+
return "boolean";
|
|
206
|
+
}
|
|
207
|
+
if (schema instanceof zod.z.ZodDate) {
|
|
208
|
+
return "Date";
|
|
209
|
+
}
|
|
210
|
+
if (schema instanceof zod.z.ZodEnum) {
|
|
211
|
+
return "string";
|
|
212
|
+
}
|
|
213
|
+
return null;
|
|
214
|
+
}
|
|
215
|
+
function getAcceptableValues(schema) {
|
|
216
|
+
if (schema instanceof zod.z.ZodEnum) {
|
|
217
|
+
return [...schema.options];
|
|
218
|
+
}
|
|
219
|
+
return null;
|
|
220
|
+
}
|
|
221
|
+
function generateRelations(definitions) {
|
|
222
|
+
const relations = [];
|
|
223
|
+
const entityMap = /* @__PURE__ */ new Map();
|
|
224
|
+
for (const def of definitions) {
|
|
225
|
+
entityMap.set(def.name, def);
|
|
226
|
+
}
|
|
227
|
+
for (const def of definitions) {
|
|
228
|
+
const referTos = [];
|
|
229
|
+
const referredBys = [];
|
|
230
|
+
for (const prop of def.properties) {
|
|
231
|
+
if (prop.isReference) {
|
|
232
|
+
referTos.push({
|
|
233
|
+
entityName: prop.targetEntityDefinitionName,
|
|
234
|
+
propertyName: prop.name,
|
|
235
|
+
isUnique: prop.isUnique
|
|
236
|
+
});
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
for (const otherDef of definitions) {
|
|
240
|
+
if (otherDef.name === def.name) {
|
|
241
|
+
continue;
|
|
242
|
+
}
|
|
243
|
+
for (const prop of otherDef.properties) {
|
|
244
|
+
if (prop.isReference && prop.targetEntityDefinitionName === def.name) {
|
|
245
|
+
referredBys.push({
|
|
246
|
+
entityName: otherDef.name,
|
|
247
|
+
propertyName: prop.name,
|
|
248
|
+
isUnique: prop.isUnique
|
|
249
|
+
});
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
relations.push({
|
|
254
|
+
entityName: def.name,
|
|
255
|
+
referTos,
|
|
256
|
+
referredBys
|
|
257
|
+
});
|
|
258
|
+
}
|
|
259
|
+
return relations;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
exports.entity = entity;
|
|
263
|
+
exports.generateEntities = generateEntities;
|
|
264
|
+
exports.generateRelations = generateRelations;
|
|
265
|
+
exports.struct = struct;
|
|
266
|
+
//# sourceMappingURL=index.js.map
|
|
267
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/setupZod.ts","../src/factories.ts","../src/generator.ts"],"names":["z","isNullable"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Extends Zod schemas with metadata methods using declaration merging\n */\nimport { z } from 'zod';\n\n// Symbols for metadata storage to avoid property name conflicts\nconst PK_SYMBOL = Symbol('zod-entity-pk');\nconst UNIQUE_SYMBOL = Symbol('zod-entity-unique');\nconst REF_SYMBOL = Symbol('zod-entity-ref');\n\nexport const METADATA_SYMBOLS = {\n PK: PK_SYMBOL,\n UNIQUE: UNIQUE_SYMBOL,\n REF: REF_SYMBOL,\n} as const;\n\nexport type RefMetadata = {\n targetEntity: z.ZodTypeAny;\n targetColumn: string;\n};\n\n// Declare module augmentation for Zod types\ndeclare module 'zod' {\n interface ZodType {\n [PK_SYMBOL]?: boolean;\n [UNIQUE_SYMBOL]?: boolean;\n [REF_SYMBOL]?: RefMetadata;\n\n pk(): this;\n unique(): this;\n ref(targetEntity: z.ZodTypeAny, targetColumn?: string): this;\n }\n}\n\n// Implement the methods on ZodType prototype\nz.ZodType.prototype.pk = function () {\n this[PK_SYMBOL] = true;\n return this;\n};\n\nz.ZodType.prototype.unique = function () {\n this[UNIQUE_SYMBOL] = true;\n return this;\n};\n\nz.ZodType.prototype.ref = function (targetEntity: z.ZodTypeAny, targetColumn = 'id') {\n this[REF_SYMBOL] = { targetEntity, targetColumn };\n return this;\n};\n\n/**\n * Helper functions to check metadata\n */\nexport function isPrimaryKey(schema: z.ZodTypeAny): boolean {\n return schema[PK_SYMBOL] === true;\n}\n\nexport function isUnique(schema: z.ZodTypeAny): boolean {\n return schema[UNIQUE_SYMBOL] === true;\n}\n\nexport function getRefMetadata(schema: z.ZodTypeAny): RefMetadata | undefined {\n return schema[REF_SYMBOL];\n}\n","/**\n * Factory functions for creating entity and struct schemas\n */\nimport { z } from 'zod';\n\n// Symbols for schema metadata\nconst SCHEMA_TYPE_SYMBOL = Symbol('zod-schema-type');\nconst SCHEMA_NAME_SYMBOL = Symbol('zod-schema-name');\nconst SCHEMA_DESCRIPTION_SYMBOL = Symbol('zod-schema-description');\n\nexport const SCHEMA_METADATA_SYMBOLS = {\n TYPE: SCHEMA_TYPE_SYMBOL,\n NAME: SCHEMA_NAME_SYMBOL,\n DESCRIPTION: SCHEMA_DESCRIPTION_SYMBOL,\n} as const;\n\nexport type EntityConfig<T extends z.ZodRawShape> = {\n name: string;\n description?: string;\n columns: T;\n};\n\nexport type StructConfig<T extends z.ZodRawShape> = {\n name: string;\n description?: string;\n columns: T;\n};\n\n// Augment ZodObject to store metadata\n// Note: Using bracket notation to add properties at runtime, avoiding type parameter conflicts\ntype ZodObjectWithMetadata = z.ZodObject<z.ZodRawShape> & {\n [SCHEMA_TYPE_SYMBOL]?: 'entity' | 'struct';\n [SCHEMA_NAME_SYMBOL]?: string;\n [SCHEMA_DESCRIPTION_SYMBOL]?: string;\n};\n\n// Branded type to carry entity name at type level\ndeclare const ENTITY_NAME_BRAND: unique symbol;\nexport type EntitySchema<\n TName extends string,\n TShape extends z.ZodRawShape,\n> = z.ZodObject<TShape> & {\n readonly [ENTITY_NAME_BRAND]: TName;\n};\n\n/**\n * Creates an entity schema with metadata\n */\nexport function entity<const TConfig extends EntityConfig<z.ZodRawShape>>(\n config: TConfig\n): EntitySchema<TConfig['name'], TConfig['columns']> {\n const schema = z.object(config.columns) as ZodObjectWithMetadata;\n schema[SCHEMA_TYPE_SYMBOL] = 'entity';\n schema[SCHEMA_NAME_SYMBOL] = config.name;\n if (config.description !== undefined) {\n schema[SCHEMA_DESCRIPTION_SYMBOL] = config.description;\n }\n return schema as EntitySchema<TConfig['name'], TConfig['columns']>;\n}\n\n/**\n * Creates a struct schema with metadata\n */\nexport function struct<T extends z.ZodRawShape>(config: StructConfig<T>): z.ZodObject<T> {\n const schema = z.object(config.columns) as ZodObjectWithMetadata;\n schema[SCHEMA_TYPE_SYMBOL] = 'struct';\n schema[SCHEMA_NAME_SYMBOL] = config.name;\n if (config.description !== undefined) {\n schema[SCHEMA_DESCRIPTION_SYMBOL] = config.description;\n }\n return schema as z.ZodObject<T>;\n}\n\n/**\n * Helper functions to check schema metadata\n */\nexport function getSchemaType(schema: z.ZodTypeAny): 'entity' | 'struct' | undefined {\n if (schema instanceof z.ZodObject) {\n return (schema as ZodObjectWithMetadata)[SCHEMA_TYPE_SYMBOL];\n }\n return undefined;\n}\n\nexport function getSchemaName(schema: z.ZodTypeAny): string | undefined {\n if (schema instanceof z.ZodObject) {\n return (schema as ZodObjectWithMetadata)[SCHEMA_NAME_SYMBOL];\n }\n return undefined;\n}\n\nexport function getSchemaDescription(schema: z.ZodTypeAny): string | undefined {\n if (schema instanceof z.ZodObject) {\n return (schema as ZodObjectWithMetadata)[SCHEMA_DESCRIPTION_SYMBOL];\n }\n return undefined;\n}\n","/**\n * Core generation logic for entity definitions and relations\n */\nimport { z } from 'zod';\nimport type { EntitySchema } from './factories';\nimport { getSchemaDescription, getSchemaName, getSchemaType } from './factories';\nimport { getRefMetadata, isPrimaryKey, isUnique } from './setupZod';\nimport type {\n EntityDefinition,\n EntityPropertyDefinition,\n EntityPropertyDefinitionPrimaryKey,\n EntityPropertyDefinitionPrimitive,\n EntityPropertyDefinitionReferencedObject,\n EntityPropertyDefinitionTypedStruct,\n EntityRelation,\n EntityRelationReferTo,\n EntityRelationReferredBy,\n} from './types';\n\n/**\n * Helper type to extract entity name from a single EntitySchema\n *\n * For example: EntitySchema<'User', {...}> => 'User'\n * For non-EntitySchema types, returns never\n */\ntype ExtractEntityName<T> = T extends EntitySchema<infer TName, z.ZodRawShape> ? TName : never;\n\n/**\n * Helper type to extract entity names from an array of schemas\n *\n * This transforms an array of EntitySchema types into a union of their names.\n * For example: [EntitySchema<'User', ...>, EntitySchema<'Company', ...>] => 'User' | 'Company'\n *\n * The pattern works by:\n * 1. Mapping over the array type to extract each entity name\n * 2. Using [number] to create a union of all extracted names\n */\ntype ExtractEntityNames<T extends readonly z.ZodTypeAny[]> = {\n [K in keyof T]: ExtractEntityName<T[K]>;\n}[number];\n\n/**\n * Unwraps a Zod schema to get the innermost type\n * Handles z.optional, z.nullable, z.array\n */\ntype UnwrapResult = {\n innerSchema: z.ZodTypeAny;\n isNullable: boolean;\n isArray: boolean;\n};\n\nfunction unwrapSchema(schema: z.ZodTypeAny): UnwrapResult {\n let current = schema;\n let isNullable = false;\n let isArray = false;\n\n // Unwrap layers\n while (true) {\n if (current instanceof z.ZodOptional) {\n isNullable = true;\n current = current.unwrap() as z.ZodTypeAny;\n } else if (current instanceof z.ZodNullable) {\n isNullable = true;\n current = current.unwrap() as z.ZodTypeAny;\n } else if (current instanceof z.ZodArray) {\n isArray = true;\n current = current.element as z.ZodTypeAny;\n } else {\n break;\n }\n }\n\n return { innerSchema: current, isNullable, isArray };\n}\n\n/**\n * Generates entity definitions from Zod schemas\n */\nexport function generateEntities<const T extends readonly z.ZodTypeAny[]>(\n schemas: T\n): EntityDefinition<ExtractEntityNames<T>>[] {\n const definitions: EntityDefinition[] = [];\n\n for (const schema of schemas) {\n const schemaType = getSchemaType(schema);\n\n // Only process entity schemas\n if (schemaType !== 'entity') {\n continue;\n }\n\n const name = getSchemaName(schema);\n if (name === undefined) {\n throw new Error('Entity schema must have a name');\n }\n\n const description = getSchemaDescription(schema);\n\n if (!(schema instanceof z.ZodObject)) {\n throw new Error(`Entity \"${name}\" must be a ZodObject`);\n }\n\n const properties: EntityPropertyDefinition[] = [];\n const shape = schema.shape;\n\n for (const [fieldName, fieldSchema] of Object.entries(shape)) {\n if (!(fieldSchema instanceof z.ZodType)) {\n continue;\n }\n\n const property = parseProperty(fieldName, fieldSchema);\n properties.push(property);\n }\n\n const entityDefinition: EntityDefinition = {\n name,\n properties,\n };\n if (description !== undefined) {\n entityDefinition.description = description;\n }\n definitions.push(entityDefinition);\n }\n\n return definitions as EntityDefinition<ExtractEntityNames<T>>[];\n}\n\n/**\n * Parses a single property from a Zod schema\n */\nfunction parseProperty(fieldName: string, fieldSchema: z.ZodTypeAny): EntityPropertyDefinition {\n const isPk = isPrimaryKey(fieldSchema);\n const isUniqueField = isUnique(fieldSchema);\n const refMetadata = getRefMetadata(fieldSchema);\n\n // Handle Primary Key\n if (isPk) {\n const property: EntityPropertyDefinitionPrimaryKey = {\n isReference: false,\n propertyType: 'PrimaryKey',\n name: fieldName,\n };\n return property;\n }\n\n // Handle Foreign Key Reference\n if (refMetadata !== undefined) {\n const { targetEntity } = refMetadata;\n\n // Validate that targetEntity is an entity\n const targetSchemaType = getSchemaType(targetEntity);\n if (targetSchemaType !== 'entity') {\n throw new Error(\n `Field \"${fieldName}\" has .ref() pointing to a non-entity schema. Only entity schemas created with entity() can be referenced.`\n );\n }\n\n const targetEntityName = getSchemaName(targetEntity);\n if (targetEntityName === undefined) {\n throw new Error(`Referenced entity for field \"${fieldName}\" must have a name`);\n }\n\n const { isNullable } = unwrapSchema(fieldSchema);\n\n const property: EntityPropertyDefinitionReferencedObject = {\n isReference: true,\n name: fieldName,\n targetEntityDefinitionName: targetEntityName,\n isUnique: isUniqueField,\n isNullable,\n };\n return property;\n }\n\n // Unwrap the schema\n const { innerSchema, isNullable, isArray } = unwrapSchema(fieldSchema);\n\n // Check if inner schema is an entity (not allowed)\n const innerSchemaType = getSchemaType(innerSchema);\n if (innerSchemaType === 'entity') {\n throw new Error(\n `Field \"${fieldName}\" contains a direct entity embedding. Entities cannot be directly nested. Use .ref() instead.`\n );\n }\n\n // Handle struct\n if (innerSchemaType === 'struct') {\n const structName = getSchemaName(innerSchema);\n if (structName === undefined) {\n throw new Error(`Struct schema for field \"${fieldName}\" must have a name`);\n }\n\n const property: EntityPropertyDefinitionTypedStruct = {\n isReference: false,\n propertyType: 'typedStruct',\n name: fieldName,\n structTypeName: structName,\n isUnique: isUniqueField,\n isNullable,\n isArray,\n };\n return property;\n }\n\n // Handle primitives\n const primitiveType = getPrimitiveType(innerSchema);\n if (primitiveType !== null) {\n const acceptableValues = getAcceptableValues(innerSchema);\n\n const property: EntityPropertyDefinitionPrimitive = {\n isReference: false,\n propertyType: primitiveType,\n name: fieldName,\n isUnique: isUniqueField,\n isNullable,\n isArray,\n acceptableValues,\n };\n return property;\n }\n\n throw new Error(`Unsupported schema type for field \"${fieldName}\"`);\n}\n\n/**\n * Determines the primitive type from a Zod schema\n */\nfunction getPrimitiveType(schema: z.ZodTypeAny): 'boolean' | 'number' | 'string' | 'Date' | null {\n if (schema instanceof z.ZodString) {\n return 'string';\n }\n if (schema instanceof z.ZodNumber) {\n return 'number';\n }\n if (schema instanceof z.ZodBoolean) {\n return 'boolean';\n }\n if (schema instanceof z.ZodDate) {\n return 'Date';\n }\n if (schema instanceof z.ZodEnum) {\n return 'string';\n }\n return null;\n}\n\n/**\n * Extracts acceptable values from z.enum\n */\nfunction getAcceptableValues(schema: z.ZodTypeAny): string[] | null {\n if (schema instanceof z.ZodEnum) {\n return [...schema.options] as string[];\n }\n return null;\n}\n\n/**\n * Generates relations from entity definitions\n */\nexport function generateRelations(definitions: EntityDefinition[]): EntityRelation[] {\n const relations: EntityRelation[] = [];\n\n // Build a map for quick lookup\n const entityMap = new Map<string, EntityDefinition>();\n for (const def of definitions) {\n entityMap.set(def.name, def);\n }\n\n // Initialize relations for each entity\n for (const def of definitions) {\n const referTos: EntityRelationReferTo[] = [];\n const referredBys: EntityRelationReferredBy[] = [];\n\n // Find referTos (outgoing references)\n for (const prop of def.properties) {\n if (prop.isReference) {\n referTos.push({\n entityName: prop.targetEntityDefinitionName,\n propertyName: prop.name,\n isUnique: prop.isUnique,\n });\n }\n }\n\n // Find referredBys (incoming references)\n for (const otherDef of definitions) {\n if (otherDef.name === def.name) {\n continue;\n }\n\n for (const prop of otherDef.properties) {\n if (prop.isReference && prop.targetEntityDefinitionName === def.name) {\n referredBys.push({\n entityName: otherDef.name,\n propertyName: prop.name,\n isUnique: prop.isUnique,\n });\n }\n }\n }\n\n relations.push({\n entityName: def.name,\n referTos,\n referredBys,\n });\n }\n\n return relations;\n}\n"]}
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
|
|
3
|
+
// src/setupZod.ts
|
|
4
|
+
var PK_SYMBOL = Symbol("zod-entity-pk");
|
|
5
|
+
var UNIQUE_SYMBOL = Symbol("zod-entity-unique");
|
|
6
|
+
var REF_SYMBOL = Symbol("zod-entity-ref");
|
|
7
|
+
z.ZodType.prototype.pk = function() {
|
|
8
|
+
this[PK_SYMBOL] = true;
|
|
9
|
+
return this;
|
|
10
|
+
};
|
|
11
|
+
z.ZodType.prototype.unique = function() {
|
|
12
|
+
this[UNIQUE_SYMBOL] = true;
|
|
13
|
+
return this;
|
|
14
|
+
};
|
|
15
|
+
z.ZodType.prototype.ref = function(targetEntity, targetColumn = "id") {
|
|
16
|
+
this[REF_SYMBOL] = { targetEntity, targetColumn };
|
|
17
|
+
return this;
|
|
18
|
+
};
|
|
19
|
+
function isPrimaryKey(schema) {
|
|
20
|
+
return schema[PK_SYMBOL] === true;
|
|
21
|
+
}
|
|
22
|
+
function isUnique(schema) {
|
|
23
|
+
return schema[UNIQUE_SYMBOL] === true;
|
|
24
|
+
}
|
|
25
|
+
function getRefMetadata(schema) {
|
|
26
|
+
return schema[REF_SYMBOL];
|
|
27
|
+
}
|
|
28
|
+
var SCHEMA_TYPE_SYMBOL = Symbol("zod-schema-type");
|
|
29
|
+
var SCHEMA_NAME_SYMBOL = Symbol("zod-schema-name");
|
|
30
|
+
var SCHEMA_DESCRIPTION_SYMBOL = Symbol("zod-schema-description");
|
|
31
|
+
function entity(config) {
|
|
32
|
+
const schema = z.object(config.columns);
|
|
33
|
+
schema[SCHEMA_TYPE_SYMBOL] = "entity";
|
|
34
|
+
schema[SCHEMA_NAME_SYMBOL] = config.name;
|
|
35
|
+
if (config.description !== void 0) {
|
|
36
|
+
schema[SCHEMA_DESCRIPTION_SYMBOL] = config.description;
|
|
37
|
+
}
|
|
38
|
+
return schema;
|
|
39
|
+
}
|
|
40
|
+
function struct(config) {
|
|
41
|
+
const schema = z.object(config.columns);
|
|
42
|
+
schema[SCHEMA_TYPE_SYMBOL] = "struct";
|
|
43
|
+
schema[SCHEMA_NAME_SYMBOL] = config.name;
|
|
44
|
+
if (config.description !== void 0) {
|
|
45
|
+
schema[SCHEMA_DESCRIPTION_SYMBOL] = config.description;
|
|
46
|
+
}
|
|
47
|
+
return schema;
|
|
48
|
+
}
|
|
49
|
+
function getSchemaType(schema) {
|
|
50
|
+
if (schema instanceof z.ZodObject) {
|
|
51
|
+
return schema[SCHEMA_TYPE_SYMBOL];
|
|
52
|
+
}
|
|
53
|
+
return void 0;
|
|
54
|
+
}
|
|
55
|
+
function getSchemaName(schema) {
|
|
56
|
+
if (schema instanceof z.ZodObject) {
|
|
57
|
+
return schema[SCHEMA_NAME_SYMBOL];
|
|
58
|
+
}
|
|
59
|
+
return void 0;
|
|
60
|
+
}
|
|
61
|
+
function getSchemaDescription(schema) {
|
|
62
|
+
if (schema instanceof z.ZodObject) {
|
|
63
|
+
return schema[SCHEMA_DESCRIPTION_SYMBOL];
|
|
64
|
+
}
|
|
65
|
+
return void 0;
|
|
66
|
+
}
|
|
67
|
+
function unwrapSchema(schema) {
|
|
68
|
+
let current = schema;
|
|
69
|
+
let isNullable = false;
|
|
70
|
+
let isArray = false;
|
|
71
|
+
while (true) {
|
|
72
|
+
if (current instanceof z.ZodOptional) {
|
|
73
|
+
isNullable = true;
|
|
74
|
+
current = current.unwrap();
|
|
75
|
+
} else if (current instanceof z.ZodNullable) {
|
|
76
|
+
isNullable = true;
|
|
77
|
+
current = current.unwrap();
|
|
78
|
+
} else if (current instanceof z.ZodArray) {
|
|
79
|
+
isArray = true;
|
|
80
|
+
current = current.element;
|
|
81
|
+
} else {
|
|
82
|
+
break;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
return { innerSchema: current, isNullable, isArray };
|
|
86
|
+
}
|
|
87
|
+
function generateEntities(schemas) {
|
|
88
|
+
const definitions = [];
|
|
89
|
+
for (const schema of schemas) {
|
|
90
|
+
const schemaType = getSchemaType(schema);
|
|
91
|
+
if (schemaType !== "entity") {
|
|
92
|
+
continue;
|
|
93
|
+
}
|
|
94
|
+
const name = getSchemaName(schema);
|
|
95
|
+
if (name === void 0) {
|
|
96
|
+
throw new Error("Entity schema must have a name");
|
|
97
|
+
}
|
|
98
|
+
const description = getSchemaDescription(schema);
|
|
99
|
+
if (!(schema instanceof z.ZodObject)) {
|
|
100
|
+
throw new Error(`Entity "${name}" must be a ZodObject`);
|
|
101
|
+
}
|
|
102
|
+
const properties = [];
|
|
103
|
+
const shape = schema.shape;
|
|
104
|
+
for (const [fieldName, fieldSchema] of Object.entries(shape)) {
|
|
105
|
+
if (!(fieldSchema instanceof z.ZodType)) {
|
|
106
|
+
continue;
|
|
107
|
+
}
|
|
108
|
+
const property = parseProperty(fieldName, fieldSchema);
|
|
109
|
+
properties.push(property);
|
|
110
|
+
}
|
|
111
|
+
const entityDefinition = {
|
|
112
|
+
name,
|
|
113
|
+
properties
|
|
114
|
+
};
|
|
115
|
+
if (description !== void 0) {
|
|
116
|
+
entityDefinition.description = description;
|
|
117
|
+
}
|
|
118
|
+
definitions.push(entityDefinition);
|
|
119
|
+
}
|
|
120
|
+
return definitions;
|
|
121
|
+
}
|
|
122
|
+
function parseProperty(fieldName, fieldSchema) {
|
|
123
|
+
const isPk = isPrimaryKey(fieldSchema);
|
|
124
|
+
const isUniqueField = isUnique(fieldSchema);
|
|
125
|
+
const refMetadata = getRefMetadata(fieldSchema);
|
|
126
|
+
if (isPk) {
|
|
127
|
+
const property = {
|
|
128
|
+
isReference: false,
|
|
129
|
+
propertyType: "PrimaryKey",
|
|
130
|
+
name: fieldName
|
|
131
|
+
};
|
|
132
|
+
return property;
|
|
133
|
+
}
|
|
134
|
+
if (refMetadata !== void 0) {
|
|
135
|
+
const { targetEntity } = refMetadata;
|
|
136
|
+
const targetSchemaType = getSchemaType(targetEntity);
|
|
137
|
+
if (targetSchemaType !== "entity") {
|
|
138
|
+
throw new Error(
|
|
139
|
+
`Field "${fieldName}" has .ref() pointing to a non-entity schema. Only entity schemas created with entity() can be referenced.`
|
|
140
|
+
);
|
|
141
|
+
}
|
|
142
|
+
const targetEntityName = getSchemaName(targetEntity);
|
|
143
|
+
if (targetEntityName === void 0) {
|
|
144
|
+
throw new Error(`Referenced entity for field "${fieldName}" must have a name`);
|
|
145
|
+
}
|
|
146
|
+
const { isNullable: isNullable2 } = unwrapSchema(fieldSchema);
|
|
147
|
+
const property = {
|
|
148
|
+
isReference: true,
|
|
149
|
+
name: fieldName,
|
|
150
|
+
targetEntityDefinitionName: targetEntityName,
|
|
151
|
+
isUnique: isUniqueField,
|
|
152
|
+
isNullable: isNullable2
|
|
153
|
+
};
|
|
154
|
+
return property;
|
|
155
|
+
}
|
|
156
|
+
const { innerSchema, isNullable, isArray } = unwrapSchema(fieldSchema);
|
|
157
|
+
const innerSchemaType = getSchemaType(innerSchema);
|
|
158
|
+
if (innerSchemaType === "entity") {
|
|
159
|
+
throw new Error(
|
|
160
|
+
`Field "${fieldName}" contains a direct entity embedding. Entities cannot be directly nested. Use .ref() instead.`
|
|
161
|
+
);
|
|
162
|
+
}
|
|
163
|
+
if (innerSchemaType === "struct") {
|
|
164
|
+
const structName = getSchemaName(innerSchema);
|
|
165
|
+
if (structName === void 0) {
|
|
166
|
+
throw new Error(`Struct schema for field "${fieldName}" must have a name`);
|
|
167
|
+
}
|
|
168
|
+
const property = {
|
|
169
|
+
isReference: false,
|
|
170
|
+
propertyType: "typedStruct",
|
|
171
|
+
name: fieldName,
|
|
172
|
+
structTypeName: structName,
|
|
173
|
+
isUnique: isUniqueField,
|
|
174
|
+
isNullable,
|
|
175
|
+
isArray
|
|
176
|
+
};
|
|
177
|
+
return property;
|
|
178
|
+
}
|
|
179
|
+
const primitiveType = getPrimitiveType(innerSchema);
|
|
180
|
+
if (primitiveType !== null) {
|
|
181
|
+
const acceptableValues = getAcceptableValues(innerSchema);
|
|
182
|
+
const property = {
|
|
183
|
+
isReference: false,
|
|
184
|
+
propertyType: primitiveType,
|
|
185
|
+
name: fieldName,
|
|
186
|
+
isUnique: isUniqueField,
|
|
187
|
+
isNullable,
|
|
188
|
+
isArray,
|
|
189
|
+
acceptableValues
|
|
190
|
+
};
|
|
191
|
+
return property;
|
|
192
|
+
}
|
|
193
|
+
throw new Error(`Unsupported schema type for field "${fieldName}"`);
|
|
194
|
+
}
|
|
195
|
+
function getPrimitiveType(schema) {
|
|
196
|
+
if (schema instanceof z.ZodString) {
|
|
197
|
+
return "string";
|
|
198
|
+
}
|
|
199
|
+
if (schema instanceof z.ZodNumber) {
|
|
200
|
+
return "number";
|
|
201
|
+
}
|
|
202
|
+
if (schema instanceof z.ZodBoolean) {
|
|
203
|
+
return "boolean";
|
|
204
|
+
}
|
|
205
|
+
if (schema instanceof z.ZodDate) {
|
|
206
|
+
return "Date";
|
|
207
|
+
}
|
|
208
|
+
if (schema instanceof z.ZodEnum) {
|
|
209
|
+
return "string";
|
|
210
|
+
}
|
|
211
|
+
return null;
|
|
212
|
+
}
|
|
213
|
+
function getAcceptableValues(schema) {
|
|
214
|
+
if (schema instanceof z.ZodEnum) {
|
|
215
|
+
return [...schema.options];
|
|
216
|
+
}
|
|
217
|
+
return null;
|
|
218
|
+
}
|
|
219
|
+
function generateRelations(definitions) {
|
|
220
|
+
const relations = [];
|
|
221
|
+
const entityMap = /* @__PURE__ */ new Map();
|
|
222
|
+
for (const def of definitions) {
|
|
223
|
+
entityMap.set(def.name, def);
|
|
224
|
+
}
|
|
225
|
+
for (const def of definitions) {
|
|
226
|
+
const referTos = [];
|
|
227
|
+
const referredBys = [];
|
|
228
|
+
for (const prop of def.properties) {
|
|
229
|
+
if (prop.isReference) {
|
|
230
|
+
referTos.push({
|
|
231
|
+
entityName: prop.targetEntityDefinitionName,
|
|
232
|
+
propertyName: prop.name,
|
|
233
|
+
isUnique: prop.isUnique
|
|
234
|
+
});
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
for (const otherDef of definitions) {
|
|
238
|
+
if (otherDef.name === def.name) {
|
|
239
|
+
continue;
|
|
240
|
+
}
|
|
241
|
+
for (const prop of otherDef.properties) {
|
|
242
|
+
if (prop.isReference && prop.targetEntityDefinitionName === def.name) {
|
|
243
|
+
referredBys.push({
|
|
244
|
+
entityName: otherDef.name,
|
|
245
|
+
propertyName: prop.name,
|
|
246
|
+
isUnique: prop.isUnique
|
|
247
|
+
});
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
relations.push({
|
|
252
|
+
entityName: def.name,
|
|
253
|
+
referTos,
|
|
254
|
+
referredBys
|
|
255
|
+
});
|
|
256
|
+
}
|
|
257
|
+
return relations;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
export { entity, generateEntities, generateRelations, struct };
|
|
261
|
+
//# sourceMappingURL=index.mjs.map
|
|
262
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/setupZod.ts","../src/factories.ts","../src/generator.ts"],"names":["z","isNullable"],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * Extends Zod schemas with metadata methods using declaration merging\n */\nimport { z } from 'zod';\n\n// Symbols for metadata storage to avoid property name conflicts\nconst PK_SYMBOL = Symbol('zod-entity-pk');\nconst UNIQUE_SYMBOL = Symbol('zod-entity-unique');\nconst REF_SYMBOL = Symbol('zod-entity-ref');\n\nexport const METADATA_SYMBOLS = {\n PK: PK_SYMBOL,\n UNIQUE: UNIQUE_SYMBOL,\n REF: REF_SYMBOL,\n} as const;\n\nexport type RefMetadata = {\n targetEntity: z.ZodTypeAny;\n targetColumn: string;\n};\n\n// Declare module augmentation for Zod types\ndeclare module 'zod' {\n interface ZodType {\n [PK_SYMBOL]?: boolean;\n [UNIQUE_SYMBOL]?: boolean;\n [REF_SYMBOL]?: RefMetadata;\n\n pk(): this;\n unique(): this;\n ref(targetEntity: z.ZodTypeAny, targetColumn?: string): this;\n }\n}\n\n// Implement the methods on ZodType prototype\nz.ZodType.prototype.pk = function () {\n this[PK_SYMBOL] = true;\n return this;\n};\n\nz.ZodType.prototype.unique = function () {\n this[UNIQUE_SYMBOL] = true;\n return this;\n};\n\nz.ZodType.prototype.ref = function (targetEntity: z.ZodTypeAny, targetColumn = 'id') {\n this[REF_SYMBOL] = { targetEntity, targetColumn };\n return this;\n};\n\n/**\n * Helper functions to check metadata\n */\nexport function isPrimaryKey(schema: z.ZodTypeAny): boolean {\n return schema[PK_SYMBOL] === true;\n}\n\nexport function isUnique(schema: z.ZodTypeAny): boolean {\n return schema[UNIQUE_SYMBOL] === true;\n}\n\nexport function getRefMetadata(schema: z.ZodTypeAny): RefMetadata | undefined {\n return schema[REF_SYMBOL];\n}\n","/**\n * Factory functions for creating entity and struct schemas\n */\nimport { z } from 'zod';\n\n// Symbols for schema metadata\nconst SCHEMA_TYPE_SYMBOL = Symbol('zod-schema-type');\nconst SCHEMA_NAME_SYMBOL = Symbol('zod-schema-name');\nconst SCHEMA_DESCRIPTION_SYMBOL = Symbol('zod-schema-description');\n\nexport const SCHEMA_METADATA_SYMBOLS = {\n TYPE: SCHEMA_TYPE_SYMBOL,\n NAME: SCHEMA_NAME_SYMBOL,\n DESCRIPTION: SCHEMA_DESCRIPTION_SYMBOL,\n} as const;\n\nexport type EntityConfig<T extends z.ZodRawShape> = {\n name: string;\n description?: string;\n columns: T;\n};\n\nexport type StructConfig<T extends z.ZodRawShape> = {\n name: string;\n description?: string;\n columns: T;\n};\n\n// Augment ZodObject to store metadata\n// Note: Using bracket notation to add properties at runtime, avoiding type parameter conflicts\ntype ZodObjectWithMetadata = z.ZodObject<z.ZodRawShape> & {\n [SCHEMA_TYPE_SYMBOL]?: 'entity' | 'struct';\n [SCHEMA_NAME_SYMBOL]?: string;\n [SCHEMA_DESCRIPTION_SYMBOL]?: string;\n};\n\n// Branded type to carry entity name at type level\ndeclare const ENTITY_NAME_BRAND: unique symbol;\nexport type EntitySchema<\n TName extends string,\n TShape extends z.ZodRawShape,\n> = z.ZodObject<TShape> & {\n readonly [ENTITY_NAME_BRAND]: TName;\n};\n\n/**\n * Creates an entity schema with metadata\n */\nexport function entity<const TConfig extends EntityConfig<z.ZodRawShape>>(\n config: TConfig\n): EntitySchema<TConfig['name'], TConfig['columns']> {\n const schema = z.object(config.columns) as ZodObjectWithMetadata;\n schema[SCHEMA_TYPE_SYMBOL] = 'entity';\n schema[SCHEMA_NAME_SYMBOL] = config.name;\n if (config.description !== undefined) {\n schema[SCHEMA_DESCRIPTION_SYMBOL] = config.description;\n }\n return schema as EntitySchema<TConfig['name'], TConfig['columns']>;\n}\n\n/**\n * Creates a struct schema with metadata\n */\nexport function struct<T extends z.ZodRawShape>(config: StructConfig<T>): z.ZodObject<T> {\n const schema = z.object(config.columns) as ZodObjectWithMetadata;\n schema[SCHEMA_TYPE_SYMBOL] = 'struct';\n schema[SCHEMA_NAME_SYMBOL] = config.name;\n if (config.description !== undefined) {\n schema[SCHEMA_DESCRIPTION_SYMBOL] = config.description;\n }\n return schema as z.ZodObject<T>;\n}\n\n/**\n * Helper functions to check schema metadata\n */\nexport function getSchemaType(schema: z.ZodTypeAny): 'entity' | 'struct' | undefined {\n if (schema instanceof z.ZodObject) {\n return (schema as ZodObjectWithMetadata)[SCHEMA_TYPE_SYMBOL];\n }\n return undefined;\n}\n\nexport function getSchemaName(schema: z.ZodTypeAny): string | undefined {\n if (schema instanceof z.ZodObject) {\n return (schema as ZodObjectWithMetadata)[SCHEMA_NAME_SYMBOL];\n }\n return undefined;\n}\n\nexport function getSchemaDescription(schema: z.ZodTypeAny): string | undefined {\n if (schema instanceof z.ZodObject) {\n return (schema as ZodObjectWithMetadata)[SCHEMA_DESCRIPTION_SYMBOL];\n }\n return undefined;\n}\n","/**\n * Core generation logic for entity definitions and relations\n */\nimport { z } from 'zod';\nimport type { EntitySchema } from './factories';\nimport { getSchemaDescription, getSchemaName, getSchemaType } from './factories';\nimport { getRefMetadata, isPrimaryKey, isUnique } from './setupZod';\nimport type {\n EntityDefinition,\n EntityPropertyDefinition,\n EntityPropertyDefinitionPrimaryKey,\n EntityPropertyDefinitionPrimitive,\n EntityPropertyDefinitionReferencedObject,\n EntityPropertyDefinitionTypedStruct,\n EntityRelation,\n EntityRelationReferTo,\n EntityRelationReferredBy,\n} from './types';\n\n/**\n * Helper type to extract entity name from a single EntitySchema\n *\n * For example: EntitySchema<'User', {...}> => 'User'\n * For non-EntitySchema types, returns never\n */\ntype ExtractEntityName<T> = T extends EntitySchema<infer TName, z.ZodRawShape> ? TName : never;\n\n/**\n * Helper type to extract entity names from an array of schemas\n *\n * This transforms an array of EntitySchema types into a union of their names.\n * For example: [EntitySchema<'User', ...>, EntitySchema<'Company', ...>] => 'User' | 'Company'\n *\n * The pattern works by:\n * 1. Mapping over the array type to extract each entity name\n * 2. Using [number] to create a union of all extracted names\n */\ntype ExtractEntityNames<T extends readonly z.ZodTypeAny[]> = {\n [K in keyof T]: ExtractEntityName<T[K]>;\n}[number];\n\n/**\n * Unwraps a Zod schema to get the innermost type\n * Handles z.optional, z.nullable, z.array\n */\ntype UnwrapResult = {\n innerSchema: z.ZodTypeAny;\n isNullable: boolean;\n isArray: boolean;\n};\n\nfunction unwrapSchema(schema: z.ZodTypeAny): UnwrapResult {\n let current = schema;\n let isNullable = false;\n let isArray = false;\n\n // Unwrap layers\n while (true) {\n if (current instanceof z.ZodOptional) {\n isNullable = true;\n current = current.unwrap() as z.ZodTypeAny;\n } else if (current instanceof z.ZodNullable) {\n isNullable = true;\n current = current.unwrap() as z.ZodTypeAny;\n } else if (current instanceof z.ZodArray) {\n isArray = true;\n current = current.element as z.ZodTypeAny;\n } else {\n break;\n }\n }\n\n return { innerSchema: current, isNullable, isArray };\n}\n\n/**\n * Generates entity definitions from Zod schemas\n */\nexport function generateEntities<const T extends readonly z.ZodTypeAny[]>(\n schemas: T\n): EntityDefinition<ExtractEntityNames<T>>[] {\n const definitions: EntityDefinition[] = [];\n\n for (const schema of schemas) {\n const schemaType = getSchemaType(schema);\n\n // Only process entity schemas\n if (schemaType !== 'entity') {\n continue;\n }\n\n const name = getSchemaName(schema);\n if (name === undefined) {\n throw new Error('Entity schema must have a name');\n }\n\n const description = getSchemaDescription(schema);\n\n if (!(schema instanceof z.ZodObject)) {\n throw new Error(`Entity \"${name}\" must be a ZodObject`);\n }\n\n const properties: EntityPropertyDefinition[] = [];\n const shape = schema.shape;\n\n for (const [fieldName, fieldSchema] of Object.entries(shape)) {\n if (!(fieldSchema instanceof z.ZodType)) {\n continue;\n }\n\n const property = parseProperty(fieldName, fieldSchema);\n properties.push(property);\n }\n\n const entityDefinition: EntityDefinition = {\n name,\n properties,\n };\n if (description !== undefined) {\n entityDefinition.description = description;\n }\n definitions.push(entityDefinition);\n }\n\n return definitions as EntityDefinition<ExtractEntityNames<T>>[];\n}\n\n/**\n * Parses a single property from a Zod schema\n */\nfunction parseProperty(fieldName: string, fieldSchema: z.ZodTypeAny): EntityPropertyDefinition {\n const isPk = isPrimaryKey(fieldSchema);\n const isUniqueField = isUnique(fieldSchema);\n const refMetadata = getRefMetadata(fieldSchema);\n\n // Handle Primary Key\n if (isPk) {\n const property: EntityPropertyDefinitionPrimaryKey = {\n isReference: false,\n propertyType: 'PrimaryKey',\n name: fieldName,\n };\n return property;\n }\n\n // Handle Foreign Key Reference\n if (refMetadata !== undefined) {\n const { targetEntity } = refMetadata;\n\n // Validate that targetEntity is an entity\n const targetSchemaType = getSchemaType(targetEntity);\n if (targetSchemaType !== 'entity') {\n throw new Error(\n `Field \"${fieldName}\" has .ref() pointing to a non-entity schema. Only entity schemas created with entity() can be referenced.`\n );\n }\n\n const targetEntityName = getSchemaName(targetEntity);\n if (targetEntityName === undefined) {\n throw new Error(`Referenced entity for field \"${fieldName}\" must have a name`);\n }\n\n const { isNullable } = unwrapSchema(fieldSchema);\n\n const property: EntityPropertyDefinitionReferencedObject = {\n isReference: true,\n name: fieldName,\n targetEntityDefinitionName: targetEntityName,\n isUnique: isUniqueField,\n isNullable,\n };\n return property;\n }\n\n // Unwrap the schema\n const { innerSchema, isNullable, isArray } = unwrapSchema(fieldSchema);\n\n // Check if inner schema is an entity (not allowed)\n const innerSchemaType = getSchemaType(innerSchema);\n if (innerSchemaType === 'entity') {\n throw new Error(\n `Field \"${fieldName}\" contains a direct entity embedding. Entities cannot be directly nested. Use .ref() instead.`\n );\n }\n\n // Handle struct\n if (innerSchemaType === 'struct') {\n const structName = getSchemaName(innerSchema);\n if (structName === undefined) {\n throw new Error(`Struct schema for field \"${fieldName}\" must have a name`);\n }\n\n const property: EntityPropertyDefinitionTypedStruct = {\n isReference: false,\n propertyType: 'typedStruct',\n name: fieldName,\n structTypeName: structName,\n isUnique: isUniqueField,\n isNullable,\n isArray,\n };\n return property;\n }\n\n // Handle primitives\n const primitiveType = getPrimitiveType(innerSchema);\n if (primitiveType !== null) {\n const acceptableValues = getAcceptableValues(innerSchema);\n\n const property: EntityPropertyDefinitionPrimitive = {\n isReference: false,\n propertyType: primitiveType,\n name: fieldName,\n isUnique: isUniqueField,\n isNullable,\n isArray,\n acceptableValues,\n };\n return property;\n }\n\n throw new Error(`Unsupported schema type for field \"${fieldName}\"`);\n}\n\n/**\n * Determines the primitive type from a Zod schema\n */\nfunction getPrimitiveType(schema: z.ZodTypeAny): 'boolean' | 'number' | 'string' | 'Date' | null {\n if (schema instanceof z.ZodString) {\n return 'string';\n }\n if (schema instanceof z.ZodNumber) {\n return 'number';\n }\n if (schema instanceof z.ZodBoolean) {\n return 'boolean';\n }\n if (schema instanceof z.ZodDate) {\n return 'Date';\n }\n if (schema instanceof z.ZodEnum) {\n return 'string';\n }\n return null;\n}\n\n/**\n * Extracts acceptable values from z.enum\n */\nfunction getAcceptableValues(schema: z.ZodTypeAny): string[] | null {\n if (schema instanceof z.ZodEnum) {\n return [...schema.options] as string[];\n }\n return null;\n}\n\n/**\n * Generates relations from entity definitions\n */\nexport function generateRelations(definitions: EntityDefinition[]): EntityRelation[] {\n const relations: EntityRelation[] = [];\n\n // Build a map for quick lookup\n const entityMap = new Map<string, EntityDefinition>();\n for (const def of definitions) {\n entityMap.set(def.name, def);\n }\n\n // Initialize relations for each entity\n for (const def of definitions) {\n const referTos: EntityRelationReferTo[] = [];\n const referredBys: EntityRelationReferredBy[] = [];\n\n // Find referTos (outgoing references)\n for (const prop of def.properties) {\n if (prop.isReference) {\n referTos.push({\n entityName: prop.targetEntityDefinitionName,\n propertyName: prop.name,\n isUnique: prop.isUnique,\n });\n }\n }\n\n // Find referredBys (incoming references)\n for (const otherDef of definitions) {\n if (otherDef.name === def.name) {\n continue;\n }\n\n for (const prop of otherDef.properties) {\n if (prop.isReference && prop.targetEntityDefinitionName === def.name) {\n referredBys.push({\n entityName: otherDef.name,\n propertyName: prop.name,\n isUnique: prop.isUnique,\n });\n }\n }\n }\n\n relations.push({\n entityName: def.name,\n referTos,\n referredBys,\n });\n }\n\n return relations;\n}\n"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@masaori/zod-to-entity-definitions",
|
|
3
|
+
"version": "1.1.7",
|
|
4
|
+
"description": "A library to define data models using Zod with extended metadata and convert them into framework-agnostic Entity Definitions",
|
|
5
|
+
"main": "./dist/index.js",
|
|
6
|
+
"module": "./dist/index.mjs",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.mjs",
|
|
12
|
+
"require": "./dist/index.js"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"dist"
|
|
17
|
+
],
|
|
18
|
+
"scripts": {
|
|
19
|
+
"build": "tsup",
|
|
20
|
+
"dev": "tsup --watch",
|
|
21
|
+
"test": "vitest run",
|
|
22
|
+
"test:watch": "vitest",
|
|
23
|
+
"lint": "biome check .",
|
|
24
|
+
"fix": "biome check --write .",
|
|
25
|
+
"format": "biome format --write .",
|
|
26
|
+
"check-types": "tsc --noEmit",
|
|
27
|
+
"prepublishOnly": "npm run check-types && npm run lint && npm run test && npm run build"
|
|
28
|
+
},
|
|
29
|
+
"keywords": [
|
|
30
|
+
"zod",
|
|
31
|
+
"entity",
|
|
32
|
+
"orm",
|
|
33
|
+
"schema",
|
|
34
|
+
"typescript",
|
|
35
|
+
"entity-definition",
|
|
36
|
+
"er-model"
|
|
37
|
+
],
|
|
38
|
+
"author": "",
|
|
39
|
+
"license": "MIT",
|
|
40
|
+
"repository": {
|
|
41
|
+
"type": "git",
|
|
42
|
+
"url": "git+https://github.com/masaori/zod-to-entity-definitions.git"
|
|
43
|
+
},
|
|
44
|
+
"publishConfig": {
|
|
45
|
+
"registry": "https://registry.npmjs.org",
|
|
46
|
+
"access": "public"
|
|
47
|
+
},
|
|
48
|
+
"peerDependencies": {
|
|
49
|
+
"zod": "4.1.13"
|
|
50
|
+
},
|
|
51
|
+
"devDependencies": {
|
|
52
|
+
"@biomejs/biome": "^1.9.4",
|
|
53
|
+
"@commitlint/cli": "^19.0.0",
|
|
54
|
+
"@commitlint/config-conventional": "^19.0.0",
|
|
55
|
+
"@semantic-release/changelog": "^6.0.3",
|
|
56
|
+
"@semantic-release/git": "^10.0.1",
|
|
57
|
+
"@semantic-release/npm": "^12.0.0",
|
|
58
|
+
"@types/node": "^22.10.1",
|
|
59
|
+
"conventional-changelog-conventionalcommits": "^8.0.0",
|
|
60
|
+
"semantic-release": "^24.0.0",
|
|
61
|
+
"tsup": "^8.3.5",
|
|
62
|
+
"tsx": "^4.20.6",
|
|
63
|
+
"typescript": "^5.7.2",
|
|
64
|
+
"vitest": "^2.1.8",
|
|
65
|
+
"zod": "4.1.13"
|
|
66
|
+
}
|
|
67
|
+
}
|