From 3fed45f47854404740d1429d6a4455bbdb6caf5a Mon Sep 17 00:00:00 2001 From: mikkelam Date: Fri, 3 Jan 2025 16:32:53 +0100 Subject: [PATCH 1/2] fix: Remove wrong date type --- src/utils.ts | 39 +++++++++++++++++++--- test/index.test.ts | 82 +++++++++++++++++++++++++++++++++++++++------- 2 files changed, 105 insertions(+), 16 deletions(-) diff --git a/src/utils.ts b/src/utils.ts index 4b69103..3bbe4ab 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -30,7 +30,6 @@ export const mapProperties = ( if (typeof schema === 'string') if (schema in models) schema = models[schema] else throw new Error(`Can't find model ${schema}`) - return Object.entries(schema?.properties ?? []).map(([key, value]) => { const { type: valueType = undefined, @@ -70,15 +69,14 @@ const mapTypesResponse = ( const responses: Record = {} for (const type of types) { - // console.log(schema) - responses[type] = { - schema: + schema: cleanDateType( typeof schema === 'string' ? { $ref: `#/components/schemas/${schema}` } : { ...(schema as any) } + ) } } @@ -108,6 +106,7 @@ const cloneHook = (hook: T) => { if (!hook) return if (typeof hook === 'string') return hook if (Array.isArray(hook)) return [...hook] + return { ...hook } } @@ -372,3 +371,35 @@ export const filterPaths = ( return newPaths } + +const cleanDateType = (schema: any): any => { + if (!schema) return schema + + if (schema.anyOf && schema.anyOf.some((x: any) => x.type === 'Date')) { + return { + ...schema, + anyOf: schema.anyOf.filter((x: any) => x.type !== 'Date') + } + } + + if (schema.type === 'object' && schema.properties) { + return { + ...schema, + properties: Object.fromEntries( + Object.entries(schema.properties).map(([key, value]) => [ + key, + cleanDateType(value) + ]) + ) + } + } + + if (schema.type === 'array' && schema.items) { + return { + ...schema, + items: cleanDateType(schema.items) + } + } + + return schema +} diff --git a/test/index.test.ts b/test/index.test.ts index 868be79..3276c16 100644 --- a/test/index.test.ts +++ b/test/index.test.ts @@ -232,27 +232,27 @@ describe('Swagger', () => { }) it('should hide routes with hide = true from paths', async () => { - const app = new Elysia().use(swagger()) - .get("/public", "omg") + const app = new Elysia() + .use(swagger()) + .get('/public', 'omg') .guard({ detail: { hide: true } }) - .get("/hidden", "ok") + .get('/hidden', 'ok') await app.modules const res = await app.handle(req('/swagger/json')) expect(res.status).toBe(200) const response = await res.json() - expect(response.paths['/public']).not.toBeUndefined(); - expect(response.paths['/hidden']).toBeUndefined(); + expect(response.paths['/public']).not.toBeUndefined() + expect(response.paths['/hidden']).toBeUndefined() }) it('should expand .all routes', async () => { - const app = new Elysia().use(swagger()) - .all("/all", "woah") + const app = new Elysia().use(swagger()).all('/all', 'woah') await app.modules @@ -263,17 +263,75 @@ describe('Swagger', () => { }) it('should hide routes that are invalid', async () => { - const app = new Elysia().use(swagger()) - .get("/valid", "ok") - .route("LOCK", "/invalid", "nope") + const app = new Elysia() + .use(swagger()) + .get('/valid', 'ok') + .route('LOCK', '/invalid', 'nope') + + await app.modules + + const res = await app.handle(req('/swagger/json')) + expect(res.status).toBe(200) + const response = await res.json() + expect(response.paths['/valid']).not.toBeUndefined() + expect(response.paths['/invalid']).toBeUndefined() + }) + + it('should properly format date-time fields in schema', async () => { + const app = new Elysia().use(swagger()).post('/user', () => {}, { + body: t.Object({ + name: t.String(), + createdAt: t.Date(), + metadata: t.Object({ + updatedAt: t.Date() + }), + history: t.Array( + t.Object({ + timestamp: t.Date() + }) + ) + }) + }) await app.modules const res = await app.handle(req('/swagger/json')) expect(res.status).toBe(200) const response = await res.json() - expect(response.paths['/valid']).not.toBeUndefined(); - expect(response.paths['/invalid']).toBeUndefined(); + const expectedDateFormat = { + anyOf: [ + { + format: 'date', + type: 'string', + default: expect.any(String) // this is the correct syntax + }, + { + format: 'date-time', + type: 'string', + default: expect.any(String) // this is the correct syntax + }, + { + type: 'number' + } + ] + } + + // Check root level date + expect( + response.paths['/user'].post.requestBody.content['application/json'] + .schema.properties.createdAt + ).toMatchObject(expectedDateFormat) + + // Check nested date in object + expect( + response.paths['/user'].post.requestBody.content['application/json'] + .schema.properties.metadata.properties.updatedAt + ).toMatchObject(expectedDateFormat) + // Check date in array items + expect( + response.paths['/user'].post.requestBody.content['application/json'] + .schema.properties.history.items.properties.timestamp + ).toMatchObject(expectedDateFormat) }) }) From a84cf6e8dd861f75c32859fb30ecd279ee123b14 Mon Sep 17 00:00:00 2001 From: mikkelam Date: Fri, 3 Jan 2025 16:36:17 +0100 Subject: [PATCH 2/2] remove weird comment --- test/index.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/index.test.ts b/test/index.test.ts index 3276c16..5bd52ef 100644 --- a/test/index.test.ts +++ b/test/index.test.ts @@ -304,12 +304,12 @@ describe('Swagger', () => { { format: 'date', type: 'string', - default: expect.any(String) // this is the correct syntax + default: expect.any(String) }, { format: 'date-time', type: 'string', - default: expect.any(String) // this is the correct syntax + default: expect.any(String) }, { type: 'number'