This commit is contained in:
Rinat Arsaev 2018-09-26 22:36:56 +03:00
parent 23c816cba1
commit fa2397dbd7
20 changed files with 1185 additions and 932 deletions

2
.prettierignore Normal file
View File

@ -0,0 +1,2 @@
package.json
package-lock.json

View File

@ -1 +1 @@
require('../lib/cli').default();
require("../lib/cli").default();

235
package-lock.json generated
View File

@ -77,12 +77,74 @@
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
"integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg="
},
"ansi-styles": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
"integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
"dev": true
},
"argparse": {
"version": "1.0.10",
"resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
"integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
"dev": true,
"requires": {
"sprintf-js": "~1.0.2"
}
},
"assertion-error": {
"version": "1.0.2",
"resolved": "http://r.npm.sankuai.com/assertion-error/download/assertion-error-1.0.2.tgz",
"integrity": "sha1-E8pRXYYgbaC6xm6DTdOX2HWBCUw=",
"dev": true
},
"babel-code-frame": {
"version": "6.26.0",
"resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz",
"integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=",
"dev": true,
"requires": {
"chalk": "^1.1.3",
"esutils": "^2.0.2",
"js-tokens": "^3.0.2"
},
"dependencies": {
"ansi-regex": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
"integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
"dev": true
},
"chalk": {
"version": "1.1.3",
"resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
"integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
"dev": true,
"requires": {
"ansi-styles": "^2.2.1",
"escape-string-regexp": "^1.0.2",
"has-ansi": "^2.0.0",
"strip-ansi": "^3.0.0",
"supports-color": "^2.0.0"
}
},
"strip-ansi": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
"integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
"dev": true,
"requires": {
"ansi-regex": "^2.0.0"
}
},
"supports-color": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
"integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
"dev": true
}
}
},
"balanced-match": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
@ -103,6 +165,12 @@
"integrity": "sha1-81HTKWnTL6XXpVZxVCY9korjvR8=",
"dev": true
},
"builtin-modules": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz",
"integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=",
"dev": true
},
"camelcase": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz",
@ -119,6 +187,43 @@
"type-detect": "^1.0.0"
}
},
"chalk": {
"version": "2.4.1",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz",
"integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==",
"dev": true,
"requires": {
"ansi-styles": "^3.2.1",
"escape-string-regexp": "^1.0.5",
"supports-color": "^5.3.0"
},
"dependencies": {
"ansi-styles": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
"integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
"dev": true,
"requires": {
"color-convert": "^1.9.0"
}
},
"has-flag": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
"integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
"dev": true
},
"supports-color": {
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
"integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
"dev": true,
"requires": {
"has-flag": "^3.0.0"
}
}
}
},
"cliui": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz",
@ -134,6 +239,21 @@
"resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
"integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c="
},
"color-convert": {
"version": "1.9.3",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
"integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
"dev": true,
"requires": {
"color-name": "1.1.3"
}
},
"color-name": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
"dev": true
},
"commander": {
"version": "2.9.0",
"resolved": "http://registry.npmjs.org/commander/-/commander-2.9.0.tgz",
@ -206,6 +326,18 @@
"integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
"dev": true
},
"esprima": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
"integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
"dev": true
},
"esutils": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz",
"integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=",
"dev": true
},
"execa": {
"version": "0.10.0",
"resolved": "https://registry.npmjs.org/execa/-/execa-0.10.0.tgz",
@ -268,6 +400,23 @@
"integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==",
"dev": true
},
"has-ansi": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz",
"integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=",
"dev": true,
"requires": {
"ansi-regex": "^2.0.0"
},
"dependencies": {
"ansi-regex": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
"integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
"dev": true
}
}
},
"has-flag": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz",
@ -320,6 +469,22 @@
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
"integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA="
},
"js-tokens": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz",
"integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=",
"dev": true
},
"js-yaml": {
"version": "3.12.0",
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.0.tgz",
"integrity": "sha512-PIt2cnwmPfL4hKNwqeiuz4bKfnzHTBv6HyVgjahA6mPLwPDzjDWrplJBMjHUFxku/N3FlmrbyPclad+I+4mJ3A==",
"dev": true,
"requires": {
"argparse": "^1.0.7",
"esprima": "^4.0.0"
}
},
"json3": {
"version": "3.3.2",
"resolved": "https://registry.npmjs.org/json3/-/json3-3.3.2.tgz",
@ -628,6 +793,12 @@
"resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz",
"integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A="
},
"path-parse": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz",
"integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==",
"dev": true
},
"path-to-regexp": {
"version": "1.7.0",
"resolved": "http://r.npm.sankuai.com/path-to-regexp/download/path-to-regexp-1.7.0.tgz",
@ -653,6 +824,15 @@
"resolved": "http://r.npm.sankuai.com/require-main-filename/download/require-main-filename-1.0.1.tgz",
"integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE="
},
"resolve": {
"version": "1.8.1",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.8.1.tgz",
"integrity": "sha512-AicPrAC7Qu1JxPCZ9ZgCZlY35QgFnNqc+0LtbRNxnVw4TXvjQ72wnuL9JQcEBgXkI9JM8MsT9kaQoHcpCRJOYA==",
"dev": true,
"requires": {
"path-parse": "^1.0.5"
}
},
"samsam": {
"version": "1.3.0",
"resolved": "http://r.npm.sankuai.com/samsam/download/samsam-1.3.0.tgz",
@ -731,6 +911,12 @@
}
}
},
"sprintf-js": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
"integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=",
"dev": true
},
"string-width": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
@ -773,6 +959,55 @@
"resolved": "https://registry.npmjs.org/thrift-parser/-/thrift-parser-0.4.2.tgz",
"integrity": "sha1-lHKac3nOA+AL6+Odocvze70zhjs="
},
"tslib": {
"version": "1.9.3",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz",
"integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==",
"dev": true
},
"tslint": {
"version": "5.11.0",
"resolved": "https://registry.npmjs.org/tslint/-/tslint-5.11.0.tgz",
"integrity": "sha1-mPMMAurjzecAYgHkwzywi0hYHu0=",
"dev": true,
"requires": {
"babel-code-frame": "^6.22.0",
"builtin-modules": "^1.1.1",
"chalk": "^2.3.0",
"commander": "^2.12.1",
"diff": "^3.2.0",
"glob": "^7.1.1",
"js-yaml": "^3.7.0",
"minimatch": "^3.0.4",
"resolve": "^1.3.2",
"semver": "^5.3.0",
"tslib": "^1.8.0",
"tsutils": "^2.27.2"
},
"dependencies": {
"commander": {
"version": "2.18.0",
"resolved": "https://registry.npmjs.org/commander/-/commander-2.18.0.tgz",
"integrity": "sha512-6CYPa+JP2ftfRU2qkDK+UTVeQYosOg/2GbcjIcKPHfinyOLPVGXu/ovN86RP49Re5ndJK1N0kuiidFFuepc4ZQ==",
"dev": true
}
}
},
"tslint-config-prettier": {
"version": "1.15.0",
"resolved": "https://registry.npmjs.org/tslint-config-prettier/-/tslint-config-prettier-1.15.0.tgz",
"integrity": "sha512-06CgrHJxJmNYVgsmeMoa1KXzQRoOdvfkqnJth6XUkNeOz707qxN0WfxfhYwhL5kXHHbYJRby2bqAPKwThlZPhw==",
"dev": true
},
"tsutils": {
"version": "2.29.0",
"resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz",
"integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==",
"dev": true,
"requires": {
"tslib": "^1.8.1"
}
},
"type-detect": {
"version": "1.0.0",
"resolved": "http://r.npm.sankuai.com/type-detect/download/type-detect-1.0.0.tgz",

View File

@ -7,7 +7,7 @@
"build": "tsc",
"test": "tsc test/* --outDir test-tmp && mocha",
"postinstall": "npm run build",
"prettier": "prettier"
"prettier": "prettier --write \"{,{src,test,bin}/**/}*.{ts,js,json}\""
},
"repository": {
"url": "https://github.com/windwhinny/thrift-ts.git",
@ -28,6 +28,8 @@
"mocha": "^3.5.3",
"prettier": "^1.14.3",
"sinon": "^4.5.0",
"tslint": "^5.11.0",
"tslint-config-prettier": "^1.15.0",
"typescript": "^3.0.3"
},
"bin": {

3
prettier.config.js Normal file
View File

@ -0,0 +1,3 @@
module.exports = {
tabWidth: 4
};

File diff suppressed because it is too large Load Diff

View File

@ -1,36 +1,30 @@
import BaseCompiler from './BaseCompiler';
import path = require('path');
import {
File,
CompileOptions,
} from './types';
import {
Includes,
Service,
} from './ast';
import BaseCompiler from "./BaseCompiler";
import path = require("path");
import { File, CompileOptions } from "./types";
import { Includes, Service } from "./ast";
export default class ServiceCompiler extends BaseCompiler {
constructor(
public basename: string,
public name: string,
public service: Service,
public includes?: Includes,
options?: CompileOptions,
) {
super(options);
}
flush(): File {
if (this.includes) {
this.writeInclude(this.includes);
constructor(
public basename: string,
public name: string,
public service: Service,
public includes?: Includes,
options?: CompileOptions
) {
super(options);
}
this.writeCallbackTypeDeclare();
this.writeCommonType();
this.wExport(() => this.wService(this.service, this.basename));
return {
filename: `${path.basename(this.name, '.thrift')}.d.ts`,
content: this.buffer.join(''),
flush(): File {
if (this.includes) {
this.writeInclude(this.includes);
}
this.writeCallbackTypeDeclare();
this.writeCommonType();
this.wExport(() => this.wService(this.service, this.basename));
return {
filename: `${path.basename(this.name, ".thrift")}.d.ts`,
content: this.buffer.join("")
};
}
}
}

View File

@ -1,124 +1,133 @@
export type SetType = {
name: 'set',
valueType: ValueType,
}
name: "set";
valueType: ValueType;
};
export type ListType = {
name: 'list',
valueType: ValueType,
}
name: "list";
valueType: ValueType;
};
export type MapType = {
name: 'map',
keyType: ValueType,
valueType: ValueType,
}
name: "map";
keyType: ValueType;
valueType: ValueType;
};
export type ValueType = string | SetType | ListType | MapType;
export type ThriftType = 'int' | 'bool' | 'i8' | 'i16' | 'i32' | 'i64' | 'string' | 'double' | 'binary';
export type FieldOption = 'required' | 'optional';
export type ThriftType =
| "int"
| "bool"
| "i8"
| "i16"
| "i32"
| "i64"
| "string"
| "double"
| "binary";
export type FieldOption = "required" | "optional";
export type Field = {
id?: string,
option?: FieldOption,
type: ThriftType,
name: string,
id?: string;
option?: FieldOption;
type: ThriftType;
name: string;
};
export type ArgOrExecption = {
id: string,
type: ValueType,
name: string,
}
id: string;
type: ValueType;
name: string;
};
export type Method = {
type: ValueType,
name: string,
args: ArgOrExecption[],
throws: ArgOrExecption[],
}
type: ValueType;
name: string;
args: ArgOrExecption[];
throws: ArgOrExecption[];
};
export type Structs = {
[name: string]: Field[],
}
[name: string]: Field[];
};
export type Unions = {
[name: string]: Field[],
}
[name: string]: Field[];
};
export type Exceptions = {
[name: string]: Field[],
}
[name: string]: Field[];
};
export type Service = {
functions: {
[methodName: string]: Method,
}
}
functions: {
[methodName: string]: Method;
};
};
export type Services = {
[name: string]: Service,
}
[name: string]: Service;
};
export type Namespaces = {
[name: string]: {
serviceName: string,
}
}
[name: string]: {
serviceName: string;
};
};
export type Includes = {
[name: string]: {
path: string,
}
}
[name: string]: {
path: string;
};
};
export type TypeDefs = {
[name: string]: {
type: ValueType,
}
}
[name: string]: {
type: ValueType;
};
};
export type StaticConst = {
type: string,
value: any,
}
type: string;
value: any;
};
export type ListConst = {
type: ListType,
value: any,
}
type: ListType;
value: any;
};
export type MapConst = {
type: MapType,
value: {
key: any,
value: any,
}[],
}
type: MapType;
value: {
key: any;
value: any;
}[];
};
export type SetConst = {
type: SetType,
value: any,
}
type: SetType;
value: any;
};
export type Consts = {
[name: string]: StaticConst | ListConst | MapConst | SetConst,
}
[name: string]: StaticConst | ListConst | MapConst | SetConst;
};
export type Enum = {
name: string,
value: string | number | boolean,
}
name: string;
value: string | number | boolean;
};
export type Enums = {
[name: string]: {
items: Enum[],
}
}
[name: string]: {
items: Enum[];
};
};
export type JsonAST = {
namespace?: Namespaces,
typedef?: TypeDefs,
include?: Includes,
const?: Consts,
enum?: Enums,
struct?: Structs,
union?: Unions,
exception?: Exceptions,
service?: Services,
namespace?: Namespaces;
typedef?: TypeDefs;
include?: Includes;
const?: Consts;
enum?: Enums;
struct?: Structs;
union?: Unions;
exception?: Exceptions;
service?: Services;
};

View File

@ -1,76 +1,75 @@
import * as fs from 'fs';
import * as glob from 'glob';
import * as path from 'path';
import * as yargs from 'yargs';
import * as fs from "fs";
import * as glob from "glob";
import * as path from "path";
import * as yargs from "yargs";
import compile from './compile';
import compile from "./compile";
export default () => {
const argv = yargs
.usage('Usage: $0 [options] files')
.option('s', {
alias: 'spaceAsTab',
describe: 'use space as tab',
.usage("Usage: $0 [options] files")
.option("s", {
alias: "spaceAsTab",
describe: "use space as tab",
default: true,
type: 'number',
type: "number"
})
.options('t', {
alias: 'tabSize',
describe: 'tab size',
.options("t", {
alias: "tabSize",
describe: "tab size",
default: 2,
type: 'boolean',
type: "boolean"
})
.options('o', {
alias: 'out',
describe: 'out put dir',
type: 'string'
.options("o", {
alias: "out",
describe: "out put dir",
type: "string"
})
.options('i', {
alias: 'int64AsString',
describe: 'treat type int64 as type string',
.options("i", {
alias: "int64AsString",
describe: "treat type int64 as type string",
default: false,
type: 'boolean'
type: "boolean"
})
.options('d', {
alias: 'definition',
describe: 'generate definition type',
.options("d", {
alias: "definition",
describe: "generate definition type",
default: true,
type: 'boolean'
type: "boolean"
})
.options('c', {
alias: 'camelCase',
describe: 'camel case',
.options("c", {
alias: "camelCase",
describe: "camel case",
default: false,
type: 'boolean'
type: "boolean"
})
.options('v', {
alias: 'version',
describe: 'current version'
.options("v", {
alias: "version",
describe: "current version"
})
.help('h')
.alias('h', 'help')
.argv;
.help("h")
.alias("h", "help").argv;
if (argv.version) {
const pkg = fs.readFileSync(path.join(__dirname, '../package.json'), {
encoding: 'utf-8'
const pkg = fs.readFileSync(path.join(__dirname, "../package.json"), {
encoding: "utf-8"
});
console.log('V' + JSON.parse(pkg).version)
console.log("V" + JSON.parse(pkg).version);
return;
}
if (!argv._.length) {
throw new Error('must specify a file');
throw new Error("must specify a file");
}
function getBasePath(files: any[]) {
let i = 0;
if (files.length <= 1) return '';
if (files.length <= 1) return "";
while (i < files[0].length) {
let char = '';
let char = "";
const equal = files.every((file: any[], index: number) => {
if (index === 0) {
char = file[i]
char = file[i];
return true;
} else if (file[i] === char) {
return true;
@ -95,9 +94,9 @@ export default () => {
const isFolder = !(folder && folder.match(/.thrift$/));
if (isFolder) {
if (folder.match(/\/$/)) {
return folder + '**/*.thrift';
return folder + "**/*.thrift";
}
return folder + '/**/*.thrift';
return folder + "/**/*.thrift";
}
return folder;
}
@ -107,12 +106,12 @@ export default () => {
basePath = getBasePath(argv._);
}
argv._.forEach((p) => {
argv._.forEach(p => {
let out: string;
if (argv.out) {
out = argv.out;
} else {
out = './';
out = "./";
}
// if you enter the folder path directly, you need to do the conversion
p = getFolderPath(p);
@ -121,27 +120,33 @@ export default () => {
if (!basePath) {
basePath = getBasePath(files);
}
console.log('basePath:', basePath);
console.log("basePath:", basePath);
files.forEach(file => {
const files = compile({
filename: file,
content: fs.readFileSync(file)
}, {
tabSize: argv.tabSize,
spaceAsTab: argv.spaceAsTab,
int64AsString: argv.int64AsString,
definition: argv.definition,
camelCase: argv.camelCase
});
const files = compile(
{
filename: file,
content: fs.readFileSync(file)
},
{
tabSize: argv.tabSize,
spaceAsTab: argv.spaceAsTab,
int64AsString: argv.int64AsString,
definition: argv.definition,
camelCase: argv.camelCase
}
);
if (!fs.existsSync(out)) {
fs.mkdirSync(out);
}
files.forEach(newFile => {
const outfile = path.join(out, newFile.filename);
console.log('outfile:', outfile);
fs.writeFileSync(outfile, '// tslint:disable\n' + newFile.content);
})
console.log("outfile:", outfile);
fs.writeFileSync(
outfile,
"// tslint:disable\n" + newFile.content
);
});
});
});
});
}
};

View File

@ -1,85 +1,93 @@
import path = require('path');
import thriftPraser = require('./thriftParser');
import BaseCompiler from './BaseCompiler';
import ServiceCompiler from './ServiceCompiler';
import {
File,
CompileOptions,
} from './types';
import path = require("path");
import thriftPraser = require("./thriftParser");
import BaseCompiler from "./BaseCompiler";
import ServiceCompiler from "./ServiceCompiler";
import { File, CompileOptions } from "./types";
class Compile extends BaseCompiler {
serviceCompilers: ServiceCompiler[] = [];
serviceCompilers: ServiceCompiler[] = [];
constructor(
file: {
filename: string,
content: string | Buffer,
constructor(
file: {
filename: string;
content: string | Buffer;
},
options?: CompileOptions
) {
super(options);
this.filename = file.filename;
this.ast = thriftPraser(file.content);
if (this.ast.service && this.definition) {
const services = this.ast.service;
const basename = path.basename(this.filename, ".thrift");
const include = Object.assign({}, this.ast.include, {
[basename]: {
path: basename
}
});
this.serviceCompilers = Object.keys(services).map(k => {
return new ServiceCompiler(
basename,
String(k),
services[k],
include,
options
);
});
}
}
flush(): File[] {
this.writeCommonType();
if (this.ast.include) {
this.writeInclude(this.ast.include);
}
if (this.ast.const) {
this.writeConst(this.ast.const);
}
if (this.ast.typedef) {
this.writeTypeof(this.ast.typedef);
}
if (this.ast.enum) {
this.writeEnum(this.ast.enum);
}
if (this.ast.struct) {
this.writeStructs(this.ast.struct);
}
if (this.ast.union) {
this.writeUnions(this.ast.union);
}
if (this.ast.exception) {
this.writeExceptions(this.ast.exception);
}
let files: File[] = [];
if (this.serviceCompilers.length) {
this.serviceCompilers.forEach(s => {
files.push(s.flush());
});
}
files.push({
filename: `${path.basename(this.filename, ".thrift")}${
this.definition ? "_types.d.ts" : ".ts"
}`,
content: this.buffer.join("")
});
return files;
}
}
export default (
sourceFile: {
filename: string;
content: string | Buffer;
},
options?: CompileOptions
) {
super(options);
this.filename = file.filename;
this.ast = thriftPraser(file.content);
if (this.ast.service && this.definition) {
const services = this.ast.service;
const basename = path.basename(this.filename, '.thrift');
const include = Object.assign({}, this.ast.include, {
[basename]: {
path: basename,
},
});
this.serviceCompilers = Object.keys(services).map((k) => {
return new ServiceCompiler(basename, String(k), services[k], include, options);
});
}
}
flush(): File[] {
this.writeCommonType();
if (this.ast.include) {
this.writeInclude(this.ast.include);
}
if (this.ast.const) {
this.writeConst(this.ast.const);
}
if (this.ast.typedef) {
this.writeTypeof(this.ast.typedef);
}
if (this.ast.enum) {
this.writeEnum(this.ast.enum);
}
if (this.ast.struct) {
this.writeStructs(this.ast.struct);
}
if (this.ast.union) {
this.writeUnions(this.ast.union);
}
if (this.ast.exception) {
this.writeExceptions(this.ast.exception);
}
let files: File[] = [];
if (this.serviceCompilers.length) {
this.serviceCompilers.forEach(s => {
files.push(s.flush());
})
}
files.push({
filename: `${path.basename(this.filename, '.thrift')}${this.definition ? '_types.d.ts' : '.ts'}`,
content: this.buffer.join(''),
});
return files;
}
}
export default (sourceFile: {
filename: string,
content: string | Buffer,
}, options?: CompileOptions): File[] => {
const compiler = new Compile(sourceFile, options);
return compiler.flush();
}
): File[] => {
const compiler = new Compile(sourceFile, options);
return compiler.flush();
};

View File

@ -1 +1 @@
export * from './compile';
export * from "./compile";

View File

@ -1,11 +1,11 @@
/// <reference types="node" />
import { JsonAST } from './ast';
import { JsonAST } from "./ast";
interface ThriftFileParsingError extends Error {
messgae: string;
name: 'THRIFT_FILE_PARSING_ERROR';
messgae: string;
name: "THRIFT_FILE_PARSING_ERROR";
}
declare function parser (str: string | Buffer): JsonAST;
declare function parser(str: string | Buffer): JsonAST;
export = parser;

View File

@ -2,5 +2,5 @@
// we will not use it directly until they publish the new version
// in this way, we can import our "correct" d.ts file
// https://github.com/eleme/thrift-parser/commit/bb998c2836f20ee8dc431be38164c4d193320f87
const parser = require('thrift-parser');
const parser = require("thrift-parser");
module.exports = parser;

View File

@ -1,18 +1,18 @@
export const SPACE = ' ';
export const TAB = ' '
export const SPACE = " ";
export const TAB = " ";
export enum INTEND_MODE {
TAB,
SPACE,
TAB,
SPACE
}
export type File = {
filename: string,
content: string,
}
filename: string;
content: string;
};
export type CompileOptions = {
tabSize?: number,
spaceAsTab?: boolean,
int64AsString?: boolean,
definition?: boolean,
camelCase?: boolean
}
tabSize?: number;
spaceAsTab?: boolean;
int64AsString?: boolean;
definition?: boolean;
camelCase?: boolean;
};

View File

@ -1,61 +1,65 @@
import BaseCompiler from '../src/BaseCompiler';
import thriftPraser = require('../src/thriftParser');
import * as sinon from 'sinon';
import * as chai from 'chai';
import * as fs from 'fs';
import { JsonAST } from '../src/ast';
import * as Path from 'path';
import BaseCompiler from "../src/BaseCompiler";
import thriftPraser = require("../src/thriftParser");
import * as sinon from "sinon";
import * as chai from "chai";
import * as fs from "fs";
import { JsonAST } from "../src/ast";
import * as Path from "path";
chai.should();
describe('src/BaseCompiler', () => {
let baseCompiler: BaseCompiler;
const stubs = sinon.stub;
describe("src/BaseCompiler", () => {
let baseCompiler: BaseCompiler;
const stubs = sinon.stub;
beforeEach(() => {
baseCompiler = new BaseCompiler();
});
describe('writeInclude', () => {
it('writeInclude, should transfer include to import', () => {
type Include = {
[key: string]: { path: string }
};
const includes: Include = {
0: { path: 'test.thrift' },
1: { path: './test.thrift' },
2: { path: '/test/test.thrift' },
3: { path: './test/test.thrift' },
4: { path: '../test.thrift' },
5: { path: '../test/test.thrift' }
};
const result: string[] = [];
const expectResult = (key: string) => `import * as ${key} from './test_types';\n`;
stubs(baseCompiler, 'write').callsFake(function () {
result.push(Array.prototype.join.call(arguments, ''));
})
baseCompiler.writeInclude(includes);
for (let key in includes) {
result[Number(key)].should.eql(expectResult(key));
}
});
})
describe('writeTypeof', () => {
let ast: JsonAST;
beforeEach(() => {
ast = thriftPraser(fs.readFileSync(Path.join(__dirname, './mock/idl/typeof.thrift')));
})
baseCompiler = new BaseCompiler();
});
it('should support typedefs keyword', () => {
const typedef = ast.typedef;
if (!typedef) throw new Error('typedef must exists');
baseCompiler.writeTypeof(typedef);
baseCompiler.buffer.join('').should.eq('type TList = T[];\n');
})
})
describe("writeInclude", () => {
it("writeInclude, should transfer include to import", () => {
type Include = {
[key: string]: { path: string };
};
const includes: Include = {
0: { path: "test.thrift" },
1: { path: "./test.thrift" },
2: { path: "/test/test.thrift" },
3: { path: "./test/test.thrift" },
4: { path: "../test.thrift" },
5: { path: "../test/test.thrift" }
};
const result: string[] = [];
const expectResult = (key: string) =>
`import * as ${key} from './test_types';\n`;
stubs(baseCompiler, "write").callsFake(function() {
result.push(Array.prototype.join.call(arguments, ""));
});
baseCompiler.writeInclude(includes);
for (let key in includes) {
result[Number(key)].should.eql(expectResult(key));
}
});
});
describe("writeTypeof", () => {
let ast: JsonAST;
beforeEach(() => {
ast = thriftPraser(
fs.readFileSync(
Path.join(__dirname, "./mock/idl/typeof.thrift")
)
);
});
it("should support typedefs keyword", () => {
const typedef = ast.typedef;
if (!typedef) throw new Error("typedef must exists");
baseCompiler.writeTypeof(typedef);
baseCompiler.buffer.join("").should.eq("type TList = T[];\n");
});
});
});

View File

@ -1,4 +1,4 @@
import * as test from './test_types';
import * as test from "./test_types";
type Callback<T, E> = (err: E, resp: T) => void;
interface Int64 {
@ -8,6 +8,9 @@ interface Int64 {
}
export class Client {
search(request: test.Request, callback: Callback<test.Response, Error>): void;
search(
request: test.Request,
callback: Callback<test.Response, Error>
): void;
search(request: test.Request): Promise<test.Response>;
}

View File

@ -6,36 +6,26 @@ interface Int64 {
export enum Status {
Success = 1,
Error = 2,
Error = 2
}
export class Result {
id: number;
name: string;
constructor(arg?: {
id: number;
name: string;
})
constructor(arg?: { id: number; name: string });
}
export class Response {
status: Status;
result?: Result[];
constructor(arg?: {
status: Status;
result?: Result[];
})
constructor(arg?: { status: Status; result?: Result[] });
}
export class Request {
query: string;
page?: number;
constructor(arg?: {
query: string;
page?: number;
})
constructor(arg?: { query: string; page?: number });
}

View File

@ -1,24 +1,31 @@
import thriftTs from '../src';
import * as fs from 'fs';
import * as Path from 'path';
import thriftTs from "../src";
import * as fs from "fs";
import * as Path from "path";
describe('thriftTs', () => {
it('should compile to d.ts', () => {
const filename = Path.join(__dirname, './mock/idl/test.thrift');
const content = fs.readFileSync(filename);
thriftTs({
filename,
content,
}, {
spaceAsTab: true,
}).forEach(newFile => {
const newFilename = Path.join(__dirname, './mock/dist', newFile.filename);
if (!fs.existsSync(newFilename)) throw new Error('file not exists');
describe("thriftTs", () => {
it("should compile to d.ts", () => {
const filename = Path.join(__dirname, "./mock/idl/test.thrift");
const content = fs.readFileSync(filename);
thriftTs(
{
filename,
content
},
{
spaceAsTab: true
}
).forEach(newFile => {
const newFilename = Path.join(
__dirname,
"./mock/dist",
newFile.filename
);
if (!fs.existsSync(newFilename)) throw new Error("file not exists");
const distContent = fs.readFileSync(newFilename).toString();
if (distContent !== newFile.content) {
throw new Error('content does not match')
}
})
})
})
const distContent = fs.readFileSync(newFilename).toString();
if (distContent !== newFile.content) {
throw new Error("content does not match");
}
});
});
});

View File

@ -1,18 +1,18 @@
{
"compilerOptions": {
"allowSyntheticDefaultImports": true,
"module": "commonjs",
"removeComments": true,
"strictNullChecks": true,
"noImplicitAny": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"sourceMap": false,
"target": "ES6",
"lib": ["es2015", "es2016", "es2017", "es2018", "scripthost"],
"experimentalDecorators": true,
"outDir": "lib",
"allowJs": true
},
"include": ["./src/**/*"]
"compilerOptions": {
"allowSyntheticDefaultImports": true,
"module": "commonjs",
"removeComments": true,
"strictNullChecks": true,
"noImplicitAny": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"sourceMap": false,
"target": "ES6",
"lib": ["es2015", "es2016", "es2017", "es2018", "scripthost"],
"experimentalDecorators": true,
"outDir": "lib",
"allowJs": true
},
"include": ["./src/**/*"]
}

View File

@ -1,57 +1,3 @@
{
"rules": {
"no-any": true,
"no-console": [true],
"class-name": true,
"comment-format": [true, "check-space"],
"indent": [true, "spaces", 2],
"no-duplicate-variable": true,
"no-eval": true,
"no-internal-module": true,
"no-trailing-whitespace": true,
"no-unsafe-finally": true,
"no-var-keyword": true,
"one-line": [true, "check-open-brace", "check-whitespace"],
"quotemark": [true, "single"],
"triple-equals": [true, "allow-null-check"],
"typedef-whitespace": [
true,
{
"call-signature": "nospace",
"index-signature": "nospace",
"parameter": "nospace",
"property-declaration": "nospace",
"variable-declaration": "nospace"
}
],
"variable-name": [true, "ban-keywords"],
"whitespace": [
true,
"check-branch",
"check-decl",
"check-operator",
"check-separator",
"check-type"
],
"no-use-before-declare": true,
"no-unused-variable": ["error"],
"eofline": true,
"max-file-line-count": [true, 1000],
"no-shadowed-variable": true,
"object-literal-shorthand": true,
"trailing-comma": [
"error",
{
"multiline": "always"
}
]
},
"jsRules": {
"no-duplicate-variable": true,
"no-shadowed-variable": true,
"no-var-keyword": true,
"no-trailing-whitespace": true,
"eofline": true,
"no-use-before-declare": true
}
"extends": ["tslint:recomended", "tslint-config-prettier"]
}