1/**
2 * `@alchemy.run/frontend-frameworks/nuxt` — Nuxt integration implementing framework-core's
3 * `Framework` service, with the deploy target passed as a value (Cloudflare
4 * Workers by default, via the `@alchemy.run/frontend-frameworks/nuxt/cloudflare` subpath
5 * module).
6 *
7 * The default export is the e2e-harness factory contract: a
8 * `(options) => Layer<Framework>` function that reads the harness's
9 * cloudflare-target configuration (compatibility date/flags, the user worker
10 * entry). Use {@link layer} directly for the fully-typed path with
11 * Nuxt-specific options.
12 *
13 * This module (and `Nuxt.ts`) is target-agnostic by contract: it must not
14 * import anything Cloudflare-specific. The Cloudflare half — the nitro
15 * `cloudflare_module` preset selection and its wrangler-free config — lives
16 * behind `@alchemy.run/frontend-frameworks/nuxt/cloudflare`.
17 */
18import type { Framework } from "../core/index.ts";
19import type * as FileSystem from "effect/FileSystem";
20import type * as Layer from "effect/Layer";
21import type * as Path from "effect/Path";
22import { layer, type NuxtOptions } from "./Nuxt.ts";
23
24export {
25 DEFAULT_TARGET_SPECIFIER,
26 layer,
27 make,
28 NUXT_KIT_SPECIFIER,
29 readNitroOutput,
30 SERVER_ENTRY_NAME,
31 type NitroOutputDirs,
32 type NuxtDevListener,
33 type NuxtDevPlatform,
34 type NuxtDevPlatformContext,
35 type NuxtInstance,
36 type NuxtKitModule,
37 type NuxtNitroContext,
38 type NuxtOptions,
39 type NuxtTarget,
40 type NuxtTargetConfig,
41 type NuxtTargetInput,
42} from "./Nuxt.ts";
43
44export {
45 enforceNitroConfig,
46 findPresetConflict,
47 isSamePreset,
48 makeNuxtOverrides,
49 normalizePresetName,
50 presetConflictMessage,
51 type EnforceNitroConfigOptions,
52 type NitroConfigSlice,
53 type NuxtConfigLayer,
54 type NuxtOverridesInput,
55} from "./UserConfig.ts";
56
57/**
58 * The structural subset of the e2e harness's cloudflare worker options this
59 * package reads (`CloudflareVitePluginOptions`). Typed structurally so the
60 * package does not depend on the harness.
61 */
62export interface HarnessWorkerOptions {
63 readonly compatibilityDate?: string | undefined;
64 readonly compatibilityFlags?: Array<string> | undefined;
65 /** The USER's worker entry (the custom-entry carriage). */
66 readonly main?: string | undefined;
67 readonly worker?:
68 | {
69 /**
70 * The worker's declared binding hooks — passed through to the
71 * deploy target's dev platform wholesale (the Cloudflare target
72 * serves them on `event.context.cloudflare.env` via
73 * cloudflare-runtime's platform proxy).
74 */
75 readonly bindings?: ReadonlyArray<unknown> | undefined;
76 }
77 | undefined;
78}
79
80/**
81 * The structural subset of the e2e harness's `Options` this package reads.
82 * The harness carries cloudflare configuration target-scoped
83 * (`target.cloudflare.worker`); the top-level `vite` field is the harness's
84 * deprecated alias for the same shape (target-scoped wins).
85 */
86export interface HarnessOptions {
87 readonly target?:
88 | {
89 readonly cloudflare?:
90 | {
91 readonly worker?: HarnessWorkerOptions | undefined;
92 }
93 | undefined;
94 }
95 | undefined;
96 /** @deprecated Harness alias for `target.cloudflare.worker`. */
97 readonly vite?: HarnessWorkerOptions | undefined;
98}
99
100/**
101 * Map the harness's options onto {@link NuxtOptions}, preferring the
102 * target-scoped carriage (`target.cloudflare.worker`) over the deprecated
103 * top-level `vite` alias.
104 */
105export const fromHarnessOptions = (options: HarnessOptions): NuxtOptions => {
106 const worker = options.target?.cloudflare?.worker ?? options.vite;
107 return {
108 compatibilityDate: worker?.compatibilityDate,
109 compatibilityFlags: worker?.compatibilityFlags,
110 main: worker?.main,
111 dev: {
112 bindings: worker?.worker?.bindings,
113 },
114 };
115};
116
117/**
118 * The e2e-harness factory contract (`framework: "@alchemy.run/frontend-frameworks/nuxt"` in
119 * `e2e.config.ts`).
120 */
121const factory = (
122 options: HarnessOptions,
123): Layer.Layer<Framework, never, FileSystem.FileSystem | Path.Path> =>
124 layer(fromHarnessOptions(options));
125
126export default factory;