@peers-app/peers-sdk 0.19.14 → 0.20.1
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/contracts/__tests__/builder.test.js +24 -0
- package/dist/contracts/__tests__/contract-events.test.d.ts +1 -0
- package/dist/contracts/__tests__/contract-events.test.js +199 -0
- package/dist/contracts/__tests__/contract-observables.test.d.ts +1 -0
- package/dist/contracts/__tests__/contract-observables.test.js +290 -0
- package/dist/contracts/__tests__/contract-provider-router.test.d.ts +1 -0
- package/dist/contracts/__tests__/contract-provider-router.test.js +193 -0
- package/dist/contracts/__tests__/contract-proxy.test.d.ts +1 -0
- package/dist/contracts/__tests__/contract-proxy.test.js +424 -0
- package/dist/contracts/__tests__/contract-resolvers.test.d.ts +1 -0
- package/dist/contracts/__tests__/contract-resolvers.test.js +148 -0
- package/dist/contracts/__tests__/contract-subscription-lifecycle.test.d.ts +1 -0
- package/dist/contracts/__tests__/contract-subscription-lifecycle.test.js +353 -0
- package/dist/contracts/__tests__/contract-table-events.test.d.ts +1 -0
- package/dist/contracts/__tests__/contract-table-events.test.js +209 -0
- package/dist/contracts/__tests__/contract-transport.test.d.ts +1 -0
- package/dist/contracts/__tests__/contract-transport.test.js +163 -0
- package/dist/contracts/__tests__/persistent-registry.test.d.ts +1 -0
- package/dist/contracts/__tests__/persistent-registry.test.js +109 -0
- package/dist/contracts/__tests__/playground.test.d.ts +1 -0
- package/dist/contracts/__tests__/playground.test.js +213 -0
- package/dist/contracts/__tests__/validate.test.js +122 -0
- package/dist/contracts/builder.d.ts +9 -1
- package/dist/contracts/builder.js +13 -0
- package/dist/contracts/contract-provider-router.d.ts +72 -0
- package/dist/contracts/contract-provider-router.js +164 -0
- package/dist/contracts/contract-proxy.d.ts +333 -0
- package/dist/contracts/contract-proxy.js +663 -0
- package/dist/contracts/contract-resolvers.d.ts +66 -0
- package/dist/contracts/contract-resolvers.js +138 -0
- package/dist/contracts/contract-transport.d.ts +94 -0
- package/dist/contracts/contract-transport.js +159 -0
- package/dist/contracts/contracts.table.d.ts +1 -1
- package/dist/contracts/contracts.table.js +2 -2
- package/dist/contracts/index.d.ts +7 -1
- package/dist/contracts/index.js +34 -1
- package/dist/contracts/persistent-registry.js +3 -1
- package/dist/contracts/system/device-operations-contract.d.ts +72 -0
- package/dist/contracts/system/device-operations-contract.js +110 -0
- package/dist/contracts/system/logs-contract.d.ts +24 -0
- package/dist/contracts/system/logs-contract.js +60 -0
- package/dist/contracts/types.d.ts +27 -4
- package/dist/contracts/validate.d.ts +2 -2
- package/dist/contracts/validate.js +44 -2
- package/dist/data/assistants.d.ts +4 -4
- package/dist/data/channels.d.ts +1 -1
- package/dist/data/devices.d.ts +1 -1
- package/dist/data/embeddings.d.ts +1 -1
- package/dist/data/group-secret.d.ts +21 -0
- package/dist/data/group-secret.js +53 -0
- package/dist/data/index.d.ts +1 -0
- package/dist/data/index.js +1 -0
- package/dist/data/messages.d.ts +1 -1
- package/dist/data/orm/decorators.d.ts +6 -0
- package/dist/data/orm/decorators.js +21 -0
- package/dist/data/package-versions.d.ts +2 -2
- package/dist/data/peer-types.d.ts +1 -1
- package/dist/data/persistent-vars.d.ts +17 -0
- package/dist/data/persistent-vars.js +115 -35
- package/dist/data/persistent-vars.migration.test.d.ts +1 -0
- package/dist/data/persistent-vars.migration.test.js +133 -0
- package/dist/data/table-definitions-table.d.ts +1 -1
- package/dist/data/tool-tests.d.ts +1 -1
- package/dist/data/tools.d.ts +1 -1
- package/dist/data/user-trust-levels.d.ts +3 -1
- package/dist/data/user-trust-levels.js +2 -1
- package/dist/data/user-trust-levels.test.d.ts +1 -0
- package/dist/data/user-trust-levels.test.js +37 -0
- package/dist/data/voice-messages.d.ts +1 -1
- package/dist/data/workflow-logs.d.ts +1 -1
- package/dist/data/workflow-runs.d.ts +2 -2
- package/dist/data/workflows.d.ts +3 -3
- package/dist/device/binary-peer-connection-v2.d.ts +2 -0
- package/dist/device/binary-peer-connection-v2.js +12 -2
- package/dist/device/binary-peer-connection-v2.test.js +23 -0
- package/dist/device/get-trust-level-fn.d.ts +6 -0
- package/dist/device/get-trust-level-fn.js +12 -7
- package/dist/device/get-trust-level-fn.test.js +16 -2
- package/dist/logging/console-logs.table.d.ts +3 -0
- package/dist/logging/console-logs.table.js +2 -1
- package/dist/rpc-types.d.ts +37 -0
- package/dist/rpc-types.js +13 -0
- package/dist/system-ids.d.ts +25 -0
- package/dist/system-ids.js +26 -1
- package/dist/types/workflow.d.ts +4 -4
- package/package.json +1 -1
|
@@ -54,8 +54,8 @@ declare const schema: z.ZodObject<{
|
|
|
54
54
|
version: string;
|
|
55
55
|
signature: string;
|
|
56
56
|
packageId: string;
|
|
57
|
-
createdBy: string;
|
|
58
57
|
createdAt: string;
|
|
58
|
+
createdBy: string;
|
|
59
59
|
packageVersionId: string;
|
|
60
60
|
packageVersionHash: string;
|
|
61
61
|
packageBundleFileId: string;
|
|
@@ -82,8 +82,8 @@ declare const schema: z.ZodObject<{
|
|
|
82
82
|
version: string;
|
|
83
83
|
signature: string;
|
|
84
84
|
packageId: string;
|
|
85
|
-
createdBy: string;
|
|
86
85
|
createdAt: string;
|
|
86
|
+
createdBy: string;
|
|
87
87
|
packageVersionId: string;
|
|
88
88
|
packageVersionHash: string;
|
|
89
89
|
packageBundleFileId: string;
|
|
@@ -91,7 +91,7 @@ declare const valueTypeSchema: z.ZodObject<{
|
|
|
91
91
|
iconClass?: string | undefined;
|
|
92
92
|
}>;
|
|
93
93
|
export type IPeerType = z.infer<typeof valueTypeSchema>;
|
|
94
|
-
export declare function PeerTypes(dataContext?: DataContext): import("
|
|
94
|
+
export declare function PeerTypes(dataContext?: DataContext): import("..").Table<{
|
|
95
95
|
name: string;
|
|
96
96
|
schema: {
|
|
97
97
|
type: import("./tools").IOSchemaType;
|
|
@@ -52,20 +52,37 @@ declare const schema: z.ZodObject<{
|
|
|
52
52
|
modifiedAt?: number | undefined;
|
|
53
53
|
packageId?: string | undefined;
|
|
54
54
|
}>;
|
|
55
|
+
/** Table metadata for persisted observable variables. */
|
|
55
56
|
export declare const persistentVarsMetaData: ITableMetaData;
|
|
57
|
+
/** Stored record for one persistent variable. */
|
|
56
58
|
export type IPersistentVar = z.infer<typeof schema>;
|
|
59
|
+
/** Persistent-variable table with deterministic IDs and secret-value handling. */
|
|
57
60
|
export declare class PersistentVarsTable extends Table<IPersistentVar> {
|
|
61
|
+
/** Insert a persistent variable through the canonical save path. */
|
|
58
62
|
insert(persistentVar: IPersistentVar): Promise<IPersistentVar>;
|
|
63
|
+
/** Update a persistent variable through the canonical save path. */
|
|
59
64
|
update(persistentVar: IPersistentVar): Promise<IPersistentVar>;
|
|
65
|
+
/** Save a variable, assigning its deterministic ID and encrypting new secret plaintext. */
|
|
60
66
|
save(persistentVar: IPersistentVar, opts?: ISaveOptions): Promise<IPersistentVar>;
|
|
67
|
+
/**
|
|
68
|
+
* Replace a legacy random record ID without re-encrypting its already-stored value.
|
|
69
|
+
*
|
|
70
|
+
* Migration is storage-only: the value and modified timestamp are preserved. If the
|
|
71
|
+
* deterministic record already exists, it wins and the duplicate legacy row is removed.
|
|
72
|
+
*/
|
|
73
|
+
migrateLegacyId(persistentVar: IPersistentVar): Promise<IPersistentVar>;
|
|
74
|
+
/** Return a stored variable's raw value by name. */
|
|
61
75
|
getPersistentVarValue<T>(name: string): Promise<T | undefined>;
|
|
62
76
|
}
|
|
77
|
+
/** Return the persistent-variable table for a data context. */
|
|
63
78
|
export declare function PersistentVars(dataContext?: DataContext): PersistentVarsTable;
|
|
79
|
+
/** Reactive persistent value with an awaitable initial load and explicit deletion. */
|
|
64
80
|
export type PersistentVar<T> = Observable<T> & {
|
|
65
81
|
loadingPromise: Promise<PersistentVar<T>>;
|
|
66
82
|
/** Delete the persistent variable from the database and reset to default value */
|
|
67
83
|
delete: () => Promise<void>;
|
|
68
84
|
};
|
|
85
|
+
/** Resolve a persistent-variable record by name, preferring device scope. */
|
|
69
86
|
export declare function getPersistentVar(name: string, dataContext?: DataContext): Promise<IPersistentVar | undefined>;
|
|
70
87
|
interface IPersistentVarOptionsBase {
|
|
71
88
|
scope?: "device" | "user" | "group" | "groupDevice" | "groupUser";
|
|
@@ -5,6 +5,40 @@
|
|
|
5
5
|
* Tests for this module are located in peers-device/src/persistent-vars.test.ts
|
|
6
6
|
* (requires SQLite which is not available in peers-sdk)
|
|
7
7
|
*/
|
|
8
|
+
var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
|
|
9
|
+
var useValue = arguments.length > 2;
|
|
10
|
+
for (var i = 0; i < initializers.length; i++) {
|
|
11
|
+
value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
|
|
12
|
+
}
|
|
13
|
+
return useValue ? value : void 0;
|
|
14
|
+
};
|
|
15
|
+
var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
|
|
16
|
+
function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
|
|
17
|
+
var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
|
|
18
|
+
var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
|
|
19
|
+
var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
|
|
20
|
+
var _, done = false;
|
|
21
|
+
for (var i = decorators.length - 1; i >= 0; i--) {
|
|
22
|
+
var context = {};
|
|
23
|
+
for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
|
|
24
|
+
for (var p in contextIn.access) context.access[p] = contextIn.access[p];
|
|
25
|
+
context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
|
|
26
|
+
var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
|
|
27
|
+
if (kind === "accessor") {
|
|
28
|
+
if (result === void 0) continue;
|
|
29
|
+
if (result === null || typeof result !== "object") throw new TypeError("Object expected");
|
|
30
|
+
if (_ = accept(result.get)) descriptor.get = _;
|
|
31
|
+
if (_ = accept(result.set)) descriptor.set = _;
|
|
32
|
+
if (_ = accept(result.init)) initializers.unshift(_);
|
|
33
|
+
}
|
|
34
|
+
else if (_ = accept(result)) {
|
|
35
|
+
if (kind === "field") initializers.unshift(_);
|
|
36
|
+
else descriptor[key] = _;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
if (target) Object.defineProperty(target, contextIn.name, descriptor);
|
|
40
|
+
done = true;
|
|
41
|
+
};
|
|
8
42
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
43
|
exports.PersistentVarsTable = exports.persistentVarsMetaData = void 0;
|
|
10
44
|
exports.PersistentVars = PersistentVars;
|
|
@@ -21,6 +55,7 @@ const observable_1 = require("../observable");
|
|
|
21
55
|
const rpc_types_1 = require("../rpc-types");
|
|
22
56
|
const zod_types_1 = require("../types/zod-types");
|
|
23
57
|
const utils_1 = require("../utils");
|
|
58
|
+
const decorators_1 = require("./orm/decorators");
|
|
24
59
|
const table_1 = require("./orm/table");
|
|
25
60
|
const table_definitions_system_1 = require("./orm/table-definitions.system");
|
|
26
61
|
const types_1 = require("./orm/types");
|
|
@@ -44,6 +79,7 @@ const schema = zod_1.z.object({
|
|
|
44
79
|
.optional()
|
|
45
80
|
.describe("The package that owns this persistent variable, if any"),
|
|
46
81
|
});
|
|
82
|
+
/** Table metadata for persisted observable variables. */
|
|
47
83
|
exports.persistentVarsMetaData = {
|
|
48
84
|
name: "PersistentVars",
|
|
49
85
|
description: "table to persist variables across sessions and devices",
|
|
@@ -52,46 +88,93 @@ exports.persistentVarsMetaData = {
|
|
|
52
88
|
iconClassName: "bi bi-braces",
|
|
53
89
|
indexes: [{ fields: ["name"], unique: true }],
|
|
54
90
|
};
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
91
|
+
/** Persistent-variable table with deterministic IDs and secret-value handling. */
|
|
92
|
+
let PersistentVarsTable = (() => {
|
|
93
|
+
let _classSuper = table_1.Table;
|
|
94
|
+
let _instanceExtraInitializers = [];
|
|
95
|
+
let _migrateLegacyId_decorators;
|
|
96
|
+
return class PersistentVarsTable extends _classSuper {
|
|
97
|
+
static {
|
|
98
|
+
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
|
|
99
|
+
_migrateLegacyId_decorators = [(0, decorators_1.ProxyClientTableMethodCalls)()];
|
|
100
|
+
__esDecorate(this, null, _migrateLegacyId_decorators, { kind: "method", name: "migrateLegacyId", static: false, private: false, access: { has: obj => "migrateLegacyId" in obj, get: obj => obj.migrateLegacyId }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
101
|
+
if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
102
|
+
}
|
|
103
|
+
/** Insert a persistent variable through the canonical save path. */
|
|
104
|
+
async insert(persistentVar) {
|
|
105
|
+
return this.save(persistentVar);
|
|
106
|
+
}
|
|
107
|
+
/** Update a persistent variable through the canonical save path. */
|
|
108
|
+
async update(persistentVar) {
|
|
109
|
+
return this.save(persistentVar);
|
|
110
|
+
}
|
|
111
|
+
/** Save a variable, assigning its deterministic ID and encrypting new secret plaintext. */
|
|
112
|
+
async save(persistentVar, opts) {
|
|
113
|
+
if (!persistentVar.persistentVarId) {
|
|
114
|
+
persistentVar.persistentVarId = (0, utils_1.deterministicPvarId)(persistentVar.name);
|
|
115
|
+
}
|
|
116
|
+
const dbVar = await this.get(persistentVar.persistentVarId);
|
|
117
|
+
if (persistentVar.isSecret &&
|
|
118
|
+
persistentVar.value.value !== undefined &&
|
|
119
|
+
(!rpc_types_1.isClient || (0, rpc_types_1.isSingleProcessClient)())) {
|
|
120
|
+
if (!dbVar ||
|
|
121
|
+
dbVar.value.value !== persistentVar.value.value ||
|
|
122
|
+
dbVar.isSecret !== persistentVar.isSecret) {
|
|
123
|
+
persistentVar.value.value = await rpc_types_1.rpcServerCalls.encryptData(persistentVar.value.value || "", this.groupId);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
persistentVar.modifiedAt = Date.now();
|
|
127
|
+
opts ??= {};
|
|
128
|
+
opts = { saveAsSnapshot: true, ...opts };
|
|
129
|
+
return super.save(persistentVar, opts);
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Replace a legacy random record ID without re-encrypting its already-stored value.
|
|
133
|
+
*
|
|
134
|
+
* Migration is storage-only: the value and modified timestamp are preserved. If the
|
|
135
|
+
* deterministic record already exists, it wins and the duplicate legacy row is removed.
|
|
136
|
+
*/
|
|
137
|
+
async migrateLegacyId(persistentVar) {
|
|
138
|
+
if ((0, utils_1.isDeterministicPvarId)(persistentVar.persistentVarId)) {
|
|
139
|
+
return persistentVar;
|
|
140
|
+
}
|
|
141
|
+
const deterministicId = (0, utils_1.deterministicPvarId)(persistentVar.name);
|
|
142
|
+
const existing = await this.get(deterministicId);
|
|
143
|
+
await super.delete(persistentVar);
|
|
144
|
+
if (existing) {
|
|
145
|
+
return existing;
|
|
146
|
+
}
|
|
147
|
+
const migrated = { ...persistentVar, persistentVarId: deterministicId };
|
|
148
|
+
try {
|
|
149
|
+
return await super.save(migrated, { saveAsSnapshot: true });
|
|
150
|
+
}
|
|
151
|
+
catch (error) {
|
|
152
|
+
await super.save(persistentVar, { saveAsSnapshot: true }).catch(() => { });
|
|
153
|
+
throw error;
|
|
154
|
+
}
|
|
65
155
|
}
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
(
|
|
70
|
-
|
|
71
|
-
dbVar.value.value !== persistentVar.value.value ||
|
|
72
|
-
dbVar.isSecret !== persistentVar.isSecret) {
|
|
73
|
-
persistentVar.value.value = await rpc_types_1.rpcServerCalls.encryptData(persistentVar.value.value || "", this.groupId);
|
|
156
|
+
/** Return a stored variable's raw value by name. */
|
|
157
|
+
async getPersistentVarValue(name) {
|
|
158
|
+
const pVars = await this.list({ name });
|
|
159
|
+
if (pVars.length > 1) {
|
|
160
|
+
console.warn(`Multiple persistent variables found with name "${name}". Using the last one.`);
|
|
74
161
|
}
|
|
162
|
+
const pVar = pVars[pVars.length - 1];
|
|
163
|
+
return pVar?.value?.value;
|
|
75
164
|
}
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
return super.save(persistentVar, opts);
|
|
80
|
-
}
|
|
81
|
-
async getPersistentVarValue(name) {
|
|
82
|
-
const pVars = await this.list({ name });
|
|
83
|
-
if (pVars.length > 1) {
|
|
84
|
-
console.warn(`Multiple persistent variables found with name "${name}". Using the last one.`);
|
|
165
|
+
constructor() {
|
|
166
|
+
super(...arguments);
|
|
167
|
+
__runInitializers(this, _instanceExtraInitializers);
|
|
85
168
|
}
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
}
|
|
89
|
-
}
|
|
169
|
+
};
|
|
170
|
+
})();
|
|
90
171
|
exports.PersistentVarsTable = PersistentVarsTable;
|
|
91
172
|
(0, table_definitions_system_1.registerSystemTableDefinition)(exports.persistentVarsMetaData, schema, PersistentVarsTable);
|
|
173
|
+
/** Return the persistent-variable table for a data context. */
|
|
92
174
|
function PersistentVars(dataContext) {
|
|
93
175
|
return (0, user_context_singleton_1.getTableContainer)(dataContext).getTable(exports.persistentVarsMetaData, schema, PersistentVarsTable);
|
|
94
176
|
}
|
|
177
|
+
/** Resolve a persistent-variable record by name, preferring device scope. */
|
|
95
178
|
async function getPersistentVar(name, dataContext) {
|
|
96
179
|
const pVars = await PersistentVars(dataContext).list({ name });
|
|
97
180
|
if (!pVars.length) {
|
|
@@ -210,10 +293,7 @@ function persistentVarFactory(name, opts) {
|
|
|
210
293
|
}
|
|
211
294
|
}
|
|
212
295
|
if (dbRec && !(0, utils_1.isDeterministicPvarId)(dbRec.persistentVarId)) {
|
|
213
|
-
|
|
214
|
-
await table.delete(dbRec);
|
|
215
|
-
dbRec.persistentVarId = newId;
|
|
216
|
-
dbRec = await table.save(dbRec);
|
|
296
|
+
dbRec = await table.migrateLegacyId(dbRec);
|
|
217
297
|
}
|
|
218
298
|
if (!dbRec) {
|
|
219
299
|
dbRec = {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const originalClientFlag = process.env.PEERS_IS_CLIENT;
|
|
4
|
+
function createEventRegistry() {
|
|
5
|
+
return {
|
|
6
|
+
getEmitter: jest.fn().mockReturnValue({
|
|
7
|
+
event: { subscribe: jest.fn() },
|
|
8
|
+
emit: jest.fn(),
|
|
9
|
+
}),
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
function createLegacyRecord(name) {
|
|
13
|
+
return {
|
|
14
|
+
persistentVarId: "00mriijkhq94msfe9m2j6quwp",
|
|
15
|
+
name,
|
|
16
|
+
scope: "device",
|
|
17
|
+
isSecret: true,
|
|
18
|
+
value: { value: "encrypted:ciphertext" },
|
|
19
|
+
modifiedAt: 1234,
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
afterEach(() => {
|
|
23
|
+
if (originalClientFlag === undefined) {
|
|
24
|
+
delete process.env.PEERS_IS_CLIENT;
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
process.env.PEERS_IS_CLIENT = originalClientFlag;
|
|
28
|
+
}
|
|
29
|
+
jest.resetModules();
|
|
30
|
+
jest.restoreAllMocks();
|
|
31
|
+
});
|
|
32
|
+
describe("PersistentVars legacy ID migration", () => {
|
|
33
|
+
it("uses one custom table RPC from a renderer client", async () => {
|
|
34
|
+
process.env.PEERS_IS_CLIENT = "true";
|
|
35
|
+
jest.resetModules();
|
|
36
|
+
await jest.isolateModulesAsync(async () => {
|
|
37
|
+
jest.doMock("../context/user-context-singleton", () => ({
|
|
38
|
+
getTableContainer: jest.fn(),
|
|
39
|
+
getUserContext: jest.fn(),
|
|
40
|
+
}));
|
|
41
|
+
const { PersistentVarsTable, persistentVarsMetaData } = await Promise.resolve().then(() => require("./persistent-vars"));
|
|
42
|
+
const { ClientProxyDataSource } = await Promise.resolve().then(() => require("./orm/client-proxy.data-source"));
|
|
43
|
+
const { rpcServerCalls } = await Promise.resolve().then(() => require("../rpc-types"));
|
|
44
|
+
const record = createLegacyRecord("rendererMigration");
|
|
45
|
+
const migrated = { ...record, persistentVarId: "00mriijkhq94msfe9m2j6quwq" };
|
|
46
|
+
const tableMethodCall = jest.fn().mockResolvedValue(migrated);
|
|
47
|
+
rpcServerCalls.tableMethodCall = tableMethodCall;
|
|
48
|
+
const dataContextId = "00mriijkhq94msfe9m2j6qabc";
|
|
49
|
+
const table = new PersistentVarsTable(persistentVarsMetaData, {
|
|
50
|
+
dataSource: new ClientProxyDataSource(persistentVarsMetaData, undefined, dataContextId),
|
|
51
|
+
eventRegistry: createEventRegistry(),
|
|
52
|
+
});
|
|
53
|
+
await expect(table.migrateLegacyId(record)).resolves.toEqual(migrated);
|
|
54
|
+
expect(tableMethodCall).toHaveBeenCalledTimes(1);
|
|
55
|
+
expect(tableMethodCall).toHaveBeenCalledWith(dataContextId, "PersistentVars", "migrateLegacyId", record);
|
|
56
|
+
});
|
|
57
|
+
});
|
|
58
|
+
it("removes a legacy duplicate when the canonical record already exists", async () => {
|
|
59
|
+
delete process.env.PEERS_IS_CLIENT;
|
|
60
|
+
jest.resetModules();
|
|
61
|
+
await jest.isolateModulesAsync(async () => {
|
|
62
|
+
jest.doMock("../context/user-context-singleton", () => ({
|
|
63
|
+
getTableContainer: jest.fn(),
|
|
64
|
+
getUserContext: jest.fn(),
|
|
65
|
+
}));
|
|
66
|
+
const { PersistentVarsTable, persistentVarsMetaData } = await Promise.resolve().then(() => require("./persistent-vars"));
|
|
67
|
+
const { deterministicPvarId } = await Promise.resolve().then(() => require("../utils"));
|
|
68
|
+
const legacy = createLegacyRecord("existingCanonical");
|
|
69
|
+
const canonical = {
|
|
70
|
+
...legacy,
|
|
71
|
+
persistentVarId: deterministicPvarId(legacy.name),
|
|
72
|
+
value: { value: "encrypted:canonical" },
|
|
73
|
+
};
|
|
74
|
+
const deleteRecord = jest.fn().mockResolvedValue(undefined);
|
|
75
|
+
const save = jest.fn();
|
|
76
|
+
const table = new PersistentVarsTable(persistentVarsMetaData, {
|
|
77
|
+
dataSource: {
|
|
78
|
+
tableName: "PersistentVars",
|
|
79
|
+
primaryKeyName: "persistentVarId",
|
|
80
|
+
get: jest.fn().mockResolvedValue(canonical),
|
|
81
|
+
list: jest.fn(),
|
|
82
|
+
count: jest.fn(),
|
|
83
|
+
save,
|
|
84
|
+
insert: jest.fn(),
|
|
85
|
+
update: jest.fn(),
|
|
86
|
+
delete: deleteRecord,
|
|
87
|
+
},
|
|
88
|
+
eventRegistry: createEventRegistry(),
|
|
89
|
+
});
|
|
90
|
+
await expect(table.migrateLegacyId(legacy)).resolves.toEqual(canonical);
|
|
91
|
+
expect(deleteRecord).toHaveBeenCalledWith(legacy);
|
|
92
|
+
expect(save).not.toHaveBeenCalled();
|
|
93
|
+
});
|
|
94
|
+
});
|
|
95
|
+
it("restores the legacy record when writing the canonical ID fails", async () => {
|
|
96
|
+
delete process.env.PEERS_IS_CLIENT;
|
|
97
|
+
jest.resetModules();
|
|
98
|
+
await jest.isolateModulesAsync(async () => {
|
|
99
|
+
jest.doMock("../context/user-context-singleton", () => ({
|
|
100
|
+
getTableContainer: jest.fn(),
|
|
101
|
+
getUserContext: jest.fn(),
|
|
102
|
+
}));
|
|
103
|
+
const { PersistentVarsTable, persistentVarsMetaData } = await Promise.resolve().then(() => require("./persistent-vars"));
|
|
104
|
+
const legacy = createLegacyRecord("rollbackMigration");
|
|
105
|
+
const migrationError = new Error("canonical write failed");
|
|
106
|
+
const deleteRecord = jest.fn().mockResolvedValue(undefined);
|
|
107
|
+
const save = jest.fn().mockRejectedValueOnce(migrationError).mockResolvedValueOnce(legacy);
|
|
108
|
+
const table = new PersistentVarsTable(persistentVarsMetaData, {
|
|
109
|
+
dataSource: {
|
|
110
|
+
tableName: "PersistentVars",
|
|
111
|
+
primaryKeyName: "persistentVarId",
|
|
112
|
+
get: jest.fn().mockResolvedValue(undefined),
|
|
113
|
+
list: jest.fn(),
|
|
114
|
+
count: jest.fn(),
|
|
115
|
+
save,
|
|
116
|
+
insert: jest.fn(),
|
|
117
|
+
update: jest.fn(),
|
|
118
|
+
delete: deleteRecord,
|
|
119
|
+
},
|
|
120
|
+
eventRegistry: createEventRegistry(),
|
|
121
|
+
});
|
|
122
|
+
await expect(table.migrateLegacyId(legacy)).rejects.toBe(migrationError);
|
|
123
|
+
expect(deleteRecord).toHaveBeenCalledWith(legacy);
|
|
124
|
+
expect(save).toHaveBeenCalledTimes(2);
|
|
125
|
+
expect(save.mock.calls[0][0]).toMatchObject({
|
|
126
|
+
name: legacy.name,
|
|
127
|
+
value: legacy.value,
|
|
128
|
+
});
|
|
129
|
+
expect(save.mock.calls[0][0].persistentVarId).not.toBe(legacy.persistentVarId);
|
|
130
|
+
expect(save.mock.calls[1][0]).toEqual(legacy);
|
|
131
|
+
});
|
|
132
|
+
});
|
|
133
|
+
});
|
|
@@ -34,7 +34,7 @@ export type ITableDefinitionRecord = z.infer<typeof tableDefinitionRecordSchema>
|
|
|
34
34
|
*
|
|
35
35
|
* @param dataContext - Optional data context; when omitted the singleton context is used.
|
|
36
36
|
*/
|
|
37
|
-
export declare function TableDefinitions(dataContext?: DataContext): import("
|
|
37
|
+
export declare function TableDefinitions(dataContext?: DataContext): import("..").Table<{
|
|
38
38
|
name: string;
|
|
39
39
|
metaData: {} & {
|
|
40
40
|
[k: string]: any;
|
|
@@ -26,7 +26,7 @@ export declare const toolTestSchema: z.ZodObject<{
|
|
|
26
26
|
mocks?: any;
|
|
27
27
|
}>;
|
|
28
28
|
export type IToolTest = z.infer<typeof toolTestSchema>;
|
|
29
|
-
export declare function ToolTests(dataContext?: DataContext): import("
|
|
29
|
+
export declare function ToolTests(dataContext?: DataContext): import("..").Table<{
|
|
30
30
|
code: string;
|
|
31
31
|
description: string;
|
|
32
32
|
toolId: string;
|
package/dist/data/tools.d.ts
CHANGED
|
@@ -313,7 +313,7 @@ export interface IToolInstance {
|
|
|
313
313
|
inputSchema?: z.ZodObject<any>;
|
|
314
314
|
outputSchema?: z.ZodObject<any>;
|
|
315
315
|
}
|
|
316
|
-
export declare function Tools(dataContext?: DataContext): import("
|
|
316
|
+
export declare function Tools(dataContext?: DataContext): import("..").Table<{
|
|
317
317
|
code: string;
|
|
318
318
|
name: string;
|
|
319
319
|
toolId: string;
|
|
@@ -24,8 +24,10 @@ export declare const userTrustLevelSchema: z.ZodObject<{
|
|
|
24
24
|
assignedAt?: Date | undefined;
|
|
25
25
|
notes?: string | undefined;
|
|
26
26
|
}>;
|
|
27
|
+
/** A trust assignment for one user within a specific data context. */
|
|
27
28
|
export type IUserTrustLevel = z.infer<typeof userTrustLevelSchema>;
|
|
28
|
-
|
|
29
|
+
/** Returns the context-scoped table containing explicit user trust assignments. */
|
|
30
|
+
export declare function UserTrustLevels(dataContext?: DataContext): import("..").Table<{
|
|
29
31
|
userId: string;
|
|
30
32
|
trustLevel: TrustLevel;
|
|
31
33
|
assignedAt?: Date | undefined;
|
|
@@ -33,6 +33,7 @@ const metaData = {
|
|
|
33
33
|
indexes: [{ fields: ["trustLevel"] }],
|
|
34
34
|
};
|
|
35
35
|
(0, table_definitions_system_1.registerSystemTableDefinition)(metaData, exports.userTrustLevelSchema);
|
|
36
|
+
/** Returns the context-scoped table containing explicit user trust assignments. */
|
|
36
37
|
function UserTrustLevels(dataContext) {
|
|
37
38
|
return (0, user_context_singleton_1.getTableContainer)(dataContext).getTable(metaData, exports.userTrustLevelSchema);
|
|
38
39
|
}
|
|
@@ -41,7 +42,7 @@ function UserTrustLevels(dataContext) {
|
|
|
41
42
|
* Returns TrustLevel.Unknown if no trust level has been assigned.
|
|
42
43
|
*/
|
|
43
44
|
async function getUserTrustLevel(dataContext, userId) {
|
|
44
|
-
const userContext =
|
|
45
|
+
const userContext = dataContext.userContext;
|
|
45
46
|
if (dataContext === userContext.userDataContext && userContext.userId === userId) {
|
|
46
47
|
return socket_type_1.TrustLevel.Self;
|
|
47
48
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const socket_type_1 = require("../device/socket.type");
|
|
4
|
+
const utils_1 = require("../utils");
|
|
5
|
+
const user_trust_levels_1 = require("./user-trust-levels");
|
|
6
|
+
function makeDataContext(userId, trustRecord) {
|
|
7
|
+
const get = jest.fn().mockResolvedValue(trustRecord);
|
|
8
|
+
const userContext = { userId };
|
|
9
|
+
const dataContext = {
|
|
10
|
+
userContext,
|
|
11
|
+
tableContainer: {
|
|
12
|
+
getTable: jest.fn().mockReturnValue({ get }),
|
|
13
|
+
},
|
|
14
|
+
};
|
|
15
|
+
Object.assign(userContext, { userDataContext: dataContext });
|
|
16
|
+
return { dataContext, get };
|
|
17
|
+
}
|
|
18
|
+
describe("getUserTrustLevel", () => {
|
|
19
|
+
it("derives Self from the supplied personal context without a global user context", async () => {
|
|
20
|
+
const userId = (0, utils_1.newid)();
|
|
21
|
+
const { dataContext, get } = makeDataContext(userId);
|
|
22
|
+
await expect((0, user_trust_levels_1.getUserTrustLevel)(dataContext, userId)).resolves.toBe(socket_type_1.TrustLevel.Self);
|
|
23
|
+
expect(get).not.toHaveBeenCalled();
|
|
24
|
+
});
|
|
25
|
+
it("reads explicit trust from the supplied context", async () => {
|
|
26
|
+
const remoteUserId = (0, utils_1.newid)();
|
|
27
|
+
const { dataContext, get } = makeDataContext((0, utils_1.newid)(), {
|
|
28
|
+
trustLevel: socket_type_1.TrustLevel.Trusted,
|
|
29
|
+
});
|
|
30
|
+
await expect((0, user_trust_levels_1.getUserTrustLevel)(dataContext, remoteUserId)).resolves.toBe(socket_type_1.TrustLevel.Trusted);
|
|
31
|
+
expect(get).toHaveBeenCalledWith(remoteUserId);
|
|
32
|
+
});
|
|
33
|
+
it("returns Unknown when the supplied context has no trust assignment", async () => {
|
|
34
|
+
const { dataContext } = makeDataContext((0, utils_1.newid)());
|
|
35
|
+
await expect((0, user_trust_levels_1.getUserTrustLevel)(dataContext, (0, utils_1.newid)())).resolves.toBe(socket_type_1.TrustLevel.Unknown);
|
|
36
|
+
});
|
|
37
|
+
});
|
|
@@ -23,7 +23,7 @@ export declare const voiceMessageSchema: z.ZodObject<{
|
|
|
23
23
|
threadId?: string | undefined;
|
|
24
24
|
}>;
|
|
25
25
|
export type IVoiceMessage = z.infer<typeof voiceMessageSchema>;
|
|
26
|
-
export declare function VoiceMessages(dataContext?: DataContext): import("
|
|
26
|
+
export declare function VoiceMessages(dataContext?: DataContext): import("..").Table<{
|
|
27
27
|
content: string;
|
|
28
28
|
role: "user" | "assistant";
|
|
29
29
|
createdAt: Date;
|
|
@@ -66,7 +66,7 @@ export declare const workflowLogSchema: z.ZodObject<{
|
|
|
66
66
|
isError?: boolean | undefined;
|
|
67
67
|
}>;
|
|
68
68
|
export type IWorkflowLog = z.infer<typeof workflowLogSchema>;
|
|
69
|
-
export declare function WorkflowLogs(dataContext?: DataContext): import("
|
|
69
|
+
export declare function WorkflowLogs(dataContext?: DataContext): import("..").Table<{
|
|
70
70
|
workflowLogId: string;
|
|
71
71
|
workflowRunId: string;
|
|
72
72
|
contextId: string;
|
|
@@ -32,6 +32,7 @@ export declare const workflowRunSchema: z.ZodObject<{
|
|
|
32
32
|
parentWorkflowRunId: z.ZodOptional<z.ZodEffects<z.ZodString, string, string>>;
|
|
33
33
|
defaultAssistantId: z.ZodEffects<z.ZodString, string, string>;
|
|
34
34
|
}, "strip", z.ZodTypeAny, {
|
|
35
|
+
createdAt: Date;
|
|
35
36
|
defaultAssistantId: string;
|
|
36
37
|
instructions: {
|
|
37
38
|
markdown?: string | undefined;
|
|
@@ -39,7 +40,6 @@ export declare const workflowRunSchema: z.ZodObject<{
|
|
|
39
40
|
directCallToolId?: string | undefined;
|
|
40
41
|
subWorkflowId?: string | undefined;
|
|
41
42
|
}[];
|
|
42
|
-
createdAt: Date;
|
|
43
43
|
workflowRunId: string;
|
|
44
44
|
parentMessageId: string;
|
|
45
45
|
currentInstructionIndex: number;
|
|
@@ -57,6 +57,7 @@ export declare const workflowRunSchema: z.ZodObject<{
|
|
|
57
57
|
defaultAssistantId: string;
|
|
58
58
|
workflowRunId: string;
|
|
59
59
|
parentMessageId: string;
|
|
60
|
+
createdAt?: Date | undefined;
|
|
60
61
|
workflowId?: string | undefined;
|
|
61
62
|
instructions?: {
|
|
62
63
|
markdown?: string | undefined;
|
|
@@ -64,7 +65,6 @@ export declare const workflowRunSchema: z.ZodObject<{
|
|
|
64
65
|
directCallToolId?: string | undefined;
|
|
65
66
|
subWorkflowId?: string | undefined;
|
|
66
67
|
}[] | undefined;
|
|
67
|
-
createdAt?: Date | undefined;
|
|
68
68
|
scheduleDT?: Date | undefined;
|
|
69
69
|
currentInstructionIndex?: number | undefined;
|
|
70
70
|
instructionResults?: any[] | undefined;
|
package/dist/data/workflows.d.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import type { DataContext } from "../context/data-context";
|
|
2
|
-
export declare function Workflows(dataContext?: DataContext): import("
|
|
2
|
+
export declare function Workflows(dataContext?: DataContext): import("..").Table<{
|
|
3
3
|
name: string;
|
|
4
4
|
description: string;
|
|
5
|
+
createdAt: Date;
|
|
6
|
+
updatedAt: Date;
|
|
5
7
|
workflowId: string;
|
|
6
8
|
defaultAssistantId: string;
|
|
7
9
|
instructions: {
|
|
@@ -11,7 +13,5 @@ export declare function Workflows(dataContext?: DataContext): import("./orm").Ta
|
|
|
11
13
|
subWorkflowId?: string | undefined;
|
|
12
14
|
}[];
|
|
13
15
|
createdBy: string;
|
|
14
|
-
createdAt: Date;
|
|
15
|
-
updatedAt: Date;
|
|
16
16
|
packageId?: string | undefined;
|
|
17
17
|
}>;
|
|
@@ -35,7 +35,9 @@ export interface IBinaryPeer {
|
|
|
35
35
|
*/
|
|
36
36
|
getBufferedAmount?(): number;
|
|
37
37
|
}
|
|
38
|
+
/** Backwards-compatible name for a WebRTC binary peer. */
|
|
38
39
|
export type IWebRTCPeer = IBinaryPeer;
|
|
40
|
+
/** Options for wrapping a binary transport in a verified Peers connection. */
|
|
39
41
|
export interface WrapBinaryPeerOptions {
|
|
40
42
|
/** Protocol identifier used for server address (e.g., 'wrtc' or 'ws') */
|
|
41
43
|
protocol: "wrtc" | "ws";
|
|
@@ -324,9 +324,19 @@ function createBinaryPeerSocket(connectionId, peer, protocol = "binary") {
|
|
|
324
324
|
return;
|
|
325
325
|
}
|
|
326
326
|
if (message.type === "call") {
|
|
327
|
-
const
|
|
327
|
+
const eventName = message.eventName;
|
|
328
|
+
const handler = eventName ? handlers[eventName] : undefined;
|
|
328
329
|
if (!handler) {
|
|
329
|
-
|
|
330
|
+
const error = eventName
|
|
331
|
+
? `No handler registered for event: ${eventName}`
|
|
332
|
+
: "RPC call did not include an event name";
|
|
333
|
+
console.warn(error);
|
|
334
|
+
const responseMessage = {
|
|
335
|
+
type: "callback",
|
|
336
|
+
callbackId: message.callbackId,
|
|
337
|
+
error,
|
|
338
|
+
};
|
|
339
|
+
sendRPC(encodeMessage(responseMessage));
|
|
330
340
|
return;
|
|
331
341
|
}
|
|
332
342
|
try {
|
|
@@ -117,6 +117,29 @@ describe("binary-peer-connection-v2", () => {
|
|
|
117
117
|
iPeer.destroy();
|
|
118
118
|
rPeer.destroy();
|
|
119
119
|
});
|
|
120
|
+
it("should return an error when the remote event has no handler", async () => {
|
|
121
|
+
const { iPeer, rPeer } = await getMockPeerPair();
|
|
122
|
+
const socketA = (0, binary_peer_connection_v2_1.createBinaryPeerSocket)("a", iPeer, "ws");
|
|
123
|
+
(0, binary_peer_connection_v2_1.createBinaryPeerSocket)("b", rPeer, "ws");
|
|
124
|
+
const warning = jest.spyOn(console, "warn").mockImplementation(() => { });
|
|
125
|
+
try {
|
|
126
|
+
const response = await new Promise((resolve) => {
|
|
127
|
+
socketA.emit("missing-event", {}, (error, result) => {
|
|
128
|
+
resolve({ error, result });
|
|
129
|
+
});
|
|
130
|
+
});
|
|
131
|
+
expect(response).toEqual({
|
|
132
|
+
error: "No handler registered for event: missing-event",
|
|
133
|
+
result: undefined,
|
|
134
|
+
});
|
|
135
|
+
expect(warning).toHaveBeenCalledWith("No handler registered for event: missing-event");
|
|
136
|
+
}
|
|
137
|
+
finally {
|
|
138
|
+
warning.mockRestore();
|
|
139
|
+
iPeer.destroy();
|
|
140
|
+
rPeer.destroy();
|
|
141
|
+
}
|
|
142
|
+
});
|
|
120
143
|
it("should handle Uint8Array args without txEncode", async () => {
|
|
121
144
|
const { iPeer, rPeer } = await getMockPeerPair();
|
|
122
145
|
const socketA = (0, binary_peer_connection_v2_1.createBinaryPeerSocket)("a", iPeer, "ws");
|
|
@@ -1,3 +1,9 @@
|
|
|
1
1
|
import { type IDeviceInfo } from "../data";
|
|
2
2
|
import { TrustLevel } from "./socket.type";
|
|
3
|
+
/**
|
|
4
|
+
* Build the connection-handshake trust evaluator for a local user identity.
|
|
5
|
+
*
|
|
6
|
+
* Known user keys are authoritative even for a newly observed device: a claimed identity
|
|
7
|
+
* whose signing or box key differs from the stored user record is rejected as untrusted.
|
|
8
|
+
*/
|
|
3
9
|
export declare function getTrustLevelFn(me: Pick<IDeviceInfo, "userId" | "publicKey" | "publicBoxKey">, serverUrl?: string): (deviceInfo: IDeviceInfo, _registerNew?: boolean) => Promise<TrustLevel>;
|