@neon/config 0.9.1 → 0.9.3

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 CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Config-as-Code for the Neon Platform. A repo-local `neon.ts` exports a TypeScript policy function describing a branch's desired state. This package exposes **functions** to inspect, diff, and deploy that policy against the Neon API.
4
4
 
5
- > No CLI commands ship here, and the package is **filesystem- and env-agnostic**: it never reads `.neon` files or `NEON_*` environment variables. You pass `projectId` and the target branch explicitly (resolve them in your CLI, e.g. neonctl). This package is functions only.
5
+ > No CLI commands ship here, and the package is **filesystem- and env-agnostic**: it never reads `.neon` files or `NEON_*` environment variables. You pass `projectId` and the target branch explicitly (resolve them in your CLI, e.g. neon). This package is functions only.
6
6
 
7
7
  ## Install
8
8
 
@@ -1 +1 @@
1
- {"version":3,"file":"define-config.d.ts","names":[],"sources":["../../src/lib/define-config.ts"],"mappings":";;;;;;AAwBoB;;;KAYf,mBAA+B,CAAA,OAAA,CAAA,GAAA,cAAA,CAAe,OAAf,CAAA,SAAA,IAAA,GAAA,CAChC,OADgC,CAAA,SAAA,CAAA;cAChC,EAAA,UAAA;AAAO,CAAA,CAAA,GAAA,KAAA,GAAA,IAAA,GAAA,KAAA;AAiBX;AAqBA;;;;;;;;;AAKI,KA1BQ,oBAAA,GA0BR,+QAAA;;AAAsB;AAAC;;;;;;;;AAwBkB;AAoC7C;;;;;AAWQ,KA5EI,YA4EJ,CAAA,IAAA,EAAA,OAAA,CAAA,GA3EP,mBA2EO,CA3Ea,OA2Eb,CAAA,SAAA,IAAA,GA1EJ,cA0EI,CA1EW,IA0EX,CAAA,SAAA,IAAA,GAzEH,OAyEG,GAzEO,YAyEP,GAxEH,oBAwEG,GAvEJ,OAuEI,GAvEM,YAuEN;;;;;;;;;;;;;;;AAUE;AA4BV;;;KAzFK,mBA2FI,CAAA,OAAA,CAAA,GAAA,CA3F4B,OA2F5B,SAAA;WACN,EAAA,KAAA,EAAA;AAAoB,CAAA,GAAA;EAgKP,SAAA,EAAA,iBA3PiB,IAAI;gBAEnC;;;4BAC8B,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAoCpB,gCACI,kEACG,4DACA;SAQf,OAAO;YAIJ,aAAa,MAAM;YAInB,UAAU,eAAe,oBAAoB;WAC9C,eAAe;IACrB,OAAO,MAAM,SAAS;;;;;;;;iBA4BV,aAAA,SACP,gBACA,eACN;;;;;;iBAgKa,eAAA"}
1
+ {"version":3,"file":"define-config.d.ts","names":[],"sources":["../../src/lib/define-config.ts"],"mappings":";;;;;;AAwBoB;;;KAYf,mBACJ,CAAA,OAAA,CAAA,GAAA,cAAA,CAAe,OAAf,CAAA,SAAA,IAAA,GAAA,CACI,OADJ,CAAA,SAAA,CAAA;cACI,EAAA,UAAA;AAAO,CAAA,CAAA,GAAA,KAAA,GAAA,IAAA,GAAA,KAAA;AAiBZ;AAqBA;;;;;;;;;AAKI,KA1BQ,oBAAA,GA0BR,+QAAA;;AAAsB;AAAC;;;;;;;;AAwBkB;AAoC7C;;;;;AAWQ,KA5EI,YA4EJ,CAAA,IAAA,EAAA,OAAA,CAAA,GA3EP,mBA2EO,CA3Ea,OA2Eb,CAAA,SAAA,IAAA,GA1EJ,cA0EI,CA1EW,IA0EX,CAAA,SAAA,IAAA,GAzEH,OAyEG,GAzEO,YAyEP,GAxEH,oBAwEG,GAvEJ,OAuEI,GAvEM,YAuEN;;;;;;;;;;;;;;;AAUE;AA4BV;;;KAzFK,mBA2FI,CAAA,OAAA,CAAA,GAAA,CA3F4B,OA2F5B,SAAA;WACN,EAAA,KAAA,EAAA;AAAoB,CAAA,GAAA;EAgKP,SAAA,EAAA,iBA3PiB,IAAI;gBAEnC;;;4BAC8B,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAoCpB,gCACI,kEACG,4DACA;SAQf,OAAO;YAIJ,aAAa,MAAM;YAInB,UAAU,eAAe,oBAAoB;WAC9C,eAAe;IACrB,OAAO,MAAM,SAAS;;;;;;;;iBA4BV,aAAA,SACP,gBACA,eACN;;;;;;iBAgKa,eAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"define-config.js","names":[],"sources":["../../src/lib/define-config.ts"],"sourcesContent":["import { parseBranchTtl } from \"./duration.js\";\nimport { ConfigValidationError } from \"./errors.js\";\nimport {\n\tbranchTuningSchema,\n\tconfigInputSchema,\n\tformatZodIssues,\n} from \"./schema.js\";\nimport type {\n\tBranchTarget,\n\tBranchTuning,\n\tBranchTuningFn,\n\tBucketDef,\n\tConfig,\n\tDataApiInput,\n\tDataApiSettings,\n\tFunctionDef,\n\tFunctionTuning,\n\tPreviewInput,\n\tResolvedBranchConfig,\n\tResolvedDataApiConfig,\n\tResolvedFunctionConfig,\n\tResolvedPreviewConfig,\n\tServiceEnabled,\n\tServiceToggleInput,\n} from \"./types.js\";\n\n/** Default deploy parameters applied to functions that omit them in `neon.ts`. */\nconst DEFAULT_FUNCTION_RUNTIME = \"nodejs24\" as const;\n\nconst REGION_PREFIX = /^(aws|azure|gcp)-/;\n\n/**\n * Whether a `dataApi` toggle is **enabled and verified by Neon Auth** at the type level: it is\n * on (see {@link ServiceEnabled}) and not the explicit `authProvider: \"external\"` variant\n * (so the default / `\"neon\"` provider). This is the case that requires top-level Neon Auth.\n */\ntype DataApiUsesNeonAuth<DataApi> = ServiceEnabled<DataApi> extends true\n\t? [DataApi] extends [{ authProvider: \"external\" }]\n\t\t? false\n\t\t: true\n\t: false;\n\n/**\n * Human-readable hint surfaced as the **expected type** of `dataApi` when a Neon-Auth Data\n * API is declared without Neon Auth enabled (see {@link DataApiField}). TypeScript prints the\n * offending value against this string literal — `Type 'true' is not assignable to type\n * '…requires `auth: true`…'` — which points straight at the fix, instead of the opaque\n * `Type 'true' is not assignable to type 'never'` an intersection guard produces.\n *\n * It documents **both** fixes: enabling Neon Auth (`auth: true`), and running the Data API\n * *without* Neon Auth by verifying a third-party IdP (`authProvider: 'external'` + `jwksUrl`).\n */\n// Exported (type-only) for the type tests in `define-config.test-d.ts`; intentionally not\n// re-exported from `v1.ts` / `index.ts`, so it stays an internal implementation detail.\nexport type NeonAuthRequiredHint =\n\t\"`dataApi` with Neon Auth (the default `authProvider: 'neon'`) requires Neon Auth, so add `auth: true`. To enable the Data API WITHOUT Neon Auth, verify a third-party IdP instead: `dataApi: { authProvider: 'external', jwksUrl: 'https://your-idp/.well-known/jwks.json' }`\";\n\n/**\n * Static cross-field guard for {@link defineConfig}, expressed as the **type of the `dataApi`\n * field** rather than an intersected requirement on `auth`.\n *\n * - A Neon-Auth Data API (`authProvider: \"neon\"`, the default) with top-level `auth` enabled,\n * or any external Data API: the field keeps its normal `DataApi & DataApiInput` type (the\n * `& DataApiInput` preserves member autocomplete; the `const DataApi` still types the\n * returned {@link Config}).\n * - A Neon-Auth Data API **without** `auth` enabled: the field's expected type collapses to\n * the {@link NeonAuthRequiredHint} message, so the author sees the rule (and the two fixes)\n * right on the `dataApi` value.\n *\n * The runtime `superRefine` in {@link configInputSchema} enforces the same invariant for\n * non-typed (plain-JS) callers, so the behavior is identical — only the type-level message\n * changes.\n */\n// Exported (type-only) for the type tests in `define-config.test-d.ts`; intentionally not\n// re-exported from `v1.ts` / `index.ts`, so it stays an internal implementation detail.\nexport type DataApiField<Auth, DataApi> =\n\tDataApiUsesNeonAuth<DataApi> extends true\n\t\t? ServiceEnabled<Auth> extends true\n\t\t\t? DataApi & DataApiInput\n\t\t\t: NeonAuthRequiredHint\n\t\t: DataApi & DataApiInput;\n\n/**\n * Autocomplete bridge for the nested `preview.functions` / `preview.buckets` slug objects.\n *\n * {@link PreviewInput} types those records with a string index signature\n * (`Record<string, FunctionDef>` / `Record<string, BucketDef>`). When `defineConfig` infers\n * `const Preview`, every authored slug becomes a **named** property on the inferred literal\n * (e.g. `{ hello: { name; source } }`), and a named property **shadows** the index signature\n * when the editor computes the contextual type of that slug's value — so the rest of\n * {@link FunctionDef} / {@link BucketDef} (`env`, `dev`, `access`, …) never surfaces as\n * completions inside `hello: { … }` / `uploads: { … }`.\n *\n * Re-declaring each inferred slug's value as `FunctionDef` / `BucketDef` (a *named* member, via\n * a mapped type over the already-inferred keys) puts those members back onto the contextual\n * type without going through an index signature, which restores autocomplete. Intersected with\n * `Preview & PreviewInput` it neither widens what is accepted (the values were already\n * `FunctionDef` / `BucketDef`) nor perturbs the inferred `const Preview` — so slug inference for\n * `BranchTuningFn<Preview>` and the returned {@link Config} is unchanged.\n */\ntype PreviewAutocomplete<Preview> = (Preview extends { functions: infer F }\n\t? { functions: { [Slug in keyof F]: FunctionDef } }\n\t: unknown) &\n\t(Preview extends { buckets: infer B }\n\t\t? { buckets: { [Name in keyof B]: BucketDef } }\n\t\t: unknown);\n\n/**\n * Validate and freeze a Neon Platform branch policy.\n *\n * Used at the top of `neon.ts`:\n * ```ts\n * import { defineConfig } from \"@neon/config/v1\";\n *\n * export default defineConfig({\n * auth: true,\n * preview: {\n * functions: {\n * hello: { name: \"Hello\", source: \"./functions/hello.ts\", dev: { port: 8787 } },\n * },\n * },\n * branch: (branch) => ({ protected: branch.name === \"main\" }),\n * });\n * ```\n *\n * The policy is split into a **static** existential set (top-level `auth` / `dataApi`\n * toggles and the beta `preview` block) and a **dynamic** per-branch `branch` closure. The\n * static half determines which secrets exist — so `NeonEnv<typeof config>` and `parseEnv`\n * are exact — while the closure can only *tune* a branch (lifecycle, compute, per-function\n * deploy settings), never change what exists.\n *\n * The `branch` callback receives a read-only {@link BranchTarget} descriptor of the branch\n * being decided for (not a live handle); switch on its facts (`branch.name`,\n * `branch.isDefault`, `branch.exists`, …) and **return** the desired tuning. It runs in two\n * modes: against an existing branch (fields populated from Neon) and during pre-create\n * evaluation (`exists: false`, `id` undefined).\n *\n * Pure: no I/O, no side effects. The static parts are validated here; the closure's output\n * is validated every time it is evaluated so errors point at the concrete branch target.\n */\nexport function defineConfig<\n\tconst Auth extends ServiceToggleInput | undefined = undefined,\n\tconst DataApi extends DataApiInput | undefined = undefined,\n\tconst Preview extends PreviewInput | undefined = undefined,\n>(input: {\n\t// Each field is intersected with its concrete interface (not just typed as the bare\n\t// generic). The generic alone — e.g. `preview?: Preview` — gives editors no members to\n\t// complete against in the object-literal position (they see `{} | undefined`), so you\n\t// lose hints for `aiGateway` / `functions` / `buckets`. `& PreviewInput` restores the\n\t// full shape for autocomplete while still inferring the `const` literal that types the\n\t// `branch` closure's slugs (BranchTuningFn<Preview>) and the returned Config.\n\tauth?: Auth & ServiceToggleInput;\n\t// The `dataApi` field carries the Neon-Auth cross-field guard at the type level (see\n\t// `DataApiField`): a Neon-Auth Data API without `auth` enabled surfaces a readable hint\n\t// as the field's expected type instead of collapsing the value to `never`.\n\tdataApi?: DataApiField<Auth, DataApi>;\n\t// `& PreviewInput` restores top-level member hints (aiGateway/functions/buckets);\n\t// `& PreviewAutocomplete<Preview>` restores hints *inside* each function/bucket slug\n\t// object (see `PreviewAutocomplete`), which the bare index signature otherwise hides.\n\tpreview?: Preview & PreviewInput & PreviewAutocomplete<Preview>;\n\tbranch?: BranchTuningFn<Preview>;\n}): Config<Auth, DataApi, Preview> {\n\tif (typeof input === \"function\") {\n\t\tthrow new ConfigValidationError([\n\t\t\t\"defineConfig now expects an object, not a function: `export default defineConfig({ auth: true, preview: { … }, branch: (branch) => ({ … }) })`.\",\n\t\t\t\"The static services/preview set moved to the top level; per-branch logic moved into the `branch` closure.\",\n\t\t]);\n\t}\n\tif (input === null || typeof input !== \"object\") {\n\t\tthrow new ConfigValidationError([\n\t\t\t\"defineConfig expects a configuration object: `export default defineConfig({ … })`.\",\n\t\t]);\n\t}\n\n\tconst parsed = configInputSchema.safeParse(input);\n\tif (!parsed.success) {\n\t\tthrow new ConfigValidationError(formatZodIssues(parsed.error));\n\t}\n\n\treturn Object.freeze({ ...input }) as Config<Auth, DataApi, Preview>;\n}\n\n/**\n * Evaluate a branch policy for a specific branch target and return a normalized config.\n *\n * Merges the static existential set (services + preview functions/buckets) with the\n * per-branch tuning returned by the `branch` closure into the same {@link\n * ResolvedBranchConfig} the rest of the runtime (diff / push / fetchEnv) consumes.\n */\nexport function resolveConfig(\n\tconfig: Config,\n\tbranch: BranchTarget,\n): ResolvedBranchConfig {\n\tconst tuning = evaluateBranchTuning(config.branch, branch);\n\n\tconst resolved: ResolvedBranchConfig = {\n\t\tauthEnabled: isServiceEnabled(config.auth),\n\t\tdataApiEnabled: isDataApiEnabled(config.dataApi),\n\t};\n\tconst dataApi = resolveDataApi(config.dataApi);\n\tif (dataApi) resolved.dataApi = dataApi;\n\tif (tuning.parent !== undefined) resolved.parent = tuning.parent;\n\tif (tuning.ttl !== undefined) {\n\t\t// `branchTuningSchema` already validated `ttl` with the same `parseBranchTtl`, so\n\t\t// this only converts the validated value to seconds — it cannot fail here.\n\t\tconst parsedTtl = parseBranchTtl(tuning.ttl);\n\t\tif (!(\"error\" in parsedTtl)) resolved.ttlSeconds = parsedTtl.seconds;\n\t}\n\tif (tuning.protected !== undefined) resolved.protected = tuning.protected;\n\tif (tuning.postgres?.computeSettings) {\n\t\tresolved.postgres = {\n\t\t\tcomputeSettings: { ...tuning.postgres.computeSettings },\n\t\t};\n\t}\n\n\tconst preview = resolvePreviewConfig(config.preview, tuning);\n\tif (preview) resolved.preview = preview;\n\n\treturn resolved;\n}\n\n/**\n * Run the `branch` closure (when present) for the target and validate its output. The\n * closure is optional — a fully static policy resolves with empty tuning.\n */\nfunction evaluateBranchTuning(\n\tbranchFn: BranchTuningFn | undefined,\n\ttarget: BranchTarget,\n): BranchTuning {\n\tif (!branchFn) return {};\n\tlet raw: unknown;\n\ttry {\n\t\traw = branchFn(Object.freeze({ ...target }));\n\t} catch (cause) {\n\t\tthrow new ConfigValidationError([\n\t\t\t`Branch policy threw while evaluating branch \"${target.name}\".`,\n\t\t\t(cause as Error)?.message ?? String(cause),\n\t\t]);\n\t}\n\tconst parsed = branchTuningSchema.safeParse(raw ?? {});\n\tif (!parsed.success) {\n\t\tthrow new ConfigValidationError(formatZodIssues(parsed.error));\n\t}\n\treturn parsed.data as BranchTuning;\n}\n\nfunction isServiceEnabled(toggle: ServiceToggleInput | undefined): boolean {\n\tif (toggle === undefined) return false;\n\tif (typeof toggle === \"boolean\") return toggle;\n\treturn toggle.enabled !== false;\n}\n\n/** Whether a {@link DataApiInput} is enabled (present object/`true` unless `enabled: false`). */\nfunction isDataApiEnabled(input: DataApiInput | undefined): boolean {\n\tif (input === undefined) return false;\n\tif (typeof input === \"boolean\") return input;\n\treturn input.enabled !== false;\n}\n\n/**\n * Normalize a {@link DataApiInput} into a {@link ResolvedDataApiConfig}, or `undefined` when\n * the Data API is not enabled. `authProvider` defaults to `\"neon\"`; the external-IdP wiring\n * is carried through only for the `\"external\"` provider; `settings` is copied with its\n * `undefined` entries dropped so diffing only considers fields the policy actually set.\n */\nfunction resolveDataApi(\n\tinput: DataApiInput | undefined,\n): ResolvedDataApiConfig | undefined {\n\tif (!isDataApiEnabled(input)) return undefined;\n\tif (typeof input !== \"object\") {\n\t\t// Bare `true`: enabled with Neon Auth and all-default settings.\n\t\treturn { authProvider: \"neon\" };\n\t}\n\tconst authProvider = input.authProvider ?? \"neon\";\n\tconst resolved: ResolvedDataApiConfig = { authProvider };\n\tif (authProvider === \"external\") {\n\t\tif (input.jwksUrl !== undefined) resolved.jwksUrl = input.jwksUrl;\n\t\tif (input.providerName !== undefined)\n\t\t\tresolved.providerName = input.providerName;\n\t\tif (input.jwtAudience !== undefined)\n\t\t\tresolved.jwtAudience = input.jwtAudience;\n\t}\n\tconst settings = normalizeDataApiSettings(input.settings);\n\tif (settings) resolved.settings = settings;\n\treturn resolved;\n}\n\n/** Copy a {@link DataApiSettings}, dropping `undefined` entries; `undefined` when empty. */\nfunction normalizeDataApiSettings(\n\tsettings: DataApiSettings | undefined,\n): DataApiSettings | undefined {\n\tif (!settings) return undefined;\n\tconst out: DataApiSettings = {};\n\tfor (const [key, value] of Object.entries(settings)) {\n\t\tif (value !== undefined) {\n\t\t\t(out as Record<string, unknown>)[key] = value;\n\t\t}\n\t}\n\treturn Object.keys(out).length > 0 ? out : undefined;\n}\n\n/**\n * Normalize the static {@link PreviewInput} (merged with per-branch function tuning) into a\n * {@link ResolvedPreviewConfig}. Returns `undefined` when the policy declares no `preview`\n * block so the field can be omitted entirely. Function slugs / bucket names come from the\n * record keys.\n */\nfunction resolvePreviewConfig(\n\tpreview: PreviewInput | undefined,\n\ttuning: BranchTuning,\n): ResolvedPreviewConfig | undefined {\n\tif (!preview) return undefined;\n\tconst fnTuning = tuning.preview?.functions ?? {};\n\tconst functions: ResolvedFunctionConfig[] = Object.entries(\n\t\tpreview.functions ?? {},\n\t).map(([slug, def]) =>\n\t\tresolveFunctionConfig(slug, def, fnTuning[slug] ?? {}),\n\t);\n\tconst buckets = Object.entries(preview.buckets ?? {}).map(\n\t\t([name, def]) => ({\n\t\t\tname,\n\t\t\taccess: def.access ?? \"private\",\n\t\t}),\n\t);\n\treturn {\n\t\tfunctions,\n\t\tbuckets,\n\t\taiGatewayEnabled: isServiceEnabled(preview.aiGateway),\n\t};\n}\n\nfunction resolveFunctionConfig(\n\tslug: string,\n\tdef: FunctionDef,\n\ttuning: FunctionTuning,\n): ResolvedFunctionConfig {\n\treturn {\n\t\tslug,\n\t\tname: def.name,\n\t\tsource: def.source,\n\t\tenv: { ...(def.env ?? {}) },\n\t\truntime: tuning.runtime ?? DEFAULT_FUNCTION_RUNTIME,\n\t\t// Passed through untouched (no defaults); only `neon dev` reads it.\n\t\t...(def.dev ? { dev: def.dev } : {}),\n\t};\n}\n\n/**\n * Normalize a region identifier to Neon's `<cloud>-<region>` format. When the user writes\n * `us-east-1` we assume `aws-us-east-1`. Pure helper used by both the validator and the\n * NeonApi adapter.\n */\nexport function normalizeRegion(region: string): string {\n\tif (REGION_PREFIX.test(region)) return region;\n\treturn `aws-${region}`;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"define-config.js","names":[],"sources":["../../src/lib/define-config.ts"],"sourcesContent":["import { parseBranchTtl } from \"./duration.js\";\nimport { ConfigValidationError } from \"./errors.js\";\nimport {\n\tbranchTuningSchema,\n\tconfigInputSchema,\n\tformatZodIssues,\n} from \"./schema.js\";\nimport type {\n\tBranchTarget,\n\tBranchTuning,\n\tBranchTuningFn,\n\tBucketDef,\n\tConfig,\n\tDataApiInput,\n\tDataApiSettings,\n\tFunctionDef,\n\tFunctionTuning,\n\tPreviewInput,\n\tResolvedBranchConfig,\n\tResolvedDataApiConfig,\n\tResolvedFunctionConfig,\n\tResolvedPreviewConfig,\n\tServiceEnabled,\n\tServiceToggleInput,\n} from \"./types.js\";\n\n/** Default deploy parameters applied to functions that omit them in `neon.ts`. */\nconst DEFAULT_FUNCTION_RUNTIME = \"nodejs24\" as const;\n\nconst REGION_PREFIX = /^(aws|azure|gcp)-/;\n\n/**\n * Whether a `dataApi` toggle is **enabled and verified by Neon Auth** at the type level: it is\n * on (see {@link ServiceEnabled}) and not the explicit `authProvider: \"external\"` variant\n * (so the default / `\"neon\"` provider). This is the case that requires top-level Neon Auth.\n */\ntype DataApiUsesNeonAuth<DataApi> =\n\tServiceEnabled<DataApi> extends true\n\t\t? [DataApi] extends [{ authProvider: \"external\" }]\n\t\t\t? false\n\t\t\t: true\n\t\t: false;\n\n/**\n * Human-readable hint surfaced as the **expected type** of `dataApi` when a Neon-Auth Data\n * API is declared without Neon Auth enabled (see {@link DataApiField}). TypeScript prints the\n * offending value against this string literal — `Type 'true' is not assignable to type\n * '…requires `auth: true`…'` — which points straight at the fix, instead of the opaque\n * `Type 'true' is not assignable to type 'never'` an intersection guard produces.\n *\n * It documents **both** fixes: enabling Neon Auth (`auth: true`), and running the Data API\n * *without* Neon Auth by verifying a third-party IdP (`authProvider: 'external'` + `jwksUrl`).\n */\n// Exported (type-only) for the type tests in `define-config.test-d.ts`; intentionally not\n// re-exported from `v1.ts` / `index.ts`, so it stays an internal implementation detail.\nexport type NeonAuthRequiredHint =\n\t\"`dataApi` with Neon Auth (the default `authProvider: 'neon'`) requires Neon Auth, so add `auth: true`. To enable the Data API WITHOUT Neon Auth, verify a third-party IdP instead: `dataApi: { authProvider: 'external', jwksUrl: 'https://your-idp/.well-known/jwks.json' }`\";\n\n/**\n * Static cross-field guard for {@link defineConfig}, expressed as the **type of the `dataApi`\n * field** rather than an intersected requirement on `auth`.\n *\n * - A Neon-Auth Data API (`authProvider: \"neon\"`, the default) with top-level `auth` enabled,\n * or any external Data API: the field keeps its normal `DataApi & DataApiInput` type (the\n * `& DataApiInput` preserves member autocomplete; the `const DataApi` still types the\n * returned {@link Config}).\n * - A Neon-Auth Data API **without** `auth` enabled: the field's expected type collapses to\n * the {@link NeonAuthRequiredHint} message, so the author sees the rule (and the two fixes)\n * right on the `dataApi` value.\n *\n * The runtime `superRefine` in {@link configInputSchema} enforces the same invariant for\n * non-typed (plain-JS) callers, so the behavior is identical — only the type-level message\n * changes.\n */\n// Exported (type-only) for the type tests in `define-config.test-d.ts`; intentionally not\n// re-exported from `v1.ts` / `index.ts`, so it stays an internal implementation detail.\nexport type DataApiField<Auth, DataApi> =\n\tDataApiUsesNeonAuth<DataApi> extends true\n\t\t? ServiceEnabled<Auth> extends true\n\t\t\t? DataApi & DataApiInput\n\t\t\t: NeonAuthRequiredHint\n\t\t: DataApi & DataApiInput;\n\n/**\n * Autocomplete bridge for the nested `preview.functions` / `preview.buckets` slug objects.\n *\n * {@link PreviewInput} types those records with a string index signature\n * (`Record<string, FunctionDef>` / `Record<string, BucketDef>`). When `defineConfig` infers\n * `const Preview`, every authored slug becomes a **named** property on the inferred literal\n * (e.g. `{ hello: { name; source } }`), and a named property **shadows** the index signature\n * when the editor computes the contextual type of that slug's value — so the rest of\n * {@link FunctionDef} / {@link BucketDef} (`env`, `dev`, `access`, …) never surfaces as\n * completions inside `hello: { … }` / `uploads: { … }`.\n *\n * Re-declaring each inferred slug's value as `FunctionDef` / `BucketDef` (a *named* member, via\n * a mapped type over the already-inferred keys) puts those members back onto the contextual\n * type without going through an index signature, which restores autocomplete. Intersected with\n * `Preview & PreviewInput` it neither widens what is accepted (the values were already\n * `FunctionDef` / `BucketDef`) nor perturbs the inferred `const Preview` — so slug inference for\n * `BranchTuningFn<Preview>` and the returned {@link Config} is unchanged.\n */\ntype PreviewAutocomplete<Preview> = (Preview extends { functions: infer F }\n\t? { functions: { [Slug in keyof F]: FunctionDef } }\n\t: unknown) &\n\t(Preview extends { buckets: infer B }\n\t\t? { buckets: { [Name in keyof B]: BucketDef } }\n\t\t: unknown);\n\n/**\n * Validate and freeze a Neon Platform branch policy.\n *\n * Used at the top of `neon.ts`:\n * ```ts\n * import { defineConfig } from \"@neon/config/v1\";\n *\n * export default defineConfig({\n * auth: true,\n * preview: {\n * functions: {\n * hello: { name: \"Hello\", source: \"./functions/hello.ts\", dev: { port: 8787 } },\n * },\n * },\n * branch: (branch) => ({ protected: branch.name === \"main\" }),\n * });\n * ```\n *\n * The policy is split into a **static** existential set (top-level `auth` / `dataApi`\n * toggles and the beta `preview` block) and a **dynamic** per-branch `branch` closure. The\n * static half determines which secrets exist — so `NeonEnv<typeof config>` and `parseEnv`\n * are exact — while the closure can only *tune* a branch (lifecycle, compute, per-function\n * deploy settings), never change what exists.\n *\n * The `branch` callback receives a read-only {@link BranchTarget} descriptor of the branch\n * being decided for (not a live handle); switch on its facts (`branch.name`,\n * `branch.isDefault`, `branch.exists`, …) and **return** the desired tuning. It runs in two\n * modes: against an existing branch (fields populated from Neon) and during pre-create\n * evaluation (`exists: false`, `id` undefined).\n *\n * Pure: no I/O, no side effects. The static parts are validated here; the closure's output\n * is validated every time it is evaluated so errors point at the concrete branch target.\n */\nexport function defineConfig<\n\tconst Auth extends ServiceToggleInput | undefined = undefined,\n\tconst DataApi extends DataApiInput | undefined = undefined,\n\tconst Preview extends PreviewInput | undefined = undefined,\n>(input: {\n\t// Each field is intersected with its concrete interface (not just typed as the bare\n\t// generic). The generic alone — e.g. `preview?: Preview` — gives editors no members to\n\t// complete against in the object-literal position (they see `{} | undefined`), so you\n\t// lose hints for `aiGateway` / `functions` / `buckets`. `& PreviewInput` restores the\n\t// full shape for autocomplete while still inferring the `const` literal that types the\n\t// `branch` closure's slugs (BranchTuningFn<Preview>) and the returned Config.\n\tauth?: Auth & ServiceToggleInput;\n\t// The `dataApi` field carries the Neon-Auth cross-field guard at the type level (see\n\t// `DataApiField`): a Neon-Auth Data API without `auth` enabled surfaces a readable hint\n\t// as the field's expected type instead of collapsing the value to `never`.\n\tdataApi?: DataApiField<Auth, DataApi>;\n\t// `& PreviewInput` restores top-level member hints (aiGateway/functions/buckets);\n\t// `& PreviewAutocomplete<Preview>` restores hints *inside* each function/bucket slug\n\t// object (see `PreviewAutocomplete`), which the bare index signature otherwise hides.\n\tpreview?: Preview & PreviewInput & PreviewAutocomplete<Preview>;\n\tbranch?: BranchTuningFn<Preview>;\n}): Config<Auth, DataApi, Preview> {\n\tif (typeof input === \"function\") {\n\t\tthrow new ConfigValidationError([\n\t\t\t\"defineConfig now expects an object, not a function: `export default defineConfig({ auth: true, preview: { … }, branch: (branch) => ({ … }) })`.\",\n\t\t\t\"The static services/preview set moved to the top level; per-branch logic moved into the `branch` closure.\",\n\t\t]);\n\t}\n\tif (input === null || typeof input !== \"object\") {\n\t\tthrow new ConfigValidationError([\n\t\t\t\"defineConfig expects a configuration object: `export default defineConfig({ … })`.\",\n\t\t]);\n\t}\n\n\tconst parsed = configInputSchema.safeParse(input);\n\tif (!parsed.success) {\n\t\tthrow new ConfigValidationError(formatZodIssues(parsed.error));\n\t}\n\n\treturn Object.freeze({ ...input }) as Config<Auth, DataApi, Preview>;\n}\n\n/**\n * Evaluate a branch policy for a specific branch target and return a normalized config.\n *\n * Merges the static existential set (services + preview functions/buckets) with the\n * per-branch tuning returned by the `branch` closure into the same {@link\n * ResolvedBranchConfig} the rest of the runtime (diff / push / fetchEnv) consumes.\n */\nexport function resolveConfig(\n\tconfig: Config,\n\tbranch: BranchTarget,\n): ResolvedBranchConfig {\n\tconst tuning = evaluateBranchTuning(config.branch, branch);\n\n\tconst resolved: ResolvedBranchConfig = {\n\t\tauthEnabled: isServiceEnabled(config.auth),\n\t\tdataApiEnabled: isDataApiEnabled(config.dataApi),\n\t};\n\tconst dataApi = resolveDataApi(config.dataApi);\n\tif (dataApi) resolved.dataApi = dataApi;\n\tif (tuning.parent !== undefined) resolved.parent = tuning.parent;\n\tif (tuning.ttl !== undefined) {\n\t\t// `branchTuningSchema` already validated `ttl` with the same `parseBranchTtl`, so\n\t\t// this only converts the validated value to seconds — it cannot fail here.\n\t\tconst parsedTtl = parseBranchTtl(tuning.ttl);\n\t\tif (!(\"error\" in parsedTtl)) resolved.ttlSeconds = parsedTtl.seconds;\n\t}\n\tif (tuning.protected !== undefined) resolved.protected = tuning.protected;\n\tif (tuning.postgres?.computeSettings) {\n\t\tresolved.postgres = {\n\t\t\tcomputeSettings: { ...tuning.postgres.computeSettings },\n\t\t};\n\t}\n\n\tconst preview = resolvePreviewConfig(config.preview, tuning);\n\tif (preview) resolved.preview = preview;\n\n\treturn resolved;\n}\n\n/**\n * Run the `branch` closure (when present) for the target and validate its output. The\n * closure is optional — a fully static policy resolves with empty tuning.\n */\nfunction evaluateBranchTuning(\n\tbranchFn: BranchTuningFn | undefined,\n\ttarget: BranchTarget,\n): BranchTuning {\n\tif (!branchFn) return {};\n\tlet raw: unknown;\n\ttry {\n\t\traw = branchFn(Object.freeze({ ...target }));\n\t} catch (cause) {\n\t\tthrow new ConfigValidationError([\n\t\t\t`Branch policy threw while evaluating branch \"${target.name}\".`,\n\t\t\t(cause as Error)?.message ?? String(cause),\n\t\t]);\n\t}\n\tconst parsed = branchTuningSchema.safeParse(raw ?? {});\n\tif (!parsed.success) {\n\t\tthrow new ConfigValidationError(formatZodIssues(parsed.error));\n\t}\n\treturn parsed.data as BranchTuning;\n}\n\nfunction isServiceEnabled(toggle: ServiceToggleInput | undefined): boolean {\n\tif (toggle === undefined) return false;\n\tif (typeof toggle === \"boolean\") return toggle;\n\treturn toggle.enabled !== false;\n}\n\n/** Whether a {@link DataApiInput} is enabled (present object/`true` unless `enabled: false`). */\nfunction isDataApiEnabled(input: DataApiInput | undefined): boolean {\n\tif (input === undefined) return false;\n\tif (typeof input === \"boolean\") return input;\n\treturn input.enabled !== false;\n}\n\n/**\n * Normalize a {@link DataApiInput} into a {@link ResolvedDataApiConfig}, or `undefined` when\n * the Data API is not enabled. `authProvider` defaults to `\"neon\"`; the external-IdP wiring\n * is carried through only for the `\"external\"` provider; `settings` is copied with its\n * `undefined` entries dropped so diffing only considers fields the policy actually set.\n */\nfunction resolveDataApi(\n\tinput: DataApiInput | undefined,\n): ResolvedDataApiConfig | undefined {\n\tif (!isDataApiEnabled(input)) return undefined;\n\tif (typeof input !== \"object\") {\n\t\t// Bare `true`: enabled with Neon Auth and all-default settings.\n\t\treturn { authProvider: \"neon\" };\n\t}\n\tconst authProvider = input.authProvider ?? \"neon\";\n\tconst resolved: ResolvedDataApiConfig = { authProvider };\n\tif (authProvider === \"external\") {\n\t\tif (input.jwksUrl !== undefined) resolved.jwksUrl = input.jwksUrl;\n\t\tif (input.providerName !== undefined)\n\t\t\tresolved.providerName = input.providerName;\n\t\tif (input.jwtAudience !== undefined)\n\t\t\tresolved.jwtAudience = input.jwtAudience;\n\t}\n\tconst settings = normalizeDataApiSettings(input.settings);\n\tif (settings) resolved.settings = settings;\n\treturn resolved;\n}\n\n/** Copy a {@link DataApiSettings}, dropping `undefined` entries; `undefined` when empty. */\nfunction normalizeDataApiSettings(\n\tsettings: DataApiSettings | undefined,\n): DataApiSettings | undefined {\n\tif (!settings) return undefined;\n\tconst out: DataApiSettings = {};\n\tfor (const [key, value] of Object.entries(settings)) {\n\t\tif (value !== undefined) {\n\t\t\t(out as Record<string, unknown>)[key] = value;\n\t\t}\n\t}\n\treturn Object.keys(out).length > 0 ? out : undefined;\n}\n\n/**\n * Normalize the static {@link PreviewInput} (merged with per-branch function tuning) into a\n * {@link ResolvedPreviewConfig}. Returns `undefined` when the policy declares no `preview`\n * block so the field can be omitted entirely. Function slugs / bucket names come from the\n * record keys.\n */\nfunction resolvePreviewConfig(\n\tpreview: PreviewInput | undefined,\n\ttuning: BranchTuning,\n): ResolvedPreviewConfig | undefined {\n\tif (!preview) return undefined;\n\tconst fnTuning = tuning.preview?.functions ?? {};\n\tconst functions: ResolvedFunctionConfig[] = Object.entries(\n\t\tpreview.functions ?? {},\n\t).map(([slug, def]) =>\n\t\tresolveFunctionConfig(slug, def, fnTuning[slug] ?? {}),\n\t);\n\tconst buckets = Object.entries(preview.buckets ?? {}).map(\n\t\t([name, def]) => ({\n\t\t\tname,\n\t\t\taccess: def.access ?? \"private\",\n\t\t}),\n\t);\n\treturn {\n\t\tfunctions,\n\t\tbuckets,\n\t\taiGatewayEnabled: isServiceEnabled(preview.aiGateway),\n\t};\n}\n\nfunction resolveFunctionConfig(\n\tslug: string,\n\tdef: FunctionDef,\n\ttuning: FunctionTuning,\n): ResolvedFunctionConfig {\n\treturn {\n\t\tslug,\n\t\tname: def.name,\n\t\tsource: def.source,\n\t\tenv: { ...(def.env ?? {}) },\n\t\truntime: tuning.runtime ?? DEFAULT_FUNCTION_RUNTIME,\n\t\t// Passed through untouched (no defaults); only `neon dev` reads it.\n\t\t...(def.dev ? { dev: def.dev } : {}),\n\t};\n}\n\n/**\n * Normalize a region identifier to Neon's `<cloud>-<region>` format. When the user writes\n * `us-east-1` we assume `aws-us-east-1`. Pure helper used by both the validator and the\n * NeonApi adapter.\n */\nexport function normalizeRegion(region: string): string {\n\tif (REGION_PREFIX.test(region)) return region;\n\treturn `aws-${region}`;\n}\n"],"mappings":"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"}
@@ -14,7 +14,7 @@ const DEFAULT_NEON_API_BASE_URL = "https://console.neon.tech/api/v2";
14
14
  */
15
15
  function unwrap(result) {
16
16
  const response = result.response;
17
- if (!response || !response.ok) throw { response: {
17
+ if (!response?.ok) throw { response: {
18
18
  status: response?.status,
19
19
  data: result.error
20
20
  } };
@@ -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"],"sources":["../../src/lib/neon-api-real.ts"],"sourcesContent":["import type {\n\tDataApiSettings as ApiDataApiSettings,\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\tgetConnectionUri as rawGetConnectionUri,\n\tgetNeonAuth as rawGetNeonAuth,\n\tgetProject as rawGetProject,\n\tgetProjectBranchDataApi as rawGetProjectBranchDataApi,\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\tCreateBranchInput,\n\tCreateBucketInput,\n\tCreateCredentialInput,\n\tCreateProjectInput,\n\tDeployFunctionInput,\n\tEnableDataApiInput,\n\tGetConnectionUriInput,\n\tNeonApi,\n\tNeonAuthSnapshot,\n\tNeonBranchSnapshot,\n\tNeonBranchStorageSnapshot,\n\tNeonBucketSnapshot,\n\tNeonCredentialMeta,\n\tNeonCredentialSecret,\n\tNeonDataApiSnapshot,\n\tNeonDatabaseSnapshot,\n\tNeonEndpointSnapshot,\n\tNeonFunctionDeploymentSnapshot,\n\tNeonFunctionSnapshot,\n\tNeonProjectSnapshot,\n\tNeonRoleSnapshot,\n\tUpdateBranchInput,\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 || !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\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\tactive_deployment: functionDeploymentSchema.optional(),\n});\nconst functionsListResponseSchema = z.object({\n\tfunctions: z.array(neonFunctionSchema),\n});\nconst functionDeploymentResponseSchema = z.object({\n\tdeployment: functionDeploymentSchema,\n});\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});\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\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\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}\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 getJson(path: string): Promise<unknown> {\n\t\treturn this.request(\"GET\", path);\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\" | \"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\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\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 `OPENAI_*` /\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 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 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\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\n/**\n * Per-status guidance for a Preview feature that came back \"unavailable\". A preview can be\n * gated several different ways and the HTTP status is the best signal for which, so we tailor\n * the next step instead of emitting one catch-all — valuable while these features are in\n * preview and rolling out region by region:\n *\n * - 404 / 501 — the route isn't deployed for this project's region (or the account isn't in\n * the private preview): create a project in a region where the preview is enabled, and\n * confirm your account has preview access.\n * - 503 — the route exists but is refusing right now: either the preview is still coming up,\n * or Neon is having a transient incident. Retry; if it persists it's likely an incident.\n * - anything else — generic \"not enabled for your account/region; request access\".\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 previewUnavailableHint(status: number | undefined): string {\n\tswitch (status) {\n\t\tcase 404:\n\t\tcase 501:\n\t\t\treturn (\n\t\t\t\t\"This usually means the preview isn't available in your project's region yet, or \" +\n\t\t\t\t\"your Neon account isn't in the private preview: create a project in a region where \" +\n\t\t\t\t\"the preview is enabled, and make sure your account has access to the preview.\"\n\t\t\t);\n\t\tcase 503:\n\t\t\treturn (\n\t\t\t\t\"The endpoint is reachable but refused the request — the preview may still be \" +\n\t\t\t\t\"coming up, or Neon may be having a transient incident. Retry shortly; if it keeps \" +\n\t\t\t\t\"failing, check https://neonstatus.com and report it to Neon support.\"\n\t\t\t);\n\t\tdefault:\n\t\t\treturn (\n\t\t\t\t\"This usually means the preview isn't enabled for your Neon account or the project's \" +\n\t\t\t\t\"region. Request access to the preview, or use a project in a region where it's available.\"\n\t\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 (valuable\n * signal while the feature is in preview), gives status-specific guidance (see\n * {@link previewUnavailableHint}), and offers removing the feature from the policy as an\n * escape hatch. `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} is a Preview feature and isn't available for this Neon project${apiContext}.`,\n\t\t\tpreviewUnavailableHint(status),\n\t\t\t\"If you don't need it, remove the corresponding feature from the `preview` block of 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\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":";;;;;;;AAyEA,MAAM,4BAA4B;;;;;;;AAQlC,SAAS,OAAU,QAIb;CACL,MAAM,WAAW,OAAO;CACxB,IAAI,CAAC,YAAY,CAAC,SAAS,IAC1B,MAAM,EACL,UAAU;EACT,QAAQ,UAAU;EAClB,MAAM,OAAO;CACd,EACD;CAED,OAAO,OAAO;AACf;AAEA,MAAM,yBAAyB,EAAE,OAAO;CACvC,0BAA0B,EAAE,OAAO;CACnC,gBAAgB,EAAE,OAAO,CAAC,CAAC,SAAS;CACpC,mBAAmB,EAAE,OAAO,CAAC,CAAC,SAAS;CACvC,UAAU,EAAE,OAAO;CACnB,UAAU,EAAE,OAAO,CAAC,CAAC,SAAS;AAC/B,CAAC;;AAKD,SAAS,qBAAqB,UAA+C;CAC5E,MAAM,MAA0B,CAAC;CACjC,IAAI,SAAS,wBAAwB,KAAA,GACpC,IAAI,wBAAwB,SAAS;CACtC,IAAI,SAAS,eAAe,KAAA,GAC3B,IAAI,eAAe,SAAS;CAC7B,IAAI,SAAS,sBAAsB,KAAA,GAClC,IAAI,uBAAuB,SAAS;CACrC,IAAI,SAAS,cAAc,KAAA,GAAW,IAAI,cAAc,SAAS;CACjE,IAAI,SAAS,cAAc,KAAA,GAAW,IAAI,aAAa,SAAS;CAChE,IAAI,SAAS,oBAAoB,KAAA,GAChC,IAAI,qBAAqB,SAAS;CACnC,IAAI,SAAS,wBAAwB,KAAA,GACpC,IAAI,yBAAyB,SAAS;CACvC,IAAI,SAAS,gBAAgB,KAAA,GAC5B,IAAI,eAAe,SAAS;CAC7B,IAAI,SAAS,6BAA6B,KAAA,GACzC,IAAI,8BAA8B,SAAS;CAC5C,IAAI,SAAS,wBAAwB,KAAA,GACpC,IAAI,wBAAwB,SAAS;CACtC,OAAO;AACR;;AAGA,SAAS,qBACR,OAC6C;CAC7C,OAAO,UAAU,uBAAuB,UAAU,aAC/C,QACA,KAAA;AACJ;;AAGA,SAAS,uBACR,UAC8B;CAC9B,IAAI,CAAC,UAAU,OAAO,KAAA;CACtB,MAAM,MAAuB,CAAC;CAC9B,IAAI,SAAS,0BAA0B,KAAA,GACtC,IAAI,sBAAsB,SAAS;CACpC,IAAI,SAAS,iBAAiB,KAAA,GAC7B,IAAI,aAAa,SAAS;CAC3B,IAAI,SAAS,yBAAyB,KAAA,GACrC,IAAI,oBAAoB,SAAS;CAClC,IAAI,SAAS,gBAAgB,KAAA,GAC5B,IAAI,YAAY,SAAS;CAC1B,IAAI,SAAS,eAAe,KAAA,GAAW,IAAI,YAAY,SAAS;CAChE,IAAI,SAAS,uBAAuB,KAAA,GACnC,IAAI,kBAAkB,SAAS;CAChC,IAAI,SAAS,2BAA2B,KAAA,GACvC,IAAI,sBAAsB,SAAS;CACpC,IAAI,SAAS,iBAAiB,KAAA,GAAW;EACxC,MAAM,OAAO,qBAAqB,SAAS,YAAY;EACvD,IAAI,SAAS,KAAA,GAAW,IAAI,cAAc;CAC3C;CACA,IAAI,SAAS,gCAAgC,KAAA,GAC5C,IAAI,2BAA2B,SAAS;CACzC,IAAI,SAAS,0BAA0B,KAAA,GACtC,IAAI,sBAAsB,SAAS;CACpC,OAAO,OAAO,KAAK,GAAG,CAAC,CAAC,SAAS,IAAI,MAAM,KAAA;AAC5C;;AAGA,SAAS,qBACR,OACuB;CACvB,MAAM,MAA4B,CAAC;CACnC,IAAI,CAAC,OAAO,OAAO;CACnB,IAAI,MAAM,iBAAiB,KAAA,GAC1B,IAAI,gBACH,MAAM,iBAAiB,SAAS,cAAc;CAChD,IAAI,MAAM,YAAY,KAAA,GAAW,IAAI,WAAW,MAAM;CACtD,IAAI,MAAM,iBAAiB,KAAA,GAC1B,IAAI,gBAAgB,MAAM;CAC3B,IAAI,MAAM,gBAAgB,KAAA,GAAW,IAAI,eAAe,MAAM;CAC9D,IAAI,MAAM,UAAU;EACnB,MAAM,WAAW,qBAAqB,MAAM,QAAQ;EACpD,IAAI,OAAO,KAAK,QAAQ,CAAC,CAAC,SAAS,GAAG,IAAI,WAAW;CACtD;CACA,OAAO;AACR;;AAGA,SAAS,4BACR,MACsB;CACtB,MAAM,WAAgC,EAAE,KAAK,KAAK,IAAI;CACtD,IAAI,KAAK,WAAW,KAAA,GAAW,SAAS,SAAS,KAAK;CACtD,MAAM,WAAW,uBAAuB,KAAK,QAAQ;CACrD,IAAI,UAAU,SAAS,WAAW;CAClC,OAAO;AACR;AAIA,MAAM,eAAe,EAAE,OAAO;CAC7B,MAAM,EAAE,OAAO;CACf,cAAc,EAAE,OAAO,CAAC,CAAC,SAAS;AACnC,CAAC;AACD,MAAM,uBAAuB,EAAE,OAAO,EAAE,QAAQ,aAAa,CAAC;AAC9D,MAAM,4BAA4B,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,EAAE,CAAC;AAC7E,MAAM,sBAAsB,EAAE,OAAO;CACpC,SAAS,EAAE,QAAQ,CAAC,CAAC,SAAS;CAC9B,aAAa,EAAE,OAAO;CACtB,QAAQ,EAAE,OAAO;CACjB,kBAAkB,EAAE,QAAQ;AAC7B,CAAC;AAID,MAAM,2BAA2B,EAAE,OAAO;CACzC,IAAI,EAAE,OAAO;CACb,QAAQ,EAAE,OAAO;AAClB,CAAC;AACD,MAAM,qBAAqB,EAAE,OAAO;CACnC,IAAI,EAAE,OAAO;CACb,MAAM,EAAE,OAAO;CACf,MAAM,EAAE,OAAO;CACf,gBAAgB,EAAE,OAAO;CACzB,mBAAmB,yBAAyB,SAAS;AACtD,CAAC;AACD,MAAM,8BAA8B,EAAE,OAAO,EAC5C,WAAW,EAAE,MAAM,kBAAkB,EACtC,CAAC;AACD,MAAM,mCAAmC,EAAE,OAAO,EACjD,YAAY,yBACb,CAAC;AAID,MAAM,wBAAwB,EAAE,KAAK;CACpC;CACA;CACA;CACA;AACD,CAAC;AACD,MAAM,iCAAiC,EAAE,OAAO;CAC/C,UAAU,EAAE,OAAO;CACnB,gBAAgB,EAAE,OAAO;CACzB,MAAM,EAAE,OAAO,CAAC,CAAC,SAAS;CAC1B,WAAW,EAAE,OAAO;CACpB,sBAAsB,EAAE,OAAO;CAC/B,QAAQ,EAAE,MAAM,qBAAqB;CACrC,WAAW,EAAE,OAAO;CACpB,YAAY,EAAE,OAAO;CACrB,YAAY,EAAE,OAAO,CAAC,CAAC,SAAS;AACjC,CAAC;AACD,MAAM,uBAAuB,EAAE,OAAO;CACrC,UAAU,EAAE,OAAO;CACnB,gBAAgB,EAAE,OAAO;CACzB,MAAM,EAAE,OAAO,CAAC,CAAC,SAAS;CAC1B,QAAQ,EAAE,MAAM,qBAAqB;CACrC,gBAAgB,EAAE,KAAK,CAAC,QAAQ,UAAU,CAAC;CAC3C,aAAa,EAAE,OAAO,CAAC,CAAC,SAAS;CACjC,WAAW,EAAE,OAAO,CAAC,CAAC,SAAS;CAC/B,YAAY,EAAE,OAAO;CACrB,cAAc,EAAE,OAAO,CAAC,CAAC,SAAS;CAClC,YAAY,EAAE,OAAO,CAAC,CAAC,SAAS;CAChC,YAAY,EAAE,OAAO,CAAC,CAAC,SAAS;AACjC,CAAC;AACD,MAAM,gCAAgC,EAAE,OAAO,EAC9C,aAAa,EAAE,MAAM,oBAAoB,EAC1C,CAAC;;;;;;AAiBD,SAAgB,kBAAkB,SAatB;CACX,IAAI,CAAC,QAAQ,UAAU,QAAQ,OAAO,KAAK,MAAM,IAChD,MAAM,IAAI,cACT,UAAU,eACV,CACC,oDACA,sHACD,CAAC,CAAC,KAAK,GAAG,CACX;CAKD,MAAM,SAAS,iBAAiB;EAC/B,QAAQ,QAAQ;EAChB,SAAS;EACT,GAAI,QAAQ,UAAU,EAAE,SAAS,QAAQ,QAAQ,IAAI,CAAC;CACvD,CAAC,CAAC,CAAC;CAEH,OAAO,IAAI,YACV,QACA;EACC,aAAa,QAAQ,eAAe,eAAe;EACnD,gBAAgB,QAAQ,eAAe,kBAAkB;EACzD,YAAY,QAAQ,eAAe,cAAc;CAClD,GACA;EACC,QAAQ,QAAQ;EAChB,SAAS,QAAQ,WAAW;CAC7B,CACD;AACD;;;;;;;;AAeA,eAAsB,cACrB,IACA,QACa;CACb,IAAI,QAAQ,OAAO;CACnB,IAAI;CACJ,KAAK,IAAI,UAAU,GAAG,WAAW,OAAO,aAAa,WACpD,IAAI;EACH,OAAO,MAAM,GAAG;CACjB,SAAS,KAAK;EACb,YAAY;EAEZ,IADe,wBAAwB,GAC9B,MAAM,OAAO,YAAY,OAAO,aAAa,MAAM;EAC5D,MAAM,MAAM,KAAK;EACjB,QAAQ,KAAK,IAAI,QAAQ,GAAG,OAAO,UAAU;CAC9C;CAED,MAAM;AACP;AAEA,SAAS,wBAAwB,KAAkC;CAClE,IAAI,QAAQ,QAAQ,OAAO,QAAQ,UAAU,OAAO,KAAA;CACpD,MAAM,WAAY,IAA+B;CACjD,IAAI,aAAa,QAAQ,OAAO,aAAa,UAAU,OAAO,KAAA;CAC9D,MAAM,SAAU,SAAkC;CAClD,OAAO,OAAO,WAAW,WAAW,SAAS,KAAA;AAC9C;AAEA,SAAS,MAAM,IAA2B;CACzC,OAAO,IAAI,SAAS,YAAY,WAAW,SAAS,EAAE,CAAC;AACxD;AAEA,IAAM,cAAN,MAAqC;CAElB;CACA;CACA;CAHlB,YACC,QACA,aACA,YACC;EAHgB,KAAA,SAAA;EACA,KAAA,cAAA;EACA,KAAA,aAAA;CACf;CAEH,MAAiB,IAAkC;EAClD,OAAO,cAAc,IAAI,KAAK,WAAW;CAC1C;CAEA,MAAc,KACb,IACA,IACA,UAAsD,CAAC,GAC1C;EACb,IAAI;GACH,OAAO,QAAQ,WAAW,MAAM,KAAK,MAAM,EAAE,IAAI,MAAM,GAAG;EAC3D,SAAS,KAAK;GAOb,MANgB,cACf,KACA,QAAQ,YACL;IAAE;IAAI,WAAW,QAAQ;GAAU,IACnC,EAAE,GAAG,CAEG;EACb;CACD;CAEA,MAAM,aAAa,QAEgB;EAClC,OAAO,KAAK,KACX,OAAO,QAAQ,oBAAoB,OAAO,MAAM,KAAK,gBACrD,YAAY;GACX,MAAM,WAA8B,CAAC;GACrC,IAAI;GACJ,OAAO,MAAM;IACZ,MAAM,OAAO,OACZ,MAAMA,aAAgB;KACrB,QAAQ,KAAK;KACb,OAAO;MACN,GAAI,OAAO,QACR,EAAE,QAAQ,OAAO,MAAM,IACvB,CAAC;MACJ,GAAI,SAAS,EAAE,OAAO,IAAI,CAAC;MAC3B,OAAO;KACR;IACD,CAAC,CACF;IACA,SAAS,KAAK,GAAG,KAAK,QAAQ;IAC9B,MAAM,OAAQ,KACZ,YAAY;IACd,IAAI,CAAC,QAAQ,SAAS,QAAQ;IAC9B,SAAS;GACV;GACA,OAAO,SAAS,IAAI,iBAAiB;EACtC,CACD;CACD;CAEA,MAAM,WAAW,WAAiD;EACjE,OAAO,KAAK,KACX,cAAc,UAAU,IACxB,YAAY;GAOX,OAAO,kBANM,OACZ,MAAMC,WAAc;IACnB,QAAQ,KAAK;IACb,MAAM,EAAE,YAAY,UAAU;GAC/B,CAAC,CAE0B,CAAC,CAAC,OAAO;EACtC,GACA,EAAE,UAAU,CACb;CACD;CAEA,MAAM,cACL,OAC+B;EAC/B,MAAM,OAA6B,EAClC,SAAS;GACR,MAAM,MAAM;GACZ,WAAW,MAAM;GACjB,GAAI,MAAM,cAAc,KAAA,IACrB,EAAE,YAAY,MAAM,UAAuB,IAC3C,CAAC;GACJ,GAAI,MAAM,QAAQ,EAAE,QAAQ,MAAM,MAAM,IAAI,CAAC;GAC7C,GAAI,MAAM,0BACP,EACA,2BACC,0BACC,MAAM,uBACP,EACF,IACC,CAAC;GACJ,GAAI,MAAM,oBACP,EAAE,QAAQ,EAAE,MAAM,MAAM,kBAAkB,EAAE,IAC5C,CAAC;EACL,EACD;EACA,OAAO,KAAK,KACX,iBAAiB,MAAM,KAAK,IAC5B,YAAY;GAIX,OAAO,kBAHM,OACZ,MAAMC,cAAiB;IAAE,QAAQ,KAAK;IAAQ;GAAK,CAAC,CAEzB,CAAC,CAAC,OAAO;EACtC,GACA,EAAE,UAAU,KAAK,CAClB;CACD;CAEA,MAAM,cACL,WACA,OAC+B;EAC/B,MAAM,OAA6B,EAClC,SAAS;GACR,GAAI,MAAM,SAAS,KAAA,IAAY,EAAE,MAAM,MAAM,KAAK,IAAI,CAAC;GACvD,GAAI,MAAM,0BACP,EACA,2BACC,0BACC,MAAM,uBACP,EACF,IACC,CAAC;EACL,EACD;EACA,OAAO,KAAK,KACX,iBAAiB,UAAU,IAC3B,YAAY;GAQX,OAAO,kBAPM,OACZ,MAAMC,cAAiB;IACtB,QAAQ,KAAK;IACb,MAAM,EAAE,YAAY,UAAU;IAC9B;GACD,CAAC,CAE0B,CAAC,CAAC,OAAO;EACtC,GACA;GAAE;GAAW,UAAU;EAAK,CAC7B;CACD;CAEA,MAAM,aAAa,WAAkD;EACpE,OAAO,KAAK,KACX,gBAAgB,UAAU,IAC1B,YAAY;GACX,MAAM,WAAqB,CAAC;GAC5B,IAAI;GACJ,OAAO,MAAM;IACZ,MAAM,OAAO,OACZ,MAAMC,oBAAuB;KAC5B,QAAQ,KAAK;KACb,MAAM,EAAE,YAAY,UAAU;KAC9B,OAAO;MACN,OAAO;MACP,GAAI,SAAS,EAAE,OAAO,IAAI,CAAC;KAC5B;IACD,CAAC,CACF;IACA,SAAS,KAAK,GAAI,KAAK,QAAqB;IAC5C,MAAM,OAAQ,KACZ,YAAY;IACd,IAAI,CAAC,QAAQ,SAAS,QAAQ;IAC9B,SAAS;GACV;GACA,OAAO,SAAS,IAAI,gBAAgB;EACrC,GACA,EAAE,UAAU,CACb;CACD;CAEA,MAAM,aACL,WACA,OAIE;EACF,MAAM,kBACL,MAAM,kBACH;GACA,MAAM;GACN,GAAG,iCACF,MAAM,eACP;EACD,IACC,EAAE,MAAM,aAAa;EAEzB,MAAM,OAA4B;GACjC,QAAQ;IACP,MAAM,MAAM;IACZ,GAAI,MAAM,WAAW,EAAE,WAAW,MAAM,SAAS,IAAI,CAAC;IACtD,GAAI,MAAM,YAAY,EAAE,YAAY,MAAM,UAAU,IAAI,CAAC;IACzD,GAAI,MAAM,cAAc,KAAA,IACrB,EAAE,WAAW,MAAM,UAAU,IAC7B,CAAC;GACL;GACA,WAAW,CAAC,eAAe;EAC5B;EACA,OAAO,KAAK,KACX,gBAAgB,UAAU,GAAG,MAAM,KAAK,IACxC,YAAY;GACX,MAAM,OAAO,OACZ,MAAMC,oBAAuB;IAC5B,QAAQ,KAAK;IACb,MAAM,EAAE,YAAY,UAAU;IAC9B;GACD,CAAC,CACF;GACA,OAAO;IACN,QAAQ,iBAAiB,KAAK,MAAM;IACpC,YAAY,KAAK,aAAa,CAAC,EAAA,CAAG,IAAI,kBAAkB;GACzD;EACD,GACA;GAAE;GAAW,UAAU;EAAK,CAC7B;CACD;CAEA,MAAM,aACL,WACA,UACA,OAC8B;EAC9B,MAAM,SAAwC,CAAC;EAC/C,IAAI,MAAM,SAAS,KAAA,GAAW,OAAO,OAAO,MAAM;EAClD,IAAI,MAAM,cAAc,KAAA,GAAW,OAAO,aAAa,MAAM;EAC7D,IAAI,MAAM,cAAc,KAAA,GAAW,OAAO,YAAY,MAAM;EAC5D,OAAO,KAAK,KACX,gBAAgB,UAAU,GAAG,SAAS,IACtC,YAAY;GAQX,OAAO,iBAPM,OACZ,MAAMC,oBAAuB;IAC5B,QAAQ,KAAK;IACb,MAAM;KAAE,YAAY;KAAW,WAAW;IAAS;IACnD,MAAM,EAAE,OAAO;GAChB,CAAC,CAEyB,CAAC,CAAC,MAAM;EACpC,GACA;GAAE;GAAW,UAAU;EAAK,CAC7B;CACD;CAEA,MAAM,cAAc,WAAoD;EACvE,OAAO,KAAK,KACX,iBAAiB,UAAU,IAC3B,YAAY;GAOX,OANa,OACZ,MAAMC,qBAAwB;IAC7B,QAAQ,KAAK;IACb,MAAM,EAAE,YAAY,UAAU;GAC/B,CAAC,CAES,CAAC,CAAC,UAAyB,IAAI,kBAAkB;EAC7D,GACA,EAAE,UAAU,CACb;CACD;CAEA,MAAM,eACL,WACA,YACA,UACgC;EAChC,MAAM,WACL,iCAAiC,QAAQ;EAC1C,OAAO,KAAK,KACX,kBAAkB,UAAU,GAAG,WAAW,IAC1C,YAAY;GAWX,OAAO,mBAVM,OACZ,MAAMC,sBAAyB;IAC9B,QAAQ,KAAK;IACb,MAAM;KACL,YAAY;KACZ,aAAa;IACd;IACA,MAAM,EAAE,SAAS;GAClB,CAAC,CAE2B,CAAC,CAAC,QAAQ;EACxC,GACA;GAAE;GAAW,UAAU;EAAK,CAC7B;CACD;CAEA,MAAM,gBACL,WACA,UAC8B;EAC9B,OAAO,KAAK,KACX,mBAAmB,UAAU,GAAG,SAAS,IACzC,YAAY;GAOX,OANa,OACZ,MAAMC,uBAA0B;IAC/B,QAAQ,KAAK;IACb,MAAM;KAAE,YAAY;KAAW,WAAW;IAAS;GACpD,CAAC,CAES,CAAC,CAAC,MAAiB,IAAI,cAAc;EACjD,GACA,EAAE,UAAU,CACb;CACD;CAEA,MAAM,oBACL,WACA,UACkC;EAClC,OAAO,KAAK,KACX,uBAAuB,UAAU,GAAG,SAAS,IAC7C,YAAY;GAOX,OANa,OACZ,MAAMC,2BAA8B;IACnC,QAAQ,KAAK;IACb,MAAM;KAAE,YAAY;KAAW,WAAW;IAAS;GACpD,CAAC,CAES,CAAC,CAAC,UAAyB,IAAI,kBAAkB;EAC7D,GACA,EAAE,UAAU,CACb;CACD;CAEA,MAAM,iBACL,WACA,OAC2B;EAC3B,MAAM,KAAK,oBAAoB,UAAU,GAAG,MAAM,aAAa,GAAG,MAAM,WAAW,MAAM,SAAS,YAAY,GAAG;EAIjH,MAAM,SAAS,MAAM,WAAW;EAChC,OAAO,KAAK,KACX,IACA,YAAY;GAkBX,OAAO,EAAE,KAjBI,OACZ,MAAMC,iBAAoB;IACzB,QAAQ,KAAK;IACb,MAAM,EAAE,YAAY,UAAU;IAC9B,OAAO;KACN,eAAe,MAAM;KACrB,WAAW,MAAM;KACjB,GAAI,MAAM,WACP,EAAE,WAAW,MAAM,SAAS,IAC5B,CAAC;KACJ,GAAI,MAAM,aACP,EAAE,aAAa,MAAM,WAAW,IAChC,CAAC;KACJ;IACD;GACD,CAAC,CAEe,CAAC,CAAC,IAAI;EACxB,GACA,EAAE,UAAU,CACb;CACD;CAEA,MAAM,YACL,WACA,UACmC;EAGnC,IAAI;GACH,OAAO,MAAM,KAAK,KACjB,eAAe,UAAU,GAAG,SAAS,IACrC,YAAY;IACX,MAAM,OAAO,OACZ,MAAMC,YAAe;KACpB,QAAQ,KAAK;KACb,MAAM;MACL,YAAY;MACZ,WAAW;KACZ;IACD,CAAC,CACF;IACA,OAAO,2BACN,uBAAuB,MAAM,IAAI,CAClC;GACD,GACA,EAAE,UAAU,CACb;EACD,SAAS,KAAK;GACb,IAAI,eAAe,iBAAiB,IAAI,SAAS,UAAU,UAC1D,OAAO;GACR,MAAM;EACP;CACD;CAEA,MAAM,eACL,WACA,UACA,QAAmC,CAAC,GACR;EAI5B,IAAI;GACH,OAAO,MAAM,KAAK,KACjB,kBAAkB,UAAU,GAAG,SAAS,IACxC,YAAY;IAGX,MAAM,OAAO,MAAM,KAAK,SACvB,aAAa,mBAAmB,SAAS,EAAE,YAAY,mBAAmB,QAAQ,EAAE,QACpF,wBAAwB,KAAK,CAC9B;IAEA,OAAO,2BADQ,uBAAuB,MAAM,IACL,CAAC;GACzC,GACA;IAAE;IAAW,UAAU;GAAK,CAC7B;EACD,SAAS,KAAK;GACb,IACC,eAAe,iBACf,IAAI,SAAS,UAAU,UACtB;IACD,MAAM,WAAW,MAAM,KAAK,YAAY,WAAW,QAAQ;IAC3D,IAAI,UAAU,OAAO;GACtB;GACA,MAAM;EACP;CACD;CAEA,MAAc,SAAS,MAAc,MAAiC;EACrE,OAAO,KAAK,QAAQ,QAAQ,MAAM;GACjC,SAAS,EAAE,gBAAgB,mBAAmB;GAC9C,MAAM,KAAK,UAAU,IAAI;EAC1B,CAAC;CACF;CAEA,MAAc,QAAQ,MAAgC;EACrD,OAAO,KAAK,QAAQ,OAAO,IAAI;CAChC;CAEA,MAAc,WAAW,MAAgC;EACxD,OAAO,KAAK,QAAQ,UAAU,IAAI;CACnC;;;;;;CAOA,MAAc,cACb,MACA,OACmB;EACnB,OAAO,KAAK,QAAQ,QAAQ,MAAM,EACjC,MAAM,wBAAwB,KAAK,EACpC,CAAC;CACF;CAEA,MAAc,QACb,QACA,MACA,OAA8D,CAAC,GAC5C;EACnB,MAAM,MAAM,GAAG,KAAK,WAAW,QAAQ,QAAQ,QAAQ,EAAE,IAAI;EAC7D,MAAM,MAAM,MAAM,MAAM,KAAK;GAC5B;GACA,SAAS;IACR,eAAe,UAAU,KAAK,WAAW;IACzC,GAAI,KAAK,WAAW,CAAC;GACtB;GACA,GAAI,KAAK,SAAS,KAAA,IAAY,EAAE,MAAM,KAAK,KAAK,IAAI,CAAC;EACtD,CAAC;EACD,MAAM,OAAO,MAAM,aAAa,GAAG;EACnC,IAAI,CAAC,IAAI,IACR,MAAM,EACL,UAAU;GACT,QAAQ,IAAI;GACZ;EACD,EACD;EAED,OAAO;CACR;CAEA,MAAM,eACL,WACA,UACA,cACsC;EAGtC,IAAI;GACH,OAAO,MAAM,KAAK,KACjB,kBAAkB,UAAU,GAAG,SAAS,GAAG,aAAa,IACxD,YACC,4BACC,OACC,MAAMC,wBAA2B;IAChC,QAAQ,KAAK;IACb,MAAM;KACL,YAAY;KACZ,WAAW;KACX,eAAe;IAChB;GACD,CAAC,CACF,CACD,GACD,EAAE,UAAU,CACb;EACD,SAAS,KAAK;GACb,IAAI,eAAe,iBAAiB,IAAI,SAAS,UAAU,UAC1D,OAAO;GACR,MAAM;EACP;CACD;CAEA,MAAM,2BACL,WACA,UACA,cACA,OAC+B;EAG/B,IAAI;GACH,OAAO,MAAM,KAAK,KACjB,8BAA8B,UAAU,GAAG,SAAS,GAAG,aAAa,IACpE,YAAY;IAcX,OAAO,EAAE,KAbI,OACZ,MAAMC,2BAA8B;KACnC,QAAQ,KAAK;KACb,MAAM;MACL,YAAY;MACZ,WAAW;MACX,eAAe;KAChB;KACA,MAAM,qBAAqB,KAAK;IACjC,CAAC,CAIe,CAAC,CAAC,IAAI;GACxB,GACA;IAAE;IAAW,UAAU;GAAK,CAC7B;EACD,SAAS,KAAK;GACb,IACC,eAAe,iBACf,IAAI,SAAS,UAAU,UACtB;IACD,MAAM,WAAW,MAAM,KAAK,eAC3B,WACA,UACA,YACD;IACA,IAAI,UAAU,OAAO;GACtB;GACA,MAAM;EACP;CACD;CAEA,MAAM,2BACL,WACA,UACA,cACA,UAC+B;EAC/B,OAAO,MAAM,KAAK,KACjB,8BAA8B,UAAU,GAAG,SAAS,GAAG,aAAa,IACpE,YAAY;GACX,OACC,MAAMC,2BAA8B;IACnC,QAAQ,KAAK;IACb,MAAM;KACL,YAAY;KACZ,WAAW;KACX,eAAe;IAChB;IACA,MAAM,EAAE,UAAU,qBAAqB,QAAQ,EAAE;GAClD,CAAC,CACF;GAaA,OAAO,4BAVM,OACZ,MAAMF,wBAA2B;IAChC,QAAQ,KAAK;IACb,MAAM;KACL,YAAY;KACZ,WAAW;KACX,eAAe;IAChB;GACD,CAAC,CAEoC,CAAC;EACxC,GACA;GAAE;GAAW,UAAU;EAAK,CAC7B;CACD;CAIA,MAAM,kBACL,WACA,UACgC;EAChC,IAAI;GACH,OAAO,MAAM,KAAK,KACjB,qBAAqB,UAAU,GAAG,SAAS,IAC3C,YAAY;IACX,MAAM,OAAO,MAAM,KAAK,QACvB,kBAAkB,WAAW,UAAU,SAAS,CACjD;IAEA,OADe,0BAA0B,MAAM,IACnC,CAAC,CAAC,QAAQ,IAAI,gBAAgB;GAC3C,GACA,EAAE,UAAU,CACb;EACD,SAAS,KAAK;GACb,MAAM,wBAAwB,KAAK,0BAA0B;EAC9D;CACD;CAEA,MAAM,mBACL,WACA,UACA,OAC8B;EAC9B,OAAO,KAAK,KACX,sBAAsB,UAAU,GAAG,SAAS,GAAG,MAAM,KAAK,IAC1D,YAAY;GACX,MAAM,OAAO,MAAM,KAAK,SACvB,kBAAkB,WAAW,UAAU,SAAS,GAChD;IACC,MAAM,MAAM;IACZ,GAAI,MAAM,cACP,EAAE,cAAc,MAAM,YAAY,IAClC,CAAC;GACL,CACD;GAEA,OAAO,iBADQ,qBAAqB,MAAM,IACb,CAAC,CAAC,MAAM;EACtC,GACA;GAAE;GAAW,UAAU;EAAK,CAC7B;CACD;CAEA,MAAM,mBACL,WACA,UACA,YACgB;EAChB,MAAM,KAAK,KACV,sBAAsB,UAAU,GAAG,SAAS,GAAG,WAAW,IAC1D,YAAY;GACX,MAAM,KAAK,WACV,GAAG,kBAAkB,WAAW,UAAU,SAAS,EAAE,GAAG,mBAAmB,UAAU,GACtF;EACD,GACA;GAAE;GAAW,UAAU;EAAK,CAC7B;CACD;CAEA,MAAM,wBACL,WACA,UAC4C;EAC5C,IAAI;GACH,OAAO,MAAM,KAAK,KACjB,2BAA2B,UAAU,GAAG,SAAS,IACjD,YAAY;IACX,MAAM,OAAO,MAAM,KAAK,QACvB,aAAa,mBAAmB,SAAS,EAAE,YAAY,mBAAmB,QAAQ,EAAE,SACrF;IACA,MAAM,SAAS,oBAAoB,MAAM,IAAI;IAC7C,OAAO;KACN,YAAY,OAAO;KACnB,QAAQ,OAAO;KACf,gBAAgB,OAAO;IACxB;GACD,GACA,EAAE,UAAU,CACb;EACD,SAAS,KAAK;GAGb,IAAI,eAAe,iBAAiB,IAAI,SAAS,UAAU,UAC1D,OAAO;GACR,MAAM,wBAAwB,KAAK,gBAAgB;EACpD;CACD;CAIA,MAAM,oBACL,WACA,UACkC;EAClC,IAAI;GACH,OAAO,MAAM,KAAK,KACjB,uBAAuB,UAAU,GAAG,SAAS,IAC7C,YAAY;IACX,MAAM,OAAO,MAAM,KAAK,QACvB,kBAAkB,WAAW,UAAU,WAAW,CACnD;IAEA,OADe,4BAA4B,MAAM,IACrC,CAAC,CAAC,UAAU,IAAI,kBAAkB;GAC/C,GACA,EAAE,UAAU,CACb;EACD,SAAS,KAAK;GACb,MAAM,wBAAwB,KAAK,WAAW;EAC/C;CACD;CAEA,MAAM,qBACL,WACA,UACA,MACgB;EAChB,MAAM,KAAK,KACV,wBAAwB,UAAU,GAAG,SAAS,GAAG,KAAK,IACtD,YAAY;GACX,MAAM,KAAK,WACV,GAAG,kBAAkB,WAAW,UAAU,WAAW,EAAE,GAAG,mBAAmB,IAAI,GAClF;EACD,GACA;GAAE;GAAW,UAAU;EAAK,CAC7B;CACD;CAEA,MAAM,qBACL,WACA,UACA,MACA,OAC0C;EAC1C,OAAO,KAAK,KACX,wBAAwB,UAAU,GAAG,SAAS,GAAG,KAAK,IACtD,YAAY;GACX,MAAM,OAAO,MAAM,KAAK,cACvB,GAAG,kBAAkB,WAAW,UAAU,WAAW,EAAE,GAAG,mBAAmB,IAAI,EAAE,eACnF,KACD;GAEA,OAAO,qBADQ,iCAAiC,MAAM,IACrB,CAAC,CAAC,UAAU;EAC9C,GACA;GAAE;GAAW,UAAU;EAAK,CAC7B;CACD;CAaA,MAAM,iBACL,WACA,UACA,OACgC;EAChC,IAAI;GACH,OAAO,MAAM,KAAK,KACjB,oBAAoB,UAAU,GAAG,SAAS,IAC1C,YAAY;IACX,MAAM,OAAO,MAAM,KAAK,SACvB,gBAAgB,WAAW,QAAQ,GACnC;KACC,QAAQ,MAAM;KACd,gBAAgB,MAAM;KACtB,GAAI,MAAM,aACP,EAAE,aAAa,MAAM,WAAW,IAChC,CAAC;KACJ,GAAI,MAAM,OAAO,EAAE,MAAM,MAAM,KAAK,IAAI,CAAC;IAC1C,CACD;IAEA,OAAO,2BADQ,+BAA+B,MAAM,IACb,CAAC;GACzC,GACA;IAAE;IAAW,UAAU;GAAK,CAC7B;EACD,SAAS,KAAK;GACb,MAAM,wBAAwB,KAAK,oBAAoB;EACxD;CACD;CAEA,MAAM,gBACL,WACA,UACgC;EAChC,IAAI;GACH,OAAO,MAAM,KAAK,KACjB,mBAAmB,UAAU,GAAG,SAAS,IACzC,YAAY;IACX,MAAM,OAAO,MAAM,KAAK,QACvB,gBAAgB,WAAW,QAAQ,CACpC;IAEA,OADe,8BAA8B,MAAM,IACvC,CAAC,CAAC,YAAY,IAAI,wBAAwB;GACvD,GACA,EAAE,UAAU,CACb;EACD,SAAS,KAAK;GACb,MAAM,wBAAwB,KAAK,oBAAoB;EACxD;CACD;CAEA,MAAM,iBACL,WACA,UACA,SACgB;EAChB,MAAM,KAAK,KACV,oBAAoB,UAAU,GAAG,SAAS,GAAG,QAAQ,IACrD,YAAY;GACX,MAAM,KAAK,WACV,GAAG,gBAAgB,WAAW,QAAQ,EAAE,GAAG,mBAAmB,OAAO,GACtE;EACD,GACA;GAAE;GAAW,UAAU;EAAK,CAC7B;CACD;AACD;AAEA,SAAS,kBACR,WACA,UACA,UACS;CACT,OAAO,aAAa,mBAAmB,SAAS,EAAE,YAAY,mBAAmB,QAAQ,EAAE,GAAG;AAC/F;AAEA,SAAS,gBAAgB,WAAmB,UAA0B;CACrE,OAAO,aAAa,mBAAmB,SAAS,EAAE,YAAY,mBAAmB,QAAQ,EAAE;AAC5F;AAEA,SAAS,2BACR,MACuB;CACvB,MAAM,WAAiC;EACtC,SAAS,KAAK;EACd,cAAc,KAAK;EACnB,UAAU,KAAK;EACf,mBAAmB,KAAK;EACxB,QAAQ,KAAK;EACb,UAAU,KAAK;EACf,WAAW,KAAK;CACjB;CACA,IAAI,KAAK,SAAS,KAAA,GAAW,SAAS,OAAO,KAAK;CAClD,IAAI,KAAK,eAAe,KAAA,GAAW,SAAS,YAAY,KAAK;CAC7D,OAAO;AACR;AAEA,SAAS,yBACR,MACqB;CACrB,MAAM,WAA+B;EACpC,SAAS,KAAK;EACd,cAAc,KAAK;EACnB,QAAQ,KAAK;EACb,eAAe,KAAK;EACpB,WAAW,KAAK;CACjB;CACA,IAAI,KAAK,SAAS,KAAA,GAAW,SAAS,OAAO,KAAK;CAClD,IAAI,KAAK,gBAAgB,KAAA,GAAW,SAAS,aAAa,KAAK;CAC/D,IAAI,KAAK,cAAc,KAAA,GAAW,SAAS,WAAW,KAAK;CAC3D,IAAI,KAAK,iBAAiB,KAAA,GACzB,SAAS,aAAa,KAAK;CAC5B,IAAI,KAAK,eAAe,KAAA,GAAW,SAAS,YAAY,KAAK;CAC7D,IAAI,KAAK,eAAe,KAAA,GAAW,SAAS,YAAY,KAAK;CAC7D,OAAO;AACR;AAEA,SAAS,iBACR,QACqB;CACrB,OAAO;EACN,MAAM,OAAO;EACb,aAAa,2BAA2B,OAAO,YAAY;CAC5D;AACD;;;;;;AAOA,SAAS,2BACR,OACoB;CACpB,OAAO,UAAU,gBAAgB,gBAAgB;AAClD;AAEA,SAAS,mBACR,IACuB;CACvB,MAAM,WAAiC;EACtC,IAAI,GAAG;EACP,MAAM,GAAG;EACT,MAAM,GAAG;EACT,eAAe,GAAG;CACnB;CACA,IAAI,GAAG,mBACN,SAAS,qBAAqB,GAAG,kBAAkB;CAEpD,OAAO;AACR;AAEA,SAAS,qBACR,YACiC;CACjC,OAAO;EACN,IAAI,WAAW;EACf,QAAQ,0BAA0B,WAAW,MAAM;CACpD;AACD;AAEA,SAAS,0BACR,OAC2C;CAC3C,QAAQ,OAAR;EACC,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK,UACJ,OAAO;EACR,SAGC,OAAO;CACT;AACD;;;;;;;;;;;;AAaA,SAAgB,4BAA4B,KAAuB;CAClE,IAAI,EAAE,eAAe,gBAAgB,OAAO;CAC5C,MAAM,SAAS,IAAI,QAAQ;CAC3B,MAAM,UACL,OAAO,IAAI,QAAQ,gBAAgB,WAChC,IAAI,QAAQ,YAAY,YAAY,IACpC;CAKJ,QAHC,QAAQ,SAAS,eAAe,KAChC,QAAQ,SAAS,gBAAgB,KACjC,QAAQ,SAAS,aAAa,OAG7B,WAAW,OAAO,WAAW,OAAO,WAAW;AAElD;;;;;;AAOA,MAAM,mBAA2C;CAChD,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;AACN;;;;;;;;;;;;;;;;;AAkBA,SAAS,uBAAuB,QAAoC;CACnE,QAAQ,QAAR;EACC,KAAK;EACL,KAAK,KACJ,OACC;EAIF,KAAK,KACJ,OACC;EAIF,SACC,OACC;CAGH;AACD;;;;;;;;;;;;AAaA,SAAgB,wBACf,KACA,cACU;CACV,IAAI,CAAC,4BAA4B,GAAG,GAAG,OAAO;CAC9C,MAAM,UAAU,eAAe,gBAAgB,IAAI,UAAU,CAAC;CAC9D,MAAM,SACL,OAAO,QAAQ,WAAW,WAAW,QAAQ,SAAS,KAAA;CACvD,MAAM,cACL,OAAO,QAAQ,gBAAgB,WAC5B,QAAQ,cACR,KAAA;CACJ,MAAM,YACL,OAAO,QAAQ,cAAc,WAAW,QAAQ,YAAY,KAAA;CAG7D,MAAM,aAAa,SAAS,iBAAiB,UAAU,KAAA;CACvD,MAAM,WAAW;EAChB,SACG,QAAQ,SAAS,aAAa,IAAI,eAAe,OACjD,KAAA;EACH,cAAc,mBAAmB,YAAY,KAAK,KAAA;EAClD,YAAY,cAAc,cAAc,KAAA;CACzC,CAAC,CAAC,QAAQ,SAAyB,SAAS,KAAA,CAAS;CACrD,MAAM,aAAa,SAAS,SAAS,IAAI,KAAK,SAAS,KAAK,IAAI,EAAE,KAAK;CAEvE,OAAO,IAAI,cACV,UAAU,oBACV;EACC,GAAG,aAAa,iEAAiE,WAAW;EAC5F,uBAAuB,MAAM;EAC7B;CACD,CAAC,CAAC,KAAK,GAAG,GACV;EACC,OAAO;EACP,SAAS;GACR,SAAS;GACT,GAAI,WAAW,KAAA,IAAY,EAAE,OAAO,IAAI,CAAC;GACzC,GAAI,cAAc,KAAA,IAAY,EAAE,UAAU,IAAI,CAAC;EAChD;CACD,CACD;AACD;AAEA,SAAS,2BACR,MACmB;CACnB,MAAM,WAA6B;EAClC,WAAW,KAAK;EAChB,SAAS,KAAK;CACf;CACA,IAAI,KAAK,mBAAmB,KAAA,GAC3B,SAAS,uBAAuB,KAAK;CAEtC,IAAI,KAAK,sBAAsB,KAAA,GAC9B,SAAS,kBAAkB,KAAK;CAEjC,IAAI,KAAK,UAAU,SAAS,UAAU,KAAK;CAC3C,OAAO;AACR;AAEA,SAAgB,wBAAwB,OAEZ;CAC3B,OAAO;EACN,eAAe;EACf,GAAI,MAAM,eAAe,EAAE,eAAe,MAAM,aAAa,IAAI,CAAC;CACnE;AACD;;;;;;;;;;;;AAaA,SAAgB,wBAAwB,OAAsC;CAC7E,MAAM,OAAO,IAAI,SAAS;CAC1B,KAAK,IACJ,OACA,IAAI,KAAK,CAAC,MAAM,MAAkB,GAAG,EAAE,MAAM,kBAAkB,CAAC,GAChE,YACD;CACA,KAAK,IAAI,WAAW,MAAM,OAAO;CACjC,IAAI,OAAO,KAAK,MAAM,WAAW,CAAC,CAAC,SAAS,GAC3C,KAAK,IAAI,eAAe,KAAK,UAAU,MAAM,WAAW,CAAC;CAE1D,OAAO;AACR;;;;;;;;;;;AAYA,eAAsB,aAAa,KAAiC;CACnE,MAAM,OAAO,MAAM,IAAI,KAAK;CAC5B,IAAI,KAAK,KAAK,MAAM,IAAI,OAAO,CAAC;CAChC,IAAI;EACH,OAAO,KAAK,MAAM,IAAI;CACvB,QAAQ;EACP,OAAO,EAAE,SAAS,KAAK,KAAK,EAAE;CAC/B;AACD;AAEA,SAAS,kBACR,SACsB;CACtB,MAAM,WAAW,QAAQ;CACzB,MAAM,WAAgC;EACrC,IAAI,QAAQ;EACZ,MAAM,QAAQ;EACd,UAAU,QAAQ;EAClB,WAAW,QAAQ;CACpB;CACA,IAAI,QAAQ,QAAQ,SAAS,QAAQ,QAAQ;CAC7C,IAAI,UAAU;EACb,MAAM,UAAU,0BAA0B,QAAQ;EAClD,IAAI,SAAS,SAAS,0BAA0B;CACjD;CACA,OAAO;AACR;AAEA,SAAS,iBAAiB,QAAoC;CAC7D,MAAM,WAA+B;EACpC,IAAI,OAAO;EACX,MAAM,OAAO;EACb,WAAW,OAAO;EAClB,WAAW,OAAO,cAAc;CACjC;CACA,IAAI,OAAO,WAAW,SAAS,WAAW,OAAO;CACjD,IAAI,OAAO,YAAY,SAAS,YAAY,OAAO;CACnD,OAAO;AACR;AAEA,SAAS,mBAAmB,UAA0C;CACrE,OAAO;EACN,IAAI,SAAS;EACb,UAAU,SAAS;EACnB,MAAM,SAAS,SAAS,cAAc,cAAc;EACpD,uBACC,SAAS;EACV,uBACC,SAAS;EACV,gBAAgB,qBAAqB,SAAS,uBAAuB;CACtE;AACD;AAEA,SAAS,eAAe,MAA8B;CACrD,OAAO;EACN,MAAM,KAAK;EACX,UAAU,KAAK;EACf,WAAW,KAAK,aAAa;CAC9B;AACD;AAEA,SAAS,mBAAmB,UAA0C;CACrE,OAAO;EACN,MAAM,SAAS;EACf,UAAU,SAAS;EACnB,WAAW,SAAS;CACrB;AACD;AAEA,SAAS,0BACR,UAC0B;CAC1B,MAAM,MAA+B,CAAC;CACtC,IAAI,SAAS,0BAA0B,KAAA,GACtC,IAAI,2BAA2B,SAAS;CACzC,IAAI,SAAS,0BAA0B,KAAA,GACtC,IAAI,2BAA2B,SAAS;CACzC,IAAI,SAAS,mBAAmB,KAAA,GAAW;EAC1C,MAAM,SAAS,oBAAoB,SAAS,cAAc;EAC1D,IAAI,WAAW,QACd,MAAM,IAAI,cACT,UAAU,eACV,2BAA2B,OAAO,OACnC;EAED,IAAI,0BAA0B,OAAO;CACtC;CACA,OAAO;AACR;AAEA,SAAS,iCAAiC,UAIxC;CACD,MAAM,MAIF,CAAC;CACL,IAAI,SAAS,0BAA0B,KAAA,GACtC,IAAI,2BAA2B,SAAS;CACzC,IAAI,SAAS,0BAA0B,KAAA,GACtC,IAAI,2BAA2B,SAAS;CACzC,IAAI,SAAS,mBAAmB,KAAA,GAAW;EAC1C,MAAM,SAAS,oBAAoB,SAAS,cAAc;EAC1D,IAAI,WAAW,QACd,MAAM,IAAI,cACT,UAAU,eACV,2BAA2B,OAAO,OACnC;EAED,IAAI,0BAA0B,OAAO;CACtC;CACA,OAAO;AACR;AAEA,SAAS,0BACR,UAC8B;CAC9B,MAAM,MAAuB,CAAC;CAC9B,IAAI,SAAS,6BAA6B,KAAA,GACzC,IAAI,wBACH,SAAS;CACX,IAAI,SAAS,6BAA6B,KAAA,GACzC,IAAI,wBACH,SAAS;CACX,IAAI,SAAS,4BAA4B,KAAA,GACxC,IAAI,iBAAiB,qBACpB,SAAS,uBACV;CACD,OAAO,OAAO,KAAK,GAAG,CAAC,CAAC,SAAS,IAAI,MAAM,KAAA;AAC5C"}
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"],"sources":["../../src/lib/neon-api-real.ts"],"sourcesContent":["import type {\n\tDataApiSettings as ApiDataApiSettings,\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\tgetConnectionUri as rawGetConnectionUri,\n\tgetNeonAuth as rawGetNeonAuth,\n\tgetProject as rawGetProject,\n\tgetProjectBranchDataApi as rawGetProjectBranchDataApi,\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\tCreateBranchInput,\n\tCreateBucketInput,\n\tCreateCredentialInput,\n\tCreateProjectInput,\n\tDeployFunctionInput,\n\tEnableDataApiInput,\n\tGetConnectionUriInput,\n\tNeonApi,\n\tNeonAuthSnapshot,\n\tNeonBranchSnapshot,\n\tNeonBranchStorageSnapshot,\n\tNeonBucketSnapshot,\n\tNeonCredentialMeta,\n\tNeonCredentialSecret,\n\tNeonDataApiSnapshot,\n\tNeonDatabaseSnapshot,\n\tNeonEndpointSnapshot,\n\tNeonFunctionDeploymentSnapshot,\n\tNeonFunctionSnapshot,\n\tNeonProjectSnapshot,\n\tNeonRoleSnapshot,\n\tUpdateBranchInput,\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\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\tactive_deployment: functionDeploymentSchema.optional(),\n});\nconst functionsListResponseSchema = z.object({\n\tfunctions: z.array(neonFunctionSchema),\n});\nconst functionDeploymentResponseSchema = z.object({\n\tdeployment: functionDeploymentSchema,\n});\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});\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\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\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}\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 getJson(path: string): Promise<unknown> {\n\t\treturn this.request(\"GET\", path);\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\" | \"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\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\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 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 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\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\n/**\n * Per-status guidance for a Preview feature that came back \"unavailable\". A preview can be\n * gated several different ways and the HTTP status is the best signal for which, so we tailor\n * the next step instead of emitting one catch-all — valuable while these features are in\n * preview and rolling out region by region:\n *\n * - 404 / 501 — the route isn't deployed for this project's region (or the account isn't in\n * the private preview): create a project in a region where the preview is enabled, and\n * confirm your account has preview access.\n * - 503 — the route exists but is refusing right now: either the preview is still coming up,\n * or Neon is having a transient incident. Retry; if it persists it's likely an incident.\n * - anything else — generic \"not enabled for your account/region; request access\".\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 previewUnavailableHint(status: number | undefined): string {\n\tswitch (status) {\n\t\tcase 404:\n\t\tcase 501:\n\t\t\treturn (\n\t\t\t\t\"This usually means the preview isn't available in your project's region yet, or \" +\n\t\t\t\t\"your Neon account isn't in the private preview: create a project in a region where \" +\n\t\t\t\t\"the preview is enabled, and make sure your account has access to the preview.\"\n\t\t\t);\n\t\tcase 503:\n\t\t\treturn (\n\t\t\t\t\"The endpoint is reachable but refused the request — the preview may still be \" +\n\t\t\t\t\"coming up, or Neon may be having a transient incident. Retry shortly; if it keeps \" +\n\t\t\t\t\"failing, check https://neonstatus.com and report it to Neon support.\"\n\t\t\t);\n\t\tdefault:\n\t\t\treturn (\n\t\t\t\t\"This usually means the preview isn't enabled for your Neon account or the project's \" +\n\t\t\t\t\"region. Request access to the preview, or use a project in a region where it's available.\"\n\t\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 (valuable\n * signal while the feature is in preview), gives status-specific guidance (see\n * {@link previewUnavailableHint}), and offers removing the feature from the policy as an\n * escape hatch. `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} is a Preview feature and isn't available for this Neon project${apiContext}.`,\n\t\t\tpreviewUnavailableHint(status),\n\t\t\t\"If you don't need it, remove the corresponding feature from the `preview` block of 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\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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@neon/config",
3
- "version": "0.9.1",
3
+ "version": "0.9.3",
4
4
  "description": "Config-as-Code for the Neon Platform. Define a `neon.ts` policy and inspect/diff/deploy it against the Neon API as plain TypeScript functions.",
5
5
  "keywords": [
6
6
  "neon",
@@ -41,16 +41,16 @@
41
41
  ],
42
42
  "devDependencies": {
43
43
  "@types/node": "^20.19.0",
44
- "@vitest/coverage-v8": "3.0.9",
44
+ "@vitest/coverage-v8": "^3.0.9",
45
45
  "console-fail-test": "0.5.0",
46
46
  "tsdown": "^0.14.1",
47
- "typescript": "^5.8.2",
47
+ "typescript": "^5.9.0",
48
48
  "vitest": "^3.0.9"
49
49
  },
50
50
  "dependencies": {
51
51
  "jiti": "^2.7.0",
52
52
  "zod": "^4.4.3",
53
- "@neon/sdk": "1.0.0"
53
+ "@neon/sdk": "1.1.1"
54
54
  },
55
55
  "engines": {
56
56
  "node": ">=20.19.0"