@run402/functions 2.5.1 → 2.6.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/dist/auth.d.ts CHANGED
@@ -12,7 +12,7 @@ export interface User {
12
12
  * application role from a declarative `requireRole` gate. For the
13
13
  * gate-resolved application role, use {@link getRole}.
14
14
  */
15
- export declare function getUser(req: Request): User | null;
15
+ export declare function getUser(req?: Request): User | null;
16
16
  /**
17
17
  * Read the gate-resolved user id from the request.
18
18
  *
@@ -33,7 +33,7 @@ export declare function getUser(req: Request): User | null;
33
33
  * `members` table via gateway-side RLS-bypass; user code does not
34
34
  * need to re-decode the JWT.
35
35
  */
36
- export declare function getUserId(req: Request): string | null;
36
+ export declare function getUserId(req?: Request): string | null;
37
37
  /**
38
38
  * Read the gate-resolved application role from the request.
39
39
  *
@@ -53,5 +53,5 @@ export declare function getUserId(req: Request): string | null;
53
53
  * {@link getUser}. The two are independent — see the JSDoc on
54
54
  * `getUser` for the distinction.
55
55
  */
56
- export declare function getRole(req: Request): string | null;
56
+ export declare function getRole(req?: Request): string | null;
57
57
  //# sourceMappingURL=auth.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,IAAI;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;;;;;;GAQG;AACH,wBAAgB,OAAO,CAAC,GAAG,EAAE,OAAO,GAAG,IAAI,GAAG,IAAI,CAmBjD;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,SAAS,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAErD;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,OAAO,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAEnD"}
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,IAAI;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;;;;;;GAQG;AACH,wBAAgB,OAAO,CAAC,GAAG,CAAC,EAAE,OAAO,GAAG,IAAI,GAAG,IAAI,CAsClD;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,SAAS,CAAC,GAAG,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAOtD;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,OAAO,CAAC,GAAG,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAOpD"}
package/dist/auth.js CHANGED
@@ -1,5 +1,6 @@
1
- import jwt from "jsonwebtoken";
1
+ import jwt from "./lib/jwt.js";
2
2
  import { config } from "./config.js";
3
+ import { getCurrentContext, taintCacheBypass } from "./runtime-context.js";
3
4
  /**
4
5
  * Verify the caller's JWT and return user identity.
5
6
  * Returns { id, role, email } or null if unauthenticated/invalid.
@@ -10,9 +11,30 @@ import { config } from "./config.js";
10
11
  * gate-resolved application role, use {@link getRole}.
11
12
  */
12
13
  export function getUser(req) {
13
- const authHeader = typeof req.headers.get === "function"
14
- ? req.headers.get("authorization")
15
- : req.headers?.authorization;
14
+ // Capability `astro-ssr-runtime` (v1.52). Taint the cache-bypass flag
15
+ // on the active request context, regardless of whether `getUser`
16
+ // resolves to a user or null — the response now depends on per-request
17
+ // auth state and MUST NOT be cached publicly.
18
+ taintCacheBypass();
19
+ // If no `req` was passed, read auth from the ALS context (the SSR
20
+ // Lambda runtime's `runWithContext` populates `request.headers`).
21
+ // This is what makes `await getUser()` work naturally inside Astro
22
+ // `[slug].astro` frontmatter without any explicit plumbing.
23
+ let authHeader;
24
+ if (req !== undefined) {
25
+ authHeader =
26
+ typeof req.headers.get === "function"
27
+ ? req.headers.get("authorization")
28
+ : req.headers?.authorization;
29
+ }
30
+ else {
31
+ const ctx = getCurrentContext();
32
+ if (ctx === undefined)
33
+ return null;
34
+ const h = ctx.request.headers;
35
+ const raw = h["authorization"] ?? h["Authorization"];
36
+ authHeader = Array.isArray(raw) ? raw[0] : raw;
37
+ }
16
38
  if (!authHeader || !authHeader.startsWith("Bearer "))
17
39
  return null;
18
40
  const token = authHeader.slice(7);
@@ -47,7 +69,15 @@ export function getUser(req) {
47
69
  * need to re-decode the JWT.
48
70
  */
49
71
  export function getUserId(req) {
50
- return req.headers.get("x-run402-user-id");
72
+ if (req !== undefined)
73
+ return req.headers.get("x-run402-user-id");
74
+ const ctx = getCurrentContext();
75
+ if (ctx === undefined)
76
+ return null;
77
+ const raw = ctx.request.headers["x-run402-user-id"];
78
+ if (Array.isArray(raw))
79
+ return raw[0] ?? null;
80
+ return raw ?? null;
51
81
  }
52
82
  /**
53
83
  * Read the gate-resolved application role from the request.
@@ -69,6 +99,14 @@ export function getUserId(req) {
69
99
  * `getUser` for the distinction.
70
100
  */
71
101
  export function getRole(req) {
72
- return req.headers.get("x-run402-user-role");
102
+ if (req !== undefined)
103
+ return req.headers.get("x-run402-user-role");
104
+ const ctx = getCurrentContext();
105
+ if (ctx === undefined)
106
+ return null;
107
+ const raw = ctx.request.headers["x-run402-user-role"];
108
+ if (Array.isArray(raw))
109
+ return raw[0] ?? null;
110
+ return raw ?? null;
73
111
  }
74
112
  //# sourceMappingURL=auth.js.map
package/dist/auth.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"auth.js","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AAAA,OAAO,GAAG,MAAM,cAAc,CAAC;AAC/B,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAQrC;;;;;;;;GAQG;AACH,MAAM,UAAU,OAAO,CAAC,GAAY;IAClC,MAAM,UAAU,GACd,OAAQ,GAAG,CAAC,OAA6C,CAAC,GAAG,KAAK,UAAU;QAC1E,CAAC,CAAE,GAAG,CAAC,OAAmB,CAAC,GAAG,CAAC,eAAe,CAAC;QAC/C,CAAC,CAAE,GAAG,CAAC,OAAyD,EAAE,aAAa,CAAC;IACpF,IAAI,CAAC,UAAU,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,SAAS,CAAC;QAAE,OAAO,IAAI,CAAC;IAClE,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAClC,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,GAAG,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,UAAU,CAKlD,CAAC;QACF,IAAI,OAAO,CAAC,UAAU,KAAK,MAAM,CAAC,UAAU;YAAE,OAAO,IAAI,CAAC;QAC1D,OAAO,EAAE,EAAE,EAAE,OAAO,CAAC,GAAG,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC;IACvE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,UAAU,SAAS,CAAC,GAAY;IACpC,OAAO,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;AAC7C,CAAC;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,UAAU,OAAO,CAAC,GAAY;IAClC,OAAO,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;AAC/C,CAAC"}
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,122 @@
1
+ /**
2
+ * SSR cache invalidation SDK — capability `ssr-isr-cache`.
3
+ *
4
+ * Server-side (function-context) only. Reads the current request's
5
+ * project_id and host from `getCurrentContext()` (AsyncLocalStorage) to
6
+ * scope invalidations safely.
7
+ *
8
+ * Four operations:
9
+ *
10
+ * - `cache.invalidate(urlOrPath)` — delete cache rows for a specific
11
+ * path (or absolute URL). Returns `{ deleted, generation, host, path }`.
12
+ * - `cache.invalidatePrefix({ host, prefix })` — delete all rows
13
+ * under a path prefix on the given host.
14
+ * - `cache.invalidateAll({ host })` — delete all rows on the given
15
+ * host. Atomic with a generation bump.
16
+ * - `cache.invalidateMany(urls)` — bulk invalidate in one round-trip.
17
+ *
18
+ * Host authorization: absolute-URL forms (or explicit `host` in the
19
+ * options bag) MUST be hosts owned by the caller's authenticated
20
+ * project. Cross-project hosts throw `R402_CACHE_INVALIDATION_HOST_FORBIDDEN`.
21
+ *
22
+ * Path-string form requires an active request context (the SDK reads
23
+ * the current host from ALS); calling it outside a handler throws
24
+ * `R402_CACHE_INVALIDATION_HOST_REQUIRED`.
25
+ *
26
+ * Tag-based invalidation is NOT in v1; future v1.5 work.
27
+ *
28
+ * @see openspec/changes/astro-ssr-runtime/specs/ssr-isr-cache/spec.md
29
+ */
30
+ /** Result envelope returned by every invalidation API. */
31
+ export interface CacheInvalidateResult {
32
+ /** Number of `internal.ssr_cache` rows DELETEd by this call. */
33
+ deleted: number;
34
+ /** Post-increment generation. Each invalidate bumps the per-(project,
35
+ * host) generation counter, which gates in-flight MISS writes from
36
+ * populating stale content after the invalidate. */
37
+ generation: bigint;
38
+ /** The host the invalidation targeted. */
39
+ host: string;
40
+ /** The pathname targeted (single-URL form only); undefined for
41
+ * prefix/all/many. */
42
+ path?: string;
43
+ }
44
+ export interface InvalidatePrefixOptions {
45
+ host: string;
46
+ prefix: string;
47
+ }
48
+ export interface InvalidateAllOptions {
49
+ host: string;
50
+ }
51
+ /**
52
+ * Structured error thrown when path-string form is called outside an
53
+ * active request context. The caller has no host to scope against.
54
+ * Use the absolute-URL form instead OR move the call into a handler.
55
+ */
56
+ export declare class CacheInvalidationHostRequiredError extends Error {
57
+ readonly code = "R402_CACHE_INVALIDATION_HOST_REQUIRED";
58
+ readonly docs = "https://docs.run402.com/cache/errors#invalidation-host-required";
59
+ readonly suggestedFix = "Pass an absolute URL (e.g., `new URL('https://eagles.kychon.com/the-guys')`) OR move the call into a request handler so the SDK can resolve the current host.";
60
+ constructor();
61
+ }
62
+ /**
63
+ * Structured error thrown when an invalidation targets a host that is
64
+ * not owned by the caller's authenticated project. Prevents project A
65
+ * from invalidating project B's cache.
66
+ */
67
+ export declare class CacheInvalidationHostForbiddenError extends Error {
68
+ readonly code = "R402_CACHE_INVALIDATION_HOST_FORBIDDEN";
69
+ readonly docs = "https://docs.run402.com/cache/errors#invalidation-host-forbidden";
70
+ readonly host: string;
71
+ readonly suggestedFix: string;
72
+ constructor(host: string);
73
+ }
74
+ /**
75
+ * Invalidate a single cached SSR response.
76
+ *
77
+ * Accepts either:
78
+ * - a path string (e.g., `'/the-guys'`) — the SDK reads the current
79
+ * host from the active request context (throws
80
+ * `CacheInvalidationHostRequiredError` if no context)
81
+ * - an absolute URL (e.g., `new URL('https://eagles.kychon.com/the-guys')`)
82
+ * — multi-host admin scenarios (host MUST be owned by caller's
83
+ * project; throws `CacheInvalidationHostForbiddenError` otherwise)
84
+ *
85
+ * Deletes GET and HEAD rows for ALL locales and ALL release ids matching
86
+ * the exact canonical pathname + normalized search on the target host.
87
+ *
88
+ * The DELETE and the per-(project, host) generation increment happen in
89
+ * the same transaction; the post-increment generation is returned.
90
+ */
91
+ export declare function invalidate(urlOrPath: string | URL): Promise<CacheInvalidateResult>;
92
+ /**
93
+ * Invalidate all cache rows under a path prefix on the given host.
94
+ */
95
+ export declare function invalidatePrefix(opts: InvalidatePrefixOptions): Promise<CacheInvalidateResult>;
96
+ /**
97
+ * Invalidate all cache rows for the given host (entire-host purge).
98
+ * Useful for catastrophic content changes (nav restructure, layout
99
+ * update, etc.) where targeted invalidation would be impractical.
100
+ */
101
+ export declare function invalidateAll(opts: InvalidateAllOptions): Promise<CacheInvalidateResult>;
102
+ /**
103
+ * Bulk-invalidate many URLs in a single round-trip. Path-string forms
104
+ * use the current request context's host; absolute URLs are scoped
105
+ * individually.
106
+ *
107
+ * Returns a SUMMARY envelope with the total deleted count. Per-URL
108
+ * results are also available on the optional `results` field of the
109
+ * returned object (not in the result type return for the common case;
110
+ * use the internal endpoint if you need per-URL precision).
111
+ */
112
+ export declare function invalidateMany(urls: Array<string | URL>): Promise<CacheInvalidateResult>;
113
+ /** The full cache namespace exported via the `cache` named export from
114
+ * `@run402/functions`. */
115
+ export declare const cache: {
116
+ readonly invalidate: typeof invalidate;
117
+ readonly invalidatePrefix: typeof invalidatePrefix;
118
+ readonly invalidateAll: typeof invalidateAll;
119
+ readonly invalidateMany: typeof invalidateMany;
120
+ };
121
+ export type Cache = typeof cache;
122
+ //# sourceMappingURL=cache.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../src/cache.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAKH,0DAA0D;AAC1D,MAAM,WAAW,qBAAqB;IACpC,gEAAgE;IAChE,OAAO,EAAE,MAAM,CAAC;IAChB;;yDAEqD;IACrD,UAAU,EAAE,MAAM,CAAC;IACnB,0CAA0C;IAC1C,IAAI,EAAE,MAAM,CAAC;IACb;2BACuB;IACvB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,uBAAuB;IACtC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;;GAIG;AACH,qBAAa,kCAAmC,SAAQ,KAAK;IAC3D,QAAQ,CAAC,IAAI,2CAA2C;IACxD,QAAQ,CAAC,IAAI,qEAAqE;IAClF,QAAQ,CAAC,YAAY,mKAC6I;;CASnK;AAED;;;;GAIG;AACH,qBAAa,mCAAoC,SAAQ,KAAK;IAC5D,QAAQ,CAAC,IAAI,4CAA4C;IACzD,QAAQ,CAAC,IAAI,sEAAsE;IACnF,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;gBAElB,IAAI,EAAE,MAAM;CAMzB;AA4DD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,GAAG,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAsCxF;AAED;;GAEG;AACH,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,uBAAuB,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAepG;AAED;;;;GAIG;AACH,wBAAsB,aAAa,CAAC,IAAI,EAAE,oBAAoB,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAW9F;AAED;;;;;;;;;GASG;AACH,wBAAsB,cAAc,CAAC,IAAI,EAAE,KAAK,CAAC,MAAM,GAAG,GAAG,CAAC,GAAG,OAAO,CAAC,qBAAqB,CAAC,CA0B9F;AAED;2BAC2B;AAC3B,eAAO,MAAM,KAAK;;;;;CAKR,CAAC;AAEX,MAAM,MAAM,KAAK,GAAG,OAAO,KAAK,CAAC"}
package/dist/cache.js ADDED
@@ -0,0 +1,243 @@
1
+ /**
2
+ * SSR cache invalidation SDK — capability `ssr-isr-cache`.
3
+ *
4
+ * Server-side (function-context) only. Reads the current request's
5
+ * project_id and host from `getCurrentContext()` (AsyncLocalStorage) to
6
+ * scope invalidations safely.
7
+ *
8
+ * Four operations:
9
+ *
10
+ * - `cache.invalidate(urlOrPath)` — delete cache rows for a specific
11
+ * path (or absolute URL). Returns `{ deleted, generation, host, path }`.
12
+ * - `cache.invalidatePrefix({ host, prefix })` — delete all rows
13
+ * under a path prefix on the given host.
14
+ * - `cache.invalidateAll({ host })` — delete all rows on the given
15
+ * host. Atomic with a generation bump.
16
+ * - `cache.invalidateMany(urls)` — bulk invalidate in one round-trip.
17
+ *
18
+ * Host authorization: absolute-URL forms (or explicit `host` in the
19
+ * options bag) MUST be hosts owned by the caller's authenticated
20
+ * project. Cross-project hosts throw `R402_CACHE_INVALIDATION_HOST_FORBIDDEN`.
21
+ *
22
+ * Path-string form requires an active request context (the SDK reads
23
+ * the current host from ALS); calling it outside a handler throws
24
+ * `R402_CACHE_INVALIDATION_HOST_REQUIRED`.
25
+ *
26
+ * Tag-based invalidation is NOT in v1; future v1.5 work.
27
+ *
28
+ * @see openspec/changes/astro-ssr-runtime/specs/ssr-isr-cache/spec.md
29
+ */
30
+ import { config } from "./config.js";
31
+ import { getCurrentContext } from "./runtime-context.js";
32
+ /**
33
+ * Structured error thrown when path-string form is called outside an
34
+ * active request context. The caller has no host to scope against.
35
+ * Use the absolute-URL form instead OR move the call into a handler.
36
+ */
37
+ export class CacheInvalidationHostRequiredError extends Error {
38
+ code = "R402_CACHE_INVALIDATION_HOST_REQUIRED";
39
+ docs = "https://docs.run402.com/cache/errors#invalidation-host-required";
40
+ suggestedFix = "Pass an absolute URL (e.g., `new URL('https://eagles.kychon.com/the-guys')`) OR move the call into a request handler so the SDK can resolve the current host.";
41
+ constructor() {
42
+ super("cache.invalidate(path) called outside a request context. " +
43
+ "Path-string form needs the current host from request scope.");
44
+ this.name = "CacheInvalidationHostRequiredError";
45
+ }
46
+ }
47
+ /**
48
+ * Structured error thrown when an invalidation targets a host that is
49
+ * not owned by the caller's authenticated project. Prevents project A
50
+ * from invalidating project B's cache.
51
+ */
52
+ export class CacheInvalidationHostForbiddenError extends Error {
53
+ code = "R402_CACHE_INVALIDATION_HOST_FORBIDDEN";
54
+ docs = "https://docs.run402.com/cache/errors#invalidation-host-forbidden";
55
+ host;
56
+ suggestedFix;
57
+ constructor(host) {
58
+ super(`host ${host} is not owned by the current project`);
59
+ this.name = "CacheInvalidationHostForbiddenError";
60
+ this.host = host;
61
+ this.suggestedFix = `Use a host attached to your project. List your project's hosts with \`r.domains.list()\` or check Run402 dashboard. The cache layer rejects cross-project invalidations to preserve tenant isolation.`;
62
+ }
63
+ }
64
+ /**
65
+ * Internal: call the gateway's cache invalidation endpoint with the
66
+ * resolved scope. The gateway enforces project ownership of the host
67
+ * server-side; this function relies on that enforcement but ALSO
68
+ * validates the response shape.
69
+ */
70
+ async function callCacheInvalidate(body) {
71
+ const url = `${config.API_BASE}/cache/v1/invalidate`;
72
+ const response = await fetch(url, {
73
+ method: "POST",
74
+ headers: {
75
+ "content-type": "application/json",
76
+ // The gateway resolves the caller's project from the service key.
77
+ // Cache invalidation is server-side only; the SDK is bundled into
78
+ // user functions and runs with RUN402_SERVICE_KEY in scope.
79
+ Authorization: "Bearer " + config.SERVICE_KEY,
80
+ },
81
+ body: JSON.stringify(body),
82
+ });
83
+ if (response.status === 403) {
84
+ const errBody = (await response.json().catch(() => ({})));
85
+ const host = typeof errBody.host === "string" ? errBody.host : (body.host ?? "");
86
+ throw new CacheInvalidationHostForbiddenError(host);
87
+ }
88
+ if (!response.ok) {
89
+ const errBody = await response.text().catch(() => "");
90
+ throw new Error(`cache.invalidate(${body.kind}) failed: HTTP ${response.status} ${errBody.slice(0, 200)}`);
91
+ }
92
+ const json = (await response.json());
93
+ return {
94
+ deleted: json.deleted,
95
+ generation: BigInt(json.generation),
96
+ host: json.host,
97
+ path: json.path,
98
+ results: json.results?.map((r) => ({
99
+ ...r,
100
+ generation: BigInt(r.generation),
101
+ })),
102
+ };
103
+ }
104
+ /**
105
+ * Invalidate a single cached SSR response.
106
+ *
107
+ * Accepts either:
108
+ * - a path string (e.g., `'/the-guys'`) — the SDK reads the current
109
+ * host from the active request context (throws
110
+ * `CacheInvalidationHostRequiredError` if no context)
111
+ * - an absolute URL (e.g., `new URL('https://eagles.kychon.com/the-guys')`)
112
+ * — multi-host admin scenarios (host MUST be owned by caller's
113
+ * project; throws `CacheInvalidationHostForbiddenError` otherwise)
114
+ *
115
+ * Deletes GET and HEAD rows for ALL locales and ALL release ids matching
116
+ * the exact canonical pathname + normalized search on the target host.
117
+ *
118
+ * The DELETE and the per-(project, host) generation increment happen in
119
+ * the same transaction; the post-increment generation is returned.
120
+ */
121
+ export async function invalidate(urlOrPath) {
122
+ let host;
123
+ let path;
124
+ if (urlOrPath instanceof URL) {
125
+ host = urlOrPath.host.toLowerCase();
126
+ path = urlOrPath.pathname + urlOrPath.search;
127
+ }
128
+ else if (typeof urlOrPath === "string" && urlOrPath.startsWith("http://")) {
129
+ // Allow http:// only for local-dev parity, but the gateway will
130
+ // typically reject it.
131
+ const u = new URL(urlOrPath);
132
+ host = u.host.toLowerCase();
133
+ path = u.pathname + u.search;
134
+ }
135
+ else if (typeof urlOrPath === "string" && urlOrPath.startsWith("https://")) {
136
+ const u = new URL(urlOrPath);
137
+ host = u.host.toLowerCase();
138
+ path = u.pathname + u.search;
139
+ }
140
+ else if (typeof urlOrPath === "string" && urlOrPath.startsWith("/")) {
141
+ // Path-string form: requires active request context to resolve host.
142
+ const ctx = getCurrentContext();
143
+ if (ctx === undefined || !ctx.active.value) {
144
+ throw new CacheInvalidationHostRequiredError();
145
+ }
146
+ host = ctx.host.toLowerCase();
147
+ path = urlOrPath;
148
+ }
149
+ else {
150
+ throw new Error(`cache.invalidate: argument must be a URL, an "https://" URL string, or a path starting with "/". Got: ${typeof urlOrPath === "string" ? `"${urlOrPath}"` : typeof urlOrPath}`);
151
+ }
152
+ const result = await callCacheInvalidate({ kind: "exact", host, path });
153
+ return {
154
+ deleted: result.deleted,
155
+ generation: result.generation,
156
+ host: result.host,
157
+ path: result.path ?? path,
158
+ };
159
+ }
160
+ /**
161
+ * Invalidate all cache rows under a path prefix on the given host.
162
+ */
163
+ export async function invalidatePrefix(opts) {
164
+ if (!opts.host)
165
+ throw new Error("cache.invalidatePrefix: host is required");
166
+ if (!opts.prefix || !opts.prefix.startsWith("/")) {
167
+ throw new Error("cache.invalidatePrefix: prefix must start with '/'");
168
+ }
169
+ const result = await callCacheInvalidate({
170
+ kind: "prefix",
171
+ host: opts.host.toLowerCase(),
172
+ prefix: opts.prefix,
173
+ });
174
+ return {
175
+ deleted: result.deleted,
176
+ generation: result.generation,
177
+ host: result.host,
178
+ };
179
+ }
180
+ /**
181
+ * Invalidate all cache rows for the given host (entire-host purge).
182
+ * Useful for catastrophic content changes (nav restructure, layout
183
+ * update, etc.) where targeted invalidation would be impractical.
184
+ */
185
+ export async function invalidateAll(opts) {
186
+ if (!opts.host)
187
+ throw new Error("cache.invalidateAll: host is required");
188
+ const result = await callCacheInvalidate({
189
+ kind: "all",
190
+ host: opts.host.toLowerCase(),
191
+ });
192
+ return {
193
+ deleted: result.deleted,
194
+ generation: result.generation,
195
+ host: result.host,
196
+ };
197
+ }
198
+ /**
199
+ * Bulk-invalidate many URLs in a single round-trip. Path-string forms
200
+ * use the current request context's host; absolute URLs are scoped
201
+ * individually.
202
+ *
203
+ * Returns a SUMMARY envelope with the total deleted count. Per-URL
204
+ * results are also available on the optional `results` field of the
205
+ * returned object (not in the result type return for the common case;
206
+ * use the internal endpoint if you need per-URL precision).
207
+ */
208
+ export async function invalidateMany(urls) {
209
+ if (!Array.isArray(urls) || urls.length === 0) {
210
+ return { deleted: 0, generation: 0n, host: "" };
211
+ }
212
+ // Resolve each URL to its absolute form, using the current context
213
+ // for path-only entries.
214
+ const ctx = getCurrentContext();
215
+ const resolved = urls.map((u) => {
216
+ if (u instanceof URL)
217
+ return u.toString();
218
+ if (u.startsWith("https://") || u.startsWith("http://"))
219
+ return u;
220
+ if (u.startsWith("/")) {
221
+ if (ctx === undefined || !ctx.active.value) {
222
+ throw new CacheInvalidationHostRequiredError();
223
+ }
224
+ return `https://${ctx.host}${u}`;
225
+ }
226
+ throw new Error(`cache.invalidateMany: invalid entry "${u}"`);
227
+ });
228
+ const result = await callCacheInvalidate({ kind: "many", urls: resolved });
229
+ return {
230
+ deleted: result.deleted,
231
+ generation: result.generation,
232
+ host: result.host ?? "",
233
+ };
234
+ }
235
+ /** The full cache namespace exported via the `cache` named export from
236
+ * `@run402/functions`. */
237
+ export const cache = {
238
+ invalidate,
239
+ invalidatePrefix,
240
+ invalidateAll,
241
+ invalidateMany,
242
+ };
243
+ //# sourceMappingURL=cache.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache.js","sourceRoot":"","sources":["../src/cache.ts"],"names":[],"mappings":"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"}
package/dist/db.d.ts CHANGED
@@ -30,15 +30,34 @@ interface CallerDbClient {
30
30
  from(table: string): QueryBuilder;
31
31
  }
32
32
  /**
33
- * Caller-context DB client. Forwards the incoming Request's Authorization
34
- * header to PostgREST so RLS policies evaluate against the caller's role.
35
- * `apikey` is the project's anon key (routing only — does not grant bypass).
33
+ * Caller-context DB client. Forwards the caller's Authorization header
34
+ * to PostgREST so RLS policies evaluate against the caller's role.
36
35
  *
37
- * If the incoming Request has no Authorization, the request is sent with
38
- * just the anon apikey; PostgREST resolves role=anon and RLS decides whether
39
- * the query succeeds or returns 401/403.
36
+ * Capability `astro-ssr-runtime` (v1.52): `db()` now accepts the request
37
+ * via either path:
38
+ *
39
+ * 1. **Explicit `db(req)`** — pass a Web `Request` (or Express
40
+ * `req.raw` equivalent). The existing v0.x call shape.
41
+ *
42
+ * 2. **Implicit `db()`** — when called with no argument, reads the
43
+ * Authorization header from the active AsyncLocalStorage request
44
+ * context (populated by the SSR Lambda runtime in `@run402/astro`).
45
+ * This is what makes `await db().from(...)` work naturally inside
46
+ * Astro `[slug].astro` frontmatter without explicit plumbing.
47
+ *
48
+ * `apikey` is the project's anon key (routing only — does not grant
49
+ * bypass). If no Authorization is present (in either form), the request
50
+ * is sent with just the anon apikey; PostgREST resolves role=anon and
51
+ * RLS decides whether the query succeeds or returns 401/403.
52
+ *
53
+ * Outside an active request context (module scope, background timer
54
+ * past response materialization), `db()` (no arg) still works — it
55
+ * sends with no Authorization, exactly as the v0.x behavior with a
56
+ * Request that has no auth header. SDK functions that REQUIRE a context
57
+ * (like `cache.invalidate` path-form) throw `R402_SDK_OUTSIDE_REQUEST_CONTEXT`
58
+ * separately.
40
59
  */
41
- export declare function db(req: Request): CallerDbClient;
60
+ export declare function db(req?: Request): CallerDbClient;
42
61
  interface AdminDbClient {
43
62
  from(table: string): QueryBuilder;
44
63
  sql(query: string, params?: unknown[]): Promise<Record<string, unknown>[]>;
package/dist/db.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"db.d.ts","sourceRoot":"","sources":["../src/db.ts"],"names":[],"mappings":"AAEA,UAAU,gBAAgB;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,EAAE,MAAM,GAAG,SAAS,CAAC;IAClC,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,qBAAa,YAAY;;gBASX,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,gBAAgB;IAOjD,MAAM,CAAC,OAAO,SAAM,GAAG,IAAI;IAK3B,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAKhD,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAKjD,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAKhD,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAKhD,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAKjD,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAKjD,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI;IAK3C,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI;IAK5C,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,GAAG,IAAI;IAKrD,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,SAAgB,EAAE;;KAAK,GAAG,IAAI;IAKtD,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAK1B,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAK3B,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,IAAI;IAMvE,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAM3C,MAAM,IAAI,IAAI;IAKd,IAAI,CACF,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,KAAK,IAAI,EACnD,MAAM,EAAE,CAAC,MAAM,EAAE,KAAK,KAAK,IAAI,GAC9B,IAAI;CA6BR;AAOD,UAAU,cAAc;IACtB,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,YAAY,CAAC;CACnC;AAED;;;;;;;;GAQG;AACH,wBAAgB,EAAE,CAAC,GAAG,EAAE,OAAO,GAAG,cAAc,CAkB/C;AAED,UAAU,aAAa;IACrB,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,YAAY,CAAC;IAClC,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC,CAAC;CAC5E;AAED;;;;;;;;GAQG;AACH,wBAAgB,OAAO,IAAI,aAAa,CA+BvC"}
1
+ {"version":3,"file":"db.d.ts","sourceRoot":"","sources":["../src/db.ts"],"names":[],"mappings":"AAGA,UAAU,gBAAgB;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,EAAE,MAAM,GAAG,SAAS,CAAC;IAClC,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,qBAAa,YAAY;;gBASX,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,gBAAgB;IAOjD,MAAM,CAAC,OAAO,SAAM,GAAG,IAAI;IAK3B,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAKhD,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAKjD,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAKhD,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAKhD,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAKjD,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAKjD,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI;IAK3C,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI;IAK5C,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,GAAG,IAAI;IAKrD,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,SAAgB,EAAE;;KAAK,GAAG,IAAI;IAKtD,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAK1B,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAK3B,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,IAAI;IAMvE,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAM3C,MAAM,IAAI,IAAI;IAKd,IAAI,CACF,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,KAAK,IAAI,EACnD,MAAM,EAAE,CAAC,MAAM,EAAE,KAAK,KAAK,IAAI,GAC9B,IAAI;CA6BR;AAgBD,UAAU,cAAc;IACtB,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,YAAY,CAAC;CACnC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,EAAE,CAAC,GAAG,CAAC,EAAE,OAAO,GAAG,cAAc,CAkBhD;AAED,UAAU,aAAa;IACrB,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,YAAY,CAAC;IAClC,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC,CAAC;CAC5E;AAED;;;;;;;;GAQG;AACH,wBAAgB,OAAO,IAAI,aAAa,CA+BvC"}
package/dist/db.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import { config } from "./config.js";
2
+ import { getCurrentContext } from "./runtime-context.js";
2
3
  export class QueryBuilder {
3
4
  #table;
4
5
  #params = new URLSearchParams();
@@ -111,21 +112,50 @@ function extractAuth(req) {
111
112
  const auth = req.headers.get("authorization") ?? req.headers.get("Authorization");
112
113
  return auth ?? undefined;
113
114
  }
115
+ function extractAuthFromAls() {
116
+ const ctx = getCurrentContext();
117
+ if (ctx === undefined)
118
+ return undefined;
119
+ const headers = ctx.request.headers;
120
+ const raw = headers["authorization"] ?? headers["Authorization"];
121
+ if (Array.isArray(raw))
122
+ return raw[0];
123
+ return raw ?? undefined;
124
+ }
114
125
  /**
115
- * Caller-context DB client. Forwards the incoming Request's Authorization
116
- * header to PostgREST so RLS policies evaluate against the caller's role.
117
- * `apikey` is the project's anon key (routing only — does not grant bypass).
126
+ * Caller-context DB client. Forwards the caller's Authorization header
127
+ * to PostgREST so RLS policies evaluate against the caller's role.
128
+ *
129
+ * Capability `astro-ssr-runtime` (v1.52): `db()` now accepts the request
130
+ * via either path:
131
+ *
132
+ * 1. **Explicit `db(req)`** — pass a Web `Request` (or Express
133
+ * `req.raw` equivalent). The existing v0.x call shape.
134
+ *
135
+ * 2. **Implicit `db()`** — when called with no argument, reads the
136
+ * Authorization header from the active AsyncLocalStorage request
137
+ * context (populated by the SSR Lambda runtime in `@run402/astro`).
138
+ * This is what makes `await db().from(...)` work naturally inside
139
+ * Astro `[slug].astro` frontmatter without explicit plumbing.
140
+ *
141
+ * `apikey` is the project's anon key (routing only — does not grant
142
+ * bypass). If no Authorization is present (in either form), the request
143
+ * is sent with just the anon apikey; PostgREST resolves role=anon and
144
+ * RLS decides whether the query succeeds or returns 401/403.
118
145
  *
119
- * If the incoming Request has no Authorization, the request is sent with
120
- * just the anon apikey; PostgREST resolves role=anon and RLS decides whether
121
- * the query succeeds or returns 401/403.
146
+ * Outside an active request context (module scope, background timer
147
+ * past response materialization), `db()` (no arg) still works it
148
+ * sends with no Authorization, exactly as the v0.x behavior with a
149
+ * Request that has no auth header. SDK functions that REQUIRE a context
150
+ * (like `cache.invalidate` path-form) throw `R402_SDK_OUTSIDE_REQUEST_CONTEXT`
151
+ * separately.
122
152
  */
123
153
  export function db(req) {
124
154
  if (!config.ANON_KEY) {
125
- throw new Error("db(req) requires RUN402_ANON_KEY in the Lambda environment. " +
155
+ throw new Error("db() requires RUN402_ANON_KEY in the Lambda environment. " +
126
156
  "Redeploy this function via the gateway to pick up the new env var.");
127
157
  }
128
- const authorization = extractAuth(req);
158
+ const authorization = req !== undefined ? extractAuth(req) : extractAuthFromAls();
129
159
  const anonKey = config.ANON_KEY;
130
160
  return {
131
161
  from(table) {
package/dist/db.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"db.js","sourceRoot":"","sources":["../src/db.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"db.js","sourceRoot":"","sources":["../src/db.ts"],"names":[],"mappings":"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"}