siteplane 0.1.41 → 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 +30 -1
- package/dist/bin/siteplane.js +2033 -417
- package/dist/index.js +1280 -363
- package/dist/next.js +1464 -382
- 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,55 +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
|
|
1025
|
-
contractVersion: z14.literal("siteplane.setup-task.v1"),
|
|
1026
|
-
workflow: z14.enum(["initial_setup", "structure_update"]),
|
|
1027
|
-
goal: z14.string().min(1),
|
|
1028
|
-
modules: z14.tuple([z14.literal("visual_editor")]),
|
|
1029
|
-
packages: z14.object({
|
|
1030
|
-
siteplane: z14.string().regex(/^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$/u),
|
|
1031
|
-
runtimeNext: z14.string().regex(/^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$/u)
|
|
1032
|
-
}).strict(),
|
|
1033
|
-
communication: z14.object({
|
|
1034
|
-
beforeSourceChanges: z14.string().min(1),
|
|
1035
|
-
updates: z14.array(z14.string().min(1)).min(1),
|
|
1036
|
-
blocker: z14.string().min(1)
|
|
1037
|
-
}).strict(),
|
|
1038
|
-
discovery: z14.object({
|
|
1039
|
-
inspectPublicRoutes: z14.boolean(),
|
|
1040
|
-
contentKinds: z14.array(z14.enum(["text", "longText", "link", "image"])).min(1),
|
|
1041
|
-
rules: z14.array(z14.string().min(1)).min(1)
|
|
1042
|
-
}).strict(),
|
|
1043
|
-
steps: z14.array(z14.object({
|
|
1044
|
-
id: z14.enum([
|
|
1045
|
-
"inspect_repository",
|
|
1046
|
-
"install_packages",
|
|
1047
|
-
"instrument_fields",
|
|
1048
|
-
"apply_contract",
|
|
1049
|
-
"deploy_production",
|
|
1050
|
-
"verify_deployment"
|
|
1051
|
-
]),
|
|
1052
|
-
instruction: z14.string().min(1)
|
|
1053
|
-
}).strict()).length(6),
|
|
1054
|
-
completion: z14.object({
|
|
1055
|
-
verifiedStatus: z14.literal("ready_for_review"),
|
|
1056
|
-
instruction: z14.string().min(1)
|
|
1057
|
-
}).strict()
|
|
1058
|
-
}).strict();
|
|
1059
|
-
var editorFieldSchema = z14.object({
|
|
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({
|
|
1060
1074
|
fieldId: fieldIdSchema,
|
|
1061
|
-
label:
|
|
1062
|
-
subsection:
|
|
1063
|
-
description:
|
|
1064
|
-
required:
|
|
1065
|
-
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()
|
|
1066
1080
|
}).strict();
|
|
1067
|
-
var editorSectionSchema =
|
|
1068
|
-
label:
|
|
1069
|
-
fields:
|
|
1081
|
+
var editorSectionSchema = z15.object({
|
|
1082
|
+
label: z15.string().trim().min(1),
|
|
1083
|
+
fields: z15.array(editorFieldSchema).min(1)
|
|
1070
1084
|
}).strict().superRefine((section, context) => {
|
|
1071
1085
|
const closedSubsections = /* @__PURE__ */ new Set();
|
|
1072
1086
|
let currentSubsection;
|
|
@@ -1085,10 +1099,10 @@ var editorSectionSchema = z14.object({
|
|
|
1085
1099
|
}
|
|
1086
1100
|
}
|
|
1087
1101
|
});
|
|
1088
|
-
var editorRouteSchema =
|
|
1102
|
+
var editorRouteSchema = z15.object({
|
|
1089
1103
|
routeKey: siteFieldRouteKeySchema,
|
|
1090
|
-
label:
|
|
1091
|
-
sections:
|
|
1104
|
+
label: z15.string().trim().min(1),
|
|
1105
|
+
sections: z15.array(editorSectionSchema).min(1)
|
|
1092
1106
|
}).strict().superRefine((route, context) => {
|
|
1093
1107
|
const sections = /* @__PURE__ */ new Set();
|
|
1094
1108
|
for (const [index, section] of route.sections.entries()) {
|
|
@@ -1102,9 +1116,9 @@ var editorRouteSchema = z14.object({
|
|
|
1102
1116
|
sections.add(section.label);
|
|
1103
1117
|
}
|
|
1104
1118
|
});
|
|
1105
|
-
var editorDefinitionV1Schema =
|
|
1106
|
-
version:
|
|
1107
|
-
routes:
|
|
1119
|
+
var editorDefinitionV1Schema = z15.object({
|
|
1120
|
+
version: z15.literal(1),
|
|
1121
|
+
routes: z15.array(editorRouteSchema).min(1)
|
|
1108
1122
|
}).strict().superRefine((definition, context) => {
|
|
1109
1123
|
const routes = /* @__PURE__ */ new Set();
|
|
1110
1124
|
const fields = /* @__PURE__ */ new Set();
|
|
@@ -1142,7 +1156,7 @@ var editorDefinitionV1Schema = z14.object({
|
|
|
1142
1156
|
var forbiddenControlOrBidi = /[\u0000-\u001f\u007f-\u009f\u202a-\u202e\u2066-\u2069]/u;
|
|
1143
1157
|
var forbiddenOwnerNoteControlOrBidi = /[\u0000-\u0008\u000b\u000c\u000e-\u001f\u007f-\u009f\u202a-\u202e\u2066-\u2069]/u;
|
|
1144
1158
|
var unsafeLocator = /<\/?[a-z][^>]*>|\b(?:javascript|data:text\/html)\s*:|\bon[a-z]+\s*=/iu;
|
|
1145
|
-
var renderedPathSchema =
|
|
1159
|
+
var renderedPathSchema = z15.string().trim().transform((value) => value !== "/" ? value.replace(/\/+$/u, "") : value).superRefine((value, context) => {
|
|
1146
1160
|
if (!value.startsWith("/") || value === "$global" || value.includes("?") || value.includes("#")) {
|
|
1147
1161
|
context.addIssue({
|
|
1148
1162
|
code: "custom",
|
|
@@ -1152,7 +1166,7 @@ var renderedPathSchema = z14.string().trim().transform((value) => value !== "/"
|
|
|
1152
1166
|
addSafeByteIssues(value, CONTINUE_SITE_SETUP_RENDERED_PATH_MAX_BYTES, "renderedPath", context);
|
|
1153
1167
|
});
|
|
1154
1168
|
function normalizedSafeTextSchema(maxBytes, label) {
|
|
1155
|
-
return
|
|
1169
|
+
return z15.string().transform((value) => value.trim().replace(new RegExp("\\p{White_Space}+", "gu"), " ")).pipe(z15.string().min(1)).superRefine((value, context) => {
|
|
1156
1170
|
addSafeByteIssues(value, maxBytes, label, context);
|
|
1157
1171
|
if (label === "locatorHint" && unsafeLocator.test(value)) {
|
|
1158
1172
|
context.addIssue({
|
|
@@ -1169,12 +1183,12 @@ var correctionItemBase = {
|
|
|
1169
1183
|
requestedLabel: normalizedSafeTextSchema(CONTINUE_SITE_SETUP_REQUESTED_LABEL_MAX_BYTES, "requestedLabel").optional(),
|
|
1170
1184
|
requestedSection: normalizedSafeTextSchema(CONTINUE_SITE_SETUP_REQUESTED_SECTION_MAX_BYTES, "requestedSection").optional(),
|
|
1171
1185
|
requestedSubsection: normalizedSafeTextSchema(CONTINUE_SITE_SETUP_REQUESTED_SUBSECTION_MAX_BYTES, "requestedSubsection").optional(),
|
|
1172
|
-
requestedSortOrder:
|
|
1186
|
+
requestedSortOrder: z15.number().int().nonnegative().optional()
|
|
1173
1187
|
};
|
|
1174
|
-
var setupCorrectionItemSchema =
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
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()
|
|
1178
1192
|
]).superRefine((item, context) => {
|
|
1179
1193
|
if (item.requestedSubsection && !item.requestedSection) {
|
|
1180
1194
|
context.addIssue({
|
|
@@ -1184,7 +1198,7 @@ var setupCorrectionItemSchema = z14.discriminatedUnion("kind", [
|
|
|
1184
1198
|
});
|
|
1185
1199
|
}
|
|
1186
1200
|
});
|
|
1187
|
-
var setupCorrectionItemsSchema =
|
|
1201
|
+
var setupCorrectionItemsSchema = z15.array(setupCorrectionItemSchema).max(CONTINUE_SITE_SETUP_MAX_ITEMS).superRefine((items, context) => {
|
|
1188
1202
|
const bytes = utf8Bytes(stableJsonStringify(items));
|
|
1189
1203
|
if (bytes > CONTINUE_SITE_SETUP_ITEMS_MAX_BYTES) {
|
|
1190
1204
|
context.addIssue({
|
|
@@ -1193,7 +1207,7 @@ var setupCorrectionItemsSchema = z14.array(setupCorrectionItemSchema).max(CONTIN
|
|
|
1193
1207
|
});
|
|
1194
1208
|
}
|
|
1195
1209
|
});
|
|
1196
|
-
var siteSetupOwnerEditabilityNoteSchema =
|
|
1210
|
+
var siteSetupOwnerEditabilityNoteSchema = z15.string().max(SITE_SETUP_OWNER_EDITABILITY_NOTE_MAX_LENGTH).superRefine((value, context) => {
|
|
1197
1211
|
if (utf8Bytes(value) > SITE_SETUP_OWNER_EDITABILITY_NOTE_MAX_BYTES) {
|
|
1198
1212
|
context.addIssue({
|
|
1199
1213
|
code: "custom",
|
|
@@ -1207,27 +1221,190 @@ var siteSetupOwnerEditabilityNoteSchema = z14.string().trim().max(SITE_SETUP_OWN
|
|
|
1207
1221
|
});
|
|
1208
1222
|
}
|
|
1209
1223
|
});
|
|
1210
|
-
var
|
|
1224
|
+
var SITE_SETUP_MODULE_SCOPES = {
|
|
1225
|
+
editing: ["setup:read", "setup:write"],
|
|
1226
|
+
analytics: [
|
|
1227
|
+
"analytics:setup",
|
|
1228
|
+
"analytics:sync",
|
|
1229
|
+
"analytics:test",
|
|
1230
|
+
"analytics:readiness",
|
|
1231
|
+
"analytics:agent_instructions",
|
|
1232
|
+
"analytics:public_key_read"
|
|
1233
|
+
]
|
|
1234
|
+
};
|
|
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.");
|
|
1236
|
+
function siteSetupScopes(modules) {
|
|
1237
|
+
return modules.flatMap((module) => [...SITE_SETUP_MODULE_SCOPES[module]]);
|
|
1238
|
+
}
|
|
1239
|
+
function hasExactSiteSetupScopes(scopes, modules) {
|
|
1240
|
+
const matches = (expected) => scopes.length === expected.length && expected.every((scope) => scopes.includes(scope));
|
|
1241
|
+
return modules ? matches(siteSetupScopes(modules)) : matches(siteSetupScopes(["editing"])) || matches(siteSetupScopes(["editing", "analytics"]));
|
|
1242
|
+
}
|
|
1243
|
+
var siteSetupActivityInputSchema = z15.object({
|
|
1244
|
+
phase: z15.enum([
|
|
1245
|
+
"inspecting",
|
|
1246
|
+
"integrating",
|
|
1247
|
+
"deploying",
|
|
1248
|
+
"verifying",
|
|
1249
|
+
"repairing"
|
|
1250
|
+
]),
|
|
1251
|
+
textId: z15.enum([
|
|
1252
|
+
"inspecting",
|
|
1253
|
+
"integrating",
|
|
1254
|
+
"deploying",
|
|
1255
|
+
"verifying",
|
|
1256
|
+
"repairing"
|
|
1257
|
+
])
|
|
1258
|
+
}).strict().refine((value) => value.phase === value.textId, "Activity text must describe its phase.");
|
|
1259
|
+
var nextActionFields = {
|
|
1260
|
+
actor: z15.enum(["agent", "user", "siteplane"]),
|
|
1261
|
+
boundary: z15.enum([
|
|
1262
|
+
"source",
|
|
1263
|
+
"environment",
|
|
1264
|
+
"deployment",
|
|
1265
|
+
"verification",
|
|
1266
|
+
"authorization",
|
|
1267
|
+
"review"
|
|
1268
|
+
]),
|
|
1269
|
+
precondition: z15.string().min(1).max(1e3),
|
|
1270
|
+
instruction: z15.string().min(1).max(2e3),
|
|
1271
|
+
expectedEvidence: z15.string().min(1).max(1e3)
|
|
1272
|
+
};
|
|
1273
|
+
var siteSetupNextActionSchema = z15.discriminatedUnion("kind", [
|
|
1274
|
+
z15.object({
|
|
1275
|
+
...nextActionFields,
|
|
1276
|
+
kind: z15.literal("run_command"),
|
|
1277
|
+
command: z15.string().min(1).max(500)
|
|
1278
|
+
}).strict(),
|
|
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()
|
|
1283
|
+
]);
|
|
1284
|
+
var siteSetupTaskRunSchema = z15.object({
|
|
1285
|
+
runId: z15.string().uuid(),
|
|
1286
|
+
mode: siteSetupRunModeSchema,
|
|
1287
|
+
status: siteSetupRunStatusSchema,
|
|
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()
|
|
1293
|
+
}).strict();
|
|
1294
|
+
var siteSetupTaskProgressSchema = z15.object({
|
|
1295
|
+
progressStage: z15.enum([
|
|
1296
|
+
"waiting_for_connection",
|
|
1297
|
+
"agent_connected",
|
|
1298
|
+
"project_context_loaded",
|
|
1299
|
+
"fields_prepared",
|
|
1300
|
+
"deployment_verification",
|
|
1301
|
+
"ready_for_review",
|
|
1302
|
+
"action_required",
|
|
1303
|
+
"completed"
|
|
1304
|
+
]),
|
|
1305
|
+
lastVerifiedAt: z15.string().datetime().nullable(),
|
|
1306
|
+
lastActivityAt: z15.string().datetime(),
|
|
1307
|
+
activitySource: z15.enum(["user", "server", "agent"]),
|
|
1308
|
+
activityPhase: siteSetupActivityInputSchema.shape.phase.nullable(),
|
|
1309
|
+
activityTextId: siteSetupActivityInputSchema.shape.textId.nullable()
|
|
1310
|
+
}).strict();
|
|
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),
|
|
1315
|
+
modules: siteSetupModulesSchema,
|
|
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()
|
|
1322
|
+
}).strict().nullable(),
|
|
1323
|
+
run: siteSetupTaskRunSchema.nullable(),
|
|
1324
|
+
progress: siteSetupTaskProgressSchema.nullable(),
|
|
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({
|
|
1330
|
+
text: siteSetupOwnerEditabilityNoteSchema,
|
|
1331
|
+
source: z15.literal("user"),
|
|
1332
|
+
trust: z15.literal("untrusted")
|
|
1333
|
+
}).strict(),
|
|
1334
|
+
corrections: setupCorrectionItemsSchema,
|
|
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)
|
|
1346
|
+
}).strict()),
|
|
1347
|
+
nextAction: siteSetupNextActionSchema,
|
|
1348
|
+
error: z15.object({
|
|
1349
|
+
code: z15.string().regex(/^[a-z0-9_.]+$/u).max(160),
|
|
1350
|
+
boundary: nextActionFields.boundary,
|
|
1351
|
+
responsibleActor: nextActionFields.actor,
|
|
1352
|
+
retryable: z15.boolean(),
|
|
1353
|
+
retryAfter: z15.number().int().nonnegative().nullable(),
|
|
1354
|
+
requestId: z15.string().regex(/^[A-Za-z0-9_-]+$/u).max(128)
|
|
1355
|
+
}).strict().nullable(),
|
|
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)
|
|
1359
|
+
}).strict(),
|
|
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)
|
|
1364
|
+
}).strict(),
|
|
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)
|
|
1369
|
+
}).strict(),
|
|
1370
|
+
steps: z15.array(z15.object({
|
|
1371
|
+
id: z15.enum([
|
|
1372
|
+
"inspect_repository",
|
|
1373
|
+
"install_packages",
|
|
1374
|
+
"instrument_fields",
|
|
1375
|
+
"apply_contract",
|
|
1376
|
+
"deploy_production",
|
|
1377
|
+
"verify_deployment"
|
|
1378
|
+
]),
|
|
1379
|
+
instruction: z15.string().min(1)
|
|
1380
|
+
}).strict()).length(6),
|
|
1381
|
+
completion: z15.object({
|
|
1382
|
+
verifiedStatus: z15.literal("ready_for_review"),
|
|
1383
|
+
instruction: z15.string().min(1)
|
|
1384
|
+
}).strict()
|
|
1385
|
+
}).strict().refine((task) => hasExactSiteSetupScopes(task.authorizedScopes, task.modules), "Task scopes must exactly match its modules.");
|
|
1386
|
+
var canonicalHashSchema = z15.string().regex(/^sha256:[0-9a-f]{64}$/iu);
|
|
1211
1387
|
var deploymentRevisionSchema = normalizedSafeTextSchema(256, "deploymentRevision");
|
|
1212
|
-
var continueSiteSetupInputSchema =
|
|
1213
|
-
siteId:
|
|
1214
|
-
runId:
|
|
1388
|
+
var continueSiteSetupInputSchema = z15.object({
|
|
1389
|
+
siteId: z15.string().uuid(),
|
|
1390
|
+
runId: z15.string().uuid(),
|
|
1215
1391
|
expectedFieldContractHash: canonicalHashSchema,
|
|
1216
1392
|
expectedDeploymentRevision: deploymentRevisionSchema,
|
|
1217
1393
|
correctionItems: setupCorrectionItemsSchema,
|
|
1218
1394
|
ownerEditabilityNote: siteSetupOwnerEditabilityNoteSchema.optional()
|
|
1219
1395
|
}).strict();
|
|
1220
|
-
var saveSiteSetupOwnerNoteInputSchema =
|
|
1221
|
-
siteId:
|
|
1222
|
-
runId:
|
|
1396
|
+
var saveSiteSetupOwnerNoteInputSchema = z15.object({
|
|
1397
|
+
siteId: z15.string().uuid(),
|
|
1398
|
+
runId: z15.string().uuid(),
|
|
1223
1399
|
expectedFieldContractHash: canonicalHashSchema,
|
|
1224
1400
|
expectedDeploymentRevision: deploymentRevisionSchema,
|
|
1225
1401
|
ownerEditabilityNote: siteSetupOwnerEditabilityNoteSchema
|
|
1226
1402
|
}).strict();
|
|
1227
|
-
var siteSetupContextInputSchema =
|
|
1228
|
-
var siteSetupApplyInputSchema =
|
|
1403
|
+
var siteSetupContextInputSchema = z15.object({}).strict();
|
|
1404
|
+
var siteSetupApplyInputSchema = z15.object({
|
|
1229
1405
|
fieldContract: siteFieldContractV1Schema,
|
|
1230
|
-
editorDefinition: editorDefinitionV1Schema
|
|
1406
|
+
editorDefinition: editorDefinitionV1Schema,
|
|
1407
|
+
contentSelectionSummary: siteSetupOwnerEditabilityNoteSchema.refine((text) => text.trim().length > 0, "Describe the selected content, important exclusions and any open gaps.")
|
|
1231
1408
|
}).strict().superRefine((input, context) => {
|
|
1232
1409
|
const contractRoutesByFieldId = new Map(input.fieldContract.fields.map((field) => [
|
|
1233
1410
|
field.fieldId,
|
|
@@ -1291,37 +1468,37 @@ var siteSetupApplyInputSchema = z14.object({
|
|
|
1291
1468
|
}
|
|
1292
1469
|
}
|
|
1293
1470
|
});
|
|
1294
|
-
var siteSetupVerifyInputSchema =
|
|
1295
|
-
deploymentUrl:
|
|
1471
|
+
var siteSetupVerifyInputSchema = z15.object({
|
|
1472
|
+
deploymentUrl: z15.string().url().refine((value) => value.startsWith("https://")),
|
|
1296
1473
|
deploymentRevision: deploymentRevisionSchema,
|
|
1297
|
-
wait:
|
|
1474
|
+
wait: z15.boolean().optional()
|
|
1298
1475
|
}).strict();
|
|
1299
|
-
var siteSetupEvidenceInputSchema =
|
|
1300
|
-
siteId:
|
|
1301
|
-
runId:
|
|
1476
|
+
var siteSetupEvidenceInputSchema = z15.object({
|
|
1477
|
+
siteId: z15.string().uuid(),
|
|
1478
|
+
runId: z15.string().uuid(),
|
|
1302
1479
|
expectedFieldContractHash: canonicalHashSchema,
|
|
1303
|
-
expectedDeploymentOrigin:
|
|
1480
|
+
expectedDeploymentOrigin: z15.string().url().refine((value) => value.startsWith("https://")),
|
|
1304
1481
|
expectedDeploymentRevision: deploymentRevisionSchema,
|
|
1305
|
-
publicRuntimeKeyId:
|
|
1482
|
+
publicRuntimeKeyId: z15.string().uuid(),
|
|
1306
1483
|
bridgeSessionId: normalizedSafeTextSchema(256, "bridgeSessionId"),
|
|
1307
|
-
observations:
|
|
1484
|
+
observations: z15.array(z15.object({
|
|
1308
1485
|
fieldId: fieldIdSchema,
|
|
1309
1486
|
routeKey: siteFieldRouteKeySchema,
|
|
1310
1487
|
renderedPath: renderedPathSchema,
|
|
1311
|
-
targetResolved:
|
|
1312
|
-
previewAck:
|
|
1488
|
+
targetResolved: z15.boolean(),
|
|
1489
|
+
previewAck: z15.boolean()
|
|
1313
1490
|
}).strict().refine((value) => !value.previewAck || value.targetResolved, "Preview ACK requires a resolved target.")).min(1).max(200)
|
|
1314
1491
|
}).strict();
|
|
1315
|
-
var completeSiteSetupInputSchema =
|
|
1316
|
-
siteId:
|
|
1317
|
-
runId:
|
|
1492
|
+
var completeSiteSetupInputSchema = z15.object({
|
|
1493
|
+
siteId: z15.string().uuid(),
|
|
1494
|
+
runId: z15.string().uuid(),
|
|
1318
1495
|
expectedFieldContractHash: canonicalHashSchema,
|
|
1319
1496
|
expectedDeploymentRevision: deploymentRevisionSchema,
|
|
1320
1497
|
expectedReadyFingerprint: canonicalHashSchema
|
|
1321
1498
|
}).strict();
|
|
1322
|
-
var refreshSiteSetupDeploymentInputSchema =
|
|
1323
|
-
siteId:
|
|
1324
|
-
deploymentUrl:
|
|
1499
|
+
var refreshSiteSetupDeploymentInputSchema = z15.object({
|
|
1500
|
+
siteId: z15.string().uuid(),
|
|
1501
|
+
deploymentUrl: z15.string().url().refine((value) => value.startsWith("https://")),
|
|
1325
1502
|
deploymentRevision: deploymentRevisionSchema
|
|
1326
1503
|
}).strict();
|
|
1327
1504
|
function addSafeByteIssues(value, maxBytes, label, context) {
|
|
@@ -1344,34 +1521,34 @@ function utf8Bytes(value) {
|
|
|
1344
1521
|
|
|
1345
1522
|
// ../shared/dist/bridge-protocol.js
|
|
1346
1523
|
var BRIDGE_PROTOCOL_VERSION = 2;
|
|
1347
|
-
var bridgeRectSchema =
|
|
1348
|
-
x:
|
|
1349
|
-
y:
|
|
1350
|
-
width:
|
|
1351
|
-
height:
|
|
1524
|
+
var bridgeRectSchema = z16.object({
|
|
1525
|
+
x: z16.number(),
|
|
1526
|
+
y: z16.number(),
|
|
1527
|
+
width: z16.number().nonnegative(),
|
|
1528
|
+
height: z16.number().nonnegative()
|
|
1352
1529
|
});
|
|
1353
|
-
var previewTextValueSchema =
|
|
1354
|
-
fieldType:
|
|
1355
|
-
value:
|
|
1530
|
+
var previewTextValueSchema = z16.object({
|
|
1531
|
+
fieldType: z16.enum(["text", "longText"]),
|
|
1532
|
+
value: z16.string()
|
|
1356
1533
|
});
|
|
1357
|
-
var previewLinkValueSchema =
|
|
1358
|
-
fieldType:
|
|
1359
|
-
value:
|
|
1360
|
-
href:
|
|
1361
|
-
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()
|
|
1362
1539
|
})
|
|
1363
1540
|
});
|
|
1364
|
-
var previewImageValueSchema =
|
|
1365
|
-
fieldType:
|
|
1541
|
+
var previewImageValueSchema = z16.object({
|
|
1542
|
+
fieldType: z16.literal("image"),
|
|
1366
1543
|
value: imageValueSchema
|
|
1367
1544
|
});
|
|
1368
|
-
var bridgePreviewValueSchema =
|
|
1545
|
+
var bridgePreviewValueSchema = z16.discriminatedUnion("fieldType", [
|
|
1369
1546
|
previewTextValueSchema,
|
|
1370
1547
|
previewLinkValueSchema,
|
|
1371
1548
|
previewImageValueSchema
|
|
1372
1549
|
]);
|
|
1373
|
-
var fieldSelectionModeSchema =
|
|
1374
|
-
var fieldBridgeMissingContentActionSchema =
|
|
1550
|
+
var fieldSelectionModeSchema = z16.enum(["replace", "range", "toggle"]);
|
|
1551
|
+
var fieldBridgeMissingContentActionSchema = z16.enum([
|
|
1375
1552
|
"add",
|
|
1376
1553
|
"select",
|
|
1377
1554
|
"remove"
|
|
@@ -1390,77 +1567,77 @@ var FIELD_BRIDGE_MESSAGE_TYPES = [
|
|
|
1390
1567
|
"siteplane:field-bridge:preview-scrolled",
|
|
1391
1568
|
"siteplane:field-bridge:error"
|
|
1392
1569
|
];
|
|
1393
|
-
var canonicalFieldContractHashSchema =
|
|
1394
|
-
var bridgeSectionSchema =
|
|
1395
|
-
var realRenderedPathSchema =
|
|
1396
|
-
var fieldBridgeIdentitySchema =
|
|
1397
|
-
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(),
|
|
1398
1575
|
fieldContractHash: canonicalFieldContractHashSchema,
|
|
1399
|
-
deploymentRevision:
|
|
1576
|
+
deploymentRevision: z16.string().trim().min(1).max(256)
|
|
1400
1577
|
}).strict();
|
|
1401
|
-
var fieldBridgeBaseSchema =
|
|
1402
|
-
version:
|
|
1403
|
-
type:
|
|
1404
|
-
siteId:
|
|
1405
|
-
sessionId:
|
|
1406
|
-
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(),
|
|
1407
1584
|
fieldContractHash: canonicalFieldContractHashSchema,
|
|
1408
|
-
deploymentRevision:
|
|
1409
|
-
requestId:
|
|
1410
|
-
sentAt:
|
|
1585
|
+
deploymentRevision: z16.string().trim().min(1).max(256),
|
|
1586
|
+
requestId: z16.string().trim().min(1),
|
|
1587
|
+
sentAt: z16.string().datetime()
|
|
1411
1588
|
}).strict();
|
|
1412
|
-
var fieldBridgeFieldSchema =
|
|
1589
|
+
var fieldBridgeFieldSchema = z16.object({
|
|
1413
1590
|
fieldId: fieldIdSchema,
|
|
1414
1591
|
fieldType: fieldTypeSchema,
|
|
1415
1592
|
routeKey: siteFieldRouteKeySchema,
|
|
1416
1593
|
renderedPath: realRenderedPathSchema,
|
|
1417
|
-
sourcePath:
|
|
1594
|
+
sourcePath: z16.string().trim().min(1).optional(),
|
|
1418
1595
|
editTarget: fieldIdSchema,
|
|
1419
1596
|
rect: bridgeRectSchema,
|
|
1420
|
-
targetResolved:
|
|
1597
|
+
targetResolved: z16.literal(true),
|
|
1421
1598
|
currentValue: bridgePreviewValueSchema.optional()
|
|
1422
1599
|
}).strict();
|
|
1423
1600
|
var fieldBridgeInitMessageSchema = fieldBridgeBaseSchema.extend({
|
|
1424
|
-
type:
|
|
1425
|
-
payload:
|
|
1426
|
-
adminOrigin:
|
|
1427
|
-
customerOrigin:
|
|
1601
|
+
type: z16.literal("siteplane:field-bridge:init"),
|
|
1602
|
+
payload: z16.object({
|
|
1603
|
+
adminOrigin: z16.string().url(),
|
|
1604
|
+
customerOrigin: z16.string().url(),
|
|
1428
1605
|
renderedPath: realRenderedPathSchema
|
|
1429
1606
|
}).strict()
|
|
1430
1607
|
});
|
|
1431
1608
|
var fieldBridgeReadyMessageSchema = fieldBridgeBaseSchema.extend({
|
|
1432
|
-
type:
|
|
1433
|
-
payload:
|
|
1609
|
+
type: z16.literal("siteplane:field-bridge:ready"),
|
|
1610
|
+
payload: z16.object({
|
|
1434
1611
|
renderedPath: realRenderedPathSchema,
|
|
1435
|
-
fieldCount:
|
|
1436
|
-
capabilities:
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
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")
|
|
1441
1618
|
])
|
|
1442
1619
|
}).strict()
|
|
1443
1620
|
});
|
|
1444
1621
|
var fieldBridgeFieldsMessageSchema = fieldBridgeBaseSchema.extend({
|
|
1445
|
-
type:
|
|
1446
|
-
payload:
|
|
1622
|
+
type: z16.literal("siteplane:field-bridge:fields"),
|
|
1623
|
+
payload: z16.object({
|
|
1447
1624
|
renderedPath: realRenderedPathSchema,
|
|
1448
|
-
fields:
|
|
1625
|
+
fields: z16.array(fieldBridgeFieldSchema)
|
|
1449
1626
|
}).strict()
|
|
1450
1627
|
});
|
|
1451
1628
|
var fieldBridgeSelectFieldMessageSchema = fieldBridgeBaseSchema.extend({
|
|
1452
|
-
type:
|
|
1453
|
-
payload:
|
|
1629
|
+
type: z16.literal("siteplane:field-bridge:select-field"),
|
|
1630
|
+
payload: z16.object({
|
|
1454
1631
|
fieldId: fieldIdSchema,
|
|
1455
1632
|
selectionMode: fieldSelectionModeSchema
|
|
1456
1633
|
}).strict()
|
|
1457
1634
|
});
|
|
1458
1635
|
var fieldBridgeSetSelectedFieldMessageSchema = fieldBridgeBaseSchema.extend({
|
|
1459
|
-
type:
|
|
1460
|
-
payload:
|
|
1461
|
-
fieldIds:
|
|
1636
|
+
type: z16.literal("siteplane:field-bridge:set-selected-field"),
|
|
1637
|
+
payload: z16.object({
|
|
1638
|
+
fieldIds: z16.array(fieldIdSchema).max(200),
|
|
1462
1639
|
primaryFieldId: fieldIdSchema.nullable(),
|
|
1463
|
-
scrollIntoView:
|
|
1640
|
+
scrollIntoView: z16.boolean().optional()
|
|
1464
1641
|
}).strict().superRefine((value, context) => {
|
|
1465
1642
|
if (value.fieldIds.length > 0 && value.primaryFieldId === null) {
|
|
1466
1643
|
context.addIssue({
|
|
@@ -1479,58 +1656,58 @@ var fieldBridgeSetSelectedFieldMessageSchema = fieldBridgeBaseSchema.extend({
|
|
|
1479
1656
|
})
|
|
1480
1657
|
});
|
|
1481
1658
|
var fieldBridgeApplyPreviewValuesMessageSchema = fieldBridgeBaseSchema.extend({
|
|
1482
|
-
type:
|
|
1483
|
-
payload:
|
|
1659
|
+
type: z16.literal("siteplane:field-bridge:apply-preview-values"),
|
|
1660
|
+
payload: z16.object({ values: z16.record(fieldIdSchema, bridgePreviewValueSchema) }).strict()
|
|
1484
1661
|
});
|
|
1485
1662
|
var fieldBridgeTestPreviewValuesMessageSchema = fieldBridgeBaseSchema.extend({
|
|
1486
|
-
type:
|
|
1487
|
-
payload:
|
|
1663
|
+
type: z16.literal("siteplane:field-bridge:test-preview-values"),
|
|
1664
|
+
payload: z16.object({ fieldIds: z16.array(fieldIdSchema).min(1).max(200) }).strict()
|
|
1488
1665
|
});
|
|
1489
1666
|
var fieldBridgePreviewAckMessageSchema = fieldBridgeBaseSchema.extend({
|
|
1490
|
-
type:
|
|
1491
|
-
payload:
|
|
1492
|
-
ackRequestId:
|
|
1493
|
-
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"]),
|
|
1494
1671
|
renderedPath: realRenderedPathSchema,
|
|
1495
|
-
fieldIds:
|
|
1672
|
+
fieldIds: z16.array(fieldIdSchema).max(200)
|
|
1496
1673
|
}).strict()
|
|
1497
1674
|
});
|
|
1498
1675
|
var fieldBridgeSetVisualControlStateMessageSchema = fieldBridgeBaseSchema.extend({
|
|
1499
|
-
type:
|
|
1500
|
-
payload:
|
|
1501
|
-
enabled:
|
|
1502
|
-
fieldProximityEnabled:
|
|
1503
|
-
pendingKeys:
|
|
1504
|
-
activeFieldIds:
|
|
1505
|
-
fieldSections:
|
|
1506
|
-
selectedPending:
|
|
1507
|
-
key:
|
|
1508
|
-
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)
|
|
1509
1686
|
}).strict()).max(50),
|
|
1510
|
-
scrollPendingIntoView:
|
|
1687
|
+
scrollPendingIntoView: z16.boolean().optional()
|
|
1511
1688
|
}).strict()
|
|
1512
1689
|
});
|
|
1513
1690
|
var fieldBridgeMissingContentMessageSchema = fieldBridgeBaseSchema.extend({
|
|
1514
|
-
type:
|
|
1515
|
-
payload:
|
|
1691
|
+
type: z16.literal("siteplane:field-bridge:missing-content"),
|
|
1692
|
+
payload: z16.object({
|
|
1516
1693
|
action: fieldBridgeMissingContentActionSchema,
|
|
1517
1694
|
item: setupCorrectionItemSchema,
|
|
1518
1695
|
suggestedSection: bridgeSectionSchema.optional()
|
|
1519
1696
|
}).strict()
|
|
1520
1697
|
});
|
|
1521
1698
|
var fieldBridgePreviewScrolledMessageSchema = fieldBridgeBaseSchema.extend({
|
|
1522
|
-
type:
|
|
1523
|
-
payload:
|
|
1699
|
+
type: z16.literal("siteplane:field-bridge:preview-scrolled"),
|
|
1700
|
+
payload: z16.object({ renderedPath: realRenderedPathSchema }).strict()
|
|
1524
1701
|
});
|
|
1525
1702
|
var fieldBridgeErrorMessageSchema = fieldBridgeBaseSchema.extend({
|
|
1526
|
-
type:
|
|
1527
|
-
payload:
|
|
1528
|
-
code:
|
|
1529
|
-
message:
|
|
1530
|
-
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)
|
|
1531
1708
|
}).strict()
|
|
1532
1709
|
});
|
|
1533
|
-
var fieldBridgeMessageSchema =
|
|
1710
|
+
var fieldBridgeMessageSchema = z16.discriminatedUnion("type", [
|
|
1534
1711
|
fieldBridgeInitMessageSchema,
|
|
1535
1712
|
fieldBridgeReadyMessageSchema,
|
|
1536
1713
|
fieldBridgeFieldsMessageSchema,
|
|
@@ -1546,51 +1723,51 @@ var fieldBridgeMessageSchema = z15.discriminatedUnion("type", [
|
|
|
1546
1723
|
]);
|
|
1547
1724
|
|
|
1548
1725
|
// ../shared/dist/commands.js
|
|
1549
|
-
import { z as
|
|
1726
|
+
import { z as z18 } from "zod";
|
|
1550
1727
|
|
|
1551
1728
|
// ../shared/dist/errors.js
|
|
1552
|
-
import { z as
|
|
1729
|
+
import { z as z17 } from "zod";
|
|
1553
1730
|
var UI_ERROR_CATEGORIES = [
|
|
1554
1731
|
"site_member",
|
|
1555
1732
|
"workspace_member",
|
|
1556
1733
|
"internal"
|
|
1557
1734
|
];
|
|
1558
|
-
var uiErrorCategorySchema =
|
|
1559
|
-
var commandErrorPayloadSchema =
|
|
1560
|
-
code:
|
|
1561
|
-
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),
|
|
1562
1739
|
category: uiErrorCategorySchema,
|
|
1563
|
-
details:
|
|
1740
|
+
details: z17.record(z17.string(), z17.unknown()).optional()
|
|
1564
1741
|
});
|
|
1565
1742
|
|
|
1566
1743
|
// ../shared/dist/commands.js
|
|
1567
|
-
var commandSuccessSchema =
|
|
1568
|
-
ok:
|
|
1569
|
-
data:
|
|
1744
|
+
var commandSuccessSchema = z18.object({
|
|
1745
|
+
ok: z18.literal(true),
|
|
1746
|
+
data: z18.unknown()
|
|
1570
1747
|
});
|
|
1571
|
-
var commandErrorSchema =
|
|
1572
|
-
ok:
|
|
1748
|
+
var commandErrorSchema = z18.object({
|
|
1749
|
+
ok: z18.literal(false),
|
|
1573
1750
|
error: commandErrorPayloadSchema
|
|
1574
1751
|
});
|
|
1575
|
-
var commandResultSchema =
|
|
1752
|
+
var commandResultSchema = z18.discriminatedUnion("ok", [
|
|
1576
1753
|
commandSuccessSchema,
|
|
1577
1754
|
commandErrorSchema
|
|
1578
1755
|
]);
|
|
1579
1756
|
|
|
1580
1757
|
// ../shared/dist/editor-settings.js
|
|
1581
|
-
import { z as
|
|
1582
|
-
var editorColorSchemeSchema =
|
|
1758
|
+
import { z as z19 } from "zod";
|
|
1759
|
+
var editorColorSchemeSchema = z19.enum([
|
|
1583
1760
|
"paper",
|
|
1584
1761
|
"slate",
|
|
1585
1762
|
"siteplane",
|
|
1586
1763
|
"bloom"
|
|
1587
1764
|
]);
|
|
1588
1765
|
var editorColorSchemes = editorColorSchemeSchema.options;
|
|
1589
|
-
var editorColorModeSchema =
|
|
1766
|
+
var editorColorModeSchema = z19.enum(["light", "dark"]);
|
|
1590
1767
|
var editorColorModes = editorColorModeSchema.options;
|
|
1591
1768
|
|
|
1592
1769
|
// ../shared/dist/site-slug.js
|
|
1593
|
-
import { z as
|
|
1770
|
+
import { z as z20 } from "zod";
|
|
1594
1771
|
var SITE_SLUG_PATTERN = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
|
|
1595
1772
|
var RESERVED_SITE_SLUGS = /* @__PURE__ */ new Set([
|
|
1596
1773
|
"account",
|
|
@@ -1607,31 +1784,31 @@ var RESERVED_SITE_SLUGS = /* @__PURE__ */ new Set([
|
|
|
1607
1784
|
"support",
|
|
1608
1785
|
"workspace"
|
|
1609
1786
|
]);
|
|
1610
|
-
var siteSlugSchema =
|
|
1787
|
+
var siteSlugSchema = z20.string().regex(SITE_SLUG_PATTERN, "Invalid site slug").refine((value) => !RESERVED_SITE_SLUGS.has(value), "Reserved site slug");
|
|
1611
1788
|
|
|
1612
1789
|
// ../shared/dist/entitlements.js
|
|
1613
|
-
import { z as
|
|
1614
|
-
var entitlementSnapshotSchema =
|
|
1615
|
-
planKey:
|
|
1616
|
-
sitesLimit:
|
|
1617
|
-
siteMembersPerSiteLimit:
|
|
1618
|
-
customAdminDomainsEnabled:
|
|
1619
|
-
agentMcpEnabled:
|
|
1620
|
-
emailNotificationsEnabled:
|
|
1621
|
-
analyticsEnabled:
|
|
1622
|
-
analyticsSitesLimit:
|
|
1623
|
-
analyticsPortalPerformanceEnabled:
|
|
1624
|
-
analyticsMonthlyReportsEnabled:
|
|
1625
|
-
analyticsAiSummaryEnabled:
|
|
1626
|
-
analyticsRawEventRetentionDays:
|
|
1627
|
-
analyticsMonthlyEventLimit:
|
|
1628
|
-
bookingEnabled:
|
|
1629
|
-
bookingSitesLimit:
|
|
1630
|
-
bookingPortalManagementEnabled:
|
|
1631
|
-
bookingResourcesPerSiteLimit:
|
|
1632
|
-
bookingServicesPerSiteLimit:
|
|
1633
|
-
bookingMonthlyBookingsLimit:
|
|
1634
|
-
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)
|
|
1635
1812
|
});
|
|
1636
1813
|
var EARLY_ACCESS_PLAN = {
|
|
1637
1814
|
planKey: "early_access_2026",
|
|
@@ -1657,7 +1834,7 @@ var EARLY_ACCESS_PLAN = {
|
|
|
1657
1834
|
};
|
|
1658
1835
|
|
|
1659
1836
|
// ../shared/dist/readiness.js
|
|
1660
|
-
import { z as
|
|
1837
|
+
import { z as z22 } from "zod";
|
|
1661
1838
|
var READINESS_CHECK_KEYS = [
|
|
1662
1839
|
"agent_instructions_installed",
|
|
1663
1840
|
"runtime_package_connected",
|
|
@@ -1672,19 +1849,19 @@ var READINESS_STATUSES = [
|
|
|
1672
1849
|
"failing",
|
|
1673
1850
|
"warning"
|
|
1674
1851
|
];
|
|
1675
|
-
var readinessCheckKeySchema =
|
|
1676
|
-
var readinessStatusSchema =
|
|
1852
|
+
var readinessCheckKeySchema = z22.enum(READINESS_CHECK_KEYS);
|
|
1853
|
+
var readinessStatusSchema = z22.enum(READINESS_STATUSES);
|
|
1677
1854
|
|
|
1678
1855
|
// ../shared/dist/site.js
|
|
1679
|
-
import { z as
|
|
1856
|
+
import { z as z23 } from "zod";
|
|
1680
1857
|
var SITE_STATUSES = [
|
|
1681
1858
|
"setup",
|
|
1682
1859
|
"active",
|
|
1683
1860
|
"disabled",
|
|
1684
1861
|
"archived"
|
|
1685
1862
|
];
|
|
1686
|
-
var siteStatusSchema =
|
|
1687
|
-
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");
|
|
1688
1865
|
|
|
1689
1866
|
// ../cli/dist/analytics/static-scan.js
|
|
1690
1867
|
import ts from "typescript";
|
|
@@ -1875,16 +2052,16 @@ ${analyticsRulesTemplate}`;
|
|
|
1875
2052
|
import { createHash } from "crypto";
|
|
1876
2053
|
|
|
1877
2054
|
// ../cli/dist/commands/analytics/public-key.js
|
|
1878
|
-
import { z as
|
|
1879
|
-
var responseSchema =
|
|
1880
|
-
ok:
|
|
1881
|
-
data:
|
|
1882
|
-
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}$/)
|
|
1883
2060
|
})
|
|
1884
2061
|
});
|
|
1885
|
-
var errorResponseSchema =
|
|
1886
|
-
error:
|
|
1887
|
-
code:
|
|
2062
|
+
var errorResponseSchema = z24.object({
|
|
2063
|
+
error: z24.object({
|
|
2064
|
+
code: z24.string().regex(/^[a-z][a-z0-9_.-]+$/u)
|
|
1888
2065
|
})
|
|
1889
2066
|
});
|
|
1890
2067
|
|
|
@@ -2080,14 +2257,22 @@ function requireContentExportScope(scopes) {
|
|
|
2080
2257
|
import { access, chmod, open, readFile as readFile5, rename, rm } from "fs/promises";
|
|
2081
2258
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
2082
2259
|
import { join as join3 } from "path";
|
|
2083
|
-
import { z as
|
|
2084
|
-
var siteplaneProjectConfigSchema =
|
|
2085
|
-
version:
|
|
2086
|
-
apiBaseUrl:
|
|
2087
|
-
siteId:
|
|
2088
|
-
publicSiteKeyId:
|
|
2089
|
-
publicSiteKey:
|
|
2090
|
-
|
|
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()
|
|
2091
2276
|
}).strict();
|
|
2092
2277
|
async function readProjectPackageJson(projectDir) {
|
|
2093
2278
|
return JSON.parse(await readFile5(join3(projectDir, "package.json"), "utf8"));
|
|
@@ -2144,16 +2329,21 @@ async function writeJsonAtomically(path, value, mode) {
|
|
|
2144
2329
|
// ../cli/dist/config/credentials.js
|
|
2145
2330
|
import { execFile } from "child_process";
|
|
2146
2331
|
import { randomUUID as randomUUID3 } from "crypto";
|
|
2147
|
-
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";
|
|
2148
2333
|
import { dirname as dirname5, join as join4, relative } from "path";
|
|
2149
2334
|
import { promisify } from "util";
|
|
2150
|
-
import { z as
|
|
2151
|
-
var siteplaneCredentialsSchema =
|
|
2152
|
-
accessToken:
|
|
2153
|
-
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()
|
|
2154
2343
|
}).strict();
|
|
2155
2344
|
async function assertLocalCredentialsPathSafe(projectDir, options = {}) {
|
|
2156
2345
|
const path = join4(projectDir, ".siteplane/credentials.json");
|
|
2346
|
+
await assertCredentialFilesystemSafe(projectDir);
|
|
2157
2347
|
const isTrackedFile = options.isTrackedFile ?? ((targetPath) => gitPathMatches(projectDir, targetPath, "ls-files"));
|
|
2158
2348
|
const isIgnoredFile = options.isIgnoredFile ?? ((targetPath) => gitPathMatches(projectDir, targetPath, "check-ignore"));
|
|
2159
2349
|
if (await isTrackedFile(path)) {
|
|
@@ -2164,6 +2354,27 @@ async function assertLocalCredentialsPathSafe(projectDir, options = {}) {
|
|
|
2164
2354
|
}
|
|
2165
2355
|
return path;
|
|
2166
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
|
+
}
|
|
2167
2378
|
async function writeLocalCredentials(projectDir, credentials, options = {}) {
|
|
2168
2379
|
const path = await assertLocalCredentialsPathSafe(projectDir, options);
|
|
2169
2380
|
const parsed = siteplaneCredentialsSchema.parse(credentials);
|
|
@@ -2172,6 +2383,7 @@ async function writeLocalCredentials(projectDir, credentials, options = {}) {
|
|
|
2172
2383
|
return path;
|
|
2173
2384
|
}
|
|
2174
2385
|
async function readLocalCredentials(projectDir) {
|
|
2386
|
+
await assertCredentialFilesystemSafe(projectDir);
|
|
2175
2387
|
return siteplaneCredentialsSchema.parse(JSON.parse(await readFile6(join4(projectDir, ".siteplane/credentials.json"), "utf8")));
|
|
2176
2388
|
}
|
|
2177
2389
|
async function writeCredentialsAtomically(path, credentials) {
|
|
@@ -2207,8 +2419,452 @@ async function gitPathMatches(projectDir, path, command) {
|
|
|
2207
2419
|
}
|
|
2208
2420
|
|
|
2209
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";
|
|
2210
2435
|
import { join as join5 } from "path";
|
|
2211
|
-
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
|
|
2212
2868
|
async function initCommand(input) {
|
|
2213
2869
|
if (!input.setupToken.trim()) {
|
|
2214
2870
|
throw new Error("A Siteplane setup token is required.");
|
|
@@ -2216,47 +2872,64 @@ async function initCommand(input) {
|
|
|
2216
2872
|
if (!await detectNextProject(input.projectDir)) {
|
|
2217
2873
|
throw new Error("Siteplane init currently supports Next.js projects.");
|
|
2218
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}`);
|
|
2219
2884
|
const bootstrap = await bootstrapProjectConnection(input);
|
|
2220
|
-
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);
|
|
2221
2886
|
await acknowledgeBootstrapResponse(input);
|
|
2222
2887
|
return {
|
|
2223
2888
|
...paths,
|
|
2224
2889
|
nextSteps: [
|
|
2225
2890
|
"Run npx siteplane setup context and read the returned task.",
|
|
2226
2891
|
"Before source changes, briefly tell the user what Siteplane requested and what you will do.",
|
|
2227
|
-
"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."
|
|
2228
2893
|
]
|
|
2229
2894
|
};
|
|
2230
2895
|
}
|
|
2231
|
-
var siteSetupBootstrapDataSchema =
|
|
2232
|
-
credentialPurpose:
|
|
2233
|
-
apiBaseUrl:
|
|
2234
|
-
siteId:
|
|
2235
|
-
publicSiteKeyId:
|
|
2236
|
-
publicSiteKey:
|
|
2237
|
-
accessToken:
|
|
2238
|
-
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()
|
|
2239
2909
|
}).strict();
|
|
2240
|
-
var featureBootstrapDataSchema =
|
|
2241
|
-
credentialPurpose:
|
|
2242
|
-
apiBaseUrl:
|
|
2243
|
-
siteId:
|
|
2244
|
-
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)
|
|
2245
2915
|
}).strict();
|
|
2246
|
-
var bootstrapResponseSchema =
|
|
2247
|
-
ok:
|
|
2248
|
-
data:
|
|
2916
|
+
var bootstrapResponseSchema = z29.object({
|
|
2917
|
+
ok: z29.literal(true),
|
|
2918
|
+
data: z29.discriminatedUnion("credentialPurpose", [
|
|
2249
2919
|
siteSetupBootstrapDataSchema,
|
|
2250
2920
|
featureBootstrapDataSchema
|
|
2251
2921
|
])
|
|
2252
2922
|
}).strict();
|
|
2253
2923
|
async function bootstrapProjectConnection(input) {
|
|
2254
2924
|
const fetcher = input.fetcher ?? fetch;
|
|
2925
|
+
const existing = await access3(join7(input.projectDir, "siteplane.config.json")).then(() => readProjectConfig(input.projectDir), () => null);
|
|
2255
2926
|
const response = await fetcher(`${input.apiBaseUrl.replace(/\/$/, "")}/api/cli/setup/bootstrap`, {
|
|
2256
2927
|
method: "POST",
|
|
2928
|
+
signal: AbortSignal.timeout(2e4),
|
|
2257
2929
|
headers: createBootstrapHeaders(input),
|
|
2258
2930
|
body: JSON.stringify({
|
|
2259
2931
|
action: "bootstrap",
|
|
2932
|
+
...existing ? { expectedSiteId: existing.siteId, expectedRunId: existing.runId } : {},
|
|
2260
2933
|
agentClient: input.agentClient ?? "codex"
|
|
2261
2934
|
})
|
|
2262
2935
|
});
|
|
@@ -2271,6 +2944,7 @@ async function acknowledgeBootstrapResponse(input) {
|
|
|
2271
2944
|
const fetcher = input.fetcher ?? fetch;
|
|
2272
2945
|
const response = await fetcher(`${input.apiBaseUrl.replace(/\/$/, "")}/api/cli/setup/bootstrap`, {
|
|
2273
2946
|
method: "POST",
|
|
2947
|
+
signal: AbortSignal.timeout(2e4),
|
|
2274
2948
|
headers: createBootstrapHeaders(input),
|
|
2275
2949
|
body: JSON.stringify({ action: "acknowledge" })
|
|
2276
2950
|
});
|
|
@@ -2278,8 +2952,13 @@ async function acknowledgeBootstrapResponse(input) {
|
|
|
2278
2952
|
throw new Error("Siteplane setup acknowledgement failed.");
|
|
2279
2953
|
}
|
|
2280
2954
|
}
|
|
2281
|
-
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;
|
|
2282
2960
|
const credentialsPath = await writeLocalCredentials(input.projectDir, {
|
|
2961
|
+
...previousCredentials?.adminSession ? { adminSession: previousCredentials.adminSession } : {},
|
|
2283
2962
|
accessToken: bootstrap.accessToken,
|
|
2284
2963
|
siteRevalidationSecret: bootstrap.siteRevalidationSecret
|
|
2285
2964
|
}, {
|
|
@@ -2287,7 +2966,13 @@ async function persistSiteSetupBootstrap(input, bootstrap) {
|
|
|
2287
2966
|
...input.isTrackedFile ? { isTrackedFile: input.isTrackedFile } : {}
|
|
2288
2967
|
});
|
|
2289
2968
|
const configPath = await writeProjectConfig(input.projectDir, {
|
|
2290
|
-
|
|
2969
|
+
...previous ?? {},
|
|
2970
|
+
version: 2,
|
|
2971
|
+
appDirectory,
|
|
2972
|
+
runId: bootstrap.runId,
|
|
2973
|
+
packages: bootstrap.packages,
|
|
2974
|
+
taskContractVersion: "siteplane.setup-task.v2",
|
|
2975
|
+
adminProtocolVersion: 2,
|
|
2291
2976
|
apiBaseUrl: bootstrap.apiBaseUrl,
|
|
2292
2977
|
siteId: bootstrap.siteId,
|
|
2293
2978
|
publicSiteKeyId: bootstrap.publicSiteKeyId,
|
|
@@ -2297,7 +2982,7 @@ async function persistSiteSetupBootstrap(input, bootstrap) {
|
|
|
2297
2982
|
readLocalCredentials(input.projectDir),
|
|
2298
2983
|
readProjectConfig(input.projectDir)
|
|
2299
2984
|
]);
|
|
2300
|
-
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) {
|
|
2301
2986
|
throw new Error("Siteplane setup files could not be verified.");
|
|
2302
2987
|
}
|
|
2303
2988
|
return { configPath, credentialsPath };
|
|
@@ -2311,8 +2996,8 @@ async function persistFeatureBootstrap(input, bootstrap) {
|
|
|
2311
2996
|
throw new Error("The setup token belongs to a different Siteplane site.");
|
|
2312
2997
|
}
|
|
2313
2998
|
const credentialsPath = await writeLocalCredentials(input.projectDir, {
|
|
2314
|
-
|
|
2315
|
-
|
|
2999
|
+
...existingCredentials,
|
|
3000
|
+
accessToken: bootstrap.accessToken
|
|
2316
3001
|
}, {
|
|
2317
3002
|
...input.isIgnoredFile ? { isIgnoredFile: input.isIgnoredFile } : {},
|
|
2318
3003
|
...input.isTrackedFile ? { isTrackedFile: input.isTrackedFile } : {}
|
|
@@ -2322,7 +3007,7 @@ async function persistFeatureBootstrap(input, bootstrap) {
|
|
|
2322
3007
|
throw new Error("Siteplane credentials could not be verified.");
|
|
2323
3008
|
}
|
|
2324
3009
|
return {
|
|
2325
|
-
configPath:
|
|
3010
|
+
configPath: join7(input.projectDir, "siteplane.config.json"),
|
|
2326
3011
|
credentialsPath
|
|
2327
3012
|
};
|
|
2328
3013
|
}
|
|
@@ -2344,71 +3029,303 @@ function readErrorMessage(payload) {
|
|
|
2344
3029
|
}
|
|
2345
3030
|
|
|
2346
3031
|
// ../cli/dist/commands/scan.js
|
|
2347
|
-
import { readdir } from "fs/promises";
|
|
2348
|
-
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
|
+
}
|
|
2349
3071
|
|
|
2350
3072
|
// ../cli/dist/commands/site-setup.js
|
|
2351
3073
|
import { execFile as execFile2 } from "child_process";
|
|
2352
|
-
import { readFile as
|
|
3074
|
+
import { readFile as readFile9 } from "fs/promises";
|
|
2353
3075
|
import { promisify as promisify2 } from "util";
|
|
2354
|
-
import { z as
|
|
3076
|
+
import { z as z30 } from "zod";
|
|
2355
3077
|
|
|
2356
3078
|
// ../cli/dist/scan/next-source-scan.js
|
|
2357
3079
|
import ts2 from "typescript";
|
|
2358
|
-
import { isAbsolute, relative as
|
|
3080
|
+
import { isAbsolute, relative as relative4 } from "path";
|
|
2359
3081
|
var legacyEditableComponentPrefix = "Editable";
|
|
2360
|
-
var editableComponentNames = new Set(["Image", "Text", "LongText", "Link"].map((
|
|
3082
|
+
var editableComponentNames = new Set(["Image", "Text", "LongText", "Link"].map((name2) => `${legacyEditableComponentPrefix}${name2}`));
|
|
2361
3083
|
|
|
2362
3084
|
// ../cli/dist/commands/site-setup.js
|
|
2363
3085
|
var execFileAsync2 = promisify2(execFile2);
|
|
2364
|
-
var safeErrorSchema =
|
|
2365
|
-
code:
|
|
2366
|
-
message:
|
|
3086
|
+
var safeErrorSchema = z30.object({
|
|
3087
|
+
code: z30.string().trim().min(1),
|
|
3088
|
+
message: z30.string().trim().min(1)
|
|
2367
3089
|
}).passthrough();
|
|
2368
|
-
var errorResponseSchema2 =
|
|
2369
|
-
var contextDataSchema =
|
|
2370
|
-
|
|
2371
|
-
|
|
2372
|
-
|
|
2373
|
-
|
|
2374
|
-
|
|
2375
|
-
|
|
2376
|
-
|
|
2377
|
-
|
|
2378
|
-
|
|
2379
|
-
|
|
2380
|
-
|
|
2381
|
-
|
|
2382
|
-
|
|
2383
|
-
|
|
2384
|
-
|
|
2385
|
-
|
|
2386
|
-
|
|
2387
|
-
|
|
2388
|
-
|
|
2389
|
-
|
|
2390
|
-
|
|
2391
|
-
|
|
2392
|
-
|
|
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()
|
|
3101
|
+
}).strict();
|
|
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()
|
|
3108
|
+
}).strict();
|
|
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
|
|
2393
3229
|
}).strict();
|
|
2394
|
-
var
|
|
2395
|
-
|
|
2396
|
-
|
|
2397
|
-
|
|
2398
|
-
|
|
2399
|
-
|
|
2400
|
-
|
|
2401
|
-
|
|
2402
|
-
|
|
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)
|
|
2403
3239
|
}).strict();
|
|
2404
|
-
|
|
2405
|
-
|
|
2406
|
-
|
|
2407
|
-
|
|
2408
|
-
|
|
2409
|
-
|
|
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()
|
|
2410
3317
|
}).strict();
|
|
2411
|
-
var
|
|
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
|
+
};
|
|
2412
3329
|
export {
|
|
2413
3330
|
bookingCheckCommand,
|
|
2414
3331
|
bookingInitCommand,
|