querysub 0.469.0 → 0.471.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/package.json +2 -2
- package/src/-c-identity/IdentityController.ts +6 -1
- package/src/2-proxy/PathValueProxyWatcher.ts +1 -1
- package/src/3-path-functions/syncSchema.ts +2 -2
- package/src/4-dom/qreactTest.tsx +8 -1
- package/src/diagnostics/logs/IndexedLogs/LogViewer3.tsx +7 -3
- package/src/diagnostics/logs/diskLogGlobalContext.ts +7 -0
- package/src/library-components/URLParam.ts +1 -0
- package/src/user-implementation/userData.ts +119 -5
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "querysub",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.471.0",
|
|
4
4
|
"main": "index.js",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"note1": "note on node-forge fork, see https://github.com/digitalbazaar/forge/issues/744 for details",
|
|
@@ -66,7 +66,7 @@
|
|
|
66
66
|
"node-forge": "https://github.com/sliftist/forge#e618181b469b07bdc70b968b0391beb8ef5fecd6",
|
|
67
67
|
"pako": "^2.1.0",
|
|
68
68
|
"peggy": "^5.0.6",
|
|
69
|
-
"socket-function": "^1.1.
|
|
69
|
+
"socket-function": "^1.1.35",
|
|
70
70
|
"terser": "^5.31.0",
|
|
71
71
|
"typesafecss": "^0.29.0",
|
|
72
72
|
"yaml": "^2.5.0",
|
|
@@ -54,7 +54,12 @@ export function IdentityController_getReconnectNodeIdAssert(callerContext: Calle
|
|
|
54
54
|
return callerContext.nodeId;
|
|
55
55
|
}
|
|
56
56
|
let reconnectId = IdentityController_getReconnectNodeId(callerContext);
|
|
57
|
-
if (!reconnectId)
|
|
57
|
+
if (!reconnectId) {
|
|
58
|
+
console.error(`Caller did not mount before connecting. This call requires the caller to be listening.`, {
|
|
59
|
+
callerNodeId: callerContext.nodeId,
|
|
60
|
+
});
|
|
61
|
+
throw new Error(`Caller did not mount before connecting. This call requires the caller to be listening.`);
|
|
62
|
+
}
|
|
58
63
|
return reconnectId;
|
|
59
64
|
}
|
|
60
65
|
export function IdentityController_getSecureIP(callerContext: CallerContext): string {
|
|
@@ -1664,7 +1664,7 @@ export class PathValueProxyWatcher {
|
|
|
1664
1664
|
|
|
1665
1665
|
let maxLocks = watcher.options.maxLocksOverride || DEFAULT_MAX_LOCKS;
|
|
1666
1666
|
if (locks.length > maxLocks) {
|
|
1667
|
-
throw new Error(`Too many locks for ${watcher.debugName} (${locks.length} > ${maxLocks}). Use Querysub.noLocks(() => ...) around code that is accessing too many values, assuming you don't want to lock them. You can override max locks with maxLocksOverride (in options / functionMetadata).`);
|
|
1667
|
+
throw new Error(`Too many locks for ${watcher.debugName} (${locks.length} > ${maxLocks}). Use Querysub.noLocks(() => ...) around code that is accessing too many values, assuming you don't want to lock them. You can override max locks with maxLocksOverride (in options / functionMetadata). Some locks are ${JSON.stringify(locks.slice(0, 3).map(x => ({ path: x.path, startTime: x.startTime, endTime: x.endTime })))}.`);
|
|
1668
1668
|
}
|
|
1669
1669
|
|
|
1670
1670
|
|
|
@@ -58,7 +58,7 @@ export type FunctionMetadata<Schema = unknown, F = unknown> = {
|
|
|
58
58
|
// NOTE: Eventually we might want to support dynamic paths per call, so we can supported nested lookups.
|
|
59
59
|
// - We also need to support specifying on the lookup that the key is in the nested lookup, which means hashing has to support wildcards, etc. All-in-all the whole change is very complicated, and only needed for hypothetical cases (data().worlds[region][id]...), which could probably be flattened anyways to just a single lookup (data().worlds[region + "-" + id]...)
|
|
60
60
|
/** This should identify the most common lookup accessed, and then give the path to that lookup and the key that we're using to access it. */
|
|
61
|
-
keyOverride
|
|
61
|
+
keyOverride: {
|
|
62
62
|
getPrefix: (data: () => Schema) => unknown;
|
|
63
63
|
getKey: (...args: Args<F>) => string;
|
|
64
64
|
};
|
|
@@ -275,7 +275,7 @@ type SyncSchemaResult<Schema> = {
|
|
|
275
275
|
moduleId: string;
|
|
276
276
|
module: NodeJS.Module;
|
|
277
277
|
functions: Functions;
|
|
278
|
-
functionMetadata
|
|
278
|
+
functionMetadata: { [name in keyof Functions]: FunctionMetadata<Schema, Functions[name]> };
|
|
279
279
|
/** Provide access to [Querysub.CALL_PERMISSIONS_KEY] to allow function calls (or provide access at the root). */
|
|
280
280
|
permissions?: SchemaToPermissions<Schema> & {
|
|
281
281
|
[CALL_PERMISSIONS_KEY]?: {
|
package/src/4-dom/qreactTest.tsx
CHANGED
|
@@ -326,7 +326,14 @@ let { data, functions } = Querysub.createSchema<{
|
|
|
326
326
|
},
|
|
327
327
|
module,
|
|
328
328
|
moduleId: "qreactTest",
|
|
329
|
-
functionMetadata: {
|
|
329
|
+
functionMetadata: {
|
|
330
|
+
setValue: {
|
|
331
|
+
keyOverride: {
|
|
332
|
+
getPrefix: data => data().values,
|
|
333
|
+
getKey: (key: string) => key,
|
|
334
|
+
},
|
|
335
|
+
},
|
|
336
|
+
},
|
|
330
337
|
permissions: {
|
|
331
338
|
PERMISSIONS: isSuperUserPERMISSIONS
|
|
332
339
|
}
|
|
@@ -95,9 +95,13 @@ export class LogViewer3 extends qreact.Component {
|
|
|
95
95
|
getPaths(): TimeFilePathWithSize[] {
|
|
96
96
|
let paths: TimeFilePathWithSize[] = [];
|
|
97
97
|
if (savedPathsURL.value) {
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
98
|
+
try {
|
|
99
|
+
const compressed = Buffer.from(savedPathsURL.value, "base64");
|
|
100
|
+
const decompressed = Zip.gunzipSync(compressed);
|
|
101
|
+
paths = JSON.parse(decompressed.toString("utf8"));
|
|
102
|
+
} catch (e: any) {
|
|
103
|
+
console.warn(`Error parsing saved paths: ${e.stack}`);
|
|
104
|
+
}
|
|
101
105
|
} else {
|
|
102
106
|
paths = this.state.paths;
|
|
103
107
|
}
|
|
@@ -7,8 +7,14 @@ import { logErrors } from "../../errors";
|
|
|
7
7
|
import { addGlobalContext } from "./diskLogger";
|
|
8
8
|
import child_process from "child_process";
|
|
9
9
|
import { getNodeIdLocation } from "socket-function/src/nodeCache";
|
|
10
|
+
import { getGitRefLive } from "../../4-deploy/git";
|
|
10
11
|
|
|
11
12
|
export function addBuiltInContext() {
|
|
13
|
+
let __gitHash = "";
|
|
14
|
+
setImmediate(async () => {
|
|
15
|
+
__gitHash = await getGitRefLive();
|
|
16
|
+
});
|
|
17
|
+
|
|
12
18
|
addGlobalContext(() => {
|
|
13
19
|
let nodeId = getOwnNodeId();
|
|
14
20
|
let nodeParts = getNodeIdLocation(nodeId);
|
|
@@ -25,6 +31,7 @@ export function addBuiltInContext() {
|
|
|
25
31
|
__os: process.platform,
|
|
26
32
|
__pid: process.pid,
|
|
27
33
|
__call: SocketFunction.TOTAL_CALLS,
|
|
34
|
+
__gitHash: __gitHash,
|
|
28
35
|
};
|
|
29
36
|
});
|
|
30
37
|
const getHostname = lazy(() => child_process.execSync("hostname").toString().trim());
|
|
@@ -285,11 +285,125 @@ const { data, functions } = Querysub.syncSchema<{
|
|
|
285
285
|
functionMetadata: {
|
|
286
286
|
// There's no point to predict sending emails, or inviting users, or registering the page load time or sending discord messages, As the main function of these can only be done server-side.
|
|
287
287
|
// verifyMachineId is used when logging in with the login token. We could predict it, but there's no real reason to because if we do, all of our reads are gonna fail until it runs, Which will actually be really confusing to the user and look like a bug.
|
|
288
|
-
sendLoginEmail: {
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
288
|
+
sendLoginEmail: {
|
|
289
|
+
nopredict: true,
|
|
290
|
+
keyOverride: {
|
|
291
|
+
getPrefix: data => data().secure.emailToUserId,
|
|
292
|
+
getKey: config => config.email,
|
|
293
|
+
},
|
|
294
|
+
},
|
|
295
|
+
verifyMachineId: {
|
|
296
|
+
nopredict: true,
|
|
297
|
+
keyOverride: {
|
|
298
|
+
getPrefix: data => data().users,
|
|
299
|
+
getKey: config => config.loginToken.split("_")[1],
|
|
300
|
+
},
|
|
301
|
+
},
|
|
302
|
+
inviteUser: {
|
|
303
|
+
nopredict: true,
|
|
304
|
+
keyOverride: {
|
|
305
|
+
getPrefix: data => data().users,
|
|
306
|
+
getKey: () => getCurrentUserAssert(),
|
|
307
|
+
},
|
|
308
|
+
},
|
|
309
|
+
registerPageLoadTime: {
|
|
310
|
+
nopredict: true,
|
|
311
|
+
keyOverride: {
|
|
312
|
+
getPrefix: data => data().users,
|
|
313
|
+
getKey: () => getCurrentUser() ?? Querysub.getCallerMachineId(),
|
|
314
|
+
},
|
|
315
|
+
},
|
|
316
|
+
testSendDiscordMessage: {
|
|
317
|
+
nopredict: true,
|
|
318
|
+
keyOverride: {
|
|
319
|
+
getPrefix: data => data().secure,
|
|
320
|
+
getKey: () => "notifyDiscordWebhookURL",
|
|
321
|
+
},
|
|
322
|
+
},
|
|
323
|
+
updateSettings: {
|
|
324
|
+
keyOverride: {
|
|
325
|
+
getPrefix: data => data().users,
|
|
326
|
+
getKey: () => getCurrentUserAssert(),
|
|
327
|
+
},
|
|
328
|
+
},
|
|
329
|
+
logoutCurrent: {
|
|
330
|
+
keyOverride: {
|
|
331
|
+
getPrefix: data => data().users,
|
|
332
|
+
getKey: () => getCurrentUser() ?? Querysub.getCallerMachineId(),
|
|
333
|
+
},
|
|
334
|
+
},
|
|
335
|
+
logoutSpecific: {
|
|
336
|
+
keyOverride: {
|
|
337
|
+
getPrefix: data => data().users,
|
|
338
|
+
getKey: () => getCurrentUserAssert(),
|
|
339
|
+
},
|
|
340
|
+
},
|
|
341
|
+
removeLoginToken: {
|
|
342
|
+
keyOverride: {
|
|
343
|
+
getPrefix: data => data().users,
|
|
344
|
+
getKey: () => getCurrentUserAssert(),
|
|
345
|
+
},
|
|
346
|
+
},
|
|
347
|
+
specialResetLogins: {
|
|
348
|
+
keyOverride: {
|
|
349
|
+
getPrefix: data => data().users,
|
|
350
|
+
getKey: config => config.userId,
|
|
351
|
+
},
|
|
352
|
+
},
|
|
353
|
+
specialBlockIP: {
|
|
354
|
+
keyOverride: {
|
|
355
|
+
getPrefix: data => data().secure.blockedIPs,
|
|
356
|
+
getKey: config => config.ip,
|
|
357
|
+
},
|
|
358
|
+
},
|
|
359
|
+
specialUnblockIP: {
|
|
360
|
+
keyOverride: {
|
|
361
|
+
getPrefix: data => data().secure.blockedIPs,
|
|
362
|
+
getKey: config => config.ip,
|
|
363
|
+
},
|
|
364
|
+
},
|
|
365
|
+
specialSetInviteCount: {
|
|
366
|
+
keyOverride: {
|
|
367
|
+
getPrefix: data => data().users,
|
|
368
|
+
getKey: config => config.userId,
|
|
369
|
+
},
|
|
370
|
+
},
|
|
371
|
+
setPostmarkAPIKey: {
|
|
372
|
+
keyOverride: {
|
|
373
|
+
getPrefix: data => data().secure,
|
|
374
|
+
getKey: () => "postmarkAPIKey",
|
|
375
|
+
},
|
|
376
|
+
},
|
|
377
|
+
setNotifyDiscordWebhookURL: {
|
|
378
|
+
keyOverride: {
|
|
379
|
+
getPrefix: data => data().secure,
|
|
380
|
+
getKey: () => "notifyDiscordWebhookURL",
|
|
381
|
+
},
|
|
382
|
+
},
|
|
383
|
+
setOpenRouterAPIKey: {
|
|
384
|
+
keyOverride: {
|
|
385
|
+
getPrefix: data => data().secure,
|
|
386
|
+
getKey: () => "openRouterAPIKey",
|
|
387
|
+
},
|
|
388
|
+
},
|
|
389
|
+
specialSetUserType: {
|
|
390
|
+
keyOverride: {
|
|
391
|
+
getPrefix: data => data().users,
|
|
392
|
+
getKey: config => config.userId,
|
|
393
|
+
},
|
|
394
|
+
},
|
|
395
|
+
banUser: {
|
|
396
|
+
keyOverride: {
|
|
397
|
+
getPrefix: data => data().users,
|
|
398
|
+
getKey: config => config.userId,
|
|
399
|
+
},
|
|
400
|
+
},
|
|
401
|
+
unbanUser: {
|
|
402
|
+
keyOverride: {
|
|
403
|
+
getPrefix: data => data().users,
|
|
404
|
+
getKey: config => config.userId,
|
|
405
|
+
},
|
|
406
|
+
},
|
|
293
407
|
},
|
|
294
408
|
});
|
|
295
409
|
|