mirror of
https://github.com/ferdikoomen/openapi-typescript-codegen.git
synced 2025-12-08 20:16:21 +00:00
- Working on v2 service generation
This commit is contained in:
parent
ec30f2852e
commit
aec93386a5
6
src/client/interfaces/Model.d.ts
vendored
6
src/client/interfaces/Model.d.ts
vendored
@ -5,9 +5,9 @@ export interface Model {
|
||||
name: string;
|
||||
base: string;
|
||||
type: string;
|
||||
template: string;
|
||||
description: string | null;
|
||||
extends: string | null;
|
||||
template?: string;
|
||||
description?: string;
|
||||
extends: string[];
|
||||
imports: string[];
|
||||
properties: ModelProperty[];
|
||||
enums: ModelEnum[];
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { ModelEnumProperty } from './ModelEnumProperty';
|
||||
import { ModelEnumValue } from './ModelEnumValue';
|
||||
|
||||
export interface ModelEnum {
|
||||
name: string;
|
||||
value: string;
|
||||
values: ModelEnumProperty[];
|
||||
values: ModelEnumValue[];
|
||||
}
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
export interface ModelEnumProperty {
|
||||
export interface ModelEnumValue {
|
||||
type: string;
|
||||
name: string;
|
||||
description?: string;
|
||||
value: string | number;
|
||||
}
|
||||
8
src/client/interfaces/ModelProperties.d.ts
vendored
8
src/client/interfaces/ModelProperties.d.ts
vendored
@ -1,8 +0,0 @@
|
||||
import { ModelProperty } from './ModelProperty';
|
||||
import { ModelEnum } from './ModelEnum';
|
||||
|
||||
export interface ModelProperties {
|
||||
imports: string[];
|
||||
properties: ModelProperty[];
|
||||
enums: ModelEnum[];
|
||||
}
|
||||
8
src/client/interfaces/ModelProperty.d.ts
vendored
8
src/client/interfaces/ModelProperty.d.ts
vendored
@ -2,9 +2,13 @@ export interface ModelProperty {
|
||||
name: string;
|
||||
type: string;
|
||||
base: string;
|
||||
template: string | null;
|
||||
description: string | null;
|
||||
template?: string;
|
||||
description?: string;
|
||||
default?: any;
|
||||
required: boolean;
|
||||
nullable: boolean;
|
||||
readOnly: boolean;
|
||||
extends: string[];
|
||||
imports: string[];
|
||||
properties: ModelProperty[];
|
||||
}
|
||||
|
||||
6
src/client/interfaces/Service.d.ts
vendored
6
src/client/interfaces/Service.d.ts
vendored
@ -1,5 +1,7 @@
|
||||
import { ServiceOperation } from './ServiceOperation';
|
||||
|
||||
export interface Service {
|
||||
name: string;
|
||||
base: string;
|
||||
imports: [];
|
||||
operations: ServiceOperation[];
|
||||
imports: string[];
|
||||
}
|
||||
|
||||
23
src/client/interfaces/ServiceOperation.d.ts
vendored
Normal file
23
src/client/interfaces/ServiceOperation.d.ts
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
import { ServiceOperationError } from './ServiceOperationError';
|
||||
import { ServiceOperationParameter } from './ServiceOperationParameter';
|
||||
import { Model } from './Model';
|
||||
import { ServiceOperationResponse } from './ServiceOperationResponse';
|
||||
|
||||
export interface ServiceOperation {
|
||||
name: string;
|
||||
summary?: string;
|
||||
description?: string;
|
||||
deprecated?: boolean;
|
||||
method: string;
|
||||
path: string;
|
||||
parameters: ServiceOperationParameter[];
|
||||
parametersPath: ServiceOperationParameter[];
|
||||
parametersQuery: ServiceOperationParameter[];
|
||||
parametersForm: ServiceOperationParameter[];
|
||||
parametersHeader: ServiceOperationParameter[];
|
||||
parametersBody: ServiceOperationParameter | null;
|
||||
models: Model[];
|
||||
errors: ServiceOperationError[];
|
||||
response: ServiceOperationResponse | null;
|
||||
result: string;
|
||||
}
|
||||
4
src/client/interfaces/ServiceOperationError.d.ts
vendored
Normal file
4
src/client/interfaces/ServiceOperationError.d.ts
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
export interface ServiceOperationError {
|
||||
code: number;
|
||||
text: string;
|
||||
}
|
||||
13
src/client/interfaces/ServiceOperationParameter.ts
Normal file
13
src/client/interfaces/ServiceOperationParameter.ts
Normal file
@ -0,0 +1,13 @@
|
||||
export interface ServiceOperationParameter {
|
||||
name: string;
|
||||
type: string;
|
||||
base: string;
|
||||
template: string;
|
||||
description: string;
|
||||
default?: any;
|
||||
required: boolean;
|
||||
nullable: boolean;
|
||||
// extends: string[];
|
||||
// imports: string[];
|
||||
// properties: ModelProperty[];
|
||||
}
|
||||
5
src/client/interfaces/ServiceOperationResponse.ts
Normal file
5
src/client/interfaces/ServiceOperationResponse.ts
Normal file
@ -0,0 +1,5 @@
|
||||
export interface ServiceOperationResponse {
|
||||
code: number;
|
||||
text: string;
|
||||
property: any;
|
||||
}
|
||||
@ -20,7 +20,7 @@ export enum HttpClient {
|
||||
|
||||
/**
|
||||
* Generate the OpenAPI client. This method will read the OpenAPI specification and based on the
|
||||
* given language it will generate the client, including the types models, validation schemas,
|
||||
* given language it will generate the client, including the typed models, validation schemas,
|
||||
* service layer, etc.
|
||||
* @param input The relative location of the OpenAPI spec.
|
||||
* @param output The relative location of the output directory
|
||||
@ -39,6 +39,8 @@ export function generate(input: string, output: string, language: Language = Lan
|
||||
console.log(os.EOL);
|
||||
|
||||
try {
|
||||
// Load the specification, read the OpenAPI version and load the
|
||||
// handlebar templates for the given language
|
||||
const openApi = getOpenApiSpec(inputPath);
|
||||
const openApiVersion = getOpenApiVersion(openApi);
|
||||
const templates = readHandlebarsTemplates(language);
|
||||
|
||||
@ -5,6 +5,11 @@ import { getServices } from './parser/getServices';
|
||||
import { getModels } from './parser/getModels';
|
||||
import { getSchemas } from './parser/getSchemas';
|
||||
|
||||
/**
|
||||
* Parse the OpenAPI specification to a Client model that contains
|
||||
* all the models, services and schema's we should output.
|
||||
* @param openApi The OpenAPI spec that we have loaded from disk.
|
||||
*/
|
||||
export function parse(openApi: OpenApi): Client {
|
||||
return {
|
||||
version: openApi.info.version,
|
||||
|
||||
2
src/openApi/v2/interfaces/OpenApiHeader.d.ts
vendored
2
src/openApi/v2/interfaces/OpenApiHeader.d.ts
vendored
@ -21,6 +21,6 @@ export interface OpenApiHeader {
|
||||
maxItems?: number;
|
||||
minItems?: number;
|
||||
uniqueItems?: boolean;
|
||||
enum?: string[] | number[];
|
||||
enum?: (string | number)[];
|
||||
multipleOf?: number;
|
||||
}
|
||||
|
||||
2
src/openApi/v2/interfaces/OpenApiItems.d.ts
vendored
2
src/openApi/v2/interfaces/OpenApiItems.d.ts
vendored
@ -17,6 +17,6 @@ export interface OpenApiItems {
|
||||
maxItems?: number;
|
||||
minItems?: number;
|
||||
uniqueItems?: number;
|
||||
enum?: string[] | number[];
|
||||
enum?: (string | number)[];
|
||||
multipleOf?: number;
|
||||
}
|
||||
|
||||
@ -15,7 +15,7 @@ export interface OpenApiOperation {
|
||||
operationId?: string;
|
||||
consumes?: string[];
|
||||
produces?: string[];
|
||||
parameters?: OpenApiParameter[] | OpenApiReference[];
|
||||
parameters?: (OpenApiParameter & OpenApiReference)[];
|
||||
responses: OpenApiResponses;
|
||||
schemes: ('http' | 'https' | 'ws' | 'wss')[];
|
||||
deprecated?: boolean;
|
||||
|
||||
@ -26,6 +26,6 @@ export interface OpenApiParameter {
|
||||
maxItems?: number;
|
||||
minItems?: number;
|
||||
uniqueItems?: boolean;
|
||||
enum?: string[] | number[];
|
||||
enum?: (string | number)[];
|
||||
multipleOf?: number;
|
||||
}
|
||||
|
||||
3
src/openApi/v2/interfaces/OpenApiPath.d.ts
vendored
3
src/openApi/v2/interfaces/OpenApiPath.d.ts
vendored
@ -6,7 +6,6 @@ import { OpenApiReference } from './OpenApiReference';
|
||||
* https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#pathItemObject
|
||||
*/
|
||||
export interface OpenApiPath {
|
||||
$ref?: string;
|
||||
get?: OpenApiOperation;
|
||||
put?: OpenApiOperation;
|
||||
post?: OpenApiOperation;
|
||||
@ -14,5 +13,5 @@ export interface OpenApiPath {
|
||||
options?: OpenApiOperation;
|
||||
head?: OpenApiOperation;
|
||||
patch?: OpenApiOperation;
|
||||
parameters?: OpenApiParameter[] | OpenApiReference[];
|
||||
parameters?: (OpenApiParameter & OpenApiReference)[];
|
||||
}
|
||||
|
||||
@ -2,5 +2,5 @@
|
||||
* https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#referenceObject
|
||||
*/
|
||||
export interface OpenApiReference {
|
||||
$ref: string;
|
||||
$ref?: string;
|
||||
}
|
||||
|
||||
@ -5,7 +5,7 @@ import { OpenApiResponse } from './OpenApiResponse';
|
||||
* https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#responsesObject
|
||||
*/
|
||||
export interface OpenApiResponses {
|
||||
[httpcode: string]: OpenApiResponse | OpenApiReference;
|
||||
[httpcode: string]: OpenApiResponse & OpenApiReference;
|
||||
|
||||
default: OpenApiResponse | OpenApiReference;
|
||||
default: OpenApiResponse & OpenApiReference;
|
||||
}
|
||||
|
||||
11
src/openApi/v2/interfaces/OpenApiSchema.d.ts
vendored
11
src/openApi/v2/interfaces/OpenApiSchema.d.ts
vendored
@ -7,7 +7,6 @@ import { OpenApiXml } from './OpenApiXml';
|
||||
* https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#schemaObject
|
||||
*/
|
||||
export interface OpenApiSchema {
|
||||
$ref?: string;
|
||||
format?: 'int32' | 'int64' | 'float' | 'double' | 'string' | 'boolean' | 'byte' | 'binary' | 'date' | 'date-time' | 'password';
|
||||
title?: string;
|
||||
description?: string;
|
||||
@ -26,12 +25,12 @@ export interface OpenApiSchema {
|
||||
maxProperties?: number;
|
||||
minProperties?: number;
|
||||
required?: string[];
|
||||
enum?: string[] | number[];
|
||||
enum?: (string | number)[];
|
||||
type?: string;
|
||||
items?: OpenApiReference | OpenApiSchema;
|
||||
allOf?: OpenApiReference[] | OpenApiSchema[];
|
||||
properties?: Dictionary<OpenApiSchema>;
|
||||
additionalProperties?: boolean | OpenApiReference | OpenApiSchema;
|
||||
items?: OpenApiSchema & OpenApiReference;
|
||||
allOf?: (OpenApiSchema & OpenApiReference)[];
|
||||
properties?: Dictionary<OpenApiSchema & OpenApiReference>;
|
||||
additionalProperties?: boolean | (OpenApiSchema & OpenApiReference);
|
||||
discriminator?: string;
|
||||
readOnly?: boolean;
|
||||
xml?: OpenApiXml;
|
||||
|
||||
@ -1,14 +1,100 @@
|
||||
import { ModelProperty } from '../../../client/interfaces/ModelProperty';
|
||||
import { OpenApiSchema } from '../interfaces/OpenApiSchema';
|
||||
import { OpenApiReference } from '../interfaces/OpenApiReference';
|
||||
import { getType } from './getType';
|
||||
|
||||
export function parseModelProperty(): ModelProperty {
|
||||
return {
|
||||
name: '',
|
||||
export function getModelProperty(name: string, schema: OpenApiSchema & OpenApiReference): ModelProperty {
|
||||
/**
|
||||
$ref?: string;
|
||||
format?: 'int32' | 'int64' | 'float' | 'double' | 'string' | 'boolean' | 'byte' | 'binary' | 'date' | 'date-time' | 'password';
|
||||
title?: string;
|
||||
description?: string;
|
||||
default?: any;
|
||||
multipleOf?: number;
|
||||
maximum?: number;
|
||||
exclusiveMaximum?: boolean;
|
||||
minimum?: number;
|
||||
exclusiveMinimum?: boolean;
|
||||
maxLength?: number;
|
||||
minLength?: number;
|
||||
pattern?: string;
|
||||
maxItems?: number;
|
||||
minItems?: number;
|
||||
uniqueItems?: number;
|
||||
maxProperties?: number;
|
||||
minProperties?: number;
|
||||
required?: string[];
|
||||
enum?: string[] | number[];
|
||||
type?: string;
|
||||
items?: OpenApiReference | OpenApiSchema;
|
||||
allOf?: OpenApiReference[] | OpenApiSchema[];
|
||||
properties?: Dictionary<OpenApiSchema>;
|
||||
additionalProperties?: boolean | OpenApiReference | OpenApiSchema;
|
||||
discriminator?: string;
|
||||
readOnly?: boolean;
|
||||
xml?: OpenApiXml;
|
||||
externalDocs?: OpenApiExternalDocs;
|
||||
example?: any;
|
||||
*/
|
||||
|
||||
const prop: ModelProperty = {
|
||||
name: name,
|
||||
type: '',
|
||||
base: '',
|
||||
template: '',
|
||||
description: null,
|
||||
description: schema.description,
|
||||
default: schema.default,
|
||||
required: false,
|
||||
readOnly: false,
|
||||
nullable: false,
|
||||
readOnly: schema.readOnly || false,
|
||||
imports: [],
|
||||
extends: [],
|
||||
properties: [],
|
||||
};
|
||||
|
||||
if (schema.$ref) {
|
||||
// console.log('parse $ref?');
|
||||
}
|
||||
|
||||
if (schema.properties || schema.type === 'object') {
|
||||
prop.type = 'interface';
|
||||
// type is interface!?
|
||||
}
|
||||
|
||||
if (schema.enum) {
|
||||
prop.type = 'enum';
|
||||
// type is enum!
|
||||
}
|
||||
|
||||
console.log('propertyName:', schema);
|
||||
console.log('format:', schema.format);
|
||||
console.log('type:', schema.type);
|
||||
|
||||
const properties = schema.properties;
|
||||
for (const propertyName in properties) {
|
||||
if (properties.hasOwnProperty(propertyName)) {
|
||||
const property = properties[propertyName];
|
||||
console.log('propertyName', propertyName);
|
||||
// getModelProperty(propertyName, property);
|
||||
}
|
||||
}
|
||||
|
||||
if (schema.allOf) {
|
||||
schema.allOf.forEach(parent => {
|
||||
if (parent.$ref) {
|
||||
const extend = getType(parent.$ref);
|
||||
prop.extends.push(extend.type);
|
||||
prop.imports.push(extend.base);
|
||||
}
|
||||
if (parent.properties) {
|
||||
console.log(parent.properties);
|
||||
// const properties: ParsedModelProperties = parseModelProperties(modelClass, definition.allOf[1].properties as SwaggerDefinitions, required);
|
||||
// model.imports.push(...properties.imports);
|
||||
// model.properties.push(...properties.properties);
|
||||
// model.enums.push(...properties.enums);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return prop;
|
||||
}
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
import { Model } from '../../../client/interfaces/Model';
|
||||
import { OpenApi } from '../interfaces/OpenApi';
|
||||
import { getType } from './getType';
|
||||
import { getModelTemplate } from './getModelTemplate';
|
||||
|
||||
/**
|
||||
* Parse and return the OpenAPI models.
|
||||
@ -9,26 +8,40 @@ import { getModelTemplate } from './getModelTemplate';
|
||||
*/
|
||||
export function getModels(openApi: OpenApi): Map<string, Model> {
|
||||
const models = new Map<string, Model>();
|
||||
|
||||
// Iterate over the definitions
|
||||
const definitions = openApi.definitions;
|
||||
for (const definitionName in definitions) {
|
||||
if (definitions.hasOwnProperty(definitionName)) {
|
||||
const definition = definitions[definitionName];
|
||||
const required = definition.required || [];
|
||||
const modelClass = getType(definitionName);
|
||||
const modelTemplate: string = getModelTemplate(modelClass);
|
||||
|
||||
// Check if we haven't already parsed the model
|
||||
if (!models.has(modelClass.base)) {
|
||||
const model: Model = {
|
||||
name: modelClass.base,
|
||||
base: modelClass.base,
|
||||
type: modelClass.type,
|
||||
template: modelTemplate,
|
||||
description: null,
|
||||
extends: null,
|
||||
imports: [],
|
||||
properties: [],
|
||||
enums: [],
|
||||
};
|
||||
models.set(modelClass.base, model);
|
||||
// // Create a new model object
|
||||
// const model: Model = {
|
||||
// name: modelClass.base,
|
||||
// base: modelClass.base,
|
||||
// type: modelClass.type,
|
||||
// template: getModelTemplate(modelClass),
|
||||
// description: null,
|
||||
// extends: [],
|
||||
// imports: [],
|
||||
// properties: [],
|
||||
// enums: [],
|
||||
// };
|
||||
//
|
||||
// const properties = definition.properties;
|
||||
// for (const propertyName in properties) {
|
||||
// if (properties.hasOwnProperty(propertyName)) {
|
||||
// const property = properties[propertyName];
|
||||
// const propertyRequired = required.includes(propertyName);
|
||||
// getModelProperty(propertyName, property);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// models.set(modelClass.base, model);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
16
src/openApi/v2/parser/getServiceOperationErrors.ts
Normal file
16
src/openApi/v2/parser/getServiceOperationErrors.ts
Normal file
@ -0,0 +1,16 @@
|
||||
import { ServiceOperationResponse } from '../../../client/interfaces/ServiceOperationResponse';
|
||||
import { ServiceOperationError } from '../../../client/interfaces/ServiceOperationError';
|
||||
|
||||
/**
|
||||
* Get list of service errors.
|
||||
* @param responses List of parsed service responses.
|
||||
* @returns List of service errors containing the error code and message.
|
||||
*/
|
||||
export function getServiceOperationErrors(responses: ServiceOperationResponse[]): ServiceOperationError[] {
|
||||
return responses
|
||||
.filter((response: ServiceOperationResponse): boolean => response.code >= 300 && response.text !== undefined && response.text !== '')
|
||||
.map(response => ({
|
||||
code: response.code,
|
||||
text: response.text,
|
||||
}));
|
||||
}
|
||||
10
src/openApi/v2/parser/getServiceOperationPath.spec.ts
Normal file
10
src/openApi/v2/parser/getServiceOperationPath.spec.ts
Normal file
@ -0,0 +1,10 @@
|
||||
import { getServiceOperationPath } from './getServiceOperationPath';
|
||||
|
||||
describe('getServiceOperationPath', () => {
|
||||
it('should produce correct result', () => {
|
||||
expect(getServiceOperationPath('/api/v{api-version}/list/{id}/{type}')).toEqual('/api/v${OpenAPI.VERSION}/list/${id}/${type}');
|
||||
expect(getServiceOperationPath('/api/v{api-version}/list/{id}')).toEqual('/api/v${OpenAPI.VERSION}/list/${id}');
|
||||
expect(getServiceOperationPath('/api/v1/list/{id}')).toEqual('/api/v1/list/${id}');
|
||||
expect(getServiceOperationPath('/api/v1/list')).toEqual('/api/v1/list');
|
||||
});
|
||||
});
|
||||
@ -4,6 +4,6 @@
|
||||
* OpenAPI version without the need to hardcode this in the URL.
|
||||
* @param path
|
||||
*/
|
||||
export function getServicePath(path: string): string {
|
||||
export function getServiceOperationPath(path: string): string {
|
||||
return path.replace(/{api-version}/g, '{OpenAPI.VERSION}').replace(/\{(.*?)\}/g, '${$1}');
|
||||
}
|
||||
16
src/openApi/v2/parser/getServiceOperationResponseCode.ts
Normal file
16
src/openApi/v2/parser/getServiceOperationResponseCode.ts
Normal file
@ -0,0 +1,16 @@
|
||||
export function getServiceOperationResponsesCode(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;
|
||||
}
|
||||
35
src/openApi/v2/parser/getServiceOperationResponses.ts
Normal file
35
src/openApi/v2/parser/getServiceOperationResponses.ts
Normal file
@ -0,0 +1,35 @@
|
||||
import { OpenApiResponses } from '../interfaces/OpenApiResponses';
|
||||
import { ServiceOperationResponse } from '../../../client/interfaces/ServiceOperationResponse';
|
||||
import { getServiceOperationResponsesCode } from './getServiceOperationResponseCode';
|
||||
|
||||
/**
|
||||
* Parse the service response object into a list with status codes and response messages.
|
||||
* @param responses Swagger responses.
|
||||
* @returns List of status codes and response messages.
|
||||
*/
|
||||
export function getServiceOperationResponses(responses: OpenApiResponses): ServiceOperationResponse[] {
|
||||
const result: ServiceOperationResponse[] = [];
|
||||
|
||||
// Iterate over each response code.
|
||||
for (const code in responses) {
|
||||
if (responses.hasOwnProperty(code)) {
|
||||
// Get the status code and response message (if any).
|
||||
const response = responses[code];
|
||||
const responseCode = getServiceOperationResponsesCode(code);
|
||||
const responseText = response.description || '';
|
||||
|
||||
if (responseCode) {
|
||||
result.push({
|
||||
code: responseCode,
|
||||
text: responseText,
|
||||
property: undefined,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Sort the responses to 2XX success codes come before 4XX and 5XX error codes.
|
||||
return result.sort((a, b): number => {
|
||||
return a.code < b.code ? -1 : a.code > b.code ? 1 : 0;
|
||||
});
|
||||
}
|
||||
29
src/openApi/v2/parser/getServiceOperationResult.ts
Normal file
29
src/openApi/v2/parser/getServiceOperationResult.ts
Normal file
@ -0,0 +1,29 @@
|
||||
import { ServiceOperationResponse } from '../../../client/interfaces/ServiceOperationResponse';
|
||||
|
||||
export interface ServiceOperationResult {
|
||||
type: string;
|
||||
imports: string[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse service result.
|
||||
* @param responses List of service responses.
|
||||
* @returns Object containing the result type and needed imports.
|
||||
*/
|
||||
export function getServiceOperationResult(responses: ServiceOperationResponse[]): ServiceOperationResult {
|
||||
let resultType = 'any';
|
||||
let resultImports: string[] = [];
|
||||
|
||||
// Fetch the first valid (2XX range) response code and return that type.
|
||||
const result = responses.find(response => response.code && response.code >= 200 && response.code < 300 && response.property);
|
||||
|
||||
if (result) {
|
||||
resultType = result.property.type;
|
||||
resultImports = [...result.property.imports];
|
||||
}
|
||||
|
||||
return {
|
||||
type: resultType,
|
||||
imports: resultImports,
|
||||
};
|
||||
}
|
||||
@ -1,10 +0,0 @@
|
||||
import { getServicePath } from './getServicePath';
|
||||
|
||||
describe('getServicePath', () => {
|
||||
it('should produce correct result', () => {
|
||||
expect(getServicePath('/api/v{api-version}/list/{id}/{type}')).toEqual('/api/v${OpenAPI.VERSION}/list/${id}/${type}');
|
||||
expect(getServicePath('/api/v{api-version}/list/{id}')).toEqual('/api/v${OpenAPI.VERSION}/list/${id}');
|
||||
expect(getServicePath('/api/v1/list/{id}')).toEqual('/api/v1/list/${id}');
|
||||
expect(getServicePath('/api/v1/list')).toEqual('/api/v1/list');
|
||||
});
|
||||
});
|
||||
@ -1,5 +1,62 @@
|
||||
import { Service } from '../../../client/interfaces/Service';
|
||||
import { OpenApi } from '../interfaces/OpenApi';
|
||||
import { OpenApiOperation } from '../interfaces/OpenApiOperation';
|
||||
import { getServiceClassName } from './getServiceClassName';
|
||||
import { getServiceOperationName } from './getServiceOperationName';
|
||||
import { getServiceOperationPath } from './getServiceOperationPath';
|
||||
import { ServiceOperation } from '../../../client/interfaces/ServiceOperation';
|
||||
import { getServiceOperationResponses } from './getServiceOperationResponses';
|
||||
import { getServiceOperationResult } from './getServiceOperationResult';
|
||||
import { getServiceOperationErrors } from './getServiceOperationErrors';
|
||||
|
||||
function getMethod(url: string, services: Map<string, Service>, op: OpenApiOperation, method: string): void {
|
||||
const serviceName = (op.tags && op.tags[0]) || 'Service';
|
||||
const serviceClassName: string = getServiceClassName(serviceName);
|
||||
const serviceOperationNameFallback = `${method}${serviceClassName}`;
|
||||
const serviceOperationName: string = getServiceOperationName(op.operationId || serviceOperationNameFallback);
|
||||
const servicePath: string = getServiceOperationPath(url);
|
||||
|
||||
// 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(serviceClassName) ||
|
||||
({
|
||||
name: serviceClassName,
|
||||
imports: [],
|
||||
operations: [],
|
||||
} as Service);
|
||||
|
||||
// Create a new operation object for this method.
|
||||
const operation: ServiceOperation = {
|
||||
name: serviceOperationName,
|
||||
summary: op.summary,
|
||||
description: op.description,
|
||||
deprecated: op.deprecated,
|
||||
method: method,
|
||||
path: servicePath,
|
||||
parameters: [],
|
||||
parametersPath: [],
|
||||
parametersQuery: [],
|
||||
parametersForm: [],
|
||||
parametersHeader: [],
|
||||
parametersBody: null,
|
||||
models: [],
|
||||
errors: [],
|
||||
response: null,
|
||||
result: 'any',
|
||||
};
|
||||
|
||||
if (op.responses) {
|
||||
const responses = getServiceOperationResponses(op.responses);
|
||||
const result = getServiceOperationResult(responses);
|
||||
operation.errors = getServiceOperationErrors(responses);
|
||||
operation.result = result.type;
|
||||
service.imports.push(...result.imports);
|
||||
}
|
||||
|
||||
service.operations.push(operation);
|
||||
services.set(serviceClassName, service);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse and return the OpenAPI services.
|
||||
@ -7,29 +64,15 @@ import { OpenApi } from '../interfaces/OpenApi';
|
||||
*/
|
||||
export function getServices(openApi: OpenApi): Map<string, Service> {
|
||||
const services = new Map<string, Service>();
|
||||
const paths = openApi.paths;
|
||||
for (const url in paths) {
|
||||
if (paths.hasOwnProperty(url)) {
|
||||
const path = paths[url];
|
||||
for (const method in path) {
|
||||
if (path.hasOwnProperty(method)) {
|
||||
switch (method) {
|
||||
case 'get':
|
||||
case 'put':
|
||||
case 'post':
|
||||
case 'delete':
|
||||
case 'options':
|
||||
case 'head':
|
||||
case 'patch':
|
||||
const op = path[method];
|
||||
if (op) {
|
||||
//
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Object.keys(openApi.paths).forEach(url => {
|
||||
const path = openApi.paths[url];
|
||||
path.get && getMethod(url, services, path.get, 'get');
|
||||
path.put && getMethod(url, services, path.put, 'put');
|
||||
path.post && getMethod(url, services, path.post, 'post');
|
||||
path.delete && getMethod(url, services, path.delete, 'delete');
|
||||
path.options && getMethod(url, services, path.options, 'options');
|
||||
path.head && getMethod(url, services, path.head, 'head');
|
||||
path.patch && getMethod(url, services, path.patch, 'patch');
|
||||
});
|
||||
return services;
|
||||
}
|
||||
|
||||
@ -5,6 +5,11 @@ import { getModels } from './parser/getModels';
|
||||
import { getServices } from './parser/getServices';
|
||||
import { getSchemas } from './parser/getSchemas';
|
||||
|
||||
/**
|
||||
* Parse the OpenAPI specification to a Client model that contains
|
||||
* all the models, services and schema's we should output.
|
||||
* @param openApi The OpenAPI spec that we have loaded from disk.
|
||||
*/
|
||||
export function parse(openApi: OpenApi): Client {
|
||||
return {
|
||||
version: openApi.info.version,
|
||||
|
||||
18
src/openApi/v3/interfaces/OpenApiComponents.d.ts
vendored
18
src/openApi/v3/interfaces/OpenApiComponents.d.ts
vendored
@ -14,13 +14,13 @@ import { OpenApiSecurityScheme } from './OpenApiSecurityScheme';
|
||||
* https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#componentsObject
|
||||
*/
|
||||
export interface OpenApiComponents {
|
||||
schemas?: Dictionary<OpenApiSchema | OpenApiReference>;
|
||||
responses?: Dictionary<OpenApiResponses | OpenApiReference>;
|
||||
parameters?: Dictionary<OpenApiParameter | OpenApiReference>;
|
||||
examples?: Dictionary<OpenApiExample | OpenApiReference>;
|
||||
requestBodies?: Dictionary<OpenApiRequestBody | OpenApiReference>;
|
||||
headers?: Dictionary<OpenApiHeader | OpenApiReference>;
|
||||
securitySchemes: Dictionary<OpenApiSecurityScheme | OpenApiReference>;
|
||||
links?: Dictionary<OpenApiLink | OpenApiReference>;
|
||||
callbacks?: Dictionary<OpenApiCallback | OpenApiReference>;
|
||||
schemas?: Dictionary<OpenApiSchema & OpenApiReference>;
|
||||
responses?: Dictionary<OpenApiResponses & OpenApiReference>;
|
||||
parameters?: Dictionary<OpenApiParameter & OpenApiReference>;
|
||||
examples?: Dictionary<OpenApiExample & OpenApiReference>;
|
||||
requestBodies?: Dictionary<OpenApiRequestBody & OpenApiReference>;
|
||||
headers?: Dictionary<OpenApiHeader & OpenApiReference>;
|
||||
securitySchemes: Dictionary<OpenApiSecurityScheme & OpenApiReference>;
|
||||
links?: Dictionary<OpenApiLink & OpenApiReference>;
|
||||
callbacks?: Dictionary<OpenApiCallback & OpenApiReference>;
|
||||
}
|
||||
|
||||
@ -7,7 +7,7 @@ import { OpenApiReference } from './OpenApiReference';
|
||||
*/
|
||||
export interface OpenApiEncoding {
|
||||
contentType?: string;
|
||||
headers?: Dictionary<OpenApiHeader | OpenApiReference>;
|
||||
headers?: Dictionary<OpenApiHeader & OpenApiReference>;
|
||||
style?: string;
|
||||
explode?: boolean;
|
||||
allowReserved?: boolean;
|
||||
|
||||
4
src/openApi/v3/interfaces/OpenApiHeader.d.ts
vendored
4
src/openApi/v3/interfaces/OpenApiHeader.d.ts
vendored
@ -14,7 +14,7 @@ export interface OpenApiHeader {
|
||||
style?: string;
|
||||
explode?: boolean;
|
||||
allowReserved?: boolean;
|
||||
schema?: OpenApiSchema | OpenApiReference;
|
||||
schema?: OpenApiSchema & OpenApiReference;
|
||||
example?: any;
|
||||
examples?: Dictionary<OpenApiExample | OpenApiReference>;
|
||||
examples?: Dictionary<OpenApiExample & OpenApiReference>;
|
||||
}
|
||||
|
||||
@ -8,8 +8,8 @@ import { OpenApiSchema } from './OpenApiSchema';
|
||||
* https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#mediaTypeObject
|
||||
*/
|
||||
export interface OpenApiMediaType {
|
||||
schema?: OpenApiSchema | OpenApiReference;
|
||||
schema?: OpenApiSchema & OpenApiReference;
|
||||
example?: any;
|
||||
examples?: Dictionary<OpenApiExample | OpenApiReference>;
|
||||
examples?: Dictionary<OpenApiExample & OpenApiReference>;
|
||||
encoding?: Dictionary<OpenApiEncoding>;
|
||||
}
|
||||
|
||||
@ -17,10 +17,10 @@ export interface OpenApiOperation {
|
||||
description?: string;
|
||||
externalDocs?: OpenApiExternalDocs;
|
||||
operationId?: string;
|
||||
parameters?: OpenApiParameter[] | OpenApiReference[];
|
||||
requestBody?: OpenApiRequestBody | OpenApiReference;
|
||||
parameters?: (OpenApiParameter & OpenApiReference)[];
|
||||
requestBody?: OpenApiRequestBody & OpenApiReference;
|
||||
responses: OpenApiResponses;
|
||||
callbacks?: Dictionary<OpenApiCallback | OpenApiReference>;
|
||||
callbacks?: Dictionary<OpenApiCallback & OpenApiReference>;
|
||||
deprecated?: boolean;
|
||||
security?: OpenApiSecurityRequirement[];
|
||||
servers?: OpenApiServer[];
|
||||
|
||||
@ -16,7 +16,7 @@ export interface OpenApiParameter {
|
||||
style?: string;
|
||||
explode?: boolean;
|
||||
allowReserved?: boolean;
|
||||
schema?: OpenApiSchema | OpenApiReference;
|
||||
schema?: OpenApiSchema & OpenApiReference;
|
||||
example?: any;
|
||||
examples?: Dictionary<OpenApiExample | OpenApiReference>;
|
||||
examples?: Dictionary<OpenApiExample & OpenApiReference>;
|
||||
}
|
||||
|
||||
3
src/openApi/v3/interfaces/OpenApiPath.d.ts
vendored
3
src/openApi/v3/interfaces/OpenApiPath.d.ts
vendored
@ -7,7 +7,6 @@ import { OpenApiServer } from './OpenApiServer';
|
||||
* https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#pathItemObject
|
||||
*/
|
||||
export interface OpenApiPath {
|
||||
$ref?: string;
|
||||
summary?: string;
|
||||
description?: string;
|
||||
get?: OpenApiOperation;
|
||||
@ -19,5 +18,5 @@ export interface OpenApiPath {
|
||||
patch?: OpenApiOperation;
|
||||
trace?: OpenApiOperation;
|
||||
servers?: OpenApiServer[];
|
||||
parameters?: OpenApiParameter[] | OpenApiReference[];
|
||||
parameters?: (OpenApiParameter & OpenApiReference)[];
|
||||
}
|
||||
|
||||
@ -2,5 +2,5 @@
|
||||
* https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#referenceObject
|
||||
*/
|
||||
export interface OpenApiReference {
|
||||
$ref: string;
|
||||
$ref?: string;
|
||||
}
|
||||
|
||||
@ -7,6 +7,6 @@ import { OpenApiReference } from './OpenApiReference';
|
||||
*/
|
||||
export interface OpenApiRequestBody {
|
||||
description?: string;
|
||||
content: Dictionary<OpenApiMediaType | OpenApiReference>;
|
||||
content: Dictionary<OpenApiMediaType & OpenApiReference>;
|
||||
required?: boolean;
|
||||
}
|
||||
|
||||
@ -9,7 +9,7 @@ import { OpenApiReference } from './OpenApiReference';
|
||||
*/
|
||||
export interface OpenApiResponse {
|
||||
description: string;
|
||||
headers?: Dictionary<OpenApiHeader | OpenApiReference>;
|
||||
headers?: Dictionary<OpenApiHeader & OpenApiReference>;
|
||||
content?: Dictionary<OpenApiMediaType>;
|
||||
links?: Dictionary<OpenApiLink | OpenApiReference>;
|
||||
links?: Dictionary<OpenApiLink & OpenApiReference>;
|
||||
}
|
||||
|
||||
@ -5,7 +5,7 @@ import { OpenApiResponse } from './OpenApiResponse';
|
||||
* https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#responsesObject
|
||||
*/
|
||||
export interface OpenApiResponses {
|
||||
[httpcode: string]: OpenApiResponse | OpenApiReference;
|
||||
[httpcode: string]: OpenApiResponse & OpenApiReference;
|
||||
|
||||
default: OpenApiResponse | OpenApiReference;
|
||||
default: OpenApiResponse & OpenApiReference;
|
||||
}
|
||||
|
||||
16
src/openApi/v3/interfaces/OpenApiSchema.d.ts
vendored
16
src/openApi/v3/interfaces/OpenApiSchema.d.ts
vendored
@ -23,15 +23,15 @@ export interface OpenApiSchema {
|
||||
maxProperties?: number;
|
||||
minProperties?: number;
|
||||
required?: string[];
|
||||
enum?: string[] | number[];
|
||||
enum?: (string | number)[];
|
||||
type?: string;
|
||||
allOf?: OpenApiReference[] | OpenApiSchema[];
|
||||
oneOf?: OpenApiReference[] | OpenApiSchema[];
|
||||
anyOf?: OpenApiReference[] | OpenApiSchema[];
|
||||
not?: OpenApiReference[] | OpenApiSchema[];
|
||||
items?: OpenApiReference | OpenApiSchema;
|
||||
properties?: Dictionary<OpenApiSchema>;
|
||||
additionalProperties?: boolean | OpenApiReference | OpenApiSchema;
|
||||
allOf?: (OpenApiSchema & OpenApiReference)[];
|
||||
oneOf?: (OpenApiSchema & OpenApiReference)[];
|
||||
anyOf?: (OpenApiSchema & OpenApiReference)[];
|
||||
not?: (OpenApiSchema & OpenApiReference)[];
|
||||
items?: OpenApiSchema & OpenApiReference;
|
||||
properties?: Dictionary<OpenApiSchema & OpenApiReference>;
|
||||
additionalProperties?: boolean | (OpenApiSchema & OpenApiReference);
|
||||
description?: string;
|
||||
format?: 'int32' | 'int64' | 'float' | 'double' | 'string' | 'boolean' | 'byte' | 'binary' | 'date' | 'date-time' | 'password';
|
||||
default?: any;
|
||||
|
||||
@ -18,6 +18,6 @@ export { {{{basename}}} } from './schemas/{{{basename}}}';
|
||||
{{#if services}}
|
||||
|
||||
{{#each services}}
|
||||
export { {{{basename}}} } from './services/{{{basename}}}';
|
||||
export { {{{name}}} } from './services/{{{name}}}';
|
||||
{{/each}}
|
||||
{{/if}}
|
||||
|
||||
@ -1,11 +1,22 @@
|
||||
/* istanbul ignore file */
|
||||
/* eslint-disable */
|
||||
{{#if enums}}
|
||||
|
||||
{{#if imports}}
|
||||
{{#each imports}}
|
||||
import { {{{this}}} } from '../models/{{{this}}}';
|
||||
{{/each}}
|
||||
{{/if}}
|
||||
import * as yup from 'yup';
|
||||
|
||||
export let {{{base}}};
|
||||
(function ({{{base}}}) {
|
||||
|
||||
{{#each enums}}
|
||||
{{#if description}}
|
||||
/**
|
||||
* {{{description}}}
|
||||
*/
|
||||
{{/if}}
|
||||
{{{../base}}}.{{{name}}} = {
|
||||
{{#each values}}
|
||||
{{{name}}}: {{{value}}},
|
||||
@ -13,5 +24,17 @@ export let {{{base}}};
|
||||
};
|
||||
|
||||
{{/each}}
|
||||
|
||||
{{{../base}}}.schema = yup.object().shape({
|
||||
// Add properties
|
||||
};
|
||||
|
||||
{{{../base}}}.validate = function(value) {
|
||||
return schema.validate(value, { strict: true });
|
||||
};
|
||||
|
||||
{{{../base}}}.validateSync = function(value) {
|
||||
return schema.validateSync(value, { strict: true });
|
||||
};
|
||||
|
||||
})({{{base}}} || ({{{base}}} = {}));
|
||||
{{/if}}
|
||||
|
||||
@ -1,2 +1,70 @@
|
||||
/* istanbul ignore file */
|
||||
/* eslint-disable */
|
||||
import * as yup from 'yup';
|
||||
|
||||
export class {{{name}}} {
|
||||
|
||||
{{#each operations}}
|
||||
/**
|
||||
{{#if deprecated}}
|
||||
* @deprecated
|
||||
{{/if}}
|
||||
{{#if summary}}
|
||||
* {{{summary}}}
|
||||
{{/if}}
|
||||
{{#if description}}
|
||||
* {{{description}}}
|
||||
{{/if}}
|
||||
{{#if parameters}}
|
||||
{{#each parameters}}
|
||||
* @param {{{name}}} {{{description}}}
|
||||
{{/each}}
|
||||
{{/if}}
|
||||
*/
|
||||
static async {{{name}}}({{#each parameters}}{{{name}}}{{#unless required}}?{{/unless}}{{#unless @last}}, {{/unless}}{{/each}}) {
|
||||
{{#if parameters}}
|
||||
|
||||
{{#each parameters}}
|
||||
yup.schema.validate();
|
||||
isValidRequiredParam({{{name}}}, '{{{name}}}');
|
||||
{{/each}}
|
||||
{{/if}}
|
||||
|
||||
const result = await request({
|
||||
method: '{{{method}}}',
|
||||
path: `{{{path}}}`,{{#if parametersHeader}}
|
||||
headers: {
|
||||
{{#each parametersHeader}}
|
||||
'{{{prop}}}': {{{name}}},
|
||||
{{/each}}
|
||||
},{{/if}}{{#if parametersQuery}}
|
||||
query: {
|
||||
{{#each parametersQuery}}
|
||||
'{{{prop}}}': {{{name}}},
|
||||
{{/each}}
|
||||
},{{/if}}{{#if parametersForm}}
|
||||
formData: {
|
||||
{{#each parametersForm}}
|
||||
'{{{prop}}}': {{{name}}},
|
||||
{{/each}}
|
||||
},{{/if}}{{#if parametersBody}}
|
||||
body: {{{parametersBody.name}}},{{/if}}
|
||||
});
|
||||
|
||||
{{#if errors}}
|
||||
if (!result.ok) {
|
||||
switch (result.status) {
|
||||
{{#each errors}}
|
||||
case {{{code}}}: throw new ApiError(result, `{{{text}}}`);
|
||||
{{/each}}
|
||||
}
|
||||
}
|
||||
{{/if}}
|
||||
|
||||
catchGenericError(result);
|
||||
|
||||
return result.body;
|
||||
}
|
||||
|
||||
{{/each}}
|
||||
}
|
||||
|
||||
@ -2,8 +2,8 @@
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
|
||||
const server: string = '{{{server}}}';
|
||||
const version: string = '{{{version}}}';
|
||||
const server = '{{{server}}}';
|
||||
const version = '{{{version}}}';
|
||||
{{#if models}}
|
||||
|
||||
{{#each models}}
|
||||
@ -19,6 +19,6 @@ export { {{{base}}} } from './schemas/{{{base}}}';
|
||||
{{#if services}}
|
||||
|
||||
{{#each services}}
|
||||
export { {{{base}}} } from './services/{{{base}}}';
|
||||
export { {{{name}}} } from './services/{{{name}}}';
|
||||
{{/each}}
|
||||
{{/if}}
|
||||
|
||||
@ -1,23 +1,38 @@
|
||||
/* istanbul ignore file */
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
{{#if imports}}
|
||||
|
||||
{{#if imports}}
|
||||
{{#each imports}}
|
||||
import { {{{this}}} } from '../models/{{{this}}}';
|
||||
{{/each}}
|
||||
{{/if}}
|
||||
import * as yup from 'yup';
|
||||
|
||||
{{#if description}}
|
||||
/**
|
||||
* {{{description}}}
|
||||
*/
|
||||
{{/if}}
|
||||
export interface {{{base}}}{{{template}}}{{#if extend}} extends {{{extend}}}{{/if}} {
|
||||
{{#each properties}}
|
||||
{{#if readOnly}}readonly {{/if}}{{{name}}}{{#unless required}}?{{/unless}}: {{{type}}};
|
||||
{{#if description}}
|
||||
/**
|
||||
* {{{description}}}
|
||||
*/
|
||||
{{/if}}
|
||||
{{#if readOnly}}readonly {{/if}}{{{name}}}{{#unless required}}?{{/unless}}: {{{type}}}{{#if nullable}} | null{{/if}};
|
||||
{{/each}}
|
||||
}
|
||||
{{#if enums}}
|
||||
|
||||
export namespace {{{base}}} {
|
||||
|
||||
{{#each enums}}
|
||||
{{#if description}}
|
||||
/**
|
||||
* {{{description}}}
|
||||
*/
|
||||
{{/if}}
|
||||
export enum {{{name}}} {
|
||||
{{#each values}}
|
||||
{{{name}}} = {{{value}}},
|
||||
@ -25,5 +40,16 @@ export namespace {{{base}}} {
|
||||
};
|
||||
|
||||
{{/each}}
|
||||
|
||||
export const schema = yup.object<{{{base}}}{{{template}}}>().shape({
|
||||
// Add properties
|
||||
});
|
||||
|
||||
export function validate(value: {{{base}}}{{{template}}}): Promise<{{{base}}}{{{template}}}> {
|
||||
return schema.validate(value, { strict: true });
|
||||
}
|
||||
|
||||
export function validateSync(value: {{{base}}}{{{template}}}): {{{base}}}{{{template}}} {
|
||||
return schema.validateSync(value, { strict: true });
|
||||
}
|
||||
}
|
||||
{{/if}}
|
||||
|
||||
@ -1,3 +1,71 @@
|
||||
/* istanbul ignore file */
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
import * as yup from 'yup';
|
||||
|
||||
export class {{{name}}} {
|
||||
|
||||
{{#each operations}}
|
||||
/**
|
||||
{{#if deprecated}}
|
||||
* @deprecated
|
||||
{{/if}}
|
||||
{{#if summary}}
|
||||
* {{{summary}}}
|
||||
{{/if}}
|
||||
{{#if description}}
|
||||
* {{{description}}}
|
||||
{{/if}}
|
||||
{{#if parameters}}
|
||||
{{#each parameters}}
|
||||
* @param {{{name}}} {{{description}}}
|
||||
{{/each}}
|
||||
{{/if}}
|
||||
*/
|
||||
public static async {{{name}}}({{#each parameters}}{{{name}}}{{#unless required}}?{{/unless}}: {{{type}}}{{#if nullable}} | null{{/if}}{{#unless @last}}, {{/unless}}{{/each}}): Promise<{{{result}}}> {
|
||||
{{#if parameters}}
|
||||
|
||||
{{#each parameters}}
|
||||
yup.schema.validate();
|
||||
isValidRequiredParam({{{name}}}, '{{{name}}}');
|
||||
{{/each}}
|
||||
{{/if}}
|
||||
|
||||
const result = await request<{{{result}}}>({
|
||||
method: '{{{method}}}',
|
||||
path: `{{{path}}}`,{{#if parametersHeader}}
|
||||
headers: {
|
||||
{{#each parametersHeader}}
|
||||
'{{{prop}}}': {{{name}}},
|
||||
{{/each}}
|
||||
},{{/if}}{{#if parametersQuery}}
|
||||
query: {
|
||||
{{#each parametersQuery}}
|
||||
'{{{prop}}}': {{{name}}},
|
||||
{{/each}}
|
||||
},{{/if}}{{#if parametersForm}}
|
||||
formData: {
|
||||
{{#each parametersForm}}
|
||||
'{{{prop}}}': {{{name}}},
|
||||
{{/each}}
|
||||
},{{/if}}{{#if parametersBody}}
|
||||
body: {{{parametersBody.name}}},{{/if}}
|
||||
});
|
||||
|
||||
{{#if errors}}
|
||||
if (!result.ok) {
|
||||
switch (result.status) {
|
||||
{{#each errors}}
|
||||
case {{{code}}}: throw new ApiError(result, `{{{text}}}`);
|
||||
{{/each}}
|
||||
}
|
||||
}
|
||||
{{/if}}
|
||||
|
||||
catchGenericError(result);
|
||||
|
||||
return result.body;
|
||||
}
|
||||
|
||||
{{/each}}
|
||||
}
|
||||
|
||||
@ -1,5 +1,10 @@
|
||||
import { Language } from '../index';
|
||||
|
||||
/**
|
||||
* Get the correct file name and extension for a given language.
|
||||
* @param fileName Any file name.
|
||||
* @param language Typescript or Javascript.
|
||||
*/
|
||||
export function getFileName(fileName: string, language: Language): string {
|
||||
switch (language) {
|
||||
case Language.TYPESCRIPT:
|
||||
|
||||
@ -9,8 +9,7 @@ describe('getSortedModels', () => {
|
||||
base: 'John',
|
||||
type: '',
|
||||
template: '',
|
||||
description: null,
|
||||
extends: null,
|
||||
extends: [],
|
||||
imports: [],
|
||||
properties: [],
|
||||
enums: [],
|
||||
@ -20,8 +19,7 @@ describe('getSortedModels', () => {
|
||||
base: 'Jane',
|
||||
type: '',
|
||||
template: '',
|
||||
description: null,
|
||||
extends: null,
|
||||
extends: [],
|
||||
imports: [],
|
||||
properties: [],
|
||||
enums: [],
|
||||
@ -31,8 +29,7 @@ describe('getSortedModels', () => {
|
||||
base: 'Doe',
|
||||
type: '',
|
||||
template: '',
|
||||
description: null,
|
||||
extends: null,
|
||||
extends: [],
|
||||
imports: [],
|
||||
properties: [],
|
||||
enums: [],
|
||||
|
||||
@ -7,8 +7,8 @@ import { Service } from '../client/interfaces/Service';
|
||||
export function getSortedServices(services: Map<string, Service>): Service[] {
|
||||
return (
|
||||
Array.from(services.values()).sort((a, b) => {
|
||||
const nameA = a.base.toLowerCase();
|
||||
const nameB = b.base.toLowerCase();
|
||||
const nameA = a.name.toLowerCase();
|
||||
const nameB = b.name.toLowerCase();
|
||||
return nameA.localeCompare(nameB, 'en');
|
||||
}) || []
|
||||
);
|
||||
|
||||
@ -25,12 +25,14 @@ export function writeClient(client: Client, language: Language, templates: Templ
|
||||
const outputPathSchemas = path.resolve(outputPath, 'schemas');
|
||||
const outputPathServices = path.resolve(outputPath, 'services');
|
||||
|
||||
// Clean output directory
|
||||
try {
|
||||
rimraf.sync(outputPath);
|
||||
} catch (e) {
|
||||
throw new Error(`Could not clean output directory`);
|
||||
}
|
||||
|
||||
// Create new directories
|
||||
try {
|
||||
mkdirp.sync(outputPath);
|
||||
mkdirp.sync(outputPathCore);
|
||||
@ -41,6 +43,7 @@ export function writeClient(client: Client, language: Language, templates: Templ
|
||||
throw new Error(`Could not create output directories`);
|
||||
}
|
||||
|
||||
// Write the client files
|
||||
try {
|
||||
writeClientIndex(client, language, templates.index, outputPath);
|
||||
writeClientModels(getSortedModels(client.models), language, templates.model, outputPathModels);
|
||||
|
||||
@ -6,43 +6,50 @@ const OpenAPI = require('../dist');
|
||||
|
||||
OpenAPI.generate(
|
||||
'./test/mock/v2/test-petstore.json',
|
||||
'./test/tmp/v2/test-petstore',
|
||||
'./test/tmp/v2/ts/test-petstore',
|
||||
OpenAPI.Language.TYPESCRIPT,
|
||||
OpenAPI.HttpClient.FETCH,
|
||||
);
|
||||
|
||||
OpenAPI.generate(
|
||||
'./test/mock/v2/test-petstore.yaml',
|
||||
'./test/tmp/v2/test-petstore-yaml',
|
||||
OpenAPI.Language.TYPESCRIPT,
|
||||
OpenAPI.HttpClient.FETCH,
|
||||
);
|
||||
|
||||
OpenAPI.generate(
|
||||
'./test/mock/v3/test-petstore.json',
|
||||
'./test/tmp/v3/test-petstore-json',
|
||||
OpenAPI.Language.TYPESCRIPT,
|
||||
OpenAPI.HttpClient.FETCH
|
||||
);
|
||||
|
||||
OpenAPI.generate(
|
||||
'./test/mock/v3/test-petstore.yaml',
|
||||
'./test/tmp/v3/test-petstore-yaml',
|
||||
OpenAPI.Language.TYPESCRIPT,
|
||||
OpenAPI.HttpClient.FETCH,
|
||||
);
|
||||
|
||||
OpenAPI.generate(
|
||||
'./test/mock/v3/test-uspto.json',
|
||||
'./test/tmp/v3/test-uspto',
|
||||
OpenAPI.Language.TYPESCRIPT,
|
||||
OpenAPI.HttpClient.FETCH,
|
||||
);
|
||||
|
||||
OpenAPI.generate(
|
||||
'./test/mock/v3/test-with-examples.json',
|
||||
'./test/tmp/v3/test-with-examples',
|
||||
OpenAPI.Language.TYPESCRIPT,
|
||||
'./test/mock/v2/test-petstore.json',
|
||||
'./test/tmp/v2/js/test-petstore',
|
||||
OpenAPI.Language.JAVASCRIPT,
|
||||
OpenAPI.HttpClient.FETCH,
|
||||
);
|
||||
|
||||
// OpenAPI.generate(
|
||||
// './test/mock/v2/test-petstore.yaml',
|
||||
// './test/tmp/v2/test-petstore-yaml',
|
||||
// OpenAPI.Language.TYPESCRIPT,
|
||||
// OpenAPI.HttpClient.FETCH,
|
||||
// );
|
||||
//
|
||||
// OpenAPI.generate(
|
||||
// './test/mock/v3/test-petstore.json',
|
||||
// './test/tmp/v3/test-petstore-json',
|
||||
// OpenAPI.Language.TYPESCRIPT,
|
||||
// OpenAPI.HttpClient.FETCH
|
||||
// );
|
||||
//
|
||||
// OpenAPI.generate(
|
||||
// './test/mock/v3/test-petstore.yaml',
|
||||
// './test/tmp/v3/test-petstore-yaml',
|
||||
// OpenAPI.Language.TYPESCRIPT,
|
||||
// OpenAPI.HttpClient.FETCH,
|
||||
// );
|
||||
//
|
||||
// OpenAPI.generate(
|
||||
// './test/mock/v3/test-uspto.json',
|
||||
// './test/tmp/v3/test-uspto',
|
||||
// OpenAPI.Language.TYPESCRIPT,
|
||||
// OpenAPI.HttpClient.FETCH,
|
||||
// );
|
||||
//
|
||||
// OpenAPI.generate(
|
||||
// './test/mock/v3/test-with-examples.json',
|
||||
// './test/tmp/v3/test-with-examples',
|
||||
// OpenAPI.Language.TYPESCRIPT,
|
||||
// OpenAPI.HttpClient.FETCH,
|
||||
// );
|
||||
//
|
||||
|
||||
954
test/mock/v2/test-addon.json
Normal file
954
test/mock/v2/test-addon.json
Normal file
@ -0,0 +1,954 @@
|
||||
{
|
||||
"x-generator": "NSwag v12.3.1.0 (NJsonSchema v9.14.1.0 (Newtonsoft.Json v12.0.0.0))",
|
||||
"swagger": "2.0",
|
||||
"info": {
|
||||
"title": "Add-on Service API",
|
||||
"version": "v1"
|
||||
},
|
||||
"host": "10.91.90.47:83",
|
||||
"schemes": [
|
||||
"http"
|
||||
],
|
||||
"paths": {
|
||||
"/addon/api/v1/addons": {
|
||||
"get": {
|
||||
"tags": [
|
||||
"Addons"
|
||||
],
|
||||
"summary": "Gets the list of addons.",
|
||||
"operationId": "GetAll",
|
||||
"responses": {
|
||||
"200": {
|
||||
"x-nullable": true,
|
||||
"description": "",
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/Addon"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"post": {
|
||||
"tags": [
|
||||
"Addons"
|
||||
],
|
||||
"summary": "Upload add-ons' zip files. Creates (or updates if exists) add-on.",
|
||||
"operationId": "Upload",
|
||||
"consumes": [
|
||||
"multipart/form-data"
|
||||
],
|
||||
"parameters": [
|
||||
{
|
||||
"type": "file",
|
||||
"name": "file",
|
||||
"in": "formData",
|
||||
"required": true,
|
||||
"description": "FileStream of the uploading file."
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"201": {
|
||||
"x-nullable": true,
|
||||
"description": "UploadResult",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/UploadResult"
|
||||
}
|
||||
},
|
||||
"202": {
|
||||
"x-nullable": true,
|
||||
"description": "UploadResult",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/UploadResult"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/addon/api/v1/addons/{id}": {
|
||||
"put": {
|
||||
"tags": [
|
||||
"Addons"
|
||||
],
|
||||
"summary": "Upload addons' zip files. Updates existing add-on.",
|
||||
"operationId": "Update",
|
||||
"consumes": [
|
||||
"multipart/form-data"
|
||||
],
|
||||
"parameters": [
|
||||
{
|
||||
"type": "integer",
|
||||
"name": "id",
|
||||
"in": "path",
|
||||
"required": true,
|
||||
"description": "The add-on id.",
|
||||
"format": "int32",
|
||||
"x-nullable": false
|
||||
},
|
||||
{
|
||||
"type": "file",
|
||||
"name": "file",
|
||||
"in": "formData",
|
||||
"required": true,
|
||||
"description": "FileStream of the uploading file."
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"x-nullable": true,
|
||||
"description": "UploadResult.",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/UploadResult"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"get": {
|
||||
"tags": [
|
||||
"Addons"
|
||||
],
|
||||
"summary": "Gets the addon metadata by the specified id.",
|
||||
"operationId": "Get",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "integer",
|
||||
"name": "id",
|
||||
"in": "path",
|
||||
"required": true,
|
||||
"description": "The addon id.",
|
||||
"format": "int32",
|
||||
"x-nullable": false
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"x-nullable": true,
|
||||
"description": "The addon metadata.",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/Addon"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"delete": {
|
||||
"tags": [
|
||||
"Addons"
|
||||
],
|
||||
"summary": "Deletes the addon with a specified id.",
|
||||
"operationId": "Delete",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "integer",
|
||||
"name": "id",
|
||||
"in": "path",
|
||||
"required": true,
|
||||
"description": "The addon id.",
|
||||
"format": "int32",
|
||||
"x-nullable": false
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"x-nullable": true,
|
||||
"description": "",
|
||||
"schema": {
|
||||
"type": "file"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/addon/api/v1/addons/{id}/status": {
|
||||
"post": {
|
||||
"tags": [
|
||||
"Addons"
|
||||
],
|
||||
"summary": "Updates the addon status.",
|
||||
"operationId": "UpdateAddonStatus",
|
||||
"consumes": [
|
||||
"application/json-patch+json",
|
||||
"application/json",
|
||||
"text/json",
|
||||
"application/*+json"
|
||||
],
|
||||
"parameters": [
|
||||
{
|
||||
"type": "integer",
|
||||
"name": "id",
|
||||
"in": "path",
|
||||
"required": true,
|
||||
"description": "The addon id.",
|
||||
"format": "int32",
|
||||
"x-nullable": false
|
||||
},
|
||||
{
|
||||
"name": "statusReport",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"description": "The status report.",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/StatusReport"
|
||||
},
|
||||
"x-nullable": false
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"x-nullable": true,
|
||||
"description": "",
|
||||
"schema": {
|
||||
"type": "file"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"delete": {
|
||||
"tags": [
|
||||
"Addons"
|
||||
],
|
||||
"summary": "Deletes the addon status.",
|
||||
"operationId": "DeleteAddonStatus",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "integer",
|
||||
"name": "id",
|
||||
"in": "path",
|
||||
"required": true,
|
||||
"description": "The addon id.",
|
||||
"format": "int32",
|
||||
"x-nullable": false
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"x-nullable": true,
|
||||
"description": "",
|
||||
"schema": {
|
||||
"type": "file"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/addon/api/v1/addons/{id}/download": {
|
||||
"get": {
|
||||
"tags": [
|
||||
"Addons"
|
||||
],
|
||||
"summary": "Downloads addon by the specified id.",
|
||||
"description": "When HEAD request is used the method only checks if the addon exists and returns the empty file.",
|
||||
"operationId": "Download",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "integer",
|
||||
"name": "id",
|
||||
"in": "path",
|
||||
"required": true,
|
||||
"description": "The addon id.",
|
||||
"format": "int32",
|
||||
"x-nullable": false
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"x-nullable": true,
|
||||
"description": "Binary addon.",
|
||||
"schema": {
|
||||
"type": "file"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"head": {
|
||||
"tags": [
|
||||
"Addons"
|
||||
],
|
||||
"summary": "Downloads addon by the specified id.",
|
||||
"description": "When HEAD request is used the method only checks if the addon exists and returns the empty file.",
|
||||
"operationId": "Fetch",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "integer",
|
||||
"name": "id",
|
||||
"in": "path",
|
||||
"required": true,
|
||||
"description": "The addon id.",
|
||||
"format": "int32",
|
||||
"x-nullable": false
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"x-nullable": true,
|
||||
"description": "Binary addon.",
|
||||
"schema": {
|
||||
"type": "file"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/addon/api/v1/addons/{id}/downloadicon": {
|
||||
"get": {
|
||||
"tags": [
|
||||
"Addons"
|
||||
],
|
||||
"summary": "Downloads Addon Icon by the specified id.",
|
||||
"operationId": "DownloadIcon",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "integer",
|
||||
"name": "id",
|
||||
"in": "path",
|
||||
"required": true,
|
||||
"description": "The addon id.",
|
||||
"format": "int32",
|
||||
"x-nullable": false
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"x-nullable": true,
|
||||
"description": "Addon icon stream.",
|
||||
"schema": {
|
||||
"type": "file"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/addon/api/v1/addons/{id}/configurations": {
|
||||
"put": {
|
||||
"tags": [
|
||||
"Configurations"
|
||||
],
|
||||
"summary": "Upload addon configuration files. Extracts required fields from the containing manifest file.",
|
||||
"operationId": "UploadConfiguration",
|
||||
"consumes": [
|
||||
"multipart/form-data"
|
||||
],
|
||||
"parameters": [
|
||||
{
|
||||
"type": "integer",
|
||||
"name": "id",
|
||||
"in": "path",
|
||||
"required": true,
|
||||
"description": "The addon id.",
|
||||
"format": "int32",
|
||||
"x-nullable": false
|
||||
},
|
||||
{
|
||||
"type": "file",
|
||||
"name": "file",
|
||||
"in": "formData",
|
||||
"required": true,
|
||||
"description": "FileStream of the uploading file."
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"x-nullable": true,
|
||||
"description": "The updated addon.",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/UploadResult"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"delete": {
|
||||
"tags": [
|
||||
"Configurations"
|
||||
],
|
||||
"summary": "Deletes the addon configuration with a specified id.",
|
||||
"operationId": "ConfigurationDelete",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "integer",
|
||||
"name": "id",
|
||||
"in": "path",
|
||||
"required": true,
|
||||
"description": "The addon id.",
|
||||
"format": "int32",
|
||||
"x-nullable": false
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"x-nullable": true,
|
||||
"description": "",
|
||||
"schema": {
|
||||
"type": "file"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"get": {
|
||||
"tags": [
|
||||
"Configurations"
|
||||
],
|
||||
"summary": "Downloads addon configuration by the specified id.",
|
||||
"description": "When HEAD request is used the method only checks if the addon exists and returns the empty file.",
|
||||
"operationId": "DownloadAddonConfiguration",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "integer",
|
||||
"name": "id",
|
||||
"in": "path",
|
||||
"required": true,
|
||||
"description": "The addon id.",
|
||||
"format": "int32",
|
||||
"x-nullable": false
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"x-nullable": true,
|
||||
"description": "Binary addon configuration.",
|
||||
"schema": {
|
||||
"type": "file"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/addon/api/v1/extensions/{id}/status": {
|
||||
"post": {
|
||||
"tags": [
|
||||
"Extensions"
|
||||
],
|
||||
"summary": "Updates the extension status.",
|
||||
"operationId": "UpdateExtensionStatus",
|
||||
"consumes": [
|
||||
"application/json-patch+json",
|
||||
"application/json",
|
||||
"text/json",
|
||||
"application/*+json"
|
||||
],
|
||||
"parameters": [
|
||||
{
|
||||
"type": "integer",
|
||||
"name": "id",
|
||||
"in": "path",
|
||||
"required": true,
|
||||
"description": "The extension id.",
|
||||
"format": "int32",
|
||||
"x-nullable": false
|
||||
},
|
||||
{
|
||||
"name": "statusReport",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"description": "The status report.",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/StatusReport"
|
||||
},
|
||||
"x-nullable": false
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"x-nullable": true,
|
||||
"description": "",
|
||||
"schema": {
|
||||
"type": "file"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"delete": {
|
||||
"tags": [
|
||||
"Extensions"
|
||||
],
|
||||
"summary": "Deletes the extension status.",
|
||||
"operationId": "DeleteExtensionStatus",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "integer",
|
||||
"name": "id",
|
||||
"in": "path",
|
||||
"required": true,
|
||||
"description": "The extension id.",
|
||||
"format": "int32",
|
||||
"x-nullable": false
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"name": "clientId",
|
||||
"in": "query",
|
||||
"description": "The client id. If it is specified, extension status for that client will be deleted.\n If not specified then extension status will be deleted for all clients.",
|
||||
"x-nullable": true
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"x-nullable": true,
|
||||
"description": "",
|
||||
"schema": {
|
||||
"type": "file"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/addon/api/v1/health": {
|
||||
"get": {
|
||||
"tags": [
|
||||
"Health"
|
||||
],
|
||||
"summary": "Checks whether the service is up and running",
|
||||
"operationId": "Health",
|
||||
"responses": {
|
||||
"200": {
|
||||
"x-nullable": true,
|
||||
"description": "Ok - in success case, otherwise return the error description.",
|
||||
"schema": {
|
||||
"type": "file"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/addon/api/v1/report/heartbeat": {
|
||||
"post": {
|
||||
"tags": [
|
||||
"Report"
|
||||
],
|
||||
"summary": "Receives heartbeat from all clients.",
|
||||
"description": "This heartbeat is used to calculate the aggregated status of the Addons.\nIf the service does not receive heartbeat for a certain while,\nall reported status are ignored during status calculation.\nAfter a longer period those ignored status reports are cleaned out.\nBoth these values are configurable in the service.",
|
||||
"operationId": "Report_Heartbeat",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"name": "environment",
|
||||
"in": "query",
|
||||
"x-nullable": true
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"name": "clientIdentity",
|
||||
"in": "query",
|
||||
"x-nullable": true
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"name": "process",
|
||||
"in": "query",
|
||||
"x-nullable": true
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"204": {
|
||||
"description": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"definitions": {
|
||||
"Addon": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"Id",
|
||||
"RequireConfiguration",
|
||||
"Enabled",
|
||||
"Status"
|
||||
],
|
||||
"properties": {
|
||||
"Id": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
},
|
||||
"ManifestVersion": {
|
||||
"type": "string",
|
||||
"description": "Gets the manifest version."
|
||||
},
|
||||
"PackageId": {
|
||||
"type": "string",
|
||||
"description": "Gets the unique identifier of the add-on."
|
||||
},
|
||||
"Name": {
|
||||
"type": "string",
|
||||
"description": "Gets the descriptive name of add-on."
|
||||
},
|
||||
"Description": {
|
||||
"type": "string",
|
||||
"description": "Gets the description of add-on."
|
||||
},
|
||||
"Author": {
|
||||
"type": "string",
|
||||
"description": "Gets the Author of add-on."
|
||||
},
|
||||
"MinVersion": {
|
||||
"type": "string",
|
||||
"description": "Gets the minimum SDL Tridion Sites version this extension supports."
|
||||
},
|
||||
"MaxVersion": {
|
||||
"type": "string",
|
||||
"description": "Gets the maximum SDL Tridion Sites version this extension supports."
|
||||
},
|
||||
"Version": {
|
||||
"type": "string",
|
||||
"description": "Gets the version of this add-on."
|
||||
},
|
||||
"Icon": {
|
||||
"type": "string",
|
||||
"description": "Gets the add-on icon."
|
||||
},
|
||||
"RequireConfiguration": {
|
||||
"description": "Describes whether the custom configuration can be uploaded for the addon.",
|
||||
"$ref": "#/definitions/RequireConfiguration"
|
||||
},
|
||||
"Dependencies": {
|
||||
"type": "array",
|
||||
"description": "Gets the collection of add-on dependencies.",
|
||||
"items": {
|
||||
"$ref": "#/definitions/Dependency"
|
||||
}
|
||||
},
|
||||
"Extensions": {
|
||||
"type": "array",
|
||||
"description": "Gets the list of extensions this add-on contains.",
|
||||
"items": {
|
||||
"$ref": "#/definitions/Extension"
|
||||
}
|
||||
},
|
||||
"Enabled": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"Status": {
|
||||
"$ref": "#/definitions/DeploymentStatus"
|
||||
},
|
||||
"PackageHash": {
|
||||
"type": "string"
|
||||
},
|
||||
"UploadedAt": {
|
||||
"type": "string",
|
||||
"format": "date-time"
|
||||
},
|
||||
"DownloadUri": {
|
||||
"type": "string",
|
||||
"format": "uri"
|
||||
},
|
||||
"StatusReports": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/StatusReport"
|
||||
}
|
||||
},
|
||||
"DownloadIconUri": {
|
||||
"type": "string",
|
||||
"format": "uri"
|
||||
},
|
||||
"DownloadConfigurationUri": {
|
||||
"type": "string",
|
||||
"format": "uri"
|
||||
},
|
||||
"Configuration": {
|
||||
"$ref": "#/definitions/Configuration"
|
||||
}
|
||||
}
|
||||
},
|
||||
"RequireConfiguration": {
|
||||
"type": "string",
|
||||
"description": "Represents whether the Addon requires configuration or not",
|
||||
"x-enumNames": [
|
||||
"Optional",
|
||||
"Yes",
|
||||
"No"
|
||||
],
|
||||
"enum": [
|
||||
"Optional",
|
||||
"Yes",
|
||||
"No"
|
||||
],
|
||||
"x-ms-enum": {
|
||||
"name": "RequireConfiguration",
|
||||
"modelAsString": false
|
||||
}
|
||||
},
|
||||
"Dependency": {
|
||||
"type": "object",
|
||||
"description": "Represents add-on dependencies from the add-on manifest file.",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"Id": {
|
||||
"type": "string",
|
||||
"description": "Gets the name of dependency package"
|
||||
},
|
||||
"Version": {
|
||||
"type": "string",
|
||||
"description": "Gets the version of dependency package"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Extension": {
|
||||
"type": "object",
|
||||
"description": "Represents extension information from the add-on manifest file.",
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"Id",
|
||||
"Status"
|
||||
],
|
||||
"properties": {
|
||||
"Id": {
|
||||
"type": "integer",
|
||||
"description": "Add-on service generated ID.",
|
||||
"format": "int32"
|
||||
},
|
||||
"Name": {
|
||||
"type": "string",
|
||||
"description": "Gets the extension name"
|
||||
},
|
||||
"SupportedVersions": {
|
||||
"type": "string",
|
||||
"description": "Gets the SDL Tridion Sites component versions this extension support"
|
||||
},
|
||||
"Type": {
|
||||
"type": "string",
|
||||
"description": "Gets the identifier of the extension point that this extension extends."
|
||||
},
|
||||
"properties": {
|
||||
"description": "Gets the custom properties associated with this extension as raw json."
|
||||
},
|
||||
"StatusReports": {
|
||||
"type": "array",
|
||||
"description": "List of status reports.",
|
||||
"items": {
|
||||
"$ref": "#/definitions/StatusReport"
|
||||
}
|
||||
},
|
||||
"DisabledClients": {
|
||||
"type": "array",
|
||||
"description": "List of the clients where the extension is disabled.",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"Status": {
|
||||
"description": "Calculated status for this extension.",
|
||||
"$ref": "#/definitions/DeploymentStatus"
|
||||
}
|
||||
}
|
||||
},
|
||||
"StatusReport": {
|
||||
"type": "object",
|
||||
"description": "Represents the extension status object to be received from the update addon status REST method.",
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"Status"
|
||||
],
|
||||
"properties": {
|
||||
"Environment": {
|
||||
"type": "string",
|
||||
"description": "The free-form unique identifier of the environment of the client reporting the addon and extension status."
|
||||
},
|
||||
"ClientIdentity": {
|
||||
"type": "string",
|
||||
"description": "The free form unique identifier of the client who reporting the addon and extension status.\n\nIs used in order to calculate the addon and extension status based on all the client's reports.\nE.g. at least one reported fail - addon extension gets failed status."
|
||||
},
|
||||
"Process": {
|
||||
"type": "string",
|
||||
"description": "The free-form unique identifier of the process of the client reporting the addon and extension status."
|
||||
},
|
||||
"Status": {
|
||||
"description": "The addon status.",
|
||||
"$ref": "#/definitions/DeploymentStatus"
|
||||
},
|
||||
"Message": {
|
||||
"type": "string",
|
||||
"description": "The exception details for the case of failed status."
|
||||
}
|
||||
}
|
||||
},
|
||||
"DeploymentStatus": {
|
||||
"type": "string",
|
||||
"description": "Represents the status the Addon or Extension is currently in",
|
||||
"x-enumNames": [
|
||||
"Fail",
|
||||
"Pending",
|
||||
"Success",
|
||||
"WaitingConfiguration",
|
||||
"Disabled"
|
||||
],
|
||||
"enum": [
|
||||
"Fail",
|
||||
"Pending",
|
||||
"Success",
|
||||
"WaitingConfiguration",
|
||||
"Disabled"
|
||||
],
|
||||
"x-ms-enum": {
|
||||
"name": "DeploymentStatus",
|
||||
"modelAsString": false
|
||||
}
|
||||
},
|
||||
"Configuration": {
|
||||
"type": "object",
|
||||
"description": "Represents add-on configuration information",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"FileName": {
|
||||
"type": "string",
|
||||
"description": "Gets the configuration file name."
|
||||
},
|
||||
"ContentHash": {
|
||||
"type": "string",
|
||||
"description": "Gets the hash of configuration file content."
|
||||
},
|
||||
"UploadedAt": {
|
||||
"type": "string",
|
||||
"description": "Gets configuration upload date.",
|
||||
"format": "date-time"
|
||||
}
|
||||
}
|
||||
},
|
||||
"UploadResult": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"Id",
|
||||
"IsModified"
|
||||
],
|
||||
"properties": {
|
||||
"Id": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
},
|
||||
"IsModified": {
|
||||
"type": "boolean"
|
||||
}
|
||||
}
|
||||
},
|
||||
"IHeaderDictionary": {
|
||||
"type": "object",
|
||||
"x-abstract": true,
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"Item"
|
||||
],
|
||||
"properties": {
|
||||
"Item": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"ContentLength": {
|
||||
"type": "integer",
|
||||
"format": "int64"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Manifest": {
|
||||
"type": "object",
|
||||
"description": "Represents add-on information from the add-on manifest file.",
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"RequireConfiguration"
|
||||
],
|
||||
"properties": {
|
||||
"ManifestVersion": {
|
||||
"type": "string",
|
||||
"description": "Gets the manifest version."
|
||||
},
|
||||
"Id": {
|
||||
"type": "string",
|
||||
"description": "Gets the unique identifier of the add-on."
|
||||
},
|
||||
"Name": {
|
||||
"type": "string",
|
||||
"description": "Gets the descriptive name of add-on."
|
||||
},
|
||||
"Description": {
|
||||
"type": "string",
|
||||
"description": "Gets the description of add-on."
|
||||
},
|
||||
"Author": {
|
||||
"type": "string",
|
||||
"description": "Gets the Author of add-on."
|
||||
},
|
||||
"MinVersion": {
|
||||
"type": "string",
|
||||
"description": "Gets the minimum SDL Tridion Sites version this extension supports."
|
||||
},
|
||||
"MaxVersion": {
|
||||
"type": "string",
|
||||
"description": "Gets the maximum SDL Tridion Sites version this extension supports."
|
||||
},
|
||||
"Version": {
|
||||
"type": "string",
|
||||
"description": "Gets the version of this add-on."
|
||||
},
|
||||
"Icon": {
|
||||
"type": "string",
|
||||
"description": "Gets the add-on icon."
|
||||
},
|
||||
"RequireConfiguration": {
|
||||
"description": "Describes whether the custom configuration can be uploaded for the addon.",
|
||||
"$ref": "#/definitions/RequireConfiguration"
|
||||
},
|
||||
"Dependencies": {
|
||||
"type": "array",
|
||||
"description": "Gets the collection of add-on dependencies.",
|
||||
"items": {
|
||||
"$ref": "#/definitions/DependencyManifest"
|
||||
}
|
||||
},
|
||||
"Extensions": {
|
||||
"type": "array",
|
||||
"description": "Gets the list of extensions this add-on contains.",
|
||||
"items": {
|
||||
"$ref": "#/definitions/ExtensionManifest"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"DependencyManifest": {
|
||||
"type": "object",
|
||||
"description": "Represents add-on dependencies from the add-on manifest file.",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"Id": {
|
||||
"type": "string",
|
||||
"description": "Gets the name of dependency package"
|
||||
},
|
||||
"Version": {
|
||||
"type": "string",
|
||||
"description": "Gets the version of dependency package"
|
||||
}
|
||||
}
|
||||
},
|
||||
"ExtensionManifest": {
|
||||
"type": "object",
|
||||
"description": "Represents extension information from the add-on manifest file.",
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"Id"
|
||||
],
|
||||
"properties": {
|
||||
"Id": {
|
||||
"type": "integer",
|
||||
"description": "Add-on service generated ID.",
|
||||
"format": "int32"
|
||||
},
|
||||
"Name": {
|
||||
"type": "string",
|
||||
"description": "Gets the extension name"
|
||||
},
|
||||
"SupportedVersions": {
|
||||
"type": "string",
|
||||
"description": "Gets the SDL Tridion Sites component versions this extension support"
|
||||
},
|
||||
"Type": {
|
||||
"type": "string",
|
||||
"description": "Gets the identifier of the extension point that this extension extends."
|
||||
},
|
||||
"properties": {
|
||||
"description": "Gets the additional properties required to configure the extension."
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
10503
test/mock/v2/test-docs.json
Normal file
10503
test/mock/v2/test-docs.json
Normal file
File diff suppressed because it is too large
Load Diff
18116
test/mock/v2/test-sites.json
Normal file
18116
test/mock/v2/test-sites.json
Normal file
File diff suppressed because it is too large
Load Diff
4217
test/mock/v3/test-access.json
Normal file
4217
test/mock/v3/test-access.json
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,11 +1,17 @@
|
||||
openapi: "3.0.0"
|
||||
swagger: "2.0"
|
||||
info:
|
||||
version: 1.0.0
|
||||
title: Swagger Petstore
|
||||
license:
|
||||
name: MIT
|
||||
servers:
|
||||
- url: http://petstore.swagger.io/v1
|
||||
host: petstore.swagger.io
|
||||
basePath: /v1
|
||||
schemes:
|
||||
- http
|
||||
consumes:
|
||||
- application/json
|
||||
produces:
|
||||
- application/json
|
||||
paths:
|
||||
/pets:
|
||||
get:
|
||||
@ -14,45 +20,37 @@ paths:
|
||||
tags:
|
||||
- pets
|
||||
parameters:
|
||||
- name: limit
|
||||
in: query
|
||||
description: How many items to return at one time (max 100)
|
||||
required: false
|
||||
schema:
|
||||
type: integer
|
||||
format: int32
|
||||
- name: limit
|
||||
in: query
|
||||
description: How many items to return at one time (max 100)
|
||||
required: false
|
||||
type: integer
|
||||
format: int32
|
||||
responses:
|
||||
'200':
|
||||
"200":
|
||||
description: A paged array of pets
|
||||
headers:
|
||||
x-next:
|
||||
type: string
|
||||
description: A link to the next page of responses
|
||||
schema:
|
||||
type: string
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Pets"
|
||||
schema:
|
||||
$ref: '#/definitions/Pets'
|
||||
default:
|
||||
description: unexpected error
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Error"
|
||||
schema:
|
||||
$ref: '#/definitions/Error'
|
||||
post:
|
||||
summary: Create a pet
|
||||
operationId: createPets
|
||||
tags:
|
||||
- pets
|
||||
responses:
|
||||
'201':
|
||||
"201":
|
||||
description: Null response
|
||||
default:
|
||||
description: unexpected error
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Error"
|
||||
schema:
|
||||
$ref: '#/definitions/Error'
|
||||
/pets/{petId}:
|
||||
get:
|
||||
summary: Info for a specific pet
|
||||
@ -60,52 +58,46 @@ paths:
|
||||
tags:
|
||||
- pets
|
||||
parameters:
|
||||
- name: petId
|
||||
in: path
|
||||
required: true
|
||||
description: The id of the pet to retrieve
|
||||
schema:
|
||||
type: string
|
||||
- name: petId
|
||||
in: path
|
||||
required: true
|
||||
description: The id of the pet to retrieve
|
||||
type: string
|
||||
responses:
|
||||
'200':
|
||||
"200":
|
||||
description: Expected response to a valid request
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Pet"
|
||||
schema:
|
||||
$ref: '#/definitions/Pets'
|
||||
default:
|
||||
description: unexpected error
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Error"
|
||||
components:
|
||||
schemas:
|
||||
Pet:
|
||||
type: object
|
||||
required:
|
||||
- id
|
||||
- name
|
||||
properties:
|
||||
id:
|
||||
type: integer
|
||||
format: int64
|
||||
name:
|
||||
type: string
|
||||
tag:
|
||||
type: string
|
||||
Pets:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/components/schemas/Pet"
|
||||
Error:
|
||||
type: object
|
||||
required:
|
||||
- code
|
||||
- message
|
||||
properties:
|
||||
code:
|
||||
type: integer
|
||||
format: int32
|
||||
message:
|
||||
type: string
|
||||
schema:
|
||||
$ref: '#/definitions/Error'
|
||||
definitions:
|
||||
Pet:
|
||||
type: "object"
|
||||
required:
|
||||
- id
|
||||
- name
|
||||
properties:
|
||||
id:
|
||||
type: integer
|
||||
format: int64
|
||||
name:
|
||||
type: string
|
||||
tag:
|
||||
type: string
|
||||
Pets:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/definitions/Pet'
|
||||
Error:
|
||||
type: "object"
|
||||
required:
|
||||
- code
|
||||
- message
|
||||
properties:
|
||||
code:
|
||||
type: integer
|
||||
format: int32
|
||||
message:
|
||||
type: string
|
||||
|
||||
@ -7,7 +7,7 @@
|
||||
"paths": {
|
||||
"/": {
|
||||
"get": {
|
||||
"operationId": "listVersionsv2",
|
||||
"operationId": "listVersions",
|
||||
"summary": "List API versions",
|
||||
"responses": {
|
||||
"200": {
|
||||
@ -64,7 +64,7 @@
|
||||
},
|
||||
"/v2": {
|
||||
"get": {
|
||||
"operationId": "getVersionDetailsv2",
|
||||
"operationId": "getVersionDetails",
|
||||
"summary": "Show API version details",
|
||||
"responses": {
|
||||
"200": {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user