Merge branch 'typescript-fetch-basic-unit-test' of https://github.com/leonyu/swagger-codegen into leonyu-typescript-fetch-basic-unit-test

This commit is contained in:
wing328
2016-05-13 18:02:38 +08:00
57 changed files with 13374 additions and 3868 deletions

View File

@@ -26,7 +26,6 @@ public class TypeScriptFetchClientCodegen extends AbstractTypeScriptClientCodege
super.processOpts();
supportingFiles.add(new SupportingFile("api.mustache", "", "api.ts"));
supportingFiles.add(new SupportingFile("git_push.sh.mustache", "", "git_push.sh"));
supportingFiles.add(new SupportingFile("assign.ts", "", "assign.ts"));
supportingFiles.add(new SupportingFile("README.md", "", "README.md"));
supportingFiles.add(new SupportingFile("package.json.mustache", "", "package.json"));
supportingFiles.add(new SupportingFile("typings.json.mustache", "", "typings.json"));

View File

@@ -1,44 +1,54 @@
# TypeScript-Fetch
This generator creates TypeScript/JavaScript client that utilizes [Fetch API](https://fetch.spec.whatwg.org/). The codegen Node module can be used in the following environments:
This generator creates TypeScript/JavaScript client that utilizes [Fetch API](https://fetch.spec.whatwg.org/). The generated Node module can be used in the following environments:
* Node.JS
Environment
* Node.js
* Webpack
* Browserify
It is usable in both TypeScript and JavaScript. In TypeScript, the definition should be automatically resolved via `typings` in `package.json`. ([Reference](http://www.typescriptlang.org/docs/handbook/typings-for-npm-packages.html))
Language level
* ES5 - you must have a Promises/A+ library installed
* ES6
Module system
* CommonJS
* ES6 module system
It can be used in both TypeScript and JavaScript. In TypeScript, the definition should be automatically resolved via `package.json`. ([Reference](http://www.typescriptlang.org/docs/handbook/typings-for-npm-packages.html))
### Installation ###
`swagger-codegen` does not generate JavaScript directly. The codegen Node module comes with `package.json` that bundles `typescript` and `typings` so it can self-compile. The self-compile is normally run automatically via the `npm` `postinstall` script of `npm install`.
`swagger-codegen` does not generate JavaScript directly. The generated Node module comes with `package.json` that bundles `typescript` and `typings` so it can self-compile during `prepublish` stage. The should be run automatically during `npm install` or `npm publish`.
CAVEAT: Due to [privilege implications](https://docs.npmjs.com/misc/scripts#user), `npm` may skip `postinstall` script if the user is `root`. You would need to manually invoke `npm install` or `npm run postinstall` for the codegen module if that's the case.
CAVEAT: Due to [privilege implications](https://docs.npmjs.com/misc/scripts#user), `npm` would skip all scripts if the user is `root`. You would need to manually run it with `npm run prepublish` or run `npm install --unsafe-perm`.
#### NPM repository ###
If you remove `"private": true` from `package.json`, you may publish the module to NPM. In which case, you would be able to install the module as any other NPM module.
#### NPM ####
You may publish the module to NPM. In this case, you would be able to install the module as any other NPM module. It maybe useful to use [scoped packages](https://docs.npmjs.com/misc/scope).
It maybe useful to use [scoped packages](https://docs.npmjs.com/misc/scope).
You can also use `npm link` to link the module. However, this would not modify `package.json` of the installing project, as such you would need to relink everytime you deploy that project.
#### NPM install local file ###
You should be able to directly install the module using `npm install file:///codegen_path`.
You can also directly install the module using `npm install file_path`. If you do `npm install file_path --save`, NPM will save relative path to `package.json`. In this case, `npm install` and `npm shrinkwrap` may misbehave. You would need to manually edit `package.json` and replace it with absolute path.
NOTES: If you do `npm install file:///codegen_path --save` NPM might convert your path to relative path, maybe have adverse affect. `npm install` and `npm shrinkwrap` may misbehave if the installation path is not absolute.
#### direct copy/symlink ###
You may also simply copy or symlink the codegen into a directly under your project. The syntax of the usage would differ if you take this route. (See below)
### Usage ###
With ES6 module syntax, the following syntaxes are supported:
Regardless of which method you deployed your NPM module, the ES6 module syntaxes are as follows:
```
import * as localName from 'npmName';
import {operationId} from 'npmName';
```
The CommonJS syntax is as follows:
```
import localName = require('npmName');
```
#### Direct copy/symlink ####
You may also simply copy or symlink the generated module into a directory under your project. The syntax of this is as follows:
With ES6 module syntax, the following syntaxes are supported:
```
import * as localName from './symlinkDir';
import {operationId} from './symlinkDir';
```
With CommonJS, the following syntaxes are supported:
The CommonJS syntax is as follows:
```
import localName = require('npmName');
import localName = require('./symlinkDir')';
```
```

View File

@@ -1,7 +1,23 @@
import * as querystring from 'querystring';
import * as fetch from 'isomorphic-fetch';
import {assign} from './assign';
import * as querystring from "querystring";
import * as url from "url";
import * as isomorphicFetch from "isomorphic-fetch";
{{^supportsES6}}
import * as assign from "core-js/library/fn/object/assign";
{{/supportsES6}}
interface Dictionary<T> { [index: string]: T; }
export interface FetchAPI { (url: string, init?: any): Promise<any>; }
export class BaseAPI {
basePath: string;
fetch: FetchAPI;
constructor(basePath: string = "{{basePath}}", fetch: FetchAPI = isomorphicFetch) {
this.basePath = basePath;
this.fetch = fetch;
}
}
{{#models}}
{{#model}}
@@ -13,24 +29,20 @@ import {assign} from './assign';
export interface {{classname}} {{#parent}}extends {{{parent}}} {{/parent}}{
{{#vars}}
{{#description}}
/**
* {{{description}}}
*/
{{/description}}
"{{name}}"{{^required}}?{{/required}}: {{#isEnum}}{{classname}}.{{{datatypeWithEnum}}}{{/isEnum}}{{^isEnum}}{{{datatype}}}{{/isEnum}};
"{{name}}"{{^required}}?{{/required}}: {{#isEnum}}{{classname}}{{{datatypeWithEnum}}}{{/isEnum}}{{^isEnum}}{{{datatype}}}{{/isEnum}};
{{/vars}}
}
{{#hasEnums}}
export namespace {{classname}} {
{{#vars}}
{{#isEnum}}
export type {{datatypeWithEnum}} = {{#allowableValues}}{{#values}}'{{.}}'{{^-last}} | {{/-last}}{{/values}}{{/allowableValues}};
export type {{classname}}{{datatypeWithEnum}} = {{#allowableValues}}{{#values}}"{{.}}"{{^-last}} | {{/-last}}{{/values}}{{/allowableValues}};
{{/isEnum}}
{{/vars}}
}
{{/hasEnums}}
{{/model}}
{{/models}}
@@ -38,96 +50,72 @@ export type {{datatypeWithEnum}} = {{#allowableValues}}{{#values}}'{{.}}'{{^-las
{{#apiInfo}}
{{#apis}}
{{#operations}}
//export namespace {{package}} {
'use strict';
{{#description}}
/**
* {{&description}}
*/
/**
* {{&description}}
*/
{{/description}}
export class {{classname}} {
protected basePath = '{{basePath}}';
public defaultHeaders : any = {};
constructor(basePath?: string) {
if (basePath) {
this.basePath = basePath;
}
}
export class {{classname}} extends BaseAPI {
{{#operation}}
/**
* {{summary}}
* {{notes}}
{{#allParams}}* @param {{paramName}} {{description}}
{{/allParams}}*/
public {{nickname}} (params: { {{#allParams}} {{paramName}}{{^required}}?{{/required}}: {{{dataType}}};{{/allParams}} }, extraQueryParams?: any, extraFetchParams?: any ) : Promise<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}{}{{/returnType}}> {
const localVarPath = this.basePath + '{{path}}'{{#pathParams}}
.replace('{' + '{{baseName}}' + '}', String(params.{{paramName}})){{/pathParams}};
let queryParameters: any = assign({}, extraQueryParams);
let headerParams: any = assign({}, this.defaultHeaders);
{{#hasFormParams}}
let formParams: any = {};
headerParams['Content-Type'] = 'application/x-www-form-urlencoded';
{{/hasFormParams}}
{{#hasBodyParam}}
headerParams['Content-Type'] = 'application/json';
{{/hasBodyParam}}
/** {{#summary}}
* {{summary}}{{/summary}}{{#notes}}
* {{notes}}{{/notes}}{{#allParams}}
* @param {{paramName}} {{description}}{{/allParams}}
*/
{{nickname}}({{#hasParams}}params: { {{#allParams}} {{paramName}}{{^required}}?{{/required}}: {{{dataType}}};{{/allParams}} }{{/hasParams}}): Promise<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}any{{/returnType}}> {
{{#allParams}}
{{#required}}
// verify required parameter '{{paramName}}' is set
if (params.{{paramName}} == null) {
throw new Error('Missing required parameter {{paramName}} when calling {{nickname}}');
}
// verify required parameter "{{paramName}}" is set
if (params["{{paramName}}"] == null) {
throw new Error("Missing required parameter {{paramName}} when calling {{nickname}}");
}
{{/required}}
{{/allParams}}
{{#queryParams}}
if (params.{{paramName}} !== undefined) {
queryParameters['{{baseName}}'] = params.{{paramName}};
}
const baseUrl = `${this.basePath}{{path}}`{{#pathParams}}
.replace(`{${"{{baseName}}"}}`, `${ params.{{paramName}} }`){{/pathParams}};
let urlObj = url.parse(baseUrl, true);
{{#hasQueryParams}}
urlObj.query = {{#supportsES6}}Object.{{/supportsES6}}assign({}, urlObj.query, { {{#queryParams}}
"{{baseName}}": params.{{paramName}},{{/queryParams}}
});
{{/hasQueryParams}}
let fetchOptions: RequestInit = { method: "{{httpMethod}}" };
{{/queryParams}}
{{#headerParams}}
headerParams['{{baseName}}'] = params.{{paramName}};
{{/headerParams}}
{{#formParams}}
formParams['{{baseName}}'] = params.{{paramName}};
{{/formParams}}
let fetchParams = {
method: '{{httpMethod}}',
headers: headerParams,
{{#bodyParam}}body: JSON.stringify(params.{{paramName}}),
{{/bodyParam}}
{{#hasFormParams}}body: querystring.stringify(formParams),
{{/hasFormParams}}
};
if (extraFetchParams) {
fetchParams = assign(fetchParams, extraFetchParams);
}
let localVarPathWithQueryParameters = localVarPath + (localVarPath.indexOf('?') !== -1 ? '&' : '?') + querystring.stringify(queryParameters);
return fetch(localVarPathWithQueryParameters, fetchParams).then((response) => {
if (response.status >= 200 && response.status < 300) {
return response.json();
} else {
let error = new Error(response.statusText);
(error as any).response = response;
throw error;
}
});
let contentTypeHeader: Dictionary<string>;
{{#hasFormParams}}
contentTypeHeader = { "Content-Type": "application/x-www-form-urlencoded" };
fetchOptions.body = querystring.stringify({ {{#formParams}}
"{{baseName}}": params.{{paramName}},{{/formParams}}
});
{{/hasFormParams}}
{{#hasBodyParam}}
contentTypeHeader = { "Content-Type": "application/json" };{{#bodyParam}}
if (params["{{paramName}}"]) {
fetchOptions.body = JSON.stringify(params["{{paramName}}"] || {});
}{{/bodyParam}}
{{/hasBodyParam}}
{{#hasHeaderParam}}
fetchOptions.headers = {{#supportsES6}}Object.{{/supportsES6}}assign({ {{#headerParams}}
"{{baseName}}": params.{{paramName}},{{/headerParams}}
}, contentTypeHeader);
{{/hasHeaderParam}}
{{^hasHeaderParam}}
if (contentTypeHeader) {
fetchOptions.headers = contentTypeHeader;
}
{{/operation}}
{{/hasHeaderParam}}
return this.fetch(url.format(urlObj), fetchOptions).then((response) => {
if (response.status >= 200 && response.status < 300) {
return response{{#returnType}}.json(){{/returnType}};
} else {
throw response;
}
});
}
//}
{{/operation}}
}
{{/operations}}
{{/apis}}
{{/apiInfo}}

View File

@@ -1,18 +0,0 @@
export function assign (target: any, ...args: any[]) {
'use strict';
if (target === undefined || target === null) {
throw new TypeError('Cannot convert undefined or null to object');
}
var output = Object(target);
for (let source of args) {
if (source !== undefined && source !== null) {
for (var nextKey in source) {
if (source.hasOwnProperty(nextKey)) {
output[nextKey] = source[nextKey];
}
}
}
}
return output;
};

View File

@@ -1,15 +1,15 @@
{
"name": "{{#npmName}}{{{npmName}}}{{/npmName}}{{^npmName}}typescript-fetch-api{{/npmName}}",
"version": "{{#npmVersion}}{{{npmVersion}}}{{/npmVersion}}{{^npmVersion}}0.0.0{{/npmVersion}}",
"private": true,
"main": "./dist/api.js",
"browser": "./dist/api.js",
"typings": "./dist/api.d.ts",
"dependencies": {
"isomorphic-fetch": "^2.2.1"
{{^supportsES6}}"core-js": "^2.4.0",
{{/supportsES6}}"isomorphic-fetch": "^2.2.1"
},
"scripts" : {
"install" : "typings install && tsc"
"prepublish" : "typings install && tsc"
},
"devDependencies": {
"typescript": "^1.8.10",

View File

@@ -1,9 +1,9 @@
{
"version": false,
"dependencies": {},
"ambientDependencies": {
{{^supportsES6}} "es6-promise": "registry:dt/es6-promise#0.0.0+20160423074304",
{{/supportsES6}} "node": "registry:dt/node#4.0.0+20160423143914",
"ambientDependencies": { {{^supportsES6}}
"core-js": "registry:dt/core-js#0.0.0+20160317120654",{{/supportsES6}}
"node": "registry:dt/node#4.0.0+20160423143914",
"isomorphic-fetch": "registry:dt/isomorphic-fetch#0.0.0+20160505171433"
}
}