Browse API 1 documentation
GroveAPI 1preview

grove.uploads.register()

Register an upload-provider implementation declared by the package.

Mango 3.1+View Markdown

Register an upload-provider implementation declared by the package.

Signature

ts
grove.uploads.register(providerID: string, handler: (
  file: GroveUploadFile, context: GroveUploadContext
) => string | { url: string } | Promise<string | { url: string }>): void
interface GroveUploadFile {
  readonly name: string; readonly type: string; readonly size: number
  read(offset: number, length: number): Promise<Uint8Array>
}
interface GroveUploadContext { progress(fraction: number): void }

Availability

Exclusive headless Root with uploads.provide and a matching contributions.uploadProviders entry. Application Roots are suitable for an app-wide service; server Roots can keep separate network accounts.

Parameters

Parameter Required Description
providerID Yes Exact provider id from the manifest, not its globally namespaced preference ID.
handler Yes Function invoked for a native user-selected file. May return a value or Promise.
file.name Host input Filename only, no local path. Treat as untrusted.
file.type Host input Native MIME-type guess; not verified content.
file.size Host input Nonnegative byte count. Manifest maxFileSize is enforced before the handler runs.
file.read Host input Bounded read of this selected file; see its dedicated page.
context.progress Host input Report a progress fraction; see its dedicated page.

Return value

Registration returns undefined. The handler must return a shareable HTTP/HTTPS URL string or { url: string }, optionally through a Promise. Return the recipient-facing URL, which may differ from an upload resource URL.

Behavior and errors

An empty provider id or non-function handler is a JavaScript no-op. Registering again replaces that handler. Native validation refuses undeclared IDs, non-headless surfaces, and missing grants. At most eight manifest providers are supported. File/context wrappers are frozen and valid only for the active upload.

Throw Error with a short user-safe explanation on failure. Mango bounds error text to 512 characters and presents the upload failure. Invalid returned URLs also fail the upload. Do not include credentials or private service responses in errors. The URL goes into the native draft for review; completing an upload does not send IRC traffic. Application Roots register in each mirrored runtime; do not assume one global singleton.

Example

js
grove.uploads.register('primary', async (file, context) => {
  // This illustrative endpoint accepts one small raw file and returns { url }.
  if (file.size === 0 || file.size > 1024 * 1024) {
    throw new Error('This example accepts files up to 1 MiB.')
  }
  const bytes = await file.read(0, file.size)
  const response = await fetch('https://uploads.example.com/files', {
    method: 'POST', body: bytes, credentials: 'omit', redirect: 'error'
  })
  if (!response.ok) throw new Error('The upload service rejected the file.')
  const result = await response.json()
  const url = new URL(result.url)
  if (url.protocol !== 'https:' || url.origin !== 'https://uploads.example.com') {
    throw new Error('The upload service returned an invalid share URL.')
  }
  context.progress(1)
  return { url: url.toString() }
})

See file.read(), context.progress(), and the complete Upload providers guide. Browser fetch in this example requires HTTPS host permission and service CORS; it is distinct from the native request bridge.