Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add OpenAPI validation to a few endpoints (#1409)
* feat: add OpenAPI validation to a few endpoints (2) * refactor: use package version as the OpenAPI version * refactor: keep the existing OpenAPI page for now * refactor: add snapshots tests for the OpenAPI output * refactor: validate Content-Type by default * refactor: update vulnerable deps * refactor: fix documentation URL to match schema * refactor: improve external type declaration * refactor: remove unused package resolutions * refactor: try express-openapi fork * Update package.json * Update src/lib/services/openapi-service.ts * Update src/lib/types/openapi.d.ts * Update src/lib/types/openapi.d.ts Co-authored-by: Ivar Conradi Østhus <ivarconr@gmail.com>
- Loading branch information
Showing
31 changed files
with
2,572 additions
and
2,595 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
import { OpenAPIV3 } from 'openapi-types'; | ||
import { featuresSchema } from './spec/features-schema'; | ||
import { featureSchema } from './spec/feature-schema'; | ||
import { strategySchema } from './spec/strategy-schema'; | ||
import { variantSchema } from './spec/variant-schema'; | ||
import { overrideSchema } from './spec/override-schema'; | ||
import { createFeatureSchema } from './spec/create-feature-schema'; | ||
import { constraintSchema } from './spec/constraint-schema'; | ||
|
||
// Create the base OpenAPI schema, with everything except paths. | ||
export const createOpenApiSchema = ( | ||
serverUrl?: string, | ||
): Omit<OpenAPIV3.Document, 'paths'> => { | ||
return { | ||
openapi: '3.0.3', | ||
servers: serverUrl ? [{ url: serverUrl }] : [], | ||
info: { | ||
title: 'Unleash API', | ||
version: process.env.npm_package_version, | ||
}, | ||
security: [ | ||
{ | ||
apiKey: [], | ||
}, | ||
], | ||
components: { | ||
securitySchemes: { | ||
apiKey: { | ||
type: 'apiKey', | ||
in: 'header', | ||
name: 'Authorization', | ||
}, | ||
}, | ||
schemas: { | ||
createFeatureSchema, | ||
featuresSchema, | ||
featureSchema, | ||
strategySchema, | ||
variantSchema, | ||
overrideSchema, | ||
constraintSchema, | ||
}, | ||
}, | ||
}; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
import { createSchemaObject, CreateSchemaType } from '../types'; | ||
|
||
export const schema = { | ||
type: 'object', | ||
required: ['contextName', 'operator'], | ||
properties: { | ||
contextName: { | ||
type: 'string', | ||
}, | ||
operator: { | ||
type: 'string', | ||
}, | ||
values: { | ||
type: 'array', | ||
items: { | ||
type: 'string', | ||
}, | ||
}, | ||
}, | ||
} as const; | ||
|
||
export type ConstraintSchema = CreateSchemaType<typeof schema>; | ||
|
||
export const constraintSchema = createSchemaObject(schema); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
import { OpenAPIV3 } from 'openapi-types'; | ||
|
||
export const createFeatureRequest: OpenAPIV3.RequestBodyObject = { | ||
required: true, | ||
content: { | ||
'application/json': { | ||
schema: { | ||
$ref: '#/components/schemas/createFeatureSchema', | ||
}, | ||
}, | ||
}, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
import { createSchemaObject, CreateSchemaType } from '../types'; | ||
|
||
const schema = { | ||
type: 'object', | ||
required: ['name'], | ||
properties: { | ||
name: { | ||
type: 'string', | ||
}, | ||
type: { | ||
type: 'string', | ||
}, | ||
description: { | ||
type: 'string', | ||
}, | ||
impressionData: { | ||
type: 'boolean', | ||
}, | ||
}, | ||
} as const; | ||
|
||
export type CreateFeatureSchema = CreateSchemaType<typeof schema>; | ||
|
||
export const createFeatureSchema = createSchemaObject(schema); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
import { OpenAPIV3 } from 'openapi-types'; | ||
|
||
export const featureResponse: OpenAPIV3.ResponseObject = { | ||
description: 'featureResponse', | ||
content: { | ||
'application/json': { | ||
schema: { | ||
$ref: '#/components/schemas/featureSchema', | ||
}, | ||
}, | ||
}, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
import { createSchemaObject, CreateSchemaType } from '../types'; | ||
|
||
const schema = { | ||
type: 'object', | ||
required: ['name', 'project'], | ||
properties: { | ||
name: { | ||
type: 'string', | ||
}, | ||
type: { | ||
type: 'string', | ||
}, | ||
description: { | ||
type: 'string', | ||
}, | ||
project: { | ||
type: 'string', | ||
}, | ||
enabled: { | ||
type: 'boolean', | ||
}, | ||
stale: { | ||
type: 'boolean', | ||
}, | ||
impressionData: { | ||
type: 'boolean', | ||
}, | ||
createdAt: { | ||
type: 'string', | ||
format: 'date', | ||
nullable: true, | ||
}, | ||
lastSeenAt: { | ||
type: 'string', | ||
format: 'date', | ||
nullable: true, | ||
}, | ||
strategies: { | ||
type: 'array', | ||
items: { | ||
$ref: '#/components/schemas/strategySchema', | ||
}, | ||
}, | ||
variants: { | ||
items: { | ||
$ref: '#/components/schemas/variantSchema', | ||
}, | ||
type: 'array', | ||
}, | ||
}, | ||
} as const; | ||
|
||
export type FeatureSchema = CreateSchemaType<typeof schema>; | ||
|
||
export const featureSchema = createSchemaObject(schema); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
import { OpenAPIV3 } from 'openapi-types'; | ||
|
||
export const featuresResponse: OpenAPIV3.ResponseObject = { | ||
description: 'featuresResponse', | ||
content: { | ||
'application/json': { | ||
schema: { | ||
$ref: '#/components/schemas/featuresSchema', | ||
}, | ||
}, | ||
}, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
import { createSchemaObject, CreateSchemaType } from '../types'; | ||
|
||
export const schema = { | ||
type: 'object', | ||
required: ['version', 'features'], | ||
properties: { | ||
version: { | ||
type: 'integer', | ||
}, | ||
features: { | ||
type: 'array', | ||
items: { | ||
$ref: '#/components/schemas/featureSchema', | ||
}, | ||
}, | ||
}, | ||
} as const; | ||
|
||
export type FeaturesSchema = CreateSchemaType<typeof schema>; | ||
|
||
export const featuresSchema = createSchemaObject(schema); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
import { createSchemaObject, CreateSchemaType } from '../types'; | ||
|
||
export const schema = { | ||
type: 'object', | ||
required: ['contextName', 'values'], | ||
properties: { | ||
contextName: { | ||
type: 'string', | ||
}, | ||
values: { | ||
type: 'array', | ||
items: { | ||
type: 'string', | ||
}, | ||
}, | ||
}, | ||
} as const; | ||
|
||
export type OverrideSchema = CreateSchemaType<typeof schema>; | ||
|
||
export const overrideSchema = createSchemaObject(schema); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
import { createSchemaObject, CreateSchemaType } from '../types'; | ||
|
||
export const schema = { | ||
type: 'object', | ||
required: ['id', 'name', 'constraints', 'parameters'], | ||
properties: { | ||
id: { | ||
type: 'string', | ||
}, | ||
name: { | ||
type: 'string', | ||
}, | ||
constraints: { | ||
type: 'array', | ||
items: { | ||
$ref: '#/components/schemas/constraintSchema', | ||
}, | ||
}, | ||
parameters: { | ||
type: 'object', | ||
}, | ||
}, | ||
} as const; | ||
|
||
export type StrategySchema = CreateSchemaType<typeof schema>; | ||
|
||
export const strategySchema = createSchemaObject(schema); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
import { createSchemaObject, CreateSchemaType } from '../types'; | ||
|
||
export const schema = { | ||
type: 'object', | ||
required: ['name', 'weight', 'weightType', 'stickiness', 'overrides'], | ||
properties: { | ||
name: { | ||
type: 'string', | ||
}, | ||
weight: { | ||
type: 'number', | ||
}, | ||
weightType: { | ||
type: 'string', | ||
}, | ||
stickiness: { | ||
type: 'string', | ||
}, | ||
payload: { | ||
type: 'object', | ||
}, | ||
overrides: { | ||
type: 'array', | ||
items: { | ||
$ref: '#/components/schemas/overrideSchema', | ||
}, | ||
}, | ||
}, | ||
} as const; | ||
|
||
export type VariantSchema = CreateSchemaType<typeof schema>; | ||
|
||
export const variantSchema = createSchemaObject(schema); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
import { OpenAPIV3 } from 'openapi-types'; | ||
import { FromSchema } from 'json-schema-to-ts'; | ||
import { DeepMutable } from '../types/mutable'; | ||
|
||
// Admin paths must have the "admin" tag. | ||
export interface AdminApiOperation | ||
extends Omit<OpenAPIV3.OperationObject, 'tags'> { | ||
tags: ['admin']; | ||
} | ||
|
||
// Client paths must have the "client" tag. | ||
export interface ClientApiOperation | ||
extends Omit<OpenAPIV3.OperationObject, 'tags'> { | ||
tags: ['client']; | ||
} | ||
|
||
// Create a type from a const schema object. | ||
export type CreateSchemaType<T> = FromSchema<T>; | ||
|
||
// Create an OpenAPIV3.SchemaObject from a const schema object. | ||
export const createSchemaObject = <T>(schema: T): DeepMutable<T> => schema; |
Oops, something went wrong.