mirror of
				https://github.com/Unleash/unleash.git
				synced 2025-10-27 11:02:16 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			123 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			123 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| 'use strict';
 | |
| 
 | |
| const joi = require('@hapi/joi');
 | |
| const fs = require('fs');
 | |
| const mime = require('mime');
 | |
| const YAML = require('js-yaml');
 | |
| const { featureShema } = require('./routes/admin-api/feature-schema');
 | |
| const strategySchema = require('./routes/admin-api/strategy-schema');
 | |
| const {
 | |
|     FEATURE_IMPORT,
 | |
|     DROP_FEATURES,
 | |
|     STRATEGY_IMPORT,
 | |
|     DROP_STRATEGIES,
 | |
| } = require('./event-type');
 | |
| 
 | |
| const dataSchema = joi.object().keys({
 | |
|     version: joi.number(),
 | |
|     features: joi
 | |
|         .array()
 | |
|         .optional()
 | |
|         .items(featureShema),
 | |
|     strategies: joi
 | |
|         .array()
 | |
|         .optional()
 | |
|         .items(strategySchema),
 | |
| });
 | |
| 
 | |
| function readFile(file) {
 | |
|     return new Promise((resolve, reject) =>
 | |
|         fs.readFile(file, (err, v) => (err ? reject(err) : resolve(v))),
 | |
|     );
 | |
| }
 | |
| 
 | |
| function parseFile(file, data) {
 | |
|     return mime.getType(file) === 'text/yaml'
 | |
|         ? YAML.safeLoad(data)
 | |
|         : JSON.parse(data);
 | |
| }
 | |
| 
 | |
| class StateService {
 | |
|     constructor(config) {
 | |
|         this.config = config;
 | |
|         this.logger = config.getLogger('state-service.js');
 | |
|     }
 | |
| 
 | |
|     importFile({ file, dropBeforeImport, userName }) {
 | |
|         return readFile(file)
 | |
|             .then(data => parseFile(file, data))
 | |
|             .then(data => this.import({ data, userName, dropBeforeImport }));
 | |
|     }
 | |
| 
 | |
|     async import({ data, userName, dropBeforeImport }) {
 | |
|         const { eventStore } = this.config.stores;
 | |
| 
 | |
|         const importData = await dataSchema.validateAsync(data);
 | |
| 
 | |
|         if (importData.features) {
 | |
|             this.logger.info(
 | |
|                 `Importing ${importData.features.length} features`,
 | |
|             );
 | |
|             if (dropBeforeImport) {
 | |
|                 this.logger.info(`Dropping existing features`);
 | |
|                 await eventStore.store({
 | |
|                     type: DROP_FEATURES,
 | |
|                     createdBy: userName,
 | |
|                     data: { name: 'all-features' },
 | |
|                 });
 | |
|             }
 | |
|             await Promise.all(
 | |
|                 importData.features.map(feature =>
 | |
|                     eventStore.store({
 | |
|                         type: FEATURE_IMPORT,
 | |
|                         createdBy: userName,
 | |
|                         data: feature,
 | |
|                     }),
 | |
|                 ),
 | |
|             );
 | |
|         }
 | |
| 
 | |
|         if (importData.strategies) {
 | |
|             this.logger.info(
 | |
|                 `Importing ${importData.strategies.length} strategies`,
 | |
|             );
 | |
|             if (dropBeforeImport) {
 | |
|                 this.logger.info(`Dropping existing strategies`);
 | |
|                 await eventStore.store({
 | |
|                     type: DROP_STRATEGIES,
 | |
|                     createdBy: userName,
 | |
|                     data: { name: 'all-strategies' },
 | |
|                 });
 | |
|             }
 | |
|             await Promise.all(
 | |
|                 importData.strategies.map(strategy =>
 | |
|                     eventStore.store({
 | |
|                         type: STRATEGY_IMPORT,
 | |
|                         createdBy: userName,
 | |
|                         data: strategy,
 | |
|                     }),
 | |
|                 ),
 | |
|             );
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     async export({ includeFeatureToggles = true, includeStrategies = true }) {
 | |
|         const { featureToggleStore, strategyStore } = this.config.stores;
 | |
| 
 | |
|         return Promise.all([
 | |
|             includeFeatureToggles
 | |
|                 ? featureToggleStore.getFeatures()
 | |
|                 : Promise.resolve(),
 | |
|             includeStrategies
 | |
|                 ? strategyStore.getEditableStrategies()
 | |
|                 : Promise.resolve(),
 | |
|         ]).then(([features, strategies]) => ({
 | |
|             version: 1,
 | |
|             features,
 | |
|             strategies,
 | |
|         }));
 | |
|     }
 | |
| }
 | |
| 
 | |
| module.exports = StateService;
 |