1import * as Cloudflare from "@/Cloudflare/index.ts";
2import * as Test from "@/Test/Alchemy";
3import { expect } from "alchemy-test";
4import * as Effect from "effect/Effect";
5import { MinimumLogLevel } from "effect/References";
6import * as pathe from "pathe";
7import {
8 expectUrlContains,
9 expectUrlHeader,
10 expectUrlRedirect,
11} from "../Utils/Http.ts";
12
13const { test } = Test.make({
14 providers: Cloudflare.providers(),
15 dev: true,
16});
17
18const logLevel = Effect.provideService(
19 MinimumLogLevel,
20 process.env.DEBUG ? "Debug" : "Info",
21);
22
23const fixtureDir = pathe.resolve(import.meta.dirname, "fixtures/assets-config");
24
25/**
26 * Regression for https://github.com/alchemy-run/alchemy/pull/1418:
27 * local asset serving used to crash with `TypeError: undefined is not an
28 * object` the moment the assets directory contained a `_headers` or
29 * `_redirects` file, because `constructHeaders` / `constructRedirects`
30 * called `logger.log` with no logger. After the crash every subsequent
31 * request hung. Those helpers now log through Effect.log.
32 *
33 * This is the local counterpart of `AssetsConfigFiles.test.ts`: the
34 * fixture's rules must reach the local assets worker and actually apply.
35 */
36test.provider(
37 "dev assets _headers and _redirects apply without crashing the assets worker",
38 (stack) =>
39 Effect.gen(function* () {
40 yield* stack.destroy();
41
42 const deployed = yield* stack.deploy(
43 Effect.gen(function* () {
44 const worker = yield* Cloudflare.Worker("assets-config-local", {
45 assets: { directory: fixtureDir },
46 });
47 return { worker };
48 }),
49 );
50
51 expect(deployed.worker.url).toMatch(/^http:\/\/localhost:\d+$/);
52
53 const url = deployed.worker.url;
54 yield* expectUrlContains(`${url}/`, "alchemy-assets-config-index");
55 yield* expectUrlHeader(
56 `${url}/`,
57 "x-alchemy-test",
58 "assets-config-header",
59 { label: "local _headers" },
60 );
61 yield* expectUrlRedirect(`${url}/old-path`, "/index.html", {
62 status: 301,
63 label: "local _redirects",
64 });
65
66 yield* stack.destroy();
67 }).pipe(logLevel),
68 {
69 tags: ["provider:cloudflare", "provider:cloudflare:worker", "local"],
70 timeout: 120_000,
71 },
72);