@neondatabase/config 0.2.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -33,6 +33,7 @@ declare const ErrorCode: {
33
33
  readonly MissingApiKey: "PLATFORM_MISSING_API_KEY";
34
34
  readonly AmbiguousBranchAuth: "PLATFORM_AMBIGUOUS_BRANCH_AUTH";
35
35
  readonly BranchNotFound: "PLATFORM_BRANCH_NOT_FOUND";
36
+ readonly FeatureUnavailable: "PLATFORM_FEATURE_UNAVAILABLE";
36
37
  readonly MissingParentBranch: "PLATFORM_MISSING_PARENT_BRANCH";
37
38
  readonly Unauthorized: "PLATFORM_UNAUTHORIZED";
38
39
  readonly Forbidden: "PLATFORM_FORBIDDEN";
@@ -1 +1 @@
1
- {"version":3,"file":"errors.d.ts","names":[],"sources":["../../src/lib/errors.ts"],"mappings":";;;;;;AAuBA;AAqBA;;;;AAAiE;AAYjE;;;;;;AAAwC;AAqBxC;AAUA;AAoBA;AAeA;;;AAIiC,cAvGpB,SAuGoB,EAAA;WAJM,aAAA,EAAA,yBAAA;EAAa,SAAA,cAAA,EAAA,2BAAA;EAqDvC,SAAA,cAAiB,EAAA,0BAAqB;EA8BtC,SAAA,YAAgB,EAAA,wBAAqB;;;;;;;;;;;;;;;;;KAjKtC,SAAA,WAAoB,wBAAwB;;;;;;;;;cAY3C,aAAA,SAAsB,KAAA;;;oBAGhB,SAAS;;;cAKa;;;;;;;;iBAazB,eAAA,CAAA;;;;;;;cAUH,qBAAA,SAA8B,aAAa;;;;;;;;;;;;cAoB3C,mBAAA,SAA4B,aAAa;;;;;;;;;;;cAezC,iBAAA,SAA0B,aAAA;;+BAET;kCAEG;;;;;;;;;cAiDpB,gBAAA,SAAyB,aAAa;;;;;;;;;cA8BtC,eAAA,SAAwB,aAAa"}
1
+ {"version":3,"file":"errors.d.ts","names":[],"sources":["../../src/lib/errors.ts"],"mappings":";;;;;;AAuBA;AAsBA;;;;AAAiE;AAYjE;;;;;;AAAwC;AAqBxC;AAUA;AAoBA;AAeA;;;AAIiC,cAxGpB,SAwGoB,EAAA;WAJM,aAAA,EAAA,yBAAA;EAAa,SAAA,cAAA,EAAA,2BAAA;EAqDvC,SAAA,cAAiB,EAAA,0BAAqB;EA8BtC,SAAA,YAAgB,EAAA,wBAAqB;;;;;;;;;;;;;;;;;;KAjKtC,SAAA,WAAoB,wBAAwB;;;;;;;;;cAY3C,aAAA,SAAsB,KAAA;;;oBAGhB,SAAS;;;cAKa;;;;;;;;iBAazB,eAAA,CAAA;;;;;;;cAUH,qBAAA,SAA8B,aAAa;;;;;;;;;;;;cAoB3C,mBAAA,SAA4B,aAAa;;;;;;;;;;;cAezC,iBAAA,SAA0B,aAAA;;+BAET;kCAEG;;;;;;;;;cAiDpB,gBAAA,SAAyB,aAAa;;;;;;;;;cA8BtC,eAAA,SAAwB,aAAa"}
@@ -30,6 +30,7 @@ const ErrorCode = {
30
30
  MissingApiKey: "PLATFORM_MISSING_API_KEY",
31
31
  AmbiguousBranchAuth: "PLATFORM_AMBIGUOUS_BRANCH_AUTH",
32
32
  BranchNotFound: "PLATFORM_BRANCH_NOT_FOUND",
33
+ FeatureUnavailable: "PLATFORM_FEATURE_UNAVAILABLE",
33
34
  MissingParentBranch: "PLATFORM_MISSING_PARENT_BRANCH",
34
35
  Unauthorized: "PLATFORM_UNAUTHORIZED",
35
36
  Forbidden: "PLATFORM_FORBIDDEN",
@@ -1 +1 @@
1
- {"version":3,"file":"errors.js","names":[],"sources":["../../src/lib/errors.ts"],"sourcesContent":["import type { ConflictReport } from \"./types.js\";\n\n/**\n * Every code a {@link PlatformError} can carry. Stable identifiers — consumers can rely on\n * these for `instanceof PlatformError && err.code === ErrorCode.…` style checks instead of\n * matching on free-text messages.\n *\n * Grouped by source:\n * - `PLATFORM_INVALID_CONFIG` — `defineConfig` / `configSchema` rejected the input.\n * - `PLATFORM_MISSING_CONTEXT` — no project / branch context could be resolved.\n * - `PLATFORM_PUSH_CONFLICT` — local config conflicts with remote and the caller did not\n * opt in to apply.\n * - `PLATFORM_CONFIG_LOAD_FAILED` — `neon.ts` could not be found or evaluated.\n * - `PLATFORM_MISSING_API_KEY` — no `NEON_API_KEY` and no explicit `apiKey` was provided.\n * - `PLATFORM_MISSING_PARENT_BRANCH` — push tried to create a child of a non-existent\n * branch.\n * - `PLATFORM_UNAUTHORIZED` / `PLATFORM_FORBIDDEN` / `PLATFORM_NOT_FOUND` /\n * `PLATFORM_CONFLICT` / `PLATFORM_RATE_LIMITED` / `PLATFORM_LOCKED` /\n * `PLATFORM_SERVER_ERROR` — wrappings of Neon HTTP failures.\n * - `PLATFORM_NETWORK_ERROR` — transport-level failure (no HTTP response at all).\n * - `PLATFORM_INTERNAL_ERROR` — invariant violations. Should never happen in production;\n * if you see one, please open an issue.\n */\nexport const ErrorCode = {\n\tInvalidConfig: \"PLATFORM_INVALID_CONFIG\",\n\tEnvNotInjected: \"PLATFORM_ENV_NOT_INJECTED\",\n\tMissingContext: \"PLATFORM_MISSING_CONTEXT\",\n\tPushConflict: \"PLATFORM_PUSH_CONFLICT\",\n\tPushAborted: \"PLATFORM_PUSH_ABORTED\",\n\tConfigLoadFailed: \"PLATFORM_CONFIG_LOAD_FAILED\",\n\tMissingApiKey: \"PLATFORM_MISSING_API_KEY\",\n\tAmbiguousBranchAuth: \"PLATFORM_AMBIGUOUS_BRANCH_AUTH\",\n\tBranchNotFound: \"PLATFORM_BRANCH_NOT_FOUND\",\n\tMissingParentBranch: \"PLATFORM_MISSING_PARENT_BRANCH\",\n\tUnauthorized: \"PLATFORM_UNAUTHORIZED\",\n\tForbidden: \"PLATFORM_FORBIDDEN\",\n\tNotFound: \"PLATFORM_NOT_FOUND\",\n\tConflict: \"PLATFORM_CONFLICT\",\n\tRateLimited: \"PLATFORM_RATE_LIMITED\",\n\tLocked: \"PLATFORM_LOCKED\",\n\tServerError: \"PLATFORM_SERVER_ERROR\",\n\tNetworkError: \"PLATFORM_NETWORK_ERROR\",\n\tInternalError: \"PLATFORM_INTERNAL_ERROR\",\n} as const;\nexport type ErrorCode = (typeof ErrorCode)[keyof typeof ErrorCode];\n\nconst ISSUE_URL = \"https://github.com/neondatabase/neon-pkgs/issues/new\";\n\n/**\n * Base class for all errors thrown by `@neondatabase/config`. Always extend this so callers\n * can catch every package-thrown error with a single `instanceof` check.\n *\n * Optional `details` carries structured context that the CLI prints under `--debug` and\n * that programmatic consumers can read (e.g. `details.status` for HTTP wrappings,\n * `details.requestId` for Neon API failures).\n */\nexport class PlatformError extends Error {\n\toverride readonly name: string = \"PlatformError\";\n\treadonly code: string;\n\treadonly details: Readonly<Record<string, unknown>>;\n\n\tconstructor(\n\t\tcode: string,\n\t\tmessage: string,\n\t\toptions?: { cause?: unknown; details?: Record<string, unknown> },\n\t) {\n\t\tsuper(message, options);\n\t\tthis.code = code;\n\t\tthis.details = Object.freeze({ ...(options?.details ?? {}) });\n\t}\n}\n\n/**\n * Append a \"report-a-bug\" footer to an error message. Used only on truly unreachable\n * internal errors — never on user-facing validation / configuration errors where the user\n * is supposed to fix something on their end.\n */\nexport function bugReportFooter(): string {\n\treturn `\\nThis indicates a bug in @neondatabase/config. Please file an issue: ${ISSUE_URL}`;\n}\n\n/**\n * Thrown by {@link defineConfig} when the user-provided configuration object is invalid.\n *\n * The class collects every validation failure rather than throwing on the first one so that\n * users get a complete picture of what is wrong with their `neon.ts`.\n */\nexport class ConfigValidationError extends PlatformError {\n\toverride readonly name = \"ConfigValidationError\";\n\treadonly issues: readonly string[];\n\n\tconstructor(issues: readonly string[]) {\n\t\tsuper(\n\t\t\t\"PLATFORM_INVALID_CONFIG\",\n\t\t\t`Invalid Neon platform config:\\n - ${issues.join(\"\\n - \")}`,\n\t\t);\n\t\tthis.issues = issues;\n\t}\n}\n\n/**\n * Thrown when the package cannot resolve which Neon project to operate on.\n *\n * Per the package's read-only-filesystem contract, we never create a `.neon` context file;\n * callers must either pass `projectId`/`orgId` explicitly or rely on an existing context file\n * (`.neon/project.json` or neonctl's `.neon`).\n */\nexport class MissingContextError extends PlatformError {\n\toverride readonly name = \"MissingContextError\";\n\n\tconstructor(message: string) {\n\t\tsuper(\"PLATFORM_MISSING_CONTEXT\", message);\n\t}\n}\n\n/**\n * Thrown by {@link pushConfig} when it detects differences between the local config and\n * the remote project that the caller hasn't opted in to apply.\n *\n * The message lists every conflict with both the current and desired value plus a\n * per-conflict hint. Mutable branch drift is applied by passing `updateExisting: true`.\n */\nexport class PushConflictError extends PlatformError {\n\toverride readonly name = \"PushConflictError\";\n\treadonly conflicts: readonly ConflictReport[];\n\n\tconstructor(conflicts: readonly ConflictReport[]) {\n\t\tconst lines: string[] = [\n\t\t\t\"pushConfig refused to apply: local config conflicts with remote state.\",\n\t\t\t\"\",\n\t\t];\n\t\tfor (const c of conflicts) {\n\t\t\tlines.push(\n\t\t\t\t` - [${c.kind}:${c.identifier}] ${c.field}: ${c.reason}`,\n\t\t\t\t` current : ${formatValue(c.current)}`,\n\t\t\t\t` desired : ${formatValue(c.desired)}`,\n\t\t\t\t` fix : ${suggestFix(c)}`,\n\t\t\t);\n\t\t}\n\t\tconst hasMutable = conflicts.some((c) => !isImmutableConflict(c));\n\t\tlines.push(\"\");\n\t\tif (hasMutable) {\n\t\t\tlines.push(\n\t\t\t\t\"For mutable conflicts, pass `updateExisting: true` (SDK) / `--update-existing` (CLI) to apply.\",\n\t\t\t);\n\t\t}\n\n\t\tsuper(\"PLATFORM_PUSH_CONFLICT\", lines.join(\"\\n\"), {\n\t\t\tdetails: { conflicts: conflicts.map((c) => ({ ...c })) },\n\t\t});\n\t\tthis.conflicts = conflicts;\n\t}\n}\n\nfunction isImmutableConflict(_c: ConflictReport): boolean {\n\treturn false;\n}\n\nfunction suggestFix(c: ConflictReport): string {\n\tif (isImmutableConflict(c)) {\n\t\treturn \"immutable on Neon — recreate the project, or change your `neon.ts` to match the remote.\";\n\t}\n\tif (c.kind === \"branch\" && c.field === \"parent\") {\n\t\treturn \"create the parent branch on Neon first, or change the `parent` reference to an existing branch.\";\n\t}\n\treturn \"pass `updateExisting: true` (SDK) / `--update-existing` (CLI) to apply.\";\n}\n\n/**\n * Thrown by {@link pushConfig} when the caller-supplied `confirm` callback declines a\n * push that requires confirmation (protected branch and/or mutable drift overriding\n * existing remote settings).\n *\n * The CLI maps this to a non-zero exit so users see \"aborted\" rather than a stack trace.\n */\nexport class PushAbortedError extends PlatformError {\n\toverride readonly name = \"PushAbortedError\";\n\treadonly branchName: string;\n\treadonly reasons: readonly (\"protected-branch\" | \"override-updates\")[];\n\n\tconstructor(\n\t\tbranchName: string,\n\t\treasons: readonly (\"protected-branch\" | \"override-updates\")[],\n\t) {\n\t\tsuper(\n\t\t\t\"PLATFORM_PUSH_ABORTED\",\n\t\t\t[\n\t\t\t\t`Aborted push to branch ${JSON.stringify(branchName)}.`,\n\t\t\t\treasons.length > 0\n\t\t\t\t\t? `Reason${reasons.length === 1 ? \"\" : \"s\"}: ${reasons.join(\", \")}.`\n\t\t\t\t\t: undefined,\n\t\t\t\t\"Re-run with `--update-existing` (override existing settings) or `--allow-protected-branch` (push to a protected branch) to skip the prompt.\",\n\t\t\t]\n\t\t\t\t.filter(Boolean)\n\t\t\t\t.join(\" \"),\n\t\t\t{ details: { branchName, reasons: [...reasons] } },\n\t\t);\n\t\tthis.branchName = branchName;\n\t\tthis.reasons = reasons;\n\t}\n}\n\n/**\n * Thrown when the SDK fails to find or load a `neon.ts` config file.\n */\nexport class ConfigLoadError extends PlatformError {\n\toverride readonly name = \"ConfigLoadError\";\n\n\tconstructor(message: string, options?: { cause?: unknown }) {\n\t\tsuper(\"PLATFORM_CONFIG_LOAD_FAILED\", message, options);\n\t}\n}\n\nfunction formatValue(value: unknown): string {\n\tif (value === undefined) return \"<unset>\";\n\tif (typeof value === \"string\") return JSON.stringify(value);\n\tif (typeof value === \"object\" && value !== null)\n\t\treturn JSON.stringify(value);\n\treturn String(value);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAuBA,MAAa,YAAY;CACxB,eAAe;CACf,gBAAgB;CAChB,gBAAgB;CAChB,cAAc;CACd,aAAa;CACb,kBAAkB;CAClB,eAAe;CACf,qBAAqB;CACrB,gBAAgB;CAChB,qBAAqB;CACrB,cAAc;CACd,WAAW;CACX,UAAU;CACV,UAAU;CACV,aAAa;CACb,QAAQ;CACR,aAAa;CACb,cAAc;CACd,eAAe;AAChB;AAGA,MAAM,YAAY;;;;;;;;;AAUlB,IAAa,gBAAb,cAAmC,MAAM;CACxC,OAAiC;CACjC;CACA;CAEA,YACC,MACA,SACA,SACC;EACD,MAAM,SAAS,OAAO;EACtB,KAAK,OAAO;EACZ,KAAK,UAAU,OAAO,OAAO,EAAE,GAAI,SAAS,WAAW,CAAC,EAAG,CAAC;CAC7D;AACD;;;;;;AAOA,SAAgB,kBAA0B;CACzC,OAAO,yEAAyE;AACjF;;;;;;;AAQA,IAAa,wBAAb,cAA2C,cAAc;CACxD,OAAyB;CACzB;CAEA,YAAY,QAA2B;EACtC,MACC,2BACA,sCAAsC,OAAO,KAAK,QAAQ,GAC3D;EACA,KAAK,SAAS;CACf;AACD;;;;;;;;AASA,IAAa,sBAAb,cAAyC,cAAc;CACtD,OAAyB;CAEzB,YAAY,SAAiB;EAC5B,MAAM,4BAA4B,OAAO;CAC1C;AACD;;;;;;;;AASA,IAAa,oBAAb,cAAuC,cAAc;CACpD,OAAyB;CACzB;CAEA,YAAY,WAAsC;EACjD,MAAM,QAAkB,CACvB,0EACA,EACD;EACA,KAAK,MAAM,KAAK,WACf,MAAM,KACL,QAAQ,EAAE,KAAK,GAAG,EAAE,WAAW,IAAI,EAAE,MAAM,IAAI,EAAE,UACjD,mBAAmB,YAAY,EAAE,OAAO,KACxC,mBAAmB,YAAY,EAAE,OAAO,KACxC,mBAAmB,WAAW,CAAC,GAChC;EAED,MAAM,aAAa,UAAU,MAAM,MAAM,CAAC,oBAAoB,CAAC,CAAC;EAChE,MAAM,KAAK,EAAE;EACb,IAAI,YACH,MAAM,KACL,gGACD;EAGD,MAAM,0BAA0B,MAAM,KAAK,IAAI,GAAG,EACjD,SAAS,EAAE,WAAW,UAAU,KAAK,OAAO,EAAE,GAAG,EAAE,EAAE,EAAE,EACxD,CAAC;EACD,KAAK,YAAY;CAClB;AACD;AAEA,SAAS,oBAAoB,IAA6B;CACzD,OAAO;AACR;AAEA,SAAS,WAAW,GAA2B;CAC9C,IAAI,oBAAoB,CAAC,GACxB,OAAO;CAER,IAAI,EAAE,SAAS,YAAY,EAAE,UAAU,UACtC,OAAO;CAER,OAAO;AACR;;;;;;;;AASA,IAAa,mBAAb,cAAsC,cAAc;CACnD,OAAyB;CACzB;CACA;CAEA,YACC,YACA,SACC;EACD,MACC,yBACA;GACC,0BAA0B,KAAK,UAAU,UAAU,EAAE;GACrD,QAAQ,SAAS,IACd,SAAS,QAAQ,WAAW,IAAI,KAAK,IAAI,IAAI,QAAQ,KAAK,IAAI,EAAE,KAChE,KAAA;GACH;EACD,EACE,OAAO,OAAO,EACd,KAAK,GAAG,GACV,EAAE,SAAS;GAAE;GAAY,SAAS,CAAC,GAAG,OAAO;EAAE,EAAE,CAClD;EACA,KAAK,aAAa;EAClB,KAAK,UAAU;CAChB;AACD;;;;AAKA,IAAa,kBAAb,cAAqC,cAAc;CAClD,OAAyB;CAEzB,YAAY,SAAiB,SAA+B;EAC3D,MAAM,+BAA+B,SAAS,OAAO;CACtD;AACD;AAEA,SAAS,YAAY,OAAwB;CAC5C,IAAI,UAAU,KAAA,GAAW,OAAO;CAChC,IAAI,OAAO,UAAU,UAAU,OAAO,KAAK,UAAU,KAAK;CAC1D,IAAI,OAAO,UAAU,YAAY,UAAU,MAC1C,OAAO,KAAK,UAAU,KAAK;CAC5B,OAAO,OAAO,KAAK;AACpB"}
1
+ {"version":3,"file":"errors.js","names":[],"sources":["../../src/lib/errors.ts"],"sourcesContent":["import type { ConflictReport } from \"./types.js\";\n\n/**\n * Every code a {@link PlatformError} can carry. Stable identifiers — consumers can rely on\n * these for `instanceof PlatformError && err.code === ErrorCode.…` style checks instead of\n * matching on free-text messages.\n *\n * Grouped by source:\n * - `PLATFORM_INVALID_CONFIG` — `defineConfig` / `configSchema` rejected the input.\n * - `PLATFORM_MISSING_CONTEXT` — no project / branch context could be resolved.\n * - `PLATFORM_PUSH_CONFLICT` — local config conflicts with remote and the caller did not\n * opt in to apply.\n * - `PLATFORM_CONFIG_LOAD_FAILED` — `neon.ts` could not be found or evaluated.\n * - `PLATFORM_MISSING_API_KEY` — no `NEON_API_KEY` and no explicit `apiKey` was provided.\n * - `PLATFORM_MISSING_PARENT_BRANCH` — push tried to create a child of a non-existent\n * branch.\n * - `PLATFORM_UNAUTHORIZED` / `PLATFORM_FORBIDDEN` / `PLATFORM_NOT_FOUND` /\n * `PLATFORM_CONFLICT` / `PLATFORM_RATE_LIMITED` / `PLATFORM_LOCKED` /\n * `PLATFORM_SERVER_ERROR` — wrappings of Neon HTTP failures.\n * - `PLATFORM_NETWORK_ERROR` — transport-level failure (no HTTP response at all).\n * - `PLATFORM_INTERNAL_ERROR` — invariant violations. Should never happen in production;\n * if you see one, please open an issue.\n */\nexport const ErrorCode = {\n\tInvalidConfig: \"PLATFORM_INVALID_CONFIG\",\n\tEnvNotInjected: \"PLATFORM_ENV_NOT_INJECTED\",\n\tMissingContext: \"PLATFORM_MISSING_CONTEXT\",\n\tPushConflict: \"PLATFORM_PUSH_CONFLICT\",\n\tPushAborted: \"PLATFORM_PUSH_ABORTED\",\n\tConfigLoadFailed: \"PLATFORM_CONFIG_LOAD_FAILED\",\n\tMissingApiKey: \"PLATFORM_MISSING_API_KEY\",\n\tAmbiguousBranchAuth: \"PLATFORM_AMBIGUOUS_BRANCH_AUTH\",\n\tBranchNotFound: \"PLATFORM_BRANCH_NOT_FOUND\",\n\tFeatureUnavailable: \"PLATFORM_FEATURE_UNAVAILABLE\",\n\tMissingParentBranch: \"PLATFORM_MISSING_PARENT_BRANCH\",\n\tUnauthorized: \"PLATFORM_UNAUTHORIZED\",\n\tForbidden: \"PLATFORM_FORBIDDEN\",\n\tNotFound: \"PLATFORM_NOT_FOUND\",\n\tConflict: \"PLATFORM_CONFLICT\",\n\tRateLimited: \"PLATFORM_RATE_LIMITED\",\n\tLocked: \"PLATFORM_LOCKED\",\n\tServerError: \"PLATFORM_SERVER_ERROR\",\n\tNetworkError: \"PLATFORM_NETWORK_ERROR\",\n\tInternalError: \"PLATFORM_INTERNAL_ERROR\",\n} as const;\nexport type ErrorCode = (typeof ErrorCode)[keyof typeof ErrorCode];\n\nconst ISSUE_URL = \"https://github.com/neondatabase/neon-pkgs/issues/new\";\n\n/**\n * Base class for all errors thrown by `@neondatabase/config`. Always extend this so callers\n * can catch every package-thrown error with a single `instanceof` check.\n *\n * Optional `details` carries structured context that the CLI prints under `--debug` and\n * that programmatic consumers can read (e.g. `details.status` for HTTP wrappings,\n * `details.requestId` for Neon API failures).\n */\nexport class PlatformError extends Error {\n\toverride readonly name: string = \"PlatformError\";\n\treadonly code: string;\n\treadonly details: Readonly<Record<string, unknown>>;\n\n\tconstructor(\n\t\tcode: string,\n\t\tmessage: string,\n\t\toptions?: { cause?: unknown; details?: Record<string, unknown> },\n\t) {\n\t\tsuper(message, options);\n\t\tthis.code = code;\n\t\tthis.details = Object.freeze({ ...(options?.details ?? {}) });\n\t}\n}\n\n/**\n * Append a \"report-a-bug\" footer to an error message. Used only on truly unreachable\n * internal errors — never on user-facing validation / configuration errors where the user\n * is supposed to fix something on their end.\n */\nexport function bugReportFooter(): string {\n\treturn `\\nThis indicates a bug in @neondatabase/config. Please file an issue: ${ISSUE_URL}`;\n}\n\n/**\n * Thrown by {@link defineConfig} when the user-provided configuration object is invalid.\n *\n * The class collects every validation failure rather than throwing on the first one so that\n * users get a complete picture of what is wrong with their `neon.ts`.\n */\nexport class ConfigValidationError extends PlatformError {\n\toverride readonly name = \"ConfigValidationError\";\n\treadonly issues: readonly string[];\n\n\tconstructor(issues: readonly string[]) {\n\t\tsuper(\n\t\t\t\"PLATFORM_INVALID_CONFIG\",\n\t\t\t`Invalid Neon platform config:\\n - ${issues.join(\"\\n - \")}`,\n\t\t);\n\t\tthis.issues = issues;\n\t}\n}\n\n/**\n * Thrown when the package cannot resolve which Neon project to operate on.\n *\n * Per the package's read-only-filesystem contract, we never create a `.neon` context file;\n * callers must either pass `projectId`/`orgId` explicitly or rely on an existing context file\n * (`.neon/project.json` or neonctl's `.neon`).\n */\nexport class MissingContextError extends PlatformError {\n\toverride readonly name = \"MissingContextError\";\n\n\tconstructor(message: string) {\n\t\tsuper(\"PLATFORM_MISSING_CONTEXT\", message);\n\t}\n}\n\n/**\n * Thrown by {@link pushConfig} when it detects differences between the local config and\n * the remote project that the caller hasn't opted in to apply.\n *\n * The message lists every conflict with both the current and desired value plus a\n * per-conflict hint. Mutable branch drift is applied by passing `updateExisting: true`.\n */\nexport class PushConflictError extends PlatformError {\n\toverride readonly name = \"PushConflictError\";\n\treadonly conflicts: readonly ConflictReport[];\n\n\tconstructor(conflicts: readonly ConflictReport[]) {\n\t\tconst lines: string[] = [\n\t\t\t\"pushConfig refused to apply: local config conflicts with remote state.\",\n\t\t\t\"\",\n\t\t];\n\t\tfor (const c of conflicts) {\n\t\t\tlines.push(\n\t\t\t\t` - [${c.kind}:${c.identifier}] ${c.field}: ${c.reason}`,\n\t\t\t\t` current : ${formatValue(c.current)}`,\n\t\t\t\t` desired : ${formatValue(c.desired)}`,\n\t\t\t\t` fix : ${suggestFix(c)}`,\n\t\t\t);\n\t\t}\n\t\tconst hasMutable = conflicts.some((c) => !isImmutableConflict(c));\n\t\tlines.push(\"\");\n\t\tif (hasMutable) {\n\t\t\tlines.push(\n\t\t\t\t\"For mutable conflicts, pass `updateExisting: true` (SDK) / `--update-existing` (CLI) to apply.\",\n\t\t\t);\n\t\t}\n\n\t\tsuper(\"PLATFORM_PUSH_CONFLICT\", lines.join(\"\\n\"), {\n\t\t\tdetails: { conflicts: conflicts.map((c) => ({ ...c })) },\n\t\t});\n\t\tthis.conflicts = conflicts;\n\t}\n}\n\nfunction isImmutableConflict(_c: ConflictReport): boolean {\n\treturn false;\n}\n\nfunction suggestFix(c: ConflictReport): string {\n\tif (isImmutableConflict(c)) {\n\t\treturn \"immutable on Neon — recreate the project, or change your `neon.ts` to match the remote.\";\n\t}\n\tif (c.kind === \"branch\" && c.field === \"parent\") {\n\t\treturn \"create the parent branch on Neon first, or change the `parent` reference to an existing branch.\";\n\t}\n\treturn \"pass `updateExisting: true` (SDK) / `--update-existing` (CLI) to apply.\";\n}\n\n/**\n * Thrown by {@link pushConfig} when the caller-supplied `confirm` callback declines a\n * push that requires confirmation (protected branch and/or mutable drift overriding\n * existing remote settings).\n *\n * The CLI maps this to a non-zero exit so users see \"aborted\" rather than a stack trace.\n */\nexport class PushAbortedError extends PlatformError {\n\toverride readonly name = \"PushAbortedError\";\n\treadonly branchName: string;\n\treadonly reasons: readonly (\"protected-branch\" | \"override-updates\")[];\n\n\tconstructor(\n\t\tbranchName: string,\n\t\treasons: readonly (\"protected-branch\" | \"override-updates\")[],\n\t) {\n\t\tsuper(\n\t\t\t\"PLATFORM_PUSH_ABORTED\",\n\t\t\t[\n\t\t\t\t`Aborted push to branch ${JSON.stringify(branchName)}.`,\n\t\t\t\treasons.length > 0\n\t\t\t\t\t? `Reason${reasons.length === 1 ? \"\" : \"s\"}: ${reasons.join(\", \")}.`\n\t\t\t\t\t: undefined,\n\t\t\t\t\"Re-run with `--update-existing` (override existing settings) or `--allow-protected-branch` (push to a protected branch) to skip the prompt.\",\n\t\t\t]\n\t\t\t\t.filter(Boolean)\n\t\t\t\t.join(\" \"),\n\t\t\t{ details: { branchName, reasons: [...reasons] } },\n\t\t);\n\t\tthis.branchName = branchName;\n\t\tthis.reasons = reasons;\n\t}\n}\n\n/**\n * Thrown when the SDK fails to find or load a `neon.ts` config file.\n */\nexport class ConfigLoadError extends PlatformError {\n\toverride readonly name = \"ConfigLoadError\";\n\n\tconstructor(message: string, options?: { cause?: unknown }) {\n\t\tsuper(\"PLATFORM_CONFIG_LOAD_FAILED\", message, options);\n\t}\n}\n\nfunction formatValue(value: unknown): string {\n\tif (value === undefined) return \"<unset>\";\n\tif (typeof value === \"string\") return JSON.stringify(value);\n\tif (typeof value === \"object\" && value !== null)\n\t\treturn JSON.stringify(value);\n\treturn String(value);\n}\n"],"mappings":"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"}
@@ -37,9 +37,38 @@ interface RetryConfig {
37
37
  * Exported only for tests; production callers go through the wrapped {@link NeonApi}.
38
38
  */
39
39
  declare function retryOnLocked<T>(fn: () => Promise<T>, config: RetryConfig): Promise<T>;
40
+ /**
41
+ * Whether an error from a Preview-feature read means the feature simply isn't available
42
+ * for this project/branch/region (as opposed to a real, transient failure). Neon signals
43
+ * this a few ways: a 404 "this route does not exist" (the route isn't deployed at all), or
44
+ * a 503/4xx whose message says the platform feature is "not available" / "not enabled".
45
+ *
46
+ * Callers do **not** swallow this into an empty result — touching a Preview feature that
47
+ * isn't available is surfaced as a {@link previewUnavailableError} so `plan` / `status` /
48
+ * `pull` (and `neon dev`) fail clearly instead of, say, planning to create resources the
49
+ * API will refuse to create.
50
+ */
51
+ declare function isPreviewFeatureUnavailable(err: unknown): boolean;
52
+ /**
53
+ * Convert a Preview-feature error into a clear {@link PlatformError} when the feature is
54
+ * unavailable for the project; otherwise pass the original error through unchanged so a
55
+ * genuine failure (auth, transient 5xx, …) keeps its specific code and message.
56
+ */
57
+ declare function previewUnavailableError(err: unknown, featureLabel: string): unknown;
40
58
  declare function createNeonAuthRestInput(input: {
41
59
  databaseName?: string;
42
60
  }): CreateNeonAuthRestInput;
61
+ /**
62
+ * Read a response body as JSON, tolerating non-JSON. Some Neon routes return a plain-text
63
+ * body (e.g. a 404 `"this route does not exist"` for a Preview feature not enabled in the
64
+ * project/region). Parsing that with `JSON.parse` used to throw a cryptic
65
+ * `SyntaxError: Unexpected token …`, which — because parsing happens before the `res.ok`
66
+ * check in {@link request} — masked the real HTTP status. We instead return the raw text
67
+ * wrapped as `{ message }` so the status-based error path in `request` / `wrapNeonError`
68
+ * runs and produces a proper {@link PlatformError} (e.g. `NotFound`), and a non-error body
69
+ * that simply isn't JSON degrades to text rather than crashing.
70
+ */
71
+ declare function readJsonBody(res: Response): Promise<unknown>;
43
72
  //#endregion
44
- export { createNeonAuthRestInput, createRealNeonApi, retryOnLocked };
73
+ export { createNeonAuthRestInput, createRealNeonApi, isPreviewFeatureUnavailable, previewUnavailableError, readJsonBody, retryOnLocked };
45
74
  //# sourceMappingURL=neon-api-real.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"neon-api-real.d.ts","names":[],"sources":["../../src/lib/neon-api-real.ts"],"mappings":";;;UAoFU,uBAAA;;EAAA,aAAA,CAAA,EAAA,MAAA;AAeV;AAyCC;AAeD;;;;AAES,iBA1DO,iBAAA,CA0DP,OAAA,EAAA;QACE,EAAA,MAAA;SAAR,CAAA,EAAA,MAAA;EAAO;AAwzBV;;;;;;;;;IAt2BI;UA8BM,WAAA;;;;;;;;;;;;iBAaY,2BACX,QAAQ,YACV,cACN,QAAQ;iBAwzBK,uBAAA;;IAEZ"}
1
+ {"version":3,"file":"neon-api-real.d.ts","names":[],"sources":["../../src/lib/neon-api-real.ts"],"mappings":";;;UAoFU,uBAAA;;EAAA,aAAA,CAAA,EAAA,MAAA;AAeV;AAyCC;AAeD;;;;AAES,iBA1DO,iBAAA,CA0DP,OAAA,EAAA;QACE,EAAA,MAAA;SAAR,CAAA,EAAA,MAAA;EAAO;AAq0BV;AAsBA;AAmCA;AAmBA;EAAkC,aAAA,CAAA,EAAA;IAAM,WAAA,CAAA,EAAA,MAAA;IAAW,cAAA,CAAA,EAAA,MAAA;IAAO,UAAA,CAAA,EAAA,MAAA;;IA/7BtD;UA8BM,WAAA;;;;;;;;;;;;iBAaY,2BACX,QAAQ,YACV,cACN,QAAQ;;;;;;;;;;;;iBAq0BK,2BAAA;;;;;;iBAsBA,uBAAA;iBAmCA,uBAAA;;IAEZ;;;;;;;;;;;iBAiBkB,YAAA,MAAkB,WAAW"}
@@ -340,10 +340,14 @@ var RealNeonApi = class {
340
340
  }
341
341
  }
342
342
  async listBranchBuckets(projectId, branchId) {
343
- return this.call(`listBranchBuckets(${projectId}/${branchId})`, async () => {
344
- const data = await this.getJson(branchPreviewPath(projectId, branchId, "buckets"));
345
- return bucketsListResponseSchema.parse(data).buckets.map(bucketToSnapshot);
346
- }, { projectId });
343
+ try {
344
+ return await this.call(`listBranchBuckets(${projectId}/${branchId})`, async () => {
345
+ const data = await this.getJson(branchPreviewPath(projectId, branchId, "buckets"));
346
+ return bucketsListResponseSchema.parse(data).buckets.map(bucketToSnapshot);
347
+ }, { projectId });
348
+ } catch (err) {
349
+ throw previewUnavailableError(err, "Object storage (buckets)");
350
+ }
347
351
  }
348
352
  async createBranchBucket(projectId, branchId, input) {
349
353
  return this.call(`createBranchBucket(${projectId}/${branchId}/${input.name})`, async () => {
@@ -366,10 +370,14 @@ var RealNeonApi = class {
366
370
  });
367
371
  }
368
372
  async listBranchFunctions(projectId, branchId) {
369
- return this.call(`listBranchFunctions(${projectId}/${branchId})`, async () => {
370
- const data = await this.getJson(branchPreviewPath(projectId, branchId, "functions"));
371
- return functionsListResponseSchema.parse(data).functions.map(functionToSnapshot);
372
- }, { projectId });
373
+ try {
374
+ return await this.call(`listBranchFunctions(${projectId}/${branchId})`, async () => {
375
+ const data = await this.getJson(branchPreviewPath(projectId, branchId, "functions"));
376
+ return functionsListResponseSchema.parse(data).functions.map(functionToSnapshot);
377
+ }, { projectId });
378
+ } catch (err) {
379
+ throw previewUnavailableError(err, "Functions");
380
+ }
373
381
  }
374
382
  async createBranchFunction(projectId, branchId, input) {
375
383
  return this.call(`createBranchFunction(${projectId}/${branchId}/${input.slug})`, async () => {
@@ -406,6 +414,7 @@ var RealNeonApi = class {
406
414
  return aiGatewayEnabledFromResponse(await this.getJson(aiGatewayPath(projectId, branchId)));
407
415
  }, { projectId });
408
416
  } catch (err) {
417
+ if (isPreviewFeatureUnavailable(err)) throw previewUnavailableError(err, "AI Gateway");
409
418
  if (err instanceof PlatformError && err.code === ErrorCode.NotFound) return false;
410
419
  throw err;
411
420
  }
@@ -476,6 +485,36 @@ function aiGatewayEnabledFromResponse(data) {
476
485
  if (data !== null && typeof data === "object" && "enabled" in data) return data.enabled === true;
477
486
  return false;
478
487
  }
488
+ /**
489
+ * Whether an error from a Preview-feature read means the feature simply isn't available
490
+ * for this project/branch/region (as opposed to a real, transient failure). Neon signals
491
+ * this a few ways: a 404 "this route does not exist" (the route isn't deployed at all), or
492
+ * a 503/4xx whose message says the platform feature is "not available" / "not enabled".
493
+ *
494
+ * Callers do **not** swallow this into an empty result — touching a Preview feature that
495
+ * isn't available is surfaced as a {@link previewUnavailableError} so `plan` / `status` /
496
+ * `pull` (and `neon dev`) fail clearly instead of, say, planning to create resources the
497
+ * API will refuse to create.
498
+ */
499
+ function isPreviewFeatureUnavailable(err) {
500
+ if (!(err instanceof PlatformError)) return false;
501
+ const status = err.details.status;
502
+ const message = typeof err.details.neonMessage === "string" ? err.details.neonMessage.toLowerCase() : "";
503
+ return (message.includes("not available") || message.includes("does not exist") || message.includes("not enabled")) && (status === 503 || status === 404 || status === 501);
504
+ }
505
+ /**
506
+ * Convert a Preview-feature error into a clear {@link PlatformError} when the feature is
507
+ * unavailable for the project; otherwise pass the original error through unchanged so a
508
+ * genuine failure (auth, transient 5xx, …) keeps its specific code and message.
509
+ */
510
+ function previewUnavailableError(err, featureLabel) {
511
+ if (!isPreviewFeatureUnavailable(err)) return err;
512
+ const neonMessage = err instanceof PlatformError && typeof err.details.neonMessage === "string" ? ` (Neon API said: "${err.details.neonMessage}")` : "";
513
+ return new PlatformError(ErrorCode.FeatureUnavailable, `${featureLabel} is a Preview feature that is not available for this project or region${neonMessage}. Enable it for your Neon account/project first, then re-run.`, {
514
+ cause: err,
515
+ details: { feature: featureLabel }
516
+ });
517
+ }
479
518
  function neonAuthResponseToSnapshot(data) {
480
519
  const snapshot = {
481
520
  projectId: data.auth_provider_project_id,
@@ -492,10 +531,24 @@ function createNeonAuthRestInput(input) {
492
531
  ...input.databaseName ? { database_name: input.databaseName } : {}
493
532
  };
494
533
  }
534
+ /**
535
+ * Read a response body as JSON, tolerating non-JSON. Some Neon routes return a plain-text
536
+ * body (e.g. a 404 `"this route does not exist"` for a Preview feature not enabled in the
537
+ * project/region). Parsing that with `JSON.parse` used to throw a cryptic
538
+ * `SyntaxError: Unexpected token …`, which — because parsing happens before the `res.ok`
539
+ * check in {@link request} — masked the real HTTP status. We instead return the raw text
540
+ * wrapped as `{ message }` so the status-based error path in `request` / `wrapNeonError`
541
+ * runs and produces a proper {@link PlatformError} (e.g. `NotFound`), and a non-error body
542
+ * that simply isn't JSON degrades to text rather than crashing.
543
+ */
495
544
  async function readJsonBody(res) {
496
545
  const text = await res.text();
497
546
  if (text.trim() === "") return {};
498
- return JSON.parse(text);
547
+ try {
548
+ return JSON.parse(text);
549
+ } catch {
550
+ return { message: text.trim() };
551
+ }
499
552
  }
500
553
  function projectToSnapshot(project) {
501
554
  const defaults = project.default_endpoint_settings;
@@ -577,6 +630,6 @@ function defaultsToComputeSettings(defaults) {
577
630
  return Object.keys(out).length > 0 ? out : void 0;
578
631
  }
579
632
  //#endregion
580
- export { createNeonAuthRestInput, createRealNeonApi, retryOnLocked };
633
+ export { createNeonAuthRestInput, createRealNeonApi, isPreviewFeatureUnavailable, previewUnavailableError, readJsonBody, retryOnLocked };
581
634
 
582
635
  //# sourceMappingURL=neon-api-real.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"neon-api-real.js","names":[],"sources":["../../src/lib/neon-api-real.ts"],"sourcesContent":["import {\n\ttype Branch,\n\ttype BranchCreateRequest,\n\ttype BranchCreateRequestEndpointOptions,\n\ttype BranchUpdateRequest,\n\tcreateApiClient,\n\ttype Database,\n\ttype DefaultEndpointSettings,\n\ttype Endpoint,\n\tEndpointType,\n\ttype EndpointUpdateRequest,\n\ttype PgVersion,\n\ttype Project,\n\ttype ProjectCreateRequest,\n\ttype ProjectListItem,\n\ttype ProjectUpdateRequest,\n\ttype Role,\n} from \"@neondatabase/api-client\";\nimport { z } from \"zod\";\nimport { formatSuspendTimeout, parseSuspendTimeout } from \"./duration.js\";\nimport { ErrorCode, PlatformError } from \"./errors.js\";\nimport type {\n\tCreateBranchInput,\n\tCreateBucketInput,\n\tCreateProjectInput,\n\tDeployFunctionInput,\n\tGetConnectionUriInput,\n\tNeonApi,\n\tNeonAuthSnapshot,\n\tNeonBranchSnapshot,\n\tNeonBucketSnapshot,\n\tNeonDataApiSnapshot,\n\tNeonDatabaseSnapshot,\n\tNeonEndpointSnapshot,\n\tNeonFunctionDeploymentSnapshot,\n\tNeonFunctionSnapshot,\n\tNeonProjectSnapshot,\n\tNeonRoleSnapshot,\n\tUpdateBranchInput,\n} from \"./neon-api.js\";\nimport type { BucketAccessLevel, ComputeSettings } from \"./types.js\";\nimport { wrapNeonError } from \"./wrap-neon-error.js\";\n\ntype ApiClient = ReturnType<typeof createApiClient>;\nconst DEFAULT_NEON_API_BASE_URL = \"https://console.neon.tech/api/v2\";\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// ─── 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) });\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 functionResponseSchema = z.object({ function: neonFunctionSchema });\nconst functionsListResponseSchema = z.object({\n\tfunctions: z.array(neonFunctionSchema),\n});\nconst functionDeploymentResponseSchema = z.object({\n\tdeployment: functionDeploymentSchema,\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 `@neondatabase/api-client` 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\tconst client = createApiClient({\n\t\tapiKey: options.apiKey,\n\t\t...(options.baseUrl ? { baseURL: options.baseUrl } : {}),\n\t});\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 res = await this.client.listProjects({\n\t\t\t\t\t\t...(filter.orgId ? { org_id: filter.orgId } : {}),\n\t\t\t\t\t\t...(cursor ? { cursor } : {}),\n\t\t\t\t\t\tlimit: 100,\n\t\t\t\t\t});\n\t\t\t\t\tprojects.push(...res.data.projects);\n\t\t\t\t\tconst next = (\n\t\t\t\t\t\tres.data as { pagination?: { next?: string } }\n\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 res = await this.client.getProject(projectId);\n\t\t\t\treturn projectToSnapshot(res.data.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 res = await this.client.createProject(body);\n\t\t\t\treturn projectToSnapshot(res.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 res = await this.client.updateProject(projectId, body);\n\t\t\t\treturn projectToSnapshot(res.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 res = await this.client.listProjectBranches({\n\t\t\t\t\t\tprojectId,\n\t\t\t\t\t\tlimit: 100,\n\t\t\t\t\t\t...(cursor ? { cursor } : {}),\n\t\t\t\t\t});\n\t\t\t\t\tbranches.push(...(res.data.branches as Branch[]));\n\t\t\t\t\tconst next = (\n\t\t\t\t\t\tres.data as { pagination?: { next?: string } }\n\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: EndpointType.ReadWrite,\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: EndpointType.ReadWrite };\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 res = await this.client.createProjectBranch(\n\t\t\t\t\tprojectId,\n\t\t\t\t\tbody,\n\t\t\t\t);\n\t\t\t\treturn {\n\t\t\t\t\tbranch: branchToSnapshot(res.data.branch),\n\t\t\t\t\tendpoints: (res.data.endpoints ?? []).map(\n\t\t\t\t\t\tendpointToSnapshot,\n\t\t\t\t\t),\n\t\t\t\t};\n\t\t\t},\n\t\t\t{ projectId, mutating: true },\n\t\t);\n\t}\n\n\tasync 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 res = await this.client.updateProjectBranch(\n\t\t\t\t\tprojectId,\n\t\t\t\t\tbranchId,\n\t\t\t\t\t{ branch },\n\t\t\t\t);\n\t\t\t\treturn branchToSnapshot(res.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 res = await this.client.listProjectEndpoints(projectId);\n\t\t\t\treturn (res.data.endpoints as Endpoint[]).map(\n\t\t\t\t\tendpointToSnapshot,\n\t\t\t\t);\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 res = await this.client.updateProjectEndpoint(\n\t\t\t\t\tprojectId,\n\t\t\t\t\tendpointId,\n\t\t\t\t\t{ endpoint },\n\t\t\t\t);\n\t\t\t\treturn endpointToSnapshot(res.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 res = await this.client.listProjectBranchRoles(\n\t\t\t\t\tprojectId,\n\t\t\t\t\tbranchId,\n\t\t\t\t);\n\t\t\t\treturn (res.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 res = await this.client.listProjectBranchDatabases(\n\t\t\t\t\tprojectId,\n\t\t\t\t\tbranchId,\n\t\t\t\t);\n\t\t\t\treturn (res.data.databases as Database[]).map(\n\t\t\t\t\tdatabaseToSnapshot,\n\t\t\t\t);\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 res = await this.client.getConnectionUri({\n\t\t\t\t\tprojectId,\n\t\t\t\t\tdatabase_name: input.databaseName,\n\t\t\t\t\trole_name: input.roleName,\n\t\t\t\t\t...(input.branchId ? { branch_id: input.branchId } : {}),\n\t\t\t\t\t...(input.endpointId\n\t\t\t\t\t\t? { endpoint_id: input.endpointId }\n\t\t\t\t\t\t: {}),\n\t\t\t\t\tpooled,\n\t\t\t\t});\n\t\t\t\treturn { uri: res.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 res = await this.client.getNeonAuth(\n\t\t\t\t\t\tprojectId,\n\t\t\t\t\t\tbranchId,\n\t\t\t\t\t);\n\t\t\t\t\treturn neonAuthResponseToSnapshot(res.data);\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// TODO: switch back to `this.client.createNeonAuth` once\n\t\t\t\t\t// @neondatabase/api-client narrows this branch endpoint to `better_auth`.\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 * Sends the bundle as the `file` field plus the deploy params Neon requires.\n\t */\n\tprivate async postMultipart(\n\t\tpath: string,\n\t\tinput: DeployFunctionInput,\n\t): Promise<unknown> {\n\t\tconst form = new FormData();\n\t\tform.set(\n\t\t\t\"file\",\n\t\t\tnew Blob([input.bundle as BlobPart], {\n\t\t\t\ttype: \"application/zip\",\n\t\t\t}),\n\t\t\t\"bundle.zip\",\n\t\t);\n\t\tform.set(\"memory_mib\", String(input.memoryMib));\n\t\t// Keep concurrency internal for now. The API requires it, but the public\n\t\t// neon.ts config surface intentionally does not expose it yet.\n\t\tform.set(\"concurrency\", \"1\");\n\t\tform.set(\"runtime\", input.runtime);\n\t\tfor (const [key, value] of Object.entries(input.environment)) {\n\t\t\tform.set(`environment[${key}]`, value);\n\t\t}\n\t\treturn this.request(\"POST\", path, { body: form });\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\tconst res = await this.client.getProjectBranchDataApi(\n\t\t\t\t\t\tprojectId,\n\t\t\t\t\t\tbranchId,\n\t\t\t\t\t\tdatabaseName,\n\t\t\t\t\t);\n\t\t\t\t\treturn { url: res.data.url };\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 enableProjectBranchDataApi(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t\tdatabaseName: string,\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 res = await this.client.createProjectBranchDataApi(\n\t\t\t\t\t\tprojectId,\n\t\t\t\t\t\tbranchId,\n\t\t\t\t\t\tdatabaseName,\n\t\t\t\t\t\t// Empty body — pick up Neon defaults (auth_provider inferred from\n\t\t\t\t\t\t// whether Neon Auth is also enabled; default schemas/grants).\n\t\t\t\t\t\t{},\n\t\t\t\t\t);\n\t\t\t\t\treturn { url: res.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\t// ─── Preview: buckets ──────────────────────────────────────────────────────\n\n\tasync listBranchBuckets(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t): Promise<NeonBucketSnapshot[]> {\n\t\treturn this.call(\n\t\t\t`listBranchBuckets(${projectId}/${branchId})`,\n\t\t\tasync () => {\n\t\t\t\tconst data = await this.getJson(\n\t\t\t\t\tbranchPreviewPath(projectId, branchId, \"buckets\"),\n\t\t\t\t);\n\t\t\t\tconst parsed = bucketsListResponseSchema.parse(data);\n\t\t\t\treturn parsed.buckets.map(bucketToSnapshot);\n\t\t\t},\n\t\t\t{ projectId },\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\t// ─── Preview: functions ────────────────────────────────────────────────────\n\n\tasync listBranchFunctions(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t): Promise<NeonFunctionSnapshot[]> {\n\t\treturn this.call(\n\t\t\t`listBranchFunctions(${projectId}/${branchId})`,\n\t\t\tasync () => {\n\t\t\t\tconst data = await this.getJson(\n\t\t\t\t\tbranchPreviewPath(projectId, branchId, \"functions\"),\n\t\t\t\t);\n\t\t\t\tconst parsed = functionsListResponseSchema.parse(data);\n\t\t\t\treturn parsed.functions.map(functionToSnapshot);\n\t\t\t},\n\t\t\t{ projectId },\n\t\t);\n\t}\n\n\tasync createBranchFunction(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t\tinput: { slug: string; name: string },\n\t): Promise<NeonFunctionSnapshot> {\n\t\treturn this.call(\n\t\t\t`createBranchFunction(${projectId}/${branchId}/${input.slug})`,\n\t\t\tasync () => {\n\t\t\t\tconst data = await this.postJson(\n\t\t\t\t\tbranchPreviewPath(projectId, branchId, \"functions\"),\n\t\t\t\t\t{ slug: input.slug, name: input.name },\n\t\t\t\t);\n\t\t\t\tconst parsed = functionResponseSchema.parse(data);\n\t\t\t\treturn functionToSnapshot(parsed.function);\n\t\t\t},\n\t\t\t{ projectId, mutating: true },\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// TODO(neon-deploy): the AI Gateway routes are not yet in the public API spec we wired\n\t// the rest of this adapter against. The paths below follow the established branch-scoped\n\t// convention (`/projects/{p}/branches/{b}/ai-gateway`); confirm them against the real\n\t// API (and the exact enable/disable verb + response shape) before relying on this in\n\t// production, and swap to the typed `@neondatabase/api-client` method once it exists.\n\n\tasync getAiGatewayEnabled(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t): Promise<boolean> {\n\t\ttry {\n\t\t\treturn await this.call(\n\t\t\t\t`getAiGatewayEnabled(${projectId}/${branchId})`,\n\t\t\t\tasync () => {\n\t\t\t\t\tconst data = await this.getJson(\n\t\t\t\t\t\taiGatewayPath(projectId, branchId),\n\t\t\t\t\t);\n\t\t\t\t\treturn aiGatewayEnabledFromResponse(data);\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 false;\n\t\t\tthrow err;\n\t\t}\n\t}\n\n\tasync enableAiGateway(projectId: string, branchId: string): Promise<void> {\n\t\tawait this.call(\n\t\t\t`enableAiGateway(${projectId}/${branchId})`,\n\t\t\tasync () => {\n\t\t\t\tawait this.postJson(aiGatewayPath(projectId, branchId), {\n\t\t\t\t\tenabled: true,\n\t\t\t\t});\n\t\t\t},\n\t\t\t{ projectId, mutating: true },\n\t\t);\n\t}\n\n\tasync disableAiGateway(projectId: string, branchId: string): Promise<void> {\n\t\tawait this.call(\n\t\t\t`disableAiGateway(${projectId}/${branchId})`,\n\t\t\tasync () => {\n\t\t\t\tawait this.deleteJson(aiGatewayPath(projectId, branchId));\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 aiGatewayPath(projectId: string, branchId: string): string {\n\treturn `/projects/${encodeURIComponent(projectId)}/branches/${encodeURIComponent(branchId)}/ai-gateway`;\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\nfunction aiGatewayEnabledFromResponse(data: unknown): boolean {\n\tif (data !== null && typeof data === \"object\" && \"enabled\" in data) {\n\t\treturn (data as { enabled?: unknown }).enabled === true;\n\t}\n\treturn false;\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\nasync function readJsonBody(res: Response): Promise<unknown> {\n\tconst text = await res.text();\n\tif (text.trim() === \"\") return {};\n\treturn JSON.parse(text);\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:\n\t\t\tendpoint.type === EndpointType.ReadOnly\n\t\t\t\t? \"read_only\"\n\t\t\t\t: \"read_write\",\n\t\tautoscalingLimitMinCu:\n\t\t\tendpoint.autoscaling_limit_min_cu as ComputeSettings[\"autoscalingLimitMinCu\"],\n\t\tautoscalingLimitMaxCu:\n\t\t\tendpoint.autoscaling_limit_max_cu as ComputeSettings[\"autoscalingLimitMaxCu\"],\n\t\tsuspendTimeout: formatSuspendTimeout(endpoint.suspend_timeout_seconds),\n\t};\n}\n\nfunction roleToSnapshot(role: Role): NeonRoleSnapshot {\n\treturn {\n\t\tname: role.name,\n\t\tbranchId: role.branch_id,\n\t\tprotected: role.protected ?? false,\n\t};\n}\n\nfunction databaseToSnapshot(database: Database): NeonDatabaseSnapshot {\n\treturn {\n\t\tname: database.name,\n\t\tbranchId: database.branch_id,\n\t\townerName: database.owner_name,\n\t};\n}\n\nfunction computeSettingsToDefaults(\n\tsettings: ComputeSettings,\n): DefaultEndpointSettings {\n\tconst out: DefaultEndpointSettings = {};\n\tif (settings.autoscalingLimitMinCu !== undefined)\n\t\tout.autoscaling_limit_min_cu = settings.autoscalingLimitMinCu;\n\tif (settings.autoscalingLimitMaxCu !== undefined)\n\t\tout.autoscaling_limit_max_cu = settings.autoscalingLimitMaxCu;\n\tif (settings.suspendTimeout !== undefined) {\n\t\tconst parsed = parseSuspendTimeout(settings.suspendTimeout);\n\t\tif (\"error\" in parsed) {\n\t\t\tthrow new PlatformError(\n\t\t\t\tErrorCode.InvalidConfig,\n\t\t\t\t`Invalid suspendTimeout: ${parsed.error}`,\n\t\t\t);\n\t\t}\n\t\tout.suspend_timeout_seconds = parsed.seconds;\n\t}\n\treturn out;\n}\n\nfunction computeSettingsToEndpointOptions(settings: ComputeSettings): {\n\tautoscaling_limit_min_cu?: number;\n\tautoscaling_limit_max_cu?: number;\n\tsuspend_timeout_seconds?: number;\n} {\n\tconst out: {\n\t\tautoscaling_limit_min_cu?: number;\n\t\tautoscaling_limit_max_cu?: number;\n\t\tsuspend_timeout_seconds?: number;\n\t} = {};\n\tif (settings.autoscalingLimitMinCu !== undefined)\n\t\tout.autoscaling_limit_min_cu = settings.autoscalingLimitMinCu;\n\tif (settings.autoscalingLimitMaxCu !== undefined)\n\t\tout.autoscaling_limit_max_cu = settings.autoscalingLimitMaxCu;\n\tif (settings.suspendTimeout !== undefined) {\n\t\tconst parsed = parseSuspendTimeout(settings.suspendTimeout);\n\t\tif (\"error\" in parsed) {\n\t\t\tthrow new PlatformError(\n\t\t\t\tErrorCode.InvalidConfig,\n\t\t\t\t`Invalid suspendTimeout: ${parsed.error}`,\n\t\t\t);\n\t\t}\n\t\tout.suspend_timeout_seconds = parsed.seconds;\n\t}\n\treturn out;\n}\n\nfunction defaultsToComputeSettings(\n\tdefaults: DefaultEndpointSettings,\n): ComputeSettings | undefined {\n\tconst out: ComputeSettings = {};\n\tif (defaults.autoscaling_limit_min_cu !== undefined)\n\t\tout.autoscalingLimitMinCu =\n\t\t\tdefaults.autoscaling_limit_min_cu as ComputeSettings[\"autoscalingLimitMinCu\"];\n\tif (defaults.autoscaling_limit_max_cu !== undefined)\n\t\tout.autoscalingLimitMaxCu =\n\t\t\tdefaults.autoscaling_limit_max_cu as ComputeSettings[\"autoscalingLimitMaxCu\"];\n\tif (defaults.suspend_timeout_seconds !== undefined)\n\t\tout.suspendTimeout = formatSuspendTimeout(\n\t\t\tdefaults.suspend_timeout_seconds,\n\t\t);\n\treturn Object.keys(out).length > 0 ? out : undefined;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"neon-api-real.js","names":[],"sources":["../../src/lib/neon-api-real.ts"],"sourcesContent":["import {\n\ttype Branch,\n\ttype BranchCreateRequest,\n\ttype BranchCreateRequestEndpointOptions,\n\ttype BranchUpdateRequest,\n\tcreateApiClient,\n\ttype Database,\n\ttype DefaultEndpointSettings,\n\ttype Endpoint,\n\tEndpointType,\n\ttype EndpointUpdateRequest,\n\ttype PgVersion,\n\ttype Project,\n\ttype ProjectCreateRequest,\n\ttype ProjectListItem,\n\ttype ProjectUpdateRequest,\n\ttype Role,\n} from \"@neondatabase/api-client\";\nimport { z } from \"zod\";\nimport { formatSuspendTimeout, parseSuspendTimeout } from \"./duration.js\";\nimport { ErrorCode, PlatformError } from \"./errors.js\";\nimport type {\n\tCreateBranchInput,\n\tCreateBucketInput,\n\tCreateProjectInput,\n\tDeployFunctionInput,\n\tGetConnectionUriInput,\n\tNeonApi,\n\tNeonAuthSnapshot,\n\tNeonBranchSnapshot,\n\tNeonBucketSnapshot,\n\tNeonDataApiSnapshot,\n\tNeonDatabaseSnapshot,\n\tNeonEndpointSnapshot,\n\tNeonFunctionDeploymentSnapshot,\n\tNeonFunctionSnapshot,\n\tNeonProjectSnapshot,\n\tNeonRoleSnapshot,\n\tUpdateBranchInput,\n} from \"./neon-api.js\";\nimport type { BucketAccessLevel, ComputeSettings } from \"./types.js\";\nimport { wrapNeonError } from \"./wrap-neon-error.js\";\n\ntype ApiClient = ReturnType<typeof createApiClient>;\nconst DEFAULT_NEON_API_BASE_URL = \"https://console.neon.tech/api/v2\";\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// ─── 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) });\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 functionResponseSchema = z.object({ function: neonFunctionSchema });\nconst functionsListResponseSchema = z.object({\n\tfunctions: z.array(neonFunctionSchema),\n});\nconst functionDeploymentResponseSchema = z.object({\n\tdeployment: functionDeploymentSchema,\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 `@neondatabase/api-client` 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\tconst client = createApiClient({\n\t\tapiKey: options.apiKey,\n\t\t...(options.baseUrl ? { baseURL: options.baseUrl } : {}),\n\t});\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 res = await this.client.listProjects({\n\t\t\t\t\t\t...(filter.orgId ? { org_id: filter.orgId } : {}),\n\t\t\t\t\t\t...(cursor ? { cursor } : {}),\n\t\t\t\t\t\tlimit: 100,\n\t\t\t\t\t});\n\t\t\t\t\tprojects.push(...res.data.projects);\n\t\t\t\t\tconst next = (\n\t\t\t\t\t\tres.data as { pagination?: { next?: string } }\n\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 res = await this.client.getProject(projectId);\n\t\t\t\treturn projectToSnapshot(res.data.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 res = await this.client.createProject(body);\n\t\t\t\treturn projectToSnapshot(res.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 res = await this.client.updateProject(projectId, body);\n\t\t\t\treturn projectToSnapshot(res.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 res = await this.client.listProjectBranches({\n\t\t\t\t\t\tprojectId,\n\t\t\t\t\t\tlimit: 100,\n\t\t\t\t\t\t...(cursor ? { cursor } : {}),\n\t\t\t\t\t});\n\t\t\t\t\tbranches.push(...(res.data.branches as Branch[]));\n\t\t\t\t\tconst next = (\n\t\t\t\t\t\tres.data as { pagination?: { next?: string } }\n\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: EndpointType.ReadWrite,\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: EndpointType.ReadWrite };\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 res = await this.client.createProjectBranch(\n\t\t\t\t\tprojectId,\n\t\t\t\t\tbody,\n\t\t\t\t);\n\t\t\t\treturn {\n\t\t\t\t\tbranch: branchToSnapshot(res.data.branch),\n\t\t\t\t\tendpoints: (res.data.endpoints ?? []).map(\n\t\t\t\t\t\tendpointToSnapshot,\n\t\t\t\t\t),\n\t\t\t\t};\n\t\t\t},\n\t\t\t{ projectId, mutating: true },\n\t\t);\n\t}\n\n\tasync 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 res = await this.client.updateProjectBranch(\n\t\t\t\t\tprojectId,\n\t\t\t\t\tbranchId,\n\t\t\t\t\t{ branch },\n\t\t\t\t);\n\t\t\t\treturn branchToSnapshot(res.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 res = await this.client.listProjectEndpoints(projectId);\n\t\t\t\treturn (res.data.endpoints as Endpoint[]).map(\n\t\t\t\t\tendpointToSnapshot,\n\t\t\t\t);\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 res = await this.client.updateProjectEndpoint(\n\t\t\t\t\tprojectId,\n\t\t\t\t\tendpointId,\n\t\t\t\t\t{ endpoint },\n\t\t\t\t);\n\t\t\t\treturn endpointToSnapshot(res.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 res = await this.client.listProjectBranchRoles(\n\t\t\t\t\tprojectId,\n\t\t\t\t\tbranchId,\n\t\t\t\t);\n\t\t\t\treturn (res.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 res = await this.client.listProjectBranchDatabases(\n\t\t\t\t\tprojectId,\n\t\t\t\t\tbranchId,\n\t\t\t\t);\n\t\t\t\treturn (res.data.databases as Database[]).map(\n\t\t\t\t\tdatabaseToSnapshot,\n\t\t\t\t);\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 res = await this.client.getConnectionUri({\n\t\t\t\t\tprojectId,\n\t\t\t\t\tdatabase_name: input.databaseName,\n\t\t\t\t\trole_name: input.roleName,\n\t\t\t\t\t...(input.branchId ? { branch_id: input.branchId } : {}),\n\t\t\t\t\t...(input.endpointId\n\t\t\t\t\t\t? { endpoint_id: input.endpointId }\n\t\t\t\t\t\t: {}),\n\t\t\t\t\tpooled,\n\t\t\t\t});\n\t\t\t\treturn { uri: res.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 res = await this.client.getNeonAuth(\n\t\t\t\t\t\tprojectId,\n\t\t\t\t\t\tbranchId,\n\t\t\t\t\t);\n\t\t\t\t\treturn neonAuthResponseToSnapshot(res.data);\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// TODO: switch back to `this.client.createNeonAuth` once\n\t\t\t\t\t// @neondatabase/api-client narrows this branch endpoint to `better_auth`.\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 * Sends the bundle as the `file` field plus the deploy params Neon requires.\n\t */\n\tprivate async postMultipart(\n\t\tpath: string,\n\t\tinput: DeployFunctionInput,\n\t): Promise<unknown> {\n\t\tconst form = new FormData();\n\t\tform.set(\n\t\t\t\"file\",\n\t\t\tnew Blob([input.bundle as BlobPart], {\n\t\t\t\ttype: \"application/zip\",\n\t\t\t}),\n\t\t\t\"bundle.zip\",\n\t\t);\n\t\tform.set(\"memory_mib\", String(input.memoryMib));\n\t\t// Keep concurrency internal for now. The API requires it, but the public\n\t\t// neon.ts config surface intentionally does not expose it yet.\n\t\tform.set(\"concurrency\", \"1\");\n\t\tform.set(\"runtime\", input.runtime);\n\t\tfor (const [key, value] of Object.entries(input.environment)) {\n\t\t\tform.set(`environment[${key}]`, value);\n\t\t}\n\t\treturn this.request(\"POST\", path, { body: form });\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\tconst res = await this.client.getProjectBranchDataApi(\n\t\t\t\t\t\tprojectId,\n\t\t\t\t\t\tbranchId,\n\t\t\t\t\t\tdatabaseName,\n\t\t\t\t\t);\n\t\t\t\t\treturn { url: res.data.url };\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 enableProjectBranchDataApi(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t\tdatabaseName: string,\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 res = await this.client.createProjectBranchDataApi(\n\t\t\t\t\t\tprojectId,\n\t\t\t\t\t\tbranchId,\n\t\t\t\t\t\tdatabaseName,\n\t\t\t\t\t\t// Empty body — pick up Neon defaults (auth_provider inferred from\n\t\t\t\t\t\t// whether Neon Auth is also enabled; default schemas/grants).\n\t\t\t\t\t\t{},\n\t\t\t\t\t);\n\t\t\t\t\treturn { url: res.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\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\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 createBranchFunction(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t\tinput: { slug: string; name: string },\n\t): Promise<NeonFunctionSnapshot> {\n\t\treturn this.call(\n\t\t\t`createBranchFunction(${projectId}/${branchId}/${input.slug})`,\n\t\t\tasync () => {\n\t\t\t\tconst data = await this.postJson(\n\t\t\t\t\tbranchPreviewPath(projectId, branchId, \"functions\"),\n\t\t\t\t\t{ slug: input.slug, name: input.name },\n\t\t\t\t);\n\t\t\t\tconst parsed = functionResponseSchema.parse(data);\n\t\t\t\treturn functionToSnapshot(parsed.function);\n\t\t\t},\n\t\t\t{ projectId, mutating: true },\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// TODO(neon-deploy): the AI Gateway routes are not yet in the public API spec we wired\n\t// the rest of this adapter against. The paths below follow the established branch-scoped\n\t// convention (`/projects/{p}/branches/{b}/ai-gateway`); confirm them against the real\n\t// API (and the exact enable/disable verb + response shape) before relying on this in\n\t// production, and swap to the typed `@neondatabase/api-client` method once it exists.\n\n\tasync getAiGatewayEnabled(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t): Promise<boolean> {\n\t\ttry {\n\t\t\treturn await this.call(\n\t\t\t\t`getAiGatewayEnabled(${projectId}/${branchId})`,\n\t\t\t\tasync () => {\n\t\t\t\t\tconst data = await this.getJson(\n\t\t\t\t\t\taiGatewayPath(projectId, branchId),\n\t\t\t\t\t);\n\t\t\t\t\treturn aiGatewayEnabledFromResponse(data);\n\t\t\t\t},\n\t\t\t\t{ projectId },\n\t\t\t);\n\t\t} catch (err) {\n\t\t\t// A \"feature unavailable\" signal (route not deployed / \"not available\")\n\t\t\t// is a hard error — surface it rather than reporting \"disabled\". A plain\n\t\t\t// NotFound *without* that signal means the route exists but AI Gateway is\n\t\t\t// simply not enabled on this branch, which is `false`.\n\t\t\tif (isPreviewFeatureUnavailable(err)) {\n\t\t\t\tthrow previewUnavailableError(err, \"AI Gateway\");\n\t\t\t}\n\t\t\tif (\n\t\t\t\terr instanceof PlatformError &&\n\t\t\t\terr.code === ErrorCode.NotFound\n\t\t\t) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tthrow err;\n\t\t}\n\t}\n\n\tasync enableAiGateway(projectId: string, branchId: string): Promise<void> {\n\t\tawait this.call(\n\t\t\t`enableAiGateway(${projectId}/${branchId})`,\n\t\t\tasync () => {\n\t\t\t\tawait this.postJson(aiGatewayPath(projectId, branchId), {\n\t\t\t\t\tenabled: true,\n\t\t\t\t});\n\t\t\t},\n\t\t\t{ projectId, mutating: true },\n\t\t);\n\t}\n\n\tasync disableAiGateway(projectId: string, branchId: string): Promise<void> {\n\t\tawait this.call(\n\t\t\t`disableAiGateway(${projectId}/${branchId})`,\n\t\t\tasync () => {\n\t\t\t\tawait this.deleteJson(aiGatewayPath(projectId, branchId));\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 aiGatewayPath(projectId: string, branchId: string): string {\n\treturn `/projects/${encodeURIComponent(projectId)}/branches/${encodeURIComponent(branchId)}/ai-gateway`;\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\nfunction aiGatewayEnabledFromResponse(data: unknown): boolean {\n\tif (data !== null && typeof data === \"object\" && \"enabled\" in data) {\n\t\treturn (data as { enabled?: unknown }).enabled === true;\n\t}\n\treturn false;\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 * 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 */\nexport function previewUnavailableError(\n\terr: unknown,\n\tfeatureLabel: string,\n): unknown {\n\tif (!isPreviewFeatureUnavailable(err)) return err;\n\tconst neonMessage =\n\t\terr instanceof PlatformError &&\n\t\ttypeof err.details.neonMessage === \"string\"\n\t\t\t? ` (Neon API said: \"${err.details.neonMessage}\")`\n\t\t\t: \"\";\n\treturn new PlatformError(\n\t\tErrorCode.FeatureUnavailable,\n\t\t`${featureLabel} is a Preview feature that is not available for this project or region${neonMessage}. ` +\n\t\t\t\"Enable it for your Neon account/project first, then re-run.\",\n\t\t{ cause: err, details: { feature: featureLabel } },\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 * 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:\n\t\t\tendpoint.type === EndpointType.ReadOnly\n\t\t\t\t? \"read_only\"\n\t\t\t\t: \"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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"}
@@ -36,13 +36,10 @@ declare const functionConfigSchema: z.ZodObject<{
36
36
  env: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
37
37
  runtime: z.ZodOptional<z.ZodLiteral<"nodejs24">>;
38
38
  memoryMib: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<256>, z.ZodLiteral<512>, z.ZodLiteral<1024>, z.ZodLiteral<2048>, z.ZodLiteral<4096>, z.ZodLiteral<8192>]>>;
39
- dev: z.ZodOptional<z.ZodUnion<readonly [z.ZodObject<{
40
- portless: z.ZodLiteral<true>;
41
- port: z.ZodNumber;
42
- }, z.core.$strict>, z.ZodObject<{
43
- portless: z.ZodOptional<z.ZodLiteral<false>>;
39
+ dev: z.ZodOptional<z.ZodObject<{
44
40
  port: z.ZodOptional<z.ZodNumber>;
45
- }, z.core.$strict>]>>;
41
+ portless: z.ZodOptional<z.ZodBoolean>;
42
+ }, z.core.$strict>>;
46
43
  }, z.core.$strict>;
47
44
  declare const bucketConfigSchema: z.ZodObject<{
48
45
  name: z.ZodString;
@@ -56,13 +53,10 @@ declare const previewConfigSchema: z.ZodObject<{
56
53
  env: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
57
54
  runtime: z.ZodOptional<z.ZodLiteral<"nodejs24">>;
58
55
  memoryMib: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<256>, z.ZodLiteral<512>, z.ZodLiteral<1024>, z.ZodLiteral<2048>, z.ZodLiteral<4096>, z.ZodLiteral<8192>]>>;
59
- dev: z.ZodOptional<z.ZodUnion<readonly [z.ZodObject<{
60
- portless: z.ZodLiteral<true>;
61
- port: z.ZodNumber;
62
- }, z.core.$strict>, z.ZodObject<{
63
- portless: z.ZodOptional<z.ZodLiteral<false>>;
56
+ dev: z.ZodOptional<z.ZodObject<{
64
57
  port: z.ZodOptional<z.ZodNumber>;
65
- }, z.core.$strict>]>>;
58
+ portless: z.ZodOptional<z.ZodBoolean>;
59
+ }, z.core.$strict>>;
66
60
  }, z.core.$strict>>>;
67
61
  buckets: z.ZodOptional<z.ZodArray<z.ZodObject<{
68
62
  name: z.ZodString;
@@ -97,13 +91,10 @@ declare const branchConfigSchema: z.ZodObject<{
97
91
  env: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
98
92
  runtime: z.ZodOptional<z.ZodLiteral<"nodejs24">>;
99
93
  memoryMib: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<256>, z.ZodLiteral<512>, z.ZodLiteral<1024>, z.ZodLiteral<2048>, z.ZodLiteral<4096>, z.ZodLiteral<8192>]>>;
100
- dev: z.ZodOptional<z.ZodUnion<readonly [z.ZodObject<{
101
- portless: z.ZodLiteral<true>;
102
- port: z.ZodNumber;
103
- }, z.core.$strict>, z.ZodObject<{
104
- portless: z.ZodOptional<z.ZodLiteral<false>>;
94
+ dev: z.ZodOptional<z.ZodObject<{
105
95
  port: z.ZodOptional<z.ZodNumber>;
106
- }, z.core.$strict>]>>;
96
+ portless: z.ZodOptional<z.ZodBoolean>;
97
+ }, z.core.$strict>>;
107
98
  }, z.core.$strict>>>;
108
99
  buckets: z.ZodOptional<z.ZodArray<z.ZodObject<{
109
100
  name: z.ZodString;
@@ -1 +1 @@
1
- {"version":3,"file":"schema.d.ts","names":[],"sources":["../../src/lib/schema.ts"],"mappings":";;;;;;AAgBA;;;;;;;;;;cAAa,uBAAqB,CAAA,CAAA;;;;;cAgDrB,qBAAmB,CAAA,CAAA;;;cAInB,sBAAoB,CAAA,CAAA;;;;;;iBApDC,CAAA;AAAA,cAiGrB,oBAjGqB,EAiGD,CAAA,CAAA,SAjGC,CAAA;EAgDrB,IAAA,aAAA;EAEX,IAAA,aAAA;;;;WAF8B,eAAA,WAAA,CAAA,SAAA,aAAA,CAAA,GAAA,CAAA,cAAA,CAAA,GAAA,CAAA,cAAA,CAAA,IAAA,CAAA,cAAA,CAAA,IAAA,CAAA,cAAA,CAAA,IAAA,CAAA,cAAA,CAAA,IAAA,CAAA,CAAA,CAAA,CAAA;EAAA,GAAA,eAAA,WAAA,CAAA,SAAA,YAAA,CAAA;IAInB,QAAA,cAEX,CAAA,IAAA,CAAA;IAAA,IAAA,aAAA;;;;;;cA8DW,oBAAkB,CAAA,CAAA;;;;cAOlB,qBAAmB,CAAA,CAAA;;;;;;;;;;;;;;;;SAvEC,eAAA,WAAA,YAAA,CAAA;IAAA,IAAA,aAAA;IA6CpB,MAAA,eAiBX,WAAA,CAAA,SAAA,aAAA,CAAA,SAAA,CAAA,cAAA,CAAA,aAAA,CAAA,CAAA,CAAA,CAAA;EAAA,CAAA,gBAAA,CAAA,CAAA,CAAA;;;;;cA2DW,oBAAkB,CAAA,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;QA5EE,QAAA,cAAA,CAAA,IAAA,CAAA;QAAA,IAAA,aAAA;MAmBpB,CAAA,gBAKX,CAAA,aAAA,CAAA;QAAA,QAAA,eAAA,aAAA,CAAA,KAAA,CAAA,CAAA;;;;;;;IAL6B,CAAA,gBAAA,CAAA,CAAA,CAAA;IAAA,SAAA,eAAA,YAAA,CAAA;MAOlB,OAAA,eAqBV,aAAA,CAAA;IAAA,CAAA,gBAAA,CAAA,CAAA;;;cA4EU,cAAY,CAAA,CAAA,YAAA,CAAA,CAAA,mBAAA,CAAA,CAAA,oBAAA,CAAA,CAAA;;;;;;;;;;iBAcT,eAAA,QAAuB,CAAA,CAAE"}
1
+ {"version":3,"file":"schema.d.ts","names":[],"sources":["../../src/lib/schema.ts"],"mappings":";;;;;;AAgBA;;;;;;;;;;cAAa,uBAAqB,CAAA,CAAA;;;;;cAgDrB,qBAAmB,CAAA,CAAA;;;cAInB,sBAAoB,CAAA,CAAA;;;;;;iBApDC,CAAA;AAAA,cA2FrB,oBA3FqB,EA2FD,CAAA,CAAA,SA3FC,CAAA;EAgDrB,IAAA,aAAA;EAEX,IAAA,aAAA;;;;WAF8B,eAAA,WAAA,CAAA,SAAA,aAAA,CAAA,GAAA,CAAA,cAAA,CAAA,GAAA,CAAA,cAAA,CAAA,IAAA,CAAA,cAAA,CAAA,IAAA,CAAA,cAAA,CAAA,IAAA,CAAA,cAAA,CAAA,IAAA,CAAA,CAAA,CAAA,CAAA;EAAA,GAAA,eAAA,YAAA,CAAA;IAInB,IAAA,eAEX,YAAA,CAAA;IAAA,QAAA,eAAA,aAAA,CAAA;;;cAwDW,oBAAkB,CAAA,CAAA;;;;cAOlB,qBAAmB,CAAA,CAAA;;;;;;;;;;;;;;;;;;;mBAjEC,CAAA,CAAA;AAAA,CAAA,gBAAA,CAAA;AAuCpB,cA4EA,kBA3DX,EA2D6B,CAAA,CAAA,SA3D7B,CAAA;EAAA,MAAA,eAAA,YAAA,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;QAjB+B,QAAA,eAAA,aAAA,CAAA;MAAA,CAAA,gBAAA,CAAA,CAAA;IAmBpB,CAAA,gBAKX,CAAA,CAAA,CAAA;IAAA,OAAA,eAAA,WAAA,YAAA,CAAA;;;;;;;mBAL6B,CAAA,CAAA;AAAA,CAAA,gBAAA,CAAA;AAOlB,cAiGA,YA5EV,EA4EsB,CAAA,CAAA,WA5EtB,CA4EsB,CAAA,CAAA,QA5EtB,CAAA,SAAA,CA4EsB,CAAA,CAAA,UA5EtB,CAAA,EAAA,IAAA,CAAA,EA4EsB,CAAA,CAAA,UA5EtB,CAAA;;;;;;;;;;iBA0Fa,eAAA,QAAuB,CAAA,CAAE"}
@@ -55,9 +55,9 @@ const serviceToggleSchema = z.strictObject({ enabled: z.boolean().optional() });
55
55
  const postgresConfigSchema = z.strictObject({ computeSettings: computeSettingsSchema.optional() });
56
56
  /**
57
57
  * Branch-unique function slug. Mirrors the Neon Functions API path-segment rule
58
- * (`platform/internal/platform/functions/name.go`): lowercase DNS label, 1–40 chars.
58
+ * (`platform/internal/platform/functions/name.go`): 1–20 lowercase letters and digits.
59
59
  */
60
- const functionSlugSchema = z.string().regex(/^[a-z0-9]([a-z0-9-]{0,38}[a-z0-9])?$/, "function slug must be a lowercase DNS label (1-40 chars, letters/digits/hyphens, no leading/trailing hyphen)");
60
+ const functionSlugSchema = z.string().regex(/^[a-z0-9]{1,20}$/, "function slug must be 1-20 lowercase letters and digits (no hyphens or other characters)");
61
61
  /**
62
62
  * Per-function environment map. Every value must be a defined string: a `process.env.X`
63
63
  * that is unset surfaces as `undefined` and is rejected here (rather than silently
@@ -70,18 +70,15 @@ const functionEnvSchema = z.record(z.string(), z.string());
70
70
  */
71
71
  const devPortSchema = z.number().int().min(1).max(65535);
72
72
  /**
73
- * Local-dev settings for a function (`neon dev` only; never affects deploy). Modeled as a
74
- * union of two strict shapes so the inferred type *is* the {@link FunctionDevConfig}
75
- * discriminated union — `portless: true` carries a required `port` (portless needs a concrete
76
- * port to map its `slug.localhost` name to); otherwise `port` is optional.
73
+ * Local-dev settings for a function (`neon dev` only; never affects deploy). `port` and
74
+ * `portless` are independent: when `portless` is true, portless assigns the port itself
75
+ * (so `port` is ignored); otherwise `port` is bound exactly when set, or a free port is
76
+ * found when omitted.
77
77
  */
78
- const functionDevConfigSchema = z.union([z.strictObject({
79
- portless: z.literal(true),
80
- port: devPortSchema
81
- }), z.strictObject({
82
- portless: z.literal(false).optional(),
83
- port: devPortSchema.optional()
84
- })]);
78
+ const functionDevConfigSchema = z.strictObject({
79
+ port: devPortSchema.optional(),
80
+ portless: z.boolean().optional()
81
+ });
85
82
  const functionConfigSchema = z.strictObject({
86
83
  slug: functionSlugSchema,
87
84
  name: z.string().min(1).max(255),
@@ -1 +1 @@
1
- {"version":3,"file":"schema.js","names":[],"sources":["../../src/lib/schema.ts"],"sourcesContent":["import { z } from \"zod\";\nimport { parseDuration, parseSuspendTimeout } from \"./duration.js\";\nimport { isWildcardPattern, validatePattern } from \"./patterns.js\";\n\n/**\n * Zod schema for {@link import(\"./types.js\").ComputeSettings}.\n *\n * - CU values must be one of: 0.25, 0.5, 1, 2, 4, 8\n * - `suspendTimeout` can be:\n * - `false` (never suspend)\n * - duration string like \"5m\", \"1h\" (must be 60s-604800s when parsed)\n * - number in seconds (60-604800, or -1/0 for special values)\n * - `undefined` (use platform default)\n *\n * Cross-field invariants (min <= max) are enforced via `superRefine`.\n */\nexport const computeSettingsSchema = z\n\t.strictObject({\n\t\tautoscalingLimitMinCu: z\n\t\t\t.union([\n\t\t\t\tz.literal(0.25),\n\t\t\t\tz.literal(0.5),\n\t\t\t\tz.literal(1),\n\t\t\t\tz.literal(2),\n\t\t\t\tz.literal(4),\n\t\t\t\tz.literal(8),\n\t\t\t])\n\t\t\t.optional(),\n\t\tautoscalingLimitMaxCu: z\n\t\t\t.union([\n\t\t\t\tz.literal(0.25),\n\t\t\t\tz.literal(0.5),\n\t\t\t\tz.literal(1),\n\t\t\t\tz.literal(2),\n\t\t\t\tz.literal(4),\n\t\t\t\tz.literal(8),\n\t\t\t])\n\t\t\t.optional(),\n\t\tsuspendTimeout: z\n\t\t\t.union([z.literal(false), z.string(), z.number()])\n\t\t\t.optional()\n\t\t\t.superRefine((value, ctx) => {\n\t\t\t\tif (value === undefined) return; // undefined is valid (use platform default)\n\t\t\t\tconst result = parseSuspendTimeout(value);\n\t\t\t\tif (\"error\" in result) {\n\t\t\t\t\tctx.addIssue({\n\t\t\t\t\t\tcode: \"custom\",\n\t\t\t\t\t\tmessage: result.error,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}),\n\t})\n\t.superRefine((settings, ctx) => {\n\t\tconst { autoscalingLimitMinCu: min, autoscalingLimitMaxCu: max } =\n\t\t\tsettings;\n\t\tif (min !== undefined && max !== undefined && min > max) {\n\t\t\tctx.addIssue({\n\t\t\t\tcode: \"custom\",\n\t\t\t\tpath: [\"autoscalingLimitMinCu\"],\n\t\t\t\tmessage: `autoscalingLimitMinCu (${min}) must be <= autoscalingLimitMaxCu (${max})`,\n\t\t\t});\n\t\t}\n\t});\n\nexport const serviceToggleSchema = z.strictObject({\n\tenabled: z.boolean().optional(),\n});\n\nexport const postgresConfigSchema = z.strictObject({\n\tcomputeSettings: computeSettingsSchema.optional(),\n});\n\n/**\n * Branch-unique function slug. Mirrors the Neon Functions API path-segment rule\n * (`platform/internal/platform/functions/name.go`): lowercase DNS label, 1–40 chars.\n */\nconst functionSlugSchema = z\n\t.string()\n\t.regex(\n\t\t/^[a-z0-9]([a-z0-9-]{0,38}[a-z0-9])?$/,\n\t\t\"function slug must be a lowercase DNS label (1-40 chars, letters/digits/hyphens, no leading/trailing hyphen)\",\n\t);\n\n/**\n * Per-function environment map. Every value must be a defined string: a `process.env.X`\n * that is unset surfaces as `undefined` and is rejected here (rather than silently\n * shipping `undefined` into the deployment).\n */\nconst functionEnvSchema = z.record(z.string(), z.string());\n\n/**\n * TCP port for a function's local dev server. Excludes 0 (which means \"any port\" to the OS\n * — `neon dev` expresses \"pick one for me\" by omitting `port`, not by passing 0).\n */\nconst devPortSchema = z.number().int().min(1).max(65535);\n\n/**\n * Local-dev settings for a function (`neon dev` only; never affects deploy). Modeled as a\n * union of two strict shapes so the inferred type *is* the {@link FunctionDevConfig}\n * discriminated union — `portless: true` carries a required `port` (portless needs a concrete\n * port to map its `slug.localhost` name to); otherwise `port` is optional.\n */\nconst functionDevConfigSchema = z.union([\n\tz.strictObject({\n\t\tportless: z.literal(true),\n\t\tport: devPortSchema,\n\t}),\n\tz.strictObject({\n\t\tportless: z.literal(false).optional(),\n\t\tport: devPortSchema.optional(),\n\t}),\n]);\n\nexport const functionConfigSchema = z.strictObject({\n\tslug: functionSlugSchema,\n\tname: z.string().min(1).max(255),\n\tsource: z.string().min(1),\n\tenv: functionEnvSchema.optional(),\n\truntime: z.literal(\"nodejs24\").optional(),\n\tmemoryMib: z\n\t\t.union([\n\t\t\tz.literal(256),\n\t\t\tz.literal(512),\n\t\t\tz.literal(1024),\n\t\t\tz.literal(2048),\n\t\t\tz.literal(4096),\n\t\t\tz.literal(8192),\n\t\t])\n\t\t.optional(),\n\tdev: functionDevConfigSchema.optional(),\n});\n\nexport const bucketConfigSchema = z.strictObject({\n\tname: z.string().min(1).max(255),\n\taccess: z\n\t\t.union([z.literal(\"private\"), z.literal(\"public_read\")])\n\t\t.optional(),\n});\n\nexport const previewConfigSchema = z\n\t.strictObject({\n\t\tfunctions: z.array(functionConfigSchema).optional(),\n\t\tbuckets: z.array(bucketConfigSchema).optional(),\n\t\taiGateway: serviceToggleSchema.optional(),\n\t})\n\t.superRefine((preview, ctx) => {\n\t\tassertUnique({\n\t\t\tctx,\n\t\t\tpath: [\"functions\"],\n\t\t\titems: preview.functions ?? [],\n\t\t\tkey: (fn) => fn.slug,\n\t\t\tlabel: \"function slug\",\n\t\t});\n\t\tassertUnique({\n\t\t\tctx,\n\t\t\tpath: [\"buckets\"],\n\t\t\titems: preview.buckets ?? [],\n\t\t\tkey: (bucket) => bucket.name,\n\t\t\tlabel: \"bucket name\",\n\t\t});\n\t});\n\n/**\n * Flag duplicate keys within a Preview collection so a typo in two function slugs (or two\n * buckets) surfaces as a config error rather than the second silently clobbering the first\n * at apply time.\n */\nfunction assertUnique<T>(args: {\n\tctx: z.RefinementCtx;\n\tpath: (string | number)[];\n\titems: T[];\n\tkey: (item: T) => string;\n\tlabel: string;\n}): void {\n\tconst { ctx, path, items, key, label } = args;\n\tconst seen = new Set<string>();\n\titems.forEach((item, index) => {\n\t\tconst value = key(item);\n\t\tif (seen.has(value)) {\n\t\t\tctx.addIssue({\n\t\t\t\tcode: \"custom\",\n\t\t\t\tpath: [...path, index],\n\t\t\t\tmessage: `duplicate ${label}: ${JSON.stringify(value)}`,\n\t\t\t});\n\t\t}\n\t\tseen.add(value);\n\t});\n}\n\nexport const branchConfigSchema = z\n\t.strictObject({\n\t\tparent: z.string().optional(),\n\t\tprotected: z.boolean().optional(),\n\t\tttl: z\n\t\t\t.union([z.string(), z.number()])\n\t\t\t.optional()\n\t\t\t.superRefine((value, ctx) => {\n\t\t\t\tif (value === undefined) return;\n\t\t\t\tconst result = parseDuration(value);\n\t\t\t\tif (\"error\" in result) {\n\t\t\t\t\tctx.addIssue({ code: \"custom\", message: result.error });\n\t\t\t\t}\n\t\t\t}),\n\t\tpostgres: postgresConfigSchema.optional(),\n\t\tauth: serviceToggleSchema.optional(),\n\t\tdataApi: serviceToggleSchema.optional(),\n\t\tpreview: previewConfigSchema.optional(),\n\t})\n\t.superRefine((cfg, ctx) => {\n\t\tvalidateParentReference({\n\t\t\tctx,\n\t\t\tpath: [\"parent\"],\n\t\t\tparent: cfg.parent,\n\t\t});\n\t});\n\nfunction validateParentReference(args: {\n\tctx: z.RefinementCtx;\n\tpath: (string | number)[];\n\tparent: string | undefined;\n}): void {\n\tconst { ctx, path, parent } = args;\n\tif (parent === undefined) return;\n\n\tconst patternCheck = validatePattern(parent);\n\tif (\"error\" in patternCheck) {\n\t\tctx.addIssue({ code: \"custom\", path, message: patternCheck.error });\n\t} else if (isWildcardPattern(parent)) {\n\t\tctx.addIssue({\n\t\t\tcode: \"custom\",\n\t\t\tpath,\n\t\t\tmessage: `parent must be a concrete branch name (no wildcards), got \"${parent}\"`,\n\t\t});\n\t}\n}\n\nexport const configSchema = z.function({\n\tinput: [z.unknown()],\n\toutput: z.unknown(),\n});\n\n/**\n * Convert the structured {@link z.ZodError} produced by `configSchema.safeParse` into the\n * `string[]` shape used by {@link import(\"./errors.js\").ConfigValidationError}.\n *\n * Issue paths are rendered as dot-separated property accesses (`postgres.computeSettings`)\n * and unknown-key issues from `strictObject` are normalised so the message contains the\n * substring \"unknown key\" — keeping pre-zod assertions in test suites and downstream tools\n * stable.\n */\nexport function formatZodIssues(error: z.ZodError): string[] {\n\treturn error.issues.map((issue) => {\n\t\tconst path = renderPath(issue.path);\n\t\tconst message = normaliseIssueMessage(issue);\n\t\treturn path ? `${path}: ${message}` : message;\n\t});\n}\n\nfunction renderPath(path: ReadonlyArray<PropertyKey>): string {\n\tlet out = \"\";\n\tfor (const segment of path) {\n\t\tif (typeof segment === \"number\") out += `[${segment}]`;\n\t\telse if (out === \"\") out += String(segment);\n\t\telse out += `.${String(segment)}`;\n\t}\n\treturn out;\n}\n\nfunction normaliseIssueMessage(issue: z.core.$ZodIssue): string {\n\tif (issue.code === \"unrecognized_keys\") {\n\t\tconst keys = (issue as z.core.$ZodIssueUnrecognizedKeys).keys ?? [];\n\t\tconst formatted = keys.map((k) => JSON.stringify(k)).join(\", \");\n\t\treturn `unknown key${keys.length === 1 ? \"\" : \"s\"}: ${formatted}`;\n\t}\n\treturn issue.message;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"schema.js","names":[],"sources":["../../src/lib/schema.ts"],"sourcesContent":["import { z } from \"zod\";\nimport { parseDuration, parseSuspendTimeout } from \"./duration.js\";\nimport { isWildcardPattern, validatePattern } from \"./patterns.js\";\n\n/**\n * Zod schema for {@link import(\"./types.js\").ComputeSettings}.\n *\n * - CU values must be one of: 0.25, 0.5, 1, 2, 4, 8\n * - `suspendTimeout` can be:\n * - `false` (never suspend)\n * - duration string like \"5m\", \"1h\" (must be 60s-604800s when parsed)\n * - number in seconds (60-604800, or -1/0 for special values)\n * - `undefined` (use platform default)\n *\n * Cross-field invariants (min <= max) are enforced via `superRefine`.\n */\nexport const computeSettingsSchema = z\n\t.strictObject({\n\t\tautoscalingLimitMinCu: z\n\t\t\t.union([\n\t\t\t\tz.literal(0.25),\n\t\t\t\tz.literal(0.5),\n\t\t\t\tz.literal(1),\n\t\t\t\tz.literal(2),\n\t\t\t\tz.literal(4),\n\t\t\t\tz.literal(8),\n\t\t\t])\n\t\t\t.optional(),\n\t\tautoscalingLimitMaxCu: z\n\t\t\t.union([\n\t\t\t\tz.literal(0.25),\n\t\t\t\tz.literal(0.5),\n\t\t\t\tz.literal(1),\n\t\t\t\tz.literal(2),\n\t\t\t\tz.literal(4),\n\t\t\t\tz.literal(8),\n\t\t\t])\n\t\t\t.optional(),\n\t\tsuspendTimeout: z\n\t\t\t.union([z.literal(false), z.string(), z.number()])\n\t\t\t.optional()\n\t\t\t.superRefine((value, ctx) => {\n\t\t\t\tif (value === undefined) return; // undefined is valid (use platform default)\n\t\t\t\tconst result = parseSuspendTimeout(value);\n\t\t\t\tif (\"error\" in result) {\n\t\t\t\t\tctx.addIssue({\n\t\t\t\t\t\tcode: \"custom\",\n\t\t\t\t\t\tmessage: result.error,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}),\n\t})\n\t.superRefine((settings, ctx) => {\n\t\tconst { autoscalingLimitMinCu: min, autoscalingLimitMaxCu: max } =\n\t\t\tsettings;\n\t\tif (min !== undefined && max !== undefined && min > max) {\n\t\t\tctx.addIssue({\n\t\t\t\tcode: \"custom\",\n\t\t\t\tpath: [\"autoscalingLimitMinCu\"],\n\t\t\t\tmessage: `autoscalingLimitMinCu (${min}) must be <= autoscalingLimitMaxCu (${max})`,\n\t\t\t});\n\t\t}\n\t});\n\nexport const serviceToggleSchema = z.strictObject({\n\tenabled: z.boolean().optional(),\n});\n\nexport const postgresConfigSchema = z.strictObject({\n\tcomputeSettings: computeSettingsSchema.optional(),\n});\n\n/**\n * Branch-unique function slug. Mirrors the Neon Functions API path-segment rule\n * (`platform/internal/platform/functions/name.go`): 1–20 lowercase letters and digits.\n */\nconst functionSlugSchema = z\n\t.string()\n\t.regex(\n\t\t/^[a-z0-9]{1,20}$/,\n\t\t\"function slug must be 1-20 lowercase letters and digits (no hyphens or other characters)\",\n\t);\n\n/**\n * Per-function environment map. Every value must be a defined string: a `process.env.X`\n * that is unset surfaces as `undefined` and is rejected here (rather than silently\n * shipping `undefined` into the deployment).\n */\nconst functionEnvSchema = z.record(z.string(), z.string());\n\n/**\n * TCP port for a function's local dev server. Excludes 0 (which means \"any port\" to the OS\n * — `neon dev` expresses \"pick one for me\" by omitting `port`, not by passing 0).\n */\nconst devPortSchema = z.number().int().min(1).max(65535);\n\n/**\n * Local-dev settings for a function (`neon dev` only; never affects deploy). `port` and\n * `portless` are independent: when `portless` is true, portless assigns the port itself\n * (so `port` is ignored); otherwise `port` is bound exactly when set, or a free port is\n * found when omitted.\n */\nconst functionDevConfigSchema = z.strictObject({\n\tport: devPortSchema.optional(),\n\tportless: z.boolean().optional(),\n});\n\nexport const functionConfigSchema = z.strictObject({\n\tslug: functionSlugSchema,\n\tname: z.string().min(1).max(255),\n\tsource: z.string().min(1),\n\tenv: functionEnvSchema.optional(),\n\truntime: z.literal(\"nodejs24\").optional(),\n\tmemoryMib: z\n\t\t.union([\n\t\t\tz.literal(256),\n\t\t\tz.literal(512),\n\t\t\tz.literal(1024),\n\t\t\tz.literal(2048),\n\t\t\tz.literal(4096),\n\t\t\tz.literal(8192),\n\t\t])\n\t\t.optional(),\n\tdev: functionDevConfigSchema.optional(),\n});\n\nexport const bucketConfigSchema = z.strictObject({\n\tname: z.string().min(1).max(255),\n\taccess: z\n\t\t.union([z.literal(\"private\"), z.literal(\"public_read\")])\n\t\t.optional(),\n});\n\nexport const previewConfigSchema = z\n\t.strictObject({\n\t\tfunctions: z.array(functionConfigSchema).optional(),\n\t\tbuckets: z.array(bucketConfigSchema).optional(),\n\t\taiGateway: serviceToggleSchema.optional(),\n\t})\n\t.superRefine((preview, ctx) => {\n\t\tassertUnique({\n\t\t\tctx,\n\t\t\tpath: [\"functions\"],\n\t\t\titems: preview.functions ?? [],\n\t\t\tkey: (fn) => fn.slug,\n\t\t\tlabel: \"function slug\",\n\t\t});\n\t\tassertUnique({\n\t\t\tctx,\n\t\t\tpath: [\"buckets\"],\n\t\t\titems: preview.buckets ?? [],\n\t\t\tkey: (bucket) => bucket.name,\n\t\t\tlabel: \"bucket name\",\n\t\t});\n\t});\n\n/**\n * Flag duplicate keys within a Preview collection so a typo in two function slugs (or two\n * buckets) surfaces as a config error rather than the second silently clobbering the first\n * at apply time.\n */\nfunction assertUnique<T>(args: {\n\tctx: z.RefinementCtx;\n\tpath: (string | number)[];\n\titems: T[];\n\tkey: (item: T) => string;\n\tlabel: string;\n}): void {\n\tconst { ctx, path, items, key, label } = args;\n\tconst seen = new Set<string>();\n\titems.forEach((item, index) => {\n\t\tconst value = key(item);\n\t\tif (seen.has(value)) {\n\t\t\tctx.addIssue({\n\t\t\t\tcode: \"custom\",\n\t\t\t\tpath: [...path, index],\n\t\t\t\tmessage: `duplicate ${label}: ${JSON.stringify(value)}`,\n\t\t\t});\n\t\t}\n\t\tseen.add(value);\n\t});\n}\n\nexport const branchConfigSchema = z\n\t.strictObject({\n\t\tparent: z.string().optional(),\n\t\tprotected: z.boolean().optional(),\n\t\tttl: z\n\t\t\t.union([z.string(), z.number()])\n\t\t\t.optional()\n\t\t\t.superRefine((value, ctx) => {\n\t\t\t\tif (value === undefined) return;\n\t\t\t\tconst result = parseDuration(value);\n\t\t\t\tif (\"error\" in result) {\n\t\t\t\t\tctx.addIssue({ code: \"custom\", message: result.error });\n\t\t\t\t}\n\t\t\t}),\n\t\tpostgres: postgresConfigSchema.optional(),\n\t\tauth: serviceToggleSchema.optional(),\n\t\tdataApi: serviceToggleSchema.optional(),\n\t\tpreview: previewConfigSchema.optional(),\n\t})\n\t.superRefine((cfg, ctx) => {\n\t\tvalidateParentReference({\n\t\t\tctx,\n\t\t\tpath: [\"parent\"],\n\t\t\tparent: cfg.parent,\n\t\t});\n\t});\n\nfunction validateParentReference(args: {\n\tctx: z.RefinementCtx;\n\tpath: (string | number)[];\n\tparent: string | undefined;\n}): void {\n\tconst { ctx, path, parent } = args;\n\tif (parent === undefined) return;\n\n\tconst patternCheck = validatePattern(parent);\n\tif (\"error\" in patternCheck) {\n\t\tctx.addIssue({ code: \"custom\", path, message: patternCheck.error });\n\t} else if (isWildcardPattern(parent)) {\n\t\tctx.addIssue({\n\t\t\tcode: \"custom\",\n\t\t\tpath,\n\t\t\tmessage: `parent must be a concrete branch name (no wildcards), got \"${parent}\"`,\n\t\t});\n\t}\n}\n\nexport const configSchema = z.function({\n\tinput: [z.unknown()],\n\toutput: z.unknown(),\n});\n\n/**\n * Convert the structured {@link z.ZodError} produced by `configSchema.safeParse` into the\n * `string[]` shape used by {@link import(\"./errors.js\").ConfigValidationError}.\n *\n * Issue paths are rendered as dot-separated property accesses (`postgres.computeSettings`)\n * and unknown-key issues from `strictObject` are normalised so the message contains the\n * substring \"unknown key\" — keeping pre-zod assertions in test suites and downstream tools\n * stable.\n */\nexport function formatZodIssues(error: z.ZodError): string[] {\n\treturn error.issues.map((issue) => {\n\t\tconst path = renderPath(issue.path);\n\t\tconst message = normaliseIssueMessage(issue);\n\t\treturn path ? `${path}: ${message}` : message;\n\t});\n}\n\nfunction renderPath(path: ReadonlyArray<PropertyKey>): string {\n\tlet out = \"\";\n\tfor (const segment of path) {\n\t\tif (typeof segment === \"number\") out += `[${segment}]`;\n\t\telse if (out === \"\") out += String(segment);\n\t\telse out += `.${String(segment)}`;\n\t}\n\treturn out;\n}\n\nfunction normaliseIssueMessage(issue: z.core.$ZodIssue): string {\n\tif (issue.code === \"unrecognized_keys\") {\n\t\tconst keys = (issue as z.core.$ZodIssueUnrecognizedKeys).keys ?? [];\n\t\tconst formatted = keys.map((k) => JSON.stringify(k)).join(\", \");\n\t\treturn `unknown key${keys.length === 1 ? \"\" : \"s\"}: ${formatted}`;\n\t}\n\treturn issue.message;\n}\n"],"mappings":"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"}
@@ -83,22 +83,26 @@ type FunctionMemoryMib = 256 | 512 | 1024 | 2048 | 4096 | 8192;
83
83
  * Local-development settings for a function, used by `neon dev` when it serves every
84
84
  * function declared in `neon.ts` (i.e. invoked with no `--source`). Never affects deploy.
85
85
  *
86
- * Typed as a discriminated union so the `portless` `port` requirement is enforced at
87
- * compile time: a `portless` route needs a concrete port to map its `slug.localhost`
88
- * name to, so `port` is mandatory when `portless: true`.
86
+ * `port` and `portless` are independent:
89
87
  *
90
- * - `{ portless: true; port }` — wrap this function with `portless run <slug> …` so it gets
91
- * a stable `slug.localhost` URL. `port` is required.
92
- * - `{ portless?: false; port? }` — serve directly. `port` is optional: when set it is bound
93
- * exactly (and `neon dev` fails loudly if it is taken); when omitted a free port is found.
88
+ * - `portless: true` — wrap this function's local server with `portless <slug> …` so it gets
89
+ * a stable `slug.localhost` URL. Portless assigns the port itself (it injects `PORT`), so
90
+ * `port` is ignored in this mode.
91
+ * - otherwise serve directly. `port`, when set, is bound exactly (and `neon dev` fails
92
+ * loudly if it is taken); when omitted a free port is found automatically.
94
93
  */
95
- type FunctionDevConfig = {
96
- portless: true;
97
- port: number;
98
- } | {
99
- portless?: false;
94
+ interface FunctionDevConfig {
95
+ /**
96
+ * Port the local server binds. Bound exactly (fails if taken) when set; a free port is
97
+ * found when omitted. Ignored when `portless` is true (portless assigns the port).
98
+ */
100
99
  port?: number;
101
- };
100
+ /**
101
+ * Expose this function via `portless` (a stable `slug.localhost` URL). Requires the
102
+ * `portless` binary on PATH. Portless assigns the port, so `port` is ignored here.
103
+ */
104
+ portless?: boolean;
105
+ }
102
106
  /**
103
107
  * A single Neon Function deployed to a branch (Preview feature).
104
108
  *
@@ -109,9 +113,9 @@ type FunctionDevConfig = {
109
113
  */
110
114
  interface FunctionConfig {
111
115
  /**
112
- * Branch-unique, lowercase DNS-label used as the path segment in the function's
113
- * invocation URL. Immutable once created. 1–40 chars, `^[a-z0-9]([a-z0-9-]{0,38}[a-z0-9])?$`.
114
- * @example "hello-world"
116
+ * Branch-unique slug used as the path segment in the function's invocation URL.
117
+ * Immutable once created. 1–20 lowercase letters and digits: `^[a-z0-9]{1,20}$`.
118
+ * @example "hellofn"
115
119
  */
116
120
  slug: string;
117
121
  /** Free-form display name. @example "Hello World" */
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","names":[],"sources":["../../src/lib/types.ts"],"mappings":";;AAIA;AASA;;AAMyB,KAfb,WAAA,GAea,IAAA,GAAA,GAAA,GAAA,CAAA,GAAA,CAAA,GAAA,CAAA,GAAA,CAAA;;AAMW;AAuBpC;AAiBA;AAKA;AASA;AAMA;AAeY,UAvFK,eAAA,CAuFY;EAYZ;;;;;uBAmCV,CAAA,EAhIkB,WAgIlB;EAAiB;AAIxB;AAKA;AAcA;;uBAEa,CAAA,EAnJY,WAmJZ;;;AAIa;AACzB;;;;AAcuB;AAAA;;;;;gBAOW,CAAA,EAAA,KAAA,GAAA,IAAA,GAAA,IAAA,GAAA,MAAA,GAAA,MAAA;AAAa;AAEhD;;;;AAAiE;AAEjE;AAAkB,UA1JD,YAAA,CA0JC;;MAA6B,EAAA,MAAA;EAAY;EAM1C,EAAA,CAAA,EAAA,MAAA;EAAsB;QAIjC,EAAA,OAAA;;UAEM,CAAA,EAAA,MAAA;;EAKY,SAAA,CAAA,EAAA,OAAA;EAIP;EAUA,WAAA,CAAA,EAAA,OAAA;EAAqB;WAC1B,CAAA,EAAA,MAAA;;AACkB,UA1Kb,aAAA,CA0Ka;EAIb;EAAoB,OAAA,CAAA,EAAA,OAAA;;AAO1B,UAhLM,cAAA,CAgLN;EAAqB,eAAA,CAAA,EA/Kb,eA+Ka;AAMhC;AAkBA;AAYA;;;;AAW0B,KAtNd,eAAA,GAsNc,UAAA;;;;;KAhNd,iBAAA;;;;;;;;;;;;;;KAeA,iBAAA;;;;;;;;;;;;;;;UAYK,cAAA;;;;;;;;;;;;;;;;;;;;;;;;;;QA0BV;;YAEI;;cAEE;;;;;QAKN;;;KAIK,iBAAA;;;;UAKK,YAAA;;;;;;;WAOP;;;;;;UAOO,aAAA;;cAEJ;;YAEF;;cAEE;;UAGH,gBAAA;;;;;;;aAOE;;;;;YAKD;;KAGN,mBAAA;;;;QAEM;;;;WACiB;;QACjB;WAAwB;;KAEvB,YAAA,GAAe,mBAAmB;KAElC,MAAA,YAAkB,iBAAiB;;;;;UAM9B,sBAAA;;;;OAIX;WACI;aACE;;;;;QAKL;;;UAIU,oBAAA;;UAER;;;;;;;UAQQ,qBAAA;aACL;WACF;;;UAIO,oBAAA;;;;aAIL;;;YAGD;;;;;UAMM,aAAA;;;;;;;;YAQN;;;;;;;;;UAUM,cAAA;;;;;;;;;;;UAYA,UAAA;;;;;;;;;;WAUP;aACE"}
1
+ {"version":3,"file":"types.d.ts","names":[],"sources":["../../src/lib/types.ts"],"mappings":";;AAIA;AASA;;AAMyB,KAfb,WAAA,GAea,IAAA,GAAA,GAAA,GAAA,CAAA,GAAA,CAAA,GAAA,CAAA,GAAA,CAAA;;AAMW;AAuBpC;AAiBA;AAKA;AASA;AAMA;AAciB,UAtFA,eAAA,CAsFiB;EAqBjB;;;;;uBAmCV,CAAA,EAxIkB,WAwIlB;EAAiB;AAIxB;AAKA;AAcA;;uBAEa,CAAA,EA3JY,WA2JZ;;;AAIa;AACzB;;;;AAcuB;AAAA;;;;;gBAOW,CAAA,EAAA,KAAA,GAAA,IAAA,GAAA,IAAA,GAAA,MAAA,GAAA,MAAA;AAAa;AAEhD;;;;AAAiE;AAEjE;AAAkB,UAlKD,YAAA,CAkKC;;MAA6B,EAAA,MAAA;EAAY;EAM1C,EAAA,CAAA,EAAA,MAAA;EAAsB;QAIjC,EAAA,OAAA;;UAEM,CAAA,EAAA,MAAA;;EAKY,SAAA,CAAA,EAAA,OAAA;EAIP;EAUA,WAAA,CAAA,EAAA,OAAA;EAAqB;WAC1B,CAAA,EAAA,MAAA;;AACkB,UAlLb,aAAA,CAkLa;EAIb;EAAoB,OAAA,CAAA,EAAA,OAAA;;AAO1B,UAxLM,cAAA,CAwLN;EAAqB,eAAA,CAAA,EAvLb,eAuLa;AAMhC;AAkBA;AAYA;;;;AAW0B,KA9Nd,eAAA,GA8Nc,UAAA;;;;;KAxNd,iBAAA;;;;;;;;;;;;;UAcK,iBAAA;;;;;;;;;;;;;;;;;;;;UAqBA,cAAA;;;;;;;;;;;;;;;;;;;;;;;;;;QA0BV;;YAEI;;cAEE;;;;;QAKN;;;KAIK,iBAAA;;;;UAKK,YAAA;;;;;;;WAOP;;;;;;UAOO,aAAA;;cAEJ;;YAEF;;cAEE;;UAGH,gBAAA;;;;;;;aAOE;;;;;YAKD;;KAGN,mBAAA;;;;QAEM;;;;WACiB;;QACjB;WAAwB;;KAEvB,YAAA,GAAe,mBAAmB;KAElC,MAAA,YAAkB,iBAAiB;;;;;UAM9B,sBAAA;;;;OAIX;WACI;aACE;;;;;QAKL;;;UAIU,oBAAA;;UAER;;;;;;;UAQQ,qBAAA;aACL;WACF;;;UAIO,oBAAA;;;;aAIL;;;YAGD;;;;;UAMM,aAAA;;;;;;;;YAQN;;;;;;;;;UAUM,cAAA;;;;;;;;;;;UAYA,UAAA;;;;;;;;;;WAUP;aACE"}
package/dist/v1.d.ts CHANGED
@@ -28,6 +28,7 @@ declare const errors: {
28
28
  readonly MissingApiKey: "PLATFORM_MISSING_API_KEY";
29
29
  readonly AmbiguousBranchAuth: "PLATFORM_AMBIGUOUS_BRANCH_AUTH";
30
30
  readonly BranchNotFound: "PLATFORM_BRANCH_NOT_FOUND";
31
+ readonly FeatureUnavailable: "PLATFORM_FEATURE_UNAVAILABLE";
31
32
  readonly MissingParentBranch: "PLATFORM_MISSING_PARENT_BRANCH";
32
33
  readonly Unauthorized: "PLATFORM_UNAUTHORIZED";
33
34
  readonly Forbidden: "PLATFORM_FORBIDDEN";
@@ -71,13 +72,10 @@ declare const schemas: {
71
72
  env: zod0.ZodOptional<zod0.ZodRecord<zod0.ZodString, zod0.ZodString>>;
72
73
  runtime: zod0.ZodOptional<zod0.ZodLiteral<"nodejs24">>;
73
74
  memoryMib: zod0.ZodOptional<zod0.ZodUnion<readonly [zod0.ZodLiteral<256>, zod0.ZodLiteral<512>, zod0.ZodLiteral<1024>, zod0.ZodLiteral<2048>, zod0.ZodLiteral<4096>, zod0.ZodLiteral<8192>]>>;
74
- dev: zod0.ZodOptional<zod0.ZodUnion<readonly [zod0.ZodObject<{
75
- portless: zod0.ZodLiteral<true>;
76
- port: zod0.ZodNumber;
77
- }, zod_v4_core0.$strict>, zod0.ZodObject<{
78
- portless: zod0.ZodOptional<zod0.ZodLiteral<false>>;
75
+ dev: zod0.ZodOptional<zod0.ZodObject<{
79
76
  port: zod0.ZodOptional<zod0.ZodNumber>;
80
- }, zod_v4_core0.$strict>]>>;
77
+ portless: zod0.ZodOptional<zod0.ZodBoolean>;
78
+ }, zod_v4_core0.$strict>>;
81
79
  }, zod_v4_core0.$strict>>>;
82
80
  buckets: zod0.ZodOptional<zod0.ZodArray<zod0.ZodObject<{
83
81
  name: zod0.ZodString;
@@ -105,13 +103,10 @@ declare const schemas: {
105
103
  env: zod0.ZodOptional<zod0.ZodRecord<zod0.ZodString, zod0.ZodString>>;
106
104
  runtime: zod0.ZodOptional<zod0.ZodLiteral<"nodejs24">>;
107
105
  memoryMib: zod0.ZodOptional<zod0.ZodUnion<readonly [zod0.ZodLiteral<256>, zod0.ZodLiteral<512>, zod0.ZodLiteral<1024>, zod0.ZodLiteral<2048>, zod0.ZodLiteral<4096>, zod0.ZodLiteral<8192>]>>;
108
- dev: zod0.ZodOptional<zod0.ZodUnion<readonly [zod0.ZodObject<{
109
- portless: zod0.ZodLiteral<true>;
110
- port: zod0.ZodNumber;
111
- }, zod_v4_core0.$strict>, zod0.ZodObject<{
112
- portless: zod0.ZodOptional<zod0.ZodLiteral<false>>;
106
+ dev: zod0.ZodOptional<zod0.ZodObject<{
113
107
  port: zod0.ZodOptional<zod0.ZodNumber>;
114
- }, zod_v4_core0.$strict>]>>;
108
+ portless: zod0.ZodOptional<zod0.ZodBoolean>;
109
+ }, zod_v4_core0.$strict>>;
115
110
  }, zod_v4_core0.$strict>;
116
111
  readonly postgres: zod0.ZodObject<{
117
112
  computeSettings: zod0.ZodOptional<zod0.ZodObject<{
@@ -128,13 +123,10 @@ declare const schemas: {
128
123
  env: zod0.ZodOptional<zod0.ZodRecord<zod0.ZodString, zod0.ZodString>>;
129
124
  runtime: zod0.ZodOptional<zod0.ZodLiteral<"nodejs24">>;
130
125
  memoryMib: zod0.ZodOptional<zod0.ZodUnion<readonly [zod0.ZodLiteral<256>, zod0.ZodLiteral<512>, zod0.ZodLiteral<1024>, zod0.ZodLiteral<2048>, zod0.ZodLiteral<4096>, zod0.ZodLiteral<8192>]>>;
131
- dev: zod0.ZodOptional<zod0.ZodUnion<readonly [zod0.ZodObject<{
132
- portless: zod0.ZodLiteral<true>;
133
- port: zod0.ZodNumber;
134
- }, zod_v4_core0.$strict>, zod0.ZodObject<{
135
- portless: zod0.ZodOptional<zod0.ZodLiteral<false>>;
126
+ dev: zod0.ZodOptional<zod0.ZodObject<{
136
127
  port: zod0.ZodOptional<zod0.ZodNumber>;
137
- }, zod_v4_core0.$strict>]>>;
128
+ portless: zod0.ZodOptional<zod0.ZodBoolean>;
129
+ }, zod_v4_core0.$strict>>;
138
130
  }, zod_v4_core0.$strict>>>;
139
131
  buckets: zod0.ZodOptional<zod0.ZodArray<zod0.ZodObject<{
140
132
  name: zod0.ZodString;
package/dist/v1.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"v1.d.ts","names":[],"sources":["../src/v1.ts"],"mappings":";;;;;;;;;;;;;;;;;cA0Da;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAWA;;6BASH,IAAA,CAAA,SAAA"}
1
+ {"version":3,"file":"v1.d.ts","names":[],"sources":["../src/v1.ts"],"mappings":";;;;;;;;;;;;;;;;;cA0Da;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAWA;;6BASH,IAAA,CAAA,SAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@neondatabase/config",
3
- "version": "0.2.0",
3
+ "version": "0.2.1",
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",