mirror of
https://github.com/Unleash/unleash.git
synced 2025-03-18 00:19:49 +01:00
refactor: migrate permissions service from another repo (#3163)
This commit is contained in:
parent
ec8de3dead
commit
bdba449a6c
@ -17,29 +17,20 @@ import { IContextFieldStore, IUnleashStores } from '../types/stores';
|
|||||||
import { ISegmentStore } from '../types/stores/segment-store';
|
import { ISegmentStore } from '../types/stores/segment-store';
|
||||||
import { ExportQuerySchema } from '../openapi/spec/export-query-schema';
|
import { ExportQuerySchema } from '../openapi/spec/export-query-schema';
|
||||||
import {
|
import {
|
||||||
CREATE_CONTEXT_FIELD,
|
|
||||||
CREATE_FEATURE,
|
|
||||||
CREATE_FEATURE_STRATEGY,
|
|
||||||
DELETE_FEATURE_STRATEGY,
|
|
||||||
FEATURES_EXPORTED,
|
FEATURES_EXPORTED,
|
||||||
FEATURES_IMPORTED,
|
FEATURES_IMPORTED,
|
||||||
IFlagResolver,
|
IFlagResolver,
|
||||||
IUnleashServices,
|
IUnleashServices,
|
||||||
UPDATE_FEATURE,
|
|
||||||
UPDATE_FEATURE_ENVIRONMENT_VARIANTS,
|
|
||||||
UPDATE_TAG_TYPE,
|
|
||||||
WithRequired,
|
WithRequired,
|
||||||
} from '../types';
|
} from '../types';
|
||||||
import {
|
import {
|
||||||
ExportResultSchema,
|
ExportResultSchema,
|
||||||
FeatureStrategySchema,
|
FeatureStrategySchema,
|
||||||
ImportTogglesValidateItemSchema,
|
|
||||||
ImportTogglesValidateSchema,
|
ImportTogglesValidateSchema,
|
||||||
} from '../openapi';
|
} from '../openapi';
|
||||||
import { ImportTogglesSchema } from '../openapi/spec/import-toggles-schema';
|
import { ImportTogglesSchema } from '../openapi/spec/import-toggles-schema';
|
||||||
import User from '../types/user';
|
import User from '../types/user';
|
||||||
import { IContextFieldDto } from '../types/stores/context-field-store';
|
import { BadDataError } from '../error';
|
||||||
import { BadDataError, InvalidOperationError } from '../error';
|
|
||||||
import { extractUsernameFromUser } from '../util';
|
import { extractUsernameFromUser } from '../util';
|
||||||
import {
|
import {
|
||||||
AccessService,
|
AccessService,
|
||||||
@ -51,6 +42,8 @@ import {
|
|||||||
} from '../services';
|
} from '../services';
|
||||||
import { isValidField } from './import-context-validation';
|
import { isValidField } from './import-context-validation';
|
||||||
import { IImportTogglesStore } from './import-toggles-store-type';
|
import { IImportTogglesStore } from './import-toggles-store-type';
|
||||||
|
import { ImportPermissionsService } from './import-permissions-service';
|
||||||
|
import { ImportValidationMessages } from './import-validation-messages';
|
||||||
|
|
||||||
export default class ExportImportService {
|
export default class ExportImportService {
|
||||||
private logger: Logger;
|
private logger: Logger;
|
||||||
@ -87,6 +80,8 @@ export default class ExportImportService {
|
|||||||
|
|
||||||
private featureTagService: FeatureTagService;
|
private featureTagService: FeatureTagService;
|
||||||
|
|
||||||
|
private importPermissionsService: ImportPermissionsService;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
stores: Pick<
|
stores: Pick<
|
||||||
IUnleashStores,
|
IUnleashStores,
|
||||||
@ -137,6 +132,12 @@ export default class ExportImportService {
|
|||||||
this.accessService = accessService;
|
this.accessService = accessService;
|
||||||
this.tagTypeService = tagTypeService;
|
this.tagTypeService = tagTypeService;
|
||||||
this.featureTagService = featureTagService;
|
this.featureTagService = featureTagService;
|
||||||
|
this.importPermissionsService = new ImportPermissionsService(
|
||||||
|
this.importTogglesStore,
|
||||||
|
this.accessService,
|
||||||
|
this.tagTypeService,
|
||||||
|
this.contextService,
|
||||||
|
);
|
||||||
this.logger = getLogger('services/state-service.js');
|
this.logger = getLogger('services/state-service.js');
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -157,20 +158,29 @@ export default class ExportImportService {
|
|||||||
this.getUnsupportedContextFields(dto),
|
this.getUnsupportedContextFields(dto),
|
||||||
this.getArchivedFeatures(dto),
|
this.getArchivedFeatures(dto),
|
||||||
this.getOtherProjectFeatures(dto),
|
this.getOtherProjectFeatures(dto),
|
||||||
this.getMissingPermissions(dto, user),
|
this.importPermissionsService.getMissingPermissions(
|
||||||
|
dto,
|
||||||
|
user,
|
||||||
|
'regular',
|
||||||
|
),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const errors = this.compileErrors(
|
const errors = ImportValidationMessages.compileErrors(
|
||||||
dto.project,
|
dto.project,
|
||||||
unsupportedStrategies,
|
unsupportedStrategies,
|
||||||
otherProjectFeatures,
|
|
||||||
unsupportedContextFields,
|
unsupportedContextFields,
|
||||||
|
[],
|
||||||
|
otherProjectFeatures,
|
||||||
|
false,
|
||||||
);
|
);
|
||||||
const warnings = this.compileWarnings(
|
const warnings = ImportValidationMessages.compileWarnings(
|
||||||
usedCustomStrategies,
|
usedCustomStrategies,
|
||||||
archivedFeatures,
|
archivedFeatures,
|
||||||
);
|
);
|
||||||
const permissions = this.compilePermissionErrors(missingPermissions);
|
const permissions =
|
||||||
|
ImportValidationMessages.compilePermissionErrors(
|
||||||
|
missingPermissions,
|
||||||
|
);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
errors,
|
errors,
|
||||||
@ -185,7 +195,11 @@ export default class ExportImportService {
|
|||||||
await Promise.all([
|
await Promise.all([
|
||||||
this.verifyStrategies(cleanedDto),
|
this.verifyStrategies(cleanedDto),
|
||||||
this.verifyContextFields(cleanedDto),
|
this.verifyContextFields(cleanedDto),
|
||||||
this.verifyPermissions(dto, user),
|
this.importPermissionsService.verifyPermissions(
|
||||||
|
dto,
|
||||||
|
user,
|
||||||
|
'regular',
|
||||||
|
),
|
||||||
this.verifyFeatures(dto),
|
this.verifyFeatures(dto),
|
||||||
]);
|
]);
|
||||||
await this.createToggles(cleanedDto, user);
|
await this.createToggles(cleanedDto, user);
|
||||||
@ -359,15 +373,6 @@ export default class ExportImportService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async verifyPermissions(dto: ImportTogglesSchema, user: User) {
|
|
||||||
const missingPermissions = await this.getMissingPermissions(dto, user);
|
|
||||||
if (missingPermissions.length > 0) {
|
|
||||||
throw new InvalidOperationError(
|
|
||||||
'You are missing permissions to import',
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private async verifyFeatures(dto: ImportTogglesSchema) {
|
private async verifyFeatures(dto: ImportTogglesSchema) {
|
||||||
const otherProjectFeatures = await this.getOtherProjectFeatures(dto);
|
const otherProjectFeatures = await this.getOtherProjectFeatures(dto);
|
||||||
if (otherProjectFeatures.length > 0) {
|
if (otherProjectFeatures.length > 0) {
|
||||||
@ -444,75 +449,6 @@ export default class ExportImportService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private compileErrors(
|
|
||||||
projectName: string,
|
|
||||||
strategies: FeatureStrategySchema[],
|
|
||||||
otherProjectFeatures: string[],
|
|
||||||
contextFields?: IContextFieldDto[],
|
|
||||||
) {
|
|
||||||
const errors: ImportTogglesValidateItemSchema[] = [];
|
|
||||||
|
|
||||||
if (strategies.length > 0) {
|
|
||||||
errors.push({
|
|
||||||
message:
|
|
||||||
'We detected the following custom strategy in the import file that needs to be created first:',
|
|
||||||
affectedItems: strategies.map((strategy) => strategy.name),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if (Array.isArray(contextFields) && contextFields.length > 0) {
|
|
||||||
errors.push({
|
|
||||||
message:
|
|
||||||
'We detected the following context fields that do not have matching legal values with the imported ones:',
|
|
||||||
affectedItems: contextFields.map(
|
|
||||||
(contextField) => contextField.name,
|
|
||||||
),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if (otherProjectFeatures.length > 0) {
|
|
||||||
errors.push({
|
|
||||||
message: `You cannot import a features that already exist in other projects. You already have the following features defined outside of project ${projectName}:`,
|
|
||||||
affectedItems: otherProjectFeatures,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return errors;
|
|
||||||
}
|
|
||||||
|
|
||||||
private compileWarnings(
|
|
||||||
usedCustomStrategies: string[],
|
|
||||||
archivedFeatures: string[],
|
|
||||||
) {
|
|
||||||
const warnings: ImportTogglesValidateItemSchema[] = [];
|
|
||||||
if (usedCustomStrategies.length > 0) {
|
|
||||||
warnings.push({
|
|
||||||
message:
|
|
||||||
'The following strategy types will be used in import. Please make sure the strategy type parameters are configured as in source environment:',
|
|
||||||
affectedItems: usedCustomStrategies,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if (archivedFeatures.length > 0) {
|
|
||||||
warnings.push({
|
|
||||||
message:
|
|
||||||
'The following features will not be imported as they are currently archived. To import them, please unarchive them first:',
|
|
||||||
affectedItems: archivedFeatures,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return warnings;
|
|
||||||
}
|
|
||||||
|
|
||||||
private compilePermissionErrors(missingPermissions: string[]) {
|
|
||||||
const errors: ImportTogglesValidateItemSchema[] = [];
|
|
||||||
if (missingPermissions.length > 0) {
|
|
||||||
errors.push({
|
|
||||||
message:
|
|
||||||
'We detected you are missing the following permissions:',
|
|
||||||
affectedItems: missingPermissions,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return errors;
|
|
||||||
}
|
|
||||||
|
|
||||||
private async getUnsupportedStrategies(
|
private async getUnsupportedStrategies(
|
||||||
dto: ImportTogglesSchema,
|
dto: ImportTogglesSchema,
|
||||||
): Promise<FeatureStrategySchema[]> {
|
): Promise<FeatureStrategySchema[]> {
|
||||||
@ -572,80 +508,6 @@ export default class ExportImportService {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async getMissingPermissions(
|
|
||||||
dto: ImportTogglesSchema,
|
|
||||||
user: User,
|
|
||||||
): Promise<string[]> {
|
|
||||||
const [
|
|
||||||
newTagTypes,
|
|
||||||
newContextFields,
|
|
||||||
strategiesExistForFeatures,
|
|
||||||
featureEnvsWithVariants,
|
|
||||||
existingFeatures,
|
|
||||||
] = await Promise.all([
|
|
||||||
this.getNewTagTypes(dto),
|
|
||||||
this.getNewContextFields(dto),
|
|
||||||
this.importTogglesStore.strategiesExistForFeatures(
|
|
||||||
dto.data.features.map((feature) => feature.name),
|
|
||||||
dto.environment,
|
|
||||||
),
|
|
||||||
dto.data.featureEnvironments?.filter(
|
|
||||||
(featureEnvironment) =>
|
|
||||||
Array.isArray(featureEnvironment.variants) &&
|
|
||||||
featureEnvironment.variants.length > 0,
|
|
||||||
) || Promise.resolve([]),
|
|
||||||
this.importTogglesStore.getExistingFeatures(
|
|
||||||
dto.data.features.map((feature) => feature.name),
|
|
||||||
),
|
|
||||||
]);
|
|
||||||
|
|
||||||
const permissions = [UPDATE_FEATURE];
|
|
||||||
if (newTagTypes.length > 0) {
|
|
||||||
permissions.push(UPDATE_TAG_TYPE);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Array.isArray(newContextFields) && newContextFields.length > 0) {
|
|
||||||
permissions.push(CREATE_CONTEXT_FIELD);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strategiesExistForFeatures) {
|
|
||||||
permissions.push(DELETE_FEATURE_STRATEGY);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dto.data.featureStrategies.length > 0) {
|
|
||||||
permissions.push(CREATE_FEATURE_STRATEGY);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (featureEnvsWithVariants.length > 0) {
|
|
||||||
permissions.push(UPDATE_FEATURE_ENVIRONMENT_VARIANTS);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (existingFeatures.length < dto.data.features.length) {
|
|
||||||
permissions.push(CREATE_FEATURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
const displayPermissions =
|
|
||||||
await this.importTogglesStore.getDisplayPermissions(permissions);
|
|
||||||
|
|
||||||
const results = await Promise.all(
|
|
||||||
displayPermissions.map((permission) =>
|
|
||||||
this.accessService
|
|
||||||
.hasPermission(
|
|
||||||
user,
|
|
||||||
permission.name,
|
|
||||||
dto.project,
|
|
||||||
dto.environment,
|
|
||||||
)
|
|
||||||
.then(
|
|
||||||
(hasPermission) => [permission, hasPermission] as const,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
return results
|
|
||||||
.filter(([, hasAccess]) => !hasAccess)
|
|
||||||
.map(([permission]) => permission.displayName);
|
|
||||||
}
|
|
||||||
|
|
||||||
private async getNewTagTypes(dto: ImportTogglesSchema) {
|
private async getNewTagTypes(dto: ImportTogglesSchema) {
|
||||||
const existingTagTypes = (await this.tagTypeService.getAll()).map(
|
const existingTagTypes = (await this.tagTypeService.getAll()).map(
|
||||||
(tagType) => tagType.name,
|
(tagType) => tagType.name,
|
||||||
|
157
src/lib/export-import-toggles/import-permissions-service.ts
Normal file
157
src/lib/export-import-toggles/import-permissions-service.ts
Normal file
@ -0,0 +1,157 @@
|
|||||||
|
import { IImportTogglesStore } from './import-toggles-store-type';
|
||||||
|
import { AccessService, ContextService, TagTypeService } from '../services';
|
||||||
|
import { ContextFieldSchema, ImportTogglesSchema } from '../openapi';
|
||||||
|
import { ITagType } from '../types/stores/tag-type-store';
|
||||||
|
import User from '../types/user';
|
||||||
|
import {
|
||||||
|
CREATE_CONTEXT_FIELD,
|
||||||
|
CREATE_FEATURE,
|
||||||
|
CREATE_FEATURE_STRATEGY,
|
||||||
|
DELETE_FEATURE_STRATEGY,
|
||||||
|
UPDATE_FEATURE,
|
||||||
|
UPDATE_FEATURE_ENVIRONMENT_VARIANTS,
|
||||||
|
UPDATE_TAG_TYPE,
|
||||||
|
} from '../types';
|
||||||
|
import { InvalidOperationError } from '../error';
|
||||||
|
|
||||||
|
type Mode = 'regular' | 'change_request';
|
||||||
|
|
||||||
|
export class ImportPermissionsService {
|
||||||
|
private importTogglesStore: IImportTogglesStore;
|
||||||
|
|
||||||
|
private accessService: AccessService;
|
||||||
|
|
||||||
|
private tagTypeService: TagTypeService;
|
||||||
|
|
||||||
|
private contextService: ContextService;
|
||||||
|
|
||||||
|
private async getNewTagTypes(
|
||||||
|
dto: ImportTogglesSchema,
|
||||||
|
): Promise<ITagType[]> {
|
||||||
|
const existingTagTypes = (await this.tagTypeService.getAll()).map(
|
||||||
|
(tagType) => tagType.name,
|
||||||
|
);
|
||||||
|
const newTagTypes = dto.data.tagTypes?.filter(
|
||||||
|
(tagType) => !existingTagTypes.includes(tagType.name),
|
||||||
|
);
|
||||||
|
return [
|
||||||
|
...new Map(newTagTypes.map((item) => [item.name, item])).values(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
private async getNewContextFields(
|
||||||
|
dto: ImportTogglesSchema,
|
||||||
|
): Promise<ContextFieldSchema[]> {
|
||||||
|
const availableContextFields = await this.contextService.getAll();
|
||||||
|
|
||||||
|
return dto.data.contextFields?.filter(
|
||||||
|
(contextField) =>
|
||||||
|
!availableContextFields.some(
|
||||||
|
(availableField) =>
|
||||||
|
availableField.name === contextField.name,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
importTogglesStore: IImportTogglesStore,
|
||||||
|
accessService: AccessService,
|
||||||
|
tagTypeService: TagTypeService,
|
||||||
|
contextService: ContextService,
|
||||||
|
) {
|
||||||
|
this.importTogglesStore = importTogglesStore;
|
||||||
|
this.accessService = accessService;
|
||||||
|
this.tagTypeService = tagTypeService;
|
||||||
|
this.contextService = contextService;
|
||||||
|
}
|
||||||
|
|
||||||
|
async getMissingPermissions(
|
||||||
|
dto: ImportTogglesSchema,
|
||||||
|
user: User,
|
||||||
|
mode: Mode,
|
||||||
|
): Promise<string[]> {
|
||||||
|
const [
|
||||||
|
newTagTypes,
|
||||||
|
newContextFields,
|
||||||
|
strategiesExistForFeatures,
|
||||||
|
featureEnvsWithVariants,
|
||||||
|
existingFeatures,
|
||||||
|
] = await Promise.all([
|
||||||
|
this.getNewTagTypes(dto),
|
||||||
|
this.getNewContextFields(dto),
|
||||||
|
this.importTogglesStore.strategiesExistForFeatures(
|
||||||
|
dto.data.features.map((feature) => feature.name),
|
||||||
|
dto.environment,
|
||||||
|
),
|
||||||
|
dto.data.featureEnvironments?.filter(
|
||||||
|
(featureEnvironment) =>
|
||||||
|
Array.isArray(featureEnvironment.variants) &&
|
||||||
|
featureEnvironment.variants.length > 0,
|
||||||
|
) || Promise.resolve([]),
|
||||||
|
this.importTogglesStore.getExistingFeatures(
|
||||||
|
dto.data.features.map((feature) => feature.name),
|
||||||
|
),
|
||||||
|
]);
|
||||||
|
const permissions = [UPDATE_FEATURE];
|
||||||
|
if (newTagTypes.length > 0) {
|
||||||
|
permissions.push(UPDATE_TAG_TYPE);
|
||||||
|
}
|
||||||
|
if (Array.isArray(newContextFields) && newContextFields.length > 0) {
|
||||||
|
permissions.push(CREATE_CONTEXT_FIELD);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strategiesExistForFeatures && mode === 'regular') {
|
||||||
|
permissions.push(DELETE_FEATURE_STRATEGY);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dto.data.featureStrategies.length > 0 && mode === 'regular') {
|
||||||
|
permissions.push(CREATE_FEATURE_STRATEGY);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (featureEnvsWithVariants.length > 0 && mode === 'regular') {
|
||||||
|
permissions.push(UPDATE_FEATURE_ENVIRONMENT_VARIANTS);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (existingFeatures.length < dto.data.features.length) {
|
||||||
|
permissions.push(CREATE_FEATURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
const displayPermissions =
|
||||||
|
await this.importTogglesStore.getDisplayPermissions(permissions);
|
||||||
|
|
||||||
|
const results = await Promise.all(
|
||||||
|
displayPermissions.map((permission) =>
|
||||||
|
this.accessService
|
||||||
|
.hasPermission(
|
||||||
|
user,
|
||||||
|
permission.name,
|
||||||
|
dto.project,
|
||||||
|
dto.environment,
|
||||||
|
)
|
||||||
|
.then(
|
||||||
|
(hasPermission) => [permission, hasPermission] as const,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
return results
|
||||||
|
.filter(([, hasAccess]) => !hasAccess)
|
||||||
|
.map(([permission]) => permission.displayName);
|
||||||
|
}
|
||||||
|
|
||||||
|
async verifyPermissions(
|
||||||
|
dto: ImportTogglesSchema,
|
||||||
|
user: User,
|
||||||
|
mode: Mode,
|
||||||
|
): Promise<void> {
|
||||||
|
const missingPermissions = await this.getMissingPermissions(
|
||||||
|
dto,
|
||||||
|
user,
|
||||||
|
mode,
|
||||||
|
);
|
||||||
|
if (missingPermissions.length > 0) {
|
||||||
|
throw new InvalidOperationError(
|
||||||
|
'You are missing permissions to import',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
94
src/lib/export-import-toggles/import-validation-messages.ts
Normal file
94
src/lib/export-import-toggles/import-validation-messages.ts
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
import {
|
||||||
|
FeatureStrategySchema,
|
||||||
|
ImportTogglesValidateItemSchema,
|
||||||
|
} from '../openapi';
|
||||||
|
import { IContextFieldDto } from '../types/stores/context-field-store';
|
||||||
|
|
||||||
|
export class ImportValidationMessages {
|
||||||
|
static compilePermissionErrors(
|
||||||
|
missingPermissions: string[],
|
||||||
|
): ImportTogglesValidateItemSchema[] {
|
||||||
|
const errors: ImportTogglesValidateItemSchema[] = [];
|
||||||
|
if (missingPermissions.length > 0) {
|
||||||
|
errors.push({
|
||||||
|
message:
|
||||||
|
'We detected you are missing the following permissions:',
|
||||||
|
affectedItems: missingPermissions,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return errors;
|
||||||
|
}
|
||||||
|
|
||||||
|
static compileErrors(
|
||||||
|
projectName: string,
|
||||||
|
strategies: FeatureStrategySchema[],
|
||||||
|
contextFields: IContextFieldDto[],
|
||||||
|
segments: string[],
|
||||||
|
otherProjectFeatures: string[],
|
||||||
|
changeRequestExists: boolean,
|
||||||
|
): ImportTogglesValidateItemSchema[] {
|
||||||
|
const errors: ImportTogglesValidateItemSchema[] = [];
|
||||||
|
|
||||||
|
if (strategies.length > 0) {
|
||||||
|
errors.push({
|
||||||
|
message:
|
||||||
|
'We detected the following custom strategy in the import file that needs to be created first:',
|
||||||
|
affectedItems: strategies.map((strategy) => strategy.name),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (contextFields.length > 0) {
|
||||||
|
errors.push({
|
||||||
|
message:
|
||||||
|
'We detected the following context fields that do not have matching legal values with the imported ones:',
|
||||||
|
affectedItems: contextFields.map(
|
||||||
|
(contextField) => contextField.name,
|
||||||
|
),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (segments.length > 0) {
|
||||||
|
errors.push({
|
||||||
|
message:
|
||||||
|
'We detected the following segments in the import file that need to be created first:',
|
||||||
|
affectedItems: segments,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (changeRequestExists) {
|
||||||
|
errors.push({
|
||||||
|
message:
|
||||||
|
'Before importing any data, please resolve your pending change request in this project and environment as it is preventing you from importing at this time',
|
||||||
|
affectedItems: [],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (otherProjectFeatures.length > 0) {
|
||||||
|
errors.push({
|
||||||
|
message: `You cannot import a features that already exist in other projects. You already have the following features defined outside of project ${projectName}:`,
|
||||||
|
affectedItems: otherProjectFeatures,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return errors;
|
||||||
|
}
|
||||||
|
|
||||||
|
static compileWarnings(
|
||||||
|
usedCustomStrategies: string[],
|
||||||
|
archivedFeatures: string[],
|
||||||
|
): ImportTogglesValidateItemSchema[] {
|
||||||
|
const warnings: ImportTogglesValidateItemSchema[] = [];
|
||||||
|
if (usedCustomStrategies.length > 0) {
|
||||||
|
warnings.push({
|
||||||
|
message:
|
||||||
|
'The following strategy types will be used in import. Please make sure the strategy type parameters are configured as in source environment:',
|
||||||
|
affectedItems: usedCustomStrategies,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (archivedFeatures.length > 0) {
|
||||||
|
warnings.push({
|
||||||
|
message:
|
||||||
|
'The following features will not be imported as they are currently archived. To import them, please unarchive them first:',
|
||||||
|
affectedItems: archivedFeatures,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return warnings;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user