Skip to content

Commit

Permalink
Refactor: move openapi utils into /util directory (#1777)
Browse files Browse the repository at this point in the history
* Refactor: move openapi utils into /util directory

* Refactor: move utils test into `util` directory

* Refactor: don't expose standard responses tied to status codes

* Feat: update empty response description + make it const

* Chore: update snapshot with new response descriptions
  • Loading branch information
thomasheartman committed Jul 1, 2022
1 parent 16dc677 commit 1a5749c
Show file tree
Hide file tree
Showing 43 changed files with 173 additions and 157 deletions.
39 changes: 1 addition & 38 deletions src/lib/openapi/index.test.ts
@@ -1,10 +1,4 @@
import {
createOpenApiSchema,
createRequestSchema,
createResponseSchema,
removeJsonSchemaProps,
schemas,
} from './index';
import { createOpenApiSchema, removeJsonSchemaProps, schemas } from './index';
import fs from 'fs';
import path from 'path';

Expand Down Expand Up @@ -32,37 +26,6 @@ test('all schema $id attributes should have the expected format', () => {
});
});

test('createRequestSchema', () => {
expect(createRequestSchema('schemaName')).toMatchInlineSnapshot(`
Object {
"content": Object {
"application/json": Object {
"schema": Object {
"$ref": "#/components/schemas/schemaName",
},
},
},
"description": "schemaName",
"required": true,
}
`);
});

test('createResponseSchema', () => {
expect(createResponseSchema('schemaName')).toMatchInlineSnapshot(`
Object {
"content": Object {
"application/json": Object {
"schema": Object {
"$ref": "#/components/schemas/schemaName",
},
},
},
"description": "schemaName",
}
`);
});

test('removeJsonSchemaProps', () => {
expect(removeJsonSchemaProps({ a: 'b', $id: 'c', components: {} }))
.toMatchInlineSnapshot(`
Expand Down
37 changes: 0 additions & 37 deletions src/lib/openapi/index.ts
Expand Up @@ -204,43 +204,6 @@ export interface JsonSchemaProps {
components: object;
}

export interface ApiOperation<Tag = 'admin' | 'client' | 'auth' | 'other'>
extends Omit<OpenAPIV3.OperationObject, 'tags'> {
operationId: string;
tags: [Tag];
}

export const createRequestSchema = (
schemaName: string,
): OpenAPIV3.RequestBodyObject => {
return {
description: schemaName,
required: true,
content: {
'application/json': {
schema: {
$ref: `#/components/schemas/${schemaName}`,
},
},
},
};
};

export const createResponseSchema = (
schemaName: string,
): OpenAPIV3.ResponseObject => {
return {
description: schemaName,
content: {
'application/json': {
schema: {
$ref: `#/components/schemas/${schemaName}`,
},
},
},
};
};

// Remove JSONSchema keys that would result in an invalid OpenAPI spec.
export const removeJsonSchemaProps = <T extends JsonSchemaProps>(
schema: T,
Expand Down
Empty file.
7 changes: 7 additions & 0 deletions src/lib/openapi/util/api-operation.ts
@@ -0,0 +1,7 @@
import { OpenAPIV3 } from 'openapi-types';

export interface ApiOperation<Tag = 'admin' | 'client' | 'auth' | 'other'>
extends Omit<OpenAPIV3.OperationObject, 'tags'> {
operationId: string;
tags: [Tag];
}
17 changes: 17 additions & 0 deletions src/lib/openapi/util/create-request-schema.test.ts
@@ -0,0 +1,17 @@
import { createRequestSchema } from './create-request-schema';

test('createRequestSchema', () => {
expect(createRequestSchema('schemaName')).toMatchInlineSnapshot(`
Object {
"content": Object {
"application/json": Object {
"schema": Object {
"$ref": "#/components/schemas/schemaName",
},
},
},
"description": "schemaName",
"required": true,
}
`);
});
17 changes: 17 additions & 0 deletions src/lib/openapi/util/create-request-schema.ts
@@ -0,0 +1,17 @@
import { OpenAPIV3 } from 'openapi-types';

export const createRequestSchema = (
schemaName: string,
): OpenAPIV3.RequestBodyObject => {
return {
description: schemaName,
required: true,
content: {
'application/json': {
schema: {
$ref: `#/components/schemas/${schemaName}`,
},
},
},
};
};
16 changes: 16 additions & 0 deletions src/lib/openapi/util/create-response-schema.test.ts
@@ -0,0 +1,16 @@
import { createResponseSchema } from './create-response-schema';

test('createResponseSchema', () => {
expect(createResponseSchema('schemaName')).toMatchInlineSnapshot(`
Object {
"content": Object {
"application/json": Object {
"schema": Object {
"$ref": "#/components/schemas/schemaName",
},
},
},
"description": "schemaName",
}
`);
});
16 changes: 16 additions & 0 deletions src/lib/openapi/util/create-response-schema.ts
@@ -0,0 +1,16 @@
import { OpenAPIV3 } from 'openapi-types';

export const createResponseSchema = (
schemaName: string,
): OpenAPIV3.ResponseObject => {
return {
description: schemaName,
content: {
'application/json': {
schema: {
$ref: `#/components/schemas/${schemaName}`,
},
},
},
};
};
10 changes: 5 additions & 5 deletions src/lib/openapi/util/standard-responses.ts
@@ -1,14 +1,14 @@
export const emptyResponse = {
description: 'emptyResponse',
};
description: 'This response has no body.',
} as const;

export const unauthorizedResponse = {
const unauthorizedResponse = {
description:
'Authorization information is missing or invalid. Provide a valid API token as the `authorization` header, e.g. `authorization:*.*.my-admin-token`.',
} as const;

export const badRequestResponse = {
description: 'The request data do not match what we expect.',
const badRequestResponse = {
description: 'The request data does not match what we expect.',
} as const;

const standardResponses = {
Expand Down
3 changes: 2 additions & 1 deletion src/lib/routes/admin-api/addon.ts
Expand Up @@ -12,7 +12,8 @@ import {
UPDATE_ADDON,
} from '../../types/permissions';
import { IAuthRequest } from '../unleash-types';
import { createRequestSchema, createResponseSchema } from '../../openapi';
import { createRequestSchema } from '../../openapi/util/create-request-schema';
import { createResponseSchema } from '../../openapi/util/create-response-schema';
import { OpenApiService } from '../../services/openapi-service';
import { AddonSchema, addonSchema } from '../../openapi/spec/addon-schema';
import { serializeDates } from '../../types/serialize-dates';
Expand Down
3 changes: 2 additions & 1 deletion src/lib/routes/admin-api/api-token.ts
Expand Up @@ -18,7 +18,8 @@ import { ApiTokenType, IApiToken } from '../../types/models/api-token';
import { createApiToken } from '../../schema/api-token-schema';
import { OpenApiService } from '../../services/openapi-service';
import { IUnleashServices } from '../../types';
import { createRequestSchema, createResponseSchema } from '../../openapi';
import { createRequestSchema } from '../../openapi/util/create-request-schema';
import { createResponseSchema } from '../../openapi/util/create-response-schema';
import {
apiTokensSchema,
ApiTokensSchema,
Expand Down
2 changes: 1 addition & 1 deletion src/lib/routes/admin-api/archive.ts
Expand Up @@ -13,7 +13,7 @@ import {
} from '../../openapi/spec/features-schema';
import { serializeDates } from '../../types/serialize-dates';
import { OpenApiService } from '../../services/openapi-service';
import { createResponseSchema } from '../../openapi';
import { createResponseSchema } from '../../openapi/util/create-response-schema';
import { emptyResponse } from '../../openapi/util/standard-responses';

export default class ArchiveController extends Controller {
Expand Down
2 changes: 1 addition & 1 deletion src/lib/routes/admin-api/bootstrap-ui.ts
Expand Up @@ -21,7 +21,7 @@ import { IProject } from '../../types/model';
import { IUserPermission } from '../../types/stores/access-store';
import { OpenApiService } from '../../services/openapi-service';
import { NONE } from '../../types/permissions';
import { createResponseSchema } from '../../openapi';
import { createResponseSchema } from '../../openapi/util/create-response-schema';
import {
BootstrapUiSchema,
bootstrapUiSchema,
Expand Down
2 changes: 1 addition & 1 deletion src/lib/routes/admin-api/client-metrics.ts
Expand Up @@ -5,7 +5,7 @@ import { IUnleashServices } from '../../types';
import { Logger } from '../../logger';
import ClientMetricsServiceV2 from '../../services/client-metrics/metrics-service-v2';
import { NONE } from '../../types/permissions';
import { createResponseSchema } from '../../openapi';
import { createResponseSchema } from '../../openapi/util/create-response-schema';
import { OpenApiService } from '../../services/openapi-service';
import { serializeDates } from '../../types/serialize-dates';
import {
Expand Down
2 changes: 1 addition & 1 deletion src/lib/routes/admin-api/config.ts
Expand Up @@ -10,7 +10,7 @@ import {
SimpleAuthSettings,
} from '../../types/settings/simple-auth-settings';
import { NONE } from '../../types/permissions';
import { createResponseSchema } from '../../openapi';
import { createResponseSchema } from '../../openapi/util/create-response-schema';
import {
uiConfigSchema,
UiConfigSchema,
Expand Down
2 changes: 1 addition & 1 deletion src/lib/routes/admin-api/constraints.ts
Expand Up @@ -7,7 +7,7 @@ import { NONE } from '../../types/permissions';
import Controller from '../controller';
import { Logger } from '../../logger';
import { OpenApiService } from '../../services/openapi-service';
import { createRequestSchema } from '../../openapi';
import { createRequestSchema } from '../../openapi/util/create-request-schema';

export default class ConstraintController extends Controller {
private featureService: FeatureToggleService;
Expand Down
3 changes: 2 additions & 1 deletion src/lib/routes/admin-api/context.ts
Expand Up @@ -23,7 +23,8 @@ import {
} from '../../openapi/spec/context-field-schema';
import { ContextFieldsSchema } from '../../openapi/spec/context-fields-schema';
import { UpsertContextFieldSchema } from '../../openapi/spec/upsert-context-field-schema';
import { createRequestSchema, createResponseSchema } from '../../openapi';
import { createRequestSchema } from '../../openapi/util/create-request-schema';
import { createResponseSchema } from '../../openapi/util/create-response-schema';
import { serializeDates } from '../../types/serialize-dates';
import NotFoundError from '../../error/notfound-error';
import { NameSchema } from '../../openapi/spec/name-schema';
Expand Down
3 changes: 2 additions & 1 deletion src/lib/routes/admin-api/environments.ts
Expand Up @@ -6,7 +6,8 @@ import EnvironmentService from '../../services/environment-service';
import { Logger } from '../../logger';
import { ADMIN, NONE } from '../../types/permissions';
import { OpenApiService } from '../../services/openapi-service';
import { createRequestSchema, createResponseSchema } from '../../openapi';
import { createRequestSchema } from '../../openapi/util/create-request-schema';
import { createResponseSchema } from '../../openapi/util/create-response-schema';
import {
environmentsSchema,
EnvironmentsSchema,
Expand Down
4 changes: 2 additions & 2 deletions src/lib/routes/admin-api/event.ts
Expand Up @@ -7,8 +7,8 @@ import { IEvent } from '../../types/events';
import Controller from '../controller';
import { anonymise } from '../../util/anonymise';
import { OpenApiService } from '../../services/openapi-service';
import { createResponseSchema } from '../../../lib/openapi';
import { endpointDescriptions } from '../../../lib/openapi/endpoint-descriptions';
import { createResponseSchema } from '../../openapi/util/create-response-schema';
import { endpointDescriptions } from '../../openapi/endpoint-descriptions';
import {
eventsSchema,
EventsSchema,
Expand Down
2 changes: 1 addition & 1 deletion src/lib/routes/admin-api/feature-type.ts
Expand Up @@ -6,7 +6,7 @@ import { IUnleashConfig } from '../../types/option';
import { OpenApiService } from '../../services/openapi-service';
import { NONE } from '../../types/permissions';
import { FeatureTypesSchema } from '../../openapi/spec/feature-types-schema';
import { createResponseSchema } from '../../openapi';
import { createResponseSchema } from '../../openapi/util/create-response-schema';
import Controller from '../controller';

const version = 1;
Expand Down
3 changes: 2 additions & 1 deletion src/lib/routes/admin-api/feature.ts
Expand Up @@ -24,7 +24,8 @@ import { TagSchema } from '../../openapi/spec/tag-schema';
import { TagsSchema } from '../../openapi/spec/tags-schema';
import { serializeDates } from '../../types/serialize-dates';
import { OpenApiService } from '../../services/openapi-service';
import { createRequestSchema, createResponseSchema } from '../../openapi';
import { createRequestSchema } from '../../openapi/util/create-request-schema';
import { createResponseSchema } from '../../openapi/util/create-response-schema';
import { emptyResponse } from '../../openapi/util/standard-responses';

const version = 1;
Expand Down
3 changes: 2 additions & 1 deletion src/lib/routes/admin-api/metrics.ts
Expand Up @@ -5,7 +5,8 @@ import { IUnleashConfig } from '../../types/option';
import { IUnleashServices } from '../../types/services';
import { Logger } from '../../logger';
import ClientInstanceService from '../../services/client-metrics/instance-service';
import { createRequestSchema, createResponseSchema } from '../../openapi';
import { createRequestSchema } from '../../openapi/util/create-request-schema';
import { createResponseSchema } from '../../openapi/util/create-response-schema';
import { ApplicationSchema } from '../../openapi/spec/application-schema';
import { ApplicationsSchema } from '../../openapi/spec/applications-schema';
import { emptyResponse } from '../../openapi/util/standard-responses';
Expand Down
2 changes: 1 addition & 1 deletion src/lib/routes/admin-api/project/environments.ts
Expand Up @@ -5,7 +5,7 @@ import { IUnleashServices } from '../../../types/services';
import { Logger } from '../../../logger';
import EnvironmentService from '../../../services/environment-service';
import { UPDATE_PROJECT } from '../../../types/permissions';
import { createRequestSchema } from '../../../openapi';
import { createRequestSchema } from '../../../openapi/util/create-request-schema';
import { ProjectEnvironmentSchema } from '../../../openapi/spec/project-environment-schema';
import { emptyResponse } from '../../../openapi/util/standard-responses';

Expand Down
3 changes: 2 additions & 1 deletion src/lib/routes/admin-api/project/features.ts
Expand Up @@ -33,7 +33,8 @@ import { UpdateFeatureStrategySchema } from '../../../openapi/spec/update-featur
import { CreateFeatureStrategySchema } from '../../../openapi/spec/create-feature-strategy-schema';
import { serializeDates } from '../../../types/serialize-dates';
import { OpenApiService } from '../../../services/openapi-service';
import { createRequestSchema, createResponseSchema } from '../../../openapi';
import { createRequestSchema } from '../../../openapi/util/create-request-schema';
import { createResponseSchema } from '../../../openapi/util/create-response-schema';
import { FeatureEnvironmentSchema } from '../../../openapi/spec/feature-environment-schema';
import { emptyResponse } from '../../../openapi/util/standard-responses';

Expand Down
2 changes: 1 addition & 1 deletion src/lib/routes/admin-api/project/health-report.ts
Expand Up @@ -7,7 +7,7 @@ import { Logger } from '../../../logger';
import { IArchivedQuery, IProjectParam } from '../../../types/model';
import { NONE } from '../../../types/permissions';
import { OpenApiService } from '../../../services/openapi-service';
import { createResponseSchema } from '../../../openapi';
import { createResponseSchema } from '../../../openapi/util/create-response-schema';
import {
healthOverviewSchema,
HealthOverviewSchema,
Expand Down
2 changes: 1 addition & 1 deletion src/lib/routes/admin-api/project/index.ts
Expand Up @@ -14,7 +14,7 @@ import {
} from '../../../openapi/spec/projects-schema';
import { OpenApiService } from '../../../services/openapi-service';
import { serializeDates } from '../../../types/serialize-dates';
import { createResponseSchema } from '../../../openapi';
import { createResponseSchema } from '../../../openapi/util/create-response-schema';

export default class ProjectApi extends Controller {
private projectService: ProjectService;
Expand Down
3 changes: 2 additions & 1 deletion src/lib/routes/admin-api/project/variants.ts
Expand Up @@ -10,7 +10,8 @@ import { IVariant } from '../../../types/model';
import { extractUsername } from '../../../util/extract-user';
import { IAuthRequest } from '../../unleash-types';
import { FeatureVariantsSchema } from '../../../openapi/spec/feature-variants-schema';
import { createRequestSchema, createResponseSchema } from '../../../openapi';
import { createRequestSchema } from '../../../openapi/util/create-request-schema';
import { createResponseSchema } from '../../../openapi/util/create-response-schema';

const PREFIX = '/:projectId/features/:featureName/variants';

Expand Down
3 changes: 2 additions & 1 deletion src/lib/routes/admin-api/state.ts
Expand Up @@ -12,7 +12,8 @@ import { Logger } from '../../logger';
import StateService from '../../services/state-service';
import { IAuthRequest } from '../unleash-types';
import { OpenApiService } from '../../services/openapi-service';
import { createRequestSchema, createResponseSchema } from '../../openapi';
import { createRequestSchema } from '../../openapi/util/create-request-schema';
import { createResponseSchema } from '../../openapi/util/create-response-schema';
import { ExportParametersSchema } from '../../openapi/spec/export-parameters-schema';
import { emptyResponse } from '../../openapi/util/standard-responses';

Expand Down
5 changes: 3 additions & 2 deletions src/lib/routes/admin-api/strategy.ts
Expand Up @@ -13,7 +13,9 @@ import {
import { Request, Response } from 'express';
import { IAuthRequest } from '../unleash-types';
import { OpenApiService } from '../../services/openapi-service';
import { createRequestSchema, createResponseSchema } from '../../openapi';
import { emptyResponse } from '../../openapi/util/standard-responses';
import { createRequestSchema } from '../../openapi/util/create-request-schema';
import { createResponseSchema } from '../../openapi/util/create-response-schema';
import {
strategySchema,
StrategySchema,
Expand All @@ -23,7 +25,6 @@ import {
StrategiesSchema,
} from '../../openapi/spec/strategies-schema';
import { UpsertStrategySchema } from '../../openapi/spec/upsert-strategy-schema';
import { emptyResponse } from '../../openapi/util/standard-responses';

const version = 1;

Expand Down

0 comments on commit 1a5749c

Please sign in to comment.