siteplane 0.1.64 → 0.1.66

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/next.js CHANGED
@@ -1,8 +1,8 @@
1
1
  // src/next.ts
2
2
  import { execFile as execFile4 } from "child_process";
3
3
  import { createHash as createHash5 } from "crypto";
4
- import { readFile as readFile13 } from "fs/promises";
5
- import { dirname as dirname9, join as join13, resolve as resolve4 } from "path";
4
+ import { access as access8, readFile as readFile13 } from "fs/promises";
5
+ import { dirname as dirname10, join as join14, resolve as resolve4 } from "path";
6
6
  import { promisify as promisify4 } from "util";
7
7
 
8
8
  // ../cli/dist/analytics/manifest.js
@@ -638,6 +638,7 @@ var bookingPublicConfigSchema = z9.object({
638
638
  settings: z9.object({
639
639
  slotIntervalMinutes: z9.number().int().positive(),
640
640
  minLeadMinutes: z9.number().int().min(0),
641
+ minCancelLeadMinutes: z9.number().int().min(0),
641
642
  maxAdvanceDays: z9.number().int().min(1),
642
643
  requirePhone: z9.boolean(),
643
644
  collectNote: z9.boolean(),
@@ -846,7 +847,7 @@ var bookingManifestSchema = z9.object({
846
847
  siteId: z9.string().trim().min(1),
847
848
  siteKeyPrefix: z9.string().startsWith("bk_pub_"),
848
849
  bookingPageSlug: z9.string().regex(/^[a-z0-9]+(?:-[a-z0-9]+)*$/).min(2).max(64),
849
- embedMode: z9.enum(["script", "web_component", "iframe"]).optional(),
850
+ integration: z9.literal("rewrite").optional(),
850
851
  productionOrigin: z9.string().url().optional()
851
852
  }).passthrough();
852
853
 
@@ -2405,6 +2406,9 @@ import ts from "typescript";
2405
2406
  import { mkdir as mkdir2, readFile as readFile2, writeFile as writeFile2 } from "fs/promises";
2406
2407
  import { dirname as dirname2 } from "path";
2407
2408
 
2409
+ // ../cli/dist/booking/static-scan.js
2410
+ import ts2 from "typescript";
2411
+
2408
2412
  // ../cli/dist/commands/analytics/check.js
2409
2413
  import { readFile as readFile3 } from "fs/promises";
2410
2414
 
@@ -2505,17 +2509,20 @@ var errorSchema = z30.object({
2505
2509
  import { randomUUID } from "crypto";
2506
2510
 
2507
2511
  // ../cli/dist/commands/booking/check.js
2508
- import { readFile as readFile4 } from "fs/promises";
2512
+ import { dirname as dirname4, join as join2 } from "path";
2513
+ import { access, readFile as readFile4 } from "fs/promises";
2509
2514
 
2510
2515
  // ../cli/dist/commands/booking/init.js
2511
2516
  import { mkdir as mkdir4, writeFile as writeFile4 } from "fs/promises";
2512
- import { dirname as dirname4, join as join2 } from "path";
2517
+ import { dirname as dirname5, join as join3 } from "path";
2513
2518
  var bookingRulesTemplate = `# Siteplane Booking Rules
2514
2519
 
2515
2520
  - Do not change layout, copy, styling, animation or business logic while adding Booking.
2516
- - Add only the Siteplane Booking embed script and a booking iframe or web component.
2517
- - Use the configured booking page slug from siteplane.booking.json.
2518
- - Register the production website origin in Siteplane before testing cross-origin embeds.
2521
+ - Integrate /booking on the customer domain through withSiteplane(nextConfig, { booking: { site: "<site-id>" } }); use the immutable Site ID supplied by Siteplane.
2522
+ - Use a normal <a href="/booking"> link, not next/link, an iframe or an embed script.
2523
+ - Preserve existing rewrites. Booking-only must not require Editor setup or siteplane.config.json.
2524
+ - Configure the public booking address in Siteplane; register its origin and call https://siteplane.io/api/booking/* directly with CORS, without a raw public key.
2525
+ - Preserve customer CSP and middleware; explain required Siteplane/Stripe permissions and exclude /booking from customer middleware.
2519
2526
  - Do not write setup tokens, project CLI tokens or private keys into source files.
2520
2527
  - Run npx siteplane booking check, npx siteplane booking sync and npx siteplane booking test after setup.
2521
2528
  - booking test stays in test_mode; live booking only starts after explicit dashboard activation.
@@ -2528,9 +2535,9 @@ alwaysApply: true
2528
2535
  ${bookingRulesTemplate}`;
2529
2536
 
2530
2537
  // ../cli/dist/config/project-config.js
2531
- import { access, chmod, open, readFile as readFile5, rename, rm } from "fs/promises";
2538
+ import { access as access2, chmod, open, readFile as readFile5, rename, rm } from "fs/promises";
2532
2539
  import { randomUUID as randomUUID2 } from "crypto";
2533
- import { join as join3 } from "path";
2540
+ import { join as join4 } from "path";
2534
2541
  import { z as z31 } from "zod";
2535
2542
  var siteplaneProjectConfigSchema = z31.object({
2536
2543
  version: z31.literal(2),
@@ -2546,14 +2553,14 @@ var siteplaneProjectConfigSchema = z31.object({
2546
2553
  fieldContractHash: z31.string().regex(/^sha256:[0-9a-f]{64}$/iu).optional()
2547
2554
  }).strict();
2548
2555
  async function readProjectConfig(projectDir) {
2549
- return siteplaneProjectConfigSchema.parse(JSON.parse(await readFile5(join3(projectDir, "siteplane.config.json"), "utf8")));
2556
+ return siteplaneProjectConfigSchema.parse(JSON.parse(await readFile5(join4(projectDir, "siteplane.config.json"), "utf8")));
2550
2557
  }
2551
2558
 
2552
2559
  // ../cli/dist/config/credentials.js
2553
2560
  import { execFile } from "child_process";
2554
2561
  import { randomUUID as randomUUID3 } from "crypto";
2555
2562
  import { chmod as chmod2, lstat, mkdir as mkdir5, open as open2, readFile as readFile6, rename as rename2, rm as rm2 } from "fs/promises";
2556
- import { dirname as dirname5, join as join4, relative } from "path";
2563
+ import { dirname as dirname6, join as join5, relative } from "path";
2557
2564
  import { promisify } from "util";
2558
2565
  import { z as z32 } from "zod";
2559
2566
  var localSetupInstallationSchema = z32.object({
@@ -2578,7 +2585,7 @@ var localSetupCredentialsSchema = z32.union([
2578
2585
  z32.object({ installation: localSetupInstallationSchema }).strict()
2579
2586
  ]);
2580
2587
  async function assertLocalCredentialsPathSafe(projectDir, options = {}) {
2581
- const path = join4(projectDir, ".siteplane/credentials.json");
2588
+ const path = join5(projectDir, ".siteplane/credentials.json");
2582
2589
  await assertCredentialFilesystemSafe(projectDir);
2583
2590
  const isTrackedFile = options.isTrackedFile ?? ((targetPath) => gitPathMatches(projectDir, targetPath, "ls-files"));
2584
2591
  const isIgnoredFile = options.isIgnoredFile ?? ((targetPath) => gitPathMatches(projectDir, targetPath, "check-ignore"));
@@ -2593,8 +2600,8 @@ async function assertLocalCredentialsPathSafe(projectDir, options = {}) {
2593
2600
  async function assertCredentialFilesystemSafe(projectDir) {
2594
2601
  for (const [path, directory, mode] of [
2595
2602
  [projectDir, true, null],
2596
- [join4(projectDir, ".siteplane"), true, 448],
2597
- [join4(projectDir, ".siteplane/credentials.json"), false, 384]
2603
+ [join5(projectDir, ".siteplane"), true, 448],
2604
+ [join5(projectDir, ".siteplane/credentials.json"), false, 384]
2598
2605
  ]) {
2599
2606
  const stat = await lstat(path).catch((error) => {
2600
2607
  if (error.code === "ENOENT")
@@ -2620,7 +2627,7 @@ async function readLocalCredentials(projectDir) {
2620
2627
  }
2621
2628
  async function readLocalSetupCredentials(projectDir) {
2622
2629
  await assertCredentialFilesystemSafe(projectDir);
2623
- return localSetupCredentialsSchema.parse(JSON.parse(await readFile6(join4(projectDir, ".siteplane/credentials.json"), "utf8")));
2630
+ return localSetupCredentialsSchema.parse(JSON.parse(await readFile6(join5(projectDir, ".siteplane/credentials.json"), "utf8")));
2624
2631
  }
2625
2632
  var execFileAsync = promisify(execFile);
2626
2633
  async function gitPathMatches(projectDir, path, command) {
@@ -2634,8 +2641,8 @@ async function gitPathMatches(projectDir, path, command) {
2634
2641
  }
2635
2642
 
2636
2643
  // ../cli/dist/commands/init.js
2637
- import { access as access3 } from "fs/promises";
2638
- import { join as join7, relative as relative3 } from "path";
2644
+ import { access as access4 } from "fs/promises";
2645
+ import { join as join8, relative as relative3 } from "path";
2639
2646
  import { z as z35 } from "zod";
2640
2647
 
2641
2648
  // ../cli/dist/commands/setup-preflight.js
@@ -2647,7 +2654,7 @@ import { parse as parseYaml } from "yaml";
2647
2654
  // ../cli/dist/config/installed-package.js
2648
2655
  import { createRequire } from "module";
2649
2656
  import { readFile as readFile7 } from "fs/promises";
2650
- import { join as join5 } from "path";
2657
+ import { join as join6 } from "path";
2651
2658
  import { z as z33 } from "zod";
2652
2659
  var packageSchema = z33.object({
2653
2660
  name: z33.string().optional(),
@@ -2655,10 +2662,10 @@ var packageSchema = z33.object({
2655
2662
  peerDependencies: z33.record(z33.string(), z33.string()).optional()
2656
2663
  });
2657
2664
  async function readInstalledPackage(projectDir, name2) {
2658
- const require2 = createRequire(join5(projectDir, "package.json"));
2665
+ const require2 = createRequire(join6(projectDir, "package.json"));
2659
2666
  for (const directory of require2.resolve.paths(name2) ?? []) {
2660
2667
  try {
2661
- return packageSchema.parse(JSON.parse(await readFile7(join5(directory, name2, "package.json"), "utf8")));
2668
+ return packageSchema.parse(JSON.parse(await readFile7(join6(directory, name2, "package.json"), "utf8")));
2662
2669
  } catch (error) {
2663
2670
  if (error.code !== "ENOENT")
2664
2671
  throw error;
@@ -2668,8 +2675,8 @@ async function readInstalledPackage(projectDir, name2) {
2668
2675
  }
2669
2676
 
2670
2677
  // ../cli/dist/commands/setup-preflight.js
2671
- import { access as access2, readFile as readFile8, realpath, readdir, readlink } from "fs/promises";
2672
- import { dirname as dirname6, join as join6, relative as relative2, resolve, sep } from "path";
2678
+ import { access as access3, readFile as readFile8, realpath, readdir, readlink } from "fs/promises";
2679
+ import { dirname as dirname7, join as join7, relative as relative2, resolve, sep } from "path";
2673
2680
  import { z as z34 } from "zod";
2674
2681
 
2675
2682
  // ../cli/dist/commands/setup-process.js
@@ -2796,15 +2803,15 @@ var vercelProjectSchema = z34.object({
2796
2803
  productionBranch: z34.string().optional()
2797
2804
  }).nullable().optional()
2798
2805
  });
2799
- var exists = async (path) => access2(path).then(() => true, () => false);
2806
+ var exists = async (path) => access3(path).then(() => true, () => false);
2800
2807
  var fail = (code, message) => {
2801
2808
  throw new SetupFailure(code, message);
2802
2809
  };
2803
2810
  var stable = (version2, major) => new RegExp(`^${major}\\.\\d+\\.\\d+$`, "u").test(version2);
2804
2811
  async function inspectSetupLocalProject(projectDir) {
2805
2812
  const projectDirectory = await realpath(resolve(projectDir));
2806
- const manifest = manifestSchema.parse(JSON.parse(await readFile8(join6(projectDirectory, "package.json"), "utf8")));
2807
- const apps = (await Promise.all(["app", "src/app"].map(async (path) => await exists(join6(projectDirectory, path)) ? path : null))).filter((path) => path !== null);
2813
+ const manifest = manifestSchema.parse(JSON.parse(await readFile8(join7(projectDirectory, "package.json"), "utf8")));
2814
+ const apps = (await Promise.all(["app", "src/app"].map(async (path) => await exists(join7(projectDirectory, path)) ? path : null))).filter((path) => path !== null);
2808
2815
  if (apps.length !== 1)
2809
2816
  fail("ambiguous_app_directory", "Select one Next.js App Router application with exactly one app/ or src/app/ directory.");
2810
2817
  const repositoryRoot = (await setupProcess("git", ["rev-parse", "--show-toplevel"], {
@@ -2818,8 +2825,8 @@ async function inspectSetupLocalProject(projectDir) {
2818
2825
  fail("git_submodule_conflict", "The repository contains Git submodules. Resolve the explicit deployment source boundary before setup; the CLI will not copy external repositories.");
2819
2826
  if (!entry.startsWith("120000 "))
2820
2827
  continue;
2821
- const path = join6(repositoryRoot, entry.slice(entry.indexOf(" ") + 1));
2822
- const target = resolve(dirname6(path), await readlink(path));
2828
+ const path = join7(repositoryRoot, entry.slice(entry.indexOf(" ") + 1));
2829
+ const target = resolve(dirname7(path), await readlink(path));
2823
2830
  const bound = relative2(repositoryRoot, target);
2824
2831
  if (bound.startsWith("..") || bound.startsWith(sep))
2825
2832
  fail("external_symlink_conflict", "A tracked symbolic link points outside this repository. Resolve that source boundary before setup; local external files cannot enter a deployment.");
@@ -2835,10 +2842,10 @@ async function inspectSetupLocalProject(projectDir) {
2835
2842
  ];
2836
2843
  let locks = [];
2837
2844
  for (; ; ) {
2838
- locks = (await Promise.all(lockNames.map(async (name3) => await exists(join6(lockfileRoot, name3)) ? name3 : null))).filter((name3) => name3 !== null);
2839
- if (locks.length || lockfileRoot === repositoryRoot || dirname6(lockfileRoot) === lockfileRoot)
2845
+ locks = (await Promise.all(lockNames.map(async (name3) => await exists(join7(lockfileRoot, name3)) ? name3 : null))).filter((name3) => name3 !== null);
2846
+ if (locks.length || lockfileRoot === repositoryRoot || dirname7(lockfileRoot) === lockfileRoot)
2840
2847
  break;
2841
- lockfileRoot = dirname6(lockfileRoot);
2848
+ lockfileRoot = dirname7(lockfileRoot);
2842
2849
  }
2843
2850
  if (locks.length > 1)
2844
2851
  fail("conflicting_lockfiles", "Resolve conflicting package-manager lockfiles before setup; Siteplane does not replace them.");
@@ -2847,9 +2854,9 @@ async function inspectSetupLocalProject(projectDir) {
2847
2854
  const lockName = locks[0];
2848
2855
  if (!["package-lock.json", "pnpm-lock.yaml"].includes(lockName))
2849
2856
  fail("unsupported_package_manager", "This setup supports npm 10 or pnpm 9/10 with their canonical lockfile.");
2850
- const rootManifest = manifestSchema.parse(JSON.parse(await readFile8(join6(lockfileRoot, "package.json"), "utf8")));
2857
+ const rootManifest = manifestSchema.parse(JSON.parse(await readFile8(join7(lockfileRoot, "package.json"), "utf8")));
2851
2858
  if (lockfileRoot !== projectDirectory) {
2852
- const workspaceFile = join6(lockfileRoot, "pnpm-workspace.yaml");
2859
+ const workspaceFile = join7(lockfileRoot, "pnpm-workspace.yaml");
2853
2860
  const workspace = lockName === "pnpm-lock.yaml" && await exists(workspaceFile) ? z34.object({ packages: z34.array(z34.string()) }).parse(parseYaml(await readFile8(workspaceFile, "utf8"))).packages : z34.union([
2854
2861
  z34.array(z34.string()),
2855
2862
  z34.object({ packages: z34.array(z34.string()) }).transform((value) => value.packages)
@@ -2858,14 +2865,14 @@ async function inspectSetupLocalProject(projectDir) {
2858
2865
  if (!workspace.some((pattern) => !pattern.startsWith("!") && minimatch(selected, pattern)) || workspace.some((pattern) => pattern.startsWith("!") && minimatch(selected, pattern.slice(1))))
2859
2866
  fail("unbound_workspace_app", "The selected application is excluded from the canonical lockfile's workspace packages. Select its actual application root.");
2860
2867
  }
2861
- for (let ancestor = dirname6(lockfileRoot); ancestor.startsWith(repositoryRoot + sep) || ancestor === repositoryRoot; ancestor = dirname6(ancestor)) {
2862
- const ancestorLocks = await Promise.all(lockNames.map((name3) => exists(join6(ancestor, name3))));
2868
+ for (let ancestor = dirname7(lockfileRoot); ancestor.startsWith(repositoryRoot + sep) || ancestor === repositoryRoot; ancestor = dirname7(ancestor)) {
2869
+ const ancestorLocks = await Promise.all(lockNames.map((name3) => exists(join7(ancestor, name3))));
2863
2870
  if (ancestorLocks.some(Boolean))
2864
2871
  fail("ambiguous_lockfile_root", "Both the selected package and its repository ancestors contain lockfiles. Select one canonical workspace resolution before setup.");
2865
2872
  if (ancestor === repositoryRoot)
2866
2873
  break;
2867
2874
  }
2868
- const lockText = await readFile8(join6(lockfileRoot, lockName), "utf8");
2875
+ const lockText = await readFile8(join7(lockfileRoot, lockName), "utf8");
2869
2876
  const npmLock = lockName === "package-lock.json" ? z34.object({
2870
2877
  lockfileVersion: z34.number(),
2871
2878
  packages: z34.record(z34.string(), z34.object({
@@ -2918,9 +2925,9 @@ async function inspectSetupLocalProject(projectDir) {
2918
2925
  fail("lockfile_format_conflict", "The canonical lockfile format does not match npm 10 or pnpm 9/10.");
2919
2926
  const sourceConflicts = [];
2920
2927
  for (const file of ["next.config.js", "next.config.mjs", "next.config.ts"]) {
2921
- if (!await exists(join6(projectDirectory, file)))
2928
+ if (!await exists(join7(projectDirectory, file)))
2922
2929
  continue;
2923
- const source = await readFile8(join6(projectDirectory, file), "utf8");
2930
+ const source = await readFile8(join7(projectDirectory, file), "utf8");
2924
2931
  if (/output\s*:\s*['"]export['"]/u.test(source))
2925
2932
  sourceConflicts.push("static_export");
2926
2933
  if (/\bbasePath\s*:/u.test(source))
@@ -2940,11 +2947,11 @@ async function inspectSetupLocalProject(projectDir) {
2940
2947
  "src/proxy.ts",
2941
2948
  "src/proxy.js"
2942
2949
  ]) {
2943
- if (await exists(join6(projectDirectory, name3))) {
2950
+ if (await exists(join7(projectDirectory, name3))) {
2944
2951
  sourceConflicts.push(`inspect_routing:${name3}`);
2945
- if (await readlink(join6(projectDirectory, name3)).catch(() => null))
2952
+ if (await readlink(join7(projectDirectory, name3)).catch(() => null))
2946
2953
  continue;
2947
- const policySource = await readFile8(join6(projectDirectory, name3), "utf8");
2954
+ const policySource = await readFile8(join7(projectDirectory, name3), "utf8");
2948
2955
  if (/Content-Security-Policy|img-src|default-src/iu.test(policySource))
2949
2956
  sourceConflicts.push(`inspect_image_csp:${name3}`);
2950
2957
  }
@@ -2953,7 +2960,7 @@ async function inspectSetupLocalProject(projectDir) {
2953
2960
  for (const entry of await readdir(directory, { withFileTypes: true })) {
2954
2961
  if (entry.isSymbolicLink() || ["node_modules", ".git", ".next", ".siteplane", ".vercel"].includes(entry.name))
2955
2962
  continue;
2956
- const path = join6(directory, entry.name);
2963
+ const path = join7(directory, entry.name);
2957
2964
  if (entry.isDirectory()) {
2958
2965
  await inspectSource(path);
2959
2966
  continue;
@@ -2973,7 +2980,7 @@ async function inspectSetupLocalProject(projectDir) {
2973
2980
  fail("next_security_advisory", `Next.js ${nextVersion} contains Server Actions affected by the July 2026 advisory. Review https://nextjs.org/blog/july-2026-security-release and explicitly update the affected dependency before setup.`);
2974
2981
  }
2975
2982
  }
2976
- await inspectSource(join6(projectDirectory, apps[0]));
2983
+ await inspectSource(join7(projectDirectory, apps[0]));
2977
2984
  const gitRead = async (args) => setupProcess("git", args, { cwd: projectDirectory }).then((value) => value.trim(), () => null);
2978
2985
  return {
2979
2986
  projectDirectory,
@@ -2985,7 +2992,7 @@ async function inspectSetupLocalProject(projectDir) {
2985
2992
  nodeVersion: process.versions.node,
2986
2993
  packageManager: { name: name2, version: localVersion, declared },
2987
2994
  lockfile: {
2988
- path: relative2(repositoryRoot, join6(lockfileRoot, lockName)),
2995
+ path: relative2(repositoryRoot, join7(lockfileRoot, lockName)),
2989
2996
  format,
2990
2997
  sha256: createHash2("sha256").update(lockText).digest("hex")
2991
2998
  },
@@ -3004,14 +3011,14 @@ async function setupPreflightCommand(input) {
3004
3011
  local = await inspectSetupLocalProject(input.projectDir);
3005
3012
  await assertLocalCredentialsPathSafe(input.projectDir);
3006
3013
  let linkDirectory = local.projectDirectory;
3007
- while (!await exists(join6(linkDirectory, ".vercel/project.json")) && linkDirectory !== local.repositoryRoot && dirname6(linkDirectory) !== linkDirectory)
3008
- linkDirectory = dirname6(linkDirectory);
3009
- if (!await exists(join6(linkDirectory, ".vercel/project.json")))
3014
+ while (!await exists(join7(linkDirectory, ".vercel/project.json")) && linkDirectory !== local.repositoryRoot && dirname7(linkDirectory) !== linkDirectory)
3015
+ linkDirectory = dirname7(linkDirectory);
3016
+ if (!await exists(join7(linkDirectory, ".vercel/project.json")))
3010
3017
  fail("vercel_project_not_linked", "Link this application to its intended Vercel project before setup; Siteplane will not guess a target.");
3011
3018
  const linked = z34.object({
3012
3019
  projectId: z34.string().regex(/^prj_[A-Za-z0-9]+$/u),
3013
3020
  orgId: z34.string().regex(/^(?:team|user)_[A-Za-z0-9]+$/u)
3014
- }).parse(JSON.parse(await readFile8(join6(linkDirectory, ".vercel/project.json"), "utf8")));
3021
+ }).parse(JSON.parse(await readFile8(join7(linkDirectory, ".vercel/project.json"), "utf8")));
3015
3022
  const project = vercelProjectSchema.parse(await setupVercelApi(linkDirectory, `/v9/projects/${linked.projectId}?teamId=${linked.orgId}`));
3016
3023
  if (project.id !== linked.projectId || project.accountId !== linked.orgId)
3017
3024
  fail("vercel_identity_conflict", "The provider project does not match the locally linked project and team.");
@@ -3122,7 +3129,7 @@ var bootstrapResponseSchema = z35.object({
3122
3129
 
3123
3130
  // ../cli/dist/commands/scan.js
3124
3131
  import { readdir as readdir2 } from "fs/promises";
3125
- import { extname, join as join8 } from "path";
3132
+ import { extname, join as join9 } from "path";
3126
3133
  var defaultScanRoots = ["app", "src", "pages", "components", "lib"];
3127
3134
  var excludedDirectories = /* @__PURE__ */ new Set([
3128
3135
  ".git",
@@ -3140,14 +3147,14 @@ async function resolveScanFilePaths(filePaths, options = {}) {
3140
3147
  return filePaths;
3141
3148
  }
3142
3149
  const projectDir = options.projectDir ?? process.cwd();
3143
- const discovered = await Promise.all(defaultScanRoots.map((root) => collectSourceFiles(join8(projectDir, root))));
3150
+ const discovered = await Promise.all(defaultScanRoots.map((root) => collectSourceFiles(join9(projectDir, root))));
3144
3151
  return [...new Set(discovered.flat())].sort();
3145
3152
  }
3146
3153
  async function collectSourceFiles(directory) {
3147
3154
  const entries = await readdir2(directory, { withFileTypes: true }).catch(() => []);
3148
3155
  const files = [];
3149
3156
  for (const entry of entries) {
3150
- const entryPath = join8(directory, entry.name);
3157
+ const entryPath = join9(directory, entry.name);
3151
3158
  if (entry.isDirectory()) {
3152
3159
  if (!excludedDirectories.has(entry.name)) {
3153
3160
  files.push(...await collectSourceFiles(entryPath));
@@ -3168,7 +3175,7 @@ import { promisify as promisify2 } from "util";
3168
3175
  import { z as z36 } from "zod";
3169
3176
 
3170
3177
  // ../cli/dist/scan/next-source-scan.js
3171
- import ts2 from "typescript";
3178
+ import ts3 from "typescript";
3172
3179
  import { isAbsolute, relative as relative4 } from "path";
3173
3180
  var eventPreviewHandlerMissingMessage = "Event preview fields must consume preview values with useSiteplanePreviewText from @siteplane/runtime-next/client or a siteplane:preview-value-applied listener.";
3174
3181
  var valueCallUnusedMessage = "Siteplane value calls must feed rendered content. Assign or await the returned value and render that value instead of ignoring the call.";
@@ -3324,10 +3331,10 @@ function scanSourceFile(file, fields, hardErrors) {
3324
3331
  const eventPreviewComponentPropUsages = [];
3325
3332
  const eventPreviewConsumerFieldIds = /* @__PURE__ */ new Set();
3326
3333
  let hasGenericEventPreviewConsumer = false;
3327
- const sourceFile = ts2.createSourceFile(file.filePath, file.sourceText, ts2.ScriptTarget.Latest, true, ts2.ScriptKind.TSX);
3334
+ const sourceFile = ts3.createSourceFile(file.filePath, file.sourceText, ts3.ScriptTarget.Latest, true, ts3.ScriptKind.TSX);
3328
3335
  function visit(node, currentComponentName) {
3329
3336
  const nextComponentName = getFunctionComponentName(node) ?? currentComponentName;
3330
- if (ts2.isJsxSelfClosingElement(node) || ts2.isJsxOpeningElement(node)) {
3337
+ if (ts3.isJsxSelfClosingElement(node) || ts3.isJsxOpeningElement(node)) {
3331
3338
  const componentName = getJsxTagName(node.tagName);
3332
3339
  if (editableComponentNames.has(componentName)) {
3333
3340
  hardErrors.push({
@@ -3338,7 +3345,7 @@ function scanSourceFile(file, fields, hardErrors) {
3338
3345
  }
3339
3346
  collectEventPreviewComponentPropUsages(node, eventPreviewAttrVariables, eventPreviewComponentPropUsages, file);
3340
3347
  }
3341
- if (ts2.isCallExpression(node)) {
3348
+ if (ts3.isCallExpression(node)) {
3342
3349
  collectAttrsCall(node, attrFieldIds, attrRouteRefs, eventPreviewAttrs, eventPreviewAttrVariables, directAttrs, file);
3343
3350
  collectUnusedValueCallError(node, hardErrors, file);
3344
3351
  const extractedFields = extractFunctionFields(node, file);
@@ -3362,7 +3369,7 @@ function scanSourceFile(file, fields, hardErrors) {
3362
3369
  if (isGenericEventPreviewConsumerReference(node)) {
3363
3370
  hasGenericEventPreviewConsumer = true;
3364
3371
  }
3365
- ts2.forEachChild(node, (child) => visit(child, nextComponentName));
3372
+ ts3.forEachChild(node, (child) => visit(child, nextComponentName));
3366
3373
  }
3367
3374
  visit(sourceFile);
3368
3375
  markMissingAttrsWarnings(fieldsInFile, attrFieldIds, attrRouteRefs);
@@ -3389,7 +3396,7 @@ function collectUnusedValueCallError(node, hardErrors, file) {
3389
3396
  });
3390
3397
  }
3391
3398
  function getSiteplaneValueFunctionName(node) {
3392
- if (!ts2.isPropertyAccessExpression(node.expression)) {
3399
+ if (!ts3.isPropertyAccessExpression(node.expression)) {
3393
3400
  return void 0;
3394
3401
  }
3395
3402
  if (node.expression.expression.getText() !== "siteplane") {
@@ -3402,16 +3409,16 @@ function getSiteplaneValueFunctionName(node) {
3402
3409
  return void 0;
3403
3410
  }
3404
3411
  function isIgnoredValueCall(node) {
3405
- if (ts2.isVoidExpression(node.parent)) {
3412
+ if (ts3.isVoidExpression(node.parent)) {
3406
3413
  return true;
3407
3414
  }
3408
- if (ts2.isExpressionStatement(node.parent)) {
3415
+ if (ts3.isExpressionStatement(node.parent)) {
3409
3416
  return true;
3410
3417
  }
3411
- return ts2.isAwaitExpression(node.parent) && ts2.isExpressionStatement(node.parent.parent);
3418
+ return ts3.isAwaitExpression(node.parent) && ts3.isExpressionStatement(node.parent.parent);
3412
3419
  }
3413
3420
  function extractFunctionFields(node, file) {
3414
- if (!ts2.isPropertyAccessExpression(node.expression)) {
3421
+ if (!ts3.isPropertyAccessExpression(node.expression)) {
3415
3422
  return [];
3416
3423
  }
3417
3424
  if (node.expression.expression.getText() !== "siteplane") {
@@ -3549,7 +3556,7 @@ function createFallbackHash(fieldType, fallback) {
3549
3556
  }
3550
3557
  }
3551
3558
  function collectAttrsCall(node, attrFieldIds, attrRouteRefs, eventPreviewAttrs, eventPreviewAttrVariables, directAttrs, file) {
3552
- if (!ts2.isPropertyAccessExpression(node.expression)) {
3559
+ if (!ts3.isPropertyAccessExpression(node.expression)) {
3553
3560
  return;
3554
3561
  }
3555
3562
  if (node.expression.expression.getText() !== "siteplane" || node.expression.name.text !== "attrs") {
@@ -3578,7 +3585,7 @@ function collectAttrsCall(node, attrFieldIds, attrRouteRefs, eventPreviewAttrs,
3578
3585
  }
3579
3586
  return;
3580
3587
  }
3581
- if (firstArg && ts2.isIdentifier(firstArg) && typeof secondArg === "string") {
3588
+ if (firstArg && ts3.isIdentifier(firstArg) && typeof secondArg === "string") {
3582
3589
  attrRouteRefs.add(`${firstArg.text}:${secondArg}`);
3583
3590
  }
3584
3591
  }
@@ -3615,7 +3622,7 @@ function hasEventPreviewStrategy(options) {
3615
3622
  return !!options && typeof options === "object" && !Array.isArray(options) && options.previewStrategy === "event";
3616
3623
  }
3617
3624
  function isGenericEventPreviewConsumerReference(node) {
3618
- return (ts2.isStringLiteral(node) || ts2.isNoSubstitutionTemplateLiteral(node)) && node.text === "siteplane:preview-value-applied";
3625
+ return (ts3.isStringLiteral(node) || ts3.isNoSubstitutionTemplateLiteral(node)) && node.text === "siteplane:preview-value-applied";
3619
3626
  }
3620
3627
  function getPreviewHookFieldId(node, eventPreviewAttrVariables) {
3621
3628
  const firstArg = getUseSiteplanePreviewTextFirstArg(node);
@@ -3626,7 +3633,7 @@ function getPreviewHookFieldId(node, eventPreviewAttrVariables) {
3626
3633
  if (typeof directFieldId === "string") {
3627
3634
  return directFieldId;
3628
3635
  }
3629
- if (ts2.isIdentifier(firstArg)) {
3636
+ if (ts3.isIdentifier(firstArg)) {
3630
3637
  return eventPreviewAttrVariables.get(firstArg.text);
3631
3638
  }
3632
3639
  return void 0;
@@ -3636,16 +3643,16 @@ function getPreviewHookPropName(node, eventPreviewAttrVariables) {
3636
3643
  if (!firstArg) {
3637
3644
  return void 0;
3638
3645
  }
3639
- if (ts2.isIdentifier(firstArg) && !eventPreviewAttrVariables.has(firstArg.text)) {
3646
+ if (ts3.isIdentifier(firstArg) && !eventPreviewAttrVariables.has(firstArg.text)) {
3640
3647
  return firstArg.text;
3641
3648
  }
3642
- if (ts2.isPropertyAccessExpression(firstArg) && ts2.isIdentifier(firstArg.expression)) {
3649
+ if (ts3.isPropertyAccessExpression(firstArg) && ts3.isIdentifier(firstArg.expression)) {
3643
3650
  return firstArg.name.text;
3644
3651
  }
3645
3652
  return void 0;
3646
3653
  }
3647
3654
  function getUseSiteplanePreviewTextFirstArg(node) {
3648
- if (ts2.isIdentifier(node.expression) && node.expression.text === "useSiteplanePreviewText") {
3655
+ if (ts3.isIdentifier(node.expression) && node.expression.text === "useSiteplanePreviewText") {
3649
3656
  return node.arguments[0];
3650
3657
  }
3651
3658
  return void 0;
@@ -3726,19 +3733,19 @@ function staticExpressionValue(expression) {
3726
3733
  if (!expression) {
3727
3734
  return void 0;
3728
3735
  }
3729
- if (ts2.isStringLiteral(expression) || ts2.isNoSubstitutionTemplateLiteral(expression)) {
3736
+ if (ts3.isStringLiteral(expression) || ts3.isNoSubstitutionTemplateLiteral(expression)) {
3730
3737
  return expression.text;
3731
3738
  }
3732
- if (ts2.isNumericLiteral(expression)) {
3739
+ if (ts3.isNumericLiteral(expression)) {
3733
3740
  return Number(expression.text);
3734
3741
  }
3735
- if (expression.kind === ts2.SyntaxKind.TrueKeyword) {
3742
+ if (expression.kind === ts3.SyntaxKind.TrueKeyword) {
3736
3743
  return true;
3737
3744
  }
3738
- if (expression.kind === ts2.SyntaxKind.FalseKeyword) {
3745
+ if (expression.kind === ts3.SyntaxKind.FalseKeyword) {
3739
3746
  return false;
3740
3747
  }
3741
- if (ts2.isObjectLiteralExpression(expression)) {
3748
+ if (ts3.isObjectLiteralExpression(expression)) {
3742
3749
  return readObjectLiteral(expression);
3743
3750
  }
3744
3751
  return void 0;
@@ -3746,7 +3753,7 @@ function staticExpressionValue(expression) {
3746
3753
  function readObjectLiteral(expression) {
3747
3754
  const value = {};
3748
3755
  for (const property of expression.properties) {
3749
- if (!ts2.isPropertyAssignment(property)) {
3756
+ if (!ts3.isPropertyAssignment(property)) {
3750
3757
  continue;
3751
3758
  }
3752
3759
  const name2 = getPropertyName(property.name);
@@ -3758,7 +3765,7 @@ function readObjectLiteral(expression) {
3758
3765
  return value;
3759
3766
  }
3760
3767
  function getPropertyName(name2) {
3761
- if (ts2.isIdentifier(name2) || ts2.isStringLiteral(name2)) {
3768
+ if (ts3.isIdentifier(name2) || ts3.isStringLiteral(name2)) {
3762
3769
  return name2.text;
3763
3770
  }
3764
3771
  return null;
@@ -3769,7 +3776,7 @@ function collectEventPreviewComponentPropUsages(node, eventPreviewAttrVariables,
3769
3776
  return;
3770
3777
  }
3771
3778
  for (const property of node.attributes.properties) {
3772
- if (!ts2.isJsxAttribute(property)) {
3779
+ if (!ts3.isJsxAttribute(property)) {
3773
3780
  continue;
3774
3781
  }
3775
3782
  const propName = getJsxAttributeName(property.name);
@@ -3786,7 +3793,7 @@ function collectEventPreviewComponentPropUsages(node, eventPreviewAttrVariables,
3786
3793
  }
3787
3794
  }
3788
3795
  function getJsxAttributeName(name2) {
3789
- if (ts2.isIdentifier(name2)) {
3796
+ if (ts3.isIdentifier(name2)) {
3790
3797
  return name2.text;
3791
3798
  }
3792
3799
  return void 0;
@@ -3795,19 +3802,19 @@ function getJsxFieldIdValue(initializer, eventPreviewAttrVariables) {
3795
3802
  if (!initializer) {
3796
3803
  return void 0;
3797
3804
  }
3798
- if (ts2.isStringLiteral(initializer)) {
3805
+ if (ts3.isStringLiteral(initializer)) {
3799
3806
  return initializer.text;
3800
3807
  }
3801
- if (ts2.isJsxExpression(initializer) && initializer.expression && ts2.isIdentifier(initializer.expression)) {
3808
+ if (ts3.isJsxExpression(initializer) && initializer.expression && ts3.isIdentifier(initializer.expression)) {
3802
3809
  return eventPreviewAttrVariables.get(initializer.expression.text);
3803
3810
  }
3804
3811
  return void 0;
3805
3812
  }
3806
3813
  function getFunctionComponentName(node) {
3807
- if (ts2.isFunctionDeclaration(node) && node.name && isComponentName(node.name.text)) {
3814
+ if (ts3.isFunctionDeclaration(node) && node.name && isComponentName(node.name.text)) {
3808
3815
  return node.name.text;
3809
3816
  }
3810
- if (ts2.isVariableDeclaration(node) && ts2.isIdentifier(node.name) && isComponentName(node.name.text) && node.initializer && (ts2.isArrowFunction(node.initializer) || ts2.isFunctionExpression(node.initializer))) {
3817
+ if (ts3.isVariableDeclaration(node) && ts3.isIdentifier(node.name) && isComponentName(node.name.text) && node.initializer && (ts3.isArrowFunction(node.initializer) || ts3.isFunctionExpression(node.initializer))) {
3811
3818
  return node.name.text;
3812
3819
  }
3813
3820
  return void 0;
@@ -3817,10 +3824,10 @@ function isComponentName(name2) {
3817
3824
  }
3818
3825
  function getAssignedVariableName(node) {
3819
3826
  let current = node;
3820
- while (ts2.isAwaitExpression(current.parent)) {
3827
+ while (ts3.isAwaitExpression(current.parent)) {
3821
3828
  current = current.parent;
3822
3829
  }
3823
- if (ts2.isVariableDeclaration(current.parent) && ts2.isIdentifier(current.parent.name)) {
3830
+ if (ts3.isVariableDeclaration(current.parent) && ts3.isIdentifier(current.parent.name)) {
3824
3831
  return current.parent.name.text;
3825
3832
  }
3826
3833
  return void 0;
@@ -3990,8 +3997,8 @@ async function readGitRevision(projectDir) {
3990
3997
 
3991
3998
  // ../cli/dist/commands/setup-start.js
3992
3999
  import { randomBytes, randomUUID as randomUUID4 } from "crypto";
3993
- import { access as access4 } from "fs/promises";
3994
- import { join as join9, relative as relative5 } from "path";
4000
+ import { access as access5 } from "fs/promises";
4001
+ import { join as join10, relative as relative5 } from "path";
3995
4002
  import { z as z37 } from "zod";
3996
4003
  var bootstrapResponseSchema2 = z37.object({
3997
4004
  ok: z37.literal(true),
@@ -4009,10 +4016,10 @@ var responseSchema2 = z38.object({
4009
4016
  }).strict();
4010
4017
 
4011
4018
  // ../cli/dist/commands/setup-prepare.js
4012
- 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";
4019
+ import { access as access6, lstat as lstat2, mkdir as mkdir6, open as open3, readFile as readFile10, rename as rename3, rm as rm3 } from "fs/promises";
4013
4020
  import { randomUUID as randomUUID5 } from "crypto";
4014
- import { dirname as dirname7, join as join10, relative as relative6, sep as sep2 } from "path";
4015
- import ts3 from "typescript";
4021
+ import { dirname as dirname8, join as join11, relative as relative6, sep as sep2 } from "path";
4022
+ import ts4 from "typescript";
4016
4023
 
4017
4024
  // ../cli/dist/commands/setup-lock.js
4018
4025
  import { randomUUID as randomUUID6 } from "crypto";
@@ -4025,7 +4032,7 @@ var ownerSchema = z39.object({ pid: z39.number().int().positive(), nonce: z39.st
4025
4032
  import { createHash as createHash3 } from "crypto";
4026
4033
  import { execFile as execFile3 } from "child_process";
4027
4034
  import { lstat as lstat4, readFile as readFile12, writeFile as writeFile5, mkdir as mkdir8 } from "fs/promises";
4028
- import { dirname as dirname8, isAbsolute as isAbsolute2, join as join11, relative as relative7, resolve as resolve3, sep as sep3 } from "path";
4035
+ import { dirname as dirname9, isAbsolute as isAbsolute2, join as join12, relative as relative7, resolve as resolve3, sep as sep3 } from "path";
4029
4036
  import { isDeepStrictEqual, promisify as promisify3 } from "util";
4030
4037
  import { z as z40 } from "zod";
4031
4038
  var execute = promisify3(execFile3);
@@ -4066,15 +4073,15 @@ async function writeBuildProvenance(checkout, revision) {
4066
4073
  if (entry.mode !== "120000")
4067
4074
  continue;
4068
4075
  const { readlink: readlink2 } = await import("fs/promises");
4069
- const path = join11(checkout, entry.path);
4070
- const target2 = resolve3(dirname8(path), await readlink2(path));
4076
+ const path = join12(checkout, entry.path);
4077
+ const target2 = resolve3(dirname9(path), await readlink2(path));
4071
4078
  const bound = relative7(checkout, target2);
4072
4079
  if (bound.startsWith("..") || isAbsolute2(bound))
4073
4080
  throw new Error("A tracked symbolic link escapes the committed upload; resolve that source boundary before deployment.");
4074
4081
  }
4075
4082
  const providerConfigurations = await Promise.all(entries.filter((entry) => /(?:^|\/)vercel\.json$/u.test(entry.path)).map(async (entry) => ({
4076
4083
  path: entry.path,
4077
- source: await readFile12(join11(checkout, entry.path), "utf8")
4084
+ source: await readFile12(join12(checkout, entry.path), "utf8")
4078
4085
  })));
4079
4086
  const record = schema.parse({
4080
4087
  version: 2,
@@ -4083,22 +4090,22 @@ async function writeBuildProvenance(checkout, revision) {
4083
4090
  entries,
4084
4091
  providerConfigurations
4085
4092
  });
4086
- const target = join11(checkout, name);
4087
- await mkdir8(dirname8(target), { recursive: true, mode: 448 });
4093
+ const target = join12(checkout, name);
4094
+ await mkdir8(dirname9(target), { recursive: true, mode: 448 });
4088
4095
  await writeFile5(target, JSON.stringify(record), { flag: "wx", mode: 384 });
4089
4096
  }
4090
4097
  async function readBuildProvenance(projectDirectory) {
4091
4098
  let root = resolve3(projectDirectory);
4092
4099
  let raw = null;
4093
4100
  for (; ; ) {
4094
- raw = await readFile12(join11(root, name), "utf8").catch((error) => {
4101
+ raw = await readFile12(join12(root, name), "utf8").catch((error) => {
4095
4102
  if (error.code === "ENOENT")
4096
4103
  return null;
4097
4104
  throw error;
4098
4105
  });
4099
- if (raw !== null || dirname8(root) === root)
4106
+ if (raw !== null || dirname9(root) === root)
4100
4107
  break;
4101
- root = dirname8(root);
4108
+ root = dirname9(root);
4102
4109
  }
4103
4110
  if (raw === null)
4104
4111
  return null;
@@ -4124,7 +4131,7 @@ async function readBuildProvenance(projectDirectory) {
4124
4131
  if (!bound.has(appRelative ? `${appRelative}/package.json` : "package.json"))
4125
4132
  throw new Error("The selected app is not part of the committed upload.");
4126
4133
  for (const entry of record.entries) {
4127
- const path = join11(root, entry.path);
4134
+ const path = join12(root, entry.path);
4128
4135
  const stat = await lstat4(path).catch((error) => {
4129
4136
  if (error.code === "ENOENT")
4130
4137
  return null;
@@ -4194,9 +4201,9 @@ function treeHash(entries) {
4194
4201
 
4195
4202
  // ../cli/dist/commands/setup-deploy.js
4196
4203
  import { createHash as createHash4, randomBytes as randomBytes2, randomUUID as randomUUID7 } from "crypto";
4197
- import { access as access6, mkdir as mkdir9, mkdtemp, rm as rm5, writeFile as writeFile6 } from "fs/promises";
4204
+ import { access as access7, mkdir as mkdir9, mkdtemp, rm as rm5, writeFile as writeFile6 } from "fs/promises";
4198
4205
  import { tmpdir } from "os";
4199
- import { join as join12 } from "path";
4206
+ import { join as join13 } from "path";
4200
4207
  import { z as z41 } from "zod";
4201
4208
  var envSchema = z41.object({
4202
4209
  id: z41.string(),
@@ -4282,6 +4289,54 @@ async function scanNextProjectFieldContract(projectDir) {
4282
4289
  }
4283
4290
  async function withSiteplane(nextConfig, options = {}) {
4284
4291
  const projectDir = options.projectDir ?? process.cwd();
4292
+ const booking = options.booking;
4293
+ let integrated = nextConfig;
4294
+ if (booking) {
4295
+ if (!/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(
4296
+ booking.site
4297
+ ))
4298
+ throw new Error(
4299
+ "Siteplane booking.site must be the Site ID from Booking settings."
4300
+ );
4301
+ for (const folder of ["app/booking", "src/app/booking"]) {
4302
+ if (await access8(join14(projectDir, folder)).then(
4303
+ () => true,
4304
+ () => false
4305
+ ))
4306
+ console.warn(
4307
+ "[Siteplane] An app/booking route exists. The Booking beforeFiles rewrite takes precedence; move that route or remove the Booking integration."
4308
+ );
4309
+ }
4310
+ integrated = {
4311
+ ...nextConfig,
4312
+ rewrites: async () => {
4313
+ const existing = await nextConfig.rewrites?.() ?? [];
4314
+ const rules = Array.isArray(existing) ? { beforeFiles: [], afterFiles: existing, fallback: [] } : existing;
4315
+ return {
4316
+ beforeFiles: [
4317
+ {
4318
+ source: "/booking",
4319
+ destination: `https://siteplane.io/booking?site=${booking.site}`
4320
+ },
4321
+ {
4322
+ source: "/booking/:path*",
4323
+ destination: `https://siteplane.io/booking/:path*?site=${booking.site}`
4324
+ },
4325
+ ...rules.beforeFiles ?? []
4326
+ ],
4327
+ afterFiles: rules.afterFiles ?? [],
4328
+ fallback: rules.fallback ?? []
4329
+ };
4330
+ }
4331
+ };
4332
+ const hasEditor = await access8(
4333
+ join14(projectDir, "siteplane.config.json")
4334
+ ).then(
4335
+ () => true,
4336
+ () => false
4337
+ );
4338
+ if (!hasEditor) return { ...integrated, env: { ...nextConfig.env } };
4339
+ }
4285
4340
  const config = await readProjectConfig(projectDir);
4286
4341
  const scan = await scanNextProjectFieldContract(projectDir);
4287
4342
  const requestedRevision = options.buildRevision?.trim() || process.env.SITEPLANE_BUILD_REVISION?.trim();
@@ -4307,7 +4362,7 @@ async function withSiteplane(nextConfig, options = {}) {
4307
4362
  );
4308
4363
  const imageOrigin = hasImages ? readImageWebsiteOrigin() : null;
4309
4364
  return {
4310
- ...nextConfig,
4365
+ ...integrated,
4311
4366
  ...hasImages ? { images: prepareImagePatterns(nextConfig.images, imageOrigin) } : {},
4312
4367
  headers: async () => frameHeaders(
4313
4368
  await nextConfig.headers?.() ?? [],
@@ -4335,18 +4390,30 @@ async function readGitRevision2(projectDir) {
4335
4390
  }
4336
4391
  function frameHeaders(rules, adminOrigin, imageOrigin) {
4337
4392
  const policy = `frame-ancestors 'self' ${adminOrigin}`;
4338
- const hasFrameOptions = rules.some((rule) => rule.headers.some((header) => header.key.toLowerCase() === "x-frame-options"));
4393
+ const hasFrameOptions = rules.some(
4394
+ (rule) => rule.headers.some(
4395
+ (header) => header.key.toLowerCase() === "x-frame-options"
4396
+ )
4397
+ );
4339
4398
  const prepared = rules.map((rule) => ({
4340
4399
  ...rule,
4341
4400
  headers: rule.headers.map((header) => {
4342
4401
  if (header.key.toLowerCase() !== "content-security-policy") return header;
4343
- const ancestors = /(?:^|;)\s*frame-ancestors\s+([^;]+)/iu.test(header.value);
4402
+ const ancestors = /(?:^|;)\s*frame-ancestors\s+([^;]+)/iu.test(
4403
+ header.value
4404
+ );
4344
4405
  const value = ancestors || hasFrameOptions ? header.value : `${header.value.replace(/;\s*$/u, "")}; ${policy}`;
4345
- return { ...header, value: imageOrigin ? prepareImageCsp(value, imageOrigin) : value };
4406
+ return {
4407
+ ...header,
4408
+ value: imageOrigin ? prepareImageCsp(value, imageOrigin) : value
4409
+ };
4346
4410
  })
4347
4411
  }));
4348
4412
  return hasFrameOptions ? prepared : [
4349
- { source: "/:path*", headers: [{ key: "Content-Security-Policy", value: policy }] },
4413
+ {
4414
+ source: "/:path*",
4415
+ headers: [{ key: "Content-Security-Policy", value: policy }]
4416
+ },
4350
4417
  ...prepared
4351
4418
  ];
4352
4419
  }
@@ -4451,7 +4518,7 @@ async function emitBuildProof(projectDir, packages, revision, fieldContractHash)
4451
4518
  let lock = null;
4452
4519
  while (true) {
4453
4520
  lock = await readFile13(
4454
- join13(
4521
+ join14(
4455
4522
  directory,
4456
4523
  packageManager === "npm" ? "package-lock.json" : "pnpm-lock.yaml"
4457
4524
  ),
@@ -4460,8 +4527,8 @@ async function emitBuildProof(projectDir, packages, revision, fieldContractHash)
4460
4527
  if (error.code === "ENOENT") return null;
4461
4528
  throw error;
4462
4529
  });
4463
- if (lock !== null || dirname9(directory) === directory) break;
4464
- directory = dirname9(directory);
4530
+ if (lock !== null || dirname10(directory) === directory) break;
4531
+ directory = dirname10(directory);
4465
4532
  }
4466
4533
  if (!lock)
4467
4534
  throw new SiteplaneNextContractError(