@agentunion/fastaun-browser 0.5.3 → 0.5.6
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/CHANGELOG.md +130 -56
- package/_packed_docs/AUN/347/246/273/347/272/277/346/216/250/351/200/201/346/216/245/345/205/245/344/270/216/346/274/224/347/244/272/346/214/207/345/215/227.md +290 -0
- package/_packed_docs/AUN/347/246/273/347/272/277/346/216/250/351/200/201/346/234/215/345/212/241/346/236/266/346/236/204/344/270/216/350/257/246/347/273/206/345/256/236/347/216/260/350/256/241/345/210/222-codex.md +994 -0
- package/_packed_docs/AUN/347/246/273/347/272/277/346/216/250/351/200/201/346/234/215/345/212/241/350/277/220/347/273/264/344/270/216/345/217/221/345/270/203/346/214/207/345/215/227.md +144 -0
- package/_packed_docs/CHANGELOG.md +130 -56
- package/_packed_docs/INDEX.md +127 -69
- package/_packed_docs/KITE_DOCS_GUIDE.md +63 -29
- package/_packed_docs/audit/AUN/346/234/215/345/212/241Go/345/214/226/351/207/215/346/236/204/347/262/276/347/273/206/345/214/226/346/272/220/347/240/201/345/256/241/346/237/245-20260718.md +366 -0
- package/_packed_docs/aun/345/205/254/347/275/221/346/265/213/350/257/225/350/277/220/350/241/214/346/214/207/345/215/227.md +227 -0
- package/_packed_docs/aun/345/210/206/345/270/203/345/274/217/346/265/213/350/257/225/350/277/220/350/241/214/346/214/207/345/215/227.md +1004 -0
- package/_packed_docs/aun/346/265/213/350/257/225/350/277/220/350/241/214/346/214/207/345/215/227.md +999 -0
- package/_packed_docs/cli/CLI/346/211/213/345/206/214.md +6 -4
- package/_packed_docs/protocol/06-/346/234/215/345/212/241/345/215/217/350/256/256.md +58 -20
- package/_packed_docs/protocol/10-Group-/345/255/220/345/215/217/350/256/256.md +219 -247
- package/_packed_docs/protocol/12-Stream-/345/255/220/345/215/217/350/256/256.md +14 -14
- package/_packed_docs/protocol/13-Agent/350/241/214/344/270/272/350/247/204/350/214/203.md +3 -3
- package/_packed_docs/protocol/15-/347/246/273/347/272/277/346/216/250/351/200/201/351/200/232/347/237/245/345/215/217/350/256/256.md +165 -421
- package/_packed_docs/protocol/README.md +1 -0
- package/_packed_docs/protocol/aun-docs-guide.md +7 -4
- package/_packed_docs/protocol/index.md +25 -19
- package/_packed_docs/sdk/02-WebSocket/345/215/217/350/256/256.md +62 -17
- package/_packed_docs/sdk/03-/346/240/270/345/277/203/346/246/202/345/277/265.md +22 -0
- package/_packed_docs/sdk/04-/350/277/236/346/216/245/344/270/216/350/256/244/350/257/201.md +67 -78
- package/_packed_docs/sdk/05-E2EE/345/212/240/345/257/206/351/200/232/344/277/241.md +6 -2
- package/_packed_docs/sdk/06-API/346/211/213/345/206/214.md +87 -41
- package/_packed_docs/sdk/08-/346/234/200/344/275/263/345/256/236/350/267/265.md +18 -5
- package/_packed_docs/sdk/09-group-rpc-manual.md +307 -267
- package/_packed_docs/sdk/09-message-rpc-manual.md +142 -103
- package/_packed_docs/sdk/09-payload-reference.md +1 -1
- package/_packed_docs/sdk/09-stream-rpc-manual.md +8 -8
- package/_packed_docs/sdk/AUN_DOCS_GUIDE.md +26 -17
- package/_packed_docs/sdk/INDEX.md +42 -34
- package/_packed_docs/sdk/README.md +7 -6
- package/_packed_docs//346/266/210/346/201/257/345/220/214/346/255/245/344/270/216/345/216/206/345/217/262/346/213/211/345/217/226/344/273/243/347/240/201/345/256/241/346/237/245/351/227/256/351/242/230/346/270/205/345/215/225.md +229 -0
- package/_packed_docs//346/266/210/346/201/257/345/220/214/346/255/245/344/270/216/345/216/206/345/217/262/346/213/211/345/217/226/346/224/271/351/200/240/346/226/271/346/241/210.md +750 -0
- package/dist/agent-md.d.ts +4 -5
- package/dist/agent-md.d.ts.map +1 -1
- package/dist/agent-md.js +66 -43
- package/dist/agent-md.js.map +1 -1
- package/dist/aid-store.d.ts +2 -6
- package/dist/aid-store.d.ts.map +1 -1
- package/dist/aid-store.js +20 -14
- package/dist/aid-store.js.map +1 -1
- package/dist/auth.d.ts.map +1 -1
- package/dist/auth.js +30 -11
- package/dist/auth.js.map +1 -1
- package/dist/bundle.js +3399 -1069
- package/dist/client/delivery.d.ts +75 -8
- package/dist/client/delivery.d.ts.map +1 -1
- package/dist/client/delivery.js +1419 -245
- package/dist/client/delivery.js.map +1 -1
- package/dist/client/group-state.d.ts.map +1 -1
- package/dist/client/group-state.js +27 -24
- package/dist/client/group-state.js.map +1 -1
- package/dist/client/lifecycle.d.ts.map +1 -1
- package/dist/client/lifecycle.js +48 -4
- package/dist/client/lifecycle.js.map +1 -1
- package/dist/client/mention-mode.d.ts +7 -0
- package/dist/client/mention-mode.d.ts.map +1 -0
- package/dist/client/mention-mode.js +184 -0
- package/dist/client/mention-mode.js.map +1 -0
- package/dist/client/peers.d.ts +1 -1
- package/dist/client/peers.d.ts.map +1 -1
- package/dist/client/peers.js +26 -3
- package/dist/client/peers.js.map +1 -1
- package/dist/client/rpc-pipeline.d.ts +22 -1
- package/dist/client/rpc-pipeline.d.ts.map +1 -1
- package/dist/client/rpc-pipeline.js +309 -74
- package/dist/client/rpc-pipeline.js.map +1 -1
- package/dist/client/v2-e2ee.d.ts +25 -2
- package/dist/client/v2-e2ee.d.ts.map +1 -1
- package/dist/client/v2-e2ee.js +606 -97
- package/dist/client/v2-e2ee.js.map +1 -1
- package/dist/client.d.ts +24 -5
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +404 -215
- package/dist/client.js.map +1 -1
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +4 -1
- package/dist/errors.js.map +1 -1
- package/dist/facades.d.ts +6 -0
- package/dist/facades.d.ts.map +1 -1
- package/dist/facades.js +199 -104
- package/dist/facades.js.map +1 -1
- package/dist/group-index.d.ts +6 -1
- package/dist/group-index.d.ts.map +1 -1
- package/dist/group-index.js +44 -25
- package/dist/group-index.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/keystore/index.d.ts +10 -5
- package/dist/keystore/index.d.ts.map +1 -1
- package/dist/keystore/indexeddb-identity-store.d.ts +0 -12
- package/dist/keystore/indexeddb-identity-store.d.ts.map +1 -1
- package/dist/keystore/indexeddb-identity-store.js +0 -60
- package/dist/keystore/indexeddb-identity-store.js.map +1 -1
- package/dist/keystore/indexeddb-shared.d.ts.map +1 -1
- package/dist/keystore/indexeddb-shared.js +9 -5
- package/dist/keystore/indexeddb-shared.js.map +1 -1
- package/dist/keystore/indexeddb-token-store.d.ts +3 -1
- package/dist/keystore/indexeddb-token-store.d.ts.map +1 -1
- package/dist/keystore/indexeddb-token-store.js +47 -2
- package/dist/keystore/indexeddb-token-store.js.map +1 -1
- package/dist/register-flow.d.ts.map +1 -1
- package/dist/register-flow.js +28 -3
- package/dist/register-flow.js.map +1 -1
- package/dist/seq-tracker.d.ts +28 -8
- package/dist/seq-tracker.d.ts.map +1 -1
- package/dist/seq-tracker.js +218 -61
- package/dist/seq-tracker.js.map +1 -1
- package/dist/storage/vfs.d.ts +1 -0
- package/dist/storage/vfs.d.ts.map +1 -1
- package/dist/storage/vfs.js +26 -2
- package/dist/storage/vfs.js.map +1 -1
- package/dist/tools/cross-sdk-agent.js +376 -10
- package/dist/tools/cross-sdk-agent.js.map +1 -1
- package/dist/transport.d.ts +12 -0
- package/dist/transport.d.ts.map +1 -1
- package/dist/transport.js +218 -101
- package/dist/transport.js.map +1 -1
- package/dist/v2/session/session.d.ts.map +1 -1
- package/dist/v2/session/session.js +3 -4
- package/dist/v2/session/session.js.map +1 -1
- package/dist/v2/state/commitment.d.ts.map +1 -1
- package/dist/v2/state/commitment.js +1 -2
- package/dist/v2/state/commitment.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +6 -5
- package/dist/group-resources.d.ts +0 -98
- package/dist/group-resources.d.ts.map +0 -1
- package/dist/group-resources.js +0 -635
- package/dist/group-resources.js.map +0 -1
- package/dist/keystore/indexeddb.d.ts +0 -179
- package/dist/keystore/indexeddb.d.ts.map +0 -1
- package/dist/keystore/indexeddb.js +0 -2031
- package/dist/keystore/indexeddb.js.map +0 -1
- package/dist/namespaces/auth.d.ts +0 -98
- package/dist/namespaces/auth.d.ts.map +0 -1
- package/dist/namespaces/auth.js +0 -992
- package/dist/namespaces/auth.js.map +0 -1
- package/dist/namespaces/custody.d.ts +0 -51
- package/dist/namespaces/custody.d.ts.map +0 -1
- package/dist/namespaces/custody.js +0 -302
- package/dist/namespaces/custody.js.map +0 -1
- package/dist/namespaces/meta.d.ts +0 -109
- package/dist/namespaces/meta.d.ts.map +0 -1
- package/dist/namespaces/meta.js +0 -549
- package/dist/namespaces/meta.js.map +0 -1
package/dist/group-resources.js
DELETED
|
@@ -1,635 +0,0 @@
|
|
|
1
|
-
import { StorageError } from './storage/errors.js';
|
|
2
|
-
const DEFAULT_SIGNER_CONNECT_OPTIONS = {
|
|
3
|
-
connection_kind: 'short',
|
|
4
|
-
short_ttl_ms: 30000,
|
|
5
|
-
heartbeat_interval: 0,
|
|
6
|
-
};
|
|
7
|
-
const GROUP_AID_CACHE_TTL_MS = 30_000;
|
|
8
|
-
const GROUP_STORAGE_BASELINE_DIRS = ['announce', 'public', 'archive', 'memberdata'];
|
|
9
|
-
const GROUP_STORAGE_ALLOWED_PENDING_RPCS = new Set([
|
|
10
|
-
'storage.put_object',
|
|
11
|
-
'storage.create_upload_session',
|
|
12
|
-
'storage.complete_upload',
|
|
13
|
-
'storage.http_put',
|
|
14
|
-
'storage.delete_object',
|
|
15
|
-
'storage.fs.mkdir',
|
|
16
|
-
'storage.fs.rename',
|
|
17
|
-
'storage.fs.remove',
|
|
18
|
-
'storage.fs.mount',
|
|
19
|
-
'storage.fs.unmount',
|
|
20
|
-
'storage.issue_token',
|
|
21
|
-
'storage.revoke_token',
|
|
22
|
-
'storage.set_acl',
|
|
23
|
-
'storage.remove_acl',
|
|
24
|
-
'storage.set_visibility',
|
|
25
|
-
]);
|
|
26
|
-
const GROUP_STORAGE_ALLOWED_CONFIRM_RPCS = new Set([
|
|
27
|
-
'group.resources.confirm',
|
|
28
|
-
'group.resources.confirm_mount',
|
|
29
|
-
]);
|
|
30
|
-
const GROUP_STORAGE_ALLOWED_COMPENSATION_RPCS = new Set([
|
|
31
|
-
'storage.delete_object',
|
|
32
|
-
'storage.fs.remove',
|
|
33
|
-
'storage.fs.unmount',
|
|
34
|
-
'storage.revoke_token',
|
|
35
|
-
'storage.remove_acl',
|
|
36
|
-
'storage.set_acl',
|
|
37
|
-
]);
|
|
38
|
-
export class GroupPendingOpsPartialFailure extends Error {
|
|
39
|
-
failedIndex;
|
|
40
|
-
failedOp;
|
|
41
|
-
storageResults;
|
|
42
|
-
opResults;
|
|
43
|
-
compensationResults;
|
|
44
|
-
compensationErrors;
|
|
45
|
-
constructor(message, details) {
|
|
46
|
-
super(message);
|
|
47
|
-
this.name = 'GroupPendingOpsPartialFailure';
|
|
48
|
-
this.failedIndex = details.failedIndex;
|
|
49
|
-
this.failedOp = details.failedOp;
|
|
50
|
-
this.storageResults = details.storageResults;
|
|
51
|
-
this.opResults = details.opResults;
|
|
52
|
-
this.compensationResults = details.compensationResults;
|
|
53
|
-
this.compensationErrors = details.compensationErrors;
|
|
54
|
-
if (details.cause !== undefined) {
|
|
55
|
-
this.cause = details.cause;
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
toJSON() {
|
|
59
|
-
return {
|
|
60
|
-
failed_index: this.failedIndex,
|
|
61
|
-
failed_op: this.failedOp,
|
|
62
|
-
storage_results: this.storageResults,
|
|
63
|
-
op_results: this.opResults,
|
|
64
|
-
compensation_results: this.compensationResults,
|
|
65
|
-
compensation_errors: this.compensationErrors,
|
|
66
|
-
};
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
function stripNil(params) {
|
|
70
|
-
const out = {};
|
|
71
|
-
for (const [key, value] of Object.entries(params ?? {})) {
|
|
72
|
-
if (value !== undefined && value !== null)
|
|
73
|
-
out[key] = value;
|
|
74
|
-
}
|
|
75
|
-
return out;
|
|
76
|
-
}
|
|
77
|
-
function isRecord(value) {
|
|
78
|
-
return value !== null && typeof value === 'object' && !Array.isArray(value);
|
|
79
|
-
}
|
|
80
|
-
function asGroupResourceParams(value) {
|
|
81
|
-
return isRecord(value) ? { ...value } : {};
|
|
82
|
-
}
|
|
83
|
-
function stringValue(value) {
|
|
84
|
-
if (value === undefined || value === null)
|
|
85
|
-
return '';
|
|
86
|
-
return String(value).trim();
|
|
87
|
-
}
|
|
88
|
-
function errorMessage(value) {
|
|
89
|
-
if (value instanceof Error)
|
|
90
|
-
return value.message;
|
|
91
|
-
return String(value || 'unknown error');
|
|
92
|
-
}
|
|
93
|
-
function memberdataLookupError(groupId, detail, cause) {
|
|
94
|
-
const error = new StorageError(`memberdata namespace lookup failed: ${detail}`, 'ELOOKUP', groupId, { group_id: groupId, cause });
|
|
95
|
-
if (cause !== undefined) {
|
|
96
|
-
error.cause = cause;
|
|
97
|
-
}
|
|
98
|
-
return error;
|
|
99
|
-
}
|
|
100
|
-
function normalizeStoragePath(value) {
|
|
101
|
-
return stringValue(value).replace(/^\/+/, '').replace(/\/+$/, '');
|
|
102
|
-
}
|
|
103
|
-
function clientAid(client) {
|
|
104
|
-
if (!isRecord(client))
|
|
105
|
-
return '';
|
|
106
|
-
const direct = stringValue(client.aid);
|
|
107
|
-
if (direct)
|
|
108
|
-
return direct;
|
|
109
|
-
const current = client.currentAid;
|
|
110
|
-
if (isRecord(current)) {
|
|
111
|
-
const value = stringValue(current.aid);
|
|
112
|
-
if (value)
|
|
113
|
-
return value;
|
|
114
|
-
}
|
|
115
|
-
return stringValue(client._aid);
|
|
116
|
-
}
|
|
117
|
-
function sameAid(left, right) {
|
|
118
|
-
return Boolean(left && right && left.trim().toLowerCase() === right.trim().toLowerCase());
|
|
119
|
-
}
|
|
120
|
-
function resultPathValue(source, path) {
|
|
121
|
-
let current = source;
|
|
122
|
-
for (const part of path.split('.')) {
|
|
123
|
-
if (!part)
|
|
124
|
-
continue;
|
|
125
|
-
if (Array.isArray(current)) {
|
|
126
|
-
const index = Number(part);
|
|
127
|
-
if (!Number.isInteger(index) || index < 0 || index >= current.length)
|
|
128
|
-
return undefined;
|
|
129
|
-
current = current[index];
|
|
130
|
-
}
|
|
131
|
-
else if (isRecord(current)) {
|
|
132
|
-
current = current[part];
|
|
133
|
-
}
|
|
134
|
-
else {
|
|
135
|
-
return undefined;
|
|
136
|
-
}
|
|
137
|
-
if (current === undefined || current === null)
|
|
138
|
-
return undefined;
|
|
139
|
-
}
|
|
140
|
-
return current;
|
|
141
|
-
}
|
|
142
|
-
function payloadSize(value) {
|
|
143
|
-
if (value instanceof Uint8Array)
|
|
144
|
-
return value.byteLength;
|
|
145
|
-
if (value instanceof ArrayBuffer)
|
|
146
|
-
return value.byteLength;
|
|
147
|
-
if (typeof Blob !== 'undefined' && value instanceof Blob)
|
|
148
|
-
return value.size;
|
|
149
|
-
if (typeof value === 'string')
|
|
150
|
-
return value.length;
|
|
151
|
-
if (isRecord(value)) {
|
|
152
|
-
const size = Number(value.size ?? value.length ?? value.byteLength);
|
|
153
|
-
return Number.isFinite(size) && size >= 0 ? size : 0;
|
|
154
|
-
}
|
|
155
|
-
return 0;
|
|
156
|
-
}
|
|
157
|
-
function extractLoadedAid(result, signAs) {
|
|
158
|
-
if (!isRecord(result) || result.ok !== true || !isRecord(result.data)) {
|
|
159
|
-
const error = isRecord(result) && isRecord(result.error) ? result.error : {};
|
|
160
|
-
throw new Error(stringValue(error.message) || `signer identity not found: ${signAs}`);
|
|
161
|
-
}
|
|
162
|
-
const aid = result.data.aid;
|
|
163
|
-
if (!aid)
|
|
164
|
-
throw new Error(`signer identity missing AID object: ${signAs}`);
|
|
165
|
-
return aid;
|
|
166
|
-
}
|
|
167
|
-
function firstResultId(result) {
|
|
168
|
-
if (!isRecord(result))
|
|
169
|
-
return '';
|
|
170
|
-
for (const key of ['folder_id', 'node_id', 'resource_id', 'object_id', 'id']) {
|
|
171
|
-
const value = result[key];
|
|
172
|
-
if (typeof value === 'string' && value.trim())
|
|
173
|
-
return value;
|
|
174
|
-
if (typeof value === 'number' && Number.isFinite(value))
|
|
175
|
-
return String(value);
|
|
176
|
-
}
|
|
177
|
-
const node = result.node;
|
|
178
|
-
if (isRecord(node)) {
|
|
179
|
-
for (const key of ['folder_id', 'node_id', 'resource_id', 'object_id', 'id']) {
|
|
180
|
-
const value = node[key];
|
|
181
|
-
if (typeof value === 'string' && value.trim())
|
|
182
|
-
return value;
|
|
183
|
-
if (typeof value === 'number' && Number.isFinite(value))
|
|
184
|
-
return String(value);
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
return '';
|
|
188
|
-
}
|
|
189
|
-
/**
|
|
190
|
-
* @deprecated 兼容旧 group.resources 控制面;新群文件系统入口使用 client.group.fs。
|
|
191
|
-
*/
|
|
192
|
-
export class GroupResourcesFacade {
|
|
193
|
-
client;
|
|
194
|
-
groupAidCache = new Map();
|
|
195
|
-
constructor(client) {
|
|
196
|
-
this.client = client;
|
|
197
|
-
}
|
|
198
|
-
async createSignerClient(aidObj, options) {
|
|
199
|
-
const factory = options.clientFactory ?? options.client_factory;
|
|
200
|
-
if (factory)
|
|
201
|
-
return factory(aidObj);
|
|
202
|
-
const mod = await import('./client.js');
|
|
203
|
-
return new mod.AUNClient(aidObj);
|
|
204
|
-
}
|
|
205
|
-
async signerFor(signAs, options, cache) {
|
|
206
|
-
const store = options.aidStore ?? options.aid_store;
|
|
207
|
-
if (!signAs || sameAid(clientAid(this.client), signAs))
|
|
208
|
-
return this.client;
|
|
209
|
-
if (!store)
|
|
210
|
-
throw new Error(`group resources operation requires aidStore to sign as ${signAs}`);
|
|
211
|
-
const cached = cache.get(signAs);
|
|
212
|
-
if (cached)
|
|
213
|
-
return cached;
|
|
214
|
-
const loaded = await store.load(signAs);
|
|
215
|
-
const aidObj = extractLoadedAid(loaded, signAs);
|
|
216
|
-
const signer = await this.createSignerClient(aidObj, options);
|
|
217
|
-
await signer.connect(options.connectOptions ?? options.connect_options ?? DEFAULT_SIGNER_CONNECT_OPTIONS);
|
|
218
|
-
cache.set(signAs, signer);
|
|
219
|
-
return signer;
|
|
220
|
-
}
|
|
221
|
-
async httpPut(params, options) {
|
|
222
|
-
const uploadUrl = stringValue(params.upload_url ?? params.uploadUrl ?? params.url);
|
|
223
|
-
if (!uploadUrl)
|
|
224
|
-
throw new Error('storage.http_put requires upload_url');
|
|
225
|
-
const dataRef = stringValue(params.data_ref ?? params.dataRef) || 'upload_data';
|
|
226
|
-
const payload = params.data ?? (dataRef === 'upload_data' ? (options.uploadData ?? options.upload_data) : options[dataRef]);
|
|
227
|
-
if (payload === undefined || payload === null)
|
|
228
|
-
throw new Error('storage.http_put requires upload_data');
|
|
229
|
-
const headers = {};
|
|
230
|
-
if (isRecord(params.headers)) {
|
|
231
|
-
for (const [key, value] of Object.entries(params.headers)) {
|
|
232
|
-
if (value !== undefined && value !== null)
|
|
233
|
-
headers[key] = String(value);
|
|
234
|
-
}
|
|
235
|
-
}
|
|
236
|
-
const contentType = stringValue(params.content_type ?? params.contentType);
|
|
237
|
-
if (contentType && !Object.keys(headers).some((key) => key.toLowerCase() === 'content-type')) {
|
|
238
|
-
headers['Content-Type'] = contentType;
|
|
239
|
-
}
|
|
240
|
-
const customPut = options.httpPut ?? options.http_put;
|
|
241
|
-
let result;
|
|
242
|
-
if (typeof customPut === 'function') {
|
|
243
|
-
result = await customPut(uploadUrl, payload, headers);
|
|
244
|
-
}
|
|
245
|
-
else {
|
|
246
|
-
const fetchFn = globalThis.fetch;
|
|
247
|
-
if (typeof fetchFn !== 'function')
|
|
248
|
-
throw new Error('storage.http_put requires fetch or httpPut option');
|
|
249
|
-
const response = await fetchFn(uploadUrl, { method: 'PUT', body: payload, headers });
|
|
250
|
-
if (!response.ok)
|
|
251
|
-
throw new Error(`HTTP PUT failed: status=${response.status}`);
|
|
252
|
-
result = { status: response.status };
|
|
253
|
-
}
|
|
254
|
-
const sizeBytes = payloadSize(payload);
|
|
255
|
-
const base = isRecord(result) ? asGroupResourceParams(result) : { status: typeof result === 'number' ? result : 200 };
|
|
256
|
-
return { ...base, upload_url: uploadUrl, size_bytes: base.size_bytes ?? base.sizeBytes ?? sizeBytes };
|
|
257
|
-
}
|
|
258
|
-
call(name, params) {
|
|
259
|
-
return this.client.call(`group.resources.${name}`, stripNil(params));
|
|
260
|
-
}
|
|
261
|
-
/**
|
|
262
|
-
* 成员挂载区透明路由:memberdata/{self_aid}/{rest} → 成员自己 storage 空间。
|
|
263
|
-
*
|
|
264
|
-
* 协议约定(group-storage 设计 §4.4/§5.3):成员挂载区的源固定指向成员自己空间的
|
|
265
|
-
* {self_aid}/{group_aid}/{rest}。命中本人槽位时返回
|
|
266
|
-
* [owner_aid=self_aid, object_key={self_aid}/{group_aid}/{rest}];
|
|
267
|
-
* 他人槽位或群自有区返回 null(不路由,由调用方走原 group.resources.* 流程)。
|
|
268
|
-
* 服务端拒绝 memberdata 路径走 group_storage 模式,所以映射必须由 SDK 完成。
|
|
269
|
-
*/
|
|
270
|
-
async memberdataNamespaceKey(params) {
|
|
271
|
-
const explicit = stringValue(params.group_aid ?? params.groupAid);
|
|
272
|
-
if (explicit)
|
|
273
|
-
return explicit;
|
|
274
|
-
const groupId = stringValue(params.group_id ?? params.groupId);
|
|
275
|
-
if (!groupId)
|
|
276
|
-
return '';
|
|
277
|
-
const cached = this.groupAidCache.get(groupId);
|
|
278
|
-
if (cached && cached.expiresAt > Date.now())
|
|
279
|
-
return cached.groupAid;
|
|
280
|
-
let result;
|
|
281
|
-
try {
|
|
282
|
-
result = await this.client.call('group.get', { group_id: groupId });
|
|
283
|
-
}
|
|
284
|
-
catch (cause) {
|
|
285
|
-
throw memberdataLookupError(groupId, errorMessage(cause), cause);
|
|
286
|
-
}
|
|
287
|
-
const group = isRecord(result) ? result.group : undefined;
|
|
288
|
-
const groupAid = isRecord(group) ? stringValue(group.group_aid) : '';
|
|
289
|
-
if (!groupAid)
|
|
290
|
-
throw memberdataLookupError(groupId, 'group_aid missing', result);
|
|
291
|
-
this.groupAidCache.set(groupId, { groupAid, expiresAt: Date.now() + GROUP_AID_CACHE_TTL_MS });
|
|
292
|
-
return groupAid;
|
|
293
|
-
}
|
|
294
|
-
resolveMemberdataTarget(groupKey, resourcePath) {
|
|
295
|
-
const path = normalizeStoragePath(resourcePath);
|
|
296
|
-
if (!path)
|
|
297
|
-
return null;
|
|
298
|
-
const parts = path.split('/');
|
|
299
|
-
if (parts.length < 2 || parts[0].toLowerCase() !== 'memberdata')
|
|
300
|
-
return null;
|
|
301
|
-
const slotAid = stringValue(parts[1]);
|
|
302
|
-
const selfAid = clientAid(this.client);
|
|
303
|
-
if (!selfAid || !sameAid(slotAid, selfAid))
|
|
304
|
-
return null;
|
|
305
|
-
const namespaceKey = normalizeStoragePath(groupKey);
|
|
306
|
-
if (!namespaceKey)
|
|
307
|
-
return null;
|
|
308
|
-
const rest = parts.slice(2).join('/').replace(/^\/+/, '').replace(/\/+$/, '');
|
|
309
|
-
const sourceRoot = `${selfAid}/${namespaceKey}`;
|
|
310
|
-
const objectKey = rest ? `${sourceRoot}/${rest}` : sourceRoot;
|
|
311
|
-
return [selfAid, objectKey];
|
|
312
|
-
}
|
|
313
|
-
isMemberdataSelfPath(resourcePath) {
|
|
314
|
-
const path = normalizeStoragePath(resourcePath);
|
|
315
|
-
if (!path)
|
|
316
|
-
return false;
|
|
317
|
-
const parts = path.split('/');
|
|
318
|
-
if (parts.length < 2 || parts[0].toLowerCase() !== 'memberdata')
|
|
319
|
-
return false;
|
|
320
|
-
return sameAid(stringValue(parts[1]), clientAid(this.client));
|
|
321
|
-
}
|
|
322
|
-
async resolveMemberdataTargetForParams(params) {
|
|
323
|
-
if (!this.isMemberdataSelfPath(params.resource_path))
|
|
324
|
-
return null;
|
|
325
|
-
return this.resolveMemberdataTarget(await this.memberdataNamespaceKey(params), params.resource_path);
|
|
326
|
-
}
|
|
327
|
-
baselineDirs(params) {
|
|
328
|
-
const raw = params.paths ?? params.baseline_dirs ?? params.baselineDirs ?? params.directories ?? params.dirs;
|
|
329
|
-
if (!Array.isArray(raw))
|
|
330
|
-
return [...GROUP_STORAGE_BASELINE_DIRS];
|
|
331
|
-
const dirs = raw.map((item) => normalizeStoragePath(item)).filter(Boolean);
|
|
332
|
-
return dirs.length > 0 ? dirs : [...GROUP_STORAGE_BASELINE_DIRS];
|
|
333
|
-
}
|
|
334
|
-
async put(params) {
|
|
335
|
-
const merged = stripNil(params);
|
|
336
|
-
const target = await this.resolveMemberdataTargetForParams(merged);
|
|
337
|
-
if (target) {
|
|
338
|
-
const [ownerAid, objectKey] = target;
|
|
339
|
-
const storageParams = {
|
|
340
|
-
owner_aid: ownerAid,
|
|
341
|
-
object_key: objectKey,
|
|
342
|
-
content: merged.content ?? '',
|
|
343
|
-
overwrite: merged.overwrite ?? false,
|
|
344
|
-
};
|
|
345
|
-
for (const key of ['content_type', 'content_encoding', 'metadata', 'expected_version']) {
|
|
346
|
-
if (merged[key] !== undefined && merged[key] !== null)
|
|
347
|
-
storageParams[key] = merged[key];
|
|
348
|
-
}
|
|
349
|
-
return this.client.call('storage.put_object', storageParams);
|
|
350
|
-
}
|
|
351
|
-
return this.call('put', merged);
|
|
352
|
-
}
|
|
353
|
-
async createFolder(params) {
|
|
354
|
-
const merged = stripNil(params);
|
|
355
|
-
const target = await this.resolveMemberdataTargetForParams(merged);
|
|
356
|
-
if (target) {
|
|
357
|
-
const [ownerAid, path] = target;
|
|
358
|
-
const parents = merged.mkdirs ?? merged.parents;
|
|
359
|
-
return this.client.call('storage.fs.mkdir', {
|
|
360
|
-
owner_aid: ownerAid,
|
|
361
|
-
path,
|
|
362
|
-
parents: parents === undefined || parents === null ? true : Boolean(parents),
|
|
363
|
-
});
|
|
364
|
-
}
|
|
365
|
-
return this.call('create_folder', merged);
|
|
366
|
-
}
|
|
367
|
-
listChildren(params) {
|
|
368
|
-
return this.call('list_children', params);
|
|
369
|
-
}
|
|
370
|
-
rename(params) {
|
|
371
|
-
return this.call('rename', params);
|
|
372
|
-
}
|
|
373
|
-
move(params) {
|
|
374
|
-
return this.call('move', params);
|
|
375
|
-
}
|
|
376
|
-
mountObject(params) {
|
|
377
|
-
return this.call('mount_object', params);
|
|
378
|
-
}
|
|
379
|
-
unmount(params) {
|
|
380
|
-
return this.call('unmount', params);
|
|
381
|
-
}
|
|
382
|
-
resolvePath(params) {
|
|
383
|
-
return this.call('resolve_path', params);
|
|
384
|
-
}
|
|
385
|
-
get(params) {
|
|
386
|
-
return this.call('get', params);
|
|
387
|
-
}
|
|
388
|
-
list(params) {
|
|
389
|
-
return this.call('list', params);
|
|
390
|
-
}
|
|
391
|
-
update(params) {
|
|
392
|
-
return this.call('update', params);
|
|
393
|
-
}
|
|
394
|
-
getAccess(params) {
|
|
395
|
-
return this.call('get_access', params);
|
|
396
|
-
}
|
|
397
|
-
resolveAccessTicket(params) {
|
|
398
|
-
return this.call('resolve_access_ticket', params);
|
|
399
|
-
}
|
|
400
|
-
async delete(params) {
|
|
401
|
-
const merged = stripNil(params);
|
|
402
|
-
const target = await this.resolveMemberdataTargetForParams(merged);
|
|
403
|
-
if (target) {
|
|
404
|
-
const [ownerAid, path] = target;
|
|
405
|
-
// memberdata 下既可能是文件也可能是目录:统一用 fs.remove(服务端对文件/目录均支持)。
|
|
406
|
-
return this.client.call('storage.fs.remove', {
|
|
407
|
-
owner_aid: ownerAid,
|
|
408
|
-
path,
|
|
409
|
-
recursive: Boolean(merged.recursive ?? false),
|
|
410
|
-
});
|
|
411
|
-
}
|
|
412
|
-
return this.call('delete', merged);
|
|
413
|
-
}
|
|
414
|
-
namespaceReady(params) {
|
|
415
|
-
return this.call('namespace_ready', params);
|
|
416
|
-
}
|
|
417
|
-
confirm(params) {
|
|
418
|
-
return this.call('confirm', params);
|
|
419
|
-
}
|
|
420
|
-
confirmMount(params) {
|
|
421
|
-
return this.call('confirm_mount', params);
|
|
422
|
-
}
|
|
423
|
-
getDf(params) {
|
|
424
|
-
return this.call('get_df', params);
|
|
425
|
-
}
|
|
426
|
-
async initializeNamespace(params = {}, options = {}) {
|
|
427
|
-
const input = params ?? {};
|
|
428
|
-
const opts = options ?? {};
|
|
429
|
-
const groupAid = stringValue(input.group_aid ?? input.groupAid ?? input.owner_aid ?? input.owner);
|
|
430
|
-
const groupId = stringValue(input.group_id ?? input.groupId);
|
|
431
|
-
if (!groupAid)
|
|
432
|
-
throw new Error('initializeNamespace requires group_aid');
|
|
433
|
-
if (!groupId)
|
|
434
|
-
throw new Error('initializeNamespace requires group_id');
|
|
435
|
-
const bucket = stringValue(input.bucket) || 'default';
|
|
436
|
-
const signAs = stringValue(input.sign_as ?? input.signAs ?? opts.sign_as ?? opts.signAs ?? groupAid);
|
|
437
|
-
const dirs = this.baselineDirs(input);
|
|
438
|
-
const folderIds = {};
|
|
439
|
-
const signerCache = new Map();
|
|
440
|
-
try {
|
|
441
|
-
const storageClient = await this.signerFor(signAs, opts, signerCache);
|
|
442
|
-
for (const dir of dirs) {
|
|
443
|
-
const mkdirParams = {
|
|
444
|
-
owner_aid: groupAid,
|
|
445
|
-
bucket,
|
|
446
|
-
path: dir,
|
|
447
|
-
parents: true,
|
|
448
|
-
};
|
|
449
|
-
const result = await storageClient.call('storage.fs.mkdir', stripNil(mkdirParams));
|
|
450
|
-
const folderId = firstResultId(result);
|
|
451
|
-
if (folderId)
|
|
452
|
-
folderIds[dir] = folderId;
|
|
453
|
-
if (dir === 'public') {
|
|
454
|
-
await storageClient.call('storage.set_visibility', stripNil({
|
|
455
|
-
owner_aid: groupAid,
|
|
456
|
-
bucket,
|
|
457
|
-
path: dir,
|
|
458
|
-
visibility: 'public',
|
|
459
|
-
}));
|
|
460
|
-
}
|
|
461
|
-
}
|
|
462
|
-
return storageClient.call('group.resources.namespace_ready', {
|
|
463
|
-
group_id: groupId,
|
|
464
|
-
group_aid: groupAid,
|
|
465
|
-
folder_ids: folderIds,
|
|
466
|
-
});
|
|
467
|
-
}
|
|
468
|
-
finally {
|
|
469
|
-
await Promise.all([...signerCache.values()].map((signer) => signer.close()));
|
|
470
|
-
}
|
|
471
|
-
}
|
|
472
|
-
async executePendingOps(plan = {}, options = {}) {
|
|
473
|
-
const input = plan ?? {};
|
|
474
|
-
const opts = options ?? {};
|
|
475
|
-
const pendingOpsRaw = input.pending_ops ?? input.pendingOps;
|
|
476
|
-
if (pendingOpsRaw !== undefined && pendingOpsRaw !== null && !Array.isArray(pendingOpsRaw)) {
|
|
477
|
-
throw new Error('executePendingOps requires pending_ops array');
|
|
478
|
-
}
|
|
479
|
-
const pendingOps = Array.isArray(pendingOpsRaw) ? pendingOpsRaw : [];
|
|
480
|
-
const confirmRpc = stringValue(input.confirm_rpc ?? input.confirmRpc) || 'group.resources.confirm';
|
|
481
|
-
if (!GROUP_STORAGE_ALLOWED_CONFIRM_RPCS.has(confirmRpc)) {
|
|
482
|
-
throw new Error(`unsupported confirm rpc: ${confirmRpc}`);
|
|
483
|
-
}
|
|
484
|
-
for (let index = 0; index < pendingOps.length; index += 1) {
|
|
485
|
-
const rawOp = pendingOps[index];
|
|
486
|
-
if (!isRecord(rawOp))
|
|
487
|
-
throw new Error(`pending op ${index} must be an object`);
|
|
488
|
-
const op = asGroupResourceParams(rawOp);
|
|
489
|
-
const rpc = stringValue(op.rpc ?? op.method);
|
|
490
|
-
if (!rpc)
|
|
491
|
-
throw new Error(`pending op ${index} missing rpc`);
|
|
492
|
-
if (rpc && !GROUP_STORAGE_ALLOWED_PENDING_RPCS.has(rpc)) {
|
|
493
|
-
throw new Error(`unsupported pending rpc: ${rpc}`);
|
|
494
|
-
}
|
|
495
|
-
const compensation = op.compensation;
|
|
496
|
-
if (isRecord(compensation)) {
|
|
497
|
-
const compensationRpc = stringValue(compensation.rpc ?? compensation.method);
|
|
498
|
-
if (compensationRpc && !GROUP_STORAGE_ALLOWED_COMPENSATION_RPCS.has(compensationRpc)) {
|
|
499
|
-
throw new Error(`unsupported compensation rpc: ${compensationRpc}`);
|
|
500
|
-
}
|
|
501
|
-
}
|
|
502
|
-
}
|
|
503
|
-
const defaultSignAs = stringValue(opts.sign_as ?? opts.signAs ?? input.sign_as ?? input.signAs ?? input.group_aid ?? input.groupAid);
|
|
504
|
-
const results = {};
|
|
505
|
-
const opResults = [];
|
|
506
|
-
const successfulOps = [];
|
|
507
|
-
let lastConfirmKey = '';
|
|
508
|
-
let lastResult;
|
|
509
|
-
const signerCache = new Map();
|
|
510
|
-
const runCompensations = async () => {
|
|
511
|
-
if (stringValue(input.failure_policy ?? input.failurePolicy) !== 'compensate_successful_ops_before_confirm') {
|
|
512
|
-
return { compensationResults: {}, compensationErrors: [] };
|
|
513
|
-
}
|
|
514
|
-
const compensationResults = {};
|
|
515
|
-
const compensationErrors = [];
|
|
516
|
-
for (const item of [...successfulOps].reverse()) {
|
|
517
|
-
const compensation = item.op.compensation;
|
|
518
|
-
if (!isRecord(compensation))
|
|
519
|
-
continue;
|
|
520
|
-
const dependsOn = stringValue(compensation.depends_on ?? compensation.dependsOn) || item.confirmKey;
|
|
521
|
-
if (dependsOn && !(dependsOn in results))
|
|
522
|
-
continue;
|
|
523
|
-
const params = asGroupResourceParams(compensation.params);
|
|
524
|
-
const mappings = compensation.params_from_results ?? compensation.paramsFromResults;
|
|
525
|
-
if (isRecord(mappings)) {
|
|
526
|
-
for (const [paramKey, resultPath] of Object.entries(mappings)) {
|
|
527
|
-
const value = resultPathValue({ ...results, results, storage_results: results, op_results: opResults }, stringValue(resultPath));
|
|
528
|
-
if (value !== undefined && value !== null) {
|
|
529
|
-
params[paramKey] = value;
|
|
530
|
-
}
|
|
531
|
-
}
|
|
532
|
-
}
|
|
533
|
-
const rpc = stringValue(compensation.rpc ?? compensation.method);
|
|
534
|
-
if (!rpc)
|
|
535
|
-
continue;
|
|
536
|
-
const signAs = stringValue(compensation.sign_as ?? compensation.signAs ?? item.op.sign_as ?? item.op.signAs ?? defaultSignAs);
|
|
537
|
-
const confirmKey = stringValue(compensation.confirm_key ?? compensation.confirmKey) || `compensate:${item.confirmKey}`;
|
|
538
|
-
try {
|
|
539
|
-
const client = await this.signerFor(signAs, opts, signerCache);
|
|
540
|
-
compensationResults[confirmKey] = await client.call(rpc, stripNil(params));
|
|
541
|
-
}
|
|
542
|
-
catch (exc) {
|
|
543
|
-
compensationErrors.push({ confirm_key: confirmKey, rpc, error: String(exc instanceof Error ? exc.message : exc) });
|
|
544
|
-
}
|
|
545
|
-
}
|
|
546
|
-
return { compensationResults, compensationErrors };
|
|
547
|
-
};
|
|
548
|
-
const applyResultMappings = (op, params) => {
|
|
549
|
-
const mappings = op.params_from_results ?? op.paramsFromResults;
|
|
550
|
-
if (isRecord(mappings)) {
|
|
551
|
-
for (const [paramKey, resultPath] of Object.entries(mappings)) {
|
|
552
|
-
const value = resultPathValue({ ...results, results, storage_results: results, op_results: opResults }, stringValue(resultPath));
|
|
553
|
-
if (value !== undefined && value !== null) {
|
|
554
|
-
params[paramKey] = value;
|
|
555
|
-
}
|
|
556
|
-
}
|
|
557
|
-
}
|
|
558
|
-
if ((op.data_ref ?? op.dataRef) !== undefined && params.data_ref === undefined && params.dataRef === undefined) {
|
|
559
|
-
params.data_ref = op.data_ref ?? op.dataRef;
|
|
560
|
-
}
|
|
561
|
-
return params;
|
|
562
|
-
};
|
|
563
|
-
try {
|
|
564
|
-
for (let index = 0; index < pendingOps.length; index += 1) {
|
|
565
|
-
if (!isRecord(pendingOps[index])) {
|
|
566
|
-
throw new Error(`pending op ${index} must be an object`);
|
|
567
|
-
}
|
|
568
|
-
const op = asGroupResourceParams(pendingOps[index]);
|
|
569
|
-
const rpc = stringValue(op.rpc ?? op.method);
|
|
570
|
-
if (!rpc)
|
|
571
|
-
throw new Error(`pending op ${index} missing rpc`);
|
|
572
|
-
const opParams = applyResultMappings(op, asGroupResourceParams(op.params));
|
|
573
|
-
const confirmKey = stringValue(op.confirm_key ?? op.confirmKey) || `op_${index}`;
|
|
574
|
-
let result;
|
|
575
|
-
try {
|
|
576
|
-
if (rpc === 'storage.http_put') {
|
|
577
|
-
result = await this.httpPut(stripNil(opParams), opts);
|
|
578
|
-
}
|
|
579
|
-
else {
|
|
580
|
-
const opSignAs = stringValue(op.sign_as ?? op.signAs ?? defaultSignAs);
|
|
581
|
-
const storageClient = await this.signerFor(opSignAs, opts, signerCache);
|
|
582
|
-
result = await storageClient.call(rpc, stripNil(opParams));
|
|
583
|
-
}
|
|
584
|
-
}
|
|
585
|
-
catch (exc) {
|
|
586
|
-
const compensation = await runCompensations();
|
|
587
|
-
if (successfulOps.length === 0 && Object.keys(compensation.compensationResults).length === 0 && compensation.compensationErrors.length === 0) {
|
|
588
|
-
throw exc;
|
|
589
|
-
}
|
|
590
|
-
throw new GroupPendingOpsPartialFailure(exc instanceof Error ? exc.message : String(exc), {
|
|
591
|
-
failedIndex: index,
|
|
592
|
-
failedOp: op,
|
|
593
|
-
storageResults: results,
|
|
594
|
-
opResults,
|
|
595
|
-
compensationResults: compensation.compensationResults,
|
|
596
|
-
compensationErrors: compensation.compensationErrors,
|
|
597
|
-
cause: exc,
|
|
598
|
-
});
|
|
599
|
-
}
|
|
600
|
-
opResults.push(result);
|
|
601
|
-
results[confirmKey] = result;
|
|
602
|
-
successfulOps.push({ op, confirmKey, index });
|
|
603
|
-
lastConfirmKey = confirmKey;
|
|
604
|
-
lastResult = result;
|
|
605
|
-
}
|
|
606
|
-
const baseConfirmParams = asGroupResourceParams(input.confirm_params ?? input.confirmParams);
|
|
607
|
-
const confirmParams = {
|
|
608
|
-
...baseConfirmParams,
|
|
609
|
-
group_id: baseConfirmParams.group_id ?? baseConfirmParams.groupId ?? input.group_id ?? input.groupId,
|
|
610
|
-
op_id: baseConfirmParams.op_id ?? baseConfirmParams.opId ?? input.op_id ?? input.opId,
|
|
611
|
-
op_results: opResults,
|
|
612
|
-
storage_results: results,
|
|
613
|
-
storage_result: lastResult,
|
|
614
|
-
confirm_key: baseConfirmParams.confirm_key ?? baseConfirmParams.confirmKey ?? input.confirm_key ?? input.confirmKey ?? lastConfirmKey,
|
|
615
|
-
};
|
|
616
|
-
const confirmSignAs = stringValue(input.confirm_sign_as
|
|
617
|
-
?? input.confirmSignAs
|
|
618
|
-
?? input.sign_as
|
|
619
|
-
?? input.signAs
|
|
620
|
-
?? input.group_aid
|
|
621
|
-
?? input.groupAid
|
|
622
|
-
?? defaultSignAs);
|
|
623
|
-
const confirmClient = await this.signerFor(confirmSignAs, opts, signerCache);
|
|
624
|
-
const confirmResult = await confirmClient.call(confirmRpc, stripNil(confirmParams));
|
|
625
|
-
return {
|
|
626
|
-
storage_results: results,
|
|
627
|
-
confirmed: confirmResult,
|
|
628
|
-
};
|
|
629
|
-
}
|
|
630
|
-
finally {
|
|
631
|
-
await Promise.all([...signerCache.values()].map((signer) => signer.close()));
|
|
632
|
-
}
|
|
633
|
-
}
|
|
634
|
-
}
|
|
635
|
-
//# sourceMappingURL=group-resources.js.map
|