Declare SCUM Run data targets
This commit is contained in:
@@ -1064,6 +1064,7 @@ export function validateSCUMLiveDataManifest(manifest: unknown, manifestDir?: st
|
||||
type Gate = { capability?: string; gate?: string; adapterVersion?: string; requiredSchemaFingerprint?: string; requiredAssetDigests?: string[]; evidenceStatus?: string; safeReason?: string };
|
||||
type Probe = { capability?: string; targetKey?: string; bounds?: { maxSampleRows?: number; timeoutMs?: number; maxResultBytes?: number } };
|
||||
type Transport = { key?: string; kind?: string; targetKey?: string; capabilities?: string[] };
|
||||
type DataTarget = { key?: string; kind?: string; transportKey?: string; sourceRootKey?: string; sourcePath?: string; workspaceKey?: string; refreshPolicy?: string; maxBytes?: number; platforms?: string[] };
|
||||
type RuntimeLogSource = { key?: string };
|
||||
type AssetFile = { path?: string };
|
||||
type Asset = { key?: string; adapterVersion?: string; assetPath?: string; digest?: string };
|
||||
@@ -1075,7 +1076,7 @@ export function validateSCUMLiveDataManifest(manifest: unknown, manifestDir?: st
|
||||
type MapAsset = Asset & { requiredSchemaFingerprint?: string; metadataSchemaRef?: string; transformAssetPath?: string; transformDigest?: string; worldBounds?: { minX?: number; minY?: number; maxX?: number; maxY?: number }; image?: { width?: number; height?: number } };
|
||||
type GiftCatalog = Asset & { catalogVersion?: string; itemSchemaRef?: string; transportTemplateKeys?: string[] };
|
||||
type LiveData = { schemaVersion?: string; probe?: Probe; capabilityGates?: Gate[]; logParsers?: LogParser[]; sqliteQueries?: SQLiteQuery[]; syncCadences?: SyncCadence[]; typedRconTemplates?: TypedRCON[]; guardedMutations?: GuardedMutation[]; mapAssets?: MapAsset[]; giftCatalogs?: GiftCatalog[] };
|
||||
const declaration = manifest as { id?: string; capabilities?: string[]; permissions?: string[]; assetFiles?: AssetFile[]; remoteAccess?: { runCapabilities?: string[]; databaseEngines?: string[] }; runtimeProfiles?: { transportProfiles?: Transport[]; logSources?: RuntimeLogSource[] }; scumLiveData?: LiveData };
|
||||
const declaration = manifest as { id?: string; capabilities?: string[]; permissions?: string[]; assetFiles?: AssetFile[]; remoteAccess?: { runCapabilities?: string[]; databaseEngines?: string[] }; runtimeProfiles?: { transportProfiles?: Transport[]; dataTargets?: DataTarget[]; logSources?: RuntimeLogSource[] }; scumLiveData?: LiveData };
|
||||
const liveData = declaration.scumLiveData;
|
||||
if (!liveData) return [];
|
||||
|
||||
@@ -1085,6 +1086,7 @@ export function validateSCUMLiveDataManifest(manifest: unknown, manifestDir?: st
|
||||
const remoteCapabilities = new Set(declaration.remoteAccess?.runCapabilities ?? []);
|
||||
const remoteDatabaseEngines = new Set(declaration.remoteAccess?.databaseEngines ?? []);
|
||||
const transportProfiles = declaration.runtimeProfiles?.transportProfiles ?? [];
|
||||
const dataTargets = declaration.runtimeProfiles?.dataTargets ?? [];
|
||||
const logSources = new Set((declaration.runtimeProfiles?.logSources ?? []).map((source) => source.key ?? ""));
|
||||
const assetFiles = new Set((declaration.assetFiles ?? []).map((asset) => asset.path ?? ""));
|
||||
const probe = liveData.probe;
|
||||
@@ -1157,6 +1159,17 @@ export function validateSCUMLiveDataManifest(manifest: unknown, manifestDir?: st
|
||||
}
|
||||
};
|
||||
const transportByKey = (key?: string): Transport | undefined => transportProfiles.find((candidate) => candidate.key === key);
|
||||
const probeDataTarget = dataTargets.find((candidate) => candidate.key === probe?.targetKey);
|
||||
const expectedProbeWorkspaceKey = `databases/${String(probe?.targetKey ?? "").replace(/^databases\//, "")}`;
|
||||
if (!probeDataTarget) {
|
||||
errors.push(`${location}.probe.targetKey: must reference a declared runtime data target`);
|
||||
} else {
|
||||
const probeDataTargetTransport = transportByKey(probeDataTarget.transportKey);
|
||||
if (probeDataTarget.kind !== "sqlite.snapshot" || probeDataTarget.workspaceKey !== expectedProbeWorkspaceKey || probeDataTarget.refreshPolicy !== "on-demand-snapshot" || !probeDataTargetTransport || probeDataTargetTransport.kind !== "sqlite" || !probeDataTargetTransport.capabilities?.includes("remote.run.db.sqlite.probe")) {
|
||||
errors.push(`${location}.probe.targetKey: must reference a sqlite snapshot data target for the generated Run workspace`);
|
||||
}
|
||||
if (!Number.isInteger(probeDataTarget.maxBytes) || (probeDataTarget.maxBytes ?? 0) < 1 || (probeDataTarget.maxBytes ?? 0) > 1073741824) errors.push(`${location}.probe.targetKey.maxBytes: must be between 1 and 1073741824`);
|
||||
}
|
||||
const requireRefs = (entry: Record<string, unknown>, entryLocation: string, refs: string[]): void => {
|
||||
for (const field of refs) {
|
||||
const ref = entry[field];
|
||||
|
||||
Reference in New Issue
Block a user