siteplane 0.1.67 → 0.2.0-next.0
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 +43 -130
- package/dist/bin/siteplane.js +1892 -6606
- package/dist/chunk-KZ3AQ6OA.js +27 -0
- package/dist/chunk-YDCNEIOB.js +339 -0
- package/dist/components.d.ts +19 -0
- package/dist/components.js +33 -0
- package/dist/config.d.ts +8 -0
- package/dist/config.js +6 -0
- package/dist/index.d.ts +38 -1
- package/dist/index.js +112 -3716
- package/dist/internal/bridge-loader.js +28 -0
- package/dist/internal/bridge.js +1 -0
- package/dist/next.cjs +204 -0
- package/dist/next.d.ts +29 -120
- package/dist/next.js +123 -4509
- package/dist/route.d.ts +13 -0
- package/dist/route.js +144 -0
- package/package.json +45 -11
package/dist/index.js
CHANGED
|
@@ -1,3742 +1,138 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
higherTierRawEventRetentionDays: 90,
|
|
19
|
-
maxRawEventRetentionDaysWithoutAdr: 180,
|
|
20
|
-
diagnosticsRetentionDays: 30,
|
|
21
|
-
rateLimitBucketRetentionDays: 2,
|
|
22
|
-
lateEventWindowHours: 72
|
|
1
|
+
import {
|
|
2
|
+
loadSiteValues
|
|
3
|
+
} from "./chunk-YDCNEIOB.js";
|
|
4
|
+
import "./chunk-KZ3AQ6OA.js";
|
|
5
|
+
|
|
6
|
+
// src/index.ts
|
|
7
|
+
import { cache } from "react";
|
|
8
|
+
|
|
9
|
+
// ../shared/dist/field-values.js
|
|
10
|
+
var FIELD_VALUE_LIMITS = {
|
|
11
|
+
text: 256,
|
|
12
|
+
longText: 5e4,
|
|
13
|
+
linkLabel: 256,
|
|
14
|
+
linkHref: 2048,
|
|
15
|
+
imageSrc: 2048,
|
|
16
|
+
imageAlt: 300,
|
|
17
|
+
imageSize: 1e5
|
|
23
18
|
};
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
var
|
|
28
|
-
var
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
"
|
|
45
|
-
"
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
if (
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
var analyticsProviderImportRowSchema = z3.object({
|
|
75
|
-
targetId: analyticsImportTargetIdSchema,
|
|
76
|
-
occurredAt: z3.string().datetime({ offset: true }),
|
|
77
|
-
attributionConfidence: z3.enum(["provider_reported", "manual_import"]),
|
|
78
|
-
providerEventId: z3.string().trim().min(1).max(160).optional(),
|
|
79
|
-
idempotencyKey: z3.string().trim().min(1).max(160).optional()
|
|
80
|
-
}).strict().superRefine((row, context) => {
|
|
81
|
-
if (!row.providerEventId && !row.idempotencyKey) {
|
|
82
|
-
context.addIssue({
|
|
83
|
-
code: "custom",
|
|
84
|
-
message: "Each import row requires providerEventId or idempotencyKey.",
|
|
85
|
-
path: ["providerEventId"]
|
|
86
|
-
});
|
|
87
|
-
}
|
|
88
|
-
});
|
|
89
|
-
var analyticsProviderImportSchema = z3.object({
|
|
90
|
-
schemaVersion: z3.literal(ANALYTICS_IMPORT_SCHEMA_VERSION),
|
|
91
|
-
provider: z3.enum(["treatwell", "beautinda", "other"]),
|
|
92
|
-
sourceName: z3.string().trim().min(1).max(160).optional(),
|
|
93
|
-
rows: z3.array(analyticsProviderImportRowSchema).min(1).max(1e3)
|
|
94
|
-
}).strict();
|
|
95
|
-
|
|
96
|
-
// ../shared/dist/analytics-config.js
|
|
97
|
-
import { z as z4 } from "zod";
|
|
98
|
-
var ANALYTICS_CONFIG_LEASE_MS = 6e4;
|
|
99
|
-
var analyticsMeasurementConfigSchema = z4.object({
|
|
100
|
-
version: z4.literal(1),
|
|
101
|
-
installationGeneration: z4.number().int().positive(),
|
|
102
|
-
configRevision: z4.number().int().positive(),
|
|
103
|
-
effectiveSiteMode: z4.enum(["disabled", "session_only", "full_analytics"]),
|
|
104
|
-
measurementEnabled: z4.boolean(),
|
|
105
|
-
issuedAt: z4.string().datetime({ offset: true }),
|
|
106
|
-
expiresAt: z4.string().datetime({ offset: true })
|
|
107
|
-
}).strict().superRefine((config, context) => {
|
|
108
|
-
const lifetime = Date.parse(config.expiresAt) - Date.parse(config.issuedAt);
|
|
109
|
-
if (lifetime <= 0 || lifetime > ANALYTICS_CONFIG_LEASE_MS) {
|
|
110
|
-
context.addIssue({
|
|
111
|
-
code: "custom",
|
|
112
|
-
path: ["expiresAt"],
|
|
113
|
-
message: "Measurement permission must expire within 60 seconds."
|
|
114
|
-
});
|
|
115
|
-
}
|
|
116
|
-
if (config.measurementEnabled !== (config.effectiveSiteMode !== "disabled")) {
|
|
117
|
-
context.addIssue({
|
|
118
|
-
code: "custom",
|
|
119
|
-
path: ["measurementEnabled"],
|
|
120
|
-
message: "Measurement permission must match the effective site mode."
|
|
121
|
-
});
|
|
19
|
+
var linkKeys = ["href", "label"];
|
|
20
|
+
var fallbackImageKeys = ["src", "alt", "width", "height"];
|
|
21
|
+
var contentImageKeys = ["assetId", "src", "alt", "width", "height"];
|
|
22
|
+
var asciiBlank = /^[ \t\n\v\f\r]*$/u;
|
|
23
|
+
var uuidPattern = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/iu;
|
|
24
|
+
var webAddress = /^https?:\/\/[^/?#@]+(?:[/?#].*)?$/isu;
|
|
25
|
+
function fieldValueProblem(type, value, origin) {
|
|
26
|
+
switch (type) {
|
|
27
|
+
case "text":
|
|
28
|
+
case "longText":
|
|
29
|
+
if (typeof value !== "string")
|
|
30
|
+
return "not_text";
|
|
31
|
+
return codePoints(value) > FIELD_VALUE_LIMITS[type] ? "too_long" : null;
|
|
32
|
+
case "link":
|
|
33
|
+
return linkProblem(value);
|
|
34
|
+
case "image":
|
|
35
|
+
return imageProblem(value, origin);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
function readFieldValue(type, value) {
|
|
39
|
+
const rendered = type === "link" ? pick(value, linkKeys) : type === "image" ? pick(value, fallbackImageKeys) : value;
|
|
40
|
+
return fieldValueProblem(type, rendered, "fallback") === null ? rendered : null;
|
|
41
|
+
}
|
|
42
|
+
function linkProblem(value) {
|
|
43
|
+
if (!isRecord(value))
|
|
44
|
+
return "not_object";
|
|
45
|
+
if (hasUnknownKey(value, linkKeys))
|
|
46
|
+
return "unknown_key";
|
|
47
|
+
if (!isHref(value.href))
|
|
48
|
+
return "href_invalid";
|
|
49
|
+
if (typeof value.label !== "string" || asciiBlank.test(value.label))
|
|
50
|
+
return "label_missing";
|
|
51
|
+
return codePoints(value.label) > FIELD_VALUE_LIMITS.linkLabel ? "label_too_long" : null;
|
|
52
|
+
}
|
|
53
|
+
function imageProblem(value, origin) {
|
|
54
|
+
if (!isRecord(value))
|
|
55
|
+
return "not_object";
|
|
56
|
+
if (hasUnknownKey(value, origin === "content" ? contentImageKeys : fallbackImageKeys))
|
|
57
|
+
return "unknown_key";
|
|
58
|
+
if (origin === "content" && (typeof value.assetId !== "string" || !uuidPattern.test(value.assetId))) {
|
|
59
|
+
return "asset_missing";
|
|
60
|
+
}
|
|
61
|
+
if (!isImageSource(value.src))
|
|
62
|
+
return "src_invalid";
|
|
63
|
+
if (typeof value.alt !== "string" || codePoints(value.alt) > FIELD_VALUE_LIMITS.imageAlt)
|
|
64
|
+
return "alt_invalid";
|
|
65
|
+
const sizeRequired = origin === "content";
|
|
66
|
+
for (const size of [value.width, value.height]) {
|
|
67
|
+
if (size === void 0 ? sizeRequired : !isImageSize(size))
|
|
68
|
+
return "size_invalid";
|
|
122
69
|
}
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
// ../shared/dist/analytics-events.js
|
|
126
|
-
import { z as z5 } from "zod";
|
|
127
|
-
var ANALYTICS_SCHEMA_VERSION = "analytics.v1";
|
|
128
|
-
var analyticsSessionIdSchema = z5.string().regex(/^cpa_s_[a-f0-9]{32}$/u);
|
|
129
|
-
var analyticsVisitorIdSchema = z5.string().regex(/^cpa_v_[a-f0-9]{32}$/u);
|
|
130
|
-
var analyticsPersistedIdentityHashSchema = z5.string().regex(/^[a-f0-9]{64}$/u);
|
|
131
|
-
var analyticsEventNames = [
|
|
132
|
-
"page_view",
|
|
133
|
-
"section_view",
|
|
134
|
-
"cta_click",
|
|
135
|
-
"outbound_click",
|
|
136
|
-
"email_click",
|
|
137
|
-
"phone_click",
|
|
138
|
-
"file_download",
|
|
139
|
-
"form_start",
|
|
140
|
-
"form_submit",
|
|
141
|
-
"form_error",
|
|
142
|
-
"lead_created",
|
|
143
|
-
"checkout_started",
|
|
144
|
-
"conversion",
|
|
145
|
-
"checkout_completed",
|
|
146
|
-
"payment_succeeded",
|
|
147
|
-
"subscription_started",
|
|
148
|
-
"purchase_completed",
|
|
149
|
-
"trial_started"
|
|
150
|
-
];
|
|
151
|
-
var serverOnlyAnalyticsEvents = [
|
|
152
|
-
"checkout_completed",
|
|
153
|
-
"payment_succeeded",
|
|
154
|
-
"subscription_started",
|
|
155
|
-
"purchase_completed",
|
|
156
|
-
"trial_started"
|
|
157
|
-
];
|
|
158
|
-
var analyticsEventSources = [
|
|
159
|
-
"browser",
|
|
160
|
-
"server",
|
|
161
|
-
"test",
|
|
162
|
-
"editor_preview",
|
|
163
|
-
"system"
|
|
164
|
-
];
|
|
165
|
-
var analyticsIngestionChannels = [
|
|
166
|
-
"browser_collector",
|
|
167
|
-
"server_sdk",
|
|
168
|
-
"provider_endpoint",
|
|
169
|
-
"provider_import",
|
|
170
|
-
"test",
|
|
171
|
-
"editor_preview",
|
|
172
|
-
"system_job"
|
|
173
|
-
];
|
|
174
|
-
var analyticsTargetTypes = [
|
|
175
|
-
"cta",
|
|
176
|
-
"form",
|
|
177
|
-
"section",
|
|
178
|
-
"file",
|
|
179
|
-
"link",
|
|
180
|
-
"conversion",
|
|
181
|
-
"server_conversion"
|
|
182
|
-
];
|
|
183
|
-
var analyticsDataAttributeEvents = [
|
|
184
|
-
"cta_click",
|
|
185
|
-
"outbound_click",
|
|
186
|
-
"email_click",
|
|
187
|
-
"phone_click",
|
|
188
|
-
"file_download",
|
|
189
|
-
"section_view",
|
|
190
|
-
"checkout_started",
|
|
191
|
-
"form"
|
|
192
|
-
];
|
|
193
|
-
var analyticsDeviceTypes = [
|
|
194
|
-
"desktop",
|
|
195
|
-
"tablet",
|
|
196
|
-
"mobile",
|
|
197
|
-
"unknown"
|
|
198
|
-
];
|
|
199
|
-
var analyticsBotClassifications = [
|
|
200
|
-
"normal",
|
|
201
|
-
"known_bot",
|
|
202
|
-
"suspicious",
|
|
203
|
-
"invalid"
|
|
204
|
-
];
|
|
205
|
-
var analyticsValidityStatuses = [
|
|
206
|
-
"accepted",
|
|
207
|
-
"rejected",
|
|
208
|
-
"ignored"
|
|
209
|
-
];
|
|
210
|
-
var analyticsEventNameSchema = z5.enum(analyticsEventNames);
|
|
211
|
-
var serverOnlyAnalyticsEventSchema = z5.enum(serverOnlyAnalyticsEvents);
|
|
212
|
-
var analyticsEventSourceSchema = z5.enum(analyticsEventSources);
|
|
213
|
-
var analyticsIngestionChannelSchema = z5.enum(analyticsIngestionChannels);
|
|
214
|
-
var analyticsTargetTypeSchema = z5.enum(analyticsTargetTypes);
|
|
215
|
-
var analyticsDataAttributeEventSchema = z5.enum(analyticsDataAttributeEvents);
|
|
216
|
-
var analyticsDeviceTypeSchema = z5.enum(analyticsDeviceTypes);
|
|
217
|
-
var analyticsBotClassificationSchema = z5.enum(analyticsBotClassifications);
|
|
218
|
-
var analyticsValidityStatusSchema = z5.enum(analyticsValidityStatuses);
|
|
219
|
-
var analyticsPropertiesSchema = z5.record(z5.string(), z5.unknown());
|
|
220
|
-
var analyticsTimestampSchema = z5.string().datetime({ offset: true });
|
|
221
|
-
var analyticsBrowserEventSchema = z5.object({
|
|
222
|
-
eventId: z5.string().min(1).max(160),
|
|
223
|
-
installationGeneration: z5.number().int().positive().optional(),
|
|
224
|
-
measurementMode: z5.enum(["session_only", "full_analytics"]).optional(),
|
|
225
|
-
eventName: analyticsEventNameSchema,
|
|
226
|
-
eventSource: analyticsEventSourceSchema.optional().default("browser"),
|
|
227
|
-
targetId: z5.string().min(1).max(160).optional(),
|
|
228
|
-
targetType: analyticsTargetTypeSchema.optional(),
|
|
229
|
-
visitorId: analyticsVisitorIdSchema.optional(),
|
|
230
|
-
sessionId: analyticsSessionIdSchema,
|
|
231
|
-
idempotencyKey: z5.string().min(1).max(240).optional(),
|
|
232
|
-
occurredAt: analyticsTimestampSchema,
|
|
233
|
-
pageUrl: z5.string().url().max(2048).optional(),
|
|
234
|
-
pagePath: z5.string().min(1).max(1024).optional(),
|
|
235
|
-
routeTemplate: z5.string().min(1).max(1024).optional(),
|
|
236
|
-
referrer: z5.string().url().max(2048).optional(),
|
|
237
|
-
utmSource: z5.string().min(1).max(200).optional(),
|
|
238
|
-
utmMedium: z5.string().min(1).max(200).optional(),
|
|
239
|
-
utmCampaign: z5.string().min(1).max(200).optional(),
|
|
240
|
-
utmContent: z5.string().min(1).max(200).optional(),
|
|
241
|
-
utmTerm: z5.string().min(1).max(200).optional(),
|
|
242
|
-
deviceType: analyticsDeviceTypeSchema.optional(),
|
|
243
|
-
browserName: z5.string().min(1).max(120).optional(),
|
|
244
|
-
osName: z5.string().min(1).max(120).optional(),
|
|
245
|
-
country: z5.string().min(1).max(80).optional(),
|
|
246
|
-
region: z5.string().min(1).max(120).optional(),
|
|
247
|
-
properties: analyticsPropertiesSchema.optional().default({})
|
|
248
|
-
}).superRefine((event, context) => {
|
|
249
|
-
if (isServerOnlyAnalyticsEvent(event.eventName)) {
|
|
250
|
-
context.addIssue({
|
|
251
|
-
code: "custom",
|
|
252
|
-
message: "Browser analytics payloads cannot contain server-only events.",
|
|
253
|
-
path: ["eventName"]
|
|
254
|
-
});
|
|
255
|
-
}
|
|
256
|
-
if (event.eventSource === "server" || event.eventSource === "system") {
|
|
257
|
-
context.addIssue({
|
|
258
|
-
code: "custom",
|
|
259
|
-
message: "Browser analytics payloads cannot use server/system sources.",
|
|
260
|
-
path: ["eventSource"]
|
|
261
|
-
});
|
|
262
|
-
}
|
|
263
|
-
if (event.targetType === "server_conversion") {
|
|
264
|
-
context.addIssue({
|
|
265
|
-
code: "custom",
|
|
266
|
-
message: "Browser analytics payloads cannot use server conversion targets.",
|
|
267
|
-
path: ["targetType"]
|
|
268
|
-
});
|
|
269
|
-
}
|
|
270
|
-
});
|
|
271
|
-
var analyticsBrowserEventPayloadSchema = z5.object({
|
|
272
|
-
siteKey: z5.string().min(1),
|
|
273
|
-
schemaVersion: z5.literal(ANALYTICS_SCHEMA_VERSION),
|
|
274
|
-
mode: z5.enum(["live", "test"]).optional().default("live"),
|
|
275
|
-
events: z5.array(analyticsBrowserEventSchema).min(1).max(50)
|
|
276
|
-
});
|
|
277
|
-
var analyticsNormalizedEventBaseSchema = z5.object({
|
|
278
|
-
site_id: z5.string().uuid(),
|
|
279
|
-
event_id: z5.string().min(1).max(160),
|
|
280
|
-
schema_version: z5.literal(ANALYTICS_SCHEMA_VERSION),
|
|
281
|
-
event_name: analyticsEventNameSchema,
|
|
282
|
-
event_source: analyticsEventSourceSchema,
|
|
283
|
-
ingestion_channel: analyticsIngestionChannelSchema,
|
|
284
|
-
target_id: z5.string().min(1).max(160).nullable().optional(),
|
|
285
|
-
target_type: analyticsTargetTypeSchema.nullable().optional(),
|
|
286
|
-
dedupe_key: z5.string().regex(/^analytics_dedupe_v1_[a-f0-9]{64}$/u).nullable().optional(),
|
|
287
|
-
idempotency_key: z5.string().min(1).max(240).nullable().optional(),
|
|
288
|
-
bot_classification: analyticsBotClassificationSchema,
|
|
289
|
-
validity_status: analyticsValidityStatusSchema,
|
|
290
|
-
rejection_reason: z5.string().min(1).max(240).nullable().optional(),
|
|
291
|
-
occurred_at: analyticsTimestampSchema,
|
|
292
|
-
received_at: analyticsTimestampSchema,
|
|
293
|
-
page_url: z5.string().url().max(2048).nullable().optional(),
|
|
294
|
-
page_path: z5.string().min(1).max(1024).nullable().optional(),
|
|
295
|
-
route_template: z5.string().min(1).max(1024).nullable().optional(),
|
|
296
|
-
referrer: z5.string().url().max(2048).nullable().optional(),
|
|
297
|
-
utm_source: z5.string().min(1).max(200).nullable().optional(),
|
|
298
|
-
utm_medium: z5.string().min(1).max(200).nullable().optional(),
|
|
299
|
-
utm_campaign: z5.string().min(1).max(200).nullable().optional(),
|
|
300
|
-
utm_content: z5.string().min(1).max(200).nullable().optional(),
|
|
301
|
-
utm_term: z5.string().min(1).max(200).nullable().optional(),
|
|
302
|
-
country: z5.string().min(1).max(80).nullable().optional(),
|
|
303
|
-
region: z5.string().min(1).max(120).nullable().optional(),
|
|
304
|
-
device_type: analyticsDeviceTypeSchema,
|
|
305
|
-
browser_name: z5.string().min(1).max(120).nullable().optional(),
|
|
306
|
-
os_name: z5.string().min(1).max(120).nullable().optional(),
|
|
307
|
-
provider: z5.string().min(1).max(120).nullable().optional(),
|
|
308
|
-
provider_event_id: z5.string().min(1).max(240).nullable().optional(),
|
|
309
|
-
properties: analyticsPropertiesSchema
|
|
310
|
-
});
|
|
311
|
-
var analyticsRawNormalizedEventSchema = analyticsNormalizedEventBaseSchema.extend({
|
|
312
|
-
visitor_id: analyticsVisitorIdSchema.nullable().optional(),
|
|
313
|
-
session_id: analyticsSessionIdSchema.nullable().optional()
|
|
314
|
-
});
|
|
315
|
-
var analyticsNormalizedEventSchema = analyticsNormalizedEventBaseSchema.extend({
|
|
316
|
-
visitor_id: analyticsPersistedIdentityHashSchema.nullable().optional(),
|
|
317
|
-
session_id: analyticsPersistedIdentityHashSchema.nullable().optional()
|
|
318
|
-
});
|
|
319
|
-
function isServerOnlyAnalyticsEvent(eventName) {
|
|
320
|
-
return serverOnlyAnalyticsEvents.includes(eventName);
|
|
70
|
+
return null;
|
|
321
71
|
}
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
message: "Analytics target IDs must be stable identifiers without whitespace or visible copy."
|
|
327
|
-
});
|
|
328
|
-
var analyticsManifestRecordSchema = z6.record(z6.string(), z6.unknown());
|
|
329
|
-
var analyticsFormPurposes = [
|
|
330
|
-
"contact",
|
|
331
|
-
"lead",
|
|
332
|
-
"newsletter",
|
|
333
|
-
"search",
|
|
334
|
-
"login",
|
|
335
|
-
"other"
|
|
336
|
-
];
|
|
337
|
-
var analyticsFormPurposeSchema = z6.enum(analyticsFormPurposes);
|
|
338
|
-
var analyticsManifestRouteSchema = z6.object({
|
|
339
|
-
path: z6.string().min(1).max(1024),
|
|
340
|
-
pageType: z6.string().min(1).max(120).optional(),
|
|
341
|
-
label: z6.string().min(1).max(200).optional()
|
|
342
|
-
}).passthrough();
|
|
343
|
-
var analyticsManifestTargetSchema = z6.object({
|
|
344
|
-
id: analyticsTargetIdSchema,
|
|
345
|
-
type: analyticsTargetTypeSchema,
|
|
346
|
-
event: analyticsEventNameSchema.optional(),
|
|
347
|
-
events: z6.array(analyticsEventNameSchema).min(1).max(20).optional(),
|
|
348
|
-
route: z6.string().min(1).max(1024).optional(),
|
|
349
|
-
label: z6.string().min(1).max(200).optional(),
|
|
350
|
-
description: z6.string().min(1).max(1e3).optional(),
|
|
351
|
-
autoActive: z6.boolean().optional(),
|
|
352
|
-
sourceHints: analyticsManifestRecordSchema.optional()
|
|
353
|
-
}).passthrough().superRefine((target, context) => {
|
|
354
|
-
if (target.event === void 0 && target.events === void 0) {
|
|
355
|
-
context.addIssue({
|
|
356
|
-
code: "custom",
|
|
357
|
-
message: "Analytics targets require event or events.",
|
|
358
|
-
path: ["event"]
|
|
359
|
-
});
|
|
360
|
-
}
|
|
361
|
-
if (target.event !== void 0 && target.events !== void 0) {
|
|
362
|
-
context.addIssue({
|
|
363
|
-
code: "custom",
|
|
364
|
-
message: "Analytics targets must use event or events, never both.",
|
|
365
|
-
path: ["events"]
|
|
366
|
-
});
|
|
367
|
-
}
|
|
368
|
-
if (target.type === "form" && !analyticsFormPurposeSchema.safeParse(target.sourceHints?.formPurpose).success) {
|
|
369
|
-
context.addIssue({
|
|
370
|
-
code: "custom",
|
|
371
|
-
message: "Analytics form targets require a typed sourceHints.formPurpose.",
|
|
372
|
-
path: ["sourceHints", "formPurpose"]
|
|
373
|
-
});
|
|
374
|
-
}
|
|
375
|
-
});
|
|
376
|
-
var analyticsManifestSchema = z6.object({
|
|
377
|
-
schemaVersion: z6.literal(ANALYTICS_SCHEMA_VERSION),
|
|
378
|
-
siteId: z6.string().min(1),
|
|
379
|
-
siteKeyRef: z6.string().regex(/^env:[A-Z][A-Z0-9_]*$/u, {
|
|
380
|
-
message: "siteKeyRef must be an environment-variable reference."
|
|
381
|
-
}),
|
|
382
|
-
siteKeyLookup: z6.string().regex(/^pk_siteplane_[A-Za-z0-9_-]{16}$/),
|
|
383
|
-
routes: z6.array(analyticsManifestRouteSchema),
|
|
384
|
-
targets: z6.array(analyticsManifestTargetSchema),
|
|
385
|
-
metadata: analyticsManifestRecordSchema.optional(),
|
|
386
|
-
siteKey: z6.string().optional(),
|
|
387
|
-
secretKey: z6.string().optional(),
|
|
388
|
-
rawKey: z6.string().optional(),
|
|
389
|
-
token: z6.string().optional(),
|
|
390
|
-
accessToken: z6.string().optional()
|
|
391
|
-
}).passthrough().superRefine((manifest, context) => {
|
|
392
|
-
const targetIds = /* @__PURE__ */ new Set();
|
|
393
|
-
for (const [index, target] of manifest.targets.entries()) {
|
|
394
|
-
if (targetIds.has(target.id)) {
|
|
395
|
-
context.addIssue({
|
|
396
|
-
code: "custom",
|
|
397
|
-
message: `Duplicate analytics target ID: ${target.id}`,
|
|
398
|
-
path: ["targets", index, "id"]
|
|
399
|
-
});
|
|
400
|
-
}
|
|
401
|
-
targetIds.add(target.id);
|
|
402
|
-
}
|
|
403
|
-
for (const issue of findUnsafeSecretReferences(manifest)) {
|
|
404
|
-
context.addIssue({
|
|
405
|
-
code: "custom",
|
|
406
|
-
message: "Raw secret material is not allowed in analytics manifests.",
|
|
407
|
-
path: issue
|
|
408
|
-
});
|
|
409
|
-
}
|
|
410
|
-
});
|
|
411
|
-
var secretValuePattern = /(?:\bsk_(?:live|test)_|\bcpb_|\bpmt_(?:pc|setup|cli)_|\bservice_role\b|bearer\s+[a-z0-9._~-]+)/iu;
|
|
412
|
-
function findUnsafeSecretReferences(value, path = []) {
|
|
413
|
-
if (Array.isArray(value)) {
|
|
414
|
-
return value.flatMap((item, index) => findUnsafeSecretReferences(item, [...path, index]));
|
|
415
|
-
}
|
|
416
|
-
if (!isPlainRecord(value)) {
|
|
417
|
-
return [];
|
|
418
|
-
}
|
|
419
|
-
return Object.entries(value).flatMap(([key, childValue]) => {
|
|
420
|
-
const childPath = [...path, key];
|
|
421
|
-
const referenceLikeKey = /(?:ref|lookup|prefix)$/iu.test(key);
|
|
422
|
-
const unsafeHere = referenceLikeKey && typeof childValue === "string" && secretValuePattern.test(childValue);
|
|
423
|
-
return [
|
|
424
|
-
...unsafeHere ? [childPath] : [],
|
|
425
|
-
...findUnsafeSecretReferences(childValue, childPath)
|
|
426
|
-
];
|
|
427
|
-
});
|
|
72
|
+
function isHref(value) {
|
|
73
|
+
if (!isAddressText(value, FIELD_VALUE_LIMITS.linkHref))
|
|
74
|
+
return false;
|
|
75
|
+
return isSitePath(value) || value.startsWith("#") || webAddress.test(value) || /^mailto:.+$/isu.test(value) || /^tel:\+?[0-9][0-9().-]*$/iu.test(value);
|
|
428
76
|
}
|
|
429
|
-
function
|
|
430
|
-
return
|
|
77
|
+
function isImageSource(value) {
|
|
78
|
+
return isAddressText(value, FIELD_VALUE_LIMITS.imageSrc) && (isSitePath(value) || webAddress.test(value));
|
|
431
79
|
}
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
import { z as z7 } from "zod";
|
|
435
|
-
var analyticsVisitorQualities = ["exact", "estimated"];
|
|
436
|
-
var analyticsVisitorQualitySchema = z7.enum(analyticsVisitorQualities);
|
|
437
|
-
var analyticsKpiKeys = [
|
|
438
|
-
"pageViews",
|
|
439
|
-
"sessions",
|
|
440
|
-
"visitors",
|
|
441
|
-
"estimatedVisitors",
|
|
442
|
-
"inquiries",
|
|
443
|
-
"leads",
|
|
444
|
-
"conversions",
|
|
445
|
-
"conversionRate",
|
|
446
|
-
"inquiryRate"
|
|
447
|
-
];
|
|
448
|
-
var analyticsKpiKeySchema = z7.enum(analyticsKpiKeys);
|
|
449
|
-
|
|
450
|
-
// ../shared/dist/analytics-privacy.js
|
|
451
|
-
var serverPropertySchemas = {
|
|
452
|
-
lead_created: {
|
|
453
|
-
conversionId: "identifier",
|
|
454
|
-
formId: "identifier",
|
|
455
|
-
formType: "enum",
|
|
456
|
-
customerRef: "identifier"
|
|
457
|
-
},
|
|
458
|
-
conversion: {
|
|
459
|
-
conversionId: "identifier",
|
|
460
|
-
conversionType: "enum",
|
|
461
|
-
attributionConfidence: "enum",
|
|
462
|
-
bookingSignalSource: "enum",
|
|
463
|
-
bookingProvider: "enum",
|
|
464
|
-
redirectStatus: "enum",
|
|
465
|
-
importId: "identifier"
|
|
466
|
-
},
|
|
467
|
-
checkout_completed: revenuePropertySchema(),
|
|
468
|
-
payment_succeeded: revenuePropertySchema(),
|
|
469
|
-
subscription_started: revenuePropertySchema(),
|
|
470
|
-
purchase_completed: revenuePropertySchema(),
|
|
471
|
-
trial_started: revenuePropertySchema()
|
|
472
|
-
};
|
|
473
|
-
function revenuePropertySchema() {
|
|
474
|
-
return {
|
|
475
|
-
conversionId: "identifier",
|
|
476
|
-
checkoutId: "identifier",
|
|
477
|
-
customerRef: "identifier",
|
|
478
|
-
amount: "amount",
|
|
479
|
-
currency: "enum",
|
|
480
|
-
planId: "identifier",
|
|
481
|
-
productId: "identifier"
|
|
482
|
-
};
|
|
80
|
+
function isSitePath(value) {
|
|
81
|
+
return value.startsWith("/") && !value.startsWith("//");
|
|
483
82
|
}
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
"draft",
|
|
492
|
-
"change_set",
|
|
493
|
-
"published_value"
|
|
494
|
-
];
|
|
495
|
-
var assetStageSchema = z8.enum(ASSET_STAGES);
|
|
496
|
-
var assetVisibilitySchema = z8.enum(ASSET_VISIBILITIES);
|
|
497
|
-
var assetUsageEntityTypeSchema = z8.enum(ASSET_USAGE_ENTITY_TYPES);
|
|
498
|
-
var brandingAccentColorSchema = z8.string().regex(/^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/);
|
|
499
|
-
|
|
500
|
-
// ../shared/dist/booking-contracts.js
|
|
501
|
-
import { z as z9 } from "zod";
|
|
502
|
-
var bookingStatuses = [
|
|
503
|
-
"pending_payment",
|
|
504
|
-
"confirmed",
|
|
505
|
-
"payment_expired",
|
|
506
|
-
"cancelled",
|
|
507
|
-
"no_show"
|
|
508
|
-
];
|
|
509
|
-
var bookingPaymentStatuses = [
|
|
510
|
-
"payment_not_required",
|
|
511
|
-
"checkout_open",
|
|
512
|
-
"processing",
|
|
513
|
-
"succeeded",
|
|
514
|
-
"failed",
|
|
515
|
-
"cancelled",
|
|
516
|
-
"expired"
|
|
517
|
-
];
|
|
518
|
-
var bookingAccountReadinessStatuses = [
|
|
519
|
-
"not_started",
|
|
520
|
-
"setup_required",
|
|
521
|
-
"under_review",
|
|
522
|
-
"payments_ready",
|
|
523
|
-
"payouts_restricted",
|
|
524
|
-
"payments_restricted",
|
|
525
|
-
"deactivated"
|
|
526
|
-
];
|
|
527
|
-
var bookingRefundStatuses = [
|
|
528
|
-
"none",
|
|
529
|
-
"pending",
|
|
530
|
-
"partially_refunded",
|
|
531
|
-
"refunded",
|
|
532
|
-
"failed"
|
|
533
|
-
];
|
|
534
|
-
var bookingDisputeStatuses = [
|
|
535
|
-
"none",
|
|
536
|
-
"needs_response",
|
|
537
|
-
"under_review",
|
|
538
|
-
"won",
|
|
539
|
-
"lost"
|
|
540
|
-
];
|
|
541
|
-
var bookingPaymentModes = [
|
|
542
|
-
"onsite_only",
|
|
543
|
-
"online_required",
|
|
544
|
-
"customer_choice"
|
|
545
|
-
];
|
|
546
|
-
var bookingPaymentCollectionTypes = [
|
|
547
|
-
"full_amount",
|
|
548
|
-
"deposit_percent"
|
|
549
|
-
];
|
|
550
|
-
var bookingResourceKinds = [
|
|
551
|
-
"person",
|
|
552
|
-
"room",
|
|
553
|
-
"equipment",
|
|
554
|
-
"other"
|
|
555
|
-
];
|
|
556
|
-
var bookingStatusSchema = z9.enum(bookingStatuses);
|
|
557
|
-
var bookingPaymentStatusSchema = z9.enum(bookingPaymentStatuses);
|
|
558
|
-
var bookingAccountReadinessStatusSchema = z9.enum(bookingAccountReadinessStatuses);
|
|
559
|
-
var bookingRefundStatusSchema = z9.enum(bookingRefundStatuses);
|
|
560
|
-
var bookingDisputeStatusSchema = z9.enum(bookingDisputeStatuses);
|
|
561
|
-
var bookingPaymentModeSchema = z9.enum(bookingPaymentModes);
|
|
562
|
-
var bookingPaymentCollectionTypeSchema = z9.enum(bookingPaymentCollectionTypes);
|
|
563
|
-
var bookingPaymentCollectionSchema = z9.discriminatedUnion("type", [
|
|
564
|
-
z9.object({ type: z9.literal("full_amount") }).strict(),
|
|
565
|
-
z9.object({
|
|
566
|
-
type: z9.literal("deposit_percent"),
|
|
567
|
-
depositPercent: z9.number().int().min(10).max(90)
|
|
568
|
-
}).strict()
|
|
569
|
-
]);
|
|
570
|
-
var bookingPaymentChoices = ["onsite", "online"];
|
|
571
|
-
var bookingPaymentChoiceSchema = z9.enum(bookingPaymentChoices);
|
|
572
|
-
var bookingPaymentSnapshotSchema = z9.object({
|
|
573
|
-
snapshotId: z9.string().uuid(),
|
|
574
|
-
snapshotVersion: z9.number().int().positive(),
|
|
575
|
-
currency: z9.literal("EUR"),
|
|
576
|
-
totalAmountCents: z9.number().int().min(0),
|
|
577
|
-
onlineAmountCents: z9.number().int().min(0),
|
|
578
|
-
onsiteRemainderCents: z9.number().int().min(0),
|
|
579
|
-
maxStripeRefundAmountCents: z9.number().int().min(0)
|
|
580
|
-
}).strict().superRefine((snapshot, context) => {
|
|
581
|
-
if (snapshot.onlineAmountCents + snapshot.onsiteRemainderCents !== snapshot.totalAmountCents) {
|
|
582
|
-
context.addIssue({
|
|
583
|
-
code: "custom",
|
|
584
|
-
message: "Payment snapshot amounts must add up to the total amount."
|
|
585
|
-
});
|
|
586
|
-
}
|
|
587
|
-
if (snapshot.maxStripeRefundAmountCents > snapshot.onlineAmountCents) {
|
|
588
|
-
context.addIssue({
|
|
589
|
-
code: "custom",
|
|
590
|
-
message: "Stripe refund basis cannot exceed the online amount."
|
|
591
|
-
});
|
|
592
|
-
}
|
|
593
|
-
});
|
|
594
|
-
var bookingServiceVariantSchema = z9.object({
|
|
595
|
-
id: z9.string().uuid(),
|
|
596
|
-
name: z9.string().trim().min(1).max(120),
|
|
597
|
-
durationMinutes: z9.number().int().min(1).max(1440),
|
|
598
|
-
priceCents: z9.number().int().min(0).nullable()
|
|
599
|
-
}).strict();
|
|
600
|
-
var bookingServiceVariantsSchema = z9.array(bookingServiceVariantSchema).min(1).max(20);
|
|
601
|
-
var isoDateSchema = z9.string().regex(/^\d{4}-\d{2}-\d{2}$/);
|
|
602
|
-
var utcDateTimeSchema = z9.string().datetime();
|
|
603
|
-
var bookingLocalTimeSchema = z9.string().regex(/^(?:[01]\d|2[0-3]):[0-5]\d$/);
|
|
604
|
-
var bookingAvailabilityIntervalsSchema = z9.array(z9.object({
|
|
605
|
-
start: bookingLocalTimeSchema,
|
|
606
|
-
end: bookingLocalTimeSchema
|
|
607
|
-
}).strict().refine((interval) => interval.end > interval.start)).superRefine((intervals, context) => {
|
|
608
|
-
const sorted = [...intervals].sort((left, right) => left.start.localeCompare(right.start));
|
|
609
|
-
for (let index = 1; index < sorted.length; index += 1) {
|
|
610
|
-
if (sorted[index].start < sorted[index - 1].end) {
|
|
611
|
-
context.addIssue({
|
|
612
|
-
code: "custom",
|
|
613
|
-
message: "Booking availability intervals must not overlap."
|
|
614
|
-
});
|
|
615
|
-
return;
|
|
616
|
-
}
|
|
83
|
+
function isAddressText(value, maxLength) {
|
|
84
|
+
if (typeof value !== "string" || value.length === 0 || codePoints(value) > maxLength)
|
|
85
|
+
return false;
|
|
86
|
+
for (const character of value) {
|
|
87
|
+
const code = character.codePointAt(0);
|
|
88
|
+
if (code <= 32 || code === 127 || character === "\\")
|
|
89
|
+
return false;
|
|
617
90
|
}
|
|
618
|
-
|
|
619
|
-
var bookingPublicConfigSchema = z9.object({
|
|
620
|
-
site: z9.object({
|
|
621
|
-
displayName: z9.string().trim().min(1),
|
|
622
|
-
timezone: z9.string().trim().min(1),
|
|
623
|
-
locale: z9.string().trim().min(2),
|
|
624
|
-
bookingPageSlug: z9.string().regex(/^[a-z0-9]+(?:-[a-z0-9]+)*$/).min(2).max(64),
|
|
625
|
-
privacyUrl: z9.string().url().nullable()
|
|
626
|
-
}),
|
|
627
|
-
branding: z9.object({
|
|
628
|
-
logoUrl: z9.string().url().nullable(),
|
|
629
|
-
accentColor: z9.string().trim().min(1).nullable()
|
|
630
|
-
}),
|
|
631
|
-
settings: z9.object({
|
|
632
|
-
slotIntervalMinutes: z9.number().int().positive(),
|
|
633
|
-
minLeadMinutes: z9.number().int().min(0),
|
|
634
|
-
minCancelLeadMinutes: z9.number().int().min(0),
|
|
635
|
-
maxAdvanceDays: z9.number().int().min(1),
|
|
636
|
-
requirePhone: z9.boolean(),
|
|
637
|
-
collectNote: z9.boolean(),
|
|
638
|
-
confirmationMessage: z9.string().nullable()
|
|
639
|
-
}),
|
|
640
|
-
/** Freitexte des Salons, im Kassen-Schritt vor der Bestaetigung sichtbar. */
|
|
641
|
-
policies: z9.object({
|
|
642
|
-
cancellation: z9.string().nullable(),
|
|
643
|
-
lateArrival: z9.string().nullable()
|
|
644
|
-
}),
|
|
645
|
-
payment: z9.object({
|
|
646
|
-
mode: bookingPaymentModeSchema,
|
|
647
|
-
collection: bookingPaymentCollectionSchema,
|
|
648
|
-
onlinePaymentsReady: z9.boolean()
|
|
649
|
-
}).strict(),
|
|
650
|
-
serviceCategories: z9.array(z9.object({
|
|
651
|
-
id: z9.string().uuid(),
|
|
652
|
-
name: z9.string().trim().min(1),
|
|
653
|
-
sortOrder: z9.number().int()
|
|
654
|
-
})),
|
|
655
|
-
serviceSubcategories: z9.array(z9.object({
|
|
656
|
-
id: z9.string().uuid(),
|
|
657
|
-
categoryId: z9.string().uuid(),
|
|
658
|
-
name: z9.string().trim().min(1),
|
|
659
|
-
sortOrder: z9.number().int()
|
|
660
|
-
})),
|
|
661
|
-
services: z9.array(z9.object({
|
|
662
|
-
id: z9.string().trim().min(1),
|
|
663
|
-
name: z9.string().trim().min(1),
|
|
664
|
-
durationMinutes: z9.number().int().positive(),
|
|
665
|
-
priceCents: z9.number().int().min(0).nullable(),
|
|
666
|
-
currency: z9.string().regex(/^[A-Z]{3}$/),
|
|
667
|
-
description: z9.string().nullable(),
|
|
668
|
-
categoryId: z9.string().uuid(),
|
|
669
|
-
subcategoryId: z9.string().uuid().nullable(),
|
|
670
|
-
variants: bookingServiceVariantsSchema,
|
|
671
|
-
allowsAnyResource: z9.boolean(),
|
|
672
|
-
sortOrder: z9.number().int()
|
|
673
|
-
})),
|
|
674
|
-
resources: z9.array(z9.object({
|
|
675
|
-
id: z9.string().trim().min(1),
|
|
676
|
-
name: z9.string().trim().min(1),
|
|
677
|
-
kind: z9.enum(bookingResourceKinds)
|
|
678
|
-
})),
|
|
679
|
-
serviceResources: z9.array(z9.object({
|
|
680
|
-
serviceId: z9.string().trim().min(1),
|
|
681
|
-
resourceId: z9.string().trim().min(1)
|
|
682
|
-
}))
|
|
683
|
-
});
|
|
684
|
-
var bookingItemSchema = z9.object({
|
|
685
|
-
serviceId: z9.string().trim().min(1),
|
|
686
|
-
variantId: z9.string().trim().min(1)
|
|
687
|
-
}).strict();
|
|
688
|
-
var bookingItemsSchema = z9.array(bookingItemSchema).min(1).max(10);
|
|
689
|
-
function parseBookingItemsParam(value) {
|
|
690
|
-
const items = value.split(",").map((entry) => entry.trim()).filter((entry) => entry !== "").map((entry) => {
|
|
691
|
-
const [serviceId, variantId, ...rest] = entry.split(":");
|
|
692
|
-
return serviceId && variantId && rest.length === 0 ? { serviceId, variantId } : null;
|
|
693
|
-
});
|
|
694
|
-
return items.every((item) => item !== null) ? items : null;
|
|
91
|
+
return true;
|
|
695
92
|
}
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
resourceId: z9.string().trim().min(1).optional(),
|
|
699
|
-
fromDate: isoDateSchema,
|
|
700
|
-
toDate: isoDateSchema
|
|
701
|
-
});
|
|
702
|
-
var bookingSlotsResponseSchema = z9.object({
|
|
703
|
-
timezone: z9.string().trim().min(1),
|
|
704
|
-
items: bookingItemsSchema,
|
|
705
|
-
// Reine Behandlungsdauer ohne Puffer: das UI zeigt damit die Terminspanne,
|
|
706
|
-
// ohne selbst rechnen zu muessen.
|
|
707
|
-
totalDurationMinutes: z9.number().int().min(1),
|
|
708
|
-
mode: z9.enum(["any", "resource"]),
|
|
709
|
-
slots: z9.array(z9.object({
|
|
710
|
-
startUtc: utcDateTimeSchema,
|
|
711
|
-
resourceId: z9.string().trim().min(1).optional()
|
|
712
|
-
}))
|
|
713
|
-
});
|
|
714
|
-
var bookingAvailabilityQuerySchema = z9.object({
|
|
715
|
-
items: z9.preprocess((value) => typeof value === "string" ? parseBookingItemsParam(value) : value, bookingItemsSchema),
|
|
716
|
-
resourceId: z9.string().trim().min(1).optional(),
|
|
717
|
-
fromDate: isoDateSchema,
|
|
718
|
-
toDate: isoDateSchema
|
|
719
|
-
});
|
|
720
|
-
var bookingAvailabilityResponseSchema = z9.object({
|
|
721
|
-
timezone: z9.string().trim().min(1),
|
|
722
|
-
totalDurationMinutes: z9.number().int().min(1),
|
|
723
|
-
days: z9.array(z9.object({
|
|
724
|
-
date: isoDateSchema,
|
|
725
|
-
hasSlots: z9.boolean()
|
|
726
|
-
})),
|
|
727
|
-
/** Erster Tag mit Slot ab `fromDate`, auch ausserhalb des Fensters. */
|
|
728
|
-
nextAvailableDate: isoDateSchema.nullable()
|
|
729
|
-
});
|
|
730
|
-
var bookingPublicErrorCodes = [
|
|
731
|
-
"slot_unavailable",
|
|
732
|
-
"validation_error",
|
|
733
|
-
"origin_not_allowed",
|
|
734
|
-
"invalid_key",
|
|
735
|
-
"rate_limited",
|
|
736
|
-
"payment_required",
|
|
737
|
-
"payment_unavailable",
|
|
738
|
-
"payment_amount_too_small",
|
|
739
|
-
"already_cancelled",
|
|
740
|
-
"too_late",
|
|
741
|
-
"not_found"
|
|
742
|
-
];
|
|
743
|
-
var bookingPublicErrorSchema = z9.object({
|
|
744
|
-
error: z9.enum(bookingPublicErrorCodes),
|
|
745
|
-
message: z9.string().optional(),
|
|
746
|
-
requestId: z9.string().optional()
|
|
747
|
-
}).strict();
|
|
748
|
-
var bookingCreateRequestSchema = z9.object({
|
|
749
|
-
items: bookingItemsSchema,
|
|
750
|
-
resourceId: z9.string().min(1).nullable(),
|
|
751
|
-
startUtc: utcDateTimeSchema,
|
|
752
|
-
customer: z9.object({
|
|
753
|
-
name: z9.string().min(1).max(120),
|
|
754
|
-
email: z9.string().email().max(254),
|
|
755
|
-
phone: z9.string().max(32).optional(),
|
|
756
|
-
note: z9.string().max(1e3).optional()
|
|
757
|
-
}).strict(),
|
|
758
|
-
hp: z9.string().optional(),
|
|
759
|
-
clientToken: z9.string().uuid(),
|
|
760
|
-
paymentChoice: bookingPaymentChoiceSchema,
|
|
761
|
-
// Werbe-Einwilligung. Bestaetigung, Erinnerung und Storno-Link sind davon
|
|
762
|
-
// unabhaengig und werden immer versendet.
|
|
763
|
-
consent: z9.object({
|
|
764
|
-
marketingEmail: z9.boolean(),
|
|
765
|
-
marketingSms: z9.boolean()
|
|
766
|
-
}).strict().optional()
|
|
767
|
-
}).strict();
|
|
768
|
-
var bookingPublicPaymentResponseSchema = z9.object({
|
|
769
|
-
clientSecret: z9.string().min(1),
|
|
770
|
-
stripeAccountId: z9.string().startsWith("acct_")
|
|
771
|
-
}).strict();
|
|
772
|
-
var bookingCreateResponseSchema = z9.union([
|
|
773
|
-
z9.object({
|
|
774
|
-
status: z9.literal("confirmed"),
|
|
775
|
-
booking: z9.object({
|
|
776
|
-
id: z9.string().min(1),
|
|
777
|
-
startUtc: utcDateTimeSchema,
|
|
778
|
-
endUtc: utcDateTimeSchema,
|
|
779
|
-
timezone: z9.string().trim().min(1),
|
|
780
|
-
serviceName: z9.string().trim().min(1),
|
|
781
|
-
resourceName: z9.string().trim().min(1)
|
|
782
|
-
}).strict(),
|
|
783
|
-
manageUrl: z9.string().url(),
|
|
784
|
-
confirmationMessage: z9.string().nullable()
|
|
785
|
-
}).strict(),
|
|
786
|
-
z9.object({
|
|
787
|
-
status: z9.literal("pending_payment"),
|
|
788
|
-
bookingId: z9.string().min(1),
|
|
789
|
-
holdExpiresAt: utcDateTimeSchema,
|
|
790
|
-
payment: bookingPublicPaymentResponseSchema,
|
|
791
|
-
statusToken: z9.string().min(20),
|
|
792
|
-
manageUrl: z9.string().url().optional()
|
|
793
|
-
}).strict(),
|
|
794
|
-
bookingPublicErrorSchema
|
|
795
|
-
]);
|
|
796
|
-
var bookingStatusResponseSchema = z9.object({
|
|
797
|
-
bookingStatus: bookingStatusSchema,
|
|
798
|
-
paymentStatus: bookingPaymentStatusSchema,
|
|
799
|
-
refundStatus: bookingRefundStatusSchema,
|
|
800
|
-
disputeStatus: bookingDisputeStatusSchema,
|
|
801
|
-
holdExpiresAt: utcDateTimeSchema.nullable()
|
|
802
|
-
}).strict();
|
|
803
|
-
var bookingCancelRequestSchema = z9.object({
|
|
804
|
-
token: z9.string().min(20)
|
|
805
|
-
});
|
|
806
|
-
var bookingCancelResponseSchema = z9.union([
|
|
807
|
-
z9.object({
|
|
808
|
-
status: z9.enum(["cancelled", "already_cancelled", "too_late", "not_found"])
|
|
809
|
-
}),
|
|
810
|
-
bookingPublicErrorSchema
|
|
811
|
-
]);
|
|
812
|
-
var bookingMoveErrorCodes = [
|
|
813
|
-
"slot_unavailable",
|
|
814
|
-
"booking_not_movable",
|
|
815
|
-
"not_found"
|
|
816
|
-
];
|
|
817
|
-
var bookingMoveRequestSchema = z9.object({
|
|
818
|
-
bookingId: z9.string().uuid(),
|
|
819
|
-
newStartUtc: utcDateTimeSchema,
|
|
820
|
-
newResourceId: z9.string().uuid().optional(),
|
|
821
|
-
notifyCustomer: z9.boolean().default(false),
|
|
822
|
-
reason: z9.string().max(500).optional()
|
|
823
|
-
});
|
|
824
|
-
var bookingMoveResponseSchema = z9.union([
|
|
825
|
-
z9.object({
|
|
826
|
-
status: z9.literal("moved"),
|
|
827
|
-
bookingId: z9.string().uuid(),
|
|
828
|
-
startUtc: utcDateTimeSchema,
|
|
829
|
-
endUtc: utcDateTimeSchema,
|
|
830
|
-
resourceId: z9.string().uuid()
|
|
831
|
-
}),
|
|
832
|
-
z9.object({
|
|
833
|
-
error: z9.enum(bookingMoveErrorCodes),
|
|
834
|
-
message: z9.string().optional(),
|
|
835
|
-
requestId: z9.string().optional()
|
|
836
|
-
})
|
|
837
|
-
]);
|
|
838
|
-
var bookingManifestSchema = z9.object({
|
|
839
|
-
schemaVersion: z9.number().int().positive(),
|
|
840
|
-
siteId: z9.string().trim().min(1),
|
|
841
|
-
bookingPageSlug: z9.string().regex(/^[a-z0-9]+(?:-[a-z0-9]+)*$/).min(2).max(64),
|
|
842
|
-
integration: z9.literal("rewrite").optional(),
|
|
843
|
-
productionOrigin: z9.string().url().optional()
|
|
844
|
-
}).passthrough();
|
|
845
|
-
var secretManifestKeys = /* @__PURE__ */ new Set([
|
|
846
|
-
"siteKey",
|
|
847
|
-
"rawKey",
|
|
848
|
-
"token",
|
|
849
|
-
"accessToken"
|
|
850
|
-
]);
|
|
851
|
-
function redactBookingManifest(value) {
|
|
852
|
-
if (Array.isArray(value)) {
|
|
853
|
-
return value.map((item) => redactBookingManifest(item));
|
|
854
|
-
}
|
|
855
|
-
if (value && typeof value === "object") {
|
|
856
|
-
return Object.fromEntries(Object.entries(value).filter(([key]) => !secretManifestKeys.has(key)).map(([key, item]) => [key, redactBookingManifest(item)]));
|
|
857
|
-
}
|
|
858
|
-
return value;
|
|
93
|
+
function isImageSize(value) {
|
|
94
|
+
return typeof value === "number" && Number.isInteger(value) && value >= 1 && value <= FIELD_VALUE_LIMITS.imageSize;
|
|
859
95
|
}
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
var BOOKING_CREATE_PAYLOAD_LIMIT_BYTES = 16 * 1024;
|
|
863
|
-
|
|
864
|
-
// ../shared/dist/bridge-protocol.js
|
|
865
|
-
import { z as z17 } from "zod";
|
|
866
|
-
|
|
867
|
-
// ../shared/dist/field-id.js
|
|
868
|
-
import { z as z10 } from "zod";
|
|
869
|
-
var FIELD_ID_PATTERN = /^[a-z][a-z0-9_-]*(\.[a-z][a-z0-9_-]*)+$/;
|
|
870
|
-
var fieldIdSchema = z10.string().regex(FIELD_ID_PATTERN, "Invalid field id");
|
|
871
|
-
|
|
872
|
-
// ../shared/dist/field-types.js
|
|
873
|
-
import { z as z11 } from "zod";
|
|
874
|
-
var FIELD_TYPES = ["text", "longText", "image", "link"];
|
|
875
|
-
var fieldTypeSchema = z11.enum(FIELD_TYPES);
|
|
876
|
-
|
|
877
|
-
// ../shared/dist/image-value.js
|
|
878
|
-
import { z as z12 } from "zod";
|
|
879
|
-
var SUPPORTED_IMAGE_CONTENT_TYPES = [
|
|
880
|
-
"image/jpeg",
|
|
881
|
-
"image/png",
|
|
882
|
-
"image/webp",
|
|
883
|
-
"image/avif"
|
|
884
|
-
];
|
|
885
|
-
var maxImageUploadBytes = 10 * 1024 * 1024;
|
|
886
|
-
var largeImageWarningBytes = 2 * 1024 * 1024;
|
|
887
|
-
var imageContentTypeSchema = z12.enum(SUPPORTED_IMAGE_CONTENT_TYPES);
|
|
888
|
-
var imageCropSchema = z12.object({
|
|
889
|
-
x: z12.number().min(0).max(100),
|
|
890
|
-
y: z12.number().min(0).max(100),
|
|
891
|
-
zoom: z12.number().min(1).max(4),
|
|
892
|
-
aspectRatio: z12.number().positive().max(10)
|
|
893
|
-
});
|
|
894
|
-
var imageValueSchema = z12.object({
|
|
895
|
-
src: z12.string().trim().min(1),
|
|
896
|
-
alt: z12.string().trim().min(1).max(300),
|
|
897
|
-
width: z12.number().int().positive().optional(),
|
|
898
|
-
height: z12.number().int().positive().optional(),
|
|
899
|
-
crop: imageCropSchema.optional(),
|
|
900
|
-
assetId: z12.string().uuid().optional(),
|
|
901
|
-
finalStorageProvider: z12.enum([
|
|
902
|
-
"repo_static_assets",
|
|
903
|
-
"repo_handoff",
|
|
904
|
-
"site_owned_storage",
|
|
905
|
-
"siteplane_managed_fallback"
|
|
906
|
-
]).optional()
|
|
907
|
-
});
|
|
908
|
-
|
|
909
|
-
// ../shared/dist/setup-deployment.js
|
|
910
|
-
import { z as z13 } from "zod";
|
|
911
|
-
var version = z13.string().regex(/^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$/u);
|
|
912
|
-
var siteSetupPackagesSchema = z13.object({
|
|
913
|
-
siteplane: version,
|
|
914
|
-
runtimeNext: version,
|
|
915
|
-
analytics: version.optional()
|
|
916
|
-
}).strict();
|
|
917
|
-
var hash = z13.string().regex(/^sha256:[0-9a-f]{64}$/u);
|
|
918
|
-
var setupDeploymentRecordSchema = z13.object({
|
|
919
|
-
version: z13.literal(1),
|
|
920
|
-
operationId: z13.string().uuid(),
|
|
921
|
-
provider: z13.literal("vercel"),
|
|
922
|
-
projectId: z13.string().regex(/^prj_[A-Za-z0-9]+$/u),
|
|
923
|
-
teamId: z13.string().regex(/^(?:team|user)_[A-Za-z0-9]+$/u),
|
|
924
|
-
origin: z13.string().url().refine((value) => {
|
|
925
|
-
const url = new URL(value);
|
|
926
|
-
return url.protocol === "https:" && url.origin === value && !url.username && !url.password;
|
|
927
|
-
}),
|
|
928
|
-
deploymentId: z13.string().regex(/^dpl_[A-Za-z0-9]+$/u).nullable(),
|
|
929
|
-
revision: z13.string().regex(/^[0-9a-f]{40}$/u),
|
|
930
|
-
fieldContractHash: hash,
|
|
931
|
-
packages: siteSetupPackagesSchema,
|
|
932
|
-
configurationFingerprint: hash,
|
|
933
|
-
adminSecretGeneration: z13.string().uuid(),
|
|
934
|
-
revalidationGeneration: z13.number().int().positive(),
|
|
935
|
-
startedAt: z13.string().datetime(),
|
|
936
|
-
environmentWrittenAt: z13.string().datetime().nullable(),
|
|
937
|
-
deployRequestedAt: z13.string().datetime().nullable(),
|
|
938
|
-
deadline: z13.string().datetime(),
|
|
939
|
-
phase: z13.enum([
|
|
940
|
-
"planned",
|
|
941
|
-
"environment_written",
|
|
942
|
-
"deploy_requested",
|
|
943
|
-
"deployed",
|
|
944
|
-
"verified",
|
|
945
|
-
"failed"
|
|
946
|
-
]),
|
|
947
|
-
build: z13.object({
|
|
948
|
-
node: version,
|
|
949
|
-
packageManager: z13.enum(["npm", "pnpm"]),
|
|
950
|
-
packageManagerVersion: version,
|
|
951
|
-
lockfileHash: hash
|
|
952
|
-
}).strict().nullable()
|
|
953
|
-
}).strict();
|
|
954
|
-
var setupDeploymentInputSchema = z13.discriminatedUnion("action", [
|
|
955
|
-
z13.object({ action: z13.literal("read") }).strict(),
|
|
956
|
-
z13.object({
|
|
957
|
-
action: z13.literal("record"),
|
|
958
|
-
expectedOperationId: z13.string().uuid().nullable(),
|
|
959
|
-
record: setupDeploymentRecordSchema
|
|
960
|
-
}).strict()
|
|
961
|
-
]);
|
|
962
|
-
|
|
963
|
-
// ../shared/dist/site-setup.js
|
|
964
|
-
import { z as z16 } from "zod";
|
|
965
|
-
|
|
966
|
-
// ../shared/dist/site-field-contract.js
|
|
967
|
-
import { z as z15 } from "zod";
|
|
968
|
-
|
|
969
|
-
// ../shared/dist/fallback-hash.js
|
|
970
|
-
import { z as z14 } from "zod";
|
|
971
|
-
var SAFE_REPRESENTATION_REASONS = [
|
|
972
|
-
"asset_import_rewritten",
|
|
973
|
-
"relative_url_normalized",
|
|
974
|
-
"line_endings_normalized",
|
|
975
|
-
"image_value_serialized"
|
|
976
|
-
];
|
|
977
|
-
var safeRepresentationReasonSchema = z14.enum(SAFE_REPRESENTATION_REASONS);
|
|
978
|
-
var linkFallbackSchema = z14.object({
|
|
979
|
-
href: z14.string().trim().min(1),
|
|
980
|
-
label: z14.string().trim().min(1).optional(),
|
|
981
|
-
target: z14.enum(["_self", "_blank"]).optional()
|
|
982
|
-
}).passthrough();
|
|
983
|
-
function stableJsonStringify(value) {
|
|
984
|
-
return JSON.stringify(sortObjectKeys(value));
|
|
96
|
+
function hasUnknownKey(value, keys) {
|
|
97
|
+
return Object.keys(value).some((key) => !keys.includes(key));
|
|
985
98
|
}
|
|
986
|
-
function
|
|
987
|
-
if (
|
|
988
|
-
return value.map(sortObjectKeys);
|
|
989
|
-
}
|
|
990
|
-
if (!value || typeof value !== "object") {
|
|
99
|
+
function pick(value, keys) {
|
|
100
|
+
if (!isRecord(value))
|
|
991
101
|
return value;
|
|
992
|
-
|
|
993
|
-
return Object.fromEntries(Object.entries(value).sort(([left], [right]) => left.localeCompare(right)).map(([key, entryValue]) => [key, sortObjectKeys(entryValue)]));
|
|
994
|
-
}
|
|
995
|
-
|
|
996
|
-
// ../shared/dist/site-field-contract.js
|
|
997
|
-
var siteFieldStatusSchema = z15.enum(["hidden", "active"]);
|
|
998
|
-
var semanticVersionSchema = z15.string().regex(/^\d+\.\d+\.\d+$/u);
|
|
999
|
-
var siteFieldRouteKeySchema = z15.string().trim().refine((value) => value === "$global" || value.startsWith("/") && !value.includes("?") && !value.includes("#") && (value === "/" || !value.endsWith("/")), "Route keys must be canonical paths or $global.");
|
|
1000
|
-
var repositoryRelativePosixPathSchema = z15.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.");
|
|
1001
|
-
var sourceMappingSchema = z15.object({
|
|
1002
|
-
kind: z15.literal("function"),
|
|
1003
|
-
filePath: repositoryRelativePosixPathSchema,
|
|
1004
|
-
exportName: z15.string().trim().min(1).optional(),
|
|
1005
|
-
sourcePath: z15.string().trim().min(1).optional(),
|
|
1006
|
-
editTarget: fieldIdSchema.optional()
|
|
1007
|
-
}).strict();
|
|
1008
|
-
var domMappingSchema = z15.object({
|
|
1009
|
-
attribute: z15.literal("data-siteplane-field-id"),
|
|
1010
|
-
previewStrategy: z15.enum(["dom", "event"])
|
|
1011
|
-
}).strict();
|
|
1012
|
-
var fieldBaseSchema = z15.object({
|
|
1013
|
-
fieldId: fieldIdSchema,
|
|
1014
|
-
routeKey: siteFieldRouteKeySchema,
|
|
1015
|
-
source: sourceMappingSchema,
|
|
1016
|
-
dom: domMappingSchema.optional()
|
|
1017
|
-
}).strict();
|
|
1018
|
-
var linkFallbackSchema2 = z15.object({
|
|
1019
|
-
href: z15.string().trim().min(1),
|
|
1020
|
-
label: z15.string().trim().min(1).optional(),
|
|
1021
|
-
target: z15.enum(["_self", "_blank"]).optional()
|
|
1022
|
-
}).strict();
|
|
1023
|
-
var imageFallbackSchema = z15.object({
|
|
1024
|
-
src: z15.string().trim().min(1),
|
|
1025
|
-
alt: z15.string().trim().max(300),
|
|
1026
|
-
width: z15.number().int().positive().optional(),
|
|
1027
|
-
height: z15.number().int().positive().optional(),
|
|
1028
|
-
crop: z15.object({
|
|
1029
|
-
x: z15.number().min(0).max(100),
|
|
1030
|
-
y: z15.number().min(0).max(100),
|
|
1031
|
-
zoom: z15.number().min(1).max(4),
|
|
1032
|
-
aspectRatio: z15.number().positive().max(10)
|
|
1033
|
-
}).strict().optional()
|
|
1034
|
-
}).strict();
|
|
1035
|
-
var siteFieldContractFieldSchema = z15.discriminatedUnion("fieldType", [
|
|
1036
|
-
fieldBaseSchema.extend({
|
|
1037
|
-
fieldType: z15.literal("text"),
|
|
1038
|
-
fallback: z15.string()
|
|
1039
|
-
}),
|
|
1040
|
-
fieldBaseSchema.extend({
|
|
1041
|
-
fieldType: z15.literal("longText"),
|
|
1042
|
-
fallback: z15.string()
|
|
1043
|
-
}),
|
|
1044
|
-
fieldBaseSchema.extend({
|
|
1045
|
-
fieldType: z15.literal("link"),
|
|
1046
|
-
fallback: linkFallbackSchema2
|
|
1047
|
-
}),
|
|
1048
|
-
fieldBaseSchema.extend({
|
|
1049
|
-
fieldType: z15.literal("image"),
|
|
1050
|
-
fallback: imageFallbackSchema
|
|
1051
|
-
})
|
|
1052
|
-
]);
|
|
1053
|
-
var siteFieldContractV1Schema = z15.object({
|
|
1054
|
-
version: z15.literal(1),
|
|
1055
|
-
fieldContractVersion: semanticVersionSchema,
|
|
1056
|
-
scannerContractVersion: semanticVersionSchema,
|
|
1057
|
-
fields: z15.array(siteFieldContractFieldSchema)
|
|
1058
|
-
}).strict().superRefine((contract, context) => {
|
|
1059
|
-
const seen = /* @__PURE__ */ new Set();
|
|
1060
|
-
for (const [index, field] of contract.fields.entries()) {
|
|
1061
|
-
if (seen.has(field.fieldId)) {
|
|
1062
|
-
context.addIssue({
|
|
1063
|
-
code: "custom",
|
|
1064
|
-
message: `Duplicate field id: ${field.fieldId}`,
|
|
1065
|
-
path: ["fields", index, "fieldId"]
|
|
1066
|
-
});
|
|
1067
|
-
}
|
|
1068
|
-
seen.add(field.fieldId);
|
|
1069
|
-
}
|
|
1070
|
-
});
|
|
1071
|
-
|
|
1072
|
-
// ../shared/dist/site-setup.js
|
|
1073
|
-
var SITE_SETUP_RUN_STATUSES = [
|
|
1074
|
-
"waiting_for_agent",
|
|
1075
|
-
"working",
|
|
1076
|
-
"action_required",
|
|
1077
|
-
"ready_for_review",
|
|
1078
|
-
"completed"
|
|
1079
|
-
];
|
|
1080
|
-
var SITE_SETUP_RUN_MODES = ["initial", "update"];
|
|
1081
|
-
var SITE_SETUP_ERROR_CODES = [
|
|
1082
|
-
"action_required",
|
|
1083
|
-
"deployment_evidence_required",
|
|
1084
|
-
"field_contract_scan_failed",
|
|
1085
|
-
"invalid_editor_definition",
|
|
1086
|
-
"invalid_field_contract",
|
|
1087
|
-
"missing_build_revision",
|
|
1088
|
-
"missing_field_contract",
|
|
1089
|
-
"review_locked",
|
|
1090
|
-
"stale_deployment_contract",
|
|
1091
|
-
"stale_field_contract",
|
|
1092
|
-
"stale_setup_review",
|
|
1093
|
-
"update_required"
|
|
1094
|
-
];
|
|
1095
|
-
var CONTINUE_SITE_SETUP_MAX_ITEMS = 50;
|
|
1096
|
-
var CONTINUE_SITE_SETUP_RENDERED_PATH_MAX_BYTES = 512;
|
|
1097
|
-
var CONTINUE_SITE_SETUP_VISIBLE_VALUE_MAX_BYTES = 256;
|
|
1098
|
-
var CONTINUE_SITE_SETUP_LOCATOR_HINT_MAX_BYTES = 512;
|
|
1099
|
-
var CONTINUE_SITE_SETUP_REQUESTED_LABEL_MAX_BYTES = 120;
|
|
1100
|
-
var CONTINUE_SITE_SETUP_REQUESTED_SECTION_MAX_BYTES = 120;
|
|
1101
|
-
var CONTINUE_SITE_SETUP_REQUESTED_SUBSECTION_MAX_BYTES = 120;
|
|
1102
|
-
var SITE_SETUP_OWNER_EDITABILITY_NOTE_MAX_LENGTH = 2e3;
|
|
1103
|
-
var SITE_SETUP_OWNER_EDITABILITY_NOTE_MAX_BYTES = 8e3;
|
|
1104
|
-
var CONTINUE_SITE_SETUP_ITEMS_MAX_BYTES = 32 * 1024;
|
|
1105
|
-
var CONTINUE_SITE_SETUP_HTTP_BODY_MAX_BYTES = 64 * 1024;
|
|
1106
|
-
var siteSetupRunStatusSchema = z16.enum(SITE_SETUP_RUN_STATUSES);
|
|
1107
|
-
var siteSetupRunModeSchema = z16.enum(SITE_SETUP_RUN_MODES);
|
|
1108
|
-
var siteSetupErrorCodeSchema = z16.enum(SITE_SETUP_ERROR_CODES);
|
|
1109
|
-
var editorFieldSchema = z16.object({
|
|
1110
|
-
fieldId: fieldIdSchema,
|
|
1111
|
-
label: z16.string().trim().min(1),
|
|
1112
|
-
subsection: z16.string().trim().min(1).optional(),
|
|
1113
|
-
description: z16.string().trim().min(1).optional(),
|
|
1114
|
-
required: z16.boolean().optional(),
|
|
1115
|
-
maxLength: z16.number().int().positive().optional()
|
|
1116
|
-
}).strict();
|
|
1117
|
-
var editorSectionSchema = z16.object({
|
|
1118
|
-
label: z16.string().trim().min(1),
|
|
1119
|
-
fields: z16.array(editorFieldSchema).min(1)
|
|
1120
|
-
}).strict().superRefine((section, context) => {
|
|
1121
|
-
const closedSubsections = /* @__PURE__ */ new Set();
|
|
1122
|
-
let currentSubsection;
|
|
1123
|
-
for (const [index, field] of section.fields.entries()) {
|
|
1124
|
-
if (field.subsection === currentSubsection)
|
|
1125
|
-
continue;
|
|
1126
|
-
if (currentSubsection)
|
|
1127
|
-
closedSubsections.add(currentSubsection);
|
|
1128
|
-
currentSubsection = field.subsection;
|
|
1129
|
-
if (currentSubsection && closedSubsections.has(currentSubsection)) {
|
|
1130
|
-
context.addIssue({
|
|
1131
|
-
code: "custom",
|
|
1132
|
-
message: `Subgroup fields must stay contiguous: ${currentSubsection}`,
|
|
1133
|
-
path: ["fields", index, "subsection"]
|
|
1134
|
-
});
|
|
1135
|
-
}
|
|
1136
|
-
}
|
|
1137
|
-
});
|
|
1138
|
-
var editorRouteSchema = z16.object({
|
|
1139
|
-
routeKey: siteFieldRouteKeySchema,
|
|
1140
|
-
previewPath: z16.string().trim().refine((path) => path.startsWith("/") && !path.startsWith("//") && !/[\\\[\]?#\s]/u.test(path) && (path === "/" || !path.endsWith("/")), "previewPath must be a concrete same-site path, for example /services/consultation.").optional(),
|
|
1141
|
-
label: z16.string().trim().min(1),
|
|
1142
|
-
sections: z16.array(editorSectionSchema).min(1)
|
|
1143
|
-
}).strict().superRefine((route, context) => {
|
|
1144
|
-
if (route.routeKey.includes("[") && !route.previewPath) {
|
|
1145
|
-
context.addIssue({
|
|
1146
|
-
code: "custom",
|
|
1147
|
-
path: ["previewPath"],
|
|
1148
|
-
message: "Dynamic editor routes need a previewPath for an existing page; keep the canonical routeKey unchanged."
|
|
1149
|
-
});
|
|
1150
|
-
}
|
|
1151
|
-
const sections = /* @__PURE__ */ new Set();
|
|
1152
|
-
for (const [index, section] of route.sections.entries()) {
|
|
1153
|
-
if (sections.has(section.label)) {
|
|
1154
|
-
context.addIssue({
|
|
1155
|
-
code: "custom",
|
|
1156
|
-
message: `Duplicate section label: ${section.label}`,
|
|
1157
|
-
path: ["sections", index, "label"]
|
|
1158
|
-
});
|
|
1159
|
-
}
|
|
1160
|
-
sections.add(section.label);
|
|
1161
|
-
}
|
|
1162
|
-
});
|
|
1163
|
-
var editorDefinitionV1Schema = z16.object({
|
|
1164
|
-
version: z16.literal(1),
|
|
1165
|
-
routes: z16.array(editorRouteSchema).min(1)
|
|
1166
|
-
}).strict().superRefine((definition, context) => {
|
|
1167
|
-
const routes = /* @__PURE__ */ new Set();
|
|
1168
|
-
const fields = /* @__PURE__ */ new Set();
|
|
1169
|
-
for (const [routeIndex, route] of definition.routes.entries()) {
|
|
1170
|
-
if (routes.has(route.routeKey)) {
|
|
1171
|
-
context.addIssue({
|
|
1172
|
-
code: "custom",
|
|
1173
|
-
message: `Duplicate route key: ${route.routeKey}`,
|
|
1174
|
-
path: ["routes", routeIndex, "routeKey"]
|
|
1175
|
-
});
|
|
1176
|
-
}
|
|
1177
|
-
routes.add(route.routeKey);
|
|
1178
|
-
for (const [sectionIndex, section] of route.sections.entries()) {
|
|
1179
|
-
for (const [fieldIndex, field] of section.fields.entries()) {
|
|
1180
|
-
if (fields.has(field.fieldId)) {
|
|
1181
|
-
context.addIssue({
|
|
1182
|
-
code: "custom",
|
|
1183
|
-
message: `Duplicate editor field id: ${field.fieldId}`,
|
|
1184
|
-
path: [
|
|
1185
|
-
"routes",
|
|
1186
|
-
routeIndex,
|
|
1187
|
-
"sections",
|
|
1188
|
-
sectionIndex,
|
|
1189
|
-
"fields",
|
|
1190
|
-
fieldIndex,
|
|
1191
|
-
"fieldId"
|
|
1192
|
-
]
|
|
1193
|
-
});
|
|
1194
|
-
}
|
|
1195
|
-
fields.add(field.fieldId);
|
|
1196
|
-
}
|
|
1197
|
-
}
|
|
1198
|
-
}
|
|
1199
|
-
});
|
|
1200
|
-
var forbiddenControlOrBidi = /[\u0000-\u001f\u007f-\u009f\u202a-\u202e\u2066-\u2069]/u;
|
|
1201
|
-
var forbiddenOwnerNoteControlOrBidi = /[\u0000-\u0008\u000b\u000c\u000e-\u001f\u007f-\u009f\u202a-\u202e\u2066-\u2069]/u;
|
|
1202
|
-
var unsafeLocator = /<\/?[a-z][^>]*>|\b(?:javascript|data:text\/html)\s*:|\bon[a-z]+\s*=/iu;
|
|
1203
|
-
var renderedPathSchema = z16.string().trim().transform((value) => value !== "/" ? value.replace(/\/+$/u, "") : value).superRefine((value, context) => {
|
|
1204
|
-
if (!value.startsWith("/") || value === "$global" || value.includes("?") || value.includes("#")) {
|
|
1205
|
-
context.addIssue({
|
|
1206
|
-
code: "custom",
|
|
1207
|
-
message: "renderedPath must be a canonical real path."
|
|
1208
|
-
});
|
|
1209
|
-
}
|
|
1210
|
-
addSafeByteIssues(value, CONTINUE_SITE_SETUP_RENDERED_PATH_MAX_BYTES, "renderedPath", context);
|
|
1211
|
-
});
|
|
1212
|
-
function normalizedSafeTextSchema(maxBytes, label) {
|
|
1213
|
-
return z16.string().transform((value) => value.trim().replace(new RegExp("\\p{White_Space}+", "gu"), " ")).pipe(z16.string().min(1)).superRefine((value, context) => {
|
|
1214
|
-
addSafeByteIssues(value, maxBytes, label, context);
|
|
1215
|
-
if (label === "locatorHint" && unsafeLocator.test(value)) {
|
|
1216
|
-
context.addIssue({
|
|
1217
|
-
code: "custom",
|
|
1218
|
-
message: "locatorHint contains unsafe markup or executable content."
|
|
1219
|
-
});
|
|
1220
|
-
}
|
|
1221
|
-
});
|
|
1222
|
-
}
|
|
1223
|
-
var correctionItemBase = {
|
|
1224
|
-
renderedPath: renderedPathSchema,
|
|
1225
|
-
visibleValue: normalizedSafeTextSchema(CONTINUE_SITE_SETUP_VISIBLE_VALUE_MAX_BYTES, "visibleValue"),
|
|
1226
|
-
locatorHint: normalizedSafeTextSchema(CONTINUE_SITE_SETUP_LOCATOR_HINT_MAX_BYTES, "locatorHint"),
|
|
1227
|
-
requestedLabel: normalizedSafeTextSchema(CONTINUE_SITE_SETUP_REQUESTED_LABEL_MAX_BYTES, "requestedLabel").optional(),
|
|
1228
|
-
requestedSection: normalizedSafeTextSchema(CONTINUE_SITE_SETUP_REQUESTED_SECTION_MAX_BYTES, "requestedSection").optional(),
|
|
1229
|
-
requestedSubsection: normalizedSafeTextSchema(CONTINUE_SITE_SETUP_REQUESTED_SUBSECTION_MAX_BYTES, "requestedSubsection").optional(),
|
|
1230
|
-
requestedSortOrder: z16.number().int().nonnegative().optional()
|
|
1231
|
-
};
|
|
1232
|
-
var setupCorrectionItemSchema = z16.discriminatedUnion("kind", [
|
|
1233
|
-
z16.object({ kind: z16.literal("text"), ...correctionItemBase }).strict(),
|
|
1234
|
-
z16.object({ kind: z16.literal("link"), ...correctionItemBase }).strict(),
|
|
1235
|
-
z16.object({ kind: z16.literal("image"), ...correctionItemBase }).strict()
|
|
1236
|
-
]).superRefine((item, context) => {
|
|
1237
|
-
if (item.requestedSubsection && !item.requestedSection) {
|
|
1238
|
-
context.addIssue({
|
|
1239
|
-
code: "custom",
|
|
1240
|
-
message: "requestedSubsection requires requestedSection.",
|
|
1241
|
-
path: ["requestedSubsection"]
|
|
1242
|
-
});
|
|
1243
|
-
}
|
|
1244
|
-
});
|
|
1245
|
-
var setupCorrectionItemsSchema = z16.array(setupCorrectionItemSchema).max(CONTINUE_SITE_SETUP_MAX_ITEMS).superRefine((items, context) => {
|
|
1246
|
-
const bytes = utf8Bytes(stableJsonStringify(items));
|
|
1247
|
-
if (bytes > CONTINUE_SITE_SETUP_ITEMS_MAX_BYTES) {
|
|
1248
|
-
context.addIssue({
|
|
1249
|
-
code: "custom",
|
|
1250
|
-
message: "Correction items exceed the 32 KiB canonical payload limit."
|
|
1251
|
-
});
|
|
1252
|
-
}
|
|
1253
|
-
});
|
|
1254
|
-
var siteSetupOwnerEditabilityNoteSchema = z16.string().max(SITE_SETUP_OWNER_EDITABILITY_NOTE_MAX_LENGTH).superRefine((value, context) => {
|
|
1255
|
-
if (utf8Bytes(value) > SITE_SETUP_OWNER_EDITABILITY_NOTE_MAX_BYTES) {
|
|
1256
|
-
context.addIssue({
|
|
1257
|
-
code: "custom",
|
|
1258
|
-
message: `ownerEditabilityNote exceeds ${SITE_SETUP_OWNER_EDITABILITY_NOTE_MAX_BYTES} UTF-8 bytes.`
|
|
1259
|
-
});
|
|
1260
|
-
}
|
|
1261
|
-
if (forbiddenOwnerNoteControlOrBidi.test(value)) {
|
|
1262
|
-
context.addIssue({
|
|
1263
|
-
code: "custom",
|
|
1264
|
-
message: "ownerEditabilityNote contains a forbidden control or bidi character."
|
|
1265
|
-
});
|
|
1266
|
-
}
|
|
1267
|
-
});
|
|
1268
|
-
var SITE_SETUP_MODULE_SCOPES = {
|
|
1269
|
-
editing: ["setup:read", "setup:write"],
|
|
1270
|
-
analytics: [
|
|
1271
|
-
"analytics:setup",
|
|
1272
|
-
"analytics:sync",
|
|
1273
|
-
"analytics:test",
|
|
1274
|
-
"analytics:readiness",
|
|
1275
|
-
"analytics:agent_instructions",
|
|
1276
|
-
"analytics:public_key_read"
|
|
1277
|
-
]
|
|
1278
|
-
};
|
|
1279
|
-
var siteSetupModulesSchema = z16.array(z16.enum(["editing", "analytics"])).min(1).max(2).refine((modules) => modules[0] === "editing" && (modules.length === 1 || modules[1] === "analytics"), "Choose Editing with optional Analytics.");
|
|
1280
|
-
function siteSetupScopes(modules) {
|
|
1281
|
-
return modules.flatMap((module) => [...SITE_SETUP_MODULE_SCOPES[module]]);
|
|
1282
|
-
}
|
|
1283
|
-
function hasExactSiteSetupScopes(scopes, modules) {
|
|
1284
|
-
const matches = (expected) => scopes.length === expected.length && expected.every((scope) => scopes.includes(scope));
|
|
1285
|
-
return modules ? matches(siteSetupScopes(modules)) : matches(siteSetupScopes(["editing"])) || matches(siteSetupScopes(["editing", "analytics"]));
|
|
1286
|
-
}
|
|
1287
|
-
var siteSetupActivityInputSchema = z16.object({
|
|
1288
|
-
phase: z16.enum([
|
|
1289
|
-
"inspecting",
|
|
1290
|
-
"integrating",
|
|
1291
|
-
"deploying",
|
|
1292
|
-
"verifying",
|
|
1293
|
-
"repairing"
|
|
1294
|
-
]),
|
|
1295
|
-
textId: z16.enum([
|
|
1296
|
-
"inspecting",
|
|
1297
|
-
"integrating",
|
|
1298
|
-
"deploying",
|
|
1299
|
-
"verifying",
|
|
1300
|
-
"repairing"
|
|
1301
|
-
])
|
|
1302
|
-
}).strict().refine((value) => value.phase === value.textId, "Activity text must describe its phase.");
|
|
1303
|
-
var nextActionFields = {
|
|
1304
|
-
actor: z16.enum(["agent", "user", "siteplane"]),
|
|
1305
|
-
boundary: z16.enum([
|
|
1306
|
-
"source",
|
|
1307
|
-
"environment",
|
|
1308
|
-
"deployment",
|
|
1309
|
-
"verification",
|
|
1310
|
-
"authorization",
|
|
1311
|
-
"review"
|
|
1312
|
-
]),
|
|
1313
|
-
precondition: z16.string().min(1).max(1e3),
|
|
1314
|
-
instruction: z16.string().min(1).max(2e3),
|
|
1315
|
-
expectedEvidence: z16.string().min(1).max(1e3)
|
|
1316
|
-
};
|
|
1317
|
-
var siteSetupNextActionSchema = z16.discriminatedUnion("kind", [
|
|
1318
|
-
z16.object({
|
|
1319
|
-
...nextActionFields,
|
|
1320
|
-
kind: z16.literal("run_command"),
|
|
1321
|
-
command: z16.string().min(1).max(500)
|
|
1322
|
-
}).strict(),
|
|
1323
|
-
z16.object({ ...nextActionFields, kind: z16.literal("agent_edit") }).strict(),
|
|
1324
|
-
z16.object({ ...nextActionFields, kind: z16.literal("needs_user_action") }).strict(),
|
|
1325
|
-
z16.object({ ...nextActionFields, kind: z16.literal("wait") }).strict(),
|
|
1326
|
-
z16.object({ ...nextActionFields, kind: z16.literal("done") }).strict()
|
|
1327
|
-
]);
|
|
1328
|
-
var siteSetupTaskRunSchema = z16.object({
|
|
1329
|
-
runId: z16.string().uuid(),
|
|
1330
|
-
mode: siteSetupRunModeSchema,
|
|
1331
|
-
status: siteSetupRunStatusSchema,
|
|
1332
|
-
fieldContractHash: z16.string().nullable(),
|
|
1333
|
-
deploymentOrigin: z16.string().url().nullable(),
|
|
1334
|
-
deploymentRevision: z16.string().nullable(),
|
|
1335
|
-
publicRuntimeKeyId: z16.string().uuid().nullable(),
|
|
1336
|
-
reviewVersion: z16.number().int().positive()
|
|
1337
|
-
}).strict();
|
|
1338
|
-
var siteSetupTaskProgressSchema = z16.object({
|
|
1339
|
-
progressStage: z16.enum([
|
|
1340
|
-
"waiting_for_connection",
|
|
1341
|
-
"agent_connected",
|
|
1342
|
-
"project_context_loaded",
|
|
1343
|
-
"fields_prepared",
|
|
1344
|
-
"deployment_verification",
|
|
1345
|
-
"ready_for_review",
|
|
1346
|
-
"action_required",
|
|
1347
|
-
"completed"
|
|
1348
|
-
]),
|
|
1349
|
-
lastVerifiedAt: z16.string().datetime().nullable(),
|
|
1350
|
-
lastActivityAt: z16.string().datetime(),
|
|
1351
|
-
activitySource: z16.enum(["user", "server", "agent"]),
|
|
1352
|
-
activityPhase: siteSetupActivityInputSchema.shape.phase.nullable(),
|
|
1353
|
-
activityTextId: siteSetupActivityInputSchema.shape.textId.nullable()
|
|
1354
|
-
}).strict();
|
|
1355
|
-
var siteSetupTaskSchema = z16.object({
|
|
1356
|
-
contractVersion: z16.literal("siteplane.setup-task.v2"),
|
|
1357
|
-
workflow: z16.enum(["initial_setup", "structure_update"]),
|
|
1358
|
-
goal: z16.string().min(1),
|
|
1359
|
-
modules: siteSetupModulesSchema,
|
|
1360
|
-
authorizationVersion: z16.number().int().positive(),
|
|
1361
|
-
authorizedScopes: z16.array(z16.string()).min(2),
|
|
1362
|
-
site: z16.object({
|
|
1363
|
-
siteId: z16.string().uuid(),
|
|
1364
|
-
portalPath: z16.string(),
|
|
1365
|
-
adminOrigin: z16.string().url()
|
|
1366
|
-
}).strict().nullable(),
|
|
1367
|
-
run: siteSetupTaskRunSchema.nullable(),
|
|
1368
|
-
progress: siteSetupTaskProgressSchema.nullable(),
|
|
1369
|
-
deployment: setupDeploymentRecordSchema.nullable(),
|
|
1370
|
-
revalidationGeneration: z16.number().int().positive(),
|
|
1371
|
-
assignment: z16.enum(["owned", "provisional", "claimed"]),
|
|
1372
|
-
deadline: z16.string().datetime().nullable(),
|
|
1373
|
-
userInstructions: z16.object({
|
|
1374
|
-
text: siteSetupOwnerEditabilityNoteSchema,
|
|
1375
|
-
source: z16.literal("user"),
|
|
1376
|
-
trust: z16.literal("untrusted")
|
|
1377
|
-
}).strict(),
|
|
1378
|
-
corrections: setupCorrectionItemsSchema,
|
|
1379
|
-
contentSelectionSummary: z16.object({
|
|
1380
|
-
text: siteSetupOwnerEditabilityNoteSchema,
|
|
1381
|
-
source: z16.literal("agent"),
|
|
1382
|
-
trust: z16.literal("untrusted")
|
|
1383
|
-
}).strict().nullable(),
|
|
1384
|
-
environmentBindings: z16.array(z16.object({
|
|
1385
|
-
name: z16.string().regex(/^[A-Z][A-Z0-9_]+$/u),
|
|
1386
|
-
source: z16.string().min(1),
|
|
1387
|
-
sensitivity: z16.enum(["public", "secret"]),
|
|
1388
|
-
usage: z16.enum(["build", "server", "build_and_server"]),
|
|
1389
|
-
evidence: z16.string().min(1)
|
|
1390
|
-
}).strict()),
|
|
1391
|
-
nextAction: siteSetupNextActionSchema,
|
|
1392
|
-
error: z16.object({
|
|
1393
|
-
code: z16.string().regex(/^[a-z0-9_.]+$/u).max(160),
|
|
1394
|
-
boundary: nextActionFields.boundary,
|
|
1395
|
-
responsibleActor: nextActionFields.actor,
|
|
1396
|
-
retryable: z16.boolean(),
|
|
1397
|
-
retryAfter: z16.number().int().nonnegative().nullable(),
|
|
1398
|
-
requestId: z16.string().regex(/^[A-Za-z0-9_-]+$/u).max(128)
|
|
1399
|
-
}).strict().nullable(),
|
|
1400
|
-
packages: siteSetupPackagesSchema,
|
|
1401
|
-
communication: z16.object({
|
|
1402
|
-
beforeSourceChanges: z16.string().min(1),
|
|
1403
|
-
updates: z16.array(z16.string().min(1)).min(1),
|
|
1404
|
-
blocker: z16.string().min(1)
|
|
1405
|
-
}).strict(),
|
|
1406
|
-
discovery: z16.object({
|
|
1407
|
-
inspectPublicRoutes: z16.boolean(),
|
|
1408
|
-
contentKinds: z16.array(z16.enum(["text", "longText", "link", "image"])).min(1),
|
|
1409
|
-
rules: z16.array(z16.string().min(1)).min(1)
|
|
1410
|
-
}).strict(),
|
|
1411
|
-
steps: z16.array(z16.object({
|
|
1412
|
-
id: z16.enum([
|
|
1413
|
-
"inspect_repository",
|
|
1414
|
-
"install_packages",
|
|
1415
|
-
"instrument_fields",
|
|
1416
|
-
"apply_contract",
|
|
1417
|
-
"deploy_production",
|
|
1418
|
-
"verify_deployment"
|
|
1419
|
-
]),
|
|
1420
|
-
instruction: z16.string().min(1)
|
|
1421
|
-
}).strict()).length(6),
|
|
1422
|
-
completion: z16.object({
|
|
1423
|
-
verifiedStatus: z16.literal("ready_for_review"),
|
|
1424
|
-
instruction: z16.string().min(1)
|
|
1425
|
-
}).strict()
|
|
1426
|
-
}).strict().refine((task) => hasExactSiteSetupScopes(task.authorizedScopes, task.modules), "Task scopes must exactly match its modules.").refine((task) => task.modules.includes("analytics") === (task.packages.analytics !== void 0), "The Analytics package pin must be present exactly when Analytics is selected.");
|
|
1427
|
-
var canonicalHashSchema = z16.string().regex(/^sha256:[0-9a-f]{64}$/iu);
|
|
1428
|
-
var deploymentRevisionSchema = normalizedSafeTextSchema(256, "deploymentRevision");
|
|
1429
|
-
var continueSiteSetupInputSchema = z16.object({
|
|
1430
|
-
siteId: z16.string().uuid(),
|
|
1431
|
-
runId: z16.string().uuid(),
|
|
1432
|
-
expectedReviewVersion: z16.number().int().positive(),
|
|
1433
|
-
mutationId: z16.string().uuid(),
|
|
1434
|
-
intent: z16.enum(["continue_review", "correct_completed_review"]),
|
|
1435
|
-
expectedFieldContractHash: canonicalHashSchema,
|
|
1436
|
-
expectedDeploymentRevision: deploymentRevisionSchema,
|
|
1437
|
-
correctionItems: setupCorrectionItemsSchema,
|
|
1438
|
-
ownerEditabilityNote: siteSetupOwnerEditabilityNoteSchema.optional()
|
|
1439
|
-
}).strict();
|
|
1440
|
-
var saveSiteSetupOwnerNoteInputSchema = z16.object({
|
|
1441
|
-
siteId: z16.string().uuid(),
|
|
1442
|
-
runId: z16.string().uuid(),
|
|
1443
|
-
expectedReviewVersion: z16.number().int().positive(),
|
|
1444
|
-
expectedFieldContractHash: canonicalHashSchema,
|
|
1445
|
-
expectedDeploymentRevision: deploymentRevisionSchema,
|
|
1446
|
-
ownerEditabilityNote: siteSetupOwnerEditabilityNoteSchema
|
|
1447
|
-
}).strict();
|
|
1448
|
-
var setupReviewPreferenceSelectionSchema = z16.object({
|
|
1449
|
-
analyticsMode: z16.enum(["disabled", "session_only"]).nullable(),
|
|
1450
|
-
assetTargetType: z16.enum(["repo_static_assets", "siteplane_managed_fallback"]).nullable(),
|
|
1451
|
-
assetTargetId: z16.string().uuid().nullable()
|
|
1452
|
-
}).strict().refine((value) => value.assetTargetType !== null || value.assetTargetId === null, {
|
|
1453
|
-
message: "An asset target requires its delivery type."
|
|
1454
|
-
});
|
|
1455
|
-
var setupReviewPreferencesSchema = setupReviewPreferenceSelectionSchema.safeExtend({
|
|
1456
|
-
managedHostingApproved: z16.boolean()
|
|
1457
|
-
});
|
|
1458
|
-
var saveSetupReviewPreferencesInputSchema = z16.object({
|
|
1459
|
-
siteId: z16.string().uuid(),
|
|
1460
|
-
runId: z16.string().uuid(),
|
|
1461
|
-
expectedReviewVersion: z16.number().int().positive(),
|
|
1462
|
-
preferences: setupReviewPreferenceSelectionSchema
|
|
1463
|
-
}).strict();
|
|
1464
|
-
var siteSetupContextInputSchema = z16.object({}).strict();
|
|
1465
|
-
var siteSetupApplyInputSchema = z16.object({
|
|
1466
|
-
fieldContract: siteFieldContractV1Schema,
|
|
1467
|
-
editorDefinition: editorDefinitionV1Schema,
|
|
1468
|
-
contentSelectionSummary: siteSetupOwnerEditabilityNoteSchema.refine((text) => text.trim().length > 0, "Describe the selected content, important exclusions and any open gaps.")
|
|
1469
|
-
}).strict().superRefine((input, context) => {
|
|
1470
|
-
const contractRoutesByFieldId = new Map(input.fieldContract.fields.map((field) => [
|
|
1471
|
-
field.fieldId,
|
|
1472
|
-
field.routeKey
|
|
1473
|
-
]));
|
|
1474
|
-
const definitionFieldIds = /* @__PURE__ */ new Set();
|
|
1475
|
-
for (const [routeIndex, route] of input.editorDefinition.routes.entries()) {
|
|
1476
|
-
for (const [sectionIndex, section] of route.sections.entries()) {
|
|
1477
|
-
for (const [fieldIndex, field] of section.fields.entries()) {
|
|
1478
|
-
const fieldPath = [
|
|
1479
|
-
"editorDefinition",
|
|
1480
|
-
"routes",
|
|
1481
|
-
routeIndex,
|
|
1482
|
-
"sections",
|
|
1483
|
-
sectionIndex,
|
|
1484
|
-
"fields",
|
|
1485
|
-
fieldIndex,
|
|
1486
|
-
"fieldId"
|
|
1487
|
-
];
|
|
1488
|
-
const contractRouteKey = contractRoutesByFieldId.get(field.fieldId);
|
|
1489
|
-
const contractField = input.fieldContract.fields.find((candidate) => candidate.fieldId === field.fieldId);
|
|
1490
|
-
definitionFieldIds.add(field.fieldId);
|
|
1491
|
-
if (!contractRouteKey) {
|
|
1492
|
-
context.addIssue({
|
|
1493
|
-
code: "custom",
|
|
1494
|
-
message: `Unknown editor field id: ${field.fieldId}`,
|
|
1495
|
-
path: fieldPath
|
|
1496
|
-
});
|
|
1497
|
-
} else if (contractRouteKey !== route.routeKey) {
|
|
1498
|
-
context.addIssue({
|
|
1499
|
-
code: "custom",
|
|
1500
|
-
message: `Editor field ${field.fieldId} must use route ${contractRouteKey}.`,
|
|
1501
|
-
path: fieldPath
|
|
1502
|
-
});
|
|
1503
|
-
} else if (field.maxLength !== void 0 && contractField?.fieldType !== "text" && contractField?.fieldType !== "longText") {
|
|
1504
|
-
context.addIssue({
|
|
1505
|
-
code: "custom",
|
|
1506
|
-
message: `maxLength is not supported for ${contractField?.fieldType ?? "unknown"} fields.`,
|
|
1507
|
-
path: [
|
|
1508
|
-
"editorDefinition",
|
|
1509
|
-
"routes",
|
|
1510
|
-
routeIndex,
|
|
1511
|
-
"sections",
|
|
1512
|
-
sectionIndex,
|
|
1513
|
-
"fields",
|
|
1514
|
-
fieldIndex,
|
|
1515
|
-
"maxLength"
|
|
1516
|
-
]
|
|
1517
|
-
});
|
|
1518
|
-
}
|
|
1519
|
-
}
|
|
1520
|
-
}
|
|
1521
|
-
}
|
|
1522
|
-
for (const field of input.fieldContract.fields) {
|
|
1523
|
-
if (!definitionFieldIds.has(field.fieldId)) {
|
|
1524
|
-
context.addIssue({
|
|
1525
|
-
code: "custom",
|
|
1526
|
-
message: `Missing editor field id: ${field.fieldId}`,
|
|
1527
|
-
path: ["editorDefinition", "routes"]
|
|
1528
|
-
});
|
|
1529
|
-
}
|
|
1530
|
-
}
|
|
1531
|
-
});
|
|
1532
|
-
var siteSetupVerifyInputSchema = z16.object({
|
|
1533
|
-
deploymentUrl: z16.string().url().refine((value) => value.startsWith("https://")),
|
|
1534
|
-
deploymentRevision: deploymentRevisionSchema,
|
|
1535
|
-
wait: z16.boolean().optional()
|
|
1536
|
-
}).strict();
|
|
1537
|
-
var siteSetupEvidenceInputSchema = z16.object({
|
|
1538
|
-
siteId: z16.string().uuid(),
|
|
1539
|
-
runId: z16.string().uuid(),
|
|
1540
|
-
expectedFieldContractHash: canonicalHashSchema,
|
|
1541
|
-
expectedDeploymentOrigin: z16.string().url().refine((value) => value.startsWith("https://")),
|
|
1542
|
-
expectedDeploymentRevision: deploymentRevisionSchema,
|
|
1543
|
-
publicRuntimeKeyId: z16.string().uuid(),
|
|
1544
|
-
bridgeSessionId: normalizedSafeTextSchema(256, "bridgeSessionId"),
|
|
1545
|
-
observations: z16.array(z16.object({
|
|
1546
|
-
fieldId: fieldIdSchema,
|
|
1547
|
-
fieldType: fieldTypeSchema,
|
|
1548
|
-
routeKey: siteFieldRouteKeySchema,
|
|
1549
|
-
renderedPath: renderedPathSchema,
|
|
1550
|
-
targetResolved: z16.boolean(),
|
|
1551
|
-
previewAck: z16.boolean()
|
|
1552
|
-
}).strict().refine((value) => !value.previewAck || value.targetResolved, "Preview ACK requires a resolved target.")).min(1).max(200)
|
|
1553
|
-
}).strict();
|
|
1554
|
-
var completeSetupReviewInputSchema = z16.object({
|
|
1555
|
-
siteId: z16.string().uuid(),
|
|
1556
|
-
runId: z16.string().uuid(),
|
|
1557
|
-
expectedReviewVersion: z16.number().int().positive(),
|
|
1558
|
-
expectedFieldContractHash: canonicalHashSchema,
|
|
1559
|
-
expectedDeploymentRevision: deploymentRevisionSchema,
|
|
1560
|
-
expectedReadyFingerprint: canonicalHashSchema
|
|
1561
|
-
}).strict();
|
|
1562
|
-
var activateSiteSetupInputSchema = z16.object({
|
|
1563
|
-
siteId: z16.string().uuid(),
|
|
1564
|
-
runId: z16.string().uuid(),
|
|
1565
|
-
expectedReviewVersion: z16.number().int().positive(),
|
|
1566
|
-
expectedSnapshotHash: canonicalHashSchema
|
|
1567
|
-
}).strict();
|
|
1568
|
-
var refreshSiteSetupDeploymentInputSchema = z16.object({
|
|
1569
|
-
siteId: z16.string().uuid(),
|
|
1570
|
-
deploymentUrl: z16.string().url().refine((value) => value.startsWith("https://")),
|
|
1571
|
-
deploymentRevision: deploymentRevisionSchema
|
|
1572
|
-
}).strict();
|
|
1573
|
-
function addSafeByteIssues(value, maxBytes, label, context) {
|
|
1574
|
-
if (utf8Bytes(value) > maxBytes) {
|
|
1575
|
-
context.addIssue({
|
|
1576
|
-
code: "custom",
|
|
1577
|
-
message: `${label} exceeds ${maxBytes} UTF-8 bytes.`
|
|
1578
|
-
});
|
|
1579
|
-
}
|
|
1580
|
-
if (forbiddenControlOrBidi.test(value)) {
|
|
1581
|
-
context.addIssue({
|
|
1582
|
-
code: "custom",
|
|
1583
|
-
message: `${label} contains a forbidden control or bidi character.`
|
|
1584
|
-
});
|
|
1585
|
-
}
|
|
1586
|
-
}
|
|
1587
|
-
function utf8Bytes(value) {
|
|
1588
|
-
return new TextEncoder().encode(value).byteLength;
|
|
1589
|
-
}
|
|
1590
|
-
var setupActivationApprovalSchema = z16.object({
|
|
1591
|
-
reviewVersion: z16.number().int().positive(),
|
|
1592
|
-
snapshotHash: canonicalHashSchema,
|
|
1593
|
-
analytics: z16.object({
|
|
1594
|
-
status: z16.enum(["active", "skipped"]),
|
|
1595
|
-
reviewVersion: z16.number().int().positive(),
|
|
1596
|
-
generation: z16.number().int().nonnegative()
|
|
1597
|
-
}).optional()
|
|
1598
|
-
});
|
|
1599
|
-
var activateSetupModulesInputSchema = activateSiteSetupInputSchema.extend({
|
|
1600
|
-
analytics: z16.discriminatedUnion("decision", [
|
|
1601
|
-
z16.object({ decision: z16.literal("pending") }).strict(),
|
|
1602
|
-
z16.object({
|
|
1603
|
-
decision: z16.literal("enable"),
|
|
1604
|
-
readinessTestRunId: z16.string().regex(/^analytics_owner_[0-9a-f-]{36}$/u),
|
|
1605
|
-
expectedInstallationGeneration: z16.number().int().positive(),
|
|
1606
|
-
measurementApproved: z16.literal(true)
|
|
1607
|
-
}).strict(),
|
|
1608
|
-
z16.object({
|
|
1609
|
-
decision: z16.literal("skip"),
|
|
1610
|
-
expectedInstallationGeneration: z16.number().int().nonnegative(),
|
|
1611
|
-
continueWithoutAnalytics: z16.literal(true)
|
|
1612
|
-
}).strict()
|
|
1613
|
-
])
|
|
1614
|
-
}).strict();
|
|
1615
|
-
|
|
1616
|
-
// ../shared/dist/bridge-protocol.js
|
|
1617
|
-
var BRIDGE_PROTOCOL_VERSION = 2;
|
|
1618
|
-
var bridgeRectSchema = z17.object({
|
|
1619
|
-
x: z17.number(),
|
|
1620
|
-
y: z17.number(),
|
|
1621
|
-
width: z17.number().nonnegative(),
|
|
1622
|
-
height: z17.number().nonnegative()
|
|
1623
|
-
});
|
|
1624
|
-
var previewTextValueSchema = z17.object({
|
|
1625
|
-
fieldType: z17.enum(["text", "longText"]),
|
|
1626
|
-
value: z17.string()
|
|
1627
|
-
});
|
|
1628
|
-
var previewLinkValueSchema = z17.object({
|
|
1629
|
-
fieldType: z17.literal("link"),
|
|
1630
|
-
value: z17.object({
|
|
1631
|
-
href: z17.string().trim().min(1),
|
|
1632
|
-
label: z17.string().trim().min(1).optional()
|
|
1633
|
-
})
|
|
1634
|
-
});
|
|
1635
|
-
var previewImageValueSchema = z17.object({
|
|
1636
|
-
fieldType: z17.literal("image"),
|
|
1637
|
-
value: imageValueSchema
|
|
1638
|
-
});
|
|
1639
|
-
var bridgePreviewValueSchema = z17.discriminatedUnion("fieldType", [
|
|
1640
|
-
previewTextValueSchema,
|
|
1641
|
-
previewLinkValueSchema,
|
|
1642
|
-
previewImageValueSchema
|
|
1643
|
-
]);
|
|
1644
|
-
var fieldSelectionModeSchema = z17.enum(["replace", "range", "toggle"]);
|
|
1645
|
-
var fieldBridgeMissingContentActionSchema = z17.enum([
|
|
1646
|
-
"add",
|
|
1647
|
-
"select",
|
|
1648
|
-
"remove"
|
|
1649
|
-
]);
|
|
1650
|
-
var FIELD_BRIDGE_MESSAGE_TYPES = [
|
|
1651
|
-
"siteplane:field-bridge:init",
|
|
1652
|
-
"siteplane:field-bridge:ready",
|
|
1653
|
-
"siteplane:field-bridge:fields",
|
|
1654
|
-
"siteplane:field-bridge:select-field",
|
|
1655
|
-
"siteplane:field-bridge:set-selected-field",
|
|
1656
|
-
"siteplane:field-bridge:apply-preview-values",
|
|
1657
|
-
"siteplane:field-bridge:test-preview-values",
|
|
1658
|
-
"siteplane:field-bridge:preview-ack",
|
|
1659
|
-
"siteplane:field-bridge:set-visual-control-state",
|
|
1660
|
-
"siteplane:field-bridge:missing-content",
|
|
1661
|
-
"siteplane:field-bridge:preview-scrolled",
|
|
1662
|
-
"siteplane:field-bridge:analytics-probe",
|
|
1663
|
-
"siteplane:field-bridge:analytics-probe-result",
|
|
1664
|
-
"siteplane:field-bridge:error"
|
|
1665
|
-
];
|
|
1666
|
-
var canonicalFieldContractHashSchema = z17.string().regex(/^sha256:[0-9a-f]{64}$/u);
|
|
1667
|
-
var bridgeSectionSchema = z17.string().trim().min(1).max(256);
|
|
1668
|
-
var realRenderedPathSchema = z17.string().trim().refine((value) => value.startsWith("/") && value !== "$global" && !value.includes("?") && !value.includes("#"), "A field bridge rendered path must be a real canonical path.");
|
|
1669
|
-
var fieldBridgeIdentitySchema = z17.object({
|
|
1670
|
-
publicRuntimeKeyId: z17.string().uuid(),
|
|
1671
|
-
fieldContractHash: canonicalFieldContractHashSchema,
|
|
1672
|
-
deploymentRevision: z17.string().trim().min(1).max(256)
|
|
1673
|
-
}).strict();
|
|
1674
|
-
var setupPreviewAccessSchema = z17.object({
|
|
1675
|
-
capability: z17.string().regex(/^v1\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]{43}$/u).max(4096),
|
|
1676
|
-
expiresAt: z17.string().datetime()
|
|
1677
|
-
}).strict();
|
|
1678
|
-
var setupPreviewReadSchema = fieldBridgeIdentitySchema.extend({
|
|
1679
|
-
scope: z17.literal("setup_preview"),
|
|
1680
|
-
siteId: z17.string().uuid(),
|
|
1681
|
-
runId: z17.string().uuid(),
|
|
1682
|
-
bridgeSessionId: z17.string().min(1),
|
|
1683
|
-
expiresAt: z17.string().datetime(),
|
|
1684
|
-
contract: siteFieldContractV1Schema
|
|
1685
|
-
}).strict();
|
|
1686
|
-
var fieldBridgeBaseSchema = z17.object({
|
|
1687
|
-
version: z17.literal(BRIDGE_PROTOCOL_VERSION),
|
|
1688
|
-
type: z17.enum(FIELD_BRIDGE_MESSAGE_TYPES),
|
|
1689
|
-
siteId: z17.string().uuid(),
|
|
1690
|
-
sessionId: z17.string().trim().min(1),
|
|
1691
|
-
publicRuntimeKeyId: z17.string().uuid(),
|
|
1692
|
-
fieldContractHash: canonicalFieldContractHashSchema,
|
|
1693
|
-
deploymentRevision: z17.string().trim().min(1).max(256),
|
|
1694
|
-
requestId: z17.string().trim().min(1),
|
|
1695
|
-
sentAt: z17.string().datetime()
|
|
1696
|
-
}).strict();
|
|
1697
|
-
var fieldBridgeFieldSchema = z17.object({
|
|
1698
|
-
fieldId: fieldIdSchema,
|
|
1699
|
-
fieldType: fieldTypeSchema,
|
|
1700
|
-
routeKey: siteFieldRouteKeySchema,
|
|
1701
|
-
renderedPath: realRenderedPathSchema,
|
|
1702
|
-
sourcePath: z17.string().trim().min(1).optional(),
|
|
1703
|
-
editTarget: fieldIdSchema,
|
|
1704
|
-
rect: bridgeRectSchema,
|
|
1705
|
-
targetResolved: z17.literal(true),
|
|
1706
|
-
currentValue: bridgePreviewValueSchema.optional()
|
|
1707
|
-
}).strict();
|
|
1708
|
-
var fieldBridgeInitMessageSchema = fieldBridgeBaseSchema.extend({
|
|
1709
|
-
type: z17.literal("siteplane:field-bridge:init"),
|
|
1710
|
-
payload: z17.object({
|
|
1711
|
-
adminOrigin: z17.string().url(),
|
|
1712
|
-
customerOrigin: z17.string().url(),
|
|
1713
|
-
renderedPath: realRenderedPathSchema,
|
|
1714
|
-
setupPreview: setupPreviewAccessSchema.optional()
|
|
1715
|
-
}).strict()
|
|
1716
|
-
});
|
|
1717
|
-
var fieldBridgeReadyMessageSchema = fieldBridgeBaseSchema.extend({
|
|
1718
|
-
type: z17.literal("siteplane:field-bridge:ready"),
|
|
1719
|
-
payload: z17.object({
|
|
1720
|
-
renderedPath: realRenderedPathSchema,
|
|
1721
|
-
fieldCount: z17.number().int().nonnegative(),
|
|
1722
|
-
capabilities: z17.tuple([
|
|
1723
|
-
z17.literal("field_selection"),
|
|
1724
|
-
z17.literal("preview_values"),
|
|
1725
|
-
z17.literal("field_evidence"),
|
|
1726
|
-
z17.literal("visual_field_control")
|
|
1727
|
-
]).rest(z17.enum(["analytics_preview_readiness", "setup_preview"])).refine((capabilities) => capabilities.length <= 6)
|
|
1728
|
-
}).strict()
|
|
1729
|
-
});
|
|
1730
|
-
var fieldBridgeFieldsMessageSchema = fieldBridgeBaseSchema.extend({
|
|
1731
|
-
type: z17.literal("siteplane:field-bridge:fields"),
|
|
1732
|
-
payload: z17.object({
|
|
1733
|
-
renderedPath: realRenderedPathSchema,
|
|
1734
|
-
fields: z17.array(fieldBridgeFieldSchema)
|
|
1735
|
-
}).strict()
|
|
1736
|
-
});
|
|
1737
|
-
var fieldBridgeSelectFieldMessageSchema = fieldBridgeBaseSchema.extend({
|
|
1738
|
-
type: z17.literal("siteplane:field-bridge:select-field"),
|
|
1739
|
-
payload: z17.object({
|
|
1740
|
-
fieldId: fieldIdSchema,
|
|
1741
|
-
selectionMode: fieldSelectionModeSchema
|
|
1742
|
-
}).strict()
|
|
1743
|
-
});
|
|
1744
|
-
var fieldBridgeSetSelectedFieldMessageSchema = fieldBridgeBaseSchema.extend({
|
|
1745
|
-
type: z17.literal("siteplane:field-bridge:set-selected-field"),
|
|
1746
|
-
payload: z17.object({
|
|
1747
|
-
fieldIds: z17.array(fieldIdSchema).max(200),
|
|
1748
|
-
primaryFieldId: fieldIdSchema.nullable(),
|
|
1749
|
-
scrollIntoView: z17.boolean().optional()
|
|
1750
|
-
}).strict().superRefine((value, context) => {
|
|
1751
|
-
if (value.fieldIds.length > 0 && value.primaryFieldId === null) {
|
|
1752
|
-
context.addIssue({
|
|
1753
|
-
code: "custom",
|
|
1754
|
-
message: "A non-empty selection needs a primary field.",
|
|
1755
|
-
path: ["primaryFieldId"]
|
|
1756
|
-
});
|
|
1757
|
-
}
|
|
1758
|
-
if (value.primaryFieldId !== null && !value.fieldIds.includes(value.primaryFieldId)) {
|
|
1759
|
-
context.addIssue({
|
|
1760
|
-
code: "custom",
|
|
1761
|
-
message: "The primary field must be part of the selection.",
|
|
1762
|
-
path: ["primaryFieldId"]
|
|
1763
|
-
});
|
|
1764
|
-
}
|
|
1765
|
-
})
|
|
1766
|
-
});
|
|
1767
|
-
var fieldBridgeApplyPreviewValuesMessageSchema = fieldBridgeBaseSchema.extend({
|
|
1768
|
-
type: z17.literal("siteplane:field-bridge:apply-preview-values"),
|
|
1769
|
-
payload: z17.object({ values: z17.record(fieldIdSchema, bridgePreviewValueSchema) }).strict()
|
|
1770
|
-
});
|
|
1771
|
-
var fieldBridgeTestPreviewValuesMessageSchema = fieldBridgeBaseSchema.extend({
|
|
1772
|
-
type: z17.literal("siteplane:field-bridge:test-preview-values"),
|
|
1773
|
-
payload: z17.object({ fieldIds: z17.array(fieldIdSchema).min(1).max(200) }).strict()
|
|
1774
|
-
});
|
|
1775
|
-
var fieldBridgePreviewAckMessageSchema = fieldBridgeBaseSchema.extend({
|
|
1776
|
-
type: z17.literal("siteplane:field-bridge:preview-ack"),
|
|
1777
|
-
payload: z17.object({
|
|
1778
|
-
ackRequestId: z17.string().trim().min(1),
|
|
1779
|
-
kind: z17.enum(["apply", "test"]),
|
|
1780
|
-
renderedPath: realRenderedPathSchema,
|
|
1781
|
-
fieldIds: z17.array(fieldIdSchema).max(200)
|
|
1782
|
-
}).strict()
|
|
1783
|
-
});
|
|
1784
|
-
var fieldBridgeSetVisualControlStateMessageSchema = fieldBridgeBaseSchema.extend({
|
|
1785
|
-
type: z17.literal("siteplane:field-bridge:set-visual-control-state"),
|
|
1786
|
-
payload: z17.object({
|
|
1787
|
-
enabled: z17.boolean(),
|
|
1788
|
-
fieldProximityEnabled: z17.boolean(),
|
|
1789
|
-
pendingKeys: z17.array(z17.string().trim().min(1).max(2048)).max(50),
|
|
1790
|
-
activeFieldIds: z17.array(fieldIdSchema),
|
|
1791
|
-
fieldSections: z17.record(fieldIdSchema, bridgeSectionSchema),
|
|
1792
|
-
selectedPending: z17.array(z17.object({
|
|
1793
|
-
key: z17.string().trim().min(1).max(2048),
|
|
1794
|
-
locatorHint: z17.string().trim().min(1).max(2048)
|
|
1795
|
-
}).strict()).max(50),
|
|
1796
|
-
scrollPendingIntoView: z17.boolean().optional()
|
|
1797
|
-
}).strict()
|
|
1798
|
-
});
|
|
1799
|
-
var fieldBridgeMissingContentMessageSchema = fieldBridgeBaseSchema.extend({
|
|
1800
|
-
type: z17.literal("siteplane:field-bridge:missing-content"),
|
|
1801
|
-
payload: z17.object({
|
|
1802
|
-
action: fieldBridgeMissingContentActionSchema,
|
|
1803
|
-
item: setupCorrectionItemSchema,
|
|
1804
|
-
suggestedSection: bridgeSectionSchema.optional()
|
|
1805
|
-
}).strict()
|
|
1806
|
-
});
|
|
1807
|
-
var fieldBridgePreviewScrolledMessageSchema = fieldBridgeBaseSchema.extend({
|
|
1808
|
-
type: z17.literal("siteplane:field-bridge:preview-scrolled"),
|
|
1809
|
-
payload: z17.object({ renderedPath: realRenderedPathSchema }).strict()
|
|
1810
|
-
});
|
|
1811
|
-
var analyticsPreviewChallengeSchema = z17.object({
|
|
1812
|
-
bridgeSessionId: z17.string().uuid(),
|
|
1813
|
-
challenge: z17.string().min(32).max(512),
|
|
1814
|
-
testRunId: z17.string().trim().min(1).max(160),
|
|
1815
|
-
expiresAt: z17.string().datetime()
|
|
1816
|
-
}).strict();
|
|
1817
|
-
var fieldBridgeAnalyticsProbeSchema = fieldBridgeBaseSchema.extend({
|
|
1818
|
-
type: z17.literal("siteplane:field-bridge:analytics-probe"),
|
|
1819
|
-
requestId: z17.string().min(1).max(256),
|
|
1820
|
-
payload: analyticsPreviewChallengeSchema
|
|
1821
|
-
});
|
|
1822
|
-
var fieldBridgeAnalyticsProbeResultSchema = fieldBridgeBaseSchema.extend({
|
|
1823
|
-
type: z17.literal("siteplane:field-bridge:analytics-probe-result"),
|
|
1824
|
-
payload: z17.object({
|
|
1825
|
-
ackRequestId: z17.string().min(1).max(256),
|
|
1826
|
-
status: z17.enum(["recorded", "failed"])
|
|
1827
|
-
}).strict()
|
|
1828
|
-
});
|
|
1829
|
-
var fieldBridgeErrorMessageSchema = fieldBridgeBaseSchema.extend({
|
|
1830
|
-
type: z17.literal("siteplane:field-bridge:error"),
|
|
1831
|
-
payload: z17.object({
|
|
1832
|
-
code: z17.string().trim().min(1),
|
|
1833
|
-
message: z17.string().trim().min(1),
|
|
1834
|
-
recoverable: z17.boolean().default(false)
|
|
1835
|
-
}).strict()
|
|
1836
|
-
});
|
|
1837
|
-
var fieldBridgeMessageSchema = z17.discriminatedUnion("type", [
|
|
1838
|
-
fieldBridgeInitMessageSchema,
|
|
1839
|
-
fieldBridgeReadyMessageSchema,
|
|
1840
|
-
fieldBridgeFieldsMessageSchema,
|
|
1841
|
-
fieldBridgeSelectFieldMessageSchema,
|
|
1842
|
-
fieldBridgeSetSelectedFieldMessageSchema,
|
|
1843
|
-
fieldBridgeApplyPreviewValuesMessageSchema,
|
|
1844
|
-
fieldBridgeTestPreviewValuesMessageSchema,
|
|
1845
|
-
fieldBridgePreviewAckMessageSchema,
|
|
1846
|
-
fieldBridgeSetVisualControlStateMessageSchema,
|
|
1847
|
-
fieldBridgeMissingContentMessageSchema,
|
|
1848
|
-
fieldBridgePreviewScrolledMessageSchema,
|
|
1849
|
-
fieldBridgeErrorMessageSchema,
|
|
1850
|
-
fieldBridgeAnalyticsProbeSchema,
|
|
1851
|
-
fieldBridgeAnalyticsProbeResultSchema
|
|
1852
|
-
]);
|
|
1853
|
-
|
|
1854
|
-
// ../shared/dist/commands.js
|
|
1855
|
-
import { z as z19 } from "zod";
|
|
1856
|
-
|
|
1857
|
-
// ../shared/dist/errors.js
|
|
1858
|
-
import { z as z18 } from "zod";
|
|
1859
|
-
var UI_ERROR_CATEGORIES = [
|
|
1860
|
-
"site_member",
|
|
1861
|
-
"workspace_member",
|
|
1862
|
-
"internal"
|
|
1863
|
-
];
|
|
1864
|
-
var uiErrorCategorySchema = z18.enum(UI_ERROR_CATEGORIES);
|
|
1865
|
-
var commandErrorPayloadSchema = z18.object({
|
|
1866
|
-
code: z18.string().min(1),
|
|
1867
|
-
message: z18.string().min(1),
|
|
1868
|
-
category: uiErrorCategorySchema,
|
|
1869
|
-
details: z18.record(z18.string(), z18.unknown()).optional()
|
|
1870
|
-
});
|
|
1871
|
-
|
|
1872
|
-
// ../shared/dist/commands.js
|
|
1873
|
-
var commandSuccessSchema = z19.object({
|
|
1874
|
-
ok: z19.literal(true),
|
|
1875
|
-
data: z19.unknown()
|
|
1876
|
-
});
|
|
1877
|
-
var commandErrorSchema = z19.object({
|
|
1878
|
-
ok: z19.literal(false),
|
|
1879
|
-
error: commandErrorPayloadSchema
|
|
1880
|
-
});
|
|
1881
|
-
var commandResultSchema = z19.discriminatedUnion("ok", [
|
|
1882
|
-
commandSuccessSchema,
|
|
1883
|
-
commandErrorSchema
|
|
1884
|
-
]);
|
|
1885
|
-
|
|
1886
|
-
// ../shared/dist/editor-settings.js
|
|
1887
|
-
import { z as z20 } from "zod";
|
|
1888
|
-
var editorColorSchemeSchema = z20.enum([
|
|
1889
|
-
"paper",
|
|
1890
|
-
"slate",
|
|
1891
|
-
"siteplane",
|
|
1892
|
-
"bloom"
|
|
1893
|
-
]);
|
|
1894
|
-
var editorColorSchemes = editorColorSchemeSchema.options;
|
|
1895
|
-
var editorColorModeSchema = z20.enum(["light", "dark"]);
|
|
1896
|
-
var editorColorModes = editorColorModeSchema.options;
|
|
1897
|
-
|
|
1898
|
-
// ../shared/dist/editor-organization.js
|
|
1899
|
-
import { z as z21 } from "zod";
|
|
1900
|
-
var labelSchema = z21.string().trim().min(1).max(120);
|
|
1901
|
-
var updateFieldSchema = z21.object({
|
|
1902
|
-
operation: z21.literal("update_field"),
|
|
1903
|
-
siteId: z21.string().uuid(),
|
|
1904
|
-
fieldId: fieldIdSchema,
|
|
1905
|
-
label: labelSchema.optional(),
|
|
1906
|
-
description: z21.string().trim().max(500).nullable().optional(),
|
|
1907
|
-
section: labelSchema.nullable().optional(),
|
|
1908
|
-
subsection: labelSchema.nullable().optional(),
|
|
1909
|
-
sortOrder: z21.number().int().nonnegative().optional(),
|
|
1910
|
-
status: z21.enum(["hidden", "active"]).optional()
|
|
1911
|
-
});
|
|
1912
|
-
var updateEditorOrganizationInputSchema = z21.discriminatedUnion("operation", [
|
|
1913
|
-
updateFieldSchema,
|
|
1914
|
-
z21.object({
|
|
1915
|
-
operation: z21.literal("rename_section"),
|
|
1916
|
-
siteId: z21.string().uuid(),
|
|
1917
|
-
routeKey: siteFieldRouteKeySchema,
|
|
1918
|
-
currentSection: labelSchema,
|
|
1919
|
-
nextSection: labelSchema
|
|
1920
|
-
}),
|
|
1921
|
-
z21.object({
|
|
1922
|
-
operation: z21.literal("create_group"),
|
|
1923
|
-
siteId: z21.string().uuid(),
|
|
1924
|
-
routeKey: siteFieldRouteKeySchema,
|
|
1925
|
-
section: labelSchema,
|
|
1926
|
-
fieldIds: z21.array(fieldIdSchema).max(200).default([])
|
|
1927
|
-
}),
|
|
1928
|
-
z21.object({
|
|
1929
|
-
operation: z21.literal("delete_section"),
|
|
1930
|
-
siteId: z21.string().uuid(),
|
|
1931
|
-
routeKey: siteFieldRouteKeySchema,
|
|
1932
|
-
section: labelSchema
|
|
1933
|
-
}),
|
|
1934
|
-
z21.object({
|
|
1935
|
-
operation: z21.literal("move_section"),
|
|
1936
|
-
siteId: z21.string().uuid(),
|
|
1937
|
-
routeKey: siteFieldRouteKeySchema,
|
|
1938
|
-
section: labelSchema,
|
|
1939
|
-
direction: z21.enum(["up", "down"])
|
|
1940
|
-
}),
|
|
1941
|
-
z21.object({
|
|
1942
|
-
operation: z21.literal("create_subgroup"),
|
|
1943
|
-
siteId: z21.string().uuid(),
|
|
1944
|
-
routeKey: siteFieldRouteKeySchema,
|
|
1945
|
-
section: labelSchema,
|
|
1946
|
-
subsection: labelSchema,
|
|
1947
|
-
fieldIds: z21.array(fieldIdSchema).min(1).max(200)
|
|
1948
|
-
}),
|
|
1949
|
-
z21.object({
|
|
1950
|
-
operation: z21.literal("update_subgroup"),
|
|
1951
|
-
siteId: z21.string().uuid(),
|
|
1952
|
-
routeKey: siteFieldRouteKeySchema,
|
|
1953
|
-
currentSection: labelSchema,
|
|
1954
|
-
currentSubsection: labelSchema,
|
|
1955
|
-
section: labelSchema,
|
|
1956
|
-
subsection: labelSchema.nullable()
|
|
1957
|
-
}),
|
|
1958
|
-
z21.object({
|
|
1959
|
-
operation: z21.literal("rename_route"),
|
|
1960
|
-
siteId: z21.string().uuid(),
|
|
1961
|
-
routeKey: siteFieldRouteKeySchema.refine((value) => value !== "$global", "Global content has no page label."),
|
|
1962
|
-
label: labelSchema
|
|
1963
|
-
})
|
|
1964
|
-
]).and(z21.object({
|
|
1965
|
-
review: z21.object({
|
|
1966
|
-
runId: z21.string().uuid(),
|
|
1967
|
-
expectedReviewVersion: z21.number().int().positive()
|
|
1968
|
-
}).strict().optional()
|
|
1969
|
-
})).superRefine((input, context) => {
|
|
1970
|
-
if (input.operation === "update_field" && input.label === void 0 && input.description === void 0 && input.section === void 0 && input.subsection === void 0 && input.sortOrder === void 0 && input.status === void 0) {
|
|
1971
|
-
context.addIssue({
|
|
1972
|
-
code: "custom",
|
|
1973
|
-
message: "At least one field organization value is required."
|
|
1974
|
-
});
|
|
1975
|
-
}
|
|
1976
|
-
if (input.operation === "update_field" && input.section === null && typeof input.subsection === "string") {
|
|
1977
|
-
context.addIssue({
|
|
1978
|
-
code: "custom",
|
|
1979
|
-
message: "A subgroup requires a group.",
|
|
1980
|
-
path: ["subsection"]
|
|
1981
|
-
});
|
|
1982
|
-
}
|
|
1983
|
-
});
|
|
1984
|
-
|
|
1985
|
-
// ../shared/dist/site-slug.js
|
|
1986
|
-
import { z as z22 } from "zod";
|
|
1987
|
-
var SITE_SLUG_PATTERN = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
|
|
1988
|
-
var RESERVED_SITE_SLUGS = /* @__PURE__ */ new Set([
|
|
1989
|
-
"account",
|
|
1990
|
-
"admin",
|
|
1991
|
-
"api",
|
|
1992
|
-
"app",
|
|
1993
|
-
"auth",
|
|
1994
|
-
"book",
|
|
1995
|
-
"claim",
|
|
1996
|
-
"dev",
|
|
1997
|
-
"login",
|
|
1998
|
-
"new",
|
|
1999
|
-
"portal",
|
|
2000
|
-
"support",
|
|
2001
|
-
"workspace"
|
|
2002
|
-
]);
|
|
2003
|
-
var siteSlugSchema = z22.string().regex(SITE_SLUG_PATTERN, "Invalid site slug").refine((value) => !RESERVED_SITE_SLUGS.has(value), "Reserved site slug");
|
|
2004
|
-
|
|
2005
|
-
// ../shared/dist/entitlements.js
|
|
2006
|
-
import { z as z23 } from "zod";
|
|
2007
|
-
var entitlementSnapshotSchema = z23.object({
|
|
2008
|
-
planKey: z23.string().trim().min(1),
|
|
2009
|
-
sitesLimit: z23.number().int().positive(),
|
|
2010
|
-
siteMembersPerSiteLimit: z23.number().int().positive(),
|
|
2011
|
-
customAdminDomainsEnabled: z23.boolean(),
|
|
2012
|
-
agentMcpEnabled: z23.boolean(),
|
|
2013
|
-
emailNotificationsEnabled: z23.boolean(),
|
|
2014
|
-
analyticsEnabled: z23.boolean(),
|
|
2015
|
-
analyticsSitesLimit: z23.number().int().min(0),
|
|
2016
|
-
analyticsPortalPerformanceEnabled: z23.boolean(),
|
|
2017
|
-
analyticsMonthlyReportsEnabled: z23.boolean(),
|
|
2018
|
-
analyticsAiSummaryEnabled: z23.boolean(),
|
|
2019
|
-
analyticsRawEventRetentionDays: z23.number().int().min(1).max(ANALYTICS_RETENTION_DEFAULTS.maxRawEventRetentionDaysWithoutAdr),
|
|
2020
|
-
analyticsMonthlyEventLimit: z23.number().int().min(0),
|
|
2021
|
-
bookingEnabled: z23.boolean().default(false),
|
|
2022
|
-
bookingSitesLimit: z23.number().int().min(0).default(0),
|
|
2023
|
-
bookingPortalManagementEnabled: z23.boolean().default(false),
|
|
2024
|
-
bookingResourcesPerSiteLimit: z23.number().int().min(0).default(0),
|
|
2025
|
-
bookingServicesPerSiteLimit: z23.number().int().min(0).default(0),
|
|
2026
|
-
bookingMonthlyBookingsLimit: z23.number().int().min(0).default(0),
|
|
2027
|
-
bookingRemindersEnabled: z23.boolean().default(false)
|
|
2028
|
-
});
|
|
2029
|
-
var EARLY_ACCESS_PLAN = {
|
|
2030
|
-
planKey: "early_access_2026",
|
|
2031
|
-
sitesLimit: 3,
|
|
2032
|
-
siteMembersPerSiteLimit: 5,
|
|
2033
|
-
customAdminDomainsEnabled: true,
|
|
2034
|
-
agentMcpEnabled: true,
|
|
2035
|
-
emailNotificationsEnabled: true,
|
|
2036
|
-
analyticsEnabled: true,
|
|
2037
|
-
analyticsSitesLimit: 3,
|
|
2038
|
-
analyticsPortalPerformanceEnabled: false,
|
|
2039
|
-
analyticsMonthlyReportsEnabled: false,
|
|
2040
|
-
analyticsAiSummaryEnabled: false,
|
|
2041
|
-
analyticsRawEventRetentionDays: ANALYTICS_RETENTION_DEFAULTS.enabledRawEventRetentionDays,
|
|
2042
|
-
analyticsMonthlyEventLimit: 0,
|
|
2043
|
-
bookingEnabled: true,
|
|
2044
|
-
bookingSitesLimit: 3,
|
|
2045
|
-
bookingPortalManagementEnabled: true,
|
|
2046
|
-
bookingResourcesPerSiteLimit: 10,
|
|
2047
|
-
bookingServicesPerSiteLimit: 50,
|
|
2048
|
-
bookingMonthlyBookingsLimit: 0,
|
|
2049
|
-
bookingRemindersEnabled: true
|
|
2050
|
-
};
|
|
2051
|
-
|
|
2052
|
-
// ../shared/dist/first-party-image-upload.js
|
|
2053
|
-
var maxFirstPartyImageUploadBytes = 4 * 1024 * 1024;
|
|
2054
|
-
|
|
2055
|
-
// ../shared/dist/readiness.js
|
|
2056
|
-
import { z as z24 } from "zod";
|
|
2057
|
-
var READINESS_CHECK_KEYS = [
|
|
2058
|
-
"agent_instructions_installed",
|
|
2059
|
-
"runtime_package_connected",
|
|
2060
|
-
"secure_server_access_configured",
|
|
2061
|
-
"preview_bridge_working",
|
|
2062
|
-
"admin_access_url_selected",
|
|
2063
|
-
"default_publishing_mode_selected"
|
|
2064
|
-
];
|
|
2065
|
-
var READINESS_STATUSES = [
|
|
2066
|
-
"pending",
|
|
2067
|
-
"passing",
|
|
2068
|
-
"failing",
|
|
2069
|
-
"warning"
|
|
2070
|
-
];
|
|
2071
|
-
var readinessCheckKeySchema = z24.enum(READINESS_CHECK_KEYS);
|
|
2072
|
-
var readinessStatusSchema = z24.enum(READINESS_STATUSES);
|
|
2073
|
-
|
|
2074
|
-
// ../shared/dist/site.js
|
|
2075
|
-
import { z as z25 } from "zod";
|
|
2076
|
-
var SITE_STATUSES = [
|
|
2077
|
-
"setup",
|
|
2078
|
-
"active",
|
|
2079
|
-
"disabled",
|
|
2080
|
-
"archived"
|
|
2081
|
-
];
|
|
2082
|
-
var siteStatusSchema = z25.enum(SITE_STATUSES);
|
|
2083
|
-
var websiteUrlSchema = z25.string().trim().url().refine((value) => value.startsWith("https://") || value.startsWith("http://"), "Website URL must use http or https");
|
|
2084
|
-
|
|
2085
|
-
// ../shared/dist/setup-assets.js
|
|
2086
|
-
import { z as z26 } from "zod";
|
|
2087
|
-
var configureSetupAssetTargetInputSchema = z26.object({
|
|
2088
|
-
siteId: z26.string().uuid(),
|
|
2089
|
-
runId: z26.string().uuid(),
|
|
2090
|
-
expectedReviewVersion: z26.number().int().positive(),
|
|
2091
|
-
expectedSnapshotHash: z26.string().regex(/^sha256:[0-9a-f]{64}$/u),
|
|
2092
|
-
mutationId: z26.string().uuid(),
|
|
2093
|
-
expectedApprovalId: z26.string().uuid().nullable(),
|
|
2094
|
-
targetId: z26.string().uuid().nullable(),
|
|
2095
|
-
targetType: z26.enum(["repo_static_assets", "siteplane_managed_fallback"]),
|
|
2096
|
-
approveManagedHosting: z26.boolean()
|
|
2097
|
-
}).strict().refine((value) => value.targetType === "siteplane_managed_fallback" || !value.approveManagedHosting);
|
|
2098
|
-
var setupAssetTargetApprovalSchema = z26.object({
|
|
2099
|
-
id: z26.string().uuid(),
|
|
2100
|
-
runId: z26.string().uuid(),
|
|
2101
|
-
reviewVersion: z26.number().int().positive(),
|
|
2102
|
-
snapshotHash: z26.string().regex(/^sha256:[0-9a-f]{64}$/u),
|
|
2103
|
-
targetId: z26.string().uuid(),
|
|
2104
|
-
targetType: z26.enum(["repo_static_assets", "siteplane_managed_fallback"]),
|
|
2105
|
-
targetRevision: z26.number().int().positive(),
|
|
2106
|
-
deploymentOrigin: z26.string().url(),
|
|
2107
|
-
gitConnectionId: z26.string().uuid().nullable(),
|
|
2108
|
-
gitRevision: z26.number().int().positive().nullable(),
|
|
2109
|
-
managedHostingApproved: z26.boolean(),
|
|
2110
|
-
actorUserId: z26.string().uuid(),
|
|
2111
|
-
approvedAt: z26.string().datetime({ offset: true })
|
|
2112
|
-
}).strict();
|
|
2113
|
-
var setupAssetReadinessSchema = z26.union([
|
|
2114
|
-
z26.object({
|
|
2115
|
-
status: z26.enum([
|
|
2116
|
-
"not_required",
|
|
2117
|
-
"needs_choice",
|
|
2118
|
-
"stale_setup_review",
|
|
2119
|
-
"permission_denied"
|
|
2120
|
-
])
|
|
2121
|
-
}).strict(),
|
|
2122
|
-
z26.object({
|
|
2123
|
-
status: z26.literal("stale_approval"),
|
|
2124
|
-
approval: setupAssetTargetApprovalSchema.optional()
|
|
2125
|
-
}).strict(),
|
|
2126
|
-
z26.object({
|
|
2127
|
-
status: z26.literal("not_verified"),
|
|
2128
|
-
approval: setupAssetTargetApprovalSchema,
|
|
2129
|
-
jobId: z26.string().uuid().optional(),
|
|
2130
|
-
checkedAt: z26.string().datetime({ offset: true }).nullable().optional()
|
|
2131
|
-
}).strict(),
|
|
2132
|
-
z26.object({
|
|
2133
|
-
status: z26.enum(["ready", "checking", "retrying"]),
|
|
2134
|
-
approval: setupAssetTargetApprovalSchema,
|
|
2135
|
-
jobId: z26.string().uuid(),
|
|
2136
|
-
checkedAt: z26.string().datetime({ offset: true }).nullable()
|
|
2137
|
-
}).strict().refine((value) => value.status !== "ready" || value.checkedAt !== null)
|
|
2138
|
-
]);
|
|
2139
|
-
var checkSetupAssetTargetInputSchema = z26.object({
|
|
2140
|
-
siteId: z26.string().uuid(),
|
|
2141
|
-
runId: z26.string().uuid(),
|
|
2142
|
-
approvalId: z26.string().uuid(),
|
|
2143
|
-
intent: z26.enum(["start", "poll"])
|
|
2144
|
-
}).strict();
|
|
2145
|
-
|
|
2146
|
-
// ../shared/dist/setup-installation.js
|
|
2147
|
-
import { z as z27 } from "zod";
|
|
2148
|
-
var setupInstallationRequestSchema = z27.object({
|
|
2149
|
-
modules: siteSetupModulesSchema,
|
|
2150
|
-
ownerEditabilityNote: siteSetupOwnerEditabilityNoteSchema,
|
|
2151
|
-
provider: z27.object({
|
|
2152
|
-
projectId: z27.string().min(1).max(200),
|
|
2153
|
-
teamId: z27.string().min(1).max(200)
|
|
2154
|
-
}).strict()
|
|
2155
|
-
}).strict();
|
|
2156
|
-
|
|
2157
|
-
// ../shared/dist/setup-claim.js
|
|
2158
|
-
import { z as z28 } from "zod";
|
|
2159
|
-
var setupClaimCodeSchema = z28.string().regex(/^[0-9A-HJKMNP-TV-Z]{8}$/u);
|
|
2160
|
-
var setupClaimBindingSchema = z28.object({
|
|
2161
|
-
siteId: z28.string().uuid(),
|
|
2162
|
-
runId: z28.string().uuid()
|
|
2163
|
-
});
|
|
2164
|
-
var setupClaimReceiptSchema = setupClaimBindingSchema.extend({
|
|
2165
|
-
status: z28.literal("claimed"),
|
|
2166
|
-
requestId: z28.string().uuid(),
|
|
2167
|
-
workspaceId: z28.string().uuid(),
|
|
2168
|
-
userId: z28.string().uuid(),
|
|
2169
|
-
claimedAt: z28.string().datetime({ offset: true })
|
|
2170
|
-
}).strict();
|
|
2171
|
-
var setupClaimInspectionSchema = setupClaimBindingSchema.extend({
|
|
2172
|
-
status: z28.literal("pending"),
|
|
2173
|
-
requestId: z28.string().uuid(),
|
|
2174
|
-
siteName: z28.string(),
|
|
2175
|
-
userId: z28.string().uuid(),
|
|
2176
|
-
accountEmail: z28.string().email(),
|
|
2177
|
-
workspaceId: z28.string().uuid(),
|
|
2178
|
-
workspaceName: z28.string(),
|
|
2179
|
-
expiresAt: z28.string().datetime({ offset: true })
|
|
2180
|
-
}).strict();
|
|
2181
|
-
var setupClaimDenialSchema = z28.object({
|
|
2182
|
-
status: z28.enum([
|
|
2183
|
-
"invalid_claim_request",
|
|
2184
|
-
"invalid_installation",
|
|
2185
|
-
"already_claimed",
|
|
2186
|
-
"project_expired",
|
|
2187
|
-
"invalid_guest_session",
|
|
2188
|
-
"stale_setup_review",
|
|
2189
|
-
"verified_account_required",
|
|
2190
|
-
"workspace_access_denied",
|
|
2191
|
-
"workspace_entitlement_required",
|
|
2192
|
-
"site_limit_reached",
|
|
2193
|
-
"provisional_relationship_conflict",
|
|
2194
|
-
"rate_limited"
|
|
2195
|
-
])
|
|
2196
|
-
}).strict();
|
|
2197
|
-
|
|
2198
|
-
// ../cli/dist/analytics/static-scan.js
|
|
2199
|
-
import ts from "typescript";
|
|
2200
|
-
|
|
2201
|
-
// ../cli/dist/booking/manifest.js
|
|
2202
|
-
import { mkdir as mkdir2, readFile as readFile2, writeFile as writeFile2 } from "fs/promises";
|
|
2203
|
-
import { dirname as dirname2 } from "path";
|
|
2204
|
-
async function readBookingManifestFile(manifestPath) {
|
|
2205
|
-
return validateBookingManifestInput(JSON.parse(await readFile2(manifestPath, "utf8")));
|
|
2206
|
-
}
|
|
2207
|
-
async function writeBookingManifestFile(manifestPath, manifest) {
|
|
2208
|
-
await mkdir2(dirname2(manifestPath), {
|
|
2209
|
-
recursive: true
|
|
2210
|
-
});
|
|
2211
|
-
await writeFile2(manifestPath, `${JSON.stringify(bookingManifestSchema.parse(manifest), null, 2)}
|
|
2212
|
-
`, "utf8");
|
|
2213
|
-
}
|
|
2214
|
-
function validateBookingManifestInput(input) {
|
|
2215
|
-
const redactedKeys = collectRedactedBookingKeys(input);
|
|
2216
|
-
const redacted = redactBookingManifest(input);
|
|
2217
|
-
return {
|
|
2218
|
-
manifest: bookingManifestSchema.parse(redacted),
|
|
2219
|
-
redactedKeys: [...redactedKeys].sort()
|
|
2220
|
-
};
|
|
2221
|
-
}
|
|
2222
|
-
var secretManifestKeys2 = /* @__PURE__ */ new Set([
|
|
2223
|
-
"siteKey",
|
|
2224
|
-
"rawKey",
|
|
2225
|
-
"token",
|
|
2226
|
-
"accessToken"
|
|
2227
|
-
]);
|
|
2228
|
-
function collectRedactedBookingKeys(input, prefix = "") {
|
|
2229
|
-
if (Array.isArray(input)) {
|
|
2230
|
-
return input.flatMap((item, index) => collectRedactedBookingKeys(item, `${prefix}[${index}]`));
|
|
2231
|
-
}
|
|
2232
|
-
if (!input || typeof input !== "object") {
|
|
2233
|
-
return [];
|
|
2234
|
-
}
|
|
2235
|
-
return Object.entries(input).flatMap(([key, value]) => {
|
|
2236
|
-
const path = prefix ? `${prefix}.${key}` : key;
|
|
2237
|
-
if (secretManifestKeys2.has(key)) {
|
|
2238
|
-
return [path];
|
|
2239
|
-
}
|
|
2240
|
-
return collectRedactedBookingKeys(value, path);
|
|
2241
|
-
});
|
|
2242
|
-
}
|
|
2243
|
-
|
|
2244
|
-
// ../cli/dist/booking/static-scan.js
|
|
2245
|
-
import ts2 from "typescript";
|
|
2246
|
-
function scanBookingSourceFiles(files, input) {
|
|
2247
|
-
const findings = [];
|
|
2248
|
-
const hardErrors = [];
|
|
2249
|
-
const warnings = [];
|
|
2250
|
-
for (const file of files) {
|
|
2251
|
-
let visit2 = function(node) {
|
|
2252
|
-
if (ts2.isCallExpression(node) && ts2.isIdentifier(node.expression) && node.expression.text === "withSiteplane") {
|
|
2253
|
-
const options = node.arguments[1];
|
|
2254
|
-
const booking = options && property(options, "booking");
|
|
2255
|
-
const site = booking && property(booking, "site");
|
|
2256
|
-
if (site && ts2.isStringLiteralLike(site)) {
|
|
2257
|
-
const issue = {
|
|
2258
|
-
code: site.text === input.siteId ? "booking_scan.integration_found" : "booking_scan.site_mismatch",
|
|
2259
|
-
message: site.text === input.siteId ? "Booking /booking rewrite configured for this Site ID." : "The Booking wrapper uses a different Site ID; use the Site ID supplied by Siteplane.",
|
|
2260
|
-
filePath: file.filePath
|
|
2261
|
-
};
|
|
2262
|
-
(site.text === input.siteId ? findings : hardErrors).push(issue);
|
|
2263
|
-
}
|
|
2264
|
-
}
|
|
2265
|
-
ts2.forEachChild(node, visit2);
|
|
2266
|
-
};
|
|
2267
|
-
var visit = visit2;
|
|
2268
|
-
const source = ts2.createSourceFile(file.filePath, file.sourceText, ts2.ScriptTarget.Latest, true, ts2.ScriptKind.TSX);
|
|
2269
|
-
visit2(source);
|
|
2270
|
-
}
|
|
2271
|
-
if (!findings.length && !hardErrors.length)
|
|
2272
|
-
hardErrors.push({
|
|
2273
|
-
code: "booking_scan.integration_missing",
|
|
2274
|
-
message: "Could not verify withSiteplane(nextConfig, { booking: { site: <site-id> } }). Include next.config.ts in the scan and use a literal Site ID.",
|
|
2275
|
-
filePath: "next.config.ts"
|
|
2276
|
-
});
|
|
2277
|
-
if (input.productionOrigin && !files.some((file) => file.sourceText.includes(input.productionOrigin)))
|
|
2278
|
-
warnings.push({
|
|
2279
|
-
code: "booking_scan.origin_not_detected",
|
|
2280
|
-
message: "Verify the public booking address and its allowed origins in Siteplane settings.",
|
|
2281
|
-
filePath: "siteplane.booking.json"
|
|
2282
|
-
});
|
|
2283
|
-
return {
|
|
2284
|
-
manifest: bookingManifestSchema.parse({
|
|
2285
|
-
schemaVersion: 1,
|
|
2286
|
-
...input,
|
|
2287
|
-
integration: "rewrite"
|
|
2288
|
-
}),
|
|
2289
|
-
findings,
|
|
2290
|
-
hardErrors,
|
|
2291
|
-
warnings,
|
|
2292
|
-
suggestions: []
|
|
2293
|
-
};
|
|
2294
|
-
}
|
|
2295
|
-
function property(node, name2) {
|
|
2296
|
-
if (!ts2.isObjectLiteralExpression(node))
|
|
2297
|
-
return;
|
|
2298
|
-
for (const item of node.properties) {
|
|
2299
|
-
if (ts2.isPropertyAssignment(item) && (ts2.isIdentifier(item.name) || ts2.isStringLiteral(item.name)) && item.name.text === name2)
|
|
2300
|
-
return item.initializer;
|
|
2301
|
-
}
|
|
2302
|
-
}
|
|
2303
|
-
|
|
2304
|
-
// ../cli/dist/commands/analytics/check.js
|
|
2305
|
-
import { readFile as readFile3 } from "fs/promises";
|
|
2306
|
-
|
|
2307
|
-
// ../cli/dist/commands/analytics/init.js
|
|
2308
|
-
import { mkdir as mkdir3, writeFile as writeFile3 } from "fs/promises";
|
|
2309
|
-
import { dirname as dirname3, join } from "path";
|
|
2310
|
-
var analyticsRulesTemplate = `# Siteplane Analytics Rules
|
|
2311
|
-
|
|
2312
|
-
Analytics contract version: ${ANALYTICS_CONTRACT_VERSION}
|
|
2313
|
-
Analytics contract hash: ${ANALYTICS_CONTRACT_HASH}
|
|
2314
|
-
|
|
2315
|
-
- Do not change visible layout, copy, styling, animation or business logic while adding analytics.
|
|
2316
|
-
- Use stable data-siteplane-target-id values that do not depend on visible copy.
|
|
2317
|
-
- Use public site keys only through environment references.
|
|
2318
|
-
- Do not write secret analytics keys, setup tokens or project CLI tokens into source files.
|
|
2319
|
-
- Mount the SDK once in the existing client lifecycle. Wire installDataAttributeTracking and createNextAppRouterNavigationAdapter to analytics.track/getRouteViewId/setPageContext, feed initial and subsequent Next.js pathname changes, and refresh attribute targets after navigation. Dispose attribute tracking and the SDK on unmount.
|
|
2320
|
-
- Inspect existing consent management. Pass consentAdapter with getConsent and subscribe to initSiteplaneAnalytics for an existing CMP; return unknown while unresolved, disabled for denial and a permitted mode only for its actual visitor grant. Subscribe returns cleanup. Do not mirror CMP snapshots with setConsent or replace stored opt-outs.
|
|
2321
|
-
- Omit consentAdapter only after confirming no existing CMP. An unrecognized CMP blocks Analytics with a concrete repair diagnostic; do not invent a grant or a no-op adapter to pass a check.
|
|
2322
|
-
- Suppress editor-preview traffic from live analytics.
|
|
2323
|
-
- Run npx siteplane analytics check, npx siteplane analytics sync and npx siteplane analytics test after setup.
|
|
2324
|
-
`;
|
|
2325
|
-
var analyticsCursorRulesTemplate = `---
|
|
2326
|
-
description: Siteplane Analytics rules
|
|
2327
|
-
alwaysApply: true
|
|
2328
|
-
---
|
|
2329
|
-
|
|
2330
|
-
${analyticsRulesTemplate}`;
|
|
2331
|
-
|
|
2332
|
-
// ../cli/dist/commands/analytics/import.js
|
|
2333
|
-
import { createHash } from "crypto";
|
|
2334
|
-
|
|
2335
|
-
// ../cli/dist/commands/analytics/sync.js
|
|
2336
|
-
function createAnalyticsCliRequestHeaders(config) {
|
|
2337
|
-
const headers = {
|
|
2338
|
-
authorization: `Bearer ${config.accessToken}`,
|
|
2339
|
-
"content-type": "application/json"
|
|
2340
|
-
};
|
|
2341
|
-
const bypassSecret = config.vercelAutomationBypassSecret?.trim();
|
|
2342
|
-
if (bypassSecret) {
|
|
2343
|
-
headers["x-vercel-protection-bypass"] = bypassSecret;
|
|
2344
|
-
}
|
|
2345
|
-
return headers;
|
|
2346
|
-
}
|
|
2347
|
-
|
|
2348
|
-
// ../cli/dist/commands/analytics/public-key.js
|
|
2349
|
-
import { z as z29 } from "zod";
|
|
2350
|
-
var responseSchema = z29.object({
|
|
2351
|
-
ok: z29.literal(true),
|
|
2352
|
-
data: z29.object({
|
|
2353
|
-
rawPublicKey: z29.string().regex(/^pk_siteplane_[A-Za-z0-9_-]{16}_[A-Za-z0-9_-]{43}$/)
|
|
2354
|
-
})
|
|
2355
|
-
});
|
|
2356
|
-
var errorResponseSchema = z29.object({
|
|
2357
|
-
error: z29.object({
|
|
2358
|
-
code: z29.string().regex(/^[a-z][a-z0-9_.-]+$/u)
|
|
2359
|
-
})
|
|
2360
|
-
});
|
|
2361
|
-
async function analyticsPublicKeyCommand(input) {
|
|
2362
|
-
const fetcher = input.fetchImpl ?? fetch;
|
|
2363
|
-
const response = await fetcher(`${input.config.apiBaseUrl.replace(/\/$/u, "")}/api/cli/analytics/public-key`, {
|
|
2364
|
-
method: "POST",
|
|
2365
|
-
redirect: "error",
|
|
2366
|
-
signal: AbortSignal.timeout(2e4),
|
|
2367
|
-
headers: createAnalyticsCliRequestHeaders(input.config),
|
|
2368
|
-
body: JSON.stringify({ siteId: input.config.siteId })
|
|
2369
|
-
});
|
|
2370
|
-
const payload = await response.json().catch(() => null);
|
|
2371
|
-
const parsed = responseSchema.safeParse(payload);
|
|
2372
|
-
if (!response.ok || !parsed.success) {
|
|
2373
|
-
const error = errorResponseSchema.safeParse(payload);
|
|
2374
|
-
throw new Error(`${error.success ? error.data.error.code : "analytics_public_key.invalid_response"}: Unable to read the active Analytics public key.`);
|
|
2375
|
-
}
|
|
2376
|
-
return parsed.data.data.rawPublicKey;
|
|
2377
|
-
}
|
|
2378
|
-
|
|
2379
|
-
// ../cli/dist/commands/analytics/prepare.js
|
|
2380
|
-
import { z as z30 } from "zod";
|
|
2381
|
-
var resultSchema = z30.object({
|
|
2382
|
-
ok: z30.literal(true),
|
|
2383
|
-
data: z30.object({
|
|
2384
|
-
rawPublicKey: z30.string().regex(/^pk_siteplane_[A-Za-z0-9_-]{16}_[A-Za-z0-9_-]{43}$/u),
|
|
2385
|
-
generation: z30.number().int().positive(),
|
|
2386
|
-
status: z30.enum([
|
|
2387
|
-
"setup_started",
|
|
2388
|
-
"test_mode",
|
|
2389
|
-
"active",
|
|
2390
|
-
"paused",
|
|
2391
|
-
"error",
|
|
2392
|
-
"deleting"
|
|
2393
|
-
])
|
|
2394
|
-
}).strict()
|
|
2395
|
-
}).strict();
|
|
2396
|
-
var errorSchema = z30.object({
|
|
2397
|
-
error: z30.object({ code: z30.string().regex(/^[a-z][a-z0-9_.-]+$/u) })
|
|
2398
|
-
});
|
|
2399
|
-
|
|
2400
|
-
// ../cli/dist/commands/analytics/test.js
|
|
2401
|
-
import { randomUUID } from "crypto";
|
|
2402
|
-
|
|
2403
|
-
// ../cli/dist/commands/booking/check.js
|
|
2404
|
-
import { dirname as dirname4, join as join2 } from "path";
|
|
2405
|
-
import { access, readFile as readFile4 } from "fs/promises";
|
|
2406
|
-
async function bookingCheckCommand(input) {
|
|
2407
|
-
const validatedManifest = await readBookingManifestFile(input.manifestPath);
|
|
2408
|
-
const configs = (await Promise.all(["next.config.ts", "next.config.js", "next.config.mjs"].map(async (name2) => {
|
|
2409
|
-
const path = join2(dirname4(input.manifestPath), name2);
|
|
2410
|
-
return await access(path).then(() => path, () => null);
|
|
2411
|
-
}))).filter((path) => path !== null);
|
|
2412
|
-
const sourceFiles = await readSourceFiles([
|
|
2413
|
-
.../* @__PURE__ */ new Set([...input.sourceFilePaths, ...configs])
|
|
2414
|
-
]);
|
|
2415
|
-
const scanInput = {
|
|
2416
|
-
siteId: validatedManifest.manifest.siteId,
|
|
2417
|
-
bookingPageSlug: validatedManifest.manifest.bookingPageSlug,
|
|
2418
|
-
...validatedManifest.manifest.productionOrigin ? { productionOrigin: validatedManifest.manifest.productionOrigin } : {}
|
|
2419
|
-
};
|
|
2420
|
-
const scanResult = scanBookingSourceFiles(sourceFiles, {
|
|
2421
|
-
...scanInput
|
|
2422
|
-
});
|
|
2423
|
-
const hardErrors = [
|
|
2424
|
-
...createBoundaryErrors(validatedManifest),
|
|
2425
|
-
...scanResult.hardErrors
|
|
2426
|
-
];
|
|
2427
|
-
return {
|
|
2428
|
-
ok: hardErrors.length === 0,
|
|
2429
|
-
manifest: validatedManifest.manifest,
|
|
2430
|
-
scannedManifest: scanResult.manifest,
|
|
2431
|
-
redactedKeys: validatedManifest.redactedKeys,
|
|
2432
|
-
hardErrors,
|
|
2433
|
-
warnings: scanResult.warnings,
|
|
2434
|
-
suggestions: scanResult.suggestions,
|
|
2435
|
-
findings: scanResult.findings
|
|
2436
|
-
};
|
|
2437
|
-
}
|
|
2438
|
-
async function readSourceFiles(filePaths) {
|
|
2439
|
-
return Promise.all(filePaths.map(async (filePath) => ({
|
|
2440
|
-
filePath,
|
|
2441
|
-
sourceText: await readFile4(filePath, "utf8")
|
|
2442
|
-
})));
|
|
2443
|
-
}
|
|
2444
|
-
function createBoundaryErrors(validation) {
|
|
2445
|
-
return validation.redactedKeys.map((key) => ({
|
|
2446
|
-
code: "booking_check.raw_key_in_manifest",
|
|
2447
|
-
message: `Booking manifest contains a raw key-like field: ${key}`,
|
|
2448
|
-
filePath: "siteplane.booking.json"
|
|
2449
|
-
}));
|
|
2450
|
-
}
|
|
2451
|
-
|
|
2452
|
-
// ../cli/dist/commands/booking/init.js
|
|
2453
|
-
import { mkdir as mkdir4, writeFile as writeFile4 } from "fs/promises";
|
|
2454
|
-
import { dirname as dirname5, join as join3 } from "path";
|
|
2455
|
-
async function bookingInitCommand(input) {
|
|
2456
|
-
const manifest = {
|
|
2457
|
-
schemaVersion: 1,
|
|
2458
|
-
siteId: input.siteId,
|
|
2459
|
-
bookingPageSlug: input.bookingPageSlug,
|
|
2460
|
-
...input.productionOrigin ? { productionOrigin: input.productionOrigin } : {}
|
|
2461
|
-
};
|
|
2462
|
-
const manifestPath = join3(input.projectDir, "siteplane.booking.json");
|
|
2463
|
-
const artifacts = createBookingArtifacts(input.agentClient);
|
|
2464
|
-
await writeBookingManifestFile(manifestPath, manifest);
|
|
2465
|
-
for (const artifact of artifacts) {
|
|
2466
|
-
await writeProjectFile(input.projectDir, artifact.path, artifact.template);
|
|
2467
|
-
}
|
|
2468
|
-
return {
|
|
2469
|
-
manifestPath,
|
|
2470
|
-
manifest,
|
|
2471
|
-
artifactPaths: artifacts.map((artifact) => artifact.path)
|
|
2472
|
-
};
|
|
2473
|
-
}
|
|
2474
|
-
function createBookingArtifacts(agentClient) {
|
|
2475
|
-
const artifacts = [
|
|
2476
|
-
{
|
|
2477
|
-
path: ".siteplane/booking.md",
|
|
2478
|
-
template: bookingRulesTemplate
|
|
2479
|
-
}
|
|
2480
|
-
];
|
|
2481
|
-
if (agentClient === "codex") {
|
|
2482
|
-
artifacts.push({
|
|
2483
|
-
path: ".agents/skills/siteplane-booking/SKILL.md",
|
|
2484
|
-
template: bookingSkillTemplate("Codex")
|
|
2485
|
-
});
|
|
2486
|
-
}
|
|
2487
|
-
if (agentClient === "claude") {
|
|
2488
|
-
artifacts.push({
|
|
2489
|
-
path: ".claude/skills/siteplane-booking/SKILL.md",
|
|
2490
|
-
template: bookingSkillTemplate("Claude Code")
|
|
2491
|
-
});
|
|
2492
|
-
}
|
|
2493
|
-
if (agentClient === "cursor") {
|
|
2494
|
-
artifacts.push({
|
|
2495
|
-
path: ".cursor/rules/siteplane-booking.mdc",
|
|
2496
|
-
template: bookingCursorRulesTemplate
|
|
2497
|
-
});
|
|
2498
|
-
}
|
|
2499
|
-
return artifacts;
|
|
2500
|
-
}
|
|
2501
|
-
async function writeProjectFile(projectDir, relativePath, contents) {
|
|
2502
|
-
const path = join3(projectDir, relativePath);
|
|
2503
|
-
await mkdir4(dirname5(path), { recursive: true });
|
|
2504
|
-
await writeFile4(path, contents, "utf8");
|
|
2505
|
-
}
|
|
2506
|
-
var bookingRulesTemplate = `# Siteplane Booking Rules
|
|
2507
|
-
|
|
2508
|
-
- Do not change layout, copy, styling, animation or business logic while adding Booking.
|
|
2509
|
-
- Integrate /booking on the customer domain through withSiteplane(nextConfig, { booking: { site: "<site-id>" } }); use the immutable Site ID supplied by Siteplane.
|
|
2510
|
-
- Use a normal <a href="/booking"> link, not next/link, an iframe or an embed script.
|
|
2511
|
-
- Preserve existing rewrites. Booking-only must not require Editor setup or siteplane.config.json.
|
|
2512
|
-
- Configure the public booking address in Siteplane; register its origin and call https://siteplane.io/api/booking/* directly with CORS, without a raw public key.
|
|
2513
|
-
- Preserve customer CSP and middleware; explain required Siteplane/Stripe permissions and exclude /booking from customer middleware.
|
|
2514
|
-
- Do not write setup tokens, project CLI tokens or private keys into source files.
|
|
2515
|
-
- Run npx siteplane booking check, npx siteplane booking sync and npx siteplane booking test after setup.
|
|
2516
|
-
- booking test stays in test_mode; live booking only starts after explicit dashboard activation.
|
|
2517
|
-
`;
|
|
2518
|
-
function bookingSkillTemplate(agentName) {
|
|
2519
|
-
return `# Siteplane Booking Skill
|
|
2520
|
-
|
|
2521
|
-
Use this skill in ${agentName} before integrating Siteplane Booking at /booking.
|
|
2522
|
-
|
|
2523
|
-
${bookingRulesTemplate}`;
|
|
2524
|
-
}
|
|
2525
|
-
var bookingCursorRulesTemplate = `---
|
|
2526
|
-
description: Siteplane Booking rules
|
|
2527
|
-
alwaysApply: true
|
|
2528
|
-
---
|
|
2529
|
-
|
|
2530
|
-
${bookingRulesTemplate}`;
|
|
2531
|
-
|
|
2532
|
-
// ../cli/dist/commands/booking/sync.js
|
|
2533
|
-
async function bookingSyncCommand(input) {
|
|
2534
|
-
const redacted = validateBookingManifestInput(input.manifest);
|
|
2535
|
-
const fetcher = input.fetchImpl ?? fetch;
|
|
2536
|
-
return fetcher(`${input.config.apiBaseUrl}/api/cli/booking/sync`, {
|
|
2537
|
-
method: "POST",
|
|
2538
|
-
headers: createBookingCliRequestHeaders(input.config),
|
|
2539
|
-
body: JSON.stringify({
|
|
2540
|
-
siteId: input.config.siteId,
|
|
2541
|
-
source: "cli",
|
|
2542
|
-
manifest: redacted.manifest
|
|
2543
|
-
})
|
|
2544
|
-
});
|
|
2545
|
-
}
|
|
2546
|
-
function createBookingCliRequestHeaders(config) {
|
|
2547
|
-
const headers = {
|
|
2548
|
-
authorization: `Bearer ${config.accessToken}`,
|
|
2549
|
-
"content-type": "application/json"
|
|
2550
|
-
};
|
|
2551
|
-
const bypassSecret = config.vercelAutomationBypassSecret?.trim();
|
|
2552
|
-
if (bypassSecret) {
|
|
2553
|
-
headers["x-vercel-protection-bypass"] = bypassSecret;
|
|
2554
|
-
}
|
|
2555
|
-
return headers;
|
|
102
|
+
return Object.fromEntries(keys.filter((key) => key in value).map((key) => [key, value[key]]));
|
|
2556
103
|
}
|
|
2557
|
-
|
|
2558
|
-
|
|
2559
|
-
async function bookingTestCommand(input) {
|
|
2560
|
-
const fetcher = input.fetchImpl ?? fetch;
|
|
2561
|
-
const booking = bookingCreateRequestSchema.parse(input.booking);
|
|
2562
|
-
return fetcher(`${input.config.apiBaseUrl}/api/cli/booking/test`, {
|
|
2563
|
-
method: "POST",
|
|
2564
|
-
headers: createBookingCliRequestHeaders(input.config),
|
|
2565
|
-
body: JSON.stringify({
|
|
2566
|
-
siteId: input.config.siteId,
|
|
2567
|
-
mode: "test",
|
|
2568
|
-
...input.manifest ? { manifest: input.manifest } : {},
|
|
2569
|
-
booking
|
|
2570
|
-
})
|
|
2571
|
-
});
|
|
104
|
+
function codePoints(value) {
|
|
105
|
+
return Array.from(value).length;
|
|
2572
106
|
}
|
|
2573
|
-
|
|
2574
|
-
|
|
2575
|
-
async function exportCommand(input) {
|
|
2576
|
-
requireContentExportScope(input.tokenScopes);
|
|
2577
|
-
const values = await input.readPublishedValues();
|
|
2578
|
-
if (input.format === "prompt") {
|
|
2579
|
-
return {
|
|
2580
|
-
kind: "prompt",
|
|
2581
|
-
output: Object.entries(values).map(([fieldId, value]) => `${fieldId}: ${JSON.stringify(value)}`).join("\n")
|
|
2582
|
-
};
|
|
2583
|
-
}
|
|
2584
|
-
return {
|
|
2585
|
-
kind: "json",
|
|
2586
|
-
values
|
|
2587
|
-
};
|
|
2588
|
-
}
|
|
2589
|
-
function requireContentExportScope(scopes) {
|
|
2590
|
-
if (!scopes?.includes("content:export")) {
|
|
2591
|
-
throw new Error("A Project Connection with content:export is required.");
|
|
2592
|
-
}
|
|
107
|
+
function isRecord(value) {
|
|
108
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
2593
109
|
}
|
|
2594
110
|
|
|
2595
|
-
//
|
|
2596
|
-
|
|
2597
|
-
|
|
2598
|
-
import { join as join4 } from "path";
|
|
2599
|
-
import { z as z31 } from "zod";
|
|
2600
|
-
var siteplaneProjectConfigSchema = z31.object({
|
|
2601
|
-
version: z31.literal(2),
|
|
2602
|
-
apiBaseUrl: z31.string().url(),
|
|
2603
|
-
siteId: z31.string().uuid(),
|
|
2604
|
-
publicSiteKeyId: z31.string().uuid(),
|
|
2605
|
-
publicSiteKey: z31.string().trim().min(1),
|
|
2606
|
-
runId: z31.string().uuid(),
|
|
2607
|
-
appDirectory: z31.string().min(1),
|
|
2608
|
-
taskContractVersion: z31.literal("siteplane.setup-task.v2"),
|
|
2609
|
-
adminProtocolVersion: z31.literal(2),
|
|
2610
|
-
packages: siteSetupPackagesSchema,
|
|
2611
|
-
fieldContractHash: z31.string().regex(/^sha256:[0-9a-f]{64}$/iu).optional()
|
|
2612
|
-
}).strict();
|
|
2613
|
-
async function readProjectPackageJson(projectDir) {
|
|
2614
|
-
return JSON.parse(await readFile5(join4(projectDir, "package.json"), "utf8"));
|
|
2615
|
-
}
|
|
2616
|
-
async function detectNextProject(projectDir) {
|
|
2617
|
-
const packageJson = await readProjectPackageJson(projectDir).catch(() => null);
|
|
2618
|
-
if (packageJson?.dependencies?.next || packageJson?.devDependencies?.next) {
|
|
2619
|
-
return true;
|
|
2620
|
-
}
|
|
2621
|
-
for (const fileName of [
|
|
2622
|
-
"next.config.js",
|
|
2623
|
-
"next.config.mjs",
|
|
2624
|
-
"next.config.ts"
|
|
2625
|
-
]) {
|
|
111
|
+
// src/runtime/fields.ts
|
|
112
|
+
function createFieldReaders(loadValues) {
|
|
113
|
+
async function read(type, fieldId, fallback) {
|
|
2626
114
|
try {
|
|
2627
|
-
await
|
|
2628
|
-
return
|
|
115
|
+
const values = await loadValues();
|
|
116
|
+
if (!Object.prototype.hasOwnProperty.call(values, fieldId)) return fallback;
|
|
117
|
+
return readFieldValue(type, values[fieldId]) ?? fallback;
|
|
2629
118
|
} catch {
|
|
119
|
+
return fallback;
|
|
2630
120
|
}
|
|
2631
121
|
}
|
|
2632
|
-
return false;
|
|
2633
|
-
}
|
|
2634
|
-
async function writeProjectConfig(projectDir, config) {
|
|
2635
|
-
const path = join4(projectDir, "siteplane.config.json");
|
|
2636
|
-
const parsed = siteplaneProjectConfigSchema.parse(config);
|
|
2637
|
-
await writeJsonAtomically(path, parsed, 420);
|
|
2638
|
-
return path;
|
|
2639
|
-
}
|
|
2640
|
-
async function readProjectConfig(projectDir) {
|
|
2641
|
-
return siteplaneProjectConfigSchema.parse(JSON.parse(await readFile5(join4(projectDir, "siteplane.config.json"), "utf8")));
|
|
2642
|
-
}
|
|
2643
|
-
async function writeJsonAtomically(path, value, mode) {
|
|
2644
|
-
const temporaryPath = `${path}.${randomUUID2()}.tmp`;
|
|
2645
|
-
const file = await open(temporaryPath, "wx", mode);
|
|
2646
|
-
try {
|
|
2647
|
-
await file.writeFile(`${JSON.stringify(value, null, 2)}
|
|
2648
|
-
`, "utf8");
|
|
2649
|
-
await file.sync();
|
|
2650
|
-
} catch (error) {
|
|
2651
|
-
await file.close();
|
|
2652
|
-
await rm(temporaryPath, { force: true });
|
|
2653
|
-
throw error;
|
|
2654
|
-
}
|
|
2655
|
-
await file.close();
|
|
2656
|
-
try {
|
|
2657
|
-
await rename(temporaryPath, path);
|
|
2658
|
-
await chmod(path, mode);
|
|
2659
|
-
} catch (error) {
|
|
2660
|
-
await rm(temporaryPath, { force: true });
|
|
2661
|
-
throw error;
|
|
2662
|
-
}
|
|
2663
|
-
}
|
|
2664
|
-
|
|
2665
|
-
// ../cli/dist/config/credentials.js
|
|
2666
|
-
import { execFile } from "child_process";
|
|
2667
|
-
import { randomUUID as randomUUID3 } from "crypto";
|
|
2668
|
-
import { chmod as chmod2, lstat, mkdir as mkdir5, open as open2, readFile as readFile6, rename as rename2, rm as rm2 } from "fs/promises";
|
|
2669
|
-
import { dirname as dirname6, join as join5, relative } from "path";
|
|
2670
|
-
import { promisify } from "util";
|
|
2671
|
-
import { z as z32 } from "zod";
|
|
2672
|
-
var localSetupInstallationSchema = z32.object({
|
|
2673
|
-
key: z32.string().regex(/^[A-Za-z0-9_-]{43}$/u),
|
|
2674
|
-
idempotencyKey: z32.string().uuid(),
|
|
2675
|
-
apiBaseUrl: z32.string().url(),
|
|
2676
|
-
request: setupInstallationRequestSchema,
|
|
2677
|
-
bootstrapAcknowledged: z32.boolean()
|
|
2678
|
-
}).strict();
|
|
2679
|
-
var siteplaneCredentialsSchema = z32.object({
|
|
2680
|
-
accessToken: z32.string().trim().min(1),
|
|
2681
|
-
siteRevalidationSecret: z32.string().trim().min(1),
|
|
2682
|
-
installation: localSetupInstallationSchema.optional(),
|
|
2683
|
-
claimReceipt: setupClaimReceiptSchema.optional(),
|
|
2684
|
-
adminSession: z32.object({
|
|
2685
|
-
secret: z32.string().regex(/^[A-Za-z0-9_-]{43}$/u),
|
|
2686
|
-
generation: z32.string().uuid()
|
|
2687
|
-
}).strict().optional()
|
|
2688
|
-
}).strict();
|
|
2689
|
-
var localSetupCredentialsSchema = z32.union([
|
|
2690
|
-
siteplaneCredentialsSchema,
|
|
2691
|
-
z32.object({ installation: localSetupInstallationSchema }).strict()
|
|
2692
|
-
]);
|
|
2693
|
-
async function assertLocalCredentialsPathSafe(projectDir, options = {}) {
|
|
2694
|
-
const path = join5(projectDir, ".siteplane/credentials.json");
|
|
2695
|
-
await assertCredentialFilesystemSafe(projectDir);
|
|
2696
|
-
const isTrackedFile = options.isTrackedFile ?? ((targetPath) => gitPathMatches(projectDir, targetPath, "ls-files"));
|
|
2697
|
-
const isIgnoredFile = options.isIgnoredFile ?? ((targetPath) => gitPathMatches(projectDir, targetPath, "check-ignore"));
|
|
2698
|
-
if (await isTrackedFile(path)) {
|
|
2699
|
-
throw new Error("Refusing to write Siteplane credentials into a tracked file.");
|
|
2700
|
-
}
|
|
2701
|
-
if (!await isIgnoredFile(path)) {
|
|
2702
|
-
throw new Error("Add .siteplane/credentials.json to .gitignore before running Siteplane init.");
|
|
2703
|
-
}
|
|
2704
|
-
return path;
|
|
2705
|
-
}
|
|
2706
|
-
async function assertCredentialFilesystemSafe(projectDir) {
|
|
2707
|
-
for (const [path, directory, mode] of [
|
|
2708
|
-
[projectDir, true, null],
|
|
2709
|
-
[join5(projectDir, ".siteplane"), true, 448],
|
|
2710
|
-
[join5(projectDir, ".siteplane/credentials.json"), false, 384]
|
|
2711
|
-
]) {
|
|
2712
|
-
const stat = await lstat(path).catch((error) => {
|
|
2713
|
-
if (error.code === "ENOENT")
|
|
2714
|
-
return null;
|
|
2715
|
-
throw error;
|
|
2716
|
-
});
|
|
2717
|
-
if (!stat)
|
|
2718
|
-
continue;
|
|
2719
|
-
if (stat.isSymbolicLink() || (directory ? !stat.isDirectory() : !stat.isFile())) {
|
|
2720
|
-
throw new Error("Siteplane credential paths must not contain symlinks or unexpected file types.");
|
|
2721
|
-
}
|
|
2722
|
-
if (mode !== null && (stat.mode & 511) !== mode) {
|
|
2723
|
-
throw new Error(`Siteplane credential ${directory ? "directory" : "file"} permissions must be ${mode.toString(8)} before setup.`);
|
|
2724
|
-
}
|
|
2725
|
-
}
|
|
2726
|
-
}
|
|
2727
|
-
async function writeLocalCredentials(projectDir, credentials, options = {}) {
|
|
2728
|
-
return writeLocalSetupCredentials(projectDir, siteplaneCredentialsSchema.parse(credentials), options);
|
|
2729
|
-
}
|
|
2730
|
-
async function writeLocalSetupCredentials(projectDir, credentials, options = {}) {
|
|
2731
|
-
const path = await assertLocalCredentialsPathSafe(projectDir, options);
|
|
2732
|
-
const parsed = localSetupCredentialsSchema.parse(credentials);
|
|
2733
|
-
await mkdir5(dirname6(path), { recursive: true, mode: 448 });
|
|
2734
|
-
await writeCredentialsAtomically(path, parsed);
|
|
2735
|
-
return path;
|
|
2736
|
-
}
|
|
2737
|
-
async function readLocalCredentials(projectDir) {
|
|
2738
|
-
const credentials = await readLocalSetupCredentials(projectDir);
|
|
2739
|
-
if (!("accessToken" in credentials)) {
|
|
2740
|
-
throw new Error("setup_exchange_pending: Run siteplane setup start to finish the stored installation exchange.");
|
|
2741
|
-
}
|
|
2742
|
-
return credentials;
|
|
2743
|
-
}
|
|
2744
|
-
async function readLocalSetupCredentials(projectDir) {
|
|
2745
|
-
await assertCredentialFilesystemSafe(projectDir);
|
|
2746
|
-
return localSetupCredentialsSchema.parse(JSON.parse(await readFile6(join5(projectDir, ".siteplane/credentials.json"), "utf8")));
|
|
2747
|
-
}
|
|
2748
|
-
async function writeCredentialsAtomically(path, credentials) {
|
|
2749
|
-
const temporaryPath = `${path}.${randomUUID3()}.tmp`;
|
|
2750
|
-
const file = await open2(temporaryPath, "wx", 384);
|
|
2751
|
-
try {
|
|
2752
|
-
await file.writeFile(`${JSON.stringify(credentials, null, 2)}
|
|
2753
|
-
`, "utf8");
|
|
2754
|
-
await file.sync();
|
|
2755
|
-
} catch (error) {
|
|
2756
|
-
await file.close();
|
|
2757
|
-
await rm2(temporaryPath, { force: true });
|
|
2758
|
-
throw error;
|
|
2759
|
-
}
|
|
2760
|
-
await file.close();
|
|
2761
|
-
try {
|
|
2762
|
-
await rename2(temporaryPath, path);
|
|
2763
|
-
await chmod2(path, 384);
|
|
2764
|
-
const directory = await open2(dirname6(path), "r");
|
|
2765
|
-
try {
|
|
2766
|
-
await directory.sync();
|
|
2767
|
-
} finally {
|
|
2768
|
-
await directory.close();
|
|
2769
|
-
}
|
|
2770
|
-
} catch (error) {
|
|
2771
|
-
await rm2(temporaryPath, { force: true });
|
|
2772
|
-
throw error;
|
|
2773
|
-
}
|
|
2774
|
-
}
|
|
2775
|
-
var execFileAsync = promisify(execFile);
|
|
2776
|
-
async function gitPathMatches(projectDir, path, command) {
|
|
2777
|
-
const args = command === "check-ignore" ? ["check-ignore", "--quiet", relative(projectDir, path)] : ["ls-files", "--error-unmatch", relative(projectDir, path)];
|
|
2778
|
-
try {
|
|
2779
|
-
await execFileAsync("git", args, { cwd: projectDir });
|
|
2780
|
-
return true;
|
|
2781
|
-
} catch {
|
|
2782
|
-
return false;
|
|
2783
|
-
}
|
|
2784
|
-
}
|
|
2785
|
-
|
|
2786
|
-
// ../cli/dist/commands/init.js
|
|
2787
|
-
import { access as access4 } from "fs/promises";
|
|
2788
|
-
import { join as join8, relative as relative3 } from "path";
|
|
2789
|
-
import { z as z35 } from "zod";
|
|
2790
|
-
|
|
2791
|
-
// ../cli/dist/commands/setup-preflight.js
|
|
2792
|
-
import { createHash as createHash2 } from "crypto";
|
|
2793
|
-
import semver from "semver";
|
|
2794
|
-
import { minimatch } from "minimatch";
|
|
2795
|
-
import { parse as parseYaml } from "yaml";
|
|
2796
|
-
|
|
2797
|
-
// ../cli/dist/config/installed-package.js
|
|
2798
|
-
import { createRequire } from "module";
|
|
2799
|
-
import { readFile as readFile7 } from "fs/promises";
|
|
2800
|
-
import { join as join6 } from "path";
|
|
2801
|
-
import { z as z33 } from "zod";
|
|
2802
|
-
var packageSchema = z33.object({
|
|
2803
|
-
name: z33.string().optional(),
|
|
2804
|
-
version: z33.string(),
|
|
2805
|
-
peerDependencies: z33.record(z33.string(), z33.string()).optional()
|
|
2806
|
-
});
|
|
2807
|
-
async function readInstalledPackage(projectDir, name2) {
|
|
2808
|
-
const require2 = createRequire(join6(projectDir, "package.json"));
|
|
2809
|
-
for (const directory of require2.resolve.paths(name2) ?? []) {
|
|
2810
|
-
try {
|
|
2811
|
-
return packageSchema.parse(JSON.parse(await readFile7(join6(directory, name2, "package.json"), "utf8")));
|
|
2812
|
-
} catch (error) {
|
|
2813
|
-
if (error.code !== "ENOENT")
|
|
2814
|
-
throw error;
|
|
2815
|
-
}
|
|
2816
|
-
}
|
|
2817
|
-
throw new Error(`Install ${name2} with the canonical package manager before setup.`);
|
|
2818
|
-
}
|
|
2819
|
-
|
|
2820
|
-
// ../cli/dist/commands/setup-preflight.js
|
|
2821
|
-
import { access as access3, readFile as readFile8, realpath, readdir, readlink } from "fs/promises";
|
|
2822
|
-
import { dirname as dirname7, join as join7, relative as relative2, resolve, sep } from "path";
|
|
2823
|
-
import { z as z34 } from "zod";
|
|
2824
|
-
|
|
2825
|
-
// ../cli/dist/commands/setup-process.js
|
|
2826
|
-
import { spawn } from "child_process";
|
|
2827
|
-
var SetupFailure = class extends Error {
|
|
2828
|
-
code;
|
|
2829
|
-
constructor(code, message) {
|
|
2830
|
-
super(message);
|
|
2831
|
-
this.code = code;
|
|
2832
|
-
}
|
|
2833
|
-
};
|
|
2834
|
-
async function setupProcess(binary, args, options) {
|
|
2835
|
-
return new Promise((resolve4, reject) => {
|
|
2836
|
-
const child = spawn(binary, args, {
|
|
2837
|
-
cwd: options.cwd,
|
|
2838
|
-
env: process.env,
|
|
2839
|
-
stdio: ["pipe", "pipe", "pipe"]
|
|
2840
|
-
});
|
|
2841
|
-
const chunks = [];
|
|
2842
|
-
const errors = [];
|
|
2843
|
-
let errorBytes = 0;
|
|
2844
|
-
let bytes = 0;
|
|
2845
|
-
let exceeded = false;
|
|
2846
|
-
const timer = setTimeout(() => {
|
|
2847
|
-
exceeded = true;
|
|
2848
|
-
child.kill("SIGKILL");
|
|
2849
|
-
}, options.timeoutMs ?? 12e4);
|
|
2850
|
-
const capture = (chunk) => {
|
|
2851
|
-
bytes += chunk.length;
|
|
2852
|
-
if (bytes > 4 * 1024 * 1024) {
|
|
2853
|
-
exceeded = true;
|
|
2854
|
-
child.kill("SIGKILL");
|
|
2855
|
-
} else
|
|
2856
|
-
chunks.push(chunk);
|
|
2857
|
-
};
|
|
2858
|
-
child.stdout.on("data", capture);
|
|
2859
|
-
child.stderr.on("data", (chunk) => {
|
|
2860
|
-
errorBytes += chunk.length;
|
|
2861
|
-
if (errorBytes <= 4 * 1024 * 1024)
|
|
2862
|
-
errors.push(chunk);
|
|
2863
|
-
else {
|
|
2864
|
-
exceeded = true;
|
|
2865
|
-
child.kill("SIGKILL");
|
|
2866
|
-
}
|
|
2867
|
-
});
|
|
2868
|
-
child.on("error", () => {
|
|
2869
|
-
clearTimeout(timer);
|
|
2870
|
-
reject(new SetupFailure("local_tool_unavailable", `${binary} could not be started. Check the local installation and access.`));
|
|
2871
|
-
});
|
|
2872
|
-
child.on("close", (code) => {
|
|
2873
|
-
clearTimeout(timer);
|
|
2874
|
-
if (exceeded)
|
|
2875
|
-
reject(new SetupFailure("provider_timeout", "The operation exceeded its time or response limit; inspect the existing operation before retrying."));
|
|
2876
|
-
else if (code !== 0) {
|
|
2877
|
-
const diagnostic = Buffer.concat([...chunks, ...errors]).toString("utf8");
|
|
2878
|
-
if (/\b(?:401|403|unauthorized|forbidden|not authenticated|not authorized|login required|E401|E403)\b/iu.test(diagnostic))
|
|
2879
|
-
reject(new SetupFailure("provider_access_denied", `${binary} denied access. Restore the existing local login and project/package permissions before retrying.`));
|
|
2880
|
-
else if (/\b(?:ECONNRESET|ETIMEDOUT|ENOTFOUND|EAI_AGAIN|ECONNREFUSED|429|502|503|504)\b/iu.test(diagnostic))
|
|
2881
|
-
reject(new SetupFailure("provider_transport_failed", `${binary} could not reach its provider. Inspect the existing operation before retrying.`));
|
|
2882
|
-
else
|
|
2883
|
-
reject(new SetupFailure("local_command_failed", `${binary} failed. Check its local login, permissions and project configuration.`));
|
|
2884
|
-
} else
|
|
2885
|
-
resolve4(Buffer.concat(options.includeStderr ? [...chunks, ...errors] : chunks).toString("utf8"));
|
|
2886
|
-
});
|
|
2887
|
-
child.stdin.on("error", () => {
|
|
2888
|
-
});
|
|
2889
|
-
child.stdin.end(options.input);
|
|
2890
|
-
});
|
|
2891
|
-
}
|
|
2892
|
-
async function setupVercelApi(cwd, endpoint, body, method, options) {
|
|
2893
|
-
const args = ["api", endpoint, "--raw"];
|
|
2894
|
-
if (body !== void 0)
|
|
2895
|
-
args.push("--method", method ?? "POST", "--input", "-");
|
|
2896
|
-
else if (method)
|
|
2897
|
-
args.push("--method", method);
|
|
2898
|
-
let output = "";
|
|
2899
|
-
for (let attempt = 0; attempt < 3; attempt++) {
|
|
2900
|
-
const remaining = (options?.deadline ?? Date.now() + 3e4) - Date.now();
|
|
2901
|
-
if (remaining <= 0)
|
|
2902
|
-
throw new SetupFailure("provider_deadline_exceeded", "The provider deadline expired; inspect the recorded operation before continuing.");
|
|
2903
|
-
try {
|
|
2904
|
-
output = await setupProcess("vercel", args, {
|
|
2905
|
-
cwd,
|
|
2906
|
-
timeoutMs: Math.min(3e4, remaining),
|
|
2907
|
-
...body === void 0 ? {} : { input: JSON.stringify(body) }
|
|
2908
|
-
});
|
|
2909
|
-
break;
|
|
2910
|
-
} catch (error) {
|
|
2911
|
-
if (!(error instanceof SetupFailure) || error.code !== "provider_transport_failed" || attempt === 2)
|
|
2912
|
-
throw error;
|
|
2913
|
-
await new Promise((resolve4) => setTimeout(resolve4, Math.min(1e3 * 2 ** attempt, Math.max(0, (options?.deadline ?? Date.now() + 2e3) - Date.now()))));
|
|
2914
|
-
}
|
|
2915
|
-
}
|
|
2916
|
-
try {
|
|
2917
|
-
return JSON.parse(output);
|
|
2918
|
-
} catch {
|
|
2919
|
-
throw new SetupFailure("invalid_provider_response", "Vercel did not return valid JSON for the bound project.");
|
|
2920
|
-
}
|
|
2921
|
-
}
|
|
2922
|
-
|
|
2923
|
-
// ../cli/dist/commands/setup-preflight.js
|
|
2924
|
-
var manifestSchema = z34.object({
|
|
2925
|
-
packageManager: z34.string().optional(),
|
|
2926
|
-
engines: z34.object({ node: z34.string().optional() }).optional(),
|
|
2927
|
-
dependencies: z34.record(z34.string(), z34.string()).optional(),
|
|
2928
|
-
devDependencies: z34.record(z34.string(), z34.string()).optional(),
|
|
2929
|
-
scripts: z34.record(z34.string(), z34.string()).optional(),
|
|
2930
|
-
workspaces: z34.unknown().optional()
|
|
2931
|
-
});
|
|
2932
|
-
var vercelProjectSchema = z34.object({
|
|
2933
|
-
id: z34.string(),
|
|
2934
|
-
accountId: z34.string(),
|
|
2935
|
-
name: z34.string(),
|
|
2936
|
-
nodeVersion: z34.string().nullable().optional(),
|
|
2937
|
-
rootDirectory: z34.string().nullable().optional(),
|
|
2938
|
-
framework: z34.string().nullable().optional(),
|
|
2939
|
-
installCommand: z34.string().nullable().optional(),
|
|
2940
|
-
buildCommand: z34.string().nullable().optional(),
|
|
2941
|
-
link: z34.object({
|
|
2942
|
-
type: z34.string(),
|
|
2943
|
-
repo: z34.string().optional(),
|
|
2944
|
-
repoId: z34.union([z34.string(), z34.number()]).optional(),
|
|
2945
|
-
org: z34.string().optional(),
|
|
2946
|
-
productionBranch: z34.string().optional()
|
|
2947
|
-
}).nullable().optional()
|
|
2948
|
-
});
|
|
2949
|
-
var exists = async (path) => access3(path).then(() => true, () => false);
|
|
2950
|
-
var fail = (code, message) => {
|
|
2951
|
-
throw new SetupFailure(code, message);
|
|
2952
|
-
};
|
|
2953
|
-
var stable = (version2, major) => new RegExp(`^${major}\\.\\d+\\.\\d+$`, "u").test(version2);
|
|
2954
|
-
async function inspectSetupLocalProject(projectDir) {
|
|
2955
|
-
const projectDirectory = await realpath(resolve(projectDir));
|
|
2956
|
-
const manifest = manifestSchema.parse(JSON.parse(await readFile8(join7(projectDirectory, "package.json"), "utf8")));
|
|
2957
|
-
const apps = (await Promise.all(["app", "src/app"].map(async (path) => await exists(join7(projectDirectory, path)) ? path : null))).filter((path) => path !== null);
|
|
2958
|
-
if (apps.length !== 1)
|
|
2959
|
-
fail("ambiguous_app_directory", "Select one Next.js App Router application with exactly one app/ or src/app/ directory.");
|
|
2960
|
-
const repositoryRoot = (await setupProcess("git", ["rev-parse", "--show-toplevel"], {
|
|
2961
|
-
cwd: projectDirectory
|
|
2962
|
-
})).trim();
|
|
2963
|
-
const tracked = await setupProcess("git", ["ls-files", "--stage", "-z"], {
|
|
2964
|
-
cwd: repositoryRoot
|
|
2965
|
-
});
|
|
2966
|
-
for (const entry of tracked.split("\0").filter(Boolean)) {
|
|
2967
|
-
if (entry.startsWith("160000 "))
|
|
2968
|
-
fail("git_submodule_conflict", "The repository contains Git submodules. Resolve the explicit deployment source boundary before setup; the CLI will not copy external repositories.");
|
|
2969
|
-
if (!entry.startsWith("120000 "))
|
|
2970
|
-
continue;
|
|
2971
|
-
const path = join7(repositoryRoot, entry.slice(entry.indexOf(" ") + 1));
|
|
2972
|
-
const target = resolve(dirname7(path), await readlink(path));
|
|
2973
|
-
const bound = relative2(repositoryRoot, target);
|
|
2974
|
-
if (bound.startsWith("..") || bound.startsWith(sep))
|
|
2975
|
-
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.");
|
|
2976
|
-
}
|
|
2977
|
-
let lockfileRoot = projectDirectory;
|
|
2978
|
-
const lockNames = [
|
|
2979
|
-
"package-lock.json",
|
|
2980
|
-
"npm-shrinkwrap.json",
|
|
2981
|
-
"pnpm-lock.yaml",
|
|
2982
|
-
"yarn.lock",
|
|
2983
|
-
"bun.lock",
|
|
2984
|
-
"bun.lockb"
|
|
2985
|
-
];
|
|
2986
|
-
let locks = [];
|
|
2987
|
-
for (; ; ) {
|
|
2988
|
-
locks = (await Promise.all(lockNames.map(async (name3) => await exists(join7(lockfileRoot, name3)) ? name3 : null))).filter((name3) => name3 !== null);
|
|
2989
|
-
if (locks.length || lockfileRoot === repositoryRoot || dirname7(lockfileRoot) === lockfileRoot)
|
|
2990
|
-
break;
|
|
2991
|
-
lockfileRoot = dirname7(lockfileRoot);
|
|
2992
|
-
}
|
|
2993
|
-
if (locks.length > 1)
|
|
2994
|
-
fail("conflicting_lockfiles", "Resolve conflicting package-manager lockfiles before setup; Siteplane does not replace them.");
|
|
2995
|
-
if (!locks.length)
|
|
2996
|
-
fail("lockfile_missing", "Install the existing application with its chosen package manager to create one canonical lockfile.");
|
|
2997
|
-
const lockName = locks[0];
|
|
2998
|
-
if (!["package-lock.json", "pnpm-lock.yaml"].includes(lockName))
|
|
2999
|
-
fail("unsupported_package_manager", "This setup supports npm 10 or pnpm 9/10 with their canonical lockfile.");
|
|
3000
|
-
const rootManifest = manifestSchema.parse(JSON.parse(await readFile8(join7(lockfileRoot, "package.json"), "utf8")));
|
|
3001
|
-
if (lockfileRoot !== projectDirectory) {
|
|
3002
|
-
const workspaceFile = join7(lockfileRoot, "pnpm-workspace.yaml");
|
|
3003
|
-
const workspace = lockName === "pnpm-lock.yaml" && await exists(workspaceFile) ? z34.object({ packages: z34.array(z34.string()) }).parse(parseYaml(await readFile8(workspaceFile, "utf8"))).packages : z34.union([
|
|
3004
|
-
z34.array(z34.string()),
|
|
3005
|
-
z34.object({ packages: z34.array(z34.string()) }).transform((value) => value.packages)
|
|
3006
|
-
]).parse(rootManifest.workspaces);
|
|
3007
|
-
const selected = relative2(lockfileRoot, projectDirectory).split(sep).join("/");
|
|
3008
|
-
if (!workspace.some((pattern) => !pattern.startsWith("!") && minimatch(selected, pattern)) || workspace.some((pattern) => pattern.startsWith("!") && minimatch(selected, pattern.slice(1))))
|
|
3009
|
-
fail("unbound_workspace_app", "The selected application is excluded from the canonical lockfile's workspace packages. Select its actual application root.");
|
|
3010
|
-
}
|
|
3011
|
-
for (let ancestor = dirname7(lockfileRoot); ancestor.startsWith(repositoryRoot + sep) || ancestor === repositoryRoot; ancestor = dirname7(ancestor)) {
|
|
3012
|
-
const ancestorLocks = await Promise.all(lockNames.map((name3) => exists(join7(ancestor, name3))));
|
|
3013
|
-
if (ancestorLocks.some(Boolean))
|
|
3014
|
-
fail("ambiguous_lockfile_root", "Both the selected package and its repository ancestors contain lockfiles. Select one canonical workspace resolution before setup.");
|
|
3015
|
-
if (ancestor === repositoryRoot)
|
|
3016
|
-
break;
|
|
3017
|
-
}
|
|
3018
|
-
const lockText = await readFile8(join7(lockfileRoot, lockName), "utf8");
|
|
3019
|
-
const npmLock = lockName === "package-lock.json" ? z34.object({
|
|
3020
|
-
lockfileVersion: z34.number(),
|
|
3021
|
-
packages: z34.record(z34.string(), z34.object({
|
|
3022
|
-
version: z34.string().optional(),
|
|
3023
|
-
peerDependencies: z34.record(z34.string(), z34.string()).optional()
|
|
3024
|
-
})).optional()
|
|
3025
|
-
}).parse(JSON.parse(lockText)) : null;
|
|
3026
|
-
async function version2(name3) {
|
|
3027
|
-
try {
|
|
3028
|
-
return (await readInstalledPackage(projectDirectory, name3)).version;
|
|
3029
|
-
} catch {
|
|
3030
|
-
const resolved = npmLock?.packages?.[`node_modules/${name3}`]?.version;
|
|
3031
|
-
if (resolved)
|
|
3032
|
-
return resolved;
|
|
3033
|
-
return fail("dependencies_not_installed", `Install the existing ${name3} dependency using the canonical lockfile before setup.`);
|
|
3034
|
-
}
|
|
3035
|
-
}
|
|
3036
|
-
const [nextVersion, reactVersion, reactDomVersion] = await Promise.all([
|
|
3037
|
-
version2("next"),
|
|
3038
|
-
version2("react"),
|
|
3039
|
-
version2("react-dom")
|
|
3040
|
-
]);
|
|
3041
|
-
if (!stable(nextVersion, 16))
|
|
3042
|
-
fail("unsupported_next_version", "Setup supports stable Next.js 16 App Router projects. Framework migration requires a separate owner decision.");
|
|
3043
|
-
if (!stable(reactVersion, 19) || reactDomVersion !== reactVersion)
|
|
3044
|
-
fail("react_version_conflict", "Use the same stable React 19/react-dom version compatible with the installed Next.js peers.");
|
|
3045
|
-
if (!stable(process.versions.node, 22))
|
|
3046
|
-
fail("unsupported_node_version", "Run setup under Node.js 22; this does not change your framework or package-manager versions.");
|
|
3047
|
-
const nextMetadata = await readInstalledPackage(projectDirectory, "next").catch(() => npmLock?.packages?.["node_modules/next"] ?? null);
|
|
3048
|
-
const peers = nextMetadata?.peerDependencies;
|
|
3049
|
-
if (!peers?.react || !peers["react-dom"])
|
|
3050
|
-
fail("next_peer_metadata_missing", "Install the locked Next.js dependency before setup so its actual React peer requirements can be checked.");
|
|
3051
|
-
if (!semver.satisfies(reactVersion, peers.react) || !semver.satisfies(reactDomVersion, peers["react-dom"]))
|
|
3052
|
-
fail("react_peer_conflict", "The installed React pair does not satisfy the installed Next.js peer requirements. Choose a compatible pair explicitly.");
|
|
3053
|
-
if (manifest.engines?.node && !semver.satisfies(process.versions.node, manifest.engines.node))
|
|
3054
|
-
fail("node_engine_conflict", "The selected application's Node engine declaration excludes the active supported Node.js 22 runtime.");
|
|
3055
|
-
const name2 = lockName === "package-lock.json" ? "npm" : "pnpm";
|
|
3056
|
-
const declared = rootManifest.packageManager ?? manifest.packageManager ?? null;
|
|
3057
|
-
if (rootManifest.packageManager && manifest.packageManager && rootManifest.packageManager !== manifest.packageManager)
|
|
3058
|
-
fail("package_manager_conflict", "Application and workspace packageManager declarations disagree.");
|
|
3059
|
-
if (declared && !new RegExp(`^${name2}@\\d+\\.\\d+\\.\\d+$`, "u").test(declared))
|
|
3060
|
-
fail("package_manager_conflict", "Declare an exact supported npm/pnpm packageManager version matching the canonical lockfile.");
|
|
3061
|
-
const localVersion = (await setupProcess(declared ? "npx" : name2, declared ? ["--yes", "--package", declared, name2, "--version"] : ["--version"], { cwd: lockfileRoot })).trim();
|
|
3062
|
-
if (!(name2 === "npm" ? stable(localVersion, 10) : stable(localVersion, 9) || stable(localVersion, 10)))
|
|
3063
|
-
fail("unsupported_package_manager_version", "Use npm 10 or pnpm 9/10; other versions are outside the initial setup support range.");
|
|
3064
|
-
if (declared && declared !== `${name2}@${localVersion}`)
|
|
3065
|
-
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.");
|
|
3066
|
-
const format = npmLock ? String(npmLock.lockfileVersion) : /^lockfileVersion:\s*['"]?([\d.]+)/mu.exec(lockText)?.[1];
|
|
3067
|
-
if (name2 === "npm" && format !== "3" || name2 === "pnpm" && format !== "9.0" && format !== "9")
|
|
3068
|
-
fail("lockfile_format_conflict", "The canonical lockfile format does not match npm 10 or pnpm 9/10.");
|
|
3069
|
-
const sourceConflicts = [];
|
|
3070
|
-
for (const file of ["next.config.js", "next.config.mjs", "next.config.ts"]) {
|
|
3071
|
-
if (!await exists(join7(projectDirectory, file)))
|
|
3072
|
-
continue;
|
|
3073
|
-
const source = await readFile8(join7(projectDirectory, file), "utf8");
|
|
3074
|
-
if (/output\s*:\s*['"]export['"]/u.test(source))
|
|
3075
|
-
sourceConflicts.push("static_export");
|
|
3076
|
-
if (/\bbasePath\s*:/u.test(source))
|
|
3077
|
-
sourceConflicts.push("base_path");
|
|
3078
|
-
if (/\bloaderFile\s*:|\bloader\s*:\s*['"](?:custom|imgix|cloudinary|akamai)['"]/u.test(source))
|
|
3079
|
-
sourceConflicts.push(`inspect_image_loader:${file}`);
|
|
3080
|
-
}
|
|
3081
|
-
if (sourceConflicts.some((conflict) => conflict === "static_export" || conflict === "base_path"))
|
|
3082
|
-
fail("unsupported_server_configuration", "Resolve static export/basePath configuration explicitly; Siteplane requires its server-side admin and revalidation handlers.");
|
|
3083
|
-
for (const name3 of [
|
|
3084
|
-
"middleware.ts",
|
|
3085
|
-
"middleware.js",
|
|
3086
|
-
"proxy.ts",
|
|
3087
|
-
"proxy.js",
|
|
3088
|
-
"src/middleware.ts",
|
|
3089
|
-
"src/middleware.js",
|
|
3090
|
-
"src/proxy.ts",
|
|
3091
|
-
"src/proxy.js"
|
|
3092
|
-
]) {
|
|
3093
|
-
if (await exists(join7(projectDirectory, name3))) {
|
|
3094
|
-
sourceConflicts.push(`inspect_routing:${name3}`);
|
|
3095
|
-
if (await readlink(join7(projectDirectory, name3)).catch(() => null))
|
|
3096
|
-
continue;
|
|
3097
|
-
const policySource = await readFile8(join7(projectDirectory, name3), "utf8");
|
|
3098
|
-
if (/Content-Security-Policy|img-src|default-src/iu.test(policySource))
|
|
3099
|
-
sourceConflicts.push(`inspect_image_csp:${name3}`);
|
|
3100
|
-
}
|
|
3101
|
-
}
|
|
3102
|
-
async function inspectSource(directory) {
|
|
3103
|
-
for (const entry of await readdir(directory, { withFileTypes: true })) {
|
|
3104
|
-
if (entry.isSymbolicLink() || ["node_modules", ".git", ".next", ".siteplane", ".vercel"].includes(entry.name))
|
|
3105
|
-
continue;
|
|
3106
|
-
const path = join7(directory, entry.name);
|
|
3107
|
-
if (entry.isDirectory()) {
|
|
3108
|
-
await inspectSource(path);
|
|
3109
|
-
continue;
|
|
3110
|
-
}
|
|
3111
|
-
if (!/\.[cm]?[jt]sx?$/u.test(entry.name))
|
|
3112
|
-
continue;
|
|
3113
|
-
const source = await readFile8(path, "utf8");
|
|
3114
|
-
if (/Content-Security-Policy|img-src|default-src/iu.test(source))
|
|
3115
|
-
sourceConflicts.push(`inspect_image_csp:${relative2(projectDirectory, path)}`);
|
|
3116
|
-
if (/from\s*["']next\/image["']/u.test(source))
|
|
3117
|
-
sourceConflicts.push(`inspect_image_policy:${relative2(projectDirectory, path)}`);
|
|
3118
|
-
if (/\b(?:Cookiebot|OneTrust|cookieyes|consentManager|cookieConsent)\b/iu.test(source))
|
|
3119
|
-
sourceConflicts.push(`inspect_existing_consent:${relative2(projectDirectory, path)}`);
|
|
3120
|
-
if (/from\s*["']next\/image["']/u.test(source) && semver.lt(nextVersion, "16.3.3"))
|
|
3121
|
-
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.`);
|
|
3122
|
-
if (/["']use server["']/u.test(source) && semver.lt(nextVersion, "16.2.11"))
|
|
3123
|
-
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.`);
|
|
3124
|
-
}
|
|
3125
|
-
}
|
|
3126
|
-
await inspectSource(join7(projectDirectory, apps[0]));
|
|
3127
|
-
const gitRead = async (args) => setupProcess("git", args, { cwd: projectDirectory }).then((value) => value.trim(), () => null);
|
|
3128
|
-
return {
|
|
3129
|
-
projectDirectory,
|
|
3130
|
-
repositoryRoot,
|
|
3131
|
-
lockfileRoot,
|
|
3132
|
-
appDirectory: apps[0],
|
|
3133
|
-
nextVersion,
|
|
3134
|
-
reactVersion,
|
|
3135
|
-
nodeVersion: process.versions.node,
|
|
3136
|
-
packageManager: { name: name2, version: localVersion, declared },
|
|
3137
|
-
lockfile: {
|
|
3138
|
-
path: relative2(repositoryRoot, join7(lockfileRoot, lockName)),
|
|
3139
|
-
format,
|
|
3140
|
-
sha256: createHash2("sha256").update(lockText).digest("hex")
|
|
3141
|
-
},
|
|
3142
|
-
git: {
|
|
3143
|
-
branch: await gitRead(["branch", "--show-current"]),
|
|
3144
|
-
revision: await gitRead(["rev-parse", "HEAD"]),
|
|
3145
|
-
remote: safeGitRemote(await gitRead(["remote", "get-url", "origin"])),
|
|
3146
|
-
changes: (await gitRead(["status", "--porcelain=v1", "--untracked-files=all"]))?.split("\n").filter(Boolean) ?? []
|
|
3147
|
-
},
|
|
3148
|
-
sourceConflicts
|
|
3149
|
-
};
|
|
3150
|
-
}
|
|
3151
|
-
async function setupPreflightCommand(input) {
|
|
3152
|
-
let local;
|
|
3153
|
-
try {
|
|
3154
|
-
local = await inspectSetupLocalProject(input.projectDir);
|
|
3155
|
-
await assertLocalCredentialsPathSafe(input.projectDir);
|
|
3156
|
-
let linkDirectory = local.projectDirectory;
|
|
3157
|
-
while (!await exists(join7(linkDirectory, ".vercel/project.json")) && linkDirectory !== local.repositoryRoot && dirname7(linkDirectory) !== linkDirectory)
|
|
3158
|
-
linkDirectory = dirname7(linkDirectory);
|
|
3159
|
-
if (!await exists(join7(linkDirectory, ".vercel/project.json")))
|
|
3160
|
-
fail("vercel_project_not_linked", "Link this application to its intended Vercel project before setup; Siteplane will not guess a target.");
|
|
3161
|
-
const linked = z34.object({
|
|
3162
|
-
projectId: z34.string().regex(/^prj_[A-Za-z0-9]+$/u),
|
|
3163
|
-
orgId: z34.string().regex(/^(?:team|user)_[A-Za-z0-9]+$/u)
|
|
3164
|
-
}).parse(JSON.parse(await readFile8(join7(linkDirectory, ".vercel/project.json"), "utf8")));
|
|
3165
|
-
const project = vercelProjectSchema.parse(await setupVercelApi(linkDirectory, `/v9/projects/${linked.projectId}?teamId=${linked.orgId}`));
|
|
3166
|
-
if (project.id !== linked.projectId || project.accountId !== linked.orgId)
|
|
3167
|
-
fail("vercel_identity_conflict", "The provider project does not match the locally linked project and team.");
|
|
3168
|
-
const expectedRoot = relative2(local.repositoryRoot, local.projectDirectory).split(sep).join("/");
|
|
3169
|
-
if ((project.rootDirectory ?? "") !== expectedRoot)
|
|
3170
|
-
fail("vercel_root_conflict", "Vercel Root Directory and the selected local app must identify the same application.");
|
|
3171
|
-
if (project.nodeVersion !== "22.x" || project.framework !== "nextjs")
|
|
3172
|
-
fail("vercel_framework_conflict", "The bound Vercel project must use Next.js with Node.js 22 before setup.");
|
|
3173
|
-
if (project.link && project.link.productionBranch !== local.git.branch)
|
|
3174
|
-
fail("vercel_production_branch_conflict", "The local branch differs from the bound Vercel Production branch.");
|
|
3175
|
-
if (project.link?.repo && project.link.org && !local.git.remote?.replace(/\.git$/u, "").endsWith(`${project.link.org}/${project.link.repo}`))
|
|
3176
|
-
fail("vercel_git_conflict", "The local origin repository differs from the Vercel Git connection.");
|
|
3177
|
-
const env = z34.object({
|
|
3178
|
-
envs: z34.array(z34.object({
|
|
3179
|
-
key: z34.string(),
|
|
3180
|
-
value: z34.string().optional(),
|
|
3181
|
-
target: z34.array(z34.string()).optional()
|
|
3182
|
-
}))
|
|
3183
|
-
}).parse(await setupVercelApi(linkDirectory, `/v10/projects/${linked.projectId}/env?teamId=${linked.orgId}`));
|
|
3184
|
-
const corepack = env.envs.some((item) => item.key === "ENABLE_EXPERIMENTAL_COREPACK" && item.value === "1" && item.target?.includes("production"));
|
|
3185
|
-
const install = project.installCommand ?? null;
|
|
3186
|
-
const selected = corepack ? "corepack" : install ? "install_override" : "automatic";
|
|
3187
|
-
if (local.packageManager.declared && selected === "automatic")
|
|
3188
|
-
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.");
|
|
3189
|
-
if (install && /\b(?:yarn|bun)\b/u.test(install))
|
|
3190
|
-
fail("vercel_package_manager_conflict", "The Vercel install override selects an unsupported package manager.");
|
|
3191
|
-
const overridePin = install ? /\b(npm|pnpm)@(\d+\.\d+\.\d+)\b/u.exec(install) : null;
|
|
3192
|
-
if (overridePin && overridePin[1] !== local.packageManager.name)
|
|
3193
|
-
fail("vercel_package_manager_conflict", "The provider override selects a different package manager than the canonical lockfile.");
|
|
3194
|
-
const overrideFamily = install ? /(?:^|[;&|]\s*)(npm|pnpm)\s+(?:ci|install)\b/u.exec(install)?.[1] : null;
|
|
3195
|
-
if (overrideFamily && overrideFamily !== local.packageManager.name)
|
|
3196
|
-
fail("vercel_package_manager_conflict", "The provider install command conflicts with the canonical lockfile.");
|
|
3197
|
-
if (overridePin && local.packageManager.declared && `${overridePin[1]}@${overridePin[2]}` !== local.packageManager.declared)
|
|
3198
|
-
fail("vercel_package_manager_conflict", "The Vercel install override conflicts with the exact packageManager declaration.");
|
|
3199
|
-
const buildRunners = (project.buildCommand ?? "").matchAll(/(?:^|[;&|\n])\s*(?:(?:corepack|npx(?:\s+(?:--yes|-y))?)\s+)?(npm|pnpm|yarn|bun)(?:@(\d+\.\d+\.\d+))?\s+(?:run\s+)?build\b/gu);
|
|
3200
|
-
for (const [, family, version2] of buildRunners) {
|
|
3201
|
-
if (family !== local.packageManager.name || version2 && local.packageManager.declared && `${family}@${version2}` !== local.packageManager.declared)
|
|
3202
|
-
fail("vercel_package_manager_conflict", "The explicit Vercel build command conflicts with the selected package manager or its declared version. Align the existing build override and rerun preflight; no setup writes were performed.");
|
|
3203
|
-
}
|
|
3204
|
-
return {
|
|
3205
|
-
status: "ready",
|
|
3206
|
-
local,
|
|
3207
|
-
provider: {
|
|
3208
|
-
projectId: project.id,
|
|
3209
|
-
teamId: project.accountId,
|
|
3210
|
-
name: project.name,
|
|
3211
|
-
rootDirectory: expectedRoot,
|
|
3212
|
-
nodeVersion: project.nodeVersion,
|
|
3213
|
-
git: project.link,
|
|
3214
|
-
installCommand: install,
|
|
3215
|
-
buildCommand: project.buildCommand ?? null,
|
|
3216
|
-
packageManagerSelection: selected,
|
|
3217
|
-
declaredPackageManager: local.packageManager.declared,
|
|
3218
|
-
observedPackageManager: null
|
|
3219
|
-
}
|
|
3220
|
-
};
|
|
3221
|
-
} catch (error) {
|
|
3222
|
-
return {
|
|
3223
|
-
status: "action_required",
|
|
3224
|
-
code: error instanceof SetupFailure ? error.code : "invalid_local_project",
|
|
3225
|
-
message: error instanceof SetupFailure ? error.message : "The selected project or provider response could not be validated. Check the application manifest and local project access.",
|
|
3226
|
-
...local ? { local } : {}
|
|
3227
|
-
};
|
|
3228
|
-
}
|
|
3229
|
-
}
|
|
3230
|
-
function safeGitRemote(value) {
|
|
3231
|
-
if (!value)
|
|
3232
|
-
return null;
|
|
3233
|
-
if (!value.includes("://"))
|
|
3234
|
-
return value;
|
|
3235
|
-
try {
|
|
3236
|
-
const url = new URL(value);
|
|
3237
|
-
url.username = "";
|
|
3238
|
-
url.password = "";
|
|
3239
|
-
url.search = "";
|
|
3240
|
-
url.hash = "";
|
|
3241
|
-
return url.toString().replace(/\/$/u, "");
|
|
3242
|
-
} catch {
|
|
3243
|
-
return null;
|
|
3244
|
-
}
|
|
3245
|
-
}
|
|
3246
|
-
|
|
3247
|
-
// ../cli/dist/commands/init.js
|
|
3248
|
-
async function initCommand(input) {
|
|
3249
|
-
if (!input.setupToken.trim()) {
|
|
3250
|
-
throw new Error("A Siteplane setup token is required.");
|
|
3251
|
-
}
|
|
3252
|
-
if (!await detectNextProject(input.projectDir)) {
|
|
3253
|
-
throw new Error("Siteplane init currently supports Next.js projects.");
|
|
3254
|
-
}
|
|
3255
|
-
await assertLocalCredentialsPathSafe(input.projectDir, {
|
|
3256
|
-
...input.isIgnoredFile ? { isIgnoredFile: input.isIgnoredFile } : {},
|
|
3257
|
-
...input.isTrackedFile ? { isTrackedFile: input.isTrackedFile } : {}
|
|
3258
|
-
});
|
|
3259
|
-
const preflight = await (input.preflight ?? setupPreflightCommand)({
|
|
3260
|
-
projectDir: input.projectDir
|
|
3261
|
-
});
|
|
3262
|
-
if (preflight.status !== "ready")
|
|
3263
|
-
throw new Error(`${preflight.code}: ${preflight.message}`);
|
|
3264
|
-
const bootstrap = await bootstrapProjectConnection(input);
|
|
3265
|
-
const paths = bootstrap.credentialPurpose === "site_setup" ? await persistSiteSetupBootstrap(input, bootstrap, relative3(preflight.local.lockfileRoot, preflight.local.projectDirectory) || ".") : await persistFeatureBootstrap(input, bootstrap);
|
|
3266
|
-
await acknowledgeBootstrapResponse(input);
|
|
3267
122
|
return {
|
|
3268
|
-
|
|
3269
|
-
|
|
3270
|
-
|
|
3271
|
-
|
|
3272
|
-
|
|
3273
|
-
]
|
|
123
|
+
text: (fieldId, fallback) => read("text", fieldId, fallback),
|
|
124
|
+
longText: (fieldId, fallback) => read("longText", fieldId, fallback),
|
|
125
|
+
link: (fieldId, fallback) => read("link", fieldId, fallback),
|
|
126
|
+
image: (fieldId, fallback) => read("image", fieldId, fallback),
|
|
127
|
+
attrs
|
|
3274
128
|
};
|
|
3275
129
|
}
|
|
3276
|
-
|
|
3277
|
-
|
|
3278
|
-
apiBaseUrl: z35.string().url(),
|
|
3279
|
-
siteId: z35.string().uuid(),
|
|
3280
|
-
publicSiteKeyId: z35.string().uuid(),
|
|
3281
|
-
publicSiteKey: z35.string().trim().min(1),
|
|
3282
|
-
accessToken: z35.string().trim().min(1),
|
|
3283
|
-
siteRevalidationSecret: z35.string().regex(/^[A-Za-z0-9_-]{43}$/u),
|
|
3284
|
-
runId: z35.string().uuid(),
|
|
3285
|
-
packages: siteSetupPackagesSchema
|
|
3286
|
-
}).strict();
|
|
3287
|
-
var featureBootstrapDataSchema = z35.object({
|
|
3288
|
-
credentialPurpose: z35.enum(["analytics", "booking"]),
|
|
3289
|
-
apiBaseUrl: z35.string().url(),
|
|
3290
|
-
siteId: z35.string().uuid(),
|
|
3291
|
-
accessToken: z35.string().trim().min(1)
|
|
3292
|
-
}).strict();
|
|
3293
|
-
var bootstrapResponseSchema = z35.object({
|
|
3294
|
-
ok: z35.literal(true),
|
|
3295
|
-
data: z35.discriminatedUnion("credentialPurpose", [
|
|
3296
|
-
siteSetupBootstrapDataSchema,
|
|
3297
|
-
featureBootstrapDataSchema
|
|
3298
|
-
])
|
|
3299
|
-
}).strict();
|
|
3300
|
-
async function bootstrapProjectConnection(input) {
|
|
3301
|
-
const fetcher = input.fetcher ?? fetch;
|
|
3302
|
-
const existing = await access4(join8(input.projectDir, "siteplane.config.json")).then(() => readProjectConfig(input.projectDir), () => null);
|
|
3303
|
-
const response = await fetcher(`${input.apiBaseUrl.replace(/\/$/, "")}/api/cli/setup/bootstrap`, {
|
|
3304
|
-
method: "POST",
|
|
3305
|
-
signal: AbortSignal.timeout(2e4),
|
|
3306
|
-
headers: createBootstrapHeaders(input),
|
|
3307
|
-
body: JSON.stringify({
|
|
3308
|
-
action: "bootstrap",
|
|
3309
|
-
...existing ? { expectedSiteId: existing.siteId, expectedRunId: existing.runId } : {},
|
|
3310
|
-
agentClient: input.agentClient ?? "codex"
|
|
3311
|
-
})
|
|
3312
|
-
});
|
|
3313
|
-
const payload = await response.json();
|
|
3314
|
-
const parsed = bootstrapResponseSchema.safeParse(payload);
|
|
3315
|
-
if (!response.ok || !parsed.success) {
|
|
3316
|
-
throw new Error(readErrorMessage(payload) ?? "Siteplane init failed.");
|
|
3317
|
-
}
|
|
3318
|
-
return parsed.data.data;
|
|
3319
|
-
}
|
|
3320
|
-
async function acknowledgeBootstrapResponse(input) {
|
|
3321
|
-
const fetcher = input.fetcher ?? fetch;
|
|
3322
|
-
const response = await fetcher(`${input.apiBaseUrl.replace(/\/$/, "")}/api/cli/setup/bootstrap`, {
|
|
3323
|
-
method: "POST",
|
|
3324
|
-
signal: AbortSignal.timeout(2e4),
|
|
3325
|
-
headers: createBootstrapHeaders(input),
|
|
3326
|
-
body: JSON.stringify({ action: "acknowledge" })
|
|
3327
|
-
});
|
|
3328
|
-
if (!response.ok) {
|
|
3329
|
-
throw new Error("Siteplane setup acknowledgement failed.");
|
|
3330
|
-
}
|
|
3331
|
-
}
|
|
3332
|
-
async function persistSiteSetupBootstrap(input, bootstrap, appDirectory, installation) {
|
|
3333
|
-
const previous = await access4(join8(input.projectDir, "siteplane.config.json")).then(() => readProjectConfig(input.projectDir), () => null);
|
|
3334
|
-
if (previous && (previous.siteId !== bootstrap.siteId || previous.runId !== bootstrap.runId || previous.publicSiteKeyId !== bootstrap.publicSiteKeyId || previous.publicSiteKey !== bootstrap.publicSiteKey))
|
|
3335
|
-
throw new Error("The grant does not match this local Siteplane run. Preserve this directory and choose the correct owner connection.");
|
|
3336
|
-
const previousCredentials = previous ? await access4(join8(input.projectDir, ".siteplane/credentials.json")).then(() => readLocalSetupCredentials(input.projectDir), () => null) : null;
|
|
3337
|
-
const credentialsPath = await writeLocalCredentials(input.projectDir, {
|
|
3338
|
-
...previousCredentials && "adminSession" in previousCredentials && previousCredentials.adminSession ? { adminSession: previousCredentials.adminSession } : {},
|
|
3339
|
-
...previousCredentials && "claimReceipt" in previousCredentials && previousCredentials.claimReceipt ? { claimReceipt: previousCredentials.claimReceipt } : {},
|
|
3340
|
-
accessToken: bootstrap.accessToken,
|
|
3341
|
-
siteRevalidationSecret: bootstrap.siteRevalidationSecret,
|
|
3342
|
-
...installation ?? previousCredentials?.installation ? { installation: installation ?? previousCredentials?.installation } : {}
|
|
3343
|
-
}, {
|
|
3344
|
-
...input.isIgnoredFile ? { isIgnoredFile: input.isIgnoredFile } : {},
|
|
3345
|
-
...input.isTrackedFile ? { isTrackedFile: input.isTrackedFile } : {}
|
|
3346
|
-
});
|
|
3347
|
-
const configPath = await writeProjectConfig(input.projectDir, {
|
|
3348
|
-
...previous ?? {},
|
|
3349
|
-
version: 2,
|
|
3350
|
-
appDirectory,
|
|
3351
|
-
runId: bootstrap.runId,
|
|
3352
|
-
packages: bootstrap.packages,
|
|
3353
|
-
taskContractVersion: "siteplane.setup-task.v2",
|
|
3354
|
-
adminProtocolVersion: 2,
|
|
3355
|
-
apiBaseUrl: bootstrap.apiBaseUrl,
|
|
3356
|
-
siteId: bootstrap.siteId,
|
|
3357
|
-
publicSiteKeyId: bootstrap.publicSiteKeyId,
|
|
3358
|
-
publicSiteKey: bootstrap.publicSiteKey
|
|
3359
|
-
});
|
|
3360
|
-
const [credentials, config] = await Promise.all([
|
|
3361
|
-
readLocalCredentials(input.projectDir),
|
|
3362
|
-
readProjectConfig(input.projectDir)
|
|
3363
|
-
]);
|
|
3364
|
-
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.packages.analytics !== bootstrap.packages.analytics || config.apiBaseUrl !== bootstrap.apiBaseUrl || config.siteId !== bootstrap.siteId || config.publicSiteKeyId !== bootstrap.publicSiteKeyId || config.publicSiteKey !== bootstrap.publicSiteKey) {
|
|
3365
|
-
throw new Error("Siteplane setup files could not be verified.");
|
|
3366
|
-
}
|
|
3367
|
-
return { configPath, credentialsPath };
|
|
3368
|
-
}
|
|
3369
|
-
async function persistFeatureBootstrap(input, bootstrap) {
|
|
3370
|
-
const [config, existingCredentials] = await Promise.all([
|
|
3371
|
-
readProjectConfig(input.projectDir),
|
|
3372
|
-
readLocalCredentials(input.projectDir)
|
|
3373
|
-
]);
|
|
3374
|
-
if (config.siteId !== bootstrap.siteId) {
|
|
3375
|
-
throw new Error("The setup token belongs to a different Siteplane site.");
|
|
3376
|
-
}
|
|
3377
|
-
const credentialsPath = await writeLocalCredentials(input.projectDir, {
|
|
3378
|
-
...existingCredentials,
|
|
3379
|
-
accessToken: bootstrap.accessToken
|
|
3380
|
-
}, {
|
|
3381
|
-
...input.isIgnoredFile ? { isIgnoredFile: input.isIgnoredFile } : {},
|
|
3382
|
-
...input.isTrackedFile ? { isTrackedFile: input.isTrackedFile } : {}
|
|
3383
|
-
});
|
|
3384
|
-
const persistedCredentials = await readLocalCredentials(input.projectDir);
|
|
3385
|
-
if (persistedCredentials.accessToken !== bootstrap.accessToken || persistedCredentials.siteRevalidationSecret !== existingCredentials.siteRevalidationSecret) {
|
|
3386
|
-
throw new Error("Siteplane credentials could not be verified.");
|
|
3387
|
-
}
|
|
3388
|
-
return {
|
|
3389
|
-
configPath: join8(input.projectDir, "siteplane.config.json"),
|
|
3390
|
-
credentialsPath
|
|
3391
|
-
};
|
|
130
|
+
function attrs(fieldId) {
|
|
131
|
+
return typeof fieldId === "string" ? { "data-siteplane-field": fieldId } : {};
|
|
3392
132
|
}
|
|
3393
|
-
function createBootstrapHeaders(input) {
|
|
3394
|
-
return new Headers({
|
|
3395
|
-
authorization: `Bearer ${input.setupToken}`,
|
|
3396
|
-
"content-type": "application/json",
|
|
3397
|
-
...input.vercelAutomationBypassSecret?.trim() ? {
|
|
3398
|
-
"x-vercel-protection-bypass": input.vercelAutomationBypassSecret.trim()
|
|
3399
|
-
} : {}
|
|
3400
|
-
});
|
|
3401
|
-
}
|
|
3402
|
-
function readErrorMessage(payload) {
|
|
3403
|
-
if (payload && typeof payload === "object" && "error" in payload && payload.error && typeof payload.error === "object" && "message" in payload.error && typeof payload.error.message === "string") {
|
|
3404
|
-
const code = "code" in payload.error && typeof payload.error.code === "string" ? payload.error.code : null;
|
|
3405
|
-
return code ? `${code}: ${payload.error.message}` : payload.error.message;
|
|
3406
|
-
}
|
|
3407
|
-
return null;
|
|
3408
|
-
}
|
|
3409
|
-
|
|
3410
|
-
// ../cli/dist/commands/scan.js
|
|
3411
|
-
import { readdir as readdir2 } from "fs/promises";
|
|
3412
|
-
import { extname, join as join9 } from "path";
|
|
3413
|
-
var defaultScanRoots = ["app", "src", "pages", "components", "lib"];
|
|
3414
|
-
var excludedDirectories = /* @__PURE__ */ new Set([
|
|
3415
|
-
".git",
|
|
3416
|
-
".next",
|
|
3417
|
-
".turbo",
|
|
3418
|
-
".vercel",
|
|
3419
|
-
"build",
|
|
3420
|
-
"coverage",
|
|
3421
|
-
"dist",
|
|
3422
|
-
"node_modules"
|
|
3423
|
-
]);
|
|
3424
|
-
var sourceExtensions = /* @__PURE__ */ new Set([".js", ".jsx", ".ts", ".tsx"]);
|
|
3425
|
-
async function resolveScanFilePaths(filePaths, options = {}) {
|
|
3426
|
-
if (filePaths.length > 0) {
|
|
3427
|
-
return filePaths;
|
|
3428
|
-
}
|
|
3429
|
-
const projectDir = options.projectDir ?? process.cwd();
|
|
3430
|
-
const discovered = await Promise.all(defaultScanRoots.map((root) => collectSourceFiles(join9(projectDir, root))));
|
|
3431
|
-
return [...new Set(discovered.flat())].sort();
|
|
3432
|
-
}
|
|
3433
|
-
async function collectSourceFiles(directory) {
|
|
3434
|
-
const entries = await readdir2(directory, { withFileTypes: true }).catch(() => []);
|
|
3435
|
-
const files = [];
|
|
3436
|
-
for (const entry of entries) {
|
|
3437
|
-
const entryPath = join9(directory, entry.name);
|
|
3438
|
-
if (entry.isDirectory()) {
|
|
3439
|
-
if (!excludedDirectories.has(entry.name)) {
|
|
3440
|
-
files.push(...await collectSourceFiles(entryPath));
|
|
3441
|
-
}
|
|
3442
|
-
continue;
|
|
3443
|
-
}
|
|
3444
|
-
if (entry.isFile() && sourceExtensions.has(extname(entry.name))) {
|
|
3445
|
-
files.push(entryPath);
|
|
3446
|
-
}
|
|
3447
|
-
}
|
|
3448
|
-
return files;
|
|
3449
|
-
}
|
|
3450
|
-
|
|
3451
|
-
// ../cli/dist/commands/site-setup.js
|
|
3452
|
-
import { execFile as execFile2 } from "child_process";
|
|
3453
|
-
import { readFile as readFile9 } from "fs/promises";
|
|
3454
|
-
import { promisify as promisify2 } from "util";
|
|
3455
|
-
import { z as z36 } from "zod";
|
|
3456
|
-
|
|
3457
|
-
// ../cli/dist/scan/next-source-scan.js
|
|
3458
|
-
import ts3 from "typescript";
|
|
3459
|
-
import { isAbsolute, relative as relative4 } from "path";
|
|
3460
|
-
var legacyEditableComponentPrefix = "Editable";
|
|
3461
|
-
var editableComponentNames = new Set(["Image", "Text", "LongText", "Link"].map((name2) => `${legacyEditableComponentPrefix}${name2}`));
|
|
3462
|
-
|
|
3463
|
-
// ../cli/dist/commands/site-setup.js
|
|
3464
|
-
var execFileAsync2 = promisify2(execFile2);
|
|
3465
|
-
var safeErrorSchema = z36.object({
|
|
3466
|
-
code: z36.string().trim().min(1),
|
|
3467
|
-
message: z36.string().trim().min(1)
|
|
3468
|
-
}).passthrough();
|
|
3469
|
-
var errorResponseSchema2 = z36.object({ ok: z36.literal(false), error: safeErrorSchema }).passthrough();
|
|
3470
|
-
var contextDataSchema = z36.object({
|
|
3471
|
-
task: siteSetupTaskSchema.refine((task) => task.run !== null)
|
|
3472
|
-
}).strict();
|
|
3473
|
-
var contextResponseSchema = z36.object({ ok: z36.literal(true), data: contextDataSchema }).strict();
|
|
3474
|
-
var applyDataSchema = z36.object({
|
|
3475
|
-
status: z36.enum(["applied", "ready_for_review"]),
|
|
3476
|
-
runId: z36.string().uuid().optional(),
|
|
3477
|
-
contractVersionId: z36.string().uuid().optional(),
|
|
3478
|
-
fieldContractHash: z36.string().regex(/^sha256:[0-9a-f]{64}$/u),
|
|
3479
|
-
editorDefinitionHash: z36.string().regex(/^sha256:[0-9a-f]{64}$/u).optional(),
|
|
3480
|
-
fieldCount: z36.number().int().nonnegative().optional(),
|
|
3481
|
-
routeCount: z36.number().int().nonnegative().optional()
|
|
3482
|
-
}).strict();
|
|
3483
|
-
var applyResponseSchema = z36.object({ ok: z36.literal(true), data: applyDataSchema }).strict();
|
|
3484
|
-
var verifyDataSchema = z36.object({
|
|
3485
|
-
status: z36.literal("ready_for_review"),
|
|
3486
|
-
runId: z36.string().uuid().optional(),
|
|
3487
|
-
deploymentOrigin: z36.string().url().optional(),
|
|
3488
|
-
deploymentRevision: z36.string().optional()
|
|
3489
|
-
}).strict();
|
|
3490
|
-
var verifyResponseSchema = z36.object({ ok: z36.literal(true), data: verifyDataSchema }).strict();
|
|
3491
|
-
async function siteSetupContextCommand(input) {
|
|
3492
|
-
const response = await postSiteSetup(input, "context", {});
|
|
3493
|
-
const parsed = contextResponseSchema.safeParse(response.payload);
|
|
3494
|
-
if (response.ok && parsed.success) {
|
|
3495
|
-
return { status: "ok", ...parsed.data.data };
|
|
3496
|
-
}
|
|
3497
|
-
return actionRequired(response.payload, "Siteplane setup context is unavailable.");
|
|
3498
|
-
}
|
|
3499
|
-
async function siteSetupVerifyCommand(input) {
|
|
3500
|
-
const resolveSourceFiles = input.resolveSourceFiles ?? resolveScanFilePaths;
|
|
3501
|
-
const readSourceFile = input.readSourceFile ?? ((path) => readFile9(path, "utf8"));
|
|
3502
|
-
const paths = await resolveSourceFiles([], { projectDir: input.projectDir });
|
|
3503
|
-
const sources = await Promise.all(paths.map(readSourceFile));
|
|
3504
|
-
if (!sources.some(hasMountedFieldRuntimeBridge)) {
|
|
3505
|
-
return {
|
|
3506
|
-
status: "action_required",
|
|
3507
|
-
code: "missing_field_runtime_bridge",
|
|
3508
|
-
message: "Mount FieldRuntimeBridge from @siteplane/runtime-next/client before deployment verification."
|
|
3509
|
-
};
|
|
3510
|
-
}
|
|
3511
|
-
const deploymentRevision = await (input.readRevision ?? readGitRevision)(input.projectDir);
|
|
3512
|
-
const response = await postSiteSetup(input, "verify", {
|
|
3513
|
-
deploymentUrl: input.deploymentUrl,
|
|
3514
|
-
deploymentRevision,
|
|
3515
|
-
...input.wait ? { wait: true } : {}
|
|
3516
|
-
});
|
|
3517
|
-
const parsed = verifyResponseSchema.safeParse(response.payload);
|
|
3518
|
-
if (response.ok && parsed.success) {
|
|
3519
|
-
return parsed.data.data;
|
|
3520
|
-
}
|
|
3521
|
-
return actionRequired(response.payload, "Siteplane deployment verification failed.");
|
|
3522
|
-
}
|
|
3523
|
-
function hasMountedFieldRuntimeBridge(source) {
|
|
3524
|
-
return /from\s+["']@siteplane\/runtime-next(?:\/client)?["']/u.test(source) && /<FieldRuntimeBridge(?:\s|\/|>)/u.test(source);
|
|
3525
|
-
}
|
|
3526
|
-
async function postSiteSetup(input, operation, body) {
|
|
3527
|
-
const [config, credentials] = await Promise.all([
|
|
3528
|
-
readProjectConfig(input.projectDir),
|
|
3529
|
-
readLocalCredentials(input.projectDir)
|
|
3530
|
-
]);
|
|
3531
|
-
try {
|
|
3532
|
-
const response = await (input.fetcher ?? fetch)(`${config.apiBaseUrl.replace(/\/$/u, "")}/api/cli/setup/${operation}`, {
|
|
3533
|
-
method: "POST",
|
|
3534
|
-
signal: AbortSignal.timeout(Math.max(1, Math.min(2e4, (input.deadline ?? Date.now() + 2e4) - Date.now()))),
|
|
3535
|
-
headers: {
|
|
3536
|
-
authorization: `Bearer ${credentials.accessToken}`,
|
|
3537
|
-
"content-type": "application/json",
|
|
3538
|
-
...input.vercelAutomationBypassSecret?.trim() ? {
|
|
3539
|
-
"x-vercel-protection-bypass": input.vercelAutomationBypassSecret.trim()
|
|
3540
|
-
} : {}
|
|
3541
|
-
},
|
|
3542
|
-
body: JSON.stringify(body)
|
|
3543
|
-
});
|
|
3544
|
-
const payload = await response.json().catch(() => null);
|
|
3545
|
-
return { ok: response.ok, payload };
|
|
3546
|
-
} catch {
|
|
3547
|
-
return {
|
|
3548
|
-
ok: false,
|
|
3549
|
-
payload: {
|
|
3550
|
-
ok: false,
|
|
3551
|
-
error: {
|
|
3552
|
-
code: "site_setup.transport_failed",
|
|
3553
|
-
message: "The setup request was not acknowledged. Reload the existing task before retrying; no credential values are included."
|
|
3554
|
-
}
|
|
3555
|
-
}
|
|
3556
|
-
};
|
|
3557
|
-
}
|
|
3558
|
-
}
|
|
3559
|
-
function actionRequired(payload, fallbackMessage) {
|
|
3560
|
-
const parsed = errorResponseSchema2.safeParse(payload);
|
|
3561
|
-
return parsed.success ? {
|
|
3562
|
-
status: "action_required",
|
|
3563
|
-
code: parsed.data.error.code,
|
|
3564
|
-
message: parsed.data.error.message
|
|
3565
|
-
} : {
|
|
3566
|
-
status: "action_required",
|
|
3567
|
-
code: "invalid_server_response",
|
|
3568
|
-
message: fallbackMessage
|
|
3569
|
-
};
|
|
3570
|
-
}
|
|
3571
|
-
async function readGitRevision(projectDir) {
|
|
3572
|
-
const { stdout } = await execFileAsync2("git", ["rev-parse", "HEAD"], {
|
|
3573
|
-
cwd: projectDir,
|
|
3574
|
-
encoding: "utf8"
|
|
3575
|
-
});
|
|
3576
|
-
const revision = stdout.trim();
|
|
3577
|
-
if (!revision) {
|
|
3578
|
-
throw new Error("A committed Git revision is required before setup verify.");
|
|
3579
|
-
}
|
|
3580
|
-
return revision;
|
|
3581
|
-
}
|
|
3582
|
-
|
|
3583
|
-
// ../cli/dist/commands/setup-start.js
|
|
3584
|
-
import { randomBytes, randomUUID as randomUUID4 } from "crypto";
|
|
3585
|
-
import { access as access5 } from "fs/promises";
|
|
3586
|
-
import { join as join10, relative as relative5 } from "path";
|
|
3587
|
-
import { z as z37 } from "zod";
|
|
3588
|
-
var bootstrapResponseSchema2 = z37.object({
|
|
3589
|
-
ok: z37.literal(true),
|
|
3590
|
-
data: siteSetupBootstrapDataSchema
|
|
3591
|
-
}).strict();
|
|
3592
|
-
|
|
3593
|
-
// ../cli/dist/commands/setup-review.js
|
|
3594
|
-
import { z as z38 } from "zod";
|
|
3595
|
-
var responseSchema2 = z38.object({
|
|
3596
|
-
ok: z38.literal(true),
|
|
3597
|
-
data: z38.object({
|
|
3598
|
-
reviewUrl: z38.string().url(),
|
|
3599
|
-
expiresAt: z38.string().datetime({ offset: true })
|
|
3600
|
-
}).strict()
|
|
3601
|
-
}).strict();
|
|
3602
|
-
|
|
3603
|
-
// ../cli/dist/commands/setup-prepare.js
|
|
3604
|
-
import { access as access6, lstat as lstat2, mkdir as mkdir6, open as open3, readFile as readFile10, rename as rename3, rm as rm3 } from "fs/promises";
|
|
3605
|
-
import { randomUUID as randomUUID5 } from "crypto";
|
|
3606
|
-
import { dirname as dirname8, join as join11, relative as relative6, sep as sep2 } from "path";
|
|
3607
|
-
import ts4 from "typescript";
|
|
3608
|
-
|
|
3609
|
-
// ../cli/dist/commands/setup-lock.js
|
|
3610
|
-
import { randomUUID as randomUUID6 } from "crypto";
|
|
3611
|
-
import { lstat as lstat3, mkdir as mkdir7, open as open4, readFile as readFile11, rm as rm4, rmdir } from "fs/promises";
|
|
3612
|
-
import { resolve as resolve2 } from "path";
|
|
3613
|
-
import { z as z39 } from "zod";
|
|
3614
|
-
var ownerSchema = z39.object({ pid: z39.number().int().positive(), nonce: z39.string().uuid() }).strict();
|
|
3615
|
-
|
|
3616
|
-
// ../cli/dist/config/build-provenance.js
|
|
3617
|
-
import { createHash as createHash3 } from "crypto";
|
|
3618
|
-
import { execFile as execFile3 } from "child_process";
|
|
3619
|
-
import { lstat as lstat4, readFile as readFile12, writeFile as writeFile5, mkdir as mkdir8 } from "fs/promises";
|
|
3620
|
-
import { dirname as dirname9, isAbsolute as isAbsolute2, join as join12, relative as relative7, resolve as resolve3, sep as sep3 } from "path";
|
|
3621
|
-
import { isDeepStrictEqual, promisify as promisify3 } from "util";
|
|
3622
|
-
import { z as z40 } from "zod";
|
|
3623
|
-
var execute = promisify3(execFile3);
|
|
3624
|
-
var name = ".siteplane/build-source.json";
|
|
3625
|
-
var oid = z40.string().regex(/^[0-9a-f]{40}$/u);
|
|
3626
|
-
var entrySchema = z40.object({
|
|
3627
|
-
path: z40.string().min(1).max(4096),
|
|
3628
|
-
mode: z40.enum(["100644", "100755", "120000"]),
|
|
3629
|
-
oid
|
|
3630
|
-
}).strict();
|
|
3631
|
-
var schema = z40.object({
|
|
3632
|
-
version: z40.literal(2),
|
|
3633
|
-
revision: oid,
|
|
3634
|
-
commit: z40.string().min(1).max(1048576),
|
|
3635
|
-
entries: z40.array(entrySchema).min(1).max(1e5),
|
|
3636
|
-
providerConfigurations: z40.array(z40.object({
|
|
3637
|
-
path: z40.string().max(4096).regex(/(?:^|\/)vercel\.json$/u),
|
|
3638
|
-
source: z40.string().max(1048576)
|
|
3639
|
-
}).strict()).max(1e3)
|
|
3640
|
-
}).strict();
|
|
3641
|
-
async function writeBuildProvenance(checkout, revision) {
|
|
3642
|
-
const commit = (await execute("git", ["cat-file", "commit", revision], {
|
|
3643
|
-
cwd: checkout,
|
|
3644
|
-
maxBuffer: 1048576
|
|
3645
|
-
})).stdout;
|
|
3646
|
-
const tree = (await execute("git", ["ls-tree", "-rz", "--full-tree", revision], {
|
|
3647
|
-
cwd: checkout,
|
|
3648
|
-
maxBuffer: 16777216
|
|
3649
|
-
})).stdout;
|
|
3650
|
-
const entries = tree.split("\0").filter(Boolean).map((line) => {
|
|
3651
|
-
const match = /^(100644|100755|120000) blob ([0-9a-f]{40})\t([\s\S]+)$/u.exec(line);
|
|
3652
|
-
if (!match)
|
|
3653
|
-
throw new Error("Git submodules or unsupported tracked objects need an explicit deployment configuration.");
|
|
3654
|
-
return { path: match[3], mode: match[1], oid: match[2] };
|
|
3655
|
-
});
|
|
3656
|
-
for (const entry of entries) {
|
|
3657
|
-
if (entry.mode !== "120000")
|
|
3658
|
-
continue;
|
|
3659
|
-
const { readlink: readlink2 } = await import("fs/promises");
|
|
3660
|
-
const path = join12(checkout, entry.path);
|
|
3661
|
-
const target2 = resolve3(dirname9(path), await readlink2(path));
|
|
3662
|
-
const bound = relative7(checkout, target2);
|
|
3663
|
-
if (bound.startsWith("..") || isAbsolute2(bound))
|
|
3664
|
-
throw new Error("A tracked symbolic link escapes the committed upload; resolve that source boundary before deployment.");
|
|
3665
|
-
}
|
|
3666
|
-
const providerConfigurations = await Promise.all(entries.filter((entry) => /(?:^|\/)vercel\.json$/u.test(entry.path)).map(async (entry) => ({
|
|
3667
|
-
path: entry.path,
|
|
3668
|
-
source: await readFile12(join12(checkout, entry.path), "utf8")
|
|
3669
|
-
})));
|
|
3670
|
-
const record = schema.parse({
|
|
3671
|
-
version: 2,
|
|
3672
|
-
revision,
|
|
3673
|
-
commit,
|
|
3674
|
-
entries,
|
|
3675
|
-
providerConfigurations
|
|
3676
|
-
});
|
|
3677
|
-
const target = join12(checkout, name);
|
|
3678
|
-
await mkdir8(dirname9(target), { recursive: true, mode: 448 });
|
|
3679
|
-
await writeFile5(target, JSON.stringify(record), { flag: "wx", mode: 384 });
|
|
3680
|
-
}
|
|
3681
|
-
|
|
3682
|
-
// ../cli/dist/commands/setup-deploy.js
|
|
3683
|
-
import { createHash as createHash4, randomBytes as randomBytes2, randomUUID as randomUUID7 } from "crypto";
|
|
3684
|
-
import { access as access7, mkdir as mkdir9, mkdtemp, rm as rm5, writeFile as writeFile6 } from "fs/promises";
|
|
3685
|
-
import { tmpdir } from "os";
|
|
3686
|
-
import { join as join13 } from "path";
|
|
3687
|
-
import { z as z41 } from "zod";
|
|
3688
|
-
var envSchema = z41.object({
|
|
3689
|
-
id: z41.string(),
|
|
3690
|
-
key: z41.string(),
|
|
3691
|
-
target: z41.array(z41.string()),
|
|
3692
|
-
type: z41.string(),
|
|
3693
|
-
comment: z41.string().optional(),
|
|
3694
|
-
updatedAt: z41.number().optional()
|
|
3695
|
-
});
|
|
3696
|
-
var deploymentSchema = z41.object({
|
|
3697
|
-
id: z41.string(),
|
|
3698
|
-
projectId: z41.string(),
|
|
3699
|
-
ownerId: z41.string().optional(),
|
|
3700
|
-
target: z41.string().nullable(),
|
|
3701
|
-
readyState: z41.string(),
|
|
3702
|
-
createdAt: z41.number(),
|
|
3703
|
-
url: z41.string(),
|
|
3704
|
-
meta: z41.record(z41.string(), z41.unknown()).optional(),
|
|
3705
|
-
gitSource: z41.object({ sha: z41.string().optional() }).nullable().optional()
|
|
3706
|
-
});
|
|
3707
|
-
var buildProofSchema = z41.object({
|
|
3708
|
-
node: z41.string(),
|
|
3709
|
-
packageManager: z41.enum(["npm", "pnpm"]),
|
|
3710
|
-
packageManagerVersion: z41.string(),
|
|
3711
|
-
lockfileHash: z41.string(),
|
|
3712
|
-
revision: z41.string(),
|
|
3713
|
-
fieldContractHash: z41.string(),
|
|
3714
|
-
siteplane: z41.string(),
|
|
3715
|
-
runtimeNext: z41.string(),
|
|
3716
|
-
analytics: z41.string().optional(),
|
|
3717
|
-
next: z41.string(),
|
|
3718
|
-
react: z41.string()
|
|
3719
|
-
}).strict();
|
|
3720
|
-
var defaults = {
|
|
3721
|
-
preflight: setupPreflightCommand,
|
|
3722
|
-
context: siteSetupContextCommand,
|
|
3723
|
-
api: setupVercelApi,
|
|
3724
|
-
process: setupProcess,
|
|
3725
|
-
verify: siteSetupVerifyCommand,
|
|
3726
|
-
post: postSiteSetup,
|
|
3727
|
-
writeBuildProvenance,
|
|
3728
|
-
analyticsPublicKey: analyticsPublicKeyCommand,
|
|
3729
|
-
now: Date.now,
|
|
3730
|
-
pause: (milliseconds) => new Promise((resolve4) => setTimeout(resolve4, milliseconds))
|
|
3731
|
-
};
|
|
3732
133
|
|
|
3733
|
-
//
|
|
3734
|
-
|
|
134
|
+
// src/index.ts
|
|
135
|
+
var siteplane = createFieldReaders(cache(loadSiteValues));
|
|
3735
136
|
export {
|
|
3736
|
-
|
|
3737
|
-
bookingInitCommand,
|
|
3738
|
-
bookingSyncCommand,
|
|
3739
|
-
bookingTestCommand,
|
|
3740
|
-
exportCommand,
|
|
3741
|
-
initCommand
|
|
137
|
+
siteplane
|
|
3742
138
|
};
|