siteplane 0.1.48 → 0.1.50
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 +23 -0
- package/dist/bin/siteplane.js +491 -290
- package/dist/index.js +231 -187
- package/dist/next.js +234 -185
- package/package.json +1 -1
package/dist/bin/siteplane.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
// src/bin/run-siteplane.ts
|
|
4
|
-
import { randomUUID as
|
|
5
|
-
import { access as
|
|
6
|
-
import { join as
|
|
4
|
+
import { randomUUID as randomUUID8 } from "crypto";
|
|
5
|
+
import { access as access7, readFile as readFile13 } from "fs/promises";
|
|
6
|
+
import { join as join13, resolve as resolve4 } from "path";
|
|
7
7
|
|
|
8
8
|
// ../cli/dist/analytics/manifest.js
|
|
9
9
|
import { mkdir, readFile, writeFile } from "fs/promises";
|
|
@@ -11,7 +11,7 @@ import { dirname } from "path";
|
|
|
11
11
|
|
|
12
12
|
// ../shared/dist/actors.js
|
|
13
13
|
import { z } from "zod";
|
|
14
|
-
var ACTOR_TYPES = ["workspace_member", "site_member", "agent", "system"];
|
|
14
|
+
var ACTOR_TYPES = ["workspace_member", "site_member", "agent", "setup_guest", "system"];
|
|
15
15
|
var actorTypeSchema = z.enum(ACTOR_TYPES);
|
|
16
16
|
|
|
17
17
|
// ../shared/dist/analytics-defaults.js
|
|
@@ -1632,7 +1632,7 @@ var siteSetupTaskSchema = z16.object({
|
|
|
1632
1632
|
progress: siteSetupTaskProgressSchema.nullable(),
|
|
1633
1633
|
deployment: setupDeploymentRecordSchema.nullable(),
|
|
1634
1634
|
revalidationGeneration: z16.number().int().positive(),
|
|
1635
|
-
assignment: z16.
|
|
1635
|
+
assignment: z16.enum(["owned", "provisional", "claimed"]),
|
|
1636
1636
|
deadline: z16.string().datetime().nullable(),
|
|
1637
1637
|
userInstructions: z16.object({
|
|
1638
1638
|
text: siteSetupOwnerEditabilityNoteSchema,
|
|
@@ -2306,6 +2306,17 @@ var checkSetupAssetTargetInputSchema = z25.object({
|
|
|
2306
2306
|
intent: z25.enum(["start", "poll"])
|
|
2307
2307
|
}).strict();
|
|
2308
2308
|
|
|
2309
|
+
// ../shared/dist/setup-installation.js
|
|
2310
|
+
import { z as z26 } from "zod";
|
|
2311
|
+
var setupInstallationRequestSchema = z26.object({
|
|
2312
|
+
modules: siteSetupModulesSchema,
|
|
2313
|
+
ownerEditabilityNote: siteSetupOwnerEditabilityNoteSchema,
|
|
2314
|
+
provider: z26.object({
|
|
2315
|
+
projectId: z26.string().min(1).max(200),
|
|
2316
|
+
teamId: z26.string().min(1).max(200)
|
|
2317
|
+
}).strict()
|
|
2318
|
+
}).strict();
|
|
2319
|
+
|
|
2309
2320
|
// ../cli/dist/analytics/manifest.js
|
|
2310
2321
|
async function readAnalyticsManifestFile(manifestPath) {
|
|
2311
2322
|
return validateAnalyticsManifestInput(JSON.parse(await readFile(manifestPath, "utf8")));
|
|
@@ -3130,16 +3141,16 @@ async function analyticsReadinessCommand(input) {
|
|
|
3130
3141
|
}
|
|
3131
3142
|
|
|
3132
3143
|
// ../cli/dist/commands/analytics/public-key.js
|
|
3133
|
-
import { z as
|
|
3134
|
-
var responseSchema =
|
|
3135
|
-
ok:
|
|
3136
|
-
data:
|
|
3137
|
-
rawPublicKey:
|
|
3144
|
+
import { z as z27 } from "zod";
|
|
3145
|
+
var responseSchema = z27.object({
|
|
3146
|
+
ok: z27.literal(true),
|
|
3147
|
+
data: z27.object({
|
|
3148
|
+
rawPublicKey: z27.string().regex(/^pk_siteplane_[A-Za-z0-9_-]{16}_[A-Za-z0-9_-]{43}$/)
|
|
3138
3149
|
})
|
|
3139
3150
|
});
|
|
3140
|
-
var errorResponseSchema =
|
|
3141
|
-
error:
|
|
3142
|
-
code:
|
|
3151
|
+
var errorResponseSchema = z27.object({
|
|
3152
|
+
error: z27.object({
|
|
3153
|
+
code: z27.string().regex(/^[a-z][a-z0-9_.-]+$/u)
|
|
3143
3154
|
})
|
|
3144
3155
|
});
|
|
3145
3156
|
async function analyticsPublicKeyCommand(input) {
|
|
@@ -3161,13 +3172,13 @@ async function analyticsPublicKeyCommand(input) {
|
|
|
3161
3172
|
}
|
|
3162
3173
|
|
|
3163
3174
|
// ../cli/dist/commands/analytics/prepare.js
|
|
3164
|
-
import { z as
|
|
3165
|
-
var resultSchema =
|
|
3166
|
-
ok:
|
|
3167
|
-
data:
|
|
3168
|
-
rawPublicKey:
|
|
3169
|
-
generation:
|
|
3170
|
-
status:
|
|
3175
|
+
import { z as z28 } from "zod";
|
|
3176
|
+
var resultSchema = z28.object({
|
|
3177
|
+
ok: z28.literal(true),
|
|
3178
|
+
data: z28.object({
|
|
3179
|
+
rawPublicKey: z28.string().regex(/^pk_siteplane_[A-Za-z0-9_-]{16}_[A-Za-z0-9_-]{43}$/u),
|
|
3180
|
+
generation: z28.number().int().positive(),
|
|
3181
|
+
status: z28.enum([
|
|
3171
3182
|
"setup_started",
|
|
3172
3183
|
"test_mode",
|
|
3173
3184
|
"active",
|
|
@@ -3177,8 +3188,8 @@ var resultSchema = z27.object({
|
|
|
3177
3188
|
])
|
|
3178
3189
|
}).strict()
|
|
3179
3190
|
}).strict();
|
|
3180
|
-
var errorSchema =
|
|
3181
|
-
error:
|
|
3191
|
+
var errorSchema = z28.object({
|
|
3192
|
+
error: z28.object({ code: z28.string().regex(/^[a-z][a-z0-9_.-]+$/u) })
|
|
3182
3193
|
});
|
|
3183
3194
|
async function analyticsPrepareCommand(input) {
|
|
3184
3195
|
const response = await (input.fetchImpl ?? fetch)(`${input.config.apiBaseUrl.replace(/\/$/u, "")}/api/cli/analytics/prepare`, {
|
|
@@ -3398,19 +3409,19 @@ async function bookingTestCommand(input) {
|
|
|
3398
3409
|
import { access, chmod, open, readFile as readFile5, rename, rm } from "fs/promises";
|
|
3399
3410
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
3400
3411
|
import { join as join3 } from "path";
|
|
3401
|
-
import { z as
|
|
3402
|
-
var siteplaneProjectConfigSchema =
|
|
3403
|
-
version:
|
|
3404
|
-
apiBaseUrl:
|
|
3405
|
-
siteId:
|
|
3406
|
-
publicSiteKeyId:
|
|
3407
|
-
publicSiteKey:
|
|
3408
|
-
runId:
|
|
3409
|
-
appDirectory:
|
|
3410
|
-
taskContractVersion:
|
|
3411
|
-
adminProtocolVersion:
|
|
3412
|
+
import { z as z29 } from "zod";
|
|
3413
|
+
var siteplaneProjectConfigSchema = z29.object({
|
|
3414
|
+
version: z29.literal(2),
|
|
3415
|
+
apiBaseUrl: z29.string().url(),
|
|
3416
|
+
siteId: z29.string().uuid(),
|
|
3417
|
+
publicSiteKeyId: z29.string().uuid(),
|
|
3418
|
+
publicSiteKey: z29.string().trim().min(1),
|
|
3419
|
+
runId: z29.string().uuid(),
|
|
3420
|
+
appDirectory: z29.string().min(1),
|
|
3421
|
+
taskContractVersion: z29.literal("siteplane.setup-task.v2"),
|
|
3422
|
+
adminProtocolVersion: z29.literal(2),
|
|
3412
3423
|
packages: siteSetupPackagesSchema,
|
|
3413
|
-
fieldContractHash:
|
|
3424
|
+
fieldContractHash: z29.string().regex(/^sha256:[0-9a-f]{64}$/iu).optional()
|
|
3414
3425
|
}).strict();
|
|
3415
3426
|
async function readProjectPackageJson(projectDir) {
|
|
3416
3427
|
return JSON.parse(await readFile5(join3(projectDir, "package.json"), "utf8"));
|
|
@@ -3470,15 +3481,27 @@ import { randomUUID as randomUUID3 } from "crypto";
|
|
|
3470
3481
|
import { chmod as chmod2, lstat, mkdir as mkdir5, open as open2, readFile as readFile6, rename as rename2, rm as rm2 } from "fs/promises";
|
|
3471
3482
|
import { dirname as dirname5, join as join4, relative } from "path";
|
|
3472
3483
|
import { promisify } from "util";
|
|
3473
|
-
import { z as
|
|
3474
|
-
var
|
|
3475
|
-
|
|
3476
|
-
|
|
3477
|
-
|
|
3478
|
-
|
|
3479
|
-
|
|
3484
|
+
import { z as z30 } from "zod";
|
|
3485
|
+
var localSetupInstallationSchema = z30.object({
|
|
3486
|
+
key: z30.string().regex(/^[A-Za-z0-9_-]{43}$/u),
|
|
3487
|
+
idempotencyKey: z30.string().uuid(),
|
|
3488
|
+
apiBaseUrl: z30.string().url(),
|
|
3489
|
+
request: setupInstallationRequestSchema,
|
|
3490
|
+
bootstrapAcknowledged: z30.boolean()
|
|
3491
|
+
}).strict();
|
|
3492
|
+
var siteplaneCredentialsSchema = z30.object({
|
|
3493
|
+
accessToken: z30.string().trim().min(1),
|
|
3494
|
+
siteRevalidationSecret: z30.string().trim().min(1),
|
|
3495
|
+
installation: localSetupInstallationSchema.optional(),
|
|
3496
|
+
adminSession: z30.object({
|
|
3497
|
+
secret: z30.string().regex(/^[A-Za-z0-9_-]{43}$/u),
|
|
3498
|
+
generation: z30.string().uuid()
|
|
3480
3499
|
}).strict().optional()
|
|
3481
3500
|
}).strict();
|
|
3501
|
+
var localSetupCredentialsSchema = z30.union([
|
|
3502
|
+
siteplaneCredentialsSchema,
|
|
3503
|
+
z30.object({ installation: localSetupInstallationSchema }).strict()
|
|
3504
|
+
]);
|
|
3482
3505
|
async function assertLocalCredentialsPathSafe(projectDir, options = {}) {
|
|
3483
3506
|
const path = join4(projectDir, ".siteplane/credentials.json");
|
|
3484
3507
|
await assertCredentialFilesystemSafe(projectDir);
|
|
@@ -3514,15 +3537,25 @@ async function assertCredentialFilesystemSafe(projectDir) {
|
|
|
3514
3537
|
}
|
|
3515
3538
|
}
|
|
3516
3539
|
async function writeLocalCredentials(projectDir, credentials, options = {}) {
|
|
3540
|
+
return writeLocalSetupCredentials(projectDir, siteplaneCredentialsSchema.parse(credentials), options);
|
|
3541
|
+
}
|
|
3542
|
+
async function writeLocalSetupCredentials(projectDir, credentials, options = {}) {
|
|
3517
3543
|
const path = await assertLocalCredentialsPathSafe(projectDir, options);
|
|
3518
|
-
const parsed =
|
|
3544
|
+
const parsed = localSetupCredentialsSchema.parse(credentials);
|
|
3519
3545
|
await mkdir5(dirname5(path), { recursive: true, mode: 448 });
|
|
3520
3546
|
await writeCredentialsAtomically(path, parsed);
|
|
3521
3547
|
return path;
|
|
3522
3548
|
}
|
|
3523
3549
|
async function readLocalCredentials(projectDir) {
|
|
3550
|
+
const credentials = await readLocalSetupCredentials(projectDir);
|
|
3551
|
+
if (!("accessToken" in credentials)) {
|
|
3552
|
+
throw new Error("setup_exchange_pending: Run siteplane setup start to finish the stored installation exchange.");
|
|
3553
|
+
}
|
|
3554
|
+
return credentials;
|
|
3555
|
+
}
|
|
3556
|
+
async function readLocalSetupCredentials(projectDir) {
|
|
3524
3557
|
await assertCredentialFilesystemSafe(projectDir);
|
|
3525
|
-
return
|
|
3558
|
+
return localSetupCredentialsSchema.parse(JSON.parse(await readFile6(join4(projectDir, ".siteplane/credentials.json"), "utf8")));
|
|
3526
3559
|
}
|
|
3527
3560
|
async function writeCredentialsAtomically(path, credentials) {
|
|
3528
3561
|
const temporaryPath = `${path}.${randomUUID3()}.tmp`;
|
|
@@ -3559,7 +3592,7 @@ async function gitPathMatches(projectDir, path, command) {
|
|
|
3559
3592
|
// ../cli/dist/commands/init.js
|
|
3560
3593
|
import { access as access3 } from "fs/promises";
|
|
3561
3594
|
import { join as join7, relative as relative3 } from "path";
|
|
3562
|
-
import { z as
|
|
3595
|
+
import { z as z33 } from "zod";
|
|
3563
3596
|
|
|
3564
3597
|
// ../cli/dist/commands/setup-preflight.js
|
|
3565
3598
|
import { createHash as createHash2 } from "crypto";
|
|
@@ -3571,11 +3604,11 @@ import { parse as parseYaml } from "yaml";
|
|
|
3571
3604
|
import { createRequire } from "module";
|
|
3572
3605
|
import { readFile as readFile7 } from "fs/promises";
|
|
3573
3606
|
import { join as join5 } from "path";
|
|
3574
|
-
import { z as
|
|
3575
|
-
var packageSchema =
|
|
3576
|
-
name:
|
|
3577
|
-
version:
|
|
3578
|
-
peerDependencies:
|
|
3607
|
+
import { z as z31 } from "zod";
|
|
3608
|
+
var packageSchema = z31.object({
|
|
3609
|
+
name: z31.string().optional(),
|
|
3610
|
+
version: z31.string(),
|
|
3611
|
+
peerDependencies: z31.record(z31.string(), z31.string()).optional()
|
|
3579
3612
|
});
|
|
3580
3613
|
async function readInstalledPackage(projectDir, name2) {
|
|
3581
3614
|
const require2 = createRequire(join5(projectDir, "package.json"));
|
|
@@ -3590,9 +3623,9 @@ async function readInstalledPackage(projectDir, name2) {
|
|
|
3590
3623
|
throw new Error(`Install ${name2} with the canonical package manager before setup.`);
|
|
3591
3624
|
}
|
|
3592
3625
|
async function assertExactSetupPackages(projectDir, packages) {
|
|
3593
|
-
const manifest =
|
|
3594
|
-
dependencies:
|
|
3595
|
-
devDependencies:
|
|
3626
|
+
const manifest = z31.object({
|
|
3627
|
+
dependencies: z31.record(z31.string(), z31.string()).optional(),
|
|
3628
|
+
devDependencies: z31.record(z31.string(), z31.string()).optional()
|
|
3596
3629
|
}).parse(JSON.parse(await readFile7(join5(projectDir, "package.json"), "utf8")));
|
|
3597
3630
|
for (const [name2, version2] of [
|
|
3598
3631
|
["siteplane", packages.siteplane],
|
|
@@ -3609,7 +3642,7 @@ async function assertExactSetupPackages(projectDir, packages) {
|
|
|
3609
3642
|
// ../cli/dist/commands/setup-preflight.js
|
|
3610
3643
|
import { access as access2, readFile as readFile8, realpath, readdir, readlink } from "fs/promises";
|
|
3611
3644
|
import { dirname as dirname6, join as join6, relative as relative2, resolve, sep } from "path";
|
|
3612
|
-
import { z as
|
|
3645
|
+
import { z as z32 } from "zod";
|
|
3613
3646
|
|
|
3614
3647
|
// ../cli/dist/commands/setup-process.js
|
|
3615
3648
|
import { spawn } from "child_process";
|
|
@@ -3710,29 +3743,29 @@ async function setupVercelApi(cwd, endpoint, body, method, options) {
|
|
|
3710
3743
|
}
|
|
3711
3744
|
|
|
3712
3745
|
// ../cli/dist/commands/setup-preflight.js
|
|
3713
|
-
var manifestSchema =
|
|
3714
|
-
packageManager:
|
|
3715
|
-
engines:
|
|
3716
|
-
dependencies:
|
|
3717
|
-
devDependencies:
|
|
3718
|
-
scripts:
|
|
3719
|
-
workspaces:
|
|
3746
|
+
var manifestSchema = z32.object({
|
|
3747
|
+
packageManager: z32.string().optional(),
|
|
3748
|
+
engines: z32.object({ node: z32.string().optional() }).optional(),
|
|
3749
|
+
dependencies: z32.record(z32.string(), z32.string()).optional(),
|
|
3750
|
+
devDependencies: z32.record(z32.string(), z32.string()).optional(),
|
|
3751
|
+
scripts: z32.record(z32.string(), z32.string()).optional(),
|
|
3752
|
+
workspaces: z32.unknown().optional()
|
|
3720
3753
|
});
|
|
3721
|
-
var vercelProjectSchema =
|
|
3722
|
-
id:
|
|
3723
|
-
accountId:
|
|
3724
|
-
name:
|
|
3725
|
-
nodeVersion:
|
|
3726
|
-
rootDirectory:
|
|
3727
|
-
framework:
|
|
3728
|
-
installCommand:
|
|
3729
|
-
buildCommand:
|
|
3730
|
-
link:
|
|
3731
|
-
type:
|
|
3732
|
-
repo:
|
|
3733
|
-
repoId:
|
|
3734
|
-
org:
|
|
3735
|
-
productionBranch:
|
|
3754
|
+
var vercelProjectSchema = z32.object({
|
|
3755
|
+
id: z32.string(),
|
|
3756
|
+
accountId: z32.string(),
|
|
3757
|
+
name: z32.string(),
|
|
3758
|
+
nodeVersion: z32.string().nullable().optional(),
|
|
3759
|
+
rootDirectory: z32.string().nullable().optional(),
|
|
3760
|
+
framework: z32.string().nullable().optional(),
|
|
3761
|
+
installCommand: z32.string().nullable().optional(),
|
|
3762
|
+
buildCommand: z32.string().nullable().optional(),
|
|
3763
|
+
link: z32.object({
|
|
3764
|
+
type: z32.string(),
|
|
3765
|
+
repo: z32.string().optional(),
|
|
3766
|
+
repoId: z32.union([z32.string(), z32.number()]).optional(),
|
|
3767
|
+
org: z32.string().optional(),
|
|
3768
|
+
productionBranch: z32.string().optional()
|
|
3736
3769
|
}).nullable().optional()
|
|
3737
3770
|
});
|
|
3738
3771
|
var exists = async (path) => access2(path).then(() => true, () => false);
|
|
@@ -3789,9 +3822,9 @@ async function inspectSetupLocalProject(projectDir) {
|
|
|
3789
3822
|
const rootManifest = manifestSchema.parse(JSON.parse(await readFile8(join6(lockfileRoot, "package.json"), "utf8")));
|
|
3790
3823
|
if (lockfileRoot !== projectDirectory) {
|
|
3791
3824
|
const workspaceFile = join6(lockfileRoot, "pnpm-workspace.yaml");
|
|
3792
|
-
const workspace = lockName === "pnpm-lock.yaml" && await exists(workspaceFile) ?
|
|
3793
|
-
|
|
3794
|
-
|
|
3825
|
+
const workspace = lockName === "pnpm-lock.yaml" && await exists(workspaceFile) ? z32.object({ packages: z32.array(z32.string()) }).parse(parseYaml(await readFile8(workspaceFile, "utf8"))).packages : z32.union([
|
|
3826
|
+
z32.array(z32.string()),
|
|
3827
|
+
z32.object({ packages: z32.array(z32.string()) }).transform((value) => value.packages)
|
|
3795
3828
|
]).parse(rootManifest.workspaces);
|
|
3796
3829
|
const selected = relative2(lockfileRoot, projectDirectory).split(sep).join("/");
|
|
3797
3830
|
if (!workspace.some((pattern) => !pattern.startsWith("!") && minimatch(selected, pattern)) || workspace.some((pattern) => pattern.startsWith("!") && minimatch(selected, pattern.slice(1))))
|
|
@@ -3805,11 +3838,11 @@ async function inspectSetupLocalProject(projectDir) {
|
|
|
3805
3838
|
break;
|
|
3806
3839
|
}
|
|
3807
3840
|
const lockText = await readFile8(join6(lockfileRoot, lockName), "utf8");
|
|
3808
|
-
const npmLock = lockName === "package-lock.json" ?
|
|
3809
|
-
lockfileVersion:
|
|
3810
|
-
packages:
|
|
3811
|
-
version:
|
|
3812
|
-
peerDependencies:
|
|
3841
|
+
const npmLock = lockName === "package-lock.json" ? z32.object({
|
|
3842
|
+
lockfileVersion: z32.number(),
|
|
3843
|
+
packages: z32.record(z32.string(), z32.object({
|
|
3844
|
+
version: z32.string().optional(),
|
|
3845
|
+
peerDependencies: z32.record(z32.string(), z32.string()).optional()
|
|
3813
3846
|
})).optional()
|
|
3814
3847
|
}).parse(JSON.parse(lockText)) : null;
|
|
3815
3848
|
async function version2(name3) {
|
|
@@ -3949,9 +3982,9 @@ async function setupPreflightCommand(input) {
|
|
|
3949
3982
|
linkDirectory = dirname6(linkDirectory);
|
|
3950
3983
|
if (!await exists(join6(linkDirectory, ".vercel/project.json")))
|
|
3951
3984
|
fail("vercel_project_not_linked", "Link this application to its intended Vercel project before setup; Siteplane will not guess a target.");
|
|
3952
|
-
const linked =
|
|
3953
|
-
projectId:
|
|
3954
|
-
orgId:
|
|
3985
|
+
const linked = z32.object({
|
|
3986
|
+
projectId: z32.string().regex(/^prj_[A-Za-z0-9]+$/u),
|
|
3987
|
+
orgId: z32.string().regex(/^(?:team|user)_[A-Za-z0-9]+$/u)
|
|
3955
3988
|
}).parse(JSON.parse(await readFile8(join6(linkDirectory, ".vercel/project.json"), "utf8")));
|
|
3956
3989
|
const project = vercelProjectSchema.parse(await setupVercelApi(linkDirectory, `/v9/projects/${linked.projectId}?teamId=${linked.orgId}`));
|
|
3957
3990
|
if (project.id !== linked.projectId || project.accountId !== linked.orgId)
|
|
@@ -3965,11 +3998,11 @@ async function setupPreflightCommand(input) {
|
|
|
3965
3998
|
fail("vercel_production_branch_conflict", "The local branch differs from the bound Vercel Production branch.");
|
|
3966
3999
|
if (project.link?.repo && project.link.org && !local.git.remote?.replace(/\.git$/u, "").endsWith(`${project.link.org}/${project.link.repo}`))
|
|
3967
4000
|
fail("vercel_git_conflict", "The local origin repository differs from the Vercel Git connection.");
|
|
3968
|
-
const env =
|
|
3969
|
-
envs:
|
|
3970
|
-
key:
|
|
3971
|
-
value:
|
|
3972
|
-
target:
|
|
4001
|
+
const env = z32.object({
|
|
4002
|
+
envs: z32.array(z32.object({
|
|
4003
|
+
key: z32.string(),
|
|
4004
|
+
value: z32.string().optional(),
|
|
4005
|
+
target: z32.array(z32.string()).optional()
|
|
3973
4006
|
}))
|
|
3974
4007
|
}).parse(await setupVercelApi(linkDirectory, `/v10/projects/${linked.projectId}/env?teamId=${linked.orgId}`));
|
|
3975
4008
|
const corepack = env.envs.some((item) => item.key === "ENABLE_EXPERIMENTAL_COREPACK" && item.value === "1" && item.target?.includes("production"));
|
|
@@ -4059,26 +4092,26 @@ async function initCommand(input) {
|
|
|
4059
4092
|
]
|
|
4060
4093
|
};
|
|
4061
4094
|
}
|
|
4062
|
-
var siteSetupBootstrapDataSchema =
|
|
4063
|
-
credentialPurpose:
|
|
4064
|
-
apiBaseUrl:
|
|
4065
|
-
siteId:
|
|
4066
|
-
publicSiteKeyId:
|
|
4067
|
-
publicSiteKey:
|
|
4068
|
-
accessToken:
|
|
4069
|
-
siteRevalidationSecret:
|
|
4070
|
-
runId:
|
|
4095
|
+
var siteSetupBootstrapDataSchema = z33.object({
|
|
4096
|
+
credentialPurpose: z33.literal("site_setup"),
|
|
4097
|
+
apiBaseUrl: z33.string().url(),
|
|
4098
|
+
siteId: z33.string().uuid(),
|
|
4099
|
+
publicSiteKeyId: z33.string().uuid(),
|
|
4100
|
+
publicSiteKey: z33.string().trim().min(1),
|
|
4101
|
+
accessToken: z33.string().trim().min(1),
|
|
4102
|
+
siteRevalidationSecret: z33.string().regex(/^[A-Za-z0-9_-]{43}$/u),
|
|
4103
|
+
runId: z33.string().uuid(),
|
|
4071
4104
|
packages: siteSetupPackagesSchema
|
|
4072
4105
|
}).strict();
|
|
4073
|
-
var featureBootstrapDataSchema =
|
|
4074
|
-
credentialPurpose:
|
|
4075
|
-
apiBaseUrl:
|
|
4076
|
-
siteId:
|
|
4077
|
-
accessToken:
|
|
4106
|
+
var featureBootstrapDataSchema = z33.object({
|
|
4107
|
+
credentialPurpose: z33.enum(["analytics", "booking"]),
|
|
4108
|
+
apiBaseUrl: z33.string().url(),
|
|
4109
|
+
siteId: z33.string().uuid(),
|
|
4110
|
+
accessToken: z33.string().trim().min(1)
|
|
4078
4111
|
}).strict();
|
|
4079
|
-
var bootstrapResponseSchema =
|
|
4080
|
-
ok:
|
|
4081
|
-
data:
|
|
4112
|
+
var bootstrapResponseSchema = z33.object({
|
|
4113
|
+
ok: z33.literal(true),
|
|
4114
|
+
data: z33.discriminatedUnion("credentialPurpose", [
|
|
4082
4115
|
siteSetupBootstrapDataSchema,
|
|
4083
4116
|
featureBootstrapDataSchema
|
|
4084
4117
|
])
|
|
@@ -4115,15 +4148,16 @@ async function acknowledgeBootstrapResponse(input) {
|
|
|
4115
4148
|
throw new Error("Siteplane setup acknowledgement failed.");
|
|
4116
4149
|
}
|
|
4117
4150
|
}
|
|
4118
|
-
async function persistSiteSetupBootstrap(input, bootstrap, appDirectory) {
|
|
4151
|
+
async function persistSiteSetupBootstrap(input, bootstrap, appDirectory, installation) {
|
|
4119
4152
|
const previous = await access3(join7(input.projectDir, "siteplane.config.json")).then(() => readProjectConfig(input.projectDir), () => null);
|
|
4120
4153
|
if (previous && (previous.siteId !== bootstrap.siteId || previous.runId !== bootstrap.runId || previous.publicSiteKeyId !== bootstrap.publicSiteKeyId || previous.publicSiteKey !== bootstrap.publicSiteKey))
|
|
4121
4154
|
throw new Error("The grant does not match this local Siteplane run. Preserve this directory and choose the correct owner connection.");
|
|
4122
|
-
const previousCredentials = previous ? await access3(join7(input.projectDir, ".siteplane/credentials.json")).then(() =>
|
|
4155
|
+
const previousCredentials = previous ? await access3(join7(input.projectDir, ".siteplane/credentials.json")).then(() => readLocalSetupCredentials(input.projectDir), () => null) : null;
|
|
4123
4156
|
const credentialsPath = await writeLocalCredentials(input.projectDir, {
|
|
4124
|
-
...previousCredentials
|
|
4157
|
+
...previousCredentials && "adminSession" in previousCredentials && previousCredentials.adminSession ? { adminSession: previousCredentials.adminSession } : {},
|
|
4125
4158
|
accessToken: bootstrap.accessToken,
|
|
4126
|
-
siteRevalidationSecret: bootstrap.siteRevalidationSecret
|
|
4159
|
+
siteRevalidationSecret: bootstrap.siteRevalidationSecret,
|
|
4160
|
+
...installation ?? previousCredentials?.installation ? { installation: installation ?? previousCredentials?.installation } : {}
|
|
4127
4161
|
}, {
|
|
4128
4162
|
...input.isIgnoredFile ? { isIgnoredFile: input.isIgnoredFile } : {},
|
|
4129
4163
|
...input.isTrackedFile ? { isTrackedFile: input.isTrackedFile } : {}
|
|
@@ -4236,7 +4270,7 @@ async function collectSourceFiles(directory) {
|
|
|
4236
4270
|
import { execFile as execFile2 } from "child_process";
|
|
4237
4271
|
import { readFile as readFile9 } from "fs/promises";
|
|
4238
4272
|
import { promisify as promisify2 } from "util";
|
|
4239
|
-
import { z as
|
|
4273
|
+
import { z as z34 } from "zod";
|
|
4240
4274
|
|
|
4241
4275
|
// ../cli/dist/scan/next-source-scan.js
|
|
4242
4276
|
import ts2 from "typescript";
|
|
@@ -4337,6 +4371,14 @@ function scanSourceFacts(files) {
|
|
|
4337
4371
|
}
|
|
4338
4372
|
for (const attr of directAttrs) {
|
|
4339
4373
|
const field = fields.find((candidate) => candidate.fieldId === attr.fieldId);
|
|
4374
|
+
if (field && attr.fieldType !== field.fieldType) {
|
|
4375
|
+
warnings.push({
|
|
4376
|
+
code: "field_scan.attrs_field_type_mismatch",
|
|
4377
|
+
message: `DOM attrs for ${attr.fieldId} declare ${attr.fieldType}, but its value call returns ${field.fieldType}. Pass fieldType: "${field.fieldType}" with the matching routeKey to siteplane.attrs on the visible element. This affects editor preview, not the website build.`,
|
|
4378
|
+
fieldId: attr.fieldId,
|
|
4379
|
+
filePath: attr.filePath
|
|
4380
|
+
});
|
|
4381
|
+
}
|
|
4340
4382
|
const expectedRoute = field?.technicalRouteKey ?? field?.routeHint;
|
|
4341
4383
|
if (!attr.routeKey || expectedRoute && attr.routeKey !== expectedRoute) {
|
|
4342
4384
|
hardErrors.push({
|
|
@@ -4618,6 +4660,7 @@ function collectAttrsCall(node, attrFieldIds, attrRouteRefs, eventPreviewAttrs,
|
|
|
4618
4660
|
directAttrs.push({
|
|
4619
4661
|
fieldId: directFieldId,
|
|
4620
4662
|
routeKey: secondArg && typeof secondArg === "object" && "routeKey" in secondArg ? stringValue2(secondArg.routeKey) : void 0,
|
|
4663
|
+
fieldType: secondArg && typeof secondArg === "object" && "fieldType" in secondArg ? stringValue2(secondArg.fieldType) ?? "text" : "text",
|
|
4621
4664
|
filePath: file.filePath
|
|
4622
4665
|
});
|
|
4623
4666
|
if (hasEventPreviewStrategy(secondArg)) {
|
|
@@ -4924,32 +4967,32 @@ function isPositionalFieldReference(value) {
|
|
|
4924
4967
|
|
|
4925
4968
|
// ../cli/dist/commands/site-setup.js
|
|
4926
4969
|
var execFileAsync2 = promisify2(execFile2);
|
|
4927
|
-
var safeErrorSchema =
|
|
4928
|
-
code:
|
|
4929
|
-
message:
|
|
4970
|
+
var safeErrorSchema = z34.object({
|
|
4971
|
+
code: z34.string().trim().min(1),
|
|
4972
|
+
message: z34.string().trim().min(1)
|
|
4930
4973
|
}).passthrough();
|
|
4931
|
-
var errorResponseSchema2 =
|
|
4932
|
-
var contextDataSchema =
|
|
4974
|
+
var errorResponseSchema2 = z34.object({ ok: z34.literal(false), error: safeErrorSchema }).passthrough();
|
|
4975
|
+
var contextDataSchema = z34.object({
|
|
4933
4976
|
task: siteSetupTaskSchema.refine((task) => task.run !== null)
|
|
4934
4977
|
}).strict();
|
|
4935
|
-
var contextResponseSchema =
|
|
4936
|
-
var applyDataSchema =
|
|
4937
|
-
status:
|
|
4938
|
-
runId:
|
|
4939
|
-
contractVersionId:
|
|
4940
|
-
fieldContractHash:
|
|
4941
|
-
editorDefinitionHash:
|
|
4942
|
-
fieldCount:
|
|
4943
|
-
routeCount:
|
|
4978
|
+
var contextResponseSchema = z34.object({ ok: z34.literal(true), data: contextDataSchema }).strict();
|
|
4979
|
+
var applyDataSchema = z34.object({
|
|
4980
|
+
status: z34.enum(["applied", "ready_for_review"]),
|
|
4981
|
+
runId: z34.string().uuid().optional(),
|
|
4982
|
+
contractVersionId: z34.string().uuid().optional(),
|
|
4983
|
+
fieldContractHash: z34.string().regex(/^sha256:[0-9a-f]{64}$/u),
|
|
4984
|
+
editorDefinitionHash: z34.string().regex(/^sha256:[0-9a-f]{64}$/u).optional(),
|
|
4985
|
+
fieldCount: z34.number().int().nonnegative().optional(),
|
|
4986
|
+
routeCount: z34.number().int().nonnegative().optional()
|
|
4944
4987
|
}).strict();
|
|
4945
|
-
var applyResponseSchema =
|
|
4946
|
-
var verifyDataSchema =
|
|
4947
|
-
status:
|
|
4948
|
-
runId:
|
|
4949
|
-
deploymentOrigin:
|
|
4950
|
-
deploymentRevision:
|
|
4988
|
+
var applyResponseSchema = z34.object({ ok: z34.literal(true), data: applyDataSchema }).strict();
|
|
4989
|
+
var verifyDataSchema = z34.object({
|
|
4990
|
+
status: z34.literal("ready_for_review"),
|
|
4991
|
+
runId: z34.string().uuid().optional(),
|
|
4992
|
+
deploymentOrigin: z34.string().url().optional(),
|
|
4993
|
+
deploymentRevision: z34.string().optional()
|
|
4951
4994
|
}).strict();
|
|
4952
|
-
var verifyResponseSchema =
|
|
4995
|
+
var verifyResponseSchema = z34.object({ ok: z34.literal(true), data: verifyDataSchema }).strict();
|
|
4953
4996
|
async function siteSetupContextCommand(input) {
|
|
4954
4997
|
const response = await postSiteSetup(input, "context", {});
|
|
4955
4998
|
const parsed = contextResponseSchema.safeParse(response.payload);
|
|
@@ -4979,6 +5022,14 @@ async function siteSetupApplyCommand(input) {
|
|
|
4979
5022
|
sourceText: await readSourceFile(filePath)
|
|
4980
5023
|
})));
|
|
4981
5024
|
const scan = scanSourceFiles(files, { projectRoot: input.projectDir });
|
|
5025
|
+
const invalidDomTypes = scan.warnings.filter((issue) => issue.code === "field_scan.attrs_field_type_mismatch");
|
|
5026
|
+
if (invalidDomTypes.length > 0) {
|
|
5027
|
+
return {
|
|
5028
|
+
status: "action_required",
|
|
5029
|
+
code: "field_scan.attrs_field_type_mismatch",
|
|
5030
|
+
message: invalidDomTypes.map((issue) => issue.message).join("\n")
|
|
5031
|
+
};
|
|
5032
|
+
}
|
|
4982
5033
|
if (scan.hardErrors.length > 0) {
|
|
4983
5034
|
return {
|
|
4984
5035
|
status: "action_required",
|
|
@@ -5105,21 +5156,154 @@ async function siteSetupActivityCommand(input) {
|
|
|
5105
5156
|
message: "Choose inspecting, integrating, deploying, verifying or repairing."
|
|
5106
5157
|
};
|
|
5107
5158
|
const response = await postSiteSetup(input, "activity", activity.data);
|
|
5108
|
-
const parsed =
|
|
5109
|
-
ok:
|
|
5110
|
-
data:
|
|
5159
|
+
const parsed = z34.object({
|
|
5160
|
+
ok: z34.literal(true),
|
|
5161
|
+
data: z34.object({ status: z34.enum(["recorded", "rate_limited"]) }).strict()
|
|
5111
5162
|
}).strict().safeParse(response.payload);
|
|
5112
5163
|
return response.ok && parsed.success ? parsed.data.data : actionRequired(response.payload, "Setup activity could not be recorded.");
|
|
5113
5164
|
}
|
|
5114
5165
|
|
|
5166
|
+
// ../cli/dist/commands/setup-start.js
|
|
5167
|
+
import { randomBytes, randomUUID as randomUUID4 } from "crypto";
|
|
5168
|
+
import { access as access4 } from "fs/promises";
|
|
5169
|
+
import { join as join9, relative as relative5 } from "path";
|
|
5170
|
+
import { z as z35 } from "zod";
|
|
5171
|
+
var bootstrapResponseSchema2 = z35.object({
|
|
5172
|
+
ok: z35.literal(true),
|
|
5173
|
+
data: siteSetupBootstrapDataSchema
|
|
5174
|
+
}).strict();
|
|
5175
|
+
async function setupStartCommand(input) {
|
|
5176
|
+
await assertLocalCredentialsPathSafe(input.projectDir, input);
|
|
5177
|
+
const [hasConfig, hasCredentials] = await Promise.all([
|
|
5178
|
+
exists2(join9(input.projectDir, "siteplane.config.json")),
|
|
5179
|
+
exists2(join9(input.projectDir, ".siteplane/credentials.json"))
|
|
5180
|
+
]);
|
|
5181
|
+
if (hasConfig && !hasCredentials) {
|
|
5182
|
+
throw new SetupFailure("local_credentials_missing", "This project has Siteplane configuration but no local credentials. Restore its credentials or explicitly start a new installation; public site identifiers cannot recover access.");
|
|
5183
|
+
}
|
|
5184
|
+
let credentials = hasCredentials ? await readLocalSetupCredentials(input.projectDir) : null;
|
|
5185
|
+
const config = hasConfig ? await readProjectConfig(input.projectDir) : null;
|
|
5186
|
+
const apiBaseUrl = new URL(input.apiBaseUrl).origin;
|
|
5187
|
+
const previous = credentials?.installation;
|
|
5188
|
+
if (config && new URL(config.apiBaseUrl).origin !== apiBaseUrl || previous && previous.apiBaseUrl !== apiBaseUrl) {
|
|
5189
|
+
throw new SetupFailure("installation_origin_mismatch", "Use the API origin stored for this installation. Credentials are never transferred to another origin.");
|
|
5190
|
+
}
|
|
5191
|
+
if (previous && (input.modules && JSON.stringify(input.modules) !== JSON.stringify(previous.request.modules) || input.instructions !== void 0 && input.instructions !== previous.request.ownerEditabilityNote)) {
|
|
5192
|
+
throw new SetupFailure("installation_request_conflict", "The stored installation has a different authorized request. Resume that request; module changes require explicit authorization in Siteplane.");
|
|
5193
|
+
}
|
|
5194
|
+
if (config && credentials && "accessToken" in credentials) {
|
|
5195
|
+
if (previous && !previous.bootstrapAcknowledged)
|
|
5196
|
+
await acknowledge(input, credentials);
|
|
5197
|
+
return result("resumed", config.siteId, config.runId);
|
|
5198
|
+
}
|
|
5199
|
+
if (credentials && !previous) {
|
|
5200
|
+
throw new SetupFailure("local_configuration_missing", "Restore the configuration belonging to these credentials. A new installation will not replace them.");
|
|
5201
|
+
}
|
|
5202
|
+
const preflight = await (input.preflight ?? setupPreflightCommand)({
|
|
5203
|
+
projectDir: input.projectDir
|
|
5204
|
+
});
|
|
5205
|
+
if (preflight.status !== "ready")
|
|
5206
|
+
throw new SetupFailure(preflight.code, preflight.message);
|
|
5207
|
+
const request = setupInstallationRequestSchema.parse({
|
|
5208
|
+
modules: input.modules ?? previous?.request.modules ?? ["editing"],
|
|
5209
|
+
ownerEditabilityNote: input.instructions ?? previous?.request.ownerEditabilityNote ?? "",
|
|
5210
|
+
provider: {
|
|
5211
|
+
projectId: preflight.provider.projectId,
|
|
5212
|
+
teamId: preflight.provider.teamId
|
|
5213
|
+
}
|
|
5214
|
+
});
|
|
5215
|
+
if (previous && JSON.stringify(request) !== JSON.stringify(previous.request)) {
|
|
5216
|
+
throw new SetupFailure("installation_request_conflict", "The local provider project or request changed. Resume from the original authorized project.");
|
|
5217
|
+
}
|
|
5218
|
+
const installation = previous ?? {
|
|
5219
|
+
key: randomBytes(32).toString("base64url"),
|
|
5220
|
+
idempotencyKey: randomUUID4(),
|
|
5221
|
+
apiBaseUrl,
|
|
5222
|
+
request,
|
|
5223
|
+
bootstrapAcknowledged: false
|
|
5224
|
+
};
|
|
5225
|
+
if (!credentials) {
|
|
5226
|
+
await writeLocalSetupCredentials(input.projectDir, { installation }, input);
|
|
5227
|
+
credentials = await readLocalSetupCredentials(input.projectDir);
|
|
5228
|
+
if (JSON.stringify(credentials.installation) !== JSON.stringify(installation)) {
|
|
5229
|
+
throw new Error("The pending installation could not be verified.");
|
|
5230
|
+
}
|
|
5231
|
+
}
|
|
5232
|
+
const payload = await installationRequest(input, installation, "provision");
|
|
5233
|
+
const parsed = bootstrapResponseSchema2.parse(payload);
|
|
5234
|
+
if (new URL(parsed.data.apiBaseUrl).origin !== apiBaseUrl) {
|
|
5235
|
+
throw new SetupFailure("installation_origin_mismatch", "The setup response belongs to another API origin.");
|
|
5236
|
+
}
|
|
5237
|
+
await persistSiteSetupBootstrap(input, parsed.data, relative5(preflight.local.lockfileRoot, preflight.local.projectDirectory) || ".", installation);
|
|
5238
|
+
await acknowledge(input, await readLocalSetupCredentials(input.projectDir));
|
|
5239
|
+
return result("created", parsed.data.siteId, parsed.data.runId);
|
|
5240
|
+
}
|
|
5241
|
+
async function acknowledge(input, credentials) {
|
|
5242
|
+
const installation = credentials.installation;
|
|
5243
|
+
if (!installation || !("accessToken" in credentials))
|
|
5244
|
+
throw new Error("Incomplete installation exchange.");
|
|
5245
|
+
const payload = await installationRequest(input, installation, "acknowledge");
|
|
5246
|
+
z35.object({
|
|
5247
|
+
ok: z35.literal(true),
|
|
5248
|
+
data: z35.object({ acknowledged: z35.literal(true) }).strict()
|
|
5249
|
+
}).strict().parse(payload);
|
|
5250
|
+
await writeLocalSetupCredentials(input.projectDir, {
|
|
5251
|
+
...credentials,
|
|
5252
|
+
installation: { ...installation, bootstrapAcknowledged: true }
|
|
5253
|
+
}, input);
|
|
5254
|
+
}
|
|
5255
|
+
async function installationRequest(input, installation, action) {
|
|
5256
|
+
const response = await (input.fetcher ?? fetch)(`${installation.apiBaseUrl}/api/cli/setup/installations`, {
|
|
5257
|
+
method: "POST",
|
|
5258
|
+
redirect: "error",
|
|
5259
|
+
signal: AbortSignal.timeout(2e4),
|
|
5260
|
+
headers: {
|
|
5261
|
+
authorization: `Bearer ${installation.key}`,
|
|
5262
|
+
"content-type": "application/json",
|
|
5263
|
+
"idempotency-key": installation.idempotencyKey
|
|
5264
|
+
},
|
|
5265
|
+
body: JSON.stringify({ action, request: installation.request })
|
|
5266
|
+
});
|
|
5267
|
+
const payload = await response.json();
|
|
5268
|
+
if (!response.ok) {
|
|
5269
|
+
const error = z35.object({
|
|
5270
|
+
error: z35.object({
|
|
5271
|
+
code: z35.string().regex(/^[a-z][a-z0-9_.]{0,100}$/u)
|
|
5272
|
+
})
|
|
5273
|
+
}).safeParse(payload);
|
|
5274
|
+
throw new SetupFailure(error.success ? error.data.error.code : "setup_start_failed", "Siteplane could not complete this installation request. The saved local key and request are unchanged; retry after resolving the reported boundary.");
|
|
5275
|
+
}
|
|
5276
|
+
return payload;
|
|
5277
|
+
}
|
|
5278
|
+
function result(status, siteId, runId) {
|
|
5279
|
+
return {
|
|
5280
|
+
status,
|
|
5281
|
+
siteId,
|
|
5282
|
+
runId,
|
|
5283
|
+
nextSteps: [
|
|
5284
|
+
"Run npx siteplane setup context and follow its authorized task."
|
|
5285
|
+
]
|
|
5286
|
+
};
|
|
5287
|
+
}
|
|
5288
|
+
async function exists2(path) {
|
|
5289
|
+
try {
|
|
5290
|
+
await access4(path);
|
|
5291
|
+
return true;
|
|
5292
|
+
} catch (error) {
|
|
5293
|
+
if (error.code === "ENOENT")
|
|
5294
|
+
return false;
|
|
5295
|
+
throw error;
|
|
5296
|
+
}
|
|
5297
|
+
}
|
|
5298
|
+
|
|
5115
5299
|
// ../cli/dist/commands/setup-prepare.js
|
|
5116
|
-
import { access as
|
|
5117
|
-
import { randomUUID as
|
|
5118
|
-
import { dirname as dirname7, join as
|
|
5300
|
+
import { access as access5, lstat as lstat2, mkdir as mkdir6, open as open3, readFile as readFile10, rename as rename3, rm as rm3 } from "fs/promises";
|
|
5301
|
+
import { randomUUID as randomUUID5 } from "crypto";
|
|
5302
|
+
import { dirname as dirname7, join as join10, relative as relative6, sep as sep2 } from "path";
|
|
5119
5303
|
import ts3 from "typescript";
|
|
5120
|
-
var
|
|
5304
|
+
var exists3 = async (path) => access5(path).then(() => true, () => false);
|
|
5121
5305
|
var importPath = (from, target) => {
|
|
5122
|
-
const path =
|
|
5306
|
+
const path = relative6(dirname7(from), target).split(sep2).join("/");
|
|
5123
5307
|
return path.startsWith(".") ? path : `./${path}`;
|
|
5124
5308
|
};
|
|
5125
5309
|
async function setupPrepareCommand(input) {
|
|
@@ -5141,18 +5325,18 @@ async function setupPrepareCommand(input) {
|
|
|
5141
5325
|
message: "The verified setup is available for owner review; no preparation writes are needed."
|
|
5142
5326
|
};
|
|
5143
5327
|
const directory = preflight.local.projectDirectory;
|
|
5144
|
-
const app =
|
|
5145
|
-
const layouts = (await Promise.all(["layout.tsx", "layout.jsx", "layout.js"].map(async (name2) => await
|
|
5328
|
+
const app = join10(directory, preflight.local.appDirectory);
|
|
5329
|
+
const layouts = (await Promise.all(["layout.tsx", "layout.jsx", "layout.js"].map(async (name2) => await exists3(join10(app, name2)) ? join10(app, name2) : null))).filter((path) => path !== null);
|
|
5146
5330
|
if (layouts.length !== 1)
|
|
5147
5331
|
throw new SetupFailure("layout_integration_conflict", "Select one root layout and mount the Siteplane preview bridge there; preserve existing providers and rendering.");
|
|
5148
5332
|
const layoutPath = layouts[0];
|
|
5149
5333
|
const typed = layoutPath.endsWith(".tsx");
|
|
5150
5334
|
const routeExtension = typed ? "ts" : "js";
|
|
5151
|
-
const bridgePath =
|
|
5335
|
+
const bridgePath = join10(app, "_siteplane", `bridge.${typed ? "tsx" : "jsx"}`);
|
|
5152
5336
|
const portal = task.site.portalPath;
|
|
5153
5337
|
if (!/^\/[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/u.test(portal))
|
|
5154
5338
|
throw new SetupFailure("portal_route_conflict", "The selected portal path is not a supported single route segment.");
|
|
5155
|
-
const adminRoot =
|
|
5339
|
+
const adminRoot = join10(app, portal.slice(1));
|
|
5156
5340
|
for (const name2 of [
|
|
5157
5341
|
"page.tsx",
|
|
5158
5342
|
"page.jsx",
|
|
@@ -5160,12 +5344,12 @@ async function setupPrepareCommand(input) {
|
|
|
5160
5344
|
"route.ts",
|
|
5161
5345
|
"route.js"
|
|
5162
5346
|
]) {
|
|
5163
|
-
if (await
|
|
5347
|
+
if (await exists3(join10(adminRoot, name2)))
|
|
5164
5348
|
throw new SetupFailure("portal_route_conflict", "The selected admin path already belongs to the website. Choose an unused editor path in Siteplane.");
|
|
5165
5349
|
}
|
|
5166
|
-
const configPath =
|
|
5167
|
-
const adminPath =
|
|
5168
|
-
const revalidationPath =
|
|
5350
|
+
const configPath = join10(directory, "siteplane.config.json");
|
|
5351
|
+
const adminPath = join10(adminRoot, "[[...siteplane]]", `route.${routeExtension}`);
|
|
5352
|
+
const revalidationPath = join10(app, "api/siteplane/revalidate", `route.${routeExtension}`);
|
|
5169
5353
|
const commonOptions = `siteId: config.siteId,
|
|
5170
5354
|
publicRuntimeKeyId: config.publicSiteKeyId,
|
|
5171
5355
|
fieldContractHash: process.env.SITEPLANE_BUILD_FIELD_CONTRACT_HASH${typed ? "!" : ""},
|
|
@@ -5236,10 +5420,10 @@ export default function SiteplaneBridge() {
|
|
|
5236
5420
|
files.set(layoutPath, `import SiteplaneBridge from "./_siteplane/bridge";
|
|
5237
5421
|
${layoutSource.slice(0, point)}<SiteplaneBridge />${layoutSource.slice(point)}`);
|
|
5238
5422
|
}
|
|
5239
|
-
const configs = (await Promise.all(["next.config.ts", "next.config.mjs", "next.config.js"].map(async (name2) => await
|
|
5423
|
+
const configs = (await Promise.all(["next.config.ts", "next.config.mjs", "next.config.js"].map(async (name2) => await exists3(join10(directory, name2)) ? join10(directory, name2) : null))).filter((path) => path !== null);
|
|
5240
5424
|
if (configs.length > 1)
|
|
5241
5425
|
throw new SetupFailure("next_config_conflict", "Choose one existing Next.js configuration before setup.");
|
|
5242
|
-
const nextPath = configs[0] ??
|
|
5426
|
+
const nextPath = configs[0] ?? join10(directory, "next.config.mjs");
|
|
5243
5427
|
const nextSource = configs.length ? await readFile10(nextPath, "utf8") : "export default {};\n";
|
|
5244
5428
|
if (!/\bwithSiteplane\s*\(/u.test(nextSource)) {
|
|
5245
5429
|
const ast = ts3.createSourceFile(nextPath, nextSource, ts3.ScriptTarget.Latest, true);
|
|
@@ -5250,7 +5434,7 @@ ${layoutSource.slice(0, point)}<SiteplaneBridge />${layoutSource.slice(point)}`)
|
|
|
5250
5434
|
files.set(nextPath, `import { withSiteplane } from "siteplane/next";
|
|
5251
5435
|
${nextSource.slice(0, expression.getStart(ast))}withSiteplane(${expression.getText(ast)})${nextSource.slice(expression.end)}`);
|
|
5252
5436
|
}
|
|
5253
|
-
files.set(
|
|
5437
|
+
files.set(join10(directory, ".siteplane/setup-guide-v2.md"), `# Siteplane setup task v2
|
|
5254
5438
|
|
|
5255
5439
|
${task.goal}
|
|
5256
5440
|
|
|
@@ -5263,8 +5447,8 @@ Run setup context for the current user instructions and authorized modules. Keep
|
|
|
5263
5447
|
for (const [path, content] of files) {
|
|
5264
5448
|
if (path === layoutPath || path === nextPath)
|
|
5265
5449
|
continue;
|
|
5266
|
-
if (await
|
|
5267
|
-
throw new SetupFailure("owned_file_conflict", `Preserve the existing ${
|
|
5450
|
+
if (await exists3(path) && await readFile10(path, "utf8") !== content)
|
|
5451
|
+
throw new SetupFailure("owned_file_conflict", `Preserve the existing ${relative6(directory, path)} and reconcile its integration with the current Siteplane guide before retrying.`);
|
|
5268
5452
|
}
|
|
5269
5453
|
for (const path of files.keys())
|
|
5270
5454
|
await assertSourcePath(directory, path);
|
|
@@ -5275,7 +5459,7 @@ Run setup context for the current user instructions and authorized modules. Keep
|
|
|
5275
5459
|
return null;
|
|
5276
5460
|
throw error;
|
|
5277
5461
|
}));
|
|
5278
|
-
const packageManifest = JSON.parse(await readFile10(
|
|
5462
|
+
const packageManifest = JSON.parse(await readFile10(join10(directory, "package.json"), "utf8"));
|
|
5279
5463
|
const pm = preflight.local.packageManager;
|
|
5280
5464
|
const command = (args) => setupProcess("npx", ["--yes", `${pm.name}@${pm.version}`, ...args], {
|
|
5281
5465
|
cwd: directory,
|
|
@@ -5330,7 +5514,7 @@ Run setup context for the current user instructions and authorized modules. Keep
|
|
|
5330
5514
|
recursive: true,
|
|
5331
5515
|
mode: path.includes(`${sep2}.siteplane${sep2}`) ? 448 : 493
|
|
5332
5516
|
});
|
|
5333
|
-
const temporary = `${path}.${
|
|
5517
|
+
const temporary = `${path}.${randomUUID5()}.tmp`;
|
|
5334
5518
|
const handle = await open3(temporary, "wx", path.includes(`${sep2}.siteplane${sep2}`) ? 384 : 420);
|
|
5335
5519
|
try {
|
|
5336
5520
|
await handle.writeFile(content, "utf8");
|
|
@@ -5349,7 +5533,7 @@ Run setup context for the current user instructions and authorized modules. Keep
|
|
|
5349
5533
|
await handle.close().catch(() => void 0);
|
|
5350
5534
|
await rm3(temporary, { force: true });
|
|
5351
5535
|
}
|
|
5352
|
-
written.push(
|
|
5536
|
+
written.push(relative6(directory, path));
|
|
5353
5537
|
}
|
|
5354
5538
|
return {
|
|
5355
5539
|
status: "prepared",
|
|
@@ -5368,10 +5552,10 @@ Run setup context for the current user instructions and authorized modules. Keep
|
|
|
5368
5552
|
}
|
|
5369
5553
|
async function assertSourcePath(root, target) {
|
|
5370
5554
|
let current = root;
|
|
5371
|
-
for (const part of
|
|
5555
|
+
for (const part of relative6(root, target).split(sep2)) {
|
|
5372
5556
|
if (part === "..")
|
|
5373
5557
|
throw new SetupFailure("unsafe_source_path", "The prepared file is outside the selected application.");
|
|
5374
|
-
current =
|
|
5558
|
+
current = join10(current, part);
|
|
5375
5559
|
const stat = await lstat2(current).catch((error) => {
|
|
5376
5560
|
if (error.code === "ENOENT")
|
|
5377
5561
|
return null;
|
|
@@ -5383,15 +5567,15 @@ async function assertSourcePath(root, target) {
|
|
|
5383
5567
|
}
|
|
5384
5568
|
|
|
5385
5569
|
// ../cli/dist/commands/setup-lock.js
|
|
5386
|
-
import { randomUUID as
|
|
5570
|
+
import { randomUUID as randomUUID6 } from "crypto";
|
|
5387
5571
|
import { lstat as lstat3, mkdir as mkdir7, open as open4, readFile as readFile11, rm as rm4, rmdir } from "fs/promises";
|
|
5388
5572
|
import { resolve as resolve2 } from "path";
|
|
5389
|
-
import { z as
|
|
5390
|
-
var ownerSchema =
|
|
5573
|
+
import { z as z36 } from "zod";
|
|
5574
|
+
var ownerSchema = z36.object({ pid: z36.number().int().positive(), nonce: z36.string().uuid() }).strict();
|
|
5391
5575
|
async function withSetupLock(projectDir, work) {
|
|
5392
5576
|
const gitPath = (await setupProcess("git", ["rev-parse", "--git-path", "siteplane-setup.lock"], { cwd: projectDir })).trim();
|
|
5393
5577
|
const path = resolve2(projectDir, gitPath);
|
|
5394
|
-
const owner = { pid: process.pid, nonce:
|
|
5578
|
+
const owner = { pid: process.pid, nonce: randomUUID6() };
|
|
5395
5579
|
for (let attempt = 0; ; attempt++) {
|
|
5396
5580
|
try {
|
|
5397
5581
|
const handle = await open4(path, "wx", 384);
|
|
@@ -5449,25 +5633,25 @@ function locked() {
|
|
|
5449
5633
|
import { createHash as createHash3 } from "crypto";
|
|
5450
5634
|
import { execFile as execFile3 } from "child_process";
|
|
5451
5635
|
import { lstat as lstat4, readFile as readFile12, writeFile as writeFile5, mkdir as mkdir8 } from "fs/promises";
|
|
5452
|
-
import { dirname as dirname8, isAbsolute as isAbsolute2, join as
|
|
5636
|
+
import { dirname as dirname8, isAbsolute as isAbsolute2, join as join11, relative as relative7, resolve as resolve3, sep as sep3 } from "path";
|
|
5453
5637
|
import { isDeepStrictEqual, promisify as promisify3 } from "util";
|
|
5454
|
-
import { z as
|
|
5638
|
+
import { z as z37 } from "zod";
|
|
5455
5639
|
var execute = promisify3(execFile3);
|
|
5456
5640
|
var name = ".siteplane/build-source.json";
|
|
5457
|
-
var oid =
|
|
5458
|
-
var entrySchema =
|
|
5459
|
-
path:
|
|
5460
|
-
mode:
|
|
5641
|
+
var oid = z37.string().regex(/^[0-9a-f]{40}$/u);
|
|
5642
|
+
var entrySchema = z37.object({
|
|
5643
|
+
path: z37.string().min(1).max(4096),
|
|
5644
|
+
mode: z37.enum(["100644", "100755", "120000"]),
|
|
5461
5645
|
oid
|
|
5462
5646
|
}).strict();
|
|
5463
|
-
var schema =
|
|
5464
|
-
version:
|
|
5647
|
+
var schema = z37.object({
|
|
5648
|
+
version: z37.literal(2),
|
|
5465
5649
|
revision: oid,
|
|
5466
|
-
commit:
|
|
5467
|
-
entries:
|
|
5468
|
-
providerConfigurations:
|
|
5469
|
-
path:
|
|
5470
|
-
source:
|
|
5650
|
+
commit: z37.string().min(1).max(1048576),
|
|
5651
|
+
entries: z37.array(entrySchema).min(1).max(1e5),
|
|
5652
|
+
providerConfigurations: z37.array(z37.object({
|
|
5653
|
+
path: z37.string().max(4096).regex(/(?:^|\/)vercel\.json$/u),
|
|
5654
|
+
source: z37.string().max(1048576)
|
|
5471
5655
|
}).strict()).max(1e3)
|
|
5472
5656
|
}).strict();
|
|
5473
5657
|
async function writeBuildProvenance(checkout, revision) {
|
|
@@ -5489,15 +5673,15 @@ async function writeBuildProvenance(checkout, revision) {
|
|
|
5489
5673
|
if (entry.mode !== "120000")
|
|
5490
5674
|
continue;
|
|
5491
5675
|
const { readlink: readlink2 } = await import("fs/promises");
|
|
5492
|
-
const path =
|
|
5676
|
+
const path = join11(checkout, entry.path);
|
|
5493
5677
|
const target2 = resolve3(dirname8(path), await readlink2(path));
|
|
5494
|
-
const bound =
|
|
5678
|
+
const bound = relative7(checkout, target2);
|
|
5495
5679
|
if (bound.startsWith("..") || isAbsolute2(bound))
|
|
5496
5680
|
throw new Error("A tracked symbolic link escapes the committed upload; resolve that source boundary before deployment.");
|
|
5497
5681
|
}
|
|
5498
5682
|
const providerConfigurations = await Promise.all(entries.filter((entry) => /(?:^|\/)vercel\.json$/u.test(entry.path)).map(async (entry) => ({
|
|
5499
5683
|
path: entry.path,
|
|
5500
|
-
source: await readFile12(
|
|
5684
|
+
source: await readFile12(join11(checkout, entry.path), "utf8")
|
|
5501
5685
|
})));
|
|
5502
5686
|
const record = schema.parse({
|
|
5503
5687
|
version: 2,
|
|
@@ -5506,48 +5690,48 @@ async function writeBuildProvenance(checkout, revision) {
|
|
|
5506
5690
|
entries,
|
|
5507
5691
|
providerConfigurations
|
|
5508
5692
|
});
|
|
5509
|
-
const target =
|
|
5693
|
+
const target = join11(checkout, name);
|
|
5510
5694
|
await mkdir8(dirname8(target), { recursive: true, mode: 448 });
|
|
5511
5695
|
await writeFile5(target, JSON.stringify(record), { flag: "wx", mode: 384 });
|
|
5512
5696
|
}
|
|
5513
5697
|
|
|
5514
5698
|
// ../cli/dist/commands/setup-deploy.js
|
|
5515
|
-
import { createHash as createHash4, randomBytes, randomUUID as
|
|
5516
|
-
import { access as
|
|
5699
|
+
import { createHash as createHash4, randomBytes as randomBytes2, randomUUID as randomUUID7 } from "crypto";
|
|
5700
|
+
import { access as access6, mkdir as mkdir9, mkdtemp, rm as rm5, writeFile as writeFile6 } from "fs/promises";
|
|
5517
5701
|
import { tmpdir } from "os";
|
|
5518
|
-
import { join as
|
|
5519
|
-
import { z as
|
|
5520
|
-
var envSchema =
|
|
5521
|
-
id:
|
|
5522
|
-
key:
|
|
5523
|
-
target:
|
|
5524
|
-
type:
|
|
5525
|
-
comment:
|
|
5526
|
-
updatedAt:
|
|
5702
|
+
import { join as join12 } from "path";
|
|
5703
|
+
import { z as z38 } from "zod";
|
|
5704
|
+
var envSchema = z38.object({
|
|
5705
|
+
id: z38.string(),
|
|
5706
|
+
key: z38.string(),
|
|
5707
|
+
target: z38.array(z38.string()),
|
|
5708
|
+
type: z38.string(),
|
|
5709
|
+
comment: z38.string().optional(),
|
|
5710
|
+
updatedAt: z38.number().optional()
|
|
5527
5711
|
});
|
|
5528
|
-
var deploymentSchema =
|
|
5529
|
-
id:
|
|
5530
|
-
projectId:
|
|
5531
|
-
ownerId:
|
|
5532
|
-
target:
|
|
5533
|
-
readyState:
|
|
5534
|
-
createdAt:
|
|
5535
|
-
url:
|
|
5536
|
-
meta:
|
|
5537
|
-
gitSource:
|
|
5712
|
+
var deploymentSchema = z38.object({
|
|
5713
|
+
id: z38.string(),
|
|
5714
|
+
projectId: z38.string(),
|
|
5715
|
+
ownerId: z38.string().optional(),
|
|
5716
|
+
target: z38.string().nullable(),
|
|
5717
|
+
readyState: z38.string(),
|
|
5718
|
+
createdAt: z38.number(),
|
|
5719
|
+
url: z38.string(),
|
|
5720
|
+
meta: z38.record(z38.string(), z38.unknown()).optional(),
|
|
5721
|
+
gitSource: z38.object({ sha: z38.string().optional() }).nullable().optional()
|
|
5538
5722
|
});
|
|
5539
|
-
var buildProofSchema =
|
|
5540
|
-
node:
|
|
5541
|
-
packageManager:
|
|
5542
|
-
packageManagerVersion:
|
|
5543
|
-
lockfileHash:
|
|
5544
|
-
revision:
|
|
5545
|
-
fieldContractHash:
|
|
5546
|
-
siteplane:
|
|
5547
|
-
runtimeNext:
|
|
5548
|
-
analytics:
|
|
5549
|
-
next:
|
|
5550
|
-
react:
|
|
5723
|
+
var buildProofSchema = z38.object({
|
|
5724
|
+
node: z38.string(),
|
|
5725
|
+
packageManager: z38.enum(["npm", "pnpm"]),
|
|
5726
|
+
packageManagerVersion: z38.string(),
|
|
5727
|
+
lockfileHash: z38.string(),
|
|
5728
|
+
revision: z38.string(),
|
|
5729
|
+
fieldContractHash: z38.string(),
|
|
5730
|
+
siteplane: z38.string(),
|
|
5731
|
+
runtimeNext: z38.string(),
|
|
5732
|
+
analytics: z38.string().optional(),
|
|
5733
|
+
next: z38.string(),
|
|
5734
|
+
react: z38.string()
|
|
5551
5735
|
}).strict();
|
|
5552
5736
|
var digest = (value) => `sha256:${createHash4("sha256").update(stableJsonStringify(value)).digest("hex")}`;
|
|
5553
5737
|
function fail2(code, message) {
|
|
@@ -5568,7 +5752,7 @@ var defaults = {
|
|
|
5568
5752
|
async function setupDeployCommand(input, deps = defaults) {
|
|
5569
5753
|
let record = null;
|
|
5570
5754
|
try {
|
|
5571
|
-
if (!await
|
|
5755
|
+
if (!await access6(join12(input.projectDir, "siteplane.config.json")).then(() => true, () => false) || !await access6(join12(input.projectDir, ".siteplane/credentials.json")).then(() => true, () => false))
|
|
5572
5756
|
fail2("local_connection_missing", "Open this site's setup and choose Replace local connection, then initialize this folder with its new one-time grant.");
|
|
5573
5757
|
await assertLocalCredentialsPathSafe(input.projectDir);
|
|
5574
5758
|
const config = await readProjectConfig(input.projectDir);
|
|
@@ -5628,16 +5812,16 @@ async function setupDeployCommand(input, deps = defaults) {
|
|
|
5628
5812
|
const scope = `teamId=${provider.teamId}`;
|
|
5629
5813
|
const api = async (endpoint, body, method) => {
|
|
5630
5814
|
remaining();
|
|
5631
|
-
const
|
|
5815
|
+
const result2 = await deps.api(local.projectDirectory, endpoint, body, method, { deadline: operationDeadline });
|
|
5632
5816
|
remaining();
|
|
5633
|
-
return
|
|
5817
|
+
return result2;
|
|
5634
5818
|
};
|
|
5635
|
-
const domains =
|
|
5636
|
-
domains:
|
|
5637
|
-
name:
|
|
5638
|
-
verified:
|
|
5639
|
-
redirect:
|
|
5640
|
-
gitBranch:
|
|
5819
|
+
const domains = z38.object({
|
|
5820
|
+
domains: z38.array(z38.object({
|
|
5821
|
+
name: z38.string(),
|
|
5822
|
+
verified: z38.boolean(),
|
|
5823
|
+
redirect: z38.string().nullable().optional(),
|
|
5824
|
+
gitBranch: z38.string().nullable().optional()
|
|
5641
5825
|
}))
|
|
5642
5826
|
}).parse(await api(`/v9/projects/${provider.projectId}/domains?${scope}`)).domains.filter((domain) => domain.verified && !domain.redirect && !domain.gitBranch);
|
|
5643
5827
|
const origin = record?.origin ?? (domains.length === 1 ? `https://${domains[0].name}` : null);
|
|
@@ -5645,7 +5829,7 @@ async function setupDeployCommand(input, deps = defaults) {
|
|
|
5645
5829
|
fail2("production_origin_ambiguous", "The linked project needs one verified canonical Production domain, or the existing setup domain must still belong to it.");
|
|
5646
5830
|
if (record && (record.projectId !== provider.projectId || record.teamId !== provider.teamId))
|
|
5647
5831
|
fail2("deployment_target_conflict", "This setup already belongs to a different provider project/team. Restore its original local link.");
|
|
5648
|
-
const listEnv = async () =>
|
|
5832
|
+
const listEnv = async () => z38.object({ envs: z38.array(envSchema) }).parse(await api(`/v10/projects/${provider.projectId}/env?${scope}`)).envs;
|
|
5649
5833
|
let env = await listEnv();
|
|
5650
5834
|
const owned = (key) => {
|
|
5651
5835
|
const matches2 = env.filter((item) => item.key === key && item.target.includes("production"));
|
|
@@ -5662,8 +5846,8 @@ async function setupDeployCommand(input, deps = defaults) {
|
|
|
5662
5846
|
credentials = {
|
|
5663
5847
|
...credentials,
|
|
5664
5848
|
adminSession: {
|
|
5665
|
-
secret:
|
|
5666
|
-
generation:
|
|
5849
|
+
secret: randomBytes2(32).toString("base64url"),
|
|
5850
|
+
generation: randomUUID7()
|
|
5667
5851
|
}
|
|
5668
5852
|
};
|
|
5669
5853
|
await writeLocalCredentials(input.projectDir, credentials);
|
|
@@ -5713,16 +5897,16 @@ async function setupDeployCommand(input, deps = defaults) {
|
|
|
5713
5897
|
lockfileHash: local.lockfile.sha256
|
|
5714
5898
|
});
|
|
5715
5899
|
const save = async (next) => {
|
|
5716
|
-
const
|
|
5900
|
+
const result2 = await deps.post({ ...input, deadline: operationDeadline }, "deployment", {
|
|
5717
5901
|
action: "record",
|
|
5718
5902
|
expectedOperationId: record?.operationId ?? null,
|
|
5719
5903
|
record: next
|
|
5720
5904
|
});
|
|
5721
|
-
const parsed =
|
|
5722
|
-
ok:
|
|
5723
|
-
data:
|
|
5724
|
-
}).strict().safeParse(
|
|
5725
|
-
if (!
|
|
5905
|
+
const parsed = z38.object({
|
|
5906
|
+
ok: z38.literal(true),
|
|
5907
|
+
data: z38.object({ record: setupDeploymentRecordSchema }).strict()
|
|
5908
|
+
}).strict().safeParse(result2.payload);
|
|
5909
|
+
if (!result2.ok || !parsed.success || stableJsonStringify(parsed.data.data.record) !== stableJsonStringify(next))
|
|
5726
5910
|
fail2("deployment_record_unconfirmed", "The setup deployment record was not acknowledged. Reload context before continuing; no deployment is blindly repeated.");
|
|
5727
5911
|
record = parsed.data.data.record;
|
|
5728
5912
|
if (next.phase === "planned")
|
|
@@ -5730,7 +5914,7 @@ async function setupDeployCommand(input, deps = defaults) {
|
|
|
5730
5914
|
};
|
|
5731
5915
|
const fresh = () => ({
|
|
5732
5916
|
version: 1,
|
|
5733
|
-
operationId:
|
|
5917
|
+
operationId: randomUUID7(),
|
|
5734
5918
|
provider: "vercel",
|
|
5735
5919
|
projectId: provider.projectId,
|
|
5736
5920
|
teamId: provider.teamId,
|
|
@@ -5770,7 +5954,7 @@ async function setupDeployCommand(input, deps = defaults) {
|
|
|
5770
5954
|
const item = owned(key);
|
|
5771
5955
|
if (key === "SITEPLANE_ADMIN_SESSION_SECRET" && item && record.phase === "verified")
|
|
5772
5956
|
continue;
|
|
5773
|
-
const current = item ?
|
|
5957
|
+
const current = item ? z38.object({ key: z38.literal(key), value: z38.string() }).parse(await api(`/v1/projects/${provider.projectId}/env/${encodeURIComponent(item.id)}?${scope}`)).value : null;
|
|
5774
5958
|
if (current !== value)
|
|
5775
5959
|
pending.push({
|
|
5776
5960
|
key,
|
|
@@ -5795,7 +5979,7 @@ async function setupDeployCommand(input, deps = defaults) {
|
|
|
5795
5979
|
const item = owned(key);
|
|
5796
5980
|
if (!item)
|
|
5797
5981
|
fail2("environment_write_unconfirmed", "A Siteplane Production binding was not persisted; retry the same configuration.");
|
|
5798
|
-
const observed =
|
|
5982
|
+
const observed = z38.object({ key: z38.literal(key), value: z38.string() }).parse(await api(`/v1/projects/${provider.projectId}/env/${encodeURIComponent(item.id)}?${scope}`));
|
|
5799
5983
|
if (observed.value !== value)
|
|
5800
5984
|
fail2("environment_write_unconfirmed", "The provider readback does not match the authorized Siteplane value; no deployment was started.");
|
|
5801
5985
|
}
|
|
@@ -5808,9 +5992,9 @@ async function setupDeployCommand(input, deps = defaults) {
|
|
|
5808
5992
|
const detail = async (id) => deploymentSchema.parse(await api(`/v13/deployments/${encodeURIComponent(id)}?${scope}&withGitRepoInfo=true`));
|
|
5809
5993
|
const matches = (deployment2) => deployment2.projectId === provider.projectId && deployment2.target === "production" && (!deployment2.ownerId || deployment2.ownerId === provider.teamId) && deployment2.createdAt >= Date.parse(record.environmentWrittenAt) && (deployment2.meta?.siteplaneOperationId === record.operationId || provider.git && (deployment2.gitSource?.sha ?? deployment2.meta?.githubCommitSha ?? deployment2.meta?.gitlabCommitSha ?? deployment2.meta?.bitbucketCommitSha ?? deployment2.meta?.gitCommitSha) === revision);
|
|
5810
5994
|
const discover = async () => {
|
|
5811
|
-
const
|
|
5995
|
+
const result2 = z38.object({ deployments: z38.array(z38.object({ uid: z38.string() })) }).parse(await api(`/v6/deployments?${scope}&projectId=${provider.projectId}&target=production&since=${Date.parse(record.environmentWrittenAt)}&limit=100`));
|
|
5812
5996
|
const candidates = [];
|
|
5813
|
-
for (const item of
|
|
5997
|
+
for (const item of result2.deployments) {
|
|
5814
5998
|
const found = await detail(item.uid);
|
|
5815
5999
|
if (matches(found))
|
|
5816
6000
|
candidates.push(found);
|
|
@@ -5863,7 +6047,7 @@ async function setupDeployCommand(input, deps = defaults) {
|
|
|
5863
6047
|
], { cwd: local.projectDirectory, input: body, timeoutMs: 3e4 });
|
|
5864
6048
|
}
|
|
5865
6049
|
} else {
|
|
5866
|
-
const upload = await mkdtemp(
|
|
6050
|
+
const upload = await mkdtemp(join12(tmpdir(), "siteplane-setup-upload-"));
|
|
5867
6051
|
try {
|
|
5868
6052
|
await processCommand("git", [
|
|
5869
6053
|
"clone",
|
|
@@ -5877,11 +6061,11 @@ async function setupDeployCommand(input, deps = defaults) {
|
|
|
5877
6061
|
cwd: upload
|
|
5878
6062
|
});
|
|
5879
6063
|
await deps.writeBuildProvenance(upload, revision);
|
|
5880
|
-
await mkdir9(
|
|
6064
|
+
await mkdir9(join12(upload, ".vercel"), {
|
|
5881
6065
|
recursive: true,
|
|
5882
6066
|
mode: 448
|
|
5883
6067
|
});
|
|
5884
|
-
await writeFile6(
|
|
6068
|
+
await writeFile6(join12(upload, ".vercel/project.json"), JSON.stringify({
|
|
5885
6069
|
projectId: provider.projectId,
|
|
5886
6070
|
orgId: provider.teamId
|
|
5887
6071
|
}), { mode: 384 });
|
|
@@ -5983,8 +6167,8 @@ async function setupDeployCommand(input, deps = defaults) {
|
|
|
5983
6167
|
|
|
5984
6168
|
// src/bin/run-siteplane.ts
|
|
5985
6169
|
async function runSiteplaneCli(args, dependencies = createDefaultDependencies()) {
|
|
5986
|
-
const writes = args[0] === "init" || args[0] === "analytics" && args[1] === "init" || args[0] === "setup" && ["apply", "prepare", "deploy"].includes(args[1] ?? "");
|
|
5987
|
-
const missingDeploy = args[0] === "setup" && args[1] === "deploy" && !await
|
|
6170
|
+
const writes = args[0] === "init" || args[0] === "analytics" && args[1] === "init" || args[0] === "setup" && ["start", "apply", "prepare", "deploy"].includes(args[1] ?? "");
|
|
6171
|
+
const missingDeploy = args[0] === "setup" && args[1] === "deploy" && !await access7(join13(dependencies.cwd(), "siteplane.config.json")).then(
|
|
5988
6172
|
() => true,
|
|
5989
6173
|
() => false
|
|
5990
6174
|
);
|
|
@@ -6001,18 +6185,18 @@ async function runSiteplaneCliUnlocked(args, dependencies = createDefaultDepende
|
|
|
6001
6185
|
if (!setupToken) {
|
|
6002
6186
|
throw new Error("Usage: siteplane init --setup-token <one-time-grant>");
|
|
6003
6187
|
}
|
|
6004
|
-
const
|
|
6188
|
+
const result2 = await dependencies.commands.initCommand({
|
|
6005
6189
|
projectDir: dependencies.cwd(),
|
|
6006
6190
|
setupToken,
|
|
6007
6191
|
apiBaseUrl,
|
|
6008
6192
|
...readOptionalVercelAutomationBypassSecret(dependencies.env)
|
|
6009
6193
|
});
|
|
6010
|
-
dependencies.stdout(`Wrote ${
|
|
6011
|
-
dependencies.stdout(`Wrote ${
|
|
6194
|
+
dependencies.stdout(`Wrote ${result2.configPath}`);
|
|
6195
|
+
dependencies.stdout(`Wrote ${result2.credentialsPath}`);
|
|
6012
6196
|
dependencies.stdout(
|
|
6013
6197
|
"Siteplane setup connection stored securely. Next steps:"
|
|
6014
6198
|
);
|
|
6015
|
-
for (const nextStep of
|
|
6199
|
+
for (const nextStep of result2.nextSteps)
|
|
6016
6200
|
dependencies.stdout(`- ${nextStep}`);
|
|
6017
6201
|
return { exitCode: 0 };
|
|
6018
6202
|
}
|
|
@@ -6066,7 +6250,7 @@ async function runAnalyticsCommand(args, dependencies) {
|
|
|
6066
6250
|
siteId: projectConfig.siteId,
|
|
6067
6251
|
...readOptionalVercelAutomationBypassSecret(dependencies.env)
|
|
6068
6252
|
};
|
|
6069
|
-
const manifestPath =
|
|
6253
|
+
const manifestPath = join13(projectDir, "siteplane.analytics.json");
|
|
6070
6254
|
if (subcommand === "init") {
|
|
6071
6255
|
const { rawPublicKey } = await dependencies.commands.analyticsPrepareCommand({
|
|
6072
6256
|
config
|
|
@@ -6078,15 +6262,15 @@ async function runAnalyticsCommand(args, dependencies) {
|
|
|
6078
6262
|
);
|
|
6079
6263
|
}
|
|
6080
6264
|
const agentClient = readAnalyticsAgentClient(subcommandArgs);
|
|
6081
|
-
const
|
|
6265
|
+
const result2 = await dependencies.commands.analyticsInitCommand({
|
|
6082
6266
|
projectDir,
|
|
6083
6267
|
siteId: projectConfig.siteId,
|
|
6084
6268
|
siteKeyRef: "env:NEXT_PUBLIC_SITEPLANE_ANALYTICS_SITE_KEY",
|
|
6085
6269
|
siteKeyLookup,
|
|
6086
6270
|
...agentClient ? { agentClient } : {}
|
|
6087
6271
|
});
|
|
6088
|
-
dependencies.stdout(`Wrote ${
|
|
6089
|
-
for (const artifactPath of
|
|
6272
|
+
dependencies.stdout(`Wrote ${result2.manifestPath}`);
|
|
6273
|
+
for (const artifactPath of result2.artifactPaths) {
|
|
6090
6274
|
dependencies.stdout(`Wrote ${artifactPath}`);
|
|
6091
6275
|
}
|
|
6092
6276
|
return { exitCode: 0 };
|
|
@@ -6098,18 +6282,18 @@ async function runAnalyticsCommand(args, dependencies) {
|
|
|
6098
6282
|
projectDir
|
|
6099
6283
|
}
|
|
6100
6284
|
);
|
|
6101
|
-
const artifactFilePaths = [
|
|
6285
|
+
const artifactFilePaths = [join13(projectDir, ".siteplane/analytics.md")];
|
|
6102
6286
|
const cspFilePaths = await existingPaths([
|
|
6103
|
-
|
|
6104
|
-
|
|
6105
|
-
|
|
6106
|
-
|
|
6107
|
-
|
|
6287
|
+
join13(projectDir, "next.config.js"),
|
|
6288
|
+
join13(projectDir, "next.config.mjs"),
|
|
6289
|
+
join13(projectDir, "next.config.ts"),
|
|
6290
|
+
join13(projectDir, "middleware.ts"),
|
|
6291
|
+
join13(projectDir, "src/middleware.ts")
|
|
6108
6292
|
]);
|
|
6109
6293
|
const check = await dependencies.commands.analyticsCheckCommand({
|
|
6110
6294
|
manifestPath,
|
|
6111
6295
|
sourceFilePaths,
|
|
6112
|
-
packageJsonPath:
|
|
6296
|
+
packageJsonPath: join13(projectDir, "package.json"),
|
|
6113
6297
|
cspFilePaths,
|
|
6114
6298
|
artifactFilePaths
|
|
6115
6299
|
});
|
|
@@ -6177,50 +6361,66 @@ async function runSetupCommand(args, dependencies) {
|
|
|
6177
6361
|
const connectionOptions = readOptionalVercelAutomationBypassSecret(
|
|
6178
6362
|
dependencies.env
|
|
6179
6363
|
);
|
|
6364
|
+
if (area === "start") {
|
|
6365
|
+
const instructionsFile = readOption(areaArgs, "--instructions-file");
|
|
6366
|
+
const modules = readOption(areaArgs, "--modules");
|
|
6367
|
+
const result2 = await dependencies.commands.setupStartCommand({
|
|
6368
|
+
projectDir,
|
|
6369
|
+
apiBaseUrl: readOption(areaArgs, "--api-base-url") ?? dependencies.env.SITEPLANE_API_BASE_URL ?? "https://siteplane.io",
|
|
6370
|
+
...modules ? { modules: modules.split(",") } : {},
|
|
6371
|
+
...instructionsFile ? {
|
|
6372
|
+
instructions: await dependencies.readTextFile(
|
|
6373
|
+
resolve4(projectDir, instructionsFile)
|
|
6374
|
+
)
|
|
6375
|
+
} : {}
|
|
6376
|
+
});
|
|
6377
|
+
dependencies.stdout(JSON.stringify(result2, null, 2));
|
|
6378
|
+
return { exitCode: 0 };
|
|
6379
|
+
}
|
|
6180
6380
|
if (area === "deploy") {
|
|
6181
|
-
const
|
|
6381
|
+
const result2 = await dependencies.commands.setupDeployCommand({
|
|
6182
6382
|
projectDir,
|
|
6183
6383
|
onProgress: (progress) => dependencies.stderr(JSON.stringify({ status: "waiting", ...progress }))
|
|
6184
6384
|
});
|
|
6185
|
-
dependencies.stdout(JSON.stringify(
|
|
6186
|
-
return { exitCode:
|
|
6385
|
+
dependencies.stdout(JSON.stringify(result2, null, 2));
|
|
6386
|
+
return { exitCode: result2.status === "ready_for_review" ? 0 : 1 };
|
|
6187
6387
|
}
|
|
6188
6388
|
if (area === "preflight") {
|
|
6189
|
-
const
|
|
6389
|
+
const result2 = await dependencies.commands.setupPreflightCommand({
|
|
6190
6390
|
projectDir
|
|
6191
6391
|
});
|
|
6192
|
-
dependencies.stdout(JSON.stringify(
|
|
6193
|
-
return { exitCode:
|
|
6392
|
+
dependencies.stdout(JSON.stringify(result2, null, 2));
|
|
6393
|
+
return { exitCode: result2.status === "ready" ? 0 : 1 };
|
|
6194
6394
|
}
|
|
6195
6395
|
if (area === "prepare") {
|
|
6196
|
-
const
|
|
6396
|
+
const result2 = await dependencies.commands.setupPrepareCommand({
|
|
6197
6397
|
projectDir
|
|
6198
6398
|
});
|
|
6199
|
-
dependencies.stdout(JSON.stringify(
|
|
6200
|
-
return { exitCode:
|
|
6399
|
+
dependencies.stdout(JSON.stringify(result2, null, 2));
|
|
6400
|
+
return { exitCode: result2.status === "action_required" ? 1 : 0 };
|
|
6201
6401
|
}
|
|
6202
6402
|
if (area === "context") {
|
|
6203
|
-
const
|
|
6403
|
+
const result2 = await dependencies.commands.siteSetupContextCommand({
|
|
6204
6404
|
projectDir,
|
|
6205
6405
|
...connectionOptions
|
|
6206
6406
|
});
|
|
6207
|
-
dependencies.stdout(JSON.stringify(
|
|
6208
|
-
return { exitCode:
|
|
6407
|
+
dependencies.stdout(JSON.stringify(result2, null, 2));
|
|
6408
|
+
return { exitCode: result2.status === "action_required" ? 1 : 0 };
|
|
6209
6409
|
}
|
|
6210
6410
|
if (area === "activity") {
|
|
6211
|
-
const
|
|
6411
|
+
const result2 = await dependencies.commands.siteSetupActivityCommand({
|
|
6212
6412
|
projectDir,
|
|
6213
6413
|
phase: readRequiredOption(areaArgs, "--phase"),
|
|
6214
6414
|
...connectionOptions
|
|
6215
6415
|
});
|
|
6216
|
-
dependencies.stdout(JSON.stringify(
|
|
6217
|
-
return { exitCode:
|
|
6416
|
+
dependencies.stdout(JSON.stringify(result2, null, 2));
|
|
6417
|
+
return { exitCode: result2.status === "action_required" ? 1 : 0 };
|
|
6218
6418
|
}
|
|
6219
6419
|
if (area === "apply") {
|
|
6220
6420
|
const editorDefinition = await dependencies.readJsonFile(
|
|
6221
6421
|
readRequiredOption(areaArgs, "--definition")
|
|
6222
6422
|
);
|
|
6223
|
-
const
|
|
6423
|
+
const result2 = await dependencies.commands.siteSetupApplyCommand({
|
|
6224
6424
|
projectDir,
|
|
6225
6425
|
editorDefinition,
|
|
6226
6426
|
contentSelectionSummary: await dependencies.readTextFile(
|
|
@@ -6231,28 +6431,28 @@ async function runSetupCommand(args, dependencies) {
|
|
|
6231
6431
|
),
|
|
6232
6432
|
...connectionOptions
|
|
6233
6433
|
});
|
|
6234
|
-
dependencies.stdout(JSON.stringify(
|
|
6235
|
-
return { exitCode:
|
|
6434
|
+
dependencies.stdout(JSON.stringify(result2, null, 2));
|
|
6435
|
+
return { exitCode: result2.status === "action_required" ? 1 : 0 };
|
|
6236
6436
|
}
|
|
6237
6437
|
if (area === "verify") {
|
|
6238
|
-
const
|
|
6438
|
+
const result2 = await dependencies.commands.siteSetupVerifyCommand({
|
|
6239
6439
|
projectDir,
|
|
6240
6440
|
deploymentUrl: readRequiredOption(areaArgs, "--deployment-url"),
|
|
6241
6441
|
wait: areaArgs.includes("--wait"),
|
|
6242
6442
|
...connectionOptions
|
|
6243
6443
|
});
|
|
6244
|
-
dependencies.stdout(JSON.stringify(
|
|
6245
|
-
return { exitCode:
|
|
6444
|
+
dependencies.stdout(JSON.stringify(result2, null, 2));
|
|
6445
|
+
return { exitCode: result2.status === "ready_for_review" ? 0 : 1 };
|
|
6246
6446
|
}
|
|
6247
6447
|
dependencies.stdout(
|
|
6248
|
-
"Usage: siteplane setup <preflight|prepare|context|activity|apply|deploy|verify>"
|
|
6448
|
+
"Usage: siteplane setup <start|preflight|prepare|context|activity|apply|deploy|verify>"
|
|
6249
6449
|
);
|
|
6250
6450
|
return { exitCode: 1 };
|
|
6251
6451
|
}
|
|
6252
6452
|
async function runBookingCommand(args, dependencies) {
|
|
6253
6453
|
const [subcommand, ...subcommandArgs] = args;
|
|
6254
6454
|
const projectDir = dependencies.cwd();
|
|
6255
|
-
const manifestPath =
|
|
6455
|
+
const manifestPath = join13(projectDir, "siteplane.booking.json");
|
|
6256
6456
|
if (subcommand === "init") {
|
|
6257
6457
|
const siteId = readRequiredOption(subcommandArgs, "--site-id");
|
|
6258
6458
|
const siteKeyPrefix = readRequiredOption(
|
|
@@ -6265,7 +6465,7 @@ async function runBookingCommand(args, dependencies) {
|
|
|
6265
6465
|
);
|
|
6266
6466
|
const productionOrigin = readOption(subcommandArgs, "--production-origin");
|
|
6267
6467
|
const agentClient = readBookingAgentClient(subcommandArgs);
|
|
6268
|
-
const
|
|
6468
|
+
const result2 = await dependencies.commands.bookingInitCommand({
|
|
6269
6469
|
projectDir,
|
|
6270
6470
|
siteId,
|
|
6271
6471
|
siteKeyPrefix,
|
|
@@ -6273,8 +6473,8 @@ async function runBookingCommand(args, dependencies) {
|
|
|
6273
6473
|
...productionOrigin ? { productionOrigin } : {},
|
|
6274
6474
|
...agentClient ? { agentClient } : {}
|
|
6275
6475
|
});
|
|
6276
|
-
dependencies.stdout(`Wrote ${
|
|
6277
|
-
for (const artifactPath of
|
|
6476
|
+
dependencies.stdout(`Wrote ${result2.manifestPath}`);
|
|
6477
|
+
for (const artifactPath of result2.artifactPaths) {
|
|
6278
6478
|
dependencies.stdout(`Wrote ${artifactPath}`);
|
|
6279
6479
|
}
|
|
6280
6480
|
return { exitCode: 0 };
|
|
@@ -6286,12 +6486,12 @@ async function runBookingCommand(args, dependencies) {
|
|
|
6286
6486
|
projectDir
|
|
6287
6487
|
}
|
|
6288
6488
|
);
|
|
6289
|
-
const
|
|
6489
|
+
const result2 = await dependencies.commands.bookingCheckCommand({
|
|
6290
6490
|
manifestPath,
|
|
6291
6491
|
sourceFilePaths
|
|
6292
6492
|
});
|
|
6293
|
-
dependencies.stdout(JSON.stringify(
|
|
6294
|
-
return { exitCode:
|
|
6493
|
+
dependencies.stdout(JSON.stringify(result2, null, 2));
|
|
6494
|
+
return { exitCode: result2.ok ? 0 : 1 };
|
|
6295
6495
|
}
|
|
6296
6496
|
if (subcommand === "sync") {
|
|
6297
6497
|
const { config, manifest } = await readBookingProjectState(
|
|
@@ -6331,7 +6531,7 @@ async function runBookingCommand(args, dependencies) {
|
|
|
6331
6531
|
resourceId: readOption(subcommandArgs, "--resource-id") ?? null,
|
|
6332
6532
|
startUtc: readRequiredOption(subcommandArgs, "--start-utc"),
|
|
6333
6533
|
customer,
|
|
6334
|
-
clientToken: readOption(subcommandArgs, "--client-token") ??
|
|
6534
|
+
clientToken: readOption(subcommandArgs, "--client-token") ?? randomUUID8(),
|
|
6335
6535
|
paymentChoice: "onsite"
|
|
6336
6536
|
}
|
|
6337
6537
|
});
|
|
@@ -6384,6 +6584,7 @@ function createDefaultDependencies() {
|
|
|
6384
6584
|
siteSetupActivityCommand,
|
|
6385
6585
|
siteSetupVerifyCommand,
|
|
6386
6586
|
setupPreflightCommand,
|
|
6587
|
+
setupStartCommand,
|
|
6387
6588
|
setupPrepareCommand,
|
|
6388
6589
|
setupDeployCommand,
|
|
6389
6590
|
initCommand,
|
|
@@ -6447,7 +6648,7 @@ async function existingPaths(paths) {
|
|
|
6447
6648
|
const existing = [];
|
|
6448
6649
|
for (const path of paths) {
|
|
6449
6650
|
try {
|
|
6450
|
-
await
|
|
6651
|
+
await access7(path);
|
|
6451
6652
|
existing.push(path);
|
|
6452
6653
|
} catch {
|
|
6453
6654
|
}
|
|
@@ -6475,8 +6676,8 @@ function readBookingAgentClient(args) {
|
|
|
6475
6676
|
|
|
6476
6677
|
// src/bin/siteplane.ts
|
|
6477
6678
|
async function main() {
|
|
6478
|
-
const
|
|
6479
|
-
process.exitCode =
|
|
6679
|
+
const result2 = await runSiteplaneCli(process.argv.slice(2));
|
|
6680
|
+
process.exitCode = result2.exitCode;
|
|
6480
6681
|
}
|
|
6481
6682
|
await main().catch((error) => {
|
|
6482
6683
|
console.error(error instanceof Error ? error.message : String(error));
|