From b92a02a907e1b6e95417615badc600d27a8806e1 Mon Sep 17 00:00:00 2001 From: Ferdi Koomen Date: Sat, 23 Nov 2019 13:47:27 +0100 Subject: [PATCH] - v3 generator --- src/client/interfaces/OperationParameter.d.ts | 2 +- src/openApi/v3/parser/constants.ts | 44 + src/openApi/v3/parser/getComment.ts | 13 + src/openApi/v3/parser/getEnum.ts | 26 + .../v3/parser/getEnumFromDescription.ts | 32 + src/openApi/v3/parser/getEnumType.ts | 18 + src/openApi/v3/parser/getEnumValues.ts | 13 + src/openApi/v3/parser/getMappedType.spec.ts | 21 + src/openApi/v3/parser/getMappedType.ts | 16 + src/openApi/v3/parser/getModel.ts | 159 + src/openApi/v3/parser/getModelProperties.ts | 60 + .../v3/parser/getModelTemplate.spec.ts | 23 + src/openApi/v3/parser/getModelTemplate.ts | 11 + src/openApi/v3/parser/getModels.ts | 20 +- src/openApi/v3/parser/getOperation.ts | 65 + src/openApi/v3/parser/getOperationErrors.ts | 13 + .../v3/parser/getOperationName.spec.ts | 10 + src/openApi/v3/parser/getOperationName.ts | 11 + .../v3/parser/getOperationParameter.ts | 59 + .../v3/parser/getOperationParameterDefault.ts | 15 + .../v3/parser/getOperationParameterName.ts | 10 + .../v3/parser/getOperationParameters.ts | 59 + .../v3/parser/getOperationPath.spec.ts | 10 + src/openApi/v3/parser/getOperationPath.ts | 9 + .../v3/parser/getOperationResponseCode.ts | 16 + .../v3/parser/getOperationResponses.ts | 86 + src/openApi/v3/parser/getOperationResults.ts | 51 + src/openApi/v3/parser/getRef.ts | 26 + .../v3/parser/getServiceClassName.spec.ts | 13 + src/openApi/v3/parser/getServiceClassName.ts | 14 + src/openApi/v3/parser/getServices.ts | 42 +- src/openApi/v3/parser/getType.spec.ts | 59 + src/openApi/v3/parser/getType.ts | 59 + src/openApi/v3/parser/isPrimaryType.spec.ts | 14 + src/openApi/v3/parser/isPrimaryType.ts | 19 + .../partials/validationInterface.hbs | 2 +- test/index.js | 25 +- test/mock/spec-v3.json | 4714 +++++++++-------- 38 files changed, 3749 insertions(+), 2110 deletions(-) create mode 100644 src/openApi/v3/parser/constants.ts create mode 100644 src/openApi/v3/parser/getComment.ts create mode 100644 src/openApi/v3/parser/getEnum.ts create mode 100644 src/openApi/v3/parser/getEnumFromDescription.ts create mode 100644 src/openApi/v3/parser/getEnumType.ts create mode 100644 src/openApi/v3/parser/getEnumValues.ts create mode 100644 src/openApi/v3/parser/getMappedType.spec.ts create mode 100644 src/openApi/v3/parser/getMappedType.ts create mode 100644 src/openApi/v3/parser/getModel.ts create mode 100644 src/openApi/v3/parser/getModelProperties.ts create mode 100644 src/openApi/v3/parser/getModelTemplate.spec.ts create mode 100644 src/openApi/v3/parser/getModelTemplate.ts create mode 100644 src/openApi/v3/parser/getOperation.ts create mode 100644 src/openApi/v3/parser/getOperationErrors.ts create mode 100644 src/openApi/v3/parser/getOperationName.spec.ts create mode 100644 src/openApi/v3/parser/getOperationName.ts create mode 100644 src/openApi/v3/parser/getOperationParameter.ts create mode 100644 src/openApi/v3/parser/getOperationParameterDefault.ts create mode 100644 src/openApi/v3/parser/getOperationParameterName.ts create mode 100644 src/openApi/v3/parser/getOperationParameters.ts create mode 100644 src/openApi/v3/parser/getOperationPath.spec.ts create mode 100644 src/openApi/v3/parser/getOperationPath.ts create mode 100644 src/openApi/v3/parser/getOperationResponseCode.ts create mode 100644 src/openApi/v3/parser/getOperationResponses.ts create mode 100644 src/openApi/v3/parser/getOperationResults.ts create mode 100644 src/openApi/v3/parser/getRef.ts create mode 100644 src/openApi/v3/parser/getServiceClassName.spec.ts create mode 100644 src/openApi/v3/parser/getServiceClassName.ts create mode 100644 src/openApi/v3/parser/getType.spec.ts create mode 100644 src/openApi/v3/parser/getType.ts create mode 100644 src/openApi/v3/parser/isPrimaryType.spec.ts create mode 100644 src/openApi/v3/parser/isPrimaryType.ts diff --git a/src/client/interfaces/OperationParameter.d.ts b/src/client/interfaces/OperationParameter.d.ts index 84290321..9d31776e 100644 --- a/src/client/interfaces/OperationParameter.d.ts +++ b/src/client/interfaces/OperationParameter.d.ts @@ -1,7 +1,7 @@ import { Model } from './Model'; export interface OperationParameter extends Model { - in: 'path' | 'query' | 'header' | 'formData' | 'body'; + in: 'path' | 'query' | 'header' | 'formData' | 'body' | 'cookie'; prop: string; default?: any; } diff --git a/src/openApi/v3/parser/constants.ts b/src/openApi/v3/parser/constants.ts new file mode 100644 index 00000000..04041dd7 --- /dev/null +++ b/src/openApi/v3/parser/constants.ts @@ -0,0 +1,44 @@ +export enum PrimaryType { + FILE = 'File', + OBJECT = 'any', + BOOLEAN = 'boolean', + NUMBER = 'number', + STRING = 'string', + VOID = 'void', + NULL = 'null', +} + +export const TYPE_MAPPINGS = new Map([ + ['file', PrimaryType.FILE], + ['binary', PrimaryType.FILE], + ['any', PrimaryType.OBJECT], + ['object', PrimaryType.OBJECT], + ['boolean', PrimaryType.BOOLEAN], + ['byte', PrimaryType.NUMBER], + ['int', PrimaryType.NUMBER], + ['int32', PrimaryType.NUMBER], + ['int64', PrimaryType.NUMBER], + ['integer', PrimaryType.NUMBER], + ['float', PrimaryType.NUMBER], + ['double', PrimaryType.NUMBER], + ['short', PrimaryType.NUMBER], + ['long', PrimaryType.NUMBER], + ['number', PrimaryType.NUMBER], + ['char', PrimaryType.STRING], + ['date', PrimaryType.STRING], + ['date-time', PrimaryType.STRING], + ['password', PrimaryType.STRING], + ['string', PrimaryType.STRING], + ['void', PrimaryType.VOID], + ['null', PrimaryType.NULL], +]); + +export enum Method { + GET = 'get', + PUT = 'put', + POST = 'post', + DELETE = 'delete', + OPTIONS = 'options', + HEAD = 'head', + PATCH = 'patch', +} diff --git a/src/openApi/v3/parser/getComment.ts b/src/openApi/v3/parser/getComment.ts new file mode 100644 index 00000000..d9af7afa --- /dev/null +++ b/src/openApi/v3/parser/getComment.ts @@ -0,0 +1,13 @@ +import { EOL } from 'os'; + +export function getComment(comment?: string): string | null { + if (comment) { + return comment + .split(/(\r\n|\n|\r)+/g) + .filter(line => line) + .map(line => line.trim()) + .join(EOL) + .replace(/(\r\n|\n|\r)+/g, '$1 * '); + } + return null; +} diff --git a/src/openApi/v3/parser/getEnum.ts b/src/openApi/v3/parser/getEnum.ts new file mode 100644 index 00000000..094a552d --- /dev/null +++ b/src/openApi/v3/parser/getEnum.ts @@ -0,0 +1,26 @@ +import { Enum } from '../../../client/interfaces/Enum'; +import { PrimaryType } from './constants'; + +export function getEnum(values?: (string | number)[]): Enum[] { + if (Array.isArray(values)) { + return values + .filter((value, index, arr) => { + return arr.indexOf(value) === index; + }) + .map(value => { + if (typeof value === 'number') { + return { + name: `NUM_${value}`, + value: String(value), + type: PrimaryType.NUMBER, + }; + } + return { + name: value.replace(/([a-z])([A-Z]+)/g, '$1_$2').toUpperCase(), + value: `'${value}'`, + type: PrimaryType.STRING, + }; + }); + } + return []; +} diff --git a/src/openApi/v3/parser/getEnumFromDescription.ts b/src/openApi/v3/parser/getEnumFromDescription.ts new file mode 100644 index 00000000..60696e7e --- /dev/null +++ b/src/openApi/v3/parser/getEnumFromDescription.ts @@ -0,0 +1,32 @@ +import { Enum } from '../../../client/interfaces/Enum'; +import { PrimaryType } from './constants'; + +export function getEnumFromDescription(description: string): Enum[] { + // Check if we can find this special format string: + // None=0,Something=1,AnotherThing=2 + if (/^(\w+=[0-9]+,?)+$/g.test(description)) { + const matches = description.match(/(\w+=[0-9]+,?)/g); + if (matches) { + // Grab the values from the description + const symbols: Enum[] = []; + matches.forEach(match => { + const name = match.split('=')[0]; + const value = parseInt(match.split('=')[1].replace(/[^0-9]/g, '')); + if (name && Number.isInteger(value)) { + symbols.push({ + name: name.replace(/([a-z])([A-Z]+)/g, '$1_$2').toUpperCase(), + value: String(value), + type: PrimaryType.NUMBER, + }); + } + }); + + // Filter out any duplicate names + return symbols.filter((symbol, index, arr) => { + return arr.map(item => item.name).indexOf(symbol.name) === index; + }); + } + } + + return []; +} diff --git a/src/openApi/v3/parser/getEnumType.ts b/src/openApi/v3/parser/getEnumType.ts new file mode 100644 index 00000000..d0415c6a --- /dev/null +++ b/src/openApi/v3/parser/getEnumType.ts @@ -0,0 +1,18 @@ +import { Enum } from '../../../client/interfaces/Enum'; +import { getEnumValues } from './getEnumValues'; + +export function getEnumType(enumerators: Enum[], addParentheses: boolean = false): string { + // Fetch values from the symbols, just to be sure we filter out + // any double values and finally we sort them to make them easier + // to read when we use them in our generated code. + const values = getEnumValues(enumerators); + + // Add grouping parentheses if needed. This can be handy if enum values + // are used in Arrays, so that you will get the following definition: + // const myArray: ('EnumValue1' | 'EnumValue2' | 'EnumValue3')[]; + if (values.length > 1 && addParentheses) { + return `(${values.join(' | ')})`; + } + + return values.join(' | '); +} diff --git a/src/openApi/v3/parser/getEnumValues.ts b/src/openApi/v3/parser/getEnumValues.ts new file mode 100644 index 00000000..348208fe --- /dev/null +++ b/src/openApi/v3/parser/getEnumValues.ts @@ -0,0 +1,13 @@ +import { Enum } from '../../../client/interfaces/Enum'; + +export function getEnumValues(enumerators: Enum[]): string[] { + // Fetch values from the symbols, just to be sure we filter out + // any double values and finally we sort them to make them easier + // to read when we use them in our generated code. + return enumerators + .map(enumerator => enumerator.value) + .filter((enumerator, index, arr) => { + return arr.indexOf(enumerator) === index; + }) + .sort(); +} diff --git a/src/openApi/v3/parser/getMappedType.spec.ts b/src/openApi/v3/parser/getMappedType.spec.ts new file mode 100644 index 00000000..b437f85d --- /dev/null +++ b/src/openApi/v3/parser/getMappedType.spec.ts @@ -0,0 +1,21 @@ +import { getMappedType } from './getMappedType'; + +describe('getMappedType', () => { + it('should map types to the basics', () => { + expect(getMappedType('File')).toEqual('File'); + expect(getMappedType('String')).toEqual('string'); + expect(getMappedType('date')).toEqual('string'); + expect(getMappedType('date-time')).toEqual('string'); + expect(getMappedType('float')).toEqual('number'); + expect(getMappedType('double')).toEqual('number'); + expect(getMappedType('short')).toEqual('number'); + expect(getMappedType('int')).toEqual('number'); + expect(getMappedType('boolean')).toEqual('boolean'); + expect(getMappedType('any')).toEqual('any'); + expect(getMappedType('object')).toEqual('any'); + expect(getMappedType('void')).toEqual('void'); + expect(getMappedType('null')).toEqual('null'); + expect(getMappedType('unknown')).toEqual('unknown'); + expect(getMappedType('')).toEqual(''); + }); +}); diff --git a/src/openApi/v3/parser/getMappedType.ts b/src/openApi/v3/parser/getMappedType.ts new file mode 100644 index 00000000..ca11fa7e --- /dev/null +++ b/src/openApi/v3/parser/getMappedType.ts @@ -0,0 +1,16 @@ +import { PrimaryType, TYPE_MAPPINGS } from './constants'; + +/** + * Get mapped type for given type to any basic Typescript/Javascript type. + */ +export function getMappedType(type: string): PrimaryType | string { + const mapped = TYPE_MAPPINGS.get(type.toLowerCase()); + if (mapped) { + return mapped; + } + return type; +} + +export function hasMappedType(type: string): boolean { + return TYPE_MAPPINGS.has(type.toLowerCase()); +} diff --git a/src/openApi/v3/parser/getModel.ts b/src/openApi/v3/parser/getModel.ts new file mode 100644 index 00000000..f69ea813 --- /dev/null +++ b/src/openApi/v3/parser/getModel.ts @@ -0,0 +1,159 @@ +import { OpenApi } from '../interfaces/OpenApi'; +import { OpenApiSchema } from '../interfaces/OpenApiSchema'; +import { getComment } from './getComment'; +import { getType } from './getType'; +import { Model } from '../../../client/interfaces/Model'; +import { PrimaryType } from './constants'; +import { getEnumType } from './getEnumType'; +import { getEnum } from './getEnum'; +import { getEnumFromDescription } from './getEnumFromDescription'; +import { getModelProperties } from './getModelProperties'; + +export function getModel(openApi: OpenApi, definition: OpenApiSchema, isProperty: boolean = false, name: string = ''): Model { + const model: Model = { + name: name, + export: 'interface', + type: PrimaryType.OBJECT, + base: PrimaryType.OBJECT, + template: null, + link: null, + description: getComment(definition.description), + isProperty: isProperty, + isReadOnly: definition.readOnly || false, + isRequired: false, + isNullable: false, + imports: [], + extends: [], + enum: [], + enums: [], + properties: [], + }; + + if (definition.$ref) { + const definitionRef = getType(definition.$ref); + model.export = 'reference'; + model.type = definitionRef.type; + model.base = definitionRef.base; + model.template = definitionRef.template; + model.imports.push(...definitionRef.imports); + return model; + } + + if (definition.enum) { + const enumerators = getEnum(definition.enum); + if (enumerators.length) { + model.export = 'enum'; + model.type = getEnumType(enumerators); + model.base = PrimaryType.STRING; + model.enum.push(...enumerators); + return model; + } + } + + if ((definition.type === 'int' || definition.type === 'integer') && definition.description) { + const enumerators = getEnumFromDescription(definition.description); + if (enumerators.length) { + model.export = 'enum'; + model.type = getEnumType(enumerators); + model.base = PrimaryType.NUMBER; + model.enum.push(...enumerators); + return model; + } + } + + if (definition.type === 'array' && definition.items) { + if (definition.items.$ref) { + const arrayItems = getType(definition.items.$ref); + model.export = 'array'; + model.type = arrayItems.type; + model.base = arrayItems.base; + model.template = arrayItems.template; + model.imports.push(...arrayItems.imports); + return model; + } else { + const arrayItems = getModel(openApi, definition.items, true); + model.export = 'array'; + model.type = arrayItems.type; + model.base = arrayItems.base; + model.template = arrayItems.template; + model.link = arrayItems; + model.imports.push(...arrayItems.imports); + return model; + } + } + + if (definition.type === 'object' && definition.additionalProperties && typeof definition.additionalProperties === 'object') { + if (definition.additionalProperties.$ref) { + const additionalProperties = getType(definition.additionalProperties.$ref); + model.export = 'dictionary'; + model.type = additionalProperties.type; + model.base = additionalProperties.base; + model.template = additionalProperties.template; + model.imports.push(...additionalProperties.imports); + model.imports.push('Dictionary'); + return model; + } else { + const additionalProperties = getModel(openApi, definition.additionalProperties); + model.export = 'dictionary'; + model.type = additionalProperties.type; + model.base = additionalProperties.base; + model.template = additionalProperties.template; + model.link = additionalProperties; + model.imports.push(...additionalProperties.imports); + model.imports.push('Dictionary'); + return model; + } + } + + if (definition.type === 'object') { + model.export = 'interface'; + model.type = PrimaryType.OBJECT; + model.base = PrimaryType.OBJECT; + + if (definition.allOf) { + definition.allOf.forEach(parent => { + if (parent.$ref) { + const parentRef = getType(parent.$ref); + model.extends.push(parentRef.type); + model.imports.push(parentRef.base); + } + if (parent.type === 'object' && parent.properties) { + const properties = getModelProperties(openApi, parent); + properties.forEach(property => { + model.properties.push(property); + model.imports.push(...property.imports); + if (property.export === 'enum') { + model.enums.push(property); + } + }); + } + }); + } + + if (definition.properties) { + const properties = getModelProperties(openApi, definition); + properties.forEach(property => { + model.properties.push(property); + model.imports.push(...property.imports); + if (property.export === 'enum') { + model.enums.push(property); + } + }); + } + + return model; + } + + // If the schema has a type than it can be a basic or generic type. + if (definition.type) { + const definitionType = getType(definition.type); + model.export = 'generic'; + model.type = definitionType.type; + model.base = definitionType.base; + model.template = definitionType.template; + model.imports.push(...definitionType.imports); + return model; + } + + return model; +} diff --git a/src/openApi/v3/parser/getModelProperties.ts b/src/openApi/v3/parser/getModelProperties.ts new file mode 100644 index 00000000..07edbd65 --- /dev/null +++ b/src/openApi/v3/parser/getModelProperties.ts @@ -0,0 +1,60 @@ +import { OpenApi } from '../interfaces/OpenApi'; +import { OpenApiSchema } from '../interfaces/OpenApiSchema'; +import { getComment } from './getComment'; +import { getType } from './getType'; +import { Model } from '../../../client/interfaces/Model'; +import { getModel } from './getModel'; + +export function getModelProperties(openApi: OpenApi, definition: OpenApiSchema): Model[] { + const models: Model[] = []; + for (const propertyName in definition.properties) { + if (definition.properties.hasOwnProperty(propertyName)) { + const property = definition.properties[propertyName]; + const propertyRequired = !!(definition.required && definition.required.includes(propertyName)); + const propertyReadOnly = !!property.readOnly; + if (property.$ref) { + const model = getType(property.$ref); + models.push({ + name: propertyName, + export: 'reference', + type: model.type, + base: model.base, + template: model.template, + link: null, + description: getComment(property.description), + isProperty: true, + isReadOnly: propertyReadOnly, + isRequired: propertyRequired, + isNullable: false, + imports: model.imports, + extends: [], + enum: [], + enums: [], + properties: [], + }); + } else { + const model = getModel(openApi, property); + models.push({ + name: propertyName, + export: model.export, + type: model.type, + base: model.base, + template: model.template, + link: model.link, + description: getComment(property.description), + isProperty: true, + isReadOnly: propertyReadOnly, + isRequired: propertyRequired, + isNullable: false, + imports: model.imports, + extends: model.extends, + enum: model.enum, + enums: model.enums, + properties: model.properties, + }); + } + } + } + + return models; +} diff --git a/src/openApi/v3/parser/getModelTemplate.spec.ts b/src/openApi/v3/parser/getModelTemplate.spec.ts new file mode 100644 index 00000000..67e46f54 --- /dev/null +++ b/src/openApi/v3/parser/getModelTemplate.spec.ts @@ -0,0 +1,23 @@ +import { getModelTemplate } from './getModelTemplate'; + +describe('getModelTemplate', () => { + it('should return generic for template type', () => { + const template = getModelTemplate({ + type: 'Link', + base: 'Link', + template: 'Model', + imports: ['Model'], + }); + expect(template).toEqual(''); + }); + + it('should return empty for primary type', () => { + const template = getModelTemplate({ + type: 'string', + base: 'string', + template: null, + imports: [], + }); + expect(template).toEqual(''); + }); +}); diff --git a/src/openApi/v3/parser/getModelTemplate.ts b/src/openApi/v3/parser/getModelTemplate.ts new file mode 100644 index 00000000..f472e784 --- /dev/null +++ b/src/openApi/v3/parser/getModelTemplate.ts @@ -0,0 +1,11 @@ +import { Type } from '../../../client/interfaces/Type'; + +/** + * If our model has a template type, then we want to generalize that! + * In that case we should return "" as our template type. + * @param modelClass The parsed model class type. + * @returns The model template type ( or empty). + */ +export function getModelTemplate(modelClass: Type): string { + return modelClass.template ? '' : ''; +} diff --git a/src/openApi/v3/parser/getModels.ts b/src/openApi/v3/parser/getModels.ts index 40db01f6..daf488a5 100644 --- a/src/openApi/v3/parser/getModels.ts +++ b/src/openApi/v3/parser/getModels.ts @@ -1,11 +1,19 @@ -import { Model } from '../../../client/interfaces/Model'; -import { OpenApi } from '../interfaces/OpenApi'; +import {Model} from '../../../client/interfaces/Model'; +import {OpenApi} from '../interfaces/OpenApi'; +import {getModel} from './getModel'; +import {getType} from './getType'; -/** - * Parse and return the OpenAPI models. - * @param openApi - */ export function getModels(openApi: OpenApi): Map { const models = new Map(); + if (openApi.components) { + for (const definitionName in openApi.components.schemas) { + if (openApi.components.schemas.hasOwnProperty(definitionName)) { + const definition = openApi.components.schemas[definitionName]; + const definitionType = getType(definitionName); + const model = getModel(openApi, definition, false, definitionType.base); + models.set(definitionType.base, model); + } + } + } return models; } diff --git a/src/openApi/v3/parser/getOperation.ts b/src/openApi/v3/parser/getOperation.ts new file mode 100644 index 00000000..23007b82 --- /dev/null +++ b/src/openApi/v3/parser/getOperation.ts @@ -0,0 +1,65 @@ +import { Service } from '../../../client/interfaces/Service'; +import { getServiceClassName } from './getServiceClassName'; +import { OpenApiOperation } from '../interfaces/OpenApiOperation'; +import { getOperationName } from './getOperationName'; +import { getOperationPath } from './getOperationPath'; +import { OpenApi } from '../interfaces/OpenApi'; +import { getComment } from './getComment'; +import { Operation } from '../../../client/interfaces/Operation'; +import { getOperationParameters } from './getOperationParameters'; +import { getOperationResponses } from './getOperationResponses'; +import { getOperationResults } from './getOperationResults'; +import { getOperationErrors } from './getOperationErrors'; + +export function getOperation(openApi: OpenApi, url: string, method: string, op: OpenApiOperation): Operation { + const serviceName = (op.tags && op.tags[0]) || 'Service'; + const serviceClassName = getServiceClassName(serviceName); + const operationNameFallback = `${method}${serviceClassName}`; + const operationName = getOperationName(op.operationId || operationNameFallback); + const operationPath = getOperationPath(url); + + // Create a new operation object for this method. + const operation: Operation = { + service: serviceClassName, + name: operationName, + summary: getComment(op.summary), + description: getComment(op.description), + deprecated: op.deprecated || false, + method: method, + path: operationPath, + parameters: [], + parametersPath: [], + parametersQuery: [], + parametersForm: [], + parametersHeader: [], + parametersBody: null, + imports: [], + errors: [], + results: [], + }; + + // Parse the operation parameters (path, query, body, etc). + if (op.parameters) { + const parameters = getOperationParameters(openApi, op.parameters); + operation.imports.push(...parameters.imports); + operation.parameters.push(...parameters.parameters); + operation.parametersPath.push(...parameters.parametersPath); + operation.parametersQuery.push(...parameters.parametersQuery); + operation.parametersForm.push(...parameters.parametersForm); + operation.parametersHeader.push(...parameters.parametersHeader); + operation.parametersBody = parameters.parametersBody; + } + + // Parse the operation responses. + if (op.responses) { + const operationResponses = getOperationResponses(openApi, op.responses); + const operationResults = getOperationResults(operationResponses); + operation.errors = getOperationErrors(operationResponses); + operationResults.forEach(operationResult => { + operation.results.push(operationResult); + operation.imports.push(...operationResult.imports); + }); + } + + return operation; +} diff --git a/src/openApi/v3/parser/getOperationErrors.ts b/src/openApi/v3/parser/getOperationErrors.ts new file mode 100644 index 00000000..2615e074 --- /dev/null +++ b/src/openApi/v3/parser/getOperationErrors.ts @@ -0,0 +1,13 @@ +import { OperationResponse } from '../../../client/interfaces/OperationResponse'; +import { OperationError } from '../../../client/interfaces/OperationError'; + +export function getOperationErrors(operationResponses: OperationResponse[]): OperationError[] { + return operationResponses + .filter(operationResponse => { + return operationResponse.code >= 300 && operationResponse.description; + }) + .map(response => ({ + code: response.code, + description: response.description!, + })); +} diff --git a/src/openApi/v3/parser/getOperationName.spec.ts b/src/openApi/v3/parser/getOperationName.spec.ts new file mode 100644 index 00000000..ba8a5d3d --- /dev/null +++ b/src/openApi/v3/parser/getOperationName.spec.ts @@ -0,0 +1,10 @@ +import { getOperationName } from './getOperationName'; + +describe('getOperationName', () => { + it('should produce correct result', () => { + expect(getOperationName('')).toEqual(''); + expect(getOperationName('FooBar')).toEqual('fooBar'); + expect(getOperationName('Foo Bar')).toEqual('fooBar'); + expect(getOperationName('foo bar')).toEqual('fooBar'); + }); +}); diff --git a/src/openApi/v3/parser/getOperationName.ts b/src/openApi/v3/parser/getOperationName.ts new file mode 100644 index 00000000..83a9abcb --- /dev/null +++ b/src/openApi/v3/parser/getOperationName.ts @@ -0,0 +1,11 @@ +import camelCase from 'camelcase'; + +/** + * Convert the input value to a correct operation (method) classname. + * This converts the input string to camelCase, so the method name follows + * the most popular Javascript and Typescript writing style. + */ +export function getOperationName(value: string): string { + const clean = value.replace(/[^\w\s\-]+/g, '_').trim(); + return camelCase(clean); +} diff --git a/src/openApi/v3/parser/getOperationParameter.ts b/src/openApi/v3/parser/getOperationParameter.ts new file mode 100644 index 00000000..8acfab6a --- /dev/null +++ b/src/openApi/v3/parser/getOperationParameter.ts @@ -0,0 +1,59 @@ +import { OpenApiParameter } from '../interfaces/OpenApiParameter'; +import { OpenApi } from '../interfaces/OpenApi'; +import { getComment } from './getComment'; +import { getOperationParameterName } from './getOperationParameterName'; +import { OperationParameter } from '../../../client/interfaces/OperationParameter'; +import { PrimaryType } from './constants'; +import { getType } from './getType'; +import { getModel } from './getModel'; + +export function getOperationParameter(openApi: OpenApi, parameter: OpenApiParameter): OperationParameter { + const operationParameter: OperationParameter = { + in: parameter.in, + prop: parameter.name, + export: 'interface', + name: getOperationParameterName(parameter.name), + type: PrimaryType.OBJECT, + base: PrimaryType.OBJECT, + template: null, + link: null, + description: getComment(parameter.description), + default: undefined, + isProperty: false, + isReadOnly: false, + isRequired: parameter.required || false, + isNullable: false, + imports: [], + extends: [], + enum: [], + enums: [], + properties: [], + }; + + if (parameter.schema) { + if (parameter.schema.$ref) { + const model = getType(parameter.schema.$ref); + operationParameter.export = 'reference'; + operationParameter.type = model.type; + operationParameter.base = model.base; + operationParameter.template = model.template; + operationParameter.imports.push(...model.imports); + return operationParameter; + } else { + const model = getModel(openApi, parameter.schema); + operationParameter.export = model.export; + operationParameter.type = model.type; + operationParameter.base = model.base; + operationParameter.template = model.template; + operationParameter.link = model.link; + operationParameter.imports.push(...model.imports); + operationParameter.extends.push(...model.extends); + operationParameter.enum.push(...model.enum); + operationParameter.enums.push(...model.enums); + operationParameter.properties.push(...model.properties); + return operationParameter; + } + } + + return operationParameter; +} diff --git a/src/openApi/v3/parser/getOperationParameterDefault.ts b/src/openApi/v3/parser/getOperationParameterDefault.ts new file mode 100644 index 00000000..5685a7db --- /dev/null +++ b/src/openApi/v3/parser/getOperationParameterDefault.ts @@ -0,0 +1,15 @@ +export function getOperationParameterDefault(value: any): string | null { + if (value === null) { + return 'null'; + } + + switch (typeof value) { + case 'number': + case 'boolean': + return JSON.stringify(value); + case 'string': + return `'${value}'`; + } + + return null; +} diff --git a/src/openApi/v3/parser/getOperationParameterName.ts b/src/openApi/v3/parser/getOperationParameterName.ts new file mode 100644 index 00000000..54d80d9f --- /dev/null +++ b/src/openApi/v3/parser/getOperationParameterName.ts @@ -0,0 +1,10 @@ +import camelCase from 'camelcase'; + +/** + * Replaces any invalid characters from a parameter name. + * For example: 'filter.someProperty' becomes 'filterSomeProperty'. + */ +export function getOperationParameterName(value: string): string { + const clean = value.replace(/[^\w\s\-]+/g, '_').trim(); + return camelCase(clean); +} diff --git a/src/openApi/v3/parser/getOperationParameters.ts b/src/openApi/v3/parser/getOperationParameters.ts new file mode 100644 index 00000000..c4af435f --- /dev/null +++ b/src/openApi/v3/parser/getOperationParameters.ts @@ -0,0 +1,59 @@ +import { OpenApiParameter } from '../interfaces/OpenApiParameter'; +import { OpenApi } from '../interfaces/OpenApi'; +import { getRef } from './getRef'; +import { OperationParameters } from '../../../client/interfaces/OperationParameters'; +import { OperationParameter } from '../../../client/interfaces/OperationParameter'; +import { getOperationParameter } from './getOperationParameter'; + +function sortByRequired(a: OperationParameter, b: OperationParameter): number { + return a.isRequired && !b.isRequired ? -1 : !a.isRequired && b.isRequired ? 1 : 0; +} + +export function getOperationParameters(openApi: OpenApi, parameters: OpenApiParameter[]): OperationParameters { + const operationParameters: OperationParameters = { + imports: [], + parameters: [], + parametersPath: [], + parametersQuery: [], + parametersForm: [], + parametersHeader: [], + parametersBody: null, + }; + + // Iterate over the parameters + parameters.forEach(parameter => { + const paramRef = getRef(openApi, parameter); + const param = getOperationParameter(openApi, paramRef); + + // We ignore the "api-version" param, since we do not want to add this + // as the first / default parameter for each of the service calls. + if (param.prop !== 'api-version') { + switch (parameter.in) { + case 'path': + operationParameters.parametersPath.push(param); + operationParameters.parameters.push(param); + operationParameters.imports.push(...param.imports); + break; + + case 'query': + operationParameters.parametersQuery.push(param); + operationParameters.parameters.push(param); + operationParameters.imports.push(...param.imports); + break; + + case 'header': + operationParameters.parametersHeader.push(param); + operationParameters.parameters.push(param); + operationParameters.imports.push(...param.imports); + break; + } + } + }); + + operationParameters.parameters = operationParameters.parameters.sort(sortByRequired); + operationParameters.parametersPath = operationParameters.parametersPath.sort(sortByRequired); + operationParameters.parametersQuery = operationParameters.parametersQuery.sort(sortByRequired); + operationParameters.parametersForm = operationParameters.parametersForm.sort(sortByRequired); + operationParameters.parametersHeader = operationParameters.parametersHeader.sort(sortByRequired); + return operationParameters; +} diff --git a/src/openApi/v3/parser/getOperationPath.spec.ts b/src/openApi/v3/parser/getOperationPath.spec.ts new file mode 100644 index 00000000..4ede28f4 --- /dev/null +++ b/src/openApi/v3/parser/getOperationPath.spec.ts @@ -0,0 +1,10 @@ +import { getOperationPath } from './getOperationPath'; + +describe('getOperationPath', () => { + it('should produce correct result', () => { + expect(getOperationPath('/api/v{api-version}/list/{id}/{type}')).toEqual('/api/v${OpenAPI.VERSION}/list/${id}/${type}'); + expect(getOperationPath('/api/v{api-version}/list/{id}')).toEqual('/api/v${OpenAPI.VERSION}/list/${id}'); + expect(getOperationPath('/api/v1/list/{id}')).toEqual('/api/v1/list/${id}'); + expect(getOperationPath('/api/v1/list')).toEqual('/api/v1/list'); + }); +}); diff --git a/src/openApi/v3/parser/getOperationPath.ts b/src/openApi/v3/parser/getOperationPath.ts new file mode 100644 index 00000000..04b6fd4e --- /dev/null +++ b/src/openApi/v3/parser/getOperationPath.ts @@ -0,0 +1,9 @@ +/** + * Get the final service path, this replaces the "{api-version}" placeholder + * with a new template string placeholder so we can dynamically inject the + * OpenAPI version without the need to hardcode this in the URL. + * @param path + */ +export function getOperationPath(path: string): string { + return path.replace(/{api-version}/g, '{OpenAPI.VERSION}').replace(/\{(.*?)\}/g, '${$1}'); +} diff --git a/src/openApi/v3/parser/getOperationResponseCode.ts b/src/openApi/v3/parser/getOperationResponseCode.ts new file mode 100644 index 00000000..080cdc02 --- /dev/null +++ b/src/openApi/v3/parser/getOperationResponseCode.ts @@ -0,0 +1,16 @@ +export function getOperationResponseCode(value: string | 'default'): number | null { + // You can specify a "default" response, this is treated as HTTP code 200 + if (value === 'default') { + return 200; + } + + // Check if we can parse the code and return of successful. + if (/[0-9]+/g.test(value)) { + const code = parseInt(value); + if (Number.isInteger(code)) { + return code; + } + } + + return null; +} diff --git a/src/openApi/v3/parser/getOperationResponses.ts b/src/openApi/v3/parser/getOperationResponses.ts new file mode 100644 index 00000000..98b16434 --- /dev/null +++ b/src/openApi/v3/parser/getOperationResponses.ts @@ -0,0 +1,86 @@ +import { OpenApiResponses } from '../interfaces/OpenApiResponses'; +import { getOperationResponseCode } from './getOperationResponseCode'; +import { OpenApiResponse } from '../interfaces/OpenApiResponse'; +import { getRef } from './getRef'; +import { OpenApi } from '../interfaces/OpenApi'; +import { OperationResponse } from '../../../client/interfaces/OperationResponse'; +import { getType } from './getType'; +import { getModel } from './getModel'; +import { getComment } from './getComment'; +import { PrimaryType } from './constants'; + +export function getOperationResponses(openApi: OpenApi, responses: OpenApiResponses): OperationResponse[] { + const operationResponses: OperationResponse[] = []; + + // Iterate over each response code and get the + // status code and response message (if any). + for (const code in responses) { + if (responses.hasOwnProperty(code)) { + const responseOrReference = responses[code]; + const response = getRef(openApi, responseOrReference); + const responseCode = getOperationResponseCode(code); + + // If there is a response code then we check what data we get back, + // if there is no typed data, we just return so the user is still + // free to do their own casting if needed. + if (responseCode) { + const operationResponse: OperationResponse = { + name: '', + code: responseCode, + description: getComment(response.description)!, + export: 'generic', + type: PrimaryType.OBJECT, + base: PrimaryType.OBJECT, + template: null, + link: null, + isProperty: false, + isReadOnly: false, + isRequired: false, + isNullable: false, + imports: [], + extends: [], + enum: [], + enums: [], + properties: [], + }; + + // If this response has a schema, then we need to check two things: + // if this is a reference then the parameter is just the 'name' of + // this reference type. Otherwise it might be a complex schema and + // then we need to parse the schema! + + // TODO: Needs content! + + // if (response.schema) { + // if (response.schema.$ref) { + // const model = getType(response.schema.$ref); + // operationResponse.export = 'reference'; + // operationResponse.type = model.type; + // operationResponse.base = model.base; + // operationResponse.template = model.template; + // operationResponse.imports.push(...model.imports); + // } else { + // const model = getModel(openApi, response.schema); + // operationResponse.export = model.export; + // operationResponse.type = model.type; + // operationResponse.base = model.base; + // operationResponse.template = model.template; + // operationResponse.link = model.link; + // operationResponse.imports.push(...model.imports); + // operationResponse.extends.push(...model.extends); + // operationResponse.enum.push(...model.enum); + // operationResponse.enums.push(...model.enums); + // operationResponse.properties.push(...model.properties); + // } + // } + + operationResponses.push(operationResponse); + } + } + } + + // Sort the responses to 2XX success codes come before 4XX and 5XX error codes. + return operationResponses.sort((a, b): number => { + return a.code < b.code ? -1 : a.code > b.code ? 1 : 0; + }); +} diff --git a/src/openApi/v3/parser/getOperationResults.ts b/src/openApi/v3/parser/getOperationResults.ts new file mode 100644 index 00000000..57456799 --- /dev/null +++ b/src/openApi/v3/parser/getOperationResults.ts @@ -0,0 +1,51 @@ +import { PrimaryType } from './constants'; +import { OperationResponse } from '../../../client/interfaces/OperationResponse'; +import { Model } from '../../../client/interfaces/Model'; + +function areEqual(a: Model, b: Model): boolean { + const equal = a.type === b.type && a.base === b.base && a.template === b.template; + if (equal && a.link && b.link) { + return areEqual(a.link, b.link); + } + return equal; +} + +export function getOperationResults(operationResponses: OperationResponse[]): OperationResponse[] { + const operationResults: OperationResponse[] = []; + + operationResponses.forEach(operationResponse => { + if (operationResponse.code && operationResponse.code >= 200 && operationResponse.code < 300) { + operationResults.push(operationResponse); + } + }); + + if (!operationResults.length) { + operationResults.push({ + name: '', + code: 200, + description: '', + export: 'interface', + type: PrimaryType.OBJECT, + base: PrimaryType.OBJECT, + template: null, + link: null, + isProperty: false, + isReadOnly: false, + isRequired: false, + isNullable: false, + imports: [], + extends: [], + enum: [], + enums: [], + properties: [], + }); + } + + return operationResults.filter((operationResult, index, arr) => { + return ( + arr.findIndex(item => { + return areEqual(item, operationResult); + }) === index + ); + }); +} diff --git a/src/openApi/v3/parser/getRef.ts b/src/openApi/v3/parser/getRef.ts new file mode 100644 index 00000000..303382ba --- /dev/null +++ b/src/openApi/v3/parser/getRef.ts @@ -0,0 +1,26 @@ +import { OpenApi } from '../interfaces/OpenApi'; +import { OpenApiReference } from '../interfaces/OpenApiReference'; + +export function getRef(openApi: OpenApi, item: T & OpenApiReference): T { + if (item.$ref) { + // Fetch the paths to the definitions, this converts: + // "#/definitions/Form" to ["definitions", "Form"] + const paths = item.$ref + .replace(/^#/g, '') + .split('/') + .filter(item => item); + + // Try to find the reference by walking down the path, + // if we cannot find it, then we throw an error. + let result: any = openApi; + paths.forEach((path: string): void => { + if (result.hasOwnProperty(path)) { + result = result[path]; + } else { + throw new Error(`Could not find reference: "${item.$ref}"`); + } + }); + return result as T; + } + return item as T; +} diff --git a/src/openApi/v3/parser/getServiceClassName.spec.ts b/src/openApi/v3/parser/getServiceClassName.spec.ts new file mode 100644 index 00000000..9bcf6e15 --- /dev/null +++ b/src/openApi/v3/parser/getServiceClassName.spec.ts @@ -0,0 +1,13 @@ +import { getServiceClassName } from './getServiceClassName'; + +describe('getServiceClassName', () => { + it('should produce correct result', () => { + expect(getServiceClassName('')).toEqual(''); + expect(getServiceClassName('FooBar')).toEqual('FooBarService'); + expect(getServiceClassName('Foo Bar')).toEqual('FooBarService'); + expect(getServiceClassName('foo bar')).toEqual('FooBarService'); + expect(getServiceClassName('FooBarService')).toEqual('FooBarService'); + expect(getServiceClassName('Foo Bar Service')).toEqual('FooBarService'); + expect(getServiceClassName('foo bar service')).toEqual('FooBarService'); + }); +}); diff --git a/src/openApi/v3/parser/getServiceClassName.ts b/src/openApi/v3/parser/getServiceClassName.ts new file mode 100644 index 00000000..94131a3d --- /dev/null +++ b/src/openApi/v3/parser/getServiceClassName.ts @@ -0,0 +1,14 @@ +import camelCase from 'camelcase'; + +/** + * Convert the input value to a correct service classname. This converts + * the input string to PascalCase and appends the "Service" prefix if needed. + */ +export function getServiceClassName(value: string): string { + const clean = value.replace(/[^\w\s\-]+/g, '_').trim(); + const name = camelCase(clean, { pascalCase: true }); + if (name && !name.endsWith('Service')) { + return `${name}Service`; + } + return name; +} diff --git a/src/openApi/v3/parser/getServices.ts b/src/openApi/v3/parser/getServices.ts index d4c59848..e9905a5e 100644 --- a/src/openApi/v3/parser/getServices.ts +++ b/src/openApi/v3/parser/getServices.ts @@ -1,11 +1,49 @@ import { Service } from '../../../client/interfaces/Service'; import { OpenApi } from '../interfaces/OpenApi'; +import { Method } from './constants'; +import { getOperation } from './getOperation'; /** - * Parse and return the OpenAPI services. - * @param openApi + * Get the OpenAPI services */ export function getServices(openApi: OpenApi): Map { const services = new Map(); + for (const url in openApi.paths) { + if (openApi.paths.hasOwnProperty(url)) { + const path = openApi.paths[url]; + for (const method in path) { + if (path.hasOwnProperty(method)) { + switch (method) { + case Method.GET: + case Method.PUT: + case Method.POST: + case Method.DELETE: + case Method.OPTIONS: + case Method.HEAD: + case Method.PATCH: + // Each method contains an OpenAPI operation, we parse the operation + const op = path[method]!; + const operation = getOperation(openApi, url, method, op); + + // If we have already declared a service, then we should fetch that and + // append the new method to it. Otherwise we should create a new service object. + const service = + services.get(operation.service) || + ({ + name: operation.service, + operations: [], + imports: [], + } as Service); + + // Push the operation in the service + service.operations.push(operation); + service.imports.push(...operation.imports); + services.set(operation.service, service); + break; + } + } + } + } + } return services; } diff --git a/src/openApi/v3/parser/getType.spec.ts b/src/openApi/v3/parser/getType.spec.ts new file mode 100644 index 00000000..a3e7e422 --- /dev/null +++ b/src/openApi/v3/parser/getType.spec.ts @@ -0,0 +1,59 @@ +import { getType } from './getType'; + +describe('getType', () => { + it('should convert int', () => { + const type = getType('int'); + expect(type.type).toEqual('number'); + expect(type.base).toEqual('number'); + expect(type.template).toEqual(null); + expect(type.imports).toEqual([]); + }); + + it('should convert string', () => { + const type = getType('String'); + expect(type.type).toEqual('string'); + expect(type.base).toEqual('string'); + expect(type.template).toEqual(null); + expect(type.imports).toEqual([]); + }); + + it('should convert string array', () => { + const type = getType('Array[String]'); + expect(type.type).toEqual('Array'); + expect(type.base).toEqual('Array'); + expect(type.template).toEqual('string'); + expect(type.imports).toEqual(['Array']); + }); + + it('should convert template with primary', () => { + const type = getType('#/definitions/Link[String]'); + expect(type.type).toEqual('Link'); + expect(type.base).toEqual('Link'); + expect(type.template).toEqual('string'); + expect(type.imports).toEqual(['Link']); + }); + + it('should convert template with model', () => { + const type = getType('#/definitions/Link[Model]'); + expect(type.type).toEqual('Link'); + expect(type.base).toEqual('Link'); + expect(type.template).toEqual('Model'); + expect(type.imports).toEqual(['Link', 'Model']); + }); + + it('should have double imports', () => { + const type = getType('#/definitions/Link[Link]'); + expect(type.type).toEqual('Link'); + expect(type.base).toEqual('Link'); + expect(type.template).toEqual('Link'); + expect(type.imports).toEqual(['Link', 'Link']); + }); + + it('should convert generic', () => { + const type = getType('#/definitions/Link', 'Link'); + expect(type.type).toEqual('T'); + expect(type.base).toEqual('T'); + expect(type.template).toEqual(null); + expect(type.imports).toEqual([]); + }); +}); diff --git a/src/openApi/v3/parser/getType.ts b/src/openApi/v3/parser/getType.ts new file mode 100644 index 00000000..7ab373f4 --- /dev/null +++ b/src/openApi/v3/parser/getType.ts @@ -0,0 +1,59 @@ +import { stripNamespace } from './stripNamespace'; +import { Type } from '../../../client/interfaces/Type'; +import { getMappedType, hasMappedType } from './getMappedType'; +import { PrimaryType } from './constants'; + +/** + * Parse any string value into a type object. + * @param value String value like "integer" or "Link[Model]". + * @param template Optional template class from parent (needed to process generics) + */ +export function getType(value?: string, template?: string): Type { + const result: Type = { + type: PrimaryType.OBJECT, + base: PrimaryType.OBJECT, + template: null, + imports: [], + }; + + const valueClean = stripNamespace(value || ''); + + if (/\[.*\]$/g.test(valueClean)) { + const matches = valueClean.match(/(.*?)\[(.*)\]$/); + if (matches && matches.length) { + const match1 = getType(matches[1]); + const match2 = getType(matches[2]); + + if (match2.type) { + result.type = `${match1.type}<${match2.type}>`; + result.base = match1.type; + result.template = match2.type; + } else { + result.type = match1.type; + result.base = match1.type; + result.template = match1.type; + } + + result.imports.push(...match1.imports); + result.imports.push(...match2.imports); + } + } else if (hasMappedType(valueClean)) { + const mapped = getMappedType(valueClean); + result.type = mapped; + result.base = mapped; + } else if (valueClean) { + result.type = valueClean; + result.base = valueClean; + result.imports.push(valueClean); + } + + // If the property that we found matched the parent template class + // Then ignore this whole property and return it as a "T" template property. + if (result.type === template) { + result.type = 'T'; // Template; + result.base = 'T'; // Template; + result.imports = []; + } + + return result; +} diff --git a/src/openApi/v3/parser/isPrimaryType.spec.ts b/src/openApi/v3/parser/isPrimaryType.spec.ts new file mode 100644 index 00000000..ed3e1774 --- /dev/null +++ b/src/openApi/v3/parser/isPrimaryType.spec.ts @@ -0,0 +1,14 @@ +import { isPrimaryType } from './isPrimaryType'; + +describe('isPrimaryType', () => { + it('should return true for primary types', () => { + expect(isPrimaryType('number')).toBeTruthy(); + expect(isPrimaryType('boolean')).toBeTruthy(); + expect(isPrimaryType('string')).toBeTruthy(); + expect(isPrimaryType('any')).toBeTruthy(); + expect(isPrimaryType('void')).toBeTruthy(); + expect(isPrimaryType('null')).toBeTruthy(); + expect(isPrimaryType('Array')).toBeFalsy(); + expect(isPrimaryType('MyModel')).toBeFalsy(); + }); +}); diff --git a/src/openApi/v3/parser/isPrimaryType.ts b/src/openApi/v3/parser/isPrimaryType.ts new file mode 100644 index 00000000..dfb9e778 --- /dev/null +++ b/src/openApi/v3/parser/isPrimaryType.ts @@ -0,0 +1,19 @@ +import { PrimaryType } from './constants'; + +/** + * Check if given type is a primary type. + * @param type + */ +export function isPrimaryType(type: string): type is PrimaryType { + switch (type.toLowerCase()) { + case PrimaryType.FILE: + case PrimaryType.OBJECT: + case PrimaryType.BOOLEAN: + case PrimaryType.NUMBER: + case PrimaryType.STRING: + case PrimaryType.VOID: + case PrimaryType.NULL: + return true; + } + return false; +} diff --git a/src/templates/typescript/partials/validationInterface.hbs b/src/templates/typescript/partials/validationInterface.hbs index a9c8a7d5..afe191f3 100644 --- a/src/templates/typescript/partials/validationInterface.hbs +++ b/src/templates/typescript/partials/validationInterface.hbs @@ -7,7 +7,7 @@ {{#if properties}} yup.object{{#unless isProperty}}{{#if name}}<{{{name}}}>{{/if}}{{/unless}}().shape({ {{#each properties}} - {{{name}}}: yup.lazy(() => {{>validation}}.default(undefined){{#if isNullable}}.isNullable(){{/if}}){{#if isRequired}}.isRequired(){{/if}}{{#unless @last}},{{/unless}} + {{{name}}}: yup.lazy(() => {{>validation}}.default(undefined){{#if isNullable}}.nullable(){{/if}}{{#if isRequired}}.required(){{/if}}){{#unless @last}},{{/unless}} {{/each}} }).noUnknown() {{else}} diff --git a/test/index.js b/test/index.js index f62fb26c..a2396b28 100644 --- a/test/index.js +++ b/test/index.js @@ -1,17 +1,24 @@ const OpenAPI = require('../dist'); OpenAPI.generate( - './test/mock/spec-v2.json', - './test/result/v2/typescript/', + './test/mock/spec-v3.json', + './test/result/v3/typescript/', OpenAPI.Language.TYPESCRIPT, OpenAPI.HttpClient.FETCH, ); -OpenAPI.generate( - './test/mock/spec-v2.json', - './test/result/v2/javascript/', - OpenAPI.Language.JAVASCRIPT, - OpenAPI.HttpClient.XHR, -); +// OpenAPI.generate( +// './test/mock/spec-v2.json', +// './test/result/v2/typescript/', +// OpenAPI.Language.TYPESCRIPT, +// OpenAPI.HttpClient.FETCH, +// ); -OpenAPI.compile('./test/result/v2/typescript/'); +// OpenAPI.generate( +// './test/mock/spec-v2.json', +// './test/result/v2/javascript/', +// OpenAPI.Language.JAVASCRIPT, +// OpenAPI.HttpClient.XHR, +// ); + +// OpenAPI.compile('./test/result/v2/typescript/'); diff --git a/test/mock/spec-v3.json b/test/mock/spec-v3.json index d1b1038a..255cea30 100644 --- a/test/mock/spec-v3.json +++ b/test/mock/spec-v3.json @@ -54,6 +54,66 @@ } } } + }, + "404": { + "description": "Not Found", + "content": { + "text/plain": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + }, + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "400": { + "description": "Bad Request", + "content": { + "text/plain": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + }, + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "500": { + "description": "Server Error", + "content": { + "text/plain": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + }, + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } } } } @@ -104,26 +164,6 @@ } } }, - "404": { - "description": "Not Found", - "content": { - "text/plain": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - }, - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - }, - "text/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - } - } - }, "400": { "description": "Bad Request", "content": { @@ -212,6 +252,66 @@ } } } + }, + "404": { + "description": "Not Found", + "content": { + "text/plain": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + }, + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "400": { + "description": "Bad Request", + "content": { + "text/plain": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + }, + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "500": { + "description": "Server Error", + "content": { + "text/plain": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + }, + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } } } } @@ -260,6 +360,66 @@ } } } + }, + "404": { + "description": "Not Found", + "content": { + "text/plain": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + }, + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "400": { + "description": "Bad Request", + "content": { + "text/plain": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + }, + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "500": { + "description": "Server Error", + "content": { + "text/plain": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + }, + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } } } } @@ -308,6 +468,66 @@ } } } + }, + "404": { + "description": "Not Found", + "content": { + "text/plain": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + }, + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "400": { + "description": "Bad Request", + "content": { + "text/plain": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + }, + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "500": { + "description": "Server Error", + "content": { + "text/plain": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + }, + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } } } } @@ -361,7 +581,8 @@ "name": { "maxLength": 256, "type": "string", - "nullable": true + "nullable": true, + "readOnly": true }, "redirectUrls": { "type": "array", @@ -369,6 +590,28 @@ "type": "string" }, "nullable": true + }, + "createdBy": { + "type": "integer", + "format": "int32", + "nullable": true, + "readOnly": true + }, + "modifiedBy": { + "type": "integer", + "format": "int32", + "nullable": true, + "readOnly": true + }, + "createdAt": { + "type": "string", + "format": "date-time", + "readOnly": true + }, + "modifiedAt": { + "type": "string", + "format": "date-time", + "readOnly": true } } } @@ -395,7 +638,8 @@ "name": { "maxLength": 256, "type": "string", - "nullable": true + "nullable": true, + "readOnly": true }, "redirectUrls": { "type": "array", @@ -403,6 +647,28 @@ "type": "string" }, "nullable": true + }, + "createdBy": { + "type": "integer", + "format": "int32", + "nullable": true, + "readOnly": true + }, + "modifiedBy": { + "type": "integer", + "format": "int32", + "nullable": true, + "readOnly": true + }, + "createdAt": { + "type": "string", + "format": "date-time", + "readOnly": true + }, + "modifiedAt": { + "type": "string", + "format": "date-time", + "readOnly": true } } } @@ -429,7 +695,8 @@ "name": { "maxLength": 256, "type": "string", - "nullable": true + "nullable": true, + "readOnly": true }, "redirectUrls": { "type": "array", @@ -437,6 +704,28 @@ "type": "string" }, "nullable": true + }, + "createdBy": { + "type": "integer", + "format": "int32", + "nullable": true, + "readOnly": true + }, + "modifiedBy": { + "type": "integer", + "format": "int32", + "nullable": true, + "readOnly": true + }, + "createdAt": { + "type": "string", + "format": "date-time", + "readOnly": true + }, + "modifiedAt": { + "type": "string", + "format": "date-time", + "readOnly": true } } } @@ -463,7 +752,8 @@ "name": { "maxLength": 256, "type": "string", - "nullable": true + "nullable": true, + "readOnly": true }, "redirectUrls": { "type": "array", @@ -471,6 +761,28 @@ "type": "string" }, "nullable": true + }, + "createdBy": { + "type": "integer", + "format": "int32", + "nullable": true, + "readOnly": true + }, + "modifiedBy": { + "type": "integer", + "format": "int32", + "nullable": true, + "readOnly": true + }, + "createdAt": { + "type": "string", + "format": "date-time", + "readOnly": true + }, + "modifiedAt": { + "type": "string", + "format": "date-time", + "readOnly": true } } } @@ -497,6 +809,66 @@ } } } + }, + "404": { + "description": "Not Found", + "content": { + "text/plain": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + }, + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "400": { + "description": "Bad Request", + "content": { + "text/plain": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + }, + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "500": { + "description": "Server Error", + "content": { + "text/plain": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + }, + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } } } }, @@ -544,6 +916,66 @@ } } } + }, + "404": { + "description": "Not Found", + "content": { + "text/plain": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + }, + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "400": { + "description": "Bad Request", + "content": { + "text/plain": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + }, + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "500": { + "description": "Server Error", + "content": { + "text/plain": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + }, + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } } } } @@ -594,26 +1026,6 @@ } } }, - "404": { - "description": "Not Found", - "content": { - "text/plain": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - }, - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - }, - "text/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - } - } - }, "400": { "description": "Bad Request", "content": { @@ -676,405 +1088,24 @@ "responses": { "200": { "description": "Success" - }, - "400": { - "description": "Bad Request", - "content": { - "text/plain": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - }, - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - }, - "text/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - } - } - }, - "500": { - "description": "Server Error", - "content": { - "text/plain": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - }, - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - }, - "text/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - } - } } } } }, - "/api/v{api-version}/ExternalClaimForwardings/getByIdentityProviderId/{identityProviderId}": { + "/api/v{api-version}/IdentityProviders/icon/{name}": { "get": { "tags": [ - "ExternalClaimForwardings" + "IdentityProviders" ], - "operationId": "GetByIdentityProviderId", + "operationId": "GetIcon", "parameters": [ { - "name": "identityProviderId", - "in": "path", - "required": true, - "schema": { - "type": "integer", - "format": "int32" - } - }, - { - "name": "api-version", + "name": "name", "in": "path", "required": true, "schema": { "type": "string" } - } - ], - "responses": { - "200": { - "description": "Success", - "content": { - "text/plain": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ExternalClaimForwarding" - } - } - }, - "application/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ExternalClaimForwarding" - } - } - }, - "text/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ExternalClaimForwarding" - } - } - } - } - }, - "404": { - "description": "Not Found", - "content": { - "text/plain": { - "schema": { - "$ref": "#/components/schemas/ProblemDetails" - } - }, - "application/json": { - "schema": { - "$ref": "#/components/schemas/ProblemDetails" - } - }, - "text/json": { - "schema": { - "$ref": "#/components/schemas/ProblemDetails" - } - } - } - }, - "500": { - "description": "Server Error", - "content": { - "text/plain": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - }, - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - }, - "text/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - } - } - } - } - } - }, - "/api/v{api-version}/ExternalClaimForwardings": { - "post": { - "tags": [ - "ExternalClaimForwardings" - ], - "operationId": "Create", - "parameters": [ - { - "name": "api-version", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - } - ], - "requestBody": { - "content": { - "application/json-patch+json": { - "schema": { - "$ref": "#/components/schemas/ExternalClaimForwarding" - } - }, - "application/json": { - "schema": { - "$ref": "#/components/schemas/ExternalClaimForwarding" - } - }, - "text/json": { - "schema": { - "$ref": "#/components/schemas/ExternalClaimForwarding" - } - }, - "application/*+json": { - "schema": { - "$ref": "#/components/schemas/ExternalClaimForwarding" - } - } - } - }, - "responses": { - "200": { - "description": "Success", - "content": { - "text/plain": { - "schema": { - "$ref": "#/components/schemas/ExternalClaimForwarding" - } - }, - "application/json": { - "schema": { - "$ref": "#/components/schemas/ExternalClaimForwarding" - } - }, - "text/json": { - "schema": { - "$ref": "#/components/schemas/ExternalClaimForwarding" - } - } - } - } - } - }, - "get": { - "tags": [ - "ExternalClaimForwardings" - ], - "operationId": "Get", - "parameters": [ - { - "name": "api-version", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "Success", - "content": { - "text/plain": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ExternalClaimForwarding" - } - } - }, - "application/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ExternalClaimForwarding" - } - } - }, - "text/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ExternalClaimForwarding" - } - } - } - } - }, - "404": { - "description": "Not Found", - "content": { - "text/plain": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - }, - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - }, - "text/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - } - } - }, - "400": { - "description": "Bad Request", - "content": { - "text/plain": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - }, - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - }, - "text/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - } - } - }, - "500": { - "description": "Server Error", - "content": { - "text/plain": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - }, - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - }, - "text/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - } - } - } - } - } - }, - "/api/v{api-version}/ExternalClaimForwardings/{id}": { - "put": { - "tags": [ - "ExternalClaimForwardings" - ], - "operationId": "Update", - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "schema": { - "type": "integer", - "format": "int32" - } - }, - { - "name": "api-version", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - } - ], - "requestBody": { - "content": { - "application/json-patch+json": { - "schema": { - "$ref": "#/components/schemas/ExternalClaimForwarding" - } - }, - "application/json": { - "schema": { - "$ref": "#/components/schemas/ExternalClaimForwarding" - } - }, - "text/json": { - "schema": { - "$ref": "#/components/schemas/ExternalClaimForwarding" - } - }, - "application/*+json": { - "schema": { - "$ref": "#/components/schemas/ExternalClaimForwarding" - } - } - } - }, - "responses": { - "200": { - "description": "Success", - "content": { - "text/plain": { - "schema": { - "$ref": "#/components/schemas/ExternalClaimForwarding" - } - }, - "application/json": { - "schema": { - "$ref": "#/components/schemas/ExternalClaimForwarding" - } - }, - "text/json": { - "schema": { - "$ref": "#/components/schemas/ExternalClaimForwarding" - } - } - } - } - } - }, - "delete": { - "tags": [ - "ExternalClaimForwardings" - ], - "operationId": "Delete", - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "schema": { - "type": "integer", - "format": "int32" - } }, { "name": "api-version", @@ -1088,469 +1119,29 @@ "responses": { "200": { "description": "Success" - } - } - }, - "get": { - "tags": [ - "ExternalClaimForwardings" - ], - "operationId": "Get", - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "schema": { - "type": "integer", - "format": "int32" - } }, - { - "name": "api-version", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "Success", - "content": { - "text/plain": { - "schema": { - "$ref": "#/components/schemas/ExternalClaimForwarding" - } - }, - "application/json": { - "schema": { - "$ref": "#/components/schemas/ExternalClaimForwarding" - } - }, - "text/json": { - "schema": { - "$ref": "#/components/schemas/ExternalClaimForwarding" - } - } - } - } - } - } - }, - "/api/v{api-version}/ExternalClaimMappings/getByIdentityProviderId/{identityProviderId}": { - "get": { - "tags": [ - "ExternalClaimMappings" - ], - "operationId": "GetByIdentityProviderId", - "parameters": [ - { - "name": "identityProviderId", - "in": "path", - "required": true, - "schema": { - "type": "integer", - "format": "int32" - } - }, - { - "name": "api-version", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "Success", - "content": { - "text/plain": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ExternalClaimMapping" - } - } - }, - "application/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ExternalClaimMapping" - } - } - }, - "text/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ExternalClaimMapping" - } - } - } - } - }, - "404": { - "description": "Not Found", - "content": { - "text/plain": { - "schema": { - "$ref": "#/components/schemas/ProblemDetails" - } - }, - "application/json": { - "schema": { - "$ref": "#/components/schemas/ProblemDetails" - } - }, - "text/json": { - "schema": { - "$ref": "#/components/schemas/ProblemDetails" - } - } - } - }, - "500": { - "description": "Server Error", - "content": { - "text/plain": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - }, - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - }, - "text/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - } - } - } - } - } - }, - "/api/v{api-version}/ExternalClaimMappings": { - "post": { - "tags": [ - "ExternalClaimMappings" - ], - "operationId": "Create", - "parameters": [ - { - "name": "api-version", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - } - ], - "requestBody": { - "content": { - "application/json-patch+json": { - "schema": { - "$ref": "#/components/schemas/ExternalClaimMapping" - } - }, - "application/json": { - "schema": { - "$ref": "#/components/schemas/ExternalClaimMapping" - } - }, - "text/json": { - "schema": { - "$ref": "#/components/schemas/ExternalClaimMapping" - } - }, - "application/*+json": { - "schema": { - "$ref": "#/components/schemas/ExternalClaimMapping" - } - } - } - }, - "responses": { - "200": { - "description": "Success", - "content": { - "text/plain": { - "schema": { - "$ref": "#/components/schemas/ExternalClaimMapping" - } - }, - "application/json": { - "schema": { - "$ref": "#/components/schemas/ExternalClaimMapping" - } - }, - "text/json": { - "schema": { - "$ref": "#/components/schemas/ExternalClaimMapping" - } - } - } - } - } - }, - "get": { - "tags": [ - "ExternalClaimMappings" - ], - "operationId": "Get", - "parameters": [ - { - "name": "api-version", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "Success", - "content": { - "text/plain": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ExternalClaimMapping" - } - } - }, - "application/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ExternalClaimMapping" - } - } - }, - "text/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ExternalClaimMapping" - } - } - } - } - }, - "404": { - "description": "Not Found", - "content": { - "text/plain": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - }, - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - }, - "text/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - } - } - }, - "400": { - "description": "Bad Request", - "content": { - "text/plain": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - }, - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - }, - "text/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - } - } - }, - "500": { - "description": "Server Error", - "content": { - "text/plain": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - }, - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - }, - "text/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - } - } - } - } - } - }, - "/api/v{api-version}/ExternalClaimMappings/{id}": { - "put": { - "tags": [ - "ExternalClaimMappings" - ], - "operationId": "Update", - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "schema": { - "type": "integer", - "format": "int32" - } - }, - { - "name": "api-version", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - } - ], - "requestBody": { - "content": { - "application/json-patch+json": { - "schema": { - "$ref": "#/components/schemas/ExternalClaimMapping" - } - }, - "application/json": { - "schema": { - "$ref": "#/components/schemas/ExternalClaimMapping" - } - }, - "text/json": { - "schema": { - "$ref": "#/components/schemas/ExternalClaimMapping" - } - }, - "application/*+json": { - "schema": { - "$ref": "#/components/schemas/ExternalClaimMapping" - } - } - } - }, - "responses": { - "200": { - "description": "Success", - "content": { - "text/plain": { - "schema": { - "$ref": "#/components/schemas/ExternalClaimMapping" - } - }, - "application/json": { - "schema": { - "$ref": "#/components/schemas/ExternalClaimMapping" - } - }, - "text/json": { - "schema": { - "$ref": "#/components/schemas/ExternalClaimMapping" - } - } - } - } - } - }, - "delete": { - "tags": [ - "ExternalClaimMappings" - ], - "operationId": "Delete", - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "schema": { - "type": "integer", - "format": "int32" - } - }, - { - "name": "api-version", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { + "204": { "description": "Success" - } - } - }, - "get": { - "tags": [ - "ExternalClaimMappings" - ], - "operationId": "Get", - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "schema": { - "type": "integer", - "format": "int32" - } }, - { - "name": "api-version", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "Success", + "206": { + "description": "Success" + }, + "416": { + "description": "Client Error", "content": { "text/plain": { "schema": { - "$ref": "#/components/schemas/ExternalClaimMapping" + "$ref": "#/components/schemas/ProblemDetails" } }, "application/json": { "schema": { - "$ref": "#/components/schemas/ExternalClaimMapping" + "$ref": "#/components/schemas/ProblemDetails" } }, "text/json": { "schema": { - "$ref": "#/components/schemas/ExternalClaimMapping" + "$ref": "#/components/schemas/ProblemDetails" } } } @@ -1604,26 +1195,6 @@ } } }, - "404": { - "description": "Not Found", - "content": { - "text/plain": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - }, - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - }, - "text/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - } - } - }, "400": { "description": "Bad Request", "content": { @@ -1711,6 +1282,66 @@ } } } + }, + "404": { + "description": "Not Found", + "content": { + "text/plain": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + }, + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "400": { + "description": "Bad Request", + "content": { + "text/plain": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + }, + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "500": { + "description": "Server Error", + "content": { + "text/plain": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + }, + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } } } } @@ -1756,7 +1387,7 @@ } }, "responses": { - "200": { + "201": { "description": "Success", "content": { "text/plain": { @@ -1775,6 +1406,46 @@ } } } + }, + "400": { + "description": "Bad Request", + "content": { + "text/plain": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + }, + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "500": { + "description": "Server Error", + "content": { + "text/plain": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + }, + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } } } }, @@ -1823,26 +1494,6 @@ } } }, - "404": { - "description": "Not Found", - "content": { - "text/plain": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - }, - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - }, - "text/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - } - } - }, "400": { "description": "Bad Request", "content": { @@ -1955,6 +1606,66 @@ } } } + }, + "404": { + "description": "Not Found", + "content": { + "text/plain": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + }, + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "400": { + "description": "Bad Request", + "content": { + "text/plain": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + }, + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "500": { + "description": "Server Error", + "content": { + "text/plain": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + }, + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } } } }, @@ -1983,8 +1694,68 @@ } ], "responses": { - "200": { + "204": { "description": "Success" + }, + "404": { + "description": "Not Found", + "content": { + "text/plain": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + }, + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "400": { + "description": "Bad Request", + "content": { + "text/plain": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + }, + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "500": { + "description": "Server Error", + "content": { + "text/plain": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + }, + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } } } }, @@ -2032,6 +1803,614 @@ } } } + }, + "404": { + "description": "Not Found", + "content": { + "text/plain": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + }, + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "400": { + "description": "Bad Request", + "content": { + "text/plain": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + }, + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "500": { + "description": "Server Error", + "content": { + "text/plain": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + }, + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + } + } + } + }, + "/api/v{api-version}/ServiceAccounts": { + "get": { + "tags": [ + "ServiceAccounts" + ], + "operationId": "Get", + "parameters": [ + { + "name": "api-version", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Success", + "content": { + "text/plain": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ServiceAccount" + } + } + }, + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ServiceAccount" + } + } + }, + "text/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ServiceAccount" + } + } + } + } + }, + "400": { + "description": "Bad Request", + "content": { + "text/plain": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + }, + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "500": { + "description": "Server Error", + "content": { + "text/plain": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + }, + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + } + } + } + }, + "/api/v{api-version}/ServiceAccounts/{id}": { + "get": { + "tags": [ + "ServiceAccounts" + ], + "operationId": "Get", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + }, + { + "name": "api-version", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Success", + "content": { + "text/plain": { + "schema": { + "$ref": "#/components/schemas/ServiceAccount" + } + }, + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceAccount" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/ServiceAccount" + } + } + } + }, + "404": { + "description": "Not Found", + "content": { + "text/plain": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + }, + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "400": { + "description": "Bad Request", + "content": { + "text/plain": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + }, + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "500": { + "description": "Server Error", + "content": { + "text/plain": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + }, + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + } + } + } + }, + "/api/v{api-version}/ServiceAccounts/{serviceAccountId}/generateClientSecret": { + "post": { + "tags": [ + "ServiceAccounts" + ], + "operationId": "GenerateClientSecret", + "parameters": [ + { + "name": "serviceAccountId", + "in": "path", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + }, + { + "name": "api-version", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Success", + "content": { + "text/plain": { + "schema": { + "$ref": "#/components/schemas/UserClientSecret" + } + }, + "application/json": { + "schema": { + "$ref": "#/components/schemas/UserClientSecret" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/UserClientSecret" + } + } + } + }, + "404": { + "description": "Not Found", + "content": { + "text/plain": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + }, + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "400": { + "description": "Bad Request", + "content": { + "text/plain": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + }, + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "500": { + "description": "Server Error", + "content": { + "text/plain": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + }, + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + } + } + } + }, + "/api/v{api-version}/ServiceAccounts/{serviceAccountId}/clientSecrets/{secretId}": { + "put": { + "tags": [ + "ServiceAccounts" + ], + "operationId": "UpdateClientSecret", + "parameters": [ + { + "name": "secretId", + "in": "path", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + }, + { + "name": "serviceAccountId", + "in": "path", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + }, + { + "name": "api-version", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json-patch+json": { + "schema": { + "$ref": "#/components/schemas/UserClientSecret" + } + }, + "application/json": { + "schema": { + "$ref": "#/components/schemas/UserClientSecret" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/UserClientSecret" + } + }, + "application/*+json": { + "schema": { + "$ref": "#/components/schemas/UserClientSecret" + } + } + } + }, + "responses": { + "200": { + "description": "Success", + "content": { + "text/plain": { + "schema": { + "$ref": "#/components/schemas/UserClientSecret" + } + }, + "application/json": { + "schema": { + "$ref": "#/components/schemas/UserClientSecret" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/UserClientSecret" + } + } + } + }, + "404": { + "description": "Not Found", + "content": { + "text/plain": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + }, + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "400": { + "description": "Bad Request", + "content": { + "text/plain": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + }, + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "500": { + "description": "Server Error", + "content": { + "text/plain": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + }, + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + } + } + }, + "delete": { + "tags": [ + "ServiceAccounts" + ], + "operationId": "DeleteClientSecret", + "parameters": [ + { + "name": "serviceAccountId", + "in": "path", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + }, + { + "name": "secretId", + "in": "path", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + }, + { + "name": "api-version", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "204": { + "description": "Success" + }, + "404": { + "description": "Not Found", + "content": { + "text/plain": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + }, + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "400": { + "description": "Bad Request", + "content": { + "text/plain": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + }, + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "500": { + "description": "Server Error", + "content": { + "text/plain": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + }, + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } } } } @@ -2089,26 +2468,6 @@ } } }, - "404": { - "description": "Not Found", - "content": { - "text/plain": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - }, - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - }, - "text/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - } - } - }, "400": { "description": "Bad Request", "content": { @@ -2152,376 +2511,6 @@ } } }, - "/api/v{api-version}/UserMappings/getByUserId/{userId}": { - "get": { - "tags": [ - "UserMappings" - ], - "operationId": "GetByUserId", - "parameters": [ - { - "name": "userId", - "in": "path", - "required": true, - "schema": { - "type": "integer", - "format": "int32" - } - }, - { - "name": "api-version", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "Success", - "content": { - "text/plain": { - "schema": { - "$ref": "#/components/schemas/UserMapping" - } - }, - "application/json": { - "schema": { - "$ref": "#/components/schemas/UserMapping" - } - }, - "text/json": { - "schema": { - "$ref": "#/components/schemas/UserMapping" - } - } - } - } - } - } - }, - "/api/v{api-version}/UserMappings": { - "post": { - "tags": [ - "UserMappings" - ], - "operationId": "Create", - "parameters": [ - { - "name": "api-version", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - } - ], - "requestBody": { - "content": { - "application/json-patch+json": { - "schema": { - "$ref": "#/components/schemas/UserMapping" - } - }, - "application/json": { - "schema": { - "$ref": "#/components/schemas/UserMapping" - } - }, - "text/json": { - "schema": { - "$ref": "#/components/schemas/UserMapping" - } - }, - "application/*+json": { - "schema": { - "$ref": "#/components/schemas/UserMapping" - } - } - } - }, - "responses": { - "200": { - "description": "Success", - "content": { - "text/plain": { - "schema": { - "$ref": "#/components/schemas/UserMapping" - } - }, - "application/json": { - "schema": { - "$ref": "#/components/schemas/UserMapping" - } - }, - "text/json": { - "schema": { - "$ref": "#/components/schemas/UserMapping" - } - } - } - } - } - }, - "get": { - "tags": [ - "UserMappings" - ], - "operationId": "Get", - "parameters": [ - { - "name": "api-version", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "Success", - "content": { - "text/plain": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/UserMapping" - } - } - }, - "application/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/UserMapping" - } - } - }, - "text/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/UserMapping" - } - } - } - } - }, - "404": { - "description": "Not Found", - "content": { - "text/plain": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - }, - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - }, - "text/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - } - } - }, - "400": { - "description": "Bad Request", - "content": { - "text/plain": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - }, - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - }, - "text/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - } - } - }, - "500": { - "description": "Server Error", - "content": { - "text/plain": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - }, - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - }, - "text/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - } - } - } - } - } - }, - "/api/v{api-version}/UserMappings/{id}": { - "put": { - "tags": [ - "UserMappings" - ], - "operationId": "Update", - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "schema": { - "type": "integer", - "format": "int32" - } - }, - { - "name": "api-version", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - } - ], - "requestBody": { - "content": { - "application/json-patch+json": { - "schema": { - "$ref": "#/components/schemas/UserMapping" - } - }, - "application/json": { - "schema": { - "$ref": "#/components/schemas/UserMapping" - } - }, - "text/json": { - "schema": { - "$ref": "#/components/schemas/UserMapping" - } - }, - "application/*+json": { - "schema": { - "$ref": "#/components/schemas/UserMapping" - } - } - } - }, - "responses": { - "200": { - "description": "Success", - "content": { - "text/plain": { - "schema": { - "$ref": "#/components/schemas/UserMapping" - } - }, - "application/json": { - "schema": { - "$ref": "#/components/schemas/UserMapping" - } - }, - "text/json": { - "schema": { - "$ref": "#/components/schemas/UserMapping" - } - } - } - } - } - }, - "delete": { - "tags": [ - "UserMappings" - ], - "operationId": "Delete", - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "schema": { - "type": "integer", - "format": "int32" - } - }, - { - "name": "api-version", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "Success" - } - } - }, - "get": { - "tags": [ - "UserMappings" - ], - "operationId": "Get", - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "schema": { - "type": "integer", - "format": "int32" - } - }, - { - "name": "api-version", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "Success", - "content": { - "text/plain": { - "schema": { - "$ref": "#/components/schemas/UserMapping" - } - }, - "application/json": { - "schema": { - "$ref": "#/components/schemas/UserMapping" - } - }, - "text/json": { - "schema": { - "$ref": "#/components/schemas/UserMapping" - } - } - } - } - } - } - }, "/api/v{api-version}/Users/{userId}/generateClientSecret": { "post": { "tags": [ @@ -2573,17 +2562,37 @@ "content": { "text/plain": { "schema": { - "$ref": "#/components/schemas/ProblemDetails" + "$ref": "#/components/schemas/ErrorResponse" } }, "application/json": { "schema": { - "$ref": "#/components/schemas/ProblemDetails" + "$ref": "#/components/schemas/ErrorResponse" } }, "text/json": { "schema": { - "$ref": "#/components/schemas/ProblemDetails" + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "400": { + "description": "Bad Request", + "content": { + "text/plain": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + }, + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" } } } @@ -2690,42 +2699,42 @@ } } }, - "400": { - "description": "Bad Request", - "content": { - "text/plain": { - "schema": { - "$ref": "#/components/schemas/ProblemDetails" - } - }, - "application/json": { - "schema": { - "$ref": "#/components/schemas/ProblemDetails" - } - }, - "text/json": { - "schema": { - "$ref": "#/components/schemas/ProblemDetails" - } - } - } - }, "404": { "description": "Not Found", "content": { "text/plain": { "schema": { - "$ref": "#/components/schemas/ProblemDetails" + "$ref": "#/components/schemas/ErrorResponse" } }, "application/json": { "schema": { - "$ref": "#/components/schemas/ProblemDetails" + "$ref": "#/components/schemas/ErrorResponse" } }, "text/json": { "schema": { - "$ref": "#/components/schemas/ProblemDetails" + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "400": { + "description": "Bad Request", + "content": { + "text/plain": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + }, + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" } } } @@ -2789,245 +2798,6 @@ "204": { "description": "Success" }, - "404": { - "description": "Not Found", - "content": { - "text/plain": { - "schema": { - "$ref": "#/components/schemas/ProblemDetails" - } - }, - "application/json": { - "schema": { - "$ref": "#/components/schemas/ProblemDetails" - } - }, - "text/json": { - "schema": { - "$ref": "#/components/schemas/ProblemDetails" - } - } - } - }, - "500": { - "description": "Server Error", - "content": { - "text/plain": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - }, - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - }, - "text/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - } - } - } - } - } - }, - "/api/v{api-version}/Users/getByClientId/{clientId}": { - "get": { - "tags": [ - "Users" - ], - "operationId": "GetByClientId", - "parameters": [ - { - "name": "clientId", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - }, - { - "name": "api-version", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "Success", - "content": { - "text/plain": { - "schema": { - "$ref": "#/components/schemas/User" - } - }, - "application/json": { - "schema": { - "$ref": "#/components/schemas/User" - } - }, - "text/json": { - "schema": { - "$ref": "#/components/schemas/User" - } - } - } - }, - "404": { - "description": "Not Found", - "content": { - "text/plain": { - "schema": { - "$ref": "#/components/schemas/ProblemDetails" - } - }, - "application/json": { - "schema": { - "$ref": "#/components/schemas/ProblemDetails" - } - }, - "text/json": { - "schema": { - "$ref": "#/components/schemas/ProblemDetails" - } - } - } - }, - "500": { - "description": "Server Error", - "content": { - "text/plain": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - }, - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - }, - "text/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - } - } - } - } - } - }, - "/api/v{api-version}/Users": { - "post": { - "tags": [ - "Users" - ], - "operationId": "Create", - "parameters": [ - { - "name": "api-version", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - } - ], - "requestBody": { - "content": { - "application/json-patch+json": { - "schema": { - "$ref": "#/components/schemas/User" - } - }, - "application/json": { - "schema": { - "$ref": "#/components/schemas/User" - } - }, - "text/json": { - "schema": { - "$ref": "#/components/schemas/User" - } - }, - "application/*+json": { - "schema": { - "$ref": "#/components/schemas/User" - } - } - } - }, - "responses": { - "200": { - "description": "Success", - "content": { - "text/plain": { - "schema": { - "$ref": "#/components/schemas/User" - } - }, - "application/json": { - "schema": { - "$ref": "#/components/schemas/User" - } - }, - "text/json": { - "schema": { - "$ref": "#/components/schemas/User" - } - } - } - } - } - }, - "get": { - "tags": [ - "Users" - ], - "operationId": "Get", - "parameters": [ - { - "name": "api-version", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "Success", - "content": { - "text/plain": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/User" - } - } - }, - "application/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/User" - } - } - }, - "text/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/User" - } - } - } - } - }, "404": { "description": "Not Found", "content": { @@ -3120,22 +2890,462 @@ "content": { "application/json-patch+json": { "schema": { - "$ref": "#/components/schemas/User" + "title": "User", + "required": [ + "identityProviderId", + "identityProviderKey", + "name", + "subject" + ], + "type": "object", + "properties": { + "name": { + "maxLength": 256, + "type": "string", + "nullable": true + }, + "email": { + "maxLength": 256, + "type": "string", + "format": "email", + "nullable": true + }, + "subject": { + "maxLength": 256, + "type": "string", + "nullable": true + }, + "identityProviderId": { + "type": "integer", + "format": "int32", + "readOnly": true + }, + "identityProviderKey": { + "maxLength": 256, + "type": "string", + "nullable": true, + "readOnly": true + }, + "clientId": { + "type": "string", + "nullable": true, + "readOnly": true + }, + "lastLoginAt": { + "type": "string", + "format": "date-time", + "nullable": true, + "readOnly": true + }, + "clientSecrets": { + "maxLength": 2, + "type": "array", + "items": { + "$ref": "#/components/schemas/UserClientSecret" + }, + "nullable": true, + "readOnly": true + }, + "accessControlEntry": { + "title": "UserBasedAccessControlEntry", + "type": "object", + "properties": { + "applications": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ApplicationLink" + }, + "nullable": true + }, + "apiResources": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ApiResourceLink" + }, + "nullable": true + }, + "apiResourceRoles": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ApiResourceRoleLink" + }, + "nullable": true + } + } + }, + "createdBy": { + "type": "integer", + "format": "int32", + "nullable": true, + "readOnly": true + }, + "modifiedBy": { + "type": "integer", + "format": "int32", + "nullable": true, + "readOnly": true + }, + "createdAt": { + "type": "string", + "format": "date-time", + "readOnly": true + }, + "modifiedAt": { + "type": "string", + "format": "date-time", + "readOnly": true + }, + "id": { + "type": "integer", + "format": "int32", + "readOnly": true + } + } } }, "application/json": { "schema": { - "$ref": "#/components/schemas/User" + "title": "User", + "required": [ + "identityProviderId", + "identityProviderKey", + "name", + "subject" + ], + "type": "object", + "properties": { + "name": { + "maxLength": 256, + "type": "string", + "nullable": true + }, + "email": { + "maxLength": 256, + "type": "string", + "format": "email", + "nullable": true + }, + "subject": { + "maxLength": 256, + "type": "string", + "nullable": true + }, + "identityProviderId": { + "type": "integer", + "format": "int32", + "readOnly": true + }, + "identityProviderKey": { + "maxLength": 256, + "type": "string", + "nullable": true, + "readOnly": true + }, + "clientId": { + "type": "string", + "nullable": true, + "readOnly": true + }, + "lastLoginAt": { + "type": "string", + "format": "date-time", + "nullable": true, + "readOnly": true + }, + "clientSecrets": { + "maxLength": 2, + "type": "array", + "items": { + "$ref": "#/components/schemas/UserClientSecret" + }, + "nullable": true, + "readOnly": true + }, + "accessControlEntry": { + "title": "UserBasedAccessControlEntry", + "type": "object", + "properties": { + "applications": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ApplicationLink" + }, + "nullable": true + }, + "apiResources": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ApiResourceLink" + }, + "nullable": true + }, + "apiResourceRoles": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ApiResourceRoleLink" + }, + "nullable": true + } + } + }, + "createdBy": { + "type": "integer", + "format": "int32", + "nullable": true, + "readOnly": true + }, + "modifiedBy": { + "type": "integer", + "format": "int32", + "nullable": true, + "readOnly": true + }, + "createdAt": { + "type": "string", + "format": "date-time", + "readOnly": true + }, + "modifiedAt": { + "type": "string", + "format": "date-time", + "readOnly": true + }, + "id": { + "type": "integer", + "format": "int32", + "readOnly": true + } + } } }, "text/json": { "schema": { - "$ref": "#/components/schemas/User" + "title": "User", + "required": [ + "identityProviderId", + "identityProviderKey", + "name", + "subject" + ], + "type": "object", + "properties": { + "name": { + "maxLength": 256, + "type": "string", + "nullable": true + }, + "email": { + "maxLength": 256, + "type": "string", + "format": "email", + "nullable": true + }, + "subject": { + "maxLength": 256, + "type": "string", + "nullable": true + }, + "identityProviderId": { + "type": "integer", + "format": "int32", + "readOnly": true + }, + "identityProviderKey": { + "maxLength": 256, + "type": "string", + "nullable": true, + "readOnly": true + }, + "clientId": { + "type": "string", + "nullable": true, + "readOnly": true + }, + "lastLoginAt": { + "type": "string", + "format": "date-time", + "nullable": true, + "readOnly": true + }, + "clientSecrets": { + "maxLength": 2, + "type": "array", + "items": { + "$ref": "#/components/schemas/UserClientSecret" + }, + "nullable": true, + "readOnly": true + }, + "accessControlEntry": { + "title": "UserBasedAccessControlEntry", + "type": "object", + "properties": { + "applications": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ApplicationLink" + }, + "nullable": true + }, + "apiResources": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ApiResourceLink" + }, + "nullable": true + }, + "apiResourceRoles": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ApiResourceRoleLink" + }, + "nullable": true + } + } + }, + "createdBy": { + "type": "integer", + "format": "int32", + "nullable": true, + "readOnly": true + }, + "modifiedBy": { + "type": "integer", + "format": "int32", + "nullable": true, + "readOnly": true + }, + "createdAt": { + "type": "string", + "format": "date-time", + "readOnly": true + }, + "modifiedAt": { + "type": "string", + "format": "date-time", + "readOnly": true + }, + "id": { + "type": "integer", + "format": "int32", + "readOnly": true + } + } } }, "application/*+json": { "schema": { - "$ref": "#/components/schemas/User" + "title": "User", + "required": [ + "identityProviderId", + "identityProviderKey", + "name", + "subject" + ], + "type": "object", + "properties": { + "name": { + "maxLength": 256, + "type": "string", + "nullable": true + }, + "email": { + "maxLength": 256, + "type": "string", + "format": "email", + "nullable": true + }, + "subject": { + "maxLength": 256, + "type": "string", + "nullable": true + }, + "identityProviderId": { + "type": "integer", + "format": "int32", + "readOnly": true + }, + "identityProviderKey": { + "maxLength": 256, + "type": "string", + "nullable": true, + "readOnly": true + }, + "clientId": { + "type": "string", + "nullable": true, + "readOnly": true + }, + "lastLoginAt": { + "type": "string", + "format": "date-time", + "nullable": true, + "readOnly": true + }, + "clientSecrets": { + "maxLength": 2, + "type": "array", + "items": { + "$ref": "#/components/schemas/UserClientSecret" + }, + "nullable": true, + "readOnly": true + }, + "accessControlEntry": { + "title": "UserBasedAccessControlEntry", + "type": "object", + "properties": { + "applications": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ApplicationLink" + }, + "nullable": true + }, + "apiResources": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ApiResourceLink" + }, + "nullable": true + }, + "apiResourceRoles": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ApiResourceRoleLink" + }, + "nullable": true + } + } + }, + "createdBy": { + "type": "integer", + "format": "int32", + "nullable": true, + "readOnly": true + }, + "modifiedBy": { + "type": "integer", + "format": "int32", + "nullable": true, + "readOnly": true + }, + "createdAt": { + "type": "string", + "format": "date-time", + "readOnly": true + }, + "modifiedAt": { + "type": "string", + "format": "date-time", + "readOnly": true + }, + "id": { + "type": "integer", + "format": "int32", + "readOnly": true + } + } } } } @@ -3160,6 +3370,66 @@ } } } + }, + "404": { + "description": "Not Found", + "content": { + "text/plain": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + }, + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "400": { + "description": "Bad Request", + "content": { + "text/plain": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + }, + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "500": { + "description": "Server Error", + "content": { + "text/plain": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + }, + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } } } }, @@ -3188,8 +3458,68 @@ } ], "responses": { - "200": { + "204": { "description": "Success" + }, + "404": { + "description": "Not Found", + "content": { + "text/plain": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + }, + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "400": { + "description": "Bad Request", + "content": { + "text/plain": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + }, + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "500": { + "description": "Server Error", + "content": { + "text/plain": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + }, + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } } } }, @@ -3237,6 +3567,257 @@ } } } + }, + "404": { + "description": "Not Found", + "content": { + "text/plain": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + }, + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "400": { + "description": "Bad Request", + "content": { + "text/plain": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + }, + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "500": { + "description": "Server Error", + "content": { + "text/plain": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + }, + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + } + } + } + }, + "/api/v{api-version}/Users": { + "post": { + "tags": [ + "Users" + ], + "operationId": "Create", + "parameters": [ + { + "name": "api-version", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json-patch+json": { + "schema": { + "$ref": "#/components/schemas/User" + } + }, + "application/json": { + "schema": { + "$ref": "#/components/schemas/User" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/User" + } + }, + "application/*+json": { + "schema": { + "$ref": "#/components/schemas/User" + } + } + } + }, + "responses": { + "201": { + "description": "Success", + "content": { + "text/plain": { + "schema": { + "$ref": "#/components/schemas/User" + } + }, + "application/json": { + "schema": { + "$ref": "#/components/schemas/User" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/User" + } + } + } + }, + "400": { + "description": "Bad Request", + "content": { + "text/plain": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + }, + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "500": { + "description": "Server Error", + "content": { + "text/plain": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + }, + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + } + } + }, + "get": { + "tags": [ + "Users" + ], + "operationId": "Get", + "parameters": [ + { + "name": "api-version", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Success", + "content": { + "text/plain": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/User" + } + } + }, + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/User" + } + } + }, + "text/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/User" + } + } + } + } + }, + "400": { + "description": "Bad Request", + "content": { + "text/plain": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + }, + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "500": { + "description": "Server Error", + "content": { + "text/plain": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + }, + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } } } } @@ -3391,13 +3972,92 @@ "type": "string" }, "nullable": true + }, + "createdBy": { + "type": "integer", + "format": "int32", + "nullable": true, + "readOnly": true + }, + "modifiedBy": { + "type": "integer", + "format": "int32", + "nullable": true, + "readOnly": true + }, + "createdAt": { + "type": "string", + "format": "date-time", + "readOnly": true + }, + "modifiedAt": { + "type": "string", + "format": "date-time", + "readOnly": true + } + }, + "additionalProperties": false + }, + "ProblemDetails": { + "type": "object", + "properties": { + "type": { + "type": "string", + "nullable": true + }, + "title": { + "type": "string", + "nullable": true + }, + "status": { + "type": "integer", + "format": "int32", + "nullable": true + }, + "detail": { + "type": "string", + "nullable": true + }, + "instance": { + "type": "string", + "nullable": true + }, + "extensions": { + "type": "object", + "additionalProperties": { + "type": "object", + "additionalProperties": false + }, + "nullable": true, + "readOnly": true + } + }, + "additionalProperties": false + }, + "LoginOption": { + "required": [ + "name" + ], + "type": "object", + "properties": { + "name": { + "maxLength": 256, + "type": "string", + "nullable": true + }, + "loginTriggerUrl": { + "type": "string", + "nullable": true + }, + "iconUrl": { + "type": "string", + "nullable": true } }, "additionalProperties": false }, "IdentityProviderType": { "enum": [ - "InternalUserClientStorage", "OpenIdConnect", "SAML2P", "LDAP", @@ -3405,8 +4065,289 @@ ], "type": "string" }, + "OpenIdParameters": { + "required": [ + "authority", + "clientId", + "fullNameClaim", + "usernameClaim" + ], + "type": "object", + "properties": { + "clientId": { + "maxLength": 256, + "type": "string", + "nullable": true + }, + "authority": { + "maxLength": 256, + "type": "string", + "nullable": true + }, + "clientSecret": { + "maxLength": 256, + "type": "string", + "nullable": true + }, + "endSessionEndpoint": { + "maxLength": 256, + "type": "string", + "nullable": true + }, + "sendIdTokenHintDuringLogout": { + "type": "boolean" + }, + "separator": { + "maxLength": 1, + "type": "string", + "nullable": true + }, + "usernameClaim": { + "maxLength": 256, + "type": "string", + "nullable": true + }, + "fullNameClaim": { + "maxLength": 256, + "type": "string", + "nullable": true + } + }, + "additionalProperties": false + }, + "SamlParameters": { + "required": [ + "certificates", + "fullNameClaim", + "issuerName", + "serviceProviderName", + "singleLogoutServiceUrl", + "singleSignOnServiceUrl", + "usernameClaim" + ], + "type": "object", + "properties": { + "issuerName": { + "maxLength": 256, + "type": "string", + "nullable": true + }, + "serviceProviderName": { + "maxLength": 256, + "type": "string", + "nullable": true + }, + "singleSignOnServiceUrl": { + "maxLength": 256, + "type": "string", + "nullable": true + }, + "singleLogoutServiceUrl": { + "maxLength": 256, + "type": "string", + "nullable": true + }, + "certificates": { + "minLength": 1, + "type": "array", + "items": { + "type": "string" + }, + "nullable": true + }, + "separator": { + "maxLength": 1, + "type": "string", + "nullable": true + }, + "usernameClaim": { + "maxLength": 256, + "type": "string", + "nullable": true + }, + "fullNameClaim": { + "maxLength": 256, + "type": "string", + "nullable": true + } + }, + "additionalProperties": false + }, + "LdapParameters": { + "required": [ + "fullNameClaim", + "port", + "searchAccount", + "searchAccountPassword", + "serverAddress", + "userBaseDn", + "usernameClaim", + "useSsl" + ], + "type": "object", + "properties": { + "serverAddress": { + "maxLength": 256, + "type": "string", + "nullable": true + }, + "port": { + "type": "integer", + "format": "int32" + }, + "useSsl": { + "type": "boolean" + }, + "searchAccount": { + "maxLength": 256, + "type": "string", + "nullable": true + }, + "searchAccountPassword": { + "maxLength": 256, + "type": "string", + "nullable": true + }, + "userBaseDn": { + "maxLength": 256, + "type": "string", + "nullable": true + }, + "groupBaseDn": { + "maxLength": 256, + "type": "string", + "nullable": true + }, + "groupMemberAttribute": { + "maxLength": 256, + "type": "string", + "nullable": true + }, + "additionalAttributes": { + "maxLength": 256, + "type": "string", + "nullable": true + }, + "separator": { + "maxLength": 1, + "type": "string", + "nullable": true + }, + "usernameClaim": { + "maxLength": 256, + "type": "string", + "nullable": true + }, + "fullNameClaim": { + "maxLength": 256, + "type": "string", + "nullable": true + } + }, + "additionalProperties": false + }, + "WindowsParameters": { + "type": "object", + "additionalProperties": false + }, "IdentityProviderParameters": { "type": "object", + "oneOf": [ + { + "$ref": "#/components/schemas/OpenIdParameters" + }, + { + "$ref": "#/components/schemas/SamlParameters" + }, + { + "$ref": "#/components/schemas/LdapParameters" + }, + { + "$ref": "#/components/schemas/WindowsParameters" + } + ], + "additionalProperties": false + }, + "ApplicationLink": { + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int32" + }, + "name": { + "type": "string", + "nullable": true, + "readOnly": true + } + }, + "additionalProperties": false + }, + "ApiResourceLink": { + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int32" + }, + "name": { + "type": "string", + "nullable": true, + "readOnly": true + } + }, + "additionalProperties": false + }, + "ApiResourceRoleLink": { + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int32" + }, + "name": { + "type": "string", + "nullable": true, + "readOnly": true + } + }, + "additionalProperties": false + }, + "ClaimBasedAccessControlEntry": { + "type": "object", + "properties": { + "claimType": { + "maxLength": 256, + "type": "string", + "nullable": true + }, + "claimValue": { + "maxLength": 256, + "type": "string", + "nullable": true + }, + "applications": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ApplicationLink" + }, + "nullable": true + }, + "apiResources": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ApiResourceLink" + }, + "nullable": true + }, + "apiResourceRoles": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ApiResourceRoleLink" + }, + "nullable": true + } + }, "additionalProperties": false }, "IdentityProvider": { @@ -3430,7 +4371,8 @@ "nullable": true }, "isEnabled": { - "type": "boolean" + "type": "boolean", + "default": true }, "description": { "maxLength": 2048, @@ -3444,6 +4386,25 @@ "type": "string", "nullable": true }, + "iconViewUrl": { + "type": "string", + "nullable": true, + "readOnly": true + }, + "accessControlList": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ClaimBasedAccessControlEntry" + }, + "nullable": true + }, + "forwardedClaims": { + "type": "array", + "items": { + "type": "string" + }, + "nullable": true + }, "parameters": { "$ref": "#/components/schemas/IdentityProviderParameters" }, @@ -3492,121 +4453,33 @@ }, "additionalProperties": false }, - "ExternalClaimForwarding": { + "UserClientSecret": { "required": [ - "claimType", - "identityProviderId" + "clientSecret", + "expiresAt" ], "type": "object", "properties": { - "identityProviderId": { - "type": "integer", - "format": "int32" - }, - "identityProvider": { - "title": "IdentityProvider", - "required": [ - "key", - "name", - "parameters", - "type" - ], - "type": "object", - "properties": { - "key": { - "maxLength": 64, - "pattern": "^[a-zA-Z0-9_]*$", - "type": "string", - "nullable": true, - "readOnly": true - }, - "name": { - "maxLength": 256, - "type": "string", - "nullable": true, - "readOnly": true - }, - "isEnabled": { - "type": "boolean", - "readOnly": true - }, - "description": { - "maxLength": 2048, - "type": "string", - "nullable": true, - "readOnly": true - }, - "type": { - "title": "IdentityProviderType", - "enum": [ - "InternalUserClientStorage", - "OpenIdConnect", - "SAML2P", - "LDAP", - "Windows" - ], - "type": "string", - "readOnly": true - }, - "iconUrl": { - "type": "string", - "nullable": true, - "readOnly": true - }, - "parameters": { - "title": "IdentityProviderParameters", - "type": "object", - "readOnly": true - }, - "redirectUrl": { - "type": "string", - "nullable": true, - "readOnly": true - }, - "postLogoutRedirectUrl": { - "type": "string", - "nullable": true, - "readOnly": true - }, - "validateUrl": { - "type": "string", - "nullable": true, - "readOnly": true - }, - "createdBy": { - "type": "integer", - "format": "int32", - "nullable": true, - "readOnly": true - }, - "modifiedBy": { - "type": "integer", - "format": "int32", - "nullable": true, - "readOnly": true - }, - "createdAt": { - "type": "string", - "format": "date-time", - "readOnly": true - }, - "modifiedAt": { - "type": "string", - "format": "date-time", - "readOnly": true - }, - "id": { - "type": "integer", - "format": "int32", - "readOnly": true - } - }, + "clientSecret": { + "maxLength": 4000, + "type": "string", + "nullable": true, "readOnly": true }, - "claimType": { - "maxLength": 256, + "clientSecretUnHashed": { "type": "string", - "nullable": true + "nullable": true, + "readOnly": true + }, + "expiresAt": { + "type": "string", + "format": "date-time" + }, + "lastLoginAt": { + "type": "string", + "format": "date-time", + "nullable": true, + "readOnly": true }, "id": { "type": "integer", @@ -3616,214 +4489,9 @@ }, "additionalProperties": false }, - "ProblemDetails": { + "ServiceAccountBasedAccessControlEntry": { "type": "object", "properties": { - "type": { - "type": "string", - "nullable": true - }, - "title": { - "type": "string", - "nullable": true - }, - "status": { - "type": "integer", - "format": "int32", - "nullable": true - }, - "detail": { - "type": "string", - "nullable": true - }, - "instance": { - "type": "string", - "nullable": true - }, - "extensions": { - "type": "object", - "additionalProperties": { - "type": "object", - "additionalProperties": false - }, - "nullable": true, - "readOnly": true - } - }, - "additionalProperties": false - }, - "ApplicationLink": { - "type": "object", - "properties": { - "id": { - "type": "integer", - "format": "int32" - }, - "name": { - "type": "string", - "nullable": true, - "readOnly": true - } - }, - "additionalProperties": false - }, - "ApiResourceLink": { - "type": "object", - "properties": { - "id": { - "type": "integer", - "format": "int32" - }, - "name": { - "type": "string", - "nullable": true, - "readOnly": true - } - }, - "additionalProperties": false - }, - "ApiResourceRoleLink": { - "type": "object", - "properties": { - "id": { - "type": "integer", - "format": "int32" - }, - "name": { - "type": "string", - "nullable": true, - "readOnly": true - } - }, - "additionalProperties": false - }, - "ExternalClaimMapping": { - "required": [ - "identityProviderId" - ], - "type": "object", - "properties": { - "identityProviderId": { - "type": "integer", - "format": "int32" - }, - "identityProvider": { - "title": "IdentityProvider", - "required": [ - "key", - "name", - "parameters", - "type" - ], - "type": "object", - "properties": { - "key": { - "maxLength": 64, - "pattern": "^[a-zA-Z0-9_]*$", - "type": "string", - "nullable": true, - "readOnly": true - }, - "name": { - "maxLength": 256, - "type": "string", - "nullable": true, - "readOnly": true - }, - "isEnabled": { - "type": "boolean", - "readOnly": true - }, - "description": { - "maxLength": 2048, - "type": "string", - "nullable": true, - "readOnly": true - }, - "type": { - "title": "IdentityProviderType", - "enum": [ - "InternalUserClientStorage", - "OpenIdConnect", - "SAML2P", - "LDAP", - "Windows" - ], - "type": "string", - "readOnly": true - }, - "iconUrl": { - "type": "string", - "nullable": true, - "readOnly": true - }, - "parameters": { - "title": "IdentityProviderParameters", - "type": "object", - "readOnly": true - }, - "redirectUrl": { - "type": "string", - "nullable": true, - "readOnly": true - }, - "postLogoutRedirectUrl": { - "type": "string", - "nullable": true, - "readOnly": true - }, - "validateUrl": { - "type": "string", - "nullable": true, - "readOnly": true - }, - "createdBy": { - "type": "integer", - "format": "int32", - "nullable": true, - "readOnly": true - }, - "modifiedBy": { - "type": "integer", - "format": "int32", - "nullable": true, - "readOnly": true - }, - "createdAt": { - "type": "string", - "format": "date-time", - "readOnly": true - }, - "modifiedAt": { - "type": "string", - "format": "date-time", - "readOnly": true - }, - "id": { - "type": "integer", - "format": "int32", - "readOnly": true - } - }, - "readOnly": true - }, - "claimType": { - "maxLength": 256, - "type": "string", - "nullable": true - }, - "claimValue": { - "maxLength": 256, - "type": "string", - "nullable": true - }, - "applications": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ApplicationLink" - }, - "nullable": true - }, "apiResources": { "type": "array", "items": { @@ -3837,6 +4505,43 @@ "$ref": "#/components/schemas/ApiResourceRoleLink" }, "nullable": true + } + }, + "additionalProperties": false + }, + "ServiceAccount": { + "required": [ + "name" + ], + "type": "object", + "properties": { + "name": { + "maxLength": 256, + "type": "string", + "nullable": true + }, + "clientId": { + "type": "string", + "nullable": true, + "readOnly": true + }, + "lastLoginAt": { + "type": "string", + "format": "date-time", + "nullable": true, + "readOnly": true + }, + "clientSecrets": { + "maxLength": 2, + "type": "array", + "items": { + "$ref": "#/components/schemas/UserClientSecret" + }, + "nullable": true, + "readOnly": true + }, + "accessControlEntry": { + "$ref": "#/components/schemas/ServiceAccountBasedAccessControlEntry" }, "createdBy": { "type": "integer", @@ -3868,61 +4573,33 @@ }, "additionalProperties": false }, - "LoginOption": { - "required": [ - "name" - ], + "UserBasedAccessControlEntry": { "type": "object", "properties": { - "name": { - "maxLength": 256, - "type": "string", + "applications": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ApplicationLink" + }, "nullable": true }, - "loginTriggerUrl": { - "type": "string", + "apiResources": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ApiResourceLink" + }, "nullable": true }, - "iconUrl": { - "type": "string", + "apiResourceRoles": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ApiResourceRoleLink" + }, "nullable": true } }, "additionalProperties": false }, - "UserClientSecret": { - "required": [ - "clientSecret", - "expiresAt" - ], - "type": "object", - "properties": { - "clientSecret": { - "maxLength": 4000, - "type": "string", - "nullable": true - }, - "clientSecretUnHashed": { - "type": "string", - "nullable": true - }, - "hint": { - "maxLength": 3, - "type": "string", - "nullable": true - }, - "expiresAt": { - "type": "string", - "format": "date-time" - }, - "id": { - "type": "integer", - "format": "int32", - "readOnly": true - } - }, - "additionalProperties": false - }, "User": { "required": [ "identityProviderId", @@ -3959,12 +4636,14 @@ }, "clientId": { "type": "string", - "nullable": true + "nullable": true, + "readOnly": true }, "lastLoginAt": { "type": "string", "format": "date-time", - "nullable": true + "nullable": true, + "readOnly": true }, "clientSecrets": { "maxLength": 2, @@ -3972,158 +4651,11 @@ "items": { "$ref": "#/components/schemas/UserClientSecret" }, - "nullable": true - }, - "createdBy": { - "type": "integer", - "format": "int32", "nullable": true, "readOnly": true }, - "modifiedBy": { - "type": "integer", - "format": "int32", - "nullable": true, - "readOnly": true - }, - "createdAt": { - "type": "string", - "format": "date-time", - "readOnly": true - }, - "modifiedAt": { - "type": "string", - "format": "date-time", - "readOnly": true - }, - "id": { - "type": "integer", - "format": "int32", - "readOnly": true - } - }, - "additionalProperties": false - }, - "UserMapping": { - "required": [ - "userId" - ], - "type": "object", - "properties": { - "userId": { - "type": "integer", - "format": "int32" - }, - "user": { - "title": "User", - "required": [ - "identityProviderId", - "identityProviderKey", - "name", - "subject" - ], - "type": "object", - "properties": { - "name": { - "maxLength": 256, - "type": "string", - "nullable": true, - "readOnly": true - }, - "email": { - "maxLength": 256, - "type": "string", - "format": "email", - "nullable": true, - "readOnly": true - }, - "subject": { - "maxLength": 256, - "type": "string", - "nullable": true, - "readOnly": true - }, - "identityProviderId": { - "type": "integer", - "format": "int32", - "readOnly": true - }, - "identityProviderKey": { - "maxLength": 256, - "type": "string", - "nullable": true, - "readOnly": true - }, - "clientId": { - "type": "string", - "nullable": true, - "readOnly": true - }, - "lastLoginAt": { - "type": "string", - "format": "date-time", - "nullable": true, - "readOnly": true - }, - "clientSecrets": { - "maxLength": 2, - "type": "array", - "items": { - "$ref": "#/components/schemas/UserClientSecret" - }, - "nullable": true, - "readOnly": true - }, - "createdBy": { - "type": "integer", - "format": "int32", - "nullable": true, - "readOnly": true - }, - "modifiedBy": { - "type": "integer", - "format": "int32", - "nullable": true, - "readOnly": true - }, - "createdAt": { - "type": "string", - "format": "date-time", - "readOnly": true - }, - "modifiedAt": { - "type": "string", - "format": "date-time", - "readOnly": true - }, - "id": { - "type": "integer", - "format": "int32", - "readOnly": true - } - }, - "readOnly": true - }, - "applications": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ApplicationLink" - }, - "nullable": true - }, - "apiResources": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ApiResourceLink" - }, - "nullable": true - }, - "apiResourceRoles": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ApiResourceRoleLink" - }, - "nullable": true + "accessControlEntry": { + "$ref": "#/components/schemas/UserBasedAccessControlEntry" }, "createdBy": { "type": "integer",