@msssystems/mss-link-sdk 0.2.1 → 0.2.3
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/core/http-client.d.ts +3 -1
- package/dist/core/http-client.js +14 -1
- package/dist/core/wasm-crypto-engine.d.ts +1 -0
- package/dist/core/wasm-crypto-engine.js +4 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.js +14 -0
- package/dist/modules/chats/chats.client.d.ts +3 -2
- package/dist/modules/chats/chats.client.js +8 -4
- package/dist/modules/messages/messages.client.d.ts +12 -3
- package/dist/modules/messages/messages.client.js +42 -3
- package/package.json +1 -1
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
export interface HttpClientOptions {
|
|
2
2
|
baseUrl: string;
|
|
3
|
-
token?: string | (() => string | Promise<string>);
|
|
3
|
+
token?: string | (() => string | Promise<string>) | undefined;
|
|
4
4
|
fetch?: typeof fetch;
|
|
5
|
+
onUnauthorized?: (() => Promise<void>) | undefined;
|
|
5
6
|
}
|
|
6
7
|
export declare class HttpClient {
|
|
7
8
|
private baseUrl;
|
|
8
9
|
private token?;
|
|
9
10
|
private customFetch;
|
|
11
|
+
private onUnauthorized?;
|
|
10
12
|
constructor(options: HttpClientOptions);
|
|
11
13
|
setToken(token: string): Promise<void>;
|
|
12
14
|
private getHeaders;
|
package/dist/core/http-client.js
CHANGED
|
@@ -3,9 +3,11 @@ export class HttpClient {
|
|
|
3
3
|
baseUrl;
|
|
4
4
|
token;
|
|
5
5
|
customFetch;
|
|
6
|
+
onUnauthorized;
|
|
6
7
|
constructor(options) {
|
|
7
8
|
this.baseUrl = options.baseUrl.replace(/\/$/, '');
|
|
8
9
|
this.token = options.token;
|
|
10
|
+
this.onUnauthorized = options.onUnauthorized;
|
|
9
11
|
// Fallback to global fetch if not provided
|
|
10
12
|
this.customFetch = options.fetch ?? (typeof globalThis !== 'undefined' ? globalThis.fetch.bind(globalThis) : fetch);
|
|
11
13
|
}
|
|
@@ -42,7 +44,18 @@ export class HttpClient {
|
|
|
42
44
|
if (options.body) {
|
|
43
45
|
fetchOptions.body = JSON.stringify(options.body);
|
|
44
46
|
}
|
|
45
|
-
|
|
47
|
+
let response = await this.customFetch(url.toString(), fetchOptions);
|
|
48
|
+
if (response.status === 401 && this.onUnauthorized) {
|
|
49
|
+
try {
|
|
50
|
+
await this.onUnauthorized();
|
|
51
|
+
// Update headers with new token
|
|
52
|
+
fetchOptions.headers = await this.getHeaders(options.headers);
|
|
53
|
+
response = await this.customFetch(url.toString(), fetchOptions);
|
|
54
|
+
}
|
|
55
|
+
catch (refreshError) {
|
|
56
|
+
// If refresh fails, let the original 401 error throw below
|
|
57
|
+
}
|
|
58
|
+
}
|
|
46
59
|
if (!response.ok) {
|
|
47
60
|
let errorPayload;
|
|
48
61
|
try {
|
|
@@ -26,6 +26,7 @@ export declare class WasmCryptoEngine {
|
|
|
26
26
|
private accessToken;
|
|
27
27
|
constructor(options: WasmCryptoEngineOptions);
|
|
28
28
|
setAccessToken(accessToken: string | null): void;
|
|
29
|
+
getLocalCryptoHealth(): Promise<import("./local-crypto-health.contracts").LocalCryptoHealth>;
|
|
29
30
|
ensureReady(): Promise<void>;
|
|
30
31
|
reset(): void;
|
|
31
32
|
runWithClient<T>(callback: (client: WasmMssClientInstance) => Promise<T>): Promise<T>;
|
|
@@ -38,6 +38,10 @@ export class WasmCryptoEngine {
|
|
|
38
38
|
this.accessToken = accessToken;
|
|
39
39
|
this.wasmClient?.setAccessToken(accessToken);
|
|
40
40
|
}
|
|
41
|
+
async getLocalCryptoHealth() {
|
|
42
|
+
const { checkLocalCryptoHealth } = await import('./local-crypto-health');
|
|
43
|
+
return checkLocalCryptoHealth(() => this.ensureReady());
|
|
44
|
+
}
|
|
41
45
|
async ensureReady() {
|
|
42
46
|
try {
|
|
43
47
|
await this.runWithClient(async (client) => {
|
package/dist/index.d.ts
CHANGED
|
@@ -3,4 +3,18 @@ export * from './client';
|
|
|
3
3
|
export * from './contracts/capabilities.contract';
|
|
4
4
|
export * from './contracts/commands.contract';
|
|
5
5
|
export * from './contracts/health.contract';
|
|
6
|
+
export * from './contracts/chat.contract';
|
|
7
|
+
export * from './contracts/user-search.contract';
|
|
6
8
|
export * from './errors/control-errors';
|
|
9
|
+
export * from './modules/media/media-crypto.contracts';
|
|
10
|
+
export * from './modules/media/media-message.contracts';
|
|
11
|
+
export * from './modules/messages/message.contracts';
|
|
12
|
+
export * from './modules/messages/message-decryption.contracts';
|
|
13
|
+
export * from './modules/messages/message-decryption-state';
|
|
14
|
+
export * from './modules/storage/drive-file-runtime.contracts';
|
|
15
|
+
export * from './modules/storage/drive-file-runtime';
|
|
16
|
+
export * from './modules/storage/drive-key-wrapping.contracts';
|
|
17
|
+
export * from './modules/storage/drive-sharing.contracts';
|
|
18
|
+
export * from './modules/storage/storage-metadata-crypto.contracts';
|
|
19
|
+
export * from './core/local-crypto-health.contracts';
|
|
20
|
+
export * from './core/local-crypto-health';
|
package/dist/index.js
CHANGED
|
@@ -3,4 +3,18 @@ export * from './client';
|
|
|
3
3
|
export * from './contracts/capabilities.contract';
|
|
4
4
|
export * from './contracts/commands.contract';
|
|
5
5
|
export * from './contracts/health.contract';
|
|
6
|
+
export * from './contracts/chat.contract';
|
|
7
|
+
export * from './contracts/user-search.contract';
|
|
6
8
|
export * from './errors/control-errors';
|
|
9
|
+
export * from './modules/media/media-crypto.contracts';
|
|
10
|
+
export * from './modules/media/media-message.contracts';
|
|
11
|
+
export * from './modules/messages/message.contracts';
|
|
12
|
+
export * from './modules/messages/message-decryption.contracts';
|
|
13
|
+
export * from './modules/messages/message-decryption-state';
|
|
14
|
+
export * from './modules/storage/drive-file-runtime.contracts';
|
|
15
|
+
export * from './modules/storage/drive-file-runtime';
|
|
16
|
+
export * from './modules/storage/drive-key-wrapping.contracts';
|
|
17
|
+
export * from './modules/storage/drive-sharing.contracts';
|
|
18
|
+
export * from './modules/storage/storage-metadata-crypto.contracts';
|
|
19
|
+
export * from './core/local-crypto-health.contracts';
|
|
20
|
+
export * from './core/local-crypto-health';
|
|
@@ -4,8 +4,9 @@ export declare class ChatsClient {
|
|
|
4
4
|
constructor(http: HttpClient);
|
|
5
5
|
list(): Promise<any[]>;
|
|
6
6
|
getDetails(chatId: string): Promise<any>;
|
|
7
|
-
createDirect(
|
|
8
|
-
createGroup(
|
|
7
|
+
createDirect(input: any): Promise<any>;
|
|
8
|
+
createGroup(input: any): Promise<any>;
|
|
9
|
+
searchUsers(query: string): Promise<any>;
|
|
9
10
|
archive(chatId: string): Promise<any>;
|
|
10
11
|
hide(chatId: string): Promise<any>;
|
|
11
12
|
}
|
|
@@ -10,11 +10,15 @@ export class ChatsClient {
|
|
|
10
10
|
async getDetails(chatId) {
|
|
11
11
|
return this.http.get(`/link/v1/chats/${chatId}`);
|
|
12
12
|
}
|
|
13
|
-
async createDirect(
|
|
14
|
-
return this.http.post('/link/v1/chats/direct',
|
|
13
|
+
async createDirect(input) {
|
|
14
|
+
return this.http.post('/link/v1/chats/direct', input);
|
|
15
15
|
}
|
|
16
|
-
async createGroup(
|
|
17
|
-
return this.http.post('/link/v1/chats/group',
|
|
16
|
+
async createGroup(input) {
|
|
17
|
+
return this.http.post('/link/v1/chats/group', input);
|
|
18
|
+
}
|
|
19
|
+
async searchUsers(query) {
|
|
20
|
+
return this.http.get('/link/v1/users/search', { params: { q: query } })
|
|
21
|
+
.then(response => response.users);
|
|
18
22
|
}
|
|
19
23
|
async archive(chatId) {
|
|
20
24
|
return this.http.post(`/link/v1/chats/${chatId}/archive`);
|
|
@@ -2,7 +2,16 @@ import { HttpClient } from '../../core/http-client';
|
|
|
2
2
|
export declare class MessagesClient {
|
|
3
3
|
private readonly http;
|
|
4
4
|
constructor(http: HttpClient);
|
|
5
|
-
list(
|
|
6
|
-
markDelivered(
|
|
7
|
-
markRead(
|
|
5
|
+
list(input: any): Promise<any>;
|
|
6
|
+
markDelivered(input: any): Promise<any>;
|
|
7
|
+
markRead(input: any): Promise<any>;
|
|
8
|
+
createMediaUpload(input: any): Promise<any>;
|
|
9
|
+
getMediaAssetUrl(assetId: string): Promise<any>;
|
|
10
|
+
downloadMediaAsset(assetId: string): Promise<{
|
|
11
|
+
blob: Blob;
|
|
12
|
+
fileName: string | undefined;
|
|
13
|
+
}>;
|
|
14
|
+
getSyncCheckpoint(): Promise<any>;
|
|
15
|
+
getSyncEvents(input?: any): Promise<any>;
|
|
16
|
+
acknowledgeSyncCheckpoint(input: any): Promise<any>;
|
|
8
17
|
}
|
|
@@ -4,21 +4,60 @@ export class MessagesClient {
|
|
|
4
4
|
constructor(http) {
|
|
5
5
|
this.http = http;
|
|
6
6
|
}
|
|
7
|
-
async list(
|
|
7
|
+
async list(input) {
|
|
8
|
+
const { chatId, before, after, limit = 30 } = input;
|
|
8
9
|
return this.http.get(`/link/v1/chats/${chatId}/messages`, {
|
|
9
10
|
params: { limit, before, after }
|
|
10
11
|
});
|
|
11
12
|
}
|
|
12
|
-
async markDelivered(
|
|
13
|
+
async markDelivered(input) {
|
|
14
|
+
const { chatId, throughMessageId, limit } = input;
|
|
13
15
|
return this.http.post(`/link/v1/chats/${chatId}/messages/delivered`, {
|
|
14
16
|
throughMessageId,
|
|
15
17
|
limit
|
|
16
18
|
});
|
|
17
19
|
}
|
|
18
|
-
async markRead(
|
|
20
|
+
async markRead(input) {
|
|
21
|
+
const { chatId, throughMessageId, limit } = input;
|
|
19
22
|
return this.http.post(`/link/v1/chats/${chatId}/messages/read`, {
|
|
20
23
|
throughMessageId,
|
|
21
24
|
limit
|
|
22
25
|
});
|
|
23
26
|
}
|
|
27
|
+
async createMediaUpload(input) {
|
|
28
|
+
return this.http.post('/link/v1/media/uploads', input);
|
|
29
|
+
}
|
|
30
|
+
async getMediaAssetUrl(assetId) {
|
|
31
|
+
return this.http.get(`/link/v1/media/assets/${assetId}/url`);
|
|
32
|
+
}
|
|
33
|
+
async downloadMediaAsset(assetId) {
|
|
34
|
+
const res = await fetch(`${this.http['baseUrl']}/link/v1/media/assets/${assetId}/download`, {
|
|
35
|
+
headers: await this.http['getHeaders']()
|
|
36
|
+
});
|
|
37
|
+
if (!res.ok)
|
|
38
|
+
throw new Error('Download failed');
|
|
39
|
+
const blob = await res.blob();
|
|
40
|
+
const disposition = res.headers.get('content-disposition');
|
|
41
|
+
let fileName;
|
|
42
|
+
if (disposition && disposition.indexOf('filename=') !== -1) {
|
|
43
|
+
const filenameRegex = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/;
|
|
44
|
+
const matches = filenameRegex.exec(disposition);
|
|
45
|
+
if (matches != null && matches[1]) {
|
|
46
|
+
fileName = matches[1].replace(/['"]/g, '');
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return { blob, fileName };
|
|
50
|
+
}
|
|
51
|
+
async getSyncCheckpoint() {
|
|
52
|
+
return this.http.get('/link/v1/sync/checkpoint');
|
|
53
|
+
}
|
|
54
|
+
async getSyncEvents(input = {}) {
|
|
55
|
+
const { cursor, limit = 100 } = input;
|
|
56
|
+
return this.http.get('/link/v1/sync/events', {
|
|
57
|
+
params: { cursor, limit }
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
async acknowledgeSyncCheckpoint(input) {
|
|
61
|
+
return this.http.post('/link/v1/sync/ack', input);
|
|
62
|
+
}
|
|
24
63
|
}
|