From 25860777e0b6263553eb904ef3fe22a163ea286b Mon Sep 17 00:00:00 2001 From: Anatoly Milkov Date: Sat, 10 Dec 2022 16:48:54 -0800 Subject: [PATCH] fix: invalid TS module name for proto files with dash or dot chars Fixes #42 The fix patches `data.GetModuleName` func to return a camel cased string to be used as a unique module name in TS artifacts. Here we replace manual conversion of a package name and base file name with `ToCamel` func of the `github.com/iancoleman/strcase` package. This helper package has already been included in go.mod. `ToCamel` removes `.`, `-`, `_` or whitespace chars from the input string and uses those as a mark to capitalize the next letter. --- data/file.go | 16 +++++++--------- data/file_test.go | 27 +++++++++++++++++++++++++++ registry/registry.go | 2 +- 3 files changed, 35 insertions(+), 10 deletions(-) create mode 100644 data/file_test.go diff --git a/data/file.go b/data/file.go index 0299ea1..f93c90c 100644 --- a/data/file.go +++ b/data/file.go @@ -5,6 +5,8 @@ import ( "path/filepath" "sort" "strings" + + "github.com/iancoleman/strcase" ) // File store the information about rendering a file @@ -85,20 +87,16 @@ type Dependency struct { SourceFile string } -// GetModuleName returns module name = package name + file name to be the unique identifier for source file in a ts file +// GetModuleName returns module name = package name + base file name to be the +// unique identifier for source file in a ts file. Package name and base file +// name are converted to camel case, special characters like dot, dash and +// underscore are removed. func GetModuleName(packageName, fileName string) string { baseName := filepath.Base(fileName) ext := filepath.Ext(fileName) name := baseName[0 : len(baseName)-len(ext)] - packageParts := strings.Split(packageName, ".") - - if packageName != "" { - for i, p := range packageParts { - packageParts[i] = strings.ToUpper(p[:1]) + p[1:] - } - } - return strings.Join(packageParts, "") + strings.ToUpper(name[:1]) + name[1:] + return strcase.ToCamel(packageName) + strcase.ToCamel(name) } // GetTSFileName gets the typescript filename out of the proto file name diff --git a/data/file_test.go b/data/file_test.go new file mode 100644 index 0000000..e9beebe --- /dev/null +++ b/data/file_test.go @@ -0,0 +1,27 @@ +package data + +import "testing" + +func TestGetModuleName(t *testing.T) { + tests := []struct { + name string + packageName string + fileName string + want string + }{ + {"empty", "", "", ""}, + {"simple", "mypackage", "service.proto", "MypackageService"}, + {"with file path", "mypackage", "path/to/proto/file/service.proto", "MypackageService"}, + {"with underscore", "my_package", "cool_service.proto", "MyPackageCoolService"}, + {"with dash", "my-package", "cool-service.proto", "MyPackageCoolService"}, + {"with dash and underscore", "my-package", "cool_service.proto", "MyPackageCoolService"}, + {"with dots", "my.package", "cool.service.proto", "MyPackageCoolService"}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := GetModuleName(tt.packageName, tt.fileName); got != tt.want { + t.Errorf("GetModuleName() = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/registry/registry.go b/registry/registry.go index fdb05a9..f384d1d 100644 --- a/registry/registry.go +++ b/registry/registry.go @@ -336,7 +336,7 @@ func (r *Registry) collectExternalDependenciesFromData(filesData map[string]*dat if _, ok := dependencies[identifier]; !ok { // only fill in if this file has not been mentioned before. - // the way import in the genrated file works is like + // the way import in the generated file works is like // import * as [ModuleIdentifier] from '[Source File]' // so there only needs to be added once. // Referencing types will be [ModuleIdentifier].[PackageIdentifier]