diff --git a/pkg/config/config.go b/pkg/config/config.go index 5471ca4e49..f28a3bd1a6 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,33 @@ 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{} + err = json.Unmarshal(in, &denoConfig) + if err != nil || 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) 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{