mirror of
https://github.com/Unleash/unleash.git
synced 2025-06-09 01:17:06 +02:00
docs: add descriptions and examples to tag schemas (#4194)
## About the changes - Adding descriptions and examples to tag and tag types schemas - Adding standard errors, summaries, and descriptions to tag and tag types endpoints - Some improvements on compilation errors --------- Co-authored-by: Thomas Heartman <thomas@getunleash.ai>
This commit is contained in:
parent
5c4f15ea5d
commit
58151d8d80
@ -117,17 +117,12 @@ const metaRules: Rule[] = [
|
|||||||
'splashSchema',
|
'splashSchema',
|
||||||
'stateSchema',
|
'stateSchema',
|
||||||
'strategiesSchema',
|
'strategiesSchema',
|
||||||
'tagTypeSchema',
|
|
||||||
'tagTypesSchema',
|
|
||||||
'tagWithVersionSchema',
|
|
||||||
'uiConfigSchema',
|
'uiConfigSchema',
|
||||||
'updateFeatureSchema',
|
'updateFeatureSchema',
|
||||||
'updateTagTypeSchema',
|
|
||||||
'upsertContextFieldSchema',
|
'upsertContextFieldSchema',
|
||||||
'upsertStrategySchema',
|
'upsertStrategySchema',
|
||||||
'usersGroupsBaseSchema',
|
'usersGroupsBaseSchema',
|
||||||
'validateEdgeTokensSchema',
|
'validateEdgeTokensSchema',
|
||||||
'validateTagTypeSchema',
|
|
||||||
'variantFlagSchema',
|
'variantFlagSchema',
|
||||||
'versionSchema',
|
'versionSchema',
|
||||||
'projectOverviewSchema',
|
'projectOverviewSchema',
|
||||||
@ -173,18 +168,13 @@ const metaRules: Rule[] = [
|
|||||||
'sortOrderSchema',
|
'sortOrderSchema',
|
||||||
'splashSchema',
|
'splashSchema',
|
||||||
'strategiesSchema',
|
'strategiesSchema',
|
||||||
'tagTypeSchema',
|
|
||||||
'tagTypesSchema',
|
|
||||||
'tagWithVersionSchema',
|
|
||||||
'uiConfigSchema',
|
'uiConfigSchema',
|
||||||
'updateFeatureSchema',
|
'updateFeatureSchema',
|
||||||
'updateTagTypeSchema',
|
|
||||||
'upsertContextFieldSchema',
|
'upsertContextFieldSchema',
|
||||||
'upsertStrategySchema',
|
'upsertStrategySchema',
|
||||||
'usersGroupsBaseSchema',
|
'usersGroupsBaseSchema',
|
||||||
'usersSearchSchema',
|
'usersSearchSchema',
|
||||||
'validateEdgeTokensSchema',
|
'validateEdgeTokensSchema',
|
||||||
'validateTagTypeSchema',
|
|
||||||
'variantFlagSchema',
|
'variantFlagSchema',
|
||||||
'variantsSchema',
|
'variantsSchema',
|
||||||
'versionSchema',
|
'versionSchema',
|
||||||
|
@ -4,17 +4,24 @@ export const tagTypeSchema = {
|
|||||||
$id: '#/components/schemas/tagTypeSchema',
|
$id: '#/components/schemas/tagTypeSchema',
|
||||||
type: 'object',
|
type: 'object',
|
||||||
additionalProperties: false,
|
additionalProperties: false,
|
||||||
|
description: 'A tag type.',
|
||||||
required: ['name'],
|
required: ['name'],
|
||||||
properties: {
|
properties: {
|
||||||
name: {
|
name: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
|
description: 'The name of the tag type.',
|
||||||
|
example: 'color',
|
||||||
},
|
},
|
||||||
description: {
|
description: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
|
description: 'The description of the tag type.',
|
||||||
|
example: 'A tag type for describing the color of a tag.',
|
||||||
},
|
},
|
||||||
icon: {
|
icon: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
nullable: true,
|
nullable: true,
|
||||||
|
description: 'The icon of the tag type.',
|
||||||
|
example: 'not-really-used',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
components: {},
|
components: {},
|
||||||
|
@ -6,12 +6,18 @@ export const tagTypesSchema = {
|
|||||||
type: 'object',
|
type: 'object',
|
||||||
additionalProperties: false,
|
additionalProperties: false,
|
||||||
required: ['version', 'tagTypes'],
|
required: ['version', 'tagTypes'],
|
||||||
|
description:
|
||||||
|
'A list of tag types with a version number representing the schema used to model the tag types.',
|
||||||
properties: {
|
properties: {
|
||||||
version: {
|
version: {
|
||||||
type: 'integer',
|
type: 'integer',
|
||||||
|
description:
|
||||||
|
'The version of the schema used to model the tag types.',
|
||||||
|
example: 1,
|
||||||
},
|
},
|
||||||
tagTypes: {
|
tagTypes: {
|
||||||
type: 'array',
|
type: 'array',
|
||||||
|
description: 'The list of tag types.',
|
||||||
items: {
|
items: {
|
||||||
$ref: '#/components/schemas/tagTypeSchema',
|
$ref: '#/components/schemas/tagTypeSchema',
|
||||||
},
|
},
|
||||||
|
@ -6,9 +6,13 @@ export const tagWithVersionSchema = {
|
|||||||
type: 'object',
|
type: 'object',
|
||||||
additionalProperties: false,
|
additionalProperties: false,
|
||||||
required: ['version', 'tag'],
|
required: ['version', 'tag'],
|
||||||
|
description:
|
||||||
|
'A tag with a version number representing the schema used to model the tag.',
|
||||||
properties: {
|
properties: {
|
||||||
version: {
|
version: {
|
||||||
type: 'integer',
|
type: 'integer',
|
||||||
|
description: 'The version of the schema used to model the tag.',
|
||||||
|
example: 1,
|
||||||
},
|
},
|
||||||
tag: {
|
tag: {
|
||||||
$ref: '#/components/schemas/tagSchema',
|
$ref: '#/components/schemas/tagSchema',
|
||||||
|
@ -3,12 +3,17 @@ import { FromSchema } from 'json-schema-to-ts';
|
|||||||
export const updateTagTypeSchema = {
|
export const updateTagTypeSchema = {
|
||||||
$id: '#/components/schemas/updateTagTypeSchema',
|
$id: '#/components/schemas/updateTagTypeSchema',
|
||||||
type: 'object',
|
type: 'object',
|
||||||
|
description: 'The request body for updating a tag type.',
|
||||||
properties: {
|
properties: {
|
||||||
description: {
|
description: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
|
description: 'The description of the tag type.',
|
||||||
|
example: 'A tag type for describing the color of a tag.',
|
||||||
},
|
},
|
||||||
icon: {
|
icon: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
|
description: 'The icon of the tag type.',
|
||||||
|
example: 'not-really-used',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
components: {},
|
components: {},
|
||||||
|
@ -5,9 +5,12 @@ export const validateTagTypeSchema = {
|
|||||||
$id: '#/components/schemas/validateTagTypeSchema',
|
$id: '#/components/schemas/validateTagTypeSchema',
|
||||||
type: 'object',
|
type: 'object',
|
||||||
required: ['valid', 'tagType'],
|
required: ['valid', 'tagType'],
|
||||||
|
description: 'The result of validating a tag type.',
|
||||||
properties: {
|
properties: {
|
||||||
valid: {
|
valid: {
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
|
description: 'Whether or not the tag type is valid.',
|
||||||
|
example: true,
|
||||||
},
|
},
|
||||||
tagType: {
|
tagType: {
|
||||||
$ref: '#/components/schemas/tagTypeSchema',
|
$ref: '#/components/schemas/tagTypeSchema',
|
||||||
|
@ -25,7 +25,10 @@ import {
|
|||||||
} from '../../openapi/spec/tag-type-schema';
|
} from '../../openapi/spec/tag-type-schema';
|
||||||
import { UpdateTagTypeSchema } from '../../openapi/spec/update-tag-type-schema';
|
import { UpdateTagTypeSchema } from '../../openapi/spec/update-tag-type-schema';
|
||||||
import { OpenApiService } from '../../services/openapi-service';
|
import { OpenApiService } from '../../services/openapi-service';
|
||||||
import { emptyResponse } from '../../openapi/util/standard-responses';
|
import {
|
||||||
|
emptyResponse,
|
||||||
|
getStandardResponses,
|
||||||
|
} from '../../openapi/util/standard-responses';
|
||||||
|
|
||||||
const version = 1;
|
const version = 1;
|
||||||
|
|
||||||
@ -56,7 +59,12 @@ class TagTypeController extends Controller {
|
|||||||
openApiService.validPath({
|
openApiService.validPath({
|
||||||
tags: ['Tags'],
|
tags: ['Tags'],
|
||||||
operationId: 'getTagTypes',
|
operationId: 'getTagTypes',
|
||||||
responses: { 200: createResponseSchema('tagTypesSchema') },
|
summary: 'Get all tag types',
|
||||||
|
description: 'Get a list of all available tag types.',
|
||||||
|
responses: {
|
||||||
|
200: createResponseSchema('tagTypesSchema'),
|
||||||
|
...getStandardResponses(401, 403),
|
||||||
|
},
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
@ -69,8 +77,11 @@ class TagTypeController extends Controller {
|
|||||||
openApiService.validPath({
|
openApiService.validPath({
|
||||||
tags: ['Tags'],
|
tags: ['Tags'],
|
||||||
operationId: 'createTagType',
|
operationId: 'createTagType',
|
||||||
|
summary: 'Create a tag type',
|
||||||
|
description: 'Create a new tag type.',
|
||||||
responses: {
|
responses: {
|
||||||
201: resourceCreatedResponseSchema('tagTypeSchema'),
|
201: resourceCreatedResponseSchema('tagTypeSchema'),
|
||||||
|
...getStandardResponses(400, 401, 403, 409, 415),
|
||||||
},
|
},
|
||||||
requestBody: createRequestSchema('tagTypeSchema'),
|
requestBody: createRequestSchema('tagTypeSchema'),
|
||||||
}),
|
}),
|
||||||
@ -85,8 +96,12 @@ class TagTypeController extends Controller {
|
|||||||
openApiService.validPath({
|
openApiService.validPath({
|
||||||
tags: ['Tags'],
|
tags: ['Tags'],
|
||||||
operationId: 'validateTagType',
|
operationId: 'validateTagType',
|
||||||
|
summary: 'Validate a tag type',
|
||||||
|
description:
|
||||||
|
'Validates whether if the body of the request is a valid tag and whether the a tag type with that name already exists or not. If a tag type with the same name exists, this operation will return a 409 status code.',
|
||||||
responses: {
|
responses: {
|
||||||
200: createResponseSchema('validateTagTypeSchema'),
|
200: createResponseSchema('validateTagTypeSchema'),
|
||||||
|
...getStandardResponses(400, 401, 403, 409, 415),
|
||||||
},
|
},
|
||||||
requestBody: createRequestSchema('tagTypeSchema'),
|
requestBody: createRequestSchema('tagTypeSchema'),
|
||||||
}),
|
}),
|
||||||
@ -101,8 +116,11 @@ class TagTypeController extends Controller {
|
|||||||
openApiService.validPath({
|
openApiService.validPath({
|
||||||
tags: ['Tags'],
|
tags: ['Tags'],
|
||||||
operationId: 'getTagType',
|
operationId: 'getTagType',
|
||||||
|
summary: 'Get a tag type',
|
||||||
|
description: 'Get a tag type by name.',
|
||||||
responses: {
|
responses: {
|
||||||
200: createResponseSchema('tagTypeSchema'),
|
200: createResponseSchema('tagTypeSchema'),
|
||||||
|
...getStandardResponses(401, 403),
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
@ -116,8 +134,12 @@ class TagTypeController extends Controller {
|
|||||||
openApiService.validPath({
|
openApiService.validPath({
|
||||||
tags: ['Tags'],
|
tags: ['Tags'],
|
||||||
operationId: 'updateTagType',
|
operationId: 'updateTagType',
|
||||||
|
summary: 'Update a tag type',
|
||||||
|
description:
|
||||||
|
'Update the configuration for the specified tag type.',
|
||||||
responses: {
|
responses: {
|
||||||
200: emptyResponse,
|
200: emptyResponse,
|
||||||
|
...getStandardResponses(400, 401, 403, 415),
|
||||||
},
|
},
|
||||||
requestBody: createRequestSchema('updateTagTypeSchema'),
|
requestBody: createRequestSchema('updateTagTypeSchema'),
|
||||||
}),
|
}),
|
||||||
@ -133,8 +155,12 @@ class TagTypeController extends Controller {
|
|||||||
openApiService.validPath({
|
openApiService.validPath({
|
||||||
tags: ['Tags'],
|
tags: ['Tags'],
|
||||||
operationId: 'deleteTagType',
|
operationId: 'deleteTagType',
|
||||||
|
summary: 'Delete a tag type',
|
||||||
|
description:
|
||||||
|
'Deletes a tag type. If any features have tags of this type, those tags will be deleted.',
|
||||||
responses: {
|
responses: {
|
||||||
200: emptyResponse,
|
200: emptyResponse,
|
||||||
|
...getStandardResponses(401, 403),
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
|
@ -21,7 +21,10 @@ import {
|
|||||||
tagWithVersionSchema,
|
tagWithVersionSchema,
|
||||||
TagWithVersionSchema,
|
TagWithVersionSchema,
|
||||||
} from '../../openapi/spec/tag-with-version-schema';
|
} from '../../openapi/spec/tag-with-version-schema';
|
||||||
import { emptyResponse } from '../../openapi/util/standard-responses';
|
import {
|
||||||
|
emptyResponse,
|
||||||
|
getStandardResponses,
|
||||||
|
} from '../../openapi/util/standard-responses';
|
||||||
import FeatureTagService from 'lib/services/feature-tag-service';
|
import FeatureTagService from 'lib/services/feature-tag-service';
|
||||||
import { IFlagResolver } from '../../types';
|
import { IFlagResolver } from '../../types';
|
||||||
|
|
||||||
@ -65,7 +68,12 @@ class TagController extends Controller {
|
|||||||
openApiService.validPath({
|
openApiService.validPath({
|
||||||
tags: ['Tags'],
|
tags: ['Tags'],
|
||||||
operationId: 'getTags',
|
operationId: 'getTags',
|
||||||
responses: { 200: createResponseSchema('tagsSchema') },
|
summary: 'List all tags.',
|
||||||
|
description: 'List all tags available in Unleash.',
|
||||||
|
responses: {
|
||||||
|
200: createResponseSchema('tagsSchema'),
|
||||||
|
...getStandardResponses(401, 403),
|
||||||
|
},
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
@ -78,10 +86,13 @@ class TagController extends Controller {
|
|||||||
openApiService.validPath({
|
openApiService.validPath({
|
||||||
tags: ['Tags'],
|
tags: ['Tags'],
|
||||||
operationId: 'createTag',
|
operationId: 'createTag',
|
||||||
|
summary: 'Create a new tag.',
|
||||||
|
description: 'Create a new tag with the specified data.',
|
||||||
responses: {
|
responses: {
|
||||||
201: resourceCreatedResponseSchema(
|
201: resourceCreatedResponseSchema(
|
||||||
'tagWithVersionSchema',
|
'tagWithVersionSchema',
|
||||||
),
|
),
|
||||||
|
...getStandardResponses(400, 401, 403, 409, 415),
|
||||||
},
|
},
|
||||||
requestBody: createRequestSchema('tagSchema'),
|
requestBody: createRequestSchema('tagSchema'),
|
||||||
}),
|
}),
|
||||||
@ -97,8 +108,12 @@ class TagController extends Controller {
|
|||||||
openApiService.validPath({
|
openApiService.validPath({
|
||||||
tags: ['Tags'],
|
tags: ['Tags'],
|
||||||
operationId: 'getTagsByType',
|
operationId: 'getTagsByType',
|
||||||
|
summary: 'List all tags of a given type.',
|
||||||
|
description:
|
||||||
|
'List all tags of a given type. If the tag type does not exist it returns an empty list.',
|
||||||
responses: {
|
responses: {
|
||||||
200: createResponseSchema('tagsSchema'),
|
200: createResponseSchema('tagsSchema'),
|
||||||
|
...getStandardResponses(401, 403),
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
@ -112,8 +127,12 @@ class TagController extends Controller {
|
|||||||
openApiService.validPath({
|
openApiService.validPath({
|
||||||
tags: ['Tags'],
|
tags: ['Tags'],
|
||||||
operationId: 'getTag',
|
operationId: 'getTag',
|
||||||
|
summary: 'Get a tag by type and value.',
|
||||||
|
description:
|
||||||
|
'Get a tag by type and value. Can be used to check whether a given tag already exists in Unleash or not.',
|
||||||
responses: {
|
responses: {
|
||||||
200: createResponseSchema('tagWithVersionSchema'),
|
200: createResponseSchema('tagWithVersionSchema'),
|
||||||
|
...getStandardResponses(401, 403, 404),
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
@ -128,6 +147,9 @@ class TagController extends Controller {
|
|||||||
openApiService.validPath({
|
openApiService.validPath({
|
||||||
tags: ['Tags'],
|
tags: ['Tags'],
|
||||||
operationId: 'deleteTag',
|
operationId: 'deleteTag',
|
||||||
|
summary: 'Delete a tag.',
|
||||||
|
description:
|
||||||
|
'Delete a tag by type and value. When a tag is deleted all references to the tag are removed.',
|
||||||
responses: {
|
responses: {
|
||||||
200: emptyResponse,
|
200: emptyResponse,
|
||||||
},
|
},
|
||||||
|
@ -170,7 +170,7 @@ export default class AddonService {
|
|||||||
const tagTypes = provider.definition.tagTypes || [];
|
const tagTypes = provider.definition.tagTypes || [];
|
||||||
const createTags = tagTypes.map(async (tagType) => {
|
const createTags = tagTypes.map(async (tagType) => {
|
||||||
try {
|
try {
|
||||||
await this.tagTypeService.validateUnique(tagType);
|
await this.tagTypeService.validateUnique(tagType.name);
|
||||||
await this.tagTypeService.createTagType(
|
await this.tagTypeService.createTagType(
|
||||||
tagType,
|
tagType,
|
||||||
providerName,
|
providerName,
|
||||||
|
@ -48,7 +48,7 @@ export default class TagTypeService {
|
|||||||
const data = (await tagTypeSchema.validateAsync(
|
const data = (await tagTypeSchema.validateAsync(
|
||||||
newTagType,
|
newTagType,
|
||||||
)) as ITagType;
|
)) as ITagType;
|
||||||
await this.validateUnique(data);
|
await this.validateUnique(data.name);
|
||||||
await this.tagTypeStore.createTagType(data);
|
await this.tagTypeStore.createTagType(data);
|
||||||
await this.eventStore.store({
|
await this.eventStore.store({
|
||||||
type: TAG_TYPE_CREATED,
|
type: TAG_TYPE_CREATED,
|
||||||
@ -58,7 +58,7 @@ export default class TagTypeService {
|
|||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
async validateUnique({ name }: Pick<ITagType, 'name'>): Promise<boolean> {
|
async validateUnique(name: string): Promise<boolean> {
|
||||||
const exists = await this.tagTypeStore.exists(name);
|
const exists = await this.tagTypeStore.exists(name);
|
||||||
if (exists) {
|
if (exists) {
|
||||||
throw new NameExistsError(
|
throw new NameExistsError(
|
||||||
@ -68,9 +68,11 @@ export default class TagTypeService {
|
|||||||
return Promise.resolve(true);
|
return Promise.resolve(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
async validate(tagType: ITagType): Promise<void> {
|
async validate(tagType: Partial<ITagType> | undefined): Promise<void> {
|
||||||
await tagTypeSchema.validateAsync(tagType);
|
await tagTypeSchema.validateAsync(tagType);
|
||||||
await this.validateUnique(tagType);
|
if (tagType && tagType.name) {
|
||||||
|
await this.validateUnique(tagType.name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async deleteTagType(name: string, userName: string): Promise<void> {
|
async deleteTagType(name: string, userName: string): Promise<void> {
|
||||||
|
Loading…
Reference in New Issue
Block a user