Skip to content

Commit c41addd

Browse files
authored
fix(openapi): support spec generation for JSON fields (#2089)
1 parent 401f45d commit c41addd

File tree

4 files changed

+956
-815
lines changed

4 files changed

+956
-815
lines changed

packages/plugins/openapi/src/rest-generator.ts

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,19 @@ import {
1212
requireOption,
1313
resolvePath,
1414
} from '@zenstackhq/sdk';
15-
import { DataModel, DataModelField, DataModelFieldType, Enum, isDataModel, isEnum, Model } from '@zenstackhq/sdk/ast';
15+
import {
16+
DataModel,
17+
DataModelField,
18+
DataModelFieldType,
19+
Enum,
20+
isDataModel,
21+
isEnum,
22+
isTypeDef,
23+
Model,
24+
TypeDef,
25+
TypeDefField,
26+
TypeDefFieldType,
27+
} from '@zenstackhq/sdk/ast';
1628
import type { DMMF } from '@zenstackhq/sdk/prisma';
1729
import fs from 'fs';
1830
import { lowerCaseFirst } from 'lower-case-first';
@@ -494,6 +506,8 @@ export class RESTfulOpenAPIGenerator extends OpenAPIGeneratorBase {
494506
schema = this.ref(fieldDecl.name);
495507
} else if (isDataModel(fieldDecl)) {
496508
schema = { type: 'string' };
509+
} else if (isTypeDef(fieldDecl) || field.type.type === 'Json') {
510+
schema = { type: 'string', format: 'json' };
497511
} else {
498512
invariant(field.type.type);
499513
schema = this.fieldTypeToOpenAPISchema(field.type);
@@ -540,6 +554,11 @@ export class RESTfulOpenAPIGenerator extends OpenAPIGeneratorBase {
540554
}
541555
}
542556

557+
// type defs
558+
for (const typeDef of this.model.declarations.filter(isTypeDef)) {
559+
schemas[typeDef.name] = this.generateTypeDefComponent(typeDef);
560+
}
561+
543562
return components;
544563
}
545564

@@ -771,7 +790,7 @@ export class RESTfulOpenAPIGenerator extends OpenAPIGeneratorBase {
771790
};
772791
}
773792

774-
private generateEnumComponent(_enum: Enum): OAPI.SchemaObject {
793+
private generateEnumComponent(_enum: Enum) {
775794
const schema: OAPI.SchemaObject = {
776795
type: 'string',
777796
description: `The "${_enum.name}" Enum`,
@@ -780,6 +799,18 @@ export class RESTfulOpenAPIGenerator extends OpenAPIGeneratorBase {
780799
return schema;
781800
}
782801

802+
private generateTypeDefComponent(typeDef: TypeDef) {
803+
const schema: OAPI.SchemaObject = {
804+
type: 'object',
805+
description: `The "${typeDef.name}" TypeDef`,
806+
properties: typeDef.fields.reduce((acc, field) => {
807+
acc[field.name] = this.generateField(field);
808+
return acc;
809+
}, {} as Record<string, OAPI.SchemaObject>),
810+
};
811+
return schema;
812+
}
813+
783814
private generateDataModelComponents(model: DataModel) {
784815
const result: Record<string, OAPI.SchemaObject> = {};
785816
result[`${model.name}`] = this.generateModelEntity(model, 'read');
@@ -945,14 +976,16 @@ export class RESTfulOpenAPIGenerator extends OpenAPIGeneratorBase {
945976
return result;
946977
}
947978

948-
private generateField(field: DataModelField) {
979+
private generateField(field: DataModelField | TypeDefField) {
949980
return this.wrapArray(
950981
this.wrapNullable(this.fieldTypeToOpenAPISchema(field.type), field.type.optional),
951982
field.type.array
952983
);
953984
}
954985

955-
private fieldTypeToOpenAPISchema(type: DataModelFieldType): OAPI.ReferenceObject | OAPI.SchemaObject {
986+
private fieldTypeToOpenAPISchema(
987+
type: DataModelFieldType | TypeDefFieldType
988+
): OAPI.ReferenceObject | OAPI.SchemaObject {
956989
return match(type.type)
957990
.with('String', () => ({ type: 'string' }))
958991
.with(P.union('Int', 'BigInt'), () => ({ type: 'integer' }))

0 commit comments

Comments
 (0)