rxdb-server 15.4.3

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 (82) hide show
  1. package/LICENSE.txt +555 -0
  2. package/README.md +7 -0
  3. package/dist/cjs/index.js +10 -0
  4. package/dist/cjs/index.js.map +1 -0
  5. package/dist/cjs/plugins/client-rest/index.js +86 -0
  6. package/dist/cjs/plugins/client-rest/index.js.map +1 -0
  7. package/dist/cjs/plugins/client-rest/utils.js +19 -0
  8. package/dist/cjs/plugins/client-rest/utils.js.map +1 -0
  9. package/dist/cjs/plugins/replication-server/helpers.js +38 -0
  10. package/dist/cjs/plugins/replication-server/helpers.js.map +1 -0
  11. package/dist/cjs/plugins/replication-server/index.js +169 -0
  12. package/dist/cjs/plugins/replication-server/index.js.map +1 -0
  13. package/dist/cjs/plugins/replication-server/types.js +2 -0
  14. package/dist/cjs/plugins/replication-server/types.js.map +1 -0
  15. package/dist/cjs/plugins/server/endpoint-replication.js +162 -0
  16. package/dist/cjs/plugins/server/endpoint-replication.js.map +1 -0
  17. package/dist/cjs/plugins/server/endpoint-rest.js +219 -0
  18. package/dist/cjs/plugins/server/endpoint-rest.js.map +1 -0
  19. package/dist/cjs/plugins/server/helper.js +173 -0
  20. package/dist/cjs/plugins/server/helper.js.map +1 -0
  21. package/dist/cjs/plugins/server/index.js +84 -0
  22. package/dist/cjs/plugins/server/index.js.map +1 -0
  23. package/dist/cjs/plugins/server/rx-server.js +51 -0
  24. package/dist/cjs/plugins/server/rx-server.js.map +1 -0
  25. package/dist/cjs/plugins/server/types.js +37 -0
  26. package/dist/cjs/plugins/server/types.js.map +1 -0
  27. package/dist/esm/index.js +4 -0
  28. package/dist/esm/index.js.map +1 -0
  29. package/dist/esm/package.json +1 -0
  30. package/dist/esm/plugins/client-rest/index.js +64 -0
  31. package/dist/esm/plugins/client-rest/index.js.map +1 -0
  32. package/dist/esm/plugins/client-rest/utils.js +13 -0
  33. package/dist/esm/plugins/client-rest/utils.js.map +1 -0
  34. package/dist/esm/plugins/replication-server/helpers.js +32 -0
  35. package/dist/esm/plugins/replication-server/helpers.js.map +1 -0
  36. package/dist/esm/plugins/replication-server/index.js +146 -0
  37. package/dist/esm/plugins/replication-server/index.js.map +1 -0
  38. package/dist/esm/plugins/replication-server/types.js +3 -0
  39. package/dist/esm/plugins/replication-server/types.js.map +1 -0
  40. package/dist/esm/plugins/server/endpoint-replication.js +156 -0
  41. package/dist/esm/plugins/server/endpoint-replication.js.map +1 -0
  42. package/dist/esm/plugins/server/endpoint-rest.js +213 -0
  43. package/dist/esm/plugins/server/endpoint-rest.js.map +1 -0
  44. package/dist/esm/plugins/server/helper.js +157 -0
  45. package/dist/esm/plugins/server/helper.js.map +1 -0
  46. package/dist/esm/plugins/server/index.js +30 -0
  47. package/dist/esm/plugins/server/index.js.map +1 -0
  48. package/dist/esm/plugins/server/rx-server.js +45 -0
  49. package/dist/esm/plugins/server/rx-server.js.map +1 -0
  50. package/dist/esm/plugins/server/types.js +37 -0
  51. package/dist/esm/plugins/server/types.js.map +1 -0
  52. package/dist/types/index.d.ts +1 -0
  53. package/dist/types/plugins/client-rest/index.d.ts +22 -0
  54. package/dist/types/plugins/client-rest/utils.d.ts +2 -0
  55. package/dist/types/plugins/replication-server/helpers.d.ts +2 -0
  56. package/dist/types/plugins/replication-server/index.d.ts +21 -0
  57. package/dist/types/plugins/replication-server/types.d.ts +17 -0
  58. package/dist/types/plugins/server/endpoint-replication.d.ts +20 -0
  59. package/dist/types/plugins/server/endpoint-rest.d.ts +16 -0
  60. package/dist/types/plugins/server/helper.d.ts +23 -0
  61. package/dist/types/plugins/server/index.d.ts +7 -0
  62. package/dist/types/plugins/server/rx-server.d.ts +44 -0
  63. package/dist/types/plugins/server/types.d.ts +66 -0
  64. package/package.json +139 -0
  65. package/plugins/client-rest/index.cjs +2 -0
  66. package/plugins/client-rest/index.d.cts +1 -0
  67. package/plugins/client-rest/index.d.mts +1 -0
  68. package/plugins/client-rest/index.mjs +1 -0
  69. package/plugins/client-rest/index.ts +1 -0
  70. package/plugins/client-rest/package.json +18 -0
  71. package/plugins/replication-server/index.cjs +2 -0
  72. package/plugins/replication-server/index.d.cts +1 -0
  73. package/plugins/replication-server/index.d.mts +1 -0
  74. package/plugins/replication-server/index.mjs +1 -0
  75. package/plugins/replication-server/index.ts +1 -0
  76. package/plugins/replication-server/package.json +18 -0
  77. package/plugins/server/index.cjs +2 -0
  78. package/plugins/server/index.d.cts +1 -0
  79. package/plugins/server/index.d.mts +1 -0
  80. package/plugins/server/index.mjs +1 -0
  81. package/plugins/server/index.ts +1 -0
  82. package/plugins/server/package.json +18 -0
@@ -0,0 +1,219 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.RxServerRestEndpoint = exports.REST_PATHS = void 0;
7
+ var _core = require("rxdb/plugins/core");
8
+ var _rxjs = require("rxjs");
9
+ var _utils = require("rxdb/plugins/utils");
10
+ var _helper = require("./helper.js");
11
+ var REST_PATHS = exports.REST_PATHS = ['query', 'query/observe', 'get', 'set', 'delete'
12
+
13
+ // TODO
14
+ /*
15
+ 'attachments/add',
16
+ 'attachments/delete',
17
+ 'events'
18
+ */];
19
+ var RxServerRestEndpoint = exports.RxServerRestEndpoint = function RxServerRestEndpoint(server, name, collection, queryModifier, changeValidator, serverOnlyFields, cors) {
20
+ var _this = this;
21
+ this.type = 'rest';
22
+ this.server = server;
23
+ this.name = name;
24
+ this.collection = collection;
25
+ this.serverOnlyFields = serverOnlyFields;
26
+ this.cors = cors;
27
+ (0, _helper.setCors)(this.server, [this.name].join('/'), cors);
28
+ (0, _helper.blockPreviousVersionPaths)(this.server, [this.name].join('/'), collection.schema.version);
29
+ this.urlPath = [this.name, collection.schema.version].join('/');
30
+ var primaryPath = this.collection.schema.primaryPath;
31
+ var authDataByRequest = (0, _helper.addAuthMiddleware)(this.server, this.urlPath);
32
+ this.queryModifier = (authData, query) => {
33
+ if ((0, _helper.doesContainRegexQuerySelector)(query.selector)) {
34
+ throw new Error('$regex queries not allowed because of DOS-attacks');
35
+ }
36
+ return queryModifier(authData, query);
37
+ };
38
+ this.changeValidator = (authData, change) => {
39
+ if (change.assumedMasterState && (0, _helper.docContainsServerOnlyFields)(serverOnlyFields, change.assumedMasterState) || (0, _helper.docContainsServerOnlyFields)(serverOnlyFields, change.newDocumentState)) {
40
+ return false;
41
+ }
42
+ return changeValidator(authData, change);
43
+ };
44
+ var removeServerOnlyFields = (0, _helper.removeServerOnlyFieldsMonad)(this.serverOnlyFields);
45
+ this.server.expressApp.post('/' + this.urlPath + '/query', async (req, res) => {
46
+ var authData = (0, _utils.getFromMapOrThrow)(authDataByRequest, req);
47
+ var useQuery;
48
+ try {
49
+ useQuery = this.queryModifier((0, _utils.ensureNotFalsy)(authData), (0, _core.normalizeMangoQuery)(this.collection.schema.jsonSchema, req.body));
50
+ } catch (err) {
51
+ (0, _helper.closeConnection)(res, 400, 'Bad Request');
52
+ return;
53
+ }
54
+ var rxQuery = this.collection.find(useQuery);
55
+ var result = await rxQuery.exec();
56
+ res.setHeader('Content-Type', 'application/json');
57
+ res.json({
58
+ documents: result.map(d => removeServerOnlyFields(d.toJSON()))
59
+ });
60
+ });
61
+
62
+ /**
63
+ * It is not possible to send data with server send events,
64
+ * so we send the query as query parameter in base64
65
+ * like ?query=e3NlbGVjdG9yOiB7fX0=
66
+ */
67
+ this.server.expressApp.get('/' + this.urlPath + '/query/observe', async (req, res) => {
68
+ var authData = (0, _utils.getFromMapOrThrow)(authDataByRequest, req);
69
+ (0, _helper.writeSSEHeaders)(res);
70
+ var useQuery = this.queryModifier((0, _utils.ensureNotFalsy)(authData), (0, _core.normalizeMangoQuery)(this.collection.schema.jsonSchema, JSON.parse(atob(req.query.query))));
71
+ var rxQuery = this.collection.find(useQuery);
72
+ var subscription = rxQuery.$.pipe((0, _rxjs.mergeMap)(async result => {
73
+ var resultData = result.map(doc => removeServerOnlyFields(doc.toJSON()));
74
+
75
+ /**
76
+ * The auth-data might be expired
77
+ * so we re-run the auth parsing each time
78
+ * before emitting the new results.
79
+ */
80
+ try {
81
+ authData = await server.authHandler(req.headers);
82
+ } catch (err) {
83
+ (0, _helper.closeConnection)(res, 401, 'Unauthorized');
84
+ return null;
85
+ }
86
+ return resultData;
87
+ }), (0, _rxjs.filter)(f => f !== null)).subscribe(resultData => {
88
+ res.write('data: ' + JSON.stringify(resultData) + '\n\n');
89
+ });
90
+
91
+ /**
92
+ * @link https://youtu.be/0PcMuYGJPzM?si=AxkczxcMaUwhh8k9&t=363
93
+ */
94
+ req.on('close', () => {
95
+ subscription.unsubscribe();
96
+ res.end();
97
+ });
98
+ });
99
+ this.server.expressApp.post('/' + this.urlPath + '/get', async (req, res) => {
100
+ var authData = (0, _utils.getFromMapOrThrow)(authDataByRequest, req);
101
+ var ids = req.body;
102
+ var rxQuery = this.collection.findByIds(ids);
103
+ var resultMap = await rxQuery.exec();
104
+ var resultValues = Array.from(resultMap.values());
105
+ var docMatcher = (0, _helper.getDocAllowedMatcher)(this, (0, _utils.ensureNotFalsy)(authData));
106
+ var useDocs = resultValues.map(d => d.toJSON());
107
+ useDocs = useDocs.filter(d => docMatcher(d));
108
+ useDocs = useDocs.map(d => removeServerOnlyFields(d));
109
+ res.setHeader('Content-Type', 'application/json');
110
+ res.json({
111
+ documents: useDocs
112
+ });
113
+ });
114
+ this.server.expressApp.post('/' + this.urlPath + '/set', async (req, res) => {
115
+ var authData = (0, _utils.getFromMapOrThrow)(authDataByRequest, req);
116
+ var docDataMatcherWrite = (0, _helper.getDocAllowedMatcher)(this, (0, _utils.ensureNotFalsy)(authData));
117
+ var docsData = req.body;
118
+ for (var docData of docsData) {
119
+ var allowed = docDataMatcherWrite(docData);
120
+ if (!allowed) {
121
+ (0, _helper.closeConnection)(res, 403, 'Forbidden');
122
+ return;
123
+ }
124
+ }
125
+ function onWriteError(err, docData) {
126
+ if (err.rxdb && err.code === 'CONFLICT') {
127
+ // just retry on conflicts
128
+ docsData.push(docData);
129
+ } else {
130
+ (0, _helper.closeConnection)(res, 500, 'Internal Server Error');
131
+ throw err;
132
+ }
133
+ }
134
+ while (docsData.length > 0) {
135
+ var promises = [];
136
+ var docs = await collection.findByIds(docsData.map(d => d[primaryPath])).exec();
137
+ var useDocsData = docsData.slice();
138
+ docsData = [];
139
+ var _loop = async function (_docData) {
140
+ var id = _docData[primaryPath];
141
+ var doc = docs.get(id);
142
+ if (!doc) {
143
+ promises.push(_this.collection.insert(_docData).catch(err => onWriteError(err, _docData)));
144
+ } else {
145
+ var isAllowed = _this.changeValidator(authData, {
146
+ newDocumentState: removeServerOnlyFields(_docData),
147
+ assumedMasterState: removeServerOnlyFields(doc.toJSON(true))
148
+ });
149
+ if (!isAllowed) {
150
+ (0, _helper.closeConnection)(res, 403, 'Forbidden');
151
+ return {
152
+ v: void 0
153
+ };
154
+ }
155
+ promises.push(doc.patch(_docData).catch(err => onWriteError(err, _docData)));
156
+ }
157
+ },
158
+ _ret;
159
+ for (var _docData of useDocsData) {
160
+ _ret = await _loop(_docData);
161
+ if (_ret) return _ret.v;
162
+ }
163
+ await Promise.all(promises);
164
+ }
165
+ res.setHeader('Content-Type', 'application/json');
166
+ res.json({});
167
+ });
168
+ this.server.expressApp.post('/' + this.urlPath + '/delete', async (req, res) => {
169
+ var authData = (0, _utils.getFromMapOrThrow)(authDataByRequest, req);
170
+ var docDataMatcherWrite = (0, _helper.getDocAllowedMatcher)(this, (0, _utils.ensureNotFalsy)(authData));
171
+ var ids = req.body;
172
+ while (ids.length > 0) {
173
+ var useIds = ids.slice(0);
174
+ ids = [];
175
+ var promises = [];
176
+ var docsMap = await this.collection.findByIds(useIds).exec();
177
+ var _loop2 = async function (id) {
178
+ var doc = docsMap.get(id);
179
+ if (doc) {
180
+ var isAllowedDoc = docDataMatcherWrite(doc.toJSON(true));
181
+ if (!isAllowedDoc) {
182
+ (0, _helper.closeConnection)(res, 403, 'Forbidden');
183
+ return {
184
+ v: void 0
185
+ };
186
+ }
187
+ var isAllowedChange = _this.changeValidator(authData, {
188
+ newDocumentState: doc.toJSON(true),
189
+ assumedMasterState: doc.toJSON(true)
190
+ });
191
+ if (!isAllowedChange) {
192
+ (0, _helper.closeConnection)(res, 403, 'Forbidden');
193
+ return {
194
+ v: void 0
195
+ };
196
+ }
197
+ promises.push(doc.remove().catch(err => {
198
+ if (err.rxdb && err.code === 'CONFLICT') {
199
+ // just retry on conflicts
200
+ ids.push(id);
201
+ } else {
202
+ (0, _helper.closeConnection)(res, 500, 'Internal Server Error');
203
+ throw err;
204
+ }
205
+ }));
206
+ }
207
+ },
208
+ _ret2;
209
+ for (var id of useIds) {
210
+ _ret2 = await _loop2(id);
211
+ if (_ret2) return _ret2.v;
212
+ }
213
+ await Promise.all(promises);
214
+ }
215
+ res.setHeader('Content-Type', 'application/json');
216
+ res.json({});
217
+ });
218
+ };
219
+ //# sourceMappingURL=endpoint-rest.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"endpoint-rest.js","names":["_core","require","_rxjs","_utils","_helper","REST_PATHS","exports","RxServerRestEndpoint","server","name","collection","queryModifier","changeValidator","serverOnlyFields","cors","_this","type","setCors","join","blockPreviousVersionPaths","schema","version","urlPath","primaryPath","authDataByRequest","addAuthMiddleware","authData","query","doesContainRegexQuerySelector","selector","Error","change","assumedMasterState","docContainsServerOnlyFields","newDocumentState","removeServerOnlyFields","removeServerOnlyFieldsMonad","expressApp","post","req","res","getFromMapOrThrow","useQuery","ensureNotFalsy","normalizeMangoQuery","jsonSchema","body","err","closeConnection","rxQuery","find","result","exec","setHeader","json","documents","map","d","toJSON","get","writeSSEHeaders","JSON","parse","atob","subscription","$","pipe","mergeMap","resultData","doc","authHandler","headers","filter","f","subscribe","write","stringify","on","unsubscribe","end","ids","findByIds","resultMap","resultValues","Array","from","values","docMatcher","getDocAllowedMatcher","useDocs","docDataMatcherWrite","docsData","docData","allowed","onWriteError","rxdb","code","push","length","promises","docs","useDocsData","slice","_loop","_docData","id","insert","catch","isAllowed","v","patch","_ret","Promise","all","useIds","docsMap","_loop2","isAllowedDoc","isAllowedChange","remove","_ret2"],"sources":["../../../../src/plugins/server/endpoint-rest.ts"],"sourcesContent":["import {\n FilledMangoQuery,\n RxCollection,\n RxError,\n normalizeMangoQuery\n} from 'rxdb/plugins/core';\nimport type { RxServer } from './rx-server.ts';\nimport type {\n RxServerChangeValidator,\n RxServerEndpoint,\n RxServerQueryModifier\n} from './types.ts';\nimport { filter, mergeMap } from 'rxjs';\nimport {\n ensureNotFalsy,\n getFromMapOrThrow\n} from 'rxdb/plugins/utils';\n\nimport {\n addAuthMiddleware,\n blockPreviousVersionPaths,\n closeConnection,\n docContainsServerOnlyFields,\n doesContainRegexQuerySelector,\n getDocAllowedMatcher,\n removeServerOnlyFieldsMonad,\n setCors,\n writeSSEHeaders\n} from './helper.ts';\n\n\nexport const REST_PATHS = [\n 'query',\n 'query/observe',\n 'get',\n 'set',\n 'delete',\n\n // TODO\n /*\n 'attachments/add',\n 'attachments/delete',\n 'events'\n */\n] as const;\n\n\nexport class RxServerRestEndpoint<AuthType, RxDocType> implements RxServerEndpoint<AuthType, RxDocType> {\n readonly type = 'rest';\n readonly urlPath: string;\n readonly changeValidator: RxServerChangeValidator<AuthType, RxDocType>;\n readonly queryModifier: RxServerQueryModifier<AuthType, RxDocType>;\n constructor(\n public readonly server: RxServer<AuthType>,\n public readonly name: string,\n public readonly collection: RxCollection<RxDocType>,\n queryModifier: RxServerQueryModifier<AuthType, RxDocType>,\n changeValidator: RxServerChangeValidator<AuthType, RxDocType>,\n public readonly serverOnlyFields: string[],\n public readonly cors?: string\n ) {\n setCors(this.server, [this.name].join('/'), cors);\n blockPreviousVersionPaths(this.server, [this.name].join('/'), collection.schema.version);\n\n this.urlPath = [this.name, collection.schema.version].join('/');\n const primaryPath = this.collection.schema.primaryPath;\n const authDataByRequest = addAuthMiddleware(\n this.server,\n this.urlPath\n );\n\n this.queryModifier = (authData, query) => {\n if (doesContainRegexQuerySelector(query.selector)) {\n throw new Error('$regex queries not allowed because of DOS-attacks');\n }\n return queryModifier(authData, query);\n }\n this.changeValidator = (authData, change) => {\n if (\n (\n change.assumedMasterState &&\n docContainsServerOnlyFields(serverOnlyFields, change.assumedMasterState)\n ) ||\n docContainsServerOnlyFields(serverOnlyFields, change.newDocumentState)\n ) {\n return false;\n }\n return changeValidator(authData, change);\n }\n const removeServerOnlyFields = removeServerOnlyFieldsMonad(this.serverOnlyFields);\n\n this.server.expressApp.post('/' + this.urlPath + '/query', async (req, res) => {\n const authData = getFromMapOrThrow(authDataByRequest, req);\n let useQuery: FilledMangoQuery<RxDocType>\n try {\n useQuery = this.queryModifier(\n ensureNotFalsy(authData),\n normalizeMangoQuery(\n this.collection.schema.jsonSchema,\n req.body\n )\n );\n } catch (err) {\n closeConnection(res, 400, 'Bad Request');\n return;\n }\n const rxQuery = this.collection.find(useQuery as any);\n const result = await rxQuery.exec();\n res.setHeader('Content-Type', 'application/json');\n res.json({\n documents: result.map(d => removeServerOnlyFields(d.toJSON()))\n });\n });\n\n /**\n * It is not possible to send data with server send events,\n * so we send the query as query parameter in base64\n * like ?query=e3NlbGVjdG9yOiB7fX0=\n */\n this.server.expressApp.get('/' + this.urlPath + '/query/observe', async (req, res) => {\n let authData = getFromMapOrThrow(authDataByRequest, req);\n writeSSEHeaders(res);\n\n const useQuery: FilledMangoQuery<RxDocType> = this.queryModifier(\n ensureNotFalsy(authData),\n normalizeMangoQuery(\n this.collection.schema.jsonSchema,\n JSON.parse(atob(req.query.query as string))\n )\n );\n\n const rxQuery = this.collection.find(useQuery as any);\n const subscription = rxQuery.$.pipe(\n mergeMap(async (result) => {\n const resultData = result.map(doc => removeServerOnlyFields(doc.toJSON()));\n\n /**\n * The auth-data might be expired\n * so we re-run the auth parsing each time\n * before emitting the new results.\n */\n try {\n authData = await server.authHandler(req.headers);\n } catch (err) {\n closeConnection(res, 401, 'Unauthorized');\n return null;\n }\n\n return resultData;\n }),\n filter(f => f !== null)\n ).subscribe(resultData => {\n res.write('data: ' + JSON.stringify(resultData) + '\\n\\n');\n });\n\n /**\n * @link https://youtu.be/0PcMuYGJPzM?si=AxkczxcMaUwhh8k9&t=363\n */\n req.on('close', () => {\n subscription.unsubscribe();\n res.end();\n });\n });\n\n\n this.server.expressApp.post('/' + this.urlPath + '/get', async (req, res) => {\n const authData = getFromMapOrThrow(authDataByRequest, req);\n const ids: string[] = req.body;\n\n const rxQuery = this.collection.findByIds(ids);\n const resultMap = await rxQuery.exec();\n const resultValues = Array.from(resultMap.values());\n const docMatcher = getDocAllowedMatcher(this, ensureNotFalsy(authData));\n let useDocs = resultValues.map(d => d.toJSON());\n useDocs = useDocs.filter(d => docMatcher(d as any));\n useDocs = useDocs.map(d => removeServerOnlyFields(d))\n\n res.setHeader('Content-Type', 'application/json');\n res.json({\n documents: useDocs\n });\n });\n\n this.server.expressApp.post('/' + this.urlPath + '/set', async (req, res) => {\n const authData = getFromMapOrThrow(authDataByRequest, req);\n const docDataMatcherWrite = getDocAllowedMatcher(this, ensureNotFalsy(authData));\n\n let docsData: RxDocType[] = req.body;\n\n for (const docData of docsData) {\n const allowed = docDataMatcherWrite(docData as any);\n if (!allowed) {\n closeConnection(res, 403, 'Forbidden');\n return;\n }\n }\n\n function onWriteError(err: RxError, docData: RxDocType) {\n if (err.rxdb && err.code === 'CONFLICT') {\n // just retry on conflicts\n docsData.push(docData);\n } else {\n closeConnection(res, 500, 'Internal Server Error');\n throw err;\n }\n }\n\n while (docsData.length > 0) {\n const promises: Promise<any>[] = [];\n const docs = await collection.findByIds(docsData.map(d => (d as any)[primaryPath])).exec();\n let useDocsData = docsData.slice();\n docsData = [];\n for (const docData of useDocsData) {\n const id = (docData as any)[primaryPath];\n const doc = docs.get(id);\n if (!doc) {\n promises.push(this.collection.insert(docData).catch(err => onWriteError(err, docData)));\n } else {\n const isAllowed = this.changeValidator(authData, {\n newDocumentState: removeServerOnlyFields(docData as any),\n assumedMasterState: removeServerOnlyFields(doc.toJSON(true))\n });\n if (!isAllowed) {\n closeConnection(res, 403, 'Forbidden');\n return;\n }\n promises.push(doc.patch(docData).catch(err => onWriteError(err, docData)));\n }\n }\n await Promise.all(promises);\n }\n\n res.setHeader('Content-Type', 'application/json');\n res.json({\n });\n });\n\n this.server.expressApp.post('/' + this.urlPath + '/delete', async (req, res) => {\n const authData = getFromMapOrThrow(authDataByRequest, req);\n const docDataMatcherWrite = getDocAllowedMatcher(this, ensureNotFalsy(authData));\n\n let ids: string[] = req.body;\n while (ids.length > 0) {\n const useIds = ids.slice(0);\n ids = [];\n const promises: Promise<any>[] = [];\n const docsMap = await this.collection.findByIds(useIds).exec();\n for (const id of useIds) {\n const doc = docsMap.get(id);\n if (doc) {\n const isAllowedDoc = docDataMatcherWrite(doc.toJSON(true) as any);\n if (!isAllowedDoc) {\n closeConnection(res, 403, 'Forbidden');\n return;\n }\n\n const isAllowedChange = this.changeValidator(authData, {\n newDocumentState: doc.toJSON(true) as any,\n assumedMasterState: doc.toJSON(true) as any\n });\n if (!isAllowedChange) {\n closeConnection(res, 403, 'Forbidden');\n return;\n }\n\n promises.push(doc.remove().catch((err: RxError) => {\n if (err.rxdb && err.code === 'CONFLICT') {\n // just retry on conflicts\n ids.push(id);\n } else {\n closeConnection(res, 500, 'Internal Server Error');\n throw err;\n }\n }));\n }\n }\n await Promise.all(promises);\n }\n res.setHeader('Content-Type', 'application/json');\n res.json({});\n });\n }\n}\n"],"mappings":";;;;;;AAAA,IAAAA,KAAA,GAAAC,OAAA;AAYA,IAAAC,KAAA,GAAAD,OAAA;AACA,IAAAE,MAAA,GAAAF,OAAA;AAKA,IAAAG,OAAA,GAAAH,OAAA;AAaO,IAAMI,UAAU,GAAAC,OAAA,CAAAD,UAAA,GAAG,CACtB,OAAO,EACP,eAAe,EACf,KAAK,EACL,KAAK,EACL;;AAEA;AACA;AACJ;AACA;AACA;AACA,EAJI,CAKM;AAAC,IAGEE,oBAAoB,GAAAD,OAAA,CAAAC,oBAAA,GAK7B,SAAAA,qBACoBC,MAA0B,EAC1BC,IAAY,EACZC,UAAmC,EACnDC,aAAyD,EACzDC,eAA6D,EAC7CC,gBAA0B,EAC1BC,IAAa,EAC/B;EAAA,IAAAC,KAAA;EAAA,KAZOC,IAAI,GAAG,MAAM;EAAA,KAKFR,MAA0B,GAA1BA,MAA0B;EAAA,KAC1BC,IAAY,GAAZA,IAAY;EAAA,KACZC,UAAmC,GAAnCA,UAAmC;EAAA,KAGnCG,gBAA0B,GAA1BA,gBAA0B;EAAA,KAC1BC,IAAa,GAAbA,IAAa;EAE7B,IAAAG,eAAO,EAAC,IAAI,CAACT,MAAM,EAAE,CAAC,IAAI,CAACC,IAAI,CAAC,CAACS,IAAI,CAAC,GAAG,CAAC,EAAEJ,IAAI,CAAC;EACjD,IAAAK,iCAAyB,EAAC,IAAI,CAACX,MAAM,EAAE,CAAC,IAAI,CAACC,IAAI,CAAC,CAACS,IAAI,CAAC,GAAG,CAAC,EAAER,UAAU,CAACU,MAAM,CAACC,OAAO,CAAC;EAExF,IAAI,CAACC,OAAO,GAAG,CAAC,IAAI,CAACb,IAAI,EAAEC,UAAU,CAACU,MAAM,CAACC,OAAO,CAAC,CAACH,IAAI,CAAC,GAAG,CAAC;EAC/D,IAAMK,WAAW,GAAG,IAAI,CAACb,UAAU,CAACU,MAAM,CAACG,WAAW;EACtD,IAAMC,iBAAiB,GAAG,IAAAC,yBAAiB,EACvC,IAAI,CAACjB,MAAM,EACX,IAAI,CAACc,OACT,CAAC;EAED,IAAI,CAACX,aAAa,GAAG,CAACe,QAAQ,EAAEC,KAAK,KAAK;IACtC,IAAI,IAAAC,qCAA6B,EAACD,KAAK,CAACE,QAAQ,CAAC,EAAE;MAC/C,MAAM,IAAIC,KAAK,CAAC,mDAAmD,CAAC;IACxE;IACA,OAAOnB,aAAa,CAACe,QAAQ,EAAEC,KAAK,CAAC;EACzC,CAAC;EACD,IAAI,CAACf,eAAe,GAAG,CAACc,QAAQ,EAAEK,MAAM,KAAK;IACzC,IAEQA,MAAM,CAACC,kBAAkB,IACzB,IAAAC,mCAA2B,EAACpB,gBAAgB,EAAEkB,MAAM,CAACC,kBAAkB,CAAC,IAE5E,IAAAC,mCAA2B,EAACpB,gBAAgB,EAAEkB,MAAM,CAACG,gBAAgB,CAAC,EACxE;MACE,OAAO,KAAK;IAChB;IACA,OAAOtB,eAAe,CAACc,QAAQ,EAAEK,MAAM,CAAC;EAC5C,CAAC;EACD,IAAMI,sBAAsB,GAAG,IAAAC,mCAA2B,EAAC,IAAI,CAACvB,gBAAgB,CAAC;EAEjF,IAAI,CAACL,MAAM,CAAC6B,UAAU,CAACC,IAAI,CAAC,GAAG,GAAG,IAAI,CAAChB,OAAO,GAAG,QAAQ,EAAE,OAAOiB,GAAG,EAAEC,GAAG,KAAK;IAC3E,IAAMd,QAAQ,GAAG,IAAAe,wBAAiB,EAACjB,iBAAiB,EAAEe,GAAG,CAAC;IAC1D,IAAIG,QAAqC;IACzC,IAAI;MACAA,QAAQ,GAAG,IAAI,CAAC/B,aAAa,CACzB,IAAAgC,qBAAc,EAACjB,QAAQ,CAAC,EACxB,IAAAkB,yBAAmB,EACf,IAAI,CAAClC,UAAU,CAACU,MAAM,CAACyB,UAAU,EACjCN,GAAG,CAACO,IACR,CACJ,CAAC;IACL,CAAC,CAAC,OAAOC,GAAG,EAAE;MACV,IAAAC,uBAAe,EAACR,GAAG,EAAE,GAAG,EAAE,aAAa,CAAC;MACxC;IACJ;IACA,IAAMS,OAAO,GAAG,IAAI,CAACvC,UAAU,CAACwC,IAAI,CAACR,QAAe,CAAC;IACrD,IAAMS,MAAM,GAAG,MAAMF,OAAO,CAACG,IAAI,CAAC,CAAC;IACnCZ,GAAG,CAACa,SAAS,CAAC,cAAc,EAAE,kBAAkB,CAAC;IACjDb,GAAG,CAACc,IAAI,CAAC;MACLC,SAAS,EAAEJ,MAAM,CAACK,GAAG,CAACC,CAAC,IAAItB,sBAAsB,CAACsB,CAAC,CAACC,MAAM,CAAC,CAAC,CAAC;IACjE,CAAC,CAAC;EACN,CAAC,CAAC;;EAEF;AACR;AACA;AACA;AACA;EACQ,IAAI,CAAClD,MAAM,CAAC6B,UAAU,CAACsB,GAAG,CAAC,GAAG,GAAG,IAAI,CAACrC,OAAO,GAAG,gBAAgB,EAAE,OAAOiB,GAAG,EAAEC,GAAG,KAAK;IAClF,IAAId,QAAQ,GAAG,IAAAe,wBAAiB,EAACjB,iBAAiB,EAAEe,GAAG,CAAC;IACxD,IAAAqB,uBAAe,EAACpB,GAAG,CAAC;IAEpB,IAAME,QAAqC,GAAG,IAAI,CAAC/B,aAAa,CAC5D,IAAAgC,qBAAc,EAACjB,QAAQ,CAAC,EACxB,IAAAkB,yBAAmB,EACf,IAAI,CAAClC,UAAU,CAACU,MAAM,CAACyB,UAAU,EACjCgB,IAAI,CAACC,KAAK,CAACC,IAAI,CAACxB,GAAG,CAACZ,KAAK,CAACA,KAAe,CAAC,CAC9C,CACJ,CAAC;IAED,IAAMsB,OAAO,GAAG,IAAI,CAACvC,UAAU,CAACwC,IAAI,CAACR,QAAe,CAAC;IACrD,IAAMsB,YAAY,GAAGf,OAAO,CAACgB,CAAC,CAACC,IAAI,CAC/B,IAAAC,cAAQ,EAAC,MAAOhB,MAAM,IAAK;MACvB,IAAMiB,UAAU,GAAGjB,MAAM,CAACK,GAAG,CAACa,GAAG,IAAIlC,sBAAsB,CAACkC,GAAG,CAACX,MAAM,CAAC,CAAC,CAAC,CAAC;;MAE1E;AACpB;AACA;AACA;AACA;MACoB,IAAI;QACAhC,QAAQ,GAAG,MAAMlB,MAAM,CAAC8D,WAAW,CAAC/B,GAAG,CAACgC,OAAO,CAAC;MACpD,CAAC,CAAC,OAAOxB,GAAG,EAAE;QACV,IAAAC,uBAAe,EAACR,GAAG,EAAE,GAAG,EAAE,cAAc,CAAC;QACzC,OAAO,IAAI;MACf;MAEA,OAAO4B,UAAU;IACrB,CAAC,CAAC,EACF,IAAAI,YAAM,EAACC,CAAC,IAAIA,CAAC,KAAK,IAAI,CAC1B,CAAC,CAACC,SAAS,CAACN,UAAU,IAAI;MACtB5B,GAAG,CAACmC,KAAK,CAAC,QAAQ,GAAGd,IAAI,CAACe,SAAS,CAACR,UAAU,CAAC,GAAG,MAAM,CAAC;IAC7D,CAAC,CAAC;;IAEF;AACZ;AACA;IACY7B,GAAG,CAACsC,EAAE,CAAC,OAAO,EAAE,MAAM;MAClBb,YAAY,CAACc,WAAW,CAAC,CAAC;MAC1BtC,GAAG,CAACuC,GAAG,CAAC,CAAC;IACb,CAAC,CAAC;EACN,CAAC,CAAC;EAGF,IAAI,CAACvE,MAAM,CAAC6B,UAAU,CAACC,IAAI,CAAC,GAAG,GAAG,IAAI,CAAChB,OAAO,GAAG,MAAM,EAAE,OAAOiB,GAAG,EAAEC,GAAG,KAAK;IACzE,IAAMd,QAAQ,GAAG,IAAAe,wBAAiB,EAACjB,iBAAiB,EAAEe,GAAG,CAAC;IAC1D,IAAMyC,GAAa,GAAGzC,GAAG,CAACO,IAAI;IAE9B,IAAMG,OAAO,GAAG,IAAI,CAACvC,UAAU,CAACuE,SAAS,CAACD,GAAG,CAAC;IAC9C,IAAME,SAAS,GAAG,MAAMjC,OAAO,CAACG,IAAI,CAAC,CAAC;IACtC,IAAM+B,YAAY,GAAGC,KAAK,CAACC,IAAI,CAACH,SAAS,CAACI,MAAM,CAAC,CAAC,CAAC;IACnD,IAAMC,UAAU,GAAG,IAAAC,4BAAoB,EAAC,IAAI,EAAE,IAAA7C,qBAAc,EAACjB,QAAQ,CAAC,CAAC;IACvE,IAAI+D,OAAO,GAAGN,YAAY,CAAC3B,GAAG,CAACC,CAAC,IAAIA,CAAC,CAACC,MAAM,CAAC,CAAC,CAAC;IAC/C+B,OAAO,GAAGA,OAAO,CAACjB,MAAM,CAACf,CAAC,IAAI8B,UAAU,CAAC9B,CAAQ,CAAC,CAAC;IACnDgC,OAAO,GAAGA,OAAO,CAACjC,GAAG,CAACC,CAAC,IAAItB,sBAAsB,CAACsB,CAAC,CAAC,CAAC;IAErDjB,GAAG,CAACa,SAAS,CAAC,cAAc,EAAE,kBAAkB,CAAC;IACjDb,GAAG,CAACc,IAAI,CAAC;MACLC,SAAS,EAAEkC;IACf,CAAC,CAAC;EACN,CAAC,CAAC;EAEF,IAAI,CAACjF,MAAM,CAAC6B,UAAU,CAACC,IAAI,CAAC,GAAG,GAAG,IAAI,CAAChB,OAAO,GAAG,MAAM,EAAE,OAAOiB,GAAG,EAAEC,GAAG,KAAK;IACzE,IAAMd,QAAQ,GAAG,IAAAe,wBAAiB,EAACjB,iBAAiB,EAAEe,GAAG,CAAC;IAC1D,IAAMmD,mBAAmB,GAAG,IAAAF,4BAAoB,EAAC,IAAI,EAAE,IAAA7C,qBAAc,EAACjB,QAAQ,CAAC,CAAC;IAEhF,IAAIiE,QAAqB,GAAGpD,GAAG,CAACO,IAAI;IAEpC,KAAK,IAAM8C,OAAO,IAAID,QAAQ,EAAE;MAC5B,IAAME,OAAO,GAAGH,mBAAmB,CAACE,OAAc,CAAC;MACnD,IAAI,CAACC,OAAO,EAAE;QACV,IAAA7C,uBAAe,EAACR,GAAG,EAAE,GAAG,EAAE,WAAW,CAAC;QACtC;MACJ;IACJ;IAEA,SAASsD,YAAYA,CAAC/C,GAAY,EAAE6C,OAAkB,EAAE;MACpD,IAAI7C,GAAG,CAACgD,IAAI,IAAIhD,GAAG,CAACiD,IAAI,KAAK,UAAU,EAAE;QACrC;QACAL,QAAQ,CAACM,IAAI,CAACL,OAAO,CAAC;MAC1B,CAAC,MAAM;QACH,IAAA5C,uBAAe,EAACR,GAAG,EAAE,GAAG,EAAE,uBAAuB,CAAC;QAClD,MAAMO,GAAG;MACb;IACJ;IAEA,OAAO4C,QAAQ,CAACO,MAAM,GAAG,CAAC,EAAE;MACxB,IAAMC,QAAwB,GAAG,EAAE;MACnC,IAAMC,IAAI,GAAG,MAAM1F,UAAU,CAACuE,SAAS,CAACU,QAAQ,CAACnC,GAAG,CAACC,CAAC,IAAKA,CAAC,CAASlC,WAAW,CAAC,CAAC,CAAC,CAAC6B,IAAI,CAAC,CAAC;MAC1F,IAAIiD,WAAW,GAAGV,QAAQ,CAACW,KAAK,CAAC,CAAC;MAClCX,QAAQ,GAAG,EAAE;MAAC,IAAAY,KAAA,kBAAAA,CAAAC,QAAA,EACqB;UAC/B,IAAMC,EAAE,GAAIb,QAAO,CAASrE,WAAW,CAAC;UACxC,IAAM8C,GAAG,GAAG+B,IAAI,CAACzC,GAAG,CAAC8C,EAAE,CAAC;UACxB,IAAI,CAACpC,GAAG,EAAE;YACN8B,QAAQ,CAACF,IAAI,CAAClF,KAAI,CAACL,UAAU,CAACgG,MAAM,CAACd,QAAO,CAAC,CAACe,KAAK,CAAC5D,GAAG,IAAI+C,YAAY,CAAC/C,GAAG,EAAE6C,QAAO,CAAC,CAAC,CAAC;UAC3F,CAAC,MAAM;YACH,IAAMgB,SAAS,GAAG7F,KAAI,CAACH,eAAe,CAACc,QAAQ,EAAE;cAC7CQ,gBAAgB,EAAEC,sBAAsB,CAACyD,QAAc,CAAC;cACxD5D,kBAAkB,EAAEG,sBAAsB,CAACkC,GAAG,CAACX,MAAM,CAAC,IAAI,CAAC;YAC/D,CAAC,CAAC;YACF,IAAI,CAACkD,SAAS,EAAE;cACZ,IAAA5D,uBAAe,EAACR,GAAG,EAAE,GAAG,EAAE,WAAW,CAAC;cAAC;gBAAAqE,CAAA;cAAA;YAE3C;YACAV,QAAQ,CAACF,IAAI,CAAC5B,GAAG,CAACyC,KAAK,CAAClB,QAAO,CAAC,CAACe,KAAK,CAAC5D,GAAG,IAAI+C,YAAY,CAAC/C,GAAG,EAAE6C,QAAO,CAAC,CAAC,CAAC;UAC9E;QACJ,CAAC;QAAAmB,IAAA;MAhBD,KAAK,IAAMnB,QAAO,IAAIS,WAAW;QAAAU,IAAA,SAAAR,KAAA,CAAAC,QAAA;QAAA,IAAAO,IAAA,SAAAA,IAAA,CAAAF,CAAA;MAAA;MAiBjC,MAAMG,OAAO,CAACC,GAAG,CAACd,QAAQ,CAAC;IAC/B;IAEA3D,GAAG,CAACa,SAAS,CAAC,cAAc,EAAE,kBAAkB,CAAC;IACjDb,GAAG,CAACc,IAAI,CAAC,CACT,CAAC,CAAC;EACN,CAAC,CAAC;EAEF,IAAI,CAAC9C,MAAM,CAAC6B,UAAU,CAACC,IAAI,CAAC,GAAG,GAAG,IAAI,CAAChB,OAAO,GAAG,SAAS,EAAE,OAAOiB,GAAG,EAAEC,GAAG,KAAK;IAC5E,IAAMd,QAAQ,GAAG,IAAAe,wBAAiB,EAACjB,iBAAiB,EAAEe,GAAG,CAAC;IAC1D,IAAMmD,mBAAmB,GAAG,IAAAF,4BAAoB,EAAC,IAAI,EAAE,IAAA7C,qBAAc,EAACjB,QAAQ,CAAC,CAAC;IAEhF,IAAIsD,GAAa,GAAGzC,GAAG,CAACO,IAAI;IAC5B,OAAOkC,GAAG,CAACkB,MAAM,GAAG,CAAC,EAAE;MACnB,IAAMgB,MAAM,GAAGlC,GAAG,CAACsB,KAAK,CAAC,CAAC,CAAC;MAC3BtB,GAAG,GAAG,EAAE;MACR,IAAMmB,QAAwB,GAAG,EAAE;MACnC,IAAMgB,OAAO,GAAG,MAAM,IAAI,CAACzG,UAAU,CAACuE,SAAS,CAACiC,MAAM,CAAC,CAAC9D,IAAI,CAAC,CAAC;MAAC,IAAAgE,MAAA,kBAAAA,CAAAX,EAAA,EACtC;UACrB,IAAMpC,GAAG,GAAG8C,OAAO,CAACxD,GAAG,CAAC8C,EAAE,CAAC;UAC3B,IAAIpC,GAAG,EAAE;YACL,IAAMgD,YAAY,GAAG3B,mBAAmB,CAACrB,GAAG,CAACX,MAAM,CAAC,IAAI,CAAQ,CAAC;YACjE,IAAI,CAAC2D,YAAY,EAAE;cACf,IAAArE,uBAAe,EAACR,GAAG,EAAE,GAAG,EAAE,WAAW,CAAC;cAAC;gBAAAqE,CAAA;cAAA;YAE3C;YAEA,IAAMS,eAAe,GAAGvG,KAAI,CAACH,eAAe,CAACc,QAAQ,EAAE;cACnDQ,gBAAgB,EAAEmC,GAAG,CAACX,MAAM,CAAC,IAAI,CAAQ;cACzC1B,kBAAkB,EAAEqC,GAAG,CAACX,MAAM,CAAC,IAAI;YACvC,CAAC,CAAC;YACF,IAAI,CAAC4D,eAAe,EAAE;cAClB,IAAAtE,uBAAe,EAACR,GAAG,EAAE,GAAG,EAAE,WAAW,CAAC;cAAC;gBAAAqE,CAAA;cAAA;YAE3C;YAEAV,QAAQ,CAACF,IAAI,CAAC5B,GAAG,CAACkD,MAAM,CAAC,CAAC,CAACZ,KAAK,CAAE5D,GAAY,IAAK;cAC/C,IAAIA,GAAG,CAACgD,IAAI,IAAIhD,GAAG,CAACiD,IAAI,KAAK,UAAU,EAAE;gBACrC;gBACAhB,GAAG,CAACiB,IAAI,CAACQ,EAAE,CAAC;cAChB,CAAC,MAAM;gBACH,IAAAzD,uBAAe,EAACR,GAAG,EAAE,GAAG,EAAE,uBAAuB,CAAC;gBAClD,MAAMO,GAAG;cACb;YACJ,CAAC,CAAC,CAAC;UACP;QACJ,CAAC;QAAAyE,KAAA;MA5BD,KAAK,IAAMf,EAAE,IAAIS,MAAM;QAAAM,KAAA,SAAAJ,MAAA,CAAAX,EAAA;QAAA,IAAAe,KAAA,SAAAA,KAAA,CAAAX,CAAA;MAAA;MA6BvB,MAAMG,OAAO,CAACC,GAAG,CAACd,QAAQ,CAAC;IAC/B;IACA3D,GAAG,CAACa,SAAS,CAAC,cAAc,EAAE,kBAAkB,CAAC;IACjDb,GAAG,CAACc,IAAI,CAAC,CAAC,CAAC,CAAC;EAChB,CAAC,CAAC;AACN,CAAC"}
@@ -0,0 +1,173 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.addAuthMiddleware = addAuthMiddleware;
8
+ exports.blockPreviousVersionPaths = blockPreviousVersionPaths;
9
+ exports.closeConnection = closeConnection;
10
+ exports.docContainsServerOnlyFields = docContainsServerOnlyFields;
11
+ exports.doesContainRegexQuerySelector = doesContainRegexQuerySelector;
12
+ exports.getDocAllowedMatcher = getDocAllowedMatcher;
13
+ exports.mergeServerDocumentFieldsMonad = mergeServerDocumentFieldsMonad;
14
+ exports.removeServerOnlyFieldsMonad = removeServerOnlyFieldsMonad;
15
+ exports.setCors = setCors;
16
+ exports.writeSSEHeaders = writeSSEHeaders;
17
+ var _cors = _interopRequireDefault(require("cors"));
18
+ var _core = require("rxdb/plugins/core");
19
+ function setCors(server, path, cors) {
20
+ var useCors = cors;
21
+ if (!useCors) {
22
+ useCors = server.cors;
23
+ }
24
+ if (useCors) {
25
+ server.expressApp.options('/' + path + '/*', (0, _cors.default)({
26
+ origin: useCors,
27
+ // some legacy browsers (IE11, various SmartTVs) choke on 204
28
+ optionsSuccessStatus: 200
29
+ }));
30
+ }
31
+ }
32
+
33
+ /**
34
+ * "block" the previous version urls and send a 426 on them so that
35
+ * the clients know they must update.
36
+ */
37
+ function blockPreviousVersionPaths(server, path, currentVersion) {
38
+ var v = 0;
39
+ var _loop = function () {
40
+ var version = v;
41
+ server.expressApp.all('/' + path + '/' + version + '/*', (req, res) => {
42
+ closeConnection(res, 426, 'Outdated version ' + version + ' (newest is ' + currentVersion + ')');
43
+ });
44
+ v++;
45
+ };
46
+ while (v < currentVersion) {
47
+ _loop();
48
+ }
49
+ }
50
+ async function closeConnection(response, code, message) {
51
+ var responseWrite = {
52
+ code,
53
+ error: true,
54
+ message
55
+ };
56
+ response.statusCode = code;
57
+ response.set("Connection", "close");
58
+ await response.write(JSON.stringify(responseWrite));
59
+ response.end();
60
+ }
61
+ function addAuthMiddleware(server, path) {
62
+ var authDataByRequest = new WeakMap();
63
+ async function auth(req, res, next) {
64
+ try {
65
+ var authData = await server.authHandler(req.headers);
66
+ authDataByRequest.set(req, authData);
67
+ next();
68
+ } catch (err) {
69
+ closeConnection(res, 401, 'Unauthorized');
70
+ return;
71
+ }
72
+ }
73
+ server.expressApp.all('/' + path + '/*', auth, function (req, res, next) {
74
+ next();
75
+ });
76
+ return authDataByRequest;
77
+ }
78
+ var defaultMatchingQuery = {
79
+ selector: {},
80
+ skip: 0,
81
+ sort: []
82
+ };
83
+ function getDocAllowedMatcher(endpoint, authData) {
84
+ var useQuery = endpoint.queryModifier ? endpoint.queryModifier(authData, (0, _core.normalizeMangoQuery)(endpoint.collection.schema.jsonSchema, {})) : defaultMatchingQuery;
85
+ var docDataMatcher = (0, _core.getQueryMatcher)(endpoint.collection.schema.jsonSchema, useQuery);
86
+ return docDataMatcher;
87
+ }
88
+ function writeSSEHeaders(res) {
89
+ res.writeHead(200, {
90
+ /**
91
+ * Use exact these headers to make is less likely
92
+ * for people to have problems.
93
+ * @link https://www.youtube.com/watch?v=0PcMuYGJPzM
94
+ */
95
+ 'Content-Type': 'text/event-stream; charset=utf-8',
96
+ 'Connection': 'keep-alive',
97
+ 'Cache-Control': 'no-cache',
98
+ /**
99
+ * Required for nginx
100
+ * @link https://stackoverflow.com/q/61029079/3443137
101
+ */
102
+ 'X-Accel-Buffering': 'no'
103
+ });
104
+ res.flushHeaders();
105
+ }
106
+ function docContainsServerOnlyFields(serverOnlyFields, doc) {
107
+ var has = serverOnlyFields.find(field => {
108
+ return typeof doc[field] !== 'undefined';
109
+ });
110
+ return has;
111
+ }
112
+ function removeServerOnlyFieldsMonad(serverOnlyFields) {
113
+ var serverOnlyFieldsStencil = {
114
+ _meta: undefined,
115
+ _rev: undefined,
116
+ _attachments: undefined
117
+ };
118
+ serverOnlyFields.forEach(field => serverOnlyFieldsStencil[field] = undefined);
119
+ return docData => {
120
+ if (!docData) {
121
+ return docData;
122
+ }
123
+ return Object.assign({}, docData, serverOnlyFieldsStencil);
124
+ };
125
+ }
126
+ function mergeServerDocumentFieldsMonad(serverOnlyFields) {
127
+ var useFields = serverOnlyFields.slice(0);
128
+ // useFields.push('_rev');
129
+ // useFields.push('_meta');
130
+ // useFields.push('_attachments');
131
+ useFields = (0, _core.uniqueArray)(useFields);
132
+ return (clientDoc, serverDoc) => {
133
+ if (!serverDoc) {
134
+ return clientDoc;
135
+ }
136
+ var ret = (0, _core.flatClone)(clientDoc);
137
+ useFields.forEach(field => {
138
+ ret[field] = serverDoc[field];
139
+ });
140
+ return ret;
141
+ };
142
+ }
143
+
144
+ /**
145
+ * $regex queries are dangerous because they can dos-attach the
146
+ *
147
+ * @param selector
148
+ */
149
+ function doesContainRegexQuerySelector(selector) {
150
+ if (!selector) {
151
+ return false;
152
+ }
153
+ if (Array.isArray(selector)) {
154
+ var found = !!selector.find(item => doesContainRegexQuerySelector(item));
155
+ return found;
156
+ }
157
+ if (typeof selector !== 'object') {
158
+ return false;
159
+ }
160
+ var entries = Object.entries(selector);
161
+ for (var [key, value] of entries) {
162
+ if (key === '$regex') {
163
+ return true;
164
+ } else {
165
+ var has = doesContainRegexQuerySelector(value);
166
+ if (has) {
167
+ return true;
168
+ }
169
+ }
170
+ }
171
+ return false;
172
+ }
173
+ //# sourceMappingURL=helper.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"helper.js","names":["_cors","_interopRequireDefault","require","_core","setCors","server","path","cors","useCors","expressApp","options","expressCors","origin","optionsSuccessStatus","blockPreviousVersionPaths","currentVersion","v","_loop","version","all","req","res","closeConnection","response","code","message","responseWrite","error","statusCode","set","write","JSON","stringify","end","addAuthMiddleware","authDataByRequest","WeakMap","auth","next","authData","authHandler","headers","err","defaultMatchingQuery","selector","skip","sort","getDocAllowedMatcher","endpoint","useQuery","queryModifier","normalizeMangoQuery","collection","schema","jsonSchema","docDataMatcher","getQueryMatcher","writeSSEHeaders","writeHead","flushHeaders","docContainsServerOnlyFields","serverOnlyFields","doc","has","find","field","removeServerOnlyFieldsMonad","serverOnlyFieldsStencil","_meta","undefined","_rev","_attachments","forEach","docData","Object","assign","mergeServerDocumentFieldsMonad","useFields","slice","uniqueArray","clientDoc","serverDoc","ret","flatClone","doesContainRegexQuerySelector","Array","isArray","found","item","entries","key","value"],"sources":["../../../../src/plugins/server/helper.ts"],"sourcesContent":["import { RxServer } from './rx-server';\nimport expressCors from 'cors';\nimport type {\n Request,\n Response,\n NextFunction\n} from 'express';\nimport { RxServerAuthData, RxServerEndpoint } from './types';\nimport {\n FilledMangoQuery,\n MangoQuerySelector,\n RxDocumentData,\n RxReplicationWriteToMasterRow,\n flatClone,\n getQueryMatcher,\n normalizeMangoQuery,\n uniqueArray\n} from 'rxdb/plugins/core';\n\nexport function setCors(\n server: RxServer<any>,\n path: string,\n cors?: string\n) {\n let useCors = cors;\n if (!useCors) {\n useCors = server.cors;\n }\n if (useCors) {\n server.expressApp.options('/' + path + '/*', expressCors({\n origin: useCors,\n // some legacy browsers (IE11, various SmartTVs) choke on 204\n optionsSuccessStatus: 200\n }));\n }\n}\n\n/**\n * \"block\" the previous version urls and send a 426 on them so that\n * the clients know they must update.\n */\nexport function blockPreviousVersionPaths(\n server: RxServer<any>,\n path: string,\n currentVersion: number\n\n) {\n let v = 0;\n while (v < currentVersion) {\n const version = v;\n server.expressApp.all('/' + path + '/' + version + '/*', (req, res) => {\n closeConnection(res, 426, 'Outdated version ' + version + ' (newest is ' + currentVersion + ')');\n });\n v++;\n }\n}\n\n\nexport async function closeConnection(response: Response, code: number, message: string) {\n const responseWrite = {\n code,\n error: true,\n message\n };\n response.statusCode = code;\n response.set(\"Connection\", \"close\");\n await response.write(JSON.stringify(responseWrite));\n response.end();\n}\n\n\nexport function addAuthMiddleware<AuthType>(\n server: RxServer<AuthType>,\n path: string,\n): WeakMap<Request, RxServerAuthData<AuthType>> {\n const authDataByRequest = new WeakMap<Request, RxServerAuthData<AuthType>>();\n async function auth(req: Request, res: Response, next: NextFunction) {\n try {\n const authData = await server.authHandler(req.headers);\n authDataByRequest.set(req, authData);\n next();\n } catch (err) {\n closeConnection(res, 401, 'Unauthorized');\n return;\n }\n }\n server.expressApp.all('/' + path + '/*', auth, function (req, res, next) {\n next();\n });\n return authDataByRequest;\n}\n\nconst defaultMatchingQuery: FilledMangoQuery<any> = {\n selector: {},\n skip: 0,\n sort: []\n} as const;\n\nexport function getDocAllowedMatcher<RxDocType, AuthType>(\n endpoint: RxServerEndpoint<AuthType, RxDocType>,\n authData: RxServerAuthData<AuthType>\n) {\n const useQuery: FilledMangoQuery<RxDocType> = endpoint.queryModifier ? endpoint.queryModifier(\n authData,\n normalizeMangoQuery(\n endpoint.collection.schema.jsonSchema,\n {}\n )\n ) : defaultMatchingQuery;\n const docDataMatcher = getQueryMatcher(endpoint.collection.schema.jsonSchema, useQuery);\n return docDataMatcher;\n}\n\nexport function writeSSEHeaders(res: Response) {\n res.writeHead(200, {\n /**\n * Use exact these headers to make is less likely\n * for people to have problems.\n * @link https://www.youtube.com/watch?v=0PcMuYGJPzM\n */\n 'Content-Type': 'text/event-stream; charset=utf-8',\n 'Connection': 'keep-alive',\n 'Cache-Control': 'no-cache',\n /**\n * Required for nginx\n * @link https://stackoverflow.com/q/61029079/3443137\n */\n 'X-Accel-Buffering': 'no'\n });\n res.flushHeaders();\n}\n\nexport function docContainsServerOnlyFields(\n serverOnlyFields: string[],\n doc: any\n) {\n const has = serverOnlyFields.find(field => {\n return typeof doc[field] !== 'undefined'\n });\n return has;\n}\n\nexport function removeServerOnlyFieldsMonad<RxDocType>(serverOnlyFields: string[]) {\n const serverOnlyFieldsStencil: any = {\n _meta: undefined,\n _rev: undefined,\n _attachments: undefined\n };\n serverOnlyFields.forEach(field => serverOnlyFieldsStencil[field] = undefined);\n return (\n docData?: RxDocType | RxDocumentData<RxDocType>\n ) => {\n if (!docData) {\n return docData;\n }\n return Object.assign({}, docData, serverOnlyFieldsStencil);\n }\n}\n\nexport function mergeServerDocumentFieldsMonad<RxDocType>(serverOnlyFields: string[]) {\n let useFields = serverOnlyFields.slice(0);\n // useFields.push('_rev');\n // useFields.push('_meta');\n // useFields.push('_attachments');\n useFields = uniqueArray(useFields);\n\n return (\n clientDoc: RxDocType | RxDocumentData<RxDocType>,\n serverDoc?: RxDocType | RxDocumentData<RxDocType>\n ) => {\n if (!serverDoc) {\n return clientDoc;\n }\n const ret = flatClone(clientDoc);\n useFields.forEach(field => {\n (ret as any)[field] = (serverDoc as any)[field];\n });\n return ret;\n }\n}\n\n\n/**\n * $regex queries are dangerous because they can dos-attach the \n * \n * @param selector \n */\nexport function doesContainRegexQuerySelector(selector: MangoQuerySelector<any> | any): boolean {\n if (!selector) {\n return false;\n }\n if (Array.isArray(selector)) {\n const found = !!selector.find(item => doesContainRegexQuerySelector(item));\n return found;\n }\n\n if (typeof selector !== 'object') {\n return false;\n }\n\n const entries = Object.entries(selector);\n for (const [key, value] of entries) {\n if (key === '$regex') {\n return true;\n } else {\n const has = doesContainRegexQuerySelector(value);\n if (has) {\n return true;\n }\n }\n }\n\n return false;\n}\n"],"mappings":"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"}
@@ -0,0 +1,84 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ var _exportNames = {
8
+ startRxServer: true
9
+ };
10
+ exports.startRxServer = startRxServer;
11
+ var _utils = require("rxdb/plugins/utils");
12
+ var _rxServer = require("./rx-server.js");
13
+ var _express = _interopRequireDefault(require("express"));
14
+ var _types = require("./types.js");
15
+ Object.keys(_types).forEach(function (key) {
16
+ if (key === "default" || key === "__esModule") return;
17
+ if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
18
+ if (key in exports && exports[key] === _types[key]) return;
19
+ Object.defineProperty(exports, key, {
20
+ enumerable: true,
21
+ get: function () {
22
+ return _types[key];
23
+ }
24
+ });
25
+ });
26
+ var _endpointReplication = require("./endpoint-replication.js");
27
+ Object.keys(_endpointReplication).forEach(function (key) {
28
+ if (key === "default" || key === "__esModule") return;
29
+ if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
30
+ if (key in exports && exports[key] === _endpointReplication[key]) return;
31
+ Object.defineProperty(exports, key, {
32
+ enumerable: true,
33
+ get: function () {
34
+ return _endpointReplication[key];
35
+ }
36
+ });
37
+ });
38
+ var _endpointRest = require("./endpoint-rest.js");
39
+ Object.keys(_endpointRest).forEach(function (key) {
40
+ if (key === "default" || key === "__esModule") return;
41
+ if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
42
+ if (key in exports && exports[key] === _endpointRest[key]) return;
43
+ Object.defineProperty(exports, key, {
44
+ enumerable: true,
45
+ get: function () {
46
+ return _endpointRest[key];
47
+ }
48
+ });
49
+ });
50
+ var _helper = require("./helper.js");
51
+ Object.keys(_helper).forEach(function (key) {
52
+ if (key === "default" || key === "__esModule") return;
53
+ if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
54
+ if (key in exports && exports[key] === _helper[key]) return;
55
+ Object.defineProperty(exports, key, {
56
+ enumerable: true,
57
+ get: function () {
58
+ return _helper[key];
59
+ }
60
+ });
61
+ });
62
+ async function startRxServer(options) {
63
+ options = (0, _utils.flatClone)(options);
64
+ if (!options.serverApp) {
65
+ var app = (0, _express.default)();
66
+ options.serverApp = app;
67
+ }
68
+ options.serverApp.use(_express.default.json());
69
+ var httpServer = await new Promise((res, rej) => {
70
+ var hostname = options.hostname ? options.hostname : 'localhost';
71
+ var ret = (0, _utils.ensureNotFalsy)(options.serverApp).listen(options.port, hostname, () => {
72
+ res(ret);
73
+ });
74
+ });
75
+ var authHandler = options.authHandler ? options.authHandler : () => {
76
+ return {
77
+ data: {},
78
+ validUntil: Date.now() * 2
79
+ };
80
+ };
81
+ var server = new _rxServer.RxServer(options.database, authHandler, httpServer, (0, _utils.ensureNotFalsy)(options.serverApp), options.cors);
82
+ return server;
83
+ }
84
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":["_utils","require","_rxServer","_express","_interopRequireDefault","_types","Object","keys","forEach","key","prototype","hasOwnProperty","call","_exportNames","exports","defineProperty","enumerable","get","_endpointReplication","_endpointRest","_helper","startRxServer","options","flatClone","serverApp","app","express","use","json","httpServer","Promise","res","rej","hostname","ret","ensureNotFalsy","listen","port","authHandler","data","validUntil","Date","now","server","RxServer","database","cors"],"sources":["../../../../src/plugins/server/index.ts"],"sourcesContent":["import { ensureNotFalsy, flatClone } from 'rxdb/plugins/utils';\nimport { RxServer } from './rx-server.ts';\nimport { RxServerAuthHandler, RxServerOptions } from './types.ts';\nimport express from 'express';\nimport {\n Server as HttpServer\n} from 'http';\n\nexport * from './types.ts';\nexport * from './endpoint-replication.ts';\nexport * from './endpoint-rest.ts';\nexport * from './helper.ts';\n\nexport async function startRxServer<AuthType>(options: RxServerOptions<AuthType>): Promise<RxServer<AuthType>> {\n options = flatClone(options);\n if (!options.serverApp) {\n const app = express();\n options.serverApp = app;\n }\n\n options.serverApp.use(express.json());\n\n\n const httpServer: HttpServer = await new Promise((res, rej) => {\n const hostname = options.hostname ? options.hostname : 'localhost';\n const ret = ensureNotFalsy(options.serverApp).listen(options.port, hostname, () => {\n res(ret);\n });\n });\n\n const authHandler: RxServerAuthHandler<AuthType> = options.authHandler ? options.authHandler : () => {\n return {\n data: {} as any,\n validUntil: Date.now() * 2\n };\n };\n\n const server = new RxServer<AuthType>(\n options.database,\n authHandler,\n httpServer,\n ensureNotFalsy(options.serverApp),\n options.cors\n );\n\n return server;\n}\n"],"mappings":"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"}
@@ -0,0 +1,51 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.RxServer = void 0;
7
+ var _endpointReplication = require("./endpoint-replication.js");
8
+ var _endpointRest = require("./endpoint-rest.js");
9
+ var RxServer = exports.RxServer = /*#__PURE__*/function () {
10
+ function RxServer(database, authHandler, httpServer, expressApp, cors = '*') {
11
+ this.endpoints = [];
12
+ this.closeFn = (() => this.close()).bind(this);
13
+ this.database = database;
14
+ this.authHandler = authHandler;
15
+ this.httpServer = httpServer;
16
+ this.expressApp = expressApp;
17
+ this.cors = cors;
18
+ database.onDestroy.push(this.closeFn);
19
+ }
20
+ var _proto = RxServer.prototype;
21
+ _proto.addReplicationEndpoint = async function addReplicationEndpoint(opts) {
22
+ var endpoint = new _endpointReplication.RxServerReplicationEndpoint(this, opts.name, opts.collection, opts.queryModifier ? opts.queryModifier : (_a, q) => q, opts.changeValidator ? opts.changeValidator : () => true, opts.serverOnlyFields ? opts.serverOnlyFields : [], opts.cors);
23
+ this.endpoints.push(endpoint);
24
+ return endpoint;
25
+ };
26
+ _proto.addRestEndpoint = async function addRestEndpoint(opts) {
27
+ var endpoint = new _endpointRest.RxServerRestEndpoint(this, opts.name, opts.collection, opts.queryModifier ? opts.queryModifier : (_a, q) => q, opts.changeValidator ? opts.changeValidator : () => true, opts.serverOnlyFields ? opts.serverOnlyFields : [], opts.cors);
28
+ this.endpoints.push(endpoint);
29
+ return endpoint;
30
+ };
31
+ _proto.close = async function close() {
32
+ this.database.onDestroy = this.database.onDestroy.filter(fn => fn !== this.closeFn);
33
+ await new Promise((res, rej) => {
34
+ this.httpServer.close(err => {
35
+ if (err) {
36
+ rej(err);
37
+ } else {
38
+ res();
39
+ }
40
+ });
41
+ /**
42
+ * By default it will await all ongoing connections
43
+ * before it closes. So we have to close it directly.
44
+ * @link https://stackoverflow.com/a/36830072/3443137
45
+ */
46
+ setImmediate(() => this.httpServer.emit('close'));
47
+ });
48
+ };
49
+ return RxServer;
50
+ }();
51
+ //# sourceMappingURL=rx-server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rx-server.js","names":["_endpointReplication","require","_endpointRest","RxServer","exports","database","authHandler","httpServer","expressApp","cors","endpoints","closeFn","close","bind","onDestroy","push","_proto","prototype","addReplicationEndpoint","opts","endpoint","RxServerReplicationEndpoint","name","collection","queryModifier","_a","q","changeValidator","serverOnlyFields","addRestEndpoint","RxServerRestEndpoint","filter","fn","Promise","res","rej","err","setImmediate","emit"],"sources":["../../../../src/plugins/server/rx-server.ts"],"sourcesContent":["import type {\n RxCollection,\n RxDatabase\n} from 'rxdb/plugins/core';\nimport { RxServerReplicationEndpoint } from './endpoint-replication.ts';\nimport type {\n RxServerAuthHandler,\n RxServerChangeValidator,\n RxServerEndpoint,\n RxServerQueryModifier\n} from './types.ts';\nimport {\n Server as HttpServer\n} from 'http';\nimport { Express } from 'express';\nimport { RxServerRestEndpoint } from './endpoint-rest.ts';\n\nexport class RxServer<AuthType> {\n public readonly endpoints: RxServerEndpoint<AuthType, any>[] = [];\n\n private closeFn = (() => this.close()).bind(this);\n\n constructor(\n public readonly database: RxDatabase,\n public readonly authHandler: RxServerAuthHandler<AuthType>,\n public readonly httpServer: HttpServer,\n public readonly expressApp: Express,\n public readonly cors: string = '*'\n ) {\n database.onDestroy.push(this.closeFn);\n }\n\n public async addReplicationEndpoint<RxDocType>(opts: {\n name: string,\n collection: RxCollection<RxDocType>,\n queryModifier?: RxServerQueryModifier<AuthType, RxDocType>,\n changeValidator?: RxServerChangeValidator<AuthType, RxDocType>,\n /**\n * Set a origin for allowed CORS requests.\n * Overwrites the cors option of the server.\n * [default='*']\n */\n cors?: '*' | string,\n serverOnlyFields?: string[]\n }) {\n const endpoint = new RxServerReplicationEndpoint(\n this,\n opts.name,\n opts.collection,\n opts.queryModifier ? opts.queryModifier : (_a, q) => q,\n opts.changeValidator ? opts.changeValidator : () => true,\n opts.serverOnlyFields ? opts.serverOnlyFields : [],\n opts.cors\n );\n this.endpoints.push(endpoint);\n return endpoint;\n }\n\n public async addRestEndpoint<RxDocType>(opts: {\n name: string,\n collection: RxCollection<RxDocType>,\n queryModifier?: RxServerQueryModifier<AuthType, RxDocType>,\n changeValidator?: RxServerChangeValidator<AuthType, RxDocType>,\n /**\n * Set a origin for allowed CORS requests.\n * Overwrites the cors option of the server.\n * [default='*']\n */\n cors?: '*' | string,\n serverOnlyFields?: string[]\n }) {\n const endpoint = new RxServerRestEndpoint(\n this,\n opts.name,\n opts.collection,\n opts.queryModifier ? opts.queryModifier : (_a, q) => q,\n opts.changeValidator ? opts.changeValidator : () => true,\n opts.serverOnlyFields ? opts.serverOnlyFields : [],\n opts.cors\n );\n this.endpoints.push(endpoint);\n return endpoint;\n }\n\n async close() {\n this.database.onDestroy = this.database.onDestroy.filter(fn => fn !== this.closeFn);\n await new Promise<void>((res, rej) => {\n this.httpServer.close((err) => {\n if (err) { rej(err); } else { res(); }\n });\n /**\n * By default it will await all ongoing connections\n * before it closes. So we have to close it directly.\n * @link https://stackoverflow.com/a/36830072/3443137\n */\n setImmediate(() => this.httpServer.emit('close'));\n });\n\n }\n}\n"],"mappings":";;;;;;AAIA,IAAAA,oBAAA,GAAAC,OAAA;AAWA,IAAAC,aAAA,GAAAD,OAAA;AAA0D,IAE7CE,QAAQ,GAAAC,OAAA,CAAAD,QAAA;EAKjB,SAAAA,SACoBE,QAAoB,EACpBC,WAA0C,EAC1CC,UAAsB,EACtBC,UAAmB,EACnBC,IAAY,GAAG,GAAG,EACpC;IAAA,KAVcC,SAAS,GAAsC,EAAE;IAAA,KAEzDC,OAAO,GAAG,CAAC,MAAM,IAAI,CAACC,KAAK,CAAC,CAAC,EAAEC,IAAI,CAAC,IAAI,CAAC;IAAA,KAG7BR,QAAoB,GAApBA,QAAoB;IAAA,KACpBC,WAA0C,GAA1CA,WAA0C;IAAA,KAC1CC,UAAsB,GAAtBA,UAAsB;IAAA,KACtBC,UAAmB,GAAnBA,UAAmB;IAAA,KACnBC,IAAY,GAAZA,IAAY;IAE5BJ,QAAQ,CAACS,SAAS,CAACC,IAAI,CAAC,IAAI,CAACJ,OAAO,CAAC;EACzC;EAAC,IAAAK,MAAA,GAAAb,QAAA,CAAAc,SAAA;EAAAD,MAAA,CAEYE,sBAAsB,GAAnC,eAAAA,uBAA+CC,IAY9C,EAAE;IACC,IAAMC,QAAQ,GAAG,IAAIC,gDAA2B,CAC5C,IAAI,EACJF,IAAI,CAACG,IAAI,EACTH,IAAI,CAACI,UAAU,EACfJ,IAAI,CAACK,aAAa,GAAGL,IAAI,CAACK,aAAa,GAAG,CAACC,EAAE,EAAEC,CAAC,KAAKA,CAAC,EACtDP,IAAI,CAACQ,eAAe,GAAGR,IAAI,CAACQ,eAAe,GAAG,MAAM,IAAI,EACxDR,IAAI,CAACS,gBAAgB,GAAGT,IAAI,CAACS,gBAAgB,GAAG,EAAE,EAClDT,IAAI,CAACV,IACT,CAAC;IACD,IAAI,CAACC,SAAS,CAACK,IAAI,CAACK,QAAQ,CAAC;IAC7B,OAAOA,QAAQ;EACnB,CAAC;EAAAJ,MAAA,CAEYa,eAAe,GAA5B,eAAAA,gBAAwCV,IAYvC,EAAE;IACC,IAAMC,QAAQ,GAAG,IAAIU,kCAAoB,CACrC,IAAI,EACJX,IAAI,CAACG,IAAI,EACTH,IAAI,CAACI,UAAU,EACfJ,IAAI,CAACK,aAAa,GAAGL,IAAI,CAACK,aAAa,GAAG,CAACC,EAAE,EAAEC,CAAC,KAAKA,CAAC,EACtDP,IAAI,CAACQ,eAAe,GAAGR,IAAI,CAACQ,eAAe,GAAG,MAAM,IAAI,EACxDR,IAAI,CAACS,gBAAgB,GAAGT,IAAI,CAACS,gBAAgB,GAAG,EAAE,EAClDT,IAAI,CAACV,IACT,CAAC;IACD,IAAI,CAACC,SAAS,CAACK,IAAI,CAACK,QAAQ,CAAC;IAC7B,OAAOA,QAAQ;EACnB,CAAC;EAAAJ,MAAA,CAEKJ,KAAK,GAAX,eAAAA,MAAA,EAAc;IACV,IAAI,CAACP,QAAQ,CAACS,SAAS,GAAG,IAAI,CAACT,QAAQ,CAACS,SAAS,CAACiB,MAAM,CAACC,EAAE,IAAIA,EAAE,KAAK,IAAI,CAACrB,OAAO,CAAC;IACnF,MAAM,IAAIsB,OAAO,CAAO,CAACC,GAAG,EAAEC,GAAG,KAAK;MAClC,IAAI,CAAC5B,UAAU,CAACK,KAAK,CAAEwB,GAAG,IAAK;QAC3B,IAAIA,GAAG,EAAE;UAAED,GAAG,CAACC,GAAG,CAAC;QAAE,CAAC,MAAM;UAAEF,GAAG,CAAC,CAAC;QAAE;MACzC,CAAC,CAAC;MACF;AACZ;AACA;AACA;AACA;MACYG,YAAY,CAAC,MAAM,IAAI,CAAC9B,UAAU,CAAC+B,IAAI,CAAC,OAAO,CAAC,CAAC;IACrD,CAAC,CAAC;EAEN,CAAC;EAAA,OAAAnC,QAAA;AAAA"}