@neondatabase/config 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { AppliedChange, BranchConfig, BranchTarget, BucketAccessLevel, BucketConfig, ComputeSettings, Config, ConflictReport, FunctionConfig, FunctionMemoryMib, FunctionRuntime, PostgresConfig, PreviewConfig, PushResult, ResolvedBranchConfig, ResolvedBucketConfig, ResolvedFunctionConfig, ResolvedPreviewConfig, ServiceToggle } from "./lib/types.js";
1
+ import { AppliedChange, BranchConfig, BranchTarget, BucketAccessLevel, BucketConfig, ComputeSettings, Config, ConflictReport, FunctionConfig, FunctionDevConfig, FunctionMemoryMib, FunctionRuntime, PostgresConfig, PreviewConfig, PushResult, ResolvedBranchConfig, ResolvedBucketConfig, ResolvedFunctionConfig, ResolvedPreviewConfig, ServiceToggle } from "./lib/types.js";
2
2
  import { ConfigLoadError, ConfigValidationError, ErrorCode, MissingContextError, PlatformError, PushAbortedError, PushConflictError } from "./lib/errors.js";
3
3
  import { CreateBranchInput, CreateBucketInput, CreateProjectInput, DeployFunctionInput, GetConnectionUriInput, NeonApi, NeonAuthSnapshot, NeonBranchSnapshot, NeonBucketSnapshot, NeonDataApiSnapshot, NeonDatabaseSnapshot, NeonEndpointSnapshot, NeonFunctionDeploymentSnapshot, NeonFunctionSnapshot, NeonProjectSnapshot, NeonRoleSnapshot, UpdateBranchInput } from "./lib/neon-api.js";
4
4
  import { createNeonApiFromOptions, resolveApiKey } from "./lib/auth.js";
@@ -7,4 +7,4 @@ import { DiffOptions, DiffResult, PlanStep, RemotePreviewState, RemoteServiceSta
7
7
  import { LoadConfigOptions, loadConfigFromFile } from "./lib/loader.js";
8
8
  import { createRealNeonApi } from "./lib/neon-api-real.js";
9
9
  import { errors, schemas } from "./v1.js";
10
- export { AppliedChange, BranchConfig, BranchTarget, BucketAccessLevel, BucketConfig, ComputeSettings, Config, ConfigLoadError, ConfigValidationError, ConflictReport, CreateBranchInput, CreateBucketInput, CreateProjectInput, DeployFunctionInput, DiffOptions, DiffResult, ErrorCode, FunctionConfig, FunctionMemoryMib, FunctionRuntime, GetConnectionUriInput, LoadConfigOptions, MissingContextError, NeonApi, NeonAuthSnapshot, NeonBranchSnapshot, NeonBucketSnapshot, NeonDataApiSnapshot, NeonDatabaseSnapshot, NeonEndpointSnapshot, NeonFunctionDeploymentSnapshot, NeonFunctionSnapshot, NeonProjectSnapshot, NeonRoleSnapshot, PlanStep, PlatformError, PostgresConfig, PreviewConfig, PushAbortedError, PushConflictError, PushResult, RemotePreviewState, RemoteServiceState, RemoteState, ResolvedBranchConfig, ResolvedBucketConfig, ResolvedFunctionConfig, ResolvedPreviewConfig, ServiceToggle, UpdateBranchInput, createNeonApiFromOptions, createRealNeonApi, defineConfig, diffConfig, errors, loadConfigFromFile, resolveApiKey, resolveConfig, schemas };
10
+ export { AppliedChange, BranchConfig, BranchTarget, BucketAccessLevel, BucketConfig, ComputeSettings, Config, ConfigLoadError, ConfigValidationError, ConflictReport, CreateBranchInput, CreateBucketInput, CreateProjectInput, DeployFunctionInput, DiffOptions, DiffResult, ErrorCode, FunctionConfig, FunctionDevConfig, FunctionMemoryMib, FunctionRuntime, GetConnectionUriInput, LoadConfigOptions, MissingContextError, NeonApi, NeonAuthSnapshot, NeonBranchSnapshot, NeonBucketSnapshot, NeonDataApiSnapshot, NeonDatabaseSnapshot, NeonEndpointSnapshot, NeonFunctionDeploymentSnapshot, NeonFunctionSnapshot, NeonProjectSnapshot, NeonRoleSnapshot, PlanStep, PlatformError, PostgresConfig, PreviewConfig, PushAbortedError, PushConflictError, PushResult, RemotePreviewState, RemoteServiceState, RemoteState, ResolvedBranchConfig, ResolvedBucketConfig, ResolvedFunctionConfig, ResolvedPreviewConfig, ServiceToggle, UpdateBranchInput, createNeonApiFromOptions, createRealNeonApi, defineConfig, diffConfig, errors, loadConfigFromFile, resolveApiKey, resolveConfig, schemas };
@@ -1 +1 @@
1
- {"version":3,"file":"define-config.d.ts","names":[],"sources":["../../src/lib/define-config.ts"],"mappings":";;;;;;AA2CA;;;;;AAAiE;AAcjE;;;;;AAGuB;AAwFvB;;;;;;;;;;;iBAzGgB,6BAA6B,eAAe,IAAI;;;;iBAchD,aAAA,SACP,gBACA,eACN;;;;;;iBAwFa,eAAA"}
1
+ {"version":3,"file":"define-config.d.ts","names":[],"sources":["../../src/lib/define-config.ts"],"mappings":";;;;;;AA4CA;;;;;AAAiE;AAcjE;;;;;AAGuB;AA0FvB;;;;;;;;;;;iBA3GgB,6BAA6B,eAAe,IAAI;;;;iBAchD,aAAA,SACP,gBACA,eACN;;;;;;iBA0Fa,eAAA"}
@@ -93,7 +93,8 @@ function resolveFunctionConfig(fn) {
93
93
  source: fn.source,
94
94
  env: { ...fn.env ?? {} },
95
95
  runtime: fn.runtime ?? DEFAULT_FUNCTION_RUNTIME,
96
- memoryMib: fn.memoryMib ?? DEFAULT_FUNCTION_MEMORY_MIB
96
+ memoryMib: fn.memoryMib ?? DEFAULT_FUNCTION_MEMORY_MIB,
97
+ ...fn.dev ? { dev: fn.dev } : {}
97
98
  };
98
99
  }
99
100
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"define-config.js","names":[],"sources":["../../src/lib/define-config.ts"],"sourcesContent":["import { parseDuration } from \"./duration.js\";\nimport { ConfigValidationError } from \"./errors.js\";\nimport { branchConfigSchema, formatZodIssues } from \"./schema.js\";\nimport type {\n\tBranchTarget,\n\tConfig,\n\tFunctionConfig,\n\tPreviewConfig,\n\tResolvedBranchConfig,\n\tResolvedPreviewConfig,\n} from \"./types.js\";\n\n/** Default deploy parameters applied to functions that omit them in `neon.ts`. */\nconst DEFAULT_FUNCTION_RUNTIME = \"nodejs24\" as const;\nconst DEFAULT_FUNCTION_MEMORY_MIB = 512 as const;\n\nconst REGION_PREFIX = /^(aws|azure|gcp)-/;\n\n/**\n * Validate and freeze a Neon Platform branch policy.\n *\n * Used at the top of `neon.ts`:\n * ```ts\n * import { defineConfig } from \"@neondatabase/config/v1\";\n *\n * export default defineConfig((branch) => {\n * if (branch.name === \"main\") {\n * return { protected: true, auth: {} };\n * }\n * return { parent: \"main\", ttl: \"7d\" };\n * });\n * ```\n *\n * The `branch` parameter is a **read-only {@link BranchTarget} descriptor** of the branch\n * this policy invocation is deciding for — not a live branch handle. You don't mutate it\n * (`branch.protected = true` does nothing); you switch on its facts (`branch.name`,\n * `branch.isDefault`, `branch.exists`, …) and **return** the desired {@link BranchConfig}.\n * The same callback runs in two modes: against an existing branch (fields populated from\n * Neon) and during pre-create evaluation (`exists: false`, `id` undefined).\n *\n * Pure function — no I/O, no side effects. The returned policy validates its output every\n * time it is evaluated so errors point at the concrete branch target that triggered them.\n */\nexport function defineConfig<const C extends Config>(input: C): C {\n\tif (typeof input !== \"function\") {\n\t\tthrow new ConfigValidationError([\n\t\t\t\"defineConfig expects a function: `export default defineConfig((branch) => ({ ... }))`.\",\n\t\t\t\"Project-level config has moved to `neonctl link`; neon.ts now describes branch-level policy only.\",\n\t\t]);\n\t}\n\n\treturn Object.freeze(input) as C;\n}\n\n/**\n * Evaluate a branch policy for a specific branch target and return a normalized config.\n */\nexport function resolveConfig(\n\tconfig: Config,\n\tbranch: BranchTarget,\n): ResolvedBranchConfig {\n\tlet raw: unknown;\n\ttry {\n\t\traw = config(Object.freeze({ ...branch }));\n\t} catch (cause) {\n\t\tthrow new ConfigValidationError([\n\t\t\t`Config function threw while evaluating branch \"${branch.name}\".`,\n\t\t\t(cause as Error)?.message ?? String(cause),\n\t\t]);\n\t}\n\n\tconst parsed = branchConfigSchema.safeParse(raw);\n\tif (!parsed.success) {\n\t\tthrow new ConfigValidationError(formatZodIssues(parsed.error));\n\t}\n\n\tconst cfg = parsed.data;\n\tconst issues: string[] = [];\n\tlet ttlSeconds: number | undefined;\n\tif (cfg.ttl !== undefined) {\n\t\tconst parsedTtl = parseDuration(cfg.ttl);\n\t\tif (\"error\" in parsedTtl) {\n\t\t\tissues.push(`ttl: ${parsedTtl.error}`);\n\t\t} else {\n\t\t\tttlSeconds = parsedTtl.seconds;\n\t\t}\n\t}\n\tif (issues.length > 0) {\n\t\tthrow new ConfigValidationError(issues);\n\t}\n\n\tconst resolved: ResolvedBranchConfig = {\n\t\tauthEnabled: isServiceEnabled(cfg.auth),\n\t\tdataApiEnabled: isServiceEnabled(cfg.dataApi),\n\t};\n\tif (cfg.parent !== undefined) resolved.parent = cfg.parent;\n\tif (ttlSeconds !== undefined) resolved.ttlSeconds = ttlSeconds;\n\tif (cfg.protected !== undefined) resolved.protected = cfg.protected;\n\tif (cfg.postgres) {\n\t\tresolved.postgres = {\n\t\t\t...(cfg.postgres.computeSettings\n\t\t\t\t? { computeSettings: { ...cfg.postgres.computeSettings } }\n\t\t\t\t: {}),\n\t\t};\n\t}\n\tif (cfg.preview) {\n\t\tresolved.preview = resolvePreviewConfig(cfg.preview);\n\t}\n\treturn resolved;\n}\n\nfunction isServiceEnabled(service: { enabled?: boolean } | undefined): boolean {\n\treturn service !== undefined && service.enabled !== false;\n}\n\n/**\n * Normalize a {@link PreviewConfig} into a {@link ResolvedPreviewConfig}: apply per-function\n * deploy defaults, default each bucket's access level to `private`, and collapse the\n * `aiGateway` toggle to a boolean using the same present-and-not-`false` rule as\n * `auth` / `dataApi`.\n */\nfunction resolvePreviewConfig(preview: PreviewConfig): ResolvedPreviewConfig {\n\treturn {\n\t\tfunctions: (preview.functions ?? []).map(resolveFunctionConfig),\n\t\tbuckets: (preview.buckets ?? []).map((bucket) => ({\n\t\t\tname: bucket.name,\n\t\t\taccess: bucket.access ?? \"private\",\n\t\t})),\n\t\taiGatewayEnabled: isServiceEnabled(preview.aiGateway),\n\t};\n}\n\nfunction resolveFunctionConfig(fn: FunctionConfig) {\n\treturn {\n\t\tslug: fn.slug,\n\t\tname: fn.name,\n\t\tsource: fn.source,\n\t\tenv: { ...(fn.env ?? {}) },\n\t\truntime: fn.runtime ?? DEFAULT_FUNCTION_RUNTIME,\n\t\tmemoryMib: fn.memoryMib ?? DEFAULT_FUNCTION_MEMORY_MIB,\n\t};\n}\n\n/**\n * Normalize a region identifier to Neon's `<cloud>-<region>` format. When the user writes\n * `us-east-1` we assume `aws-us-east-1`. Pure helper used by both the validator and the\n * NeonApi adapter.\n */\nexport function normalizeRegion(region: string): string {\n\tif (REGION_PREFIX.test(region)) return region;\n\treturn `aws-${region}`;\n}\n"],"mappings":";;;;;AAaA,MAAM,2BAA2B;AACjC,MAAM,8BAA8B;AAEpC,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;AA2BtB,SAAgB,aAAqC,OAAa;CACjE,IAAI,OAAO,UAAU,YACpB,MAAM,IAAI,sBAAsB,CAC/B,0FACA,mGACD,CAAC;CAGF,OAAO,OAAO,OAAO,KAAK;AAC3B;;;;AAKA,SAAgB,cACf,QACA,QACuB;CACvB,IAAI;CACJ,IAAI;EACH,MAAM,OAAO,OAAO,OAAO,EAAE,GAAG,OAAO,CAAC,CAAC;CAC1C,SAAS,OAAO;EACf,MAAM,IAAI,sBAAsB,CAC/B,kDAAkD,OAAO,KAAK,KAC7D,OAAiB,WAAW,OAAO,KAAK,CAC1C,CAAC;CACF;CAEA,MAAM,SAAS,mBAAmB,UAAU,GAAG;CAC/C,IAAI,CAAC,OAAO,SACX,MAAM,IAAI,sBAAsB,gBAAgB,OAAO,KAAK,CAAC;CAG9D,MAAM,MAAM,OAAO;CACnB,MAAM,SAAmB,CAAC;CAC1B,IAAI;CACJ,IAAI,IAAI,QAAQ,KAAA,GAAW;EAC1B,MAAM,YAAY,cAAc,IAAI,GAAG;EACvC,IAAI,WAAW,WACd,OAAO,KAAK,QAAQ,UAAU,OAAO;OAErC,aAAa,UAAU;CAEzB;CACA,IAAI,OAAO,SAAS,GACnB,MAAM,IAAI,sBAAsB,MAAM;CAGvC,MAAM,WAAiC;EACtC,aAAa,iBAAiB,IAAI,IAAI;EACtC,gBAAgB,iBAAiB,IAAI,OAAO;CAC7C;CACA,IAAI,IAAI,WAAW,KAAA,GAAW,SAAS,SAAS,IAAI;CACpD,IAAI,eAAe,KAAA,GAAW,SAAS,aAAa;CACpD,IAAI,IAAI,cAAc,KAAA,GAAW,SAAS,YAAY,IAAI;CAC1D,IAAI,IAAI,UACP,SAAS,WAAW,EACnB,GAAI,IAAI,SAAS,kBACd,EAAE,iBAAiB,EAAE,GAAG,IAAI,SAAS,gBAAgB,EAAE,IACvD,CAAC,EACL;CAED,IAAI,IAAI,SACP,SAAS,UAAU,qBAAqB,IAAI,OAAO;CAEpD,OAAO;AACR;AAEA,SAAS,iBAAiB,SAAqD;CAC9E,OAAO,YAAY,KAAA,KAAa,QAAQ,YAAY;AACrD;;;;;;;AAQA,SAAS,qBAAqB,SAA+C;CAC5E,OAAO;EACN,YAAY,QAAQ,aAAa,CAAC,GAAG,IAAI,qBAAqB;EAC9D,UAAU,QAAQ,WAAW,CAAC,GAAG,KAAK,YAAY;GACjD,MAAM,OAAO;GACb,QAAQ,OAAO,UAAU;EAC1B,EAAE;EACF,kBAAkB,iBAAiB,QAAQ,SAAS;CACrD;AACD;AAEA,SAAS,sBAAsB,IAAoB;CAClD,OAAO;EACN,MAAM,GAAG;EACT,MAAM,GAAG;EACT,QAAQ,GAAG;EACX,KAAK,EAAE,GAAI,GAAG,OAAO,CAAC,EAAG;EACzB,SAAS,GAAG,WAAW;EACvB,WAAW,GAAG,aAAa;CAC5B;AACD;;;;;;AAOA,SAAgB,gBAAgB,QAAwB;CACvD,IAAI,cAAc,KAAK,MAAM,GAAG,OAAO;CACvC,OAAO,OAAO;AACf"}
1
+ {"version":3,"file":"define-config.js","names":[],"sources":["../../src/lib/define-config.ts"],"sourcesContent":["import { parseDuration } from \"./duration.js\";\nimport { ConfigValidationError } from \"./errors.js\";\nimport { branchConfigSchema, formatZodIssues } from \"./schema.js\";\nimport type {\n\tBranchTarget,\n\tConfig,\n\tFunctionConfig,\n\tPreviewConfig,\n\tResolvedBranchConfig,\n\tResolvedFunctionConfig,\n\tResolvedPreviewConfig,\n} from \"./types.js\";\n\n/** Default deploy parameters applied to functions that omit them in `neon.ts`. */\nconst DEFAULT_FUNCTION_RUNTIME = \"nodejs24\" as const;\nconst DEFAULT_FUNCTION_MEMORY_MIB = 512 as const;\n\nconst REGION_PREFIX = /^(aws|azure|gcp)-/;\n\n/**\n * Validate and freeze a Neon Platform branch policy.\n *\n * Used at the top of `neon.ts`:\n * ```ts\n * import { defineConfig } from \"@neondatabase/config/v1\";\n *\n * export default defineConfig((branch) => {\n * if (branch.name === \"main\") {\n * return { protected: true, auth: {} };\n * }\n * return { parent: \"main\", ttl: \"7d\" };\n * });\n * ```\n *\n * The `branch` parameter is a **read-only {@link BranchTarget} descriptor** of the branch\n * this policy invocation is deciding for — not a live branch handle. You don't mutate it\n * (`branch.protected = true` does nothing); you switch on its facts (`branch.name`,\n * `branch.isDefault`, `branch.exists`, …) and **return** the desired {@link BranchConfig}.\n * The same callback runs in two modes: against an existing branch (fields populated from\n * Neon) and during pre-create evaluation (`exists: false`, `id` undefined).\n *\n * Pure function — no I/O, no side effects. The returned policy validates its output every\n * time it is evaluated so errors point at the concrete branch target that triggered them.\n */\nexport function defineConfig<const C extends Config>(input: C): C {\n\tif (typeof input !== \"function\") {\n\t\tthrow new ConfigValidationError([\n\t\t\t\"defineConfig expects a function: `export default defineConfig((branch) => ({ ... }))`.\",\n\t\t\t\"Project-level config has moved to `neonctl link`; neon.ts now describes branch-level policy only.\",\n\t\t]);\n\t}\n\n\treturn Object.freeze(input) as C;\n}\n\n/**\n * Evaluate a branch policy for a specific branch target and return a normalized config.\n */\nexport function resolveConfig(\n\tconfig: Config,\n\tbranch: BranchTarget,\n): ResolvedBranchConfig {\n\tlet raw: unknown;\n\ttry {\n\t\traw = config(Object.freeze({ ...branch }));\n\t} catch (cause) {\n\t\tthrow new ConfigValidationError([\n\t\t\t`Config function threw while evaluating branch \"${branch.name}\".`,\n\t\t\t(cause as Error)?.message ?? String(cause),\n\t\t]);\n\t}\n\n\tconst parsed = branchConfigSchema.safeParse(raw);\n\tif (!parsed.success) {\n\t\tthrow new ConfigValidationError(formatZodIssues(parsed.error));\n\t}\n\n\tconst cfg = parsed.data;\n\tconst issues: string[] = [];\n\tlet ttlSeconds: number | undefined;\n\tif (cfg.ttl !== undefined) {\n\t\tconst parsedTtl = parseDuration(cfg.ttl);\n\t\tif (\"error\" in parsedTtl) {\n\t\t\tissues.push(`ttl: ${parsedTtl.error}`);\n\t\t} else {\n\t\t\tttlSeconds = parsedTtl.seconds;\n\t\t}\n\t}\n\tif (issues.length > 0) {\n\t\tthrow new ConfigValidationError(issues);\n\t}\n\n\tconst resolved: ResolvedBranchConfig = {\n\t\tauthEnabled: isServiceEnabled(cfg.auth),\n\t\tdataApiEnabled: isServiceEnabled(cfg.dataApi),\n\t};\n\tif (cfg.parent !== undefined) resolved.parent = cfg.parent;\n\tif (ttlSeconds !== undefined) resolved.ttlSeconds = ttlSeconds;\n\tif (cfg.protected !== undefined) resolved.protected = cfg.protected;\n\tif (cfg.postgres) {\n\t\tresolved.postgres = {\n\t\t\t...(cfg.postgres.computeSettings\n\t\t\t\t? { computeSettings: { ...cfg.postgres.computeSettings } }\n\t\t\t\t: {}),\n\t\t};\n\t}\n\tif (cfg.preview) {\n\t\tresolved.preview = resolvePreviewConfig(cfg.preview);\n\t}\n\treturn resolved;\n}\n\nfunction isServiceEnabled(service: { enabled?: boolean } | undefined): boolean {\n\treturn service !== undefined && service.enabled !== false;\n}\n\n/**\n * Normalize a {@link PreviewConfig} into a {@link ResolvedPreviewConfig}: apply per-function\n * deploy defaults, default each bucket's access level to `private`, and collapse the\n * `aiGateway` toggle to a boolean using the same present-and-not-`false` rule as\n * `auth` / `dataApi`.\n */\nfunction resolvePreviewConfig(preview: PreviewConfig): ResolvedPreviewConfig {\n\treturn {\n\t\tfunctions: (preview.functions ?? []).map(resolveFunctionConfig),\n\t\tbuckets: (preview.buckets ?? []).map((bucket) => ({\n\t\t\tname: bucket.name,\n\t\t\taccess: bucket.access ?? \"private\",\n\t\t})),\n\t\taiGatewayEnabled: isServiceEnabled(preview.aiGateway),\n\t};\n}\n\nfunction resolveFunctionConfig(fn: FunctionConfig): ResolvedFunctionConfig {\n\treturn {\n\t\tslug: fn.slug,\n\t\tname: fn.name,\n\t\tsource: fn.source,\n\t\tenv: { ...(fn.env ?? {}) },\n\t\truntime: fn.runtime ?? DEFAULT_FUNCTION_RUNTIME,\n\t\tmemoryMib: fn.memoryMib ?? DEFAULT_FUNCTION_MEMORY_MIB,\n\t\t// Passed through untouched (no defaults); only `neon dev` reads it.\n\t\t...(fn.dev ? { dev: fn.dev } : {}),\n\t};\n}\n\n/**\n * Normalize a region identifier to Neon's `<cloud>-<region>` format. When the user writes\n * `us-east-1` we assume `aws-us-east-1`. Pure helper used by both the validator and the\n * NeonApi adapter.\n */\nexport function normalizeRegion(region: string): string {\n\tif (REGION_PREFIX.test(region)) return region;\n\treturn `aws-${region}`;\n}\n"],"mappings":";;;;;AAcA,MAAM,2BAA2B;AACjC,MAAM,8BAA8B;AAEpC,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;AA2BtB,SAAgB,aAAqC,OAAa;CACjE,IAAI,OAAO,UAAU,YACpB,MAAM,IAAI,sBAAsB,CAC/B,0FACA,mGACD,CAAC;CAGF,OAAO,OAAO,OAAO,KAAK;AAC3B;;;;AAKA,SAAgB,cACf,QACA,QACuB;CACvB,IAAI;CACJ,IAAI;EACH,MAAM,OAAO,OAAO,OAAO,EAAE,GAAG,OAAO,CAAC,CAAC;CAC1C,SAAS,OAAO;EACf,MAAM,IAAI,sBAAsB,CAC/B,kDAAkD,OAAO,KAAK,KAC7D,OAAiB,WAAW,OAAO,KAAK,CAC1C,CAAC;CACF;CAEA,MAAM,SAAS,mBAAmB,UAAU,GAAG;CAC/C,IAAI,CAAC,OAAO,SACX,MAAM,IAAI,sBAAsB,gBAAgB,OAAO,KAAK,CAAC;CAG9D,MAAM,MAAM,OAAO;CACnB,MAAM,SAAmB,CAAC;CAC1B,IAAI;CACJ,IAAI,IAAI,QAAQ,KAAA,GAAW;EAC1B,MAAM,YAAY,cAAc,IAAI,GAAG;EACvC,IAAI,WAAW,WACd,OAAO,KAAK,QAAQ,UAAU,OAAO;OAErC,aAAa,UAAU;CAEzB;CACA,IAAI,OAAO,SAAS,GACnB,MAAM,IAAI,sBAAsB,MAAM;CAGvC,MAAM,WAAiC;EACtC,aAAa,iBAAiB,IAAI,IAAI;EACtC,gBAAgB,iBAAiB,IAAI,OAAO;CAC7C;CACA,IAAI,IAAI,WAAW,KAAA,GAAW,SAAS,SAAS,IAAI;CACpD,IAAI,eAAe,KAAA,GAAW,SAAS,aAAa;CACpD,IAAI,IAAI,cAAc,KAAA,GAAW,SAAS,YAAY,IAAI;CAC1D,IAAI,IAAI,UACP,SAAS,WAAW,EACnB,GAAI,IAAI,SAAS,kBACd,EAAE,iBAAiB,EAAE,GAAG,IAAI,SAAS,gBAAgB,EAAE,IACvD,CAAC,EACL;CAED,IAAI,IAAI,SACP,SAAS,UAAU,qBAAqB,IAAI,OAAO;CAEpD,OAAO;AACR;AAEA,SAAS,iBAAiB,SAAqD;CAC9E,OAAO,YAAY,KAAA,KAAa,QAAQ,YAAY;AACrD;;;;;;;AAQA,SAAS,qBAAqB,SAA+C;CAC5E,OAAO;EACN,YAAY,QAAQ,aAAa,CAAC,GAAG,IAAI,qBAAqB;EAC9D,UAAU,QAAQ,WAAW,CAAC,GAAG,KAAK,YAAY;GACjD,MAAM,OAAO;GACb,QAAQ,OAAO,UAAU;EAC1B,EAAE;EACF,kBAAkB,iBAAiB,QAAQ,SAAS;CACrD;AACD;AAEA,SAAS,sBAAsB,IAA4C;CAC1E,OAAO;EACN,MAAM,GAAG;EACT,MAAM,GAAG;EACT,QAAQ,GAAG;EACX,KAAK,EAAE,GAAI,GAAG,OAAO,CAAC,EAAG;EACzB,SAAS,GAAG,WAAW;EACvB,WAAW,GAAG,aAAa;EAE3B,GAAI,GAAG,MAAM,EAAE,KAAK,GAAG,IAAI,IAAI,CAAC;CACjC;AACD;;;;;;AAOA,SAAgB,gBAAgB,QAAwB;CACvD,IAAI,cAAc,KAAK,MAAM,GAAG,OAAO;CACvC,OAAO,OAAO;AACf"}
@@ -36,6 +36,13 @@ 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>>;
44
+ port: z.ZodOptional<z.ZodNumber>;
45
+ }, z.core.$strict>]>>;
39
46
  }, z.core.$strict>;
40
47
  declare const bucketConfigSchema: z.ZodObject<{
41
48
  name: z.ZodString;
@@ -49,6 +56,13 @@ declare const previewConfigSchema: z.ZodObject<{
49
56
  env: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
50
57
  runtime: z.ZodOptional<z.ZodLiteral<"nodejs24">>;
51
58
  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>>;
64
+ port: z.ZodOptional<z.ZodNumber>;
65
+ }, z.core.$strict>]>>;
52
66
  }, z.core.$strict>>>;
53
67
  buckets: z.ZodOptional<z.ZodArray<z.ZodObject<{
54
68
  name: z.ZodString;
@@ -83,6 +97,13 @@ declare const branchConfigSchema: z.ZodObject<{
83
97
  env: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
84
98
  runtime: z.ZodOptional<z.ZodLiteral<"nodejs24">>;
85
99
  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>>;
105
+ port: z.ZodOptional<z.ZodNumber>;
106
+ }, z.core.$strict>]>>;
86
107
  }, z.core.$strict>>>;
87
108
  buckets: z.ZodOptional<z.ZodArray<z.ZodObject<{
88
109
  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,cA0ErB,oBA1EqB,EA0ED,CAAA,CAAA,SA1EC,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;AAAA,CAAA,gBAAA,CAAA;AAInB,cAwCA,kBAtCX,EAsC6B,CAAA,CAAA,SAtC7B,CAAA;EAAA,IAAA,aAAA;;;cA6CW,qBAAmB,CAAA,CAAA;;;;;;;;;;;;;;;;;cAkDnB,oBAAkB,CAAA,CAAA;;;;;;MAjGE,qBAAA,eAAA,WAAA,CAAA,SAAA,aAAA,CAAA,IAAA,CAAA,cAAA,CAAA,GAAA,CAAA,cAAA,CAAA,CAAA,CAAA,cAAA,CAAA,CAAA,CAAA,cAAA,CAAA,CAAA,CAAA,cAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA;MAAA,qBAAA,eAAA,WAAA,CAAA,SAAA,aAAA,CAAA,IAAA,CAAA,cAAA,CAAA,GAAA,CAAA,cAAA,CAAA,CAAA,CAAA,cAAA,CAAA,CAAA,CAAA,cAAA,CAAA,CAAA,CAAA,cAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA;MAsBpB,cAAA,eAgBX,WAAA,CAAA,SAAA,aAAA,CAAA,KAAA,CAAA,aAAA,aAAA,CAAA,CAAA,CAAA;IAAA,CAAA,gBAAA,CAAA,CAAA;;;;;;;;;;;;;;;;;;;MAhB+B,MAAA,eAAA,WAAA,CAAA,SAAA,aAAA,CAAA,SAAA,CAAA,cAAA,CAAA,aAAA,CAAA,CAAA,CAAA,CAAA;IAAA,CAAA,gBAAA,CAAA,CAAA,CAAA;IAkBpB,SAAA,eAKX,YAAA,CAAA;MAAA,OAAA,eAAA,aAAA,CAAA;;;;cAmGW,cAAY,CAAA,CAAA,YAAA,CAAA,CAAA,mBAAA,CAAA,CAAA,oBAAA,CAAA,CAAA;;;;AAxGM;AAO/B;;;;;iBA+GgB,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,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"}
@@ -64,6 +64,24 @@ const functionSlugSchema = z.string().regex(/^[a-z0-9]([a-z0-9-]{0,38}[a-z0-9])?
64
64
  * shipping `undefined` into the deployment).
65
65
  */
66
66
  const functionEnvSchema = z.record(z.string(), z.string());
67
+ /**
68
+ * TCP port for a function's local dev server. Excludes 0 (which means "any port" to the OS
69
+ * — `neon dev` expresses "pick one for me" by omitting `port`, not by passing 0).
70
+ */
71
+ const devPortSchema = z.number().int().min(1).max(65535);
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.
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
+ })]);
67
85
  const functionConfigSchema = z.strictObject({
68
86
  slug: functionSlugSchema,
69
87
  name: z.string().min(1).max(255),
@@ -77,7 +95,8 @@ const functionConfigSchema = z.strictObject({
77
95
  z.literal(2048),
78
96
  z.literal(4096),
79
97
  z.literal(8192)
80
- ]).optional()
98
+ ]).optional(),
99
+ dev: functionDevConfigSchema.optional()
81
100
  });
82
101
  const bucketConfigSchema = z.strictObject({
83
102
  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\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});\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`): 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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"}
@@ -79,6 +79,26 @@ type FunctionRuntime = "nodejs24";
79
79
  * `memory_mib` enum in the spec.
80
80
  */
81
81
  type FunctionMemoryMib = 256 | 512 | 1024 | 2048 | 4096 | 8192;
82
+ /**
83
+ * Local-development settings for a function, used by `neon dev` when it serves every
84
+ * function declared in `neon.ts` (i.e. invoked with no `--source`). Never affects deploy.
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`.
89
+ *
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.
94
+ */
95
+ type FunctionDevConfig = {
96
+ portless: true;
97
+ port: number;
98
+ } | {
99
+ portless?: false;
100
+ port?: number;
101
+ };
82
102
  /**
83
103
  * A single Neon Function deployed to a branch (Preview feature).
84
104
  *
@@ -118,6 +138,11 @@ interface FunctionConfig {
118
138
  runtime?: FunctionRuntime;
119
139
  /** Memory allotted to each invocation, in MiB. Defaults to `512`. */
120
140
  memoryMib?: FunctionMemoryMib;
141
+ /**
142
+ * Local-development settings used by `neon dev` when serving every function from
143
+ * `neon.ts`. Ignored at deploy time. See {@link FunctionDevConfig}.
144
+ */
145
+ dev?: FunctionDevConfig;
121
146
  }
122
147
  /** Anonymous-access level for a branchable object-storage bucket. */
123
148
  type BucketAccessLevel = "private" | "public_read";
@@ -185,6 +210,11 @@ interface ResolvedFunctionConfig {
185
210
  env: Record<string, string>;
186
211
  runtime: FunctionRuntime;
187
212
  memoryMib: FunctionMemoryMib;
213
+ /**
214
+ * Local-development settings, passed through untouched from {@link FunctionConfig.dev}
215
+ * (no defaults applied). Only consumed by `neon dev`; deploy ignores it.
216
+ */
217
+ dev?: FunctionDevConfig;
188
218
  }
189
219
  /** A bucket with its access level defaulted to `private`. */
190
220
  interface ResolvedBucketConfig {
@@ -255,5 +285,5 @@ interface PushResult {
255
285
  conflicts: ConflictReport[];
256
286
  }
257
287
  //#endregion
258
- export { AppliedChange, BranchConfig, BranchTarget, BucketAccessLevel, BucketConfig, ComputeSettings, ComputeUnit, Config, ConflictReport, FunctionConfig, FunctionMemoryMib, FunctionRuntime, PostgresConfig, PreviewConfig, PushResult, ResolvedBranchConfig, ResolvedBucketConfig, ResolvedFunctionConfig, ResolvedPreviewConfig, ServiceToggle };
288
+ export { AppliedChange, BranchConfig, BranchTarget, BucketAccessLevel, BucketConfig, ComputeSettings, ComputeUnit, Config, ConflictReport, FunctionConfig, FunctionDevConfig, FunctionMemoryMib, FunctionRuntime, PostgresConfig, PreviewConfig, PushResult, ResolvedBranchConfig, ResolvedBucketConfig, ResolvedFunctionConfig, ResolvedPreviewConfig, ServiceToggle };
259
289
  //# sourceMappingURL=types.d.ts.map
@@ -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;AAUiB,UAlFA,eAAA,CAkFc;EAAA;;;;AA8BD;EAIlB,qBAAiB,CAAA,EA9GJ,WA8GI;EAKZ;AAcjB;;;;uBAMa,CAAA,EAjIY,WAiIZ;EAAa;AACzB;;;;AAcuB;AAAA;;;;;;AAOwB;EAEpC,cAAA,CAAY,EAAA,KAAA,GAAA,IAAA,GAAA,IAAA,GAAA,MAAA,GAAA,MAAA;;;;AAAyC;AAEjE;;;AAA+C,UApI9B,YAAA,CAoI8B;EAAY;EAM1C,IAAA,EAAA,MAAA;EAAsB;KAIjC,EAAA,MAAA;;QAEM,EAAA,OAAA;EAAiB;EAIZ,QAAA,CAAA,EAAA,MAAA;EAUA;EAAqB,SAAA,CAAA,EAAA,OAAA;;aAE5B,CAAA,EAAA,OAAA;EAAoB;EAIb,SAAA,CAAA,EAAA,MAAA;;AAIL,UAvJK,aAAA,CAuJL;;EAGoB,OAAA,CAAA,EAAA,OAAA;AAMhC;AAkBiB,UA7KA,cAAA,CA6Kc;EAYd,eAAU,CAAA,EAxLR,eAwLQ;;;;AAWD;;;KA3Ld,eAAA;;;;;KAMA,iBAAA;;;;;;;;;UAUK,cAAA;;;;;;;;;;;;;;;;;;;;;;;;;;QA0BV;;YAEI;;cAEE;;;KAID,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;;;UAIK,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;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"}
package/dist/v1.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { AppliedChange, BranchConfig, BranchTarget, BucketAccessLevel, BucketConfig, ComputeSettings, Config, ConflictReport, FunctionConfig, FunctionMemoryMib, FunctionRuntime, PostgresConfig, PreviewConfig, PushResult, ResolvedBranchConfig, ResolvedBucketConfig, ResolvedFunctionConfig, ResolvedPreviewConfig, ServiceToggle } from "./lib/types.js";
1
+ import { AppliedChange, BranchConfig, BranchTarget, BucketAccessLevel, BucketConfig, ComputeSettings, Config, ConflictReport, FunctionConfig, FunctionDevConfig, FunctionMemoryMib, FunctionRuntime, PostgresConfig, PreviewConfig, PushResult, ResolvedBranchConfig, ResolvedBucketConfig, ResolvedFunctionConfig, ResolvedPreviewConfig, ServiceToggle } from "./lib/types.js";
2
2
  import { ConfigLoadError, ConfigValidationError, ErrorCode, MissingContextError, PlatformError, PushAbortedError, PushConflictError } from "./lib/errors.js";
3
3
  import { CreateBranchInput, CreateBucketInput, CreateProjectInput, DeployFunctionInput, GetConnectionUriInput, NeonApi, NeonAuthSnapshot, NeonBranchSnapshot, NeonBucketSnapshot, NeonDataApiSnapshot, NeonDatabaseSnapshot, NeonEndpointSnapshot, NeonFunctionDeploymentSnapshot, NeonFunctionSnapshot, NeonProjectSnapshot, NeonRoleSnapshot, UpdateBranchInput } from "./lib/neon-api.js";
4
4
  import { createNeonApiFromOptions, resolveApiKey } from "./lib/auth.js";
@@ -71,6 +71,13 @@ declare const schemas: {
71
71
  env: zod0.ZodOptional<zod0.ZodRecord<zod0.ZodString, zod0.ZodString>>;
72
72
  runtime: zod0.ZodOptional<zod0.ZodLiteral<"nodejs24">>;
73
73
  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>>;
79
+ port: zod0.ZodOptional<zod0.ZodNumber>;
80
+ }, zod_v4_core0.$strict>]>>;
74
81
  }, zod_v4_core0.$strict>>>;
75
82
  buckets: zod0.ZodOptional<zod0.ZodArray<zod0.ZodObject<{
76
83
  name: zod0.ZodString;
@@ -98,6 +105,13 @@ declare const schemas: {
98
105
  env: zod0.ZodOptional<zod0.ZodRecord<zod0.ZodString, zod0.ZodString>>;
99
106
  runtime: zod0.ZodOptional<zod0.ZodLiteral<"nodejs24">>;
100
107
  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>>;
113
+ port: zod0.ZodOptional<zod0.ZodNumber>;
114
+ }, zod_v4_core0.$strict>]>>;
101
115
  }, zod_v4_core0.$strict>;
102
116
  readonly postgres: zod0.ZodObject<{
103
117
  computeSettings: zod0.ZodOptional<zod0.ZodObject<{
@@ -114,6 +128,13 @@ declare const schemas: {
114
128
  env: zod0.ZodOptional<zod0.ZodRecord<zod0.ZodString, zod0.ZodString>>;
115
129
  runtime: zod0.ZodOptional<zod0.ZodLiteral<"nodejs24">>;
116
130
  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>>;
136
+ port: zod0.ZodOptional<zod0.ZodNumber>;
137
+ }, zod_v4_core0.$strict>]>>;
117
138
  }, zod_v4_core0.$strict>>>;
118
139
  buckets: zod0.ZodOptional<zod0.ZodArray<zod0.ZodObject<{
119
140
  name: zod0.ZodString;
@@ -128,5 +149,5 @@ declare const schemas: {
128
149
  }, zod_v4_core0.$strict>;
129
150
  };
130
151
  //#endregion
131
- export { type AppliedChange, type BranchConfig, type BranchTarget, type BucketAccessLevel, type BucketConfig, type ComputeSettings, type Config, ConfigLoadError, ConfigValidationError, type ConflictReport, type CreateBranchInput, type CreateBucketInput, type CreateProjectInput, type DeployFunctionInput, type DiffOptions, type DiffResult, ErrorCode, type FunctionConfig, type FunctionMemoryMib, type FunctionRuntime, type GetConnectionUriInput, type LoadConfigOptions, MissingContextError, type NeonApi, type NeonAuthSnapshot, type NeonBranchSnapshot, type NeonBucketSnapshot, type NeonDataApiSnapshot, type NeonDatabaseSnapshot, type NeonEndpointSnapshot, type NeonFunctionDeploymentSnapshot, type NeonFunctionSnapshot, type NeonProjectSnapshot, type NeonRoleSnapshot, type PlanStep, PlatformError, type PostgresConfig, type PreviewConfig, PushAbortedError, PushConflictError, type PushResult, type RemotePreviewState, type RemoteServiceState, type RemoteState, type ResolvedBranchConfig, type ResolvedBucketConfig, type ResolvedFunctionConfig, type ResolvedPreviewConfig, type ServiceToggle, type UpdateBranchInput, createNeonApiFromOptions, createRealNeonApi, defineConfig, diffConfig, errors, loadConfigFromFile, resolveApiKey, resolveConfig, schemas };
152
+ export { type AppliedChange, type BranchConfig, type BranchTarget, type BucketAccessLevel, type BucketConfig, type ComputeSettings, type Config, ConfigLoadError, ConfigValidationError, type ConflictReport, type CreateBranchInput, type CreateBucketInput, type CreateProjectInput, type DeployFunctionInput, type DiffOptions, type DiffResult, ErrorCode, type FunctionConfig, type FunctionDevConfig, type FunctionMemoryMib, type FunctionRuntime, type GetConnectionUriInput, type LoadConfigOptions, MissingContextError, type NeonApi, type NeonAuthSnapshot, type NeonBranchSnapshot, type NeonBucketSnapshot, type NeonDataApiSnapshot, type NeonDatabaseSnapshot, type NeonEndpointSnapshot, type NeonFunctionDeploymentSnapshot, type NeonFunctionSnapshot, type NeonProjectSnapshot, type NeonRoleSnapshot, type PlanStep, PlatformError, type PostgresConfig, type PreviewConfig, PushAbortedError, PushConflictError, type PushResult, type RemotePreviewState, type RemoteServiceState, type RemoteState, type ResolvedBranchConfig, type ResolvedBucketConfig, type ResolvedFunctionConfig, type ResolvedPreviewConfig, type ServiceToggle, type UpdateBranchInput, createNeonApiFromOptions, createRealNeonApi, defineConfig, diffConfig, errors, loadConfigFromFile, resolveApiKey, resolveConfig, schemas };
132
153
  //# sourceMappingURL=v1.d.ts.map
package/dist/v1.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"v1.js","names":[],"sources":["../src/v1.ts"],"sourcesContent":["/**\n * `@neondatabase/config/v1` — the v1 public API for Config-as-Code on the Neon Platform.\n *\n * Usage in `neon.ts`:\n * ```ts\n * import { defineConfig } from \"@neondatabase/config/v1\";\n *\n * export default defineConfig((branch) => {\n * if (branch.name === \"main\") return { protected: true, auth: {} };\n * return { parent: \"main\", ttl: \"7d\" };\n * });\n * ```\n *\n * This is the **authoring** surface — `defineConfig`, types, schemas, the pure diff engine,\n * and the Neon API adapter. It is intentionally free of heavy/native dependencies so that\n * importing it from `neon.ts` stays cheap and bundler-safe.\n *\n * The imperative operations (`inspect` / `plan` / `apply`, `pushConfig` / `pullConfig`) and\n * function bundling/deploy live in **`@neondatabase/config-runtime`**, which depends on this\n * package and pulls in `esbuild`. Import that from your CLI / CI, not from `neon.ts`:\n * ```ts\n * import config from \"../neon\";\n * import { inspect, plan, apply } from \"@neondatabase/config-runtime/v1\";\n * ```\n *\n * Surface guidelines:\n * - Top-level: `defineConfig` / `resolveConfig`, the pure `diffConfig` engine, the\n * `createRealNeonApi` adapter + `NeonApi` types, the config loader, the `PlatformError`\n * base class + `ErrorCode` enum, and the config types used in `neon.ts`.\n * - `errors` namespace: specific `PlatformError` subclasses (`ConfigLoadError`,\n * `PushConflictError`, …).\n * - `schemas` namespace: the zod schemas underlying `defineConfig`.\n */\n\nimport {\n\tConfigLoadError,\n\tConfigValidationError,\n\tErrorCode,\n\tMissingContextError,\n\tPlatformError,\n\tPushAbortedError,\n\tPushConflictError,\n} from \"./lib/errors.js\";\nimport {\n\tbranchConfigSchema,\n\tbucketConfigSchema,\n\tcomputeSettingsSchema,\n\tconfigSchema,\n\tfunctionConfigSchema,\n\tpostgresConfigSchema,\n\tpreviewConfigSchema,\n\tserviceToggleSchema,\n} from \"./lib/schema.js\";\n\n/**\n * Specific `PlatformError` subclasses, grouped for `instanceof` / structured access.\n * Also available as top-level exports.\n */\nexport const errors = {\n\tConfigLoadError,\n\tConfigValidationError,\n\tErrorCode,\n\tMissingContextError,\n\tPlatformError,\n\tPushAbortedError,\n\tPushConflictError,\n} as const;\n\n/** The zod schemas underlying `defineConfig`, grouped under product-friendly names. */\nexport const schemas = {\n\tbranch: branchConfigSchema,\n\tbucket: bucketConfigSchema,\n\tcomputeSettings: computeSettingsSchema,\n\tconfig: configSchema,\n\tfunction: functionConfigSchema,\n\tpostgres: postgresConfigSchema,\n\tpreview: previewConfigSchema,\n\tservice: serviceToggleSchema,\n} as const;\n\n// ─── Lower-level adapters ──────────────────────────────────────────────────────\nexport { createNeonApiFromOptions, resolveApiKey } from \"./lib/auth.js\";\nexport { defineConfig, resolveConfig } from \"./lib/define-config.js\";\n// ─── Diff engine (pure; consumed by @neondatabase/config-runtime) ─────────────\nexport type {\n\tDiffOptions,\n\tDiffResult,\n\tPlanStep,\n\tRemotePreviewState,\n\tRemoteServiceState,\n\tRemoteState,\n} from \"./lib/diff.js\";\nexport { diffConfig } from \"./lib/diff.js\";\n// ─── Errors ────────────────────────────────────────────────────────────────────\nexport {\n\tConfigLoadError,\n\tConfigValidationError,\n\tErrorCode,\n\tMissingContextError,\n\tPlatformError,\n\tPushAbortedError,\n\tPushConflictError,\n} from \"./lib/errors.js\";\nexport type { LoadConfigOptions } from \"./lib/loader.js\";\nexport { loadConfigFromFile } from \"./lib/loader.js\";\n// ─── NeonApi types (needed by callers implementing their own adapters) ────────\nexport 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 \"./lib/neon-api.js\";\nexport { createRealNeonApi } from \"./lib/neon-api-real.js\";\n// ─── Config types (used in neon.ts and in operation return values) ────────────\nexport type {\n\tAppliedChange,\n\tBranchConfig,\n\tBranchTarget,\n\tBucketAccessLevel,\n\tBucketConfig,\n\tComputeSettings,\n\tConfig,\n\tConflictReport,\n\tFunctionConfig,\n\tFunctionMemoryMib,\n\tFunctionRuntime,\n\tPostgresConfig,\n\tPreviewConfig,\n\tPushResult,\n\tResolvedBranchConfig,\n\tResolvedBucketConfig,\n\tResolvedFunctionConfig,\n\tResolvedPreviewConfig,\n\tServiceToggle,\n} from \"./lib/types.js\";\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA0DA,MAAa,SAAS;CACrB;CACA;CACA;CACA;CACA;CACA;CACA;AACD;;AAGA,MAAa,UAAU;CACtB,QAAQ;CACR,QAAQ;CACR,iBAAiB;CACjB,QAAQ;CACR,UAAU;CACV,UAAU;CACV,SAAS;CACT,SAAS;AACV"}
1
+ {"version":3,"file":"v1.js","names":[],"sources":["../src/v1.ts"],"sourcesContent":["/**\n * `@neondatabase/config/v1` — the v1 public API for Config-as-Code on the Neon Platform.\n *\n * Usage in `neon.ts`:\n * ```ts\n * import { defineConfig } from \"@neondatabase/config/v1\";\n *\n * export default defineConfig((branch) => {\n * if (branch.name === \"main\") return { protected: true, auth: {} };\n * return { parent: \"main\", ttl: \"7d\" };\n * });\n * ```\n *\n * This is the **authoring** surface — `defineConfig`, types, schemas, the pure diff engine,\n * and the Neon API adapter. It is intentionally free of heavy/native dependencies so that\n * importing it from `neon.ts` stays cheap and bundler-safe.\n *\n * The imperative operations (`inspect` / `plan` / `apply`, `pushConfig` / `pullConfig`) and\n * function bundling/deploy live in **`@neondatabase/config-runtime`**, which depends on this\n * package and pulls in `esbuild`. Import that from your CLI / CI, not from `neon.ts`:\n * ```ts\n * import config from \"../neon\";\n * import { inspect, plan, apply } from \"@neondatabase/config-runtime/v1\";\n * ```\n *\n * Surface guidelines:\n * - Top-level: `defineConfig` / `resolveConfig`, the pure `diffConfig` engine, the\n * `createRealNeonApi` adapter + `NeonApi` types, the config loader, the `PlatformError`\n * base class + `ErrorCode` enum, and the config types used in `neon.ts`.\n * - `errors` namespace: specific `PlatformError` subclasses (`ConfigLoadError`,\n * `PushConflictError`, …).\n * - `schemas` namespace: the zod schemas underlying `defineConfig`.\n */\n\nimport {\n\tConfigLoadError,\n\tConfigValidationError,\n\tErrorCode,\n\tMissingContextError,\n\tPlatformError,\n\tPushAbortedError,\n\tPushConflictError,\n} from \"./lib/errors.js\";\nimport {\n\tbranchConfigSchema,\n\tbucketConfigSchema,\n\tcomputeSettingsSchema,\n\tconfigSchema,\n\tfunctionConfigSchema,\n\tpostgresConfigSchema,\n\tpreviewConfigSchema,\n\tserviceToggleSchema,\n} from \"./lib/schema.js\";\n\n/**\n * Specific `PlatformError` subclasses, grouped for `instanceof` / structured access.\n * Also available as top-level exports.\n */\nexport const errors = {\n\tConfigLoadError,\n\tConfigValidationError,\n\tErrorCode,\n\tMissingContextError,\n\tPlatformError,\n\tPushAbortedError,\n\tPushConflictError,\n} as const;\n\n/** The zod schemas underlying `defineConfig`, grouped under product-friendly names. */\nexport const schemas = {\n\tbranch: branchConfigSchema,\n\tbucket: bucketConfigSchema,\n\tcomputeSettings: computeSettingsSchema,\n\tconfig: configSchema,\n\tfunction: functionConfigSchema,\n\tpostgres: postgresConfigSchema,\n\tpreview: previewConfigSchema,\n\tservice: serviceToggleSchema,\n} as const;\n\n// ─── Lower-level adapters ──────────────────────────────────────────────────────\nexport { createNeonApiFromOptions, resolveApiKey } from \"./lib/auth.js\";\nexport { defineConfig, resolveConfig } from \"./lib/define-config.js\";\n// ─── Diff engine (pure; consumed by @neondatabase/config-runtime) ─────────────\nexport type {\n\tDiffOptions,\n\tDiffResult,\n\tPlanStep,\n\tRemotePreviewState,\n\tRemoteServiceState,\n\tRemoteState,\n} from \"./lib/diff.js\";\nexport { diffConfig } from \"./lib/diff.js\";\n// ─── Errors ────────────────────────────────────────────────────────────────────\nexport {\n\tConfigLoadError,\n\tConfigValidationError,\n\tErrorCode,\n\tMissingContextError,\n\tPlatformError,\n\tPushAbortedError,\n\tPushConflictError,\n} from \"./lib/errors.js\";\nexport type { LoadConfigOptions } from \"./lib/loader.js\";\nexport { loadConfigFromFile } from \"./lib/loader.js\";\n// ─── NeonApi types (needed by callers implementing their own adapters) ────────\nexport 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 \"./lib/neon-api.js\";\nexport { createRealNeonApi } from \"./lib/neon-api-real.js\";\n// ─── Config types (used in neon.ts and in operation return values) ────────────\nexport type {\n\tAppliedChange,\n\tBranchConfig,\n\tBranchTarget,\n\tBucketAccessLevel,\n\tBucketConfig,\n\tComputeSettings,\n\tConfig,\n\tConflictReport,\n\tFunctionConfig,\n\tFunctionDevConfig,\n\tFunctionMemoryMib,\n\tFunctionRuntime,\n\tPostgresConfig,\n\tPreviewConfig,\n\tPushResult,\n\tResolvedBranchConfig,\n\tResolvedBucketConfig,\n\tResolvedFunctionConfig,\n\tResolvedPreviewConfig,\n\tServiceToggle,\n} from \"./lib/types.js\";\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA0DA,MAAa,SAAS;CACrB;CACA;CACA;CACA;CACA;CACA;CACA;AACD;;AAGA,MAAa,UAAU;CACtB,QAAQ;CACR,QAAQ;CACR,iBAAiB;CACjB,QAAQ;CACR,UAAU;CACV,UAAU;CACV,SAAS;CACT,SAAS;AACV"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@neondatabase/config",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
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",