Skip to content

Commit

Permalink
fix: make domain a required property
Browse files Browse the repository at this point in the history
Ticket: DX-631
  • Loading branch information
anshchaturvedi committed Jul 31, 2024
1 parent 662cc75 commit b491e26
Show file tree
Hide file tree
Showing 2 changed files with 103 additions and 227 deletions.
2 changes: 1 addition & 1 deletion packages/openapi-generator/src/ir.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ export type Object = {

export type RecordObject = {
type: 'record';
domain?: Schema;
domain: Schema;
codomain: Schema;
};

Expand Down
328 changes: 102 additions & 226 deletions packages/openapi-generator/test/openapi.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import * as E from 'fp-ts/lib/Either';
import assert from 'node:assert/strict';
import test from 'node:test';
import { OpenAPIV3_1 } from 'openapi-types';
import * as fs from 'fs';

import {
convertRoutesToOpenAPI,
Expand Down Expand Up @@ -61,8 +60,6 @@ async function testCase(
schemas,
);

fs.writeFileSync("actual.json", JSON.stringify(actual, null, 2));

assert.deepEqual(errors, expectedErrors);
assert.deepEqual(actual, expected);
});
Expand Down Expand Up @@ -3822,144 +3819,6 @@ testCase("route with consolidatable union schemas", ROUTE_WITH_CONSOLIDATABLE_UN
}
});

const ROUTE_WITH_RECORD_TYPES = `
import * as t from 'io-ts';
import * as h from '@api-ts/io-ts-http';
const ValidKeys = t.keyof({ name: "name", age: "age", address: "address" });
const PersonObject = t.type({ bigName: t.string, bigAge: t.number });
export const route = h.httpRoute({
path: '/foo',
method: 'GET',
request: h.httpRequest({
query: {
name: t.string,
},
}),
response: {
200: {
person: t.record(ValidKeys, t.string),
anotherPerson: t.record(ValidKeys, PersonObject),
bigPerson: t.record(t.string, t.string),
anotherBigPerson: t.record(t.string, PersonObject),
}
},
});
`;

testCase("route with record types", ROUTE_WITH_RECORD_TYPES, {
openapi: '3.0.3',
info: {
title: 'Test',
version: '1.0.0'
},
paths: {
'/foo': {
get: {
parameters: [
{
name: 'name',
in: 'query',
required: true,
schema: {
type: 'string'
}
}
],
responses: {
'200': {
description: 'OK',
content: {
'application/json': {
schema: {
type: 'object',
properties: {
// becomes t.type()
person: {
type: 'object',
properties: {
name: { type: 'string' },
age: { type: 'string' },
address: { type: 'string' }
},
required: [ 'name', 'age', 'address' ]
},
// becomes t.type()
anotherPerson: {
type: 'object',
properties: {
name: {
type: 'object',
properties: {
bigName: { type: 'string' },
bigAge: { type: 'number' }
},
required: [ 'bigName', 'bigAge' ]
},
age: {
type: 'object',
properties: {
bigName: { type: 'string' },
bigAge: { type: 'number' }
},
required: [ 'bigName', 'bigAge' ]
},
address: {
type: 'object',
properties: {
bigName: { type: 'string' },
bigAge: { type: 'number' }
},
required: [ 'bigName', 'bigAge' ]
}
},
required: [ 'name', 'age', 'address' ]
},
bigPerson: {
// stays as t.record()
type: 'object',
additionalProperties: { type: 'string' }
},
anotherBigPerson: {
// stays as t.record()
type: 'object',
additionalProperties: {
type: 'object',
properties: {
bigName: { type: 'string' },
bigAge: { type: 'number' }
},
required: [ 'bigName', 'bigAge' ]
}
}
},
required: [ 'person', 'anotherPerson', 'bigPerson', 'anotherBigPerson' ]
}
}
}
}
}
}
}
},
components: {
schemas: {
ValidKeys: {
title: 'ValidKeys',
type: 'string',
enum: [ 'name', 'age', 'address' ]
},
PersonObject: {
title: 'PersonObject',
type: 'object',
properties: { bigName: { type: 'string' }, bigAge: { type: 'number' } },
required: [ 'bigName', 'bigAge' ]
}
}
}
});

const ROUTE_WITH_NESTED_ARRAY_EXAMPLES = `
import * as t from 'io-ts';
import * as h from '@api-ts/io-ts-http';
Expand Down Expand Up @@ -4081,77 +3940,119 @@ testCase("route with nested array examples", ROUTE_WITH_NESTED_ARRAY_EXAMPLES, {
}
});

const ROUTE_WITH_NESTED_ARRAY_EXAMPLES = `
const ROUTE_WITH_RECORD_TYPES = `
import * as t from 'io-ts';
import * as h from '@api-ts/io-ts-http';
/**
* @example ["a", "b"]
*/
const firstLevel = t.array(t.string);
/**
* @example [["a", "b"], ["c", "d"]]
*/
const secondLevel = t.array(firstLevel);
/**
* @example [[["a"], ["b"]], [["c"], ["d"]]]
*/
const thirdLevel = t.array(secondLevel);
const ValidKeys = t.keyof({ name: "name", age: "age", address: "address" });
const PersonObject = t.type({ bigName: t.string, bigAge: t.number });
export const route = h.httpRoute({
path: '/foo',
method: 'POST',
request: h.httpRequest({
params: {},
body: t.type({
nested: thirdLevel
})
method: 'GET',
request: h.httpRequest({
query: {
name: t.string,
},
}),
response: {
200: t.literal('OK'),
200: {
person: t.record(ValidKeys, t.string),
anotherPerson: t.record(ValidKeys, PersonObject),
bigPerson: t.record(t.string, t.string),
anotherBigPerson: t.record(t.string, PersonObject),
}
},
});
`;

testCase("route with nested array examples", ROUTE_WITH_NESTED_ARRAY_EXAMPLES, {
openapi: "3.0.3",
testCase("route with record types", ROUTE_WITH_RECORD_TYPES, {
openapi: '3.0.3',
info: {
title: "Test",
version: "1.0.0"
title: 'Test',
version: '1.0.0'
},
paths: {
"/foo": {
post: {
parameters: [],
requestBody: {
content: {
"application/json": {
schema: {
type: "object",
properties: {
nested: {
"$ref": "#/components/schemas/thirdLevel"
}
},
required: [
"nested"
]
}
'/foo': {
get: {
parameters: [
{
name: 'name',
in: 'query',
required: true,
schema: {
type: 'string'
}
}
},
],
responses: {
200: {
description: "OK",
'200': {
description: 'OK',
content: {
"application/json": {
'application/json': {
schema: {
type: "string",
enum: [
"OK"
]
type: 'object',
properties: {
// becomes t.type()
person: {
type: 'object',
properties: {
name: { type: 'string' },
age: { type: 'string' },
address: { type: 'string' }
},
required: [ 'name', 'age', 'address' ]
},
// becomes t.type()
anotherPerson: {
type: 'object',
properties: {
name: {
type: 'object',
properties: {
bigName: { type: 'string' },
bigAge: { type: 'number' }
},
required: [ 'bigName', 'bigAge' ]
},
age: {
type: 'object',
properties: {
bigName: { type: 'string' },
bigAge: { type: 'number' }
},
required: [ 'bigName', 'bigAge' ]
},
address: {
type: 'object',
properties: {
bigName: { type: 'string' },
bigAge: { type: 'number' }
},
required: [ 'bigName', 'bigAge' ]
}
},
required: [ 'name', 'age', 'address' ]
},
bigPerson: {
// stays as t.record()
type: 'object',
additionalProperties: { type: 'string' }
},
anotherBigPerson: {
// stays as t.record()
type: 'object',
additionalProperties: {
type: 'object',
properties: {
bigName: { type: 'string' },
bigAge: { type: 'number' }
},
required: [ 'bigName', 'bigAge' ]
}
}
},
required: [ 'person', 'anotherPerson', 'bigPerson', 'anotherBigPerson' ]
}
}
}
Expand All @@ -4162,41 +4063,16 @@ testCase("route with nested array examples", ROUTE_WITH_NESTED_ARRAY_EXAMPLES, {
},
components: {
schemas: {
firstLevel: {
title: "firstLevel",
type: "array",
example: [ "a", "b" ],
items: {
type: "string"
}
},
secondLevel: {
title: "secondLevel",
type: "array",
example: [ [ "a", "b" ], [ "c", "d" ] ],
items: {
type: "array",
example: [ "a", "b" ],
items: {
type: "string"
}
}
ValidKeys: {
title: 'ValidKeys',
type: 'string',
enum: [ 'name', 'age', 'address' ]
},
thirdLevel: {
title: "thirdLevel",
type: "array",
example: [[["a"],["b"]],[["c"],["d"]]],
items: {
type: "array",
example: [["a","b"],["c","d"]],
items: {
type: "array",
example: ["a","b"],
items: {
type: "string"
}
}
}
PersonObject: {
title: 'PersonObject',
type: 'object',
properties: { bigName: { type: 'string' }, bigAge: { type: 'number' } },
required: [ 'bigName', 'bigAge' ]
}
}
}
Expand Down

0 comments on commit b491e26

Please sign in to comment.