@softr/sdk 0.0.10 → 0.0.11

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/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { a as readSessionToken, c as writeCookies, i as readSessionData, l as assert, n as makeSessionDataCookie, o as fetchVisitor, t as clearSession } from "./session-Blx62HHJ.js";
1
+ import { a as readSessionToken, c as writeCookies, i as readSessionData, l as assert, n as makeSessionDataCookie, o as fetchVisitor, t as clearSession } from "./session-GUEI96C8.js";
2
2
  import { redirect } from "@tanstack/react-router";
3
3
  import { createMiddleware, createServerFn, getGlobalStartContext } from "@tanstack/react-start";
4
4
 
package/dist/server.js CHANGED
@@ -1,4 +1,4 @@
1
- import { a as readSessionToken, c as writeCookies, d as softAssert, f as todo, n as makeSessionDataCookie, o as fetchVisitor, r as makeSessionTokenCookie, s as sessionConfig, t as clearSession, u as panic } from "./session-Blx62HHJ.js";
1
+ import { a as readSessionToken, c as writeCookies, d as softAssert, f as todo, n as makeSessionDataCookie, o as fetchVisitor, r as makeSessionTokenCookie, s as platformFetch, t as clearSession, u as panic } from "./session-GUEI96C8.js";
2
2
  import { z } from "zod";
3
3
  import "@tanstack/react-start/server-only";
4
4
 
@@ -18,9 +18,6 @@ async function describe(response, action) {
18
18
  const said = body.success && body.data.message ? body.data.message : response.statusText;
19
19
  return `Softr platform refused the ${action}: ${response.status} ${said}`.trim();
20
20
  }
21
- function endpoint(config, path) {
22
- return `${config.platformApiUrl}/v1/applications/${config.applicationId}/users/${path}`;
23
- }
24
21
 
25
22
  //#endregion
26
23
  //#region src/auth/methods/password.ts
@@ -35,8 +32,7 @@ const signInBody = z.object({
35
32
  * so the next request costs no round-trip.
36
33
  */
37
34
  async function signIn(credentials) {
38
- const config = sessionConfig();
39
- const response = await fetch(endpoint(config, "sign-in"), {
35
+ const response = await platformFetch("sign-in", {
40
36
  method: "POST",
41
37
  headers: {
42
38
  "content-type": "application/json",
@@ -73,11 +69,10 @@ async function signIn(credentials) {
73
69
  * because the local half already succeeded.
74
70
  */
75
71
  async function signOut() {
76
- const config = sessionConfig();
77
72
  const token = readSessionToken();
78
73
  clearSession();
79
74
  if (!token) return;
80
- const response = await fetch(endpoint(config, "sign-out"), {
75
+ const response = await platformFetch("sign-out", {
81
76
  method: "POST",
82
77
  headers: {
83
78
  authorization: `Bearer ${token}`,
@@ -95,7 +90,7 @@ async function signOut() {
95
90
  * User only exists once `confirmSignUp` returns the code.
96
91
  */
97
92
  async function signUp(details) {
98
- const response = await fetch(endpoint(sessionConfig(), "sign-up"), {
93
+ const response = await platformFetch("sign-up", {
99
94
  method: "POST",
100
95
  headers: {
101
96
  "content-type": "application/json",
@@ -120,8 +115,7 @@ async function signUp(details) {
120
115
  * `users/new`.
121
116
  */
122
117
  async function confirmSignUp(details) {
123
- const config = sessionConfig();
124
- const verified = await fetch(endpoint(config, "sign-up"), {
118
+ const verified = await platformFetch("sign-up", {
125
119
  method: "POST",
126
120
  headers: {
127
121
  "content-type": "application/json",
@@ -138,7 +132,7 @@ async function confirmSignUp(details) {
138
132
  const verifiedBody = await verified.text();
139
133
  let token = tokenBody.parse(verifiedBody.length === 0 ? {} : JSON.parse(verifiedBody)).jwt;
140
134
  if (!token) {
141
- const created = await fetch(endpoint(config, "new"), {
135
+ const created = await platformFetch("new", {
142
136
  method: "POST",
143
137
  headers: {
144
138
  "content-type": "application/json",
@@ -103,19 +103,14 @@ function writeCookies(cookies) {
103
103
  //#endregion
104
104
  //#region src/auth/config.ts
105
105
  const DEFAULT_SESSION_MAX_AGE = 2160 * 60 * 60;
106
- /** 32 bytes, hex encoded. */
107
- const SESSION_SECRET = /^[0-9a-f]{64}$/i;
108
106
  function loadSessionConfig() {
109
107
  const missing = [];
110
108
  const applicationId = process.env.SOFTR_APPLICATION_ID;
111
109
  if (!applicationId) missing.push("SOFTR_APPLICATION_ID");
112
110
  const sessionSecret = process.env.SOFTR_SESSION_SECRET;
113
111
  if (!sessionSecret) missing.push("SOFTR_SESSION_SECRET");
114
- const platformApiUrl = process.env.SOFTR_PLATFORM_API_URL;
115
- if (!platformApiUrl) missing.push("SOFTR_PLATFORM_API_URL");
116
112
  if (missing.length > 0) throw new Error(`Softr auth is not configured: missing ${missing.join(", ")}.`);
117
- assert(applicationId && sessionSecret && platformApiUrl);
118
- if (!SESSION_SECRET.test(sessionSecret)) throw new Error("SOFTR_SESSION_SECRET must be 32 random bytes encoded as hex.\nGenerate one with: openssl rand -hex 32");
113
+ assert(applicationId && sessionSecret);
119
114
  const rawMaxAge = process.env.SOFTR_SESSION_MAX_AGE;
120
115
  let sessionMaxAge = DEFAULT_SESSION_MAX_AGE;
121
116
  if (rawMaxAge) {
@@ -125,7 +120,6 @@ function loadSessionConfig() {
125
120
  return {
126
121
  applicationId,
127
122
  sessionSecret,
128
- platformApiUrl,
129
123
  sessionMaxAge
130
124
  };
131
125
  }
@@ -135,6 +129,39 @@ function sessionConfig() {
135
129
  return cached;
136
130
  }
137
131
 
132
+ //#endregion
133
+ //#region src/auth/platform.ts
134
+ const contextSchema = z.object({ platformApiUrl: z.string() });
135
+ /** Calls one of this app's user endpoints on the Softr platform. */
136
+ async function platformFetch(path, init) {
137
+ const { applicationId } = sessionConfig();
138
+ const origin = await platformApiUrl();
139
+ return fetch(`${origin}/v1/applications/${applicationId}/users/${path}`, init);
140
+ }
141
+ /** Origin of the Softr platform API, with no trailing slash. */
142
+ async function platformApiUrl() {
143
+ const pinned = process.env.SOFTR_PLATFORM_API_URL;
144
+ if (pinned) return withoutTrailingSlash(pinned);
145
+ const studioApiUrl = process.env.SOFTR_STUDIO_API_URL;
146
+ if (!studioApiUrl || process.env.NODE_ENV === "production") panic("Softr auth is not configured: SOFTR_PLATFORM_API_URL is not set.");
147
+ const { applicationId } = sessionConfig();
148
+ const url = `${withoutTrailingSlash(studioApiUrl)}/v1/api/applications/${applicationId}/context/public`;
149
+ let response;
150
+ try {
151
+ response = await fetch(url, { headers: { accept: "application/json" } });
152
+ } catch {
153
+ panic(`Could not reach studio-api: ${url}`);
154
+ }
155
+ if (response.status === 404) panic(`studio-api does not know application ${applicationId}`);
156
+ if (!response.ok) panic(`studio-api answered ${response.status} for ${url}`);
157
+ const body = contextSchema.safeParse(await response.json().catch(() => null));
158
+ if (!body.success) panic(`studio-api returned no platformApiUrl: ${url}`);
159
+ return withoutTrailingSlash(body.data.platformApiUrl);
160
+ }
161
+ function withoutTrailingSlash(url) {
162
+ return url.replace(/\/+$/, "");
163
+ }
164
+
138
165
  //#endregion
139
166
  //#region src/auth/me.ts
140
167
  /**
@@ -143,8 +170,7 @@ function sessionConfig() {
143
170
  * informative. Anything else that is not a 200 throws.
144
171
  */
145
172
  async function fetchVisitor(token) {
146
- const config = sessionConfig();
147
- const response = await fetch(`${config.platformApiUrl}/v1/applications/${config.applicationId}/users/me`, {
173
+ const response = await platformFetch("me", {
148
174
  method: "GET",
149
175
  headers: {
150
176
  authorization: `Bearer ${token}`,
@@ -331,4 +357,4 @@ function openEnvelope(raw, purpose) {
331
357
  }
332
358
 
333
359
  //#endregion
334
- export { readSessionToken as a, writeCookies as c, softAssert as d, todo as f, readSessionData as i, assert as l, makeSessionDataCookie as n, fetchVisitor as o, makeSessionTokenCookie as r, sessionConfig as s, clearSession as t, panic as u };
360
+ export { readSessionToken as a, writeCookies as c, softAssert as d, todo as f, readSessionData as i, assert as l, makeSessionDataCookie as n, fetchVisitor as o, makeSessionTokenCookie as r, platformFetch as s, clearSession as t, panic as u };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@softr/sdk",
3
- "version": "0.0.10",
3
+ "version": "0.0.11",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": { "types": "./dist/index.d.ts", "import": "./dist/index.js" },