From d066b5f30547768a89093c4112e0838b1acb6124 Mon Sep 17 00:00:00 2001 From: kallebysantos Date: Sun, 13 Apr 2025 12:56:30 +0100 Subject: [PATCH 1/4] feat: load `import_map` from deno's `importMap` field - It allows to use the `importMap` field to pass the `import_map.json` path directly from `deno.json` --- pkg/config/config.go | 34 +++++++++++++++++++++++++++++----- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/pkg/config/config.go b/pkg/config/config.go index 5471ca4e49..16c71c68cb 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -257,6 +257,11 @@ type ( } ) +// Represents the `functions/[slug]/deno.json(c)` file +type DenoConfig struct { + ImportMap string `json:"importMap,omitempty"` +} + func (a *auth) Clone() auth { copy := *a if copy.Captcha != nil { @@ -672,15 +677,34 @@ func (c *baseConfig) resolve(builder pathBuilder, fsys fs.FS) error { // Append supabase/ because paths in configs are specified relative to config.toml function.Entrypoint = filepath.Join(builder.SupabaseDirPath, function.Entrypoint) } - if len(function.ImportMap) == 0 { + if len(function.ImportMap) == 0 || strings.Contains(function.ImportMap, "deno.json") { functionDir := filepath.Dir(function.Entrypoint) denoJsonPath := filepath.Join(functionDir, "deno.json") denoJsoncPath := filepath.Join(functionDir, "deno.jsonc") - if _, err := fs.Stat(fsys, denoJsonPath); err == nil { - function.ImportMap = denoJsonPath - } else if _, err := fs.Stat(fsys, denoJsoncPath); err == nil { - function.ImportMap = denoJsoncPath + + // We preference opt to load `importMap` field then fallback to `imports: {}` + loadDenoImportMap := func(denoConfigPath string) (string, error) { + in, err := fs.ReadFile(fsys, denoConfigPath) + if err != nil { + return "", err + } + + denoConfig := DenoConfig{} + json.Unmarshal(in, &denoConfig) + + if len(denoConfig.ImportMap) == 0 { + return denoConfigPath, nil + } + + return filepath.Join(functionDir, denoConfig.ImportMap), nil + } + + if denoJsonImportMap, err := loadDenoImportMap(denoJsonPath); err == nil { + function.ImportMap = denoJsonImportMap + } else if denoJsoncImportMap, err := loadDenoImportMap(denoJsoncPath); err == nil { + function.ImportMap = denoJsoncImportMap } + // Functions may not use import map so we don't set a default value } else if !filepath.IsAbs(function.ImportMap) { function.ImportMap = filepath.Join(builder.SupabaseDirPath, function.ImportMap) From 15d5c05000b2340a3df859a4baf963185f97d17b Mon Sep 17 00:00:00 2001 From: kallebysantos Date: Sun, 13 Apr 2025 13:06:41 +0100 Subject: [PATCH 2/4] chore: test for deno's `importMap` field --- pkg/config/config_test.go | 40 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/pkg/config/config_test.go b/pkg/config/config_test.go index 54278862ca..173f809ffc 100644 --- a/pkg/config/config_test.go +++ b/pkg/config/config_test.go @@ -428,6 +428,26 @@ func TestLoadFunctionImportMap(t *testing.T) { assert.Equal(t, "supabase/functions/hello/deno.json", config.Functions["hello"].ImportMap) }) + t.Run("uses deno.json+importMap field as import map when present", func(t *testing.T) { + config := NewConfig() + fsys := fs.MapFS{ + "supabase/config.toml": &fs.MapFile{Data: []byte(` + project_id = "bvikqvbczudanvggcord" + [functions.hello] + `)}, + "supabase/functions/hello/deno.json": &fs.MapFile{Data: []byte(` + { + "importMap": "../import_map.json" + }`)}, + "supabase/functions/import_map.json": &fs.MapFile{}, + "supabase/functions/hello/index.ts": &fs.MapFile{}, + } + // Run test + assert.NoError(t, config.Load("", fsys)) + // Check that deno.json was set as import map + assert.Equal(t, "supabase/functions/import_map.json", config.Functions["hello"].ImportMap) + }) + t.Run("uses deno.jsonc as import map when present", func(t *testing.T) { config := NewConfig() fsys := fs.MapFS{ @@ -444,6 +464,26 @@ func TestLoadFunctionImportMap(t *testing.T) { assert.Equal(t, "supabase/functions/hello/deno.jsonc", config.Functions["hello"].ImportMap) }) + t.Run("uses deno.jsonc+importMap field as import map when present", func(t *testing.T) { + config := NewConfig() + fsys := fs.MapFS{ + "supabase/config.toml": &fs.MapFile{Data: []byte(` + project_id = "bvikqvbczudanvggcord" + [functions.hello] + `)}, + "supabase/functions/hello/deno.jsonc": &fs.MapFile{Data: []byte(` + { + "importMap": "../import_map.json" + }`)}, + "supabase/functions/import_map.json": &fs.MapFile{}, + "supabase/functions/hello/index.ts": &fs.MapFile{}, + } + // Run test + assert.NoError(t, config.Load("", fsys)) + // Check that deno.json was set as import map + assert.Equal(t, "supabase/functions/import_map.json", config.Functions["hello"].ImportMap) + }) + t.Run("config.toml takes precedence over deno.json", func(t *testing.T) { config := NewConfig() fsys := fs.MapFS{ From a9489d941a0abf39d750fbed5b141f1b85dd96c1 Mon Sep 17 00:00:00 2001 From: kallebysantos Date: Sun, 13 Apr 2025 13:23:52 +0100 Subject: [PATCH 3/4] stamp: lint --- pkg/config/config.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/pkg/config/config.go b/pkg/config/config.go index 16c71c68cb..991d4acfb8 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -690,7 +690,10 @@ func (c *baseConfig) resolve(builder pathBuilder, fsys fs.FS) error { } denoConfig := DenoConfig{} - json.Unmarshal(in, &denoConfig) + err = json.Unmarshal(in, &denoConfig) + if err != nil { + return "", err + } if len(denoConfig.ImportMap) == 0 { return denoConfigPath, nil From b9b38a7bc9629e14723a61534e54f357db6e945f Mon Sep 17 00:00:00 2001 From: kallebysantos Date: Sun, 13 Apr 2025 13:29:47 +0100 Subject: [PATCH 4/4] fix: fallback to original file path --- pkg/config/config.go | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/pkg/config/config.go b/pkg/config/config.go index 991d4acfb8..f28a3bd1a6 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -691,11 +691,7 @@ func (c *baseConfig) resolve(builder pathBuilder, fsys fs.FS) error { denoConfig := DenoConfig{} err = json.Unmarshal(in, &denoConfig) - if err != nil { - return "", err - } - - if len(denoConfig.ImportMap) == 0 { + if err != nil || len(denoConfig.ImportMap) == 0 { return denoConfigPath, nil }