@run402/functions 2.0.1 → 2.2.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 CHANGED
@@ -1,9 +1,9 @@
1
1
  # @run402/functions
2
2
 
3
- In-function helper library for [Run402](https://run402.com) serverless functions. Imported _inside_ a deployed function — gives you typed access to the caller's database (RLS-respecting) and the project's admin database, the caller's auth, the project's mailbox, and AI helpers.
3
+ In-function helper library for [Run402](https://run402.com) serverless functions. Imported _inside_ a deployed function — gives you typed access to the caller's database (RLS-respecting) and the project's admin database, the caller's auth, the project's mailbox, AI helpers, and runtime asset uploads.
4
4
 
5
5
  ```ts
6
- import { db, adminDb, getUser, email, ai } from "@run402/functions";
6
+ import { db, adminDb, getUser, email, ai, assets } from "@run402/functions";
7
7
 
8
8
  export default async (req: Request) => {
9
9
  const user = await getUser(req);
@@ -142,6 +142,24 @@ const image = await ai.generateImage({
142
142
 
143
143
  Translation requires the AI Translation add-on on the project; moderation is free for all projects.
144
144
 
145
+ ## `assets.put(...)` — upload runtime assets
146
+
147
+ Upload bytes from inside a deployed function using the project's service key. This routes through the same CAS-backed apply substrate as deploy-time assets, so public/private visibility, immutable URLs, retention, quota checks, and storage billing match `r.project(id).apply({ assets: { put: [...] } })`.
148
+
149
+ ```ts
150
+ import { assets } from "@run402/functions";
151
+
152
+ const asset = await assets.put("generated/avatar.png", pngBytes, {
153
+ contentType: "image/png",
154
+ visibility: "public",
155
+ immutable: true,
156
+ });
157
+
158
+ return Response.json({ url: asset.immutableUrl ?? asset.url });
159
+ ```
160
+
161
+ `source` can be a string, `Uint8Array`, `{ content: string }`, or `{ bytes: Uint8Array }`. The returned `AssetRef` includes both snake_case wire fields (`immutable_url`, `size_bytes`, `content_type`) and SDK-style camelCase aliases (`immutableUrl`, `size`, `contentType`).
162
+
145
163
  ### Routed image generation example
146
164
 
147
165
  Use a routed function when the browser should request an image at app runtime. Keep app-level auth/rate limits in your handler before calling `ai.generateImage`, especially for public routes.
@@ -0,0 +1,80 @@
1
+ /**
2
+ * `assets` namespace — in-function blob upload via the unified-apply substrate.
3
+ *
4
+ * Calls `POST /apply/v1/service-asset-put` with service-key auth. The gateway
5
+ * runs the same activation sub-transaction the wallet-auth apply hero uses
6
+ * (`promoteStagedAssetSlice`), so visibility, immutable-URL retention, and
7
+ * per-unique-hash storage billing all behave identically to deploy-time
8
+ * `r.project(id).apply({ assets: { put: [...] } })`.
9
+ *
10
+ * Pre-v1.48 the runtime called `/storage/v1/uploads*`; that substrate was
11
+ * removed in the unified-apply migration. This namespace is the v2.1+
12
+ * in-function replacement.
13
+ */
14
+ export type AssetVisibility = "public" | "private";
15
+ export interface AssetPutSource {
16
+ content?: string;
17
+ bytes?: Uint8Array;
18
+ }
19
+ export type AssetPutSourceInput = string | Uint8Array | AssetPutSource;
20
+ export interface AssetPutOptions {
21
+ contentType?: string;
22
+ visibility?: AssetVisibility;
23
+ /**
24
+ * When `true` (default), the returned `immutableUrl` is content-addressed
25
+ * and the underlying `internal.asset_versions` row is retained per the
26
+ * project's tier. When `false`, only the mutable `url` is meaningful;
27
+ * `immutableUrl` is null.
28
+ */
29
+ immutable?: boolean;
30
+ }
31
+ /**
32
+ * Resolved asset reference. Wire shape matches the AssetRef the SDK's
33
+ * `r.project(id).apply` and `r.assets.put` return, so HTML rendered against
34
+ * these URLs is byte-identical to the deploy-time path.
35
+ *
36
+ * Mutable URL: `url` (and `cdnUrl`).
37
+ * Immutable URL: `immutableUrl` (and `cdnImmutableUrl`) — content-hashed
38
+ * suffix, suitable for SRI + indefinite caching.
39
+ *
40
+ * snake_case (`immutable_url`, `size_bytes`, `content_type`) and camelCase
41
+ * (`immutableUrl`, `size`, `contentType`) aliases are both emitted so
42
+ * existing callers and the SDK's surface keep working without translation.
43
+ */
44
+ export interface AssetRef {
45
+ key: string;
46
+ sha256: string;
47
+ size_bytes: number;
48
+ content_type: string;
49
+ visibility: AssetVisibility;
50
+ immutable: boolean;
51
+ url: string | null;
52
+ immutable_url: string | null;
53
+ cdn_url: string | null;
54
+ cdn_immutable_url: string | null;
55
+ sri: string | null;
56
+ etag: string;
57
+ content_digest: string;
58
+ immutableUrl: string | null;
59
+ cdnUrl: string | null;
60
+ cdnImmutableUrl: string | null;
61
+ size: number;
62
+ contentType: string;
63
+ contentSha256: string;
64
+ }
65
+ export declare const assets: {
66
+ /**
67
+ * Upload bytes to the project's blob store and return the resolved AssetRef.
68
+ *
69
+ * Defaults: `visibility: "public"`, `immutable: true`. The mutable `url`
70
+ * always serves the latest bytes for the key; the `immutableUrl` is
71
+ * content-hashed and stable for SRI / long-TTL caching.
72
+ *
73
+ * The gateway runs the same activation sub-transaction the wallet apply
74
+ * hero uses, so quota enforcement (402 on storage-tier overage),
75
+ * per-unique-hash storage billing, and immutable-URL retention all match
76
+ * deploy-time behavior.
77
+ */
78
+ put(key: string, source: AssetPutSourceInput, opts?: AssetPutOptions): Promise<AssetRef>;
79
+ };
80
+ //# sourceMappingURL=assets.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assets.d.ts","sourceRoot":"","sources":["../src/assets.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAIH,MAAM,MAAM,eAAe,GAAG,QAAQ,GAAG,SAAS,CAAC;AAEnD,MAAM,WAAW,cAAc;IAC7B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,UAAU,CAAC;CACpB;AAED,MAAM,MAAM,mBAAmB,GAAG,MAAM,GAAG,UAAU,GAAG,cAAc,CAAC;AAEvE,MAAM,WAAW,eAAe;IAC9B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,eAAe,CAAC;IAC7B;;;;;OAKG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,QAAQ;IACvB,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,eAAe,CAAC;IAC5B,SAAS,EAAE,OAAO,CAAC;IACnB,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,cAAc,EAAE,MAAM,CAAC;IAEvB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;CACvB;AAgGD,eAAO,MAAM,MAAM;IACjB;;;;;;;;;;;OAWG;aAEI,MAAM,UACH,mBAAmB,SACrB,eAAe,GACpB,OAAO,CAAC,QAAQ,CAAC;CAsCrB,CAAC"}
package/dist/assets.js ADDED
@@ -0,0 +1,144 @@
1
+ /**
2
+ * `assets` namespace — in-function blob upload via the unified-apply substrate.
3
+ *
4
+ * Calls `POST /apply/v1/service-asset-put` with service-key auth. The gateway
5
+ * runs the same activation sub-transaction the wallet-auth apply hero uses
6
+ * (`promoteStagedAssetSlice`), so visibility, immutable-URL retention, and
7
+ * per-unique-hash storage billing all behave identically to deploy-time
8
+ * `r.project(id).apply({ assets: { put: [...] } })`.
9
+ *
10
+ * Pre-v1.48 the runtime called `/storage/v1/uploads*`; that substrate was
11
+ * removed in the unified-apply migration. This namespace is the v2.1+
12
+ * in-function replacement.
13
+ */
14
+ import { config } from "./config.js";
15
+ const CONTENT_TYPE_BY_EXT = {
16
+ png: "image/png",
17
+ jpg: "image/jpeg",
18
+ jpeg: "image/jpeg",
19
+ gif: "image/gif",
20
+ svg: "image/svg+xml",
21
+ webp: "image/webp",
22
+ html: "text/html; charset=utf-8",
23
+ css: "text/css; charset=utf-8",
24
+ js: "text/javascript; charset=utf-8",
25
+ json: "application/json",
26
+ txt: "text/plain; charset=utf-8",
27
+ md: "text/markdown; charset=utf-8",
28
+ pdf: "application/pdf",
29
+ zip: "application/zip",
30
+ tgz: "application/gzip",
31
+ gz: "application/gzip",
32
+ };
33
+ function guessContentType(key) {
34
+ const dot = key.lastIndexOf(".");
35
+ if (dot < 0)
36
+ return "application/octet-stream";
37
+ const ext = key.slice(dot + 1).toLowerCase();
38
+ return CONTENT_TYPE_BY_EXT[ext] ?? "application/octet-stream";
39
+ }
40
+ function normalizeSource(source) {
41
+ if (typeof source === "string") {
42
+ return new TextEncoder().encode(source);
43
+ }
44
+ if (source instanceof Uint8Array) {
45
+ return source;
46
+ }
47
+ if (source && typeof source === "object") {
48
+ if (source.content !== undefined && source.bytes !== undefined) {
49
+ throw new Error("assets.put: provide exactly one of `content` or `bytes` in source");
50
+ }
51
+ if (typeof source.content === "string") {
52
+ return new TextEncoder().encode(source.content);
53
+ }
54
+ if (source.bytes instanceof Uint8Array) {
55
+ return source.bytes;
56
+ }
57
+ }
58
+ throw new Error("assets.put: source must be a string, Uint8Array, or { content | bytes } object");
59
+ }
60
+ function widenAssetRef(raw) {
61
+ const url = raw.url ?? null;
62
+ const immutableUrl = raw.immutable_url ?? null;
63
+ const cdnUrl = raw.cdn_url ?? null;
64
+ const cdnImmutableUrl = raw.cdn_immutable_url ?? null;
65
+ return {
66
+ key: String(raw.key ?? ""),
67
+ sha256: String(raw.sha256 ?? ""),
68
+ size_bytes: Number(raw.size_bytes ?? 0),
69
+ content_type: String(raw.content_type ?? "application/octet-stream"),
70
+ visibility: raw.visibility ?? "public",
71
+ immutable: raw.immutable === true,
72
+ url,
73
+ immutable_url: immutableUrl,
74
+ cdn_url: cdnUrl,
75
+ cdn_immutable_url: cdnImmutableUrl,
76
+ sri: raw.sri ?? null,
77
+ etag: String(raw.etag ?? ""),
78
+ content_digest: String(raw.content_digest ?? ""),
79
+ immutableUrl,
80
+ cdnUrl,
81
+ cdnImmutableUrl,
82
+ size: Number(raw.size_bytes ?? 0),
83
+ contentType: String(raw.content_type ?? "application/octet-stream"),
84
+ contentSha256: String(raw.sha256 ?? ""),
85
+ };
86
+ }
87
+ async function readErrorMessage(res) {
88
+ const text = await res.text();
89
+ try {
90
+ const parsed = JSON.parse(text);
91
+ const msg = parsed.message || parsed.error || text;
92
+ return parsed.code ? `${parsed.code}: ${msg}` : msg;
93
+ }
94
+ catch {
95
+ return text;
96
+ }
97
+ }
98
+ export const assets = {
99
+ /**
100
+ * Upload bytes to the project's blob store and return the resolved AssetRef.
101
+ *
102
+ * Defaults: `visibility: "public"`, `immutable: true`. The mutable `url`
103
+ * always serves the latest bytes for the key; the `immutableUrl` is
104
+ * content-hashed and stable for SRI / long-TTL caching.
105
+ *
106
+ * The gateway runs the same activation sub-transaction the wallet apply
107
+ * hero uses, so quota enforcement (402 on storage-tier overage),
108
+ * per-unique-hash storage billing, and immutable-URL retention all match
109
+ * deploy-time behavior.
110
+ */
111
+ async put(key, source, opts = {}) {
112
+ if (typeof key !== "string" || key === "") {
113
+ throw new Error("assets.put: key must be a non-empty string");
114
+ }
115
+ const bytes = normalizeSource(source);
116
+ if (bytes.byteLength === 0) {
117
+ throw new Error("assets.put: bytes must be non-empty");
118
+ }
119
+ const contentType = opts.contentType ?? guessContentType(key);
120
+ const visibility = opts.visibility ?? "public";
121
+ const immutable = opts.immutable ?? true;
122
+ // Slice into a fresh ArrayBuffer so the fetch body is a `BufferSource`
123
+ // (Uint8Array<ArrayBufferLike> stopped matching the DOM `BodyInit` union
124
+ // when TS 5.7 made TypedArrays generic over their backing buffer).
125
+ const buf = bytes.buffer.slice(bytes.byteOffset, bytes.byteOffset + bytes.byteLength);
126
+ const res = await fetch(config.API_BASE + "/apply/v1/service-asset-put", {
127
+ method: "POST",
128
+ headers: {
129
+ Authorization: "Bearer " + config.SERVICE_KEY,
130
+ "Content-Type": contentType,
131
+ "x-run402-asset-key": key,
132
+ "x-run402-asset-visibility": visibility,
133
+ "x-run402-asset-immutable": immutable ? "true" : "false",
134
+ },
135
+ body: buf,
136
+ });
137
+ if (!res.ok) {
138
+ throw new Error("Asset put failed (" + res.status + "): " + (await readErrorMessage(res)));
139
+ }
140
+ const raw = (await res.json());
141
+ return widenAssetRef(raw);
142
+ },
143
+ };
144
+ //# sourceMappingURL=assets.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assets.js","sourceRoot":"","sources":["../src/assets.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -5,6 +5,8 @@ export { email } from "./email.js";
5
5
  export type { EmailSendOptions, EmailRawOptions, EmailTemplateOptions, EmailSendResult } from "./email.js";
6
6
  export { ai } from "./ai.js";
7
7
  export type { GenerateImageOptions, GenerateImageResult, ImageAspect, TranslateOptions, TranslateResult, ModerateResult, } from "./ai.js";
8
+ export { assets } from "./assets.js";
9
+ export type { AssetPutOptions, AssetPutSource, AssetPutSourceInput, AssetRef, AssetVisibility, } from "./assets.js";
8
10
  export { bytes, isRequest, json, routedHttp, text } from "./routed-http.js";
9
11
  export type { RoutedHttpHeaderList, RoutedHttpRequestV1, RoutedHttpResponseInit, RoutedHttpResponseV1, } from "./routed-http.js";
10
12
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACpD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,YAAY,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,YAAY,EAAE,gBAAgB,EAAE,eAAe,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAC3G,OAAO,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC;AAC7B,YAAY,EACV,oBAAoB,EACpB,mBAAmB,EACnB,WAAW,EACX,gBAAgB,EAChB,eAAe,EACf,cAAc,GACf,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAC5E,YAAY,EACV,oBAAoB,EACpB,mBAAmB,EACnB,sBAAsB,EACtB,oBAAoB,GACrB,MAAM,kBAAkB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACpD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,YAAY,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,YAAY,EAAE,gBAAgB,EAAE,eAAe,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAC3G,OAAO,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC;AAC7B,YAAY,EACV,oBAAoB,EACpB,mBAAmB,EACnB,WAAW,EACX,gBAAgB,EAChB,eAAe,EACf,cAAc,GACf,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,YAAY,EACV,eAAe,EACf,cAAc,EACd,mBAAmB,EACnB,QAAQ,EACR,eAAe,GAChB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAC5E,YAAY,EACV,oBAAoB,EACpB,mBAAmB,EACnB,sBAAsB,EACtB,oBAAoB,GACrB,MAAM,kBAAkB,CAAC"}
package/dist/index.js CHANGED
@@ -2,5 +2,6 @@ export { db, adminDb, QueryBuilder } from "./db.js";
2
2
  export { getUser } from "./auth.js";
3
3
  export { email } from "./email.js";
4
4
  export { ai } from "./ai.js";
5
+ export { assets } from "./assets.js";
5
6
  export { bytes, isRequest, json, routedHttp, text } from "./routed-http.js";
6
7
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACpD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAEnC,OAAO,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC;AAS7B,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACpD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAEnC,OAAO,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC;AAS7B,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAQrC,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@run402/functions",
3
- "version": "2.0.1",
4
- "description": "In-function helper library for Run402 serverless functions — db, adminDb, getUser, email, ai. Auto-bundled into deployed functions; also installable for local TypeScript autocomplete.",
3
+ "version": "2.2.0",
4
+ "description": "In-function helper library for Run402 serverless functions — db, adminDb, getUser, email, ai, assets. Auto-bundled into deployed functions; also installable for local TypeScript autocomplete.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
7
7
  "types": "dist/index.d.ts",