Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ Options:
-p, --path <path> path/url to swagger scheme
-o, --output <output> output path of typescript api file (default: "./")
-n, --name <name> name of output typescript api file (default: "Api.ts")
-t, --templates <path> path to folder containing templates (default: "./src/templates")
-d, --default-as-success use "default" response status code as success response too.
some swagger schemas use "default" response status code
as success response type by default. (default: false)
Expand Down
15 changes: 9 additions & 6 deletions index.d.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@

interface GenerateApiParams {

/**
* path to swagger schema
*/
Expand All @@ -20,7 +18,12 @@ interface GenerateApiParams {
* path to folder where will been located the created api module
*/
output?: string;


/**
* path to folder containing templates (default: ./scr/templates)
*/
templates?: string;

/**
* generate type definitions for API routes (default: false)
*/
Expand All @@ -32,7 +35,7 @@ interface GenerateApiParams {
generateClient?: boolean;

/**
* use "default" response status code as success response too.
* use "default" response status code as success response too.
* some swagger schemas use "default" response status code as success response type by default.
*/
defaultResponseAsSuccess?: boolean;
Expand All @@ -44,5 +47,5 @@ interface GenerateApiParams {
generateResponses?: boolean;
}

export declare function generateApi(params: Omit<GenerateApiParams, "url">): Promise<string>
export declare function generateApi(params: Omit<GenerateApiParams, "input">): Promise<string>
export declare function generateApi(params: Omit<GenerateApiParams, "url">): Promise<string>;
export declare function generateApi(params: Omit<GenerateApiParams, "input">): Promise<string>;
50 changes: 22 additions & 28 deletions index.js
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -6,43 +6,36 @@
// License text available at https://opensource.org/licenses/MIT
// Repository https://github.com/acacode/swagger-typescript-api

const program = require('commander');
const { resolve } = require('path');
const { generateApi } = require('./src');
const { version } = require('./package.json');
const program = require("commander");
const { resolve } = require("path");
const { generateApi } = require("./src");
const { version } = require("./package.json");

program
.version(version, '-v, --version', 'output the current version')
.version(version, "-v, --version", "output the current version")
.description("Generate api via swagger scheme.\nSupports OA 3.0, 2.0, JSON, yaml.")
.requiredOption('-p, --path <path>', 'path/url to swagger scheme')
.option('-o, --output <output>', 'output path of typescript api file', './')
.option('-n, --name <name>', 'name of output typescript api file', 'Api.ts')
.requiredOption("-p, --path <path>", "path/url to swagger scheme")
.option("-o, --output <output>", "output path of typescript api file", "./")
.option("-n, --name <name>", "name of output typescript api file", "Api.ts")
.option("-t, --templates <path>", "path to folder containing templates")
.option(
'-d, --default-as-success',
"-d, --default-as-success",
'use "default" response status code as success response too.\n' +
'some swagger schemas use "default" response status code as success response type by default.',
false
'some swagger schemas use "default" response status code as success response type by default.',
false,
)
.option(
'-r, --responses',
'generate additional information about request responses\n' +
'also add typings for bad responses',
"-r, --responses",
"generate additional information about request responses\n" +
"also add typings for bad responses",
false,
)
.option('--route-types', 'generate type definitions for API routes', false)
.option('--no-client', 'do not generate an API class', false);
.option("--route-types", "generate type definitions for API routes", false)
.option("--no-client", "do not generate an API class", false);

program.parse(process.argv);

const {
path,
output,
name,
routeTypes,
client,
defaultAsSuccess,
responses,
} = program;
const { path, output, name, templates, routeTypes, client, defaultAsSuccess, responses } = program;

generateApi({
name,
Expand All @@ -52,5 +45,6 @@ generateApi({
defaultResponseAsSuccess: defaultAsSuccess,
generateResponses: responses,
input: resolve(process.cwd(), path),
output: resolve(process.cwd(), output || '.')
})
output: resolve(process.cwd(), output || "."),
templates: resolve(templates ? process.cwd() : __dirname, templates || "./src/templates"),
});
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,15 @@
"cli:debug:json": "node --nolazy --inspect-brk=9229 index.js -p ./swagger-test-cli.json -n swagger-test-cli.ts",
"cli:debug:yaml": "node --nolazy --inspect-brk=9229 index.js -p ./swagger-test-cli.yaml -n swagger-test-cli.ts",
"cli:help": "node index.js -h",
"test:all": "npm-run-all generate validate test:routeTypes test:noClient test:defaultAsSuccess test:responses --continue-on-error",
"test:all": "npm-run-all generate validate test:routeTypes test:noClient test:defaultAsSuccess test:responses test:templates --continue-on-error",
"generate": "node tests/generate.js",
"generate:debug": "node --nolazy --inspect-brk=9229 tests/generate.js",
"validate": "node tests/validate.js",
"validate:debug": "node --nolazy --inspect-brk=9229 tests/validate.js",
"test:routeTypes": "node tests/spec/routeTypes/test.js",
"test:noClient": "node tests/spec/noClient/test.js",
"test:defaultAsSuccess": "node tests/spec/defaultAsSuccess/test.js",
"test:templates": "node tests/spec/templates/test.js",
"test:responses": "node tests/spec/responses/test.js"
},
"author": "acacode",
Expand Down
2 changes: 2 additions & 0 deletions src/config.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
const config = {
/** CLI flag */
templates: "./templates",
/** CLI flag */
generateResponses: false,
/** CLI flag */
Expand Down
14 changes: 4 additions & 10 deletions src/files.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,15 @@ const _ = require("lodash");
const fs = require("fs");
const { resolve } = require("path");

const getFileContent = path =>
fs.readFileSync(path, { encoding: 'UTF-8' })
const getFileContent = (path) => fs.readFileSync(path, { encoding: "UTF-8" });

const pathIsExist = path =>
path && fs.existsSync(path)
const pathIsExist = (path) => path && fs.existsSync(path);

const createFile = (pathTo, fileName, content) =>
fs.writeFileSync(resolve(__dirname, pathTo, `./${fileName}`), content, _.noop)

const getTemplate = templateName =>
getFileContent(resolve(__dirname, `./templates/${templateName}.mustache`))
fs.writeFileSync(resolve(__dirname, pathTo, `./${fileName}`), content, _.noop);

module.exports = {
getTemplate,
createFile,
pathIsExist,
getFileContent,
}
};
12 changes: 7 additions & 5 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,16 @@
const mustache = require("mustache");
const prettier = require("prettier");
const _ = require("lodash");
const { resolve } = require("path");
const { parseSchemas } = require("./schema");
const { parseRoutes, groupRoutes } = require("./routes");
const { createApiConfig } = require("./apiConfig");
const { getModelType } = require("./modelTypes");
const { getSwaggerObject, fixSwaggerScheme } = require("./swagger");
const { createComponentsMap, filterComponentsMap } = require("./components");
const { getTemplate, createFile, pathIsExist } = require("./files");
const { createFile, pathIsExist } = require("./files");
const { addToConfig, config } = require("./config");
const { getTemplates } = require("./templates");

mustache.escape = (value) => value;

Expand All @@ -33,6 +35,7 @@ module.exports = {
output,
url,
name,
templates = resolve(__dirname, config.templates),
generateResponses = config.generateResponses,
defaultResponseAsSuccess = config.defaultResponseAsSuccess,
generateRouteTypes = config.generateRouteTypes,
Expand All @@ -44,9 +47,12 @@ module.exports = {
generateRouteTypes,
generateClient,
generateResponses,
templates,
});
getSwaggerObject(input, url)
.then(({ usageSchema, originalSchema }) => {
const { apiTemplate, clientTemplate, routeTypesTemplate } = getTemplates();

console.log("☄️ start generating your typescript api");

fixSwaggerScheme(usageSchema, originalSchema);
Expand All @@ -58,10 +64,6 @@ module.exports = {

const { info, paths, servers, components } = usageSchema;

const apiTemplate = getTemplate("api");
const clientTemplate = getTemplate("client");
const routeTypesTemplate = getTemplate("route-types");

const componentsMap = createComponentsMap(components);
const schemasMap = filterComponentsMap(componentsMap, "schemas");

Expand Down
20 changes: 20 additions & 0 deletions src/templates.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
const { getFileContent } = require("./files");
const { config } = require("./config");
const { resolve } = require("path");

const getTemplates = () => {
console.log(`✨ try to read templates from directory "${config.templates}"`);

return {
apiTemplate: getTemplate("api"),
clientTemplate: config.generateClient ? getTemplate("client") : null,
routeTypesTemplate: config.generateRouteTypes ? getTemplate("route-types") : null,
};
};

const getTemplate = (templateName) =>
getFileContent(resolve(config.templates, `./${templateName}.mustache`));

module.exports = {
getTemplates,
};
60 changes: 60 additions & 0 deletions tests/spec/templates/schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
{
"swagger": "2.0",
"info": {
"version": "1.0.0",
"title": "Swagger Petstore",
"description": "A sample API that uses a petstore as an example to demonstrate features in the swagger-2.0 specification",
"termsOfService": "http://swagger.io/terms/",
"contact": {
"name": "Swagger API Team"
},
"license": {
"name": "MIT"
}
},
"host": "petstore.swagger.io",
"basePath": "/api",
"schemes": ["http"],
"consumes": ["application/json"],
"produces": ["application/json"],
"paths": {
"/pets": {
"get": {
"description": "Returns all pets from the system that the user has access to",
"produces": ["application/json"],
"responses": {
"200": {
"description": "A list of pets.",
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/Pet"
}
}
}
}
}
}
},
"definitions": {
"Pet": {
"type": "object",
"required": ["id", "name"],
"properties": {
"id": {
"type": "integer",
"format": "int64"
},
"name": {
"type": "string"
},
"tag": {
"type": "string"
},
"multiple": {
"type": ["string", "number"]
}
}
}
}
}
Empty file added tests/spec/templates/schema.ts
Empty file.
6 changes: 6 additions & 0 deletions tests/spec/templates/spec_templates/api.mustache
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/* tslint:disable */
/* eslint-disable */

{{#modelTypes}}
export {{typeIdentifier}} {{name}} {{content}}
{{/modelTypes}}
Loading