import { z } from "zod"; import type { BlockComponents } from "./block_components"; import { WorkflowSchemaV1 } from "./block_components"; import { ContentRelative, ContentRelativeBinary, ContentRelativeText } from "./content_types"; import { CreateBlockPackDescriptionSchema } from "./block_description"; import { BlockPackMeta } from "./block_meta"; import { toMerged } from "es-toolkit"; import type { BlockPackId } from "./block_id"; export type BlockComponentsManifest = BlockComponents; /** * Block-components shape stored in a manifest. The consolidator always writes * the wrapped `{type: "workflow-v1", main: ...}` form, so the manifest schema * accepts the wrapped form only. */ export const BlockComponentsManifest = z.object({ workflow: WorkflowSchemaV1(ContentRelative), model: ContentRelative, ui: ContentRelative, }) satisfies z.ZodType; export const BlockPackMetaManifest = BlockPackMeta(ContentRelativeText, ContentRelativeBinary); export type BlockPackMetaManifest = z.infer; /** Block description to be used in block manifest */ export const BlockPackDescriptionManifest = CreateBlockPackDescriptionSchema( BlockComponentsManifest, BlockPackMetaManifest, ); export type BlockPackDescriptionManifest = z.infer; export const Sha256Schema = z .string() .regex(/[0-9a-fA-F]/) .toUpperCase() .length(64); // 256 / 4 (bits per hex register); export const ManifestFileInfo = z.object({ name: z.string(), size: z.number().int(), sha256: Sha256Schema, }); export type ManifestFileInfo = z.infer; export const BlockPackManifest = z .object({ schema: z.literal("v2"), description: BlockPackDescriptionManifest, timestamp: z.number().optional(), files: z.array(ManifestFileInfo), }) .passthrough(); export type BlockPackManifest = z.infer; export const BlockPackManifestFile = "manifest.json"; export function overrideManifestVersion( manifest: T, newVersion: string, ): T { return toMerged(manifest, { description: { id: { version: newVersion } } }) as T; }