siteplane 0.1.42 → 0.1.43
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +20 -1
- package/dist/bin/siteplane.js +1925 -433
- package/dist/index.js +1198 -377
- package/dist/next.js +1382 -396
- package/package.json +4 -1
package/dist/index.js
CHANGED
|
@@ -831,7 +831,7 @@ function redactBookingManifest(value) {
|
|
|
831
831
|
var BOOKING_CREATE_PAYLOAD_LIMIT_BYTES = 16 * 1024;
|
|
832
832
|
|
|
833
833
|
// ../shared/dist/bridge-protocol.js
|
|
834
|
-
import { z as
|
|
834
|
+
import { z as z16 } from "zod";
|
|
835
835
|
|
|
836
836
|
// ../shared/dist/field-id.js
|
|
837
837
|
import { z as z9 } from "zod";
|
|
@@ -875,25 +875,74 @@ var imageValueSchema = z11.object({
|
|
|
875
875
|
]).optional()
|
|
876
876
|
});
|
|
877
877
|
|
|
878
|
+
// ../shared/dist/setup-deployment.js
|
|
879
|
+
import { z as z12 } from "zod";
|
|
880
|
+
var version = z12.string().regex(/^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$/u);
|
|
881
|
+
var hash = z12.string().regex(/^sha256:[0-9a-f]{64}$/u);
|
|
882
|
+
var setupDeploymentRecordSchema = z12.object({
|
|
883
|
+
version: z12.literal(1),
|
|
884
|
+
operationId: z12.string().uuid(),
|
|
885
|
+
provider: z12.literal("vercel"),
|
|
886
|
+
projectId: z12.string().regex(/^prj_[A-Za-z0-9]+$/u),
|
|
887
|
+
teamId: z12.string().regex(/^(?:team|user)_[A-Za-z0-9]+$/u),
|
|
888
|
+
origin: z12.string().url().refine((value) => {
|
|
889
|
+
const url = new URL(value);
|
|
890
|
+
return url.protocol === "https:" && url.origin === value && !url.username && !url.password;
|
|
891
|
+
}),
|
|
892
|
+
deploymentId: z12.string().regex(/^dpl_[A-Za-z0-9]+$/u).nullable(),
|
|
893
|
+
revision: z12.string().regex(/^[0-9a-f]{40}$/u),
|
|
894
|
+
fieldContractHash: hash,
|
|
895
|
+
packages: z12.object({ siteplane: version, runtimeNext: version }).strict(),
|
|
896
|
+
configurationFingerprint: hash,
|
|
897
|
+
adminSecretGeneration: z12.string().uuid(),
|
|
898
|
+
revalidationGeneration: z12.number().int().positive(),
|
|
899
|
+
startedAt: z12.string().datetime(),
|
|
900
|
+
environmentWrittenAt: z12.string().datetime().nullable(),
|
|
901
|
+
deployRequestedAt: z12.string().datetime().nullable(),
|
|
902
|
+
deadline: z12.string().datetime(),
|
|
903
|
+
phase: z12.enum([
|
|
904
|
+
"planned",
|
|
905
|
+
"environment_written",
|
|
906
|
+
"deploy_requested",
|
|
907
|
+
"deployed",
|
|
908
|
+
"verified",
|
|
909
|
+
"failed"
|
|
910
|
+
]),
|
|
911
|
+
build: z12.object({
|
|
912
|
+
node: version,
|
|
913
|
+
packageManager: z12.enum(["npm", "pnpm"]),
|
|
914
|
+
packageManagerVersion: version,
|
|
915
|
+
lockfileHash: hash
|
|
916
|
+
}).strict().nullable()
|
|
917
|
+
}).strict();
|
|
918
|
+
var setupDeploymentInputSchema = z12.discriminatedUnion("action", [
|
|
919
|
+
z12.object({ action: z12.literal("read") }).strict(),
|
|
920
|
+
z12.object({
|
|
921
|
+
action: z12.literal("record"),
|
|
922
|
+
expectedOperationId: z12.string().uuid().nullable(),
|
|
923
|
+
record: setupDeploymentRecordSchema
|
|
924
|
+
}).strict()
|
|
925
|
+
]);
|
|
926
|
+
|
|
878
927
|
// ../shared/dist/site-setup.js
|
|
879
|
-
import { z as
|
|
928
|
+
import { z as z15 } from "zod";
|
|
880
929
|
|
|
881
930
|
// ../shared/dist/site-field-contract.js
|
|
882
|
-
import { z as
|
|
931
|
+
import { z as z14 } from "zod";
|
|
883
932
|
|
|
884
933
|
// ../shared/dist/fallback-hash.js
|
|
885
|
-
import { z as
|
|
934
|
+
import { z as z13 } from "zod";
|
|
886
935
|
var SAFE_REPRESENTATION_REASONS = [
|
|
887
936
|
"asset_import_rewritten",
|
|
888
937
|
"relative_url_normalized",
|
|
889
938
|
"line_endings_normalized",
|
|
890
939
|
"image_value_serialized"
|
|
891
940
|
];
|
|
892
|
-
var safeRepresentationReasonSchema =
|
|
893
|
-
var linkFallbackSchema =
|
|
894
|
-
href:
|
|
895
|
-
label:
|
|
896
|
-
target:
|
|
941
|
+
var safeRepresentationReasonSchema = z13.enum(SAFE_REPRESENTATION_REASONS);
|
|
942
|
+
var linkFallbackSchema = z13.object({
|
|
943
|
+
href: z13.string().trim().min(1),
|
|
944
|
+
label: z13.string().trim().min(1).optional(),
|
|
945
|
+
target: z13.enum(["_self", "_blank"]).optional()
|
|
897
946
|
}).passthrough();
|
|
898
947
|
function stableJsonStringify(value) {
|
|
899
948
|
return JSON.stringify(sortObjectKeys(value));
|
|
@@ -909,67 +958,67 @@ function sortObjectKeys(value) {
|
|
|
909
958
|
}
|
|
910
959
|
|
|
911
960
|
// ../shared/dist/site-field-contract.js
|
|
912
|
-
var siteFieldStatusSchema =
|
|
913
|
-
var semanticVersionSchema =
|
|
914
|
-
var siteFieldRouteKeySchema =
|
|
915
|
-
var repositoryRelativePosixPathSchema =
|
|
916
|
-
var sourceMappingSchema =
|
|
917
|
-
kind:
|
|
961
|
+
var siteFieldStatusSchema = z14.enum(["hidden", "active"]);
|
|
962
|
+
var semanticVersionSchema = z14.string().regex(/^\d+\.\d+\.\d+$/u);
|
|
963
|
+
var siteFieldRouteKeySchema = z14.string().trim().refine((value) => value === "$global" || value.startsWith("/") && !value.includes("?") && !value.includes("#") && (value === "/" || !value.endsWith("/")), "Route keys must be canonical paths or $global.");
|
|
964
|
+
var repositoryRelativePosixPathSchema = z14.string().trim().min(1).refine((value) => !value.startsWith("/") && !value.includes("\\") && !/^[a-z]:/iu.test(value) && !value.split("/").includes(".."), "Source paths must be repository-relative POSIX paths.");
|
|
965
|
+
var sourceMappingSchema = z14.object({
|
|
966
|
+
kind: z14.literal("function"),
|
|
918
967
|
filePath: repositoryRelativePosixPathSchema,
|
|
919
|
-
exportName:
|
|
920
|
-
sourcePath:
|
|
968
|
+
exportName: z14.string().trim().min(1).optional(),
|
|
969
|
+
sourcePath: z14.string().trim().min(1).optional(),
|
|
921
970
|
editTarget: fieldIdSchema.optional()
|
|
922
971
|
}).strict();
|
|
923
|
-
var domMappingSchema =
|
|
924
|
-
attribute:
|
|
925
|
-
previewStrategy:
|
|
972
|
+
var domMappingSchema = z14.object({
|
|
973
|
+
attribute: z14.literal("data-siteplane-field-id"),
|
|
974
|
+
previewStrategy: z14.enum(["dom", "event"])
|
|
926
975
|
}).strict();
|
|
927
|
-
var fieldBaseSchema =
|
|
976
|
+
var fieldBaseSchema = z14.object({
|
|
928
977
|
fieldId: fieldIdSchema,
|
|
929
978
|
routeKey: siteFieldRouteKeySchema,
|
|
930
979
|
source: sourceMappingSchema,
|
|
931
980
|
dom: domMappingSchema.optional()
|
|
932
981
|
}).strict();
|
|
933
|
-
var linkFallbackSchema2 =
|
|
934
|
-
href:
|
|
935
|
-
label:
|
|
936
|
-
target:
|
|
982
|
+
var linkFallbackSchema2 = z14.object({
|
|
983
|
+
href: z14.string().trim().min(1),
|
|
984
|
+
label: z14.string().trim().min(1).optional(),
|
|
985
|
+
target: z14.enum(["_self", "_blank"]).optional()
|
|
937
986
|
}).strict();
|
|
938
|
-
var imageFallbackSchema =
|
|
939
|
-
src:
|
|
940
|
-
alt:
|
|
941
|
-
width:
|
|
942
|
-
height:
|
|
943
|
-
crop:
|
|
944
|
-
x:
|
|
945
|
-
y:
|
|
946
|
-
zoom:
|
|
947
|
-
aspectRatio:
|
|
987
|
+
var imageFallbackSchema = z14.object({
|
|
988
|
+
src: z14.string().trim().min(1),
|
|
989
|
+
alt: z14.string().trim().max(300),
|
|
990
|
+
width: z14.number().int().positive().optional(),
|
|
991
|
+
height: z14.number().int().positive().optional(),
|
|
992
|
+
crop: z14.object({
|
|
993
|
+
x: z14.number().min(0).max(100),
|
|
994
|
+
y: z14.number().min(0).max(100),
|
|
995
|
+
zoom: z14.number().min(1).max(4),
|
|
996
|
+
aspectRatio: z14.number().positive().max(10)
|
|
948
997
|
}).strict().optional()
|
|
949
998
|
}).strict();
|
|
950
|
-
var siteFieldContractFieldSchema =
|
|
999
|
+
var siteFieldContractFieldSchema = z14.discriminatedUnion("fieldType", [
|
|
951
1000
|
fieldBaseSchema.extend({
|
|
952
|
-
fieldType:
|
|
953
|
-
fallback:
|
|
1001
|
+
fieldType: z14.literal("text"),
|
|
1002
|
+
fallback: z14.string()
|
|
954
1003
|
}),
|
|
955
1004
|
fieldBaseSchema.extend({
|
|
956
|
-
fieldType:
|
|
957
|
-
fallback:
|
|
1005
|
+
fieldType: z14.literal("longText"),
|
|
1006
|
+
fallback: z14.string()
|
|
958
1007
|
}),
|
|
959
1008
|
fieldBaseSchema.extend({
|
|
960
|
-
fieldType:
|
|
1009
|
+
fieldType: z14.literal("link"),
|
|
961
1010
|
fallback: linkFallbackSchema2
|
|
962
1011
|
}),
|
|
963
1012
|
fieldBaseSchema.extend({
|
|
964
|
-
fieldType:
|
|
1013
|
+
fieldType: z14.literal("image"),
|
|
965
1014
|
fallback: imageFallbackSchema
|
|
966
1015
|
})
|
|
967
1016
|
]);
|
|
968
|
-
var siteFieldContractV1Schema =
|
|
969
|
-
version:
|
|
1017
|
+
var siteFieldContractV1Schema = z14.object({
|
|
1018
|
+
version: z14.literal(1),
|
|
970
1019
|
fieldContractVersion: semanticVersionSchema,
|
|
971
1020
|
scannerContractVersion: semanticVersionSchema,
|
|
972
|
-
fields:
|
|
1021
|
+
fields: z14.array(siteFieldContractFieldSchema)
|
|
973
1022
|
}).strict().superRefine((contract, context) => {
|
|
974
1023
|
const seen = /* @__PURE__ */ new Set();
|
|
975
1024
|
for (const [index, field] of contract.fields.entries()) {
|
|
@@ -1018,20 +1067,20 @@ var SITE_SETUP_OWNER_EDITABILITY_NOTE_MAX_LENGTH = 2e3;
|
|
|
1018
1067
|
var SITE_SETUP_OWNER_EDITABILITY_NOTE_MAX_BYTES = 8e3;
|
|
1019
1068
|
var CONTINUE_SITE_SETUP_ITEMS_MAX_BYTES = 32 * 1024;
|
|
1020
1069
|
var CONTINUE_SITE_SETUP_HTTP_BODY_MAX_BYTES = 64 * 1024;
|
|
1021
|
-
var siteSetupRunStatusSchema =
|
|
1022
|
-
var siteSetupRunModeSchema =
|
|
1023
|
-
var siteSetupErrorCodeSchema =
|
|
1024
|
-
var editorFieldSchema =
|
|
1070
|
+
var siteSetupRunStatusSchema = z15.enum(SITE_SETUP_RUN_STATUSES);
|
|
1071
|
+
var siteSetupRunModeSchema = z15.enum(SITE_SETUP_RUN_MODES);
|
|
1072
|
+
var siteSetupErrorCodeSchema = z15.enum(SITE_SETUP_ERROR_CODES);
|
|
1073
|
+
var editorFieldSchema = z15.object({
|
|
1025
1074
|
fieldId: fieldIdSchema,
|
|
1026
|
-
label:
|
|
1027
|
-
subsection:
|
|
1028
|
-
description:
|
|
1029
|
-
required:
|
|
1030
|
-
maxLength:
|
|
1075
|
+
label: z15.string().trim().min(1),
|
|
1076
|
+
subsection: z15.string().trim().min(1).optional(),
|
|
1077
|
+
description: z15.string().trim().min(1).optional(),
|
|
1078
|
+
required: z15.boolean().optional(),
|
|
1079
|
+
maxLength: z15.number().int().positive().optional()
|
|
1031
1080
|
}).strict();
|
|
1032
|
-
var editorSectionSchema =
|
|
1033
|
-
label:
|
|
1034
|
-
fields:
|
|
1081
|
+
var editorSectionSchema = z15.object({
|
|
1082
|
+
label: z15.string().trim().min(1),
|
|
1083
|
+
fields: z15.array(editorFieldSchema).min(1)
|
|
1035
1084
|
}).strict().superRefine((section, context) => {
|
|
1036
1085
|
const closedSubsections = /* @__PURE__ */ new Set();
|
|
1037
1086
|
let currentSubsection;
|
|
@@ -1050,10 +1099,10 @@ var editorSectionSchema = z14.object({
|
|
|
1050
1099
|
}
|
|
1051
1100
|
}
|
|
1052
1101
|
});
|
|
1053
|
-
var editorRouteSchema =
|
|
1102
|
+
var editorRouteSchema = z15.object({
|
|
1054
1103
|
routeKey: siteFieldRouteKeySchema,
|
|
1055
|
-
label:
|
|
1056
|
-
sections:
|
|
1104
|
+
label: z15.string().trim().min(1),
|
|
1105
|
+
sections: z15.array(editorSectionSchema).min(1)
|
|
1057
1106
|
}).strict().superRefine((route, context) => {
|
|
1058
1107
|
const sections = /* @__PURE__ */ new Set();
|
|
1059
1108
|
for (const [index, section] of route.sections.entries()) {
|
|
@@ -1067,9 +1116,9 @@ var editorRouteSchema = z14.object({
|
|
|
1067
1116
|
sections.add(section.label);
|
|
1068
1117
|
}
|
|
1069
1118
|
});
|
|
1070
|
-
var editorDefinitionV1Schema =
|
|
1071
|
-
version:
|
|
1072
|
-
routes:
|
|
1119
|
+
var editorDefinitionV1Schema = z15.object({
|
|
1120
|
+
version: z15.literal(1),
|
|
1121
|
+
routes: z15.array(editorRouteSchema).min(1)
|
|
1073
1122
|
}).strict().superRefine((definition, context) => {
|
|
1074
1123
|
const routes = /* @__PURE__ */ new Set();
|
|
1075
1124
|
const fields = /* @__PURE__ */ new Set();
|
|
@@ -1107,7 +1156,7 @@ var editorDefinitionV1Schema = z14.object({
|
|
|
1107
1156
|
var forbiddenControlOrBidi = /[\u0000-\u001f\u007f-\u009f\u202a-\u202e\u2066-\u2069]/u;
|
|
1108
1157
|
var forbiddenOwnerNoteControlOrBidi = /[\u0000-\u0008\u000b\u000c\u000e-\u001f\u007f-\u009f\u202a-\u202e\u2066-\u2069]/u;
|
|
1109
1158
|
var unsafeLocator = /<\/?[a-z][^>]*>|\b(?:javascript|data:text\/html)\s*:|\bon[a-z]+\s*=/iu;
|
|
1110
|
-
var renderedPathSchema =
|
|
1159
|
+
var renderedPathSchema = z15.string().trim().transform((value) => value !== "/" ? value.replace(/\/+$/u, "") : value).superRefine((value, context) => {
|
|
1111
1160
|
if (!value.startsWith("/") || value === "$global" || value.includes("?") || value.includes("#")) {
|
|
1112
1161
|
context.addIssue({
|
|
1113
1162
|
code: "custom",
|
|
@@ -1117,7 +1166,7 @@ var renderedPathSchema = z14.string().trim().transform((value) => value !== "/"
|
|
|
1117
1166
|
addSafeByteIssues(value, CONTINUE_SITE_SETUP_RENDERED_PATH_MAX_BYTES, "renderedPath", context);
|
|
1118
1167
|
});
|
|
1119
1168
|
function normalizedSafeTextSchema(maxBytes, label) {
|
|
1120
|
-
return
|
|
1169
|
+
return z15.string().transform((value) => value.trim().replace(new RegExp("\\p{White_Space}+", "gu"), " ")).pipe(z15.string().min(1)).superRefine((value, context) => {
|
|
1121
1170
|
addSafeByteIssues(value, maxBytes, label, context);
|
|
1122
1171
|
if (label === "locatorHint" && unsafeLocator.test(value)) {
|
|
1123
1172
|
context.addIssue({
|
|
@@ -1134,12 +1183,12 @@ var correctionItemBase = {
|
|
|
1134
1183
|
requestedLabel: normalizedSafeTextSchema(CONTINUE_SITE_SETUP_REQUESTED_LABEL_MAX_BYTES, "requestedLabel").optional(),
|
|
1135
1184
|
requestedSection: normalizedSafeTextSchema(CONTINUE_SITE_SETUP_REQUESTED_SECTION_MAX_BYTES, "requestedSection").optional(),
|
|
1136
1185
|
requestedSubsection: normalizedSafeTextSchema(CONTINUE_SITE_SETUP_REQUESTED_SUBSECTION_MAX_BYTES, "requestedSubsection").optional(),
|
|
1137
|
-
requestedSortOrder:
|
|
1186
|
+
requestedSortOrder: z15.number().int().nonnegative().optional()
|
|
1138
1187
|
};
|
|
1139
|
-
var setupCorrectionItemSchema =
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1188
|
+
var setupCorrectionItemSchema = z15.discriminatedUnion("kind", [
|
|
1189
|
+
z15.object({ kind: z15.literal("text"), ...correctionItemBase }).strict(),
|
|
1190
|
+
z15.object({ kind: z15.literal("link"), ...correctionItemBase }).strict(),
|
|
1191
|
+
z15.object({ kind: z15.literal("image"), ...correctionItemBase }).strict()
|
|
1143
1192
|
]).superRefine((item, context) => {
|
|
1144
1193
|
if (item.requestedSubsection && !item.requestedSection) {
|
|
1145
1194
|
context.addIssue({
|
|
@@ -1149,7 +1198,7 @@ var setupCorrectionItemSchema = z14.discriminatedUnion("kind", [
|
|
|
1149
1198
|
});
|
|
1150
1199
|
}
|
|
1151
1200
|
});
|
|
1152
|
-
var setupCorrectionItemsSchema =
|
|
1201
|
+
var setupCorrectionItemsSchema = z15.array(setupCorrectionItemSchema).max(CONTINUE_SITE_SETUP_MAX_ITEMS).superRefine((items, context) => {
|
|
1153
1202
|
const bytes = utf8Bytes(stableJsonStringify(items));
|
|
1154
1203
|
if (bytes > CONTINUE_SITE_SETUP_ITEMS_MAX_BYTES) {
|
|
1155
1204
|
context.addIssue({
|
|
@@ -1158,7 +1207,7 @@ var setupCorrectionItemsSchema = z14.array(setupCorrectionItemSchema).max(CONTIN
|
|
|
1158
1207
|
});
|
|
1159
1208
|
}
|
|
1160
1209
|
});
|
|
1161
|
-
var siteSetupOwnerEditabilityNoteSchema =
|
|
1210
|
+
var siteSetupOwnerEditabilityNoteSchema = z15.string().max(SITE_SETUP_OWNER_EDITABILITY_NOTE_MAX_LENGTH).superRefine((value, context) => {
|
|
1162
1211
|
if (utf8Bytes(value) > SITE_SETUP_OWNER_EDITABILITY_NOTE_MAX_BYTES) {
|
|
1163
1212
|
context.addIssue({
|
|
1164
1213
|
code: "custom",
|
|
@@ -1183,7 +1232,7 @@ var SITE_SETUP_MODULE_SCOPES = {
|
|
|
1183
1232
|
"analytics:public_key_read"
|
|
1184
1233
|
]
|
|
1185
1234
|
};
|
|
1186
|
-
var siteSetupModulesSchema =
|
|
1235
|
+
var siteSetupModulesSchema = z15.array(z15.enum(["editing", "analytics"])).min(1).max(2).refine((modules) => modules[0] === "editing" && (modules.length === 1 || modules[1] === "analytics"), "Choose Editing with optional Analytics.");
|
|
1187
1236
|
function siteSetupScopes(modules) {
|
|
1188
1237
|
return modules.flatMap((module) => [...SITE_SETUP_MODULE_SCOPES[module]]);
|
|
1189
1238
|
}
|
|
@@ -1191,15 +1240,15 @@ function hasExactSiteSetupScopes(scopes, modules) {
|
|
|
1191
1240
|
const matches = (expected) => scopes.length === expected.length && expected.every((scope) => scopes.includes(scope));
|
|
1192
1241
|
return modules ? matches(siteSetupScopes(modules)) : matches(siteSetupScopes(["editing"])) || matches(siteSetupScopes(["editing", "analytics"]));
|
|
1193
1242
|
}
|
|
1194
|
-
var siteSetupActivityInputSchema =
|
|
1195
|
-
phase:
|
|
1243
|
+
var siteSetupActivityInputSchema = z15.object({
|
|
1244
|
+
phase: z15.enum([
|
|
1196
1245
|
"inspecting",
|
|
1197
1246
|
"integrating",
|
|
1198
1247
|
"deploying",
|
|
1199
1248
|
"verifying",
|
|
1200
1249
|
"repairing"
|
|
1201
1250
|
]),
|
|
1202
|
-
textId:
|
|
1251
|
+
textId: z15.enum([
|
|
1203
1252
|
"inspecting",
|
|
1204
1253
|
"integrating",
|
|
1205
1254
|
"deploying",
|
|
@@ -1208,8 +1257,8 @@ var siteSetupActivityInputSchema = z14.object({
|
|
|
1208
1257
|
])
|
|
1209
1258
|
}).strict().refine((value) => value.phase === value.textId, "Activity text must describe its phase.");
|
|
1210
1259
|
var nextActionFields = {
|
|
1211
|
-
actor:
|
|
1212
|
-
boundary:
|
|
1260
|
+
actor: z15.enum(["agent", "user", "siteplane"]),
|
|
1261
|
+
boundary: z15.enum([
|
|
1213
1262
|
"source",
|
|
1214
1263
|
"environment",
|
|
1215
1264
|
"deployment",
|
|
@@ -1217,33 +1266,33 @@ var nextActionFields = {
|
|
|
1217
1266
|
"authorization",
|
|
1218
1267
|
"review"
|
|
1219
1268
|
]),
|
|
1220
|
-
precondition:
|
|
1221
|
-
instruction:
|
|
1222
|
-
expectedEvidence:
|
|
1269
|
+
precondition: z15.string().min(1).max(1e3),
|
|
1270
|
+
instruction: z15.string().min(1).max(2e3),
|
|
1271
|
+
expectedEvidence: z15.string().min(1).max(1e3)
|
|
1223
1272
|
};
|
|
1224
|
-
var siteSetupNextActionSchema =
|
|
1225
|
-
|
|
1273
|
+
var siteSetupNextActionSchema = z15.discriminatedUnion("kind", [
|
|
1274
|
+
z15.object({
|
|
1226
1275
|
...nextActionFields,
|
|
1227
|
-
kind:
|
|
1228
|
-
command:
|
|
1276
|
+
kind: z15.literal("run_command"),
|
|
1277
|
+
command: z15.string().min(1).max(500)
|
|
1229
1278
|
}).strict(),
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1279
|
+
z15.object({ ...nextActionFields, kind: z15.literal("agent_edit") }).strict(),
|
|
1280
|
+
z15.object({ ...nextActionFields, kind: z15.literal("needs_user_action") }).strict(),
|
|
1281
|
+
z15.object({ ...nextActionFields, kind: z15.literal("wait") }).strict(),
|
|
1282
|
+
z15.object({ ...nextActionFields, kind: z15.literal("done") }).strict()
|
|
1234
1283
|
]);
|
|
1235
|
-
var siteSetupTaskRunSchema =
|
|
1236
|
-
runId:
|
|
1284
|
+
var siteSetupTaskRunSchema = z15.object({
|
|
1285
|
+
runId: z15.string().uuid(),
|
|
1237
1286
|
mode: siteSetupRunModeSchema,
|
|
1238
1287
|
status: siteSetupRunStatusSchema,
|
|
1239
|
-
fieldContractHash:
|
|
1240
|
-
deploymentOrigin:
|
|
1241
|
-
deploymentRevision:
|
|
1242
|
-
publicRuntimeKeyId:
|
|
1243
|
-
reviewVersion:
|
|
1288
|
+
fieldContractHash: z15.string().nullable(),
|
|
1289
|
+
deploymentOrigin: z15.string().url().nullable(),
|
|
1290
|
+
deploymentRevision: z15.string().nullable(),
|
|
1291
|
+
publicRuntimeKeyId: z15.string().uuid().nullable(),
|
|
1292
|
+
reviewVersion: z15.string().nullable()
|
|
1244
1293
|
}).strict();
|
|
1245
|
-
var siteSetupTaskProgressSchema =
|
|
1246
|
-
progressStage:
|
|
1294
|
+
var siteSetupTaskProgressSchema = z15.object({
|
|
1295
|
+
progressStage: z15.enum([
|
|
1247
1296
|
"waiting_for_connection",
|
|
1248
1297
|
"agent_connected",
|
|
1249
1298
|
"project_context_loaded",
|
|
@@ -1253,66 +1302,73 @@ var siteSetupTaskProgressSchema = z14.object({
|
|
|
1253
1302
|
"action_required",
|
|
1254
1303
|
"completed"
|
|
1255
1304
|
]),
|
|
1256
|
-
lastVerifiedAt:
|
|
1257
|
-
lastActivityAt:
|
|
1258
|
-
activitySource:
|
|
1305
|
+
lastVerifiedAt: z15.string().datetime().nullable(),
|
|
1306
|
+
lastActivityAt: z15.string().datetime(),
|
|
1307
|
+
activitySource: z15.enum(["user", "server", "agent"]),
|
|
1259
1308
|
activityPhase: siteSetupActivityInputSchema.shape.phase.nullable(),
|
|
1260
1309
|
activityTextId: siteSetupActivityInputSchema.shape.textId.nullable()
|
|
1261
1310
|
}).strict();
|
|
1262
|
-
var siteSetupTaskSchema =
|
|
1263
|
-
contractVersion:
|
|
1264
|
-
workflow:
|
|
1265
|
-
goal:
|
|
1311
|
+
var siteSetupTaskSchema = z15.object({
|
|
1312
|
+
contractVersion: z15.literal("siteplane.setup-task.v2"),
|
|
1313
|
+
workflow: z15.enum(["initial_setup", "structure_update"]),
|
|
1314
|
+
goal: z15.string().min(1),
|
|
1266
1315
|
modules: siteSetupModulesSchema,
|
|
1267
|
-
authorizationVersion:
|
|
1268
|
-
authorizedScopes:
|
|
1269
|
-
site:
|
|
1270
|
-
siteId:
|
|
1271
|
-
portalPath:
|
|
1272
|
-
adminOrigin:
|
|
1316
|
+
authorizationVersion: z15.number().int().positive(),
|
|
1317
|
+
authorizedScopes: z15.array(z15.string()).min(2),
|
|
1318
|
+
site: z15.object({
|
|
1319
|
+
siteId: z15.string().uuid(),
|
|
1320
|
+
portalPath: z15.string(),
|
|
1321
|
+
adminOrigin: z15.string().url()
|
|
1273
1322
|
}).strict().nullable(),
|
|
1274
1323
|
run: siteSetupTaskRunSchema.nullable(),
|
|
1275
1324
|
progress: siteSetupTaskProgressSchema.nullable(),
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1325
|
+
deployment: setupDeploymentRecordSchema.nullable(),
|
|
1326
|
+
revalidationGeneration: z15.number().int().positive(),
|
|
1327
|
+
assignment: z15.literal("owned"),
|
|
1328
|
+
deadline: z15.string().datetime().nullable(),
|
|
1329
|
+
userInstructions: z15.object({
|
|
1279
1330
|
text: siteSetupOwnerEditabilityNoteSchema,
|
|
1280
|
-
source:
|
|
1281
|
-
trust:
|
|
1331
|
+
source: z15.literal("user"),
|
|
1332
|
+
trust: z15.literal("untrusted")
|
|
1282
1333
|
}).strict(),
|
|
1283
1334
|
corrections: setupCorrectionItemsSchema,
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
source:
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1335
|
+
contentSelectionSummary: z15.object({
|
|
1336
|
+
text: siteSetupOwnerEditabilityNoteSchema,
|
|
1337
|
+
source: z15.literal("agent"),
|
|
1338
|
+
trust: z15.literal("untrusted")
|
|
1339
|
+
}).strict().nullable(),
|
|
1340
|
+
environmentBindings: z15.array(z15.object({
|
|
1341
|
+
name: z15.string().regex(/^[A-Z][A-Z0-9_]+$/u),
|
|
1342
|
+
source: z15.string().min(1),
|
|
1343
|
+
sensitivity: z15.enum(["public", "secret"]),
|
|
1344
|
+
usage: z15.enum(["build", "server", "build_and_server"]),
|
|
1345
|
+
evidence: z15.string().min(1)
|
|
1290
1346
|
}).strict()),
|
|
1291
1347
|
nextAction: siteSetupNextActionSchema,
|
|
1292
|
-
error:
|
|
1293
|
-
code:
|
|
1348
|
+
error: z15.object({
|
|
1349
|
+
code: z15.string().regex(/^[a-z0-9_.]+$/u).max(160),
|
|
1294
1350
|
boundary: nextActionFields.boundary,
|
|
1295
1351
|
responsibleActor: nextActionFields.actor,
|
|
1296
|
-
retryable:
|
|
1297
|
-
retryAfter:
|
|
1298
|
-
requestId:
|
|
1352
|
+
retryable: z15.boolean(),
|
|
1353
|
+
retryAfter: z15.number().int().nonnegative().nullable(),
|
|
1354
|
+
requestId: z15.string().regex(/^[A-Za-z0-9_-]+$/u).max(128)
|
|
1299
1355
|
}).strict().nullable(),
|
|
1300
|
-
packages:
|
|
1301
|
-
siteplane:
|
|
1302
|
-
runtimeNext:
|
|
1356
|
+
packages: z15.object({
|
|
1357
|
+
siteplane: z15.string().regex(/^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$/u),
|
|
1358
|
+
runtimeNext: z15.string().regex(/^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$/u)
|
|
1303
1359
|
}).strict(),
|
|
1304
|
-
communication:
|
|
1305
|
-
beforeSourceChanges:
|
|
1306
|
-
updates:
|
|
1307
|
-
blocker:
|
|
1360
|
+
communication: z15.object({
|
|
1361
|
+
beforeSourceChanges: z15.string().min(1),
|
|
1362
|
+
updates: z15.array(z15.string().min(1)).min(1),
|
|
1363
|
+
blocker: z15.string().min(1)
|
|
1308
1364
|
}).strict(),
|
|
1309
|
-
discovery:
|
|
1310
|
-
inspectPublicRoutes:
|
|
1311
|
-
contentKinds:
|
|
1312
|
-
rules:
|
|
1365
|
+
discovery: z15.object({
|
|
1366
|
+
inspectPublicRoutes: z15.boolean(),
|
|
1367
|
+
contentKinds: z15.array(z15.enum(["text", "longText", "link", "image"])).min(1),
|
|
1368
|
+
rules: z15.array(z15.string().min(1)).min(1)
|
|
1313
1369
|
}).strict(),
|
|
1314
|
-
steps:
|
|
1315
|
-
id:
|
|
1370
|
+
steps: z15.array(z15.object({
|
|
1371
|
+
id: z15.enum([
|
|
1316
1372
|
"inspect_repository",
|
|
1317
1373
|
"install_packages",
|
|
1318
1374
|
"instrument_fields",
|
|
@@ -1320,34 +1376,35 @@ var siteSetupTaskSchema = z14.object({
|
|
|
1320
1376
|
"deploy_production",
|
|
1321
1377
|
"verify_deployment"
|
|
1322
1378
|
]),
|
|
1323
|
-
instruction:
|
|
1379
|
+
instruction: z15.string().min(1)
|
|
1324
1380
|
}).strict()).length(6),
|
|
1325
|
-
completion:
|
|
1326
|
-
verifiedStatus:
|
|
1327
|
-
instruction:
|
|
1381
|
+
completion: z15.object({
|
|
1382
|
+
verifiedStatus: z15.literal("ready_for_review"),
|
|
1383
|
+
instruction: z15.string().min(1)
|
|
1328
1384
|
}).strict()
|
|
1329
1385
|
}).strict().refine((task) => hasExactSiteSetupScopes(task.authorizedScopes, task.modules), "Task scopes must exactly match its modules.");
|
|
1330
|
-
var canonicalHashSchema =
|
|
1386
|
+
var canonicalHashSchema = z15.string().regex(/^sha256:[0-9a-f]{64}$/iu);
|
|
1331
1387
|
var deploymentRevisionSchema = normalizedSafeTextSchema(256, "deploymentRevision");
|
|
1332
|
-
var continueSiteSetupInputSchema =
|
|
1333
|
-
siteId:
|
|
1334
|
-
runId:
|
|
1388
|
+
var continueSiteSetupInputSchema = z15.object({
|
|
1389
|
+
siteId: z15.string().uuid(),
|
|
1390
|
+
runId: z15.string().uuid(),
|
|
1335
1391
|
expectedFieldContractHash: canonicalHashSchema,
|
|
1336
1392
|
expectedDeploymentRevision: deploymentRevisionSchema,
|
|
1337
1393
|
correctionItems: setupCorrectionItemsSchema,
|
|
1338
1394
|
ownerEditabilityNote: siteSetupOwnerEditabilityNoteSchema.optional()
|
|
1339
1395
|
}).strict();
|
|
1340
|
-
var saveSiteSetupOwnerNoteInputSchema =
|
|
1341
|
-
siteId:
|
|
1342
|
-
runId:
|
|
1396
|
+
var saveSiteSetupOwnerNoteInputSchema = z15.object({
|
|
1397
|
+
siteId: z15.string().uuid(),
|
|
1398
|
+
runId: z15.string().uuid(),
|
|
1343
1399
|
expectedFieldContractHash: canonicalHashSchema,
|
|
1344
1400
|
expectedDeploymentRevision: deploymentRevisionSchema,
|
|
1345
1401
|
ownerEditabilityNote: siteSetupOwnerEditabilityNoteSchema
|
|
1346
1402
|
}).strict();
|
|
1347
|
-
var siteSetupContextInputSchema =
|
|
1348
|
-
var siteSetupApplyInputSchema =
|
|
1403
|
+
var siteSetupContextInputSchema = z15.object({}).strict();
|
|
1404
|
+
var siteSetupApplyInputSchema = z15.object({
|
|
1349
1405
|
fieldContract: siteFieldContractV1Schema,
|
|
1350
|
-
editorDefinition: editorDefinitionV1Schema
|
|
1406
|
+
editorDefinition: editorDefinitionV1Schema,
|
|
1407
|
+
contentSelectionSummary: siteSetupOwnerEditabilityNoteSchema.refine((text) => text.trim().length > 0, "Describe the selected content, important exclusions and any open gaps.")
|
|
1351
1408
|
}).strict().superRefine((input, context) => {
|
|
1352
1409
|
const contractRoutesByFieldId = new Map(input.fieldContract.fields.map((field) => [
|
|
1353
1410
|
field.fieldId,
|
|
@@ -1411,37 +1468,37 @@ var siteSetupApplyInputSchema = z14.object({
|
|
|
1411
1468
|
}
|
|
1412
1469
|
}
|
|
1413
1470
|
});
|
|
1414
|
-
var siteSetupVerifyInputSchema =
|
|
1415
|
-
deploymentUrl:
|
|
1471
|
+
var siteSetupVerifyInputSchema = z15.object({
|
|
1472
|
+
deploymentUrl: z15.string().url().refine((value) => value.startsWith("https://")),
|
|
1416
1473
|
deploymentRevision: deploymentRevisionSchema,
|
|
1417
|
-
wait:
|
|
1474
|
+
wait: z15.boolean().optional()
|
|
1418
1475
|
}).strict();
|
|
1419
|
-
var siteSetupEvidenceInputSchema =
|
|
1420
|
-
siteId:
|
|
1421
|
-
runId:
|
|
1476
|
+
var siteSetupEvidenceInputSchema = z15.object({
|
|
1477
|
+
siteId: z15.string().uuid(),
|
|
1478
|
+
runId: z15.string().uuid(),
|
|
1422
1479
|
expectedFieldContractHash: canonicalHashSchema,
|
|
1423
|
-
expectedDeploymentOrigin:
|
|
1480
|
+
expectedDeploymentOrigin: z15.string().url().refine((value) => value.startsWith("https://")),
|
|
1424
1481
|
expectedDeploymentRevision: deploymentRevisionSchema,
|
|
1425
|
-
publicRuntimeKeyId:
|
|
1482
|
+
publicRuntimeKeyId: z15.string().uuid(),
|
|
1426
1483
|
bridgeSessionId: normalizedSafeTextSchema(256, "bridgeSessionId"),
|
|
1427
|
-
observations:
|
|
1484
|
+
observations: z15.array(z15.object({
|
|
1428
1485
|
fieldId: fieldIdSchema,
|
|
1429
1486
|
routeKey: siteFieldRouteKeySchema,
|
|
1430
1487
|
renderedPath: renderedPathSchema,
|
|
1431
|
-
targetResolved:
|
|
1432
|
-
previewAck:
|
|
1488
|
+
targetResolved: z15.boolean(),
|
|
1489
|
+
previewAck: z15.boolean()
|
|
1433
1490
|
}).strict().refine((value) => !value.previewAck || value.targetResolved, "Preview ACK requires a resolved target.")).min(1).max(200)
|
|
1434
1491
|
}).strict();
|
|
1435
|
-
var completeSiteSetupInputSchema =
|
|
1436
|
-
siteId:
|
|
1437
|
-
runId:
|
|
1492
|
+
var completeSiteSetupInputSchema = z15.object({
|
|
1493
|
+
siteId: z15.string().uuid(),
|
|
1494
|
+
runId: z15.string().uuid(),
|
|
1438
1495
|
expectedFieldContractHash: canonicalHashSchema,
|
|
1439
1496
|
expectedDeploymentRevision: deploymentRevisionSchema,
|
|
1440
1497
|
expectedReadyFingerprint: canonicalHashSchema
|
|
1441
1498
|
}).strict();
|
|
1442
|
-
var refreshSiteSetupDeploymentInputSchema =
|
|
1443
|
-
siteId:
|
|
1444
|
-
deploymentUrl:
|
|
1499
|
+
var refreshSiteSetupDeploymentInputSchema = z15.object({
|
|
1500
|
+
siteId: z15.string().uuid(),
|
|
1501
|
+
deploymentUrl: z15.string().url().refine((value) => value.startsWith("https://")),
|
|
1445
1502
|
deploymentRevision: deploymentRevisionSchema
|
|
1446
1503
|
}).strict();
|
|
1447
1504
|
function addSafeByteIssues(value, maxBytes, label, context) {
|
|
@@ -1464,34 +1521,34 @@ function utf8Bytes(value) {
|
|
|
1464
1521
|
|
|
1465
1522
|
// ../shared/dist/bridge-protocol.js
|
|
1466
1523
|
var BRIDGE_PROTOCOL_VERSION = 2;
|
|
1467
|
-
var bridgeRectSchema =
|
|
1468
|
-
x:
|
|
1469
|
-
y:
|
|
1470
|
-
width:
|
|
1471
|
-
height:
|
|
1524
|
+
var bridgeRectSchema = z16.object({
|
|
1525
|
+
x: z16.number(),
|
|
1526
|
+
y: z16.number(),
|
|
1527
|
+
width: z16.number().nonnegative(),
|
|
1528
|
+
height: z16.number().nonnegative()
|
|
1472
1529
|
});
|
|
1473
|
-
var previewTextValueSchema =
|
|
1474
|
-
fieldType:
|
|
1475
|
-
value:
|
|
1530
|
+
var previewTextValueSchema = z16.object({
|
|
1531
|
+
fieldType: z16.enum(["text", "longText"]),
|
|
1532
|
+
value: z16.string()
|
|
1476
1533
|
});
|
|
1477
|
-
var previewLinkValueSchema =
|
|
1478
|
-
fieldType:
|
|
1479
|
-
value:
|
|
1480
|
-
href:
|
|
1481
|
-
label:
|
|
1534
|
+
var previewLinkValueSchema = z16.object({
|
|
1535
|
+
fieldType: z16.literal("link"),
|
|
1536
|
+
value: z16.object({
|
|
1537
|
+
href: z16.string().trim().min(1),
|
|
1538
|
+
label: z16.string().trim().min(1).optional()
|
|
1482
1539
|
})
|
|
1483
1540
|
});
|
|
1484
|
-
var previewImageValueSchema =
|
|
1485
|
-
fieldType:
|
|
1541
|
+
var previewImageValueSchema = z16.object({
|
|
1542
|
+
fieldType: z16.literal("image"),
|
|
1486
1543
|
value: imageValueSchema
|
|
1487
1544
|
});
|
|
1488
|
-
var bridgePreviewValueSchema =
|
|
1545
|
+
var bridgePreviewValueSchema = z16.discriminatedUnion("fieldType", [
|
|
1489
1546
|
previewTextValueSchema,
|
|
1490
1547
|
previewLinkValueSchema,
|
|
1491
1548
|
previewImageValueSchema
|
|
1492
1549
|
]);
|
|
1493
|
-
var fieldSelectionModeSchema =
|
|
1494
|
-
var fieldBridgeMissingContentActionSchema =
|
|
1550
|
+
var fieldSelectionModeSchema = z16.enum(["replace", "range", "toggle"]);
|
|
1551
|
+
var fieldBridgeMissingContentActionSchema = z16.enum([
|
|
1495
1552
|
"add",
|
|
1496
1553
|
"select",
|
|
1497
1554
|
"remove"
|
|
@@ -1510,77 +1567,77 @@ var FIELD_BRIDGE_MESSAGE_TYPES = [
|
|
|
1510
1567
|
"siteplane:field-bridge:preview-scrolled",
|
|
1511
1568
|
"siteplane:field-bridge:error"
|
|
1512
1569
|
];
|
|
1513
|
-
var canonicalFieldContractHashSchema =
|
|
1514
|
-
var bridgeSectionSchema =
|
|
1515
|
-
var realRenderedPathSchema =
|
|
1516
|
-
var fieldBridgeIdentitySchema =
|
|
1517
|
-
publicRuntimeKeyId:
|
|
1570
|
+
var canonicalFieldContractHashSchema = z16.string().regex(/^sha256:[0-9a-f]{64}$/u);
|
|
1571
|
+
var bridgeSectionSchema = z16.string().trim().min(1).max(256);
|
|
1572
|
+
var realRenderedPathSchema = z16.string().trim().refine((value) => value.startsWith("/") && value !== "$global" && !value.includes("?") && !value.includes("#"), "A field bridge rendered path must be a real canonical path.");
|
|
1573
|
+
var fieldBridgeIdentitySchema = z16.object({
|
|
1574
|
+
publicRuntimeKeyId: z16.string().uuid(),
|
|
1518
1575
|
fieldContractHash: canonicalFieldContractHashSchema,
|
|
1519
|
-
deploymentRevision:
|
|
1576
|
+
deploymentRevision: z16.string().trim().min(1).max(256)
|
|
1520
1577
|
}).strict();
|
|
1521
|
-
var fieldBridgeBaseSchema =
|
|
1522
|
-
version:
|
|
1523
|
-
type:
|
|
1524
|
-
siteId:
|
|
1525
|
-
sessionId:
|
|
1526
|
-
publicRuntimeKeyId:
|
|
1578
|
+
var fieldBridgeBaseSchema = z16.object({
|
|
1579
|
+
version: z16.literal(BRIDGE_PROTOCOL_VERSION),
|
|
1580
|
+
type: z16.enum(FIELD_BRIDGE_MESSAGE_TYPES),
|
|
1581
|
+
siteId: z16.string().uuid(),
|
|
1582
|
+
sessionId: z16.string().trim().min(1),
|
|
1583
|
+
publicRuntimeKeyId: z16.string().uuid(),
|
|
1527
1584
|
fieldContractHash: canonicalFieldContractHashSchema,
|
|
1528
|
-
deploymentRevision:
|
|
1529
|
-
requestId:
|
|
1530
|
-
sentAt:
|
|
1585
|
+
deploymentRevision: z16.string().trim().min(1).max(256),
|
|
1586
|
+
requestId: z16.string().trim().min(1),
|
|
1587
|
+
sentAt: z16.string().datetime()
|
|
1531
1588
|
}).strict();
|
|
1532
|
-
var fieldBridgeFieldSchema =
|
|
1589
|
+
var fieldBridgeFieldSchema = z16.object({
|
|
1533
1590
|
fieldId: fieldIdSchema,
|
|
1534
1591
|
fieldType: fieldTypeSchema,
|
|
1535
1592
|
routeKey: siteFieldRouteKeySchema,
|
|
1536
1593
|
renderedPath: realRenderedPathSchema,
|
|
1537
|
-
sourcePath:
|
|
1594
|
+
sourcePath: z16.string().trim().min(1).optional(),
|
|
1538
1595
|
editTarget: fieldIdSchema,
|
|
1539
1596
|
rect: bridgeRectSchema,
|
|
1540
|
-
targetResolved:
|
|
1597
|
+
targetResolved: z16.literal(true),
|
|
1541
1598
|
currentValue: bridgePreviewValueSchema.optional()
|
|
1542
1599
|
}).strict();
|
|
1543
1600
|
var fieldBridgeInitMessageSchema = fieldBridgeBaseSchema.extend({
|
|
1544
|
-
type:
|
|
1545
|
-
payload:
|
|
1546
|
-
adminOrigin:
|
|
1547
|
-
customerOrigin:
|
|
1601
|
+
type: z16.literal("siteplane:field-bridge:init"),
|
|
1602
|
+
payload: z16.object({
|
|
1603
|
+
adminOrigin: z16.string().url(),
|
|
1604
|
+
customerOrigin: z16.string().url(),
|
|
1548
1605
|
renderedPath: realRenderedPathSchema
|
|
1549
1606
|
}).strict()
|
|
1550
1607
|
});
|
|
1551
1608
|
var fieldBridgeReadyMessageSchema = fieldBridgeBaseSchema.extend({
|
|
1552
|
-
type:
|
|
1553
|
-
payload:
|
|
1609
|
+
type: z16.literal("siteplane:field-bridge:ready"),
|
|
1610
|
+
payload: z16.object({
|
|
1554
1611
|
renderedPath: realRenderedPathSchema,
|
|
1555
|
-
fieldCount:
|
|
1556
|
-
capabilities:
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1612
|
+
fieldCount: z16.number().int().nonnegative(),
|
|
1613
|
+
capabilities: z16.tuple([
|
|
1614
|
+
z16.literal("field_selection"),
|
|
1615
|
+
z16.literal("preview_values"),
|
|
1616
|
+
z16.literal("field_evidence"),
|
|
1617
|
+
z16.literal("visual_field_control")
|
|
1561
1618
|
])
|
|
1562
1619
|
}).strict()
|
|
1563
1620
|
});
|
|
1564
1621
|
var fieldBridgeFieldsMessageSchema = fieldBridgeBaseSchema.extend({
|
|
1565
|
-
type:
|
|
1566
|
-
payload:
|
|
1622
|
+
type: z16.literal("siteplane:field-bridge:fields"),
|
|
1623
|
+
payload: z16.object({
|
|
1567
1624
|
renderedPath: realRenderedPathSchema,
|
|
1568
|
-
fields:
|
|
1625
|
+
fields: z16.array(fieldBridgeFieldSchema)
|
|
1569
1626
|
}).strict()
|
|
1570
1627
|
});
|
|
1571
1628
|
var fieldBridgeSelectFieldMessageSchema = fieldBridgeBaseSchema.extend({
|
|
1572
|
-
type:
|
|
1573
|
-
payload:
|
|
1629
|
+
type: z16.literal("siteplane:field-bridge:select-field"),
|
|
1630
|
+
payload: z16.object({
|
|
1574
1631
|
fieldId: fieldIdSchema,
|
|
1575
1632
|
selectionMode: fieldSelectionModeSchema
|
|
1576
1633
|
}).strict()
|
|
1577
1634
|
});
|
|
1578
1635
|
var fieldBridgeSetSelectedFieldMessageSchema = fieldBridgeBaseSchema.extend({
|
|
1579
|
-
type:
|
|
1580
|
-
payload:
|
|
1581
|
-
fieldIds:
|
|
1636
|
+
type: z16.literal("siteplane:field-bridge:set-selected-field"),
|
|
1637
|
+
payload: z16.object({
|
|
1638
|
+
fieldIds: z16.array(fieldIdSchema).max(200),
|
|
1582
1639
|
primaryFieldId: fieldIdSchema.nullable(),
|
|
1583
|
-
scrollIntoView:
|
|
1640
|
+
scrollIntoView: z16.boolean().optional()
|
|
1584
1641
|
}).strict().superRefine((value, context) => {
|
|
1585
1642
|
if (value.fieldIds.length > 0 && value.primaryFieldId === null) {
|
|
1586
1643
|
context.addIssue({
|
|
@@ -1599,58 +1656,58 @@ var fieldBridgeSetSelectedFieldMessageSchema = fieldBridgeBaseSchema.extend({
|
|
|
1599
1656
|
})
|
|
1600
1657
|
});
|
|
1601
1658
|
var fieldBridgeApplyPreviewValuesMessageSchema = fieldBridgeBaseSchema.extend({
|
|
1602
|
-
type:
|
|
1603
|
-
payload:
|
|
1659
|
+
type: z16.literal("siteplane:field-bridge:apply-preview-values"),
|
|
1660
|
+
payload: z16.object({ values: z16.record(fieldIdSchema, bridgePreviewValueSchema) }).strict()
|
|
1604
1661
|
});
|
|
1605
1662
|
var fieldBridgeTestPreviewValuesMessageSchema = fieldBridgeBaseSchema.extend({
|
|
1606
|
-
type:
|
|
1607
|
-
payload:
|
|
1663
|
+
type: z16.literal("siteplane:field-bridge:test-preview-values"),
|
|
1664
|
+
payload: z16.object({ fieldIds: z16.array(fieldIdSchema).min(1).max(200) }).strict()
|
|
1608
1665
|
});
|
|
1609
1666
|
var fieldBridgePreviewAckMessageSchema = fieldBridgeBaseSchema.extend({
|
|
1610
|
-
type:
|
|
1611
|
-
payload:
|
|
1612
|
-
ackRequestId:
|
|
1613
|
-
kind:
|
|
1667
|
+
type: z16.literal("siteplane:field-bridge:preview-ack"),
|
|
1668
|
+
payload: z16.object({
|
|
1669
|
+
ackRequestId: z16.string().trim().min(1),
|
|
1670
|
+
kind: z16.enum(["apply", "test"]),
|
|
1614
1671
|
renderedPath: realRenderedPathSchema,
|
|
1615
|
-
fieldIds:
|
|
1672
|
+
fieldIds: z16.array(fieldIdSchema).max(200)
|
|
1616
1673
|
}).strict()
|
|
1617
1674
|
});
|
|
1618
1675
|
var fieldBridgeSetVisualControlStateMessageSchema = fieldBridgeBaseSchema.extend({
|
|
1619
|
-
type:
|
|
1620
|
-
payload:
|
|
1621
|
-
enabled:
|
|
1622
|
-
fieldProximityEnabled:
|
|
1623
|
-
pendingKeys:
|
|
1624
|
-
activeFieldIds:
|
|
1625
|
-
fieldSections:
|
|
1626
|
-
selectedPending:
|
|
1627
|
-
key:
|
|
1628
|
-
locatorHint:
|
|
1676
|
+
type: z16.literal("siteplane:field-bridge:set-visual-control-state"),
|
|
1677
|
+
payload: z16.object({
|
|
1678
|
+
enabled: z16.boolean(),
|
|
1679
|
+
fieldProximityEnabled: z16.boolean(),
|
|
1680
|
+
pendingKeys: z16.array(z16.string().trim().min(1).max(2048)).max(50),
|
|
1681
|
+
activeFieldIds: z16.array(fieldIdSchema),
|
|
1682
|
+
fieldSections: z16.record(fieldIdSchema, bridgeSectionSchema),
|
|
1683
|
+
selectedPending: z16.array(z16.object({
|
|
1684
|
+
key: z16.string().trim().min(1).max(2048),
|
|
1685
|
+
locatorHint: z16.string().trim().min(1).max(2048)
|
|
1629
1686
|
}).strict()).max(50),
|
|
1630
|
-
scrollPendingIntoView:
|
|
1687
|
+
scrollPendingIntoView: z16.boolean().optional()
|
|
1631
1688
|
}).strict()
|
|
1632
1689
|
});
|
|
1633
1690
|
var fieldBridgeMissingContentMessageSchema = fieldBridgeBaseSchema.extend({
|
|
1634
|
-
type:
|
|
1635
|
-
payload:
|
|
1691
|
+
type: z16.literal("siteplane:field-bridge:missing-content"),
|
|
1692
|
+
payload: z16.object({
|
|
1636
1693
|
action: fieldBridgeMissingContentActionSchema,
|
|
1637
1694
|
item: setupCorrectionItemSchema,
|
|
1638
1695
|
suggestedSection: bridgeSectionSchema.optional()
|
|
1639
1696
|
}).strict()
|
|
1640
1697
|
});
|
|
1641
1698
|
var fieldBridgePreviewScrolledMessageSchema = fieldBridgeBaseSchema.extend({
|
|
1642
|
-
type:
|
|
1643
|
-
payload:
|
|
1699
|
+
type: z16.literal("siteplane:field-bridge:preview-scrolled"),
|
|
1700
|
+
payload: z16.object({ renderedPath: realRenderedPathSchema }).strict()
|
|
1644
1701
|
});
|
|
1645
1702
|
var fieldBridgeErrorMessageSchema = fieldBridgeBaseSchema.extend({
|
|
1646
|
-
type:
|
|
1647
|
-
payload:
|
|
1648
|
-
code:
|
|
1649
|
-
message:
|
|
1650
|
-
recoverable:
|
|
1703
|
+
type: z16.literal("siteplane:field-bridge:error"),
|
|
1704
|
+
payload: z16.object({
|
|
1705
|
+
code: z16.string().trim().min(1),
|
|
1706
|
+
message: z16.string().trim().min(1),
|
|
1707
|
+
recoverable: z16.boolean().default(false)
|
|
1651
1708
|
}).strict()
|
|
1652
1709
|
});
|
|
1653
|
-
var fieldBridgeMessageSchema =
|
|
1710
|
+
var fieldBridgeMessageSchema = z16.discriminatedUnion("type", [
|
|
1654
1711
|
fieldBridgeInitMessageSchema,
|
|
1655
1712
|
fieldBridgeReadyMessageSchema,
|
|
1656
1713
|
fieldBridgeFieldsMessageSchema,
|
|
@@ -1666,51 +1723,51 @@ var fieldBridgeMessageSchema = z15.discriminatedUnion("type", [
|
|
|
1666
1723
|
]);
|
|
1667
1724
|
|
|
1668
1725
|
// ../shared/dist/commands.js
|
|
1669
|
-
import { z as
|
|
1726
|
+
import { z as z18 } from "zod";
|
|
1670
1727
|
|
|
1671
1728
|
// ../shared/dist/errors.js
|
|
1672
|
-
import { z as
|
|
1729
|
+
import { z as z17 } from "zod";
|
|
1673
1730
|
var UI_ERROR_CATEGORIES = [
|
|
1674
1731
|
"site_member",
|
|
1675
1732
|
"workspace_member",
|
|
1676
1733
|
"internal"
|
|
1677
1734
|
];
|
|
1678
|
-
var uiErrorCategorySchema =
|
|
1679
|
-
var commandErrorPayloadSchema =
|
|
1680
|
-
code:
|
|
1681
|
-
message:
|
|
1735
|
+
var uiErrorCategorySchema = z17.enum(UI_ERROR_CATEGORIES);
|
|
1736
|
+
var commandErrorPayloadSchema = z17.object({
|
|
1737
|
+
code: z17.string().min(1),
|
|
1738
|
+
message: z17.string().min(1),
|
|
1682
1739
|
category: uiErrorCategorySchema,
|
|
1683
|
-
details:
|
|
1740
|
+
details: z17.record(z17.string(), z17.unknown()).optional()
|
|
1684
1741
|
});
|
|
1685
1742
|
|
|
1686
1743
|
// ../shared/dist/commands.js
|
|
1687
|
-
var commandSuccessSchema =
|
|
1688
|
-
ok:
|
|
1689
|
-
data:
|
|
1744
|
+
var commandSuccessSchema = z18.object({
|
|
1745
|
+
ok: z18.literal(true),
|
|
1746
|
+
data: z18.unknown()
|
|
1690
1747
|
});
|
|
1691
|
-
var commandErrorSchema =
|
|
1692
|
-
ok:
|
|
1748
|
+
var commandErrorSchema = z18.object({
|
|
1749
|
+
ok: z18.literal(false),
|
|
1693
1750
|
error: commandErrorPayloadSchema
|
|
1694
1751
|
});
|
|
1695
|
-
var commandResultSchema =
|
|
1752
|
+
var commandResultSchema = z18.discriminatedUnion("ok", [
|
|
1696
1753
|
commandSuccessSchema,
|
|
1697
1754
|
commandErrorSchema
|
|
1698
1755
|
]);
|
|
1699
1756
|
|
|
1700
1757
|
// ../shared/dist/editor-settings.js
|
|
1701
|
-
import { z as
|
|
1702
|
-
var editorColorSchemeSchema =
|
|
1758
|
+
import { z as z19 } from "zod";
|
|
1759
|
+
var editorColorSchemeSchema = z19.enum([
|
|
1703
1760
|
"paper",
|
|
1704
1761
|
"slate",
|
|
1705
1762
|
"siteplane",
|
|
1706
1763
|
"bloom"
|
|
1707
1764
|
]);
|
|
1708
1765
|
var editorColorSchemes = editorColorSchemeSchema.options;
|
|
1709
|
-
var editorColorModeSchema =
|
|
1766
|
+
var editorColorModeSchema = z19.enum(["light", "dark"]);
|
|
1710
1767
|
var editorColorModes = editorColorModeSchema.options;
|
|
1711
1768
|
|
|
1712
1769
|
// ../shared/dist/site-slug.js
|
|
1713
|
-
import { z as
|
|
1770
|
+
import { z as z20 } from "zod";
|
|
1714
1771
|
var SITE_SLUG_PATTERN = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
|
|
1715
1772
|
var RESERVED_SITE_SLUGS = /* @__PURE__ */ new Set([
|
|
1716
1773
|
"account",
|
|
@@ -1727,31 +1784,31 @@ var RESERVED_SITE_SLUGS = /* @__PURE__ */ new Set([
|
|
|
1727
1784
|
"support",
|
|
1728
1785
|
"workspace"
|
|
1729
1786
|
]);
|
|
1730
|
-
var siteSlugSchema =
|
|
1787
|
+
var siteSlugSchema = z20.string().regex(SITE_SLUG_PATTERN, "Invalid site slug").refine((value) => !RESERVED_SITE_SLUGS.has(value), "Reserved site slug");
|
|
1731
1788
|
|
|
1732
1789
|
// ../shared/dist/entitlements.js
|
|
1733
|
-
import { z as
|
|
1734
|
-
var entitlementSnapshotSchema =
|
|
1735
|
-
planKey:
|
|
1736
|
-
sitesLimit:
|
|
1737
|
-
siteMembersPerSiteLimit:
|
|
1738
|
-
customAdminDomainsEnabled:
|
|
1739
|
-
agentMcpEnabled:
|
|
1740
|
-
emailNotificationsEnabled:
|
|
1741
|
-
analyticsEnabled:
|
|
1742
|
-
analyticsSitesLimit:
|
|
1743
|
-
analyticsPortalPerformanceEnabled:
|
|
1744
|
-
analyticsMonthlyReportsEnabled:
|
|
1745
|
-
analyticsAiSummaryEnabled:
|
|
1746
|
-
analyticsRawEventRetentionDays:
|
|
1747
|
-
analyticsMonthlyEventLimit:
|
|
1748
|
-
bookingEnabled:
|
|
1749
|
-
bookingSitesLimit:
|
|
1750
|
-
bookingPortalManagementEnabled:
|
|
1751
|
-
bookingResourcesPerSiteLimit:
|
|
1752
|
-
bookingServicesPerSiteLimit:
|
|
1753
|
-
bookingMonthlyBookingsLimit:
|
|
1754
|
-
bookingRemindersEnabled:
|
|
1790
|
+
import { z as z21 } from "zod";
|
|
1791
|
+
var entitlementSnapshotSchema = z21.object({
|
|
1792
|
+
planKey: z21.string().trim().min(1),
|
|
1793
|
+
sitesLimit: z21.number().int().positive(),
|
|
1794
|
+
siteMembersPerSiteLimit: z21.number().int().positive(),
|
|
1795
|
+
customAdminDomainsEnabled: z21.boolean(),
|
|
1796
|
+
agentMcpEnabled: z21.boolean(),
|
|
1797
|
+
emailNotificationsEnabled: z21.boolean(),
|
|
1798
|
+
analyticsEnabled: z21.boolean(),
|
|
1799
|
+
analyticsSitesLimit: z21.number().int().min(0),
|
|
1800
|
+
analyticsPortalPerformanceEnabled: z21.boolean(),
|
|
1801
|
+
analyticsMonthlyReportsEnabled: z21.boolean(),
|
|
1802
|
+
analyticsAiSummaryEnabled: z21.boolean(),
|
|
1803
|
+
analyticsRawEventRetentionDays: z21.number().int().min(1).max(ANALYTICS_RETENTION_DEFAULTS.maxRawEventRetentionDaysWithoutAdr),
|
|
1804
|
+
analyticsMonthlyEventLimit: z21.number().int().min(0),
|
|
1805
|
+
bookingEnabled: z21.boolean().default(false),
|
|
1806
|
+
bookingSitesLimit: z21.number().int().min(0).default(0),
|
|
1807
|
+
bookingPortalManagementEnabled: z21.boolean().default(false),
|
|
1808
|
+
bookingResourcesPerSiteLimit: z21.number().int().min(0).default(0),
|
|
1809
|
+
bookingServicesPerSiteLimit: z21.number().int().min(0).default(0),
|
|
1810
|
+
bookingMonthlyBookingsLimit: z21.number().int().min(0).default(0),
|
|
1811
|
+
bookingRemindersEnabled: z21.boolean().default(false)
|
|
1755
1812
|
});
|
|
1756
1813
|
var EARLY_ACCESS_PLAN = {
|
|
1757
1814
|
planKey: "early_access_2026",
|
|
@@ -1777,7 +1834,7 @@ var EARLY_ACCESS_PLAN = {
|
|
|
1777
1834
|
};
|
|
1778
1835
|
|
|
1779
1836
|
// ../shared/dist/readiness.js
|
|
1780
|
-
import { z as
|
|
1837
|
+
import { z as z22 } from "zod";
|
|
1781
1838
|
var READINESS_CHECK_KEYS = [
|
|
1782
1839
|
"agent_instructions_installed",
|
|
1783
1840
|
"runtime_package_connected",
|
|
@@ -1792,19 +1849,19 @@ var READINESS_STATUSES = [
|
|
|
1792
1849
|
"failing",
|
|
1793
1850
|
"warning"
|
|
1794
1851
|
];
|
|
1795
|
-
var readinessCheckKeySchema =
|
|
1796
|
-
var readinessStatusSchema =
|
|
1852
|
+
var readinessCheckKeySchema = z22.enum(READINESS_CHECK_KEYS);
|
|
1853
|
+
var readinessStatusSchema = z22.enum(READINESS_STATUSES);
|
|
1797
1854
|
|
|
1798
1855
|
// ../shared/dist/site.js
|
|
1799
|
-
import { z as
|
|
1856
|
+
import { z as z23 } from "zod";
|
|
1800
1857
|
var SITE_STATUSES = [
|
|
1801
1858
|
"setup",
|
|
1802
1859
|
"active",
|
|
1803
1860
|
"disabled",
|
|
1804
1861
|
"archived"
|
|
1805
1862
|
];
|
|
1806
|
-
var siteStatusSchema =
|
|
1807
|
-
var websiteUrlSchema =
|
|
1863
|
+
var siteStatusSchema = z23.enum(SITE_STATUSES);
|
|
1864
|
+
var websiteUrlSchema = z23.string().trim().url().refine((value) => value.startsWith("https://") || value.startsWith("http://"), "Website URL must use http or https");
|
|
1808
1865
|
|
|
1809
1866
|
// ../cli/dist/analytics/static-scan.js
|
|
1810
1867
|
import ts from "typescript";
|
|
@@ -1995,16 +2052,16 @@ ${analyticsRulesTemplate}`;
|
|
|
1995
2052
|
import { createHash } from "crypto";
|
|
1996
2053
|
|
|
1997
2054
|
// ../cli/dist/commands/analytics/public-key.js
|
|
1998
|
-
import { z as
|
|
1999
|
-
var responseSchema =
|
|
2000
|
-
ok:
|
|
2001
|
-
data:
|
|
2002
|
-
rawPublicKey:
|
|
2055
|
+
import { z as z24 } from "zod";
|
|
2056
|
+
var responseSchema = z24.object({
|
|
2057
|
+
ok: z24.literal(true),
|
|
2058
|
+
data: z24.object({
|
|
2059
|
+
rawPublicKey: z24.string().regex(/^pk_siteplane_[A-Za-z0-9_-]{16}_[A-Za-z0-9_-]{43}$/)
|
|
2003
2060
|
})
|
|
2004
2061
|
});
|
|
2005
|
-
var errorResponseSchema =
|
|
2006
|
-
error:
|
|
2007
|
-
code:
|
|
2062
|
+
var errorResponseSchema = z24.object({
|
|
2063
|
+
error: z24.object({
|
|
2064
|
+
code: z24.string().regex(/^[a-z][a-z0-9_.-]+$/u)
|
|
2008
2065
|
})
|
|
2009
2066
|
});
|
|
2010
2067
|
|
|
@@ -2200,14 +2257,22 @@ function requireContentExportScope(scopes) {
|
|
|
2200
2257
|
import { access, chmod, open, readFile as readFile5, rename, rm } from "fs/promises";
|
|
2201
2258
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
2202
2259
|
import { join as join3 } from "path";
|
|
2203
|
-
import { z as
|
|
2204
|
-
var siteplaneProjectConfigSchema =
|
|
2205
|
-
version:
|
|
2206
|
-
apiBaseUrl:
|
|
2207
|
-
siteId:
|
|
2208
|
-
publicSiteKeyId:
|
|
2209
|
-
publicSiteKey:
|
|
2210
|
-
|
|
2260
|
+
import { z as z25 } from "zod";
|
|
2261
|
+
var siteplaneProjectConfigSchema = z25.object({
|
|
2262
|
+
version: z25.literal(2),
|
|
2263
|
+
apiBaseUrl: z25.string().url(),
|
|
2264
|
+
siteId: z25.string().uuid(),
|
|
2265
|
+
publicSiteKeyId: z25.string().uuid(),
|
|
2266
|
+
publicSiteKey: z25.string().trim().min(1),
|
|
2267
|
+
runId: z25.string().uuid(),
|
|
2268
|
+
appDirectory: z25.string().min(1),
|
|
2269
|
+
taskContractVersion: z25.literal("siteplane.setup-task.v2"),
|
|
2270
|
+
adminProtocolVersion: z25.literal(2),
|
|
2271
|
+
packages: z25.object({
|
|
2272
|
+
siteplane: z25.string().regex(/^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$/u),
|
|
2273
|
+
runtimeNext: z25.string().regex(/^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$/u)
|
|
2274
|
+
}).strict(),
|
|
2275
|
+
fieldContractHash: z25.string().regex(/^sha256:[0-9a-f]{64}$/iu).optional()
|
|
2211
2276
|
}).strict();
|
|
2212
2277
|
async function readProjectPackageJson(projectDir) {
|
|
2213
2278
|
return JSON.parse(await readFile5(join3(projectDir, "package.json"), "utf8"));
|
|
@@ -2264,16 +2329,21 @@ async function writeJsonAtomically(path, value, mode) {
|
|
|
2264
2329
|
// ../cli/dist/config/credentials.js
|
|
2265
2330
|
import { execFile } from "child_process";
|
|
2266
2331
|
import { randomUUID as randomUUID3 } from "crypto";
|
|
2267
|
-
import { chmod as chmod2, mkdir as mkdir5, open as open2, readFile as readFile6, rename as rename2, rm as rm2 } from "fs/promises";
|
|
2332
|
+
import { chmod as chmod2, lstat, mkdir as mkdir5, open as open2, readFile as readFile6, rename as rename2, rm as rm2 } from "fs/promises";
|
|
2268
2333
|
import { dirname as dirname5, join as join4, relative } from "path";
|
|
2269
2334
|
import { promisify } from "util";
|
|
2270
|
-
import { z as
|
|
2271
|
-
var siteplaneCredentialsSchema =
|
|
2272
|
-
accessToken:
|
|
2273
|
-
siteRevalidationSecret:
|
|
2335
|
+
import { z as z26 } from "zod";
|
|
2336
|
+
var siteplaneCredentialsSchema = z26.object({
|
|
2337
|
+
accessToken: z26.string().trim().min(1),
|
|
2338
|
+
siteRevalidationSecret: z26.string().trim().min(1),
|
|
2339
|
+
adminSession: z26.object({
|
|
2340
|
+
secret: z26.string().regex(/^[A-Za-z0-9_-]{43}$/u),
|
|
2341
|
+
generation: z26.string().uuid()
|
|
2342
|
+
}).strict().optional()
|
|
2274
2343
|
}).strict();
|
|
2275
2344
|
async function assertLocalCredentialsPathSafe(projectDir, options = {}) {
|
|
2276
2345
|
const path = join4(projectDir, ".siteplane/credentials.json");
|
|
2346
|
+
await assertCredentialFilesystemSafe(projectDir);
|
|
2277
2347
|
const isTrackedFile = options.isTrackedFile ?? ((targetPath) => gitPathMatches(projectDir, targetPath, "ls-files"));
|
|
2278
2348
|
const isIgnoredFile = options.isIgnoredFile ?? ((targetPath) => gitPathMatches(projectDir, targetPath, "check-ignore"));
|
|
2279
2349
|
if (await isTrackedFile(path)) {
|
|
@@ -2284,6 +2354,27 @@ async function assertLocalCredentialsPathSafe(projectDir, options = {}) {
|
|
|
2284
2354
|
}
|
|
2285
2355
|
return path;
|
|
2286
2356
|
}
|
|
2357
|
+
async function assertCredentialFilesystemSafe(projectDir) {
|
|
2358
|
+
for (const [path, directory, mode] of [
|
|
2359
|
+
[projectDir, true, null],
|
|
2360
|
+
[join4(projectDir, ".siteplane"), true, 448],
|
|
2361
|
+
[join4(projectDir, ".siteplane/credentials.json"), false, 384]
|
|
2362
|
+
]) {
|
|
2363
|
+
const stat = await lstat(path).catch((error) => {
|
|
2364
|
+
if (error.code === "ENOENT")
|
|
2365
|
+
return null;
|
|
2366
|
+
throw error;
|
|
2367
|
+
});
|
|
2368
|
+
if (!stat)
|
|
2369
|
+
continue;
|
|
2370
|
+
if (stat.isSymbolicLink() || (directory ? !stat.isDirectory() : !stat.isFile())) {
|
|
2371
|
+
throw new Error("Siteplane credential paths must not contain symlinks or unexpected file types.");
|
|
2372
|
+
}
|
|
2373
|
+
if (mode !== null && (stat.mode & 511) !== mode) {
|
|
2374
|
+
throw new Error(`Siteplane credential ${directory ? "directory" : "file"} permissions must be ${mode.toString(8)} before setup.`);
|
|
2375
|
+
}
|
|
2376
|
+
}
|
|
2377
|
+
}
|
|
2287
2378
|
async function writeLocalCredentials(projectDir, credentials, options = {}) {
|
|
2288
2379
|
const path = await assertLocalCredentialsPathSafe(projectDir, options);
|
|
2289
2380
|
const parsed = siteplaneCredentialsSchema.parse(credentials);
|
|
@@ -2292,6 +2383,7 @@ async function writeLocalCredentials(projectDir, credentials, options = {}) {
|
|
|
2292
2383
|
return path;
|
|
2293
2384
|
}
|
|
2294
2385
|
async function readLocalCredentials(projectDir) {
|
|
2386
|
+
await assertCredentialFilesystemSafe(projectDir);
|
|
2295
2387
|
return siteplaneCredentialsSchema.parse(JSON.parse(await readFile6(join4(projectDir, ".siteplane/credentials.json"), "utf8")));
|
|
2296
2388
|
}
|
|
2297
2389
|
async function writeCredentialsAtomically(path, credentials) {
|
|
@@ -2327,8 +2419,452 @@ async function gitPathMatches(projectDir, path, command) {
|
|
|
2327
2419
|
}
|
|
2328
2420
|
|
|
2329
2421
|
// ../cli/dist/commands/init.js
|
|
2422
|
+
import { access as access3 } from "fs/promises";
|
|
2423
|
+
import { join as join7, relative as relative3 } from "path";
|
|
2424
|
+
import { z as z29 } from "zod";
|
|
2425
|
+
|
|
2426
|
+
// ../cli/dist/commands/setup-preflight.js
|
|
2427
|
+
import { createHash as createHash2 } from "crypto";
|
|
2428
|
+
import semver from "semver";
|
|
2429
|
+
import { minimatch } from "minimatch";
|
|
2430
|
+
import { parse as parseYaml } from "yaml";
|
|
2431
|
+
|
|
2432
|
+
// ../cli/dist/config/installed-package.js
|
|
2433
|
+
import { createRequire } from "module";
|
|
2434
|
+
import { readFile as readFile7 } from "fs/promises";
|
|
2330
2435
|
import { join as join5 } from "path";
|
|
2331
|
-
import { z as
|
|
2436
|
+
import { z as z27 } from "zod";
|
|
2437
|
+
var packageSchema = z27.object({
|
|
2438
|
+
name: z27.string().optional(),
|
|
2439
|
+
version: z27.string(),
|
|
2440
|
+
peerDependencies: z27.record(z27.string(), z27.string()).optional()
|
|
2441
|
+
});
|
|
2442
|
+
async function readInstalledPackage(projectDir, name2) {
|
|
2443
|
+
const require2 = createRequire(join5(projectDir, "package.json"));
|
|
2444
|
+
for (const directory of require2.resolve.paths(name2) ?? []) {
|
|
2445
|
+
try {
|
|
2446
|
+
return packageSchema.parse(JSON.parse(await readFile7(join5(directory, name2, "package.json"), "utf8")));
|
|
2447
|
+
} catch (error) {
|
|
2448
|
+
if (error.code !== "ENOENT")
|
|
2449
|
+
throw error;
|
|
2450
|
+
}
|
|
2451
|
+
}
|
|
2452
|
+
throw new Error(`Install ${name2} with the canonical package manager before setup.`);
|
|
2453
|
+
}
|
|
2454
|
+
|
|
2455
|
+
// ../cli/dist/commands/setup-preflight.js
|
|
2456
|
+
import { access as access2, readFile as readFile8, realpath, readdir, readlink } from "fs/promises";
|
|
2457
|
+
import { dirname as dirname6, join as join6, relative as relative2, resolve, sep } from "path";
|
|
2458
|
+
import { z as z28 } from "zod";
|
|
2459
|
+
|
|
2460
|
+
// ../cli/dist/commands/setup-process.js
|
|
2461
|
+
import { spawn } from "child_process";
|
|
2462
|
+
var SetupFailure = class extends Error {
|
|
2463
|
+
code;
|
|
2464
|
+
constructor(code, message) {
|
|
2465
|
+
super(message);
|
|
2466
|
+
this.code = code;
|
|
2467
|
+
}
|
|
2468
|
+
};
|
|
2469
|
+
async function setupProcess(binary, args, options) {
|
|
2470
|
+
return new Promise((resolve4, reject) => {
|
|
2471
|
+
const child = spawn(binary, args, {
|
|
2472
|
+
cwd: options.cwd,
|
|
2473
|
+
env: process.env,
|
|
2474
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
2475
|
+
});
|
|
2476
|
+
const chunks = [];
|
|
2477
|
+
const errors = [];
|
|
2478
|
+
let errorBytes = 0;
|
|
2479
|
+
let bytes = 0;
|
|
2480
|
+
let exceeded = false;
|
|
2481
|
+
const timer = setTimeout(() => {
|
|
2482
|
+
exceeded = true;
|
|
2483
|
+
child.kill("SIGKILL");
|
|
2484
|
+
}, options.timeoutMs ?? 12e4);
|
|
2485
|
+
const capture = (chunk) => {
|
|
2486
|
+
bytes += chunk.length;
|
|
2487
|
+
if (bytes > 4 * 1024 * 1024) {
|
|
2488
|
+
exceeded = true;
|
|
2489
|
+
child.kill("SIGKILL");
|
|
2490
|
+
} else
|
|
2491
|
+
chunks.push(chunk);
|
|
2492
|
+
};
|
|
2493
|
+
child.stdout.on("data", capture);
|
|
2494
|
+
child.stderr.on("data", (chunk) => {
|
|
2495
|
+
errorBytes += chunk.length;
|
|
2496
|
+
if (errorBytes <= 4 * 1024 * 1024)
|
|
2497
|
+
errors.push(chunk);
|
|
2498
|
+
else {
|
|
2499
|
+
exceeded = true;
|
|
2500
|
+
child.kill("SIGKILL");
|
|
2501
|
+
}
|
|
2502
|
+
});
|
|
2503
|
+
child.on("error", () => {
|
|
2504
|
+
clearTimeout(timer);
|
|
2505
|
+
reject(new SetupFailure("local_tool_unavailable", `${binary} could not be started. Check the local installation and access.`));
|
|
2506
|
+
});
|
|
2507
|
+
child.on("close", (code) => {
|
|
2508
|
+
clearTimeout(timer);
|
|
2509
|
+
if (exceeded)
|
|
2510
|
+
reject(new SetupFailure("provider_timeout", "The operation exceeded its time or response limit; inspect the existing operation before retrying."));
|
|
2511
|
+
else if (code !== 0) {
|
|
2512
|
+
const diagnostic = Buffer.concat([...chunks, ...errors]).toString("utf8");
|
|
2513
|
+
if (/\b(?:401|403|unauthorized|forbidden|not authenticated|not authorized|login required|E401|E403)\b/iu.test(diagnostic))
|
|
2514
|
+
reject(new SetupFailure("provider_access_denied", `${binary} denied access. Restore the existing local login and project/package permissions before retrying.`));
|
|
2515
|
+
else if (/\b(?:ECONNRESET|ETIMEDOUT|ENOTFOUND|EAI_AGAIN|ECONNREFUSED|429|502|503|504)\b/iu.test(diagnostic))
|
|
2516
|
+
reject(new SetupFailure("provider_transport_failed", `${binary} could not reach its provider. Inspect the existing operation before retrying.`));
|
|
2517
|
+
else
|
|
2518
|
+
reject(new SetupFailure("local_command_failed", `${binary} failed. Check its local login, permissions and project configuration.`));
|
|
2519
|
+
} else
|
|
2520
|
+
resolve4(Buffer.concat(options.includeStderr ? [...chunks, ...errors] : chunks).toString("utf8"));
|
|
2521
|
+
});
|
|
2522
|
+
child.stdin.on("error", () => {
|
|
2523
|
+
});
|
|
2524
|
+
child.stdin.end(options.input);
|
|
2525
|
+
});
|
|
2526
|
+
}
|
|
2527
|
+
async function setupVercelApi(cwd, endpoint, body, method, options) {
|
|
2528
|
+
const args = ["api", endpoint, "--raw"];
|
|
2529
|
+
if (body !== void 0)
|
|
2530
|
+
args.push("--method", method ?? "POST", "--input", "-");
|
|
2531
|
+
else if (method)
|
|
2532
|
+
args.push("--method", method);
|
|
2533
|
+
let output = "";
|
|
2534
|
+
for (let attempt = 0; attempt < 3; attempt++) {
|
|
2535
|
+
const remaining = (options?.deadline ?? Date.now() + 3e4) - Date.now();
|
|
2536
|
+
if (remaining <= 0)
|
|
2537
|
+
throw new SetupFailure("provider_deadline_exceeded", "The provider deadline expired; inspect the recorded operation before continuing.");
|
|
2538
|
+
try {
|
|
2539
|
+
output = await setupProcess("vercel", args, {
|
|
2540
|
+
cwd,
|
|
2541
|
+
timeoutMs: Math.min(3e4, remaining),
|
|
2542
|
+
...body === void 0 ? {} : { input: JSON.stringify(body) }
|
|
2543
|
+
});
|
|
2544
|
+
break;
|
|
2545
|
+
} catch (error) {
|
|
2546
|
+
if (!(error instanceof SetupFailure) || error.code !== "provider_transport_failed" || attempt === 2)
|
|
2547
|
+
throw error;
|
|
2548
|
+
await new Promise((resolve4) => setTimeout(resolve4, Math.min(1e3 * 2 ** attempt, Math.max(0, (options?.deadline ?? Date.now() + 2e3) - Date.now()))));
|
|
2549
|
+
}
|
|
2550
|
+
}
|
|
2551
|
+
try {
|
|
2552
|
+
return JSON.parse(output);
|
|
2553
|
+
} catch {
|
|
2554
|
+
throw new SetupFailure("invalid_provider_response", "Vercel did not return valid JSON for the bound project.");
|
|
2555
|
+
}
|
|
2556
|
+
}
|
|
2557
|
+
|
|
2558
|
+
// ../cli/dist/commands/setup-preflight.js
|
|
2559
|
+
var manifestSchema = z28.object({
|
|
2560
|
+
packageManager: z28.string().optional(),
|
|
2561
|
+
engines: z28.object({ node: z28.string().optional() }).optional(),
|
|
2562
|
+
dependencies: z28.record(z28.string(), z28.string()).optional(),
|
|
2563
|
+
devDependencies: z28.record(z28.string(), z28.string()).optional(),
|
|
2564
|
+
scripts: z28.record(z28.string(), z28.string()).optional(),
|
|
2565
|
+
workspaces: z28.unknown().optional()
|
|
2566
|
+
});
|
|
2567
|
+
var vercelProjectSchema = z28.object({
|
|
2568
|
+
id: z28.string(),
|
|
2569
|
+
accountId: z28.string(),
|
|
2570
|
+
name: z28.string(),
|
|
2571
|
+
nodeVersion: z28.string().nullable().optional(),
|
|
2572
|
+
rootDirectory: z28.string().nullable().optional(),
|
|
2573
|
+
framework: z28.string().nullable().optional(),
|
|
2574
|
+
installCommand: z28.string().nullable().optional(),
|
|
2575
|
+
buildCommand: z28.string().nullable().optional(),
|
|
2576
|
+
link: z28.object({
|
|
2577
|
+
type: z28.string(),
|
|
2578
|
+
repo: z28.string().optional(),
|
|
2579
|
+
repoId: z28.union([z28.string(), z28.number()]).optional(),
|
|
2580
|
+
org: z28.string().optional(),
|
|
2581
|
+
productionBranch: z28.string().optional()
|
|
2582
|
+
}).nullable().optional()
|
|
2583
|
+
});
|
|
2584
|
+
var exists = async (path) => access2(path).then(() => true, () => false);
|
|
2585
|
+
var fail = (code, message) => {
|
|
2586
|
+
throw new SetupFailure(code, message);
|
|
2587
|
+
};
|
|
2588
|
+
var stable = (version2, major) => new RegExp(`^${major}\\.\\d+\\.\\d+$`, "u").test(version2);
|
|
2589
|
+
async function inspectSetupLocalProject(projectDir) {
|
|
2590
|
+
const projectDirectory = await realpath(resolve(projectDir));
|
|
2591
|
+
const manifest = manifestSchema.parse(JSON.parse(await readFile8(join6(projectDirectory, "package.json"), "utf8")));
|
|
2592
|
+
const apps = (await Promise.all(["app", "src/app"].map(async (path) => await exists(join6(projectDirectory, path)) ? path : null))).filter((path) => path !== null);
|
|
2593
|
+
if (apps.length !== 1)
|
|
2594
|
+
fail("ambiguous_app_directory", "Select one Next.js App Router application with exactly one app/ or src/app/ directory.");
|
|
2595
|
+
const repositoryRoot = (await setupProcess("git", ["rev-parse", "--show-toplevel"], {
|
|
2596
|
+
cwd: projectDirectory
|
|
2597
|
+
})).trim();
|
|
2598
|
+
const tracked = await setupProcess("git", ["ls-files", "--stage", "-z"], {
|
|
2599
|
+
cwd: repositoryRoot
|
|
2600
|
+
});
|
|
2601
|
+
for (const entry of tracked.split("\0").filter(Boolean)) {
|
|
2602
|
+
if (entry.startsWith("160000 "))
|
|
2603
|
+
fail("git_submodule_conflict", "The repository contains Git submodules. Resolve the explicit deployment source boundary before setup; the CLI will not copy external repositories.");
|
|
2604
|
+
if (!entry.startsWith("120000 "))
|
|
2605
|
+
continue;
|
|
2606
|
+
const path = join6(repositoryRoot, entry.slice(entry.indexOf(" ") + 1));
|
|
2607
|
+
const target = resolve(dirname6(path), await readlink(path));
|
|
2608
|
+
const bound = relative2(repositoryRoot, target);
|
|
2609
|
+
if (bound.startsWith("..") || bound.startsWith(sep))
|
|
2610
|
+
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.");
|
|
2611
|
+
}
|
|
2612
|
+
let lockfileRoot = projectDirectory;
|
|
2613
|
+
const lockNames = [
|
|
2614
|
+
"package-lock.json",
|
|
2615
|
+
"npm-shrinkwrap.json",
|
|
2616
|
+
"pnpm-lock.yaml",
|
|
2617
|
+
"yarn.lock",
|
|
2618
|
+
"bun.lock",
|
|
2619
|
+
"bun.lockb"
|
|
2620
|
+
];
|
|
2621
|
+
let locks = [];
|
|
2622
|
+
for (; ; ) {
|
|
2623
|
+
locks = (await Promise.all(lockNames.map(async (name3) => await exists(join6(lockfileRoot, name3)) ? name3 : null))).filter((name3) => name3 !== null);
|
|
2624
|
+
if (locks.length || lockfileRoot === repositoryRoot || dirname6(lockfileRoot) === lockfileRoot)
|
|
2625
|
+
break;
|
|
2626
|
+
lockfileRoot = dirname6(lockfileRoot);
|
|
2627
|
+
}
|
|
2628
|
+
if (locks.length > 1)
|
|
2629
|
+
fail("conflicting_lockfiles", "Resolve conflicting package-manager lockfiles before setup; Siteplane does not replace them.");
|
|
2630
|
+
if (!locks.length)
|
|
2631
|
+
fail("lockfile_missing", "Install the existing application with its chosen package manager to create one canonical lockfile.");
|
|
2632
|
+
const lockName = locks[0];
|
|
2633
|
+
if (!["package-lock.json", "pnpm-lock.yaml"].includes(lockName))
|
|
2634
|
+
fail("unsupported_package_manager", "This setup supports npm 10 or pnpm 9/10 with their canonical lockfile.");
|
|
2635
|
+
const rootManifest = manifestSchema.parse(JSON.parse(await readFile8(join6(lockfileRoot, "package.json"), "utf8")));
|
|
2636
|
+
if (lockfileRoot !== projectDirectory) {
|
|
2637
|
+
const workspaceFile = join6(lockfileRoot, "pnpm-workspace.yaml");
|
|
2638
|
+
const workspace = lockName === "pnpm-lock.yaml" && await exists(workspaceFile) ? z28.object({ packages: z28.array(z28.string()) }).parse(parseYaml(await readFile8(workspaceFile, "utf8"))).packages : z28.union([
|
|
2639
|
+
z28.array(z28.string()),
|
|
2640
|
+
z28.object({ packages: z28.array(z28.string()) }).transform((value) => value.packages)
|
|
2641
|
+
]).parse(rootManifest.workspaces);
|
|
2642
|
+
const selected = relative2(lockfileRoot, projectDirectory).split(sep).join("/");
|
|
2643
|
+
if (!workspace.some((pattern) => !pattern.startsWith("!") && minimatch(selected, pattern)) || workspace.some((pattern) => pattern.startsWith("!") && minimatch(selected, pattern.slice(1))))
|
|
2644
|
+
fail("unbound_workspace_app", "The selected application is excluded from the canonical lockfile's workspace packages. Select its actual application root.");
|
|
2645
|
+
}
|
|
2646
|
+
for (let ancestor = dirname6(lockfileRoot); ancestor.startsWith(repositoryRoot + sep) || ancestor === repositoryRoot; ancestor = dirname6(ancestor)) {
|
|
2647
|
+
const ancestorLocks = await Promise.all(lockNames.map((name3) => exists(join6(ancestor, name3))));
|
|
2648
|
+
if (ancestorLocks.some(Boolean))
|
|
2649
|
+
fail("ambiguous_lockfile_root", "Both the selected package and its repository ancestors contain lockfiles. Select one canonical workspace resolution before setup.");
|
|
2650
|
+
if (ancestor === repositoryRoot)
|
|
2651
|
+
break;
|
|
2652
|
+
}
|
|
2653
|
+
const lockText = await readFile8(join6(lockfileRoot, lockName), "utf8");
|
|
2654
|
+
const npmLock = lockName === "package-lock.json" ? z28.object({
|
|
2655
|
+
lockfileVersion: z28.number(),
|
|
2656
|
+
packages: z28.record(z28.string(), z28.object({
|
|
2657
|
+
version: z28.string().optional(),
|
|
2658
|
+
peerDependencies: z28.record(z28.string(), z28.string()).optional()
|
|
2659
|
+
})).optional()
|
|
2660
|
+
}).parse(JSON.parse(lockText)) : null;
|
|
2661
|
+
async function version2(name3) {
|
|
2662
|
+
try {
|
|
2663
|
+
return (await readInstalledPackage(projectDirectory, name3)).version;
|
|
2664
|
+
} catch {
|
|
2665
|
+
const resolved = npmLock?.packages?.[`node_modules/${name3}`]?.version;
|
|
2666
|
+
if (resolved)
|
|
2667
|
+
return resolved;
|
|
2668
|
+
return fail("dependencies_not_installed", `Install the existing ${name3} dependency using the canonical lockfile before setup.`);
|
|
2669
|
+
}
|
|
2670
|
+
}
|
|
2671
|
+
const [nextVersion, reactVersion, reactDomVersion] = await Promise.all([
|
|
2672
|
+
version2("next"),
|
|
2673
|
+
version2("react"),
|
|
2674
|
+
version2("react-dom")
|
|
2675
|
+
]);
|
|
2676
|
+
if (!stable(nextVersion, 16))
|
|
2677
|
+
fail("unsupported_next_version", "Setup supports stable Next.js 16 App Router projects. Framework migration requires a separate owner decision.");
|
|
2678
|
+
if (!stable(reactVersion, 19) || reactDomVersion !== reactVersion)
|
|
2679
|
+
fail("react_version_conflict", "Use the same stable React 19/react-dom version compatible with the installed Next.js peers.");
|
|
2680
|
+
if (!stable(process.versions.node, 22))
|
|
2681
|
+
fail("unsupported_node_version", "Run setup under Node.js 22; this does not change your framework or package-manager versions.");
|
|
2682
|
+
const nextMetadata = await readInstalledPackage(projectDirectory, "next").catch(() => npmLock?.packages?.["node_modules/next"] ?? null);
|
|
2683
|
+
const peers = nextMetadata?.peerDependencies;
|
|
2684
|
+
if (!peers?.react || !peers["react-dom"])
|
|
2685
|
+
fail("next_peer_metadata_missing", "Install the locked Next.js dependency before setup so its actual React peer requirements can be checked.");
|
|
2686
|
+
if (!semver.satisfies(reactVersion, peers.react) || !semver.satisfies(reactDomVersion, peers["react-dom"]))
|
|
2687
|
+
fail("react_peer_conflict", "The installed React pair does not satisfy the installed Next.js peer requirements. Choose a compatible pair explicitly.");
|
|
2688
|
+
if (manifest.engines?.node && !semver.satisfies(process.versions.node, manifest.engines.node))
|
|
2689
|
+
fail("node_engine_conflict", "The selected application's Node engine declaration excludes the active supported Node.js 22 runtime.");
|
|
2690
|
+
const name2 = lockName === "package-lock.json" ? "npm" : "pnpm";
|
|
2691
|
+
const declared = rootManifest.packageManager ?? manifest.packageManager ?? null;
|
|
2692
|
+
if (rootManifest.packageManager && manifest.packageManager && rootManifest.packageManager !== manifest.packageManager)
|
|
2693
|
+
fail("package_manager_conflict", "Application and workspace packageManager declarations disagree.");
|
|
2694
|
+
if (declared && !new RegExp(`^${name2}@\\d+\\.\\d+\\.\\d+$`, "u").test(declared))
|
|
2695
|
+
fail("package_manager_conflict", "Declare an exact supported npm/pnpm packageManager version matching the canonical lockfile.");
|
|
2696
|
+
const localVersion = (await setupProcess(declared ? "npx" : name2, declared ? ["--yes", declared, "--version"] : ["--version"], { cwd: lockfileRoot })).trim();
|
|
2697
|
+
if (!(name2 === "npm" ? stable(localVersion, 10) : stable(localVersion, 9) || stable(localVersion, 10)))
|
|
2698
|
+
fail("unsupported_package_manager_version", "Use npm 10 or pnpm 9/10; other versions are outside the initial setup support range.");
|
|
2699
|
+
if (declared && declared !== `${name2}@${localVersion}`)
|
|
2700
|
+
fail("package_manager_conflict", "The actual local package-manager version differs from the project's exact packageManager declaration. Select the declared tool without rewriting the lockfile.");
|
|
2701
|
+
const format = npmLock ? String(npmLock.lockfileVersion) : /^lockfileVersion:\s*['"]?([\d.]+)/mu.exec(lockText)?.[1];
|
|
2702
|
+
if (name2 === "npm" && format !== "3" || name2 === "pnpm" && format !== "9.0" && format !== "9")
|
|
2703
|
+
fail("lockfile_format_conflict", "The canonical lockfile format does not match npm 10 or pnpm 9/10.");
|
|
2704
|
+
const sourceConflicts = [];
|
|
2705
|
+
for (const file of ["next.config.js", "next.config.mjs", "next.config.ts"]) {
|
|
2706
|
+
if (!await exists(join6(projectDirectory, file)))
|
|
2707
|
+
continue;
|
|
2708
|
+
const source = await readFile8(join6(projectDirectory, file), "utf8");
|
|
2709
|
+
if (/output\s*:\s*['"]export['"]/u.test(source))
|
|
2710
|
+
sourceConflicts.push("static_export");
|
|
2711
|
+
if (/\bbasePath\s*:/u.test(source))
|
|
2712
|
+
sourceConflicts.push("base_path");
|
|
2713
|
+
}
|
|
2714
|
+
if (sourceConflicts.length)
|
|
2715
|
+
fail("unsupported_server_configuration", "Resolve static export/basePath configuration explicitly; Siteplane requires its server-side admin and revalidation handlers.");
|
|
2716
|
+
for (const name3 of [
|
|
2717
|
+
"middleware.ts",
|
|
2718
|
+
"middleware.js",
|
|
2719
|
+
"proxy.ts",
|
|
2720
|
+
"proxy.js",
|
|
2721
|
+
"src/middleware.ts",
|
|
2722
|
+
"src/middleware.js",
|
|
2723
|
+
"src/proxy.ts",
|
|
2724
|
+
"src/proxy.js"
|
|
2725
|
+
]) {
|
|
2726
|
+
if (await exists(join6(projectDirectory, name3)))
|
|
2727
|
+
sourceConflicts.push(`inspect_routing:${name3}`);
|
|
2728
|
+
}
|
|
2729
|
+
async function inspectSource(directory) {
|
|
2730
|
+
for (const entry of await readdir(directory, { withFileTypes: true })) {
|
|
2731
|
+
if (entry.isSymbolicLink() || ["node_modules", ".git", ".next", ".siteplane", ".vercel"].includes(entry.name))
|
|
2732
|
+
continue;
|
|
2733
|
+
const path = join6(directory, entry.name);
|
|
2734
|
+
if (entry.isDirectory()) {
|
|
2735
|
+
await inspectSource(path);
|
|
2736
|
+
continue;
|
|
2737
|
+
}
|
|
2738
|
+
if (!/\.[cm]?[jt]sx?$/u.test(entry.name))
|
|
2739
|
+
continue;
|
|
2740
|
+
const source = await readFile8(path, "utf8");
|
|
2741
|
+
if (/from\s*["']next\/image["']/u.test(source))
|
|
2742
|
+
sourceConflicts.push(`inspect_image_policy:${relative2(projectDirectory, path)}`);
|
|
2743
|
+
if (/\b(?:Cookiebot|OneTrust|cookieyes|consentManager|cookieConsent)\b/iu.test(source))
|
|
2744
|
+
sourceConflicts.push(`inspect_existing_consent:${relative2(projectDirectory, path)}`);
|
|
2745
|
+
if (/from\s*["']next\/image["']/u.test(source) && semver.lt(nextVersion, "16.3.3"))
|
|
2746
|
+
fail("next_security_advisory", `Next.js ${nextVersion} uses image optimization affected by the August 2026 AVIF advisory. Review https://nextjs.org/blog/august-2026-security-release and explicitly update the affected dependency before setup; no framework upgrade was performed.`);
|
|
2747
|
+
if (/["']use server["']/u.test(source) && semver.lt(nextVersion, "16.2.11"))
|
|
2748
|
+
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.`);
|
|
2749
|
+
}
|
|
2750
|
+
}
|
|
2751
|
+
await inspectSource(join6(projectDirectory, apps[0]));
|
|
2752
|
+
const gitRead = async (args) => setupProcess("git", args, { cwd: projectDirectory }).then((value) => value.trim(), () => null);
|
|
2753
|
+
return {
|
|
2754
|
+
projectDirectory,
|
|
2755
|
+
repositoryRoot,
|
|
2756
|
+
lockfileRoot,
|
|
2757
|
+
appDirectory: apps[0],
|
|
2758
|
+
nextVersion,
|
|
2759
|
+
reactVersion,
|
|
2760
|
+
nodeVersion: process.versions.node,
|
|
2761
|
+
packageManager: { name: name2, version: localVersion, declared },
|
|
2762
|
+
lockfile: {
|
|
2763
|
+
path: relative2(repositoryRoot, join6(lockfileRoot, lockName)),
|
|
2764
|
+
format,
|
|
2765
|
+
sha256: createHash2("sha256").update(lockText).digest("hex")
|
|
2766
|
+
},
|
|
2767
|
+
git: {
|
|
2768
|
+
branch: await gitRead(["branch", "--show-current"]),
|
|
2769
|
+
revision: await gitRead(["rev-parse", "HEAD"]),
|
|
2770
|
+
remote: safeGitRemote(await gitRead(["remote", "get-url", "origin"])),
|
|
2771
|
+
changes: (await gitRead(["status", "--porcelain=v1", "--untracked-files=all"]))?.split("\n").filter(Boolean) ?? []
|
|
2772
|
+
},
|
|
2773
|
+
sourceConflicts
|
|
2774
|
+
};
|
|
2775
|
+
}
|
|
2776
|
+
async function setupPreflightCommand(input) {
|
|
2777
|
+
let local;
|
|
2778
|
+
try {
|
|
2779
|
+
local = await inspectSetupLocalProject(input.projectDir);
|
|
2780
|
+
await assertLocalCredentialsPathSafe(input.projectDir);
|
|
2781
|
+
let linkDirectory = local.projectDirectory;
|
|
2782
|
+
while (!await exists(join6(linkDirectory, ".vercel/project.json")) && linkDirectory !== local.repositoryRoot && dirname6(linkDirectory) !== linkDirectory)
|
|
2783
|
+
linkDirectory = dirname6(linkDirectory);
|
|
2784
|
+
if (!await exists(join6(linkDirectory, ".vercel/project.json")))
|
|
2785
|
+
fail("vercel_project_not_linked", "Link this application to its intended Vercel project before setup; Siteplane will not guess a target.");
|
|
2786
|
+
const linked = z28.object({
|
|
2787
|
+
projectId: z28.string().regex(/^prj_[A-Za-z0-9]+$/u),
|
|
2788
|
+
orgId: z28.string().regex(/^(?:team|user)_[A-Za-z0-9]+$/u)
|
|
2789
|
+
}).parse(JSON.parse(await readFile8(join6(linkDirectory, ".vercel/project.json"), "utf8")));
|
|
2790
|
+
const project = vercelProjectSchema.parse(await setupVercelApi(linkDirectory, `/v9/projects/${linked.projectId}?teamId=${linked.orgId}`));
|
|
2791
|
+
if (project.id !== linked.projectId || project.accountId !== linked.orgId)
|
|
2792
|
+
fail("vercel_identity_conflict", "The provider project does not match the locally linked project and team.");
|
|
2793
|
+
const expectedRoot = relative2(local.repositoryRoot, local.projectDirectory).split(sep).join("/");
|
|
2794
|
+
if ((project.rootDirectory ?? "") !== expectedRoot)
|
|
2795
|
+
fail("vercel_root_conflict", "Vercel Root Directory and the selected local app must identify the same application.");
|
|
2796
|
+
if (project.nodeVersion !== "22.x" || project.framework !== "nextjs")
|
|
2797
|
+
fail("vercel_framework_conflict", "The bound Vercel project must use Next.js with Node.js 22 before setup.");
|
|
2798
|
+
if (project.link && project.link.productionBranch !== local.git.branch)
|
|
2799
|
+
fail("vercel_production_branch_conflict", "The local branch differs from the bound Vercel Production branch.");
|
|
2800
|
+
if (project.link?.repo && project.link.org && !local.git.remote?.replace(/\.git$/u, "").endsWith(`${project.link.org}/${project.link.repo}`))
|
|
2801
|
+
fail("vercel_git_conflict", "The local origin repository differs from the Vercel Git connection.");
|
|
2802
|
+
const env = z28.object({
|
|
2803
|
+
envs: z28.array(z28.object({
|
|
2804
|
+
key: z28.string(),
|
|
2805
|
+
value: z28.string().optional(),
|
|
2806
|
+
target: z28.array(z28.string()).optional()
|
|
2807
|
+
}))
|
|
2808
|
+
}).parse(await setupVercelApi(linkDirectory, `/v10/projects/${linked.projectId}/env?teamId=${linked.orgId}`));
|
|
2809
|
+
const corepack = env.envs.some((item) => item.key === "ENABLE_EXPERIMENTAL_COREPACK" && item.value === "1" && item.target?.includes("production"));
|
|
2810
|
+
const install = project.installCommand ?? null;
|
|
2811
|
+
const selected = corepack ? "corepack" : install ? "install_override" : "automatic";
|
|
2812
|
+
if (local.packageManager.declared && selected === "automatic")
|
|
2813
|
+
fail("vercel_package_manager_pin_unconfirmed", "This project declares an exact packageManager but Vercel automatic selection does not bind that version. Enable its supported Corepack selection or set an exact install AND build override in the existing project, then rerun preflight. No package, lockfile or provider setting was changed.");
|
|
2814
|
+
if (install && /\b(?:yarn|bun)\b/u.test(install))
|
|
2815
|
+
fail("vercel_package_manager_conflict", "The Vercel install override selects an unsupported package manager.");
|
|
2816
|
+
const overridePin = install ? /\b(npm|pnpm)@(\d+\.\d+\.\d+)\b/u.exec(install) : null;
|
|
2817
|
+
if (overridePin && overridePin[1] !== local.packageManager.name)
|
|
2818
|
+
fail("vercel_package_manager_conflict", "The provider override selects a different package manager than the canonical lockfile.");
|
|
2819
|
+
const overrideFamily = install ? /(?:^|[;&|]\s*)(npm|pnpm)\s+(?:ci|install)\b/u.exec(install)?.[1] : null;
|
|
2820
|
+
if (overrideFamily && overrideFamily !== local.packageManager.name)
|
|
2821
|
+
fail("vercel_package_manager_conflict", "The provider install command conflicts with the canonical lockfile.");
|
|
2822
|
+
if (overridePin && local.packageManager.declared && `${overridePin[1]}@${overridePin[2]}` !== local.packageManager.declared)
|
|
2823
|
+
fail("vercel_package_manager_conflict", "The Vercel install override conflicts with the exact packageManager declaration.");
|
|
2824
|
+
return {
|
|
2825
|
+
status: "ready",
|
|
2826
|
+
local,
|
|
2827
|
+
provider: {
|
|
2828
|
+
projectId: project.id,
|
|
2829
|
+
teamId: project.accountId,
|
|
2830
|
+
name: project.name,
|
|
2831
|
+
rootDirectory: expectedRoot,
|
|
2832
|
+
nodeVersion: project.nodeVersion,
|
|
2833
|
+
git: project.link,
|
|
2834
|
+
installCommand: install,
|
|
2835
|
+
buildCommand: project.buildCommand ?? null,
|
|
2836
|
+
packageManagerSelection: selected,
|
|
2837
|
+
declaredPackageManager: local.packageManager.declared,
|
|
2838
|
+
observedPackageManager: null
|
|
2839
|
+
}
|
|
2840
|
+
};
|
|
2841
|
+
} catch (error) {
|
|
2842
|
+
return {
|
|
2843
|
+
status: "action_required",
|
|
2844
|
+
code: error instanceof SetupFailure ? error.code : "invalid_local_project",
|
|
2845
|
+
message: error instanceof SetupFailure ? error.message : "The selected project or provider response could not be validated. Check the application manifest and local project access.",
|
|
2846
|
+
...local ? { local } : {}
|
|
2847
|
+
};
|
|
2848
|
+
}
|
|
2849
|
+
}
|
|
2850
|
+
function safeGitRemote(value) {
|
|
2851
|
+
if (!value)
|
|
2852
|
+
return null;
|
|
2853
|
+
if (!value.includes("://"))
|
|
2854
|
+
return value;
|
|
2855
|
+
try {
|
|
2856
|
+
const url = new URL(value);
|
|
2857
|
+
url.username = "";
|
|
2858
|
+
url.password = "";
|
|
2859
|
+
url.search = "";
|
|
2860
|
+
url.hash = "";
|
|
2861
|
+
return url.toString().replace(/\/$/u, "");
|
|
2862
|
+
} catch {
|
|
2863
|
+
return null;
|
|
2864
|
+
}
|
|
2865
|
+
}
|
|
2866
|
+
|
|
2867
|
+
// ../cli/dist/commands/init.js
|
|
2332
2868
|
async function initCommand(input) {
|
|
2333
2869
|
if (!input.setupToken.trim()) {
|
|
2334
2870
|
throw new Error("A Siteplane setup token is required.");
|
|
@@ -2336,47 +2872,64 @@ async function initCommand(input) {
|
|
|
2336
2872
|
if (!await detectNextProject(input.projectDir)) {
|
|
2337
2873
|
throw new Error("Siteplane init currently supports Next.js projects.");
|
|
2338
2874
|
}
|
|
2875
|
+
await assertLocalCredentialsPathSafe(input.projectDir, {
|
|
2876
|
+
...input.isIgnoredFile ? { isIgnoredFile: input.isIgnoredFile } : {},
|
|
2877
|
+
...input.isTrackedFile ? { isTrackedFile: input.isTrackedFile } : {}
|
|
2878
|
+
});
|
|
2879
|
+
const preflight = await (input.preflight ?? setupPreflightCommand)({
|
|
2880
|
+
projectDir: input.projectDir
|
|
2881
|
+
});
|
|
2882
|
+
if (preflight.status !== "ready")
|
|
2883
|
+
throw new Error(`${preflight.code}: ${preflight.message}`);
|
|
2339
2884
|
const bootstrap = await bootstrapProjectConnection(input);
|
|
2340
|
-
const paths = bootstrap.credentialPurpose === "site_setup" ? await persistSiteSetupBootstrap(input, bootstrap) : await persistFeatureBootstrap(input, bootstrap);
|
|
2885
|
+
const paths = bootstrap.credentialPurpose === "site_setup" ? await persistSiteSetupBootstrap(input, bootstrap, relative3(preflight.local.lockfileRoot, preflight.local.projectDirectory) || ".") : await persistFeatureBootstrap(input, bootstrap);
|
|
2341
2886
|
await acknowledgeBootstrapResponse(input);
|
|
2342
2887
|
return {
|
|
2343
2888
|
...paths,
|
|
2344
2889
|
nextSteps: [
|
|
2345
2890
|
"Run npx siteplane setup context and read the returned task.",
|
|
2346
2891
|
"Before source changes, briefly tell the user what Siteplane requested and what you will do.",
|
|
2347
|
-
"Follow the returned steps through setup
|
|
2892
|
+
"Follow the returned steps through setup prepare and setup deploy --wait, which performs setup verify; stop only at ready_for_review or action_required."
|
|
2348
2893
|
]
|
|
2349
2894
|
};
|
|
2350
2895
|
}
|
|
2351
|
-
var siteSetupBootstrapDataSchema =
|
|
2352
|
-
credentialPurpose:
|
|
2353
|
-
apiBaseUrl:
|
|
2354
|
-
siteId:
|
|
2355
|
-
publicSiteKeyId:
|
|
2356
|
-
publicSiteKey:
|
|
2357
|
-
accessToken:
|
|
2358
|
-
siteRevalidationSecret:
|
|
2896
|
+
var siteSetupBootstrapDataSchema = z29.object({
|
|
2897
|
+
credentialPurpose: z29.literal("site_setup"),
|
|
2898
|
+
apiBaseUrl: z29.string().url(),
|
|
2899
|
+
siteId: z29.string().uuid(),
|
|
2900
|
+
publicSiteKeyId: z29.string().uuid(),
|
|
2901
|
+
publicSiteKey: z29.string().trim().min(1),
|
|
2902
|
+
accessToken: z29.string().trim().min(1),
|
|
2903
|
+
siteRevalidationSecret: z29.string().regex(/^[A-Za-z0-9_-]{43}$/u),
|
|
2904
|
+
runId: z29.string().uuid(),
|
|
2905
|
+
packages: z29.object({
|
|
2906
|
+
siteplane: z29.string().regex(/^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$/u),
|
|
2907
|
+
runtimeNext: z29.string().regex(/^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$/u)
|
|
2908
|
+
}).strict()
|
|
2359
2909
|
}).strict();
|
|
2360
|
-
var featureBootstrapDataSchema =
|
|
2361
|
-
credentialPurpose:
|
|
2362
|
-
apiBaseUrl:
|
|
2363
|
-
siteId:
|
|
2364
|
-
accessToken:
|
|
2910
|
+
var featureBootstrapDataSchema = z29.object({
|
|
2911
|
+
credentialPurpose: z29.enum(["analytics", "booking"]),
|
|
2912
|
+
apiBaseUrl: z29.string().url(),
|
|
2913
|
+
siteId: z29.string().uuid(),
|
|
2914
|
+
accessToken: z29.string().trim().min(1)
|
|
2365
2915
|
}).strict();
|
|
2366
|
-
var bootstrapResponseSchema =
|
|
2367
|
-
ok:
|
|
2368
|
-
data:
|
|
2916
|
+
var bootstrapResponseSchema = z29.object({
|
|
2917
|
+
ok: z29.literal(true),
|
|
2918
|
+
data: z29.discriminatedUnion("credentialPurpose", [
|
|
2369
2919
|
siteSetupBootstrapDataSchema,
|
|
2370
2920
|
featureBootstrapDataSchema
|
|
2371
2921
|
])
|
|
2372
2922
|
}).strict();
|
|
2373
2923
|
async function bootstrapProjectConnection(input) {
|
|
2374
2924
|
const fetcher = input.fetcher ?? fetch;
|
|
2925
|
+
const existing = await access3(join7(input.projectDir, "siteplane.config.json")).then(() => readProjectConfig(input.projectDir), () => null);
|
|
2375
2926
|
const response = await fetcher(`${input.apiBaseUrl.replace(/\/$/, "")}/api/cli/setup/bootstrap`, {
|
|
2376
2927
|
method: "POST",
|
|
2928
|
+
signal: AbortSignal.timeout(2e4),
|
|
2377
2929
|
headers: createBootstrapHeaders(input),
|
|
2378
2930
|
body: JSON.stringify({
|
|
2379
2931
|
action: "bootstrap",
|
|
2932
|
+
...existing ? { expectedSiteId: existing.siteId, expectedRunId: existing.runId } : {},
|
|
2380
2933
|
agentClient: input.agentClient ?? "codex"
|
|
2381
2934
|
})
|
|
2382
2935
|
});
|
|
@@ -2391,6 +2944,7 @@ async function acknowledgeBootstrapResponse(input) {
|
|
|
2391
2944
|
const fetcher = input.fetcher ?? fetch;
|
|
2392
2945
|
const response = await fetcher(`${input.apiBaseUrl.replace(/\/$/, "")}/api/cli/setup/bootstrap`, {
|
|
2393
2946
|
method: "POST",
|
|
2947
|
+
signal: AbortSignal.timeout(2e4),
|
|
2394
2948
|
headers: createBootstrapHeaders(input),
|
|
2395
2949
|
body: JSON.stringify({ action: "acknowledge" })
|
|
2396
2950
|
});
|
|
@@ -2398,8 +2952,13 @@ async function acknowledgeBootstrapResponse(input) {
|
|
|
2398
2952
|
throw new Error("Siteplane setup acknowledgement failed.");
|
|
2399
2953
|
}
|
|
2400
2954
|
}
|
|
2401
|
-
async function persistSiteSetupBootstrap(input, bootstrap) {
|
|
2955
|
+
async function persistSiteSetupBootstrap(input, bootstrap, appDirectory) {
|
|
2956
|
+
const previous = await access3(join7(input.projectDir, "siteplane.config.json")).then(() => readProjectConfig(input.projectDir), () => null);
|
|
2957
|
+
if (previous && (previous.siteId !== bootstrap.siteId || previous.runId !== bootstrap.runId || previous.publicSiteKeyId !== bootstrap.publicSiteKeyId || previous.publicSiteKey !== bootstrap.publicSiteKey))
|
|
2958
|
+
throw new Error("The grant does not match this local Siteplane run. Preserve this directory and choose the correct owner connection.");
|
|
2959
|
+
const previousCredentials = previous ? await access3(join7(input.projectDir, ".siteplane/credentials.json")).then(() => readLocalCredentials(input.projectDir), () => null) : null;
|
|
2402
2960
|
const credentialsPath = await writeLocalCredentials(input.projectDir, {
|
|
2961
|
+
...previousCredentials?.adminSession ? { adminSession: previousCredentials.adminSession } : {},
|
|
2403
2962
|
accessToken: bootstrap.accessToken,
|
|
2404
2963
|
siteRevalidationSecret: bootstrap.siteRevalidationSecret
|
|
2405
2964
|
}, {
|
|
@@ -2407,7 +2966,13 @@ async function persistSiteSetupBootstrap(input, bootstrap) {
|
|
|
2407
2966
|
...input.isTrackedFile ? { isTrackedFile: input.isTrackedFile } : {}
|
|
2408
2967
|
});
|
|
2409
2968
|
const configPath = await writeProjectConfig(input.projectDir, {
|
|
2410
|
-
|
|
2969
|
+
...previous ?? {},
|
|
2970
|
+
version: 2,
|
|
2971
|
+
appDirectory,
|
|
2972
|
+
runId: bootstrap.runId,
|
|
2973
|
+
packages: bootstrap.packages,
|
|
2974
|
+
taskContractVersion: "siteplane.setup-task.v2",
|
|
2975
|
+
adminProtocolVersion: 2,
|
|
2411
2976
|
apiBaseUrl: bootstrap.apiBaseUrl,
|
|
2412
2977
|
siteId: bootstrap.siteId,
|
|
2413
2978
|
publicSiteKeyId: bootstrap.publicSiteKeyId,
|
|
@@ -2417,7 +2982,7 @@ async function persistSiteSetupBootstrap(input, bootstrap) {
|
|
|
2417
2982
|
readLocalCredentials(input.projectDir),
|
|
2418
2983
|
readProjectConfig(input.projectDir)
|
|
2419
2984
|
]);
|
|
2420
|
-
if (credentials.accessToken !== bootstrap.accessToken || credentials.siteRevalidationSecret !== bootstrap.siteRevalidationSecret || config.apiBaseUrl !== bootstrap.apiBaseUrl || config.siteId !== bootstrap.siteId || config.publicSiteKeyId !== bootstrap.publicSiteKeyId || config.publicSiteKey !== bootstrap.publicSiteKey) {
|
|
2985
|
+
if (credentials.accessToken !== bootstrap.accessToken || credentials.siteRevalidationSecret !== bootstrap.siteRevalidationSecret || config.runId !== bootstrap.runId || config.packages.siteplane !== bootstrap.packages.siteplane || config.packages.runtimeNext !== bootstrap.packages.runtimeNext || config.apiBaseUrl !== bootstrap.apiBaseUrl || config.siteId !== bootstrap.siteId || config.publicSiteKeyId !== bootstrap.publicSiteKeyId || config.publicSiteKey !== bootstrap.publicSiteKey) {
|
|
2421
2986
|
throw new Error("Siteplane setup files could not be verified.");
|
|
2422
2987
|
}
|
|
2423
2988
|
return { configPath, credentialsPath };
|
|
@@ -2431,8 +2996,8 @@ async function persistFeatureBootstrap(input, bootstrap) {
|
|
|
2431
2996
|
throw new Error("The setup token belongs to a different Siteplane site.");
|
|
2432
2997
|
}
|
|
2433
2998
|
const credentialsPath = await writeLocalCredentials(input.projectDir, {
|
|
2434
|
-
|
|
2435
|
-
|
|
2999
|
+
...existingCredentials,
|
|
3000
|
+
accessToken: bootstrap.accessToken
|
|
2436
3001
|
}, {
|
|
2437
3002
|
...input.isIgnoredFile ? { isIgnoredFile: input.isIgnoredFile } : {},
|
|
2438
3003
|
...input.isTrackedFile ? { isTrackedFile: input.isTrackedFile } : {}
|
|
@@ -2442,7 +3007,7 @@ async function persistFeatureBootstrap(input, bootstrap) {
|
|
|
2442
3007
|
throw new Error("Siteplane credentials could not be verified.");
|
|
2443
3008
|
}
|
|
2444
3009
|
return {
|
|
2445
|
-
configPath:
|
|
3010
|
+
configPath: join7(input.projectDir, "siteplane.config.json"),
|
|
2446
3011
|
credentialsPath
|
|
2447
3012
|
};
|
|
2448
3013
|
}
|
|
@@ -2464,47 +3029,303 @@ function readErrorMessage(payload) {
|
|
|
2464
3029
|
}
|
|
2465
3030
|
|
|
2466
3031
|
// ../cli/dist/commands/scan.js
|
|
2467
|
-
import { readdir } from "fs/promises";
|
|
2468
|
-
import { extname, join as
|
|
3032
|
+
import { readdir as readdir2 } from "fs/promises";
|
|
3033
|
+
import { extname, join as join8 } from "path";
|
|
3034
|
+
var defaultScanRoots = ["app", "src", "pages", "components", "lib"];
|
|
3035
|
+
var excludedDirectories = /* @__PURE__ */ new Set([
|
|
3036
|
+
".git",
|
|
3037
|
+
".next",
|
|
3038
|
+
".turbo",
|
|
3039
|
+
".vercel",
|
|
3040
|
+
"build",
|
|
3041
|
+
"coverage",
|
|
3042
|
+
"dist",
|
|
3043
|
+
"node_modules"
|
|
3044
|
+
]);
|
|
3045
|
+
var sourceExtensions = /* @__PURE__ */ new Set([".js", ".jsx", ".ts", ".tsx"]);
|
|
3046
|
+
async function resolveScanFilePaths(filePaths, options = {}) {
|
|
3047
|
+
if (filePaths.length > 0) {
|
|
3048
|
+
return filePaths;
|
|
3049
|
+
}
|
|
3050
|
+
const projectDir = options.projectDir ?? process.cwd();
|
|
3051
|
+
const discovered = await Promise.all(defaultScanRoots.map((root) => collectSourceFiles(join8(projectDir, root))));
|
|
3052
|
+
return [...new Set(discovered.flat())].sort();
|
|
3053
|
+
}
|
|
3054
|
+
async function collectSourceFiles(directory) {
|
|
3055
|
+
const entries = await readdir2(directory, { withFileTypes: true }).catch(() => []);
|
|
3056
|
+
const files = [];
|
|
3057
|
+
for (const entry of entries) {
|
|
3058
|
+
const entryPath = join8(directory, entry.name);
|
|
3059
|
+
if (entry.isDirectory()) {
|
|
3060
|
+
if (!excludedDirectories.has(entry.name)) {
|
|
3061
|
+
files.push(...await collectSourceFiles(entryPath));
|
|
3062
|
+
}
|
|
3063
|
+
continue;
|
|
3064
|
+
}
|
|
3065
|
+
if (entry.isFile() && sourceExtensions.has(extname(entry.name))) {
|
|
3066
|
+
files.push(entryPath);
|
|
3067
|
+
}
|
|
3068
|
+
}
|
|
3069
|
+
return files;
|
|
3070
|
+
}
|
|
2469
3071
|
|
|
2470
3072
|
// ../cli/dist/commands/site-setup.js
|
|
2471
3073
|
import { execFile as execFile2 } from "child_process";
|
|
2472
|
-
import { readFile as
|
|
3074
|
+
import { readFile as readFile9 } from "fs/promises";
|
|
2473
3075
|
import { promisify as promisify2 } from "util";
|
|
2474
|
-
import { z as
|
|
3076
|
+
import { z as z30 } from "zod";
|
|
2475
3077
|
|
|
2476
3078
|
// ../cli/dist/scan/next-source-scan.js
|
|
2477
3079
|
import ts2 from "typescript";
|
|
2478
|
-
import { isAbsolute, relative as
|
|
3080
|
+
import { isAbsolute, relative as relative4 } from "path";
|
|
2479
3081
|
var legacyEditableComponentPrefix = "Editable";
|
|
2480
|
-
var editableComponentNames = new Set(["Image", "Text", "LongText", "Link"].map((
|
|
3082
|
+
var editableComponentNames = new Set(["Image", "Text", "LongText", "Link"].map((name2) => `${legacyEditableComponentPrefix}${name2}`));
|
|
2481
3083
|
|
|
2482
3084
|
// ../cli/dist/commands/site-setup.js
|
|
2483
3085
|
var execFileAsync2 = promisify2(execFile2);
|
|
2484
|
-
var safeErrorSchema =
|
|
2485
|
-
code:
|
|
2486
|
-
message:
|
|
3086
|
+
var safeErrorSchema = z30.object({
|
|
3087
|
+
code: z30.string().trim().min(1),
|
|
3088
|
+
message: z30.string().trim().min(1)
|
|
2487
3089
|
}).passthrough();
|
|
2488
|
-
var errorResponseSchema2 =
|
|
2489
|
-
var contextDataSchema =
|
|
2490
|
-
var contextResponseSchema =
|
|
2491
|
-
var applyDataSchema =
|
|
2492
|
-
status:
|
|
2493
|
-
runId:
|
|
2494
|
-
contractVersionId:
|
|
2495
|
-
fieldContractHash:
|
|
2496
|
-
editorDefinitionHash:
|
|
2497
|
-
fieldCount:
|
|
2498
|
-
routeCount:
|
|
3090
|
+
var errorResponseSchema2 = z30.object({ ok: z30.literal(false), error: safeErrorSchema }).passthrough();
|
|
3091
|
+
var contextDataSchema = z30.object({ task: siteSetupTaskSchema }).strict();
|
|
3092
|
+
var contextResponseSchema = z30.object({ ok: z30.literal(true), data: contextDataSchema }).strict();
|
|
3093
|
+
var applyDataSchema = z30.object({
|
|
3094
|
+
status: z30.enum(["applied", "ready_for_review"]),
|
|
3095
|
+
runId: z30.string().uuid().optional(),
|
|
3096
|
+
contractVersionId: z30.string().uuid().optional(),
|
|
3097
|
+
fieldContractHash: z30.string().regex(/^sha256:[0-9a-f]{64}$/u),
|
|
3098
|
+
editorDefinitionHash: z30.string().regex(/^sha256:[0-9a-f]{64}$/u).optional(),
|
|
3099
|
+
fieldCount: z30.number().int().nonnegative().optional(),
|
|
3100
|
+
routeCount: z30.number().int().nonnegative().optional()
|
|
2499
3101
|
}).strict();
|
|
2500
|
-
var applyResponseSchema =
|
|
2501
|
-
var verifyDataSchema =
|
|
2502
|
-
status:
|
|
2503
|
-
runId:
|
|
2504
|
-
deploymentOrigin:
|
|
2505
|
-
deploymentRevision:
|
|
3102
|
+
var applyResponseSchema = z30.object({ ok: z30.literal(true), data: applyDataSchema }).strict();
|
|
3103
|
+
var verifyDataSchema = z30.object({
|
|
3104
|
+
status: z30.literal("ready_for_review"),
|
|
3105
|
+
runId: z30.string().uuid().optional(),
|
|
3106
|
+
deploymentOrigin: z30.string().url().optional(),
|
|
3107
|
+
deploymentRevision: z30.string().optional()
|
|
2506
3108
|
}).strict();
|
|
2507
|
-
var verifyResponseSchema =
|
|
3109
|
+
var verifyResponseSchema = z30.object({ ok: z30.literal(true), data: verifyDataSchema }).strict();
|
|
3110
|
+
async function siteSetupContextCommand(input) {
|
|
3111
|
+
const response = await postSiteSetup(input, "context", {});
|
|
3112
|
+
const parsed = contextResponseSchema.safeParse(response.payload);
|
|
3113
|
+
if (response.ok && parsed.success) {
|
|
3114
|
+
return { status: "ok", ...parsed.data.data };
|
|
3115
|
+
}
|
|
3116
|
+
return actionRequired(response.payload, "Siteplane setup context is unavailable.");
|
|
3117
|
+
}
|
|
3118
|
+
async function siteSetupVerifyCommand(input) {
|
|
3119
|
+
const resolveSourceFiles = input.resolveSourceFiles ?? resolveScanFilePaths;
|
|
3120
|
+
const readSourceFile = input.readSourceFile ?? ((path) => readFile9(path, "utf8"));
|
|
3121
|
+
const paths = await resolveSourceFiles([], { projectDir: input.projectDir });
|
|
3122
|
+
const sources = await Promise.all(paths.map(readSourceFile));
|
|
3123
|
+
if (!sources.some(hasMountedFieldRuntimeBridge)) {
|
|
3124
|
+
return {
|
|
3125
|
+
status: "action_required",
|
|
3126
|
+
code: "missing_field_runtime_bridge",
|
|
3127
|
+
message: "Mount FieldRuntimeBridge from @siteplane/runtime-next/client before deployment verification."
|
|
3128
|
+
};
|
|
3129
|
+
}
|
|
3130
|
+
const deploymentRevision = await (input.readRevision ?? readGitRevision)(input.projectDir);
|
|
3131
|
+
const response = await postSiteSetup(input, "verify", {
|
|
3132
|
+
deploymentUrl: input.deploymentUrl,
|
|
3133
|
+
deploymentRevision,
|
|
3134
|
+
...input.wait ? { wait: true } : {}
|
|
3135
|
+
});
|
|
3136
|
+
const parsed = verifyResponseSchema.safeParse(response.payload);
|
|
3137
|
+
if (response.ok && parsed.success) {
|
|
3138
|
+
return parsed.data.data;
|
|
3139
|
+
}
|
|
3140
|
+
return actionRequired(response.payload, "Siteplane deployment verification failed.");
|
|
3141
|
+
}
|
|
3142
|
+
function hasMountedFieldRuntimeBridge(source) {
|
|
3143
|
+
return /from\s+["']@siteplane\/runtime-next(?:\/client)?["']/u.test(source) && /<FieldRuntimeBridge(?:\s|\/|>)/u.test(source);
|
|
3144
|
+
}
|
|
3145
|
+
async function postSiteSetup(input, operation, body) {
|
|
3146
|
+
const [config, credentials] = await Promise.all([
|
|
3147
|
+
readProjectConfig(input.projectDir),
|
|
3148
|
+
readLocalCredentials(input.projectDir)
|
|
3149
|
+
]);
|
|
3150
|
+
try {
|
|
3151
|
+
const response = await (input.fetcher ?? fetch)(`${config.apiBaseUrl.replace(/\/$/u, "")}/api/cli/setup/${operation}`, {
|
|
3152
|
+
method: "POST",
|
|
3153
|
+
signal: AbortSignal.timeout(Math.max(1, Math.min(2e4, (input.deadline ?? Date.now() + 2e4) - Date.now()))),
|
|
3154
|
+
headers: {
|
|
3155
|
+
authorization: `Bearer ${credentials.accessToken}`,
|
|
3156
|
+
"content-type": "application/json",
|
|
3157
|
+
...input.vercelAutomationBypassSecret?.trim() ? {
|
|
3158
|
+
"x-vercel-protection-bypass": input.vercelAutomationBypassSecret.trim()
|
|
3159
|
+
} : {}
|
|
3160
|
+
},
|
|
3161
|
+
body: JSON.stringify(body)
|
|
3162
|
+
});
|
|
3163
|
+
const payload = await response.json().catch(() => null);
|
|
3164
|
+
return { ok: response.ok, payload };
|
|
3165
|
+
} catch {
|
|
3166
|
+
return {
|
|
3167
|
+
ok: false,
|
|
3168
|
+
payload: {
|
|
3169
|
+
ok: false,
|
|
3170
|
+
error: {
|
|
3171
|
+
code: "site_setup.transport_failed",
|
|
3172
|
+
message: "The setup request was not acknowledged. Reload the existing task before retrying; no credential values are included."
|
|
3173
|
+
}
|
|
3174
|
+
}
|
|
3175
|
+
};
|
|
3176
|
+
}
|
|
3177
|
+
}
|
|
3178
|
+
function actionRequired(payload, fallbackMessage) {
|
|
3179
|
+
const parsed = errorResponseSchema2.safeParse(payload);
|
|
3180
|
+
return parsed.success ? {
|
|
3181
|
+
status: "action_required",
|
|
3182
|
+
code: parsed.data.error.code,
|
|
3183
|
+
message: parsed.data.error.message
|
|
3184
|
+
} : {
|
|
3185
|
+
status: "action_required",
|
|
3186
|
+
code: "invalid_server_response",
|
|
3187
|
+
message: fallbackMessage
|
|
3188
|
+
};
|
|
3189
|
+
}
|
|
3190
|
+
async function readGitRevision(projectDir) {
|
|
3191
|
+
const { stdout } = await execFileAsync2("git", ["rev-parse", "HEAD"], {
|
|
3192
|
+
cwd: projectDir,
|
|
3193
|
+
encoding: "utf8"
|
|
3194
|
+
});
|
|
3195
|
+
const revision = stdout.trim();
|
|
3196
|
+
if (!revision) {
|
|
3197
|
+
throw new Error("A committed Git revision is required before setup verify.");
|
|
3198
|
+
}
|
|
3199
|
+
return revision;
|
|
3200
|
+
}
|
|
3201
|
+
|
|
3202
|
+
// ../cli/dist/commands/setup-prepare.js
|
|
3203
|
+
import { access as access4, lstat as lstat2, mkdir as mkdir6, open as open3, readFile as readFile10, rename as rename3, rm as rm3 } from "fs/promises";
|
|
3204
|
+
import { randomUUID as randomUUID4 } from "crypto";
|
|
3205
|
+
import { dirname as dirname7, join as join9, relative as relative5, sep as sep2 } from "path";
|
|
3206
|
+
import ts3 from "typescript";
|
|
3207
|
+
|
|
3208
|
+
// ../cli/dist/commands/setup-lock.js
|
|
3209
|
+
import { randomUUID as randomUUID5 } from "crypto";
|
|
3210
|
+
import { lstat as lstat3, mkdir as mkdir7, open as open4, readFile as readFile11, rm as rm4, rmdir } from "fs/promises";
|
|
3211
|
+
import { resolve as resolve2 } from "path";
|
|
3212
|
+
import { z as z31 } from "zod";
|
|
3213
|
+
var ownerSchema = z31.object({ pid: z31.number().int().positive(), nonce: z31.string().uuid() }).strict();
|
|
3214
|
+
|
|
3215
|
+
// ../cli/dist/config/build-provenance.js
|
|
3216
|
+
import { createHash as createHash3 } from "crypto";
|
|
3217
|
+
import { execFile as execFile3 } from "child_process";
|
|
3218
|
+
import { lstat as lstat4, readFile as readFile12, writeFile as writeFile5, mkdir as mkdir8 } from "fs/promises";
|
|
3219
|
+
import { dirname as dirname8, isAbsolute as isAbsolute2, join as join10, relative as relative6, resolve as resolve3, sep as sep3 } from "path";
|
|
3220
|
+
import { isDeepStrictEqual, promisify as promisify3 } from "util";
|
|
3221
|
+
import { z as z32 } from "zod";
|
|
3222
|
+
var execute = promisify3(execFile3);
|
|
3223
|
+
var name = ".siteplane/build-source.json";
|
|
3224
|
+
var oid = z32.string().regex(/^[0-9a-f]{40}$/u);
|
|
3225
|
+
var entrySchema = z32.object({
|
|
3226
|
+
path: z32.string().min(1).max(4096),
|
|
3227
|
+
mode: z32.enum(["100644", "100755", "120000"]),
|
|
3228
|
+
oid
|
|
3229
|
+
}).strict();
|
|
3230
|
+
var schema = z32.object({
|
|
3231
|
+
version: z32.literal(2),
|
|
3232
|
+
revision: oid,
|
|
3233
|
+
commit: z32.string().min(1).max(1048576),
|
|
3234
|
+
entries: z32.array(entrySchema).min(1).max(1e5),
|
|
3235
|
+
providerConfigurations: z32.array(z32.object({
|
|
3236
|
+
path: z32.string().max(4096).regex(/(?:^|\/)vercel\.json$/u),
|
|
3237
|
+
source: z32.string().max(1048576)
|
|
3238
|
+
}).strict()).max(1e3)
|
|
3239
|
+
}).strict();
|
|
3240
|
+
async function writeBuildProvenance(checkout, revision) {
|
|
3241
|
+
const commit = (await execute("git", ["cat-file", "commit", revision], {
|
|
3242
|
+
cwd: checkout,
|
|
3243
|
+
maxBuffer: 1048576
|
|
3244
|
+
})).stdout;
|
|
3245
|
+
const tree = (await execute("git", ["ls-tree", "-rz", "--full-tree", revision], {
|
|
3246
|
+
cwd: checkout,
|
|
3247
|
+
maxBuffer: 16777216
|
|
3248
|
+
})).stdout;
|
|
3249
|
+
const entries = tree.split("\0").filter(Boolean).map((line) => {
|
|
3250
|
+
const match = /^(100644|100755|120000) blob ([0-9a-f]{40})\t([\s\S]+)$/u.exec(line);
|
|
3251
|
+
if (!match)
|
|
3252
|
+
throw new Error("Git submodules or unsupported tracked objects need an explicit deployment configuration.");
|
|
3253
|
+
return { path: match[3], mode: match[1], oid: match[2] };
|
|
3254
|
+
});
|
|
3255
|
+
for (const entry of entries) {
|
|
3256
|
+
if (entry.mode !== "120000")
|
|
3257
|
+
continue;
|
|
3258
|
+
const { readlink: readlink2 } = await import("fs/promises");
|
|
3259
|
+
const path = join10(checkout, entry.path);
|
|
3260
|
+
const target2 = resolve3(dirname8(path), await readlink2(path));
|
|
3261
|
+
const bound = relative6(checkout, target2);
|
|
3262
|
+
if (bound.startsWith("..") || isAbsolute2(bound))
|
|
3263
|
+
throw new Error("A tracked symbolic link escapes the committed upload; resolve that source boundary before deployment.");
|
|
3264
|
+
}
|
|
3265
|
+
const providerConfigurations = await Promise.all(entries.filter((entry) => /(?:^|\/)vercel\.json$/u.test(entry.path)).map(async (entry) => ({
|
|
3266
|
+
path: entry.path,
|
|
3267
|
+
source: await readFile12(join10(checkout, entry.path), "utf8")
|
|
3268
|
+
})));
|
|
3269
|
+
const record = schema.parse({
|
|
3270
|
+
version: 2,
|
|
3271
|
+
revision,
|
|
3272
|
+
commit,
|
|
3273
|
+
entries,
|
|
3274
|
+
providerConfigurations
|
|
3275
|
+
});
|
|
3276
|
+
const target = join10(checkout, name);
|
|
3277
|
+
await mkdir8(dirname8(target), { recursive: true, mode: 448 });
|
|
3278
|
+
await writeFile5(target, JSON.stringify(record), { flag: "wx", mode: 384 });
|
|
3279
|
+
}
|
|
3280
|
+
|
|
3281
|
+
// ../cli/dist/commands/setup-deploy.js
|
|
3282
|
+
import { createHash as createHash4, randomBytes, randomUUID as randomUUID6 } from "crypto";
|
|
3283
|
+
import { access as access5, mkdir as mkdir9, mkdtemp, rm as rm5, writeFile as writeFile6 } from "fs/promises";
|
|
3284
|
+
import { tmpdir } from "os";
|
|
3285
|
+
import { join as join11 } from "path";
|
|
3286
|
+
import { z as z33 } from "zod";
|
|
3287
|
+
var envSchema = z33.object({
|
|
3288
|
+
id: z33.string(),
|
|
3289
|
+
key: z33.string(),
|
|
3290
|
+
target: z33.array(z33.string()),
|
|
3291
|
+
type: z33.string(),
|
|
3292
|
+
comment: z33.string().optional(),
|
|
3293
|
+
updatedAt: z33.number().optional()
|
|
3294
|
+
});
|
|
3295
|
+
var deploymentSchema = z33.object({
|
|
3296
|
+
id: z33.string(),
|
|
3297
|
+
projectId: z33.string(),
|
|
3298
|
+
ownerId: z33.string().optional(),
|
|
3299
|
+
target: z33.string().nullable(),
|
|
3300
|
+
readyState: z33.string(),
|
|
3301
|
+
createdAt: z33.number(),
|
|
3302
|
+
url: z33.string(),
|
|
3303
|
+
meta: z33.record(z33.string(), z33.unknown()).optional(),
|
|
3304
|
+
gitSource: z33.object({ sha: z33.string().optional() }).nullable().optional()
|
|
3305
|
+
});
|
|
3306
|
+
var buildProofSchema = z33.object({
|
|
3307
|
+
node: z33.string(),
|
|
3308
|
+
packageManager: z33.enum(["npm", "pnpm"]),
|
|
3309
|
+
packageManagerVersion: z33.string(),
|
|
3310
|
+
lockfileHash: z33.string(),
|
|
3311
|
+
revision: z33.string(),
|
|
3312
|
+
fieldContractHash: z33.string(),
|
|
3313
|
+
siteplane: z33.string(),
|
|
3314
|
+
runtimeNext: z33.string(),
|
|
3315
|
+
next: z33.string(),
|
|
3316
|
+
react: z33.string()
|
|
3317
|
+
}).strict();
|
|
3318
|
+
var defaults = {
|
|
3319
|
+
preflight: setupPreflightCommand,
|
|
3320
|
+
context: siteSetupContextCommand,
|
|
3321
|
+
api: setupVercelApi,
|
|
3322
|
+
process: setupProcess,
|
|
3323
|
+
verify: siteSetupVerifyCommand,
|
|
3324
|
+
post: postSiteSetup,
|
|
3325
|
+
writeBuildProvenance,
|
|
3326
|
+
now: Date.now,
|
|
3327
|
+
pause: (milliseconds) => new Promise((resolve4) => setTimeout(resolve4, milliseconds))
|
|
3328
|
+
};
|
|
2508
3329
|
export {
|
|
2509
3330
|
bookingCheckCommand,
|
|
2510
3331
|
bookingInitCommand,
|