deployFunction method
Deploys (creates or updates) an Edge Function.
Maps to POST /v1/projects/{ref}/functions/deploy?slug=<slug>. The
body is a multipart/form-data request containing:
- a
metadatatext part withentrypoint_path+name(+ optionalverify_jwt, defaulting tofalse— the relay's HS256-only check is replaced by in-function JWKS verification via_shared/jwt.ts) - one
filepart per source file, using the relative path as the filename so the Supabase runtime preserves the directory layout
files maps relative path → file contents. entrypoint must be one
of the keys in files (e.g. index.ts). The function endpoint is
idempotent: if a function with the same slug exists it is updated,
otherwise a new one is created.
Implementation
Future<void> deployFunction({
required String projectRef,
required String accessToken,
required String slug,
required String entrypoint,
required Map<String, String> files,
bool verifyJwt = false,
}) async {
if (!files.containsKey(entrypoint)) {
throw ProvisioningException(
'Function $slug is missing its entrypoint $entrypoint in the '
'bundled source.',
);
}
final url = '$_baseUrl/v1/projects/$projectRef/functions/deploy?slug=$slug';
final metadata = {
'entrypoint_path': entrypoint,
'name': slug,
'verify_jwt': verifyJwt,
};
final formData = FormData();
formData.fields.add(MapEntry('metadata', jsonEncode(metadata)));
for (final entry in files.entries) {
formData.files.add(
MapEntry(
'file',
MultipartFile.fromString(entry.value, filename: entry.key),
),
);
}
final Response<dynamic> response;
try {
response = await _dio.post<dynamic>(
url,
data: formData,
options: Options(
headers: _authHeaders(accessToken),
sendTimeout: _timeout,
receiveTimeout: _timeout,
validateStatus: (_) => true,
),
);
} on DioException catch (e) {
throw ProvisioningException(
_dioMessage(e, 'deploying Edge Function "$slug"'),
);
}
final status = response.statusCode ?? 0;
if (status >= 200 && status < 300) {
dev.log(
'Deployed function $slug to project $projectRef (HTTP $status).',
name: 'SupabaseProvisioner',
);
return;
}
throw ProvisioningException(_mapStatus(status, projectRef, response.data));
}