proto.io 0.0.165 → 0.0.167

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 (31) 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 +1 -1
  5. package/dist/adapters/storage/progres.mjs +1 -1
  6. package/dist/client.d.ts +3 -3
  7. package/dist/client.js +1 -1
  8. package/dist/client.mjs +2 -2
  9. package/dist/index.d.ts +3 -3
  10. package/dist/index.js +62 -33
  11. package/dist/index.js.map +1 -1
  12. package/dist/index.mjs +65 -36
  13. package/dist/index.mjs.map +1 -1
  14. package/dist/internals/{index-bCACA0cS.d.ts → index-BQggoDNX.d.ts} +2 -2
  15. package/dist/internals/index-BQggoDNX.d.ts.map +1 -0
  16. package/dist/internals/{index-Dz3jvqxZ.js → index-CyzpkgJB.js} +8 -21
  17. package/dist/internals/index-CyzpkgJB.js.map +1 -0
  18. package/dist/internals/{index-BibByOcU.mjs → index-Dyfia5Om.mjs} +9 -22
  19. package/dist/internals/index-Dyfia5Om.mjs.map +1 -0
  20. package/dist/internals/{index-DaDfXlay.d.ts → index-rkqvel7o.d.ts} +2 -2
  21. package/dist/internals/index-rkqvel7o.d.ts.map +1 -0
  22. package/dist/internals/{index-RPh4TX0T.d.ts → index-y8EePsDY.d.ts} +8 -5
  23. package/dist/internals/index-y8EePsDY.d.ts.map +1 -0
  24. package/dist/internals/{random-B1P0EZO5.mjs → random-DrURPPxr.mjs} +2 -2
  25. package/dist/internals/{random-B1P0EZO5.mjs.map → random-DrURPPxr.mjs.map} +1 -1
  26. package/package.json +3 -3
  27. package/dist/internals/index-BibByOcU.mjs.map +0 -1
  28. package/dist/internals/index-DaDfXlay.d.ts.map +0 -1
  29. package/dist/internals/index-Dz3jvqxZ.js.map +0 -1
  30. package/dist/internals/index-RPh4TX0T.d.ts.map +0 -1
  31. package/dist/internals/index-bCACA0cS.d.ts.map +0 -1
package/dist/index.mjs CHANGED
@@ -1,10 +1,10 @@
1
1
  import _ from 'lodash';
2
2
  import { Server } from '@o2ter/server-js';
3
- import { Q as QueryValidator, r as resolveColumn, g as generateId, a as resolveDataType } from './internals/random-B1P0EZO5.mjs';
3
+ import { Q as QueryValidator, r as resolveColumn, a as resolveDataType, g as generateId } from './internals/random-DrURPPxr.mjs';
4
4
  import { P as PVK } from './internals/private-BUpLAMZi.mjs';
5
- import { asyncStream, asyncIterableToArray, isBinaryData, base64ToBuffer } from '@o2ter/utils-js';
6
- import { T as TQuery, M as MASTER_USER_HEADER_NAME, a as MASTER_PASS_HEADER_NAME, A as AUTH_COOKIE_KEY, b as TUser, P as ProtoType, s as serialize, d as deserialize, U as UPLOAD_TOKEN_HEADER_NAME } from './internals/index-BibByOcU.mjs';
7
- export { c as ProtoClient, e as classExtends, j as isFile, f as isObject, i as isQuery, h as isRole, g as isUser } from './internals/index-BibByOcU.mjs';
5
+ import { prototypes, asyncStream, asyncIterableToArray, isBinaryData, base64ToBuffer } from '@o2ter/utils-js';
6
+ import { T as TQuery, M as MASTER_USER_HEADER_NAME, a as MASTER_PASS_HEADER_NAME, A as AUTH_COOKIE_KEY, b as TUser, P as ProtoType, s as serialize, d as deserialize, U as UPLOAD_TOKEN_HEADER_NAME } from './internals/index-Dyfia5Om.mjs';
7
+ export { c as ProtoClient, e as classExtends, j as isFile, f as isObject, i as isQuery, h as isRole, g as isUser } from './internals/index-Dyfia5Om.mjs';
8
8
  import { i as isPointer, a as isRelation, d as decodeUpdateOp, T as TObject, b as isShape, c as defaultObjectKeyTypes, e as isPrimitive } from './internals/index-BYbMU-Ao.mjs';
9
9
  import jwt from 'jsonwebtoken';
10
10
  import { Blob } from 'node:buffer';
@@ -246,14 +246,7 @@ const dispatcher = (proto, options, disableSecurity) => {
246
246
  const proxy = (x) => {
247
247
  const self = x;
248
248
  const proxy = _.create(self);
249
- const _prototypes = (x) => {
250
- const prototype = Object.getPrototypeOf(x);
251
- if (_.isNil(prototype) || prototype === Object.prototype)
252
- return [];
253
- return [prototype, ..._prototypes(prototype)];
254
- };
255
- const prototypes = _prototypes(proxy);
256
- for (const name of _.uniq(_.flatMap(prototypes, x => Object.getOwnPropertyNames(x)))) {
249
+ for (const name of _.uniq(_.flatMap(prototypes(proxy), x => Object.getOwnPropertyNames(x)))) {
257
250
  if (name === 'constructor')
258
251
  continue;
259
252
  if (_.isFunction(self[name])) {
@@ -855,6 +848,12 @@ class ProtoInternal {
855
848
  validateSchemaName(options.schema);
856
849
  const schema = mergeSchema(defaultSchema, options.fileStorage.schema, options.schema);
857
850
  validateSchema(schema);
851
+ if (!_.every(options.roleInheritKeys, k => {
852
+ const type = resolveDataType(schema, 'Role', k);
853
+ return type && isRelation(type) && _.includes(['User', 'Role'], type.target);
854
+ })) {
855
+ throw Error(`Invalid role keys`);
856
+ }
858
857
  this.options = {
859
858
  ...options,
860
859
  schema,
@@ -1293,29 +1292,7 @@ const signUser = async (proto, res, user, options) => {
1293
1292
  //
1294
1293
  const scheduleOp = {
1295
1294
  expireDocument: async (proto) => {
1296
- for (const className of proto.classes()) {
1297
- if (className === 'File') {
1298
- const found = proto.storage.find({
1299
- className: 'File',
1300
- filter: QuerySelector.decode({ _expired_at: { $lt: new Date() } }),
1301
- matches: {},
1302
- includes: ['_id', '_expired_at', 'token'],
1303
- objectIdSize: 0
1304
- });
1305
- for await (const item of found) {
1306
- const token = item.get('token');
1307
- if (!_.isEmpty(token))
1308
- await proto.fileStorage.destroy(proto, token);
1309
- }
1310
- }
1311
- await proto.storage.deleteMany({
1312
- className,
1313
- filter: QuerySelector.decode({ _expired_at: { $lt: new Date() } }),
1314
- includes: ['_id', '_expired_at'],
1315
- matches: {},
1316
- objectIdSize: 0
1317
- });
1318
- }
1295
+ await proto.gc();
1319
1296
  }
1320
1297
  };
1321
1298
  const schedule = (proto) => {
@@ -1377,6 +1354,7 @@ class ProtoService extends ProtoType {
1377
1354
  constructor(options) {
1378
1355
  super();
1379
1356
  this[PVK] = new ProtoInternal({
1357
+ roleInheritKeys: [],
1380
1358
  objectIdSize: 10,
1381
1359
  maxFetchLimit: 1000,
1382
1360
  maxUploadSize: 20 * 1024 * 1024,
@@ -1462,6 +1440,32 @@ class ProtoService extends ProtoType {
1462
1440
  const payload = _.create(this, { session });
1463
1441
  return _.assign(payload, _.isFunction(attrs) ? attrs(payload) : attrs);
1464
1442
  }
1443
+ async userRoles(user) {
1444
+ const roleInheritKeys = this[PVK].options.roleInheritKeys;
1445
+ const schema = this.schema;
1446
+ const userKeys = _.filter(roleInheritKeys, k => {
1447
+ const type = resolveDataType(schema, 'Role', k);
1448
+ return !!type && isRelation(type) && type.target === 'User';
1449
+ });
1450
+ const roleKeys = _.filter(roleInheritKeys, k => {
1451
+ const type = resolveDataType(schema, 'Role', k);
1452
+ return !!type && isRelation(type) && type.target === 'Role';
1453
+ });
1454
+ let queue = await this.Query('Role')
1455
+ .or(_.map(_.uniq(['users', ...userKeys]), k => q => q.isIntersect(k, [user])))
1456
+ .includes('name')
1457
+ .find({ master: true });
1458
+ let roles = queue;
1459
+ while (!_.isEmpty(queue)) {
1460
+ queue = await this.Query('Role')
1461
+ .or(_.map(_.uniq(['roles', ...roleKeys]), k => q => q.isIntersect(k, queue)))
1462
+ .notContainsIn('_id', _.compact(_.map(roles, x => x.objectId)))
1463
+ .includes('name')
1464
+ .find({ master: true });
1465
+ roles = _.uniqBy([...roles, ...queue], x => x.objectId);
1466
+ }
1467
+ return roles;
1468
+ }
1465
1469
  async becomeUser(req, user, options) {
1466
1470
  if (!user.objectId)
1467
1471
  throw Error('Invalid user object');
@@ -1566,6 +1570,31 @@ class ProtoService extends ProtoType {
1566
1570
  yield self.rebind(object);
1567
1571
  });
1568
1572
  }
1573
+ async gc(classNames) {
1574
+ for (const className of _.castArray(classNames ?? this.classes())) {
1575
+ if (className === 'File') {
1576
+ const found = this.storage.find({
1577
+ className: 'File',
1578
+ filter: QuerySelector.decode({ _expired_at: { $lt: new Date() } }),
1579
+ matches: {},
1580
+ includes: ['_id', '_expired_at', 'token'],
1581
+ objectIdSize: 0
1582
+ });
1583
+ for await (const item of found) {
1584
+ const token = item.get('token');
1585
+ if (!_.isEmpty(token))
1586
+ await this.fileStorage.destroy(this, token);
1587
+ }
1588
+ }
1589
+ await this.storage.deleteMany({
1590
+ className,
1591
+ filter: QuerySelector.decode({ _expired_at: { $lt: new Date() } }),
1592
+ includes: ['_id', '_expired_at'],
1593
+ matches: {},
1594
+ objectIdSize: 0
1595
+ });
1596
+ }
1597
+ }
1569
1598
  }
1570
1599
 
1571
1600
  //
@@ -1632,7 +1661,7 @@ const encodeError = (error) => {
1632
1661
  if (error instanceof String)
1633
1662
  return { message: error };
1634
1663
  if (error instanceof Error)
1635
- return { ...error, message: error.message };
1664
+ return { message: error.message };
1636
1665
  return error;
1637
1666
  };
1638
1667
  const response = async (res, callback) => {