diff --git a/components/legacy/extension-data/extension-data-list.ts b/components/legacy/extension-data/extension-data-list.ts index 2bf1e98be974..d3f06daf96a6 100644 --- a/components/legacy/extension-data/extension-data-list.ts +++ b/components/legacy/extension-data/extension-data-list.ts @@ -98,6 +98,12 @@ export class ExtensionDataList extends Array { }); } + filterIgnoredFromSpecificExtensions(): ExtensionDataList { + return this.filter((entry) => { + return !entry.isIgnoredFromSpecific; + }); + } + toConfigObject() { const res = {}; this.forEach((entry) => { diff --git a/components/legacy/extension-data/extension-data.ts b/components/legacy/extension-data/extension-data.ts index 3d4d63750e9a..c1c33a30892c 100644 --- a/components/legacy/extension-data/extension-data.ts +++ b/components/legacy/extension-data/extension-data.ts @@ -1,10 +1,13 @@ -import { cloneDeep } from 'lodash'; +import { cloneDeep, isObject } from 'lodash'; import { ComponentID } from '@teambit/component-id'; -type ExtensionConfig = { [extName: string]: any } | RemoveExtensionSpecialSign; +type ExtensionConfig = { [extName: string]: any } | RemoveExtensionSpecialSign | IgnoreFromSpecificSpecialSign; export const REMOVE_EXTENSION_SPECIAL_SIGN = '-'; +export const IGNORE_FROM_SPECIFIC_SPECIAL_SIGN = '--'; + type RemoveExtensionSpecialSign = '-'; +type IgnoreFromSpecificSpecialSign = '--'; export class ExtensionDataEntry { constructor( @@ -33,7 +36,7 @@ export class ExtensionDataEntry { return ''; } - get config(): { [key: string]: any } { + get config(): { [key: string]: any } | string { if (this.rawConfig === REMOVE_EXTENSION_SPECIAL_SIGN) return {}; return this.rawConfig; } @@ -43,7 +46,7 @@ export class ExtensionDataEntry { } get isLegacy(): boolean { - if (this.config?.__legacy) return true; + if (isObject(this.config) && this.config?.__legacy) return true; return false; } @@ -51,6 +54,10 @@ export class ExtensionDataEntry { return this.rawConfig === REMOVE_EXTENSION_SPECIAL_SIGN; } + get isIgnoredFromSpecific(): boolean { + return this.rawConfig === IGNORE_FROM_SPECIFIC_SPECIAL_SIGN; + } + toModelObject() { const extensionId = this.extensionId && this.extensionId.serialize ? this.extensionId.serialize() : this.extensionId; diff --git a/components/legacy/extension-data/index.ts b/components/legacy/extension-data/index.ts index e2b3410b6279..febc05c1cb90 100644 --- a/components/legacy/extension-data/index.ts +++ b/components/legacy/extension-data/index.ts @@ -1,4 +1,4 @@ -export { ExtensionDataEntry, REMOVE_EXTENSION_SPECIAL_SIGN } from './extension-data'; +export { ExtensionDataEntry, REMOVE_EXTENSION_SPECIAL_SIGN, IGNORE_FROM_SPECIFIC_SPECIAL_SIGN } from './extension-data'; export { ExtensionDataList, removeInternalConfigFields, diff --git a/scopes/workspace/workspace/aspects-merger.ts b/scopes/workspace/workspace/aspects-merger.ts index 169f02d8c9df..c7c881f2cae1 100644 --- a/scopes/workspace/workspace/aspects-merger.ts +++ b/scopes/workspace/workspace/aspects-merger.ts @@ -5,7 +5,7 @@ import { ComponentID } from '@teambit/component-id'; import { EnvsAspect } from '@teambit/envs'; import { DependencyResolverAspect } from '@teambit/dependency-resolver'; import { ExtensionDataList, getCompareExtPredicate } from '@teambit/legacy.extension-data'; -import { partition, mergeWith, merge, uniq, uniqWith, compact } from 'lodash'; +import { partition, mergeWith, merge, uniq, uniqWith, compact, isObject } from 'lodash'; import { MergeConfigConflict } from './exceptions/merge-config-conflict'; import { AspectSpecificField, ExtensionsOrigin, Workspace } from './workspace'; import { MergeConflictFile } from './merge-conflict-file'; @@ -120,13 +120,25 @@ export class AspectsMerger { const extensionsToMerge: Array<{ origin: ExtensionsOrigin; extensions: ExtensionDataList; extraData: any }> = []; let envWasFoundPreviously = false; const removedExtensionIds: string[] = []; + const ignoredFromSpecificsExtensionIds: string[] = []; const addExtensionsToMerge = async (extensions: ExtensionDataList, origin: ExtensionsOrigin, extraData?: any) => { if (!extensions.length) { return; } + + const isSpecific = ['BitmapFile', 'ModelSpecific', 'ComponentJsonFile'].includes(origin); + removedExtensionIds.push(...extensions.filter((extData) => extData.isRemoved).map((extData) => extData.stringId)); - const extsWithoutRemoved = extensions.filterRemovedExtensions(); + let extsWithoutIgnored = extensions; + if (isSpecific) { + ignoredFromSpecificsExtensionIds.push( + ...extensions.filter((extData) => extData.isIgnoredFromSpecific).map((extData) => extData.stringId) + ); + extsWithoutIgnored = extensions.filter((ext) => !ignoredFromSpecificsExtensionIds.includes(ext.stringId)); + } + + const extsWithoutRemoved = extsWithoutIgnored.filterRemovedExtensions(); const selfInMergedExtensions = extsWithoutRemoved.findExtension(componentId.toStringWithoutVersion(), true); const extsWithoutSelf = selfInMergedExtensions?.extensionId ? extsWithoutRemoved.remove(selfInMergedExtensions.extensionId) @@ -149,7 +161,11 @@ export class AspectsMerger { extensionsToMerge.push({ origin, extensions: extensionDataListFiltered, extraData }); }; const setDataListAsSpecific = (extensions: ExtensionDataList) => { - extensions.forEach((dataEntry) => (dataEntry.config[AspectSpecificField] = true)); + extensions.forEach((dataEntry) => { + if (isObject(dataEntry.config)) { + dataEntry.config[AspectSpecificField] = true; + } + }); }; if (bitMapExtensions && !excludeOrigins.includes('BitmapFile')) { const extensionDataList = ExtensionDataList.fromConfigObject(bitMapExtensions);