mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 01:38:56 -04:00
[Saved objects] Prepare SO management for versionable types (#149495)
## Summary Part of preparing HTTP APIs and associated interfaces for versioning: * Add domain-specific interfaces to the saved object management plugin * Add a V1 interface of domain types to `common` * Remove use of deprecated `SavedObject` type from public * Follows on from https://github.com/elastic/kibana/pull/148602 Related https://github.com/elastic/kibana/issues/149098 Fixes https://github.com/elastic/kibana/pull/149495 --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
parent
b1617498a5
commit
df809bd53a
35 changed files with 383 additions and 211 deletions
|
@ -12,6 +12,6 @@ export type {
|
|||
SavedObjectRelation,
|
||||
SavedObjectRelationKind,
|
||||
SavedObjectInvalidRelation,
|
||||
SavedObjectGetRelationshipsResponse,
|
||||
SavedObjectManagementTypeInfo,
|
||||
v1,
|
||||
} from './types';
|
||||
|
|
|
@ -1,61 +0,0 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import type { SavedObject } from '@kbn/core/types';
|
||||
import type { SavedObjectsNamespaceType } from '@kbn/core/public';
|
||||
|
||||
/**
|
||||
* The metadata injected into a {@link SavedObject | saved object} when returning
|
||||
* {@link SavedObjectWithMetadata | enhanced objects} from the plugin API endpoints.
|
||||
*/
|
||||
export interface SavedObjectMetadata {
|
||||
icon?: string;
|
||||
title?: string;
|
||||
editUrl?: string;
|
||||
inAppUrl?: { path: string; uiCapabilitiesPath: string };
|
||||
namespaceType?: SavedObjectsNamespaceType;
|
||||
hiddenType?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* A {@link SavedObject | saved object} enhanced with meta properties used by the client-side plugin.
|
||||
*/
|
||||
export type SavedObjectWithMetadata<T = unknown> = SavedObject<T> & {
|
||||
meta: SavedObjectMetadata;
|
||||
};
|
||||
|
||||
export type SavedObjectRelationKind = 'child' | 'parent';
|
||||
|
||||
/**
|
||||
* Represents a relation between two {@link SavedObject | saved object}
|
||||
*/
|
||||
export interface SavedObjectRelation {
|
||||
id: string;
|
||||
type: string;
|
||||
relationship: SavedObjectRelationKind;
|
||||
meta: SavedObjectMetadata;
|
||||
}
|
||||
|
||||
export interface SavedObjectInvalidRelation {
|
||||
id: string;
|
||||
type: string;
|
||||
relationship: SavedObjectRelationKind;
|
||||
error: string;
|
||||
}
|
||||
|
||||
export interface SavedObjectGetRelationshipsResponse {
|
||||
relations: SavedObjectRelation[];
|
||||
invalidRelations: SavedObjectInvalidRelation[];
|
||||
}
|
||||
|
||||
export interface SavedObjectManagementTypeInfo {
|
||||
name: string;
|
||||
namespaceType: SavedObjectsNamespaceType;
|
||||
hidden: boolean;
|
||||
displayName: string;
|
||||
}
|
58
src/plugins/saved_objects_management/common/types/README.md
Normal file
58
src/plugins/saved_objects_management/common/types/README.md
Normal file
|
@ -0,0 +1,58 @@
|
|||
## Versioned interfaces
|
||||
|
||||
This folder contains types that are shared between the server and client:
|
||||
|
||||
```ts
|
||||
// v1.ts
|
||||
export interface SavedObjectWithMetadata { name: string }
|
||||
|
||||
// index.ts
|
||||
import * as v1 from './v1';
|
||||
export type { v1 };
|
||||
|
||||
// Used elsewhere
|
||||
import type { v1 } from '../common';
|
||||
const myObject: v1.SavedObjectWithMetadata = { name: 'my object' };
|
||||
```
|
||||
|
||||
**Do not alter a versioned type**. Types may be in use by clients (if the code is released).
|
||||
Alterations must be made on a new version of the TS interface.
|
||||
|
||||
## Create a new version
|
||||
|
||||
Versions in this plugin are determined using monotonically increasing numbers: 1, 2, 3, etc.
|
||||
|
||||
1. Find the latest version, e.g: `v2`.
|
||||
2. Create a new file, e.g., `v3.ts` if it does not exist.
|
||||
3. Copy the type(s) to change from previous version. E.g. `v2.ts`'s `SavedObjectWithMetadata`.
|
||||
4. Alter the interface as needed
|
||||
5. Re-export `v2` types to "inherit" the entire previous version's types: `export * from './v2';`
|
||||
6. Export your new version from latest: `export * from './v3';`. This may result in TS errors
|
||||
to be fixed.
|
||||
7. Export your new file from index.ts as `v3`.
|
||||
|
||||
Your `v3.ts` file should look something like:
|
||||
|
||||
```ts
|
||||
export * from './v3';
|
||||
export interface SavedObjectWithMetadata { name: string; a_new_field: string; }
|
||||
```
|
||||
|
||||
In this way the entire API is accessible from `v3` including types that may
|
||||
not have changed.
|
||||
|
||||
Any alterations post-release must be in a new version (start at step 1).
|
||||
|
||||
|
||||
## The `latest.ts` file
|
||||
|
||||
The `latest.ts` file is a container for all "latest" versions of types. This is useful
|
||||
for app code that always needs the latest version of your interfaces. E.g.:
|
||||
|
||||
```ts
|
||||
import type { SavedObjectWithMetadata } from '../common';
|
||||
```
|
||||
|
||||
Notice that there is no version number mentioned. Either in the interface name
|
||||
or import path. To update the "latest" type you must re-export the new version
|
||||
from the appropriate versioned path.
|
19
src/plugins/saved_objects_management/common/types/index.ts
Normal file
19
src/plugins/saved_objects_management/common/types/index.ts
Normal file
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
export type {
|
||||
SavedObjectInvalidRelation,
|
||||
SavedObjectManagementTypeInfo,
|
||||
SavedObjectMetadata,
|
||||
SavedObjectRelation,
|
||||
SavedObjectRelationKind,
|
||||
SavedObjectWithMetadata,
|
||||
} from './latest';
|
||||
|
||||
import type * as v1 from './v1';
|
||||
export type { v1 };
|
|
@ -6,8 +6,4 @@
|
|||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import { mapKeys, camelCase } from 'lodash';
|
||||
|
||||
export function keysToCamelCaseShallow(object: Record<string, any>) {
|
||||
return mapKeys(object, (value, key) => camelCase(key));
|
||||
}
|
||||
export * from './v1';
|
178
src/plugins/saved_objects_management/common/types/v1.ts
Normal file
178
src/plugins/saved_objects_management/common/types/v1.ts
Normal file
|
@ -0,0 +1,178 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import type { SavedObjectError } from '@kbn/core/types';
|
||||
import type { SavedObjectsNamespaceType } from '@kbn/core/public';
|
||||
|
||||
/** Domain interfaces */
|
||||
|
||||
/**
|
||||
* Saved Object Management metadata associated with a saved object. See
|
||||
* {@link SavedObjectWithMetadata}.
|
||||
*/
|
||||
export interface SavedObjectMetadata {
|
||||
icon?: string;
|
||||
title?: string;
|
||||
editUrl?: string;
|
||||
inAppUrl?: { path: string; uiCapabilitiesPath: string };
|
||||
namespaceType?: SavedObjectsNamespaceType;
|
||||
hiddenType?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* One saved object's reference to another saved object.
|
||||
*/
|
||||
export interface SavedObjectReference {
|
||||
name: string;
|
||||
type: string;
|
||||
id: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* A saved object.
|
||||
*
|
||||
* @note This is intended as a domain-specific representation of a SavedObject
|
||||
* which is intended for server-side only use.
|
||||
*/
|
||||
export interface SavedObjectWithMetadata<T = unknown> {
|
||||
id: string;
|
||||
type: string;
|
||||
meta: SavedObjectMetadata;
|
||||
error?: SavedObjectError;
|
||||
created_at?: string;
|
||||
updated_at?: string;
|
||||
attributes: T;
|
||||
namespaces?: string[];
|
||||
references: SavedObjectReference[];
|
||||
}
|
||||
|
||||
export type SavedObjectRelationKind = 'child' | 'parent';
|
||||
|
||||
/**
|
||||
* Represents a relation between two {@link SavedObjectWithMetadata | saved objects}.
|
||||
*/
|
||||
export interface SavedObjectRelation {
|
||||
id: string;
|
||||
type: string;
|
||||
relationship: SavedObjectRelationKind;
|
||||
meta: SavedObjectMetadata;
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a relation between two {@link SavedObjectWithMetadata | saved objects}.
|
||||
*/
|
||||
export interface SavedObjectInvalidRelation {
|
||||
id: string;
|
||||
type: string;
|
||||
relationship: SavedObjectRelationKind;
|
||||
error: string;
|
||||
}
|
||||
|
||||
export interface SavedObjectManagementTypeInfo {
|
||||
name: string;
|
||||
// TODO: Fix. We should not directly expose these values to public code.
|
||||
namespaceType: SavedObjectsNamespaceType;
|
||||
hidden: boolean;
|
||||
displayName: string;
|
||||
}
|
||||
|
||||
/** HTTP API interfaces */
|
||||
|
||||
export type BulkGetBodyHTTP = Array<{
|
||||
id: string;
|
||||
type: string;
|
||||
}>;
|
||||
|
||||
export type BulkGetResponseHTTP = SavedObjectWithMetadata[];
|
||||
|
||||
export type BulkDeleteBodyHTTP = Array<{
|
||||
type: string;
|
||||
id: string;
|
||||
}>;
|
||||
|
||||
export type BulkDeleteResponseHTTP = Array<{
|
||||
/** The ID of the saved object */
|
||||
id: string;
|
||||
/** The type of the saved object */
|
||||
type: string;
|
||||
/** The status of deleting the object: true for deleted, false for error */
|
||||
success: boolean;
|
||||
/** Reason the object could not be deleted (success is false) */
|
||||
error?: SavedObjectError;
|
||||
}>;
|
||||
|
||||
export type FindSearchOperatorHTTP = 'AND' | 'OR';
|
||||
export type FindSortOrderHTTP = 'asc' | 'desc';
|
||||
|
||||
export interface ReferenceHTTP {
|
||||
type: string;
|
||||
id: string;
|
||||
}
|
||||
|
||||
export interface FindQueryHTTP {
|
||||
perPage?: number;
|
||||
page?: number;
|
||||
type: string | string[];
|
||||
// TODO: Fix. this API allows writing an arbitrary query that is passed straight to our persistence layer, thus leaking SO attributes to the public...
|
||||
search?: string;
|
||||
defaultSearchOperator?: FindSearchOperatorHTTP;
|
||||
// TODO: Fix. this API allows sorting by any field, thus leaking SO attributes to the public...
|
||||
sortField?: string;
|
||||
sortOrder?: FindSortOrderHTTP;
|
||||
hasReference?: ReferenceHTTP | ReferenceHTTP[];
|
||||
hasReferenceOperator?: FindSearchOperatorHTTP;
|
||||
// TODO: Fix. This exposes attribute schemas to clients.
|
||||
fields?: string | string[];
|
||||
}
|
||||
|
||||
export interface FindResponseHTTP {
|
||||
saved_objects: SavedObjectWithMetadata[];
|
||||
total: number;
|
||||
page: number;
|
||||
per_page: number;
|
||||
}
|
||||
|
||||
export interface GetAllowedTypesResponseHTTP {
|
||||
types: SavedObjectManagementTypeInfo[];
|
||||
}
|
||||
|
||||
export interface RelationshipsParamsHTTP {
|
||||
type: string;
|
||||
id: string;
|
||||
}
|
||||
|
||||
export interface RelationshipsQueryHTTP {
|
||||
size: number;
|
||||
savedObjectTypes: string | string[];
|
||||
}
|
||||
|
||||
export interface RelationshipsResponseHTTP {
|
||||
relations: SavedObjectRelation[];
|
||||
invalidRelations: SavedObjectInvalidRelation[];
|
||||
}
|
||||
|
||||
export interface ScrollCountBodyHTTP {
|
||||
typesToInclude: string[];
|
||||
// TODO: Fix. this API allows writing an arbitrary query that is passed straight to our persistence layer, thus leaking SO attributes to the public...
|
||||
searchString?: string;
|
||||
references?: Array<{ type: string; id: string }>;
|
||||
}
|
||||
|
||||
export interface DeleteObjectBodyHTTP {
|
||||
id: string;
|
||||
type: string;
|
||||
}
|
||||
|
||||
export interface DeleteObjectResponseHTTP {
|
||||
id: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* In this case "string" is a direct mapping from "typesToInlcude" in {@link ScrollCountBodyHTTP['typesToInclude']']}
|
||||
*/
|
||||
export type ScrollCountResponseHTTP = Record<string, number>;
|
|
@ -6,24 +6,14 @@
|
|||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import { HttpStart } from '@kbn/core/public';
|
||||
import { SavedObjectError, SavedObjectTypeIdTuple } from '@kbn/core-saved-objects-common';
|
||||
|
||||
interface SavedObjectDeleteStatus {
|
||||
id: string;
|
||||
success: boolean;
|
||||
type: string;
|
||||
error?: SavedObjectError;
|
||||
}
|
||||
import type { HttpStart } from '@kbn/core/public';
|
||||
import type { v1 } from '../../common';
|
||||
|
||||
export function bulkDeleteObjects(
|
||||
http: HttpStart,
|
||||
objects: SavedObjectTypeIdTuple[]
|
||||
): Promise<SavedObjectDeleteStatus[]> {
|
||||
return http.post<SavedObjectDeleteStatus[]>(
|
||||
'/internal/kibana/management/saved_objects/_bulk_delete',
|
||||
{
|
||||
body: JSON.stringify(objects),
|
||||
}
|
||||
);
|
||||
objects: v1.BulkDeleteBodyHTTP
|
||||
): Promise<v1.BulkDeleteResponseHTTP> {
|
||||
return http.post('/internal/kibana/management/saved_objects/_bulk_delete', {
|
||||
body: JSON.stringify(objects),
|
||||
});
|
||||
}
|
||||
|
|
|
@ -6,15 +6,14 @@
|
|||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import { HttpStart } from '@kbn/core/public';
|
||||
import { SavedObjectWithMetadata } from '../types';
|
||||
import type { HttpStart } from '@kbn/core/public';
|
||||
import type { v1 } from '../../common';
|
||||
|
||||
export async function bulkGetObjects(
|
||||
http: HttpStart,
|
||||
objects: Array<{ type: string; id: string }>
|
||||
): Promise<SavedObjectWithMetadata[]> {
|
||||
return await http.post<SavedObjectWithMetadata[]>(
|
||||
`/api/kibana/management/saved_objects/_bulk_get`,
|
||||
{ body: JSON.stringify(objects) }
|
||||
);
|
||||
objects: v1.BulkGetBodyHTTP
|
||||
): Promise<v1.BulkGetResponseHTTP> {
|
||||
return await http.post(`/api/kibana/management/saved_objects/_bulk_get`, {
|
||||
body: JSON.stringify(objects),
|
||||
});
|
||||
}
|
||||
|
|
|
@ -1,25 +0,0 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import { keysToCamelCaseShallow } from './case_conversion';
|
||||
|
||||
describe('keysToCamelCaseShallow', () => {
|
||||
test("should convert all of an object's keys to camel case", () => {
|
||||
const data = {
|
||||
camelCase: 'camelCase',
|
||||
'kebab-case': 'kebabCase',
|
||||
snake_case: 'snakeCase',
|
||||
};
|
||||
|
||||
const result = keysToCamelCaseShallow(data);
|
||||
|
||||
expect(result.camelCase).toBe('camelCase');
|
||||
expect(result.kebabCase).toBe('kebabCase');
|
||||
expect(result.snakeCase).toBe('snakeCase');
|
||||
});
|
||||
});
|
|
@ -6,7 +6,7 @@
|
|||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import { HttpStart, SavedObjectsFindOptionsReference } from '@kbn/core/public';
|
||||
import type { HttpStart, SavedObjectsFindOptionsReference } from '@kbn/core/public';
|
||||
|
||||
export async function fetchExportByTypeAndSearch({
|
||||
http,
|
||||
|
|
|
@ -6,32 +6,17 @@
|
|||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import { HttpStart, SavedObjectsFindOptions } from '@kbn/core/public';
|
||||
import { keysToCamelCaseShallow } from './case_conversion';
|
||||
import { SavedObjectWithMetadata } from '../types';
|
||||
|
||||
interface SavedObjectsFindResponse {
|
||||
total: number;
|
||||
page: number;
|
||||
perPage: number;
|
||||
savedObjects: SavedObjectWithMetadata[];
|
||||
}
|
||||
import { HttpStart } from '@kbn/core/public';
|
||||
import type { v1 } from '../../common';
|
||||
|
||||
export async function findObjects(
|
||||
http: HttpStart,
|
||||
findOptions: SavedObjectsFindOptions
|
||||
): Promise<SavedObjectsFindResponse> {
|
||||
const response = await http.get<Record<string, any>>(
|
||||
'/api/kibana/management/saved_objects/_find',
|
||||
{
|
||||
query: {
|
||||
...findOptions,
|
||||
hasReference: findOptions.hasReference
|
||||
? JSON.stringify(findOptions.hasReference)
|
||||
: undefined,
|
||||
} as Record<string, any>,
|
||||
}
|
||||
);
|
||||
|
||||
return keysToCamelCaseShallow(response) as SavedObjectsFindResponse;
|
||||
findOptions: v1.FindQueryHTTP
|
||||
): Promise<v1.FindResponseHTTP> {
|
||||
return http.get('/api/kibana/management/saved_objects/_find', {
|
||||
query: {
|
||||
...findOptions,
|
||||
hasReference: findOptions.hasReference ? JSON.stringify(findOptions.hasReference) : undefined,
|
||||
} as Record<string, any>,
|
||||
});
|
||||
}
|
||||
|
|
|
@ -7,14 +7,12 @@
|
|||
*/
|
||||
|
||||
import type { HttpStart } from '@kbn/core/public';
|
||||
import type { SavedObjectManagementTypeInfo } from '../../common/types';
|
||||
import type { v1 } from '../../common';
|
||||
|
||||
interface GetAllowedTypesResponse {
|
||||
types: SavedObjectManagementTypeInfo[];
|
||||
}
|
||||
|
||||
export async function getAllowedTypes(http: HttpStart): Promise<SavedObjectManagementTypeInfo[]> {
|
||||
const response = await http.get<GetAllowedTypesResponse>(
|
||||
export async function getAllowedTypes(
|
||||
http: HttpStart
|
||||
): Promise<v1.GetAllowedTypesResponseHTTP['types']> {
|
||||
const response = await http.get<v1.GetAllowedTypesResponseHTTP>(
|
||||
'/api/kibana/management/saved_objects/_allowed_types'
|
||||
);
|
||||
return response.types;
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import { SavedObjectGetRelationshipsResponse } from '../types';
|
||||
import { v1 } from '../../common';
|
||||
import { httpServiceMock } from '@kbn/core/public/mocks';
|
||||
import { getRelationships } from './get_relationships';
|
||||
|
||||
|
@ -23,7 +23,7 @@ describe('getRelationships', () => {
|
|||
});
|
||||
|
||||
it('should handle successful responses', async () => {
|
||||
const serverResponse: SavedObjectGetRelationshipsResponse = {
|
||||
const serverResponse: v1.RelationshipsResponseHTTP = {
|
||||
relations: [],
|
||||
invalidRelations: [],
|
||||
};
|
||||
|
|
|
@ -6,21 +6,21 @@
|
|||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import { HttpStart } from '@kbn/core/public';
|
||||
import type { HttpStart } from '@kbn/core/public';
|
||||
import { get } from 'lodash';
|
||||
import { SavedObjectGetRelationshipsResponse } from '../types';
|
||||
import type { v1 } from '../../common';
|
||||
|
||||
export async function getRelationships(
|
||||
http: HttpStart,
|
||||
type: string,
|
||||
id: string,
|
||||
savedObjectTypes: string[]
|
||||
): Promise<SavedObjectGetRelationshipsResponse> {
|
||||
): Promise<v1.RelationshipsResponseHTTP> {
|
||||
const url = `/api/kibana/management/saved_objects/relationships/${encodeURIComponent(
|
||||
type
|
||||
)}/${encodeURIComponent(id)}`;
|
||||
try {
|
||||
return await http.get<SavedObjectGetRelationshipsResponse>(url, {
|
||||
return await http.get(url, {
|
||||
query: {
|
||||
savedObjectTypes,
|
||||
},
|
||||
|
|
|
@ -6,7 +6,8 @@
|
|||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import { HttpStart, SavedObjectsFindOptionsReference } from '@kbn/core/public';
|
||||
import type { HttpStart, SavedObjectsFindOptionsReference } from '@kbn/core/public';
|
||||
import type { v1 } from '../../common';
|
||||
|
||||
export async function getSavedObjectCounts({
|
||||
http,
|
||||
|
@ -18,9 +19,8 @@ export async function getSavedObjectCounts({
|
|||
typesToInclude: string[];
|
||||
searchString?: string;
|
||||
references?: SavedObjectsFindOptionsReference[];
|
||||
}): Promise<Record<string, number>> {
|
||||
return await http.post<Record<string, number>>(
|
||||
`/api/kibana/management/saved_objects/scroll/counts`,
|
||||
{ body: JSON.stringify({ typesToInclude, searchString, references }) }
|
||||
);
|
||||
}): Promise<v1.ScrollCountResponseHTTP> {
|
||||
return await http.post(`/api/kibana/management/saved_objects/scroll/counts`, {
|
||||
body: JSON.stringify({ typesToInclude, searchString, references }),
|
||||
});
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import {
|
||||
import type {
|
||||
SavedObjectsImportConflictError,
|
||||
SavedObjectsImportAmbiguousConflictError,
|
||||
SavedObjectsImportUnknownError,
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import {
|
||||
import type {
|
||||
SavedObjectsImportResponse,
|
||||
SavedObjectsImportConflictError,
|
||||
SavedObjectsImportAmbiguousConflictError,
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import {
|
||||
import type {
|
||||
HttpStart,
|
||||
SavedObjectsImportConflictError,
|
||||
SavedObjectsImportRetry,
|
||||
|
|
|
@ -28,17 +28,17 @@ import { FormattedMessage } from '@kbn/i18n-react';
|
|||
import { IBasePath } from '@kbn/core/public';
|
||||
import type { SavedObjectManagementTypeInfo } from '../../../../common/types';
|
||||
import { getDefaultTitle, getSavedObjectLabel } from '../../../lib';
|
||||
import type { v1 } from '../../../../common';
|
||||
import {
|
||||
SavedObjectWithMetadata,
|
||||
SavedObjectRelationKind,
|
||||
SavedObjectRelation,
|
||||
SavedObjectInvalidRelation,
|
||||
SavedObjectGetRelationshipsResponse,
|
||||
} from '../../../types';
|
||||
|
||||
export interface RelationshipsProps {
|
||||
basePath: IBasePath;
|
||||
getRelationships: (type: string, id: string) => Promise<SavedObjectGetRelationshipsResponse>;
|
||||
getRelationships: (type: string, id: string) => Promise<v1.RelationshipsResponseHTTP>;
|
||||
savedObject: SavedObjectWithMetadata;
|
||||
close: () => void;
|
||||
goInspectObject: (obj: SavedObjectWithMetadata) => void;
|
||||
|
|
|
@ -121,6 +121,7 @@ describe('SavedObjectsTable', () => {
|
|||
};
|
||||
|
||||
http.post.mockResolvedValue([]);
|
||||
http.delete.mockResolvedValue({ id: 'test' });
|
||||
|
||||
getSavedObjectCountsMock.mockReturnValue({
|
||||
'index-pattern': 0,
|
||||
|
@ -147,7 +148,7 @@ describe('SavedObjectsTable', () => {
|
|||
|
||||
findObjectsMock.mockImplementation(() => ({
|
||||
total: 4,
|
||||
savedObjects: [
|
||||
saved_objects: [
|
||||
{
|
||||
id: '1',
|
||||
type: 'index-pattern',
|
||||
|
|
|
@ -34,6 +34,7 @@ import {
|
|||
SavedObjectsExportResultDetails,
|
||||
getTagFindReferences,
|
||||
} from '../../lib';
|
||||
|
||||
import { SavedObjectWithMetadata } from '../../types';
|
||||
import {
|
||||
SavedObjectsManagementActionServiceStart,
|
||||
|
@ -257,7 +258,7 @@ export class SavedObjectsTable extends Component<SavedObjectsTableProps, SavedOb
|
|||
}
|
||||
|
||||
return {
|
||||
savedObjects: resp.savedObjects,
|
||||
savedObjects: resp.saved_objects,
|
||||
filteredItemCount: resp.total,
|
||||
isSearching: false,
|
||||
};
|
||||
|
|
|
@ -23,7 +23,9 @@ import {
|
|||
SavedObjectsManagementColumnServiceStart,
|
||||
} from './services';
|
||||
|
||||
import { SavedObjectManagementTypeInfo, SavedObjectGetRelationshipsResponse } from './types';
|
||||
import type { v1 } from '../common';
|
||||
|
||||
import { SavedObjectManagementTypeInfo } from './types';
|
||||
import {
|
||||
getAllowedTypes,
|
||||
getRelationships,
|
||||
|
@ -46,7 +48,7 @@ export interface SavedObjectsManagementPluginStart {
|
|||
type: string,
|
||||
id: string,
|
||||
savedObjectTypes: string[]
|
||||
) => Promise<SavedObjectGetRelationshipsResponse>;
|
||||
) => Promise<v1.RelationshipsResponseHTTP>;
|
||||
getSavedObjectLabel: typeof getSavedObjectLabel;
|
||||
getDefaultTitle: typeof getDefaultTitle;
|
||||
parseQuery: typeof parseQuery;
|
||||
|
|
|
@ -12,6 +12,5 @@ export type {
|
|||
SavedObjectRelationKind,
|
||||
SavedObjectRelation,
|
||||
SavedObjectInvalidRelation,
|
||||
SavedObjectGetRelationshipsResponse,
|
||||
SavedObjectManagementTypeInfo,
|
||||
} from '../common';
|
||||
|
|
|
@ -9,11 +9,8 @@
|
|||
import { SavedObjectsClientContract } from '@kbn/core/server';
|
||||
import { injectMetaAttributes } from './inject_meta_attributes';
|
||||
import { ISavedObjectsManagement } from '../services';
|
||||
import {
|
||||
SavedObjectInvalidRelation,
|
||||
SavedObjectWithMetadata,
|
||||
SavedObjectGetRelationshipsResponse,
|
||||
} from '../types';
|
||||
import { v1 } from '../../common';
|
||||
import { SavedObjectInvalidRelation, SavedObjectWithMetadata } from '../types';
|
||||
|
||||
export async function findRelationships({
|
||||
type,
|
||||
|
@ -29,7 +26,7 @@ export async function findRelationships({
|
|||
client: SavedObjectsClientContract;
|
||||
referenceTypes: string[];
|
||||
savedObjectsManagement: ISavedObjectsManagement;
|
||||
}): Promise<SavedObjectGetRelationshipsResponse> {
|
||||
}): Promise<v1.RelationshipsResponseHTTP> {
|
||||
const { references = [] } = await client.get(type, id);
|
||||
|
||||
// Use a map to avoid duplicates, it does happen but have a different "name" in the reference
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
export { toSavedObjectWithMeta } from './to_saved_object_with_meta';
|
||||
export { injectMetaAttributes } from './inject_meta_attributes';
|
||||
export { findAll } from './find_all';
|
||||
export { findRelationships } from './find_relationships';
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import { SavedObject } from '@kbn/core/server';
|
||||
import { SavedObjectWithMetadata } from '../../common/types/v1';
|
||||
|
||||
export function toSavedObjectWithMeta(so: SavedObject): SavedObjectWithMetadata {
|
||||
return {
|
||||
id: so.id,
|
||||
type: so.type,
|
||||
namespaces: so.namespaces,
|
||||
references: so.references,
|
||||
updated_at: so.updated_at,
|
||||
attributes: so.attributes,
|
||||
created_at: so.created_at,
|
||||
error: so.error,
|
||||
meta: {},
|
||||
};
|
||||
}
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
import { schema } from '@kbn/config-schema';
|
||||
import { IRouter } from '@kbn/core/server';
|
||||
import type { v1 } from '../../common';
|
||||
|
||||
export const registerBulkDeleteRoute = (router: IRouter) => {
|
||||
router.post(
|
||||
|
@ -29,7 +30,8 @@ export const registerBulkDeleteRoute = (router: IRouter) => {
|
|||
const client = getClient();
|
||||
const response = await client.bulkDelete(objects, { force: true });
|
||||
|
||||
return res.ok({ body: response.statuses });
|
||||
const body: v1.BulkDeleteResponseHTTP = response.statuses;
|
||||
return res.ok({ body });
|
||||
})
|
||||
);
|
||||
};
|
||||
|
|
|
@ -7,9 +7,10 @@
|
|||
*/
|
||||
|
||||
import { schema } from '@kbn/config-schema';
|
||||
import { IRouter } from '@kbn/core/server';
|
||||
import { injectMetaAttributes } from '../lib';
|
||||
import { ISavedObjectsManagement } from '../services';
|
||||
import type { IRouter } from '@kbn/core/server';
|
||||
import { injectMetaAttributes, toSavedObjectWithMeta } from '../lib';
|
||||
import type { v1 } from '../../common';
|
||||
import type { ISavedObjectsManagement } from '../services';
|
||||
|
||||
export const registerBulkGetRoute = (
|
||||
router: IRouter,
|
||||
|
@ -39,14 +40,16 @@ export const registerBulkGetRoute = (
|
|||
|
||||
const client = getClient({ includedHiddenTypes });
|
||||
const response = await client.bulkGet<unknown>(objects);
|
||||
const enhancedObjects = response.saved_objects.map((obj) => {
|
||||
if (!obj.error) {
|
||||
|
||||
const body: v1.BulkGetResponseHTTP = response.saved_objects.map((obj) => {
|
||||
const so = toSavedObjectWithMeta(obj);
|
||||
if (!so.error) {
|
||||
return injectMetaAttributes(obj, managementService);
|
||||
}
|
||||
return obj;
|
||||
return so;
|
||||
});
|
||||
|
||||
return res.ok({ body: enhancedObjects });
|
||||
return res.ok({ body });
|
||||
})
|
||||
);
|
||||
};
|
||||
|
|
|
@ -7,9 +7,11 @@
|
|||
*/
|
||||
|
||||
import { schema } from '@kbn/config-schema';
|
||||
import { IRouter } from '@kbn/core/server';
|
||||
import { injectMetaAttributes } from '../lib';
|
||||
import { ISavedObjectsManagement } from '../services';
|
||||
import type { IRouter } from '@kbn/core/server';
|
||||
|
||||
import type { v1 } from '../../common';
|
||||
import { injectMetaAttributes, toSavedObjectWithMeta } from '../lib';
|
||||
import type { ISavedObjectsManagement } from '../services';
|
||||
|
||||
export const registerFindRoute = (
|
||||
router: IRouter,
|
||||
|
@ -77,22 +79,23 @@ export const registerFindRoute = (
|
|||
searchFields: [...searchFields],
|
||||
});
|
||||
|
||||
const enhancedSavedObjects = findResponse.saved_objects
|
||||
.map((so) => injectMetaAttributes(so, managementService))
|
||||
.map((obj) => {
|
||||
const result = { ...obj, attributes: {} as Record<string, any> };
|
||||
const savedObjects = findResponse.saved_objects.map(toSavedObjectWithMeta);
|
||||
|
||||
const response: v1.FindResponseHTTP = {
|
||||
saved_objects: savedObjects.map((so) => {
|
||||
const obj = injectMetaAttributes(so, managementService);
|
||||
const result = { ...obj, attributes: {} as Record<string, unknown> };
|
||||
for (const field of includedFields) {
|
||||
result.attributes[field] = obj.attributes[field];
|
||||
result.attributes[field] = (obj.attributes as Record<string, unknown>)[field];
|
||||
}
|
||||
return result;
|
||||
});
|
||||
}),
|
||||
total: findResponse.total,
|
||||
per_page: findResponse.per_page,
|
||||
page: findResponse.page,
|
||||
};
|
||||
|
||||
return res.ok({
|
||||
body: {
|
||||
...findResponse,
|
||||
saved_objects: enhancedSavedObjects,
|
||||
},
|
||||
});
|
||||
return res.ok({ body: response });
|
||||
})
|
||||
);
|
||||
};
|
||||
|
|
|
@ -6,8 +6,8 @@
|
|||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import { IRouter, SavedObjectsType } from '@kbn/core/server';
|
||||
import { SavedObjectManagementTypeInfo } from '../../common';
|
||||
import type { IRouter, SavedObjectsType } from '@kbn/core/server';
|
||||
import type { SavedObjectManagementTypeInfo } from '../../common';
|
||||
|
||||
const convertType = (sot: SavedObjectsType): SavedObjectManagementTypeInfo => {
|
||||
return {
|
||||
|
|
|
@ -7,10 +7,11 @@
|
|||
*/
|
||||
|
||||
import { schema } from '@kbn/config-schema';
|
||||
import { IRouter } from '@kbn/core/server';
|
||||
import type { IRouter } from '@kbn/core/server';
|
||||
import { chain } from 'lodash';
|
||||
import { findRelationships } from '../lib';
|
||||
import { ISavedObjectsManagement } from '../services';
|
||||
import type { ISavedObjectsManagement } from '../services';
|
||||
import type { v1 } from '../../common';
|
||||
|
||||
export const registerRelationshipsRoute = (
|
||||
router: IRouter,
|
||||
|
@ -48,7 +49,7 @@ export const registerRelationshipsRoute = (
|
|||
|
||||
const client = getClient({ includedHiddenTypes });
|
||||
|
||||
const findRelationsResponse = await findRelationships({
|
||||
const findRelationsResponse: v1.RelationshipsResponseHTTP = await findRelationships({
|
||||
type,
|
||||
id,
|
||||
client,
|
||||
|
|
|
@ -7,8 +7,9 @@
|
|||
*/
|
||||
|
||||
import { schema } from '@kbn/config-schema';
|
||||
import { IRouter, SavedObjectsCreatePointInTimeFinderOptions } from '@kbn/core/server';
|
||||
import type { IRouter, SavedObjectsCreatePointInTimeFinderOptions } from '@kbn/core/server';
|
||||
import { chain } from 'lodash';
|
||||
import type { v1 } from '../../common';
|
||||
import { findAll } from '../lib';
|
||||
|
||||
export const registerScrollForCountRoute = (router: IRouter) => {
|
||||
|
@ -70,8 +71,10 @@ export const registerScrollForCountRoute = (router: IRouter) => {
|
|||
}
|
||||
}
|
||||
|
||||
const body: v1.ScrollCountResponseHTTP = counts;
|
||||
|
||||
return res.ok({
|
||||
body: counts,
|
||||
body,
|
||||
});
|
||||
})
|
||||
);
|
||||
|
|
|
@ -18,5 +18,4 @@ export type {
|
|||
SavedObjectRelationKind,
|
||||
SavedObjectRelation,
|
||||
SavedObjectInvalidRelation,
|
||||
SavedObjectGetRelationshipsResponse,
|
||||
} from '../common';
|
||||
|
|
|
@ -22,7 +22,6 @@
|
|||
"@kbn/i18n-react",
|
||||
"@kbn/test-jest-helpers",
|
||||
"@kbn/core-saved-objects-api-server",
|
||||
"@kbn/core-saved-objects-common",
|
||||
"@kbn/monaco",
|
||||
"@kbn/config-schema",
|
||||
"@kbn/core-custom-branding-browser-mocks",
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
import { join } from 'path';
|
||||
import expect from '@kbn/expect';
|
||||
import type { Response } from 'supertest';
|
||||
import { SavedObject } from '@kbn/core/types';
|
||||
import { SavedObject } from '@kbn/core/server';
|
||||
import type { SavedObjectManagementTypeInfo } from '@kbn/saved-objects-management-plugin/common/types';
|
||||
import type { PluginFunctionalProviderContext } from '../../services';
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue