mirror of
https://github.com/wailsapp/wails.git
synced 2025-05-02 18:10:48 +08:00
Ability to define prefix / suffix for TS module (#2101)
* add tspostfix and tsprefix flags + organise under struct * postifx -> suffix * tsPrefix options on bindings struct * pass prefix and suffix to the executable * add support for CLI flags for generating module * method to set TSpref/suff to bindings * use passed ts prefix for typescriptify * add brief Readme udpate to include new flags * create reusable common flags * use common flags instead of hardcoded text * support tsprefix & suffix for dev * add tsPrefix & tsSuffix for build cmd * take pref & suff in account when gen d.ts * export colorsful log functions into utils for reuse * detect and warn the user about usage of reserved keyword * fmt * add TrimSpace on fn input * refactor utils -> logutils * add bindings -> ts_generation options to wailsjson parse * use wailsjson for ts generation * update warning message + extract to func * remove suff/pref info from readme * update json schema * add tests for prefix and suffix case * rename suffix method * Update v2/internal/typescriptify/typescriptify.go Co-authored-by: Lea Anthony <lea.anthony@gmail.com> * Update website/static/schemas/config.v2.json Co-authored-by: Lea Anthony <lea.anthony@gmail.com> * Update website/static/schemas/config.v2.json Co-authored-by: Lea Anthony <lea.anthony@gmail.com> * update changelog * Minor tweaks Co-authored-by: Lea Anthony <lea.anthony@gmail.com>
This commit is contained in:
parent
c1c1bff7a4
commit
ca8a1fab36
@ -2,7 +2,6 @@ package build
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/wailsapp/wails/v2/pkg/commands/buildtags"
|
||||
"io"
|
||||
"os"
|
||||
"os/exec"
|
||||
@ -11,6 +10,8 @@ import (
|
||||
"text/tabwriter"
|
||||
"time"
|
||||
|
||||
"github.com/wailsapp/wails/v2/pkg/commands/buildtags"
|
||||
|
||||
"github.com/wailsapp/wails/v2/internal/colour"
|
||||
"github.com/wailsapp/wails/v2/internal/project"
|
||||
"github.com/wailsapp/wails/v2/internal/system"
|
||||
|
@ -33,36 +33,13 @@ import (
|
||||
|
||||
"github.com/fsnotify/fsnotify"
|
||||
"github.com/leaanthony/clir"
|
||||
"github.com/wailsapp/wails/v2/cmd/wails/internal/logutils"
|
||||
"github.com/wailsapp/wails/v2/internal/fs"
|
||||
"github.com/wailsapp/wails/v2/internal/process"
|
||||
"github.com/wailsapp/wails/v2/pkg/clilogger"
|
||||
"github.com/wailsapp/wails/v2/pkg/commands/build"
|
||||
)
|
||||
|
||||
func LogGreen(message string, args ...interface{}) {
|
||||
if len(message) == 0 {
|
||||
return
|
||||
}
|
||||
text := fmt.Sprintf(message, args...)
|
||||
println(colour.Green(text))
|
||||
}
|
||||
|
||||
func LogRed(message string, args ...interface{}) {
|
||||
if len(message) == 0 {
|
||||
return
|
||||
}
|
||||
text := fmt.Sprintf(message, args...)
|
||||
println(colour.Red(text))
|
||||
}
|
||||
|
||||
func LogDarkYellow(message string, args ...interface{}) {
|
||||
if len(message) == 0 {
|
||||
return
|
||||
}
|
||||
text := fmt.Sprintf(message, args...)
|
||||
println(colour.DarkYellow(text))
|
||||
}
|
||||
|
||||
func sliceToMap(input []string) map[string]struct{} {
|
||||
result := map[string]struct{}{}
|
||||
for _, value := range input {
|
||||
@ -184,16 +161,18 @@ func AddSubcommand(app *clir.Cli, w io.Writer) error {
|
||||
|
||||
if !buildOptions.SkipBindings {
|
||||
if flags.verbosity == build.VERBOSE {
|
||||
LogGreen("Generating Bindings...")
|
||||
logutils.LogGreen("Generating Bindings...")
|
||||
}
|
||||
stdout, err := bindings.GenerateBindings(bindings.Options{
|
||||
Tags: buildOptions.UserTags,
|
||||
Tags: buildOptions.UserTags,
|
||||
TsPrefix: projectConfig.Bindings.TsGeneration.Prefix,
|
||||
TsSuffix: projectConfig.Bindings.TsGeneration.Suffix,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if flags.verbosity == build.VERBOSE {
|
||||
LogGreen(stdout)
|
||||
logutils.LogGreen(stdout)
|
||||
}
|
||||
}
|
||||
|
||||
@ -238,7 +217,7 @@ func AddSubcommand(app *clir.Cli, w io.Writer) error {
|
||||
}
|
||||
defer func() {
|
||||
if err := killProcessAndCleanupBinary(debugBinaryProcess, appBinary); err != nil {
|
||||
LogDarkYellow("Unable to kill process and cleanup binary: %s", err)
|
||||
logutils.LogDarkYellow("Unable to kill process and cleanup binary: %s", err)
|
||||
}
|
||||
}()
|
||||
|
||||
@ -263,17 +242,17 @@ func AddSubcommand(app *clir.Cli, w io.Writer) error {
|
||||
}
|
||||
}(watcher)
|
||||
|
||||
LogGreen("Watching (sub)/directory: %s", cwd)
|
||||
LogGreen("Using DevServer URL: %s", devServerURL)
|
||||
logutils.LogGreen("Watching (sub)/directory: %s", cwd)
|
||||
logutils.LogGreen("Using DevServer URL: %s", devServerURL)
|
||||
if flags.frontendDevServerURL != "" {
|
||||
LogGreen("Using Frontend DevServer URL: %s", flags.frontendDevServerURL)
|
||||
logutils.LogGreen("Using Frontend DevServer URL: %s", flags.frontendDevServerURL)
|
||||
}
|
||||
LogGreen("Using reload debounce setting of %d milliseconds", flags.debounceMS)
|
||||
logutils.LogGreen("Using reload debounce setting of %d milliseconds", flags.debounceMS)
|
||||
|
||||
// Show dev server URL in terminal after 3 seconds
|
||||
go func() {
|
||||
time.Sleep(3 * time.Second)
|
||||
LogGreen("\n\nTo develop in the browser and call your bound Go methods from Javascript, navigate to: %s", devServerURL)
|
||||
logutils.LogGreen("\n\nTo develop in the browser and call your bound Go methods from Javascript, navigate to: %s", devServerURL)
|
||||
}()
|
||||
|
||||
// Watch for changes and trigger restartApp()
|
||||
@ -288,7 +267,7 @@ func AddSubcommand(app *clir.Cli, w io.Writer) error {
|
||||
debugBinaryProcess = nil
|
||||
appBinary = ""
|
||||
|
||||
LogGreen("Development mode exited")
|
||||
logutils.LogGreen("Development mode exited")
|
||||
|
||||
return nil
|
||||
})
|
||||
@ -312,7 +291,7 @@ func killProcessAndCleanupBinary(process *process.Process, binary string) error
|
||||
}
|
||||
|
||||
func runCommand(dir string, exitOnError bool, command string, args ...string) error {
|
||||
LogGreen("Executing: " + command + " " + strings.Join(args, " "))
|
||||
logutils.LogGreen("Executing: " + command + " " + strings.Join(args, " "))
|
||||
cmd := exec.Command(command, args...)
|
||||
cmd.Dir = dir
|
||||
output, err := cmd.CombinedOutput()
|
||||
@ -460,7 +439,7 @@ func runFrontendDevWatcherCommand(frontendDirectory string, devCommand string, d
|
||||
}
|
||||
}
|
||||
|
||||
LogGreen("Running frontend DevWatcher command: '%s'", devCommand)
|
||||
logutils.LogGreen("Running frontend DevWatcher command: '%s'", devCommand)
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(1)
|
||||
|
||||
@ -474,7 +453,7 @@ func runFrontendDevWatcherCommand(frontendDirectory string, devCommand string, d
|
||||
if err := cmd.Wait(); err != nil {
|
||||
wasRunning := atomic.CompareAndSwapInt32(&state, stateRunning, stateStopped)
|
||||
if err.Error() != "exit status 1" && wasRunning {
|
||||
LogRed("Error from DevWatcher '%s': %s", devCommand, err.Error())
|
||||
logutils.LogRed("Error from DevWatcher '%s': %s", devCommand, err.Error())
|
||||
}
|
||||
}
|
||||
atomic.StoreInt32(&state, stateStopped)
|
||||
@ -496,13 +475,13 @@ func restartApp(buildOptions *build.Options, debugBinaryProcess *process.Process
|
||||
appBinary, err := build.Build(buildOptions)
|
||||
println()
|
||||
if err != nil {
|
||||
LogRed("Build error - " + err.Error())
|
||||
logutils.LogRed("Build error - " + err.Error())
|
||||
|
||||
msg := "Continuing to run current version"
|
||||
if debugBinaryProcess == nil {
|
||||
msg = "No version running, build will be retriggered as soon as changes have been detected"
|
||||
}
|
||||
LogDarkYellow(msg)
|
||||
logutils.LogDarkYellow(msg)
|
||||
return nil, "", nil
|
||||
}
|
||||
|
||||
@ -558,7 +537,7 @@ func doWatcherLoop(buildOptions *build.Options, debugBinaryProcess *process.Proc
|
||||
}
|
||||
thePath, err := filepath.Abs(dir)
|
||||
if err != nil {
|
||||
LogRed("Unable to expand reloadDir '%s': %s", dir, err)
|
||||
logutils.LogRed("Unable to expand reloadDir '%s': %s", dir, err)
|
||||
continue
|
||||
}
|
||||
dirsThatTriggerAReload = append(dirsThatTriggerAReload, thePath)
|
||||
@ -585,7 +564,7 @@ func doWatcherLoop(buildOptions *build.Options, debugBinaryProcess *process.Proc
|
||||
quit = true
|
||||
}
|
||||
case err := <-watcher.Errors:
|
||||
LogDarkYellow(err.Error())
|
||||
logutils.LogDarkYellow(err.Error())
|
||||
case item := <-watcher.Events:
|
||||
isEligibleFile := func(fileName string) bool {
|
||||
// Iterate all file patterns
|
||||
@ -637,7 +616,7 @@ func doWatcherLoop(buildOptions *build.Options, debugBinaryProcess *process.Proc
|
||||
if err != nil {
|
||||
buildOptions.Logger.Fatal("%s", err.Error())
|
||||
}
|
||||
LogGreen("Added new directory to watcher: %s", item.Name)
|
||||
logutils.LogGreen("Added new directory to watcher: %s", item.Name)
|
||||
}
|
||||
} else if isEligibleFile(item.Name) {
|
||||
// Handle creation of new file.
|
||||
@ -652,11 +631,11 @@ func doWatcherLoop(buildOptions *build.Options, debugBinaryProcess *process.Proc
|
||||
case <-timer.C:
|
||||
if rebuild {
|
||||
rebuild = false
|
||||
LogGreen("[Rebuild triggered] files updated")
|
||||
logutils.LogGreen("[Rebuild triggered] files updated")
|
||||
// Try and build the app
|
||||
newBinaryProcess, _, err := restartApp(buildOptions, debugBinaryProcess, flags, exitCodeChannel)
|
||||
if err != nil {
|
||||
LogRed("Error during build: %s", err.Error())
|
||||
logutils.LogRed("Error during build: %s", err.Error())
|
||||
continue
|
||||
}
|
||||
// If we have a new process, saveConfig it
|
||||
@ -669,11 +648,11 @@ func doWatcherLoop(buildOptions *build.Options, debugBinaryProcess *process.Proc
|
||||
if assetDir == "" {
|
||||
resp, err := http.Get(assetDirURL)
|
||||
if err != nil {
|
||||
LogRed("Error during retrieving assetdir: %s", err.Error())
|
||||
logutils.LogRed("Error during retrieving assetdir: %s", err.Error())
|
||||
} else {
|
||||
content, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
LogRed("Error reading assetdir from devserver: %s", err.Error())
|
||||
logutils.LogRed("Error reading assetdir from devserver: %s", err.Error())
|
||||
} else {
|
||||
assetDir = string(content)
|
||||
}
|
||||
@ -689,19 +668,19 @@ func doWatcherLoop(buildOptions *build.Options, debugBinaryProcess *process.Proc
|
||||
}
|
||||
}
|
||||
} else if len(dirsThatTriggerAReload) == 0 {
|
||||
LogRed("Reloading couldn't be triggered: Please specify -assetdir or -reloaddirs")
|
||||
logutils.LogRed("Reloading couldn't be triggered: Please specify -assetdir or -reloaddirs")
|
||||
}
|
||||
}
|
||||
if reload {
|
||||
reload = false
|
||||
_, err := http.Get(reloadURL)
|
||||
if err != nil {
|
||||
LogRed("Error during refresh: %s", err.Error())
|
||||
logutils.LogRed("Error during refresh: %s", err.Error())
|
||||
}
|
||||
}
|
||||
changedPaths = map[string]struct{}{}
|
||||
case <-quitChannel:
|
||||
LogGreen("\nCaught quit")
|
||||
logutils.LogGreen("\nCaught quit")
|
||||
quit = true
|
||||
}
|
||||
}
|
||||
|
@ -7,6 +7,7 @@ import (
|
||||
"os/exec"
|
||||
"syscall"
|
||||
|
||||
"github.com/wailsapp/wails/v2/cmd/wails/internal/logutils"
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
@ -30,7 +31,7 @@ func killProc(cmd *exec.Cmd, devCommand string) {
|
||||
if err == nil {
|
||||
err := syscall.Kill(-pgid, unix.SIGTERM) // note the minus sign
|
||||
if err != nil {
|
||||
LogRed("Error from '%s' when attempting to kill the process: %s", devCommand, err.Error())
|
||||
logutils.LogRed("Error from '%s' when attempting to kill the process: %s", devCommand, err.Error())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -7,6 +7,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/acarl005/stripansi"
|
||||
"github.com/wailsapp/wails/v2/cmd/wails/internal/logutils"
|
||||
)
|
||||
|
||||
// stdoutScanner acts as a stdout target that will scan the incoming
|
||||
@ -35,10 +36,10 @@ func (s *stdoutScanner) Write(data []byte) (n int, err error) {
|
||||
continue
|
||||
}
|
||||
viteServerURL := strings.TrimSpace(line[index+6:])
|
||||
LogGreen("Vite Server URL: %s", viteServerURL)
|
||||
logutils.LogGreen("Vite Server URL: %s", viteServerURL)
|
||||
_, err := url.Parse(viteServerURL)
|
||||
if err != nil {
|
||||
LogRed(err.Error())
|
||||
logutils.LogRed(err.Error())
|
||||
} else {
|
||||
s.ViteServerURLChan <- viteServerURL
|
||||
}
|
||||
|
@ -16,3 +16,10 @@ Generate a starter template for you to customise.
|
||||
| :------------- | :----------- |
|
||||
| -frontend | Copies all the files from the current directory into the template's `frontend` directory. Useful for converting frontend projects created by boilerplate generators. |
|
||||
| -q | Suppress output |
|
||||
|
||||
|
||||
## Module
|
||||
|
||||
`wails generate module [-h]`
|
||||
|
||||
Generate TS module for your frontend
|
||||
|
@ -1,28 +1,45 @@
|
||||
package generate
|
||||
|
||||
import (
|
||||
"io"
|
||||
"os"
|
||||
|
||||
"github.com/leaanthony/clir"
|
||||
"github.com/wailsapp/wails/v2/internal/project"
|
||||
"github.com/wailsapp/wails/v2/pkg/commands/bindings"
|
||||
"github.com/wailsapp/wails/v2/pkg/commands/buildtags"
|
||||
"io"
|
||||
)
|
||||
|
||||
type generateFlags struct {
|
||||
tags string
|
||||
}
|
||||
|
||||
// AddModuleCommand adds the `module` subcommand for the `generate` command
|
||||
func AddModuleCommand(app *clir.Cli, parent *clir.Command, w io.Writer) error {
|
||||
|
||||
command := parent.NewSubCommand("module", "Generate wailsjs modules")
|
||||
var tags string
|
||||
command.StringFlag("tags", "tags to pass to Go compiler (quoted and space separated)", &tags)
|
||||
genFlags := generateFlags{}
|
||||
command.StringFlag("tags", "tags to pass to Go compiler (quoted and space separated)", &genFlags.tags)
|
||||
|
||||
command.Action(func() error {
|
||||
cwd, err := os.Getwd()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
projectConfig, err := project.Load(cwd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
buildTags, err := buildtags.Parse(tags)
|
||||
buildTags, err := buildtags.Parse(genFlags.tags)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = bindings.GenerateBindings(bindings.Options{
|
||||
Tags: buildTags,
|
||||
Tags: buildTags,
|
||||
TsPrefix: projectConfig.Bindings.TsGeneration.Prefix,
|
||||
TsSuffix: projectConfig.Bindings.TsGeneration.Suffix,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
|
31
v2/cmd/wails/internal/logutils/color-logs.go
Normal file
31
v2/cmd/wails/internal/logutils/color-logs.go
Normal file
@ -0,0 +1,31 @@
|
||||
package logutils
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/wailsapp/wails/v2/internal/colour"
|
||||
)
|
||||
|
||||
func LogGreen(message string, args ...interface{}) {
|
||||
if len(message) == 0 {
|
||||
return
|
||||
}
|
||||
text := fmt.Sprintf(message, args...)
|
||||
println(colour.Green(text))
|
||||
}
|
||||
|
||||
func LogRed(message string, args ...interface{}) {
|
||||
if len(message) == 0 {
|
||||
return
|
||||
}
|
||||
text := fmt.Sprintf(message, args...)
|
||||
println(colour.Red(text))
|
||||
}
|
||||
|
||||
func LogDarkYellow(message string, args ...interface{}) {
|
||||
if len(message) == 0 {
|
||||
return
|
||||
}
|
||||
text := fmt.Sprintf(message, args...)
|
||||
println(colour.DarkYellow(text))
|
||||
}
|
@ -5,6 +5,7 @@ package app
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"flag"
|
||||
|
||||
"github.com/leaanthony/gosod"
|
||||
"github.com/wailsapp/wails/v2/internal/binding"
|
||||
@ -25,8 +26,35 @@ func (a *App) Run() error {
|
||||
a.options.OnBeforeClose,
|
||||
}
|
||||
|
||||
// Check for CLI Flags
|
||||
bindingFlags := flag.NewFlagSet("bindings", flag.ContinueOnError)
|
||||
|
||||
var tsPrefixFlag *string
|
||||
var tsPostfixFlag *string
|
||||
|
||||
tsPrefix := os.Getenv("tsprefix")
|
||||
if tsPrefix == "" {
|
||||
tsPrefixFlag = bindingFlags.String("tsprefix", "", "Prefix for generated typescript entities")
|
||||
}
|
||||
|
||||
tsSuffix := os.Getenv("tssuffix")
|
||||
if tsSuffix == "" {
|
||||
tsPostfixFlag = bindingFlags.String("tssuffix", "", "Suffix for generated typescript entities")
|
||||
}
|
||||
|
||||
_ = bindingFlags.Parse(os.Args[1:])
|
||||
if tsPrefixFlag != nil {
|
||||
tsPrefix = *tsPrefixFlag
|
||||
}
|
||||
if tsPostfixFlag != nil {
|
||||
tsSuffix = *tsPostfixFlag
|
||||
}
|
||||
|
||||
appBindings := binding.NewBindings(a.logger, a.options.Bind, bindingExemptions, IsObfuscated())
|
||||
|
||||
appBindings.SetTsPrefix(tsPrefix)
|
||||
appBindings.SetTsPostfix(tsSuffix)
|
||||
|
||||
err := generateBindings(appBindings)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -23,6 +23,8 @@ type Bindings struct {
|
||||
exemptions slicer.StringSlicer
|
||||
|
||||
structsToGenerateTS map[string]map[string]interface{}
|
||||
tsPrefix string
|
||||
tsSuffix string
|
||||
obfuscate bool
|
||||
}
|
||||
|
||||
@ -92,6 +94,8 @@ func (b *Bindings) GenerateModels() ([]byte, error) {
|
||||
for packageName, structsToGenerate := range b.structsToGenerateTS {
|
||||
thisPackageCode := ""
|
||||
w := typescriptify.New()
|
||||
w.WithPrefix(b.tsPrefix)
|
||||
w.WithSuffix(b.tsSuffix)
|
||||
w.Namespace = packageName
|
||||
w.WithBackupDir("")
|
||||
w.KnownStructs = allStructNames
|
||||
@ -219,6 +223,16 @@ func (b *Bindings) AddStructToGenerateTS(packageName string, structName string,
|
||||
}
|
||||
}
|
||||
|
||||
func (b *Bindings) SetTsPrefix(prefix string) *Bindings {
|
||||
b.tsPrefix = prefix
|
||||
return b
|
||||
}
|
||||
|
||||
func (b *Bindings) SetTsSuffix(postfix string) *Bindings {
|
||||
b.tsSuffix = postfix
|
||||
return b
|
||||
}
|
||||
|
||||
func (b *Bindings) getAllStructNames() *slicer.StringSlicer {
|
||||
var result slicer.StringSlicer
|
||||
for packageName, structsToGenerate := range b.structsToGenerateTS {
|
||||
|
@ -16,6 +16,12 @@ type BindingTest struct {
|
||||
exemptions []interface{}
|
||||
want string
|
||||
shouldError bool
|
||||
TsGenerationOptionsTest
|
||||
}
|
||||
|
||||
type TsGenerationOptionsTest struct {
|
||||
TsPrefix string
|
||||
TsSuffix string
|
||||
}
|
||||
|
||||
func TestBindings_GenerateModels(t *testing.T) {
|
||||
@ -30,6 +36,7 @@ func TestBindings_GenerateModels(t *testing.T) {
|
||||
SingleFieldTest,
|
||||
MultistructTest,
|
||||
EmptyStructTest,
|
||||
GeneratedJsEntityTest,
|
||||
}
|
||||
|
||||
testLogger := &logger.Logger{}
|
||||
@ -40,6 +47,10 @@ func TestBindings_GenerateModels(t *testing.T) {
|
||||
err := b.Add(s)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
b.SetTsPrefix(tt.TsPrefix)
|
||||
|
||||
// TODO - rename this to SetTsSuffix
|
||||
b.SetTsSuffix(tt.TsSuffix)
|
||||
got, err := b.GenerateModels()
|
||||
if (err != nil) != tt.shouldError {
|
||||
t.Errorf("GenerateModels() error = %v, shouldError %v", err, tt.shouldError)
|
||||
|
@ -0,0 +1,41 @@
|
||||
package binding_test
|
||||
|
||||
type GeneratedJsEntity struct {
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
func (s GeneratedJsEntity) Get() GeneratedJsEntity {
|
||||
return s
|
||||
}
|
||||
|
||||
var GeneratedJsEntityTest = BindingTest{
|
||||
name: "GeneratedJsEntityTest ",
|
||||
structs: []interface{}{
|
||||
&GeneratedJsEntity{},
|
||||
},
|
||||
exemptions: nil,
|
||||
shouldError: false,
|
||||
TsGenerationOptionsTest: TsGenerationOptionsTest{
|
||||
TsPrefix: "MY_PREFIX_",
|
||||
TsSuffix: "_MY_SUFFIX",
|
||||
},
|
||||
want: `
|
||||
export namespace binding_test {
|
||||
|
||||
export class MY_PREFIX_GeneratedJsEntity_MY_SUFFIX {
|
||||
name: string;
|
||||
|
||||
static createFrom(source: any = {}) {
|
||||
return new MY_PREFIX_GeneratedJsEntity_MY_SUFFIX(source);
|
||||
}
|
||||
|
||||
constructor(source: any = {}) {
|
||||
if ('string' === typeof source) source = JSON.parse(source);
|
||||
this.name = source["name"];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
`,
|
||||
}
|
@ -79,11 +79,13 @@ func (b *Bindings) GenerateGoBindings(baseDir string) error {
|
||||
tsBody.WriteString(args.Join(",") + "):")
|
||||
returnType := "Promise"
|
||||
if methodDetails.OutputCount() > 0 {
|
||||
firstType := goTypeToTypescriptType(methodDetails.Outputs[0].TypeName, &importNamespaces)
|
||||
outputTypeName := entityFullReturnType(methodDetails.Outputs[0].TypeName, b.tsPrefix, b.tsSuffix, &importNamespaces)
|
||||
firstType := goTypeToTypescriptType(outputTypeName, &importNamespaces)
|
||||
returnType += "<" + firstType
|
||||
if methodDetails.OutputCount() == 2 {
|
||||
if methodDetails.Outputs[1].TypeName != "error" {
|
||||
secondType := goTypeToTypescriptType(methodDetails.Outputs[1].TypeName, &importNamespaces)
|
||||
outputTypeName = entityFullReturnType(methodDetails.Outputs[1].TypeName, b.tsPrefix, b.tsSuffix, &importNamespaces)
|
||||
secondType := goTypeToTypescriptType(outputTypeName, &importNamespaces)
|
||||
returnType += "|" + secondType
|
||||
}
|
||||
}
|
||||
@ -171,3 +173,12 @@ func goTypeToTypescriptType(input string, importNamespaces *slicer.StringSlicer)
|
||||
}
|
||||
return goTypeToJSDocType(input, importNamespaces)
|
||||
}
|
||||
|
||||
func entityFullReturnType(input, prefix, suffix string, importNamespaces *slicer.StringSlicer) string {
|
||||
if strings.ContainsRune(input, '.') {
|
||||
nameSpace, returnType := getSplitReturn(input)
|
||||
return nameSpace + "." + prefix + returnType + suffix
|
||||
}
|
||||
|
||||
return input
|
||||
}
|
||||
|
@ -166,6 +166,12 @@ func getPackageName(in string) string {
|
||||
return result
|
||||
}
|
||||
|
||||
func getSplitReturn(in string) (string, string) {
|
||||
result := strings.Split(in, ".")
|
||||
return result[0], result[1]
|
||||
|
||||
}
|
||||
|
||||
func hasElements(typ reflect.Type) bool {
|
||||
kind := typ.Kind()
|
||||
return kind == reflect.Ptr || kind == reflect.Array || kind == reflect.Slice || kind == reflect.Map
|
||||
|
@ -2,11 +2,12 @@ package project
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"github.com/samber/lo"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
|
||||
"github.com/samber/lo"
|
||||
)
|
||||
|
||||
// Project holds the data related to a Wails project
|
||||
@ -92,6 +93,8 @@ type Project struct {
|
||||
|
||||
// Frontend directory
|
||||
FrontendDir string `json:"frontend:dir"`
|
||||
|
||||
Bindings Bindings `json:"bindings"`
|
||||
}
|
||||
|
||||
func (p *Project) GetFrontendDir() string {
|
||||
@ -222,6 +225,15 @@ type Info struct {
|
||||
Comments *string `json:"comments"`
|
||||
}
|
||||
|
||||
type Bindings struct {
|
||||
TsGeneration TsGeneration `json:"ts_generation"`
|
||||
}
|
||||
|
||||
type TsGeneration struct {
|
||||
Prefix string `json:"prefix"`
|
||||
Suffix string `json:"suffix"`
|
||||
}
|
||||
|
||||
// Parse the given JSON data into a Project struct
|
||||
func Parse(projectData []byte) (*Project, error) {
|
||||
project := &Project{}
|
||||
|
69
v2/internal/typescriptify/js-reserved-keywords.go
Normal file
69
v2/internal/typescriptify/js-reserved-keywords.go
Normal file
@ -0,0 +1,69 @@
|
||||
package typescriptify
|
||||
|
||||
var jsReservedKeywords []string = []string{
|
||||
"abstract",
|
||||
"arguments",
|
||||
"await",
|
||||
"boolean",
|
||||
"break",
|
||||
"byte",
|
||||
"case",
|
||||
"catch",
|
||||
"char",
|
||||
"class",
|
||||
"const",
|
||||
"continue",
|
||||
"debugger",
|
||||
"default",
|
||||
"delete",
|
||||
"do",
|
||||
"double",
|
||||
"else",
|
||||
"enum",
|
||||
"eval",
|
||||
"export",
|
||||
"extends",
|
||||
"false",
|
||||
"final",
|
||||
"finally",
|
||||
"float",
|
||||
"for",
|
||||
"function",
|
||||
"goto",
|
||||
"if",
|
||||
"implements",
|
||||
"import",
|
||||
"in",
|
||||
"instanceof",
|
||||
"int",
|
||||
"interface",
|
||||
"let",
|
||||
"long",
|
||||
"native",
|
||||
"new",
|
||||
"null",
|
||||
"package",
|
||||
"private",
|
||||
"protected",
|
||||
"public",
|
||||
"return",
|
||||
"short",
|
||||
"static",
|
||||
"super",
|
||||
"switch",
|
||||
"synchronized",
|
||||
"this",
|
||||
"throw",
|
||||
"throws",
|
||||
"transient",
|
||||
"true",
|
||||
"try",
|
||||
"typeof",
|
||||
"var",
|
||||
"void",
|
||||
"volotile",
|
||||
"while",
|
||||
"with",
|
||||
"yield",
|
||||
"object",
|
||||
}
|
@ -4,6 +4,7 @@ import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
"path"
|
||||
"reflect"
|
||||
@ -595,6 +596,11 @@ func (t *TypeScriptify) convertType(depth int, typeOf reflect.Type, customCode m
|
||||
t.alreadyConverted[typeOf.String()] = true
|
||||
|
||||
entityName := t.Prefix + typeOf.Name() + t.Suffix
|
||||
|
||||
if typeClashWithReservedKeyword(entityName) {
|
||||
warnAboutTypesClash(entityName)
|
||||
}
|
||||
|
||||
result := ""
|
||||
if t.CreateInterface {
|
||||
result += fmt.Sprintf("interface %s {\n", entityName)
|
||||
@ -901,3 +907,21 @@ func differentNamespaces(namespace string, typeOf reflect.Type) bool {
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func typeClashWithReservedKeyword(input string) bool {
|
||||
in := strings.ToLower(strings.TrimSpace(input))
|
||||
for _, v := range jsReservedKeywords {
|
||||
if in == v {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func warnAboutTypesClash(entity string) {
|
||||
// TODO: Refactor logging
|
||||
l := log.New(os.Stderr, "", 0)
|
||||
l.Println(fmt.Sprintf("Usage of reserved keyword found and not supported: %s", entity))
|
||||
log.Println("Please rename returned type or consider adding bindings config to your wails.json")
|
||||
}
|
||||
|
@ -2,12 +2,15 @@ package bindings
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/samber/lo"
|
||||
"github.com/wailsapp/wails/v2/internal/shell"
|
||||
"github.com/wailsapp/wails/v2/pkg/commands/buildtags"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
|
||||
"github.com/samber/lo"
|
||||
"github.com/wailsapp/wails/v2/internal/colour"
|
||||
"github.com/wailsapp/wails/v2/internal/shell"
|
||||
"github.com/wailsapp/wails/v2/pkg/commands/buildtags"
|
||||
)
|
||||
|
||||
// Options for generating bindings
|
||||
@ -16,6 +19,8 @@ type Options struct {
|
||||
Tags []string
|
||||
ProjectDirectory string
|
||||
GoModTidy bool
|
||||
TsPrefix string
|
||||
TsSuffix string
|
||||
}
|
||||
|
||||
// GenerateBindings generates bindings for the Wails project in the given ProjectDirectory.
|
||||
@ -57,10 +62,14 @@ func GenerateBindings(options Options) (string, error) {
|
||||
_ = os.Remove(filename)
|
||||
}()
|
||||
|
||||
stdout, stderr, err = shell.RunCommand(workingDirectory, filename)
|
||||
stdout, stderr, err = shell.RunCommand(workingDirectory, filename, "-tsprefix", options.TsPrefix, "-tssuffix", options.TsSuffix)
|
||||
if err != nil {
|
||||
return stdout, fmt.Errorf("%s\n%s\n%s", stdout, stderr, err)
|
||||
}
|
||||
|
||||
if stderr != "" {
|
||||
log.Println(colour.DarkYellow(stderr))
|
||||
}
|
||||
|
||||
return stdout, nil
|
||||
}
|
||||
|
@ -199,6 +199,8 @@ func GenerateBindings(buildOptions *Options) error {
|
||||
output, err := bindings.GenerateBindings(bindings.Options{
|
||||
Tags: buildOptions.UserTags,
|
||||
GoModTidy: !buildOptions.SkipModTidy,
|
||||
TsPrefix: buildOptions.ProjectData.Bindings.TsGeneration.Prefix,
|
||||
TsSuffix: buildOptions.ProjectData.Bindings.TsGeneration.Suffix,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -18,6 +18,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
- Added `OpenInspectorOnStartup` to debug options to allow opening the WebInspector during startup of the application in debug mode. Added by @stffabi in [PR](https://github.com/wailsapp/wails/pull/2080)
|
||||
- On macOS `wails doctor` now also shows the version of Xcode installed. Added by @stffabi in [PR](https://github.com/wailsapp/wails/pull/2089)
|
||||
- The [AssetServer](/docs/reference/options#assetserver) now supports handling range-requests if the [Assets](/docs/reference/options/#assets-1) `fs.FS` provides an `io.ReadSeeker`. Added by @stffabi in [PR](https://github.com/wailsapp/wails/pull/2091)
|
||||
- Add new property for the `wails.json` config file - `bindings`. More information on the new property can be found in the updated [schema](static/schemas/config.v2.json). Properties `prefix` and `suffix` allow you to control the generated TypeScript entity name in the `model.ts` file. Added by @OlegGulevskyy in [PR](https://github.com/wailsapp/wails/pull/2101)
|
||||
- The `WindowSetAlwaysOnTop` method is now exposed in the JS runtime. Fixed by @gotid in [PR](https://github.com/wailsapp/wails/pull/2128)
|
||||
|
||||
### Fixed
|
||||
|
@ -226,5 +226,25 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"bindings": {
|
||||
"type": "object",
|
||||
"description": "Bindings configurations",
|
||||
"properties": {
|
||||
"ts_generation": {
|
||||
"type": "object",
|
||||
"description": "model.ts file generation config",
|
||||
"properties": {
|
||||
"prefix": {
|
||||
"type": "string",
|
||||
"description": "All generated JavaScript entities will be prefixed with this value"
|
||||
},
|
||||
"suffix": {
|
||||
"type": "string",
|
||||
"description": "All generated JavaScript entities will be suffixed with this value"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user