UNPKG

unleash-server

Version:

Unleash is an enterprise ready feature flag service. It provides different strategies for handling feature flags.

233 lines • 11.1 kB
import Controller from '../../routes/controller.js'; import { CREATE_CONTEXT_FIELD, UPDATE_CONTEXT_FIELD, DELETE_CONTEXT_FIELD, NONE, } from '../../types/permissions.js'; import { contextFieldSchema, } from '../../openapi/spec/context-field-schema.js'; import { createRequestSchema } from '../../openapi/util/create-request-schema.js'; import { createResponseSchema, resourceCreatedResponseSchema, } from '../../openapi/util/create-response-schema.js'; import { serializeDates } from '../../types/serialize-dates.js'; import NotFoundError from '../../error/notfound-error.js'; import { emptyResponse, getStandardResponses, } from '../../openapi/util/standard-responses.js'; import { contextFieldStrategiesSchema, } from '../../openapi/spec/context-field-strategies-schema.js'; import { extractUserIdFromUser } from '../../util/index.js'; export class ContextController extends Controller { constructor(config, { transactionalContextService, openApiService, }) { super(config); this.openApiService = openApiService; this.logger = config.getLogger('/admin-api/context.ts'); this.transactionalContextService = transactionalContextService; this.route({ method: 'get', path: '', handler: this.getContextFields, permission: NONE, middleware: [ openApiService.validPath({ tags: ['Context'], summary: 'Gets configured context fields', description: 'Returns all configured [Context fields](https://docs.getunleash.io/reference/unleash-context) that have been created.', operationId: 'getContextFields', responses: { 200: createResponseSchema('contextFieldsSchema'), }, }), ], }); this.route({ method: 'get', path: '/:contextField', handler: this.getContextField, permission: NONE, middleware: [ openApiService.validPath({ tags: ['Context'], summary: 'Gets context field', description: 'Returns specific [context field](https://docs.getunleash.io/reference/unleash-context) identified by the name in the path', operationId: 'getContextField', responses: { 200: createResponseSchema('contextFieldSchema'), }, }), ], }); this.route({ method: 'get', path: '/:contextField/strategies', handler: this.getStrategiesByContextField, permission: NONE, middleware: [ openApiService.validPath({ tags: ['Strategies'], operationId: 'getStrategiesByContextField', summary: 'Get strategies that use a context field', description: "Retrieves a list of all strategies that use the specified context field. If the context field doesn't exist, returns an empty list of strategies", responses: { 200: createResponseSchema('contextFieldStrategiesSchema'), ...getStandardResponses(401), }, }), ], }); this.route({ method: 'post', path: '', handler: this.createContextField, permission: CREATE_CONTEXT_FIELD, middleware: [ openApiService.validPath({ tags: ['Context'], operationId: 'createContextField', summary: 'Create a context field', description: 'Endpoint that allows creation of [custom context fields](https://docs.getunleash.io/reference/unleash-context#custom-context-fields)', requestBody: createRequestSchema('createContextFieldSchema'), responses: { 201: resourceCreatedResponseSchema('contextFieldSchema'), }, }), ], }); this.route({ method: 'put', path: '/:contextField', handler: this.updateContextField, permission: UPDATE_CONTEXT_FIELD, middleware: [ openApiService.validPath({ tags: ['Context'], summary: 'Update an existing context field', description: `Endpoint that allows updating a custom context field. Used to toggle stickiness and add/remove legal values for this context field`, operationId: 'updateContextField', requestBody: createRequestSchema('updateContextFieldSchema'), responses: { 200: emptyResponse, }, }), ], }); this.route({ method: 'post', path: '/:contextField/legal-values', handler: this.updateLegalValue, permission: UPDATE_CONTEXT_FIELD, middleware: [ openApiService.validPath({ tags: ['Context'], summary: 'Add or update legal value for the context field', description: `Endpoint that allows adding or updating a single custom context field legal value. If the legal value already exists, it will be updated with the new description`, operationId: 'updateContextFieldLegalValue', requestBody: createRequestSchema('legalValueSchema'), responses: { 200: emptyResponse, }, }), ], }); this.route({ method: 'delete', path: '/:contextField/legal-values/:legalValue', handler: this.deleteLegalValue, acceptAnyContentType: true, permission: UPDATE_CONTEXT_FIELD, middleware: [ openApiService.validPath({ tags: ['Context'], summary: 'Delete legal value for the context field', description: `Removes the specified custom context field legal value. Does not validate that the legal value is not in use and does not remove usage from constraints that use it.`, operationId: 'deleteContextFieldLegalValue', responses: { 200: emptyResponse, }, }), ], }); this.route({ method: 'delete', path: '/:contextField', handler: this.deleteContextField, acceptAnyContentType: true, permission: DELETE_CONTEXT_FIELD, middleware: [ openApiService.validPath({ tags: ['Context'], summary: 'Delete an existing context field', description: 'Endpoint that allows deletion of a custom context field. Does not validate that context field is not in use, but since context field configuration is stored in a json blob for the strategy, existing strategies are safe.', operationId: 'deleteContextField', responses: { 200: emptyResponse, }, }), ], }); this.route({ method: 'post', path: '/validate', handler: this.validate, permission: UPDATE_CONTEXT_FIELD, middleware: [ openApiService.validPath({ tags: ['Context'], summary: 'Validate a context field', description: 'Check whether the provided data can be used to create a context field. If the data is not valid, returns a 400 status code with the reason why it is not valid.', operationId: 'validate', requestBody: createRequestSchema('nameSchema'), responses: { 200: emptyResponse, }, }), ], }); } async getContextFields(req, res) { res.status(200) .json(serializeDates(await this.transactionalContextService.getAll())) .end(); } async getContextField(req, res) { try { const name = req.params.contextField; const contextField = await this.transactionalContextService.getContextField(name); this.openApiService.respondWithValidation(200, res, contextFieldSchema.$id, serializeDates(contextField)); } catch (err) { throw new NotFoundError('Could not find context field'); } } async createContextField(req, res) { const value = req.body; const result = await this.transactionalContextService.transactional((service) => service.createContextField(value, req.audit)); this.openApiService.respondWithValidation(201, res, contextFieldSchema.$id, serializeDates(result), { location: `context/${result.name}` }); } async updateContextField(req, res) { const name = req.params.contextField; const contextField = req.body; await this.transactionalContextService.transactional((service) => service.updateContextField({ ...contextField, name }, req.audit)); res.status(200).end(); } async updateLegalValue(req, res) { const name = req.params.contextField; const legalValue = req.body; await this.transactionalContextService.transactional((service) => service.updateLegalValue({ name, legalValue }, req.audit)); res.status(200).end(); } async deleteLegalValue(req, res) { const name = req.params.contextField; const legalValue = req.params.legalValue; await this.transactionalContextService.transactional((service) => service.deleteLegalValue({ name, legalValue }, req.audit)); res.status(200).end(); } async deleteContextField(req, res) { const name = req.params.contextField; await this.transactionalContextService.transactional((service) => service.deleteContextField(name, req.audit)); res.status(200).end(); } async validate(req, res) { const { name } = req.body; await this.transactionalContextService.validateName(name); res.status(200).end(); } async getStrategiesByContextField(req, res) { const { contextField } = req.params; const { user } = req; const contextFields = await this.transactionalContextService.getStrategiesByContextField(contextField, extractUserIdFromUser(user)); this.openApiService.respondWithValidation(200, res, contextFieldStrategiesSchema.$id, serializeDates(contextFields)); } } //# sourceMappingURL=context.js.map