Ported from PR #15 (packages-side surface only; the fork's dev UI page is intentionally dropped - the API surface is the product): - job_events table + repository, worker emits stage transitions, additive GET /v1/clones/:id/events polling route. The fork's hand-written migration was never registered in Drizzle's journal (it silently never applied); regenerated properly via drizzle-kit from schema.ts with the (job_id, seq) index declared, and verified against a live Postgres - In-memory backend moves to the documented enqueue-202 + poll contract with single-flight BUSY guard; POST honors backend httpStatus - app-preview static serving routes; the preview BUILD half is deferred until the compiler exports buildApp/DEFAULT_HARNESS_DIR - routes 404 cleanly until then - preview option threaded through core types; cache key intentionally unchanged while the flag is inert All workspaces typecheck; api 18/18, core 13/13, worker 1/1 pass; migration verified applying (table + index + FK) on postgres:16. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
62 lines
2.1 KiB
TypeScript
62 lines
2.1 KiB
TypeScript
import type { CloneFramework, CloneMode, CloneOptions, CloneStyling } from "./types.js";
|
|
|
|
export type ResolvedCloneOptions = CloneOptions & {
|
|
mode: CloneMode;
|
|
styling: CloneStyling;
|
|
framework: CloneFramework;
|
|
multiPage: boolean;
|
|
humanizeMode: CloneStyling;
|
|
interactions: boolean;
|
|
components: boolean;
|
|
motion: boolean;
|
|
preview: boolean;
|
|
};
|
|
|
|
export function resolveCloneMode(options: CloneOptions = {}): CloneMode {
|
|
return options.mode ?? (options.multiPage ? "multi" : "single");
|
|
}
|
|
|
|
export function resolveCloneStyling(options: CloneOptions = {}): CloneStyling {
|
|
return options.styling ?? options.humanizeMode ?? "tailwind";
|
|
}
|
|
|
|
export function resolveCloneFramework(options: CloneOptions = {}): CloneFramework {
|
|
return options.framework ?? "next";
|
|
}
|
|
|
|
/** Normalize the request-facing shape. Deprecated aliases are consumed but not
|
|
* echoed, so REST/MCP results present the product-level option names. */
|
|
export function normalizeCloneRequestOptions(options: CloneOptions = {}): CloneOptions {
|
|
const normalized: CloneOptions = {
|
|
...options,
|
|
mode: resolveCloneMode(options),
|
|
styling: resolveCloneStyling(options),
|
|
framework: resolveCloneFramework(options),
|
|
};
|
|
delete normalized.multiPage;
|
|
delete normalized.humanizeMode;
|
|
return normalized;
|
|
}
|
|
|
|
/** Resolve options for the compiler adapter. This is where automatic internal
|
|
* defaults live; callers should not need to choose these in normal use. */
|
|
export function resolveCloneOptions(options: CloneOptions = {}): ResolvedCloneOptions {
|
|
const mode = resolveCloneMode(options);
|
|
const styling = resolveCloneStyling(options);
|
|
const framework = resolveCloneFramework(options);
|
|
return {
|
|
...options,
|
|
mode,
|
|
styling,
|
|
framework,
|
|
multiPage: mode === "multi",
|
|
humanizeMode: styling,
|
|
interactions: options.interactions ?? true,
|
|
components: options.components ?? true,
|
|
motion: options.motion ?? true,
|
|
// Preview builds are the single-page product surface; multi-page exports can be
|
|
// large, so previewing a site clone stays an explicit opt-in.
|
|
preview: options.preview ?? mode === "single",
|
|
};
|
|
}
|