@yongdall/core 0.4.3 → 0.5.0
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/index.d.mts +62 -46
- package/index.mjs +331 -118
- package/index.mjs.map +1 -1
- package/package.json +6 -5
package/index.mjs
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { Hook, Search, isFunction } from "@yongdall/common";
|
|
1
|
+
import { Hook, LazyPromise, Search, isFunction } from "@yongdall/common";
|
|
2
2
|
import { Query, Where, afterCreate, afterCreateMany, afterDelete, afterUpdate, beforeCreate, beforeCreateMany, beforeDelete, beforeUpdate, coefficient, decrement, expandModel, getDefinePermission, increment, multiply } from "@yongdall/model";
|
|
3
3
|
import { createKeyStore, createStoreSerializable } from "@yongdall/context";
|
|
4
|
+
import { loadPluginProfiles } from "@yongdall/plugins";
|
|
4
5
|
|
|
5
6
|
//#region packages/core/polyfill.mjs
|
|
6
7
|
if (!Symbol.metadata) Symbol.metadata = Symbol.for("Symbol.metadata");
|
|
@@ -60,23 +61,21 @@ function getMenus(type, group = "") {
|
|
|
60
61
|
//#region packages/core/models.mjs
|
|
61
62
|
/** @import { Permission } from '@yongdall/types' */
|
|
62
63
|
/** @import { FieldDefine, Fields, ModelTable, TableDefine } from '@yongdall/model' */
|
|
63
|
-
/** @import {
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
getModelPermissionsHooks = [...hooks.get("getModelPermissions").values()].filter((v) => typeof v === "function");
|
|
79
|
-
const modelFields = [...hooks.get("modelExpands").entriesObject()].flatMap(([p, modelId, fields]) => [fields].flatMap((v) => {
|
|
64
|
+
/** @import { ModelProfile } from './types.mjs' */
|
|
65
|
+
const ModelProfilePromise = LazyPromise.try(async function() {
|
|
66
|
+
return await Array.fromAsync(loadPluginProfiles("model", (v) => [v]));
|
|
67
|
+
});
|
|
68
|
+
const modelsPromise = ModelProfilePromise.lazyThen((list) => {
|
|
69
|
+
return Object.fromEntries(list.flatMap((v) => Object.entries(v.models || {})));
|
|
70
|
+
});
|
|
71
|
+
const modelLoadersPromise = ModelProfilePromise.lazyThen((list) => {
|
|
72
|
+
return Object.fromEntries(list.flatMap((v) => Object.entries(v.modelLoaders || {})));
|
|
73
|
+
});
|
|
74
|
+
const getModelPermissionsHooksPromise = ModelProfilePromise.lazyThen((list) => {
|
|
75
|
+
return list.map((v) => v.getModelPermissions).filter((v) => typeof v === "function");
|
|
76
|
+
});
|
|
77
|
+
const modelExpandsPromise = ModelProfilePromise.lazyThen((list) => {
|
|
78
|
+
const modelFields = list.flatMap((v) => Object.entries(v.modelExpands || {})).flatMap(([modelId, fields]) => [fields].flatMap((v) => {
|
|
80
79
|
if (!v || typeof v !== "object" || Array.isArray(v)) return [];
|
|
81
80
|
return Object.entries(v).map(([fieldName, field]) => [
|
|
82
81
|
modelId,
|
|
@@ -91,8 +90,9 @@ hooks.listen(() => {
|
|
|
91
90
|
if (!fields?.length) continue;
|
|
92
91
|
expands[modelId] = Object.fromEntries(fields.map(([, fieldName, field]) => [fieldName, field]));
|
|
93
92
|
}
|
|
94
|
-
|
|
95
|
-
}
|
|
93
|
+
return expands;
|
|
94
|
+
});
|
|
95
|
+
const modelMap = /* @__PURE__ */ new WeakMap();
|
|
96
96
|
/**
|
|
97
97
|
*
|
|
98
98
|
* @param {string | string[]} ident
|
|
@@ -101,9 +101,11 @@ hooks.listen(() => {
|
|
|
101
101
|
async function findModel(ident) {
|
|
102
102
|
const [model, ...collection] = (Array.isArray(ident) ? ident : ident.split(":")).filter(Boolean);
|
|
103
103
|
if (!collection.length) {
|
|
104
|
+
const models = await modelsPromise;
|
|
104
105
|
const define = Object.hasOwn(models, model) && models[model];
|
|
105
106
|
return (typeof define === "object" || typeof define === "function") && define || null;
|
|
106
107
|
}
|
|
108
|
+
const modelLoaders = await modelLoadersPromise;
|
|
107
109
|
const loader = Object.hasOwn(modelLoaders, model) && modelLoaders[model];
|
|
108
110
|
if (typeof loader !== "function") return null;
|
|
109
111
|
const define = await loader(collection);
|
|
@@ -120,13 +122,14 @@ async function getModel(ident) {
|
|
|
120
122
|
const define = modelMap.get(model);
|
|
121
123
|
if (define) return define;
|
|
122
124
|
const modelIdent = Array.isArray(ident) ? ident.join(":") : ident;
|
|
125
|
+
const modelExpands = await modelExpandsPromise;
|
|
123
126
|
const newDefine = expandModel(model, Object.hasOwn(modelExpands, modelIdent) ? modelExpands[modelIdent] : {});
|
|
124
127
|
modelMap.set(model, newDefine);
|
|
125
128
|
return newDefine;
|
|
126
129
|
}
|
|
127
130
|
/** @type {(modelId: string, groupId?: string?) => Promise<Permission[]?>} */
|
|
128
131
|
const getModelPermissions = createKeyStore(async (modelId, groupId) => {
|
|
129
|
-
for (const fn of
|
|
132
|
+
for (const fn of await getModelPermissionsHooksPromise) {
|
|
130
133
|
const permissions = await fn(modelId, groupId);
|
|
131
134
|
if (permissions) return permissions;
|
|
132
135
|
}
|
|
@@ -180,7 +183,7 @@ async function getCurrentTenant() {
|
|
|
180
183
|
}
|
|
181
184
|
throw new Error("[noTenant] 找不到租户");
|
|
182
185
|
}
|
|
183
|
-
async function get$
|
|
186
|
+
async function get$2() {
|
|
184
187
|
let state = tenantGetter();
|
|
185
188
|
if (!state) {
|
|
186
189
|
state = getCurrentTenant();
|
|
@@ -193,7 +196,7 @@ async function get$1() {
|
|
|
193
196
|
* @returns {Promise<Tenant>}
|
|
194
197
|
*/
|
|
195
198
|
function useTenant() {
|
|
196
|
-
return get$
|
|
199
|
+
return get$2();
|
|
197
200
|
}
|
|
198
201
|
|
|
199
202
|
//#endregion
|
|
@@ -201,7 +204,7 @@ function useTenant() {
|
|
|
201
204
|
/** @import { Permissions, Tenant } from '@yongdall/types' */
|
|
202
205
|
/** @import { UserManager, MaybePromise } from './types.mjs' */
|
|
203
206
|
/**
|
|
204
|
-
* @typedef {[result: string | null, UserManager['set'] | null, UserManager['exit'] | null, user: string | null, sUser: string | null]}
|
|
207
|
+
* @typedef {[result: string | null, UserManager['set'] | null, UserManager['exit'] | null, user: string | null, sUser: string | null]} UserState
|
|
205
208
|
*/
|
|
206
209
|
const [userGetter, userSetter] = createStoreSerializable("userStatus", async (state) => {
|
|
207
210
|
if (!state) return null;
|
|
@@ -221,80 +224,70 @@ const [userGetter, userSetter] = createStoreSerializable("userStatus", async (st
|
|
|
221
224
|
sUserId
|
|
222
225
|
]);
|
|
223
226
|
}, null);
|
|
224
|
-
|
|
225
|
-
return
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
227
|
+
const userManagerMap = LazyPromise.try(async function() {
|
|
228
|
+
return await Array.fromAsync(loadPluginProfiles("user"));
|
|
229
|
+
});
|
|
230
|
+
const userManagers = userManagerMap.lazyThen((list) => list.map((v) => v[1]));
|
|
231
|
+
const defaultLogin$1 = userManagers.lazyThen((userMangers) => {
|
|
232
|
+
return userMangers.find((v) => typeof v.login === "function")?.login || null;
|
|
233
|
+
});
|
|
234
|
+
const switchableListPromise = userManagers.lazyThen((userMangers) => {
|
|
231
235
|
const switchableList = userMangers.map((v) => v.switchable).filter(isFunction);
|
|
232
|
-
/** @type {(() => MaybePromise<string?>)[]} */
|
|
233
|
-
const suGets = userMangers.map((v) => v.suGet).filter(isFunction);
|
|
234
|
-
/** @type {[UserManager['get'], UserManager['set'] | null, UserManager['exit'] | null][]} */
|
|
235
|
-
const getLoggedUserFn = [];
|
|
236
|
-
/** @type {Record<string, ((userId: string, password: string) => MaybePromise<number>)[]>} */
|
|
237
|
-
const verifiers = Object.create(null);
|
|
238
|
-
/** @type {Record<string, ((userId: string, password: string?, deadline?: Date?) => MaybePromise<boolean>)[]>} */
|
|
239
|
-
const setVerifiers = Object.create(null);
|
|
240
|
-
const finders = userMangers.map((v) => v.find).filter((v) => typeof v === "function");
|
|
241
|
-
const loaders = userMangers.map((v) => v.load).filter((v) => typeof v === "function");
|
|
242
|
-
const existTesters = userMangers.map((v) => v.exist).filter((v) => typeof v === "function");
|
|
243
|
-
const getPermissions = userMangers.map((v) => v.getPermissions).filter((v) => typeof v === "function");
|
|
244
|
-
const getOrganizationPermissions = userMangers.map((v) => v.getOrganizationPermissions).filter((v) => typeof v === "function");
|
|
245
|
-
const getOrganizationAllPermissions = userMangers.map((v) => v.getOrganizationAllPermissions).filter((v) => typeof v === "function");
|
|
246
|
-
for (const { get, set, exit, find, verify, setVerify } of userMangers) {
|
|
247
|
-
if (typeof get === "function") getLoggedUserFn.push([
|
|
248
|
-
get,
|
|
249
|
-
set || null,
|
|
250
|
-
exit || null
|
|
251
|
-
]);
|
|
252
|
-
if (verify) for (const [k, v] of Object.entries(verify)) {
|
|
253
|
-
const list = verifiers[k];
|
|
254
|
-
if (list) list.push(v);
|
|
255
|
-
else verifiers[k] = [v];
|
|
256
|
-
}
|
|
257
|
-
if (setVerify) for (const [k, v] of Object.entries(setVerify)) {
|
|
258
|
-
const list = setVerifiers[k];
|
|
259
|
-
if (list) list.push(v);
|
|
260
|
-
else setVerifiers[k] = [v];
|
|
261
|
-
}
|
|
262
|
-
}
|
|
263
236
|
/**
|
|
264
237
|
* @param {Tenant} tenant
|
|
265
238
|
* @param {string} user
|
|
266
239
|
* @param {string} sUser
|
|
267
240
|
* @returns {Promise<boolean>}
|
|
268
241
|
*/
|
|
269
|
-
async function switchable(tenant, user, sUser) {
|
|
242
|
+
return async function switchable(tenant, user, sUser) {
|
|
270
243
|
if (!switchableList.length) return false;
|
|
271
244
|
for (const s of switchableList) {
|
|
272
245
|
if (await s(user, sUser)) continue;
|
|
273
246
|
return false;
|
|
274
247
|
}
|
|
275
248
|
return true;
|
|
276
|
-
}
|
|
277
|
-
return {
|
|
278
|
-
defaultLogin,
|
|
279
|
-
switchable,
|
|
280
|
-
suGets,
|
|
281
|
-
getLoggedUserFn,
|
|
282
|
-
finders,
|
|
283
|
-
verifiers,
|
|
284
|
-
setVerifiers,
|
|
285
|
-
loaders,
|
|
286
|
-
existTesters,
|
|
287
|
-
getPermissions,
|
|
288
|
-
getOrganizationPermissions,
|
|
289
|
-
getOrganizationAllPermissions
|
|
290
249
|
};
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
250
|
+
});
|
|
251
|
+
const suGets = userManagers.lazyThen((userMangers) => {
|
|
252
|
+
/** @type {(() => MaybePromise<string?>)[]} */
|
|
253
|
+
return userMangers.map((v) => v.suGet).filter(isFunction);
|
|
254
|
+
});
|
|
255
|
+
const finders$1 = userManagers.lazyThen((userMangers) => {
|
|
256
|
+
return userMangers.map((v) => v.find).filter((v) => typeof v === "function");
|
|
257
|
+
});
|
|
258
|
+
const loaders = userManagers.lazyThen((userMangers) => {
|
|
259
|
+
return userMangers.map((v) => v.load).filter((v) => typeof v === "function");
|
|
260
|
+
});
|
|
261
|
+
const existTesters$1 = userManagers.lazyThen((userMangers) => {
|
|
262
|
+
return userMangers.map((v) => v.exist).filter((v) => typeof v === "function");
|
|
263
|
+
});
|
|
264
|
+
const getPermissions = userManagers.lazyThen((userMangers) => {
|
|
265
|
+
return userMangers.map((v) => v.getPermissions).filter((v) => typeof v === "function");
|
|
266
|
+
});
|
|
267
|
+
const getOrganizationPermissions = userManagers.lazyThen((userMangers) => {
|
|
268
|
+
return userMangers.map((v) => v.getOrganizationPermissions).filter((v) => typeof v === "function");
|
|
269
|
+
});
|
|
270
|
+
const getOrganizationAllPermissions = userManagers.lazyThen((userMangers) => {
|
|
271
|
+
return userMangers.map((v) => v.getOrganizationAllPermissions).filter((v) => typeof v === "function");
|
|
272
|
+
});
|
|
273
|
+
const getLoggedUserFn = userManagers.lazyThen((userMangers) => {
|
|
274
|
+
/** @type {[UserManager['get'], UserManager['set'] | null, UserManager['exit'] | null][]} */
|
|
275
|
+
const getLoggedUserFn = [];
|
|
276
|
+
for (const { get, set, exit } of userMangers) if (typeof get === "function") getLoggedUserFn.push([
|
|
277
|
+
get,
|
|
278
|
+
set || null,
|
|
279
|
+
exit || null
|
|
280
|
+
]);
|
|
281
|
+
return getLoggedUserFn;
|
|
282
|
+
});
|
|
283
|
+
const verifiersPromise = userManagers.lazyThen((userMangers) => {
|
|
284
|
+
const list = userMangers.map((v) => v).flatMap((v) => Object.entries(v.verify || {}));
|
|
285
|
+
return Object.fromEntries(Object.entries(Object.groupBy(list, (v) => v[0])).map(([k, v]) => [k, v?.map((v) => v[1]) || []]));
|
|
286
|
+
});
|
|
287
|
+
const setVerifiersPromise = userManagers.lazyThen((userMangers) => {
|
|
288
|
+
const list = userMangers.map((v) => v).flatMap((v) => Object.entries(v.setVerify || {}));
|
|
289
|
+
return Object.fromEntries(Object.entries(Object.groupBy(list, (v) => v[0])).map(([k, v]) => [k, v?.map((v) => v[1]) || []]));
|
|
290
|
+
});
|
|
298
291
|
/**
|
|
299
292
|
*
|
|
300
293
|
* @param {string} userId
|
|
@@ -302,17 +295,17 @@ hooks.listen(() => {
|
|
|
302
295
|
* @returns {Promise<boolean>}
|
|
303
296
|
*/
|
|
304
297
|
async function existUser(userId, login) {
|
|
305
|
-
for (const fn of existTesters) if (await fn(userId, login)) return true;
|
|
298
|
+
for (const fn of await existTesters$1) if (await fn(userId, login)) return true;
|
|
306
299
|
return false;
|
|
307
300
|
}
|
|
308
301
|
/**
|
|
309
302
|
*
|
|
310
|
-
* @returns {Promise<
|
|
303
|
+
* @returns {Promise<UserState>}
|
|
311
304
|
*/
|
|
312
305
|
async function getLoggedUser() {
|
|
313
306
|
const tenant = await useTenant();
|
|
314
307
|
if (tenant.single) {
|
|
315
|
-
for (const suGet of suGets) {
|
|
308
|
+
for (const suGet of await suGets) {
|
|
316
309
|
const suUser = await suGet();
|
|
317
310
|
if (!suUser) continue;
|
|
318
311
|
if (!await existUser(suUser)) continue;
|
|
@@ -338,7 +331,7 @@ async function getLoggedUser() {
|
|
|
338
331
|
let exitUser = null;
|
|
339
332
|
/** @type {string?} */
|
|
340
333
|
let user = null;
|
|
341
|
-
for (const [get, set, exit] of getLoggedUserFn) {
|
|
334
|
+
for (const [get, set, exit] of await getLoggedUserFn) {
|
|
342
335
|
const u = await get();
|
|
343
336
|
if (!u || !await existUser(u)) continue;
|
|
344
337
|
user = u;
|
|
@@ -348,16 +341,16 @@ async function getLoggedUser() {
|
|
|
348
341
|
}
|
|
349
342
|
if (!user) return [
|
|
350
343
|
null,
|
|
351
|
-
defaultLogin,
|
|
344
|
+
await defaultLogin$1,
|
|
352
345
|
null,
|
|
353
346
|
null,
|
|
354
347
|
null
|
|
355
348
|
];
|
|
356
|
-
for (const suGet of suGets) {
|
|
349
|
+
for (const suGet of await suGets) {
|
|
357
350
|
const suUser = await suGet();
|
|
358
351
|
if (!suUser) continue;
|
|
359
352
|
if (!await existUser(suUser)) continue;
|
|
360
|
-
if (await
|
|
353
|
+
if (await (await switchableListPromise)(tenant, user, suUser)) continue;
|
|
361
354
|
return [
|
|
362
355
|
null,
|
|
363
356
|
setUser,
|
|
@@ -374,7 +367,7 @@ async function getLoggedUser() {
|
|
|
374
367
|
null
|
|
375
368
|
];
|
|
376
369
|
}
|
|
377
|
-
async function get() {
|
|
370
|
+
async function get$1() {
|
|
378
371
|
let state = userGetter();
|
|
379
372
|
if (!state) {
|
|
380
373
|
state = getLoggedUser();
|
|
@@ -388,7 +381,7 @@ async function get() {
|
|
|
388
381
|
*/
|
|
389
382
|
function isSingleUser(logged) {
|
|
390
383
|
if (logged) return useTenant().then((g) => g.single);
|
|
391
|
-
return get().then(([, , , su]) => su ? false : useTenant().then((g) => g.single));
|
|
384
|
+
return get$1().then(([, , , su]) => su ? false : useTenant().then((g) => g.single));
|
|
392
385
|
}
|
|
393
386
|
/**
|
|
394
387
|
*
|
|
@@ -396,7 +389,7 @@ function isSingleUser(logged) {
|
|
|
396
389
|
* @returns {Promise<string?>}
|
|
397
390
|
*/
|
|
398
391
|
function getUser(logged) {
|
|
399
|
-
return get().then(([, , , current, su]) => {
|
|
392
|
+
return get$1().then(([, , , current, su]) => {
|
|
400
393
|
if (logged === false) return su;
|
|
401
394
|
if (logged) return current;
|
|
402
395
|
return su || current;
|
|
@@ -484,7 +477,7 @@ function setUser(userId, sudo) {
|
|
|
484
477
|
*/
|
|
485
478
|
async function findUser(loginName, loginType) {
|
|
486
479
|
const types = new Set([loginType || ""].flat().filter(Boolean));
|
|
487
|
-
for (const fn of finders) {
|
|
480
|
+
for (const fn of await finders$1) {
|
|
488
481
|
const userId = await fn(loginName, types);
|
|
489
482
|
if (userId) return userId;
|
|
490
483
|
}
|
|
@@ -499,6 +492,8 @@ async function findUser(loginName, loginType) {
|
|
|
499
492
|
* @returns {Promise<number>}
|
|
500
493
|
*/
|
|
501
494
|
async function verifyUser(userId, password, type, returnError) {
|
|
495
|
+
const verifiers = await verifiersPromise;
|
|
496
|
+
if (!Object.hasOwn(verifiers, type)) return 0;
|
|
502
497
|
for (const fn of verifiers[type] || []) {
|
|
503
498
|
const res = await fn(userId, password);
|
|
504
499
|
if (res < 0) return returnError ? res : 0;
|
|
@@ -515,13 +510,15 @@ async function verifyUser(userId, password, type, returnError) {
|
|
|
515
510
|
* @returns {Promise<boolean>}
|
|
516
511
|
*/
|
|
517
512
|
async function setUserVerify(userId, type, password, deadline) {
|
|
513
|
+
const setVerifiers = await setVerifiersPromise;
|
|
514
|
+
if (!Object.hasOwn(setVerifiers, type)) return false;
|
|
518
515
|
for (const fn of setVerifiers[type] || []) if (await fn(userId, password, deadline)) return true;
|
|
519
516
|
return false;
|
|
520
517
|
}
|
|
521
518
|
/** @type {(user?: string?) => Promise<Set<string>>} */
|
|
522
519
|
const loadUserPermissions = createKeyStore(async (user) => {
|
|
523
520
|
if (!user) return /* @__PURE__ */ new Set();
|
|
524
|
-
for (const f of getPermissions) {
|
|
521
|
+
for (const f of await getPermissions) {
|
|
525
522
|
const r = await f(user);
|
|
526
523
|
if (r) return new Set(r);
|
|
527
524
|
}
|
|
@@ -553,7 +550,7 @@ async function hasUserPermission(permission, logged) {
|
|
|
553
550
|
/** @type {(user?: string?) => Promise<Set<string>>} */
|
|
554
551
|
const loadUserOrganizationAllPermissions = createKeyStore(async (user) => {
|
|
555
552
|
if (!user) return /* @__PURE__ */ new Set();
|
|
556
|
-
for (const f of getOrganizationAllPermissions) {
|
|
553
|
+
for (const f of await getOrganizationAllPermissions) {
|
|
557
554
|
const r = await f(user);
|
|
558
555
|
if (r) return new Set(r);
|
|
559
556
|
}
|
|
@@ -576,7 +573,7 @@ async function getUserOrganizationAllPermissions(logged) {
|
|
|
576
573
|
/** @type {(user?: string?) => Promise<Record<string, Set<string>>>} */
|
|
577
574
|
const loadUserOrganizationPermissions = createKeyStore(async (user) => {
|
|
578
575
|
if (!user) return Object.create(null);
|
|
579
|
-
for (const f of getOrganizationPermissions) {
|
|
576
|
+
for (const f of await getOrganizationPermissions) {
|
|
580
577
|
const r = await f(user);
|
|
581
578
|
if (r) return Object.assign(Object.create(null), Object.fromEntries(Object.entries(r).map(([k, v]) => [k, new Set(v)])));
|
|
582
579
|
}
|
|
@@ -631,13 +628,17 @@ async function hasUserOrganizationPermissions(permission, organization, logged)
|
|
|
631
628
|
if (!permission) return true;
|
|
632
629
|
return permissions.has(permission);
|
|
633
630
|
}
|
|
631
|
+
const userPluginLoaders = userManagerMap.lazyThen((list) => {
|
|
632
|
+
return list.map(([k, v]) => [k, v?.loadPlugin]).filter(([, v]) => typeof v === "function");
|
|
633
|
+
});
|
|
634
634
|
/**
|
|
635
635
|
*
|
|
636
636
|
* @param {string} userId
|
|
637
637
|
* @returns {Promise<Record<string, any>>}
|
|
638
638
|
*/
|
|
639
639
|
async function loadPluginUser(userId) {
|
|
640
|
-
const
|
|
640
|
+
const loaders = await userPluginLoaders;
|
|
641
|
+
const list2 = await Promise.all(loaders.map(([p, f]) => Promise.all([p, f(userId)])));
|
|
641
642
|
return Object.fromEntries(Object.entries(Object.groupBy(list2, ([k]) => k)).map(([k, l]) => {
|
|
642
643
|
return [k, Object.assign({}, ...l?.map((v) => v[1]) || [])];
|
|
643
644
|
}));
|
|
@@ -649,7 +650,7 @@ async function loadPluginUser(userId) {
|
|
|
649
650
|
*/
|
|
650
651
|
async function loadUser(userId, plugin = false) {
|
|
651
652
|
const [list, plugins, permissions, organizationPermissions] = await Promise.all([
|
|
652
|
-
Promise.all(loaders.map((f) => f(userId))),
|
|
653
|
+
loaders.then((loaders) => Promise.all(loaders.map((f) => f(userId)))),
|
|
653
654
|
plugin ? loadPluginUser(userId) : {},
|
|
654
655
|
loadUserPermissions(userId).then((p) => [...p]),
|
|
655
656
|
loadUserOrganizationPermissions(userId).then((p) => Object.fromEntries(Object.entries(p).map(([k, v]) => [k, [...v]])))
|
|
@@ -662,6 +663,160 @@ async function loadUser(userId, plugin = false) {
|
|
|
662
663
|
});
|
|
663
664
|
}
|
|
664
665
|
|
|
666
|
+
//#endregion
|
|
667
|
+
//#region packages/core/visitor.mjs
|
|
668
|
+
/** @import { VisitorManager } from './types.mjs' */
|
|
669
|
+
/**
|
|
670
|
+
* @typedef {[result: string | null, VisitorManager['set'] | null, VisitorManager['exit'] | null, visitor: string | null]} VisitorState
|
|
671
|
+
*/
|
|
672
|
+
const [visitorGetter, visitorSetter] = createStoreSerializable("visitorStatus", async (state) => {
|
|
673
|
+
if (!state) return null;
|
|
674
|
+
return { visitor: (await state)[3] };
|
|
675
|
+
}, (val) => {
|
|
676
|
+
if (!val) return null;
|
|
677
|
+
const { visitor: visitorId } = val;
|
|
678
|
+
return Promise.resolve([
|
|
679
|
+
null,
|
|
680
|
+
null,
|
|
681
|
+
null,
|
|
682
|
+
visitorId
|
|
683
|
+
]);
|
|
684
|
+
}, null);
|
|
685
|
+
const visitors = LazyPromise.try(async function() {
|
|
686
|
+
return (await Array.fromAsync(loadPluginProfiles("visitor"))).map((v) => v[1]);
|
|
687
|
+
});
|
|
688
|
+
const existTesters = visitors.lazyThen((v) => v.map((v) => v.exist).filter((v) => typeof v === "function"));
|
|
689
|
+
/**
|
|
690
|
+
*
|
|
691
|
+
* @param {string} visitorId
|
|
692
|
+
* @returns {Promise<boolean>}
|
|
693
|
+
*/
|
|
694
|
+
async function existVisitor(visitorId) {
|
|
695
|
+
for (const fn of await existTesters) if (await fn(visitorId)) return true;
|
|
696
|
+
return false;
|
|
697
|
+
}
|
|
698
|
+
const getLoggedVisitorFn = visitors.lazyThen((list) => {
|
|
699
|
+
/** @type {[VisitorManager['get'], VisitorManager['set'] | null, VisitorManager['exit'] | null][]} */
|
|
700
|
+
const getLoggedVisitorFn = [];
|
|
701
|
+
for (const { get, set, exit } of list) {
|
|
702
|
+
if (typeof get !== "function") continue;
|
|
703
|
+
getLoggedVisitorFn.push([
|
|
704
|
+
get,
|
|
705
|
+
set || null,
|
|
706
|
+
exit || null
|
|
707
|
+
]);
|
|
708
|
+
}
|
|
709
|
+
return getLoggedVisitorFn;
|
|
710
|
+
});
|
|
711
|
+
const defaultLogin = visitors.lazyThen((v) => v.find((v) => typeof v.login === "function")?.login || null);
|
|
712
|
+
/**
|
|
713
|
+
*
|
|
714
|
+
* @returns {Promise<VisitorState>}
|
|
715
|
+
*/
|
|
716
|
+
async function getLoggedVisitor() {
|
|
717
|
+
/** @type {VisitorManager['set']?} */
|
|
718
|
+
let setVisitor = null;
|
|
719
|
+
/** @type {VisitorManager['exit']?} */
|
|
720
|
+
let exitVisitor = null;
|
|
721
|
+
/** @type {string?} */
|
|
722
|
+
let visitor = null;
|
|
723
|
+
for (const [get, set, exit] of await getLoggedVisitorFn) {
|
|
724
|
+
const u = await get();
|
|
725
|
+
if (!u || !await existVisitor(u)) continue;
|
|
726
|
+
visitor = u;
|
|
727
|
+
setVisitor = set;
|
|
728
|
+
exitVisitor = exit;
|
|
729
|
+
break;
|
|
730
|
+
}
|
|
731
|
+
if (!visitor) return [
|
|
732
|
+
null,
|
|
733
|
+
await defaultLogin,
|
|
734
|
+
null,
|
|
735
|
+
null
|
|
736
|
+
];
|
|
737
|
+
return [
|
|
738
|
+
null,
|
|
739
|
+
setVisitor,
|
|
740
|
+
exitVisitor,
|
|
741
|
+
visitor
|
|
742
|
+
];
|
|
743
|
+
}
|
|
744
|
+
async function get() {
|
|
745
|
+
let state = visitorGetter();
|
|
746
|
+
if (!state) {
|
|
747
|
+
state = getLoggedVisitor();
|
|
748
|
+
visitorSetter(state);
|
|
749
|
+
}
|
|
750
|
+
return state;
|
|
751
|
+
}
|
|
752
|
+
/**
|
|
753
|
+
*
|
|
754
|
+
* @returns {Promise<string?>}
|
|
755
|
+
*/
|
|
756
|
+
function getVisitor() {
|
|
757
|
+
return get().then(([, , , current]) => current);
|
|
758
|
+
}
|
|
759
|
+
/**
|
|
760
|
+
*
|
|
761
|
+
* @param {string?} visitorId
|
|
762
|
+
* @returns {Promise<string?>}
|
|
763
|
+
*/
|
|
764
|
+
function setVisitor(visitorId) {
|
|
765
|
+
let state = Promise.resolve(visitorGetter() || getLoggedVisitor());
|
|
766
|
+
state = state.then(async ([, set, exit, current]) => {
|
|
767
|
+
if (!visitorId) {
|
|
768
|
+
if (current && exit) await exit(current);
|
|
769
|
+
return [
|
|
770
|
+
null,
|
|
771
|
+
set,
|
|
772
|
+
exit,
|
|
773
|
+
null
|
|
774
|
+
];
|
|
775
|
+
}
|
|
776
|
+
if (!set) return [
|
|
777
|
+
current,
|
|
778
|
+
set,
|
|
779
|
+
exit,
|
|
780
|
+
current
|
|
781
|
+
];
|
|
782
|
+
if (!await set(visitorId)) return [
|
|
783
|
+
null,
|
|
784
|
+
set,
|
|
785
|
+
exit,
|
|
786
|
+
current
|
|
787
|
+
];
|
|
788
|
+
return [
|
|
789
|
+
visitorId,
|
|
790
|
+
set,
|
|
791
|
+
exit,
|
|
792
|
+
visitorId
|
|
793
|
+
];
|
|
794
|
+
});
|
|
795
|
+
visitorSetter(state);
|
|
796
|
+
return state.then((v) => v[0]);
|
|
797
|
+
}
|
|
798
|
+
const finders = visitors.lazyThen((v) => v.map((v) => v.find).filter((v) => typeof v === "function"));
|
|
799
|
+
/**
|
|
800
|
+
*
|
|
801
|
+
* @param {Record<string, unknown>} loginName
|
|
802
|
+
* @returns {Promise<string>}
|
|
803
|
+
*/
|
|
804
|
+
async function findVisitor(loginName) {
|
|
805
|
+
for (const fn of await finders) {
|
|
806
|
+
const visitorId = await fn(loginName);
|
|
807
|
+
if (visitorId) return visitorId;
|
|
808
|
+
}
|
|
809
|
+
return "";
|
|
810
|
+
}
|
|
811
|
+
/**
|
|
812
|
+
*
|
|
813
|
+
* @param {string} visitorId
|
|
814
|
+
* @returns {Promise<Record<string, any>>}
|
|
815
|
+
*/
|
|
816
|
+
async function loadVisitor(visitorId) {
|
|
817
|
+
return { id: visitorId };
|
|
818
|
+
}
|
|
819
|
+
|
|
665
820
|
//#endregion
|
|
666
821
|
//#region packages/core/permission/createPermissionMatches.mjs
|
|
667
822
|
/** @import { Permission } from '@yongdall/types' */
|
|
@@ -957,7 +1112,6 @@ async function filterPermissionUpdate({ fields }, permissions, document, newDocu
|
|
|
957
1112
|
* @returns
|
|
958
1113
|
*/
|
|
959
1114
|
async function testPermissions(allPermissions, document) {
|
|
960
|
-
if (await isSingleUser()) return true;
|
|
961
1115
|
if (!allPermissions?.length) return false;
|
|
962
1116
|
const permissionInGlobal = allPermissions.filter((v) => !v.organizationField);
|
|
963
1117
|
const permissionInOrganization = allPermissions.filter((v) => v.organizationField);
|
|
@@ -1010,18 +1164,21 @@ async function testPermissions(allPermissions, document) {
|
|
|
1010
1164
|
//#endregion
|
|
1011
1165
|
//#region packages/core/decorators/modelHook.mjs
|
|
1012
1166
|
/** @import { Hooks, ClassDecorator } from '@yongdall/model' */
|
|
1013
|
-
/** @
|
|
1014
|
-
|
|
1167
|
+
/** @import { ModelProfile } from '../types.mjs' */
|
|
1168
|
+
const modelHooksPromise = LazyPromise.try(async function() {
|
|
1015
1169
|
/** @returns {{[K in keyof Hooks]: Record<string, Hooks[K][]>}} */
|
|
1016
1170
|
const modelHooks = Object.create(null);
|
|
1017
|
-
|
|
1171
|
+
const list = await Array.fromAsync(loadPluginProfiles("model", function* ({ modelHook }) {
|
|
1172
|
+
if (!modelHook || typeof modelHook !== "object" || Array.isArray(modelHook)) return;
|
|
1173
|
+
yield* Object.entries(modelHook);
|
|
1174
|
+
}));
|
|
1175
|
+
for (const [model, v] of Object.entries(list)) for (const [name, fn] of Object.entries(v)) {
|
|
1018
1176
|
if (typeof fn !== "function") continue;
|
|
1019
1177
|
const list = modelHooks[name] ||= Object.create(null);
|
|
1020
1178
|
(list[model] ||= []).push(fn);
|
|
1021
1179
|
}
|
|
1022
1180
|
return modelHooks;
|
|
1023
|
-
}
|
|
1024
|
-
const modelHooks = loadHooks();
|
|
1181
|
+
});
|
|
1025
1182
|
/**
|
|
1026
1183
|
*
|
|
1027
1184
|
* @param {Partial<Hooks>} hooks
|
|
@@ -1035,6 +1192,7 @@ function bindModelHooks({ where, beforeCreateMany, afterCreateMany, beforeCreate
|
|
|
1035
1192
|
where: where || (() => {}),
|
|
1036
1193
|
async beforeCreateMany(conn, model, record) {
|
|
1037
1194
|
let data = record;
|
|
1195
|
+
const modelHooks = await modelHooksPromise;
|
|
1038
1196
|
for (const name of names) for (const hook of modelHooks.beforeCreateMany[name] || []) {
|
|
1039
1197
|
if (typeof hook !== "function") continue;
|
|
1040
1198
|
data = await hook(conn, model, data) || data;
|
|
@@ -1044,6 +1202,7 @@ function bindModelHooks({ where, beforeCreateMany, afterCreateMany, beforeCreate
|
|
|
1044
1202
|
},
|
|
1045
1203
|
async afterCreateMany(conn, model, record) {
|
|
1046
1204
|
if (typeof afterCreateMany === "function") await afterCreateMany(conn, model, record);
|
|
1205
|
+
const modelHooks = await modelHooksPromise;
|
|
1047
1206
|
for (const name of names) for (const hook of modelHooks.afterCreateMany[name] || []) {
|
|
1048
1207
|
if (typeof hook !== "function") continue;
|
|
1049
1208
|
await hook(conn, model, record);
|
|
@@ -1051,6 +1210,7 @@ function bindModelHooks({ where, beforeCreateMany, afterCreateMany, beforeCreate
|
|
|
1051
1210
|
},
|
|
1052
1211
|
async beforeCreate(conn, model, record) {
|
|
1053
1212
|
let data = record;
|
|
1213
|
+
const modelHooks = await modelHooksPromise;
|
|
1054
1214
|
for (const name of names) for (const hook of modelHooks.beforeCreate[name] || []) {
|
|
1055
1215
|
if (typeof hook !== "function") continue;
|
|
1056
1216
|
data = await hook(conn, model, data) || data;
|
|
@@ -1060,6 +1220,7 @@ function bindModelHooks({ where, beforeCreateMany, afterCreateMany, beforeCreate
|
|
|
1060
1220
|
},
|
|
1061
1221
|
async afterCreate(conn, model, record) {
|
|
1062
1222
|
if (typeof afterCreate === "function") await afterCreate(conn, model, record);
|
|
1223
|
+
const modelHooks = await modelHooksPromise;
|
|
1063
1224
|
for (const name of names) for (const hook of modelHooks.afterCreate[name] || []) {
|
|
1064
1225
|
if (typeof hook !== "function") continue;
|
|
1065
1226
|
await hook(conn, model, record);
|
|
@@ -1067,6 +1228,7 @@ function bindModelHooks({ where, beforeCreateMany, afterCreateMany, beforeCreate
|
|
|
1067
1228
|
},
|
|
1068
1229
|
async beforeUpdate(conn, model, record, set) {
|
|
1069
1230
|
let data = set;
|
|
1231
|
+
const modelHooks = await modelHooksPromise;
|
|
1070
1232
|
for (const name of names) for (const hook of modelHooks.beforeUpdate[name] || []) {
|
|
1071
1233
|
if (typeof hook !== "function") continue;
|
|
1072
1234
|
data = await hook(conn, model, record, data) || data;
|
|
@@ -1076,12 +1238,14 @@ function bindModelHooks({ where, beforeCreateMany, afterCreateMany, beforeCreate
|
|
|
1076
1238
|
},
|
|
1077
1239
|
async afterUpdate(conn, model, record, oldRecord) {
|
|
1078
1240
|
if (typeof afterUpdate === "function") await afterUpdate(conn, model, record, oldRecord);
|
|
1241
|
+
const modelHooks = await modelHooksPromise;
|
|
1079
1242
|
for (const name of names) for (const hook of modelHooks.afterUpdate[name] || []) {
|
|
1080
1243
|
if (typeof hook !== "function") continue;
|
|
1081
1244
|
await hook(conn, model, record, oldRecord);
|
|
1082
1245
|
}
|
|
1083
1246
|
},
|
|
1084
1247
|
async beforeDelete(conn, model, record, update) {
|
|
1248
|
+
const modelHooks = await modelHooksPromise;
|
|
1085
1249
|
for (const name of names) for (const hook of modelHooks.beforeDelete[name] || []) {
|
|
1086
1250
|
if (typeof hook !== "function") continue;
|
|
1087
1251
|
await hook(conn, model, record, update);
|
|
@@ -1090,6 +1254,7 @@ function bindModelHooks({ where, beforeCreateMany, afterCreateMany, beforeCreate
|
|
|
1090
1254
|
},
|
|
1091
1255
|
async afterDelete(conn, model, record, update) {
|
|
1092
1256
|
if (typeof afterDelete === "function") await afterDelete(conn, model, record, update);
|
|
1257
|
+
const modelHooks = await modelHooksPromise;
|
|
1093
1258
|
for (const name of names) for (const hook of modelHooks.afterDelete[name] || []) {
|
|
1094
1259
|
if (typeof hook !== "function") continue;
|
|
1095
1260
|
await hook(conn, model, record, update);
|
|
@@ -1109,6 +1274,7 @@ function modelHook(...hookNames) {
|
|
|
1109
1274
|
if (!names.length) return;
|
|
1110
1275
|
beforeCreateMany(Model, async (conn, model, record) => {
|
|
1111
1276
|
let data = record;
|
|
1277
|
+
const modelHooks = await modelHooksPromise;
|
|
1112
1278
|
for (const name of names) for (const hook of modelHooks.beforeCreateMany[name] || []) {
|
|
1113
1279
|
if (typeof hook !== "function") continue;
|
|
1114
1280
|
data = await hook(conn, model, data) || data;
|
|
@@ -1116,6 +1282,7 @@ function modelHook(...hookNames) {
|
|
|
1116
1282
|
return data;
|
|
1117
1283
|
});
|
|
1118
1284
|
afterCreateMany(Model, async (conn, model, record) => {
|
|
1285
|
+
const modelHooks = await modelHooksPromise;
|
|
1119
1286
|
for (const name of names) for (const hook of modelHooks.afterCreateMany[name] || []) {
|
|
1120
1287
|
if (typeof hook !== "function") continue;
|
|
1121
1288
|
await hook(conn, model, record);
|
|
@@ -1123,6 +1290,7 @@ function modelHook(...hookNames) {
|
|
|
1123
1290
|
});
|
|
1124
1291
|
beforeCreate(Model, async (conn, model, record) => {
|
|
1125
1292
|
let data = record;
|
|
1293
|
+
const modelHooks = await modelHooksPromise;
|
|
1126
1294
|
for (const name of names) for (const hook of modelHooks.beforeCreate[name] || []) {
|
|
1127
1295
|
if (typeof hook !== "function") continue;
|
|
1128
1296
|
data = await hook(conn, model, data) || data;
|
|
@@ -1130,6 +1298,7 @@ function modelHook(...hookNames) {
|
|
|
1130
1298
|
return data;
|
|
1131
1299
|
});
|
|
1132
1300
|
afterCreate(Model, async (conn, model, record) => {
|
|
1301
|
+
const modelHooks = await modelHooksPromise;
|
|
1133
1302
|
for (const name of names) for (const hook of modelHooks.afterCreate[name] || []) {
|
|
1134
1303
|
if (typeof hook !== "function") continue;
|
|
1135
1304
|
await hook(conn, model, record);
|
|
@@ -1137,6 +1306,7 @@ function modelHook(...hookNames) {
|
|
|
1137
1306
|
});
|
|
1138
1307
|
beforeUpdate(Model, async (conn, model, record, set) => {
|
|
1139
1308
|
let data = set;
|
|
1309
|
+
const modelHooks = await modelHooksPromise;
|
|
1140
1310
|
for (const name of names) for (const hook of modelHooks.beforeUpdate[name] || []) {
|
|
1141
1311
|
if (typeof hook !== "function") continue;
|
|
1142
1312
|
data = await hook(conn, model, record, data) || data;
|
|
@@ -1144,18 +1314,21 @@ function modelHook(...hookNames) {
|
|
|
1144
1314
|
return data;
|
|
1145
1315
|
});
|
|
1146
1316
|
afterUpdate(Model, async (conn, model, record, oldRecord) => {
|
|
1317
|
+
const modelHooks = await modelHooksPromise;
|
|
1147
1318
|
for (const name of names) for (const hook of modelHooks.afterUpdate[name] || []) {
|
|
1148
1319
|
if (typeof hook !== "function") continue;
|
|
1149
1320
|
await hook(conn, model, record, oldRecord);
|
|
1150
1321
|
}
|
|
1151
1322
|
});
|
|
1152
1323
|
beforeDelete(Model, async (conn, model, record, update) => {
|
|
1324
|
+
const modelHooks = await modelHooksPromise;
|
|
1153
1325
|
for (const name of names) for (const hook of modelHooks.beforeDelete[name] || []) {
|
|
1154
1326
|
if (typeof hook !== "function") continue;
|
|
1155
1327
|
await hook(conn, model, record, update);
|
|
1156
1328
|
}
|
|
1157
1329
|
});
|
|
1158
1330
|
afterDelete(Model, async (conn, model, record, update) => {
|
|
1331
|
+
const modelHooks = await modelHooksPromise;
|
|
1159
1332
|
for (const name of names) for (const hook of modelHooks.afterDelete[name] || []) {
|
|
1160
1333
|
if (typeof hook !== "function") continue;
|
|
1161
1334
|
await hook(conn, model, record, update);
|
|
@@ -1168,14 +1341,17 @@ function modelHook(...hookNames) {
|
|
|
1168
1341
|
//#region packages/core/ServerError.mjs
|
|
1169
1342
|
var ServerError = class extends Error {
|
|
1170
1343
|
status = 500;
|
|
1344
|
+
code = "";
|
|
1171
1345
|
/**
|
|
1172
1346
|
*
|
|
1173
|
-
* @param {string} message
|
|
1347
|
+
* @param {string | {code?: string; message: string; status?: number}} message
|
|
1174
1348
|
* @param {number} [status]
|
|
1175
1349
|
*/
|
|
1176
1350
|
constructor(message, status = 500) {
|
|
1177
|
-
super(message);
|
|
1178
|
-
|
|
1351
|
+
super(typeof message === "string" ? message : message.message);
|
|
1352
|
+
const s = typeof message === "object" && message.status || status;
|
|
1353
|
+
this.status = s;
|
|
1354
|
+
this.code = typeof message === "object" && message.code || String(s);
|
|
1179
1355
|
}
|
|
1180
1356
|
};
|
|
1181
1357
|
|
|
@@ -1360,20 +1536,24 @@ function toDocumentFields(fields) {
|
|
|
1360
1536
|
//#endregion
|
|
1361
1537
|
//#region packages/core/enumerations.mjs
|
|
1362
1538
|
/** @import { MaybePromise } from './types.mjs' */
|
|
1363
|
-
/** @type {Record<string, (Record<string, any> | (() => MaybePromise<Record<string, any>[]>))[]
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1539
|
+
/** @type {Promise<Record<string, (Record<string, any> | (() => MaybePromise<Record<string, any>[]>))[]>>} */
|
|
1540
|
+
const enumerationsPromise = LazyPromise.try(async function() {
|
|
1541
|
+
const list = await Array.fromAsync(loadPluginProfiles("enumeration", function* (c) {
|
|
1542
|
+
yield* c && typeof c === "object" && !Array.isArray(c) ? Object.entries(c) : [];
|
|
1543
|
+
}));
|
|
1544
|
+
const groups = Object.groupBy(list, ([k]) => k);
|
|
1545
|
+
return Object.fromEntries(Object.entries(groups).map(([k, v]) => [k, v?.map((v) => v[1]).flat(2) || []]));
|
|
1546
|
+
});
|
|
1369
1547
|
/**
|
|
1370
1548
|
*
|
|
1371
1549
|
* @param {string} name
|
|
1372
1550
|
* @returns {Promise<Record<string, any>[]>}
|
|
1373
1551
|
*/
|
|
1374
1552
|
async function getEnumerations(name) {
|
|
1375
|
-
|
|
1376
|
-
|
|
1553
|
+
const allEnumerations = await enumerationsPromise;
|
|
1554
|
+
if (!Object.hasOwn(allEnumerations, name)) return [];
|
|
1555
|
+
const enumerations = allEnumerations[name].map((v) => typeof v === "function" ? v() : v);
|
|
1556
|
+
return await Promise.all(enumerations).then((v) => v.flat());
|
|
1377
1557
|
}
|
|
1378
1558
|
|
|
1379
1559
|
//#endregion
|
|
@@ -1734,6 +1914,39 @@ async function search2where(fields, and, or, or2) {
|
|
|
1734
1914
|
}, fields, and, or, or2), execWhere, null);
|
|
1735
1915
|
}
|
|
1736
1916
|
|
|
1917
|
+
//#endregion
|
|
1918
|
+
//#region packages/core/safe.mjs
|
|
1919
|
+
/**
|
|
1920
|
+
* 使用 HMAC-SHA256 对一个或多个值进行哈希,使用 salt 作为密钥。
|
|
1921
|
+
* 输出为 base64url 格式。
|
|
1922
|
+
*
|
|
1923
|
+
* @param {string | ArrayBuffer | ArrayBufferView<ArrayBuffer>} salt
|
|
1924
|
+
* @param {string | number} value
|
|
1925
|
+
* @param {...(string | number)} values
|
|
1926
|
+
* @returns {Promise<string>}
|
|
1927
|
+
*/
|
|
1928
|
+
async function hashSHA256(salt, value, ...values) {
|
|
1929
|
+
/** @type {ArrayBuffer | ArrayBufferView<ArrayBuffer>} */
|
|
1930
|
+
let keyBuffer;
|
|
1931
|
+
if (salt instanceof ArrayBuffer || ArrayBuffer.isView(salt)) keyBuffer = salt;
|
|
1932
|
+
else if (typeof salt === "string") keyBuffer = new TextEncoder().encode(salt);
|
|
1933
|
+
else throw new Error("`salt` 参数必须为字符串或 Uint8Array");
|
|
1934
|
+
const cryptoKey = await crypto.subtle.importKey("raw", keyBuffer, {
|
|
1935
|
+
name: "HMAC",
|
|
1936
|
+
hash: "SHA-256"
|
|
1937
|
+
}, false, ["sign"]);
|
|
1938
|
+
/** @type {string[]} */
|
|
1939
|
+
let data = [];
|
|
1940
|
+
if (typeof value === "number") data.push(String(value));
|
|
1941
|
+
else if (typeof value === "string") data.push(JSON.stringify(value).slice(1, -1));
|
|
1942
|
+
else throw new Error("`value` 参数必须为字符串或数字");
|
|
1943
|
+
for (const v of values) if (typeof v === "number") data.push(String(v));
|
|
1944
|
+
else if (typeof v === "string") data.push(JSON.stringify(v).slice(1, -1));
|
|
1945
|
+
const messageBuffer = new TextEncoder().encode(data.join("\n"));
|
|
1946
|
+
const signature = await crypto.subtle.sign("HMAC", cryptoKey, messageBuffer);
|
|
1947
|
+
return btoa(String.fromCharCode(...new Uint8Array(signature))).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
|
|
1948
|
+
}
|
|
1949
|
+
|
|
1737
1950
|
//#endregion
|
|
1738
1951
|
//#region packages/core/index.mjs
|
|
1739
1952
|
/**
|
|
@@ -1749,5 +1962,5 @@ function initSystem(tenant, boot, pluginHooks) {
|
|
|
1749
1962
|
}
|
|
1750
1963
|
|
|
1751
1964
|
//#endregion
|
|
1752
|
-
export { ServerError, bindModelHooks, bootConfiguration, createPermissionMatches, initSystem as default, existUser, filterPermissionDocument, filterPermissionUpdate, filterPermissions, findModel, findUser, getEnumerations, getMenus, getModel, getModelAuthorizationPermissions, getModelPermissions, getUser, getUserOrganizationAllPermissions, getUserOrganizationPermissions, getUserPermissions, hasUserOrganizationPermissions, hasUserPermission, hooks, initConfig, isSingleUser, loadPluginUser, loadUser, loadUserOrganizationAllPermissions, loadUserOrganizationPermissions, loadUserPermissions, mainTenant, modelHook,
|
|
1965
|
+
export { ServerError, bindModelHooks, bootConfiguration, createPermissionMatches, initSystem as default, existUser, existVisitor, filterPermissionDocument, filterPermissionUpdate, filterPermissions, findModel, findUser, findVisitor, getEnumerations, getMenus, getModel, getModelAuthorizationPermissions, getModelPermissions, getUser, getUserOrganizationAllPermissions, getUserOrganizationPermissions, getUserPermissions, getVisitor, hasUserOrganizationPermissions, hasUserPermission, hashSHA256, hooks, initConfig, isSingleUser, loadPluginUser, loadUser, loadUserOrganizationAllPermissions, loadUserOrganizationPermissions, loadUserPermissions, loadVisitor, mainTenant, modelHook, nestedSetTree, search2where, setUser, setUserVerify, setVisitor, testPermissionConstraints, testPermissions, toDocumentFields, useTenant, verifyUser };
|
|
1753
1966
|
//# sourceMappingURL=index.mjs.map
|