mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 17:59:23 -04:00
[content management / maps] Content management / Saved object schema abstraction (#155342)
## Summary Abstract schema definitions for using Saved Objects with the content management api. For most schema types, this will reduce creation to only the attributes specific to a saved object. For Option types (create options, update options, search options) the saved object api is more complex and its likely that most SO types will only need to use a portion of it. In these cases we recommend using the provided schema definitions as a pattern for creating simpler schemas. Follow up to - https://github.com/elastic/kibana/pull/154985 - expresses types in schema form --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
parent
b01d60a994
commit
0c8f38b86f
5 changed files with 143 additions and 72 deletions
|
@ -6,4 +6,5 @@
|
|||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
export * from './types';
|
||||
export * from './src/types';
|
||||
export * from './src/schema';
|
||||
|
|
122
packages/kbn-content-management-utils/src/schema.ts
Normal file
122
packages/kbn-content-management-utils/src/schema.ts
Normal file
|
@ -0,0 +1,122 @@
|
|||
/*
|
||||
* 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 { schema, ObjectType } from '@kbn/config-schema';
|
||||
|
||||
export const apiError = schema.object({
|
||||
error: schema.string(),
|
||||
message: schema.string(),
|
||||
statusCode: schema.number(),
|
||||
metadata: schema.object({}, { unknowns: 'allow' }),
|
||||
});
|
||||
|
||||
export const referenceSchema = schema.object(
|
||||
{
|
||||
name: schema.maybe(schema.string()),
|
||||
type: schema.string(),
|
||||
id: schema.string(),
|
||||
},
|
||||
{ unknowns: 'forbid' }
|
||||
);
|
||||
|
||||
export const referencesSchema = schema.arrayOf(referenceSchema);
|
||||
|
||||
export const savedObjectSchema = (attributesSchema: ObjectType<any>) =>
|
||||
schema.object(
|
||||
{
|
||||
id: schema.string(),
|
||||
type: schema.string(),
|
||||
version: schema.maybe(schema.string()),
|
||||
createdAt: schema.maybe(schema.string()),
|
||||
updatedAt: schema.maybe(schema.string()),
|
||||
error: schema.maybe(apiError),
|
||||
attributes: attributesSchema,
|
||||
references: referencesSchema,
|
||||
namespaces: schema.maybe(schema.arrayOf(schema.string())),
|
||||
originId: schema.maybe(schema.string()),
|
||||
},
|
||||
{ unknowns: 'allow' }
|
||||
);
|
||||
|
||||
export const objectTypeToGetResultSchema = (soSchema: ObjectType<any>) =>
|
||||
schema.object(
|
||||
{
|
||||
item: soSchema,
|
||||
meta: schema.object(
|
||||
{
|
||||
outcome: schema.oneOf([
|
||||
schema.literal('exactMatch'),
|
||||
schema.literal('aliasMatch'),
|
||||
schema.literal('conflict'),
|
||||
]),
|
||||
aliasTargetId: schema.maybe(schema.string()),
|
||||
aliasPurpose: schema.maybe(
|
||||
schema.oneOf([
|
||||
schema.literal('savedObjectConversion'),
|
||||
schema.literal('savedObjectImport'),
|
||||
])
|
||||
),
|
||||
},
|
||||
{ unknowns: 'forbid' }
|
||||
),
|
||||
},
|
||||
{ unknowns: 'forbid' }
|
||||
);
|
||||
|
||||
// its recommended to create a subset of this schema for stricter validation
|
||||
export const createOptionsSchemas = {
|
||||
id: schema.maybe(schema.string()),
|
||||
references: schema.maybe(referencesSchema),
|
||||
overwrite: schema.maybe(schema.boolean()),
|
||||
version: schema.maybe(schema.string()),
|
||||
refresh: schema.maybe(schema.boolean()),
|
||||
initialNamespaces: schema.maybe(schema.arrayOf(schema.string())),
|
||||
};
|
||||
|
||||
export const schemaAndOr = schema.oneOf([schema.literal('AND'), schema.literal('OR')]);
|
||||
|
||||
// its recommended to create a subset of this schema for stricter validation
|
||||
export const searchOptionsSchemas = {
|
||||
page: schema.maybe(schema.number()),
|
||||
perPage: schema.maybe(schema.number()),
|
||||
sortField: schema.maybe(schema.string()),
|
||||
sortOrder: schema.maybe(schema.oneOf([schema.literal('asc'), schema.literal('desc')])),
|
||||
fields: schema.maybe(schema.arrayOf(schema.string())),
|
||||
search: schema.maybe(schema.string()),
|
||||
searchFields: schema.maybe(schema.oneOf([schema.string(), schema.arrayOf(schema.string())])),
|
||||
rootSearchFields: schema.maybe(schema.arrayOf(schema.string())),
|
||||
|
||||
hasReference: schema.maybe(schema.oneOf([referenceSchema, schema.arrayOf(referenceSchema)])),
|
||||
hasReferenceOperator: schema.maybe(schemaAndOr),
|
||||
hasNoReference: schema.maybe(schema.oneOf([referenceSchema, schema.arrayOf(referenceSchema)])),
|
||||
hasNoReferenceOperator: schema.maybe(schemaAndOr),
|
||||
defaultSearchOperator: schema.maybe(schemaAndOr),
|
||||
namespaces: schema.maybe(schema.arrayOf(schema.string())),
|
||||
type: schema.maybe(schema.string()),
|
||||
|
||||
filter: schema.maybe(schema.string()),
|
||||
pit: schema.maybe(
|
||||
schema.object({ id: schema.string(), keepAlive: schema.maybe(schema.string()) })
|
||||
),
|
||||
};
|
||||
|
||||
// its recommended to create a subset of this schema for stricter validation
|
||||
export const updateOptionsSchema = {
|
||||
references: schema.maybe(referencesSchema),
|
||||
version: schema.maybe(schema.string()),
|
||||
refresh: schema.maybe(schema.oneOf([schema.boolean(), schema.literal('wait_for')])),
|
||||
upsert: (attributesSchema: ObjectType<any>) => schema.maybe(savedObjectSchema(attributesSchema)),
|
||||
retryOnConflict: schema.maybe(schema.number()),
|
||||
};
|
||||
|
||||
export const createResultSchema = (soSchema: ObjectType<any>) =>
|
||||
schema.object(
|
||||
{
|
||||
item: soSchema,
|
||||
},
|
||||
{ unknowns: 'forbid' }
|
||||
);
|
|
@ -17,6 +17,7 @@
|
|||
],
|
||||
"kbn_references": [
|
||||
"@kbn/content-management-plugin",
|
||||
"@kbn/config-schema",
|
||||
"@kbn/core-saved-objects-api-server",
|
||||
]
|
||||
}
|
||||
|
|
|
@ -6,24 +6,12 @@
|
|||
*/
|
||||
import { schema } from '@kbn/config-schema';
|
||||
import type { ContentManagementServicesDefinition as ServicesDefinition } from '@kbn/object-versioning';
|
||||
|
||||
const apiError = schema.object({
|
||||
error: schema.string(),
|
||||
message: schema.string(),
|
||||
statusCode: schema.number(),
|
||||
metadata: schema.object({}, { unknowns: 'allow' }),
|
||||
});
|
||||
|
||||
const referenceSchema = schema.object(
|
||||
{
|
||||
name: schema.maybe(schema.string()),
|
||||
type: schema.string(),
|
||||
id: schema.string(),
|
||||
},
|
||||
{ unknowns: 'forbid' }
|
||||
);
|
||||
|
||||
const referencesSchema = schema.arrayOf(referenceSchema);
|
||||
import {
|
||||
savedObjectSchema,
|
||||
objectTypeToGetResultSchema,
|
||||
createOptionsSchemas,
|
||||
createResultSchema,
|
||||
} from '@kbn/content-management-utils';
|
||||
|
||||
const mapAttributesSchema = schema.object(
|
||||
{
|
||||
|
@ -36,48 +24,19 @@ const mapAttributesSchema = schema.object(
|
|||
{ unknowns: 'forbid' }
|
||||
);
|
||||
|
||||
const mapSavedObjectSchema = schema.object(
|
||||
{
|
||||
id: schema.string(),
|
||||
type: schema.string(),
|
||||
version: schema.maybe(schema.string()),
|
||||
createdAt: schema.maybe(schema.string()),
|
||||
updatedAt: schema.maybe(schema.string()),
|
||||
error: schema.maybe(apiError),
|
||||
attributes: mapAttributesSchema,
|
||||
references: referencesSchema,
|
||||
namespaces: schema.maybe(schema.arrayOf(schema.string())),
|
||||
originId: schema.maybe(schema.string()),
|
||||
},
|
||||
{ unknowns: 'allow' }
|
||||
);
|
||||
const mapSavedObjectSchema = savedObjectSchema(mapAttributesSchema);
|
||||
|
||||
const getResultSchema = schema.object(
|
||||
{
|
||||
item: mapSavedObjectSchema,
|
||||
meta: schema.object(
|
||||
{
|
||||
outcome: schema.oneOf([
|
||||
schema.literal('exactMatch'),
|
||||
schema.literal('aliasMatch'),
|
||||
schema.literal('conflict'),
|
||||
]),
|
||||
aliasTargetId: schema.maybe(schema.string()),
|
||||
aliasPurpose: schema.maybe(
|
||||
schema.oneOf([
|
||||
schema.literal('savedObjectConversion'),
|
||||
schema.literal('savedObjectImport'),
|
||||
])
|
||||
),
|
||||
},
|
||||
{ unknowns: 'forbid' }
|
||||
),
|
||||
},
|
||||
{ unknowns: 'forbid' }
|
||||
const searchOptionsSchema = schema.maybe(
|
||||
schema.object(
|
||||
{
|
||||
onlyTitle: schema.maybe(schema.boolean()),
|
||||
},
|
||||
{ unknowns: 'forbid' }
|
||||
)
|
||||
);
|
||||
|
||||
const createOptionsSchema = schema.object({
|
||||
references: schema.maybe(referencesSchema),
|
||||
references: schema.maybe(createOptionsSchemas.references),
|
||||
});
|
||||
|
||||
// Content management service definition.
|
||||
|
@ -86,7 +45,7 @@ export const serviceDefinition: ServicesDefinition = {
|
|||
get: {
|
||||
out: {
|
||||
result: {
|
||||
schema: getResultSchema,
|
||||
schema: objectTypeToGetResultSchema(mapSavedObjectSchema),
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -101,12 +60,7 @@ export const serviceDefinition: ServicesDefinition = {
|
|||
},
|
||||
out: {
|
||||
result: {
|
||||
schema: schema.object(
|
||||
{
|
||||
item: mapSavedObjectSchema,
|
||||
},
|
||||
{ unknowns: 'forbid' }
|
||||
),
|
||||
schema: createResultSchema(mapSavedObjectSchema),
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -123,14 +77,7 @@ export const serviceDefinition: ServicesDefinition = {
|
|||
search: {
|
||||
in: {
|
||||
options: {
|
||||
schema: schema.maybe(
|
||||
schema.object(
|
||||
{
|
||||
onlyTitle: schema.maybe(schema.boolean()),
|
||||
},
|
||||
{ unknowns: 'forbid' }
|
||||
)
|
||||
),
|
||||
schema: searchOptionsSchema,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue