* Rename ts-codegen to ts-gyb

* Drop @microsoft prefix

* GYB and features
This commit is contained in:
Zhuoran 2021-07-29 17:34:01 +08:00 коммит произвёл GitHub
Родитель f9026f0b1b
Коммит a9b296304e
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
14 изменённых файлов: 59 добавлений и 58 удалений

Просмотреть файл

@ -1,21 +1,27 @@
# ts-codegen
# ts-gyb
ts-codegen is a multi-purpose code generation tool based on TypeScript interfaces. It was initially designed for generating boilerplate interfacing code between web and mobile platforms in hybrid apps. With custom templates, it can generate code for any use from TypeScript.
ts-gyb is a multi-purpose code generation tool based on TypeScript interfaces. It was initially designed for generating boilerplate interfacing code between web and mobile platforms in hybrid apps. With custom templates, it can generate code for any use from TypeScript.
GYB: Generate Your Boilerplate. Inspired by [swift/gyb.py](https://github.com/apple/swift/blob/main/utils/gyb.py).
## Features
- Generate production ready and well documented code from TypeScript code
- Support most of TypeScript syntax
- Fully customizable template makes the generated code fit perfectly into any project
## Installation
To use ts-codegen with an existing project managed by npm, it is recommended to install ts-codegen as a dev dependency:
To use ts-gyb with an existing project managed by npm, it is recommended to install ts-gyb as a dev dependency:
```shell
npm install --save-dev @microsoft/ts-codegen
npm install --save-dev ts-gyb
```
You can also install ts-codegen globally:
You can also install ts-gyb globally:
```shell
npm install --global @microsoft/ts-codegen
npm install --global ts-gyb
```
## Get Started
@ -39,11 +45,11 @@ interface EditorSelection {
}
```
ts-codegen only handles method members like `methodName(): ReturnType;`. If a method needs to take in parameters, it must define one object argument. The type of this object can either be an interface or an object literal. For more information on how to write interfaces for ts-codegen, please refer to [TypeScript Interface Guide](documentation/interface-guide.md).
ts-gyb only handles method members like `methodName(): ReturnType;`. If a method needs to take in parameters, it must define one object argument. The type of this object can either be an interface or an object literal. For more information on how to write interfaces for ts-gyb, please refer to [TypeScript Interface Guide](documentation/interface-guide.md).
### 2. Provide templates
ts-codegen generates code from [mustache](http://mustache.github.io) templates. At least two templates are needed:
ts-gyb generates code from [mustache](http://mustache.github.io) templates. At least two templates are needed:
- **Module template**: used to generate a file for every TypeScript interface
- **Custom type template**: used to generate the file that hosts all TypeScript types found in method parameters or return types
@ -80,16 +86,16 @@ Create a json configuration file in your project:
All paths are relative to the configuration file. For all supported options in the configuration file, please refer to [Configuration Reference](documentation/generated/interfaces/Configuration.md).
### 4. Run ts-codegen
### 4. Run ts-gyb
```shell
npx ts-codegen --config path/to/config.json
npx ts-gyb --config path/to/config.json
```
Or if ts-codegen is installed globally:
Or if ts-gyb is installed globally:
```shell
ts-codegen --config path/to/config.json
ts-gyb --config path/to/config.json
```
Generated code can be found at the output directory specified in the configuration file.
@ -98,7 +104,7 @@ Generated code can be found at the output directory specified in the configurati
[mini-editor](demo/mini-editor) contains an iOS and an Android rich text editing app. Their editors are powered by the same TypeScript web project.
The web part provides some rich text formatting operations that can be invoked from native code (Kotlin/Swift). The operations are defined in [IEditor.ts](demo/mini-editor/web/src/editor/IEditor.ts). ts-codegen generates [EditorBridge.swift](demo/mini-editor/apple/MiniEditor/Generated/EditorBridge.swift) from that TypeScript interface.
The web part provides some rich text formatting operations that can be invoked from native code (Kotlin/Swift). The operations are defined in [IEditor.ts](demo/mini-editor/web/src/editor/IEditor.ts). ts-gyb generates [EditorBridge.swift](demo/mini-editor/apple/MiniEditor/Generated/EditorBridge.swift) from that TypeScript interface.
## Documentation

Просмотреть файл

Просмотреть файл

@ -74,7 +74,7 @@ class MainActivity : AppCompatActivity() {
fun onInsertContentButtonClick(view: View) {
bridge.insertContent("[inserted content]", true) { result ->
println("[ts-codegen] result: $result")
println("[ts-gyb] result: $result")
}
}
}
}

Просмотреть файл

@ -23,33 +23,33 @@ open class EditorBridge(private val webView: WebView, private val gson: Gson) :
override fun toggleBold() {
val javascriptString = "editor.toggleBold()"
println("[ts-codegen] evaluating JavaScript: $javascriptString")
println("[ts-gyb] evaluating JavaScript: $javascriptString")
webView.evaluateJavascript(javascriptString){ evaluationResult ->
println("[ts-codegen] JavaScript result: $evaluationResult")
println("[ts-gyb] JavaScript result: $evaluationResult")
}
}
override fun toggleItalic() {
val javascriptString = "editor.toggleItalic()"
println("[ts-codegen] evaluating JavaScript: $javascriptString")
println("[ts-gyb] evaluating JavaScript: $javascriptString")
webView.evaluateJavascript(javascriptString){ evaluationResult ->
println("[ts-codegen] JavaScript result: $evaluationResult")
println("[ts-gyb] JavaScript result: $evaluationResult")
}
}
override fun toggleUnderline() {
val javascriptString = "editor.toggleUnderline()"
println("[ts-codegen] evaluating JavaScript: $javascriptString")
println("[ts-gyb] evaluating JavaScript: $javascriptString")
webView.evaluateJavascript(javascriptString){ evaluationResult ->
println("[ts-codegen] JavaScript result: $evaluationResult")
println("[ts-gyb] JavaScript result: $evaluationResult")
}
}
override fun clear() {
val javascriptString = "editor.clear()"
println("[ts-codegen] evaluating JavaScript: $javascriptString")
println("[ts-gyb] evaluating JavaScript: $javascriptString")
webView.evaluateJavascript(javascriptString){ evaluationResult ->
println("[ts-codegen] JavaScript result: $evaluationResult")
println("[ts-gyb] JavaScript result: $evaluationResult")
}
}
@ -64,7 +64,7 @@ open class EditorBridge(private val webView: WebView, private val gson: Gson) :
)
val jsonString = gson.toJson(args, Args_insertContent::class.java)
val javascriptString = "editor.insertContent($jsonString)"
println("[ts-codegen] evaluating JavaScript: $javascriptString")
println("[ts-gyb] evaluating JavaScript: $javascriptString")
webView.evaluateJavascript(javascriptString){ evaluationResult ->
val result = gson.fromJson(evaluationResult, InsertContentResult::class.java)
callback(result)

Просмотреть файл

@ -20,7 +20,7 @@ public class EditorBridge {
public func toggleBold(completion: ((Result<Void, Error>) -> Void)? = nil) {
let javaScriptString = "editor.toggleBold" + "(" + ")"
print("[ts-codegen] evaluating: \(javaScriptString)")
print("[ts-gyb] evaluating: \(javaScriptString)")
webView?.evaluateJavaScript(javaScriptString) { evaluationResult, error in
guard let completion = completion else { return }
@ -35,7 +35,7 @@ public class EditorBridge {
public func toggleItalic(completion: ((Result<Void, Error>) -> Void)? = nil) {
let javaScriptString = "editor.toggleItalic" + "(" + ")"
print("[ts-codegen] evaluating: \(javaScriptString)")
print("[ts-gyb] evaluating: \(javaScriptString)")
webView?.evaluateJavaScript(javaScriptString) { evaluationResult, error in
guard let completion = completion else { return }
@ -50,7 +50,7 @@ public class EditorBridge {
public func toggleUnderline(completion: ((Result<Void, Error>) -> Void)? = nil) {
let javaScriptString = "editor.toggleUnderline" + "(" + ")"
print("[ts-codegen] evaluating: \(javaScriptString)")
print("[ts-gyb] evaluating: \(javaScriptString)")
webView?.evaluateJavaScript(javaScriptString) { evaluationResult, error in
guard let completion = completion else { return }
@ -65,7 +65,7 @@ public class EditorBridge {
public func clear(completion: ((Result<Void, Error>) -> Void)? = nil) {
let javaScriptString = "editor.clear" + "(" + ")"
print("[ts-codegen] evaluating: \(javaScriptString)")
print("[ts-gyb] evaluating: \(javaScriptString)")
webView?.evaluateJavaScript(javaScriptString) { evaluationResult, error in
guard let completion = completion else { return }
@ -89,7 +89,7 @@ public class EditorBridge {
let argsString = String(data: try! jsonEncoder.encode(args), encoding: .utf8)!
let javaScriptString = "editor.insertContent" + "(" + "\(argsString)" + ")"
print("[ts-codegen] evaluating: \(javaScriptString)")
print("[ts-gyb] evaluating: \(javaScriptString)")
webView?.evaluateJavaScript(javaScriptString) { [unowned self]evaluationResult, error in
if let error = error {

Просмотреть файл

@ -65,7 +65,7 @@ extension ViewController: ToolbarDelegate {
) { result in
switch result {
case .success(let contentString):
print("[ts-codegen] contentString after insertContent(): \(contentString)")
print("[ts-gyb] contentString after insertContent(): \(contentString)")
case .failure(let error):
assertionFailure("\(error)")
}

Просмотреть файл

@ -37,14 +37,14 @@ open class {{moduleName}}(private val webView: WebView, private val gson: Gson)
val jsonString = gson.toJson(args, Args_{{methodName}}::class.java)
{{/parameters.length}}
val javascriptString = "{{customTags.invokePath}}.{{methodName}}({{#parameters.length}}$jsonString{{/parameters.length}})"
println("[ts-codegen] evaluating JavaScript: $javascriptString")
println("[ts-gyb] evaluating JavaScript: $javascriptString")
webView.evaluateJavascript(javascriptString){ evaluationResult ->
{{#returnType}}
val result = gson.fromJson(evaluationResult, {{{returnType}}}::class.java)
callback(result)
{{/returnType}}
{{^returnType}}
println("[ts-codegen] JavaScript result: $evaluationResult")
println("[ts-gyb] JavaScript result: $evaluationResult")
{{/returnType}}
}
}

Просмотреть файл

@ -39,7 +39,7 @@ public class {{moduleName}} {
{{/parameters.length}}
let javaScriptString = "{{customTags.invokePath}}.{{methodName}}" + "(" {{#parameters.length}}+ "\(argsString)"{{/parameters.length}} + ")"
print("[ts-codegen] evaluating: \(javaScriptString)")
print("[ts-gyb] evaluating: \(javaScriptString)")
webView?.evaluateJavaScript(javaScriptString) { {{#returnType}}[unowned self]{{/returnType}}evaluationResult, error in
{{^returnType}}

Просмотреть файл

@ -1,7 +1,7 @@
{
"name": "mini-editor-web",
"version": "0.0.1",
"description": "An end-to-end example of ts-codegen",
"description": "An end-to-end example of ts-gyb",
"main": "src/main.ts",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",

Просмотреть файл

@ -2,7 +2,7 @@
## Method definition
ts-codegen only recognizes interface members defined as methods.
ts-gyb only recognizes interface members defined as methods.
```typescript
/**
@ -51,7 +51,7 @@ Refer to [Value types](#value-types) for allowed parameter types.
## Return type
Return type must be explicitly specified. When not provided, TypeScript would use `any` which is not supported by ts-codegen. Use `void` when the method does not return a value.
Return type must be explicitly specified. When not provided, TypeScript would use `any` which is not supported by ts-gyb. Use `void` when the method does not return a value.
Return type can be a `Promise`.
@ -65,7 +65,7 @@ Refer to [Value types](#value-types) for allowed types as return type.
- `number`
- `boolean`
> Tips: TypeScript does not distinguish integer from float point number, and ts-codegen would map `number` to the default float point type in the target language. To map a value to integer, refer to the guide in [Integer type](#integer-type).
> Tips: TypeScript does not distinguish integer from float point number, and ts-gyb would map `number` to the default float point type in the target language. To map a value to integer, refer to the guide in [Integer type](#integer-type).
### `interface` and object literal
@ -79,7 +79,7 @@ When an interface extends another interface, all members of the parent interface
#### Indexable types
When an interface or an object literal contains an index member, it would be parsed as [index signature](https://www.typescriptlang.org/docs/handbook/2/objects.html#index-signatures) and be mapped to dictionary. ts-codegen only recognizes indexable types with only one index member. Currently the index type can only be `string`. The type of the value can be any type specified in [Value types](#value-types).
When an interface or an object literal contains an index member, it would be parsed as [index signature](https://www.typescriptlang.org/docs/handbook/2/objects.html#index-signatures) and be mapped to dictionary. ts-gyb only recognizes indexable types with only one index member. Currently the index type can only be `string`. The type of the value can be any type specified in [Value types](#value-types).
```typescript
// allowed: indexable interface
@ -186,20 +186,20 @@ type AliasDefinedInterface = { stringField: string }
### Predefined type
You can define some types as predefined. ts-codegen would treat these as known types and would assume they exist in the generated code. You must ensure these types can be correctly referenced in your project when using generated code.
You can define some types as predefined. ts-gyb would treat these as known types and would assume they exist in the generated code. You must ensure these types can be correctly referenced in your project when using generated code.
This is helpful for working around types that not supported by TypeScript or ts-codegen. [Workarounds](#workarounds) section introduces some use cases for this type.
This is helpful for working around types that not supported by TypeScript or ts-gyb. [Workarounds](#workarounds) section introduces some use cases for this type.
Refer to [Predefined Type](./predefined-type.md) for how to configure predefined types.
## Tags
ts-codegen parses tags in [JSDoc](https://jsdoc.app) documentation.
ts-gyb parses tags in [JSDoc](https://jsdoc.app) documentation.
### Built-in tags
- `@shouldExport`: Specify whether an `interface` should be exported. Set it to `true` to export.
- `@overrideModuleName`: Change the name of the interface for ts-codegen. This is helpful for dropping the `I` prefix in TypeScript interface name.
- `@overrideModuleName`: Change the name of the interface for ts-gyb. This is helpful for dropping the `I` prefix in TypeScript interface name.
- `@overrideTypeName`: Similar to `@overrideModuleName`, this is used to override the name of custom types used in method parameters or return values.
```typescript
@ -217,7 +217,7 @@ interface InterfaceWithTags {
You can also define custom tags and use them in templates. Refer to [module in template](template-guide.md#module) for how to use them.
ts-codegen would try to parse the value of custom tags via `JSON.parse()`. If failed, it would be passed as string.
ts-gyb would try to parse the value of custom tags via `JSON.parse()`. If failed, it would be passed as string.
```typescript
/**
@ -233,7 +233,7 @@ interface InterfaceWithTags {
## JSDoc documentation
ts-codegen would read the documentation comment from `interface` and `enum`, and their members. Documentation comment must be placed above all tags.
ts-gyb would read the documentation comment from `interface` and `enum`, and their members. Documentation comment must be placed above all tags.
```typescript
/**
@ -254,7 +254,7 @@ interface InterfaceWithTags {
TypeScript does not have an integer type. To generate methods with an integer as a parameter or return value, you can use the combination of [Type alias](#type-alias) and [Predefined type](#predefined-type).
First, define an integer type as an alias to `number`. For basic types like `number`, `string` and `boolean`, the type alias must be branded. This is because [TypeScript interns certain types](https://github.com/microsoft/TypeScript/issues/28197#issuecomment-434027046), and ts-codegen cannot distinguish these types from the target types. Learn more about TypeScript type branding [here](https://medium.com/@KevinBGreene/surviving-the-typescript-ecosystem-branding-and-type-tagging-6cf6e516523d).
First, define an integer type as an alias to `number`. For basic types like `number`, `string` and `boolean`, the type alias must be branded. This is because [TypeScript interns certain types](https://github.com/microsoft/TypeScript/issues/28197#issuecomment-434027046), and ts-gyb cannot distinguish these types from the target types. Learn more about TypeScript type branding [here](https://medium.com/@KevinBGreene/surviving-the-typescript-ecosystem-branding-and-type-tagging-6cf6e516523d).
```typescript
type CodeGen_Int = number & { _intBrand: never }

Просмотреть файл

@ -1,22 +1,22 @@
# Template Guide
ts-codegen uses [mustache](http://mustache.github.io) template to generate code. Refer to [mustache Manul](http://mustache.github.io/mustache.5.html) for supported syntax.
ts-gyb uses [mustache](http://mustache.github.io) template to generate code. Refer to [mustache Manul](http://mustache.github.io/mustache.5.html) for supported syntax.
## Required templates
ts-codegen needs two templates: module template and named type template.
ts-gyb needs two templates: module template and named type template.
### Module template
ts-codegen uses this template to generate a file for every module. Typically, generated file includes a module class and all types used in the method parameters and return values of the module.
ts-gyb uses this template to generate a file for every module. Typically, generated file includes a module class and all types used in the method parameters and return values of the module.
### Named type template
When a TypeScript `interface` or an `enum` is used by more than one module, it is not suitable to place the generated type in any module file. ts-codegen uses this template to generate a single file that hosts all shared TypeScript types found in method parameters and return types.
When a TypeScript `interface` or an `enum` is used by more than one module, it is not suitable to place the generated type in any module file. ts-gyb uses this template to generate a single file that hosts all shared TypeScript types found in method parameters and return types.
## Variables
ts-codegen defines some variables that can be directly used in templates.
ts-gyb defines some variables that can be directly used in templates.
### Variables in templates

2
package-lock.json сгенерированный
Просмотреть файл

@ -1,5 +1,5 @@
{
"name": "@olm/ts-codegen",
"name": "ts-gyb",
"version": "0.3.0",
"lockfileVersion": 1,
"requires": true,

Просмотреть файл

@ -1,5 +1,5 @@
{
"name": "@olm/ts-codegen",
"name": "ts-gyb",
"version": "0.3.0",
"description": "Generate Native API based on TS interface",
"scripts": {
@ -18,7 +18,7 @@
},
"main": "dist/index.js",
"bin": {
"ts-codegen": "bin/ts-codegen"
"ts-gyb": "bin/ts-gyb"
},
"files": [
"dist/**/*.js",

Просмотреть файл

@ -14,11 +14,6 @@
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"paths": {
"@olm/ts-codegen-basic-type": [
"src/basic-types/types.ts"
]
},
"baseUrl": ""
}
}