From 33f56ac17b9a3ca926f69bad19800e66cf1baf84 Mon Sep 17 00:00:00 2001 From: Nate Moore Date: Wed, 4 Oct 2023 12:52:32 -0500 Subject: [PATCH] wip: add util to infer expected params from filename --- internal/printer/utils.go | 34 ++++++++++++++++++++++ internal/printer/utils_test.go | 52 ++++++++++++++++++++++++++++++++++ 2 files changed, 86 insertions(+) create mode 100644 internal/printer/utils_test.go diff --git a/internal/printer/utils.go b/internal/printer/utils.go index 7da77c159..48c98f5dd 100644 --- a/internal/printer/utils.go +++ b/internal/printer/utils.go @@ -3,6 +3,7 @@ package printer import ( "errors" "fmt" + "path/filepath" "regexp" "strings" @@ -46,6 +47,39 @@ func getTSXComponentName(filename string) string { } } +func trimExt(filename string) string { + return strings.TrimSuffix(filename, filepath.Ext(filename)) +} + +func getParamsTypeFromFilename(filename string) string { + defaultType := "Record" + if filename == "" { + return defaultType + } + if len(filename) == 0 { + return defaultType + } + parts := strings.Split(filename, "/") + params := make([]string, 0) + r, err := regexp.Compile(`\[(?:\.{3})?([^]]+)\]`) + if err != nil { + return defaultType + } + for _, part := range parts { + if !strings.ContainsAny(part, "[]") { + continue + } + part = trimExt(part) + for _, match := range r.FindAllStringSubmatch(part, -1) { + params = append(params, fmt.Sprintf(`"%s"`, match[1])) + } + } + if len(params) == 0 { + return defaultType + } + return fmt.Sprintf("Record<%s, string | number>", strings.Join(params, " | ")) +} + func getComponentName(filename string) string { if len(filename) == 0 { return "$$Component" diff --git a/internal/printer/utils_test.go b/internal/printer/utils_test.go new file mode 100644 index 000000000..73d09222b --- /dev/null +++ b/internal/printer/utils_test.go @@ -0,0 +1,52 @@ +package printer + +import ( + "strings" + "testing" + + "github.com/withastro/compiler/internal/test_utils" +) + +type paramsTestcase struct { + name string + want string +} + +func TestUtilParamsType(t *testing.T) { + tests := []paramsTestcase{ + { + name: "/src/pages/index.astro", + want: `Record`, + }, + { + name: "/src/pages/blog/[slug].astro", + want: `Record<"slug", string | number>`, + }, + { + name: "/src/pages/[lang]/blog/[slug].astro", + want: `Record<"lang" | "slug", string | number>`, + }, + { + name: "/src/pages/[...fallback].astro", + want: `Record<"fallback", string | number>`, + }, + { + name: "/src/pages/[year]-[month]-[day]/[post].astro", + want: `Record<"year" | "month" | "day" | "post", string | number>`, + }, + { + name: "/src/pages/post-[id]/[post].astro", + want: `Record<"id" | "post", string | number>`, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result := getParamsTypeFromFilename(tt.name) + // compare to expected string, show diff if mismatch + if diff := test_utils.ANSIDiff(strings.TrimSpace(tt.want), strings.TrimSpace(string(result))); diff != "" { + t.Errorf("mismatch (-want +got):\n%s", diff) + } + }) + } +}