proto.io 0.0.161 → 0.0.163

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 (38) hide show
  1. package/dist/adapters/file/database.d.ts +2 -2
  2. package/dist/adapters/file/database.mjs +2 -2
  3. package/dist/adapters/file/filesystem.d.ts +2 -2
  4. package/dist/adapters/file/google-cloud-storage.d.ts +2 -2
  5. package/dist/adapters/storage/progres.d.ts +1 -1
  6. package/dist/adapters/storage/progres.mjs +3 -3
  7. package/dist/client.d.ts +3 -3
  8. package/dist/client.js +1 -1
  9. package/dist/client.mjs +3 -3
  10. package/dist/index.d.ts +3 -3
  11. package/dist/index.js +117 -59
  12. package/dist/index.js.map +1 -1
  13. package/dist/index.mjs +121 -63
  14. package/dist/index.mjs.map +1 -1
  15. package/dist/internals/{index-2EQQyKaU.d.ts → index-BeV63sFw.d.ts} +2 -2
  16. package/dist/internals/index-BeV63sFw.d.ts.map +1 -0
  17. package/dist/internals/{index-B01TqoO1.mjs → index-BoP4kl2R.mjs} +49 -25
  18. package/dist/internals/index-BoP4kl2R.mjs.map +1 -0
  19. package/dist/internals/{index-CHKUNXoz.d.ts → index-BsuUdR0W.d.ts} +3 -3
  20. package/dist/internals/index-BsuUdR0W.d.ts.map +1 -0
  21. package/dist/internals/{index-BmRuvHVZ.mjs → index-ByfpVHca.mjs} +2 -2
  22. package/dist/internals/index-ByfpVHca.mjs.map +1 -0
  23. package/dist/internals/index-CVutVPmd.js.map +1 -1
  24. package/dist/internals/{index-Bs06MNCK.js → index-Dz3jvqxZ.js} +48 -24
  25. package/dist/internals/index-Dz3jvqxZ.js.map +1 -0
  26. package/dist/internals/{index-tU-lsQqj.mjs → index-S5Bq-KsU.mjs} +2 -2
  27. package/dist/internals/{index-tU-lsQqj.mjs.map → index-S5Bq-KsU.mjs.map} +1 -1
  28. package/dist/internals/{index-CXLttbg-.d.ts → index-YdOGTHp1.d.ts} +5 -6
  29. package/dist/internals/index-YdOGTHp1.d.ts.map +1 -0
  30. package/dist/internals/{random-DifCxbl6.mjs → random-w8WDYQEe.mjs} +4 -4
  31. package/dist/internals/{random-DifCxbl6.mjs.map → random-w8WDYQEe.mjs.map} +1 -1
  32. package/package.json +1 -1
  33. package/dist/internals/index-2EQQyKaU.d.ts.map +0 -1
  34. package/dist/internals/index-B01TqoO1.mjs.map +0 -1
  35. package/dist/internals/index-BmRuvHVZ.mjs.map +0 -1
  36. package/dist/internals/index-Bs06MNCK.js.map +0 -1
  37. package/dist/internals/index-CHKUNXoz.d.ts.map +0 -1
  38. package/dist/internals/index-CXLttbg-.d.ts.map +0 -1
@@ -1,5 +1,5 @@
1
- import { T as TSchema, P as ProtoService } from '../../internals/index-CXLttbg-.js';
2
- import { F as FileStorageBase, a as FileStorageOptions } from '../../internals/index-2EQQyKaU.js';
1
+ import { T as TSchema, P as ProtoService } from '../../internals/index-YdOGTHp1.js';
2
+ import { F as FileStorageBase, a as FileStorageOptions } from '../../internals/index-BeV63sFw.js';
3
3
  import '@o2ter/utils-js';
4
4
  import 'jsonwebtoken';
5
5
  import '@o2ter/server-js';
@@ -1,11 +1,11 @@
1
1
  import _ from 'lodash';
2
2
  import { F as FileStorageBase } from '../../internals/index-be1VYBY2.mjs';
3
- import { Q as QuerySelector } from '../../internals/index-tU-lsQqj.mjs';
3
+ import { Q as QuerySelector } from '../../internals/index-S5Bq-KsU.mjs';
4
4
  import { bufferToBase64, base64ToBuffer } from '@o2ter/utils-js';
5
5
  import 'util';
6
6
  import 'zlib';
7
7
  import '../../internals/private-BUpLAMZi.mjs';
8
- import '../../internals/index-BmRuvHVZ.mjs';
8
+ import '../../internals/index-ByfpVHca.mjs';
9
9
  import 'decimal.js';
10
10
 
11
11
  //
@@ -1,5 +1,5 @@
1
- import { P as ProtoService } from '../../internals/index-CXLttbg-.js';
2
- import { F as FileStorageBase, a as FileStorageOptions } from '../../internals/index-2EQQyKaU.js';
1
+ import { P as ProtoService } from '../../internals/index-YdOGTHp1.js';
2
+ import { F as FileStorageBase, a as FileStorageOptions } from '../../internals/index-BeV63sFw.js';
3
3
  import '@o2ter/utils-js';
4
4
  import 'jsonwebtoken';
5
5
  import '@o2ter/server-js';
@@ -1,7 +1,7 @@
1
1
  import * as _google_cloud_storage from '@google-cloud/storage';
2
2
  import { Storage } from '@google-cloud/storage';
3
- import { P as ProtoService } from '../../internals/index-CXLttbg-.js';
4
- import { F as FileStorageBase, a as FileStorageOptions } from '../../internals/index-2EQQyKaU.js';
3
+ import { P as ProtoService } from '../../internals/index-YdOGTHp1.js';
4
+ import { F as FileStorageBase, a as FileStorageOptions } from '../../internals/index-BeV63sFw.js';
5
5
  import '@o2ter/utils-js';
6
6
  import 'jsonwebtoken';
7
7
  import '@o2ter/server-js';
@@ -1,5 +1,5 @@
1
1
  import { Pool, PoolClient, PoolConfig } from 'pg';
2
- import { _ as _TValue, n as EventData, T as TSchema, o as DecodedQuery, F as FindOptions, R as RelationOptions, Q as QuerySelector, p as DecodedSortOption, I as InsertOptions, q as TValue, r as FindOneOptions, t as TUpdateOp, u as FieldSelectorExpression, v as QueryExpression, w as TStorage, x as TransactionOptions, h as TObject, y as TQueryRandomOptions, z as TPubSub } from '../../internals/index-CXLttbg-.js';
2
+ import { _ as _TValue, o as EventData, T as TSchema, p as DecodedQuery, F as FindOptions, R as RelationOptions, Q as QuerySelector, q as DecodedSortOption, I as InsertOptions, r as TValue, t as FindOneOptions, u as TUpdateOp, v as FieldSelectorExpression, w as QueryExpression, x as TStorage, y as TransactionOptions, h as TObject, z as TQueryRandomOptions, A as TPubSub } from '../../internals/index-YdOGTHp1.js';
3
3
  import * as _o2ter_utils_js from '@o2ter/utils-js';
4
4
  import { asyncStream } from '@o2ter/utils-js';
5
5
  import 'jsonwebtoken';
@@ -1,13 +1,13 @@
1
1
  import _ from 'lodash';
2
- import { a as isPointer, b as isRelation, i as isShape, d as decodeUpdateOp, s as shapePaths, e as isPrimitive, T as TObject, f as isVector, _ as _decodeValue, g as _encodeValue, h as dimensionOf, j as _typeof } from '../../internals/index-BmRuvHVZ.mjs';
2
+ import { i as isPointer, a as isRelation, b as isShape, d as decodeUpdateOp, s as shapePaths, e as isPrimitive, T as TObject, f as isVector, _ as _decodeValue, g as _encodeValue, h as dimensionOf, j as _typeof } from '../../internals/index-ByfpVHca.mjs';
3
3
  import { Pool, types } from 'pg';
4
4
  import QueryStream from 'pg-query-stream';
5
5
  import { asyncStream } from '@o2ter/utils-js';
6
6
  import Decimal from 'decimal.js';
7
7
  import { escapeLiteral, escapeIdentifier } from 'pg/lib/utils';
8
- import { a as QueryCoditionalSelector, b as QueryFieldSelector, c as QueryExpressionSelector, d as QueryDistanceExpression, e as QueryCoditionalExpression, f as QueryComparisonExpression, g as QueryNotExpression, h as QueryArrayExpression, i as QueryValueExpression, j as QueryKeyExpression, Q as QuerySelector, F as FieldSelectorExpression } from '../../internals/index-tU-lsQqj.mjs';
8
+ import { a as QueryCoditionalSelector, b as QueryFieldSelector, c as QueryExpressionSelector, d as QueryDistanceExpression, e as QueryCoditionalExpression, f as QueryComparisonExpression, g as QueryNotExpression, h as QueryArrayExpression, i as QueryValueExpression, j as QueryKeyExpression, Q as QuerySelector, F as FieldSelectorExpression } from '../../internals/index-S5Bq-KsU.mjs';
9
9
  import '@o2ter/crypto-js';
10
- import { a as resolveColumn, r as resolveDataType, g as generateId, Q as QueryValidator } from '../../internals/random-DifCxbl6.mjs';
10
+ import { r as resolveColumn, a as resolveDataType, g as generateId, Q as QueryValidator } from '../../internals/random-w8WDYQEe.mjs';
11
11
  import { P as PVK } from '../../internals/private-BUpLAMZi.mjs';
12
12
 
13
13
  //
package/dist/client.d.ts CHANGED
@@ -1,7 +1,7 @@
1
- import { P as ProtoClient } from './internals/index-CHKUNXoz.js';
2
- export { c as classExtends, e as isFile, a as isObject, i as isQuery, d as isRole, b as isUser } from './internals/index-CHKUNXoz.js';
1
+ import { P as ProtoClient } from './internals/index-BsuUdR0W.js';
2
+ export { c as classExtends, e as isFile, a as isObject, i as isQuery, d as isRole, b as isUser } from './internals/index-BsuUdR0W.js';
3
3
  export { Decimal } from 'decimal.js';
4
- export { D as DeserializeOptions, S as SerializeOptions, d as TSerializable, e as deserialize, s as serialize } from './internals/index-CXLttbg-.js';
4
+ export { D as DeserializeOptions, S as SerializeOptions, d as TSerializable, e as deserialize, s as serialize } from './internals/index-YdOGTHp1.js';
5
5
  import '@o2ter/utils-js';
6
6
  import 'socket.io-client';
7
7
  import '@socket.io/component-emitter';
package/dist/client.js CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- var index = require('./internals/index-Bs06MNCK.js');
5
+ var index = require('./internals/index-Dz3jvqxZ.js');
6
6
  var Decimal = require('decimal.js');
7
7
  require('./internals/index-CVutVPmd.js');
8
8
  require('lodash');
package/dist/client.mjs CHANGED
@@ -1,7 +1,7 @@
1
- import { c as ProtoClient } from './internals/index-B01TqoO1.mjs';
2
- export { e as classExtends, d as deserialize, j as isFile, f as isObject, i as isQuery, h as isRole, g as isUser, s as serialize } from './internals/index-B01TqoO1.mjs';
1
+ import { c as ProtoClient } from './internals/index-BoP4kl2R.mjs';
2
+ export { e as classExtends, d as deserialize, j as isFile, f as isObject, i as isQuery, h as isRole, g as isUser, s as serialize } from './internals/index-BoP4kl2R.mjs';
3
3
  export { Decimal } from 'decimal.js';
4
- import './internals/index-BmRuvHVZ.mjs';
4
+ import './internals/index-ByfpVHca.mjs';
5
5
  import 'lodash';
6
6
  import './internals/private-BUpLAMZi.mjs';
7
7
  import '@o2ter/utils-js';
package/dist/index.d.ts CHANGED
@@ -2,11 +2,11 @@ import * as socket_io from 'socket.io';
2
2
  import * as socket_io_dist_typed_events from 'socket.io/dist/typed-events';
3
3
  import * as express_serve_static_core from 'express-serve-static-core';
4
4
  import { Server, RequestHandler } from '@o2ter/server-js';
5
- import { T as TSchema, _ as _TValue, P as ProtoService, a as ProtoServiceOptions, b as ProtoServiceKeyOptions } from './internals/index-CXLttbg-.js';
6
- export { D as DeserializeOptions, S as SerializeOptions, c as TFileStorage, d as TSerializable, e as deserialize, s as serialize } from './internals/index-CXLttbg-.js';
5
+ import { T as TSchema, _ as _TValue, P as ProtoService, a as ProtoServiceOptions, b as ProtoServiceKeyOptions } from './internals/index-YdOGTHp1.js';
6
+ export { D as DeserializeOptions, S as SerializeOptions, c as TFileStorage, d as TSerializable, e as deserialize, s as serialize } from './internals/index-YdOGTHp1.js';
7
7
  import Decimal from 'decimal.js';
8
8
  export { Decimal } from 'decimal.js';
9
- export { P as ProtoClient, c as classExtends, e as isFile, a as isObject, i as isQuery, d as isRole, b as isUser } from './internals/index-CHKUNXoz.js';
9
+ export { P as ProtoClient, c as classExtends, e as isFile, a as isObject, i as isQuery, d as isRole, b as isUser } from './internals/index-BsuUdR0W.js';
10
10
  import '@o2ter/utils-js';
11
11
  import 'jsonwebtoken';
12
12
  import 'lodash';
package/dist/index.js CHANGED
@@ -7,7 +7,7 @@ var serverJs = require('@o2ter/server-js');
7
7
  var random = require('./internals/random-uT4D0y_q.js');
8
8
  var _private = require('./internals/private-CSB1Ep4g.js');
9
9
  var utilsJs = require('@o2ter/utils-js');
10
- var index = require('./internals/index-Bs06MNCK.js');
10
+ var index = require('./internals/index-Dz3jvqxZ.js');
11
11
  var index$1 = require('./internals/index-CVutVPmd.js');
12
12
  var jwt = require('jsonwebtoken');
13
13
  var node_buffer = require('node:buffer');
@@ -319,19 +319,19 @@ const _serviceOf = (options) => options?.session instanceof ProtoService ? optio
319
319
  // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
320
320
  // THE SOFTWARE.
321
321
  //
322
- class ProtoQuery extends index.TQuery {
322
+ class _ProtoQuery extends index.TQuery {
323
323
  _proto;
324
324
  _opts;
325
- constructor(className, proto, opts) {
326
- super(className);
325
+ constructor(proto, opts) {
326
+ super();
327
327
  this._proto = proto;
328
328
  this._opts = opts;
329
329
  }
330
330
  get _queryOptions() {
331
331
  return {
332
+ ...this[_private.PVK].options,
332
333
  className: this.className,
333
334
  relatedBy: this._opts.relatedBy,
334
- ...this[_private.PVK].options,
335
335
  };
336
336
  }
337
337
  _dispatcher(options) {
@@ -347,11 +347,6 @@ class ProtoQuery extends index.TQuery {
347
347
  count(options) {
348
348
  return this._dispatcher(options).count(this._queryOptions);
349
349
  }
350
- clone(options) {
351
- const clone = new ProtoQuery(this.className, this._proto, this._opts);
352
- clone[_private.PVK].options = options ?? { ...this[_private.PVK].options };
353
- return clone;
354
- }
355
350
  _objectMethods(object) {
356
351
  return this._proto.rebind(object);
357
352
  }
@@ -541,6 +536,38 @@ class ProtoQuery extends index.TQuery {
541
536
  return this._dispatcher(options).deleteMany(this._queryOptions);
542
537
  }
543
538
  }
539
+ class ProtoQuery extends _ProtoQuery {
540
+ _className;
541
+ constructor(className, proto, opts) {
542
+ super(proto, opts);
543
+ this._className = className;
544
+ }
545
+ get className() {
546
+ return this._className;
547
+ }
548
+ clone(options) {
549
+ const clone = new ProtoQuery(this.className, this._proto, this._opts);
550
+ clone[_private.PVK].options = options ?? { ...this[_private.PVK].options };
551
+ return clone;
552
+ }
553
+ }
554
+ class ProtoRelationQuery extends _ProtoQuery {
555
+ constructor(proto, opts) {
556
+ super(proto, opts);
557
+ }
558
+ get className() {
559
+ const { className, key } = this._opts.relatedBy;
560
+ const { dataType } = random.resolveColumn(this._proto.schema, className, key);
561
+ if (!index$1.isPointer(dataType) && !index$1.isRelation(dataType))
562
+ throw Error(`Invalid relation key: ${key}`);
563
+ return dataType.target;
564
+ }
565
+ clone(options) {
566
+ const clone = new ProtoRelationQuery(this._proto, this._opts);
567
+ clone[_private.PVK].options = options ?? { ...this[_private.PVK].options };
568
+ return clone;
569
+ }
570
+ }
544
571
 
545
572
  //
546
573
  // defaults.ts
@@ -1384,11 +1411,11 @@ class ProtoService extends index.ProtoType {
1384
1411
  Query(className) {
1385
1412
  return new ProtoQuery(className, this, {});
1386
1413
  }
1387
- Relation(className, object, key) {
1414
+ Relation(object, key) {
1388
1415
  const objectId = object.objectId;
1389
1416
  if (!objectId)
1390
1417
  throw Error('Invalid object');
1391
- return new ProtoQuery(className, this, {
1418
+ return new ProtoRelationQuery(this, {
1392
1419
  relatedBy: {
1393
1420
  className: object.className,
1394
1421
  objectId,
@@ -1673,64 +1700,70 @@ const verifyRelatedBy = (relatedBy) => {
1673
1700
  throw Error('Invalid option');
1674
1701
  };
1675
1702
  var classesRoute = (router, proto) => {
1703
+ const defaultHandler = async (req) => {
1704
+ const { name } = req.params;
1705
+ const { operation, context, silent, random, attributes, update, setOnInsert, relatedBy, ...options } = index.deserialize(req.body);
1706
+ verifyRelatedBy(relatedBy);
1707
+ const payload = proto.connect(req);
1708
+ const query = relatedBy ? payload.Relation(payload.Object(relatedBy.className, relatedBy.objectId), relatedBy.key) : payload.Query(name);
1709
+ query[_private.PVK].options = options;
1710
+ const opts = { master: payload.isMaster, context, silent };
1711
+ switch (operation) {
1712
+ case 'explain':
1713
+ if (!payload.isMaster)
1714
+ throw Error('No permission');
1715
+ return query.explain(opts);
1716
+ case 'count': return query.count(opts);
1717
+ case 'find':
1718
+ {
1719
+ const maxFetchLimit = payload[_private.PVK].options.maxFetchLimit;
1720
+ query[_private.PVK].options.limit = query[_private.PVK].options.limit ?? maxFetchLimit;
1721
+ if (query[_private.PVK].options.limit > maxFetchLimit)
1722
+ throw Error('Query over limit');
1723
+ return await query.find(opts);
1724
+ }
1725
+ case 'random':
1726
+ {
1727
+ const maxFetchLimit = payload[_private.PVK].options.maxFetchLimit;
1728
+ query[_private.PVK].options.limit = query[_private.PVK].options.limit ?? maxFetchLimit;
1729
+ if (query[_private.PVK].options.limit > maxFetchLimit)
1730
+ throw Error('Query over limit');
1731
+ return await query.random(random, opts);
1732
+ }
1733
+ case 'nonrefs':
1734
+ {
1735
+ const maxFetchLimit = payload[_private.PVK].options.maxFetchLimit;
1736
+ query[_private.PVK].options.limit = query[_private.PVK].options.limit ?? maxFetchLimit;
1737
+ if (query[_private.PVK].options.limit > maxFetchLimit)
1738
+ throw Error('Query over limit');
1739
+ return await query.nonrefs(opts);
1740
+ }
1741
+ case 'insert': return query.insert(attributes, opts);
1742
+ case 'insertMany': return query.insertMany(attributes, opts);
1743
+ case 'updateOne': return query.updateOne(update, opts);
1744
+ case 'upsertOne': return query.upsertOne(update, setOnInsert, opts);
1745
+ case 'deleteOne': return query.deleteOne(opts);
1746
+ case 'deleteMany': return query.deleteMany(opts);
1747
+ default: throw Error('Invalid operation');
1748
+ }
1749
+ };
1676
1750
  router.post('/classes/:name', serverJs.Server.text({ type: '*/*' }), async (req, res) => {
1677
1751
  res.setHeader('Cache-Control', ['no-cache', 'no-store']);
1678
1752
  const { name } = req.params;
1679
1753
  const classes = proto.classes();
1680
1754
  if (!_.includes(classes, name))
1681
1755
  return res.sendStatus(404);
1682
- await response(res, async () => {
1683
- const { operation, context, silent, random, attributes, update, setOnInsert, relatedBy, ...options } = index.deserialize(req.body);
1684
- verifyRelatedBy(relatedBy);
1685
- const payload = proto.connect(req);
1686
- const query = relatedBy ? payload.Relation(name, payload.Object(relatedBy.className, relatedBy.objectId), relatedBy.key) : payload.Query(name);
1687
- query[_private.PVK].options = options;
1688
- const opts = { master: payload.isMaster, context, silent };
1689
- switch (operation) {
1690
- case 'explain':
1691
- if (!payload.isMaster)
1692
- throw Error('No permission');
1693
- return query.explain(opts);
1694
- case 'count': return query.count(opts);
1695
- case 'find':
1696
- {
1697
- const maxFetchLimit = payload[_private.PVK].options.maxFetchLimit;
1698
- query[_private.PVK].options.limit = query[_private.PVK].options.limit ?? maxFetchLimit;
1699
- if (query[_private.PVK].options.limit > maxFetchLimit)
1700
- throw Error('Query over limit');
1701
- return await query.find(opts);
1702
- }
1703
- case 'random':
1704
- {
1705
- const maxFetchLimit = payload[_private.PVK].options.maxFetchLimit;
1706
- query[_private.PVK].options.limit = query[_private.PVK].options.limit ?? maxFetchLimit;
1707
- if (query[_private.PVK].options.limit > maxFetchLimit)
1708
- throw Error('Query over limit');
1709
- return await query.random(random, opts);
1710
- }
1711
- case 'nonrefs':
1712
- {
1713
- const maxFetchLimit = payload[_private.PVK].options.maxFetchLimit;
1714
- query[_private.PVK].options.limit = query[_private.PVK].options.limit ?? maxFetchLimit;
1715
- if (query[_private.PVK].options.limit > maxFetchLimit)
1716
- throw Error('Query over limit');
1717
- return await query.nonrefs(opts);
1718
- }
1719
- case 'insert': return query.insert(attributes, opts);
1720
- case 'insertMany': return query.insertMany(attributes, opts);
1721
- case 'updateOne': return query.updateOne(update, opts);
1722
- case 'upsertOne': return query.upsertOne(update, setOnInsert, opts);
1723
- case 'deleteOne': return query.deleteOne(opts);
1724
- case 'deleteMany': return query.deleteMany(opts);
1725
- default: throw Error('Invalid operation');
1726
- }
1727
- });
1756
+ await response(res, () => defaultHandler(req));
1757
+ });
1758
+ router.post('/relation', serverJs.Server.text({ type: '*/*' }), async (req, res) => {
1759
+ res.setHeader('Cache-Control', ['no-cache', 'no-store']);
1760
+ await response(res, () => defaultHandler(req));
1728
1761
  });
1729
1762
  const createQuery = (payload, req, checkLimit) => {
1730
1763
  const { name } = req.params;
1731
1764
  const { filter, sort, includes, skip, limit, relatedBy, } = req.query;
1732
1765
  verifyRelatedBy(relatedBy);
1733
- const query = relatedBy ? payload.Relation(name, payload.Object(relatedBy.className, relatedBy.objectId), relatedBy.key) : payload.Query(name);
1766
+ const query = relatedBy ? payload.Relation(payload.Object(relatedBy.className, relatedBy.objectId), relatedBy.key) : payload.Query(name);
1734
1767
  query[_private.PVK].options.filter = !_.isEmpty(filter) && _.isString(filter) ? _.castArray(index.deserialize(filter)) : [];
1735
1768
  query[_private.PVK].options.sort = _.isPlainObject(sort) && _.every(_.values(sort), _.isNumber) ? sort : undefined;
1736
1769
  query[_private.PVK].options.includes = _.isArray(includes) && _.every(includes, _.isString) ? includes : undefined;
@@ -1755,6 +1788,11 @@ var classesRoute = (router, proto) => {
1755
1788
  const payload = proto.connect(req);
1756
1789
  await response(res, async () => createQuery(payload, req, true).find({ master: payload.isMaster }));
1757
1790
  });
1791
+ router.get('/relation', queryType.middleware(), async (req, res) => {
1792
+ res.setHeader('Cache-Control', ['no-cache', 'no-store']);
1793
+ const payload = proto.connect(req);
1794
+ await response(res, async () => createQuery(payload, req, true).find({ master: payload.isMaster }));
1795
+ });
1758
1796
  router.get('/classes/:name/random', queryType.middleware(), async (req, res) => {
1759
1797
  res.setHeader('Cache-Control', ['no-cache', 'no-store']);
1760
1798
  const { name } = req.params;
@@ -1767,6 +1805,14 @@ var classesRoute = (router, proto) => {
1767
1805
  throw Error('Invalid operation');
1768
1806
  await response(res, async () => createQuery(payload, req, true).random({ weight }, { master: payload.isMaster }));
1769
1807
  });
1808
+ router.get('/relation/random', queryType.middleware(), async (req, res) => {
1809
+ res.setHeader('Cache-Control', ['no-cache', 'no-store']);
1810
+ const payload = proto.connect(req);
1811
+ const { weight } = req.query;
1812
+ if (_.isEmpty(weight) || !_.isString(weight))
1813
+ throw Error('Invalid operation');
1814
+ await response(res, async () => createQuery(payload, req, true).random({ weight }, { master: payload.isMaster }));
1815
+ });
1770
1816
  router.get('/classes/:name/nonrefs', queryType.middleware(), async (req, res) => {
1771
1817
  res.setHeader('Cache-Control', ['no-cache', 'no-store']);
1772
1818
  const { name } = req.params;
@@ -1776,6 +1822,11 @@ var classesRoute = (router, proto) => {
1776
1822
  const payload = proto.connect(req);
1777
1823
  await response(res, async () => createQuery(payload, req, true).nonrefs({ master: payload.isMaster }));
1778
1824
  });
1825
+ router.get('/relation/nonrefs', queryType.middleware(), async (req, res) => {
1826
+ res.setHeader('Cache-Control', ['no-cache', 'no-store']);
1827
+ const payload = proto.connect(req);
1828
+ await response(res, async () => createQuery(payload, req, true).nonrefs({ master: payload.isMaster }));
1829
+ });
1779
1830
  router.get('/classes/:name/:id', async (req, res) => {
1780
1831
  res.setHeader('Cache-Control', ['no-cache', 'no-store']);
1781
1832
  const { name, id } = req.params;
@@ -1816,6 +1867,13 @@ var classesRoute = (router, proto) => {
1816
1867
  const payload = proto.connect(req);
1817
1868
  await response(res, () => createQuery(payload, req, false).deleteMany({ master: payload.isMaster }));
1818
1869
  });
1870
+ router.delete('/relation', serverJs.Server.text({ type: '*/*' }), async (req, res) => {
1871
+ res.setHeader('Cache-Control', ['no-cache', 'no-store']);
1872
+ if (!_.isEmpty(req.body))
1873
+ return res.sendStatus(400);
1874
+ const payload = proto.connect(req);
1875
+ await response(res, () => createQuery(payload, req, false).deleteMany({ master: payload.isMaster }));
1876
+ });
1819
1877
  router.delete('/classes/:name/:id', serverJs.Server.text({ type: '*/*' }), async (req, res) => {
1820
1878
  res.setHeader('Cache-Control', ['no-cache', 'no-store']);
1821
1879
  if (!_.isEmpty(req.body))