import * as workers from "@distilled.cloud/cloudflare/workers"; import * as Effect from "effect/Effect"; import * as FileSystem from "effect/FileSystem"; import * as Path from "effect/Path"; import type { PlatformError } from "effect/PlatformError"; import type { ScopedPlanStatusSession } from "../../Cli/Cli.ts"; export interface Assets { kind: "Cloudflare.Workers.Assets"; } export declare const isAssets: (value: any) => value is Assets; /** * Routing configuration for a Worker's static assets — sent to Cloudflare * as `metadata.assets.config` on script upload. Declared explicitly (not * derived from the distilled API schema) so alchemy owns and documents its * public surface. */ export interface AssetsConfig { /** * Determines the redirects and rewrites of requests for HTML content: * whether `/page` serves `page.html`, and whether trailing slashes are * added or dropped. * * @default "auto-trailing-slash" */ htmlHandling?: "auto-trailing-slash" | "force-trailing-slash" | "drop-trailing-slash" | "none"; /** * Determines the response when a request does not match a static asset: * `"404-page"` serves the nearest `404.html`, and * `"single-page-application"` serves `index.html` for client-side * routing. When the Worker has a script, an unmatched request falls * through to the Worker instead. * * @default "none" */ notFoundHandling?: "none" | "404-page" | "single-page-application"; /** * Routes requests through the Worker *before* static-asset matching. * * Assets-first by default: a request matching a file is served directly * and never invokes the Worker. `true` routes every request through the * Worker ahead of the asset layer — serve files yourself via the * `ASSETS` binding. A path-rule array routes only matching paths * worker-first (e.g. `["/api/*"]`): glob (`*`) and negative (`!`) rules * are supported, rules must start with `/` or `!/`, and negative rules * take precedence. The same routing applies under `alchemy dev`. * * @default false */ runWorkerFirst?: boolean | string[]; /** * Legacy routing flag predating `runWorkerFirst`. */ serveDirectly?: boolean; /** * Raw contents of a `_headers` file — header rules applied by the asset * layer. Overrides a `_headers` file read from the assets directory. */ headers?: string; /** * Raw contents of a `_redirects` file — redirect rules applied by the * asset layer. Overrides a `_redirects` file read from the assets * directory. */ redirects?: string; } export interface AssetReadResult { directory: string; /** * The normalized `base` this manifest was keyed with (`""` when the * assets are served from the origin root). Manifest keys are request * paths, so `uploadAssets` strips this back off to find each file on * disk. */ pathPrefix: string; config: AssetsConfig | undefined; manifest: Record; _headers: string | undefined; _redirects: string | undefined; hash: string; } export interface AssetsProps extends AssetsConfig { directory: string; /** * The path this site is served from, when it is not the origin root — * e.g. `"/docs"` for a Worker on the route `example.com/docs*`. Matches * Vite's `base`, and `Website.Vite` fills it in from the resolved Vite * config automatically; set it by hand when you bring your own build. * * Cloudflare's asset router matches request paths against the manifest * literally and never strips a prefix, so its model is that the assets * directory mirrors the served path. This does that at manifest time: * `dist/app.js` is uploaded as `/docs/app.js`, leaving the build output * on disk untouched. * * Bases that name no path — `"/"`, `"./"`, `"https://cdn.example.com/"` — * are ignored, as an absolute base means the assets are served by a CDN * rather than by this Worker. * * `_headers` and `_redirects` are NOT rewritten: their rules match the * incoming request path, so author them with the full served path * (`/docs/old /docs/new 301`). * * @default undefined (assets are served from the origin root) * @see https://developers.cloudflare.com/workers/static-assets/routing/advanced/serving-a-subdirectory/ */ base?: string; } /** * `base` → manifest path prefix. Only a root-relative base names a path * this Worker serves; `"/"`, `"./"`, protocol-relative and absolute URLs * all mean "no prefix". */ export declare const getAssetsPathPrefix: (base: string | undefined) => string; export type ValidationError = AssetTooLargeError | TooManyAssetsError | AssetNotFoundError | FailedToReadAssetError; declare const AssetTooLargeError_base: new = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & { readonly _tag: "AssetTooLargeError"; } & Readonly; export declare class AssetTooLargeError extends AssetTooLargeError_base<{ message: string; name: string; size: number; }> { } declare const TooManyAssetsError_base: new = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & { readonly _tag: "TooManyAssetsError"; } & Readonly; export declare class TooManyAssetsError extends TooManyAssetsError_base<{ message: string; directory: string; count: number; }> { } declare const AssetNotFoundError_base: new = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & { readonly _tag: "AssetNotFoundError"; } & Readonly; export declare class AssetNotFoundError extends AssetNotFoundError_base<{ message: string; hash: string; }> { } declare const FailedToReadAssetError_base: new = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & { readonly _tag: "FailedToReadAssetError"; } & Readonly; export declare class FailedToReadAssetError extends FailedToReadAssetError_base<{ message: string; name: string; cause: PlatformError; }> { } declare const AssetUploadSessionError_base: new = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & { readonly _tag: "AssetUploadSessionError"; } & Readonly; export declare class AssetUploadSessionError extends AssetUploadSessionError_base<{ message: string; workerName: string; }> { } /** * Read the special `_headers` / `_redirects` files from an assets * directory. They are excluded from the upload manifest, but their raw * contents must be sent to Cloudflare in the script metadata's asset * config (`config._headers` / `config._redirects`) for the rules to * apply. * * The directory is optional: a config-only assets object (e.g. Vite's * `assets: { runWorkerFirst: true }`, whose directory is supplied by the * build) has no directory to read, and in `dev` there is no build output at * all. That yields no rules rather than an error. */ export declare const readAssetsConfigFiles: (directory: string | undefined) => Effect.Effect<{ _headers: string | undefined; _redirects: string | undefined; }, PlatformError, FileSystem.FileSystem | Path.Path>; /** * Merge `_headers` / `_redirects` file contents into an asset config, * producing the config to send in the script-upload metadata. Explicit * `headers` / `redirects` props win over the files. */ export declare const mergeAssetsConfigFiles: (config: AssetsConfig | undefined, files: { _headers: string | undefined; _redirects: string | undefined; }) => AssetsConfig | undefined; export declare const readAssets: (args_0: AssetsProps) => Effect.Effect<{ directory: string; pathPrefix: string; config: AssetsConfig | undefined; manifest: { [k: string]: { hash: string; size: number; }; }; _headers: string | undefined; _redirects: string | undefined; hash: string; }, AssetTooLargeError | PlatformError | TooManyAssetsError, FileSystem.FileSystem | Path.Path>; export declare const uploadAssets: (accountId: string, workerName: string, assets: AssetReadResult, args_3: ScopedPlanStatusSession) => Effect.Effect<{ jwt: string; }, AssetNotFoundError | AssetUploadSessionError | import("@distilled.cloud/axiom").BadGateway | import("@distilled.cloud/cloudflare").CloudflareError | import("@distilled.cloud/cloudflare").CloudflareHttpError | import("@distilled.cloud/cloudflare").CloudflareParseError | import("@distilled.cloud/cloudflare").CloudflareRateLimited | import("@distilled.cloud/axiom").ConfigError | FailedToReadAssetError | import("@distilled.cloud/axiom").GatewayTimeout | import("effect/unstable/http/HttpClientError").HttpClientError | import("@distilled.cloud/axiom").InternalServerError | import("@distilled.cloud/cloudflare").InvalidRoute | workers.InvalidRoute | import("@distilled.cloud/cloudflare").OAuthRefreshError | import("@distilled.cloud/axiom").ServiceUnavailable | import("@distilled.cloud/axiom").TooManyRequests | import("@distilled.cloud/axiom").Unauthorized | import("@distilled.cloud/cloudflare").UnknownCloudflareError, FileSystem.FileSystem | Path.Path | workers.CloudflareOpContext>; export {}; //# sourceMappingURL=Assets.d.ts.map