mirror of
https://github.com/Unleash/unleash.git
synced 2025-01-25 00:07:47 +01:00
refactor: add OpenAPI schema to UI config controller (#1681)
This commit is contained in:
parent
cbffe0eda0
commit
09a6b578bf
@ -18,10 +18,12 @@ import { patchesSchema } from './spec/patches-schema';
|
||||
import { strategySchema } from './spec/strategy-schema';
|
||||
import { tagSchema } from './spec/tag-schema';
|
||||
import { tagsSchema } from './spec/tags-schema';
|
||||
import { uiConfigSchema } from './spec/ui-config-schema';
|
||||
import { updateFeatureSchema } from './spec/update-feature-schema';
|
||||
import { updateStrategySchema } from './spec/update-strategy-schema';
|
||||
import { variantSchema } from './spec/variant-schema';
|
||||
import { variantsSchema } from './spec/variants-schema';
|
||||
import { versionSchema } from './spec/version-schema';
|
||||
|
||||
// Schemas must have $id property on the form "#/components/schemas/mySchema".
|
||||
export type SchemaId = typeof schemas[keyof typeof schemas]['$id'];
|
||||
@ -57,10 +59,12 @@ export const schemas = {
|
||||
strategySchema,
|
||||
tagSchema,
|
||||
tagsSchema,
|
||||
uiConfigSchema,
|
||||
updateFeatureSchema,
|
||||
updateStrategySchema,
|
||||
variantSchema,
|
||||
variantsSchema,
|
||||
versionSchema,
|
||||
};
|
||||
|
||||
export const createRequestSchema = (
|
||||
|
24
src/lib/openapi/spec/ui-config-schema.test.ts
Normal file
24
src/lib/openapi/spec/ui-config-schema.test.ts
Normal file
@ -0,0 +1,24 @@
|
||||
import { validateSchema } from '../validate';
|
||||
import { UiConfigSchema } from './ui-config-schema';
|
||||
|
||||
test('uiConfigSchema', () => {
|
||||
const data: UiConfigSchema = {
|
||||
slogan: 'a',
|
||||
version: 'a',
|
||||
unleashUrl: 'a',
|
||||
baseUriPath: 'a',
|
||||
disablePasswordAuth: false,
|
||||
segmentValuesLimit: 0,
|
||||
strategySegmentsLimit: 0,
|
||||
versionInfo: {
|
||||
current: {},
|
||||
latest: {},
|
||||
isLatest: true,
|
||||
instanceId: 'a',
|
||||
},
|
||||
};
|
||||
|
||||
expect(
|
||||
validateSchema('#/components/schemas/uiConfigSchema', data),
|
||||
).toBeUndefined();
|
||||
});
|
76
src/lib/openapi/spec/ui-config-schema.ts
Normal file
76
src/lib/openapi/spec/ui-config-schema.ts
Normal file
@ -0,0 +1,76 @@
|
||||
import { FromSchema } from 'json-schema-to-ts';
|
||||
import { versionSchema } from './version-schema';
|
||||
|
||||
export const uiConfigSchema = {
|
||||
$id: '#/components/schemas/uiConfigSchema',
|
||||
type: 'object',
|
||||
additionalProperties: false,
|
||||
required: [
|
||||
'version',
|
||||
'unleashUrl',
|
||||
'baseUriPath',
|
||||
'versionInfo',
|
||||
'disablePasswordAuth',
|
||||
'segmentValuesLimit',
|
||||
'strategySegmentsLimit',
|
||||
],
|
||||
properties: {
|
||||
slogan: {
|
||||
type: 'string',
|
||||
},
|
||||
name: {
|
||||
type: 'string',
|
||||
},
|
||||
version: {
|
||||
type: 'string',
|
||||
},
|
||||
unleashUrl: {
|
||||
type: 'string',
|
||||
},
|
||||
baseUriPath: {
|
||||
type: 'string',
|
||||
},
|
||||
disablePasswordAuth: {
|
||||
type: 'boolean',
|
||||
},
|
||||
segmentValuesLimit: {
|
||||
type: 'number',
|
||||
},
|
||||
strategySegmentsLimit: {
|
||||
type: 'number',
|
||||
},
|
||||
flags: {
|
||||
type: 'object',
|
||||
additionalProperties: {
|
||||
type: 'boolean',
|
||||
},
|
||||
},
|
||||
links: {
|
||||
type: 'array',
|
||||
items: {
|
||||
type: 'object',
|
||||
},
|
||||
},
|
||||
authenticationType: {
|
||||
type: 'string',
|
||||
enum: [
|
||||
'open-source',
|
||||
'demo',
|
||||
'enterprise',
|
||||
'hosted',
|
||||
'custom',
|
||||
'none',
|
||||
],
|
||||
},
|
||||
versionInfo: {
|
||||
$ref: '#/components/schemas/versionSchema',
|
||||
},
|
||||
},
|
||||
components: {
|
||||
schemas: {
|
||||
versionSchema,
|
||||
},
|
||||
},
|
||||
} as const;
|
||||
|
||||
export type UiConfigSchema = FromSchema<typeof uiConfigSchema>;
|
43
src/lib/openapi/spec/version-schema.ts
Normal file
43
src/lib/openapi/spec/version-schema.ts
Normal file
@ -0,0 +1,43 @@
|
||||
import { FromSchema } from 'json-schema-to-ts';
|
||||
|
||||
export const versionSchema = {
|
||||
$id: '#/components/schemas/versionSchema',
|
||||
type: 'object',
|
||||
additionalProperties: false,
|
||||
required: ['current', 'latest', 'isLatest', 'instanceId'],
|
||||
properties: {
|
||||
current: {
|
||||
type: 'object',
|
||||
additionalProperties: false,
|
||||
properties: {
|
||||
oss: {
|
||||
type: 'string',
|
||||
},
|
||||
enterprise: {
|
||||
type: 'string',
|
||||
},
|
||||
},
|
||||
},
|
||||
latest: {
|
||||
type: 'object',
|
||||
additionalProperties: false,
|
||||
properties: {
|
||||
oss: {
|
||||
type: 'string',
|
||||
},
|
||||
enterprise: {
|
||||
type: 'string',
|
||||
},
|
||||
},
|
||||
},
|
||||
isLatest: {
|
||||
type: 'boolean',
|
||||
},
|
||||
instanceId: {
|
||||
type: 'string',
|
||||
},
|
||||
},
|
||||
components: {},
|
||||
} as const;
|
||||
|
||||
export type VersionSchema = FromSchema<typeof versionSchema>;
|
@ -1,73 +1,91 @@
|
||||
import { Request, Response } from 'express';
|
||||
import { IUnleashServices } from '../../types/services';
|
||||
import { IAuthType, IUIConfig, IUnleashConfig } from '../../types/option';
|
||||
import { IAuthType, IUnleashConfig } from '../../types/option';
|
||||
import version from '../../util/version';
|
||||
import Controller from '../controller';
|
||||
import VersionService, { IVersionHolder } from '../../services/version-service';
|
||||
import VersionService from '../../services/version-service';
|
||||
import SettingService from '../../services/setting-service';
|
||||
import {
|
||||
simpleAuthKey,
|
||||
SimpleAuthSettings,
|
||||
} from '../../types/settings/simple-auth-settings';
|
||||
|
||||
interface IUIConfigResponse extends IUIConfig {
|
||||
version: string;
|
||||
unleashUrl: string;
|
||||
baseUriPath: string;
|
||||
authenticationType?: IAuthType;
|
||||
versionInfo: IVersionHolder;
|
||||
disablePasswordAuth: boolean;
|
||||
segmentValuesLimit: number;
|
||||
strategySegmentsLimit: number;
|
||||
}
|
||||
import { NONE } from '../../types/permissions';
|
||||
import { createResponseSchema } from '../../openapi';
|
||||
import {
|
||||
uiConfigSchema,
|
||||
UiConfigSchema,
|
||||
} from '../../openapi/spec/ui-config-schema';
|
||||
import { OpenApiService } from '../../services/openapi-service';
|
||||
|
||||
class ConfigController extends Controller {
|
||||
private versionService: VersionService;
|
||||
|
||||
private settingService: SettingService;
|
||||
|
||||
private uiConfig: Omit<
|
||||
IUIConfigResponse,
|
||||
'versionInfo' | 'disablePasswordAuth'
|
||||
>;
|
||||
private readonly openApiService: OpenApiService;
|
||||
|
||||
constructor(
|
||||
config: IUnleashConfig,
|
||||
{
|
||||
versionService,
|
||||
settingService,
|
||||
}: Pick<IUnleashServices, 'versionService' | 'settingService'>,
|
||||
openApiService,
|
||||
}: Pick<
|
||||
IUnleashServices,
|
||||
'versionService' | 'settingService' | 'openApiService'
|
||||
>,
|
||||
) {
|
||||
super(config);
|
||||
this.versionService = versionService;
|
||||
this.settingService = settingService;
|
||||
const authenticationType =
|
||||
config.authentication && config.authentication.type;
|
||||
this.uiConfig = {
|
||||
...config.ui,
|
||||
version,
|
||||
unleashUrl: config.server.unleashUrl,
|
||||
baseUriPath: config.server.baseUriPath,
|
||||
authenticationType,
|
||||
segmentValuesLimit: config.segmentValuesLimit,
|
||||
strategySegmentsLimit: config.strategySegmentsLimit,
|
||||
};
|
||||
this.get('/', this.getUIConfig);
|
||||
this.openApiService = openApiService;
|
||||
|
||||
this.route({
|
||||
method: 'get',
|
||||
path: '',
|
||||
handler: this.getUIConfig,
|
||||
permission: NONE,
|
||||
middleware: [
|
||||
openApiService.validPath({
|
||||
tags: ['admin'],
|
||||
operationId: 'getUIConfig',
|
||||
responses: {
|
||||
200: createResponseSchema('uiConfigSchema'),
|
||||
},
|
||||
}),
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
async getUIConfig(
|
||||
req: Request,
|
||||
res: Response<IUIConfigResponse>,
|
||||
res: Response<UiConfigSchema>,
|
||||
): Promise<void> {
|
||||
const config = this.uiConfig;
|
||||
const simpleAuthSettings =
|
||||
await this.settingService.get<SimpleAuthSettings>(simpleAuthKey);
|
||||
|
||||
const versionInfo = this.versionService.getVersionInfo();
|
||||
const disablePasswordAuth =
|
||||
simpleAuthSettings?.disabled ||
|
||||
this.config.authentication.type == IAuthType.NONE;
|
||||
res.json({ ...config, versionInfo, disablePasswordAuth });
|
||||
|
||||
const response: UiConfigSchema = {
|
||||
...this.config.ui,
|
||||
version,
|
||||
unleashUrl: this.config.server.unleashUrl,
|
||||
baseUriPath: this.config.server.baseUriPath,
|
||||
authenticationType: this.config.authentication?.type,
|
||||
segmentValuesLimit: this.config.segmentValuesLimit,
|
||||
strategySegmentsLimit: this.config.strategySegmentsLimit,
|
||||
versionInfo: this.versionService.getVersionInfo(),
|
||||
disablePasswordAuth,
|
||||
};
|
||||
|
||||
this.openApiService.respondWithValidation(
|
||||
200,
|
||||
res,
|
||||
uiConfigSchema.$id,
|
||||
response,
|
||||
);
|
||||
}
|
||||
}
|
||||
export default ConfigController;
|
||||
|
@ -147,6 +147,7 @@ export interface IUIConfig {
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
export interface ICspDomainOptions {
|
||||
defaultSrc?: string[];
|
||||
fontSrc?: string[];
|
||||
|
@ -455,6 +455,71 @@ Object {
|
||||
],
|
||||
"type": "object",
|
||||
},
|
||||
"uiConfigSchema": Object {
|
||||
"additionalProperties": false,
|
||||
"properties": Object {
|
||||
"authenticationType": Object {
|
||||
"enum": Array [
|
||||
"open-source",
|
||||
"demo",
|
||||
"enterprise",
|
||||
"hosted",
|
||||
"custom",
|
||||
"none",
|
||||
],
|
||||
"type": "string",
|
||||
},
|
||||
"baseUriPath": Object {
|
||||
"type": "string",
|
||||
},
|
||||
"disablePasswordAuth": Object {
|
||||
"type": "boolean",
|
||||
},
|
||||
"flags": Object {
|
||||
"additionalProperties": Object {
|
||||
"type": "boolean",
|
||||
},
|
||||
"type": "object",
|
||||
},
|
||||
"links": Object {
|
||||
"items": Object {
|
||||
"type": "object",
|
||||
},
|
||||
"type": "array",
|
||||
},
|
||||
"name": Object {
|
||||
"type": "string",
|
||||
},
|
||||
"segmentValuesLimit": Object {
|
||||
"type": "number",
|
||||
},
|
||||
"slogan": Object {
|
||||
"type": "string",
|
||||
},
|
||||
"strategySegmentsLimit": Object {
|
||||
"type": "number",
|
||||
},
|
||||
"unleashUrl": Object {
|
||||
"type": "string",
|
||||
},
|
||||
"version": Object {
|
||||
"type": "string",
|
||||
},
|
||||
"versionInfo": Object {
|
||||
"$ref": "#/components/schemas/versionSchema",
|
||||
},
|
||||
},
|
||||
"required": Array [
|
||||
"version",
|
||||
"unleashUrl",
|
||||
"baseUriPath",
|
||||
"versionInfo",
|
||||
"disablePasswordAuth",
|
||||
"segmentValuesLimit",
|
||||
"strategySegmentsLimit",
|
||||
],
|
||||
"type": "object",
|
||||
},
|
||||
"updateFeatureSchema": Object {
|
||||
"properties": Object {
|
||||
"archived": Object {
|
||||
@ -567,6 +632,48 @@ Object {
|
||||
},
|
||||
"type": "array",
|
||||
},
|
||||
"versionSchema": Object {
|
||||
"additionalProperties": false,
|
||||
"properties": Object {
|
||||
"current": Object {
|
||||
"additionalProperties": false,
|
||||
"properties": Object {
|
||||
"enterprise": Object {
|
||||
"type": "string",
|
||||
},
|
||||
"oss": Object {
|
||||
"type": "string",
|
||||
},
|
||||
},
|
||||
"type": "object",
|
||||
},
|
||||
"instanceId": Object {
|
||||
"type": "string",
|
||||
},
|
||||
"isLatest": Object {
|
||||
"type": "boolean",
|
||||
},
|
||||
"latest": Object {
|
||||
"additionalProperties": false,
|
||||
"properties": Object {
|
||||
"enterprise": Object {
|
||||
"type": "string",
|
||||
},
|
||||
"oss": Object {
|
||||
"type": "string",
|
||||
},
|
||||
},
|
||||
"type": "object",
|
||||
},
|
||||
},
|
||||
"required": Array [
|
||||
"current",
|
||||
"latest",
|
||||
"isLatest",
|
||||
"instanceId",
|
||||
],
|
||||
"type": "object",
|
||||
},
|
||||
},
|
||||
"securitySchemes": Object {
|
||||
"apiKey": Object {
|
||||
@ -1676,6 +1783,26 @@ Object {
|
||||
],
|
||||
},
|
||||
},
|
||||
"/api/admin/ui-config": Object {
|
||||
"get": Object {
|
||||
"operationId": "getUIConfig",
|
||||
"responses": Object {
|
||||
"200": Object {
|
||||
"content": Object {
|
||||
"application/json": Object {
|
||||
"schema": Object {
|
||||
"$ref": "#/components/schemas/uiConfigSchema",
|
||||
},
|
||||
},
|
||||
},
|
||||
"description": "uiConfigSchema",
|
||||
},
|
||||
},
|
||||
"tags": Array [
|
||||
"admin",
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
"security": Array [
|
||||
Object {
|
||||
|
Loading…
Reference in New Issue
Block a user