@synap-core/sdk 1.2.0 → 1.3.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 +80 -0
- package/dist/chunk-J7XHAAFJ.js +79 -0
- package/dist/chunk-J7XHAAFJ.js.map +1 -0
- package/dist/{client-C5sF20f1.d.cts → client-CVUT1Mcf.d.cts} +1 -1
- package/dist/{client-C5sF20f1.d.ts → client-CVUT1Mcf.d.ts} +1 -1
- package/dist/connect.browser.cjs +22 -0
- package/dist/connect.browser.cjs.map +1 -0
- package/dist/connect.browser.d.cts +2 -0
- package/dist/connect.browser.d.ts +2 -0
- package/dist/connect.browser.js +5 -0
- package/dist/connect.browser.js.map +1 -0
- package/dist/connect.cjs +1206 -0
- package/dist/connect.cjs.map +1 -0
- package/dist/connect.d.cts +442 -0
- package/dist/connect.d.ts +442 -0
- package/dist/connect.js +1092 -0
- package/dist/connect.js.map +1 -0
- package/dist/public.d.cts +2 -2
- package/dist/public.d.ts +2 -2
- package/dist/testing.cjs +304 -19
- package/dist/testing.cjs.map +1 -1
- package/dist/testing.d.cts +73 -2
- package/dist/testing.d.ts +73 -2
- package/dist/testing.js +281 -19
- package/dist/testing.js.map +1 -1
- package/dist/types-DpqPNaaa.d.cts +76 -0
- package/dist/types-DpqPNaaa.d.ts +76 -0
- package/package.json +11 -3
- package/src/connect/auth.ts +405 -0
- package/src/connect/browser.ts +10 -0
- package/src/connect/client.ts +193 -0
- package/src/connect/discovery.ts +262 -0
- package/src/connect/encoding.ts +93 -0
- package/src/connect/errors.ts +115 -0
- package/src/connect/flow.ts +449 -0
- package/src/connect/guard.ts +25 -0
- package/src/connect/index.ts +59 -0
- package/src/connect/seal.ts +119 -0
- package/src/connect/store.ts +151 -0
- package/src/connect/types.ts +80 -0
- package/src/testing/auth-server.ts +380 -0
- package/src/testing/index.ts +5 -0
package/README.md
CHANGED
|
@@ -119,6 +119,86 @@ SDK refuses out-of-bounds `offset`/`limit`/`sort` locally, without a request),
|
|
|
119
119
|
pass `ifNoneMatch` from a browser: the doors allow no cross-origin request header
|
|
120
120
|
but `Content-Type`, so the preflight fails (browsers revalidate on their own).
|
|
121
121
|
|
|
122
|
+
## Pod-app sign-in (server-only): `@synap-core/sdk/connect` (1.3.0)
|
|
123
|
+
|
|
124
|
+
An app that reads and writes a person's OWN pod connects as an OAuth 2.1 public
|
|
125
|
+
client of that pod: its `client_id` is the https URL of its client metadata
|
|
126
|
+
document (CIMD), PKCE S256, every answer checked for the pod's `iss`. The pod
|
|
127
|
+
token stays on the app's server, sealed (AES-GCM) in an HttpOnly cookie; the
|
|
128
|
+
browser never sees it. Framework-free and Web-standard (`Request` → `Response`,
|
|
129
|
+
WebCrypto): Next route handlers and `proxy.ts`, Hono, Remix, edge runtimes.
|
|
130
|
+
**Server-only**: it throws when loaded in a browser, and a browser bundle
|
|
131
|
+
resolves it to a stub that throws.
|
|
132
|
+
|
|
133
|
+
```typescript
|
|
134
|
+
// lib/synap/pod-app/auth.ts (server-only)
|
|
135
|
+
import { createPodAppAuth } from "@synap-core/sdk/connect";
|
|
136
|
+
|
|
137
|
+
export const synap = createPodAppAuth({
|
|
138
|
+
appUrl: process.env.SITE_URL!, // https://studio.example.com
|
|
139
|
+
clientName: "Studio",
|
|
140
|
+
requests: [
|
|
141
|
+
{ permission: "entity.post.read", reason: "Show your posts" },
|
|
142
|
+
{ permission: "entity.post.create", reason: "Save drafts to your pod" },
|
|
143
|
+
],
|
|
144
|
+
secret: process.env.SYNAP_APP_SESSION_SECRET!, // ≥ 32 chars, never NEXT_PUBLIC_
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
// app/.well-known/synap-client.json/route.ts export const GET = synap.handlers.clientMetadata;
|
|
148
|
+
// app/api/synap/connect/route.ts export const POST = synap.handlers.connect; // form { pod, next?, space? }
|
|
149
|
+
// app/api/synap/callback/route.ts export const GET = synap.handlers.callback;
|
|
150
|
+
// app/api/synap/disconnect/route.ts export const POST = synap.handlers.disconnect; // form { next? }
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
```typescript
|
|
154
|
+
// proxy.ts: refresh before render (server components cannot set cookies)
|
|
155
|
+
const out = await synap.refreshIfNeeded(request);
|
|
156
|
+
// out.status: none | skipped | fresh | refreshed | kept | expired | revoked | unavailable
|
|
157
|
+
// send out.setCookies on the response; forward out.cookieHeader (when set) as the request's Cookie
|
|
158
|
+
|
|
159
|
+
// a server component / action (no Request there: pass the Cookie header)
|
|
160
|
+
const connection = await synap.readConnection((await headers()).get("cookie"));
|
|
161
|
+
const pod = synap.client(connection!);
|
|
162
|
+
const res = await pod.post("/entities", { profileSlug: "post", title: "Hello" });
|
|
163
|
+
if (res.ok && res.status === "proposed") showPending(res.reviewUrl); // success: queued for review, never retry
|
|
164
|
+
if (!res.ok) res.error.code; // expired | unauthorized | forbidden | door_unsupported | rate_limited (retryAfterSec) | pod_unreachable | …
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
- **Discovery**: `discoverPod("pod.example.com")` fetches the pod's RFC 8414
|
|
168
|
+
metadata and requires `issuer` equal to the address, CIMD, `iss` on answers and
|
|
169
|
+
S256 (`not_a_pod`, `pod_unsupported`, `pod_unreachable`). A browser launch
|
|
170
|
+
(`?iss=…&target_link_uri=…`) is read with `acceptLaunch` and only pre-fills the
|
|
171
|
+
connect page. Synap Cloud discovery is not available yet:
|
|
172
|
+
`cloudConnectAvailable()` is `false`.
|
|
173
|
+
- **Failures** redirect with `?error=<ConnectErrorCode>`: `denied`,
|
|
174
|
+
`expired_transaction`, `mismatch`, `misconfigured`, `rate_limited`,
|
|
175
|
+
`pod_unreachable`, … (`parseConnectErrorCode` reads it back). `connect` and
|
|
176
|
+
`disconnect` are POST and same-origin only.
|
|
177
|
+
- **Refresh** (rotating, single-use, 30 days from issue) is feature-detected: a
|
|
178
|
+
pod that issues no `refresh_token` gives a connection that ends with its
|
|
179
|
+
1-hour access token. `refreshIfNeeded` rotates only inside the last 5
|
|
180
|
+
minutes, is single-flight per connection in the process, and persists the
|
|
181
|
+
rotated connection BEFORE returning it. The pod revokes the whole connection
|
|
182
|
+
when a spent refresh token is presented again, so for 2 minutes a request
|
|
183
|
+
still carrying the spent token (a parallel request, a second tab) gets the
|
|
184
|
+
rotation's result instead of reaching the pod. Across server instances only
|
|
185
|
+
a shared server-side `ConnectionStore` rules that replay out. A concurrent
|
|
186
|
+
loser (refused softly by the pod) keeps the still-valid access token.
|
|
187
|
+
- **Your own store**: implement `ConnectionStore` (`read`, `write`, `clear`,
|
|
188
|
+
returning Set-Cookie values) and pass it as `store`.
|
|
189
|
+
- Lower level: `startConnect`, `handleCallback`, `refreshConnection`,
|
|
190
|
+
`revokeConnection`, `buildClientMetadata`, `seal`/`unseal`.
|
|
191
|
+
|
|
192
|
+
Test without a pod: `createMockAuthServer()` from `@synap-core/sdk/testing`
|
|
193
|
+
(metadata, `authorize()` as the consent screen, `/token` with PKCE, rotating
|
|
194
|
+
refresh, `/revoke`, Hub REST doors; `writeMode`, `failures`, `refresh: false`):
|
|
195
|
+
|
|
196
|
+
```typescript
|
|
197
|
+
const pod = createMockAuthServer();
|
|
198
|
+
const synap = createPodAppAuth({ ...config, fetch: pod.fetch });
|
|
199
|
+
// POST connect → Location → pod.authorize(location) → GET callback with that URL
|
|
200
|
+
```
|
|
201
|
+
|
|
122
202
|
## Mock pod: `@synap-core/sdk/testing`
|
|
123
203
|
|
|
124
204
|
A fake `fetch` that answers the public doors (forms, shares, sites) from fixtures,
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
// src/connect/encoding.ts
|
|
2
|
+
var encoder = new TextEncoder();
|
|
3
|
+
var decoder = new TextDecoder();
|
|
4
|
+
function utf8(text) {
|
|
5
|
+
return encoder.encode(text);
|
|
6
|
+
}
|
|
7
|
+
function fromUtf8(bytes) {
|
|
8
|
+
return decoder.decode(bytes);
|
|
9
|
+
}
|
|
10
|
+
function base64url(bytes) {
|
|
11
|
+
let binary = "";
|
|
12
|
+
for (let i = 0; i < bytes.length; i++) binary += String.fromCharCode(bytes[i]);
|
|
13
|
+
return btoa(binary).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
|
|
14
|
+
}
|
|
15
|
+
function fromBase64url(text) {
|
|
16
|
+
if (!/^[A-Za-z0-9_-]*$/.test(text)) return null;
|
|
17
|
+
const padded = text.replace(/-/g, "+").replace(/_/g, "/") + "===".slice((text.length + 3) % 4);
|
|
18
|
+
let binary;
|
|
19
|
+
try {
|
|
20
|
+
binary = atob(padded);
|
|
21
|
+
} catch {
|
|
22
|
+
return null;
|
|
23
|
+
}
|
|
24
|
+
const out = new Uint8Array(binary.length);
|
|
25
|
+
for (let i = 0; i < binary.length; i++) out[i] = binary.charCodeAt(i);
|
|
26
|
+
return out;
|
|
27
|
+
}
|
|
28
|
+
function randomBytes(length) {
|
|
29
|
+
const out = new Uint8Array(length);
|
|
30
|
+
crypto.getRandomValues(out);
|
|
31
|
+
return out;
|
|
32
|
+
}
|
|
33
|
+
function randomToken() {
|
|
34
|
+
return base64url(randomBytes(32));
|
|
35
|
+
}
|
|
36
|
+
async function pkceChallenge(verifier) {
|
|
37
|
+
const digest = await crypto.subtle.digest("SHA-256", utf8(verifier));
|
|
38
|
+
return base64url(new Uint8Array(digest));
|
|
39
|
+
}
|
|
40
|
+
function constantTimeEqual(a, b) {
|
|
41
|
+
const x = utf8(a);
|
|
42
|
+
const y = utf8(b);
|
|
43
|
+
let diff = x.length ^ y.length;
|
|
44
|
+
for (let i = 0; i < Math.max(x.length, y.length); i++) diff |= (x[i] ?? 0) ^ (y[i] ?? 0);
|
|
45
|
+
return diff === 0;
|
|
46
|
+
}
|
|
47
|
+
function parseCookies(header) {
|
|
48
|
+
const out = /* @__PURE__ */ new Map();
|
|
49
|
+
if (!header) return out;
|
|
50
|
+
for (const part of header.split(";")) {
|
|
51
|
+
const eq = part.indexOf("=");
|
|
52
|
+
if (eq < 0) continue;
|
|
53
|
+
const name = part.slice(0, eq).trim();
|
|
54
|
+
if (!name || out.has(name)) continue;
|
|
55
|
+
let value = part.slice(eq + 1).trim();
|
|
56
|
+
if (value.startsWith('"') && value.endsWith('"')) value = value.slice(1, -1);
|
|
57
|
+
out.set(name, value);
|
|
58
|
+
}
|
|
59
|
+
return out;
|
|
60
|
+
}
|
|
61
|
+
function serializeCookie(name, value, attrs) {
|
|
62
|
+
const parts = [`${name}=${value}`, "Path=/", "HttpOnly", "SameSite=Lax", `Max-Age=${Math.max(0, Math.floor(attrs.maxAgeSec))}`];
|
|
63
|
+
if (attrs.secure) parts.push("Secure");
|
|
64
|
+
return parts.join("; ");
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export {
|
|
68
|
+
utf8,
|
|
69
|
+
fromUtf8,
|
|
70
|
+
base64url,
|
|
71
|
+
fromBase64url,
|
|
72
|
+
randomBytes,
|
|
73
|
+
randomToken,
|
|
74
|
+
pkceChallenge,
|
|
75
|
+
constantTimeEqual,
|
|
76
|
+
parseCookies,
|
|
77
|
+
serializeCookie
|
|
78
|
+
};
|
|
79
|
+
//# sourceMappingURL=chunk-J7XHAAFJ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/connect/encoding.ts"],"sourcesContent":["/**\n * Web-standard primitives (WebCrypto, TextEncoder, btoa/atob): the same code\n * runs on Node 18+, edge runtimes and workers. No Node import.\n */\n\nconst encoder = new TextEncoder();\nconst decoder = new TextDecoder();\n\n/** `Uint8Array<ArrayBuffer>`: what WebCrypto's `BufferSource` takes under TS 5.7+ lib types. */\nexport type Bytes = Uint8Array<ArrayBuffer>;\n\nexport function utf8(text: string): Bytes {\n return encoder.encode(text);\n}\n\nexport function fromUtf8(bytes: Uint8Array): string {\n return decoder.decode(bytes);\n}\n\nexport function base64url(bytes: Uint8Array): string {\n let binary = \"\";\n for (let i = 0; i < bytes.length; i++) binary += String.fromCharCode(bytes[i]);\n return btoa(binary).replace(/\\+/g, \"-\").replace(/\\//g, \"_\").replace(/=+$/, \"\");\n}\n\n/** Null when `text` is not base64url. */\nexport function fromBase64url(text: string): Bytes | null {\n if (!/^[A-Za-z0-9_-]*$/.test(text)) return null;\n const padded = text.replace(/-/g, \"+\").replace(/_/g, \"/\") + \"===\".slice((text.length + 3) % 4);\n let binary: string;\n try {\n binary = atob(padded);\n } catch {\n return null;\n }\n const out = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i++) out[i] = binary.charCodeAt(i);\n return out;\n}\n\nexport function randomBytes(length: number): Bytes {\n const out = new Uint8Array(length);\n crypto.getRandomValues(out);\n return out;\n}\n\n/** 32 random bytes, base64url (43 chars): a state value or a PKCE verifier. */\nexport function randomToken(): string {\n return base64url(randomBytes(32));\n}\n\n/** RFC 7636 §4.2: `BASE64URL(SHA256(ASCII(code_verifier)))`. */\nexport async function pkceChallenge(verifier: string): Promise<string> {\n const digest = await crypto.subtle.digest(\"SHA-256\", utf8(verifier));\n return base64url(new Uint8Array(digest));\n}\n\n/** Compare two strings without an early exit on the first differing byte. */\nexport function constantTimeEqual(a: string, b: string): boolean {\n const x = utf8(a);\n const y = utf8(b);\n let diff = x.length ^ y.length;\n for (let i = 0; i < Math.max(x.length, y.length); i++) diff |= (x[i] ?? 0) ^ (y[i] ?? 0);\n return diff === 0;\n}\n\n/** The request's cookies by name (the first value wins, as browsers order the most specific first). */\nexport function parseCookies(header: string | null): Map<string, string> {\n const out = new Map<string, string>();\n if (!header) return out;\n for (const part of header.split(\";\")) {\n const eq = part.indexOf(\"=\");\n if (eq < 0) continue;\n const name = part.slice(0, eq).trim();\n if (!name || out.has(name)) continue;\n let value = part.slice(eq + 1).trim();\n if (value.startsWith('\"') && value.endsWith('\"')) value = value.slice(1, -1);\n out.set(name, value);\n }\n return out;\n}\n\nexport interface CookieAttributes {\n maxAgeSec: number;\n secure: boolean;\n}\n\n/** `HttpOnly; SameSite=Lax; Path=/` always; `Secure` on https. Never a `Domain`. */\nexport function serializeCookie(name: string, value: string, attrs: CookieAttributes): string {\n const parts = [`${name}=${value}`, \"Path=/\", \"HttpOnly\", \"SameSite=Lax\", `Max-Age=${Math.max(0, Math.floor(attrs.maxAgeSec))}`];\n if (attrs.secure) parts.push(\"Secure\");\n return parts.join(\"; \");\n}\n"],"mappings":";AAKA,IAAM,UAAU,IAAI,YAAY;AAChC,IAAM,UAAU,IAAI,YAAY;AAKzB,SAAS,KAAK,MAAqB;AACxC,SAAO,QAAQ,OAAO,IAAI;AAC5B;AAEO,SAAS,SAAS,OAA2B;AAClD,SAAO,QAAQ,OAAO,KAAK;AAC7B;AAEO,SAAS,UAAU,OAA2B;AACnD,MAAI,SAAS;AACb,WAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,IAAK,WAAU,OAAO,aAAa,MAAM,CAAC,CAAC;AAC7E,SAAO,KAAK,MAAM,EAAE,QAAQ,OAAO,GAAG,EAAE,QAAQ,OAAO,GAAG,EAAE,QAAQ,OAAO,EAAE;AAC/E;AAGO,SAAS,cAAc,MAA4B;AACxD,MAAI,CAAC,mBAAmB,KAAK,IAAI,EAAG,QAAO;AAC3C,QAAM,SAAS,KAAK,QAAQ,MAAM,GAAG,EAAE,QAAQ,MAAM,GAAG,IAAI,MAAM,OAAO,KAAK,SAAS,KAAK,CAAC;AAC7F,MAAI;AACJ,MAAI;AACF,aAAS,KAAK,MAAM;AAAA,EACtB,QAAQ;AACN,WAAO;AAAA,EACT;AACA,QAAM,MAAM,IAAI,WAAW,OAAO,MAAM;AACxC,WAAS,IAAI,GAAG,IAAI,OAAO,QAAQ,IAAK,KAAI,CAAC,IAAI,OAAO,WAAW,CAAC;AACpE,SAAO;AACT;AAEO,SAAS,YAAY,QAAuB;AACjD,QAAM,MAAM,IAAI,WAAW,MAAM;AACjC,SAAO,gBAAgB,GAAG;AAC1B,SAAO;AACT;AAGO,SAAS,cAAsB;AACpC,SAAO,UAAU,YAAY,EAAE,CAAC;AAClC;AAGA,eAAsB,cAAc,UAAmC;AACrE,QAAM,SAAS,MAAM,OAAO,OAAO,OAAO,WAAW,KAAK,QAAQ,CAAC;AACnE,SAAO,UAAU,IAAI,WAAW,MAAM,CAAC;AACzC;AAGO,SAAS,kBAAkB,GAAW,GAAoB;AAC/D,QAAM,IAAI,KAAK,CAAC;AAChB,QAAM,IAAI,KAAK,CAAC;AAChB,MAAI,OAAO,EAAE,SAAS,EAAE;AACxB,WAAS,IAAI,GAAG,IAAI,KAAK,IAAI,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAK,UAAS,EAAE,CAAC,KAAK,MAAM,EAAE,CAAC,KAAK;AACtF,SAAO,SAAS;AAClB;AAGO,SAAS,aAAa,QAA4C;AACvE,QAAM,MAAM,oBAAI,IAAoB;AACpC,MAAI,CAAC,OAAQ,QAAO;AACpB,aAAW,QAAQ,OAAO,MAAM,GAAG,GAAG;AACpC,UAAM,KAAK,KAAK,QAAQ,GAAG;AAC3B,QAAI,KAAK,EAAG;AACZ,UAAM,OAAO,KAAK,MAAM,GAAG,EAAE,EAAE,KAAK;AACpC,QAAI,CAAC,QAAQ,IAAI,IAAI,IAAI,EAAG;AAC5B,QAAI,QAAQ,KAAK,MAAM,KAAK,CAAC,EAAE,KAAK;AACpC,QAAI,MAAM,WAAW,GAAG,KAAK,MAAM,SAAS,GAAG,EAAG,SAAQ,MAAM,MAAM,GAAG,EAAE;AAC3E,QAAI,IAAI,MAAM,KAAK;AAAA,EACrB;AACA,SAAO;AACT;AAQO,SAAS,gBAAgB,MAAc,OAAe,OAAiC;AAC5F,QAAM,QAAQ,CAAC,GAAG,IAAI,IAAI,KAAK,IAAI,UAAU,YAAY,gBAAgB,WAAW,KAAK,IAAI,GAAG,KAAK,MAAM,MAAM,SAAS,CAAC,CAAC,EAAE;AAC9H,MAAI,MAAM,OAAQ,OAAM,KAAK,QAAQ;AACrC,SAAO,MAAM,KAAK,IAAI;AACxB;","names":[]}
|
|
@@ -250,4 +250,4 @@ interface PublicClient {
|
|
|
250
250
|
}
|
|
251
251
|
declare function createPublicClient(opts: PublicClientOptions): PublicClient;
|
|
252
252
|
|
|
253
|
-
export { type CollectionQuery as C, type PublicForm as P, type Revalidate as R, type SubmitResult as S, type
|
|
253
|
+
export { type CollectionQuery as C, type PublicForm as P, type Revalidate as R, type SubmitResult as S, type PublicShare as a, type PublicRecord as b, type PublicReadError as c, type PublicRecordSummary as d, type PublicValue as e, type PublicCollectionPage as f, type PublicResult as g, type PublicClient as h, type PublicClientOptions as i, type PublicFailure as j, type PublicFormField as k, type PublicFormFieldType as l, type PublicNotModified as m, type PublicSite as n, type PublicSiteCollection as o, type PublicSiteError as p, type PublicSiteResult as q, type PublicSubmitError as r, SITE_MAX_LIMIT as s, SITE_MAX_OFFSET as t, SITE_MAX_SORT_KEYS as u, SITE_PUBLISHED_AT_SORT as v, type SubmitFormInput as w, createPublicClient as x };
|
|
@@ -250,4 +250,4 @@ interface PublicClient {
|
|
|
250
250
|
}
|
|
251
251
|
declare function createPublicClient(opts: PublicClientOptions): PublicClient;
|
|
252
252
|
|
|
253
|
-
export { type CollectionQuery as C, type PublicForm as P, type Revalidate as R, type SubmitResult as S, type
|
|
253
|
+
export { type CollectionQuery as C, type PublicForm as P, type Revalidate as R, type SubmitResult as S, type PublicShare as a, type PublicRecord as b, type PublicReadError as c, type PublicRecordSummary as d, type PublicValue as e, type PublicCollectionPage as f, type PublicResult as g, type PublicClient as h, type PublicClientOptions as i, type PublicFailure as j, type PublicFormField as k, type PublicFormFieldType as l, type PublicNotModified as m, type PublicSite as n, type PublicSiteCollection as o, type PublicSiteError as p, type PublicSiteResult as q, type PublicSubmitError as r, SITE_MAX_LIMIT as s, SITE_MAX_OFFSET as t, SITE_MAX_SORT_KEYS as u, SITE_PUBLISHED_AT_SORT as v, type SubmitFormInput as w, createPublicClient as x };
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __copyProps = (to, from, except, desc) => {
|
|
7
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
8
|
+
for (let key of __getOwnPropNames(from))
|
|
9
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
10
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
11
|
+
}
|
|
12
|
+
return to;
|
|
13
|
+
};
|
|
14
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
15
|
+
|
|
16
|
+
// src/connect/browser.ts
|
|
17
|
+
var browser_exports = {};
|
|
18
|
+
module.exports = __toCommonJS(browser_exports);
|
|
19
|
+
throw new Error(
|
|
20
|
+
"@synap-core/sdk/connect is server-only: it holds the pod's tokens and the app secret. Import it from route handlers, proxy.ts or server code, never from a client component."
|
|
21
|
+
);
|
|
22
|
+
//# sourceMappingURL=connect.browser.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/connect/browser.ts"],"sourcesContent":["/**\n * What a BROWSER bundle gets for `@synap-core/sdk/connect` (the `browser`\n * export condition): no exports, and a throw on load. See ./guard.ts.\n */\nthrow new Error(\n \"@synap-core/sdk/connect is server-only: it holds the pod's tokens and the app secret. \" +\n \"Import it from route handlers, proxy.ts or server code, never from a client component.\",\n);\n\nexport {};\n"],"mappings":";;;;;;;;;;;;;;;;AAAA;AAAA;AAIA,MAAM,IAAI;AAAA,EACR;AAEF;","names":[]}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
// src/connect/browser.ts
|
|
2
|
+
throw new Error(
|
|
3
|
+
"@synap-core/sdk/connect is server-only: it holds the pod's tokens and the app secret. Import it from route handlers, proxy.ts or server code, never from a client component."
|
|
4
|
+
);
|
|
5
|
+
//# sourceMappingURL=connect.browser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/connect/browser.ts"],"sourcesContent":["/**\n * What a BROWSER bundle gets for `@synap-core/sdk/connect` (the `browser`\n * export condition): no exports, and a throw on load. See ./guard.ts.\n */\nthrow new Error(\n \"@synap-core/sdk/connect is server-only: it holds the pod's tokens and the app secret. \" +\n \"Import it from route handlers, proxy.ts or server code, never from a client component.\",\n);\n\nexport {};\n"],"mappings":";AAIA,MAAM,IAAI;AAAA,EACR;AAEF;","names":[]}
|