Skip to content

Commit

Permalink
Add code style rules
Browse files Browse the repository at this point in the history
  • Loading branch information
anilcse committed Sep 25, 2019
1 parent 32f6f38 commit c5579f6
Show file tree
Hide file tree
Showing 6 changed files with 98 additions and 23 deletions.
24 changes: 24 additions & 0 deletions .eslintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"env": {
"node": true,
"es6": true
},
"parserOptions": {
"sourceType": "module",
"ecmaVersion": 9
},
"rules": {
"padding-line-between-statements": [
"error",
{
"blankLine": "always",
"prev": "*",
"next": "return"
}
],
"quotes": [
"error",
"double"
]
}
}
3 changes: 3 additions & 0 deletions .jshintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"esversion": 9
}
19 changes: 16 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,23 @@
# JS-SDKGen

JS-SDKGen is JavaScript API SDK Code generator, based on json file generated for api docs by Swagger or apidocjs or optionally your own json file with any shape with transform function. It just requires a apidoc definition (swagger and apidocjs genenrated api docs aslo supported now) and it generates the JavaScript SDK for you. Thus eliminate the work of writing your own SDK. It can run in both browser(a tool can be made) and node.
JS-SDKGen is a JavaScript SDK Code generator for your API. It uses apidoc definitions from swagger or apidocjs and generates the Javascript SDK automatically. Along with SDK, it also generates SDK usage documentation, thus saving hours of work for you in writing SDK & usage documentation. More importantly, it eliminates the manual errors. Optionally you can use your own json file with any shape with transform function.

## Installation

### Prerequisites

```sh
Node.js
```

### Install

```sh
npm install -g js-sdkgen
```

### Usage
```sh
js-sdkgen --json-file=api-docs.json name=MySDK --version=1.0.0 base-url=https://vitwit.com/api --requiredHeaders accoundId,key --optionalHeaders name
```

Expand All @@ -15,7 +27,7 @@ Below are parameter available for node cli while generating SDK.
| ------------------- | ----- | -------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------- |
| `--json-file` | `-f` | path of json | required (if not provided will look for 'api-docs.json' file in current directory) |
| `--js-file` | `-j` | path of a js file which named exports two function `transformJson` and `transformOperations` | not required if json is already in below mentioned format or no operation's response data need to be transformed | |
| `--base-url` | `-b` | base url of your app, will be passed axios instance | required |
| `--base-url` | `-b` | base url of your application (API endpoint), will be passed axios instance | required |
| `--name` | `-n` | it will be name of generated sdk class | optional |
| `--version` | `-v` | version of sdk | optional |
| `--requiredHeaders` | `-r` | requirdHeaders params will berequired to pass when initiate the sdk class on frontend |
Expand All @@ -30,7 +42,8 @@ const mySDK = new MySDK({
});
```

### Mandatory Headers & Optional Headers?

### Mandatory Headers & Optional Headers

This is a tricky part in the SDK generation. As we are automating the SDK generation, we need to understand, what are all the headers we need for our APIs. For example, AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY are the required configuration credentials to use AWS SDKs. In the same way, if your SDK needs any credentials that need to be sent for every API request, you need to mention them as mandatory headers in headers configuration.

Expand Down
13 changes: 12 additions & 1 deletion src/cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@ import arg from "arg";
import { createProject } from "./main";
import { printManPage } from "./utils";

/**
*
*
* @param {*} rawArgs
* @returns
*/
function parseArgumentsIntoOptions(rawArgs) {
let args;
try {
Expand All @@ -21,7 +27,6 @@ function parseArgumentsIntoOptions(rawArgs) {
"-f": "--js-file",
"-v": "--version",
"-b": "--base-url",
"-h": "--help",
"-o": "--optional-headers",
"-r": "--required-headers",
"-h": "--help"
Expand Down Expand Up @@ -56,6 +61,12 @@ function parseArgumentsIntoOptions(rawArgs) {
};
}

/**
*
*
* @export
* @param {*} args
*/
export async function cli(args) {
let options = parseArgumentsIntoOptions(args);

Expand Down
43 changes: 32 additions & 11 deletions src/codeStrings.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,17 @@
import chalk from "chalk";
import { notEmptyObj } from "./utils";

/**
*
*
* @param {*} {
* sdkName,
* version,
* baseUrl,
* requiredHeaders,
* optionalHeaders,
* transformOperations
* }
* @returns
*/
const stringOne = ({
sdkName,
version,
Expand All @@ -11,33 +23,38 @@ const stringOne = ({
return `
import axios from "axios";
${
transformOperations
? "import { transformOperations } from './transformOperations'"
: ""
}
transformOperations ?
"import { transformOperations } from './transformOperations'"
: ""
}
export default class ${sdkName} {
constructor( headersObj ={}) {${
version ? "\n this.version =" : ""
}'${version}'
}'${version}'
this.requiredHeaders = '${requiredHeaders}';
this.optionalHeaders = '${optionalHeaders}';
this.name = "${sdkName}";
if(this.requiredHeaders){
this.requiredHeaders.split(',').forEach(header => {
if (Object.keys(headersObj).indexOf(header) < 0) {
throw Error("All required header to initiate not passed");
}
});
}
this.configs = {
baseURL: "${baseUrl}",
headers: {
...headersObj,
}
}
const instance = axios.create({
...this.configs
});
// get authorization on every request
instance.interceptors.request.use(
configs => {
Expand All @@ -48,10 +65,12 @@ export default class ${sdkName} {
}
configs.headers = this.configs.headers
configs.baseURL = this.configs.baseURL
return configs
},
error => Promise.reject(error)
);
this.axiosInstance = instance;
}
Expand All @@ -70,7 +89,9 @@ export default class ${sdkName} {
error: null,
data: null
};
let data = _data;
if (isFormData) {
const formdata = new FormData();
Object.entries(_data).forEach(arr => {
Expand Down Expand Up @@ -162,17 +183,17 @@ function functionSignature({
return `
${operationName}({ _params,_pathParams,${
requestMethod === "PUT" || requestMethod === "POST" ? "..._data" : ""
} } = {}) {
} } = {}) {
return this.fetchApi({
method: "${requestMethod}",${
isFormData ? "\n isFormData: true," : ""
}
}
_url: '${url}',${
requestMethod === "PUT" || requestMethod === "POST" ? "\n _data," : ""
}
}
_params,${hasPathParams ? "\n _pathParams," : ""}${
transformResponse ? getTransformResString(operationName) : ""
}
}
});
}
`;
Expand Down
19 changes: 11 additions & 8 deletions src/codgen.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
operationMarkdownEnd,
responseMarkdown
} from "./codeStrings";

import {
extractPathParams,
toCamelCase,
Expand All @@ -18,10 +19,12 @@ import {
getDefinitionKey,
removeKeys
} from "./utils";

import cp from "cp";

const isGoJson = json => {
const api = json && json[0];

return api && api.type && api.url && api.name && api.parameter.fields;
};
const isSwaggerJson = json => {
Expand All @@ -32,7 +35,7 @@ const stringifyObj = obj =>
.map(key => {
return `${key}:${
typeof obj[key] !== "object" ? obj[key] : JSON.stringify(obj[key])
}`;
}`;
})
.join()
.replace(/:/g, "-");
Expand Down Expand Up @@ -130,7 +133,7 @@ export function generateSDK({
_jsonFile.definitions[getDefinitionKey(schema)];
storeMarkdown.push(
` /** ${getDefinitionKey(schema)} modal,${
schema.type ? "type - " + schema.type + "," : ""
schema.type ? "type - " + schema.type + "," : ""
} ${stringifyObj(removeKeys(other, "in"))} */`
);
thisOperationBodyParamsModals.push(getDefinitionKey(schema));
Expand All @@ -144,26 +147,26 @@ export function generateSDK({
}
});
if (pathParams.length) {
storeMarkdown.push(` _pathParams: {\n`);
storeMarkdown.push(" _pathParams: {\n");
pathParams.forEach(({ name, type, ...other }) => {
storeMarkdown.push(
` ${name}:${type}, /** ${stringifyObj({
...removeKeys(other, "in")
})} */ \n`
);
});
storeMarkdown.push(` }`);
storeMarkdown.push(" }");
}
if (qparams.length) {
storeMarkdown.push(` _params: {\n`);
storeMarkdown.push(" _params: {\n");
qparams.forEach(({ name, type, ...other }) => {
storeMarkdown.push(
` ${name}:${type}, /** ${stringifyObj({
...removeKeys(other, "in")
})} */ \n`
);
});
storeMarkdown.push(` }`);
storeMarkdown.push(" }");
}
storeMarkdown.push(markdownCodeBlockEnd());
};
Expand Down Expand Up @@ -224,7 +227,7 @@ export function generateSDK({
...thisOperationResponesModals
];
if (thisOperationsModals.length) {
storeMarkdown.push(`\n###### `);
storeMarkdown.push("\n###### ");
thisOperationsModals.forEach(a =>
storeMarkdown.push(appendModalLink(a))
);
Expand Down Expand Up @@ -285,7 +288,7 @@ export function generateSDK({
if (isSwaggerGenerated) {
const generateModalsReadeMe = json => {
const definitions = json.definitions;
storeMarkdown.push(`\n# Modal Definations\n`);
storeMarkdown.push("\n# Modal Definations\n");
Object.keys(definitions).forEach(key => {
storeMarkdown.push(
`\n ### ${key}-modal\n \`\`\`json\n${JSON.stringify(
Expand Down

0 comments on commit c5579f6

Please sign in to comment.