itd-api 0.7.2 → 0.9.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/README.md +72 -27
- package/dist/events/index.cjs +53 -0
- package/dist/events/index.d.cts +3 -0
- package/dist/events/index.d.ts +3 -0
- package/dist/events/index.js +5 -0
- package/dist/index.cjs +234 -200
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +70 -64
- package/dist/index.d.ts +70 -64
- package/dist/index.js +202 -179
- package/dist/index.js.map +1 -1
- package/dist/node/index.cjs +6 -5
- package/dist/node/index.cjs.map +1 -1
- package/dist/node/index.d.cts +2 -2
- package/dist/node/index.d.ts +2 -2
- package/dist/node/index.js +5 -4
- package/dist/node/index.js.map +1 -1
- package/dist/rest/index.cjs +32 -26
- package/dist/rest/index.cjs.map +1 -1
- package/dist/rest/index.d.cts +9 -7
- package/dist/rest/index.d.ts +9 -7
- package/dist/rest/index.js +19 -21
- package/dist/rest/index.js.map +1 -1
- package/dist/shared/{errors-DfU8M5eS.cjs → errors-BmP3TKoW.cjs} +3 -3
- package/dist/shared/{errors-DfU8M5eS.cjs.map → errors-BmP3TKoW.cjs.map} +1 -1
- package/dist/shared/{errors-Bhrd2fJd.js → errors-GI10kZxk.js} +3 -3
- package/dist/shared/{errors-Bhrd2fJd.js.map → errors-GI10kZxk.js.map} +1 -1
- package/dist/shared/{websocket-BLR8eVJV.js → events-C5wnTXPT.js} +770 -490
- package/dist/shared/events-C5wnTXPT.js.map +1 -0
- package/dist/shared/events-CqtkP65d.d.ts +698 -0
- package/dist/shared/events-DGAWlCaI.d.cts +698 -0
- package/dist/shared/{websocket-C_eI4H2o.cjs → events-FZfnEez0.cjs} +834 -518
- package/dist/shared/events-FZfnEez0.cjs.map +1 -0
- package/dist/shared/{storage-BPJR_k4-.cjs → key-value-store-B5GYVEYZ.cjs} +2 -86
- package/dist/shared/key-value-store-B5GYVEYZ.cjs.map +1 -0
- package/dist/shared/{storage-D86edNCB.js → key-value-store-Bt2PSMxY.js} +3 -69
- package/dist/shared/key-value-store-Bt2PSMxY.js.map +1 -0
- package/dist/shared/key-value-store-COZaNHZS.d.cts +69 -0
- package/dist/shared/key-value-store-COZaNHZS.d.ts +69 -0
- package/dist/shared/{multi-storage-DccjD7Ww.d.ts → multi-storage-BEL7tcKn.d.cts} +3 -2
- package/dist/shared/{multi-storage--yTEqiod.cjs → multi-storage-CDKLa956.cjs} +11 -10
- package/dist/shared/{multi-storage--yTEqiod.cjs.map → multi-storage-CDKLa956.cjs.map} +1 -1
- package/dist/shared/{multi-storage-CjAPB5Kq.d.cts → multi-storage-LkljOSzA.d.ts} +3 -2
- package/dist/shared/{multi-storage-CkvTUC5m.js → multi-storage-SoW05uzO.js} +5 -4
- package/dist/shared/{multi-storage-CkvTUC5m.js.map → multi-storage-SoW05uzO.js.map} +1 -1
- package/dist/shared/{options-Dg5N3r1V.cjs → options-DOJYtoti.cjs} +8 -6
- package/dist/shared/options-DOJYtoti.cjs.map +1 -0
- package/dist/shared/{options-DtATYdLr.js → options-DhgGg7Ms.js} +8 -6
- package/dist/shared/options-DhgGg7Ms.js.map +1 -0
- package/dist/shared/{cookies-DZwFq6kr.cjs → redact-BP00URmQ.cjs} +312 -2
- package/dist/shared/redact-BP00URmQ.cjs.map +1 -0
- package/dist/shared/{cookies-tX2sNwxb.js → redact-Ba5iSVYZ.js} +235 -3
- package/dist/shared/redact-Ba5iSVYZ.js.map +1 -0
- package/dist/shared/{render-CgwKdOzu.d.ts → render-B4qis7Sb.d.ts} +775 -313
- package/dist/shared/{render-DO0F5YSm.d.cts → render-DDwy2Ame.d.cts} +775 -313
- package/dist/shared/{render-mcuELiYi.cjs → render-Dqi8Owqk.cjs} +1464 -662
- package/dist/shared/render-Dqi8Owqk.cjs.map +1 -0
- package/dist/shared/{render-C6HRPs10.js → render-hiWFh2s4.js} +1366 -618
- package/dist/shared/render-hiWFh2s4.js.map +1 -0
- package/dist/shared/storage-BQrtKon9.d.cts +86 -0
- package/dist/shared/storage-CTRGT5wF.d.ts +86 -0
- package/dist/shared/storage-CfHKzVHf.js +71 -0
- package/dist/shared/storage-CfHKzVHf.js.map +1 -0
- package/dist/shared/storage-QNVxzpDB.cjs +88 -0
- package/dist/shared/storage-QNVxzpDB.cjs.map +1 -0
- package/dist/shared/{url-BaMCQpYH.cjs → url-Bsb3xE5U.cjs} +577 -466
- package/dist/shared/url-Bsb3xE5U.cjs.map +1 -0
- package/dist/shared/{url-IU0xN9wX.js → url-DP33mp3s.js} +508 -409
- package/dist/shared/url-DP33mp3s.js.map +1 -0
- package/dist/shared/{url-DTfZ2toq.d.ts → url-XBsMdAcv.d.cts} +1313 -1200
- package/dist/shared/{url-DTfZ2toq.d.cts → url-XBsMdAcv.d.ts} +1313 -1200
- package/dist/web/index.cjs +5 -4
- package/dist/web/index.cjs.map +1 -1
- package/dist/web/index.d.cts +1 -1
- package/dist/web/index.d.ts +1 -1
- package/dist/web/index.js +3 -2
- package/dist/web/index.js.map +1 -1
- package/package.json +16 -15
- package/dist/realtime/index.cjs +0 -165
- package/dist/realtime/index.cjs.map +0 -1
- package/dist/realtime/index.d.cts +0 -51
- package/dist/realtime/index.d.ts +0 -51
- package/dist/realtime/index.js +0 -120
- package/dist/realtime/index.js.map +0 -1
- package/dist/shared/auth-provider-CG8oCQ9F.cjs +0 -108
- package/dist/shared/auth-provider-CG8oCQ9F.cjs.map +0 -1
- package/dist/shared/auth-provider-mYqxsSVa.js +0 -91
- package/dist/shared/auth-provider-mYqxsSVa.js.map +0 -1
- package/dist/shared/cookies-DZwFq6kr.cjs.map +0 -1
- package/dist/shared/cookies-tX2sNwxb.js.map +0 -1
- package/dist/shared/options-Dg5N3r1V.cjs.map +0 -1
- package/dist/shared/options-DtATYdLr.js.map +0 -1
- package/dist/shared/render-C6HRPs10.js.map +0 -1
- package/dist/shared/render-mcuELiYi.cjs.map +0 -1
- package/dist/shared/storage-BPJR_k4-.cjs.map +0 -1
- package/dist/shared/storage-C_eICCep.d.cts +0 -152
- package/dist/shared/storage-C_eICCep.d.ts +0 -152
- package/dist/shared/storage-D86edNCB.js.map +0 -1
- package/dist/shared/url-BaMCQpYH.cjs.map +0 -1
- package/dist/shared/url-IU0xN9wX.js.map +0 -1
- package/dist/shared/websocket-BLR8eVJV.js.map +0 -1
- package/dist/shared/websocket-C_eI4H2o.cjs.map +0 -1
- package/dist/shared/websocket-DF7XIMiX.d.cts +0 -562
- package/dist/shared/websocket-DYKBr8HF.d.ts +0 -562
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { r as KeyValueStore } from "./key-value-store-COZaNHZS.cjs";
|
|
2
|
+
//#region src/session/storage.d.ts
|
|
3
|
+
/**
|
|
4
|
+
* Сохранённая сессия.
|
|
5
|
+
*
|
|
6
|
+
* Кроме токенов сюда попадают cookie: refresh-токен итд.com живёт именно в cookie, и без них
|
|
7
|
+
* восстановить сессию после перезапуска процесса невозможно.
|
|
8
|
+
*/
|
|
9
|
+
interface ItdSession {
|
|
10
|
+
/** Токен доступа для заголовка `Authorization: Bearer`. */
|
|
11
|
+
accessToken?: string | undefined;
|
|
12
|
+
/**
|
|
13
|
+
* Refresh-токен, если удалось получить его явным значением.
|
|
14
|
+
*
|
|
15
|
+
* Обычно сервер держит его в httpOnly-cookie и наружу не отдаёт — тогда поле останется
|
|
16
|
+
* пустым, а обновление пойдёт через {@link ItdSession.cookies}.
|
|
17
|
+
*/
|
|
18
|
+
refreshToken?: string | undefined;
|
|
19
|
+
/** Сырые cookie в форме `имя=значение`, привязанные к origin API. */
|
|
20
|
+
cookies?: string[] | undefined;
|
|
21
|
+
/**
|
|
22
|
+
* Идентификатор устройства для заголовка `X-Device-Id`.
|
|
23
|
+
*
|
|
24
|
+
* Сервер различает по нему записи в списке сессий, поэтому значение должно пережить
|
|
25
|
+
* перезапуск процесса — иначе каждый старт бота порождает новую сессию. Библиотека
|
|
26
|
+
* заводит его сама при первом запросе и хранит здесь.
|
|
27
|
+
*/
|
|
28
|
+
deviceId?: string | undefined;
|
|
29
|
+
/** Когда сессия получена, мс с начала эпохи. Нужно для диагностики. */
|
|
30
|
+
obtainedAt?: number | undefined;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Хранилище сессии.
|
|
34
|
+
*
|
|
35
|
+
* Подключаемый компонент: библиотека не знает, где вы держите токены, и обращается к ним
|
|
36
|
+
* только через этот интерфейс. Все методы могут быть как синхронными, так и асинхронными.
|
|
37
|
+
*
|
|
38
|
+
* @example Своё хранилище поверх AsyncStorage в React Native
|
|
39
|
+
* ```ts
|
|
40
|
+
* const backend = withCodec(createKeyValueStore({
|
|
41
|
+
* get: (key) => AsyncStorage.getItem(key).then((value) => value ?? undefined),
|
|
42
|
+
* set: (key, value) => AsyncStorage.setItem(key, value),
|
|
43
|
+
* delete: (key) => AsyncStorage.removeItem(key),
|
|
44
|
+
* }), { encode: JSON.stringify, decode: JSON.parse });
|
|
45
|
+
* const storage = createTokenStorage(withNamespace(backend, 'my-app'));
|
|
46
|
+
* ```
|
|
47
|
+
*/
|
|
48
|
+
interface TokenStorage {
|
|
49
|
+
/** Прочитать сессию. `null`, если её нет. */
|
|
50
|
+
get(): ItdSession | null | Promise<ItdSession | null>;
|
|
51
|
+
/** Сохранить сессию целиком. */
|
|
52
|
+
set(session: ItdSession): void | Promise<void>;
|
|
53
|
+
/** Удалить сессию. Вызывается при выходе и при неудачном обновлении токена. */
|
|
54
|
+
clear(): void | Promise<void>;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Хранилище в памяти процесса — вариант по умолчанию.
|
|
58
|
+
*
|
|
59
|
+
* Сессия теряется при перезапуске. Для долгоживущих ботов возьмите `FileTokenStorage`
|
|
60
|
+
* из `itd-api/node`, для браузера — `LocalStorageTokenStorage` или
|
|
61
|
+
* `SessionStorageTokenStorage` из `itd-api/web`.
|
|
62
|
+
*/
|
|
63
|
+
declare class MemoryTokenStorage implements TokenStorage {
|
|
64
|
+
#private;
|
|
65
|
+
constructor(initial?: ItdSession | null);
|
|
66
|
+
get(): ItdSession | null;
|
|
67
|
+
set(session: ItdSession): void;
|
|
68
|
+
clear(): void;
|
|
69
|
+
}
|
|
70
|
+
/** Настройки доменного адаптера одной сессии. */
|
|
71
|
+
interface TokenStorageAdapterOptions {
|
|
72
|
+
/** Ключ сессии в backend. По умолчанию `session`. */
|
|
73
|
+
key?: string | undefined;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Создаёт доменное хранилище сессии поверх общего {@link KeyValueStore}.
|
|
77
|
+
*
|
|
78
|
+
* @example
|
|
79
|
+
* ```ts
|
|
80
|
+
* const storage = createTokenStorage(withNamespace(redisStore, 'itd'));
|
|
81
|
+
* ```
|
|
82
|
+
*/
|
|
83
|
+
declare function createTokenStorage(store: KeyValueStore<ItdSession>, options?: TokenStorageAdapterOptions): TokenStorage;
|
|
84
|
+
//#endregion
|
|
85
|
+
export { createTokenStorage as a, TokenStorageAdapterOptions as i, MemoryTokenStorage as n, TokenStorage as r, ItdSession as t };
|
|
86
|
+
//# sourceMappingURL=storage-BQrtKon9.d.cts.map
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { r as KeyValueStore } from "./key-value-store-COZaNHZS.js";
|
|
2
|
+
//#region src/session/storage.d.ts
|
|
3
|
+
/**
|
|
4
|
+
* Сохранённая сессия.
|
|
5
|
+
*
|
|
6
|
+
* Кроме токенов сюда попадают cookie: refresh-токен итд.com живёт именно в cookie, и без них
|
|
7
|
+
* восстановить сессию после перезапуска процесса невозможно.
|
|
8
|
+
*/
|
|
9
|
+
interface ItdSession {
|
|
10
|
+
/** Токен доступа для заголовка `Authorization: Bearer`. */
|
|
11
|
+
accessToken?: string | undefined;
|
|
12
|
+
/**
|
|
13
|
+
* Refresh-токен, если удалось получить его явным значением.
|
|
14
|
+
*
|
|
15
|
+
* Обычно сервер держит его в httpOnly-cookie и наружу не отдаёт — тогда поле останется
|
|
16
|
+
* пустым, а обновление пойдёт через {@link ItdSession.cookies}.
|
|
17
|
+
*/
|
|
18
|
+
refreshToken?: string | undefined;
|
|
19
|
+
/** Сырые cookie в форме `имя=значение`, привязанные к origin API. */
|
|
20
|
+
cookies?: string[] | undefined;
|
|
21
|
+
/**
|
|
22
|
+
* Идентификатор устройства для заголовка `X-Device-Id`.
|
|
23
|
+
*
|
|
24
|
+
* Сервер различает по нему записи в списке сессий, поэтому значение должно пережить
|
|
25
|
+
* перезапуск процесса — иначе каждый старт бота порождает новую сессию. Библиотека
|
|
26
|
+
* заводит его сама при первом запросе и хранит здесь.
|
|
27
|
+
*/
|
|
28
|
+
deviceId?: string | undefined;
|
|
29
|
+
/** Когда сессия получена, мс с начала эпохи. Нужно для диагностики. */
|
|
30
|
+
obtainedAt?: number | undefined;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Хранилище сессии.
|
|
34
|
+
*
|
|
35
|
+
* Подключаемый компонент: библиотека не знает, где вы держите токены, и обращается к ним
|
|
36
|
+
* только через этот интерфейс. Все методы могут быть как синхронными, так и асинхронными.
|
|
37
|
+
*
|
|
38
|
+
* @example Своё хранилище поверх AsyncStorage в React Native
|
|
39
|
+
* ```ts
|
|
40
|
+
* const backend = withCodec(createKeyValueStore({
|
|
41
|
+
* get: (key) => AsyncStorage.getItem(key).then((value) => value ?? undefined),
|
|
42
|
+
* set: (key, value) => AsyncStorage.setItem(key, value),
|
|
43
|
+
* delete: (key) => AsyncStorage.removeItem(key),
|
|
44
|
+
* }), { encode: JSON.stringify, decode: JSON.parse });
|
|
45
|
+
* const storage = createTokenStorage(withNamespace(backend, 'my-app'));
|
|
46
|
+
* ```
|
|
47
|
+
*/
|
|
48
|
+
interface TokenStorage {
|
|
49
|
+
/** Прочитать сессию. `null`, если её нет. */
|
|
50
|
+
get(): ItdSession | null | Promise<ItdSession | null>;
|
|
51
|
+
/** Сохранить сессию целиком. */
|
|
52
|
+
set(session: ItdSession): void | Promise<void>;
|
|
53
|
+
/** Удалить сессию. Вызывается при выходе и при неудачном обновлении токена. */
|
|
54
|
+
clear(): void | Promise<void>;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Хранилище в памяти процесса — вариант по умолчанию.
|
|
58
|
+
*
|
|
59
|
+
* Сессия теряется при перезапуске. Для долгоживущих ботов возьмите `FileTokenStorage`
|
|
60
|
+
* из `itd-api/node`, для браузера — `LocalStorageTokenStorage` или
|
|
61
|
+
* `SessionStorageTokenStorage` из `itd-api/web`.
|
|
62
|
+
*/
|
|
63
|
+
declare class MemoryTokenStorage implements TokenStorage {
|
|
64
|
+
#private;
|
|
65
|
+
constructor(initial?: ItdSession | null);
|
|
66
|
+
get(): ItdSession | null;
|
|
67
|
+
set(session: ItdSession): void;
|
|
68
|
+
clear(): void;
|
|
69
|
+
}
|
|
70
|
+
/** Настройки доменного адаптера одной сессии. */
|
|
71
|
+
interface TokenStorageAdapterOptions {
|
|
72
|
+
/** Ключ сессии в backend. По умолчанию `session`. */
|
|
73
|
+
key?: string | undefined;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Создаёт доменное хранилище сессии поверх общего {@link KeyValueStore}.
|
|
77
|
+
*
|
|
78
|
+
* @example
|
|
79
|
+
* ```ts
|
|
80
|
+
* const storage = createTokenStorage(withNamespace(redisStore, 'itd'));
|
|
81
|
+
* ```
|
|
82
|
+
*/
|
|
83
|
+
declare function createTokenStorage(store: KeyValueStore<ItdSession>, options?: TokenStorageAdapterOptions): TokenStorage;
|
|
84
|
+
//#endregion
|
|
85
|
+
export { createTokenStorage as a, TokenStorageAdapterOptions as i, MemoryTokenStorage as n, TokenStorage as r, ItdSession as t };
|
|
86
|
+
//# sourceMappingURL=storage-CTRGT5wF.d.ts.map
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { a as ItdConfigError } from "./errors-GI10kZxk.js";
|
|
2
|
+
import { r as createKeyValueStore, t as MemoryKeyValueStore } from "./key-value-store-Bt2PSMxY.js";
|
|
3
|
+
//#region src/session/storage.ts
|
|
4
|
+
/**
|
|
5
|
+
* Создаёт независимый снимок сессии.
|
|
6
|
+
*
|
|
7
|
+
* Сессии пересекают границу пользовательского кода и внутреннего состояния клиента.
|
|
8
|
+
* Возвращать или сохранять их по ссылке нельзя: последующая мутация объекта или массива
|
|
9
|
+
* cookie меняла бы уже сохранённую сессию без вызова `set()`.
|
|
10
|
+
*
|
|
11
|
+
* @internal
|
|
12
|
+
*/
|
|
13
|
+
function copySession(session) {
|
|
14
|
+
return {
|
|
15
|
+
...session,
|
|
16
|
+
...session.cookies ? { cookies: [...session.cookies] } : {}
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Хранилище в памяти процесса — вариант по умолчанию.
|
|
21
|
+
*
|
|
22
|
+
* Сессия теряется при перезапуске. Для долгоживущих ботов возьмите `FileTokenStorage`
|
|
23
|
+
* из `itd-api/node`, для браузера — `LocalStorageTokenStorage` или
|
|
24
|
+
* `SessionStorageTokenStorage` из `itd-api/web`.
|
|
25
|
+
*/
|
|
26
|
+
var MemoryTokenStorage = class {
|
|
27
|
+
#store = new MemoryKeyValueStore();
|
|
28
|
+
constructor(initial) {
|
|
29
|
+
if (initial) this.#store.set(TOKEN_STORAGE_KEY, copySession(initial));
|
|
30
|
+
}
|
|
31
|
+
get() {
|
|
32
|
+
const session = this.#store.get(TOKEN_STORAGE_KEY);
|
|
33
|
+
return session ? copySession(session) : null;
|
|
34
|
+
}
|
|
35
|
+
set(session) {
|
|
36
|
+
this.#store.set(TOKEN_STORAGE_KEY, copySession(session));
|
|
37
|
+
}
|
|
38
|
+
clear() {
|
|
39
|
+
this.#store.delete(TOKEN_STORAGE_KEY);
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
const TOKEN_STORAGE_KEY = "session";
|
|
43
|
+
function isPromise(value) {
|
|
44
|
+
return typeof value === "object" && value !== null && typeof value.then === "function";
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Создаёт доменное хранилище сессии поверх общего {@link KeyValueStore}.
|
|
48
|
+
*
|
|
49
|
+
* @example
|
|
50
|
+
* ```ts
|
|
51
|
+
* const storage = createTokenStorage(withNamespace(redisStore, 'itd'));
|
|
52
|
+
* ```
|
|
53
|
+
*/
|
|
54
|
+
function createTokenStorage(store, options = {}) {
|
|
55
|
+
const key = options.key ?? TOKEN_STORAGE_KEY;
|
|
56
|
+
if (typeof key !== "string") throw new ItdConfigError("key TokenStorage должен быть строкой");
|
|
57
|
+
const backend = createKeyValueStore(store);
|
|
58
|
+
return {
|
|
59
|
+
get() {
|
|
60
|
+
const value = backend.get(key);
|
|
61
|
+
if (isPromise(value)) return value.then((session) => session ? copySession(session) : null);
|
|
62
|
+
return value ? copySession(value) : null;
|
|
63
|
+
},
|
|
64
|
+
set: (session) => backend.set(key, copySession(session)),
|
|
65
|
+
clear: () => backend.delete(key)
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
//#endregion
|
|
69
|
+
export { copySession as n, createTokenStorage as r, MemoryTokenStorage as t };
|
|
70
|
+
|
|
71
|
+
//# sourceMappingURL=storage-CfHKzVHf.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storage-CfHKzVHf.js","names":["#store"],"sources":["../../src/session/storage.ts"],"sourcesContent":["import { ItdConfigError } from '../core/errors.js';\nimport {\n createKeyValueStore,\n type KeyValueStore,\n MemoryKeyValueStore,\n} from '../core/key-value-store.js';\n\n/**\n * Сохранённая сессия.\n *\n * Кроме токенов сюда попадают cookie: refresh-токен итд.com живёт именно в cookie, и без них\n * восстановить сессию после перезапуска процесса невозможно.\n */\nexport interface ItdSession {\n /** Токен доступа для заголовка `Authorization: Bearer`. */\n accessToken?: string | undefined;\n /**\n * Refresh-токен, если удалось получить его явным значением.\n *\n * Обычно сервер держит его в httpOnly-cookie и наружу не отдаёт — тогда поле останется\n * пустым, а обновление пойдёт через {@link ItdSession.cookies}.\n */\n refreshToken?: string | undefined;\n /** Сырые cookie в форме `имя=значение`, привязанные к origin API. */\n cookies?: string[] | undefined;\n /**\n * Идентификатор устройства для заголовка `X-Device-Id`.\n *\n * Сервер различает по нему записи в списке сессий, поэтому значение должно пережить\n * перезапуск процесса — иначе каждый старт бота порождает новую сессию. Библиотека\n * заводит его сама при первом запросе и хранит здесь.\n */\n deviceId?: string | undefined;\n /** Когда сессия получена, мс с начала эпохи. Нужно для диагностики. */\n obtainedAt?: number | undefined;\n}\n\n/**\n * Создаёт независимый снимок сессии.\n *\n * Сессии пересекают границу пользовательского кода и внутреннего состояния клиента.\n * Возвращать или сохранять их по ссылке нельзя: последующая мутация объекта или массива\n * cookie меняла бы уже сохранённую сессию без вызова `set()`.\n *\n * @internal\n */\nexport function copySession(session: ItdSession): ItdSession {\n return {\n ...session,\n ...(session.cookies ? { cookies: [...session.cookies] } : {}),\n };\n}\n\n/**\n * Хранилище сессии.\n *\n * Подключаемый компонент: библиотека не знает, где вы держите токены, и обращается к ним\n * только через этот интерфейс. Все методы могут быть как синхронными, так и асинхронными.\n *\n * @example Своё хранилище поверх AsyncStorage в React Native\n * ```ts\n * const backend = withCodec(createKeyValueStore({\n * get: (key) => AsyncStorage.getItem(key).then((value) => value ?? undefined),\n * set: (key, value) => AsyncStorage.setItem(key, value),\n * delete: (key) => AsyncStorage.removeItem(key),\n * }), { encode: JSON.stringify, decode: JSON.parse });\n * const storage = createTokenStorage(withNamespace(backend, 'my-app'));\n * ```\n */\nexport interface TokenStorage {\n /** Прочитать сессию. `null`, если её нет. */\n get(): ItdSession | null | Promise<ItdSession | null>;\n /** Сохранить сессию целиком. */\n set(session: ItdSession): void | Promise<void>;\n /** Удалить сессию. Вызывается при выходе и при неудачном обновлении токена. */\n clear(): void | Promise<void>;\n}\n\n/**\n * Хранилище в памяти процесса — вариант по умолчанию.\n *\n * Сессия теряется при перезапуске. Для долгоживущих ботов возьмите `FileTokenStorage`\n * из `itd-api/node`, для браузера — `LocalStorageTokenStorage` или\n * `SessionStorageTokenStorage` из `itd-api/web`.\n */\nexport class MemoryTokenStorage implements TokenStorage {\n readonly #store = new MemoryKeyValueStore<ItdSession>();\n\n constructor(initial?: ItdSession | null) {\n if (initial) this.#store.set(TOKEN_STORAGE_KEY, copySession(initial));\n }\n\n get(): ItdSession | null {\n const session = this.#store.get(TOKEN_STORAGE_KEY);\n return session ? copySession(session) : null;\n }\n\n set(session: ItdSession): void {\n this.#store.set(TOKEN_STORAGE_KEY, copySession(session));\n }\n\n clear(): void {\n this.#store.delete(TOKEN_STORAGE_KEY);\n }\n}\n\nconst TOKEN_STORAGE_KEY = 'session';\n\n/** Настройки доменного адаптера одной сессии. */\nexport interface TokenStorageAdapterOptions {\n /** Ключ сессии в backend. По умолчанию `session`. */\n key?: string | undefined;\n}\n\nfunction isPromise<T>(value: T | Promise<T>): value is Promise<T> {\n return (\n typeof value === 'object' && value !== null && typeof (value as Promise<T>).then === 'function'\n );\n}\n\n/**\n * Создаёт доменное хранилище сессии поверх общего {@link KeyValueStore}.\n *\n * @example\n * ```ts\n * const storage = createTokenStorage(withNamespace(redisStore, 'itd'));\n * ```\n */\nexport function createTokenStorage(\n store: KeyValueStore<ItdSession>,\n options: TokenStorageAdapterOptions = {},\n): TokenStorage {\n const key = options.key ?? TOKEN_STORAGE_KEY;\n if (typeof key !== 'string') throw new ItdConfigError('key TokenStorage должен быть строкой');\n const backend = createKeyValueStore(store);\n return {\n get() {\n const value = backend.get(key);\n if (isPromise(value)) {\n return value.then((session) => (session ? copySession(session) : null));\n }\n return value ? copySession(value) : null;\n },\n set: (session) => backend.set(key, copySession(session)),\n clear: () => backend.delete(key),\n };\n}\n"],"mappings":";;;;;;;;;;;;AA8CA,SAAgB,YAAY,SAAiC;CAC3D,OAAO;EACL,GAAG;EACH,GAAI,QAAQ,UAAU,EAAE,SAAS,CAAC,GAAG,QAAQ,OAAO,EAAE,IAAI,CAAC;CAC7D;AACF;;;;;;;;AAkCA,IAAa,qBAAb,MAAwD;CACtD,SAAkB,IAAI,oBAAgC;CAEtD,YAAY,SAA6B;EACvC,IAAI,SAAS,KAAKA,OAAO,IAAI,mBAAmB,YAAY,OAAO,CAAC;CACtE;CAEA,MAAyB;EACvB,MAAM,UAAU,KAAKA,OAAO,IAAI,iBAAiB;EACjD,OAAO,UAAU,YAAY,OAAO,IAAI;CAC1C;CAEA,IAAI,SAA2B;EAC7B,KAAKA,OAAO,IAAI,mBAAmB,YAAY,OAAO,CAAC;CACzD;CAEA,QAAc;EACZ,KAAKA,OAAO,OAAO,iBAAiB;CACtC;AACF;AAEA,MAAM,oBAAoB;AAQ1B,SAAS,UAAa,OAA4C;CAChE,OACE,OAAO,UAAU,YAAY,UAAU,QAAQ,OAAQ,MAAqB,SAAS;AAEzF;;;;;;;;;AAUA,SAAgB,mBACd,OACA,UAAsC,CAAC,GACzB;CACd,MAAM,MAAM,QAAQ,OAAO;CAC3B,IAAI,OAAO,QAAQ,UAAU,MAAM,IAAI,eAAe,sCAAsC;CAC5F,MAAM,UAAU,oBAAoB,KAAK;CACzC,OAAO;EACL,MAAM;GACJ,MAAM,QAAQ,QAAQ,IAAI,GAAG;GAC7B,IAAI,UAAU,KAAK,GACjB,OAAO,MAAM,MAAM,YAAa,UAAU,YAAY,OAAO,IAAI,IAAK;GAExE,OAAO,QAAQ,YAAY,KAAK,IAAI;EACtC;EACA,MAAM,YAAY,QAAQ,IAAI,KAAK,YAAY,OAAO,CAAC;EACvD,aAAa,QAAQ,OAAO,GAAG;CACjC;AACF"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
const require_errors = require("./errors-BmP3TKoW.cjs");
|
|
2
|
+
const require_key_value_store = require("./key-value-store-B5GYVEYZ.cjs");
|
|
3
|
+
//#region src/session/storage.ts
|
|
4
|
+
/**
|
|
5
|
+
* Создаёт независимый снимок сессии.
|
|
6
|
+
*
|
|
7
|
+
* Сессии пересекают границу пользовательского кода и внутреннего состояния клиента.
|
|
8
|
+
* Возвращать или сохранять их по ссылке нельзя: последующая мутация объекта или массива
|
|
9
|
+
* cookie меняла бы уже сохранённую сессию без вызова `set()`.
|
|
10
|
+
*
|
|
11
|
+
* @internal
|
|
12
|
+
*/
|
|
13
|
+
function copySession(session) {
|
|
14
|
+
return {
|
|
15
|
+
...session,
|
|
16
|
+
...session.cookies ? { cookies: [...session.cookies] } : {}
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Хранилище в памяти процесса — вариант по умолчанию.
|
|
21
|
+
*
|
|
22
|
+
* Сессия теряется при перезапуске. Для долгоживущих ботов возьмите `FileTokenStorage`
|
|
23
|
+
* из `itd-api/node`, для браузера — `LocalStorageTokenStorage` или
|
|
24
|
+
* `SessionStorageTokenStorage` из `itd-api/web`.
|
|
25
|
+
*/
|
|
26
|
+
var MemoryTokenStorage = class {
|
|
27
|
+
#store = new require_key_value_store.MemoryKeyValueStore();
|
|
28
|
+
constructor(initial) {
|
|
29
|
+
if (initial) this.#store.set(TOKEN_STORAGE_KEY, copySession(initial));
|
|
30
|
+
}
|
|
31
|
+
get() {
|
|
32
|
+
const session = this.#store.get(TOKEN_STORAGE_KEY);
|
|
33
|
+
return session ? copySession(session) : null;
|
|
34
|
+
}
|
|
35
|
+
set(session) {
|
|
36
|
+
this.#store.set(TOKEN_STORAGE_KEY, copySession(session));
|
|
37
|
+
}
|
|
38
|
+
clear() {
|
|
39
|
+
this.#store.delete(TOKEN_STORAGE_KEY);
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
const TOKEN_STORAGE_KEY = "session";
|
|
43
|
+
function isPromise(value) {
|
|
44
|
+
return typeof value === "object" && value !== null && typeof value.then === "function";
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Создаёт доменное хранилище сессии поверх общего {@link KeyValueStore}.
|
|
48
|
+
*
|
|
49
|
+
* @example
|
|
50
|
+
* ```ts
|
|
51
|
+
* const storage = createTokenStorage(withNamespace(redisStore, 'itd'));
|
|
52
|
+
* ```
|
|
53
|
+
*/
|
|
54
|
+
function createTokenStorage(store, options = {}) {
|
|
55
|
+
const key = options.key ?? TOKEN_STORAGE_KEY;
|
|
56
|
+
if (typeof key !== "string") throw new require_errors.ItdConfigError("key TokenStorage должен быть строкой");
|
|
57
|
+
const backend = require_key_value_store.createKeyValueStore(store);
|
|
58
|
+
return {
|
|
59
|
+
get() {
|
|
60
|
+
const value = backend.get(key);
|
|
61
|
+
if (isPromise(value)) return value.then((session) => session ? copySession(session) : null);
|
|
62
|
+
return value ? copySession(value) : null;
|
|
63
|
+
},
|
|
64
|
+
set: (session) => backend.set(key, copySession(session)),
|
|
65
|
+
clear: () => backend.delete(key)
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
//#endregion
|
|
69
|
+
Object.defineProperty(exports, "MemoryTokenStorage", {
|
|
70
|
+
enumerable: true,
|
|
71
|
+
get: function() {
|
|
72
|
+
return MemoryTokenStorage;
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
Object.defineProperty(exports, "copySession", {
|
|
76
|
+
enumerable: true,
|
|
77
|
+
get: function() {
|
|
78
|
+
return copySession;
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
Object.defineProperty(exports, "createTokenStorage", {
|
|
82
|
+
enumerable: true,
|
|
83
|
+
get: function() {
|
|
84
|
+
return createTokenStorage;
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
//# sourceMappingURL=storage-QNVxzpDB.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storage-QNVxzpDB.cjs","names":["#store","MemoryKeyValueStore","ItdConfigError","createKeyValueStore"],"sources":["../../src/session/storage.ts"],"sourcesContent":["import { ItdConfigError } from '../core/errors.js';\nimport {\n createKeyValueStore,\n type KeyValueStore,\n MemoryKeyValueStore,\n} from '../core/key-value-store.js';\n\n/**\n * Сохранённая сессия.\n *\n * Кроме токенов сюда попадают cookie: refresh-токен итд.com живёт именно в cookie, и без них\n * восстановить сессию после перезапуска процесса невозможно.\n */\nexport interface ItdSession {\n /** Токен доступа для заголовка `Authorization: Bearer`. */\n accessToken?: string | undefined;\n /**\n * Refresh-токен, если удалось получить его явным значением.\n *\n * Обычно сервер держит его в httpOnly-cookie и наружу не отдаёт — тогда поле останется\n * пустым, а обновление пойдёт через {@link ItdSession.cookies}.\n */\n refreshToken?: string | undefined;\n /** Сырые cookie в форме `имя=значение`, привязанные к origin API. */\n cookies?: string[] | undefined;\n /**\n * Идентификатор устройства для заголовка `X-Device-Id`.\n *\n * Сервер различает по нему записи в списке сессий, поэтому значение должно пережить\n * перезапуск процесса — иначе каждый старт бота порождает новую сессию. Библиотека\n * заводит его сама при первом запросе и хранит здесь.\n */\n deviceId?: string | undefined;\n /** Когда сессия получена, мс с начала эпохи. Нужно для диагностики. */\n obtainedAt?: number | undefined;\n}\n\n/**\n * Создаёт независимый снимок сессии.\n *\n * Сессии пересекают границу пользовательского кода и внутреннего состояния клиента.\n * Возвращать или сохранять их по ссылке нельзя: последующая мутация объекта или массива\n * cookie меняла бы уже сохранённую сессию без вызова `set()`.\n *\n * @internal\n */\nexport function copySession(session: ItdSession): ItdSession {\n return {\n ...session,\n ...(session.cookies ? { cookies: [...session.cookies] } : {}),\n };\n}\n\n/**\n * Хранилище сессии.\n *\n * Подключаемый компонент: библиотека не знает, где вы держите токены, и обращается к ним\n * только через этот интерфейс. Все методы могут быть как синхронными, так и асинхронными.\n *\n * @example Своё хранилище поверх AsyncStorage в React Native\n * ```ts\n * const backend = withCodec(createKeyValueStore({\n * get: (key) => AsyncStorage.getItem(key).then((value) => value ?? undefined),\n * set: (key, value) => AsyncStorage.setItem(key, value),\n * delete: (key) => AsyncStorage.removeItem(key),\n * }), { encode: JSON.stringify, decode: JSON.parse });\n * const storage = createTokenStorage(withNamespace(backend, 'my-app'));\n * ```\n */\nexport interface TokenStorage {\n /** Прочитать сессию. `null`, если её нет. */\n get(): ItdSession | null | Promise<ItdSession | null>;\n /** Сохранить сессию целиком. */\n set(session: ItdSession): void | Promise<void>;\n /** Удалить сессию. Вызывается при выходе и при неудачном обновлении токена. */\n clear(): void | Promise<void>;\n}\n\n/**\n * Хранилище в памяти процесса — вариант по умолчанию.\n *\n * Сессия теряется при перезапуске. Для долгоживущих ботов возьмите `FileTokenStorage`\n * из `itd-api/node`, для браузера — `LocalStorageTokenStorage` или\n * `SessionStorageTokenStorage` из `itd-api/web`.\n */\nexport class MemoryTokenStorage implements TokenStorage {\n readonly #store = new MemoryKeyValueStore<ItdSession>();\n\n constructor(initial?: ItdSession | null) {\n if (initial) this.#store.set(TOKEN_STORAGE_KEY, copySession(initial));\n }\n\n get(): ItdSession | null {\n const session = this.#store.get(TOKEN_STORAGE_KEY);\n return session ? copySession(session) : null;\n }\n\n set(session: ItdSession): void {\n this.#store.set(TOKEN_STORAGE_KEY, copySession(session));\n }\n\n clear(): void {\n this.#store.delete(TOKEN_STORAGE_KEY);\n }\n}\n\nconst TOKEN_STORAGE_KEY = 'session';\n\n/** Настройки доменного адаптера одной сессии. */\nexport interface TokenStorageAdapterOptions {\n /** Ключ сессии в backend. По умолчанию `session`. */\n key?: string | undefined;\n}\n\nfunction isPromise<T>(value: T | Promise<T>): value is Promise<T> {\n return (\n typeof value === 'object' && value !== null && typeof (value as Promise<T>).then === 'function'\n );\n}\n\n/**\n * Создаёт доменное хранилище сессии поверх общего {@link KeyValueStore}.\n *\n * @example\n * ```ts\n * const storage = createTokenStorage(withNamespace(redisStore, 'itd'));\n * ```\n */\nexport function createTokenStorage(\n store: KeyValueStore<ItdSession>,\n options: TokenStorageAdapterOptions = {},\n): TokenStorage {\n const key = options.key ?? TOKEN_STORAGE_KEY;\n if (typeof key !== 'string') throw new ItdConfigError('key TokenStorage должен быть строкой');\n const backend = createKeyValueStore(store);\n return {\n get() {\n const value = backend.get(key);\n if (isPromise(value)) {\n return value.then((session) => (session ? copySession(session) : null));\n }\n return value ? copySession(value) : null;\n },\n set: (session) => backend.set(key, copySession(session)),\n clear: () => backend.delete(key),\n };\n}\n"],"mappings":";;;;;;;;;;;;AA8CA,SAAgB,YAAY,SAAiC;CAC3D,OAAO;EACL,GAAG;EACH,GAAI,QAAQ,UAAU,EAAE,SAAS,CAAC,GAAG,QAAQ,OAAO,EAAE,IAAI,CAAC;CAC7D;AACF;;;;;;;;AAkCA,IAAa,qBAAb,MAAwD;CACtD,SAAkB,IAAIC,wBAAAA,oBAAgC;CAEtD,YAAY,SAA6B;EACvC,IAAI,SAAS,KAAKD,OAAO,IAAI,mBAAmB,YAAY,OAAO,CAAC;CACtE;CAEA,MAAyB;EACvB,MAAM,UAAU,KAAKA,OAAO,IAAI,iBAAiB;EACjD,OAAO,UAAU,YAAY,OAAO,IAAI;CAC1C;CAEA,IAAI,SAA2B;EAC7B,KAAKA,OAAO,IAAI,mBAAmB,YAAY,OAAO,CAAC;CACzD;CAEA,QAAc;EACZ,KAAKA,OAAO,OAAO,iBAAiB;CACtC;AACF;AAEA,MAAM,oBAAoB;AAQ1B,SAAS,UAAa,OAA4C;CAChE,OACE,OAAO,UAAU,YAAY,UAAU,QAAQ,OAAQ,MAAqB,SAAS;AAEzF;;;;;;;;;AAUA,SAAgB,mBACd,OACA,UAAsC,CAAC,GACzB;CACd,MAAM,MAAM,QAAQ,OAAO;CAC3B,IAAI,OAAO,QAAQ,UAAU,MAAM,IAAIE,eAAAA,eAAe,sCAAsC;CAC5F,MAAM,UAAUC,wBAAAA,oBAAoB,KAAK;CACzC,OAAO;EACL,MAAM;GACJ,MAAM,QAAQ,QAAQ,IAAI,GAAG;GAC7B,IAAI,UAAU,KAAK,GACjB,OAAO,MAAM,MAAM,YAAa,UAAU,YAAY,OAAO,IAAI,IAAK;GAExE,OAAO,QAAQ,YAAY,KAAK,IAAI;EACtC;EACA,MAAM,YAAY,QAAQ,IAAI,KAAK,YAAY,OAAO,CAAC;EACvD,aAAa,QAAQ,OAAO,GAAG;CACjC;AACF"}
|