Files
supabase__supabase/apps/studio/components/interfaces/EdgeFunctions/EdgeFunctions.utils.test.ts
Joshen Lim 957f84b17c Joshenlim/fe 4348 find an alternative to the jsr stdpath dependency (#50111)
## Context

Drops the `@std/path` dependency which is used in `EdgeFunctions.utils`
as `npm.jsr.io` was putting up a Cloudflare bot challenge on some
connections which blocks `pnpm install`. Instead, opting to directly
port the exact required methods as self-contained functions. Also added
some unit tests to check that UI behaviour remains status quo.

## To test: 
Important to test that everything in the edge functions UI remains
status quo
- [ ] Open an existing edge function with a single root-level file -
should load as expected
<img width="310" height="176" alt="image"
src="https://github.com/user-attachments/assets/4d724ab0-33bb-4093-a574-52984b2743fd"
/>
- [ ] Open (or create) an edge function with nested folders - confirm
file paths in the editor are shown correctly
  - Can create nested folders by using `../` as such
<img width="319" height="228" alt="image"
src="https://github.com/user-attachments/assets/dd345b1f-7c45-47e9-975c-f2f2e53a0106"
/>
- [ ] Similarly, download the edge function as ZIP to verify that the
nested folders are all correctly located
- [ ] Open a function with `import_map.json` - confirm still detected as
import map through the network tab GET request for the edge function
code (Examples here with and without import map)
<img width="333" height="245" alt="image"
src="https://github.com/user-attachments/assets/90fc90e3-4a62-493b-9246-ed7e3b662e96"
/>
<img width="290" height="237" alt="image"
src="https://github.com/user-attachments/assets/2f692362-c9d4-4394-bc5a-4f84ab5fb6f1"
/>
- [ ] Deploy a new function via the editor
- [ ] Update an existing function via the editor (Test adding new files
etc)


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **Bug Fixes**
- Improved Edge Functions file path handling across supported
application environments.
- Nested entrypoints, URL-based entrypoints, root-level files, and
unmatched paths are now handled consistently.
- Generated files retain their content and receive sequential
identifiers reliably.
- Improved compatibility when processing and displaying files in
different application environments.

- **Tests**
- Added coverage for entrypoint path formatting, relative paths,
fallback behavior, unchanged paths, and identifier assignment.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-09-09 14:37:32 +08:00

73 lines
2.8 KiB
TypeScript

import { describe, expect, it } from 'vitest'
import { formatFunctionBodyToFiles } from './EdgeFunctions.utils'
describe('formatFunctionBodyToFiles', () => {
it('returns no files when there is no entrypoint path', () => {
const files = [{ name: 'index.ts', content: 'a' }]
const result = formatFunctionBodyToFiles({ functionBody: { files, metadata: {} } })
expect(result).toEqual([])
})
it('rewrites nested file paths relative to a nested entrypoint', () => {
const files = [
{ name: 'functions/hello/index.ts', content: 'a' },
{ name: 'functions/hello/utils/helper.ts', content: 'b' },
]
const result = formatFunctionBodyToFiles({
functionBody: { files, metadata: { deno2_entrypoint_path: 'functions/hello/index.ts' } },
})
expect(result.map((f) => f.name)).toEqual(['index.ts', 'utils/helper.ts'])
})
it('leaves file paths unmodified when the entrypoint is a bare filename at the root', () => {
const files = [{ name: 'index.ts', content: 'a' }]
const result = formatFunctionBodyToFiles({
functionBody: { files, metadata: { deno2_entrypoint_path: 'index.ts' } },
})
expect(result.map((f) => f.name)).toEqual(['index.ts'])
})
it('falls back to parsing a URL entrypoint when no file name matches', () => {
const files = [
{ name: 'functions/hello/index.ts', content: 'a' },
{ name: 'functions/hello/utils/helper.ts', content: 'b' },
]
const result = formatFunctionBodyToFiles({
functionBody: { files, metadata: {} },
entrypointPath: 'https://edge.supabase.com/deploy/abc123/main.ts',
})
// the URL's parsed base path ('/deploy/abc123') shares no common prefix with
// the relative file names, so they're left unmodified (per commonPath)
expect(result.map((f) => f.name)).toEqual([
'functions/hello/index.ts',
'functions/hello/utils/helper.ts',
])
})
it('leaves a file unmodified when it shares no common path with the base path', () => {
const files = [
{ name: 'functions/hello/index.ts', content: 'a' },
{ name: 'unrelated/other.ts', content: 'b' },
]
const result = formatFunctionBodyToFiles({
functionBody: { files, metadata: { deno2_entrypoint_path: 'functions/hello/index.ts' } },
})
expect(result.map((f) => f.name)).toEqual(['index.ts', 'unrelated/other.ts'])
})
it('assigns sequential ids and preserves content', () => {
const files = [
{ name: 'a.ts', content: 'foo' },
{ name: 'b.ts', content: 'bar' },
]
const result = formatFunctionBodyToFiles({
functionBody: { files, metadata: { deno2_entrypoint_path: 'a.ts' } },
})
expect(result).toEqual([
{ id: 1, name: 'a.ts', content: 'foo', state: 'unchanged' },
{ id: 2, name: 'b.ts', content: 'bar', state: 'unchanged' },
])
})
})