@saacms/storage-r2 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.
- package/README.md +31 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +56 -0
- package/dist/r2-adapter.d.ts +94 -0
- package/dist/r2-adapter.d.ts.map +1 -0
- package/dist/r2-adapter.js +81 -0
- package/package.json +43 -0
package/README.md
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# @saacms/storage-r2
|
|
2
|
+
|
|
3
|
+
Cloudflare R2 storage adapter for saacms. Implements the `StorageAdapter` interface (`{ put, get, delete, signedUrl }`) over a Workers `R2Bucket` binding, for use by Media Collections in `bucket` storage mode.
|
|
4
|
+
|
|
5
|
+
See [ADR 0009 — Media as Collection kind](../../docs/adr/0009-media-as-collection-kind.md) for the storage-adapter interface and the bucket vs repo modes, and [ADR 0024 — v1 alpha scope](../../docs/adr/0024-v1-alpha-scope-astro-cloudflare.md) for why R2 is the v1 default bucket.
|
|
6
|
+
|
|
7
|
+
## Status
|
|
8
|
+
|
|
9
|
+
Scaffold. The `put` / `get` / `delete` operations forward to the `R2Bucket` binding the host passes in. `signedUrl` returns a public URL when `publicBaseUrl` is configured; pre-signed URL generation (AWS SigV4 over R2's S3 endpoint, via `aws4fetch`) is deferred until ADR 0009's open question on transform URL syntax is resolved.
|
|
10
|
+
|
|
11
|
+
## Usage (target shape)
|
|
12
|
+
|
|
13
|
+
```ts
|
|
14
|
+
// saacms.config.ts
|
|
15
|
+
import { defineConfig } from "saacms"
|
|
16
|
+
import { r2Adapter } from "@saacms/storage-r2"
|
|
17
|
+
|
|
18
|
+
export default defineConfig({
|
|
19
|
+
storage: r2Adapter({
|
|
20
|
+
bucket: env.SAACMS_MEDIA, // R2Bucket binding from wrangler.toml
|
|
21
|
+
prefix: "media/",
|
|
22
|
+
publicBaseUrl: "https://cdn.example.com",
|
|
23
|
+
}),
|
|
24
|
+
})
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
The `bucket` field is the Workers R2 binding object — saacms doesn't open the binding for you; the host (Astro on Cloudflare Pages, per ADR 0024) injects it from `wrangler.toml`.
|
|
28
|
+
|
|
29
|
+
## Known reconciliation TODO
|
|
30
|
+
|
|
31
|
+
The local `StorageAdapter` interface in `src/r2-adapter.ts` is a copy with TODO. Replace with `import type { StorageAdapter } from "@saacms/core"` once the cross-package contract test (per ADR 0019) is wired up to enforce conformance.
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @saacms/storage-r2 — public surface.
|
|
3
|
+
*
|
|
4
|
+
* Cloudflare R2 implementation of the saacms `StorageAdapter` interface
|
|
5
|
+
* (per ADR 0009 § 3 — bucket-mode storage adapters expose `{ put, get, delete, signedUrl }`).
|
|
6
|
+
*
|
|
7
|
+
* v1 alpha status: scaffold. `put` / `get` / `delete` forward to the Workers
|
|
8
|
+
* `R2Bucket` binding the host passes in; `signedUrl` returns a public URL
|
|
9
|
+
* when `publicBaseUrl` is set, and throws `NOT_IMPLEMENTED` otherwise
|
|
10
|
+
* (ADR 0009 open question on transform URL syntax).
|
|
11
|
+
*/
|
|
12
|
+
export { r2Adapter } from "./r2-adapter.ts";
|
|
13
|
+
export type { R2AdapterOpts, StorageAdapter, StorageError, SignedUrlOpts, } from "./r2-adapter.ts";
|
|
14
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAC3C,YAAY,EACV,aAAa,EACb,cAAc,EACd,YAAY,EACZ,aAAa,GACd,MAAM,iBAAiB,CAAA"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
// src/r2-adapter.ts
|
|
2
|
+
class StorageError extends Error {
|
|
3
|
+
code;
|
|
4
|
+
cause;
|
|
5
|
+
name = "StorageError";
|
|
6
|
+
constructor(code, message, cause) {
|
|
7
|
+
super(message);
|
|
8
|
+
this.code = code;
|
|
9
|
+
this.cause = cause;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
function r2Adapter(opts) {
|
|
13
|
+
const { bucket, prefix = "", publicBaseUrl } = opts;
|
|
14
|
+
const fullKey = (key) => prefix + key;
|
|
15
|
+
return {
|
|
16
|
+
async put(key, body, contentType) {
|
|
17
|
+
const k = fullKey(key);
|
|
18
|
+
try {
|
|
19
|
+
await bucket.put(k, body, {
|
|
20
|
+
httpMetadata: contentType !== undefined ? { contentType } : undefined
|
|
21
|
+
});
|
|
22
|
+
return { key: k };
|
|
23
|
+
} catch (cause) {
|
|
24
|
+
throw new StorageError("PUT_FAILED", `R2 put failed for key "${k}"`, cause);
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
async get(key) {
|
|
28
|
+
const k = fullKey(key);
|
|
29
|
+
try {
|
|
30
|
+
return await bucket.get(k);
|
|
31
|
+
} catch (cause) {
|
|
32
|
+
throw new StorageError("GET_FAILED", `R2 get failed for key "${k}"`, cause);
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
async delete(key) {
|
|
36
|
+
const k = fullKey(key);
|
|
37
|
+
try {
|
|
38
|
+
await bucket.delete(k);
|
|
39
|
+
} catch (cause) {
|
|
40
|
+
throw new StorageError("DELETE_FAILED", `R2 delete failed for key "${k}"`, cause);
|
|
41
|
+
}
|
|
42
|
+
},
|
|
43
|
+
async signedUrl(key, _opts) {
|
|
44
|
+
const k = fullKey(key);
|
|
45
|
+
if (publicBaseUrl !== undefined) {
|
|
46
|
+
const base = publicBaseUrl.replace(/\/+$/, "");
|
|
47
|
+
const path = k.replace(/^\/+/, "");
|
|
48
|
+
return `${base}/${path}`;
|
|
49
|
+
}
|
|
50
|
+
throw new StorageError("NOT_IMPLEMENTED", "signed URLs require AWS SigV4 (e.g. via aws4fetch); see ADR 0009 open question on transform URL syntax");
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
export {
|
|
55
|
+
r2Adapter
|
|
56
|
+
};
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* R2 storage adapter — implements the saacms `StorageAdapter` interface
|
|
3
|
+
* over a Cloudflare Workers `R2Bucket` binding.
|
|
4
|
+
*
|
|
5
|
+
* Per ADR 0009 § 3, bucket-mode Media Collections delegate binary storage
|
|
6
|
+
* to a pluggable adapter exposing `{ put, get, delete, signedUrl }`. This
|
|
7
|
+
* is the v1 alpha R2 implementation (ADR 0024 — the only bucket adapter
|
|
8
|
+
* shipped at v1.0; `vercelBlobAdapter` and `s3Adapter` follow in v1.x).
|
|
9
|
+
*
|
|
10
|
+
* Workers API reference:
|
|
11
|
+
* https://developers.cloudflare.com/r2/api/workers/workers-api-reference/
|
|
12
|
+
*/
|
|
13
|
+
/**
|
|
14
|
+
* The interface every saacms storage adapter implements.
|
|
15
|
+
*
|
|
16
|
+
* Defined locally for now; will move to `@saacms/core` (likely
|
|
17
|
+
* `@saacms/core/storage`) when that surface lands.
|
|
18
|
+
*/
|
|
19
|
+
export interface StorageAdapter {
|
|
20
|
+
/** Write a binary at the given key. Returns the canonical key (post-prefix). */
|
|
21
|
+
put(key: string, body: StorageBody, contentType?: string): Promise<{
|
|
22
|
+
key: string;
|
|
23
|
+
}>;
|
|
24
|
+
/** Fetch the object at the given key. Returns null when absent. */
|
|
25
|
+
get(key: string): Promise<R2ObjectBodyLike | null>;
|
|
26
|
+
/** Delete the object at the given key. Idempotent. */
|
|
27
|
+
delete(key: string): Promise<void>;
|
|
28
|
+
/** Resolve to a URL that serves the object. See implementation for v1 limitations. */
|
|
29
|
+
signedUrl(key: string, opts?: SignedUrlOpts): Promise<string>;
|
|
30
|
+
}
|
|
31
|
+
/** Body shapes accepted by `put`. Mirrors `R2Bucket.put`'s value parameter. */
|
|
32
|
+
export type StorageBody = ReadableStream | ArrayBuffer | ArrayBufferView | string | null | Blob;
|
|
33
|
+
export interface SignedUrlOpts {
|
|
34
|
+
/** Lifetime of the signed URL in seconds. v1 ignores this when `publicBaseUrl` is used. */
|
|
35
|
+
readonly expiresInSeconds?: number;
|
|
36
|
+
/** Force-download with this filename via `Content-Disposition`. v1 ignored. */
|
|
37
|
+
readonly downloadAs?: string;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Tagged error surface for storage operations. Bubbles up to the runtime
|
|
41
|
+
* which converts to RFC 9457 Problem Details (ADR 0018).
|
|
42
|
+
*/
|
|
43
|
+
export declare class StorageError extends Error {
|
|
44
|
+
readonly code: "PUT_FAILED" | "GET_FAILED" | "DELETE_FAILED" | "NOT_IMPLEMENTED" | "MISCONFIGURED";
|
|
45
|
+
readonly cause?: unknown | undefined;
|
|
46
|
+
readonly name = "StorageError";
|
|
47
|
+
constructor(code: "PUT_FAILED" | "GET_FAILED" | "DELETE_FAILED" | "NOT_IMPLEMENTED" | "MISCONFIGURED", message: string, cause?: unknown | undefined);
|
|
48
|
+
}
|
|
49
|
+
/** Subset of the `R2PutOptions` shape used by this adapter. */
|
|
50
|
+
export interface R2PutOptionsLike {
|
|
51
|
+
readonly httpMetadata?: {
|
|
52
|
+
readonly contentType?: string;
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
/** Subset of `R2Object` returned by `put`. */
|
|
56
|
+
export interface R2ObjectLike {
|
|
57
|
+
readonly key: string;
|
|
58
|
+
}
|
|
59
|
+
/** Subset of `R2ObjectBody` returned by `get`. */
|
|
60
|
+
export interface R2ObjectBodyLike extends R2ObjectLike {
|
|
61
|
+
readonly body: ReadableStream | null;
|
|
62
|
+
arrayBuffer(): Promise<ArrayBuffer>;
|
|
63
|
+
text(): Promise<string>;
|
|
64
|
+
}
|
|
65
|
+
/** Subset of the `R2Bucket` binding used by this adapter. */
|
|
66
|
+
export interface R2BucketLike {
|
|
67
|
+
put(key: string, value: StorageBody, options?: R2PutOptionsLike): Promise<R2ObjectLike | null>;
|
|
68
|
+
get(key: string): Promise<R2ObjectBodyLike | null>;
|
|
69
|
+
delete(key: string | string[]): Promise<void>;
|
|
70
|
+
}
|
|
71
|
+
export interface R2AdapterOpts {
|
|
72
|
+
/** The Workers `R2Bucket` binding; supplied by the host (e.g. `env.SAACMS_MEDIA`). */
|
|
73
|
+
readonly bucket: R2BucketLike;
|
|
74
|
+
/** Optional key prefix (e.g. `"media/"`). Joined verbatim — caller controls trailing slash. */
|
|
75
|
+
readonly prefix?: string;
|
|
76
|
+
/**
|
|
77
|
+
* Optional public base URL for served objects (e.g. `https://cdn.example.com`).
|
|
78
|
+
* When set, `signedUrl` returns `${publicBaseUrl}/${prefix}${key}` (with
|
|
79
|
+
* any duplicate slashes collapsed). When unset, `signedUrl` throws
|
|
80
|
+
* `NOT_IMPLEMENTED` until pre-signed AWS SigV4 URL generation lands
|
|
81
|
+
* (ADR 0009 open question on transform URL syntax).
|
|
82
|
+
*/
|
|
83
|
+
readonly publicBaseUrl?: string;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Build an R2-backed `StorageAdapter`.
|
|
87
|
+
*
|
|
88
|
+
* The `bucket` field is the live Workers binding; this factory does not
|
|
89
|
+
* open it. On Cloudflare Pages with `@saacms/host-astro`, the host injects
|
|
90
|
+
* the binding declared in `wrangler.toml` (per ADR 0024 § "R2 binding
|
|
91
|
+
* name convention" — likely `SAACMS_MEDIA`).
|
|
92
|
+
*/
|
|
93
|
+
export declare function r2Adapter(opts: R2AdapterOpts): StorageAdapter;
|
|
94
|
+
//# sourceMappingURL=r2-adapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"r2-adapter.d.ts","sourceRoot":"","sources":["../src/r2-adapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAMH;;;;;GAKG;AACH,MAAM,WAAW,cAAc;IAC7B,gFAAgF;IAChF,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IACnF,mEAAmE;IACnE,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAAA;IAClD,sDAAsD;IACtD,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAClC,sFAAsF;IACtF,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;CAC9D;AAED,+EAA+E;AAC/E,MAAM,MAAM,WAAW,GACnB,cAAc,GACd,WAAW,GACX,eAAe,GACf,MAAM,GACN,IAAI,GACJ,IAAI,CAAA;AAER,MAAM,WAAW,aAAa;IAC5B,2FAA2F;IAC3F,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAA;IAClC,+EAA+E;IAC/E,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAC7B;AAED;;;GAGG;AACH,qBAAa,YAAa,SAAQ,KAAK;IAGnC,QAAQ,CAAC,IAAI,EACT,YAAY,GACZ,YAAY,GACZ,eAAe,GACf,iBAAiB,GACjB,eAAe;IAEnB,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO;IAT1B,SAAkB,IAAI,kBAAiB;gBAE5B,IAAI,EACT,YAAY,GACZ,YAAY,GACZ,eAAe,GACf,iBAAiB,GACjB,eAAe,EACnB,OAAO,EAAE,MAAM,EACN,KAAK,CAAC,EAAE,OAAO,YAAA;CAI3B;AAgBD,+DAA+D;AAC/D,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,YAAY,CAAC,EAAE;QAAE,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;CAC1D;AAED,8CAA8C;AAC9C,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;CACrB;AAED,kDAAkD;AAClD,MAAM,WAAW,gBAAiB,SAAQ,YAAY;IACpD,QAAQ,CAAC,IAAI,EAAE,cAAc,GAAG,IAAI,CAAA;IACpC,WAAW,IAAI,OAAO,CAAC,WAAW,CAAC,CAAA;IACnC,IAAI,IAAI,OAAO,CAAC,MAAM,CAAC,CAAA;CACxB;AAED,6DAA6D;AAC7D,MAAM,WAAW,YAAY;IAC3B,GAAG,CACD,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,WAAW,EAClB,OAAO,CAAC,EAAE,gBAAgB,GACzB,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAAA;IAC/B,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAAA;IAClD,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CAC9C;AAMD,MAAM,WAAW,aAAa;IAC5B,sFAAsF;IACtF,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAA;IAC7B,+FAA+F;IAC/F,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;IACxB;;;;;;OAMG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAA;CAChC;AAED;;;;;;;GAOG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,aAAa,GAAG,cAAc,CA+D7D"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* R2 storage adapter — implements the saacms `StorageAdapter` interface
|
|
3
|
+
* over a Cloudflare Workers `R2Bucket` binding.
|
|
4
|
+
*
|
|
5
|
+
* Per ADR 0009 § 3, bucket-mode Media Collections delegate binary storage
|
|
6
|
+
* to a pluggable adapter exposing `{ put, get, delete, signedUrl }`. This
|
|
7
|
+
* is the v1 alpha R2 implementation (ADR 0024 — the only bucket adapter
|
|
8
|
+
* shipped at v1.0; `vercelBlobAdapter` and `s3Adapter` follow in v1.x).
|
|
9
|
+
*
|
|
10
|
+
* Workers API reference:
|
|
11
|
+
* https://developers.cloudflare.com/r2/api/workers/workers-api-reference/
|
|
12
|
+
*/
|
|
13
|
+
/**
|
|
14
|
+
* Tagged error surface for storage operations. Bubbles up to the runtime
|
|
15
|
+
* which converts to RFC 9457 Problem Details (ADR 0018).
|
|
16
|
+
*/
|
|
17
|
+
export class StorageError extends Error {
|
|
18
|
+
code;
|
|
19
|
+
cause;
|
|
20
|
+
name = "StorageError";
|
|
21
|
+
constructor(code, message, cause) {
|
|
22
|
+
super(message);
|
|
23
|
+
this.code = code;
|
|
24
|
+
this.cause = cause;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Build an R2-backed `StorageAdapter`.
|
|
29
|
+
*
|
|
30
|
+
* The `bucket` field is the live Workers binding; this factory does not
|
|
31
|
+
* open it. On Cloudflare Pages with `@saacms/host-astro`, the host injects
|
|
32
|
+
* the binding declared in `wrangler.toml` (per ADR 0024 § "R2 binding
|
|
33
|
+
* name convention" — likely `SAACMS_MEDIA`).
|
|
34
|
+
*/
|
|
35
|
+
export function r2Adapter(opts) {
|
|
36
|
+
const { bucket, prefix = "", publicBaseUrl } = opts;
|
|
37
|
+
const fullKey = (key) => prefix + key;
|
|
38
|
+
return {
|
|
39
|
+
async put(key, body, contentType) {
|
|
40
|
+
const k = fullKey(key);
|
|
41
|
+
try {
|
|
42
|
+
await bucket.put(k, body, {
|
|
43
|
+
httpMetadata: contentType !== undefined ? { contentType } : undefined,
|
|
44
|
+
});
|
|
45
|
+
return { key: k };
|
|
46
|
+
}
|
|
47
|
+
catch (cause) {
|
|
48
|
+
throw new StorageError("PUT_FAILED", `R2 put failed for key "${k}"`, cause);
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
async get(key) {
|
|
52
|
+
const k = fullKey(key);
|
|
53
|
+
try {
|
|
54
|
+
return await bucket.get(k);
|
|
55
|
+
}
|
|
56
|
+
catch (cause) {
|
|
57
|
+
throw new StorageError("GET_FAILED", `R2 get failed for key "${k}"`, cause);
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
async delete(key) {
|
|
61
|
+
const k = fullKey(key);
|
|
62
|
+
try {
|
|
63
|
+
await bucket.delete(k);
|
|
64
|
+
}
|
|
65
|
+
catch (cause) {
|
|
66
|
+
throw new StorageError("DELETE_FAILED", `R2 delete failed for key "${k}"`, cause);
|
|
67
|
+
}
|
|
68
|
+
},
|
|
69
|
+
async signedUrl(key, _opts) {
|
|
70
|
+
const k = fullKey(key);
|
|
71
|
+
if (publicBaseUrl !== undefined) {
|
|
72
|
+
// Collapse duplicate slashes between segments. We trust the caller's
|
|
73
|
+
// base URL otherwise (no protocol re-write, no normalisation).
|
|
74
|
+
const base = publicBaseUrl.replace(/\/+$/, "");
|
|
75
|
+
const path = k.replace(/^\/+/, "");
|
|
76
|
+
return `${base}/${path}`;
|
|
77
|
+
}
|
|
78
|
+
throw new StorageError("NOT_IMPLEMENTED", "signed URLs require AWS SigV4 (e.g. via aws4fetch); see ADR 0009 open question on transform URL syntax");
|
|
79
|
+
},
|
|
80
|
+
};
|
|
81
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@saacms/storage-r2",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"exports": {
|
|
6
|
+
".": {
|
|
7
|
+
"import": "./dist/index.js",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"default": "./dist/index.js"
|
|
10
|
+
}
|
|
11
|
+
},
|
|
12
|
+
"files": [
|
|
13
|
+
"dist",
|
|
14
|
+
"README.md"
|
|
15
|
+
],
|
|
16
|
+
"scripts": {
|
|
17
|
+
"build": "tsc --build",
|
|
18
|
+
"typecheck": "tsc --build --noEmit",
|
|
19
|
+
"prepack": "cp package.json package.json.pack-bak && bun run ../../scripts/prepack-pkg.ts",
|
|
20
|
+
"postpack": "mv package.json.pack-bak package.json"
|
|
21
|
+
},
|
|
22
|
+
"publishConfig": {
|
|
23
|
+
"access": "public"
|
|
24
|
+
},
|
|
25
|
+
"dependencies": {
|
|
26
|
+
"@saacms/core": "workspace:*",
|
|
27
|
+
"@cloudflare/workers-types": "^4.20240925.0"
|
|
28
|
+
},
|
|
29
|
+
"peerDependencies": {
|
|
30
|
+
"aws4fetch": "^1.0.20"
|
|
31
|
+
},
|
|
32
|
+
"peerDependenciesMeta": {
|
|
33
|
+
"aws4fetch": {
|
|
34
|
+
"optional": true
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
"devDependencies": {
|
|
38
|
+
"@types/bun": "latest",
|
|
39
|
+
"typescript": "^5.7.0"
|
|
40
|
+
},
|
|
41
|
+
"main": "./dist/index.js",
|
|
42
|
+
"types": "./dist/index.d.ts"
|
|
43
|
+
}
|