@neondatabase/config 0.2.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +20 -7
- package/dist/index.d.ts +2 -2
- package/dist/lib/define-config.d.ts +32 -15
- package/dist/lib/define-config.d.ts.map +1 -1
- package/dist/lib/define-config.js +79 -58
- package/dist/lib/define-config.js.map +1 -1
- package/dist/lib/errors.d.ts +1 -0
- package/dist/lib/errors.d.ts.map +1 -1
- package/dist/lib/errors.js +1 -0
- package/dist/lib/errors.js.map +1 -1
- package/dist/lib/neon-api-real.d.ts +43 -2
- package/dist/lib/neon-api-real.d.ts.map +1 -1
- package/dist/lib/neon-api-real.js +85 -19
- package/dist/lib/neon-api-real.js.map +1 -1
- package/dist/lib/neon-api.d.ts +1 -2
- package/dist/lib/neon-api.d.ts.map +1 -1
- package/dist/lib/schema.d.ts +61 -50
- package/dist/lib/schema.d.ts.map +1 -1
- package/dist/lib/schema.js +52 -72
- package/dist/lib/schema.js.map +1 -1
- package/dist/lib/types.d.ts +129 -75
- package/dist/lib/types.d.ts.map +1 -1
- package/dist/v1.d.ts +48 -55
- package/dist/v1.d.ts.map +1 -1
- package/dist/v1.js +9 -7
- package/dist/v1.js.map +1 -1
- package/package.json +1 -1
package/dist/lib/schema.js
CHANGED
|
@@ -51,13 +51,21 @@ const computeSettingsSchema = z.strictObject({
|
|
|
51
51
|
message: `autoscalingLimitMinCu (${min}) must be <= autoscalingLimitMaxCu (${max})`
|
|
52
52
|
});
|
|
53
53
|
});
|
|
54
|
+
/** Object form of a service toggle (`{ enabled?: boolean }`). */
|
|
54
55
|
const serviceToggleSchema = z.strictObject({ enabled: z.boolean().optional() });
|
|
56
|
+
/** A service toggle as written in a policy: `boolean` or `{ enabled?: boolean }`. */
|
|
57
|
+
const serviceToggleInputSchema = z.union([z.boolean(), serviceToggleSchema]);
|
|
55
58
|
const postgresConfigSchema = z.strictObject({ computeSettings: computeSettingsSchema.optional() });
|
|
56
59
|
/**
|
|
57
60
|
* Branch-unique function slug. Mirrors the Neon Functions API path-segment rule
|
|
58
|
-
* (`platform/internal/platform/functions/name.go`): lowercase
|
|
61
|
+
* (`platform/internal/platform/functions/name.go`): 1–20 lowercase letters and digits.
|
|
62
|
+
* Used as the **key schema** of the `preview.functions` record, so a bad slug fails
|
|
63
|
+
* validation with a path pointing at the offending key and duplicate slugs are impossible
|
|
64
|
+
* by construction (object keys are unique).
|
|
59
65
|
*/
|
|
60
|
-
const functionSlugSchema = z.string().regex(/^[a-z0-9]
|
|
66
|
+
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)");
|
|
67
|
+
/** Bucket name: 1–255 chars. Used as the key schema of the `preview.buckets` record. */
|
|
68
|
+
const bucketNameSchema = z.string().min(1).max(255);
|
|
61
69
|
/**
|
|
62
70
|
* Per-function environment map. Every value must be a defined string: a `process.env.X`
|
|
63
71
|
* that is unset surfaces as `undefined` and is rejected here (rather than silently
|
|
@@ -70,77 +78,44 @@ const functionEnvSchema = z.record(z.string(), z.string());
|
|
|
70
78
|
*/
|
|
71
79
|
const devPortSchema = z.number().int().min(1).max(65535);
|
|
72
80
|
/**
|
|
73
|
-
* Local-dev settings for a function (`neon dev` only; never affects deploy).
|
|
74
|
-
*
|
|
75
|
-
*
|
|
76
|
-
*
|
|
81
|
+
* Local-dev settings for a function (`neon dev` only; never affects deploy). `port` and
|
|
82
|
+
* `portless` are independent: when `portless` is true, portless assigns the port itself
|
|
83
|
+
* (so `port` is ignored); otherwise `port` is bound exactly when set, or a free port is
|
|
84
|
+
* found when omitted.
|
|
77
85
|
*/
|
|
78
|
-
const functionDevConfigSchema = z.
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
})
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
86
|
+
const functionDevConfigSchema = z.strictObject({
|
|
87
|
+
port: devPortSchema.optional(),
|
|
88
|
+
portless: z.boolean().optional()
|
|
89
|
+
});
|
|
90
|
+
const runtimeSchema = z.literal("nodejs24");
|
|
91
|
+
/**
|
|
92
|
+
* Static definition of a function (existence). The slug is the record key (validated by
|
|
93
|
+
* {@link functionSlugSchema}), so it is not a field here. Deploy tuning (`runtime`) lives
|
|
94
|
+
* in the `branch` closure, not here.
|
|
95
|
+
*/
|
|
96
|
+
const functionDefSchema = z.strictObject({
|
|
87
97
|
name: z.string().min(1).max(255),
|
|
88
98
|
source: z.string().min(1),
|
|
89
99
|
env: functionEnvSchema.optional(),
|
|
90
|
-
runtime: z.literal("nodejs24").optional(),
|
|
91
|
-
memoryMib: z.union([
|
|
92
|
-
z.literal(256),
|
|
93
|
-
z.literal(512),
|
|
94
|
-
z.literal(1024),
|
|
95
|
-
z.literal(2048),
|
|
96
|
-
z.literal(4096),
|
|
97
|
-
z.literal(8192)
|
|
98
|
-
]).optional(),
|
|
99
100
|
dev: functionDevConfigSchema.optional()
|
|
100
101
|
});
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
functions: z.
|
|
107
|
-
buckets: z.
|
|
108
|
-
aiGateway: serviceToggleSchema.optional()
|
|
109
|
-
}).superRefine((preview, ctx) => {
|
|
110
|
-
assertUnique({
|
|
111
|
-
ctx,
|
|
112
|
-
path: ["functions"],
|
|
113
|
-
items: preview.functions ?? [],
|
|
114
|
-
key: (fn) => fn.slug,
|
|
115
|
-
label: "function slug"
|
|
116
|
-
});
|
|
117
|
-
assertUnique({
|
|
118
|
-
ctx,
|
|
119
|
-
path: ["buckets"],
|
|
120
|
-
items: preview.buckets ?? [],
|
|
121
|
-
key: (bucket) => bucket.name,
|
|
122
|
-
label: "bucket name"
|
|
123
|
-
});
|
|
102
|
+
/** Static definition of a bucket (existence). Name is the record key. */
|
|
103
|
+
const bucketDefSchema = z.strictObject({ access: z.union([z.literal("private"), z.literal("public_read")]).optional() });
|
|
104
|
+
/** Static, beta Preview feature set: AI Gateway toggle + functions/buckets records. */
|
|
105
|
+
const previewInputSchema = z.strictObject({
|
|
106
|
+
aiGateway: serviceToggleInputSchema.optional(),
|
|
107
|
+
functions: z.record(functionSlugSchema, functionDefSchema).optional(),
|
|
108
|
+
buckets: z.record(bucketNameSchema, bucketDefSchema).optional()
|
|
124
109
|
});
|
|
110
|
+
/** Per-function deploy tuning returned by the `branch` closure. */
|
|
111
|
+
const functionTuningSchema = z.strictObject({ runtime: runtimeSchema.optional() });
|
|
112
|
+
/** Per-branch Preview tuning. Keys must be slugs declared in the static `preview`. */
|
|
113
|
+
const previewTuningSchema = z.strictObject({ functions: z.record(functionSlugSchema, functionTuningSchema).optional() });
|
|
125
114
|
/**
|
|
126
|
-
*
|
|
127
|
-
*
|
|
128
|
-
* at apply time.
|
|
115
|
+
* The object returned by the `branch` closure. Validated on every `resolveConfig` call so
|
|
116
|
+
* tuning errors point at the concrete branch target that triggered them.
|
|
129
117
|
*/
|
|
130
|
-
|
|
131
|
-
const { ctx, path, items, key, label } = args;
|
|
132
|
-
const seen = /* @__PURE__ */ new Set();
|
|
133
|
-
items.forEach((item, index) => {
|
|
134
|
-
const value = key(item);
|
|
135
|
-
if (seen.has(value)) ctx.addIssue({
|
|
136
|
-
code: "custom",
|
|
137
|
-
path: [...path, index],
|
|
138
|
-
message: `duplicate ${label}: ${JSON.stringify(value)}`
|
|
139
|
-
});
|
|
140
|
-
seen.add(value);
|
|
141
|
-
});
|
|
142
|
-
}
|
|
143
|
-
const branchConfigSchema = z.strictObject({
|
|
118
|
+
const branchTuningSchema = z.strictObject({
|
|
144
119
|
parent: z.string().optional(),
|
|
145
120
|
protected: z.boolean().optional(),
|
|
146
121
|
ttl: z.union([z.string(), z.number()]).optional().superRefine((value, ctx) => {
|
|
@@ -152,9 +127,7 @@ const branchConfigSchema = z.strictObject({
|
|
|
152
127
|
});
|
|
153
128
|
}),
|
|
154
129
|
postgres: postgresConfigSchema.optional(),
|
|
155
|
-
|
|
156
|
-
dataApi: serviceToggleSchema.optional(),
|
|
157
|
-
preview: previewConfigSchema.optional()
|
|
130
|
+
preview: previewTuningSchema.optional()
|
|
158
131
|
}).superRefine((cfg, ctx) => {
|
|
159
132
|
validateParentReference({
|
|
160
133
|
ctx,
|
|
@@ -162,6 +135,17 @@ const branchConfigSchema = z.strictObject({
|
|
|
162
135
|
parent: cfg.parent
|
|
163
136
|
});
|
|
164
137
|
});
|
|
138
|
+
/**
|
|
139
|
+
* The top-level object accepted by `defineConfig`. The `branch` closure is validated
|
|
140
|
+
* structurally as a function here; its returned tuning is validated per-evaluation by
|
|
141
|
+
* {@link branchTuningSchema} inside `resolveConfig`.
|
|
142
|
+
*/
|
|
143
|
+
const configInputSchema = z.strictObject({
|
|
144
|
+
auth: serviceToggleInputSchema.optional(),
|
|
145
|
+
dataApi: serviceToggleInputSchema.optional(),
|
|
146
|
+
preview: previewInputSchema.optional(),
|
|
147
|
+
branch: z.custom((value) => typeof value === "function", { message: "branch must be a function: `branch: (branch) => ({ … })`" }).optional()
|
|
148
|
+
});
|
|
165
149
|
function validateParentReference(args) {
|
|
166
150
|
const { ctx, path, parent } = args;
|
|
167
151
|
if (parent === void 0) return;
|
|
@@ -177,10 +161,6 @@ function validateParentReference(args) {
|
|
|
177
161
|
message: `parent must be a concrete branch name (no wildcards), got "${parent}"`
|
|
178
162
|
});
|
|
179
163
|
}
|
|
180
|
-
const configSchema = z.function({
|
|
181
|
-
input: [z.unknown()],
|
|
182
|
-
output: z.unknown()
|
|
183
|
-
});
|
|
184
164
|
/**
|
|
185
165
|
* Convert the structured {@link z.ZodError} produced by `configSchema.safeParse` into the
|
|
186
166
|
* `string[]` shape used by {@link import("./errors.js").ConfigValidationError}.
|
|
@@ -213,6 +193,6 @@ function normaliseIssueMessage(issue) {
|
|
|
213
193
|
return issue.message;
|
|
214
194
|
}
|
|
215
195
|
//#endregion
|
|
216
|
-
export {
|
|
196
|
+
export { branchTuningSchema, bucketDefSchema, computeSettingsSchema, configInputSchema, formatZodIssues, functionDefSchema, functionTuningSchema, postgresConfigSchema, previewInputSchema, serviceToggleInputSchema, serviceToggleSchema };
|
|
217
197
|
|
|
218
198
|
//# sourceMappingURL=schema.js.map
|
package/dist/lib/schema.js.map
CHANGED
|
@@ -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\n/** Object form of a service toggle (`{ enabled?: boolean }`). */\nexport const serviceToggleSchema = z.strictObject({\n\tenabled: z.boolean().optional(),\n});\n\n/** A service toggle as written in a policy: `boolean` or `{ enabled?: boolean }`. */\nexport const serviceToggleInputSchema = z.union([\n\tz.boolean(),\n\tserviceToggleSchema,\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 * Used as the **key schema** of the `preview.functions` record, so a bad slug fails\n * validation with a path pointing at the offending key and duplicate slugs are impossible\n * by construction (object keys are unique).\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/** Bucket name: 1–255 chars. Used as the key schema of the `preview.buckets` record. */\nconst bucketNameSchema = z.string().min(1).max(255);\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\nconst runtimeSchema = z.literal(\"nodejs24\");\n\n/**\n * Static definition of a function (existence). The slug is the record key (validated by\n * {@link functionSlugSchema}), so it is not a field here. Deploy tuning (`runtime`) lives\n * in the `branch` closure, not here.\n */\nexport const functionDefSchema = z.strictObject({\n\tname: z.string().min(1).max(255),\n\tsource: z.string().min(1),\n\tenv: functionEnvSchema.optional(),\n\tdev: functionDevConfigSchema.optional(),\n});\n\n/** Static definition of a bucket (existence). Name is the record key. */\nexport const bucketDefSchema = z.strictObject({\n\taccess: z\n\t\t.union([z.literal(\"private\"), z.literal(\"public_read\")])\n\t\t.optional(),\n});\n\n/** Static, beta Preview feature set: AI Gateway toggle + functions/buckets records. */\nexport const previewInputSchema = z.strictObject({\n\taiGateway: serviceToggleInputSchema.optional(),\n\tfunctions: z.record(functionSlugSchema, functionDefSchema).optional(),\n\tbuckets: z.record(bucketNameSchema, bucketDefSchema).optional(),\n});\n\n/** Per-function deploy tuning returned by the `branch` closure. */\nexport const functionTuningSchema = z.strictObject({\n\truntime: runtimeSchema.optional(),\n});\n\n/** Per-branch Preview tuning. Keys must be slugs declared in the static `preview`. */\nconst previewTuningSchema = z.strictObject({\n\tfunctions: z.record(functionSlugSchema, functionTuningSchema).optional(),\n});\n\n/**\n * The object returned by the `branch` closure. Validated on every `resolveConfig` call so\n * tuning errors point at the concrete branch target that triggered them.\n */\nexport const branchTuningSchema = 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\tpreview: previewTuningSchema.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\n/**\n * The top-level object accepted by `defineConfig`. The `branch` closure is validated\n * structurally as a function here; its returned tuning is validated per-evaluation by\n * {@link branchTuningSchema} inside `resolveConfig`.\n */\nexport const configInputSchema = z.strictObject({\n\tauth: serviceToggleInputSchema.optional(),\n\tdataApi: serviceToggleInputSchema.optional(),\n\tpreview: previewInputSchema.optional(),\n\tbranch: z\n\t\t.custom<(...args: unknown[]) => unknown>(\n\t\t\t(value) => typeof value === \"function\",\n\t\t\t{\n\t\t\t\tmessage:\n\t\t\t\t\t\"branch must be a function: `branch: (branch) => ({ … })`\",\n\t\t\t},\n\t\t)\n\t\t.optional(),\n});\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\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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"}
|
package/dist/lib/types.d.ts
CHANGED
|
@@ -61,10 +61,26 @@ interface BranchTarget {
|
|
|
61
61
|
/** Current expiration timestamp from Neon, when set. */
|
|
62
62
|
expiresAt?: string;
|
|
63
63
|
}
|
|
64
|
+
/**
|
|
65
|
+
* Object form of a branch-scoped service toggle. `{}` or `{ enabled: true }` enables it;
|
|
66
|
+
* `{ enabled: false }` opts out. Used as the object half of {@link ServiceToggleInput}.
|
|
67
|
+
*/
|
|
64
68
|
interface ServiceToggle {
|
|
65
69
|
/** Defaults to `true` when the service namespace is present. Set `false` to opt out. */
|
|
66
70
|
enabled?: boolean;
|
|
67
71
|
}
|
|
72
|
+
/**
|
|
73
|
+
* How a branch-scoped service (Neon Auth, Data API, AI Gateway) is toggled in a policy.
|
|
74
|
+
*
|
|
75
|
+
* - `true` / `{}` / `{ enabled: true }` — enabled.
|
|
76
|
+
* - `false` / `{ enabled: false }` — disabled.
|
|
77
|
+
* - omitted (`undefined`) — not part of the policy at all.
|
|
78
|
+
*
|
|
79
|
+
* These toggles are **static** (they live in the top-level `defineConfig({ … })` object,
|
|
80
|
+
* not in the per-branch `branch` closure) so the secret set they imply can be derived at
|
|
81
|
+
* the type level — that's what makes `NeonEnv<typeof config>` exact.
|
|
82
|
+
*/
|
|
83
|
+
type ServiceToggleInput = boolean | ServiceToggle;
|
|
68
84
|
interface PostgresConfig {
|
|
69
85
|
computeSettings?: ComputeSettings;
|
|
70
86
|
}
|
|
@@ -74,46 +90,46 @@ interface PostgresConfig {
|
|
|
74
90
|
* non-breaking, type-checked change.
|
|
75
91
|
*/
|
|
76
92
|
type FunctionRuntime = "nodejs24";
|
|
77
|
-
/**
|
|
78
|
-
* Memory sizes (MiB) accepted by the Neon Functions deploy API. Mirrors the
|
|
79
|
-
* `memory_mib` enum in the spec.
|
|
80
|
-
*/
|
|
81
|
-
type FunctionMemoryMib = 256 | 512 | 1024 | 2048 | 4096 | 8192;
|
|
82
93
|
/**
|
|
83
94
|
* Local-development settings for a function, used by `neon dev` when it serves every
|
|
84
95
|
* function declared in `neon.ts` (i.e. invoked with no `--source`). Never affects deploy.
|
|
85
96
|
*
|
|
86
|
-
*
|
|
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`.
|
|
97
|
+
* `port` and `portless` are independent:
|
|
89
98
|
*
|
|
90
|
-
* - `
|
|
91
|
-
* a stable `slug.localhost` URL.
|
|
92
|
-
*
|
|
93
|
-
*
|
|
99
|
+
* - `portless: true` — wrap this function's local server with `portless <slug> …` so it gets
|
|
100
|
+
* a stable `slug.localhost` URL. Portless assigns the port itself (it injects `PORT`), so
|
|
101
|
+
* `port` is ignored in this mode.
|
|
102
|
+
* - otherwise — serve directly. `port`, when set, is bound exactly (and `neon dev` fails
|
|
103
|
+
* loudly if it is taken); when omitted a free port is found automatically.
|
|
94
104
|
*/
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
105
|
+
interface FunctionDevConfig {
|
|
106
|
+
/**
|
|
107
|
+
* Port the local server binds. Bound exactly (fails if taken) when set; a free port is
|
|
108
|
+
* found when omitted. Ignored when `portless` is true (portless assigns the port).
|
|
109
|
+
*/
|
|
100
110
|
port?: number;
|
|
101
|
-
|
|
111
|
+
/**
|
|
112
|
+
* Expose this function via `portless` (a stable `slug.localhost` URL). Requires the
|
|
113
|
+
* `portless` binary on PATH. Portless assigns the port, so `port` is ignored here.
|
|
114
|
+
*/
|
|
115
|
+
portless?: boolean;
|
|
116
|
+
}
|
|
102
117
|
/**
|
|
103
|
-
*
|
|
118
|
+
* Static definition of a Neon Function (Preview feature). Declares that the function
|
|
119
|
+
* **exists** on every branch; its branch-unique slug is the **record key** in
|
|
120
|
+
* {@link PreviewInput.functions} (not a field here), so slugs are statically enumerable,
|
|
121
|
+
* cannot duplicate, and the `branch` closure can only tune slugs that are declared here.
|
|
104
122
|
*
|
|
105
123
|
* A function is invoked like a Cloudflare/Vercel handler — its source module
|
|
106
124
|
* `export default { fetch }` or `export async function handler(req): Response`. The
|
|
107
|
-
* `source` path is bundled (esbuild) and uploaded as a deployment; the newest
|
|
108
|
-
*
|
|
125
|
+
* `source` path is bundled (esbuild) and uploaded as a deployment; the newest deployment
|
|
126
|
+
* becomes active.
|
|
127
|
+
*
|
|
128
|
+
* Runtime tuning is **not** here — it varies per branch and lives in the `branch` closure
|
|
129
|
+
* (see {@link FunctionTuning}). Memory is fixed by the platform policy for now and is not
|
|
130
|
+
* user-configurable.
|
|
109
131
|
*/
|
|
110
|
-
interface
|
|
111
|
-
/**
|
|
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"
|
|
115
|
-
*/
|
|
116
|
-
slug: string;
|
|
132
|
+
interface FunctionDef {
|
|
117
133
|
/** Free-form display name. @example "Hello World" */
|
|
118
134
|
name: string;
|
|
119
135
|
/**
|
|
@@ -128,16 +144,16 @@ interface FunctionConfig {
|
|
|
128
144
|
*/
|
|
129
145
|
source: string;
|
|
130
146
|
/**
|
|
131
|
-
* Environment variables injected into the deployed function
|
|
132
|
-
*
|
|
133
|
-
*
|
|
134
|
-
*
|
|
147
|
+
* Environment variables injected into the deployed function, keyed by the var name the
|
|
148
|
+
* function reads at runtime. The **keys** are static (preserved at the type level so
|
|
149
|
+
* `parseEnv(config, "<slug>").function.<key>` is typed); the **values** are arbitrary
|
|
150
|
+
* strings evaluated when `neon.ts` is loaded (typically `process.env.X`) and uploaded
|
|
151
|
+
* at `config apply`. Every value must be a defined string — a `process.env.X` that is
|
|
152
|
+
* `undefined` (unset) errors at validation time rather than silently shipping
|
|
153
|
+
* `undefined`.
|
|
154
|
+
* @example { resendApiKey: process.env.RESEND_API_KEY ?? "" }
|
|
135
155
|
*/
|
|
136
156
|
env?: Record<string, string>;
|
|
137
|
-
/** Runtime to execute the function with. Defaults to `"nodejs24"`. */
|
|
138
|
-
runtime?: FunctionRuntime;
|
|
139
|
-
/** Memory allotted to each invocation, in MiB. Defaults to `512`. */
|
|
140
|
-
memoryMib?: FunctionMemoryMib;
|
|
141
157
|
/**
|
|
142
158
|
* Local-development settings used by `neon dev` when serving every function from
|
|
143
159
|
* `neon.ts`. Ignored at deploy time. See {@link FunctionDevConfig}.
|
|
@@ -147,11 +163,11 @@ interface FunctionConfig {
|
|
|
147
163
|
/** Anonymous-access level for a branchable object-storage bucket. */
|
|
148
164
|
type BucketAccessLevel = "private" | "public_read";
|
|
149
165
|
/**
|
|
150
|
-
*
|
|
166
|
+
* Static definition of a branchable object-storage bucket (Preview feature). The bucket's
|
|
167
|
+
* name is the **record key** in {@link PreviewInput.buckets}, so names are statically
|
|
168
|
+
* enumerable and cannot duplicate.
|
|
151
169
|
*/
|
|
152
|
-
interface
|
|
153
|
-
/** Bucket name, unique within a branch. 1–255 chars. */
|
|
154
|
-
name: string;
|
|
170
|
+
interface BucketDef {
|
|
155
171
|
/**
|
|
156
172
|
* Anonymous access level. `private` (default) requires authenticated reads/writes;
|
|
157
173
|
* `public_read` allows anonymous GetObject/HeadObject.
|
|
@@ -159,18 +175,44 @@ interface BucketConfig {
|
|
|
159
175
|
access?: BucketAccessLevel;
|
|
160
176
|
}
|
|
161
177
|
/**
|
|
162
|
-
*
|
|
163
|
-
* Neon `x-stability-level: beta` endpoints and may change before GA.
|
|
178
|
+
* Static, branch-scoped **Preview** features. Grouped under `preview` to signal they are
|
|
179
|
+
* backed by Neon `x-stability-level: beta` endpoints and may change before GA. Everything
|
|
180
|
+
* here is existential (it determines what exists on the branch); per-branch tuning lives in
|
|
181
|
+
* the `branch` closure.
|
|
164
182
|
*/
|
|
165
|
-
interface
|
|
166
|
-
/** Functions to deploy on the branch. */
|
|
167
|
-
functions?: FunctionConfig[];
|
|
168
|
-
/** Object-storage buckets to create on the branch. */
|
|
169
|
-
buckets?: BucketConfig[];
|
|
183
|
+
interface PreviewInput {
|
|
170
184
|
/** Enable/disable the AI Gateway on the branch (toggle, like auth / dataApi). */
|
|
171
|
-
aiGateway?:
|
|
185
|
+
aiGateway?: ServiceToggleInput;
|
|
186
|
+
/** Functions to deploy, keyed by branch-unique slug (`^[a-z0-9]{1,20}$`). */
|
|
187
|
+
functions?: Record<string, FunctionDef>;
|
|
188
|
+
/** Object-storage buckets to create, keyed by bucket name. */
|
|
189
|
+
buckets?: Record<string, BucketDef>;
|
|
172
190
|
}
|
|
173
|
-
|
|
191
|
+
/**
|
|
192
|
+
* Per-branch deploy tuning for a single function. Returned (per slug) by the `branch`
|
|
193
|
+
* closure. Deliberately **cannot** change the function's existence, source, name, env
|
|
194
|
+
* **keys**, or memory — only runtime selection is currently configurable — so the static
|
|
195
|
+
* secret/function set stays sound.
|
|
196
|
+
*/
|
|
197
|
+
interface FunctionTuning {
|
|
198
|
+
/** Runtime to execute the function with. Defaults to `"nodejs24"`. */
|
|
199
|
+
runtime?: FunctionRuntime;
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Per-branch tuning of Preview features. Only existing function slugs (those declared in
|
|
203
|
+
* the static {@link PreviewInput.functions}) may be tuned — `Slug` is constrained to the
|
|
204
|
+
* declared keys by {@link BranchTuningFn}.
|
|
205
|
+
*/
|
|
206
|
+
interface PreviewTuning<Slug extends string = string> {
|
|
207
|
+
functions?: Partial<Record<Slug, FunctionTuning>>;
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* The per-branch tuning object returned by the `branch` closure. It can adjust branch
|
|
211
|
+
* lifecycle (`parent`, `ttl`, `protected`), Postgres compute settings, and per-function
|
|
212
|
+
* deploy tuning — but **cannot** add/remove services or functions. That guarantee is what
|
|
213
|
+
* keeps the static secret set (and therefore `NeonEnv`) exact.
|
|
214
|
+
*/
|
|
215
|
+
interface BranchTuning<Slug extends string = string> {
|
|
174
216
|
/** Parent branch name used when creating a new branch. Not a Postgres setting. */
|
|
175
217
|
parent?: string;
|
|
176
218
|
/** Time-to-live applied when creating a new branch, or reconciled on existing branches. */
|
|
@@ -178,30 +220,43 @@ interface BranchConfigBase {
|
|
|
178
220
|
/** Whether the selected branch should be protected. Undefined means "leave as-is". */
|
|
179
221
|
protected?: boolean;
|
|
180
222
|
postgres?: PostgresConfig;
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
223
|
+
preview?: PreviewTuning<Slug>;
|
|
224
|
+
}
|
|
225
|
+
/** Extract the declared function slugs from a {@link PreviewInput} for closure typing. */
|
|
226
|
+
type FunctionSlugsOf<Preview extends PreviewInput | undefined> = Preview extends {
|
|
227
|
+
functions: infer F;
|
|
228
|
+
} ? Extract<keyof F, string> : string;
|
|
229
|
+
/**
|
|
230
|
+
* Signature of the `branch` closure. Generic over the static {@link PreviewInput} so the
|
|
231
|
+
* `preview.functions` keys it may tune are constrained to the slugs actually declared.
|
|
232
|
+
*/
|
|
233
|
+
type BranchTuningFn<Preview extends PreviewInput | undefined = PreviewInput | undefined> = (branch: BranchTarget) => BranchTuning<FunctionSlugsOf<Preview>>;
|
|
234
|
+
/**
|
|
235
|
+
* A validated Neon branch policy — the value `defineConfig({ … })` returns and `neon.ts`
|
|
236
|
+
* default-exports.
|
|
237
|
+
*
|
|
238
|
+
* Split into a **static** existential set (top-level `auth` / `dataApi` GA toggles plus the
|
|
239
|
+
* beta `preview` block) and a **dynamic** per-branch `branch` closure for tuning. The
|
|
240
|
+
* static half is what makes the secret set — and therefore `NeonEnv<typeof config>` and
|
|
241
|
+
* `parseEnv` — exact; the closure can tune but never change what exists.
|
|
242
|
+
*
|
|
243
|
+
* Generic over the three static fields so the type system can read the exact toggle/slug
|
|
244
|
+
* literals; the defaults make the bare `Config` a usable "any policy" type for runtime
|
|
245
|
+
* function signatures.
|
|
246
|
+
*/
|
|
247
|
+
interface Config<Auth extends ServiceToggleInput | undefined = ServiceToggleInput | undefined, DataApi extends ServiceToggleInput | undefined = ServiceToggleInput | undefined, Preview extends PreviewInput | undefined = PreviewInput | undefined> {
|
|
248
|
+
/** Neon Auth integration toggle (GA). Static — drives `NeonEnv.auth`. */
|
|
249
|
+
auth?: Auth;
|
|
250
|
+
/** Neon Data API integration toggle (GA). Static — drives `NeonEnv.dataApi`. */
|
|
251
|
+
dataApi?: DataApi;
|
|
252
|
+
/** Beta (Preview) feature set: AI Gateway, functions, buckets. Static. */
|
|
253
|
+
preview?: Preview;
|
|
254
|
+
/** Per-branch tuning closure. Cannot change the static existential set. */
|
|
255
|
+
branch?: BranchTuningFn<Preview>;
|
|
186
256
|
}
|
|
187
|
-
type BranchServiceConfig = {
|
|
188
|
-
auth?: never;
|
|
189
|
-
dataApi?: never;
|
|
190
|
-
} | {
|
|
191
|
-
auth: ServiceToggle;
|
|
192
|
-
dataApi?: never;
|
|
193
|
-
} | {
|
|
194
|
-
auth?: never;
|
|
195
|
-
dataApi: ServiceToggle;
|
|
196
|
-
} | {
|
|
197
|
-
auth: ServiceToggle;
|
|
198
|
-
dataApi: ServiceToggle;
|
|
199
|
-
};
|
|
200
|
-
type BranchConfig = BranchConfigBase & BranchServiceConfig;
|
|
201
|
-
type Config = (branch: BranchTarget) => BranchConfig;
|
|
202
257
|
/**
|
|
203
|
-
* A function with all deploy defaults applied. `resolveConfig` fills in `runtime`
|
|
204
|
-
*
|
|
258
|
+
* A function with all deploy defaults applied. `resolveConfig` fills in `runtime` so
|
|
259
|
+
* downstream diff/apply never has to re-derive it.
|
|
205
260
|
*/
|
|
206
261
|
interface ResolvedFunctionConfig {
|
|
207
262
|
slug: string;
|
|
@@ -209,9 +264,8 @@ interface ResolvedFunctionConfig {
|
|
|
209
264
|
source: string;
|
|
210
265
|
env: Record<string, string>;
|
|
211
266
|
runtime: FunctionRuntime;
|
|
212
|
-
memoryMib: FunctionMemoryMib;
|
|
213
267
|
/**
|
|
214
|
-
* Local-development settings, passed through untouched from {@link
|
|
268
|
+
* Local-development settings, passed through untouched from {@link FunctionDef.dev}
|
|
215
269
|
* (no defaults applied). Only consumed by `neon dev`; deploy ignores it.
|
|
216
270
|
*/
|
|
217
271
|
dev?: FunctionDevConfig;
|
|
@@ -222,7 +276,7 @@ interface ResolvedBucketConfig {
|
|
|
222
276
|
access: BucketAccessLevel;
|
|
223
277
|
}
|
|
224
278
|
/**
|
|
225
|
-
* Normalized {@link
|
|
279
|
+
* Normalized {@link PreviewInput}. Only present on {@link ResolvedBranchConfig} when the
|
|
226
280
|
* policy returned a `preview` block. `aiGatewayEnabled` follows the same
|
|
227
281
|
* "present-and-not-`false`" semantics as `authEnabled` / `dataApiEnabled`.
|
|
228
282
|
*/
|
|
@@ -285,5 +339,5 @@ interface PushResult {
|
|
|
285
339
|
conflicts: ConflictReport[];
|
|
286
340
|
}
|
|
287
341
|
//#endregion
|
|
288
|
-
export { AppliedChange,
|
|
342
|
+
export { AppliedChange, BranchTarget, BranchTuning, BranchTuningFn, BucketAccessLevel, BucketDef, ComputeSettings, ComputeUnit, Config, ConflictReport, FunctionDef, FunctionDevConfig, FunctionRuntime, FunctionTuning, PostgresConfig, PreviewInput, PreviewTuning, PushResult, ResolvedBranchConfig, ResolvedBucketConfig, ResolvedFunctionConfig, ResolvedPreviewConfig, ServiceToggle, ServiceToggleInput };
|
|
289
343
|
//# sourceMappingURL=types.d.ts.map
|
package/dist/lib/types.d.ts.map
CHANGED
|
@@ -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;
|
|
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;AAqBA;AAgBA;AAEA;AASA;AAciB,UAjGA,eAAA,CAiGiB;EA4BjB;;;;AA6BO;EAIZ,qBAAiB,CAAA,EAxJJ,WAwJI;EAOZ;AAcjB;;;;uBAIa,CAAA,EA3KY,WA2KZ;;;AAEI;AASjB;AAUA;;;;;;AACoB;AASpB;;gBAOY,CAAA,EAAA,KAAA,GAAA,IAAA,GAAA,IAAA,GAAA,MAAA,GAAA,MAAA;;;AACY;AACvB;;;;AAOiB,UAnMD,YAAA,CAmMC;;EAAP,IAAA,EAAA,MAAA;EAOC;EAAc,EAAA,CAAA,EAAA,MAAA;;QACkB,EAAA,OAAA;;UACe,CAAA,EAAA,MAAA;;WAA7B,CAAA,EAAA,OAAA;EAAY;EAezB,WAAM,CAAA,EAAA,OAAA;EAAA;WACT,CAAA,EAAA,MAAA;;;;;;AASN,UAhNS,aAAA,CAgNT;;SAIG,CAAA,EAAA,OAAA;;;AAEa;AAOxB;;;;;AAUwB;AAIxB;AAUA;;AACY,KAtOA,kBAAA,GAsOA,OAAA,GAtO+B,aAsO/B;AACF,UArOO,cAAA,CAqOP;EAAoB,eAAA,CAAA,EApOX,eAoOW;AAI9B;;;;AAOgC;AAMhC;AAkBiB,KA/PL,eAAA,GA+PmB,UAAA;AAY/B;;;;AAW0B;;;;;;;;UAxQT,iBAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;UA4BA,WAAA;;;;;;;;;;;;;;;;;;;;;;;;QAwBV;;;;;QAKA;;;KAIK,iBAAA;;;;;;UAOK,SAAA;;;;;WAKP;;;;;;;;UASO,YAAA;;cAEJ;;cAEA,eAAe;;YAEjB,eAAe;;;;;;;;UAST,cAAA;;YAEN;;;;;;;UAQM;cACJ,QAAQ,OAAO,MAAM;;;;;;;;UASjB;;;;;;;aAOL;YACD,cAAc;;;KAIpB,gCAAgC,4BACpC;;IAGG,cAAc;;;;;KAON,+BACK,2BAA2B,qCAC/B,iBAAiB,aAAa,gBAAgB;;;;;;;;;;;;;;UAe1C,oBACH,iCACV,gDAEa,iCACb,gDAEa,2BAA2B;;SAGpC;;YAEG;;YAEA;;WAED,eAAe;;;;;;UAOR,sBAAA;;;;OAIX;WACI;;;;;QAKH;;;UAIU,oBAAA;;UAER;;;;;;;UAQQ,qBAAA;aACL;WACF;;;UAIO,oBAAA;;;;aAIL;;;YAGD;;;;;UAMM,aAAA;;;;;;;;YAQN;;;;;;;;;UAUM,cAAA;;;;;;;;;;;UAYA,UAAA;;;;;;;;;;WAUP;aACE"}
|