@demokit-ai/schema 0.0.2 → 0.2.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.
- package/README.md +244 -0
- package/package.json +1 -1
package/README.md
ADDED
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
# @demokit-ai/schema
|
|
2
|
+
|
|
3
|
+

|
|
4
|
+

|
|
5
|
+
|
|
6
|
+
OpenAPI schema parsing with relationship detection for DemoKit.
|
|
7
|
+
|
|
8
|
+
## Installation
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
npm install @demokit-ai/schema
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
## Features
|
|
15
|
+
|
|
16
|
+
- **OpenAPI Parsing** - Parse OpenAPI 3.x specifications
|
|
17
|
+
- **Relationship Detection** - Automatically detect model relationships
|
|
18
|
+
- **Schema Normalization** - Convert to DemoKit's internal schema format
|
|
19
|
+
- **Type Inference** - Infer property types and constraints
|
|
20
|
+
- **Validation** - Validate schemas against OpenAPI spec
|
|
21
|
+
- Full TypeScript support
|
|
22
|
+
|
|
23
|
+
## Usage
|
|
24
|
+
|
|
25
|
+
### Parse OpenAPI Spec
|
|
26
|
+
|
|
27
|
+
```ts
|
|
28
|
+
import { parseOpenAPI } from '@demokit-ai/schema'
|
|
29
|
+
|
|
30
|
+
const schema = await parseOpenAPI('./openapi.yaml')
|
|
31
|
+
|
|
32
|
+
console.log(schema.models)
|
|
33
|
+
// {
|
|
34
|
+
// User: {
|
|
35
|
+
// properties: {
|
|
36
|
+
// id: { type: 'string', format: 'uuid' },
|
|
37
|
+
// name: { type: 'string' },
|
|
38
|
+
// email: { type: 'string', format: 'email' },
|
|
39
|
+
// },
|
|
40
|
+
// required: ['id', 'name', 'email'],
|
|
41
|
+
// },
|
|
42
|
+
// Order: { ... },
|
|
43
|
+
// }
|
|
44
|
+
|
|
45
|
+
console.log(schema.relationships)
|
|
46
|
+
// [
|
|
47
|
+
// { from: { model: 'Order', field: 'userId' }, to: { model: 'User', field: 'id' }, type: 'many-to-one' },
|
|
48
|
+
// ]
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### Parse from URL
|
|
52
|
+
|
|
53
|
+
```ts
|
|
54
|
+
import { parseOpenAPI } from '@demokit-ai/schema'
|
|
55
|
+
|
|
56
|
+
const schema = await parseOpenAPI('https://api.example.com/openapi.json')
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### Parse from Object
|
|
60
|
+
|
|
61
|
+
```ts
|
|
62
|
+
import { parseOpenAPIObject } from '@demokit-ai/schema'
|
|
63
|
+
|
|
64
|
+
const spec = {
|
|
65
|
+
openapi: '3.0.0',
|
|
66
|
+
paths: { ... },
|
|
67
|
+
components: {
|
|
68
|
+
schemas: {
|
|
69
|
+
User: { ... },
|
|
70
|
+
},
|
|
71
|
+
},
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const schema = parseOpenAPIObject(spec)
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### Detect Relationships
|
|
78
|
+
|
|
79
|
+
```ts
|
|
80
|
+
import { detectRelationships } from '@demokit-ai/schema'
|
|
81
|
+
|
|
82
|
+
const models = {
|
|
83
|
+
User: {
|
|
84
|
+
properties: {
|
|
85
|
+
id: { type: 'string' },
|
|
86
|
+
},
|
|
87
|
+
},
|
|
88
|
+
Order: {
|
|
89
|
+
properties: {
|
|
90
|
+
id: { type: 'string' },
|
|
91
|
+
userId: { type: 'string' },
|
|
92
|
+
},
|
|
93
|
+
},
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const relationships = detectRelationships(models)
|
|
97
|
+
// [
|
|
98
|
+
// {
|
|
99
|
+
// from: { model: 'Order', field: 'userId' },
|
|
100
|
+
// to: { model: 'User', field: 'id' },
|
|
101
|
+
// type: 'many-to-one',
|
|
102
|
+
// },
|
|
103
|
+
// ]
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### Define Schema Manually
|
|
107
|
+
|
|
108
|
+
```ts
|
|
109
|
+
import { defineSchema } from '@demokit-ai/schema'
|
|
110
|
+
|
|
111
|
+
const schema = defineSchema({
|
|
112
|
+
models: {
|
|
113
|
+
User: {
|
|
114
|
+
properties: {
|
|
115
|
+
id: { type: 'string', format: 'uuid' },
|
|
116
|
+
name: { type: 'string', minLength: 1 },
|
|
117
|
+
email: { type: 'string', format: 'email' },
|
|
118
|
+
role: { type: 'string', enum: ['admin', 'user', 'guest'] },
|
|
119
|
+
createdAt: { type: 'string', format: 'date-time' },
|
|
120
|
+
},
|
|
121
|
+
required: ['id', 'name', 'email'],
|
|
122
|
+
},
|
|
123
|
+
Order: {
|
|
124
|
+
properties: {
|
|
125
|
+
id: { type: 'string', format: 'uuid' },
|
|
126
|
+
userId: {
|
|
127
|
+
type: 'string',
|
|
128
|
+
relationshipTo: { model: 'User', field: 'id' },
|
|
129
|
+
},
|
|
130
|
+
total: { type: 'number', minimum: 0 },
|
|
131
|
+
status: { type: 'string', enum: ['pending', 'completed', 'cancelled'] },
|
|
132
|
+
},
|
|
133
|
+
required: ['id', 'userId', 'total', 'status'],
|
|
134
|
+
},
|
|
135
|
+
},
|
|
136
|
+
})
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
### Validate Schema
|
|
140
|
+
|
|
141
|
+
```ts
|
|
142
|
+
import { validateSchema } from '@demokit-ai/schema'
|
|
143
|
+
|
|
144
|
+
const result = validateSchema(schema)
|
|
145
|
+
|
|
146
|
+
if (!result.valid) {
|
|
147
|
+
console.error('Schema errors:', result.errors)
|
|
148
|
+
}
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
## API Reference
|
|
152
|
+
|
|
153
|
+
### `parseOpenAPI(pathOrUrl)`
|
|
154
|
+
|
|
155
|
+
Parse an OpenAPI spec from a file path or URL.
|
|
156
|
+
|
|
157
|
+
Returns: `Promise<DemokitSchema>`
|
|
158
|
+
|
|
159
|
+
### `parseOpenAPIObject(spec)`
|
|
160
|
+
|
|
161
|
+
Parse an OpenAPI spec from a JavaScript object.
|
|
162
|
+
|
|
163
|
+
Returns: `DemokitSchema`
|
|
164
|
+
|
|
165
|
+
### `detectRelationships(models)`
|
|
166
|
+
|
|
167
|
+
Detect relationships between models based on field naming conventions.
|
|
168
|
+
|
|
169
|
+
Returns: `Relationship[]`
|
|
170
|
+
|
|
171
|
+
### `defineSchema(options)`
|
|
172
|
+
|
|
173
|
+
Define a schema manually with full type inference.
|
|
174
|
+
|
|
175
|
+
Options:
|
|
176
|
+
- `models` - Model definitions
|
|
177
|
+
- `relationships` - Explicit relationship definitions (optional)
|
|
178
|
+
|
|
179
|
+
Returns: `DemokitSchema`
|
|
180
|
+
|
|
181
|
+
### `validateSchema(schema)`
|
|
182
|
+
|
|
183
|
+
Validate a schema for correctness.
|
|
184
|
+
|
|
185
|
+
Returns:
|
|
186
|
+
- `valid` - Whether schema is valid
|
|
187
|
+
- `errors` - Array of validation errors
|
|
188
|
+
- `warnings` - Array of warnings
|
|
189
|
+
|
|
190
|
+
## Types
|
|
191
|
+
|
|
192
|
+
### `DemokitSchema`
|
|
193
|
+
|
|
194
|
+
```ts
|
|
195
|
+
interface DemokitSchema {
|
|
196
|
+
version: string
|
|
197
|
+
models: Record<string, DataModel>
|
|
198
|
+
relationships: Relationship[]
|
|
199
|
+
}
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
### `DataModel`
|
|
203
|
+
|
|
204
|
+
```ts
|
|
205
|
+
interface DataModel {
|
|
206
|
+
properties: Record<string, PropertyDef>
|
|
207
|
+
required?: string[]
|
|
208
|
+
}
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
### `PropertyDef`
|
|
212
|
+
|
|
213
|
+
```ts
|
|
214
|
+
interface PropertyDef {
|
|
215
|
+
type: 'string' | 'number' | 'integer' | 'boolean' | 'array' | 'object'
|
|
216
|
+
name?: string
|
|
217
|
+
format?: string
|
|
218
|
+
enum?: unknown[]
|
|
219
|
+
minimum?: number
|
|
220
|
+
maximum?: number
|
|
221
|
+
minLength?: number
|
|
222
|
+
maxLength?: number
|
|
223
|
+
pattern?: string
|
|
224
|
+
nullable?: boolean
|
|
225
|
+
default?: unknown
|
|
226
|
+
example?: unknown
|
|
227
|
+
relationshipTo?: { model: string; field: string }
|
|
228
|
+
items?: PropertyDef | DataModel
|
|
229
|
+
}
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
### `Relationship`
|
|
233
|
+
|
|
234
|
+
```ts
|
|
235
|
+
interface Relationship {
|
|
236
|
+
from: { model: string; field: string }
|
|
237
|
+
to: { model: string; field: string }
|
|
238
|
+
type: 'one-to-one' | 'one-to-many' | 'many-to-one' | 'many-to-many'
|
|
239
|
+
}
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
## License
|
|
243
|
+
|
|
244
|
+
MIT
|