@neondatabase/config 0.0.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/LICENSE.md +178 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +8 -0
- package/dist/lib/auth.d.ts +63 -0
- package/dist/lib/auth.d.ts.map +1 -0
- package/dist/lib/auth.js +93 -0
- package/dist/lib/auth.js.map +1 -0
- package/dist/lib/define-config.d.ts +43 -0
- package/dist/lib/define-config.d.ts.map +1 -0
- package/dist/lib/define-config.js +112 -0
- package/dist/lib/define-config.js.map +1 -0
- package/dist/lib/diff.d.ts +109 -0
- package/dist/lib/diff.d.ts.map +1 -0
- package/dist/lib/diff.js +205 -0
- package/dist/lib/diff.js.map +1 -0
- package/dist/lib/duration.d.ts +46 -0
- package/dist/lib/duration.d.ts.map +1 -0
- package/dist/lib/duration.js +96 -0
- package/dist/lib/duration.js.map +1 -0
- package/dist/lib/errors.d.ts +129 -0
- package/dist/lib/errors.d.ts.map +1 -0
- package/dist/lib/errors.js +168 -0
- package/dist/lib/errors.js.map +1 -0
- package/dist/lib/loader.d.ts +44 -0
- package/dist/lib/loader.d.ts.map +1 -0
- package/dist/lib/loader.js +119 -0
- package/dist/lib/loader.js.map +1 -0
- package/dist/lib/neon-api-real.d.ts +45 -0
- package/dist/lib/neon-api-real.d.ts.map +1 -0
- package/dist/lib/neon-api-real.js +582 -0
- package/dist/lib/neon-api-real.js.map +1 -0
- package/dist/lib/neon-api.d.ts +262 -0
- package/dist/lib/neon-api.d.ts.map +1 -0
- package/dist/lib/neon-api.js +1 -0
- package/dist/lib/patterns.d.ts +43 -0
- package/dist/lib/patterns.d.ts.map +1 -0
- package/dist/lib/patterns.js +76 -0
- package/dist/lib/patterns.js.map +1 -0
- package/dist/lib/schema.d.ts +130 -0
- package/dist/lib/schema.d.ts.map +1 -0
- package/dist/lib/schema.js +218 -0
- package/dist/lib/schema.js.map +1 -0
- package/dist/lib/types.d.ts +289 -0
- package/dist/lib/types.d.ts.map +1 -0
- package/dist/lib/types.js +1 -0
- package/dist/lib/wrap-neon-error.d.ts +30 -0
- package/dist/lib/wrap-neon-error.d.ts.map +1 -0
- package/dist/lib/wrap-neon-error.js +139 -0
- package/dist/lib/wrap-neon-error.js.map +1 -0
- package/dist/v1.d.ts +153 -0
- package/dist/v1.d.ts.map +1 -0
- package/dist/v1.js +69 -0
- package/dist/v1.js.map +1 -0
- package/package.json +67 -17
- package/.env.example +0 -5
- package/e2e/errors.e2e.test.ts +0 -52
- package/e2e/helpers.ts +0 -205
- package/e2e/load-env.ts +0 -29
- package/e2e/setup.ts +0 -24
- package/src/index.ts +0 -5
- package/src/lib/auth.test.ts +0 -166
- package/src/lib/auth.ts +0 -124
- package/src/lib/define-config.test.ts +0 -161
- package/src/lib/define-config.ts +0 -152
- package/src/lib/diff.test.ts +0 -142
- package/src/lib/diff.ts +0 -391
- package/src/lib/duration.test.ts +0 -105
- package/src/lib/duration.ts +0 -147
- package/src/lib/errors.test.ts +0 -26
- package/src/lib/errors.ts +0 -220
- package/src/lib/fake-neon-api.ts +0 -782
- package/src/lib/loader.test.ts +0 -35
- package/src/lib/loader.ts +0 -215
- package/src/lib/neon-api-real.test.ts +0 -72
- package/src/lib/neon-api-real.ts +0 -1123
- package/src/lib/neon-api.ts +0 -356
- package/src/lib/patterns.test.ts +0 -80
- package/src/lib/patterns.ts +0 -98
- package/src/lib/schema.test.ts +0 -88
- package/src/lib/schema.ts +0 -252
- package/src/lib/test-utils.ts +0 -83
- package/src/lib/types.ts +0 -268
- package/src/lib/wrap-neon-error.test.ts +0 -145
- package/src/lib/wrap-neon-error.ts +0 -204
- package/src/v1.test.ts +0 -33
- package/src/v1.ts +0 -148
- package/tsconfig.json +0 -4
- package/tsdown.config.ts +0 -19
- package/vitest.config.ts +0 -19
- package/vitest.e2e.config.ts +0 -29
|
@@ -1,161 +0,0 @@
|
|
|
1
|
-
import { describe, expect, test } from "vitest";
|
|
2
|
-
import { defineConfig, resolveConfig } from "./define-config.js";
|
|
3
|
-
import { ConfigValidationError } from "./errors.js";
|
|
4
|
-
|
|
5
|
-
describe("defineConfig", () => {
|
|
6
|
-
test("accepts a branch policy function and preserves literal behavior", () => {
|
|
7
|
-
const config = defineConfig((branch) => {
|
|
8
|
-
if (branch.name === "main")
|
|
9
|
-
return { protected: true, auth: { enabled: true } };
|
|
10
|
-
return { parent: "main", ttl: "7d" };
|
|
11
|
-
});
|
|
12
|
-
expect(typeof config).toBe("function");
|
|
13
|
-
expect(config({ name: "main", exists: true })).toEqual({
|
|
14
|
-
protected: true,
|
|
15
|
-
auth: { enabled: true },
|
|
16
|
-
});
|
|
17
|
-
});
|
|
18
|
-
|
|
19
|
-
test("rejects object configs so project-level config is not accepted", () => {
|
|
20
|
-
expect(() => defineConfig({ project: { name: "x" } } as never)).toThrow(
|
|
21
|
-
ConfigValidationError,
|
|
22
|
-
);
|
|
23
|
-
});
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
describe("resolveConfig", () => {
|
|
27
|
-
test("normalizes branch policy output", () => {
|
|
28
|
-
const config = defineConfig(() => ({
|
|
29
|
-
parent: "main",
|
|
30
|
-
ttl: "1h",
|
|
31
|
-
protected: true,
|
|
32
|
-
postgres: { computeSettings: { autoscalingLimitMaxCu: 2 } },
|
|
33
|
-
auth: {},
|
|
34
|
-
dataApi: {},
|
|
35
|
-
}));
|
|
36
|
-
const resolved = resolveConfig(config, {
|
|
37
|
-
name: "dev-a",
|
|
38
|
-
exists: false,
|
|
39
|
-
});
|
|
40
|
-
expect(resolved).toMatchObject({
|
|
41
|
-
parent: "main",
|
|
42
|
-
ttlSeconds: 3600,
|
|
43
|
-
protected: true,
|
|
44
|
-
authEnabled: true,
|
|
45
|
-
dataApiEnabled: true,
|
|
46
|
-
postgres: { computeSettings: { autoscalingLimitMaxCu: 2 } },
|
|
47
|
-
});
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
test("treats explicit service false as disabled", () => {
|
|
51
|
-
const config = defineConfig(() => ({
|
|
52
|
-
auth: { enabled: false },
|
|
53
|
-
dataApi: { enabled: false },
|
|
54
|
-
}));
|
|
55
|
-
const resolved = resolveConfig(config, {
|
|
56
|
-
name: "dev-a",
|
|
57
|
-
exists: false,
|
|
58
|
-
});
|
|
59
|
-
expect(resolved.authEnabled).toBe(false);
|
|
60
|
-
expect(resolved.dataApiEnabled).toBe(false);
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
test("reports invalid returned branch config", () => {
|
|
64
|
-
const config = defineConfig(() => ({ parent: "preview-*" }));
|
|
65
|
-
expect(() =>
|
|
66
|
-
resolveConfig(config, { name: "dev", exists: false }),
|
|
67
|
-
).toThrow(ConfigValidationError);
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
test("resolves preview functions with deploy defaults and buckets with private access", () => {
|
|
71
|
-
const config = defineConfig(() => ({
|
|
72
|
-
preview: {
|
|
73
|
-
functions: [
|
|
74
|
-
{
|
|
75
|
-
name: "Hello World",
|
|
76
|
-
slug: "hello-world",
|
|
77
|
-
source: "./functions/hello-world.ts",
|
|
78
|
-
env: { RESEND_API_KEY: "re_abc" },
|
|
79
|
-
},
|
|
80
|
-
],
|
|
81
|
-
buckets: [{ name: "uploads" }],
|
|
82
|
-
aiGateway: { enabled: true },
|
|
83
|
-
},
|
|
84
|
-
}));
|
|
85
|
-
const resolved = resolveConfig(config, {
|
|
86
|
-
name: "preview-1",
|
|
87
|
-
exists: false,
|
|
88
|
-
});
|
|
89
|
-
expect(resolved.preview).toEqual({
|
|
90
|
-
functions: [
|
|
91
|
-
{
|
|
92
|
-
slug: "hello-world",
|
|
93
|
-
name: "Hello World",
|
|
94
|
-
source: "./functions/hello-world.ts",
|
|
95
|
-
env: { RESEND_API_KEY: "re_abc" },
|
|
96
|
-
runtime: "nodejs24",
|
|
97
|
-
memoryMib: 512,
|
|
98
|
-
},
|
|
99
|
-
],
|
|
100
|
-
buckets: [{ name: "uploads", access: "private" }],
|
|
101
|
-
aiGatewayEnabled: true,
|
|
102
|
-
});
|
|
103
|
-
});
|
|
104
|
-
|
|
105
|
-
test("treats aiGateway enabled:false as disabled", () => {
|
|
106
|
-
const config = defineConfig(() => ({
|
|
107
|
-
preview: { aiGateway: { enabled: false } },
|
|
108
|
-
}));
|
|
109
|
-
const resolved = resolveConfig(config, {
|
|
110
|
-
name: "preview-1",
|
|
111
|
-
exists: false,
|
|
112
|
-
});
|
|
113
|
-
expect(resolved.preview?.aiGatewayEnabled).toBe(false);
|
|
114
|
-
});
|
|
115
|
-
|
|
116
|
-
test("rejects a function env value that is undefined (e.g. unset process.env)", () => {
|
|
117
|
-
const config = defineConfig(() => ({
|
|
118
|
-
preview: {
|
|
119
|
-
functions: [
|
|
120
|
-
{
|
|
121
|
-
name: "Hello",
|
|
122
|
-
slug: "hello",
|
|
123
|
-
source: "./hello.ts",
|
|
124
|
-
// Simulates `RESEND_API_KEY: process.env.RESEND_API_KEY` when unset.
|
|
125
|
-
env: { RESEND_API_KEY: undefined as unknown as string },
|
|
126
|
-
},
|
|
127
|
-
],
|
|
128
|
-
},
|
|
129
|
-
}));
|
|
130
|
-
expect(() =>
|
|
131
|
-
resolveConfig(config, { name: "preview-1", exists: false }),
|
|
132
|
-
).toThrow(ConfigValidationError);
|
|
133
|
-
});
|
|
134
|
-
|
|
135
|
-
test("rejects an invalid function slug", () => {
|
|
136
|
-
const config = defineConfig(() => ({
|
|
137
|
-
preview: {
|
|
138
|
-
functions: [
|
|
139
|
-
{ name: "Bad", slug: "Hello World", source: "./x.ts" },
|
|
140
|
-
],
|
|
141
|
-
},
|
|
142
|
-
}));
|
|
143
|
-
expect(() =>
|
|
144
|
-
resolveConfig(config, { name: "preview-1", exists: false }),
|
|
145
|
-
).toThrow(ConfigValidationError);
|
|
146
|
-
});
|
|
147
|
-
|
|
148
|
-
test("rejects duplicate function slugs", () => {
|
|
149
|
-
const config = defineConfig(() => ({
|
|
150
|
-
preview: {
|
|
151
|
-
functions: [
|
|
152
|
-
{ name: "A", slug: "dup", source: "./a.ts" },
|
|
153
|
-
{ name: "B", slug: "dup", source: "./b.ts" },
|
|
154
|
-
],
|
|
155
|
-
},
|
|
156
|
-
}));
|
|
157
|
-
expect(() =>
|
|
158
|
-
resolveConfig(config, { name: "preview-1", exists: false }),
|
|
159
|
-
).toThrow(ConfigValidationError);
|
|
160
|
-
});
|
|
161
|
-
});
|
package/src/lib/define-config.ts
DELETED
|
@@ -1,152 +0,0 @@
|
|
|
1
|
-
import { parseDuration } from "./duration.js";
|
|
2
|
-
import { ConfigValidationError } from "./errors.js";
|
|
3
|
-
import { branchConfigSchema, formatZodIssues } from "./schema.js";
|
|
4
|
-
import type {
|
|
5
|
-
BranchTarget,
|
|
6
|
-
Config,
|
|
7
|
-
FunctionConfig,
|
|
8
|
-
PreviewConfig,
|
|
9
|
-
ResolvedBranchConfig,
|
|
10
|
-
ResolvedPreviewConfig,
|
|
11
|
-
} from "./types.js";
|
|
12
|
-
|
|
13
|
-
/** Default deploy parameters applied to functions that omit them in `neon.ts`. */
|
|
14
|
-
const DEFAULT_FUNCTION_RUNTIME = "nodejs24" as const;
|
|
15
|
-
const DEFAULT_FUNCTION_MEMORY_MIB = 512 as const;
|
|
16
|
-
|
|
17
|
-
const REGION_PREFIX = /^(aws|azure|gcp)-/;
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* Validate and freeze a Neon Platform branch policy.
|
|
21
|
-
*
|
|
22
|
-
* Used at the top of `neon.ts`:
|
|
23
|
-
* ```ts
|
|
24
|
-
* import { defineConfig } from "@neondatabase/config/v1";
|
|
25
|
-
*
|
|
26
|
-
* export default defineConfig((branch) => {
|
|
27
|
-
* if (branch.name === "main") {
|
|
28
|
-
* return { protected: true, auth: {} };
|
|
29
|
-
* }
|
|
30
|
-
* return { parent: "main", ttl: "7d" };
|
|
31
|
-
* });
|
|
32
|
-
* ```
|
|
33
|
-
*
|
|
34
|
-
* The `branch` parameter is a **read-only {@link BranchTarget} descriptor** of the branch
|
|
35
|
-
* this policy invocation is deciding for — not a live branch handle. You don't mutate it
|
|
36
|
-
* (`branch.protected = true` does nothing); you switch on its facts (`branch.name`,
|
|
37
|
-
* `branch.isDefault`, `branch.exists`, …) and **return** the desired {@link BranchConfig}.
|
|
38
|
-
* The same callback runs in two modes: against an existing branch (fields populated from
|
|
39
|
-
* Neon) and during pre-create evaluation (`exists: false`, `id` undefined).
|
|
40
|
-
*
|
|
41
|
-
* Pure function — no I/O, no side effects. The returned policy validates its output every
|
|
42
|
-
* time it is evaluated so errors point at the concrete branch target that triggered them.
|
|
43
|
-
*/
|
|
44
|
-
export function defineConfig<const C extends Config>(input: C): C {
|
|
45
|
-
if (typeof input !== "function") {
|
|
46
|
-
throw new ConfigValidationError([
|
|
47
|
-
"defineConfig expects a function: `export default defineConfig((branch) => ({ ... }))`.",
|
|
48
|
-
"Project-level config has moved to `neonctl link`; neon.ts now describes branch-level policy only.",
|
|
49
|
-
]);
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
return Object.freeze(input) as C;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
/**
|
|
56
|
-
* Evaluate a branch policy for a specific branch target and return a normalized config.
|
|
57
|
-
*/
|
|
58
|
-
export function resolveConfig(
|
|
59
|
-
config: Config,
|
|
60
|
-
branch: BranchTarget,
|
|
61
|
-
): ResolvedBranchConfig {
|
|
62
|
-
let raw: unknown;
|
|
63
|
-
try {
|
|
64
|
-
raw = config(Object.freeze({ ...branch }));
|
|
65
|
-
} catch (cause) {
|
|
66
|
-
throw new ConfigValidationError([
|
|
67
|
-
`Config function threw while evaluating branch "${branch.name}".`,
|
|
68
|
-
(cause as Error)?.message ?? String(cause),
|
|
69
|
-
]);
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
const parsed = branchConfigSchema.safeParse(raw);
|
|
73
|
-
if (!parsed.success) {
|
|
74
|
-
throw new ConfigValidationError(formatZodIssues(parsed.error));
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
const cfg = parsed.data;
|
|
78
|
-
const issues: string[] = [];
|
|
79
|
-
let ttlSeconds: number | undefined;
|
|
80
|
-
if (cfg.ttl !== undefined) {
|
|
81
|
-
const parsedTtl = parseDuration(cfg.ttl);
|
|
82
|
-
if ("error" in parsedTtl) {
|
|
83
|
-
issues.push(`ttl: ${parsedTtl.error}`);
|
|
84
|
-
} else {
|
|
85
|
-
ttlSeconds = parsedTtl.seconds;
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
if (issues.length > 0) {
|
|
89
|
-
throw new ConfigValidationError(issues);
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
const resolved: ResolvedBranchConfig = {
|
|
93
|
-
authEnabled: isServiceEnabled(cfg.auth),
|
|
94
|
-
dataApiEnabled: isServiceEnabled(cfg.dataApi),
|
|
95
|
-
};
|
|
96
|
-
if (cfg.parent !== undefined) resolved.parent = cfg.parent;
|
|
97
|
-
if (ttlSeconds !== undefined) resolved.ttlSeconds = ttlSeconds;
|
|
98
|
-
if (cfg.protected !== undefined) resolved.protected = cfg.protected;
|
|
99
|
-
if (cfg.postgres) {
|
|
100
|
-
resolved.postgres = {
|
|
101
|
-
...(cfg.postgres.computeSettings
|
|
102
|
-
? { computeSettings: { ...cfg.postgres.computeSettings } }
|
|
103
|
-
: {}),
|
|
104
|
-
};
|
|
105
|
-
}
|
|
106
|
-
if (cfg.preview) {
|
|
107
|
-
resolved.preview = resolvePreviewConfig(cfg.preview);
|
|
108
|
-
}
|
|
109
|
-
return resolved;
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
function isServiceEnabled(service: { enabled?: boolean } | undefined): boolean {
|
|
113
|
-
return service !== undefined && service.enabled !== false;
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
/**
|
|
117
|
-
* Normalize a {@link PreviewConfig} into a {@link ResolvedPreviewConfig}: apply per-function
|
|
118
|
-
* deploy defaults, default each bucket's access level to `private`, and collapse the
|
|
119
|
-
* `aiGateway` toggle to a boolean using the same present-and-not-`false` rule as
|
|
120
|
-
* `auth` / `dataApi`.
|
|
121
|
-
*/
|
|
122
|
-
function resolvePreviewConfig(preview: PreviewConfig): ResolvedPreviewConfig {
|
|
123
|
-
return {
|
|
124
|
-
functions: (preview.functions ?? []).map(resolveFunctionConfig),
|
|
125
|
-
buckets: (preview.buckets ?? []).map((bucket) => ({
|
|
126
|
-
name: bucket.name,
|
|
127
|
-
access: bucket.access ?? "private",
|
|
128
|
-
})),
|
|
129
|
-
aiGatewayEnabled: isServiceEnabled(preview.aiGateway),
|
|
130
|
-
};
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
function resolveFunctionConfig(fn: FunctionConfig) {
|
|
134
|
-
return {
|
|
135
|
-
slug: fn.slug,
|
|
136
|
-
name: fn.name,
|
|
137
|
-
source: fn.source,
|
|
138
|
-
env: { ...(fn.env ?? {}) },
|
|
139
|
-
runtime: fn.runtime ?? DEFAULT_FUNCTION_RUNTIME,
|
|
140
|
-
memoryMib: fn.memoryMib ?? DEFAULT_FUNCTION_MEMORY_MIB,
|
|
141
|
-
};
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
/**
|
|
145
|
-
* Normalize a region identifier to Neon's `<cloud>-<region>` format. When the user writes
|
|
146
|
-
* `us-east-1` we assume `aws-us-east-1`. Pure helper used by both the validator and the
|
|
147
|
-
* NeonApi adapter.
|
|
148
|
-
*/
|
|
149
|
-
export function normalizeRegion(region: string): string {
|
|
150
|
-
if (REGION_PREFIX.test(region)) return region;
|
|
151
|
-
return `aws-${region}`;
|
|
152
|
-
}
|
package/src/lib/diff.test.ts
DELETED
|
@@ -1,142 +0,0 @@
|
|
|
1
|
-
import { describe, expect, test } from "vitest";
|
|
2
|
-
import { diffConfig, type RemoteState } from "./diff.js";
|
|
3
|
-
|
|
4
|
-
describe("diffConfig", () => {
|
|
5
|
-
const remote: RemoteState = {
|
|
6
|
-
projectId: "proj",
|
|
7
|
-
branch: {
|
|
8
|
-
id: "br-main",
|
|
9
|
-
name: "main",
|
|
10
|
-
isDefault: true,
|
|
11
|
-
protected: false,
|
|
12
|
-
},
|
|
13
|
-
endpoint: {
|
|
14
|
-
id: "ep",
|
|
15
|
-
branchId: "br-main",
|
|
16
|
-
type: "read_write" as const,
|
|
17
|
-
autoscalingLimitMinCu: 0.25,
|
|
18
|
-
autoscalingLimitMaxCu: 1,
|
|
19
|
-
suspendTimeout: "5m",
|
|
20
|
-
},
|
|
21
|
-
services: {
|
|
22
|
-
databaseName: "neondb",
|
|
23
|
-
authEnabled: false,
|
|
24
|
-
dataApiEnabled: false,
|
|
25
|
-
},
|
|
26
|
-
};
|
|
27
|
-
|
|
28
|
-
test("plans service enables", () => {
|
|
29
|
-
const diff = diffConfig(
|
|
30
|
-
{ authEnabled: true, dataApiEnabled: true },
|
|
31
|
-
remote,
|
|
32
|
-
{ updateExisting: false },
|
|
33
|
-
);
|
|
34
|
-
expect(diff.plan.map((p) => p.kind)).toEqual([
|
|
35
|
-
"enable-auth",
|
|
36
|
-
"enable-data-api",
|
|
37
|
-
]);
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
test("reports compute drift unless updateExisting is set", () => {
|
|
41
|
-
const diff = diffConfig(
|
|
42
|
-
{
|
|
43
|
-
authEnabled: false,
|
|
44
|
-
dataApiEnabled: false,
|
|
45
|
-
postgres: { computeSettings: { autoscalingLimitMaxCu: 2 } },
|
|
46
|
-
},
|
|
47
|
-
remote,
|
|
48
|
-
{ updateExisting: false },
|
|
49
|
-
);
|
|
50
|
-
expect(diff.conflicts[0]).toMatchObject({ field: "computeSettings" });
|
|
51
|
-
});
|
|
52
|
-
|
|
53
|
-
test("plans mutable branch updates with updateExisting", () => {
|
|
54
|
-
const diff = diffConfig(
|
|
55
|
-
{ authEnabled: false, dataApiEnabled: false, protected: true },
|
|
56
|
-
remote,
|
|
57
|
-
{ updateExisting: true },
|
|
58
|
-
);
|
|
59
|
-
expect(diff.plan[0]).toMatchObject({
|
|
60
|
-
kind: "update-branch-protected",
|
|
61
|
-
branchId: "br-main",
|
|
62
|
-
});
|
|
63
|
-
});
|
|
64
|
-
|
|
65
|
-
test("plans preview create + deploy + bucket + ai-gateway when nothing exists", () => {
|
|
66
|
-
const diff = diffConfig(
|
|
67
|
-
{
|
|
68
|
-
authEnabled: false,
|
|
69
|
-
dataApiEnabled: false,
|
|
70
|
-
preview: {
|
|
71
|
-
functions: [
|
|
72
|
-
{
|
|
73
|
-
slug: "hello-world",
|
|
74
|
-
name: "Hello World",
|
|
75
|
-
source: "./hello.ts",
|
|
76
|
-
env: {},
|
|
77
|
-
runtime: "nodejs24",
|
|
78
|
-
memoryMib: 512,
|
|
79
|
-
},
|
|
80
|
-
],
|
|
81
|
-
buckets: [{ name: "uploads", access: "private" }],
|
|
82
|
-
aiGatewayEnabled: true,
|
|
83
|
-
},
|
|
84
|
-
},
|
|
85
|
-
{
|
|
86
|
-
...remote,
|
|
87
|
-
preview: {
|
|
88
|
-
buckets: [],
|
|
89
|
-
functions: [],
|
|
90
|
-
aiGatewayEnabled: false,
|
|
91
|
-
},
|
|
92
|
-
},
|
|
93
|
-
{ updateExisting: false },
|
|
94
|
-
);
|
|
95
|
-
expect(diff.plan.map((p) => p.kind)).toEqual([
|
|
96
|
-
"create-bucket",
|
|
97
|
-
"create-function",
|
|
98
|
-
"deploy-function",
|
|
99
|
-
"enable-ai-gateway",
|
|
100
|
-
]);
|
|
101
|
-
});
|
|
102
|
-
|
|
103
|
-
test("skips create-function and skips enable-ai-gateway when already present, but still re-deploys", () => {
|
|
104
|
-
const diff = diffConfig(
|
|
105
|
-
{
|
|
106
|
-
authEnabled: false,
|
|
107
|
-
dataApiEnabled: false,
|
|
108
|
-
preview: {
|
|
109
|
-
functions: [
|
|
110
|
-
{
|
|
111
|
-
slug: "hello-world",
|
|
112
|
-
name: "Hello World",
|
|
113
|
-
source: "./hello.ts",
|
|
114
|
-
env: {},
|
|
115
|
-
runtime: "nodejs24",
|
|
116
|
-
memoryMib: 512,
|
|
117
|
-
},
|
|
118
|
-
],
|
|
119
|
-
buckets: [{ name: "uploads", access: "private" }],
|
|
120
|
-
aiGatewayEnabled: true,
|
|
121
|
-
},
|
|
122
|
-
},
|
|
123
|
-
{
|
|
124
|
-
...remote,
|
|
125
|
-
preview: {
|
|
126
|
-
buckets: [{ name: "uploads", accessLevel: "private" }],
|
|
127
|
-
functions: [
|
|
128
|
-
{
|
|
129
|
-
id: "fn-1",
|
|
130
|
-
slug: "hello-world",
|
|
131
|
-
name: "Hello World",
|
|
132
|
-
invocationUrl: "https://x/functions/hello-world",
|
|
133
|
-
},
|
|
134
|
-
],
|
|
135
|
-
aiGatewayEnabled: true,
|
|
136
|
-
},
|
|
137
|
-
},
|
|
138
|
-
{ updateExisting: false },
|
|
139
|
-
);
|
|
140
|
-
expect(diff.plan.map((p) => p.kind)).toEqual(["deploy-function"]);
|
|
141
|
-
});
|
|
142
|
-
});
|