UNPKG

unleash-server

Version:

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

169 lines • 7.6 kB
import Controller from '../../routes/controller.js'; import { NONE, UPDATE_FEATURE_DEPENDENCY, } from '../../types/index.js'; import { createRequestSchema, createResponseSchema, emptyResponse, getStandardResponses, parentFeatureOptionsSchema, parentVariantOptionsSchema, } from '../../openapi/index.js'; const PATH = '/:projectId/features'; const PATH_FEATURE = `${PATH}/:child`; const PATH_DEPENDENCIES = `${PATH_FEATURE}/dependencies`; const PATH_DEPENDENCIES_CHECK = `/:projectId/dependencies`; const PATH_PARENTS = `${PATH_FEATURE}/parents`; const PATH_PARENT_VARIANTS = `${PATH}/:parent/parent-variants`; const PATH_DEPENDENCY = `${PATH_FEATURE}/dependencies/:parent`; export default class DependentFeaturesController extends Controller { constructor(config, { transactionalDependentFeaturesService, openApiService, }) { super(config); this.dependentFeaturesService = transactionalDependentFeaturesService; this.openApiService = openApiService; this.flagResolver = config.flagResolver; this.logger = config.getLogger('/dependent-features/dependent-features-controller.ts'); this.route({ method: 'post', path: PATH_DEPENDENCIES, handler: this.addFeatureDependency, permission: UPDATE_FEATURE_DEPENDENCY, middleware: [ openApiService.validPath({ tags: ['Dependencies'], summary: 'Add a feature dependency.', description: 'Add a dependency to a parent feature. Each environment will resolve corresponding dependency independently.', operationId: 'addFeatureDependency', requestBody: createRequestSchema('createDependentFeatureSchema'), responses: { 200: emptyResponse, ...getStandardResponses(401, 403, 404), }, }), ], }); this.route({ method: 'delete', path: PATH_DEPENDENCY, handler: this.deleteFeatureDependency, permission: UPDATE_FEATURE_DEPENDENCY, acceptAnyContentType: true, middleware: [ openApiService.validPath({ tags: ['Dependencies'], summary: 'Deletes a feature dependency.', description: 'Remove a dependency to a parent feature.', operationId: 'deleteFeatureDependency', responses: { 200: emptyResponse, ...getStandardResponses(401, 403, 404), }, }), ], }); this.route({ method: 'delete', path: PATH_DEPENDENCIES, handler: this.deleteFeatureDependencies, permission: UPDATE_FEATURE_DEPENDENCY, acceptAnyContentType: true, middleware: [ openApiService.validPath({ tags: ['Dependencies'], summary: 'Deletes feature dependencies.', description: 'Remove dependencies to all parent features.', operationId: 'deleteFeatureDependencies', responses: { 200: emptyResponse, ...getStandardResponses(401, 403, 404), }, }), ], }); this.route({ method: 'get', path: PATH_PARENTS, handler: this.getPossibleParentFeatures, permission: NONE, middleware: [ openApiService.validPath({ tags: ['Dependencies'], summary: 'List parent options.', description: 'List available parents who have no transitive dependencies.', operationId: 'listParentOptions', responses: { 200: createResponseSchema('parentFeatureOptionsSchema'), ...getStandardResponses(401, 403, 404), }, }), ], }); this.route({ method: 'get', path: PATH_PARENT_VARIANTS, handler: this.getPossibleParentVariants, permission: NONE, middleware: [ openApiService.validPath({ tags: ['Dependencies'], summary: 'List parent feature variants.', description: 'List available parent variants across all strategy variants and feature environment variants.', operationId: 'listParentVariantOptions', responses: { 200: createResponseSchema('parentVariantOptionsSchema'), ...getStandardResponses(401, 403, 404), }, }), ], }); this.route({ method: 'get', path: PATH_DEPENDENCIES_CHECK, handler: this.checkDependenciesExist, permission: NONE, middleware: [ openApiService.validPath({ tags: ['Dependencies'], summary: 'Check dependencies exist.', description: 'Check if any dependencies exist in this Unleash instance', operationId: 'checkDependenciesExist', responses: { 200: createResponseSchema('dependenciesExistSchema'), ...getStandardResponses(401, 403), }, }), ], }); } async addFeatureDependency(req, res) { const { child, projectId } = req.params; const { variants, enabled, feature } = req.body; await this.dependentFeaturesService.transactional((service) => service.upsertFeatureDependency({ child, projectId }, { variants, enabled, feature, }, req.user, req.audit)); res.status(200).end(); } async deleteFeatureDependency(req, res) { const { child, parent, projectId } = req.params; await this.dependentFeaturesService.transactional((service) => service.deleteFeatureDependency({ parent, child, }, projectId, req.user, req.audit)); res.status(200).end(); } async deleteFeatureDependencies(req, res) { const { child, projectId } = req.params; await this.dependentFeaturesService.transactional((service) => service.deleteFeaturesDependencies([child], projectId, req.user, req.audit)); res.status(200).end(); } async getPossibleParentFeatures(req, res) { const { child } = req.params; const options = await this.dependentFeaturesService.getPossibleParentFeatures(child); this.openApiService.respondWithValidation(200, res, parentFeatureOptionsSchema.$id, options); } async getPossibleParentVariants(req, res) { const { parent } = req.params; const options = await this.dependentFeaturesService.getPossibleParentVariants(parent); this.openApiService.respondWithValidation(200, res, parentVariantOptionsSchema.$id, options); } async checkDependenciesExist(req, res) { const { child } = req.params; const exist = await this.dependentFeaturesService.checkDependenciesExist(); res.send(exist); } } //# sourceMappingURL=dependent-features-controller.js.map