@gaballahtech/seba 0.2.1 → 0.5.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.
Files changed (76) hide show
  1. package/ARCHITECTURE.md +4 -2
  2. package/CHANGELOG.md +130 -0
  3. package/MIGRATION.md +60 -0
  4. package/README.md +174 -8
  5. package/SECURITY.md +1 -1
  6. package/assets/seba-icon-favicon.png +0 -0
  7. package/assets/seba-icon-solid.png +0 -0
  8. package/assets/seba-logo-inverse.png +0 -0
  9. package/assets/seba-logo-monochrome.png +0 -0
  10. package/assets/seba-logo-primary.png +0 -0
  11. package/dist/assets/icons.d.ts +32 -0
  12. package/dist/assets/icons.d.ts.map +1 -0
  13. package/dist/assets/icons.js +30 -0
  14. package/dist/assets/icons.js.map +1 -0
  15. package/dist/assets/png-data.d.ts +8 -0
  16. package/dist/assets/png-data.d.ts.map +1 -0
  17. package/dist/assets/png-data.js +13 -0
  18. package/dist/assets/png-data.js.map +1 -0
  19. package/dist/browser/platform.d.ts +6 -0
  20. package/dist/browser/platform.d.ts.map +1 -1
  21. package/dist/browser/platform.js +17 -0
  22. package/dist/browser/platform.js.map +1 -1
  23. package/dist/browser/storage.d.ts +3 -2
  24. package/dist/browser/storage.d.ts.map +1 -1
  25. package/dist/browser/storage.js +26 -14
  26. package/dist/browser/storage.js.map +1 -1
  27. package/dist/cli.d.ts +61 -0
  28. package/dist/cli.d.ts.map +1 -0
  29. package/dist/cli.js +223 -0
  30. package/dist/cli.js.map +1 -0
  31. package/dist/core/client.d.ts +18 -8
  32. package/dist/core/client.d.ts.map +1 -1
  33. package/dist/core/client.js +130 -6
  34. package/dist/core/client.js.map +1 -1
  35. package/dist/core/errors.d.ts +10 -1
  36. package/dist/core/errors.d.ts.map +1 -1
  37. package/dist/core/errors.js +7 -2
  38. package/dist/core/errors.js.map +1 -1
  39. package/dist/core/events.d.ts +27 -0
  40. package/dist/core/events.d.ts.map +1 -0
  41. package/dist/core/events.js +45 -0
  42. package/dist/core/events.js.map +1 -0
  43. package/dist/core/http.d.ts.map +1 -1
  44. package/dist/core/http.js +6 -1
  45. package/dist/core/http.js.map +1 -1
  46. package/dist/core/oidc.d.ts +17 -7
  47. package/dist/core/oidc.d.ts.map +1 -1
  48. package/dist/core/oidc.js +76 -27
  49. package/dist/core/oidc.js.map +1 -1
  50. package/dist/core/session.d.ts +10 -3
  51. package/dist/core/session.d.ts.map +1 -1
  52. package/dist/core/session.js +131 -20
  53. package/dist/core/session.js.map +1 -1
  54. package/dist/element.d.ts +43 -0
  55. package/dist/element.d.ts.map +1 -0
  56. package/dist/element.js +416 -0
  57. package/dist/element.js.map +1 -0
  58. package/dist/index.d.ts +6 -1
  59. package/dist/index.d.ts.map +1 -1
  60. package/dist/index.js +3 -0
  61. package/dist/index.js.map +1 -1
  62. package/dist/pod.d.ts +50 -0
  63. package/dist/pod.d.ts.map +1 -0
  64. package/dist/pod.js +264 -0
  65. package/dist/pod.js.map +1 -0
  66. package/dist/react/index.d.ts +52 -0
  67. package/dist/react/index.d.ts.map +1 -0
  68. package/dist/react/index.js +87 -0
  69. package/dist/react/index.js.map +1 -0
  70. package/dist/seba.d.ts +40 -1
  71. package/dist/seba.d.ts.map +1 -1
  72. package/dist/seba.js +90 -2
  73. package/dist/seba.js.map +1 -1
  74. package/dist/types.d.ts +140 -6
  75. package/dist/types.d.ts.map +1 -1
  76. package/package.json +27 -1
package/dist/pod.js ADDED
@@ -0,0 +1,264 @@
1
+ /**
2
+ * Tiny, dependency-free helpers for the Turtle subset used by Solid pods.
3
+ *
4
+ * Supported syntax: `.`-terminated triples with `<iri>`, `_:blank`, and literal
5
+ * terms (`"value"`, `"value"@lang`, `"value"^^<datatype>`), plus bare integers,
6
+ * decimals and booleans. `@prefix`/`PREFIX`/`BASE` lines are ignored; prefix
7
+ * expansion is not performed, so terms must already be absolute.
8
+ */
9
+ const XSD = "http://www.w3.org/2001/XMLSchema#";
10
+ /**
11
+ * Parse a small Turtle document into triples.
12
+ *
13
+ * @throws Error when a statement does not contain exactly three supported terms.
14
+ */
15
+ export function parseSubjectTriples(input) {
16
+ const tokens = tokenize(input);
17
+ const triples = [];
18
+ let statement = [];
19
+ for (const token of tokens) {
20
+ if (token === ".") {
21
+ if (statement.length === 0) {
22
+ continue;
23
+ }
24
+ if (statement.length !== 3) {
25
+ throw new Error(`Unsupported Turtle statement: expected 3 terms, found ${String(statement.length)}.`);
26
+ }
27
+ triples.push({
28
+ subject: parseTerm(statement[0]),
29
+ predicate: parseTerm(statement[1]),
30
+ object: parseTerm(statement[2]),
31
+ });
32
+ statement = [];
33
+ continue;
34
+ }
35
+ statement.push(token);
36
+ }
37
+ if (statement.length > 0) {
38
+ throw new Error("Unsupported Turtle: the final statement is not terminated by '.'.");
39
+ }
40
+ return triples;
41
+ }
42
+ /** Turn triples into a nested `{ [subject]: { [predicate]: value } }` object. */
43
+ export function objectify(triples) {
44
+ const document = {};
45
+ for (const { subject, predicate, object } of triples) {
46
+ const bucket = (document[subject.value] ??= {});
47
+ const value = toValue(object);
48
+ const existing = bucket[predicate.value];
49
+ if (existing === undefined) {
50
+ bucket[predicate.value] = value;
51
+ }
52
+ else if (Array.isArray(existing)) {
53
+ existing.push(value);
54
+ }
55
+ else {
56
+ bucket[predicate.value] = [existing, value];
57
+ }
58
+ }
59
+ return document;
60
+ }
61
+ /** Serialize triples to Turtle, one statement per line. */
62
+ export function toTurtle(triples) {
63
+ return triples
64
+ .map(({ subject, predicate, object }) => `${formatTerm(subject)} ${formatTerm(predicate)} ${formatTerm(object)} .`)
65
+ .join("\n");
66
+ }
67
+ /** The three helpers, also exposed as `Seba.pod`. */
68
+ export const pod = { parseSubjectTriples, objectify, toTurtle };
69
+ function tokenize(input) {
70
+ const tokens = [];
71
+ let index = 0;
72
+ while (index < input.length) {
73
+ const character = input[index];
74
+ if (/\s/.test(character)) {
75
+ index += 1;
76
+ continue;
77
+ }
78
+ if (character === "#") {
79
+ while (index < input.length && input[index] !== "\n") {
80
+ index += 1;
81
+ }
82
+ continue;
83
+ }
84
+ if (isDirectiveStart(input, index)) {
85
+ while (index < input.length && input[index] !== "\n") {
86
+ index += 1;
87
+ }
88
+ continue;
89
+ }
90
+ if (character === "<") {
91
+ const end = input.indexOf(">", index);
92
+ if (end < 0) {
93
+ throw new Error("Unsupported Turtle: unterminated IRI.");
94
+ }
95
+ tokens.push(input.slice(index, end + 1));
96
+ index = end + 1;
97
+ continue;
98
+ }
99
+ if (character === '"') {
100
+ let cursor = index + 1;
101
+ let token = '"';
102
+ while (cursor < input.length) {
103
+ const current = input[cursor];
104
+ token += current;
105
+ cursor += 1;
106
+ if (current === "\\") {
107
+ token += input[cursor] ?? "";
108
+ cursor += 1;
109
+ continue;
110
+ }
111
+ if (current === '"') {
112
+ break;
113
+ }
114
+ }
115
+ while (cursor < input.length) {
116
+ if (input[cursor] === "@") {
117
+ let end = cursor + 1;
118
+ while (end < input.length && /[A-Za-z0-9-]/.test(input[end])) {
119
+ end += 1;
120
+ }
121
+ token += input.slice(cursor, end);
122
+ cursor = end;
123
+ continue;
124
+ }
125
+ if (input.startsWith("^^", cursor)) {
126
+ const iriStart = input.indexOf("<", cursor);
127
+ const iriEnd = iriStart < 0 ? -1 : input.indexOf(">", iriStart);
128
+ if (iriStart < 0 || iriEnd < 0) {
129
+ throw new Error("Unsupported Turtle: malformed datatype suffix.");
130
+ }
131
+ token += input.slice(cursor, iriEnd + 1);
132
+ cursor = iriEnd + 1;
133
+ continue;
134
+ }
135
+ break;
136
+ }
137
+ tokens.push(token);
138
+ index = cursor;
139
+ continue;
140
+ }
141
+ if (character === "." && isStatementEnd(input, index)) {
142
+ tokens.push(".");
143
+ index += 1;
144
+ continue;
145
+ }
146
+ let end = index;
147
+ while (end < input.length && !/[\s]/.test(input[end])) {
148
+ if (input[end] === "." && isStatementEnd(input, end)) {
149
+ break;
150
+ }
151
+ end += 1;
152
+ }
153
+ tokens.push(input.slice(index, end));
154
+ index = end;
155
+ }
156
+ return tokens;
157
+ }
158
+ function isStatementEnd(input, index) {
159
+ const next = input[index + 1];
160
+ return next === undefined || /\s/.test(next);
161
+ }
162
+ function isDirectiveStart(input, index) {
163
+ const lineStart = /(?:^|\n)[ \t]*$/.test(input.slice(0, index));
164
+ if (!lineStart) {
165
+ return false;
166
+ }
167
+ return /^(@prefix|@base|PREFIX\b|BASE\b)/i.test(input.slice(index));
168
+ }
169
+ function parseTerm(token) {
170
+ if (token.startsWith("<") && token.endsWith(">")) {
171
+ return { termType: "NamedNode", value: token.slice(1, -1) };
172
+ }
173
+ if (token.startsWith("_:")) {
174
+ return { termType: "BlankNode", value: token.slice(2) };
175
+ }
176
+ if (token.startsWith('"')) {
177
+ const end = closingQuoteIndex(token);
178
+ const literal = { termType: "Literal", value: unescapeLiteral(token.slice(1, end)) };
179
+ const suffix = token.slice(end + 1);
180
+ if (suffix.startsWith("@")) {
181
+ literal.language = suffix.slice(1);
182
+ }
183
+ else if (suffix.startsWith("^^")) {
184
+ const datatype = suffix.slice(2);
185
+ literal.datatype = datatype.startsWith("<") ? datatype.slice(1, -1) : datatype;
186
+ }
187
+ return literal;
188
+ }
189
+ if (token === "true" || token === "false") {
190
+ return { termType: "Literal", value: token, datatype: `${XSD}boolean` };
191
+ }
192
+ if (/^[+-]?\d+$/.test(token)) {
193
+ return { termType: "Literal", value: token, datatype: `${XSD}integer` };
194
+ }
195
+ if (/^[+-]?(?:\d+\.\d*|\.\d+)$/.test(token)) {
196
+ return { termType: "Literal", value: token, datatype: `${XSD}decimal` };
197
+ }
198
+ throw new Error(`Unsupported Turtle term: ${token}`);
199
+ }
200
+ function closingQuoteIndex(token) {
201
+ for (let index = 1; index < token.length; index += 1) {
202
+ if (token[index] === "\\") {
203
+ index += 1;
204
+ continue;
205
+ }
206
+ if (token[index] === '"') {
207
+ return index;
208
+ }
209
+ }
210
+ throw new Error("Unsupported Turtle: unterminated literal.");
211
+ }
212
+ function unescapeLiteral(value) {
213
+ return value
214
+ .replace(/\\n/g, "\n")
215
+ .replace(/\\r/g, "\r")
216
+ .replace(/\\t/g, "\t")
217
+ .replace(/\\"/g, '"')
218
+ .replace(/\\\\/g, "\\");
219
+ }
220
+ function toValue(term) {
221
+ if (term.termType !== "Literal") {
222
+ return { id: term.value };
223
+ }
224
+ switch (term.datatype) {
225
+ case `${XSD}boolean`:
226
+ return term.value === "true";
227
+ case `${XSD}integer`:
228
+ case `${XSD}decimal`:
229
+ case `${XSD}double`: {
230
+ const numeric = Number(term.value);
231
+ return Number.isFinite(numeric) ? numeric : term.value;
232
+ }
233
+ default:
234
+ return term.value;
235
+ }
236
+ }
237
+ function formatTerm(term) {
238
+ if (term.termType === "NamedNode") {
239
+ return `<${term.value}>`;
240
+ }
241
+ if (term.termType === "BlankNode") {
242
+ return `_:${term.value.replace(/^_:/, "")}`;
243
+ }
244
+ if (term.datatype === `${XSD}integer` ||
245
+ term.datatype === `${XSD}decimal` ||
246
+ term.datatype === `${XSD}double` ||
247
+ term.datatype === `${XSD}boolean`) {
248
+ return term.value;
249
+ }
250
+ const escaped = term.value
251
+ .replace(/\\/g, "\\\\")
252
+ .replace(/"/g, '\\"')
253
+ .replace(/\n/g, "\\n")
254
+ .replace(/\r/g, "\\r")
255
+ .replace(/\t/g, "\\t");
256
+ if (term.language !== undefined) {
257
+ return `"${escaped}"@${term.language}`;
258
+ }
259
+ if (term.datatype !== undefined) {
260
+ return `"${escaped}"^^<${term.datatype}>`;
261
+ }
262
+ return `"${escaped}"`;
263
+ }
264
+ //# sourceMappingURL=pod.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pod.js","sourceRoot":"","sources":["../src/pod.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,52 @@
1
+ /**
2
+ * React bindings (`@gaballahtech/seba/react`).
3
+ *
4
+ * `react` is an optional peer dependency: the core entry point never imports this file.
5
+ * The wrapper registers `<seba-login>` on mount, so no separate setup call is needed.
6
+ */
7
+ import type { ReactElement } from "react";
8
+ import type { SebaConfig, Session } from "../types.js";
9
+ import type { Seba } from "../seba.js";
10
+ /** Props accepted by {@link SebaLoginButton}. */
11
+ export interface SebaLoginButtonProps {
12
+ /** Published Solid Client ID Document URL. */
13
+ clientId: string;
14
+ /** Redirect URI registered in the Client ID Document. Defaults to the current page URL. */
15
+ redirectUri?: string;
16
+ /** Identity provider issuer, used instead of WebID discovery. */
17
+ issuer?: string;
18
+ /** WebID whose profile lists the provider. */
19
+ webId?: string;
20
+ /** Button text while signed out. */
21
+ label?: string;
22
+ /** Colour scheme. Defaults to the system preference. */
23
+ theme?: "auto" | "light" | "dark";
24
+ /** Logo treatment, or `"none"`. Defaults to the theme's treatment. */
25
+ logo?: "primary" | "inverse" | "monochrome" | "solid" | "favicon" | "none";
26
+ /** Multi-account storage namespace. */
27
+ account?: string;
28
+ /** Advanced configuration (e.g. per-provider `tolerances`), serialized into the element. */
29
+ config?: Partial<Omit<SebaConfig, "clientId" | "redirectUri">>;
30
+ /** Identity providers offered in a picker; at least two are needed to show it. */
31
+ providers?: string[];
32
+ /** Extra class name for the host element. */
33
+ className?: string;
34
+ /** Called after a successful login or restore. */
35
+ onLogin?: (session: Session) => void;
36
+ /** Called after logout. */
37
+ onLogout?: () => void;
38
+ /** Called when the session expires. */
39
+ onSessionExpired?: () => void;
40
+ /** Called with any login, logout or configuration error. */
41
+ onError?: (error: unknown) => void;
42
+ }
43
+ /** A Solid sign-in button backed by `<seba-login>`. */
44
+ export declare function SebaLoginButton(props: SebaLoginButtonProps): ReactElement;
45
+ /**
46
+ * Track the session of a {@link Seba} instance.
47
+ *
48
+ * @returns The current session, or `null` while signed out. Updates on login,
49
+ * restore, logout and expiry (expiry always yields `null`).
50
+ */
51
+ export declare function useSession(seba: Seba | null | undefined): Session | null;
52
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/react/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAI1C,OAAO,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AACvD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAEvC,iDAAiD;AACjD,MAAM,WAAW,oBAAoB;IACnC,8CAA8C;IAC9C,QAAQ,EAAE,MAAM,CAAC;IACjB,2FAA2F;IAC3F,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,iEAAiE;IACjE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,8CAA8C;IAC9C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,oCAAoC;IACpC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,wDAAwD;IACxD,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,MAAM,CAAC;IAClC,sEAAsE;IACtE,IAAI,CAAC,EAAE,SAAS,GAAG,SAAS,GAAG,YAAY,GAAG,OAAO,GAAG,SAAS,GAAG,MAAM,CAAC;IAC3E,uCAAuC;IACvC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,4FAA4F;IAC5F,MAAM,CAAC,EAAE,OAAO,CAAC,IAAI,CAAC,UAAU,EAAE,UAAU,GAAG,aAAa,CAAC,CAAC,CAAC;IAC/D,kFAAkF;IAClF,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,6CAA6C;IAC7C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,kDAAkD;IAClD,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IACrC,2BAA2B;IAC3B,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IACtB,uCAAuC;IACvC,gBAAgB,CAAC,EAAE,MAAM,IAAI,CAAC;IAC9B,4DAA4D;IAC5D,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;CACpC;AAED,uDAAuD;AACvD,wBAAgB,eAAe,CAAC,KAAK,EAAE,oBAAoB,GAAG,YAAY,CAiDzE;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO,GAAG,IAAI,CAwBxE"}
@@ -0,0 +1,87 @@
1
+ /**
2
+ * React bindings (`@gaballahtech/seba/react`).
3
+ *
4
+ * `react` is an optional peer dependency: the core entry point never imports this file.
5
+ * The wrapper registers `<seba-login>` on mount, so no separate setup call is needed.
6
+ */
7
+ import { createElement, useEffect, useRef, useState } from "react";
8
+ import { defineSebaLogin } from "../element.js";
9
+ /** A Solid sign-in button backed by `<seba-login>`. */
10
+ export function SebaLoginButton(props) {
11
+ const host = useRef(null);
12
+ useEffect(() => {
13
+ defineSebaLogin();
14
+ const element = host.current;
15
+ if (element === null) {
16
+ return;
17
+ }
18
+ const onLogin = (event) => {
19
+ props.onLogin?.(event.detail.session);
20
+ };
21
+ const onLogout = () => {
22
+ props.onLogout?.();
23
+ };
24
+ const onExpired = () => {
25
+ props.onSessionExpired?.();
26
+ };
27
+ const onError = (event) => {
28
+ props.onError?.(event.detail.error);
29
+ };
30
+ element.addEventListener("seba:login", onLogin);
31
+ element.addEventListener("seba:restore", onLogin);
32
+ element.addEventListener("seba:logout", onLogout);
33
+ element.addEventListener("seba:session-expired", onExpired);
34
+ element.addEventListener("seba:error", onError);
35
+ return () => {
36
+ element.removeEventListener("seba:login", onLogin);
37
+ element.removeEventListener("seba:restore", onLogin);
38
+ element.removeEventListener("seba:logout", onLogout);
39
+ element.removeEventListener("seba:session-expired", onExpired);
40
+ element.removeEventListener("seba:error", onError);
41
+ };
42
+ }, [props.onLogin, props.onLogout, props.onSessionExpired, props.onError]);
43
+ return createElement("seba-login", {
44
+ ref: host,
45
+ "client-id": props.clientId,
46
+ ...(props.redirectUri === undefined ? {} : { "redirect-uri": props.redirectUri }),
47
+ ...(props.issuer === undefined ? {} : { issuer: props.issuer }),
48
+ ...(props.webId === undefined ? {} : { "web-id": props.webId }),
49
+ ...(props.label === undefined ? {} : { label: props.label }),
50
+ ...(props.theme === undefined ? {} : { theme: props.theme }),
51
+ ...(props.logo === undefined ? {} : { logo: props.logo }),
52
+ ...(props.account === undefined ? {} : { account: props.account }),
53
+ ...(props.providers === undefined ? {} : { providers: props.providers.join(" ") }),
54
+ ...(props.config === undefined ? {} : { config: JSON.stringify(props.config) }),
55
+ ...(props.className === undefined ? {} : { class: props.className }),
56
+ });
57
+ }
58
+ /**
59
+ * Track the session of a {@link Seba} instance.
60
+ *
61
+ * @returns The current session, or `null` while signed out. Updates on login,
62
+ * restore, logout and expiry (expiry always yields `null`).
63
+ */
64
+ export function useSession(seba) {
65
+ const [session, setSession] = useState(null);
66
+ useEffect(() => {
67
+ if (seba === null || seba === undefined) {
68
+ setSession(null);
69
+ return;
70
+ }
71
+ let active = true;
72
+ void seba.getSession().then((current) => {
73
+ if (active) {
74
+ setSession(current);
75
+ }
76
+ });
77
+ const unsubscribe = seba.onSessionChange((event) => {
78
+ setSession(event.session);
79
+ });
80
+ return () => {
81
+ active = false;
82
+ unsubscribe();
83
+ };
84
+ }, [seba]);
85
+ return session;
86
+ }
87
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/react/index.ts"],"names":[],"mappings":"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"}
package/dist/seba.d.ts CHANGED
@@ -4,7 +4,7 @@
4
4
  * The platform module is imported dynamically so a browser bundle never includes the
5
5
  * Node.js HTTP server and vice versa.
6
6
  */
7
- import type { LoginOptions, SebaConfig, Session } from "./types.js";
7
+ import type { LoginOptions, SebaConfig, Session, SessionChangeListener, SessionInfo } from "./types.js";
8
8
  /**
9
9
  * Solid-OIDC client with four operations: {@link Seba.login}, {@link Seba.restoreSession},
10
10
  * {@link Seba.fetch} and {@link Seba.logout}.
@@ -22,15 +22,54 @@ import type { LoginOptions, SebaConfig, Session } from "./types.js";
22
22
  */
23
23
  export declare class Seba {
24
24
  #private;
25
+ /** Pod helpers: `parseSubjectTriples`, `objectify` and `toTurtle`. */
26
+ static readonly pod: {
27
+ parseSubjectTriples: typeof import("./pod.js").parseSubjectTriples;
28
+ objectify: typeof import("./pod.js").objectify;
29
+ toTurtle: typeof import("./pod.js").toTurtle;
30
+ };
25
31
  /**
26
32
  * @param config - Client ID Document URL, redirect URI and optional storage settings.
27
33
  * Configuration is validated when the first operation runs.
28
34
  */
29
35
  constructor(config: SebaConfig);
36
+ /**
37
+ * Subscribe to session transitions (`login`, `restore`, `logout`, `expired`).
38
+ *
39
+ * @returns An unsubscribe function.
40
+ */
41
+ onSessionChange(listener: SessionChangeListener): () => void;
42
+ /** Remove a listener previously added with {@link Seba.onSessionChange}. */
43
+ offSessionChange(listener: SessionChangeListener): void;
44
+ /**
45
+ * Subscribe to the single `expired` transition of a session.
46
+ *
47
+ * @returns An unsubscribe function.
48
+ */
49
+ onSessionExpired(listener: SessionChangeListener): () => void;
50
+ /** Token-free current session, or `null` when signed out. */
51
+ getSession(): Promise<Session | null>;
30
52
  /** Start or finish an interactive login. See {@link SebaClient.login}. */
31
53
  login(options?: LoginOptions): Promise<Session>;
54
+ /**
55
+ * Complete a login whose callback URL is in the current address, WITHOUT starting a
56
+ * new one. Throws when no authorization response is present, so applications can
57
+ * call it on page load only when the URL actually carries `code`/`error` + `state`.
58
+ * This avoids the "login() never settles" redirect mode in explicit flows.
59
+ *
60
+ * @throws {@link SebaAuthError} when the current URL carries no callback parameters.
61
+ */
62
+ completeLogin(): Promise<Session>;
63
+ /** Whether the given (or current) URL carries an authorization response. */
64
+ static isCallbackResponse(url?: string | URL): boolean;
32
65
  /** Restore a stored session, or `null` when none exists. */
33
66
  restoreSession(): Promise<Session | null>;
67
+ /**
68
+ * Token-free details of the current session (WebID, provider and access-token
69
+ * expiry), or `null` when no session is active. Lets applications warn the user
70
+ * before the access token expires instead of failing mid-request.
71
+ */
72
+ getSessionInfo(): Promise<SessionInfo | null>;
34
73
  /** DPoP-authenticated `fetch`. Never forwards credentials to another origin. */
35
74
  fetch(input: RequestInfo | URL, init?: RequestInit): Promise<Response>;
36
75
  /** Sign out and revoke the refresh token when the provider supports it. */
@@ -1 +1 @@
1
- {"version":3,"file":"seba.d.ts","sourceRoot":"","sources":["../src/seba.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAY,UAAU,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAY9E;;;;;;;;;;;;;;GAcG;AACH,qBAAa,IAAI;;IAGf;;;OAGG;gBACS,MAAM,EAAE,UAAU;IAI9B,0EAA0E;IACpE,KAAK,CAAC,OAAO,GAAE,YAAiB,GAAG,OAAO,CAAC,OAAO,CAAC;IAIzD,4DAA4D;IACtD,cAAc,IAAI,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC;IAI/C,gFAAgF;IAC1E,KAAK,CAAC,KAAK,EAAE,WAAW,GAAG,GAAG,EAAE,IAAI,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,QAAQ,CAAC;IAI5E,2EAA2E;IACrE,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;CAG9B"}
1
+ {"version":3,"file":"seba.d.ts","sourceRoot":"","sources":["../src/seba.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,OAAO,KAAK,EACV,YAAY,EAEZ,UAAU,EACV,OAAO,EACP,qBAAqB,EACrB,WAAW,EACZ,MAAM,YAAY,CAAC;AAsBpB;;;;;;;;;;;;;;GAcG;AACH,qBAAa,IAAI;;IAIf,sEAAsE;IACtE,MAAM,CAAC,QAAQ,CAAC,GAAG;;;;MAAO;IAE1B;;;OAGG;gBACS,MAAM,EAAE,UAAU;IAY9B;;;;OAIG;IACH,eAAe,CAAC,QAAQ,EAAE,qBAAqB,GAAG,MAAM,IAAI;IAI5D,4EAA4E;IAC5E,gBAAgB,CAAC,QAAQ,EAAE,qBAAqB,GAAG,IAAI;IAIvD;;;;OAIG;IACH,gBAAgB,CAAC,QAAQ,EAAE,qBAAqB,GAAG,MAAM,IAAI;IAQ7D,6DAA6D;IACvD,UAAU,IAAI,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC;IAI3C,0EAA0E;IACpE,KAAK,CAAC,OAAO,GAAE,YAAiB,GAAG,OAAO,CAAC,OAAO,CAAC;IAIzD;;;;;;;OAOG;IACG,aAAa,IAAI,OAAO,CAAC,OAAO,CAAC;IAIvC,4EAA4E;IAC5E,MAAM,CAAC,kBAAkB,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,GAAG,GAAG,OAAO;IAiBtD,4DAA4D;IACtD,cAAc,IAAI,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC;IAI/C;;;;OAIG;IACG,cAAc,IAAI,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;IAInD,gFAAgF;IAC1E,KAAK,CAAC,KAAK,EAAE,WAAW,GAAG,GAAG,EAAE,IAAI,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,QAAQ,CAAC;IAI5E,2EAA2E;IACrE,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;CAG9B"}
package/dist/seba.js CHANGED
@@ -4,7 +4,9 @@
4
4
  * The platform module is imported dynamically so a browser bundle never includes the
5
5
  * Node.js HTTP server and vice versa.
6
6
  */
7
- import { SebaClient } from "./core/client.js";
7
+ import { SebaClient, isAuthorizationResponse } from "./core/client.js";
8
+ import { SessionEmitter } from "./core/events.js";
9
+ import { pod } from "./pod.js";
8
10
  async function loadPlatform() {
9
11
  const isBrowser = typeof window !== "undefined" && typeof document !== "undefined";
10
12
  if (isBrowser) {
@@ -14,6 +16,15 @@ async function loadPlatform() {
14
16
  const { createNodePlatform } = await import("./node/platform.js");
15
17
  return createNodePlatform();
16
18
  }
19
+ async function loadNamespacer() {
20
+ const isBrowser = typeof window !== "undefined" && typeof document !== "undefined";
21
+ if (isBrowser) {
22
+ const { namespaceBrowserPlatform } = await import("./browser/platform.js");
23
+ return namespaceBrowserPlatform;
24
+ }
25
+ // Node.js sessions live in per-instance memory, so no namespacing is needed.
26
+ return (platform) => platform;
27
+ }
17
28
  /**
18
29
  * Solid-OIDC client with four operations: {@link Seba.login}, {@link Seba.restoreSession},
19
30
  * {@link Seba.fetch} and {@link Seba.logout}.
@@ -31,21 +42,98 @@ async function loadPlatform() {
31
42
  */
32
43
  export class Seba {
33
44
  #client;
45
+ #events = new SessionEmitter();
46
+ /** Pod helpers: `parseSubjectTriples`, `objectify` and `toTurtle`. */
47
+ static pod = pod;
34
48
  /**
35
49
  * @param config - Client ID Document URL, redirect URI and optional storage settings.
36
50
  * Configuration is validated when the first operation runs.
37
51
  */
38
52
  constructor(config) {
39
- this.#client = loadPlatform().then((platform) => new SebaClient(config, platform));
53
+ this.#client = (async () => {
54
+ const [platform, namespacer] = await Promise.all([loadPlatform(), loadNamespacer()]);
55
+ const scoped = config.account === undefined ? platform : namespacer(platform, config.account);
56
+ return new SebaClient(config, scoped, {
57
+ onSessionChange: (event) => {
58
+ this.#events.emit(event);
59
+ },
60
+ });
61
+ })();
62
+ }
63
+ /**
64
+ * Subscribe to session transitions (`login`, `restore`, `logout`, `expired`).
65
+ *
66
+ * @returns An unsubscribe function.
67
+ */
68
+ onSessionChange(listener) {
69
+ return this.#events.on(listener);
70
+ }
71
+ /** Remove a listener previously added with {@link Seba.onSessionChange}. */
72
+ offSessionChange(listener) {
73
+ this.#events.off(listener);
74
+ }
75
+ /**
76
+ * Subscribe to the single `expired` transition of a session.
77
+ *
78
+ * @returns An unsubscribe function.
79
+ */
80
+ onSessionExpired(listener) {
81
+ return this.onSessionChange((event) => {
82
+ if (event.reason === "expired") {
83
+ listener(event);
84
+ }
85
+ });
86
+ }
87
+ /** Token-free current session, or `null` when signed out. */
88
+ async getSession() {
89
+ return (await this.#client).session;
40
90
  }
41
91
  /** Start or finish an interactive login. See {@link SebaClient.login}. */
42
92
  async login(options = {}) {
43
93
  return (await this.#client).login(options);
44
94
  }
95
+ /**
96
+ * Complete a login whose callback URL is in the current address, WITHOUT starting a
97
+ * new one. Throws when no authorization response is present, so applications can
98
+ * call it on page load only when the URL actually carries `code`/`error` + `state`.
99
+ * This avoids the "login() never settles" redirect mode in explicit flows.
100
+ *
101
+ * @throws {@link SebaAuthError} when the current URL carries no callback parameters.
102
+ */
103
+ async completeLogin() {
104
+ return (await this.#client).completeLoginFromCurrentUrl();
105
+ }
106
+ /** Whether the given (or current) URL carries an authorization response. */
107
+ static isCallbackResponse(url) {
108
+ let target;
109
+ if (url === undefined) {
110
+ if (typeof window === "undefined") {
111
+ return false;
112
+ }
113
+ target = new URL(window.location.href);
114
+ }
115
+ else {
116
+ try {
117
+ target = url instanceof URL ? url : new URL(url);
118
+ }
119
+ catch {
120
+ return false;
121
+ }
122
+ }
123
+ return isAuthorizationResponse(target);
124
+ }
45
125
  /** Restore a stored session, or `null` when none exists. */
46
126
  async restoreSession() {
47
127
  return (await this.#client).restoreSession();
48
128
  }
129
+ /**
130
+ * Token-free details of the current session (WebID, provider and access-token
131
+ * expiry), or `null` when no session is active. Lets applications warn the user
132
+ * before the access token expires instead of failing mid-request.
133
+ */
134
+ async getSessionInfo() {
135
+ return (await this.#client).sessionInfo();
136
+ }
49
137
  /** DPoP-authenticated `fetch`. Never forwards credentials to another origin. */
50
138
  async fetch(input, init) {
51
139
  return (await this.#client).fetch(input, init);
package/dist/seba.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"seba.js","sourceRoot":"","sources":["../src/seba.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAG9C,KAAK,UAAU,YAAY;IACzB,MAAM,SAAS,GAAG,OAAO,MAAM,KAAK,WAAW,IAAI,OAAO,QAAQ,KAAK,WAAW,CAAC;IACnF,IAAI,SAAS,EAAE,CAAC;QACd,MAAM,EAAE,qBAAqB,EAAE,GAAG,MAAM,MAAM,CAAC,uBAAuB,CAAC,CAAC;QACxE,OAAO,qBAAqB,EAAE,CAAC;IACjC,CAAC;IACD,MAAM,EAAE,kBAAkB,EAAE,GAAG,MAAM,MAAM,CAAC,oBAAoB,CAAC,CAAC;IAClE,OAAO,kBAAkB,EAAE,CAAC;AAC9B,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,OAAO,IAAI;IACN,OAAO,CAAsB;IAEtC;;;OAGG;IACH,YAAY,MAAkB;QAC5B,IAAI,CAAC,OAAO,GAAG,YAAY,EAAE,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,IAAI,UAAU,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC;IACrF,CAAC;IAED,0EAA0E;IAC1E,KAAK,CAAC,KAAK,CAAC,UAAwB,EAAE;QACpC,OAAO,CAAC,MAAM,IAAI,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAC7C,CAAC;IAED,4DAA4D;IAC5D,KAAK,CAAC,cAAc;QAClB,OAAO,CAAC,MAAM,IAAI,CAAC,OAAO,CAAC,CAAC,cAAc,EAAE,CAAC;IAC/C,CAAC;IAED,gFAAgF;IAChF,KAAK,CAAC,KAAK,CAAC,KAAwB,EAAE,IAAkB;QACtD,OAAO,CAAC,MAAM,IAAI,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IACjD,CAAC;IAED,2EAA2E;IAC3E,KAAK,CAAC,MAAM;QACV,OAAO,CAAC,MAAM,IAAI,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,CAAC;IACvC,CAAC;CACF"}
1
+ {"version":3,"file":"seba.js","sourceRoot":"","sources":["../src/seba.ts"],"names":[],"mappings":"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"}