diff --git a/server/adaptors/integrations/__test__/builder.test.ts b/server/adaptors/integrations/__test__/builder.test.ts index 4ebec0ad3..e55bc805e 100644 --- a/server/adaptors/integrations/__test__/builder.test.ts +++ b/server/adaptors/integrations/__test__/builder.test.ts @@ -65,10 +65,12 @@ describe('IntegrationInstanceBuilder', () => { const remappedAssets = [ { id: 'remapped-asset1', + override: false, references: [{ id: 'remapped-ref1' }], }, { id: 'remapped-asset2', + override: false, references: [{ id: 'remapped-ref2' }], }, ]; @@ -111,7 +113,7 @@ describe('IntegrationInstanceBuilder', () => { // sampleIntegration.deepCheck = jest.fn().mockResolvedValue({ ok: true, value: mockTemplate }); sampleIntegration.getAssets = jest.fn().mockResolvedValue({ ok: true, - value: [{ type: 'savedObjectBundle', data: remappedAssets }], + value: [{ type: 'savedObjectBundle', override: false, data: remappedAssets }], }); sampleIntegration.getConfig = jest.fn().mockResolvedValue({ ok: true, value: mockTemplate }); diff --git a/server/adaptors/integrations/integrations_builder.ts b/server/adaptors/integrations/integrations_builder.ts index 033acf580..e516dc1e0 100644 --- a/server/adaptors/integrations/integrations_builder.ts +++ b/server/adaptors/integrations/integrations_builder.ts @@ -21,6 +21,7 @@ interface BuilderOptions { interface SavedObject { id: string; + override: boolean; type: string; attributes: { title: string }; references: Array<{ id: string }>; @@ -124,8 +125,14 @@ export class IntegrationInstanceBuilder { } return includeWorkflows.some((w) => asset.workflows?.includes(w)); }) - .map((asset) => (asset as { type: 'savedObjectBundle'; data: object[] }).data) - .flat() as SavedObject[]; + .flatMap((asset) => + (asset as { type: 'savedObjectBundle'; data: object[]; override: boolean }).data.map( + (item) => ({ + ...item, + override: asset.override ?? false, // default to false + }) + ) + ) as SavedObject[]; } remapDataSource(assets: SavedObject[], dataSource: string | undefined): SavedObject[] { @@ -142,21 +149,22 @@ export class IntegrationInstanceBuilder { const toRemap = assets.filter((asset) => asset.id); const idMap = new Map(); return toRemap.map((item) => { - if (!idMap.has(item.id)) { - idMap.set(item.id, uuidv4()); - } - item.id = idMap.get(item.id)!; - for (let ref = 0; ref < item.references.length; ref++) { - const refId = item.references[ref].id; - if (!idMap.has(refId)) { - idMap.set(refId, uuidv4()); + if (!item.override) { + if (!idMap.has(item.id)) { + idMap.set(item.id, uuidv4()); + } + item.id = idMap.get(item.id)!; + for (let ref = 0; ref < item.references.length; ref++) { + const refId = item.references[ref].id; + if (!idMap.has(refId)) { + idMap.set(refId, uuidv4()); + } + item.references[ref].id = idMap.get(refId)!; } - item.references[ref].id = idMap.get(refId)!; } return item; }); } - async postAssets(assets: SavedObjectsBulkCreateObject[]): Promise { try { const response = await this.client.bulkCreate(assets); diff --git a/server/adaptors/integrations/repository/integration_reader.ts b/server/adaptors/integrations/repository/integration_reader.ts index e8d2e5380..dfcf10bd1 100644 --- a/server/adaptors/integrations/repository/integration_reader.ts +++ b/server/adaptors/integrations/repository/integration_reader.ts @@ -202,6 +202,7 @@ export class IntegrationReader { case 'savedObjectBundle': resultValue.push({ type: 'savedObjectBundle', + override: asset.override, workflows: asset.workflows, data: JSON.parse(serializedResult.value.data), }); diff --git a/server/adaptors/integrations/types.ts b/server/adaptors/integrations/types.ts index 0f229526f..38b9b56b7 100644 --- a/server/adaptors/integrations/types.ts +++ b/server/adaptors/integrations/types.ts @@ -58,6 +58,7 @@ interface IntegrationAsset { version: string; extension: string; type: SupportedAssetType; + override: boolean; workflows?: string[]; } @@ -70,7 +71,7 @@ interface IntegrationWorkflow { } type ParsedIntegrationAsset = - | { type: 'savedObjectBundle'; workflows?: string[]; data: object[] } + | { type: 'savedObjectBundle'; workflows?: string[]; data: object[]; override?: boolean } | { type: 'query'; workflows?: string[]; query: string; language: string }; interface SerializedIntegrationAsset extends IntegrationAsset { diff --git a/server/adaptors/integrations/validators.ts b/server/adaptors/integrations/validators.ts index 2ae70cf53..767286856 100644 --- a/server/adaptors/integrations/validators.ts +++ b/server/adaptors/integrations/validators.ts @@ -83,6 +83,7 @@ const templateSchema: JSONSchemaType = { name: { type: 'string' }, version: { type: 'string' }, extension: { type: 'string' }, + override: { type: 'boolean', nullable: true }, type: { type: 'string' }, data: { type: 'string', nullable: true }, workflows: {