diff --git a/src/core/server/saved_objects/export/get_sorted_objects_for_export.test.ts b/src/core/server/saved_objects/export/get_sorted_objects_for_export.test.ts index 9a3449b65a9412..fafa04447ddfea 100644 --- a/src/core/server/saved_objects/export/get_sorted_objects_for_export.test.ts +++ b/src/core/server/saved_objects/export/get_sorted_objects_for_export.test.ts @@ -108,8 +108,6 @@ describe('getSortedObjectsForExport()', () => { "namespace": undefined, "perPage": 500, "search": undefined, - "sortField": "_id", - "sortOrder": "asc", "type": Array [ "index-pattern", "search", @@ -256,8 +254,6 @@ describe('getSortedObjectsForExport()', () => { "namespace": undefined, "perPage": 500, "search": "foo", - "sortField": "_id", - "sortOrder": "asc", "type": Array [ "index-pattern", "search", @@ -345,8 +341,6 @@ describe('getSortedObjectsForExport()', () => { "namespace": "foo", "perPage": 500, "search": undefined, - "sortField": "_id", - "sortOrder": "asc", "type": Array [ "index-pattern", "search", @@ -399,6 +393,79 @@ describe('getSortedObjectsForExport()', () => { ).rejects.toThrowErrorMatchingInlineSnapshot(`"Can't export more than 1 objects"`); }); + test('sorts objects within type', async () => { + savedObjectsClient.find.mockResolvedValueOnce({ + total: 3, + per_page: 10000, + page: 1, + saved_objects: [ + { + id: '3', + type: 'index-pattern', + attributes: { + name: 'baz', + }, + references: [], + }, + { + id: '1', + type: 'index-pattern', + attributes: { + name: 'foo', + }, + references: [], + }, + { + id: '2', + type: 'index-pattern', + attributes: { + name: 'bar', + }, + references: [], + }, + ], + }); + const exportStream = await getSortedObjectsForExport({ + exportSizeLimit: 10000, + savedObjectsClient, + types: ['index-pattern'], + }); + const response = await readStreamToCompletion(exportStream); + expect(response).toMatchInlineSnapshot(` + Array [ + Object { + "attributes": Object { + "name": "foo", + }, + "id": "1", + "references": Array [], + "type": "index-pattern", + }, + Object { + "attributes": Object { + "name": "bar", + }, + "id": "2", + "references": Array [], + "type": "index-pattern", + }, + Object { + "attributes": Object { + "name": "baz", + }, + "id": "3", + "references": Array [], + "type": "index-pattern", + }, + Object { + "exportedCount": 3, + "missingRefCount": 0, + "missingReferences": Array [], + }, + ] + `); + }); + test('exports selected objects and sorts them', async () => { savedObjectsClient.bulkGet.mockResolvedValueOnce({ saved_objects: [ diff --git a/src/core/server/saved_objects/export/get_sorted_objects_for_export.ts b/src/core/server/saved_objects/export/get_sorted_objects_for_export.ts index e1a705a36db75a..a4dfacfd9e34f8 100644 --- a/src/core/server/saved_objects/export/get_sorted_objects_for_export.ts +++ b/src/core/server/saved_objects/export/get_sorted_objects_for_export.ts @@ -19,7 +19,7 @@ import Boom from 'boom'; import { createListStream } from '../../../../legacy/utils/streams'; -import { SavedObjectsClientContract } from '../types'; +import { SavedObjectsClientContract, SavedObject } from '../types'; import { fetchNestedDependencies } from './inject_nested_depdendencies'; import { sortObjects } from './sort_objects'; @@ -105,15 +105,17 @@ async function fetchObjectsToExport({ const findResponse = await savedObjectsClient.find({ type: types, search, - sortField: '_id', - sortOrder: 'asc', perPage: exportSizeLimit, namespace, }); if (findResponse.total > exportSizeLimit) { throw Boom.badRequest(`Can't export more than ${exportSizeLimit} objects`); } - return findResponse.saved_objects; + + // sorts server-side by _id, since it's only available in fielddata + return findResponse.saved_objects.sort((a: SavedObject, b: SavedObject) => + a.id > b.id ? 1 : -1 + ); } else { throw Boom.badRequest('Either `type` or `objects` are required.'); } @@ -137,14 +139,17 @@ export async function getSortedObjectsForExport({ exportSizeLimit, namespace, }); - let exportedObjects = [...rootObjects]; + let exportedObjects = []; let missingReferences: SavedObjectsExportResultDetails['missingReferences'] = []; + if (includeReferencesDeep) { const fetchResult = await fetchNestedDependencies(rootObjects, savedObjectsClient, namespace); - exportedObjects = fetchResult.objects; + exportedObjects = sortObjects(fetchResult.objects); missingReferences = fetchResult.missingRefs; + } else { + exportedObjects = sortObjects(rootObjects); } - exportedObjects = sortObjects(exportedObjects); + const exportDetails: SavedObjectsExportResultDetails = { exportedCount: exportedObjects.length, missingRefCount: missingReferences.length,