@vertracloud/api-types 0.3.6 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["api-key.ts"],"sourcesContent":["import type { ISODateString } from \"../../common/v1\";\n\n/**\n * API key scope, in the form `<resource>:<action>`. Presets: `read` = every `*:read`;\n * `write` = `read` + every `*:write`; `full` = all of them, including the ones without a\n * `read`/`write` suffix (delete, envs, files, credentials).\n * @see https://docs.vertracloud.app/api-reference/introduction#scopes\n */\nexport type APIApiKeyScope =\n\t| \"apps:read\"\n\t| \"apps:write\"\n\t| \"apps:delete\"\n\t| \"apps:envs\"\n\t| \"apps:files\"\n\t| \"databases:read\"\n\t| \"databases:write\"\n\t| \"databases:delete\"\n\t| \"databases:credentials\"\n\t| \"snapshots:read\"\n\t| \"snapshots:write\"\n\t| \"account:read\"\n\t| \"account:write\"\n\t| \"workspaces:read\"\n\t| \"workspaces:write\"\n\t| \"workspaces:delete\"\n\t| \"workspaces:invites\"\n\t| \"billing:read\"\n\t| \"billing:write\"\n\t| \"redeem:write\";\n\nexport const APIApiKeyScope = {\n\tAPPS_READ: \"apps:read\",\n\tAPPS_WRITE: \"apps:write\",\n\tAPPS_DELETE: \"apps:delete\",\n\tAPPS_ENVS: \"apps:envs\",\n\tAPPS_FILES: \"apps:files\",\n\tDATABASES_READ: \"databases:read\",\n\tDATABASES_WRITE: \"databases:write\",\n\tDATABASES_DELETE: \"databases:delete\",\n\tDATABASES_CREDENTIALS: \"databases:credentials\",\n\tSNAPSHOTS_READ: \"snapshots:read\",\n\tSNAPSHOTS_WRITE: \"snapshots:write\",\n\tACCOUNT_READ: \"account:read\",\n\tACCOUNT_WRITE: \"account:write\",\n\tWORKSPACES_READ: \"workspaces:read\",\n\tWORKSPACES_WRITE: \"workspaces:write\",\n\tWORKSPACES_DELETE: \"workspaces:delete\",\n\tWORKSPACES_INVITES: \"workspaces:invites\",\n\tBILLING_READ: \"billing:read\",\n\tBILLING_WRITE: \"billing:write\",\n\tREDEEM_WRITE: \"redeem:write\",\n} as const satisfies Record<string, APIApiKeyScope>;\n\nexport type APIApiKeyPreset = \"read\" | \"write\" | \"full\";\nexport const APIApiKeyPreset = { Read: \"read\", Write: \"write\", Full: \"full\" } as const;\n\nexport type APIApiKeyRouteMethod = \"GET\" | \"POST\" | \"PUT\" | \"PATCH\" | \"DELETE\";\n\nexport interface APIApiKeyRoute {\n\tmethod: APIApiKeyRouteMethod;\n\t/** Full route pattern with `:param` placeholders (`/v1/apps/:id/files`). Matched exactly, no regex. */\n\tpath: string;\n}\n\nexport interface APIApiKeyScopeEntry {\n\t/** Display group the scope belongs to. */\n\tgroup: \"apps\" | \"databases\" | \"snapshots\" | \"account\" | \"workspaces\" | \"billing\";\n\troutes: APIApiKeyRoute[];\n}\n\n/**\n * Closed catalog of the routes an API key can reach, per scope. A key without the route's scope\n * gets 403 `API_KEY_SCOPE_DENIED`; a route that is not listed here always returns 403 to an API key.\n *\n * Intentionally left out (dashboard session only): key management, creating workspace invites\n * (an invite would outlive the key's revocation), revoking sessions, plan downgrade, and the\n * database **Data** tab (`/v1/databases/:id/data/*`).\n *\n * The rollback `POST` with `restore_environment: true` also requires `apps:envs` for an API key;\n * without it the request returns 403 `API_KEY_SCOPE_DENIED`.\n */\nexport const API_KEY_SCOPES: Record<APIApiKeyScope, APIApiKeyScopeEntry> = {\n\t\"apps:read\": {\n\t\tgroup: \"apps\",\n\t\troutes: [\n\t\t\t{ method: \"GET\", path: \"/v1/apps/runtimes\" },\n\t\t\t{ method: \"GET\", path: \"/v1/apps/status\" },\n\t\t\t{ method: \"GET\", path: \"/v1/apps/:id\" },\n\t\t\t{ method: \"GET\", path: \"/v1/apps/:id/status\" },\n\t\t\t{ method: \"GET\", path: \"/v1/apps/:id/realtime\" },\n\t\t\t{ method: \"GET\", path: \"/v1/apps/:id/metrics\" },\n\t\t\t{ method: \"GET\", path: \"/v1/apps/:id/logs\" },\n\t\t\t{ method: \"GET\", path: \"/v1/apps/:id/download\" },\n\t\t\t{ method: \"GET\", path: \"/v1/apps/:id/deploys\" },\n\t\t\t{ method: \"GET\", path: \"/v1/apps/:id/deploys/webhook\" },\n\t\t\t{ method: \"GET\", path: \"/v1/apps/:id/releases\" },\n\t\t\t{ method: \"GET\", path: \"/v1/apps/:id/releases/:release_id/log\" },\n\t\t\t{ method: \"GET\", path: \"/v1/apps/:id/network/custom\" },\n\t\t\t{ method: \"GET\", path: \"/v1/apps/:id/network/dns\" },\n\t\t],\n\t},\n\t\"apps:write\": {\n\t\tgroup: \"apps\",\n\t\troutes: [\n\t\t\t{ method: \"POST\", path: \"/v1/apps\" },\n\t\t\t{ method: \"POST\", path: \"/v1/apps/:id/start\" },\n\t\t\t{ method: \"POST\", path: \"/v1/apps/:id/stop\" },\n\t\t\t{ method: \"POST\", path: \"/v1/apps/:id/restart\" },\n\t\t\t{ method: \"PATCH\", path: \"/v1/apps/:id/config\" },\n\t\t\t{ method: \"POST\", path: \"/v1/apps/:id/deploys/webhook\" },\n\t\t\t{ method: \"DELETE\", path: \"/v1/apps/:id/deploys/webhook\" },\n\t\t\t{ method: \"POST\", path: \"/v1/apps/:id/network/custom\" },\n\t\t\t{ method: \"DELETE\", path: \"/v1/apps/:id/network/custom\" },\n\t\t\t{ method: \"POST\", path: \"/v1/apps/:id/network/purge-cache\" },\n\t\t\t{ method: \"PATCH\", path: \"/v1/apps/:id/network/subdomain\" },\n\t\t\t{ method: \"POST\", path: \"/v1/apps/:id/network/publish\" },\n\t\t\t{ method: \"DELETE\", path: \"/v1/apps/:id/network/publish\" },\n\t\t\t{ method: \"POST\", path: \"/v1/apps/:id/releases/:release_id/rollback\" },\n\t\t],\n\t},\n\t\"apps:delete\": { group: \"apps\", routes: [{ method: \"DELETE\", path: \"/v1/apps/:id\" }] },\n\t\"apps:envs\": {\n\t\tgroup: \"apps\",\n\t\troutes: [\n\t\t\t{ method: \"GET\", path: \"/v1/apps/:id/envs\" },\n\t\t\t{ method: \"POST\", path: \"/v1/apps/:id/envs\" },\n\t\t\t{ method: \"DELETE\", path: \"/v1/apps/:id/envs/:envId\" },\n\t\t\t{ method: \"GET\", path: \"/v1/apps/:id/releases/:release_id/rollback\" },\n\t\t],\n\t},\n\t\"apps:files\": {\n\t\tgroup: \"apps\",\n\t\troutes: [\n\t\t\t{ method: \"GET\", path: \"/v1/apps/:id/files\" },\n\t\t\t{ method: \"GET\", path: \"/v1/apps/:id/files/tree\" },\n\t\t\t{ method: \"GET\", path: \"/v1/apps/:id/files/content\" },\n\t\t\t{ method: \"PUT\", path: \"/v1/apps/:id/files\" },\n\t\t\t{ method: \"PATCH\", path: \"/v1/apps/:id/files\" },\n\t\t\t{ method: \"DELETE\", path: \"/v1/apps/:id/files\" },\n\t\t\t{ method: \"POST\", path: \"/v1/apps/:id/files/upload\" },\n\t\t],\n\t},\n\t\"databases:read\": {\n\t\tgroup: \"databases\",\n\t\troutes: [\n\t\t\t{ method: \"GET\", path: \"/v1/databases/status\" },\n\t\t\t{ method: \"GET\", path: \"/v1/databases/:id\" },\n\t\t\t{ method: \"GET\", path: \"/v1/databases/:id/status\" },\n\t\t\t{ method: \"GET\", path: \"/v1/databases/:id/metrics\" },\n\t\t],\n\t},\n\t\"databases:write\": {\n\t\tgroup: \"databases\",\n\t\troutes: [\n\t\t\t{ method: \"POST\", path: \"/v1/databases\" },\n\t\t\t{ method: \"PUT\", path: \"/v1/databases/:id\" },\n\t\t\t{ method: \"POST\", path: \"/v1/databases/:id/start\" },\n\t\t\t{ method: \"POST\", path: \"/v1/databases/:id/stop\" },\n\t\t\t{ method: \"POST\", path: \"/v1/databases/:id/reset\" },\n\t\t],\n\t},\n\t\"databases:delete\": { group: \"databases\", routes: [{ method: \"DELETE\", path: \"/v1/databases/:id\" }] },\n\t\"databases:credentials\": {\n\t\tgroup: \"databases\",\n\t\troutes: [\n\t\t\t{ method: \"GET\", path: \"/v1/databases/:id/credentials/certificate\" },\n\t\t\t{ method: \"POST\", path: \"/v1/databases/:id/credentials/certificate/reset\" },\n\t\t\t{ method: \"POST\", path: \"/v1/databases/:id/credentials/reset\" },\n\t\t],\n\t},\n\t\"snapshots:read\": {\n\t\tgroup: \"snapshots\",\n\t\troutes: [\n\t\t\t{ method: \"GET\", path: \"/v1/users/snapshots\" },\n\t\t\t{ method: \"GET\", path: \"/v1/users/:id/snapshots\" },\n\t\t\t{ method: \"GET\", path: \"/v1/users/:id/snapshots/:snapshot_id/download\" },\n\t\t],\n\t},\n\t\"snapshots:write\": {\n\t\tgroup: \"snapshots\",\n\t\troutes: [\n\t\t\t{ method: \"POST\", path: \"/v1/users/:id/snapshots\" },\n\t\t\t{ method: \"POST\", path: \"/v1/users/:id/snapshots/:snapshot_id/restore\" },\n\t\t],\n\t},\n\t\"account:read\": {\n\t\tgroup: \"account\",\n\t\troutes: [\n\t\t\t{ method: \"GET\", path: \"/v1/users/me\" },\n\t\t\t{ method: \"GET\", path: \"/v1/users/me/sessions\" },\n\t\t],\n\t},\n\t\"account:write\": {\n\t\tgroup: \"account\",\n\t\troutes: [\n\t\t\t{ method: \"PATCH\", path: \"/v1/users/me\" },\n\t\t\t{ method: \"POST\", path: \"/v1/users/me/folders\" },\n\t\t\t{ method: \"PATCH\", path: \"/v1/users/me/folders/:folder_id\" },\n\t\t\t{ method: \"DELETE\", path: \"/v1/users/me/folders/:folder_id\" },\n\t\t\t{ method: \"PUT\", path: \"/v1/users/me/folders/:folder_id/resources/:resource_type/:resource_id\" },\n\t\t\t{ method: \"DELETE\", path: \"/v1/users/me/folders/:folder_id/resources/:resource_type/:resource_id\" },\n\t\t\t{ method: \"PUT\", path: \"/v1/users/me/favorites/:resource_type/:resource_id\" },\n\t\t\t{ method: \"DELETE\", path: \"/v1/users/me/favorites/:resource_type/:resource_id\" },\n\t\t],\n\t},\n\t\"workspaces:read\": {\n\t\tgroup: \"workspaces\",\n\t\troutes: [\n\t\t\t{ method: \"GET\", path: \"/v1/workspaces\" },\n\t\t\t{ method: \"GET\", path: \"/v1/workspaces/:id\" },\n\t\t\t{ method: \"GET\", path: \"/v1/workspaces/:id/members\" },\n\t\t\t{ method: \"GET\", path: \"/v1/workspaces/:id/roles\" },\n\t\t\t{ method: \"GET\", path: \"/v1/workspaces/:id/action-requests\" },\n\t\t],\n\t},\n\t\"workspaces:write\": {\n\t\tgroup: \"workspaces\",\n\t\troutes: [\n\t\t\t{ method: \"POST\", path: \"/v1/workspaces\" },\n\t\t\t{ method: \"PUT\", path: \"/v1/workspaces/:id\" },\n\t\t\t{ method: \"PUT\", path: \"/v1/workspaces/:id/members/:user_id\" },\n\t\t\t{ method: \"DELETE\", path: \"/v1/workspaces/:id/members/:user_id\" },\n\t\t\t{ method: \"POST\", path: \"/v1/workspaces/:id/roles\" },\n\t\t\t{ method: \"PUT\", path: \"/v1/workspaces/:id/roles/:role_id\" },\n\t\t\t{ method: \"DELETE\", path: \"/v1/workspaces/:id/roles/:role_id\" },\n\t\t\t{ method: \"POST\", path: \"/v1/workspaces/:id/apps/:app_id\" },\n\t\t\t{ method: \"DELETE\", path: \"/v1/workspaces/:id/apps/:app_id\" },\n\t\t\t{ method: \"POST\", path: \"/v1/workspaces/:id/databases/:db_id\" },\n\t\t\t{ method: \"DELETE\", path: \"/v1/workspaces/:id/databases/:db_id\" },\n\t\t\t{ method: \"POST\", path: \"/v1/workspaces/:id/folders\" },\n\t\t\t{ method: \"PATCH\", path: \"/v1/workspaces/:id/folders/:folder_id\" },\n\t\t\t{ method: \"DELETE\", path: \"/v1/workspaces/:id/folders/:folder_id\" },\n\t\t\t{ method: \"PUT\", path: \"/v1/workspaces/:id/folders/:folder_id/resources/:resource_type/:resource_id\" },\n\t\t\t{ method: \"DELETE\", path: \"/v1/workspaces/:id/folders/:folder_id/resources/:resource_type/:resource_id\" },\n\t\t\t{ method: \"PUT\", path: \"/v1/workspaces/:id/favorites/:resource_type/:resource_id\" },\n\t\t\t{ method: \"DELETE\", path: \"/v1/workspaces/:id/favorites/:resource_type/:resource_id\" },\n\t\t\t{ method: \"POST\", path: \"/v1/workspaces/:id/action-requests\" },\n\t\t],\n\t},\n\t/**\n\t * Intentionally left out (dashboard session only): creating invites (a leaked key could grant\n\t * access that outlives its revocation), transferring ownership, approving/rejecting action\n\t * requests (approval is a human decision) and exporting activities.\n\t */\n\t/** Delete a workspace (soft delete). Only in the `full` preset, like `apps:delete`. */\n\t\"workspaces:delete\": {\n\t\tgroup: \"workspaces\",\n\t\troutes: [{ method: \"DELETE\", path: \"/v1/workspaces/:id\" }],\n\t},\n\t/** List and revoke workspace invites; view, accept and decline your own invite by token. Only in the `full` preset. */\n\t\"workspaces:invites\": {\n\t\tgroup: \"workspaces\",\n\t\troutes: [\n\t\t\t{ method: \"GET\", path: \"/v1/workspaces/:id/invites\" },\n\t\t\t{ method: \"DELETE\", path: \"/v1/workspaces/:id/invites/:invite_id\" },\n\t\t\t{ method: \"GET\", path: \"/v1/workspaces/invites/:token\" },\n\t\t\t{ method: \"POST\", path: \"/v1/workspaces/invites/:token/accept\" },\n\t\t\t{ method: \"POST\", path: \"/v1/workspaces/invites/:token/decline\" },\n\t\t],\n\t},\n\t\"billing:read\": {\n\t\tgroup: \"billing\",\n\t\troutes: [\n\t\t\t{ method: \"GET\", path: \"/v1/orders\" },\n\t\t\t{ method: \"GET\", path: \"/v1/orders/:orderId/status\" },\n\t\t\t{ method: \"GET\", path: \"/v1/users/me/billing\" },\n\t\t],\n\t},\n\t/**\n\t * Creates a plan order and generates the PIX charge; the payment itself is made by a person in their banking app.\n\t * Also saves the billing details (name, address, CPF/CNPJ) an order needs.\n\t */\n\t\"billing:write\": {\n\t\tgroup: \"billing\",\n\t\troutes: [\n\t\t\t{ method: \"POST\", path: \"/v1/orders\" },\n\t\t\t{ method: \"POST\", path: \"/v1/orders/:orderId/initiate/pix\" },\n\t\t\t{ method: \"PUT\", path: \"/v1/users/me/billing\" },\n\t\t],\n\t},\n\t\"redeem:write\": { group: \"billing\", routes: [{ method: \"POST\", path: \"/v1/redeem/:code\" }] },\n};\n\nexport const API_KEY_SCOPE_LIST = Object.keys(API_KEY_SCOPES) as APIApiKeyScope[];\n\n/** Scopes selected by a preset. `full` is the whole catalog. */\nexport function apiKeyPresetScopes(preset: APIApiKeyPreset): APIApiKeyScope[] {\n\tif (preset === \"full\") return API_KEY_SCOPE_LIST;\n\treturn API_KEY_SCOPE_LIST.filter((s) => s.endsWith(\":read\") || (preset === \"write\" && s.endsWith(\":write\")));\n}\n\n/** Maximum keys per account, entries in `allowed_ips`, and key name length. */\nexport const API_KEY_MAX_PER_USER = 10;\nexport const API_KEY_MAX_ALLOWED_IPS = 20;\nexport const API_KEY_NAME_MAX_LENGTH = 40;\n\n/**\n * An API key as listed. The secret is returned only ONCE, in `APIApiKeyCreated`.\n * @see https://docs.vertracloud.app/api-reference/endpoint/users/api-keys/list\n */\nexport interface APIApiKey {\n\tid: string;\n\tname: string;\n\t/** Public start of the key (`vc_live_a1b2c3d4`; older keys: 8 hex characters). */\n\tprefix: string;\n\t/** Last 4 characters; `null` for keys generated before the `vc_live_` format. */\n\tlast4: string | null;\n\tscopes: APIApiKeyScope[];\n\t/** Allowed IPs/CIDRs. Empty list = any IP. */\n\tallowed_ips: string[];\n\tcreated_at: ISODateString;\n\tlast_used_at: ISODateString | null;\n}\n\nexport interface APIApiKeyCreated extends APIApiKey {\n\t/** The full secret. Shown once; it cannot be recovered. */\n\tapi_key: string;\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["api-key.ts"],"sourcesContent":["import type { ISODateString } from \"../../common/v1\";\n\n/**\n * API key scope, in the form `<resource>:<action>`. Presets: `read` = every `*:read`;\n * `write` = `read` + every `*:write`; `full` = all of them, including the ones without a\n * `read`/`write` suffix (delete, envs, files, credentials).\n * @see https://docs.vertracloud.app/api-reference/introduction#scopes\n */\nexport type APIApiKeyScope =\n\t| \"apps:read\"\n\t| \"apps:write\"\n\t| \"apps:delete\"\n\t| \"apps:envs\"\n\t| \"apps:files\"\n\t| \"databases:read\"\n\t| \"databases:write\"\n\t| \"databases:delete\"\n\t| \"databases:credentials\"\n\t| \"snapshots:read\"\n\t| \"snapshots:write\"\n\t| \"account:read\"\n\t| \"account:write\"\n\t| \"workspaces:read\"\n\t| \"workspaces:write\"\n\t| \"workspaces:delete\"\n\t| \"workspaces:invites\"\n\t| \"blob:read\"\n\t| \"blob:write\"\n\t| \"billing:read\"\n\t| \"billing:write\"\n\t| \"redeem:write\";\n\nexport const APIApiKeyScope = {\n\tAPPS_READ: \"apps:read\",\n\tAPPS_WRITE: \"apps:write\",\n\tAPPS_DELETE: \"apps:delete\",\n\tAPPS_ENVS: \"apps:envs\",\n\tAPPS_FILES: \"apps:files\",\n\tDATABASES_READ: \"databases:read\",\n\tDATABASES_WRITE: \"databases:write\",\n\tDATABASES_DELETE: \"databases:delete\",\n\tDATABASES_CREDENTIALS: \"databases:credentials\",\n\tSNAPSHOTS_READ: \"snapshots:read\",\n\tSNAPSHOTS_WRITE: \"snapshots:write\",\n\tACCOUNT_READ: \"account:read\",\n\tACCOUNT_WRITE: \"account:write\",\n\tWORKSPACES_READ: \"workspaces:read\",\n\tWORKSPACES_WRITE: \"workspaces:write\",\n\tWORKSPACES_DELETE: \"workspaces:delete\",\n\tWORKSPACES_INVITES: \"workspaces:invites\",\n\tBLOB_READ: \"blob:read\",\n\tBLOB_WRITE: \"blob:write\",\n\tBILLING_READ: \"billing:read\",\n\tBILLING_WRITE: \"billing:write\",\n\tREDEEM_WRITE: \"redeem:write\",\n} as const satisfies Record<string, APIApiKeyScope>;\n\nexport type APIApiKeyPreset = \"read\" | \"write\" | \"full\";\nexport const APIApiKeyPreset = { Read: \"read\", Write: \"write\", Full: \"full\" } as const;\n\nexport type APIApiKeyRouteMethod = \"GET\" | \"POST\" | \"PUT\" | \"PATCH\" | \"DELETE\";\n\nexport interface APIApiKeyRoute {\n\tmethod: APIApiKeyRouteMethod;\n\t/** Full route pattern with `:param` placeholders (`/v1/apps/:id/files`). Matched exactly, no regex. */\n\tpath: string;\n}\n\nexport interface APIApiKeyScopeEntry {\n\t/** Display group the scope belongs to. */\n\tgroup: \"apps\" | \"databases\" | \"snapshots\" | \"account\" | \"workspaces\" | \"billing\" | \"blob\";\n\troutes: APIApiKeyRoute[];\n}\n\n/**\n * Closed catalog of the routes an API key can reach, per scope. A key without the route's scope\n * gets 403 `API_KEY_SCOPE_DENIED`; a route that is not listed here always returns 403 to an API key.\n *\n * Intentionally left out (dashboard session only): key management, creating workspace invites\n * (an invite would outlive the key's revocation), revoking sessions, plan downgrade, and the\n * database **Data** tab (`/v1/databases/:id/data/*`).\n *\n * The rollback `POST` with `restore_environment: true` also requires `apps:envs` for an API key;\n * without it the request returns 403 `API_KEY_SCOPE_DENIED`.\n */\nexport const API_KEY_SCOPES: Record<APIApiKeyScope, APIApiKeyScopeEntry> = {\n\t\"apps:read\": {\n\t\tgroup: \"apps\",\n\t\troutes: [\n\t\t\t{ method: \"GET\", path: \"/v1/apps/runtimes\" },\n\t\t\t{ method: \"GET\", path: \"/v1/apps/status\" },\n\t\t\t{ method: \"GET\", path: \"/v1/apps/:id\" },\n\t\t\t{ method: \"GET\", path: \"/v1/apps/:id/status\" },\n\t\t\t{ method: \"GET\", path: \"/v1/apps/:id/realtime\" },\n\t\t\t{ method: \"GET\", path: \"/v1/apps/:id/metrics\" },\n\t\t\t{ method: \"GET\", path: \"/v1/apps/:id/logs\" },\n\t\t\t{ method: \"GET\", path: \"/v1/apps/:id/download\" },\n\t\t\t{ method: \"GET\", path: \"/v1/apps/:id/deploys\" },\n\t\t\t{ method: \"GET\", path: \"/v1/apps/:id/deploys/webhook\" },\n\t\t\t{ method: \"GET\", path: \"/v1/apps/:id/releases\" },\n\t\t\t{ method: \"GET\", path: \"/v1/apps/:id/releases/:release_id/log\" },\n\t\t\t{ method: \"GET\", path: \"/v1/apps/:id/network/custom\" },\n\t\t\t{ method: \"GET\", path: \"/v1/apps/:id/network/dns\" },\n\t\t],\n\t},\n\t\"apps:write\": {\n\t\tgroup: \"apps\",\n\t\troutes: [\n\t\t\t{ method: \"POST\", path: \"/v1/apps\" },\n\t\t\t{ method: \"POST\", path: \"/v1/apps/:id/start\" },\n\t\t\t{ method: \"POST\", path: \"/v1/apps/:id/stop\" },\n\t\t\t{ method: \"POST\", path: \"/v1/apps/:id/restart\" },\n\t\t\t{ method: \"PATCH\", path: \"/v1/apps/:id/config\" },\n\t\t\t{ method: \"POST\", path: \"/v1/apps/:id/deploys/webhook\" },\n\t\t\t{ method: \"DELETE\", path: \"/v1/apps/:id/deploys/webhook\" },\n\t\t\t{ method: \"POST\", path: \"/v1/apps/:id/network/custom\" },\n\t\t\t{ method: \"DELETE\", path: \"/v1/apps/:id/network/custom\" },\n\t\t\t{ method: \"POST\", path: \"/v1/apps/:id/network/purge-cache\" },\n\t\t\t{ method: \"PATCH\", path: \"/v1/apps/:id/network/subdomain\" },\n\t\t\t{ method: \"POST\", path: \"/v1/apps/:id/network/publish\" },\n\t\t\t{ method: \"DELETE\", path: \"/v1/apps/:id/network/publish\" },\n\t\t\t{ method: \"POST\", path: \"/v1/apps/:id/releases/:release_id/rollback\" },\n\t\t],\n\t},\n\t\"apps:delete\": { group: \"apps\", routes: [{ method: \"DELETE\", path: \"/v1/apps/:id\" }] },\n\t\"apps:envs\": {\n\t\tgroup: \"apps\",\n\t\troutes: [\n\t\t\t{ method: \"GET\", path: \"/v1/apps/:id/envs\" },\n\t\t\t{ method: \"POST\", path: \"/v1/apps/:id/envs\" },\n\t\t\t{ method: \"DELETE\", path: \"/v1/apps/:id/envs/:envId\" },\n\t\t\t{ method: \"GET\", path: \"/v1/apps/:id/releases/:release_id/rollback\" },\n\t\t],\n\t},\n\t\"apps:files\": {\n\t\tgroup: \"apps\",\n\t\troutes: [\n\t\t\t{ method: \"GET\", path: \"/v1/apps/:id/files\" },\n\t\t\t{ method: \"GET\", path: \"/v1/apps/:id/files/tree\" },\n\t\t\t{ method: \"GET\", path: \"/v1/apps/:id/files/content\" },\n\t\t\t{ method: \"PUT\", path: \"/v1/apps/:id/files\" },\n\t\t\t{ method: \"PATCH\", path: \"/v1/apps/:id/files\" },\n\t\t\t{ method: \"DELETE\", path: \"/v1/apps/:id/files\" },\n\t\t\t{ method: \"POST\", path: \"/v1/apps/:id/files/upload\" },\n\t\t],\n\t},\n\t\"databases:read\": {\n\t\tgroup: \"databases\",\n\t\troutes: [\n\t\t\t{ method: \"GET\", path: \"/v1/databases/status\" },\n\t\t\t{ method: \"GET\", path: \"/v1/databases/:id\" },\n\t\t\t{ method: \"GET\", path: \"/v1/databases/:id/status\" },\n\t\t\t{ method: \"GET\", path: \"/v1/databases/:id/metrics\" },\n\t\t],\n\t},\n\t\"databases:write\": {\n\t\tgroup: \"databases\",\n\t\troutes: [\n\t\t\t{ method: \"POST\", path: \"/v1/databases\" },\n\t\t\t{ method: \"PUT\", path: \"/v1/databases/:id\" },\n\t\t\t{ method: \"POST\", path: \"/v1/databases/:id/start\" },\n\t\t\t{ method: \"POST\", path: \"/v1/databases/:id/stop\" },\n\t\t\t{ method: \"POST\", path: \"/v1/databases/:id/reset\" },\n\t\t],\n\t},\n\t\"databases:delete\": { group: \"databases\", routes: [{ method: \"DELETE\", path: \"/v1/databases/:id\" }] },\n\t\"databases:credentials\": {\n\t\tgroup: \"databases\",\n\t\troutes: [\n\t\t\t{ method: \"GET\", path: \"/v1/databases/:id/credentials/certificate\" },\n\t\t\t{ method: \"POST\", path: \"/v1/databases/:id/credentials/certificate/reset\" },\n\t\t\t{ method: \"POST\", path: \"/v1/databases/:id/credentials/reset\" },\n\t\t],\n\t},\n\t\"snapshots:read\": {\n\t\tgroup: \"snapshots\",\n\t\troutes: [\n\t\t\t{ method: \"GET\", path: \"/v1/users/snapshots\" },\n\t\t\t{ method: \"GET\", path: \"/v1/users/:id/snapshots\" },\n\t\t\t{ method: \"GET\", path: \"/v1/users/:id/snapshots/:snapshot_id/download\" },\n\t\t],\n\t},\n\t\"snapshots:write\": {\n\t\tgroup: \"snapshots\",\n\t\troutes: [\n\t\t\t{ method: \"POST\", path: \"/v1/users/:id/snapshots\" },\n\t\t\t{ method: \"POST\", path: \"/v1/users/:id/snapshots/:snapshot_id/restore\" },\n\t\t],\n\t},\n\t\"account:read\": {\n\t\tgroup: \"account\",\n\t\troutes: [\n\t\t\t{ method: \"GET\", path: \"/v1/users/me\" },\n\t\t\t{ method: \"GET\", path: \"/v1/users/me/sessions\" },\n\t\t],\n\t},\n\t\"account:write\": {\n\t\tgroup: \"account\",\n\t\troutes: [\n\t\t\t{ method: \"PATCH\", path: \"/v1/users/me\" },\n\t\t\t{ method: \"POST\", path: \"/v1/users/me/folders\" },\n\t\t\t{ method: \"PATCH\", path: \"/v1/users/me/folders/:folder_id\" },\n\t\t\t{ method: \"DELETE\", path: \"/v1/users/me/folders/:folder_id\" },\n\t\t\t{ method: \"PUT\", path: \"/v1/users/me/folders/:folder_id/resources/:resource_type/:resource_id\" },\n\t\t\t{ method: \"DELETE\", path: \"/v1/users/me/folders/:folder_id/resources/:resource_type/:resource_id\" },\n\t\t\t{ method: \"PUT\", path: \"/v1/users/me/favorites/:resource_type/:resource_id\" },\n\t\t\t{ method: \"DELETE\", path: \"/v1/users/me/favorites/:resource_type/:resource_id\" },\n\t\t],\n\t},\n\t\"workspaces:read\": {\n\t\tgroup: \"workspaces\",\n\t\troutes: [\n\t\t\t{ method: \"GET\", path: \"/v1/workspaces\" },\n\t\t\t{ method: \"GET\", path: \"/v1/workspaces/:id\" },\n\t\t\t{ method: \"GET\", path: \"/v1/workspaces/:id/members\" },\n\t\t\t{ method: \"GET\", path: \"/v1/workspaces/:id/roles\" },\n\t\t\t{ method: \"GET\", path: \"/v1/workspaces/:id/action-requests\" },\n\t\t],\n\t},\n\t\"workspaces:write\": {\n\t\tgroup: \"workspaces\",\n\t\troutes: [\n\t\t\t{ method: \"POST\", path: \"/v1/workspaces\" },\n\t\t\t{ method: \"PUT\", path: \"/v1/workspaces/:id\" },\n\t\t\t{ method: \"PUT\", path: \"/v1/workspaces/:id/members/:user_id\" },\n\t\t\t{ method: \"DELETE\", path: \"/v1/workspaces/:id/members/:user_id\" },\n\t\t\t{ method: \"POST\", path: \"/v1/workspaces/:id/roles\" },\n\t\t\t{ method: \"PUT\", path: \"/v1/workspaces/:id/roles/:role_id\" },\n\t\t\t{ method: \"DELETE\", path: \"/v1/workspaces/:id/roles/:role_id\" },\n\t\t\t{ method: \"POST\", path: \"/v1/workspaces/:id/apps/:app_id\" },\n\t\t\t{ method: \"DELETE\", path: \"/v1/workspaces/:id/apps/:app_id\" },\n\t\t\t{ method: \"POST\", path: \"/v1/workspaces/:id/databases/:db_id\" },\n\t\t\t{ method: \"DELETE\", path: \"/v1/workspaces/:id/databases/:db_id\" },\n\t\t\t{ method: \"POST\", path: \"/v1/workspaces/:id/folders\" },\n\t\t\t{ method: \"PATCH\", path: \"/v1/workspaces/:id/folders/:folder_id\" },\n\t\t\t{ method: \"DELETE\", path: \"/v1/workspaces/:id/folders/:folder_id\" },\n\t\t\t{ method: \"PUT\", path: \"/v1/workspaces/:id/folders/:folder_id/resources/:resource_type/:resource_id\" },\n\t\t\t{ method: \"DELETE\", path: \"/v1/workspaces/:id/folders/:folder_id/resources/:resource_type/:resource_id\" },\n\t\t\t{ method: \"PUT\", path: \"/v1/workspaces/:id/favorites/:resource_type/:resource_id\" },\n\t\t\t{ method: \"DELETE\", path: \"/v1/workspaces/:id/favorites/:resource_type/:resource_id\" },\n\t\t\t{ method: \"POST\", path: \"/v1/workspaces/:id/action-requests\" },\n\t\t],\n\t},\n\t/**\n\t * Intentionally left out (dashboard session only): creating invites (a leaked key could grant\n\t * access that outlives its revocation), transferring ownership, approving/rejecting action\n\t * requests (approval is a human decision) and exporting activities.\n\t */\n\t/** Delete a workspace (soft delete). Only in the `full` preset, like `apps:delete`. */\n\t\"workspaces:delete\": {\n\t\tgroup: \"workspaces\",\n\t\troutes: [{ method: \"DELETE\", path: \"/v1/workspaces/:id\" }],\n\t},\n\t/** List and revoke workspace invites; view, accept and decline your own invite by token. Only in the `full` preset. */\n\t\"workspaces:invites\": {\n\t\tgroup: \"workspaces\",\n\t\troutes: [\n\t\t\t{ method: \"GET\", path: \"/v1/workspaces/:id/invites\" },\n\t\t\t{ method: \"DELETE\", path: \"/v1/workspaces/:id/invites/:invite_id\" },\n\t\t\t{ method: \"GET\", path: \"/v1/workspaces/invites/:token\" },\n\t\t\t{ method: \"POST\", path: \"/v1/workspaces/invites/:token/accept\" },\n\t\t\t{ method: \"POST\", path: \"/v1/workspaces/invites/:token/decline\" },\n\t\t],\n\t},\n\t/** Blob Storage (`blob.vertracloud.app`). Upload tokens (`vcup_`) are a separate credential, not a scope. */\n\t\"blob:read\": {\n\t\tgroup: \"blob\",\n\t\troutes: [\n\t\t\t{ method: \"GET\", path: \"/v1/blob/objects\" },\n\t\t\t{ method: \"GET\", path: \"/v1/blob/objects/:object_id\" },\n\t\t\t{ method: \"GET\", path: \"/v1/blob/objects/:object_id/download\" },\n\t\t\t{ method: \"GET\", path: \"/v1/blob/shares\" },\n\t\t\t{ method: \"GET\", path: \"/v1/blob/rules\" },\n\t\t\t{ method: \"GET\", path: \"/v1/blob/stats\" },\n\t\t\t{ method: \"GET\", path: \"/v1/blob/s3/credentials\" },\n\t\t\t{ method: \"GET\", path: \"/v1/blob/domains\" },\n\t\t],\n\t},\n\t\"blob:write\": {\n\t\tgroup: \"blob\",\n\t\troutes: [\n\t\t\t{ method: \"POST\", path: \"/v1/blob/objects\" },\n\t\t\t{ method: \"PATCH\", path: \"/v1/blob/objects\" },\n\t\t\t{ method: \"PATCH\", path: \"/v1/blob/objects/:object_id\" },\n\t\t\t{ method: \"POST\", path: \"/v1/blob/objects/copy\" },\n\t\t\t{ method: \"DELETE\", path: \"/v1/blob/objects\" },\n\t\t\t{ method: \"DELETE\", path: \"/v1/blob/objects/:object_id\" },\n\t\t\t{ method: \"POST\", path: \"/v1/blob/uploads\" },\n\t\t\t{ method: \"GET\", path: \"/v1/blob/uploads\" },\n\t\t\t{ method: \"GET\", path: \"/v1/blob/uploads/:upload_id\" },\n\t\t\t{ method: \"POST\", path: \"/v1/blob/uploads/:upload_id/parts\" },\n\t\t\t{ method: \"POST\", path: \"/v1/blob/uploads/:upload_id/complete\" },\n\t\t\t{ method: \"DELETE\", path: \"/v1/blob/uploads/:upload_id\" },\n\t\t\t{ method: \"POST\", path: \"/v1/blob/shares\" },\n\t\t\t{ method: \"DELETE\", path: \"/v1/blob/shares/:share_id\" },\n\t\t\t{ method: \"PUT\", path: \"/v1/blob/rules\" },\n\t\t\t{ method: \"PUT\", path: \"/v1/blob/rules/:prefix\" },\n\t\t\t{ method: \"DELETE\", path: \"/v1/blob/rules/:prefix\" },\n\t\t\t{ method: \"POST\", path: \"/v1/blob/upload-tokens\" },\n\t\t\t{ method: \"POST\", path: \"/v1/blob/domains\" },\n\t\t\t{ method: \"POST\", path: \"/v1/blob/domains/:domain_id/verify\" },\n\t\t\t{ method: \"PATCH\", path: \"/v1/blob/domains/:domain_id\" },\n\t\t\t{ method: \"DELETE\", path: \"/v1/blob/domains/:domain_id\" },\n\t\t],\n\t},\n\t\"billing:read\": {\n\t\tgroup: \"billing\",\n\t\troutes: [\n\t\t\t{ method: \"GET\", path: \"/v1/orders\" },\n\t\t\t{ method: \"GET\", path: \"/v1/orders/:orderId/status\" },\n\t\t\t{ method: \"GET\", path: \"/v1/users/me/billing\" },\n\t\t],\n\t},\n\t/**\n\t * Creates a plan order and generates the PIX charge; the payment itself is made by a person in their banking app.\n\t * Also saves the billing details (name, address, CPF/CNPJ) an order needs.\n\t */\n\t\"billing:write\": {\n\t\tgroup: \"billing\",\n\t\troutes: [\n\t\t\t{ method: \"POST\", path: \"/v1/orders\" },\n\t\t\t{ method: \"POST\", path: \"/v1/orders/:orderId/initiate/pix\" },\n\t\t\t{ method: \"PUT\", path: \"/v1/users/me/billing\" },\n\t\t],\n\t},\n\t\"redeem:write\": { group: \"billing\", routes: [{ method: \"POST\", path: \"/v1/redeem/:code\" }] },\n};\n\nexport const API_KEY_SCOPE_LIST = Object.keys(API_KEY_SCOPES) as APIApiKeyScope[];\n\n/** Scopes selected by a preset. `full` is the whole catalog. */\nexport function apiKeyPresetScopes(preset: APIApiKeyPreset): APIApiKeyScope[] {\n\tif (preset === \"full\") return API_KEY_SCOPE_LIST;\n\treturn API_KEY_SCOPE_LIST.filter((s) => s.endsWith(\":read\") || (preset === \"write\" && s.endsWith(\":write\")));\n}\n\n/** Maximum keys per account, entries in `allowed_ips`, and key name length. */\nexport const API_KEY_MAX_PER_USER = 10;\nexport const API_KEY_MAX_ALLOWED_IPS = 20;\nexport const API_KEY_NAME_MAX_LENGTH = 40;\n\n/**\n * An API key as listed. The secret is returned only ONCE, in `APIApiKeyCreated`.\n * @see https://docs.vertracloud.app/api-reference/endpoint/users/api-keys/list\n */\nexport interface APIApiKey {\n\tid: string;\n\tname: string;\n\t/** Public start of the key (`vc_live_a1b2c3d4`; older keys: 8 hex characters). */\n\tprefix: string;\n\t/** Last 4 characters; `null` for keys generated before the `vc_live_` format. */\n\tlast4: string | null;\n\tscopes: APIApiKeyScope[];\n\t/** Allowed IPs/CIDRs. Empty list = any IP. */\n\tallowed_ips: string[];\n\tcreated_at: ISODateString;\n\tlast_used_at: ISODateString | null;\n}\n\nexport interface APIApiKeyCreated extends APIApiKey {\n\t/** The full secret. Shown once; it cannot be recovered. */\n\tapi_key: string;\n}\n"],"mappings":"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","names":[]}
@@ -17,6 +17,8 @@ var APIApiKeyScope = {
17
17
  WORKSPACES_WRITE: "workspaces:write",
18
18
  WORKSPACES_DELETE: "workspaces:delete",
19
19
  WORKSPACES_INVITES: "workspaces:invites",
20
+ BLOB_READ: "blob:read",
21
+ BLOB_WRITE: "blob:write",
20
22
  BILLING_READ: "billing:read",
21
23
  BILLING_WRITE: "billing:write",
22
24
  REDEEM_WRITE: "redeem:write"
@@ -201,6 +203,47 @@ var API_KEY_SCOPES = {
201
203
  { method: "POST", path: "/v1/workspaces/invites/:token/decline" }
202
204
  ]
203
205
  },
206
+ /** Blob Storage (`blob.vertracloud.app`). Upload tokens (`vcup_`) are a separate credential, not a scope. */
207
+ "blob:read": {
208
+ group: "blob",
209
+ routes: [
210
+ { method: "GET", path: "/v1/blob/objects" },
211
+ { method: "GET", path: "/v1/blob/objects/:object_id" },
212
+ { method: "GET", path: "/v1/blob/objects/:object_id/download" },
213
+ { method: "GET", path: "/v1/blob/shares" },
214
+ { method: "GET", path: "/v1/blob/rules" },
215
+ { method: "GET", path: "/v1/blob/stats" },
216
+ { method: "GET", path: "/v1/blob/s3/credentials" },
217
+ { method: "GET", path: "/v1/blob/domains" }
218
+ ]
219
+ },
220
+ "blob:write": {
221
+ group: "blob",
222
+ routes: [
223
+ { method: "POST", path: "/v1/blob/objects" },
224
+ { method: "PATCH", path: "/v1/blob/objects" },
225
+ { method: "PATCH", path: "/v1/blob/objects/:object_id" },
226
+ { method: "POST", path: "/v1/blob/objects/copy" },
227
+ { method: "DELETE", path: "/v1/blob/objects" },
228
+ { method: "DELETE", path: "/v1/blob/objects/:object_id" },
229
+ { method: "POST", path: "/v1/blob/uploads" },
230
+ { method: "GET", path: "/v1/blob/uploads" },
231
+ { method: "GET", path: "/v1/blob/uploads/:upload_id" },
232
+ { method: "POST", path: "/v1/blob/uploads/:upload_id/parts" },
233
+ { method: "POST", path: "/v1/blob/uploads/:upload_id/complete" },
234
+ { method: "DELETE", path: "/v1/blob/uploads/:upload_id" },
235
+ { method: "POST", path: "/v1/blob/shares" },
236
+ { method: "DELETE", path: "/v1/blob/shares/:share_id" },
237
+ { method: "PUT", path: "/v1/blob/rules" },
238
+ { method: "PUT", path: "/v1/blob/rules/:prefix" },
239
+ { method: "DELETE", path: "/v1/blob/rules/:prefix" },
240
+ { method: "POST", path: "/v1/blob/upload-tokens" },
241
+ { method: "POST", path: "/v1/blob/domains" },
242
+ { method: "POST", path: "/v1/blob/domains/:domain_id/verify" },
243
+ { method: "PATCH", path: "/v1/blob/domains/:domain_id" },
244
+ { method: "DELETE", path: "/v1/blob/domains/:domain_id" }
245
+ ]
246
+ },
204
247
  "billing:read": {
205
248
  group: "billing",
206
249
  routes: [
@@ -0,0 +1,248 @@
1
+ import { SnowFlake, ISODateString } from '../../common/v1.js';
2
+ import { APIErrorCode } from './api-error.js';
3
+
4
+ /** Who can read an object by its public URL. `private` objects need a temporary link or a share. */
5
+ type BlobVisibility = "public" | "private";
6
+ declare const BlobVisibility: {
7
+ readonly PUBLIC: "public";
8
+ readonly PRIVATE: "private";
9
+ };
10
+ /** How a browser treats the file: shown in the page (`inline`) or saved (`attachment`). */
11
+ type BlobContentDisposition = "inline" | "attachment";
12
+ declare const BlobContentDisposition: {
13
+ readonly INLINE: "inline";
14
+ readonly ATTACHMENT: "attachment";
15
+ };
16
+ /** `single` = one `PUT` to one URL; `multipart` = several parts, each with its own URL. */
17
+ type BlobUploadMode = "single" | "multipart";
18
+ declare const BlobUploadMode: {
19
+ readonly SINGLE: "single";
20
+ readonly MULTIPART: "multipart";
21
+ };
22
+ type BlobUploadStatus = "pending" | "completed" | "aborted" | "expired";
23
+ declare const BlobUploadStatus: {
24
+ readonly PENDING: "pending";
25
+ readonly COMPLETED: "completed";
26
+ readonly ABORTED: "aborted";
27
+ readonly EXPIRED: "expired";
28
+ };
29
+ type BlobCustomDomainStatus = "pending" | "active" | "failed" | "suspended";
30
+ declare const BlobCustomDomainStatus: {
31
+ readonly PENDING: "pending";
32
+ readonly ACTIVE: "active";
33
+ readonly FAILED: "failed";
34
+ readonly SUSPENDED: "suspended";
35
+ };
36
+ /** A stored file. The `id` never changes; `path` can (move, rename). */
37
+ interface APIBlobObject {
38
+ id: SnowFlake;
39
+ /** Full path inside the account, for example `images/avatars/joao.png`. */
40
+ path: string;
41
+ size: number;
42
+ content_type: string;
43
+ etag: string;
44
+ /** SHA-256 (hex) of the content, when the upload sent a checksum. */
45
+ sha256: string | null;
46
+ visibility: BlobVisibility;
47
+ /** Public URL; `null` while the object is private. */
48
+ url: string | null;
49
+ /** `immutable`, `max-age=<seconds>` or `no-cache` (plan-dependent); `null` = default. */
50
+ cache_control: string | null;
51
+ content_disposition: BlobContentDisposition;
52
+ /** File name suggested on download; `null` = the last segment of `path`. */
53
+ filename: string | null;
54
+ /** Up to 5 keys (`[a-z0-9-]{1,64}`) and 512 bytes in total; plan-dependent. */
55
+ metadata: Record<string, string>;
56
+ expires_at: ISODateString | null;
57
+ created_at: ISODateString;
58
+ updated_at: ISODateString;
59
+ }
60
+ /** Result of listing objects: one page of files plus the folders found under the prefix. */
61
+ interface APIBlobObjectList {
62
+ objects: APIBlobObject[];
63
+ /** Folder prefixes ending in `/` (empty without a `delimiter`). */
64
+ folders: string[];
65
+ /** Pass back as `cursor` for the next page; `null` = last page. */
66
+ cursor: string | null;
67
+ }
68
+ /** A direct upload in progress. Bytes go straight to the URLs, not through the API. */
69
+ interface APIBlobUpload {
70
+ id: SnowFlake;
71
+ /** Final path (with the random suffix, when requested). */
72
+ path: string;
73
+ mode: BlobUploadMode;
74
+ status: BlobUploadStatus;
75
+ size: number;
76
+ /** When the URLs and the reserved storage expire. */
77
+ expires_at: ISODateString;
78
+ /** `single` mode: URL to `PUT` the whole file to. */
79
+ url?: string;
80
+ /** Headers the `PUT` must send exactly as given. */
81
+ headers: Record<string, string>;
82
+ /** `multipart` mode: fixed part size (the last part can be smaller). */
83
+ part_size?: number;
84
+ part_count?: number;
85
+ /** Part numbers already stored; use it to resume an interrupted upload. */
86
+ uploaded_parts?: number[];
87
+ created_at: ISODateString;
88
+ }
89
+ interface APIBlobUploadPart {
90
+ part_number: number;
91
+ url: string;
92
+ size: number;
93
+ /** Headers the `PUT` of this part must send exactly as given. */
94
+ headers: Record<string, string>;
95
+ }
96
+ /** Plan limits that apply to Blob Storage, so clients need not hardcode them. */
97
+ interface APIBlobLimits {
98
+ /** Largest file accepted by the single-request upload. */
99
+ max_simple_upload_bytes: number;
100
+ /** Largest file that can be sent in one part of a direct upload. */
101
+ max_single_put_bytes: number;
102
+ max_object_bytes: number;
103
+ min_part_bytes: number;
104
+ max_part_bytes: number;
105
+ max_parts: number;
106
+ max_open_uploads: number;
107
+ /** `null` = no limit of its own. */
108
+ uploads_per_second: number | null;
109
+ max_rules: number;
110
+ max_custom_domains: number;
111
+ metadata_enabled: boolean;
112
+ share_password_enabled: boolean;
113
+ /** Whether `cache_control: "no-cache"` is allowed. */
114
+ no_cache_enabled: boolean;
115
+ /** Shortest accepted `expires_at` from now, in seconds. */
116
+ min_expiration_seconds: number;
117
+ /** 0 = image transformation is not included in the plan. */
118
+ image_transformations_per_month: number;
119
+ }
120
+ interface APIBlobStats {
121
+ objects: number;
122
+ used_bytes: number;
123
+ quota_bytes: number;
124
+ /** Above 0 only after a plan downgrade. */
125
+ over_quota_bytes: number;
126
+ /** Estimated overage charge, in cents, billed on renewal. */
127
+ estimated_overage_cents: number;
128
+ month_average_bytes: number;
129
+ /** Image transformations used in the current month. */
130
+ image_transformations_used: number;
131
+ /** Base URL of the public files of the account. */
132
+ public_base_url: string;
133
+ limits: APIBlobLimits;
134
+ }
135
+ /** One item of a batch update. */
136
+ interface APIBlobBatchResult {
137
+ id: SnowFlake;
138
+ ok: boolean;
139
+ /** Set when `ok` is `false`. */
140
+ code?: APIErrorCode;
141
+ /** Set when `ok` is `true`. */
142
+ object?: APIBlobObject;
143
+ }
144
+ interface APIBlobDeleteResult {
145
+ deleted: SnowFlake[];
146
+ not_found: SnowFlake[];
147
+ /** `true` when more objects match and another call is needed. */
148
+ remaining: boolean;
149
+ }
150
+ /** Temporary download link, returned when `redirect=false`. */
151
+ interface APIBlobDownload {
152
+ url: string;
153
+ expires_at: ISODateString;
154
+ }
155
+ /** Short-lived credential for browsers and untrusted clients; usable only on the upload routes. */
156
+ interface APIBlobUploadToken {
157
+ /** Starts with `vcup_`. Shown once. */
158
+ token: string;
159
+ expires_at: ISODateString;
160
+ max_uses: number;
161
+ }
162
+ interface APIBlobShare {
163
+ id: SnowFlake;
164
+ object_id: SnowFlake;
165
+ /** Share page URL. */
166
+ url: string;
167
+ expires_at: ISODateString;
168
+ max_downloads: number | null;
169
+ remaining_downloads: number | null;
170
+ has_password: boolean;
171
+ /** `true` = the object is public, so the share does not protect it. */
172
+ object_is_public: boolean;
173
+ created_at: ISODateString;
174
+ }
175
+ /** What the public share page shows before the download. No sign-in needed; the token is the credential. */
176
+ interface APIBlobSharePublic {
177
+ filename: string;
178
+ size: number;
179
+ content_type: string;
180
+ has_password: boolean;
181
+ expires_at: ISODateString;
182
+ remaining_downloads: number | null;
183
+ }
184
+ /** Defaults and limits applied to every object under a folder prefix. The longest matching prefix wins. */
185
+ interface APIBlobRule {
186
+ /** Folder prefix, always stored with a trailing `/`. */
187
+ prefix: string;
188
+ /** Default visibility of new objects in the folder. */
189
+ visibility?: BlobVisibility;
190
+ /** Default expiration of each new object, in seconds. */
191
+ expire_seconds?: number;
192
+ /** Largest accepted file, 512 bytes to 10 GB. */
193
+ max_size?: number;
194
+ /** Accepted extensions (1–50), lowercase, without the dot. */
195
+ extensions?: string[];
196
+ cache_control?: string;
197
+ /** Delete objects this many days after upload (1–3650). */
198
+ delete_after_days?: number;
199
+ /** When `delete_after_days` starts to apply. */
200
+ active_from?: ISODateString;
201
+ created_at: ISODateString;
202
+ }
203
+ /** The rule list and the version tag to send back as `If-Match` when replacing it. */
204
+ interface APIBlobRules {
205
+ rules: APIBlobRule[];
206
+ etag: string;
207
+ }
208
+ /** S3-compatible credentials, derived from the API key that requested them. */
209
+ interface APIBlobS3Credentials {
210
+ access_key_id: string;
211
+ secret_access_key: string;
212
+ endpoint: string;
213
+ region: "auto";
214
+ buckets: ["public", "private"];
215
+ access: {
216
+ read: boolean;
217
+ write: boolean;
218
+ };
219
+ }
220
+ interface APIBlobCustomDomain {
221
+ id: SnowFlake;
222
+ /** Subdomain only (`cdn.example.com`). */
223
+ hostname: string;
224
+ status: BlobCustomDomainStatus;
225
+ ssl_status: string;
226
+ /** Point a CNAME record of `hostname` to this value. */
227
+ cname_target: string;
228
+ /** When set, the domain serves only this folder. */
229
+ prefix: string | null;
230
+ /**
231
+ * `true`: on this domain, `.html`, `.htm`, `.xhtml`, `.svg` and `.xml` open in the browser with their real type (pages
232
+ * run JavaScript in a sandbox: no forms, no cookies, no top-level navigation). `false` (default): they always download.
233
+ * The default public URL always downloads them, whatever this value.
234
+ */
235
+ web_content: boolean;
236
+ /**
237
+ * Ownership proof: publish this `TXT` record at `name` with the exact `value`. The domain only becomes
238
+ * `active` after it resolves (and the CNAME and certificate are ready). `null` once the domain is active.
239
+ */
240
+ verification?: {
241
+ type: "txt";
242
+ name: string;
243
+ value: string;
244
+ } | null;
245
+ created_at: ISODateString;
246
+ }
247
+
248
+ export { type APIBlobBatchResult, type APIBlobCustomDomain, type APIBlobDeleteResult, type APIBlobDownload, type APIBlobLimits, type APIBlobObject, type APIBlobObjectList, type APIBlobRule, type APIBlobRules, type APIBlobS3Credentials, type APIBlobShare, type APIBlobSharePublic, type APIBlobStats, type APIBlobUpload, type APIBlobUploadPart, type APIBlobUploadToken, BlobContentDisposition, BlobCustomDomainStatus, BlobUploadMode, BlobUploadStatus, BlobVisibility };
@@ -0,0 +1,56 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // payloads/v1/blob.ts
21
+ var blob_exports = {};
22
+ __export(blob_exports, {
23
+ BlobContentDisposition: () => BlobContentDisposition,
24
+ BlobCustomDomainStatus: () => BlobCustomDomainStatus,
25
+ BlobUploadMode: () => BlobUploadMode,
26
+ BlobUploadStatus: () => BlobUploadStatus,
27
+ BlobVisibility: () => BlobVisibility
28
+ });
29
+ module.exports = __toCommonJS(blob_exports);
30
+ var BlobVisibility = { PUBLIC: "public", PRIVATE: "private" };
31
+ var BlobContentDisposition = {
32
+ INLINE: "inline",
33
+ ATTACHMENT: "attachment"
34
+ };
35
+ var BlobUploadMode = { SINGLE: "single", MULTIPART: "multipart" };
36
+ var BlobUploadStatus = {
37
+ PENDING: "pending",
38
+ COMPLETED: "completed",
39
+ ABORTED: "aborted",
40
+ EXPIRED: "expired"
41
+ };
42
+ var BlobCustomDomainStatus = {
43
+ PENDING: "pending",
44
+ ACTIVE: "active",
45
+ FAILED: "failed",
46
+ SUSPENDED: "suspended"
47
+ };
48
+ // Annotate the CommonJS export names for ESM import in node:
49
+ 0 && (module.exports = {
50
+ BlobContentDisposition,
51
+ BlobCustomDomainStatus,
52
+ BlobUploadMode,
53
+ BlobUploadStatus,
54
+ BlobVisibility
55
+ });
56
+ //# sourceMappingURL=blob.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["blob.ts"],"sourcesContent":["import type { ISODateString, SnowFlake } from \"../../v1\";\nimport type { APIErrorCode } from \"./api-error\";\n\n/** Who can read an object by its public URL. `private` objects need a temporary link or a share. */\nexport type BlobVisibility = \"public\" | \"private\";\nexport const BlobVisibility = { PUBLIC: \"public\", PRIVATE: \"private\" } as const satisfies Record<string, BlobVisibility>;\n\n/** How a browser treats the file: shown in the page (`inline`) or saved (`attachment`). */\nexport type BlobContentDisposition = \"inline\" | \"attachment\";\nexport const BlobContentDisposition = {\n\tINLINE: \"inline\",\n\tATTACHMENT: \"attachment\",\n} as const satisfies Record<string, BlobContentDisposition>;\n\n/** `single` = one `PUT` to one URL; `multipart` = several parts, each with its own URL. */\nexport type BlobUploadMode = \"single\" | \"multipart\";\nexport const BlobUploadMode = { SINGLE: \"single\", MULTIPART: \"multipart\" } as const satisfies Record<string, BlobUploadMode>;\n\nexport type BlobUploadStatus = \"pending\" | \"completed\" | \"aborted\" | \"expired\";\nexport const BlobUploadStatus = {\n\tPENDING: \"pending\",\n\tCOMPLETED: \"completed\",\n\tABORTED: \"aborted\",\n\tEXPIRED: \"expired\",\n} as const satisfies Record<string, BlobUploadStatus>;\n\nexport type BlobCustomDomainStatus = \"pending\" | \"active\" | \"failed\" | \"suspended\";\nexport const BlobCustomDomainStatus = {\n\tPENDING: \"pending\",\n\tACTIVE: \"active\",\n\tFAILED: \"failed\",\n\tSUSPENDED: \"suspended\",\n} as const satisfies Record<string, BlobCustomDomainStatus>;\n\n/** A stored file. The `id` never changes; `path` can (move, rename). */\nexport interface APIBlobObject {\n\tid: SnowFlake;\n\t/** Full path inside the account, for example `images/avatars/joao.png`. */\n\tpath: string;\n\tsize: number;\n\tcontent_type: string;\n\tetag: string;\n\t/** SHA-256 (hex) of the content, when the upload sent a checksum. */\n\tsha256: string | null;\n\tvisibility: BlobVisibility;\n\t/** Public URL; `null` while the object is private. */\n\turl: string | null;\n\t/** `immutable`, `max-age=<seconds>` or `no-cache` (plan-dependent); `null` = default. */\n\tcache_control: string | null;\n\tcontent_disposition: BlobContentDisposition;\n\t/** File name suggested on download; `null` = the last segment of `path`. */\n\tfilename: string | null;\n\t/** Up to 5 keys (`[a-z0-9-]{1,64}`) and 512 bytes in total; plan-dependent. */\n\tmetadata: Record<string, string>;\n\texpires_at: ISODateString | null;\n\tcreated_at: ISODateString;\n\tupdated_at: ISODateString;\n}\n\n/** Result of listing objects: one page of files plus the folders found under the prefix. */\nexport interface APIBlobObjectList {\n\tobjects: APIBlobObject[];\n\t/** Folder prefixes ending in `/` (empty without a `delimiter`). */\n\tfolders: string[];\n\t/** Pass back as `cursor` for the next page; `null` = last page. */\n\tcursor: string | null;\n}\n\n/** A direct upload in progress. Bytes go straight to the URLs, not through the API. */\nexport interface APIBlobUpload {\n\tid: SnowFlake;\n\t/** Final path (with the random suffix, when requested). */\n\tpath: string;\n\tmode: BlobUploadMode;\n\tstatus: BlobUploadStatus;\n\tsize: number;\n\t/** When the URLs and the reserved storage expire. */\n\texpires_at: ISODateString;\n\t/** `single` mode: URL to `PUT` the whole file to. */\n\turl?: string;\n\t/** Headers the `PUT` must send exactly as given. */\n\theaders: Record<string, string>;\n\t/** `multipart` mode: fixed part size (the last part can be smaller). */\n\tpart_size?: number;\n\tpart_count?: number;\n\t/** Part numbers already stored; use it to resume an interrupted upload. */\n\tuploaded_parts?: number[];\n\tcreated_at: ISODateString;\n}\n\nexport interface APIBlobUploadPart {\n\tpart_number: number;\n\turl: string;\n\tsize: number;\n\t/** Headers the `PUT` of this part must send exactly as given. */\n\theaders: Record<string, string>;\n}\n\n/** Plan limits that apply to Blob Storage, so clients need not hardcode them. */\nexport interface APIBlobLimits {\n\t/** Largest file accepted by the single-request upload. */\n\tmax_simple_upload_bytes: number;\n\t/** Largest file that can be sent in one part of a direct upload. */\n\tmax_single_put_bytes: number;\n\tmax_object_bytes: number;\n\tmin_part_bytes: number;\n\tmax_part_bytes: number;\n\tmax_parts: number;\n\tmax_open_uploads: number;\n\t/** `null` = no limit of its own. */\n\tuploads_per_second: number | null;\n\tmax_rules: number;\n\tmax_custom_domains: number;\n\tmetadata_enabled: boolean;\n\tshare_password_enabled: boolean;\n\t/** Whether `cache_control: \"no-cache\"` is allowed. */\n\tno_cache_enabled: boolean;\n\t/** Shortest accepted `expires_at` from now, in seconds. */\n\tmin_expiration_seconds: number;\n\t/** 0 = image transformation is not included in the plan. */\n\timage_transformations_per_month: number;\n}\n\nexport interface APIBlobStats {\n\tobjects: number;\n\tused_bytes: number;\n\tquota_bytes: number;\n\t/** Above 0 only after a plan downgrade. */\n\tover_quota_bytes: number;\n\t/** Estimated overage charge, in cents, billed on renewal. */\n\testimated_overage_cents: number;\n\tmonth_average_bytes: number;\n\t/** Image transformations used in the current month. */\n\timage_transformations_used: number;\n\t/** Base URL of the public files of the account. */\n\tpublic_base_url: string;\n\tlimits: APIBlobLimits;\n}\n\n/** One item of a batch update. */\nexport interface APIBlobBatchResult {\n\tid: SnowFlake;\n\tok: boolean;\n\t/** Set when `ok` is `false`. */\n\tcode?: APIErrorCode;\n\t/** Set when `ok` is `true`. */\n\tobject?: APIBlobObject;\n}\n\nexport interface APIBlobDeleteResult {\n\tdeleted: SnowFlake[];\n\tnot_found: SnowFlake[];\n\t/** `true` when more objects match and another call is needed. */\n\tremaining: boolean;\n}\n\n/** Temporary download link, returned when `redirect=false`. */\nexport interface APIBlobDownload {\n\turl: string;\n\texpires_at: ISODateString;\n}\n\n/** Short-lived credential for browsers and untrusted clients; usable only on the upload routes. */\nexport interface APIBlobUploadToken {\n\t/** Starts with `vcup_`. Shown once. */\n\ttoken: string;\n\texpires_at: ISODateString;\n\tmax_uses: number;\n}\n\nexport interface APIBlobShare {\n\tid: SnowFlake;\n\tobject_id: SnowFlake;\n\t/** Share page URL. */\n\turl: string;\n\texpires_at: ISODateString;\n\tmax_downloads: number | null;\n\tremaining_downloads: number | null;\n\thas_password: boolean;\n\t/** `true` = the object is public, so the share does not protect it. */\n\tobject_is_public: boolean;\n\tcreated_at: ISODateString;\n}\n\n/** What the public share page shows before the download. No sign-in needed; the token is the credential. */\nexport interface APIBlobSharePublic {\n\tfilename: string;\n\tsize: number;\n\tcontent_type: string;\n\thas_password: boolean;\n\texpires_at: ISODateString;\n\tremaining_downloads: number | null;\n}\n\n/** Defaults and limits applied to every object under a folder prefix. The longest matching prefix wins. */\nexport interface APIBlobRule {\n\t/** Folder prefix, always stored with a trailing `/`. */\n\tprefix: string;\n\t/** Default visibility of new objects in the folder. */\n\tvisibility?: BlobVisibility;\n\t/** Default expiration of each new object, in seconds. */\n\texpire_seconds?: number;\n\t/** Largest accepted file, 512 bytes to 10 GB. */\n\tmax_size?: number;\n\t/** Accepted extensions (1–50), lowercase, without the dot. */\n\textensions?: string[];\n\tcache_control?: string;\n\t/** Delete objects this many days after upload (1–3650). */\n\tdelete_after_days?: number;\n\t/** When `delete_after_days` starts to apply. */\n\tactive_from?: ISODateString;\n\tcreated_at: ISODateString;\n}\n\n/** The rule list and the version tag to send back as `If-Match` when replacing it. */\nexport interface APIBlobRules {\n\trules: APIBlobRule[];\n\tetag: string;\n}\n\n/** S3-compatible credentials, derived from the API key that requested them. */\nexport interface APIBlobS3Credentials {\n\taccess_key_id: string;\n\tsecret_access_key: string;\n\tendpoint: string;\n\tregion: \"auto\";\n\tbuckets: [\"public\", \"private\"];\n\taccess: { read: boolean; write: boolean };\n}\n\nexport interface APIBlobCustomDomain {\n\tid: SnowFlake;\n\t/** Subdomain only (`cdn.example.com`). */\n\thostname: string;\n\tstatus: BlobCustomDomainStatus;\n\tssl_status: string;\n\t/** Point a CNAME record of `hostname` to this value. */\n\tcname_target: string;\n\t/** When set, the domain serves only this folder. */\n\tprefix: string | null;\n\t/**\n\t * `true`: on this domain, `.html`, `.htm`, `.xhtml`, `.svg` and `.xml` open in the browser with their real type (pages\n\t * run JavaScript in a sandbox: no forms, no cookies, no top-level navigation). `false` (default): they always download.\n\t * The default public URL always downloads them, whatever this value.\n\t */\n\tweb_content: boolean;\n\t/**\n\t * Ownership proof: publish this `TXT` record at `name` with the exact `value`. The domain only becomes\n\t * `active` after it resolves (and the CNAME and certificate are ready). `null` once the domain is active.\n\t */\n\tverification?: { type: \"txt\"; name: string; value: string } | null;\n\tcreated_at: ISODateString;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAKO,IAAM,iBAAiB,EAAE,QAAQ,UAAU,SAAS,UAAU;AAI9D,IAAM,yBAAyB;AAAA,EACrC,QAAQ;AAAA,EACR,YAAY;AACb;AAIO,IAAM,iBAAiB,EAAE,QAAQ,UAAU,WAAW,YAAY;AAGlE,IAAM,mBAAmB;AAAA,EAC/B,SAAS;AAAA,EACT,WAAW;AAAA,EACX,SAAS;AAAA,EACT,SAAS;AACV;AAGO,IAAM,yBAAyB;AAAA,EACrC,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,WAAW;AACZ;","names":[]}
@@ -0,0 +1,27 @@
1
+ // payloads/v1/blob.ts
2
+ var BlobVisibility = { PUBLIC: "public", PRIVATE: "private" };
3
+ var BlobContentDisposition = {
4
+ INLINE: "inline",
5
+ ATTACHMENT: "attachment"
6
+ };
7
+ var BlobUploadMode = { SINGLE: "single", MULTIPART: "multipart" };
8
+ var BlobUploadStatus = {
9
+ PENDING: "pending",
10
+ COMPLETED: "completed",
11
+ ABORTED: "aborted",
12
+ EXPIRED: "expired"
13
+ };
14
+ var BlobCustomDomainStatus = {
15
+ PENDING: "pending",
16
+ ACTIVE: "active",
17
+ FAILED: "failed",
18
+ SUSPENDED: "suspended"
19
+ };
20
+ export {
21
+ BlobContentDisposition,
22
+ BlobCustomDomainStatus,
23
+ BlobUploadMode,
24
+ BlobUploadStatus,
25
+ BlobVisibility
26
+ };
27
+ //# sourceMappingURL=blob.mjs.map
@@ -3,6 +3,7 @@ export { APIApiKey, APIApiKeyCreated, APIApiKeyPreset, APIApiKeyRoute, APIApiKey
3
3
  export { APIErrorCode, API_ERROR_CODES } from './api-error.js';
4
4
  export { APIApplication, APIApplicationConfig, APIApplicationCustomDomain, APIApplicationDeploySettings, APIApplicationDeployment, APIApplicationDnsRecord, APIApplicationEnvironment, APIApplicationFile, APIApplicationFileContent, APIApplicationFileTree, APIApplicationFileUpload, APIApplicationGithub, APIApplicationMetric, APIApplicationNetwork, APIApplicationOperationResponse, APIApplicationRealtimeEvent, APIApplicationRelease, APIApplicationReleaseLog, APIApplicationRollbackPreview, APIApplicationRuntime, APIApplicationRuntimes, APIApplicationScanSuggestions, APIApplicationShieldCooldown, APIApplicationStatus, APIApplicationStatusShort, APIApplicationSubdomain, APIApplicationWebPublish, APIApplicationWebhook, APIApplicationWebhookUrl, ApplicationCluster, ApplicationDnsRecordStatus, ApplicationDnsRecordType, ApplicationEnvironmentChange, ApplicationFileContentType, ApplicationFileType, ApplicationLanguage, ApplicationRealtimeEventType, ApplicationReleaseSource, ApplicationReleaseStatus, ApplicationStatus, ApplicationType, ApplicationVersion, ApplicationZeroDowntime, ShieldIncidentDirection, ShieldIncidentReason } from './application.js';
5
5
  export { APIBillingAddress, APIBillingCard, APIBillingDetails, APIBillingRenewal, APIBillingTaxId, BillingTaxIdType } from './billing.js';
6
+ export { APIBlobBatchResult, APIBlobCustomDomain, APIBlobDeleteResult, APIBlobDownload, APIBlobLimits, APIBlobObject, APIBlobObjectList, APIBlobRule, APIBlobRules, APIBlobS3Credentials, APIBlobShare, APIBlobSharePublic, APIBlobStats, APIBlobUpload, APIBlobUploadPart, APIBlobUploadToken, BlobContentDisposition, BlobCustomDomainStatus, BlobUploadMode, BlobUploadStatus, BlobVisibility } from './blob.js';
6
7
  export { APIDatabase, APIDatabaseCertificate, APIDatabaseMetrics, APIDatabaseNetwork, APIDatabaseOperationResponse, APIDatabasePasswordReset, APIDatabaseStatus, APIDatabaseStatusShort, DatabaseCluster, DatabaseStatus, DatabaseType } from './database.js';
7
8
  export { APIDatabaseCollection, APIDatabaseColumn, APIDatabaseColumnReference, APIDatabaseDataError, APIDatabaseDataOverview, APIDatabaseDocumentListParams, APIDatabaseDocumentsPage, APIDatabaseIndex, APIDatabaseListParams, APIDatabaseMongoIndex, APIDatabaseQueryResult, APIDatabaseRedisInfo, APIDatabaseRedisKey, APIDatabaseRedisKeyValue, APIDatabaseRedisKeysPage, APIDatabaseRedisScanParams, APIDatabaseRedisZSetMember, APIDatabaseRowFilter, APIDatabaseRowsPage, APIDatabaseSchema, APIDatabaseTable, DatabaseFilterOperator, DatabaseRedisKeyType, DatabaseSortDirection, DatabaseTableKind } from './database-data.js';
8
9
  export { APINotification, LocalizedContent, NotificationImportance, NotificationType } from './notification.js';