@calimero-network/mero-js 13.0.0 → 13.2.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/dist/account/index.d.ts +43 -0
- package/dist/account/index.js +139 -0
- package/dist/ephemeral/codec.d.ts +4 -0
- package/dist/ephemeral/codec.js +12 -0
- package/dist/ephemeral/index.d.ts +51 -0
- package/dist/ephemeral/index.js +81 -0
- package/dist/ephemeral/types.d.ts +22 -0
- package/dist/ephemeral/types.js +1 -0
- package/dist/events/sse.js +23 -2
- package/dist/index.browser.mjs +2 -2
- package/dist/index.browser.mjs.map +4 -4
- package/dist/index.cjs +216 -25
- package/dist/index.cjs.map +4 -4
- package/dist/index.d.ts +3 -0
- package/dist/index.js +4 -0
- package/dist/index.mjs +216 -25
- package/dist/index.mjs.map +4 -4
- package/dist/mero-js.d.ts +9 -0
- package/dist/mero-js.js +16 -0
- package/dist/rpc/index.d.ts +8 -0
- package/dist/rpc/index.js +28 -20
- package/package.json +1 -1
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Account id encoding.
|
|
3
|
+
*
|
|
4
|
+
* Core names the same account in two encodings, and the split is deliberate:
|
|
5
|
+
* the admin API serves and requires **64 hex characters**, while contract data
|
|
6
|
+
* (`sender`, `get_profiles`, anything stamped by `env::account_id()`) carries
|
|
7
|
+
* **base58**. They are rendered differently on purpose, so that handing one
|
|
8
|
+
* where the other is expected fails loudly instead of resolving to the wrong
|
|
9
|
+
* principal.
|
|
10
|
+
*
|
|
11
|
+
* The cost is that any client reading a member from the admin API and
|
|
12
|
+
* comparing it against a message sender is comparing two spellings of the same
|
|
13
|
+
* value. A raw `===` silently never matches, and passing a contract-sourced id
|
|
14
|
+
* to an admin route answers `400 Invalid account format: expected 64 hex
|
|
15
|
+
* characters (32 bytes)`. Both failure modes are quiet enough to ship.
|
|
16
|
+
*
|
|
17
|
+
* These helpers canonicalise at that boundary. They convert accounts and
|
|
18
|
+
* nothing else: a device key, an alias or any other value is returned
|
|
19
|
+
* unchanged, because converting is this module's job and destroying what it
|
|
20
|
+
* cannot convert is not.
|
|
21
|
+
*/
|
|
22
|
+
/**
|
|
23
|
+
* Canonicalise an account id to hex — the form every admin route expects.
|
|
24
|
+
*
|
|
25
|
+
* Returns the input unchanged if it is not a 32-byte account, so a device key
|
|
26
|
+
* or an alias survives a call to this function intact.
|
|
27
|
+
*/
|
|
28
|
+
export declare function toAccountHex(id: string | null | undefined): string;
|
|
29
|
+
/**
|
|
30
|
+
* Canonicalise an account id to base58 — the form the contract stamps on
|
|
31
|
+
* `sender` and keys `get_profiles` by.
|
|
32
|
+
*
|
|
33
|
+
* Returns the input unchanged if it is not a 32-byte account.
|
|
34
|
+
*/
|
|
35
|
+
export declare function toAccountBase58(id: string | null | undefined): string;
|
|
36
|
+
/**
|
|
37
|
+
* True when both ids name the same account, whichever encoding each is in.
|
|
38
|
+
*
|
|
39
|
+
* This is the comparison to reach for when checking a contract-sourced
|
|
40
|
+
* `sender` against an admin-sourced member id. Two ids that are not accounts
|
|
41
|
+
* compare false rather than accidentally matching as raw strings.
|
|
42
|
+
*/
|
|
43
|
+
export declare function sameAccount(a: string | null | undefined, b: string | null | undefined): boolean;
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Account id encoding.
|
|
3
|
+
*
|
|
4
|
+
* Core names the same account in two encodings, and the split is deliberate:
|
|
5
|
+
* the admin API serves and requires **64 hex characters**, while contract data
|
|
6
|
+
* (`sender`, `get_profiles`, anything stamped by `env::account_id()`) carries
|
|
7
|
+
* **base58**. They are rendered differently on purpose, so that handing one
|
|
8
|
+
* where the other is expected fails loudly instead of resolving to the wrong
|
|
9
|
+
* principal.
|
|
10
|
+
*
|
|
11
|
+
* The cost is that any client reading a member from the admin API and
|
|
12
|
+
* comparing it against a message sender is comparing two spellings of the same
|
|
13
|
+
* value. A raw `===` silently never matches, and passing a contract-sourced id
|
|
14
|
+
* to an admin route answers `400 Invalid account format: expected 64 hex
|
|
15
|
+
* characters (32 bytes)`. Both failure modes are quiet enough to ship.
|
|
16
|
+
*
|
|
17
|
+
* These helpers canonicalise at that boundary. They convert accounts and
|
|
18
|
+
* nothing else: a device key, an alias or any other value is returned
|
|
19
|
+
* unchanged, because converting is this module's job and destroying what it
|
|
20
|
+
* cannot convert is not.
|
|
21
|
+
*/
|
|
22
|
+
const BASE58_ALPHABET = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz';
|
|
23
|
+
/** A 32-byte account rendered as 64 hex characters. */
|
|
24
|
+
const HEX_ACCOUNT = /^[0-9a-f]{64}$/i;
|
|
25
|
+
/** Bytes → base58. Leading zero bytes become leading '1's, as in bitcoin base58. */
|
|
26
|
+
function encodeBase58(bytes) {
|
|
27
|
+
if (bytes.length === 0)
|
|
28
|
+
return '';
|
|
29
|
+
const digits = [0];
|
|
30
|
+
for (const byte of bytes) {
|
|
31
|
+
let carry = byte;
|
|
32
|
+
for (let i = 0; i < digits.length; i++) {
|
|
33
|
+
carry += digits[i] << 8;
|
|
34
|
+
digits[i] = carry % 58;
|
|
35
|
+
carry = (carry / 58) | 0;
|
|
36
|
+
}
|
|
37
|
+
while (carry > 0) {
|
|
38
|
+
digits.push(carry % 58);
|
|
39
|
+
carry = (carry / 58) | 0;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
let out = '';
|
|
43
|
+
for (const byte of bytes) {
|
|
44
|
+
if (byte !== 0)
|
|
45
|
+
break;
|
|
46
|
+
out += BASE58_ALPHABET[0];
|
|
47
|
+
}
|
|
48
|
+
for (let i = digits.length - 1; i >= 0; i--) {
|
|
49
|
+
out += BASE58_ALPHABET[digits[i]];
|
|
50
|
+
}
|
|
51
|
+
return out;
|
|
52
|
+
}
|
|
53
|
+
/** base58 → bytes. Returns null when the input is not valid base58. */
|
|
54
|
+
function decodeBase58(value) {
|
|
55
|
+
if (value.length === 0)
|
|
56
|
+
return null;
|
|
57
|
+
const bytes = [0];
|
|
58
|
+
for (const char of value) {
|
|
59
|
+
const index = BASE58_ALPHABET.indexOf(char);
|
|
60
|
+
if (index < 0)
|
|
61
|
+
return null;
|
|
62
|
+
let carry = index;
|
|
63
|
+
for (let i = 0; i < bytes.length; i++) {
|
|
64
|
+
carry += bytes[i] * 58;
|
|
65
|
+
bytes[i] = carry & 0xff;
|
|
66
|
+
carry >>= 8;
|
|
67
|
+
}
|
|
68
|
+
while (carry > 0) {
|
|
69
|
+
bytes.push(carry & 0xff);
|
|
70
|
+
carry >>= 8;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
let leadingZeros = 0;
|
|
74
|
+
for (const char of value) {
|
|
75
|
+
if (char !== BASE58_ALPHABET[0])
|
|
76
|
+
break;
|
|
77
|
+
leadingZeros++;
|
|
78
|
+
}
|
|
79
|
+
return Uint8Array.from([
|
|
80
|
+
...new Array(leadingZeros).fill(0),
|
|
81
|
+
...bytes.reverse(),
|
|
82
|
+
]);
|
|
83
|
+
}
|
|
84
|
+
function toHex(bytes) {
|
|
85
|
+
let out = '';
|
|
86
|
+
for (const byte of bytes)
|
|
87
|
+
out += byte.toString(16).padStart(2, '0');
|
|
88
|
+
return out;
|
|
89
|
+
}
|
|
90
|
+
function fromHex(hex) {
|
|
91
|
+
const bytes = new Uint8Array(hex.length / 2);
|
|
92
|
+
for (let i = 0; i < bytes.length; i++) {
|
|
93
|
+
bytes[i] = parseInt(hex.slice(i * 2, i * 2 + 2), 16);
|
|
94
|
+
}
|
|
95
|
+
return bytes;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Canonicalise an account id to hex — the form every admin route expects.
|
|
99
|
+
*
|
|
100
|
+
* Returns the input unchanged if it is not a 32-byte account, so a device key
|
|
101
|
+
* or an alias survives a call to this function intact.
|
|
102
|
+
*/
|
|
103
|
+
export function toAccountHex(id) {
|
|
104
|
+
const trimmed = (id ?? '').trim();
|
|
105
|
+
if (!trimmed)
|
|
106
|
+
return '';
|
|
107
|
+
if (HEX_ACCOUNT.test(trimmed))
|
|
108
|
+
return trimmed.toLowerCase();
|
|
109
|
+
const decoded = decodeBase58(trimmed);
|
|
110
|
+
if (!decoded || decoded.length !== 32)
|
|
111
|
+
return trimmed;
|
|
112
|
+
return toHex(decoded);
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Canonicalise an account id to base58 — the form the contract stamps on
|
|
116
|
+
* `sender` and keys `get_profiles` by.
|
|
117
|
+
*
|
|
118
|
+
* Returns the input unchanged if it is not a 32-byte account.
|
|
119
|
+
*/
|
|
120
|
+
export function toAccountBase58(id) {
|
|
121
|
+
const trimmed = (id ?? '').trim();
|
|
122
|
+
if (!trimmed)
|
|
123
|
+
return '';
|
|
124
|
+
if (!HEX_ACCOUNT.test(trimmed))
|
|
125
|
+
return trimmed;
|
|
126
|
+
return encodeBase58(fromHex(trimmed));
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* True when both ids name the same account, whichever encoding each is in.
|
|
130
|
+
*
|
|
131
|
+
* This is the comparison to reach for when checking a contract-sourced
|
|
132
|
+
* `sender` against an admin-sourced member id. Two ids that are not accounts
|
|
133
|
+
* compare false rather than accidentally matching as raw strings.
|
|
134
|
+
*/
|
|
135
|
+
export function sameAccount(a, b) {
|
|
136
|
+
const left = toAccountHex(a);
|
|
137
|
+
const right = toAccountHex(b);
|
|
138
|
+
return HEX_ACCOUNT.test(left) && left === right;
|
|
139
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/** Default codec: JSON text as a byte array. The wire carries `state` as
|
|
2
|
+
* `number[]`, not a string, so this encodes to bytes rather than to text. */
|
|
3
|
+
export function jsonCodec() {
|
|
4
|
+
return {
|
|
5
|
+
encode(value) {
|
|
6
|
+
return Array.from(new TextEncoder().encode(JSON.stringify(value)));
|
|
7
|
+
},
|
|
8
|
+
decode(bytes) {
|
|
9
|
+
return JSON.parse(new TextDecoder().decode(new Uint8Array(bytes)));
|
|
10
|
+
},
|
|
11
|
+
};
|
|
12
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import type { HttpClient } from '../http-client/index.js';
|
|
2
|
+
import type { SseClient } from '../events/index.js';
|
|
3
|
+
import { jsonCodec } from './codec.js';
|
|
4
|
+
import type { Codec, EphemeralEntry } from './types.js';
|
|
5
|
+
export { jsonCodec };
|
|
6
|
+
export type { Codec, EphemeralEntry };
|
|
7
|
+
/**
|
|
8
|
+
* Ephemeral presence: transient, encrypted, never-persisted state (cursors,
|
|
9
|
+
* typing, presence) that gossips between nodes without a WASM run or DAG
|
|
10
|
+
* growth.
|
|
11
|
+
*
|
|
12
|
+
* The write/read asymmetry is the model, not an oversight. `set` takes no
|
|
13
|
+
* author: you can only ever write your OWN slot, and the node resolves the
|
|
14
|
+
* author server-side from its owned context identity — which is also why a
|
|
15
|
+
* client cannot publish as somebody else. `subscribe` returns everyone's
|
|
16
|
+
* slots, so each carries its `author`. The store is N independent
|
|
17
|
+
* single-writer registers keyed by author; there is no merge across authors.
|
|
18
|
+
*
|
|
19
|
+
* There is a single read path: `subscribe`. On subscribing to a context, the
|
|
20
|
+
* node replays that context's current presence to this connection as
|
|
21
|
+
* ordinary `Ephemeral` events (carrying `ageMs`), before any live deltas
|
|
22
|
+
* (which carry no `ageMs`). There is no separate snapshot RPC.
|
|
23
|
+
*/
|
|
24
|
+
export declare class EphemeralClient {
|
|
25
|
+
private httpClient;
|
|
26
|
+
private sse;
|
|
27
|
+
constructor(opts: {
|
|
28
|
+
httpClient: HttpClient;
|
|
29
|
+
sse: SseClient;
|
|
30
|
+
});
|
|
31
|
+
/**
|
|
32
|
+
* Publish your own presence slice, replacing it wholesale.
|
|
33
|
+
*
|
|
34
|
+
* Rejects with an `RpcError` (not a bare `Error`), so a typed failure such as
|
|
35
|
+
* an oversized slice keeps its `type` and `data` — e.g. `SliceTooLarge` with
|
|
36
|
+
* the offending size — and is `instanceof RpcError` like every other RPC in
|
|
37
|
+
* this SDK.
|
|
38
|
+
*/
|
|
39
|
+
set<T>(contextId: string, state: T, codec?: Codec<T>): Promise<void>;
|
|
40
|
+
/**
|
|
41
|
+
* Observe presence changes for a context.
|
|
42
|
+
*
|
|
43
|
+
* This adds NO transport — it is a typed filter over the existing SSE event
|
|
44
|
+
* stream, which already carries `{ contextId, type, data }`. On subscribing,
|
|
45
|
+
* the node replays that context's current presence to this connection as
|
|
46
|
+
* ordinary `Ephemeral` events before any live deltas; a replayed entry
|
|
47
|
+
* carries `ageMs`, a live delta does not (never synthesized as `0` — absent
|
|
48
|
+
* and zero mean different things). Returns an unsubscribe function.
|
|
49
|
+
*/
|
|
50
|
+
subscribe<T>(contextId: string, handler: (entry: EphemeralEntry<T>) => void, codec?: Codec<T>): () => void;
|
|
51
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { jsonRpcCall } from '../rpc/index.js';
|
|
2
|
+
import { jsonCodec } from './codec.js';
|
|
3
|
+
export { jsonCodec };
|
|
4
|
+
/**
|
|
5
|
+
* Ephemeral presence: transient, encrypted, never-persisted state (cursors,
|
|
6
|
+
* typing, presence) that gossips between nodes without a WASM run or DAG
|
|
7
|
+
* growth.
|
|
8
|
+
*
|
|
9
|
+
* The write/read asymmetry is the model, not an oversight. `set` takes no
|
|
10
|
+
* author: you can only ever write your OWN slot, and the node resolves the
|
|
11
|
+
* author server-side from its owned context identity — which is also why a
|
|
12
|
+
* client cannot publish as somebody else. `subscribe` returns everyone's
|
|
13
|
+
* slots, so each carries its `author`. The store is N independent
|
|
14
|
+
* single-writer registers keyed by author; there is no merge across authors.
|
|
15
|
+
*
|
|
16
|
+
* There is a single read path: `subscribe`. On subscribing to a context, the
|
|
17
|
+
* node replays that context's current presence to this connection as
|
|
18
|
+
* ordinary `Ephemeral` events (carrying `ageMs`), before any live deltas
|
|
19
|
+
* (which carry no `ageMs`). There is no separate snapshot RPC.
|
|
20
|
+
*/
|
|
21
|
+
export class EphemeralClient {
|
|
22
|
+
constructor(opts) {
|
|
23
|
+
this.httpClient = opts.httpClient;
|
|
24
|
+
this.sse = opts.sse;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Publish your own presence slice, replacing it wholesale.
|
|
28
|
+
*
|
|
29
|
+
* Rejects with an `RpcError` (not a bare `Error`), so a typed failure such as
|
|
30
|
+
* an oversized slice keeps its `type` and `data` — e.g. `SliceTooLarge` with
|
|
31
|
+
* the offending size — and is `instanceof RpcError` like every other RPC in
|
|
32
|
+
* this SDK.
|
|
33
|
+
*/
|
|
34
|
+
async set(contextId, state, codec = jsonCodec()) {
|
|
35
|
+
await jsonRpcCall(this.httpClient, 'set_ephemeral', {
|
|
36
|
+
contextId,
|
|
37
|
+
state: codec.encode(state),
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Observe presence changes for a context.
|
|
42
|
+
*
|
|
43
|
+
* This adds NO transport — it is a typed filter over the existing SSE event
|
|
44
|
+
* stream, which already carries `{ contextId, type, data }`. On subscribing,
|
|
45
|
+
* the node replays that context's current presence to this connection as
|
|
46
|
+
* ordinary `Ephemeral` events before any live deltas; a replayed entry
|
|
47
|
+
* carries `ageMs`, a live delta does not (never synthesized as `0` — absent
|
|
48
|
+
* and zero mean different things). Returns an unsubscribe function.
|
|
49
|
+
*/
|
|
50
|
+
subscribe(contextId, handler, codec = jsonCodec()) {
|
|
51
|
+
const listener = (event) => {
|
|
52
|
+
const e = event;
|
|
53
|
+
if (e.type !== 'Ephemeral' || e.contextId !== contextId)
|
|
54
|
+
return;
|
|
55
|
+
const data = e.data;
|
|
56
|
+
if (!data?.author)
|
|
57
|
+
return;
|
|
58
|
+
// `removed` is omitted on an upsert, so normalize to a boolean here and
|
|
59
|
+
// spare every caller the truthiness rule.
|
|
60
|
+
const removed = Boolean(data.removed);
|
|
61
|
+
const entry = {
|
|
62
|
+
author: data.author,
|
|
63
|
+
state: removed || data.state === undefined ? undefined : codec.decode(data.state),
|
|
64
|
+
removed,
|
|
65
|
+
};
|
|
66
|
+
// `ageMs` is present only on a replayed seed entry; pass it through as-is
|
|
67
|
+
// rather than defaulting a live delta to 0.
|
|
68
|
+
if (data.ageMs !== undefined)
|
|
69
|
+
entry.ageMs = data.ageMs;
|
|
70
|
+
handler(entry);
|
|
71
|
+
};
|
|
72
|
+
this.sse.on('event', listener);
|
|
73
|
+
// Errors surface via the SSE client's own 'error' event; nothing more to
|
|
74
|
+
// do with them here.
|
|
75
|
+
void this.sse.connect().catch(() => undefined);
|
|
76
|
+
void this.sse.subscribe([contextId]).catch(() => undefined);
|
|
77
|
+
return () => {
|
|
78
|
+
this.sse.off('event', listener);
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/** Encoding for a presence slice. The node never deserializes it — the wire
|
|
2
|
+
* encoding is chosen client-side and travels client-to-client. */
|
|
3
|
+
export interface Codec<T> {
|
|
4
|
+
encode(value: T): number[];
|
|
5
|
+
decode(bytes: number[]): T;
|
|
6
|
+
}
|
|
7
|
+
/** One entry from `subscribe`. `state` is absent on a removal; `removed` is
|
|
8
|
+
* ABSENT (not false) on an upsert.
|
|
9
|
+
*
|
|
10
|
+
* On subscribing to a context, the node replays that context's current
|
|
11
|
+
* presence to this connection as ordinary `Ephemeral` events (same shape as a
|
|
12
|
+
* live delta), before any live deltas. `ageMs` distinguishes a replayed seed
|
|
13
|
+
* entry from a live one: it is ABSENT on a live delta (fresh at receipt) and
|
|
14
|
+
* PRESENT on a replayed entry, giving milliseconds since that author was last
|
|
15
|
+
* heard from, measured on the node. Relative, so no clock agreement between
|
|
16
|
+
* machines is needed. Bounded above by the node's 7s presence TTL. */
|
|
17
|
+
export interface EphemeralEntry<T> {
|
|
18
|
+
author: string;
|
|
19
|
+
state?: T;
|
|
20
|
+
removed?: boolean;
|
|
21
|
+
ageMs?: number;
|
|
22
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/events/sse.js
CHANGED
|
@@ -1,4 +1,11 @@
|
|
|
1
1
|
import { isGroupMigrationEvent } from './group.js';
|
|
2
|
+
import { AuthRevokedError, HTTPError } from '../http-client/index.js';
|
|
3
|
+
/**
|
|
4
|
+
* `x-auth-error` reasons that mean the whole token family is gone, mirroring
|
|
5
|
+
* the request path in `web-client.ts`. Anything else — `token_expired` above
|
|
6
|
+
* all — is recoverable by refreshing and reconnecting.
|
|
7
|
+
*/
|
|
8
|
+
const TERMINAL_AUTH_ERRORS = new Set(['token_reuse', 'token_revoked']);
|
|
2
9
|
export class SseClient {
|
|
3
10
|
constructor(opts) {
|
|
4
11
|
this.sessionId = null;
|
|
@@ -88,7 +95,8 @@ export class SseClient {
|
|
|
88
95
|
this.abortController = new AbortController();
|
|
89
96
|
try {
|
|
90
97
|
const token = await this.getAuthToken();
|
|
91
|
-
const
|
|
98
|
+
const url = `${this.baseUrl}/sse`;
|
|
99
|
+
const response = await fetch(url, {
|
|
92
100
|
headers: {
|
|
93
101
|
'Authorization': `Bearer ${token}`,
|
|
94
102
|
'Accept': 'text/event-stream',
|
|
@@ -96,7 +104,20 @@ export class SseClient {
|
|
|
96
104
|
signal: this.abortController.signal,
|
|
97
105
|
});
|
|
98
106
|
if (!response.ok) {
|
|
99
|
-
|
|
107
|
+
// Throw the same typed errors the request path throws. A bare
|
|
108
|
+
// `Error("SSE connection failed: 401")` forced callers to string-match
|
|
109
|
+
// the status and guess what it meant, and the honest guess — treat any
|
|
110
|
+
// 401 as fatal — logs the user out on a routine reconnect after the
|
|
111
|
+
// access token ages out, discarding a refresh token that was still
|
|
112
|
+
// good. The distinction is in the header; surface it.
|
|
113
|
+
const authError = response.headers.get('x-auth-error');
|
|
114
|
+
const bodyText = await response.text().catch(() => undefined);
|
|
115
|
+
if (response.status === 401 &&
|
|
116
|
+
authError &&
|
|
117
|
+
TERMINAL_AUTH_ERRORS.has(authError)) {
|
|
118
|
+
throw new AuthRevokedError(authError, response.status, response.statusText, url, response.headers, bodyText);
|
|
119
|
+
}
|
|
120
|
+
throw new HTTPError(response.status, response.statusText, url, response.headers, bodyText);
|
|
100
121
|
}
|
|
101
122
|
if (!response.body) {
|
|
102
123
|
throw new Error('SSE response has no body');
|
package/dist/index.browser.mjs
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
function N(n){let e=n.filter(Boolean);if(e.length===0)return;let t=AbortSignal;if(typeof t.any=="function")try{return t.any(e)}catch{}let s=new AbortController,r=i=>{s.abort(i.target.reason);for(let o of e)o.removeEventListener("abort",r)};for(let i of e){if(i.aborted)return AbortSignal.abort(i.reason);i.addEventListener("abort",r,{once:!0})}return s.signal}function _(n){if(typeof AbortSignal.timeout=="function")return AbortSignal.timeout(n);let e=new AbortController;return setTimeout(()=>{e.abort(new DOMException("Timeout","TimeoutError"))},n),e.signal}var oe=new Set(["token_reuse","token_revoked"]);function pe(n){if(n)try{let e=JSON.parse(n)?.error;if(typeof e=="string"&&e.trim()!=="")return e;let t=e?.message;if(typeof t=="string"&&t.trim()!=="")return t}catch{}}var y=class extends Error{constructor(t,s,r,i,o){let c=pe(o);super(c?`HTTP ${t} ${s}: ${c}`:`HTTP ${t} ${s}`);this.status=t;this.statusText=s;this.url=r;this.headers=i;this.bodyText=o;this.name="HTTPError"}toJSON(){return{status:this.status,statusText:this.statusText,url:this.url,headers:F(this.headers),bodyText:this.bodyText}}},I=class extends y{constructor(t,s,r,i,o,c){super(s,r,i,o,c);this.reason=t;this.name="AuthRevokedError";this.message=`Authentication revoked (${t}): HTTP ${s} ${r}`}};function F(n){let e={};return n.forEach((t,s)=>{e[s]=t}),e}var v=class{constructor(e){this.transport=e;this.refreshTokenPromise=null;this.onTokenRefreshPromise=null}async get(e,t){return this.request(e,{...t,method:"GET"})}async post(e,t,s){return this.request(e,{...s,method:"POST",body:t?JSON.stringify(t):void 0,headers:{"Content-Type":"application/json",...s?.headers}})}async put(e,t,s){return this.request(e,{...s,method:"PUT",body:t?JSON.stringify(t):void 0,headers:{"Content-Type":"application/json",...s?.headers}})}async delete(e,t){return this.request(e,{...t,method:"DELETE"})}async patch(e,t,s){return this.request(e,{...s,method:"PATCH",body:t?JSON.stringify(t):void 0,headers:{"Content-Type":"application/json",...s?.headers}})}async head(e,t){let s=await this.makeRequest(e,{...t,method:"HEAD",parse:"response"});return{headers:F(s.headers),status:s.status}}async request(e,t){return this.makeRequest(e,t)}async makeRequest(e,t,s=0,r){let o=this.buildUrl(e),c=r??Date.now(),m=this.createAbortSignal(t),u=await this.buildHeaders(t?.headers),d;u instanceof Headers?(d={},u.forEach((p,b)=>{d[b]=p})):d=u;let l={method:t?.method||"GET",headers:d},h=t?.body instanceof ReadableStream||typeof t?.body=="object"&&t?.body!==null&&"getReader"in t.body&&!(t.body instanceof Blob);(t?.body!==void 0&&!h||t?.body!==void 0&&h&&s===0)&&(l.body=t.body);let g;if(s>0&&r!==void 0){let p=t?.timeoutMs||this.transport.timeoutMs;if(p){let b=Date.now()-c,T=Math.max(0,p-b);g=this.createAbortSignal({...t,timeoutMs:T})}else g=this.createAbortSignal(t)}else g=m;g&&(l.signal=g),this.transport.credentials!==void 0&&(l.credentials=this.transport.credentials),t?.mode!==void 0&&(l.mode=t.mode),t?.cache!==void 0&&(l.cache=t.cache),t?.redirect!==void 0&&(l.redirect=t.redirect),t?.referrer!==void 0&&(l.referrer=t.referrer),t?.referrerPolicy!==void 0&&(l.referrerPolicy=t.referrerPolicy),t?.integrity!==void 0&&(l.integrity=t.integrity),t?.keepalive!==void 0&&(l.keepalive=t.keepalive);try{let p=await this.transport.fetch(o,l);if(!p.ok){let b=await this.getBodyText(p),T=new y(p.status,p.statusText,o,p.headers,b),P=p.headers.get("x-auth-error");if((p.status===401||p.status===403)&&P&&oe.has(P)){if(this.refreshTokenPromise=null,this.onTokenRefreshPromise=null,this.transport.onAuthRevoked)try{await this.transport.onAuthRevoked()}catch{}throw new I(P,p.status,p.statusText,o,p.headers,b)}let ie=t?.signal?.aborted===!0;if(p.status===401&&this.transport.refreshToken&&P==="token_expired"&&s<1&&!h&&!ie)try{let f=this.refreshTokenPromise;f||(f=this.transport.refreshToken(),this.refreshTokenPromise=f);let U=await f;if(!U||U.trim()==="")throw this.refreshTokenPromise=null,this.onTokenRefreshPromise=null,new Error("Refresh token returned empty token");if(!this.transport.onTokenRefresh)throw this.refreshTokenPromise=null,this.onTokenRefreshPromise=null,new Error("onTokenRefresh callback is required when refreshToken is provided. The callback must update the token storage so getAuthToken() returns the new token.");let S=this.onTokenRefreshPromise;S||(S=this.transport.onTokenRefresh(U),this.onTokenRefreshPromise=S),await S,this.refreshTokenPromise=null,this.onTokenRefreshPromise=null;let K=t?.timeoutMs||this.transport.timeoutMs;if(K&&r!==void 0){let ae=Date.now()-c;if(K-ae<=0)throw T}return this.makeRequest(e,t,s+1,c)}catch(f){throw this.refreshTokenPromise=null,this.onTokenRefreshPromise=null,f instanceof Error&&f.message.includes("onTokenRefresh")?f:T}throw T}return this.parseResponse(p,t?.parse)}catch(p){throw p instanceof y||p instanceof Error&&p.message.includes("onTokenRefresh")?p:new y(0,"Network Error",o,new Headers,p instanceof Error?p.message:"Unknown error")}}buildUrl(e){if(e.startsWith("http://")||e.startsWith("https://"))return e;let t=this.transport.baseUrl;return e.startsWith("/")?`${t.endsWith("/")?t.slice(0,-1):t}${e}`:`${t.endsWith("/")?t:`${t}/`}${e}`}createAbortSignal(e){let t=[];this.transport.defaultAbortSignal&&t.push(this.transport.defaultAbortSignal),e?.signal&&t.push(e.signal);let s=e?.timeoutMs||this.transport.timeoutMs;return s&&t.push(_(s)),t.length>0?N(t):void 0}async buildHeaders(e){let t={...this.transport.defaultHeaders};if(this.transport.getAuthToken)try{let s=await this.transport.getAuthToken();s&&s.trim()!==""&&(t.Authorization=`Bearer ${s}`)}catch{}return e&&(e instanceof Headers?e.forEach((s,r)=>{t[r]=s}):Array.isArray(e)?e.forEach(([s,r])=>{t[s]=r}):Object.assign(t,e)),t}async parseResponse(e,t){switch(t){case"text":return await e.text();case"blob":return await e.blob();case"arrayBuffer":return await e.arrayBuffer();case"response":return e;default:{let s=await e.text();if(!s)return null;try{return JSON.parse(s)}catch{throw new Error(`Expected a JSON response (status ${e.status}) but body was not JSON: ${s.slice(0,200)}`)}}}}async getBodyText(e){try{let t=await e.text();return t.length>65536?t.slice(0,65536)+"...":t}catch{return""}}};function q(n){return new v(n)}function k(n){let e={fetch:(t,s)=>globalThis.fetch(t,s),baseUrl:n.baseUrl,getAuthToken:n.getAuthToken,onTokenRefresh:n.onTokenRefresh,refreshToken:n.refreshToken,onAuthRevoked:n.onAuthRevoked,defaultHeaders:n.defaultHeaders,timeoutMs:n.timeoutMs,credentials:n.credentials,defaultAbortSignal:n.defaultAbortSignal};return q(e)}function E(n){let e=n.fetch??globalThis.fetch;if(!e)throw new Error("No fetch implementation available. Please provide a fetch implementation (e.g., undici.fetch) or use Node.js 18+ which has native fetch support.");let s={fetch:e===globalThis.fetch?(r,i)=>globalThis.fetch(r,i):(r,i)=>e(r,i),baseUrl:n.baseUrl,getAuthToken:n.getAuthToken,onTokenRefresh:n.onTokenRefresh,refreshToken:n.refreshToken,onAuthRevoked:n.onAuthRevoked,defaultHeaders:n.defaultHeaders,timeoutMs:n.timeoutMs,credentials:n.credentials,defaultAbortSignal:n.defaultAbortSignal};return q(s)}function L(n){return typeof window<"u"?k(n):E(n)}function ce(n,e){if(e<=0)return!1;let s=n?.name;if(s==="TimeoutError")return!0;if(s==="AbortError")return!1;let r=n;if("status"in r&&typeof r.status=="number"){let i=r.status;return i>=500||i===429}return s==="TypeError"}function le(n){let t=250*Math.pow(2,n-1),s=(Math.random()-.5)*.4*t;return Math.max(0,t+s)}async function M(n,e={}){let{attempts:t=3}=e,s;for(let r=1;r<=t;r++)try{return await n(r)}catch(i){if(s=i,!ce(s,t-r))throw s;let o=le(r),u=s.headers?.get?.("Retry-After");if(u){let d=parseInt(u,10);if(!isNaN(d))o=Math.max(o,d*1e3);else{let l=new Date(u);if(!isNaN(l.getTime())){let h=Math.max(0,l.getTime()-Date.now());o=Math.max(o,Math.min(h,6e4))}}}await new Promise(d=>setTimeout(d,o))}throw s||new Error("Retry failed without error")}function ue(n,e={}){return async(...t)=>M(()=>n(...t),e)}var C=class{constructor(e){this.httpClient=e}async getHealth(){let e=await this.httpClient.get("/auth/health");if(!e.data)throw new Error("Health response data is null");return e.data}async getIdentity(){let e=await this.httpClient.get("/admin/identity");if(!e.data)throw new Error("Identity response data is null");return e.data}async getProviders(){let e=await this.httpClient.get("/auth/providers");if(!e.data)throw new Error("Providers response data is null");return e.data}async getLoginPage(){return this.httpClient.get("/auth/login",{parse:"text"})}async generateTokens(e){return this.httpClient.post("/auth/token",e)}async refreshToken(e){return this.httpClient.post("/auth/refresh",e)}async generateMockTokens(e){return this.httpClient.post("/auth/mock-token",e)}async validateToken(e){try{let t=await this.validateTokenGet(e);return{valid:t.status===200,headers:t.headers,status:t.status}}catch{return{valid:!1,headers:{},status:401}}}async validateTokenGet(e){let t=await this.httpClient.head("/auth/validate",{headers:{Authorization:`Bearer ${e}`}});return{status:t.status,headers:t.headers}}async revokeTokens(e){let t=await this.httpClient.post("/admin/revoke",e);if(!t.data)throw new Error("Revoke tokens response data is null");return t.data}async listRootKeys(){let e=await this.httpClient.get("/admin/keys");if(!e.data)throw new Error("Root keys response data is null");return e.data}async createRootKey(e){let t=await this.httpClient.post("/admin/keys",e);if(!t.data)throw new Error("Create root key response data is null");return t.data}async deleteRootKey(e){return this.httpClient.delete(`/admin/keys/${e}`)}async listClientKeys(){let e=await this.httpClient.get("/admin/keys/clients");if(!e.data)throw new Error("Client keys response data is null");return e.data}async generateClientKey(e){return this.httpClient.post("/admin/client-key",e)}async deleteClientKey(e,t){return this.httpClient.delete(`/admin/keys/${e}/clients/${t}`)}async getKeyPermissions(e){return this.httpClient.get(`/admin/keys/${e}/permissions`)}async updateKeyPermissions(e,t){return this.httpClient.put(`/admin/keys/${e}/permissions`,{add:t.add,remove:t.remove})}};var x=class{async get(){throw new Error("HTTP client not implemented - use createAuthApiClientFromHttpClient with a real HTTP client")}async post(){throw new Error("HTTP client not implemented - use createAuthApiClientFromHttpClient with a real HTTP client")}async put(){throw new Error("HTTP client not implemented - use createAuthApiClientFromHttpClient with a real HTTP client")}async delete(){throw new Error("HTTP client not implemented - use createAuthApiClientFromHttpClient with a real HTTP client")}async patch(){throw new Error("HTTP client not implemented - use createAuthApiClientFromHttpClient with a real HTTP client")}async head(){throw new Error("HTTP client not implemented - use createAuthApiClientFromHttpClient with a real HTTP client")}async request(){throw new Error("HTTP client not implemented - use createAuthApiClientFromHttpClient with a real HTTP client")}};function Ne(n){let e=new x;return new C(e)}function _e(n){let e=new x;return new C(e)}function qe(n){let e=new x;return new C(e)}function z(n,e){return new C(n)}function a(n){return n?.data}function de(n,e){let[t,s]=Q(n),[r,i]=Q(e),o=t.split("."),c=r.split("."),m=Math.max(o.length,c.length);for(let h=0;h<m;h++){let g=X(o[h]??"0",c[h]??"0");if(g!==0)return g}if(s===void 0&&i===void 0)return 0;if(s===void 0)return 1;if(i===void 0)return-1;let u=s.split("."),d=i.split("."),l=Math.max(u.length,d.length);for(let h=0;h<l;h++){if(h>=u.length)return-1;if(h>=d.length)return 1;let g=X(u[h],d[h]);if(g!==0)return g}return 0}function Q(n){let e=n.split("+",1)[0],t=e.indexOf("-");return t===-1?[e,void 0]:[e.slice(0,t),e.slice(t+1)]}function X(n,e){let t=/^\d+$/.test(n),s=/^\d+$/.test(e);if(t&&s){let r=Number(n)-Number(e);return r<0?-1:r>0?1:0}return t?-1:s?1:n<e?-1:n>e?1:0}async function Y(n,e,t){return M(async()=>{let s=await fetch(n,{signal:AbortSignal.timeout(1e4)});if(!s.ok){let r=new Error(`registry ${e} fetch failed (${s.status}) for ${t}`);throw r.status=s.status,r}return s},{attempts:3})}var R=class{constructor(e){this.httpClient=e}async healthCheck(){return a(await this.httpClient.get("/admin-api/health"))}async isAuthed(){return this.httpClient.get("/admin-api/is-authed")}async installApplication(e){return a(await this.httpClient.post("/admin-api/install-application",e))}async installFromRegistry(e,t,s){let r=new URL(e).origin,i=new URL(`/api/v2/bundles/${encodeURIComponent(t)}/${encodeURIComponent(s)}`,r).toString(),c=await(await Y(i,"manifest",`${t}@${s}`)).json(),m=encodeURIComponent(c.package),u=encodeURIComponent(c.appVersion),d=`${r}/artifacts/${m}/${u}/${m}-${u}.mpk`;return this.installApplication({url:d,package:c.package,version:c.appVersion,metadata:[]})}async getRegistryVersions(e,t){let s=new URL("/api/v2/bundles",new URL(e).origin);s.searchParams.set("package",t);let i=await(await Y(s.toString(),"versions",t)).json();return(Array.isArray(i)?i:[]).map(o=>o.appVersion).filter(o=>typeof o=="string").sort((o,c)=>de(c,o))}async installDevApplication(e){return a(await this.httpClient.post("/admin-api/install-dev-application",e))}async uninstallApplication(e){return a(await this.httpClient.delete(`/admin-api/applications/${e}`))}async listApplications(){return a(await this.httpClient.get("/admin-api/applications"))}async getApplication(e){return a(await this.httpClient.get(`/admin-api/applications/${e}`))}async listApplicationVersions(e){return a(await this.httpClient.get(`/admin-api/applications/${e}/versions`))}async getApplicationAbi(e,t){let s=t?`?service_name=${encodeURIComponent(t)}`:"";return a(await this.httpClient.get(`/admin-api/applications/${e}/abi${s}`))}async listPackages(){let e=await this.httpClient.get("/admin-api/packages");return e?.data??e}async listPackageVersions(e){let t=await this.httpClient.get(`/admin-api/packages/${encodeURIComponent(e)}/versions`);return t?.data??t}async getLatestPackageVersion(e){return this.httpClient.get(`/admin-api/packages/${encodeURIComponent(e)}/latest`)}async createContext(e){let t={...e,initializationParams:e.initializationParams??[]};return a(await this.httpClient.post("/admin-api/contexts",t))}async deleteContext(e,t){return a(t?await this.httpClient.request(`/admin-api/contexts/${e}`,{method:"DELETE",body:JSON.stringify(t),headers:{"Content-Type":"application/json"}}):await this.httpClient.delete(`/admin-api/contexts/${e}`))}async getContexts(){return a(await this.httpClient.get("/admin-api/contexts"))}async getContext(e){return a(await this.httpClient.get(`/admin-api/contexts/${e}`))}async getContextsForApplication(e){return a(await this.httpClient.get(`/admin-api/contexts/for-application/${e}`))}async generateContextIdentity(){return a(await this.httpClient.post("/admin-api/identity/context",{}))}async getContextIdentities(e){return a(await this.httpClient.get(`/admin-api/contexts/${e}/identities`))}async getContextIdentitiesOwned(e){return a(await this.httpClient.get(`/admin-api/contexts/${e}/identities-owned`))}async joinContext(e){return a(await this.httpClient.post(`/admin-api/contexts/${e}/join`,{}))}async getContextGroup(e){return a(await this.httpClient.get(`/admin-api/contexts/${e}/group`))}async getContextStorage(e){return a(await this.httpClient.get(`/admin-api/contexts/${e}/storage`))}async syncContext(e){await this.httpClient.post(`/admin-api/contexts/sync/${e??""}`,{})}async resyncContext(e,t={}){return await this.httpClient.post(`/admin-api/contexts/${e}/resync`,t)??{contextId:e,resyncStarted:!0}}async inviteSpecializedNode(e){return a(await this.httpClient.post("/admin-api/contexts/invite-specialized-node",e))}async updateContextApplication(e,t){await this.httpClient.post(`/admin-api/contexts/${e}/application`,t)}async getContextsWithExecutorsForApplication(e){let t=await this.httpClient.get(`/admin-api/contexts/with-executors/for-application/${e}`);return Array.isArray(t)?t:t?.contexts??t?.data??[]}async uploadBlob(e){let t=new URLSearchParams;e.hash&&t.set("hash",e.hash),e.contextId&&t.set("context_id",e.contextId);let s=t.toString(),r=s?`/admin-api/blobs?${s}`:"/admin-api/blobs",i=a(await this.httpClient.request(r,{method:"PUT",body:e.data,headers:{"Content-Type":"application/octet-stream"}}));return{blobId:i.blob_id,size:i.size}}async deleteBlob(e){let t=await this.httpClient.delete(`/admin-api/blobs/${e}`);return{blobId:t.blob_id,deleted:t.deleted}}async listBlobs(){return{blobs:a(await this.httpClient.get("/admin-api/blobs")).blobs.map(t=>({blobId:t.blob_id,size:t.size}))}}async getBlob(e){return this.httpClient.get(`/admin-api/blobs/${e}`,{parse:"arrayBuffer"})}async getBlobInfo(e){let{headers:t}=await this.httpClient.head(`/admin-api/blobs/${e}`),s=Number(t["content-length"]);return{blobId:t["x-blob-id"]??e,size:Number.isFinite(s)?s:0,hash:t["x-blob-hash"],mimeType:t["x-blob-mime-type"]}}async createContextAlias(e){return a(await this.httpClient.post("/admin-api/alias/create/context",{alias:e.alias,contextId:e.contextId}))}async createApplicationAlias(e){return a(await this.httpClient.post("/admin-api/alias/create/application",{alias:e.alias,applicationId:e.applicationId}))}async lookupContextAlias(e){return a(await this.httpClient.post(`/admin-api/alias/lookup/context/${encodeURIComponent(e)}`,{}))}async lookupApplicationAlias(e){return a(await this.httpClient.post(`/admin-api/alias/lookup/application/${encodeURIComponent(e)}`,{}))}async deleteContextAlias(e){return a(await this.httpClient.post(`/admin-api/alias/delete/context/${encodeURIComponent(e)}`,{}))}async deleteApplicationAlias(e){return a(await this.httpClient.post(`/admin-api/alias/delete/application/${encodeURIComponent(e)}`,{}))}async listContextAliases(){return a(await this.httpClient.get("/admin-api/alias/list/context"))}async listApplicationAliases(){return a(await this.httpClient.get("/admin-api/alias/list/application"))}async listNamespaces(){return a(await this.httpClient.get("/admin-api/namespaces"))}async getNamespace(e){return a(await this.httpClient.get(`/admin-api/namespaces/${e}`))}async getNodeIdentity(){return a(await this.httpClient.get("/admin-api/identity"))}async getNamespaceIdentity(e){let t=await this.getNodeIdentity();return{namespaceId:e,publicKey:t.publicKey,account:t.accountId}}async listNamespacesForApplication(e){return a(await this.httpClient.get(`/admin-api/namespaces/for-application/${e}`))}async createNamespace(e){return a(await this.httpClient.post("/admin-api/namespaces",{upgradePolicy:"LazyOnAccess",...e}))}async deleteNamespace(e,t){return a(await this.httpClient.request(`/admin-api/namespaces/${e}`,{method:"DELETE",body:JSON.stringify(t??{}),headers:{"Content-Type":"application/json"}}))}async createNamespaceInvitation(e,t){return a(await this.httpClient.post(`/admin-api/namespaces/${e}/invite`,t??{}))}async joinNamespace(e,t){return a(await this.httpClient.post(`/admin-api/namespaces/${e}/join`,t,{timeoutMs:65e3}))}async createGroupInNamespace(e,t){return a(await this.httpClient.post(`/admin-api/namespaces/${e}/groups`,t??{}))}async listNamespaceGroups(e){return a(await this.httpClient.get(`/admin-api/namespaces/${e}/groups`))}async getGroupInfo(e){return a(await this.httpClient.get(`/admin-api/groups/${e}`))}async getDefaultCapabilities(e){return(await this.getGroupInfo(e)).defaultCapabilities}async getSubgroupVisibility(e){return(await this.getGroupInfo(e)).subgroupVisibility}async deleteGroup(e,t){return a(await this.httpClient.request(`/admin-api/groups/${e}`,{method:"DELETE",body:JSON.stringify(t??{}),headers:{"Content-Type":"application/json"}}))}async listGroupMembers(e){let t=await this.httpClient.get(`/admin-api/groups/${e}/members`);if(!Array.isArray(t?.members)){let s=String(e).replace(/[\r\n\t\s]/g,"").slice(0,64);throw new Error(`Invalid listGroupMembers response for group ${s}: missing or non-array \`members\` field`)}return t}async listGroupContexts(e){return a(await this.httpClient.get(`/admin-api/groups/${e}/contexts`))}async addGroupMembers(e,t){await this.httpClient.post(`/admin-api/groups/${e}/members`,t)}async removeGroupMembers(e,t){await this.httpClient.post(`/admin-api/groups/${e}/members/remove`,t)}async updateMemberRole(e,t,s){await this.httpClient.put(`/admin-api/groups/${e}/members/${t}/role`,s)}async getMemberCapabilities(e,t){return a(await this.httpClient.get(`/admin-api/groups/${e}/members/${t}/capabilities`))}async setMemberCapabilities(e,t,s){await this.httpClient.put(`/admin-api/groups/${e}/members/${t}/capabilities`,s)}async setDefaultCapabilities(e,t){await this.httpClient.put(`/admin-api/groups/${e}/settings/default-capabilities`,t)}async setSubgroupVisibility(e,t){await this.httpClient.put(`/admin-api/groups/${e}/settings/subgroup-visibility`,t)}async setTeeAdmissionPolicy(e,t){await this.httpClient.put(`/admin-api/groups/${e}/settings/tee-admission-policy`,t)}async getTeeAdmissionPolicy(e){let t=await this.httpClient.get(`/admin-api/groups/${e}/settings/tee-admission-policy`);return t.data??t}async setGroupMetadata(e,t){await this.httpClient.put(`/admin-api/groups/${e}/metadata`,t)}async getGroupMetadata(e){return(await this.httpClient.get(`/admin-api/groups/${e}/metadata`))?.data??null}async setMemberMetadata(e,t,s){await this.httpClient.put(`/admin-api/groups/${e}/members/${t}/metadata`,s)}async getMemberMetadata(e,t){return(await this.httpClient.get(`/admin-api/groups/${e}/members/${t}/metadata`))?.data??null}async setContextMetadata(e,t,s){await this.httpClient.put(`/admin-api/groups/${e}/contexts/${t}/metadata`,s)}async getContextMetadata(e,t){return(await this.httpClient.get(`/admin-api/groups/${e}/contexts/${t}/metadata`))?.data??null}async syncGroup(e,t){return a(await this.httpClient.post(`/admin-api/groups/${e}/sync`,t??{}))}async upgradeGroup(e,t){return a(await this.httpClient.post(`/admin-api/groups/${e}/upgrade`,t))}async getGroupUpgradeStatus(e){return a(await this.httpClient.get(`/admin-api/groups/${e}/upgrade/status`))}async getMigrationStatus(e){let t=encodeURIComponent(e);return this.httpClient.get(`/admin-api/groups/${t}/migration-status`)}async getCascadeStatus(e){let t=encodeURIComponent(e);return a(await this.httpClient.get(`/admin-api/groups/${t}/cascade-status`))}async retryGroupUpgrade(e,t){return a(await this.httpClient.post(`/admin-api/groups/${e}/upgrade/retry`,t??{}))}async reparentGroup(e,t){let s=await this.httpClient.post(`/admin-api/groups/${e}/reparent`,t);return s?.data??s}async listSubgroups(e){let t=await this.httpClient.get(`/admin-api/groups/${e}/subgroups`);return t.subgroups??t.data??[]}async detachContextFromGroup(e,t,s){await this.httpClient.post(`/admin-api/groups/${e}/contexts/${t}/remove`,s??{})}async createGroupInvitation(e,t){return a(await this.httpClient.post(`/admin-api/groups/${e}/invite`,t??{}))}async joinGroup(e){return a(await this.httpClient.post("/admin-api/groups/join",e))}async joinSubgroupInheritance(e){return a(await this.httpClient.post(`/admin-api/groups/${e}/join-via-inheritance`,{}))}async getTeeInfo(){return a(await this.httpClient.get("/admin-api/tee/info"))}async teeAttest(e){return a(await this.httpClient.post("/admin-api/tee/attest",e))}async teeVerifyQuote(e){return a(await this.httpClient.post("/admin-api/tee/verify-quote",e))}async getPeersCount(){return this.httpClient.get("/admin-api/peers")}async getNetworkStatus(){return this.httpClient.get("/admin-api/network/status")}async getUsage(){return this.httpClient.get("/admin-api/usage")}async getCertificate(){return this.httpClient.get("/admin-api/certificate",{parse:"text"})}async createGroup(e){return a(await this.httpClient.post("/admin-api/groups",{upgradePolicy:"LazyOnAccess",...e}))}async leaveGroup(e,t){await this.httpClient.post(`/admin-api/groups/${e}/leave`,t??{})}async leaveContext(e,t){await this.httpClient.post(`/admin-api/contexts/${e}/leave`,t??{})}async leaveNamespace(e,t){await this.httpClient.post(`/admin-api/namespaces/${e}/leave`,t??{})}async issueOwnershipProof(e,t){return this.httpClient.post(`/admin-api/groups/${e}/issue-ownership-proof`,t??{})}async issueNamespaceOwnershipProof(e,t){return this.httpClient.post(`/admin-api/groups/${e}/issue-namespace-ownership-proof`,t??{})}async setMemberAutoFollow(e,t,s){await this.httpClient.put(`/admin-api/groups/${e}/members/${t}/auto-follow`,s)}async abortMigration(e,t){return this.httpClient.post(`/admin-api/groups/${e}/migration/abort`,t??{})}};function Ke(n){return new R(k(n))}function Fe(n){return new R(E(n))}function ze(n){return new R(L(n))}function Z(n,e){return new R(n)}function O(n){try{let e=n.indexOf("#");if(e===-1)return null;let t=n.substring(e+1),s=new URLSearchParams(t),r=s.get("access_token");return r?{accessToken:r,refreshToken:s.get("refresh_token")??"",applicationId:s.get("application_id")??"",contextId:s.get("context_id")??"",contextIdentity:s.get("context_identity")??"",nodeUrl:s.get("node_url")??""}:null}catch{return null}}function W(n,e){let t=new URLSearchParams;return t.set("callback-url",e.callbackUrl),e.permissions&&e.permissions.length>0&&t.set("permissions",e.permissions.join(",")),t.set("mode",e.mode),e.packageName&&(t.set("package-name",e.packageName),e.packageVersion&&t.set("package-version",e.packageVersion),e.registryUrl&&t.set("registry-url",e.registryUrl)),`${n.replace(/\/+$/,"")}/auth/login?${t.toString()}`}var G=class extends Error{constructor(e,t,s,r){super(t),this.name="RpcError",this.code=e,this.data=s,this.type=r}},D=class{constructor(e){this.httpClient=e.httpClient}async execute(e){let t={jsonrpc:"2.0",id:1,method:"execute",params:{contextId:e.contextId,method:e.method,argsJson:e.argsJson??{}}},s=await this.httpClient.post("/jsonrpc",t);if(s.error){let r=s.error,i=r.code??-1,o=r.message??r.type??"RPC error";throw new G(i,o,r.data,r.type)}return s.result&&"output"in s.result?s.result.output:s.result}async migrateMyEntries(e){return this.execute({contextId:e,method:"migrate_my_entries"})}async countMyPending(e){return this.execute({contextId:e,method:"count_my_pending"})}};var he=new Set(["MigrationStarted","MigrationProgress","CascadeProgress","MigrationCompleted"]);function ee(n){return n.type!==void 0&&he.has(n.type)}var w=class{constructor(e){this.sessionId=null;this.abortController=null;this.reconnectTimer=null;this.subscribedContextIds=new Set;this.subscribedGroupIds=new Set;this.closed=!1;this.listeners={connect:[],event:[],error:[]};this.baseUrl=e.baseUrl.replace(/\/+$/,""),this.getAuthToken=e.getAuthToken,this.reconnectDelayMs=e.reconnectDelayMs??3e3}on(e,t){let s=e;if(s in this.listeners){let r=this.listeners[s];r.includes(t)||r.push(t)}}off(e,t){let s=e;if(s in this.listeners){let r=this.listeners[s],i=r.indexOf(t);i!==-1&&r.splice(i,1)}}onAppVersionChanged(e){let t=s=>{if(s.type!=="AppVersionChanged")return;let r=s.data;e({contextId:s.contextId,fromVersion:r?.fromVersion,toVersion:r?.toVersion})};return this.on("event",t),()=>this.off("event",t)}onMigrationEvent(e){let t=s=>{ee(s)&&e(s)};return this.on("event",t),()=>this.off("event",t)}emit(e,t){let s=e;if(s in this.listeners)for(let r of this.listeners[s])try{r(t)}catch{}}async connect(){if(!(this.abortController&&!this.closed)){this.closed=!1,this.abortController=new AbortController;try{let e=await this.getAuthToken(),t=await fetch(`${this.baseUrl}/sse`,{headers:{Authorization:`Bearer ${e}`,Accept:"text/event-stream"},signal:this.abortController.signal});if(!t.ok)throw new Error(`SSE connection failed: ${t.status}`);if(!t.body)throw new Error("SSE response has no body");this.readStream(t.body).catch(s=>{if(this.closed)return;let r=s instanceof Error?s:new Error(String(s));this.emit("error",r),this.scheduleReconnect()})}catch(e){if(this.closed)return;let t=e instanceof Error?e:new Error(String(e));this.emit("error",t),this.scheduleReconnect()}}}async readStream(e){let t=e.getReader(),s=new TextDecoder,r="";try{for(;;){let{done:i,value:o}=await t.read();if(i)break;r+=s.decode(o,{stream:!0});let c=r.split(`
|
|
2
|
-
`);r=c.pop()??"";for(let m of c)if(m.startsWith("data:")){let u=m.slice(5).trim();u&&this.handleMessage(u)}}if(r+=s.decode(),r.startsWith("data:")){let i=r.slice(5).trim();i&&this.handleMessage(i)}}catch(i){if(this.closed)return;let o=i instanceof Error?i:new Error(String(i));this.emit("error",o)}this.closed||this.scheduleReconnect()}handleMessage(e){try{let t=JSON.parse(e);if(t.type==="connect"&&t.session_id){this.sessionId=t.session_id,this.emit("connect",t.session_id),(this.subscribedContextIds.size>0||this.subscribedGroupIds.size>0)&&this.sendSubscription("subscribe",{contextIds:[...this.subscribedContextIds],groupIds:[...this.subscribedGroupIds]});return}if(!t.result)return;let s=t.result.data;if(Array.isArray(s))try{let r=new Uint8Array(s),i=new TextDecoder().decode(r);s=JSON.parse(i)}catch{}if(t.result.contextId){this.emit("event",{contextId:t.result.contextId,type:t.result.type,data:s});return}t.result.groupId&&this.emit("event",{groupId:t.result.groupId,type:t.result.type,data:s})}catch{}}async subscribe(e){let t=Array.isArray(e)?{contextIds:e}:e,s=(t.contextIds??[]).filter(i=>!this.subscribedContextIds.has(i)),r=(t.groupIds??[]).filter(i=>!this.subscribedGroupIds.has(i));for(let i of t.contextIds??[])this.subscribedContextIds.add(i);for(let i of t.groupIds??[])this.subscribedGroupIds.add(i);(s.length>0||r.length>0)&&this.sessionId&&await this.sendSubscription("subscribe",{contextIds:s,groupIds:r})}async unsubscribe(e){let t=Array.isArray(e)?{contextIds:e}:e,s=(t.contextIds??[]).filter(i=>this.subscribedContextIds.has(i)),r=(t.groupIds??[]).filter(i=>this.subscribedGroupIds.has(i));for(let i of t.contextIds??[])this.subscribedContextIds.delete(i);for(let i of t.groupIds??[])this.subscribedGroupIds.delete(i);(s.length>0||r.length>0)&&this.sessionId&&await this.sendSubscription("unsubscribe",{contextIds:s,groupIds:r})}async sendSubscription(e,t){try{let s=await this.getAuthToken(),r={};t.contextIds&&t.contextIds.length>0&&(r.contextIds=t.contextIds),t.groupIds&&t.groupIds.length>0&&(r.groupIds=t.groupIds);let i=await fetch(`${this.baseUrl}/sse/subscription`,{method:"POST",headers:{Authorization:`Bearer ${s}`,"Content-Type":"application/json"},body:JSON.stringify({id:this.sessionId,method:e,params:r})});i.ok||this.emit("error",new Error(`SSE ${e} failed: ${i.status}`))}catch(s){this.emit("error",s instanceof Error?s:new Error(`SSE ${e} failed`))}}forceReconnect(){this.abortController&&(this.abortController.abort(),this.abortController=null),this.sessionId=null,this.connect()}scheduleReconnect(){this.closed||(this.reconnectTimer&&clearTimeout(this.reconnectTimer),this.reconnectTimer=setTimeout(()=>{this.reconnectTimer=null,this.forceReconnect()},this.reconnectDelayMs))}close(){this.closed=!0,this.abortController&&(this.abortController.abort(),this.abortController=null),this.reconnectTimer&&(clearTimeout(this.reconnectTimer),this.reconnectTimer=null),this.sessionId=null,this.subscribedContextIds.clear(),this.subscribedGroupIds.clear()}};var $=class ${constructor(e){this.ws=null;this.closed=!1;this.reconnectAttempt=0;this.reconnectTimer=null;this.subscribedContextIds=new Set;this.subscribedGroupIds=new Set;this.listeners={connect:[],event:[],error:[]};this.baseUrl=e.baseUrl.replace(/\/+$/,""),this.getAuthToken=e.getAuthToken}on(e,t){let s=e;if(s in this.listeners){let r=this.listeners[s];r.includes(t)||r.push(t)}}off(e,t){let s=e;if(s in this.listeners){let r=this.listeners[s],i=r.indexOf(t);i!==-1&&r.splice(i,1)}}emit(e,t){let s=e;if(s in this.listeners)for(let r of this.listeners[s])try{r(t)}catch{}}async connect(){if(!(this.ws&&(this.ws.readyState===0||this.ws.readyState===1))){this.closed=!1;try{let e=await this.getAuthToken();if(!e)throw new Error("No authentication token available for WebSocket connection");let t=this.baseUrl.replace(/^http/,"ws");this.ws=new WebSocket(`${t}/ws?token=${encodeURIComponent(e)}`),this.ws.onopen=()=>{this.reconnectAttempt=0,this.emit("connect"),this.resubscribeAfterReconnect()},this.ws.onmessage=s=>{this.handleMessage(s.data)},this.ws.onerror=()=>{this.emit("error",new Error("WebSocket error"))},this.ws.onclose=()=>{this.closed||this.scheduleReconnect()}}catch(e){if(this.closed)return;let t=e instanceof Error?e:new Error(String(e));this.emit("error",t),this.scheduleReconnect()}}}handleMessage(e){if(typeof e=="string")try{let t=JSON.parse(e);if(!t.result)return;let s=t.result.data;if(Array.isArray(s))try{let r=new Uint8Array(s),i=new TextDecoder().decode(r);s=JSON.parse(i)}catch{}if(t.result.contextId){this.emit("event",{contextId:t.result.contextId,type:t.result.type,data:s});return}t.result.groupId&&this.emit("event",{groupId:t.result.groupId,type:t.result.type,data:s})}catch{}}subscribe(e){let t=Array.isArray(e)?{contextIds:e}:e;for(let s of t.contextIds??[])this.subscribedContextIds.add(s);for(let s of t.groupIds??[])this.subscribedGroupIds.add(s);this.ws&&this.ws.readyState===1&&this.sendMessage({id:null,method:"subscribe",params:this.buildSubscriptionParams(t.contextIds??[],t.groupIds??[])})}unsubscribe(e){let t=Array.isArray(e)?{contextIds:e}:e;for(let s of t.contextIds??[])this.subscribedContextIds.delete(s);for(let s of t.groupIds??[])this.subscribedGroupIds.delete(s);this.ws&&this.ws.readyState===1&&this.sendMessage({id:null,method:"unsubscribe",params:this.buildSubscriptionParams(t.contextIds??[],t.groupIds??[])})}resubscribeAfterReconnect(){this.subscribedContextIds.size===0&&this.subscribedGroupIds.size===0||this.sendMessage({id:null,method:"subscribe",params:this.buildSubscriptionParams([...this.subscribedContextIds],[...this.subscribedGroupIds])})}buildSubscriptionParams(e,t){let s={};return e.length>0&&(s.contextIds=e),t.length>0&&(s.groupIds=t),s}sendMessage(e){this.ws&&this.ws.readyState===1&&this.ws.send(JSON.stringify(e))}scheduleReconnect(){if(this.closed)return;this.reconnectTimer&&clearTimeout(this.reconnectTimer);let e=Math.min(1e3*Math.pow(2,this.reconnectAttempt),$.MAX_BACKOFF_MS);this.reconnectAttempt++,this.reconnectTimer=setTimeout(()=>{this.reconnectTimer=null,this.connect()},e)}close(){this.closed=!0,this.reconnectTimer&&(clearTimeout(this.reconnectTimer),this.reconnectTimer=null),this.ws&&(this.ws.onclose=null,this.ws.close(),this.ws=null),this.subscribedContextIds.clear(),this.subscribedGroupIds.clear()}};$.MAX_BACKOFF_MS=3e4;var A=$;var me="mero-js:token-refresh";function ge(){let e=globalThis.navigator?.locks;return e&&typeof e.request=="function"?e:null}function V(n,e){try{let t=n.split(".");if(t.length===3){let s=t[1].replace(/-/g,"+").replace(/_/g,"/");for(;s.length%4;)s+="=";let r=JSON.parse(atob(s));if(typeof r.exp=="number")return r.exp*1e3}}catch{}return e}var H=class{constructor(e){this.tokenData=null;this.refreshPromise=null;this.rpcClient=null;this.sseClient=null;this.wsClient=null;this.wsWarned=!1;this.config={timeoutMs:1e4,...e},this.tokenStore=e.tokenStore??null,this.tokenStore&&(this.tokenData=this.tokenStore.getTokens());let t=typeof window<"u"&&"__TAURI_INTERNALS__"in window;this.httpClient=k({baseUrl:this.config.baseUrl,getAuthToken:async()=>(await this.getValidToken())?.access_token||"",refreshToken:async()=>(await this.performTokenRefresh()).access_token,onTokenRefresh:async s=>{this.tokenData&&(this.tokenData.access_token=s,this.tokenStore?.setTokens(this.tokenData))},onAuthRevoked:async()=>{this.clearToken();try{await this.config.onAuthRevoked?.()}catch{}},timeoutMs:this.config.timeoutMs,credentials:this.config.requestCredentials??(t?"omit":void 0)}),this.authClient=z(this.httpClient,{baseUrl:this.config.baseUrl,getAuthToken:async()=>(await this.getValidToken())?.access_token||"",timeoutMs:this.config.timeoutMs}),this.adminClient=Z(this.httpClient,{baseUrl:this.config.baseUrl,getAuthToken:async()=>(await this.getValidToken())?.access_token||"",timeoutMs:this.config.timeoutMs})}get auth(){return this.authClient}get admin(){return this.adminClient}get rpc(){return this.rpcClient||(this.rpcClient=new D({httpClient:this.httpClient})),this.rpcClient}get events(){return this.sseClient||(this.sseClient=new w({baseUrl:this.config.baseUrl,getAuthToken:async()=>(await this.getValidToken())?.access_token||""})),this.sseClient}get ws(){return this.wsWarned||(this.wsWarned=!0,console.warn("[mero-js] WsClient is experimental. Use mero.events (SSE) for production.")),this.wsClient||(this.wsClient=new A({baseUrl:this.config.baseUrl,getAuthToken:async()=>(await this.getValidToken())?.access_token||""})),this.wsClient}async authenticate(e){let t=e||this.config.credentials;if(!t)throw new Error("No credentials provided for authentication");try{let s={auth_method:"user_password",public_key:t.username,client_name:"mero-js-sdk",permissions:["admin"],timestamp:Math.floor(Date.now()/1e3),provider_data:{username:t.username,password:t.password}},r=await this.authClient.generateTokens(s),i=r.data.access_token;return this.tokenData={access_token:i,refresh_token:r.data.refresh_token,expires_at:V(i,Date.now()+36e5)},this.tokenStore?.setTokens(this.tokenData),this.tokenData}catch(s){throw new Error(`Authentication failed: ${s instanceof Error?s.message:"Unknown error"}`)}}async getValidToken(){return this.tokenData}async performTokenRefresh(){if(this.refreshPromise)return this.refreshPromise;let e=this.tokenData?.access_token,t=this.withRefreshLock(()=>this.performTokenRefreshLocked(e));this.refreshPromise=t;try{return await t}finally{this.refreshPromise===t&&(this.refreshPromise=null)}}withRefreshLock(e){let t=ge();return t?t.request(me,e):e()}async performTokenRefreshLocked(e){let t=this.tokenStore?.getTokens()??null;if(t?.refresh_token&&(this.tokenData=t,e&&t.access_token!==e))return t;if(!this.tokenData?.refresh_token)throw new Error("No refresh token available");try{let s=await this.authClient.refreshToken({access_token:this.tokenData.access_token,refresh_token:this.tokenData.refresh_token}),r=s.data.access_token;return this.tokenData={access_token:r,refresh_token:s.data.refresh_token,expires_at:V(r,Date.now()+36e5)},this.tokenStore?.setTokens(this.tokenData),this.tokenData}catch(s){throw new Error(`Token refresh failed: ${s instanceof Error?s.message:"Unknown error"}`)}}clearToken(){this.refreshPromise=null,this.tokenData=null,this.tokenStore?.clear()}isAuthenticated(){return this.tokenData!==null}setTokenData(e){let t=e.expires_at||V(e.access_token,Date.now()+36e5);this.tokenData={...e,expires_at:t},this.tokenStore?.setTokens(this.tokenData)}getTokenData(){return this.tokenData}close(){this.sseClient?.close(),this.wsClient?.close()}static parseAuthCallback(e){return O(e)}static buildAuthLoginUrl(e,t){return W(e,t)}};function fe(n){return new H(n)}var B=class{constructor(){this.tokens=null}getTokens(){return this.tokens}setTokens(e){this.tokens=e}clear(){this.tokens=null}},ye="mero-tokens",j=class{constructor(e=ye){this.key=e}getTokens(){try{if(typeof localStorage>"u")return null;let e=localStorage.getItem(this.key);if(!e)return null;let t=JSON.parse(e);return t&&t.access_token&&t.refresh_token?{access_token:t.access_token,refresh_token:t.refresh_token,expires_at:typeof t.expires_at=="number"?t.expires_at:Date.now()+36e5}:null}catch{return null}}setTokens(e){try{if(typeof localStorage>"u")return;localStorage.setItem(this.key,JSON.stringify(e))}catch{}}clear(){try{if(typeof localStorage>"u")return;localStorage.removeItem(this.key)}catch{}}};var J=class{constructor(e={}){this.baseUrl=(e.cloudBaseUrl||"https://cloud.calimero.network").replace(/\/+$/,"")}enableHA(e){let t=new URLSearchParams({group_id:e.groupId,context_id:e.contextId});e.redirectUrl&&t.set("redirect_url",e.redirectUrl),window.open(`${this.baseUrl}/enable-ha?${t.toString()}`)}disableHA(e){let t=new URLSearchParams({group_id:e.groupId,context_id:e.contextId});e.redirectUrl&&t.set("redirect_url",e.redirectUrl),window.open(`${this.baseUrl}/disable-ha?${t.toString()}`)}};var Ct={CAN_CREATE_CONTEXT:1,CAN_INVITE_MEMBERS:2,CAN_JOIN_OPEN_SUBGROUPS:4,MANAGE_MEMBERS:8,MANAGE_APPLICATION:16,CAN_CREATE_SUBGROUP:32,CAN_DELETE_SUBGROUP:64,CAN_MANAGE_VISIBILITY:128,CAN_MANAGE_METADATA:256};function Rt(n,e){let t=e>>>0;return(n&t)>>>0===t}function bt(n,e){return(n|e)>>>0}function kt(n,e){return(n&~e)>>>0}var te=[2428,2429,2528,2529],Ce="localhost",Re=2e3;function se(n){return`http://${Ce}:${n}`}function ne(n,e){let t=n.endsWith("/")?n:`${n}/`;return new URL(e,t).toString()}async function re(n,e={}){let{timeoutMs:t=Re,signal:s}=e;if(s?.aborted)return!1;let r=new AbortController,i=()=>r.abort(),o=s;o&&o.addEventListener("abort",i,{once:!0});let c=setTimeout(()=>r.abort(),t);try{let m=ne(n,"admin-api/health"),u=await fetch(m,{method:"GET",signal:r.signal});if(!u.ok)return!1;try{let d=await u.json(),l=d?.data?.status!==void 0?d?.data?.status:d?.status;return l===void 0?!0:typeof l=="string"&&l.toLowerCase()==="alive"}catch{return!0}}catch{return!1}finally{clearTimeout(c),o&&o.removeEventListener("abort",i)}}async function be(n={}){let{ports:e=te,timeoutMs:t,signal:s}=n;return(await Promise.all(e.map(async i=>{let o=se(i);return await re(o,{timeoutMs:t,signal:s})?o:null}))).filter(i=>i!==null)}export{R as AdminApiClient,C as AuthApiClient,I as AuthRevokedError,Ct as CAPABILITIES,J as CloudClient,te as DEFAULT_LOCAL_NODE_PORTS,y as HTTPError,j as LocalStorageTokenStore,B as MemoryTokenStore,H as MeroJs,D as RpcClient,G as RpcError,w as SseClient,v as WebHttpClient,A as WsClient,W as buildAuthLoginUrl,N as combineSignals,de as compareSemver,ze as createAdminApiClient,Z as createAdminApiClientFromHttpClient,qe as createAuthApiClient,z as createAuthApiClientFromHttpClient,Ke as createBrowserAdminApiClient,Ne as createBrowserAuthApiClient,k as createBrowserHttpClient,q as createHttpClient,fe as createMeroJs,Fe as createNodeAdminApiClient,_e as createNodeAuthApiClient,E as createNodeHttpClient,ue as createRetryableMethod,_ as createTimeoutSignal,L as createUniversalHttpClient,be as discoverLocalNodes,Rt as hasCap,se as localNodeUrl,ne as nodeEndpoint,O as parseAuthCallback,re as probeNodeHealth,bt as withCap,M as withRetry,kt as withoutCap};
|
|
1
|
+
function L(n){let e=n.filter(Boolean);if(e.length===0)return;let t=AbortSignal;if(typeof t.any=="function")try{return t.any(e)}catch{}let s=new AbortController,r=i=>{s.abort(i.target.reason);for(let a of e)a.removeEventListener("abort",r)};for(let i of e){if(i.aborted)return AbortSignal.abort(i.reason);i.addEventListener("abort",r,{once:!0})}return s.signal}function O(n){if(typeof AbortSignal.timeout=="function")return AbortSignal.timeout(n);let e=new AbortController;return setTimeout(()=>{e.abort(new DOMException("Timeout","TimeoutError"))},n),e.signal}var he=new Set(["token_reuse","token_revoked"]);function me(n){if(n)try{let e=JSON.parse(n)?.error;if(typeof e=="string"&&e.trim()!=="")return e;let t=e?.message;if(typeof t=="string"&&t.trim()!=="")return t}catch{}}var f=class extends Error{constructor(t,s,r,i,a){let p=me(a);super(p?`HTTP ${t} ${s}: ${p}`:`HTTP ${t} ${s}`);this.status=t;this.statusText=s;this.url=r;this.headers=i;this.bodyText=a;this.name="HTTPError"}toJSON(){return{status:this.status,statusText:this.statusText,url:this.url,headers:ee(this.headers),bodyText:this.bodyText}}},k=class extends f{constructor(t,s,r,i,a,p){super(s,r,i,a,p);this.reason=t;this.name="AuthRevokedError";this.message=`Authentication revoked (${t}): HTTP ${s} ${r}`}};function ee(n){let e={};return n.forEach((t,s)=>{e[s]=t}),e}var x=class{constructor(e){this.transport=e;this.refreshTokenPromise=null;this.onTokenRefreshPromise=null}async get(e,t){return this.request(e,{...t,method:"GET"})}async post(e,t,s){return this.request(e,{...s,method:"POST",body:t?JSON.stringify(t):void 0,headers:{"Content-Type":"application/json",...s?.headers}})}async put(e,t,s){return this.request(e,{...s,method:"PUT",body:t?JSON.stringify(t):void 0,headers:{"Content-Type":"application/json",...s?.headers}})}async delete(e,t){return this.request(e,{...t,method:"DELETE"})}async patch(e,t,s){return this.request(e,{...s,method:"PATCH",body:t?JSON.stringify(t):void 0,headers:{"Content-Type":"application/json",...s?.headers}})}async head(e,t){let s=await this.makeRequest(e,{...t,method:"HEAD",parse:"response"});return{headers:ee(s.headers),status:s.status}}async request(e,t){return this.makeRequest(e,t)}async makeRequest(e,t,s=0,r){let a=this.buildUrl(e),p=r??Date.now(),m=this.createAbortSignal(t),l=await this.buildHeaders(t?.headers),d;l instanceof Headers?(d={},l.forEach((c,R)=>{d[R]=c})):d=l;let u={method:t?.method||"GET",headers:d},h=t?.body instanceof ReadableStream||typeof t?.body=="object"&&t?.body!==null&&"getReader"in t.body&&!(t.body instanceof Blob);(t?.body!==void 0&&!h||t?.body!==void 0&&h&&s===0)&&(u.body=t.body);let g;if(s>0&&r!==void 0){let c=t?.timeoutMs||this.transport.timeoutMs;if(c){let R=Date.now()-p,v=Math.max(0,c-R);g=this.createAbortSignal({...t,timeoutMs:v})}else g=this.createAbortSignal(t)}else g=m;g&&(u.signal=g),this.transport.credentials!==void 0&&(u.credentials=this.transport.credentials),t?.mode!==void 0&&(u.mode=t.mode),t?.cache!==void 0&&(u.cache=t.cache),t?.redirect!==void 0&&(u.redirect=t.redirect),t?.referrer!==void 0&&(u.referrer=t.referrer),t?.referrerPolicy!==void 0&&(u.referrerPolicy=t.referrerPolicy),t?.integrity!==void 0&&(u.integrity=t.integrity),t?.keepalive!==void 0&&(u.keepalive=t.keepalive);try{let c=await this.transport.fetch(a,u);if(!c.ok){let R=await this.getBodyText(c),v=new f(c.status,c.statusText,a,c.headers,R),E=c.headers.get("x-auth-error");if((c.status===401||c.status===403)&&E&&he.has(E)){if(this.refreshTokenPromise=null,this.onTokenRefreshPromise=null,this.transport.onAuthRevoked)try{await this.transport.onAuthRevoked()}catch{}throw new k(E,c.status,c.statusText,a,c.headers,R)}let ue=t?.signal?.aborted===!0;if(c.status===401&&this.transport.refreshToken&&E==="token_expired"&&s<1&&!h&&!ue)try{let y=this.refreshTokenPromise;y||(y=this.transport.refreshToken(),this.refreshTokenPromise=y);let q=await y;if(!q||q.trim()==="")throw this.refreshTokenPromise=null,this.onTokenRefreshPromise=null,new Error("Refresh token returned empty token");if(!this.transport.onTokenRefresh)throw this.refreshTokenPromise=null,this.onTokenRefreshPromise=null,new Error("onTokenRefresh callback is required when refreshToken is provided. The callback must update the token storage so getAuthToken() returns the new token.");let I=this.onTokenRefreshPromise;I||(I=this.transport.onTokenRefresh(q),this.onTokenRefreshPromise=I),await I,this.refreshTokenPromise=null,this.onTokenRefreshPromise=null;let Z=t?.timeoutMs||this.transport.timeoutMs;if(Z&&r!==void 0){let de=Date.now()-p;if(Z-de<=0)throw v}return this.makeRequest(e,t,s+1,p)}catch(y){throw this.refreshTokenPromise=null,this.onTokenRefreshPromise=null,y instanceof Error&&y.message.includes("onTokenRefresh")?y:v}throw v}return this.parseResponse(c,t?.parse)}catch(c){throw c instanceof f||c instanceof Error&&c.message.includes("onTokenRefresh")?c:new f(0,"Network Error",a,new Headers,c instanceof Error?c.message:"Unknown error")}}buildUrl(e){if(e.startsWith("http://")||e.startsWith("https://"))return e;let t=this.transport.baseUrl;return e.startsWith("/")?`${t.endsWith("/")?t.slice(0,-1):t}${e}`:`${t.endsWith("/")?t:`${t}/`}${e}`}createAbortSignal(e){let t=[];this.transport.defaultAbortSignal&&t.push(this.transport.defaultAbortSignal),e?.signal&&t.push(e.signal);let s=e?.timeoutMs||this.transport.timeoutMs;return s&&t.push(O(s)),t.length>0?L(t):void 0}async buildHeaders(e){let t={...this.transport.defaultHeaders};if(this.transport.getAuthToken)try{let s=await this.transport.getAuthToken();s&&s.trim()!==""&&(t.Authorization=`Bearer ${s}`)}catch{}return e&&(e instanceof Headers?e.forEach((s,r)=>{t[r]=s}):Array.isArray(e)?e.forEach(([s,r])=>{t[s]=r}):Object.assign(t,e)),t}async parseResponse(e,t){switch(t){case"text":return await e.text();case"blob":return await e.blob();case"arrayBuffer":return await e.arrayBuffer();case"response":return e;default:{let s=await e.text();if(!s)return null;try{return JSON.parse(s)}catch{throw new Error(`Expected a JSON response (status ${e.status}) but body was not JSON: ${s.slice(0,200)}`)}}}}async getBodyText(e){try{let t=await e.text();return t.length>65536?t.slice(0,65536)+"...":t}catch{return""}}};function W(n){return new x(n)}function A(n){let e={fetch:(t,s)=>globalThis.fetch(t,s),baseUrl:n.baseUrl,getAuthToken:n.getAuthToken,onTokenRefresh:n.onTokenRefresh,refreshToken:n.refreshToken,onAuthRevoked:n.onAuthRevoked,defaultHeaders:n.defaultHeaders,timeoutMs:n.timeoutMs,credentials:n.credentials,defaultAbortSignal:n.defaultAbortSignal};return W(e)}function M(n){let e=n.fetch??globalThis.fetch;if(!e)throw new Error("No fetch implementation available. Please provide a fetch implementation (e.g., undici.fetch) or use Node.js 18+ which has native fetch support.");let s={fetch:e===globalThis.fetch?(r,i)=>globalThis.fetch(r,i):(r,i)=>e(r,i),baseUrl:n.baseUrl,getAuthToken:n.getAuthToken,onTokenRefresh:n.onTokenRefresh,refreshToken:n.refreshToken,onAuthRevoked:n.onAuthRevoked,defaultHeaders:n.defaultHeaders,timeoutMs:n.timeoutMs,credentials:n.credentials,defaultAbortSignal:n.defaultAbortSignal};return W(s)}function j(n){return typeof window<"u"?A(n):M(n)}function ge(n,e){if(e<=0)return!1;let s=n?.name;if(s==="TimeoutError")return!0;if(s==="AbortError")return!1;let r=n;if("status"in r&&typeof r.status=="number"){let i=r.status;return i>=500||i===429}return s==="TypeError"}function fe(n){let t=250*Math.pow(2,n-1),s=(Math.random()-.5)*.4*t;return Math.max(0,t+s)}async function G(n,e={}){let{attempts:t=3}=e,s;for(let r=1;r<=t;r++)try{return await n(r)}catch(i){if(s=i,!ge(s,t-r))throw s;let a=fe(r),l=s.headers?.get?.("Retry-After");if(l){let d=parseInt(l,10);if(!isNaN(d))a=Math.max(a,d*1e3);else{let u=new Date(l);if(!isNaN(u.getTime())){let h=Math.max(0,u.getTime()-Date.now());a=Math.max(a,Math.min(h,6e4))}}}await new Promise(d=>setTimeout(d,a))}throw s||new Error("Retry failed without error")}function ye(n,e={}){return async(...t)=>G(()=>n(...t),e)}var C=class{constructor(e){this.httpClient=e}async getHealth(){let e=await this.httpClient.get("/auth/health");if(!e.data)throw new Error("Health response data is null");return e.data}async getIdentity(){let e=await this.httpClient.get("/admin/identity");if(!e.data)throw new Error("Identity response data is null");return e.data}async getProviders(){let e=await this.httpClient.get("/auth/providers");if(!e.data)throw new Error("Providers response data is null");return e.data}async getLoginPage(){return this.httpClient.get("/auth/login",{parse:"text"})}async generateTokens(e){return this.httpClient.post("/auth/token",e)}async refreshToken(e){return this.httpClient.post("/auth/refresh",e)}async generateMockTokens(e){return this.httpClient.post("/auth/mock-token",e)}async validateToken(e){try{let t=await this.validateTokenGet(e);return{valid:t.status===200,headers:t.headers,status:t.status}}catch{return{valid:!1,headers:{},status:401}}}async validateTokenGet(e){let t=await this.httpClient.head("/auth/validate",{headers:{Authorization:`Bearer ${e}`}});return{status:t.status,headers:t.headers}}async revokeTokens(e){let t=await this.httpClient.post("/admin/revoke",e);if(!t.data)throw new Error("Revoke tokens response data is null");return t.data}async listRootKeys(){let e=await this.httpClient.get("/admin/keys");if(!e.data)throw new Error("Root keys response data is null");return e.data}async createRootKey(e){let t=await this.httpClient.post("/admin/keys",e);if(!t.data)throw new Error("Create root key response data is null");return t.data}async deleteRootKey(e){return this.httpClient.delete(`/admin/keys/${e}`)}async listClientKeys(){let e=await this.httpClient.get("/admin/keys/clients");if(!e.data)throw new Error("Client keys response data is null");return e.data}async generateClientKey(e){return this.httpClient.post("/admin/client-key",e)}async deleteClientKey(e,t){return this.httpClient.delete(`/admin/keys/${e}/clients/${t}`)}async getKeyPermissions(e){return this.httpClient.get(`/admin/keys/${e}/permissions`)}async updateKeyPermissions(e,t){return this.httpClient.put(`/admin/keys/${e}/permissions`,{add:t.add,remove:t.remove})}};var D=class{async get(){throw new Error("HTTP client not implemented - use createAuthApiClientFromHttpClient with a real HTTP client")}async post(){throw new Error("HTTP client not implemented - use createAuthApiClientFromHttpClient with a real HTTP client")}async put(){throw new Error("HTTP client not implemented - use createAuthApiClientFromHttpClient with a real HTTP client")}async delete(){throw new Error("HTTP client not implemented - use createAuthApiClientFromHttpClient with a real HTTP client")}async patch(){throw new Error("HTTP client not implemented - use createAuthApiClientFromHttpClient with a real HTTP client")}async head(){throw new Error("HTTP client not implemented - use createAuthApiClientFromHttpClient with a real HTTP client")}async request(){throw new Error("HTTP client not implemented - use createAuthApiClientFromHttpClient with a real HTTP client")}};function Qe(n){let e=new D;return new C(e)}function Xe(n){let e=new D;return new C(e)}function Ye(n){let e=new D;return new C(e)}function te(n,e){return new C(n)}function o(n){return n?.data}function Ce(n,e){let[t,s]=se(n),[r,i]=se(e),a=t.split("."),p=r.split("."),m=Math.max(a.length,p.length);for(let h=0;h<m;h++){let g=ne(a[h]??"0",p[h]??"0");if(g!==0)return g}if(s===void 0&&i===void 0)return 0;if(s===void 0)return 1;if(i===void 0)return-1;let l=s.split("."),d=i.split("."),u=Math.max(l.length,d.length);for(let h=0;h<u;h++){if(h>=l.length)return-1;if(h>=d.length)return 1;let g=ne(l[h],d[h]);if(g!==0)return g}return 0}function se(n){let e=n.split("+",1)[0],t=e.indexOf("-");return t===-1?[e,void 0]:[e.slice(0,t),e.slice(t+1)]}function ne(n,e){let t=/^\d+$/.test(n),s=/^\d+$/.test(e);if(t&&s){let r=Number(n)-Number(e);return r<0?-1:r>0?1:0}return t?-1:s?1:n<e?-1:n>e?1:0}async function re(n,e,t){return G(async()=>{let s=await fetch(n,{signal:AbortSignal.timeout(1e4)});if(!s.ok){let r=new Error(`registry ${e} fetch failed (${s.status}) for ${t}`);throw r.status=s.status,r}return s},{attempts:3})}var b=class{constructor(e){this.httpClient=e}async healthCheck(){return o(await this.httpClient.get("/admin-api/health"))}async isAuthed(){return this.httpClient.get("/admin-api/is-authed")}async installApplication(e){return o(await this.httpClient.post("/admin-api/install-application",e))}async installFromRegistry(e,t,s){let r=new URL(e).origin,i=new URL(`/api/v2/bundles/${encodeURIComponent(t)}/${encodeURIComponent(s)}`,r).toString(),p=await(await re(i,"manifest",`${t}@${s}`)).json(),m=encodeURIComponent(p.package),l=encodeURIComponent(p.appVersion),d=`${r}/artifacts/${m}/${l}/${m}-${l}.mpk`;return this.installApplication({url:d,package:p.package,version:p.appVersion,metadata:[]})}async getRegistryVersions(e,t){let s=new URL("/api/v2/bundles",new URL(e).origin);s.searchParams.set("package",t);let i=await(await re(s.toString(),"versions",t)).json();return(Array.isArray(i)?i:[]).map(a=>a.appVersion).filter(a=>typeof a=="string").sort((a,p)=>Ce(p,a))}async installDevApplication(e){return o(await this.httpClient.post("/admin-api/install-dev-application",e))}async uninstallApplication(e){return o(await this.httpClient.delete(`/admin-api/applications/${e}`))}async listApplications(){return o(await this.httpClient.get("/admin-api/applications"))}async getApplication(e){return o(await this.httpClient.get(`/admin-api/applications/${e}`))}async listApplicationVersions(e){return o(await this.httpClient.get(`/admin-api/applications/${e}/versions`))}async getApplicationAbi(e,t){let s=t?`?service_name=${encodeURIComponent(t)}`:"";return o(await this.httpClient.get(`/admin-api/applications/${e}/abi${s}`))}async listPackages(){let e=await this.httpClient.get("/admin-api/packages");return e?.data??e}async listPackageVersions(e){let t=await this.httpClient.get(`/admin-api/packages/${encodeURIComponent(e)}/versions`);return t?.data??t}async getLatestPackageVersion(e){return this.httpClient.get(`/admin-api/packages/${encodeURIComponent(e)}/latest`)}async createContext(e){let t={...e,initializationParams:e.initializationParams??[]};return o(await this.httpClient.post("/admin-api/contexts",t))}async deleteContext(e,t){return o(t?await this.httpClient.request(`/admin-api/contexts/${e}`,{method:"DELETE",body:JSON.stringify(t),headers:{"Content-Type":"application/json"}}):await this.httpClient.delete(`/admin-api/contexts/${e}`))}async getContexts(){return o(await this.httpClient.get("/admin-api/contexts"))}async getContext(e){return o(await this.httpClient.get(`/admin-api/contexts/${e}`))}async getContextsForApplication(e){return o(await this.httpClient.get(`/admin-api/contexts/for-application/${e}`))}async generateContextIdentity(){return o(await this.httpClient.post("/admin-api/identity/context",{}))}async getContextIdentities(e){return o(await this.httpClient.get(`/admin-api/contexts/${e}/identities`))}async getContextIdentitiesOwned(e){return o(await this.httpClient.get(`/admin-api/contexts/${e}/identities-owned`))}async joinContext(e){return o(await this.httpClient.post(`/admin-api/contexts/${e}/join`,{}))}async getContextGroup(e){return o(await this.httpClient.get(`/admin-api/contexts/${e}/group`))}async getContextStorage(e){return o(await this.httpClient.get(`/admin-api/contexts/${e}/storage`))}async syncContext(e){await this.httpClient.post(`/admin-api/contexts/sync/${e??""}`,{})}async resyncContext(e,t={}){return await this.httpClient.post(`/admin-api/contexts/${e}/resync`,t)??{contextId:e,resyncStarted:!0}}async inviteSpecializedNode(e){return o(await this.httpClient.post("/admin-api/contexts/invite-specialized-node",e))}async updateContextApplication(e,t){await this.httpClient.post(`/admin-api/contexts/${e}/application`,t)}async getContextsWithExecutorsForApplication(e){let t=await this.httpClient.get(`/admin-api/contexts/with-executors/for-application/${e}`);return Array.isArray(t)?t:t?.contexts??t?.data??[]}async uploadBlob(e){let t=new URLSearchParams;e.hash&&t.set("hash",e.hash),e.contextId&&t.set("context_id",e.contextId);let s=t.toString(),r=s?`/admin-api/blobs?${s}`:"/admin-api/blobs",i=o(await this.httpClient.request(r,{method:"PUT",body:e.data,headers:{"Content-Type":"application/octet-stream"}}));return{blobId:i.blob_id,size:i.size}}async deleteBlob(e){let t=await this.httpClient.delete(`/admin-api/blobs/${e}`);return{blobId:t.blob_id,deleted:t.deleted}}async listBlobs(){return{blobs:o(await this.httpClient.get("/admin-api/blobs")).blobs.map(t=>({blobId:t.blob_id,size:t.size}))}}async getBlob(e){return this.httpClient.get(`/admin-api/blobs/${e}`,{parse:"arrayBuffer"})}async getBlobInfo(e){let{headers:t}=await this.httpClient.head(`/admin-api/blobs/${e}`),s=Number(t["content-length"]);return{blobId:t["x-blob-id"]??e,size:Number.isFinite(s)?s:0,hash:t["x-blob-hash"],mimeType:t["x-blob-mime-type"]}}async createContextAlias(e){return o(await this.httpClient.post("/admin-api/alias/create/context",{alias:e.alias,contextId:e.contextId}))}async createApplicationAlias(e){return o(await this.httpClient.post("/admin-api/alias/create/application",{alias:e.alias,applicationId:e.applicationId}))}async lookupContextAlias(e){return o(await this.httpClient.post(`/admin-api/alias/lookup/context/${encodeURIComponent(e)}`,{}))}async lookupApplicationAlias(e){return o(await this.httpClient.post(`/admin-api/alias/lookup/application/${encodeURIComponent(e)}`,{}))}async deleteContextAlias(e){return o(await this.httpClient.post(`/admin-api/alias/delete/context/${encodeURIComponent(e)}`,{}))}async deleteApplicationAlias(e){return o(await this.httpClient.post(`/admin-api/alias/delete/application/${encodeURIComponent(e)}`,{}))}async listContextAliases(){return o(await this.httpClient.get("/admin-api/alias/list/context"))}async listApplicationAliases(){return o(await this.httpClient.get("/admin-api/alias/list/application"))}async listNamespaces(){return o(await this.httpClient.get("/admin-api/namespaces"))}async getNamespace(e){return o(await this.httpClient.get(`/admin-api/namespaces/${e}`))}async getNodeIdentity(){return o(await this.httpClient.get("/admin-api/identity"))}async getNamespaceIdentity(e){let t=await this.getNodeIdentity();return{namespaceId:e,publicKey:t.publicKey,account:t.accountId}}async listNamespacesForApplication(e){return o(await this.httpClient.get(`/admin-api/namespaces/for-application/${e}`))}async createNamespace(e){return o(await this.httpClient.post("/admin-api/namespaces",{upgradePolicy:"LazyOnAccess",...e}))}async deleteNamespace(e,t){return o(await this.httpClient.request(`/admin-api/namespaces/${e}`,{method:"DELETE",body:JSON.stringify(t??{}),headers:{"Content-Type":"application/json"}}))}async createNamespaceInvitation(e,t){return o(await this.httpClient.post(`/admin-api/namespaces/${e}/invite`,t??{}))}async joinNamespace(e,t){return o(await this.httpClient.post(`/admin-api/namespaces/${e}/join`,t,{timeoutMs:65e3}))}async createGroupInNamespace(e,t){return o(await this.httpClient.post(`/admin-api/namespaces/${e}/groups`,t??{}))}async listNamespaceGroups(e){return o(await this.httpClient.get(`/admin-api/namespaces/${e}/groups`))}async getGroupInfo(e){return o(await this.httpClient.get(`/admin-api/groups/${e}`))}async getDefaultCapabilities(e){return(await this.getGroupInfo(e)).defaultCapabilities}async getSubgroupVisibility(e){return(await this.getGroupInfo(e)).subgroupVisibility}async deleteGroup(e,t){return o(await this.httpClient.request(`/admin-api/groups/${e}`,{method:"DELETE",body:JSON.stringify(t??{}),headers:{"Content-Type":"application/json"}}))}async listGroupMembers(e){let t=await this.httpClient.get(`/admin-api/groups/${e}/members`);if(!Array.isArray(t?.members)){let s=String(e).replace(/[\r\n\t\s]/g,"").slice(0,64);throw new Error(`Invalid listGroupMembers response for group ${s}: missing or non-array \`members\` field`)}return t}async listGroupContexts(e){return o(await this.httpClient.get(`/admin-api/groups/${e}/contexts`))}async addGroupMembers(e,t){await this.httpClient.post(`/admin-api/groups/${e}/members`,t)}async removeGroupMembers(e,t){await this.httpClient.post(`/admin-api/groups/${e}/members/remove`,t)}async updateMemberRole(e,t,s){await this.httpClient.put(`/admin-api/groups/${e}/members/${t}/role`,s)}async getMemberCapabilities(e,t){return o(await this.httpClient.get(`/admin-api/groups/${e}/members/${t}/capabilities`))}async setMemberCapabilities(e,t,s){await this.httpClient.put(`/admin-api/groups/${e}/members/${t}/capabilities`,s)}async setDefaultCapabilities(e,t){await this.httpClient.put(`/admin-api/groups/${e}/settings/default-capabilities`,t)}async setSubgroupVisibility(e,t){await this.httpClient.put(`/admin-api/groups/${e}/settings/subgroup-visibility`,t)}async setTeeAdmissionPolicy(e,t){await this.httpClient.put(`/admin-api/groups/${e}/settings/tee-admission-policy`,t)}async getTeeAdmissionPolicy(e){let t=await this.httpClient.get(`/admin-api/groups/${e}/settings/tee-admission-policy`);return t.data??t}async setGroupMetadata(e,t){await this.httpClient.put(`/admin-api/groups/${e}/metadata`,t)}async getGroupMetadata(e){return(await this.httpClient.get(`/admin-api/groups/${e}/metadata`))?.data??null}async setMemberMetadata(e,t,s){await this.httpClient.put(`/admin-api/groups/${e}/members/${t}/metadata`,s)}async getMemberMetadata(e,t){return(await this.httpClient.get(`/admin-api/groups/${e}/members/${t}/metadata`))?.data??null}async setContextMetadata(e,t,s){await this.httpClient.put(`/admin-api/groups/${e}/contexts/${t}/metadata`,s)}async getContextMetadata(e,t){return(await this.httpClient.get(`/admin-api/groups/${e}/contexts/${t}/metadata`))?.data??null}async syncGroup(e,t){return o(await this.httpClient.post(`/admin-api/groups/${e}/sync`,t??{}))}async upgradeGroup(e,t){return o(await this.httpClient.post(`/admin-api/groups/${e}/upgrade`,t))}async getGroupUpgradeStatus(e){return o(await this.httpClient.get(`/admin-api/groups/${e}/upgrade/status`))}async getMigrationStatus(e){let t=encodeURIComponent(e);return this.httpClient.get(`/admin-api/groups/${t}/migration-status`)}async getCascadeStatus(e){let t=encodeURIComponent(e);return o(await this.httpClient.get(`/admin-api/groups/${t}/cascade-status`))}async retryGroupUpgrade(e,t){return o(await this.httpClient.post(`/admin-api/groups/${e}/upgrade/retry`,t??{}))}async reparentGroup(e,t){let s=await this.httpClient.post(`/admin-api/groups/${e}/reparent`,t);return s?.data??s}async listSubgroups(e){let t=await this.httpClient.get(`/admin-api/groups/${e}/subgroups`);return t.subgroups??t.data??[]}async detachContextFromGroup(e,t,s){await this.httpClient.post(`/admin-api/groups/${e}/contexts/${t}/remove`,s??{})}async createGroupInvitation(e,t){return o(await this.httpClient.post(`/admin-api/groups/${e}/invite`,t??{}))}async joinGroup(e){return o(await this.httpClient.post("/admin-api/groups/join",e))}async joinSubgroupInheritance(e){return o(await this.httpClient.post(`/admin-api/groups/${e}/join-via-inheritance`,{}))}async getTeeInfo(){return o(await this.httpClient.get("/admin-api/tee/info"))}async teeAttest(e){return o(await this.httpClient.post("/admin-api/tee/attest",e))}async teeVerifyQuote(e){return o(await this.httpClient.post("/admin-api/tee/verify-quote",e))}async getPeersCount(){return this.httpClient.get("/admin-api/peers")}async getNetworkStatus(){return this.httpClient.get("/admin-api/network/status")}async getUsage(){return this.httpClient.get("/admin-api/usage")}async getCertificate(){return this.httpClient.get("/admin-api/certificate",{parse:"text"})}async createGroup(e){return o(await this.httpClient.post("/admin-api/groups",{upgradePolicy:"LazyOnAccess",...e}))}async leaveGroup(e,t){await this.httpClient.post(`/admin-api/groups/${e}/leave`,t??{})}async leaveContext(e,t){await this.httpClient.post(`/admin-api/contexts/${e}/leave`,t??{})}async leaveNamespace(e,t){await this.httpClient.post(`/admin-api/namespaces/${e}/leave`,t??{})}async issueOwnershipProof(e,t){return this.httpClient.post(`/admin-api/groups/${e}/issue-ownership-proof`,t??{})}async issueNamespaceOwnershipProof(e,t){return this.httpClient.post(`/admin-api/groups/${e}/issue-namespace-ownership-proof`,t??{})}async setMemberAutoFollow(e,t,s){await this.httpClient.put(`/admin-api/groups/${e}/members/${t}/auto-follow`,s)}async abortMigration(e,t){return this.httpClient.post(`/admin-api/groups/${e}/migration/abort`,t??{})}};function ot(n){return new b(A(n))}function at(n){return new b(M(n))}function pt(n){return new b(j(n))}function ie(n,e){return new b(n)}function B(n){try{let e=n.indexOf("#");if(e===-1)return null;let t=n.substring(e+1),s=new URLSearchParams(t),r=s.get("access_token");return r?{accessToken:r,refreshToken:s.get("refresh_token")??"",applicationId:s.get("application_id")??"",contextId:s.get("context_id")??"",contextIdentity:s.get("context_identity")??"",nodeUrl:s.get("node_url")??""}:null}catch{return null}}function V(n,e){let t=new URLSearchParams;return t.set("callback-url",e.callbackUrl),e.permissions&&e.permissions.length>0&&t.set("permissions",e.permissions.join(",")),t.set("mode",e.mode),e.packageName&&(t.set("package-name",e.packageName),e.packageVersion&&t.set("package-version",e.packageVersion),e.registryUrl&&t.set("registry-url",e.registryUrl)),`${n.replace(/\/+$/,"")}/auth/login?${t.toString()}`}var H=class extends Error{constructor(e,t,s,r){super(t),this.name="RpcError",this.code=e,this.data=s,this.type=r}};async function J(n,e,t){let s=await n.post("/jsonrpc",{jsonrpc:"2.0",id:1,method:e,params:t});if(s.error){let r=s.error;throw new H(r.code??-1,r.message??r.type??"RPC error",r.data,r.type)}return s.result}var P=class{constructor(e){this.httpClient=e.httpClient}async execute(e){let t=await J(this.httpClient,"execute",{contextId:e.contextId,method:e.method,argsJson:e.argsJson??{}});return t&&"output"in t?t.output:t}async migrateMyEntries(e){return this.execute({contextId:e,method:"migrate_my_entries"})}async countMyPending(e){return this.execute({contextId:e,method:"count_my_pending"})}};var be=new Set(["MigrationStarted","MigrationProgress","CascadeProgress","MigrationCompleted"]);function oe(n){return n.type!==void 0&&be.has(n.type)}var Re=new Set(["token_reuse","token_revoked"]),w=class{constructor(e){this.sessionId=null;this.abortController=null;this.reconnectTimer=null;this.subscribedContextIds=new Set;this.subscribedGroupIds=new Set;this.closed=!1;this.listeners={connect:[],event:[],error:[]};this.baseUrl=e.baseUrl.replace(/\/+$/,""),this.getAuthToken=e.getAuthToken,this.reconnectDelayMs=e.reconnectDelayMs??3e3}on(e,t){let s=e;if(s in this.listeners){let r=this.listeners[s];r.includes(t)||r.push(t)}}off(e,t){let s=e;if(s in this.listeners){let r=this.listeners[s],i=r.indexOf(t);i!==-1&&r.splice(i,1)}}onAppVersionChanged(e){let t=s=>{if(s.type!=="AppVersionChanged")return;let r=s.data;e({contextId:s.contextId,fromVersion:r?.fromVersion,toVersion:r?.toVersion})};return this.on("event",t),()=>this.off("event",t)}onMigrationEvent(e){let t=s=>{oe(s)&&e(s)};return this.on("event",t),()=>this.off("event",t)}emit(e,t){let s=e;if(s in this.listeners)for(let r of this.listeners[s])try{r(t)}catch{}}async connect(){if(!(this.abortController&&!this.closed)){this.closed=!1,this.abortController=new AbortController;try{let e=await this.getAuthToken(),t=`${this.baseUrl}/sse`,s=await fetch(t,{headers:{Authorization:`Bearer ${e}`,Accept:"text/event-stream"},signal:this.abortController.signal});if(!s.ok){let r=s.headers.get("x-auth-error"),i=await s.text().catch(()=>{});throw s.status===401&&r&&Re.has(r)?new k(r,s.status,s.statusText,t,s.headers,i):new f(s.status,s.statusText,t,s.headers,i)}if(!s.body)throw new Error("SSE response has no body");this.readStream(s.body).catch(r=>{if(this.closed)return;let i=r instanceof Error?r:new Error(String(r));this.emit("error",i),this.scheduleReconnect()})}catch(e){if(this.closed)return;let t=e instanceof Error?e:new Error(String(e));this.emit("error",t),this.scheduleReconnect()}}}async readStream(e){let t=e.getReader(),s=new TextDecoder,r="";try{for(;;){let{done:i,value:a}=await t.read();if(i)break;r+=s.decode(a,{stream:!0});let p=r.split(`
|
|
2
|
+
`);r=p.pop()??"";for(let m of p)if(m.startsWith("data:")){let l=m.slice(5).trim();l&&this.handleMessage(l)}}if(r+=s.decode(),r.startsWith("data:")){let i=r.slice(5).trim();i&&this.handleMessage(i)}}catch(i){if(this.closed)return;let a=i instanceof Error?i:new Error(String(i));this.emit("error",a)}this.closed||this.scheduleReconnect()}handleMessage(e){try{let t=JSON.parse(e);if(t.type==="connect"&&t.session_id){this.sessionId=t.session_id,this.emit("connect",t.session_id),(this.subscribedContextIds.size>0||this.subscribedGroupIds.size>0)&&this.sendSubscription("subscribe",{contextIds:[...this.subscribedContextIds],groupIds:[...this.subscribedGroupIds]});return}if(!t.result)return;let s=t.result.data;if(Array.isArray(s))try{let r=new Uint8Array(s),i=new TextDecoder().decode(r);s=JSON.parse(i)}catch{}if(t.result.contextId){this.emit("event",{contextId:t.result.contextId,type:t.result.type,data:s});return}t.result.groupId&&this.emit("event",{groupId:t.result.groupId,type:t.result.type,data:s})}catch{}}async subscribe(e){let t=Array.isArray(e)?{contextIds:e}:e,s=(t.contextIds??[]).filter(i=>!this.subscribedContextIds.has(i)),r=(t.groupIds??[]).filter(i=>!this.subscribedGroupIds.has(i));for(let i of t.contextIds??[])this.subscribedContextIds.add(i);for(let i of t.groupIds??[])this.subscribedGroupIds.add(i);(s.length>0||r.length>0)&&this.sessionId&&await this.sendSubscription("subscribe",{contextIds:s,groupIds:r})}async unsubscribe(e){let t=Array.isArray(e)?{contextIds:e}:e,s=(t.contextIds??[]).filter(i=>this.subscribedContextIds.has(i)),r=(t.groupIds??[]).filter(i=>this.subscribedGroupIds.has(i));for(let i of t.contextIds??[])this.subscribedContextIds.delete(i);for(let i of t.groupIds??[])this.subscribedGroupIds.delete(i);(s.length>0||r.length>0)&&this.sessionId&&await this.sendSubscription("unsubscribe",{contextIds:s,groupIds:r})}async sendSubscription(e,t){try{let s=await this.getAuthToken(),r={};t.contextIds&&t.contextIds.length>0&&(r.contextIds=t.contextIds),t.groupIds&&t.groupIds.length>0&&(r.groupIds=t.groupIds);let i=await fetch(`${this.baseUrl}/sse/subscription`,{method:"POST",headers:{Authorization:`Bearer ${s}`,"Content-Type":"application/json"},body:JSON.stringify({id:this.sessionId,method:e,params:r})});i.ok||this.emit("error",new Error(`SSE ${e} failed: ${i.status}`))}catch(s){this.emit("error",s instanceof Error?s:new Error(`SSE ${e} failed`))}}forceReconnect(){this.abortController&&(this.abortController.abort(),this.abortController=null),this.sessionId=null,this.connect()}scheduleReconnect(){this.closed||(this.reconnectTimer&&clearTimeout(this.reconnectTimer),this.reconnectTimer=setTimeout(()=>{this.reconnectTimer=null,this.forceReconnect()},this.reconnectDelayMs))}close(){this.closed=!0,this.abortController&&(this.abortController.abort(),this.abortController=null),this.reconnectTimer&&(clearTimeout(this.reconnectTimer),this.reconnectTimer=null),this.sessionId=null,this.subscribedContextIds.clear(),this.subscribedGroupIds.clear()}};var U=class U{constructor(e){this.ws=null;this.closed=!1;this.reconnectAttempt=0;this.reconnectTimer=null;this.subscribedContextIds=new Set;this.subscribedGroupIds=new Set;this.listeners={connect:[],event:[],error:[]};this.baseUrl=e.baseUrl.replace(/\/+$/,""),this.getAuthToken=e.getAuthToken}on(e,t){let s=e;if(s in this.listeners){let r=this.listeners[s];r.includes(t)||r.push(t)}}off(e,t){let s=e;if(s in this.listeners){let r=this.listeners[s],i=r.indexOf(t);i!==-1&&r.splice(i,1)}}emit(e,t){let s=e;if(s in this.listeners)for(let r of this.listeners[s])try{r(t)}catch{}}async connect(){if(!(this.ws&&(this.ws.readyState===0||this.ws.readyState===1))){this.closed=!1;try{let e=await this.getAuthToken();if(!e)throw new Error("No authentication token available for WebSocket connection");let t=this.baseUrl.replace(/^http/,"ws");this.ws=new WebSocket(`${t}/ws?token=${encodeURIComponent(e)}`),this.ws.onopen=()=>{this.reconnectAttempt=0,this.emit("connect"),this.resubscribeAfterReconnect()},this.ws.onmessage=s=>{this.handleMessage(s.data)},this.ws.onerror=()=>{this.emit("error",new Error("WebSocket error"))},this.ws.onclose=()=>{this.closed||this.scheduleReconnect()}}catch(e){if(this.closed)return;let t=e instanceof Error?e:new Error(String(e));this.emit("error",t),this.scheduleReconnect()}}}handleMessage(e){if(typeof e=="string")try{let t=JSON.parse(e);if(!t.result)return;let s=t.result.data;if(Array.isArray(s))try{let r=new Uint8Array(s),i=new TextDecoder().decode(r);s=JSON.parse(i)}catch{}if(t.result.contextId){this.emit("event",{contextId:t.result.contextId,type:t.result.type,data:s});return}t.result.groupId&&this.emit("event",{groupId:t.result.groupId,type:t.result.type,data:s})}catch{}}subscribe(e){let t=Array.isArray(e)?{contextIds:e}:e;for(let s of t.contextIds??[])this.subscribedContextIds.add(s);for(let s of t.groupIds??[])this.subscribedGroupIds.add(s);this.ws&&this.ws.readyState===1&&this.sendMessage({id:null,method:"subscribe",params:this.buildSubscriptionParams(t.contextIds??[],t.groupIds??[])})}unsubscribe(e){let t=Array.isArray(e)?{contextIds:e}:e;for(let s of t.contextIds??[])this.subscribedContextIds.delete(s);for(let s of t.groupIds??[])this.subscribedGroupIds.delete(s);this.ws&&this.ws.readyState===1&&this.sendMessage({id:null,method:"unsubscribe",params:this.buildSubscriptionParams(t.contextIds??[],t.groupIds??[])})}resubscribeAfterReconnect(){this.subscribedContextIds.size===0&&this.subscribedGroupIds.size===0||this.sendMessage({id:null,method:"subscribe",params:this.buildSubscriptionParams([...this.subscribedContextIds],[...this.subscribedGroupIds])})}buildSubscriptionParams(e,t){let s={};return e.length>0&&(s.contextIds=e),t.length>0&&(s.groupIds=t),s}sendMessage(e){this.ws&&this.ws.readyState===1&&this.ws.send(JSON.stringify(e))}scheduleReconnect(){if(this.closed)return;this.reconnectTimer&&clearTimeout(this.reconnectTimer);let e=Math.min(1e3*Math.pow(2,this.reconnectAttempt),U.MAX_BACKOFF_MS);this.reconnectAttempt++,this.reconnectTimer=setTimeout(()=>{this.reconnectTimer=null,this.connect()},e)}close(){this.closed=!0,this.reconnectTimer&&(clearTimeout(this.reconnectTimer),this.reconnectTimer=null),this.ws&&(this.ws.onclose=null,this.ws.close(),this.ws=null),this.subscribedContextIds.clear(),this.subscribedGroupIds.clear()}};U.MAX_BACKOFF_MS=3e4;var T=U;function $(){return{encode(n){return Array.from(new TextEncoder().encode(JSON.stringify(n)))},decode(n){return JSON.parse(new TextDecoder().decode(new Uint8Array(n)))}}}var S=class{constructor(e){this.httpClient=e.httpClient,this.sse=e.sse}async set(e,t,s=$()){await J(this.httpClient,"set_ephemeral",{contextId:e,state:s.encode(t)})}subscribe(e,t,s=$()){let r=i=>{let a=i;if(a.type!=="Ephemeral"||a.contextId!==e)return;let p=a.data;if(!p?.author)return;let m=!!p.removed,l={author:p.author,state:m||p.state===void 0?void 0:s.decode(p.state),removed:m};p.ageMs!==void 0&&(l.ageMs=p.ageMs),t(l)};return this.sse.on("event",r),this.sse.connect().catch(()=>{}),this.sse.subscribe([e]).catch(()=>{}),()=>{this.sse.off("event",r)}}};var ke="mero-js:token-refresh";function Ae(){let e=globalThis.navigator?.locks;return e&&typeof e.request=="function"?e:null}function K(n,e){try{let t=n.split(".");if(t.length===3){let s=t[1].replace(/-/g,"+").replace(/_/g,"/");for(;s.length%4;)s+="=";let r=JSON.parse(atob(s));if(typeof r.exp=="number")return r.exp*1e3}}catch{}return e}var N=class{constructor(e){this.tokenData=null;this.refreshPromise=null;this.rpcClient=null;this.sseClient=null;this.wsClient=null;this.wsWarned=!1;this.config={timeoutMs:1e4,...e},this.tokenStore=e.tokenStore??null,this.tokenStore&&(this.tokenData=this.tokenStore.getTokens());let t=typeof window<"u"&&"__TAURI_INTERNALS__"in window;this.httpClient=A({baseUrl:this.config.baseUrl,getAuthToken:async()=>(await this.getValidToken())?.access_token||"",refreshToken:async()=>(await this.performTokenRefresh()).access_token,onTokenRefresh:async s=>{this.tokenData&&(this.tokenData.access_token=s,this.tokenStore?.setTokens(this.tokenData))},onAuthRevoked:async()=>{this.clearToken();try{await this.config.onAuthRevoked?.()}catch{}},timeoutMs:this.config.timeoutMs,credentials:this.config.requestCredentials??(t?"omit":void 0)}),this.authClient=te(this.httpClient,{baseUrl:this.config.baseUrl,getAuthToken:async()=>(await this.getValidToken())?.access_token||"",timeoutMs:this.config.timeoutMs}),this.adminClient=ie(this.httpClient,{baseUrl:this.config.baseUrl,getAuthToken:async()=>(await this.getValidToken())?.access_token||"",timeoutMs:this.config.timeoutMs})}get auth(){return this.authClient}get admin(){return this.adminClient}get rpc(){return this.rpcClient||(this.rpcClient=new P({httpClient:this.httpClient})),this.rpcClient}get events(){return this.sseClient||(this.sseClient=new w({baseUrl:this.config.baseUrl,getAuthToken:async()=>(await this.getValidToken())?.access_token||""})),this.sseClient}get ephemeral(){return this.ephemeralClient||(this.ephemeralClient=new S({httpClient:this.httpClient,sse:this.events})),this.ephemeralClient}get ws(){return this.wsWarned||(this.wsWarned=!0,console.warn("[mero-js] WsClient is experimental. Use mero.events (SSE) for production.")),this.wsClient||(this.wsClient=new T({baseUrl:this.config.baseUrl,getAuthToken:async()=>(await this.getValidToken())?.access_token||""})),this.wsClient}async authenticate(e){let t=e||this.config.credentials;if(!t)throw new Error("No credentials provided for authentication");try{let s={auth_method:"user_password",public_key:t.username,client_name:"mero-js-sdk",permissions:["admin"],timestamp:Math.floor(Date.now()/1e3),provider_data:{username:t.username,password:t.password}},r=await this.authClient.generateTokens(s),i=r.data.access_token;return this.tokenData={access_token:i,refresh_token:r.data.refresh_token,expires_at:K(i,Date.now()+36e5)},this.tokenStore?.setTokens(this.tokenData),this.tokenData}catch(s){throw new Error(`Authentication failed: ${s instanceof Error?s.message:"Unknown error"}`)}}async getValidToken(){return this.tokenData}async performTokenRefresh(){if(this.refreshPromise)return this.refreshPromise;let e=this.tokenData?.access_token,t=this.withRefreshLock(()=>this.performTokenRefreshLocked(e));this.refreshPromise=t;try{return await t}finally{this.refreshPromise===t&&(this.refreshPromise=null)}}withRefreshLock(e){let t=Ae();return t?t.request(ke,e):e()}async performTokenRefreshLocked(e){let t=this.tokenStore?.getTokens()??null;if(t?.refresh_token&&(this.tokenData=t,e&&t.access_token!==e))return t;if(!this.tokenData?.refresh_token)throw new Error("No refresh token available");try{let s=await this.authClient.refreshToken({access_token:this.tokenData.access_token,refresh_token:this.tokenData.refresh_token}),r=s.data.access_token;return this.tokenData={access_token:r,refresh_token:s.data.refresh_token,expires_at:K(r,Date.now()+36e5)},this.tokenStore?.setTokens(this.tokenData),this.tokenData}catch(s){throw new Error(`Token refresh failed: ${s instanceof Error?s.message:"Unknown error"}`)}}clearToken(){this.refreshPromise=null,this.tokenData=null,this.tokenStore?.clear()}isAuthenticated(){return this.tokenData!==null}setTokenData(e){let t=e.expires_at||K(e.access_token,Date.now()+36e5);this.tokenData={...e,expires_at:t},this.tokenStore?.setTokens(this.tokenData)}getTokenData(){return this.tokenData}close(){this.sseClient?.close(),this.wsClient?.close()}static parseAuthCallback(e){return B(e)}static buildAuthLoginUrl(e,t){return V(e,t)}};function we(n){return new N(n)}var _="123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz",z=/^[0-9a-f]{64}$/i;function Te(n){if(n.length===0)return"";let e=[0];for(let s of n){let r=s;for(let i=0;i<e.length;i++)r+=e[i]<<8,e[i]=r%58,r=r/58|0;for(;r>0;)e.push(r%58),r=r/58|0}let t="";for(let s of n){if(s!==0)break;t+=_[0]}for(let s=e.length-1;s>=0;s--)t+=_[e[s]];return t}function ve(n){if(n.length===0)return null;let e=[0];for(let s of n){let r=_.indexOf(s);if(r<0)return null;let i=r;for(let a=0;a<e.length;a++)i+=e[a]*58,e[a]=i&255,i>>=8;for(;i>0;)e.push(i&255),i>>=8}let t=0;for(let s of n){if(s!==_[0])break;t++}return Uint8Array.from([...new Array(t).fill(0),...e.reverse()])}function xe(n){let e="";for(let t of n)e+=t.toString(16).padStart(2,"0");return e}function De(n){let e=new Uint8Array(n.length/2);for(let t=0;t<e.length;t++)e[t]=parseInt(n.slice(t*2,t*2+2),16);return e}function F(n){let e=(n??"").trim();if(!e)return"";if(z.test(e))return e.toLowerCase();let t=ve(e);return!t||t.length!==32?e:xe(t)}function Pe(n){let e=(n??"").trim();return e?z.test(e)?Te(De(e)):e:""}function Se(n,e){let t=F(n),s=F(e);return z.test(t)&&t===s}var Q=class{constructor(){this.tokens=null}getTokens(){return this.tokens}setTokens(e){this.tokens=e}clear(){this.tokens=null}},Ee="mero-tokens",X=class{constructor(e=Ee){this.key=e}getTokens(){try{if(typeof localStorage>"u")return null;let e=localStorage.getItem(this.key);if(!e)return null;let t=JSON.parse(e);return t&&t.access_token&&t.refresh_token?{access_token:t.access_token,refresh_token:t.refresh_token,expires_at:typeof t.expires_at=="number"?t.expires_at:Date.now()+36e5}:null}catch{return null}}setTokens(e){try{if(typeof localStorage>"u")return;localStorage.setItem(this.key,JSON.stringify(e))}catch{}}clear(){try{if(typeof localStorage>"u")return;localStorage.removeItem(this.key)}catch{}}};var Y=class{constructor(e={}){this.baseUrl=(e.cloudBaseUrl||"https://cloud.calimero.network").replace(/\/+$/,"")}enableHA(e){let t=new URLSearchParams({group_id:e.groupId,context_id:e.contextId});e.redirectUrl&&t.set("redirect_url",e.redirectUrl),window.open(`${this.baseUrl}/enable-ha?${t.toString()}`)}disableHA(e){let t=new URLSearchParams({group_id:e.groupId,context_id:e.contextId});e.redirectUrl&&t.set("redirect_url",e.redirectUrl),window.open(`${this.baseUrl}/disable-ha?${t.toString()}`)}};var _t={CAN_CREATE_CONTEXT:1,CAN_INVITE_MEMBERS:2,CAN_JOIN_OPEN_SUBGROUPS:4,MANAGE_MEMBERS:8,MANAGE_APPLICATION:16,CAN_CREATE_SUBGROUP:32,CAN_DELETE_SUBGROUP:64,CAN_MANAGE_VISIBILITY:128,CAN_MANAGE_METADATA:256};function qt(n,e){let t=e>>>0;return(n&t)>>>0===t}function Lt(n,e){return(n|e)>>>0}function Ot(n,e){return(n&~e)>>>0}var ae=[2428,2429,2528,2529],Ie="localhost",Me=2e3;function pe(n){return`http://${Ie}:${n}`}function ce(n,e){let t=n.endsWith("/")?n:`${n}/`;return new URL(e,t).toString()}async function le(n,e={}){let{timeoutMs:t=Me,signal:s}=e;if(s?.aborted)return!1;let r=new AbortController,i=()=>r.abort(),a=s;a&&a.addEventListener("abort",i,{once:!0});let p=setTimeout(()=>r.abort(),t);try{let m=ce(n,"admin-api/health"),l=await fetch(m,{method:"GET",signal:r.signal});if(!l.ok)return!1;try{let d=await l.json(),u=d?.data?.status!==void 0?d?.data?.status:d?.status;return u===void 0?!0:typeof u=="string"&&u.toLowerCase()==="alive"}catch{return!0}}catch{return!1}finally{clearTimeout(p),a&&a.removeEventListener("abort",i)}}async function Ge(n={}){let{ports:e=ae,timeoutMs:t,signal:s}=n;return(await Promise.all(e.map(async i=>{let a=pe(i);return await le(a,{timeoutMs:t,signal:s})?a:null}))).filter(i=>i!==null)}export{b as AdminApiClient,C as AuthApiClient,k as AuthRevokedError,_t as CAPABILITIES,Y as CloudClient,ae as DEFAULT_LOCAL_NODE_PORTS,S as EphemeralClient,f as HTTPError,X as LocalStorageTokenStore,Q as MemoryTokenStore,N as MeroJs,P as RpcClient,H as RpcError,w as SseClient,x as WebHttpClient,T as WsClient,V as buildAuthLoginUrl,L as combineSignals,Ce as compareSemver,pt as createAdminApiClient,ie as createAdminApiClientFromHttpClient,Ye as createAuthApiClient,te as createAuthApiClientFromHttpClient,ot as createBrowserAdminApiClient,Qe as createBrowserAuthApiClient,A as createBrowserHttpClient,W as createHttpClient,we as createMeroJs,at as createNodeAdminApiClient,Xe as createNodeAuthApiClient,M as createNodeHttpClient,ye as createRetryableMethod,O as createTimeoutSignal,j as createUniversalHttpClient,Ge as discoverLocalNodes,qt as hasCap,$ as jsonCodec,pe as localNodeUrl,ce as nodeEndpoint,B as parseAuthCallback,le as probeNodeHealth,Se as sameAccount,Pe as toAccountBase58,F as toAccountHex,Lt as withCap,G as withRetry,Ot as withoutCap};
|
|
3
3
|
//# sourceMappingURL=index.browser.mjs.map
|