Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[TypeScript][Aurelia] Create Aurelia code generator #5987 #5991

Merged
merged 6 commits into from
Jul 23, 2017
Merged
Show file tree
Hide file tree
Changes from all 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
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
package io.swagger.codegen.languages;

import io.swagger.codegen.*;

import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.TreeSet;

public class TypeScriptAureliaClientCodegen extends AbstractTypeScriptClientCodegen {

public static final String NPM_NAME = "npmName";
public static final String NPM_VERSION = "npmVersion";

protected String npmName = null;
protected String npmVersion = "1.0.0";

public TypeScriptAureliaClientCodegen() {
super();

apiTemplateFiles.put("api.mustache", ".ts");

// clear import mapping (from default generator) as TS does not use it
// at the moment
importMapping.clear();

outputFolder = "generated-code/typescript-aurelia";
embeddedTemplateDir = templateDir = "typescript-aurelia";
this.cliOptions.add(new CliOption(NPM_NAME, "The name under which you want to publish generated npm package"));
this.cliOptions.add(new CliOption(NPM_VERSION, "The version of your npm package"));
}

@Override
public void processOpts() {
super.processOpts();

if (additionalProperties.containsKey(NPM_NAME)) {
this.setNpmName(additionalProperties.get(NPM_NAME).toString());
}

if (additionalProperties.containsKey(NPM_VERSION)) {
this.setNpmVersion(additionalProperties.get(NPM_VERSION).toString());
}

// Set supporting files
supportingFiles.add(new SupportingFile("models.mustache", "", "models.ts"));
supportingFiles.add(new SupportingFile("index.ts.mustache", "", "index.ts"));
supportingFiles.add(new SupportingFile("Api.ts.mustache", "", "Api.ts"));
supportingFiles.add(new SupportingFile("AuthStorage.ts.mustache", "", "AuthStorage.ts"));
supportingFiles.add(new SupportingFile("git_push.sh.mustache", "", "git_push.sh"));
supportingFiles.add(new SupportingFile("README.md", "", "README.md"));
supportingFiles.add(new SupportingFile("package.json.mustache", "", "package.json"));
supportingFiles.add(new SupportingFile("tsconfig.json.mustache", "", "tsconfig.json"));
supportingFiles.add(new SupportingFile("tslint.json.mustache", "", "tslint.json"));
supportingFiles.add(new SupportingFile("gitignore", "", ".gitignore"));
}

@Override
public String getName() {
return "typescript-aurelia";
}

@Override
public String getHelp() {
return "Generates a TypeScript client library for the Aurelia framework (beta).";
}

public String getNpmName() {
return npmName;
}

public void setNpmName(String npmName) {
this.npmName = npmName;
}

public String getNpmVersion() {
return npmVersion;
}

public void setNpmVersion(String npmVersion) {
this.npmVersion = npmVersion;
}

@Override
public Map<String, Object> postProcessOperations(Map<String, Object> objs) {
objs = super.postProcessOperations(objs);

HashSet<String> modelImports = new HashSet<>();
Map<String, Object> operations = (Map<String, Object>) objs.get("operations");
List<CodegenOperation> operationList = (List<CodegenOperation>) operations.get("operation");
for (CodegenOperation op : operationList) {
// Aurelia uses "asGet", "asPost", ... methods; change the method format
op.httpMethod = initialCaps(op.httpMethod.toLowerCase());

// Collect models to be imported
for (CodegenParameter param : op.allParams) {
if (!param.isPrimitiveType) {
modelImports.add(param.dataType);
}
}
if (op.returnBaseType != null && !op.returnTypeIsPrimitive) {
modelImports.add(op.returnBaseType);
}
}

objs.put("modelImports", modelImports);

return objs;
}

@Override
public Map<String, Object> postProcessModels(Map<String, Object> objs) {
// process enum in models
List<Object> models = (List<Object>) postProcessModelsEnum(objs).get("models");
for (Object _mo : models) {
Map<String, Object> mo = (Map<String, Object>) _mo;
CodegenModel cm = (CodegenModel) mo.get("model");
cm.imports = new TreeSet(cm.imports);
for (CodegenProperty var : cm.vars) {
// name enum with model name, e.g. StatuEnum => PetStatusEnum
if (Boolean.TRUE.equals(var.isEnum)) {
var.datatypeWithEnum = var.datatypeWithEnum.replace(var.enumName, cm.classname + var.enumName);
var.enumName = cm.classname + var.enumName;
}
}
}

return objs;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ io.swagger.codegen.languages.SwiftCodegen
io.swagger.codegen.languages.TizenClientCodegen
io.swagger.codegen.languages.TypeScriptAngular2ClientCodegen
io.swagger.codegen.languages.TypeScriptAngularClientCodegen
io.swagger.codegen.languages.TypeScriptAureliaClientCodegen
io.swagger.codegen.languages.TypeScriptFetchClientCodegen
io.swagger.codegen.languages.TypeScriptJqueryClientCodegen
io.swagger.codegen.languages.TypeScriptNodeClientCodegen
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
{{>licenseInfo}}
import { HttpClient } from 'aurelia-http-client';
import { AuthStorage } from './AuthStorage';

const BASE_PATH = '{{{basePath}}}'.replace(/\/+$/, '');

export class Api {
basePath: string;
httpClient: HttpClient;
authStorage: AuthStorage;

constructor(httpClient: HttpClient, authStorage: AuthStorage, basePath: string = BASE_PATH) {
this.basePath = basePath;
this.httpClient = httpClient;
this.authStorage = authStorage;
}

/**
* Encodes a query string.
*
* @param params The params to encode.
* @return An encoded query string.
*/
protected queryString(params: { [key: string]: any }): string {
const queries = [];
for (let key in params) {
const value = this.toString(params[key]);
if (value != null) {
queries.push(`${key}=${encodeURIComponent(value)}`);
}
}

return queries.join('&');
}

/**
* Converts a value to string.
*
* @param value The value to convert.
*/
protected toString(value: any): string | null {
if (value === null) {
return null;
}
switch (typeof value) {
case 'undefined': return null;
case 'boolean': return value ? 'true' : 'false';
case 'string': return value;
default: return '' + value;
}
}

/**
* Ensures that a given parameter is set.
*
* @param context A name for the callee's context.
* @param params The parameters being set.
* @param paramName The required parameter to check.
*/
protected ensureParamIsSet<T>(context: string, params: T, paramName: keyof T): void {
if (null === params[paramName]) {
throw new Error(`Missing required parameter ${paramName} when calling ${context}`);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
{{>licenseInfo}}
/**
* Class to storage authentication data
*/
export class AuthStorage {
private storage: Map<string, string>;

constructor() {
this.storage = new Map();
}
{{#authMethods}}

/**
* Sets the {{name}} auth method value.
*
* @param value The new value to set for {{name}}.
*/
set{{name}}(value: string): this {
this.storage.set('{{name}}', value);
return this;
}

/**
* Removes the {{name}} auth method value.
*/
remove{{name}}(): this {
this.storage.delete('{{name}}');
return this;
}

/**
* Gets the {{name}} auth method value.
*/
get{{name}}(): null | string {
return this.storage.get('{{name}}') || null;
}
{{/authMethods}}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# TypeScript-Aurelia

This generator creates TypeScript/JavaScript client that is injectable by [Aurelia](http://aurelia.io/).
The generated Node module can be used in the following environments:

Environment
* Node.js
* Webpack
* Browserify

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 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` 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 ####
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).

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 every time you deploy that project.

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.

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';
```
The CommonJS syntax is as follows:
```
import localName = require('./symlinkDir')';
```
Loading