proto.io 0.0.227 → 0.0.229
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/README.md +1017 -0
- package/dist/adapters/file/aliyun-oss.d.mts +26 -0
- package/dist/adapters/file/aliyun-oss.d.mts.map +1 -0
- package/dist/adapters/file/aliyun-oss.d.ts +3 -3
- package/dist/adapters/file/database.d.mts +23 -0
- package/dist/adapters/file/database.d.mts.map +1 -0
- package/dist/adapters/file/database.d.ts +2 -2
- package/dist/adapters/file/database.js +1 -1
- package/dist/adapters/file/database.mjs +1 -1
- package/dist/adapters/file/filesystem.d.mts +25 -0
- package/dist/adapters/file/filesystem.d.mts.map +1 -0
- package/dist/adapters/file/filesystem.d.ts +3 -3
- package/dist/adapters/file/google-cloud-storage.d.mts +29 -0
- package/dist/adapters/file/google-cloud-storage.d.mts.map +1 -0
- package/dist/adapters/file/google-cloud-storage.d.ts +3 -3
- package/dist/adapters/storage/postgres.d.mts +299 -0
- package/dist/adapters/storage/postgres.d.mts.map +1 -0
- package/dist/adapters/storage/postgres.d.ts +5 -1
- package/dist/adapters/storage/postgres.d.ts.map +1 -1
- package/dist/adapters/storage/postgres.js +182 -74
- package/dist/adapters/storage/postgres.js.map +1 -1
- package/dist/adapters/storage/postgres.mjs +182 -74
- package/dist/adapters/storage/postgres.mjs.map +1 -1
- package/dist/client.d.mts +16 -0
- package/dist/client.d.mts.map +1 -0
- package/dist/client.d.ts +3 -3
- package/dist/client.js +1 -1
- package/dist/client.mjs +2 -2
- package/dist/index.d.mts +151 -0
- package/dist/index.d.mts.map +1 -0
- package/dist/index.d.ts +3 -3
- package/dist/index.js +68 -25
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +69 -26
- package/dist/index.mjs.map +1 -1
- package/dist/internals/{base-DSo02iAX.d.ts → base-Bhrj5Pq1.d.ts} +2 -2
- package/dist/internals/{base-DSo02iAX.d.ts.map → base-Bhrj5Pq1.d.ts.map} +1 -1
- package/dist/internals/base-CiZHXD0o.d.mts +27 -0
- package/dist/internals/base-CiZHXD0o.d.mts.map +1 -0
- package/dist/internals/chunk-Cp2QN7ug.d.mts +17 -0
- package/dist/internals/chunk-Cp2QN7ug.d.mts.map +1 -0
- package/dist/internals/{chunk-BhwfdCdq.d.ts → chunk-o7lWIP-f.d.ts} +3 -3
- package/dist/internals/{chunk-BhwfdCdq.d.ts.map → chunk-o7lWIP-f.d.ts.map} +1 -1
- package/dist/internals/{index-vOFh8pVc.js → index-B0TO6h9r.js} +8 -1
- package/dist/internals/index-B0TO6h9r.js.map +1 -0
- package/dist/internals/{index-Cj45GkKv.d.ts → index-B710pfTH.d.ts} +2 -2
- package/dist/internals/{index-Cj45GkKv.d.ts.map → index-B710pfTH.d.ts.map} +1 -1
- package/dist/internals/{index-BWZIV3_T.mjs → index-DG2-4tQ1.mjs} +8 -1
- package/dist/internals/index-DG2-4tQ1.mjs.map +1 -0
- package/dist/internals/index-DwjvuRyl.d.mts +92 -0
- package/dist/internals/index-DwjvuRyl.d.mts.map +1 -0
- package/dist/internals/index-OwgXw07h.d.mts +2107 -0
- package/dist/internals/index-OwgXw07h.d.mts.map +1 -0
- package/dist/internals/{index-1ZK5N4yb.d.ts → index-OwgXw07h.d.ts} +49 -7
- package/dist/internals/index-OwgXw07h.d.ts.map +1 -0
- package/dist/internals/{validator-Bc1jRJfA.js → validator-CFlx3oyq.js} +33 -1
- package/dist/internals/validator-CFlx3oyq.js.map +1 -0
- package/dist/internals/{validator-Boj1PUjM.mjs → validator-DubDY921.mjs} +32 -2
- package/dist/internals/validator-DubDY921.mjs.map +1 -0
- package/package.json +7 -19
- package/dist/internals/index-1ZK5N4yb.d.ts.map +0 -1
- package/dist/internals/index-BWZIV3_T.mjs.map +0 -1
- package/dist/internals/index-vOFh8pVc.js.map +0 -1
- package/dist/internals/validator-Bc1jRJfA.js.map +0 -1
- package/dist/internals/validator-Boj1PUjM.mjs.map +0 -1
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { P as ProtoClient } from './internals/index-DwjvuRyl.mjs';
|
|
2
|
+
export { c as classExtends } from './internals/index-DwjvuRyl.mjs';
|
|
3
|
+
export { D as DeserializeOptions, S as SerializeOptions, e as TNumber, f as TSerializable, g as deserialize, s as serialize } from './internals/index-OwgXw07h.mjs';
|
|
4
|
+
export { Decimal } from 'decimal.js';
|
|
5
|
+
import '@o2ter/utils-js';
|
|
6
|
+
import 'socket.io-client';
|
|
7
|
+
import '@socket.io/component-emitter';
|
|
8
|
+
import 'jsonwebtoken';
|
|
9
|
+
import '@o2ter/server-js';
|
|
10
|
+
import 'lodash';
|
|
11
|
+
import 'node:stream';
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
export { ProtoClient, ProtoClient as default };
|
|
16
|
+
//# sourceMappingURL=client.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.mts","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;"}
|
package/dist/client.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { P as ProtoClient } from './internals/index-
|
|
2
|
-
export { c as classExtends } from './internals/index-
|
|
3
|
-
export { D as DeserializeOptions, S as SerializeOptions, e as TNumber, f as TSerializable, g as deserialize, s as serialize } from './internals/index-
|
|
1
|
+
import { P as ProtoClient } from './internals/index-B710pfTH.js';
|
|
2
|
+
export { c as classExtends } from './internals/index-B710pfTH.js';
|
|
3
|
+
export { D as DeserializeOptions, S as SerializeOptions, e as TNumber, f as TSerializable, g as deserialize, s as serialize } from './internals/index-OwgXw07h.js';
|
|
4
4
|
export { Decimal } from 'decimal.js';
|
|
5
5
|
import '@o2ter/utils-js';
|
|
6
6
|
import 'socket.io-client';
|
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-
|
|
5
|
+
var index = require('./internals/index-B0TO6h9r.js');
|
|
6
6
|
var Decimal = require('decimal.js');
|
|
7
7
|
require('@o2ter/utils-js');
|
|
8
8
|
require('./internals/private-Ciddhure.js');
|
package/dist/client.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { b as ProtoClient } from './internals/index-
|
|
2
|
-
export { c as classExtends, d as deserialize, s as serialize } from './internals/index-
|
|
1
|
+
import { b as ProtoClient } from './internals/index-DG2-4tQ1.mjs';
|
|
2
|
+
export { c as classExtends, d as deserialize, s as serialize } from './internals/index-DG2-4tQ1.mjs';
|
|
3
3
|
export { Decimal } from 'decimal.js';
|
|
4
4
|
import '@o2ter/utils-js';
|
|
5
5
|
import './internals/private-CNw40LZ7.mjs';
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import * as socket_io from 'socket.io';
|
|
2
|
+
import { Router } from 'express';
|
|
3
|
+
import { Server } from '@o2ter/server-js';
|
|
4
|
+
import { P as ProtoService, a as ProtoServiceOptions, b as ProtoServiceKeyOptions, T as TSchema, c as TValueWithoutObject } from './internals/index-OwgXw07h.mjs';
|
|
5
|
+
export { D as DeserializeOptions, S as SerializeOptions, d as TFileStorage, e as TNumber, f as TSerializable, g as deserialize, s as serialize } from './internals/index-OwgXw07h.mjs';
|
|
6
|
+
import Decimal from 'decimal.js';
|
|
7
|
+
export { Decimal } from 'decimal.js';
|
|
8
|
+
export { P as ProtoClient, c as classExtends } from './internals/index-DwjvuRyl.mjs';
|
|
9
|
+
import '@o2ter/utils-js';
|
|
10
|
+
import 'jsonwebtoken';
|
|
11
|
+
import 'lodash';
|
|
12
|
+
import 'node:stream';
|
|
13
|
+
import 'socket.io-client';
|
|
14
|
+
import '@socket.io/component-emitter';
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Schema definition utility functions.
|
|
18
|
+
*/
|
|
19
|
+
declare const schema: ((x: Record<string, TSchema>) => Record<string, TSchema>) & {
|
|
20
|
+
/**
|
|
21
|
+
* Defines a boolean schema.
|
|
22
|
+
* @param defaultValue - The default value for the boolean.
|
|
23
|
+
* @returns The boolean schema.
|
|
24
|
+
*/
|
|
25
|
+
boolean: (defaultValue?: boolean) => {
|
|
26
|
+
readonly type: "boolean";
|
|
27
|
+
readonly default: boolean | undefined;
|
|
28
|
+
};
|
|
29
|
+
/**
|
|
30
|
+
* Defines a number schema.
|
|
31
|
+
* @param defaultValue - The default value for the number.
|
|
32
|
+
* @returns The number schema.
|
|
33
|
+
*/
|
|
34
|
+
number: (defaultValue?: number) => {
|
|
35
|
+
readonly type: "number";
|
|
36
|
+
readonly default: number | undefined;
|
|
37
|
+
};
|
|
38
|
+
/**
|
|
39
|
+
* Defines a decimal schema.
|
|
40
|
+
* @param defaultValue - The default value for the decimal.
|
|
41
|
+
* @returns The decimal schema.
|
|
42
|
+
*/
|
|
43
|
+
decimal: (defaultValue?: Decimal) => {
|
|
44
|
+
readonly type: "decimal";
|
|
45
|
+
readonly default: Decimal | undefined;
|
|
46
|
+
};
|
|
47
|
+
/**
|
|
48
|
+
* Defines a string schema.
|
|
49
|
+
* @param defaultValue - The default value for the string.
|
|
50
|
+
* @returns The string schema.
|
|
51
|
+
*/
|
|
52
|
+
string: (defaultValue?: string) => {
|
|
53
|
+
readonly type: "string";
|
|
54
|
+
readonly default: string | undefined;
|
|
55
|
+
};
|
|
56
|
+
/**
|
|
57
|
+
* Defines a string array schema.
|
|
58
|
+
* @param defaultValue - The default value for the string array.
|
|
59
|
+
* @returns The string array schema.
|
|
60
|
+
*/
|
|
61
|
+
stringArray: (defaultValue?: string[]) => {
|
|
62
|
+
readonly type: "string[]";
|
|
63
|
+
readonly default: string[] | undefined;
|
|
64
|
+
};
|
|
65
|
+
/**
|
|
66
|
+
* Defines a date schema.
|
|
67
|
+
* @param defaultValue - The default value for the date.
|
|
68
|
+
* @returns The date schema.
|
|
69
|
+
*/
|
|
70
|
+
date: (defaultValue?: Date) => {
|
|
71
|
+
readonly type: "date";
|
|
72
|
+
readonly default: Date | undefined;
|
|
73
|
+
};
|
|
74
|
+
/**
|
|
75
|
+
* Defines an object schema.
|
|
76
|
+
* @param defaultValue - The default value for the object.
|
|
77
|
+
* @returns The object schema.
|
|
78
|
+
*/
|
|
79
|
+
object: <T extends Record<string, TValueWithoutObject>>(defaultValue?: T) => {
|
|
80
|
+
readonly type: "object";
|
|
81
|
+
readonly default: T | undefined;
|
|
82
|
+
};
|
|
83
|
+
/**
|
|
84
|
+
* Defines an array schema.
|
|
85
|
+
* @param defaultValue - The default value for the array.
|
|
86
|
+
* @returns The array schema.
|
|
87
|
+
*/
|
|
88
|
+
array: <T extends TValueWithoutObject[]>(defaultValue?: T) => {
|
|
89
|
+
readonly type: "array";
|
|
90
|
+
readonly default: T | undefined;
|
|
91
|
+
};
|
|
92
|
+
/**
|
|
93
|
+
* Defines a vector schema.
|
|
94
|
+
* @param dimension - The dimension of the vector.
|
|
95
|
+
* @param defaultValue - The default value for the vector.
|
|
96
|
+
* @returns The vector schema.
|
|
97
|
+
*/
|
|
98
|
+
vector: (dimension: number, defaultValue?: number[]) => {
|
|
99
|
+
readonly type: "vector";
|
|
100
|
+
readonly dimension: number;
|
|
101
|
+
readonly default: number[] | undefined;
|
|
102
|
+
};
|
|
103
|
+
/**
|
|
104
|
+
* Defines a shape schema.
|
|
105
|
+
* @param shape - The shape definition.
|
|
106
|
+
* @returns The shape schema.
|
|
107
|
+
*/
|
|
108
|
+
shape: (shape: Record<string, TSchema.DataType>) => {
|
|
109
|
+
readonly type: "shape";
|
|
110
|
+
readonly shape: Record<string, TSchema.DataType>;
|
|
111
|
+
};
|
|
112
|
+
/**
|
|
113
|
+
* Defines a pointer schema.
|
|
114
|
+
* @param target - The target of the pointer.
|
|
115
|
+
* @returns The pointer schema.
|
|
116
|
+
*/
|
|
117
|
+
pointer: (target: string) => {
|
|
118
|
+
readonly type: "pointer";
|
|
119
|
+
readonly target: string;
|
|
120
|
+
};
|
|
121
|
+
/**
|
|
122
|
+
* Defines a relation schema.
|
|
123
|
+
* @param target - The target of the relation.
|
|
124
|
+
* @param foreignField - The foreign field of the relation.
|
|
125
|
+
* @returns The relation schema.
|
|
126
|
+
*/
|
|
127
|
+
relation: (target: string, foreignField?: string) => {
|
|
128
|
+
readonly type: "relation";
|
|
129
|
+
readonly target: string;
|
|
130
|
+
readonly foreignField: string | undefined;
|
|
131
|
+
};
|
|
132
|
+
};
|
|
133
|
+
/**
|
|
134
|
+
* Creates a ProtoRoute.
|
|
135
|
+
* @param options - The options for the ProtoRoute.
|
|
136
|
+
* @returns A promise that resolves to a Router.
|
|
137
|
+
*/
|
|
138
|
+
declare const ProtoRoute: <E>(options: {
|
|
139
|
+
proto: ProtoService<E> | (ProtoServiceOptions<E> & ProtoServiceKeyOptions);
|
|
140
|
+
}) => Promise<Router>;
|
|
141
|
+
/**
|
|
142
|
+
* Registers a ProtoSocket.
|
|
143
|
+
* @param proto - The ProtoService instance.
|
|
144
|
+
* @param server - The server instance.
|
|
145
|
+
* @param endpoint - The optional endpoint.
|
|
146
|
+
* @returns The socket.io instance.
|
|
147
|
+
*/
|
|
148
|
+
declare const registerProtoSocket: <E>(proto: ProtoService<E>, server: Server, endpoint?: string) => socket_io.Server<socket_io.DefaultEventsMap, socket_io.DefaultEventsMap, socket_io.DefaultEventsMap, any> | socket_io.Namespace<socket_io.DefaultEventsMap, socket_io.DefaultEventsMap, socket_io.DefaultEventsMap, any>;
|
|
149
|
+
|
|
150
|
+
export { ProtoRoute, ProtoService, ProtoRoute as default, registerProtoSocket, schema };
|
|
151
|
+
//# sourceMappingURL=index.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.mts","sources":["../src/index.ts"],"sourcesContent":["//\n// index.ts\n//\n// The MIT License\n// Copyright (c) 2021 - 2025 O2ter Limited. All rights reserved.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n//\n\nimport _ from 'lodash';\nimport { Router } from 'express';\nimport { Server } from '@o2ter/server-js';\nimport { ProtoService } from './server/proto';\nimport { ProtoServiceKeyOptions, ProtoServiceOptions } from './server/proto/types';\nimport authHandler from './server/auth';\nimport classesRoute from './server/routes/classes';\nimport functionRoute from './server/routes/function';\nimport jobRoute from './server/routes/job';\nimport filesRoute from './server/routes/files';\nimport userRoute from './server/routes/user';\nimport notifyRoute from './server/routes/notify';\nimport schemaRoute from './server/routes/schema';\nimport configRoute from './server/routes/config';\nimport { TSchema } from './internals/schema';\nimport { PVK } from './internals/private';\nimport { TValueWithoutObject } from './internals/types';\nimport Decimal from 'decimal.js';\nimport { response } from './server/routes/common';\nimport { QuerySelector } from './server/query/dispatcher/parser';\nimport { serialize } from './internals/codec';\n\nexport * from './internals/codec';\nexport { classExtends } from './internals/utils';\nexport { TFileStorage } from './server/file';\nexport { ProtoService } from './server/proto';\nexport { ProtoClient } from './client';\n\n/**\n * Schema definition utility functions.\n */\nexport const schema = _.assign((x: Record<string, TSchema>) => x, {\n /**\n * Defines a boolean schema.\n * @param defaultValue - The default value for the boolean.\n * @returns The boolean schema.\n */\n boolean: (defaultValue?: boolean) => ({ type: 'boolean', default: defaultValue }) as const,\n\n /**\n * Defines a number schema.\n * @param defaultValue - The default value for the number.\n * @returns The number schema.\n */\n number: (defaultValue?: number) => ({ type: 'number', default: defaultValue }) as const,\n\n /**\n * Defines a decimal schema.\n * @param defaultValue - The default value for the decimal.\n * @returns The decimal schema.\n */\n decimal: (defaultValue?: Decimal) => ({ type: 'decimal', default: defaultValue }) as const,\n\n /**\n * Defines a string schema.\n * @param defaultValue - The default value for the string.\n * @returns The string schema.\n */\n string: (defaultValue?: string) => ({ type: 'string', default: defaultValue }) as const,\n\n /**\n * Defines a string array schema.\n * @param defaultValue - The default value for the string array.\n * @returns The string array schema.\n */\n stringArray: (defaultValue?: string[]) => ({ type: 'string[]', default: defaultValue }) as const,\n\n /**\n * Defines a date schema.\n * @param defaultValue - The default value for the date.\n * @returns The date schema.\n */\n date: (defaultValue?: Date) => ({ type: 'date', default: defaultValue }) as const,\n\n /**\n * Defines an object schema.\n * @param defaultValue - The default value for the object.\n * @returns The object schema.\n */\n object: <T extends Record<string, TValueWithoutObject>>(defaultValue?: T) => ({ type: 'object', default: defaultValue }) as const,\n\n /**\n * Defines an array schema.\n * @param defaultValue - The default value for the array.\n * @returns The array schema.\n */\n array: <T extends TValueWithoutObject[]>(defaultValue?: T) => ({ type: 'array', default: defaultValue }) as const,\n\n /**\n * Defines a vector schema.\n * @param dimension - The dimension of the vector.\n * @param defaultValue - The default value for the vector.\n * @returns The vector schema.\n */\n vector: (dimension: number, defaultValue?: number[]) => ({ type: 'vector', dimension, default: defaultValue }) as const,\n\n /**\n * Defines a shape schema.\n * @param shape - The shape definition.\n * @returns The shape schema.\n */\n shape: (shape: Record<string, TSchema.DataType>) => ({ type: 'shape', shape }) as const,\n\n /**\n * Defines a pointer schema.\n * @param target - The target of the pointer.\n * @returns The pointer schema.\n */\n pointer: (target: string) => ({ type: 'pointer', target }) as const,\n\n /**\n * Defines a relation schema.\n * @param target - The target of the relation.\n * @param foreignField - The foreign field of the relation.\n * @returns The relation schema.\n */\n relation: (target: string, foreignField?: string) => ({ type: 'relation', target, foreignField }) as const,\n});\n\n/**\n * Creates a ProtoRoute.\n * @param options - The options for the ProtoRoute.\n * @returns A promise that resolves to a Router.\n */\nexport const ProtoRoute = async <E>(options: {\n proto: ProtoService<E> | (ProtoServiceOptions<E> & ProtoServiceKeyOptions);\n}): Promise<Router> => {\n\n const proto = options.proto instanceof ProtoService ? options.proto : new ProtoService(options.proto);\n await proto[PVK].prepare();\n\n const router = Server.Router().use(\n authHandler(proto),\n (req, res, next) => {\n const payload = proto.connect(req);\n if (!payload.isInvalidMasterToken) return next();\n res.status(400).json({ message: 'Invalid token' });\n },\n );\n\n router.get('/health', (req, res) => { res.sendStatus(200); });\n router.get('/sessionInfo', async (req, res) => {\n await response(res, () => proto.connect(req).sessionInfo());\n });\n\n classesRoute(router, proto);\n functionRoute(router, proto);\n jobRoute(router, proto);\n filesRoute(router, proto);\n userRoute(router, proto);\n notifyRoute(router, proto);\n schemaRoute(router, proto);\n configRoute(router, proto);\n\n return router;\n}\n\n/**\n * Registers a ProtoSocket.\n * @param proto - The ProtoService instance.\n * @param server - The server instance.\n * @param endpoint - The optional endpoint.\n * @returns The socket.io instance.\n */\nexport const registerProtoSocket = <E>(\n proto: ProtoService<E>,\n server: Server,\n endpoint?: string,\n) => {\n const io = endpoint ? server.socket().of(endpoint) : server.socket();\n\n io.on('connection', async (socket) => {\n\n let { token } = socket.handshake.auth;\n const service = await proto.connectWithSessionToken(token);\n\n socket.on('auth', (t) => {\n token = t;\n service.connectWithSessionToken(t);\n });\n\n type QueryOpts = {\n event: string;\n className: string;\n filter: QuerySelector | boolean;\n };\n\n let events: Record<string, QuerySelector | boolean> = {};\n let queries: Record<string, QueryOpts> = {};\n\n const { remove: remove_basic } = service.listen(data => {\n const ids = _.keys(_.pickBy(events, v => v instanceof QuerySelector ? v.eval(data) : v));\n const payload = JSON.parse(serialize(data));\n if (!_.isEmpty(ids)) socket.emit('ON_EV_NOTIFY', { ids, data: payload });\n });\n\n const { remove: remove_livequery } = service[PVK]._liveQuery(service, (ev, objs) => {\n const ids: Record<string, string[]> = {};\n for (const obj of objs) {\n ids[obj.id!] = _.keys(_.pickBy(queries, v => {\n if (v.event !== ev || v.className !== obj.className) return false;\n return v.filter instanceof QuerySelector ? v.filter.eval(obj) : v.filter;\n }));\n }\n if (_.isEmpty(ids)) return;\n const payload = JSON.parse(serialize(_.filter(objs, obj => !_.isEmpty(ids[obj.id!]))));\n socket.emit('ON_EV_LIVEQUERY', { ids, data: payload });\n });\n\n socket.on('disconnect', () => {\n remove_basic();\n remove_livequery();\n });\n\n socket.on('EV_NOTIFY', (payload) => {\n events = _.mapValues(payload, v => {\n if (_.isBoolean(v)) return true;\n try {\n return QuerySelector.decode(v);\n } catch (error) {\n proto.logger.error(error);\n return false;\n }\n });\n });\n\n socket.on('EV_LIVEQUERY', (payload) => {\n queries = _.mapValues(payload, v => {\n const { event = '', className = '', filter } = v ?? {};\n if (_.isBoolean(v)) return { event, className, filter: true };\n try {\n return { event, className, filter: QuerySelector.decode(filter) };\n } catch (error) {\n proto.logger.error(error);\n return { event, className, filter: false };\n }\n });\n });\n });\n\n return io;\n}\n\nexport default ProtoRoute;"],"names":[],"mappings":";;;;;;;;;;;;;;;AAYA;AACA;AACA;AACO,cAAA,MAAA,OAAA,MAAA,SAAA,OAAA,MAAA,MAAA,SAAA,OAAA;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6BAAA,OAAA;AACA;AACA,0BAAA,OAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0BAAA,IAAA;AACA;AACA,0BAAA,IAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uBAAA,MAAA,SAAA,mBAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAA,mBAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAA,MAAA,SAAA,OAAA,CAAA,QAAA;AACA;AACA,wBAAA,MAAA,SAAA,OAAA,CAAA,QAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,cAAA,UAAA;AACP,WAAA,YAAA,OAAA,mBAAA,MAAA,sBAAA;AACA,MAAA,OAAA,CAAA,MAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,cAAA,mBAAA,aAAA,YAAA,aAAA,MAAA,wBAAqG,SAAmB,CAAA,MAAA,CAAQ,SAAmB,CAAA,gBAAA,EAAmB,SAAmB,CAAA,gBAAA,EAAmB,SAAmB,CAAA,gBAAA,SAA0B,SAAmB,CAAA,SAAA,CAAW,SAAmB,CAAA,gBAAA,EAAmB,SAAmB,mBAAmB,SAAmB,CAAA,gBAAA;;;;"}
|
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 { P as ProtoService, a as ProtoServiceOptions, b as ProtoServiceKeyOptions, T as TSchema, c as TValueWithoutObject } from './internals/index-
|
|
5
|
-
export { D as DeserializeOptions, S as SerializeOptions, d as TFileStorage, e as TNumber, f as TSerializable, g as deserialize, s as serialize } from './internals/index-
|
|
4
|
+
import { P as ProtoService, a as ProtoServiceOptions, b as ProtoServiceKeyOptions, T as TSchema, c as TValueWithoutObject } from './internals/index-OwgXw07h.js';
|
|
5
|
+
export { D as DeserializeOptions, S as SerializeOptions, d as TFileStorage, e as TNumber, f as TSerializable, g as deserialize, s as serialize } from './internals/index-OwgXw07h.js';
|
|
6
6
|
import Decimal from 'decimal.js';
|
|
7
7
|
export { Decimal } from 'decimal.js';
|
|
8
|
-
export { P as ProtoClient, c as classExtends } from './internals/index-
|
|
8
|
+
export { P as ProtoClient, c as classExtends } from './internals/index-B710pfTH.js';
|
|
9
9
|
import '@o2ter/utils-js';
|
|
10
10
|
import 'jsonwebtoken';
|
|
11
11
|
import 'lodash';
|
package/dist/index.js
CHANGED
|
@@ -4,10 +4,10 @@ Object.defineProperty(exports, '__esModule', { value: true });
|
|
|
4
4
|
|
|
5
5
|
var _ = require('lodash');
|
|
6
6
|
var serverJs = require('@o2ter/server-js');
|
|
7
|
-
var validator = require('./internals/validator-
|
|
7
|
+
var validator = require('./internals/validator-CFlx3oyq.js');
|
|
8
8
|
var _private = require('./internals/private-Ciddhure.js');
|
|
9
9
|
var utilsJs = require('@o2ter/utils-js');
|
|
10
|
-
var index = require('./internals/index-
|
|
10
|
+
var index = require('./internals/index-B0TO6h9r.js');
|
|
11
11
|
var index$1 = require('./internals/index-CLKTEIj0.js');
|
|
12
12
|
var jwt = require('jsonwebtoken');
|
|
13
13
|
var node_buffer = require('node:buffer');
|
|
@@ -116,6 +116,16 @@ const dispatcher = (proto, options) => {
|
|
|
116
116
|
throw Error('No permission');
|
|
117
117
|
return proto.storage.find(decoded);
|
|
118
118
|
},
|
|
119
|
+
async groupFind(query, accumulators) {
|
|
120
|
+
validator.QueryValidator.recursiveCheck(query);
|
|
121
|
+
const _validator = await validator$1();
|
|
122
|
+
const decoded = _validator.decodeQuery(normalize(query), 'read');
|
|
123
|
+
const isGet = _validator.isGetMethod(decoded.filter);
|
|
124
|
+
if (!_validator.validateCLPs(query.className, isGet ? 'get' : 'find'))
|
|
125
|
+
throw Error('No permission');
|
|
126
|
+
const acc = _.mapValues(accumulators, x => validator.QueryAccumulator.decode(x).simplify());
|
|
127
|
+
return proto.storage.groupFind(decoded, acc);
|
|
128
|
+
},
|
|
119
129
|
async nonrefs(query) {
|
|
120
130
|
validator.QueryValidator.recursiveCheck(query);
|
|
121
131
|
const _validator = await validator$1();
|
|
@@ -312,6 +322,9 @@ class _ProtoQuery extends index.TQuery {
|
|
|
312
322
|
yield self._objectMethods(object);
|
|
313
323
|
});
|
|
314
324
|
}
|
|
325
|
+
groupFind(accumulators, options) {
|
|
326
|
+
return this._dispatcher(options).groupFind(this._queryOptions, accumulators);
|
|
327
|
+
}
|
|
315
328
|
nonrefs(options) {
|
|
316
329
|
const self = this;
|
|
317
330
|
return utilsJs.asyncStream(async function* () {
|
|
@@ -526,6 +539,8 @@ const defaultSchema = {
|
|
|
526
539
|
'User': {
|
|
527
540
|
fields: {
|
|
528
541
|
password: 'object',
|
|
542
|
+
password_history: 'array',
|
|
543
|
+
password_changed_at: 'date',
|
|
529
544
|
},
|
|
530
545
|
classLevelPermissions: {
|
|
531
546
|
find: [],
|
|
@@ -535,7 +550,7 @@ const defaultSchema = {
|
|
|
535
550
|
fieldLevelPermissions: {
|
|
536
551
|
_expired_at: { create: [], update: [] },
|
|
537
552
|
},
|
|
538
|
-
secureFields: ['password'],
|
|
553
|
+
secureFields: ['password', 'password_history', 'password_changed_at'],
|
|
539
554
|
},
|
|
540
555
|
'Role': {
|
|
541
556
|
fields: {
|
|
@@ -704,7 +719,7 @@ const passwordHash = async (alg, password, options) => {
|
|
|
704
719
|
...options
|
|
705
720
|
};
|
|
706
721
|
};
|
|
707
|
-
const
|
|
722
|
+
const verifyPassword = async (alg, password, options) => {
|
|
708
723
|
if (!_.isString(options.salt))
|
|
709
724
|
return false;
|
|
710
725
|
if (!_.isString(options.derivedKey))
|
|
@@ -901,7 +916,7 @@ class ProtoInternal {
|
|
|
901
916
|
}
|
|
902
917
|
return callback(proxy(payload ?? proto));
|
|
903
918
|
}
|
|
904
|
-
async
|
|
919
|
+
async verifyPassword(proto, user, password, options) {
|
|
905
920
|
if (!user.id)
|
|
906
921
|
throw Error('Invalid user object');
|
|
907
922
|
const _user = await proto.InsecureQuery('User')
|
|
@@ -909,20 +924,46 @@ class ProtoInternal {
|
|
|
909
924
|
.includes('_id', 'password')
|
|
910
925
|
.first(options);
|
|
911
926
|
const { alg, ...opts } = _user?.get('password') ?? {};
|
|
912
|
-
return
|
|
927
|
+
return verifyPassword(alg, password, opts);
|
|
913
928
|
}
|
|
914
929
|
async setPassword(proto, user, password, options) {
|
|
915
930
|
if (!user.id)
|
|
916
931
|
throw Error('Invalid user object');
|
|
917
932
|
if (_.isEmpty(password))
|
|
918
933
|
throw Error('Invalid password');
|
|
934
|
+
const { maxPasswordHistory, validatorCallback, } = this.options.passwordPolicy || {};
|
|
935
|
+
if (validatorCallback) {
|
|
936
|
+
const isValid = await validatorCallback(password, user);
|
|
937
|
+
if (!isValid)
|
|
938
|
+
throw Error('Password does not meet the policy requirements');
|
|
939
|
+
}
|
|
919
940
|
const { alg, ...opts } = this.options.passwordHashOptions;
|
|
920
941
|
const hashed = await passwordHash(alg, password, opts);
|
|
942
|
+
let history = [];
|
|
943
|
+
if (maxPasswordHistory && maxPasswordHistory > 0) {
|
|
944
|
+
const _user = await proto.InsecureQuery('User')
|
|
945
|
+
.equalTo('_id', user.id)
|
|
946
|
+
.includes('_id', 'password_history')
|
|
947
|
+
.first(options);
|
|
948
|
+
history = _.slice(_user?.get('password_history') ?? [], 0, maxPasswordHistory);
|
|
949
|
+
for (const entry of history) {
|
|
950
|
+
const { alg, ...opts } = entry;
|
|
951
|
+
if (await verifyPassword(alg, password, opts)) {
|
|
952
|
+
throw Error('Cannot reuse previous passwords');
|
|
953
|
+
}
|
|
954
|
+
}
|
|
955
|
+
}
|
|
921
956
|
await proto.InsecureQuery('User')
|
|
922
957
|
.equalTo('_id', user.id)
|
|
923
958
|
.includes('_id')
|
|
924
959
|
.updateOne({
|
|
925
960
|
password: { $set: hashed },
|
|
961
|
+
password_history: {
|
|
962
|
+
$set: maxPasswordHistory && maxPasswordHistory > 0
|
|
963
|
+
? _.slice([{ ...hashed, password }, ...history], 0, maxPasswordHistory)
|
|
964
|
+
: [],
|
|
965
|
+
},
|
|
966
|
+
password_changed_at: { $set: new Date() },
|
|
926
967
|
}, options);
|
|
927
968
|
}
|
|
928
969
|
async unsetPassword(proto, user, options) {
|
|
@@ -933,6 +974,7 @@ class ProtoInternal {
|
|
|
933
974
|
.includes('_id')
|
|
934
975
|
.updateOne({
|
|
935
976
|
password: { $set: {} },
|
|
977
|
+
password_changed_at: { $set: new Date() },
|
|
936
978
|
}, options);
|
|
937
979
|
}
|
|
938
980
|
async updateFile(proto, object, options) {
|
|
@@ -950,8 +992,8 @@ class ProtoInternal {
|
|
|
950
992
|
}
|
|
951
993
|
return object;
|
|
952
994
|
}
|
|
953
|
-
|
|
954
|
-
const { nonce, attributes, maxUploadSize, } = (_.isString(token) ? this.
|
|
995
|
+
verifyUploadToken(proto, token, isMaster) {
|
|
996
|
+
const { nonce, attributes, maxUploadSize, } = (_.isString(token) ? this.jwtVerify(token, 'upload') ?? {} : {});
|
|
955
997
|
if (!isMaster && !nonce)
|
|
956
998
|
throw Error('Upload token is required');
|
|
957
999
|
return {
|
|
@@ -964,7 +1006,7 @@ class ProtoInternal {
|
|
|
964
1006
|
const data = object[_private.PVK].extra.data;
|
|
965
1007
|
if (_.isNil(data))
|
|
966
1008
|
throw Error('Invalid file object');
|
|
967
|
-
const { nonce, attributes = {}, maxUploadSize = this.options.maxUploadSize, } = options?.uploadToken ? this.
|
|
1009
|
+
const { nonce, attributes = {}, maxUploadSize = this.options.maxUploadSize, } = options?.uploadToken ? this.verifyUploadToken(proto, options.uploadToken, options.master) : {};
|
|
968
1010
|
if (nonce) {
|
|
969
1011
|
const found = await proto.Query('File').equalTo('nonce', nonce).first({ master: true });
|
|
970
1012
|
if (found)
|
|
@@ -1071,7 +1113,7 @@ class ProtoInternal {
|
|
|
1071
1113
|
})();
|
|
1072
1114
|
return jwt.sign(payload, this.options.jwtToken, opts);
|
|
1073
1115
|
}
|
|
1074
|
-
|
|
1116
|
+
jwtVerify(token, options = {}) {
|
|
1075
1117
|
try {
|
|
1076
1118
|
const opts = (() => {
|
|
1077
1119
|
switch (options) {
|
|
@@ -1207,7 +1249,7 @@ class ProtoInternal {
|
|
|
1207
1249
|
obj.set('data', params);
|
|
1208
1250
|
obj.set('user', user);
|
|
1209
1251
|
await obj.save({ master: true });
|
|
1210
|
-
this.jobRunner.
|
|
1252
|
+
this.jobRunner.executeJob(proto);
|
|
1211
1253
|
return obj;
|
|
1212
1254
|
}
|
|
1213
1255
|
}
|
|
@@ -1269,7 +1311,7 @@ class JobRunner {
|
|
|
1269
1311
|
job.set('completedAt', new Date());
|
|
1270
1312
|
await job.save({ master: true });
|
|
1271
1313
|
}
|
|
1272
|
-
async
|
|
1314
|
+
async executeJob(proto) {
|
|
1273
1315
|
if (this._running || this._stopped)
|
|
1274
1316
|
return;
|
|
1275
1317
|
this._running = true;
|
|
@@ -1299,7 +1341,7 @@ class JobRunner {
|
|
|
1299
1341
|
finally {
|
|
1300
1342
|
clearInterval(timer);
|
|
1301
1343
|
}
|
|
1302
|
-
this.
|
|
1344
|
+
this.executeJob(proto);
|
|
1303
1345
|
})();
|
|
1304
1346
|
}
|
|
1305
1347
|
this._running = false;
|
|
@@ -1333,7 +1375,7 @@ class JobRunner {
|
|
|
1333
1375
|
const _sessionWithToken = async (proto, token) => {
|
|
1334
1376
|
if (_.isEmpty(token))
|
|
1335
1377
|
return;
|
|
1336
|
-
const payload = proto[_private.PVK].
|
|
1378
|
+
const payload = proto[_private.PVK].jwtVerify(token, 'login') ?? {};
|
|
1337
1379
|
if (!_.isString(payload.sessionId) || _.isEmpty(payload.sessionId))
|
|
1338
1380
|
return;
|
|
1339
1381
|
const session = await proto.Query('_Session')
|
|
@@ -1492,8 +1534,8 @@ const scheduleOp = {
|
|
|
1492
1534
|
expireDocument: async (proto) => {
|
|
1493
1535
|
await proto.gc();
|
|
1494
1536
|
},
|
|
1495
|
-
|
|
1496
|
-
proto[_private.PVK].jobRunner.
|
|
1537
|
+
executeJob: async (proto) => {
|
|
1538
|
+
proto[_private.PVK].jobRunner.executeJob(proto);
|
|
1497
1539
|
},
|
|
1498
1540
|
};
|
|
1499
1541
|
const schedule = (proto) => {
|
|
@@ -1702,8 +1744,8 @@ class ProtoService extends index.ProtoType {
|
|
|
1702
1744
|
if (req.res)
|
|
1703
1745
|
await signUser(this, req.res, undefined, options);
|
|
1704
1746
|
}
|
|
1705
|
-
|
|
1706
|
-
return this[_private.PVK].
|
|
1747
|
+
verifyPassword(user, password, options) {
|
|
1748
|
+
return this[_private.PVK].verifyPassword(this, user, password, options);
|
|
1707
1749
|
}
|
|
1708
1750
|
setPassword(user, password, options) {
|
|
1709
1751
|
return this[_private.PVK].setPassword(this, user, password, options);
|
|
@@ -1790,8 +1832,8 @@ class ProtoService extends index.ProtoType {
|
|
|
1790
1832
|
jwtSign(payload, options) {
|
|
1791
1833
|
return this[_private.PVK].jwtSign(payload, options);
|
|
1792
1834
|
}
|
|
1793
|
-
|
|
1794
|
-
return this[_private.PVK].
|
|
1835
|
+
jwtVerify(token, options = {}) {
|
|
1836
|
+
return this[_private.PVK].jwtVerify(token, options);
|
|
1795
1837
|
}
|
|
1796
1838
|
notify(data) {
|
|
1797
1839
|
return this[_private.PVK].notify(this, data);
|
|
@@ -1977,7 +2019,7 @@ const verifyRelatedBy = (relatedBy) => {
|
|
|
1977
2019
|
var classesRoute = (router, proto) => {
|
|
1978
2020
|
const defaultHandler = async (req) => {
|
|
1979
2021
|
const { name } = req.params;
|
|
1980
|
-
const { operation, random, attributes, update, setOnInsert, relatedBy, silent, ...options } = index.deserialize(req.body);
|
|
2022
|
+
const { operation, accumulators, random, attributes, update, setOnInsert, relatedBy, silent, ...options } = index.deserialize(req.body);
|
|
1981
2023
|
verifyRelatedBy(relatedBy);
|
|
1982
2024
|
const payload = proto.connect(req);
|
|
1983
2025
|
const query = relatedBy ? payload.Relation(payload.Object(relatedBy.className, relatedBy.id), relatedBy.key) : payload.Query(name);
|
|
@@ -1998,15 +2040,16 @@ var classesRoute = (router, proto) => {
|
|
|
1998
2040
|
query[_private.PVK].options.limit = query[_private.PVK].options.limit ?? maxFetchLimit;
|
|
1999
2041
|
if (query[_private.PVK].options.limit > maxFetchLimit)
|
|
2000
2042
|
throw Error('Query over limit');
|
|
2001
|
-
return
|
|
2043
|
+
return query.find(opts);
|
|
2002
2044
|
}
|
|
2045
|
+
case 'groupFind': return query.groupFind(accumulators, opts);
|
|
2003
2046
|
case 'random':
|
|
2004
2047
|
{
|
|
2005
2048
|
const maxFetchLimit = payload[_private.PVK].options.maxFetchLimit;
|
|
2006
2049
|
query[_private.PVK].options.limit = query[_private.PVK].options.limit ?? maxFetchLimit;
|
|
2007
2050
|
if (query[_private.PVK].options.limit > maxFetchLimit)
|
|
2008
2051
|
throw Error('Query over limit');
|
|
2009
|
-
return
|
|
2052
|
+
return query.random(random, opts);
|
|
2010
2053
|
}
|
|
2011
2054
|
case 'nonrefs':
|
|
2012
2055
|
{
|
|
@@ -2014,7 +2057,7 @@ var classesRoute = (router, proto) => {
|
|
|
2014
2057
|
query[_private.PVK].options.limit = query[_private.PVK].options.limit ?? maxFetchLimit;
|
|
2015
2058
|
if (query[_private.PVK].options.limit > maxFetchLimit)
|
|
2016
2059
|
throw Error('Query over limit');
|
|
2017
|
-
return
|
|
2060
|
+
return query.nonrefs(opts);
|
|
2018
2061
|
}
|
|
2019
2062
|
case 'insert': return query.insert(attributes, opts);
|
|
2020
2063
|
case 'insertMany': return query.insertMany(attributes, opts);
|
|
@@ -2284,7 +2327,7 @@ var filesRoute = (router, proto) => {
|
|
|
2284
2327
|
await response(res, async () => {
|
|
2285
2328
|
const payload = proto.connect(req);
|
|
2286
2329
|
const uploadToken = req.header(_const.UPLOAD_TOKEN_HEADER_NAME);
|
|
2287
|
-
const { maxUploadSize } = payload[_private.PVK].
|
|
2330
|
+
const { maxUploadSize } = payload[_private.PVK].verifyUploadToken(payload, uploadToken, payload.isMaster);
|
|
2288
2331
|
const { attributes, file } = await decodeFormStream(req, (file, info) => proto.fileStorage.create(proto, file, info, maxUploadSize));
|
|
2289
2332
|
try {
|
|
2290
2333
|
const obj = payload.Object('File');
|