@flowerforce/flowerbase-client 0.1.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 (63) hide show
  1. package/CHANGELOG.md +0 -0
  2. package/LICENSE +3 -0
  3. package/README.md +209 -0
  4. package/dist/app.d.ts +85 -0
  5. package/dist/app.d.ts.map +1 -0
  6. package/dist/app.js +461 -0
  7. package/dist/bson.d.ts +8 -0
  8. package/dist/bson.d.ts.map +1 -0
  9. package/dist/bson.js +10 -0
  10. package/dist/credentials.d.ts +8 -0
  11. package/dist/credentials.d.ts.map +1 -0
  12. package/dist/credentials.js +30 -0
  13. package/dist/functions.d.ts +6 -0
  14. package/dist/functions.d.ts.map +1 -0
  15. package/dist/functions.js +47 -0
  16. package/dist/http.d.ts +35 -0
  17. package/dist/http.d.ts.map +1 -0
  18. package/dist/http.js +170 -0
  19. package/dist/index.d.ts +8 -0
  20. package/dist/index.d.ts.map +1 -0
  21. package/dist/index.js +16 -0
  22. package/dist/mongo.d.ts +4 -0
  23. package/dist/mongo.d.ts.map +1 -0
  24. package/dist/mongo.js +106 -0
  25. package/dist/session.d.ts +18 -0
  26. package/dist/session.d.ts.map +1 -0
  27. package/dist/session.js +105 -0
  28. package/dist/session.native.d.ts +14 -0
  29. package/dist/session.native.d.ts.map +1 -0
  30. package/dist/session.native.js +76 -0
  31. package/dist/types.d.ts +97 -0
  32. package/dist/types.d.ts.map +1 -0
  33. package/dist/types.js +2 -0
  34. package/dist/user.d.ts +37 -0
  35. package/dist/user.d.ts.map +1 -0
  36. package/dist/user.js +125 -0
  37. package/dist/watch.d.ts +3 -0
  38. package/dist/watch.d.ts.map +1 -0
  39. package/dist/watch.js +139 -0
  40. package/jest.config.ts +13 -0
  41. package/package.json +41 -0
  42. package/project.json +11 -0
  43. package/rollup.config.js +17 -0
  44. package/src/__tests__/auth.test.ts +213 -0
  45. package/src/__tests__/compat.test.ts +22 -0
  46. package/src/__tests__/functions.test.ts +312 -0
  47. package/src/__tests__/mongo.test.ts +83 -0
  48. package/src/__tests__/session.test.ts +597 -0
  49. package/src/__tests__/watch.test.ts +336 -0
  50. package/src/app.ts +562 -0
  51. package/src/bson.ts +6 -0
  52. package/src/credentials.ts +31 -0
  53. package/src/functions.ts +56 -0
  54. package/src/http.ts +221 -0
  55. package/src/index.ts +15 -0
  56. package/src/mongo.ts +112 -0
  57. package/src/session.native.ts +89 -0
  58. package/src/session.ts +114 -0
  59. package/src/types.ts +114 -0
  60. package/src/user.ts +150 -0
  61. package/src/watch.ts +156 -0
  62. package/tsconfig.json +34 -0
  63. package/tsconfig.spec.json +13 -0
package/CHANGELOG.md ADDED
File without changes
package/LICENSE ADDED
@@ -0,0 +1,3 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Flowerbase
package/README.md ADDED
@@ -0,0 +1,209 @@
1
+ # @flowerforce/flowerbase-client
2
+
3
+ Client TypeScript leggero per usare Flowerbase con API in stile Realm:
4
+
5
+ - autenticazione (`local-userpass`, `anon-user`, `custom-function`)
6
+ - chiamate funzioni (`user.functions.<name>(...)`)
7
+ - accesso a MongoDB Atlas service (`user.mongoClient("mongodb-atlas")`)
8
+ - change stream via `watch()` con async iterator
9
+ - supporto BSON/EJSON (`ObjectId`, `Date`, ecc.)
10
+
11
+ ## Installazione
12
+
13
+ ```bash
14
+ npm i @flowerforce/flowerbase-client
15
+ ```
16
+
17
+ ## Quick start
18
+
19
+ ```ts
20
+ import { App, Credentials } from '@flowerforce/flowerbase-client'
21
+
22
+ const app = new App({
23
+ id: 'my-app-id',
24
+ baseUrl: 'http://localhost:8000',
25
+ timeout: 10000
26
+ })
27
+
28
+ await app.logIn(Credentials.emailPassword('user@example.com', 'secret'))
29
+
30
+ const user = app.currentUser
31
+ if (!user) throw new Error('User not logged in')
32
+
33
+ const result = await user.functions.myFunction('hello')
34
+ console.log(result)
35
+ ```
36
+
37
+ ## Configurazione `App`
38
+
39
+ ```ts
40
+ new App({
41
+ id: string, // app id Flowerbase
42
+ baseUrl: string, // URL base backend (es: http://localhost:8000)
43
+ timeout?: number // default 10000
44
+ })
45
+ ```
46
+
47
+ ## Autenticazione
48
+
49
+ ### Local user/pass
50
+
51
+ ```ts
52
+ await app.logIn(Credentials.emailPassword(email, password))
53
+ ```
54
+
55
+ ### Anonymous
56
+
57
+ ```ts
58
+ await app.logIn(Credentials.anonymous())
59
+ ```
60
+
61
+ ### Custom function auth
62
+
63
+ ```ts
64
+ await app.logIn(
65
+ Credentials.function({
66
+ username: 'demo',
67
+ pin: '1234'
68
+ })
69
+ )
70
+ ```
71
+
72
+ ### Utility `emailPasswordAuth`
73
+
74
+ ```ts
75
+ await app.emailPasswordAuth.registerUser({ email, password })
76
+ await app.emailPasswordAuth.sendResetPasswordEmail(email)
77
+ await app.emailPasswordAuth.callResetPasswordFunction(email, newPassword, extraArg1, extraArg2)
78
+ await app.emailPasswordAuth.resetPassword({ token, tokenId, password })
79
+ ```
80
+
81
+ ## Current user
82
+
83
+ Dopo il login:
84
+
85
+ ```ts
86
+ const user = app.currentUser
87
+ ```
88
+
89
+ Interfaccia principale:
90
+
91
+ - `user.id`
92
+ - `user.functions.<functionName>(...args)`
93
+ - `user.mongoClient('mongodb-atlas')`
94
+ - `user.refreshAccessToken()`
95
+ - `user.refreshCustomData()`
96
+ - `user.logOut()`
97
+
98
+ ## Funzioni server
99
+
100
+ ```ts
101
+ const response = await user.functions.calculateScore({ workspaceId: 'w1' })
102
+ ```
103
+
104
+ Le risposte sono normalizzate lato client per gestire payload JSON/EJSON.
105
+
106
+ ## Mongo service
107
+
108
+ ```ts
109
+ const mongo = user.mongoClient('mongodb-atlas')
110
+ const collection = mongo.db('mydb').collection('todos')
111
+
112
+ const one = await collection.findOne({ done: false })
113
+ const many = await collection.find({ done: false })
114
+
115
+ await collection.insertOne({ title: 'Task', createdAt: new Date() })
116
+ await collection.updateOne({ title: 'Task' }, { $set: { done: true } })
117
+ await collection.deleteOne({ title: 'Task' })
118
+ ```
119
+
120
+ Metodi disponibili su `collection`:
121
+
122
+ - `find(query?, options?)`
123
+ - `findOne(query?, options?)`
124
+ - `insertOne(document, options?)`
125
+ - `updateOne(filter, update, options?)`
126
+ - `updateMany(filter, update, options?)`
127
+ - `deleteOne(filter, options?)`
128
+ - `watch(options?)`
129
+
130
+ ## Watch / Change streams
131
+
132
+ `watch()` restituisce un async iterator con reconnect automatico e metodo `close()`.
133
+
134
+ ```ts
135
+ const stream = collection.watch()
136
+
137
+ try {
138
+ for await (const change of stream) {
139
+ console.log(change)
140
+ }
141
+ } finally {
142
+ stream.close()
143
+ }
144
+ ```
145
+
146
+ Esempio con filtro Realm-like:
147
+
148
+ ```ts
149
+ const stream = collection.watch({
150
+ filter: {
151
+ operationType: 'update',
152
+ 'fullDocument.type': 'perennial'
153
+ }
154
+ })
155
+ ```
156
+
157
+ ## BSON / EJSON
158
+
159
+ Il client esporta anche:
160
+
161
+ ```ts
162
+ import { BSON, EJSON, ObjectId, ObjectID } from '@flowerforce/flowerbase-client'
163
+ ```
164
+
165
+ Il layer Mongo client serializza query/opzioni con EJSON e deserializza le risposte, così tipi BSON come `ObjectId` e `Date` restano coerenti con l'uso Realm-like.
166
+
167
+ ## Sessione
168
+
169
+ La sessione (`accessToken`, `refreshToken`, `userId`) viene salvata con chiave:
170
+
171
+ - `flowerbase:<appId>:session`
172
+
173
+ Storage usato:
174
+
175
+ - `localStorage` se disponibile (browser)
176
+ - memory store fallback (ambienti senza `localStorage`)
177
+
178
+ Su bootstrap dell'app viene tentato un refresh automatico dell'access token usando il refresh token salvato.
179
+
180
+ ## Logout
181
+
182
+ ```ts
183
+ await user.logOut()
184
+ ```
185
+
186
+ Invia `DELETE /auth/session` con refresh token e pulisce la sessione locale.
187
+
188
+ ## Tipi esportati
189
+
190
+ - `AppConfig`
191
+ - `CredentialsLike`
192
+ - `UserLike`
193
+ - `MongoClientLike`
194
+ - `CollectionLike`
195
+ - `WatchAsyncIterator`
196
+
197
+ ## Build e test (workspace)
198
+
199
+ ```bash
200
+ npm run build --workspace @flowerforce/flowerbase-client
201
+ npm run test --workspace @flowerforce/flowerbase-client
202
+ ```
203
+
204
+ Oppure dal package:
205
+
206
+ ```bash
207
+ npm run build
208
+ npm test
209
+ ```
package/dist/app.d.ts ADDED
@@ -0,0 +1,85 @@
1
+ import { AppConfig, CredentialsLike, ProfileData, SessionData } from './types';
2
+ import { Credentials } from './credentials';
3
+ import { User } from './user';
4
+ export declare class App {
5
+ private static readonly appCache;
6
+ static readonly Credentials: typeof Credentials;
7
+ readonly id: string;
8
+ readonly baseUrl: string;
9
+ readonly timeout: number;
10
+ private readonly sessionManager;
11
+ private readonly usersById;
12
+ private readonly sessionsByUserId;
13
+ private usersOrder;
14
+ private readonly profilesByUserId;
15
+ private readonly sessionBootstrapPromise;
16
+ private readonly listeners;
17
+ emailPasswordAuth: {
18
+ registerUser: (input: {
19
+ email: string;
20
+ password: string;
21
+ }) => Promise<unknown>;
22
+ confirmUser: (input: {
23
+ token: string;
24
+ tokenId: string;
25
+ }) => Promise<unknown>;
26
+ resendConfirmationEmail: (input: {
27
+ email: string;
28
+ }) => Promise<unknown>;
29
+ retryCustomConfirmation: (input: {
30
+ email: string;
31
+ }) => Promise<unknown>;
32
+ sendResetPasswordEmail: (input: {
33
+ email: string;
34
+ } | string) => Promise<unknown>;
35
+ callResetPasswordFunction: (input: {
36
+ email: string;
37
+ password: string;
38
+ } | string, passwordOrArg?: string, ...args: unknown[]) => Promise<unknown>;
39
+ resetPassword: (input: {
40
+ token: string;
41
+ tokenId: string;
42
+ password: string;
43
+ }) => Promise<unknown>;
44
+ };
45
+ constructor(idOrConfig: string | AppConfig);
46
+ static getApp(appIdOrConfig: string | AppConfig): App;
47
+ get currentUser(): User | null;
48
+ get allUsers(): Readonly<Record<string, User>>;
49
+ private persistSessionsByUser;
50
+ private persistUsersOrder;
51
+ private touchUser;
52
+ private removeUserFromOrder;
53
+ private setSessionForUser;
54
+ private clearSessionForUser;
55
+ private setCurrentSessionFromOrder;
56
+ private notifyListeners;
57
+ private providerUrl;
58
+ private authUrl;
59
+ private functionsUrl;
60
+ private createSession;
61
+ private bootstrapSessionOnLoad;
62
+ private ensureSessionBootstrapped;
63
+ private setLoggedInUser;
64
+ private getOrCreateUser;
65
+ logIn(credentials: CredentialsLike): Promise<User>;
66
+ switchUser(nextUser: User): void;
67
+ removeUser(user: User): Promise<void>;
68
+ deleteUser(user: User): Promise<void>;
69
+ getSessionOrThrow(userId?: string): SessionData;
70
+ getSession(userId?: string): SessionData | null;
71
+ hasUser(userId: string): boolean;
72
+ getProfileSnapshot(userId: string): ProfileData | undefined;
73
+ postProvider<T = unknown>(path: string, body: unknown): Promise<T>;
74
+ private requestWithAccessToken;
75
+ callFunction(name: string, args: unknown[], userId?: string): Promise<any>;
76
+ callFunctionStreaming(name: string, args: unknown[], userId?: string): Promise<AsyncIterable<Uint8Array>>;
77
+ callService(name: string, args: unknown[], service?: string, userId?: string): Promise<unknown>;
78
+ getProfile(userId?: string): Promise<ProfileData>;
79
+ refreshAccessToken(userId?: string): Promise<string>;
80
+ logoutUser(userId?: string): Promise<void>;
81
+ addListener(callback: () => void): void;
82
+ removeListener(callback: () => void): void;
83
+ removeAllListeners(): void;
84
+ }
85
+ //# sourceMappingURL=app.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":"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"}