siteplane 0.1.66 → 0.1.68
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +30 -147
- package/dist/bin/siteplane.js +923 -5592
- package/dist/index.js +568 -2387
- package/dist/next.d.ts +1 -2
- package/dist/next.js +624 -2320
- package/package.json +1 -1
package/dist/next.js
CHANGED
|
@@ -1,19 +1,41 @@
|
|
|
1
1
|
// src/next.ts
|
|
2
|
-
import { execFile
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import { promisify as promisify4 } from "util";
|
|
2
|
+
import { execFile } from "child_process";
|
|
3
|
+
import { access as access2, readFile as readFile5 } from "fs/promises";
|
|
4
|
+
import { join as join6, resolve } from "path";
|
|
5
|
+
import { promisify } from "util";
|
|
7
6
|
|
|
8
|
-
// ../cli/dist/
|
|
7
|
+
// ../cli/dist/booking/manifest.js
|
|
9
8
|
import { mkdir, readFile, writeFile } from "fs/promises";
|
|
10
9
|
import { dirname } from "path";
|
|
11
10
|
|
|
12
11
|
// ../shared/dist/actors.js
|
|
13
12
|
import { z } from "zod";
|
|
14
|
-
var ACTOR_TYPES = ["workspace_member", "site_member", "agent", "
|
|
13
|
+
var ACTOR_TYPES = ["workspace_member", "site_member", "agent", "system"];
|
|
15
14
|
var actorTypeSchema = z.enum(ACTOR_TYPES);
|
|
16
15
|
|
|
16
|
+
// ../shared/dist/agent-connection.js
|
|
17
|
+
import { z as z2 } from "zod";
|
|
18
|
+
var AGENT_CONNECTION_TOKEN_PREFIX = "sp_agent_";
|
|
19
|
+
var deviceAuthorizationResponseSchema = z2.object({
|
|
20
|
+
device_code: z2.string().min(43),
|
|
21
|
+
user_code: z2.string().min(8),
|
|
22
|
+
verification_uri: z2.string().url(),
|
|
23
|
+
verification_uri_complete: z2.string().url(),
|
|
24
|
+
expires_in: z2.number().int().positive(),
|
|
25
|
+
interval: z2.number().int().positive()
|
|
26
|
+
});
|
|
27
|
+
var deviceTokenResponseSchema = z2.object({
|
|
28
|
+
access_token: z2.string().startsWith(AGENT_CONNECTION_TOKEN_PREFIX).min(40),
|
|
29
|
+
token_type: z2.literal("Bearer"),
|
|
30
|
+
scope: z2.string(),
|
|
31
|
+
expires_in: z2.number().int().positive()
|
|
32
|
+
});
|
|
33
|
+
var deviceTokenErrorSchema = z2.object({
|
|
34
|
+
error: z2.string(),
|
|
35
|
+
error_description: z2.string().optional(),
|
|
36
|
+
interval: z2.number().int().positive().optional()
|
|
37
|
+
});
|
|
38
|
+
|
|
17
39
|
// ../shared/dist/analytics-defaults.js
|
|
18
40
|
var ANALYTICS_BATCH_LIMITS = {
|
|
19
41
|
maxEventsPerRequest: 50,
|
|
@@ -30,7 +52,7 @@ var ANALYTICS_RETENTION_DEFAULTS = {
|
|
|
30
52
|
};
|
|
31
53
|
|
|
32
54
|
// ../shared/dist/analytics-booking.js
|
|
33
|
-
import { z as
|
|
55
|
+
import { z as z3 } from "zod";
|
|
34
56
|
var bookingProviders = ["treatwell", "beautinda", "other"];
|
|
35
57
|
var bookingAttributionModes = [
|
|
36
58
|
"outbound_click_and_utm",
|
|
@@ -52,16 +74,16 @@ var bookingAttributionConfidences = [
|
|
|
52
74
|
"manual_import",
|
|
53
75
|
"verified_webhook"
|
|
54
76
|
];
|
|
55
|
-
var bookingProviderSchema =
|
|
56
|
-
var bookingAttributionModeSchema =
|
|
57
|
-
var bookingSignalSourceSchema =
|
|
58
|
-
var bookingAttributionConfidenceSchema =
|
|
59
|
-
var bookingProviderHintSchema =
|
|
77
|
+
var bookingProviderSchema = z3.enum(bookingProviders);
|
|
78
|
+
var bookingAttributionModeSchema = z3.enum(bookingAttributionModes);
|
|
79
|
+
var bookingSignalSourceSchema = z3.enum(bookingSignalSources);
|
|
80
|
+
var bookingAttributionConfidenceSchema = z3.enum(bookingAttributionConfidences);
|
|
81
|
+
var bookingProviderHintSchema = z3.object({
|
|
60
82
|
bookingProvider: bookingProviderSchema,
|
|
61
|
-
bookingUrlHost:
|
|
83
|
+
bookingUrlHost: z3.string().min(1).max(253),
|
|
62
84
|
bookingAttributionMode: bookingAttributionModeSchema,
|
|
63
|
-
utmContent:
|
|
64
|
-
successCondition:
|
|
85
|
+
utmContent: z3.string().min(1).max(200).optional(),
|
|
86
|
+
successCondition: z3.literal("redirect_status=succeeded").optional()
|
|
65
87
|
}).superRefine((hint, context) => {
|
|
66
88
|
if (hint.successCondition !== void 0 && hint.bookingAttributionMode !== "provider_redirect") {
|
|
67
89
|
context.addIssue({
|
|
@@ -73,17 +95,15 @@ var bookingProviderHintSchema = z2.object({
|
|
|
73
95
|
});
|
|
74
96
|
|
|
75
97
|
// ../shared/dist/analytics-contract.js
|
|
76
|
-
import { z as
|
|
77
|
-
var ANALYTICS_CONTRACT_VERSION = "analytics-contract.v1";
|
|
78
|
-
var ANALYTICS_CONTRACT_HASH = "sha256:a91bddcc3c5e4196933b0335d03eaf41ff929cb736bdd694fe54d07ab52dada1";
|
|
98
|
+
import { z as z4 } from "zod";
|
|
79
99
|
var ANALYTICS_IMPORT_SCHEMA_VERSION = "analytics-provider-import.v1";
|
|
80
|
-
var analyticsImportTargetIdSchema =
|
|
81
|
-
var analyticsProviderImportRowSchema =
|
|
100
|
+
var analyticsImportTargetIdSchema = z4.string().min(1).max(120).regex(/^[a-zA-Z][a-zA-Z0-9]*(?:[._-][a-zA-Z0-9]+)*$/u);
|
|
101
|
+
var analyticsProviderImportRowSchema = z4.object({
|
|
82
102
|
targetId: analyticsImportTargetIdSchema,
|
|
83
|
-
occurredAt:
|
|
84
|
-
attributionConfidence:
|
|
85
|
-
providerEventId:
|
|
86
|
-
idempotencyKey:
|
|
103
|
+
occurredAt: z4.string().datetime({ offset: true }),
|
|
104
|
+
attributionConfidence: z4.enum(["provider_reported", "manual_import"]),
|
|
105
|
+
providerEventId: z4.string().trim().min(1).max(160).optional(),
|
|
106
|
+
idempotencyKey: z4.string().trim().min(1).max(160).optional()
|
|
87
107
|
}).strict().superRefine((row, context) => {
|
|
88
108
|
if (!row.providerEventId && !row.idempotencyKey) {
|
|
89
109
|
context.addIssue({
|
|
@@ -93,24 +113,24 @@ var analyticsProviderImportRowSchema = z3.object({
|
|
|
93
113
|
});
|
|
94
114
|
}
|
|
95
115
|
});
|
|
96
|
-
var analyticsProviderImportSchema =
|
|
97
|
-
schemaVersion:
|
|
98
|
-
provider:
|
|
99
|
-
sourceName:
|
|
100
|
-
rows:
|
|
116
|
+
var analyticsProviderImportSchema = z4.object({
|
|
117
|
+
schemaVersion: z4.literal(ANALYTICS_IMPORT_SCHEMA_VERSION),
|
|
118
|
+
provider: z4.enum(["treatwell", "beautinda", "other"]),
|
|
119
|
+
sourceName: z4.string().trim().min(1).max(160).optional(),
|
|
120
|
+
rows: z4.array(analyticsProviderImportRowSchema).min(1).max(1e3)
|
|
101
121
|
}).strict();
|
|
102
122
|
|
|
103
123
|
// ../shared/dist/analytics-config.js
|
|
104
|
-
import { z as
|
|
124
|
+
import { z as z5 } from "zod";
|
|
105
125
|
var ANALYTICS_CONFIG_LEASE_MS = 6e4;
|
|
106
|
-
var analyticsMeasurementConfigSchema =
|
|
107
|
-
version:
|
|
108
|
-
installationGeneration:
|
|
109
|
-
configRevision:
|
|
110
|
-
effectiveSiteMode:
|
|
111
|
-
measurementEnabled:
|
|
112
|
-
issuedAt:
|
|
113
|
-
expiresAt:
|
|
126
|
+
var analyticsMeasurementConfigSchema = z5.object({
|
|
127
|
+
version: z5.literal(1),
|
|
128
|
+
installationGeneration: z5.number().int().positive(),
|
|
129
|
+
configRevision: z5.number().int().positive(),
|
|
130
|
+
effectiveSiteMode: z5.enum(["disabled", "session_only", "full_analytics"]),
|
|
131
|
+
measurementEnabled: z5.boolean(),
|
|
132
|
+
issuedAt: z5.string().datetime({ offset: true }),
|
|
133
|
+
expiresAt: z5.string().datetime({ offset: true })
|
|
114
134
|
}).strict().superRefine((config, context) => {
|
|
115
135
|
const lifetime = Date.parse(config.expiresAt) - Date.parse(config.issuedAt);
|
|
116
136
|
if (lifetime <= 0 || lifetime > ANALYTICS_CONFIG_LEASE_MS) {
|
|
@@ -130,11 +150,11 @@ var analyticsMeasurementConfigSchema = z4.object({
|
|
|
130
150
|
});
|
|
131
151
|
|
|
132
152
|
// ../shared/dist/analytics-events.js
|
|
133
|
-
import { z as
|
|
153
|
+
import { z as z6 } from "zod";
|
|
134
154
|
var ANALYTICS_SCHEMA_VERSION = "analytics.v1";
|
|
135
|
-
var analyticsSessionIdSchema =
|
|
136
|
-
var analyticsVisitorIdSchema =
|
|
137
|
-
var analyticsPersistedIdentityHashSchema =
|
|
155
|
+
var analyticsSessionIdSchema = z6.string().regex(/^cpa_s_[a-f0-9]{32}$/u);
|
|
156
|
+
var analyticsVisitorIdSchema = z6.string().regex(/^cpa_v_[a-f0-9]{32}$/u);
|
|
157
|
+
var analyticsPersistedIdentityHashSchema = z6.string().regex(/^[a-f0-9]{64}$/u);
|
|
138
158
|
var analyticsEventNames = [
|
|
139
159
|
"page_view",
|
|
140
160
|
"section_view",
|
|
@@ -214,43 +234,43 @@ var analyticsValidityStatuses = [
|
|
|
214
234
|
"rejected",
|
|
215
235
|
"ignored"
|
|
216
236
|
];
|
|
217
|
-
var analyticsEventNameSchema =
|
|
218
|
-
var serverOnlyAnalyticsEventSchema =
|
|
219
|
-
var analyticsEventSourceSchema =
|
|
220
|
-
var analyticsIngestionChannelSchema =
|
|
221
|
-
var analyticsTargetTypeSchema =
|
|
222
|
-
var analyticsDataAttributeEventSchema =
|
|
223
|
-
var analyticsDeviceTypeSchema =
|
|
224
|
-
var analyticsBotClassificationSchema =
|
|
225
|
-
var analyticsValidityStatusSchema =
|
|
226
|
-
var analyticsPropertiesSchema =
|
|
227
|
-
var analyticsTimestampSchema =
|
|
228
|
-
var analyticsBrowserEventSchema =
|
|
229
|
-
eventId:
|
|
230
|
-
installationGeneration:
|
|
231
|
-
measurementMode:
|
|
237
|
+
var analyticsEventNameSchema = z6.enum(analyticsEventNames);
|
|
238
|
+
var serverOnlyAnalyticsEventSchema = z6.enum(serverOnlyAnalyticsEvents);
|
|
239
|
+
var analyticsEventSourceSchema = z6.enum(analyticsEventSources);
|
|
240
|
+
var analyticsIngestionChannelSchema = z6.enum(analyticsIngestionChannels);
|
|
241
|
+
var analyticsTargetTypeSchema = z6.enum(analyticsTargetTypes);
|
|
242
|
+
var analyticsDataAttributeEventSchema = z6.enum(analyticsDataAttributeEvents);
|
|
243
|
+
var analyticsDeviceTypeSchema = z6.enum(analyticsDeviceTypes);
|
|
244
|
+
var analyticsBotClassificationSchema = z6.enum(analyticsBotClassifications);
|
|
245
|
+
var analyticsValidityStatusSchema = z6.enum(analyticsValidityStatuses);
|
|
246
|
+
var analyticsPropertiesSchema = z6.record(z6.string(), z6.unknown());
|
|
247
|
+
var analyticsTimestampSchema = z6.string().datetime({ offset: true });
|
|
248
|
+
var analyticsBrowserEventSchema = z6.object({
|
|
249
|
+
eventId: z6.string().min(1).max(160),
|
|
250
|
+
installationGeneration: z6.number().int().positive().optional(),
|
|
251
|
+
measurementMode: z6.enum(["session_only", "full_analytics"]).optional(),
|
|
232
252
|
eventName: analyticsEventNameSchema,
|
|
233
253
|
eventSource: analyticsEventSourceSchema.optional().default("browser"),
|
|
234
|
-
targetId:
|
|
254
|
+
targetId: z6.string().min(1).max(160).optional(),
|
|
235
255
|
targetType: analyticsTargetTypeSchema.optional(),
|
|
236
256
|
visitorId: analyticsVisitorIdSchema.optional(),
|
|
237
257
|
sessionId: analyticsSessionIdSchema,
|
|
238
|
-
idempotencyKey:
|
|
258
|
+
idempotencyKey: z6.string().min(1).max(240).optional(),
|
|
239
259
|
occurredAt: analyticsTimestampSchema,
|
|
240
|
-
pageUrl:
|
|
241
|
-
pagePath:
|
|
242
|
-
routeTemplate:
|
|
243
|
-
referrer:
|
|
244
|
-
utmSource:
|
|
245
|
-
utmMedium:
|
|
246
|
-
utmCampaign:
|
|
247
|
-
utmContent:
|
|
248
|
-
utmTerm:
|
|
260
|
+
pageUrl: z6.string().url().max(2048).optional(),
|
|
261
|
+
pagePath: z6.string().min(1).max(1024).optional(),
|
|
262
|
+
routeTemplate: z6.string().min(1).max(1024).optional(),
|
|
263
|
+
referrer: z6.string().url().max(2048).optional(),
|
|
264
|
+
utmSource: z6.string().min(1).max(200).optional(),
|
|
265
|
+
utmMedium: z6.string().min(1).max(200).optional(),
|
|
266
|
+
utmCampaign: z6.string().min(1).max(200).optional(),
|
|
267
|
+
utmContent: z6.string().min(1).max(200).optional(),
|
|
268
|
+
utmTerm: z6.string().min(1).max(200).optional(),
|
|
249
269
|
deviceType: analyticsDeviceTypeSchema.optional(),
|
|
250
|
-
browserName:
|
|
251
|
-
osName:
|
|
252
|
-
country:
|
|
253
|
-
region:
|
|
270
|
+
browserName: z6.string().min(1).max(120).optional(),
|
|
271
|
+
osName: z6.string().min(1).max(120).optional(),
|
|
272
|
+
country: z6.string().min(1).max(80).optional(),
|
|
273
|
+
region: z6.string().min(1).max(120).optional(),
|
|
254
274
|
properties: analyticsPropertiesSchema.optional().default({})
|
|
255
275
|
}).superRefine((event, context) => {
|
|
256
276
|
if (isServerOnlyAnalyticsEvent(event.eventName)) {
|
|
@@ -275,44 +295,44 @@ var analyticsBrowserEventSchema = z5.object({
|
|
|
275
295
|
});
|
|
276
296
|
}
|
|
277
297
|
});
|
|
278
|
-
var analyticsBrowserEventPayloadSchema =
|
|
279
|
-
siteKey:
|
|
280
|
-
schemaVersion:
|
|
281
|
-
mode:
|
|
282
|
-
events:
|
|
298
|
+
var analyticsBrowserEventPayloadSchema = z6.object({
|
|
299
|
+
siteKey: z6.string().min(1),
|
|
300
|
+
schemaVersion: z6.literal(ANALYTICS_SCHEMA_VERSION),
|
|
301
|
+
mode: z6.enum(["live", "test"]).optional().default("live"),
|
|
302
|
+
events: z6.array(analyticsBrowserEventSchema).min(1).max(50)
|
|
283
303
|
});
|
|
284
|
-
var analyticsNormalizedEventBaseSchema =
|
|
285
|
-
site_id:
|
|
286
|
-
event_id:
|
|
287
|
-
schema_version:
|
|
304
|
+
var analyticsNormalizedEventBaseSchema = z6.object({
|
|
305
|
+
site_id: z6.string().uuid(),
|
|
306
|
+
event_id: z6.string().min(1).max(160),
|
|
307
|
+
schema_version: z6.literal(ANALYTICS_SCHEMA_VERSION),
|
|
288
308
|
event_name: analyticsEventNameSchema,
|
|
289
309
|
event_source: analyticsEventSourceSchema,
|
|
290
310
|
ingestion_channel: analyticsIngestionChannelSchema,
|
|
291
|
-
target_id:
|
|
311
|
+
target_id: z6.string().min(1).max(160).nullable().optional(),
|
|
292
312
|
target_type: analyticsTargetTypeSchema.nullable().optional(),
|
|
293
|
-
dedupe_key:
|
|
294
|
-
idempotency_key:
|
|
313
|
+
dedupe_key: z6.string().regex(/^analytics_dedupe_v1_[a-f0-9]{64}$/u).nullable().optional(),
|
|
314
|
+
idempotency_key: z6.string().min(1).max(240).nullable().optional(),
|
|
295
315
|
bot_classification: analyticsBotClassificationSchema,
|
|
296
316
|
validity_status: analyticsValidityStatusSchema,
|
|
297
|
-
rejection_reason:
|
|
317
|
+
rejection_reason: z6.string().min(1).max(240).nullable().optional(),
|
|
298
318
|
occurred_at: analyticsTimestampSchema,
|
|
299
319
|
received_at: analyticsTimestampSchema,
|
|
300
|
-
page_url:
|
|
301
|
-
page_path:
|
|
302
|
-
route_template:
|
|
303
|
-
referrer:
|
|
304
|
-
utm_source:
|
|
305
|
-
utm_medium:
|
|
306
|
-
utm_campaign:
|
|
307
|
-
utm_content:
|
|
308
|
-
utm_term:
|
|
309
|
-
country:
|
|
310
|
-
region:
|
|
320
|
+
page_url: z6.string().url().max(2048).nullable().optional(),
|
|
321
|
+
page_path: z6.string().min(1).max(1024).nullable().optional(),
|
|
322
|
+
route_template: z6.string().min(1).max(1024).nullable().optional(),
|
|
323
|
+
referrer: z6.string().url().max(2048).nullable().optional(),
|
|
324
|
+
utm_source: z6.string().min(1).max(200).nullable().optional(),
|
|
325
|
+
utm_medium: z6.string().min(1).max(200).nullable().optional(),
|
|
326
|
+
utm_campaign: z6.string().min(1).max(200).nullable().optional(),
|
|
327
|
+
utm_content: z6.string().min(1).max(200).nullable().optional(),
|
|
328
|
+
utm_term: z6.string().min(1).max(200).nullable().optional(),
|
|
329
|
+
country: z6.string().min(1).max(80).nullable().optional(),
|
|
330
|
+
region: z6.string().min(1).max(120).nullable().optional(),
|
|
311
331
|
device_type: analyticsDeviceTypeSchema,
|
|
312
|
-
browser_name:
|
|
313
|
-
os_name:
|
|
314
|
-
provider:
|
|
315
|
-
provider_event_id:
|
|
332
|
+
browser_name: z6.string().min(1).max(120).nullable().optional(),
|
|
333
|
+
os_name: z6.string().min(1).max(120).nullable().optional(),
|
|
334
|
+
provider: z6.string().min(1).max(120).nullable().optional(),
|
|
335
|
+
provider_event_id: z6.string().min(1).max(240).nullable().optional(),
|
|
316
336
|
properties: analyticsPropertiesSchema
|
|
317
337
|
});
|
|
318
338
|
var analyticsRawNormalizedEventSchema = analyticsNormalizedEventBaseSchema.extend({
|
|
@@ -328,11 +348,11 @@ function isServerOnlyAnalyticsEvent(eventName) {
|
|
|
328
348
|
}
|
|
329
349
|
|
|
330
350
|
// ../shared/dist/analytics-manifest.js
|
|
331
|
-
import { z as
|
|
332
|
-
var analyticsTargetIdSchema =
|
|
351
|
+
import { z as z7 } from "zod";
|
|
352
|
+
var analyticsTargetIdSchema = z7.string().min(1).max(120).regex(/^[a-zA-Z][a-zA-Z0-9]*(?:[._-][a-zA-Z0-9]+)*$/u, {
|
|
333
353
|
message: "Analytics target IDs must be stable identifiers without whitespace or visible copy."
|
|
334
354
|
});
|
|
335
|
-
var analyticsManifestRecordSchema =
|
|
355
|
+
var analyticsManifestRecordSchema = z7.record(z7.string(), z7.unknown());
|
|
336
356
|
var analyticsFormPurposes = [
|
|
337
357
|
"contact",
|
|
338
358
|
"lead",
|
|
@@ -341,21 +361,21 @@ var analyticsFormPurposes = [
|
|
|
341
361
|
"login",
|
|
342
362
|
"other"
|
|
343
363
|
];
|
|
344
|
-
var analyticsFormPurposeSchema =
|
|
345
|
-
var analyticsManifestRouteSchema =
|
|
346
|
-
path:
|
|
347
|
-
pageType:
|
|
348
|
-
label:
|
|
364
|
+
var analyticsFormPurposeSchema = z7.enum(analyticsFormPurposes);
|
|
365
|
+
var analyticsManifestRouteSchema = z7.object({
|
|
366
|
+
path: z7.string().min(1).max(1024),
|
|
367
|
+
pageType: z7.string().min(1).max(120).optional(),
|
|
368
|
+
label: z7.string().min(1).max(200).optional()
|
|
349
369
|
}).passthrough();
|
|
350
|
-
var analyticsManifestTargetSchema =
|
|
370
|
+
var analyticsManifestTargetSchema = z7.object({
|
|
351
371
|
id: analyticsTargetIdSchema,
|
|
352
372
|
type: analyticsTargetTypeSchema,
|
|
353
373
|
event: analyticsEventNameSchema.optional(),
|
|
354
|
-
events:
|
|
355
|
-
route:
|
|
356
|
-
label:
|
|
357
|
-
description:
|
|
358
|
-
autoActive:
|
|
374
|
+
events: z7.array(analyticsEventNameSchema).min(1).max(20).optional(),
|
|
375
|
+
route: z7.string().min(1).max(1024).optional(),
|
|
376
|
+
label: z7.string().min(1).max(200).optional(),
|
|
377
|
+
description: z7.string().min(1).max(1e3).optional(),
|
|
378
|
+
autoActive: z7.boolean().optional(),
|
|
359
379
|
sourceHints: analyticsManifestRecordSchema.optional()
|
|
360
380
|
}).passthrough().superRefine((target, context) => {
|
|
361
381
|
if (target.event === void 0 && target.events === void 0) {
|
|
@@ -380,21 +400,21 @@ var analyticsManifestTargetSchema = z6.object({
|
|
|
380
400
|
});
|
|
381
401
|
}
|
|
382
402
|
});
|
|
383
|
-
var analyticsManifestSchema =
|
|
384
|
-
schemaVersion:
|
|
385
|
-
siteId:
|
|
386
|
-
siteKeyRef:
|
|
403
|
+
var analyticsManifestSchema = z7.object({
|
|
404
|
+
schemaVersion: z7.literal(ANALYTICS_SCHEMA_VERSION),
|
|
405
|
+
siteId: z7.string().min(1),
|
|
406
|
+
siteKeyRef: z7.string().regex(/^env:[A-Z][A-Z0-9_]*$/u, {
|
|
387
407
|
message: "siteKeyRef must be an environment-variable reference."
|
|
388
408
|
}),
|
|
389
|
-
siteKeyLookup:
|
|
390
|
-
routes:
|
|
391
|
-
targets:
|
|
409
|
+
siteKeyLookup: z7.string().regex(/^pk_siteplane_[A-Za-z0-9_-]{16}$/),
|
|
410
|
+
routes: z7.array(analyticsManifestRouteSchema),
|
|
411
|
+
targets: z7.array(analyticsManifestTargetSchema),
|
|
392
412
|
metadata: analyticsManifestRecordSchema.optional(),
|
|
393
|
-
siteKey:
|
|
394
|
-
secretKey:
|
|
395
|
-
rawKey:
|
|
396
|
-
token:
|
|
397
|
-
accessToken:
|
|
413
|
+
siteKey: z7.string().optional(),
|
|
414
|
+
secretKey: z7.string().optional(),
|
|
415
|
+
rawKey: z7.string().optional(),
|
|
416
|
+
token: z7.string().optional(),
|
|
417
|
+
accessToken: z7.string().optional()
|
|
398
418
|
}).passthrough().superRefine((manifest, context) => {
|
|
399
419
|
const targetIds = /* @__PURE__ */ new Set();
|
|
400
420
|
for (const [index, target] of manifest.targets.entries()) {
|
|
@@ -438,9 +458,9 @@ function isPlainRecord(value) {
|
|
|
438
458
|
}
|
|
439
459
|
|
|
440
460
|
// ../shared/dist/analytics-metrics.js
|
|
441
|
-
import { z as
|
|
461
|
+
import { z as z8 } from "zod";
|
|
442
462
|
var analyticsVisitorQualities = ["exact", "estimated"];
|
|
443
|
-
var analyticsVisitorQualitySchema =
|
|
463
|
+
var analyticsVisitorQualitySchema = z8.enum(analyticsVisitorQualities);
|
|
444
464
|
var analyticsKpiKeys = [
|
|
445
465
|
"pageViews",
|
|
446
466
|
"sessions",
|
|
@@ -452,7 +472,7 @@ var analyticsKpiKeys = [
|
|
|
452
472
|
"conversionRate",
|
|
453
473
|
"inquiryRate"
|
|
454
474
|
];
|
|
455
|
-
var analyticsKpiKeySchema =
|
|
475
|
+
var analyticsKpiKeySchema = z8.enum(analyticsKpiKeys);
|
|
456
476
|
|
|
457
477
|
// ../shared/dist/analytics-privacy.js
|
|
458
478
|
var serverPropertySchemas = {
|
|
@@ -490,7 +510,7 @@ function revenuePropertySchema() {
|
|
|
490
510
|
}
|
|
491
511
|
|
|
492
512
|
// ../shared/dist/assets.js
|
|
493
|
-
import { z as
|
|
513
|
+
import { z as z9 } from "zod";
|
|
494
514
|
var ASSET_STAGES = ["staging", "final", "deleted"];
|
|
495
515
|
var ASSET_VISIBILITIES = ["private", "public", "deleted"];
|
|
496
516
|
var ASSET_USAGE_ENTITY_TYPES = [
|
|
@@ -499,13 +519,13 @@ var ASSET_USAGE_ENTITY_TYPES = [
|
|
|
499
519
|
"change_set",
|
|
500
520
|
"published_value"
|
|
501
521
|
];
|
|
502
|
-
var assetStageSchema =
|
|
503
|
-
var assetVisibilitySchema =
|
|
504
|
-
var assetUsageEntityTypeSchema =
|
|
505
|
-
var brandingAccentColorSchema =
|
|
522
|
+
var assetStageSchema = z9.enum(ASSET_STAGES);
|
|
523
|
+
var assetVisibilitySchema = z9.enum(ASSET_VISIBILITIES);
|
|
524
|
+
var assetUsageEntityTypeSchema = z9.enum(ASSET_USAGE_ENTITY_TYPES);
|
|
525
|
+
var brandingAccentColorSchema = z9.string().regex(/^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/);
|
|
506
526
|
|
|
507
527
|
// ../shared/dist/booking-contracts.js
|
|
508
|
-
import { z as
|
|
528
|
+
import { z as z10 } from "zod";
|
|
509
529
|
var bookingStatuses = [
|
|
510
530
|
"pending_payment",
|
|
511
531
|
"confirmed",
|
|
@@ -560,30 +580,30 @@ var bookingResourceKinds = [
|
|
|
560
580
|
"equipment",
|
|
561
581
|
"other"
|
|
562
582
|
];
|
|
563
|
-
var bookingStatusSchema =
|
|
564
|
-
var bookingPaymentStatusSchema =
|
|
565
|
-
var bookingAccountReadinessStatusSchema =
|
|
566
|
-
var bookingRefundStatusSchema =
|
|
567
|
-
var bookingDisputeStatusSchema =
|
|
568
|
-
var bookingPaymentModeSchema =
|
|
569
|
-
var bookingPaymentCollectionTypeSchema =
|
|
570
|
-
var bookingPaymentCollectionSchema =
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
type:
|
|
574
|
-
depositPercent:
|
|
583
|
+
var bookingStatusSchema = z10.enum(bookingStatuses);
|
|
584
|
+
var bookingPaymentStatusSchema = z10.enum(bookingPaymentStatuses);
|
|
585
|
+
var bookingAccountReadinessStatusSchema = z10.enum(bookingAccountReadinessStatuses);
|
|
586
|
+
var bookingRefundStatusSchema = z10.enum(bookingRefundStatuses);
|
|
587
|
+
var bookingDisputeStatusSchema = z10.enum(bookingDisputeStatuses);
|
|
588
|
+
var bookingPaymentModeSchema = z10.enum(bookingPaymentModes);
|
|
589
|
+
var bookingPaymentCollectionTypeSchema = z10.enum(bookingPaymentCollectionTypes);
|
|
590
|
+
var bookingPaymentCollectionSchema = z10.discriminatedUnion("type", [
|
|
591
|
+
z10.object({ type: z10.literal("full_amount") }).strict(),
|
|
592
|
+
z10.object({
|
|
593
|
+
type: z10.literal("deposit_percent"),
|
|
594
|
+
depositPercent: z10.number().int().min(10).max(90)
|
|
575
595
|
}).strict()
|
|
576
596
|
]);
|
|
577
597
|
var bookingPaymentChoices = ["onsite", "online"];
|
|
578
|
-
var bookingPaymentChoiceSchema =
|
|
579
|
-
var bookingPaymentSnapshotSchema =
|
|
580
|
-
snapshotId:
|
|
581
|
-
snapshotVersion:
|
|
582
|
-
currency:
|
|
583
|
-
totalAmountCents:
|
|
584
|
-
onlineAmountCents:
|
|
585
|
-
onsiteRemainderCents:
|
|
586
|
-
maxStripeRefundAmountCents:
|
|
598
|
+
var bookingPaymentChoiceSchema = z10.enum(bookingPaymentChoices);
|
|
599
|
+
var bookingPaymentSnapshotSchema = z10.object({
|
|
600
|
+
snapshotId: z10.string().uuid(),
|
|
601
|
+
snapshotVersion: z10.number().int().positive(),
|
|
602
|
+
currency: z10.literal("EUR"),
|
|
603
|
+
totalAmountCents: z10.number().int().min(0),
|
|
604
|
+
onlineAmountCents: z10.number().int().min(0),
|
|
605
|
+
onsiteRemainderCents: z10.number().int().min(0),
|
|
606
|
+
maxStripeRefundAmountCents: z10.number().int().min(0)
|
|
587
607
|
}).strict().superRefine((snapshot, context) => {
|
|
588
608
|
if (snapshot.onlineAmountCents + snapshot.onsiteRemainderCents !== snapshot.totalAmountCents) {
|
|
589
609
|
context.addIssue({
|
|
@@ -598,17 +618,17 @@ var bookingPaymentSnapshotSchema = z9.object({
|
|
|
598
618
|
});
|
|
599
619
|
}
|
|
600
620
|
});
|
|
601
|
-
var bookingServiceVariantSchema =
|
|
602
|
-
id:
|
|
603
|
-
name:
|
|
604
|
-
durationMinutes:
|
|
605
|
-
priceCents:
|
|
621
|
+
var bookingServiceVariantSchema = z10.object({
|
|
622
|
+
id: z10.string().uuid(),
|
|
623
|
+
name: z10.string().trim().min(1).max(120),
|
|
624
|
+
durationMinutes: z10.number().int().min(1).max(1440),
|
|
625
|
+
priceCents: z10.number().int().min(0).nullable()
|
|
606
626
|
}).strict();
|
|
607
|
-
var bookingServiceVariantsSchema =
|
|
608
|
-
var isoDateSchema =
|
|
609
|
-
var utcDateTimeSchema =
|
|
610
|
-
var bookingLocalTimeSchema =
|
|
611
|
-
var bookingAvailabilityIntervalsSchema =
|
|
627
|
+
var bookingServiceVariantsSchema = z10.array(bookingServiceVariantSchema).min(1).max(20);
|
|
628
|
+
var isoDateSchema = z10.string().regex(/^\d{4}-\d{2}-\d{2}$/);
|
|
629
|
+
var utcDateTimeSchema = z10.string().datetime();
|
|
630
|
+
var bookingLocalTimeSchema = z10.string().regex(/^(?:[01]\d|2[0-3]):[0-5]\d$/);
|
|
631
|
+
var bookingAvailabilityIntervalsSchema = z10.array(z10.object({
|
|
612
632
|
start: bookingLocalTimeSchema,
|
|
613
633
|
end: bookingLocalTimeSchema
|
|
614
634
|
}).strict().refine((interval) => interval.end > interval.start)).superRefine((intervals, context) => {
|
|
@@ -623,76 +643,78 @@ var bookingAvailabilityIntervalsSchema = z9.array(z9.object({
|
|
|
623
643
|
}
|
|
624
644
|
}
|
|
625
645
|
});
|
|
626
|
-
var bookingPublicConfigSchema =
|
|
627
|
-
site:
|
|
628
|
-
displayName:
|
|
629
|
-
timezone:
|
|
630
|
-
locale:
|
|
631
|
-
bookingPageSlug:
|
|
632
|
-
privacyUrl:
|
|
646
|
+
var bookingPublicConfigSchema = z10.object({
|
|
647
|
+
site: z10.object({
|
|
648
|
+
displayName: z10.string().trim().min(1),
|
|
649
|
+
timezone: z10.string().trim().min(1),
|
|
650
|
+
locale: z10.string().trim().min(2),
|
|
651
|
+
bookingPageSlug: z10.string().regex(/^[a-z0-9]+(?:-[a-z0-9]+)*$/).min(2).max(64),
|
|
652
|
+
privacyUrl: z10.string().url().nullable()
|
|
633
653
|
}),
|
|
634
|
-
branding:
|
|
635
|
-
logoUrl:
|
|
636
|
-
accentColor:
|
|
654
|
+
branding: z10.object({
|
|
655
|
+
logoUrl: z10.string().url().nullable(),
|
|
656
|
+
accentColor: z10.string().trim().min(1).nullable()
|
|
637
657
|
}),
|
|
638
|
-
settings:
|
|
639
|
-
slotIntervalMinutes:
|
|
640
|
-
minLeadMinutes:
|
|
641
|
-
minCancelLeadMinutes:
|
|
642
|
-
maxAdvanceDays:
|
|
643
|
-
requirePhone:
|
|
644
|
-
collectNote:
|
|
645
|
-
confirmationMessage:
|
|
658
|
+
settings: z10.object({
|
|
659
|
+
slotIntervalMinutes: z10.number().int().positive(),
|
|
660
|
+
minLeadMinutes: z10.number().int().min(0),
|
|
661
|
+
minCancelLeadMinutes: z10.number().int().min(0),
|
|
662
|
+
maxAdvanceDays: z10.number().int().min(1),
|
|
663
|
+
requirePhone: z10.boolean(),
|
|
664
|
+
collectNote: z10.boolean(),
|
|
665
|
+
confirmationMessage: z10.string().nullable()
|
|
646
666
|
}),
|
|
647
667
|
/** Freitexte des Salons, im Kassen-Schritt vor der Bestaetigung sichtbar. */
|
|
648
|
-
policies:
|
|
649
|
-
cancellation:
|
|
650
|
-
lateArrival:
|
|
668
|
+
policies: z10.object({
|
|
669
|
+
cancellation: z10.string().nullable(),
|
|
670
|
+
lateArrival: z10.string().nullable()
|
|
651
671
|
}),
|
|
652
|
-
payment:
|
|
672
|
+
payment: z10.object({
|
|
653
673
|
mode: bookingPaymentModeSchema,
|
|
654
674
|
collection: bookingPaymentCollectionSchema,
|
|
655
|
-
onlinePaymentsReady:
|
|
675
|
+
onlinePaymentsReady: z10.boolean()
|
|
656
676
|
}).strict(),
|
|
657
|
-
serviceCategories:
|
|
658
|
-
id:
|
|
659
|
-
name:
|
|
660
|
-
sortOrder:
|
|
677
|
+
serviceCategories: z10.array(z10.object({
|
|
678
|
+
id: z10.string().uuid(),
|
|
679
|
+
name: z10.string().trim().min(1),
|
|
680
|
+
sortOrder: z10.number().int()
|
|
661
681
|
})),
|
|
662
|
-
serviceSubcategories:
|
|
663
|
-
id:
|
|
664
|
-
categoryId:
|
|
665
|
-
name:
|
|
666
|
-
sortOrder:
|
|
682
|
+
serviceSubcategories: z10.array(z10.object({
|
|
683
|
+
id: z10.string().uuid(),
|
|
684
|
+
categoryId: z10.string().uuid(),
|
|
685
|
+
name: z10.string().trim().min(1),
|
|
686
|
+
sortOrder: z10.number().int()
|
|
667
687
|
})),
|
|
668
|
-
services:
|
|
669
|
-
id:
|
|
670
|
-
name:
|
|
671
|
-
durationMinutes:
|
|
672
|
-
priceCents:
|
|
673
|
-
currency:
|
|
674
|
-
description:
|
|
675
|
-
categoryId:
|
|
676
|
-
subcategoryId:
|
|
688
|
+
services: z10.array(z10.object({
|
|
689
|
+
id: z10.string().trim().min(1),
|
|
690
|
+
name: z10.string().trim().min(1),
|
|
691
|
+
durationMinutes: z10.number().int().positive(),
|
|
692
|
+
priceCents: z10.number().int().min(0).nullable(),
|
|
693
|
+
currency: z10.string().regex(/^[A-Z]{3}$/),
|
|
694
|
+
description: z10.string().nullable(),
|
|
695
|
+
categoryId: z10.string().uuid(),
|
|
696
|
+
subcategoryId: z10.string().uuid().nullable(),
|
|
677
697
|
variants: bookingServiceVariantsSchema,
|
|
678
|
-
allowsAnyResource:
|
|
679
|
-
sortOrder:
|
|
698
|
+
allowsAnyResource: z10.boolean(),
|
|
699
|
+
sortOrder: z10.number().int()
|
|
680
700
|
})),
|
|
681
|
-
resources:
|
|
682
|
-
id:
|
|
683
|
-
name:
|
|
684
|
-
kind:
|
|
701
|
+
resources: z10.array(z10.object({
|
|
702
|
+
id: z10.string().trim().min(1),
|
|
703
|
+
name: z10.string().trim().min(1),
|
|
704
|
+
kind: z10.enum(bookingResourceKinds),
|
|
705
|
+
/** Profilfoto für „Bei wem?“; `null` ohne Foto. */
|
|
706
|
+
photoUrl: z10.string().url().nullable()
|
|
685
707
|
})),
|
|
686
|
-
serviceResources:
|
|
687
|
-
serviceId:
|
|
688
|
-
resourceId:
|
|
708
|
+
serviceResources: z10.array(z10.object({
|
|
709
|
+
serviceId: z10.string().trim().min(1),
|
|
710
|
+
resourceId: z10.string().trim().min(1)
|
|
689
711
|
}))
|
|
690
712
|
});
|
|
691
|
-
var bookingItemSchema =
|
|
692
|
-
serviceId:
|
|
693
|
-
variantId:
|
|
713
|
+
var bookingItemSchema = z10.object({
|
|
714
|
+
serviceId: z10.string().trim().min(1),
|
|
715
|
+
variantId: z10.string().trim().min(1)
|
|
694
716
|
}).strict();
|
|
695
|
-
var bookingItemsSchema =
|
|
717
|
+
var bookingItemsSchema = z10.array(bookingItemSchema).min(1).max(10);
|
|
696
718
|
function parseBookingItemsParam(value) {
|
|
697
719
|
const items = value.split(",").map((entry) => entry.trim()).filter((entry) => entry !== "").map((entry) => {
|
|
698
720
|
const [serviceId, variantId, ...rest] = entry.split(":");
|
|
@@ -700,36 +722,36 @@ function parseBookingItemsParam(value) {
|
|
|
700
722
|
});
|
|
701
723
|
return items.every((item) => item !== null) ? items : null;
|
|
702
724
|
}
|
|
703
|
-
var bookingSlotsQuerySchema =
|
|
704
|
-
items:
|
|
705
|
-
resourceId:
|
|
725
|
+
var bookingSlotsQuerySchema = z10.object({
|
|
726
|
+
items: z10.preprocess((value) => typeof value === "string" ? parseBookingItemsParam(value) : value, bookingItemsSchema),
|
|
727
|
+
resourceId: z10.string().trim().min(1).optional(),
|
|
706
728
|
fromDate: isoDateSchema,
|
|
707
729
|
toDate: isoDateSchema
|
|
708
730
|
});
|
|
709
|
-
var bookingSlotsResponseSchema =
|
|
710
|
-
timezone:
|
|
731
|
+
var bookingSlotsResponseSchema = z10.object({
|
|
732
|
+
timezone: z10.string().trim().min(1),
|
|
711
733
|
items: bookingItemsSchema,
|
|
712
734
|
// Reine Behandlungsdauer ohne Puffer: das UI zeigt damit die Terminspanne,
|
|
713
735
|
// ohne selbst rechnen zu muessen.
|
|
714
|
-
totalDurationMinutes:
|
|
715
|
-
mode:
|
|
716
|
-
slots:
|
|
736
|
+
totalDurationMinutes: z10.number().int().min(1),
|
|
737
|
+
mode: z10.enum(["any", "resource"]),
|
|
738
|
+
slots: z10.array(z10.object({
|
|
717
739
|
startUtc: utcDateTimeSchema,
|
|
718
|
-
resourceId:
|
|
740
|
+
resourceId: z10.string().trim().min(1).optional()
|
|
719
741
|
}))
|
|
720
742
|
});
|
|
721
|
-
var bookingAvailabilityQuerySchema =
|
|
722
|
-
items:
|
|
723
|
-
resourceId:
|
|
743
|
+
var bookingAvailabilityQuerySchema = z10.object({
|
|
744
|
+
items: z10.preprocess((value) => typeof value === "string" ? parseBookingItemsParam(value) : value, bookingItemsSchema),
|
|
745
|
+
resourceId: z10.string().trim().min(1).optional(),
|
|
724
746
|
fromDate: isoDateSchema,
|
|
725
747
|
toDate: isoDateSchema
|
|
726
748
|
});
|
|
727
|
-
var bookingAvailabilityResponseSchema =
|
|
728
|
-
timezone:
|
|
729
|
-
totalDurationMinutes:
|
|
730
|
-
days:
|
|
749
|
+
var bookingAvailabilityResponseSchema = z10.object({
|
|
750
|
+
timezone: z10.string().trim().min(1),
|
|
751
|
+
totalDurationMinutes: z10.number().int().min(1),
|
|
752
|
+
days: z10.array(z10.object({
|
|
731
753
|
date: isoDateSchema,
|
|
732
|
-
hasSlots:
|
|
754
|
+
hasSlots: z10.boolean()
|
|
733
755
|
})),
|
|
734
756
|
/** Erster Tag mit Slot ab `fromDate`, auch ausserhalb des Fensters. */
|
|
735
757
|
nextAvailableDate: isoDateSchema.nullable()
|
|
@@ -747,72 +769,72 @@ var bookingPublicErrorCodes = [
|
|
|
747
769
|
"too_late",
|
|
748
770
|
"not_found"
|
|
749
771
|
];
|
|
750
|
-
var bookingPublicErrorSchema =
|
|
751
|
-
error:
|
|
752
|
-
message:
|
|
753
|
-
requestId:
|
|
772
|
+
var bookingPublicErrorSchema = z10.object({
|
|
773
|
+
error: z10.enum(bookingPublicErrorCodes),
|
|
774
|
+
message: z10.string().optional(),
|
|
775
|
+
requestId: z10.string().optional()
|
|
754
776
|
}).strict();
|
|
755
|
-
var bookingCreateRequestSchema =
|
|
777
|
+
var bookingCreateRequestSchema = z10.object({
|
|
756
778
|
items: bookingItemsSchema,
|
|
757
|
-
resourceId:
|
|
779
|
+
resourceId: z10.string().min(1).nullable(),
|
|
758
780
|
startUtc: utcDateTimeSchema,
|
|
759
|
-
customer:
|
|
760
|
-
name:
|
|
761
|
-
email:
|
|
762
|
-
phone:
|
|
763
|
-
note:
|
|
781
|
+
customer: z10.object({
|
|
782
|
+
name: z10.string().min(1).max(120),
|
|
783
|
+
email: z10.string().email().max(254),
|
|
784
|
+
phone: z10.string().max(32).optional(),
|
|
785
|
+
note: z10.string().max(1e3).optional()
|
|
764
786
|
}).strict(),
|
|
765
|
-
hp:
|
|
766
|
-
clientToken:
|
|
787
|
+
hp: z10.string().optional(),
|
|
788
|
+
clientToken: z10.string().uuid(),
|
|
767
789
|
paymentChoice: bookingPaymentChoiceSchema,
|
|
768
790
|
// Werbe-Einwilligung. Bestaetigung, Erinnerung und Storno-Link sind davon
|
|
769
791
|
// unabhaengig und werden immer versendet.
|
|
770
|
-
consent:
|
|
771
|
-
marketingEmail:
|
|
772
|
-
marketingSms:
|
|
792
|
+
consent: z10.object({
|
|
793
|
+
marketingEmail: z10.boolean(),
|
|
794
|
+
marketingSms: z10.boolean()
|
|
773
795
|
}).strict().optional()
|
|
774
796
|
}).strict();
|
|
775
|
-
var bookingPublicPaymentResponseSchema =
|
|
776
|
-
clientSecret:
|
|
777
|
-
stripeAccountId:
|
|
797
|
+
var bookingPublicPaymentResponseSchema = z10.object({
|
|
798
|
+
clientSecret: z10.string().min(1),
|
|
799
|
+
stripeAccountId: z10.string().startsWith("acct_")
|
|
778
800
|
}).strict();
|
|
779
|
-
var bookingCreateResponseSchema =
|
|
780
|
-
|
|
781
|
-
status:
|
|
782
|
-
booking:
|
|
783
|
-
id:
|
|
801
|
+
var bookingCreateResponseSchema = z10.union([
|
|
802
|
+
z10.object({
|
|
803
|
+
status: z10.literal("confirmed"),
|
|
804
|
+
booking: z10.object({
|
|
805
|
+
id: z10.string().min(1),
|
|
784
806
|
startUtc: utcDateTimeSchema,
|
|
785
807
|
endUtc: utcDateTimeSchema,
|
|
786
|
-
timezone:
|
|
787
|
-
serviceName:
|
|
788
|
-
resourceName:
|
|
808
|
+
timezone: z10.string().trim().min(1),
|
|
809
|
+
serviceName: z10.string().trim().min(1),
|
|
810
|
+
resourceName: z10.string().trim().min(1)
|
|
789
811
|
}).strict(),
|
|
790
|
-
manageUrl:
|
|
791
|
-
confirmationMessage:
|
|
812
|
+
manageUrl: z10.string().url(),
|
|
813
|
+
confirmationMessage: z10.string().nullable()
|
|
792
814
|
}).strict(),
|
|
793
|
-
|
|
794
|
-
status:
|
|
795
|
-
bookingId:
|
|
815
|
+
z10.object({
|
|
816
|
+
status: z10.literal("pending_payment"),
|
|
817
|
+
bookingId: z10.string().min(1),
|
|
796
818
|
holdExpiresAt: utcDateTimeSchema,
|
|
797
819
|
payment: bookingPublicPaymentResponseSchema,
|
|
798
|
-
statusToken:
|
|
799
|
-
manageUrl:
|
|
820
|
+
statusToken: z10.string().min(20),
|
|
821
|
+
manageUrl: z10.string().url().optional()
|
|
800
822
|
}).strict(),
|
|
801
823
|
bookingPublicErrorSchema
|
|
802
824
|
]);
|
|
803
|
-
var bookingStatusResponseSchema =
|
|
825
|
+
var bookingStatusResponseSchema = z10.object({
|
|
804
826
|
bookingStatus: bookingStatusSchema,
|
|
805
827
|
paymentStatus: bookingPaymentStatusSchema,
|
|
806
828
|
refundStatus: bookingRefundStatusSchema,
|
|
807
829
|
disputeStatus: bookingDisputeStatusSchema,
|
|
808
830
|
holdExpiresAt: utcDateTimeSchema.nullable()
|
|
809
831
|
}).strict();
|
|
810
|
-
var bookingCancelRequestSchema =
|
|
811
|
-
token:
|
|
832
|
+
var bookingCancelRequestSchema = z10.object({
|
|
833
|
+
token: z10.string().min(20)
|
|
812
834
|
});
|
|
813
|
-
var bookingCancelResponseSchema =
|
|
814
|
-
|
|
815
|
-
status:
|
|
835
|
+
var bookingCancelResponseSchema = z10.union([
|
|
836
|
+
z10.object({
|
|
837
|
+
status: z10.enum(["cancelled", "already_cancelled", "too_late", "not_found"])
|
|
816
838
|
}),
|
|
817
839
|
bookingPublicErrorSchema
|
|
818
840
|
]);
|
|
@@ -821,34 +843,33 @@ var bookingMoveErrorCodes = [
|
|
|
821
843
|
"booking_not_movable",
|
|
822
844
|
"not_found"
|
|
823
845
|
];
|
|
824
|
-
var bookingMoveRequestSchema =
|
|
825
|
-
bookingId:
|
|
846
|
+
var bookingMoveRequestSchema = z10.object({
|
|
847
|
+
bookingId: z10.string().uuid(),
|
|
826
848
|
newStartUtc: utcDateTimeSchema,
|
|
827
|
-
newResourceId:
|
|
828
|
-
notifyCustomer:
|
|
829
|
-
reason:
|
|
830
|
-
});
|
|
831
|
-
var bookingMoveResponseSchema =
|
|
832
|
-
|
|
833
|
-
status:
|
|
834
|
-
bookingId:
|
|
849
|
+
newResourceId: z10.string().uuid().optional(),
|
|
850
|
+
notifyCustomer: z10.boolean().default(false),
|
|
851
|
+
reason: z10.string().max(500).optional()
|
|
852
|
+
});
|
|
853
|
+
var bookingMoveResponseSchema = z10.union([
|
|
854
|
+
z10.object({
|
|
855
|
+
status: z10.literal("moved"),
|
|
856
|
+
bookingId: z10.string().uuid(),
|
|
835
857
|
startUtc: utcDateTimeSchema,
|
|
836
858
|
endUtc: utcDateTimeSchema,
|
|
837
|
-
resourceId:
|
|
859
|
+
resourceId: z10.string().uuid()
|
|
838
860
|
}),
|
|
839
|
-
|
|
840
|
-
error:
|
|
841
|
-
message:
|
|
842
|
-
requestId:
|
|
861
|
+
z10.object({
|
|
862
|
+
error: z10.enum(bookingMoveErrorCodes),
|
|
863
|
+
message: z10.string().optional(),
|
|
864
|
+
requestId: z10.string().optional()
|
|
843
865
|
})
|
|
844
866
|
]);
|
|
845
|
-
var bookingManifestSchema =
|
|
846
|
-
schemaVersion:
|
|
847
|
-
siteId:
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
productionOrigin: z9.string().url().optional()
|
|
867
|
+
var bookingManifestSchema = z10.object({
|
|
868
|
+
schemaVersion: z10.number().int().positive(),
|
|
869
|
+
siteId: z10.string().trim().min(1),
|
|
870
|
+
bookingPageSlug: z10.string().regex(/^[a-z0-9]+(?:-[a-z0-9]+)*$/).min(2).max(64),
|
|
871
|
+
integration: z10.literal("rewrite").optional(),
|
|
872
|
+
productionOrigin: z10.string().url().optional()
|
|
852
873
|
}).passthrough();
|
|
853
874
|
|
|
854
875
|
// ../shared/dist/booking-defaults.js
|
|
@@ -858,20 +879,20 @@ var BOOKING_CREATE_PAYLOAD_LIMIT_BYTES = 16 * 1024;
|
|
|
858
879
|
import { z as z17 } from "zod";
|
|
859
880
|
|
|
860
881
|
// ../shared/dist/field-id.js
|
|
861
|
-
import { z as
|
|
882
|
+
import { z as z11 } from "zod";
|
|
862
883
|
var FIELD_ID_PATTERN = /^[a-z][a-z0-9_-]*(\.[a-z][a-z0-9_-]*)+$/;
|
|
863
|
-
var fieldIdSchema =
|
|
884
|
+
var fieldIdSchema = z11.string().regex(FIELD_ID_PATTERN, "Invalid field id");
|
|
864
885
|
function isFieldId(value) {
|
|
865
886
|
return typeof value === "string" && fieldIdSchema.safeParse(value).success;
|
|
866
887
|
}
|
|
867
888
|
|
|
868
889
|
// ../shared/dist/field-types.js
|
|
869
|
-
import { z as
|
|
890
|
+
import { z as z12 } from "zod";
|
|
870
891
|
var FIELD_TYPES = ["text", "longText", "image", "link"];
|
|
871
|
-
var fieldTypeSchema =
|
|
892
|
+
var fieldTypeSchema = z12.enum(FIELD_TYPES);
|
|
872
893
|
|
|
873
894
|
// ../shared/dist/image-value.js
|
|
874
|
-
import { z as
|
|
895
|
+
import { z as z13 } from "zod";
|
|
875
896
|
var SUPPORTED_IMAGE_CONTENT_TYPES = [
|
|
876
897
|
"image/jpeg",
|
|
877
898
|
"image/png",
|
|
@@ -880,21 +901,21 @@ var SUPPORTED_IMAGE_CONTENT_TYPES = [
|
|
|
880
901
|
];
|
|
881
902
|
var maxImageUploadBytes = 10 * 1024 * 1024;
|
|
882
903
|
var largeImageWarningBytes = 2 * 1024 * 1024;
|
|
883
|
-
var imageContentTypeSchema =
|
|
884
|
-
var imageCropSchema =
|
|
885
|
-
x:
|
|
886
|
-
y:
|
|
887
|
-
zoom:
|
|
888
|
-
aspectRatio:
|
|
889
|
-
});
|
|
890
|
-
var imageValueSchema =
|
|
891
|
-
src:
|
|
892
|
-
alt:
|
|
893
|
-
width:
|
|
894
|
-
height:
|
|
904
|
+
var imageContentTypeSchema = z13.enum(SUPPORTED_IMAGE_CONTENT_TYPES);
|
|
905
|
+
var imageCropSchema = z13.object({
|
|
906
|
+
x: z13.number().min(0).max(100),
|
|
907
|
+
y: z13.number().min(0).max(100),
|
|
908
|
+
zoom: z13.number().min(1).max(4),
|
|
909
|
+
aspectRatio: z13.number().positive().max(10)
|
|
910
|
+
});
|
|
911
|
+
var imageValueSchema = z13.object({
|
|
912
|
+
src: z13.string().trim().min(1),
|
|
913
|
+
alt: z13.string().trim().min(1).max(300),
|
|
914
|
+
width: z13.number().int().positive().optional(),
|
|
915
|
+
height: z13.number().int().positive().optional(),
|
|
895
916
|
crop: imageCropSchema.optional(),
|
|
896
|
-
assetId:
|
|
897
|
-
finalStorageProvider:
|
|
917
|
+
assetId: z13.string().uuid().optional(),
|
|
918
|
+
finalStorageProvider: z13.enum([
|
|
898
919
|
"repo_static_assets",
|
|
899
920
|
"repo_handoff",
|
|
900
921
|
"site_owned_storage",
|
|
@@ -902,75 +923,83 @@ var imageValueSchema = z12.object({
|
|
|
902
923
|
]).optional()
|
|
903
924
|
});
|
|
904
925
|
|
|
905
|
-
// ../shared/dist/
|
|
906
|
-
import { z as
|
|
907
|
-
var
|
|
908
|
-
var
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
var
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
}),
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
926
|
+
// ../shared/dist/missing-content.js
|
|
927
|
+
import { z as z14 } from "zod";
|
|
928
|
+
var MISSING_CONTENT_RENDERED_PATH_MAX_BYTES = 512;
|
|
929
|
+
var MISSING_CONTENT_VISIBLE_VALUE_MAX_BYTES = 256;
|
|
930
|
+
var MISSING_CONTENT_LOCATOR_HINT_MAX_BYTES = 512;
|
|
931
|
+
var MISSING_CONTENT_LABEL_MAX_BYTES = 120;
|
|
932
|
+
var forbiddenControlOrBidi = /[\u0000-\u001f\u007f-\u009f--]/u;
|
|
933
|
+
var unsafeLocator = /<\/?[a-z][^>]*>|\b(?:javascript|data:text\/html)\s*:|\bon[a-z]+\s*=/iu;
|
|
934
|
+
var renderedPathSchema = z14.string().trim().transform((value) => value !== "/" ? value.replace(/\/+$/u, "") : value).superRefine((value, context) => {
|
|
935
|
+
if (!value.startsWith("/") || value === "$global" || value.includes("?") || value.includes("#")) {
|
|
936
|
+
context.addIssue({
|
|
937
|
+
code: "custom",
|
|
938
|
+
message: "renderedPath must be a canonical real path."
|
|
939
|
+
});
|
|
940
|
+
}
|
|
941
|
+
addSafeByteIssues(value, MISSING_CONTENT_RENDERED_PATH_MAX_BYTES, "renderedPath", context);
|
|
942
|
+
});
|
|
943
|
+
function normalizedSafeTextSchema(maxBytes, label) {
|
|
944
|
+
return z14.string().transform((value) => value.trim().replace(new RegExp("\\p{White_Space}+", "gu"), " ")).pipe(z14.string().min(1)).superRefine((value, context) => {
|
|
945
|
+
addSafeByteIssues(value, maxBytes, label, context);
|
|
946
|
+
if (label === "locatorHint" && unsafeLocator.test(value)) {
|
|
947
|
+
context.addIssue({
|
|
948
|
+
code: "custom",
|
|
949
|
+
message: "locatorHint contains unsafe markup or executable content."
|
|
950
|
+
});
|
|
951
|
+
}
|
|
952
|
+
});
|
|
953
|
+
}
|
|
954
|
+
var missingContentItemBase = {
|
|
955
|
+
renderedPath: renderedPathSchema,
|
|
956
|
+
visibleValue: normalizedSafeTextSchema(MISSING_CONTENT_VISIBLE_VALUE_MAX_BYTES, "visibleValue"),
|
|
957
|
+
locatorHint: normalizedSafeTextSchema(MISSING_CONTENT_LOCATOR_HINT_MAX_BYTES, "locatorHint"),
|
|
958
|
+
requestedLabel: normalizedSafeTextSchema(MISSING_CONTENT_LABEL_MAX_BYTES, "requestedLabel").optional(),
|
|
959
|
+
requestedSection: normalizedSafeTextSchema(MISSING_CONTENT_LABEL_MAX_BYTES, "requestedSection").optional(),
|
|
960
|
+
requestedSubsection: normalizedSafeTextSchema(MISSING_CONTENT_LABEL_MAX_BYTES, "requestedSubsection").optional(),
|
|
961
|
+
requestedSortOrder: z14.number().int().nonnegative().optional()
|
|
962
|
+
};
|
|
963
|
+
var missingContentItemSchema = z14.discriminatedUnion("kind", [
|
|
964
|
+
z14.object({ kind: z14.literal("text"), ...missingContentItemBase }).strict(),
|
|
965
|
+
z14.object({ kind: z14.literal("link"), ...missingContentItemBase }).strict(),
|
|
966
|
+
z14.object({ kind: z14.literal("image"), ...missingContentItemBase }).strict()
|
|
967
|
+
]).superRefine((item, context) => {
|
|
968
|
+
if (item.requestedSubsection && !item.requestedSection) {
|
|
969
|
+
context.addIssue({
|
|
970
|
+
code: "custom",
|
|
971
|
+
message: "requestedSubsection requires requestedSection.",
|
|
972
|
+
path: ["requestedSubsection"]
|
|
973
|
+
});
|
|
974
|
+
}
|
|
975
|
+
});
|
|
976
|
+
function addSafeByteIssues(value, maxBytes, label, context) {
|
|
977
|
+
if (new TextEncoder().encode(value).byteLength > maxBytes) {
|
|
978
|
+
context.addIssue({
|
|
979
|
+
code: "custom",
|
|
980
|
+
message: `${label} exceeds ${maxBytes} UTF-8 bytes.`
|
|
981
|
+
});
|
|
982
|
+
}
|
|
983
|
+
if (forbiddenControlOrBidi.test(value)) {
|
|
984
|
+
context.addIssue({
|
|
985
|
+
code: "custom",
|
|
986
|
+
message: `${label} contains a forbidden control or bidi character.`
|
|
987
|
+
});
|
|
988
|
+
}
|
|
989
|
+
}
|
|
961
990
|
|
|
962
991
|
// ../shared/dist/site-field-contract.js
|
|
963
|
-
import { z as
|
|
992
|
+
import { z as z16 } from "zod";
|
|
964
993
|
|
|
965
994
|
// ../shared/dist/fallback-hash.js
|
|
966
|
-
import { z as
|
|
995
|
+
import { z as z15 } from "zod";
|
|
967
996
|
var SAFE_REPRESENTATION_REASONS = [
|
|
968
997
|
"asset_import_rewritten",
|
|
969
998
|
"relative_url_normalized",
|
|
970
999
|
"line_endings_normalized",
|
|
971
1000
|
"image_value_serialized"
|
|
972
1001
|
];
|
|
973
|
-
var safeRepresentationReasonSchema =
|
|
1002
|
+
var safeRepresentationReasonSchema = z15.enum(SAFE_REPRESENTATION_REASONS);
|
|
974
1003
|
function canonicalizeFallbackValue(input) {
|
|
975
1004
|
const fieldType = fieldTypeSchema.parse(input.fieldType);
|
|
976
1005
|
if (input.safeRepresentationReason !== void 0) {
|
|
@@ -1006,10 +1035,10 @@ function createCanonicalFallbackHash(input) {
|
|
|
1006
1035
|
const payload = stableJsonStringify(canonical);
|
|
1007
1036
|
return `sha256:${sha256Hex(payload)}`;
|
|
1008
1037
|
}
|
|
1009
|
-
var linkFallbackSchema =
|
|
1010
|
-
href:
|
|
1011
|
-
label:
|
|
1012
|
-
target:
|
|
1038
|
+
var linkFallbackSchema = z15.object({
|
|
1039
|
+
href: z15.string().trim().min(1),
|
|
1040
|
+
label: z15.string().trim().min(1).optional(),
|
|
1041
|
+
target: z15.enum(["_self", "_blank"]).optional()
|
|
1013
1042
|
}).passthrough();
|
|
1014
1043
|
function normalizeLineEndings(value) {
|
|
1015
1044
|
return value.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
|
|
@@ -1187,67 +1216,67 @@ var SHA256_CONSTANTS = [
|
|
|
1187
1216
|
// ../shared/dist/site-field-contract.js
|
|
1188
1217
|
var fieldContractVersion = "1.0.0";
|
|
1189
1218
|
var scannerContractVersion = "1.0.0";
|
|
1190
|
-
var siteFieldStatusSchema =
|
|
1191
|
-
var semanticVersionSchema =
|
|
1192
|
-
var siteFieldRouteKeySchema =
|
|
1193
|
-
var repositoryRelativePosixPathSchema =
|
|
1194
|
-
var sourceMappingSchema =
|
|
1195
|
-
kind:
|
|
1219
|
+
var siteFieldStatusSchema = z16.enum(["hidden", "active"]);
|
|
1220
|
+
var semanticVersionSchema = z16.string().regex(/^\d+\.\d+\.\d+$/u);
|
|
1221
|
+
var siteFieldRouteKeySchema = z16.string().trim().refine((value) => value === "$global" || value.startsWith("/") && !value.includes("?") && !value.includes("#") && (value === "/" || !value.endsWith("/")), "Route keys must be canonical paths or $global.");
|
|
1222
|
+
var repositoryRelativePosixPathSchema = z16.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.");
|
|
1223
|
+
var sourceMappingSchema = z16.object({
|
|
1224
|
+
kind: z16.literal("function"),
|
|
1196
1225
|
filePath: repositoryRelativePosixPathSchema,
|
|
1197
|
-
exportName:
|
|
1198
|
-
sourcePath:
|
|
1226
|
+
exportName: z16.string().trim().min(1).optional(),
|
|
1227
|
+
sourcePath: z16.string().trim().min(1).optional(),
|
|
1199
1228
|
editTarget: fieldIdSchema.optional()
|
|
1200
1229
|
}).strict();
|
|
1201
|
-
var domMappingSchema =
|
|
1202
|
-
attribute:
|
|
1203
|
-
previewStrategy:
|
|
1230
|
+
var domMappingSchema = z16.object({
|
|
1231
|
+
attribute: z16.literal("data-siteplane-field-id"),
|
|
1232
|
+
previewStrategy: z16.enum(["dom", "event"])
|
|
1204
1233
|
}).strict();
|
|
1205
|
-
var fieldBaseSchema =
|
|
1234
|
+
var fieldBaseSchema = z16.object({
|
|
1206
1235
|
fieldId: fieldIdSchema,
|
|
1207
1236
|
routeKey: siteFieldRouteKeySchema,
|
|
1208
1237
|
source: sourceMappingSchema,
|
|
1209
1238
|
dom: domMappingSchema.optional()
|
|
1210
1239
|
}).strict();
|
|
1211
|
-
var linkFallbackSchema2 =
|
|
1212
|
-
href:
|
|
1213
|
-
label:
|
|
1214
|
-
target:
|
|
1240
|
+
var linkFallbackSchema2 = z16.object({
|
|
1241
|
+
href: z16.string().trim().min(1),
|
|
1242
|
+
label: z16.string().trim().min(1).optional(),
|
|
1243
|
+
target: z16.enum(["_self", "_blank"]).optional()
|
|
1215
1244
|
}).strict();
|
|
1216
|
-
var imageFallbackSchema =
|
|
1217
|
-
src:
|
|
1218
|
-
alt:
|
|
1219
|
-
width:
|
|
1220
|
-
height:
|
|
1221
|
-
crop:
|
|
1222
|
-
x:
|
|
1223
|
-
y:
|
|
1224
|
-
zoom:
|
|
1225
|
-
aspectRatio:
|
|
1245
|
+
var imageFallbackSchema = z16.object({
|
|
1246
|
+
src: z16.string().trim().min(1),
|
|
1247
|
+
alt: z16.string().trim().max(300),
|
|
1248
|
+
width: z16.number().int().positive().optional(),
|
|
1249
|
+
height: z16.number().int().positive().optional(),
|
|
1250
|
+
crop: z16.object({
|
|
1251
|
+
x: z16.number().min(0).max(100),
|
|
1252
|
+
y: z16.number().min(0).max(100),
|
|
1253
|
+
zoom: z16.number().min(1).max(4),
|
|
1254
|
+
aspectRatio: z16.number().positive().max(10)
|
|
1226
1255
|
}).strict().optional()
|
|
1227
1256
|
}).strict();
|
|
1228
|
-
var siteFieldContractFieldSchema =
|
|
1257
|
+
var siteFieldContractFieldSchema = z16.discriminatedUnion("fieldType", [
|
|
1229
1258
|
fieldBaseSchema.extend({
|
|
1230
|
-
fieldType:
|
|
1231
|
-
fallback:
|
|
1259
|
+
fieldType: z16.literal("text"),
|
|
1260
|
+
fallback: z16.string()
|
|
1232
1261
|
}),
|
|
1233
1262
|
fieldBaseSchema.extend({
|
|
1234
|
-
fieldType:
|
|
1235
|
-
fallback:
|
|
1263
|
+
fieldType: z16.literal("longText"),
|
|
1264
|
+
fallback: z16.string()
|
|
1236
1265
|
}),
|
|
1237
1266
|
fieldBaseSchema.extend({
|
|
1238
|
-
fieldType:
|
|
1267
|
+
fieldType: z16.literal("link"),
|
|
1239
1268
|
fallback: linkFallbackSchema2
|
|
1240
1269
|
}),
|
|
1241
1270
|
fieldBaseSchema.extend({
|
|
1242
|
-
fieldType:
|
|
1271
|
+
fieldType: z16.literal("image"),
|
|
1243
1272
|
fallback: imageFallbackSchema
|
|
1244
1273
|
})
|
|
1245
1274
|
]);
|
|
1246
|
-
var siteFieldContractV1Schema =
|
|
1247
|
-
version:
|
|
1275
|
+
var siteFieldContractV1Schema = z16.object({
|
|
1276
|
+
version: z16.literal(1),
|
|
1248
1277
|
fieldContractVersion: semanticVersionSchema,
|
|
1249
1278
|
scannerContractVersion: semanticVersionSchema,
|
|
1250
|
-
fields:
|
|
1279
|
+
fields: z16.array(siteFieldContractFieldSchema)
|
|
1251
1280
|
}).strict().superRefine((contract, context) => {
|
|
1252
1281
|
const seen = /* @__PURE__ */ new Set();
|
|
1253
1282
|
for (const [index, field] of contract.fields.entries()) {
|
|
@@ -1273,550 +1302,6 @@ function createSiteFieldContractHash(input) {
|
|
|
1273
1302
|
return `sha256:${sha256Hex(payload)}`;
|
|
1274
1303
|
}
|
|
1275
1304
|
|
|
1276
|
-
// ../shared/dist/site-setup.js
|
|
1277
|
-
var SITE_SETUP_RUN_STATUSES = [
|
|
1278
|
-
"waiting_for_agent",
|
|
1279
|
-
"working",
|
|
1280
|
-
"action_required",
|
|
1281
|
-
"ready_for_review",
|
|
1282
|
-
"completed"
|
|
1283
|
-
];
|
|
1284
|
-
var SITE_SETUP_RUN_MODES = ["initial", "update"];
|
|
1285
|
-
var SITE_SETUP_ERROR_CODES = [
|
|
1286
|
-
"action_required",
|
|
1287
|
-
"deployment_evidence_required",
|
|
1288
|
-
"field_contract_scan_failed",
|
|
1289
|
-
"invalid_editor_definition",
|
|
1290
|
-
"invalid_field_contract",
|
|
1291
|
-
"missing_build_revision",
|
|
1292
|
-
"missing_field_contract",
|
|
1293
|
-
"review_locked",
|
|
1294
|
-
"stale_deployment_contract",
|
|
1295
|
-
"stale_field_contract",
|
|
1296
|
-
"stale_setup_review",
|
|
1297
|
-
"update_required"
|
|
1298
|
-
];
|
|
1299
|
-
var CONTINUE_SITE_SETUP_MAX_ITEMS = 50;
|
|
1300
|
-
var CONTINUE_SITE_SETUP_RENDERED_PATH_MAX_BYTES = 512;
|
|
1301
|
-
var CONTINUE_SITE_SETUP_VISIBLE_VALUE_MAX_BYTES = 256;
|
|
1302
|
-
var CONTINUE_SITE_SETUP_LOCATOR_HINT_MAX_BYTES = 512;
|
|
1303
|
-
var CONTINUE_SITE_SETUP_REQUESTED_LABEL_MAX_BYTES = 120;
|
|
1304
|
-
var CONTINUE_SITE_SETUP_REQUESTED_SECTION_MAX_BYTES = 120;
|
|
1305
|
-
var CONTINUE_SITE_SETUP_REQUESTED_SUBSECTION_MAX_BYTES = 120;
|
|
1306
|
-
var SITE_SETUP_OWNER_EDITABILITY_NOTE_MAX_LENGTH = 2e3;
|
|
1307
|
-
var SITE_SETUP_OWNER_EDITABILITY_NOTE_MAX_BYTES = 8e3;
|
|
1308
|
-
var CONTINUE_SITE_SETUP_ITEMS_MAX_BYTES = 32 * 1024;
|
|
1309
|
-
var CONTINUE_SITE_SETUP_HTTP_BODY_MAX_BYTES = 64 * 1024;
|
|
1310
|
-
var siteSetupRunStatusSchema = z16.enum(SITE_SETUP_RUN_STATUSES);
|
|
1311
|
-
var siteSetupRunModeSchema = z16.enum(SITE_SETUP_RUN_MODES);
|
|
1312
|
-
var siteSetupErrorCodeSchema = z16.enum(SITE_SETUP_ERROR_CODES);
|
|
1313
|
-
var editorFieldSchema = z16.object({
|
|
1314
|
-
fieldId: fieldIdSchema,
|
|
1315
|
-
label: z16.string().trim().min(1),
|
|
1316
|
-
subsection: z16.string().trim().min(1).optional(),
|
|
1317
|
-
description: z16.string().trim().min(1).optional(),
|
|
1318
|
-
required: z16.boolean().optional(),
|
|
1319
|
-
maxLength: z16.number().int().positive().optional()
|
|
1320
|
-
}).strict();
|
|
1321
|
-
var editorSectionSchema = z16.object({
|
|
1322
|
-
label: z16.string().trim().min(1),
|
|
1323
|
-
fields: z16.array(editorFieldSchema).min(1)
|
|
1324
|
-
}).strict().superRefine((section, context) => {
|
|
1325
|
-
const closedSubsections = /* @__PURE__ */ new Set();
|
|
1326
|
-
let currentSubsection;
|
|
1327
|
-
for (const [index, field] of section.fields.entries()) {
|
|
1328
|
-
if (field.subsection === currentSubsection)
|
|
1329
|
-
continue;
|
|
1330
|
-
if (currentSubsection)
|
|
1331
|
-
closedSubsections.add(currentSubsection);
|
|
1332
|
-
currentSubsection = field.subsection;
|
|
1333
|
-
if (currentSubsection && closedSubsections.has(currentSubsection)) {
|
|
1334
|
-
context.addIssue({
|
|
1335
|
-
code: "custom",
|
|
1336
|
-
message: `Subgroup fields must stay contiguous: ${currentSubsection}`,
|
|
1337
|
-
path: ["fields", index, "subsection"]
|
|
1338
|
-
});
|
|
1339
|
-
}
|
|
1340
|
-
}
|
|
1341
|
-
});
|
|
1342
|
-
var editorRouteSchema = z16.object({
|
|
1343
|
-
routeKey: siteFieldRouteKeySchema,
|
|
1344
|
-
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(),
|
|
1345
|
-
label: z16.string().trim().min(1),
|
|
1346
|
-
sections: z16.array(editorSectionSchema).min(1)
|
|
1347
|
-
}).strict().superRefine((route, context) => {
|
|
1348
|
-
if (route.routeKey.includes("[") && !route.previewPath) {
|
|
1349
|
-
context.addIssue({
|
|
1350
|
-
code: "custom",
|
|
1351
|
-
path: ["previewPath"],
|
|
1352
|
-
message: "Dynamic editor routes need a previewPath for an existing page; keep the canonical routeKey unchanged."
|
|
1353
|
-
});
|
|
1354
|
-
}
|
|
1355
|
-
const sections = /* @__PURE__ */ new Set();
|
|
1356
|
-
for (const [index, section] of route.sections.entries()) {
|
|
1357
|
-
if (sections.has(section.label)) {
|
|
1358
|
-
context.addIssue({
|
|
1359
|
-
code: "custom",
|
|
1360
|
-
message: `Duplicate section label: ${section.label}`,
|
|
1361
|
-
path: ["sections", index, "label"]
|
|
1362
|
-
});
|
|
1363
|
-
}
|
|
1364
|
-
sections.add(section.label);
|
|
1365
|
-
}
|
|
1366
|
-
});
|
|
1367
|
-
var editorDefinitionV1Schema = z16.object({
|
|
1368
|
-
version: z16.literal(1),
|
|
1369
|
-
routes: z16.array(editorRouteSchema).min(1)
|
|
1370
|
-
}).strict().superRefine((definition, context) => {
|
|
1371
|
-
const routes = /* @__PURE__ */ new Set();
|
|
1372
|
-
const fields = /* @__PURE__ */ new Set();
|
|
1373
|
-
for (const [routeIndex, route] of definition.routes.entries()) {
|
|
1374
|
-
if (routes.has(route.routeKey)) {
|
|
1375
|
-
context.addIssue({
|
|
1376
|
-
code: "custom",
|
|
1377
|
-
message: `Duplicate route key: ${route.routeKey}`,
|
|
1378
|
-
path: ["routes", routeIndex, "routeKey"]
|
|
1379
|
-
});
|
|
1380
|
-
}
|
|
1381
|
-
routes.add(route.routeKey);
|
|
1382
|
-
for (const [sectionIndex, section] of route.sections.entries()) {
|
|
1383
|
-
for (const [fieldIndex, field] of section.fields.entries()) {
|
|
1384
|
-
if (fields.has(field.fieldId)) {
|
|
1385
|
-
context.addIssue({
|
|
1386
|
-
code: "custom",
|
|
1387
|
-
message: `Duplicate editor field id: ${field.fieldId}`,
|
|
1388
|
-
path: [
|
|
1389
|
-
"routes",
|
|
1390
|
-
routeIndex,
|
|
1391
|
-
"sections",
|
|
1392
|
-
sectionIndex,
|
|
1393
|
-
"fields",
|
|
1394
|
-
fieldIndex,
|
|
1395
|
-
"fieldId"
|
|
1396
|
-
]
|
|
1397
|
-
});
|
|
1398
|
-
}
|
|
1399
|
-
fields.add(field.fieldId);
|
|
1400
|
-
}
|
|
1401
|
-
}
|
|
1402
|
-
}
|
|
1403
|
-
});
|
|
1404
|
-
var forbiddenControlOrBidi = /[\u0000-\u001f\u007f-\u009f\u202a-\u202e\u2066-\u2069]/u;
|
|
1405
|
-
var forbiddenOwnerNoteControlOrBidi = /[\u0000-\u0008\u000b\u000c\u000e-\u001f\u007f-\u009f\u202a-\u202e\u2066-\u2069]/u;
|
|
1406
|
-
var unsafeLocator = /<\/?[a-z][^>]*>|\b(?:javascript|data:text\/html)\s*:|\bon[a-z]+\s*=/iu;
|
|
1407
|
-
var renderedPathSchema = z16.string().trim().transform((value) => value !== "/" ? value.replace(/\/+$/u, "") : value).superRefine((value, context) => {
|
|
1408
|
-
if (!value.startsWith("/") || value === "$global" || value.includes("?") || value.includes("#")) {
|
|
1409
|
-
context.addIssue({
|
|
1410
|
-
code: "custom",
|
|
1411
|
-
message: "renderedPath must be a canonical real path."
|
|
1412
|
-
});
|
|
1413
|
-
}
|
|
1414
|
-
addSafeByteIssues(value, CONTINUE_SITE_SETUP_RENDERED_PATH_MAX_BYTES, "renderedPath", context);
|
|
1415
|
-
});
|
|
1416
|
-
function normalizedSafeTextSchema(maxBytes, label) {
|
|
1417
|
-
return z16.string().transform((value) => value.trim().replace(new RegExp("\\p{White_Space}+", "gu"), " ")).pipe(z16.string().min(1)).superRefine((value, context) => {
|
|
1418
|
-
addSafeByteIssues(value, maxBytes, label, context);
|
|
1419
|
-
if (label === "locatorHint" && unsafeLocator.test(value)) {
|
|
1420
|
-
context.addIssue({
|
|
1421
|
-
code: "custom",
|
|
1422
|
-
message: "locatorHint contains unsafe markup or executable content."
|
|
1423
|
-
});
|
|
1424
|
-
}
|
|
1425
|
-
});
|
|
1426
|
-
}
|
|
1427
|
-
var correctionItemBase = {
|
|
1428
|
-
renderedPath: renderedPathSchema,
|
|
1429
|
-
visibleValue: normalizedSafeTextSchema(CONTINUE_SITE_SETUP_VISIBLE_VALUE_MAX_BYTES, "visibleValue"),
|
|
1430
|
-
locatorHint: normalizedSafeTextSchema(CONTINUE_SITE_SETUP_LOCATOR_HINT_MAX_BYTES, "locatorHint"),
|
|
1431
|
-
requestedLabel: normalizedSafeTextSchema(CONTINUE_SITE_SETUP_REQUESTED_LABEL_MAX_BYTES, "requestedLabel").optional(),
|
|
1432
|
-
requestedSection: normalizedSafeTextSchema(CONTINUE_SITE_SETUP_REQUESTED_SECTION_MAX_BYTES, "requestedSection").optional(),
|
|
1433
|
-
requestedSubsection: normalizedSafeTextSchema(CONTINUE_SITE_SETUP_REQUESTED_SUBSECTION_MAX_BYTES, "requestedSubsection").optional(),
|
|
1434
|
-
requestedSortOrder: z16.number().int().nonnegative().optional()
|
|
1435
|
-
};
|
|
1436
|
-
var setupCorrectionItemSchema = z16.discriminatedUnion("kind", [
|
|
1437
|
-
z16.object({ kind: z16.literal("text"), ...correctionItemBase }).strict(),
|
|
1438
|
-
z16.object({ kind: z16.literal("link"), ...correctionItemBase }).strict(),
|
|
1439
|
-
z16.object({ kind: z16.literal("image"), ...correctionItemBase }).strict()
|
|
1440
|
-
]).superRefine((item, context) => {
|
|
1441
|
-
if (item.requestedSubsection && !item.requestedSection) {
|
|
1442
|
-
context.addIssue({
|
|
1443
|
-
code: "custom",
|
|
1444
|
-
message: "requestedSubsection requires requestedSection.",
|
|
1445
|
-
path: ["requestedSubsection"]
|
|
1446
|
-
});
|
|
1447
|
-
}
|
|
1448
|
-
});
|
|
1449
|
-
var setupCorrectionItemsSchema = z16.array(setupCorrectionItemSchema).max(CONTINUE_SITE_SETUP_MAX_ITEMS).superRefine((items, context) => {
|
|
1450
|
-
const bytes = utf8Bytes(stableJsonStringify(items));
|
|
1451
|
-
if (bytes > CONTINUE_SITE_SETUP_ITEMS_MAX_BYTES) {
|
|
1452
|
-
context.addIssue({
|
|
1453
|
-
code: "custom",
|
|
1454
|
-
message: "Correction items exceed the 32 KiB canonical payload limit."
|
|
1455
|
-
});
|
|
1456
|
-
}
|
|
1457
|
-
});
|
|
1458
|
-
var siteSetupOwnerEditabilityNoteSchema = z16.string().max(SITE_SETUP_OWNER_EDITABILITY_NOTE_MAX_LENGTH).superRefine((value, context) => {
|
|
1459
|
-
if (utf8Bytes(value) > SITE_SETUP_OWNER_EDITABILITY_NOTE_MAX_BYTES) {
|
|
1460
|
-
context.addIssue({
|
|
1461
|
-
code: "custom",
|
|
1462
|
-
message: `ownerEditabilityNote exceeds ${SITE_SETUP_OWNER_EDITABILITY_NOTE_MAX_BYTES} UTF-8 bytes.`
|
|
1463
|
-
});
|
|
1464
|
-
}
|
|
1465
|
-
if (forbiddenOwnerNoteControlOrBidi.test(value)) {
|
|
1466
|
-
context.addIssue({
|
|
1467
|
-
code: "custom",
|
|
1468
|
-
message: "ownerEditabilityNote contains a forbidden control or bidi character."
|
|
1469
|
-
});
|
|
1470
|
-
}
|
|
1471
|
-
});
|
|
1472
|
-
var SITE_SETUP_MODULE_SCOPES = {
|
|
1473
|
-
editing: ["setup:read", "setup:write"],
|
|
1474
|
-
analytics: [
|
|
1475
|
-
"analytics:setup",
|
|
1476
|
-
"analytics:sync",
|
|
1477
|
-
"analytics:test",
|
|
1478
|
-
"analytics:readiness",
|
|
1479
|
-
"analytics:agent_instructions",
|
|
1480
|
-
"analytics:public_key_read"
|
|
1481
|
-
]
|
|
1482
|
-
};
|
|
1483
|
-
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.");
|
|
1484
|
-
function siteSetupScopes(modules) {
|
|
1485
|
-
return modules.flatMap((module) => [...SITE_SETUP_MODULE_SCOPES[module]]);
|
|
1486
|
-
}
|
|
1487
|
-
function hasExactSiteSetupScopes(scopes, modules) {
|
|
1488
|
-
const matches = (expected) => scopes.length === expected.length && expected.every((scope) => scopes.includes(scope));
|
|
1489
|
-
return modules ? matches(siteSetupScopes(modules)) : matches(siteSetupScopes(["editing"])) || matches(siteSetupScopes(["editing", "analytics"]));
|
|
1490
|
-
}
|
|
1491
|
-
var siteSetupActivityInputSchema = z16.object({
|
|
1492
|
-
phase: z16.enum([
|
|
1493
|
-
"inspecting",
|
|
1494
|
-
"integrating",
|
|
1495
|
-
"deploying",
|
|
1496
|
-
"verifying",
|
|
1497
|
-
"repairing"
|
|
1498
|
-
]),
|
|
1499
|
-
textId: z16.enum([
|
|
1500
|
-
"inspecting",
|
|
1501
|
-
"integrating",
|
|
1502
|
-
"deploying",
|
|
1503
|
-
"verifying",
|
|
1504
|
-
"repairing"
|
|
1505
|
-
])
|
|
1506
|
-
}).strict().refine((value) => value.phase === value.textId, "Activity text must describe its phase.");
|
|
1507
|
-
var nextActionFields = {
|
|
1508
|
-
actor: z16.enum(["agent", "user", "siteplane"]),
|
|
1509
|
-
boundary: z16.enum([
|
|
1510
|
-
"source",
|
|
1511
|
-
"environment",
|
|
1512
|
-
"deployment",
|
|
1513
|
-
"verification",
|
|
1514
|
-
"authorization",
|
|
1515
|
-
"review"
|
|
1516
|
-
]),
|
|
1517
|
-
precondition: z16.string().min(1).max(1e3),
|
|
1518
|
-
instruction: z16.string().min(1).max(2e3),
|
|
1519
|
-
expectedEvidence: z16.string().min(1).max(1e3)
|
|
1520
|
-
};
|
|
1521
|
-
var siteSetupNextActionSchema = z16.discriminatedUnion("kind", [
|
|
1522
|
-
z16.object({
|
|
1523
|
-
...nextActionFields,
|
|
1524
|
-
kind: z16.literal("run_command"),
|
|
1525
|
-
command: z16.string().min(1).max(500)
|
|
1526
|
-
}).strict(),
|
|
1527
|
-
z16.object({ ...nextActionFields, kind: z16.literal("agent_edit") }).strict(),
|
|
1528
|
-
z16.object({ ...nextActionFields, kind: z16.literal("needs_user_action") }).strict(),
|
|
1529
|
-
z16.object({ ...nextActionFields, kind: z16.literal("wait") }).strict(),
|
|
1530
|
-
z16.object({ ...nextActionFields, kind: z16.literal("done") }).strict()
|
|
1531
|
-
]);
|
|
1532
|
-
var siteSetupTaskRunSchema = z16.object({
|
|
1533
|
-
runId: z16.string().uuid(),
|
|
1534
|
-
mode: siteSetupRunModeSchema,
|
|
1535
|
-
status: siteSetupRunStatusSchema,
|
|
1536
|
-
fieldContractHash: z16.string().nullable(),
|
|
1537
|
-
deploymentOrigin: z16.string().url().nullable(),
|
|
1538
|
-
deploymentRevision: z16.string().nullable(),
|
|
1539
|
-
publicRuntimeKeyId: z16.string().uuid().nullable(),
|
|
1540
|
-
reviewVersion: z16.number().int().positive()
|
|
1541
|
-
}).strict();
|
|
1542
|
-
var siteSetupTaskProgressSchema = z16.object({
|
|
1543
|
-
progressStage: z16.enum([
|
|
1544
|
-
"waiting_for_connection",
|
|
1545
|
-
"agent_connected",
|
|
1546
|
-
"project_context_loaded",
|
|
1547
|
-
"fields_prepared",
|
|
1548
|
-
"deployment_verification",
|
|
1549
|
-
"ready_for_review",
|
|
1550
|
-
"action_required",
|
|
1551
|
-
"completed"
|
|
1552
|
-
]),
|
|
1553
|
-
lastVerifiedAt: z16.string().datetime().nullable(),
|
|
1554
|
-
lastActivityAt: z16.string().datetime(),
|
|
1555
|
-
activitySource: z16.enum(["user", "server", "agent"]),
|
|
1556
|
-
activityPhase: siteSetupActivityInputSchema.shape.phase.nullable(),
|
|
1557
|
-
activityTextId: siteSetupActivityInputSchema.shape.textId.nullable()
|
|
1558
|
-
}).strict();
|
|
1559
|
-
var siteSetupTaskSchema = z16.object({
|
|
1560
|
-
contractVersion: z16.literal("siteplane.setup-task.v2"),
|
|
1561
|
-
workflow: z16.enum(["initial_setup", "structure_update"]),
|
|
1562
|
-
goal: z16.string().min(1),
|
|
1563
|
-
modules: siteSetupModulesSchema,
|
|
1564
|
-
authorizationVersion: z16.number().int().positive(),
|
|
1565
|
-
authorizedScopes: z16.array(z16.string()).min(2),
|
|
1566
|
-
site: z16.object({
|
|
1567
|
-
siteId: z16.string().uuid(),
|
|
1568
|
-
portalPath: z16.string(),
|
|
1569
|
-
adminOrigin: z16.string().url()
|
|
1570
|
-
}).strict().nullable(),
|
|
1571
|
-
run: siteSetupTaskRunSchema.nullable(),
|
|
1572
|
-
progress: siteSetupTaskProgressSchema.nullable(),
|
|
1573
|
-
deployment: setupDeploymentRecordSchema.nullable(),
|
|
1574
|
-
revalidationGeneration: z16.number().int().positive(),
|
|
1575
|
-
assignment: z16.enum(["owned", "provisional", "claimed"]),
|
|
1576
|
-
deadline: z16.string().datetime().nullable(),
|
|
1577
|
-
userInstructions: z16.object({
|
|
1578
|
-
text: siteSetupOwnerEditabilityNoteSchema,
|
|
1579
|
-
source: z16.literal("user"),
|
|
1580
|
-
trust: z16.literal("untrusted")
|
|
1581
|
-
}).strict(),
|
|
1582
|
-
corrections: setupCorrectionItemsSchema,
|
|
1583
|
-
contentSelectionSummary: z16.object({
|
|
1584
|
-
text: siteSetupOwnerEditabilityNoteSchema,
|
|
1585
|
-
source: z16.literal("agent"),
|
|
1586
|
-
trust: z16.literal("untrusted")
|
|
1587
|
-
}).strict().nullable(),
|
|
1588
|
-
environmentBindings: z16.array(z16.object({
|
|
1589
|
-
name: z16.string().regex(/^[A-Z][A-Z0-9_]+$/u),
|
|
1590
|
-
source: z16.string().min(1),
|
|
1591
|
-
sensitivity: z16.enum(["public", "secret"]),
|
|
1592
|
-
usage: z16.enum(["build", "server", "build_and_server"]),
|
|
1593
|
-
evidence: z16.string().min(1)
|
|
1594
|
-
}).strict()),
|
|
1595
|
-
nextAction: siteSetupNextActionSchema,
|
|
1596
|
-
error: z16.object({
|
|
1597
|
-
code: z16.string().regex(/^[a-z0-9_.]+$/u).max(160),
|
|
1598
|
-
boundary: nextActionFields.boundary,
|
|
1599
|
-
responsibleActor: nextActionFields.actor,
|
|
1600
|
-
retryable: z16.boolean(),
|
|
1601
|
-
retryAfter: z16.number().int().nonnegative().nullable(),
|
|
1602
|
-
requestId: z16.string().regex(/^[A-Za-z0-9_-]+$/u).max(128)
|
|
1603
|
-
}).strict().nullable(),
|
|
1604
|
-
packages: siteSetupPackagesSchema,
|
|
1605
|
-
communication: z16.object({
|
|
1606
|
-
beforeSourceChanges: z16.string().min(1),
|
|
1607
|
-
updates: z16.array(z16.string().min(1)).min(1),
|
|
1608
|
-
blocker: z16.string().min(1)
|
|
1609
|
-
}).strict(),
|
|
1610
|
-
discovery: z16.object({
|
|
1611
|
-
inspectPublicRoutes: z16.boolean(),
|
|
1612
|
-
contentKinds: z16.array(z16.enum(["text", "longText", "link", "image"])).min(1),
|
|
1613
|
-
rules: z16.array(z16.string().min(1)).min(1)
|
|
1614
|
-
}).strict(),
|
|
1615
|
-
steps: z16.array(z16.object({
|
|
1616
|
-
id: z16.enum([
|
|
1617
|
-
"inspect_repository",
|
|
1618
|
-
"install_packages",
|
|
1619
|
-
"instrument_fields",
|
|
1620
|
-
"apply_contract",
|
|
1621
|
-
"deploy_production",
|
|
1622
|
-
"verify_deployment"
|
|
1623
|
-
]),
|
|
1624
|
-
instruction: z16.string().min(1)
|
|
1625
|
-
}).strict()).length(6),
|
|
1626
|
-
completion: z16.object({
|
|
1627
|
-
verifiedStatus: z16.literal("ready_for_review"),
|
|
1628
|
-
instruction: z16.string().min(1)
|
|
1629
|
-
}).strict()
|
|
1630
|
-
}).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.");
|
|
1631
|
-
var canonicalHashSchema = z16.string().regex(/^sha256:[0-9a-f]{64}$/iu);
|
|
1632
|
-
var deploymentRevisionSchema = normalizedSafeTextSchema(256, "deploymentRevision");
|
|
1633
|
-
var continueSiteSetupInputSchema = z16.object({
|
|
1634
|
-
siteId: z16.string().uuid(),
|
|
1635
|
-
runId: z16.string().uuid(),
|
|
1636
|
-
expectedReviewVersion: z16.number().int().positive(),
|
|
1637
|
-
mutationId: z16.string().uuid(),
|
|
1638
|
-
intent: z16.enum(["continue_review", "correct_completed_review"]),
|
|
1639
|
-
expectedFieldContractHash: canonicalHashSchema,
|
|
1640
|
-
expectedDeploymentRevision: deploymentRevisionSchema,
|
|
1641
|
-
correctionItems: setupCorrectionItemsSchema,
|
|
1642
|
-
ownerEditabilityNote: siteSetupOwnerEditabilityNoteSchema.optional()
|
|
1643
|
-
}).strict();
|
|
1644
|
-
var saveSiteSetupOwnerNoteInputSchema = z16.object({
|
|
1645
|
-
siteId: z16.string().uuid(),
|
|
1646
|
-
runId: z16.string().uuid(),
|
|
1647
|
-
expectedReviewVersion: z16.number().int().positive(),
|
|
1648
|
-
expectedFieldContractHash: canonicalHashSchema,
|
|
1649
|
-
expectedDeploymentRevision: deploymentRevisionSchema,
|
|
1650
|
-
ownerEditabilityNote: siteSetupOwnerEditabilityNoteSchema
|
|
1651
|
-
}).strict();
|
|
1652
|
-
var setupReviewPreferenceSelectionSchema = z16.object({
|
|
1653
|
-
analyticsMode: z16.enum(["disabled", "session_only"]).nullable(),
|
|
1654
|
-
assetTargetType: z16.enum(["repo_static_assets", "siteplane_managed_fallback"]).nullable(),
|
|
1655
|
-
assetTargetId: z16.string().uuid().nullable()
|
|
1656
|
-
}).strict().refine((value) => value.assetTargetType !== null || value.assetTargetId === null, {
|
|
1657
|
-
message: "An asset target requires its delivery type."
|
|
1658
|
-
});
|
|
1659
|
-
var setupReviewPreferencesSchema = setupReviewPreferenceSelectionSchema.safeExtend({
|
|
1660
|
-
managedHostingApproved: z16.boolean()
|
|
1661
|
-
});
|
|
1662
|
-
var saveSetupReviewPreferencesInputSchema = z16.object({
|
|
1663
|
-
siteId: z16.string().uuid(),
|
|
1664
|
-
runId: z16.string().uuid(),
|
|
1665
|
-
expectedReviewVersion: z16.number().int().positive(),
|
|
1666
|
-
preferences: setupReviewPreferenceSelectionSchema
|
|
1667
|
-
}).strict();
|
|
1668
|
-
var siteSetupContextInputSchema = z16.object({}).strict();
|
|
1669
|
-
var siteSetupApplyInputSchema = z16.object({
|
|
1670
|
-
fieldContract: siteFieldContractV1Schema,
|
|
1671
|
-
editorDefinition: editorDefinitionV1Schema,
|
|
1672
|
-
contentSelectionSummary: siteSetupOwnerEditabilityNoteSchema.refine((text) => text.trim().length > 0, "Describe the selected content, important exclusions and any open gaps.")
|
|
1673
|
-
}).strict().superRefine((input, context) => {
|
|
1674
|
-
const contractRoutesByFieldId = new Map(input.fieldContract.fields.map((field) => [
|
|
1675
|
-
field.fieldId,
|
|
1676
|
-
field.routeKey
|
|
1677
|
-
]));
|
|
1678
|
-
const definitionFieldIds = /* @__PURE__ */ new Set();
|
|
1679
|
-
for (const [routeIndex, route] of input.editorDefinition.routes.entries()) {
|
|
1680
|
-
for (const [sectionIndex, section] of route.sections.entries()) {
|
|
1681
|
-
for (const [fieldIndex, field] of section.fields.entries()) {
|
|
1682
|
-
const fieldPath = [
|
|
1683
|
-
"editorDefinition",
|
|
1684
|
-
"routes",
|
|
1685
|
-
routeIndex,
|
|
1686
|
-
"sections",
|
|
1687
|
-
sectionIndex,
|
|
1688
|
-
"fields",
|
|
1689
|
-
fieldIndex,
|
|
1690
|
-
"fieldId"
|
|
1691
|
-
];
|
|
1692
|
-
const contractRouteKey = contractRoutesByFieldId.get(field.fieldId);
|
|
1693
|
-
const contractField = input.fieldContract.fields.find((candidate) => candidate.fieldId === field.fieldId);
|
|
1694
|
-
definitionFieldIds.add(field.fieldId);
|
|
1695
|
-
if (!contractRouteKey) {
|
|
1696
|
-
context.addIssue({
|
|
1697
|
-
code: "custom",
|
|
1698
|
-
message: `Unknown editor field id: ${field.fieldId}`,
|
|
1699
|
-
path: fieldPath
|
|
1700
|
-
});
|
|
1701
|
-
} else if (contractRouteKey !== route.routeKey) {
|
|
1702
|
-
context.addIssue({
|
|
1703
|
-
code: "custom",
|
|
1704
|
-
message: `Editor field ${field.fieldId} must use route ${contractRouteKey}.`,
|
|
1705
|
-
path: fieldPath
|
|
1706
|
-
});
|
|
1707
|
-
} else if (field.maxLength !== void 0 && contractField?.fieldType !== "text" && contractField?.fieldType !== "longText") {
|
|
1708
|
-
context.addIssue({
|
|
1709
|
-
code: "custom",
|
|
1710
|
-
message: `maxLength is not supported for ${contractField?.fieldType ?? "unknown"} fields.`,
|
|
1711
|
-
path: [
|
|
1712
|
-
"editorDefinition",
|
|
1713
|
-
"routes",
|
|
1714
|
-
routeIndex,
|
|
1715
|
-
"sections",
|
|
1716
|
-
sectionIndex,
|
|
1717
|
-
"fields",
|
|
1718
|
-
fieldIndex,
|
|
1719
|
-
"maxLength"
|
|
1720
|
-
]
|
|
1721
|
-
});
|
|
1722
|
-
}
|
|
1723
|
-
}
|
|
1724
|
-
}
|
|
1725
|
-
}
|
|
1726
|
-
for (const field of input.fieldContract.fields) {
|
|
1727
|
-
if (!definitionFieldIds.has(field.fieldId)) {
|
|
1728
|
-
context.addIssue({
|
|
1729
|
-
code: "custom",
|
|
1730
|
-
message: `Missing editor field id: ${field.fieldId}`,
|
|
1731
|
-
path: ["editorDefinition", "routes"]
|
|
1732
|
-
});
|
|
1733
|
-
}
|
|
1734
|
-
}
|
|
1735
|
-
});
|
|
1736
|
-
var siteSetupVerifyInputSchema = z16.object({
|
|
1737
|
-
deploymentUrl: z16.string().url().refine((value) => value.startsWith("https://")),
|
|
1738
|
-
deploymentRevision: deploymentRevisionSchema,
|
|
1739
|
-
wait: z16.boolean().optional()
|
|
1740
|
-
}).strict();
|
|
1741
|
-
var siteSetupEvidenceInputSchema = z16.object({
|
|
1742
|
-
siteId: z16.string().uuid(),
|
|
1743
|
-
runId: z16.string().uuid(),
|
|
1744
|
-
expectedFieldContractHash: canonicalHashSchema,
|
|
1745
|
-
expectedDeploymentOrigin: z16.string().url().refine((value) => value.startsWith("https://")),
|
|
1746
|
-
expectedDeploymentRevision: deploymentRevisionSchema,
|
|
1747
|
-
publicRuntimeKeyId: z16.string().uuid(),
|
|
1748
|
-
bridgeSessionId: normalizedSafeTextSchema(256, "bridgeSessionId"),
|
|
1749
|
-
observations: z16.array(z16.object({
|
|
1750
|
-
fieldId: fieldIdSchema,
|
|
1751
|
-
fieldType: fieldTypeSchema,
|
|
1752
|
-
routeKey: siteFieldRouteKeySchema,
|
|
1753
|
-
renderedPath: renderedPathSchema,
|
|
1754
|
-
targetResolved: z16.boolean(),
|
|
1755
|
-
previewAck: z16.boolean()
|
|
1756
|
-
}).strict().refine((value) => !value.previewAck || value.targetResolved, "Preview ACK requires a resolved target.")).min(1).max(200)
|
|
1757
|
-
}).strict();
|
|
1758
|
-
var completeSetupReviewInputSchema = z16.object({
|
|
1759
|
-
siteId: z16.string().uuid(),
|
|
1760
|
-
runId: z16.string().uuid(),
|
|
1761
|
-
expectedReviewVersion: z16.number().int().positive(),
|
|
1762
|
-
expectedFieldContractHash: canonicalHashSchema,
|
|
1763
|
-
expectedDeploymentRevision: deploymentRevisionSchema,
|
|
1764
|
-
expectedReadyFingerprint: canonicalHashSchema
|
|
1765
|
-
}).strict();
|
|
1766
|
-
var activateSiteSetupInputSchema = z16.object({
|
|
1767
|
-
siteId: z16.string().uuid(),
|
|
1768
|
-
runId: z16.string().uuid(),
|
|
1769
|
-
expectedReviewVersion: z16.number().int().positive(),
|
|
1770
|
-
expectedSnapshotHash: canonicalHashSchema
|
|
1771
|
-
}).strict();
|
|
1772
|
-
var refreshSiteSetupDeploymentInputSchema = z16.object({
|
|
1773
|
-
siteId: z16.string().uuid(),
|
|
1774
|
-
deploymentUrl: z16.string().url().refine((value) => value.startsWith("https://")),
|
|
1775
|
-
deploymentRevision: deploymentRevisionSchema
|
|
1776
|
-
}).strict();
|
|
1777
|
-
function addSafeByteIssues(value, maxBytes, label, context) {
|
|
1778
|
-
if (utf8Bytes(value) > maxBytes) {
|
|
1779
|
-
context.addIssue({
|
|
1780
|
-
code: "custom",
|
|
1781
|
-
message: `${label} exceeds ${maxBytes} UTF-8 bytes.`
|
|
1782
|
-
});
|
|
1783
|
-
}
|
|
1784
|
-
if (forbiddenControlOrBidi.test(value)) {
|
|
1785
|
-
context.addIssue({
|
|
1786
|
-
code: "custom",
|
|
1787
|
-
message: `${label} contains a forbidden control or bidi character.`
|
|
1788
|
-
});
|
|
1789
|
-
}
|
|
1790
|
-
}
|
|
1791
|
-
function utf8Bytes(value) {
|
|
1792
|
-
return new TextEncoder().encode(value).byteLength;
|
|
1793
|
-
}
|
|
1794
|
-
var setupActivationApprovalSchema = z16.object({
|
|
1795
|
-
reviewVersion: z16.number().int().positive(),
|
|
1796
|
-
snapshotHash: canonicalHashSchema,
|
|
1797
|
-
analytics: z16.object({
|
|
1798
|
-
status: z16.enum(["active", "skipped"]),
|
|
1799
|
-
reviewVersion: z16.number().int().positive(),
|
|
1800
|
-
generation: z16.number().int().nonnegative()
|
|
1801
|
-
}).optional()
|
|
1802
|
-
});
|
|
1803
|
-
var activateSetupModulesInputSchema = activateSiteSetupInputSchema.extend({
|
|
1804
|
-
analytics: z16.discriminatedUnion("decision", [
|
|
1805
|
-
z16.object({ decision: z16.literal("pending") }).strict(),
|
|
1806
|
-
z16.object({
|
|
1807
|
-
decision: z16.literal("enable"),
|
|
1808
|
-
readinessTestRunId: z16.string().regex(/^analytics_owner_[0-9a-f-]{36}$/u),
|
|
1809
|
-
expectedInstallationGeneration: z16.number().int().positive(),
|
|
1810
|
-
measurementApproved: z16.literal(true)
|
|
1811
|
-
}).strict(),
|
|
1812
|
-
z16.object({
|
|
1813
|
-
decision: z16.literal("skip"),
|
|
1814
|
-
expectedInstallationGeneration: z16.number().int().nonnegative(),
|
|
1815
|
-
continueWithoutAnalytics: z16.literal(true)
|
|
1816
|
-
}).strict()
|
|
1817
|
-
])
|
|
1818
|
-
}).strict();
|
|
1819
|
-
|
|
1820
1305
|
// ../shared/dist/bridge-protocol.js
|
|
1821
1306
|
var BRIDGE_PROTOCOL_VERSION = 2;
|
|
1822
1307
|
var bridgeRectSchema = z17.object({
|
|
@@ -1875,18 +1360,6 @@ var fieldBridgeIdentitySchema = z17.object({
|
|
|
1875
1360
|
fieldContractHash: canonicalFieldContractHashSchema,
|
|
1876
1361
|
deploymentRevision: z17.string().trim().min(1).max(256)
|
|
1877
1362
|
}).strict();
|
|
1878
|
-
var setupPreviewAccessSchema = z17.object({
|
|
1879
|
-
capability: z17.string().regex(/^v1\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]{43}$/u).max(4096),
|
|
1880
|
-
expiresAt: z17.string().datetime()
|
|
1881
|
-
}).strict();
|
|
1882
|
-
var setupPreviewReadSchema = fieldBridgeIdentitySchema.extend({
|
|
1883
|
-
scope: z17.literal("setup_preview"),
|
|
1884
|
-
siteId: z17.string().uuid(),
|
|
1885
|
-
runId: z17.string().uuid(),
|
|
1886
|
-
bridgeSessionId: z17.string().min(1),
|
|
1887
|
-
expiresAt: z17.string().datetime(),
|
|
1888
|
-
contract: siteFieldContractV1Schema
|
|
1889
|
-
}).strict();
|
|
1890
1363
|
var fieldBridgeBaseSchema = z17.object({
|
|
1891
1364
|
version: z17.literal(BRIDGE_PROTOCOL_VERSION),
|
|
1892
1365
|
type: z17.enum(FIELD_BRIDGE_MESSAGE_TYPES),
|
|
@@ -1914,8 +1387,7 @@ var fieldBridgeInitMessageSchema = fieldBridgeBaseSchema.extend({
|
|
|
1914
1387
|
payload: z17.object({
|
|
1915
1388
|
adminOrigin: z17.string().url(),
|
|
1916
1389
|
customerOrigin: z17.string().url(),
|
|
1917
|
-
renderedPath: realRenderedPathSchema
|
|
1918
|
-
setupPreview: setupPreviewAccessSchema.optional()
|
|
1390
|
+
renderedPath: realRenderedPathSchema
|
|
1919
1391
|
}).strict()
|
|
1920
1392
|
});
|
|
1921
1393
|
var fieldBridgeReadyMessageSchema = fieldBridgeBaseSchema.extend({
|
|
@@ -1928,7 +1400,7 @@ var fieldBridgeReadyMessageSchema = fieldBridgeBaseSchema.extend({
|
|
|
1928
1400
|
z17.literal("preview_values"),
|
|
1929
1401
|
z17.literal("field_evidence"),
|
|
1930
1402
|
z17.literal("visual_field_control")
|
|
1931
|
-
]).rest(z17.enum(["analytics_preview_readiness"
|
|
1403
|
+
]).rest(z17.enum(["analytics_preview_readiness"])).refine((capabilities) => capabilities.length <= 5)
|
|
1932
1404
|
}).strict()
|
|
1933
1405
|
});
|
|
1934
1406
|
var fieldBridgeFieldsMessageSchema = fieldBridgeBaseSchema.extend({
|
|
@@ -2004,7 +1476,7 @@ var fieldBridgeMissingContentMessageSchema = fieldBridgeBaseSchema.extend({
|
|
|
2004
1476
|
type: z17.literal("siteplane:field-bridge:missing-content"),
|
|
2005
1477
|
payload: z17.object({
|
|
2006
1478
|
action: fieldBridgeMissingContentActionSchema,
|
|
2007
|
-
item:
|
|
1479
|
+
item: missingContentItemSchema,
|
|
2008
1480
|
suggestedSection: bridgeSectionSchema.optional()
|
|
2009
1481
|
}).strict()
|
|
2010
1482
|
});
|
|
@@ -2165,12 +1637,7 @@ var updateEditorOrganizationInputSchema = z21.discriminatedUnion("operation", [
|
|
|
2165
1637
|
routeKey: siteFieldRouteKeySchema.refine((value) => value !== "$global", "Global content has no page label."),
|
|
2166
1638
|
label: labelSchema
|
|
2167
1639
|
})
|
|
2168
|
-
]).
|
|
2169
|
-
review: z21.object({
|
|
2170
|
-
runId: z21.string().uuid(),
|
|
2171
|
-
expectedReviewVersion: z21.number().int().positive()
|
|
2172
|
-
}).strict().optional()
|
|
2173
|
-
})).superRefine((input, context) => {
|
|
1640
|
+
]).superRefine((input, context) => {
|
|
2174
1641
|
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) {
|
|
2175
1642
|
context.addIssue({
|
|
2176
1643
|
code: "custom",
|
|
@@ -2253,9 +1720,6 @@ var EARLY_ACCESS_PLAN = {
|
|
|
2253
1720
|
bookingRemindersEnabled: true
|
|
2254
1721
|
};
|
|
2255
1722
|
|
|
2256
|
-
// ../shared/dist/first-party-image-upload.js
|
|
2257
|
-
var maxFirstPartyImageUploadBytes = 4 * 1024 * 1024;
|
|
2258
|
-
|
|
2259
1723
|
// ../shared/dist/readiness.js
|
|
2260
1724
|
import { z as z24 } from "zod";
|
|
2261
1725
|
var READINESS_CHECK_KEYS = [
|
|
@@ -2277,244 +1741,82 @@ var readinessStatusSchema = z24.enum(READINESS_STATUSES);
|
|
|
2277
1741
|
|
|
2278
1742
|
// ../shared/dist/site.js
|
|
2279
1743
|
import { z as z25 } from "zod";
|
|
2280
|
-
var SITE_STATUSES = [
|
|
2281
|
-
"setup",
|
|
2282
|
-
"active",
|
|
2283
|
-
"disabled",
|
|
2284
|
-
"archived"
|
|
2285
|
-
];
|
|
1744
|
+
var SITE_STATUSES = ["active", "disabled", "archived"];
|
|
2286
1745
|
var siteStatusSchema = z25.enum(SITE_STATUSES);
|
|
2287
1746
|
var websiteUrlSchema = z25.string().trim().url().refine((value) => value.startsWith("https://") || value.startsWith("http://"), "Website URL must use http or https");
|
|
2288
1747
|
|
|
2289
|
-
// ../shared/dist/
|
|
1748
|
+
// ../shared/dist/field-sync.js
|
|
2290
1749
|
import { z as z26 } from "zod";
|
|
2291
|
-
var
|
|
2292
|
-
|
|
2293
|
-
|
|
2294
|
-
|
|
2295
|
-
|
|
2296
|
-
|
|
2297
|
-
|
|
2298
|
-
|
|
2299
|
-
|
|
2300
|
-
|
|
2301
|
-
}).strict().refine((value) => value.targetType === "siteplane_managed_fallback" || !value.approveManagedHosting);
|
|
2302
|
-
var setupAssetTargetApprovalSchema = z26.object({
|
|
2303
|
-
id: z26.string().uuid(),
|
|
2304
|
-
runId: z26.string().uuid(),
|
|
2305
|
-
reviewVersion: z26.number().int().positive(),
|
|
2306
|
-
snapshotHash: z26.string().regex(/^sha256:[0-9a-f]{64}$/u),
|
|
2307
|
-
targetId: z26.string().uuid(),
|
|
2308
|
-
targetType: z26.enum(["repo_static_assets", "siteplane_managed_fallback"]),
|
|
2309
|
-
targetRevision: z26.number().int().positive(),
|
|
2310
|
-
deploymentOrigin: z26.string().url(),
|
|
2311
|
-
gitConnectionId: z26.string().uuid().nullable(),
|
|
2312
|
-
gitRevision: z26.number().int().positive().nullable(),
|
|
2313
|
-
managedHostingApproved: z26.boolean(),
|
|
2314
|
-
actorUserId: z26.string().uuid(),
|
|
2315
|
-
approvedAt: z26.string().datetime({ offset: true })
|
|
2316
|
-
}).strict();
|
|
2317
|
-
var setupAssetReadinessSchema = z26.union([
|
|
2318
|
-
z26.object({
|
|
2319
|
-
status: z26.enum([
|
|
2320
|
-
"not_required",
|
|
2321
|
-
"needs_choice",
|
|
2322
|
-
"stale_setup_review",
|
|
2323
|
-
"permission_denied"
|
|
2324
|
-
])
|
|
2325
|
-
}).strict(),
|
|
2326
|
-
z26.object({
|
|
2327
|
-
status: z26.literal("stale_approval"),
|
|
2328
|
-
approval: setupAssetTargetApprovalSchema.optional()
|
|
2329
|
-
}).strict(),
|
|
1750
|
+
var FIELD_SYNC_MAX_FIELDS = 2e3;
|
|
1751
|
+
var filePathSchema = z26.string().trim().min(1).max(500).refine((value) => !value.startsWith("/") && !value.includes("\\") && !/^[a-z]:/iu.test(value) && !value.split("/").includes(".."), "Use the file path relative to the project root.");
|
|
1752
|
+
var fieldBase = {
|
|
1753
|
+
id: fieldIdSchema.max(160),
|
|
1754
|
+
file: filePathSchema,
|
|
1755
|
+
label: z26.string().trim().min(1).max(120).optional()
|
|
1756
|
+
};
|
|
1757
|
+
var fieldSyncFieldSchema = z26.discriminatedUnion("type", [
|
|
1758
|
+
z26.object({ ...fieldBase, type: z26.literal("text"), fallback: z26.string().max(256) }).strict(),
|
|
1759
|
+
z26.object({ ...fieldBase, type: z26.literal("longText"), fallback: z26.string().max(5e4) }).strict(),
|
|
2330
1760
|
z26.object({
|
|
2331
|
-
|
|
2332
|
-
|
|
2333
|
-
|
|
2334
|
-
checkedAt: z26.string().datetime({ offset: true }).nullable().optional()
|
|
1761
|
+
...fieldBase,
|
|
1762
|
+
type: z26.literal("link"),
|
|
1763
|
+
fallback: z26.object({ href: z26.string().min(1).max(2048), label: z26.string().max(256) }).strict()
|
|
2335
1764
|
}).strict(),
|
|
2336
1765
|
z26.object({
|
|
2337
|
-
|
|
2338
|
-
|
|
2339
|
-
|
|
2340
|
-
checkedAt: z26.string().datetime({ offset: true }).nullable()
|
|
2341
|
-
}).strict().refine((value) => value.status !== "ready" || value.checkedAt !== null)
|
|
2342
|
-
]);
|
|
2343
|
-
var checkSetupAssetTargetInputSchema = z26.object({
|
|
2344
|
-
siteId: z26.string().uuid(),
|
|
2345
|
-
runId: z26.string().uuid(),
|
|
2346
|
-
approvalId: z26.string().uuid(),
|
|
2347
|
-
intent: z26.enum(["start", "poll"])
|
|
2348
|
-
}).strict();
|
|
2349
|
-
|
|
2350
|
-
// ../shared/dist/setup-installation.js
|
|
2351
|
-
import { z as z27 } from "zod";
|
|
2352
|
-
var setupInstallationRequestSchema = z27.object({
|
|
2353
|
-
modules: siteSetupModulesSchema,
|
|
2354
|
-
ownerEditabilityNote: siteSetupOwnerEditabilityNoteSchema,
|
|
2355
|
-
provider: z27.object({
|
|
2356
|
-
projectId: z27.string().min(1).max(200),
|
|
2357
|
-
teamId: z27.string().min(1).max(200)
|
|
1766
|
+
...fieldBase,
|
|
1767
|
+
type: z26.literal("image"),
|
|
1768
|
+
fallback: z26.object({ src: z26.string().min(1).max(2048), alt: z26.string().max(300) }).strict()
|
|
2358
1769
|
}).strict()
|
|
2359
|
-
|
|
2360
|
-
|
|
2361
|
-
|
|
2362
|
-
|
|
2363
|
-
var
|
|
2364
|
-
|
|
2365
|
-
|
|
2366
|
-
|
|
2367
|
-
|
|
2368
|
-
|
|
2369
|
-
|
|
2370
|
-
|
|
2371
|
-
|
|
2372
|
-
|
|
2373
|
-
|
|
2374
|
-
|
|
2375
|
-
|
|
2376
|
-
|
|
2377
|
-
|
|
2378
|
-
|
|
2379
|
-
|
|
2380
|
-
|
|
2381
|
-
workspaceId: z28.string().uuid(),
|
|
2382
|
-
workspaceName: z28.string(),
|
|
2383
|
-
expiresAt: z28.string().datetime({ offset: true })
|
|
2384
|
-
}).strict();
|
|
2385
|
-
var setupClaimDenialSchema = z28.object({
|
|
2386
|
-
status: z28.enum([
|
|
2387
|
-
"invalid_claim_request",
|
|
2388
|
-
"invalid_installation",
|
|
2389
|
-
"already_claimed",
|
|
2390
|
-
"project_expired",
|
|
2391
|
-
"invalid_guest_session",
|
|
2392
|
-
"stale_setup_review",
|
|
2393
|
-
"verified_account_required",
|
|
2394
|
-
"workspace_access_denied",
|
|
2395
|
-
"workspace_entitlement_required",
|
|
2396
|
-
"site_limit_reached",
|
|
2397
|
-
"provisional_relationship_conflict",
|
|
2398
|
-
"rate_limited"
|
|
2399
|
-
])
|
|
2400
|
-
}).strict();
|
|
2401
|
-
|
|
2402
|
-
// ../cli/dist/analytics/static-scan.js
|
|
2403
|
-
import ts from "typescript";
|
|
2404
|
-
|
|
2405
|
-
// ../cli/dist/booking/manifest.js
|
|
2406
|
-
import { mkdir as mkdir2, readFile as readFile2, writeFile as writeFile2 } from "fs/promises";
|
|
2407
|
-
import { dirname as dirname2 } from "path";
|
|
2408
|
-
|
|
2409
|
-
// ../cli/dist/booking/static-scan.js
|
|
2410
|
-
import ts2 from "typescript";
|
|
2411
|
-
|
|
2412
|
-
// ../cli/dist/commands/analytics/check.js
|
|
2413
|
-
import { readFile as readFile3 } from "fs/promises";
|
|
2414
|
-
|
|
2415
|
-
// ../cli/dist/commands/analytics/init.js
|
|
2416
|
-
import { mkdir as mkdir3, writeFile as writeFile3 } from "fs/promises";
|
|
2417
|
-
import { dirname as dirname3, join } from "path";
|
|
2418
|
-
var analyticsRulesTemplate = `# Siteplane Analytics Rules
|
|
2419
|
-
|
|
2420
|
-
Analytics contract version: ${ANALYTICS_CONTRACT_VERSION}
|
|
2421
|
-
Analytics contract hash: ${ANALYTICS_CONTRACT_HASH}
|
|
2422
|
-
|
|
2423
|
-
- Do not change visible layout, copy, styling, animation or business logic while adding analytics.
|
|
2424
|
-
- Use stable data-siteplane-target-id values that do not depend on visible copy.
|
|
2425
|
-
- Use public site keys only through environment references.
|
|
2426
|
-
- Do not write secret analytics keys, setup tokens or project CLI tokens into source files.
|
|
2427
|
-
- 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.
|
|
2428
|
-
- 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.
|
|
2429
|
-
- 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.
|
|
2430
|
-
- Suppress editor-preview traffic from live analytics.
|
|
2431
|
-
- Run npx siteplane analytics check, npx siteplane analytics sync and npx siteplane analytics test after setup.
|
|
2432
|
-
`;
|
|
2433
|
-
var analyticsCursorRulesTemplate = `---
|
|
2434
|
-
description: Siteplane Analytics rules
|
|
2435
|
-
alwaysApply: true
|
|
2436
|
-
---
|
|
2437
|
-
|
|
2438
|
-
${analyticsRulesTemplate}`;
|
|
2439
|
-
|
|
2440
|
-
// ../cli/dist/commands/analytics/import.js
|
|
2441
|
-
import { createHash } from "crypto";
|
|
1770
|
+
]);
|
|
1771
|
+
var fieldSyncRequestSchema = z26.object({ fields: z26.array(fieldSyncFieldSchema).max(FIELD_SYNC_MAX_FIELDS) }).strict();
|
|
1772
|
+
|
|
1773
|
+
// ../shared/dist/signing-keys.js
|
|
1774
|
+
var pkcs8Ed25519Prefix = Uint8Array.from([
|
|
1775
|
+
48,
|
|
1776
|
+
46,
|
|
1777
|
+
2,
|
|
1778
|
+
1,
|
|
1779
|
+
0,
|
|
1780
|
+
48,
|
|
1781
|
+
5,
|
|
1782
|
+
6,
|
|
1783
|
+
3,
|
|
1784
|
+
43,
|
|
1785
|
+
101,
|
|
1786
|
+
112,
|
|
1787
|
+
4,
|
|
1788
|
+
34,
|
|
1789
|
+
4,
|
|
1790
|
+
32
|
|
1791
|
+
]);
|
|
2442
1792
|
|
|
2443
|
-
// ../
|
|
2444
|
-
|
|
2445
|
-
|
|
2446
|
-
|
|
2447
|
-
|
|
2448
|
-
};
|
|
2449
|
-
const bypassSecret = config.vercelAutomationBypassSecret?.trim();
|
|
2450
|
-
if (bypassSecret) {
|
|
2451
|
-
headers["x-vercel-protection-bypass"] = bypassSecret;
|
|
2452
|
-
}
|
|
2453
|
-
return headers;
|
|
1793
|
+
// ../shared/dist/preview-token.js
|
|
1794
|
+
var PREVIEW_TOKEN_MAX_SECONDS = 60 * 60;
|
|
1795
|
+
var header = encodeJson({ alg: "EdDSA", typ: "JWT" });
|
|
1796
|
+
function encodeJson(value) {
|
|
1797
|
+
return toBase64Url(new TextEncoder().encode(JSON.stringify(value)));
|
|
2454
1798
|
}
|
|
2455
|
-
|
|
2456
|
-
|
|
2457
|
-
|
|
2458
|
-
|
|
2459
|
-
|
|
2460
|
-
data: z29.object({
|
|
2461
|
-
rawPublicKey: z29.string().regex(/^pk_siteplane_[A-Za-z0-9_-]{16}_[A-Za-z0-9_-]{43}$/)
|
|
2462
|
-
})
|
|
2463
|
-
});
|
|
2464
|
-
var errorResponseSchema = z29.object({
|
|
2465
|
-
error: z29.object({
|
|
2466
|
-
code: z29.string().regex(/^[a-z][a-z0-9_.-]+$/u)
|
|
2467
|
-
})
|
|
2468
|
-
});
|
|
2469
|
-
async function analyticsPublicKeyCommand(input) {
|
|
2470
|
-
const fetcher = input.fetchImpl ?? fetch;
|
|
2471
|
-
const response = await fetcher(`${input.config.apiBaseUrl.replace(/\/$/u, "")}/api/cli/analytics/public-key`, {
|
|
2472
|
-
method: "POST",
|
|
2473
|
-
redirect: "error",
|
|
2474
|
-
signal: AbortSignal.timeout(2e4),
|
|
2475
|
-
headers: createAnalyticsCliRequestHeaders(input.config),
|
|
2476
|
-
body: JSON.stringify({ siteId: input.config.siteId })
|
|
2477
|
-
});
|
|
2478
|
-
const payload = await response.json().catch(() => null);
|
|
2479
|
-
const parsed = responseSchema.safeParse(payload);
|
|
2480
|
-
if (!response.ok || !parsed.success) {
|
|
2481
|
-
const error = errorResponseSchema.safeParse(payload);
|
|
2482
|
-
throw new Error(`${error.success ? error.data.error.code : "analytics_public_key.invalid_response"}: Unable to read the active Analytics public key.`);
|
|
2483
|
-
}
|
|
2484
|
-
return parsed.data.data.rawPublicKey;
|
|
1799
|
+
function toBase64Url(bytes) {
|
|
1800
|
+
let binary = "";
|
|
1801
|
+
for (const byte of bytes)
|
|
1802
|
+
binary += String.fromCharCode(byte);
|
|
1803
|
+
return btoa(binary).replace(/\+/gu, "-").replace(/\//gu, "_").replace(/=+$/u, "");
|
|
2485
1804
|
}
|
|
2486
1805
|
|
|
2487
|
-
// ../
|
|
2488
|
-
|
|
2489
|
-
var
|
|
2490
|
-
ok: z30.literal(true),
|
|
2491
|
-
data: z30.object({
|
|
2492
|
-
rawPublicKey: z30.string().regex(/^pk_siteplane_[A-Za-z0-9_-]{16}_[A-Za-z0-9_-]{43}$/u),
|
|
2493
|
-
generation: z30.number().int().positive(),
|
|
2494
|
-
status: z30.enum([
|
|
2495
|
-
"setup_started",
|
|
2496
|
-
"test_mode",
|
|
2497
|
-
"active",
|
|
2498
|
-
"paused",
|
|
2499
|
-
"error",
|
|
2500
|
-
"deleting"
|
|
2501
|
-
])
|
|
2502
|
-
}).strict()
|
|
2503
|
-
}).strict();
|
|
2504
|
-
var errorSchema = z30.object({
|
|
2505
|
-
error: z30.object({ code: z30.string().regex(/^[a-z][a-z0-9_.-]+$/u) })
|
|
2506
|
-
});
|
|
1806
|
+
// ../shared/dist/webhook-signature.js
|
|
1807
|
+
var WEBHOOK_TOLERANCE_SECONDS = 5 * 60;
|
|
1808
|
+
var encoder = new TextEncoder();
|
|
2507
1809
|
|
|
2508
|
-
// ../cli/dist/
|
|
2509
|
-
import
|
|
1810
|
+
// ../cli/dist/booking/static-scan.js
|
|
1811
|
+
import ts from "typescript";
|
|
2510
1812
|
|
|
2511
1813
|
// ../cli/dist/commands/booking/check.js
|
|
2512
|
-
import { dirname as
|
|
2513
|
-
import { access, readFile as
|
|
1814
|
+
import { dirname as dirname2, join } from "path";
|
|
1815
|
+
import { access, readFile as readFile2 } from "fs/promises";
|
|
2514
1816
|
|
|
2515
1817
|
// ../cli/dist/commands/booking/init.js
|
|
2516
|
-
import { mkdir as
|
|
2517
|
-
import { dirname as
|
|
1818
|
+
import { mkdir as mkdir2, writeFile as writeFile2 } from "fs/promises";
|
|
1819
|
+
import { dirname as dirname3, join as join2 } from "path";
|
|
2518
1820
|
var bookingRulesTemplate = `# Siteplane Booking Rules
|
|
2519
1821
|
|
|
2520
1822
|
- Do not change layout, copy, styling, animation or business logic while adding Booking.
|
|
@@ -2525,6 +1827,7 @@ var bookingRulesTemplate = `# Siteplane Booking Rules
|
|
|
2525
1827
|
- Preserve customer CSP and middleware; explain required Siteplane/Stripe permissions and exclude /booking from customer middleware.
|
|
2526
1828
|
- Do not write setup tokens, project CLI tokens or private keys into source files.
|
|
2527
1829
|
- Run npx siteplane booking check, npx siteplane booking sync and npx siteplane booking test after setup.
|
|
1830
|
+
- The first booking sync prints a link and code for the Siteplane approval; give both to the user and wait until they click Connect. The connection stays outside the project.
|
|
2528
1831
|
- booking test stays in test_mode; live booking only starts after explicit dashboard activation.
|
|
2529
1832
|
`;
|
|
2530
1833
|
var bookingCursorRulesTemplate = `---
|
|
@@ -2534,602 +1837,9 @@ alwaysApply: true
|
|
|
2534
1837
|
|
|
2535
1838
|
${bookingRulesTemplate}`;
|
|
2536
1839
|
|
|
2537
|
-
// ../cli/dist/config/project-config.js
|
|
2538
|
-
import { access as access2, chmod, open, readFile as readFile5, rename, rm } from "fs/promises";
|
|
2539
|
-
import { randomUUID as randomUUID2 } from "crypto";
|
|
2540
|
-
import { join as join4 } from "path";
|
|
2541
|
-
import { z as z31 } from "zod";
|
|
2542
|
-
var siteplaneProjectConfigSchema = z31.object({
|
|
2543
|
-
version: z31.literal(2),
|
|
2544
|
-
apiBaseUrl: z31.string().url(),
|
|
2545
|
-
siteId: z31.string().uuid(),
|
|
2546
|
-
publicSiteKeyId: z31.string().uuid(),
|
|
2547
|
-
publicSiteKey: z31.string().trim().min(1),
|
|
2548
|
-
runId: z31.string().uuid(),
|
|
2549
|
-
appDirectory: z31.string().min(1),
|
|
2550
|
-
taskContractVersion: z31.literal("siteplane.setup-task.v2"),
|
|
2551
|
-
adminProtocolVersion: z31.literal(2),
|
|
2552
|
-
packages: siteSetupPackagesSchema,
|
|
2553
|
-
fieldContractHash: z31.string().regex(/^sha256:[0-9a-f]{64}$/iu).optional()
|
|
2554
|
-
}).strict();
|
|
2555
|
-
async function readProjectConfig(projectDir) {
|
|
2556
|
-
return siteplaneProjectConfigSchema.parse(JSON.parse(await readFile5(join4(projectDir, "siteplane.config.json"), "utf8")));
|
|
2557
|
-
}
|
|
2558
|
-
|
|
2559
|
-
// ../cli/dist/config/credentials.js
|
|
2560
|
-
import { execFile } from "child_process";
|
|
2561
|
-
import { randomUUID as randomUUID3 } from "crypto";
|
|
2562
|
-
import { chmod as chmod2, lstat, mkdir as mkdir5, open as open2, readFile as readFile6, rename as rename2, rm as rm2 } from "fs/promises";
|
|
2563
|
-
import { dirname as dirname6, join as join5, relative } from "path";
|
|
2564
|
-
import { promisify } from "util";
|
|
2565
|
-
import { z as z32 } from "zod";
|
|
2566
|
-
var localSetupInstallationSchema = z32.object({
|
|
2567
|
-
key: z32.string().regex(/^[A-Za-z0-9_-]{43}$/u),
|
|
2568
|
-
idempotencyKey: z32.string().uuid(),
|
|
2569
|
-
apiBaseUrl: z32.string().url(),
|
|
2570
|
-
request: setupInstallationRequestSchema,
|
|
2571
|
-
bootstrapAcknowledged: z32.boolean()
|
|
2572
|
-
}).strict();
|
|
2573
|
-
var siteplaneCredentialsSchema = z32.object({
|
|
2574
|
-
accessToken: z32.string().trim().min(1),
|
|
2575
|
-
siteRevalidationSecret: z32.string().trim().min(1),
|
|
2576
|
-
installation: localSetupInstallationSchema.optional(),
|
|
2577
|
-
claimReceipt: setupClaimReceiptSchema.optional(),
|
|
2578
|
-
adminSession: z32.object({
|
|
2579
|
-
secret: z32.string().regex(/^[A-Za-z0-9_-]{43}$/u),
|
|
2580
|
-
generation: z32.string().uuid()
|
|
2581
|
-
}).strict().optional()
|
|
2582
|
-
}).strict();
|
|
2583
|
-
var localSetupCredentialsSchema = z32.union([
|
|
2584
|
-
siteplaneCredentialsSchema,
|
|
2585
|
-
z32.object({ installation: localSetupInstallationSchema }).strict()
|
|
2586
|
-
]);
|
|
2587
|
-
async function assertLocalCredentialsPathSafe(projectDir, options = {}) {
|
|
2588
|
-
const path = join5(projectDir, ".siteplane/credentials.json");
|
|
2589
|
-
await assertCredentialFilesystemSafe(projectDir);
|
|
2590
|
-
const isTrackedFile = options.isTrackedFile ?? ((targetPath) => gitPathMatches(projectDir, targetPath, "ls-files"));
|
|
2591
|
-
const isIgnoredFile = options.isIgnoredFile ?? ((targetPath) => gitPathMatches(projectDir, targetPath, "check-ignore"));
|
|
2592
|
-
if (await isTrackedFile(path)) {
|
|
2593
|
-
throw new Error("Refusing to write Siteplane credentials into a tracked file.");
|
|
2594
|
-
}
|
|
2595
|
-
if (!await isIgnoredFile(path)) {
|
|
2596
|
-
throw new Error("Add .siteplane/credentials.json to .gitignore before running Siteplane init.");
|
|
2597
|
-
}
|
|
2598
|
-
return path;
|
|
2599
|
-
}
|
|
2600
|
-
async function assertCredentialFilesystemSafe(projectDir) {
|
|
2601
|
-
for (const [path, directory, mode] of [
|
|
2602
|
-
[projectDir, true, null],
|
|
2603
|
-
[join5(projectDir, ".siteplane"), true, 448],
|
|
2604
|
-
[join5(projectDir, ".siteplane/credentials.json"), false, 384]
|
|
2605
|
-
]) {
|
|
2606
|
-
const stat = await lstat(path).catch((error) => {
|
|
2607
|
-
if (error.code === "ENOENT")
|
|
2608
|
-
return null;
|
|
2609
|
-
throw error;
|
|
2610
|
-
});
|
|
2611
|
-
if (!stat)
|
|
2612
|
-
continue;
|
|
2613
|
-
if (stat.isSymbolicLink() || (directory ? !stat.isDirectory() : !stat.isFile())) {
|
|
2614
|
-
throw new Error("Siteplane credential paths must not contain symlinks or unexpected file types.");
|
|
2615
|
-
}
|
|
2616
|
-
if (mode !== null && (stat.mode & 511) !== mode) {
|
|
2617
|
-
throw new Error(`Siteplane credential ${directory ? "directory" : "file"} permissions must be ${mode.toString(8)} before setup.`);
|
|
2618
|
-
}
|
|
2619
|
-
}
|
|
2620
|
-
}
|
|
2621
|
-
async function readLocalCredentials(projectDir) {
|
|
2622
|
-
const credentials = await readLocalSetupCredentials(projectDir);
|
|
2623
|
-
if (!("accessToken" in credentials)) {
|
|
2624
|
-
throw new Error("setup_exchange_pending: Run siteplane setup start to finish the stored installation exchange.");
|
|
2625
|
-
}
|
|
2626
|
-
return credentials;
|
|
2627
|
-
}
|
|
2628
|
-
async function readLocalSetupCredentials(projectDir) {
|
|
2629
|
-
await assertCredentialFilesystemSafe(projectDir);
|
|
2630
|
-
return localSetupCredentialsSchema.parse(JSON.parse(await readFile6(join5(projectDir, ".siteplane/credentials.json"), "utf8")));
|
|
2631
|
-
}
|
|
2632
|
-
var execFileAsync = promisify(execFile);
|
|
2633
|
-
async function gitPathMatches(projectDir, path, command) {
|
|
2634
|
-
const args = command === "check-ignore" ? ["check-ignore", "--quiet", relative(projectDir, path)] : ["ls-files", "--error-unmatch", relative(projectDir, path)];
|
|
2635
|
-
try {
|
|
2636
|
-
await execFileAsync("git", args, { cwd: projectDir });
|
|
2637
|
-
return true;
|
|
2638
|
-
} catch {
|
|
2639
|
-
return false;
|
|
2640
|
-
}
|
|
2641
|
-
}
|
|
2642
|
-
|
|
2643
|
-
// ../cli/dist/commands/init.js
|
|
2644
|
-
import { access as access4 } from "fs/promises";
|
|
2645
|
-
import { join as join8, relative as relative3 } from "path";
|
|
2646
|
-
import { z as z35 } from "zod";
|
|
2647
|
-
|
|
2648
|
-
// ../cli/dist/commands/setup-preflight.js
|
|
2649
|
-
import { createHash as createHash2 } from "crypto";
|
|
2650
|
-
import semver from "semver";
|
|
2651
|
-
import { minimatch } from "minimatch";
|
|
2652
|
-
import { parse as parseYaml } from "yaml";
|
|
2653
|
-
|
|
2654
|
-
// ../cli/dist/config/installed-package.js
|
|
2655
|
-
import { createRequire } from "module";
|
|
2656
|
-
import { readFile as readFile7 } from "fs/promises";
|
|
2657
|
-
import { join as join6 } from "path";
|
|
2658
|
-
import { z as z33 } from "zod";
|
|
2659
|
-
var packageSchema = z33.object({
|
|
2660
|
-
name: z33.string().optional(),
|
|
2661
|
-
version: z33.string(),
|
|
2662
|
-
peerDependencies: z33.record(z33.string(), z33.string()).optional()
|
|
2663
|
-
});
|
|
2664
|
-
async function readInstalledPackage(projectDir, name2) {
|
|
2665
|
-
const require2 = createRequire(join6(projectDir, "package.json"));
|
|
2666
|
-
for (const directory of require2.resolve.paths(name2) ?? []) {
|
|
2667
|
-
try {
|
|
2668
|
-
return packageSchema.parse(JSON.parse(await readFile7(join6(directory, name2, "package.json"), "utf8")));
|
|
2669
|
-
} catch (error) {
|
|
2670
|
-
if (error.code !== "ENOENT")
|
|
2671
|
-
throw error;
|
|
2672
|
-
}
|
|
2673
|
-
}
|
|
2674
|
-
throw new Error(`Install ${name2} with the canonical package manager before setup.`);
|
|
2675
|
-
}
|
|
2676
|
-
|
|
2677
|
-
// ../cli/dist/commands/setup-preflight.js
|
|
2678
|
-
import { access as access3, readFile as readFile8, realpath, readdir, readlink } from "fs/promises";
|
|
2679
|
-
import { dirname as dirname7, join as join7, relative as relative2, resolve, sep } from "path";
|
|
2680
|
-
import { z as z34 } from "zod";
|
|
2681
|
-
|
|
2682
|
-
// ../cli/dist/commands/setup-process.js
|
|
2683
|
-
import { spawn } from "child_process";
|
|
2684
|
-
var SetupFailure = class extends Error {
|
|
2685
|
-
code;
|
|
2686
|
-
constructor(code, message) {
|
|
2687
|
-
super(message);
|
|
2688
|
-
this.code = code;
|
|
2689
|
-
}
|
|
2690
|
-
};
|
|
2691
|
-
async function setupProcess(binary, args, options) {
|
|
2692
|
-
return new Promise((resolve5, reject) => {
|
|
2693
|
-
const child = spawn(binary, args, {
|
|
2694
|
-
cwd: options.cwd,
|
|
2695
|
-
env: process.env,
|
|
2696
|
-
stdio: ["pipe", "pipe", "pipe"]
|
|
2697
|
-
});
|
|
2698
|
-
const chunks = [];
|
|
2699
|
-
const errors = [];
|
|
2700
|
-
let errorBytes = 0;
|
|
2701
|
-
let bytes = 0;
|
|
2702
|
-
let exceeded = false;
|
|
2703
|
-
const timer = setTimeout(() => {
|
|
2704
|
-
exceeded = true;
|
|
2705
|
-
child.kill("SIGKILL");
|
|
2706
|
-
}, options.timeoutMs ?? 12e4);
|
|
2707
|
-
const capture = (chunk) => {
|
|
2708
|
-
bytes += chunk.length;
|
|
2709
|
-
if (bytes > 4 * 1024 * 1024) {
|
|
2710
|
-
exceeded = true;
|
|
2711
|
-
child.kill("SIGKILL");
|
|
2712
|
-
} else
|
|
2713
|
-
chunks.push(chunk);
|
|
2714
|
-
};
|
|
2715
|
-
child.stdout.on("data", capture);
|
|
2716
|
-
child.stderr.on("data", (chunk) => {
|
|
2717
|
-
errorBytes += chunk.length;
|
|
2718
|
-
if (errorBytes <= 4 * 1024 * 1024)
|
|
2719
|
-
errors.push(chunk);
|
|
2720
|
-
else {
|
|
2721
|
-
exceeded = true;
|
|
2722
|
-
child.kill("SIGKILL");
|
|
2723
|
-
}
|
|
2724
|
-
});
|
|
2725
|
-
child.on("error", () => {
|
|
2726
|
-
clearTimeout(timer);
|
|
2727
|
-
reject(new SetupFailure("local_tool_unavailable", `${binary} could not be started. Check the local installation and access.`));
|
|
2728
|
-
});
|
|
2729
|
-
child.on("close", (code) => {
|
|
2730
|
-
clearTimeout(timer);
|
|
2731
|
-
if (exceeded)
|
|
2732
|
-
reject(new SetupFailure("provider_timeout", "The operation exceeded its time or response limit; inspect the existing operation before retrying."));
|
|
2733
|
-
else if (code !== 0) {
|
|
2734
|
-
const diagnostic = Buffer.concat([...chunks, ...errors]).toString("utf8");
|
|
2735
|
-
if (/\b(?:401|403|unauthorized|forbidden|not authenticated|not authorized|login required|E401|E403)\b/iu.test(diagnostic))
|
|
2736
|
-
reject(new SetupFailure("provider_access_denied", `${binary} denied access. Restore the existing local login and project/package permissions before retrying.`));
|
|
2737
|
-
else if (/\b(?:ECONNRESET|ETIMEDOUT|ENOTFOUND|EAI_AGAIN|ECONNREFUSED|429|502|503|504)\b/iu.test(diagnostic))
|
|
2738
|
-
reject(new SetupFailure("provider_transport_failed", `${binary} could not reach its provider. Inspect the existing operation before retrying.`));
|
|
2739
|
-
else
|
|
2740
|
-
reject(new SetupFailure("local_command_failed", `${binary} failed. Check its local login, permissions and project configuration.`));
|
|
2741
|
-
} else
|
|
2742
|
-
resolve5(Buffer.concat(options.includeStderr ? [...chunks, ...errors] : chunks).toString("utf8"));
|
|
2743
|
-
});
|
|
2744
|
-
child.stdin.on("error", () => {
|
|
2745
|
-
});
|
|
2746
|
-
child.stdin.end(options.input);
|
|
2747
|
-
});
|
|
2748
|
-
}
|
|
2749
|
-
async function setupVercelApi(cwd, endpoint, body, method, options) {
|
|
2750
|
-
const args = ["api", endpoint, "--raw"];
|
|
2751
|
-
if (body !== void 0)
|
|
2752
|
-
args.push("--method", method ?? "POST", "--input", "-");
|
|
2753
|
-
else if (method)
|
|
2754
|
-
args.push("--method", method);
|
|
2755
|
-
let output = "";
|
|
2756
|
-
for (let attempt = 0; attempt < 3; attempt++) {
|
|
2757
|
-
const remaining = (options?.deadline ?? Date.now() + 3e4) - Date.now();
|
|
2758
|
-
if (remaining <= 0)
|
|
2759
|
-
throw new SetupFailure("provider_deadline_exceeded", "The provider deadline expired; inspect the recorded operation before continuing.");
|
|
2760
|
-
try {
|
|
2761
|
-
output = await setupProcess("vercel", args, {
|
|
2762
|
-
cwd,
|
|
2763
|
-
timeoutMs: Math.min(3e4, remaining),
|
|
2764
|
-
...body === void 0 ? {} : { input: JSON.stringify(body) }
|
|
2765
|
-
});
|
|
2766
|
-
break;
|
|
2767
|
-
} catch (error) {
|
|
2768
|
-
if (!(error instanceof SetupFailure) || error.code !== "provider_transport_failed" || attempt === 2)
|
|
2769
|
-
throw error;
|
|
2770
|
-
await new Promise((resolve5) => setTimeout(resolve5, Math.min(1e3 * 2 ** attempt, Math.max(0, (options?.deadline ?? Date.now() + 2e3) - Date.now()))));
|
|
2771
|
-
}
|
|
2772
|
-
}
|
|
2773
|
-
try {
|
|
2774
|
-
return JSON.parse(output);
|
|
2775
|
-
} catch {
|
|
2776
|
-
throw new SetupFailure("invalid_provider_response", "Vercel did not return valid JSON for the bound project.");
|
|
2777
|
-
}
|
|
2778
|
-
}
|
|
2779
|
-
|
|
2780
|
-
// ../cli/dist/commands/setup-preflight.js
|
|
2781
|
-
var manifestSchema = z34.object({
|
|
2782
|
-
packageManager: z34.string().optional(),
|
|
2783
|
-
engines: z34.object({ node: z34.string().optional() }).optional(),
|
|
2784
|
-
dependencies: z34.record(z34.string(), z34.string()).optional(),
|
|
2785
|
-
devDependencies: z34.record(z34.string(), z34.string()).optional(),
|
|
2786
|
-
scripts: z34.record(z34.string(), z34.string()).optional(),
|
|
2787
|
-
workspaces: z34.unknown().optional()
|
|
2788
|
-
});
|
|
2789
|
-
var vercelProjectSchema = z34.object({
|
|
2790
|
-
id: z34.string(),
|
|
2791
|
-
accountId: z34.string(),
|
|
2792
|
-
name: z34.string(),
|
|
2793
|
-
nodeVersion: z34.string().nullable().optional(),
|
|
2794
|
-
rootDirectory: z34.string().nullable().optional(),
|
|
2795
|
-
framework: z34.string().nullable().optional(),
|
|
2796
|
-
installCommand: z34.string().nullable().optional(),
|
|
2797
|
-
buildCommand: z34.string().nullable().optional(),
|
|
2798
|
-
link: z34.object({
|
|
2799
|
-
type: z34.string(),
|
|
2800
|
-
repo: z34.string().optional(),
|
|
2801
|
-
repoId: z34.union([z34.string(), z34.number()]).optional(),
|
|
2802
|
-
org: z34.string().optional(),
|
|
2803
|
-
productionBranch: z34.string().optional()
|
|
2804
|
-
}).nullable().optional()
|
|
2805
|
-
});
|
|
2806
|
-
var exists = async (path) => access3(path).then(() => true, () => false);
|
|
2807
|
-
var fail = (code, message) => {
|
|
2808
|
-
throw new SetupFailure(code, message);
|
|
2809
|
-
};
|
|
2810
|
-
var stable = (version2, major) => new RegExp(`^${major}\\.\\d+\\.\\d+$`, "u").test(version2);
|
|
2811
|
-
async function inspectSetupLocalProject(projectDir) {
|
|
2812
|
-
const projectDirectory = await realpath(resolve(projectDir));
|
|
2813
|
-
const manifest = manifestSchema.parse(JSON.parse(await readFile8(join7(projectDirectory, "package.json"), "utf8")));
|
|
2814
|
-
const apps = (await Promise.all(["app", "src/app"].map(async (path) => await exists(join7(projectDirectory, path)) ? path : null))).filter((path) => path !== null);
|
|
2815
|
-
if (apps.length !== 1)
|
|
2816
|
-
fail("ambiguous_app_directory", "Select one Next.js App Router application with exactly one app/ or src/app/ directory.");
|
|
2817
|
-
const repositoryRoot = (await setupProcess("git", ["rev-parse", "--show-toplevel"], {
|
|
2818
|
-
cwd: projectDirectory
|
|
2819
|
-
})).trim();
|
|
2820
|
-
const tracked = await setupProcess("git", ["ls-files", "--stage", "-z"], {
|
|
2821
|
-
cwd: repositoryRoot
|
|
2822
|
-
});
|
|
2823
|
-
for (const entry of tracked.split("\0").filter(Boolean)) {
|
|
2824
|
-
if (entry.startsWith("160000 "))
|
|
2825
|
-
fail("git_submodule_conflict", "The repository contains Git submodules. Resolve the explicit deployment source boundary before setup; the CLI will not copy external repositories.");
|
|
2826
|
-
if (!entry.startsWith("120000 "))
|
|
2827
|
-
continue;
|
|
2828
|
-
const path = join7(repositoryRoot, entry.slice(entry.indexOf(" ") + 1));
|
|
2829
|
-
const target = resolve(dirname7(path), await readlink(path));
|
|
2830
|
-
const bound = relative2(repositoryRoot, target);
|
|
2831
|
-
if (bound.startsWith("..") || bound.startsWith(sep))
|
|
2832
|
-
fail("external_symlink_conflict", "A tracked symbolic link points outside this repository. Resolve that source boundary before setup; local external files cannot enter a deployment.");
|
|
2833
|
-
}
|
|
2834
|
-
let lockfileRoot = projectDirectory;
|
|
2835
|
-
const lockNames = [
|
|
2836
|
-
"package-lock.json",
|
|
2837
|
-
"npm-shrinkwrap.json",
|
|
2838
|
-
"pnpm-lock.yaml",
|
|
2839
|
-
"yarn.lock",
|
|
2840
|
-
"bun.lock",
|
|
2841
|
-
"bun.lockb"
|
|
2842
|
-
];
|
|
2843
|
-
let locks = [];
|
|
2844
|
-
for (; ; ) {
|
|
2845
|
-
locks = (await Promise.all(lockNames.map(async (name3) => await exists(join7(lockfileRoot, name3)) ? name3 : null))).filter((name3) => name3 !== null);
|
|
2846
|
-
if (locks.length || lockfileRoot === repositoryRoot || dirname7(lockfileRoot) === lockfileRoot)
|
|
2847
|
-
break;
|
|
2848
|
-
lockfileRoot = dirname7(lockfileRoot);
|
|
2849
|
-
}
|
|
2850
|
-
if (locks.length > 1)
|
|
2851
|
-
fail("conflicting_lockfiles", "Resolve conflicting package-manager lockfiles before setup; Siteplane does not replace them.");
|
|
2852
|
-
if (!locks.length)
|
|
2853
|
-
fail("lockfile_missing", "Install the existing application with its chosen package manager to create one canonical lockfile.");
|
|
2854
|
-
const lockName = locks[0];
|
|
2855
|
-
if (!["package-lock.json", "pnpm-lock.yaml"].includes(lockName))
|
|
2856
|
-
fail("unsupported_package_manager", "This setup supports npm 10 or pnpm 9/10 with their canonical lockfile.");
|
|
2857
|
-
const rootManifest = manifestSchema.parse(JSON.parse(await readFile8(join7(lockfileRoot, "package.json"), "utf8")));
|
|
2858
|
-
if (lockfileRoot !== projectDirectory) {
|
|
2859
|
-
const workspaceFile = join7(lockfileRoot, "pnpm-workspace.yaml");
|
|
2860
|
-
const workspace = lockName === "pnpm-lock.yaml" && await exists(workspaceFile) ? z34.object({ packages: z34.array(z34.string()) }).parse(parseYaml(await readFile8(workspaceFile, "utf8"))).packages : z34.union([
|
|
2861
|
-
z34.array(z34.string()),
|
|
2862
|
-
z34.object({ packages: z34.array(z34.string()) }).transform((value) => value.packages)
|
|
2863
|
-
]).parse(rootManifest.workspaces);
|
|
2864
|
-
const selected = relative2(lockfileRoot, projectDirectory).split(sep).join("/");
|
|
2865
|
-
if (!workspace.some((pattern) => !pattern.startsWith("!") && minimatch(selected, pattern)) || workspace.some((pattern) => pattern.startsWith("!") && minimatch(selected, pattern.slice(1))))
|
|
2866
|
-
fail("unbound_workspace_app", "The selected application is excluded from the canonical lockfile's workspace packages. Select its actual application root.");
|
|
2867
|
-
}
|
|
2868
|
-
for (let ancestor = dirname7(lockfileRoot); ancestor.startsWith(repositoryRoot + sep) || ancestor === repositoryRoot; ancestor = dirname7(ancestor)) {
|
|
2869
|
-
const ancestorLocks = await Promise.all(lockNames.map((name3) => exists(join7(ancestor, name3))));
|
|
2870
|
-
if (ancestorLocks.some(Boolean))
|
|
2871
|
-
fail("ambiguous_lockfile_root", "Both the selected package and its repository ancestors contain lockfiles. Select one canonical workspace resolution before setup.");
|
|
2872
|
-
if (ancestor === repositoryRoot)
|
|
2873
|
-
break;
|
|
2874
|
-
}
|
|
2875
|
-
const lockText = await readFile8(join7(lockfileRoot, lockName), "utf8");
|
|
2876
|
-
const npmLock = lockName === "package-lock.json" ? z34.object({
|
|
2877
|
-
lockfileVersion: z34.number(),
|
|
2878
|
-
packages: z34.record(z34.string(), z34.object({
|
|
2879
|
-
version: z34.string().optional(),
|
|
2880
|
-
peerDependencies: z34.record(z34.string(), z34.string()).optional()
|
|
2881
|
-
})).optional()
|
|
2882
|
-
}).parse(JSON.parse(lockText)) : null;
|
|
2883
|
-
async function version2(name3) {
|
|
2884
|
-
try {
|
|
2885
|
-
return (await readInstalledPackage(projectDirectory, name3)).version;
|
|
2886
|
-
} catch {
|
|
2887
|
-
const resolved = npmLock?.packages?.[`node_modules/${name3}`]?.version;
|
|
2888
|
-
if (resolved)
|
|
2889
|
-
return resolved;
|
|
2890
|
-
return fail("dependencies_not_installed", `Install the existing ${name3} dependency using the canonical lockfile before setup.`);
|
|
2891
|
-
}
|
|
2892
|
-
}
|
|
2893
|
-
const [nextVersion, reactVersion, reactDomVersion] = await Promise.all([
|
|
2894
|
-
version2("next"),
|
|
2895
|
-
version2("react"),
|
|
2896
|
-
version2("react-dom")
|
|
2897
|
-
]);
|
|
2898
|
-
if (!stable(nextVersion, 16))
|
|
2899
|
-
fail("unsupported_next_version", "Setup supports stable Next.js 16 App Router projects. Framework migration requires a separate owner decision.");
|
|
2900
|
-
if (!stable(reactVersion, 19) || reactDomVersion !== reactVersion)
|
|
2901
|
-
fail("react_version_conflict", "Use the same stable React 19/react-dom version compatible with the installed Next.js peers.");
|
|
2902
|
-
if (!stable(process.versions.node, 22))
|
|
2903
|
-
fail("unsupported_node_version", "Run setup under Node.js 22; this does not change your framework or package-manager versions.");
|
|
2904
|
-
const nextMetadata = await readInstalledPackage(projectDirectory, "next").catch(() => npmLock?.packages?.["node_modules/next"] ?? null);
|
|
2905
|
-
const peers = nextMetadata?.peerDependencies;
|
|
2906
|
-
if (!peers?.react || !peers["react-dom"])
|
|
2907
|
-
fail("next_peer_metadata_missing", "Install the locked Next.js dependency before setup so its actual React peer requirements can be checked.");
|
|
2908
|
-
if (!semver.satisfies(reactVersion, peers.react) || !semver.satisfies(reactDomVersion, peers["react-dom"]))
|
|
2909
|
-
fail("react_peer_conflict", "The installed React pair does not satisfy the installed Next.js peer requirements. Choose a compatible pair explicitly.");
|
|
2910
|
-
if (manifest.engines?.node && !semver.satisfies(process.versions.node, manifest.engines.node))
|
|
2911
|
-
fail("node_engine_conflict", "The selected application's Node engine declaration excludes the active supported Node.js 22 runtime.");
|
|
2912
|
-
const name2 = lockName === "package-lock.json" ? "npm" : "pnpm";
|
|
2913
|
-
const declared = rootManifest.packageManager ?? manifest.packageManager ?? null;
|
|
2914
|
-
if (rootManifest.packageManager && manifest.packageManager && rootManifest.packageManager !== manifest.packageManager)
|
|
2915
|
-
fail("package_manager_conflict", "Application and workspace packageManager declarations disagree.");
|
|
2916
|
-
if (declared && !new RegExp(`^${name2}@\\d+\\.\\d+\\.\\d+$`, "u").test(declared))
|
|
2917
|
-
fail("package_manager_conflict", "Declare an exact supported npm/pnpm packageManager version matching the canonical lockfile.");
|
|
2918
|
-
const localVersion = (await setupProcess(declared ? "npx" : name2, declared ? ["--yes", "--package", declared, name2, "--version"] : ["--version"], { cwd: lockfileRoot })).trim();
|
|
2919
|
-
if (!(name2 === "npm" ? stable(localVersion, 10) : stable(localVersion, 9) || stable(localVersion, 10)))
|
|
2920
|
-
fail("unsupported_package_manager_version", "Use npm 10 or pnpm 9/10; other versions are outside the initial setup support range.");
|
|
2921
|
-
if (declared && declared !== `${name2}@${localVersion}`)
|
|
2922
|
-
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.");
|
|
2923
|
-
const format = npmLock ? String(npmLock.lockfileVersion) : /^lockfileVersion:\s*['"]?([\d.]+)/mu.exec(lockText)?.[1];
|
|
2924
|
-
if (name2 === "npm" && format !== "3" || name2 === "pnpm" && format !== "9.0" && format !== "9")
|
|
2925
|
-
fail("lockfile_format_conflict", "The canonical lockfile format does not match npm 10 or pnpm 9/10.");
|
|
2926
|
-
const sourceConflicts = [];
|
|
2927
|
-
for (const file of ["next.config.js", "next.config.mjs", "next.config.ts"]) {
|
|
2928
|
-
if (!await exists(join7(projectDirectory, file)))
|
|
2929
|
-
continue;
|
|
2930
|
-
const source = await readFile8(join7(projectDirectory, file), "utf8");
|
|
2931
|
-
if (/output\s*:\s*['"]export['"]/u.test(source))
|
|
2932
|
-
sourceConflicts.push("static_export");
|
|
2933
|
-
if (/\bbasePath\s*:/u.test(source))
|
|
2934
|
-
sourceConflicts.push("base_path");
|
|
2935
|
-
if (/\bloaderFile\s*:|\bloader\s*:\s*['"](?:custom|imgix|cloudinary|akamai)['"]/u.test(source))
|
|
2936
|
-
sourceConflicts.push(`inspect_image_loader:${file}`);
|
|
2937
|
-
}
|
|
2938
|
-
if (sourceConflicts.some((conflict) => conflict === "static_export" || conflict === "base_path"))
|
|
2939
|
-
fail("unsupported_server_configuration", "Resolve static export/basePath configuration explicitly; Siteplane requires its server-side admin and revalidation handlers.");
|
|
2940
|
-
for (const name3 of [
|
|
2941
|
-
"middleware.ts",
|
|
2942
|
-
"middleware.js",
|
|
2943
|
-
"proxy.ts",
|
|
2944
|
-
"proxy.js",
|
|
2945
|
-
"src/middleware.ts",
|
|
2946
|
-
"src/middleware.js",
|
|
2947
|
-
"src/proxy.ts",
|
|
2948
|
-
"src/proxy.js"
|
|
2949
|
-
]) {
|
|
2950
|
-
if (await exists(join7(projectDirectory, name3))) {
|
|
2951
|
-
sourceConflicts.push(`inspect_routing:${name3}`);
|
|
2952
|
-
if (await readlink(join7(projectDirectory, name3)).catch(() => null))
|
|
2953
|
-
continue;
|
|
2954
|
-
const policySource = await readFile8(join7(projectDirectory, name3), "utf8");
|
|
2955
|
-
if (/Content-Security-Policy|img-src|default-src/iu.test(policySource))
|
|
2956
|
-
sourceConflicts.push(`inspect_image_csp:${name3}`);
|
|
2957
|
-
}
|
|
2958
|
-
}
|
|
2959
|
-
async function inspectSource(directory) {
|
|
2960
|
-
for (const entry of await readdir(directory, { withFileTypes: true })) {
|
|
2961
|
-
if (entry.isSymbolicLink() || ["node_modules", ".git", ".next", ".siteplane", ".vercel"].includes(entry.name))
|
|
2962
|
-
continue;
|
|
2963
|
-
const path = join7(directory, entry.name);
|
|
2964
|
-
if (entry.isDirectory()) {
|
|
2965
|
-
await inspectSource(path);
|
|
2966
|
-
continue;
|
|
2967
|
-
}
|
|
2968
|
-
if (!/\.[cm]?[jt]sx?$/u.test(entry.name))
|
|
2969
|
-
continue;
|
|
2970
|
-
const source = await readFile8(path, "utf8");
|
|
2971
|
-
if (/Content-Security-Policy|img-src|default-src/iu.test(source))
|
|
2972
|
-
sourceConflicts.push(`inspect_image_csp:${relative2(projectDirectory, path)}`);
|
|
2973
|
-
if (/from\s*["']next\/image["']/u.test(source))
|
|
2974
|
-
sourceConflicts.push(`inspect_image_policy:${relative2(projectDirectory, path)}`);
|
|
2975
|
-
if (/\b(?:Cookiebot|OneTrust|cookieyes|consentManager|cookieConsent)\b/iu.test(source))
|
|
2976
|
-
sourceConflicts.push(`inspect_existing_consent:${relative2(projectDirectory, path)}`);
|
|
2977
|
-
if (/from\s*["']next\/image["']/u.test(source) && semver.lt(nextVersion, "16.3.3"))
|
|
2978
|
-
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.`);
|
|
2979
|
-
if (/["']use server["']/u.test(source) && semver.lt(nextVersion, "16.2.11"))
|
|
2980
|
-
fail("next_security_advisory", `Next.js ${nextVersion} contains Server Actions affected by the July 2026 advisory. Review https://nextjs.org/blog/july-2026-security-release and explicitly update the affected dependency before setup.`);
|
|
2981
|
-
}
|
|
2982
|
-
}
|
|
2983
|
-
await inspectSource(join7(projectDirectory, apps[0]));
|
|
2984
|
-
const gitRead = async (args) => setupProcess("git", args, { cwd: projectDirectory }).then((value) => value.trim(), () => null);
|
|
2985
|
-
return {
|
|
2986
|
-
projectDirectory,
|
|
2987
|
-
repositoryRoot,
|
|
2988
|
-
lockfileRoot,
|
|
2989
|
-
appDirectory: apps[0],
|
|
2990
|
-
nextVersion,
|
|
2991
|
-
reactVersion,
|
|
2992
|
-
nodeVersion: process.versions.node,
|
|
2993
|
-
packageManager: { name: name2, version: localVersion, declared },
|
|
2994
|
-
lockfile: {
|
|
2995
|
-
path: relative2(repositoryRoot, join7(lockfileRoot, lockName)),
|
|
2996
|
-
format,
|
|
2997
|
-
sha256: createHash2("sha256").update(lockText).digest("hex")
|
|
2998
|
-
},
|
|
2999
|
-
git: {
|
|
3000
|
-
branch: await gitRead(["branch", "--show-current"]),
|
|
3001
|
-
revision: await gitRead(["rev-parse", "HEAD"]),
|
|
3002
|
-
remote: safeGitRemote(await gitRead(["remote", "get-url", "origin"])),
|
|
3003
|
-
changes: (await gitRead(["status", "--porcelain=v1", "--untracked-files=all"]))?.split("\n").filter(Boolean) ?? []
|
|
3004
|
-
},
|
|
3005
|
-
sourceConflicts
|
|
3006
|
-
};
|
|
3007
|
-
}
|
|
3008
|
-
async function setupPreflightCommand(input) {
|
|
3009
|
-
let local;
|
|
3010
|
-
try {
|
|
3011
|
-
local = await inspectSetupLocalProject(input.projectDir);
|
|
3012
|
-
await assertLocalCredentialsPathSafe(input.projectDir);
|
|
3013
|
-
let linkDirectory = local.projectDirectory;
|
|
3014
|
-
while (!await exists(join7(linkDirectory, ".vercel/project.json")) && linkDirectory !== local.repositoryRoot && dirname7(linkDirectory) !== linkDirectory)
|
|
3015
|
-
linkDirectory = dirname7(linkDirectory);
|
|
3016
|
-
if (!await exists(join7(linkDirectory, ".vercel/project.json")))
|
|
3017
|
-
fail("vercel_project_not_linked", "Link this application to its intended Vercel project before setup; Siteplane will not guess a target.");
|
|
3018
|
-
const linked = z34.object({
|
|
3019
|
-
projectId: z34.string().regex(/^prj_[A-Za-z0-9]+$/u),
|
|
3020
|
-
orgId: z34.string().regex(/^(?:team|user)_[A-Za-z0-9]+$/u)
|
|
3021
|
-
}).parse(JSON.parse(await readFile8(join7(linkDirectory, ".vercel/project.json"), "utf8")));
|
|
3022
|
-
const project = vercelProjectSchema.parse(await setupVercelApi(linkDirectory, `/v9/projects/${linked.projectId}?teamId=${linked.orgId}`));
|
|
3023
|
-
if (project.id !== linked.projectId || project.accountId !== linked.orgId)
|
|
3024
|
-
fail("vercel_identity_conflict", "The provider project does not match the locally linked project and team.");
|
|
3025
|
-
const expectedRoot = relative2(local.repositoryRoot, local.projectDirectory).split(sep).join("/");
|
|
3026
|
-
if ((project.rootDirectory ?? "") !== expectedRoot)
|
|
3027
|
-
fail("vercel_root_conflict", "Vercel Root Directory and the selected local app must identify the same application.");
|
|
3028
|
-
if (project.nodeVersion !== "22.x" || project.framework !== "nextjs")
|
|
3029
|
-
fail("vercel_framework_conflict", "The bound Vercel project must use Next.js with Node.js 22 before setup.");
|
|
3030
|
-
if (project.link && project.link.productionBranch !== local.git.branch)
|
|
3031
|
-
fail("vercel_production_branch_conflict", "The local branch differs from the bound Vercel Production branch.");
|
|
3032
|
-
if (project.link?.repo && project.link.org && !local.git.remote?.replace(/\.git$/u, "").endsWith(`${project.link.org}/${project.link.repo}`))
|
|
3033
|
-
fail("vercel_git_conflict", "The local origin repository differs from the Vercel Git connection.");
|
|
3034
|
-
const env = z34.object({
|
|
3035
|
-
envs: z34.array(z34.object({
|
|
3036
|
-
key: z34.string(),
|
|
3037
|
-
value: z34.string().optional(),
|
|
3038
|
-
target: z34.array(z34.string()).optional()
|
|
3039
|
-
}))
|
|
3040
|
-
}).parse(await setupVercelApi(linkDirectory, `/v10/projects/${linked.projectId}/env?teamId=${linked.orgId}`));
|
|
3041
|
-
const corepack = env.envs.some((item) => item.key === "ENABLE_EXPERIMENTAL_COREPACK" && item.value === "1" && item.target?.includes("production"));
|
|
3042
|
-
const install = project.installCommand ?? null;
|
|
3043
|
-
const selected = corepack ? "corepack" : install ? "install_override" : "automatic";
|
|
3044
|
-
if (local.packageManager.declared && selected === "automatic")
|
|
3045
|
-
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.");
|
|
3046
|
-
if (install && /\b(?:yarn|bun)\b/u.test(install))
|
|
3047
|
-
fail("vercel_package_manager_conflict", "The Vercel install override selects an unsupported package manager.");
|
|
3048
|
-
const overridePin = install ? /\b(npm|pnpm)@(\d+\.\d+\.\d+)\b/u.exec(install) : null;
|
|
3049
|
-
if (overridePin && overridePin[1] !== local.packageManager.name)
|
|
3050
|
-
fail("vercel_package_manager_conflict", "The provider override selects a different package manager than the canonical lockfile.");
|
|
3051
|
-
const overrideFamily = install ? /(?:^|[;&|]\s*)(npm|pnpm)\s+(?:ci|install)\b/u.exec(install)?.[1] : null;
|
|
3052
|
-
if (overrideFamily && overrideFamily !== local.packageManager.name)
|
|
3053
|
-
fail("vercel_package_manager_conflict", "The provider install command conflicts with the canonical lockfile.");
|
|
3054
|
-
if (overridePin && local.packageManager.declared && `${overridePin[1]}@${overridePin[2]}` !== local.packageManager.declared)
|
|
3055
|
-
fail("vercel_package_manager_conflict", "The Vercel install override conflicts with the exact packageManager declaration.");
|
|
3056
|
-
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);
|
|
3057
|
-
for (const [, family, version2] of buildRunners) {
|
|
3058
|
-
if (family !== local.packageManager.name || version2 && local.packageManager.declared && `${family}@${version2}` !== local.packageManager.declared)
|
|
3059
|
-
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.");
|
|
3060
|
-
}
|
|
3061
|
-
return {
|
|
3062
|
-
status: "ready",
|
|
3063
|
-
local,
|
|
3064
|
-
provider: {
|
|
3065
|
-
projectId: project.id,
|
|
3066
|
-
teamId: project.accountId,
|
|
3067
|
-
name: project.name,
|
|
3068
|
-
rootDirectory: expectedRoot,
|
|
3069
|
-
nodeVersion: project.nodeVersion,
|
|
3070
|
-
git: project.link,
|
|
3071
|
-
installCommand: install,
|
|
3072
|
-
buildCommand: project.buildCommand ?? null,
|
|
3073
|
-
packageManagerSelection: selected,
|
|
3074
|
-
declaredPackageManager: local.packageManager.declared,
|
|
3075
|
-
observedPackageManager: null
|
|
3076
|
-
}
|
|
3077
|
-
};
|
|
3078
|
-
} catch (error) {
|
|
3079
|
-
return {
|
|
3080
|
-
status: "action_required",
|
|
3081
|
-
code: error instanceof SetupFailure ? error.code : "invalid_local_project",
|
|
3082
|
-
message: error instanceof SetupFailure ? error.message : "The selected project or provider response could not be validated. Check the application manifest and local project access.",
|
|
3083
|
-
...local ? { local } : {}
|
|
3084
|
-
};
|
|
3085
|
-
}
|
|
3086
|
-
}
|
|
3087
|
-
function safeGitRemote(value) {
|
|
3088
|
-
if (!value)
|
|
3089
|
-
return null;
|
|
3090
|
-
if (!value.includes("://"))
|
|
3091
|
-
return value;
|
|
3092
|
-
try {
|
|
3093
|
-
const url = new URL(value);
|
|
3094
|
-
url.username = "";
|
|
3095
|
-
url.password = "";
|
|
3096
|
-
url.search = "";
|
|
3097
|
-
url.hash = "";
|
|
3098
|
-
return url.toString().replace(/\/$/u, "");
|
|
3099
|
-
} catch {
|
|
3100
|
-
return null;
|
|
3101
|
-
}
|
|
3102
|
-
}
|
|
3103
|
-
|
|
3104
|
-
// ../cli/dist/commands/init.js
|
|
3105
|
-
var siteSetupBootstrapDataSchema = z35.object({
|
|
3106
|
-
credentialPurpose: z35.literal("site_setup"),
|
|
3107
|
-
apiBaseUrl: z35.string().url(),
|
|
3108
|
-
siteId: z35.string().uuid(),
|
|
3109
|
-
publicSiteKeyId: z35.string().uuid(),
|
|
3110
|
-
publicSiteKey: z35.string().trim().min(1),
|
|
3111
|
-
accessToken: z35.string().trim().min(1),
|
|
3112
|
-
siteRevalidationSecret: z35.string().regex(/^[A-Za-z0-9_-]{43}$/u),
|
|
3113
|
-
runId: z35.string().uuid(),
|
|
3114
|
-
packages: siteSetupPackagesSchema
|
|
3115
|
-
}).strict();
|
|
3116
|
-
var featureBootstrapDataSchema = z35.object({
|
|
3117
|
-
credentialPurpose: z35.enum(["analytics", "booking"]),
|
|
3118
|
-
apiBaseUrl: z35.string().url(),
|
|
3119
|
-
siteId: z35.string().uuid(),
|
|
3120
|
-
accessToken: z35.string().trim().min(1)
|
|
3121
|
-
}).strict();
|
|
3122
|
-
var bootstrapResponseSchema = z35.object({
|
|
3123
|
-
ok: z35.literal(true),
|
|
3124
|
-
data: z35.discriminatedUnion("credentialPurpose", [
|
|
3125
|
-
siteSetupBootstrapDataSchema,
|
|
3126
|
-
featureBootstrapDataSchema
|
|
3127
|
-
])
|
|
3128
|
-
}).strict();
|
|
3129
|
-
|
|
3130
1840
|
// ../cli/dist/commands/scan.js
|
|
3131
|
-
import { readdir
|
|
3132
|
-
import { extname, join as
|
|
1841
|
+
import { readdir } from "fs/promises";
|
|
1842
|
+
import { extname, join as join3 } from "path";
|
|
3133
1843
|
var defaultScanRoots = ["app", "src", "pages", "components", "lib"];
|
|
3134
1844
|
var excludedDirectories = /* @__PURE__ */ new Set([
|
|
3135
1845
|
".git",
|
|
@@ -3147,14 +1857,14 @@ async function resolveScanFilePaths(filePaths, options = {}) {
|
|
|
3147
1857
|
return filePaths;
|
|
3148
1858
|
}
|
|
3149
1859
|
const projectDir = options.projectDir ?? process.cwd();
|
|
3150
|
-
const discovered = await Promise.all(defaultScanRoots.map((root) => collectSourceFiles(
|
|
1860
|
+
const discovered = await Promise.all(defaultScanRoots.map((root) => collectSourceFiles(join3(projectDir, root))));
|
|
3151
1861
|
return [...new Set(discovered.flat())].sort();
|
|
3152
1862
|
}
|
|
3153
1863
|
async function collectSourceFiles(directory) {
|
|
3154
|
-
const entries = await
|
|
1864
|
+
const entries = await readdir(directory, { withFileTypes: true }).catch(() => []);
|
|
3155
1865
|
const files = [];
|
|
3156
1866
|
for (const entry of entries) {
|
|
3157
|
-
const entryPath =
|
|
1867
|
+
const entryPath = join3(directory, entry.name);
|
|
3158
1868
|
if (entry.isDirectory()) {
|
|
3159
1869
|
if (!excludedDirectories.has(entry.name)) {
|
|
3160
1870
|
files.push(...await collectSourceFiles(entryPath));
|
|
@@ -3168,19 +1878,59 @@ async function collectSourceFiles(directory) {
|
|
|
3168
1878
|
return files;
|
|
3169
1879
|
}
|
|
3170
1880
|
|
|
3171
|
-
// ../cli/dist/
|
|
3172
|
-
import {
|
|
3173
|
-
import {
|
|
3174
|
-
|
|
3175
|
-
|
|
1881
|
+
// ../cli/dist/auth/device-login.js
|
|
1882
|
+
import { spawn } from "child_process";
|
|
1883
|
+
import { hostname } from "os";
|
|
1884
|
+
|
|
1885
|
+
// ../cli/dist/config/agent-connections.js
|
|
1886
|
+
import { randomUUID } from "crypto";
|
|
1887
|
+
import { chmod, mkdir as mkdir3, open, readFile as readFile3, rename, rm } from "fs/promises";
|
|
1888
|
+
import { join as join4 } from "path";
|
|
1889
|
+
import { z as z27 } from "zod";
|
|
1890
|
+
var storeSchema = z27.object({
|
|
1891
|
+
connections: z27.array(z27.object({
|
|
1892
|
+
apiOrigin: z27.string().url(),
|
|
1893
|
+
siteId: z27.string().min(1),
|
|
1894
|
+
accessToken: z27.string().min(1),
|
|
1895
|
+
scopes: z27.array(z27.string()),
|
|
1896
|
+
expiresAt: z27.string()
|
|
1897
|
+
}))
|
|
1898
|
+
});
|
|
1899
|
+
|
|
1900
|
+
// ../cli/dist/config/project-config.js
|
|
1901
|
+
import { readFile as readFile4 } from "fs/promises";
|
|
1902
|
+
import { join as join5 } from "path";
|
|
1903
|
+
import { z as z28 } from "zod";
|
|
1904
|
+
var packageVersionSchema = z28.string().regex(/^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$/u);
|
|
1905
|
+
var projectPackagesSchema = z28.object({
|
|
1906
|
+
siteplane: packageVersionSchema,
|
|
1907
|
+
runtimeNext: packageVersionSchema,
|
|
1908
|
+
analytics: packageVersionSchema.optional()
|
|
1909
|
+
}).strict();
|
|
1910
|
+
var siteplaneProjectConfigSchema = z28.object({
|
|
1911
|
+
version: z28.literal(2),
|
|
1912
|
+
apiBaseUrl: z28.string().url(),
|
|
1913
|
+
siteId: z28.string().uuid(),
|
|
1914
|
+
publicSiteKeyId: z28.string().uuid(),
|
|
1915
|
+
publicSiteKey: z28.string().trim().min(1),
|
|
1916
|
+
runId: z28.string().uuid(),
|
|
1917
|
+
appDirectory: z28.string().min(1),
|
|
1918
|
+
taskContractVersion: z28.literal("siteplane.setup-task.v2"),
|
|
1919
|
+
adminProtocolVersion: z28.literal(2),
|
|
1920
|
+
packages: projectPackagesSchema,
|
|
1921
|
+
fieldContractHash: z28.string().regex(/^sha256:[0-9a-f]{64}$/iu).optional()
|
|
1922
|
+
}).strict();
|
|
1923
|
+
async function readProjectConfig(projectDir) {
|
|
1924
|
+
return siteplaneProjectConfigSchema.parse(JSON.parse(await readFile4(join5(projectDir, "siteplane.config.json"), "utf8")));
|
|
1925
|
+
}
|
|
3176
1926
|
|
|
3177
1927
|
// ../cli/dist/scan/next-source-scan.js
|
|
3178
|
-
import
|
|
3179
|
-
import { isAbsolute, relative
|
|
1928
|
+
import ts2 from "typescript";
|
|
1929
|
+
import { isAbsolute, relative } from "path";
|
|
3180
1930
|
var eventPreviewHandlerMissingMessage = "Event preview fields must consume preview values with useSiteplanePreviewText from @siteplane/runtime-next/client or a siteplane:preview-value-applied listener.";
|
|
3181
1931
|
var valueCallUnusedMessage = "Siteplane value calls must feed rendered content. Assign or await the returned value and render that value instead of ignoring the call.";
|
|
3182
1932
|
var legacyEditableComponentPrefix = "Editable";
|
|
3183
|
-
var editableComponentNames = new Set(["Image", "Text", "LongText", "Link"].map((
|
|
1933
|
+
var editableComponentNames = new Set(["Image", "Text", "LongText", "Link"].map((name) => `${legacyEditableComponentPrefix}${name}`));
|
|
3184
1934
|
var functionTypeByName = {
|
|
3185
1935
|
text: "text",
|
|
3186
1936
|
longText: "longText",
|
|
@@ -3331,10 +2081,10 @@ function scanSourceFile(file, fields, hardErrors) {
|
|
|
3331
2081
|
const eventPreviewComponentPropUsages = [];
|
|
3332
2082
|
const eventPreviewConsumerFieldIds = /* @__PURE__ */ new Set();
|
|
3333
2083
|
let hasGenericEventPreviewConsumer = false;
|
|
3334
|
-
const sourceFile =
|
|
2084
|
+
const sourceFile = ts2.createSourceFile(file.filePath, file.sourceText, ts2.ScriptTarget.Latest, true, ts2.ScriptKind.TSX);
|
|
3335
2085
|
function visit(node, currentComponentName) {
|
|
3336
2086
|
const nextComponentName = getFunctionComponentName(node) ?? currentComponentName;
|
|
3337
|
-
if (
|
|
2087
|
+
if (ts2.isJsxSelfClosingElement(node) || ts2.isJsxOpeningElement(node)) {
|
|
3338
2088
|
const componentName = getJsxTagName(node.tagName);
|
|
3339
2089
|
if (editableComponentNames.has(componentName)) {
|
|
3340
2090
|
hardErrors.push({
|
|
@@ -3345,7 +2095,7 @@ function scanSourceFile(file, fields, hardErrors) {
|
|
|
3345
2095
|
}
|
|
3346
2096
|
collectEventPreviewComponentPropUsages(node, eventPreviewAttrVariables, eventPreviewComponentPropUsages, file);
|
|
3347
2097
|
}
|
|
3348
|
-
if (
|
|
2098
|
+
if (ts2.isCallExpression(node)) {
|
|
3349
2099
|
collectAttrsCall(node, attrFieldIds, attrRouteRefs, eventPreviewAttrs, eventPreviewAttrVariables, directAttrs, file);
|
|
3350
2100
|
collectUnusedValueCallError(node, hardErrors, file);
|
|
3351
2101
|
const extractedFields = extractFunctionFields(node, file);
|
|
@@ -3369,7 +2119,7 @@ function scanSourceFile(file, fields, hardErrors) {
|
|
|
3369
2119
|
if (isGenericEventPreviewConsumerReference(node)) {
|
|
3370
2120
|
hasGenericEventPreviewConsumer = true;
|
|
3371
2121
|
}
|
|
3372
|
-
|
|
2122
|
+
ts2.forEachChild(node, (child) => visit(child, nextComponentName));
|
|
3373
2123
|
}
|
|
3374
2124
|
visit(sourceFile);
|
|
3375
2125
|
markMissingAttrsWarnings(fieldsInFile, attrFieldIds, attrRouteRefs);
|
|
@@ -3396,7 +2146,7 @@ function collectUnusedValueCallError(node, hardErrors, file) {
|
|
|
3396
2146
|
});
|
|
3397
2147
|
}
|
|
3398
2148
|
function getSiteplaneValueFunctionName(node) {
|
|
3399
|
-
if (!
|
|
2149
|
+
if (!ts2.isPropertyAccessExpression(node.expression)) {
|
|
3400
2150
|
return void 0;
|
|
3401
2151
|
}
|
|
3402
2152
|
if (node.expression.expression.getText() !== "siteplane") {
|
|
@@ -3409,16 +2159,16 @@ function getSiteplaneValueFunctionName(node) {
|
|
|
3409
2159
|
return void 0;
|
|
3410
2160
|
}
|
|
3411
2161
|
function isIgnoredValueCall(node) {
|
|
3412
|
-
if (
|
|
2162
|
+
if (ts2.isVoidExpression(node.parent)) {
|
|
3413
2163
|
return true;
|
|
3414
2164
|
}
|
|
3415
|
-
if (
|
|
2165
|
+
if (ts2.isExpressionStatement(node.parent)) {
|
|
3416
2166
|
return true;
|
|
3417
2167
|
}
|
|
3418
|
-
return
|
|
2168
|
+
return ts2.isAwaitExpression(node.parent) && ts2.isExpressionStatement(node.parent.parent);
|
|
3419
2169
|
}
|
|
3420
2170
|
function extractFunctionFields(node, file) {
|
|
3421
|
-
if (!
|
|
2171
|
+
if (!ts2.isPropertyAccessExpression(node.expression)) {
|
|
3422
2172
|
return [];
|
|
3423
2173
|
}
|
|
3424
2174
|
if (node.expression.expression.getText() !== "siteplane") {
|
|
@@ -3556,7 +2306,7 @@ function createFallbackHash(fieldType, fallback) {
|
|
|
3556
2306
|
}
|
|
3557
2307
|
}
|
|
3558
2308
|
function collectAttrsCall(node, attrFieldIds, attrRouteRefs, eventPreviewAttrs, eventPreviewAttrVariables, directAttrs, file) {
|
|
3559
|
-
if (!
|
|
2309
|
+
if (!ts2.isPropertyAccessExpression(node.expression)) {
|
|
3560
2310
|
return;
|
|
3561
2311
|
}
|
|
3562
2312
|
if (node.expression.expression.getText() !== "siteplane" || node.expression.name.text !== "attrs") {
|
|
@@ -3585,7 +2335,7 @@ function collectAttrsCall(node, attrFieldIds, attrRouteRefs, eventPreviewAttrs,
|
|
|
3585
2335
|
}
|
|
3586
2336
|
return;
|
|
3587
2337
|
}
|
|
3588
|
-
if (firstArg &&
|
|
2338
|
+
if (firstArg && ts2.isIdentifier(firstArg) && typeof secondArg === "string") {
|
|
3589
2339
|
attrRouteRefs.add(`${firstArg.text}:${secondArg}`);
|
|
3590
2340
|
}
|
|
3591
2341
|
}
|
|
@@ -3622,7 +2372,7 @@ function hasEventPreviewStrategy(options) {
|
|
|
3622
2372
|
return !!options && typeof options === "object" && !Array.isArray(options) && options.previewStrategy === "event";
|
|
3623
2373
|
}
|
|
3624
2374
|
function isGenericEventPreviewConsumerReference(node) {
|
|
3625
|
-
return (
|
|
2375
|
+
return (ts2.isStringLiteral(node) || ts2.isNoSubstitutionTemplateLiteral(node)) && node.text === "siteplane:preview-value-applied";
|
|
3626
2376
|
}
|
|
3627
2377
|
function getPreviewHookFieldId(node, eventPreviewAttrVariables) {
|
|
3628
2378
|
const firstArg = getUseSiteplanePreviewTextFirstArg(node);
|
|
@@ -3633,7 +2383,7 @@ function getPreviewHookFieldId(node, eventPreviewAttrVariables) {
|
|
|
3633
2383
|
if (typeof directFieldId === "string") {
|
|
3634
2384
|
return directFieldId;
|
|
3635
2385
|
}
|
|
3636
|
-
if (
|
|
2386
|
+
if (ts2.isIdentifier(firstArg)) {
|
|
3637
2387
|
return eventPreviewAttrVariables.get(firstArg.text);
|
|
3638
2388
|
}
|
|
3639
2389
|
return void 0;
|
|
@@ -3643,16 +2393,16 @@ function getPreviewHookPropName(node, eventPreviewAttrVariables) {
|
|
|
3643
2393
|
if (!firstArg) {
|
|
3644
2394
|
return void 0;
|
|
3645
2395
|
}
|
|
3646
|
-
if (
|
|
2396
|
+
if (ts2.isIdentifier(firstArg) && !eventPreviewAttrVariables.has(firstArg.text)) {
|
|
3647
2397
|
return firstArg.text;
|
|
3648
2398
|
}
|
|
3649
|
-
if (
|
|
2399
|
+
if (ts2.isPropertyAccessExpression(firstArg) && ts2.isIdentifier(firstArg.expression)) {
|
|
3650
2400
|
return firstArg.name.text;
|
|
3651
2401
|
}
|
|
3652
2402
|
return void 0;
|
|
3653
2403
|
}
|
|
3654
2404
|
function getUseSiteplanePreviewTextFirstArg(node) {
|
|
3655
|
-
if (
|
|
2405
|
+
if (ts2.isIdentifier(node.expression) && node.expression.text === "useSiteplanePreviewText") {
|
|
3656
2406
|
return node.arguments[0];
|
|
3657
2407
|
}
|
|
3658
2408
|
return void 0;
|
|
@@ -3733,19 +2483,19 @@ function staticExpressionValue(expression) {
|
|
|
3733
2483
|
if (!expression) {
|
|
3734
2484
|
return void 0;
|
|
3735
2485
|
}
|
|
3736
|
-
if (
|
|
2486
|
+
if (ts2.isStringLiteral(expression) || ts2.isNoSubstitutionTemplateLiteral(expression)) {
|
|
3737
2487
|
return expression.text;
|
|
3738
2488
|
}
|
|
3739
|
-
if (
|
|
2489
|
+
if (ts2.isNumericLiteral(expression)) {
|
|
3740
2490
|
return Number(expression.text);
|
|
3741
2491
|
}
|
|
3742
|
-
if (expression.kind ===
|
|
2492
|
+
if (expression.kind === ts2.SyntaxKind.TrueKeyword) {
|
|
3743
2493
|
return true;
|
|
3744
2494
|
}
|
|
3745
|
-
if (expression.kind ===
|
|
2495
|
+
if (expression.kind === ts2.SyntaxKind.FalseKeyword) {
|
|
3746
2496
|
return false;
|
|
3747
2497
|
}
|
|
3748
|
-
if (
|
|
2498
|
+
if (ts2.isObjectLiteralExpression(expression)) {
|
|
3749
2499
|
return readObjectLiteral(expression);
|
|
3750
2500
|
}
|
|
3751
2501
|
return void 0;
|
|
@@ -3753,20 +2503,20 @@ function staticExpressionValue(expression) {
|
|
|
3753
2503
|
function readObjectLiteral(expression) {
|
|
3754
2504
|
const value = {};
|
|
3755
2505
|
for (const property of expression.properties) {
|
|
3756
|
-
if (!
|
|
2506
|
+
if (!ts2.isPropertyAssignment(property)) {
|
|
3757
2507
|
continue;
|
|
3758
2508
|
}
|
|
3759
|
-
const
|
|
3760
|
-
if (!
|
|
2509
|
+
const name = getPropertyName(property.name);
|
|
2510
|
+
if (!name) {
|
|
3761
2511
|
continue;
|
|
3762
2512
|
}
|
|
3763
|
-
value[
|
|
2513
|
+
value[name] = staticExpressionValue(property.initializer);
|
|
3764
2514
|
}
|
|
3765
2515
|
return value;
|
|
3766
2516
|
}
|
|
3767
|
-
function getPropertyName(
|
|
3768
|
-
if (
|
|
3769
|
-
return
|
|
2517
|
+
function getPropertyName(name) {
|
|
2518
|
+
if (ts2.isIdentifier(name) || ts2.isStringLiteral(name)) {
|
|
2519
|
+
return name.text;
|
|
3770
2520
|
}
|
|
3771
2521
|
return null;
|
|
3772
2522
|
}
|
|
@@ -3776,7 +2526,7 @@ function collectEventPreviewComponentPropUsages(node, eventPreviewAttrVariables,
|
|
|
3776
2526
|
return;
|
|
3777
2527
|
}
|
|
3778
2528
|
for (const property of node.attributes.properties) {
|
|
3779
|
-
if (!
|
|
2529
|
+
if (!ts2.isJsxAttribute(property)) {
|
|
3780
2530
|
continue;
|
|
3781
2531
|
}
|
|
3782
2532
|
const propName = getJsxAttributeName(property.name);
|
|
@@ -3792,9 +2542,9 @@ function collectEventPreviewComponentPropUsages(node, eventPreviewAttrVariables,
|
|
|
3792
2542
|
});
|
|
3793
2543
|
}
|
|
3794
2544
|
}
|
|
3795
|
-
function getJsxAttributeName(
|
|
3796
|
-
if (
|
|
3797
|
-
return
|
|
2545
|
+
function getJsxAttributeName(name) {
|
|
2546
|
+
if (ts2.isIdentifier(name)) {
|
|
2547
|
+
return name.text;
|
|
3798
2548
|
}
|
|
3799
2549
|
return void 0;
|
|
3800
2550
|
}
|
|
@@ -3802,32 +2552,32 @@ function getJsxFieldIdValue(initializer, eventPreviewAttrVariables) {
|
|
|
3802
2552
|
if (!initializer) {
|
|
3803
2553
|
return void 0;
|
|
3804
2554
|
}
|
|
3805
|
-
if (
|
|
2555
|
+
if (ts2.isStringLiteral(initializer)) {
|
|
3806
2556
|
return initializer.text;
|
|
3807
2557
|
}
|
|
3808
|
-
if (
|
|
2558
|
+
if (ts2.isJsxExpression(initializer) && initializer.expression && ts2.isIdentifier(initializer.expression)) {
|
|
3809
2559
|
return eventPreviewAttrVariables.get(initializer.expression.text);
|
|
3810
2560
|
}
|
|
3811
2561
|
return void 0;
|
|
3812
2562
|
}
|
|
3813
2563
|
function getFunctionComponentName(node) {
|
|
3814
|
-
if (
|
|
2564
|
+
if (ts2.isFunctionDeclaration(node) && node.name && isComponentName(node.name.text)) {
|
|
3815
2565
|
return node.name.text;
|
|
3816
2566
|
}
|
|
3817
|
-
if (
|
|
2567
|
+
if (ts2.isVariableDeclaration(node) && ts2.isIdentifier(node.name) && isComponentName(node.name.text) && node.initializer && (ts2.isArrowFunction(node.initializer) || ts2.isFunctionExpression(node.initializer))) {
|
|
3818
2568
|
return node.name.text;
|
|
3819
2569
|
}
|
|
3820
2570
|
return void 0;
|
|
3821
2571
|
}
|
|
3822
|
-
function isComponentName(
|
|
3823
|
-
return /^[A-Z]/.test(
|
|
2572
|
+
function isComponentName(name) {
|
|
2573
|
+
return /^[A-Z]/.test(name);
|
|
3824
2574
|
}
|
|
3825
2575
|
function getAssignedVariableName(node) {
|
|
3826
2576
|
let current = node;
|
|
3827
|
-
while (
|
|
2577
|
+
while (ts2.isAwaitExpression(current.parent)) {
|
|
3828
2578
|
current = current.parent;
|
|
3829
2579
|
}
|
|
3830
|
-
if (
|
|
2580
|
+
if (ts2.isVariableDeclaration(current.parent) && ts2.isIdentifier(current.parent.name)) {
|
|
3831
2581
|
return current.parent.name.text;
|
|
3832
2582
|
}
|
|
3833
2583
|
return void 0;
|
|
@@ -3868,391 +2618,13 @@ function inferRouteHint(filePath) {
|
|
|
3868
2618
|
return route ? `/${route}` : "/";
|
|
3869
2619
|
}
|
|
3870
2620
|
function toRepositoryRelativePosixPath(filePath, projectRoot) {
|
|
3871
|
-
const path = isAbsolute(filePath) ?
|
|
2621
|
+
const path = isAbsolute(filePath) ? relative(projectRoot, filePath) : filePath;
|
|
3872
2622
|
return path.replaceAll("\\", "/");
|
|
3873
2623
|
}
|
|
3874
2624
|
function isPositionalFieldReference(value) {
|
|
3875
2625
|
return value ? /\[\d+\]|\.\d+(?:\.|$)/.test(value) : false;
|
|
3876
2626
|
}
|
|
3877
2627
|
|
|
3878
|
-
// ../cli/dist/commands/site-setup.js
|
|
3879
|
-
var execFileAsync2 = promisify2(execFile2);
|
|
3880
|
-
var safeErrorSchema = z36.object({
|
|
3881
|
-
code: z36.string().trim().min(1),
|
|
3882
|
-
message: z36.string().trim().min(1)
|
|
3883
|
-
}).passthrough();
|
|
3884
|
-
var errorResponseSchema2 = z36.object({ ok: z36.literal(false), error: safeErrorSchema }).passthrough();
|
|
3885
|
-
var contextDataSchema = z36.object({
|
|
3886
|
-
task: siteSetupTaskSchema.refine((task) => task.run !== null)
|
|
3887
|
-
}).strict();
|
|
3888
|
-
var contextResponseSchema = z36.object({ ok: z36.literal(true), data: contextDataSchema }).strict();
|
|
3889
|
-
var applyDataSchema = z36.object({
|
|
3890
|
-
status: z36.enum(["applied", "ready_for_review"]),
|
|
3891
|
-
runId: z36.string().uuid().optional(),
|
|
3892
|
-
contractVersionId: z36.string().uuid().optional(),
|
|
3893
|
-
fieldContractHash: z36.string().regex(/^sha256:[0-9a-f]{64}$/u),
|
|
3894
|
-
editorDefinitionHash: z36.string().regex(/^sha256:[0-9a-f]{64}$/u).optional(),
|
|
3895
|
-
fieldCount: z36.number().int().nonnegative().optional(),
|
|
3896
|
-
routeCount: z36.number().int().nonnegative().optional()
|
|
3897
|
-
}).strict();
|
|
3898
|
-
var applyResponseSchema = z36.object({ ok: z36.literal(true), data: applyDataSchema }).strict();
|
|
3899
|
-
var verifyDataSchema = z36.object({
|
|
3900
|
-
status: z36.literal("ready_for_review"),
|
|
3901
|
-
runId: z36.string().uuid().optional(),
|
|
3902
|
-
deploymentOrigin: z36.string().url().optional(),
|
|
3903
|
-
deploymentRevision: z36.string().optional()
|
|
3904
|
-
}).strict();
|
|
3905
|
-
var verifyResponseSchema = z36.object({ ok: z36.literal(true), data: verifyDataSchema }).strict();
|
|
3906
|
-
async function siteSetupContextCommand(input) {
|
|
3907
|
-
const response = await postSiteSetup(input, "context", {});
|
|
3908
|
-
const parsed = contextResponseSchema.safeParse(response.payload);
|
|
3909
|
-
if (response.ok && parsed.success) {
|
|
3910
|
-
return { status: "ok", ...parsed.data.data };
|
|
3911
|
-
}
|
|
3912
|
-
return actionRequired(response.payload, "Siteplane setup context is unavailable.");
|
|
3913
|
-
}
|
|
3914
|
-
async function siteSetupVerifyCommand(input) {
|
|
3915
|
-
const resolveSourceFiles = input.resolveSourceFiles ?? resolveScanFilePaths;
|
|
3916
|
-
const readSourceFile = input.readSourceFile ?? ((path) => readFile9(path, "utf8"));
|
|
3917
|
-
const paths = await resolveSourceFiles([], { projectDir: input.projectDir });
|
|
3918
|
-
const sources = await Promise.all(paths.map(readSourceFile));
|
|
3919
|
-
if (!sources.some(hasMountedFieldRuntimeBridge)) {
|
|
3920
|
-
return {
|
|
3921
|
-
status: "action_required",
|
|
3922
|
-
code: "missing_field_runtime_bridge",
|
|
3923
|
-
message: "Mount FieldRuntimeBridge from @siteplane/runtime-next/client before deployment verification."
|
|
3924
|
-
};
|
|
3925
|
-
}
|
|
3926
|
-
const deploymentRevision = await (input.readRevision ?? readGitRevision)(input.projectDir);
|
|
3927
|
-
const response = await postSiteSetup(input, "verify", {
|
|
3928
|
-
deploymentUrl: input.deploymentUrl,
|
|
3929
|
-
deploymentRevision,
|
|
3930
|
-
...input.wait ? { wait: true } : {}
|
|
3931
|
-
});
|
|
3932
|
-
const parsed = verifyResponseSchema.safeParse(response.payload);
|
|
3933
|
-
if (response.ok && parsed.success) {
|
|
3934
|
-
return parsed.data.data;
|
|
3935
|
-
}
|
|
3936
|
-
return actionRequired(response.payload, "Siteplane deployment verification failed.");
|
|
3937
|
-
}
|
|
3938
|
-
function hasMountedFieldRuntimeBridge(source) {
|
|
3939
|
-
return /from\s+["']@siteplane\/runtime-next(?:\/client)?["']/u.test(source) && /<FieldRuntimeBridge(?:\s|\/|>)/u.test(source);
|
|
3940
|
-
}
|
|
3941
|
-
async function postSiteSetup(input, operation, body) {
|
|
3942
|
-
const [config, credentials] = await Promise.all([
|
|
3943
|
-
readProjectConfig(input.projectDir),
|
|
3944
|
-
readLocalCredentials(input.projectDir)
|
|
3945
|
-
]);
|
|
3946
|
-
try {
|
|
3947
|
-
const response = await (input.fetcher ?? fetch)(`${config.apiBaseUrl.replace(/\/$/u, "")}/api/cli/setup/${operation}`, {
|
|
3948
|
-
method: "POST",
|
|
3949
|
-
signal: AbortSignal.timeout(Math.max(1, Math.min(2e4, (input.deadline ?? Date.now() + 2e4) - Date.now()))),
|
|
3950
|
-
headers: {
|
|
3951
|
-
authorization: `Bearer ${credentials.accessToken}`,
|
|
3952
|
-
"content-type": "application/json",
|
|
3953
|
-
...input.vercelAutomationBypassSecret?.trim() ? {
|
|
3954
|
-
"x-vercel-protection-bypass": input.vercelAutomationBypassSecret.trim()
|
|
3955
|
-
} : {}
|
|
3956
|
-
},
|
|
3957
|
-
body: JSON.stringify(body)
|
|
3958
|
-
});
|
|
3959
|
-
const payload = await response.json().catch(() => null);
|
|
3960
|
-
return { ok: response.ok, payload };
|
|
3961
|
-
} catch {
|
|
3962
|
-
return {
|
|
3963
|
-
ok: false,
|
|
3964
|
-
payload: {
|
|
3965
|
-
ok: false,
|
|
3966
|
-
error: {
|
|
3967
|
-
code: "site_setup.transport_failed",
|
|
3968
|
-
message: "The setup request was not acknowledged. Reload the existing task before retrying; no credential values are included."
|
|
3969
|
-
}
|
|
3970
|
-
}
|
|
3971
|
-
};
|
|
3972
|
-
}
|
|
3973
|
-
}
|
|
3974
|
-
function actionRequired(payload, fallbackMessage) {
|
|
3975
|
-
const parsed = errorResponseSchema2.safeParse(payload);
|
|
3976
|
-
return parsed.success ? {
|
|
3977
|
-
status: "action_required",
|
|
3978
|
-
code: parsed.data.error.code,
|
|
3979
|
-
message: parsed.data.error.message
|
|
3980
|
-
} : {
|
|
3981
|
-
status: "action_required",
|
|
3982
|
-
code: "invalid_server_response",
|
|
3983
|
-
message: fallbackMessage
|
|
3984
|
-
};
|
|
3985
|
-
}
|
|
3986
|
-
async function readGitRevision(projectDir) {
|
|
3987
|
-
const { stdout } = await execFileAsync2("git", ["rev-parse", "HEAD"], {
|
|
3988
|
-
cwd: projectDir,
|
|
3989
|
-
encoding: "utf8"
|
|
3990
|
-
});
|
|
3991
|
-
const revision = stdout.trim();
|
|
3992
|
-
if (!revision) {
|
|
3993
|
-
throw new Error("A committed Git revision is required before setup verify.");
|
|
3994
|
-
}
|
|
3995
|
-
return revision;
|
|
3996
|
-
}
|
|
3997
|
-
|
|
3998
|
-
// ../cli/dist/commands/setup-start.js
|
|
3999
|
-
import { randomBytes, randomUUID as randomUUID4 } from "crypto";
|
|
4000
|
-
import { access as access5 } from "fs/promises";
|
|
4001
|
-
import { join as join10, relative as relative5 } from "path";
|
|
4002
|
-
import { z as z37 } from "zod";
|
|
4003
|
-
var bootstrapResponseSchema2 = z37.object({
|
|
4004
|
-
ok: z37.literal(true),
|
|
4005
|
-
data: siteSetupBootstrapDataSchema
|
|
4006
|
-
}).strict();
|
|
4007
|
-
|
|
4008
|
-
// ../cli/dist/commands/setup-review.js
|
|
4009
|
-
import { z as z38 } from "zod";
|
|
4010
|
-
var responseSchema2 = z38.object({
|
|
4011
|
-
ok: z38.literal(true),
|
|
4012
|
-
data: z38.object({
|
|
4013
|
-
reviewUrl: z38.string().url(),
|
|
4014
|
-
expiresAt: z38.string().datetime({ offset: true })
|
|
4015
|
-
}).strict()
|
|
4016
|
-
}).strict();
|
|
4017
|
-
|
|
4018
|
-
// ../cli/dist/commands/setup-prepare.js
|
|
4019
|
-
import { access as access6, lstat as lstat2, mkdir as mkdir6, open as open3, readFile as readFile10, rename as rename3, rm as rm3 } from "fs/promises";
|
|
4020
|
-
import { randomUUID as randomUUID5 } from "crypto";
|
|
4021
|
-
import { dirname as dirname8, join as join11, relative as relative6, sep as sep2 } from "path";
|
|
4022
|
-
import ts4 from "typescript";
|
|
4023
|
-
|
|
4024
|
-
// ../cli/dist/commands/setup-lock.js
|
|
4025
|
-
import { randomUUID as randomUUID6 } from "crypto";
|
|
4026
|
-
import { lstat as lstat3, mkdir as mkdir7, open as open4, readFile as readFile11, rm as rm4, rmdir } from "fs/promises";
|
|
4027
|
-
import { resolve as resolve2 } from "path";
|
|
4028
|
-
import { z as z39 } from "zod";
|
|
4029
|
-
var ownerSchema = z39.object({ pid: z39.number().int().positive(), nonce: z39.string().uuid() }).strict();
|
|
4030
|
-
|
|
4031
|
-
// ../cli/dist/config/build-provenance.js
|
|
4032
|
-
import { createHash as createHash3 } from "crypto";
|
|
4033
|
-
import { execFile as execFile3 } from "child_process";
|
|
4034
|
-
import { lstat as lstat4, readFile as readFile12, writeFile as writeFile5, mkdir as mkdir8 } from "fs/promises";
|
|
4035
|
-
import { dirname as dirname9, isAbsolute as isAbsolute2, join as join12, relative as relative7, resolve as resolve3, sep as sep3 } from "path";
|
|
4036
|
-
import { isDeepStrictEqual, promisify as promisify3 } from "util";
|
|
4037
|
-
import { z as z40 } from "zod";
|
|
4038
|
-
var execute = promisify3(execFile3);
|
|
4039
|
-
var name = ".siteplane/build-source.json";
|
|
4040
|
-
var oid = z40.string().regex(/^[0-9a-f]{40}$/u);
|
|
4041
|
-
var entrySchema = z40.object({
|
|
4042
|
-
path: z40.string().min(1).max(4096),
|
|
4043
|
-
mode: z40.enum(["100644", "100755", "120000"]),
|
|
4044
|
-
oid
|
|
4045
|
-
}).strict();
|
|
4046
|
-
var schema = z40.object({
|
|
4047
|
-
version: z40.literal(2),
|
|
4048
|
-
revision: oid,
|
|
4049
|
-
commit: z40.string().min(1).max(1048576),
|
|
4050
|
-
entries: z40.array(entrySchema).min(1).max(1e5),
|
|
4051
|
-
providerConfigurations: z40.array(z40.object({
|
|
4052
|
-
path: z40.string().max(4096).regex(/(?:^|\/)vercel\.json$/u),
|
|
4053
|
-
source: z40.string().max(1048576)
|
|
4054
|
-
}).strict()).max(1e3)
|
|
4055
|
-
}).strict();
|
|
4056
|
-
var gitHash = (type, content) => createHash3("sha1").update(`${type} ${content.length}\0`).update(content).digest("hex");
|
|
4057
|
-
async function writeBuildProvenance(checkout, revision) {
|
|
4058
|
-
const commit = (await execute("git", ["cat-file", "commit", revision], {
|
|
4059
|
-
cwd: checkout,
|
|
4060
|
-
maxBuffer: 1048576
|
|
4061
|
-
})).stdout;
|
|
4062
|
-
const tree = (await execute("git", ["ls-tree", "-rz", "--full-tree", revision], {
|
|
4063
|
-
cwd: checkout,
|
|
4064
|
-
maxBuffer: 16777216
|
|
4065
|
-
})).stdout;
|
|
4066
|
-
const entries = tree.split("\0").filter(Boolean).map((line) => {
|
|
4067
|
-
const match = /^(100644|100755|120000) blob ([0-9a-f]{40})\t([\s\S]+)$/u.exec(line);
|
|
4068
|
-
if (!match)
|
|
4069
|
-
throw new Error("Git submodules or unsupported tracked objects need an explicit deployment configuration.");
|
|
4070
|
-
return { path: match[3], mode: match[1], oid: match[2] };
|
|
4071
|
-
});
|
|
4072
|
-
for (const entry of entries) {
|
|
4073
|
-
if (entry.mode !== "120000")
|
|
4074
|
-
continue;
|
|
4075
|
-
const { readlink: readlink2 } = await import("fs/promises");
|
|
4076
|
-
const path = join12(checkout, entry.path);
|
|
4077
|
-
const target2 = resolve3(dirname9(path), await readlink2(path));
|
|
4078
|
-
const bound = relative7(checkout, target2);
|
|
4079
|
-
if (bound.startsWith("..") || isAbsolute2(bound))
|
|
4080
|
-
throw new Error("A tracked symbolic link escapes the committed upload; resolve that source boundary before deployment.");
|
|
4081
|
-
}
|
|
4082
|
-
const providerConfigurations = await Promise.all(entries.filter((entry) => /(?:^|\/)vercel\.json$/u.test(entry.path)).map(async (entry) => ({
|
|
4083
|
-
path: entry.path,
|
|
4084
|
-
source: await readFile12(join12(checkout, entry.path), "utf8")
|
|
4085
|
-
})));
|
|
4086
|
-
const record = schema.parse({
|
|
4087
|
-
version: 2,
|
|
4088
|
-
revision,
|
|
4089
|
-
commit,
|
|
4090
|
-
entries,
|
|
4091
|
-
providerConfigurations
|
|
4092
|
-
});
|
|
4093
|
-
const target = join12(checkout, name);
|
|
4094
|
-
await mkdir8(dirname9(target), { recursive: true, mode: 448 });
|
|
4095
|
-
await writeFile5(target, JSON.stringify(record), { flag: "wx", mode: 384 });
|
|
4096
|
-
}
|
|
4097
|
-
async function readBuildProvenance(projectDirectory) {
|
|
4098
|
-
let root = resolve3(projectDirectory);
|
|
4099
|
-
let raw = null;
|
|
4100
|
-
for (; ; ) {
|
|
4101
|
-
raw = await readFile12(join12(root, name), "utf8").catch((error) => {
|
|
4102
|
-
if (error.code === "ENOENT")
|
|
4103
|
-
return null;
|
|
4104
|
-
throw error;
|
|
4105
|
-
});
|
|
4106
|
-
if (raw !== null || dirname9(root) === root)
|
|
4107
|
-
break;
|
|
4108
|
-
root = dirname9(root);
|
|
4109
|
-
}
|
|
4110
|
-
if (raw === null)
|
|
4111
|
-
return null;
|
|
4112
|
-
if (Buffer.byteLength(raw) > 16777216)
|
|
4113
|
-
throw new Error("Build provenance is oversized.");
|
|
4114
|
-
const record = schema.parse(JSON.parse(raw));
|
|
4115
|
-
if (gitHash("commit", Buffer.from(record.commit)) !== record.revision)
|
|
4116
|
-
throw new Error("The build revision is not the supplied Git commit.");
|
|
4117
|
-
const expectedTree = /^tree ([0-9a-f]{40})\n/u.exec(record.commit)?.[1];
|
|
4118
|
-
if (treeHash(record.entries) !== expectedTree)
|
|
4119
|
-
throw new Error("The build file inventory does not belong to this Git commit.");
|
|
4120
|
-
const bound = new Map(record.entries.map((entry) => [entry.path, entry]));
|
|
4121
|
-
const configurations = /* @__PURE__ */ new Map();
|
|
4122
|
-
for (const config of record.providerConfigurations) {
|
|
4123
|
-
const entry = bound.get(config.path);
|
|
4124
|
-
if (!entry || entry.mode === "120000" || configurations.has(config.path) || gitHash("blob", Buffer.from(config.source)) !== entry.oid)
|
|
4125
|
-
throw new Error("The original provider configuration is not bound to the Git commit.");
|
|
4126
|
-
configurations.set(config.path, config.source);
|
|
4127
|
-
}
|
|
4128
|
-
if (record.entries.some((entry) => /(?:^|\/)vercel\.json$/u.test(entry.path) && !configurations.has(entry.path)))
|
|
4129
|
-
throw new Error("The committed provider configuration is missing from the build provenance.");
|
|
4130
|
-
const appRelative = relative7(root, projectDirectory).split(sep3).join("/");
|
|
4131
|
-
if (!bound.has(appRelative ? `${appRelative}/package.json` : "package.json"))
|
|
4132
|
-
throw new Error("The selected app is not part of the committed upload.");
|
|
4133
|
-
for (const entry of record.entries) {
|
|
4134
|
-
const path = join12(root, entry.path);
|
|
4135
|
-
const stat = await lstat4(path).catch((error) => {
|
|
4136
|
-
if (error.code === "ENOENT")
|
|
4137
|
-
return null;
|
|
4138
|
-
throw error;
|
|
4139
|
-
});
|
|
4140
|
-
if (!stat)
|
|
4141
|
-
continue;
|
|
4142
|
-
if (stat.isSymbolicLink()) {
|
|
4143
|
-
const { readlink: readlink2 } = await import("fs/promises");
|
|
4144
|
-
if (entry.mode !== "120000" || gitHash("blob", Buffer.from(await readlink2(path))) !== entry.oid)
|
|
4145
|
-
throw new Error("A deployed symbolic link differs from the commit.");
|
|
4146
|
-
} else {
|
|
4147
|
-
const contents = stat.isFile() ? await readFile12(path) : null;
|
|
4148
|
-
if (contents && entry.mode !== "120000" && gitHash("blob", contents) === entry.oid)
|
|
4149
|
-
continue;
|
|
4150
|
-
const original = configurations.get(entry.path);
|
|
4151
|
-
if (contents && original && entry.mode !== "120000") {
|
|
4152
|
-
try {
|
|
4153
|
-
const object = z40.record(z40.string(), z40.unknown());
|
|
4154
|
-
const actual = object.parse(JSON.parse(contents.toString("utf8")));
|
|
4155
|
-
const expected = object.parse(JSON.parse(original));
|
|
4156
|
-
if (!Object.hasOwn(expected, "version") && actual.version === 2)
|
|
4157
|
-
delete actual.version;
|
|
4158
|
-
if (!Object.hasOwn(expected, "name") && typeof actual.name === "string" && /^[a-z0-9][a-z0-9._-]{0,99}$/iu.test(actual.name))
|
|
4159
|
-
delete actual.name;
|
|
4160
|
-
if (isDeepStrictEqual(actual, expected))
|
|
4161
|
-
continue;
|
|
4162
|
-
} catch {
|
|
4163
|
-
}
|
|
4164
|
-
}
|
|
4165
|
-
throw new Error(`A deployed file ${JSON.stringify(entry.path).slice(0, 260)} differs from the committed upload.`);
|
|
4166
|
-
}
|
|
4167
|
-
}
|
|
4168
|
-
return record.revision;
|
|
4169
|
-
}
|
|
4170
|
-
function treeHash(entries) {
|
|
4171
|
-
const root = /* @__PURE__ */ new Map();
|
|
4172
|
-
for (const entry of entries) {
|
|
4173
|
-
const parts = entry.path.split("/");
|
|
4174
|
-
if (parts.some((part) => !part || part === "." || part === ".." || part.includes("\0") || part.includes("\\")))
|
|
4175
|
-
throw new Error("Unsafe Git inventory path.");
|
|
4176
|
-
let tree = root;
|
|
4177
|
-
for (const part of parts.slice(0, -1)) {
|
|
4178
|
-
let child = tree.get(part);
|
|
4179
|
-
if (!child) {
|
|
4180
|
-
child = /* @__PURE__ */ new Map();
|
|
4181
|
-
tree.set(part, child);
|
|
4182
|
-
}
|
|
4183
|
-
if (!(child instanceof Map))
|
|
4184
|
-
throw new Error("Conflicting Git inventory path.");
|
|
4185
|
-
tree = child;
|
|
4186
|
-
}
|
|
4187
|
-
const leaf = parts.at(-1);
|
|
4188
|
-
if (tree.has(leaf))
|
|
4189
|
-
throw new Error("Duplicate Git inventory path.");
|
|
4190
|
-
tree.set(leaf, { mode: entry.mode, oid: entry.oid });
|
|
4191
|
-
}
|
|
4192
|
-
const hash2 = (tree) => {
|
|
4193
|
-
const sorted = [...tree].sort(([a, av], [b, bv]) => Buffer.compare(Buffer.from(a + (av instanceof Map ? "/" : "")), Buffer.from(b + (bv instanceof Map ? "/" : ""))));
|
|
4194
|
-
return gitHash("tree", Buffer.concat(sorted.map(([path, value]) => Buffer.concat([
|
|
4195
|
-
Buffer.from(`${value instanceof Map ? "40000" : value.mode} ${path}\0`),
|
|
4196
|
-
Buffer.from(value instanceof Map ? hash2(value) : value.oid, "hex")
|
|
4197
|
-
]))));
|
|
4198
|
-
};
|
|
4199
|
-
return hash2(root);
|
|
4200
|
-
}
|
|
4201
|
-
|
|
4202
|
-
// ../cli/dist/commands/setup-deploy.js
|
|
4203
|
-
import { createHash as createHash4, randomBytes as randomBytes2, randomUUID as randomUUID7 } from "crypto";
|
|
4204
|
-
import { access as access7, mkdir as mkdir9, mkdtemp, rm as rm5, writeFile as writeFile6 } from "fs/promises";
|
|
4205
|
-
import { tmpdir } from "os";
|
|
4206
|
-
import { join as join13 } from "path";
|
|
4207
|
-
import { z as z41 } from "zod";
|
|
4208
|
-
var envSchema = z41.object({
|
|
4209
|
-
id: z41.string(),
|
|
4210
|
-
key: z41.string(),
|
|
4211
|
-
target: z41.array(z41.string()),
|
|
4212
|
-
type: z41.string(),
|
|
4213
|
-
comment: z41.string().optional(),
|
|
4214
|
-
updatedAt: z41.number().optional()
|
|
4215
|
-
});
|
|
4216
|
-
var deploymentSchema = z41.object({
|
|
4217
|
-
id: z41.string(),
|
|
4218
|
-
projectId: z41.string(),
|
|
4219
|
-
ownerId: z41.string().optional(),
|
|
4220
|
-
target: z41.string().nullable(),
|
|
4221
|
-
readyState: z41.string(),
|
|
4222
|
-
createdAt: z41.number(),
|
|
4223
|
-
url: z41.string(),
|
|
4224
|
-
meta: z41.record(z41.string(), z41.unknown()).optional(),
|
|
4225
|
-
gitSource: z41.object({ sha: z41.string().optional() }).nullable().optional()
|
|
4226
|
-
});
|
|
4227
|
-
var buildProofSchema = z41.object({
|
|
4228
|
-
node: z41.string(),
|
|
4229
|
-
packageManager: z41.enum(["npm", "pnpm"]),
|
|
4230
|
-
packageManagerVersion: z41.string(),
|
|
4231
|
-
lockfileHash: z41.string(),
|
|
4232
|
-
revision: z41.string(),
|
|
4233
|
-
fieldContractHash: z41.string(),
|
|
4234
|
-
siteplane: z41.string(),
|
|
4235
|
-
runtimeNext: z41.string(),
|
|
4236
|
-
analytics: z41.string().optional(),
|
|
4237
|
-
next: z41.string(),
|
|
4238
|
-
react: z41.string()
|
|
4239
|
-
}).strict();
|
|
4240
|
-
var defaults = {
|
|
4241
|
-
preflight: setupPreflightCommand,
|
|
4242
|
-
context: siteSetupContextCommand,
|
|
4243
|
-
api: setupVercelApi,
|
|
4244
|
-
process: setupProcess,
|
|
4245
|
-
verify: siteSetupVerifyCommand,
|
|
4246
|
-
post: postSiteSetup,
|
|
4247
|
-
writeBuildProvenance,
|
|
4248
|
-
analyticsPublicKey: analyticsPublicKeyCommand,
|
|
4249
|
-
now: Date.now,
|
|
4250
|
-
pause: (milliseconds) => new Promise((resolve5) => setTimeout(resolve5, milliseconds))
|
|
4251
|
-
};
|
|
4252
|
-
|
|
4253
|
-
// ../cli/dist/commands/setup-claim.js
|
|
4254
|
-
import { z as z42 } from "zod";
|
|
4255
|
-
|
|
4256
2628
|
// src/next.ts
|
|
4257
2629
|
var SiteplaneNextContractError = class extends Error {
|
|
4258
2630
|
constructor(code, message) {
|
|
@@ -4263,14 +2635,14 @@ var SiteplaneNextContractError = class extends Error {
|
|
|
4263
2635
|
code;
|
|
4264
2636
|
};
|
|
4265
2637
|
async function scanNextProjectFieldContract(projectDir) {
|
|
4266
|
-
const resolvedProjectDir =
|
|
2638
|
+
const resolvedProjectDir = resolve(projectDir);
|
|
4267
2639
|
const filePaths = await resolveScanFilePaths([], {
|
|
4268
2640
|
projectDir: resolvedProjectDir
|
|
4269
2641
|
});
|
|
4270
2642
|
const files = await Promise.all(
|
|
4271
2643
|
filePaths.map(async (filePath) => ({
|
|
4272
2644
|
filePath,
|
|
4273
|
-
sourceText: await
|
|
2645
|
+
sourceText: await readFile5(filePath, "utf8")
|
|
4274
2646
|
}))
|
|
4275
2647
|
);
|
|
4276
2648
|
const result = scanNextSourceFilesToSiteFieldContract(files, {
|
|
@@ -4299,7 +2671,7 @@ async function withSiteplane(nextConfig, options = {}) {
|
|
|
4299
2671
|
"Siteplane booking.site must be the Site ID from Booking settings."
|
|
4300
2672
|
);
|
|
4301
2673
|
for (const folder of ["app/booking", "src/app/booking"]) {
|
|
4302
|
-
if (await
|
|
2674
|
+
if (await access2(join6(projectDir, folder)).then(
|
|
4303
2675
|
() => true,
|
|
4304
2676
|
() => false
|
|
4305
2677
|
))
|
|
@@ -4329,34 +2701,13 @@ async function withSiteplane(nextConfig, options = {}) {
|
|
|
4329
2701
|
};
|
|
4330
2702
|
}
|
|
4331
2703
|
};
|
|
4332
|
-
|
|
4333
|
-
join14(projectDir, "siteplane.config.json")
|
|
4334
|
-
).then(
|
|
4335
|
-
() => true,
|
|
4336
|
-
() => false
|
|
4337
|
-
);
|
|
4338
|
-
if (!hasEditor) return { ...integrated, env: { ...nextConfig.env } };
|
|
2704
|
+
return { ...integrated, env: { ...nextConfig.env } };
|
|
4339
2705
|
}
|
|
4340
2706
|
const config = await readProjectConfig(projectDir);
|
|
4341
2707
|
const scan = await scanNextProjectFieldContract(projectDir);
|
|
4342
2708
|
const requestedRevision = options.buildRevision?.trim() || process.env.SITEPLANE_BUILD_REVISION?.trim();
|
|
4343
2709
|
const providerRevision = process.env.VERCEL === "1" ? process.env.VERCEL_GIT_COMMIT_SHA?.trim() : void 0;
|
|
4344
|
-
const buildRevision = providerRevision || await
|
|
4345
|
-
if (process.env.VERCEL === "1" && /^[0-9a-f]{40}$/u.test(buildRevision)) {
|
|
4346
|
-
try {
|
|
4347
|
-
await emitBuildProof(
|
|
4348
|
-
projectDir,
|
|
4349
|
-
config.packages,
|
|
4350
|
-
buildRevision,
|
|
4351
|
-
scan.fieldContractHash
|
|
4352
|
-
);
|
|
4353
|
-
} catch (error) {
|
|
4354
|
-
const detail = error instanceof SiteplaneNextContractError ? error.code : "unavailable";
|
|
4355
|
-
console.warn(
|
|
4356
|
-
`[Siteplane] Build proof ${detail}; the website build continues. Run the scoped Siteplane setup verification when editor evidence must be refreshed.`
|
|
4357
|
-
);
|
|
4358
|
-
}
|
|
4359
|
-
}
|
|
2710
|
+
const buildRevision = providerRevision || await readGitRevision(projectDir) || requestedRevision || "local";
|
|
4360
2711
|
const hasImages = scan.contract.fields.some(
|
|
4361
2712
|
(field) => field.fieldType === "image"
|
|
4362
2713
|
);
|
|
@@ -4377,10 +2728,10 @@ async function withSiteplane(nextConfig, options = {}) {
|
|
|
4377
2728
|
}
|
|
4378
2729
|
};
|
|
4379
2730
|
}
|
|
4380
|
-
var
|
|
4381
|
-
async function
|
|
2731
|
+
var execFileAsync = promisify(execFile);
|
|
2732
|
+
async function readGitRevision(projectDir) {
|
|
4382
2733
|
try {
|
|
4383
|
-
const result = await
|
|
2734
|
+
const result = await execFileAsync("git", ["rev-parse", "HEAD"], {
|
|
4384
2735
|
cwd: projectDir
|
|
4385
2736
|
});
|
|
4386
2737
|
return result.stdout.trim();
|
|
@@ -4392,19 +2743,19 @@ function frameHeaders(rules, adminOrigin, imageOrigin) {
|
|
|
4392
2743
|
const policy = `frame-ancestors 'self' ${adminOrigin}`;
|
|
4393
2744
|
const hasFrameOptions = rules.some(
|
|
4394
2745
|
(rule) => rule.headers.some(
|
|
4395
|
-
(
|
|
2746
|
+
(header2) => header2.key.toLowerCase() === "x-frame-options"
|
|
4396
2747
|
)
|
|
4397
2748
|
);
|
|
4398
2749
|
const prepared = rules.map((rule) => ({
|
|
4399
2750
|
...rule,
|
|
4400
|
-
headers: rule.headers.map((
|
|
4401
|
-
if (
|
|
2751
|
+
headers: rule.headers.map((header2) => {
|
|
2752
|
+
if (header2.key.toLowerCase() !== "content-security-policy") return header2;
|
|
4402
2753
|
const ancestors = /(?:^|;)\s*frame-ancestors\s+([^;]+)/iu.test(
|
|
4403
|
-
|
|
2754
|
+
header2.value
|
|
4404
2755
|
);
|
|
4405
|
-
const value = ancestors || hasFrameOptions ?
|
|
2756
|
+
const value = ancestors || hasFrameOptions ? header2.value : `${header2.value.replace(/;\s*$/u, "")}; ${policy}`;
|
|
4406
2757
|
return {
|
|
4407
|
-
...
|
|
2758
|
+
...header2,
|
|
4408
2759
|
value: imageOrigin ? prepareImageCsp(value, imageOrigin) : value
|
|
4409
2760
|
};
|
|
4410
2761
|
})
|
|
@@ -4429,7 +2780,7 @@ function readImageWebsiteOrigin() {
|
|
|
4429
2780
|
} catch {
|
|
4430
2781
|
throw new SiteplaneNextContractError(
|
|
4431
2782
|
"image_origin_missing",
|
|
4432
|
-
"If configured, SITEPLANE_SITE_ORIGIN must be the exact public HTTPS website origin
|
|
2783
|
+
"If configured, SITEPLANE_SITE_ORIGIN must be the exact public HTTPS website origin; local fallback-image builds can omit it. Never substitute a wildcard or private host."
|
|
4433
2784
|
);
|
|
4434
2785
|
}
|
|
4435
2786
|
}
|
|
@@ -4470,14 +2821,14 @@ function prepareImageCsp(policy, websiteOrigin) {
|
|
|
4470
2821
|
"Split combined CSP policies into separate header rules before image preparation; preserve every existing directive."
|
|
4471
2822
|
);
|
|
4472
2823
|
const directives = policy.split(";").map((part) => part.trim()).filter(Boolean);
|
|
4473
|
-
const find = (
|
|
4474
|
-
const image = find("img-src"),
|
|
4475
|
-
if (image.length > 1 ||
|
|
2824
|
+
const find = (name) => directives.map((part, index) => ({ index, tokens: part.split(/\s+/u) })).filter((part) => part.tokens[0]?.toLowerCase() === name);
|
|
2825
|
+
const image = find("img-src"), defaults = find("default-src");
|
|
2826
|
+
if (image.length > 1 || defaults.length > 1)
|
|
4476
2827
|
throw new SiteplaneNextContractError(
|
|
4477
2828
|
"image_policy_conflict",
|
|
4478
2829
|
"Remove ambiguous duplicate img-src/default-src directives before image preparation without changing unrelated policies."
|
|
4479
2830
|
);
|
|
4480
|
-
const existing = image[0] ??
|
|
2831
|
+
const existing = image[0] ?? defaults[0];
|
|
4481
2832
|
if (!existing) return policy;
|
|
4482
2833
|
const sources = existing.tokens.slice(1).filter((source) => source !== "'none'");
|
|
4483
2834
|
for (const source of [
|
|
@@ -4492,53 +2843,6 @@ function prepareImageCsp(policy, websiteOrigin) {
|
|
|
4492
2843
|
else directives.push(value);
|
|
4493
2844
|
return directives.join("; ");
|
|
4494
2845
|
}
|
|
4495
|
-
async function emitBuildProof(projectDir, packages, revision, fieldContractHash) {
|
|
4496
|
-
const [cli, runtime, next, react] = await Promise.all(
|
|
4497
|
-
["siteplane", "@siteplane/runtime-next", "next", "react"].map(
|
|
4498
|
-
(name2) => readInstalledPackage(projectDir, name2)
|
|
4499
|
-
)
|
|
4500
|
-
);
|
|
4501
|
-
const analytics = packages.analytics ? await readInstalledPackage(projectDir, "@siteplane/analytics") : void 0;
|
|
4502
|
-
if (analytics?.version !== packages.analytics || cli.version !== packages.siteplane || runtime.version !== packages.runtimeNext)
|
|
4503
|
-
throw new SiteplaneNextContractError(
|
|
4504
|
-
"build_identity_missing",
|
|
4505
|
-
"The provider installed different Siteplane package versions than the task requires."
|
|
4506
|
-
);
|
|
4507
|
-
const executable = process.env.npm_execpath;
|
|
4508
|
-
if (!executable)
|
|
4509
|
-
throw new SiteplaneNextContractError(
|
|
4510
|
-
"build_identity_missing",
|
|
4511
|
-
"Run the provider build through the selected npm/pnpm executable so its actual version can be verified."
|
|
4512
|
-
);
|
|
4513
|
-
const packageManager = /pnpm/iu.test(executable) ? "pnpm" : "npm";
|
|
4514
|
-
const packageManagerVersion = (await execFileAsync3(process.execPath, [executable, "--version"], {
|
|
4515
|
-
cwd: projectDir
|
|
4516
|
-
})).stdout.trim();
|
|
4517
|
-
let directory = resolve4(projectDir);
|
|
4518
|
-
let lock = null;
|
|
4519
|
-
while (true) {
|
|
4520
|
-
lock = await readFile13(
|
|
4521
|
-
join14(
|
|
4522
|
-
directory,
|
|
4523
|
-
packageManager === "npm" ? "package-lock.json" : "pnpm-lock.yaml"
|
|
4524
|
-
),
|
|
4525
|
-
"utf8"
|
|
4526
|
-
).catch((error) => {
|
|
4527
|
-
if (error.code === "ENOENT") return null;
|
|
4528
|
-
throw error;
|
|
4529
|
-
});
|
|
4530
|
-
if (lock !== null || dirname10(directory) === directory) break;
|
|
4531
|
-
directory = dirname10(directory);
|
|
4532
|
-
}
|
|
4533
|
-
if (!lock)
|
|
4534
|
-
throw new SiteplaneNextContractError(
|
|
4535
|
-
"build_identity_missing",
|
|
4536
|
-
"The provider build is missing the selected canonical lockfile."
|
|
4537
|
-
);
|
|
4538
|
-
console.info(
|
|
4539
|
-
`SITEPLANE_BUILD_PROOF=${JSON.stringify({ node: process.versions.node, packageManager, packageManagerVersion, lockfileHash: `sha256:${createHash5("sha256").update(lock).digest("hex")}`, revision, fieldContractHash, siteplane: cli.version, runtimeNext: runtime.version, ...analytics ? { analytics: analytics.version } : {}, next: next.version, react: react.version })}`
|
|
4540
|
-
);
|
|
4541
|
-
}
|
|
4542
2846
|
export {
|
|
4543
2847
|
SiteplaneNextContractError,
|
|
4544
2848
|
scanNextProjectFieldContract,
|