@softr/sdk 0.0.47-alpha.0 → 0.0.47

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.
@@ -17,7 +17,7 @@ import * as _tanstack_react_start0 from "@tanstack/react-start";
17
17
  * requestMiddleware: [softrAuthMiddleware()],
18
18
  * }))
19
19
  */
20
- declare function softrAuthMiddleware(): _tanstack_react_start0.RequestMiddlewareAfterServer<{}, readonly [_tanstack_react_start0.RequestMiddlewareAfterServer<{}, undefined, undefined>, _tanstack_react_start0.RequestMiddlewareAfterServer<{}, undefined, undefined>], {
20
+ declare function softrAuthMiddleware(): _tanstack_react_start0.RequestMiddlewareAfterServer<{}, readonly [_tanstack_react_start0.RequestMiddlewareAfterServer<{}, undefined, undefined>], {
21
21
  user: User | null;
22
22
  permissions: Permissions;
23
23
  }>;
@@ -4,7 +4,6 @@ import { sessionConfig } from "./config.js";
4
4
  import { clearSession, makeSessionDataCookie, readSessionData, readSessionToken } from "./session.js";
5
5
  import { makePlatform } from "./platform.js";
6
6
  import { bootErrorMiddleware } from "../boot-error.js";
7
- import { pwaMiddleware } from "../pwa.js";
8
7
  import { createMiddleware, createServerFn, getGlobalStartContext } from "@tanstack/react-start";
9
8
  import { rootRouteId, useRouteContext } from "@tanstack/react-router";
10
9
 
@@ -22,7 +21,7 @@ import { rootRouteId, useRouteContext } from "@tanstack/react-router";
22
21
  * }))
23
22
  */
24
23
  function softrAuthMiddleware() {
25
- return createMiddleware({ type: "request" }).middleware([bootErrorMiddleware(), pwaMiddleware()]).server(async ({ next }) => {
24
+ return createMiddleware({ type: "request" }).middleware([bootErrorMiddleware()]).server(async ({ next }) => {
26
25
  async function getSession() {
27
26
  const token = readSessionToken();
28
27
  const cached = readSessionData(token);
@@ -3,6 +3,7 @@ import { permissionsSchema } from "./permissions.js";
3
3
  import { sessionConfig } from "./config.js";
4
4
  import { userSchema } from "./user.js";
5
5
  import { createCipheriv, createDecipheriv, createHash, randomBytes } from "node:crypto";
6
+ import { AsyncLocalStorage } from "node:async_hooks";
6
7
  import { getRequestProtocol } from "@tanstack/react-start/server";
7
8
  import { z } from "zod";
8
9
 
@@ -35,8 +36,20 @@ function sessionCookie(base) {
35
36
  secure
36
37
  };
37
38
  }
39
+ /**
40
+ * Runs `fn` with `token` standing in for the request's session cookie, so that
41
+ * every datasource call inside it acts as that visitor.
42
+ *
43
+ * For requests that carry who they are somewhere other than the cookie: an MCP
44
+ * call authenticates with a bearer token and has no cookie at all.
45
+ */
46
+ function withSessionToken(token, fn) {
47
+ return standInToken.run(token, fn);
48
+ }
38
49
  /** The platform token this request carries, or `null`. */
39
50
  function readSessionToken() {
51
+ const standIn = standInToken.getStore();
52
+ if (standIn !== void 0) return standIn;
40
53
  const { name } = sessionCookie(SESSION_TOKEN);
41
54
  return openEnvelope(readRequestCookies()[name], SESSION_TOKEN);
42
55
  }
@@ -105,6 +118,7 @@ function clearSession() {
105
118
  PENDING_AUTH
106
119
  ]);
107
120
  }
121
+ const standInToken = new AsyncLocalStorage();
108
122
  const sessionDataSchema = z.object({
109
123
  user: userSchema.nullable(),
110
124
  permissions: permissionsSchema,
@@ -196,4 +210,4 @@ function openEnvelope(raw, purpose) {
196
210
  }
197
211
 
198
212
  //#endregion
199
- export { clearPendingAuth, clearSession, makePendingAuthCookie, makeSessionDataCookie, makeSessionTokenCookie, readPendingAuthToken, readSessionData, readSessionToken };
213
+ export { clearPendingAuth, clearSession, makePendingAuthCookie, makeSessionDataCookie, makeSessionTokenCookie, readPendingAuthToken, readSessionData, readSessionToken, withSessionToken };
@@ -1,4 +1,4 @@
1
- import * as react1 from "react";
1
+ import * as react0 from "react";
2
2
 
3
3
  //#region src/default-error-overlay.d.ts
4
4
  type Props = {
@@ -8,6 +8,6 @@ type Props = {
8
8
  declare function DefaultErrorOverlay({
9
9
  error,
10
10
  reset
11
- }: Props): react1.JSX.Element;
11
+ }: Props): react0.JSX.Element;
12
12
  //#endregion
13
13
  export { DefaultErrorOverlay };
package/dist/index.d.ts CHANGED
@@ -6,8 +6,8 @@ import { SoftrContext } from "./auth/context.js";
6
6
  import { checkAccess, defineVisibility, isAuthorized } from "./visibility/visibility.js";
7
7
  import { assertRouteAccess, guardRoute, isAccessError, isAlreadyAuthenticatedError, isForbiddenError, isUnauthenticatedError } from "./visibility/route.js";
8
8
  import { getSoftrContext, initialSoftrContext, softrAuthMiddleware, useCurrentUser } from "./auth/isomorphic.js";
9
+ import { softrMcpMiddleware } from "./mcp.js";
9
10
  import { useUserTimezone } from "./timezone.js";
10
- import { PwaInstall, PwaPlatform, SoftrPwaHead, usePwaInstall } from "./pwa.js";
11
11
  import { DefaultErrorOverlay } from "./default-error-overlay.js";
12
12
  import { Audience } from "./visibility/audience.js";
13
- export { type ActionPermissions, Audience, DefaultErrorOverlay, type FileAttachment, type FileItem, type PwaInstall, type PwaPlatform, type SoftrContext, type SoftrDatasources, SoftrPwaHead, type SoftrUserGroupId, type SoftrUserGroups, type User, assertRouteAccess, checkAccess, defineIntegration, defineMutation, defineQuery, defineVisibility, defineWorkflow, getSoftrContext, guardRoute, initialSoftrContext, isAccessError, isAlreadyAuthenticatedError, isAuthorized, isForbiddenError, isUnauthenticatedError, softrAuthMiddleware, useCurrentUser, useFileUpload, usePwaInstall, useUserTimezone };
13
+ export { type ActionPermissions, Audience, DefaultErrorOverlay, type FileAttachment, type FileItem, type SoftrContext, type SoftrDatasources, type SoftrUserGroupId, type SoftrUserGroups, type User, assertRouteAccess, checkAccess, defineIntegration, defineMutation, defineQuery, defineVisibility, defineWorkflow, getSoftrContext, guardRoute, initialSoftrContext, isAccessError, isAlreadyAuthenticatedError, isAuthorized, isForbiddenError, isUnauthenticatedError, softrAuthMiddleware, softrMcpMiddleware, useCurrentUser, useFileUpload, useUserTimezone };
package/dist/index.js CHANGED
@@ -2,10 +2,10 @@ import { useFileUpload } from "./core/use-file-upload.js";
2
2
  import { defineIntegration, defineMutation, defineQuery, defineWorkflow } from "./action.js";
3
3
  import { checkAccess, defineVisibility, isAuthorized } from "./visibility/visibility.js";
4
4
  import { assertRouteAccess, guardRoute, isAccessError, isAlreadyAuthenticatedError, isForbiddenError, isUnauthenticatedError } from "./visibility/route.js";
5
- import { SoftrPwaHead, usePwaInstall } from "./pwa.js";
6
5
  import { getSoftrContext, initialSoftrContext, softrAuthMiddleware, useCurrentUser } from "./auth/isomorphic.js";
6
+ import { softrMcpMiddleware } from "./mcp.js";
7
7
  import { useUserTimezone } from "./timezone.js";
8
8
  import { DefaultErrorOverlay } from "./default-error-overlay.js";
9
9
  import { Audience } from "./visibility/audience.js";
10
10
 
11
- export { Audience, DefaultErrorOverlay, SoftrPwaHead, assertRouteAccess, checkAccess, defineIntegration, defineMutation, defineQuery, defineVisibility, defineWorkflow, getSoftrContext, guardRoute, initialSoftrContext, isAccessError, isAlreadyAuthenticatedError, isAuthorized, isForbiddenError, isUnauthenticatedError, softrAuthMiddleware, useCurrentUser, useFileUpload, usePwaInstall, useUserTimezone };
11
+ export { Audience, DefaultErrorOverlay, assertRouteAccess, checkAccess, defineIntegration, defineMutation, defineQuery, defineVisibility, defineWorkflow, getSoftrContext, guardRoute, initialSoftrContext, isAccessError, isAlreadyAuthenticatedError, isAuthorized, isForbiddenError, isUnauthenticatedError, softrAuthMiddleware, softrMcpMiddleware, useCurrentUser, useFileUpload, useUserTimezone };
package/dist/mcp.d.ts ADDED
@@ -0,0 +1,42 @@
1
+ import { DatasourceAction } from "./action.js";
2
+ import * as _tanstack_react_start2 from "@tanstack/react-start";
3
+
4
+ //#region src/mcp.d.ts
5
+
6
+ type SoftrMcpOptions = {
7
+ /**
8
+ * The actions to expose as tools, from `defineQuery` and `defineMutation`.
9
+ *
10
+ * Listing them is deliberate: an action left out is invisible over MCP, even
11
+ * though the app's own pages may use it. The action's own `permissions` still
12
+ * decide who may run the ones that are listed.
13
+ */
14
+ actions?: Array<DatasourceAction>;
15
+ /**
16
+ * The app's sign-in page, as a path on this app. A signed-out visitor who
17
+ * opens the approval page is sent here with `?redirect=` pointing back at it.
18
+ * Defaults to `/login`.
19
+ */
20
+ loginPath?: string;
21
+ };
22
+ /**
23
+ * Serves the MCP endpoint and its OAuth flow from the app's own origin.
24
+ *
25
+ * Register it in the app's `src/start.ts`, ahead of `softrAuthMiddleware`: it
26
+ * answers its own paths and resolves the caller from the bearer token, so it
27
+ * must not sit behind the session lookup that middleware does on every
28
+ * request. Everything else passes straight through.
29
+ *
30
+ * @example
31
+ * import { publishedPosts, addCafe } from './actions'
32
+ *
33
+ * export const startInstance = createStart(() => ({
34
+ * requestMiddleware: [
35
+ * softrMcpMiddleware({ actions: [publishedPosts, addCafe] }),
36
+ * softrAuthMiddleware(),
37
+ * ],
38
+ * }))
39
+ */
40
+ declare function softrMcpMiddleware(options?: SoftrMcpOptions): _tanstack_react_start2.RequestMiddlewareAfterServer<{}, undefined, undefined>;
41
+ //#endregion
42
+ export { softrMcpMiddleware };