/** * Release Asset Manifest — builder executor. * * Runs inside the project runtime as the `task:release-asset-build` handler. * Materializes a release's file set, transforms every browser module through * the SAME pipeline `serveModule` uses (byte parity is a hard requirement), * compiles route CSS where reachable, content-addresses and * uploads each asset, then assembles and PUTs the manifest (→ ready). * * Defensive by construction: * - Any browser graph or CSS coverage failure prevents manifest publication. * - Build failures (transform/list/hash/upload/PUT) report `failed`. * - The temp dir is always cleaned up by the caller. * * @module release-assets/build-executor */ import type { VeryfrontConfig } from "../config/index.js"; import { VERYFRONT_CONFIG_FILES } from "../config/config-files.js"; import type { RuntimeAdapter } from "../platform/adapters/base.js"; import { type DependencyPinningSnapshot, type DependencyPinningSourceInput } from "../transforms/esm/package-registry.js"; import { type ReleaseAssetContentType } from "./constants.js"; export { routeForPage } from "./route-path.js"; import { type ReleaseAssetDependencyMode } from "./manifest-schema.js"; import type { CompileProjectCssResult } from "./css-compile.js"; type VeryfrontConfigFileName = (typeof VERYFRONT_CONFIG_FILES)[number]; /** Inputs required to build and publish one release asset manifest generation. */ export interface ReleaseAssetBuildInput { /** Project reference (slug or id) used for API calls. */ projectReference: string; /** Project UUID. */ projectId: string; /** Release UUID. */ releaseId: string; /** Release version (integer). */ releaseVersion: number; /** Release version string used for API path segments. */ releaseVersionRef: string; /** * Trusted composition seam for declaratively evaluating the exact config * source selected from the immutable release file set. Implementations must * return a validated configuration snapshot without executing tenant code in * the host realm. `null` requests framework defaults. */ loadConfig: ReleaseAssetConfigLoader; /** Authenticated, project-scoped API client. */ client: ReleaseAssetBuildClient; /** Runtime adapter used by the transform pipeline. */ adapter: RuntimeAdapter; /** * Dependency closure represented by the published manifest. `immutable` * requires an explicitly composed policy-enforced vendor; `source` keeps * transformed HTTP imports on their canonical source URLs. */ dependencyMode: ReleaseAssetDependencyMode; /** * Explicit browser transform composition seam. Production must provide the * same pipeline `serveModule` uses (browser, non-SSR); byte parity is a hard * requirement. */ transform: ReleaseAssetTransform; /** * HTTP dependency vendor required by `dependencyMode: "immutable"`. */ vendorHttpImports?: ReleaseAssetHttpDependencyVendor; } /** Exact configuration source selected from the immutable release file set. */ export interface ReleaseAssetConfigSource { readonly fileName: VeryfrontConfigFileName; readonly source: string; } /** Trusted release configuration composition boundary. */ export type ReleaseAssetConfigLoader = (source: ReleaseAssetConfigSource | null) => Promise; /** Browser transform contract shared with the module-serving pipeline. */ export type ReleaseAssetTransform = (source: string, sourceFile: string, projectDir: string, adapter: RuntimeAdapter, options: { projectId: string; dev: boolean; ssr: boolean; reactVersion?: string; /** Immutable dependency state shared by every transform in this build. */ dependencyPinningSnapshot?: DependencyPinningSnapshot; /** Package source paired with dependencyPinningSnapshot. */ dependencyPinningSource?: DependencyPinningSourceInput; }) => Promise; /** One vendored dependency and the source identity represented by its code. */ export interface ReleaseAssetVendorDependency { /** Specifier currently used by transformed code after vendoring. */ specifier: string; /** Stable manifest key, normally the original HTTP source URL. */ manifestKey: string; /** Absolute local cache path when the dependency came from disk. */ sourcePath?: string; /** Browser ESM source for this dependency. */ code: string; } /** Rewritten module code plus every dependency needed by that rewrite. */ export interface ReleaseAssetVendorResult { code: string; dependencies: ReleaseAssetVendorDependency[]; } /** Injectable HTTP dependency vendoring contract. */ export type ReleaseAssetHttpDependencyVendor = (code: string, options: { tempDir: string; reactVersion?: string; }) => Promise; /** Subset of the API client used by the builder (eases testing). */ export interface ReleaseAssetBuildClient { beginReleaseAssetManifestBuild(version: string): Promise<{ id: string; manifest_version: number; state: string; }>; listAllReleaseFiles(version: string): Promise>; uploadReleaseAsset(version: string, contentHash: string, contentType: ReleaseAssetContentType, bytes: Uint8Array): Promise<{ stored: boolean; existed: boolean; }>; putReleaseAssetManifest(version: string, manifest: unknown): Promise<{ state: string; manifest_version?: number; }>; reportReleaseAssetManifestState(version: string, state: "failed", error?: string): Promise; /** * Required project CSS compiler. A build client without an explicitly * composed CSS pipeline is invalid even when the current source set happens * not to request CSS. * * Receives the CSS class candidates extracted from the release source * plus the resolved project stylesheet (so the implementation can compile * without re-fetching the file set). It may return `null` only when neither * candidates nor a stylesheet require CSS. Invalid output and compilation * failures fail the release build. */ compileProjectCss(candidates: Set, stylesheet: string | undefined, options: { config: VeryfrontConfig; }): Promise; } /** Observable outcome of a release asset build attempt. */ export interface ReleaseAssetBuildResult { success: boolean; state: "ready" | "failed"; moduleCount: number; cssCount: number; routeCount: number; /** Bounded coverage diagnostics; always empty for a successful build. */ coverageFailures: readonly string[]; error?: string; } interface PreparedAsset { logicalPath: string; contentHash: string; size: number; contentType: ReleaseAssetContentType; } /** Prepared content-addressed asset bytes ready for upload. */ export interface PreparedReleaseAsset extends PreparedAsset { bytes: Uint8Array; } declare function releaseLogicalPathFromMaterializedPath(basePath: string, tempDir: string, hostOs?: string): string; /** @internal Test seams for portable release materialization rules. */ export declare const releaseAssetBuildInternals: Readonly<{ releaseLogicalPathFromMaterializedPath: typeof releaseLogicalPathFromMaterializedPath; }>; export declare function buildReleaseAssetDependencyUrlMap(dependencies: Record): Map; export declare function buildReactImportMapDependencyAssets(options: { tempDir: string; reactVersion?: string; vendorHttpImports: ReleaseAssetHttpDependencyVendor; }): Promise<{ dependencies: Record; assets: PreparedReleaseAsset[]; gaps: string[]; }>; export declare function buildCachedHttpDependencyAssets(options: { cacheDir: string; }): Promise<{ dependencies: Record; assets: PreparedReleaseAsset[]; gaps: string[]; }>; export declare function buildFrameworkDependencyAssets(options: { tempDir: string; adapter: RuntimeAdapter; reactVersion?: string; projectId?: string; transform: ReleaseAssetTransform; dependencyUrls: Map; dependencyPinningSnapshot?: DependencyPinningSnapshot; dependencyPinningSource?: DependencyPinningSourceInput; }): Promise<{ dependencies: Record; assets: PreparedReleaseAsset[]; gaps: string[]; }>; /** * Execute a release asset build. Pure orchestration over the injected client * and a runtime-provided temp dir + react version. */ export declare function runReleaseAssetBuild(input: ReleaseAssetBuildInput, tempDir: string): Promise; //# sourceMappingURL=build-executor.d.ts.map