/** * Pre-publish validators for Zveltio extensions (S4-04). * * Pure functions — no Node-specific imports, no Zod runtime. Designed so the * CLI (`zveltio extension validate`) can call them on file contents read from * disk, the engine can call them on uploaded archives, and registry code can * call them on publish. Each returns a `ValidationResult` with structured * diagnostics instead of throwing, so the CLI can print all problems at once. * * What's checked: * - manifest.json shape (required fields, semver, sane category) * - name matches the folder path it lives in * - peerDependencies appear on the platform allow-list * - migration SQL files parse + table coverage looks sane * - destructive DDL in migrations has a `-- DOWN` section * - bundle size stays within quota * * Out of scope (deferred): * - Loading the extension module to inspect its default export. Requires * a Bun runtime + sandbox. CLI's `validate` cannot guarantee correctness * for runtime contracts; that's what `extension types` (S4-01) + `tsc` * gives you locally. * - Building the Studio bundle. Too slow; pair with `zveltio extension build` * which can call validate as a sub-step. */ export interface ValidationError { /** Stable machine-readable code (e.g. `MANIFEST_NAME_MISMATCH`). */ code: string; /** Operator-facing message. */ message: string; /** Optional file path the error applies to, relative to the extension root. */ file?: string; } export interface ValidationResult { ok: boolean; errors: ValidationError[]; /** Counts surfaced for human-readable summaries. */ stats: { tables: number; migrations: number; peerDeps: number; }; } export interface ManifestValidationInput { /** Parsed JSON object (or `null` if file couldn't be read). */ manifest: unknown; /** Folder path slug — e.g. `'finance/invoicing'`. Used for name-match. */ expectedName?: string; } export declare function validateManifest(input: ManifestValidationInput): ValidationError[]; export interface PeerDepsValidationInput { /** From manifest.json: `{ "lodash": "^4.0.0", ... }` (or undefined). */ peerDependencies: Record | undefined; /** The platform allow-list (caller supplies it — see peer-deps-allowlist.ts). */ allowedPackages: ReadonlySet; } export declare function validatePeerDependencies(input: PeerDepsValidationInput): ValidationError[]; export interface MigrationsValidationInput { /** Pairs of (filename, sql contents). Filename is just for diagnostics. */ files: Array<{ filename: string; sql: string; }>; /** When `true`, every migration with destructive DDL must have a -- DOWN section. */ requireDownForDestructive?: boolean; } export declare function validateMigrations(input: MigrationsValidationInput): ValidationError[]; export interface FilePresenceInput { /** Mapping of relative path → existence boolean. Caller does the disk hit. */ paths: Record; /** Paths that MUST exist. */ required: string[]; } export declare function validateFilePresence(input: FilePresenceInput): ValidationError[]; export interface BundleSizeInput { /** Size of the extension folder (excluding node_modules), in bytes. */ bundleBytes: number; /** Override the default cap (50 MB). */ bundleSizeKbMax?: number; } export declare function validateBundleSize(input: BundleSizeInput): ValidationError[]; export interface ValidateExtensionInput { manifest: ManifestValidationInput; peerDeps: PeerDepsValidationInput; migrations: MigrationsValidationInput; filePresence: FilePresenceInput; bundleSize?: BundleSizeInput; /** Numbers used to fill the result's `stats` for human summaries. */ stats: { tables: number; migrations: number; }; } export declare function validateExtension(input: ValidateExtensionInput): ValidationResult; //# sourceMappingURL=index.d.ts.map