@flowerforce/flowerbase-client 0.3.1-beta.0 → 0.3.1-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/app.d.ts +2 -2
- package/dist/app.d.ts.map +1 -1
- package/dist/app.js +19 -8
- package/dist/mongo.d.ts +2 -2
- package/dist/mongo.d.ts.map +1 -1
- package/dist/session.d.ts.map +1 -1
- package/dist/types.d.ts +23 -2
- package/dist/types.d.ts.map +1 -1
- package/dist/user.d.ts +2 -2
- package/dist/user.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/__tests__/functions.test.ts +1 -1
- package/src/__tests__/mongo.test.ts +4 -4
- package/src/app.ts +94 -44
- package/src/mongo.ts +2 -2
- package/src/session.ts +1 -1
- package/src/types.ts +31 -5
- package/src/user.ts +2 -2
package/dist/app.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { AppConfig, CredentialsLike, ProfileData, SessionData } from './types';
|
|
2
1
|
import { Credentials } from './credentials';
|
|
2
|
+
import { AppConfig, CredentialsLike, MongoDbServiceArguments, MongoDbServiceName, ProfileData, SessionData } from './types';
|
|
3
3
|
import { User } from './user';
|
|
4
4
|
export declare class App {
|
|
5
5
|
private static readonly appCache;
|
|
@@ -76,7 +76,7 @@ export declare class App {
|
|
|
76
76
|
private requestWithAccessToken;
|
|
77
77
|
callFunction(name: string, args: unknown[], userId?: string): Promise<any>;
|
|
78
78
|
callFunctionStreaming(name: string, args: unknown[], userId?: string): Promise<AsyncIterable<Uint8Array>>;
|
|
79
|
-
callService(name: string, args:
|
|
79
|
+
callService(name: string, args: MongoDbServiceArguments, service?: MongoDbServiceName, userId?: string): Promise<unknown>;
|
|
80
80
|
getProfile(userId?: string): Promise<ProfileData>;
|
|
81
81
|
refreshAccessToken(userId?: string): Promise<string>;
|
|
82
82
|
logoutUser(userId?: string): Promise<void>;
|
package/dist/app.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":"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"}
|
package/dist/app.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.App = void 0;
|
|
4
|
+
const credentials_1 = require("./credentials");
|
|
4
5
|
const functions_1 = require("./functions");
|
|
5
6
|
const http_1 = require("./http");
|
|
6
7
|
const session_1 = require("./session");
|
|
7
|
-
const credentials_1 = require("./credentials");
|
|
8
8
|
const user_1 = require("./user");
|
|
9
9
|
const API_PREFIX = '/api/client/v2.0';
|
|
10
10
|
class App {
|
|
@@ -79,7 +79,10 @@ class App {
|
|
|
79
79
|
loggedOutUsers.push(userId);
|
|
80
80
|
}
|
|
81
81
|
}
|
|
82
|
-
const users = Object.fromEntries([...activeUsers, ...loggedOutUsers].map((userId) => [
|
|
82
|
+
const users = Object.fromEntries([...activeUsers, ...loggedOutUsers].map((userId) => [
|
|
83
|
+
userId,
|
|
84
|
+
this.usersById.get(userId)
|
|
85
|
+
]));
|
|
83
86
|
return users;
|
|
84
87
|
}
|
|
85
88
|
persistSessionsByUser() {
|
|
@@ -244,7 +247,9 @@ class App {
|
|
|
244
247
|
return this.setLoggedInUser(result, 'custom-function');
|
|
245
248
|
}
|
|
246
249
|
if (credentials.provider === 'custom-token') {
|
|
247
|
-
const result = await this.postProvider('/custom-token/login', {
|
|
250
|
+
const result = await this.postProvider('/custom-token/login', {
|
|
251
|
+
token: credentials.token
|
|
252
|
+
});
|
|
248
253
|
return this.setLoggedInUser(result, 'custom-token');
|
|
249
254
|
}
|
|
250
255
|
const unsupportedProvider = credentials;
|
|
@@ -288,7 +293,9 @@ class App {
|
|
|
288
293
|
}
|
|
289
294
|
getSessionOrThrow(userId) {
|
|
290
295
|
const targetUserId = userId ?? this.currentUser?.id;
|
|
291
|
-
const session = targetUserId
|
|
296
|
+
const session = targetUserId
|
|
297
|
+
? this.sessionsByUserId.get(targetUserId)
|
|
298
|
+
: this.sessionManager.get();
|
|
292
299
|
if (!session) {
|
|
293
300
|
throw new Error('User is not authenticated');
|
|
294
301
|
}
|
|
@@ -335,7 +342,7 @@ class App {
|
|
|
335
342
|
arguments: args
|
|
336
343
|
};
|
|
337
344
|
const result = await this.requestWithAccessToken((accessToken) => (0, http_1.requestJson)({
|
|
338
|
-
url: this.functionsUrl(
|
|
345
|
+
url: this.functionsUrl(`/call?func=${name}`),
|
|
339
346
|
method: 'POST',
|
|
340
347
|
body: payload,
|
|
341
348
|
bearerToken: accessToken,
|
|
@@ -369,7 +376,9 @@ class App {
|
|
|
369
376
|
});
|
|
370
377
|
}
|
|
371
378
|
catch (error) {
|
|
372
|
-
if (!didRefresh &&
|
|
379
|
+
if (!didRefresh &&
|
|
380
|
+
error instanceof http_1.FlowerbaseHttpError &&
|
|
381
|
+
error.status === 401) {
|
|
373
382
|
await refreshSession();
|
|
374
383
|
didRefresh = true;
|
|
375
384
|
continue;
|
|
@@ -383,7 +392,9 @@ class App {
|
|
|
383
392
|
return;
|
|
384
393
|
}
|
|
385
394
|
catch (error) {
|
|
386
|
-
if (!didRefresh &&
|
|
395
|
+
if (!didRefresh &&
|
|
396
|
+
error instanceof http_1.FlowerbaseHttpError &&
|
|
397
|
+
error.status === 401) {
|
|
387
398
|
await refreshSession();
|
|
388
399
|
didRefresh = true;
|
|
389
400
|
continue;
|
|
@@ -402,7 +413,7 @@ class App {
|
|
|
402
413
|
arguments: args
|
|
403
414
|
};
|
|
404
415
|
return this.requestWithAccessToken((accessToken) => (0, http_1.requestJson)({
|
|
405
|
-
url: this.functionsUrl(
|
|
416
|
+
url: this.functionsUrl(`/call?col=${args[0].collection}-${name}`),
|
|
406
417
|
method: 'POST',
|
|
407
418
|
body: payload,
|
|
408
419
|
bearerToken: accessToken,
|
package/dist/mongo.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import type { App } from './app';
|
|
2
|
-
import { MongoClientLike } from './types';
|
|
3
|
-
export declare const createMongoClient: (app: App, serviceName:
|
|
2
|
+
import { MongoClientLike, MongoDbServiceName } from './types';
|
|
3
|
+
export declare const createMongoClient: (app: App, serviceName: MongoDbServiceName, userId: string) => MongoClientLike;
|
|
4
4
|
//# sourceMappingURL=mongo.d.ts.map
|
package/dist/mongo.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mongo.d.ts","sourceRoot":"","sources":["../src/mongo.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,OAAO,CAAA;AAEhC,OAAO,EAAkB,eAAe,EAAE,MAAM,SAAS,CAAA;
|
|
1
|
+
{"version":3,"file":"mongo.d.ts","sourceRoot":"","sources":["../src/mongo.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,OAAO,CAAA;AAEhC,OAAO,EAAkB,eAAe,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAA;AAoB7E,eAAO,MAAM,iBAAiB,QAAS,GAAG,eAAe,kBAAkB,UAAU,MAAM,KAAG,eAyF5F,CAAA"}
|
package/dist/session.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../src/session.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../src/session.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,SAAS,CAAA;AA+CrC,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAQ;IAC5B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAQ;IACjC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAQ;IACpC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAkB;IAC1C,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAe;IAChD,OAAO,CAAC,OAAO,CAA2B;IAC1C,OAAO,CAAC,UAAU,CAAe;IACjC,OAAO,CAAC,cAAc,CAAkC;gBAE5C,KAAK,EAAE,MAAM;YAUX,OAAO;IAOrB,SAAS;IAIT,oBAAoB;IAIpB,GAAG;IAIH,GAAG,CAAC,OAAO,EAAE,WAAW;IAKxB,KAAK;IAKL,aAAa;IAIb,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE;IAS7B,iBAAiB;;;IAIjB,iBAAiB,CAAC,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC;CAQ9D"}
|
package/dist/types.d.ts
CHANGED
|
@@ -28,10 +28,31 @@ export type ProfileData = {
|
|
|
28
28
|
custom_data?: Record<string, unknown>;
|
|
29
29
|
data?: Record<string, unknown>;
|
|
30
30
|
};
|
|
31
|
+
export type MongoDbDocument = Record<string, unknown>;
|
|
32
|
+
export type MongoDbServiceName = 'mongodb-atlas';
|
|
33
|
+
export type MongoDbServiceArgument = {
|
|
34
|
+
database: string;
|
|
35
|
+
collection: string;
|
|
36
|
+
query?: MongoDbDocument;
|
|
37
|
+
filter?: MongoDbDocument;
|
|
38
|
+
update?: MongoDbDocument | MongoDbDocument[];
|
|
39
|
+
projection?: MongoDbDocument;
|
|
40
|
+
options?: MongoDbDocument;
|
|
41
|
+
returnNewDocument?: boolean;
|
|
42
|
+
document?: MongoDbDocument;
|
|
43
|
+
documents?: MongoDbDocument[];
|
|
44
|
+
pipeline?: MongoDbDocument[];
|
|
45
|
+
replacement?: MongoDbDocument;
|
|
46
|
+
};
|
|
47
|
+
export type MongoDbServiceArguments = [MongoDbServiceArgument];
|
|
31
48
|
export type FunctionCallPayload = {
|
|
32
49
|
name: string;
|
|
33
50
|
arguments: unknown[];
|
|
34
|
-
service?:
|
|
51
|
+
service?: undefined;
|
|
52
|
+
} | {
|
|
53
|
+
name: string;
|
|
54
|
+
arguments: MongoDbServiceArguments;
|
|
55
|
+
service: MongoDbServiceName;
|
|
35
56
|
};
|
|
36
57
|
export type WatchConfig = {
|
|
37
58
|
appId: string;
|
|
@@ -89,7 +110,7 @@ export interface UserLike {
|
|
|
89
110
|
callFunction: (name: string, ...args: unknown[]) => Promise<unknown>;
|
|
90
111
|
refreshAccessToken: () => Promise<string>;
|
|
91
112
|
refreshCustomData: () => Promise<Record<string, unknown>>;
|
|
92
|
-
mongoClient: (serviceName:
|
|
113
|
+
mongoClient: (serviceName: MongoDbServiceName) => MongoClientLike;
|
|
93
114
|
addListener: (callback: () => void) => void;
|
|
94
115
|
removeListener: (callback: () => void) => void;
|
|
95
116
|
removeAllListeners: () => void;
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,SAAS,GAAG;IACtB,EAAE,EAAE,MAAM,CAAA;IACV,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB,CAAA;AAED,MAAM,MAAM,eAAe,GACvB;IAAE,QAAQ,EAAE,gBAAgB,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAC/D;IAAE,QAAQ,EAAE,WAAW,CAAA;CAAE,GACzB;IAAE,QAAQ,EAAE,iBAAiB,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,GACjE;IAAE,QAAQ,EAAE,cAAc,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAA;AAE/C,MAAM,MAAM,WAAW,GAAG;IACxB,WAAW,EAAE,MAAM,CAAA;IACnB,YAAY,EAAE,MAAM,CAAA;IACpB,MAAM,EAAE,MAAM,CAAA;CACf,CAAA;AAED,MAAM,MAAM,WAAW,GAAG;IACxB,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,UAAU,CAAC,EAAE,OAAO,EAAE,CAAA;IACtB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IACrC,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAC/B,CAAA;AAED,MAAM,MAAM,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/user.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { App } from './app';
|
|
2
|
-
import { MongoClientLike, UserLike } from './types';
|
|
2
|
+
import { MongoClientLike, MongoDbServiceName, UserLike } from './types';
|
|
3
3
|
export declare class User implements UserLike {
|
|
4
4
|
readonly id: string;
|
|
5
5
|
customData: Record<string, unknown>;
|
|
@@ -28,7 +28,7 @@ export declare class User implements UserLike {
|
|
|
28
28
|
callFunction(name: string, ...args: unknown[]): Promise<any>;
|
|
29
29
|
refreshAccessToken(): Promise<string>;
|
|
30
30
|
refreshCustomData(): Promise<Record<string, unknown>>;
|
|
31
|
-
mongoClient(serviceName:
|
|
31
|
+
mongoClient(serviceName: MongoDbServiceName): MongoClientLike;
|
|
32
32
|
addListener(callback: () => void): void;
|
|
33
33
|
removeListener(callback: () => void): void;
|
|
34
34
|
removeAllListeners(): void;
|
package/dist/user.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"user.d.ts","sourceRoot":"","sources":["../src/user.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,OAAO,CAAA;AAGhC,OAAO,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAA;
|
|
1
|
+
{"version":3,"file":"user.d.ts","sourceRoot":"","sources":["../src/user.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,OAAO,CAAA;AAGhC,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAA;AAEvE,qBAAa,IAAK,YAAW,QAAQ;IACnC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAK;IACxC,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAA,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;KAAE,CAAA;IACnD,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAK;IACzB,OAAO,CAAC,aAAa,CAAsB;IAC3C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAwB;IAElD,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC,GAAG;QACpE,YAAY,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,CAAC,OAAO,CAAC,CAAA;QACpE,qBAAqB,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC,CAAA;KAChG,CAAA;gBAEW,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,MAAM;IAUhC,IAAI,KAAK,wCAKR;IAED,IAAI,UAAU,YAEb;IAED,IAAI,YAAY,kBAEf;IAED,IAAI,UAAU,cAEb;IAED,OAAO,CAAC,0BAA0B;IAclC,IAAI,WAAW,kBAId;IAED,IAAI,YAAY,kBAIf;IAED,eAAe,CAAC,YAAY,EAAE,MAAM;IAIpC,OAAO,CAAC,wBAAwB;IAuB1B,MAAM;IAIN,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE;IAI7C,kBAAkB;IAMlB,iBAAiB,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAU3D,WAAW,CAAC,WAAW,EAAE,kBAAkB,GAAG,eAAe;IAI7D,WAAW,CAAC,QAAQ,EAAE,MAAM,IAAI;IAIhC,cAAc,CAAC,QAAQ,EAAE,MAAM,IAAI;IAInC,kBAAkB;IAIlB,eAAe;CAShB"}
|
package/package.json
CHANGED
|
@@ -46,7 +46,7 @@ describe('flowerbase-client functions', () => {
|
|
|
46
46
|
|
|
47
47
|
expect(global.fetch).toHaveBeenNthCalledWith(
|
|
48
48
|
3,
|
|
49
|
-
'http://localhost:3000/api/client/v2.0/app/my-app/functions/call',
|
|
49
|
+
'http://localhost:3000/api/client/v2.0/app/my-app/functions/call?func=sum',
|
|
50
50
|
expect.objectContaining({
|
|
51
51
|
method: 'POST',
|
|
52
52
|
headers: expect.objectContaining({ Authorization: 'Bearer access' })
|
|
@@ -39,14 +39,14 @@ describe('flowerbase-client mongo service wrapper', () => {
|
|
|
39
39
|
|
|
40
40
|
expect((global.fetch as jest.Mock).mock.calls).toHaveLength(8)
|
|
41
41
|
const [url, request] = (global.fetch as jest.Mock).mock.calls[3]
|
|
42
|
-
expect(url).toBe('http://localhost:3000/api/client/v2.0/app/my-app/functions/call')
|
|
42
|
+
expect(url).toBe('http://localhost:3000/api/client/v2.0/app/my-app/functions/call?col=todos-findOne')
|
|
43
43
|
expect(request.method).toBe('POST')
|
|
44
44
|
const parsed = JSON.parse(request.body)
|
|
45
45
|
expect(parsed.service).toBe('mongodb-atlas')
|
|
46
46
|
expect(parsed.name).toBe('findOne')
|
|
47
47
|
})
|
|
48
48
|
|
|
49
|
-
it('supports extended CRUD operations
|
|
49
|
+
it('supports extended CRUD operations on mongodb-atlas', async () => {
|
|
50
50
|
global.fetch = jest
|
|
51
51
|
.fn()
|
|
52
52
|
.mockResolvedValueOnce({
|
|
@@ -65,7 +65,7 @@ describe('flowerbase-client mongo service wrapper', () => {
|
|
|
65
65
|
const app = new App({ id: 'my-app', baseUrl: 'http://localhost:3000' })
|
|
66
66
|
await app.logIn(Credentials.emailPassword('john@doe.com', 'secret123'))
|
|
67
67
|
|
|
68
|
-
const collection = app.currentUser!.mongoClient('
|
|
68
|
+
const collection = app.currentUser!.mongoClient('mongodb-atlas').db('testdb').collection('todos')
|
|
69
69
|
|
|
70
70
|
await collection.findOneAndUpdate({ done: false }, { $set: { done: true } })
|
|
71
71
|
await collection.findOneAndReplace({ done: true }, { done: true, title: 'done' })
|
|
@@ -77,7 +77,7 @@ describe('flowerbase-client mongo service wrapper', () => {
|
|
|
77
77
|
|
|
78
78
|
const calls = (global.fetch as jest.Mock).mock.calls
|
|
79
79
|
const lastBody = JSON.parse(calls[calls.length - 1][1].body)
|
|
80
|
-
expect(lastBody.service).toBe('
|
|
80
|
+
expect(lastBody.service).toBe('mongodb-atlas')
|
|
81
81
|
expect(lastBody.name).toBe('deleteMany')
|
|
82
82
|
})
|
|
83
83
|
})
|
package/src/app.ts
CHANGED
|
@@ -1,8 +1,16 @@
|
|
|
1
|
+
import { Credentials } from './credentials'
|
|
1
2
|
import { normalizeFunctionResponse } from './functions'
|
|
2
3
|
import { FlowerbaseHttpError, requestJson, requestStream } from './http'
|
|
3
4
|
import { SessionManager } from './session'
|
|
4
|
-
import {
|
|
5
|
-
|
|
5
|
+
import {
|
|
6
|
+
AppConfig,
|
|
7
|
+
CredentialsLike,
|
|
8
|
+
FunctionCallPayload,
|
|
9
|
+
MongoDbServiceArguments,
|
|
10
|
+
MongoDbServiceName,
|
|
11
|
+
ProfileData,
|
|
12
|
+
SessionData
|
|
13
|
+
} from './types'
|
|
6
14
|
import { User } from './user'
|
|
7
15
|
|
|
8
16
|
const API_PREFIX = '/api/client/v2.0'
|
|
@@ -43,7 +51,11 @@ export class App {
|
|
|
43
51
|
passwordOrArg?: string,
|
|
44
52
|
...args: unknown[]
|
|
45
53
|
) => Promise<unknown>
|
|
46
|
-
resetPassword: (input: {
|
|
54
|
+
resetPassword: (input: {
|
|
55
|
+
token: string
|
|
56
|
+
tokenId: string
|
|
57
|
+
password: string
|
|
58
|
+
}) => Promise<unknown>
|
|
47
59
|
}
|
|
48
60
|
|
|
49
61
|
constructor(idOrConfig: string | AppConfig) {
|
|
@@ -123,13 +135,18 @@ export class App {
|
|
|
123
135
|
}
|
|
124
136
|
|
|
125
137
|
const users = Object.fromEntries(
|
|
126
|
-
[...activeUsers, ...loggedOutUsers].map((userId) => [
|
|
138
|
+
[...activeUsers, ...loggedOutUsers].map((userId) => [
|
|
139
|
+
userId,
|
|
140
|
+
this.usersById.get(userId)!
|
|
141
|
+
])
|
|
127
142
|
)
|
|
128
143
|
return users
|
|
129
144
|
}
|
|
130
145
|
|
|
131
146
|
private persistSessionsByUser() {
|
|
132
|
-
this.sessionManager.setSessionsByUser(
|
|
147
|
+
this.sessionManager.setSessionsByUser(
|
|
148
|
+
Object.fromEntries(this.sessionsByUserId.entries())
|
|
149
|
+
)
|
|
133
150
|
}
|
|
134
151
|
|
|
135
152
|
private persistUsersOrder() {
|
|
@@ -314,17 +331,24 @@ export class App {
|
|
|
314
331
|
}
|
|
315
332
|
|
|
316
333
|
if (credentials.provider === 'custom-function') {
|
|
317
|
-
const result = await this.postProvider<LoginResponse>(
|
|
334
|
+
const result = await this.postProvider<LoginResponse>(
|
|
335
|
+
'/custom-function/login',
|
|
336
|
+
credentials.payload
|
|
337
|
+
)
|
|
318
338
|
return this.setLoggedInUser(result, 'custom-function')
|
|
319
339
|
}
|
|
320
340
|
|
|
321
341
|
if (credentials.provider === 'custom-token') {
|
|
322
|
-
const result = await this.postProvider<LoginResponse>('/custom-token/login', {
|
|
342
|
+
const result = await this.postProvider<LoginResponse>('/custom-token/login', {
|
|
343
|
+
token: credentials.token
|
|
344
|
+
})
|
|
323
345
|
return this.setLoggedInUser(result, 'custom-token')
|
|
324
346
|
}
|
|
325
347
|
|
|
326
348
|
const unsupportedProvider: never = credentials
|
|
327
|
-
throw new Error(
|
|
349
|
+
throw new Error(
|
|
350
|
+
`Unsupported credentials provider: ${JSON.stringify(unsupportedProvider)}`
|
|
351
|
+
)
|
|
328
352
|
}
|
|
329
353
|
|
|
330
354
|
switchUser(nextUser: User) {
|
|
@@ -357,13 +381,14 @@ export class App {
|
|
|
357
381
|
}
|
|
358
382
|
|
|
359
383
|
async deleteUser(user: User) {
|
|
360
|
-
await this.requestWithAccessToken(
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
384
|
+
await this.requestWithAccessToken(
|
|
385
|
+
(accessToken) =>
|
|
386
|
+
requestJson({
|
|
387
|
+
url: this.authUrl('/delete'),
|
|
388
|
+
method: 'DELETE',
|
|
389
|
+
bearerToken: accessToken,
|
|
390
|
+
timeout: this.timeout
|
|
391
|
+
}),
|
|
367
392
|
user.id
|
|
368
393
|
)
|
|
369
394
|
await this.removeUser(user)
|
|
@@ -371,7 +396,9 @@ export class App {
|
|
|
371
396
|
|
|
372
397
|
getSessionOrThrow(userId?: string) {
|
|
373
398
|
const targetUserId = userId ?? this.currentUser?.id
|
|
374
|
-
const session = targetUserId
|
|
399
|
+
const session = targetUserId
|
|
400
|
+
? this.sessionsByUserId.get(targetUserId)
|
|
401
|
+
: this.sessionManager.get()
|
|
375
402
|
if (!session) {
|
|
376
403
|
throw new Error('User is not authenticated')
|
|
377
404
|
}
|
|
@@ -402,7 +429,10 @@ export class App {
|
|
|
402
429
|
})
|
|
403
430
|
}
|
|
404
431
|
|
|
405
|
-
private async requestWithAccessToken<T>(
|
|
432
|
+
private async requestWithAccessToken<T>(
|
|
433
|
+
operation: (accessToken: string) => Promise<T>,
|
|
434
|
+
userId?: string
|
|
435
|
+
) {
|
|
406
436
|
const firstSession = this.getSessionOrThrow(userId)
|
|
407
437
|
try {
|
|
408
438
|
return await operation(firstSession.accessToken)
|
|
@@ -423,21 +453,26 @@ export class App {
|
|
|
423
453
|
arguments: args
|
|
424
454
|
}
|
|
425
455
|
|
|
426
|
-
const result = await this.requestWithAccessToken(
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
456
|
+
const result = await this.requestWithAccessToken(
|
|
457
|
+
(accessToken) =>
|
|
458
|
+
requestJson<unknown>({
|
|
459
|
+
url: this.functionsUrl(`/call?func=${name}`),
|
|
460
|
+
method: 'POST',
|
|
461
|
+
body: payload,
|
|
462
|
+
bearerToken: accessToken,
|
|
463
|
+
timeout: this.timeout
|
|
464
|
+
}),
|
|
434
465
|
userId
|
|
435
466
|
)
|
|
436
467
|
|
|
437
468
|
return normalizeFunctionResponse(result)
|
|
438
469
|
}
|
|
439
470
|
|
|
440
|
-
async callFunctionStreaming(
|
|
471
|
+
async callFunctionStreaming(
|
|
472
|
+
name: string,
|
|
473
|
+
args: unknown[],
|
|
474
|
+
userId?: string
|
|
475
|
+
): Promise<AsyncIterable<Uint8Array>> {
|
|
441
476
|
await this.ensureSessionBootstrapped()
|
|
442
477
|
const payload: FunctionCallPayload = {
|
|
443
478
|
name,
|
|
@@ -464,7 +499,11 @@ export class App {
|
|
|
464
499
|
timeout
|
|
465
500
|
})
|
|
466
501
|
} catch (error) {
|
|
467
|
-
if (
|
|
502
|
+
if (
|
|
503
|
+
!didRefresh &&
|
|
504
|
+
error instanceof FlowerbaseHttpError &&
|
|
505
|
+
error.status === 401
|
|
506
|
+
) {
|
|
468
507
|
await refreshSession()
|
|
469
508
|
didRefresh = true
|
|
470
509
|
continue
|
|
@@ -478,7 +517,11 @@ export class App {
|
|
|
478
517
|
}
|
|
479
518
|
return
|
|
480
519
|
} catch (error) {
|
|
481
|
-
if (
|
|
520
|
+
if (
|
|
521
|
+
!didRefresh &&
|
|
522
|
+
error instanceof FlowerbaseHttpError &&
|
|
523
|
+
error.status === 401
|
|
524
|
+
) {
|
|
482
525
|
await refreshSession()
|
|
483
526
|
didRefresh = true
|
|
484
527
|
continue
|
|
@@ -490,7 +533,12 @@ export class App {
|
|
|
490
533
|
}
|
|
491
534
|
}
|
|
492
535
|
|
|
493
|
-
async callService(
|
|
536
|
+
async callService(
|
|
537
|
+
name: string,
|
|
538
|
+
args: MongoDbServiceArguments,
|
|
539
|
+
service: MongoDbServiceName = 'mongodb-atlas',
|
|
540
|
+
userId?: string
|
|
541
|
+
) {
|
|
494
542
|
await this.ensureSessionBootstrapped()
|
|
495
543
|
const payload: FunctionCallPayload = {
|
|
496
544
|
name,
|
|
@@ -498,27 +546,29 @@ export class App {
|
|
|
498
546
|
arguments: args
|
|
499
547
|
}
|
|
500
548
|
|
|
501
|
-
return this.requestWithAccessToken(
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
549
|
+
return this.requestWithAccessToken(
|
|
550
|
+
(accessToken) =>
|
|
551
|
+
requestJson<unknown>({
|
|
552
|
+
url: this.functionsUrl(`/call?col=${args[0].collection}-${name}`),
|
|
553
|
+
method: 'POST',
|
|
554
|
+
body: payload,
|
|
555
|
+
bearerToken: accessToken,
|
|
556
|
+
timeout: this.timeout
|
|
557
|
+
}),
|
|
509
558
|
userId
|
|
510
559
|
)
|
|
511
560
|
}
|
|
512
561
|
|
|
513
562
|
async getProfile(userId?: string): Promise<ProfileData> {
|
|
514
563
|
await this.ensureSessionBootstrapped()
|
|
515
|
-
const profile = await this.requestWithAccessToken(
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
564
|
+
const profile = await this.requestWithAccessToken(
|
|
565
|
+
(accessToken) =>
|
|
566
|
+
requestJson<ProfileData>({
|
|
567
|
+
url: this.authUrl('/profile'),
|
|
568
|
+
method: 'GET',
|
|
569
|
+
bearerToken: accessToken,
|
|
570
|
+
timeout: this.timeout
|
|
571
|
+
}),
|
|
522
572
|
userId
|
|
523
573
|
)
|
|
524
574
|
const session = this.getSessionOrThrow(userId)
|
package/src/mongo.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { App } from './app'
|
|
2
2
|
import { EJSON } from './bson'
|
|
3
|
-
import { CollectionLike, MongoClientLike } from './types'
|
|
3
|
+
import { CollectionLike, MongoClientLike, MongoDbServiceName } from './types'
|
|
4
4
|
import { createWatchIterator } from './watch'
|
|
5
5
|
|
|
6
6
|
const serialize = (value: unknown) => EJSON.serialize(value, { relaxed: false })
|
|
@@ -20,7 +20,7 @@ const mapResult = (value: unknown) => {
|
|
|
20
20
|
return deserialize(value)
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
-
export const createMongoClient = (app: App, serviceName:
|
|
23
|
+
export const createMongoClient = (app: App, serviceName: MongoDbServiceName, userId: string): MongoClientLike => ({
|
|
24
24
|
db: (database: string) => ({
|
|
25
25
|
collection: (collection: string): CollectionLike => {
|
|
26
26
|
const callService = async (name: string, args: unknown[]) => {
|
package/src/session.ts
CHANGED
package/src/types.ts
CHANGED
|
@@ -24,12 +24,38 @@ export type ProfileData = {
|
|
|
24
24
|
data?: Record<string, unknown>
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
export type
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
27
|
+
export type MongoDbDocument = Record<string, unknown>
|
|
28
|
+
export type MongoDbServiceName = 'mongodb-atlas'
|
|
29
|
+
|
|
30
|
+
export type MongoDbServiceArgument = {
|
|
31
|
+
database: string
|
|
32
|
+
collection: string
|
|
33
|
+
query?: MongoDbDocument
|
|
34
|
+
filter?: MongoDbDocument
|
|
35
|
+
update?: MongoDbDocument | MongoDbDocument[]
|
|
36
|
+
projection?: MongoDbDocument
|
|
37
|
+
options?: MongoDbDocument
|
|
38
|
+
returnNewDocument?: boolean
|
|
39
|
+
document?: MongoDbDocument
|
|
40
|
+
documents?: MongoDbDocument[]
|
|
41
|
+
pipeline?: MongoDbDocument[]
|
|
42
|
+
replacement?: MongoDbDocument
|
|
31
43
|
}
|
|
32
44
|
|
|
45
|
+
export type MongoDbServiceArguments = [MongoDbServiceArgument]
|
|
46
|
+
|
|
47
|
+
export type FunctionCallPayload =
|
|
48
|
+
| {
|
|
49
|
+
name: string
|
|
50
|
+
arguments: unknown[]
|
|
51
|
+
service?: undefined
|
|
52
|
+
}
|
|
53
|
+
| {
|
|
54
|
+
name: string
|
|
55
|
+
arguments: MongoDbServiceArguments
|
|
56
|
+
service: MongoDbServiceName
|
|
57
|
+
}
|
|
58
|
+
|
|
33
59
|
export type WatchConfig = {
|
|
34
60
|
appId: string
|
|
35
61
|
baseUrl: string
|
|
@@ -107,7 +133,7 @@ export interface UserLike {
|
|
|
107
133
|
callFunction: (name: string, ...args: unknown[]) => Promise<unknown>
|
|
108
134
|
refreshAccessToken: () => Promise<string>
|
|
109
135
|
refreshCustomData: () => Promise<Record<string, unknown>>
|
|
110
|
-
mongoClient: (serviceName:
|
|
136
|
+
mongoClient: (serviceName: MongoDbServiceName) => MongoClientLike
|
|
111
137
|
addListener: (callback: () => void) => void
|
|
112
138
|
removeListener: (callback: () => void) => void
|
|
113
139
|
removeAllListeners: () => void
|
package/src/user.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { App } from './app'
|
|
2
2
|
import { createFunctionsProxy } from './functions'
|
|
3
3
|
import { createMongoClient } from './mongo'
|
|
4
|
-
import { MongoClientLike, UserLike } from './types'
|
|
4
|
+
import { MongoClientLike, MongoDbServiceName, UserLike } from './types'
|
|
5
5
|
|
|
6
6
|
export class User implements UserLike {
|
|
7
7
|
readonly id: string
|
|
@@ -122,7 +122,7 @@ export class User implements UserLike {
|
|
|
122
122
|
return this.customData
|
|
123
123
|
}
|
|
124
124
|
|
|
125
|
-
mongoClient(serviceName:
|
|
125
|
+
mongoClient(serviceName: MongoDbServiceName): MongoClientLike {
|
|
126
126
|
return createMongoClient(this.app, serviceName, this.id)
|
|
127
127
|
}
|
|
128
128
|
|