@livequery/nestjs 1.0.38 → 1.0.41
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/build/index.d.ts +4 -2
- package/build/index.js +9 -2
- package/build/src/LivequeryDatasourceInterceptors.d.ts +16 -0
- package/build/src/LivequeryDatasourceInterceptors.js +35 -0
- package/build/src/LivequeryInterceptor.d.ts +9 -4
- package/build/src/LivequeryInterceptor.js +21 -11
- package/build/src/LivequeryWebsocketSync.d.ts +11 -4
- package/build/src/LivequeryWebsocketSync.js +51 -28
- package/build/src/PathHelper.d.ts +3 -3
- package/build/src/PathHelper.js +22 -6
- package/build/src/UseWebsocketShareKeyPair.d.ts +5 -0
- package/build/src/UseWebsocketShareKeyPair.js +20 -0
- package/build/src/createDatasourceMapper.d.ts +6 -0
- package/build/src/createDatasourceMapper.js +32 -0
- package/build/src/helpers/PathHelper.d.ts +11 -0
- package/build/src/helpers/PathHelper.js +44 -0
- package/build/src/helpers/createDatasourceMapper.d.ts +6 -0
- package/build/src/helpers/createDatasourceMapper.js +32 -0
- package/package.json +14 -10
- package/build/src/UseDatasource.d.ts +0 -28
- package/build/src/UseDatasource.js +0 -59
package/build/index.d.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
export
|
|
1
|
+
export { LivequeryRequest } from './src/LivequeryRequest';
|
|
2
2
|
export * from './src/LivequeryResponse';
|
|
3
3
|
export * from './src/LivequeryInterceptor';
|
|
4
4
|
export * from './src/LivequeryWebsocketSync';
|
|
5
|
-
export * from './src/
|
|
5
|
+
export * from './src/helpers/createDatasourceMapper';
|
|
6
|
+
export { LivequeryDatasourceInterceptors } from './src/LivequeryDatasourceInterceptors';
|
|
7
|
+
export { UseWebsocketPublicKey, UseWebsocketPrivateKey } from './src/UseWebsocketShareKeyPair';
|
package/build/index.js
CHANGED
|
@@ -14,8 +14,15 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
|
|
17
|
+
exports.UseWebsocketPrivateKey = exports.UseWebsocketPublicKey = exports.LivequeryDatasourceInterceptors = exports.LivequeryRequest = void 0;
|
|
18
|
+
var LivequeryRequest_1 = require("./src/LivequeryRequest");
|
|
19
|
+
Object.defineProperty(exports, "LivequeryRequest", { enumerable: true, get: function () { return LivequeryRequest_1.LivequeryRequest; } });
|
|
18
20
|
__exportStar(require("./src/LivequeryResponse"), exports);
|
|
19
21
|
__exportStar(require("./src/LivequeryInterceptor"), exports);
|
|
20
22
|
__exportStar(require("./src/LivequeryWebsocketSync"), exports);
|
|
21
|
-
__exportStar(require("./src/
|
|
23
|
+
__exportStar(require("./src/helpers/createDatasourceMapper"), exports);
|
|
24
|
+
var LivequeryDatasourceInterceptors_1 = require("./src/LivequeryDatasourceInterceptors");
|
|
25
|
+
Object.defineProperty(exports, "LivequeryDatasourceInterceptors", { enumerable: true, get: function () { return LivequeryDatasourceInterceptors_1.LivequeryDatasourceInterceptors; } });
|
|
26
|
+
var UseWebsocketShareKeyPair_1 = require("./src/UseWebsocketShareKeyPair");
|
|
27
|
+
Object.defineProperty(exports, "UseWebsocketPublicKey", { enumerable: true, get: function () { return UseWebsocketShareKeyPair_1.UseWebsocketPublicKey; } });
|
|
28
|
+
Object.defineProperty(exports, "UseWebsocketPrivateKey", { enumerable: true, get: function () { return UseWebsocketShareKeyPair_1.UseWebsocketPrivateKey; } });
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { CallHandler, ExecutionContext, NestInterceptor } from '@nestjs/common';
|
|
2
|
+
import { LivequeryRequest } from '@livequery/types';
|
|
3
|
+
import { ModuleRef } from '@nestjs/core';
|
|
4
|
+
export declare type DatasourceOptions<T> = Array<T & {
|
|
5
|
+
refs: string[];
|
|
6
|
+
}>;
|
|
7
|
+
export declare type Datasource<T = any> = {
|
|
8
|
+
query(query: LivequeryRequest): any;
|
|
9
|
+
};
|
|
10
|
+
export declare const DatasourceList: Map<new (...args: any[]) => Datasource, Datasource<any>>;
|
|
11
|
+
export declare const $__datasource_factory_token: unique symbol;
|
|
12
|
+
export declare class LivequeryDatasourceInterceptors implements NestInterceptor {
|
|
13
|
+
private moduleRef;
|
|
14
|
+
constructor(moduleRef: ModuleRef);
|
|
15
|
+
intercept(ctx: ExecutionContext, next: CallHandler): Promise<import("rxjs").Observable<any>>;
|
|
16
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.LivequeryDatasourceInterceptors = exports.$__datasource_factory_token = exports.DatasourceList = void 0;
|
|
13
|
+
const common_1 = require("@nestjs/common");
|
|
14
|
+
const rxjs_1 = require("rxjs");
|
|
15
|
+
const core_1 = require("@nestjs/core");
|
|
16
|
+
exports.DatasourceList = new Map();
|
|
17
|
+
exports.$__datasource_factory_token = Symbol();
|
|
18
|
+
let LivequeryDatasourceInterceptors = class LivequeryDatasourceInterceptors {
|
|
19
|
+
moduleRef;
|
|
20
|
+
constructor(moduleRef) {
|
|
21
|
+
this.moduleRef = moduleRef;
|
|
22
|
+
}
|
|
23
|
+
async intercept(ctx, next) {
|
|
24
|
+
const token = Reflect.getMetadata(exports.$__datasource_factory_token, ctx.getHandler());
|
|
25
|
+
const datasource = exports.DatasourceList.has(token) ? exports.DatasourceList.get(token) : this.moduleRef.get(token);
|
|
26
|
+
const req = ctx.switchToHttp().getRequest();
|
|
27
|
+
req.livequery_response = await datasource.query(req.livequery);
|
|
28
|
+
return next.handle().pipe((0, rxjs_1.map)(rs => rs ?? req.livequery_response));
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
LivequeryDatasourceInterceptors = __decorate([
|
|
32
|
+
(0, common_1.Injectable)(),
|
|
33
|
+
__metadata("design:paramtypes", [core_1.ModuleRef])
|
|
34
|
+
], LivequeryDatasourceInterceptors);
|
|
35
|
+
exports.LivequeryDatasourceInterceptors = LivequeryDatasourceInterceptors;
|
|
@@ -1,10 +1,15 @@
|
|
|
1
1
|
import { CallHandler, ExecutionContext, NestInterceptor } from "@nestjs/common";
|
|
2
|
-
import { LivequeryWebsocketSync } from
|
|
2
|
+
import { LivequeryWebsocketSync } from "./LivequeryWebsocketSync";
|
|
3
|
+
export declare type RealtimeSubscription = {
|
|
4
|
+
collection_ref: string;
|
|
5
|
+
doc_id: string;
|
|
6
|
+
};
|
|
3
7
|
export declare class LivequeryInterceptor implements NestInterceptor {
|
|
4
8
|
private LivequeryWebsocketSync;
|
|
5
|
-
|
|
6
|
-
|
|
9
|
+
private secret_or_private_key;
|
|
10
|
+
constructor(LivequeryWebsocketSync: LivequeryWebsocketSync, secret_or_private_key: string);
|
|
11
|
+
intercept(context: ExecutionContext, next: CallHandler): Promise<import("rxjs").Observable<{
|
|
7
12
|
data: any;
|
|
8
|
-
}
|
|
13
|
+
}>>;
|
|
9
14
|
}
|
|
10
15
|
export declare const UseLivequeryInterceptor: () => MethodDecorator & ClassDecorator;
|
|
@@ -14,15 +14,19 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
15
|
exports.UseLivequeryInterceptor = exports.LivequeryInterceptor = void 0;
|
|
16
16
|
const common_1 = require("@nestjs/common");
|
|
17
|
-
const LivequeryWebsocketSync_1 = require("./LivequeryWebsocketSync");
|
|
18
17
|
const operators_1 = require("rxjs/operators");
|
|
19
|
-
const PathHelper_1 = require("./PathHelper");
|
|
18
|
+
const PathHelper_1 = require("./helpers/PathHelper");
|
|
19
|
+
const LivequeryWebsocketSync_1 = require("./LivequeryWebsocketSync");
|
|
20
|
+
const UseWebsocketShareKeyPair_1 = require("./UseWebsocketShareKeyPair");
|
|
21
|
+
const JWT = require('jsonwebtoken');
|
|
20
22
|
let LivequeryInterceptor = class LivequeryInterceptor {
|
|
21
23
|
LivequeryWebsocketSync;
|
|
22
|
-
|
|
24
|
+
secret_or_private_key;
|
|
25
|
+
constructor(LivequeryWebsocketSync, secret_or_private_key) {
|
|
23
26
|
this.LivequeryWebsocketSync = LivequeryWebsocketSync;
|
|
27
|
+
this.secret_or_private_key = secret_or_private_key;
|
|
24
28
|
}
|
|
25
|
-
intercept(context, next) {
|
|
29
|
+
async intercept(context, next) {
|
|
26
30
|
const req = context.switchToHttp().getRequest();
|
|
27
31
|
const { _limit = 20, _cursor, _order_by, _sort, _select, ...rest } = req.query;
|
|
28
32
|
const filters = Object
|
|
@@ -36,8 +40,8 @@ let LivequeryInterceptor = class LivequeryInterceptor {
|
|
|
36
40
|
return [name, expression || 'eq', rest[key]];
|
|
37
41
|
}
|
|
38
42
|
});
|
|
39
|
-
const { ref, is_collection, collection_ref, doc_id, } = PathHelper_1.PathHelper.
|
|
40
|
-
const { collection_ref: schema_collection_ref, ref: schema_ref } = PathHelper_1.PathHelper.
|
|
43
|
+
const { ref, is_collection, collection_ref, doc_id, } = PathHelper_1.PathHelper.parseHttpRequestPath(req._parsedUrl.pathname);
|
|
44
|
+
const { collection_ref: schema_collection_ref, ref: schema_ref } = PathHelper_1.PathHelper.parseHttpRequestPath(req.route.path);
|
|
41
45
|
req.livequery = {
|
|
42
46
|
ref,
|
|
43
47
|
schema_ref,
|
|
@@ -57,16 +61,22 @@ let LivequeryInterceptor = class LivequeryInterceptor {
|
|
|
57
61
|
body: req.body,
|
|
58
62
|
method: req.method.toLowerCase()
|
|
59
63
|
};
|
|
60
|
-
|
|
61
|
-
const
|
|
62
|
-
|
|
63
|
-
|
|
64
|
+
req.headers.socket_id && this.LivequeryWebsocketSync?.listen(req.headers.socket_id, { collection_ref, doc_id });
|
|
65
|
+
const realtime_token = await new Promise(s => {
|
|
66
|
+
if (this.LivequeryWebsocketSync || !this.secret_or_private_key || req.method.toLowerCase() != 'get' || req.query._cursor)
|
|
67
|
+
return s(null);
|
|
68
|
+
JWT.sign({ collection_ref, doc_id }, this.secret_or_private_key, {}, (error, data) => s(error ? null : data));
|
|
69
|
+
});
|
|
70
|
+
return next.handle().pipe((0, operators_1.map)(data => ({ data: { ...data, realtime_token } })));
|
|
64
71
|
}
|
|
65
72
|
};
|
|
66
73
|
LivequeryInterceptor = __decorate([
|
|
67
74
|
(0, common_1.Injectable)(),
|
|
68
75
|
__param(0, (0, common_1.Optional)()),
|
|
69
|
-
|
|
76
|
+
__param(0, (0, common_1.Inject)((0, common_1.forwardRef)(() => LivequeryWebsocketSync_1.LivequeryWebsocketSync))),
|
|
77
|
+
__param(1, (0, common_1.Optional)()),
|
|
78
|
+
__param(1, (0, UseWebsocketShareKeyPair_1.InjectWebsocketPrivateKey)()),
|
|
79
|
+
__metadata("design:paramtypes", [LivequeryWebsocketSync_1.LivequeryWebsocketSync, String])
|
|
70
80
|
], LivequeryInterceptor);
|
|
71
81
|
exports.LivequeryInterceptor = LivequeryInterceptor;
|
|
72
82
|
const UseLivequeryInterceptor = () => (0, common_1.UseInterceptors)(LivequeryInterceptor);
|
|
@@ -1,20 +1,27 @@
|
|
|
1
|
-
import { UpdatedData } from "@livequery/types";
|
|
2
1
|
import { Subject } from "rxjs";
|
|
2
|
+
import { LivequeryInterceptor, RealtimeSubscription } from "./LivequeryInterceptor";
|
|
3
|
+
import { UpdatedData } from "@livequery/types";
|
|
3
4
|
export declare class LivequeryWebsocketSync {
|
|
5
|
+
private secret_or_public_key;
|
|
4
6
|
private connections;
|
|
5
7
|
private refs;
|
|
6
8
|
readonly changes: Subject<UpdatedData<any>>;
|
|
7
|
-
constructor();
|
|
9
|
+
constructor(secret_or_public_key: string, LivequeryInterceptor: LivequeryInterceptor);
|
|
8
10
|
private handleDisconnect;
|
|
9
|
-
|
|
11
|
+
start({ id }: {
|
|
10
12
|
id: string;
|
|
11
13
|
}, socket: WebSocket & {
|
|
12
14
|
id: string;
|
|
13
15
|
}): void;
|
|
16
|
+
subscribe({ realtime_token }: {
|
|
17
|
+
realtime_token: string;
|
|
18
|
+
}, socket: WebSocket & {
|
|
19
|
+
id: string;
|
|
20
|
+
}): Promise<void>;
|
|
14
21
|
unsubscribe({ ref }: {
|
|
15
22
|
ref: string;
|
|
16
23
|
}, socket: WebSocket & {
|
|
17
24
|
id: string;
|
|
18
25
|
}): void;
|
|
19
|
-
listen(connection_id: string,
|
|
26
|
+
listen(connection_id: string, subscription: RealtimeSubscription): void;
|
|
20
27
|
}
|
|
@@ -15,51 +15,62 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
15
15
|
exports.LivequeryWebsocketSync = void 0;
|
|
16
16
|
const websockets_1 = require("@nestjs/websockets");
|
|
17
17
|
const rxjs_1 = require("rxjs");
|
|
18
|
+
const LivequeryInterceptor_1 = require("./LivequeryInterceptor");
|
|
19
|
+
const uuid_1 = require("uuid");
|
|
20
|
+
const common_1 = require("@nestjs/common");
|
|
21
|
+
const UseWebsocketShareKeyPair_1 = require("./UseWebsocketShareKeyPair");
|
|
22
|
+
const JWT = require('jsonwebtoken');
|
|
18
23
|
let LivequeryWebsocketSync = class LivequeryWebsocketSync {
|
|
24
|
+
secret_or_public_key;
|
|
19
25
|
connections = new Map();
|
|
20
26
|
refs = new Map();
|
|
21
27
|
changes = new rxjs_1.Subject();
|
|
22
|
-
constructor() {
|
|
23
|
-
this.
|
|
24
|
-
|
|
25
|
-
|
|
28
|
+
constructor(secret_or_public_key, LivequeryInterceptor) {
|
|
29
|
+
this.secret_or_public_key = secret_or_public_key;
|
|
30
|
+
if (!LivequeryInterceptor && !secret_or_public_key)
|
|
31
|
+
throw new Error('Missing api-websocket key pair, please use UseWebsocketPublicKey in providers list');
|
|
32
|
+
this.changes.subscribe(({ ref, data, type, ...rest }) => {
|
|
26
33
|
const connections = new Set([
|
|
27
|
-
...this.refs.get(
|
|
28
|
-
...this.refs.get(`${
|
|
34
|
+
...this.refs.get(ref)?.values() || [],
|
|
35
|
+
...this.refs.get(`${ref}/${data.id}`)?.values() || []
|
|
29
36
|
]);
|
|
30
|
-
if (
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
for (const cid of connections) {
|
|
34
|
-
const connection = this.connections.get(cid);
|
|
35
|
-
connection && connection.socket.OPEN && connection.socket.send(payload);
|
|
37
|
+
if (connections.size > 0) {
|
|
38
|
+
const payload = JSON.stringify({ event: 'sync', data: { changes: [{ ref, data, type }] } });
|
|
39
|
+
connections.forEach(({ socket }) => socket.OPEN && socket.send(payload));
|
|
36
40
|
}
|
|
37
41
|
});
|
|
38
42
|
}
|
|
39
43
|
async handleDisconnect(socket) {
|
|
40
|
-
|
|
44
|
+
this.connections.get(socket.id)?.refs.forEach(ref => {
|
|
41
45
|
this.refs.get(ref)?.delete(socket.id);
|
|
42
|
-
}
|
|
46
|
+
});
|
|
43
47
|
this.connections.delete(socket.id);
|
|
44
48
|
}
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
49
|
+
start({ id = (0, uuid_1.v4)() }, socket) {
|
|
50
|
+
if (typeof id == 'string' && id.length < 40) {
|
|
51
|
+
socket.id = id;
|
|
52
|
+
this.connections.set(id, { socket, refs: new Set() });
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
async subscribe({ realtime_token }, socket) {
|
|
56
|
+
if (realtime_token && this.secret_or_public_key) {
|
|
57
|
+
const options = await new Promise(s => JWT.verify(realtime_token, this.secret_or_public_key, {}, (error, data) => s(error ? null : data)));
|
|
58
|
+
options && this.listen(socket.id, options);
|
|
59
|
+
}
|
|
48
60
|
}
|
|
49
61
|
unsubscribe({ ref }, socket) {
|
|
50
|
-
|
|
51
|
-
return;
|
|
52
|
-
this.connections.get(socket.id)?.refs?.delete(ref);
|
|
62
|
+
this.connections.get(socket.id)?.refs.delete(ref);
|
|
53
63
|
this.refs.get(ref)?.delete(socket.id);
|
|
54
|
-
this.refs.get(ref)?.size == 0 && this.refs.delete(ref);
|
|
55
64
|
}
|
|
56
|
-
listen(connection_id,
|
|
57
|
-
const
|
|
58
|
-
if (
|
|
65
|
+
listen(connection_id, subscription) {
|
|
66
|
+
const connection = this.connections.get(connection_id);
|
|
67
|
+
if (connection) {
|
|
68
|
+
const { collection_ref, doc_id } = subscription;
|
|
59
69
|
const ref = `${collection_ref}${doc_id ? `/${doc_id}` : ''}`;
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
this.refs.
|
|
70
|
+
const { socket, refs } = connection;
|
|
71
|
+
refs.add(ref);
|
|
72
|
+
!this.refs.has(ref) && this.refs.set(ref, new Map());
|
|
73
|
+
!this.refs.get(ref).has(connection_id) && this.refs.get(ref).set(connection_id, { socket });
|
|
63
74
|
}
|
|
64
75
|
}
|
|
65
76
|
};
|
|
@@ -70,6 +81,14 @@ __decorate([
|
|
|
70
81
|
__metadata("design:type", Function),
|
|
71
82
|
__metadata("design:paramtypes", [Object, Object]),
|
|
72
83
|
__metadata("design:returntype", void 0)
|
|
84
|
+
], LivequeryWebsocketSync.prototype, "start", null);
|
|
85
|
+
__decorate([
|
|
86
|
+
(0, websockets_1.SubscribeMessage)('subscribe'),
|
|
87
|
+
__param(0, (0, websockets_1.MessageBody)()),
|
|
88
|
+
__param(1, (0, websockets_1.ConnectedSocket)()),
|
|
89
|
+
__metadata("design:type", Function),
|
|
90
|
+
__metadata("design:paramtypes", [Object, Object]),
|
|
91
|
+
__metadata("design:returntype", Promise)
|
|
73
92
|
], LivequeryWebsocketSync.prototype, "subscribe", null);
|
|
74
93
|
__decorate([
|
|
75
94
|
(0, websockets_1.SubscribeMessage)('unsubscribe'),
|
|
@@ -81,6 +100,10 @@ __decorate([
|
|
|
81
100
|
], LivequeryWebsocketSync.prototype, "unsubscribe", null);
|
|
82
101
|
LivequeryWebsocketSync = __decorate([
|
|
83
102
|
(0, websockets_1.WebSocketGateway)({ path: process.env.REALTIME_UPDATE_SOCKET_PATH || '/livequery/realtime-updates' }),
|
|
84
|
-
|
|
103
|
+
__param(0, (0, common_1.Optional)()),
|
|
104
|
+
__param(0, (0, UseWebsocketShareKeyPair_1.InjectWebsocketPublicKey)()),
|
|
105
|
+
__param(1, (0, common_1.Optional)()),
|
|
106
|
+
__param(1, (0, common_1.Inject)((0, common_1.forwardRef)(() => LivequeryInterceptor_1.LivequeryInterceptor))),
|
|
107
|
+
__metadata("design:paramtypes", [String, LivequeryInterceptor_1.LivequeryInterceptor])
|
|
85
108
|
], LivequeryWebsocketSync);
|
|
86
109
|
exports.LivequeryWebsocketSync = LivequeryWebsocketSync;
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
export declare class PathHelper {
|
|
2
|
-
|
|
3
|
-
static
|
|
2
|
+
static trimLivequeryHotkey(path: string): string;
|
|
3
|
+
static parseHttpRequestPath(path: string): {
|
|
4
4
|
ref: string;
|
|
5
5
|
schema_ref: string;
|
|
6
6
|
is_collection: boolean;
|
|
7
7
|
doc_id: string;
|
|
8
8
|
collection_ref: string;
|
|
9
9
|
};
|
|
10
|
-
static
|
|
10
|
+
static join(a: string | string[], b: string | string[]): string[];
|
|
11
11
|
}
|
package/build/src/PathHelper.js
CHANGED
|
@@ -3,9 +3,21 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.PathHelper = void 0;
|
|
4
4
|
const const_1 = require("./const");
|
|
5
5
|
class PathHelper {
|
|
6
|
-
static
|
|
7
|
-
|
|
6
|
+
static trimLivequeryHotkey(path) {
|
|
7
|
+
const ref = path
|
|
8
|
+
?.split('~')[0]
|
|
9
|
+
?.replaceAll(':', '')
|
|
10
|
+
?.split(const_1.LIVEQUERY_MAGIC_KEY)?.[1]
|
|
11
|
+
?.split('/')
|
|
12
|
+
?.filter(s => s.length > 0)
|
|
13
|
+
?.join('/');
|
|
14
|
+
if (!ref)
|
|
15
|
+
throw 'LIVEQUERY_MAGIC_KEY_NOT_FOUND';
|
|
16
|
+
return ref;
|
|
17
|
+
}
|
|
18
|
+
static parseHttpRequestPath(path) {
|
|
8
19
|
const refs = path
|
|
20
|
+
?.split('~')[0]
|
|
9
21
|
?.replaceAll(':', '')
|
|
10
22
|
?.split(const_1.LIVEQUERY_MAGIC_KEY)?.[1]
|
|
11
23
|
?.split('/')
|
|
@@ -19,10 +31,14 @@ class PathHelper {
|
|
|
19
31
|
const doc_id = is_collection ? null : refs[refs.length - 1];
|
|
20
32
|
return { ref, schema_ref, is_collection, doc_id, collection_ref };
|
|
21
33
|
}
|
|
22
|
-
static
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
34
|
+
static join(a, b) {
|
|
35
|
+
return [a || '']
|
|
36
|
+
.flat(2)
|
|
37
|
+
.map(r1 => [b || ''].flat(2).map(r2 => `${r1}/${r2}`))
|
|
38
|
+
.flat(2)
|
|
39
|
+
.map(r => r.split('/')
|
|
40
|
+
.filter(r => r != '')
|
|
41
|
+
.join('/'));
|
|
26
42
|
}
|
|
27
43
|
}
|
|
28
44
|
exports.PathHelper = PathHelper;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { Provider } from "@nestjs/common";
|
|
2
|
+
export declare const InjectWebsocketPublicKey: () => (target: object, key: string | symbol, index?: number) => void;
|
|
3
|
+
export declare const InjectWebsocketPrivateKey: () => (target: object, key: string | symbol, index?: number) => void;
|
|
4
|
+
export declare const UseWebsocketPublicKey: (secret_or_public_key: string) => Provider<any>;
|
|
5
|
+
export declare const UseWebsocketPrivateKey: (secret_or_private_key: string) => Provider<any>;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.UseWebsocketPrivateKey = exports.UseWebsocketPublicKey = exports.InjectWebsocketPrivateKey = exports.InjectWebsocketPublicKey = void 0;
|
|
4
|
+
const common_1 = require("@nestjs/common");
|
|
5
|
+
const WebsocketPublicKey = 'WebsocketPublicKey';
|
|
6
|
+
const WebsocketPrivateKey = 'WebsocketPrivateKey';
|
|
7
|
+
const InjectWebsocketPublicKey = () => (0, common_1.Inject)(WebsocketPublicKey);
|
|
8
|
+
exports.InjectWebsocketPublicKey = InjectWebsocketPublicKey;
|
|
9
|
+
const InjectWebsocketPrivateKey = () => (0, common_1.Inject)(WebsocketPrivateKey);
|
|
10
|
+
exports.InjectWebsocketPrivateKey = InjectWebsocketPrivateKey;
|
|
11
|
+
const UseWebsocketPublicKey = (secret_or_public_key) => ({
|
|
12
|
+
provide: WebsocketPublicKey,
|
|
13
|
+
useFactory: () => secret_or_public_key
|
|
14
|
+
});
|
|
15
|
+
exports.UseWebsocketPublicKey = UseWebsocketPublicKey;
|
|
16
|
+
const UseWebsocketPrivateKey = (secret_or_private_key) => ({
|
|
17
|
+
provide: WebsocketPrivateKey,
|
|
18
|
+
useFactory: () => secret_or_private_key
|
|
19
|
+
});
|
|
20
|
+
exports.UseWebsocketPrivateKey = UseWebsocketPrivateKey;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { Provider } from "@nestjs/common";
|
|
2
|
+
import { Datasource, DatasourceOptions } from "./LivequeryDatasourceInterceptors";
|
|
3
|
+
export declare const createDatasourceMapper: <T extends {}>(datasource_factory: new (...args: any[]) => Datasource) => [({ useFactory, inject }: {
|
|
4
|
+
useFactory: (options: DatasourceOptions<T>, ...injects: any[]) => Datasource<T> | Promise<Datasource<T>>;
|
|
5
|
+
inject?: any[];
|
|
6
|
+
}) => Provider<any>, (options: T) => <TFunction extends Function, Y>(target: object | TFunction, propertyKey?: string | symbol, descriptor?: TypedPropertyDescriptor<Y>) => void];
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createDatasourceMapper = void 0;
|
|
4
|
+
const common_1 = require("@nestjs/common");
|
|
5
|
+
const LivequeryDatasourceInterceptors_1 = require("./LivequeryDatasourceInterceptors");
|
|
6
|
+
const LivequeryInterceptor_1 = require("./LivequeryInterceptor");
|
|
7
|
+
const PathHelper_1 = require("./PathHelper");
|
|
8
|
+
const createDatasourceMapper = (datasource_factory) => {
|
|
9
|
+
const RouteConfigList = [];
|
|
10
|
+
const decorator = (options) => (0, common_1.applyDecorators)((target, method) => RouteConfigList.push({ target, method, options }), (0, LivequeryInterceptor_1.UseLivequeryInterceptor)(), (0, common_1.UseInterceptors)(LivequeryDatasourceInterceptors_1.LivequeryDatasourceInterceptors), (target, method, descriptor) => {
|
|
11
|
+
Reflect.defineMetadata(LivequeryDatasourceInterceptors_1.$__datasource_factory_token, datasource_factory, descriptor.value);
|
|
12
|
+
});
|
|
13
|
+
const UseDatasource = ({ useFactory, inject }) => {
|
|
14
|
+
return {
|
|
15
|
+
provide: datasource_factory,
|
|
16
|
+
inject,
|
|
17
|
+
useFactory: async (...injects) => {
|
|
18
|
+
const options = RouteConfigList.map(config => {
|
|
19
|
+
return {
|
|
20
|
+
...(config.options || {}),
|
|
21
|
+
refs: PathHelper_1.PathHelper.join(Reflect.getMetadata('path', config.target.constructor), Reflect.getMetadata('path', config.target[config.method])).map(PathHelper_1.PathHelper.trimLivequeryHotkey)
|
|
22
|
+
};
|
|
23
|
+
});
|
|
24
|
+
const datasource = await useFactory(options, ...injects);
|
|
25
|
+
LivequeryDatasourceInterceptors_1.DatasourceList.set(datasource_factory, datasource);
|
|
26
|
+
return datasource;
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
};
|
|
30
|
+
return [UseDatasource, decorator];
|
|
31
|
+
};
|
|
32
|
+
exports.createDatasourceMapper = createDatasourceMapper;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export declare class PathHelper {
|
|
2
|
+
static trimLivequeryHotkey(path: string): string;
|
|
3
|
+
static parseHttpRequestPath(path: string): {
|
|
4
|
+
ref: string;
|
|
5
|
+
schema_ref: string;
|
|
6
|
+
is_collection: boolean;
|
|
7
|
+
doc_id: string;
|
|
8
|
+
collection_ref: string;
|
|
9
|
+
};
|
|
10
|
+
static join(a: string | string[], b: string | string[]): string[];
|
|
11
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PathHelper = void 0;
|
|
4
|
+
const const_1 = require("../const");
|
|
5
|
+
class PathHelper {
|
|
6
|
+
static trimLivequeryHotkey(path) {
|
|
7
|
+
const ref = path
|
|
8
|
+
?.split('~')[0]
|
|
9
|
+
?.replaceAll(':', '')
|
|
10
|
+
?.split(const_1.LIVEQUERY_MAGIC_KEY)?.[1]
|
|
11
|
+
?.split('/')
|
|
12
|
+
?.filter(s => s.length > 0)
|
|
13
|
+
?.join('/');
|
|
14
|
+
if (!ref)
|
|
15
|
+
throw 'LIVEQUERY_MAGIC_KEY_NOT_FOUND';
|
|
16
|
+
return ref;
|
|
17
|
+
}
|
|
18
|
+
static parseHttpRequestPath(path) {
|
|
19
|
+
const refs = path
|
|
20
|
+
?.split('~')[0]
|
|
21
|
+
?.replaceAll(':', '')
|
|
22
|
+
?.split(const_1.LIVEQUERY_MAGIC_KEY)?.[1]
|
|
23
|
+
?.split('/')
|
|
24
|
+
?.filter(s => s.length > 0);
|
|
25
|
+
if (!refs)
|
|
26
|
+
throw 'LIVEQUERY_MAGIC_KEY_NOT_FOUND';
|
|
27
|
+
const is_collection = refs.length % 2 == 1;
|
|
28
|
+
const ref = refs.join('/');
|
|
29
|
+
const collection_ref = is_collection ? ref : refs.slice(0, refs.length - 1).join('/');
|
|
30
|
+
const schema_ref = refs.filter((_, i) => i % 2 == 0).join('/');
|
|
31
|
+
const doc_id = is_collection ? null : refs[refs.length - 1];
|
|
32
|
+
return { ref, schema_ref, is_collection, doc_id, collection_ref };
|
|
33
|
+
}
|
|
34
|
+
static join(a, b) {
|
|
35
|
+
return [a || '']
|
|
36
|
+
.flat(2)
|
|
37
|
+
.map(r1 => [b || ''].flat(2).map(r2 => `${r1}/${r2}`))
|
|
38
|
+
.flat(2)
|
|
39
|
+
.map(r => r.split('/')
|
|
40
|
+
.filter(r => r != '')
|
|
41
|
+
.join('/'));
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
exports.PathHelper = PathHelper;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { Provider } from "@nestjs/common";
|
|
2
|
+
import { Datasource, DatasourceOptions } from "../LivequeryDatasourceInterceptors";
|
|
3
|
+
export declare const createDatasourceMapper: <T extends {}>(datasource_factory: new (...args: any[]) => Datasource) => [({ useFactory, inject }: {
|
|
4
|
+
useFactory: (options: DatasourceOptions<T>, ...injects: any[]) => Datasource<T> | Promise<Datasource<T>>;
|
|
5
|
+
inject?: any[];
|
|
6
|
+
}) => Provider<any>, (options: T) => <TFunction extends Function, Y>(target: object | TFunction, propertyKey?: string | symbol, descriptor?: TypedPropertyDescriptor<Y>) => void];
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createDatasourceMapper = void 0;
|
|
4
|
+
const common_1 = require("@nestjs/common");
|
|
5
|
+
const LivequeryDatasourceInterceptors_1 = require("../LivequeryDatasourceInterceptors");
|
|
6
|
+
const LivequeryInterceptor_1 = require("../LivequeryInterceptor");
|
|
7
|
+
const PathHelper_1 = require("./PathHelper");
|
|
8
|
+
const createDatasourceMapper = (datasource_factory) => {
|
|
9
|
+
const RouteConfigList = [];
|
|
10
|
+
const decorator = (options) => (0, common_1.applyDecorators)((target, method) => RouteConfigList.push({ target, method, options }), (0, LivequeryInterceptor_1.UseLivequeryInterceptor)(), (0, common_1.UseInterceptors)(LivequeryDatasourceInterceptors_1.LivequeryDatasourceInterceptors), (target, method, descriptor) => {
|
|
11
|
+
Reflect.defineMetadata(LivequeryDatasourceInterceptors_1.$__datasource_factory_token, datasource_factory, descriptor.value);
|
|
12
|
+
});
|
|
13
|
+
const UseDatasource = ({ useFactory, inject }) => {
|
|
14
|
+
return {
|
|
15
|
+
provide: datasource_factory,
|
|
16
|
+
inject,
|
|
17
|
+
useFactory: async (...injects) => {
|
|
18
|
+
const options = RouteConfigList.map(config => {
|
|
19
|
+
return {
|
|
20
|
+
...(config.options || {}),
|
|
21
|
+
refs: PathHelper_1.PathHelper.join(Reflect.getMetadata('path', config.target.constructor), Reflect.getMetadata('path', config.target[config.method])).map(PathHelper_1.PathHelper.trimLivequeryHotkey)
|
|
22
|
+
};
|
|
23
|
+
});
|
|
24
|
+
const datasource = await useFactory(options, ...injects);
|
|
25
|
+
LivequeryDatasourceInterceptors_1.DatasourceList.set(datasource_factory, datasource);
|
|
26
|
+
return datasource;
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
};
|
|
30
|
+
return [UseDatasource, decorator];
|
|
31
|
+
};
|
|
32
|
+
exports.createDatasourceMapper = createDatasourceMapper;
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"repository": {
|
|
4
4
|
"url": "git@github.com:livequery/nestjs.git"
|
|
5
5
|
},
|
|
6
|
-
"version": "1.0.
|
|
6
|
+
"version": "1.0.41",
|
|
7
7
|
"description": "",
|
|
8
8
|
"main": "build/index.js",
|
|
9
9
|
"types": "build/index.d.ts",
|
|
@@ -11,14 +11,14 @@
|
|
|
11
11
|
"build/**/*"
|
|
12
12
|
],
|
|
13
13
|
"devDependencies": {
|
|
14
|
-
"@livequery/types": "
|
|
15
|
-
"@nestjs/common": "
|
|
16
|
-
"@nestjs/core": "
|
|
17
|
-
"@nestjs/websockets": "
|
|
18
|
-
"@types/express": "
|
|
19
|
-
"@types/node": "
|
|
20
|
-
"reflect-metadata": "
|
|
21
|
-
"rxjs": "
|
|
14
|
+
"@livequery/types": "1.x",
|
|
15
|
+
"@nestjs/common": "8.x",
|
|
16
|
+
"@nestjs/core": "8.x",
|
|
17
|
+
"@nestjs/websockets": "8.x",
|
|
18
|
+
"@types/express": "4.x",
|
|
19
|
+
"@types/node": "14.x",
|
|
20
|
+
"reflect-metadata": "0.x",
|
|
21
|
+
"rxjs": "^.x"
|
|
22
22
|
},
|
|
23
23
|
"peerDependencies": {
|
|
24
24
|
"@nestjs/common": "^7.6.17",
|
|
@@ -33,5 +33,9 @@
|
|
|
33
33
|
"deploy": "yarn build; git add .; git commit -m \"Update\"; git push origin master; npm publish --access public"
|
|
34
34
|
},
|
|
35
35
|
"author": "",
|
|
36
|
-
"license": "ISC"
|
|
36
|
+
"license": "ISC",
|
|
37
|
+
"dependencies": {
|
|
38
|
+
"@types/jsonwebtoken": "^8.5.8",
|
|
39
|
+
"jsonwebtoken": "^8.5.1"
|
|
40
|
+
}
|
|
37
41
|
}
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import { LivequeryRequest } from "@livequery/types";
|
|
2
|
-
import { CallHandler, ExecutionContext } from "@nestjs/common";
|
|
3
|
-
import { ModuleRef, Reflector } from "@nestjs/core";
|
|
4
|
-
declare type Datasource = {
|
|
5
|
-
query(req: LivequeryRequest): Promise<any>;
|
|
6
|
-
};
|
|
7
|
-
export declare class UseDatasource {
|
|
8
|
-
private moduleRef;
|
|
9
|
-
private reflector;
|
|
10
|
-
private static ControllerList;
|
|
11
|
-
constructor(moduleRef: ModuleRef, reflector: Reflector);
|
|
12
|
-
static createDatasourceMapper<T = {}>(factory: {
|
|
13
|
-
new (): Datasource;
|
|
14
|
-
}): [(options: T & {
|
|
15
|
-
_manual_query?: boolean;
|
|
16
|
-
}) => <TFunction extends Function, Y>(target: object | TFunction, propertyKey?: string | symbol, descriptor?: TypedPropertyDescriptor<Y>) => void, () => {
|
|
17
|
-
paths: {
|
|
18
|
-
ref: string;
|
|
19
|
-
schema_ref: string;
|
|
20
|
-
is_collection: boolean;
|
|
21
|
-
doc_id: string;
|
|
22
|
-
collection_ref: string;
|
|
23
|
-
}[];
|
|
24
|
-
options: T;
|
|
25
|
-
}[]];
|
|
26
|
-
intercept(context: ExecutionContext, next: CallHandler): Promise<import("rxjs").Observable<any>>;
|
|
27
|
-
}
|
|
28
|
-
export {};
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
-
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
-
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
-
};
|
|
8
|
-
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
-
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
-
};
|
|
11
|
-
var UseDatasource_1;
|
|
12
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
-
exports.UseDatasource = void 0;
|
|
14
|
-
const common_1 = require("@nestjs/common");
|
|
15
|
-
const core_1 = require("@nestjs/core");
|
|
16
|
-
const LivequeryInterceptor_1 = require("./LivequeryInterceptor");
|
|
17
|
-
const LivequeryRequest_1 = require("./LivequeryRequest");
|
|
18
|
-
const PathHelper_1 = require("./PathHelper");
|
|
19
|
-
const rxjs_1 = require("rxjs");
|
|
20
|
-
let UseDatasource = UseDatasource_1 = class UseDatasource {
|
|
21
|
-
moduleRef;
|
|
22
|
-
reflector;
|
|
23
|
-
static ControllerList = [];
|
|
24
|
-
constructor(moduleRef, reflector) {
|
|
25
|
-
this.moduleRef = moduleRef;
|
|
26
|
-
this.reflector = reflector;
|
|
27
|
-
}
|
|
28
|
-
static createDatasourceMapper(factory) {
|
|
29
|
-
const decorator = (options) => (0, common_1.applyDecorators)((0, common_1.UseInterceptors)(LivequeryInterceptor_1.LivequeryInterceptor), ...options._manual_query == true ? [] : [
|
|
30
|
-
(0, common_1.SetMetadata)(UseDatasource_1, { options, factory }),
|
|
31
|
-
(0, common_1.UseInterceptors)(this)
|
|
32
|
-
], (target, method) => this.ControllerList.push({
|
|
33
|
-
target: target.constructor,
|
|
34
|
-
method,
|
|
35
|
-
options
|
|
36
|
-
}));
|
|
37
|
-
const list = () => this.ControllerList.map(({ method, target, options }) => {
|
|
38
|
-
const paths = PathHelper_1.PathHelper.nestjsPathResolver(target, method).map(path => {
|
|
39
|
-
return PathHelper_1.PathHelper.livequeryPathExtractor(path);
|
|
40
|
-
});
|
|
41
|
-
return { paths, options: options };
|
|
42
|
-
}).flat(2);
|
|
43
|
-
return [decorator, list];
|
|
44
|
-
}
|
|
45
|
-
async intercept(context, next) {
|
|
46
|
-
const request = context.switchToHttp().getRequest();
|
|
47
|
-
const livequery = request[LivequeryRequest_1.LivequeryRequestKey];
|
|
48
|
-
const { factory } = this.reflector.get(UseDatasource_1, context.getHandler());
|
|
49
|
-
const ds = await this.moduleRef.get(factory);
|
|
50
|
-
const result = await ds.query(livequery);
|
|
51
|
-
return next.handle().pipe((0, rxjs_1.map)(data => data ?? result));
|
|
52
|
-
}
|
|
53
|
-
};
|
|
54
|
-
UseDatasource = UseDatasource_1 = __decorate([
|
|
55
|
-
(0, common_1.Injectable)(),
|
|
56
|
-
__metadata("design:paramtypes", [core_1.ModuleRef,
|
|
57
|
-
core_1.Reflector])
|
|
58
|
-
], UseDatasource);
|
|
59
|
-
exports.UseDatasource = UseDatasource;
|