riverbankcms 0.22.2 → 0.23.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/acceptance/matrix.mjs +3 -3
- package/dist/cli/index.mjs +1842 -1205
- package/dist/cli/init-docs/content/cli-reference.md +2 -2
- package/dist/cli/init-docs/content/content-management.md +1 -1
- package/dist/cli/init-docs/content/workflow-custom-block.md +4 -4
- package/dist/cli/init-docs/content/workflow-publish.md +11 -5
- package/dist/{entryCommands-BGVgMNMw.mjs → entryCommands-BdN5YrqI.mjs} +242 -170
- package/dist/{eventUpsertInputSchema-CdX--hHz.mjs → eventUpsertInputSchema-kp-U13TZ.mjs} +70 -32
- package/dist/load-config-C7Rd822n.mjs +4 -0
- package/dist/{load-config-BV9Ig2CH.mjs → load-config-D5DDfmv1.mjs} +2 -2
- package/dist/{plan-CFMj_Hee.mjs → plan-6m8gsGI8.mjs} +1 -1
- package/dist/scaffold/index.mjs +2 -2
- package/dist/{sdk-event-upsert-zWw5VolM.mjs → sdk-event-upsert-BnBxyTR6.mjs} +486 -122
- package/dist/{src-ZACBG29u.mjs → src-BPh_OivC.mjs} +463 -85
- package/dist/testing.mjs +4 -4
- package/package.json +1 -1
- package/dist/load-config-JWz__Dkx.mjs +0 -4
|
@@ -52,6 +52,7 @@ const unsafeAsPageId = (id) => id;
|
|
|
52
52
|
const unsafeAsPageSurfaceId = (id) => id;
|
|
53
53
|
const unsafeAsEditLeaseToken = (id) => id;
|
|
54
54
|
const unsafeAsEditorClientId = (id) => id;
|
|
55
|
+
const unsafeAsPageDocumentCheckpointId = (id) => id;
|
|
55
56
|
const unsafeAsOccurrenceId = (id) => id;
|
|
56
57
|
const unsafeAsEventOfferingId = (id) => id;
|
|
57
58
|
const unsafeAsEventSeriesId = (id) => id;
|
|
@@ -166,6 +167,7 @@ const parsePageId = (value) => parseUuidBrand(value, unsafeAsPageId);
|
|
|
166
167
|
const parsePageSurfaceId = (value) => parseUuidBrand(value, unsafeAsPageSurfaceId);
|
|
167
168
|
const parseEditLeaseToken = (value) => parseUuidBrand(value, unsafeAsEditLeaseToken);
|
|
168
169
|
const parseEditorClientId = (value) => parseUuidBrand(value, unsafeAsEditorClientId);
|
|
170
|
+
const parsePageDocumentCheckpointId = (value) => parseUuidBrand(value, unsafeAsPageDocumentCheckpointId);
|
|
169
171
|
const parseOccurrenceId = (value) => parseUuidBrand(value, unsafeAsOccurrenceId);
|
|
170
172
|
const parseEventOfferingId = (value) => parseUuidBrand(value, unsafeAsEventOfferingId);
|
|
171
173
|
const parseEventAttendeeTicketLineId = (value) => parseUuidBrand(value, unsafeAsEventAttendeeTicketLineId);
|
|
@@ -1385,7 +1387,7 @@ function parseEventPageSurfaceDestinationMode(value) {
|
|
|
1385
1387
|
return value === "cms-managed" || value === "system-managed" ? value : undefined;
|
|
1386
1388
|
}
|
|
1387
1389
|
function parseEventPageSurfaceSubject(value) {
|
|
1388
|
-
if (!isRecord$
|
|
1390
|
+
if (!isRecord$10(value)) return err({ kind: "notObject" });
|
|
1389
1391
|
const parsed = value.kind === "eventSeries" ? parseEventSeriesPageSurfaceSubject(value) : value.kind === "eventOffering" ? parseEventOfferingPageSurfaceSubject(value) : err({
|
|
1390
1392
|
kind: "unsupportedSubject",
|
|
1391
1393
|
subjectKind: value.kind
|
|
@@ -1458,7 +1460,7 @@ function parseEventSeriesIdList(values) {
|
|
|
1458
1460
|
}
|
|
1459
1461
|
return ok(parsed);
|
|
1460
1462
|
}
|
|
1461
|
-
function isRecord$
|
|
1463
|
+
function isRecord$10(value) {
|
|
1462
1464
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
1463
1465
|
}
|
|
1464
1466
|
|
|
@@ -3111,28 +3113,6 @@ const RECTIFICATION_HISTORY_PROPAGATION_PLANS = {
|
|
|
3111
3113
|
blocked_immutable_history: { kind: "blocked_immutable_history" }
|
|
3112
3114
|
};
|
|
3113
3115
|
|
|
3114
|
-
//#endregion
|
|
3115
|
-
//#region ../core/src/location.ts
|
|
3116
|
-
function normalizeLocationAddressText(value) {
|
|
3117
|
-
if (typeof value !== "string") {
|
|
3118
|
-
return null;
|
|
3119
|
-
}
|
|
3120
|
-
const trimmed = value.trim();
|
|
3121
|
-
return trimmed.length > 0 ? trimmed : null;
|
|
3122
|
-
}
|
|
3123
|
-
function hasLocationCoordinates(value) {
|
|
3124
|
-
return value != null && typeof value.lat === "number" && typeof value.lng === "number";
|
|
3125
|
-
}
|
|
3126
|
-
function toLocationCoordinates(value) {
|
|
3127
|
-
if (!hasLocationCoordinates(value)) {
|
|
3128
|
-
return null;
|
|
3129
|
-
}
|
|
3130
|
-
return {
|
|
3131
|
-
lat: value.lat,
|
|
3132
|
-
lng: value.lng
|
|
3133
|
-
};
|
|
3134
|
-
}
|
|
3135
|
-
|
|
3136
3116
|
//#endregion
|
|
3137
3117
|
//#region ../core/src/string.ts
|
|
3138
3118
|
/**
|
|
@@ -3182,6 +3162,363 @@ function capitalize(str) {
|
|
|
3182
3162
|
return str.charAt(0).toUpperCase() + str.slice(1);
|
|
3183
3163
|
}
|
|
3184
3164
|
|
|
3165
|
+
//#endregion
|
|
3166
|
+
//#region ../core/src/location.ts
|
|
3167
|
+
/** One complete, finite, bounded arrival pin; zero is a valid coordinate. */
|
|
3168
|
+
const locationPinSchema = z.strictObject({
|
|
3169
|
+
lat: z.number().min(-90).max(90),
|
|
3170
|
+
lng: z.number().min(-180).max(180)
|
|
3171
|
+
}).readonly().brand();
|
|
3172
|
+
const addressPart = z.string().trim().max(200).nullish().transform((value) => trimmedStringOrNull(value));
|
|
3173
|
+
/** Building identifies the place; unit/floor refine it without moving it. */
|
|
3174
|
+
const locationAddressSchema = z.strictObject({
|
|
3175
|
+
building: addressPart,
|
|
3176
|
+
unit: addressPart,
|
|
3177
|
+
floor: addressPart,
|
|
3178
|
+
street: addressPart,
|
|
3179
|
+
locality: addressPart,
|
|
3180
|
+
region: addressPart,
|
|
3181
|
+
postalCode: addressPart,
|
|
3182
|
+
country: addressPart.transform((value) => value?.length === 2 ? value.toUpperCase() : value)
|
|
3183
|
+
}).readonly().transform((address) => Object.values(address).some((part) => part !== null) ? address : null);
|
|
3184
|
+
const locationAddressMatchSchema = z.strictObject({
|
|
3185
|
+
point: locationPinSchema,
|
|
3186
|
+
precision: z.enum([
|
|
3187
|
+
"building",
|
|
3188
|
+
"street",
|
|
3189
|
+
"area",
|
|
3190
|
+
"unknown"
|
|
3191
|
+
]),
|
|
3192
|
+
placeId: z.string().trim().max(1024).regex(/^[a-z][a-z0-9-]*:\S+$/),
|
|
3193
|
+
attribution: z.array(z.strictObject({
|
|
3194
|
+
text: z.string().trim().min(1).max(500),
|
|
3195
|
+
url: z.url().max(2048).refine((value) => /^https?:\/\//.test(value))
|
|
3196
|
+
}).readonly()).min(1).max(4).readonly()
|
|
3197
|
+
}).readonly();
|
|
3198
|
+
const locationValueSchema = z.strictObject({
|
|
3199
|
+
address: locationAddressSchema.nullable().default(null),
|
|
3200
|
+
pin: locationPinSchema.nullable().default(null),
|
|
3201
|
+
doorNote: z.string().trim().max(1e3).nullish().transform(trimmedStringOrNull),
|
|
3202
|
+
addressMatch: locationAddressMatchSchema.nullable().default(null),
|
|
3203
|
+
ownerConfirmedPinAndAddress: z.boolean().default(false)
|
|
3204
|
+
}).superRefine((value, context) => {
|
|
3205
|
+
if (value.address === null && value.pin === null) {
|
|
3206
|
+
context.addIssue({
|
|
3207
|
+
code: "custom",
|
|
3208
|
+
path: ["address"],
|
|
3209
|
+
message: "Use null to remove a location."
|
|
3210
|
+
});
|
|
3211
|
+
}
|
|
3212
|
+
if (value.address === null && value.addressMatch !== null) {
|
|
3213
|
+
context.addIssue({
|
|
3214
|
+
code: "custom",
|
|
3215
|
+
path: ["addressMatch"],
|
|
3216
|
+
message: "Address evidence requires an address."
|
|
3217
|
+
});
|
|
3218
|
+
}
|
|
3219
|
+
if (value.ownerConfirmedPinAndAddress && (value.address === null || value.pin === null)) {
|
|
3220
|
+
context.addIssue({
|
|
3221
|
+
code: "custom",
|
|
3222
|
+
path: ["ownerConfirmedPinAndAddress"],
|
|
3223
|
+
message: "Confirmation requires both address and pin."
|
|
3224
|
+
});
|
|
3225
|
+
}
|
|
3226
|
+
}).readonly();
|
|
3227
|
+
/** API/DB ingress parses once. Removed locations are represented by null. */
|
|
3228
|
+
function parseLocationValue(input) {
|
|
3229
|
+
const parsed = locationValueSchema.nullable().safeParse(input);
|
|
3230
|
+
return parsed.success ? ok(parsed.data) : err({
|
|
3231
|
+
kind: "invalid_location",
|
|
3232
|
+
issues: parsed.error.issues
|
|
3233
|
+
});
|
|
3234
|
+
}
|
|
3235
|
+
function formatLocationAddress(address) {
|
|
3236
|
+
if (address === null) return null;
|
|
3237
|
+
const parts = [
|
|
3238
|
+
address.building,
|
|
3239
|
+
address.street,
|
|
3240
|
+
address.unit,
|
|
3241
|
+
address.floor,
|
|
3242
|
+
address.locality,
|
|
3243
|
+
address.region,
|
|
3244
|
+
address.postalCode,
|
|
3245
|
+
address.country
|
|
3246
|
+
];
|
|
3247
|
+
return parts.filter((part) => part !== null).join(", ") || null;
|
|
3248
|
+
}
|
|
3249
|
+
/** Permission belongs to the resource/source owner before this projection. */
|
|
3250
|
+
function projectPublicLocation(location) {
|
|
3251
|
+
return {
|
|
3252
|
+
address: location.address,
|
|
3253
|
+
displayAddress: formatLocationAddress(location.address),
|
|
3254
|
+
pin: location.pin,
|
|
3255
|
+
doorNote: location.doorNote,
|
|
3256
|
+
attribution: location.addressMatch?.attribution ?? []
|
|
3257
|
+
};
|
|
3258
|
+
}
|
|
3259
|
+
function normalizeLocationAddressText(value) {
|
|
3260
|
+
if (typeof value !== "string") {
|
|
3261
|
+
return null;
|
|
3262
|
+
}
|
|
3263
|
+
return trimmedStringOrNull(value);
|
|
3264
|
+
}
|
|
3265
|
+
function hasLocationCoordinates(value) {
|
|
3266
|
+
return value != null && typeof value.lat === "number" && Number.isFinite(value.lat) && Math.abs(value.lat) <= 90 && typeof value.lng === "number" && Number.isFinite(value.lng) && Math.abs(value.lng) <= 180;
|
|
3267
|
+
}
|
|
3268
|
+
function toLocationCoordinates(value) {
|
|
3269
|
+
if (!hasLocationCoordinates(value)) {
|
|
3270
|
+
return null;
|
|
3271
|
+
}
|
|
3272
|
+
return {
|
|
3273
|
+
lat: value.lat,
|
|
3274
|
+
lng: value.lng
|
|
3275
|
+
};
|
|
3276
|
+
}
|
|
3277
|
+
|
|
3278
|
+
//#endregion
|
|
3279
|
+
//#region ../core/src/location-relationship.ts
|
|
3280
|
+
/** Initial bounded policy; Opus can tune these values without changing callers. */
|
|
3281
|
+
const LOCATION_MATCH_THRESHOLDS_METRES = {
|
|
3282
|
+
building: 100,
|
|
3283
|
+
street: 300,
|
|
3284
|
+
area: 1e3
|
|
3285
|
+
};
|
|
3286
|
+
function locationDistanceMetres(a, b) {
|
|
3287
|
+
const radians = Math.PI / 180;
|
|
3288
|
+
const haversine = Math.sin((b.lat - a.lat) * radians / 2) ** 2 + Math.cos(a.lat * radians) * Math.cos(b.lat * radians) * Math.sin((b.lng - a.lng) * radians / 2) ** 2;
|
|
3289
|
+
return 6371e3 * 2 * Math.asin(Math.sqrt(Math.min(1, Math.max(0, haversine))));
|
|
3290
|
+
}
|
|
3291
|
+
/** Arrival pins are never substituted for missing provider address points. */
|
|
3292
|
+
function decideLocationRelationship(location) {
|
|
3293
|
+
if (location === null) return { kind: "empty" };
|
|
3294
|
+
if (location.pin === null) return { kind: "address_only" };
|
|
3295
|
+
if (location.address === null) return { kind: "pin_only" };
|
|
3296
|
+
if (location.addressMatch === null || location.addressMatch.precision === "unknown") {
|
|
3297
|
+
return { kind: "unchecked" };
|
|
3298
|
+
}
|
|
3299
|
+
const { point, precision } = location.addressMatch;
|
|
3300
|
+
const distanceMetres = locationDistanceMetres(point, location.pin);
|
|
3301
|
+
const thresholdMetres = LOCATION_MATCH_THRESHOLDS_METRES[precision];
|
|
3302
|
+
const beyondThreshold = distanceMetres > thresholdMetres * (1 + 8 * Number.EPSILON);
|
|
3303
|
+
return {
|
|
3304
|
+
kind: beyondThreshold ? "far" : precision === "building" ? "near" : "approximate",
|
|
3305
|
+
distanceMetres,
|
|
3306
|
+
thresholdMetres,
|
|
3307
|
+
precision
|
|
3308
|
+
};
|
|
3309
|
+
}
|
|
3310
|
+
const spatialAddressParts = [
|
|
3311
|
+
"building",
|
|
3312
|
+
"street",
|
|
3313
|
+
"locality",
|
|
3314
|
+
"postalCode",
|
|
3315
|
+
"country"
|
|
3316
|
+
];
|
|
3317
|
+
const comparisonText = (text) => (text ?? "").trim().replace(/\s+/g, " ").toLowerCase();
|
|
3318
|
+
function sameMeaningfulAddress(a, b) {
|
|
3319
|
+
if (a === null || b === null) return a === b;
|
|
3320
|
+
return spatialAddressParts.every((part) => comparisonText(a[part]) === comparisonText(b[part]));
|
|
3321
|
+
}
|
|
3322
|
+
function samePin(a, b) {
|
|
3323
|
+
return a === null || b === null ? a === b : a.lat === b.lat && a.lng === b.lng;
|
|
3324
|
+
}
|
|
3325
|
+
/** Edits cannot carry forward old confirmation or address evidence by accident. */
|
|
3326
|
+
function editLocationValue(previous, details) {
|
|
3327
|
+
if (details.address === null && details.pin === null) return ok(null);
|
|
3328
|
+
if (previous === null) {
|
|
3329
|
+
return parseLocationValue({
|
|
3330
|
+
...details,
|
|
3331
|
+
addressMatch: null,
|
|
3332
|
+
ownerConfirmedPinAndAddress: false
|
|
3333
|
+
});
|
|
3334
|
+
}
|
|
3335
|
+
const sameAddress = sameMeaningfulAddress(previous.address, details.address);
|
|
3336
|
+
const samePair = sameAddress && samePin(previous.pin, details.pin);
|
|
3337
|
+
return parseLocationValue({
|
|
3338
|
+
...details,
|
|
3339
|
+
addressMatch: sameAddress ? previous.addressMatch : null,
|
|
3340
|
+
ownerConfirmedPinAndAddress: samePair && previous.ownerConfirmedPinAndAddress
|
|
3341
|
+
});
|
|
3342
|
+
}
|
|
3343
|
+
function confirmLocationPair(location) {
|
|
3344
|
+
return location.address !== null && location.pin !== null ? ok({
|
|
3345
|
+
...location,
|
|
3346
|
+
ownerConfirmedPinAndAddress: true
|
|
3347
|
+
}) : err({ kind: "missing_address_or_pin" });
|
|
3348
|
+
}
|
|
3349
|
+
/** Forms receive the decided save value, rather than a collection of flags. */
|
|
3350
|
+
function decideLocationSave(location, activity) {
|
|
3351
|
+
if (activity === "address-check") return {
|
|
3352
|
+
kind: "blocked",
|
|
3353
|
+
reason: "pending_address_check"
|
|
3354
|
+
};
|
|
3355
|
+
if (activity === "reverse") return {
|
|
3356
|
+
kind: "blocked",
|
|
3357
|
+
reason: "pending_reverse"
|
|
3358
|
+
};
|
|
3359
|
+
const relationship = decideLocationRelationship(location);
|
|
3360
|
+
return relationship.kind === "far" && location?.ownerConfirmedPinAndAddress !== true ? {
|
|
3361
|
+
kind: "blocked",
|
|
3362
|
+
reason: "unconfirmed_mismatch"
|
|
3363
|
+
} : {
|
|
3364
|
+
kind: "ready",
|
|
3365
|
+
location
|
|
3366
|
+
};
|
|
3367
|
+
}
|
|
3368
|
+
|
|
3369
|
+
//#endregion
|
|
3370
|
+
//#region ../core/src/location-migration.ts
|
|
3371
|
+
/** Offline expand/contract conversions, not runtime fallback readers. */
|
|
3372
|
+
const legacyText = z.string().nullable().optional();
|
|
3373
|
+
const legacyCoordinatesSchema = z.strictObject({
|
|
3374
|
+
lat: z.number().min(-90).max(90).nullable().optional(),
|
|
3375
|
+
lng: z.number().min(-180).max(180).nullable().optional()
|
|
3376
|
+
}).superRefine((value, context) => {
|
|
3377
|
+
if (value.lat == null !== (value.lng == null)) {
|
|
3378
|
+
context.addIssue({
|
|
3379
|
+
code: "custom",
|
|
3380
|
+
message: "Legacy pin is incomplete."
|
|
3381
|
+
});
|
|
3382
|
+
}
|
|
3383
|
+
});
|
|
3384
|
+
const venueAddressSchema = z.strictObject({
|
|
3385
|
+
street: legacyText,
|
|
3386
|
+
line1: legacyText,
|
|
3387
|
+
line2: legacyText,
|
|
3388
|
+
city: legacyText,
|
|
3389
|
+
state: legacyText,
|
|
3390
|
+
region: legacyText,
|
|
3391
|
+
postalCode: legacyText,
|
|
3392
|
+
postal_code: legacyText,
|
|
3393
|
+
postcode: legacyText,
|
|
3394
|
+
country: legacyText,
|
|
3395
|
+
formatted: legacyText,
|
|
3396
|
+
summary: legacyText
|
|
3397
|
+
}).superRefine((value, context) => {
|
|
3398
|
+
const aliases = [
|
|
3399
|
+
[value.street, value.line1],
|
|
3400
|
+
[value.state, value.region],
|
|
3401
|
+
[
|
|
3402
|
+
value.postalCode,
|
|
3403
|
+
value.postal_code,
|
|
3404
|
+
value.postcode
|
|
3405
|
+
],
|
|
3406
|
+
[value.formatted, value.summary]
|
|
3407
|
+
];
|
|
3408
|
+
aliases.forEach((parts) => {
|
|
3409
|
+
const meaningful = parts.filter((part) => displayComparison(part) !== "");
|
|
3410
|
+
if (meaningful.some((part) => displayComparison(part) !== displayComparison(meaningful[0]))) {
|
|
3411
|
+
context.addIssue({
|
|
3412
|
+
code: "custom",
|
|
3413
|
+
message: "Legacy address aliases disagree."
|
|
3414
|
+
});
|
|
3415
|
+
}
|
|
3416
|
+
});
|
|
3417
|
+
}).nullable();
|
|
3418
|
+
const businessAddressSchema = legacyCoordinatesSchema.safeExtend({
|
|
3419
|
+
addressLine1: legacyText,
|
|
3420
|
+
addressLine2: legacyText,
|
|
3421
|
+
locality: legacyText,
|
|
3422
|
+
region: legacyText,
|
|
3423
|
+
postalCode: legacyText,
|
|
3424
|
+
countryCode: legacyText,
|
|
3425
|
+
displayAddress: legacyText
|
|
3426
|
+
});
|
|
3427
|
+
const customLocationSchema = legacyCoordinatesSchema.safeExtend({ addressText: legacyText });
|
|
3428
|
+
function finishConversion(address, coordinates) {
|
|
3429
|
+
const parsedAddress = locationAddressSchema.nullable().safeParse(address);
|
|
3430
|
+
if (!parsedAddress.success) return err({
|
|
3431
|
+
kind: "invalid_legacy_location",
|
|
3432
|
+
issues: parsedAddress.error.issues
|
|
3433
|
+
});
|
|
3434
|
+
const pin = coordinates.lat == null || coordinates.lng == null ? null : {
|
|
3435
|
+
lat: coordinates.lat,
|
|
3436
|
+
lng: coordinates.lng
|
|
3437
|
+
};
|
|
3438
|
+
if (parsedAddress.data === null && pin === null) return ok(null);
|
|
3439
|
+
const result = parseLocationValue({
|
|
3440
|
+
address: parsedAddress.data,
|
|
3441
|
+
pin,
|
|
3442
|
+
addressMatch: null,
|
|
3443
|
+
ownerConfirmedPinAndAddress: false
|
|
3444
|
+
});
|
|
3445
|
+
return result.ok ? result : err({
|
|
3446
|
+
kind: "invalid_legacy_location",
|
|
3447
|
+
issues: result.error.issues
|
|
3448
|
+
});
|
|
3449
|
+
}
|
|
3450
|
+
function convertVenue(input) {
|
|
3451
|
+
const address = venueAddressSchema.safeParse(input.addressJson ?? null);
|
|
3452
|
+
const coordinates = legacyCoordinatesSchema.safeParse(input.locationJson ?? {});
|
|
3453
|
+
if (!address.success) return err({
|
|
3454
|
+
kind: "invalid_legacy_location",
|
|
3455
|
+
issues: address.error.issues
|
|
3456
|
+
});
|
|
3457
|
+
if (!coordinates.success) return err({
|
|
3458
|
+
kind: "invalid_legacy_location",
|
|
3459
|
+
issues: coordinates.error.issues
|
|
3460
|
+
});
|
|
3461
|
+
const result = finishConversion(mapVenueAddress(address.data), coordinates.data);
|
|
3462
|
+
return checkDisplayText(result, firstText(address.data?.formatted, address.data?.summary));
|
|
3463
|
+
}
|
|
3464
|
+
const displayComparison = (text) => (text ?? "").trim().replace(/\s+/g, " ").toLowerCase();
|
|
3465
|
+
const firstText = (...parts) => parts.find((part) => part != null && part.trim().length > 0)?.trim() ?? null;
|
|
3466
|
+
function mapVenueAddress(address) {
|
|
3467
|
+
if (address === null) return null;
|
|
3468
|
+
const structured = {
|
|
3469
|
+
street: firstText(address.street, address.line1),
|
|
3470
|
+
unit: address.line2,
|
|
3471
|
+
locality: address.city,
|
|
3472
|
+
region: firstText(address.state, address.region),
|
|
3473
|
+
postalCode: firstText(address.postalCode, address.postal_code, address.postcode),
|
|
3474
|
+
country: address.country
|
|
3475
|
+
};
|
|
3476
|
+
return Object.values(structured).some((part) => displayComparison(part) !== "") ? structured : { street: firstText(address.formatted, address.summary) };
|
|
3477
|
+
}
|
|
3478
|
+
function checkDisplayText(result, text) {
|
|
3479
|
+
if (!result.ok) return result;
|
|
3480
|
+
const original = text?.trim() ?? "";
|
|
3481
|
+
const derived = formatLocationAddress(result.value?.address ?? null);
|
|
3482
|
+
return original.length > 0 && displayComparison(original) !== displayComparison(derived) ? err({
|
|
3483
|
+
kind: "display_address_conflict",
|
|
3484
|
+
original,
|
|
3485
|
+
derived
|
|
3486
|
+
}) : result;
|
|
3487
|
+
}
|
|
3488
|
+
function convertBusiness(value) {
|
|
3489
|
+
if (value == null) return ok(null);
|
|
3490
|
+
const parsed = businessAddressSchema.safeParse(value);
|
|
3491
|
+
if (!parsed.success) return err({
|
|
3492
|
+
kind: "invalid_legacy_location",
|
|
3493
|
+
issues: parsed.error.issues
|
|
3494
|
+
});
|
|
3495
|
+
const result = finishConversion({
|
|
3496
|
+
street: parsed.data.addressLine1,
|
|
3497
|
+
unit: parsed.data.addressLine2,
|
|
3498
|
+
locality: parsed.data.locality,
|
|
3499
|
+
region: parsed.data.region,
|
|
3500
|
+
postalCode: parsed.data.postalCode,
|
|
3501
|
+
country: parsed.data.countryCode
|
|
3502
|
+
}, parsed.data);
|
|
3503
|
+
return checkDisplayText(result, parsed.data.displayAddress);
|
|
3504
|
+
}
|
|
3505
|
+
function convertCustom(value) {
|
|
3506
|
+
if (value == null) return ok(null);
|
|
3507
|
+
const parsed = customLocationSchema.safeParse(value);
|
|
3508
|
+
return parsed.success ? finishConversion({ street: parsed.data.addressText }, parsed.data) : err({
|
|
3509
|
+
kind: "invalid_legacy_location",
|
|
3510
|
+
issues: parsed.error.issues
|
|
3511
|
+
});
|
|
3512
|
+
}
|
|
3513
|
+
/** Preserve pins exactly; never split free text or fabricate match evidence. */
|
|
3514
|
+
function convertLegacyLocation(input) {
|
|
3515
|
+
switch (input.kind) {
|
|
3516
|
+
case "venue": return convertVenue(input);
|
|
3517
|
+
case "business": return convertBusiness(input.value);
|
|
3518
|
+
case "custom": return convertCustom(input.value);
|
|
3519
|
+
}
|
|
3520
|
+
}
|
|
3521
|
+
|
|
3185
3522
|
//#endregion
|
|
3186
3523
|
//#region ../core/src/business-address.ts
|
|
3187
3524
|
function normalizeCountryCode(value) {
|
|
@@ -3198,15 +3535,16 @@ function isLongitude(value) {
|
|
|
3198
3535
|
return value >= -180 && value <= 180;
|
|
3199
3536
|
}
|
|
3200
3537
|
function buildBusinessAddressDisplayText(input) {
|
|
3201
|
-
|
|
3202
|
-
|
|
3203
|
-
trimmedStringOrNull(input.
|
|
3204
|
-
trimmedStringOrNull(input.
|
|
3205
|
-
|
|
3206
|
-
trimmedStringOrNull(input.
|
|
3207
|
-
|
|
3208
|
-
|
|
3209
|
-
|
|
3538
|
+
return formatLocationAddress({
|
|
3539
|
+
building: null,
|
|
3540
|
+
street: trimmedStringOrNull(input.addressLine1),
|
|
3541
|
+
unit: trimmedStringOrNull(input.addressLine2),
|
|
3542
|
+
floor: null,
|
|
3543
|
+
locality: trimmedStringOrNull(input.locality),
|
|
3544
|
+
region: trimmedStringOrNull(input.region),
|
|
3545
|
+
postalCode: trimmedStringOrNull(input.postalCode),
|
|
3546
|
+
country: normalizeCountryCode(input.countryCode)
|
|
3547
|
+
});
|
|
3210
3548
|
}
|
|
3211
3549
|
function validateBusinessAddressDraft(input) {
|
|
3212
3550
|
const addressLine1 = trimmedStringOrNull(input.addressLine1);
|
|
@@ -3378,6 +3716,18 @@ function syncStateOf(sync) {
|
|
|
3378
3716
|
* reload handover is only worth presenting within it (issue 1570).
|
|
3379
3717
|
*/
|
|
3380
3718
|
const EDIT_LEASE_TTL_SECONDS = 60;
|
|
3719
|
+
/** One-use navigation transport for the same previous-client acquire contract. */
|
|
3720
|
+
const EDIT_LEASE_HANDOVER_QUERY_PARAM = "edit_lease_handover";
|
|
3721
|
+
/** Frozen at editor mount; reacquiring a lease never advances this session's admission stamp. */
|
|
3722
|
+
const PAGE_DOCUMENT_SESSION_CHECKPOINT_HEADER = "X-Riverbank-Page-Checkpoint";
|
|
3723
|
+
function parsePageDocumentSessionCheckpoint(value) {
|
|
3724
|
+
if (value === "legacy") return { kind: "legacy" };
|
|
3725
|
+
const parsed = parsePageDocumentCheckpointId(value);
|
|
3726
|
+
return parsed.ok ? {
|
|
3727
|
+
kind: "document",
|
|
3728
|
+
checkpointId: parsed.value
|
|
3729
|
+
} : undefined;
|
|
3730
|
+
}
|
|
3381
3731
|
function parseEditLeaseScope(input) {
|
|
3382
3732
|
switch (input.nodeType) {
|
|
3383
3733
|
case "page": {
|
|
@@ -4056,7 +4406,7 @@ const knownSocialPlatformLabels = {
|
|
|
4056
4406
|
x: "X",
|
|
4057
4407
|
youtube: "YouTube"
|
|
4058
4408
|
};
|
|
4059
|
-
function isRecord$
|
|
4409
|
+
function isRecord$9(value) {
|
|
4060
4410
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
4061
4411
|
}
|
|
4062
4412
|
function trimmedOptionalString(value) {
|
|
@@ -4066,7 +4416,7 @@ function trimmedOptionalString(value) {
|
|
|
4066
4416
|
return trimmed.length > 0 ? trimmed : null;
|
|
4067
4417
|
}
|
|
4068
4418
|
function parsePublicContactDetails(value) {
|
|
4069
|
-
if (!isRecord$
|
|
4419
|
+
if (!isRecord$9(value)) {
|
|
4070
4420
|
return err({
|
|
4071
4421
|
code: "invalid_shape",
|
|
4072
4422
|
path: "contact",
|
|
@@ -4162,7 +4512,7 @@ function minutesSinceMidnight(value) {
|
|
|
4162
4512
|
}
|
|
4163
4513
|
function parseOpeningHoursDay(value, expectedWeekday, index) {
|
|
4164
4514
|
const path = `openingHours.days.${index}`;
|
|
4165
|
-
if (!isRecord$
|
|
4515
|
+
if (!isRecord$9(value) || value.weekday !== expectedWeekday) {
|
|
4166
4516
|
return err({
|
|
4167
4517
|
code: "invalid_weekdays",
|
|
4168
4518
|
path,
|
|
@@ -4183,7 +4533,7 @@ function parseOpeningHoursDay(value, expectedWeekday, index) {
|
|
|
4183
4533
|
const intervals = [];
|
|
4184
4534
|
for (const [intervalIndex, rawInterval] of value.intervals.entries()) {
|
|
4185
4535
|
const intervalPath = `${path}.intervals.${intervalIndex}`;
|
|
4186
|
-
if (!isRecord$
|
|
4536
|
+
if (!isRecord$9(rawInterval)) {
|
|
4187
4537
|
return err({
|
|
4188
4538
|
code: "invalid_interval",
|
|
4189
4539
|
path: intervalPath,
|
|
@@ -4255,7 +4605,7 @@ function parseOpeningHoursWeek(rawDays) {
|
|
|
4255
4605
|
]);
|
|
4256
4606
|
}
|
|
4257
4607
|
function parseWeeklyOpeningHours(value) {
|
|
4258
|
-
if (!isRecord$
|
|
4608
|
+
if (!isRecord$9(value) || !Array.isArray(value.days) || value.days.length !== publicProfileWeekdays.length) {
|
|
4259
4609
|
return err({
|
|
4260
4610
|
code: "invalid_weekdays",
|
|
4261
4611
|
path: "openingHours.days",
|
|
@@ -4324,7 +4674,7 @@ function parsePublicSocialLinks(value) {
|
|
|
4324
4674
|
const ids = new Set();
|
|
4325
4675
|
for (const [index, rawLink] of value.entries()) {
|
|
4326
4676
|
const path = `socialLinks.${index}`;
|
|
4327
|
-
if (!isRecord$
|
|
4677
|
+
if (!isRecord$9(rawLink)) {
|
|
4328
4678
|
return err({
|
|
4329
4679
|
code: "invalid_social_link",
|
|
4330
4680
|
path,
|
|
@@ -4397,7 +4747,7 @@ function parsePublicProfilePresentation(value) {
|
|
|
4397
4747
|
});
|
|
4398
4748
|
}
|
|
4399
4749
|
function parsePublicProfile(value) {
|
|
4400
|
-
if (!isRecord$
|
|
4750
|
+
if (!isRecord$9(value)) {
|
|
4401
4751
|
return err({
|
|
4402
4752
|
code: "invalid_shape",
|
|
4403
4753
|
path: "",
|
|
@@ -4435,7 +4785,7 @@ function parseContactVisibility(value) {
|
|
|
4435
4785
|
email: "shown"
|
|
4436
4786
|
});
|
|
4437
4787
|
}
|
|
4438
|
-
if (!isRecord$
|
|
4788
|
+
if (!isRecord$9(value)) {
|
|
4439
4789
|
return err({
|
|
4440
4790
|
code: "invalid_contact_visibility",
|
|
4441
4791
|
path: "contactVisibility",
|
|
@@ -4579,7 +4929,7 @@ function parsePublicExperience(value) {
|
|
|
4579
4929
|
|
|
4580
4930
|
//#endregion
|
|
4581
4931
|
//#region ../core/src/rich-text.ts
|
|
4582
|
-
function isRecord$
|
|
4932
|
+
function isRecord$8(value) {
|
|
4583
4933
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
4584
4934
|
}
|
|
4585
4935
|
function hasOnlyKeys(value, allowed) {
|
|
@@ -4601,10 +4951,10 @@ function isDenseArrayOf(value, predicate) {
|
|
|
4601
4951
|
return true;
|
|
4602
4952
|
}
|
|
4603
4953
|
function isTipTapMark(value) {
|
|
4604
|
-
return isRecord$
|
|
4954
|
+
return isRecord$8(value) && hasOnlyKeys(value, markKeys) && typeof value.type === "string" && value.type.length > 0 && (value.attrs === undefined || isRecord$8(value.attrs));
|
|
4605
4955
|
}
|
|
4606
4956
|
function isTipTapNode(value) {
|
|
4607
|
-
if (!isRecord$
|
|
4957
|
+
if (!isRecord$8(value) || !hasOnlyKeys(value, nodeKeys) || typeof value.type !== "string" || value.type.length === 0 || value.type === "doc" || value.attrs !== undefined && !isRecord$8(value.attrs) || value.marks !== undefined && (!Array.isArray(value.marks) || !isDenseArrayOf(value.marks, isTipTapMark)) || value.content !== undefined && (!Array.isArray(value.content) || !isDenseArrayOf(value.content, isTipTapNode))) {
|
|
4608
4958
|
return false;
|
|
4609
4959
|
}
|
|
4610
4960
|
if (value.type === "text") {
|
|
@@ -4613,7 +4963,7 @@ function isTipTapNode(value) {
|
|
|
4613
4963
|
return value.text === undefined;
|
|
4614
4964
|
}
|
|
4615
4965
|
function isCanonicalRichTextDoc(value) {
|
|
4616
|
-
return isRecord$
|
|
4966
|
+
return isRecord$8(value) && hasOnlyKeys(value, rootKeys) && value.type === "doc" && Array.isArray(value.content) && isDenseArrayOf(value.content, isTipTapNode);
|
|
4617
4967
|
}
|
|
4618
4968
|
|
|
4619
4969
|
//#endregion
|
|
@@ -4853,10 +5203,10 @@ function presentVisitorSelection(selection, optionCount) {
|
|
|
4853
5203
|
//#region ../core/src/mailing-list-targeting-parser.ts
|
|
4854
5204
|
function parseMailingListPlacementTargeting(value) {
|
|
4855
5205
|
if (value == null) return ok(DEFAULT_MAILING_LIST_TARGETING);
|
|
4856
|
-
if (!isRecord$
|
|
5206
|
+
if (!isRecord$7(value)) return targetingError("shape");
|
|
4857
5207
|
if (value.mode === "default") return ok({ mode: "default" });
|
|
4858
5208
|
if (value.mode !== "custom") return targetingError("mode");
|
|
4859
|
-
if (!isRecord$
|
|
5209
|
+
if (!isRecord$7(value.selection)) return targetingError("selection");
|
|
4860
5210
|
switch (value.provider) {
|
|
4861
5211
|
case "native": return parseNativeTargeting(value.selection);
|
|
4862
5212
|
case "brevo": return parseBrevoTargeting(value.selection);
|
|
@@ -4865,7 +5215,7 @@ function parseMailingListPlacementTargeting(value) {
|
|
|
4865
5215
|
}
|
|
4866
5216
|
}
|
|
4867
5217
|
function parseMailingListVisitorSelection(value) {
|
|
4868
|
-
if (!isRecord$
|
|
5218
|
+
if (!isRecord$7(value)) return visitorSelectionError("shape");
|
|
4869
5219
|
switch (value.provider) {
|
|
4870
5220
|
case "native": {
|
|
4871
5221
|
if (Object.keys(value).some((key) => key !== "provider" && key !== "topicIds")) return visitorSelectionError("shape");
|
|
@@ -4996,7 +5346,7 @@ function parseVisitorIds(value, parseId) {
|
|
|
4996
5346
|
const parsed = parseNonEmptyUniqueIds(value, parseId);
|
|
4997
5347
|
return parsed.ok ? parsed.value : null;
|
|
4998
5348
|
}
|
|
4999
|
-
function isRecord$
|
|
5349
|
+
function isRecord$7(value) {
|
|
5000
5350
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
5001
5351
|
}
|
|
5002
5352
|
function targetingError(field) {
|
|
@@ -5014,7 +5364,7 @@ function visitorSelectionError(field) {
|
|
|
5014
5364
|
|
|
5015
5365
|
//#endregion
|
|
5016
5366
|
//#region ../core/src/footer-engagement.ts
|
|
5017
|
-
function isRecord$
|
|
5367
|
+
function isRecord$6(value) {
|
|
5018
5368
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
5019
5369
|
}
|
|
5020
5370
|
function invalid(path, message) {
|
|
@@ -5048,7 +5398,7 @@ function parseEngagementBase(value, base, path) {
|
|
|
5048
5398
|
}
|
|
5049
5399
|
const treatment = parseTreatment(value.treatment, `${path}.treatment`);
|
|
5050
5400
|
if (!treatment.ok) return treatment;
|
|
5051
|
-
if (!isRecord$
|
|
5401
|
+
if (!isRecord$6(value.source)) {
|
|
5052
5402
|
return err(invalid(`${path}.source`, "Footer engagement source is invalid."));
|
|
5053
5403
|
}
|
|
5054
5404
|
const intro = parseBoundedText(value.source.intro, `${path}.source.intro`, {
|
|
@@ -5095,7 +5445,7 @@ function parseFooterEngagementSectionValue(value, sectionBase, path) {
|
|
|
5095
5445
|
const base = parseEngagementBase(value, sectionBase, path);
|
|
5096
5446
|
if (!base.ok) return base;
|
|
5097
5447
|
const source = value.source;
|
|
5098
|
-
if (!isRecord$
|
|
5448
|
+
if (!isRecord$6(source)) {
|
|
5099
5449
|
return err(invalid(`${path}.source`, "Footer engagement source is invalid."));
|
|
5100
5450
|
}
|
|
5101
5451
|
switch (source.kind) {
|
|
@@ -5256,7 +5606,7 @@ function unsafeAsFooterModuleId(value) {
|
|
|
5256
5606
|
function parseFooterModuleId(value) {
|
|
5257
5607
|
return parseSectionId(value, "sectionId");
|
|
5258
5608
|
}
|
|
5259
|
-
function isRecord$
|
|
5609
|
+
function isRecord$5(value) {
|
|
5260
5610
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
5261
5611
|
}
|
|
5262
5612
|
function isRichText(value) {
|
|
@@ -5286,7 +5636,7 @@ function parseHeading(value, path) {
|
|
|
5286
5636
|
}
|
|
5287
5637
|
function parseFooterSection(value, index) {
|
|
5288
5638
|
const path = `sections.${index}`;
|
|
5289
|
-
if (!isRecord$
|
|
5639
|
+
if (!isRecord$5(value)) {
|
|
5290
5640
|
return err({
|
|
5291
5641
|
code: "invalid_section",
|
|
5292
5642
|
path,
|
|
@@ -5321,7 +5671,7 @@ function parseFooterSection(value, index) {
|
|
|
5321
5671
|
}
|
|
5322
5672
|
break;
|
|
5323
5673
|
case "navigation":
|
|
5324
|
-
if (isRecord$
|
|
5674
|
+
if (isRecord$5(value.source) && value.source.kind === "menu-role" && value.source.role === "main") {
|
|
5325
5675
|
return ok({
|
|
5326
5676
|
...base,
|
|
5327
5677
|
kind: "navigation",
|
|
@@ -5334,7 +5684,7 @@ function parseFooterSection(value, index) {
|
|
|
5334
5684
|
}
|
|
5335
5685
|
break;
|
|
5336
5686
|
case "legal-navigation":
|
|
5337
|
-
if (isRecord$
|
|
5687
|
+
if (isRecord$5(value.source) && value.source.kind === "menu-role" && value.source.role === "legal-policy") {
|
|
5338
5688
|
return ok({
|
|
5339
5689
|
...base,
|
|
5340
5690
|
kind: "legal-navigation",
|
|
@@ -5347,7 +5697,7 @@ function parseFooterSection(value, index) {
|
|
|
5347
5697
|
}
|
|
5348
5698
|
break;
|
|
5349
5699
|
case "business-address":
|
|
5350
|
-
if (isRecord$
|
|
5700
|
+
if (isRecord$5(value.source) && value.source.kind === "business-address") {
|
|
5351
5701
|
return ok({
|
|
5352
5702
|
...base,
|
|
5353
5703
|
kind: "business-address",
|
|
@@ -5359,7 +5709,7 @@ function parseFooterSection(value, index) {
|
|
|
5359
5709
|
case "contact":
|
|
5360
5710
|
case "opening-hours":
|
|
5361
5711
|
case "social-links":
|
|
5362
|
-
if (isRecord$
|
|
5712
|
+
if (isRecord$5(value.source) && value.source.kind === "public-profile") {
|
|
5363
5713
|
return ok({
|
|
5364
5714
|
...base,
|
|
5365
5715
|
kind: value.kind,
|
|
@@ -5411,7 +5761,7 @@ function validateFooterComposition(composition) {
|
|
|
5411
5761
|
return ok(composition);
|
|
5412
5762
|
}
|
|
5413
5763
|
function parseFooterCompositionV1(value) {
|
|
5414
|
-
if (!isRecord$
|
|
5764
|
+
if (!isRecord$5(value)) {
|
|
5415
5765
|
return err({
|
|
5416
5766
|
code: "invalid_shape",
|
|
5417
5767
|
path: "",
|
|
@@ -5444,7 +5794,7 @@ function parseFooterCompositionV1(value) {
|
|
|
5444
5794
|
});
|
|
5445
5795
|
}
|
|
5446
5796
|
function parseLegacyPlacementSection(value, index, selectedIds) {
|
|
5447
|
-
if (!isRecord$
|
|
5797
|
+
if (!isRecord$5(value)) {
|
|
5448
5798
|
return err({
|
|
5449
5799
|
code: "invalid_section",
|
|
5450
5800
|
path: `modules.${index}`,
|
|
@@ -5452,7 +5802,7 @@ function parseLegacyPlacementSection(value, index, selectedIds) {
|
|
|
5452
5802
|
});
|
|
5453
5803
|
}
|
|
5454
5804
|
const selected = typeof value.id === "string" && selectedIds.has(value.id);
|
|
5455
|
-
const source = isRecord$
|
|
5805
|
+
const source = isRecord$5(value.source) ? value.source : null;
|
|
5456
5806
|
const mapped = value.kind === "navigation" && source?.kind === "menu-role" && source.role === "footer" ? {
|
|
5457
5807
|
...value,
|
|
5458
5808
|
source: {
|
|
@@ -5471,7 +5821,7 @@ function parseLegacyPlacementSection(value, index, selectedIds) {
|
|
|
5471
5821
|
* It is intentionally not called by the runtime parser.
|
|
5472
5822
|
*/
|
|
5473
5823
|
function upgradePlacementFooterCompositionV1(value) {
|
|
5474
|
-
if (!isRecord$
|
|
5824
|
+
if (!isRecord$5(value) || value.schemaVersion !== 1 || !Array.isArray(value.modules) || !Array.isArray(value.placements)) {
|
|
5475
5825
|
return err({
|
|
5476
5826
|
code: "invalid_shape",
|
|
5477
5827
|
path: "",
|
|
@@ -5480,7 +5830,7 @@ function upgradePlacementFooterCompositionV1(value) {
|
|
|
5480
5830
|
}
|
|
5481
5831
|
const selectedIds = new Set();
|
|
5482
5832
|
for (const [index, placement] of value.placements.entries()) {
|
|
5483
|
-
if (!isRecord$
|
|
5833
|
+
if (!isRecord$5(placement) || typeof placement.moduleId !== "string") {
|
|
5484
5834
|
return err({
|
|
5485
5835
|
code: "invalid_shape",
|
|
5486
5836
|
path: `placements.${index}`,
|
|
@@ -5695,7 +6045,7 @@ const defaultSections = (legacy, options) => {
|
|
|
5695
6045
|
];
|
|
5696
6046
|
};
|
|
5697
6047
|
function normalizeLegacyFooterContentToV1(value, options = {}) {
|
|
5698
|
-
if (!isRecord$
|
|
6048
|
+
if (!isRecord$5(value)) {
|
|
5699
6049
|
return err({
|
|
5700
6050
|
code: "invalid_shape",
|
|
5701
6051
|
path: "",
|
|
@@ -5710,7 +6060,7 @@ function normalizeLegacyFooterContentToV1(value, options = {}) {
|
|
|
5710
6060
|
|
|
5711
6061
|
//#endregion
|
|
5712
6062
|
//#region ../core/src/mailing-list-setup.ts
|
|
5713
|
-
function isRecord$
|
|
6063
|
+
function isRecord$4(value) {
|
|
5714
6064
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
5715
6065
|
}
|
|
5716
6066
|
/** The name shown to people for each provider; the native one is the product brand. */
|
|
@@ -5825,7 +6175,7 @@ function mailingListProviderScopeFromConfigured(provider) {
|
|
|
5825
6175
|
}
|
|
5826
6176
|
}
|
|
5827
6177
|
function parseMailingListProviderScope(value) {
|
|
5828
|
-
if (!isRecord$
|
|
6178
|
+
if (!isRecord$4(value)) return err("invalid_mailing_list_provider_scope");
|
|
5829
6179
|
if (value.provider === "native") return ok({ provider: "native" });
|
|
5830
6180
|
if (value.provider === "brevo") {
|
|
5831
6181
|
const accountId = parseBrevoAccountId(value.accountId);
|
|
@@ -5867,7 +6217,7 @@ const newsletterAudienceSchema = z.unknown().transform((value, ctx) => {
|
|
|
5867
6217
|
return z.NEVER;
|
|
5868
6218
|
});
|
|
5869
6219
|
function parseMailingListGlobalForm(value) {
|
|
5870
|
-
if (!isRecord$
|
|
6220
|
+
if (!isRecord$3(value)) return formError("shape");
|
|
5871
6221
|
const fields = parseGlobalFields(value.fields);
|
|
5872
6222
|
if (fields === null) return formError("fields");
|
|
5873
6223
|
if (typeof value.includeOptionalPhone !== "boolean") {
|
|
@@ -5888,7 +6238,7 @@ function parseMailingListGlobalForm(value) {
|
|
|
5888
6238
|
});
|
|
5889
6239
|
}
|
|
5890
6240
|
function parseMailingListSiteSetup(value) {
|
|
5891
|
-
if (!isRecord$
|
|
6241
|
+
if (!isRecord$3(value)) return setupError("shape");
|
|
5892
6242
|
const siteId = parseSiteId(value.siteId);
|
|
5893
6243
|
if (!siteId.ok) return setupError("siteId");
|
|
5894
6244
|
if (value.tag === "not_configured") {
|
|
@@ -5918,7 +6268,7 @@ function parseConfiguredSiteSetup(value, siteId) {
|
|
|
5918
6268
|
});
|
|
5919
6269
|
}
|
|
5920
6270
|
function parseConfiguredMailingListProvider(value) {
|
|
5921
|
-
if (!isRecord$
|
|
6271
|
+
if (!isRecord$3(value) || typeof value.provider !== "string") {
|
|
5922
6272
|
return setupError("provider");
|
|
5923
6273
|
}
|
|
5924
6274
|
switch (value.provider) {
|
|
@@ -5972,7 +6322,7 @@ function parseBrevoSetup(value) {
|
|
|
5972
6322
|
});
|
|
5973
6323
|
}
|
|
5974
6324
|
function parseNewsletterAudience(value) {
|
|
5975
|
-
if (!isRecord$
|
|
6325
|
+
if (!isRecord$3(value)) return err("invalid_newsletter_audience");
|
|
5976
6326
|
if (value.kind === "general" && Object.keys(value).length === 1) {
|
|
5977
6327
|
return ok({ kind: "general" });
|
|
5978
6328
|
}
|
|
@@ -5986,7 +6336,7 @@ function parseNewsletterAudience(value) {
|
|
|
5986
6336
|
});
|
|
5987
6337
|
}
|
|
5988
6338
|
function parseGlobalFields(value) {
|
|
5989
|
-
if (!isRecord$
|
|
6339
|
+
if (!isRecord$3(value) || typeof value.preset !== "string") return null;
|
|
5990
6340
|
switch (value.preset) {
|
|
5991
6341
|
case "emailOnly": return { preset: "emailOnly" };
|
|
5992
6342
|
case "emailName": return isRequirement(value.name) ? {
|
|
@@ -6011,11 +6361,11 @@ function parseGlobalFields(value) {
|
|
|
6011
6361
|
}
|
|
6012
6362
|
}
|
|
6013
6363
|
function parseToggleConfirmation(value) {
|
|
6014
|
-
if (!isRecord$
|
|
6364
|
+
if (!isRecord$3(value)) return null;
|
|
6015
6365
|
return value.tag === "on" || value.tag === "off" ? { tag: value.tag } : null;
|
|
6016
6366
|
}
|
|
6017
6367
|
function parseBrevoConfirmation(value) {
|
|
6018
|
-
if (!isRecord$
|
|
6368
|
+
if (!isRecord$3(value)) return null;
|
|
6019
6369
|
if (value.tag === "off") return { tag: "off" };
|
|
6020
6370
|
if (value.tag !== "on") return null;
|
|
6021
6371
|
const templateId = parseBrevoConfirmationTemplateId(value.templateId);
|
|
@@ -6052,7 +6402,7 @@ function parseOptionalString(value) {
|
|
|
6052
6402
|
function isRequirement(value) {
|
|
6053
6403
|
return value === "required" || value === "optional";
|
|
6054
6404
|
}
|
|
6055
|
-
function isRecord$
|
|
6405
|
+
function isRecord$3(value) {
|
|
6056
6406
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
6057
6407
|
}
|
|
6058
6408
|
function formError(field) {
|
|
@@ -6175,7 +6525,7 @@ function assessMatchedChoices(matched, choices) {
|
|
|
6175
6525
|
//#endregion
|
|
6176
6526
|
//#region ../core/src/mailing-list-runtime.ts
|
|
6177
6527
|
function parseMailingListRuntimeContext(value) {
|
|
6178
|
-
if (!isRecord$
|
|
6528
|
+
if (!isRecord$2(value)) return invalidRuntimeContext();
|
|
6179
6529
|
if (value.tag === "not_configured") return ok({ tag: "not_configured" });
|
|
6180
6530
|
if (value.tag !== "configured") return invalidRuntimeContext();
|
|
6181
6531
|
return parseConfiguredRuntimeContext(value);
|
|
@@ -6223,7 +6573,7 @@ function parseBookingSignupOffer(value) {
|
|
|
6223
6573
|
tag: "unavailable",
|
|
6224
6574
|
reason: "disabled"
|
|
6225
6575
|
};
|
|
6226
|
-
if (!isRecord$
|
|
6576
|
+
if (!isRecord$2(value)) return null;
|
|
6227
6577
|
if (value.tag === "offered") return { tag: "offered" };
|
|
6228
6578
|
if (value.tag === "unavailable" && (value.reason === "disabled" || value.reason === "fields" || value.reason === "destination")) {
|
|
6229
6579
|
return {
|
|
@@ -6234,7 +6584,7 @@ function parseBookingSignupOffer(value) {
|
|
|
6234
6584
|
return null;
|
|
6235
6585
|
}
|
|
6236
6586
|
function parseRuntimeProvider(value) {
|
|
6237
|
-
if (!isRecord$
|
|
6587
|
+
if (!isRecord$2(value)) return null;
|
|
6238
6588
|
switch (value.provider) {
|
|
6239
6589
|
case "native": return parseNativeRuntimeProvider(value);
|
|
6240
6590
|
case "brevo": return parseBrevoRuntimeProvider(value);
|
|
@@ -6272,7 +6622,7 @@ function parseMailchimpRuntimeProvider(value) {
|
|
|
6272
6622
|
} : null;
|
|
6273
6623
|
}
|
|
6274
6624
|
function parseMailchimpAudience(value) {
|
|
6275
|
-
if (!isRecord$
|
|
6625
|
+
if (!isRecord$2(value) || !Array.isArray(value.interests)) return null;
|
|
6276
6626
|
const id = parseMailchimpAudienceId(value.id);
|
|
6277
6627
|
const name = parseName(value.name);
|
|
6278
6628
|
const interests = Array.from(value.interests, parseMailchimpInterest);
|
|
@@ -6283,7 +6633,7 @@ function parseMailchimpAudience(value) {
|
|
|
6283
6633
|
} : null;
|
|
6284
6634
|
}
|
|
6285
6635
|
function parseMailchimpInterest(value) {
|
|
6286
|
-
if (!isRecord$
|
|
6636
|
+
if (!isRecord$2(value)) return null;
|
|
6287
6637
|
const id = parseMailchimpInterestId(value.id);
|
|
6288
6638
|
const name = parseName(value.name);
|
|
6289
6639
|
const categoryName = parseName(value.categoryName);
|
|
@@ -6296,7 +6646,7 @@ function parseMailchimpInterest(value) {
|
|
|
6296
6646
|
function parseNamedItems(value, parseId) {
|
|
6297
6647
|
if (!Array.isArray(value)) return null;
|
|
6298
6648
|
const items = Array.from(value, (item) => {
|
|
6299
|
-
if (!isRecord$
|
|
6649
|
+
if (!isRecord$2(item)) return null;
|
|
6300
6650
|
const id = parseId(item.id);
|
|
6301
6651
|
const name = parseName(item.name);
|
|
6302
6652
|
return id !== null && name !== null ? {
|
|
@@ -6311,7 +6661,7 @@ function parseName(value) {
|
|
|
6311
6661
|
const name = value.trim();
|
|
6312
6662
|
return name.length > 0 ? name : null;
|
|
6313
6663
|
}
|
|
6314
|
-
function isRecord$
|
|
6664
|
+
function isRecord$2(value) {
|
|
6315
6665
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
6316
6666
|
}
|
|
6317
6667
|
function invalidRuntimeContext() {
|
|
@@ -6585,11 +6935,11 @@ const PRIORITY_IDS = new Set([
|
|
|
6585
6935
|
"emailaddress"
|
|
6586
6936
|
]);
|
|
6587
6937
|
const MAX_COLUMNS = 5;
|
|
6588
|
-
function isRecord(value) {
|
|
6938
|
+
function isRecord$1(value) {
|
|
6589
6939
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
6590
6940
|
}
|
|
6591
6941
|
function isSchemaField(value) {
|
|
6592
|
-
return isRecord(value) && typeof value.id === "string";
|
|
6942
|
+
return isRecord$1(value) && typeof value.id === "string";
|
|
6593
6943
|
}
|
|
6594
6944
|
function selectSubmissionPreviewFields(schemaFields, submissions) {
|
|
6595
6945
|
const fields = Array.isArray(schemaFields) ? schemaFields.filter(isSchemaField) : [];
|
|
@@ -6682,7 +7032,7 @@ function valueIsMeaningful(value) {
|
|
|
6682
7032
|
if (value === null || value === undefined) return false;
|
|
6683
7033
|
if (typeof value === "string") return value.trim().length > 0;
|
|
6684
7034
|
if (Array.isArray(value)) return value.length > 0;
|
|
6685
|
-
if (isRecord(value)) return Object.keys(value).length > 0;
|
|
7035
|
+
if (isRecord$1(value)) return Object.keys(value).length > 0;
|
|
6686
7036
|
return true;
|
|
6687
7037
|
}
|
|
6688
7038
|
function orderSubmissionFields(schemaFields, data) {
|
|
@@ -8477,4 +8827,32 @@ function resolvePublicSiteVisibility(input) {
|
|
|
8477
8827
|
}
|
|
8478
8828
|
|
|
8479
8829
|
//#endregion
|
|
8480
|
-
|
|
8830
|
+
//#region ../core/src/authored-values.ts
|
|
8831
|
+
/** Canonical authored equality: empty storage values and absent optional members agree. */
|
|
8832
|
+
function canonicalAuthoredValue(value) {
|
|
8833
|
+
if (value == null || value === "" || typeof value === "number" && Number.isNaN(value)) return null;
|
|
8834
|
+
if (Array.isArray(value)) return value.map(canonicalAuthoredValue);
|
|
8835
|
+
if (typeof value !== "object") return value;
|
|
8836
|
+
const entries = Object.entries(value).sort(([a], [b]) => a.localeCompare(b)).map(([key, member]) => [key, canonicalAuthoredValue(member)]).filter(([, member]) => member !== null);
|
|
8837
|
+
return entries.length === 0 ? null : Object.fromEntries(entries);
|
|
8838
|
+
}
|
|
8839
|
+
function authoredValuesEqual(left, right) {
|
|
8840
|
+
return JSON.stringify(canonicalAuthoredValue(left)) === JSON.stringify(canonicalAuthoredValue(right));
|
|
8841
|
+
}
|
|
8842
|
+
|
|
8843
|
+
//#endregion
|
|
8844
|
+
//#region ../core/src/record-guards.ts
|
|
8845
|
+
function isRecord(value) {
|
|
8846
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
8847
|
+
}
|
|
8848
|
+
/**
|
|
8849
|
+
* Type guard for plain object records (excludes class instances like Error/Date).
|
|
8850
|
+
*/
|
|
8851
|
+
function isPlainRecord(value) {
|
|
8852
|
+
if (!isRecord(value)) return false;
|
|
8853
|
+
const proto = Object.getPrototypeOf(value);
|
|
8854
|
+
return proto === Object.prototype || proto === null;
|
|
8855
|
+
}
|
|
8856
|
+
|
|
8857
|
+
//#endregion
|
|
8858
|
+
export { inferSiteDateLocale as $, parseCurrencyCode as $t, assessMailingListTargeting as A, unsafeAsPositiveByteCount as An, resolveFlexibleBalanceInitialPaymentCents as At, parsePublicContactDetails as B, unsafeAsStoragePath as Bn, resolveExactOrFreePriceDisplay as Bt, parseManagementKey as C, unsafeAsEventOfferingId as Cn, clampConfiguredAmount as Ct, parseMailingListContentVersionId as D, unsafeAsOccurrenceId as Dn, omitZeroAmountFutureRows as Dt, parseMailingListBlockId as E, unsafeAsMediaAssetId as En, getBookingInstalmentProtectedDepositAmountCents as Et, parseMailingListPlacementTargeting as F, unsafeAsSiteFontId as Fn, isPublicEventPricingOptionDisplayable as Ft, isPresent as G, isNonNegativeWholeCents as Gt, assertAllowedPublicUrl as H, unsafeAsUserId as Hn, fromArray as Ht, DEFAULT_MAILING_LIST_TARGETING as I, unsafeAsSiteId as In, publicEventPricingCurrency as It, formatDateRange as J, toCents as Jt, selectCategoryView as K, parseNonNegativeCents as Kt, planMailingListChoicePresentation as L, unsafeAsSiteScopedStoragePath as Ln, publicEventPricingDisplay as Lt, parseMailingListProviderScope as M, unsafeAsPricingOptionId as Mn, parseEventPageSurfaceSubject as Mt, parseFooterCompositionV1 as N, unsafeAsProductId as Nn, formatBookingPriceDisplay as Nt, parseMailingListSignedSourceToken as O, unsafeAsOriginalFilename as On, splitAmountWithRemainderInFirst as Ot, footerNavigationLayouts as P, unsafeAsSafeDownloadFilename as Pn, formatEventPricing as Pt, formatTimeRange as Q, formatCurrencyAmount as Qt, isCanonicalRichTextDoc as R, unsafeAsStaffMemberId as Rn, publicEventPricingOptions as Rt, exposeSecret as S, unsafeAsEventInstanceId as Sn, addIntervalPreservingMonthAnchor as St, slugify as T, unsafeAsFileChecksumSha256 as Tn, getBookingInstalmentPlanIntervalCount as Tt, normalizeLocationAddressText as U, err as Un, mapNonEmptyArray as Ut, parseWeeklyOpeningHours as V, unsafeAsUploadSessionId as Vn, resolvePricingOptionsPriceDisplay as Vt, toLocationCoordinates as W, ok as Wn, mapReadonlyNonEmptyArray as Wt, formatDateTimeRange as X, unsafeAsNonNegativeCents as Xt, formatDateTime as Y, toNonNegativeCents as Yt, formatTime as Z, unsafeAsPositiveCents as Zt, nextLiveRunSessionStartMs as _, unsafeAsCheckoutLineId as _n, parseBookingTimeZone as _t, areConfiguredBookingVerticalConfigsEqual as a, parseDatedOfferingCapacityHoldId as an, getBookingLocalDateKey as at, resolveWholeSeriesRunLifecycle as b, unsafeAsDetectedMimeType as bn, isSettleableFlexibleBalanceContractStatus as bt, parseVerticalPresetId as c, parseMembershipId as cn, localScheduleTimePattern as ct, EVENT_PRESET_VALUES as d, parseSiteId as dn, parseUtcIsoDateTimeString as dt, assertNever as en, resolveBookingDisplayContext as et, ORDINARY_EVENT_PRESET_VALUES as f, parseSiteTermsVersionId as fn, resolveBookingBusinessTimeZone as ft, CANCELLED_SESSION_STATUS as g, unsafeAsBookingSessionId as gn, toUtcIsoDateTimeString as gt, publicReadFreshnessSeconds as h, unsafeAsBookingRequirementId as hn, toScheduledBookingDateTime as ht, NAVIGATION_LOCATIONS as i, parseDatedOfferingCapacityHoldAuditRef as in, formatLocalScheduleTime as it, DEFAULT_MAILING_LIST_SUCCESS_MESSAGE as j, unsafeAsPositiveSeconds as jn, deriveTotalTicketQuantity as jt, parseMailingListRuntimeContext as k, unsafeAsPassId as kn, resolveFlexibleBalanceDueAt as kt, resolveSiteVerticalBookingConfig as l, parsePageId as ln, parseBookingLocalDate as lt, WHOLE_SERIES_EVENT_PRESET_VALUES as m, unsafeAsAppointmentResourceId as mn, toBookingTimeZone as mt, resolveEventCatalogue as n, parseApiKeyId as nn, compareLocalScheduleDates as nt, canonicalizeConfiguredBookingVerticalConfig as o, parseEventSeriesId as on, getLocalScheduleDate as ot, SURFACE_EVENT_PRESET_VALUES as p, parseUserId as pn, resolveBookingTimeZoneId as pt, formatDate as q, parsePositiveCents as qt, EVENT_PRESET_VOCABULARY as r, parseCustomerId as rn, formatLocalScheduleDate as rt, parseVerticalId as s, parseMediaAssetId as sn, getLocalScheduleTime as st, authoredValuesEqual as t, formatDurationUnitLabel as tn, buildBookingUtcDateWindow as tt, DEFAULT_EVENT_TYPE_PRESETS as u, parseRetiredCourseId as un, parseLocalScheduleTime as ut, orderedLiveRunSessions as v, unsafeAsDeclaredMimeType as vn, validateBookingPaymentOptionKinds as vt, stableJsonStringify as w, unsafeAsEventSeriesId as wn, getBookingInstalmentDepositRefundability as wt, createSecret as x, unsafeAsEntitlementId as xn, isSettleableOrderInstalmentPlanStatus as xt, resolveWholeSeriesBookingPhase as y, unsafeAsDemoCapability as yn, isLiveOrderInstalmentPlanStatus as yt, formatOpeningHoursRows as z, unsafeAsStorageBucketName as zn, publicEventPricingType as zt };
|