@builder.io/ai-utils 0.81.0 → 0.81.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/builder-config.d.ts +16 -16
- package/src/builder-config.js +35 -6
- package/src/builder-config.test.d.ts +1 -0
- package/src/builder-config.test.js +57 -0
- package/src/projects.d.ts +10 -1
- package/src/projects.js +22 -0
package/package.json
CHANGED
package/src/builder-config.d.ts
CHANGED
|
@@ -20,18 +20,18 @@ export declare const BuilderConfigDatabaseSchema: z.ZodObject<{
|
|
|
20
20
|
export type BuilderConfigDatabase = z.infer<typeof BuilderConfigDatabaseSchema>;
|
|
21
21
|
/** `hosting` block in `builder.config.json` — see First Class Hosting spec. */
|
|
22
22
|
export declare const BuilderConfigHostingEnvironmentSchema: z.ZodObject<{
|
|
23
|
-
build: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString
|
|
24
|
-
prod: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString
|
|
23
|
+
build: z.ZodCatch<z.ZodOptional<z.ZodPreprocess<z.ZodRecord<z.ZodString, z.ZodString>>>>;
|
|
24
|
+
prod: z.ZodCatch<z.ZodOptional<z.ZodPreprocess<z.ZodRecord<z.ZodString, z.ZodString>>>>;
|
|
25
25
|
}, z.core.$strip>;
|
|
26
26
|
export type BuilderConfigHostingEnvironment = z.infer<typeof BuilderConfigHostingEnvironmentSchema>;
|
|
27
27
|
export declare const BuilderConfigHostingSchema: z.ZodObject<{
|
|
28
|
-
buildCommand: z.ZodOptional<z.ZodString
|
|
29
|
-
nodeVersion: z.ZodOptional<z.ZodString
|
|
30
|
-
buildOutputDir: z.ZodOptional<z.ZodString
|
|
31
|
-
environment: z.ZodOptional<z.ZodObject<{
|
|
32
|
-
build: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString
|
|
33
|
-
prod: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString
|
|
34
|
-
}, z.core.$strip
|
|
28
|
+
buildCommand: z.ZodCatch<z.ZodOptional<z.ZodString>>;
|
|
29
|
+
nodeVersion: z.ZodCatch<z.ZodOptional<z.ZodPipe<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>, z.ZodTransform<string, string | number>>>>;
|
|
30
|
+
buildOutputDir: z.ZodCatch<z.ZodOptional<z.ZodString>>;
|
|
31
|
+
environment: z.ZodCatch<z.ZodOptional<z.ZodObject<{
|
|
32
|
+
build: z.ZodCatch<z.ZodOptional<z.ZodPreprocess<z.ZodRecord<z.ZodString, z.ZodString>>>>;
|
|
33
|
+
prod: z.ZodCatch<z.ZodOptional<z.ZodPreprocess<z.ZodRecord<z.ZodString, z.ZodString>>>>;
|
|
34
|
+
}, z.core.$strip>>>;
|
|
35
35
|
}, z.core.$strip>;
|
|
36
36
|
export type BuilderConfigHosting = z.infer<typeof BuilderConfigHostingSchema>;
|
|
37
37
|
export declare const BuilderConfigSchema: z.ZodObject<{
|
|
@@ -41,13 +41,13 @@ export declare const BuilderConfigSchema: z.ZodObject<{
|
|
|
41
41
|
schemaDir: z.ZodDefault<z.ZodString>;
|
|
42
42
|
}, z.core.$strip>>;
|
|
43
43
|
hosting: z.ZodOptional<z.ZodObject<{
|
|
44
|
-
buildCommand: z.ZodOptional<z.ZodString
|
|
45
|
-
nodeVersion: z.ZodOptional<z.ZodString
|
|
46
|
-
buildOutputDir: z.ZodOptional<z.ZodString
|
|
47
|
-
environment: z.ZodOptional<z.ZodObject<{
|
|
48
|
-
build: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString
|
|
49
|
-
prod: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString
|
|
50
|
-
}, z.core.$strip
|
|
44
|
+
buildCommand: z.ZodCatch<z.ZodOptional<z.ZodString>>;
|
|
45
|
+
nodeVersion: z.ZodCatch<z.ZodOptional<z.ZodPipe<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>, z.ZodTransform<string, string | number>>>>;
|
|
46
|
+
buildOutputDir: z.ZodCatch<z.ZodOptional<z.ZodString>>;
|
|
47
|
+
environment: z.ZodCatch<z.ZodOptional<z.ZodObject<{
|
|
48
|
+
build: z.ZodCatch<z.ZodOptional<z.ZodPreprocess<z.ZodRecord<z.ZodString, z.ZodString>>>>;
|
|
49
|
+
prod: z.ZodCatch<z.ZodOptional<z.ZodPreprocess<z.ZodRecord<z.ZodString, z.ZodString>>>>;
|
|
50
|
+
}, z.core.$strip>>>;
|
|
51
51
|
}, z.core.$strip>>;
|
|
52
52
|
}, z.core.$strip>;
|
|
53
53
|
export type BuilderConfig = z.infer<typeof BuilderConfigSchema>;
|
package/src/builder-config.js
CHANGED
|
@@ -17,16 +17,45 @@ export const BuilderConfigDatabaseSchema = z.object({
|
|
|
17
17
|
migrations: z.literal("drizzle"),
|
|
18
18
|
schemaDir: z.string().default("drizzle"),
|
|
19
19
|
});
|
|
20
|
+
/**
|
|
21
|
+
* Env values are always strings at runtime, but JSON authors commonly write
|
|
22
|
+
* booleans/numbers (e.g. `"DISABLE_AUTH": true`). Coerce them to strings rather
|
|
23
|
+
* than rejecting, and drop any single value that can't be coerced (object/array/
|
|
24
|
+
* null) instead of failing the whole map — a malformed value must not silently
|
|
25
|
+
* discard the entire hosting config downstream.
|
|
26
|
+
*/
|
|
27
|
+
const HostingEnvRecordSchema = z.preprocess((input) => {
|
|
28
|
+
if (!input || typeof input !== "object" || Array.isArray(input)) {
|
|
29
|
+
return input;
|
|
30
|
+
}
|
|
31
|
+
const result = {};
|
|
32
|
+
for (const [key, value] of Object.entries(input)) {
|
|
33
|
+
if (typeof value === "string" ||
|
|
34
|
+
typeof value === "number" ||
|
|
35
|
+
typeof value === "boolean") {
|
|
36
|
+
result[key] = String(value);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return result;
|
|
40
|
+
}, z.record(z.string(), z.string()));
|
|
20
41
|
/** `hosting` block in `builder.config.json` — see First Class Hosting spec. */
|
|
21
42
|
export const BuilderConfigHostingEnvironmentSchema = z.object({
|
|
22
|
-
build:
|
|
23
|
-
prod:
|
|
43
|
+
build: HostingEnvRecordSchema.optional().catch(undefined),
|
|
44
|
+
prod: HostingEnvRecordSchema.optional().catch(undefined),
|
|
24
45
|
});
|
|
46
|
+
// `nodeVersion` is commonly authored as a JSON number (e.g. `"nodeVersion": 20`),
|
|
47
|
+
// so coerce it to a string. `buildCommand`/`buildOutputDir` accept strings only.
|
|
48
|
+
const NodeVersionSchema = z
|
|
49
|
+
.union([z.string(), z.number()])
|
|
50
|
+
.transform((value) => String(value));
|
|
51
|
+
// `.catch(undefined)` per field so one malformed field (e.g. an object-valued
|
|
52
|
+
// buildOutputDir) is dropped individually instead of invalidating the whole
|
|
53
|
+
// hosting block.
|
|
25
54
|
export const BuilderConfigHostingSchema = z.object({
|
|
26
|
-
buildCommand: z.string().optional(),
|
|
27
|
-
nodeVersion:
|
|
28
|
-
buildOutputDir: z.string().optional(),
|
|
29
|
-
environment: BuilderConfigHostingEnvironmentSchema.optional(),
|
|
55
|
+
buildCommand: z.string().optional().catch(undefined),
|
|
56
|
+
nodeVersion: NodeVersionSchema.optional().catch(undefined),
|
|
57
|
+
buildOutputDir: z.string().optional().catch(undefined),
|
|
58
|
+
environment: BuilderConfigHostingEnvironmentSchema.optional().catch(undefined),
|
|
30
59
|
});
|
|
31
60
|
export const BuilderConfigSchema = z.object({
|
|
32
61
|
database: BuilderConfigDatabaseSchema.optional(),
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import { BuilderConfigHostingSchema } from "./builder-config";
|
|
3
|
+
describe("BuilderConfigHostingSchema", () => {
|
|
4
|
+
it("coerces boolean/number env values to strings", () => {
|
|
5
|
+
var _a, _b;
|
|
6
|
+
const parsed = BuilderConfigHostingSchema.parse({
|
|
7
|
+
buildOutputDir: "dist",
|
|
8
|
+
environment: {
|
|
9
|
+
prod: { DISABLE_AUTH: true },
|
|
10
|
+
build: { PORT: 3000, NITRO_PRESET: "netlify" },
|
|
11
|
+
},
|
|
12
|
+
});
|
|
13
|
+
expect(parsed.buildOutputDir).toBe("dist");
|
|
14
|
+
expect((_a = parsed.environment) === null || _a === void 0 ? void 0 : _a.prod).toEqual({ DISABLE_AUTH: "true" });
|
|
15
|
+
expect((_b = parsed.environment) === null || _b === void 0 ? void 0 : _b.build).toEqual({
|
|
16
|
+
PORT: "3000",
|
|
17
|
+
NITRO_PRESET: "netlify",
|
|
18
|
+
});
|
|
19
|
+
});
|
|
20
|
+
it("coerces a numeric nodeVersion to a string", () => {
|
|
21
|
+
const parsed = BuilderConfigHostingSchema.parse({
|
|
22
|
+
nodeVersion: 20,
|
|
23
|
+
buildOutputDir: "dist",
|
|
24
|
+
});
|
|
25
|
+
expect(parsed.nodeVersion).toBe("20");
|
|
26
|
+
expect(parsed.buildOutputDir).toBe("dist");
|
|
27
|
+
});
|
|
28
|
+
it("does not coerce numeric buildCommand/buildOutputDir (strings only)", () => {
|
|
29
|
+
const parsed = BuilderConfigHostingSchema.parse({
|
|
30
|
+
buildCommand: 123,
|
|
31
|
+
buildOutputDir: 456,
|
|
32
|
+
nodeVersion: "20",
|
|
33
|
+
});
|
|
34
|
+
expect(parsed.buildCommand).toBeUndefined();
|
|
35
|
+
expect(parsed.buildOutputDir).toBeUndefined();
|
|
36
|
+
expect(parsed.nodeVersion).toBe("20");
|
|
37
|
+
});
|
|
38
|
+
it("drops a single uncoercible env value but keeps the rest of the block", () => {
|
|
39
|
+
var _a;
|
|
40
|
+
const parsed = BuilderConfigHostingSchema.parse({
|
|
41
|
+
buildOutputDir: "dist",
|
|
42
|
+
environment: {
|
|
43
|
+
prod: { GOOD: "yes", BAD: { nested: "object" } },
|
|
44
|
+
},
|
|
45
|
+
});
|
|
46
|
+
expect(parsed.buildOutputDir).toBe("dist");
|
|
47
|
+
expect((_a = parsed.environment) === null || _a === void 0 ? void 0 : _a.prod).toEqual({ GOOD: "yes" });
|
|
48
|
+
});
|
|
49
|
+
it("drops a malformed field instead of invalidating the whole block", () => {
|
|
50
|
+
const parsed = BuilderConfigHostingSchema.parse({
|
|
51
|
+
buildCommand: "npm run build",
|
|
52
|
+
buildOutputDir: { nested: "object" },
|
|
53
|
+
});
|
|
54
|
+
expect(parsed.buildCommand).toBe("npm run build");
|
|
55
|
+
expect(parsed.buildOutputDir).toBeUndefined();
|
|
56
|
+
});
|
|
57
|
+
});
|
package/src/projects.d.ts
CHANGED
|
@@ -487,7 +487,9 @@ export interface OrgAgentConfig {
|
|
|
487
487
|
enabledTools: string[];
|
|
488
488
|
longLived: boolean;
|
|
489
489
|
}
|
|
490
|
-
export type BranchType = "code-review" | "setup-project"
|
|
490
|
+
export type BranchType = "code-review" | "setup-project"
|
|
491
|
+
/** Hidden branch the webapp creates when the user picks manual setup. */
|
|
492
|
+
| "manual-setup" | "org-agent" | "snapshot-build" | "design-system-indexing" | "deploy" | "default";
|
|
491
493
|
/** Category of work a branch represents, auto-assigned during prompt analysis. */
|
|
492
494
|
export type BranchCategory = "feature" | "fix" | "research" | "other";
|
|
493
495
|
export interface BranchSharedData {
|
|
@@ -1613,6 +1615,8 @@ export type DeployListItem = z.infer<typeof DeployListItemSchema>;
|
|
|
1613
1615
|
export declare const DeployArtifactManifestSchema: z.ZodObject<{
|
|
1614
1616
|
files: z.ZodRecord<z.ZodString, z.ZodString>;
|
|
1615
1617
|
functions: z.ZodRecord<z.ZodString, z.ZodString>;
|
|
1618
|
+
functions_config: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
|
|
1619
|
+
function_invocation_modes: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
1616
1620
|
}, z.core.$strip>;
|
|
1617
1621
|
export type DeployArtifactManifest = z.infer<typeof DeployArtifactManifestSchema>;
|
|
1618
1622
|
/**
|
|
@@ -1733,4 +1737,9 @@ export declare const DuplicateBranchOptionsSchema: z.ZodObject<{
|
|
|
1733
1737
|
friendlyName: z.ZodOptional<z.ZodString>;
|
|
1734
1738
|
}, z.core.$strip>;
|
|
1735
1739
|
export type DuplicateBranchOptions = z.infer<typeof DuplicateBranchOptionsSchema>;
|
|
1740
|
+
export declare const EnsureMainBranchExistsOptionsSchema: z.ZodObject<{
|
|
1741
|
+
projectId: z.ZodString;
|
|
1742
|
+
branchName: z.ZodString;
|
|
1743
|
+
}, z.core.$strip>;
|
|
1744
|
+
export type EnsureMainBranchExistsOptions = z.infer<typeof EnsureMainBranchExistsOptionsSchema>;
|
|
1736
1745
|
export {};
|
package/src/projects.js
CHANGED
|
@@ -462,6 +462,20 @@ export const DeployArtifactManifestSchema = z.object({
|
|
|
462
462
|
functions: z.record(z.string(), z.string()).meta({
|
|
463
463
|
description: "serverless function name → sha256 hash",
|
|
464
464
|
}),
|
|
465
|
+
// Netlify Functions v2 routing config: function name → config object.
|
|
466
|
+
// Kept as a loose record so ai-utils does not need to depend on the Netlify
|
|
467
|
+
// API package for the exact functionConfig schema.
|
|
468
|
+
functions_config: z
|
|
469
|
+
.record(z.string(), z.record(z.string(), z.unknown()))
|
|
470
|
+
.optional()
|
|
471
|
+
.meta({
|
|
472
|
+
description: "Netlify Functions v2 routing config per function name",
|
|
473
|
+
}),
|
|
474
|
+
// Lambda invocation mode per function: "stream" for v2 functions using
|
|
475
|
+
// awslambda.streamifyResponse bootstrap; absent/undefined means buffered.
|
|
476
|
+
function_invocation_modes: z.record(z.string(), z.string()).optional().meta({
|
|
477
|
+
description: 'Lambda invocation mode per function name (e.g. "stream" for v2 streaming functions)',
|
|
478
|
+
}),
|
|
465
479
|
});
|
|
466
480
|
/**
|
|
467
481
|
* Per-deploy overrides passed from ai-services to the deploy pod's build-and-upload endpoint.
|
|
@@ -645,3 +659,11 @@ export const DuplicateBranchOptionsSchema = z.object({
|
|
|
645
659
|
description: "Optional friendly (display) name for the new branch.",
|
|
646
660
|
}),
|
|
647
661
|
});
|
|
662
|
+
export const EnsureMainBranchExistsOptionsSchema = z.object({
|
|
663
|
+
projectId: z.string().min(1).meta({
|
|
664
|
+
description: "Project to ensure the main branch exists for.",
|
|
665
|
+
}),
|
|
666
|
+
branchName: z.string().min(1).meta({
|
|
667
|
+
description: "Branch whose head ref seeds the main branch when it doesn't exist yet. No-op for non-internalHost projects.",
|
|
668
|
+
}),
|
|
669
|
+
});
|