@neondatabase/config 1.9.6 → 1.10.1
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.
- package/README.md +2 -0
- package/dist/lib/neon-api-real.d.ts.map +1 -1
- package/dist/lib/neon-api-real.js +10 -0
- package/dist/lib/neon-api-real.js.map +1 -1
- package/dist/lib/neon-api.d.ts +18 -1
- package/dist/lib/neon-api.d.ts.map +1 -1
- package/dist/lib/types.d.ts +1 -1
- package/dist/lib/types.js.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -210,6 +210,8 @@ Two invariants are enforced **both** at author time (TypeScript) and at runtime
|
|
|
210
210
|
|
|
211
211
|
The auth wiring (`authProvider`, `jwksUrl`, …) is set when the Data API is first **enabled** and is immutable afterwards. The runtime `settings` are reconcilable: changing them is treated as an **update** and requires `updateExisting: true` (`apply`) / `--update-existing` (CLI), like compute/TTL/`protected` drift.
|
|
212
212
|
|
|
213
|
+
Because the provider cannot change, `neon init --services data-api` and `config pull` declare what the live Data API has rather than assuming Neon Auth: when the linked branch's Data API verifies an external IdP (or the API does not say and Neon Auth is off on the branch), they write `dataApi: { authProvider: "external", … }` with whatever wiring the API reports and leave `auth` alone. Otherwise they write `dataApi: true` with `auth: true`.
|
|
214
|
+
|
|
213
215
|
## Functions
|
|
214
216
|
|
|
215
217
|
The three operations mirror the Terraform mental model: **`inspect`** (read live state), **`plan`** (dry-run diff), **`apply`** (reconcile).
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"neon-api-real.d.ts","names":["DeployFunctionInput","NeonApi","CreateNeonAuthRestInput","createRealNeonApi","RetryConfig","retryOnLocked","T","Promise","collectCursorPages","isPreviewFeatureUnavailable","customDomainsUnavailableError","previewUnavailableError","createNeonAuthRestInput","buildFunctionDeployForm","FormData","readJsonBody","Response","DeployFunctionInput","NeonApi","CreateNeonAuthRestInput","auth_provider","database_name","createRealNeonApi","options","apiKey","baseUrl","retryOnLocked","maxAttempts","initialDelayMs","maxDelayMs","RetryConfig","fn","Promise","T","config","collectCursorPages","fetchPage","cursor","items","next","isPreviewFeatureUnavailable","err","customDomainsUnavailableError","previewUnavailableError","featureLabel","createNeonAuthRestInput","input","databaseName","buildFunctionDeployForm","FormData","readJsonBody","res","Response"],"sources":["../../src/lib/neon-api-real.ts"],"mappings":";;;A,
|
|
1
|
+
{"version":3,"file":"neon-api-real.d.ts","names":["DeployFunctionInput","NeonApi","CreateNeonAuthRestInput","createRealNeonApi","RetryConfig","retryOnLocked","T","Promise","collectCursorPages","isPreviewFeatureUnavailable","customDomainsUnavailableError","previewUnavailableError","createNeonAuthRestInput","buildFunctionDeployForm","FormData","readJsonBody","Response","DeployFunctionInput","NeonApi","CreateNeonAuthRestInput","auth_provider","database_name","createRealNeonApi","options","apiKey","baseUrl","retryOnLocked","maxAttempts","initialDelayMs","maxDelayMs","RetryConfig","fn","Promise","T","config","collectCursorPages","fetchPage","cursor","items","next","isPreviewFeatureUnavailable","err","customDomainsUnavailableError","previewUnavailableError","featureLabel","createNeonAuthRestInput","input","databaseName","buildFunctionDeployForm","FormData","readJsonBody","res","Response"],"sources":["../../src/lib/neon-api-real.ts"],"mappings":";;;A,UAgZUE,uBAAAA,C;;EAAAA,aAAAA,CAAAA,EAAAA,MAAAA;AAeV;AA4CC;AAeD;AAAmC;AAChBI;AAARC;AACFH,iBA7DOD,iBAAAA,CA6DPC,OAAAA,EAAAA;EACEE,MAAAA,EAAAA,MAAAA;EAARC,OAAAA,CAAAA,EAAAA,MAAAA;EAAO;AA6BV;AAAwC;AAGjBD;AAAjBC;EACKD,aAAAA,CAAAA,EAAAA;IAARC,WAAAA,CAAAA,EAAAA,MAAAA;IAAOqB,cAAA,CAAA,EAAA,MAAA;IAm6CMnB,UAAAA,CAAAA,EAAAA,MAAAA;EAgGAC,CAAAA;AAuDhB,CAAA,CAAA,EA5oDIT,OA4oDYU;AAqFhB,UAhsDUP,WAAAA,CAgsDMQ;EAoBAC,WAAAA,EAAAA,MAAAA;EAAuBe,cAAA,EAAA,MAAA;EAAQ5B,UAAAA,EAAAA,MAAAA;AAAsBc;AAAQ;AAwB7E;AAAkC;AAAME;AAAWT;AAAO;;A,iBA/tDpCF,a,cACXE,O,CAAQD,C,WACVF,W,GACNG,O,CAAQD,C;A,iBA6BWE,kB,+CAGhBD,O;E,OAAiBD,C;;A,KACpBC,O,CAAQD,C;;;;;;;;;;;;A,iBAm6CKG,2BAAAA,C;;;;;A,iBAgGAC,6BAAAA,C;;;;;;;;;;;;A,iBAuDAC,uBAAAA,C;A,iBAqFAC,uBAAAA,C;;A,IAEZV,uB;;;;;;;;;;;;A,iBAkBYW,uBAAAA,C,OAA+Bb,mB,GAAsBc,Q;;;;;;;;;;;A,iBAwB/CC,YAAAA,C,KAAkBC,Q,GAAWT,O"}
|
|
@@ -79,12 +79,22 @@ function dataApiCreateRequest(input) {
|
|
|
79
79
|
}
|
|
80
80
|
return req;
|
|
81
81
|
}
|
|
82
|
+
const REMOTE_DATA_API_AUTH_PROVIDERS = /* @__PURE__ */ new Set([
|
|
83
|
+
"neon_auth",
|
|
84
|
+
"external",
|
|
85
|
+
"none"
|
|
86
|
+
]);
|
|
82
87
|
/** Map a `DataAPIReponse` (GET) onto our {@link NeonDataApiSnapshot}. */
|
|
83
88
|
function dataApiSnapshotFromResponse(data) {
|
|
84
89
|
const snapshot = { url: data.url };
|
|
85
90
|
if (data.status !== void 0) snapshot.status = data.status;
|
|
86
91
|
const settings = dataApiSettingsFromApi(data.settings);
|
|
87
92
|
if (settings) snapshot.settings = settings;
|
|
93
|
+
const auth = data;
|
|
94
|
+
if (typeof auth.auth_provider === "string" && REMOTE_DATA_API_AUTH_PROVIDERS.has(auth.auth_provider)) snapshot.authProvider = auth.auth_provider;
|
|
95
|
+
if (typeof auth.jwks_url === "string") snapshot.jwksUrl = auth.jwks_url;
|
|
96
|
+
if (typeof auth.provider_name === "string") snapshot.providerName = auth.provider_name;
|
|
97
|
+
if (typeof auth.jwt_audience === "string") snapshot.jwtAudience = auth.jwt_audience;
|
|
88
98
|
return snapshot;
|
|
89
99
|
}
|
|
90
100
|
function realtimeOptionsToApi(input) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"neon-api-real.js","names":["rawListProjects","rawGetProject","rawCreateProject","rawUpdateProject","rawListProjectBranches","rawCreateProjectBranch","rawUpdateProjectBranch","rawListProjectEndpoints","rawUpdateProjectEndpoint","rawListProjectBranchRoles","rawListProjectBranchDatabases","rawGetConnectionUri","rawGetNeonAuth","rawGetProjectBranchDataApi","rawCreateProjectBranchDataApi","rawUpdateProjectBranchDataApi","rawDeleteProjectBranchDataApi","rawGetProjectBranchRealtime","rawGetProjectBranchRealtimeSecret","rawEnableProjectBranchRealtime","rawDisableProjectBranchRealtime"],"sources":["../../src/lib/neon-api-real.ts"],"sourcesContent":["import type {\n\tDataApiSettings as ApiDataApiSettings,\n\tRealtime as ApiRealtime,\n\tRealtimeOptions as ApiRealtimeOptions,\n\tRealtimeSecret as ApiRealtimeSecret,\n\tBranch,\n\tBranchCreateRequest,\n\tBranchCreateRequestEndpointOptions,\n\tBranchUpdateRequest,\n\tDataApiCreateRequest,\n\tDataApiReponse,\n\tDatabase,\n\tDefaultEndpointSettings,\n\tEndpoint,\n\tEndpointUpdateRequest,\n\tPgVersion,\n\tProject,\n\tProjectCreateRequest,\n\tProjectListItem,\n\tProjectUpdateRequest,\n\tRole,\n} from \"@neon/sdk\";\nimport { createNeonClient } from \"@neon/sdk\";\nimport {\n\tcreateProject as rawCreateProject,\n\tcreateProjectBranch as rawCreateProjectBranch,\n\tcreateProjectBranchDataApi as rawCreateProjectBranchDataApi,\n\tdeleteProjectBranchDataApi as rawDeleteProjectBranchDataApi,\n\tdisableProjectBranchRealtime as rawDisableProjectBranchRealtime,\n\tenableProjectBranchRealtime as rawEnableProjectBranchRealtime,\n\tgetConnectionUri as rawGetConnectionUri,\n\tgetNeonAuth as rawGetNeonAuth,\n\tgetProject as rawGetProject,\n\tgetProjectBranchDataApi as rawGetProjectBranchDataApi,\n\tgetProjectBranchRealtime as rawGetProjectBranchRealtime,\n\tgetProjectBranchRealtimeSecret as rawGetProjectBranchRealtimeSecret,\n\tlistProjectBranchDatabases as rawListProjectBranchDatabases,\n\tlistProjectBranches as rawListProjectBranches,\n\tlistProjectBranchRoles as rawListProjectBranchRoles,\n\tlistProjectEndpoints as rawListProjectEndpoints,\n\tlistProjects as rawListProjects,\n\tupdateProject as rawUpdateProject,\n\tupdateProjectBranch as rawUpdateProjectBranch,\n\tupdateProjectBranchDataApi as rawUpdateProjectBranchDataApi,\n\tupdateProjectEndpoint as rawUpdateProjectEndpoint,\n} from \"@neon/sdk/raw\";\nimport { z } from \"zod\";\nimport { formatSuspendTimeout, parseSuspendTimeout } from \"./duration.js\";\nimport { ErrorCode, PlatformError } from \"./errors.js\";\nimport type {\n\tConfigureRealtimeInput,\n\tCreateBranchInput,\n\tCreateBucketInput,\n\tCreateCredentialInput,\n\tCreateProjectInput,\n\tCreateTriggerInput,\n\tDeployFunctionInput,\n\tEnableDataApiInput,\n\tGetConnectionUriInput,\n\tNeonApi,\n\tNeonAuthSnapshot,\n\tNeonBranchSnapshot,\n\tNeonBranchStorageSnapshot,\n\tNeonBucketSnapshot,\n\tNeonCredentialMeta,\n\tNeonCredentialReveal,\n\tNeonCredentialSecret,\n\tNeonCustomDomainSnapshot,\n\tNeonDataApiSnapshot,\n\tNeonDatabaseSnapshot,\n\tNeonEndpointSnapshot,\n\tNeonFunctionDeploymentSnapshot,\n\tNeonFunctionSnapshot,\n\tNeonProjectSnapshot,\n\tNeonRealtimeSecret,\n\tNeonRealtimeSnapshot,\n\tNeonRoleSnapshot,\n\tNeonTriggerSnapshot,\n\tUpdateBranchInput,\n\tUpdateTriggerInput,\n} from \"./neon-api.js\";\nimport type {\n\tBucketAccessLevel,\n\tComputeSettings,\n\tDataApiSettings,\n} from \"./types.js\";\nimport { wrapNeonError } from \"./wrap-neon-error.js\";\n\ntype ApiClient = ReturnType<typeof createNeonClient>[\"client\"];\nconst DEFAULT_NEON_API_BASE_URL = \"https://console.neon.tech/api/v2\";\n\n/**\n * Unwrap a `@neon/sdk` raw `{ data, error, response }` result into the bare body, throwing\n * on a non-2xx response. The thrown shape (`{ response: { status, data } }`) deliberately\n * matches what the package's REST fallbacks already throw, so {@link wrapNeonError} and the\n * 423 {@link retryOnLocked} retry keep working unchanged across both transports.\n */\nfunction unwrap<T>(result: {\n\tdata?: T;\n\terror?: unknown;\n\tresponse?: Response;\n}): T {\n\tconst response = result.response;\n\tif (!response?.ok) {\n\t\tthrow {\n\t\t\tresponse: {\n\t\t\t\tstatus: response?.status,\n\t\t\t\tdata: result.error,\n\t\t\t},\n\t\t};\n\t}\n\treturn result.data as T;\n}\n\nconst neonAuthResponseSchema = z.object({\n\tauth_provider_project_id: z.string(),\n\tpub_client_key: z.string().optional(),\n\tsecret_server_key: z.string().optional(),\n\tjwks_url: z.string(),\n\tbase_url: z.string().optional(),\n});\n\n// ─── Data API mapping (camelCase neon.ts ↔ snake_case Neon API) ───────────────\n\n/** Map our camelCase {@link DataApiSettings} onto the Neon API's snake_case `DataAPISettings`. */\nfunction dataApiSettingsToApi(settings: DataApiSettings): ApiDataApiSettings {\n\tconst out: ApiDataApiSettings = {};\n\tif (settings.dbAggregatesEnabled !== undefined)\n\t\tout.db_aggregates_enabled = settings.dbAggregatesEnabled;\n\tif (settings.dbAnonRole !== undefined)\n\t\tout.db_anon_role = settings.dbAnonRole;\n\tif (settings.dbExtraSearchPath !== undefined)\n\t\tout.db_extra_search_path = settings.dbExtraSearchPath;\n\tif (settings.dbMaxRows !== undefined) out.db_max_rows = settings.dbMaxRows;\n\tif (settings.dbSchemas !== undefined) out.db_schemas = settings.dbSchemas;\n\tif (settings.jwtRoleClaimKey !== undefined)\n\t\tout.jwt_role_claim_key = settings.jwtRoleClaimKey;\n\tif (settings.jwtCacheMaxLifetime !== undefined)\n\t\tout.jwt_cache_max_lifetime = settings.jwtCacheMaxLifetime;\n\tif (settings.openapiMode !== undefined)\n\t\tout.openapi_mode = settings.openapiMode;\n\tif (settings.serverCorsAllowedOrigins !== undefined)\n\t\tout.server_cors_allowed_origins = settings.serverCorsAllowedOrigins;\n\tif (settings.serverTimingEnabled !== undefined)\n\t\tout.server_timing_enabled = settings.serverTimingEnabled;\n\treturn out;\n}\n\n/** Narrow the API's free-form `openapi_mode` string to our literal union (else drop it). */\nfunction normalizeOpenapiMode(\n\tvalue: string,\n): DataApiSettings[\"openapiMode\"] | undefined {\n\treturn value === \"ignore-privileges\" || value === \"disabled\"\n\t\t? value\n\t\t: undefined;\n}\n\n/** Map the Neon API's snake_case `DataAPISettings` back to our camelCase {@link DataApiSettings}. */\nfunction dataApiSettingsFromApi(\n\tsettings: ApiDataApiSettings | null | undefined,\n): DataApiSettings | undefined {\n\tif (!settings) return undefined;\n\tconst out: DataApiSettings = {};\n\tif (settings.db_aggregates_enabled !== undefined)\n\t\tout.dbAggregatesEnabled = settings.db_aggregates_enabled;\n\tif (settings.db_anon_role !== undefined)\n\t\tout.dbAnonRole = settings.db_anon_role;\n\tif (settings.db_extra_search_path !== undefined)\n\t\tout.dbExtraSearchPath = settings.db_extra_search_path;\n\tif (settings.db_max_rows !== undefined)\n\t\tout.dbMaxRows = settings.db_max_rows;\n\tif (settings.db_schemas !== undefined) out.dbSchemas = settings.db_schemas;\n\tif (settings.jwt_role_claim_key !== undefined)\n\t\tout.jwtRoleClaimKey = settings.jwt_role_claim_key;\n\tif (settings.jwt_cache_max_lifetime !== undefined)\n\t\tout.jwtCacheMaxLifetime = settings.jwt_cache_max_lifetime;\n\tif (settings.openapi_mode !== undefined) {\n\t\tconst mode = normalizeOpenapiMode(settings.openapi_mode);\n\t\tif (mode !== undefined) out.openapiMode = mode;\n\t}\n\tif (settings.server_cors_allowed_origins !== undefined)\n\t\tout.serverCorsAllowedOrigins = settings.server_cors_allowed_origins;\n\tif (settings.server_timing_enabled !== undefined)\n\t\tout.serverTimingEnabled = settings.server_timing_enabled;\n\treturn Object.keys(out).length > 0 ? out : undefined;\n}\n\n/** Build the Neon API `DataAPICreateRequest` from our {@link EnableDataApiInput}. */\nfunction dataApiCreateRequest(\n\tinput: EnableDataApiInput | undefined,\n): DataApiCreateRequest {\n\tconst req: DataApiCreateRequest = {};\n\tif (!input) return req;\n\tif (input.authProvider !== undefined)\n\t\treq.auth_provider =\n\t\t\tinput.authProvider === \"neon\" ? \"neon_auth\" : \"external\";\n\tif (input.jwksUrl !== undefined) req.jwks_url = input.jwksUrl;\n\tif (input.providerName !== undefined)\n\t\treq.provider_name = input.providerName;\n\tif (input.jwtAudience !== undefined) req.jwt_audience = input.jwtAudience;\n\tif (input.settings) {\n\t\tconst settings = dataApiSettingsToApi(input.settings);\n\t\tif (Object.keys(settings).length > 0) req.settings = settings;\n\t}\n\treturn req;\n}\n\n/** Map a `DataAPIReponse` (GET) onto our {@link NeonDataApiSnapshot}. */\nfunction dataApiSnapshotFromResponse(\n\tdata: DataApiReponse,\n): NeonDataApiSnapshot {\n\tconst snapshot: NeonDataApiSnapshot = { url: data.url };\n\tif (data.status !== undefined) snapshot.status = data.status;\n\tconst settings = dataApiSettingsFromApi(data.settings);\n\tif (settings) snapshot.settings = settings;\n\treturn snapshot;\n}\n\nfunction realtimeOptionsToApi(\n\tinput: ConfigureRealtimeInput | undefined,\n): ApiRealtimeOptions {\n\treturn input?.allowedOrigins === undefined\n\t\t? {}\n\t\t: { allowed_origins: [...input.allowedOrigins] };\n}\n\nfunction realtimeSnapshotFromApi(data: ApiRealtime): NeonRealtimeSnapshot {\n\treturn {\n\t\tenabled: data.enabled,\n\t\tpending: data.pending,\n\t\t...(data.invocation_url !== undefined\n\t\t\t? { invocationUrl: data.invocation_url }\n\t\t\t: {}),\n\t\t...(data.revision !== undefined ? { revision: data.revision } : {}),\n\t\t...(data.allowed_origins !== undefined\n\t\t\t? { allowedOrigins: [...data.allowed_origins] }\n\t\t\t: {}),\n\t};\n}\n\nfunction realtimeSecretFromApi(data: ApiRealtimeSecret): NeonRealtimeSecret {\n\treturn { secret: data.secret, pending: data.pending };\n}\n\n// ─── Preview: buckets ──────────────────────────────────────────────────────\n\nconst bucketSchema = z.object({\n\tname: z.string(),\n\taccess_level: z.string().optional(),\n});\nconst bucketResponseSchema = z.object({ bucket: bucketSchema });\nconst bucketsListResponseSchema = z.object({ buckets: z.array(bucketSchema) });\nconst branchStorageSchema = z.object({\n\tenabled: z.boolean().optional(),\n\ts3_endpoint: z.string(),\n\tregion: z.string(),\n\tforce_path_style: z.boolean(),\n});\n\n// ─── Preview: functions ────────────────────────────────────────────────────\n\nconst functionDeploymentSchema = z.object({\n\tid: z.number(),\n\tstatus: z.string(),\n});\nconst neonFunctionSchema = z.object({\n\tid: z.string(),\n\tslug: z.string(),\n\tname: z.string(),\n\tinvocation_url: z.string(),\n\tcurrent_deployment: functionDeploymentSchema.optional(),\n\tactive_deployment: functionDeploymentSchema.optional(),\n});\nconst functionsListResponseSchema = z.object({\n\tfunctions: z.array(neonFunctionSchema),\n});\nconst functionGetResponseSchema = z.object({\n\tfunction: neonFunctionSchema,\n});\nconst functionDeploymentResponseSchema = z.object({\n\tdeployment: functionDeploymentSchema,\n});\n\nconst scheduleTriggerSchema = z.object({\n\ttype: z.literal(\"schedule\"),\n\ttrigger_id: z.string(),\n\tfunction_slug: z.string(),\n\tname: z.string(),\n\tfunction_path: z.string(),\n\tschedule: z.object({ cron: z.string() }),\n\tenabled: z.boolean(),\n\tinherited: z.boolean(),\n\tnext_run_at: z.string().nullable(),\n});\nconst storageObjectCreatedTriggerSchema = z.object({\n\ttype: z.literal(\"storage_object_created\"),\n\ttrigger_id: z.string(),\n\tfunction_slug: z.string(),\n\tname: z.string(),\n\tfunction_path: z.string(),\n\tstorage_object_created: z.object({\n\t\tbucket_name: z.string(),\n\t\tprefix: z.string().optional(),\n\t}),\n\tenabled: z.boolean(),\n\tinherited: z.boolean(),\n});\nconst triggerApiSchema = z.discriminatedUnion(\"type\", [\n\tscheduleTriggerSchema,\n\tstorageObjectCreatedTriggerSchema,\n]);\nconst triggerResponseSchema = z.object({ trigger: triggerApiSchema });\nconst triggersListResponseSchema = z.object({\n\ttriggers: z.array(triggerApiSchema),\n});\n\nconst customDomainApiSchema = z.object({\n\tdomain: z.string(),\n\tentity_type: z.string(),\n\tentity_id: z.string(),\n\tcname_target: z.string(),\n});\nconst customDomainsListResponseSchema = z.object({\n\tcustom_domains: z.array(customDomainApiSchema),\n\tpagination: z.object({ next: z.string().optional() }).optional(),\n});\nconst CUSTOM_DOMAINS_LIST_LIMIT = 100;\n\n// ─── Preview: branch-scoped credentials ─────────────────────────────────────\n\nconst credentialScopeSchema = z.enum([\n\t\"storage:read\",\n\t\"storage:write\",\n\t\"ai_gateway:invoke\",\n\t\"functions:invoke\",\n]);\nconst createCredentialResponseSchema = z.object({\n\ttoken_id: z.string(),\n\ttoken_id_short: z.string(),\n\tname: z.string().optional(),\n\tapi_token: z.string(),\n\ts3_secret_access_key: z.string(),\n\tscopes: z.array(credentialScopeSchema),\n\tbranch_id: z.string(),\n\tcreated_at: z.string(),\n\texpires_at: z.string().optional(),\n});\nconst credentialMetaSchema = z.object({\n\ttoken_id: z.string(),\n\ttoken_id_short: z.string(),\n\tname: z.string().optional(),\n\tscopes: z.array(credentialScopeSchema),\n\tprincipal_type: z.enum([\"user\", \"function\"]),\n\tfunction_id: z.string().optional(),\n\tbranch_id: z.string().optional(),\n\tcreated_at: z.string(),\n\tlast_used_at: z.string().optional(),\n\trevoked_at: z.string().optional(),\n\texpires_at: z.string().optional(),\n});\nconst listCredentialsResponseSchema = z.object({\n\tcredentials: z.array(credentialMetaSchema),\n});\nconst revealCredentialResponseSchema = z.object({\n\ttoken_id: z.string(),\n\tapi_token: z.string(),\n\ts3_secret_access_key: z.string(),\n});\n\ninterface CreateNeonAuthRestInput {\n\tauth_provider: \"better_auth\";\n\tdatabase_name?: string;\n}\n\ninterface RestConfig {\n\tapiKey: string;\n\tbaseUrl: string;\n}\n\n/**\n * Adapt `@neon/sdk` (raw layer) to the narrow {@link NeonApi} façade used by the rest of\n * this package. Constructs are restricted to whole-object read/write of just the fields we\n * model in {@link Config}; anything else stays untouched on the remote.\n */\nexport function createRealNeonApi(options: {\n\tapiKey: string;\n\tbaseUrl?: string;\n\t/**\n\t * Tuning knob for the built-in 423 retry. Defaults: ~30s of total wait spread across\n\t * 12 attempts with exponential backoff capped at 5s. Lowering this is mostly useful in\n\t * tests; raising it is rarely needed because Neon operations are usually sub-second.\n\t */\n\tretryOnLocked?: {\n\t\tmaxAttempts?: number;\n\t\tinitialDelayMs?: number;\n\t\tmaxDelayMs?: number;\n\t};\n}): NeonApi {\n\tif (!options.apiKey || options.apiKey.trim() === \"\") {\n\t\tthrow new PlatformError(\n\t\t\tErrorCode.MissingApiKey,\n\t\t\t[\n\t\t\t\t\"createRealNeonApi requires a non-empty `apiKey`.\",\n\t\t\t\t\"Generate one at https://console.neon.tech/app/settings/api-keys and pass it as { apiKey: process.env.NEON_API_KEY }.\",\n\t\t\t].join(\" \"),\n\t\t);\n\t}\n\n\t// The SDK runs its own retries by default; this adapter does its own 423-aware\n\t// `retryOnLocked`, so disable the SDK's to avoid compounding backoff.\n\tconst client = createNeonClient({\n\t\tapiKey: options.apiKey,\n\t\tretries: 0,\n\t\t...(options.baseUrl ? { baseUrl: options.baseUrl } : {}),\n\t}).client;\n\n\treturn new RealNeonApi(\n\t\tclient,\n\t\t{\n\t\t\tmaxAttempts: options.retryOnLocked?.maxAttempts ?? 12,\n\t\t\tinitialDelayMs: options.retryOnLocked?.initialDelayMs ?? 250,\n\t\t\tmaxDelayMs: options.retryOnLocked?.maxDelayMs ?? 5_000,\n\t\t},\n\t\t{\n\t\t\tapiKey: options.apiKey,\n\t\t\tbaseUrl: options.baseUrl ?? DEFAULT_NEON_API_BASE_URL,\n\t\t},\n\t);\n}\n\ninterface RetryConfig {\n\tmaxAttempts: number;\n\tinitialDelayMs: number;\n\tmaxDelayMs: number;\n}\n\n/**\n * Retry a function whenever it throws an HTTP 423 (Locked) — Neon's signal that a prior\n * mutation on the same resource is still in flight. Uses exponential backoff capped at\n * `maxDelayMs`. Any other error (and the last attempt) propagates.\n *\n * Exported only for tests; production callers go through the wrapped {@link NeonApi}.\n */\nexport async function retryOnLocked<T>(\n\tfn: () => Promise<T>,\n\tconfig: RetryConfig,\n): Promise<T> {\n\tlet delay = config.initialDelayMs;\n\tlet lastError: unknown;\n\tfor (let attempt = 1; attempt <= config.maxAttempts; attempt++) {\n\t\ttry {\n\t\t\treturn await fn();\n\t\t} catch (err) {\n\t\t\tlastError = err;\n\t\t\tconst status = readHttpStatusFromError(err);\n\t\t\tif (status !== 423 || attempt === config.maxAttempts) throw err;\n\t\t\tawait sleep(delay);\n\t\t\tdelay = Math.min(delay * 2, config.maxDelayMs);\n\t\t}\n\t}\n\tthrow lastError;\n}\n\nfunction readHttpStatusFromError(err: unknown): number | undefined {\n\tif (err === null || typeof err !== \"object\") return undefined;\n\tconst response = (err as { response?: unknown }).response;\n\tif (response === null || typeof response !== \"object\") return undefined;\n\tconst status = (response as { status?: unknown }).status;\n\treturn typeof status === \"number\" ? status : undefined;\n}\n\nfunction sleep(ms: number): Promise<void> {\n\treturn new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nexport async function collectCursorPages<T>(\n\tfetchPage: (\n\t\tcursor: string | undefined,\n\t) => Promise<{ items: T[]; next?: string }>,\n): Promise<T[]> {\n\tconst items: T[] = [];\n\tlet cursor: string | undefined;\n\tfor (;;) {\n\t\tconst page = await fetchPage(cursor);\n\t\titems.push(...page.items);\n\t\tif (!page.next || page.next === cursor) break;\n\t\tcursor = page.next;\n\t}\n\treturn items;\n}\n\nclass RealNeonApi implements NeonApi {\n\tconstructor(\n\t\tprivate readonly client: ApiClient,\n\t\tprivate readonly retryConfig: RetryConfig,\n\t\tprivate readonly restConfig: RestConfig,\n\t) {}\n\n\tprivate retry<T>(fn: () => Promise<T>): Promise<T> {\n\t\treturn retryOnLocked(fn, this.retryConfig);\n\t}\n\n\tprivate async call<T>(\n\t\top: string,\n\t\tfn: () => Promise<T>,\n\t\toptions: { projectId?: string; mutating?: boolean } = {},\n\t): Promise<T> {\n\t\ttry {\n\t\t\treturn options.mutating ? await this.retry(fn) : await fn();\n\t\t} catch (err) {\n\t\t\tconst wrapped = wrapNeonError(\n\t\t\t\terr,\n\t\t\t\toptions.projectId\n\t\t\t\t\t? { op, projectId: options.projectId }\n\t\t\t\t\t: { op },\n\t\t\t);\n\t\t\tthrow wrapped;\n\t\t}\n\t}\n\n\tasync listProjects(filter: {\n\t\torgId?: string;\n\t}): Promise<NeonProjectSnapshot[]> {\n\t\treturn this.call(\n\t\t\tfilter.orgId ? `listProjects(org=${filter.orgId})` : \"listProjects\",\n\t\t\tasync () => {\n\t\t\t\tconst projects: ProjectListItem[] = [];\n\t\t\t\tlet cursor: string | undefined;\n\t\t\t\twhile (true) {\n\t\t\t\t\tconst body = unwrap(\n\t\t\t\t\t\tawait rawListProjects({\n\t\t\t\t\t\t\tclient: this.client,\n\t\t\t\t\t\t\tquery: {\n\t\t\t\t\t\t\t\t...(filter.orgId\n\t\t\t\t\t\t\t\t\t? { org_id: filter.orgId }\n\t\t\t\t\t\t\t\t\t: {}),\n\t\t\t\t\t\t\t\t...(cursor ? { cursor } : {}),\n\t\t\t\t\t\t\t\tlimit: 100,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t}),\n\t\t\t\t\t);\n\t\t\t\t\tprojects.push(...body.projects);\n\t\t\t\t\tconst next = (body as { pagination?: { next?: string } })\n\t\t\t\t\t\t.pagination?.next;\n\t\t\t\t\tif (!next || next === cursor) break;\n\t\t\t\t\tcursor = next;\n\t\t\t\t}\n\t\t\t\treturn projects.map(projectToSnapshot);\n\t\t\t},\n\t\t);\n\t}\n\n\tasync getProject(projectId: string): Promise<NeonProjectSnapshot> {\n\t\treturn this.call(\n\t\t\t`getProject(${projectId})`,\n\t\t\tasync () => {\n\t\t\t\tconst body = unwrap(\n\t\t\t\t\tawait rawGetProject({\n\t\t\t\t\t\tclient: this.client,\n\t\t\t\t\t\tpath: { project_id: projectId },\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t\treturn projectToSnapshot(body.project);\n\t\t\t},\n\t\t\t{ projectId },\n\t\t);\n\t}\n\n\tasync createProject(\n\t\tinput: CreateProjectInput,\n\t): Promise<NeonProjectSnapshot> {\n\t\tconst body: ProjectCreateRequest = {\n\t\t\tproject: {\n\t\t\t\tname: input.name,\n\t\t\t\tregion_id: input.regionId,\n\t\t\t\t...(input.pgVersion !== undefined\n\t\t\t\t\t? { pg_version: input.pgVersion as PgVersion }\n\t\t\t\t\t: {}),\n\t\t\t\t...(input.orgId ? { org_id: input.orgId } : {}),\n\t\t\t\t...(input.defaultEndpointSettings\n\t\t\t\t\t? {\n\t\t\t\t\t\t\tdefault_endpoint_settings:\n\t\t\t\t\t\t\t\tcomputeSettingsToDefaults(\n\t\t\t\t\t\t\t\t\tinput.defaultEndpointSettings,\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t}\n\t\t\t\t\t: {}),\n\t\t\t\t...(input.defaultBranchName\n\t\t\t\t\t? { branch: { name: input.defaultBranchName } }\n\t\t\t\t\t: {}),\n\t\t\t},\n\t\t};\n\t\treturn this.call(\n\t\t\t`createProject(${input.name})`,\n\t\t\tasync () => {\n\t\t\t\tconst data = unwrap(\n\t\t\t\t\tawait rawCreateProject({ client: this.client, body }),\n\t\t\t\t);\n\t\t\t\treturn projectToSnapshot(data.project);\n\t\t\t},\n\t\t\t{ mutating: true },\n\t\t);\n\t}\n\n\tasync updateProject(\n\t\tprojectId: string,\n\t\tinput: { name?: string; defaultEndpointSettings?: ComputeSettings },\n\t): Promise<NeonProjectSnapshot> {\n\t\tconst body: ProjectUpdateRequest = {\n\t\t\tproject: {\n\t\t\t\t...(input.name !== undefined ? { name: input.name } : {}),\n\t\t\t\t...(input.defaultEndpointSettings\n\t\t\t\t\t? {\n\t\t\t\t\t\t\tdefault_endpoint_settings:\n\t\t\t\t\t\t\t\tcomputeSettingsToDefaults(\n\t\t\t\t\t\t\t\t\tinput.defaultEndpointSettings,\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t}\n\t\t\t\t\t: {}),\n\t\t\t},\n\t\t};\n\t\treturn this.call(\n\t\t\t`updateProject(${projectId})`,\n\t\t\tasync () => {\n\t\t\t\tconst data = unwrap(\n\t\t\t\t\tawait rawUpdateProject({\n\t\t\t\t\t\tclient: this.client,\n\t\t\t\t\t\tpath: { project_id: projectId },\n\t\t\t\t\t\tbody,\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t\treturn projectToSnapshot(data.project);\n\t\t\t},\n\t\t\t{ projectId, mutating: true },\n\t\t);\n\t}\n\n\tasync listBranches(projectId: string): Promise<NeonBranchSnapshot[]> {\n\t\treturn this.call(\n\t\t\t`listBranches(${projectId})`,\n\t\t\tasync () => {\n\t\t\t\tconst branches: Branch[] = [];\n\t\t\t\tlet cursor: string | undefined;\n\t\t\t\twhile (true) {\n\t\t\t\t\tconst body = unwrap(\n\t\t\t\t\t\tawait rawListProjectBranches({\n\t\t\t\t\t\t\tclient: this.client,\n\t\t\t\t\t\t\tpath: { project_id: projectId },\n\t\t\t\t\t\t\tquery: {\n\t\t\t\t\t\t\t\tlimit: 100,\n\t\t\t\t\t\t\t\t...(cursor ? { cursor } : {}),\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t}),\n\t\t\t\t\t);\n\t\t\t\t\tbranches.push(...(body.branches as Branch[]));\n\t\t\t\t\tconst next = (body as { pagination?: { next?: string } })\n\t\t\t\t\t\t.pagination?.next;\n\t\t\t\t\tif (!next || next === cursor) break;\n\t\t\t\t\tcursor = next;\n\t\t\t\t}\n\t\t\t\treturn branches.map(branchToSnapshot);\n\t\t\t},\n\t\t\t{ projectId },\n\t\t);\n\t}\n\n\tasync createBranch(\n\t\tprojectId: string,\n\t\tinput: CreateBranchInput,\n\t): Promise<{\n\t\tbranch: NeonBranchSnapshot;\n\t\tendpoints: NeonEndpointSnapshot[];\n\t}> {\n\t\tconst endpointOptions: BranchCreateRequestEndpointOptions | undefined =\n\t\t\tinput.computeSettings\n\t\t\t\t? {\n\t\t\t\t\t\ttype: \"read_write\",\n\t\t\t\t\t\t...computeSettingsToEndpointOptions(\n\t\t\t\t\t\t\tinput.computeSettings,\n\t\t\t\t\t\t),\n\t\t\t\t\t}\n\t\t\t\t: { type: \"read_write\" };\n\n\t\tconst body: BranchCreateRequest = {\n\t\t\tbranch: {\n\t\t\t\tname: input.name,\n\t\t\t\t...(input.parentId ? { parent_id: input.parentId } : {}),\n\t\t\t\t...(input.expiresAt ? { expires_at: input.expiresAt } : {}),\n\t\t\t\t...(input.protected !== undefined\n\t\t\t\t\t? { protected: input.protected }\n\t\t\t\t\t: {}),\n\t\t\t},\n\t\t\tendpoints: [endpointOptions],\n\t\t};\n\t\treturn this.call(\n\t\t\t`createBranch(${projectId}/${input.name})`,\n\t\t\tasync () => {\n\t\t\t\tconst data = unwrap(\n\t\t\t\t\tawait rawCreateProjectBranch({\n\t\t\t\t\t\tclient: this.client,\n\t\t\t\t\t\tpath: { project_id: projectId },\n\t\t\t\t\t\tbody,\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t\treturn {\n\t\t\t\t\tbranch: branchToSnapshot(data.branch),\n\t\t\t\t\tendpoints: (data.endpoints ?? []).map(endpointToSnapshot),\n\t\t\t\t};\n\t\t\t},\n\t\t\t{ projectId, mutating: true },\n\t\t);\n\t}\n\n\tasync updateBranch(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t\tinput: UpdateBranchInput,\n\t): Promise<NeonBranchSnapshot> {\n\t\tconst branch: BranchUpdateRequest[\"branch\"] = {};\n\t\tif (input.name !== undefined) branch.name = input.name;\n\t\tif (input.expiresAt !== undefined) branch.expires_at = input.expiresAt;\n\t\tif (input.protected !== undefined) branch.protected = input.protected;\n\t\treturn this.call(\n\t\t\t`updateBranch(${projectId}/${branchId})`,\n\t\t\tasync () => {\n\t\t\t\tconst data = unwrap(\n\t\t\t\t\tawait rawUpdateProjectBranch({\n\t\t\t\t\t\tclient: this.client,\n\t\t\t\t\t\tpath: { project_id: projectId, branch_id: branchId },\n\t\t\t\t\t\tbody: { branch },\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t\treturn branchToSnapshot(data.branch);\n\t\t\t},\n\t\t\t{ projectId, mutating: true },\n\t\t);\n\t}\n\n\tasync listEndpoints(projectId: string): Promise<NeonEndpointSnapshot[]> {\n\t\treturn this.call(\n\t\t\t`listEndpoints(${projectId})`,\n\t\t\tasync () => {\n\t\t\t\tconst data = unwrap(\n\t\t\t\t\tawait rawListProjectEndpoints({\n\t\t\t\t\t\tclient: this.client,\n\t\t\t\t\t\tpath: { project_id: projectId },\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t\treturn (data.endpoints as Endpoint[]).map(endpointToSnapshot);\n\t\t\t},\n\t\t\t{ projectId },\n\t\t);\n\t}\n\n\tasync updateEndpoint(\n\t\tprojectId: string,\n\t\tendpointId: string,\n\t\tsettings: ComputeSettings,\n\t): Promise<NeonEndpointSnapshot> {\n\t\tconst endpoint: EndpointUpdateRequest[\"endpoint\"] =\n\t\t\tcomputeSettingsToEndpointOptions(settings);\n\t\treturn this.call(\n\t\t\t`updateEndpoint(${projectId}/${endpointId})`,\n\t\t\tasync () => {\n\t\t\t\tconst data = unwrap(\n\t\t\t\t\tawait rawUpdateProjectEndpoint({\n\t\t\t\t\t\tclient: this.client,\n\t\t\t\t\t\tpath: {\n\t\t\t\t\t\t\tproject_id: projectId,\n\t\t\t\t\t\t\tendpoint_id: endpointId,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tbody: { endpoint },\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t\treturn endpointToSnapshot(data.endpoint);\n\t\t\t},\n\t\t\t{ projectId, mutating: true },\n\t\t);\n\t}\n\n\tasync listBranchRoles(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t): Promise<NeonRoleSnapshot[]> {\n\t\treturn this.call(\n\t\t\t`listBranchRoles(${projectId}/${branchId})`,\n\t\t\tasync () => {\n\t\t\t\tconst data = unwrap(\n\t\t\t\t\tawait rawListProjectBranchRoles({\n\t\t\t\t\t\tclient: this.client,\n\t\t\t\t\t\tpath: { project_id: projectId, branch_id: branchId },\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t\treturn (data.roles as Role[]).map(roleToSnapshot);\n\t\t\t},\n\t\t\t{ projectId },\n\t\t);\n\t}\n\n\tasync listBranchDatabases(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t): Promise<NeonDatabaseSnapshot[]> {\n\t\treturn this.call(\n\t\t\t`listBranchDatabases(${projectId}/${branchId})`,\n\t\t\tasync () => {\n\t\t\t\tconst data = unwrap(\n\t\t\t\t\tawait rawListProjectBranchDatabases({\n\t\t\t\t\t\tclient: this.client,\n\t\t\t\t\t\tpath: { project_id: projectId, branch_id: branchId },\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t\treturn (data.databases as Database[]).map(databaseToSnapshot);\n\t\t\t},\n\t\t\t{ projectId },\n\t\t);\n\t}\n\n\tasync getConnectionUri(\n\t\tprojectId: string,\n\t\tinput: GetConnectionUriInput,\n\t): Promise<{ uri: string }> {\n\t\tconst op = `getConnectionUri(${projectId}/${input.databaseName}@${input.roleName}${input.pooled ? \" pooled\" : \"\"})`;\n\t\t// Always send `pooled` explicitly. The Neon API has switched its default\n\t\t// to returning the pooled URI when the parameter is omitted, so we have\n\t\t// to be explicit to get the direct URI back.\n\t\tconst pooled = input.pooled === true;\n\t\treturn this.call(\n\t\t\top,\n\t\t\tasync () => {\n\t\t\t\tconst data = unwrap(\n\t\t\t\t\tawait rawGetConnectionUri({\n\t\t\t\t\t\tclient: this.client,\n\t\t\t\t\t\tpath: { project_id: projectId },\n\t\t\t\t\t\tquery: {\n\t\t\t\t\t\t\tdatabase_name: input.databaseName,\n\t\t\t\t\t\t\trole_name: input.roleName,\n\t\t\t\t\t\t\t...(input.branchId\n\t\t\t\t\t\t\t\t? { branch_id: input.branchId }\n\t\t\t\t\t\t\t\t: {}),\n\t\t\t\t\t\t\t...(input.endpointId\n\t\t\t\t\t\t\t\t? { endpoint_id: input.endpointId }\n\t\t\t\t\t\t\t\t: {}),\n\t\t\t\t\t\t\tpooled,\n\t\t\t\t\t\t},\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t\treturn { uri: data.uri };\n\t\t\t},\n\t\t\t{ projectId },\n\t\t);\n\t}\n\n\tasync getNeonAuth(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t): Promise<NeonAuthSnapshot | null> {\n\t\t// `GET /projects/:pid/branches/:bid/auth` returns 404 when no integration exists.\n\t\t// Surface that as `null` so callers can branch cleanly instead of try/catch.\n\t\ttry {\n\t\t\treturn await this.call(\n\t\t\t\t`getNeonAuth(${projectId}/${branchId})`,\n\t\t\t\tasync () => {\n\t\t\t\t\tconst data = unwrap(\n\t\t\t\t\t\tawait rawGetNeonAuth({\n\t\t\t\t\t\t\tclient: this.client,\n\t\t\t\t\t\t\tpath: {\n\t\t\t\t\t\t\t\tproject_id: projectId,\n\t\t\t\t\t\t\t\tbranch_id: branchId,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t}),\n\t\t\t\t\t);\n\t\t\t\t\treturn neonAuthResponseToSnapshot(\n\t\t\t\t\t\tneonAuthResponseSchema.parse(data),\n\t\t\t\t\t);\n\t\t\t\t},\n\t\t\t\t{ projectId },\n\t\t\t);\n\t\t} catch (err) {\n\t\t\tif (err instanceof PlatformError && err.code === ErrorCode.NotFound)\n\t\t\t\treturn null;\n\t\t\tthrow err;\n\t\t}\n\t}\n\n\tasync enableNeonAuth(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t\tinput: { databaseName?: string } = {},\n\t): Promise<NeonAuthSnapshot> {\n\t\t// Idempotent: if an integration already exists on the branch, the POST returns 409\n\t\t// (`Conflict`). We swallow that and re-fetch the existing snapshot so callers can\n\t\t// rely on `enableNeonAuth` to be safe to invoke from any push, including no-ops.\n\t\t// A 409 with no integration to re-fetch is a failed provisioning and is thrown.\n\t\ttry {\n\t\t\treturn await this.call(\n\t\t\t\t`enableNeonAuth(${projectId}/${branchId})`,\n\t\t\t\tasync () => {\n\t\t\t\t\t// The generated `createNeonAuth` doesn't narrow this branch\n\t\t\t\t\t// endpoint to `better_auth`, so post the REST body directly.\n\t\t\t\t\tconst data = await this.postJson(\n\t\t\t\t\t\t`/projects/${encodeURIComponent(projectId)}/branches/${encodeURIComponent(branchId)}/auth`,\n\t\t\t\t\t\tcreateNeonAuthRestInput(input),\n\t\t\t\t\t);\n\t\t\t\t\tconst parsed = neonAuthResponseSchema.parse(data);\n\t\t\t\t\treturn neonAuthResponseToSnapshot(parsed);\n\t\t\t\t},\n\t\t\t\t{ projectId, mutating: true },\n\t\t\t);\n\t\t} catch (err) {\n\t\t\tif (\n\t\t\t\terr instanceof PlatformError &&\n\t\t\t\terr.code === ErrorCode.Conflict\n\t\t\t) {\n\t\t\t\tconst existing = await this.getNeonAuth(projectId, branchId);\n\t\t\t\tif (existing) return existing;\n\t\t\t\tthrow neonAuthProvisioningConflict(err, projectId, branchId);\n\t\t\t}\n\t\t\tthrow err;\n\t\t}\n\t}\n\n\tprivate async postJson(path: string, body: unknown): Promise<unknown> {\n\t\treturn this.request(\"POST\", path, {\n\t\t\theaders: { \"Content-Type\": \"application/json\" },\n\t\t\tbody: JSON.stringify(body),\n\t\t});\n\t}\n\n\tprivate async patchJson(path: string, body: unknown): Promise<unknown> {\n\t\treturn this.request(\"PATCH\", path, {\n\t\t\theaders: { \"Content-Type\": \"application/json\" },\n\t\t\tbody: JSON.stringify(body),\n\t\t});\n\t}\n\n\tprivate async getJson(\n\t\tpath: string,\n\t\tquery?: Record<string, string | number | undefined>,\n\t): Promise<unknown> {\n\t\treturn this.request(\"GET\", withQuery(path, query));\n\t}\n\n\tprivate async deleteJson(path: string): Promise<unknown> {\n\t\treturn this.request(\"DELETE\", path);\n\t}\n\n\t/**\n\t * Upload a built function bundle via `multipart/form-data` to the deploy endpoint\n\t * (`POST .../functions/{slug}/deployments`). Body shape lives in the pure\n\t * {@link buildFunctionDeployForm} helper so it can be unit-tested against the spec.\n\t */\n\tprivate async postMultipart(\n\t\tpath: string,\n\t\tinput: DeployFunctionInput,\n\t): Promise<unknown> {\n\t\treturn this.request(\"POST\", path, {\n\t\t\tbody: buildFunctionDeployForm(input),\n\t\t});\n\t}\n\n\tprivate async request(\n\t\tmethod: \"GET\" | \"POST\" | \"PATCH\" | \"DELETE\",\n\t\tpath: string,\n\t\tinit: { headers?: Record<string, string>; body?: BodyInit } = {},\n\t): Promise<unknown> {\n\t\tconst url = `${this.restConfig.baseUrl.replace(/\\/+$/, \"\")}${path}`;\n\t\tconst res = await fetch(url, {\n\t\t\tmethod,\n\t\t\theaders: {\n\t\t\t\tAuthorization: `Bearer ${this.restConfig.apiKey}`,\n\t\t\t\t...(init.headers ?? {}),\n\t\t\t},\n\t\t\t...(init.body !== undefined ? { body: init.body } : {}),\n\t\t});\n\t\tconst data = await readJsonBody(res);\n\t\tif (!res.ok) {\n\t\t\tthrow {\n\t\t\t\tresponse: {\n\t\t\t\t\tstatus: res.status,\n\t\t\t\t\tdata,\n\t\t\t\t},\n\t\t\t};\n\t\t}\n\t\treturn data;\n\t}\n\n\tasync getNeonDataApi(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t\tdatabaseName: string,\n\t): Promise<NeonDataApiSnapshot | null> {\n\t\t// Same shape as getNeonAuth — 404 means \"no integration on this branch/db\", which\n\t\t// we translate to `null` for the caller.\n\t\ttry {\n\t\t\treturn await this.call(\n\t\t\t\t`getNeonDataApi(${projectId}/${branchId}/${databaseName})`,\n\t\t\t\tasync () =>\n\t\t\t\t\tdataApiSnapshotFromResponse(\n\t\t\t\t\t\tunwrap(\n\t\t\t\t\t\t\tawait rawGetProjectBranchDataApi({\n\t\t\t\t\t\t\t\tclient: this.client,\n\t\t\t\t\t\t\t\tpath: {\n\t\t\t\t\t\t\t\t\tproject_id: projectId,\n\t\t\t\t\t\t\t\t\tbranch_id: branchId,\n\t\t\t\t\t\t\t\t\tdatabase_name: databaseName,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t),\n\t\t\t\t\t),\n\t\t\t\t{ projectId },\n\t\t\t);\n\t\t} catch (err) {\n\t\t\tif (err instanceof PlatformError && err.code === ErrorCode.NotFound)\n\t\t\t\treturn null;\n\t\t\tthrow err;\n\t\t}\n\t}\n\n\tasync enableProjectBranchDataApi(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t\tdatabaseName: string,\n\t\tinput?: EnableDataApiInput,\n\t): Promise<NeonDataApiSnapshot> {\n\t\t// Idempotent in the same shape as `enableNeonAuth`: if an integration already\n\t\t// exists, the POST returns 409 and we re-fetch the existing snapshot.\n\t\ttry {\n\t\t\treturn await this.call(\n\t\t\t\t`enableProjectBranchDataApi(${projectId}/${branchId}/${databaseName})`,\n\t\t\t\tasync () => {\n\t\t\t\t\tconst data = unwrap(\n\t\t\t\t\t\tawait rawCreateProjectBranchDataApi({\n\t\t\t\t\t\t\tclient: this.client,\n\t\t\t\t\t\t\tpath: {\n\t\t\t\t\t\t\t\tproject_id: projectId,\n\t\t\t\t\t\t\t\tbranch_id: branchId,\n\t\t\t\t\t\t\t\tdatabase_name: databaseName,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tbody: dataApiCreateRequest(input),\n\t\t\t\t\t\t}),\n\t\t\t\t\t);\n\t\t\t\t\t// The create response only carries `url`; settings/status come from a\n\t\t\t\t\t// follow-up GET, which we leave to the caller when it needs them.\n\t\t\t\t\treturn { url: data.url };\n\t\t\t\t},\n\t\t\t\t{ projectId, mutating: true },\n\t\t\t);\n\t\t} catch (err) {\n\t\t\tif (\n\t\t\t\terr instanceof PlatformError &&\n\t\t\t\terr.code === ErrorCode.Conflict\n\t\t\t) {\n\t\t\t\tconst existing = await this.getNeonDataApi(\n\t\t\t\t\tprojectId,\n\t\t\t\t\tbranchId,\n\t\t\t\t\tdatabaseName,\n\t\t\t\t);\n\t\t\t\tif (existing) return existing;\n\t\t\t}\n\t\t\tthrow err;\n\t\t}\n\t}\n\n\tasync updateProjectBranchDataApi(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t\tdatabaseName: string,\n\t\tsettings: DataApiSettings,\n\t): Promise<NeonDataApiSnapshot> {\n\t\treturn await this.call(\n\t\t\t`updateProjectBranchDataApi(${projectId}/${branchId}/${databaseName})`,\n\t\t\tasync () => {\n\t\t\t\tunwrap(\n\t\t\t\t\tawait rawUpdateProjectBranchDataApi({\n\t\t\t\t\t\tclient: this.client,\n\t\t\t\t\t\tpath: {\n\t\t\t\t\t\t\tproject_id: projectId,\n\t\t\t\t\t\t\tbranch_id: branchId,\n\t\t\t\t\t\t\tdatabase_name: databaseName,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tbody: { settings: dataApiSettingsToApi(settings) },\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t\t// The PATCH returns an empty body; re-fetch so the caller sees the\n\t\t\t\t// post-update url/status/settings.\n\t\t\t\tconst data = unwrap(\n\t\t\t\t\tawait rawGetProjectBranchDataApi({\n\t\t\t\t\t\tclient: this.client,\n\t\t\t\t\t\tpath: {\n\t\t\t\t\t\t\tproject_id: projectId,\n\t\t\t\t\t\t\tbranch_id: branchId,\n\t\t\t\t\t\t\tdatabase_name: databaseName,\n\t\t\t\t\t\t},\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t\treturn dataApiSnapshotFromResponse(data);\n\t\t\t},\n\t\t\t{ projectId, mutating: true },\n\t\t);\n\t}\n\n\tasync deleteProjectBranchDataApi(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t\tdatabaseName: string,\n\t): Promise<void> {\n\t\ttry {\n\t\t\tawait this.call(\n\t\t\t\t`deleteProjectBranchDataApi(${projectId}/${branchId}/${databaseName})`,\n\t\t\t\tasync () => {\n\t\t\t\t\tunwrap(\n\t\t\t\t\t\tawait rawDeleteProjectBranchDataApi({\n\t\t\t\t\t\t\tclient: this.client,\n\t\t\t\t\t\t\tpath: {\n\t\t\t\t\t\t\t\tproject_id: projectId,\n\t\t\t\t\t\t\t\tbranch_id: branchId,\n\t\t\t\t\t\t\t\tdatabase_name: databaseName,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t}),\n\t\t\t\t\t);\n\t\t\t\t},\n\t\t\t\t{ projectId, mutating: true },\n\t\t\t);\n\t\t} catch (err) {\n\t\t\tif (err instanceof PlatformError && err.code === ErrorCode.NotFound)\n\t\t\t\treturn;\n\t\t\tthrow err;\n\t\t}\n\t}\n\n\t// ─── Realtime ──────────────────────────────────────────────────────────────\n\n\tasync getProjectBranchRealtime(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t): Promise<NeonRealtimeSnapshot> {\n\t\treturn this.call(\n\t\t\t`getProjectBranchRealtime(${projectId}/${branchId})`,\n\t\t\tasync () =>\n\t\t\t\trealtimeSnapshotFromApi(\n\t\t\t\t\tunwrap(\n\t\t\t\t\t\tawait rawGetProjectBranchRealtime({\n\t\t\t\t\t\t\tclient: this.client,\n\t\t\t\t\t\t\tpath: {\n\t\t\t\t\t\t\t\tproject_id: projectId,\n\t\t\t\t\t\t\t\tbranch_id: branchId,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t}),\n\t\t\t\t\t),\n\t\t\t\t),\n\t\t\t{ projectId },\n\t\t);\n\t}\n\n\tasync getProjectBranchRealtimeSecret(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t): Promise<NeonRealtimeSecret> {\n\t\treturn this.call(\n\t\t\t`getProjectBranchRealtimeSecret(${projectId}/${branchId})`,\n\t\t\tasync () =>\n\t\t\t\trealtimeSecretFromApi(\n\t\t\t\t\tunwrap(\n\t\t\t\t\t\tawait rawGetProjectBranchRealtimeSecret({\n\t\t\t\t\t\t\tclient: this.client,\n\t\t\t\t\t\t\tpath: {\n\t\t\t\t\t\t\t\tproject_id: projectId,\n\t\t\t\t\t\t\t\tbranch_id: branchId,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t}),\n\t\t\t\t\t),\n\t\t\t\t),\n\t\t\t{ projectId },\n\t\t);\n\t}\n\n\tasync enableProjectBranchRealtime(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t\tinput?: ConfigureRealtimeInput,\n\t): Promise<void> {\n\t\tawait this.call(\n\t\t\t`enableProjectBranchRealtime(${projectId}/${branchId})`,\n\t\t\tasync () => {\n\t\t\t\tunwrap(\n\t\t\t\t\tawait rawEnableProjectBranchRealtime({\n\t\t\t\t\t\tclient: this.client,\n\t\t\t\t\t\tpath: {\n\t\t\t\t\t\t\tproject_id: projectId,\n\t\t\t\t\t\t\tbranch_id: branchId,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tbody: realtimeOptionsToApi(input),\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t},\n\t\t\t{ projectId, mutating: true },\n\t\t);\n\t}\n\n\tasync disableProjectBranchRealtime(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t): Promise<void> {\n\t\tawait this.call(\n\t\t\t`disableProjectBranchRealtime(${projectId}/${branchId})`,\n\t\t\tasync () => {\n\t\t\t\tunwrap(\n\t\t\t\t\tawait rawDisableProjectBranchRealtime({\n\t\t\t\t\t\tclient: this.client,\n\t\t\t\t\t\tpath: {\n\t\t\t\t\t\t\tproject_id: projectId,\n\t\t\t\t\t\t\tbranch_id: branchId,\n\t\t\t\t\t\t},\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t},\n\t\t\t{ projectId, mutating: true },\n\t\t);\n\t}\n\n\t// ─── Preview: buckets ──────────────────────────────────────────────────────\n\n\tasync listBranchBuckets(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t): Promise<NeonBucketSnapshot[]> {\n\t\ttry {\n\t\t\treturn await this.call(\n\t\t\t\t`listBranchBuckets(${projectId}/${branchId})`,\n\t\t\t\tasync () => {\n\t\t\t\t\tconst data = await this.getJson(\n\t\t\t\t\t\tbranchPreviewPath(projectId, branchId, \"buckets\"),\n\t\t\t\t\t);\n\t\t\t\t\tconst parsed = bucketsListResponseSchema.parse(data);\n\t\t\t\t\treturn parsed.buckets.map(bucketToSnapshot);\n\t\t\t\t},\n\t\t\t\t{ projectId },\n\t\t\t);\n\t\t} catch (err) {\n\t\t\tthrow previewUnavailableError(err, \"Object storage (buckets)\");\n\t\t}\n\t}\n\n\tasync createBranchBucket(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t\tinput: CreateBucketInput,\n\t): Promise<NeonBucketSnapshot> {\n\t\treturn this.call(\n\t\t\t`createBranchBucket(${projectId}/${branchId}/${input.name})`,\n\t\t\tasync () => {\n\t\t\t\tconst data = await this.postJson(\n\t\t\t\t\tbranchPreviewPath(projectId, branchId, \"buckets\"),\n\t\t\t\t\t{\n\t\t\t\t\t\tname: input.name,\n\t\t\t\t\t\t...(input.accessLevel\n\t\t\t\t\t\t\t? { access_level: input.accessLevel }\n\t\t\t\t\t\t\t: {}),\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t\tconst parsed = bucketResponseSchema.parse(data);\n\t\t\t\treturn bucketToSnapshot(parsed.bucket);\n\t\t\t},\n\t\t\t{ projectId, mutating: true },\n\t\t);\n\t}\n\n\tasync deleteBranchBucket(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t\tbucketName: string,\n\t): Promise<void> {\n\t\tawait this.call(\n\t\t\t`deleteBranchBucket(${projectId}/${branchId}/${bucketName})`,\n\t\t\tasync () => {\n\t\t\t\tawait this.deleteJson(\n\t\t\t\t\t`${branchPreviewPath(projectId, branchId, \"buckets\")}/${encodeURIComponent(bucketName)}`,\n\t\t\t\t);\n\t\t\t},\n\t\t\t{ projectId, mutating: true },\n\t\t);\n\t}\n\n\tasync getProjectBranchStorage(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t): Promise<NeonBranchStorageSnapshot | null> {\n\t\ttry {\n\t\t\treturn await this.call(\n\t\t\t\t`getProjectBranchStorage(${projectId}/${branchId})`,\n\t\t\t\tasync () => {\n\t\t\t\t\tconst data = await this.getJson(\n\t\t\t\t\t\t`/projects/${encodeURIComponent(projectId)}/branches/${encodeURIComponent(branchId)}/storage`,\n\t\t\t\t\t);\n\t\t\t\t\tconst parsed = branchStorageSchema.parse(data);\n\t\t\t\t\treturn {\n\t\t\t\t\t\ts3Endpoint: parsed.s3_endpoint,\n\t\t\t\t\t\tregion: parsed.region,\n\t\t\t\t\t\tforcePathStyle: parsed.force_path_style,\n\t\t\t\t\t};\n\t\t\t\t},\n\t\t\t\t{ projectId },\n\t\t\t);\n\t\t} catch (err) {\n\t\t\t// 404 BranchStorageNotEnabled → storage not usable on this branch; let the\n\t\t\t// caller decide (fetchEnv throws a clear \"enable storage first\" error).\n\t\t\tif (err instanceof PlatformError && err.code === ErrorCode.NotFound)\n\t\t\t\treturn null;\n\t\t\tthrow previewUnavailableError(err, \"Object storage\");\n\t\t}\n\t}\n\n\t// ─── Preview: functions ────────────────────────────────────────────────────\n\n\tasync listBranchFunctions(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t): Promise<NeonFunctionSnapshot[]> {\n\t\ttry {\n\t\t\treturn await this.call(\n\t\t\t\t`listBranchFunctions(${projectId}/${branchId})`,\n\t\t\t\tasync () => {\n\t\t\t\t\tconst data = await this.getJson(\n\t\t\t\t\t\tbranchPreviewPath(projectId, branchId, \"functions\"),\n\t\t\t\t\t);\n\t\t\t\t\tconst parsed = functionsListResponseSchema.parse(data);\n\t\t\t\t\treturn parsed.functions.map(functionToSnapshot);\n\t\t\t\t},\n\t\t\t\t{ projectId },\n\t\t\t);\n\t\t} catch (err) {\n\t\t\tthrow previewUnavailableError(err, \"Functions\");\n\t\t}\n\t}\n\n\tasync deleteBranchFunction(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t\tslug: string,\n\t): Promise<void> {\n\t\tawait this.call(\n\t\t\t`deleteBranchFunction(${projectId}/${branchId}/${slug})`,\n\t\t\tasync () => {\n\t\t\t\tawait this.deleteJson(\n\t\t\t\t\t`${branchPreviewPath(projectId, branchId, \"functions\")}/${encodeURIComponent(slug)}`,\n\t\t\t\t);\n\t\t\t},\n\t\t\t{ projectId, mutating: true },\n\t\t);\n\t}\n\n\tasync deployBranchFunction(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t\tslug: string,\n\t\tinput: DeployFunctionInput,\n\t): Promise<NeonFunctionDeploymentSnapshot> {\n\t\treturn this.call(\n\t\t\t`deployBranchFunction(${projectId}/${branchId}/${slug})`,\n\t\t\tasync () => {\n\t\t\t\tconst data = await this.postMultipart(\n\t\t\t\t\t`${branchPreviewPath(projectId, branchId, \"functions\")}/${encodeURIComponent(slug)}/deployments`,\n\t\t\t\t\tinput,\n\t\t\t\t);\n\t\t\t\tconst parsed = functionDeploymentResponseSchema.parse(data);\n\t\t\t\treturn deploymentToSnapshot(parsed.deployment);\n\t\t\t},\n\t\t\t{ projectId, mutating: true },\n\t\t);\n\t}\n\n\tasync getBranchFunction(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t\tslug: string,\n\t): Promise<NeonFunctionSnapshot> {\n\t\treturn this.call(\n\t\t\t`getBranchFunction(${projectId}/${branchId}/${slug})`,\n\t\t\tasync () => {\n\t\t\t\tconst data = await this.getJson(\n\t\t\t\t\t`${branchPreviewPath(projectId, branchId, \"functions\")}/${encodeURIComponent(slug)}`,\n\t\t\t\t);\n\t\t\t\treturn functionToSnapshot(\n\t\t\t\t\tfunctionGetResponseSchema.parse(data).function,\n\t\t\t\t);\n\t\t\t},\n\t\t\t{ projectId },\n\t\t);\n\t}\n\n\tasync listBranchTriggers(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t): Promise<NeonTriggerSnapshot[]> {\n\t\ttry {\n\t\t\treturn await this.call(\n\t\t\t\t`listBranchTriggers(${projectId}/${branchId})`,\n\t\t\t\tasync () => {\n\t\t\t\t\tconst data = await this.getJson(\n\t\t\t\t\t\ttriggersPath(projectId, branchId),\n\t\t\t\t\t);\n\t\t\t\t\tconst parsed = triggersListResponseSchema.parse(data);\n\t\t\t\t\treturn parsed.triggers.map(triggerToSnapshot);\n\t\t\t\t},\n\t\t\t\t{ projectId },\n\t\t\t);\n\t\t} catch (err) {\n\t\t\tthrow previewUnavailableError(err, \"Function triggers\");\n\t\t}\n\t}\n\n\tasync createBranchTrigger(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t\tinput: CreateTriggerInput,\n\t): Promise<NeonTriggerSnapshot> {\n\t\ttry {\n\t\t\treturn await this.call(\n\t\t\t\t`createBranchTrigger(${projectId}/${branchId}/${input.name})`,\n\t\t\t\tasync () => {\n\t\t\t\t\tconst data = await this.postJson(\n\t\t\t\t\t\ttriggersPath(projectId, branchId),\n\t\t\t\t\t\tcreateTriggerRequestBody(input),\n\t\t\t\t\t);\n\t\t\t\t\tconst parsed = triggerResponseSchema.parse(data);\n\t\t\t\t\treturn triggerToSnapshot(parsed.trigger);\n\t\t\t\t},\n\t\t\t\t{ projectId, mutating: true },\n\t\t\t);\n\t\t} catch (err) {\n\t\t\tthrow previewUnavailableError(err, \"Function triggers\");\n\t\t}\n\t}\n\n\tasync updateBranchTrigger(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t\ttriggerId: string,\n\t\tinput: UpdateTriggerInput,\n\t): Promise<NeonTriggerSnapshot> {\n\t\ttry {\n\t\t\treturn await this.call(\n\t\t\t\t`updateBranchTrigger(${projectId}/${branchId}/${triggerId})`,\n\t\t\t\tasync () => {\n\t\t\t\t\tconst data = await this.patchJson(\n\t\t\t\t\t\t`${triggersPath(projectId, branchId)}/${encodeURIComponent(triggerId)}`,\n\t\t\t\t\t\tupdateTriggerRequestBody(input),\n\t\t\t\t\t);\n\t\t\t\t\tconst parsed = triggerResponseSchema.parse(data);\n\t\t\t\t\treturn triggerToSnapshot(parsed.trigger);\n\t\t\t\t},\n\t\t\t\t{ projectId, mutating: true },\n\t\t\t);\n\t\t} catch (err) {\n\t\t\tthrow previewUnavailableError(err, \"Function triggers\");\n\t\t}\n\t}\n\n\tasync deleteBranchTrigger(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t\ttriggerId: string,\n\t): Promise<void> {\n\t\tawait this.call(\n\t\t\t`deleteBranchTrigger(${projectId}/${branchId}/${triggerId})`,\n\t\t\tasync () => {\n\t\t\t\tawait this.deleteJson(\n\t\t\t\t\t`${triggersPath(projectId, branchId)}/${encodeURIComponent(triggerId)}`,\n\t\t\t\t);\n\t\t\t},\n\t\t\t{ projectId, mutating: true },\n\t\t);\n\t}\n\n\tasync listBranchCustomDomains(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t): Promise<NeonCustomDomainSnapshot[]> {\n\t\ttry {\n\t\t\treturn await this.call(\n\t\t\t\t`listBranchCustomDomains(${projectId}/${branchId})`,\n\t\t\t\tasync () =>\n\t\t\t\t\tcollectCursorPages(async (cursor) => {\n\t\t\t\t\t\tconst data = await this.getJson(\n\t\t\t\t\t\t\tcustomDomainsPath(projectId, branchId),\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tlimit: CUSTOM_DOMAINS_LIST_LIMIT,\n\t\t\t\t\t\t\t\t...(cursor ? { cursor } : {}),\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t);\n\t\t\t\t\t\tconst parsed =\n\t\t\t\t\t\t\tcustomDomainsListResponseSchema.parse(data);\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\titems: parsed.custom_domains.map(\n\t\t\t\t\t\t\t\tcustomDomainToSnapshot,\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t...(parsed.pagination?.next\n\t\t\t\t\t\t\t\t? { next: parsed.pagination.next }\n\t\t\t\t\t\t\t\t: {}),\n\t\t\t\t\t\t};\n\t\t\t\t\t}),\n\t\t\t\t{ projectId },\n\t\t\t);\n\t\t} catch (err) {\n\t\t\tthrow customDomainsUnavailableError(err);\n\t\t}\n\t}\n\n\tasync registerBranchCustomDomain(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t\tinput: { domain: string; functionSlug: string },\n\t): Promise<NeonCustomDomainSnapshot> {\n\t\ttry {\n\t\t\treturn await this.call(\n\t\t\t\t`registerBranchCustomDomain(${projectId}/${branchId}/${input.domain})`,\n\t\t\t\tasync () => {\n\t\t\t\t\tconst data = await this.postJson(\n\t\t\t\t\t\tcustomDomainsPath(projectId, branchId),\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tdomain: input.domain,\n\t\t\t\t\t\t\tentity_type: \"function\",\n\t\t\t\t\t\t\tentity_id: input.functionSlug,\n\t\t\t\t\t\t},\n\t\t\t\t\t);\n\t\t\t\t\treturn customDomainToSnapshot(\n\t\t\t\t\t\tcustomDomainApiSchema.parse(data),\n\t\t\t\t\t);\n\t\t\t\t},\n\t\t\t\t{ projectId, mutating: true },\n\t\t\t);\n\t\t} catch (err) {\n\t\t\tthrow customDomainsUnavailableError(err);\n\t\t}\n\t}\n\n\tasync deleteBranchCustomDomain(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t\tdomain: string,\n\t): Promise<void> {\n\t\ttry {\n\t\t\tawait this.call(\n\t\t\t\t`deleteBranchCustomDomain(${projectId}/${branchId}/${domain})`,\n\t\t\t\tasync () => {\n\t\t\t\t\tawait this.deleteJson(\n\t\t\t\t\t\t`${customDomainsPath(projectId, branchId)}/${encodeURIComponent(domain)}`,\n\t\t\t\t\t);\n\t\t\t\t},\n\t\t\t\t{ projectId, mutating: true },\n\t\t\t);\n\t\t} catch (err) {\n\t\t\tthrow customDomainsUnavailableError(err);\n\t\t}\n\t}\n\n\t// ─── Preview: AI Gateway ───────────────────────────────────────────────────\n\t//\n\t// No methods: the AI Gateway is always available on a branch (credential-gated, not\n\t// per-branch provisioned). There is no control-plane enable/disable/status route — the\n\t// gateway is reached at the branch host with a credential carrying `ai_gateway:invoke`.\n\t// `preview.aiGateway` only drives that credential scope and the\n\t// `NEON_AI_GATEWAY_*` env vars (see `@neon/env`); nothing is provisioned here, so\n\t// `plan` / `apply` never touch an AI Gateway route and can't fail on its availability.\n\n\t// ─── Preview: branch-scoped credentials ──────────────────────────────────\n\n\tasync createCredential(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t\tinput: CreateCredentialInput,\n\t): Promise<NeonCredentialSecret> {\n\t\ttry {\n\t\t\treturn await this.call(\n\t\t\t\t`createCredential(${projectId}/${branchId})`,\n\t\t\t\tasync () => {\n\t\t\t\t\tconst data = await this.postJson(\n\t\t\t\t\t\tcredentialsPath(projectId, branchId),\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tscopes: input.scopes,\n\t\t\t\t\t\t\tprincipal_type: input.principalType,\n\t\t\t\t\t\t\t...(input.functionId\n\t\t\t\t\t\t\t\t? { function_id: input.functionId }\n\t\t\t\t\t\t\t\t: {}),\n\t\t\t\t\t\t\t...(input.name ? { name: input.name } : {}),\n\t\t\t\t\t\t},\n\t\t\t\t\t);\n\t\t\t\t\tconst parsed = createCredentialResponseSchema.parse(data);\n\t\t\t\t\treturn createCredentialToSnapshot(parsed);\n\t\t\t\t},\n\t\t\t\t{ projectId, mutating: true },\n\t\t\t);\n\t\t} catch (err) {\n\t\t\tthrow previewUnavailableError(err, \"Branch credentials\");\n\t\t}\n\t}\n\n\tasync listCredentials(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t): Promise<NeonCredentialMeta[]> {\n\t\ttry {\n\t\t\treturn await this.call(\n\t\t\t\t`listCredentials(${projectId}/${branchId})`,\n\t\t\t\tasync () => {\n\t\t\t\t\tconst data = await this.getJson(\n\t\t\t\t\t\tcredentialsPath(projectId, branchId),\n\t\t\t\t\t);\n\t\t\t\t\tconst parsed = listCredentialsResponseSchema.parse(data);\n\t\t\t\t\treturn parsed.credentials.map(credentialMetaToSnapshot);\n\t\t\t\t},\n\t\t\t\t{ projectId },\n\t\t\t);\n\t\t} catch (err) {\n\t\t\tthrow previewUnavailableError(err, \"Branch credentials\");\n\t\t}\n\t}\n\n\tasync revealCredential(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t\ttokenId: string,\n\t): Promise<NeonCredentialReveal> {\n\t\ttry {\n\t\t\treturn await this.call(\n\t\t\t\t`revealCredential(${projectId}/${branchId}/${tokenId})`,\n\t\t\t\tasync () => {\n\t\t\t\t\tconst data = await this.postJson(\n\t\t\t\t\t\t`${credentialsPath(projectId, branchId)}/${encodeURIComponent(tokenId)}/reveal`,\n\t\t\t\t\t\t{},\n\t\t\t\t\t);\n\t\t\t\t\tconst parsed = revealCredentialResponseSchema.parse(data);\n\t\t\t\t\treturn {\n\t\t\t\t\t\ttokenId: parsed.token_id,\n\t\t\t\t\t\tapiToken: parsed.api_token,\n\t\t\t\t\t\ts3SecretAccessKey: parsed.s3_secret_access_key,\n\t\t\t\t\t};\n\t\t\t\t},\n\t\t\t\t{ projectId, mutating: true },\n\t\t\t);\n\t\t} catch (err) {\n\t\t\tthrow previewUnavailableError(err, \"Branch credentials\");\n\t\t}\n\t}\n\n\tasync revokeCredential(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t\ttokenId: string,\n\t): Promise<void> {\n\t\tawait this.call(\n\t\t\t`revokeCredential(${projectId}/${branchId}/${tokenId})`,\n\t\t\tasync () => {\n\t\t\t\tawait this.deleteJson(\n\t\t\t\t\t`${credentialsPath(projectId, branchId)}/${encodeURIComponent(tokenId)}`,\n\t\t\t\t);\n\t\t\t},\n\t\t\t{ projectId, mutating: true },\n\t\t);\n\t}\n}\n\nfunction branchPreviewPath(\n\tprojectId: string,\n\tbranchId: string,\n\tresource: \"buckets\" | \"functions\",\n): string {\n\treturn `/projects/${encodeURIComponent(projectId)}/branches/${encodeURIComponent(branchId)}/${resource}`;\n}\n\nfunction credentialsPath(projectId: string, branchId: string): string {\n\treturn `/projects/${encodeURIComponent(projectId)}/branches/${encodeURIComponent(branchId)}/credentials`;\n}\n\nfunction triggersPath(projectId: string, branchId: string): string {\n\treturn `/projects/${encodeURIComponent(projectId)}/branches/${encodeURIComponent(branchId)}/triggers`;\n}\n\nfunction customDomainsPath(projectId: string, branchId: string): string {\n\treturn `/projects/${encodeURIComponent(projectId)}/branches/${encodeURIComponent(branchId)}/custom-domains`;\n}\n\nfunction withQuery(\n\tpath: string,\n\tquery?: Record<string, string | number | undefined>,\n): string {\n\tif (!query) return path;\n\tconst params = new URLSearchParams();\n\tfor (const [key, value] of Object.entries(query)) {\n\t\tif (value === undefined) continue;\n\t\tparams.set(key, String(value));\n\t}\n\tconst qs = params.toString();\n\treturn qs.length > 0 ? `${path}?${qs}` : path;\n}\n\nfunction customDomainToSnapshot(\n\tdata: z.infer<typeof customDomainApiSchema>,\n): NeonCustomDomainSnapshot {\n\treturn {\n\t\tdomain: data.domain,\n\t\tentityType: data.entity_type,\n\t\tentityId: data.entity_id,\n\t\tcnameTarget: data.cname_target,\n\t};\n}\n\nfunction triggerToSnapshot(\n\tdata: z.infer<typeof triggerApiSchema>,\n): NeonTriggerSnapshot {\n\tif (data.type === \"schedule\") {\n\t\treturn {\n\t\t\ttype: \"schedule\",\n\t\t\ttriggerId: data.trigger_id,\n\t\t\tname: data.name,\n\t\t\tfunctionSlug: data.function_slug,\n\t\t\tfunctionPath: data.function_path,\n\t\t\tcron: data.schedule.cron,\n\t\t\tenabled: data.enabled,\n\t\t\tinherited: data.inherited,\n\t\t\tnextRunAt: data.next_run_at,\n\t\t};\n\t}\n\treturn {\n\t\ttype: \"storage_object_created\",\n\t\ttriggerId: data.trigger_id,\n\t\tname: data.name,\n\t\tfunctionSlug: data.function_slug,\n\t\tfunctionPath: data.function_path,\n\t\tbucketName: data.storage_object_created.bucket_name,\n\t\t...(data.storage_object_created.prefix !== undefined\n\t\t\t? { prefix: data.storage_object_created.prefix }\n\t\t\t: {}),\n\t\tenabled: data.enabled,\n\t\tinherited: data.inherited,\n\t};\n}\n\nfunction createTriggerRequestBody(\n\tinput: CreateTriggerInput,\n): Record<string, unknown> {\n\tif (input.type === \"storage_object_created\") {\n\t\treturn {\n\t\t\ttype: \"storage_object_created\",\n\t\t\tname: input.name,\n\t\t\tfunction_slug: input.functionSlug,\n\t\t\tstorage_object_created: {\n\t\t\t\tbucket_name: input.bucketName,\n\t\t\t\t...(input.prefix !== undefined ? { prefix: input.prefix } : {}),\n\t\t\t},\n\t\t\t...(input.functionPath !== undefined\n\t\t\t\t? { function_path: input.functionPath }\n\t\t\t\t: {}),\n\t\t\t...(input.enabled !== undefined ? { enabled: input.enabled } : {}),\n\t\t};\n\t}\n\treturn {\n\t\ttype: \"schedule\",\n\t\tname: input.name,\n\t\tfunction_slug: input.functionSlug,\n\t\tschedule: { cron: input.cron },\n\t\t...(input.functionPath !== undefined\n\t\t\t? { function_path: input.functionPath }\n\t\t\t: {}),\n\t\t...(input.enabled !== undefined ? { enabled: input.enabled } : {}),\n\t};\n}\n\nfunction updateTriggerRequestBody(\n\tinput: UpdateTriggerInput,\n): Record<string, unknown> {\n\tif (input.type === \"storage_object_created\") {\n\t\treturn {\n\t\t\ttype: \"storage_object_created\",\n\t\t\t...(input.name !== undefined ? { name: input.name } : {}),\n\t\t\t...(input.functionSlug !== undefined\n\t\t\t\t? { function_slug: input.functionSlug }\n\t\t\t\t: {}),\n\t\t\t...(input.functionPath !== undefined\n\t\t\t\t? { function_path: input.functionPath }\n\t\t\t\t: {}),\n\t\t\t...(input.enabled !== undefined ? { enabled: input.enabled } : {}),\n\t\t\t...(input.bucketName !== undefined\n\t\t\t\t? {\n\t\t\t\t\t\tstorage_object_created: {\n\t\t\t\t\t\t\tbucket_name: input.bucketName,\n\t\t\t\t\t\t\t...(input.prefix !== undefined\n\t\t\t\t\t\t\t\t? { prefix: input.prefix }\n\t\t\t\t\t\t\t\t: {}),\n\t\t\t\t\t\t},\n\t\t\t\t\t}\n\t\t\t\t: {}),\n\t\t};\n\t}\n\treturn {\n\t\ttype: \"schedule\",\n\t\t...(input.name !== undefined ? { name: input.name } : {}),\n\t\t...(input.functionSlug !== undefined\n\t\t\t? { function_slug: input.functionSlug }\n\t\t\t: {}),\n\t\t...(input.cron !== undefined ? { schedule: { cron: input.cron } } : {}),\n\t\t...(input.functionPath !== undefined\n\t\t\t? { function_path: input.functionPath }\n\t\t\t: {}),\n\t\t...(input.enabled !== undefined ? { enabled: input.enabled } : {}),\n\t};\n}\n\nfunction createCredentialToSnapshot(\n\tdata: z.infer<typeof createCredentialResponseSchema>,\n): NeonCredentialSecret {\n\tconst snapshot: NeonCredentialSecret = {\n\t\ttokenId: data.token_id,\n\t\ttokenIdShort: data.token_id_short,\n\t\tapiToken: data.api_token,\n\t\ts3SecretAccessKey: data.s3_secret_access_key,\n\t\tscopes: data.scopes,\n\t\tbranchId: data.branch_id,\n\t\tcreatedAt: data.created_at,\n\t};\n\tif (data.name !== undefined) snapshot.name = data.name;\n\tif (data.expires_at !== undefined) snapshot.expiresAt = data.expires_at;\n\treturn snapshot;\n}\n\nfunction credentialMetaToSnapshot(\n\tdata: z.infer<typeof credentialMetaSchema>,\n): NeonCredentialMeta {\n\tconst snapshot: NeonCredentialMeta = {\n\t\ttokenId: data.token_id,\n\t\ttokenIdShort: data.token_id_short,\n\t\tscopes: data.scopes,\n\t\tprincipalType: data.principal_type,\n\t\tcreatedAt: data.created_at,\n\t};\n\tif (data.name !== undefined) snapshot.name = data.name;\n\tif (data.function_id !== undefined) snapshot.functionId = data.function_id;\n\tif (data.branch_id !== undefined) snapshot.branchId = data.branch_id;\n\tif (data.last_used_at !== undefined)\n\t\tsnapshot.lastUsedAt = data.last_used_at;\n\tif (data.revoked_at !== undefined) snapshot.revokedAt = data.revoked_at;\n\tif (data.expires_at !== undefined) snapshot.expiresAt = data.expires_at;\n\treturn snapshot;\n}\n\nfunction bucketToSnapshot(\n\tbucket: z.infer<typeof bucketSchema>,\n): NeonBucketSnapshot {\n\treturn {\n\t\tname: bucket.name,\n\t\taccessLevel: normalizeBucketAccessLevel(bucket.access_level),\n\t};\n}\n\n/**\n * The Neon API returns `access_level` as a free-form string (per the API guidelines:\n * responses use plain strings, not enums). Map the known values onto our union and treat\n * anything else as `private` — the safe default for an unrecognised access level.\n */\nfunction normalizeBucketAccessLevel(\n\tvalue: string | undefined,\n): BucketAccessLevel {\n\treturn value === \"public_read\" ? \"public_read\" : \"private\";\n}\n\nfunction functionToSnapshot(\n\tfn: z.infer<typeof neonFunctionSchema>,\n): NeonFunctionSnapshot {\n\tconst snapshot: NeonFunctionSnapshot = {\n\t\tid: fn.id,\n\t\tslug: fn.slug,\n\t\tname: fn.name,\n\t\tinvocationUrl: fn.invocation_url,\n\t};\n\tif (fn.active_deployment) {\n\t\tsnapshot.activeDeploymentId = fn.active_deployment.id;\n\t}\n\tif (fn.current_deployment) {\n\t\tsnapshot.currentDeployment = deploymentToSnapshot(\n\t\t\tfn.current_deployment,\n\t\t);\n\t}\n\treturn snapshot;\n}\n\nfunction deploymentToSnapshot(\n\tdeployment: z.infer<typeof functionDeploymentSchema>,\n): NeonFunctionDeploymentSnapshot {\n\treturn {\n\t\tid: deployment.id,\n\t\tstatus: normalizeDeploymentStatus(deployment.status),\n\t};\n}\n\nfunction normalizeDeploymentStatus(\n\tvalue: string,\n): NeonFunctionDeploymentSnapshot[\"status\"] {\n\tswitch (value) {\n\t\tcase \"pending\":\n\t\tcase \"building\":\n\t\tcase \"completed\":\n\t\tcase \"failed\":\n\t\t\treturn value;\n\t\tdefault:\n\t\t\t// Unknown status from a newer server — surface as `pending` rather than throwing,\n\t\t\t// matching the API guideline that clients treat undocumented enum values leniently.\n\t\t\treturn \"pending\";\n\t}\n}\n\n/**\n * Whether an error from a Preview-feature read means the feature simply isn't available\n * for this project/branch/region (as opposed to a real, transient failure). Neon signals\n * this a few ways: a 404 \"this route does not exist\" (the route isn't deployed at all), or\n * a 503/4xx whose message says the platform feature is \"not available\" / \"not enabled\".\n *\n * Callers do **not** swallow this into an empty result — touching a Preview feature that\n * isn't available is surfaced as a {@link previewUnavailableError} so `plan` / `status` /\n * `pull` (and `neon dev`) fail clearly instead of, say, planning to create resources the\n * API will refuse to create.\n */\nexport function isPreviewFeatureUnavailable(err: unknown): boolean {\n\tif (!(err instanceof PlatformError)) return false;\n\tconst status = err.details.status;\n\tconst message =\n\t\ttypeof err.details.neonMessage === \"string\"\n\t\t\t? err.details.neonMessage.toLowerCase()\n\t\t\t: \"\";\n\tconst mentionsUnavailable =\n\t\tmessage.includes(\"not available\") ||\n\t\tmessage.includes(\"does not exist\") ||\n\t\tmessage.includes(\"not enabled\");\n\treturn (\n\t\tmentionsUnavailable &&\n\t\t(status === 503 || status === 404 || status === 501)\n\t);\n}\n\n/**\n * Reason phrase for the handful of HTTP statuses a Preview-feature read can surface as\n * \"unavailable\". Used to print a short `HTTP <status> <reason>` line (not a stack trace),\n * so the message reads like the API response the user would see in a tool like curl.\n */\nconst HTTP_STATUS_TEXT: Record<number, string> = {\n\t401: \"Unauthorized\",\n\t403: \"Forbidden\",\n\t404: \"Not Found\",\n\t500: \"Internal Server Error\",\n\t501: \"Not Implemented\",\n\t503: \"Service Unavailable\",\n};\n\nconst PLATFORM_FEATURE_REGIONS =\n\t\"AWS US East (Ohio) (`aws-us-east-2`), AWS US East (N. Virginia) (`aws-us-east-1`), AWS Europe (Frankfurt) (`aws-eu-central-1`), and AWS Asia Pacific (Singapore) (`aws-ap-southeast-1`)\";\n\nconst PLATFORM_FEATURE_REGION_GUIDANCE =\n\t\"Neon features (Functions, Object Storage, and the AI Gateway) are currently only available in \" +\n\t`${PLATFORM_FEATURE_REGIONS}; more regions are coming shortly. Run \\`neon link\\` to link or create a new project in one of those regions.`;\n\nconst PLATFORM_FEATURE_REGION_GUIDANCE_SHORT =\n\t\"Neon features are currently only available in \" +\n\t`${PLATFORM_FEATURE_REGIONS}; more regions are coming shortly. Run \\`neon link\\` to link or create a new project in one of those regions.`;\n\n/**\n * True when the Neon API body indicates the feature isn't deployed for this project's\n * region (as opposed to a transient 503 incident).\n */\nfunction isRegionUnavailableNeonMessage(\n\tneonMessage: string | undefined,\n): boolean {\n\tif (!neonMessage) return false;\n\tconst lower = neonMessage.toLowerCase();\n\treturn (\n\t\tlower.includes(\"not available for this region\") ||\n\t\tlower.includes(\"not available for this project\") ||\n\t\tlower.includes(\"platform functions not available\") ||\n\t\tlower.includes(\"platform service not available\")\n\t);\n}\n\n/**\n * Per-status guidance for a platform feature that came back \"unavailable\". These features\n * roll out region by region, so we tailor the next step instead of emitting one catch-all:\n *\n * - 404 / 501, or an API message that names region/project unavailability — the route\n * isn't deployed for this project's region.\n * - 503 without a region-unavailable body — the route exists but is refusing right now;\n * Neon may be having a transient incident. Retry; if it persists check neonstatus.com.\n * - anything else — point at the region requirement.\n *\n * Only statuses {@link isPreviewFeatureUnavailable} accepts (404/501/503) actually reach\n * this, so there is intentionally no 401/403 branch — those never classify as \"unavailable\".\n */\nfunction platformFeatureUnavailableHint(\n\tstatus: number | undefined,\n\tneonMessage: string | undefined,\n): string {\n\tif (\n\t\tisRegionUnavailableNeonMessage(neonMessage) ||\n\t\tstatus === 404 ||\n\t\tstatus === 501\n\t) {\n\t\treturn PLATFORM_FEATURE_REGION_GUIDANCE;\n\t}\n\tif (status === 503) {\n\t\treturn \"The endpoint is reachable but refused the request — Neon may be having a transient incident. Retry shortly; if it keeps failing, check https://neonstatus.com and contact Neon support.\";\n\t}\n\treturn PLATFORM_FEATURE_REGION_GUIDANCE_SHORT;\n}\n\nconst CUSTOM_DOMAINS_UNAVAILABLE_HINT =\n\t\"Custom domains are enabled per project; deploying functions does not enable them. Remove `customDomains` from the function in neon.ts to continue deploying functions.\";\n\n/**\n * Custom-domain 404s in Functions-capable regions are project enablement, not a\n * missing-region problem.\n */\nexport function customDomainsUnavailableError(err: unknown): unknown {\n\tif (!isPreviewFeatureUnavailable(err)) return err;\n\tconst details = err instanceof PlatformError ? err.details : {};\n\tconst status =\n\t\ttypeof details.status === \"number\" ? details.status : undefined;\n\tconst neonMessage =\n\t\ttypeof details.neonMessage === \"string\"\n\t\t\t? details.neonMessage\n\t\t\t: undefined;\n\tconst requestId =\n\t\ttypeof details.requestId === \"string\" ? details.requestId : undefined;\n\n\tconst statusText = status ? HTTP_STATUS_TEXT[status] : undefined;\n\tconst apiParts = [\n\t\tstatus\n\t\t\t? `HTTP ${status}${statusText ? ` ${statusText}` : \"\"}`\n\t\t\t: undefined,\n\t\tneonMessage ? `Neon API said: \"${neonMessage}\"` : undefined,\n\t\trequestId ? `request id ${requestId}` : undefined,\n\t].filter((part): part is string => part !== undefined);\n\tconst apiContext = apiParts.length > 0 ? ` (${apiParts.join(\"; \")})` : \"\";\n\n\tconst hint =\n\t\tstatus === 503 && !isRegionUnavailableNeonMessage(neonMessage)\n\t\t\t? \"The endpoint is reachable but refused the request — Neon may be having a transient incident. Retry shortly; if it keeps failing, check https://neonstatus.com and contact Neon support.\"\n\t\t\t: CUSTOM_DOMAINS_UNAVAILABLE_HINT;\n\n\treturn new PlatformError(\n\t\tErrorCode.FeatureUnavailable,\n\t\t[\n\t\t\t`Custom domains aren't available for this Neon project${apiContext}.`,\n\t\t\thint,\n\t\t].join(\" \"),\n\t\t{\n\t\t\tcause: err,\n\t\t\tdetails: {\n\t\t\t\tfeature: \"Custom domains\",\n\t\t\t\t...(status !== undefined ? { status } : {}),\n\t\t\t\t...(requestId !== undefined ? { requestId } : {}),\n\t\t\t},\n\t\t},\n\t);\n}\n\n/**\n * Convert a Preview-feature error into a clear {@link PlatformError} when the feature is\n * unavailable for the project; otherwise pass the original error through unchanged so a\n * genuine failure (auth, transient 5xx, …) keeps its specific code and message.\n *\n * The message names the failing feature, summarizes the response in one short\n * `HTTP <status> <reason>` line, includes the raw Neon API message + request id,\n * gives status-specific guidance (see {@link platformFeatureUnavailableHint}),\n * and offers removing the feature from the policy as an escape hatch.\n * `status`/`requestId` are also kept on `details` for programmatic consumers.\n */\nexport function previewUnavailableError(\n\terr: unknown,\n\tfeatureLabel: string,\n): unknown {\n\tif (!isPreviewFeatureUnavailable(err)) return err;\n\tconst details = err instanceof PlatformError ? err.details : {};\n\tconst status =\n\t\ttypeof details.status === \"number\" ? details.status : undefined;\n\tconst neonMessage =\n\t\ttypeof details.neonMessage === \"string\"\n\t\t\t? details.neonMessage\n\t\t\t: undefined;\n\tconst requestId =\n\t\ttypeof details.requestId === \"string\" ? details.requestId : undefined;\n\n\t// One short status line + the raw API message + request id — never a stack trace.\n\tconst statusText = status ? HTTP_STATUS_TEXT[status] : undefined;\n\tconst apiParts = [\n\t\tstatus\n\t\t\t? `HTTP ${status}${statusText ? ` ${statusText}` : \"\"}`\n\t\t\t: undefined,\n\t\tneonMessage ? `Neon API said: \"${neonMessage}\"` : undefined,\n\t\trequestId ? `request id ${requestId}` : undefined,\n\t].filter((part): part is string => part !== undefined);\n\tconst apiContext = apiParts.length > 0 ? ` (${apiParts.join(\"; \")})` : \"\";\n\n\treturn new PlatformError(\n\t\tErrorCode.FeatureUnavailable,\n\t\t[\n\t\t\t`${featureLabel} isn't available for this Neon project${apiContext}.`,\n\t\t\tplatformFeatureUnavailableHint(status, neonMessage),\n\t\t\t\"If you don't need it, remove the corresponding feature from your neon.ts and re-run.\",\n\t\t].join(\" \"),\n\t\t{\n\t\t\tcause: err,\n\t\t\tdetails: {\n\t\t\t\tfeature: featureLabel,\n\t\t\t\t...(status !== undefined ? { status } : {}),\n\t\t\t\t...(requestId !== undefined ? { requestId } : {}),\n\t\t\t},\n\t\t},\n\t);\n}\n\nfunction neonAuthResponseToSnapshot(\n\tdata: z.infer<typeof neonAuthResponseSchema>,\n): NeonAuthSnapshot {\n\tconst snapshot: NeonAuthSnapshot = {\n\t\tprojectId: data.auth_provider_project_id,\n\t\tjwksUrl: data.jwks_url,\n\t};\n\tif (data.pub_client_key !== undefined) {\n\t\tsnapshot.publishableClientKey = data.pub_client_key;\n\t}\n\tif (data.secret_server_key !== undefined) {\n\t\tsnapshot.secretServerKey = data.secret_server_key;\n\t}\n\tif (data.base_url) snapshot.baseUrl = data.base_url;\n\treturn snapshot;\n}\n\n/**\n * A 409 from enabling Neon Auth on a branch that still has no integration. The cause is\n * whatever the API says (for example an existing `neon_auth` schema), so its message replaces\n * the generic name-collision hint that `wrapNeonError` adds to every 409.\n */\nfunction neonAuthProvisioningConflict(\n\terr: PlatformError,\n\tprojectId: string,\n\tbranchId: string,\n): PlatformError {\n\tconst { neonMessage, requestId } = err.details;\n\tconst requestIdSuffix =\n\t\ttypeof requestId === \"string\" ? ` (request id ${requestId})` : \"\";\n\tconst reason =\n\t\ttypeof neonMessage === \"string\"\n\t\t\t? `Neon API said: \"${neonMessage}\"${requestIdSuffix}.`\n\t\t\t: `Neon Auth is not enabled on this branch and could not be provisioned (HTTP 409)${requestIdSuffix}.`;\n\treturn new PlatformError(\n\t\tErrorCode.Conflict,\n\t\t`enableNeonAuth(${projectId}/${branchId}) failed: ${reason}`,\n\t\t{ cause: err, details: err.details },\n\t);\n}\n\nexport function createNeonAuthRestInput(input: {\n\tdatabaseName?: string;\n}): CreateNeonAuthRestInput {\n\treturn {\n\t\tauth_provider: \"better_auth\",\n\t\t...(input.databaseName ? { database_name: input.databaseName } : {}),\n\t};\n}\n\n/**\n * Build the `multipart/form-data` body for a function deployment, matching the public\n * `FunctionDeployRequest` schema (`POST .../functions/{slug}/deployments`):\n *\n * - `zip` — the bundle as a binary part (named `bundle.zip`).\n * - `runtime` — the function runtime.\n * - `environment` — a single JSON-encoded string→string map (multipart can't carry a typed\n * object part), omitted entirely when there are no env vars.\n *\n * Pure (no I/O) so it can be unit-tested against the spec without stubbing `fetch`.\n */\nexport function buildFunctionDeployForm(input: DeployFunctionInput): FormData {\n\tconst form = new FormData();\n\tform.set(\n\t\t\"zip\",\n\t\tnew Blob([input.bundle as BlobPart], { type: \"application/zip\" }),\n\t\t\"bundle.zip\",\n\t);\n\tform.set(\"runtime\", input.runtime);\n\tif (Object.keys(input.environment).length > 0) {\n\t\tform.set(\"environment\", JSON.stringify(input.environment));\n\t}\n\treturn form;\n}\n\n/**\n * Read a response body as JSON, tolerating non-JSON. Some Neon routes return a plain-text\n * body (e.g. a 404 `\"this route does not exist\"` for a Preview feature not enabled in the\n * project/region). Parsing that with `JSON.parse` used to throw a cryptic\n * `SyntaxError: Unexpected token …`, which — because parsing happens before the `res.ok`\n * check in {@link request} — masked the real HTTP status. We instead return the raw text\n * wrapped as `{ message }` so the status-based error path in `request` / `wrapNeonError`\n * runs and produces a proper {@link PlatformError} (e.g. `NotFound`), and a non-error body\n * that simply isn't JSON degrades to text rather than crashing.\n */\nexport async function readJsonBody(res: Response): Promise<unknown> {\n\tconst text = await res.text();\n\tif (text.trim() === \"\") return {};\n\ttry {\n\t\treturn JSON.parse(text);\n\t} catch {\n\t\treturn { message: text.trim() };\n\t}\n}\n\nfunction projectToSnapshot(\n\tproject: Project | ProjectListItem,\n): NeonProjectSnapshot {\n\tconst defaults = project.default_endpoint_settings;\n\tconst snapshot: NeonProjectSnapshot = {\n\t\tid: project.id,\n\t\tname: project.name,\n\t\tregionId: project.region_id,\n\t\tpgVersion: project.pg_version,\n\t};\n\tif (project.org_id) snapshot.orgId = project.org_id;\n\tif (defaults) {\n\t\tconst compute = defaultsToComputeSettings(defaults);\n\t\tif (compute) snapshot.defaultEndpointSettings = compute;\n\t}\n\treturn snapshot;\n}\n\nfunction branchToSnapshot(branch: Branch): NeonBranchSnapshot {\n\tconst snapshot: NeonBranchSnapshot = {\n\t\tid: branch.id,\n\t\tname: branch.name,\n\t\tisDefault: branch.default,\n\t\tprotected: branch.protected === true,\n\t};\n\tif (branch.parent_id) snapshot.parentId = branch.parent_id;\n\tif (branch.expires_at) snapshot.expiresAt = branch.expires_at;\n\treturn snapshot;\n}\n\nfunction endpointToSnapshot(endpoint: Endpoint): NeonEndpointSnapshot {\n\treturn {\n\t\tid: endpoint.id,\n\t\tbranchId: endpoint.branch_id,\n\t\ttype: endpoint.type === \"read_only\" ? \"read_only\" : \"read_write\",\n\t\tautoscalingLimitMinCu:\n\t\t\tendpoint.autoscaling_limit_min_cu as ComputeSettings[\"autoscalingLimitMinCu\"],\n\t\tautoscalingLimitMaxCu:\n\t\t\tendpoint.autoscaling_limit_max_cu as ComputeSettings[\"autoscalingLimitMaxCu\"],\n\t\tsuspendTimeout: formatSuspendTimeout(endpoint.suspend_timeout_seconds),\n\t};\n}\n\nfunction roleToSnapshot(role: Role): NeonRoleSnapshot {\n\treturn {\n\t\tname: role.name,\n\t\tbranchId: role.branch_id,\n\t\tprotected: role.protected ?? false,\n\t};\n}\n\nfunction databaseToSnapshot(database: Database): NeonDatabaseSnapshot {\n\treturn {\n\t\tname: database.name,\n\t\tbranchId: database.branch_id,\n\t\townerName: database.owner_name,\n\t};\n}\n\nfunction computeSettingsToDefaults(\n\tsettings: ComputeSettings,\n): DefaultEndpointSettings {\n\tconst out: DefaultEndpointSettings = {};\n\tif (settings.autoscalingLimitMinCu !== undefined)\n\t\tout.autoscaling_limit_min_cu = settings.autoscalingLimitMinCu;\n\tif (settings.autoscalingLimitMaxCu !== undefined)\n\t\tout.autoscaling_limit_max_cu = settings.autoscalingLimitMaxCu;\n\tif (settings.suspendTimeout !== undefined) {\n\t\tconst parsed = parseSuspendTimeout(settings.suspendTimeout);\n\t\tif (\"error\" in parsed) {\n\t\t\tthrow new PlatformError(\n\t\t\t\tErrorCode.InvalidConfig,\n\t\t\t\t`Invalid suspendTimeout: ${parsed.error}`,\n\t\t\t);\n\t\t}\n\t\tout.suspend_timeout_seconds = parsed.seconds;\n\t}\n\treturn out;\n}\n\nfunction computeSettingsToEndpointOptions(settings: ComputeSettings): {\n\tautoscaling_limit_min_cu?: number;\n\tautoscaling_limit_max_cu?: number;\n\tsuspend_timeout_seconds?: number;\n} {\n\tconst out: {\n\t\tautoscaling_limit_min_cu?: number;\n\t\tautoscaling_limit_max_cu?: number;\n\t\tsuspend_timeout_seconds?: number;\n\t} = {};\n\tif (settings.autoscalingLimitMinCu !== undefined)\n\t\tout.autoscaling_limit_min_cu = settings.autoscalingLimitMinCu;\n\tif (settings.autoscalingLimitMaxCu !== undefined)\n\t\tout.autoscaling_limit_max_cu = settings.autoscalingLimitMaxCu;\n\tif (settings.suspendTimeout !== undefined) {\n\t\tconst parsed = parseSuspendTimeout(settings.suspendTimeout);\n\t\tif (\"error\" in parsed) {\n\t\t\tthrow new PlatformError(\n\t\t\t\tErrorCode.InvalidConfig,\n\t\t\t\t`Invalid suspendTimeout: ${parsed.error}`,\n\t\t\t);\n\t\t}\n\t\tout.suspend_timeout_seconds = parsed.seconds;\n\t}\n\treturn out;\n}\n\nfunction defaultsToComputeSettings(\n\tdefaults: DefaultEndpointSettings,\n): ComputeSettings | undefined {\n\tconst out: ComputeSettings = {};\n\tif (defaults.autoscaling_limit_min_cu !== undefined)\n\t\tout.autoscalingLimitMinCu =\n\t\t\tdefaults.autoscaling_limit_min_cu as ComputeSettings[\"autoscalingLimitMinCu\"];\n\tif (defaults.autoscaling_limit_max_cu !== undefined)\n\t\tout.autoscalingLimitMaxCu =\n\t\t\tdefaults.autoscaling_limit_max_cu as ComputeSettings[\"autoscalingLimitMaxCu\"];\n\tif (defaults.suspend_timeout_seconds !== undefined)\n\t\tout.suspendTimeout = formatSuspendTimeout(\n\t\t\tdefaults.suspend_timeout_seconds,\n\t\t);\n\treturn Object.keys(out).length > 0 ? out : undefined;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"neon-api-real.js","names":["rawListProjects","rawGetProject","rawCreateProject","rawUpdateProject","rawListProjectBranches","rawCreateProjectBranch","rawUpdateProjectBranch","rawListProjectEndpoints","rawUpdateProjectEndpoint","rawListProjectBranchRoles","rawListProjectBranchDatabases","rawGetConnectionUri","rawGetNeonAuth","rawGetProjectBranchDataApi","rawCreateProjectBranchDataApi","rawUpdateProjectBranchDataApi","rawDeleteProjectBranchDataApi","rawGetProjectBranchRealtime","rawGetProjectBranchRealtimeSecret","rawEnableProjectBranchRealtime","rawDisableProjectBranchRealtime"],"sources":["../../src/lib/neon-api-real.ts"],"sourcesContent":["import type {\n\tDataApiSettings as ApiDataApiSettings,\n\tRealtime as ApiRealtime,\n\tRealtimeOptions as ApiRealtimeOptions,\n\tRealtimeSecret as ApiRealtimeSecret,\n\tBranch,\n\tBranchCreateRequest,\n\tBranchCreateRequestEndpointOptions,\n\tBranchUpdateRequest,\n\tDataApiCreateRequest,\n\tDataApiReponse,\n\tDatabase,\n\tDefaultEndpointSettings,\n\tEndpoint,\n\tEndpointUpdateRequest,\n\tPgVersion,\n\tProject,\n\tProjectCreateRequest,\n\tProjectListItem,\n\tProjectUpdateRequest,\n\tRole,\n} from \"@neon/sdk\";\nimport { createNeonClient } from \"@neon/sdk\";\nimport {\n\tcreateProject as rawCreateProject,\n\tcreateProjectBranch as rawCreateProjectBranch,\n\tcreateProjectBranchDataApi as rawCreateProjectBranchDataApi,\n\tdeleteProjectBranchDataApi as rawDeleteProjectBranchDataApi,\n\tdisableProjectBranchRealtime as rawDisableProjectBranchRealtime,\n\tenableProjectBranchRealtime as rawEnableProjectBranchRealtime,\n\tgetConnectionUri as rawGetConnectionUri,\n\tgetNeonAuth as rawGetNeonAuth,\n\tgetProject as rawGetProject,\n\tgetProjectBranchDataApi as rawGetProjectBranchDataApi,\n\tgetProjectBranchRealtime as rawGetProjectBranchRealtime,\n\tgetProjectBranchRealtimeSecret as rawGetProjectBranchRealtimeSecret,\n\tlistProjectBranchDatabases as rawListProjectBranchDatabases,\n\tlistProjectBranches as rawListProjectBranches,\n\tlistProjectBranchRoles as rawListProjectBranchRoles,\n\tlistProjectEndpoints as rawListProjectEndpoints,\n\tlistProjects as rawListProjects,\n\tupdateProject as rawUpdateProject,\n\tupdateProjectBranch as rawUpdateProjectBranch,\n\tupdateProjectBranchDataApi as rawUpdateProjectBranchDataApi,\n\tupdateProjectEndpoint as rawUpdateProjectEndpoint,\n} from \"@neon/sdk/raw\";\nimport { z } from \"zod\";\nimport { formatSuspendTimeout, parseSuspendTimeout } from \"./duration.js\";\nimport { ErrorCode, PlatformError } from \"./errors.js\";\nimport type {\n\tConfigureRealtimeInput,\n\tCreateBranchInput,\n\tCreateBucketInput,\n\tCreateCredentialInput,\n\tCreateProjectInput,\n\tCreateTriggerInput,\n\tDeployFunctionInput,\n\tEnableDataApiInput,\n\tGetConnectionUriInput,\n\tNeonApi,\n\tNeonAuthSnapshot,\n\tNeonBranchSnapshot,\n\tNeonBranchStorageSnapshot,\n\tNeonBucketSnapshot,\n\tNeonCredentialMeta,\n\tNeonCredentialReveal,\n\tNeonCredentialSecret,\n\tNeonCustomDomainSnapshot,\n\tNeonDataApiSnapshot,\n\tNeonDatabaseSnapshot,\n\tNeonEndpointSnapshot,\n\tNeonFunctionDeploymentSnapshot,\n\tNeonFunctionSnapshot,\n\tNeonProjectSnapshot,\n\tNeonRealtimeSecret,\n\tNeonRealtimeSnapshot,\n\tNeonRoleSnapshot,\n\tNeonTriggerSnapshot,\n\tRemoteDataApiAuthProvider,\n\tUpdateBranchInput,\n\tUpdateTriggerInput,\n} from \"./neon-api.js\";\nimport type {\n\tBucketAccessLevel,\n\tComputeSettings,\n\tDataApiSettings,\n} from \"./types.js\";\nimport { wrapNeonError } from \"./wrap-neon-error.js\";\n\ntype ApiClient = ReturnType<typeof createNeonClient>[\"client\"];\nconst DEFAULT_NEON_API_BASE_URL = \"https://console.neon.tech/api/v2\";\n\n/**\n * Unwrap a `@neon/sdk` raw `{ data, error, response }` result into the bare body, throwing\n * on a non-2xx response. The thrown shape (`{ response: { status, data } }`) deliberately\n * matches what the package's REST fallbacks already throw, so {@link wrapNeonError} and the\n * 423 {@link retryOnLocked} retry keep working unchanged across both transports.\n */\nfunction unwrap<T>(result: {\n\tdata?: T;\n\terror?: unknown;\n\tresponse?: Response;\n}): T {\n\tconst response = result.response;\n\tif (!response?.ok) {\n\t\tthrow {\n\t\t\tresponse: {\n\t\t\t\tstatus: response?.status,\n\t\t\t\tdata: result.error,\n\t\t\t},\n\t\t};\n\t}\n\treturn result.data as T;\n}\n\nconst neonAuthResponseSchema = z.object({\n\tauth_provider_project_id: z.string(),\n\tpub_client_key: z.string().optional(),\n\tsecret_server_key: z.string().optional(),\n\tjwks_url: z.string(),\n\tbase_url: z.string().optional(),\n});\n\n// ─── Data API mapping (camelCase neon.ts ↔ snake_case Neon API) ───────────────\n\n/** Map our camelCase {@link DataApiSettings} onto the Neon API's snake_case `DataAPISettings`. */\nfunction dataApiSettingsToApi(settings: DataApiSettings): ApiDataApiSettings {\n\tconst out: ApiDataApiSettings = {};\n\tif (settings.dbAggregatesEnabled !== undefined)\n\t\tout.db_aggregates_enabled = settings.dbAggregatesEnabled;\n\tif (settings.dbAnonRole !== undefined)\n\t\tout.db_anon_role = settings.dbAnonRole;\n\tif (settings.dbExtraSearchPath !== undefined)\n\t\tout.db_extra_search_path = settings.dbExtraSearchPath;\n\tif (settings.dbMaxRows !== undefined) out.db_max_rows = settings.dbMaxRows;\n\tif (settings.dbSchemas !== undefined) out.db_schemas = settings.dbSchemas;\n\tif (settings.jwtRoleClaimKey !== undefined)\n\t\tout.jwt_role_claim_key = settings.jwtRoleClaimKey;\n\tif (settings.jwtCacheMaxLifetime !== undefined)\n\t\tout.jwt_cache_max_lifetime = settings.jwtCacheMaxLifetime;\n\tif (settings.openapiMode !== undefined)\n\t\tout.openapi_mode = settings.openapiMode;\n\tif (settings.serverCorsAllowedOrigins !== undefined)\n\t\tout.server_cors_allowed_origins = settings.serverCorsAllowedOrigins;\n\tif (settings.serverTimingEnabled !== undefined)\n\t\tout.server_timing_enabled = settings.serverTimingEnabled;\n\treturn out;\n}\n\n/** Narrow the API's free-form `openapi_mode` string to our literal union (else drop it). */\nfunction normalizeOpenapiMode(\n\tvalue: string,\n): DataApiSettings[\"openapiMode\"] | undefined {\n\treturn value === \"ignore-privileges\" || value === \"disabled\"\n\t\t? value\n\t\t: undefined;\n}\n\n/** Map the Neon API's snake_case `DataAPISettings` back to our camelCase {@link DataApiSettings}. */\nfunction dataApiSettingsFromApi(\n\tsettings: ApiDataApiSettings | null | undefined,\n): DataApiSettings | undefined {\n\tif (!settings) return undefined;\n\tconst out: DataApiSettings = {};\n\tif (settings.db_aggregates_enabled !== undefined)\n\t\tout.dbAggregatesEnabled = settings.db_aggregates_enabled;\n\tif (settings.db_anon_role !== undefined)\n\t\tout.dbAnonRole = settings.db_anon_role;\n\tif (settings.db_extra_search_path !== undefined)\n\t\tout.dbExtraSearchPath = settings.db_extra_search_path;\n\tif (settings.db_max_rows !== undefined)\n\t\tout.dbMaxRows = settings.db_max_rows;\n\tif (settings.db_schemas !== undefined) out.dbSchemas = settings.db_schemas;\n\tif (settings.jwt_role_claim_key !== undefined)\n\t\tout.jwtRoleClaimKey = settings.jwt_role_claim_key;\n\tif (settings.jwt_cache_max_lifetime !== undefined)\n\t\tout.jwtCacheMaxLifetime = settings.jwt_cache_max_lifetime;\n\tif (settings.openapi_mode !== undefined) {\n\t\tconst mode = normalizeOpenapiMode(settings.openapi_mode);\n\t\tif (mode !== undefined) out.openapiMode = mode;\n\t}\n\tif (settings.server_cors_allowed_origins !== undefined)\n\t\tout.serverCorsAllowedOrigins = settings.server_cors_allowed_origins;\n\tif (settings.server_timing_enabled !== undefined)\n\t\tout.serverTimingEnabled = settings.server_timing_enabled;\n\treturn Object.keys(out).length > 0 ? out : undefined;\n}\n\n/** Build the Neon API `DataAPICreateRequest` from our {@link EnableDataApiInput}. */\nfunction dataApiCreateRequest(\n\tinput: EnableDataApiInput | undefined,\n): DataApiCreateRequest {\n\tconst req: DataApiCreateRequest = {};\n\tif (!input) return req;\n\tif (input.authProvider !== undefined)\n\t\treq.auth_provider =\n\t\t\tinput.authProvider === \"neon\" ? \"neon_auth\" : \"external\";\n\tif (input.jwksUrl !== undefined) req.jwks_url = input.jwksUrl;\n\tif (input.providerName !== undefined)\n\t\treq.provider_name = input.providerName;\n\tif (input.jwtAudience !== undefined) req.jwt_audience = input.jwtAudience;\n\tif (input.settings) {\n\t\tconst settings = dataApiSettingsToApi(input.settings);\n\t\tif (Object.keys(settings).length > 0) req.settings = settings;\n\t}\n\treturn req;\n}\n\n/**\n * The auth-provider fields of `DataAPIReponse`. Read off the raw response rather than the\n * generated type: the vendored spec predates them, and a response that lacks them is a\n * valid older Data API rather than an error.\n */\ninterface DataApiAuthFields {\n\tauth_provider?: unknown;\n\tjwks_url?: unknown;\n\tprovider_name?: unknown;\n\tjwt_audience?: unknown;\n}\n\nconst REMOTE_DATA_API_AUTH_PROVIDERS: ReadonlySet<string> = new Set([\n\t\"neon_auth\",\n\t\"external\",\n\t\"none\",\n]);\n\n/** Map a `DataAPIReponse` (GET) onto our {@link NeonDataApiSnapshot}. */\nfunction dataApiSnapshotFromResponse(\n\tdata: DataApiReponse,\n): NeonDataApiSnapshot {\n\tconst snapshot: NeonDataApiSnapshot = { url: data.url };\n\tif (data.status !== undefined) snapshot.status = data.status;\n\tconst settings = dataApiSettingsFromApi(data.settings);\n\tif (settings) snapshot.settings = settings;\n\tconst auth = data as DataApiAuthFields;\n\tif (\n\t\ttypeof auth.auth_provider === \"string\" &&\n\t\tREMOTE_DATA_API_AUTH_PROVIDERS.has(auth.auth_provider)\n\t) {\n\t\tsnapshot.authProvider = auth.auth_provider as RemoteDataApiAuthProvider;\n\t}\n\tif (typeof auth.jwks_url === \"string\") snapshot.jwksUrl = auth.jwks_url;\n\tif (typeof auth.provider_name === \"string\")\n\t\tsnapshot.providerName = auth.provider_name;\n\tif (typeof auth.jwt_audience === \"string\")\n\t\tsnapshot.jwtAudience = auth.jwt_audience;\n\treturn snapshot;\n}\n\nfunction realtimeOptionsToApi(\n\tinput: ConfigureRealtimeInput | undefined,\n): ApiRealtimeOptions {\n\treturn input?.allowedOrigins === undefined\n\t\t? {}\n\t\t: { allowed_origins: [...input.allowedOrigins] };\n}\n\nfunction realtimeSnapshotFromApi(data: ApiRealtime): NeonRealtimeSnapshot {\n\treturn {\n\t\tenabled: data.enabled,\n\t\tpending: data.pending,\n\t\t...(data.invocation_url !== undefined\n\t\t\t? { invocationUrl: data.invocation_url }\n\t\t\t: {}),\n\t\t...(data.revision !== undefined ? { revision: data.revision } : {}),\n\t\t...(data.allowed_origins !== undefined\n\t\t\t? { allowedOrigins: [...data.allowed_origins] }\n\t\t\t: {}),\n\t};\n}\n\nfunction realtimeSecretFromApi(data: ApiRealtimeSecret): NeonRealtimeSecret {\n\treturn { secret: data.secret, pending: data.pending };\n}\n\n// ─── Preview: buckets ──────────────────────────────────────────────────────\n\nconst bucketSchema = z.object({\n\tname: z.string(),\n\taccess_level: z.string().optional(),\n});\nconst bucketResponseSchema = z.object({ bucket: bucketSchema });\nconst bucketsListResponseSchema = z.object({ buckets: z.array(bucketSchema) });\nconst branchStorageSchema = z.object({\n\tenabled: z.boolean().optional(),\n\ts3_endpoint: z.string(),\n\tregion: z.string(),\n\tforce_path_style: z.boolean(),\n});\n\n// ─── Preview: functions ────────────────────────────────────────────────────\n\nconst functionDeploymentSchema = z.object({\n\tid: z.number(),\n\tstatus: z.string(),\n});\nconst neonFunctionSchema = z.object({\n\tid: z.string(),\n\tslug: z.string(),\n\tname: z.string(),\n\tinvocation_url: z.string(),\n\tcurrent_deployment: functionDeploymentSchema.optional(),\n\tactive_deployment: functionDeploymentSchema.optional(),\n});\nconst functionsListResponseSchema = z.object({\n\tfunctions: z.array(neonFunctionSchema),\n});\nconst functionGetResponseSchema = z.object({\n\tfunction: neonFunctionSchema,\n});\nconst functionDeploymentResponseSchema = z.object({\n\tdeployment: functionDeploymentSchema,\n});\n\nconst scheduleTriggerSchema = z.object({\n\ttype: z.literal(\"schedule\"),\n\ttrigger_id: z.string(),\n\tfunction_slug: z.string(),\n\tname: z.string(),\n\tfunction_path: z.string(),\n\tschedule: z.object({ cron: z.string() }),\n\tenabled: z.boolean(),\n\tinherited: z.boolean(),\n\tnext_run_at: z.string().nullable(),\n});\nconst storageObjectCreatedTriggerSchema = z.object({\n\ttype: z.literal(\"storage_object_created\"),\n\ttrigger_id: z.string(),\n\tfunction_slug: z.string(),\n\tname: z.string(),\n\tfunction_path: z.string(),\n\tstorage_object_created: z.object({\n\t\tbucket_name: z.string(),\n\t\tprefix: z.string().optional(),\n\t}),\n\tenabled: z.boolean(),\n\tinherited: z.boolean(),\n});\nconst triggerApiSchema = z.discriminatedUnion(\"type\", [\n\tscheduleTriggerSchema,\n\tstorageObjectCreatedTriggerSchema,\n]);\nconst triggerResponseSchema = z.object({ trigger: triggerApiSchema });\nconst triggersListResponseSchema = z.object({\n\ttriggers: z.array(triggerApiSchema),\n});\n\nconst customDomainApiSchema = z.object({\n\tdomain: z.string(),\n\tentity_type: z.string(),\n\tentity_id: z.string(),\n\tcname_target: z.string(),\n});\nconst customDomainsListResponseSchema = z.object({\n\tcustom_domains: z.array(customDomainApiSchema),\n\tpagination: z.object({ next: z.string().optional() }).optional(),\n});\nconst CUSTOM_DOMAINS_LIST_LIMIT = 100;\n\n// ─── Preview: branch-scoped credentials ─────────────────────────────────────\n\nconst credentialScopeSchema = z.enum([\n\t\"storage:read\",\n\t\"storage:write\",\n\t\"ai_gateway:invoke\",\n\t\"functions:invoke\",\n]);\nconst createCredentialResponseSchema = z.object({\n\ttoken_id: z.string(),\n\ttoken_id_short: z.string(),\n\tname: z.string().optional(),\n\tapi_token: z.string(),\n\ts3_secret_access_key: z.string(),\n\tscopes: z.array(credentialScopeSchema),\n\tbranch_id: z.string(),\n\tcreated_at: z.string(),\n\texpires_at: z.string().optional(),\n});\nconst credentialMetaSchema = z.object({\n\ttoken_id: z.string(),\n\ttoken_id_short: z.string(),\n\tname: z.string().optional(),\n\tscopes: z.array(credentialScopeSchema),\n\tprincipal_type: z.enum([\"user\", \"function\"]),\n\tfunction_id: z.string().optional(),\n\tbranch_id: z.string().optional(),\n\tcreated_at: z.string(),\n\tlast_used_at: z.string().optional(),\n\trevoked_at: z.string().optional(),\n\texpires_at: z.string().optional(),\n});\nconst listCredentialsResponseSchema = z.object({\n\tcredentials: z.array(credentialMetaSchema),\n});\nconst revealCredentialResponseSchema = z.object({\n\ttoken_id: z.string(),\n\tapi_token: z.string(),\n\ts3_secret_access_key: z.string(),\n});\n\ninterface CreateNeonAuthRestInput {\n\tauth_provider: \"better_auth\";\n\tdatabase_name?: string;\n}\n\ninterface RestConfig {\n\tapiKey: string;\n\tbaseUrl: string;\n}\n\n/**\n * Adapt `@neon/sdk` (raw layer) to the narrow {@link NeonApi} façade used by the rest of\n * this package. Constructs are restricted to whole-object read/write of just the fields we\n * model in {@link Config}; anything else stays untouched on the remote.\n */\nexport function createRealNeonApi(options: {\n\tapiKey: string;\n\tbaseUrl?: string;\n\t/**\n\t * Tuning knob for the built-in 423 retry. Defaults: ~30s of total wait spread across\n\t * 12 attempts with exponential backoff capped at 5s. Lowering this is mostly useful in\n\t * tests; raising it is rarely needed because Neon operations are usually sub-second.\n\t */\n\tretryOnLocked?: {\n\t\tmaxAttempts?: number;\n\t\tinitialDelayMs?: number;\n\t\tmaxDelayMs?: number;\n\t};\n}): NeonApi {\n\tif (!options.apiKey || options.apiKey.trim() === \"\") {\n\t\tthrow new PlatformError(\n\t\t\tErrorCode.MissingApiKey,\n\t\t\t[\n\t\t\t\t\"createRealNeonApi requires a non-empty `apiKey`.\",\n\t\t\t\t\"Generate one at https://console.neon.tech/app/settings/api-keys and pass it as { apiKey: process.env.NEON_API_KEY }.\",\n\t\t\t].join(\" \"),\n\t\t);\n\t}\n\n\t// The SDK runs its own retries by default; this adapter does its own 423-aware\n\t// `retryOnLocked`, so disable the SDK's to avoid compounding backoff.\n\tconst client = createNeonClient({\n\t\tapiKey: options.apiKey,\n\t\tretries: 0,\n\t\t...(options.baseUrl ? { baseUrl: options.baseUrl } : {}),\n\t}).client;\n\n\treturn new RealNeonApi(\n\t\tclient,\n\t\t{\n\t\t\tmaxAttempts: options.retryOnLocked?.maxAttempts ?? 12,\n\t\t\tinitialDelayMs: options.retryOnLocked?.initialDelayMs ?? 250,\n\t\t\tmaxDelayMs: options.retryOnLocked?.maxDelayMs ?? 5_000,\n\t\t},\n\t\t{\n\t\t\tapiKey: options.apiKey,\n\t\t\tbaseUrl: options.baseUrl ?? DEFAULT_NEON_API_BASE_URL,\n\t\t},\n\t);\n}\n\ninterface RetryConfig {\n\tmaxAttempts: number;\n\tinitialDelayMs: number;\n\tmaxDelayMs: number;\n}\n\n/**\n * Retry a function whenever it throws an HTTP 423 (Locked) — Neon's signal that a prior\n * mutation on the same resource is still in flight. Uses exponential backoff capped at\n * `maxDelayMs`. Any other error (and the last attempt) propagates.\n *\n * Exported only for tests; production callers go through the wrapped {@link NeonApi}.\n */\nexport async function retryOnLocked<T>(\n\tfn: () => Promise<T>,\n\tconfig: RetryConfig,\n): Promise<T> {\n\tlet delay = config.initialDelayMs;\n\tlet lastError: unknown;\n\tfor (let attempt = 1; attempt <= config.maxAttempts; attempt++) {\n\t\ttry {\n\t\t\treturn await fn();\n\t\t} catch (err) {\n\t\t\tlastError = err;\n\t\t\tconst status = readHttpStatusFromError(err);\n\t\t\tif (status !== 423 || attempt === config.maxAttempts) throw err;\n\t\t\tawait sleep(delay);\n\t\t\tdelay = Math.min(delay * 2, config.maxDelayMs);\n\t\t}\n\t}\n\tthrow lastError;\n}\n\nfunction readHttpStatusFromError(err: unknown): number | undefined {\n\tif (err === null || typeof err !== \"object\") return undefined;\n\tconst response = (err as { response?: unknown }).response;\n\tif (response === null || typeof response !== \"object\") return undefined;\n\tconst status = (response as { status?: unknown }).status;\n\treturn typeof status === \"number\" ? status : undefined;\n}\n\nfunction sleep(ms: number): Promise<void> {\n\treturn new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nexport async function collectCursorPages<T>(\n\tfetchPage: (\n\t\tcursor: string | undefined,\n\t) => Promise<{ items: T[]; next?: string }>,\n): Promise<T[]> {\n\tconst items: T[] = [];\n\tlet cursor: string | undefined;\n\tfor (;;) {\n\t\tconst page = await fetchPage(cursor);\n\t\titems.push(...page.items);\n\t\tif (!page.next || page.next === cursor) break;\n\t\tcursor = page.next;\n\t}\n\treturn items;\n}\n\nclass RealNeonApi implements NeonApi {\n\tconstructor(\n\t\tprivate readonly client: ApiClient,\n\t\tprivate readonly retryConfig: RetryConfig,\n\t\tprivate readonly restConfig: RestConfig,\n\t) {}\n\n\tprivate retry<T>(fn: () => Promise<T>): Promise<T> {\n\t\treturn retryOnLocked(fn, this.retryConfig);\n\t}\n\n\tprivate async call<T>(\n\t\top: string,\n\t\tfn: () => Promise<T>,\n\t\toptions: { projectId?: string; mutating?: boolean } = {},\n\t): Promise<T> {\n\t\ttry {\n\t\t\treturn options.mutating ? await this.retry(fn) : await fn();\n\t\t} catch (err) {\n\t\t\tconst wrapped = wrapNeonError(\n\t\t\t\terr,\n\t\t\t\toptions.projectId\n\t\t\t\t\t? { op, projectId: options.projectId }\n\t\t\t\t\t: { op },\n\t\t\t);\n\t\t\tthrow wrapped;\n\t\t}\n\t}\n\n\tasync listProjects(filter: {\n\t\torgId?: string;\n\t}): Promise<NeonProjectSnapshot[]> {\n\t\treturn this.call(\n\t\t\tfilter.orgId ? `listProjects(org=${filter.orgId})` : \"listProjects\",\n\t\t\tasync () => {\n\t\t\t\tconst projects: ProjectListItem[] = [];\n\t\t\t\tlet cursor: string | undefined;\n\t\t\t\twhile (true) {\n\t\t\t\t\tconst body = unwrap(\n\t\t\t\t\t\tawait rawListProjects({\n\t\t\t\t\t\t\tclient: this.client,\n\t\t\t\t\t\t\tquery: {\n\t\t\t\t\t\t\t\t...(filter.orgId\n\t\t\t\t\t\t\t\t\t? { org_id: filter.orgId }\n\t\t\t\t\t\t\t\t\t: {}),\n\t\t\t\t\t\t\t\t...(cursor ? { cursor } : {}),\n\t\t\t\t\t\t\t\tlimit: 100,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t}),\n\t\t\t\t\t);\n\t\t\t\t\tprojects.push(...body.projects);\n\t\t\t\t\tconst next = (body as { pagination?: { next?: string } })\n\t\t\t\t\t\t.pagination?.next;\n\t\t\t\t\tif (!next || next === cursor) break;\n\t\t\t\t\tcursor = next;\n\t\t\t\t}\n\t\t\t\treturn projects.map(projectToSnapshot);\n\t\t\t},\n\t\t);\n\t}\n\n\tasync getProject(projectId: string): Promise<NeonProjectSnapshot> {\n\t\treturn this.call(\n\t\t\t`getProject(${projectId})`,\n\t\t\tasync () => {\n\t\t\t\tconst body = unwrap(\n\t\t\t\t\tawait rawGetProject({\n\t\t\t\t\t\tclient: this.client,\n\t\t\t\t\t\tpath: { project_id: projectId },\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t\treturn projectToSnapshot(body.project);\n\t\t\t},\n\t\t\t{ projectId },\n\t\t);\n\t}\n\n\tasync createProject(\n\t\tinput: CreateProjectInput,\n\t): Promise<NeonProjectSnapshot> {\n\t\tconst body: ProjectCreateRequest = {\n\t\t\tproject: {\n\t\t\t\tname: input.name,\n\t\t\t\tregion_id: input.regionId,\n\t\t\t\t...(input.pgVersion !== undefined\n\t\t\t\t\t? { pg_version: input.pgVersion as PgVersion }\n\t\t\t\t\t: {}),\n\t\t\t\t...(input.orgId ? { org_id: input.orgId } : {}),\n\t\t\t\t...(input.defaultEndpointSettings\n\t\t\t\t\t? {\n\t\t\t\t\t\t\tdefault_endpoint_settings:\n\t\t\t\t\t\t\t\tcomputeSettingsToDefaults(\n\t\t\t\t\t\t\t\t\tinput.defaultEndpointSettings,\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t}\n\t\t\t\t\t: {}),\n\t\t\t\t...(input.defaultBranchName\n\t\t\t\t\t? { branch: { name: input.defaultBranchName } }\n\t\t\t\t\t: {}),\n\t\t\t},\n\t\t};\n\t\treturn this.call(\n\t\t\t`createProject(${input.name})`,\n\t\t\tasync () => {\n\t\t\t\tconst data = unwrap(\n\t\t\t\t\tawait rawCreateProject({ client: this.client, body }),\n\t\t\t\t);\n\t\t\t\treturn projectToSnapshot(data.project);\n\t\t\t},\n\t\t\t{ mutating: true },\n\t\t);\n\t}\n\n\tasync updateProject(\n\t\tprojectId: string,\n\t\tinput: { name?: string; defaultEndpointSettings?: ComputeSettings },\n\t): Promise<NeonProjectSnapshot> {\n\t\tconst body: ProjectUpdateRequest = {\n\t\t\tproject: {\n\t\t\t\t...(input.name !== undefined ? { name: input.name } : {}),\n\t\t\t\t...(input.defaultEndpointSettings\n\t\t\t\t\t? {\n\t\t\t\t\t\t\tdefault_endpoint_settings:\n\t\t\t\t\t\t\t\tcomputeSettingsToDefaults(\n\t\t\t\t\t\t\t\t\tinput.defaultEndpointSettings,\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t}\n\t\t\t\t\t: {}),\n\t\t\t},\n\t\t};\n\t\treturn this.call(\n\t\t\t`updateProject(${projectId})`,\n\t\t\tasync () => {\n\t\t\t\tconst data = unwrap(\n\t\t\t\t\tawait rawUpdateProject({\n\t\t\t\t\t\tclient: this.client,\n\t\t\t\t\t\tpath: { project_id: projectId },\n\t\t\t\t\t\tbody,\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t\treturn projectToSnapshot(data.project);\n\t\t\t},\n\t\t\t{ projectId, mutating: true },\n\t\t);\n\t}\n\n\tasync listBranches(projectId: string): Promise<NeonBranchSnapshot[]> {\n\t\treturn this.call(\n\t\t\t`listBranches(${projectId})`,\n\t\t\tasync () => {\n\t\t\t\tconst branches: Branch[] = [];\n\t\t\t\tlet cursor: string | undefined;\n\t\t\t\twhile (true) {\n\t\t\t\t\tconst body = unwrap(\n\t\t\t\t\t\tawait rawListProjectBranches({\n\t\t\t\t\t\t\tclient: this.client,\n\t\t\t\t\t\t\tpath: { project_id: projectId },\n\t\t\t\t\t\t\tquery: {\n\t\t\t\t\t\t\t\tlimit: 100,\n\t\t\t\t\t\t\t\t...(cursor ? { cursor } : {}),\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t}),\n\t\t\t\t\t);\n\t\t\t\t\tbranches.push(...(body.branches as Branch[]));\n\t\t\t\t\tconst next = (body as { pagination?: { next?: string } })\n\t\t\t\t\t\t.pagination?.next;\n\t\t\t\t\tif (!next || next === cursor) break;\n\t\t\t\t\tcursor = next;\n\t\t\t\t}\n\t\t\t\treturn branches.map(branchToSnapshot);\n\t\t\t},\n\t\t\t{ projectId },\n\t\t);\n\t}\n\n\tasync createBranch(\n\t\tprojectId: string,\n\t\tinput: CreateBranchInput,\n\t): Promise<{\n\t\tbranch: NeonBranchSnapshot;\n\t\tendpoints: NeonEndpointSnapshot[];\n\t}> {\n\t\tconst endpointOptions: BranchCreateRequestEndpointOptions | undefined =\n\t\t\tinput.computeSettings\n\t\t\t\t? {\n\t\t\t\t\t\ttype: \"read_write\",\n\t\t\t\t\t\t...computeSettingsToEndpointOptions(\n\t\t\t\t\t\t\tinput.computeSettings,\n\t\t\t\t\t\t),\n\t\t\t\t\t}\n\t\t\t\t: { type: \"read_write\" };\n\n\t\tconst body: BranchCreateRequest = {\n\t\t\tbranch: {\n\t\t\t\tname: input.name,\n\t\t\t\t...(input.parentId ? { parent_id: input.parentId } : {}),\n\t\t\t\t...(input.expiresAt ? { expires_at: input.expiresAt } : {}),\n\t\t\t\t...(input.protected !== undefined\n\t\t\t\t\t? { protected: input.protected }\n\t\t\t\t\t: {}),\n\t\t\t},\n\t\t\tendpoints: [endpointOptions],\n\t\t};\n\t\treturn this.call(\n\t\t\t`createBranch(${projectId}/${input.name})`,\n\t\t\tasync () => {\n\t\t\t\tconst data = unwrap(\n\t\t\t\t\tawait rawCreateProjectBranch({\n\t\t\t\t\t\tclient: this.client,\n\t\t\t\t\t\tpath: { project_id: projectId },\n\t\t\t\t\t\tbody,\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t\treturn {\n\t\t\t\t\tbranch: branchToSnapshot(data.branch),\n\t\t\t\t\tendpoints: (data.endpoints ?? []).map(endpointToSnapshot),\n\t\t\t\t};\n\t\t\t},\n\t\t\t{ projectId, mutating: true },\n\t\t);\n\t}\n\n\tasync updateBranch(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t\tinput: UpdateBranchInput,\n\t): Promise<NeonBranchSnapshot> {\n\t\tconst branch: BranchUpdateRequest[\"branch\"] = {};\n\t\tif (input.name !== undefined) branch.name = input.name;\n\t\tif (input.expiresAt !== undefined) branch.expires_at = input.expiresAt;\n\t\tif (input.protected !== undefined) branch.protected = input.protected;\n\t\treturn this.call(\n\t\t\t`updateBranch(${projectId}/${branchId})`,\n\t\t\tasync () => {\n\t\t\t\tconst data = unwrap(\n\t\t\t\t\tawait rawUpdateProjectBranch({\n\t\t\t\t\t\tclient: this.client,\n\t\t\t\t\t\tpath: { project_id: projectId, branch_id: branchId },\n\t\t\t\t\t\tbody: { branch },\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t\treturn branchToSnapshot(data.branch);\n\t\t\t},\n\t\t\t{ projectId, mutating: true },\n\t\t);\n\t}\n\n\tasync listEndpoints(projectId: string): Promise<NeonEndpointSnapshot[]> {\n\t\treturn this.call(\n\t\t\t`listEndpoints(${projectId})`,\n\t\t\tasync () => {\n\t\t\t\tconst data = unwrap(\n\t\t\t\t\tawait rawListProjectEndpoints({\n\t\t\t\t\t\tclient: this.client,\n\t\t\t\t\t\tpath: { project_id: projectId },\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t\treturn (data.endpoints as Endpoint[]).map(endpointToSnapshot);\n\t\t\t},\n\t\t\t{ projectId },\n\t\t);\n\t}\n\n\tasync updateEndpoint(\n\t\tprojectId: string,\n\t\tendpointId: string,\n\t\tsettings: ComputeSettings,\n\t): Promise<NeonEndpointSnapshot> {\n\t\tconst endpoint: EndpointUpdateRequest[\"endpoint\"] =\n\t\t\tcomputeSettingsToEndpointOptions(settings);\n\t\treturn this.call(\n\t\t\t`updateEndpoint(${projectId}/${endpointId})`,\n\t\t\tasync () => {\n\t\t\t\tconst data = unwrap(\n\t\t\t\t\tawait rawUpdateProjectEndpoint({\n\t\t\t\t\t\tclient: this.client,\n\t\t\t\t\t\tpath: {\n\t\t\t\t\t\t\tproject_id: projectId,\n\t\t\t\t\t\t\tendpoint_id: endpointId,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tbody: { endpoint },\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t\treturn endpointToSnapshot(data.endpoint);\n\t\t\t},\n\t\t\t{ projectId, mutating: true },\n\t\t);\n\t}\n\n\tasync listBranchRoles(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t): Promise<NeonRoleSnapshot[]> {\n\t\treturn this.call(\n\t\t\t`listBranchRoles(${projectId}/${branchId})`,\n\t\t\tasync () => {\n\t\t\t\tconst data = unwrap(\n\t\t\t\t\tawait rawListProjectBranchRoles({\n\t\t\t\t\t\tclient: this.client,\n\t\t\t\t\t\tpath: { project_id: projectId, branch_id: branchId },\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t\treturn (data.roles as Role[]).map(roleToSnapshot);\n\t\t\t},\n\t\t\t{ projectId },\n\t\t);\n\t}\n\n\tasync listBranchDatabases(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t): Promise<NeonDatabaseSnapshot[]> {\n\t\treturn this.call(\n\t\t\t`listBranchDatabases(${projectId}/${branchId})`,\n\t\t\tasync () => {\n\t\t\t\tconst data = unwrap(\n\t\t\t\t\tawait rawListProjectBranchDatabases({\n\t\t\t\t\t\tclient: this.client,\n\t\t\t\t\t\tpath: { project_id: projectId, branch_id: branchId },\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t\treturn (data.databases as Database[]).map(databaseToSnapshot);\n\t\t\t},\n\t\t\t{ projectId },\n\t\t);\n\t}\n\n\tasync getConnectionUri(\n\t\tprojectId: string,\n\t\tinput: GetConnectionUriInput,\n\t): Promise<{ uri: string }> {\n\t\tconst op = `getConnectionUri(${projectId}/${input.databaseName}@${input.roleName}${input.pooled ? \" pooled\" : \"\"})`;\n\t\t// Always send `pooled` explicitly. The Neon API has switched its default\n\t\t// to returning the pooled URI when the parameter is omitted, so we have\n\t\t// to be explicit to get the direct URI back.\n\t\tconst pooled = input.pooled === true;\n\t\treturn this.call(\n\t\t\top,\n\t\t\tasync () => {\n\t\t\t\tconst data = unwrap(\n\t\t\t\t\tawait rawGetConnectionUri({\n\t\t\t\t\t\tclient: this.client,\n\t\t\t\t\t\tpath: { project_id: projectId },\n\t\t\t\t\t\tquery: {\n\t\t\t\t\t\t\tdatabase_name: input.databaseName,\n\t\t\t\t\t\t\trole_name: input.roleName,\n\t\t\t\t\t\t\t...(input.branchId\n\t\t\t\t\t\t\t\t? { branch_id: input.branchId }\n\t\t\t\t\t\t\t\t: {}),\n\t\t\t\t\t\t\t...(input.endpointId\n\t\t\t\t\t\t\t\t? { endpoint_id: input.endpointId }\n\t\t\t\t\t\t\t\t: {}),\n\t\t\t\t\t\t\tpooled,\n\t\t\t\t\t\t},\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t\treturn { uri: data.uri };\n\t\t\t},\n\t\t\t{ projectId },\n\t\t);\n\t}\n\n\tasync getNeonAuth(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t): Promise<NeonAuthSnapshot | null> {\n\t\t// `GET /projects/:pid/branches/:bid/auth` returns 404 when no integration exists.\n\t\t// Surface that as `null` so callers can branch cleanly instead of try/catch.\n\t\ttry {\n\t\t\treturn await this.call(\n\t\t\t\t`getNeonAuth(${projectId}/${branchId})`,\n\t\t\t\tasync () => {\n\t\t\t\t\tconst data = unwrap(\n\t\t\t\t\t\tawait rawGetNeonAuth({\n\t\t\t\t\t\t\tclient: this.client,\n\t\t\t\t\t\t\tpath: {\n\t\t\t\t\t\t\t\tproject_id: projectId,\n\t\t\t\t\t\t\t\tbranch_id: branchId,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t}),\n\t\t\t\t\t);\n\t\t\t\t\treturn neonAuthResponseToSnapshot(\n\t\t\t\t\t\tneonAuthResponseSchema.parse(data),\n\t\t\t\t\t);\n\t\t\t\t},\n\t\t\t\t{ projectId },\n\t\t\t);\n\t\t} catch (err) {\n\t\t\tif (err instanceof PlatformError && err.code === ErrorCode.NotFound)\n\t\t\t\treturn null;\n\t\t\tthrow err;\n\t\t}\n\t}\n\n\tasync enableNeonAuth(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t\tinput: { databaseName?: string } = {},\n\t): Promise<NeonAuthSnapshot> {\n\t\t// Idempotent: if an integration already exists on the branch, the POST returns 409\n\t\t// (`Conflict`). We swallow that and re-fetch the existing snapshot so callers can\n\t\t// rely on `enableNeonAuth` to be safe to invoke from any push, including no-ops.\n\t\t// A 409 with no integration to re-fetch is a failed provisioning and is thrown.\n\t\ttry {\n\t\t\treturn await this.call(\n\t\t\t\t`enableNeonAuth(${projectId}/${branchId})`,\n\t\t\t\tasync () => {\n\t\t\t\t\t// The generated `createNeonAuth` doesn't narrow this branch\n\t\t\t\t\t// endpoint to `better_auth`, so post the REST body directly.\n\t\t\t\t\tconst data = await this.postJson(\n\t\t\t\t\t\t`/projects/${encodeURIComponent(projectId)}/branches/${encodeURIComponent(branchId)}/auth`,\n\t\t\t\t\t\tcreateNeonAuthRestInput(input),\n\t\t\t\t\t);\n\t\t\t\t\tconst parsed = neonAuthResponseSchema.parse(data);\n\t\t\t\t\treturn neonAuthResponseToSnapshot(parsed);\n\t\t\t\t},\n\t\t\t\t{ projectId, mutating: true },\n\t\t\t);\n\t\t} catch (err) {\n\t\t\tif (\n\t\t\t\terr instanceof PlatformError &&\n\t\t\t\terr.code === ErrorCode.Conflict\n\t\t\t) {\n\t\t\t\tconst existing = await this.getNeonAuth(projectId, branchId);\n\t\t\t\tif (existing) return existing;\n\t\t\t\tthrow neonAuthProvisioningConflict(err, projectId, branchId);\n\t\t\t}\n\t\t\tthrow err;\n\t\t}\n\t}\n\n\tprivate async postJson(path: string, body: unknown): Promise<unknown> {\n\t\treturn this.request(\"POST\", path, {\n\t\t\theaders: { \"Content-Type\": \"application/json\" },\n\t\t\tbody: JSON.stringify(body),\n\t\t});\n\t}\n\n\tprivate async patchJson(path: string, body: unknown): Promise<unknown> {\n\t\treturn this.request(\"PATCH\", path, {\n\t\t\theaders: { \"Content-Type\": \"application/json\" },\n\t\t\tbody: JSON.stringify(body),\n\t\t});\n\t}\n\n\tprivate async getJson(\n\t\tpath: string,\n\t\tquery?: Record<string, string | number | undefined>,\n\t): Promise<unknown> {\n\t\treturn this.request(\"GET\", withQuery(path, query));\n\t}\n\n\tprivate async deleteJson(path: string): Promise<unknown> {\n\t\treturn this.request(\"DELETE\", path);\n\t}\n\n\t/**\n\t * Upload a built function bundle via `multipart/form-data` to the deploy endpoint\n\t * (`POST .../functions/{slug}/deployments`). Body shape lives in the pure\n\t * {@link buildFunctionDeployForm} helper so it can be unit-tested against the spec.\n\t */\n\tprivate async postMultipart(\n\t\tpath: string,\n\t\tinput: DeployFunctionInput,\n\t): Promise<unknown> {\n\t\treturn this.request(\"POST\", path, {\n\t\t\tbody: buildFunctionDeployForm(input),\n\t\t});\n\t}\n\n\tprivate async request(\n\t\tmethod: \"GET\" | \"POST\" | \"PATCH\" | \"DELETE\",\n\t\tpath: string,\n\t\tinit: { headers?: Record<string, string>; body?: BodyInit } = {},\n\t): Promise<unknown> {\n\t\tconst url = `${this.restConfig.baseUrl.replace(/\\/+$/, \"\")}${path}`;\n\t\tconst res = await fetch(url, {\n\t\t\tmethod,\n\t\t\theaders: {\n\t\t\t\tAuthorization: `Bearer ${this.restConfig.apiKey}`,\n\t\t\t\t...(init.headers ?? {}),\n\t\t\t},\n\t\t\t...(init.body !== undefined ? { body: init.body } : {}),\n\t\t});\n\t\tconst data = await readJsonBody(res);\n\t\tif (!res.ok) {\n\t\t\tthrow {\n\t\t\t\tresponse: {\n\t\t\t\t\tstatus: res.status,\n\t\t\t\t\tdata,\n\t\t\t\t},\n\t\t\t};\n\t\t}\n\t\treturn data;\n\t}\n\n\tasync getNeonDataApi(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t\tdatabaseName: string,\n\t): Promise<NeonDataApiSnapshot | null> {\n\t\t// Same shape as getNeonAuth — 404 means \"no integration on this branch/db\", which\n\t\t// we translate to `null` for the caller.\n\t\ttry {\n\t\t\treturn await this.call(\n\t\t\t\t`getNeonDataApi(${projectId}/${branchId}/${databaseName})`,\n\t\t\t\tasync () =>\n\t\t\t\t\tdataApiSnapshotFromResponse(\n\t\t\t\t\t\tunwrap(\n\t\t\t\t\t\t\tawait rawGetProjectBranchDataApi({\n\t\t\t\t\t\t\t\tclient: this.client,\n\t\t\t\t\t\t\t\tpath: {\n\t\t\t\t\t\t\t\t\tproject_id: projectId,\n\t\t\t\t\t\t\t\t\tbranch_id: branchId,\n\t\t\t\t\t\t\t\t\tdatabase_name: databaseName,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t),\n\t\t\t\t\t),\n\t\t\t\t{ projectId },\n\t\t\t);\n\t\t} catch (err) {\n\t\t\tif (err instanceof PlatformError && err.code === ErrorCode.NotFound)\n\t\t\t\treturn null;\n\t\t\tthrow err;\n\t\t}\n\t}\n\n\tasync enableProjectBranchDataApi(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t\tdatabaseName: string,\n\t\tinput?: EnableDataApiInput,\n\t): Promise<NeonDataApiSnapshot> {\n\t\t// Idempotent in the same shape as `enableNeonAuth`: if an integration already\n\t\t// exists, the POST returns 409 and we re-fetch the existing snapshot.\n\t\ttry {\n\t\t\treturn await this.call(\n\t\t\t\t`enableProjectBranchDataApi(${projectId}/${branchId}/${databaseName})`,\n\t\t\t\tasync () => {\n\t\t\t\t\tconst data = unwrap(\n\t\t\t\t\t\tawait rawCreateProjectBranchDataApi({\n\t\t\t\t\t\t\tclient: this.client,\n\t\t\t\t\t\t\tpath: {\n\t\t\t\t\t\t\t\tproject_id: projectId,\n\t\t\t\t\t\t\t\tbranch_id: branchId,\n\t\t\t\t\t\t\t\tdatabase_name: databaseName,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tbody: dataApiCreateRequest(input),\n\t\t\t\t\t\t}),\n\t\t\t\t\t);\n\t\t\t\t\t// The create response only carries `url`; settings/status come from a\n\t\t\t\t\t// follow-up GET, which we leave to the caller when it needs them.\n\t\t\t\t\treturn { url: data.url };\n\t\t\t\t},\n\t\t\t\t{ projectId, mutating: true },\n\t\t\t);\n\t\t} catch (err) {\n\t\t\tif (\n\t\t\t\terr instanceof PlatformError &&\n\t\t\t\terr.code === ErrorCode.Conflict\n\t\t\t) {\n\t\t\t\tconst existing = await this.getNeonDataApi(\n\t\t\t\t\tprojectId,\n\t\t\t\t\tbranchId,\n\t\t\t\t\tdatabaseName,\n\t\t\t\t);\n\t\t\t\tif (existing) return existing;\n\t\t\t}\n\t\t\tthrow err;\n\t\t}\n\t}\n\n\tasync updateProjectBranchDataApi(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t\tdatabaseName: string,\n\t\tsettings: DataApiSettings,\n\t): Promise<NeonDataApiSnapshot> {\n\t\treturn await this.call(\n\t\t\t`updateProjectBranchDataApi(${projectId}/${branchId}/${databaseName})`,\n\t\t\tasync () => {\n\t\t\t\tunwrap(\n\t\t\t\t\tawait rawUpdateProjectBranchDataApi({\n\t\t\t\t\t\tclient: this.client,\n\t\t\t\t\t\tpath: {\n\t\t\t\t\t\t\tproject_id: projectId,\n\t\t\t\t\t\t\tbranch_id: branchId,\n\t\t\t\t\t\t\tdatabase_name: databaseName,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tbody: { settings: dataApiSettingsToApi(settings) },\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t\t// The PATCH returns an empty body; re-fetch so the caller sees the\n\t\t\t\t// post-update url/status/settings.\n\t\t\t\tconst data = unwrap(\n\t\t\t\t\tawait rawGetProjectBranchDataApi({\n\t\t\t\t\t\tclient: this.client,\n\t\t\t\t\t\tpath: {\n\t\t\t\t\t\t\tproject_id: projectId,\n\t\t\t\t\t\t\tbranch_id: branchId,\n\t\t\t\t\t\t\tdatabase_name: databaseName,\n\t\t\t\t\t\t},\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t\treturn dataApiSnapshotFromResponse(data);\n\t\t\t},\n\t\t\t{ projectId, mutating: true },\n\t\t);\n\t}\n\n\tasync deleteProjectBranchDataApi(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t\tdatabaseName: string,\n\t): Promise<void> {\n\t\ttry {\n\t\t\tawait this.call(\n\t\t\t\t`deleteProjectBranchDataApi(${projectId}/${branchId}/${databaseName})`,\n\t\t\t\tasync () => {\n\t\t\t\t\tunwrap(\n\t\t\t\t\t\tawait rawDeleteProjectBranchDataApi({\n\t\t\t\t\t\t\tclient: this.client,\n\t\t\t\t\t\t\tpath: {\n\t\t\t\t\t\t\t\tproject_id: projectId,\n\t\t\t\t\t\t\t\tbranch_id: branchId,\n\t\t\t\t\t\t\t\tdatabase_name: databaseName,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t}),\n\t\t\t\t\t);\n\t\t\t\t},\n\t\t\t\t{ projectId, mutating: true },\n\t\t\t);\n\t\t} catch (err) {\n\t\t\tif (err instanceof PlatformError && err.code === ErrorCode.NotFound)\n\t\t\t\treturn;\n\t\t\tthrow err;\n\t\t}\n\t}\n\n\t// ─── Realtime ──────────────────────────────────────────────────────────────\n\n\tasync getProjectBranchRealtime(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t): Promise<NeonRealtimeSnapshot> {\n\t\treturn this.call(\n\t\t\t`getProjectBranchRealtime(${projectId}/${branchId})`,\n\t\t\tasync () =>\n\t\t\t\trealtimeSnapshotFromApi(\n\t\t\t\t\tunwrap(\n\t\t\t\t\t\tawait rawGetProjectBranchRealtime({\n\t\t\t\t\t\t\tclient: this.client,\n\t\t\t\t\t\t\tpath: {\n\t\t\t\t\t\t\t\tproject_id: projectId,\n\t\t\t\t\t\t\t\tbranch_id: branchId,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t}),\n\t\t\t\t\t),\n\t\t\t\t),\n\t\t\t{ projectId },\n\t\t);\n\t}\n\n\tasync getProjectBranchRealtimeSecret(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t): Promise<NeonRealtimeSecret> {\n\t\treturn this.call(\n\t\t\t`getProjectBranchRealtimeSecret(${projectId}/${branchId})`,\n\t\t\tasync () =>\n\t\t\t\trealtimeSecretFromApi(\n\t\t\t\t\tunwrap(\n\t\t\t\t\t\tawait rawGetProjectBranchRealtimeSecret({\n\t\t\t\t\t\t\tclient: this.client,\n\t\t\t\t\t\t\tpath: {\n\t\t\t\t\t\t\t\tproject_id: projectId,\n\t\t\t\t\t\t\t\tbranch_id: branchId,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t}),\n\t\t\t\t\t),\n\t\t\t\t),\n\t\t\t{ projectId },\n\t\t);\n\t}\n\n\tasync enableProjectBranchRealtime(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t\tinput?: ConfigureRealtimeInput,\n\t): Promise<void> {\n\t\tawait this.call(\n\t\t\t`enableProjectBranchRealtime(${projectId}/${branchId})`,\n\t\t\tasync () => {\n\t\t\t\tunwrap(\n\t\t\t\t\tawait rawEnableProjectBranchRealtime({\n\t\t\t\t\t\tclient: this.client,\n\t\t\t\t\t\tpath: {\n\t\t\t\t\t\t\tproject_id: projectId,\n\t\t\t\t\t\t\tbranch_id: branchId,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tbody: realtimeOptionsToApi(input),\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t},\n\t\t\t{ projectId, mutating: true },\n\t\t);\n\t}\n\n\tasync disableProjectBranchRealtime(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t): Promise<void> {\n\t\tawait this.call(\n\t\t\t`disableProjectBranchRealtime(${projectId}/${branchId})`,\n\t\t\tasync () => {\n\t\t\t\tunwrap(\n\t\t\t\t\tawait rawDisableProjectBranchRealtime({\n\t\t\t\t\t\tclient: this.client,\n\t\t\t\t\t\tpath: {\n\t\t\t\t\t\t\tproject_id: projectId,\n\t\t\t\t\t\t\tbranch_id: branchId,\n\t\t\t\t\t\t},\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t},\n\t\t\t{ projectId, mutating: true },\n\t\t);\n\t}\n\n\t// ─── Preview: buckets ──────────────────────────────────────────────────────\n\n\tasync listBranchBuckets(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t): Promise<NeonBucketSnapshot[]> {\n\t\ttry {\n\t\t\treturn await this.call(\n\t\t\t\t`listBranchBuckets(${projectId}/${branchId})`,\n\t\t\t\tasync () => {\n\t\t\t\t\tconst data = await this.getJson(\n\t\t\t\t\t\tbranchPreviewPath(projectId, branchId, \"buckets\"),\n\t\t\t\t\t);\n\t\t\t\t\tconst parsed = bucketsListResponseSchema.parse(data);\n\t\t\t\t\treturn parsed.buckets.map(bucketToSnapshot);\n\t\t\t\t},\n\t\t\t\t{ projectId },\n\t\t\t);\n\t\t} catch (err) {\n\t\t\tthrow previewUnavailableError(err, \"Object storage (buckets)\");\n\t\t}\n\t}\n\n\tasync createBranchBucket(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t\tinput: CreateBucketInput,\n\t): Promise<NeonBucketSnapshot> {\n\t\treturn this.call(\n\t\t\t`createBranchBucket(${projectId}/${branchId}/${input.name})`,\n\t\t\tasync () => {\n\t\t\t\tconst data = await this.postJson(\n\t\t\t\t\tbranchPreviewPath(projectId, branchId, \"buckets\"),\n\t\t\t\t\t{\n\t\t\t\t\t\tname: input.name,\n\t\t\t\t\t\t...(input.accessLevel\n\t\t\t\t\t\t\t? { access_level: input.accessLevel }\n\t\t\t\t\t\t\t: {}),\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t\tconst parsed = bucketResponseSchema.parse(data);\n\t\t\t\treturn bucketToSnapshot(parsed.bucket);\n\t\t\t},\n\t\t\t{ projectId, mutating: true },\n\t\t);\n\t}\n\n\tasync deleteBranchBucket(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t\tbucketName: string,\n\t): Promise<void> {\n\t\tawait this.call(\n\t\t\t`deleteBranchBucket(${projectId}/${branchId}/${bucketName})`,\n\t\t\tasync () => {\n\t\t\t\tawait this.deleteJson(\n\t\t\t\t\t`${branchPreviewPath(projectId, branchId, \"buckets\")}/${encodeURIComponent(bucketName)}`,\n\t\t\t\t);\n\t\t\t},\n\t\t\t{ projectId, mutating: true },\n\t\t);\n\t}\n\n\tasync getProjectBranchStorage(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t): Promise<NeonBranchStorageSnapshot | null> {\n\t\ttry {\n\t\t\treturn await this.call(\n\t\t\t\t`getProjectBranchStorage(${projectId}/${branchId})`,\n\t\t\t\tasync () => {\n\t\t\t\t\tconst data = await this.getJson(\n\t\t\t\t\t\t`/projects/${encodeURIComponent(projectId)}/branches/${encodeURIComponent(branchId)}/storage`,\n\t\t\t\t\t);\n\t\t\t\t\tconst parsed = branchStorageSchema.parse(data);\n\t\t\t\t\treturn {\n\t\t\t\t\t\ts3Endpoint: parsed.s3_endpoint,\n\t\t\t\t\t\tregion: parsed.region,\n\t\t\t\t\t\tforcePathStyle: parsed.force_path_style,\n\t\t\t\t\t};\n\t\t\t\t},\n\t\t\t\t{ projectId },\n\t\t\t);\n\t\t} catch (err) {\n\t\t\t// 404 BranchStorageNotEnabled → storage not usable on this branch; let the\n\t\t\t// caller decide (fetchEnv throws a clear \"enable storage first\" error).\n\t\t\tif (err instanceof PlatformError && err.code === ErrorCode.NotFound)\n\t\t\t\treturn null;\n\t\t\tthrow previewUnavailableError(err, \"Object storage\");\n\t\t}\n\t}\n\n\t// ─── Preview: functions ────────────────────────────────────────────────────\n\n\tasync listBranchFunctions(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t): Promise<NeonFunctionSnapshot[]> {\n\t\ttry {\n\t\t\treturn await this.call(\n\t\t\t\t`listBranchFunctions(${projectId}/${branchId})`,\n\t\t\t\tasync () => {\n\t\t\t\t\tconst data = await this.getJson(\n\t\t\t\t\t\tbranchPreviewPath(projectId, branchId, \"functions\"),\n\t\t\t\t\t);\n\t\t\t\t\tconst parsed = functionsListResponseSchema.parse(data);\n\t\t\t\t\treturn parsed.functions.map(functionToSnapshot);\n\t\t\t\t},\n\t\t\t\t{ projectId },\n\t\t\t);\n\t\t} catch (err) {\n\t\t\tthrow previewUnavailableError(err, \"Functions\");\n\t\t}\n\t}\n\n\tasync deleteBranchFunction(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t\tslug: string,\n\t): Promise<void> {\n\t\tawait this.call(\n\t\t\t`deleteBranchFunction(${projectId}/${branchId}/${slug})`,\n\t\t\tasync () => {\n\t\t\t\tawait this.deleteJson(\n\t\t\t\t\t`${branchPreviewPath(projectId, branchId, \"functions\")}/${encodeURIComponent(slug)}`,\n\t\t\t\t);\n\t\t\t},\n\t\t\t{ projectId, mutating: true },\n\t\t);\n\t}\n\n\tasync deployBranchFunction(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t\tslug: string,\n\t\tinput: DeployFunctionInput,\n\t): Promise<NeonFunctionDeploymentSnapshot> {\n\t\treturn this.call(\n\t\t\t`deployBranchFunction(${projectId}/${branchId}/${slug})`,\n\t\t\tasync () => {\n\t\t\t\tconst data = await this.postMultipart(\n\t\t\t\t\t`${branchPreviewPath(projectId, branchId, \"functions\")}/${encodeURIComponent(slug)}/deployments`,\n\t\t\t\t\tinput,\n\t\t\t\t);\n\t\t\t\tconst parsed = functionDeploymentResponseSchema.parse(data);\n\t\t\t\treturn deploymentToSnapshot(parsed.deployment);\n\t\t\t},\n\t\t\t{ projectId, mutating: true },\n\t\t);\n\t}\n\n\tasync getBranchFunction(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t\tslug: string,\n\t): Promise<NeonFunctionSnapshot> {\n\t\treturn this.call(\n\t\t\t`getBranchFunction(${projectId}/${branchId}/${slug})`,\n\t\t\tasync () => {\n\t\t\t\tconst data = await this.getJson(\n\t\t\t\t\t`${branchPreviewPath(projectId, branchId, \"functions\")}/${encodeURIComponent(slug)}`,\n\t\t\t\t);\n\t\t\t\treturn functionToSnapshot(\n\t\t\t\t\tfunctionGetResponseSchema.parse(data).function,\n\t\t\t\t);\n\t\t\t},\n\t\t\t{ projectId },\n\t\t);\n\t}\n\n\tasync listBranchTriggers(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t): Promise<NeonTriggerSnapshot[]> {\n\t\ttry {\n\t\t\treturn await this.call(\n\t\t\t\t`listBranchTriggers(${projectId}/${branchId})`,\n\t\t\t\tasync () => {\n\t\t\t\t\tconst data = await this.getJson(\n\t\t\t\t\t\ttriggersPath(projectId, branchId),\n\t\t\t\t\t);\n\t\t\t\t\tconst parsed = triggersListResponseSchema.parse(data);\n\t\t\t\t\treturn parsed.triggers.map(triggerToSnapshot);\n\t\t\t\t},\n\t\t\t\t{ projectId },\n\t\t\t);\n\t\t} catch (err) {\n\t\t\tthrow previewUnavailableError(err, \"Function triggers\");\n\t\t}\n\t}\n\n\tasync createBranchTrigger(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t\tinput: CreateTriggerInput,\n\t): Promise<NeonTriggerSnapshot> {\n\t\ttry {\n\t\t\treturn await this.call(\n\t\t\t\t`createBranchTrigger(${projectId}/${branchId}/${input.name})`,\n\t\t\t\tasync () => {\n\t\t\t\t\tconst data = await this.postJson(\n\t\t\t\t\t\ttriggersPath(projectId, branchId),\n\t\t\t\t\t\tcreateTriggerRequestBody(input),\n\t\t\t\t\t);\n\t\t\t\t\tconst parsed = triggerResponseSchema.parse(data);\n\t\t\t\t\treturn triggerToSnapshot(parsed.trigger);\n\t\t\t\t},\n\t\t\t\t{ projectId, mutating: true },\n\t\t\t);\n\t\t} catch (err) {\n\t\t\tthrow previewUnavailableError(err, \"Function triggers\");\n\t\t}\n\t}\n\n\tasync updateBranchTrigger(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t\ttriggerId: string,\n\t\tinput: UpdateTriggerInput,\n\t): Promise<NeonTriggerSnapshot> {\n\t\ttry {\n\t\t\treturn await this.call(\n\t\t\t\t`updateBranchTrigger(${projectId}/${branchId}/${triggerId})`,\n\t\t\t\tasync () => {\n\t\t\t\t\tconst data = await this.patchJson(\n\t\t\t\t\t\t`${triggersPath(projectId, branchId)}/${encodeURIComponent(triggerId)}`,\n\t\t\t\t\t\tupdateTriggerRequestBody(input),\n\t\t\t\t\t);\n\t\t\t\t\tconst parsed = triggerResponseSchema.parse(data);\n\t\t\t\t\treturn triggerToSnapshot(parsed.trigger);\n\t\t\t\t},\n\t\t\t\t{ projectId, mutating: true },\n\t\t\t);\n\t\t} catch (err) {\n\t\t\tthrow previewUnavailableError(err, \"Function triggers\");\n\t\t}\n\t}\n\n\tasync deleteBranchTrigger(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t\ttriggerId: string,\n\t): Promise<void> {\n\t\tawait this.call(\n\t\t\t`deleteBranchTrigger(${projectId}/${branchId}/${triggerId})`,\n\t\t\tasync () => {\n\t\t\t\tawait this.deleteJson(\n\t\t\t\t\t`${triggersPath(projectId, branchId)}/${encodeURIComponent(triggerId)}`,\n\t\t\t\t);\n\t\t\t},\n\t\t\t{ projectId, mutating: true },\n\t\t);\n\t}\n\n\tasync listBranchCustomDomains(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t): Promise<NeonCustomDomainSnapshot[]> {\n\t\ttry {\n\t\t\treturn await this.call(\n\t\t\t\t`listBranchCustomDomains(${projectId}/${branchId})`,\n\t\t\t\tasync () =>\n\t\t\t\t\tcollectCursorPages(async (cursor) => {\n\t\t\t\t\t\tconst data = await this.getJson(\n\t\t\t\t\t\t\tcustomDomainsPath(projectId, branchId),\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tlimit: CUSTOM_DOMAINS_LIST_LIMIT,\n\t\t\t\t\t\t\t\t...(cursor ? { cursor } : {}),\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t);\n\t\t\t\t\t\tconst parsed =\n\t\t\t\t\t\t\tcustomDomainsListResponseSchema.parse(data);\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\titems: parsed.custom_domains.map(\n\t\t\t\t\t\t\t\tcustomDomainToSnapshot,\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t...(parsed.pagination?.next\n\t\t\t\t\t\t\t\t? { next: parsed.pagination.next }\n\t\t\t\t\t\t\t\t: {}),\n\t\t\t\t\t\t};\n\t\t\t\t\t}),\n\t\t\t\t{ projectId },\n\t\t\t);\n\t\t} catch (err) {\n\t\t\tthrow customDomainsUnavailableError(err);\n\t\t}\n\t}\n\n\tasync registerBranchCustomDomain(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t\tinput: { domain: string; functionSlug: string },\n\t): Promise<NeonCustomDomainSnapshot> {\n\t\ttry {\n\t\t\treturn await this.call(\n\t\t\t\t`registerBranchCustomDomain(${projectId}/${branchId}/${input.domain})`,\n\t\t\t\tasync () => {\n\t\t\t\t\tconst data = await this.postJson(\n\t\t\t\t\t\tcustomDomainsPath(projectId, branchId),\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tdomain: input.domain,\n\t\t\t\t\t\t\tentity_type: \"function\",\n\t\t\t\t\t\t\tentity_id: input.functionSlug,\n\t\t\t\t\t\t},\n\t\t\t\t\t);\n\t\t\t\t\treturn customDomainToSnapshot(\n\t\t\t\t\t\tcustomDomainApiSchema.parse(data),\n\t\t\t\t\t);\n\t\t\t\t},\n\t\t\t\t{ projectId, mutating: true },\n\t\t\t);\n\t\t} catch (err) {\n\t\t\tthrow customDomainsUnavailableError(err);\n\t\t}\n\t}\n\n\tasync deleteBranchCustomDomain(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t\tdomain: string,\n\t): Promise<void> {\n\t\ttry {\n\t\t\tawait this.call(\n\t\t\t\t`deleteBranchCustomDomain(${projectId}/${branchId}/${domain})`,\n\t\t\t\tasync () => {\n\t\t\t\t\tawait this.deleteJson(\n\t\t\t\t\t\t`${customDomainsPath(projectId, branchId)}/${encodeURIComponent(domain)}`,\n\t\t\t\t\t);\n\t\t\t\t},\n\t\t\t\t{ projectId, mutating: true },\n\t\t\t);\n\t\t} catch (err) {\n\t\t\tthrow customDomainsUnavailableError(err);\n\t\t}\n\t}\n\n\t// ─── Preview: AI Gateway ───────────────────────────────────────────────────\n\t//\n\t// No methods: the AI Gateway is always available on a branch (credential-gated, not\n\t// per-branch provisioned). There is no control-plane enable/disable/status route — the\n\t// gateway is reached at the branch host with a credential carrying `ai_gateway:invoke`.\n\t// `preview.aiGateway` only drives that credential scope and the\n\t// `NEON_AI_GATEWAY_*` env vars (see `@neon/env`); nothing is provisioned here, so\n\t// `plan` / `apply` never touch an AI Gateway route and can't fail on its availability.\n\n\t// ─── Preview: branch-scoped credentials ──────────────────────────────────\n\n\tasync createCredential(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t\tinput: CreateCredentialInput,\n\t): Promise<NeonCredentialSecret> {\n\t\ttry {\n\t\t\treturn await this.call(\n\t\t\t\t`createCredential(${projectId}/${branchId})`,\n\t\t\t\tasync () => {\n\t\t\t\t\tconst data = await this.postJson(\n\t\t\t\t\t\tcredentialsPath(projectId, branchId),\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tscopes: input.scopes,\n\t\t\t\t\t\t\tprincipal_type: input.principalType,\n\t\t\t\t\t\t\t...(input.functionId\n\t\t\t\t\t\t\t\t? { function_id: input.functionId }\n\t\t\t\t\t\t\t\t: {}),\n\t\t\t\t\t\t\t...(input.name ? { name: input.name } : {}),\n\t\t\t\t\t\t},\n\t\t\t\t\t);\n\t\t\t\t\tconst parsed = createCredentialResponseSchema.parse(data);\n\t\t\t\t\treturn createCredentialToSnapshot(parsed);\n\t\t\t\t},\n\t\t\t\t{ projectId, mutating: true },\n\t\t\t);\n\t\t} catch (err) {\n\t\t\tthrow previewUnavailableError(err, \"Branch credentials\");\n\t\t}\n\t}\n\n\tasync listCredentials(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t): Promise<NeonCredentialMeta[]> {\n\t\ttry {\n\t\t\treturn await this.call(\n\t\t\t\t`listCredentials(${projectId}/${branchId})`,\n\t\t\t\tasync () => {\n\t\t\t\t\tconst data = await this.getJson(\n\t\t\t\t\t\tcredentialsPath(projectId, branchId),\n\t\t\t\t\t);\n\t\t\t\t\tconst parsed = listCredentialsResponseSchema.parse(data);\n\t\t\t\t\treturn parsed.credentials.map(credentialMetaToSnapshot);\n\t\t\t\t},\n\t\t\t\t{ projectId },\n\t\t\t);\n\t\t} catch (err) {\n\t\t\tthrow previewUnavailableError(err, \"Branch credentials\");\n\t\t}\n\t}\n\n\tasync revealCredential(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t\ttokenId: string,\n\t): Promise<NeonCredentialReveal> {\n\t\ttry {\n\t\t\treturn await this.call(\n\t\t\t\t`revealCredential(${projectId}/${branchId}/${tokenId})`,\n\t\t\t\tasync () => {\n\t\t\t\t\tconst data = await this.postJson(\n\t\t\t\t\t\t`${credentialsPath(projectId, branchId)}/${encodeURIComponent(tokenId)}/reveal`,\n\t\t\t\t\t\t{},\n\t\t\t\t\t);\n\t\t\t\t\tconst parsed = revealCredentialResponseSchema.parse(data);\n\t\t\t\t\treturn {\n\t\t\t\t\t\ttokenId: parsed.token_id,\n\t\t\t\t\t\tapiToken: parsed.api_token,\n\t\t\t\t\t\ts3SecretAccessKey: parsed.s3_secret_access_key,\n\t\t\t\t\t};\n\t\t\t\t},\n\t\t\t\t{ projectId, mutating: true },\n\t\t\t);\n\t\t} catch (err) {\n\t\t\tthrow previewUnavailableError(err, \"Branch credentials\");\n\t\t}\n\t}\n\n\tasync revokeCredential(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t\ttokenId: string,\n\t): Promise<void> {\n\t\tawait this.call(\n\t\t\t`revokeCredential(${projectId}/${branchId}/${tokenId})`,\n\t\t\tasync () => {\n\t\t\t\tawait this.deleteJson(\n\t\t\t\t\t`${credentialsPath(projectId, branchId)}/${encodeURIComponent(tokenId)}`,\n\t\t\t\t);\n\t\t\t},\n\t\t\t{ projectId, mutating: true },\n\t\t);\n\t}\n}\n\nfunction branchPreviewPath(\n\tprojectId: string,\n\tbranchId: string,\n\tresource: \"buckets\" | \"functions\",\n): string {\n\treturn `/projects/${encodeURIComponent(projectId)}/branches/${encodeURIComponent(branchId)}/${resource}`;\n}\n\nfunction credentialsPath(projectId: string, branchId: string): string {\n\treturn `/projects/${encodeURIComponent(projectId)}/branches/${encodeURIComponent(branchId)}/credentials`;\n}\n\nfunction triggersPath(projectId: string, branchId: string): string {\n\treturn `/projects/${encodeURIComponent(projectId)}/branches/${encodeURIComponent(branchId)}/triggers`;\n}\n\nfunction customDomainsPath(projectId: string, branchId: string): string {\n\treturn `/projects/${encodeURIComponent(projectId)}/branches/${encodeURIComponent(branchId)}/custom-domains`;\n}\n\nfunction withQuery(\n\tpath: string,\n\tquery?: Record<string, string | number | undefined>,\n): string {\n\tif (!query) return path;\n\tconst params = new URLSearchParams();\n\tfor (const [key, value] of Object.entries(query)) {\n\t\tif (value === undefined) continue;\n\t\tparams.set(key, String(value));\n\t}\n\tconst qs = params.toString();\n\treturn qs.length > 0 ? `${path}?${qs}` : path;\n}\n\nfunction customDomainToSnapshot(\n\tdata: z.infer<typeof customDomainApiSchema>,\n): NeonCustomDomainSnapshot {\n\treturn {\n\t\tdomain: data.domain,\n\t\tentityType: data.entity_type,\n\t\tentityId: data.entity_id,\n\t\tcnameTarget: data.cname_target,\n\t};\n}\n\nfunction triggerToSnapshot(\n\tdata: z.infer<typeof triggerApiSchema>,\n): NeonTriggerSnapshot {\n\tif (data.type === \"schedule\") {\n\t\treturn {\n\t\t\ttype: \"schedule\",\n\t\t\ttriggerId: data.trigger_id,\n\t\t\tname: data.name,\n\t\t\tfunctionSlug: data.function_slug,\n\t\t\tfunctionPath: data.function_path,\n\t\t\tcron: data.schedule.cron,\n\t\t\tenabled: data.enabled,\n\t\t\tinherited: data.inherited,\n\t\t\tnextRunAt: data.next_run_at,\n\t\t};\n\t}\n\treturn {\n\t\ttype: \"storage_object_created\",\n\t\ttriggerId: data.trigger_id,\n\t\tname: data.name,\n\t\tfunctionSlug: data.function_slug,\n\t\tfunctionPath: data.function_path,\n\t\tbucketName: data.storage_object_created.bucket_name,\n\t\t...(data.storage_object_created.prefix !== undefined\n\t\t\t? { prefix: data.storage_object_created.prefix }\n\t\t\t: {}),\n\t\tenabled: data.enabled,\n\t\tinherited: data.inherited,\n\t};\n}\n\nfunction createTriggerRequestBody(\n\tinput: CreateTriggerInput,\n): Record<string, unknown> {\n\tif (input.type === \"storage_object_created\") {\n\t\treturn {\n\t\t\ttype: \"storage_object_created\",\n\t\t\tname: input.name,\n\t\t\tfunction_slug: input.functionSlug,\n\t\t\tstorage_object_created: {\n\t\t\t\tbucket_name: input.bucketName,\n\t\t\t\t...(input.prefix !== undefined ? { prefix: input.prefix } : {}),\n\t\t\t},\n\t\t\t...(input.functionPath !== undefined\n\t\t\t\t? { function_path: input.functionPath }\n\t\t\t\t: {}),\n\t\t\t...(input.enabled !== undefined ? { enabled: input.enabled } : {}),\n\t\t};\n\t}\n\treturn {\n\t\ttype: \"schedule\",\n\t\tname: input.name,\n\t\tfunction_slug: input.functionSlug,\n\t\tschedule: { cron: input.cron },\n\t\t...(input.functionPath !== undefined\n\t\t\t? { function_path: input.functionPath }\n\t\t\t: {}),\n\t\t...(input.enabled !== undefined ? { enabled: input.enabled } : {}),\n\t};\n}\n\nfunction updateTriggerRequestBody(\n\tinput: UpdateTriggerInput,\n): Record<string, unknown> {\n\tif (input.type === \"storage_object_created\") {\n\t\treturn {\n\t\t\ttype: \"storage_object_created\",\n\t\t\t...(input.name !== undefined ? { name: input.name } : {}),\n\t\t\t...(input.functionSlug !== undefined\n\t\t\t\t? { function_slug: input.functionSlug }\n\t\t\t\t: {}),\n\t\t\t...(input.functionPath !== undefined\n\t\t\t\t? { function_path: input.functionPath }\n\t\t\t\t: {}),\n\t\t\t...(input.enabled !== undefined ? { enabled: input.enabled } : {}),\n\t\t\t...(input.bucketName !== undefined\n\t\t\t\t? {\n\t\t\t\t\t\tstorage_object_created: {\n\t\t\t\t\t\t\tbucket_name: input.bucketName,\n\t\t\t\t\t\t\t...(input.prefix !== undefined\n\t\t\t\t\t\t\t\t? { prefix: input.prefix }\n\t\t\t\t\t\t\t\t: {}),\n\t\t\t\t\t\t},\n\t\t\t\t\t}\n\t\t\t\t: {}),\n\t\t};\n\t}\n\treturn {\n\t\ttype: \"schedule\",\n\t\t...(input.name !== undefined ? { name: input.name } : {}),\n\t\t...(input.functionSlug !== undefined\n\t\t\t? { function_slug: input.functionSlug }\n\t\t\t: {}),\n\t\t...(input.cron !== undefined ? { schedule: { cron: input.cron } } : {}),\n\t\t...(input.functionPath !== undefined\n\t\t\t? { function_path: input.functionPath }\n\t\t\t: {}),\n\t\t...(input.enabled !== undefined ? { enabled: input.enabled } : {}),\n\t};\n}\n\nfunction createCredentialToSnapshot(\n\tdata: z.infer<typeof createCredentialResponseSchema>,\n): NeonCredentialSecret {\n\tconst snapshot: NeonCredentialSecret = {\n\t\ttokenId: data.token_id,\n\t\ttokenIdShort: data.token_id_short,\n\t\tapiToken: data.api_token,\n\t\ts3SecretAccessKey: data.s3_secret_access_key,\n\t\tscopes: data.scopes,\n\t\tbranchId: data.branch_id,\n\t\tcreatedAt: data.created_at,\n\t};\n\tif (data.name !== undefined) snapshot.name = data.name;\n\tif (data.expires_at !== undefined) snapshot.expiresAt = data.expires_at;\n\treturn snapshot;\n}\n\nfunction credentialMetaToSnapshot(\n\tdata: z.infer<typeof credentialMetaSchema>,\n): NeonCredentialMeta {\n\tconst snapshot: NeonCredentialMeta = {\n\t\ttokenId: data.token_id,\n\t\ttokenIdShort: data.token_id_short,\n\t\tscopes: data.scopes,\n\t\tprincipalType: data.principal_type,\n\t\tcreatedAt: data.created_at,\n\t};\n\tif (data.name !== undefined) snapshot.name = data.name;\n\tif (data.function_id !== undefined) snapshot.functionId = data.function_id;\n\tif (data.branch_id !== undefined) snapshot.branchId = data.branch_id;\n\tif (data.last_used_at !== undefined)\n\t\tsnapshot.lastUsedAt = data.last_used_at;\n\tif (data.revoked_at !== undefined) snapshot.revokedAt = data.revoked_at;\n\tif (data.expires_at !== undefined) snapshot.expiresAt = data.expires_at;\n\treturn snapshot;\n}\n\nfunction bucketToSnapshot(\n\tbucket: z.infer<typeof bucketSchema>,\n): NeonBucketSnapshot {\n\treturn {\n\t\tname: bucket.name,\n\t\taccessLevel: normalizeBucketAccessLevel(bucket.access_level),\n\t};\n}\n\n/**\n * The Neon API returns `access_level` as a free-form string (per the API guidelines:\n * responses use plain strings, not enums). Map the known values onto our union and treat\n * anything else as `private` — the safe default for an unrecognised access level.\n */\nfunction normalizeBucketAccessLevel(\n\tvalue: string | undefined,\n): BucketAccessLevel {\n\treturn value === \"public_read\" ? \"public_read\" : \"private\";\n}\n\nfunction functionToSnapshot(\n\tfn: z.infer<typeof neonFunctionSchema>,\n): NeonFunctionSnapshot {\n\tconst snapshot: NeonFunctionSnapshot = {\n\t\tid: fn.id,\n\t\tslug: fn.slug,\n\t\tname: fn.name,\n\t\tinvocationUrl: fn.invocation_url,\n\t};\n\tif (fn.active_deployment) {\n\t\tsnapshot.activeDeploymentId = fn.active_deployment.id;\n\t}\n\tif (fn.current_deployment) {\n\t\tsnapshot.currentDeployment = deploymentToSnapshot(\n\t\t\tfn.current_deployment,\n\t\t);\n\t}\n\treturn snapshot;\n}\n\nfunction deploymentToSnapshot(\n\tdeployment: z.infer<typeof functionDeploymentSchema>,\n): NeonFunctionDeploymentSnapshot {\n\treturn {\n\t\tid: deployment.id,\n\t\tstatus: normalizeDeploymentStatus(deployment.status),\n\t};\n}\n\nfunction normalizeDeploymentStatus(\n\tvalue: string,\n): NeonFunctionDeploymentSnapshot[\"status\"] {\n\tswitch (value) {\n\t\tcase \"pending\":\n\t\tcase \"building\":\n\t\tcase \"completed\":\n\t\tcase \"failed\":\n\t\t\treturn value;\n\t\tdefault:\n\t\t\t// Unknown status from a newer server — surface as `pending` rather than throwing,\n\t\t\t// matching the API guideline that clients treat undocumented enum values leniently.\n\t\t\treturn \"pending\";\n\t}\n}\n\n/**\n * Whether an error from a Preview-feature read means the feature simply isn't available\n * for this project/branch/region (as opposed to a real, transient failure). Neon signals\n * this a few ways: a 404 \"this route does not exist\" (the route isn't deployed at all), or\n * a 503/4xx whose message says the platform feature is \"not available\" / \"not enabled\".\n *\n * Callers do **not** swallow this into an empty result — touching a Preview feature that\n * isn't available is surfaced as a {@link previewUnavailableError} so `plan` / `status` /\n * `pull` (and `neon dev`) fail clearly instead of, say, planning to create resources the\n * API will refuse to create.\n */\nexport function isPreviewFeatureUnavailable(err: unknown): boolean {\n\tif (!(err instanceof PlatformError)) return false;\n\tconst status = err.details.status;\n\tconst message =\n\t\ttypeof err.details.neonMessage === \"string\"\n\t\t\t? err.details.neonMessage.toLowerCase()\n\t\t\t: \"\";\n\tconst mentionsUnavailable =\n\t\tmessage.includes(\"not available\") ||\n\t\tmessage.includes(\"does not exist\") ||\n\t\tmessage.includes(\"not enabled\");\n\treturn (\n\t\tmentionsUnavailable &&\n\t\t(status === 503 || status === 404 || status === 501)\n\t);\n}\n\n/**\n * Reason phrase for the handful of HTTP statuses a Preview-feature read can surface as\n * \"unavailable\". Used to print a short `HTTP <status> <reason>` line (not a stack trace),\n * so the message reads like the API response the user would see in a tool like curl.\n */\nconst HTTP_STATUS_TEXT: Record<number, string> = {\n\t401: \"Unauthorized\",\n\t403: \"Forbidden\",\n\t404: \"Not Found\",\n\t500: \"Internal Server Error\",\n\t501: \"Not Implemented\",\n\t503: \"Service Unavailable\",\n};\n\nconst PLATFORM_FEATURE_REGIONS =\n\t\"AWS US East (Ohio) (`aws-us-east-2`), AWS US East (N. Virginia) (`aws-us-east-1`), AWS Europe (Frankfurt) (`aws-eu-central-1`), and AWS Asia Pacific (Singapore) (`aws-ap-southeast-1`)\";\n\nconst PLATFORM_FEATURE_REGION_GUIDANCE =\n\t\"Neon features (Functions, Object Storage, and the AI Gateway) are currently only available in \" +\n\t`${PLATFORM_FEATURE_REGIONS}; more regions are coming shortly. Run \\`neon link\\` to link or create a new project in one of those regions.`;\n\nconst PLATFORM_FEATURE_REGION_GUIDANCE_SHORT =\n\t\"Neon features are currently only available in \" +\n\t`${PLATFORM_FEATURE_REGIONS}; more regions are coming shortly. Run \\`neon link\\` to link or create a new project in one of those regions.`;\n\n/**\n * True when the Neon API body indicates the feature isn't deployed for this project's\n * region (as opposed to a transient 503 incident).\n */\nfunction isRegionUnavailableNeonMessage(\n\tneonMessage: string | undefined,\n): boolean {\n\tif (!neonMessage) return false;\n\tconst lower = neonMessage.toLowerCase();\n\treturn (\n\t\tlower.includes(\"not available for this region\") ||\n\t\tlower.includes(\"not available for this project\") ||\n\t\tlower.includes(\"platform functions not available\") ||\n\t\tlower.includes(\"platform service not available\")\n\t);\n}\n\n/**\n * Per-status guidance for a platform feature that came back \"unavailable\". These features\n * roll out region by region, so we tailor the next step instead of emitting one catch-all:\n *\n * - 404 / 501, or an API message that names region/project unavailability — the route\n * isn't deployed for this project's region.\n * - 503 without a region-unavailable body — the route exists but is refusing right now;\n * Neon may be having a transient incident. Retry; if it persists check neonstatus.com.\n * - anything else — point at the region requirement.\n *\n * Only statuses {@link isPreviewFeatureUnavailable} accepts (404/501/503) actually reach\n * this, so there is intentionally no 401/403 branch — those never classify as \"unavailable\".\n */\nfunction platformFeatureUnavailableHint(\n\tstatus: number | undefined,\n\tneonMessage: string | undefined,\n): string {\n\tif (\n\t\tisRegionUnavailableNeonMessage(neonMessage) ||\n\t\tstatus === 404 ||\n\t\tstatus === 501\n\t) {\n\t\treturn PLATFORM_FEATURE_REGION_GUIDANCE;\n\t}\n\tif (status === 503) {\n\t\treturn \"The endpoint is reachable but refused the request — Neon may be having a transient incident. Retry shortly; if it keeps failing, check https://neonstatus.com and contact Neon support.\";\n\t}\n\treturn PLATFORM_FEATURE_REGION_GUIDANCE_SHORT;\n}\n\nconst CUSTOM_DOMAINS_UNAVAILABLE_HINT =\n\t\"Custom domains are enabled per project; deploying functions does not enable them. Remove `customDomains` from the function in neon.ts to continue deploying functions.\";\n\n/**\n * Custom-domain 404s in Functions-capable regions are project enablement, not a\n * missing-region problem.\n */\nexport function customDomainsUnavailableError(err: unknown): unknown {\n\tif (!isPreviewFeatureUnavailable(err)) return err;\n\tconst details = err instanceof PlatformError ? err.details : {};\n\tconst status =\n\t\ttypeof details.status === \"number\" ? details.status : undefined;\n\tconst neonMessage =\n\t\ttypeof details.neonMessage === \"string\"\n\t\t\t? details.neonMessage\n\t\t\t: undefined;\n\tconst requestId =\n\t\ttypeof details.requestId === \"string\" ? details.requestId : undefined;\n\n\tconst statusText = status ? HTTP_STATUS_TEXT[status] : undefined;\n\tconst apiParts = [\n\t\tstatus\n\t\t\t? `HTTP ${status}${statusText ? ` ${statusText}` : \"\"}`\n\t\t\t: undefined,\n\t\tneonMessage ? `Neon API said: \"${neonMessage}\"` : undefined,\n\t\trequestId ? `request id ${requestId}` : undefined,\n\t].filter((part): part is string => part !== undefined);\n\tconst apiContext = apiParts.length > 0 ? ` (${apiParts.join(\"; \")})` : \"\";\n\n\tconst hint =\n\t\tstatus === 503 && !isRegionUnavailableNeonMessage(neonMessage)\n\t\t\t? \"The endpoint is reachable but refused the request — Neon may be having a transient incident. Retry shortly; if it keeps failing, check https://neonstatus.com and contact Neon support.\"\n\t\t\t: CUSTOM_DOMAINS_UNAVAILABLE_HINT;\n\n\treturn new PlatformError(\n\t\tErrorCode.FeatureUnavailable,\n\t\t[\n\t\t\t`Custom domains aren't available for this Neon project${apiContext}.`,\n\t\t\thint,\n\t\t].join(\" \"),\n\t\t{\n\t\t\tcause: err,\n\t\t\tdetails: {\n\t\t\t\tfeature: \"Custom domains\",\n\t\t\t\t...(status !== undefined ? { status } : {}),\n\t\t\t\t...(requestId !== undefined ? { requestId } : {}),\n\t\t\t},\n\t\t},\n\t);\n}\n\n/**\n * Convert a Preview-feature error into a clear {@link PlatformError} when the feature is\n * unavailable for the project; otherwise pass the original error through unchanged so a\n * genuine failure (auth, transient 5xx, …) keeps its specific code and message.\n *\n * The message names the failing feature, summarizes the response in one short\n * `HTTP <status> <reason>` line, includes the raw Neon API message + request id,\n * gives status-specific guidance (see {@link platformFeatureUnavailableHint}),\n * and offers removing the feature from the policy as an escape hatch.\n * `status`/`requestId` are also kept on `details` for programmatic consumers.\n */\nexport function previewUnavailableError(\n\terr: unknown,\n\tfeatureLabel: string,\n): unknown {\n\tif (!isPreviewFeatureUnavailable(err)) return err;\n\tconst details = err instanceof PlatformError ? err.details : {};\n\tconst status =\n\t\ttypeof details.status === \"number\" ? details.status : undefined;\n\tconst neonMessage =\n\t\ttypeof details.neonMessage === \"string\"\n\t\t\t? details.neonMessage\n\t\t\t: undefined;\n\tconst requestId =\n\t\ttypeof details.requestId === \"string\" ? details.requestId : undefined;\n\n\t// One short status line + the raw API message + request id — never a stack trace.\n\tconst statusText = status ? HTTP_STATUS_TEXT[status] : undefined;\n\tconst apiParts = [\n\t\tstatus\n\t\t\t? `HTTP ${status}${statusText ? ` ${statusText}` : \"\"}`\n\t\t\t: undefined,\n\t\tneonMessage ? `Neon API said: \"${neonMessage}\"` : undefined,\n\t\trequestId ? `request id ${requestId}` : undefined,\n\t].filter((part): part is string => part !== undefined);\n\tconst apiContext = apiParts.length > 0 ? ` (${apiParts.join(\"; \")})` : \"\";\n\n\treturn new PlatformError(\n\t\tErrorCode.FeatureUnavailable,\n\t\t[\n\t\t\t`${featureLabel} isn't available for this Neon project${apiContext}.`,\n\t\t\tplatformFeatureUnavailableHint(status, neonMessage),\n\t\t\t\"If you don't need it, remove the corresponding feature from your neon.ts and re-run.\",\n\t\t].join(\" \"),\n\t\t{\n\t\t\tcause: err,\n\t\t\tdetails: {\n\t\t\t\tfeature: featureLabel,\n\t\t\t\t...(status !== undefined ? { status } : {}),\n\t\t\t\t...(requestId !== undefined ? { requestId } : {}),\n\t\t\t},\n\t\t},\n\t);\n}\n\nfunction neonAuthResponseToSnapshot(\n\tdata: z.infer<typeof neonAuthResponseSchema>,\n): NeonAuthSnapshot {\n\tconst snapshot: NeonAuthSnapshot = {\n\t\tprojectId: data.auth_provider_project_id,\n\t\tjwksUrl: data.jwks_url,\n\t};\n\tif (data.pub_client_key !== undefined) {\n\t\tsnapshot.publishableClientKey = data.pub_client_key;\n\t}\n\tif (data.secret_server_key !== undefined) {\n\t\tsnapshot.secretServerKey = data.secret_server_key;\n\t}\n\tif (data.base_url) snapshot.baseUrl = data.base_url;\n\treturn snapshot;\n}\n\n/**\n * A 409 from enabling Neon Auth on a branch that still has no integration. The cause is\n * whatever the API says (for example an existing `neon_auth` schema), so its message replaces\n * the generic name-collision hint that `wrapNeonError` adds to every 409.\n */\nfunction neonAuthProvisioningConflict(\n\terr: PlatformError,\n\tprojectId: string,\n\tbranchId: string,\n): PlatformError {\n\tconst { neonMessage, requestId } = err.details;\n\tconst requestIdSuffix =\n\t\ttypeof requestId === \"string\" ? ` (request id ${requestId})` : \"\";\n\tconst reason =\n\t\ttypeof neonMessage === \"string\"\n\t\t\t? `Neon API said: \"${neonMessage}\"${requestIdSuffix}.`\n\t\t\t: `Neon Auth is not enabled on this branch and could not be provisioned (HTTP 409)${requestIdSuffix}.`;\n\treturn new PlatformError(\n\t\tErrorCode.Conflict,\n\t\t`enableNeonAuth(${projectId}/${branchId}) failed: ${reason}`,\n\t\t{ cause: err, details: err.details },\n\t);\n}\n\nexport function createNeonAuthRestInput(input: {\n\tdatabaseName?: string;\n}): CreateNeonAuthRestInput {\n\treturn {\n\t\tauth_provider: \"better_auth\",\n\t\t...(input.databaseName ? { database_name: input.databaseName } : {}),\n\t};\n}\n\n/**\n * Build the `multipart/form-data` body for a function deployment, matching the public\n * `FunctionDeployRequest` schema (`POST .../functions/{slug}/deployments`):\n *\n * - `zip` — the bundle as a binary part (named `bundle.zip`).\n * - `runtime` — the function runtime.\n * - `environment` — a single JSON-encoded string→string map (multipart can't carry a typed\n * object part), omitted entirely when there are no env vars.\n *\n * Pure (no I/O) so it can be unit-tested against the spec without stubbing `fetch`.\n */\nexport function buildFunctionDeployForm(input: DeployFunctionInput): FormData {\n\tconst form = new FormData();\n\tform.set(\n\t\t\"zip\",\n\t\tnew Blob([input.bundle as BlobPart], { type: \"application/zip\" }),\n\t\t\"bundle.zip\",\n\t);\n\tform.set(\"runtime\", input.runtime);\n\tif (Object.keys(input.environment).length > 0) {\n\t\tform.set(\"environment\", JSON.stringify(input.environment));\n\t}\n\treturn form;\n}\n\n/**\n * Read a response body as JSON, tolerating non-JSON. Some Neon routes return a plain-text\n * body (e.g. a 404 `\"this route does not exist\"` for a Preview feature not enabled in the\n * project/region). Parsing that with `JSON.parse` used to throw a cryptic\n * `SyntaxError: Unexpected token …`, which — because parsing happens before the `res.ok`\n * check in {@link request} — masked the real HTTP status. We instead return the raw text\n * wrapped as `{ message }` so the status-based error path in `request` / `wrapNeonError`\n * runs and produces a proper {@link PlatformError} (e.g. `NotFound`), and a non-error body\n * that simply isn't JSON degrades to text rather than crashing.\n */\nexport async function readJsonBody(res: Response): Promise<unknown> {\n\tconst text = await res.text();\n\tif (text.trim() === \"\") return {};\n\ttry {\n\t\treturn JSON.parse(text);\n\t} catch {\n\t\treturn { message: text.trim() };\n\t}\n}\n\nfunction projectToSnapshot(\n\tproject: Project | ProjectListItem,\n): NeonProjectSnapshot {\n\tconst defaults = project.default_endpoint_settings;\n\tconst snapshot: NeonProjectSnapshot = {\n\t\tid: project.id,\n\t\tname: project.name,\n\t\tregionId: project.region_id,\n\t\tpgVersion: project.pg_version,\n\t};\n\tif (project.org_id) snapshot.orgId = project.org_id;\n\tif (defaults) {\n\t\tconst compute = defaultsToComputeSettings(defaults);\n\t\tif (compute) snapshot.defaultEndpointSettings = compute;\n\t}\n\treturn snapshot;\n}\n\nfunction branchToSnapshot(branch: Branch): NeonBranchSnapshot {\n\tconst snapshot: NeonBranchSnapshot = {\n\t\tid: branch.id,\n\t\tname: branch.name,\n\t\tisDefault: branch.default,\n\t\tprotected: branch.protected === true,\n\t};\n\tif (branch.parent_id) snapshot.parentId = branch.parent_id;\n\tif (branch.expires_at) snapshot.expiresAt = branch.expires_at;\n\treturn snapshot;\n}\n\nfunction endpointToSnapshot(endpoint: Endpoint): NeonEndpointSnapshot {\n\treturn {\n\t\tid: endpoint.id,\n\t\tbranchId: endpoint.branch_id,\n\t\ttype: endpoint.type === \"read_only\" ? \"read_only\" : \"read_write\",\n\t\tautoscalingLimitMinCu:\n\t\t\tendpoint.autoscaling_limit_min_cu as ComputeSettings[\"autoscalingLimitMinCu\"],\n\t\tautoscalingLimitMaxCu:\n\t\t\tendpoint.autoscaling_limit_max_cu as ComputeSettings[\"autoscalingLimitMaxCu\"],\n\t\tsuspendTimeout: formatSuspendTimeout(endpoint.suspend_timeout_seconds),\n\t};\n}\n\nfunction roleToSnapshot(role: Role): NeonRoleSnapshot {\n\treturn {\n\t\tname: role.name,\n\t\tbranchId: role.branch_id,\n\t\tprotected: role.protected ?? false,\n\t};\n}\n\nfunction databaseToSnapshot(database: Database): NeonDatabaseSnapshot {\n\treturn {\n\t\tname: database.name,\n\t\tbranchId: database.branch_id,\n\t\townerName: database.owner_name,\n\t};\n}\n\nfunction computeSettingsToDefaults(\n\tsettings: ComputeSettings,\n): DefaultEndpointSettings {\n\tconst out: DefaultEndpointSettings = {};\n\tif (settings.autoscalingLimitMinCu !== undefined)\n\t\tout.autoscaling_limit_min_cu = settings.autoscalingLimitMinCu;\n\tif (settings.autoscalingLimitMaxCu !== undefined)\n\t\tout.autoscaling_limit_max_cu = settings.autoscalingLimitMaxCu;\n\tif (settings.suspendTimeout !== undefined) {\n\t\tconst parsed = parseSuspendTimeout(settings.suspendTimeout);\n\t\tif (\"error\" in parsed) {\n\t\t\tthrow new PlatformError(\n\t\t\t\tErrorCode.InvalidConfig,\n\t\t\t\t`Invalid suspendTimeout: ${parsed.error}`,\n\t\t\t);\n\t\t}\n\t\tout.suspend_timeout_seconds = parsed.seconds;\n\t}\n\treturn out;\n}\n\nfunction computeSettingsToEndpointOptions(settings: ComputeSettings): {\n\tautoscaling_limit_min_cu?: number;\n\tautoscaling_limit_max_cu?: number;\n\tsuspend_timeout_seconds?: number;\n} {\n\tconst out: {\n\t\tautoscaling_limit_min_cu?: number;\n\t\tautoscaling_limit_max_cu?: number;\n\t\tsuspend_timeout_seconds?: number;\n\t} = {};\n\tif (settings.autoscalingLimitMinCu !== undefined)\n\t\tout.autoscaling_limit_min_cu = settings.autoscalingLimitMinCu;\n\tif (settings.autoscalingLimitMaxCu !== undefined)\n\t\tout.autoscaling_limit_max_cu = settings.autoscalingLimitMaxCu;\n\tif (settings.suspendTimeout !== undefined) {\n\t\tconst parsed = parseSuspendTimeout(settings.suspendTimeout);\n\t\tif (\"error\" in parsed) {\n\t\t\tthrow new PlatformError(\n\t\t\t\tErrorCode.InvalidConfig,\n\t\t\t\t`Invalid suspendTimeout: ${parsed.error}`,\n\t\t\t);\n\t\t}\n\t\tout.suspend_timeout_seconds = parsed.seconds;\n\t}\n\treturn out;\n}\n\nfunction defaultsToComputeSettings(\n\tdefaults: DefaultEndpointSettings,\n): ComputeSettings | undefined {\n\tconst out: ComputeSettings = {};\n\tif (defaults.autoscaling_limit_min_cu !== undefined)\n\t\tout.autoscalingLimitMinCu =\n\t\t\tdefaults.autoscaling_limit_min_cu as ComputeSettings[\"autoscalingLimitMinCu\"];\n\tif (defaults.autoscaling_limit_max_cu !== undefined)\n\t\tout.autoscalingLimitMaxCu =\n\t\t\tdefaults.autoscaling_limit_max_cu as ComputeSettings[\"autoscalingLimitMaxCu\"];\n\tif (defaults.suspend_timeout_seconds !== undefined)\n\t\tout.suspendTimeout = formatSuspendTimeout(\n\t\t\tdefaults.suspend_timeout_seconds,\n\t\t);\n\treturn Object.keys(out).length > 0 ? out : undefined;\n}\n"],"mappings":"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"}
|
package/dist/lib/neon-api.d.ts
CHANGED
|
@@ -94,6 +94,13 @@ interface NeonAuthSnapshot {
|
|
|
94
94
|
/** Optional base URL of the Neon Auth deployment. */
|
|
95
95
|
baseUrl?: string;
|
|
96
96
|
}
|
|
97
|
+
/**
|
|
98
|
+
* How a live Data API verifies tokens, in the Neon API's own spelling: `neon_auth` is Neon
|
|
99
|
+
* Auth, `external` a third-party IdP's JWKS, `none` a Data API created without a provider.
|
|
100
|
+
* Distinct from the policy-side {@link DataApiAuthProvider} (`"neon"` / `"external"`), which
|
|
101
|
+
* has no way to say "none".
|
|
102
|
+
*/
|
|
103
|
+
type RemoteDataApiAuthProvider = "neon_auth" | "external" | "none";
|
|
97
104
|
/**
|
|
98
105
|
* Public, fetchable bits of a Neon Data API integration on a specific branch — the subset of
|
|
99
106
|
* the Neon API `DataAPIReponse` we model. `settings` is only populated for SubZero-backed
|
|
@@ -107,6 +114,16 @@ interface NeonDataApiSnapshot {
|
|
|
107
114
|
status?: string;
|
|
108
115
|
/** Current runtime settings (SubZero only); `null`/absent when not reported. */
|
|
109
116
|
settings?: DataApiSettings | null;
|
|
117
|
+
/**
|
|
118
|
+
* The auth provider the Data API was created with, when the API reports it. Absent for
|
|
119
|
+
* Data APIs created before the API recorded it — callers that need an answer fall back to
|
|
120
|
+
* the branch's Neon Auth state.
|
|
121
|
+
*/
|
|
122
|
+
authProvider?: RemoteDataApiAuthProvider;
|
|
123
|
+
/** External-provider wiring, reported only alongside `authProvider: "external"`. */
|
|
124
|
+
jwksUrl?: string;
|
|
125
|
+
providerName?: string;
|
|
126
|
+
jwtAudience?: string;
|
|
110
127
|
}
|
|
111
128
|
/**
|
|
112
129
|
* Input for {@link NeonApi.enableProjectBranchDataApi} — the create-time wiring for a Data
|
|
@@ -486,5 +503,5 @@ interface NeonApi {
|
|
|
486
503
|
*/
|
|
487
504
|
revokeCredential(projectId: string, branchId: string, tokenId: string): Promise<void>;
|
|
488
505
|
}
|
|
489
|
-
export { ConfigureRealtimeInput, CreateBranchInput, CreateBucketInput, CreateCredentialInput, CreateProjectInput, CreateTriggerInput, DeployFunctionInput, EnableDataApiInput, GetConnectionUriInput, NeonApi, NeonAuthSnapshot, NeonBranchSnapshot, NeonBranchStorageSnapshot, NeonBucketSnapshot, NeonCredentialMeta, NeonCredentialReveal, NeonCredentialSecret, NeonCustomDomainSnapshot, NeonDataApiSnapshot, NeonDatabaseSnapshot, NeonEndpointSnapshot, NeonFunctionDeploymentSnapshot, NeonFunctionSnapshot, NeonProjectSnapshot, NeonRealtimeSecret, NeonRealtimeSnapshot, NeonRoleSnapshot, NeonScheduleTriggerSnapshot, NeonStorageObjectCreatedTriggerSnapshot, NeonTriggerSnapshot, UpdateBranchInput, UpdateTriggerInput };
|
|
506
|
+
export { ConfigureRealtimeInput, CreateBranchInput, CreateBucketInput, CreateCredentialInput, CreateProjectInput, CreateTriggerInput, DeployFunctionInput, EnableDataApiInput, GetConnectionUriInput, NeonApi, NeonAuthSnapshot, NeonBranchSnapshot, NeonBranchStorageSnapshot, NeonBucketSnapshot, NeonCredentialMeta, NeonCredentialReveal, NeonCredentialSecret, NeonCustomDomainSnapshot, NeonDataApiSnapshot, NeonDatabaseSnapshot, NeonEndpointSnapshot, NeonFunctionDeploymentSnapshot, NeonFunctionSnapshot, NeonProjectSnapshot, NeonRealtimeSecret, NeonRealtimeSnapshot, NeonRoleSnapshot, NeonScheduleTriggerSnapshot, NeonStorageObjectCreatedTriggerSnapshot, NeonTriggerSnapshot, RemoteDataApiAuthProvider, UpdateBranchInput, UpdateTriggerInput };
|
|
490
507
|
//# sourceMappingURL=neon-api.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"neon-api.d.ts","names":["BucketAccessLevel","ComputeSettings","CredentialPrincipalType","CredentialScope","DataApiAuthProvider","DataApiSettings","FunctionRuntime","NeonProjectSnapshot","NeonBranchSnapshot","NeonEndpointSnapshot","CreateProjectInput","CreateBranchInput","UpdateBranchInput","NeonRoleSnapshot","NeonDatabaseSnapshot","NeonAuthSnapshot","NeonDataApiSnapshot","EnableDataApiInput","NeonRealtimeSnapshot","NeonRealtimeSecret","ConfigureRealtimeInput","NeonBucketSnapshot","NeonBranchStorageSnapshot","CreateBucketInput","NeonFunctionSnapshot","NeonFunctionDeploymentSnapshot","DeployFunctionInput","Uint8Array","Record","NeonTriggerSnapshotBase","NeonScheduleTriggerSnapshot","NeonStorageObjectCreatedTriggerSnapshot","NeonTriggerSnapshot","CreateTriggerInput","UpdateTriggerInput","NeonCustomDomainSnapshot","CreateCredentialInput","NeonCredentialSecret","NeonCredentialReveal","NeonCredentialMeta","GetConnectionUriInput","NeonApi","Promise","BucketAccessLevel","ComputeSettings","CredentialPrincipalType","CredentialScope","DataApiAuthProvider","DataApiSettings","FunctionRuntime","NeonProjectSnapshot","id","name","regionId","pgVersion","orgId","defaultEndpointSettings","NeonBranchSnapshot","parentId","isDefault","protected","expiresAt","NeonEndpointSnapshot","branchId","type","autoscalingLimitMinCu","autoscalingLimitMaxCu","suspendTimeout","CreateProjectInput","defaultBranchName","CreateBranchInput","computeSettings","UpdateBranchInput","NeonRoleSnapshot","NeonDatabaseSnapshot","ownerName","NeonAuthSnapshot","projectId","publishableClientKey","secretServerKey","jwksUrl","baseUrl","NeonDataApiSnapshot","url","status","settings","
|
|
1
|
+
{"version":3,"file":"neon-api.d.ts","names":["BucketAccessLevel","ComputeSettings","CredentialPrincipalType","CredentialScope","DataApiAuthProvider","DataApiSettings","FunctionRuntime","NeonProjectSnapshot","NeonBranchSnapshot","NeonEndpointSnapshot","CreateProjectInput","CreateBranchInput","UpdateBranchInput","NeonRoleSnapshot","NeonDatabaseSnapshot","NeonAuthSnapshot","RemoteDataApiAuthProvider","NeonDataApiSnapshot","EnableDataApiInput","NeonRealtimeSnapshot","NeonRealtimeSecret","ConfigureRealtimeInput","NeonBucketSnapshot","NeonBranchStorageSnapshot","CreateBucketInput","NeonFunctionSnapshot","NeonFunctionDeploymentSnapshot","DeployFunctionInput","Uint8Array","Record","NeonTriggerSnapshotBase","NeonScheduleTriggerSnapshot","NeonStorageObjectCreatedTriggerSnapshot","NeonTriggerSnapshot","CreateTriggerInput","UpdateTriggerInput","NeonCustomDomainSnapshot","CreateCredentialInput","NeonCredentialSecret","NeonCredentialReveal","NeonCredentialMeta","GetConnectionUriInput","NeonApi","Promise","BucketAccessLevel","ComputeSettings","CredentialPrincipalType","CredentialScope","DataApiAuthProvider","DataApiSettings","FunctionRuntime","NeonProjectSnapshot","id","name","regionId","pgVersion","orgId","defaultEndpointSettings","NeonBranchSnapshot","parentId","isDefault","protected","expiresAt","NeonEndpointSnapshot","branchId","type","autoscalingLimitMinCu","autoscalingLimitMaxCu","suspendTimeout","CreateProjectInput","defaultBranchName","CreateBranchInput","computeSettings","UpdateBranchInput","NeonRoleSnapshot","NeonDatabaseSnapshot","ownerName","NeonAuthSnapshot","projectId","publishableClientKey","secretServerKey","jwksUrl","baseUrl","RemoteDataApiAuthProvider","NeonDataApiSnapshot","url","status","settings","authProvider","providerName","jwtAudience","EnableDataApiInput","NeonRealtimeSnapshot","enabled","pending","invocationUrl","revision","allowedOrigins","NeonRealtimeSecret","secret","ConfigureRealtimeInput","NeonBucketSnapshot","accessLevel","NeonBranchStorageSnapshot","s3Endpoint","region","forcePathStyle","CreateBucketInput","NeonFunctionSnapshot","slug","activeDeploymentId","currentDeployment","NeonFunctionDeploymentSnapshot","DeployFunctionInput","bundle","Uint8Array","runtime","environment","Record","NeonTriggerSnapshotBase","triggerId","functionSlug","functionPath","inherited","NeonScheduleTriggerSnapshot","cron","nextRunAt","NeonStorageObjectCreatedTriggerSnapshot","bucketName","prefix","NeonTriggerSnapshot","CreateTriggerInput","UpdateTriggerInput","NeonCustomDomainSnapshot","domain","entityType","entityId","cnameTarget","CreateCredentialInput","scopes","principalType","functionId","NeonCredentialSecret","tokenId","tokenIdShort","apiToken","s3SecretAccessKey","createdAt","NeonCredentialReveal","NeonCredentialMeta","lastUsedAt","revokedAt","GetConnectionUriInput","endpointId","databaseName","roleName","pooled","NeonApi","listProjects","filter","Promise","getProject","createProject","input","updateProject","listBranches","createBranch","branch","endpoints","updateBranch","listEndpoints","updateEndpoint","listBranchRoles","listBranchDatabases","getConnectionUri","uri","getNeonAuth","enableNeonAuth","getNeonDataApi","enableProjectBranchDataApi","updateProjectBranchDataApi","deleteProjectBranchDataApi","getProjectBranchRealtime","getProjectBranchRealtimeSecret","enableProjectBranchRealtime","disableProjectBranchRealtime","listBranchBuckets","createBranchBucket","deleteBranchBucket","getProjectBranchStorage","listBranchFunctions","deleteBranchFunction","deployBranchFunction","getBranchFunction","listBranchTriggers","createBranchTrigger","updateBranchTrigger","deleteBranchTrigger","listBranchCustomDomains","registerBranchCustomDomain","deleteBranchCustomDomain","createCredential","listCredentials","revealCredential","revokeCredential"],"sources":["../../src/lib/neon-api.ts"],"mappings":"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AAQpC,mB;E,iCAEsBoC,O,CAAQnC,kB;E,uCAGjCG,iB,GACLgC,O;I,QACMnC,kB;I,WACGC,oB;;E,yDAKJG,iB,GACL+B,O,CAAQnC,kB;E,kCAEuBmC,O,CAAQlC,oB;E,gEAI/BR,e,GACR0C,O,CAAQlC,oB;;E,sDAMRkC,O,CAAQ9B,gB;;E,0DAMR8B,O,CAAQ7B,oB;;;;;E,2CAQH2B,qB,GACLE,O;;;;;;;;E,kDAUAA,O,CAAQ5B,gB;;;;;;;;E,IAWR4B,O,CAAQ5B,gB;;;;;;E,2EAWR4B,O,CAAQ1B,mB;;;;;;;;E,8FAaFC,kB,GACNyB,O,CAAQ1B,mB;;;;;;;E,gGAYAZ,e,GACRsC,O,CAAQ1B,mB;E,uFAMR0B,O;;E,gEAQAA,O,CAAQxB,oB;;E,sEAMRwB,O,CAAQvB,kB;;E,0EAMFC,sB,GACNsB,O;;E,oEAMAA,O;;E,wDAQAA,O,CAAQrB,kB;;E,+DAMHE,iB,GACLmB,O,CAAQrB,kB;;E,6EAORqB,O;;;;;;;E,8DAWAA,O,CAAQpB,yB;;E,0DAQRoB,O,CAAQlB,oB;;E,yEAORkB,O;;;;;;;E,+EAYKhB,mB,GACLgB,O,CAAQjB,8B;;;;;;E,uEAWRiB,O,CAAQlB,oB;E,yDAKRkB,O,CAAQV,mB;E,gEAKHC,kB,GACLS,O,CAAQV,mB;E,mFAMHE,kB,GACLQ,O,CAAQV,mB;E,6EAMRU,O;;;;;;E,+DAUAA,O,CAAQP,wB;;;;E,IAMRO,O,CAAQP,wB;E,gFAMRO,O;;;;;;E,6DAqBKN,qB,GACLM,O,CAAQL,oB;;;;;;E,sDAURK,O,CAAQH,kB;;;;;E,wEAURG,O,CAAQJ,oB;;;;;E,wEAURI,O"}
|
package/dist/lib/types.d.ts
CHANGED
|
@@ -433,7 +433,7 @@ interface FunctionDef {
|
|
|
433
433
|
*/
|
|
434
434
|
dev?: FunctionDevConfig;
|
|
435
435
|
/**
|
|
436
|
-
* Customer-owned hostnames that should point at this function
|
|
436
|
+
* Customer-owned hostnames that should point at this function.
|
|
437
437
|
* v1 only supports functions. Hostnames are unique across functions in the resolved
|
|
438
438
|
* policy. Applied after the function is deployed, on the project's default branch.
|
|
439
439
|
* Other branches apply a list only when {@link FunctionTuning.customDomains} sets one.
|
package/dist/lib/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","names":[],"sources":["../../src/lib/types.ts"],"sourcesContent":["/**\n * Every compute size in the Console size table\n * (https://neon.com/docs/manage/endpoints#compute-size-and-autoscaling-configuration).\n * Plan availability is enforced by the API, not this list.\n */\nexport const COMPUTE_UNITS = [\n\t0.25, 0.5, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 18, 20,\n\t22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56,\n] as const;\n\nexport type ComputeUnit = (typeof COMPUTE_UNITS)[number];\n\n/** Time units accepted in a {@link DurationString}: seconds, minutes, hours, days, weeks. */\nexport type DurationUnit = \"s\" | \"m\" | \"h\" | \"d\" | \"w\";\n\n/**\n * A Neon duration string: a positive integer **followed by a unit** — `s` (seconds),\n * `m` (minutes), `h` (hours), `d` (days), or `w` (weeks). Used by\n * {@link ComputeSettings.suspendTimeout} and {@link BranchTuning.ttl}.\n *\n * A **unit is required**: a bare numeric string like `\"7\"` is rejected at the type level. To\n * express a raw number of seconds, pass a `number` (`300`) — not a string (`\"300\"`). This\n * removes the old ambiguity where `\"7\"` silently meant 7 *seconds* instead of, say, `\"7d\"`.\n *\n * @example \"5m\" // 5 minutes\n * @example \"1h\" // 1 hour\n * @example \"7d\" // 7 days\n */\nexport type DurationString = `${number}${DurationUnit}`;\n\n/**\n * Autocomplete suggestions for {@link ComputeSettings.suspendTimeout}. Every value sits inside\n * the Neon API's allowed scale-to-zero band: **60s–604800s** (1 minute – 1 week). This is *not*\n * a closed set — the field also accepts any other {@link DurationString} or a `number` of\n * seconds; out-of-range values type-check but are rejected at apply time.\n */\ntype SuspendTimeoutSuggestion =\n\t| \"1m\"\n\t| \"5m\"\n\t| \"15m\"\n\t| \"30m\"\n\t| \"1h\"\n\t| \"6h\"\n\t| \"12h\"\n\t| \"1d\"\n\t| \"7d\";\n\n/**\n * Autocomplete suggestions for {@link BranchTuning.ttl}. Every value sits within the Neon API's\n * branch-expiration limit (**max 30 days** from creation; the Console's own presets are 1h / 1d\n * / 7d). This is *not* a closed set — the field also accepts any other {@link DurationString} or\n * a `number` of seconds; values over 30 days are rejected at apply time.\n */\ntype TtlSuggestion = \"1h\" | \"6h\" | \"12h\" | \"1d\" | \"3d\" | \"7d\" | \"14d\" | \"30d\";\n\n/**\n * Compose a field's duration type: its curated autocomplete `Suggestions` plus the open\n * `DurationString` template (so any `<integer><unit>` string still type-checks) and a `number`\n * of seconds. Intersecting the template arm with `NonNullable<unknown>` stops TypeScript from\n * collapsing the literal suggestions into the template, which is what preserves the autocomplete.\n */\ntype DurationField<Suggestions extends DurationString> =\n\t| Suggestions\n\t| (DurationString & NonNullable<unknown>)\n\t| number;\n\n/**\n * Compute settings applied to the read/write endpoint of a branch.\n *\n * Mirrors the subset of {@link https://api-docs.neon.tech/reference/getting-started-with-neon-api Neon endpoint}\n * fields that we expose as IaC primitives. Anything left undefined falls back to the project's\n * `default_endpoint_settings` (which themselves fall back to Neon defaults).\n */\nexport interface ComputeSettings {\n\t/**\n\t * Minimum number of Compute Units. Set to 0.25 for true scale-to-zero.\n\t *\n\t * Sizes above 16 CU are fixed-size only: if this is set with a different\n\t * {@link ComputeSettings.autoscalingLimitMaxCu}, both bounds must be ≤ 16 and\n\t * `max - min` cannot exceed 8 CU. A single bound is checked against the catalog\n\t * only — the other bound comes from the project's default endpoint settings, so\n\t * the API is the arbiter of the resolved pair.\n\t *\n\t * @example 0.25 // scale-to-zero\n\t * @example 1 // always-on with 1 CU minimum\n\t * @example 4\n\t */\n\tautoscalingLimitMinCu?: ComputeUnit;\n\t/**\n\t * Maximum number of Compute Units for autoscaling, or the fixed size when equal\n\t * to {@link ComputeSettings.autoscalingLimitMinCu}.\n\t *\n\t * @example 2\n\t * @example 12\n\t * @example 56 // fixed-size; pair with the same min\n\t */\n\tautoscalingLimitMaxCu?: ComputeUnit;\n\t/**\n\t * How long an idle compute waits before suspending (Neon's scale-to-zero). Accepts a\n\t * {@link DurationString} (autocompletes common values), a number of seconds, or `false`.\n\t *\n\t * - `false` — never suspend (always-on compute)\n\t * - {@link DurationString} — e.g. `\"5m\"`; autocompletes the in-range values `\"1m\"`, `\"5m\"`,\n\t * `\"15m\"`, `\"30m\"`, `\"1h\"`, `\"6h\"`, `\"12h\"`, `\"1d\"`, `\"7d\"`, and accepts any other\n\t * `<integer><unit>` (units: `s`, `m`, `h`, `d`, `w`). A **unit is required** — for raw\n\t * seconds pass a `number`, not a string.\n\t * - `number` — custom timeout in **seconds**, must be in `60`–`604800` (1 minute to 1 week)\n\t * - `undefined` — use the Neon default (currently 300s / 5 minutes)\n\t *\n\t * Whichever form you use, the resolved timeout must fall in `60`–`604800` seconds (the Neon\n\t * API limit); the suggestions are all within that band, anything else is checked at apply.\n\t *\n\t * @example false // never suspend (always-on)\n\t * @example \"5m\" // suspend after 5 minutes idle\n\t * @example \"1h\" // suspend after 1 hour idle\n\t * @example 300 // 5 minutes, expressed in seconds\n\t */\n\tsuspendTimeout?: false | DurationField<SuspendTimeoutSuggestion>;\n}\n\n/**\n * Read-only descriptor of the branch a {@link Config} policy is being evaluated for — the\n * `branch` argument passed to your `defineConfig({ branch: (branch) => … })` closure. It describes\n * **which** branch this invocation decides for; it is not a live branch handle and must not\n * be mutated. Switch on its fields and return the desired {@link BranchConfig}.\n */\nexport interface BranchTarget {\n\t/** Branch name being evaluated. For `branch dev`, this is the generated branch name. */\n\tname: string;\n\t/** Neon branch id when the branch already exists. Undefined during pre-create eval. */\n\tid?: string;\n\t/** Whether this branch already exists on Neon. */\n\texists: boolean;\n\t/** Parent branch id from Neon when known. */\n\tparentId?: string;\n\t/** Whether Neon marks this branch as the project default. */\n\tisDefault?: boolean;\n\t/** Whether Neon currently marks this branch protected. */\n\tisProtected?: boolean;\n\t/** Current expiration timestamp from Neon, when set. */\n\texpiresAt?: string;\n}\n\n/**\n * Object form of a branch-scoped service toggle. `{}` or `{ enabled: true }` enables it;\n * `{ enabled: false }` opts out. Used as the object half of {@link ServiceToggleInput}.\n */\nexport interface ServiceToggle {\n\t/** Defaults to `true` when the service namespace is present. Set `false` to opt out. */\n\tenabled?: boolean;\n}\n\n/**\n * How a branch-scoped service (Neon Auth, Data API, AI Gateway) is toggled in a policy.\n *\n * - `true` / `{}` / `{ enabled: true }` — enabled.\n * - `false` / `{ enabled: false }` — disabled.\n * - omitted (`undefined`) — not part of the policy at all.\n *\n * These toggles are **static** (they live in the top-level `defineConfig({ … })` object,\n * not in the per-branch `branch` closure) so the secret set they imply can be derived at\n * the type level — that's what makes `NeonEnv<typeof config>` exact.\n */\nexport type ServiceToggleInput = boolean | ServiceToggle;\n\n/**\n * Realtime settings for a branch. The object's presence enables Realtime; omit\n * `allowedOrigins` to leave the inherited/current allowlist unchanged.\n */\nexport interface RealtimeConfig {\n\t/** Browser origins allowed to connect. `[]` or `[\"*\"]` allows every origin. */\n\tallowedOrigins?: readonly string[];\n}\n\n/**\n * How Realtime is managed by a policy.\n *\n * - `true` — enable Realtime without changing allowed origins.\n * - `{ allowedOrigins?: [...] }` — enable Realtime and optionally configure origins.\n * - `false` — disable Realtime.\n * - omitted (`undefined`) — leave Realtime unmanaged.\n */\nexport type RealtimeInput = boolean | RealtimeConfig;\n\n/**\n * Resolve a **static** service toggle (`true` / `false` / `{ enabled?: boolean }` / object /\n * `undefined`) to a type-level boolean. The tuple wrapping (`[T] extends […]`) disables\n * distribution so a union/`undefined` is judged as a single unit:\n *\n * - `false` / `{ enabled: false }` / `undefined` → `false`\n * - `true` / `{ enabled: true }` / any other object (`{}`, `{ enabled?: boolean }`) → `true`\n * (a present toggle defaults to enabled)\n * - the bare `boolean | … | undefined` (no literal info) → `false`\n *\n * Shared by the {@link Config} static cross-field checks and the `@neon/env`\n * `NeonEnv` namespace derivation, so both read \"is this service on?\" identically.\n */\nexport type ServiceEnabled<T> = [T] extends [false]\n\t? false\n\t: [T] extends [{ enabled: false }]\n\t\t? false\n\t\t: [T] extends [undefined]\n\t\t\t? false\n\t\t\t: [T] extends [true]\n\t\t\t\t? true\n\t\t\t\t: [T] extends [{ enabled: true }]\n\t\t\t\t\t? true\n\t\t\t\t\t: [T] extends [object]\n\t\t\t\t\t\t? true\n\t\t\t\t\t\t: false;\n\nexport interface PostgresConfig {\n\tcomputeSettings?: ComputeSettings;\n}\n\n/**\n * Authentication providers a Data API integration can verify JWTs against, as written in\n * `neon.ts`. Friendly authoring values (mapped to the Neon API's `neon_auth` / `external`\n * at the API boundary):\n *\n * - `\"neon\"` — verify tokens minted by **Neon Auth** on the same branch. Neon supplies the\n * JWKS URL / provider wiring for you, so the `jwksUrl` / `providerName` / `jwtAudience`\n * fields are forbidden (a type error) on this variant — and the policy must also enable\n * top-level `auth` (Neon Auth) so the tokens exist.\n * - `\"external\"` — verify tokens from a third-party IdP (Clerk, Stytch, Auth0, …). You\n * provide `jwksUrl` (and optionally `providerName` / `jwtAudience`).\n */\nexport const DATA_API_AUTH_PROVIDERS = [\"neon\", \"external\"] as const;\nexport type DataApiAuthProvider = (typeof DATA_API_AUTH_PROVIDERS)[number];\n\n/**\n * Reusable runtime settings for a Data API integration (the Neon API `DataAPISettings`,\n * camelCased to match the rest of `neon.ts`). Every field is optional; omitted fields keep\n * the Neon defaults shown below. These are the **only** Data API fields that can change on\n * an already-enabled integration — drift here is reconciled as an *update* (requires\n * `updateExisting` / `--update-existing`); the create-only auth wiring above cannot.\n */\nexport interface DataApiSettings {\n\t/** Enable the aggregates feature (`db_aggregates_enabled`). Default `true`. */\n\tdbAggregatesEnabled?: boolean;\n\t/** Database role used for anonymous requests (`db_anon_role`). Default `\"anonymous\"`. */\n\tdbAnonRole?: string;\n\t/** Extra schemas appended to the search path (`db_extra_search_path`). */\n\tdbExtraSearchPath?: string;\n\t/** Maximum rows returned in a single request (`db_max_rows`). */\n\tdbMaxRows?: number;\n\t/** Schemas exposed via the API (`db_schemas`). Default `[\"public\"]`. */\n\tdbSchemas?: string[];\n\t/** JWT claim key used for role extraction (`jwt_role_claim_key`). Default `\".role\"`. */\n\tjwtRoleClaimKey?: string;\n\t/** Maximum lifetime of the JWT cache, in seconds (`jwt_cache_max_lifetime`). */\n\tjwtCacheMaxLifetime?: number;\n\t/** OpenAPI spec mode (`openapi_mode`). Default `\"disabled\"`. */\n\topenapiMode?: \"ignore-privileges\" | \"disabled\";\n\t/** CORS allowed origins (`server_cors_allowed_origins`). */\n\tserverCorsAllowedOrigins?: string;\n\t/** Emit server-timing headers (`server_timing_enabled`). */\n\tserverTimingEnabled?: boolean;\n}\n\n/** Fields shared by every {@link DataApiConfig} variant. */\ninterface DataApiConfigBase {\n\t/** Defaults to `true` when the `dataApi` namespace is present. `false` disables and apply deletes. */\n\tenabled?: boolean;\n\t/** Reusable runtime settings. Drift here is reconciled as an update. */\n\tsettings?: DataApiSettings;\n}\n\n/**\n * Data API verified by **Neon Auth** (`authProvider: \"neon\"`, the default). The external\n * IdP fields are statically forbidden (`?: never`) because Neon supplies them; declaring any\n * of them is a type error directing you to `authProvider: \"external\"`.\n */\nexport interface DataApiNeonAuthConfig extends DataApiConfigBase {\n\tauthProvider?: \"neon\";\n\t/** Forbidden with `authProvider: \"neon\"` — Neon provides the JWKS URL. */\n\tjwksUrl?: never;\n\t/** Forbidden with `authProvider: \"neon\"` — the provider is Neon Auth. */\n\tproviderName?: never;\n\t/** Forbidden with `authProvider: \"neon\"` — Neon manages the audience. */\n\tjwtAudience?: never;\n}\n\n/**\n * Data API verified by an **external** IdP (`authProvider: \"external\"`). You provide the\n * JWKS URL (and optionally a provider label / expected audience).\n */\nexport interface DataApiExternalAuthConfig extends DataApiConfigBase {\n\tauthProvider: \"external\";\n\t/** URL that publishes the IdP's JWKS (JSON Web Key Set). */\n\tjwksUrl?: string;\n\t/** Human label for the IdP (e.g. \"Clerk\", \"Stytch\", \"Auth0\"). */\n\tproviderName?: string;\n\t/**\n\t * Expected `aud` claim. ⚠️ This only **rejects** tokens carrying a *different* audience;\n\t * tokens with no `aud` claim are still accepted.\n\t */\n\tjwtAudience?: string;\n}\n\n/**\n * Object form of the `dataApi` toggle. A discriminated union on {@link DataApiAuthProvider}:\n * the `\"neon\"` variant forbids the external-IdP fields, the `\"external\"` variant allows them.\n */\nexport type DataApiConfig = DataApiNeonAuthConfig | DataApiExternalAuthConfig;\n\n/**\n * How the Data API is toggled in a policy: a bare boolean (like the other service toggles)\n * or the richer {@link DataApiConfig} object. `true` / `{}` / `{ enabled: true }` enable it\n * with Neon defaults. `false` / `{ enabled: false }` disable it; apply deletes an existing\n * Data API. Omit the field to leave an existing integration alone.\n */\nexport type DataApiInput = boolean | DataApiConfig;\n\n/**\n * Supported function runtimes. Mirrors the Neon Functions deploy API `runtime` enum.\n * Only `nodejs24` exists today; kept as a union so adding runtimes later is a\n * non-breaking, type-checked change.\n */\nexport type FunctionRuntime = \"nodejs24\";\n\n/**\n * Local-development settings for a function, used by `neon dev` when it serves every\n * function declared in `neon.ts` (i.e. invoked with no `--source`). Never affects deploy.\n */\nexport interface FunctionDevConfig {\n\t/**\n\t * Port the local server binds. Bound exactly (and `neon dev` fails loudly if it is taken)\n\t * when set; a free port is found automatically when omitted.\n\t */\n\tport?: number;\n}\n\n/**\n * The object form of an {@link FunctionDef.externalPackages} entry, for the one case the\n * bare string cannot express: externalizing a package without shipping its files.\n */\nexport interface ExternalPackageDef {\n\t/** Package name, optionally with a subpath: `sharp`, `@scope/pkg`, `pkg/sub`. */\n\tname: string;\n\t/**\n\t * Whether the package's real files ship into the deployed archive next to the bundle.\n\t *\n\t * Defaults to `true`, which is the state where the import resolves and the function\n\t * works. Set it to `false` only for a package the function never reaches: nothing is\n\t * shipped for it, so reaching it throws `Cannot find module` at invoke.\n\t */\n\tincludeFiles?: boolean;\n}\n\n/**\n * One entry of {@link FunctionDef.externalPackages}. A bare string is the common form and\n * ships the package's files; {@link ExternalPackageDef} exists to turn that off.\n */\nexport type ExternalPackageEntry = string | ExternalPackageDef;\n\n/**\n * An {@link ExternalPackageEntry} with its default applied, as every consumer downstream of\n * `resolveConfig` reads it.\n */\nexport interface ResolvedExternalPackage {\n\t/** Package name as declared, subpath included. */\n\tname: string;\n\t/** Whether this package's files are staged into the archive. */\n\tincludeFiles: boolean;\n}\n\n/** Archive-relative paths. The runtime imports `index.mjs` or `index.js` at the root. */\nexport type FunctionBundle = Record<string, Uint8Array>;\n\n/** Defined here so policy imports stay free of build-time dependencies. */\nexport type FunctionBundler = (\n\tfn: ResolvedFunctionConfig,\n) => Promise<FunctionBundle>;\n\n/**\n * `\"esbuild\"` (default) bundles a file, or a directory from the first of\n * `index.ts`, `index.js`, `index.mjs`. `\"none\"` ships a prebuilt directory or a\n * single `index.mjs` / `index.js`. An inline {@link FunctionBundler} returns the\n * file map.\n */\nexport type FunctionBundlerInput = \"esbuild\" | \"none\" | FunctionBundler;\n\n/**\n * Static definition of a Neon Function. Declares that the function\n * **exists** on every branch; its branch-unique slug is the **record key** in\n * `functions` (or deprecated {@link PreviewInput.functions}), so slugs are statically enumerable,\n * cannot duplicate, and the `branch` closure can only tune slugs that are declared here.\n * Runtime tuning is **not** here — it varies per branch and lives in the `branch` closure\n * (see {@link FunctionTuning}). Memory is fixed by the platform policy for now and is not\n * user-configurable.\n */\nexport interface FunctionDef {\n\t/** Free-form display name. @example \"Hello World\" */\n\tname: string;\n\t/**\n\t * Path to the entry module or source directory, relative to `neon.ts` (or\n\t * absolute). A file is the entry; a directory is searched for `index.ts`,\n\t * then `index.js`, then `index.mjs`. A JS function value has no source path\n\t * for a bundler to resolve.\n\t * @example \"./functions/hello-world.ts\"\n\t * @example \".mastra/output\"\n\t */\n\tsource: string;\n\t/**\n\t * Environment variables injected into the deployed function, keyed by the var name the\n\t * function reads at runtime. The **keys** are static (preserved at the type level so\n\t * `parseEnv(config, \"<slug>\").function.<key>` is typed). An unset `process.env.X`\n\t * fails validation. Omit a key to preserve its deployed value; an empty string deletes it.\n\t * @example { resendApiKey: process.env.RESEND_API_KEY! }\n\t */\n\tenv?: Record<string, string>;\n\t/**\n\t * Ship a dependency's real files into the deployed archive instead of bundling it —\n\t * `sharp` and other packages backed by a native binary.\n\t *\n\t * The deploy-time equivalent of Next.js's `serverExternalPackages`. Every entry is passed\n\t * to esbuild's `external`, so the import survives into the bundle instead of being\n\t * followed, and the package's own files are shipped beside the bundle so that import\n\t * resolves.\n\t *\n\t * Reach for this when bundling a package is impossible rather than merely undesirable.\n\t * The case that comes up is a package backed by a native `.node` binary: the binary is a\n\t * compiled object the platform loads from a real path, so no bundler can inline it.\n\t * `sharp` is the common one, and it does not even fail at build time — it loads its\n\t * binary through `createRequire`, which esbuild does not follow, so it bundles cleanly\n\t * and then fails at invoke with \"Could not load the sharp module\".\n\t *\n\t * ```ts\n\t * externalPackages: [\"sharp\"]\n\t * ```\n\t *\n\t * Each declared package is installed for the Functions runtime target — **linux-arm64,\n\t * glibc** — into a throwaway directory, traced for the files it actually reaches, and\n\t * copied into the archive under `node_modules/` with its directory layout preserved. That\n\t * layout is load-bearing rather than cosmetic: a `.node` addon locates its sibling shared\n\t * libraries relative to its own directory, so a flattened tree fails to load.\n\t *\n\t * Your own `node_modules` is never read for these files or modified. Its binaries are\n\t * built for your machine rather than the deploy target, and a cross-platform install does\n\t * not survive your next plain `npm install`, so the target's packages are resolved fresh\n\t * on each deploy.\n\t *\n\t * Requirements, all reported at deploy time rather than at invoke: the package must\n\t * publish a linux-arm64 glibc build (`sharp` and most `@napi-rs/*` packages do; anything\n\t * compiled from source at install time does not), `npm` must be on `PATH`, and the\n\t * archive must stay inside the deploy size limits — native binaries are large.\n\t *\n\t * ### Excluding a package's files\n\t *\n\t * `includeFiles: false` externalizes the import without shipping anything, which is the\n\t * escape hatch for a package that cannot be staged — no build for the target, or too\n\t * large — and that the function never actually reaches:\n\t *\n\t * ```ts\n\t * externalPackages: [\"sharp\", { name: \"canvas\", includeFiles: false }]\n\t * ```\n\t *\n\t * **An excluded package is not resolvable at runtime.** Nothing is shipped for it, so it\n\t * throws `Cannot find module` if the function reaches it. It unblocks an import that is\n\t * never evaluated; it does not make a dependency usable.\n\t *\n\t * Entries are package names, optionally with a subpath (`pkg`, `@scope/pkg`, `pkg/sub`),\n\t * matching esbuild. A relative or absolute path is rejected at validation time: those are\n\t * local modules, and a local module that cannot be bundled is a different problem. Files\n\t * are staged per package, so a subpath narrows what esbuild leaves unresolved without\n\t * narrowing what ships.\n\t *\n\t * Under `neon dev` the list only keeps the package out of the bundle — nothing is\n\t * installed or copied, and it resolves from your own `node_modules` against your host\n\t * architecture, which is what you want locally.\n\t * @example [\"sharp\", { name: \"canvas\", includeFiles: false }]\n\t */\n\texternalPackages?: ExternalPackageEntry[];\n\t/**\n\t * How {@link source} becomes deployable files. Defaults to `\"esbuild\"`.\n\t * `\"none\"` ships a prebuilt directory or `index.mjs` / `index.js` file.\n\t * An inline {@link FunctionBundler} returns the file map used by deploy and\n\t * `neon dev`. Inline functions do not round-trip through inspect or pull and\n\t * must be re-declared.\n\t * @example \"none\"\n\t * @example (fn) => myFrameworkBuild(fn.source)\n\t */\n\tbundler?: FunctionBundlerInput;\n\t/**\n\t * Local-development settings used by `neon dev` when serving every function from\n\t * `neon.ts`. Ignored at deploy time. See {@link FunctionDevConfig}.\n\t */\n\tdev?: FunctionDevConfig;\n\t/**\n\t * Customer-owned hostnames that should point at this function (beta).\n\t * v1 only supports functions. Hostnames are unique across functions in the resolved\n\t * policy. Applied after the function is deployed, on the project's default branch.\n\t * Other branches apply a list only when {@link FunctionTuning.customDomains} sets one.\n\t * Domains that exist remotely but are omitted here are left alone — delete with\n\t * `neon function domains delete`.\n\t *\n\t * @example [\"docs.example.com\"]\n\t */\n\tcustomDomains?: string[];\n}\n\n/**\n * A trigger that invokes a function. The trigger name is the record key in\n * {@link Config.triggers}. `functionPath` defaults to `/`. `enabled` defaults to `true`.\n *\n * @example { type: \"schedule\", function: \"cron\", cron: \"0 * * * *\" }\n * @example { type: \"storage_object_created\", function: \"ingest\", bucket: \"assets\", prefix: \"logos/\" }\n */\nexport type FunctionTriggerDef =\n\t| FunctionScheduleTriggerDef\n\t| FunctionStorageObjectCreatedTriggerDef;\n\n/**\n * A cron schedule that invokes a function. `function` is a slug from {@link Config.functions}\n * (or deprecated `preview.functions`). `cron` is a numeric five-field expression in UTC.\n *\n * @example { type: \"schedule\", function: \"cron\", cron: \"0 * * * *\" }\n */\nexport interface FunctionScheduleTriggerDef {\n\ttype: \"schedule\";\n\tfunction: string;\n\tcron: string;\n\tfunctionPath?: string;\n\tenabled?: boolean;\n}\n\n/**\n * Invokes a function when an object is created in a bucket from {@link Config.buckets}\n * (or deprecated `preview.buckets`). `prefix` is an exact object-key prefix; omit it to\n * match every key in the bucket.\n *\n * @example { type: \"storage_object_created\", function: \"ingest\", bucket: \"assets\", prefix: \"logos/\" }\n */\nexport interface FunctionStorageObjectCreatedTriggerDef {\n\ttype: \"storage_object_created\";\n\tfunction: string;\n\tbucket: string;\n\tprefix?: string;\n\tfunctionPath?: string;\n\tenabled?: boolean;\n}\n\n/**\n * A single capability a branch-scoped service credential may exercise (Preview). A\n * credential is granted a set of these and may only perform the listed actions. Mirrors\n * the Neon API `CredentialScope` enum (`x-stability-level: beta`):\n *\n * - `storage:read` / `storage:write` — object-storage (bucket) access via the S3 key.\n * - `ai_gateway:invoke` — call the AI Gateway with the bearer `api_token`.\n * - `functions:invoke` — invoke Neon Functions with the bearer `api_token`.\n *\n * The set a policy needs is derived from its enabled Preview features (see\n * {@link deriveCredentialScopes}); it is never authored by hand.\n */\nexport type CredentialScope =\n\t| \"storage:read\"\n\t| \"storage:write\"\n\t| \"ai_gateway:invoke\"\n\t| \"functions:invoke\";\n\n/**\n * Who a credential acts as. `user` is the developer/app principal minted for local dev and\n * app bootstrap (`fetchEnv` / `env pull`); `function` is a deployed-function principal\n * (carries a `function_id`). The env tooling only mints `user` credentials today.\n */\nexport type CredentialPrincipalType = \"user\" | \"function\";\n\n/** Anonymous-access level for a branchable object-storage bucket. */\nexport type BucketAccessLevel = \"private\" | \"public_read\";\n\n/**\n * Static definition of a branchable object-storage bucket. The bucket's\n * name is the **record key** in `buckets` (or deprecated {@link PreviewInput.buckets}), so names are statically\n * enumerable and cannot duplicate.\n */\nexport interface BucketDef {\n\t/**\n\t * Anonymous access level. `private` (default) requires authenticated reads/writes;\n\t * `public_read` allows anonymous GetObject/HeadObject.\n\t */\n\taccess?: BucketAccessLevel;\n}\n\n/** Preview features, plus deprecated homes for services that have graduated to GA. */\nexport interface PreviewInput {\n\t/** Enable, configure, or disable Realtime on every branch this policy is applied to. */\n\trealtime?: RealtimeInput;\n\t/**\n\t * Enable/disable the AI Gateway on the branch (toggle, like auth / dataApi).\n\t * @deprecated Use top-level `aiGateway`.\n\t */\n\taiGateway?: ServiceToggleInput;\n\t/**\n\t * Functions to deploy, keyed by branch-unique slug (`^[a-z0-9]{1,20}$`).\n\t * @deprecated Use top-level `functions`.\n\t */\n\tfunctions?: Record<string, FunctionDef>;\n\t/**\n\t * Object-storage buckets to create, keyed by bucket name.\n\t * @deprecated Use top-level `buckets`.\n\t */\n\tbuckets?: Record<string, BucketDef>;\n}\n\n/**\n * Per-branch deploy tuning for a single function. Returned (per slug) by the `branch`\n * closure. Deliberately **cannot** change the function's existence, source, name, env\n * **keys**, or memory — so the static secret/function set stays sound. Runtime selection\n * and the custom-domain list may vary per branch.\n */\nexport interface FunctionTuning {\n\t/** Runtime to execute the function with. Defaults to `\"nodejs24\"`. */\n\truntime?: FunctionRuntime;\n\t/**\n\t * When present, replaces {@link FunctionDef.customDomains} for this branch.\n\t * `[]` registers nothing on this branch. Omit the key: the default branch\n\t * inherits the static list; other branches do not.\n\t */\n\tcustomDomains?: string[];\n}\n\n/**\n * Per-branch tuning of functions under the deprecated `preview` key.\n * Only existing function slugs may be tuned — `Slug` is constrained to the\n * declared keys by {@link BranchTuningFn}.\n *\n * @deprecated Use top-level `branch: (branch) => ({ functions: { … } })`.\n */\nexport interface PreviewTuning<Slug extends string = string> {\n\t/**\n\t * @deprecated Use top-level `functions` on the object returned by `branch`.\n\t */\n\tfunctions?: Partial<Record<Slug, FunctionTuning>>;\n}\n\n/**\n * The per-branch tuning object returned by the `branch` closure. It can adjust branch\n * lifecycle (`parent`, `ttl`, `protected`), Postgres compute settings, and per-function\n * deploy tuning — but **cannot** add/remove services or functions. That guarantee is what\n * keeps the static secret set (and therefore `NeonEnv`) exact.\n */\nexport interface BranchTuning<Slug extends string = string> {\n\t/** Parent branch name used when creating a new branch. Not a Postgres setting. */\n\tparent?: string;\n\t/**\n\t * Branch time-to-live: how long after creation the branch should auto-expire. Applied\n\t * when creating a new branch and reconciled on existing branches (when `updateExisting`\n\t * is set). Accepts a {@link DurationString} (autocompletes common values) or a number of\n\t * seconds. Omit to keep the branch indefinitely.\n\t *\n\t * - {@link DurationString} — e.g. `\"7d\"`; autocompletes `\"1h\"`, `\"6h\"`, `\"12h\"`, `\"1d\"`,\n\t * `\"3d\"`, `\"7d\"`, `\"14d\"`, `\"30d\"`, and accepts any other `<integer><unit>` (units: `s`,\n\t * `m`, `h`, `d`, `w` — e.g. `\"12h\"`, `\"2w\"`). A **unit is required** — `\"7\"` is rejected;\n\t * for raw seconds pass a `number`.\n\t * - `number` — custom TTL in **seconds** (e.g. `3600`)\n\t * - `undefined` — no expiry; the branch persists until explicitly deleted\n\t *\n\t * The Neon API caps branch expiration at **30 days** from creation, so the resolved TTL must\n\t * be `> 0` and `<= 30d`; the suggestions stay within that limit and anything longer is\n\t * rejected at apply.\n\t *\n\t * @example \"1d\" // ephemeral preview branch: expires a day after creation\n\t * @example \"7d\" // one-week TTL\n\t * @example \"30d\" // the maximum the API allows\n\t * @example 3600 // 1 hour, expressed in seconds\n\t */\n\tttl?: DurationField<TtlSuggestion>;\n\t/** Whether the selected branch should be protected. Undefined means \"leave as-is\". */\n\tprotected?: boolean;\n\tpostgres?: PostgresConfig;\n\t/** Per-function deploy tuning, keyed by declared slug. */\n\tfunctions?: Partial<Record<Slug, FunctionTuning>>;\n\t/**\n\t * @deprecated Use top-level `functions` on this object.\n\t */\n\tpreview?: PreviewTuning<Slug>;\n}\n\n/** Extract declared function slugs from top-level `functions` and/or `preview.functions`. */\ntype PreviewFunctionSlugs<Preview> = Preview extends { functions: infer F }\n\t? Extract<keyof F, string>\n\t: never;\n\n// Config's Functions default is `Record<string, FunctionDef> | undefined`. A string\n// index would otherwise union into FunctionSlugsOf as `string` and drop slug checking\n// on positional `Config<Auth, DataApi, Preview>`.\ntype GaFunctionSlugs<Functions> = [Functions] extends [undefined]\n\t? never\n\t: string extends keyof NonNullable<Functions>\n\t\t? never\n\t\t: Extract<keyof NonNullable<Functions>, string>;\n\ntype FunctionSlugsOf<\n\tPreview extends PreviewInput | undefined,\n\tFunctions extends Record<string, FunctionDef> | undefined = undefined,\n> = [PreviewFunctionSlugs<Preview> | GaFunctionSlugs<Functions>] extends [never]\n\t? string\n\t: PreviewFunctionSlugs<Preview> | GaFunctionSlugs<Functions>;\n\n/**\n * Signature of the `branch` closure. Generic over the static function homes so the\n * `functions` keys it may tune are constrained to the slugs actually declared.\n */\nexport type BranchTuningFn<\n\tPreview extends PreviewInput | undefined = PreviewInput | undefined,\n\tFunctions extends Record<string, FunctionDef> | undefined = undefined,\n> = (branch: BranchTarget) => BranchTuning<FunctionSlugsOf<Preview, Functions>>;\n\n/**\n * A validated Neon branch policy — the value `defineConfig({ … })` returns and `neon.ts`\n * default-exports.\n *\n * Split into a **static** existential set (top-level service toggles and records) and a\n * **dynamic** per-branch `branch` closure for tuning. The static half is what makes the\n * secret set — and therefore `NeonEnv<typeof config>` and `parseEnv` — exact; the closure\n * can tune but never change what exists.\n *\n * Generic over the static fields so the type system can read the exact toggle/slug\n * literals; the defaults make the bare `Config` a usable \"any policy\" type for runtime\n * function signatures. The first three type parameters stay `Auth`, `DataApi`, `Preview`\n * so existing positional `Config<Auth, DataApi, Preview>` consumers keep compiling.\n */\nexport interface Config<\n\tAuth extends ServiceToggleInput | undefined =\n\t\t| ServiceToggleInput\n\t\t| undefined,\n\tDataApi extends DataApiInput | undefined = DataApiInput | undefined,\n\tPreview extends PreviewInput | undefined = PreviewInput | undefined,\n\tFunctions extends Record<string, FunctionDef> | undefined =\n\t\t| Record<string, FunctionDef>\n\t\t| undefined,\n\tBuckets extends Record<string, BucketDef> | undefined =\n\t\t| Record<string, BucketDef>\n\t\t| undefined,\n\tAiGateway extends ServiceToggleInput | undefined =\n\t\t| ServiceToggleInput\n\t\t| undefined,\n> {\n\t/** Neon Auth integration toggle (GA). Static — drives `NeonEnv.auth`. */\n\tauth?: Auth;\n\t/**\n\t * Neon Data API integration (GA). Static — drives `NeonEnv.dataApi`. A boolean/toggle, or\n\t * a {@link DataApiConfig} object selecting the auth provider (`\"neon\"` / `\"external\"`) and\n\t * runtime {@link DataApiSettings}. With `authProvider: \"neon\"` the policy must also enable\n\t * top-level `auth`.\n\t */\n\tdataApi?: DataApi;\n\t/**\n\t * AI Gateway toggle (GA). Static — drives `NeonEnv.aiGateway`. Same shapes as `auth`.\n\t */\n\taiGateway?: AiGateway;\n\t/**\n\t * Functions to deploy, keyed by branch-unique slug (`^[a-z0-9]{1,20}$`).\n\t */\n\tfunctions?: Functions;\n\t/**\n\t * Object-storage buckets to create, keyed by bucket name.\n\t */\n\tbuckets?: Buckets;\n\t/**\n\t * Function triggers, keyed by branch-unique name. Each value names the function\n\t * (and, for `storage_object_created`, the bucket) it binds. Applied after functions\n\t * are deployed. Triggers that exist remotely but are omitted here are left alone.\n\t */\n\ttriggers?: Record<string, FunctionTriggerDef>;\n\t/** Preview features and deprecated aliases for graduated services. */\n\tpreview?: Preview;\n\t/** Per-branch tuning closure. Cannot change the static existential set. */\n\tbranch?: BranchTuningFn<Preview, Functions>;\n\t/**\n\t * Experimental (unstable) features, isolated in their own namespace so they can change\n\t * shape or disappear without touching the rest of the policy. See {@link ExperimentalInput}.\n\t */\n\texperimental?: ExperimentalInput;\n}\n\n/**\n * Experimental (unstable) features. Currently just `hooks`. Kept out of the top-level\n * namespace — rather than a sibling of `auth` / `functions` / `branch` — as a signal that\n * this shape is still moving and isn't covered by the same stability guarantees as the rest\n * of the policy.\n */\nexport interface ExperimentalInput {\n\t/**\n\t * Imperative lifecycle hooks (Preview) — run side effects (migrations, seeding, …) on the\n\t * real `checkout` / `deploy` commands. The declarative companion to {@link Config.branch}:\n\t * hooks never run during `plan` / `status` / `inspect`, so the diff engine stays sound.\n\t * See {@link Hooks}.\n\t */\n\thooks?: Hooks;\n}\n\n// ─── Lifecycle hooks (Preview) ──────────────────────────────────────────────────\n//\n// Hooks are the **imperative** companion to the pure, declarative `branch` closure.\n// `branch()` answers *\"what should this branch look like?\"* (and runs during `plan` /\n// `status` / `apply`, so it must stay side-effect free). Hooks answer *\"do this when a\n// branch is created / checked out / deployed\"* (migrations, seeding, notifications) and\n// run **only** during the real `checkout` / `deploy` commands (and, for `create`,\n// whenever those actually create a branch) — never during `plan` / `status` / `inspect`.\n\n/**\n * Read-only git facts injected into every hook by the CLI. A hook can *read* the git state\n * (to name a branch, gate a migration, …) but the hooks never *drive* git — that keeps the\n * git → Neon relationship a loop-free, one-way edge (`git checkout` syncs Neon, never the\n * reverse). Populated from the surrounding repository; all fields except `available`,\n * `isDetached`, and `isDirty` are absent when {@link available} is `false` (not a git repo,\n * or `git` is not installed).\n *\n * What *triggered* this hook invocation — the installed git hook vs. an explicit CLI\n * command — is a separate concern; see {@link CheckoutEvent} / {@link DeployEvent} on each\n * hook context's `event` field, not this type.\n */\nexport interface GitContext {\n\t/** `false` when the command did not run inside a git work tree (or `git` is missing). */\n\tavailable: boolean;\n\t/** Current branch (`git symbolic-ref --short HEAD`). Undefined in detached-HEAD state. */\n\tbranch?: string;\n\t/**\n\t * `branch`, sanitized into a valid Neon branch name: lowercased, each `/`-separated\n\t * segment reduced to `[a-z0-9-]`, empty results fall back to `\"branch\"`, clamped to 256\n\t * characters. Undefined whenever `branch` is (detached HEAD, not a git repo, or `git` is\n\t * unavailable). Prepend your own prefix with plain string concatenation, e.g.\n\t * `` `preview/${git.neonSafeBranchName}` ``.\n\t */\n\tneonSafeBranchName?: string;\n\t/** Full commit SHA of `HEAD`. */\n\tsha?: string;\n\t/** Abbreviated commit SHA of `HEAD`. */\n\tshortSha?: string;\n\t/** `true` when `HEAD` is detached (no current branch). */\n\tisDetached: boolean;\n\t/** `true` when the work tree has uncommitted changes (`git status --porcelain`). */\n\tisDirty: boolean;\n\t/** Default branch the remote points at (`origin/HEAD`), e.g. `\"main\"`, when resolvable. */\n\tdefaultBranch?: string;\n\t/** `origin` remote URL, when configured. */\n\tremoteUrl?: string;\n\t/** Absolute path to the repository root (`git rev-parse --show-toplevel`). */\n\trepoRoot?: string;\n}\n\n/**\n * What triggered a `checkout` (and the `create` it may perform). `inputName` — what the user\n * typed at a Neon prompt, if anything — lives *inside* the event so narrowing on `event.type`\n * narrows `inputName` too (TypeScript only propagates discriminated-union narrowing within\n * the object actually holding the discriminant, not to sibling fields of an outer object):\n *\n * - `\"git-checkout\"` — the installed `post-checkout` git hook, via `neon git sync`. Carries\n * the git branch that triggered it (`gitBranch`); `inputName` is always `undefined` here —\n * nothing was typed at a Neon prompt. The sanitized Neon-safe form of that branch is on the\n * sibling `git` context, at `git.neonSafeBranchName`.\n * - `\"neon-checkout\"` — an explicit `neon checkout` invocation. `inputName` is the name/id\n * the user passed, or `undefined` when they omitted it (interactive picker).\n */\nexport type CheckoutEvent =\n\t| { type: \"git-checkout\"; gitBranch: string; inputName?: undefined }\n\t| { type: \"neon-checkout\"; inputName?: string };\n\n/** What triggered a `deploy`. Currently always `\"neon-deploy\"` — an explicit `neon deploy` / `config apply` invocation; `deploy` is never triggered by the git hook. */\nexport type DeployEvent = { type: \"neon-deploy\" };\n\n/**\n * The branch a hook is acting on — a resolved, live branch (unlike the pre-create\n * {@link BranchTarget} the `branch` closure may receive). Always carries a concrete `id`.\n */\nexport interface HookBranch {\n\t/** Neon project id the branch belongs to. */\n\tprojectId: string;\n\t/** Neon branch id (`br-…`). */\n\tid: string;\n\t/** Branch name. */\n\tname: string;\n\t/** `true` when **this** operation created the branch (vs selecting an existing one). */\n\tcreated: boolean;\n\t/** Whether Neon marks the branch as the project default. */\n\tisDefault: boolean;\n\t/** Whether Neon marks the branch protected. */\n\tisProtected: boolean;\n\t/** Parent branch id, when known. */\n\tparentId?: string;\n\t/** Branch expiration timestamp, when set. */\n\texpiresAt?: string;\n}\n\n/**\n * A resolved branch's env vars, namespaced like `@neon/env`'s `NeonEnv<C>` — but **not**\n * generic over the policy. `@neon/config` cannot import the real, policy-exact `NeonEnv<C>`\n * (it lives in a package that itself depends on `@neon/config`, and importing it back would\n * be a dependency cycle), so every namespace here is optional regardless of what the policy\n * declares, rather than conditionally present/absent. `postgres` is the only field every\n * resolved branch actually has, so it stays the one non-optional namespace.\n */\nexport interface HookEnv {\n\tpostgres: {\n\t\tdatabaseUrl: string;\n\t\tdatabaseUrlUnpooled: string;\n\t};\n\tbranch?: { name: string };\n\tauth?: { baseUrl: string; jwksUrl: string };\n\tdataApi?: { url: string };\n\tstorage?: {\n\t\taccessKeyId: string;\n\t\tsecretAccessKey: string;\n\t\tendpoint: string;\n\t\tregion: string;\n\t};\n\taiGateway?: { apiKey: string; baseUrl: string };\n\tfunctions?: Record<string, { baseUrl: string }>;\n}\n\n/** Context passed to `hooks.checkout.before` (runs before the branch name is resolved). */\nexport interface CheckoutBeforeContext {\n\tevent: CheckoutEvent;\n\tgit: GitContext;\n}\n\n/**\n * Return value of a `hooks.checkout.before` **function** hook. Return `{ name }` to rewrite\n * the branch that will be checked out / created; return nothing to keep the resolved name.\n * Throw to abort the checkout. (Shell-command `before` hooks cannot rewrite the name — only\n * abort via a non-zero exit — since they have no return channel.)\n */\nexport interface CheckoutBeforeResult {\n\t/** Overrides the Neon branch name to check out / create. */\n\tname?: string;\n}\n\n/**\n * Context passed to `hooks.checkout.after` (branch resolved + env pulled). `env` is\n * {@link HookEnv} — every namespace optional; see that type for why it can't be the exact,\n * policy-typed `NeonEnv<C>`.\n */\nexport interface CheckoutAfterContext {\n\tbranch: HookBranch;\n\tenv: HookEnv;\n\tgit: GitContext;\n\tevent: CheckoutEvent;\n}\n\n/**\n * Context passed to `hooks.create.before` (runs before a new branch is created). Fires only\n * for a genuine creation — never for `checkout` selecting an existing branch. Unlike\n * `checkout.before`, this cannot rename the branch: by the time a `create` is reached, the\n * name is already resolved (rename via `checkout.before` if you need that).\n */\nexport interface CreateBeforeContext {\n\t/** Name of the branch about to be created. */\n\tbranchName: string;\n\tgit: GitContext;\n\t/** The event that triggered the enclosing `checkout` — `create` never runs standalone. */\n\tevent: CheckoutEvent;\n}\n\n/** Context passed to `hooks.create.after` (branch created, policy applied, env pulled). `branch.created` is always `true` here. */\nexport interface CreateAfterContext {\n\tbranch: HookBranch;\n\tenv: HookEnv;\n\tgit: GitContext;\n\tevent: CheckoutEvent;\n}\n\n/** Context passed to `hooks.deploy.before` (branch resolved, policy not yet applied). */\nexport interface DeployBeforeContext {\n\tbranch: HookBranch;\n\tgit: GitContext;\n\tevent: DeployEvent;\n}\n\n/** Context passed to `hooks.deploy.after` (policy applied, env pulled). */\nexport interface DeployAfterContext {\n\tbranch: HookBranch;\n\tenv: HookEnv;\n\t/** What the apply changed. */\n\tresult: PushResult;\n\tgit: GitContext;\n\tevent: DeployEvent;\n}\n\n/**\n * A shell-command hook: a single command string, or a list of commands run sequentially\n * (each must exit 0 or the operation aborts). Commands run **non-interactively** (stdin is\n * not a TTY and `CI=1` is set) so an accidental interactive command fails fast instead of\n * hanging. Resolved Neon env vars are injected into the command's environment.\n */\nexport type ShellHook = string | string[];\n\n/**\n * A lifecycle hook: either a (possibly async) function receiving a typed `Ctx`, or a\n * {@link ShellHook}. `before` hooks may influence/abort (functions can return `Result`,\n * any hook can throw to abort); `after` hooks observe (their return value is ignored).\n */\nexport type Hook<Ctx, Result = void> =\n\t| ((ctx: Ctx) => Result | Promise<Result>)\n\t| ShellHook;\n\n/** Hooks for the `checkout` command (`neon checkout`). */\nexport interface CheckoutHooks {\n\t/** Runs before the branch is resolved; may rewrite the name (function form) or abort. */\n\t// biome-ignore lint/suspicious/noConfusingVoidType: a `before` hook may return an override or nothing — `void` (not `undefined`) is what lets a no-op `() => {}` validation hook type-check.\n\tbefore?: Hook<CheckoutBeforeContext, CheckoutBeforeResult | void>;\n\t/** Runs after checkout + env pull. Use `branch.created` to distinguish new vs existing. */\n\tafter?: Hook<CheckoutAfterContext>;\n}\n\n/**\n * Hooks for branch **creation**. Fires only when `checkout` (or another consumer of the\n * runtime's create operation) actually creates a new branch — not when `checkout` selects\n * an existing one. Distinct from `checkout`, which brackets the whole `checkout` command\n * regardless of whether it created or selected a branch: use `create` when you specifically\n * care about the creation moment.\n */\nexport interface CreateHooks {\n\t/** Runs before the branch is created; throw/non-zero exit to abort. */\n\tbefore?: Hook<CreateBeforeContext, void>;\n\t/** Runs after the branch is created and the policy applied. */\n\tafter?: Hook<CreateAfterContext>;\n}\n\n/** Hooks for the `deploy` command (`neon deploy` / `config apply`). */\nexport interface DeployHooks {\n\t/** Runs before the policy is applied; throw/non-zero exit to abort. */\n\tbefore?: Hook<DeployBeforeContext, void>;\n\t/** Runs after a successful apply + env pull. */\n\tafter?: Hook<DeployAfterContext>;\n}\n\n/**\n * Imperative lifecycle hooks, keyed by the phase they bracket. Each phase exposes a\n * `before` (influence/abort) and `after` (observe) hook. Hooks never run during `plan` /\n * `status` / `inspect`.\n *\n * `env` in every `after` hook is the fixed {@link HookEnv}, not a policy-exact type — see\n * that type's doc comment for why.\n */\nexport interface Hooks {\n\tcheckout?: CheckoutHooks;\n\tcreate?: CreateHooks;\n\tdeploy?: DeployHooks;\n}\n\n/**\n * A function with all deploy defaults applied. `resolveConfig` fills in `runtime` so\n * downstream diff/apply never has to re-derive it.\n */\nexport interface ResolvedFunctionConfig {\n\tslug: string;\n\tname: string;\n\tsource: string;\n\tenv: Record<string, string>;\n\t/**\n\t * Packages the bundler leaves unresolved, normalized from\n\t * {@link FunctionDef.externalPackages} with `includeFiles` defaulted.\n\t *\n\t * Absent rather than empty when undeclared, so a policy that never mentions it takes the\n\t * pre-existing bundling path and produces the archive it always did.\n\t */\n\texternalPackages?: ResolvedExternalPackage[];\n\truntime: FunctionRuntime;\n\tbundler: FunctionBundlerInput;\n\t/**\n\t * Local-development settings, passed through untouched from {@link FunctionDef.dev}\n\t * (no defaults applied). Only consumed by `neon dev`; deploy ignores it.\n\t */\n\tdev?: FunctionDevConfig;\n\t/**\n\t * Normalized hostnames this function should own on the branch. Absent when this\n\t * branch has no list to apply. Empty when tuning replaced the list with `[]`.\n\t */\n\tcustomDomains?: string[];\n}\n\nexport type ResolvedFunctionTrigger =\n\t| ResolvedFunctionScheduleTrigger\n\t| ResolvedFunctionStorageObjectCreatedTrigger;\n\nexport interface ResolvedFunctionScheduleTrigger {\n\ttype: \"schedule\";\n\tname: string;\n\tfunctionSlug: string;\n\tcron: string;\n\tfunctionPath: string;\n\tenabled: boolean;\n}\n\nexport interface ResolvedFunctionStorageObjectCreatedTrigger {\n\ttype: \"storage_object_created\";\n\tname: string;\n\tfunctionSlug: string;\n\tbucketName: string;\n\tprefix?: string;\n\tfunctionPath: string;\n\tenabled: boolean;\n}\n\n/** A bucket with its access level defaulted to `private`. */\nexport interface ResolvedBucketConfig {\n\tname: string;\n\taccess: BucketAccessLevel;\n}\n\n/**\n * Normalized {@link PreviewInput}. Only present on {@link ResolvedBranchConfig} when the\n * policy returned a `preview` block. `aiGatewayEnabled` follows the same\n * \"present-and-not-`false`\" semantics as `authEnabled` / `dataApiEnabled`.\n */\nexport interface ResolvedPreviewConfig {\n\tfunctions: ResolvedFunctionConfig[];\n\tbuckets: ResolvedBucketConfig[];\n\taiGatewayEnabled: boolean;\n}\n\n/**\n * Normalized Data API integration. Present on {@link ResolvedBranchConfig} only when the\n * policy enables `dataApi`. `authProvider` always resolves (defaults to `\"neon\"`); the\n * external-IdP wiring is present only for `\"external\"`; `settings` carries the camelCase\n * runtime settings (reconciled as an update when they drift).\n */\nexport interface ResolvedDataApiConfig {\n\tauthProvider: DataApiAuthProvider;\n\tjwksUrl?: string;\n\tproviderName?: string;\n\tjwtAudience?: string;\n\tsettings?: DataApiSettings;\n}\n\nexport interface ResolvedBranchConfig {\n\tparent?: string;\n\tttlSeconds?: number;\n\tprotected?: boolean;\n\tpostgres?: PostgresConfig;\n\t/** Optional for compatibility with hand-built configs. */\n\trealtimePolicy?: \"omitted\" | \"enabled\" | \"disabled\";\n\t/** Realtime options to apply when {@link realtimePolicy} is `\"enabled\"`. */\n\trealtime?: RealtimeConfig;\n\tauthEnabled: boolean;\n\tdataApiEnabled: boolean;\n\t/** Optional for compatibility with hand-built configs. */\n\tdataApiPolicy?: \"omitted\" | \"enabled\" | \"disabled\";\n\t/**\n\t * Resolved Data API integration. Present iff {@link dataApiEnabled} is `true`. Carries the\n\t * create-time auth wiring and the updatable {@link DataApiSettings}.\n\t */\n\tdataApi?: ResolvedDataApiConfig;\n\tpreview?: ResolvedPreviewConfig;\n\t/**\n\t * Resolved triggers from {@link Config.triggers}. Absent when none are declared\n\t * (hand-built configs may omit it).\n\t */\n\ttriggers?: ResolvedFunctionTrigger[];\n}\n\n/**\n * One concrete change `pushConfig` made (or, in dry-run, would make) on the remote.\n */\nexport interface AppliedChange {\n\t/**\n\t * `service` covers branch-scoped integrations driven by the branch policy (e.g.\n\t * Neon Auth, Data API).\n\t */\n\tkind: \"branch\" | \"service\";\n\taction: \"create\" | \"update\" | \"delete\" | \"noop\";\n\tidentifier: string;\n\tdetails?: Record<string, unknown>;\n}\n\n/**\n * A diff entry that conflicts with the desired config. `pushConfig` throws\n * {@link PushConflictError} on the first call when conflicts exist; pass\n * `updateExisting: true` to apply mutable drift (settings, `protected`, TTL, project\n * rename). Immutable fields (region, Postgres major version) are always conflicts —\n * recreate the project to change them.\n */\nexport interface ConflictReport {\n\tkind: \"branch\";\n\tidentifier: string;\n\tfield: string;\n\tcurrent: unknown;\n\tdesired: unknown;\n\treason: string;\n}\n\n/**\n * Result of a `pushConfig` invocation.\n */\nexport interface PushResult {\n\tprojectId: string;\n\torgId?: string;\n\tbranchId: string;\n\tbranchName: string;\n\t/**\n\t * `true` when `pushConfig` was called with `{ dryRun: true }`. `applied` then records\n\t * what **would** be applied on a real push; no API mutations were performed.\n\t */\n\tdryRun: boolean;\n\tapplied: AppliedChange[];\n\tconflicts: ConflictReport[];\n\t/**\n\t * Declared custom domains for this branch after the push (or what apply would\n\t * leave in place). `cnameTarget` is omitted when the domain is not registered yet\n\t * (dry-run of a new registration). An empty string means the region has no\n\t * custom-domains front door.\n\t */\n\tcustomDomains?: Array<{\n\t\tdomain: string;\n\t\tslug: string;\n\t\tcnameTarget?: string;\n\t}>;\n\t/**\n\t * Advisory findings from the push — a function that bundles a native dependency it never\n\t * declared, or a staged package whose version could not be pinned.\n\t *\n\t * Returned rather than logged, because a library has no business choosing an output\n\t * channel, and returned rather than left to an opt-in callback, because these are the\n\t * only warning that a deployed function will fail at invoke and an unregistered callback\n\t * is easy to never notice. Empty when there is nothing to report.\n\t *\n\t * Only populated by the built-in bundler: a caller that injects its own `bundleFunction`\n\t * owns its own reporting.\n\t */\n\twarnings: string[];\n}\n"],"mappings":";;;;;;AAKA,MAAa,gBAAgB;CAC5B;CAAM;CAAK;CAAG;CAAG;CAAG;CAAG;CAAG;CAAG;CAAG;CAAG;CAAG;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CACtE;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;AACrE;;;;;;;;;;;;;AA2NA,MAAa,0BAA0B,CAAC,QAAQ,UAAU"}
|
|
1
|
+
{"version":3,"file":"types.js","names":[],"sources":["../../src/lib/types.ts"],"sourcesContent":["/**\n * Every compute size in the Console size table\n * (https://neon.com/docs/manage/endpoints#compute-size-and-autoscaling-configuration).\n * Plan availability is enforced by the API, not this list.\n */\nexport const COMPUTE_UNITS = [\n\t0.25, 0.5, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 18, 20,\n\t22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56,\n] as const;\n\nexport type ComputeUnit = (typeof COMPUTE_UNITS)[number];\n\n/** Time units accepted in a {@link DurationString}: seconds, minutes, hours, days, weeks. */\nexport type DurationUnit = \"s\" | \"m\" | \"h\" | \"d\" | \"w\";\n\n/**\n * A Neon duration string: a positive integer **followed by a unit** — `s` (seconds),\n * `m` (minutes), `h` (hours), `d` (days), or `w` (weeks). Used by\n * {@link ComputeSettings.suspendTimeout} and {@link BranchTuning.ttl}.\n *\n * A **unit is required**: a bare numeric string like `\"7\"` is rejected at the type level. To\n * express a raw number of seconds, pass a `number` (`300`) — not a string (`\"300\"`). This\n * removes the old ambiguity where `\"7\"` silently meant 7 *seconds* instead of, say, `\"7d\"`.\n *\n * @example \"5m\" // 5 minutes\n * @example \"1h\" // 1 hour\n * @example \"7d\" // 7 days\n */\nexport type DurationString = `${number}${DurationUnit}`;\n\n/**\n * Autocomplete suggestions for {@link ComputeSettings.suspendTimeout}. Every value sits inside\n * the Neon API's allowed scale-to-zero band: **60s–604800s** (1 minute – 1 week). This is *not*\n * a closed set — the field also accepts any other {@link DurationString} or a `number` of\n * seconds; out-of-range values type-check but are rejected at apply time.\n */\ntype SuspendTimeoutSuggestion =\n\t| \"1m\"\n\t| \"5m\"\n\t| \"15m\"\n\t| \"30m\"\n\t| \"1h\"\n\t| \"6h\"\n\t| \"12h\"\n\t| \"1d\"\n\t| \"7d\";\n\n/**\n * Autocomplete suggestions for {@link BranchTuning.ttl}. Every value sits within the Neon API's\n * branch-expiration limit (**max 30 days** from creation; the Console's own presets are 1h / 1d\n * / 7d). This is *not* a closed set — the field also accepts any other {@link DurationString} or\n * a `number` of seconds; values over 30 days are rejected at apply time.\n */\ntype TtlSuggestion = \"1h\" | \"6h\" | \"12h\" | \"1d\" | \"3d\" | \"7d\" | \"14d\" | \"30d\";\n\n/**\n * Compose a field's duration type: its curated autocomplete `Suggestions` plus the open\n * `DurationString` template (so any `<integer><unit>` string still type-checks) and a `number`\n * of seconds. Intersecting the template arm with `NonNullable<unknown>` stops TypeScript from\n * collapsing the literal suggestions into the template, which is what preserves the autocomplete.\n */\ntype DurationField<Suggestions extends DurationString> =\n\t| Suggestions\n\t| (DurationString & NonNullable<unknown>)\n\t| number;\n\n/**\n * Compute settings applied to the read/write endpoint of a branch.\n *\n * Mirrors the subset of {@link https://api-docs.neon.tech/reference/getting-started-with-neon-api Neon endpoint}\n * fields that we expose as IaC primitives. Anything left undefined falls back to the project's\n * `default_endpoint_settings` (which themselves fall back to Neon defaults).\n */\nexport interface ComputeSettings {\n\t/**\n\t * Minimum number of Compute Units. Set to 0.25 for true scale-to-zero.\n\t *\n\t * Sizes above 16 CU are fixed-size only: if this is set with a different\n\t * {@link ComputeSettings.autoscalingLimitMaxCu}, both bounds must be ≤ 16 and\n\t * `max - min` cannot exceed 8 CU. A single bound is checked against the catalog\n\t * only — the other bound comes from the project's default endpoint settings, so\n\t * the API is the arbiter of the resolved pair.\n\t *\n\t * @example 0.25 // scale-to-zero\n\t * @example 1 // always-on with 1 CU minimum\n\t * @example 4\n\t */\n\tautoscalingLimitMinCu?: ComputeUnit;\n\t/**\n\t * Maximum number of Compute Units for autoscaling, or the fixed size when equal\n\t * to {@link ComputeSettings.autoscalingLimitMinCu}.\n\t *\n\t * @example 2\n\t * @example 12\n\t * @example 56 // fixed-size; pair with the same min\n\t */\n\tautoscalingLimitMaxCu?: ComputeUnit;\n\t/**\n\t * How long an idle compute waits before suspending (Neon's scale-to-zero). Accepts a\n\t * {@link DurationString} (autocompletes common values), a number of seconds, or `false`.\n\t *\n\t * - `false` — never suspend (always-on compute)\n\t * - {@link DurationString} — e.g. `\"5m\"`; autocompletes the in-range values `\"1m\"`, `\"5m\"`,\n\t * `\"15m\"`, `\"30m\"`, `\"1h\"`, `\"6h\"`, `\"12h\"`, `\"1d\"`, `\"7d\"`, and accepts any other\n\t * `<integer><unit>` (units: `s`, `m`, `h`, `d`, `w`). A **unit is required** — for raw\n\t * seconds pass a `number`, not a string.\n\t * - `number` — custom timeout in **seconds**, must be in `60`–`604800` (1 minute to 1 week)\n\t * - `undefined` — use the Neon default (currently 300s / 5 minutes)\n\t *\n\t * Whichever form you use, the resolved timeout must fall in `60`–`604800` seconds (the Neon\n\t * API limit); the suggestions are all within that band, anything else is checked at apply.\n\t *\n\t * @example false // never suspend (always-on)\n\t * @example \"5m\" // suspend after 5 minutes idle\n\t * @example \"1h\" // suspend after 1 hour idle\n\t * @example 300 // 5 minutes, expressed in seconds\n\t */\n\tsuspendTimeout?: false | DurationField<SuspendTimeoutSuggestion>;\n}\n\n/**\n * Read-only descriptor of the branch a {@link Config} policy is being evaluated for — the\n * `branch` argument passed to your `defineConfig({ branch: (branch) => … })` closure. It describes\n * **which** branch this invocation decides for; it is not a live branch handle and must not\n * be mutated. Switch on its fields and return the desired {@link BranchConfig}.\n */\nexport interface BranchTarget {\n\t/** Branch name being evaluated. For `branch dev`, this is the generated branch name. */\n\tname: string;\n\t/** Neon branch id when the branch already exists. Undefined during pre-create eval. */\n\tid?: string;\n\t/** Whether this branch already exists on Neon. */\n\texists: boolean;\n\t/** Parent branch id from Neon when known. */\n\tparentId?: string;\n\t/** Whether Neon marks this branch as the project default. */\n\tisDefault?: boolean;\n\t/** Whether Neon currently marks this branch protected. */\n\tisProtected?: boolean;\n\t/** Current expiration timestamp from Neon, when set. */\n\texpiresAt?: string;\n}\n\n/**\n * Object form of a branch-scoped service toggle. `{}` or `{ enabled: true }` enables it;\n * `{ enabled: false }` opts out. Used as the object half of {@link ServiceToggleInput}.\n */\nexport interface ServiceToggle {\n\t/** Defaults to `true` when the service namespace is present. Set `false` to opt out. */\n\tenabled?: boolean;\n}\n\n/**\n * How a branch-scoped service (Neon Auth, Data API, AI Gateway) is toggled in a policy.\n *\n * - `true` / `{}` / `{ enabled: true }` — enabled.\n * - `false` / `{ enabled: false }` — disabled.\n * - omitted (`undefined`) — not part of the policy at all.\n *\n * These toggles are **static** (they live in the top-level `defineConfig({ … })` object,\n * not in the per-branch `branch` closure) so the secret set they imply can be derived at\n * the type level — that's what makes `NeonEnv<typeof config>` exact.\n */\nexport type ServiceToggleInput = boolean | ServiceToggle;\n\n/**\n * Realtime settings for a branch. The object's presence enables Realtime; omit\n * `allowedOrigins` to leave the inherited/current allowlist unchanged.\n */\nexport interface RealtimeConfig {\n\t/** Browser origins allowed to connect. `[]` or `[\"*\"]` allows every origin. */\n\tallowedOrigins?: readonly string[];\n}\n\n/**\n * How Realtime is managed by a policy.\n *\n * - `true` — enable Realtime without changing allowed origins.\n * - `{ allowedOrigins?: [...] }` — enable Realtime and optionally configure origins.\n * - `false` — disable Realtime.\n * - omitted (`undefined`) — leave Realtime unmanaged.\n */\nexport type RealtimeInput = boolean | RealtimeConfig;\n\n/**\n * Resolve a **static** service toggle (`true` / `false` / `{ enabled?: boolean }` / object /\n * `undefined`) to a type-level boolean. The tuple wrapping (`[T] extends […]`) disables\n * distribution so a union/`undefined` is judged as a single unit:\n *\n * - `false` / `{ enabled: false }` / `undefined` → `false`\n * - `true` / `{ enabled: true }` / any other object (`{}`, `{ enabled?: boolean }`) → `true`\n * (a present toggle defaults to enabled)\n * - the bare `boolean | … | undefined` (no literal info) → `false`\n *\n * Shared by the {@link Config} static cross-field checks and the `@neon/env`\n * `NeonEnv` namespace derivation, so both read \"is this service on?\" identically.\n */\nexport type ServiceEnabled<T> = [T] extends [false]\n\t? false\n\t: [T] extends [{ enabled: false }]\n\t\t? false\n\t\t: [T] extends [undefined]\n\t\t\t? false\n\t\t\t: [T] extends [true]\n\t\t\t\t? true\n\t\t\t\t: [T] extends [{ enabled: true }]\n\t\t\t\t\t? true\n\t\t\t\t\t: [T] extends [object]\n\t\t\t\t\t\t? true\n\t\t\t\t\t\t: false;\n\nexport interface PostgresConfig {\n\tcomputeSettings?: ComputeSettings;\n}\n\n/**\n * Authentication providers a Data API integration can verify JWTs against, as written in\n * `neon.ts`. Friendly authoring values (mapped to the Neon API's `neon_auth` / `external`\n * at the API boundary):\n *\n * - `\"neon\"` — verify tokens minted by **Neon Auth** on the same branch. Neon supplies the\n * JWKS URL / provider wiring for you, so the `jwksUrl` / `providerName` / `jwtAudience`\n * fields are forbidden (a type error) on this variant — and the policy must also enable\n * top-level `auth` (Neon Auth) so the tokens exist.\n * - `\"external\"` — verify tokens from a third-party IdP (Clerk, Stytch, Auth0, …). You\n * provide `jwksUrl` (and optionally `providerName` / `jwtAudience`).\n */\nexport const DATA_API_AUTH_PROVIDERS = [\"neon\", \"external\"] as const;\nexport type DataApiAuthProvider = (typeof DATA_API_AUTH_PROVIDERS)[number];\n\n/**\n * Reusable runtime settings for a Data API integration (the Neon API `DataAPISettings`,\n * camelCased to match the rest of `neon.ts`). Every field is optional; omitted fields keep\n * the Neon defaults shown below. These are the **only** Data API fields that can change on\n * an already-enabled integration — drift here is reconciled as an *update* (requires\n * `updateExisting` / `--update-existing`); the create-only auth wiring above cannot.\n */\nexport interface DataApiSettings {\n\t/** Enable the aggregates feature (`db_aggregates_enabled`). Default `true`. */\n\tdbAggregatesEnabled?: boolean;\n\t/** Database role used for anonymous requests (`db_anon_role`). Default `\"anonymous\"`. */\n\tdbAnonRole?: string;\n\t/** Extra schemas appended to the search path (`db_extra_search_path`). */\n\tdbExtraSearchPath?: string;\n\t/** Maximum rows returned in a single request (`db_max_rows`). */\n\tdbMaxRows?: number;\n\t/** Schemas exposed via the API (`db_schemas`). Default `[\"public\"]`. */\n\tdbSchemas?: string[];\n\t/** JWT claim key used for role extraction (`jwt_role_claim_key`). Default `\".role\"`. */\n\tjwtRoleClaimKey?: string;\n\t/** Maximum lifetime of the JWT cache, in seconds (`jwt_cache_max_lifetime`). */\n\tjwtCacheMaxLifetime?: number;\n\t/** OpenAPI spec mode (`openapi_mode`). Default `\"disabled\"`. */\n\topenapiMode?: \"ignore-privileges\" | \"disabled\";\n\t/** CORS allowed origins (`server_cors_allowed_origins`). */\n\tserverCorsAllowedOrigins?: string;\n\t/** Emit server-timing headers (`server_timing_enabled`). */\n\tserverTimingEnabled?: boolean;\n}\n\n/** Fields shared by every {@link DataApiConfig} variant. */\ninterface DataApiConfigBase {\n\t/** Defaults to `true` when the `dataApi` namespace is present. `false` disables and apply deletes. */\n\tenabled?: boolean;\n\t/** Reusable runtime settings. Drift here is reconciled as an update. */\n\tsettings?: DataApiSettings;\n}\n\n/**\n * Data API verified by **Neon Auth** (`authProvider: \"neon\"`, the default). The external\n * IdP fields are statically forbidden (`?: never`) because Neon supplies them; declaring any\n * of them is a type error directing you to `authProvider: \"external\"`.\n */\nexport interface DataApiNeonAuthConfig extends DataApiConfigBase {\n\tauthProvider?: \"neon\";\n\t/** Forbidden with `authProvider: \"neon\"` — Neon provides the JWKS URL. */\n\tjwksUrl?: never;\n\t/** Forbidden with `authProvider: \"neon\"` — the provider is Neon Auth. */\n\tproviderName?: never;\n\t/** Forbidden with `authProvider: \"neon\"` — Neon manages the audience. */\n\tjwtAudience?: never;\n}\n\n/**\n * Data API verified by an **external** IdP (`authProvider: \"external\"`). You provide the\n * JWKS URL (and optionally a provider label / expected audience).\n */\nexport interface DataApiExternalAuthConfig extends DataApiConfigBase {\n\tauthProvider: \"external\";\n\t/** URL that publishes the IdP's JWKS (JSON Web Key Set). */\n\tjwksUrl?: string;\n\t/** Human label for the IdP (e.g. \"Clerk\", \"Stytch\", \"Auth0\"). */\n\tproviderName?: string;\n\t/**\n\t * Expected `aud` claim. ⚠️ This only **rejects** tokens carrying a *different* audience;\n\t * tokens with no `aud` claim are still accepted.\n\t */\n\tjwtAudience?: string;\n}\n\n/**\n * Object form of the `dataApi` toggle. A discriminated union on {@link DataApiAuthProvider}:\n * the `\"neon\"` variant forbids the external-IdP fields, the `\"external\"` variant allows them.\n */\nexport type DataApiConfig = DataApiNeonAuthConfig | DataApiExternalAuthConfig;\n\n/**\n * How the Data API is toggled in a policy: a bare boolean (like the other service toggles)\n * or the richer {@link DataApiConfig} object. `true` / `{}` / `{ enabled: true }` enable it\n * with Neon defaults. `false` / `{ enabled: false }` disable it; apply deletes an existing\n * Data API. Omit the field to leave an existing integration alone.\n */\nexport type DataApiInput = boolean | DataApiConfig;\n\n/**\n * Supported function runtimes. Mirrors the Neon Functions deploy API `runtime` enum.\n * Only `nodejs24` exists today; kept as a union so adding runtimes later is a\n * non-breaking, type-checked change.\n */\nexport type FunctionRuntime = \"nodejs24\";\n\n/**\n * Local-development settings for a function, used by `neon dev` when it serves every\n * function declared in `neon.ts` (i.e. invoked with no `--source`). Never affects deploy.\n */\nexport interface FunctionDevConfig {\n\t/**\n\t * Port the local server binds. Bound exactly (and `neon dev` fails loudly if it is taken)\n\t * when set; a free port is found automatically when omitted.\n\t */\n\tport?: number;\n}\n\n/**\n * The object form of an {@link FunctionDef.externalPackages} entry, for the one case the\n * bare string cannot express: externalizing a package without shipping its files.\n */\nexport interface ExternalPackageDef {\n\t/** Package name, optionally with a subpath: `sharp`, `@scope/pkg`, `pkg/sub`. */\n\tname: string;\n\t/**\n\t * Whether the package's real files ship into the deployed archive next to the bundle.\n\t *\n\t * Defaults to `true`, which is the state where the import resolves and the function\n\t * works. Set it to `false` only for a package the function never reaches: nothing is\n\t * shipped for it, so reaching it throws `Cannot find module` at invoke.\n\t */\n\tincludeFiles?: boolean;\n}\n\n/**\n * One entry of {@link FunctionDef.externalPackages}. A bare string is the common form and\n * ships the package's files; {@link ExternalPackageDef} exists to turn that off.\n */\nexport type ExternalPackageEntry = string | ExternalPackageDef;\n\n/**\n * An {@link ExternalPackageEntry} with its default applied, as every consumer downstream of\n * `resolveConfig` reads it.\n */\nexport interface ResolvedExternalPackage {\n\t/** Package name as declared, subpath included. */\n\tname: string;\n\t/** Whether this package's files are staged into the archive. */\n\tincludeFiles: boolean;\n}\n\n/** Archive-relative paths. The runtime imports `index.mjs` or `index.js` at the root. */\nexport type FunctionBundle = Record<string, Uint8Array>;\n\n/** Defined here so policy imports stay free of build-time dependencies. */\nexport type FunctionBundler = (\n\tfn: ResolvedFunctionConfig,\n) => Promise<FunctionBundle>;\n\n/**\n * `\"esbuild\"` (default) bundles a file, or a directory from the first of\n * `index.ts`, `index.js`, `index.mjs`. `\"none\"` ships a prebuilt directory or a\n * single `index.mjs` / `index.js`. An inline {@link FunctionBundler} returns the\n * file map.\n */\nexport type FunctionBundlerInput = \"esbuild\" | \"none\" | FunctionBundler;\n\n/**\n * Static definition of a Neon Function. Declares that the function\n * **exists** on every branch; its branch-unique slug is the **record key** in\n * `functions` (or deprecated {@link PreviewInput.functions}), so slugs are statically enumerable,\n * cannot duplicate, and the `branch` closure can only tune slugs that are declared here.\n * Runtime tuning is **not** here — it varies per branch and lives in the `branch` closure\n * (see {@link FunctionTuning}). Memory is fixed by the platform policy for now and is not\n * user-configurable.\n */\nexport interface FunctionDef {\n\t/** Free-form display name. @example \"Hello World\" */\n\tname: string;\n\t/**\n\t * Path to the entry module or source directory, relative to `neon.ts` (or\n\t * absolute). A file is the entry; a directory is searched for `index.ts`,\n\t * then `index.js`, then `index.mjs`. A JS function value has no source path\n\t * for a bundler to resolve.\n\t * @example \"./functions/hello-world.ts\"\n\t * @example \".mastra/output\"\n\t */\n\tsource: string;\n\t/**\n\t * Environment variables injected into the deployed function, keyed by the var name the\n\t * function reads at runtime. The **keys** are static (preserved at the type level so\n\t * `parseEnv(config, \"<slug>\").function.<key>` is typed). An unset `process.env.X`\n\t * fails validation. Omit a key to preserve its deployed value; an empty string deletes it.\n\t * @example { resendApiKey: process.env.RESEND_API_KEY! }\n\t */\n\tenv?: Record<string, string>;\n\t/**\n\t * Ship a dependency's real files into the deployed archive instead of bundling it —\n\t * `sharp` and other packages backed by a native binary.\n\t *\n\t * The deploy-time equivalent of Next.js's `serverExternalPackages`. Every entry is passed\n\t * to esbuild's `external`, so the import survives into the bundle instead of being\n\t * followed, and the package's own files are shipped beside the bundle so that import\n\t * resolves.\n\t *\n\t * Reach for this when bundling a package is impossible rather than merely undesirable.\n\t * The case that comes up is a package backed by a native `.node` binary: the binary is a\n\t * compiled object the platform loads from a real path, so no bundler can inline it.\n\t * `sharp` is the common one, and it does not even fail at build time — it loads its\n\t * binary through `createRequire`, which esbuild does not follow, so it bundles cleanly\n\t * and then fails at invoke with \"Could not load the sharp module\".\n\t *\n\t * ```ts\n\t * externalPackages: [\"sharp\"]\n\t * ```\n\t *\n\t * Each declared package is installed for the Functions runtime target — **linux-arm64,\n\t * glibc** — into a throwaway directory, traced for the files it actually reaches, and\n\t * copied into the archive under `node_modules/` with its directory layout preserved. That\n\t * layout is load-bearing rather than cosmetic: a `.node` addon locates its sibling shared\n\t * libraries relative to its own directory, so a flattened tree fails to load.\n\t *\n\t * Your own `node_modules` is never read for these files or modified. Its binaries are\n\t * built for your machine rather than the deploy target, and a cross-platform install does\n\t * not survive your next plain `npm install`, so the target's packages are resolved fresh\n\t * on each deploy.\n\t *\n\t * Requirements, all reported at deploy time rather than at invoke: the package must\n\t * publish a linux-arm64 glibc build (`sharp` and most `@napi-rs/*` packages do; anything\n\t * compiled from source at install time does not), `npm` must be on `PATH`, and the\n\t * archive must stay inside the deploy size limits — native binaries are large.\n\t *\n\t * ### Excluding a package's files\n\t *\n\t * `includeFiles: false` externalizes the import without shipping anything, which is the\n\t * escape hatch for a package that cannot be staged — no build for the target, or too\n\t * large — and that the function never actually reaches:\n\t *\n\t * ```ts\n\t * externalPackages: [\"sharp\", { name: \"canvas\", includeFiles: false }]\n\t * ```\n\t *\n\t * **An excluded package is not resolvable at runtime.** Nothing is shipped for it, so it\n\t * throws `Cannot find module` if the function reaches it. It unblocks an import that is\n\t * never evaluated; it does not make a dependency usable.\n\t *\n\t * Entries are package names, optionally with a subpath (`pkg`, `@scope/pkg`, `pkg/sub`),\n\t * matching esbuild. A relative or absolute path is rejected at validation time: those are\n\t * local modules, and a local module that cannot be bundled is a different problem. Files\n\t * are staged per package, so a subpath narrows what esbuild leaves unresolved without\n\t * narrowing what ships.\n\t *\n\t * Under `neon dev` the list only keeps the package out of the bundle — nothing is\n\t * installed or copied, and it resolves from your own `node_modules` against your host\n\t * architecture, which is what you want locally.\n\t * @example [\"sharp\", { name: \"canvas\", includeFiles: false }]\n\t */\n\texternalPackages?: ExternalPackageEntry[];\n\t/**\n\t * How {@link source} becomes deployable files. Defaults to `\"esbuild\"`.\n\t * `\"none\"` ships a prebuilt directory or `index.mjs` / `index.js` file.\n\t * An inline {@link FunctionBundler} returns the file map used by deploy and\n\t * `neon dev`. Inline functions do not round-trip through inspect or pull and\n\t * must be re-declared.\n\t * @example \"none\"\n\t * @example (fn) => myFrameworkBuild(fn.source)\n\t */\n\tbundler?: FunctionBundlerInput;\n\t/**\n\t * Local-development settings used by `neon dev` when serving every function from\n\t * `neon.ts`. Ignored at deploy time. See {@link FunctionDevConfig}.\n\t */\n\tdev?: FunctionDevConfig;\n\t/**\n\t * Customer-owned hostnames that should point at this function.\n\t * v1 only supports functions. Hostnames are unique across functions in the resolved\n\t * policy. Applied after the function is deployed, on the project's default branch.\n\t * Other branches apply a list only when {@link FunctionTuning.customDomains} sets one.\n\t * Domains that exist remotely but are omitted here are left alone — delete with\n\t * `neon function domains delete`.\n\t *\n\t * @example [\"docs.example.com\"]\n\t */\n\tcustomDomains?: string[];\n}\n\n/**\n * A trigger that invokes a function. The trigger name is the record key in\n * {@link Config.triggers}. `functionPath` defaults to `/`. `enabled` defaults to `true`.\n *\n * @example { type: \"schedule\", function: \"cron\", cron: \"0 * * * *\" }\n * @example { type: \"storage_object_created\", function: \"ingest\", bucket: \"assets\", prefix: \"logos/\" }\n */\nexport type FunctionTriggerDef =\n\t| FunctionScheduleTriggerDef\n\t| FunctionStorageObjectCreatedTriggerDef;\n\n/**\n * A cron schedule that invokes a function. `function` is a slug from {@link Config.functions}\n * (or deprecated `preview.functions`). `cron` is a numeric five-field expression in UTC.\n *\n * @example { type: \"schedule\", function: \"cron\", cron: \"0 * * * *\" }\n */\nexport interface FunctionScheduleTriggerDef {\n\ttype: \"schedule\";\n\tfunction: string;\n\tcron: string;\n\tfunctionPath?: string;\n\tenabled?: boolean;\n}\n\n/**\n * Invokes a function when an object is created in a bucket from {@link Config.buckets}\n * (or deprecated `preview.buckets`). `prefix` is an exact object-key prefix; omit it to\n * match every key in the bucket.\n *\n * @example { type: \"storage_object_created\", function: \"ingest\", bucket: \"assets\", prefix: \"logos/\" }\n */\nexport interface FunctionStorageObjectCreatedTriggerDef {\n\ttype: \"storage_object_created\";\n\tfunction: string;\n\tbucket: string;\n\tprefix?: string;\n\tfunctionPath?: string;\n\tenabled?: boolean;\n}\n\n/**\n * A single capability a branch-scoped service credential may exercise (Preview). A\n * credential is granted a set of these and may only perform the listed actions. Mirrors\n * the Neon API `CredentialScope` enum (`x-stability-level: beta`):\n *\n * - `storage:read` / `storage:write` — object-storage (bucket) access via the S3 key.\n * - `ai_gateway:invoke` — call the AI Gateway with the bearer `api_token`.\n * - `functions:invoke` — invoke Neon Functions with the bearer `api_token`.\n *\n * The set a policy needs is derived from its enabled Preview features (see\n * {@link deriveCredentialScopes}); it is never authored by hand.\n */\nexport type CredentialScope =\n\t| \"storage:read\"\n\t| \"storage:write\"\n\t| \"ai_gateway:invoke\"\n\t| \"functions:invoke\";\n\n/**\n * Who a credential acts as. `user` is the developer/app principal minted for local dev and\n * app bootstrap (`fetchEnv` / `env pull`); `function` is a deployed-function principal\n * (carries a `function_id`). The env tooling only mints `user` credentials today.\n */\nexport type CredentialPrincipalType = \"user\" | \"function\";\n\n/** Anonymous-access level for a branchable object-storage bucket. */\nexport type BucketAccessLevel = \"private\" | \"public_read\";\n\n/**\n * Static definition of a branchable object-storage bucket. The bucket's\n * name is the **record key** in `buckets` (or deprecated {@link PreviewInput.buckets}), so names are statically\n * enumerable and cannot duplicate.\n */\nexport interface BucketDef {\n\t/**\n\t * Anonymous access level. `private` (default) requires authenticated reads/writes;\n\t * `public_read` allows anonymous GetObject/HeadObject.\n\t */\n\taccess?: BucketAccessLevel;\n}\n\n/** Preview features, plus deprecated homes for services that have graduated to GA. */\nexport interface PreviewInput {\n\t/** Enable, configure, or disable Realtime on every branch this policy is applied to. */\n\trealtime?: RealtimeInput;\n\t/**\n\t * Enable/disable the AI Gateway on the branch (toggle, like auth / dataApi).\n\t * @deprecated Use top-level `aiGateway`.\n\t */\n\taiGateway?: ServiceToggleInput;\n\t/**\n\t * Functions to deploy, keyed by branch-unique slug (`^[a-z0-9]{1,20}$`).\n\t * @deprecated Use top-level `functions`.\n\t */\n\tfunctions?: Record<string, FunctionDef>;\n\t/**\n\t * Object-storage buckets to create, keyed by bucket name.\n\t * @deprecated Use top-level `buckets`.\n\t */\n\tbuckets?: Record<string, BucketDef>;\n}\n\n/**\n * Per-branch deploy tuning for a single function. Returned (per slug) by the `branch`\n * closure. Deliberately **cannot** change the function's existence, source, name, env\n * **keys**, or memory — so the static secret/function set stays sound. Runtime selection\n * and the custom-domain list may vary per branch.\n */\nexport interface FunctionTuning {\n\t/** Runtime to execute the function with. Defaults to `\"nodejs24\"`. */\n\truntime?: FunctionRuntime;\n\t/**\n\t * When present, replaces {@link FunctionDef.customDomains} for this branch.\n\t * `[]` registers nothing on this branch. Omit the key: the default branch\n\t * inherits the static list; other branches do not.\n\t */\n\tcustomDomains?: string[];\n}\n\n/**\n * Per-branch tuning of functions under the deprecated `preview` key.\n * Only existing function slugs may be tuned — `Slug` is constrained to the\n * declared keys by {@link BranchTuningFn}.\n *\n * @deprecated Use top-level `branch: (branch) => ({ functions: { … } })`.\n */\nexport interface PreviewTuning<Slug extends string = string> {\n\t/**\n\t * @deprecated Use top-level `functions` on the object returned by `branch`.\n\t */\n\tfunctions?: Partial<Record<Slug, FunctionTuning>>;\n}\n\n/**\n * The per-branch tuning object returned by the `branch` closure. It can adjust branch\n * lifecycle (`parent`, `ttl`, `protected`), Postgres compute settings, and per-function\n * deploy tuning — but **cannot** add/remove services or functions. That guarantee is what\n * keeps the static secret set (and therefore `NeonEnv`) exact.\n */\nexport interface BranchTuning<Slug extends string = string> {\n\t/** Parent branch name used when creating a new branch. Not a Postgres setting. */\n\tparent?: string;\n\t/**\n\t * Branch time-to-live: how long after creation the branch should auto-expire. Applied\n\t * when creating a new branch and reconciled on existing branches (when `updateExisting`\n\t * is set). Accepts a {@link DurationString} (autocompletes common values) or a number of\n\t * seconds. Omit to keep the branch indefinitely.\n\t *\n\t * - {@link DurationString} — e.g. `\"7d\"`; autocompletes `\"1h\"`, `\"6h\"`, `\"12h\"`, `\"1d\"`,\n\t * `\"3d\"`, `\"7d\"`, `\"14d\"`, `\"30d\"`, and accepts any other `<integer><unit>` (units: `s`,\n\t * `m`, `h`, `d`, `w` — e.g. `\"12h\"`, `\"2w\"`). A **unit is required** — `\"7\"` is rejected;\n\t * for raw seconds pass a `number`.\n\t * - `number` — custom TTL in **seconds** (e.g. `3600`)\n\t * - `undefined` — no expiry; the branch persists until explicitly deleted\n\t *\n\t * The Neon API caps branch expiration at **30 days** from creation, so the resolved TTL must\n\t * be `> 0` and `<= 30d`; the suggestions stay within that limit and anything longer is\n\t * rejected at apply.\n\t *\n\t * @example \"1d\" // ephemeral preview branch: expires a day after creation\n\t * @example \"7d\" // one-week TTL\n\t * @example \"30d\" // the maximum the API allows\n\t * @example 3600 // 1 hour, expressed in seconds\n\t */\n\tttl?: DurationField<TtlSuggestion>;\n\t/** Whether the selected branch should be protected. Undefined means \"leave as-is\". */\n\tprotected?: boolean;\n\tpostgres?: PostgresConfig;\n\t/** Per-function deploy tuning, keyed by declared slug. */\n\tfunctions?: Partial<Record<Slug, FunctionTuning>>;\n\t/**\n\t * @deprecated Use top-level `functions` on this object.\n\t */\n\tpreview?: PreviewTuning<Slug>;\n}\n\n/** Extract declared function slugs from top-level `functions` and/or `preview.functions`. */\ntype PreviewFunctionSlugs<Preview> = Preview extends { functions: infer F }\n\t? Extract<keyof F, string>\n\t: never;\n\n// Config's Functions default is `Record<string, FunctionDef> | undefined`. A string\n// index would otherwise union into FunctionSlugsOf as `string` and drop slug checking\n// on positional `Config<Auth, DataApi, Preview>`.\ntype GaFunctionSlugs<Functions> = [Functions] extends [undefined]\n\t? never\n\t: string extends keyof NonNullable<Functions>\n\t\t? never\n\t\t: Extract<keyof NonNullable<Functions>, string>;\n\ntype FunctionSlugsOf<\n\tPreview extends PreviewInput | undefined,\n\tFunctions extends Record<string, FunctionDef> | undefined = undefined,\n> = [PreviewFunctionSlugs<Preview> | GaFunctionSlugs<Functions>] extends [never]\n\t? string\n\t: PreviewFunctionSlugs<Preview> | GaFunctionSlugs<Functions>;\n\n/**\n * Signature of the `branch` closure. Generic over the static function homes so the\n * `functions` keys it may tune are constrained to the slugs actually declared.\n */\nexport type BranchTuningFn<\n\tPreview extends PreviewInput | undefined = PreviewInput | undefined,\n\tFunctions extends Record<string, FunctionDef> | undefined = undefined,\n> = (branch: BranchTarget) => BranchTuning<FunctionSlugsOf<Preview, Functions>>;\n\n/**\n * A validated Neon branch policy — the value `defineConfig({ … })` returns and `neon.ts`\n * default-exports.\n *\n * Split into a **static** existential set (top-level service toggles and records) and a\n * **dynamic** per-branch `branch` closure for tuning. The static half is what makes the\n * secret set — and therefore `NeonEnv<typeof config>` and `parseEnv` — exact; the closure\n * can tune but never change what exists.\n *\n * Generic over the static fields so the type system can read the exact toggle/slug\n * literals; the defaults make the bare `Config` a usable \"any policy\" type for runtime\n * function signatures. The first three type parameters stay `Auth`, `DataApi`, `Preview`\n * so existing positional `Config<Auth, DataApi, Preview>` consumers keep compiling.\n */\nexport interface Config<\n\tAuth extends ServiceToggleInput | undefined =\n\t\t| ServiceToggleInput\n\t\t| undefined,\n\tDataApi extends DataApiInput | undefined = DataApiInput | undefined,\n\tPreview extends PreviewInput | undefined = PreviewInput | undefined,\n\tFunctions extends Record<string, FunctionDef> | undefined =\n\t\t| Record<string, FunctionDef>\n\t\t| undefined,\n\tBuckets extends Record<string, BucketDef> | undefined =\n\t\t| Record<string, BucketDef>\n\t\t| undefined,\n\tAiGateway extends ServiceToggleInput | undefined =\n\t\t| ServiceToggleInput\n\t\t| undefined,\n> {\n\t/** Neon Auth integration toggle (GA). Static — drives `NeonEnv.auth`. */\n\tauth?: Auth;\n\t/**\n\t * Neon Data API integration (GA). Static — drives `NeonEnv.dataApi`. A boolean/toggle, or\n\t * a {@link DataApiConfig} object selecting the auth provider (`\"neon\"` / `\"external\"`) and\n\t * runtime {@link DataApiSettings}. With `authProvider: \"neon\"` the policy must also enable\n\t * top-level `auth`.\n\t */\n\tdataApi?: DataApi;\n\t/**\n\t * AI Gateway toggle (GA). Static — drives `NeonEnv.aiGateway`. Same shapes as `auth`.\n\t */\n\taiGateway?: AiGateway;\n\t/**\n\t * Functions to deploy, keyed by branch-unique slug (`^[a-z0-9]{1,20}$`).\n\t */\n\tfunctions?: Functions;\n\t/**\n\t * Object-storage buckets to create, keyed by bucket name.\n\t */\n\tbuckets?: Buckets;\n\t/**\n\t * Function triggers, keyed by branch-unique name. Each value names the function\n\t * (and, for `storage_object_created`, the bucket) it binds. Applied after functions\n\t * are deployed. Triggers that exist remotely but are omitted here are left alone.\n\t */\n\ttriggers?: Record<string, FunctionTriggerDef>;\n\t/** Preview features and deprecated aliases for graduated services. */\n\tpreview?: Preview;\n\t/** Per-branch tuning closure. Cannot change the static existential set. */\n\tbranch?: BranchTuningFn<Preview, Functions>;\n\t/**\n\t * Experimental (unstable) features, isolated in their own namespace so they can change\n\t * shape or disappear without touching the rest of the policy. See {@link ExperimentalInput}.\n\t */\n\texperimental?: ExperimentalInput;\n}\n\n/**\n * Experimental (unstable) features. Currently just `hooks`. Kept out of the top-level\n * namespace — rather than a sibling of `auth` / `functions` / `branch` — as a signal that\n * this shape is still moving and isn't covered by the same stability guarantees as the rest\n * of the policy.\n */\nexport interface ExperimentalInput {\n\t/**\n\t * Imperative lifecycle hooks (Preview) — run side effects (migrations, seeding, …) on the\n\t * real `checkout` / `deploy` commands. The declarative companion to {@link Config.branch}:\n\t * hooks never run during `plan` / `status` / `inspect`, so the diff engine stays sound.\n\t * See {@link Hooks}.\n\t */\n\thooks?: Hooks;\n}\n\n// ─── Lifecycle hooks (Preview) ──────────────────────────────────────────────────\n//\n// Hooks are the **imperative** companion to the pure, declarative `branch` closure.\n// `branch()` answers *\"what should this branch look like?\"* (and runs during `plan` /\n// `status` / `apply`, so it must stay side-effect free). Hooks answer *\"do this when a\n// branch is created / checked out / deployed\"* (migrations, seeding, notifications) and\n// run **only** during the real `checkout` / `deploy` commands (and, for `create`,\n// whenever those actually create a branch) — never during `plan` / `status` / `inspect`.\n\n/**\n * Read-only git facts injected into every hook by the CLI. A hook can *read* the git state\n * (to name a branch, gate a migration, …) but the hooks never *drive* git — that keeps the\n * git → Neon relationship a loop-free, one-way edge (`git checkout` syncs Neon, never the\n * reverse). Populated from the surrounding repository; all fields except `available`,\n * `isDetached`, and `isDirty` are absent when {@link available} is `false` (not a git repo,\n * or `git` is not installed).\n *\n * What *triggered* this hook invocation — the installed git hook vs. an explicit CLI\n * command — is a separate concern; see {@link CheckoutEvent} / {@link DeployEvent} on each\n * hook context's `event` field, not this type.\n */\nexport interface GitContext {\n\t/** `false` when the command did not run inside a git work tree (or `git` is missing). */\n\tavailable: boolean;\n\t/** Current branch (`git symbolic-ref --short HEAD`). Undefined in detached-HEAD state. */\n\tbranch?: string;\n\t/**\n\t * `branch`, sanitized into a valid Neon branch name: lowercased, each `/`-separated\n\t * segment reduced to `[a-z0-9-]`, empty results fall back to `\"branch\"`, clamped to 256\n\t * characters. Undefined whenever `branch` is (detached HEAD, not a git repo, or `git` is\n\t * unavailable). Prepend your own prefix with plain string concatenation, e.g.\n\t * `` `preview/${git.neonSafeBranchName}` ``.\n\t */\n\tneonSafeBranchName?: string;\n\t/** Full commit SHA of `HEAD`. */\n\tsha?: string;\n\t/** Abbreviated commit SHA of `HEAD`. */\n\tshortSha?: string;\n\t/** `true` when `HEAD` is detached (no current branch). */\n\tisDetached: boolean;\n\t/** `true` when the work tree has uncommitted changes (`git status --porcelain`). */\n\tisDirty: boolean;\n\t/** Default branch the remote points at (`origin/HEAD`), e.g. `\"main\"`, when resolvable. */\n\tdefaultBranch?: string;\n\t/** `origin` remote URL, when configured. */\n\tremoteUrl?: string;\n\t/** Absolute path to the repository root (`git rev-parse --show-toplevel`). */\n\trepoRoot?: string;\n}\n\n/**\n * What triggered a `checkout` (and the `create` it may perform). `inputName` — what the user\n * typed at a Neon prompt, if anything — lives *inside* the event so narrowing on `event.type`\n * narrows `inputName` too (TypeScript only propagates discriminated-union narrowing within\n * the object actually holding the discriminant, not to sibling fields of an outer object):\n *\n * - `\"git-checkout\"` — the installed `post-checkout` git hook, via `neon git sync`. Carries\n * the git branch that triggered it (`gitBranch`); `inputName` is always `undefined` here —\n * nothing was typed at a Neon prompt. The sanitized Neon-safe form of that branch is on the\n * sibling `git` context, at `git.neonSafeBranchName`.\n * - `\"neon-checkout\"` — an explicit `neon checkout` invocation. `inputName` is the name/id\n * the user passed, or `undefined` when they omitted it (interactive picker).\n */\nexport type CheckoutEvent =\n\t| { type: \"git-checkout\"; gitBranch: string; inputName?: undefined }\n\t| { type: \"neon-checkout\"; inputName?: string };\n\n/** What triggered a `deploy`. Currently always `\"neon-deploy\"` — an explicit `neon deploy` / `config apply` invocation; `deploy` is never triggered by the git hook. */\nexport type DeployEvent = { type: \"neon-deploy\" };\n\n/**\n * The branch a hook is acting on — a resolved, live branch (unlike the pre-create\n * {@link BranchTarget} the `branch` closure may receive). Always carries a concrete `id`.\n */\nexport interface HookBranch {\n\t/** Neon project id the branch belongs to. */\n\tprojectId: string;\n\t/** Neon branch id (`br-…`). */\n\tid: string;\n\t/** Branch name. */\n\tname: string;\n\t/** `true` when **this** operation created the branch (vs selecting an existing one). */\n\tcreated: boolean;\n\t/** Whether Neon marks the branch as the project default. */\n\tisDefault: boolean;\n\t/** Whether Neon marks the branch protected. */\n\tisProtected: boolean;\n\t/** Parent branch id, when known. */\n\tparentId?: string;\n\t/** Branch expiration timestamp, when set. */\n\texpiresAt?: string;\n}\n\n/**\n * A resolved branch's env vars, namespaced like `@neon/env`'s `NeonEnv<C>` — but **not**\n * generic over the policy. `@neon/config` cannot import the real, policy-exact `NeonEnv<C>`\n * (it lives in a package that itself depends on `@neon/config`, and importing it back would\n * be a dependency cycle), so every namespace here is optional regardless of what the policy\n * declares, rather than conditionally present/absent. `postgres` is the only field every\n * resolved branch actually has, so it stays the one non-optional namespace.\n */\nexport interface HookEnv {\n\tpostgres: {\n\t\tdatabaseUrl: string;\n\t\tdatabaseUrlUnpooled: string;\n\t};\n\tbranch?: { name: string };\n\tauth?: { baseUrl: string; jwksUrl: string };\n\tdataApi?: { url: string };\n\tstorage?: {\n\t\taccessKeyId: string;\n\t\tsecretAccessKey: string;\n\t\tendpoint: string;\n\t\tregion: string;\n\t};\n\taiGateway?: { apiKey: string; baseUrl: string };\n\tfunctions?: Record<string, { baseUrl: string }>;\n}\n\n/** Context passed to `hooks.checkout.before` (runs before the branch name is resolved). */\nexport interface CheckoutBeforeContext {\n\tevent: CheckoutEvent;\n\tgit: GitContext;\n}\n\n/**\n * Return value of a `hooks.checkout.before` **function** hook. Return `{ name }` to rewrite\n * the branch that will be checked out / created; return nothing to keep the resolved name.\n * Throw to abort the checkout. (Shell-command `before` hooks cannot rewrite the name — only\n * abort via a non-zero exit — since they have no return channel.)\n */\nexport interface CheckoutBeforeResult {\n\t/** Overrides the Neon branch name to check out / create. */\n\tname?: string;\n}\n\n/**\n * Context passed to `hooks.checkout.after` (branch resolved + env pulled). `env` is\n * {@link HookEnv} — every namespace optional; see that type for why it can't be the exact,\n * policy-typed `NeonEnv<C>`.\n */\nexport interface CheckoutAfterContext {\n\tbranch: HookBranch;\n\tenv: HookEnv;\n\tgit: GitContext;\n\tevent: CheckoutEvent;\n}\n\n/**\n * Context passed to `hooks.create.before` (runs before a new branch is created). Fires only\n * for a genuine creation — never for `checkout` selecting an existing branch. Unlike\n * `checkout.before`, this cannot rename the branch: by the time a `create` is reached, the\n * name is already resolved (rename via `checkout.before` if you need that).\n */\nexport interface CreateBeforeContext {\n\t/** Name of the branch about to be created. */\n\tbranchName: string;\n\tgit: GitContext;\n\t/** The event that triggered the enclosing `checkout` — `create` never runs standalone. */\n\tevent: CheckoutEvent;\n}\n\n/** Context passed to `hooks.create.after` (branch created, policy applied, env pulled). `branch.created` is always `true` here. */\nexport interface CreateAfterContext {\n\tbranch: HookBranch;\n\tenv: HookEnv;\n\tgit: GitContext;\n\tevent: CheckoutEvent;\n}\n\n/** Context passed to `hooks.deploy.before` (branch resolved, policy not yet applied). */\nexport interface DeployBeforeContext {\n\tbranch: HookBranch;\n\tgit: GitContext;\n\tevent: DeployEvent;\n}\n\n/** Context passed to `hooks.deploy.after` (policy applied, env pulled). */\nexport interface DeployAfterContext {\n\tbranch: HookBranch;\n\tenv: HookEnv;\n\t/** What the apply changed. */\n\tresult: PushResult;\n\tgit: GitContext;\n\tevent: DeployEvent;\n}\n\n/**\n * A shell-command hook: a single command string, or a list of commands run sequentially\n * (each must exit 0 or the operation aborts). Commands run **non-interactively** (stdin is\n * not a TTY and `CI=1` is set) so an accidental interactive command fails fast instead of\n * hanging. Resolved Neon env vars are injected into the command's environment.\n */\nexport type ShellHook = string | string[];\n\n/**\n * A lifecycle hook: either a (possibly async) function receiving a typed `Ctx`, or a\n * {@link ShellHook}. `before` hooks may influence/abort (functions can return `Result`,\n * any hook can throw to abort); `after` hooks observe (their return value is ignored).\n */\nexport type Hook<Ctx, Result = void> =\n\t| ((ctx: Ctx) => Result | Promise<Result>)\n\t| ShellHook;\n\n/** Hooks for the `checkout` command (`neon checkout`). */\nexport interface CheckoutHooks {\n\t/** Runs before the branch is resolved; may rewrite the name (function form) or abort. */\n\t// biome-ignore lint/suspicious/noConfusingVoidType: a `before` hook may return an override or nothing — `void` (not `undefined`) is what lets a no-op `() => {}` validation hook type-check.\n\tbefore?: Hook<CheckoutBeforeContext, CheckoutBeforeResult | void>;\n\t/** Runs after checkout + env pull. Use `branch.created` to distinguish new vs existing. */\n\tafter?: Hook<CheckoutAfterContext>;\n}\n\n/**\n * Hooks for branch **creation**. Fires only when `checkout` (or another consumer of the\n * runtime's create operation) actually creates a new branch — not when `checkout` selects\n * an existing one. Distinct from `checkout`, which brackets the whole `checkout` command\n * regardless of whether it created or selected a branch: use `create` when you specifically\n * care about the creation moment.\n */\nexport interface CreateHooks {\n\t/** Runs before the branch is created; throw/non-zero exit to abort. */\n\tbefore?: Hook<CreateBeforeContext, void>;\n\t/** Runs after the branch is created and the policy applied. */\n\tafter?: Hook<CreateAfterContext>;\n}\n\n/** Hooks for the `deploy` command (`neon deploy` / `config apply`). */\nexport interface DeployHooks {\n\t/** Runs before the policy is applied; throw/non-zero exit to abort. */\n\tbefore?: Hook<DeployBeforeContext, void>;\n\t/** Runs after a successful apply + env pull. */\n\tafter?: Hook<DeployAfterContext>;\n}\n\n/**\n * Imperative lifecycle hooks, keyed by the phase they bracket. Each phase exposes a\n * `before` (influence/abort) and `after` (observe) hook. Hooks never run during `plan` /\n * `status` / `inspect`.\n *\n * `env` in every `after` hook is the fixed {@link HookEnv}, not a policy-exact type — see\n * that type's doc comment for why.\n */\nexport interface Hooks {\n\tcheckout?: CheckoutHooks;\n\tcreate?: CreateHooks;\n\tdeploy?: DeployHooks;\n}\n\n/**\n * A function with all deploy defaults applied. `resolveConfig` fills in `runtime` so\n * downstream diff/apply never has to re-derive it.\n */\nexport interface ResolvedFunctionConfig {\n\tslug: string;\n\tname: string;\n\tsource: string;\n\tenv: Record<string, string>;\n\t/**\n\t * Packages the bundler leaves unresolved, normalized from\n\t * {@link FunctionDef.externalPackages} with `includeFiles` defaulted.\n\t *\n\t * Absent rather than empty when undeclared, so a policy that never mentions it takes the\n\t * pre-existing bundling path and produces the archive it always did.\n\t */\n\texternalPackages?: ResolvedExternalPackage[];\n\truntime: FunctionRuntime;\n\tbundler: FunctionBundlerInput;\n\t/**\n\t * Local-development settings, passed through untouched from {@link FunctionDef.dev}\n\t * (no defaults applied). Only consumed by `neon dev`; deploy ignores it.\n\t */\n\tdev?: FunctionDevConfig;\n\t/**\n\t * Normalized hostnames this function should own on the branch. Absent when this\n\t * branch has no list to apply. Empty when tuning replaced the list with `[]`.\n\t */\n\tcustomDomains?: string[];\n}\n\nexport type ResolvedFunctionTrigger =\n\t| ResolvedFunctionScheduleTrigger\n\t| ResolvedFunctionStorageObjectCreatedTrigger;\n\nexport interface ResolvedFunctionScheduleTrigger {\n\ttype: \"schedule\";\n\tname: string;\n\tfunctionSlug: string;\n\tcron: string;\n\tfunctionPath: string;\n\tenabled: boolean;\n}\n\nexport interface ResolvedFunctionStorageObjectCreatedTrigger {\n\ttype: \"storage_object_created\";\n\tname: string;\n\tfunctionSlug: string;\n\tbucketName: string;\n\tprefix?: string;\n\tfunctionPath: string;\n\tenabled: boolean;\n}\n\n/** A bucket with its access level defaulted to `private`. */\nexport interface ResolvedBucketConfig {\n\tname: string;\n\taccess: BucketAccessLevel;\n}\n\n/**\n * Normalized {@link PreviewInput}. Only present on {@link ResolvedBranchConfig} when the\n * policy returned a `preview` block. `aiGatewayEnabled` follows the same\n * \"present-and-not-`false`\" semantics as `authEnabled` / `dataApiEnabled`.\n */\nexport interface ResolvedPreviewConfig {\n\tfunctions: ResolvedFunctionConfig[];\n\tbuckets: ResolvedBucketConfig[];\n\taiGatewayEnabled: boolean;\n}\n\n/**\n * Normalized Data API integration. Present on {@link ResolvedBranchConfig} only when the\n * policy enables `dataApi`. `authProvider` always resolves (defaults to `\"neon\"`); the\n * external-IdP wiring is present only for `\"external\"`; `settings` carries the camelCase\n * runtime settings (reconciled as an update when they drift).\n */\nexport interface ResolvedDataApiConfig {\n\tauthProvider: DataApiAuthProvider;\n\tjwksUrl?: string;\n\tproviderName?: string;\n\tjwtAudience?: string;\n\tsettings?: DataApiSettings;\n}\n\nexport interface ResolvedBranchConfig {\n\tparent?: string;\n\tttlSeconds?: number;\n\tprotected?: boolean;\n\tpostgres?: PostgresConfig;\n\t/** Optional for compatibility with hand-built configs. */\n\trealtimePolicy?: \"omitted\" | \"enabled\" | \"disabled\";\n\t/** Realtime options to apply when {@link realtimePolicy} is `\"enabled\"`. */\n\trealtime?: RealtimeConfig;\n\tauthEnabled: boolean;\n\tdataApiEnabled: boolean;\n\t/** Optional for compatibility with hand-built configs. */\n\tdataApiPolicy?: \"omitted\" | \"enabled\" | \"disabled\";\n\t/**\n\t * Resolved Data API integration. Present iff {@link dataApiEnabled} is `true`. Carries the\n\t * create-time auth wiring and the updatable {@link DataApiSettings}.\n\t */\n\tdataApi?: ResolvedDataApiConfig;\n\tpreview?: ResolvedPreviewConfig;\n\t/**\n\t * Resolved triggers from {@link Config.triggers}. Absent when none are declared\n\t * (hand-built configs may omit it).\n\t */\n\ttriggers?: ResolvedFunctionTrigger[];\n}\n\n/**\n * One concrete change `pushConfig` made (or, in dry-run, would make) on the remote.\n */\nexport interface AppliedChange {\n\t/**\n\t * `service` covers branch-scoped integrations driven by the branch policy (e.g.\n\t * Neon Auth, Data API).\n\t */\n\tkind: \"branch\" | \"service\";\n\taction: \"create\" | \"update\" | \"delete\" | \"noop\";\n\tidentifier: string;\n\tdetails?: Record<string, unknown>;\n}\n\n/**\n * A diff entry that conflicts with the desired config. `pushConfig` throws\n * {@link PushConflictError} on the first call when conflicts exist; pass\n * `updateExisting: true` to apply mutable drift (settings, `protected`, TTL, project\n * rename). Immutable fields (region, Postgres major version) are always conflicts —\n * recreate the project to change them.\n */\nexport interface ConflictReport {\n\tkind: \"branch\";\n\tidentifier: string;\n\tfield: string;\n\tcurrent: unknown;\n\tdesired: unknown;\n\treason: string;\n}\n\n/**\n * Result of a `pushConfig` invocation.\n */\nexport interface PushResult {\n\tprojectId: string;\n\torgId?: string;\n\tbranchId: string;\n\tbranchName: string;\n\t/**\n\t * `true` when `pushConfig` was called with `{ dryRun: true }`. `applied` then records\n\t * what **would** be applied on a real push; no API mutations were performed.\n\t */\n\tdryRun: boolean;\n\tapplied: AppliedChange[];\n\tconflicts: ConflictReport[];\n\t/**\n\t * Declared custom domains for this branch after the push (or what apply would\n\t * leave in place). `cnameTarget` is omitted when the domain is not registered yet\n\t * (dry-run of a new registration). An empty string means the region has no\n\t * custom-domains front door.\n\t */\n\tcustomDomains?: Array<{\n\t\tdomain: string;\n\t\tslug: string;\n\t\tcnameTarget?: string;\n\t}>;\n\t/**\n\t * Advisory findings from the push — a function that bundles a native dependency it never\n\t * declared, or a staged package whose version could not be pinned.\n\t *\n\t * Returned rather than logged, because a library has no business choosing an output\n\t * channel, and returned rather than left to an opt-in callback, because these are the\n\t * only warning that a deployed function will fail at invoke and an unregistered callback\n\t * is easy to never notice. Empty when there is nothing to report.\n\t *\n\t * Only populated by the built-in bundler: a caller that injects its own `bundleFunction`\n\t * owns its own reporting.\n\t */\n\twarnings: string[];\n}\n"],"mappings":";;;;;;AAKA,MAAa,gBAAgB;CAC5B;CAAM;CAAK;CAAG;CAAG;CAAG;CAAG;CAAG;CAAG;CAAG;CAAG;CAAG;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CACtE;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;AACrE;;;;;;;;;;;;;AA2NA,MAAa,0BAA0B,CAAC,QAAQ,UAAU"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@neondatabase/config",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.10.1",
|
|
4
4
|
"description": "Config-as-Code for Neon. Define a `neon.ts` policy and inspect/diff/deploy it against the Neon API as plain TypeScript functions.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"neon",
|
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
"dependencies": {
|
|
52
52
|
"jiti": "^2.7.0",
|
|
53
53
|
"zod": "^4.5.4",
|
|
54
|
-
"@neon/sdk": "7.
|
|
54
|
+
"@neon/sdk": "7.8.0"
|
|
55
55
|
},
|
|
56
56
|
"engines": {
|
|
57
57
|
"node": ">=20.19.0"
|