proto.io 0.0.171 → 0.0.173

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 (32) hide show
  1. package/dist/adapters/file/database.d.ts +2 -2
  2. package/dist/adapters/file/filesystem.d.ts +2 -2
  3. package/dist/adapters/file/google-cloud-storage.d.ts +2 -2
  4. package/dist/adapters/storage/progres.d.ts +8 -1
  5. package/dist/adapters/storage/progres.js +66 -9
  6. package/dist/adapters/storage/progres.js.map +1 -1
  7. package/dist/adapters/storage/progres.mjs +66 -9
  8. package/dist/adapters/storage/progres.mjs.map +1 -1
  9. package/dist/client.d.ts +3 -3
  10. package/dist/client.js +1 -1
  11. package/dist/client.mjs +2 -2
  12. package/dist/index.d.ts +3 -3
  13. package/dist/index.js +137 -25
  14. package/dist/index.js.map +1 -1
  15. package/dist/index.mjs +138 -26
  16. package/dist/index.mjs.map +1 -1
  17. package/dist/internals/{index-B5u7VXjz.d.ts → index-BJnQhKf3.d.ts} +2 -2
  18. package/dist/internals/index-BJnQhKf3.d.ts.map +1 -0
  19. package/dist/internals/{index-D0hHgn2P.mjs → index-BZNPlw1L.mjs} +20 -1
  20. package/dist/internals/index-BZNPlw1L.mjs.map +1 -0
  21. package/dist/internals/{index-BJP46VGq.js → index-CIecB6mS.js} +20 -1
  22. package/dist/internals/index-CIecB6mS.js.map +1 -0
  23. package/dist/internals/{index-D_GYwO8X.d.ts → index-Cpv1DoEI.d.ts} +2 -2
  24. package/dist/internals/index-Cpv1DoEI.d.ts.map +1 -0
  25. package/dist/internals/{index-BB2vDnq0.d.ts → index-lX-M76Tn.d.ts} +16 -3
  26. package/dist/internals/index-lX-M76Tn.d.ts.map +1 -0
  27. package/package.json +1 -1
  28. package/dist/internals/index-B5u7VXjz.d.ts.map +0 -1
  29. package/dist/internals/index-BB2vDnq0.d.ts.map +0 -1
  30. package/dist/internals/index-BJP46VGq.js.map +0 -1
  31. package/dist/internals/index-D0hHgn2P.mjs.map +0 -1
  32. package/dist/internals/index-D_GYwO8X.d.ts.map +0 -1
package/dist/client.d.ts CHANGED
@@ -1,7 +1,7 @@
1
- import { P as ProtoClient } from './internals/index-D_GYwO8X.js';
2
- export { c as classExtends, e as isFile, a as isObject, i as isQuery, d as isRole, b as isUser } from './internals/index-D_GYwO8X.js';
1
+ import { P as ProtoClient } from './internals/index-Cpv1DoEI.js';
2
+ export { c as classExtends, e as isFile, a as isObject, i as isQuery, d as isRole, b as isUser } from './internals/index-Cpv1DoEI.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-BB2vDnq0.js';
4
+ export { D as DeserializeOptions, S as SerializeOptions, d as TSerializable, e as deserialize, s as serialize } from './internals/index-lX-M76Tn.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-BJP46VGq.js');
5
+ var index = require('./internals/index-CIecB6mS.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,5 +1,5 @@
1
- import { c as ProtoClient } from './internals/index-D0hHgn2P.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-D0hHgn2P.mjs';
1
+ import { c as ProtoClient } from './internals/index-BZNPlw1L.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-BZNPlw1L.mjs';
3
3
  export { Decimal } from 'decimal.js';
4
4
  import './internals/index-BYbMU-Ao.mjs';
5
5
  import 'lodash';
package/dist/index.d.ts CHANGED
@@ -1,11 +1,11 @@
1
1
  import * as socket_io from 'socket.io';
2
2
  import { Router } from 'express';
3
3
  import { Server } from '@o2ter/server-js';
4
- import { T as TSchema, _ as _TValue, P as ProtoService, a as ProtoServiceOptions, b as ProtoServiceKeyOptions } from './internals/index-BB2vDnq0.js';
5
- export { D as DeserializeOptions, S as SerializeOptions, c as TFileStorage, d as TSerializable, e as deserialize, s as serialize } from './internals/index-BB2vDnq0.js';
4
+ import { T as TSchema, _ as _TValue, P as ProtoService, a as ProtoServiceOptions, b as ProtoServiceKeyOptions } from './internals/index-lX-M76Tn.js';
5
+ export { D as DeserializeOptions, S as SerializeOptions, c as TFileStorage, d as TSerializable, e as deserialize, s as serialize } from './internals/index-lX-M76Tn.js';
6
6
  import Decimal from 'decimal.js';
7
7
  export { Decimal } from 'decimal.js';
8
- 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-D_GYwO8X.js';
8
+ 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-Cpv1DoEI.js';
9
9
  import '@o2ter/utils-js';
10
10
  import 'jsonwebtoken';
11
11
  import 'lodash';
package/dist/index.js CHANGED
@@ -7,7 +7,7 @@ var serverJs = require('@o2ter/server-js');
7
7
  var random = require('./internals/random-Dytum6Nh.js');
8
8
  var _private = require('./internals/private-CSB1Ep4g.js');
9
9
  var utilsJs = require('@o2ter/utils-js');
10
- var index = require('./internals/index-BJP46VGq.js');
10
+ var index = require('./internals/index-CIecB6mS.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');
@@ -186,6 +186,13 @@ const dispatcher = (proto, options, disableSecurity) => {
186
186
  throw Error('No permission');
187
187
  return proto.storage.atomic((storage) => storage.updateOne(_validator.decodeQuery(normalize(query), 'update'), normalize(_validator.validateFields(query.className, update, 'update', random.QueryValidator.patterns.path))));
188
188
  },
189
+ async updateMany(query, update) {
190
+ random.QueryValidator.recursiveCheck(query, update);
191
+ const _validator = await validator();
192
+ if (!_validator.validateCLPs(query.className, 'update'))
193
+ throw Error('No permission');
194
+ return proto.storage.atomic((storage) => storage.updateMany(_validator.decodeQuery(normalize(query), 'update'), normalize(_validator.validateFields(query.className, update, 'update', random.QueryValidator.patterns.path))));
195
+ },
189
196
  async upsertOne(query, update, setOnInsert) {
190
197
  random.QueryValidator.recursiveCheck(query, update, setOnInsert);
191
198
  const _validator = await validator();
@@ -205,6 +212,25 @@ const dispatcher = (proto, options, disableSecurity) => {
205
212
  }
206
213
  }
207
214
  },
215
+ async upsertMany(query, update, setOnInsert) {
216
+ random.QueryValidator.recursiveCheck(query, update, setOnInsert);
217
+ const _validator = await validator();
218
+ if (!_validator.validateCLPs(query.className, 'create', 'update'))
219
+ throw Error('No permission');
220
+ const _query = _validator.decodeQuery(normalize(query), 'update');
221
+ const _update = normalize(_validator.validateFields(query.className, update, 'update', random.QueryValidator.patterns.path));
222
+ const _setOnInsert = normalize(_validator.validateFields(query.className, setOnInsert, 'create', random.QueryValidator.patterns.name));
223
+ while (true) {
224
+ try {
225
+ return await proto.storage.atomic((storage) => storage.upsertMany(_query, _update, _setOnInsert), { lockTable: query.className, retry: true });
226
+ }
227
+ catch (e) {
228
+ if (proto.storage.isDuplicateIdError(e))
229
+ continue;
230
+ throw e;
231
+ }
232
+ }
233
+ },
208
234
  async deleteOne(query) {
209
235
  random.QueryValidator.recursiveCheck(query);
210
236
  const _validator = await validator();
@@ -443,6 +469,33 @@ class _ProtoQuery extends index.TQuery {
443
469
  }
444
470
  return result;
445
471
  }
472
+ async updateMany(update, options) {
473
+ const context = options?.context ?? {};
474
+ const silent = _.castArray(options?.silent ?? []);
475
+ const beforeSave = _.includes(silent, 'beforeSave') ? null : this._proto[_private.PVK].triggers?.beforeSave?.[this.className];
476
+ const afterSave = _.includes(silent, 'afterSave') ? null : this._proto[_private.PVK].triggers?.afterSave?.[this.className];
477
+ if (_.isFunction(beforeSave) || _.isFunction(afterSave)) {
478
+ const objects = this._objectMethods(await utilsJs.asyncIterableToArray(this._dispatcher(options).find(this._queryOptions)));
479
+ if (_.isEmpty(objects))
480
+ return 0;
481
+ if (_.isFunction(beforeSave)) {
482
+ await Promise.all(_.map(objects, object => beforeSave(proxy(Object.setPrototypeOf({ object, context }, options?.session ?? this._proto)))));
483
+ }
484
+ if (!_.isFunction(afterSave)) {
485
+ return this._dispatcher(options).updateMany({
486
+ ...this._queryOptions,
487
+ filter: { _id: { $in: _.map(objects, x => x.objectId) } },
488
+ }, update);
489
+ }
490
+ const updated = await Promise.all(_.map(objects, x => this._dispatcher(options).updateOne({
491
+ ...this._queryOptions,
492
+ filter: { _id: { $eq: x.objectId } },
493
+ }, update)));
494
+ await Promise.all(_.map(updated, object => afterSave(proxy(Object.setPrototypeOf({ object, context }, options?.session ?? this._proto)))));
495
+ return updated.length;
496
+ }
497
+ return this._dispatcher(options).updateMany(this._queryOptions, update);
498
+ }
446
499
  async upsertOne(update, setOnInsert, options) {
447
500
  const context = options?.context ?? {};
448
501
  const silent = _.castArray(options?.silent ?? []);
@@ -481,6 +534,47 @@ class _ProtoQuery extends index.TQuery {
481
534
  }
482
535
  return result;
483
536
  }
537
+ async upsertMany(update, setOnInsert, options) {
538
+ const context = options?.context ?? {};
539
+ const silent = _.castArray(options?.silent ?? []);
540
+ const beforeSave = _.includes(silent, 'beforeSave') ? null : this._proto[_private.PVK].triggers?.beforeSave?.[this.className];
541
+ const afterSave = _.includes(silent, 'afterSave') ? null : this._proto[_private.PVK].triggers?.afterSave?.[this.className];
542
+ if (_.isFunction(beforeSave) || _.isFunction(afterSave)) {
543
+ const objects = this._objectMethods(await utilsJs.asyncIterableToArray(this._dispatcher(options).find(this._queryOptions)));
544
+ if (!_.isEmpty(objects) && _.isFunction(beforeSave)) {
545
+ await Promise.all(_.map(objects, object => beforeSave(proxy(Object.setPrototypeOf({ object, context }, options?.session ?? this._proto)))));
546
+ }
547
+ if (_.isEmpty(objects)) {
548
+ const result = await this._dispatcher(options).insert({
549
+ className: this.className,
550
+ includes: this[_private.PVK].options.includes,
551
+ matches: this[_private.PVK].options.matches,
552
+ }, setOnInsert);
553
+ if (!result)
554
+ throw Error('Unable to insert document');
555
+ if (_.isFunction(afterSave)) {
556
+ await afterSave(proxy(Object.setPrototypeOf({ object: result, context }, options?.session ?? this._proto)));
557
+ }
558
+ return { updated: 0, inserted: 1 };
559
+ }
560
+ if (!_.isFunction(afterSave)) {
561
+ return {
562
+ inserted: 0,
563
+ updated: await this._dispatcher(options).updateMany({
564
+ ...this._queryOptions,
565
+ filter: { _id: { $in: _.map(objects, x => x.objectId) } },
566
+ }, update),
567
+ };
568
+ }
569
+ const updated = await Promise.all(_.map(objects, x => this._dispatcher(options).updateOne({
570
+ ...this._queryOptions,
571
+ filter: { _id: { $eq: x.objectId } },
572
+ }, update)));
573
+ await Promise.all(_.map(updated, object => afterSave(proxy(Object.setPrototypeOf({ object, context }, options?.session ?? this._proto)))));
574
+ return { updated: updated.length, inserted: 0 };
575
+ }
576
+ return this._dispatcher(options).upsertMany(this._queryOptions, update, setOnInsert);
577
+ }
484
578
  async deleteOne(options) {
485
579
  const context = options?.context ?? {};
486
580
  const silent = _.castArray(options?.silent ?? []);
@@ -851,7 +945,7 @@ class ProtoInternal {
851
945
  validateSchemaName(options.schema);
852
946
  const schema = mergeSchema(defaultSchema, options.fileStorage.schema, options.schema);
853
947
  validateSchema(schema);
854
- if (!_.every(options.roleInheritKeys, k => {
948
+ if (!_.every(options.roleResolver?.inheritKeys, k => {
855
949
  const type = random.resolveDataType(schema, 'Role', k);
856
950
  return type && index$1.isRelation(type) && _.includes(['User', 'Role'], type.target);
857
951
  })) {
@@ -1357,7 +1451,7 @@ class ProtoService extends index.ProtoType {
1357
1451
  constructor(options) {
1358
1452
  super();
1359
1453
  this[_private.PVK] = new ProtoInternal({
1360
- roleInheritKeys: [],
1454
+ roleResolver: {},
1361
1455
  objectIdSize: 10,
1362
1456
  maxFetchLimit: 1000,
1363
1457
  maxUploadSize: 20 * 1024 * 1024,
@@ -1444,30 +1538,36 @@ class ProtoService extends index.ProtoType {
1444
1538
  return _.assign(payload, _.isFunction(attrs) ? attrs(payload) : attrs);
1445
1539
  }
1446
1540
  async userRoles(user) {
1447
- const roleInheritKeys = this[_private.PVK].options.roleInheritKeys;
1448
- const schema = this.schema;
1449
- const userKeys = _.filter(roleInheritKeys, k => {
1450
- const type = random.resolveDataType(schema, 'Role', k);
1451
- return !!type && index$1.isRelation(type) && type.target === 'User';
1452
- });
1453
- const roleKeys = _.filter(roleInheritKeys, k => {
1454
- const type = random.resolveDataType(schema, 'Role', k);
1455
- return !!type && index$1.isRelation(type) && type.target === 'Role';
1456
- });
1457
- let queue = await this.Query('Role')
1458
- .or(_.map(_.uniq(['users', ...userKeys]), k => q => q.isIntersect(k, [user])))
1459
- .includes('name')
1460
- .find({ master: true });
1461
- let roles = queue;
1462
- while (!_.isEmpty(queue)) {
1463
- queue = await this.Query('Role')
1464
- .or(_.map(_.uniq(['roles', ...roleKeys]), k => q => q.isIntersect(k, queue)))
1465
- .notContainsIn('_id', _.compact(_.map(roles, x => x.objectId)))
1541
+ const self = this;
1542
+ const { inheritKeys, resolver } = self[_private.PVK].options.roleResolver;
1543
+ const defaultResolver = async () => {
1544
+ const schema = self.schema;
1545
+ const userKeys = _.filter(inheritKeys, k => {
1546
+ const type = random.resolveDataType(schema, 'Role', k);
1547
+ return !!type && index$1.isRelation(type) && type.target === 'User';
1548
+ });
1549
+ const roleKeys = _.filter(inheritKeys, k => {
1550
+ const type = random.resolveDataType(schema, 'Role', k);
1551
+ return !!type && index$1.isRelation(type) && type.target === 'Role';
1552
+ });
1553
+ let queue = await self.Query('Role')
1554
+ .or(_.map(_.uniq(['users', ...userKeys]), k => q => q.isIntersect(k, [user])))
1466
1555
  .includes('name')
1467
1556
  .find({ master: true });
1468
- roles = _.uniqBy([...roles, ...queue], x => x.objectId);
1469
- }
1470
- return roles;
1557
+ let roles = queue;
1558
+ while (!_.isEmpty(queue)) {
1559
+ queue = await self.Query('Role')
1560
+ .or(_.map(_.uniq(['roles', ...roleKeys]), k => q => q.isIntersect(k, queue)))
1561
+ .notContainsIn('_id', _.compact(_.map(roles, x => x.objectId)))
1562
+ .includes('name')
1563
+ .find({ master: true });
1564
+ roles = _.uniqBy([...roles, ...queue], x => x.objectId);
1565
+ }
1566
+ return roles;
1567
+ };
1568
+ if (resolver)
1569
+ return resolver(user, defaultResolver);
1570
+ return defaultResolver();
1471
1571
  }
1472
1572
  async becomeUser(req, user, options) {
1473
1573
  if (!user.objectId)
@@ -1772,7 +1872,9 @@ var classesRoute = (router, proto) => {
1772
1872
  case 'insert': return query.insert(attributes, opts);
1773
1873
  case 'insertMany': return query.insertMany(attributes, opts);
1774
1874
  case 'updateOne': return query.updateOne(update, opts);
1875
+ case 'updateMany': return query.updateMany(update, opts);
1775
1876
  case 'upsertOne': return query.upsertOne(update, setOnInsert, opts);
1877
+ case 'upsertMany': return query.upsertMany(update, setOnInsert, opts);
1776
1878
  case 'deleteOne': return query.deleteOne(opts);
1777
1879
  case 'deleteMany': return query.deleteMany(opts);
1778
1880
  default: throw Error('Invalid operation');
@@ -1876,6 +1978,16 @@ var classesRoute = (router, proto) => {
1876
1978
  const payload = proto.connect(req);
1877
1979
  await response(res, async () => payload.refs(payload.Object(name, id), { master: payload.isMaster }));
1878
1980
  });
1981
+ router.patch('/classes/:name', serverJs.Server.text({ type: '*/*' }), async (req, res) => {
1982
+ res.setHeader('Cache-Control', ['no-cache', 'no-store']);
1983
+ const { name } = req.params;
1984
+ const classes = proto.classes();
1985
+ if (!_.includes(classes, name))
1986
+ return void res.sendStatus(404);
1987
+ const payload = proto.connect(req);
1988
+ const update = _.mapValues(index.deserialize(req.body), v => ({ $set: v }));
1989
+ await response(res, () => createQuery(payload, req, false).updateMany(update, { master: payload.isMaster }));
1990
+ });
1879
1991
  router.patch('/classes/:name/:id', serverJs.Server.text({ type: '*/*' }), async (req, res) => {
1880
1992
  res.setHeader('Cache-Control', ['no-cache', 'no-store']);
1881
1993
  const { name, id } = req.params;