itd-api 0.8.0 → 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.
Files changed (80) hide show
  1. package/README.md +63 -18
  2. package/dist/events/index.cjs +3 -3
  3. package/dist/events/index.d.cts +2 -2
  4. package/dist/events/index.d.ts +2 -2
  5. package/dist/events/index.js +3 -3
  6. package/dist/index.cjs +26 -13
  7. package/dist/index.cjs.map +1 -1
  8. package/dist/index.d.cts +9 -6
  9. package/dist/index.d.ts +9 -6
  10. package/dist/index.js +13 -8
  11. package/dist/index.js.map +1 -1
  12. package/dist/node/index.cjs +5 -4
  13. package/dist/node/index.cjs.map +1 -1
  14. package/dist/node/index.d.cts +2 -2
  15. package/dist/node/index.d.ts +2 -2
  16. package/dist/node/index.js +4 -3
  17. package/dist/node/index.js.map +1 -1
  18. package/dist/rest/index.cjs +16 -4
  19. package/dist/rest/index.cjs.map +1 -1
  20. package/dist/rest/index.d.cts +5 -3
  21. package/dist/rest/index.d.ts +5 -3
  22. package/dist/rest/index.js +9 -5
  23. package/dist/rest/index.js.map +1 -1
  24. package/dist/shared/{events-TfhKh26b.js → events-C5wnTXPT.js} +3 -3
  25. package/dist/shared/{events-TfhKh26b.js.map → events-C5wnTXPT.js.map} +1 -1
  26. package/dist/shared/{events-QyhQZrnC.d.ts → events-CqtkP65d.d.ts} +2 -2
  27. package/dist/shared/{events-Br2r7coi.d.cts → events-DGAWlCaI.d.cts} +2 -2
  28. package/dist/shared/{events-iTteVsd_.cjs → events-FZfnEez0.cjs} +3 -3
  29. package/dist/shared/{events-iTteVsd_.cjs.map → events-FZfnEez0.cjs.map} +1 -1
  30. package/dist/shared/{storage-BLmXmzKF.cjs → key-value-store-B5GYVEYZ.cjs} +1 -85
  31. package/dist/shared/key-value-store-B5GYVEYZ.cjs.map +1 -0
  32. package/dist/shared/{storage-CCxn0Kkv.js → key-value-store-Bt2PSMxY.js} +2 -68
  33. package/dist/shared/key-value-store-Bt2PSMxY.js.map +1 -0
  34. package/dist/shared/key-value-store-COZaNHZS.d.cts +69 -0
  35. package/dist/shared/key-value-store-COZaNHZS.d.ts +69 -0
  36. package/dist/shared/{multi-storage-DccjD7Ww.d.ts → multi-storage-BEL7tcKn.d.cts} +3 -2
  37. package/dist/shared/{multi-storage-CCUgkqvI.cjs → multi-storage-CDKLa956.cjs} +8 -7
  38. package/dist/shared/{multi-storage-CCUgkqvI.cjs.map → multi-storage-CDKLa956.cjs.map} +1 -1
  39. package/dist/shared/{multi-storage-CjAPB5Kq.d.cts → multi-storage-LkljOSzA.d.ts} +3 -2
  40. package/dist/shared/{multi-storage-1AEZTczk.js → multi-storage-SoW05uzO.js} +4 -3
  41. package/dist/shared/{multi-storage-1AEZTczk.js.map → multi-storage-SoW05uzO.js.map} +1 -1
  42. package/dist/shared/{options-BUfoHE9G.cjs → options-DOJYtoti.cjs} +2 -2
  43. package/dist/shared/{options-BUfoHE9G.cjs.map → options-DOJYtoti.cjs.map} +1 -1
  44. package/dist/shared/{options-BNP633A5.js → options-DhgGg7Ms.js} +2 -2
  45. package/dist/shared/{options-BNP633A5.js.map → options-DhgGg7Ms.js.map} +1 -1
  46. package/dist/shared/{redact-DB9EMGJx.cjs → redact-BP00URmQ.cjs} +15 -4
  47. package/dist/shared/{redact-DB9EMGJx.cjs.map → redact-BP00URmQ.cjs.map} +1 -1
  48. package/dist/shared/{redact-FNK29Fv-.js → redact-Ba5iSVYZ.js} +15 -4
  49. package/dist/shared/{redact-FNK29Fv-.js.map → redact-Ba5iSVYZ.js.map} +1 -1
  50. package/dist/shared/{render-DVB7T8pm.d.ts → render-B4qis7Sb.d.ts} +348 -3
  51. package/dist/shared/{render-BszcKF7S.d.cts → render-DDwy2Ame.d.cts} +348 -3
  52. package/dist/shared/{render-DNTESBSl.cjs → render-Dqi8Owqk.cjs} +457 -4
  53. package/dist/shared/render-Dqi8Owqk.cjs.map +1 -0
  54. package/dist/shared/{render-CiL1VS0b.js → render-hiWFh2s4.js} +411 -6
  55. package/dist/shared/render-hiWFh2s4.js.map +1 -0
  56. package/dist/shared/storage-BQrtKon9.d.cts +86 -0
  57. package/dist/shared/storage-CTRGT5wF.d.ts +86 -0
  58. package/dist/shared/storage-CfHKzVHf.js +71 -0
  59. package/dist/shared/storage-CfHKzVHf.js.map +1 -0
  60. package/dist/shared/storage-QNVxzpDB.cjs +88 -0
  61. package/dist/shared/storage-QNVxzpDB.cjs.map +1 -0
  62. package/dist/shared/{url-CFN1sT9S.cjs → url-Bsb3xE5U.cjs} +83 -4
  63. package/dist/shared/{url-CFN1sT9S.cjs.map → url-Bsb3xE5U.cjs.map} +1 -1
  64. package/dist/shared/{url-B3ocFlHj.js → url-DP33mp3s.js} +78 -5
  65. package/dist/shared/{url-B3ocFlHj.js.map → url-DP33mp3s.js.map} +1 -1
  66. package/dist/shared/{url-Be9jlWRv.d.ts → url-XBsMdAcv.d.cts} +75 -2
  67. package/dist/shared/{url-Be9jlWRv.d.cts → url-XBsMdAcv.d.ts} +75 -2
  68. package/dist/web/index.cjs +4 -3
  69. package/dist/web/index.cjs.map +1 -1
  70. package/dist/web/index.d.cts +1 -1
  71. package/dist/web/index.d.ts +1 -1
  72. package/dist/web/index.js +2 -1
  73. package/dist/web/index.js.map +1 -1
  74. package/package.json +1 -1
  75. package/dist/shared/render-CiL1VS0b.js.map +0 -1
  76. package/dist/shared/render-DNTESBSl.cjs.map +0 -1
  77. package/dist/shared/storage-BLmXmzKF.cjs.map +0 -1
  78. package/dist/shared/storage-CCxn0Kkv.js.map +0 -1
  79. package/dist/shared/storage-C_eICCep.d.cts +0 -152
  80. package/dist/shared/storage-C_eICCep.d.ts +0 -152
@@ -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"}
@@ -1,5 +1,5 @@
1
1
  const require_errors = require("./errors-BmP3TKoW.cjs");
2
- const require_redact = require("./redact-DB9EMGJx.cjs");
2
+ const require_redact = require("./redact-BP00URmQ.cjs");
3
3
  //#region src/core/async-dispose.ts
4
4
  /**
5
5
  * Подставляет метод `await using` там, где `Symbol.asyncDispose` отсутствует.
@@ -85,7 +85,7 @@ function requireOptionalBoolean(value, name) {
85
85
  //#endregion
86
86
  //#region src/core/version.ts
87
87
  /** Версия библиотеки. Попадает в `User-Agent`. */
88
- const LIBRARY_VERSION = "0.8.0";
88
+ const LIBRARY_VERSION = "0.9.0";
89
89
  //#endregion
90
90
  //#region src/core/config.ts
91
91
  /** Базовый URL API итд.com. Домен записан в punycode: `итд.com`. */
@@ -2608,7 +2608,16 @@ const BUCKET_LIMITS = Object.freeze({
2608
2608
  "posts.create": 5,
2609
2609
  "users.updateMe": 3,
2610
2610
  "reports.create": 3,
2611
- "verification.submit": 3
2611
+ "verification.submit": 3,
2612
+ shop: 150,
2613
+ "shop.delivery.cities": 60,
2614
+ "shop.delivery.calculate": 45,
2615
+ "shop.delivery.points": 30,
2616
+ "shop.consents.record": 15,
2617
+ "shop.orders.pay": 13,
2618
+ "shop.orders.verifyAccessCode": 13,
2619
+ "shop.orders.create": 12,
2620
+ "shop.orders.requestAccessCode": 4
2612
2621
  });
2613
2622
  /** Счётчик, из которого списывается путь без собственного правила на сервере. */
2614
2623
  const DEFAULT_RATE_LIMIT_BUCKET = "default";
@@ -3059,6 +3068,69 @@ const OPERATIONS = freezeOperations({
3059
3068
  "telemetry.interaction": {
3060
3069
  method: "POST",
3061
3070
  retrySafety: RetrySafety.Unsafe
3071
+ },
3072
+ "shop.products.list": {
3073
+ method: "GET",
3074
+ retrySafety: RetrySafety.Safe,
3075
+ bucket: "shop"
3076
+ },
3077
+ "shop.products.get": {
3078
+ method: "GET",
3079
+ retrySafety: RetrySafety.Safe,
3080
+ bucket: "shop"
3081
+ },
3082
+ "shop.delivery.countries": {
3083
+ method: "GET",
3084
+ retrySafety: RetrySafety.Safe,
3085
+ bucket: "shop"
3086
+ },
3087
+ "shop.delivery.cities": {
3088
+ method: "GET",
3089
+ retrySafety: RetrySafety.Safe,
3090
+ bucket: "shop.delivery.cities"
3091
+ },
3092
+ "shop.delivery.points": {
3093
+ method: "GET",
3094
+ retrySafety: RetrySafety.Safe,
3095
+ bucket: "shop.delivery.points"
3096
+ },
3097
+ "shop.delivery.calculate": {
3098
+ method: "POST",
3099
+ retrySafety: RetrySafety.Safe,
3100
+ bucket: "shop.delivery.calculate"
3101
+ },
3102
+ "shop.orders.create": {
3103
+ method: "POST",
3104
+ retrySafety: RetrySafety.Idempotent,
3105
+ bucket: "shop.orders.create"
3106
+ },
3107
+ "shop.orders.list": {
3108
+ method: "GET",
3109
+ retrySafety: RetrySafety.Safe
3110
+ },
3111
+ "shop.orders.get": {
3112
+ method: "GET",
3113
+ retrySafety: RetrySafety.Safe
3114
+ },
3115
+ "shop.orders.pay": {
3116
+ method: "POST",
3117
+ retrySafety: RetrySafety.Unsafe,
3118
+ bucket: "shop.orders.pay"
3119
+ },
3120
+ "shop.orders.requestAccessCode": {
3121
+ method: "POST",
3122
+ retrySafety: RetrySafety.Unsafe,
3123
+ bucket: "shop.orders.requestAccessCode"
3124
+ },
3125
+ "shop.orders.verifyAccessCode": {
3126
+ method: "POST",
3127
+ retrySafety: RetrySafety.Unsafe,
3128
+ bucket: "shop.orders.verifyAccessCode"
3129
+ },
3130
+ "shop.consents.record": {
3131
+ method: "POST",
3132
+ retrySafety: RetrySafety.Unsafe,
3133
+ bucket: "shop.consents.record"
3062
3134
  }
3063
3135
  });
3064
3136
  /** Создаёт контракт результата встроенной операции с проверяемым ID. */
@@ -3356,6 +3428,7 @@ const ItdErrorCode = Object.freeze({
3356
3428
  SESSION_NOT_FOUND: "SESSION_NOT_FOUND",
3357
3429
  MISSING_FLOW_TOKEN: "MISSING_FLOW_TOKEN",
3358
3430
  PROFILE_USERNAME_TAKEN: "PROFILE_USERNAME_TAKEN",
3431
+ PROFILE_USERNAME_RESERVED: "PROFILE_USERNAME_RESERVED",
3359
3432
  PROFILE_RESTRICTION_ACTIVE: "PROFILE_RESTRICTION_ACTIVE",
3360
3433
  PROFILE_MODIFICATION_RESTRICTED: "PROFILE_MODIFICATION_RESTRICTED",
3361
3434
  CONTENT_MODERATION_FAILED: "CONTENT_MODERATION_FAILED",
@@ -4112,5 +4185,11 @@ Object.defineProperty(exports, "voidOperation", {
4112
4185
  return voidOperation;
4113
4186
  }
4114
4187
  });
4188
+ Object.defineProperty(exports, "voidResult", {
4189
+ enumerable: true,
4190
+ get: function() {
4191
+ return voidResult;
4192
+ }
4193
+ });
4115
4194
 
4116
- //# sourceMappingURL=url-CFN1sT9S.cjs.map
4195
+ //# sourceMappingURL=url-Bsb3xE5U.cjs.map