ClientAPI, ServerAPI interface, Schema TS codegen
ClientAPI: use Axios ServerAPI: use @koa/router FullDate: wrapped Date only class APIPromise: enhanced Promise on api response application/json only(multipart/*, image/*, ... are not supported) get, post, put, delete, patch only
This commit is contained in:
commit
75674df502
36 changed files with 3210 additions and 0 deletions
3
.eslintignore
Normal file
3
.eslintignore
Normal file
|
@ -0,0 +1,3 @@
|
|||
dist/
|
||||
./utils/
|
||||
node_modules/
|
33
.eslintrc.js
Normal file
33
.eslintrc.js
Normal file
|
@ -0,0 +1,33 @@
|
|||
module.exports = {
|
||||
'env': {
|
||||
'es6': true,
|
||||
'node': true
|
||||
},
|
||||
'extends': [
|
||||
'google'
|
||||
],
|
||||
'globals': {
|
||||
'Atomics': 'readonly',
|
||||
'SharedArrayBuffer': 'readonly'
|
||||
},
|
||||
'parser': '@typescript-eslint/parser',
|
||||
'parserOptions': {
|
||||
'ecmaVersion': 2018,
|
||||
'sourceType': 'module'
|
||||
},
|
||||
'plugins': [
|
||||
'@typescript-eslint'
|
||||
],
|
||||
'rules': {
|
||||
'require-jsdoc': 'off',
|
||||
'arrow-parens': ['error', 'as-needed'],
|
||||
'indent': ['error', 2, {'MemberExpression': 1}],
|
||||
// no-unused-vars except ts interface
|
||||
'no-unused-vars': 'off',
|
||||
'@typescript-eslint/no-unused-vars': ['error', {
|
||||
'vars': 'all',
|
||||
'args': 'after-used',
|
||||
'ignoreRestSiblings': false
|
||||
}],
|
||||
},
|
||||
};
|
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
node_modules/
|
6
README.md
Normal file
6
README.md
Normal file
|
@ -0,0 +1,6 @@
|
|||
# OpenAPI codegen for TypeScript
|
||||
## TODO
|
||||
- Usage
|
||||
- Features
|
||||
- Limitations
|
||||
- Examples
|
108
bin/api-codegen.js
Executable file
108
bin/api-codegen.js
Executable file
|
@ -0,0 +1,108 @@
|
|||
#!/usr/bin/env node
|
||||
const fs = require('fs');
|
||||
const yaml = require('js-yaml');
|
||||
const {default: codegen} = require('../dist/codegen.js');
|
||||
|
||||
const badArgv = (x, code=1) => {
|
||||
console.error(`\x1b[1;31mError: ${x}\x1b[0m`);
|
||||
console.error([
|
||||
'Usage: api-codegen <apiDocPath> [flags]',
|
||||
'Flags:',
|
||||
' -o --outputDir: outputDir',
|
||||
].join('\n'));
|
||||
process.exit(code);
|
||||
};
|
||||
const errExit = (x, err, code=1) => {
|
||||
console.error(`\x1b[1;31mError: ${x}\x1b[0m`);
|
||||
if (err) console.error(err);
|
||||
process.exit(code);
|
||||
};
|
||||
|
||||
const argAttrs = ['apiDocPath'];
|
||||
const flag2attr = {
|
||||
o: 'outputDir',
|
||||
outputDir: 'outputDir',
|
||||
};
|
||||
const requiredAttrs = [
|
||||
...argAttrs,
|
||||
];
|
||||
function parseArgv(argv) {
|
||||
const argAttrLs = [...argAttrs];
|
||||
const config = {};
|
||||
let flag0 = null;
|
||||
let attr = null;
|
||||
|
||||
const setFlag = flag => {
|
||||
flag0 = flag;
|
||||
const attr0 = flag2attr[flag];
|
||||
if (attr0 == null) return badArgv(`Unknown flag: ${flag}`);
|
||||
if (config[attr0] != null) return badArgv(`Duplicate flag: ${flag}`);
|
||||
attr = attr0;
|
||||
};
|
||||
const setVal = val => {
|
||||
if (attr == null) {
|
||||
const attr0 = argAttrLs.shift();
|
||||
if (attr0 == null) return badArgv(`Unexpected token: ${val}`);
|
||||
config[attr0] = val;
|
||||
} else {
|
||||
config[attr] = val;
|
||||
attr = null;
|
||||
}
|
||||
};
|
||||
|
||||
for (const arg of argv) {
|
||||
if (arg.startsWith('-')) {
|
||||
if (arg.length == 1) {
|
||||
return badArgv(`Unexpected token: -`);
|
||||
} else if (arg[1] == '-') {
|
||||
// flag name
|
||||
setFlag(arg.substring(2));
|
||||
} else {
|
||||
// flag name + para
|
||||
setFlag(arg[1]);
|
||||
if (arg.length > 2) setVal(arg.substring(2));
|
||||
}
|
||||
} else { // val
|
||||
setVal(arg);
|
||||
}
|
||||
}
|
||||
// check
|
||||
if (attr != null) return badArgv(`Expect value for flag: ${flag0}`);
|
||||
for (const attr of requiredAttrs) {
|
||||
if (!config[attr]) return badArgv(`${attr} is required`);
|
||||
}
|
||||
return config;
|
||||
}
|
||||
|
||||
async function miku() {
|
||||
const config = parseArgv(process.argv.slice(2));
|
||||
const {apiDocPath} = config;
|
||||
let sAPI;
|
||||
try {
|
||||
sAPI = fs.readFileSync(apiDocPath).toString();
|
||||
} catch (err) {
|
||||
return errExit(`Fail to read api doc with path: ${apiDocPath}`, err);
|
||||
}
|
||||
let api;
|
||||
if (apiDocPath.endsWith('.json')) {
|
||||
try {
|
||||
api = JSON.parse(sAPI);
|
||||
} catch (err) {
|
||||
return errExit('Invalid JSON file', err);
|
||||
}
|
||||
} else if (apiDocPath.match(/\.ya?ml$/)) {
|
||||
try {
|
||||
api = yaml.load(sAPI);
|
||||
} catch (err) {
|
||||
return errExit('Invalid YAML file', err);
|
||||
}
|
||||
} else {
|
||||
return errExit(`Unknown file type: ${apiDocPath}`);
|
||||
}
|
||||
// TODO
|
||||
const openAPI = api;
|
||||
return codegen(openAPI, config);
|
||||
}
|
||||
miku()
|
||||
.then(() => console.log('\x1b[1;96mDONE\x1b[0m'))
|
||||
.catch(err => errExit('Fail to codegen', err));
|
23
dist/CodePrinter.d.ts
vendored
Normal file
23
dist/CodePrinter.d.ts
vendored
Normal file
|
@ -0,0 +1,23 @@
|
|||
interface WriteStream {
|
||||
write(s: string): void;
|
||||
on(s: string, callback: () => void): void;
|
||||
end(): void;
|
||||
}
|
||||
export declare class StringStream implements WriteStream {
|
||||
private content;
|
||||
write(s: string): void;
|
||||
on(): void;
|
||||
end(): void;
|
||||
toString(): string;
|
||||
}
|
||||
export declare class CodePrinter {
|
||||
private writeStream;
|
||||
private indentString;
|
||||
private cIndent;
|
||||
constructor(writeStream?: WriteStream, indentString?: string);
|
||||
writeln(s?: string, dIndent?: number): void;
|
||||
write(s: string): void;
|
||||
tab(x: number): void;
|
||||
end(): Promise<void>;
|
||||
}
|
||||
export {};
|
50
dist/CodePrinter.js
vendored
Normal file
50
dist/CodePrinter.js
vendored
Normal file
|
@ -0,0 +1,50 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
var StringStream = /** @class */ (function () {
|
||||
function StringStream() {
|
||||
this.content = '';
|
||||
}
|
||||
StringStream.prototype.write = function (s) {
|
||||
this.content += s;
|
||||
};
|
||||
StringStream.prototype.on = function () { };
|
||||
StringStream.prototype.end = function () { };
|
||||
StringStream.prototype.toString = function () {
|
||||
return this.content;
|
||||
};
|
||||
return StringStream;
|
||||
}());
|
||||
exports.StringStream = StringStream;
|
||||
var CodePrinter = /** @class */ (function () {
|
||||
function CodePrinter(writeStream, indentString) {
|
||||
if (writeStream === void 0) { writeStream = new StringStream(); }
|
||||
if (indentString === void 0) { indentString = ' '; }
|
||||
this.writeStream = writeStream;
|
||||
this.indentString = indentString;
|
||||
this.cIndent = 0;
|
||||
}
|
||||
CodePrinter.prototype.writeln = function (s, dIndent) {
|
||||
if (s === void 0) { s = ''; }
|
||||
if (dIndent === void 0) { dIndent = 0; }
|
||||
if (dIndent < 0)
|
||||
this.cIndent = Math.max(0, this.cIndent + dIndent);
|
||||
this.write(this.indentString.repeat(this.cIndent) + s + "\n");
|
||||
if (dIndent > 0)
|
||||
this.cIndent += dIndent;
|
||||
};
|
||||
CodePrinter.prototype.write = function (s) {
|
||||
this.writeStream.write(s);
|
||||
};
|
||||
CodePrinter.prototype.tab = function (x) {
|
||||
this.cIndent += x;
|
||||
};
|
||||
CodePrinter.prototype.end = function () {
|
||||
var _this = this;
|
||||
return new Promise(function (rsv) {
|
||||
_this.writeStream.on('finish', rsv);
|
||||
_this.writeStream.end();
|
||||
});
|
||||
};
|
||||
return CodePrinter;
|
||||
}());
|
||||
exports.CodePrinter = CodePrinter;
|
22
dist/Config.d.ts
vendored
Normal file
22
dist/Config.d.ts
vendored
Normal file
|
@ -0,0 +1,22 @@
|
|||
export declare type Config = ConfigRequired & ConfigOptional;
|
||||
export declare type ConfigUser = ConfigRequired & Partial<ConfigOptional>;
|
||||
export interface ConfigRequired {
|
||||
}
|
||||
export interface ConfigOptional {
|
||||
interfacePrefix: string;
|
||||
indentString: string;
|
||||
responsePrefix: string;
|
||||
schemasName: string;
|
||||
IHandlerName: string;
|
||||
IServerAPIName: string;
|
||||
IClientAPIName: string;
|
||||
ClientAPIName: string;
|
||||
routerName: string;
|
||||
apiDirTSPath: string;
|
||||
ServerAPITSPath: string;
|
||||
utilsTSPath: string;
|
||||
stateTSPath: string | null;
|
||||
outputDir: string;
|
||||
validateStatus: (status: string) => boolean;
|
||||
}
|
||||
export declare const configDefault: ConfigOptional;
|
23
dist/Config.js
vendored
Normal file
23
dist/Config.js
vendored
Normal file
|
@ -0,0 +1,23 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.configDefault = {
|
||||
// format
|
||||
interfacePrefix: 'I',
|
||||
indentString: ' ',
|
||||
responsePrefix: '',
|
||||
// name
|
||||
schemasName: 'schemas',
|
||||
IHandlerName: 'IHandler',
|
||||
IServerAPIName: 'IServerAPI',
|
||||
IClientAPIName: 'IClientAPI',
|
||||
ClientAPIName: 'ClientAPI',
|
||||
routerName: 'apiRouter',
|
||||
// TS path
|
||||
apiDirTSPath: '#api',
|
||||
ServerAPITSPath: '#ServerAPI',
|
||||
utilsTSPath: 'api-codegen-ts/utils',
|
||||
stateTSPath: null,
|
||||
// other
|
||||
outputDir: 'api/generated',
|
||||
validateStatus: function (status) { return /^2..$/.test(status); },
|
||||
};
|
127
dist/OpenAPI.d.ts
vendored
Normal file
127
dist/OpenAPI.d.ts
vendored
Normal file
|
@ -0,0 +1,127 @@
|
|||
export interface OpenAPI {
|
||||
paths: Paths;
|
||||
components?: Components;
|
||||
}
|
||||
interface Paths {
|
||||
[path: string]: PathItem;
|
||||
}
|
||||
interface PathItem {
|
||||
get?: Operation;
|
||||
put?: Operation;
|
||||
post?: Operation;
|
||||
delete?: Operation;
|
||||
patch?: Operation;
|
||||
[_: string]: any;
|
||||
}
|
||||
interface Operation {
|
||||
responses: Responses;
|
||||
parameters?: Parameter[];
|
||||
requestBody?: RequestBody;
|
||||
operationId?: string;
|
||||
}
|
||||
interface Responses {
|
||||
[status: string]: Response;
|
||||
}
|
||||
interface Response {
|
||||
content?: TMediaTypes;
|
||||
}
|
||||
declare type TMediaTypes = {
|
||||
[contentType: string]: MediaType;
|
||||
};
|
||||
interface MediaType {
|
||||
schema?: Schema | Reference;
|
||||
example?: any;
|
||||
examples?: {
|
||||
[_: string]: object;
|
||||
};
|
||||
}
|
||||
interface Parameter {
|
||||
name: string;
|
||||
in: EParameterIn;
|
||||
description?: string;
|
||||
required?: boolean;
|
||||
deprecated?: boolean;
|
||||
style?: string;
|
||||
schema?: Schema | Reference;
|
||||
}
|
||||
declare type EParameterIn = 'query' | 'header' | 'path' | 'cookie';
|
||||
export declare const ELParameterIn: Array<EParameterIn>;
|
||||
interface RequestBody {
|
||||
description: string;
|
||||
content: {
|
||||
[contentType: string]: MediaType;
|
||||
};
|
||||
required?: boolean;
|
||||
}
|
||||
interface Components {
|
||||
schemas: {
|
||||
[_: string]: Schema | Reference;
|
||||
};
|
||||
}
|
||||
export declare type Schemas = {
|
||||
[_: string]: Schema | Reference;
|
||||
};
|
||||
interface Schema {
|
||||
type: string;
|
||||
format?: string;
|
||||
nullable?: boolean;
|
||||
readOnly?: boolean;
|
||||
maxSize?: number;
|
||||
}
|
||||
interface ArraySchema extends Schema {
|
||||
items: Schema | Reference;
|
||||
}
|
||||
export declare function isArraySchema(x: any): x is ArraySchema;
|
||||
interface ObjectSchema extends Schema {
|
||||
properties: {
|
||||
[name: string]: Schema | Reference;
|
||||
};
|
||||
}
|
||||
export declare function isObjectSchema(x: any): x is ObjectSchema;
|
||||
interface Reference {
|
||||
$ref: string;
|
||||
maxSize?: string | number;
|
||||
}
|
||||
declare class APIFunction {
|
||||
method: string;
|
||||
url: string;
|
||||
reqTypes: TReqTypes;
|
||||
resTypes: TResTypes;
|
||||
constructor(method: string, url: string, reqTypes: TReqTypes, resTypes: TResTypes);
|
||||
}
|
||||
declare type TReqTypes = {
|
||||
query?: {
|
||||
[name: string]: SchemaType;
|
||||
};
|
||||
header?: {
|
||||
[name: string]: SchemaType;
|
||||
};
|
||||
path?: {
|
||||
[name: string]: SchemaType;
|
||||
};
|
||||
cookie?: {
|
||||
[name: string]: SchemaType;
|
||||
};
|
||||
body?: SchemaType;
|
||||
};
|
||||
declare type TResTypes = {
|
||||
[status: string]: SchemaType;
|
||||
};
|
||||
export declare class SchemaType {
|
||||
private _required;
|
||||
private _typeName?;
|
||||
get typeName(): string;
|
||||
get required(): boolean;
|
||||
get maxSize(): string | number | undefined;
|
||||
forProp(prop: string): string;
|
||||
stp(prop: string): string;
|
||||
private schema;
|
||||
constructor(schema: Schema | Reference | string, _required: boolean);
|
||||
static typeNameOf(schema: Schema | Reference): string;
|
||||
static gcStp(para: string, schema: Schema | Reference): string;
|
||||
}
|
||||
export declare type APIFunctions = {
|
||||
[_: string]: APIFunction;
|
||||
};
|
||||
export declare function apiFunctionsOf(openAPI: OpenAPI): APIFunctions;
|
||||
export {};
|
226
dist/OpenAPI.js
vendored
Normal file
226
dist/OpenAPI.js
vendored
Normal file
|
@ -0,0 +1,226 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
var StrictTypeParser_1 = require("./utils/StrictTypeParser");
|
||||
var warn = function (x) { return console.warn('\x1b[1;33mWarning: ' + x + '\x1b[0m'); };
|
||||
var ELMethod = ['get', 'put', 'post', 'delete', 'patch'];
|
||||
exports.ELParameterIn = [
|
||||
'path', 'query', 'header', 'cookie'
|
||||
];
|
||||
function isArraySchema(x) {
|
||||
return x.type === 'array';
|
||||
}
|
||||
exports.isArraySchema = isArraySchema;
|
||||
function isObjectSchema(x) {
|
||||
return x.type === 'object';
|
||||
}
|
||||
exports.isObjectSchema = isObjectSchema;
|
||||
function isReference(x) {
|
||||
return typeof x.$ref === 'string';
|
||||
}
|
||||
// api
|
||||
var APIFunction = /** @class */ (function () {
|
||||
function APIFunction(method, url, reqTypes, resTypes) {
|
||||
this.method = method;
|
||||
this.url = url;
|
||||
this.reqTypes = reqTypes;
|
||||
this.resTypes = resTypes;
|
||||
}
|
||||
return APIFunction;
|
||||
}());
|
||||
/* ==== ==== */
|
||||
function mediaTypes2type(content, required) {
|
||||
var media = content === null || content === void 0 ? void 0 : content['application/json']; // TODO
|
||||
if (media == null) {
|
||||
if (Object.keys(content !== null && content !== void 0 ? content : {}).length > 0) {
|
||||
warn('only support application/json now');
|
||||
}
|
||||
return new SchemaType('any', false);
|
||||
}
|
||||
// schema
|
||||
var schema = media.schema;
|
||||
return new SchemaType(schema !== null && schema !== void 0 ? schema : 'any', required !== null && required !== void 0 ? required : false);
|
||||
}
|
||||
var SchemaType = /** @class */ (function () {
|
||||
function SchemaType(schema, _required) {
|
||||
this._required = _required;
|
||||
this.schema = typeof schema === 'string' ? { type: schema } : schema;
|
||||
}
|
||||
Object.defineProperty(SchemaType.prototype, "typeName", {
|
||||
get: function () {
|
||||
var _a;
|
||||
return (_a = this._typeName) !== null && _a !== void 0 ? _a : (this._typeName = SchemaType.typeNameOf(this.schema));
|
||||
},
|
||||
enumerable: true,
|
||||
configurable: true
|
||||
});
|
||||
Object.defineProperty(SchemaType.prototype, "required", {
|
||||
get: function () {
|
||||
return this._required;
|
||||
},
|
||||
enumerable: true,
|
||||
configurable: true
|
||||
});
|
||||
Object.defineProperty(SchemaType.prototype, "maxSize", {
|
||||
get: function () {
|
||||
return this.schema.maxSize;
|
||||
},
|
||||
enumerable: true,
|
||||
configurable: true
|
||||
});
|
||||
SchemaType.prototype.forProp = function (prop) {
|
||||
return "" + prop + (this.required ? '' : '?') + ": " + this.typeName;
|
||||
};
|
||||
SchemaType.prototype.stp = function (prop) {
|
||||
var stp = SchemaType.gcStp(prop, this.schema);
|
||||
return (this.required ? '' : prop + "===undefined ? undefined : ") + stp;
|
||||
};
|
||||
SchemaType.typeNameOf = function (schema) {
|
||||
var _a;
|
||||
if (isReference(schema)) {
|
||||
var $ref = schema.$ref;
|
||||
var typeName = (_a = /^#\/components\/schemas\/(\w+)$/g.exec($ref)) === null || _a === void 0 ? void 0 : _a[1];
|
||||
if (typeName == null) {
|
||||
warn("Invalid $ref, use any instead: " + $ref);
|
||||
return 'any';
|
||||
}
|
||||
return "Schemas." + typeName;
|
||||
}
|
||||
var type = schema.type, format = schema.format, nullable = schema.nullable, readOnly = schema.readOnly;
|
||||
var sType = type;
|
||||
if (isArraySchema(schema)) {
|
||||
sType = "Array<" + SchemaType.typeNameOf(schema.items) + ">";
|
||||
}
|
||||
else if (isObjectSchema(schema)) {
|
||||
sType = '{';
|
||||
for (var _i = 0, _b = Object.entries(schema.properties); _i < _b.length; _i++) {
|
||||
var _c = _b[_i], name_1 = _c[0], sub = _c[1];
|
||||
sType += name_1 + ": " + SchemaType.typeNameOf(sub) + ", ";
|
||||
}
|
||||
sType += '}';
|
||||
}
|
||||
else if (type === 'string') {
|
||||
if (format === 'date-time')
|
||||
sType = 'Date';
|
||||
else if (format === 'date')
|
||||
sType = 'FullDate';
|
||||
else if (format === 'byte')
|
||||
sType = 'string'; // TODO Buffer
|
||||
else if (format === 'binary')
|
||||
sType = 'string'; // TODO Buffer
|
||||
else if (format)
|
||||
warn("Unknown format " + format + ", use string instead");
|
||||
}
|
||||
else if (type === 'integer')
|
||||
sType = 'number'; // TODO integer
|
||||
if (nullable)
|
||||
sType = sType + " | null";
|
||||
if (readOnly)
|
||||
sType = "Readonly<" + sType + ">";
|
||||
return sType;
|
||||
};
|
||||
SchemaType.gcStp = function (para, schema) {
|
||||
var sPara = "'" + para.replace(/'/g, '\\\'') + "'";
|
||||
// object
|
||||
if (isReference(schema)) {
|
||||
return "new " + new SchemaType(schema, true).typeName + "(" + para + ")";
|
||||
}
|
||||
// any
|
||||
var code;
|
||||
var type = schema.type, nullable = schema.nullable, format = schema.format;
|
||||
if (type === 'any')
|
||||
return para;
|
||||
if (isArraySchema(schema)) {
|
||||
code = "STP._Array(" + para + ", " + sPara + ").map(o=>" + SchemaType.gcStp('o', schema.items) + ")";
|
||||
}
|
||||
else if (isObjectSchema(schema)) {
|
||||
code = '{';
|
||||
for (var _i = 0, _a = Object.entries(schema.properties); _i < _a.length; _i++) {
|
||||
var _b = _a[_i], name_2 = _b[0], sub = _b[1];
|
||||
code += name_2 + ": " + SchemaType.gcStp(para + '.' + name_2, sub) + ", ";
|
||||
}
|
||||
code += '}';
|
||||
}
|
||||
else {
|
||||
var t = void 0;
|
||||
if (type === 'string') {
|
||||
if (format === 'date-time')
|
||||
t = 'Date';
|
||||
else if (format === 'date')
|
||||
t = 'FullDate';
|
||||
else if (format === 'byte')
|
||||
t = 'string'; // TODO
|
||||
else if (format === 'binary')
|
||||
t = 'string'; // TODO
|
||||
else {
|
||||
if (format)
|
||||
warn("Unknown format " + format + ", use string instead");
|
||||
t = 'string';
|
||||
}
|
||||
}
|
||||
else if (type === 'integer')
|
||||
t = 'number';
|
||||
else
|
||||
t = type;
|
||||
if (!StrictTypeParser_1.StrictTypeParser.supportTypes.includes(t)) {
|
||||
warn("Unknown type " + type + ", use any instead");
|
||||
return para;
|
||||
}
|
||||
else
|
||||
code = "STP._" + t + "(" + para + ", " + sPara + ")";
|
||||
}
|
||||
// nullable
|
||||
if (nullable)
|
||||
code = para + "===null ? null : " + code;
|
||||
return code;
|
||||
};
|
||||
return SchemaType;
|
||||
}());
|
||||
exports.SchemaType = SchemaType;
|
||||
function apiFunctionsOf(openAPI) {
|
||||
var paths = openAPI.paths;
|
||||
var functions = {};
|
||||
for (var _i = 0, _a = Object.entries(paths); _i < _a.length; _i++) {
|
||||
var _b = _a[_i], url = _b[0], pathItem = _b[1];
|
||||
for (var _c = 0, ELMethod_1 = ELMethod; _c < ELMethod_1.length; _c++) {
|
||||
var method = ELMethod_1[_c];
|
||||
var op = pathItem[method];
|
||||
if (op == null)
|
||||
continue;
|
||||
// operationId
|
||||
var operationId = op.operationId, parameters = op.parameters, requestBody = op.requestBody, responses = op.responses;
|
||||
if (operationId == null) {
|
||||
warn("ignore operation in " + method + " " + url + ": " +
|
||||
'operationId should be given');
|
||||
continue;
|
||||
}
|
||||
var name_3 = operationId;
|
||||
var reqTypes = {};
|
||||
var resTypes = {};
|
||||
// reqParas
|
||||
if (parameters != null) {
|
||||
for (var _d = 0, parameters_1 = parameters; _d < parameters_1.length; _d++) {
|
||||
var para = parameters_1[_d];
|
||||
var name_4 = para.name, _in = para.in, required = para.required, schema = para.schema;
|
||||
// add
|
||||
if (reqTypes[_in] == null)
|
||||
reqTypes[_in] = {};
|
||||
reqTypes[_in][name_4] = new SchemaType(schema !== null && schema !== void 0 ? schema : 'any', required !== null && required !== void 0 ? required : false);
|
||||
}
|
||||
}
|
||||
// requestBody
|
||||
if (requestBody != null) {
|
||||
reqTypes.body = mediaTypes2type(requestBody.content, requestBody.required);
|
||||
}
|
||||
// responses
|
||||
for (var _e = 0, _f = Object.entries(responses); _e < _f.length; _e++) {
|
||||
var _g = _f[_e], status_1 = _g[0], res = _g[1];
|
||||
resTypes[status_1] = mediaTypes2type(res.content, true);
|
||||
}
|
||||
// add to group
|
||||
var saf = new APIFunction(method, url, reqTypes, resTypes);
|
||||
functions[name_3] = saf;
|
||||
}
|
||||
}
|
||||
return functions;
|
||||
}
|
||||
exports.apiFunctionsOf = apiFunctionsOf;
|
3
dist/codegen.d.ts
vendored
Normal file
3
dist/codegen.d.ts
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
import { ConfigUser } from './Config';
|
||||
import { OpenAPI } from './OpenAPI';
|
||||
export default function codegen(openAPI: OpenAPI, configUser: ConfigUser): Promise<any[]>;
|
374
dist/codegen.js
vendored
Normal file
374
dist/codegen.js
vendored
Normal file
|
@ -0,0 +1,374 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
var fs = require("fs");
|
||||
var path = require("path");
|
||||
var Config_1 = require("./Config");
|
||||
var OpenAPI_1 = require("./OpenAPI");
|
||||
var CodePrinter_1 = require("./CodePrinter");
|
||||
function codegenIServerAPI(funcs, config, cp) {
|
||||
var apiDirTSPath = config.apiDirTSPath, IHandlerName = config.IHandlerName;
|
||||
// import
|
||||
cp.writeln("import * as IHandler from '" + apiDirTSPath + "/" + IHandlerName + "'");
|
||||
// export default
|
||||
cp.writeln('\nexport default interface IAPI {', 1);
|
||||
for (var _i = 0, _a = Object.keys(funcs); _i < _a.length; _i++) {
|
||||
var funcName = _a[_i];
|
||||
cp.writeln(funcName + ": IHandler." + funcName + ".IServerHandler;");
|
||||
}
|
||||
cp.writeln('};', -1);
|
||||
return cp.end();
|
||||
}
|
||||
function codegenIHandler(funcs, config, cp) {
|
||||
var apiDirTSPath = config.apiDirTSPath, schemasName = config.schemasName, utilsTSPath = config.utilsTSPath, responsePrefix = config.responsePrefix, validateStatus = config.validateStatus, stateTSPath = config.stateTSPath;
|
||||
// import
|
||||
cp.writeln("import * as Schemas from '" + apiDirTSPath + "/" + schemasName + "'");
|
||||
cp.writeln('import {FullDate, StrictTypeParser as STP, APIPromise} ' +
|
||||
("from '" + utilsTSPath + "'"));
|
||||
cp.writeln('import {RouterContext as Context} from \'@koa/router\'');
|
||||
cp.writeln('import {AxiosResponse} from \'axios\'');
|
||||
cp.writeln(stateTSPath ?
|
||||
"import IState from '" + stateTSPath + "'" : 'type IState = any');
|
||||
// handler types
|
||||
for (var _i = 0, _a = Object.entries(funcs); _i < _a.length; _i++) {
|
||||
var _b = _a[_i], funcName = _b[0], func = _b[1];
|
||||
var reqTypes = func.reqTypes, resTypes = func.resTypes, method = func.method;
|
||||
cp.writeln("export namespace " + funcName + " {", 1);
|
||||
// req
|
||||
var sReqTypes = [];
|
||||
// paras
|
||||
for (var _c = 0, ELParameterIn_1 = OpenAPI_1.ELParameterIn; _c < ELParameterIn_1.length; _c++) {
|
||||
var _in = ELParameterIn_1[_c];
|
||||
var paras = reqTypes[_in];
|
||||
if (paras == null)
|
||||
continue;
|
||||
cp.writeln("export type T_" + _in + " = {", 1);
|
||||
for (var _d = 0, _e = Object.entries(paras); _d < _e.length; _d++) {
|
||||
var _f = _e[_d], propName = _f[0], schemaType = _f[1];
|
||||
cp.writeln(schemaType.forProp(propName) + ';');
|
||||
}
|
||||
cp.writeln('};', -1);
|
||||
sReqTypes.push(_in + ": T_" + _in);
|
||||
}
|
||||
// body
|
||||
var body = reqTypes.body;
|
||||
if (body != null) {
|
||||
// PATCH's req body: Partial
|
||||
var typeName = body.typeName;
|
||||
if (method == 'patch')
|
||||
typeName = "Partial<" + typeName + ">";
|
||||
cp.writeln("export type T_body = " + typeName + ";");
|
||||
sReqTypes.push("body" + (body.required ? '' : '?') + ": T_body");
|
||||
}
|
||||
// IRequest
|
||||
if (sReqTypes.length > 0) {
|
||||
cp.writeln('interface IRequest {', 1);
|
||||
for (var _g = 0, sReqTypes_1 = sReqTypes; _g < sReqTypes_1.length; _g++) {
|
||||
var sReqType = sReqTypes_1[_g];
|
||||
cp.writeln(sReqType + ";");
|
||||
}
|
||||
cp.writeln('}', -1);
|
||||
}
|
||||
else
|
||||
cp.writeln('interface IRequest {}');
|
||||
// res
|
||||
cp.writeln('interface IResponses<T> {', 1);
|
||||
for (var _h = 0, _j = Object.entries(resTypes); _h < _j.length; _h++) {
|
||||
var _k = _j[_h], status_1 = _k[0], schema = _k[1];
|
||||
cp.writeln("" + responsePrefix + status_1 + ": " + ("(" + schema.forProp('body') + ") => T;"));
|
||||
}
|
||||
cp.writeln('}', -1);
|
||||
cp.writeln('export interface IServerHandler {', 1);
|
||||
cp.writeln('(req: IRequest, res: IResponses<void>, ' +
|
||||
'state: IState, ctx: Context): void;');
|
||||
cp.writeln('}', -1);
|
||||
// class _ResponsePromise
|
||||
var validTypes = new Set();
|
||||
cp.writeln('export class ResponsePromise<T> extends ' +
|
||||
'APIPromise<T|T_ValidResponse> {', 1);
|
||||
// handler
|
||||
cp.writeln('private handlers: Partial<IResponses<T>> = {};');
|
||||
// on
|
||||
cp.writeln('on<K extends keyof IResponses<T>, U>(', 1);
|
||||
cp.writeln('k: K, h: IResponses<U>[K]): ResponsePromise<T|U>');
|
||||
cp.tab(-1);
|
||||
cp.writeln('{ const e: ResponsePromise<T|U> = this; ' +
|
||||
'e.handlers[k] = h; return e; }');
|
||||
// onResponse
|
||||
cp.writeln('onResponse(res: AxiosResponse<any>){', 1);
|
||||
cp.writeln('const {status, data} = res');
|
||||
cp.writeln('switch(status){', 1);
|
||||
for (var _l = 0, _m = Object.entries(resTypes); _l < _m.length; _l++) {
|
||||
var _o = _m[_l], status_2 = _o[0], schema = _o[1];
|
||||
// TODO void -> string or any
|
||||
var isValid = validateStatus(status_2);
|
||||
cp.writeln("case " + status_2 + ": return this." + (isValid ? 'onSuccess' : 'onFail') + "(this.handlers[" + status_2 + "],", 1);
|
||||
cp.writeln(schema.stp('data') + ");");
|
||||
cp.tab(-1);
|
||||
if (isValid)
|
||||
validTypes.add(schema.typeName);
|
||||
}
|
||||
cp.writeln('}', -1); // end switch
|
||||
cp.writeln('throw new Error(\'Unexpect status code: \'+status);');
|
||||
cp.writeln('}', -1); // end onResponse
|
||||
cp.writeln('}', -1); // end class
|
||||
// valid type
|
||||
var sValidTypes = Array.from(validTypes.values()).join(' | ');
|
||||
cp.writeln("export type T_ValidResponse = " + sValidTypes + ";");
|
||||
// export client handler
|
||||
cp.writeln('export interface IClientHandler {', 1);
|
||||
cp.writeln("(" + sReqTypes.join(', ') + "): ResponsePromise<never>;");
|
||||
cp.writeln('}', -1); // end client handler
|
||||
cp.writeln('}', -1); // end namespace
|
||||
}
|
||||
return cp.end();
|
||||
}
|
||||
function codegenRouter(funcs, config, cp) {
|
||||
var apiDirTSPath = config.apiDirTSPath, schemasName = config.schemasName, responsePrefix = config.responsePrefix, ServerAPITSPath = config.ServerAPITSPath, utilsTSPath = config.utilsTSPath, stateTSPath = config.stateTSPath;
|
||||
// import
|
||||
cp.writeln("import * as Schemas from '" + apiDirTSPath + "/" + schemasName + "'");
|
||||
cp.writeln("import * as Router from '@koa/router'");
|
||||
cp.writeln("import {FullDate, StrictTypeParser as STP} from '" + utilsTSPath + "'");
|
||||
cp.writeln("import * as bodyParser from 'koa-body'");
|
||||
cp.writeln(stateTSPath ?
|
||||
"import IState from '" + stateTSPath + "'" : 'type IState = any');
|
||||
cp.writeln("type CTX = Router.RouterContext<IState>;");
|
||||
// router
|
||||
cp.writeln("\nconst router = new Router<IState>();");
|
||||
cp.writeln('');
|
||||
// function
|
||||
cp.writeln('function isEmpty(x: any): boolean {', 1);
|
||||
cp.writeln('if(x == null || x === \'\') return true;');
|
||||
cp.writeln('if(typeof x === \'object\') return Object.keys(x).length===0');
|
||||
cp.writeln('return false;');
|
||||
cp.writeln('}', -1);
|
||||
cp.writeln('function nullableParse<T>(v: any, ' +
|
||||
'p: (x: any)=>T): T | undefined {', 1);
|
||||
cp.writeln('return isEmpty(v) ? undefined : p(v);');
|
||||
cp.writeln('}', -1);
|
||||
cp.writeln('const ctxGetParas = {', 1);
|
||||
cp.writeln('path: (ctx: CTX, attr: string) => ctx.params[attr],');
|
||||
cp.writeln('query: (ctx: CTX, attr: string) => ctx.query[attr],');
|
||||
cp.writeln('header: (ctx: CTX, attr: string) => ctx.headers[attr],');
|
||||
cp.writeln('cookie: (ctx: CTX, attr: string) => ctx.cookies.get(attr),');
|
||||
cp.writeln('};', -1);
|
||||
// response generator
|
||||
cp.writeln('function g_res<T>(ctx: CTX, ' +
|
||||
'status: number, dft: string = \'\'){', 1);
|
||||
cp.writeln('return (body: T) => {', 1);
|
||||
cp.writeln('ctx.status = status;');
|
||||
cp.writeln('ctx.body = body ?? dft;');
|
||||
cp.writeln('}', -1);
|
||||
cp.writeln('}', -1);
|
||||
// route
|
||||
cp.writeln("\nimport api from '" + ServerAPITSPath + "'");
|
||||
for (var _i = 0, _a = Object.entries(funcs); _i < _a.length; _i++) {
|
||||
var _b = _a[_i], funcName = _b[0], func = _b[1];
|
||||
var method = func.method, url = func.url, reqTypes = func.reqTypes, resTypes = func.resTypes;
|
||||
var statuses = Object.keys(resTypes);
|
||||
// TODO escape
|
||||
var sURL = url.replace(/{(.*?)}/g, ':$1'); // {a} -> :a
|
||||
var mid = '';
|
||||
if (reqTypes.body) {
|
||||
var maxSize = reqTypes.body.maxSize;
|
||||
var config_1 = maxSize == null ? '' : "{jsonLimit: '" + maxSize + "'}";
|
||||
mid = "bodyParser(" + config_1 + "), ";
|
||||
}
|
||||
cp.writeln("router." + method + "('" + sURL + "', " + mid + "async ctx => {", 1);
|
||||
// TODO permission check, etc
|
||||
if (Object.keys(reqTypes).length === 0) {
|
||||
cp.writeln('const req = {};');
|
||||
}
|
||||
else {
|
||||
cp.writeln('let req;');
|
||||
cp.writeln('const {body: reqBody} = ctx.request;');
|
||||
cp.writeln('try { req = {', 1);
|
||||
// paras
|
||||
for (var _c = 0, ELParameterIn_2 = OpenAPI_1.ELParameterIn; _c < ELParameterIn_2.length; _c++) {
|
||||
var _in = ELParameterIn_2[_c];
|
||||
var paras = reqTypes[_in];
|
||||
if (paras == null)
|
||||
continue;
|
||||
cp.writeln(_in + ": {", 1);
|
||||
for (var _d = 0, _e = Object.entries(paras); _d < _e.length; _d++) {
|
||||
var _f = _e[_d], name_1 = _f[0], schema = _f[1];
|
||||
var pn = "ctxGetParas." + _in + "(ctx, '" + name_1 + "')";
|
||||
cp.writeln(name_1 + ": " + schema.stp(pn) + ",");
|
||||
}
|
||||
cp.writeln('},', -1);
|
||||
}
|
||||
// body
|
||||
var body = reqTypes.body;
|
||||
if (body != null) {
|
||||
var name_2 = 'body';
|
||||
var pn = 'reqBody';
|
||||
cp.writeln(name_2 + ": " + body.stp(pn));
|
||||
}
|
||||
cp.writeln('}} catch(err) {', -1);
|
||||
cp.tab(1);
|
||||
cp.writeln('if(err instanceof STP.BadValueError)', 1);
|
||||
cp.writeln('return ctx.throw(400, err.toString());');
|
||||
cp.tab(-1);
|
||||
cp.writeln('throw err;');
|
||||
cp.writeln('}', -1);
|
||||
}
|
||||
// res
|
||||
cp.writeln('const res = {', 1);
|
||||
for (var _g = 0, statuses_1 = statuses; _g < statuses_1.length; _g++) {
|
||||
var status_3 = statuses_1[_g];
|
||||
cp.writeln("" + responsePrefix + status_3 + ": g_res(ctx, " + status_3 + "),");
|
||||
}
|
||||
cp.writeln('};', -1);
|
||||
// call
|
||||
cp.writeln("await api." + funcName + "(req, res, ctx.state, ctx);");
|
||||
cp.writeln('})', -1);
|
||||
}
|
||||
cp.writeln('\nexport default router;');
|
||||
return cp.end();
|
||||
}
|
||||
function codegenIClientAPI(funcs, config, cp) {
|
||||
var apiDirTSPath = config.apiDirTSPath, IHandlerName = config.IHandlerName;
|
||||
// import
|
||||
cp.writeln("import * as IHandler from '" + apiDirTSPath + "/" + IHandlerName + "'");
|
||||
// export default
|
||||
cp.writeln('\nexport default interface IAPI {', 1);
|
||||
cp.writeln('$baseURL: string;');
|
||||
for (var _i = 0, _a = Object.keys(funcs); _i < _a.length; _i++) {
|
||||
var funcName = _a[_i];
|
||||
cp.writeln(funcName + ": IHandler." + funcName + ".IClientHandler;");
|
||||
}
|
||||
cp.writeln('}', -1);
|
||||
return cp.end();
|
||||
}
|
||||
function codegenClientAPI(funcs, config, cp) {
|
||||
var apiDirTSPath = config.apiDirTSPath, IClientAPIName = config.IClientAPIName, IHandlerName = config.IHandlerName;
|
||||
// import
|
||||
cp.writeln("import * as _IAPI from '" + apiDirTSPath + "/" + IClientAPIName + "'");
|
||||
cp.writeln("import IAPI from '" + apiDirTSPath + "/" + IClientAPIName + "'");
|
||||
cp.writeln("import * as IHandler from '" + apiDirTSPath + "/" + IHandlerName + "'");
|
||||
cp.writeln('import axios from \'axios\'');
|
||||
// axios
|
||||
cp.writeln('\nconst $http = axios.create({', 1);
|
||||
cp.writeln('validateStatus: ()=>true,');
|
||||
cp.writeln('});', -1);
|
||||
// function
|
||||
cp.writeln('\nfunction urlReplacer(url: string, ' +
|
||||
'rules: {[_: string]: any}): string {', 1);
|
||||
cp.writeln('for(const [attr, value] of Object.entries(rules))', 1);
|
||||
cp.writeln('url = url.replace(\'{\'+attr+\'}\', value)');
|
||||
cp.writeln('return url;', -1);
|
||||
cp.writeln('};', -1);
|
||||
// implementation
|
||||
// export default
|
||||
cp.writeln('\nexport default {', 1);
|
||||
// set $baseURL
|
||||
cp.writeln('set $baseURL(url: string) {', 1);
|
||||
cp.writeln('$http.interceptors.request.use(async config => {', 1);
|
||||
cp.writeln('config.baseURL = url;');
|
||||
cp.writeln('return config;', -1);
|
||||
cp.writeln('}, err => Promise.reject(err));', -1);
|
||||
cp.writeln('},');
|
||||
// functions
|
||||
for (var _i = 0, _a = Object.entries(funcs); _i < _a.length; _i++) {
|
||||
var _b = _a[_i], funcName = _b[0], func = _b[1];
|
||||
var ncHandler = "IHandler." + funcName;
|
||||
var method = func.method, url = func.url, reqTypes = func.reqTypes;
|
||||
var query = reqTypes.query, header = reqTypes.header, path_1 = reqTypes.path, body = reqTypes.body; // TODO cookie
|
||||
// name
|
||||
cp.writeln(funcName + "(", 1);
|
||||
// paras
|
||||
for (var _c = 0, ELParameterIn_3 = OpenAPI_1.ELParameterIn; _c < ELParameterIn_3.length; _c++) {
|
||||
var _in = ELParameterIn_3[_c];
|
||||
var paras = reqTypes[_in];
|
||||
if (paras == null)
|
||||
continue;
|
||||
var _required = false;
|
||||
for (var _d = 0, _e = Object.values(paras); _d < _e.length; _d++) {
|
||||
var required = _e[_d].required;
|
||||
if (required) {
|
||||
_required = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
cp.writeln(_in + ": " + ncHandler + ".T_" + _in + (_required ? '' : '={}') + ",");
|
||||
}
|
||||
// body
|
||||
if (body != null) {
|
||||
cp.writeln("body" + (body.required ? '' : '?') + ": " + ncHandler + ".T_body,");
|
||||
}
|
||||
// function body
|
||||
cp.tab(-1);
|
||||
cp.writeln("){return new " + ncHandler +
|
||||
'.ResponsePromise<never>($http({', 1);
|
||||
cp.writeln("method: '" + method + "',");
|
||||
var sURL = "'" + url + "'";
|
||||
cp.writeln("url: " + (path_1 ? "urlReplacer(" + sURL + ", path)" : sURL) + ",");
|
||||
if (query)
|
||||
cp.writeln('params: query,');
|
||||
if (header)
|
||||
cp.writeln('header: header,');
|
||||
if (body != null)
|
||||
cp.writeln('data: body,');
|
||||
cp.writeln('}));},', -1);
|
||||
}
|
||||
cp.writeln('} as IAPI', -1);
|
||||
return cp.end();
|
||||
}
|
||||
function codegenSchemas(schemas, config, cp) {
|
||||
var utilsTSPath = config.utilsTSPath;
|
||||
// import
|
||||
cp.writeln("import {FullDate, StrictTypeParser as STP} from '" + utilsTSPath + "'");
|
||||
cp.writeln();
|
||||
// schema
|
||||
for (var _i = 0, _a = Object.entries(schemas); _i < _a.length; _i++) {
|
||||
var _b = _a[_i], name_3 = _b[0], schema = _b[1];
|
||||
if (OpenAPI_1.isObjectSchema(schema)) {
|
||||
cp.writeln("export class " + name_3 + " {", 1);
|
||||
var propTypes = [];
|
||||
for (var _c = 0, _d = Object.entries(schema.properties); _c < _d.length; _c++) {
|
||||
var _e = _d[_c], propName = _e[0], prop = _e[1];
|
||||
var propType = new OpenAPI_1.SchemaType(prop, true); // TODO required?
|
||||
propTypes.push([propName, propType]);
|
||||
cp.writeln(propType.forProp(propName) + ';');
|
||||
}
|
||||
// method
|
||||
cp.writeln('constructor(o: {[_: string]: any}){', 1);
|
||||
for (var _f = 0, propTypes_1 = propTypes; _f < propTypes_1.length; _f++) {
|
||||
var _g = propTypes_1[_f], n = _g[0], t = _g[1];
|
||||
cp.writeln("this." + n + " = " + t.stp("o." + n) + ";");
|
||||
}
|
||||
cp.writeln('}', -1);
|
||||
cp.writeln('}', -1);
|
||||
}
|
||||
else {
|
||||
cp.writeln("export type " + name_3 + " = " + OpenAPI_1.SchemaType.typeNameOf(schema));
|
||||
}
|
||||
}
|
||||
// return
|
||||
return cp.end();
|
||||
}
|
||||
function codegen(openAPI, configUser) {
|
||||
var _a;
|
||||
var config = Object.assign({}, configUser, Config_1.configDefault);
|
||||
// prepare
|
||||
fs.mkdirSync(config.outputDir, { recursive: true });
|
||||
var apiFuncs = OpenAPI_1.apiFunctionsOf(openAPI);
|
||||
var gCP = function (fn) { return new CodePrinter_1.CodePrinter(fs.createWriteStream(path.join(config.outputDir, fn + '.ts')), config.indentString); };
|
||||
var ps = [];
|
||||
// write files
|
||||
// handler
|
||||
ps.push(codegenIHandler(apiFuncs, config, gCP(config.IHandlerName)));
|
||||
// server
|
||||
ps.push(codegenIServerAPI(apiFuncs, config, gCP(config.IServerAPIName)));
|
||||
ps.push(codegenRouter(apiFuncs, config, gCP(config.routerName)));
|
||||
// client
|
||||
ps.push(codegenIClientAPI(apiFuncs, config, gCP(config.IClientAPIName)));
|
||||
ps.push(codegenClientAPI(apiFuncs, config, gCP(config.ClientAPIName)));
|
||||
// schema
|
||||
var schemas = (_a = openAPI.components) === null || _a === void 0 ? void 0 : _a.schemas;
|
||||
if (schemas != null) {
|
||||
ps.push(codegenSchemas(schemas, config, gCP(config.schemasName)));
|
||||
}
|
||||
// return
|
||||
return Promise.all(ps);
|
||||
}
|
||||
exports.default = codegen;
|
2
dist/index.d.ts
vendored
Normal file
2
dist/index.d.ts
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
export { default as codegen } from './codegen';
|
||||
export * from './Config';
|
8
dist/index.js
vendored
Normal file
8
dist/index.js
vendored
Normal file
|
@ -0,0 +1,8 @@
|
|||
"use strict";
|
||||
function __export(m) {
|
||||
for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
|
||||
}
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
var codegen_1 = require("./codegen");
|
||||
exports.codegen = codegen_1.default;
|
||||
__export(require("./Config"));
|
13
dist/utils/APIPromise.d.ts
vendored
Normal file
13
dist/utils/APIPromise.d.ts
vendored
Normal file
|
@ -0,0 +1,13 @@
|
|||
import { AxiosResponse } from 'axios';
|
||||
declare type Optional<T> = T | undefined | null;
|
||||
declare type TPromiseOn<T, R> = Optional<(_: T) => R | PromiseLike<R>>;
|
||||
export declare abstract class APIPromise<T> implements PromiseLike<T> {
|
||||
promise: Promise<T>;
|
||||
constructor(req: Promise<AxiosResponse<any>>);
|
||||
then<T1 = T, T2 = never>(onRsv?: TPromiseOn<T, T1>, onRjt?: TPromiseOn<any, T2>): Promise<T1 | T2>;
|
||||
catch<T2>(onRjt: TPromiseOn<any, T2>): Promise<T | T2>;
|
||||
abstract onResponse(res: AxiosResponse<any>): T;
|
||||
onSuccess<U, V>(f: Optional<(x: U) => V>, v: U): U | V;
|
||||
onFail<U, V>(f: Optional<(x: U) => V>, v: U): V;
|
||||
}
|
||||
export {};
|
61
dist/utils/APIPromise.js
vendored
Normal file
61
dist/utils/APIPromise.js
vendored
Normal file
|
@ -0,0 +1,61 @@
|
|||
"use strict";
|
||||
var __extends = (this && this.__extends) || (function () {
|
||||
var extendStatics = function (d, b) {
|
||||
extendStatics = Object.setPrototypeOf ||
|
||||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
||||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
|
||||
return extendStatics(d, b);
|
||||
};
|
||||
return function (d, b) {
|
||||
extendStatics(d, b);
|
||||
function __() { this.constructor = d; }
|
||||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
||||
};
|
||||
})();
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
var BadResponseError = /** @class */ (function (_super) {
|
||||
__extends(BadResponseError, _super);
|
||||
function BadResponseError(err, res) {
|
||||
var _this = _super.call(this, err.toString()) || this;
|
||||
_this.err = err;
|
||||
_this.res = res;
|
||||
Object.setPrototypeOf(_this, BadResponseError.prototype);
|
||||
return _this;
|
||||
}
|
||||
return BadResponseError;
|
||||
}(Error));
|
||||
var APIPromise = /** @class */ (function () {
|
||||
function APIPromise(req) {
|
||||
var _this = this;
|
||||
this.promise = new Promise(function (rsv, rjt) {
|
||||
req.then(function (res) {
|
||||
try {
|
||||
rsv(_this.onResponse(res));
|
||||
}
|
||||
catch (err) {
|
||||
rjt(new BadResponseError(err, res));
|
||||
}
|
||||
}).catch(function (err) { return rjt(err); });
|
||||
});
|
||||
}
|
||||
APIPromise.prototype.then = function (onRsv, onRjt) {
|
||||
return this.promise.then(onRsv, onRjt);
|
||||
};
|
||||
APIPromise.prototype.catch = function (onRjt) {
|
||||
return this.then(undefined, onRjt);
|
||||
};
|
||||
APIPromise.prototype.onSuccess = function (f, v) {
|
||||
if (f)
|
||||
return f(v);
|
||||
else
|
||||
return v;
|
||||
};
|
||||
APIPromise.prototype.onFail = function (f, v) {
|
||||
if (f)
|
||||
return f(v);
|
||||
else
|
||||
throw new Error();
|
||||
};
|
||||
return APIPromise;
|
||||
}());
|
||||
exports.APIPromise = APIPromise;
|
10
dist/utils/FullDate.d.ts
vendored
Normal file
10
dist/utils/FullDate.d.ts
vendored
Normal file
|
@ -0,0 +1,10 @@
|
|||
export declare class FullDate {
|
||||
private date;
|
||||
constructor(...argv: any);
|
||||
toString(): string;
|
||||
toJSON(): string;
|
||||
valueOf(): number;
|
||||
getFullYear(): number;
|
||||
getMonth(): number;
|
||||
getDate(): number;
|
||||
}
|
53
dist/utils/FullDate.js
vendored
Normal file
53
dist/utils/FullDate.js
vendored
Normal file
|
@ -0,0 +1,53 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
var FullDate = /** @class */ (function () {
|
||||
function FullDate() {
|
||||
var argv = [];
|
||||
for (var _i = 0; _i < arguments.length; _i++) {
|
||||
argv[_i] = arguments[_i];
|
||||
}
|
||||
this.date = (function () {
|
||||
var _a;
|
||||
if (argv.length == 1) {
|
||||
var arg = argv[0];
|
||||
if (arg instanceof FullDate)
|
||||
return new Date(+arg);
|
||||
if (arg instanceof Date)
|
||||
return arg;
|
||||
if (typeof arg === 'string') {
|
||||
var tokens = (_a = /^(\d+)-(\d+)-(\d+)$/g.exec(arg)) === null || _a === void 0 ? void 0 : _a.slice(1, 4);
|
||||
if (tokens)
|
||||
return new Date(+tokens[0], +tokens[1] - 1, +tokens[2]);
|
||||
}
|
||||
return new Date(arg);
|
||||
}
|
||||
else if (argv.length == 3) {
|
||||
return new Date(argv[0], argv[1] - 1, argv[2]);
|
||||
}
|
||||
return new Date();
|
||||
})();
|
||||
}
|
||||
FullDate.prototype.toString = function () {
|
||||
var d = this.date;
|
||||
var f = function (s) { return ('0' + s).slice(-2); };
|
||||
return d.getFullYear() + "-" + f(d.getMonth() + 1) + "-" + f(d.getDate());
|
||||
};
|
||||
FullDate.prototype.toJSON = function () {
|
||||
return this.toString();
|
||||
};
|
||||
FullDate.prototype.valueOf = function () {
|
||||
return new Date(this.date).setHours(0, 0, 0, 0);
|
||||
};
|
||||
// prop
|
||||
FullDate.prototype.getFullYear = function () {
|
||||
return this.date.getFullYear();
|
||||
};
|
||||
FullDate.prototype.getMonth = function () {
|
||||
return this.date.getMonth() + 1;
|
||||
};
|
||||
FullDate.prototype.getDate = function () {
|
||||
return this.date.getDate();
|
||||
};
|
||||
return FullDate;
|
||||
}());
|
||||
exports.FullDate = FullDate;
|
18
dist/utils/StrictTypeParser.d.ts
vendored
Normal file
18
dist/utils/StrictTypeParser.d.ts
vendored
Normal file
|
@ -0,0 +1,18 @@
|
|||
import { FullDate } from './FullDate';
|
||||
export declare module StrictTypeParser {
|
||||
class BadValueError extends Error {
|
||||
attr: string;
|
||||
type: string;
|
||||
value: any;
|
||||
constructor(attr: string, type: string, value: any);
|
||||
}
|
||||
function _number(x: any, attr: string): number;
|
||||
function _string(x: any, attr: string): string;
|
||||
function _boolean(x: any, attr: string): boolean;
|
||||
function _Date(x: any, attr: string): Date;
|
||||
function _FullDate(x: any, attr: string): FullDate;
|
||||
function _byte(x: any, attr: string): string;
|
||||
function _binary(x: any, attr: string): string;
|
||||
function _Array(x: any, attr: string): Array<any>;
|
||||
const supportTypes: string[];
|
||||
}
|
104
dist/utils/StrictTypeParser.js
vendored
Normal file
104
dist/utils/StrictTypeParser.js
vendored
Normal file
|
@ -0,0 +1,104 @@
|
|||
"use strict";
|
||||
var __extends = (this && this.__extends) || (function () {
|
||||
var extendStatics = function (d, b) {
|
||||
extendStatics = Object.setPrototypeOf ||
|
||||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
||||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
|
||||
return extendStatics(d, b);
|
||||
};
|
||||
return function (d, b) {
|
||||
extendStatics(d, b);
|
||||
function __() { this.constructor = d; }
|
||||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
||||
};
|
||||
})();
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
var FullDate_1 = require("./FullDate");
|
||||
var StrictTypeParser;
|
||||
(function (StrictTypeParser) {
|
||||
var BadValueError = /** @class */ (function (_super) {
|
||||
__extends(BadValueError, _super);
|
||||
function BadValueError(attr, type, value) {
|
||||
var _this = _super.call(this, attr + ": Can not convert `" + (['object', 'array'].includes(typeof value) ?
|
||||
JSON.stringify(value) : "" + value) + "` to type " + type) || this;
|
||||
_this.attr = attr;
|
||||
_this.type = type;
|
||||
_this.value = value;
|
||||
console.error(_this.message);
|
||||
Object.setPrototypeOf(_this, BadValueError.prototype);
|
||||
return _this;
|
||||
}
|
||||
return BadValueError;
|
||||
}(Error));
|
||||
StrictTypeParser.BadValueError = BadValueError;
|
||||
function _number(x, attr) {
|
||||
if (typeof x === 'number')
|
||||
return x;
|
||||
if (typeof x === 'string') {
|
||||
var r = +x;
|
||||
if (!isNaN(r))
|
||||
return r;
|
||||
}
|
||||
throw new BadValueError(attr, 'number', x);
|
||||
}
|
||||
StrictTypeParser._number = _number;
|
||||
function _string(x, attr) {
|
||||
if (typeof x === 'string')
|
||||
return x;
|
||||
if (typeof x === 'object')
|
||||
return x.toString();
|
||||
throw new BadValueError(attr, 'string', x);
|
||||
}
|
||||
StrictTypeParser._string = _string;
|
||||
function _boolean(x, attr) {
|
||||
if (typeof x === 'boolean')
|
||||
return x;
|
||||
if (x === 'true')
|
||||
return true;
|
||||
if (x === 'false')
|
||||
return false;
|
||||
throw new BadValueError(attr, 'boolean', x);
|
||||
}
|
||||
StrictTypeParser._boolean = _boolean;
|
||||
function _Date(x, attr) {
|
||||
var r = new Date(x);
|
||||
if (!isNaN(+r))
|
||||
return r;
|
||||
throw new BadValueError(attr, 'Date', x);
|
||||
}
|
||||
StrictTypeParser._Date = _Date;
|
||||
function _FullDate(x, attr) {
|
||||
var r = new FullDate_1.FullDate(x);
|
||||
if (!isNaN(+r))
|
||||
return r;
|
||||
throw new BadValueError(attr, 'FullDate', x);
|
||||
}
|
||||
StrictTypeParser._FullDate = _FullDate;
|
||||
function _byte(x, attr) {
|
||||
if (typeof x === 'string')
|
||||
return x;
|
||||
if (x instanceof Buffer)
|
||||
return x.toString('base64');
|
||||
throw new BadValueError(attr, 'byte', x);
|
||||
}
|
||||
StrictTypeParser._byte = _byte;
|
||||
function _binary(x, attr) {
|
||||
if (typeof x === 'string')
|
||||
return x;
|
||||
if (x instanceof Buffer)
|
||||
return x.toString('hex');
|
||||
if ((x === null || x === void 0 ? void 0 : x.buffer) instanceof Buffer)
|
||||
return x.toString('hex');
|
||||
throw new BadValueError(attr, 'binary', x);
|
||||
}
|
||||
StrictTypeParser._binary = _binary;
|
||||
function _Array(x, attr) {
|
||||
if (x instanceof Array)
|
||||
return x;
|
||||
throw new BadValueError(attr, 'Array', x);
|
||||
}
|
||||
StrictTypeParser._Array = _Array;
|
||||
StrictTypeParser.supportTypes = [
|
||||
'number', 'string', 'boolean', 'Date', 'FullDate', 'byte', 'binary'
|
||||
];
|
||||
})(StrictTypeParser = exports.StrictTypeParser || (exports.StrictTypeParser = {}));
|
3
dist/utils/index.d.ts
vendored
Normal file
3
dist/utils/index.d.ts
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
export * from './APIPromise';
|
||||
export * from './FullDate';
|
||||
export * from './StrictTypeParser';
|
8
dist/utils/index.js
vendored
Normal file
8
dist/utils/index.js
vendored
Normal file
|
@ -0,0 +1,8 @@
|
|||
"use strict";
|
||||
function __export(m) {
|
||||
for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
|
||||
}
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
__export(require("./APIPromise"));
|
||||
__export(require("./FullDate"));
|
||||
__export(require("./StrictTypeParser"));
|
42
lib/CodePrinter.ts
Normal file
42
lib/CodePrinter.ts
Normal file
|
@ -0,0 +1,42 @@
|
|||
interface WriteStream {
|
||||
write(s: string): void;
|
||||
on(s: string, callback: () => void): void;
|
||||
end(): void;
|
||||
}
|
||||
|
||||
export class StringStream implements WriteStream {
|
||||
private content = ''
|
||||
write(s: string) {
|
||||
this.content += s;
|
||||
}
|
||||
on() {}
|
||||
end() {}
|
||||
toString(): string {
|
||||
return this.content;
|
||||
}
|
||||
}
|
||||
|
||||
export class CodePrinter {
|
||||
private cIndent = 0;
|
||||
constructor(
|
||||
private writeStream: WriteStream = new StringStream(),
|
||||
private indentString: string = ' ',
|
||||
) {}
|
||||
writeln(s: string = '', dIndent: number = 0) {
|
||||
if (dIndent < 0) this.cIndent = Math.max(0, this.cIndent + dIndent);
|
||||
this.write(`${this.indentString.repeat(this.cIndent) + s}\n`);
|
||||
if (dIndent > 0) this.cIndent += dIndent;
|
||||
}
|
||||
write(s: string) {
|
||||
this.writeStream.write(s);
|
||||
}
|
||||
tab(x: number) {
|
||||
this.cIndent += x;
|
||||
}
|
||||
end(): Promise<void> {
|
||||
return new Promise(rsv => {
|
||||
this.writeStream.on('finish', rsv);
|
||||
this.writeStream.end();
|
||||
});
|
||||
}
|
||||
}
|
46
lib/Config.ts
Normal file
46
lib/Config.ts
Normal file
|
@ -0,0 +1,46 @@
|
|||
export type Config = ConfigRequired & ConfigOptional;
|
||||
export type ConfigUser = ConfigRequired & Partial<ConfigOptional>;
|
||||
export interface ConfigRequired {
|
||||
}
|
||||
export interface ConfigOptional {
|
||||
// format
|
||||
interfacePrefix: string;
|
||||
indentString: string;
|
||||
responsePrefix: string;
|
||||
// name
|
||||
schemasName: string;
|
||||
IHandlerName: string;
|
||||
IServerAPIName: string;
|
||||
IClientAPIName: string;
|
||||
ClientAPIName: string;
|
||||
routerName: string;
|
||||
// TS path
|
||||
apiDirTSPath: string;
|
||||
ServerAPITSPath: string;
|
||||
utilsTSPath: string;
|
||||
stateTSPath: string | null;
|
||||
// other
|
||||
outputDir: string;
|
||||
validateStatus: (status: string) => boolean;
|
||||
}
|
||||
export const configDefault: ConfigOptional = {
|
||||
// format
|
||||
interfacePrefix: 'I',
|
||||
indentString: ' ',
|
||||
responsePrefix: '',
|
||||
// name
|
||||
schemasName: 'schemas',
|
||||
IHandlerName: 'IHandler',
|
||||
IServerAPIName: 'IServerAPI',
|
||||
IClientAPIName: 'IClientAPI',
|
||||
ClientAPIName: 'ClientAPI',
|
||||
routerName: 'apiRouter',
|
||||
// TS path
|
||||
apiDirTSPath: '#api',
|
||||
ServerAPITSPath: '#ServerAPI',
|
||||
utilsTSPath: 'api-codegen-ts/utils',
|
||||
stateTSPath: null,
|
||||
// other
|
||||
outputDir: 'api/generated',
|
||||
validateStatus: (status: string) => /^2..$/.test(status),
|
||||
};
|
284
lib/OpenAPI.ts
Normal file
284
lib/OpenAPI.ts
Normal file
|
@ -0,0 +1,284 @@
|
|||
import {StrictTypeParser as STP} from './utils/StrictTypeParser';
|
||||
const warn = (x: any) => console.warn('\x1b[1;33mWarning: '+x+'\x1b[0m');
|
||||
|
||||
/* ==== type declaration ==== */
|
||||
export interface OpenAPI {
|
||||
paths: Paths;
|
||||
components?: Components;
|
||||
}
|
||||
|
||||
// path
|
||||
interface Paths {
|
||||
[path: string]: PathItem
|
||||
}
|
||||
interface PathItem {
|
||||
get?: Operation;
|
||||
put?: Operation;
|
||||
post?: Operation;
|
||||
delete?: Operation;
|
||||
patch?: Operation;
|
||||
[_: string]: any;
|
||||
}
|
||||
type EMethod = 'get' | 'put' | 'post' | 'delete' | 'patch';
|
||||
const ELMethod: Array<EMethod> = ['get', 'put', 'post', 'delete', 'patch'];
|
||||
interface Operation {
|
||||
responses: Responses;
|
||||
parameters?: Parameter[];
|
||||
requestBody?: RequestBody;
|
||||
operationId?: string;
|
||||
}
|
||||
|
||||
// response
|
||||
interface Responses {
|
||||
[status: string]: Response // | Reference;
|
||||
}
|
||||
interface Response {
|
||||
// headers?: Header;
|
||||
content?: TMediaTypes;
|
||||
}
|
||||
type TMediaTypes = {[contentType: string]: MediaType};
|
||||
interface MediaType {
|
||||
schema?: Schema | Reference;
|
||||
example?: any;
|
||||
examples?: {[_: string]: object};
|
||||
}
|
||||
|
||||
// parameter
|
||||
interface Parameter {
|
||||
name: string;
|
||||
in: EParameterIn;
|
||||
description?: string;
|
||||
required?: boolean;
|
||||
deprecated?: boolean;
|
||||
style?: string;
|
||||
schema?: Schema | Reference;
|
||||
}
|
||||
type EParameterIn = 'query' | 'header' | 'path' | 'cookie';
|
||||
export const ELParameterIn: Array<EParameterIn> = [
|
||||
'path', 'query', 'header', 'cookie'];
|
||||
|
||||
// request body
|
||||
interface RequestBody {
|
||||
description: string;
|
||||
content: {[contentType: string]: MediaType};
|
||||
required?: boolean;
|
||||
}
|
||||
|
||||
// components
|
||||
interface Components {
|
||||
schemas: {[_: string]: Schema | Reference};
|
||||
}
|
||||
|
||||
// schemeType
|
||||
export type Schemas = {[_: string]: Schema | Reference};
|
||||
interface Schema {
|
||||
type: string;
|
||||
format?: string;
|
||||
nullable?: boolean;
|
||||
readOnly?: boolean;
|
||||
maxSize?: number;
|
||||
}
|
||||
interface ArraySchema extends Schema {
|
||||
items: Schema | Reference;
|
||||
}
|
||||
export function isArraySchema(x: any): x is ArraySchema {
|
||||
return x.type === 'array';
|
||||
}
|
||||
interface ObjectSchema extends Schema {
|
||||
properties: {[name: string]: Schema | Reference};
|
||||
}
|
||||
export function isObjectSchema(x: any): x is ObjectSchema {
|
||||
return x.type === 'object';
|
||||
}
|
||||
interface Reference {
|
||||
$ref: string;
|
||||
maxSize?: string | number;
|
||||
}
|
||||
function isReference(x: any): x is Reference {
|
||||
return typeof x.$ref === 'string';
|
||||
}
|
||||
|
||||
// api
|
||||
class APIFunction {
|
||||
constructor(
|
||||
public method: string,
|
||||
public url: string,
|
||||
public reqTypes: TReqTypes,
|
||||
public resTypes: TResTypes,
|
||||
) {}
|
||||
}
|
||||
type TReqTypes = {
|
||||
query?: {[name: string]: SchemaType};
|
||||
header?: {[name: string]: SchemaType};
|
||||
path?: {[name: string]: SchemaType};
|
||||
cookie?: {[name: string]: SchemaType};
|
||||
body?: SchemaType;
|
||||
};
|
||||
type TResTypes = {[status: string]: SchemaType};
|
||||
/* ==== ==== */
|
||||
|
||||
function mediaTypes2type(content?: TMediaTypes, required?: boolean):
|
||||
SchemaType {
|
||||
const media = content?.['application/json']; // TODO
|
||||
if (media == null) {
|
||||
if (Object.keys(content ?? {}).length > 0) {
|
||||
warn('only support application/json now');
|
||||
}
|
||||
return new SchemaType('any', false);
|
||||
}
|
||||
// schema
|
||||
const {schema} = media;
|
||||
return new SchemaType(schema ?? 'any', required ?? false);
|
||||
}
|
||||
export class SchemaType {
|
||||
private _typeName?: string;
|
||||
get typeName(): string {
|
||||
return this._typeName ??
|
||||
(this._typeName = SchemaType.typeNameOf(this.schema));
|
||||
}
|
||||
get required(): boolean {
|
||||
return this._required;
|
||||
}
|
||||
get maxSize(): string | number | undefined {
|
||||
return this.schema.maxSize;
|
||||
}
|
||||
forProp(prop: string): string {
|
||||
return `${prop}${this.required ? '' : '?'}: ${this.typeName}`;
|
||||
}
|
||||
stp(prop: string): string {
|
||||
const stp = SchemaType.gcStp(prop, this.schema);
|
||||
return (this.required ? '' : `${prop}===undefined ? undefined : `)+stp;
|
||||
}
|
||||
|
||||
private schema: Schema | Reference;
|
||||
constructor(schema: Schema | Reference | string,
|
||||
private _required: boolean) {
|
||||
this.schema = typeof schema === 'string' ? {type: schema} : schema;
|
||||
}
|
||||
|
||||
static typeNameOf(schema: Schema | Reference): string {
|
||||
if (isReference(schema)) {
|
||||
const {$ref} = schema;
|
||||
const typeName = /^#\/components\/schemas\/(\w+)$/g.exec($ref)?.[1];
|
||||
if (typeName == null) {
|
||||
warn(`Invalid $ref, use any instead: ${$ref}`);
|
||||
return 'any';
|
||||
}
|
||||
return `Schemas.${typeName}`;
|
||||
}
|
||||
const {
|
||||
type, format, nullable, readOnly,
|
||||
} = schema;
|
||||
let sType = type;
|
||||
if (isArraySchema(schema)) {
|
||||
sType = `Array<${SchemaType.typeNameOf(schema.items)}>`;
|
||||
} else if (isObjectSchema(schema)) {
|
||||
sType = '{';
|
||||
for (const [name, sub] of Object.entries(schema.properties)) {
|
||||
sType += `${name}: ${SchemaType.typeNameOf(sub)}, `;
|
||||
}
|
||||
sType += '}';
|
||||
} else if (type === 'string') {
|
||||
if (format === 'date-time') sType = 'Date';
|
||||
else if (format === 'date') sType = 'FullDate';
|
||||
else if (format === 'byte') sType = 'string'; // TODO Buffer
|
||||
else if (format === 'binary') sType = 'string'; // TODO Buffer
|
||||
else if (format) warn(`Unknown format ${format}, use string instead`);
|
||||
} else if (type === 'integer') sType = 'number'; // TODO integer
|
||||
if (nullable) sType = `${sType} | null`;
|
||||
if (readOnly) sType = `Readonly<${sType}>`;
|
||||
return sType;
|
||||
}
|
||||
static gcStp(para: string, schema: Schema | Reference): string {
|
||||
const sPara = `'${para.replace(/'/g, '\\\'')}'`;
|
||||
// object
|
||||
if (isReference(schema)) {
|
||||
return `new ${new SchemaType(schema, true).typeName}(${para})`;
|
||||
}
|
||||
// any
|
||||
let code;
|
||||
const {type, nullable, format} = schema;
|
||||
if (type === 'any') return para;
|
||||
if (isArraySchema(schema)) {
|
||||
code = `STP._Array(${para}, ${sPara}).map(o=>${
|
||||
SchemaType.gcStp('o', schema.items)})`;
|
||||
} else if (isObjectSchema(schema)) {
|
||||
code = '{';
|
||||
for (const [name, sub] of Object.entries(schema.properties)) {
|
||||
code += `${name}: ${SchemaType.gcStp(para+'.'+name, sub)}, `;
|
||||
}
|
||||
code += '}';
|
||||
} else {
|
||||
let t;
|
||||
if (type === 'string') {
|
||||
if (format === 'date-time') t = 'Date';
|
||||
else if (format === 'date') t = 'FullDate';
|
||||
else if (format === 'byte') t = 'string'; // TODO
|
||||
else if (format === 'binary') t = 'string'; // TODO
|
||||
else {
|
||||
if (format) warn(`Unknown format ${format}, use string instead`);
|
||||
t = 'string';
|
||||
}
|
||||
} else if (type === 'integer') t = 'number';
|
||||
else t = type;
|
||||
if (!STP.supportTypes.includes(t)) {
|
||||
warn(`Unknown type ${type}, use any instead`);
|
||||
return para;
|
||||
} else code = `STP._${t}(${para}, ${sPara})`;
|
||||
}
|
||||
// nullable
|
||||
if (nullable) code = `${para}===null ? null : ${code}`;
|
||||
return code;
|
||||
}
|
||||
}
|
||||
|
||||
export type APIFunctions = {[_: string]: APIFunction};
|
||||
export function apiFunctionsOf(openAPI: OpenAPI): APIFunctions {
|
||||
const {paths} = openAPI;
|
||||
const functions: APIFunctions = {};
|
||||
for (const [url, pathItem] of Object.entries(paths)) {
|
||||
for (const method of ELMethod) {
|
||||
const op = pathItem[method];
|
||||
if (op == null) continue;
|
||||
// operationId
|
||||
const {
|
||||
operationId, parameters, requestBody, responses,
|
||||
} = op;
|
||||
if (operationId == null) {
|
||||
warn(`ignore operation in ${method} ${url}: ` +
|
||||
'operationId should be given');
|
||||
continue;
|
||||
}
|
||||
const name = operationId;
|
||||
const reqTypes: TReqTypes = {};
|
||||
const resTypes: TResTypes = {};
|
||||
// reqParas
|
||||
if (parameters != null) {
|
||||
for (const para of parameters) {
|
||||
const {
|
||||
name, in: _in, required, schema,
|
||||
} = para;
|
||||
// add
|
||||
if (reqTypes[_in] == null) reqTypes[_in] = {};
|
||||
reqTypes[_in]![name] = new SchemaType(
|
||||
schema ?? 'any', required ?? false);
|
||||
}
|
||||
}
|
||||
// requestBody
|
||||
if (requestBody != null) {
|
||||
reqTypes.body = mediaTypes2type(
|
||||
requestBody.content,
|
||||
requestBody.required,
|
||||
);
|
||||
}
|
||||
// responses
|
||||
for (const [status, res] of Object.entries(responses)) {
|
||||
resTypes[status] = mediaTypes2type(res.content, true);
|
||||
}
|
||||
// add to group
|
||||
const saf = new APIFunction(method, url, reqTypes, resTypes);
|
||||
functions[name] = saf;
|
||||
}
|
||||
}
|
||||
return functions;
|
||||
}
|
369
lib/codegen.ts
Normal file
369
lib/codegen.ts
Normal file
|
@ -0,0 +1,369 @@
|
|||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
import {Config, ConfigUser, configDefault} from './Config';
|
||||
import {
|
||||
apiFunctionsOf, OpenAPI, APIFunctions as APIFuncs,
|
||||
ELParameterIn, SchemaType, Schemas, isObjectSchema,
|
||||
} from './OpenAPI';
|
||||
import {CodePrinter} from './CodePrinter';
|
||||
|
||||
function codegenIServerAPI(funcs: APIFuncs, config: Config, cp: CodePrinter) {
|
||||
const {apiDirTSPath, IHandlerName} = config;
|
||||
// import
|
||||
cp.writeln(`import * as IHandler from '${apiDirTSPath}/${IHandlerName}'`);
|
||||
// export default
|
||||
cp.writeln('\nexport default interface IAPI {', 1);
|
||||
for (const funcName of Object.keys(funcs)) {
|
||||
cp.writeln(
|
||||
`${funcName}: IHandler.${funcName}.IServerHandler;`,
|
||||
);
|
||||
}
|
||||
cp.writeln('};', -1);
|
||||
return cp.end();
|
||||
}
|
||||
|
||||
function codegenIHandler(funcs: APIFuncs, config: Config, cp: CodePrinter) {
|
||||
const {
|
||||
apiDirTSPath, schemasName, utilsTSPath,
|
||||
responsePrefix, validateStatus, stateTSPath,
|
||||
} = config;
|
||||
// import
|
||||
cp.writeln(`import * as Schemas from '${apiDirTSPath}/${schemasName}'`);
|
||||
cp.writeln('import {FullDate, StrictTypeParser as STP, APIPromise} ' +
|
||||
`from '${utilsTSPath}'`);
|
||||
cp.writeln('import {RouterContext as Context} from \'@koa/router\'');
|
||||
cp.writeln('import {AxiosResponse} from \'axios\'');
|
||||
cp.writeln(stateTSPath ?
|
||||
`import IState from '${stateTSPath}'` : 'type IState = any');
|
||||
// handler types
|
||||
for (const [funcName, func] of Object.entries(funcs)) {
|
||||
const {reqTypes, resTypes, method} = func;
|
||||
cp.writeln(`export namespace ${funcName} {`, 1);
|
||||
// req
|
||||
const sReqTypes: string[] = [];
|
||||
// paras
|
||||
for (const _in of ELParameterIn) {
|
||||
const paras = reqTypes[_in];
|
||||
if (paras == null) continue;
|
||||
cp.writeln(`export type T_${_in} = {`, 1);
|
||||
for (const [propName, schemaType] of Object.entries(paras)) {
|
||||
cp.writeln(schemaType.forProp(propName)+';');
|
||||
}
|
||||
cp.writeln('};', -1);
|
||||
sReqTypes.push(`${_in}: T_${_in}`);
|
||||
}
|
||||
// body
|
||||
const {body} = reqTypes;
|
||||
if (body != null) {
|
||||
// PATCH's req body: Partial
|
||||
let {typeName} = body;
|
||||
if (method == 'patch') typeName = `Partial<${typeName}>`;
|
||||
cp.writeln(`export type T_body = ${typeName};`);
|
||||
sReqTypes.push(`body${body.required ? '' : '?'}: T_body`);
|
||||
}
|
||||
// IRequest
|
||||
if (sReqTypes.length > 0) {
|
||||
cp.writeln('interface IRequest {', 1);
|
||||
for (const sReqType of sReqTypes) cp.writeln(`${sReqType};`);
|
||||
cp.writeln('}', -1);
|
||||
} else cp.writeln('interface IRequest {}');
|
||||
// res
|
||||
cp.writeln('interface IResponses<T> {', 1);
|
||||
for (const [status, schema] of Object.entries(resTypes)) {
|
||||
cp.writeln(`${responsePrefix}${status}: ${
|
||||
`(${schema.forProp('body')}) => T;`
|
||||
}`);
|
||||
}
|
||||
cp.writeln('}', -1);
|
||||
cp.writeln('export interface IServerHandler {', 1);
|
||||
cp.writeln('(req: IRequest, res: IResponses<void>, ' +
|
||||
'state: IState, ctx: Context): void;');
|
||||
cp.writeln('}', -1);
|
||||
// class _ResponsePromise
|
||||
const validTypes = new Set<string>();
|
||||
cp.writeln('export class ResponsePromise<T> extends ' +
|
||||
'APIPromise<T|T_ValidResponse> {', 1);
|
||||
// handler
|
||||
cp.writeln('private handlers: Partial<IResponses<T>> = {};');
|
||||
// on
|
||||
cp.writeln('on<K extends keyof IResponses<T>, U>(', 1);
|
||||
cp.writeln('k: K, h: IResponses<U>[K]): ResponsePromise<T|U>');
|
||||
cp.tab(-1);
|
||||
cp.writeln('{ const e: ResponsePromise<T|U> = this; ' +
|
||||
'e.handlers[k] = h; return e; }');
|
||||
// onResponse
|
||||
cp.writeln('onResponse(res: AxiosResponse<any>){', 1);
|
||||
cp.writeln('const {status, data} = res');
|
||||
cp.writeln('switch(status){', 1);
|
||||
for (const [status, schema] of Object.entries(resTypes)) {
|
||||
// TODO void -> string or any
|
||||
const isValid = validateStatus(status);
|
||||
cp.writeln(`case ${status}: return this.${
|
||||
isValid ? 'onSuccess' : 'onFail'
|
||||
}(this.handlers[${status}],`, 1);
|
||||
cp.writeln(`${schema.stp('data')});`);
|
||||
cp.tab(-1);
|
||||
if (isValid) validTypes.add(schema.typeName);
|
||||
}
|
||||
cp.writeln('}', -1); // end switch
|
||||
cp.writeln('throw new Error(\'Unexpect status code: \'+status);');
|
||||
cp.writeln('}', -1); // end onResponse
|
||||
cp.writeln('}', -1); // end class
|
||||
// valid type
|
||||
const sValidTypes = Array.from(validTypes.values()).join(' | ');
|
||||
cp.writeln(`export type T_ValidResponse = ${sValidTypes};`);
|
||||
// export client handler
|
||||
cp.writeln('export interface IClientHandler {', 1);
|
||||
cp.writeln(`(${sReqTypes.join(', ')}): ResponsePromise<never>;`);
|
||||
cp.writeln('}', -1); // end client handler
|
||||
cp.writeln('}', -1); // end namespace
|
||||
}
|
||||
return cp.end();
|
||||
}
|
||||
function codegenRouter(funcs: APIFuncs, config: Config, cp: CodePrinter) {
|
||||
const {
|
||||
apiDirTSPath, schemasName, responsePrefix,
|
||||
ServerAPITSPath, utilsTSPath, stateTSPath,
|
||||
} = config;
|
||||
// import
|
||||
cp.writeln(`import * as Schemas from '${apiDirTSPath}/${schemasName}'`);
|
||||
cp.writeln(`import * as Router from '@koa/router'`);
|
||||
cp.writeln(
|
||||
`import {FullDate, StrictTypeParser as STP} from '${utilsTSPath}'`);
|
||||
cp.writeln(`import * as bodyParser from 'koa-body'`);
|
||||
cp.writeln(stateTSPath ?
|
||||
`import IState from '${stateTSPath}'` : 'type IState = any');
|
||||
cp.writeln(`type CTX = Router.RouterContext<IState>;`);
|
||||
// router
|
||||
cp.writeln(`\nconst router = new Router<IState>();`);
|
||||
cp.writeln('');
|
||||
// function
|
||||
cp.writeln('function isEmpty(x: any): boolean {', 1);
|
||||
cp.writeln('if(x == null || x === \'\') return true;');
|
||||
cp.writeln('if(typeof x === \'object\') return Object.keys(x).length===0');
|
||||
cp.writeln('return false;');
|
||||
cp.writeln('}', -1);
|
||||
cp.writeln('function nullableParse<T>(v: any, ' +
|
||||
'p: (x: any)=>T): T | undefined {', 1);
|
||||
cp.writeln('return isEmpty(v) ? undefined : p(v);');
|
||||
cp.writeln('}', -1);
|
||||
cp.writeln('const ctxGetParas = {', 1);
|
||||
cp.writeln('path: (ctx: CTX, attr: string) => ctx.params[attr],');
|
||||
cp.writeln('query: (ctx: CTX, attr: string) => ctx.query[attr],');
|
||||
cp.writeln('header: (ctx: CTX, attr: string) => ctx.headers[attr],');
|
||||
cp.writeln('cookie: (ctx: CTX, attr: string) => ctx.cookies.get(attr),');
|
||||
cp.writeln('};', -1);
|
||||
// response generator
|
||||
cp.writeln('function g_res<T>(ctx: CTX, ' +
|
||||
'status: number, dft: string = \'\'){', 1);
|
||||
cp.writeln('return (body: T) => {', 1);
|
||||
cp.writeln('ctx.status = status;');
|
||||
cp.writeln('ctx.body = body ?? dft;');
|
||||
cp.writeln('}', -1);
|
||||
cp.writeln('}', -1);
|
||||
// route
|
||||
cp.writeln(`\nimport api from '${ServerAPITSPath}'`);
|
||||
for (const [funcName, func] of Object.entries(funcs)) {
|
||||
const {
|
||||
method, url, reqTypes, resTypes,
|
||||
} = func;
|
||||
const statuses = Object.keys(resTypes);
|
||||
// TODO escape
|
||||
const sURL = url.replace(/{(.*?)}/g, ':$1'); // {a} -> :a
|
||||
let mid = '';
|
||||
if (reqTypes.body) {
|
||||
const {maxSize} = reqTypes.body;
|
||||
const config = maxSize == null ? '' : `{jsonLimit: '${maxSize}'}`;
|
||||
mid = `bodyParser(${config}), `;
|
||||
}
|
||||
cp.writeln(`router.${method}('${sURL}', ${mid}async ctx => {`, 1);
|
||||
// TODO permission check, etc
|
||||
if (Object.keys(reqTypes).length === 0) {
|
||||
cp.writeln('const req = {};');
|
||||
} else {
|
||||
cp.writeln('let req;');
|
||||
cp.writeln('const {body: reqBody} = ctx.request;');
|
||||
cp.writeln('try { req = {', 1);
|
||||
// paras
|
||||
for (const _in of ELParameterIn) {
|
||||
const paras = reqTypes[_in];
|
||||
if (paras == null) continue;
|
||||
cp.writeln(`${_in}: {`, 1);
|
||||
for (const [name, schema] of Object.entries(paras)) {
|
||||
const pn = `ctxGetParas.${_in}(ctx, '${name}')`;
|
||||
cp.writeln(`${name}: ${schema.stp(pn)},`);
|
||||
}
|
||||
cp.writeln('},', -1);
|
||||
}
|
||||
// body
|
||||
const {body} = reqTypes;
|
||||
if (body != null) {
|
||||
const name = 'body';
|
||||
const pn = 'reqBody';
|
||||
cp.writeln(`${name}: ${body.stp(pn)}`);
|
||||
}
|
||||
cp.writeln('}} catch(err) {', -1); cp.tab(1);
|
||||
cp.writeln('if(err instanceof STP.BadValueError)', 1);
|
||||
cp.writeln('return ctx.throw(400, err.toString());'); cp.tab(-1);
|
||||
cp.writeln('throw err;');
|
||||
cp.writeln('}', -1);
|
||||
}
|
||||
// res
|
||||
cp.writeln('const res = {', 1);
|
||||
for (const status of statuses) {
|
||||
cp.writeln(`${responsePrefix}${status}: g_res(ctx, ${status}),`);
|
||||
}
|
||||
cp.writeln('};', -1);
|
||||
// call
|
||||
cp.writeln(`await api.${funcName}(req, res, ctx.state, ctx);`);
|
||||
cp.writeln('})', -1);
|
||||
}
|
||||
cp.writeln('\nexport default router;');
|
||||
return cp.end();
|
||||
}
|
||||
|
||||
function codegenIClientAPI(funcs: APIFuncs, config: Config, cp: CodePrinter) {
|
||||
const {apiDirTSPath, IHandlerName} = config;
|
||||
// import
|
||||
cp.writeln(`import * as IHandler from '${apiDirTSPath}/${IHandlerName}'`);
|
||||
// export default
|
||||
cp.writeln('\nexport default interface IAPI {', 1);
|
||||
cp.writeln('$baseURL: string;');
|
||||
for (const funcName of Object.keys(funcs)) {
|
||||
cp.writeln(
|
||||
`${funcName}: IHandler.${funcName}.IClientHandler;`,
|
||||
);
|
||||
}
|
||||
cp.writeln('}', -1);
|
||||
return cp.end();
|
||||
}
|
||||
|
||||
function codegenClientAPI(funcs: APIFuncs, config: Config, cp: CodePrinter) {
|
||||
const {
|
||||
apiDirTSPath, IClientAPIName, IHandlerName,
|
||||
} = config;
|
||||
// import
|
||||
cp.writeln(`import * as _IAPI from '${apiDirTSPath}/${IClientAPIName}'`);
|
||||
cp.writeln(`import IAPI from '${apiDirTSPath}/${IClientAPIName}'`);
|
||||
cp.writeln(`import * as IHandler from '${apiDirTSPath}/${IHandlerName}'`);
|
||||
cp.writeln('import axios from \'axios\'');
|
||||
// axios
|
||||
cp.writeln('\nconst $http = axios.create({', 1);
|
||||
cp.writeln('validateStatus: ()=>true,');
|
||||
cp.writeln('});', -1);
|
||||
// function
|
||||
cp.writeln('\nfunction urlReplacer(url: string, ' +
|
||||
'rules: {[_: string]: any}): string {', 1);
|
||||
cp.writeln('for(const [attr, value] of Object.entries(rules))', 1);
|
||||
cp.writeln('url = url.replace(\'{\'+attr+\'}\', value)');
|
||||
cp.writeln('return url;', -1);
|
||||
cp.writeln('};', -1);
|
||||
// implementation
|
||||
// export default
|
||||
cp.writeln('\nexport default {', 1);
|
||||
// set $baseURL
|
||||
cp.writeln('set $baseURL(url: string) {', 1);
|
||||
cp.writeln('$http.interceptors.request.use(async config => {', 1);
|
||||
cp.writeln('config.baseURL = url;');
|
||||
cp.writeln('return config;', -1);
|
||||
cp.writeln('}, err => Promise.reject(err));', -1);
|
||||
cp.writeln('},');
|
||||
// functions
|
||||
for (const [funcName, func] of Object.entries(funcs)) {
|
||||
const ncHandler = `IHandler.${funcName}`;
|
||||
const {method, url, reqTypes} = func;
|
||||
const {
|
||||
query, header, path, body,
|
||||
} = reqTypes; // TODO cookie
|
||||
// name
|
||||
cp.writeln(`${funcName}(`, 1);
|
||||
// paras
|
||||
for (const _in of ELParameterIn) {
|
||||
const paras = reqTypes[_in];
|
||||
if (paras == null) continue;
|
||||
let _required = false;
|
||||
for (const {required} of Object.values(paras)) {
|
||||
if (required) {
|
||||
_required = true; break;
|
||||
}
|
||||
}
|
||||
cp.writeln(`${_in}: ${ncHandler}.T_${_in}${_required ? '' : '={}'},`);
|
||||
}
|
||||
// body
|
||||
if (body != null) {
|
||||
cp.writeln(`body${body.required ? '' : '?'}: ${ncHandler}.T_body,`);
|
||||
}
|
||||
// function body
|
||||
cp.tab(-1);
|
||||
cp.writeln(`){return new ${ncHandler}`+
|
||||
'.ResponsePromise<never>($http({', 1);
|
||||
cp.writeln(`method: '${method}',`);
|
||||
const sURL = `'${url}'`;
|
||||
cp.writeln(`url: ${path ? `urlReplacer(${sURL}, path)` : sURL},`);
|
||||
if (query) cp.writeln('params: query,');
|
||||
if (header) cp.writeln('header: header,');
|
||||
if (body != null) cp.writeln('data: body,');
|
||||
cp.writeln('}));},', -1);
|
||||
}
|
||||
cp.writeln('} as IAPI', -1);
|
||||
return cp.end();
|
||||
}
|
||||
|
||||
function codegenSchemas(schemas: Schemas, config: Config, cp: CodePrinter) {
|
||||
const {utilsTSPath} = config;
|
||||
// import
|
||||
cp.writeln(
|
||||
`import {FullDate, StrictTypeParser as STP} from '${utilsTSPath}'`);
|
||||
cp.writeln();
|
||||
// schema
|
||||
for (const [name, schema] of Object.entries(schemas)) {
|
||||
if (isObjectSchema(schema)) {
|
||||
cp.writeln(`export class ${name} {`, 1);
|
||||
const propTypes: [string, SchemaType][] = [];
|
||||
for (const [propName, prop] of Object.entries(schema.properties)) {
|
||||
const propType = new SchemaType(prop, true); // TODO required?
|
||||
propTypes.push([propName, propType]);
|
||||
cp.writeln(propType.forProp(propName)+';');
|
||||
}
|
||||
// method
|
||||
cp.writeln('constructor(o: {[_: string]: any}){', 1);
|
||||
for (const [n, t] of propTypes) {
|
||||
cp.writeln(`this.${n} = ${t.stp(`o.${n}`)};`);
|
||||
}
|
||||
cp.writeln('}', -1);
|
||||
cp.writeln('}', -1);
|
||||
} else {
|
||||
cp.writeln(`export type ${name} = ${SchemaType.typeNameOf(schema)}`);
|
||||
}
|
||||
}
|
||||
// return
|
||||
return cp.end();
|
||||
}
|
||||
|
||||
export default function codegen(openAPI: OpenAPI, configUser: ConfigUser) {
|
||||
const config: Config = Object.assign({}, configUser, configDefault);
|
||||
// prepare
|
||||
fs.mkdirSync(config.outputDir, {recursive: true});
|
||||
const apiFuncs = apiFunctionsOf(openAPI);
|
||||
const gCP = (fn: string) => new CodePrinter(
|
||||
fs.createWriteStream(path.join(config.outputDir, fn+'.ts')),
|
||||
config.indentString,
|
||||
);
|
||||
const ps: Promise<any>[] = [];
|
||||
// write files
|
||||
// handler
|
||||
ps.push(codegenIHandler(apiFuncs, config, gCP(config.IHandlerName)));
|
||||
// server
|
||||
ps.push(codegenIServerAPI(apiFuncs, config, gCP(config.IServerAPIName)));
|
||||
ps.push(codegenRouter(apiFuncs, config, gCP(config.routerName)));
|
||||
// client
|
||||
ps.push(codegenIClientAPI(apiFuncs, config, gCP(config.IClientAPIName)));
|
||||
ps.push(codegenClientAPI(apiFuncs, config, gCP(config.ClientAPIName)));
|
||||
// schema
|
||||
const schemas = openAPI.components?.schemas;
|
||||
if (schemas != null) {
|
||||
ps.push(codegenSchemas(schemas, config, gCP(config.schemasName)));
|
||||
}
|
||||
// return
|
||||
return Promise.all(ps);
|
||||
}
|
2
lib/index.ts
Normal file
2
lib/index.ts
Normal file
|
@ -0,0 +1,2 @@
|
|||
export {default as codegen} from './codegen';
|
||||
export * from './Config';
|
43
lib/utils/APIPromise.ts
Normal file
43
lib/utils/APIPromise.ts
Normal file
|
@ -0,0 +1,43 @@
|
|||
import {AxiosResponse} from 'axios';
|
||||
|
||||
class BadResponseError extends Error {
|
||||
constructor(public err: Error, public res: AxiosResponse<any>) {
|
||||
super(err.toString());
|
||||
Object.setPrototypeOf(this, BadResponseError.prototype);
|
||||
}
|
||||
}
|
||||
|
||||
type Optional<T> = T | undefined | null;
|
||||
type TPromiseOn<T, R> = Optional<(_: T) => R | PromiseLike<R>>;
|
||||
export abstract class APIPromise<T> implements PromiseLike<T> {
|
||||
promise: Promise<T>;
|
||||
|
||||
constructor(req: Promise<AxiosResponse<any>>) {
|
||||
this.promise = new Promise((rsv, rjt)=>{
|
||||
req.then(res=>{
|
||||
try {
|
||||
rsv(this.onResponse(res));
|
||||
} catch (err) {
|
||||
rjt(new BadResponseError(err, res));
|
||||
}
|
||||
}).catch(err=>rjt(err));
|
||||
});
|
||||
}
|
||||
|
||||
then<T1=T, T2=never>(onRsv?: TPromiseOn<T, T1>, onRjt?: TPromiseOn<any, T2>) {
|
||||
return this.promise.then(onRsv, onRjt);
|
||||
}
|
||||
catch<T2>(onRjt: TPromiseOn<any, T2>) {
|
||||
return this.then(undefined, onRjt);
|
||||
}
|
||||
|
||||
abstract onResponse(res: AxiosResponse<any>): T;
|
||||
onSuccess<U, V>(f: Optional<(x: U)=>V>, v: U): U | V {
|
||||
if (f) return f(v);
|
||||
else return v;
|
||||
}
|
||||
onFail<U, V>(f: Optional<(x: U)=>V>, v: U) {
|
||||
if (f) return f(v);
|
||||
else throw new Error();
|
||||
}
|
||||
}
|
41
lib/utils/FullDate.ts
Normal file
41
lib/utils/FullDate.ts
Normal file
|
@ -0,0 +1,41 @@
|
|||
export class FullDate {
|
||||
private date: Date;
|
||||
constructor(...argv: any) {
|
||||
this.date = (()=>{
|
||||
if (argv.length==1) {
|
||||
const arg = argv[0];
|
||||
if (arg instanceof FullDate) return new Date(+arg);
|
||||
if (arg instanceof Date) return arg;
|
||||
if (typeof arg === 'string') {
|
||||
const tokens = /^(\d+)-(\d+)-(\d+)$/g.exec(arg)?.slice(1, 4);
|
||||
if (tokens) return new Date(+tokens[0], +tokens[1]-1, +tokens[2]);
|
||||
}
|
||||
return new Date(arg);
|
||||
} else if (argv.length==3) {
|
||||
return new Date(argv[0], argv[1]-1, argv[2]);
|
||||
}
|
||||
return new Date();
|
||||
})();
|
||||
}
|
||||
toString(): string {
|
||||
const d = this.date;
|
||||
const f = (s: any) => ('0'+s).slice(-2);
|
||||
return `${d.getFullYear()}-${f(d.getMonth()+1)}-${f(d.getDate())}`;
|
||||
}
|
||||
toJSON(): string {
|
||||
return this.toString();
|
||||
}
|
||||
valueOf(): number {
|
||||
return new Date(this.date).setHours(0, 0, 0, 0);
|
||||
}
|
||||
// prop
|
||||
getFullYear(): number {
|
||||
return this.date.getFullYear();
|
||||
}
|
||||
getMonth(): number {
|
||||
return this.date.getMonth()+1;
|
||||
}
|
||||
getDate(): number {
|
||||
return this.date.getDate();
|
||||
}
|
||||
}
|
61
lib/utils/StrictTypeParser.ts
Normal file
61
lib/utils/StrictTypeParser.ts
Normal file
|
@ -0,0 +1,61 @@
|
|||
import {FullDate} from './FullDate';
|
||||
|
||||
export module StrictTypeParser {
|
||||
export class BadValueError extends Error {
|
||||
constructor(public attr: string, public type: string, public value: any) {
|
||||
super(`${attr}: Can not convert \`${
|
||||
['object', 'array'].includes(typeof value) ?
|
||||
JSON.stringify(value) : `${value}`
|
||||
}\` to type ${type}`);
|
||||
console.error(this.message);
|
||||
Object.setPrototypeOf(this, BadValueError.prototype);
|
||||
}
|
||||
}
|
||||
|
||||
export function _number(x: any, attr: string): number {
|
||||
if (typeof x === 'number') return x;
|
||||
if (typeof x === 'string') {
|
||||
const r = +x;
|
||||
if (!isNaN(r)) return r;
|
||||
}
|
||||
throw new BadValueError(attr, 'number', x);
|
||||
}
|
||||
export function _string(x: any, attr: string): string {
|
||||
if (typeof x === 'string') return x;
|
||||
if (typeof x === 'object') return x.toString();
|
||||
throw new BadValueError(attr, 'string', x);
|
||||
}
|
||||
export function _boolean(x: any, attr: string): boolean {
|
||||
if (typeof x === 'boolean') return x;
|
||||
if (x==='true') return true;
|
||||
if (x==='false') return false;
|
||||
throw new BadValueError(attr, 'boolean', x);
|
||||
}
|
||||
export function _Date(x: any, attr: string): Date {
|
||||
const r = new Date(x);
|
||||
if (!isNaN(+r)) return r;
|
||||
throw new BadValueError(attr, 'Date', x);
|
||||
}
|
||||
export function _FullDate(x: any, attr: string): FullDate {
|
||||
const r = new FullDate(x);
|
||||
if (!isNaN(+r)) return r;
|
||||
throw new BadValueError(attr, 'FullDate', x);
|
||||
}
|
||||
export function _byte(x: any, attr: string): string {
|
||||
if (typeof x === 'string') return x;
|
||||
if (x instanceof Buffer) return x.toString('base64');
|
||||
throw new BadValueError(attr, 'byte', x);
|
||||
}
|
||||
export function _binary(x: any, attr: string): string {
|
||||
if (typeof x === 'string') return x;
|
||||
if (x instanceof Buffer) return x.toString('hex');
|
||||
if (x?.buffer instanceof Buffer) return x.toString('hex');
|
||||
throw new BadValueError(attr, 'binary', x);
|
||||
}
|
||||
export function _Array(x: any, attr: string): Array<any> {
|
||||
if (x instanceof Array) return x;
|
||||
throw new BadValueError(attr, 'Array', x);
|
||||
}
|
||||
export const supportTypes = [
|
||||
'number', 'string', 'boolean', 'Date', 'FullDate', 'byte', 'binary'];
|
||||
}
|
3
lib/utils/index.ts
Normal file
3
lib/utils/index.ts
Normal file
|
@ -0,0 +1,3 @@
|
|||
export * from './APIPromise';
|
||||
export * from './FullDate';
|
||||
export * from './StrictTypeParser';
|
30
package.json
Normal file
30
package.json
Normal file
|
@ -0,0 +1,30 @@
|
|||
{
|
||||
"name": "api-codegen-ts",
|
||||
"version": "1.0.0",
|
||||
"description": "OpenAPI code generator for TypeScript",
|
||||
"main": "dist/index.js",
|
||||
"types": "dist/index.d.ts",
|
||||
"scripts": {
|
||||
"clean": "rm -rf dist",
|
||||
"build": "tsc",
|
||||
"lint": "eslint lib bin --ext ts --ext js"
|
||||
},
|
||||
"author": "supmiku39",
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"api-codegen": "bin/api-codegen.js"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/js-yaml": "^3.12.3",
|
||||
"@types/node": "^13.11.0",
|
||||
"@typescript-eslint/eslint-plugin": "^2.26.0",
|
||||
"@typescript-eslint/parser": "^2.26.0",
|
||||
"axios": "^0.19.2",
|
||||
"eslint": "^6.8.0",
|
||||
"eslint-config-google": "^0.14.0",
|
||||
"typescript": "^3.8.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"js-yaml": "^3.13.1"
|
||||
}
|
||||
}
|
15
tsconfig.json
Normal file
15
tsconfig.json
Normal file
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"declaration": true,
|
||||
"lib": [
|
||||
"dom"
|
||||
],
|
||||
"target": "es5",
|
||||
"module": "commonjs",
|
||||
"moduleResolution": "node",
|
||||
"outDir": "dist",
|
||||
"rootDir": "lib",
|
||||
"strict": true
|
||||
},
|
||||
"include": ["lib"]
|
||||
}
|
1
utils
Symbolic link
1
utils
Symbolic link
|
@ -0,0 +1 @@
|
|||
dist/utils
|
994
yarn.lock
Normal file
994
yarn.lock
Normal file
|
@ -0,0 +1,994 @@
|
|||
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
|
||||
# yarn lockfile v1
|
||||
|
||||
|
||||
"@babel/code-frame@^7.0.0":
|
||||
version "7.8.3"
|
||||
resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.8.3.tgz#33e25903d7481181534e12ec0a25f16b6fcf419e"
|
||||
integrity sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==
|
||||
dependencies:
|
||||
"@babel/highlight" "^7.8.3"
|
||||
|
||||
"@babel/helper-validator-identifier@^7.9.0":
|
||||
version "7.9.0"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.9.0.tgz#ad53562a7fc29b3b9a91bbf7d10397fd146346ed"
|
||||
integrity sha512-6G8bQKjOh+of4PV/ThDm/rRqlU7+IGoJuofpagU5GlEl29Vv0RGqqt86ZGRV8ZuSOY3o+8yXl5y782SMcG7SHw==
|
||||
|
||||
"@babel/highlight@^7.8.3":
|
||||
version "7.9.0"
|
||||
resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.9.0.tgz#4e9b45ccb82b79607271b2979ad82c7b68163079"
|
||||
integrity sha512-lJZPilxX7Op3Nv/2cvFdnlepPXDxi29wxteT57Q965oc5R9v86ztx0jfxVrTcBk8C2kcPkkDa2Z4T3ZsPPVWsQ==
|
||||
dependencies:
|
||||
"@babel/helper-validator-identifier" "^7.9.0"
|
||||
chalk "^2.0.0"
|
||||
js-tokens "^4.0.0"
|
||||
|
||||
"@types/color-name@^1.1.1":
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/color-name/-/color-name-1.1.1.tgz#1c1261bbeaa10a8055bbc5d8ab84b7b2afc846a0"
|
||||
integrity sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==
|
||||
|
||||
"@types/eslint-visitor-keys@^1.0.0":
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#1ee30d79544ca84d68d4b3cdb0af4f205663dd2d"
|
||||
integrity sha512-OCutwjDZ4aFS6PB1UZ988C4YgwlBHJd6wCeQqaLdmadZ/7e+w79+hbMUFC1QXDNCmdyoRfAFdm0RypzwR+Qpag==
|
||||
|
||||
"@types/js-yaml@^3.12.3":
|
||||
version "3.12.3"
|
||||
resolved "https://registry.yarnpkg.com/@types/js-yaml/-/js-yaml-3.12.3.tgz#abf383c5b639d0aa8b8c4a420d6a85f703357d6c"
|
||||
integrity sha512-otRe77JNNWzoVGLKw8TCspKswRoQToys4tuL6XYVBFxjgeM0RUrx7m3jkaTdxILxeGry3zM8mGYkGXMeQ02guA==
|
||||
|
||||
"@types/json-schema@^7.0.3":
|
||||
version "7.0.4"
|
||||
resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.4.tgz#38fd73ddfd9b55abb1e1b2ed578cb55bd7b7d339"
|
||||
integrity sha512-8+KAKzEvSUdeo+kmqnKrqgeE+LcA0tjYWFY7RPProVYwnqDjukzO+3b6dLD56rYX5TdWejnEOLJYOIeh4CXKuA==
|
||||
|
||||
"@types/node@^13.11.0":
|
||||
version "13.11.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-13.11.0.tgz#390ea202539c61c8fa6ba4428b57e05bc36dc47b"
|
||||
integrity sha512-uM4mnmsIIPK/yeO+42F2RQhGUIs39K2RFmugcJANppXe6J1nvH87PvzPZYpza7Xhhs8Yn9yIAVdLZ84z61+0xQ==
|
||||
|
||||
"@typescript-eslint/eslint-plugin@^2.26.0":
|
||||
version "2.26.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-2.26.0.tgz#04c96560c8981421e5a9caad8394192363cc423f"
|
||||
integrity sha512-4yUnLv40bzfzsXcTAtZyTjbiGUXMrcIJcIMioI22tSOyAxpdXiZ4r7YQUU8Jj6XXrLz9d5aMHPQf5JFR7h27Nw==
|
||||
dependencies:
|
||||
"@typescript-eslint/experimental-utils" "2.26.0"
|
||||
functional-red-black-tree "^1.0.1"
|
||||
regexpp "^3.0.0"
|
||||
tsutils "^3.17.1"
|
||||
|
||||
"@typescript-eslint/experimental-utils@2.26.0":
|
||||
version "2.26.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-2.26.0.tgz#063390c404d9980767d76274df386c0aa675d91d"
|
||||
integrity sha512-RELVoH5EYd+JlGprEyojUv9HeKcZqF7nZUGSblyAw1FwOGNnmQIU8kxJ69fttQvEwCsX5D6ECJT8GTozxrDKVQ==
|
||||
dependencies:
|
||||
"@types/json-schema" "^7.0.3"
|
||||
"@typescript-eslint/typescript-estree" "2.26.0"
|
||||
eslint-scope "^5.0.0"
|
||||
eslint-utils "^2.0.0"
|
||||
|
||||
"@typescript-eslint/parser@^2.26.0":
|
||||
version "2.26.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-2.26.0.tgz#385463615818b33acb72a25b39c03579df93d76f"
|
||||
integrity sha512-+Xj5fucDtdKEVGSh9353wcnseMRkPpEAOY96EEenN7kJVrLqy/EVwtIh3mxcUz8lsFXW1mT5nN5vvEam/a5HiQ==
|
||||
dependencies:
|
||||
"@types/eslint-visitor-keys" "^1.0.0"
|
||||
"@typescript-eslint/experimental-utils" "2.26.0"
|
||||
"@typescript-eslint/typescript-estree" "2.26.0"
|
||||
eslint-visitor-keys "^1.1.0"
|
||||
|
||||
"@typescript-eslint/typescript-estree@2.26.0":
|
||||
version "2.26.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-2.26.0.tgz#d8132cf1ee8a72234f996519a47d8a9118b57d56"
|
||||
integrity sha512-3x4SyZCLB4zsKsjuhxDLeVJN6W29VwBnYpCsZ7vIdPel9ZqLfIZJgJXO47MNUkurGpQuIBALdPQKtsSnWpE1Yg==
|
||||
dependencies:
|
||||
debug "^4.1.1"
|
||||
eslint-visitor-keys "^1.1.0"
|
||||
glob "^7.1.6"
|
||||
is-glob "^4.0.1"
|
||||
lodash "^4.17.15"
|
||||
semver "^6.3.0"
|
||||
tsutils "^3.17.1"
|
||||
|
||||
acorn-jsx@^5.2.0:
|
||||
version "5.2.0"
|
||||
resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.2.0.tgz#4c66069173d6fdd68ed85239fc256226182b2ebe"
|
||||
integrity sha512-HiUX/+K2YpkpJ+SzBffkM/AQ2YE03S0U1kjTLVpoJdhZMOWy8qvXVN9JdLqv2QsaQ6MPYQIuNmwD8zOiYUofLQ==
|
||||
|
||||
acorn@^7.1.1:
|
||||
version "7.1.1"
|
||||
resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.1.1.tgz#e35668de0b402f359de515c5482a1ab9f89a69bf"
|
||||
integrity sha512-add7dgA5ppRPxCFJoAGfMDi7PIBXq1RtGo7BhbLaxwrXPOmw8gq48Y9ozT01hUKy9byMjlR20EJhu5zlkErEkg==
|
||||
|
||||
ajv@^6.10.0, ajv@^6.10.2:
|
||||
version "6.12.0"
|
||||
resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.0.tgz#06d60b96d87b8454a5adaba86e7854da629db4b7"
|
||||
integrity sha512-D6gFiFA0RRLyUbvijN74DWAjXSFxWKaWP7mldxkVhyhAV3+SWA9HEJPHQ2c9soIeTFJqcSdFDGFgdqs1iUU2Hw==
|
||||
dependencies:
|
||||
fast-deep-equal "^3.1.1"
|
||||
fast-json-stable-stringify "^2.0.0"
|
||||
json-schema-traverse "^0.4.1"
|
||||
uri-js "^4.2.2"
|
||||
|
||||
ansi-escapes@^4.2.1:
|
||||
version "4.3.1"
|
||||
resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.1.tgz#a5c47cc43181f1f38ffd7076837700d395522a61"
|
||||
integrity sha512-JWF7ocqNrp8u9oqpgV+wH5ftbt+cfvv+PTjOvKLT3AdYly/LmORARfEVT1iyjwN+4MqE5UmVKoAdIBqeoCHgLA==
|
||||
dependencies:
|
||||
type-fest "^0.11.0"
|
||||
|
||||
ansi-regex@^4.1.0:
|
||||
version "4.1.0"
|
||||
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997"
|
||||
integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==
|
||||
|
||||
ansi-regex@^5.0.0:
|
||||
version "5.0.0"
|
||||
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.0.tgz#388539f55179bf39339c81af30a654d69f87cb75"
|
||||
integrity sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==
|
||||
|
||||
ansi-styles@^3.2.0, ansi-styles@^3.2.1:
|
||||
version "3.2.1"
|
||||
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d"
|
||||
integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==
|
||||
dependencies:
|
||||
color-convert "^1.9.0"
|
||||
|
||||
ansi-styles@^4.1.0:
|
||||
version "4.2.1"
|
||||
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.2.1.tgz#90ae75c424d008d2624c5bf29ead3177ebfcf359"
|
||||
integrity sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==
|
||||
dependencies:
|
||||
"@types/color-name" "^1.1.1"
|
||||
color-convert "^2.0.1"
|
||||
|
||||
argparse@^1.0.7:
|
||||
version "1.0.10"
|
||||
resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911"
|
||||
integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==
|
||||
dependencies:
|
||||
sprintf-js "~1.0.2"
|
||||
|
||||
astral-regex@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9"
|
||||
integrity sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==
|
||||
|
||||
axios@^0.19.2:
|
||||
version "0.19.2"
|
||||
resolved "https://registry.yarnpkg.com/axios/-/axios-0.19.2.tgz#3ea36c5d8818d0d5f8a8a97a6d36b86cdc00cb27"
|
||||
integrity sha512-fjgm5MvRHLhx+osE2xoekY70AhARk3a6hkN+3Io1jc00jtquGvxYlKlsFUhmUET0V5te6CcZI7lcv2Ym61mjHA==
|
||||
dependencies:
|
||||
follow-redirects "1.5.10"
|
||||
|
||||
balanced-match@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767"
|
||||
integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c=
|
||||
|
||||
brace-expansion@^1.1.7:
|
||||
version "1.1.11"
|
||||
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd"
|
||||
integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==
|
||||
dependencies:
|
||||
balanced-match "^1.0.0"
|
||||
concat-map "0.0.1"
|
||||
|
||||
callsites@^3.0.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73"
|
||||
integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==
|
||||
|
||||
chalk@^2.0.0, chalk@^2.1.0:
|
||||
version "2.4.2"
|
||||
resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424"
|
||||
integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==
|
||||
dependencies:
|
||||
ansi-styles "^3.2.1"
|
||||
escape-string-regexp "^1.0.5"
|
||||
supports-color "^5.3.0"
|
||||
|
||||
chalk@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/chalk/-/chalk-3.0.0.tgz#3f73c2bf526591f574cc492c51e2456349f844e4"
|
||||
integrity sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==
|
||||
dependencies:
|
||||
ansi-styles "^4.1.0"
|
||||
supports-color "^7.1.0"
|
||||
|
||||
chardet@^0.7.0:
|
||||
version "0.7.0"
|
||||
resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e"
|
||||
integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==
|
||||
|
||||
cli-cursor@^3.1.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-3.1.0.tgz#264305a7ae490d1d03bf0c9ba7c925d1753af307"
|
||||
integrity sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==
|
||||
dependencies:
|
||||
restore-cursor "^3.1.0"
|
||||
|
||||
cli-width@^2.0.0:
|
||||
version "2.2.0"
|
||||
resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.0.tgz#ff19ede8a9a5e579324147b0c11f0fbcbabed639"
|
||||
integrity sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=
|
||||
|
||||
color-convert@^1.9.0:
|
||||
version "1.9.3"
|
||||
resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8"
|
||||
integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==
|
||||
dependencies:
|
||||
color-name "1.1.3"
|
||||
|
||||
color-convert@^2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3"
|
||||
integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==
|
||||
dependencies:
|
||||
color-name "~1.1.4"
|
||||
|
||||
color-name@1.1.3:
|
||||
version "1.1.3"
|
||||
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25"
|
||||
integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=
|
||||
|
||||
color-name@~1.1.4:
|
||||
version "1.1.4"
|
||||
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2"
|
||||
integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
|
||||
|
||||
concat-map@0.0.1:
|
||||
version "0.0.1"
|
||||
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
|
||||
integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=
|
||||
|
||||
cross-spawn@^6.0.5:
|
||||
version "6.0.5"
|
||||
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4"
|
||||
integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==
|
||||
dependencies:
|
||||
nice-try "^1.0.4"
|
||||
path-key "^2.0.1"
|
||||
semver "^5.5.0"
|
||||
shebang-command "^1.2.0"
|
||||
which "^1.2.9"
|
||||
|
||||
debug@=3.1.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261"
|
||||
integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==
|
||||
dependencies:
|
||||
ms "2.0.0"
|
||||
|
||||
debug@^4.0.1, debug@^4.1.1:
|
||||
version "4.1.1"
|
||||
resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791"
|
||||
integrity sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==
|
||||
dependencies:
|
||||
ms "^2.1.1"
|
||||
|
||||
deep-is@~0.1.3:
|
||||
version "0.1.3"
|
||||
resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34"
|
||||
integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=
|
||||
|
||||
doctrine@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961"
|
||||
integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==
|
||||
dependencies:
|
||||
esutils "^2.0.2"
|
||||
|
||||
emoji-regex@^7.0.1:
|
||||
version "7.0.3"
|
||||
resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156"
|
||||
integrity sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==
|
||||
|
||||
emoji-regex@^8.0.0:
|
||||
version "8.0.0"
|
||||
resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37"
|
||||
integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==
|
||||
|
||||
escape-string-regexp@^1.0.5:
|
||||
version "1.0.5"
|
||||
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
|
||||
integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=
|
||||
|
||||
eslint-config-google@^0.14.0:
|
||||
version "0.14.0"
|
||||
resolved "https://registry.yarnpkg.com/eslint-config-google/-/eslint-config-google-0.14.0.tgz#4f5f8759ba6e11b424294a219dbfa18c508bcc1a"
|
||||
integrity sha512-WsbX4WbjuMvTdeVL6+J3rK1RGhCTqjsFjX7UMSMgZiyxxaNLkoJENbrGExzERFeoTpGw3F3FypTiWAP9ZXzkEw==
|
||||
|
||||
eslint-scope@^5.0.0:
|
||||
version "5.0.0"
|
||||
resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.0.0.tgz#e87c8887c73e8d1ec84f1ca591645c358bfc8fb9"
|
||||
integrity sha512-oYrhJW7S0bxAFDvWqzvMPRm6pcgcnWc4QnofCAqRTRfQC0JcwenzGglTtsLyIuuWFfkqDG9vz67cnttSd53djw==
|
||||
dependencies:
|
||||
esrecurse "^4.1.0"
|
||||
estraverse "^4.1.1"
|
||||
|
||||
eslint-utils@^1.4.3:
|
||||
version "1.4.3"
|
||||
resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-1.4.3.tgz#74fec7c54d0776b6f67e0251040b5806564e981f"
|
||||
integrity sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q==
|
||||
dependencies:
|
||||
eslint-visitor-keys "^1.1.0"
|
||||
|
||||
eslint-utils@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-2.0.0.tgz#7be1cc70f27a72a76cd14aa698bcabed6890e1cd"
|
||||
integrity sha512-0HCPuJv+7Wv1bACm8y5/ECVfYdfsAm9xmVb7saeFlxjPYALefjhbYoCkBjPdPzGH8wWyTpAez82Fh3VKYEZ8OA==
|
||||
dependencies:
|
||||
eslint-visitor-keys "^1.1.0"
|
||||
|
||||
eslint-visitor-keys@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz#e2a82cea84ff246ad6fb57f9bde5b46621459ec2"
|
||||
integrity sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A==
|
||||
|
||||
eslint@^6.8.0:
|
||||
version "6.8.0"
|
||||
resolved "https://registry.yarnpkg.com/eslint/-/eslint-6.8.0.tgz#62262d6729739f9275723824302fb227c8c93ffb"
|
||||
integrity sha512-K+Iayyo2LtyYhDSYwz5D5QdWw0hCacNzyq1Y821Xna2xSJj7cijoLLYmLxTQgcgZ9mC61nryMy9S7GRbYpI5Ig==
|
||||
dependencies:
|
||||
"@babel/code-frame" "^7.0.0"
|
||||
ajv "^6.10.0"
|
||||
chalk "^2.1.0"
|
||||
cross-spawn "^6.0.5"
|
||||
debug "^4.0.1"
|
||||
doctrine "^3.0.0"
|
||||
eslint-scope "^5.0.0"
|
||||
eslint-utils "^1.4.3"
|
||||
eslint-visitor-keys "^1.1.0"
|
||||
espree "^6.1.2"
|
||||
esquery "^1.0.1"
|
||||
esutils "^2.0.2"
|
||||
file-entry-cache "^5.0.1"
|
||||
functional-red-black-tree "^1.0.1"
|
||||
glob-parent "^5.0.0"
|
||||
globals "^12.1.0"
|
||||
ignore "^4.0.6"
|
||||
import-fresh "^3.0.0"
|
||||
imurmurhash "^0.1.4"
|
||||
inquirer "^7.0.0"
|
||||
is-glob "^4.0.0"
|
||||
js-yaml "^3.13.1"
|
||||
json-stable-stringify-without-jsonify "^1.0.1"
|
||||
levn "^0.3.0"
|
||||
lodash "^4.17.14"
|
||||
minimatch "^3.0.4"
|
||||
mkdirp "^0.5.1"
|
||||
natural-compare "^1.4.0"
|
||||
optionator "^0.8.3"
|
||||
progress "^2.0.0"
|
||||
regexpp "^2.0.1"
|
||||
semver "^6.1.2"
|
||||
strip-ansi "^5.2.0"
|
||||
strip-json-comments "^3.0.1"
|
||||
table "^5.2.3"
|
||||
text-table "^0.2.0"
|
||||
v8-compile-cache "^2.0.3"
|
||||
|
||||
espree@^6.1.2:
|
||||
version "6.2.1"
|
||||
resolved "https://registry.yarnpkg.com/espree/-/espree-6.2.1.tgz#77fc72e1fd744a2052c20f38a5b575832e82734a"
|
||||
integrity sha512-ysCxRQY3WaXJz9tdbWOwuWr5Y/XrPTGX9Kiz3yoUXwW0VZ4w30HTkQLaGx/+ttFjF8i+ACbArnB4ce68a9m5hw==
|
||||
dependencies:
|
||||
acorn "^7.1.1"
|
||||
acorn-jsx "^5.2.0"
|
||||
eslint-visitor-keys "^1.1.0"
|
||||
|
||||
esprima@^4.0.0:
|
||||
version "4.0.1"
|
||||
resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71"
|
||||
integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==
|
||||
|
||||
esquery@^1.0.1:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.2.0.tgz#a010a519c0288f2530b3404124bfb5f02e9797fe"
|
||||
integrity sha512-weltsSqdeWIX9G2qQZz7KlTRJdkkOCTPgLYJUz1Hacf48R4YOwGPHO3+ORfWedqJKbq5WQmsgK90n+pFLIKt/Q==
|
||||
dependencies:
|
||||
estraverse "^5.0.0"
|
||||
|
||||
esrecurse@^4.1.0:
|
||||
version "4.2.1"
|
||||
resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.2.1.tgz#007a3b9fdbc2b3bb87e4879ea19c92fdbd3942cf"
|
||||
integrity sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==
|
||||
dependencies:
|
||||
estraverse "^4.1.0"
|
||||
|
||||
estraverse@^4.1.0, estraverse@^4.1.1:
|
||||
version "4.3.0"
|
||||
resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d"
|
||||
integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==
|
||||
|
||||
estraverse@^5.0.0:
|
||||
version "5.0.0"
|
||||
resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.0.0.tgz#ac81750b482c11cca26e4b07e83ed8f75fbcdc22"
|
||||
integrity sha512-j3acdrMzqrxmJTNj5dbr1YbjacrYgAxVMeF0gK16E3j494mOe7xygM/ZLIguEQ0ETwAg2hlJCtHRGav+y0Ny5A==
|
||||
|
||||
esutils@^2.0.2:
|
||||
version "2.0.3"
|
||||
resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64"
|
||||
integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==
|
||||
|
||||
external-editor@^3.0.3:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.1.0.tgz#cb03f740befae03ea4d283caed2741a83f335495"
|
||||
integrity sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==
|
||||
dependencies:
|
||||
chardet "^0.7.0"
|
||||
iconv-lite "^0.4.24"
|
||||
tmp "^0.0.33"
|
||||
|
||||
fast-deep-equal@^3.1.1:
|
||||
version "3.1.1"
|
||||
resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz#545145077c501491e33b15ec408c294376e94ae4"
|
||||
integrity sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA==
|
||||
|
||||
fast-json-stable-stringify@^2.0.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633"
|
||||
integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==
|
||||
|
||||
fast-levenshtein@~2.0.6:
|
||||
version "2.0.6"
|
||||
resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917"
|
||||
integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=
|
||||
|
||||
figures@^3.0.0:
|
||||
version "3.2.0"
|
||||
resolved "https://registry.yarnpkg.com/figures/-/figures-3.2.0.tgz#625c18bd293c604dc4a8ddb2febf0c88341746af"
|
||||
integrity sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==
|
||||
dependencies:
|
||||
escape-string-regexp "^1.0.5"
|
||||
|
||||
file-entry-cache@^5.0.1:
|
||||
version "5.0.1"
|
||||
resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-5.0.1.tgz#ca0f6efa6dd3d561333fb14515065c2fafdf439c"
|
||||
integrity sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==
|
||||
dependencies:
|
||||
flat-cache "^2.0.1"
|
||||
|
||||
flat-cache@^2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-2.0.1.tgz#5d296d6f04bda44a4630a301413bdbc2ec085ec0"
|
||||
integrity sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==
|
||||
dependencies:
|
||||
flatted "^2.0.0"
|
||||
rimraf "2.6.3"
|
||||
write "1.0.3"
|
||||
|
||||
flatted@^2.0.0:
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/flatted/-/flatted-2.0.2.tgz#4575b21e2bcee7434aa9be662f4b7b5f9c2b5138"
|
||||
integrity sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==
|
||||
|
||||
follow-redirects@1.5.10:
|
||||
version "1.5.10"
|
||||
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.5.10.tgz#7b7a9f9aea2fdff36786a94ff643ed07f4ff5e2a"
|
||||
integrity sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==
|
||||
dependencies:
|
||||
debug "=3.1.0"
|
||||
|
||||
fs.realpath@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
|
||||
integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8=
|
||||
|
||||
functional-red-black-tree@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327"
|
||||
integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=
|
||||
|
||||
glob-parent@^5.0.0:
|
||||
version "5.1.1"
|
||||
resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.1.tgz#b6c1ef417c4e5663ea498f1c45afac6916bbc229"
|
||||
integrity sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==
|
||||
dependencies:
|
||||
is-glob "^4.0.1"
|
||||
|
||||
glob@^7.1.3, glob@^7.1.6:
|
||||
version "7.1.6"
|
||||
resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6"
|
||||
integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==
|
||||
dependencies:
|
||||
fs.realpath "^1.0.0"
|
||||
inflight "^1.0.4"
|
||||
inherits "2"
|
||||
minimatch "^3.0.4"
|
||||
once "^1.3.0"
|
||||
path-is-absolute "^1.0.0"
|
||||
|
||||
globals@^12.1.0:
|
||||
version "12.4.0"
|
||||
resolved "https://registry.yarnpkg.com/globals/-/globals-12.4.0.tgz#a18813576a41b00a24a97e7f815918c2e19925f8"
|
||||
integrity sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==
|
||||
dependencies:
|
||||
type-fest "^0.8.1"
|
||||
|
||||
has-flag@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd"
|
||||
integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0=
|
||||
|
||||
has-flag@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b"
|
||||
integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==
|
||||
|
||||
iconv-lite@^0.4.24:
|
||||
version "0.4.24"
|
||||
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b"
|
||||
integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==
|
||||
dependencies:
|
||||
safer-buffer ">= 2.1.2 < 3"
|
||||
|
||||
ignore@^4.0.6:
|
||||
version "4.0.6"
|
||||
resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc"
|
||||
integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==
|
||||
|
||||
import-fresh@^3.0.0:
|
||||
version "3.2.1"
|
||||
resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.2.1.tgz#633ff618506e793af5ac91bf48b72677e15cbe66"
|
||||
integrity sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ==
|
||||
dependencies:
|
||||
parent-module "^1.0.0"
|
||||
resolve-from "^4.0.0"
|
||||
|
||||
imurmurhash@^0.1.4:
|
||||
version "0.1.4"
|
||||
resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea"
|
||||
integrity sha1-khi5srkoojixPcT7a21XbyMUU+o=
|
||||
|
||||
inflight@^1.0.4:
|
||||
version "1.0.6"
|
||||
resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9"
|
||||
integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=
|
||||
dependencies:
|
||||
once "^1.3.0"
|
||||
wrappy "1"
|
||||
|
||||
inherits@2:
|
||||
version "2.0.4"
|
||||
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
|
||||
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
|
||||
|
||||
inquirer@^7.0.0:
|
||||
version "7.1.0"
|
||||
resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-7.1.0.tgz#1298a01859883e17c7264b82870ae1034f92dd29"
|
||||
integrity sha512-5fJMWEmikSYu0nv/flMc475MhGbB7TSPd/2IpFV4I4rMklboCH2rQjYY5kKiYGHqUF9gvaambupcJFFG9dvReg==
|
||||
dependencies:
|
||||
ansi-escapes "^4.2.1"
|
||||
chalk "^3.0.0"
|
||||
cli-cursor "^3.1.0"
|
||||
cli-width "^2.0.0"
|
||||
external-editor "^3.0.3"
|
||||
figures "^3.0.0"
|
||||
lodash "^4.17.15"
|
||||
mute-stream "0.0.8"
|
||||
run-async "^2.4.0"
|
||||
rxjs "^6.5.3"
|
||||
string-width "^4.1.0"
|
||||
strip-ansi "^6.0.0"
|
||||
through "^2.3.6"
|
||||
|
||||
is-extglob@^2.1.1:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2"
|
||||
integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=
|
||||
|
||||
is-fullwidth-code-point@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f"
|
||||
integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=
|
||||
|
||||
is-fullwidth-code-point@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d"
|
||||
integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==
|
||||
|
||||
is-glob@^4.0.0, is-glob@^4.0.1:
|
||||
version "4.0.1"
|
||||
resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc"
|
||||
integrity sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==
|
||||
dependencies:
|
||||
is-extglob "^2.1.1"
|
||||
|
||||
is-promise@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa"
|
||||
integrity sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=
|
||||
|
||||
isexe@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10"
|
||||
integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=
|
||||
|
||||
js-tokens@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
|
||||
integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==
|
||||
|
||||
js-yaml@^3.13.1:
|
||||
version "3.13.1"
|
||||
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.13.1.tgz#aff151b30bfdfa8e49e05da22e7415e9dfa37847"
|
||||
integrity sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==
|
||||
dependencies:
|
||||
argparse "^1.0.7"
|
||||
esprima "^4.0.0"
|
||||
|
||||
json-schema-traverse@^0.4.1:
|
||||
version "0.4.1"
|
||||
resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660"
|
||||
integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==
|
||||
|
||||
json-stable-stringify-without-jsonify@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651"
|
||||
integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=
|
||||
|
||||
levn@^0.3.0, levn@~0.3.0:
|
||||
version "0.3.0"
|
||||
resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee"
|
||||
integrity sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=
|
||||
dependencies:
|
||||
prelude-ls "~1.1.2"
|
||||
type-check "~0.3.2"
|
||||
|
||||
lodash@^4.17.14, lodash@^4.17.15:
|
||||
version "4.17.15"
|
||||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548"
|
||||
integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==
|
||||
|
||||
mimic-fn@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b"
|
||||
integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==
|
||||
|
||||
minimatch@^3.0.4:
|
||||
version "3.0.4"
|
||||
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083"
|
||||
integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==
|
||||
dependencies:
|
||||
brace-expansion "^1.1.7"
|
||||
|
||||
minimist@^1.2.5:
|
||||
version "1.2.5"
|
||||
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602"
|
||||
integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==
|
||||
|
||||
mkdirp@^0.5.1:
|
||||
version "0.5.5"
|
||||
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def"
|
||||
integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==
|
||||
dependencies:
|
||||
minimist "^1.2.5"
|
||||
|
||||
ms@2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
|
||||
integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=
|
||||
|
||||
ms@^2.1.1:
|
||||
version "2.1.2"
|
||||
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009"
|
||||
integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==
|
||||
|
||||
mute-stream@0.0.8:
|
||||
version "0.0.8"
|
||||
resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d"
|
||||
integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==
|
||||
|
||||
natural-compare@^1.4.0:
|
||||
version "1.4.0"
|
||||
resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7"
|
||||
integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=
|
||||
|
||||
nice-try@^1.0.4:
|
||||
version "1.0.5"
|
||||
resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366"
|
||||
integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==
|
||||
|
||||
once@^1.3.0:
|
||||
version "1.4.0"
|
||||
resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
|
||||
integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E=
|
||||
dependencies:
|
||||
wrappy "1"
|
||||
|
||||
onetime@^5.1.0:
|
||||
version "5.1.0"
|
||||
resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.0.tgz#fff0f3c91617fe62bb50189636e99ac8a6df7be5"
|
||||
integrity sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q==
|
||||
dependencies:
|
||||
mimic-fn "^2.1.0"
|
||||
|
||||
optionator@^0.8.3:
|
||||
version "0.8.3"
|
||||
resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.3.tgz#84fa1d036fe9d3c7e21d99884b601167ec8fb495"
|
||||
integrity sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==
|
||||
dependencies:
|
||||
deep-is "~0.1.3"
|
||||
fast-levenshtein "~2.0.6"
|
||||
levn "~0.3.0"
|
||||
prelude-ls "~1.1.2"
|
||||
type-check "~0.3.2"
|
||||
word-wrap "~1.2.3"
|
||||
|
||||
os-tmpdir@~1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274"
|
||||
integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=
|
||||
|
||||
parent-module@^1.0.0:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2"
|
||||
integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==
|
||||
dependencies:
|
||||
callsites "^3.0.0"
|
||||
|
||||
path-is-absolute@^1.0.0:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
|
||||
integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18=
|
||||
|
||||
path-key@^2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40"
|
||||
integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=
|
||||
|
||||
prelude-ls@~1.1.2:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54"
|
||||
integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=
|
||||
|
||||
progress@^2.0.0:
|
||||
version "2.0.3"
|
||||
resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8"
|
||||
integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==
|
||||
|
||||
punycode@^2.1.0:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec"
|
||||
integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==
|
||||
|
||||
regexpp@^2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-2.0.1.tgz#8d19d31cf632482b589049f8281f93dbcba4d07f"
|
||||
integrity sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==
|
||||
|
||||
regexpp@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.0.0.tgz#dd63982ee3300e67b41c1956f850aa680d9d330e"
|
||||
integrity sha512-Z+hNr7RAVWxznLPuA7DIh8UNX1j9CDrUQxskw9IrBE1Dxue2lyXT+shqEIeLUjrokxIP8CMy1WkjgG3rTsd5/g==
|
||||
|
||||
resolve-from@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6"
|
||||
integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==
|
||||
|
||||
restore-cursor@^3.1.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-3.1.0.tgz#39f67c54b3a7a58cea5236d95cf0034239631f7e"
|
||||
integrity sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==
|
||||
dependencies:
|
||||
onetime "^5.1.0"
|
||||
signal-exit "^3.0.2"
|
||||
|
||||
rimraf@2.6.3:
|
||||
version "2.6.3"
|
||||
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab"
|
||||
integrity sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==
|
||||
dependencies:
|
||||
glob "^7.1.3"
|
||||
|
||||
run-async@^2.4.0:
|
||||
version "2.4.0"
|
||||
resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.4.0.tgz#e59054a5b86876cfae07f431d18cbaddc594f1e8"
|
||||
integrity sha512-xJTbh/d7Lm7SBhc1tNvTpeCHaEzoyxPrqNlvSdMfBTYwaY++UJFyXUOxAtsRUXjlqOfj8luNaR9vjCh4KeV+pg==
|
||||
dependencies:
|
||||
is-promise "^2.1.0"
|
||||
|
||||
rxjs@^6.5.3:
|
||||
version "6.5.5"
|
||||
resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.5.5.tgz#c5c884e3094c8cfee31bf27eb87e54ccfc87f9ec"
|
||||
integrity sha512-WfQI+1gohdf0Dai/Bbmk5L5ItH5tYqm3ki2c5GdWhKjalzjg93N3avFjVStyZZz+A2Em+ZxKH5bNghw9UeylGQ==
|
||||
dependencies:
|
||||
tslib "^1.9.0"
|
||||
|
||||
"safer-buffer@>= 2.1.2 < 3":
|
||||
version "2.1.2"
|
||||
resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
|
||||
integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==
|
||||
|
||||
semver@^5.5.0:
|
||||
version "5.7.1"
|
||||
resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7"
|
||||
integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==
|
||||
|
||||
semver@^6.1.2, semver@^6.3.0:
|
||||
version "6.3.0"
|
||||
resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d"
|
||||
integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==
|
||||
|
||||
shebang-command@^1.2.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea"
|
||||
integrity sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=
|
||||
dependencies:
|
||||
shebang-regex "^1.0.0"
|
||||
|
||||
shebang-regex@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3"
|
||||
integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=
|
||||
|
||||
signal-exit@^3.0.2:
|
||||
version "3.0.3"
|
||||
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c"
|
||||
integrity sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==
|
||||
|
||||
slice-ansi@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-2.1.0.tgz#cacd7693461a637a5788d92a7dd4fba068e81636"
|
||||
integrity sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==
|
||||
dependencies:
|
||||
ansi-styles "^3.2.0"
|
||||
astral-regex "^1.0.0"
|
||||
is-fullwidth-code-point "^2.0.0"
|
||||
|
||||
sprintf-js@~1.0.2:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c"
|
||||
integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=
|
||||
|
||||
string-width@^3.0.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961"
|
||||
integrity sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==
|
||||
dependencies:
|
||||
emoji-regex "^7.0.1"
|
||||
is-fullwidth-code-point "^2.0.0"
|
||||
strip-ansi "^5.1.0"
|
||||
|
||||
string-width@^4.1.0:
|
||||
version "4.2.0"
|
||||
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.0.tgz#952182c46cc7b2c313d1596e623992bd163b72b5"
|
||||
integrity sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==
|
||||
dependencies:
|
||||
emoji-regex "^8.0.0"
|
||||
is-fullwidth-code-point "^3.0.0"
|
||||
strip-ansi "^6.0.0"
|
||||
|
||||
strip-ansi@^5.1.0, strip-ansi@^5.2.0:
|
||||
version "5.2.0"
|
||||
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae"
|
||||
integrity sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==
|
||||
dependencies:
|
||||
ansi-regex "^4.1.0"
|
||||
|
||||
strip-ansi@^6.0.0:
|
||||
version "6.0.0"
|
||||
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.0.tgz#0b1571dd7669ccd4f3e06e14ef1eed26225ae532"
|
||||
integrity sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==
|
||||
dependencies:
|
||||
ansi-regex "^5.0.0"
|
||||
|
||||
strip-json-comments@^3.0.1:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.0.1.tgz#85713975a91fb87bf1b305cca77395e40d2a64a7"
|
||||
integrity sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw==
|
||||
|
||||
supports-color@^5.3.0:
|
||||
version "5.5.0"
|
||||
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f"
|
||||
integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==
|
||||
dependencies:
|
||||
has-flag "^3.0.0"
|
||||
|
||||
supports-color@^7.1.0:
|
||||
version "7.1.0"
|
||||
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.1.0.tgz#68e32591df73e25ad1c4b49108a2ec507962bfd1"
|
||||
integrity sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==
|
||||
dependencies:
|
||||
has-flag "^4.0.0"
|
||||
|
||||
table@^5.2.3:
|
||||
version "5.4.6"
|
||||
resolved "https://registry.yarnpkg.com/table/-/table-5.4.6.tgz#1292d19500ce3f86053b05f0e8e7e4a3bb21079e"
|
||||
integrity sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==
|
||||
dependencies:
|
||||
ajv "^6.10.2"
|
||||
lodash "^4.17.14"
|
||||
slice-ansi "^2.1.0"
|
||||
string-width "^3.0.0"
|
||||
|
||||
text-table@^0.2.0:
|
||||
version "0.2.0"
|
||||
resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4"
|
||||
integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=
|
||||
|
||||
through@^2.3.6:
|
||||
version "2.3.8"
|
||||
resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5"
|
||||
integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=
|
||||
|
||||
tmp@^0.0.33:
|
||||
version "0.0.33"
|
||||
resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9"
|
||||
integrity sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==
|
||||
dependencies:
|
||||
os-tmpdir "~1.0.2"
|
||||
|
||||
tslib@^1.8.1, tslib@^1.9.0:
|
||||
version "1.11.1"
|
||||
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.11.1.tgz#eb15d128827fbee2841549e171f45ed338ac7e35"
|
||||
integrity sha512-aZW88SY8kQbU7gpV19lN24LtXh/yD4ZZg6qieAJDDg+YBsJcSmLGK9QpnUjAKVG/xefmvJGd1WUmfpT/g6AJGA==
|
||||
|
||||
tsutils@^3.17.1:
|
||||
version "3.17.1"
|
||||
resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.17.1.tgz#ed719917f11ca0dee586272b2ac49e015a2dd759"
|
||||
integrity sha512-kzeQ5B8H3w60nFY2g8cJIuH7JDpsALXySGtwGJ0p2LSjLgay3NdIpqq5SoOBe46bKDW2iq25irHCr8wjomUS2g==
|
||||
dependencies:
|
||||
tslib "^1.8.1"
|
||||
|
||||
type-check@~0.3.2:
|
||||
version "0.3.2"
|
||||
resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72"
|
||||
integrity sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=
|
||||
dependencies:
|
||||
prelude-ls "~1.1.2"
|
||||
|
||||
type-fest@^0.11.0:
|
||||
version "0.11.0"
|
||||
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.11.0.tgz#97abf0872310fed88a5c466b25681576145e33f1"
|
||||
integrity sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ==
|
||||
|
||||
type-fest@^0.8.1:
|
||||
version "0.8.1"
|
||||
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d"
|
||||
integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==
|
||||
|
||||
typescript@^3.8.3:
|
||||
version "3.8.3"
|
||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.8.3.tgz#409eb8544ea0335711205869ec458ab109ee1061"
|
||||
integrity sha512-MYlEfn5VrLNsgudQTVJeNaQFUAI7DkhnOjdpAp4T+ku1TfQClewlbSuTVHiA+8skNBgaf02TL/kLOvig4y3G8w==
|
||||
|
||||
uri-js@^4.2.2:
|
||||
version "4.2.2"
|
||||
resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0"
|
||||
integrity sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==
|
||||
dependencies:
|
||||
punycode "^2.1.0"
|
||||
|
||||
v8-compile-cache@^2.0.3:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.1.0.tgz#e14de37b31a6d194f5690d67efc4e7f6fc6ab30e"
|
||||
integrity sha512-usZBT3PW+LOjM25wbqIlZwPeJV+3OSz3M1k1Ws8snlW39dZyYL9lOGC5FgPVHfk0jKmjiDV8Z0mIbVQPiwFs7g==
|
||||
|
||||
which@^1.2.9:
|
||||
version "1.3.1"
|
||||
resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a"
|
||||
integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==
|
||||
dependencies:
|
||||
isexe "^2.0.0"
|
||||
|
||||
word-wrap@~1.2.3:
|
||||
version "1.2.3"
|
||||
resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c"
|
||||
integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==
|
||||
|
||||
wrappy@1:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
|
||||
integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=
|
||||
|
||||
write@1.0.3:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/write/-/write-1.0.3.tgz#0800e14523b923a387e415123c865616aae0f5c3"
|
||||
integrity sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==
|
||||
dependencies:
|
||||
mkdirp "^0.5.1"
|
Reference in a new issue