Skip to content

Commit 020254f

Browse files
committed
fix(openapi): type "id" field according to ZModel schema type
fixes #1908
1 parent 93246f3 commit 020254f

File tree

2 files changed

+34
-4
lines changed

2 files changed

+34
-4
lines changed

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

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -906,16 +906,24 @@ export class RESTfulOpenAPIGenerator extends OpenAPIGeneratorBase {
906906
},
907907
};
908908

909+
let idFieldSchema: OAPI.SchemaObject = { type: 'string' };
910+
if (idFields.length === 1) {
911+
// FIXME: JSON:API actually requires id field to be a string,
912+
// but currently the RESTAPIHandler returns the original data
913+
// type as declared in the ZModel schema.
914+
idFieldSchema = this.fieldTypeToOpenAPISchema(idFields[0].type);
915+
}
916+
909917
if (mode === 'create') {
910918
// 'id' is required if there's no default value
911919
const idFields = model.fields.filter((f) => isIdField(f));
912920
if (idFields.length === 1 && !hasAttribute(idFields[0], '@default')) {
913-
properties = { id: { type: 'string' }, ...properties };
921+
properties = { id: idFieldSchema, ...properties };
914922
toplevelRequired.unshift('id');
915923
}
916924
} else {
917925
// 'id' always required for read and update
918-
properties = { id: { type: 'string' }, ...properties };
926+
properties = { id: idFieldSchema, ...properties };
919927
toplevelRequired.unshift('id');
920928
}
921929

packages/plugins/openapi/tests/openapi-restful.test.ts

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ model Bar {
8484

8585
const { name: output } = tmp.fileSync({ postfix: '.yaml' });
8686

87-
const options = buildOptions(model, modelFile, output, '3.1.0');
87+
const options = buildOptions(model, modelFile, output, specVersion);
8888
await generate(model, options, dmmf);
8989

9090
console.log(`OpenAPI specification generated for ${specVersion}: ${output}`);
@@ -324,7 +324,7 @@ model Foo {
324324

325325
const { name: output } = tmp.fileSync({ postfix: '.yaml' });
326326

327-
const options = buildOptions(model, modelFile, output, '3.1.0');
327+
const options = buildOptions(model, modelFile, output, specVersion);
328328
await generate(model, options, dmmf);
329329

330330
console.log(`OpenAPI specification generated for ${specVersion}: ${output}`);
@@ -340,6 +340,28 @@ model Foo {
340340
}
341341
});
342342

343+
it('int field as id', async () => {
344+
const { model, dmmf, modelFile } = await loadZModelAndDmmf(`
345+
plugin openapi {
346+
provider = '${normalizePath(path.resolve(__dirname, '../dist'))}'
347+
}
348+
349+
model Foo {
350+
id Int @id @default(autoincrement())
351+
}
352+
`);
353+
354+
const { name: output } = tmp.fileSync({ postfix: '.yaml' });
355+
356+
const options = buildOptions(model, modelFile, output, '3.0.0');
357+
await generate(model, options, dmmf);
358+
console.log(`OpenAPI specification generated: ${output}`);
359+
await OpenAPIParser.validate(output);
360+
361+
const parsed = YAML.parse(fs.readFileSync(output, 'utf-8'));
362+
expect(parsed.components.schemas.Foo.properties.id.type).toBe('integer');
363+
});
364+
343365
it('exposes individual fields from a compound id as attributes', async () => {
344366
const { model, dmmf, modelFile } = await loadZModelAndDmmf(`
345367
plugin openapi {

0 commit comments

Comments
 (0)