Skip to content

Commit

Permalink
generate void headers schema as before
Browse files Browse the repository at this point in the history
  • Loading branch information
dmitrysteblyuk committed Jul 26, 2023
1 parent 5375ca9 commit 554c77f
Show file tree
Hide file tree
Showing 5 changed files with 28 additions and 25 deletions.
5 changes: 5 additions & 0 deletions packages/oats-runtime/src/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,11 @@ function voidify(value: object | undefined | null) {
}

function cleanHeaders<H>(mode: Mode, maker: Maker<any, H>, headers: object) {
// If headers are not declared in the spec, return null.
const acceptsNull = maker(null);
if (acceptsNull.isSuccess()) {
return acceptsNull.success();
}
// note: we now expect that on client side headers are type conforming so do not need to lowercase those
// this is slightly breaking change is somebody has subverted the type checker
const normalized = mode === 'server' ? lowercaseObject(headers) : headers;
Expand Down
4 changes: 2 additions & 2 deletions packages/oats-runtime/test/server.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {
describe('safe', () => {
it('validates request and response', async () => {
const endpoint = server.safe<any, any, any, any, any, any>(
makeObject({}),
makeVoid(),
makeVoid(),
makeObject({ param: makeNumber() }) as Maker<any, any>,
makeVoid(),
Expand Down Expand Up @@ -47,7 +47,7 @@ describe('safe', () => {

it('accepts empty array as body', async () => {
const endpoint = server.safe<any, any, any, any, any, any>(
makeObject({}),
makeVoid(),
makeVoid(),
makeObject({ param: makeNumber() }) as Maker<any, any>,
makeArray(makeString()),
Expand Down
9 changes: 4 additions & 5 deletions packages/oats/src/generate-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ interface ImportDefinition {

// bit of a lie here really
const voidSchema: oas.SchemaObject = { type: 'void' as any };
const emptyObjectSchema: oas.SchemaObject = { type: 'object', additionalProperties: false };

export type Resolve = (
ref: string,
Expand Down Expand Up @@ -243,15 +242,16 @@ export function run(options: Options) {
paramSchema: undefined | ReadonlyArray<oas.ParameterObject | oas.ReferenceObject>,
oasSchema: oas.OpenAPIObject
) {
const noQueryParams = { type: 'object' as const, additionalProperties: false };
if (!paramSchema) {
return generateTopLevelType(op, emptyObjectSchema);
return generateTopLevelType(op, noQueryParams);
}
const schema = oautil.deref(paramSchema, oasSchema);
const queryParams = schema
.map(schema => oautil.deref(schema, oasSchema))
.filter(schema => schema.in === 'query');
if (queryParams.length === 0) {
return generateTopLevelType(op, emptyObjectSchema);
return generateTopLevelType(op, noQueryParams);
}
if (queryParams.some(param => !!param.explode)) {
assert(queryParams.length === 1, 'only one explode: true parameter is supported');
Expand All @@ -277,8 +277,7 @@ export function run(options: Options) {
oasSchema: oas.OpenAPIObject,
normalize = (name: string) => name
) {
const empty = generateTopLevelType(op, type === 'header' ? emptyObjectSchema : voidSchema);

const empty = generateTopLevelType(op, voidSchema);
if (!paramSchema) {
return empty;
}
Expand Down
10 changes: 5 additions & 5 deletions test/fetch-adapter/fetch-adapter.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ describe('fetch adapter', () => {
expect(receivedContext.method).toEqual('get');
expect(receivedContext.path).toEqual('/');
expect(receivedContext.query).toEqual({});
expect(receivedContext.headers).toEqual({});
expect(receivedContext.headers).toEqual(null);
expect(receivedContext.body).toEqual(null);
});

Expand All @@ -94,7 +94,7 @@ describe('fetch adapter', () => {
expect(receivedContext.method).toEqual('get');
expect(receivedContext.path).toEqual('/with-query');
expect(receivedContext.query).toEqual({ one: 'the loneliest number' });
expect(receivedContext.headers).toEqual({});
expect(receivedContext.headers).toEqual(null);
expect(receivedContext.body).toEqual(null);
});

Expand All @@ -110,7 +110,7 @@ describe('fetch adapter', () => {
expect(receivedContext.method).toEqual('get');
expect(receivedContext.path).toEqual('/with-array-query');
expect(receivedContext.query).toEqual({ numbers: ['one', 'two'] });
expect(receivedContext.headers).toEqual({});
expect(receivedContext.headers).toEqual(null);
expect(receivedContext.body).toEqual(null);
});

Expand Down Expand Up @@ -143,7 +143,7 @@ describe('fetch adapter', () => {
expect(receivedContext).toBeDefined();
expect(receivedContext.method).toEqual('post');
expect(receivedContext.path).toEqual('/json-body');
expect(receivedContext.headers).toEqual({});
expect(receivedContext.headers).toEqual(null);
expect(receivedContext.body).toEqual({
contentType: 'application/json',
value: { one: 'the loneliest number' }
Expand All @@ -165,7 +165,7 @@ describe('fetch adapter', () => {
expect(receivedContext).toBeDefined();
expect(receivedContext.method).toEqual('patch');
expect(receivedContext.path).toEqual('/with-patch');
expect(receivedContext.headers).toEqual({});
expect(receivedContext.headers).toEqual(null);
expect(receivedContext.body).toEqual({
contentType: 'application/json',
value: { one: 'the loneliest number' }
Expand Down
25 changes: 12 additions & 13 deletions test/request-headers/server-parse-headers.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ import { AddressInfo } from 'net';
import { Axios } from 'axios';

describe('server parse headers', () => {
let parsedHeaders: object | null = null;
let parsedHeadersRef: { current: object | void } | null = null;

beforeEach(() => {
parsedHeaders = null;
parsedHeadersRef = null;
});

const getRoutes = () =>
Expand All @@ -20,21 +20,21 @@ describe('server parse headers', () => {
{
'/send-required-header': {
get: async ctx => {
parsedHeaders = ctx.headers;
parsedHeadersRef = { current: ctx.headers };

return runtime.noContent(204);
}
},
'/send-optional-header': {
get: async ctx => {
parsedHeaders = ctx.headers;
parsedHeadersRef = { current: ctx.headers };

return runtime.noContent(204);
}
},
'/send-no-headers': {
get: async ctx => {
parsedHeaders = ctx.headers;
parsedHeadersRef = { current: ctx.headers };

return runtime.noContent(204);
}
Expand Down Expand Up @@ -100,7 +100,7 @@ describe('server parse headers', () => {
expect(response.data).toContain(
'invalid request headers authorization: expected a string, but got `undefined` instead.'
);
expect(parsedHeaders).toBeNull();
expect(parsedHeadersRef).toBeNull();
});

it('should drop unknown headers', async () => {
Expand All @@ -109,8 +109,7 @@ describe('server parse headers', () => {
});

expect(response.status).toBe(204);
expect(parsedHeaders).toEqual({ authorization: 'basic auth' });
expect('unknown' in parsedHeaders!).toBe(false);
expect(parsedHeadersRef).toEqual({ current: { authorization: 'basic auth' } });
});

it('should accept request with required headers', async () => {
Expand All @@ -119,7 +118,7 @@ describe('server parse headers', () => {
});

expect(response.status).toBe(204);
expect(parsedHeaders).toEqual({ authorization: 'basic auth' });
expect(parsedHeadersRef).toEqual({ current: { authorization: 'basic auth' } });
});
});

Expand All @@ -130,7 +129,7 @@ describe('server parse headers', () => {
const response = await axios.get(endpointUrl);

expect(response.status).toBe(204);
expect(parsedHeaders).toEqual({});
expect(parsedHeadersRef).toEqual({ current: {} });
});

it('should include optional headers', async () => {
Expand All @@ -139,7 +138,7 @@ describe('server parse headers', () => {
});

expect(response.status).toBe(204);
expect(parsedHeaders).toEqual({ 'x-request-id': 'testrequestid' });
expect(parsedHeadersRef).toEqual({ current: { 'x-request-id': 'testrequestid' } });
});
});

Expand All @@ -152,14 +151,14 @@ describe('server parse headers', () => {
});

expect(response.status).toBe(204);
expect(parsedHeaders).toEqual({});
expect(parsedHeadersRef).toEqual({ current: null });
});

it('should accept request without headers', async () => {
const response = await axios.get(endpointUrl);

expect(response.status).toBe(204);
expect(parsedHeaders).toEqual({});
expect(parsedHeadersRef).toEqual({ current: null });
});
});
});

0 comments on commit 554c77f

Please sign in to comment.