1import * as Data from "effect/Data";
2import * as Effect from "effect/Effect";
3import * as FileSystem from "effect/FileSystem";
4import * as Path from "effect/Path";
5import { UserFacingError } from "../UserFacingError.ts";
6
7export class StackEntrypointError extends Data.TaggedError(
8 "StackEntrypointError",
9)<{ readonly message: string }> {
10 readonly [UserFacingError] = true;
11}
12
13export const DEFAULT_ENTRYPOINT = "alchemy.run.ts";
14
15/**
16 * The absolute path of the stack entrypoint, or the user-facing error for
17 * a missing one. Kept apart from `Session.ts` so the `alchemy dev`
18 * supervisor can check the entry before it starts an exec child, without
19 * loading the engine that module carries.
20 */
21export const resolveStackEntrypoint = Effect.fn(function* (main: string) {
22 const fs = yield* FileSystem.FileSystem;
23 const path = yield* Path.Path;
24 const absolutePath = path.resolve(main);
25 if (!(yield* fs.exists(absolutePath))) {
26 return yield* Effect.fail(
27 new StackEntrypointError({
28 message: `Stack entrypoint '${main}' does not exist in '${path.dirname(absolutePath)}'. Run this command from an Alchemy project or pass --config <path>.`,
29 }),
30 );
31 }
32 return absolutePath;
33});