@void/platform 0.27.0 → 0.28.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/index.mjs +40 -57
- package/dist/installer.mjs +23 -25
- package/dist/plans.mjs +8 -11
- package/dist/runtime/api/assets/admin/client.js +22 -22
- package/dist/runtime/api/assets/admin/style.css +1 -1
- package/dist/runtime/api/index.js +257 -251
- package/dist/runtime/dispatch/index.js +7 -7
- package/dist/runtime/drizzle/0059_oauth_clients.sql +44 -0
- package/dist/runtime/drizzle/compatibility.json +4 -0
- package/dist/runtime/drizzle/meta/_journal.json +7 -0
- package/dist/runtime/emailGateway/index.js +5 -5
- package/dist/runtime/manifest.json +26 -16
- package/dist/runtime/proxy/index.js +5 -5
- package/dist/validate-DbJR7Q0Z.mjs +30 -0
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { a as isSourceRevision, c as requiredString, i as isSandboxDrainProtocol, n as isPrintableText, o as isUsageProtocolVersion, s as record, t as assertRecord } from "./validate-DbJR7Q0Z.mjs";
|
|
1
2
|
import { BUILD_INSTANCE_FREE, BUILD_INSTANCE_LARGE, PLAN_EDITABLE_LIMIT_KEYS, PLAN_LIMITS, createDefaultPlanCatalog, parseBuildInstanceType, parsePlanLimitsPatch, parsePlanName, parsePlatformPlanCatalog, parsePlatformPlanId, validatePlanLimits } from "./plans.mjs";
|
|
2
3
|
//#region src/app-access.ts
|
|
3
4
|
const PLATFORM_APP_ACCESS_SETUP_PROOF_PREFIX = "void-platform-app-access-v1";
|
|
@@ -125,12 +126,8 @@ function parsePlatformAuthenticationSetup(value) {
|
|
|
125
126
|
const DEFAULT_PLATFORM_SESSION_SECONDS = 2592e3;
|
|
126
127
|
const GOOGLE_OIDC_ISSUER = "https://accounts.google.com";
|
|
127
128
|
const PLATFORM_AUTH_SETUP_PROOF_PREFIX = "void.platform.auth.setup.v1";
|
|
128
|
-
function record(value, name) {
|
|
129
|
-
if (!value || typeof value !== "object" || Array.isArray(value)) throw new Error(`${name} must be an object.`);
|
|
130
|
-
return value;
|
|
131
|
-
}
|
|
132
129
|
function string(value, name, maximum = 512) {
|
|
133
|
-
if (
|
|
130
|
+
if (!isPrintableText(value, maximum)) throw new Error(`${name} must be a nonempty string of at most ${maximum} characters.`);
|
|
134
131
|
return value.trim();
|
|
135
132
|
}
|
|
136
133
|
function strings(value, name, maximum = 100) {
|
|
@@ -262,13 +259,6 @@ const CONTROL_PLANE_DEFAULTS = {
|
|
|
262
259
|
dashboardHostname: null,
|
|
263
260
|
proxyHostname: null
|
|
264
261
|
};
|
|
265
|
-
function assertRecord$1(value, label) {
|
|
266
|
-
if (!value || typeof value !== "object" || Array.isArray(value)) throw new Error(`${label} must be an object.`);
|
|
267
|
-
}
|
|
268
|
-
function requiredString$1(value, label) {
|
|
269
|
-
if (typeof value !== "string" || value.trim() === "") throw new Error(`${label} must be a non-empty string.`);
|
|
270
|
-
return value;
|
|
271
|
-
}
|
|
272
262
|
function normalizeInstallationSlug(value) {
|
|
273
263
|
const slug = value.trim().toLowerCase().replaceAll(/[^a-z0-9-]+/g, "-").replaceAll(/^-+|-+$/g, "").replaceAll(/-{2,}/g, "-");
|
|
274
264
|
if (!slug) throw new Error("The installation name must contain a letter or number.");
|
|
@@ -384,7 +374,7 @@ function createPlatformDeploymentManifest(input) {
|
|
|
384
374
|
dedicatedZone: input.application.dedicatedZone ?? false,
|
|
385
375
|
zoneName,
|
|
386
376
|
...workersDev ? { workersDev: { ...workersDev } } : {},
|
|
387
|
-
...input.application.zoneId ? { zoneId: requiredString
|
|
377
|
+
...input.application.zoneId ? { zoneId: requiredString(input.application.zoneId, "application.zoneId") } : {}
|
|
388
378
|
},
|
|
389
379
|
authentication: {
|
|
390
380
|
providers: [...providers],
|
|
@@ -392,7 +382,7 @@ function createPlatformDeploymentManifest(input) {
|
|
|
392
382
|
...input.authentication?.accessProtection ? { accessProtection: true } : {}
|
|
393
383
|
},
|
|
394
384
|
capabilities,
|
|
395
|
-
...input.emailSharedZoneId !== void 0 ? { emailSharedZoneId: requiredString
|
|
385
|
+
...input.emailSharedZoneId !== void 0 ? { emailSharedZoneId: requiredString(input.emailSharedZoneId, "emailSharedZoneId") } : {},
|
|
396
386
|
...input.emailSenderDomain !== void 0 ? { emailSenderDomain: normalizeApplicationDomain(input.emailSenderDomain) } : {},
|
|
397
387
|
controlPlane: {
|
|
398
388
|
...CONTROL_PLANE_DEFAULTS,
|
|
@@ -402,7 +392,7 @@ function createPlatformDeploymentManifest(input) {
|
|
|
402
392
|
dashboardHostname: input.controlPlane?.dashboardHostname ?? new URL(dashboardUrl).hostname
|
|
403
393
|
} : {}
|
|
404
394
|
},
|
|
405
|
-
displayName: requiredString
|
|
395
|
+
displayName: requiredString(input.displayName, "displayName").trim(),
|
|
406
396
|
installationSlug,
|
|
407
397
|
resources,
|
|
408
398
|
schemaVersion: input.appAccess !== void 0 ? 4 : configurable ? 3 : workersDev ? 2 : 1
|
|
@@ -416,30 +406,30 @@ function createPlatformDeploymentManifest(input) {
|
|
|
416
406
|
const hostname = new URL(manifest.controlPlane.dashboardUrl).hostname;
|
|
417
407
|
if (manifest.controlPlane.dashboardHostname !== hostname) throw new Error("The dashboard URL and dashboard hostname must agree.");
|
|
418
408
|
}
|
|
419
|
-
for (const [key, value] of Object.entries(manifest.resources)) requiredString
|
|
409
|
+
for (const [key, value] of Object.entries(manifest.resources)) requiredString(value, `resources.${key}`);
|
|
420
410
|
return manifest;
|
|
421
411
|
}
|
|
422
412
|
function parsePlatformDeploymentManifest(value) {
|
|
423
|
-
assertRecord
|
|
413
|
+
assertRecord(value, "Platform deployment manifest");
|
|
424
414
|
if (value.schemaVersion !== 1 && value.schemaVersion !== 2 && value.schemaVersion !== 3 && value.schemaVersion !== 4) throw new Error(`Unsupported platform deployment schema version: ${String(value.schemaVersion)}.`);
|
|
425
415
|
const application = value.application;
|
|
426
416
|
const authentication = value.authentication;
|
|
427
417
|
const rawCapabilities = value.capabilities;
|
|
428
418
|
const controlPlane = value.controlPlane;
|
|
429
419
|
const rawResources = value.resources;
|
|
430
|
-
assertRecord
|
|
420
|
+
assertRecord(application, "application");
|
|
431
421
|
let workersDev;
|
|
432
422
|
if (value.schemaVersion === 2 || (value.schemaVersion === 3 || value.schemaVersion === 4) && application.workersDev !== void 0) {
|
|
433
|
-
assertRecord
|
|
423
|
+
assertRecord(application.workersDev, "application.workersDev");
|
|
434
424
|
workersDev = {
|
|
435
|
-
subdomain: requiredString
|
|
436
|
-
installationId: requiredString
|
|
425
|
+
subdomain: requiredString(application.workersDev.subdomain, "workersDev.subdomain"),
|
|
426
|
+
installationId: requiredString(application.workersDev.installationId, "workersDev.installationId")
|
|
437
427
|
};
|
|
438
428
|
} else if (application.workersDev !== void 0) throw new Error("workers.dev requires platform deployment schema version 2.");
|
|
439
|
-
assertRecord
|
|
440
|
-
assertRecord
|
|
441
|
-
assertRecord
|
|
442
|
-
assertRecord
|
|
429
|
+
assertRecord(rawCapabilities, "capabilities");
|
|
430
|
+
assertRecord(controlPlane, "controlPlane");
|
|
431
|
+
assertRecord(authentication, "authentication");
|
|
432
|
+
assertRecord(rawResources, "resources");
|
|
443
433
|
const capabilityKeys = Object.keys(CORE_CAPABILITIES);
|
|
444
434
|
const capabilities = {};
|
|
445
435
|
for (const key of capabilityKeys) {
|
|
@@ -456,19 +446,19 @@ function parsePlatformDeploymentManifest(value) {
|
|
|
456
446
|
"custom"
|
|
457
447
|
].includes(String(value.appAccess)) : value.appAccess !== void 0) throw new Error("Guided app access requires deployment schema version 4 and a valid appAccess choice.");
|
|
458
448
|
if (authentication.configurable !== void 0 && authentication.configurable !== true) throw new Error("Invalid configurable authentication flag.");
|
|
459
|
-
const resourceDefaults = createPlatformResourceNames(requiredString
|
|
449
|
+
const resourceDefaults = createPlatformResourceNames(requiredString(value.installationSlug, "installationSlug"));
|
|
460
450
|
const resources = {};
|
|
461
|
-
for (const key of Object.keys(resourceDefaults)) resources[key] = requiredString
|
|
451
|
+
for (const key of Object.keys(resourceDefaults)) resources[key] = requiredString(rawResources[key] ?? (key === "emailGatewayWorker" || key === "deploymentQueue" ? resourceDefaults[key] : void 0), `resources.${key}`);
|
|
462
452
|
const readHostname = (key) => {
|
|
463
453
|
const hostname = controlPlane[key];
|
|
464
|
-
return hostname === null ? null : requiredString
|
|
454
|
+
return hostname === null ? null : requiredString(hostname, `controlPlane.${key}`);
|
|
465
455
|
};
|
|
466
456
|
return createPlatformDeploymentManifest({
|
|
467
457
|
...value.schemaVersion === 4 ? { appAccess: value.appAccess } : {},
|
|
468
458
|
application: {
|
|
469
|
-
baseDomain: requiredString
|
|
459
|
+
baseDomain: requiredString(application.baseDomain, "application.baseDomain"),
|
|
470
460
|
dedicatedZone: application.dedicatedZone === true,
|
|
471
|
-
zoneName: workersDev && application.zoneName === "" ? "" : requiredString
|
|
461
|
+
zoneName: workersDev && application.zoneName === "" ? "" : requiredString(application.zoneName, "application.zoneName"),
|
|
472
462
|
...workersDev ? { workersDev } : {},
|
|
473
463
|
...typeof application.zoneId === "string" ? { zoneId: application.zoneId } : {}
|
|
474
464
|
},
|
|
@@ -478,16 +468,16 @@ function parsePlatformDeploymentManifest(value) {
|
|
|
478
468
|
...authentication.accessProtection === true ? { accessProtection: true } : {}
|
|
479
469
|
},
|
|
480
470
|
capabilities,
|
|
481
|
-
...value.emailSharedZoneId !== void 0 ? { emailSharedZoneId: requiredString
|
|
482
|
-
...value.emailSenderDomain !== void 0 ? { emailSenderDomain: requiredString
|
|
471
|
+
...value.emailSharedZoneId !== void 0 ? { emailSharedZoneId: requiredString(value.emailSharedZoneId, "emailSharedZoneId") } : {},
|
|
472
|
+
...value.emailSenderDomain !== void 0 ? { emailSenderDomain: requiredString(value.emailSenderDomain, "emailSenderDomain") } : {},
|
|
483
473
|
controlPlane: {
|
|
484
474
|
apiHostname: readHostname("apiHostname"),
|
|
485
475
|
dashboardHostname: readHostname("dashboardHostname"),
|
|
486
|
-
...controlPlane.dashboardUrl !== void 0 ? { dashboardUrl: requiredString
|
|
476
|
+
...controlPlane.dashboardUrl !== void 0 ? { dashboardUrl: requiredString(controlPlane.dashboardUrl, "controlPlane.dashboardUrl") } : {},
|
|
487
477
|
proxyHostname: readHostname("proxyHostname")
|
|
488
478
|
},
|
|
489
|
-
displayName: requiredString
|
|
490
|
-
installationSlug: requiredString
|
|
479
|
+
displayName: requiredString(value.displayName, "displayName"),
|
|
480
|
+
installationSlug: requiredString(value.installationSlug, "installationSlug"),
|
|
491
481
|
resources
|
|
492
482
|
});
|
|
493
483
|
}
|
|
@@ -609,13 +599,6 @@ const STATUS_TRANSITIONS = {
|
|
|
609
599
|
"uninstalling"
|
|
610
600
|
]
|
|
611
601
|
};
|
|
612
|
-
function assertRecord(value, label) {
|
|
613
|
-
if (!value || typeof value !== "object" || Array.isArray(value)) throw new Error(`${label} must be an object.`);
|
|
614
|
-
}
|
|
615
|
-
function requiredString(value, label) {
|
|
616
|
-
if (typeof value !== "string" || value.trim() === "") throw new Error(`${label} must be a non-empty string.`);
|
|
617
|
-
return value;
|
|
618
|
-
}
|
|
619
602
|
function isInstallationStatus(value) {
|
|
620
603
|
return typeof value === "string" && Object.hasOwn(STATUS_TRANSITIONS, value);
|
|
621
604
|
}
|
|
@@ -847,15 +830,14 @@ function parseAuthenticationResources(value) {
|
|
|
847
830
|
return resources;
|
|
848
831
|
}
|
|
849
832
|
function parseUsageProtocolVersion(value) {
|
|
850
|
-
if (value === void 0
|
|
851
|
-
if (value
|
|
852
|
-
|
|
853
|
-
throw new Error("usageProtocolVersion must be 0, 1, or 2.");
|
|
833
|
+
if (value === void 0) return 0;
|
|
834
|
+
if (!isUsageProtocolVersion(value)) throw new Error("usageProtocolVersion must be 0, 1, or 2.");
|
|
835
|
+
return value;
|
|
854
836
|
}
|
|
855
837
|
function parseSafetyProtocols(value) {
|
|
856
838
|
if (value === void 0) return { sandboxDrain: 0 };
|
|
857
839
|
assertRecord(value, "safetyProtocols");
|
|
858
|
-
if (value.sandboxDrain
|
|
840
|
+
if (!isSandboxDrainProtocol(value.sandboxDrain)) throw new Error("safetyProtocols.sandboxDrain must be 0, 1, 2, or 3.");
|
|
859
841
|
return { sandboxDrain: value.sandboxDrain };
|
|
860
842
|
}
|
|
861
843
|
function parsePlatformRuntimeProvenance(value) {
|
|
@@ -865,7 +847,7 @@ function parsePlatformRuntimeProvenance(value) {
|
|
|
865
847
|
const manifestSha256 = requiredString(value.manifestSha256, "runtime.manifestSha256");
|
|
866
848
|
if (!/^[0-9a-f]{64}$/.test(manifestSha256)) throw new Error("runtime.manifestSha256 must be a SHA-256 digest.");
|
|
867
849
|
const sourceRevision = value.sourceRevision === null || value.sourceRevision === void 0 ? null : requiredString(value.sourceRevision, "runtime.sourceRevision");
|
|
868
|
-
if (sourceRevision !== null && (sourceRevision
|
|
850
|
+
if (sourceRevision !== null && !isSourceRevision(sourceRevision)) throw new Error("runtime.sourceRevision is invalid.");
|
|
869
851
|
return {
|
|
870
852
|
manifestSha256,
|
|
871
853
|
source: value.source,
|
|
@@ -890,10 +872,14 @@ function readPlatformApplication(env) {
|
|
|
890
872
|
zoneName: baseDomain,
|
|
891
873
|
dedicatedZone: false
|
|
892
874
|
};
|
|
875
|
+
return parsePlatformApplication(JSON.parse(env.PLATFORM_APPLICATION));
|
|
876
|
+
}
|
|
877
|
+
/** Applies the deployment manifest's application rules to a parsed value. */
|
|
878
|
+
function parsePlatformApplication(value) {
|
|
893
879
|
return createPlatformDeploymentManifest({
|
|
894
880
|
installationSlug: "runtime",
|
|
895
881
|
displayName: "Runtime",
|
|
896
|
-
application:
|
|
882
|
+
application: value
|
|
897
883
|
}).application;
|
|
898
884
|
}
|
|
899
885
|
function platformWorkersDevAliasKey(hostname) {
|
|
@@ -968,7 +954,7 @@ function createPlatformDiscoveryDocument(input) {
|
|
|
968
954
|
if (!input.displayName.trim()) throw new Error("displayName must not be empty.");
|
|
969
955
|
if (!input.platformVersion.trim()) throw new Error("platformVersion must not be empty.");
|
|
970
956
|
if (input.applicationRouting) {
|
|
971
|
-
const application =
|
|
957
|
+
const application = parsePlatformApplication(input.applicationRouting);
|
|
972
958
|
if (!application.workersDev || application.baseDomain !== input.applicationDomain || application.workersDev.installationId !== input.installationId) throw new Error("Application routing must match the discovery domain and installation identity.");
|
|
973
959
|
}
|
|
974
960
|
const usageProtocolVersion = parseUsageProtocolVersion(input.usageProtocolVersion);
|
|
@@ -994,13 +980,12 @@ function createPlatformDiscoveryDocument(input) {
|
|
|
994
980
|
};
|
|
995
981
|
}
|
|
996
982
|
function parsePlatformDiscoveryDocument(value) {
|
|
997
|
-
|
|
998
|
-
const document = value;
|
|
983
|
+
const document = record(value, "Platform discovery document");
|
|
999
984
|
if (document.schemaVersion !== 1 && document.schemaVersion !== 2 && document.schemaVersion !== 3) throw new Error(`Unsupported platform discovery schema version: ${String(document.schemaVersion)}.`);
|
|
1000
985
|
const capabilities = document.capabilities;
|
|
1001
986
|
if (document.schemaVersion === 1 && document.applicationRouting !== void 0) throw new Error("Application routing requires discovery schema version 2.");
|
|
1002
987
|
if (document.schemaVersion === 2 && document.applicationRouting === void 0) throw new Error("Discovery schema version 2 requires application routing.");
|
|
1003
|
-
|
|
988
|
+
assertRecord(capabilities, "capabilities");
|
|
1004
989
|
const capabilityNames = [
|
|
1005
990
|
"ai",
|
|
1006
991
|
"customDomains",
|
|
@@ -1032,7 +1017,7 @@ function parsePlatformDiscoveryDocument(value) {
|
|
|
1032
1017
|
return createPlatformDiscoveryDocument({
|
|
1033
1018
|
apiUrl,
|
|
1034
1019
|
applicationDomain: string("applicationDomain"),
|
|
1035
|
-
...document.applicationRouting !== void 0 ? { applicationRouting:
|
|
1020
|
+
...document.applicationRouting !== void 0 ? { applicationRouting: parsePlatformApplication(document.applicationRouting) } : {},
|
|
1036
1021
|
authenticationProviders: providers,
|
|
1037
1022
|
...authentication ? { authentication } : {},
|
|
1038
1023
|
capabilities: parsedCapabilities,
|
|
@@ -1045,8 +1030,7 @@ function parsePlatformDiscoveryDocument(value) {
|
|
|
1045
1030
|
});
|
|
1046
1031
|
}
|
|
1047
1032
|
function parseAuthentication(value) {
|
|
1048
|
-
|
|
1049
|
-
const authentication = value;
|
|
1033
|
+
const authentication = record(value, "Authentication discovery");
|
|
1050
1034
|
if (!Array.isArray(authentication.methods) || authentication.methods.length > 32 || typeof authentication.protectedByAccess !== "boolean" || authentication.setupPending !== void 0 && typeof authentication.setupPending !== "boolean") throw new Error("Authentication discovery requires login methods and a protection flag.");
|
|
1051
1035
|
const methods = authentication.methods.map(parsePlatformLoginDescriptor);
|
|
1052
1036
|
if (new Set(methods.map((method) => method.id)).size !== methods.length) throw new Error("Authentication connection IDs must be unique.");
|
|
@@ -1281,7 +1265,6 @@ function createPlatformWorkerConfigs(input) {
|
|
|
1281
1265
|
proxy,
|
|
1282
1266
|
emailGateway: {
|
|
1283
1267
|
...common,
|
|
1284
|
-
workers_dev: publicEndpoints,
|
|
1285
1268
|
preview_urls: false,
|
|
1286
1269
|
name: names.emailGatewayWorker,
|
|
1287
1270
|
main: runtimeEntrypoints.emailGateway,
|
package/dist/installer.mjs
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { a as isSourceRevision, i as isSandboxDrainProtocol, o as isUsageProtocolVersion, r as isRecord } from "./validate-DbJR7Q0Z.mjs";
|
|
1
2
|
import { createHash } from "node:crypto";
|
|
2
3
|
import { readFileSync, realpathSync, statSync } from "node:fs";
|
|
3
4
|
import { fileURLToPath } from "node:url";
|
|
@@ -105,26 +106,20 @@ function parsePlatformRuntimeManifest(value) {
|
|
|
105
106
|
}
|
|
106
107
|
function parseSafetyProtocols(value) {
|
|
107
108
|
if (value === void 0) return { sandboxDrain: 0 };
|
|
108
|
-
const
|
|
109
|
-
if (
|
|
110
|
-
return { sandboxDrain
|
|
109
|
+
const { sandboxDrain } = record(value, "runtime manifest safetyProtocols");
|
|
110
|
+
if (!isSandboxDrainProtocol(sandboxDrain)) throw new Error("runtime manifest safetyProtocols.sandboxDrain must be 0, 1, 2, or 3");
|
|
111
|
+
return { sandboxDrain };
|
|
111
112
|
}
|
|
112
113
|
function usageProtocolVersion(value) {
|
|
113
|
-
if (value === void 0
|
|
114
|
-
if (value
|
|
115
|
-
|
|
116
|
-
throw new Error("runtime manifest usageProtocolVersion must be 0, 1, or 2");
|
|
114
|
+
if (value === void 0) return 0;
|
|
115
|
+
if (!isUsageProtocolVersion(value)) throw new Error("runtime manifest usageProtocolVersion must be 0, 1, or 2");
|
|
116
|
+
return value;
|
|
117
117
|
}
|
|
118
118
|
function getPlatformRuntimeDirectory() {
|
|
119
119
|
return join(dirname(fileURLToPath(import.meta.url)), "runtime");
|
|
120
120
|
}
|
|
121
121
|
function readPlatformRuntimeManifest(runtimeDirectory = getPlatformRuntimeDirectory()) {
|
|
122
|
-
|
|
123
|
-
try {
|
|
124
|
-
return parsePlatformRuntimeManifest(JSON.parse(readFileSync(path, "utf8")));
|
|
125
|
-
} catch (error) {
|
|
126
|
-
throw new Error(`Void Platform deployment artifacts are missing or invalid at ${path}: ${error instanceof Error ? error.message : String(error)}`);
|
|
127
|
-
}
|
|
122
|
+
return readRuntimeManifestFile(join(runtimeDirectory, "manifest.json")).manifest;
|
|
128
123
|
}
|
|
129
124
|
function resolvePlatformRuntime(customRuntimeDirectory, baseDirectory = process.cwd()) {
|
|
130
125
|
const source = customRuntimeDirectory ? "custom" : "package";
|
|
@@ -136,22 +131,25 @@ function resolvePlatformRuntime(customRuntimeDirectory, baseDirectory = process.
|
|
|
136
131
|
} catch (error) {
|
|
137
132
|
throw new Error(`Void Platform runtime directory is unavailable at ${requestedDirectory}: ${error instanceof Error ? error.message : String(error)}`);
|
|
138
133
|
}
|
|
139
|
-
const
|
|
140
|
-
let manifestContents;
|
|
141
|
-
let manifest;
|
|
142
|
-
try {
|
|
143
|
-
manifestContents = readFileSync(manifestPath);
|
|
144
|
-
manifest = parsePlatformRuntimeManifest(JSON.parse(manifestContents.toString("utf8")));
|
|
145
|
-
} catch (error) {
|
|
146
|
-
throw new Error(`Void Platform deployment artifacts are missing or invalid at ${manifestPath}: ${error instanceof Error ? error.message : String(error)}`);
|
|
147
|
-
}
|
|
134
|
+
const { contents, manifest } = readRuntimeManifestFile(join(directory, "manifest.json"));
|
|
148
135
|
return {
|
|
149
136
|
directory,
|
|
150
137
|
manifest,
|
|
151
|
-
manifestSha256: createHash("sha256").update(
|
|
138
|
+
manifestSha256: createHash("sha256").update(contents).digest("hex"),
|
|
152
139
|
source
|
|
153
140
|
};
|
|
154
141
|
}
|
|
142
|
+
function readRuntimeManifestFile(path) {
|
|
143
|
+
try {
|
|
144
|
+
const contents = readFileSync(path);
|
|
145
|
+
return {
|
|
146
|
+
contents,
|
|
147
|
+
manifest: parsePlatformRuntimeManifest(JSON.parse(contents.toString("utf8")))
|
|
148
|
+
};
|
|
149
|
+
} catch (error) {
|
|
150
|
+
throw new Error(`Void Platform deployment artifacts are missing or invalid at ${path}: ${error instanceof Error ? error.message : String(error)}`);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
155
153
|
function parseArtifact(value, name) {
|
|
156
154
|
const artifact = record(value, `runtime manifest artifact ${name}`);
|
|
157
155
|
const path = nonemptyString(artifact.path, `runtime manifest artifact ${name} path`);
|
|
@@ -179,7 +177,7 @@ function parseMigration(value, position) {
|
|
|
179
177
|
};
|
|
180
178
|
}
|
|
181
179
|
function record(value, name) {
|
|
182
|
-
if (!
|
|
180
|
+
if (!isRecord(value)) throw new Error(`${name} must be an object`);
|
|
183
181
|
return value;
|
|
184
182
|
}
|
|
185
183
|
function array(value, name) {
|
|
@@ -192,7 +190,7 @@ function nonemptyString(value, name) {
|
|
|
192
190
|
}
|
|
193
191
|
function sourceRevision(value) {
|
|
194
192
|
const revision = nonemptyString(value, "runtime manifest sourceRevision");
|
|
195
|
-
if (
|
|
193
|
+
if (!isSourceRevision(revision)) throw new Error("runtime manifest sourceRevision is invalid");
|
|
196
194
|
return revision;
|
|
197
195
|
}
|
|
198
196
|
function safeInteger(value, name) {
|
package/dist/plans.mjs
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { n as isPrintableText, s as record } from "./validate-DbJR7Q0Z.mjs";
|
|
1
2
|
//#region src/plans.ts
|
|
2
3
|
const GB = 1073741824;
|
|
3
4
|
const PLAN_LIMITS = {
|
|
@@ -119,15 +120,11 @@ function parsePlatformPlanId(value) {
|
|
|
119
120
|
return value;
|
|
120
121
|
}
|
|
121
122
|
function parsePlanName(value) {
|
|
122
|
-
if (
|
|
123
|
+
if (!isPrintableText(value, 80)) throw new Error("Plan names must contain 1 to 80 printable characters.");
|
|
123
124
|
return value.trim();
|
|
124
125
|
}
|
|
125
|
-
function object(value, label) {
|
|
126
|
-
if (!value || typeof value !== "object" || Array.isArray(value)) throw new Error(label + " must be an object.");
|
|
127
|
-
return value;
|
|
128
|
-
}
|
|
129
126
|
function parsePlanLimitsPatch(value) {
|
|
130
|
-
const input =
|
|
127
|
+
const input = record(value, "Plan limits");
|
|
131
128
|
for (const [key, limit] of Object.entries(input)) {
|
|
132
129
|
if (!PLAN_EDITABLE_LIMIT_KEYS.includes(key)) throw new Error("Unknown or unenforced plan limit: " + key + ".");
|
|
133
130
|
if (!Number.isSafeInteger(limit) || limit < 0) throw new Error(key + " must be a nonnegative safe integer; 0 means unlimited.");
|
|
@@ -146,18 +143,18 @@ function parseBuildInstanceType(value) {
|
|
|
146
143
|
}
|
|
147
144
|
/** Strict saved-state validation: invalid configuration must not silently lift quotas. */
|
|
148
145
|
function parsePlatformPlanCatalog(value) {
|
|
149
|
-
const input =
|
|
146
|
+
const input = record(value, "Plan catalog");
|
|
150
147
|
if (!Number.isSafeInteger(input.revision) || input.revision < 0) throw new Error("Invalid plan catalog revision.");
|
|
151
148
|
if (!Array.isArray(input.plans) || input.plans.length === 0 || input.plans.length > 100) throw new Error("A plan catalog must contain between 1 and 100 plans.");
|
|
152
149
|
const ids = /* @__PURE__ */ new Set();
|
|
153
150
|
const plans = input.plans.map((value) => {
|
|
154
|
-
const plan =
|
|
151
|
+
const plan = record(value, "Plan");
|
|
155
152
|
const id = parsePlatformPlanId(plan.id);
|
|
156
153
|
if (ids.has(id)) throw new Error("Duplicate plan ID: " + id + ".");
|
|
157
154
|
ids.add(id);
|
|
158
155
|
if (typeof plan.archived !== "boolean") throw new Error("archived must be a boolean.");
|
|
159
156
|
if (typeof plan.allowShortSlugs !== "boolean") throw new Error("allowShortSlugs must be a boolean.");
|
|
160
|
-
const limits =
|
|
157
|
+
const limits = record(plan.limits, "Plan limits");
|
|
161
158
|
const keys = Object.keys(PLAN_LIMITS.free);
|
|
162
159
|
if (Object.keys(limits).length !== keys.length || keys.some((key) => !Object.hasOwn(limits, key))) throw new Error("Plan limits must contain all supported fields.");
|
|
163
160
|
validatePlanLimits(limits);
|
|
@@ -174,13 +171,13 @@ function parsePlatformPlanCatalog(value) {
|
|
|
174
171
|
if (!plans.some((plan) => plan.id === defaultPlanId && !plan.archived)) throw new Error("The default plan must exist and be active.");
|
|
175
172
|
let reconciliation = null;
|
|
176
173
|
if (input.reconciliation !== null) {
|
|
177
|
-
const operation =
|
|
174
|
+
const operation = record(input.reconciliation, "Plan reconciliation");
|
|
178
175
|
if (operation.revision !== input.revision || typeof operation.complete !== "boolean" || !(operation.cursor === null || typeof operation.cursor === "string") || !Array.isArray(operation.planIds) || operation.planIds.length > 100) throw new Error("Invalid plan reconciliation state.");
|
|
179
176
|
const planIds = operation.planIds.map(parsePlatformPlanId);
|
|
180
177
|
if (planIds.some((id) => !ids.has(id))) throw new Error("A reconciliation plan is missing.");
|
|
181
178
|
let error;
|
|
182
179
|
if (operation.error !== void 0) {
|
|
183
|
-
const failure =
|
|
180
|
+
const failure = record(operation.error, "Plan reconciliation failure");
|
|
184
181
|
if (typeof failure.accountId !== "string" || typeof failure.message !== "string" || failure.message.length > 1e3) throw new Error("Invalid plan reconciliation failure.");
|
|
185
182
|
error = {
|
|
186
183
|
accountId: failure.accountId,
|