@calimero-network/mero-js 11.1.0 → 12.1.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/admin-api/admin-types.d.ts +37 -8
- package/dist/events/group.d.ts +87 -2
- package/dist/events/group.js +10 -1
- package/dist/events/index.d.ts +1 -1
- package/dist/events/sse.d.ts +16 -3
- package/dist/events/sse.js +20 -1
- package/dist/events/ws.d.ts +6 -3
- package/dist/events/ws.js +2 -1
- package/dist/index.browser.mjs +2 -2
- package/dist/index.browser.mjs.map +4 -4
- package/dist/index.cjs +27 -0
- package/dist/index.cjs.map +3 -3
- package/dist/index.d.ts +1 -1
- package/dist/index.mjs +27 -0
- package/dist/index.mjs.map +3 -3
- package/package.json +1 -1
|
@@ -400,8 +400,14 @@ export interface JoinNamespaceRequest {
|
|
|
400
400
|
}
|
|
401
401
|
export interface JoinNamespaceResponseData {
|
|
402
402
|
groupId: string;
|
|
403
|
+
/** The key the joiner signs with, base58. */
|
|
403
404
|
memberIdentity: string;
|
|
404
|
-
|
|
405
|
+
/**
|
|
406
|
+
* The account that key joined as, 64 hex characters. This — not
|
|
407
|
+
* `memberIdentity` — is what every member-addressing endpoint takes, so it
|
|
408
|
+
* is how the caller addresses the member it just became.
|
|
409
|
+
*/
|
|
410
|
+
memberAccount: string;
|
|
405
411
|
}
|
|
406
412
|
export interface CreateGroupInNamespaceRequest {
|
|
407
413
|
groupId?: string;
|
|
@@ -430,15 +436,25 @@ export interface GroupUpgradeStatus {
|
|
|
430
436
|
initiatedAt: number;
|
|
431
437
|
initiatedBy: string;
|
|
432
438
|
status: string;
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
439
|
+
/** Contexts THIS NODE enumerated for the upgrade. Node-local; fleet progress
|
|
440
|
+
* is the `getMigrationStatus` rollup. */
|
|
441
|
+
localContextsTotal?: number;
|
|
442
|
+
localContextsSwapped?: number;
|
|
443
|
+
/** Contexts whose swap failed on this node; a non-zero value is what
|
|
444
|
+
* `retryGroupUpgrade` picks up. */
|
|
445
|
+
localContextsFailed?: number;
|
|
446
|
+
/** Unix seconds at which THIS NODE finished its own context swaps. Not fleet
|
|
447
|
+
* convergence - that is `MigrationStatus.fleetCompletedAt`. */
|
|
436
448
|
completedAt?: number;
|
|
437
449
|
}
|
|
438
450
|
export type MemberMigrationState = 'migrated' | 'in_progress' | 'unknown' | 'failed';
|
|
439
451
|
/** Why a member's migration did not complete. */
|
|
440
452
|
export type MigrationFailureReason = 'check_aborted' | 'apply_failed' | 'no_migration_path';
|
|
441
453
|
export interface MemberMigrationReport {
|
|
454
|
+
/** ABI state version the member has loaded, from `#[app::state(version = N)]` -
|
|
455
|
+
* the engine's migration gate, not the bundle semver and not a CRDT concept.
|
|
456
|
+
* The wrong reading here is how the core rollup defect (comparing bundle-semver
|
|
457
|
+
* majors instead of state versions) went unnoticed. */
|
|
442
458
|
schemaVersion: number;
|
|
443
459
|
residueAuto: number;
|
|
444
460
|
syncedUpToHlc: number;
|
|
@@ -471,7 +487,14 @@ export interface MigrationStatusRollup {
|
|
|
471
487
|
export interface MigrationStatus {
|
|
472
488
|
targetVersion: number;
|
|
473
489
|
expectedMembers: number;
|
|
490
|
+
/** Governance HLC the cohort was pinned at, as an opaque display string.
|
|
491
|
+
* Absent when there is no migration record. */
|
|
474
492
|
cohortPinnedAtHlc?: string;
|
|
493
|
+
/** Unix seconds at which this node watched the FLEET converge, absent while it
|
|
494
|
+
* has not. Distinct from `GroupUpgradeStatus.completedAt`, which is this node's
|
|
495
|
+
* own local swap completion. Durable, unlike `rollup.allMigrated`, which is
|
|
496
|
+
* recomputed from in-TTL heartbeats and lapses when a member goes quiet. */
|
|
497
|
+
fleetCompletedAt?: number;
|
|
475
498
|
rollup: MigrationStatusRollup;
|
|
476
499
|
members: MemberMigrationStatusEntry[];
|
|
477
500
|
}
|
|
@@ -670,9 +693,9 @@ export interface UpgradeGroupRequest {
|
|
|
670
693
|
export interface UpgradeGroupResponseData {
|
|
671
694
|
groupId: string;
|
|
672
695
|
status: string;
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
696
|
+
localContextsTotal?: number;
|
|
697
|
+
localContextsSwapped?: number;
|
|
698
|
+
localContextsFailed?: number;
|
|
676
699
|
}
|
|
677
700
|
export type GroupUpgradeStatusResponseData = GroupUpgradeStatus | null;
|
|
678
701
|
export interface RetryGroupUpgradeRequest {
|
|
@@ -709,8 +732,14 @@ export interface JoinGroupRequest {
|
|
|
709
732
|
}
|
|
710
733
|
export interface JoinGroupResponseData {
|
|
711
734
|
groupId: string;
|
|
735
|
+
/** The key the joiner signs with, base58. */
|
|
712
736
|
memberIdentity: string;
|
|
713
|
-
|
|
737
|
+
/**
|
|
738
|
+
* The account that key joined as, 64 hex characters. This — not
|
|
739
|
+
* `memberIdentity` — is what every member-addressing endpoint takes, so it
|
|
740
|
+
* is how the caller addresses the member it just became.
|
|
741
|
+
*/
|
|
742
|
+
memberAccount: string;
|
|
714
743
|
}
|
|
715
744
|
export interface TeeInfoResponseData {
|
|
716
745
|
cloudProvider: string;
|
package/dist/events/group.d.ts
CHANGED
|
@@ -3,7 +3,92 @@ export interface GroupMembershipEventData {
|
|
|
3
3
|
groupId: string;
|
|
4
4
|
type: 'MemberJoined' | 'MemberAdded' | 'MemberRemoved';
|
|
5
5
|
data: {
|
|
6
|
-
member
|
|
7
|
-
|
|
6
|
+
/** The member's ACCOUNT, hex-encoded 32 bytes (64 chars) - the principal the
|
|
7
|
+
* governance rows name. Not a bs58 signing key: the field this replaced
|
|
8
|
+
* carried one, and both are strings, so the rename is what makes a stale
|
|
9
|
+
* consumer fail loudly instead of comparing accounts against keys forever. */
|
|
10
|
+
memberAccount: string;
|
|
11
|
+
/** Absent on `MemberRemoved`, and on a `MemberJoined` inherited from an Open
|
|
12
|
+
* subgroup. Core's set is closed. */
|
|
13
|
+
role?: 'Admin' | 'Member' | 'ReadOnly' | 'ReadOnlyTee';
|
|
8
14
|
};
|
|
9
15
|
}
|
|
16
|
+
/**
|
|
17
|
+
* A migration was accepted and its target ABI state version resolved.
|
|
18
|
+
* `toStateVersion` is the `#[app::state(version = N)]` number, not the bundle
|
|
19
|
+
* semver (`toVersion`).
|
|
20
|
+
*/
|
|
21
|
+
export interface MigrationStartedData {
|
|
22
|
+
fromVersion: string;
|
|
23
|
+
toVersion: string;
|
|
24
|
+
toStateVersion: number;
|
|
25
|
+
/** Contexts the EMITTING NODE enumerated for the migration. Node-local, never
|
|
26
|
+
* the fleet cohort size that `MigrationProgressData.total` carries. */
|
|
27
|
+
localContextsTotal: number;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Fleet rollup counters, recomputed as peers' heartbeat facts change. Counters
|
|
31
|
+
* only: the per-member detail behind them stays in the admin-gated
|
|
32
|
+
* `getMigrationStatus` read.
|
|
33
|
+
*/
|
|
34
|
+
export interface MigrationProgressData {
|
|
35
|
+
migrated: number;
|
|
36
|
+
inProgress: number;
|
|
37
|
+
unknown: number;
|
|
38
|
+
failed: number;
|
|
39
|
+
/** The pinned FLEET COHORT size, never a node-local context count like
|
|
40
|
+
* `MigrationStartedData.localContextsTotal`. */
|
|
41
|
+
total: number;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* One subgroup's local context swaps advanced on the emitting node.
|
|
45
|
+
*
|
|
46
|
+
* Admin-only: it names a descendant subgroup, which a plain namespace member
|
|
47
|
+
* may not enumerate, so core withholds it from non-admin subscribers. A
|
|
48
|
+
* non-admin never receiving this variant is correct behaviour, not a gap.
|
|
49
|
+
*/
|
|
50
|
+
export interface CascadeProgressData {
|
|
51
|
+
/** Hex-encoded descendant subgroup id, never the namespace root the event is
|
|
52
|
+
* keyed on. */
|
|
53
|
+
subgroupId: string;
|
|
54
|
+
localContextsSwapped: number;
|
|
55
|
+
/** Contexts the emitting node holds for THIS SUBGROUP. Node-local and
|
|
56
|
+
* per-subgroup; unrelated to both sibling totals. */
|
|
57
|
+
localContextsTotal: number;
|
|
58
|
+
}
|
|
59
|
+
/** Every pinned-cohort member reported the target version. */
|
|
60
|
+
export interface MigrationCompletedData {
|
|
61
|
+
toVersion: string;
|
|
62
|
+
/** FLEET convergence, in seconds since the epoch: the same stamp
|
|
63
|
+
* `MigrationStatus.fleetCompletedAt` returns. Not `GroupUpgradeStatus.completedAt`,
|
|
64
|
+
* which is this node's own local swap completion. */
|
|
65
|
+
completedAt: number;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Parsed group-migration event (core's `GroupMigration` `NodeEvent` variant),
|
|
69
|
+
* keyed on the namespace root a client subscribes with.
|
|
70
|
+
*
|
|
71
|
+
* `MigrationStarted`, `MigrationProgress` and `MigrationCompleted` reach every
|
|
72
|
+
* subscribed member; `CascadeProgress` reaches namespace admins only.
|
|
73
|
+
*/
|
|
74
|
+
export type GroupMigrationEventData = {
|
|
75
|
+
groupId: string;
|
|
76
|
+
type: 'MigrationStarted';
|
|
77
|
+
data: MigrationStartedData;
|
|
78
|
+
} | {
|
|
79
|
+
groupId: string;
|
|
80
|
+
type: 'MigrationProgress';
|
|
81
|
+
data: MigrationProgressData;
|
|
82
|
+
} | {
|
|
83
|
+
groupId: string;
|
|
84
|
+
type: 'CascadeProgress';
|
|
85
|
+
data: CascadeProgressData;
|
|
86
|
+
} | {
|
|
87
|
+
groupId: string;
|
|
88
|
+
type: 'MigrationCompleted';
|
|
89
|
+
data: MigrationCompletedData;
|
|
90
|
+
};
|
|
91
|
+
/** Narrows a raw `'event'` payload to the group-migration family by its tag. */
|
|
92
|
+
export declare function isGroupMigrationEvent(event: {
|
|
93
|
+
type?: string;
|
|
94
|
+
}): event is GroupMigrationEventData;
|
package/dist/events/group.js
CHANGED
|
@@ -1 +1,10 @@
|
|
|
1
|
-
|
|
1
|
+
const MIGRATION_EVENT_TYPES = new Set([
|
|
2
|
+
'MigrationStarted',
|
|
3
|
+
'MigrationProgress',
|
|
4
|
+
'CascadeProgress',
|
|
5
|
+
'MigrationCompleted',
|
|
6
|
+
]);
|
|
7
|
+
/** Narrows a raw `'event'` payload to the group-migration family by its tag. */
|
|
8
|
+
export function isGroupMigrationEvent(event) {
|
|
9
|
+
return event.type !== undefined && MIGRATION_EVENT_TYPES.has(event.type);
|
|
10
|
+
}
|
package/dist/events/index.d.ts
CHANGED
|
@@ -2,4 +2,4 @@ export { SseClient } from './sse.js';
|
|
|
2
2
|
export type { SseEventData, AppVersionChangedEvent } from './sse.js';
|
|
3
3
|
export { WsClient } from './ws.js';
|
|
4
4
|
export type { WsEventData } from './ws.js';
|
|
5
|
-
export type { GroupMembershipEventData } from './group.js';
|
|
5
|
+
export type { GroupMembershipEventData, GroupMigrationEventData, MigrationStartedData, MigrationProgressData, CascadeProgressData, MigrationCompletedData, } from './group.js';
|
package/dist/events/sse.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { GroupMembershipEventData } from './group.js';
|
|
2
|
-
export type { GroupMembershipEventData };
|
|
1
|
+
import type { GroupMembershipEventData, GroupMigrationEventData } from './group.js';
|
|
2
|
+
export type { GroupMembershipEventData, GroupMigrationEventData };
|
|
3
3
|
export interface SseEventData {
|
|
4
4
|
contextId: string;
|
|
5
5
|
/** The context-event discriminator (core serializes it as a sibling of
|
|
@@ -13,7 +13,10 @@ export interface AppVersionChangedEvent {
|
|
|
13
13
|
fromVersion?: string;
|
|
14
14
|
toVersion?: string;
|
|
15
15
|
}
|
|
16
|
-
|
|
16
|
+
/** Anything the `'event'` stream can deliver: context events plus the
|
|
17
|
+
* group-keyed membership and migration families. */
|
|
18
|
+
type SseEvent = SseEventData | GroupMembershipEventData | GroupMigrationEventData;
|
|
19
|
+
type SseEventHandler = (event: SseEvent) => void;
|
|
17
20
|
type SseConnectHandler = (sessionId: string) => void;
|
|
18
21
|
type SseErrorHandler = (error: Error) => void;
|
|
19
22
|
export declare class SseClient {
|
|
@@ -44,6 +47,16 @@ export declare class SseClient {
|
|
|
44
47
|
* Returns an unsubscribe closure (so callers need not retain the listener).
|
|
45
48
|
*/
|
|
46
49
|
onAppVersionChanged(handler: (e: AppVersionChangedEvent) => void): () => void;
|
|
50
|
+
/**
|
|
51
|
+
* Typed convenience over the generic `'event'` stream: invokes `handler` only
|
|
52
|
+
* for group-migration events, narrowed on `type` so `data` is the matching
|
|
53
|
+
* payload. Returns an unsubscribe closure.
|
|
54
|
+
*
|
|
55
|
+
* A non-admin subscriber sees `MigrationStarted`, `MigrationProgress` and
|
|
56
|
+
* `MigrationCompleted` but never `CascadeProgress`, which core delivers to
|
|
57
|
+
* namespace admins only.
|
|
58
|
+
*/
|
|
59
|
+
onMigrationEvent(handler: (e: GroupMigrationEventData) => void): () => void;
|
|
47
60
|
private emit;
|
|
48
61
|
connect(): Promise<void>;
|
|
49
62
|
private readStream;
|
package/dist/events/sse.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { isGroupMigrationEvent } from './group.js';
|
|
1
2
|
export class SseClient {
|
|
2
3
|
constructor(opts) {
|
|
3
4
|
this.sessionId = null;
|
|
@@ -47,6 +48,23 @@ export class SseClient {
|
|
|
47
48
|
this.on('event', listener);
|
|
48
49
|
return () => this.off('event', listener);
|
|
49
50
|
}
|
|
51
|
+
/**
|
|
52
|
+
* Typed convenience over the generic `'event'` stream: invokes `handler` only
|
|
53
|
+
* for group-migration events, narrowed on `type` so `data` is the matching
|
|
54
|
+
* payload. Returns an unsubscribe closure.
|
|
55
|
+
*
|
|
56
|
+
* A non-admin subscriber sees `MigrationStarted`, `MigrationProgress` and
|
|
57
|
+
* `MigrationCompleted` but never `CascadeProgress`, which core delivers to
|
|
58
|
+
* namespace admins only.
|
|
59
|
+
*/
|
|
60
|
+
onMigrationEvent(handler) {
|
|
61
|
+
const listener = (ev) => {
|
|
62
|
+
if (isGroupMigrationEvent(ev))
|
|
63
|
+
handler(ev);
|
|
64
|
+
};
|
|
65
|
+
this.on('event', listener);
|
|
66
|
+
return () => this.off('event', listener);
|
|
67
|
+
}
|
|
50
68
|
emit(event, arg) {
|
|
51
69
|
const key = event;
|
|
52
70
|
if (key in this.listeners) {
|
|
@@ -182,7 +200,8 @@ export class SseClient {
|
|
|
182
200
|
});
|
|
183
201
|
return;
|
|
184
202
|
}
|
|
185
|
-
// Group-
|
|
203
|
+
// Group-keyed event message (untagged NodeEvent's membership and
|
|
204
|
+
// migration variants; the `type` tag tells them apart).
|
|
186
205
|
if (msg.result.groupId) {
|
|
187
206
|
this.emit('event', {
|
|
188
207
|
groupId: msg.result.groupId,
|
package/dist/events/ws.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { GroupMembershipEventData } from './group.js';
|
|
2
|
-
export type { GroupMembershipEventData };
|
|
1
|
+
import type { GroupMembershipEventData, GroupMigrationEventData } from './group.js';
|
|
2
|
+
export type { GroupMembershipEventData, GroupMigrationEventData };
|
|
3
3
|
export interface WsEventData {
|
|
4
4
|
contextId: string;
|
|
5
5
|
/** The context-event discriminator (core serializes it as a sibling of
|
|
@@ -7,7 +7,10 @@ export interface WsEventData {
|
|
|
7
7
|
type?: string;
|
|
8
8
|
data: unknown;
|
|
9
9
|
}
|
|
10
|
-
|
|
10
|
+
/** Anything the `'event'` stream can deliver: context events plus the
|
|
11
|
+
* group-keyed membership and migration families. */
|
|
12
|
+
type WsEvent = WsEventData | GroupMembershipEventData | GroupMigrationEventData;
|
|
13
|
+
type WsEventHandler = (event: WsEvent) => void;
|
|
11
14
|
type WsConnectHandler = () => void;
|
|
12
15
|
type WsErrorHandler = (error: Error) => void;
|
|
13
16
|
/**
|
package/dist/events/ws.js
CHANGED
|
@@ -113,7 +113,8 @@ export class WsClient {
|
|
|
113
113
|
});
|
|
114
114
|
return;
|
|
115
115
|
}
|
|
116
|
-
// Group-
|
|
116
|
+
// Group-keyed event message (untagged NodeEvent's membership and
|
|
117
|
+
// migration variants; the `type` tag tells them apart).
|
|
117
118
|
if (msg.result.groupId) {
|
|
118
119
|
this.emit('event', {
|
|
119
120
|
groupId: msg.result.groupId,
|
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 ae=new Set(["token_reuse","token_revoked"]);function oe(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=oe(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,C)=>{d[C]=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 C=Date.now()-c,T=Math.max(0,p-C);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 C=await this.getBodyText(p),T=new y(p.status,p.statusText,o,p.headers,C),P=p.headers.get("x-auth-error");if((p.status===401||p.status===403)&&P&&ae.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,C)}let re=t?.signal?.aborted===!0;if(p.status===401&&this.transport.refreshToken&&P==="token_expired"&&s<1&&!h&&!re)try{let f=this.refreshTokenPromise;f||(f=this.transport.refreshToken(),this.refreshTokenPromise=f);let H=await f;if(!H||H.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(H),this.onTokenRefreshPromise=S),await S,this.refreshTokenPromise=null,this.onTokenRefreshPromise=null;let K=t?.timeoutMs||this.transport.timeoutMs;if(K&&r!==void 0){let ie=Date.now()-c;if(K-ie<=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 pe(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 ce(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,!pe(s,t-r))throw s;let o=ce(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 le(n,e={}){return async(...t)=>M(()=>n(...t),e)}var R=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 Ue(n){let e=new x;return new R(e)}function He(n){let e=new x;return new R(e)}function Ne(n){let e=new x;return new R(e)}function z(n,e){return new R(n)}function a(n){return n?.data}function ue(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 b=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)=>ue(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 Ve(n){return new b(k(n))}function Je(n){return new b(E(n))}function Ke(n){return new b(L(n))}function Z(n,e){return new b(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 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)}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 de="mero-js:token-refresh";function he(){let e=globalThis.navigator?.locks;return e&&typeof e.request=="function"?e:null}function B(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 U=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:B(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=he();return t?t.request(de,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:B(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||B(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 me(n){return new U(n)}var j=class{constructor(){this.tokens=null}getTokens(){return this.tokens}setTokens(e){this.tokens=e}clear(){this.tokens=null}},ge="mero-tokens",V=class{constructor(e=ge){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 mt={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 gt(n,e){let t=e>>>0;return(n&t)>>>0===t}function ft(n,e){return(n|e)>>>0}function yt(n,e){return(n&~e)>>>0}var ee=[2428,2429,2528,2529],fe="localhost",ye=2e3;function te(n){return`http://${fe}:${n}`}function se(n,e){let t=n.endsWith("/")?n:`${n}/`;return new URL(e,t).toString()}async function ne(n,e={}){let{timeoutMs:t=ye,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=se(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 Re(n={}){let{ports:e=ee,timeoutMs:t,signal:s}=n;return(await Promise.all(e.map(async i=>{let o=te(i);return await ne(o,{timeoutMs:t,signal:s})?o:null}))).filter(i=>i!==null)}export{b as AdminApiClient,R as AuthApiClient,I as AuthRevokedError,mt as CAPABILITIES,J as CloudClient,ee as DEFAULT_LOCAL_NODE_PORTS,y as HTTPError,V as LocalStorageTokenStore,j as MemoryTokenStore,U as MeroJs,D as RpcClient,G as RpcError,w as SseClient,v as WebHttpClient,A as WsClient,W as buildAuthLoginUrl,N as combineSignals,ue as compareSemver,Ke as createAdminApiClient,Z as createAdminApiClientFromHttpClient,Ne as createAuthApiClient,z as createAuthApiClientFromHttpClient,Ve as createBrowserAdminApiClient,Ue as createBrowserAuthApiClient,k as createBrowserHttpClient,q as createHttpClient,me as createMeroJs,Je as createNodeAdminApiClient,He as createNodeAuthApiClient,E as createNodeHttpClient,le as createRetryableMethod,_ as createTimeoutSignal,L as createUniversalHttpClient,Re as discoverLocalNodes,gt as hasCap,te as localNodeUrl,se as nodeEndpoint,O as parseAuthCallback,ne as probeNodeHealth,ft as withCap,M as withRetry,yt as withoutCap};
|
|
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};
|
|
3
3
|
//# sourceMappingURL=index.browser.mjs.map
|