@freeappstore/sdk 0.3.1 → 0.4.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 +14 -10
- package/dist/auth.d.ts +8 -3
- package/dist/auth.d.ts.map +1 -1
- package/dist/auth.js +17 -8
- package/dist/auth.js.map +1 -1
- package/dist/auth.test.js +17 -17
- package/dist/auth.test.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/kv.d.ts +15 -3
- package/dist/kv.d.ts.map +1 -1
- package/dist/kv.js +42 -32
- package/dist/kv.js.map +1 -1
- package/dist/kv.test.js +40 -42
- package/dist/kv.test.js.map +1 -1
- package/dist/proxy.d.ts.map +1 -1
- package/dist/proxy.js +4 -4
- package/dist/proxy.js.map +1 -1
- package/dist/proxy.test.js +1 -1
- package/dist/proxy.test.js.map +1 -1
- package/dist/rooms.d.ts +3 -3
- package/dist/rooms.d.ts.map +1 -1
- package/dist/rooms.js +16 -16
- package/dist/rooms.js.map +1 -1
- package/dist/rooms.test.js +78 -74
- package/dist/rooms.test.js.map +1 -1
- package/dist/types.d.ts +5 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +7 -7
- package/LICENSE +0 -21
package/README.md
CHANGED
|
@@ -2,11 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
Browser SDK for free apps published on **freeappstore.online**.
|
|
4
4
|
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
5
7
|
```bash
|
|
6
8
|
npm i @freeappstore/sdk
|
|
7
9
|
```
|
|
8
10
|
|
|
9
|
-
##
|
|
11
|
+
## Usage
|
|
10
12
|
|
|
11
13
|
```ts
|
|
12
14
|
import { initApp } from '@freeappstore/sdk';
|
|
@@ -51,9 +53,13 @@ Per-user, per-app key-value store. Scoped to `(appId, userId)` server-side, so a
|
|
|
51
53
|
await fas.kv.set('theme', { color: 'plum' });
|
|
52
54
|
const theme = await fas.kv.get<{ color: string }>('theme');
|
|
53
55
|
await fas.kv.delete('theme');
|
|
56
|
+
|
|
57
|
+
const allKeys = await fas.kv.list();
|
|
58
|
+
const noteKeys = await fas.kv.list({ prefix: 'note:' });
|
|
59
|
+
const notes = await fas.kv.getMany<Note>(noteKeys);
|
|
54
60
|
```
|
|
55
61
|
|
|
56
|
-
Limits (server-enforced): max 1MB per user, max 100 keys per user, max 64KB per value.
|
|
62
|
+
Limits (server-enforced): max 1MB per user, max 100 keys per user, max 64KB per value.
|
|
57
63
|
|
|
58
64
|
### Realtime rooms
|
|
59
65
|
|
|
@@ -74,16 +80,14 @@ room.close();
|
|
|
74
80
|
|
|
75
81
|
Limits (server-enforced): 32 peers per room, 100 msgs/sec per peer, 4KB per message, 24h idle eviction, 64 active rooms per app.
|
|
76
82
|
|
|
77
|
-
|
|
83
|
+
### Secret-injecting proxy
|
|
78
84
|
|
|
79
|
-
-
|
|
80
|
-
- Push notifications
|
|
81
|
-
- Outbound HTTP / AI proxy
|
|
82
|
-
- Scheduled tasks / cron
|
|
83
|
-
- Email / magic links
|
|
84
|
-
- Search
|
|
85
|
+
Call third-party APIs without exposing your keys in the browser. The platform Worker authenticates the call, injects the developer's stored API key server-side, and forwards the request.
|
|
85
86
|
|
|
86
|
-
|
|
87
|
+
```ts
|
|
88
|
+
const res = await fas.proxy.fetch('api.openweathermap.org/data/2.5/weather?q=London');
|
|
89
|
+
const data = await res.json();
|
|
90
|
+
```
|
|
87
91
|
|
|
88
92
|
## License
|
|
89
93
|
|
package/dist/auth.d.ts
CHANGED
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
import type { Unsubscribe, User } from "./types.js";
|
|
2
|
+
/** GitHub OAuth authentication — sign in, sign out, session management. */
|
|
2
3
|
export declare class Auth {
|
|
3
4
|
private readonly appId;
|
|
4
5
|
private readonly apiBase;
|
|
5
6
|
private session;
|
|
6
7
|
private listeners;
|
|
7
8
|
constructor(appId: string, apiBase: string);
|
|
9
|
+
/** Current signed-in user, or null if not authenticated. */
|
|
8
10
|
get user(): User | null;
|
|
11
|
+
/** Current session token, or null if not authenticated. */
|
|
9
12
|
get token(): string | null;
|
|
13
|
+
/** Subscribe to auth state changes. Fires immediately with current user, then on every change. */
|
|
10
14
|
onChange(listener: (user: User | null) => void): Unsubscribe;
|
|
11
15
|
/**
|
|
12
16
|
* Redirect-based GitHub OAuth. Opens the platform's hosted OAuth start URL,
|
|
@@ -17,11 +21,12 @@ export declare class Auth {
|
|
|
17
21
|
* hash-based router state otherwise.
|
|
18
22
|
*/
|
|
19
23
|
signIn(): void;
|
|
24
|
+
/** Clear the session and notify listeners. */
|
|
20
25
|
signOut(): void;
|
|
21
26
|
/**
|
|
22
|
-
* Called
|
|
23
|
-
* Clears the stale session so the UI reacts
|
|
24
|
-
*
|
|
27
|
+
* @internal Called by Kv and ApiProxy on 401 responses.
|
|
28
|
+
* Clears the stale session so the UI reacts immediately.
|
|
29
|
+
* Do not call directly — use `signOut()` instead.
|
|
25
30
|
*/
|
|
26
31
|
handleUnauthorized(): void;
|
|
27
32
|
/**
|
package/dist/auth.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAapD,qBAAa,IAAI;IAKb,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAL1B,OAAO,CAAC,OAAO,CAAwB;IACvC,OAAO,CAAC,SAAS,CAA0C;gBAGxC,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,MAAM;IAKlC,IAAI,IAAI,IAAI,IAAI,GAAG,IAAI,CAEtB;IAED,IAAI,KAAK,IAAI,MAAM,GAAG,IAAI,CAEzB;IAED,QAAQ,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,KAAK,IAAI,GAAG,WAAW;IAM5D;;;;;;;OAOG;IACH,MAAM,IAAI,IAAI;
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAapD,2EAA2E;AAC3E,qBAAa,IAAI;IAKb,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAL1B,OAAO,CAAC,OAAO,CAAwB;IACvC,OAAO,CAAC,SAAS,CAA0C;gBAGxC,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,MAAM;IAKlC,4DAA4D;IAC5D,IAAI,IAAI,IAAI,IAAI,GAAG,IAAI,CAEtB;IAED,2DAA2D;IAC3D,IAAI,KAAK,IAAI,MAAM,GAAG,IAAI,CAEzB;IAED,kGAAkG;IAClG,QAAQ,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,KAAK,IAAI,GAAG,WAAW;IAM5D;;;;;;;OAOG;IACH,MAAM,IAAI,IAAI;IAUd,8CAA8C;IAC9C,OAAO,IAAI,IAAI;IAQf;;;;OAIG;IACH,kBAAkB,IAAI,IAAI;IAI1B;;;;;;;;;;;;OAYG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;YA8Bb,SAAS;IAQvB,OAAO,CAAC,WAAW;IAWnB,OAAO,CAAC,YAAY;IAIpB,OAAO,CAAC,IAAI;CAGb"}
|
package/dist/auth.js
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
* A user signed in on one FAS app is signed in on all of them.
|
|
4
4
|
*/
|
|
5
5
|
const STORAGE_KEY = "fas:session";
|
|
6
|
+
/** GitHub OAuth authentication — sign in, sign out, session management. */
|
|
6
7
|
export class Auth {
|
|
7
8
|
appId;
|
|
8
9
|
apiBase;
|
|
@@ -13,12 +14,15 @@ export class Auth {
|
|
|
13
14
|
this.apiBase = apiBase;
|
|
14
15
|
this.session = this.readStorage();
|
|
15
16
|
}
|
|
17
|
+
/** Current signed-in user, or null if not authenticated. */
|
|
16
18
|
get user() {
|
|
17
19
|
return this.session?.user ?? null;
|
|
18
20
|
}
|
|
21
|
+
/** Current session token, or null if not authenticated. */
|
|
19
22
|
get token() {
|
|
20
23
|
return this.session?.token ?? null;
|
|
21
24
|
}
|
|
25
|
+
/** Subscribe to auth state changes. Fires immediately with current user, then on every change. */
|
|
22
26
|
onChange(listener) {
|
|
23
27
|
this.listeners.add(listener);
|
|
24
28
|
listener(this.user);
|
|
@@ -33,6 +37,8 @@ export class Auth {
|
|
|
33
37
|
* hash-based router state otherwise.
|
|
34
38
|
*/
|
|
35
39
|
signIn() {
|
|
40
|
+
if (typeof window === "undefined")
|
|
41
|
+
return;
|
|
36
42
|
const here = new URL(window.location.href);
|
|
37
43
|
here.hash = "";
|
|
38
44
|
const url = new URL("/v1/auth/github/start", this.apiBase);
|
|
@@ -40,15 +46,18 @@ export class Auth {
|
|
|
40
46
|
url.searchParams.set("return_to", here.toString());
|
|
41
47
|
window.location.assign(url.toString());
|
|
42
48
|
}
|
|
49
|
+
/** Clear the session and notify listeners. */
|
|
43
50
|
signOut() {
|
|
44
51
|
this.session = null;
|
|
45
|
-
window
|
|
52
|
+
if (typeof window !== "undefined") {
|
|
53
|
+
window.localStorage.removeItem(STORAGE_KEY);
|
|
54
|
+
}
|
|
46
55
|
this.emit();
|
|
47
56
|
}
|
|
48
57
|
/**
|
|
49
|
-
* Called
|
|
50
|
-
* Clears the stale session so the UI reacts
|
|
51
|
-
*
|
|
58
|
+
* @internal Called by Kv and ApiProxy on 401 responses.
|
|
59
|
+
* Clears the stale session so the UI reacts immediately.
|
|
60
|
+
* Do not call directly — use `signOut()` instead.
|
|
52
61
|
*/
|
|
53
62
|
handleUnauthorized() {
|
|
54
63
|
if (this.session)
|
|
@@ -99,12 +108,12 @@ export class Auth {
|
|
|
99
108
|
}
|
|
100
109
|
}
|
|
101
110
|
async fetchUser(token) {
|
|
102
|
-
const
|
|
111
|
+
const response = await fetch(new URL("/v1/auth/me", this.apiBase), {
|
|
103
112
|
headers: { Authorization: `Bearer ${token}` },
|
|
104
113
|
});
|
|
105
|
-
if (!
|
|
106
|
-
throw new Error(`Auth failed: ${
|
|
107
|
-
return (await
|
|
114
|
+
if (!response.ok)
|
|
115
|
+
throw new Error(`Auth failed: ${response.status}`);
|
|
116
|
+
return (await response.json());
|
|
108
117
|
}
|
|
109
118
|
readStorage() {
|
|
110
119
|
if (typeof window === "undefined")
|
package/dist/auth.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,MAAM,WAAW,GAAG,aAAa,CAAC;AAOlC,MAAM,OAAO,IAAI;IAKI;IACA;IALX,OAAO,GAAmB,IAAI,CAAC;IAC/B,SAAS,GAAG,IAAI,GAAG,EAA+B,CAAC;IAE3D,YACmB,KAAa,EACb,OAAe;QADf,UAAK,GAAL,KAAK,CAAQ;QACb,YAAO,GAAP,OAAO,CAAQ;QAEhC,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;IACpC,CAAC;IAED,IAAI,IAAI;QACN,OAAO,IAAI,CAAC,OAAO,EAAE,IAAI,IAAI,IAAI,CAAC;IACpC,CAAC;IAED,IAAI,KAAK;QACP,OAAO,IAAI,CAAC,OAAO,EAAE,KAAK,IAAI,IAAI,CAAC;IACrC,CAAC;IAED,QAAQ,CAAC,QAAqC;QAC5C,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAC7B,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACpB,OAAO,GAAG,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IAC/C,CAAC;IAED;;;;;;;OAOG;IACH,MAAM;QACJ,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QAC3C,IAAI,CAAC,IAAI,GAAG,EAAE,CAAC;QACf,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,uBAAuB,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;QAC3D,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,QAAQ,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;QAC3C,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,WAAW,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;QACnD,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAC;IACzC,CAAC;IAED,OAAO;QACL,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;QACpB,MAAM,CAAC,YAAY,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"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"}
|
package/dist/auth.test.js
CHANGED
|
@@ -32,21 +32,21 @@ function makeWindow(initial) {
|
|
|
32
32
|
}
|
|
33
33
|
beforeEach(() => {
|
|
34
34
|
// happy-dom-style globals; we install per-test
|
|
35
|
-
delete globalThis
|
|
36
|
-
delete globalThis
|
|
37
|
-
delete globalThis
|
|
35
|
+
delete globalThis.window;
|
|
36
|
+
delete globalThis.history;
|
|
37
|
+
delete globalThis.fetch;
|
|
38
38
|
});
|
|
39
39
|
afterEach(() => {
|
|
40
|
-
delete globalThis
|
|
41
|
-
delete globalThis
|
|
42
|
-
delete globalThis
|
|
40
|
+
delete globalThis.window;
|
|
41
|
+
delete globalThis.history;
|
|
42
|
+
delete globalThis.fetch;
|
|
43
43
|
});
|
|
44
44
|
describe("Auth.signIn", () => {
|
|
45
45
|
it("strips the hash from return_to so the OAuth callback does not clobber app router state", () => {
|
|
46
46
|
const { window, assigns } = makeWindow({
|
|
47
47
|
href: "https://app.freeappstore.online/dashboard?team=42#/settings/profile",
|
|
48
48
|
});
|
|
49
|
-
globalThis
|
|
49
|
+
globalThis.window = window;
|
|
50
50
|
const auth = new Auth("demo", "https://api.freeappstore.online");
|
|
51
51
|
auth.signIn();
|
|
52
52
|
expect(assigns).toHaveLength(1);
|
|
@@ -58,7 +58,7 @@ describe("Auth.signIn", () => {
|
|
|
58
58
|
});
|
|
59
59
|
it("still preserves pathname + querystring", () => {
|
|
60
60
|
const { window, assigns } = makeWindow({ href: "https://app.example/page?x=1" });
|
|
61
|
-
globalThis
|
|
61
|
+
globalThis.window = window;
|
|
62
62
|
const auth = new Auth("demo", "https://api.example");
|
|
63
63
|
auth.signIn();
|
|
64
64
|
const returnTo = new URL(assigns[0]).searchParams.get("return_to");
|
|
@@ -71,8 +71,8 @@ describe("Auth.init — hash handling", () => {
|
|
|
71
71
|
href: "https://app.example/",
|
|
72
72
|
hash: "#fas_session=bad-token",
|
|
73
73
|
});
|
|
74
|
-
globalThis
|
|
75
|
-
globalThis
|
|
74
|
+
globalThis.window = window;
|
|
75
|
+
globalThis.history = window.history;
|
|
76
76
|
globalThis.fetch = vi.fn().mockResolvedValue(new Response("", { status: 401 }));
|
|
77
77
|
const auth = new Auth("demo", "https://api.example");
|
|
78
78
|
// init() no longer throws — it silently remains signed out.
|
|
@@ -87,8 +87,8 @@ describe("Auth.init — hash handling", () => {
|
|
|
87
87
|
href: "https://app.example/dashboard",
|
|
88
88
|
hash: "#fas_session=good-token",
|
|
89
89
|
});
|
|
90
|
-
globalThis
|
|
91
|
-
globalThis
|
|
90
|
+
globalThis.window = window;
|
|
91
|
+
globalThis.history = window.history;
|
|
92
92
|
globalThis.fetch = vi.fn().mockResolvedValue(new Response(JSON.stringify({ id: "gh:1", login: "alice", avatarUrl: null }), {
|
|
93
93
|
status: 200,
|
|
94
94
|
}));
|
|
@@ -101,8 +101,8 @@ describe("Auth.init — hash handling", () => {
|
|
|
101
101
|
});
|
|
102
102
|
it("is a no-op when no fas_session hash is present", async () => {
|
|
103
103
|
const { window, replaces } = makeWindow({ href: "https://app.example/" });
|
|
104
|
-
globalThis
|
|
105
|
-
globalThis
|
|
104
|
+
globalThis.window = window;
|
|
105
|
+
globalThis.history = window.history;
|
|
106
106
|
const fetchSpy = vi.fn();
|
|
107
107
|
globalThis.fetch = fetchSpy;
|
|
108
108
|
const auth = new Auth("demo", "https://api.example");
|
|
@@ -119,7 +119,7 @@ describe("Auth — storage round-trip", () => {
|
|
|
119
119
|
token: "cached",
|
|
120
120
|
user: { id: "gh:7", login: "returning-user", avatarUrl: null },
|
|
121
121
|
}));
|
|
122
|
-
globalThis
|
|
122
|
+
globalThis.window = window;
|
|
123
123
|
const auth = new Auth("demo", "https://api.example");
|
|
124
124
|
expect(auth.user?.login).toBe("returning-user");
|
|
125
125
|
expect(auth.token).toBe("cached");
|
|
@@ -130,7 +130,7 @@ describe("Auth — storage round-trip", () => {
|
|
|
130
130
|
token: "cached",
|
|
131
131
|
user: { id: "gh:7", login: "u", avatarUrl: null },
|
|
132
132
|
}));
|
|
133
|
-
globalThis
|
|
133
|
+
globalThis.window = window;
|
|
134
134
|
const auth = new Auth("demo", "https://api.example");
|
|
135
135
|
const seen = [];
|
|
136
136
|
auth.onChange((u) => seen.push(u));
|
|
@@ -143,7 +143,7 @@ describe("Auth — storage round-trip", () => {
|
|
|
143
143
|
it("returns null when localStorage has corrupt JSON (does not crash)", () => {
|
|
144
144
|
const { window } = makeWindow({ href: "https://app.example/" });
|
|
145
145
|
window.localStorage.store.set("fas:session", "{ not: json");
|
|
146
|
-
globalThis
|
|
146
|
+
globalThis.window = window;
|
|
147
147
|
const auth = new Auth("demo", "https://api.example");
|
|
148
148
|
expect(auth.user).toBeNull();
|
|
149
149
|
});
|
package/dist/auth.test.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.test.js","sourceRoot":"","sources":["../src/auth.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AACzE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAejC,SAAS,UAAU,CAAC,OAAwC;IAC1D,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAClC,IAAI,OAAO,CAAC,IAAI;QAAE,GAAG,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAC1C,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,MAAM,OAAO,GAAgB;QAC3B,KAAK,EAAE,IAAI,GAAG,EAAE;QAChB,OAAO,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,IAAI;QAC5C,OAAO,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,KAAK,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC;QAC/C,UAAU,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;KAChD,CAAC;IACF,OAAO;QACL,MAAM,EAAE;YACN,QAAQ,EAAE;gBACR,IAAI,EAAE,GAAG,CAAC,QAAQ,EAAE;gBACpB,IAAI,EAAE,GAAG,CAAC,IAAI;gBACd,QAAQ,EAAE,GAAG,CAAC,QAAQ;gBACtB,MAAM,EAAE,GAAG,CAAC,MAAM;gBAClB,MAAM,EAAE,CAAC,CAAS,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;aACvC;YACD,YAAY,EAAE,OAAO;YACrB,OAAO,EAAE;gBACP,YAAY,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;aAC9C;SACF;QACD,OAAO;QACP,QAAQ;KACT,CAAC;AACJ,CAAC;AAED,UAAU,CAAC,GAAG,EAAE;IACd,+CAA+C;IAC/C,OAAQ,UAAsC,CAAC,
|
|
1
|
+
{"version":3,"file":"auth.test.js","sourceRoot":"","sources":["../src/auth.test.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -5,6 +5,7 @@ import { Rooms } from "./rooms.js";
|
|
|
5
5
|
import type { FasInitOptions } from "./types.js";
|
|
6
6
|
export type { ConnectionState, Room, RoomMessage, RoomPeer } from "./rooms.js";
|
|
7
7
|
export type { FasInitOptions, Unsubscribe, User } from "./types.js";
|
|
8
|
+
/** Root SDK instance — provides auth, kv, rooms, and proxy sub-clients. */
|
|
8
9
|
export declare class FreeAppStore {
|
|
9
10
|
readonly auth: Auth;
|
|
10
11
|
readonly kv: Kv;
|
|
@@ -12,5 +13,6 @@ export declare class FreeAppStore {
|
|
|
12
13
|
readonly proxy: ApiProxy;
|
|
13
14
|
constructor(opts: FasInitOptions);
|
|
14
15
|
}
|
|
16
|
+
/** Create a new FreeAppStore SDK instance for the given app. */
|
|
15
17
|
export declare function initApp(opts: FasInitOptions): FreeAppStore;
|
|
16
18
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC;AAC7B,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjD,YAAY,EAAE,eAAe,EAAE,IAAI,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAC/E,YAAY,EAAE,cAAc,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAEpE,qBAAa,YAAY;IACvB,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC;IACpB,QAAQ,CAAC,EAAE,EAAE,EAAE,CAAC;IAChB,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC;gBAEb,IAAI,EAAE,cAAc;CAOjC;AAED,wBAAgB,OAAO,CAAC,IAAI,EAAE,cAAc,GAAG,YAAY,CAE1D"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC;AAC7B,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjD,YAAY,EAAE,eAAe,EAAE,IAAI,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAC/E,YAAY,EAAE,cAAc,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAEpE,2EAA2E;AAC3E,qBAAa,YAAY;IACvB,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC;IACpB,QAAQ,CAAC,EAAE,EAAE,EAAE,CAAC;IAChB,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC;gBAEb,IAAI,EAAE,cAAc;CAOjC;AAED,gEAAgE;AAChE,wBAAgB,OAAO,CAAC,IAAI,EAAE,cAAc,GAAG,YAAY,CAE1D"}
|
package/dist/index.js
CHANGED
|
@@ -2,6 +2,7 @@ import { Auth } from "./auth.js";
|
|
|
2
2
|
import { Kv } from "./kv.js";
|
|
3
3
|
import { ApiProxy } from "./proxy.js";
|
|
4
4
|
import { Rooms } from "./rooms.js";
|
|
5
|
+
/** Root SDK instance — provides auth, kv, rooms, and proxy sub-clients. */
|
|
5
6
|
export class FreeAppStore {
|
|
6
7
|
auth;
|
|
7
8
|
kv;
|
|
@@ -15,6 +16,7 @@ export class FreeAppStore {
|
|
|
15
16
|
this.proxy = new ApiProxy(opts.appId, apiBase, this.auth);
|
|
16
17
|
}
|
|
17
18
|
}
|
|
19
|
+
/** Create a new FreeAppStore SDK instance for the given app. */
|
|
18
20
|
export function initApp(opts) {
|
|
19
21
|
return new FreeAppStore(opts);
|
|
20
22
|
}
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC;AAC7B,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAMnC,MAAM,OAAO,YAAY;IACd,IAAI,CAAO;IACX,EAAE,CAAK;IACP,KAAK,CAAQ;IACb,KAAK,CAAW;IAEzB,YAAY,IAAoB;QAC9B,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI,iCAAiC,CAAC;QAClE,IAAI,CAAC,IAAI,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QAC1C,IAAI,CAAC,EAAE,GAAG,IAAI,EAAE,CAAC,IAAI,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;QACjD,IAAI,CAAC,KAAK,GAAG,IAAI,KAAK,CAAC,IAAI,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;QACvD,IAAI,CAAC,KAAK,GAAG,IAAI,QAAQ,CAAC,IAAI,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;IAC5D,CAAC;CACF;AAED,MAAM,UAAU,OAAO,CAAC,IAAoB;IAC1C,OAAO,IAAI,YAAY,CAAC,IAAI,CAAC,CAAC;AAChC,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC;AAC7B,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAMnC,2EAA2E;AAC3E,MAAM,OAAO,YAAY;IACd,IAAI,CAAO;IACX,EAAE,CAAK;IACP,KAAK,CAAQ;IACb,KAAK,CAAW;IAEzB,YAAY,IAAoB;QAC9B,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI,iCAAiC,CAAC;QAClE,IAAI,CAAC,IAAI,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QAC1C,IAAI,CAAC,EAAE,GAAG,IAAI,EAAE,CAAC,IAAI,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;QACjD,IAAI,CAAC,KAAK,GAAG,IAAI,KAAK,CAAC,IAAI,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;QACvD,IAAI,CAAC,KAAK,GAAG,IAAI,QAAQ,CAAC,IAAI,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;IAC5D,CAAC;CACF;AAED,gEAAgE;AAChE,MAAM,UAAU,OAAO,CAAC,IAAoB;IAC1C,OAAO,IAAI,YAAY,CAAC,IAAI,CAAC,CAAC;AAChC,CAAC"}
|
package/dist/kv.d.ts
CHANGED
|
@@ -4,13 +4,25 @@ export declare class Kv {
|
|
|
4
4
|
private readonly apiBase;
|
|
5
5
|
private readonly auth;
|
|
6
6
|
constructor(appId: string, apiBase: string, auth: Auth);
|
|
7
|
+
/** List all keys for this user. Optionally filter by prefix. */
|
|
7
8
|
list(opts?: {
|
|
8
9
|
prefix?: string;
|
|
10
|
+
signal?: AbortSignal;
|
|
9
11
|
}): Promise<string[]>;
|
|
12
|
+
/** Fetch multiple keys in parallel. Returns a Map of found key-value pairs (skips failures and missing keys). */
|
|
10
13
|
getMany<T = unknown>(keys: string[]): Promise<Map<string, T>>;
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
+
/** Get a value by key. Returns null if not found. */
|
|
15
|
+
get<T = unknown>(key: string, opts?: {
|
|
16
|
+
signal?: AbortSignal;
|
|
17
|
+
}): Promise<T | null>;
|
|
18
|
+
/** Store a JSON-serializable value under the given key. */
|
|
19
|
+
set<T = unknown>(key: string, value: T, opts?: {
|
|
20
|
+
signal?: AbortSignal;
|
|
21
|
+
}): Promise<void>;
|
|
22
|
+
/** Delete a key. No-op if the key doesn't exist. */
|
|
23
|
+
delete(key: string, opts?: {
|
|
24
|
+
signal?: AbortSignal;
|
|
25
|
+
}): Promise<void>;
|
|
14
26
|
private request;
|
|
15
27
|
}
|
|
16
28
|
//# sourceMappingURL=kv.d.ts.map
|
package/dist/kv.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"kv.d.ts","sourceRoot":"","sources":["../src/kv.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAyBtC,qBAAa,EAAE;IAEX,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,IAAI;gBAFJ,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,IAAI;
|
|
1
|
+
{"version":3,"file":"kv.d.ts","sourceRoot":"","sources":["../src/kv.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAyBtC,qBAAa,EAAE;IAEX,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,IAAI;gBAFJ,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,IAAI;IAG7B,gEAAgE;IAC1D,IAAI,CAAC,IAAI,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,WAAW,CAAA;KAAE,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAoB/E,iHAAiH;IAC3G,OAAO,CAAC,CAAC,GAAG,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IAiBnE,qDAAqD;IAC/C,GAAG,CAAC,CAAC,GAAG,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,WAAW,CAAA;KAAE,GAAG,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC;IAQvF,2DAA2D;IACrD,GAAG,CAAC,CAAC,GAAG,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,WAAW,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAc7F,oDAAoD;IAC9C,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,WAAW,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC;YAQ3D,OAAO;CAetB"}
|
package/dist/kv.js
CHANGED
|
@@ -28,6 +28,7 @@ export class Kv {
|
|
|
28
28
|
this.apiBase = apiBase;
|
|
29
29
|
this.auth = auth;
|
|
30
30
|
}
|
|
31
|
+
/** List all keys for this user. Optionally filter by prefix. */
|
|
31
32
|
async list(opts) {
|
|
32
33
|
const token = this.auth.token;
|
|
33
34
|
if (!token)
|
|
@@ -35,63 +36,72 @@ export class Kv {
|
|
|
35
36
|
const url = new URL(`/v1/apps/${encodeURIComponent(this.appId)}/kv`, this.apiBase);
|
|
36
37
|
if (opts?.prefix)
|
|
37
38
|
url.searchParams.set("prefix", opts.prefix);
|
|
38
|
-
const
|
|
39
|
+
const listResponse = await fetch(url, {
|
|
39
40
|
headers: { Authorization: `Bearer ${token}` },
|
|
41
|
+
...(opts?.signal && { signal: opts.signal }),
|
|
40
42
|
});
|
|
41
|
-
if (
|
|
43
|
+
if (listResponse.status === 401) {
|
|
42
44
|
this.auth.handleUnauthorized();
|
|
43
45
|
throw new Error("Not signed in.");
|
|
44
46
|
}
|
|
45
|
-
if (!
|
|
46
|
-
throw new Error(`kv.list failed: ${
|
|
47
|
-
let keys = (await
|
|
47
|
+
if (!listResponse.ok)
|
|
48
|
+
throw new Error(`kv.list failed: ${listResponse.status}`);
|
|
49
|
+
let keys = (await listResponse.json());
|
|
48
50
|
// Client-side prefix filter as fallback if server doesn't support it yet
|
|
49
51
|
if (opts?.prefix)
|
|
50
|
-
keys = keys.filter(k => k.startsWith(opts.prefix));
|
|
52
|
+
keys = keys.filter((k) => k.startsWith(opts.prefix));
|
|
51
53
|
return keys;
|
|
52
54
|
}
|
|
55
|
+
/** Fetch multiple keys in parallel. Returns a Map of found key-value pairs (skips failures and missing keys). */
|
|
53
56
|
async getMany(keys) {
|
|
54
57
|
for (const key of keys)
|
|
55
58
|
assertValidKey(key);
|
|
56
59
|
const results = new Map();
|
|
57
|
-
const
|
|
58
|
-
const
|
|
59
|
-
if (
|
|
60
|
-
results.set(key,
|
|
61
|
-
});
|
|
62
|
-
|
|
60
|
+
const settled = await Promise.allSettled(keys.map(async (key) => {
|
|
61
|
+
const stored = await this.get(key);
|
|
62
|
+
if (stored !== null)
|
|
63
|
+
results.set(key, stored);
|
|
64
|
+
}));
|
|
65
|
+
// If ALL requests failed with auth error, re-throw so callers know
|
|
66
|
+
const allFailed = settled.every((s) => s.status === "rejected");
|
|
67
|
+
if (allFailed && settled.length > 0) {
|
|
68
|
+
throw settled[0].reason;
|
|
69
|
+
}
|
|
63
70
|
return results;
|
|
64
71
|
}
|
|
65
|
-
|
|
72
|
+
/** Get a value by key. Returns null if not found. */
|
|
73
|
+
async get(key, opts) {
|
|
66
74
|
assertValidKey(key);
|
|
67
|
-
const
|
|
68
|
-
if (
|
|
75
|
+
const getResponse = await this.request("GET", key, undefined, opts?.signal);
|
|
76
|
+
if (getResponse.status === 404)
|
|
69
77
|
return null;
|
|
70
|
-
if (!
|
|
71
|
-
throw new Error(`kv.get failed: ${
|
|
72
|
-
return (await
|
|
78
|
+
if (!getResponse.ok)
|
|
79
|
+
throw new Error(`kv.get failed: ${getResponse.status}`);
|
|
80
|
+
return (await getResponse.json());
|
|
73
81
|
}
|
|
74
|
-
|
|
82
|
+
/** Store a JSON-serializable value under the given key. */
|
|
83
|
+
async set(key, value, opts) {
|
|
75
84
|
assertValidKey(key);
|
|
76
85
|
// JSON.stringify(undefined) returns undefined, which would store an empty
|
|
77
86
|
// body and break later get() calls. Reject up front instead.
|
|
78
87
|
if (value === undefined) {
|
|
79
88
|
throw new Error("kv.set: value is undefined. Use kv.delete(key) to remove a key.");
|
|
80
89
|
}
|
|
81
|
-
const
|
|
82
|
-
if (!
|
|
83
|
-
const text = await
|
|
84
|
-
throw new Error(`kv.set failed (${
|
|
90
|
+
const setResponse = await this.request("PUT", key, JSON.stringify(value), opts?.signal);
|
|
91
|
+
if (!setResponse.ok) {
|
|
92
|
+
const text = await setResponse.text();
|
|
93
|
+
throw new Error(`kv.set failed (${setResponse.status}): ${text}`);
|
|
85
94
|
}
|
|
86
95
|
}
|
|
87
|
-
|
|
96
|
+
/** Delete a key. No-op if the key doesn't exist. */
|
|
97
|
+
async delete(key, opts) {
|
|
88
98
|
assertValidKey(key);
|
|
89
|
-
const
|
|
90
|
-
if (!
|
|
91
|
-
throw new Error(`kv.delete failed: ${
|
|
99
|
+
const deleteResponse = await this.request("DELETE", key, undefined, opts?.signal);
|
|
100
|
+
if (!deleteResponse.ok && deleteResponse.status !== 404) {
|
|
101
|
+
throw new Error(`kv.delete failed: ${deleteResponse.status}`);
|
|
92
102
|
}
|
|
93
103
|
}
|
|
94
|
-
async request(method, key, body) {
|
|
104
|
+
async request(method, key, body, signal) {
|
|
95
105
|
const token = this.auth.token;
|
|
96
106
|
if (!token)
|
|
97
107
|
throw new Error("Not signed in.");
|
|
@@ -99,15 +109,15 @@ export class Kv {
|
|
|
99
109
|
const headers = { Authorization: `Bearer ${token}` };
|
|
100
110
|
if (body !== undefined)
|
|
101
111
|
headers["Content-Type"] = "application/json";
|
|
102
|
-
const init = { method, headers };
|
|
112
|
+
const init = { method, headers, ...(signal && { signal }) };
|
|
103
113
|
if (body !== undefined)
|
|
104
114
|
init.body = body;
|
|
105
|
-
const
|
|
106
|
-
if (
|
|
115
|
+
const kvResponse = await fetch(url, init);
|
|
116
|
+
if (kvResponse.status === 401) {
|
|
107
117
|
this.auth.handleUnauthorized();
|
|
108
118
|
throw new Error("Not signed in.");
|
|
109
119
|
}
|
|
110
|
-
return
|
|
120
|
+
return kvResponse;
|
|
111
121
|
}
|
|
112
122
|
}
|
|
113
123
|
//# sourceMappingURL=kv.js.map
|
package/dist/kv.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"kv.js","sourceRoot":"","sources":["../src/kv.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;GAWG;AACH,MAAM,cAAc,GAAG,GAAG,CAAC;AAE3B,SAAS,cAAc,CAAC,GAAW;IACjC,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAChD,MAAM,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAC;IACxD,CAAC;IACD,IAAI,GAAG,CAAC,MAAM,GAAG,cAAc,EAAE,CAAC;QAChC,MAAM,IAAI,KAAK,CAAC,kBAAkB,cAAc,SAAS,CAAC,CAAC;IAC7D,CAAC;AACH,CAAC;AAED,MAAM,OAAO,EAAE;IAEM;IACA;IACA;IAHnB,YACmB,KAAa,EACb,OAAe,EACf,IAAU;QAFV,UAAK,GAAL,KAAK,CAAQ;QACb,YAAO,GAAP,OAAO,CAAQ;QACf,SAAI,GAAJ,IAAI,CAAM;IAC1B,CAAC;IAEJ,KAAK,CAAC,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"kv.js","sourceRoot":"","sources":["../src/kv.ts"],"names":[],"mappings":"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"}
|