Support TS declaration files

This commit is contained in:
Lea Anthony
2020-11-11 21:27:40 +11:00
parent 450775a582
commit 9b516adb32
7 changed files with 197 additions and 44 deletions

View File

@@ -83,7 +83,44 @@ func goTypeToTS(input *Field, pkgName string) string {
}
if input.IsArray {
result = "Array<" + result + ">"
result = result + "[]"
}
return result
}
func goTypeToTSDeclaration(input *Field, pkgName string) string {
var result string
switch input.Type {
case "string":
result = "string"
case "int", "int8", "int16", "int32", "int64", "uint", "uint8", "uint16", "uint32", "uint64":
result = "number"
case "float32", "float64":
result = "number"
case "bool":
result = "boolean"
case "struct":
if input.Struct.Package.Name != "" {
if input.Struct.Package.Name != pkgName {
result = `import("./_` + input.Struct.Package.Name + `").`
}
}
result += input.Struct.Name
// case reflect.Array, reflect.Slice:
// return string(JsArray)
// case reflect.Ptr, reflect.Struct:
// fqt := input.Type().String()
// return strings.Split(fqt, ".")[1]
// case reflect.Map, reflect.Interface:
// return string(JsObject)
default:
fmt.Printf("Unsupported input to goTypeToTS: %+v", input)
return JsUnsupported
}
if input.IsArray {
result = result + "[]"
}
return result

View File

@@ -51,6 +51,23 @@ func (f *Field) JSName() string {
return f.Name
}
// TSName returns the Typescript name for this field
func (f *Field) TSName() string {
result := f.Name
if f.JSONOptions.Name != "" {
result = f.JSONOptions.Name
}
if f.IsOptional {
result += "?"
}
return result
}
// AsTSDeclaration returns a TS definition of a single type field
func (f *Field) AsTSDeclaration(pkgName string) string {
return f.TSName() + ": " + f.TypeAsTSType(pkgName)
}
// NameForPropertyDoc returns a formatted name for the jsdoc @property declaration
func (f *Field) NameForPropertyDoc() string {
if f.IsOptional {

View File

@@ -69,6 +69,11 @@ func (p *Parser) generateModule() error {
if err != nil {
return err
}
// Generate the index.d.ts file
err = generateIndexTS(moduleDir, packagesToGenerate)
if err != nil {
return err
}
return nil
}
@@ -97,28 +102,28 @@ func createBackendJSDirectory() (string, error) {
func generatePackage(pkg *Package, moduledir string) error {
// // Get path to local file
// typescriptTemplateFile := fs.RelativePath("./package.d.template")
// Get path to local file
typescriptTemplateFile := fs.RelativePath("./package.d.template")
// // Load typescript template
// typescriptTemplateData := fs.MustLoadString(typescriptTemplateFile)
// typescriptTemplate, err := template.New("typescript").Parse(typescriptTemplateData)
// if err != nil {
// return errors.Wrap(err, "Error creating template")
// }
// Load typescript template
typescriptTemplateData := fs.MustLoadString(typescriptTemplateFile)
typescriptTemplate, err := template.New("typescript").Parse(typescriptTemplateData)
if err != nil {
return errors.Wrap(err, "Error creating template")
}
// Execute javascript template
var buffer bytes.Buffer
// err = typescriptTemplate.Execute(&buffer, pkg)
// if err != nil {
// return errors.Wrap(err, "Error generating code")
// }
err = typescriptTemplate.Execute(&buffer, pkg)
if err != nil {
return errors.Wrap(err, "Error generating code")
}
// // Save typescript file
// err = ioutil.WriteFile(filepath.Join(moduledir, "index.d.ts"), buffer.Bytes(), 0755)
// if err != nil {
// return errors.Wrap(err, "Error writing backend package file")
// }
// Save typescript file
err = ioutil.WriteFile(filepath.Join(moduledir, "_"+pkg.Name+".d.ts"), buffer.Bytes(), 0755)
if err != nil {
return errors.Wrap(err, "Error writing backend package file")
}
// Get path to local file
javascriptTemplateFile := fs.RelativePath("./package.template")
@@ -176,6 +181,35 @@ func generateIndexJS(dir string, packages []*Package) error {
return nil
}
func generateIndexTS(dir string, packages []*Package) error {
// Get path to local file
templateFile := fs.RelativePath("./index.d.template")
// Load template
templateData := fs.MustLoadString(templateFile)
indexTSTemplate, err := template.New("index.d").Parse(templateData)
if err != nil {
return errors.Wrap(err, "Error creating template")
}
// Execute template
var buffer bytes.Buffer
err = indexTSTemplate.Execute(&buffer, packages)
if err != nil {
return errors.Wrap(err, "Error generating code")
}
// Calculate target filename
indexJS := filepath.Join(dir, "index.d.ts")
err = ioutil.WriteFile(indexJS, buffer.Bytes(), 0755)
if err != nil {
return errors.Wrap(err, "Error writing backend package index.d.ts file")
}
return nil
}
func generateGlobalsTS(dir string, packages []*Package) error {

View File

@@ -0,0 +1,7 @@
// @ts-check
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
// This file is automatically generated. DO NOT EDIT
{{- range .}}
export const {{.Name}}: typeof import("./_{{.Name}}");
{{- end}}

View File

@@ -150,6 +150,22 @@ func (m *Method) OutputsAsTSText(pkgName string) string {
return strings.Join(result, ", ")
}
// OutputsAsTSDeclarationText generates a string with the method inputs
// formatted in a way acceptable to Javascript
func (m *Method) OutputsAsTSDeclarationText(pkgName string) string {
if len(m.Returns) == 0 {
return "void"
}
var result []string
for _, output := range m.Returns {
result = append(result, goTypeToTSDeclaration(output, pkgName))
}
return strings.Join(result, ", ")
}
// InputsAsJSText generates a string with the method inputs
// formatted in a way acceptable to Javascript
func (m *Method) InputsAsJSText() string {

View File

@@ -0,0 +1,31 @@
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
// This file is automatically generated. DO NOT EDIT
{{- if .DeclarationReferences }}
{{range .DeclarationReferences}}
/// <reference types="../{{.}}" />{{end}}{{- end}}
export namespace {{.Name}} { {{range .Structs}}
{{- if or .IsBound .IsUsedAsData}}
{{if .Comments }}{{range .Comments}}// {{ . }}{{end}}{{- end}}
interface {{.Name}} { {{ if .IsUsedAsData }}
{{- range .Fields}}{{if .Comments }}
{{range .Comments}}//{{ . }}{{end}}{{- end}}
{{.Name}}: {{.TypeAsTSType $.Name}}; {{- end}} {{ end }}
{{- if .IsBound }}
{{- range .Methods}}
/**{{if .Comments }}
{{range .Comments}} * {{ . }}{{end}}
*{{end}}
* @function {{.Name}}
{{range .Inputs}} * @param {{"{"}}{{.JSType}}{{"}"}} {{.Name}}
{{end}} *
* @returns {Promise<{{.OutputsAsTSText $.Name}}>}
*/
{{.Name}}({{.InputsAsTSText $.Name}}): Promise<{{.OutputsAsTSText $.Name}}>;
{{- end}}{{end}}
}{{- end}}
{{end}}
}

View File

@@ -1,31 +1,42 @@
// @ts-check
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
// This file is automatically generated. DO NOT EDIT
{{- if .DeclarationReferences }}
{{range .DeclarationReferences}}
/// <reference types="../{{.}}" />{{end}}{{- end}}
export namespace {{.Name}} { {{range .Structs}}
{{- if or .IsBound .IsUsedAsData}}
{{if .Comments }}{{range .Comments}}// {{ . }}{{end}}{{- end}}
interface {{.Name}} { {{ if .IsUsedAsData }}
{{- range .Fields}}{{if .Comments }}
{{range .Comments}}//{{ . }}{{end}}{{- end}}
{{.Name}}: {{.TypeAsTSType $.Name}}; {{- end}} {{ end }}
{{- if .IsBound }}
{{- range .Methods}}
/**{{if .Comments }}
{{range .Comments}} * {{ . }}{{end}}
*{{end}}
* @function {{.Name}}
{{range .Inputs}} * @param {{"{"}}{{.JSType}}{{"}"}} {{.Name}}
{{end}} *
* @returns {Promise<{{.OutputsAsTSText $.Name}}>}
*/
{{.Name}}({{.InputsAsTSText $.Name}}): Promise<{{.OutputsAsTSText $.Name}}>;
{{- end}}{{end}}
}{{- end}}
{{end}}
{{- range .Structs}}
{{- if .IsBound}}
export namespace {{.Name}} {
{{- range .Methods}}
{{- if .Comments }}
{{range .Comments}}
// {{ . }}{{end}}
{{- end}}
function {{.Name}}({{.InputsAsTSText $.Name}}): Promise<{{.OutputsAsTSDeclarationText $.Name}}>;
{{- end}}
}
{{- end}}
{{- if .IsUsedAsData}}
{{if .Comments }}
/**
{{range .Comments}} *{{ . }}{{end}}
*/
export type {{.Name}} = {
{{- range .Fields}}
{{- if not .Ignored}}
{{- if .Comments }}{{range .Comments}}
//{{ . }}{{end}}{{- end}}
{{ .AsTSDeclaration $.Name}}; {{- end}}
{{- end}}
};
/**
{{if .Comments }}{{range .Comments}} *{{ . }}{{end}}{{end}}
* @typedef {object} {{.Name}}
{{- range .Fields}}{{- if not .JSONOptions.Ignored }}
* @property {{"{"}}{{.TypeForPropertyDoc}}{{"}"}} {{.NameForPropertyDoc}} {{- if .Comments}} - {{- range .Comments}}{{ . }}{{- end}}{{- end}}{{- end}}
{{- end}}
*/
export var {{.Name}}: any;
{{- end}}
{{- end}}
{{- end}}