mirror of
https://github.com/ferdikoomen/openapi-typescript-codegen.git
synced 2025-12-08 20:16:21 +00:00
- Added initial setup
This commit is contained in:
parent
9f5586523f
commit
6ffbe926d5
9
.editorconfig
Executable file
9
.editorconfig
Executable file
@ -0,0 +1,9 @@
|
||||
root = true
|
||||
|
||||
[*]
|
||||
end_of_line = lf
|
||||
charset = utf-8
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
21
.eslintrc.json
Normal file
21
.eslintrc.json
Normal file
@ -0,0 +1,21 @@
|
||||
{
|
||||
"parser": "@typescript-eslint/parser",
|
||||
"extends": [
|
||||
"plugin:@typescript-eslint/recommended",
|
||||
"prettier/@typescript-eslint",
|
||||
"plugin:prettier/recommended"
|
||||
],
|
||||
"env": {
|
||||
"es6": true,
|
||||
"node": true,
|
||||
"jest": true
|
||||
},
|
||||
"rules": {
|
||||
"@typescript-eslint/no-explicit-any": 0,
|
||||
"@typescript-eslint/no-non-null-assertion": 0,
|
||||
"@typescript-eslint/explicit-function-return-type": 0,
|
||||
"prettier/prettier": [
|
||||
"error"
|
||||
]
|
||||
}
|
||||
}
|
||||
14
.gitignore
vendored
Normal file
14
.gitignore
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
node_modules
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
junit.xml
|
||||
.DS_Store
|
||||
.tmp
|
||||
.idea
|
||||
.vscode
|
||||
*.iml
|
||||
dist
|
||||
archive
|
||||
coverage
|
||||
test/tmp
|
||||
7
.prettierrc.json
Normal file
7
.prettierrc.json
Normal file
@ -0,0 +1,7 @@
|
||||
{
|
||||
"semi": true,
|
||||
"singleQuote": true,
|
||||
"trailingComma": "es5",
|
||||
"printWidth": 500,
|
||||
"tabWidth": 4
|
||||
}
|
||||
5
.travis.yml
Normal file
5
.travis.yml
Normal file
@ -0,0 +1,5 @@
|
||||
language: node_js
|
||||
node_js:
|
||||
- node
|
||||
script:
|
||||
- npm run test
|
||||
66
README.md
66
README.md
@ -1 +1,65 @@
|
||||
# openapi-typescript-codegen
|
||||
# OpenAPI Typescript Codegen
|
||||
|
||||
[](https://www.npmjs.com/package/openapi-typescript-codegen)
|
||||
[](https://www.npmjs.com/package/openapi-typescript-codegen)
|
||||
[](https://david-dm.org/ferdikoomen/openapi-typescript-codegen)
|
||||
[](https://bundlephobia.com/result?p=openapi-typescript-codegen)
|
||||
[](https://travis-ci.org/ferdikoomen/openapi-typescript-codegen)
|
||||
[](https://lgtm.com/projects/g/ferdikoomen/openapi-typescript-codegen)
|
||||
|
||||
> NodeJS library that generates Typescript or Javascript clients based on the OpenAPI specification.
|
||||
|
||||
#### Why?
|
||||
- Frontend ❤️ OpenAPI, but we do not want to use JAVA codegen in our builds.
|
||||
- Quick, lightweight, robust and framework agnostic.
|
||||
- Supports generation of Typescript and Javascript clients.
|
||||
- Supports generations of fetch and XHR http clients.
|
||||
- Supports OpenAPI specification v2.0 and v3.0.
|
||||
- Supports JSON and YAML files for input.
|
||||
|
||||
|
||||
## Known issues:
|
||||
- If you use enums inside your models / definitions then those enums are now
|
||||
inside a namespace with the same name as your model. This is called declaration
|
||||
merging. However Babel 7 now support compiling of Typescript and right now they
|
||||
do not support namespaces.
|
||||
|
||||
|
||||
## Installation
|
||||
|
||||
```
|
||||
npm install openapi-typescript-codegen --save-dev
|
||||
```
|
||||
|
||||
## Example
|
||||
|
||||
**package.json**
|
||||
```json
|
||||
{
|
||||
"scripts": {
|
||||
"generate": "openapi ./api/openapi.json ./dist"
|
||||
}
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
Command line
|
||||
|
||||
```
|
||||
npm install openapi-typescript-codegen -g
|
||||
|
||||
openapi ./api/openapi.json ./dist
|
||||
```
|
||||
|
||||
NodeJS API:
|
||||
|
||||
```
|
||||
const OpenAPI = require('openapi-typescript-codegen');
|
||||
|
||||
const result = OpenAPI.generate(
|
||||
'./api/openapi.json',
|
||||
'./dist'
|
||||
);
|
||||
|
||||
console.log(result);
|
||||
```
|
||||
|
||||
29
bin/index.js
Executable file
29
bin/index.js
Executable file
@ -0,0 +1,29 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
'use strict';
|
||||
|
||||
const path = require('path');
|
||||
const program = require('commander');
|
||||
const pkg = require('../package.json');
|
||||
|
||||
program
|
||||
.version(pkg.version)
|
||||
.option('--input [value]', 'Path to swagger specification', './spec.json')
|
||||
.option('--output [value]', 'Output directory', './generated')
|
||||
.option('--language', 'Language to generate [typescript, javascript]', 'typescript')
|
||||
.option('--http-client', 'HTTP client to generate [fetch, xhr]', 'fetch')
|
||||
.parse(process.argv);
|
||||
|
||||
const SwaggerCodegen = require(path.resolve(__dirname, '../dist/index.js'));
|
||||
|
||||
if (SwaggerCodegen) {
|
||||
|
||||
const result = SwaggerCodegen.generate(
|
||||
program.input,
|
||||
program.output,
|
||||
program.language,
|
||||
program.httpClient
|
||||
);
|
||||
|
||||
console.log(result);
|
||||
}
|
||||
17
jest.config.js
Normal file
17
jest.config.js
Normal file
@ -0,0 +1,17 @@
|
||||
module.exports = {
|
||||
testRegex: '\\.spec\\.tsx?$',
|
||||
testEnvironment: 'node',
|
||||
transform: {
|
||||
'\\.tsx?$': 'ts-jest'
|
||||
},
|
||||
globals: {
|
||||
'ts-jest': {
|
||||
compiler: 'typescript',
|
||||
tsConfig: {
|
||||
declaration: false,
|
||||
declarationMap: false,
|
||||
sourceMap: false
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
86
package.json
Normal file
86
package.json
Normal file
@ -0,0 +1,86 @@
|
||||
{
|
||||
"name": "openapi-typescript-codegen",
|
||||
"version": "0.0.1",
|
||||
"description": "NodeJS library that generates Typescript or Javascript clients based on the OpenAPI specification.",
|
||||
"author": "Ferdi Koomen",
|
||||
"homepage": "https://github.com/ferdikoomen/openapi-typescript-codegen",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/ferdikoomen/openapi-typescript-codegen.git"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/ferdikoomen/openapi-typescript-codegen/issues"
|
||||
},
|
||||
"license": "MIT",
|
||||
"keywords": [
|
||||
"openapi",
|
||||
"swagger",
|
||||
"codegen",
|
||||
"generator",
|
||||
"client",
|
||||
"typescript",
|
||||
"javascript",
|
||||
"yaml",
|
||||
"json",
|
||||
"fetch",
|
||||
"xhr",
|
||||
"node"
|
||||
],
|
||||
"maintainers": [
|
||||
{
|
||||
"name": "Ferdi Koomen",
|
||||
"email": "info@madebyferdi.com"
|
||||
}
|
||||
],
|
||||
"main": "dist/index.js",
|
||||
"module": "dist/index.js",
|
||||
"bin": {
|
||||
"openapi": "bin/index.js"
|
||||
},
|
||||
"files": [
|
||||
"bin/index.js",
|
||||
"dist/index.js",
|
||||
"dist/**/*.js",
|
||||
"src/templates/javascript/*.hbs",
|
||||
"src/templates/typescript/*.hbs"
|
||||
],
|
||||
"scripts": {
|
||||
"clean": "rimraf \"./dist\" \"./test/tmp\"",
|
||||
"build": "tsc",
|
||||
"start": "tsc && node ./test/index.js",
|
||||
"test": "jest ./src",
|
||||
"test:watch": "jest --watch",
|
||||
"test:coverage": "jest --coverage",
|
||||
"eslint": "eslint \"./src/**/*.ts\"",
|
||||
"eslint:fix": "eslint \"./src/**/*.ts\" --fix",
|
||||
"prettier": "prettier \"./src/**/*.ts\" --check",
|
||||
"prettier:fix": "prettier \"./src/**/*.ts\" --write"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/jest": "24.0.20",
|
||||
"@types/js-yaml": "3.12.1",
|
||||
"@types/mkdirp": "0.5.2",
|
||||
"@types/node": "12.11.7",
|
||||
"@types/rimraf": "2.0.3",
|
||||
"@types/yup": "0.26.24",
|
||||
"@typescript-eslint/eslint-plugin": "2.5.0",
|
||||
"@typescript-eslint/parser": "2.5.0",
|
||||
"camelcase": "5.3.1",
|
||||
"chalk": "2.4.2",
|
||||
"commander": "3.0.2",
|
||||
"eslint": "6.6.0",
|
||||
"eslint-config-prettier": "6.5.0",
|
||||
"eslint-plugin-prettier": "3.1.1",
|
||||
"handlebars": "4.4.5",
|
||||
"jest": "24.9.0",
|
||||
"jest-cli": "24.9.0",
|
||||
"js-yaml": "3.13.1",
|
||||
"mkdirp": "0.5.1",
|
||||
"path": "0.12.7",
|
||||
"prettier": "1.18.2",
|
||||
"rimraf": "3.0.0",
|
||||
"ts-jest": "24.1.0",
|
||||
"typescript": "3.6.4",
|
||||
"yup": "0.27.0"
|
||||
}
|
||||
}
|
||||
11
src/client/interfaces/Client.d.ts
vendored
Normal file
11
src/client/interfaces/Client.d.ts
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
import { Model } from './Model';
|
||||
import { Service } from './Service';
|
||||
import { Schema } from './Schema';
|
||||
|
||||
export interface Client {
|
||||
version: string;
|
||||
server: string;
|
||||
models: Map<string, Model>;
|
||||
schemas: Map<string, Schema>;
|
||||
services: Map<string, Service>;
|
||||
}
|
||||
14
src/client/interfaces/Model.d.ts
vendored
Normal file
14
src/client/interfaces/Model.d.ts
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
import { ModelProperty } from './ModelProperty';
|
||||
import { ModelEnum } from './ModelEnum';
|
||||
|
||||
export interface Model {
|
||||
name: string;
|
||||
base: string;
|
||||
type: string;
|
||||
template: string;
|
||||
description: string | null;
|
||||
extends: string | null;
|
||||
imports: string[];
|
||||
properties: ModelProperty[];
|
||||
enums: ModelEnum[];
|
||||
}
|
||||
7
src/client/interfaces/ModelEnum.ts
Normal file
7
src/client/interfaces/ModelEnum.ts
Normal file
@ -0,0 +1,7 @@
|
||||
import { ModelEnumProperty } from './ModelEnumProperty';
|
||||
|
||||
export interface ModelEnum {
|
||||
name: string;
|
||||
value: string;
|
||||
values: ModelEnumProperty[];
|
||||
}
|
||||
5
src/client/interfaces/ModelEnumProperty.ts
Normal file
5
src/client/interfaces/ModelEnumProperty.ts
Normal file
@ -0,0 +1,5 @@
|
||||
export interface ModelEnumProperty {
|
||||
type: string;
|
||||
name: string;
|
||||
value: string | number;
|
||||
}
|
||||
8
src/client/interfaces/ModelProperties.d.ts
vendored
Normal file
8
src/client/interfaces/ModelProperties.d.ts
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
import { ModelProperty } from './ModelProperty';
|
||||
import { ModelEnum } from './ModelEnum';
|
||||
|
||||
export interface ModelProperties {
|
||||
imports: string[];
|
||||
properties: ModelProperty[];
|
||||
enums: ModelEnum[];
|
||||
}
|
||||
10
src/client/interfaces/ModelProperty.d.ts
vendored
Normal file
10
src/client/interfaces/ModelProperty.d.ts
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
export interface ModelProperty {
|
||||
name: string;
|
||||
type: string;
|
||||
base: string;
|
||||
template: string | null;
|
||||
description: string | null;
|
||||
required: boolean;
|
||||
readOnly: boolean;
|
||||
imports: string[];
|
||||
}
|
||||
5
src/client/interfaces/Schema.d.ts
vendored
Normal file
5
src/client/interfaces/Schema.d.ts
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
export interface Schema {
|
||||
name: string;
|
||||
base: string;
|
||||
imports: [];
|
||||
}
|
||||
5
src/client/interfaces/Service.d.ts
vendored
Normal file
5
src/client/interfaces/Service.d.ts
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
export interface Service {
|
||||
name: string;
|
||||
base: string;
|
||||
imports: [];
|
||||
}
|
||||
6
src/client/interfaces/Type.d.ts
vendored
Normal file
6
src/client/interfaces/Type.d.ts
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
export interface Type {
|
||||
type: string;
|
||||
base: string;
|
||||
template: string | null;
|
||||
imports: string[];
|
||||
}
|
||||
65
src/index.ts
Normal file
65
src/index.ts
Normal file
@ -0,0 +1,65 @@
|
||||
import * as path from 'path';
|
||||
import { parse as parseV2 } from './openApi/v2';
|
||||
import { parse as parseV3 } from './openApi/v3';
|
||||
import { readHandlebarsTemplates } from './utils/readHandlebarsTemplates';
|
||||
import { getOpenApiSpec } from './utils/getOpenApiSpec';
|
||||
import { writeClient } from './utils/writeClient';
|
||||
import * as os from 'os';
|
||||
import chalk from 'chalk';
|
||||
import { getOpenApiVersion, OpenApiVersion } from './utils/getOpenApiVersion';
|
||||
|
||||
export enum Language {
|
||||
TYPESCRIPT = 'typescript',
|
||||
JAVASCRIPT = 'javascript',
|
||||
}
|
||||
|
||||
export enum HttpClient {
|
||||
FETCH = 'fetch',
|
||||
XHR = 'xhr',
|
||||
}
|
||||
|
||||
/**
|
||||
* 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,
|
||||
* service layer, etc.
|
||||
* @param input The relative location of the OpenAPI spec.
|
||||
* @param output The relative location of the output directory
|
||||
* @param language: The language that should be generated (Typescript or Javascript)
|
||||
* @param httpClient: The selected httpClient (fetch or XHR)
|
||||
*/
|
||||
export function generate(input: string, output: string, language: Language = Language.TYPESCRIPT, httpClient: HttpClient = HttpClient.FETCH): void {
|
||||
const inputPath = path.resolve(process.cwd(), input);
|
||||
const outputPath = path.resolve(process.cwd(), output);
|
||||
|
||||
console.log(chalk.bold.green('Generate:'));
|
||||
console.log(chalk.grey(' Input:'), input);
|
||||
console.log(chalk.grey(' Output:'), output);
|
||||
console.log(chalk.grey(' Language:'), language);
|
||||
console.log(chalk.grey(' HTTP client:'), httpClient);
|
||||
console.log(os.EOL);
|
||||
|
||||
try {
|
||||
const openApi = getOpenApiSpec(inputPath);
|
||||
const openApiVersion = getOpenApiVersion(openApi);
|
||||
const templates = readHandlebarsTemplates(language);
|
||||
|
||||
switch (language) {
|
||||
case Language.JAVASCRIPT:
|
||||
case Language.TYPESCRIPT:
|
||||
// Generate and write version 2 client
|
||||
if (openApiVersion === OpenApiVersion.V2) {
|
||||
const clientV2 = parseV2(openApi);
|
||||
writeClient(clientV2, language, templates, outputPath);
|
||||
}
|
||||
|
||||
// Generate and write version 3 client
|
||||
if (openApiVersion === OpenApiVersion.V3) {
|
||||
const clientV3 = parseV3(openApi);
|
||||
writeClient(clientV3, language, templates, outputPath);
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
16
src/openApi/v2/index.ts
Normal file
16
src/openApi/v2/index.ts
Normal file
@ -0,0 +1,16 @@
|
||||
import { OpenApi } from './interfaces/OpenApi';
|
||||
import { Client } from '../../client/interfaces/Client';
|
||||
import { getServer } from './parser/getServer';
|
||||
import { getServices } from './parser/getServices';
|
||||
import { getModels } from './parser/getModels';
|
||||
import { getSchemas } from './parser/getSchemas';
|
||||
|
||||
export function parse(openApi: OpenApi): Client {
|
||||
return {
|
||||
version: openApi.info.version,
|
||||
server: getServer(openApi),
|
||||
models: getModels(openApi),
|
||||
schemas: getSchemas(openApi),
|
||||
services: getServices(openApi),
|
||||
};
|
||||
}
|
||||
31
src/openApi/v2/interfaces/OpenApi.d.ts
vendored
Normal file
31
src/openApi/v2/interfaces/OpenApi.d.ts
vendored
Normal file
@ -0,0 +1,31 @@
|
||||
import { Dictionary } from '../../../utils/types';
|
||||
import { OpenApiExternalDocs } from './OpenApiExternalDocs';
|
||||
import { OpenApiInfo } from './OpenApiInfo';
|
||||
import { OpenApiParameter } from './OpenApiParameter';
|
||||
import { OpenApiPath } from './OpenApiPath';
|
||||
import { OpenApiResponse } from './OpenApiResponse';
|
||||
import { OpenApiSchema } from './OpenApiSchema';
|
||||
import { OpenApiSecurityRequirement } from './OpenApiSecurityRequirement';
|
||||
import { OpenApiSecurityScheme } from './OpenApiSecurityScheme';
|
||||
import { OpenApiTag } from './OpenApiTag';
|
||||
|
||||
/**
|
||||
* https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md
|
||||
*/
|
||||
export interface OpenApi {
|
||||
swagger: string;
|
||||
info: OpenApiInfo;
|
||||
host?: string;
|
||||
basePath?: string;
|
||||
schemes?: string[];
|
||||
consumes?: string[];
|
||||
produces?: string[];
|
||||
paths: Dictionary<OpenApiPath>;
|
||||
definitions?: Dictionary<OpenApiSchema>;
|
||||
parameters?: Dictionary<OpenApiParameter>;
|
||||
responses?: Dictionary<OpenApiResponse>;
|
||||
securityDefinitions?: Dictionary<OpenApiSecurityScheme>;
|
||||
security?: OpenApiSecurityRequirement[];
|
||||
tags?: OpenApiTag[];
|
||||
externalDocs?: OpenApiExternalDocs;
|
||||
}
|
||||
8
src/openApi/v2/interfaces/OpenApiContact.d.ts
vendored
Normal file
8
src/openApi/v2/interfaces/OpenApiContact.d.ts
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
/**
|
||||
* https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#contactObject
|
||||
*/
|
||||
export interface OpenApiContact {
|
||||
name?: string;
|
||||
url?: string;
|
||||
email?: string;
|
||||
}
|
||||
6
src/openApi/v2/interfaces/OpenApiExample.d.ts
vendored
Normal file
6
src/openApi/v2/interfaces/OpenApiExample.d.ts
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
/**
|
||||
* https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#exampleObject
|
||||
*/
|
||||
export interface OpenApiExample {
|
||||
[mimetype: string]: any;
|
||||
}
|
||||
7
src/openApi/v2/interfaces/OpenApiExternalDocs.d.ts
vendored
Normal file
7
src/openApi/v2/interfaces/OpenApiExternalDocs.d.ts
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
/**
|
||||
* https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#externalDocumentationObject
|
||||
*/
|
||||
export interface OpenApiExternalDocs {
|
||||
description?: string;
|
||||
url: string;
|
||||
}
|
||||
26
src/openApi/v2/interfaces/OpenApiHeader.d.ts
vendored
Normal file
26
src/openApi/v2/interfaces/OpenApiHeader.d.ts
vendored
Normal file
@ -0,0 +1,26 @@
|
||||
import { Dictionary } from '../../../utils/types';
|
||||
import { OpenApiItems } from './OpenApiItems';
|
||||
|
||||
/**
|
||||
* https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#headerObject
|
||||
*/
|
||||
export interface OpenApiHeader {
|
||||
description?: string;
|
||||
type: 'string' | 'number' | 'integer' | 'boolean' | 'array';
|
||||
format?: 'int32' | 'int64' | 'float' | 'double' | 'string' | 'boolean' | 'byte' | 'binary' | 'date' | 'date-time' | 'password';
|
||||
items?: Dictionary<OpenApiItems>;
|
||||
collectionFormat?: 'csv' | 'ssv' | 'tsv' | 'pipes';
|
||||
default?: any;
|
||||
maximum?: number;
|
||||
exclusiveMaximum?: boolean;
|
||||
minimum?: number;
|
||||
exclusiveMinimum?: boolean;
|
||||
maxLength?: number;
|
||||
minLength?: number;
|
||||
pattern?: string;
|
||||
maxItems?: number;
|
||||
minItems?: number;
|
||||
uniqueItems?: boolean;
|
||||
enum?: string[] | number[];
|
||||
multipleOf?: number;
|
||||
}
|
||||
14
src/openApi/v2/interfaces/OpenApiInfo.d.ts
vendored
Normal file
14
src/openApi/v2/interfaces/OpenApiInfo.d.ts
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
import { OpenApiContact } from './OpenApiContact';
|
||||
import { OpenApiLicense } from './OpenApiLicense';
|
||||
|
||||
/**
|
||||
* https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#infoObject
|
||||
*/
|
||||
export interface OpenApiInfo {
|
||||
title: string;
|
||||
description?: string;
|
||||
termsOfService?: string;
|
||||
contact?: OpenApiContact;
|
||||
license?: OpenApiLicense;
|
||||
version: string;
|
||||
}
|
||||
22
src/openApi/v2/interfaces/OpenApiItems.d.ts
vendored
Normal file
22
src/openApi/v2/interfaces/OpenApiItems.d.ts
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
/**
|
||||
* https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#itemsObject
|
||||
*/
|
||||
export interface OpenApiItems {
|
||||
type?: 'string' | 'number' | 'integer' | 'boolean' | 'array';
|
||||
format?: 'int32' | 'int64' | 'float' | 'double' | 'string' | 'boolean' | 'byte' | 'binary' | 'date' | 'date-time' | 'password';
|
||||
items?: OpenApiItems;
|
||||
collectionFormat?: 'csv' | 'ssv' | 'tsv' | 'pipes';
|
||||
default?: any;
|
||||
maximum?: number;
|
||||
exclusiveMaximum?: number;
|
||||
minimum?: number;
|
||||
exclusiveMinimum?: number;
|
||||
maxLength?: number;
|
||||
minLength?: number;
|
||||
pattern?: string;
|
||||
maxItems?: number;
|
||||
minItems?: number;
|
||||
uniqueItems?: number;
|
||||
enum?: string[] | number[];
|
||||
multipleOf?: number;
|
||||
}
|
||||
7
src/openApi/v2/interfaces/OpenApiLicense.d.ts
vendored
Normal file
7
src/openApi/v2/interfaces/OpenApiLicense.d.ts
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
/**
|
||||
* https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#licenseObject
|
||||
*/
|
||||
export interface OpenApiLicense {
|
||||
name: string;
|
||||
url?: string;
|
||||
}
|
||||
23
src/openApi/v2/interfaces/OpenApiOperation.d.ts
vendored
Normal file
23
src/openApi/v2/interfaces/OpenApiOperation.d.ts
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
import { OpenApiExternalDocs } from './OpenApiExternalDocs';
|
||||
import { OpenApiParameter } from './OpenApiParameter';
|
||||
import { OpenApiReference } from './OpenApiReference';
|
||||
import { OpenApiResponses } from './OpenApiResponses';
|
||||
import { OpenApiSecurityRequirement } from './OpenApiSecurityRequirement';
|
||||
|
||||
/**
|
||||
* https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#operationObject
|
||||
*/
|
||||
export interface OpenApiOperation {
|
||||
tags?: string[];
|
||||
summary?: string;
|
||||
description?: string;
|
||||
externalDocs?: OpenApiExternalDocs;
|
||||
operationId?: string;
|
||||
consumes?: string[];
|
||||
produces?: string[];
|
||||
parameters?: OpenApiParameter[] | OpenApiReference[];
|
||||
responses: OpenApiResponses;
|
||||
schemes: ('http' | 'https' | 'ws' | 'wss')[];
|
||||
deprecated?: boolean;
|
||||
security?: OpenApiSecurityRequirement[];
|
||||
}
|
||||
31
src/openApi/v2/interfaces/OpenApiParameter.d.ts
vendored
Normal file
31
src/openApi/v2/interfaces/OpenApiParameter.d.ts
vendored
Normal file
@ -0,0 +1,31 @@
|
||||
import { OpenApiItems } from './OpenApiItems';
|
||||
import { OpenApiSchema } from './OpenApiSchema';
|
||||
|
||||
/**
|
||||
* https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#parameterObject
|
||||
*/
|
||||
export interface OpenApiParameter {
|
||||
name: string;
|
||||
in: 'path' | 'query' | 'header' | 'formData' | 'body';
|
||||
description?: string;
|
||||
required?: boolean;
|
||||
schema?: OpenApiSchema;
|
||||
type?: 'string' | 'number' | 'integer' | 'boolean' | 'array' | 'file';
|
||||
format?: 'int32' | 'int64' | 'float' | 'double' | 'string' | 'boolean' | 'byte' | 'binary' | 'date' | 'date-time' | 'password';
|
||||
allowEmptyValue?: boolean;
|
||||
items?: OpenApiItems;
|
||||
collectionFormat?: 'csv' | 'ssv' | 'tsv' | 'pipes' | 'multi';
|
||||
default?: any;
|
||||
maximum?: number;
|
||||
exclusiveMaximum?: boolean;
|
||||
minimum?: number;
|
||||
exclusiveMinimum?: boolean;
|
||||
maxLength?: number;
|
||||
minLength?: number;
|
||||
pattern?: string;
|
||||
maxItems?: number;
|
||||
minItems?: number;
|
||||
uniqueItems?: boolean;
|
||||
enum?: string[] | number[];
|
||||
multipleOf?: number;
|
||||
}
|
||||
18
src/openApi/v2/interfaces/OpenApiPath.d.ts
vendored
Normal file
18
src/openApi/v2/interfaces/OpenApiPath.d.ts
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
import { OpenApiOperation } from './OpenApiOperation';
|
||||
import { OpenApiParameter } from './OpenApiParameter';
|
||||
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;
|
||||
delete?: OpenApiOperation;
|
||||
options?: OpenApiOperation;
|
||||
head?: OpenApiOperation;
|
||||
patch?: OpenApiOperation;
|
||||
parameters?: OpenApiParameter[] | OpenApiReference[];
|
||||
}
|
||||
6
src/openApi/v2/interfaces/OpenApiReference.d.ts
vendored
Normal file
6
src/openApi/v2/interfaces/OpenApiReference.d.ts
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
/**
|
||||
* https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#referenceObject
|
||||
*/
|
||||
export interface OpenApiReference {
|
||||
$ref: string;
|
||||
}
|
||||
14
src/openApi/v2/interfaces/OpenApiResponse.d.ts
vendored
Normal file
14
src/openApi/v2/interfaces/OpenApiResponse.d.ts
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
import { Dictionary } from '../../../utils/types';
|
||||
import { OpenApiExample } from './OpenApiExample';
|
||||
import { OpenApiHeader } from './OpenApiHeader';
|
||||
import { OpenApiSchema } from './OpenApiSchema';
|
||||
|
||||
/**
|
||||
* https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#responseObject
|
||||
*/
|
||||
export interface OpenApiResponse {
|
||||
description: string;
|
||||
schema?: OpenApiSchema;
|
||||
headers?: Dictionary<OpenApiHeader>;
|
||||
examples?: OpenApiExample;
|
||||
}
|
||||
11
src/openApi/v2/interfaces/OpenApiResponses.d.ts
vendored
Normal file
11
src/openApi/v2/interfaces/OpenApiResponses.d.ts
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
import { OpenApiReference } from './OpenApiReference';
|
||||
import { OpenApiResponse } from './OpenApiResponse';
|
||||
|
||||
/**
|
||||
* https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#responsesObject
|
||||
*/
|
||||
export interface OpenApiResponses {
|
||||
[httpcode: string]: OpenApiResponse | OpenApiReference;
|
||||
|
||||
default: OpenApiResponse | OpenApiReference;
|
||||
}
|
||||
40
src/openApi/v2/interfaces/OpenApiSchema.d.ts
vendored
Normal file
40
src/openApi/v2/interfaces/OpenApiSchema.d.ts
vendored
Normal file
@ -0,0 +1,40 @@
|
||||
import { Dictionary } from '../../../utils/types';
|
||||
import { OpenApiExternalDocs } from './OpenApiExternalDocs';
|
||||
import { OpenApiReference } from './OpenApiReference';
|
||||
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;
|
||||
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;
|
||||
}
|
||||
6
src/openApi/v2/interfaces/OpenApiSecurityRequirement.d.ts
vendored
Normal file
6
src/openApi/v2/interfaces/OpenApiSecurityRequirement.d.ts
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
/**
|
||||
* https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#securityRequirementObject
|
||||
*/
|
||||
export interface OpenApiSecurityRequirement {
|
||||
[key: string]: string;
|
||||
}
|
||||
15
src/openApi/v2/interfaces/OpenApiSecurityScheme.d.ts
vendored
Normal file
15
src/openApi/v2/interfaces/OpenApiSecurityScheme.d.ts
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
import { Dictionary } from '../../../utils/types';
|
||||
|
||||
/**
|
||||
* https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#securitySchemeObject
|
||||
*/
|
||||
export interface OpenApiSecurityScheme {
|
||||
type: 'basic' | 'apiKey' | 'oauth2';
|
||||
description?: string;
|
||||
name?: string;
|
||||
in?: 'query' | 'header';
|
||||
flow?: 'implicit' | 'password' | 'application' | 'accessCode';
|
||||
authorizationUrl?: string;
|
||||
tokenUrl?: string;
|
||||
scopes: Dictionary<string>;
|
||||
}
|
||||
10
src/openApi/v2/interfaces/OpenApiTag.d.ts
vendored
Normal file
10
src/openApi/v2/interfaces/OpenApiTag.d.ts
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
import { OpenApiExternalDocs } from './OpenApiExternalDocs';
|
||||
|
||||
/**
|
||||
* https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#tagObject
|
||||
*/
|
||||
export interface OpenApiTag {
|
||||
name: string;
|
||||
description?: string;
|
||||
externalDocs?: OpenApiExternalDocs;
|
||||
}
|
||||
10
src/openApi/v2/interfaces/OpenApiXml.d.ts
vendored
Normal file
10
src/openApi/v2/interfaces/OpenApiXml.d.ts
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
/**
|
||||
* https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#xmlObject
|
||||
*/
|
||||
export interface OpenApiXml {
|
||||
name?: string;
|
||||
namespace?: string;
|
||||
prefix?: string;
|
||||
attribute?: boolean;
|
||||
wrapped?: boolean;
|
||||
}
|
||||
23
src/openApi/v2/parser/getMappedType.spec.ts
Normal file
23
src/openApi/v2/parser/getMappedType.spec.ts
Normal file
@ -0,0 +1,23 @@
|
||||
import { getMappedType } from './getMappedType';
|
||||
|
||||
describe('getMappedType', () => {
|
||||
it('should map types to the basics', () => {
|
||||
expect(getMappedType('File')).toEqual('File');
|
||||
expect(getMappedType('Array')).toEqual('any[]');
|
||||
expect(getMappedType('List')).toEqual('any[]');
|
||||
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('');
|
||||
});
|
||||
});
|
||||
42
src/openApi/v2/parser/getMappedType.ts
Normal file
42
src/openApi/v2/parser/getMappedType.ts
Normal file
@ -0,0 +1,42 @@
|
||||
const MAPPINGS = new Map<string, string>([
|
||||
['file', 'File'],
|
||||
['binary', 'File'],
|
||||
['array', 'any[]'],
|
||||
['list', 'any[]'],
|
||||
['object', 'any'],
|
||||
['any', 'any'],
|
||||
['boolean', 'boolean'],
|
||||
['byte', 'number'],
|
||||
['int', 'number'],
|
||||
['int32', 'number'],
|
||||
['int64', 'number'],
|
||||
['integer', 'number'],
|
||||
['float', 'number'],
|
||||
['double', 'number'],
|
||||
['short', 'number'],
|
||||
['long', 'number'],
|
||||
['number', 'number'],
|
||||
['char', 'string'],
|
||||
['date', 'string'],
|
||||
['date-time', 'string'],
|
||||
['password', 'string'],
|
||||
['string', 'string'],
|
||||
['void', 'void'],
|
||||
['null', 'null'],
|
||||
]);
|
||||
|
||||
/**
|
||||
* Get mapped type for given type to any basic Typescript/Javascript type.
|
||||
* @param type
|
||||
*/
|
||||
export function getMappedType(type: string): string {
|
||||
const mapped = MAPPINGS.get(type.toLowerCase());
|
||||
if (mapped) {
|
||||
return mapped;
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
export function hasMappedType(type: string): boolean {
|
||||
return MAPPINGS.has(type.toLowerCase());
|
||||
}
|
||||
9
src/openApi/v2/parser/getModelProperties.ts
Normal file
9
src/openApi/v2/parser/getModelProperties.ts
Normal file
@ -0,0 +1,9 @@
|
||||
import { ModelProperties } from '../../../client/interfaces/ModelProperties';
|
||||
|
||||
export function parseModelProperties(): ModelProperties {
|
||||
return {
|
||||
imports: [],
|
||||
properties: [],
|
||||
enums: [],
|
||||
};
|
||||
}
|
||||
14
src/openApi/v2/parser/getModelProperty.ts
Normal file
14
src/openApi/v2/parser/getModelProperty.ts
Normal file
@ -0,0 +1,14 @@
|
||||
import { ModelProperty } from '../../../client/interfaces/ModelProperty';
|
||||
|
||||
export function parseModelProperty(): ModelProperty {
|
||||
return {
|
||||
name: '',
|
||||
type: '',
|
||||
base: '',
|
||||
template: '',
|
||||
description: null,
|
||||
required: false,
|
||||
readOnly: false,
|
||||
imports: [],
|
||||
};
|
||||
}
|
||||
23
src/openApi/v2/parser/getModelTemplate.spec.ts
Normal file
23
src/openApi/v2/parser/getModelTemplate.spec.ts
Normal file
@ -0,0 +1,23 @@
|
||||
import { getModelTemplate } from './getModelTemplate';
|
||||
|
||||
describe('getModelTemplate', () => {
|
||||
it('should return generic for template type', () => {
|
||||
const template: string = getModelTemplate({
|
||||
type: 'Link<Model>',
|
||||
base: 'Link',
|
||||
template: 'Model',
|
||||
imports: ['Model'],
|
||||
});
|
||||
expect(template).toEqual('<T>');
|
||||
});
|
||||
|
||||
it('should return empty for primary type', () => {
|
||||
const template: string = getModelTemplate({
|
||||
type: 'string',
|
||||
base: 'string',
|
||||
template: null,
|
||||
imports: [],
|
||||
});
|
||||
expect(template).toEqual('');
|
||||
});
|
||||
});
|
||||
11
src/openApi/v2/parser/getModelTemplate.ts
Normal file
11
src/openApi/v2/parser/getModelTemplate.ts
Normal file
@ -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 "<T>" as our template type.
|
||||
* @param modelClass The parsed model class type.
|
||||
* @returns The model template type (<T> or empty).
|
||||
*/
|
||||
export function getModelTemplate(modelClass: Type): string {
|
||||
return modelClass.template !== null ? '<T>' : '';
|
||||
}
|
||||
36
src/openApi/v2/parser/getModels.ts
Normal file
36
src/openApi/v2/parser/getModels.ts
Normal file
@ -0,0 +1,36 @@
|
||||
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.
|
||||
* @param openApi
|
||||
*/
|
||||
export function getModels(openApi: OpenApi): Map<string, Model> {
|
||||
const models = new Map<string, Model>();
|
||||
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);
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
return models;
|
||||
}
|
||||
11
src/openApi/v2/parser/getSchemas.ts
Normal file
11
src/openApi/v2/parser/getSchemas.ts
Normal file
@ -0,0 +1,11 @@
|
||||
import { Schema } from '../../../client/interfaces/Schema';
|
||||
import { OpenApi } from '../interfaces/OpenApi';
|
||||
|
||||
/**
|
||||
* Parse and return the OpenAPI schemas.
|
||||
* @param openApi
|
||||
*/
|
||||
export function getSchemas(openApi: OpenApi): Map<string, Schema> {
|
||||
const schemas = new Map<string, Schema>();
|
||||
return schemas;
|
||||
}
|
||||
13
src/openApi/v2/parser/getServer.spec.ts
Normal file
13
src/openApi/v2/parser/getServer.spec.ts
Normal file
@ -0,0 +1,13 @@
|
||||
import { getServer } from './getServer';
|
||||
|
||||
describe('getServer', () => {
|
||||
it('should produce correct result', () => {
|
||||
expect(
|
||||
getServer({
|
||||
host: 'localhost:8080',
|
||||
basePath: '/api',
|
||||
schemes: ['http', 'https'],
|
||||
})
|
||||
).toEqual('http://localhost:8080/api');
|
||||
});
|
||||
});
|
||||
10
src/openApi/v2/parser/getServer.ts
Normal file
10
src/openApi/v2/parser/getServer.ts
Normal file
@ -0,0 +1,10 @@
|
||||
import { OpenApi } from '../interfaces/OpenApi';
|
||||
|
||||
type Props = Pick<OpenApi, 'schemes' | 'host' | 'basePath'>;
|
||||
|
||||
export function getServer(openApi: Props): string {
|
||||
const scheme = (openApi.schemes && openApi.schemes[0]) || 'http';
|
||||
const host = openApi.host;
|
||||
const basePath = openApi.basePath || '';
|
||||
return host ? `${scheme}://${host}${basePath}` : basePath;
|
||||
}
|
||||
13
src/openApi/v2/parser/getServiceClassName.spec.ts
Normal file
13
src/openApi/v2/parser/getServiceClassName.spec.ts
Normal file
@ -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');
|
||||
});
|
||||
});
|
||||
14
src/openApi/v2/parser/getServiceClassName.ts
Normal file
14
src/openApi/v2/parser/getServiceClassName.ts
Normal file
@ -0,0 +1,14 @@
|
||||
import * as 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.
|
||||
* @param value
|
||||
*/
|
||||
export function getServiceClassName(value: string): string {
|
||||
const name = camelcase(value, { pascalCase: true });
|
||||
if (name && !name.endsWith('Service')) {
|
||||
return `${name}Service`;
|
||||
}
|
||||
return name;
|
||||
}
|
||||
10
src/openApi/v2/parser/getServiceOperationName.spec.ts
Normal file
10
src/openApi/v2/parser/getServiceOperationName.spec.ts
Normal file
@ -0,0 +1,10 @@
|
||||
import { getServiceOperationName } from './getServiceOperationName';
|
||||
|
||||
describe('getServiceOperationName', () => {
|
||||
it('should produce correct result', () => {
|
||||
expect(getServiceOperationName('')).toEqual('');
|
||||
expect(getServiceOperationName('FooBar')).toEqual('fooBar');
|
||||
expect(getServiceOperationName('Foo Bar')).toEqual('fooBar');
|
||||
expect(getServiceOperationName('foo bar')).toEqual('fooBar');
|
||||
});
|
||||
});
|
||||
11
src/openApi/v2/parser/getServiceOperationName.ts
Normal file
11
src/openApi/v2/parser/getServiceOperationName.ts
Normal file
@ -0,0 +1,11 @@
|
||||
import * as camelcase from 'camelcase';
|
||||
|
||||
/**
|
||||
* Convert the input value to a correct operation (method) classname. This converts
|
||||
* the input string to cascalCase, so the method name follows the most popular
|
||||
* Javascript and Typescript writing style.
|
||||
* @param value
|
||||
*/
|
||||
export function getServiceOperationName(value: string): string {
|
||||
return camelcase(value);
|
||||
}
|
||||
10
src/openApi/v2/parser/getServicePath.spec.ts
Normal file
10
src/openApi/v2/parser/getServicePath.spec.ts
Normal file
@ -0,0 +1,10 @@
|
||||
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');
|
||||
});
|
||||
});
|
||||
9
src/openApi/v2/parser/getServicePath.ts
Normal file
9
src/openApi/v2/parser/getServicePath.ts
Normal file
@ -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 getServicePath(path: string): string {
|
||||
return path.replace(/{api-version}/g, '{OpenAPI.VERSION}').replace(/\{(.*?)\}/g, '${$1}');
|
||||
}
|
||||
9
src/openApi/v2/parser/getServiceVersion.spec.ts
Normal file
9
src/openApi/v2/parser/getServiceVersion.spec.ts
Normal file
@ -0,0 +1,9 @@
|
||||
import { getServiceVersion } from './getServiceVersion';
|
||||
|
||||
describe('getServiceVersion', () => {
|
||||
it('should produce correct result', () => {
|
||||
expect(getServiceVersion('1.0')).toEqual('1.0');
|
||||
expect(getServiceVersion('v1.0')).toEqual('1.0');
|
||||
expect(getServiceVersion('V1.0')).toEqual('1.0');
|
||||
});
|
||||
});
|
||||
8
src/openApi/v2/parser/getServiceVersion.ts
Normal file
8
src/openApi/v2/parser/getServiceVersion.ts
Normal file
@ -0,0 +1,8 @@
|
||||
/**
|
||||
* Convert the service version to 'normal' version.
|
||||
* This basically removes any "v" prefix from the version string.
|
||||
* @param version
|
||||
*/
|
||||
export function getServiceVersion(version = '1.0'): string {
|
||||
return version.replace(/^v/gi, '');
|
||||
}
|
||||
35
src/openApi/v2/parser/getServices.ts
Normal file
35
src/openApi/v2/parser/getServices.ts
Normal file
@ -0,0 +1,35 @@
|
||||
import { Service } from '../../../client/interfaces/Service';
|
||||
import { OpenApi } from '../interfaces/OpenApi';
|
||||
|
||||
/**
|
||||
* Parse and return the OpenAPI services.
|
||||
* @param 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return services;
|
||||
}
|
||||
51
src/openApi/v2/parser/getType.spec.ts
Normal file
51
src/openApi/v2/parser/getType.spec.ts
Normal file
@ -0,0 +1,51 @@
|
||||
import { getType } from './getType';
|
||||
|
||||
describe('getType', () => {
|
||||
it('should convert int', () => {
|
||||
const type = getType('int', null);
|
||||
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', null);
|
||||
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]', null);
|
||||
expect(type.type).toEqual('string[]');
|
||||
expect(type.base).toEqual('string');
|
||||
expect(type.template).toEqual(null);
|
||||
expect(type.imports).toEqual([]);
|
||||
});
|
||||
|
||||
it('should convert template with primary', () => {
|
||||
const type = getType('#/definitions/Link[String]', null);
|
||||
expect(type.type).toEqual('Link<string>');
|
||||
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]', null);
|
||||
expect(type.type).toEqual('Link<Model>');
|
||||
expect(type.base).toEqual('Link');
|
||||
expect(type.template).toEqual('Model');
|
||||
expect(type.imports).toEqual(['Link', 'Model']);
|
||||
});
|
||||
|
||||
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([]);
|
||||
});
|
||||
});
|
||||
74
src/openApi/v2/parser/getType.ts
Normal file
74
src/openApi/v2/parser/getType.ts
Normal file
@ -0,0 +1,74 @@
|
||||
import { stripNamespace } from './stripNamespace';
|
||||
import { Type } from '../../../client/interfaces/Type';
|
||||
import { getMappedType, hasMappedType } from './getMappedType';
|
||||
|
||||
/**
|
||||
* Parse any 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 | null = null): Type {
|
||||
let propertyType = 'any';
|
||||
let propertyBase = 'any';
|
||||
let propertyTemplate: string | null = null;
|
||||
let propertyImports: string[] = [];
|
||||
|
||||
// Remove definitions prefix and cleanup string.
|
||||
const valueTrimmed = stripNamespace(value || '');
|
||||
|
||||
// Check of we have an Array type or generic type, for instance: "Link[Model]".
|
||||
if (/\[.*\]$/g.test(valueTrimmed)) {
|
||||
// Find the first and second type
|
||||
const match = valueTrimmed.match(/(.*?)\[(.*)\]$/);
|
||||
if (match) {
|
||||
// Both of the types can be complex types so parse each of them.
|
||||
const match1 = getType(match[1]);
|
||||
const match2 = getType(match[2]);
|
||||
|
||||
// If the first match is a generic array then construct a correct array type,
|
||||
// for example the type "Array[Model]" becomes "Model[]".
|
||||
if (match1.type === 'any[]') {
|
||||
propertyType = `${match2.type}[]`;
|
||||
propertyBase = `${match2.type}`;
|
||||
match1.imports = [];
|
||||
} else if (match2.type === '') {
|
||||
// Primary types like number[] or string[]
|
||||
propertyType = match1.type;
|
||||
propertyBase = match1.type;
|
||||
propertyTemplate = match1.type;
|
||||
match2.imports = [];
|
||||
} else {
|
||||
propertyType = `${match1.type}<${match2.type}>`;
|
||||
propertyBase = match1.type;
|
||||
propertyTemplate = match2.type;
|
||||
}
|
||||
|
||||
// Either way we need to add the found imports
|
||||
propertyImports.push(...match1.imports);
|
||||
propertyImports.push(...match2.imports);
|
||||
}
|
||||
} else if (hasMappedType(valueTrimmed)) {
|
||||
const mapped = getMappedType(valueTrimmed);
|
||||
propertyType = mapped;
|
||||
propertyBase = mapped;
|
||||
} else {
|
||||
propertyType = valueTrimmed;
|
||||
propertyBase = valueTrimmed;
|
||||
propertyImports.push(valueTrimmed);
|
||||
}
|
||||
|
||||
// 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 (propertyType === template) {
|
||||
propertyType = 'T'; // Template;
|
||||
propertyBase = 'T'; // Template;
|
||||
propertyImports = [];
|
||||
}
|
||||
|
||||
return {
|
||||
type: propertyType,
|
||||
base: propertyBase,
|
||||
template: propertyTemplate,
|
||||
imports: propertyImports,
|
||||
};
|
||||
}
|
||||
15
src/openApi/v2/parser/isPrimaryType.spec.ts
Normal file
15
src/openApi/v2/parser/isPrimaryType.spec.ts
Normal file
@ -0,0 +1,15 @@
|
||||
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('object')).toBeTruthy();
|
||||
expect(isPrimaryType('void')).toBeTruthy();
|
||||
expect(isPrimaryType('null')).toBeTruthy();
|
||||
expect(isPrimaryType('Array')).toBeFalsy();
|
||||
expect(isPrimaryType('MyModel')).toBeFalsy();
|
||||
});
|
||||
});
|
||||
17
src/openApi/v2/parser/isPrimaryType.ts
Normal file
17
src/openApi/v2/parser/isPrimaryType.ts
Normal file
@ -0,0 +1,17 @@
|
||||
/**
|
||||
* Check if given type is a primary type.
|
||||
* @param type
|
||||
*/
|
||||
export function isPrimaryType(type: string): boolean {
|
||||
switch (type.toLowerCase()) {
|
||||
case 'number':
|
||||
case 'boolean':
|
||||
case 'string':
|
||||
case 'object':
|
||||
case 'any':
|
||||
case 'void':
|
||||
case 'null':
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
14
src/openApi/v2/parser/stripNamespace.spec.ts
Normal file
14
src/openApi/v2/parser/stripNamespace.spec.ts
Normal file
@ -0,0 +1,14 @@
|
||||
import { stripNamespace } from './stripNamespace';
|
||||
|
||||
describe('stripNamespace', () => {
|
||||
it('should strip namespace', () => {
|
||||
expect(stripNamespace('#/definitions/Item')).toEqual('Item');
|
||||
expect(stripNamespace('#/parameters/Item')).toEqual('Item');
|
||||
expect(stripNamespace('#/responses/Item')).toEqual('Item');
|
||||
expect(stripNamespace('#/securityDefinitions/Item')).toEqual('Item');
|
||||
expect(stripNamespace('Template[Model]')).toEqual('Template[Model]');
|
||||
expect(stripNamespace('namespace.Template[Model]')).toEqual('Template[Model]');
|
||||
expect(stripNamespace('namespace.Template[namespace.Model]')).toEqual('Template[Model]');
|
||||
expect(stripNamespace('Item')).toEqual('Item');
|
||||
});
|
||||
});
|
||||
31
src/openApi/v2/parser/stripNamespace.ts
Normal file
31
src/openApi/v2/parser/stripNamespace.ts
Normal file
@ -0,0 +1,31 @@
|
||||
/**
|
||||
* Strip (OpenAPI) namespaces fom values.
|
||||
* @param value
|
||||
*/
|
||||
export function stripNamespace(value: string): string {
|
||||
return (
|
||||
value
|
||||
.trim()
|
||||
.replace(/^#\/definitions\//, '')
|
||||
.replace(/^#\/parameters\//, '')
|
||||
.replace(/^#\/responses\//, '')
|
||||
.replace(/^#\/securityDefinitions\//, '')
|
||||
|
||||
// First we remove the namespace from template notation:
|
||||
// Example: namespace.Template[namespace.Model] -> namespace.Template[Model]
|
||||
.replace(/(\[.*\]$)/, (s: string): string => {
|
||||
const v = s
|
||||
.replace('[', '')
|
||||
.replace(']', '')
|
||||
.split('.')
|
||||
.pop()!;
|
||||
return `[${v}]`;
|
||||
})
|
||||
|
||||
// Then we remove the namespace from the complete result:
|
||||
// Example: namespace.Template[Model] -> Template[Model]
|
||||
.replace(/.*/, (s: string): string => {
|
||||
return s.split('.').pop()!;
|
||||
})
|
||||
);
|
||||
}
|
||||
16
src/openApi/v3/index.ts
Normal file
16
src/openApi/v3/index.ts
Normal file
@ -0,0 +1,16 @@
|
||||
import { OpenApi } from './interfaces/OpenApi';
|
||||
import { Client } from '../../client/interfaces/Client';
|
||||
import { getServer } from './parser/getServer';
|
||||
import { getModels } from './parser/getModels';
|
||||
import { getServices } from './parser/getServices';
|
||||
import { getSchemas } from './parser/getSchemas';
|
||||
|
||||
export function parse(openApi: OpenApi): Client {
|
||||
return {
|
||||
version: openApi.info.version,
|
||||
server: getServer(openApi),
|
||||
models: getModels(openApi),
|
||||
schemas: getSchemas(openApi),
|
||||
services: getServices(openApi),
|
||||
};
|
||||
}
|
||||
21
src/openApi/v3/interfaces/OpenApi.d.ts
vendored
Normal file
21
src/openApi/v3/interfaces/OpenApi.d.ts
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
import { OpenApiComponents } from './OpenApiComponents';
|
||||
import { OpenApiExternalDocs } from './OpenApiExternalDocs';
|
||||
import { OpenApiInfo } from './OpenApiInfo';
|
||||
import { OpenApiPaths } from './OpenApiPaths';
|
||||
import { OpenApiSecurityRequirement } from './OpenApiSecurityRequirement';
|
||||
import { OpenApiServer } from './OpenApiServer';
|
||||
import { OpenApiTag } from './OpenApiTag';
|
||||
|
||||
/**
|
||||
* https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md
|
||||
*/
|
||||
export interface OpenApi {
|
||||
openapi: string;
|
||||
info: OpenApiInfo;
|
||||
servers?: OpenApiServer[];
|
||||
paths: OpenApiPaths;
|
||||
components?: OpenApiComponents;
|
||||
security?: OpenApiSecurityRequirement[];
|
||||
tags?: OpenApiTag[];
|
||||
externalDocs?: OpenApiExternalDocs;
|
||||
}
|
||||
8
src/openApi/v3/interfaces/OpenApiCallback.d.ts
vendored
Normal file
8
src/openApi/v3/interfaces/OpenApiCallback.d.ts
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
import { OpenApiPath } from './OpenApiPath';
|
||||
|
||||
/**
|
||||
* https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#callbackObject
|
||||
*/
|
||||
export interface OpenApiCallback {
|
||||
[key: string]: OpenApiPath;
|
||||
}
|
||||
26
src/openApi/v3/interfaces/OpenApiComponents.d.ts
vendored
Normal file
26
src/openApi/v3/interfaces/OpenApiComponents.d.ts
vendored
Normal file
@ -0,0 +1,26 @@
|
||||
import { Dictionary } from '../../../utils/types';
|
||||
import { OpenApiCallback } from './OpenApiCallback';
|
||||
import { OpenApiExample } from './OpenApiExample';
|
||||
import { OpenApiHeader } from './OpenApiHeader';
|
||||
import { OpenApiLink } from './OpenApiLink';
|
||||
import { OpenApiParameter } from './OpenApiParameter';
|
||||
import { OpenApiReference } from './OpenApiReference';
|
||||
import { OpenApiRequestBody } from './OpenApiRequestBody';
|
||||
import { OpenApiResponses } from './OpenApiResponses';
|
||||
import { OpenApiSchema } from './OpenApiSchema';
|
||||
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>;
|
||||
}
|
||||
8
src/openApi/v3/interfaces/OpenApiContact.d.ts
vendored
Normal file
8
src/openApi/v3/interfaces/OpenApiContact.d.ts
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
/**
|
||||
* https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#contactObject
|
||||
*/
|
||||
export interface OpenApiContact {
|
||||
name?: string;
|
||||
url?: string;
|
||||
email?: string;
|
||||
}
|
||||
9
src/openApi/v3/interfaces/OpenApiDiscriminator.d.ts
vendored
Normal file
9
src/openApi/v3/interfaces/OpenApiDiscriminator.d.ts
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
import { Dictionary } from '../../../utils/types';
|
||||
|
||||
/**
|
||||
* https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#discriminatorObject
|
||||
*/
|
||||
export interface OpenApiDiscriminator {
|
||||
propertyName: string;
|
||||
mapping?: Dictionary<string>;
|
||||
}
|
||||
14
src/openApi/v3/interfaces/OpenApiEncoding.d.ts
vendored
Normal file
14
src/openApi/v3/interfaces/OpenApiEncoding.d.ts
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
import { Dictionary } from '../../../utils/types';
|
||||
import { OpenApiHeader } from './OpenApiHeader';
|
||||
import { OpenApiReference } from './OpenApiReference';
|
||||
|
||||
/**
|
||||
* https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#encodingObject
|
||||
*/
|
||||
export interface OpenApiEncoding {
|
||||
contentType?: string;
|
||||
headers?: Dictionary<OpenApiHeader | OpenApiReference>;
|
||||
style?: string;
|
||||
explode?: boolean;
|
||||
allowReserved?: boolean;
|
||||
}
|
||||
9
src/openApi/v3/interfaces/OpenApiExample.d.ts
vendored
Normal file
9
src/openApi/v3/interfaces/OpenApiExample.d.ts
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
/**
|
||||
* https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#exampleObject
|
||||
*/
|
||||
export interface OpenApiExample {
|
||||
summary?: string;
|
||||
description?: string;
|
||||
value?: any;
|
||||
externalValue?: string;
|
||||
}
|
||||
7
src/openApi/v3/interfaces/OpenApiExternalDocs.d.ts
vendored
Normal file
7
src/openApi/v3/interfaces/OpenApiExternalDocs.d.ts
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
/**
|
||||
* https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#externalDocumentationObject
|
||||
*/
|
||||
export interface OpenApiExternalDocs {
|
||||
description?: string;
|
||||
url: string;
|
||||
}
|
||||
20
src/openApi/v3/interfaces/OpenApiHeader.d.ts
vendored
Normal file
20
src/openApi/v3/interfaces/OpenApiHeader.d.ts
vendored
Normal file
@ -0,0 +1,20 @@
|
||||
import { Dictionary } from '../../../utils/types';
|
||||
import { OpenApiExample } from './OpenApiExample';
|
||||
import { OpenApiReference } from './OpenApiReference';
|
||||
import { OpenApiSchema } from './OpenApiSchema';
|
||||
|
||||
/**
|
||||
* https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#headerObject
|
||||
*/
|
||||
export interface OpenApiHeader {
|
||||
description?: string;
|
||||
required?: boolean;
|
||||
deprecated?: boolean;
|
||||
allowEmptyValue?: boolean;
|
||||
style?: string;
|
||||
explode?: boolean;
|
||||
allowReserved?: boolean;
|
||||
schema?: OpenApiSchema | OpenApiReference;
|
||||
example?: any;
|
||||
examples?: Dictionary<OpenApiExample | OpenApiReference>;
|
||||
}
|
||||
14
src/openApi/v3/interfaces/OpenApiInfo.d.ts
vendored
Normal file
14
src/openApi/v3/interfaces/OpenApiInfo.d.ts
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
import { OpenApiContact } from './OpenApiContact';
|
||||
import { OpenApiLicense } from './OpenApiLicense';
|
||||
|
||||
/**
|
||||
* https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#infoObject
|
||||
*/
|
||||
export interface OpenApiInfo {
|
||||
title: string;
|
||||
description?: string;
|
||||
termsOfService?: string;
|
||||
contact?: OpenApiContact;
|
||||
license?: OpenApiLicense;
|
||||
version: string;
|
||||
}
|
||||
7
src/openApi/v3/interfaces/OpenApiLicense.d.ts
vendored
Normal file
7
src/openApi/v3/interfaces/OpenApiLicense.d.ts
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
/**
|
||||
* https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#licenseObject
|
||||
*/
|
||||
export interface OpenApiLicense {
|
||||
name: string;
|
||||
url?: string;
|
||||
}
|
||||
14
src/openApi/v3/interfaces/OpenApiLink.d.ts
vendored
Normal file
14
src/openApi/v3/interfaces/OpenApiLink.d.ts
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
import { Dictionary } from '../../../utils/types';
|
||||
import { OpenApiServer } from './OpenApiServer';
|
||||
|
||||
/**
|
||||
* https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#linkObject
|
||||
*/
|
||||
export interface OpenApiLink {
|
||||
operationRef?: string;
|
||||
operationId?: string;
|
||||
parameters?: Dictionary<any>;
|
||||
requestBody?: any;
|
||||
description?: string;
|
||||
server?: OpenApiServer;
|
||||
}
|
||||
15
src/openApi/v3/interfaces/OpenApiMediaType.d.ts
vendored
Normal file
15
src/openApi/v3/interfaces/OpenApiMediaType.d.ts
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
import { Dictionary } from '../../../utils/types';
|
||||
import { OpenApiEncoding } from './OpenApiEncoding';
|
||||
import { OpenApiExample } from './OpenApiExample';
|
||||
import { OpenApiReference } from './OpenApiReference';
|
||||
import { OpenApiSchema } from './OpenApiSchema';
|
||||
|
||||
/**
|
||||
* https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#mediaTypeObject
|
||||
*/
|
||||
export interface OpenApiMediaType {
|
||||
schema?: OpenApiSchema | OpenApiReference;
|
||||
example?: any;
|
||||
examples?: Dictionary<OpenApiExample | OpenApiReference>;
|
||||
encoding?: Dictionary<OpenApiEncoding>;
|
||||
}
|
||||
11
src/openApi/v3/interfaces/OpenApiOAuthFlow.d.ts
vendored
Normal file
11
src/openApi/v3/interfaces/OpenApiOAuthFlow.d.ts
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
import { Dictionary } from '../../../utils/types';
|
||||
|
||||
/**
|
||||
* https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#oauthFlowObject
|
||||
*/
|
||||
export interface OpenApiOAuthFlow {
|
||||
authorizationUrl: string;
|
||||
tokenUrl: string;
|
||||
refreshUrl?: string;
|
||||
scopes: Dictionary<string>;
|
||||
}
|
||||
11
src/openApi/v3/interfaces/OpenApiOAuthFlows.d.ts
vendored
Normal file
11
src/openApi/v3/interfaces/OpenApiOAuthFlows.d.ts
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
import { OpenApiOAuthFlow } from './OpenApiOAuthFlow';
|
||||
|
||||
/**
|
||||
* https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#oauthFlowsObject
|
||||
*/
|
||||
export interface OpenApiOAuthFlows {
|
||||
implicit?: OpenApiOAuthFlow;
|
||||
password?: OpenApiOAuthFlow;
|
||||
clientCredentials?: OpenApiOAuthFlow;
|
||||
authorizationCode?: OpenApiOAuthFlow;
|
||||
}
|
||||
27
src/openApi/v3/interfaces/OpenApiOperation.d.ts
vendored
Normal file
27
src/openApi/v3/interfaces/OpenApiOperation.d.ts
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
import { Dictionary } from '../../../utils/types';
|
||||
import { OpenApiCallback } from './OpenApiCallback';
|
||||
import { OpenApiExternalDocs } from './OpenApiExternalDocs';
|
||||
import { OpenApiParameter } from './OpenApiParameter';
|
||||
import { OpenApiReference } from './OpenApiReference';
|
||||
import { OpenApiRequestBody } from './OpenApiRequestBody';
|
||||
import { OpenApiResponses } from './OpenApiResponses';
|
||||
import { OpenApiSecurityRequirement } from './OpenApiSecurityRequirement';
|
||||
import { OpenApiServer } from './OpenApiServer';
|
||||
|
||||
/**
|
||||
* https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#operationObject
|
||||
*/
|
||||
export interface OpenApiOperation {
|
||||
tags?: string[];
|
||||
summary?: string;
|
||||
description?: string;
|
||||
externalDocs?: OpenApiExternalDocs;
|
||||
operationId?: string;
|
||||
parameters?: OpenApiParameter[] | OpenApiReference[];
|
||||
requestBody?: OpenApiRequestBody | OpenApiReference;
|
||||
responses: OpenApiResponses;
|
||||
callbacks?: Dictionary<OpenApiCallback | OpenApiReference>;
|
||||
deprecated?: boolean;
|
||||
security?: OpenApiSecurityRequirement[];
|
||||
servers?: OpenApiServer[];
|
||||
}
|
||||
22
src/openApi/v3/interfaces/OpenApiParameter.d.ts
vendored
Normal file
22
src/openApi/v3/interfaces/OpenApiParameter.d.ts
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
import { Dictionary } from '../../../utils/types';
|
||||
import { OpenApiExample } from './OpenApiExample';
|
||||
import { OpenApiReference } from './OpenApiReference';
|
||||
import { OpenApiSchema } from './OpenApiSchema';
|
||||
|
||||
/**
|
||||
* https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#parameterObject
|
||||
*/
|
||||
export interface OpenApiParameter {
|
||||
name: string;
|
||||
in: 'path' | 'query' | 'header' | 'cookie';
|
||||
description?: string;
|
||||
required: boolean;
|
||||
deprecated?: boolean;
|
||||
allowEmptyValue?: boolean;
|
||||
style?: string;
|
||||
explode?: boolean;
|
||||
allowReserved?: boolean;
|
||||
schema?: OpenApiSchema | OpenApiReference;
|
||||
example?: any;
|
||||
examples?: Dictionary<OpenApiExample | OpenApiReference>;
|
||||
}
|
||||
23
src/openApi/v3/interfaces/OpenApiPath.d.ts
vendored
Normal file
23
src/openApi/v3/interfaces/OpenApiPath.d.ts
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
import { OpenApiOperation } from './OpenApiOperation';
|
||||
import { OpenApiParameter } from './OpenApiParameter';
|
||||
import { OpenApiReference } from './OpenApiReference';
|
||||
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;
|
||||
put?: OpenApiOperation;
|
||||
post?: OpenApiOperation;
|
||||
delete?: OpenApiOperation;
|
||||
options?: OpenApiOperation;
|
||||
head?: OpenApiOperation;
|
||||
patch?: OpenApiOperation;
|
||||
trace?: OpenApiOperation;
|
||||
servers?: OpenApiServer[];
|
||||
parameters?: OpenApiParameter[] | OpenApiReference[];
|
||||
}
|
||||
8
src/openApi/v3/interfaces/OpenApiPaths.d.ts
vendored
Normal file
8
src/openApi/v3/interfaces/OpenApiPaths.d.ts
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
import { OpenApiPath } from './OpenApiPath';
|
||||
|
||||
/**
|
||||
* https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#pathsObject
|
||||
*/
|
||||
export interface OpenApiPaths {
|
||||
[path: string]: OpenApiPath;
|
||||
}
|
||||
6
src/openApi/v3/interfaces/OpenApiReference.d.ts
vendored
Normal file
6
src/openApi/v3/interfaces/OpenApiReference.d.ts
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
/**
|
||||
* https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#referenceObject
|
||||
*/
|
||||
export interface OpenApiReference {
|
||||
$ref: string;
|
||||
}
|
||||
12
src/openApi/v3/interfaces/OpenApiRequestBody.d.ts
vendored
Normal file
12
src/openApi/v3/interfaces/OpenApiRequestBody.d.ts
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
import { Dictionary } from '../../../utils/types';
|
||||
import { OpenApiMediaType } from './OpenApiMediaType';
|
||||
import { OpenApiReference } from './OpenApiReference';
|
||||
|
||||
/**
|
||||
* https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#requestBodyObject
|
||||
*/
|
||||
export interface OpenApiRequestBody {
|
||||
description?: string;
|
||||
content: Dictionary<OpenApiMediaType | OpenApiReference>;
|
||||
required?: boolean;
|
||||
}
|
||||
15
src/openApi/v3/interfaces/OpenApiResponse.d.ts
vendored
Normal file
15
src/openApi/v3/interfaces/OpenApiResponse.d.ts
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
import { Dictionary } from '../../../utils/types';
|
||||
import { OpenApiHeader } from './OpenApiHeader';
|
||||
import { OpenApiLink } from './OpenApiLink';
|
||||
import { OpenApiMediaType } from './OpenApiMediaType';
|
||||
import { OpenApiReference } from './OpenApiReference';
|
||||
|
||||
/**
|
||||
* https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#responseObject
|
||||
*/
|
||||
export interface OpenApiResponse {
|
||||
description: string;
|
||||
headers?: Dictionary<OpenApiHeader | OpenApiReference>;
|
||||
content?: Dictionary<OpenApiMediaType>;
|
||||
links?: Dictionary<OpenApiLink | OpenApiReference>;
|
||||
}
|
||||
11
src/openApi/v3/interfaces/OpenApiResponses.d.ts
vendored
Normal file
11
src/openApi/v3/interfaces/OpenApiResponses.d.ts
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
import { OpenApiReference } from './OpenApiReference';
|
||||
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;
|
||||
|
||||
default: OpenApiResponse | OpenApiReference;
|
||||
}
|
||||
46
src/openApi/v3/interfaces/OpenApiSchema.d.ts
vendored
Normal file
46
src/openApi/v3/interfaces/OpenApiSchema.d.ts
vendored
Normal file
@ -0,0 +1,46 @@
|
||||
import { Dictionary } from '../../../utils/types';
|
||||
import { OpenApiDiscriminator } from './OpenApiDiscriminator';
|
||||
import { OpenApiExternalDocs } from './OpenApiExternalDocs';
|
||||
import { OpenApiReference } from './OpenApiReference';
|
||||
import { OpenApiXml } from './OpenApiXml';
|
||||
|
||||
/**
|
||||
* https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#schemaObject
|
||||
*/
|
||||
export interface OpenApiSchema {
|
||||
title?: string;
|
||||
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;
|
||||
allOf?: OpenApiReference[] | OpenApiSchema[];
|
||||
oneOf?: OpenApiReference[] | OpenApiSchema[];
|
||||
anyOf?: OpenApiReference[] | OpenApiSchema[];
|
||||
not?: OpenApiReference[] | OpenApiSchema[];
|
||||
items?: OpenApiReference | OpenApiSchema;
|
||||
properties?: Dictionary<OpenApiSchema>;
|
||||
additionalProperties?: boolean | OpenApiReference | OpenApiSchema;
|
||||
description?: string;
|
||||
format?: 'int32' | 'int64' | 'float' | 'double' | 'string' | 'boolean' | 'byte' | 'binary' | 'date' | 'date-time' | 'password';
|
||||
default?: any;
|
||||
nullable?: boolean;
|
||||
discriminator?: OpenApiDiscriminator;
|
||||
readOnly?: boolean;
|
||||
writeOnly?: boolean;
|
||||
xml?: OpenApiXml;
|
||||
externalDocs?: OpenApiExternalDocs;
|
||||
example?: any;
|
||||
deprecated?: boolean;
|
||||
}
|
||||
6
src/openApi/v3/interfaces/OpenApiSecurityRequirement.d.ts
vendored
Normal file
6
src/openApi/v3/interfaces/OpenApiSecurityRequirement.d.ts
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
/**
|
||||
* https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#securityRequirementObject
|
||||
*/
|
||||
export interface OpenApiSecurityRequirement {
|
||||
[name: string]: string;
|
||||
}
|
||||
15
src/openApi/v3/interfaces/OpenApiSecurityScheme.d.ts
vendored
Normal file
15
src/openApi/v3/interfaces/OpenApiSecurityScheme.d.ts
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
import { OpenApiOAuthFlows } from './OpenApiOAuthFlows';
|
||||
|
||||
/**
|
||||
* https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#securitySchemeObject
|
||||
*/
|
||||
export interface OpenApiSecurityScheme {
|
||||
type: 'apiKey' | 'http' | 'oauth2' | 'openIdConnect';
|
||||
description?: string;
|
||||
name?: string;
|
||||
in?: 'query' | 'header' | 'cookie';
|
||||
scheme?: string;
|
||||
bearerFormat?: string;
|
||||
flows?: OpenApiOAuthFlows;
|
||||
openIdConnectUrl?: string;
|
||||
}
|
||||
11
src/openApi/v3/interfaces/OpenApiServer.d.ts
vendored
Normal file
11
src/openApi/v3/interfaces/OpenApiServer.d.ts
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
import { Dictionary } from '../../../utils/types';
|
||||
import { OpenApiServerVariable } from './OpenApiServerVariable';
|
||||
|
||||
/**
|
||||
* https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#serverObject
|
||||
*/
|
||||
export interface OpenApiServer {
|
||||
url: string;
|
||||
description?: string;
|
||||
variables?: Dictionary<OpenApiServerVariable>;
|
||||
}
|
||||
8
src/openApi/v3/interfaces/OpenApiServerVariable.d.ts
vendored
Normal file
8
src/openApi/v3/interfaces/OpenApiServerVariable.d.ts
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
/**
|
||||
* https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#serverVariableObject
|
||||
*/
|
||||
export interface OpenApiServerVariable {
|
||||
enum?: string[];
|
||||
default: string;
|
||||
description?: string;
|
||||
}
|
||||
10
src/openApi/v3/interfaces/OpenApiTag.d.ts
vendored
Normal file
10
src/openApi/v3/interfaces/OpenApiTag.d.ts
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
import { OpenApiExternalDocs } from './OpenApiExternalDocs';
|
||||
|
||||
/**
|
||||
* https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#tagObject
|
||||
*/
|
||||
export interface OpenApiTag {
|
||||
name: string;
|
||||
description?: string;
|
||||
externalDocs?: OpenApiExternalDocs;
|
||||
}
|
||||
10
src/openApi/v3/interfaces/OpenApiXml.d.ts
vendored
Normal file
10
src/openApi/v3/interfaces/OpenApiXml.d.ts
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
/**
|
||||
* https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#xmlObject
|
||||
*/
|
||||
export interface OpenApiXml {
|
||||
name?: string;
|
||||
namespace?: string;
|
||||
prefix?: string;
|
||||
attribute?: boolean;
|
||||
wrapped?: boolean;
|
||||
}
|
||||
23
src/openApi/v3/parser/getMappedType.spec.ts
Normal file
23
src/openApi/v3/parser/getMappedType.spec.ts
Normal file
@ -0,0 +1,23 @@
|
||||
import { getMappedType } from './getMappedType';
|
||||
|
||||
describe('getMappedType', () => {
|
||||
it('should map types to the basics', () => {
|
||||
expect(getMappedType('File')).toEqual('File');
|
||||
expect(getMappedType('Array')).toEqual('any[]');
|
||||
expect(getMappedType('List')).toEqual('any[]');
|
||||
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('');
|
||||
});
|
||||
});
|
||||
42
src/openApi/v3/parser/getMappedType.ts
Normal file
42
src/openApi/v3/parser/getMappedType.ts
Normal file
@ -0,0 +1,42 @@
|
||||
const MAPPINGS = new Map<string, string>([
|
||||
['file', 'File'],
|
||||
['binary', 'File'],
|
||||
['array', 'any[]'],
|
||||
['list', 'any[]'],
|
||||
['object', 'any'],
|
||||
['any', 'any'],
|
||||
['boolean', 'boolean'],
|
||||
['byte', 'number'],
|
||||
['int', 'number'],
|
||||
['int32', 'number'],
|
||||
['int64', 'number'],
|
||||
['integer', 'number'],
|
||||
['float', 'number'],
|
||||
['double', 'number'],
|
||||
['short', 'number'],
|
||||
['long', 'number'],
|
||||
['number', 'number'],
|
||||
['char', 'string'],
|
||||
['date', 'string'],
|
||||
['date-time', 'string'],
|
||||
['password', 'string'],
|
||||
['string', 'string'],
|
||||
['void', 'void'],
|
||||
['null', 'null'],
|
||||
]);
|
||||
|
||||
/**
|
||||
* Get mapped type for given type to any basic Typescript/Javascript type.
|
||||
* @param type
|
||||
*/
|
||||
export function getMappedType(type: string): string {
|
||||
const mapped = MAPPINGS.get(type.toLowerCase());
|
||||
if (mapped) {
|
||||
return mapped;
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
export function hasMappedType(type: string): boolean {
|
||||
return MAPPINGS.has(type.toLowerCase());
|
||||
}
|
||||
11
src/openApi/v3/parser/getModels.ts
Normal file
11
src/openApi/v3/parser/getModels.ts
Normal file
@ -0,0 +1,11 @@
|
||||
import { Model } from '../../../client/interfaces/Model';
|
||||
import { OpenApi } from '../interfaces/OpenApi';
|
||||
|
||||
/**
|
||||
* Parse and return the OpenAPI models.
|
||||
* @param openApi
|
||||
*/
|
||||
export function getModels(openApi: OpenApi): Map<string, Model> {
|
||||
const models = new Map<string, Model>();
|
||||
return models;
|
||||
}
|
||||
11
src/openApi/v3/parser/getSchemas.ts
Normal file
11
src/openApi/v3/parser/getSchemas.ts
Normal file
@ -0,0 +1,11 @@
|
||||
import { Schema } from '../../../client/interfaces/Schema';
|
||||
import { OpenApi } from '../interfaces/OpenApi';
|
||||
|
||||
/**
|
||||
* Parse and return the OpenAPI schemas.
|
||||
* @param openApi
|
||||
*/
|
||||
export function getSchemas(openApi: OpenApi): Map<string, Schema> {
|
||||
const schemas = new Map<string, Schema>();
|
||||
return schemas;
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user