Skip to content

Commit 89df6b9

Browse files
fix(edge-functions): add warning for edge-functions configuration (#2984)
* feat(functions): auto add deno.jsonc and .npmrc to new functions * feat(deploy): add warning for functions imports structure * Update internal/functions/new/templates/.npmrc Co-authored-by: Han Qiao <[email protected]> * fix: function prototype --------- Co-authored-by: Han Qiao <[email protected]>
1 parent 1b58c87 commit 89df6b9

File tree

5 files changed

+62
-12
lines changed

5 files changed

+62
-12
lines changed

internal/functions/deploy/deploy.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,8 @@ func GetFunctionConfig(slugs []string, importMapPath string, noVerifyJWT *bool,
7171
// Although some functions do not require import map, it's more convenient to setup
7272
// vscode deno extension with a single import map for all functions.
7373
fallbackExists := true
74+
functionsUsingDeprecatedGlobalFallback := []string{}
75+
functionsUsingDeprecatedImportMap := []string{}
7476
if _, err := fsys.Stat(utils.FallbackImportMapPath); errors.Is(err, os.ErrNotExist) {
7577
fallbackExists = false
7678
} else if err != nil {
@@ -94,18 +96,30 @@ func GetFunctionConfig(slugs []string, importMapPath string, noVerifyJWT *bool,
9496
} else if len(function.ImportMap) == 0 {
9597
denoJsonPath := filepath.Join(functionDir, "deno.json")
9698
denoJsoncPath := filepath.Join(functionDir, "deno.jsonc")
99+
importMapPath := filepath.Join(functionDir, "import_map.json")
97100
if _, err := fsys.Stat(denoJsonPath); err == nil {
98101
function.ImportMap = denoJsonPath
99102
} else if _, err := fsys.Stat(denoJsoncPath); err == nil {
100103
function.ImportMap = denoJsoncPath
104+
} else if _, err := fsys.Stat(importMapPath); err == nil {
105+
function.ImportMap = importMapPath
106+
functionsUsingDeprecatedImportMap = append(functionsUsingDeprecatedImportMap, name)
101107
} else if fallbackExists {
102108
function.ImportMap = utils.FallbackImportMapPath
109+
functionsUsingDeprecatedGlobalFallback = append(functionsUsingDeprecatedGlobalFallback, name)
103110
}
104111
}
105112
if noVerifyJWT != nil {
106113
function.VerifyJWT = cast.Ptr(!*noVerifyJWT)
107114
}
108115
functionConfig[name] = function
109116
}
117+
if len(functionsUsingDeprecatedImportMap) > 0 {
118+
fmt.Fprintln(os.Stderr, utils.Yellow("WARNING:"), "Functions using deprecated import_map.json (please migrate to deno.jsonc):", utils.Aqua(strings.Join(functionsUsingDeprecatedImportMap, ", ")))
119+
}
120+
if len(functionsUsingDeprecatedGlobalFallback) > 0 {
121+
fmt.Fprintln(os.Stderr, utils.Yellow("WARNING:"), "Functions using fallback import map:", utils.Aqua(strings.Join(functionsUsingDeprecatedGlobalFallback, ", ")))
122+
fmt.Fprintln(os.Stderr, "Please use recommended per function dependency declaration ", utils.Aqua("https://supabase.com/docs/guides/functions/import-maps"))
123+
}
110124
return functionConfig, nil
111125
}

internal/functions/new/new.go

Lines changed: 29 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,13 @@ import (
1515

1616
var (
1717
//go:embed templates/index.ts
18-
indexEmbed string
19-
indexTemplate = template.Must(template.New("indexl").Parse(indexEmbed))
18+
indexEmbed string
19+
//go:embed templates/deno.jsonc
20+
denoEmbed string
21+
//go:embed templates/.npmrc
22+
npmrcEmbed string
23+
24+
indexTemplate = template.Must(template.New("index").Parse(indexEmbed))
2025
)
2126

2227
type indexConfig struct {
@@ -38,25 +43,37 @@ func Run(ctx context.Context, slug string, fsys afero.Fs) error {
3843
if err := utils.MkdirIfNotExistFS(fsys, funcDir); err != nil {
3944
return err
4045
}
41-
path := filepath.Join(funcDir, "index.ts")
42-
f, err := fsys.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_EXCL, 0644)
43-
if err != nil {
44-
return errors.Errorf("failed to create function entrypoint: %w", err)
45-
}
46-
defer f.Close()
47-
// Templatize index.ts by config.toml if available
46+
47+
// Load config if available
4848
if err := utils.LoadConfigFS(fsys); err != nil {
4949
utils.CmdSuggestion = ""
5050
}
51-
config := indexConfig{
51+
52+
if err := createTemplateFile(fsys, filepath.Join(funcDir, "index.ts"), indexTemplate, indexConfig{
5253
URL: utils.GetApiUrl("/functions/v1/" + slug),
5354
Token: utils.Config.Auth.AnonKey,
55+
}); err != nil {
56+
return errors.Errorf("failed to create function entrypoint: %w", err)
5457
}
55-
if err := indexTemplate.Option("missingkey=error").Execute(f, config); err != nil {
56-
return errors.Errorf("failed to initialise function entrypoint: %w", err)
58+
59+
if err := afero.WriteFile(fsys, filepath.Join(funcDir, "deno.jsonc"), []byte(denoEmbed), 0644); err != nil {
60+
return errors.Errorf("failed to create deno.jsonc config: %w", err)
61+
}
62+
63+
if err := afero.WriteFile(fsys, filepath.Join(funcDir, ".npmrc"), []byte(npmrcEmbed), 0644); err != nil {
64+
return errors.Errorf("failed to create .npmrc config: %w", err)
5765
}
5866
}
5967

6068
fmt.Println("Created new Function at " + utils.Bold(funcDir))
6169
return nil
6270
}
71+
72+
func createTemplateFile(fsys afero.Fs, path string, tmpl *template.Template, data interface{}) error {
73+
f, err := fsys.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_EXCL, 0644)
74+
if err != nil {
75+
return err
76+
}
77+
defer f.Close()
78+
return tmpl.Option("missingkey=error").Execute(f, data)
79+
}

internal/functions/new/new_test.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,16 @@ func TestNewCommand(t *testing.T) {
2424
assert.Contains(t, string(content),
2525
"curl -i --location --request POST 'http://127.0.0.1:54321/functions/v1/test-func'",
2626
)
27+
28+
// Verify deno.jsonc exists
29+
denoPath := filepath.Join(utils.FunctionsDir, "test-func", "deno.jsonc")
30+
_, err = afero.ReadFile(fsys, denoPath)
31+
assert.NoError(t, err, "deno.jsonc should be created")
32+
33+
// Verify .npmrc exists
34+
npmrcPath := filepath.Join(utils.FunctionsDir, "test-func", ".npmrc")
35+
_, err = afero.ReadFile(fsys, npmrcPath)
36+
assert.NoError(t, err, ".npmrc should be created")
2737
})
2838

2939
t.Run("throws error on malformed slug", func(t *testing.T) {
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Configuration for private npm package dependencies
2+
# For more information on using private registries with Edge Functions, see:
3+
# https://supabase.com/docs/guides/functions/import-maps#importing-from-private-registries
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"imports": {
3+
// Add your dependencies here
4+
// See: https://supabase.com/docs/guides/functions/import-maps#using-denojson-recommended
5+
}
6+
}

0 commit comments

Comments
 (0)