|
1 | 1 | import { z } from "zod"; |
2 | | -import type { StrapiContentType, StrapiAttribute } from "../types/strapi"; |
| 2 | +import type { StrapiComponent, StrapiContentType, StrapiAttribute } from "../types/strapi"; |
3 | 3 |
|
4 | 4 | export class StrapiSchemaGenerator { |
5 | 5 | private contentTypes: Array<StrapiContentType> = []; |
| 6 | + private components: Array<StrapiComponent> = []; |
6 | 7 | private strict: boolean = false; |
7 | 8 |
|
8 | | - constructor(contentTypes: Array<StrapiContentType>, strict: boolean = false) { |
| 9 | + constructor(contentTypes: Array<StrapiContentType>, components: Array<StrapiComponent>, strict: boolean = false) { |
9 | 10 | this.contentTypes = contentTypes; |
| 11 | + this.components = components; |
10 | 12 | this.strict = strict; |
11 | 13 | } |
12 | 14 |
|
@@ -123,8 +125,16 @@ export class StrapiSchemaGenerator { |
123 | 125 | case "component": |
124 | 126 | if (!attribute.component) |
125 | 127 | throw new Error("Component type requires component name"); |
126 | | - // TODO: Implement component schema generation |
127 | | - return z.any(); |
| 128 | + const component = this.components.find( |
| 129 | + (component) => component.uid === attribute.component, |
| 130 | + ); |
| 131 | + if (!component) |
| 132 | + throw new Error(`Component ${attribute.component} not found`); |
| 133 | + |
| 134 | + if (attribute.repeatable) { |
| 135 | + return z.array(this.generateComponentSchema(component.schema)); |
| 136 | + } |
| 137 | + return this.generateComponentSchema(component.schema); |
128 | 138 |
|
129 | 139 | case "dynamiczone": |
130 | 140 | // TODO: Implement dynamiczone schema generation |
@@ -172,6 +182,16 @@ export class StrapiSchemaGenerator { |
172 | 182 | return z.object(shape); |
173 | 183 | } |
174 | 184 |
|
| 185 | + private generateComponentSchema(componentSchema: StrapiComponent["schema"]): z.ZodObject<any> { |
| 186 | + const ref = this; |
| 187 | + const shape: Record<string, z.ZodTypeAny> = Object.entries(componentSchema.attributes).reduce((acc, [key, attribute]) => { |
| 188 | + const schema = ref.generateAttributeSchema(attribute); |
| 189 | + return { ...acc, [key]: schema }; |
| 190 | + }, {}); |
| 191 | + |
| 192 | + return z.object(shape); |
| 193 | + } |
| 194 | + |
175 | 195 | public generateSchema(contentTypeName: string): z.ZodObject<any> { |
176 | 196 | const contentType = this.contentTypes.find( |
177 | 197 | (contentType) => contentType.apiID === contentTypeName, |
|
0 commit comments