@ayepi/files 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,51 @@
1
+ import { FileStore, Presigner } from "./index.cjs";
2
+ import { AnySpec, MountHandle, Server } from "@ayepi/core";
3
+
4
+ //#region src/server.d.ts
5
+
6
+ /** Shared options for the two serving styles. */
7
+ interface FilesServerOptions {
8
+ /** HMAC secret used to sign/verify presigned tokens (server-side only). */
9
+ readonly secret: string;
10
+ /** URL path the up/download routes live at (default `'/_files'`). */
11
+ readonly basePath?: string;
12
+ /** Default presigned-URL lifetime in seconds (default 900). */
13
+ readonly expiresIn?: number;
14
+ /** Clock injection (default `Date.now`) — for tests. */
15
+ readonly now?: () => number;
16
+ }
17
+ /**
18
+ * Hot-mount presigned `GET`/`PUT` routes for `store` onto a running `app` and return a
19
+ * {@link Presigner} for them. The download sets `Content-Length` (so HTTP Range / resumable
20
+ * downloads work) and the object's content-type; the upload streams the request body straight
21
+ * into `store.put`. Tear the routes down later with `app.uninstall(handle)`.
22
+ *
23
+ * @example
24
+ * ```ts
25
+ * const files = fsFiles({ dir: './uploads' });
26
+ * const { presign, handle } = mountFiles(app, files, { secret: process.env.FILES_SECRET! });
27
+ * const url = await presign.presignDownload('reports/2026.csv', { expiresIn: 60 });
28
+ * ```
29
+ */
30
+ declare function mountFiles(app: Server<AnySpec>, store: FileStore, opts: FilesServerOptions): {
31
+ handle: MountHandle;
32
+ presign: Presigner;
33
+ };
34
+ /**
35
+ * Build a standalone `fetch(req)` that serves the presigned `GET`/`PUT` for `store`, plus a
36
+ * {@link Presigner} for them. Returns `undefined` for requests that aren't `basePath`, so you
37
+ * can compose it around your server's `fetch` (the example `_harness` pattern) — no spec, no
38
+ * mount, works on any runtime.
39
+ *
40
+ * @example
41
+ * ```ts
42
+ * const { fetch: filesFetch, presign } = createFilesHandler(files, { secret, basePath: '/files' });
43
+ * const handler = async (req: Request) => (await filesFetch(req)) ?? app.fetch(req);
44
+ * ```
45
+ */
46
+ declare function createFilesHandler(store: FileStore, opts: FilesServerOptions): {
47
+ fetch: (req: Request) => Promise<Response | undefined>;
48
+ presign: Presigner;
49
+ };
50
+ //#endregion
51
+ export { FilesServerOptions, createFilesHandler, mountFiles };
@@ -0,0 +1,51 @@
1
+ import { FileStore, Presigner } from "./index.js";
2
+ import { AnySpec, MountHandle, Server } from "@ayepi/core";
3
+
4
+ //#region src/server.d.ts
5
+
6
+ /** Shared options for the two serving styles. */
7
+ interface FilesServerOptions {
8
+ /** HMAC secret used to sign/verify presigned tokens (server-side only). */
9
+ readonly secret: string;
10
+ /** URL path the up/download routes live at (default `'/_files'`). */
11
+ readonly basePath?: string;
12
+ /** Default presigned-URL lifetime in seconds (default 900). */
13
+ readonly expiresIn?: number;
14
+ /** Clock injection (default `Date.now`) — for tests. */
15
+ readonly now?: () => number;
16
+ }
17
+ /**
18
+ * Hot-mount presigned `GET`/`PUT` routes for `store` onto a running `app` and return a
19
+ * {@link Presigner} for them. The download sets `Content-Length` (so HTTP Range / resumable
20
+ * downloads work) and the object's content-type; the upload streams the request body straight
21
+ * into `store.put`. Tear the routes down later with `app.uninstall(handle)`.
22
+ *
23
+ * @example
24
+ * ```ts
25
+ * const files = fsFiles({ dir: './uploads' });
26
+ * const { presign, handle } = mountFiles(app, files, { secret: process.env.FILES_SECRET! });
27
+ * const url = await presign.presignDownload('reports/2026.csv', { expiresIn: 60 });
28
+ * ```
29
+ */
30
+ declare function mountFiles(app: Server<AnySpec>, store: FileStore, opts: FilesServerOptions): {
31
+ handle: MountHandle;
32
+ presign: Presigner;
33
+ };
34
+ /**
35
+ * Build a standalone `fetch(req)` that serves the presigned `GET`/`PUT` for `store`, plus a
36
+ * {@link Presigner} for them. Returns `undefined` for requests that aren't `basePath`, so you
37
+ * can compose it around your server's `fetch` (the example `_harness` pattern) — no spec, no
38
+ * mount, works on any runtime.
39
+ *
40
+ * @example
41
+ * ```ts
42
+ * const { fetch: filesFetch, presign } = createFilesHandler(files, { secret, basePath: '/files' });
43
+ * const handler = async (req: Request) => (await filesFetch(req)) ?? app.fetch(req);
44
+ * ```
45
+ */
46
+ declare function createFilesHandler(store: FileStore, opts: FilesServerOptions): {
47
+ fetch: (req: Request) => Promise<Response | undefined>;
48
+ presign: Presigner;
49
+ };
50
+ //#endregion
51
+ export { FilesServerOptions, createFilesHandler, mountFiles };