mirror of
https://github.com/Unleash/unleash.git
synced 2025-01-11 00:08:30 +01:00
refactor: add OpenAPI schema to context controller (#1711)
* refactor: add OpenAPI schema to context controller * Update src/lib/routes/admin-api/context.ts Co-authored-by: olav <mail@olav.io> * address PR comments, misc fixes and improvements * refactor: address PR comments * add createdAt to test * fix: reverted upsert schema after discussion Co-authored-by: olav <mail@olav.io>
This commit is contained in:
parent
e6b49e4bce
commit
525fce3e86
@ -1,6 +1,8 @@
|
|||||||
import { OpenAPIV3 } from 'openapi-types';
|
import { OpenAPIV3 } from 'openapi-types';
|
||||||
import { cloneFeatureSchema } from './spec/clone-feature-schema';
|
import { cloneFeatureSchema } from './spec/clone-feature-schema';
|
||||||
import { constraintSchema } from './spec/constraint-schema';
|
import { constraintSchema } from './spec/constraint-schema';
|
||||||
|
import { contextFieldSchema } from './spec/context-field-schema';
|
||||||
|
import { contextFieldsSchema } from './spec/context-fields-schema';
|
||||||
import { createFeatureSchema } from './spec/create-feature-schema';
|
import { createFeatureSchema } from './spec/create-feature-schema';
|
||||||
import { createStrategySchema } from './spec/create-strategy-schema';
|
import { createStrategySchema } from './spec/create-strategy-schema';
|
||||||
import { environmentSchema } from './spec/environment-schema';
|
import { environmentSchema } from './spec/environment-schema';
|
||||||
@ -15,7 +17,9 @@ import { featuresSchema } from './spec/features-schema';
|
|||||||
import { feedbackSchema } from './spec/feedback-schema';
|
import { feedbackSchema } from './spec/feedback-schema';
|
||||||
import { healthOverviewSchema } from './spec/health-overview-schema';
|
import { healthOverviewSchema } from './spec/health-overview-schema';
|
||||||
import { healthReportSchema } from './spec/health-report-schema';
|
import { healthReportSchema } from './spec/health-report-schema';
|
||||||
|
import { legalValueSchema } from './spec/legal-value-schema';
|
||||||
import { mapValues } from '../util/map-values';
|
import { mapValues } from '../util/map-values';
|
||||||
|
import { nameSchema } from './spec/name-schema';
|
||||||
import { omitKeys } from '../util/omit-keys';
|
import { omitKeys } from '../util/omit-keys';
|
||||||
import { overrideSchema } from './spec/override-schema';
|
import { overrideSchema } from './spec/override-schema';
|
||||||
import { parametersSchema } from './spec/parameters-schema';
|
import { parametersSchema } from './spec/parameters-schema';
|
||||||
@ -32,6 +36,7 @@ import { tagsSchema } from './spec/tags-schema';
|
|||||||
import { uiConfigSchema } from './spec/ui-config-schema';
|
import { uiConfigSchema } from './spec/ui-config-schema';
|
||||||
import { updateFeatureSchema } from './spec/update-feature-schema';
|
import { updateFeatureSchema } from './spec/update-feature-schema';
|
||||||
import { updateStrategySchema } from './spec/update-strategy-schema';
|
import { updateStrategySchema } from './spec/update-strategy-schema';
|
||||||
|
import { upsertContextFieldSchema } from './spec/upsert-context-field-schema';
|
||||||
import { variantSchema } from './spec/variant-schema';
|
import { variantSchema } from './spec/variant-schema';
|
||||||
import { variantsSchema } from './spec/variants-schema';
|
import { variantsSchema } from './spec/variants-schema';
|
||||||
import { versionSchema } from './spec/version-schema';
|
import { versionSchema } from './spec/version-schema';
|
||||||
@ -44,6 +49,8 @@ import { validateTagTypeSchema } from './spec/validate-tag-type-schema';
|
|||||||
export const schemas = {
|
export const schemas = {
|
||||||
cloneFeatureSchema,
|
cloneFeatureSchema,
|
||||||
constraintSchema,
|
constraintSchema,
|
||||||
|
contextFieldSchema,
|
||||||
|
contextFieldsSchema,
|
||||||
createFeatureSchema,
|
createFeatureSchema,
|
||||||
createStrategySchema,
|
createStrategySchema,
|
||||||
environmentSchema,
|
environmentSchema,
|
||||||
@ -58,6 +65,8 @@ export const schemas = {
|
|||||||
feedbackSchema,
|
feedbackSchema,
|
||||||
healthOverviewSchema,
|
healthOverviewSchema,
|
||||||
healthReportSchema,
|
healthReportSchema,
|
||||||
|
legalValueSchema,
|
||||||
|
nameSchema,
|
||||||
overrideSchema,
|
overrideSchema,
|
||||||
parametersSchema,
|
parametersSchema,
|
||||||
patchSchema,
|
patchSchema,
|
||||||
@ -76,6 +85,7 @@ export const schemas = {
|
|||||||
updateFeatureSchema,
|
updateFeatureSchema,
|
||||||
updateStrategySchema,
|
updateStrategySchema,
|
||||||
updateTagTypeSchema,
|
updateTagTypeSchema,
|
||||||
|
upsertContextFieldSchema,
|
||||||
validateTagTypeSchema,
|
validateTagTypeSchema,
|
||||||
variantSchema,
|
variantSchema,
|
||||||
variantsSchema,
|
variantsSchema,
|
||||||
|
@ -0,0 +1,19 @@
|
|||||||
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
|
exports[`contextFieldSchema empty 1`] = `
|
||||||
|
Object {
|
||||||
|
"data": Object {},
|
||||||
|
"errors": Array [
|
||||||
|
Object {
|
||||||
|
"instancePath": "",
|
||||||
|
"keyword": "required",
|
||||||
|
"message": "must have required property 'name'",
|
||||||
|
"params": Object {
|
||||||
|
"missingProperty": "name",
|
||||||
|
},
|
||||||
|
"schemaPath": "#/required",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"schema": "#/components/schemas/contextFieldSchema",
|
||||||
|
}
|
||||||
|
`;
|
23
src/lib/openapi/spec/context-field-schema.test.ts
Normal file
23
src/lib/openapi/spec/context-field-schema.test.ts
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
import { validateSchema } from '../validate';
|
||||||
|
import { ContextFieldSchema } from './context-field-schema';
|
||||||
|
|
||||||
|
test('contextFieldSchema', () => {
|
||||||
|
const data: ContextFieldSchema = {
|
||||||
|
name: '',
|
||||||
|
description: '',
|
||||||
|
stickiness: false,
|
||||||
|
sortOrder: 0,
|
||||||
|
createdAt: '2022-01-01T00:00:00.000Z',
|
||||||
|
legalValues: [],
|
||||||
|
};
|
||||||
|
|
||||||
|
expect(
|
||||||
|
validateSchema('#/components/schemas/contextFieldSchema', data),
|
||||||
|
).toBeUndefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('contextFieldSchema empty', () => {
|
||||||
|
expect(
|
||||||
|
validateSchema('#/components/schemas/contextFieldSchema', {}),
|
||||||
|
).toMatchSnapshot();
|
||||||
|
});
|
41
src/lib/openapi/spec/context-field-schema.ts
Normal file
41
src/lib/openapi/spec/context-field-schema.ts
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
import { FromSchema } from 'json-schema-to-ts';
|
||||||
|
import { legalValueSchema } from './legal-value-schema';
|
||||||
|
|
||||||
|
export const contextFieldSchema = {
|
||||||
|
$id: '#/components/schemas/contextFieldSchema',
|
||||||
|
type: 'object',
|
||||||
|
additionalProperties: false,
|
||||||
|
required: ['name'],
|
||||||
|
properties: {
|
||||||
|
name: {
|
||||||
|
type: 'string',
|
||||||
|
},
|
||||||
|
description: {
|
||||||
|
type: 'string',
|
||||||
|
},
|
||||||
|
stickiness: {
|
||||||
|
type: 'boolean',
|
||||||
|
},
|
||||||
|
sortOrder: {
|
||||||
|
type: 'number',
|
||||||
|
},
|
||||||
|
createdAt: {
|
||||||
|
type: 'string',
|
||||||
|
format: 'date-time',
|
||||||
|
nullable: true,
|
||||||
|
},
|
||||||
|
legalValues: {
|
||||||
|
type: 'array',
|
||||||
|
items: {
|
||||||
|
$ref: '#/components/schemas/legalValueSchema',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
components: {
|
||||||
|
schemas: {
|
||||||
|
legalValueSchema,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
} as const;
|
||||||
|
|
||||||
|
export type ContextFieldSchema = FromSchema<typeof contextFieldSchema>;
|
19
src/lib/openapi/spec/context-fields-schema.ts
Normal file
19
src/lib/openapi/spec/context-fields-schema.ts
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
import { FromSchema } from 'json-schema-to-ts';
|
||||||
|
import { contextFieldSchema } from './context-field-schema';
|
||||||
|
import { legalValueSchema } from './legal-value-schema';
|
||||||
|
|
||||||
|
export const contextFieldsSchema = {
|
||||||
|
$id: '#/components/schemas/contextFieldsSchema',
|
||||||
|
type: 'array',
|
||||||
|
items: {
|
||||||
|
$ref: '#/components/schemas/contextFieldSchema',
|
||||||
|
},
|
||||||
|
components: {
|
||||||
|
schemas: {
|
||||||
|
contextFieldSchema,
|
||||||
|
legalValueSchema,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
} as const;
|
||||||
|
|
||||||
|
export type ContextFieldsSchema = FromSchema<typeof contextFieldsSchema>;
|
19
src/lib/openapi/spec/legal-value-schema.ts
Normal file
19
src/lib/openapi/spec/legal-value-schema.ts
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
import { FromSchema } from 'json-schema-to-ts';
|
||||||
|
|
||||||
|
export const legalValueSchema = {
|
||||||
|
$id: '#/components/schemas/legalValueSchema',
|
||||||
|
type: 'object',
|
||||||
|
additionalProperties: false,
|
||||||
|
required: ['value'],
|
||||||
|
properties: {
|
||||||
|
value: {
|
||||||
|
type: 'string',
|
||||||
|
},
|
||||||
|
description: {
|
||||||
|
type: 'string',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
components: {},
|
||||||
|
} as const;
|
||||||
|
|
||||||
|
export type LegalValueSchema = FromSchema<typeof legalValueSchema>;
|
16
src/lib/openapi/spec/name-schema.ts
Normal file
16
src/lib/openapi/spec/name-schema.ts
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
import { FromSchema } from 'json-schema-to-ts';
|
||||||
|
|
||||||
|
export const nameSchema = {
|
||||||
|
$id: '#/components/schemas/nameSchema',
|
||||||
|
type: 'object',
|
||||||
|
additionalProperties: false,
|
||||||
|
required: ['name'],
|
||||||
|
properties: {
|
||||||
|
name: {
|
||||||
|
type: 'string',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
components: {},
|
||||||
|
} as const;
|
||||||
|
|
||||||
|
export type NameSchema = FromSchema<typeof nameSchema>;
|
38
src/lib/openapi/spec/upsert-context-field-schema.ts
Normal file
38
src/lib/openapi/spec/upsert-context-field-schema.ts
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
import { FromSchema } from 'json-schema-to-ts';
|
||||||
|
import { legalValueSchema } from './legal-value-schema';
|
||||||
|
|
||||||
|
export const upsertContextFieldSchema = {
|
||||||
|
$id: '#/components/schemas/upsertContextFieldSchema',
|
||||||
|
type: 'object',
|
||||||
|
additionalProperties: false,
|
||||||
|
required: ['name'],
|
||||||
|
properties: {
|
||||||
|
name: {
|
||||||
|
type: 'string',
|
||||||
|
},
|
||||||
|
description: {
|
||||||
|
type: 'string',
|
||||||
|
},
|
||||||
|
stickiness: {
|
||||||
|
type: 'boolean',
|
||||||
|
},
|
||||||
|
sortOrder: {
|
||||||
|
type: 'number',
|
||||||
|
},
|
||||||
|
legalValues: {
|
||||||
|
type: 'array',
|
||||||
|
items: {
|
||||||
|
$ref: '#/components/schemas/legalValueSchema',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
components: {
|
||||||
|
schemas: {
|
||||||
|
legalValueSchema,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
} as const;
|
||||||
|
|
||||||
|
export type UpsertContextFieldSchema = FromSchema<
|
||||||
|
typeof upsertContextFieldSchema
|
||||||
|
>;
|
@ -8,6 +8,7 @@ import {
|
|||||||
CREATE_CONTEXT_FIELD,
|
CREATE_CONTEXT_FIELD,
|
||||||
UPDATE_CONTEXT_FIELD,
|
UPDATE_CONTEXT_FIELD,
|
||||||
DELETE_CONTEXT_FIELD,
|
DELETE_CONTEXT_FIELD,
|
||||||
|
NONE,
|
||||||
} from '../../types/permissions';
|
} from '../../types/permissions';
|
||||||
import { IUnleashConfig } from '../../types/option';
|
import { IUnleashConfig } from '../../types/option';
|
||||||
import { IUnleashServices } from '../../types/services';
|
import { IUnleashServices } from '../../types/services';
|
||||||
@ -15,53 +16,180 @@ import ContextService from '../../services/context-service';
|
|||||||
import { Logger } from '../../logger';
|
import { Logger } from '../../logger';
|
||||||
import { IAuthRequest } from '../unleash-types';
|
import { IAuthRequest } from '../unleash-types';
|
||||||
|
|
||||||
class ContextController extends Controller {
|
import { OpenApiService } from '../../services/openapi-service';
|
||||||
private logger: Logger;
|
import {
|
||||||
|
contextFieldSchema,
|
||||||
|
ContextFieldSchema,
|
||||||
|
} 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 { serializeDates } from '../../types/serialize-dates';
|
||||||
|
import NotFoundError from '../../error/notfound-error';
|
||||||
|
import { emptyResponse } from '../../openapi/spec/empty-response';
|
||||||
|
import { NameSchema } from '../../openapi/spec/name-schema';
|
||||||
|
|
||||||
|
interface ContextParam {
|
||||||
|
contextField: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class ContextController extends Controller {
|
||||||
private contextService: ContextService;
|
private contextService: ContextService;
|
||||||
|
|
||||||
|
private openApiService: OpenApiService;
|
||||||
|
|
||||||
|
private logger: Logger;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
config: IUnleashConfig,
|
config: IUnleashConfig,
|
||||||
{ contextService }: Pick<IUnleashServices, 'contextService'>,
|
{
|
||||||
|
contextService,
|
||||||
|
openApiService,
|
||||||
|
}: Pick<IUnleashServices, 'contextService' | 'openApiService'>,
|
||||||
) {
|
) {
|
||||||
super(config);
|
super(config);
|
||||||
|
this.openApiService = openApiService;
|
||||||
this.logger = config.getLogger('/admin-api/context.ts');
|
this.logger = config.getLogger('/admin-api/context.ts');
|
||||||
this.contextService = contextService;
|
this.contextService = contextService;
|
||||||
|
|
||||||
this.get('/', this.getContextFields);
|
this.route({
|
||||||
this.post('/', this.createContextField, CREATE_CONTEXT_FIELD);
|
method: 'get',
|
||||||
this.get('/:contextField', this.getContextField);
|
path: '',
|
||||||
this.put(
|
handler: this.getContextFields,
|
||||||
'/:contextField',
|
permission: NONE,
|
||||||
this.updateContextField,
|
middleware: [
|
||||||
UPDATE_CONTEXT_FIELD,
|
openApiService.validPath({
|
||||||
);
|
tags: ['admin'],
|
||||||
this.delete(
|
operationId: 'getContextFields',
|
||||||
'/:contextField',
|
responses: {
|
||||||
this.deleteContextField,
|
200: createResponseSchema('contextFieldsSchema'),
|
||||||
DELETE_CONTEXT_FIELD,
|
},
|
||||||
);
|
}),
|
||||||
this.post('/validate', this.validate, UPDATE_CONTEXT_FIELD);
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
this.route({
|
||||||
|
method: 'get',
|
||||||
|
path: '/:contextField',
|
||||||
|
handler: this.getContextField,
|
||||||
|
permission: NONE,
|
||||||
|
middleware: [
|
||||||
|
openApiService.validPath({
|
||||||
|
tags: ['admin'],
|
||||||
|
operationId: 'getContextField',
|
||||||
|
responses: {
|
||||||
|
200: createResponseSchema('contextFieldSchema'),
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
this.route({
|
||||||
|
method: 'post',
|
||||||
|
path: '',
|
||||||
|
handler: this.createContextField,
|
||||||
|
permission: CREATE_CONTEXT_FIELD,
|
||||||
|
middleware: [
|
||||||
|
openApiService.validPath({
|
||||||
|
tags: ['admin'],
|
||||||
|
operationId: 'createContextField',
|
||||||
|
requestBody: createRequestSchema(
|
||||||
|
'upsertContextFieldSchema',
|
||||||
|
),
|
||||||
|
responses: {
|
||||||
|
201: emptyResponse,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
this.route({
|
||||||
|
method: 'put',
|
||||||
|
path: '/:contextField',
|
||||||
|
handler: this.updateContextField,
|
||||||
|
permission: UPDATE_CONTEXT_FIELD,
|
||||||
|
middleware: [
|
||||||
|
openApiService.validPath({
|
||||||
|
tags: ['admin'],
|
||||||
|
operationId: 'updateContextField',
|
||||||
|
requestBody: createRequestSchema(
|
||||||
|
'upsertContextFieldSchema',
|
||||||
|
),
|
||||||
|
responses: {
|
||||||
|
200: emptyResponse,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
this.route({
|
||||||
|
method: 'delete',
|
||||||
|
path: '/:contextField',
|
||||||
|
handler: this.deleteContextField,
|
||||||
|
acceptAnyContentType: true,
|
||||||
|
permission: DELETE_CONTEXT_FIELD,
|
||||||
|
middleware: [
|
||||||
|
openApiService.validPath({
|
||||||
|
tags: ['admin'],
|
||||||
|
operationId: 'deleteContextField',
|
||||||
|
responses: {
|
||||||
|
200: emptyResponse,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
this.route({
|
||||||
|
method: 'post',
|
||||||
|
path: '/validate',
|
||||||
|
handler: this.validate,
|
||||||
|
permission: UPDATE_CONTEXT_FIELD,
|
||||||
|
middleware: [
|
||||||
|
openApiService.validPath({
|
||||||
|
tags: ['admin'],
|
||||||
|
operationId: 'validate',
|
||||||
|
requestBody: createRequestSchema('nameSchema'),
|
||||||
|
responses: {
|
||||||
|
200: emptyResponse,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async getContextFields(req: Request, res: Response): Promise<void> {
|
async getContextFields(
|
||||||
const fields = await this.contextService.getAll();
|
req: Request,
|
||||||
res.status(200).json(fields).end();
|
res: Response<ContextFieldsSchema>,
|
||||||
|
): Promise<void> {
|
||||||
|
res.status(200)
|
||||||
|
.json(serializeDates(await this.contextService.getAll()))
|
||||||
|
.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
async getContextField(req: Request, res: Response): Promise<void> {
|
async getContextField(
|
||||||
|
req: Request<ContextParam>,
|
||||||
|
res: Response<ContextFieldSchema>,
|
||||||
|
): Promise<void> {
|
||||||
try {
|
try {
|
||||||
const name = req.params.contextField;
|
const name = req.params.contextField;
|
||||||
const contextField = await this.contextService.getContextField(
|
const contextField = await this.contextService.getContextField(
|
||||||
name,
|
name,
|
||||||
);
|
);
|
||||||
res.json(contextField).end();
|
this.openApiService.respondWithValidation(
|
||||||
|
200,
|
||||||
|
res,
|
||||||
|
contextFieldSchema.$id,
|
||||||
|
serializeDates(contextField),
|
||||||
|
);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
res.status(404).json({ error: 'Could not find context field' });
|
throw new NotFoundError('Could not find context field');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async createContextField(req: IAuthRequest, res: Response): Promise<void> {
|
async createContextField(
|
||||||
|
req: IAuthRequest<void, void, UpsertContextFieldSchema>,
|
||||||
|
res: Response,
|
||||||
|
): Promise<void> {
|
||||||
const value = req.body;
|
const value = req.body;
|
||||||
const userName = extractUsername(req);
|
const userName = extractUsername(req);
|
||||||
|
|
||||||
@ -69,7 +197,10 @@ class ContextController extends Controller {
|
|||||||
res.status(201).end();
|
res.status(201).end();
|
||||||
}
|
}
|
||||||
|
|
||||||
async updateContextField(req: IAuthRequest, res: Response): Promise<void> {
|
async updateContextField(
|
||||||
|
req: IAuthRequest<ContextParam, void, UpsertContextFieldSchema>,
|
||||||
|
res: Response,
|
||||||
|
): Promise<void> {
|
||||||
const name = req.params.contextField;
|
const name = req.params.contextField;
|
||||||
const userName = extractUsername(req);
|
const userName = extractUsername(req);
|
||||||
const contextField = req.body;
|
const contextField = req.body;
|
||||||
@ -80,7 +211,10 @@ class ContextController extends Controller {
|
|||||||
res.status(200).end();
|
res.status(200).end();
|
||||||
}
|
}
|
||||||
|
|
||||||
async deleteContextField(req: IAuthRequest, res: Response): Promise<void> {
|
async deleteContextField(
|
||||||
|
req: IAuthRequest<ContextParam>,
|
||||||
|
res: Response,
|
||||||
|
): Promise<void> {
|
||||||
const name = req.params.contextField;
|
const name = req.params.contextField;
|
||||||
const userName = extractUsername(req);
|
const userName = extractUsername(req);
|
||||||
|
|
||||||
@ -88,12 +222,13 @@ class ContextController extends Controller {
|
|||||||
res.status(200).end();
|
res.status(200).end();
|
||||||
}
|
}
|
||||||
|
|
||||||
async validate(req: Request, res: Response): Promise<void> {
|
async validate(
|
||||||
|
req: Request<void, void, NameSchema>,
|
||||||
|
res: Response,
|
||||||
|
): Promise<void> {
|
||||||
const { name } = req.body;
|
const { name } = req.body;
|
||||||
|
|
||||||
await this.contextService.validateName(name);
|
await this.contextService.validateName(name);
|
||||||
res.status(200).end();
|
res.status(200).end();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
export default ContextController;
|
|
||||||
module.exports = ContextController;
|
|
||||||
|
@ -10,7 +10,7 @@ import EventController from './event';
|
|||||||
import MetricsController from './metrics';
|
import MetricsController from './metrics';
|
||||||
import UserController from './user';
|
import UserController from './user';
|
||||||
import ConfigController from './config';
|
import ConfigController from './config';
|
||||||
import ContextController from './context';
|
import { ContextController } from './context';
|
||||||
import ClientMetricsController from './client-metrics';
|
import ClientMetricsController from './client-metrics';
|
||||||
import BootstrapController from './bootstrap';
|
import BootstrapController from './bootstrap';
|
||||||
import StateController from './state';
|
import StateController from './state';
|
||||||
|
@ -2,9 +2,9 @@ import { Store } from './store';
|
|||||||
|
|
||||||
export interface IContextFieldDto {
|
export interface IContextFieldDto {
|
||||||
name: string;
|
name: string;
|
||||||
description: string;
|
description?: string;
|
||||||
stickiness: boolean;
|
stickiness?: boolean;
|
||||||
sortOrder: number;
|
sortOrder?: number;
|
||||||
legalValues?: ILegalValue[];
|
legalValues?: ILegalValue[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,6 +113,44 @@ Object {
|
|||||||
],
|
],
|
||||||
"type": "object",
|
"type": "object",
|
||||||
},
|
},
|
||||||
|
"contextFieldSchema": Object {
|
||||||
|
"additionalProperties": false,
|
||||||
|
"properties": Object {
|
||||||
|
"createdAt": Object {
|
||||||
|
"format": "date-time",
|
||||||
|
"nullable": true,
|
||||||
|
"type": "string",
|
||||||
|
},
|
||||||
|
"description": Object {
|
||||||
|
"type": "string",
|
||||||
|
},
|
||||||
|
"legalValues": Object {
|
||||||
|
"items": Object {
|
||||||
|
"$ref": "#/components/schemas/legalValueSchema",
|
||||||
|
},
|
||||||
|
"type": "array",
|
||||||
|
},
|
||||||
|
"name": Object {
|
||||||
|
"type": "string",
|
||||||
|
},
|
||||||
|
"sortOrder": Object {
|
||||||
|
"type": "number",
|
||||||
|
},
|
||||||
|
"stickiness": Object {
|
||||||
|
"type": "boolean",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"required": Array [
|
||||||
|
"name",
|
||||||
|
],
|
||||||
|
"type": "object",
|
||||||
|
},
|
||||||
|
"contextFieldsSchema": Object {
|
||||||
|
"items": Object {
|
||||||
|
"$ref": "#/components/schemas/contextFieldSchema",
|
||||||
|
},
|
||||||
|
"type": "array",
|
||||||
|
},
|
||||||
"createFeatureSchema": Object {
|
"createFeatureSchema": Object {
|
||||||
"properties": Object {
|
"properties": Object {
|
||||||
"description": Object {
|
"description": Object {
|
||||||
@ -539,6 +577,33 @@ Object {
|
|||||||
],
|
],
|
||||||
"type": "object",
|
"type": "object",
|
||||||
},
|
},
|
||||||
|
"legalValueSchema": Object {
|
||||||
|
"additionalProperties": false,
|
||||||
|
"properties": Object {
|
||||||
|
"description": Object {
|
||||||
|
"type": "string",
|
||||||
|
},
|
||||||
|
"value": Object {
|
||||||
|
"type": "string",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"required": Array [
|
||||||
|
"value",
|
||||||
|
],
|
||||||
|
"type": "object",
|
||||||
|
},
|
||||||
|
"nameSchema": Object {
|
||||||
|
"additionalProperties": false,
|
||||||
|
"properties": Object {
|
||||||
|
"name": Object {
|
||||||
|
"type": "string",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"required": Array [
|
||||||
|
"name",
|
||||||
|
],
|
||||||
|
"type": "object",
|
||||||
|
},
|
||||||
"overrideSchema": Object {
|
"overrideSchema": Object {
|
||||||
"additionalProperties": false,
|
"additionalProperties": false,
|
||||||
"properties": Object {
|
"properties": Object {
|
||||||
@ -927,6 +992,33 @@ Object {
|
|||||||
},
|
},
|
||||||
"type": "object",
|
"type": "object",
|
||||||
},
|
},
|
||||||
|
"upsertContextFieldSchema": Object {
|
||||||
|
"additionalProperties": false,
|
||||||
|
"properties": Object {
|
||||||
|
"description": Object {
|
||||||
|
"type": "string",
|
||||||
|
},
|
||||||
|
"legalValues": Object {
|
||||||
|
"items": Object {
|
||||||
|
"$ref": "#/components/schemas/legalValueSchema",
|
||||||
|
},
|
||||||
|
"type": "array",
|
||||||
|
},
|
||||||
|
"name": Object {
|
||||||
|
"type": "string",
|
||||||
|
},
|
||||||
|
"sortOrder": Object {
|
||||||
|
"type": "number",
|
||||||
|
},
|
||||||
|
"stickiness": Object {
|
||||||
|
"type": "boolean",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"required": Array [
|
||||||
|
"name",
|
||||||
|
],
|
||||||
|
"type": "object",
|
||||||
|
},
|
||||||
"validateTagTypeSchema": Object {
|
"validateTagTypeSchema": Object {
|
||||||
"additionalProperties": false,
|
"additionalProperties": false,
|
||||||
"properties": Object {
|
"properties": Object {
|
||||||
@ -1175,6 +1267,155 @@ Object {
|
|||||||
],
|
],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
"/api/admin/context": Object {
|
||||||
|
"get": Object {
|
||||||
|
"operationId": "getContextFields",
|
||||||
|
"responses": Object {
|
||||||
|
"200": Object {
|
||||||
|
"content": Object {
|
||||||
|
"application/json": Object {
|
||||||
|
"schema": Object {
|
||||||
|
"$ref": "#/components/schemas/contextFieldsSchema",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"description": "contextFieldsSchema",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"tags": Array [
|
||||||
|
"admin",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
"post": Object {
|
||||||
|
"operationId": "createContextField",
|
||||||
|
"requestBody": Object {
|
||||||
|
"content": Object {
|
||||||
|
"application/json": Object {
|
||||||
|
"schema": Object {
|
||||||
|
"$ref": "#/components/schemas/upsertContextFieldSchema",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"description": "upsertContextFieldSchema",
|
||||||
|
"required": true,
|
||||||
|
},
|
||||||
|
"responses": Object {
|
||||||
|
"201": Object {
|
||||||
|
"description": "emptyResponse",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"tags": Array [
|
||||||
|
"admin",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"/api/admin/context/validate": Object {
|
||||||
|
"post": Object {
|
||||||
|
"operationId": "validate",
|
||||||
|
"requestBody": Object {
|
||||||
|
"content": Object {
|
||||||
|
"application/json": Object {
|
||||||
|
"schema": Object {
|
||||||
|
"$ref": "#/components/schemas/nameSchema",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"description": "nameSchema",
|
||||||
|
"required": true,
|
||||||
|
},
|
||||||
|
"responses": Object {
|
||||||
|
"200": Object {
|
||||||
|
"description": "emptyResponse",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"tags": Array [
|
||||||
|
"admin",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"/api/admin/context/{contextField}": Object {
|
||||||
|
"delete": Object {
|
||||||
|
"operationId": "deleteContextField",
|
||||||
|
"parameters": Array [
|
||||||
|
Object {
|
||||||
|
"in": "path",
|
||||||
|
"name": "contextField",
|
||||||
|
"required": true,
|
||||||
|
"schema": Object {
|
||||||
|
"type": "string",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"responses": Object {
|
||||||
|
"200": Object {
|
||||||
|
"description": "emptyResponse",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"tags": Array [
|
||||||
|
"admin",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
"get": Object {
|
||||||
|
"operationId": "getContextField",
|
||||||
|
"parameters": Array [
|
||||||
|
Object {
|
||||||
|
"in": "path",
|
||||||
|
"name": "contextField",
|
||||||
|
"required": true,
|
||||||
|
"schema": Object {
|
||||||
|
"type": "string",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"responses": Object {
|
||||||
|
"200": Object {
|
||||||
|
"content": Object {
|
||||||
|
"application/json": Object {
|
||||||
|
"schema": Object {
|
||||||
|
"$ref": "#/components/schemas/contextFieldSchema",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"description": "contextFieldSchema",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"tags": Array [
|
||||||
|
"admin",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
"put": Object {
|
||||||
|
"operationId": "updateContextField",
|
||||||
|
"parameters": Array [
|
||||||
|
Object {
|
||||||
|
"in": "path",
|
||||||
|
"name": "contextField",
|
||||||
|
"required": true,
|
||||||
|
"schema": Object {
|
||||||
|
"type": "string",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"requestBody": Object {
|
||||||
|
"content": Object {
|
||||||
|
"application/json": Object {
|
||||||
|
"schema": Object {
|
||||||
|
"$ref": "#/components/schemas/upsertContextFieldSchema",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"description": "upsertContextFieldSchema",
|
||||||
|
"required": true,
|
||||||
|
},
|
||||||
|
"responses": Object {
|
||||||
|
"200": Object {
|
||||||
|
"description": "emptyResponse",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"tags": Array [
|
||||||
|
"admin",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
"/api/admin/environments": Object {
|
"/api/admin/environments": Object {
|
||||||
"get": Object {
|
"get": Object {
|
||||||
"operationId": "getAllEnvironments",
|
"operationId": "getAllEnvironments",
|
||||||
|
Loading…
Reference in New Issue
Block a user