proto.io 0.0.160 → 0.0.162
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/adapters/file/database.d.ts +2 -2
- package/dist/adapters/file/database.mjs +2 -2
- package/dist/adapters/file/filesystem.d.ts +2 -2
- package/dist/adapters/file/google-cloud-storage.d.ts +2 -2
- package/dist/adapters/storage/progres.d.ts +1 -1
- package/dist/adapters/storage/progres.mjs +3 -3
- package/dist/client.d.ts +3 -3
- package/dist/client.js +1 -1
- package/dist/client.mjs +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +134 -64
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +138 -68
- package/dist/index.mjs.map +1 -1
- package/dist/internals/{index-Bs06MNCK.js → index-4YC13MvT.js} +43 -24
- package/dist/internals/index-4YC13MvT.js.map +1 -0
- package/dist/internals/{index-BmRuvHVZ.mjs → index-ByfpVHca.mjs} +2 -2
- package/dist/internals/{index-BmRuvHVZ.mjs.map → index-ByfpVHca.mjs.map} +1 -1
- package/dist/internals/{index-CXPH5Pup.d.ts → index-C1NwI5ZD.d.ts} +5 -7
- package/dist/internals/index-C1NwI5ZD.d.ts.map +1 -0
- package/dist/internals/{index-B01TqoO1.mjs → index-CupbSHHH.mjs} +44 -25
- package/dist/internals/index-CupbSHHH.mjs.map +1 -0
- package/dist/internals/{index-sFLwlp-C.d.ts → index-DlvbXwIt.d.ts} +3 -3
- package/dist/internals/index-DlvbXwIt.d.ts.map +1 -0
- package/dist/internals/{index-BraAbRER.d.ts → index-LYC1mup1.d.ts} +2 -2
- package/dist/internals/index-LYC1mup1.d.ts.map +1 -0
- package/dist/internals/{index-tU-lsQqj.mjs → index-S5Bq-KsU.mjs} +2 -2
- package/dist/internals/{index-tU-lsQqj.mjs.map → index-S5Bq-KsU.mjs.map} +1 -1
- package/dist/internals/{random-DifCxbl6.mjs → random-w8WDYQEe.mjs} +4 -4
- package/dist/internals/{random-DifCxbl6.mjs.map → random-w8WDYQEe.mjs.map} +1 -1
- package/package.json +1 -1
- package/dist/internals/index-B01TqoO1.mjs.map +0 -1
- package/dist/internals/index-BraAbRER.d.ts.map +0 -1
- package/dist/internals/index-Bs06MNCK.js.map +0 -1
- package/dist/internals/index-CXPH5Pup.d.ts.map +0 -1
- package/dist/internals/index-sFLwlp-C.d.ts.map +0 -1
package/dist/index.mjs
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
import _ from 'lodash';
|
|
2
2
|
import { Server } from '@o2ter/server-js';
|
|
3
|
-
import { Q as QueryValidator, g as generateId,
|
|
3
|
+
import { Q as QueryValidator, r as resolveColumn, g as generateId, a as resolveDataType } from './internals/random-w8WDYQEe.mjs';
|
|
4
4
|
import { P as PVK } from './internals/private-BUpLAMZi.mjs';
|
|
5
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-
|
|
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-
|
|
8
|
-
import {
|
|
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-CupbSHHH.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-CupbSHHH.mjs';
|
|
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-ByfpVHca.mjs';
|
|
9
9
|
import jwt from 'jsonwebtoken';
|
|
10
10
|
import { Blob } from 'node:buffer';
|
|
11
11
|
import { Readable } from 'node:stream';
|
|
12
12
|
import { scrypt } from 'node:crypto';
|
|
13
13
|
import { promisify } from 'util';
|
|
14
14
|
import { randomBytes, randomUUID } from '@o2ter/crypto-js';
|
|
15
|
-
import { Q as QuerySelector } from './internals/index-
|
|
15
|
+
import { Q as QuerySelector } from './internals/index-S5Bq-KsU.mjs';
|
|
16
16
|
import queryType from 'query-types';
|
|
17
17
|
import busboy from 'busboy';
|
|
18
18
|
export { Decimal } from 'decimal.js';
|
|
@@ -316,19 +316,19 @@ const _serviceOf = (options) => options?.session instanceof ProtoService ? optio
|
|
|
316
316
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
317
317
|
// THE SOFTWARE.
|
|
318
318
|
//
|
|
319
|
-
class
|
|
319
|
+
class _ProtoQuery extends TQuery {
|
|
320
320
|
_proto;
|
|
321
321
|
_opts;
|
|
322
|
-
constructor(
|
|
323
|
-
super(
|
|
322
|
+
constructor(proto, opts) {
|
|
323
|
+
super();
|
|
324
324
|
this._proto = proto;
|
|
325
325
|
this._opts = opts;
|
|
326
326
|
}
|
|
327
327
|
get _queryOptions() {
|
|
328
328
|
return {
|
|
329
|
+
...this[PVK].options,
|
|
329
330
|
className: this.className,
|
|
330
331
|
relatedBy: this._opts.relatedBy,
|
|
331
|
-
...this[PVK].options,
|
|
332
332
|
};
|
|
333
333
|
}
|
|
334
334
|
_dispatcher(options) {
|
|
@@ -344,11 +344,6 @@ class ProtoQuery extends TQuery {
|
|
|
344
344
|
count(options) {
|
|
345
345
|
return this._dispatcher(options).count(this._queryOptions);
|
|
346
346
|
}
|
|
347
|
-
clone(options) {
|
|
348
|
-
const clone = new ProtoQuery(this.className, this._proto, this._opts);
|
|
349
|
-
clone[PVK].options = options ?? { ...this[PVK].options };
|
|
350
|
-
return clone;
|
|
351
|
-
}
|
|
352
347
|
_objectMethods(object) {
|
|
353
348
|
return this._proto.rebind(object);
|
|
354
349
|
}
|
|
@@ -538,6 +533,38 @@ class ProtoQuery extends TQuery {
|
|
|
538
533
|
return this._dispatcher(options).deleteMany(this._queryOptions);
|
|
539
534
|
}
|
|
540
535
|
}
|
|
536
|
+
class ProtoQuery extends _ProtoQuery {
|
|
537
|
+
_className;
|
|
538
|
+
constructor(className, proto, opts) {
|
|
539
|
+
super(proto, opts);
|
|
540
|
+
this._className = className;
|
|
541
|
+
}
|
|
542
|
+
get className() {
|
|
543
|
+
return this._className;
|
|
544
|
+
}
|
|
545
|
+
clone(options) {
|
|
546
|
+
const clone = new ProtoQuery(this.className, this._proto, this._opts);
|
|
547
|
+
clone[PVK].options = options ?? { ...this[PVK].options };
|
|
548
|
+
return clone;
|
|
549
|
+
}
|
|
550
|
+
}
|
|
551
|
+
class ProtoRelationQuery extends _ProtoQuery {
|
|
552
|
+
constructor(proto, opts) {
|
|
553
|
+
super(proto, opts);
|
|
554
|
+
}
|
|
555
|
+
get className() {
|
|
556
|
+
const { className, key } = this._opts.relatedBy;
|
|
557
|
+
const { dataType } = resolveColumn(this._proto.schema, className, key);
|
|
558
|
+
if (!isPointer(dataType) && !isRelation(dataType))
|
|
559
|
+
throw Error(`Invalid relation key: ${key}`);
|
|
560
|
+
return dataType.target;
|
|
561
|
+
}
|
|
562
|
+
clone(options) {
|
|
563
|
+
const clone = new ProtoRelationQuery(this._proto, this._opts);
|
|
564
|
+
clone[PVK].options = options ?? { ...this[PVK].options };
|
|
565
|
+
return clone;
|
|
566
|
+
}
|
|
567
|
+
}
|
|
541
568
|
|
|
542
569
|
//
|
|
543
570
|
// defaults.ts
|
|
@@ -1168,13 +1195,24 @@ const sessionId = (proto, request) => {
|
|
|
1168
1195
|
const session = _session(proto, request);
|
|
1169
1196
|
return sessionMap.get(request)?.sessionId ?? session?.sessionId;
|
|
1170
1197
|
};
|
|
1171
|
-
const
|
|
1198
|
+
const userCacheMap = new WeakMap;
|
|
1172
1199
|
const fetchSessionInfo = async (proto, userId) => {
|
|
1173
|
-
|
|
1174
|
-
|
|
1200
|
+
if (!userId)
|
|
1201
|
+
return {};
|
|
1202
|
+
if (!userCacheMap.has(proto[PVK]))
|
|
1203
|
+
userCacheMap.set(proto[PVK], {});
|
|
1204
|
+
const cache = userCacheMap.get(proto[PVK]);
|
|
1205
|
+
if (_.isNil(cache[userId]))
|
|
1206
|
+
cache[userId] = (async () => {
|
|
1207
|
+
const user = _.isString(userId) ? await proto.Query('User').get(userId, { master: true }) : undefined;
|
|
1208
|
+
const _roles = user instanceof TUser ? _.filter(await proto.userRoles(user), x => !_.isEmpty(x.name)) : [];
|
|
1209
|
+
cache[userId] = undefined;
|
|
1210
|
+
return { user, _roles };
|
|
1211
|
+
})();
|
|
1212
|
+
const { user, _roles } = await cache[userId];
|
|
1175
1213
|
return {
|
|
1176
|
-
|
|
1177
|
-
|
|
1214
|
+
user: user?.clone(),
|
|
1215
|
+
_roles: _.map(_roles, x => x.clone()),
|
|
1178
1216
|
};
|
|
1179
1217
|
};
|
|
1180
1218
|
const sessionWithToken = async (proto, token) => {
|
|
@@ -1186,6 +1224,7 @@ const sessionWithToken = async (proto, token) => {
|
|
|
1186
1224
|
loginedAt: info?.user ? session?.loginedAt : undefined,
|
|
1187
1225
|
};
|
|
1188
1226
|
};
|
|
1227
|
+
const sessionInfoMap = new WeakMap();
|
|
1189
1228
|
const session = async (proto, request) => {
|
|
1190
1229
|
const session = _session(proto, request);
|
|
1191
1230
|
const cached = sessionInfoMap.get(request);
|
|
@@ -1369,11 +1408,11 @@ class ProtoService extends ProtoType {
|
|
|
1369
1408
|
Query(className) {
|
|
1370
1409
|
return new ProtoQuery(className, this, {});
|
|
1371
1410
|
}
|
|
1372
|
-
Relation(
|
|
1411
|
+
Relation(object, key) {
|
|
1373
1412
|
const objectId = object.objectId;
|
|
1374
1413
|
if (!objectId)
|
|
1375
1414
|
throw Error('Invalid object');
|
|
1376
|
-
return new
|
|
1415
|
+
return new ProtoRelationQuery(this, {
|
|
1377
1416
|
relatedBy: {
|
|
1378
1417
|
className: object.className,
|
|
1379
1418
|
objectId,
|
|
@@ -1658,64 +1697,70 @@ const verifyRelatedBy = (relatedBy) => {
|
|
|
1658
1697
|
throw Error('Invalid option');
|
|
1659
1698
|
};
|
|
1660
1699
|
var classesRoute = (router, proto) => {
|
|
1700
|
+
const defaultHandler = async (req) => {
|
|
1701
|
+
const { name } = req.params;
|
|
1702
|
+
const { operation, context, silent, random, attributes, update, setOnInsert, relatedBy, ...options } = deserialize(req.body);
|
|
1703
|
+
verifyRelatedBy(relatedBy);
|
|
1704
|
+
const payload = proto.connect(req);
|
|
1705
|
+
const query = relatedBy ? payload.Relation(payload.Object(relatedBy.className, relatedBy.objectId), relatedBy.key) : payload.Query(name);
|
|
1706
|
+
query[PVK].options = options;
|
|
1707
|
+
const opts = { master: payload.isMaster, context, silent };
|
|
1708
|
+
switch (operation) {
|
|
1709
|
+
case 'explain':
|
|
1710
|
+
if (!payload.isMaster)
|
|
1711
|
+
throw Error('No permission');
|
|
1712
|
+
return query.explain(opts);
|
|
1713
|
+
case 'count': return query.count(opts);
|
|
1714
|
+
case 'find':
|
|
1715
|
+
{
|
|
1716
|
+
const maxFetchLimit = payload[PVK].options.maxFetchLimit;
|
|
1717
|
+
query[PVK].options.limit = query[PVK].options.limit ?? maxFetchLimit;
|
|
1718
|
+
if (query[PVK].options.limit > maxFetchLimit)
|
|
1719
|
+
throw Error('Query over limit');
|
|
1720
|
+
return await query.find(opts);
|
|
1721
|
+
}
|
|
1722
|
+
case 'random':
|
|
1723
|
+
{
|
|
1724
|
+
const maxFetchLimit = payload[PVK].options.maxFetchLimit;
|
|
1725
|
+
query[PVK].options.limit = query[PVK].options.limit ?? maxFetchLimit;
|
|
1726
|
+
if (query[PVK].options.limit > maxFetchLimit)
|
|
1727
|
+
throw Error('Query over limit');
|
|
1728
|
+
return await query.random(random, opts);
|
|
1729
|
+
}
|
|
1730
|
+
case 'nonrefs':
|
|
1731
|
+
{
|
|
1732
|
+
const maxFetchLimit = payload[PVK].options.maxFetchLimit;
|
|
1733
|
+
query[PVK].options.limit = query[PVK].options.limit ?? maxFetchLimit;
|
|
1734
|
+
if (query[PVK].options.limit > maxFetchLimit)
|
|
1735
|
+
throw Error('Query over limit');
|
|
1736
|
+
return await query.nonrefs(opts);
|
|
1737
|
+
}
|
|
1738
|
+
case 'insert': return query.insert(attributes, opts);
|
|
1739
|
+
case 'insertMany': return query.insertMany(attributes, opts);
|
|
1740
|
+
case 'updateOne': return query.updateOne(update, opts);
|
|
1741
|
+
case 'upsertOne': return query.upsertOne(update, setOnInsert, opts);
|
|
1742
|
+
case 'deleteOne': return query.deleteOne(opts);
|
|
1743
|
+
case 'deleteMany': return query.deleteMany(opts);
|
|
1744
|
+
default: throw Error('Invalid operation');
|
|
1745
|
+
}
|
|
1746
|
+
};
|
|
1661
1747
|
router.post('/classes/:name', Server.text({ type: '*/*' }), async (req, res) => {
|
|
1662
1748
|
res.setHeader('Cache-Control', ['no-cache', 'no-store']);
|
|
1663
1749
|
const { name } = req.params;
|
|
1664
1750
|
const classes = proto.classes();
|
|
1665
1751
|
if (!_.includes(classes, name))
|
|
1666
1752
|
return res.sendStatus(404);
|
|
1667
|
-
await response(res,
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
query[PVK].options = options;
|
|
1673
|
-
const opts = { master: payload.isMaster, context, silent };
|
|
1674
|
-
switch (operation) {
|
|
1675
|
-
case 'explain':
|
|
1676
|
-
if (!payload.isMaster)
|
|
1677
|
-
throw Error('No permission');
|
|
1678
|
-
return query.explain(opts);
|
|
1679
|
-
case 'count': return query.count(opts);
|
|
1680
|
-
case 'find':
|
|
1681
|
-
{
|
|
1682
|
-
const maxFetchLimit = payload[PVK].options.maxFetchLimit;
|
|
1683
|
-
query[PVK].options.limit = query[PVK].options.limit ?? maxFetchLimit;
|
|
1684
|
-
if (query[PVK].options.limit > maxFetchLimit)
|
|
1685
|
-
throw Error('Query over limit');
|
|
1686
|
-
return await query.find(opts);
|
|
1687
|
-
}
|
|
1688
|
-
case 'random':
|
|
1689
|
-
{
|
|
1690
|
-
const maxFetchLimit = payload[PVK].options.maxFetchLimit;
|
|
1691
|
-
query[PVK].options.limit = query[PVK].options.limit ?? maxFetchLimit;
|
|
1692
|
-
if (query[PVK].options.limit > maxFetchLimit)
|
|
1693
|
-
throw Error('Query over limit');
|
|
1694
|
-
return await query.random(random, opts);
|
|
1695
|
-
}
|
|
1696
|
-
case 'nonrefs':
|
|
1697
|
-
{
|
|
1698
|
-
const maxFetchLimit = payload[PVK].options.maxFetchLimit;
|
|
1699
|
-
query[PVK].options.limit = query[PVK].options.limit ?? maxFetchLimit;
|
|
1700
|
-
if (query[PVK].options.limit > maxFetchLimit)
|
|
1701
|
-
throw Error('Query over limit');
|
|
1702
|
-
return await query.nonrefs(opts);
|
|
1703
|
-
}
|
|
1704
|
-
case 'insert': return query.insert(attributes, opts);
|
|
1705
|
-
case 'insertMany': return query.insertMany(attributes, opts);
|
|
1706
|
-
case 'updateOne': return query.updateOne(update, opts);
|
|
1707
|
-
case 'upsertOne': return query.upsertOne(update, setOnInsert, opts);
|
|
1708
|
-
case 'deleteOne': return query.deleteOne(opts);
|
|
1709
|
-
case 'deleteMany': return query.deleteMany(opts);
|
|
1710
|
-
default: throw Error('Invalid operation');
|
|
1711
|
-
}
|
|
1712
|
-
});
|
|
1753
|
+
await response(res, () => defaultHandler(req));
|
|
1754
|
+
});
|
|
1755
|
+
router.post('/relation', Server.text({ type: '*/*' }), async (req, res) => {
|
|
1756
|
+
res.setHeader('Cache-Control', ['no-cache', 'no-store']);
|
|
1757
|
+
await response(res, () => defaultHandler(req));
|
|
1713
1758
|
});
|
|
1714
1759
|
const createQuery = (payload, req, checkLimit) => {
|
|
1715
1760
|
const { name } = req.params;
|
|
1716
1761
|
const { filter, sort, includes, skip, limit, relatedBy, } = req.query;
|
|
1717
1762
|
verifyRelatedBy(relatedBy);
|
|
1718
|
-
const query = relatedBy ? payload.Relation(
|
|
1763
|
+
const query = relatedBy ? payload.Relation(payload.Object(relatedBy.className, relatedBy.objectId), relatedBy.key) : payload.Query(name);
|
|
1719
1764
|
query[PVK].options.filter = !_.isEmpty(filter) && _.isString(filter) ? _.castArray(deserialize(filter)) : [];
|
|
1720
1765
|
query[PVK].options.sort = _.isPlainObject(sort) && _.every(_.values(sort), _.isNumber) ? sort : undefined;
|
|
1721
1766
|
query[PVK].options.includes = _.isArray(includes) && _.every(includes, _.isString) ? includes : undefined;
|
|
@@ -1740,6 +1785,11 @@ var classesRoute = (router, proto) => {
|
|
|
1740
1785
|
const payload = proto.connect(req);
|
|
1741
1786
|
await response(res, async () => createQuery(payload, req, true).find({ master: payload.isMaster }));
|
|
1742
1787
|
});
|
|
1788
|
+
router.get('/relation', queryType.middleware(), async (req, res) => {
|
|
1789
|
+
res.setHeader('Cache-Control', ['no-cache', 'no-store']);
|
|
1790
|
+
const payload = proto.connect(req);
|
|
1791
|
+
await response(res, async () => createQuery(payload, req, true).find({ master: payload.isMaster }));
|
|
1792
|
+
});
|
|
1743
1793
|
router.get('/classes/:name/random', queryType.middleware(), async (req, res) => {
|
|
1744
1794
|
res.setHeader('Cache-Control', ['no-cache', 'no-store']);
|
|
1745
1795
|
const { name } = req.params;
|
|
@@ -1752,6 +1802,14 @@ var classesRoute = (router, proto) => {
|
|
|
1752
1802
|
throw Error('Invalid operation');
|
|
1753
1803
|
await response(res, async () => createQuery(payload, req, true).random({ weight }, { master: payload.isMaster }));
|
|
1754
1804
|
});
|
|
1805
|
+
router.get('/relation/random', queryType.middleware(), async (req, res) => {
|
|
1806
|
+
res.setHeader('Cache-Control', ['no-cache', 'no-store']);
|
|
1807
|
+
const payload = proto.connect(req);
|
|
1808
|
+
const { weight } = req.query;
|
|
1809
|
+
if (_.isEmpty(weight) || !_.isString(weight))
|
|
1810
|
+
throw Error('Invalid operation');
|
|
1811
|
+
await response(res, async () => createQuery(payload, req, true).random({ weight }, { master: payload.isMaster }));
|
|
1812
|
+
});
|
|
1755
1813
|
router.get('/classes/:name/nonrefs', queryType.middleware(), async (req, res) => {
|
|
1756
1814
|
res.setHeader('Cache-Control', ['no-cache', 'no-store']);
|
|
1757
1815
|
const { name } = req.params;
|
|
@@ -1761,6 +1819,11 @@ var classesRoute = (router, proto) => {
|
|
|
1761
1819
|
const payload = proto.connect(req);
|
|
1762
1820
|
await response(res, async () => createQuery(payload, req, true).nonrefs({ master: payload.isMaster }));
|
|
1763
1821
|
});
|
|
1822
|
+
router.get('/relation/nonrefs', queryType.middleware(), async (req, res) => {
|
|
1823
|
+
res.setHeader('Cache-Control', ['no-cache', 'no-store']);
|
|
1824
|
+
const payload = proto.connect(req);
|
|
1825
|
+
await response(res, async () => createQuery(payload, req, true).nonrefs({ master: payload.isMaster }));
|
|
1826
|
+
});
|
|
1764
1827
|
router.get('/classes/:name/:id', async (req, res) => {
|
|
1765
1828
|
res.setHeader('Cache-Control', ['no-cache', 'no-store']);
|
|
1766
1829
|
const { name, id } = req.params;
|
|
@@ -1801,6 +1864,13 @@ var classesRoute = (router, proto) => {
|
|
|
1801
1864
|
const payload = proto.connect(req);
|
|
1802
1865
|
await response(res, () => createQuery(payload, req, false).deleteMany({ master: payload.isMaster }));
|
|
1803
1866
|
});
|
|
1867
|
+
router.delete('/relation', Server.text({ type: '*/*' }), async (req, res) => {
|
|
1868
|
+
res.setHeader('Cache-Control', ['no-cache', 'no-store']);
|
|
1869
|
+
if (!_.isEmpty(req.body))
|
|
1870
|
+
return res.sendStatus(400);
|
|
1871
|
+
const payload = proto.connect(req);
|
|
1872
|
+
await response(res, () => createQuery(payload, req, false).deleteMany({ master: payload.isMaster }));
|
|
1873
|
+
});
|
|
1804
1874
|
router.delete('/classes/:name/:id', Server.text({ type: '*/*' }), async (req, res) => {
|
|
1805
1875
|
res.setHeader('Cache-Control', ['no-cache', 'no-store']);
|
|
1806
1876
|
if (!_.isEmpty(req.body))
|