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.
Files changed (104) hide show
  1. package/README.md +72 -27
  2. package/dist/events/index.cjs +53 -0
  3. package/dist/events/index.d.cts +3 -0
  4. package/dist/events/index.d.ts +3 -0
  5. package/dist/events/index.js +5 -0
  6. package/dist/index.cjs +234 -200
  7. package/dist/index.cjs.map +1 -1
  8. package/dist/index.d.cts +70 -64
  9. package/dist/index.d.ts +70 -64
  10. package/dist/index.js +202 -179
  11. package/dist/index.js.map +1 -1
  12. package/dist/node/index.cjs +6 -5
  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 +5 -4
  17. package/dist/node/index.js.map +1 -1
  18. package/dist/rest/index.cjs +32 -26
  19. package/dist/rest/index.cjs.map +1 -1
  20. package/dist/rest/index.d.cts +9 -7
  21. package/dist/rest/index.d.ts +9 -7
  22. package/dist/rest/index.js +19 -21
  23. package/dist/rest/index.js.map +1 -1
  24. package/dist/shared/{errors-DfU8M5eS.cjs → errors-BmP3TKoW.cjs} +3 -3
  25. package/dist/shared/{errors-DfU8M5eS.cjs.map → errors-BmP3TKoW.cjs.map} +1 -1
  26. package/dist/shared/{errors-Bhrd2fJd.js → errors-GI10kZxk.js} +3 -3
  27. package/dist/shared/{errors-Bhrd2fJd.js.map → errors-GI10kZxk.js.map} +1 -1
  28. package/dist/shared/{websocket-BLR8eVJV.js → events-C5wnTXPT.js} +770 -490
  29. package/dist/shared/events-C5wnTXPT.js.map +1 -0
  30. package/dist/shared/events-CqtkP65d.d.ts +698 -0
  31. package/dist/shared/events-DGAWlCaI.d.cts +698 -0
  32. package/dist/shared/{websocket-C_eI4H2o.cjs → events-FZfnEez0.cjs} +834 -518
  33. package/dist/shared/events-FZfnEez0.cjs.map +1 -0
  34. package/dist/shared/{storage-BPJR_k4-.cjs → key-value-store-B5GYVEYZ.cjs} +2 -86
  35. package/dist/shared/key-value-store-B5GYVEYZ.cjs.map +1 -0
  36. package/dist/shared/{storage-D86edNCB.js → key-value-store-Bt2PSMxY.js} +3 -69
  37. package/dist/shared/key-value-store-Bt2PSMxY.js.map +1 -0
  38. package/dist/shared/key-value-store-COZaNHZS.d.cts +69 -0
  39. package/dist/shared/key-value-store-COZaNHZS.d.ts +69 -0
  40. package/dist/shared/{multi-storage-DccjD7Ww.d.ts → multi-storage-BEL7tcKn.d.cts} +3 -2
  41. package/dist/shared/{multi-storage--yTEqiod.cjs → multi-storage-CDKLa956.cjs} +11 -10
  42. package/dist/shared/{multi-storage--yTEqiod.cjs.map → multi-storage-CDKLa956.cjs.map} +1 -1
  43. package/dist/shared/{multi-storage-CjAPB5Kq.d.cts → multi-storage-LkljOSzA.d.ts} +3 -2
  44. package/dist/shared/{multi-storage-CkvTUC5m.js → multi-storage-SoW05uzO.js} +5 -4
  45. package/dist/shared/{multi-storage-CkvTUC5m.js.map → multi-storage-SoW05uzO.js.map} +1 -1
  46. package/dist/shared/{options-Dg5N3r1V.cjs → options-DOJYtoti.cjs} +8 -6
  47. package/dist/shared/options-DOJYtoti.cjs.map +1 -0
  48. package/dist/shared/{options-DtATYdLr.js → options-DhgGg7Ms.js} +8 -6
  49. package/dist/shared/options-DhgGg7Ms.js.map +1 -0
  50. package/dist/shared/{cookies-DZwFq6kr.cjs → redact-BP00URmQ.cjs} +312 -2
  51. package/dist/shared/redact-BP00URmQ.cjs.map +1 -0
  52. package/dist/shared/{cookies-tX2sNwxb.js → redact-Ba5iSVYZ.js} +235 -3
  53. package/dist/shared/redact-Ba5iSVYZ.js.map +1 -0
  54. package/dist/shared/{render-CgwKdOzu.d.ts → render-B4qis7Sb.d.ts} +775 -313
  55. package/dist/shared/{render-DO0F5YSm.d.cts → render-DDwy2Ame.d.cts} +775 -313
  56. package/dist/shared/{render-mcuELiYi.cjs → render-Dqi8Owqk.cjs} +1464 -662
  57. package/dist/shared/render-Dqi8Owqk.cjs.map +1 -0
  58. package/dist/shared/{render-C6HRPs10.js → render-hiWFh2s4.js} +1366 -618
  59. package/dist/shared/render-hiWFh2s4.js.map +1 -0
  60. package/dist/shared/storage-BQrtKon9.d.cts +86 -0
  61. package/dist/shared/storage-CTRGT5wF.d.ts +86 -0
  62. package/dist/shared/storage-CfHKzVHf.js +71 -0
  63. package/dist/shared/storage-CfHKzVHf.js.map +1 -0
  64. package/dist/shared/storage-QNVxzpDB.cjs +88 -0
  65. package/dist/shared/storage-QNVxzpDB.cjs.map +1 -0
  66. package/dist/shared/{url-BaMCQpYH.cjs → url-Bsb3xE5U.cjs} +577 -466
  67. package/dist/shared/url-Bsb3xE5U.cjs.map +1 -0
  68. package/dist/shared/{url-IU0xN9wX.js → url-DP33mp3s.js} +508 -409
  69. package/dist/shared/url-DP33mp3s.js.map +1 -0
  70. package/dist/shared/{url-DTfZ2toq.d.ts → url-XBsMdAcv.d.cts} +1313 -1200
  71. package/dist/shared/{url-DTfZ2toq.d.cts → url-XBsMdAcv.d.ts} +1313 -1200
  72. package/dist/web/index.cjs +5 -4
  73. package/dist/web/index.cjs.map +1 -1
  74. package/dist/web/index.d.cts +1 -1
  75. package/dist/web/index.d.ts +1 -1
  76. package/dist/web/index.js +3 -2
  77. package/dist/web/index.js.map +1 -1
  78. package/package.json +16 -15
  79. package/dist/realtime/index.cjs +0 -165
  80. package/dist/realtime/index.cjs.map +0 -1
  81. package/dist/realtime/index.d.cts +0 -51
  82. package/dist/realtime/index.d.ts +0 -51
  83. package/dist/realtime/index.js +0 -120
  84. package/dist/realtime/index.js.map +0 -1
  85. package/dist/shared/auth-provider-CG8oCQ9F.cjs +0 -108
  86. package/dist/shared/auth-provider-CG8oCQ9F.cjs.map +0 -1
  87. package/dist/shared/auth-provider-mYqxsSVa.js +0 -91
  88. package/dist/shared/auth-provider-mYqxsSVa.js.map +0 -1
  89. package/dist/shared/cookies-DZwFq6kr.cjs.map +0 -1
  90. package/dist/shared/cookies-tX2sNwxb.js.map +0 -1
  91. package/dist/shared/options-Dg5N3r1V.cjs.map +0 -1
  92. package/dist/shared/options-DtATYdLr.js.map +0 -1
  93. package/dist/shared/render-C6HRPs10.js.map +0 -1
  94. package/dist/shared/render-mcuELiYi.cjs.map +0 -1
  95. package/dist/shared/storage-BPJR_k4-.cjs.map +0 -1
  96. package/dist/shared/storage-C_eICCep.d.cts +0 -152
  97. package/dist/shared/storage-C_eICCep.d.ts +0 -152
  98. package/dist/shared/storage-D86edNCB.js.map +0 -1
  99. package/dist/shared/url-BaMCQpYH.cjs.map +0 -1
  100. package/dist/shared/url-IU0xN9wX.js.map +0 -1
  101. package/dist/shared/websocket-BLR8eVJV.js.map +0 -1
  102. package/dist/shared/websocket-C_eI4H2o.cjs.map +0 -1
  103. package/dist/shared/websocket-DF7XIMiX.d.cts +0 -562
  104. package/dist/shared/websocket-DYKBr8HF.d.ts +0 -562
@@ -1,8 +1,9 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_errors = require("../shared/errors-DfU8M5eS.cjs");
3
- const require_storage = require("../shared/storage-BPJR_k4-.cjs");
4
- const require_options = require("../shared/options-Dg5N3r1V.cjs");
5
- const require_multi_storage = require("../shared/multi-storage--yTEqiod.cjs");
2
+ const require_errors = require("../shared/errors-BmP3TKoW.cjs");
3
+ const require_options = require("../shared/options-DOJYtoti.cjs");
4
+ const require_key_value_store = require("../shared/key-value-store-B5GYVEYZ.cjs");
5
+ const require_storage = require("../shared/storage-QNVxzpDB.cjs");
6
+ const require_multi_storage = require("../shared/multi-storage-CDKLa956.cjs");
6
7
  //#region src/node.ts
7
8
  /**
8
9
  * `itd-api/node` — файловая система для Node, Bun и Deno.
@@ -145,7 +146,7 @@ var FileKeyValueStore = class {
145
146
  /** @param path путь к JSON-файлу. Для секретов добавьте его в `.gitignore`. */
146
147
  constructor(path) {
147
148
  this.#path = path;
148
- this.#inner = require_storage.createRecordKeyValueStore({
149
+ this.#inner = require_key_value_store.createRecordKeyValueStore({
149
150
  read: () => this.#read(),
150
151
  write: (values) => writeJsonAtomic(path, {
151
152
  version: FILE_STORE_VERSION,
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":["resolveFileStreamOptions","FileTransferMode","ItdFileError","ItdFileErrorReason","boundedFileStream","ItdConfigError","#path","#inner","createRecordKeyValueStore","#read","createTokenStorage","createMultiTokenStorage"],"sources":["../../src/node.ts"],"sourcesContent":["/**\n * `itd-api/node` — файловая система для Node, Bun и Deno.\n *\n * Здесь лежит только то, что требует `node:fs` и потому не может попасть в основной бандл:\n * иначе браузерные сборщики пытались бы разрешить этот модуль. Клиент, аккаунты, билдеры,\n * типы и всё остальное берутся из `itd-api` — одинаково на всех платформах.\n *\n * @example\n * ```ts\n * import { ItdClient } from 'itd-api';\n * import { FileTokenStorage, fromPath } from 'itd-api/node';\n *\n * // Когда сессия уже сохранена, `auth` не нужен — токен возьмётся из хранилища.\n * const itd = new ItdClient({ storage: new FileTokenStorage('./.itd-session.json') });\n *\n * await itd.posts.create((p) => p.content('привет').attach(fromPath('./photo.jpg')));\n * ```\n *\n * @packageDocumentation\n */\n\nimport { boundedFileStream } from './core/attachments/bounded-stream.js';\nimport {\n type FileStreamOptions,\n FileTransferMode,\n type LazyFile,\n type StreamFile,\n} from './core/attachments/contracts.js';\nimport { resolveFileStreamOptions } from './core/attachments/options.js';\nimport { ItdConfigError, ItdFileError, ItdFileErrorReason } from './core/errors.js';\nimport { createRecordKeyValueStore, type EnumerableKeyValueStore } from './core/key-value-store.js';\nimport { createMultiTokenStorage, type MultiTokenStorage } from './session/multi-storage.js';\nimport { createTokenStorage, type ItdSession, type TokenStorage } from './session/storage.js';\n\n/** Проверяет код системной ошибки без привязки к типам конкретного рантайма. */\nfunction hasErrorCode(error: unknown, code: string): boolean {\n return typeof error === 'object' && error !== null && 'code' in error && error.code === code;\n}\n\n/** Что можно уточнить у файла с диска. */\nexport interface PathFileOptions extends FileStreamOptions {\n /** Имя файла. По умолчанию — имя из пути. */\n filename?: string | undefined;\n /** MIME-тип. По умолчанию определяется по расширению. */\n contentType?: string | undefined;\n}\n\n/**\n * Вложение из файла на диске.\n *\n * Клиент настраивать не нужно: чтение диска приезжает вместе со значением, а не через\n * опцию, поэтому один и тот же клиент принимает и файлы с диска, и всё остальное.\n *\n * По умолчанию файл читается целиком непосредственно перед отправкой. Режим\n * `{ mode: 'stream' }` передаёт его частями и открывает заново при повторной попытке.\n * Модуль `node:fs` подключается динамически.\n *\n * @example\n * ```ts\n * import { ItdClient } from 'itd-api';\n * import { fromPath } from 'itd-api/node';\n *\n * const itd = new ItdClient({ auth });\n *\n * await itd.posts.create((p) =>\n * p.content('смотрите').attach(fromPath('./photo.jpg')),\n * );\n * ```\n */\nexport function fromPath(\n path: string,\n options: PathFileOptions & { mode: typeof FileTransferMode.Stream },\n): StreamFile;\nexport function fromPath(\n path: string,\n options?: PathFileOptions & { mode?: typeof FileTransferMode.Buffer },\n): LazyFile;\nexport function fromPath(path: string, options: PathFileOptions): LazyFile | StreamFile;\nexport function fromPath(path: string, options: PathFileOptions = {}): LazyFile | StreamFile {\n const resolved = resolveFileStreamOptions(options);\n\n if (resolved.mode === FileTransferMode.Stream) {\n return {\n open: async ({ signal }) => {\n const [{ createReadStream }, { stat }, { basename }, { Readable }] = await Promise.all([\n import('node:fs'),\n import('node:fs/promises'),\n import('node:path'),\n import('node:stream'),\n ]);\n const info = await stat(path);\n if (resolved.maxBytes !== undefined && info.size > resolved.maxBytes) {\n throw new ItdFileError(\n `файл ${path} больше предела в ${resolved.maxBytes} байт: ${info.size}`,\n {\n reason: ItdFileErrorReason.TooLarge,\n limit: resolved.maxBytes,\n actual: info.size,\n },\n );\n }\n\n const file = createReadStream(path, {\n highWaterMark: Math.min(resolved.streamBufferBytes, 1024 * 1024),\n ...(signal ? { signal } : {}),\n });\n const source = Readable.toWeb(file) as ReadableStream<Uint8Array>;\n return {\n stream: boundedFileStream(source, {\n ...(resolved.maxBytes !== undefined ? { maxBytes: resolved.maxBytes } : {}),\n streamBufferBytes: resolved.streamBufferBytes,\n ...(signal ? { signal } : {}),\n }),\n filename: options.filename ?? basename(path),\n ...(options.contentType ? { contentType: options.contentType } : {}),\n size: info.size,\n close: () => {\n file.destroy();\n },\n };\n },\n };\n }\n\n return {\n load: async ({ signal }) => {\n const [{ readFile, stat }, { basename }] = await Promise.all([\n import('node:fs/promises'),\n import('node:path'),\n ]);\n if (resolved.maxBytes !== undefined) {\n const info = await stat(path);\n if (info.size > resolved.maxBytes) {\n throw new ItdFileError(\n `файл ${path} больше предела в ${resolved.maxBytes} байт: ${info.size}`,\n {\n reason: ItdFileErrorReason.TooLarge,\n limit: resolved.maxBytes,\n actual: info.size,\n },\n );\n }\n }\n\n const file = new Uint8Array(await readFile(path, signal ? { signal } : undefined));\n if (resolved.maxBytes !== undefined && file.byteLength > resolved.maxBytes) {\n throw new ItdFileError(\n `файл ${path} больше предела в ${resolved.maxBytes} байт: ${file.byteLength}`,\n {\n reason: ItdFileErrorReason.TooLarge,\n limit: resolved.maxBytes,\n actual: file.byteLength,\n },\n );\n }\n\n return {\n file,\n filename: options.filename ?? basename(path),\n ...(options.contentType ? { contentType: options.contentType } : {}),\n };\n },\n };\n}\n\n/**\n * Читает и разбирает JSON-файл.\n *\n * Отсутствующий файл означает `undefined`. Повреждённый JSON не считается пустым хранилищем:\n * иначе следующая запись могла бы незаметно затереть данные.\n */\nasync function readJsonFile(path: string): Promise<unknown> {\n let raw: string;\n try {\n const { readFile } = await import('node:fs/promises');\n raw = await readFile(path, 'utf8');\n } catch (error) {\n if (hasErrorCode(error, 'ENOENT')) return undefined;\n throw error;\n }\n\n try {\n return JSON.parse(raw) as unknown;\n } catch {\n throw new ItdConfigError(\n `Файл ${path} повреждён: ожидался JSON key-value хранилища. ` +\n 'Исправьте файл или перенесите его перед следующим сохранением.',\n );\n }\n}\n\n/**\n * Записывает JSON во временный файл и переименовывает его поверх целевого.\n *\n * Права `0600` (чтение и запись только владельцу) — в файле лежат токены. Переименование\n * атомарно, поэтому падение процесса посреди сохранения не оставит повреждённого файла.\n */\nasync function writeJsonAtomic(path: string, value: unknown): Promise<void> {\n const { writeFile, rename, unlink } = await import('node:fs/promises');\n\n // Временный файл уникален на процесс и вызов — иначе параллельные записи (в том числе\n // из разных процессов) делят один `.tmp`.\n const pid = typeof process !== 'undefined' ? process.pid : 0;\n const temporary = `${path}.${pid}.${Math.random().toString(36).slice(2)}.tmp`;\n\n try {\n await writeFile(temporary, JSON.stringify(value, null, 2), { encoding: 'utf8', mode: 0o600 });\n await rename(temporary, path);\n } catch (error) {\n await unlink(temporary).catch(() => {});\n throw error;\n }\n}\n\n/** Удаляет файл. Благодаря `force` отсутствие файла ошибкой не считается. */\nasync function removeFile(path: string): Promise<void> {\n const { rm } = await import('node:fs/promises');\n await rm(path, { force: true });\n}\n\n/** Версия общего формата файлового key-value backend. */\nconst FILE_STORE_VERSION = 1;\n\n/**\n * Key-value backend в одном JSON-файле.\n *\n * Изменения сериализуются внутри экземпляра и записываются атомарным переименованием. Несколько\n * экземпляров или процессов, направленных на один путь, требуют внешней синхронизации.\n */\nexport class FileKeyValueStore<T> {\n readonly #path: string;\n readonly #inner: EnumerableKeyValueStore<T>;\n\n /** @param path путь к JSON-файлу. Для секретов добавьте его в `.gitignore`. */\n constructor(path: string) {\n this.#path = path;\n this.#inner = createRecordKeyValueStore<T>({\n read: () => this.#read(),\n write: (values) => writeJsonAtomic(path, { version: FILE_STORE_VERSION, values }),\n delete: () => removeFile(path),\n });\n }\n\n get(key: string): Promise<T | undefined> {\n return Promise.resolve(this.#inner.get(key));\n }\n\n set(key: string, value: T): Promise<void> {\n return Promise.resolve(this.#inner.set(key, value));\n }\n\n delete(key: string): Promise<void> {\n return Promise.resolve(this.#inner.delete(key));\n }\n\n keys(prefix?: string): Promise<Iterable<string> | AsyncIterable<string>> {\n return Promise.resolve(this.#inner.keys(prefix));\n }\n\n async #read(): Promise<Readonly<Record<string, T>> | undefined> {\n const parsed = await readJsonFile(this.#path);\n if (parsed === undefined) return undefined;\n const envelope =\n typeof parsed === 'object' && parsed !== null\n ? (parsed as { version?: unknown; values?: unknown })\n : undefined;\n if (\n envelope?.version !== FILE_STORE_VERSION ||\n typeof envelope.values !== 'object' ||\n envelope.values === null ||\n Array.isArray(envelope.values)\n ) {\n throw new ItdConfigError(\n `Файл ${this.#path} имеет неподдерживаемый формат: ожидается ` +\n `{ version: ${FILE_STORE_VERSION}, values }. Возьмите другой путь, чтобы не ` +\n 'перезаписать посторонние данные.',\n );\n }\n return envelope.values as Readonly<Record<string, T>>;\n }\n}\n\n/**\n * Хранит сессию в файле.\n *\n * Нужна долгоживущим процессам: без неё бот при каждом запуске входит заново — а вход\n * требует решённой капчи, да и серия входов подряд может привести к временной блокировке\n * аккаунта. С сохранённой сессией опция `auth` не нужна вовсе.\n *\n * Файл создаётся с правами `0600` (чтение и запись только владельцу) — в нём лежат токены.\n * Запись идёт через временный файл с последующим переименованием, поэтому падение процесса\n * посреди сохранения не оставит повреждённую сессию.\n *\n * @example\n * ```ts\n * const itd = new ItdClient({ storage: new FileTokenStorage('./.itd-session.json') });\n * ```\n */\nexport class FileTokenStorage implements TokenStorage {\n readonly #inner: TokenStorage;\n\n /** @param path путь к файлу сессии. Добавьте его в `.gitignore`. */\n constructor(path: string) {\n this.#inner = createTokenStorage(new FileKeyValueStore<ItdSession>(path));\n }\n\n get(): Promise<ItdSession | null> {\n return Promise.resolve(this.#inner.get());\n }\n\n set(session: ItdSession): Promise<void> {\n return Promise.resolve(this.#inner.set(session));\n }\n\n clear(): Promise<void> {\n return Promise.resolve(this.#inner.clear());\n }\n}\n\n/**\n * Хранит сессии нескольких аккаунтов в одном файле.\n *\n * Разбирается с гонкой «прочитать, изменить, записать»: десять аккаунтов пишут в один файл,\n * и без общего слепка с очередью записей они теряли бы сессии друг друга. Как и\n * {@link FileTokenStorage}, пишет через временный файл с правами `0600`.\n *\n * Использует тот же версионированный {@link FileKeyValueStore}, что и одиночное хранилище.\n *\n * @example\n * ```ts\n * const accounts = new ItdAccounts({\n * storage: new FileMultiTokenStorage('./.itd-sessions.json'),\n * });\n * await accounts.restore();\n * ```\n */\nexport class FileMultiTokenStorage implements MultiTokenStorage {\n readonly #inner: MultiTokenStorage;\n\n /** @param path путь к файлу сессий. Добавьте его в `.gitignore`. */\n constructor(path: string) {\n this.#inner = createMultiTokenStorage(new FileKeyValueStore<ItdSession>(path));\n }\n\n get(account: string): Promise<ItdSession | null> {\n return Promise.resolve(this.#inner.get(account));\n }\n\n set(account: string, session: ItdSession): Promise<void> {\n return Promise.resolve(this.#inner.set(account, session));\n }\n\n clear(account: string): Promise<void> {\n return Promise.resolve(this.#inner.clear(account));\n }\n\n accounts(): Promise<readonly string[]> {\n return Promise.resolve(this.#inner.accounts());\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","names":["resolveFileStreamOptions","FileTransferMode","ItdFileError","ItdFileErrorReason","boundedFileStream","ItdConfigError","#path","#inner","createRecordKeyValueStore","#read","createTokenStorage","createMultiTokenStorage"],"sources":["../../src/node.ts"],"sourcesContent":["/**\n * `itd-api/node` — файловая система для Node, Bun и Deno.\n *\n * Здесь лежит только то, что требует `node:fs` и потому не может попасть в основной бандл:\n * иначе браузерные сборщики пытались бы разрешить этот модуль. Клиент, аккаунты, билдеры,\n * типы и всё остальное берутся из `itd-api` — одинаково на всех платформах.\n *\n * @example\n * ```ts\n * import { ItdClient } from 'itd-api';\n * import { FileTokenStorage, fromPath } from 'itd-api/node';\n *\n * // Когда сессия уже сохранена, `auth` не нужен — токен возьмётся из хранилища.\n * const itd = new ItdClient({ storage: new FileTokenStorage('./.itd-session.json') });\n *\n * await itd.posts.create((p) => p.content('привет').attach(fromPath('./photo.jpg')));\n * ```\n *\n * @packageDocumentation\n */\n\nimport { boundedFileStream } from './core/attachments/bounded-stream.js';\nimport {\n type FileStreamOptions,\n FileTransferMode,\n type LazyFile,\n type StreamFile,\n} from './core/attachments/contracts.js';\nimport { resolveFileStreamOptions } from './core/attachments/options.js';\nimport { ItdConfigError, ItdFileError, ItdFileErrorReason } from './core/errors.js';\nimport { createRecordKeyValueStore, type EnumerableKeyValueStore } from './core/key-value-store.js';\nimport { createMultiTokenStorage, type MultiTokenStorage } from './session/multi-storage.js';\nimport { createTokenStorage, type ItdSession, type TokenStorage } from './session/storage.js';\n\n/** Проверяет код системной ошибки без привязки к типам конкретного рантайма. */\nfunction hasErrorCode(error: unknown, code: string): boolean {\n return typeof error === 'object' && error !== null && 'code' in error && error.code === code;\n}\n\n/** Что можно уточнить у файла с диска. */\nexport interface PathFileOptions extends FileStreamOptions {\n /** Имя файла. По умолчанию — имя из пути. */\n filename?: string | undefined;\n /** MIME-тип. По умолчанию определяется по расширению. */\n contentType?: string | undefined;\n}\n\n/**\n * Вложение из файла на диске.\n *\n * Клиент настраивать не нужно: чтение диска приезжает вместе со значением, а не через\n * опцию, поэтому один и тот же клиент принимает и файлы с диска, и всё остальное.\n *\n * По умолчанию файл читается целиком непосредственно перед отправкой. Режим\n * `{ mode: 'stream' }` передаёт его частями и открывает заново при повторной попытке.\n * Модуль `node:fs` подключается динамически.\n *\n * @example\n * ```ts\n * import { ItdClient } from 'itd-api';\n * import { fromPath } from 'itd-api/node';\n *\n * const itd = new ItdClient({ auth });\n *\n * await itd.posts.create((p) =>\n * p.content('смотрите').attach(fromPath('./photo.jpg')),\n * );\n * ```\n */\nexport function fromPath(\n path: string,\n options: PathFileOptions & { mode: typeof FileTransferMode.Stream },\n): StreamFile;\nexport function fromPath(\n path: string,\n options?: PathFileOptions & { mode?: typeof FileTransferMode.Buffer },\n): LazyFile;\nexport function fromPath(path: string, options: PathFileOptions): LazyFile | StreamFile;\nexport function fromPath(path: string, options: PathFileOptions = {}): LazyFile | StreamFile {\n const resolved = resolveFileStreamOptions(options);\n\n if (resolved.mode === FileTransferMode.Stream) {\n return {\n open: async ({ signal }) => {\n const [{ createReadStream }, { stat }, { basename }, { Readable }] = await Promise.all([\n import('node:fs'),\n import('node:fs/promises'),\n import('node:path'),\n import('node:stream'),\n ]);\n const info = await stat(path);\n if (resolved.maxBytes !== undefined && info.size > resolved.maxBytes) {\n throw new ItdFileError(\n `файл ${path} больше предела в ${resolved.maxBytes} байт: ${info.size}`,\n {\n reason: ItdFileErrorReason.TooLarge,\n limit: resolved.maxBytes,\n actual: info.size,\n },\n );\n }\n\n const file = createReadStream(path, {\n highWaterMark: Math.min(resolved.streamBufferBytes, 1024 * 1024),\n ...(signal ? { signal } : {}),\n });\n const source = Readable.toWeb(file) as ReadableStream<Uint8Array>;\n return {\n stream: boundedFileStream(source, {\n ...(resolved.maxBytes !== undefined ? { maxBytes: resolved.maxBytes } : {}),\n streamBufferBytes: resolved.streamBufferBytes,\n ...(signal ? { signal } : {}),\n }),\n filename: options.filename ?? basename(path),\n ...(options.contentType ? { contentType: options.contentType } : {}),\n size: info.size,\n close: () => {\n file.destroy();\n },\n };\n },\n };\n }\n\n return {\n load: async ({ signal }) => {\n const [{ readFile, stat }, { basename }] = await Promise.all([\n import('node:fs/promises'),\n import('node:path'),\n ]);\n if (resolved.maxBytes !== undefined) {\n const info = await stat(path);\n if (info.size > resolved.maxBytes) {\n throw new ItdFileError(\n `файл ${path} больше предела в ${resolved.maxBytes} байт: ${info.size}`,\n {\n reason: ItdFileErrorReason.TooLarge,\n limit: resolved.maxBytes,\n actual: info.size,\n },\n );\n }\n }\n\n const file = new Uint8Array(await readFile(path, signal ? { signal } : undefined));\n if (resolved.maxBytes !== undefined && file.byteLength > resolved.maxBytes) {\n throw new ItdFileError(\n `файл ${path} больше предела в ${resolved.maxBytes} байт: ${file.byteLength}`,\n {\n reason: ItdFileErrorReason.TooLarge,\n limit: resolved.maxBytes,\n actual: file.byteLength,\n },\n );\n }\n\n return {\n file,\n filename: options.filename ?? basename(path),\n ...(options.contentType ? { contentType: options.contentType } : {}),\n };\n },\n };\n}\n\n/**\n * Читает и разбирает JSON-файл.\n *\n * Отсутствующий файл означает `undefined`. Повреждённый JSON не считается пустым хранилищем:\n * иначе следующая запись могла бы незаметно затереть данные.\n */\nasync function readJsonFile(path: string): Promise<unknown> {\n let raw: string;\n try {\n const { readFile } = await import('node:fs/promises');\n raw = await readFile(path, 'utf8');\n } catch (error) {\n if (hasErrorCode(error, 'ENOENT')) return undefined;\n throw error;\n }\n\n try {\n return JSON.parse(raw) as unknown;\n } catch {\n throw new ItdConfigError(\n `Файл ${path} повреждён: ожидался JSON key-value хранилища. ` +\n 'Исправьте файл или перенесите его перед следующим сохранением.',\n );\n }\n}\n\n/**\n * Записывает JSON во временный файл и переименовывает его поверх целевого.\n *\n * Права `0600` (чтение и запись только владельцу) — в файле лежат токены. Переименование\n * атомарно, поэтому падение процесса посреди сохранения не оставит повреждённого файла.\n */\nasync function writeJsonAtomic(path: string, value: unknown): Promise<void> {\n const { writeFile, rename, unlink } = await import('node:fs/promises');\n\n // Временный файл уникален на процесс и вызов — иначе параллельные записи (в том числе\n // из разных процессов) делят один `.tmp`.\n const pid = typeof process !== 'undefined' ? process.pid : 0;\n const temporary = `${path}.${pid}.${Math.random().toString(36).slice(2)}.tmp`;\n\n try {\n await writeFile(temporary, JSON.stringify(value, null, 2), { encoding: 'utf8', mode: 0o600 });\n await rename(temporary, path);\n } catch (error) {\n await unlink(temporary).catch(() => {});\n throw error;\n }\n}\n\n/** Удаляет файл. Благодаря `force` отсутствие файла ошибкой не считается. */\nasync function removeFile(path: string): Promise<void> {\n const { rm } = await import('node:fs/promises');\n await rm(path, { force: true });\n}\n\n/** Версия общего формата файлового key-value backend. */\nconst FILE_STORE_VERSION = 1;\n\n/**\n * Key-value backend в одном JSON-файле.\n *\n * Изменения сериализуются внутри экземпляра и записываются атомарным переименованием. Несколько\n * экземпляров или процессов, направленных на один путь, требуют внешней синхронизации.\n */\nexport class FileKeyValueStore<T> {\n readonly #path: string;\n readonly #inner: EnumerableKeyValueStore<T>;\n\n /** @param path путь к JSON-файлу. Для секретов добавьте его в `.gitignore`. */\n constructor(path: string) {\n this.#path = path;\n this.#inner = createRecordKeyValueStore<T>({\n read: () => this.#read(),\n write: (values) => writeJsonAtomic(path, { version: FILE_STORE_VERSION, values }),\n delete: () => removeFile(path),\n });\n }\n\n get(key: string): Promise<T | undefined> {\n return Promise.resolve(this.#inner.get(key));\n }\n\n set(key: string, value: T): Promise<void> {\n return Promise.resolve(this.#inner.set(key, value));\n }\n\n delete(key: string): Promise<void> {\n return Promise.resolve(this.#inner.delete(key));\n }\n\n keys(prefix?: string): Promise<Iterable<string> | AsyncIterable<string>> {\n return Promise.resolve(this.#inner.keys(prefix));\n }\n\n async #read(): Promise<Readonly<Record<string, T>> | undefined> {\n const parsed = await readJsonFile(this.#path);\n if (parsed === undefined) return undefined;\n const envelope =\n typeof parsed === 'object' && parsed !== null\n ? (parsed as { version?: unknown; values?: unknown })\n : undefined;\n if (\n envelope?.version !== FILE_STORE_VERSION ||\n typeof envelope.values !== 'object' ||\n envelope.values === null ||\n Array.isArray(envelope.values)\n ) {\n throw new ItdConfigError(\n `Файл ${this.#path} имеет неподдерживаемый формат: ожидается ` +\n `{ version: ${FILE_STORE_VERSION}, values }. Возьмите другой путь, чтобы не ` +\n 'перезаписать посторонние данные.',\n );\n }\n return envelope.values as Readonly<Record<string, T>>;\n }\n}\n\n/**\n * Хранит сессию в файле.\n *\n * Нужна долгоживущим процессам: без неё бот при каждом запуске входит заново — а вход\n * требует решённой капчи, да и серия входов подряд может привести к временной блокировке\n * аккаунта. С сохранённой сессией опция `auth` не нужна вовсе.\n *\n * Файл создаётся с правами `0600` (чтение и запись только владельцу) — в нём лежат токены.\n * Запись идёт через временный файл с последующим переименованием, поэтому падение процесса\n * посреди сохранения не оставит повреждённую сессию.\n *\n * @example\n * ```ts\n * const itd = new ItdClient({ storage: new FileTokenStorage('./.itd-session.json') });\n * ```\n */\nexport class FileTokenStorage implements TokenStorage {\n readonly #inner: TokenStorage;\n\n /** @param path путь к файлу сессии. Добавьте его в `.gitignore`. */\n constructor(path: string) {\n this.#inner = createTokenStorage(new FileKeyValueStore<ItdSession>(path));\n }\n\n get(): Promise<ItdSession | null> {\n return Promise.resolve(this.#inner.get());\n }\n\n set(session: ItdSession): Promise<void> {\n return Promise.resolve(this.#inner.set(session));\n }\n\n clear(): Promise<void> {\n return Promise.resolve(this.#inner.clear());\n }\n}\n\n/**\n * Хранит сессии нескольких аккаунтов в одном файле.\n *\n * Разбирается с гонкой «прочитать, изменить, записать»: десять аккаунтов пишут в один файл,\n * и без общего слепка с очередью записей они теряли бы сессии друг друга. Как и\n * {@link FileTokenStorage}, пишет через временный файл с правами `0600`.\n *\n * Использует тот же версионированный {@link FileKeyValueStore}, что и одиночное хранилище.\n *\n * @example\n * ```ts\n * const accounts = new ItdAccounts({\n * storage: new FileMultiTokenStorage('./.itd-sessions.json'),\n * });\n * await accounts.restore();\n * ```\n */\nexport class FileMultiTokenStorage implements MultiTokenStorage {\n readonly #inner: MultiTokenStorage;\n\n /** @param path путь к файлу сессий. Добавьте его в `.gitignore`. */\n constructor(path: string) {\n this.#inner = createMultiTokenStorage(new FileKeyValueStore<ItdSession>(path));\n }\n\n get(account: string): Promise<ItdSession | null> {\n return Promise.resolve(this.#inner.get(account));\n }\n\n set(account: string, session: ItdSession): Promise<void> {\n return Promise.resolve(this.#inner.set(account, session));\n }\n\n clear(account: string): Promise<void> {\n return Promise.resolve(this.#inner.clear(account));\n }\n\n accounts(): Promise<readonly string[]> {\n return Promise.resolve(this.#inner.accounts());\n }\n}\n"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
- import { r as TokenStorage, t as ItdSession } from "../shared/storage-C_eICCep.cjs";
2
1
  import { a as FileStreamOptions, c as LazyFile, l as StreamFile, o as FileTransferMode } from "../shared/contracts-BoT7msmq.cjs";
3
- import { n as MultiTokenStorage } from "../shared/multi-storage-CjAPB5Kq.cjs";
2
+ import { r as TokenStorage, t as ItdSession } from "../shared/storage-BQrtKon9.cjs";
3
+ import { n as MultiTokenStorage } from "../shared/multi-storage-BEL7tcKn.cjs";
4
4
  //#region src/node.d.ts
5
5
  /** Что можно уточнить у файла с диска. */
6
6
  interface PathFileOptions extends FileStreamOptions {
@@ -1,6 +1,6 @@
1
- import { r as TokenStorage, t as ItdSession } from "../shared/storage-C_eICCep.js";
2
1
  import { a as FileStreamOptions, c as LazyFile, l as StreamFile, o as FileTransferMode } from "../shared/contracts-BoT7msmq.js";
3
- import { n as MultiTokenStorage } from "../shared/multi-storage-DccjD7Ww.js";
2
+ import { r as TokenStorage, t as ItdSession } from "../shared/storage-CTRGT5wF.js";
3
+ import { n as MultiTokenStorage } from "../shared/multi-storage-LkljOSzA.js";
4
4
  //#region src/node.d.ts
5
5
  /** Что можно уточнить у файла с диска. */
6
6
  interface PathFileOptions extends FileStreamOptions {
@@ -1,7 +1,8 @@
1
- import { a as ItdConfigError, l as ItdFileError, u as ItdFileErrorReason } from "../shared/errors-Bhrd2fJd.js";
2
- import { r as createTokenStorage, s as createRecordKeyValueStore } from "../shared/storage-D86edNCB.js";
3
- import { c as FileTransferMode, n as boundedFileStream, t as resolveFileStreamOptions } from "../shared/options-DtATYdLr.js";
4
- import { r as createMultiTokenStorage } from "../shared/multi-storage-CkvTUC5m.js";
1
+ import { a as ItdConfigError, l as ItdFileError, u as ItdFileErrorReason } from "../shared/errors-GI10kZxk.js";
2
+ import { c as FileTransferMode, n as boundedFileStream, t as resolveFileStreamOptions } from "../shared/options-DhgGg7Ms.js";
3
+ import { i as createRecordKeyValueStore } from "../shared/key-value-store-Bt2PSMxY.js";
4
+ import { r as createTokenStorage } from "../shared/storage-CfHKzVHf.js";
5
+ import { r as createMultiTokenStorage } from "../shared/multi-storage-SoW05uzO.js";
5
6
  //#region src/node.ts
6
7
  /**
7
8
  * `itd-api/node` — файловая система для Node, Bun и Deno.
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["#path","#inner","#read"],"sources":["../../src/node.ts"],"sourcesContent":["/**\n * `itd-api/node` — файловая система для Node, Bun и Deno.\n *\n * Здесь лежит только то, что требует `node:fs` и потому не может попасть в основной бандл:\n * иначе браузерные сборщики пытались бы разрешить этот модуль. Клиент, аккаунты, билдеры,\n * типы и всё остальное берутся из `itd-api` — одинаково на всех платформах.\n *\n * @example\n * ```ts\n * import { ItdClient } from 'itd-api';\n * import { FileTokenStorage, fromPath } from 'itd-api/node';\n *\n * // Когда сессия уже сохранена, `auth` не нужен — токен возьмётся из хранилища.\n * const itd = new ItdClient({ storage: new FileTokenStorage('./.itd-session.json') });\n *\n * await itd.posts.create((p) => p.content('привет').attach(fromPath('./photo.jpg')));\n * ```\n *\n * @packageDocumentation\n */\n\nimport { boundedFileStream } from './core/attachments/bounded-stream.js';\nimport {\n type FileStreamOptions,\n FileTransferMode,\n type LazyFile,\n type StreamFile,\n} from './core/attachments/contracts.js';\nimport { resolveFileStreamOptions } from './core/attachments/options.js';\nimport { ItdConfigError, ItdFileError, ItdFileErrorReason } from './core/errors.js';\nimport { createRecordKeyValueStore, type EnumerableKeyValueStore } from './core/key-value-store.js';\nimport { createMultiTokenStorage, type MultiTokenStorage } from './session/multi-storage.js';\nimport { createTokenStorage, type ItdSession, type TokenStorage } from './session/storage.js';\n\n/** Проверяет код системной ошибки без привязки к типам конкретного рантайма. */\nfunction hasErrorCode(error: unknown, code: string): boolean {\n return typeof error === 'object' && error !== null && 'code' in error && error.code === code;\n}\n\n/** Что можно уточнить у файла с диска. */\nexport interface PathFileOptions extends FileStreamOptions {\n /** Имя файла. По умолчанию — имя из пути. */\n filename?: string | undefined;\n /** MIME-тип. По умолчанию определяется по расширению. */\n contentType?: string | undefined;\n}\n\n/**\n * Вложение из файла на диске.\n *\n * Клиент настраивать не нужно: чтение диска приезжает вместе со значением, а не через\n * опцию, поэтому один и тот же клиент принимает и файлы с диска, и всё остальное.\n *\n * По умолчанию файл читается целиком непосредственно перед отправкой. Режим\n * `{ mode: 'stream' }` передаёт его частями и открывает заново при повторной попытке.\n * Модуль `node:fs` подключается динамически.\n *\n * @example\n * ```ts\n * import { ItdClient } from 'itd-api';\n * import { fromPath } from 'itd-api/node';\n *\n * const itd = new ItdClient({ auth });\n *\n * await itd.posts.create((p) =>\n * p.content('смотрите').attach(fromPath('./photo.jpg')),\n * );\n * ```\n */\nexport function fromPath(\n path: string,\n options: PathFileOptions & { mode: typeof FileTransferMode.Stream },\n): StreamFile;\nexport function fromPath(\n path: string,\n options?: PathFileOptions & { mode?: typeof FileTransferMode.Buffer },\n): LazyFile;\nexport function fromPath(path: string, options: PathFileOptions): LazyFile | StreamFile;\nexport function fromPath(path: string, options: PathFileOptions = {}): LazyFile | StreamFile {\n const resolved = resolveFileStreamOptions(options);\n\n if (resolved.mode === FileTransferMode.Stream) {\n return {\n open: async ({ signal }) => {\n const [{ createReadStream }, { stat }, { basename }, { Readable }] = await Promise.all([\n import('node:fs'),\n import('node:fs/promises'),\n import('node:path'),\n import('node:stream'),\n ]);\n const info = await stat(path);\n if (resolved.maxBytes !== undefined && info.size > resolved.maxBytes) {\n throw new ItdFileError(\n `файл ${path} больше предела в ${resolved.maxBytes} байт: ${info.size}`,\n {\n reason: ItdFileErrorReason.TooLarge,\n limit: resolved.maxBytes,\n actual: info.size,\n },\n );\n }\n\n const file = createReadStream(path, {\n highWaterMark: Math.min(resolved.streamBufferBytes, 1024 * 1024),\n ...(signal ? { signal } : {}),\n });\n const source = Readable.toWeb(file) as ReadableStream<Uint8Array>;\n return {\n stream: boundedFileStream(source, {\n ...(resolved.maxBytes !== undefined ? { maxBytes: resolved.maxBytes } : {}),\n streamBufferBytes: resolved.streamBufferBytes,\n ...(signal ? { signal } : {}),\n }),\n filename: options.filename ?? basename(path),\n ...(options.contentType ? { contentType: options.contentType } : {}),\n size: info.size,\n close: () => {\n file.destroy();\n },\n };\n },\n };\n }\n\n return {\n load: async ({ signal }) => {\n const [{ readFile, stat }, { basename }] = await Promise.all([\n import('node:fs/promises'),\n import('node:path'),\n ]);\n if (resolved.maxBytes !== undefined) {\n const info = await stat(path);\n if (info.size > resolved.maxBytes) {\n throw new ItdFileError(\n `файл ${path} больше предела в ${resolved.maxBytes} байт: ${info.size}`,\n {\n reason: ItdFileErrorReason.TooLarge,\n limit: resolved.maxBytes,\n actual: info.size,\n },\n );\n }\n }\n\n const file = new Uint8Array(await readFile(path, signal ? { signal } : undefined));\n if (resolved.maxBytes !== undefined && file.byteLength > resolved.maxBytes) {\n throw new ItdFileError(\n `файл ${path} больше предела в ${resolved.maxBytes} байт: ${file.byteLength}`,\n {\n reason: ItdFileErrorReason.TooLarge,\n limit: resolved.maxBytes,\n actual: file.byteLength,\n },\n );\n }\n\n return {\n file,\n filename: options.filename ?? basename(path),\n ...(options.contentType ? { contentType: options.contentType } : {}),\n };\n },\n };\n}\n\n/**\n * Читает и разбирает JSON-файл.\n *\n * Отсутствующий файл означает `undefined`. Повреждённый JSON не считается пустым хранилищем:\n * иначе следующая запись могла бы незаметно затереть данные.\n */\nasync function readJsonFile(path: string): Promise<unknown> {\n let raw: string;\n try {\n const { readFile } = await import('node:fs/promises');\n raw = await readFile(path, 'utf8');\n } catch (error) {\n if (hasErrorCode(error, 'ENOENT')) return undefined;\n throw error;\n }\n\n try {\n return JSON.parse(raw) as unknown;\n } catch {\n throw new ItdConfigError(\n `Файл ${path} повреждён: ожидался JSON key-value хранилища. ` +\n 'Исправьте файл или перенесите его перед следующим сохранением.',\n );\n }\n}\n\n/**\n * Записывает JSON во временный файл и переименовывает его поверх целевого.\n *\n * Права `0600` (чтение и запись только владельцу) — в файле лежат токены. Переименование\n * атомарно, поэтому падение процесса посреди сохранения не оставит повреждённого файла.\n */\nasync function writeJsonAtomic(path: string, value: unknown): Promise<void> {\n const { writeFile, rename, unlink } = await import('node:fs/promises');\n\n // Временный файл уникален на процесс и вызов — иначе параллельные записи (в том числе\n // из разных процессов) делят один `.tmp`.\n const pid = typeof process !== 'undefined' ? process.pid : 0;\n const temporary = `${path}.${pid}.${Math.random().toString(36).slice(2)}.tmp`;\n\n try {\n await writeFile(temporary, JSON.stringify(value, null, 2), { encoding: 'utf8', mode: 0o600 });\n await rename(temporary, path);\n } catch (error) {\n await unlink(temporary).catch(() => {});\n throw error;\n }\n}\n\n/** Удаляет файл. Благодаря `force` отсутствие файла ошибкой не считается. */\nasync function removeFile(path: string): Promise<void> {\n const { rm } = await import('node:fs/promises');\n await rm(path, { force: true });\n}\n\n/** Версия общего формата файлового key-value backend. */\nconst FILE_STORE_VERSION = 1;\n\n/**\n * Key-value backend в одном JSON-файле.\n *\n * Изменения сериализуются внутри экземпляра и записываются атомарным переименованием. Несколько\n * экземпляров или процессов, направленных на один путь, требуют внешней синхронизации.\n */\nexport class FileKeyValueStore<T> {\n readonly #path: string;\n readonly #inner: EnumerableKeyValueStore<T>;\n\n /** @param path путь к JSON-файлу. Для секретов добавьте его в `.gitignore`. */\n constructor(path: string) {\n this.#path = path;\n this.#inner = createRecordKeyValueStore<T>({\n read: () => this.#read(),\n write: (values) => writeJsonAtomic(path, { version: FILE_STORE_VERSION, values }),\n delete: () => removeFile(path),\n });\n }\n\n get(key: string): Promise<T | undefined> {\n return Promise.resolve(this.#inner.get(key));\n }\n\n set(key: string, value: T): Promise<void> {\n return Promise.resolve(this.#inner.set(key, value));\n }\n\n delete(key: string): Promise<void> {\n return Promise.resolve(this.#inner.delete(key));\n }\n\n keys(prefix?: string): Promise<Iterable<string> | AsyncIterable<string>> {\n return Promise.resolve(this.#inner.keys(prefix));\n }\n\n async #read(): Promise<Readonly<Record<string, T>> | undefined> {\n const parsed = await readJsonFile(this.#path);\n if (parsed === undefined) return undefined;\n const envelope =\n typeof parsed === 'object' && parsed !== null\n ? (parsed as { version?: unknown; values?: unknown })\n : undefined;\n if (\n envelope?.version !== FILE_STORE_VERSION ||\n typeof envelope.values !== 'object' ||\n envelope.values === null ||\n Array.isArray(envelope.values)\n ) {\n throw new ItdConfigError(\n `Файл ${this.#path} имеет неподдерживаемый формат: ожидается ` +\n `{ version: ${FILE_STORE_VERSION}, values }. Возьмите другой путь, чтобы не ` +\n 'перезаписать посторонние данные.',\n );\n }\n return envelope.values as Readonly<Record<string, T>>;\n }\n}\n\n/**\n * Хранит сессию в файле.\n *\n * Нужна долгоживущим процессам: без неё бот при каждом запуске входит заново — а вход\n * требует решённой капчи, да и серия входов подряд может привести к временной блокировке\n * аккаунта. С сохранённой сессией опция `auth` не нужна вовсе.\n *\n * Файл создаётся с правами `0600` (чтение и запись только владельцу) — в нём лежат токены.\n * Запись идёт через временный файл с последующим переименованием, поэтому падение процесса\n * посреди сохранения не оставит повреждённую сессию.\n *\n * @example\n * ```ts\n * const itd = new ItdClient({ storage: new FileTokenStorage('./.itd-session.json') });\n * ```\n */\nexport class FileTokenStorage implements TokenStorage {\n readonly #inner: TokenStorage;\n\n /** @param path путь к файлу сессии. Добавьте его в `.gitignore`. */\n constructor(path: string) {\n this.#inner = createTokenStorage(new FileKeyValueStore<ItdSession>(path));\n }\n\n get(): Promise<ItdSession | null> {\n return Promise.resolve(this.#inner.get());\n }\n\n set(session: ItdSession): Promise<void> {\n return Promise.resolve(this.#inner.set(session));\n }\n\n clear(): Promise<void> {\n return Promise.resolve(this.#inner.clear());\n }\n}\n\n/**\n * Хранит сессии нескольких аккаунтов в одном файле.\n *\n * Разбирается с гонкой «прочитать, изменить, записать»: десять аккаунтов пишут в один файл,\n * и без общего слепка с очередью записей они теряли бы сессии друг друга. Как и\n * {@link FileTokenStorage}, пишет через временный файл с правами `0600`.\n *\n * Использует тот же версионированный {@link FileKeyValueStore}, что и одиночное хранилище.\n *\n * @example\n * ```ts\n * const accounts = new ItdAccounts({\n * storage: new FileMultiTokenStorage('./.itd-sessions.json'),\n * });\n * await accounts.restore();\n * ```\n */\nexport class FileMultiTokenStorage implements MultiTokenStorage {\n readonly #inner: MultiTokenStorage;\n\n /** @param path путь к файлу сессий. Добавьте его в `.gitignore`. */\n constructor(path: string) {\n this.#inner = createMultiTokenStorage(new FileKeyValueStore<ItdSession>(path));\n }\n\n get(account: string): Promise<ItdSession | null> {\n return Promise.resolve(this.#inner.get(account));\n }\n\n set(account: string, session: ItdSession): Promise<void> {\n return Promise.resolve(this.#inner.set(account, session));\n }\n\n clear(account: string): Promise<void> {\n return Promise.resolve(this.#inner.clear(account));\n }\n\n accounts(): Promise<readonly string[]> {\n return Promise.resolve(this.#inner.accounts());\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":["#path","#inner","#read"],"sources":["../../src/node.ts"],"sourcesContent":["/**\n * `itd-api/node` — файловая система для Node, Bun и Deno.\n *\n * Здесь лежит только то, что требует `node:fs` и потому не может попасть в основной бандл:\n * иначе браузерные сборщики пытались бы разрешить этот модуль. Клиент, аккаунты, билдеры,\n * типы и всё остальное берутся из `itd-api` — одинаково на всех платформах.\n *\n * @example\n * ```ts\n * import { ItdClient } from 'itd-api';\n * import { FileTokenStorage, fromPath } from 'itd-api/node';\n *\n * // Когда сессия уже сохранена, `auth` не нужен — токен возьмётся из хранилища.\n * const itd = new ItdClient({ storage: new FileTokenStorage('./.itd-session.json') });\n *\n * await itd.posts.create((p) => p.content('привет').attach(fromPath('./photo.jpg')));\n * ```\n *\n * @packageDocumentation\n */\n\nimport { boundedFileStream } from './core/attachments/bounded-stream.js';\nimport {\n type FileStreamOptions,\n FileTransferMode,\n type LazyFile,\n type StreamFile,\n} from './core/attachments/contracts.js';\nimport { resolveFileStreamOptions } from './core/attachments/options.js';\nimport { ItdConfigError, ItdFileError, ItdFileErrorReason } from './core/errors.js';\nimport { createRecordKeyValueStore, type EnumerableKeyValueStore } from './core/key-value-store.js';\nimport { createMultiTokenStorage, type MultiTokenStorage } from './session/multi-storage.js';\nimport { createTokenStorage, type ItdSession, type TokenStorage } from './session/storage.js';\n\n/** Проверяет код системной ошибки без привязки к типам конкретного рантайма. */\nfunction hasErrorCode(error: unknown, code: string): boolean {\n return typeof error === 'object' && error !== null && 'code' in error && error.code === code;\n}\n\n/** Что можно уточнить у файла с диска. */\nexport interface PathFileOptions extends FileStreamOptions {\n /** Имя файла. По умолчанию — имя из пути. */\n filename?: string | undefined;\n /** MIME-тип. По умолчанию определяется по расширению. */\n contentType?: string | undefined;\n}\n\n/**\n * Вложение из файла на диске.\n *\n * Клиент настраивать не нужно: чтение диска приезжает вместе со значением, а не через\n * опцию, поэтому один и тот же клиент принимает и файлы с диска, и всё остальное.\n *\n * По умолчанию файл читается целиком непосредственно перед отправкой. Режим\n * `{ mode: 'stream' }` передаёт его частями и открывает заново при повторной попытке.\n * Модуль `node:fs` подключается динамически.\n *\n * @example\n * ```ts\n * import { ItdClient } from 'itd-api';\n * import { fromPath } from 'itd-api/node';\n *\n * const itd = new ItdClient({ auth });\n *\n * await itd.posts.create((p) =>\n * p.content('смотрите').attach(fromPath('./photo.jpg')),\n * );\n * ```\n */\nexport function fromPath(\n path: string,\n options: PathFileOptions & { mode: typeof FileTransferMode.Stream },\n): StreamFile;\nexport function fromPath(\n path: string,\n options?: PathFileOptions & { mode?: typeof FileTransferMode.Buffer },\n): LazyFile;\nexport function fromPath(path: string, options: PathFileOptions): LazyFile | StreamFile;\nexport function fromPath(path: string, options: PathFileOptions = {}): LazyFile | StreamFile {\n const resolved = resolveFileStreamOptions(options);\n\n if (resolved.mode === FileTransferMode.Stream) {\n return {\n open: async ({ signal }) => {\n const [{ createReadStream }, { stat }, { basename }, { Readable }] = await Promise.all([\n import('node:fs'),\n import('node:fs/promises'),\n import('node:path'),\n import('node:stream'),\n ]);\n const info = await stat(path);\n if (resolved.maxBytes !== undefined && info.size > resolved.maxBytes) {\n throw new ItdFileError(\n `файл ${path} больше предела в ${resolved.maxBytes} байт: ${info.size}`,\n {\n reason: ItdFileErrorReason.TooLarge,\n limit: resolved.maxBytes,\n actual: info.size,\n },\n );\n }\n\n const file = createReadStream(path, {\n highWaterMark: Math.min(resolved.streamBufferBytes, 1024 * 1024),\n ...(signal ? { signal } : {}),\n });\n const source = Readable.toWeb(file) as ReadableStream<Uint8Array>;\n return {\n stream: boundedFileStream(source, {\n ...(resolved.maxBytes !== undefined ? { maxBytes: resolved.maxBytes } : {}),\n streamBufferBytes: resolved.streamBufferBytes,\n ...(signal ? { signal } : {}),\n }),\n filename: options.filename ?? basename(path),\n ...(options.contentType ? { contentType: options.contentType } : {}),\n size: info.size,\n close: () => {\n file.destroy();\n },\n };\n },\n };\n }\n\n return {\n load: async ({ signal }) => {\n const [{ readFile, stat }, { basename }] = await Promise.all([\n import('node:fs/promises'),\n import('node:path'),\n ]);\n if (resolved.maxBytes !== undefined) {\n const info = await stat(path);\n if (info.size > resolved.maxBytes) {\n throw new ItdFileError(\n `файл ${path} больше предела в ${resolved.maxBytes} байт: ${info.size}`,\n {\n reason: ItdFileErrorReason.TooLarge,\n limit: resolved.maxBytes,\n actual: info.size,\n },\n );\n }\n }\n\n const file = new Uint8Array(await readFile(path, signal ? { signal } : undefined));\n if (resolved.maxBytes !== undefined && file.byteLength > resolved.maxBytes) {\n throw new ItdFileError(\n `файл ${path} больше предела в ${resolved.maxBytes} байт: ${file.byteLength}`,\n {\n reason: ItdFileErrorReason.TooLarge,\n limit: resolved.maxBytes,\n actual: file.byteLength,\n },\n );\n }\n\n return {\n file,\n filename: options.filename ?? basename(path),\n ...(options.contentType ? { contentType: options.contentType } : {}),\n };\n },\n };\n}\n\n/**\n * Читает и разбирает JSON-файл.\n *\n * Отсутствующий файл означает `undefined`. Повреждённый JSON не считается пустым хранилищем:\n * иначе следующая запись могла бы незаметно затереть данные.\n */\nasync function readJsonFile(path: string): Promise<unknown> {\n let raw: string;\n try {\n const { readFile } = await import('node:fs/promises');\n raw = await readFile(path, 'utf8');\n } catch (error) {\n if (hasErrorCode(error, 'ENOENT')) return undefined;\n throw error;\n }\n\n try {\n return JSON.parse(raw) as unknown;\n } catch {\n throw new ItdConfigError(\n `Файл ${path} повреждён: ожидался JSON key-value хранилища. ` +\n 'Исправьте файл или перенесите его перед следующим сохранением.',\n );\n }\n}\n\n/**\n * Записывает JSON во временный файл и переименовывает его поверх целевого.\n *\n * Права `0600` (чтение и запись только владельцу) — в файле лежат токены. Переименование\n * атомарно, поэтому падение процесса посреди сохранения не оставит повреждённого файла.\n */\nasync function writeJsonAtomic(path: string, value: unknown): Promise<void> {\n const { writeFile, rename, unlink } = await import('node:fs/promises');\n\n // Временный файл уникален на процесс и вызов — иначе параллельные записи (в том числе\n // из разных процессов) делят один `.tmp`.\n const pid = typeof process !== 'undefined' ? process.pid : 0;\n const temporary = `${path}.${pid}.${Math.random().toString(36).slice(2)}.tmp`;\n\n try {\n await writeFile(temporary, JSON.stringify(value, null, 2), { encoding: 'utf8', mode: 0o600 });\n await rename(temporary, path);\n } catch (error) {\n await unlink(temporary).catch(() => {});\n throw error;\n }\n}\n\n/** Удаляет файл. Благодаря `force` отсутствие файла ошибкой не считается. */\nasync function removeFile(path: string): Promise<void> {\n const { rm } = await import('node:fs/promises');\n await rm(path, { force: true });\n}\n\n/** Версия общего формата файлового key-value backend. */\nconst FILE_STORE_VERSION = 1;\n\n/**\n * Key-value backend в одном JSON-файле.\n *\n * Изменения сериализуются внутри экземпляра и записываются атомарным переименованием. Несколько\n * экземпляров или процессов, направленных на один путь, требуют внешней синхронизации.\n */\nexport class FileKeyValueStore<T> {\n readonly #path: string;\n readonly #inner: EnumerableKeyValueStore<T>;\n\n /** @param path путь к JSON-файлу. Для секретов добавьте его в `.gitignore`. */\n constructor(path: string) {\n this.#path = path;\n this.#inner = createRecordKeyValueStore<T>({\n read: () => this.#read(),\n write: (values) => writeJsonAtomic(path, { version: FILE_STORE_VERSION, values }),\n delete: () => removeFile(path),\n });\n }\n\n get(key: string): Promise<T | undefined> {\n return Promise.resolve(this.#inner.get(key));\n }\n\n set(key: string, value: T): Promise<void> {\n return Promise.resolve(this.#inner.set(key, value));\n }\n\n delete(key: string): Promise<void> {\n return Promise.resolve(this.#inner.delete(key));\n }\n\n keys(prefix?: string): Promise<Iterable<string> | AsyncIterable<string>> {\n return Promise.resolve(this.#inner.keys(prefix));\n }\n\n async #read(): Promise<Readonly<Record<string, T>> | undefined> {\n const parsed = await readJsonFile(this.#path);\n if (parsed === undefined) return undefined;\n const envelope =\n typeof parsed === 'object' && parsed !== null\n ? (parsed as { version?: unknown; values?: unknown })\n : undefined;\n if (\n envelope?.version !== FILE_STORE_VERSION ||\n typeof envelope.values !== 'object' ||\n envelope.values === null ||\n Array.isArray(envelope.values)\n ) {\n throw new ItdConfigError(\n `Файл ${this.#path} имеет неподдерживаемый формат: ожидается ` +\n `{ version: ${FILE_STORE_VERSION}, values }. Возьмите другой путь, чтобы не ` +\n 'перезаписать посторонние данные.',\n );\n }\n return envelope.values as Readonly<Record<string, T>>;\n }\n}\n\n/**\n * Хранит сессию в файле.\n *\n * Нужна долгоживущим процессам: без неё бот при каждом запуске входит заново — а вход\n * требует решённой капчи, да и серия входов подряд может привести к временной блокировке\n * аккаунта. С сохранённой сессией опция `auth` не нужна вовсе.\n *\n * Файл создаётся с правами `0600` (чтение и запись только владельцу) — в нём лежат токены.\n * Запись идёт через временный файл с последующим переименованием, поэтому падение процесса\n * посреди сохранения не оставит повреждённую сессию.\n *\n * @example\n * ```ts\n * const itd = new ItdClient({ storage: new FileTokenStorage('./.itd-session.json') });\n * ```\n */\nexport class FileTokenStorage implements TokenStorage {\n readonly #inner: TokenStorage;\n\n /** @param path путь к файлу сессии. Добавьте его в `.gitignore`. */\n constructor(path: string) {\n this.#inner = createTokenStorage(new FileKeyValueStore<ItdSession>(path));\n }\n\n get(): Promise<ItdSession | null> {\n return Promise.resolve(this.#inner.get());\n }\n\n set(session: ItdSession): Promise<void> {\n return Promise.resolve(this.#inner.set(session));\n }\n\n clear(): Promise<void> {\n return Promise.resolve(this.#inner.clear());\n }\n}\n\n/**\n * Хранит сессии нескольких аккаунтов в одном файле.\n *\n * Разбирается с гонкой «прочитать, изменить, записать»: десять аккаунтов пишут в один файл,\n * и без общего слепка с очередью записей они теряли бы сессии друг друга. Как и\n * {@link FileTokenStorage}, пишет через временный файл с правами `0600`.\n *\n * Использует тот же версионированный {@link FileKeyValueStore}, что и одиночное хранилище.\n *\n * @example\n * ```ts\n * const accounts = new ItdAccounts({\n * storage: new FileMultiTokenStorage('./.itd-sessions.json'),\n * });\n * await accounts.restore();\n * ```\n */\nexport class FileMultiTokenStorage implements MultiTokenStorage {\n readonly #inner: MultiTokenStorage;\n\n /** @param path путь к файлу сессий. Добавьте его в `.gitignore`. */\n constructor(path: string) {\n this.#inner = createMultiTokenStorage(new FileKeyValueStore<ItdSession>(path));\n }\n\n get(account: string): Promise<ItdSession | null> {\n return Promise.resolve(this.#inner.get(account));\n }\n\n set(account: string, session: ItdSession): Promise<void> {\n return Promise.resolve(this.#inner.set(account, session));\n }\n\n clear(account: string): Promise<void> {\n return Promise.resolve(this.#inner.clear(account));\n }\n\n accounts(): Promise<readonly string[]> {\n return Promise.resolve(this.#inner.accounts());\n }\n}\n"],"mappings":"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"}
@@ -1,9 +1,9 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_url = require("../shared/url-BaMCQpYH.cjs");
3
- const require_errors = require("../shared/errors-DfU8M5eS.cjs");
4
- const require_render = require("../shared/render-mcuELiYi.cjs");
5
- const require_options = require("../shared/options-Dg5N3r1V.cjs");
6
- const require_auth_provider = require("../shared/auth-provider-CG8oCQ9F.cjs");
2
+ const require_url = require("../shared/url-Bsb3xE5U.cjs");
3
+ const require_errors = require("../shared/errors-BmP3TKoW.cjs");
4
+ const require_redact = require("../shared/redact-BP00URmQ.cjs");
5
+ const require_render = require("../shared/render-Dqi8Owqk.cjs");
6
+ const require_options = require("../shared/options-DOJYtoti.cjs");
7
7
  //#region src/rest/client.ts
8
8
  /**
9
9
  * Минимальный клиент REST API итд.com.
@@ -56,6 +56,10 @@ var ItdRestClient = class ItdRestClient {
56
56
  get search() {
57
57
  return this.#resources.search;
58
58
  }
59
+ /** Каталог, доставка и заказы магазина ИТД. */
60
+ get shop() {
61
+ return this.#resources.shop;
62
+ }
59
63
  /** Жалобы на контент и пользователей. */
60
64
  get reports() {
61
65
  return this.#resources.reports;
@@ -84,22 +88,16 @@ var ItdRestClient = class ItdRestClient {
84
88
  assertActive: (action) => this.#assertActive(action),
85
89
  auth: () => resolveAuthProvider(auth)
86
90
  });
87
- this.#features = new require_render.FeatureRegistry({
88
- http: this.#runtime.http,
89
- services: this.#runtime.services,
90
- serviceOverrides: this.#runtime.config.services,
91
+ this.#features = require_render.createFeatureHost(this.#runtime, {
91
92
  catalog,
92
- baseUrl: this.#runtime.config.baseUrl,
93
- clock: this.#runtime.config.clock,
94
- logger: this.#runtime.config.logger,
95
- assertActive: (action) => this.#assertActive(action),
96
- registerBucket: (name, definition) => this.#runtime.registerRateLimitBucket(name, definition)
93
+ assertActive: (action) => this.#assertActive(action)
97
94
  });
98
95
  const status = this.#features.install(require_render.createStatusFeature());
99
96
  this.#resources = require_render.createResources({
100
97
  http: this.#runtime.http,
101
- fetch: this.#runtime.config.fetch,
102
- status
98
+ files: this.#features.files,
99
+ status,
100
+ createNotifications: (http) => new require_render.NotificationsResource(http)
103
101
  });
104
102
  }
105
103
  #assertActive(action) {
@@ -132,11 +130,11 @@ var ItdRestClient = class ItdRestClient {
132
130
  rateLimitState() {
133
131
  return this.#runtime.rateLimitState();
134
132
  }
135
- /** Устанавливает REST feature поверх общего request pipeline клиента. */
133
+ /** Устанавливает REST-модуль с общей обработкой запросов клиента. */
136
134
  install(feature) {
137
135
  return this.#features.install(feature);
138
136
  }
139
- /** Устанавливает REST feature и публикует его API как readonly-свойство клиента. */
137
+ /** Устанавливает REST-модуль и добавляет его API в свойство только для чтения. */
140
138
  withFeature(key, feature) {
141
139
  this.#assertActive("установить feature");
142
140
  if (typeof key !== "string" || key.trim() === "" || key !== key.trim()) throw new require_errors.ItdConfigError("Свойство feature должно иметь непустое имя без краевых пробелов");
@@ -151,11 +149,11 @@ var ItdRestClient = class ItdRestClient {
151
149
  });
152
150
  return this;
153
151
  }
154
- /** Имена установленных feature в порядке установки. */
152
+ /** Имена установленных модулей в порядке установки. */
155
153
  featureNames() {
156
154
  return this.#features.names();
157
155
  }
158
- /** Установлен ли feature с таким именем. */
156
+ /** Установлен ли модуль с таким именем. */
159
157
  hasFeature(name) {
160
158
  return this.#features.has(name);
161
159
  }
@@ -283,8 +281,8 @@ var ItdRestClient = class ItdRestClient {
283
281
  };
284
282
  /** Приводит опцию `auth` к провайдеру конвейера. */
285
283
  function resolveAuthProvider(auth) {
286
- if (auth === void 0) return require_auth_provider.anonymousAuth();
287
- return typeof auth === "string" ? require_auth_provider.bearerToken(auth) : auth;
284
+ if (auth === void 0) return require_url.anonymousAuth();
285
+ return typeof auth === "string" ? require_url.bearerToken(auth) : auth;
288
286
  }
289
287
  /**
290
288
  * Создаёт минимальный клиент REST API. Равнозначно конструктору {@link ItdRestClient}.
@@ -334,6 +332,7 @@ exports.ItdTimeoutError = require_errors.ItdTimeoutError;
334
332
  exports.ItdValidationError = require_errors.ItdValidationError;
335
333
  exports.LIBRARY_VERSION = require_url.LIBRARY_VERSION;
336
334
  exports.LikesVisibility = require_url.LikesVisibility;
335
+ exports.MemoryShopOrderAccessStorage = require_render.MemoryShopOrderAccessStorage;
337
336
  exports.NotificationType = require_url.NotificationType;
338
337
  exports.OPERATIONS = require_url.OPERATIONS;
339
338
  exports.PaginationMode = require_render.PaginationMode;
@@ -342,21 +341,28 @@ exports.RateLimitPacing = require_url.RateLimitPacing;
342
341
  exports.ReportReason = require_url.ReportReason;
343
342
  exports.ReportTargetType = require_url.ReportTargetType;
344
343
  exports.RetrySafety = require_url.RetrySafety;
345
- exports.RuntimeMode = require_url.RuntimeMode;
344
+ exports.RuntimeMode = require_redact.RuntimeMode;
346
345
  exports.STATUS_SERVICE = require_url.STATUS_SERVICE;
347
346
  exports.ServiceState = require_url.ServiceState;
347
+ exports.ShopConsentKind = require_render.ShopConsentKind;
348
+ exports.ShopOrderStatus = require_render.ShopOrderStatus;
349
+ exports.ShopProductCategory = require_render.ShopProductCategory;
350
+ exports.ShopProductStatus = require_render.ShopProductStatus;
348
351
  exports.SpanRenderFormat = require_render.SpanRenderFormat;
349
352
  exports.SpanType = require_url.SpanType;
350
353
  exports.VIDEO_MIME_TYPES = require_render.VIDEO_MIME_TYPES;
351
354
  exports.ViewReason = require_url.ViewReason;
352
355
  exports.ViewSource = require_url.ViewSource;
353
356
  exports.WallAccess = require_url.WallAccess;
354
- exports.anonymousAuth = require_auth_provider.anonymousAuth;
357
+ exports.anonymousAuth = require_url.anonymousAuth;
355
358
  exports.autoSpans = require_render.autoSpans;
356
- exports.bearerToken = require_auth_provider.bearerToken;
359
+ exports.bearerToken = require_url.bearerToken;
357
360
  exports.canonicalNotificationType = require_url.canonicalNotificationType;
358
361
  exports.comment = require_render.comment;
362
+ exports.createMemoryShopOrderAccessStorage = require_render.createMemoryShopOrderAccessStorage;
359
363
  exports.createRestClient = createRestClient;
364
+ exports.createShopFeature = require_render.createShopFeature;
365
+ exports.createShopOrderAccessStorage = require_render.createShopOrderAccessStorage;
360
366
  exports.formatNotificationText = require_url.formatNotificationText;
361
367
  exports.fromStream = require_render.fromStream;
362
368
  exports.fromUrl = require_render.fromUrl;
@@ -392,7 +398,7 @@ exports.resolveNotificationUrl = require_url.resolveNotificationUrl;
392
398
  exports.statusDays = require_render.statusDays;
393
399
  exports.systemClock = require_url.systemClock;
394
400
  exports.toDate = require_render.toDate;
395
- exports.tokenProvider = require_auth_provider.tokenProvider;
401
+ exports.tokenProvider = require_url.tokenProvider;
396
402
  exports.utcStampToIso = require_render.utcStampToIso;
397
403
 
398
404
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":["#runtime","#features","#resources","ExtensibleOperationCatalog","ITD_CATALOG","createClientRuntime","#assertActive","FeatureRegistry","createStatusFeature","createResources","#disposed","ItdStateError","ItdConfigError","#disposePromise","#dispose","anonymousAuth","bearerToken"],"sources":["../../src/rest/client.ts"],"sourcesContent":["import { installAsyncDisposeFallback } from '../core/async-dispose.js';\nimport { type AuthProvider, anonymousAuth, bearerToken } from '../core/auth-provider.js';\nimport { ItdConfigError, ItdStateError } from '../core/errors.js';\nimport { type ClientRuntime, createClientRuntime } from '../core/execution/client-runtime.js';\nimport { ExtensibleOperationCatalog } from '../core/feature-catalog.js';\nimport { type ClientFeature, FeatureRegistry } from '../core/features.js';\nimport type { RawRequestOptions, RuntimeOptions } from '../core/options.js';\nimport type { ClientPlugin } from '../core/plugins/contracts.js';\nimport type { RateLimitBucketState } from '../core/scheduling/rate-limit.js';\nimport type { ServiceDefinition } from '../core/services.js';\nimport { ITD_CATALOG } from '../domain/catalog.js';\nimport type { CommentsResource } from '../resources/comments.js';\nimport type { FilesResource } from '../resources/files.js';\nimport type { HashtagsResource } from '../resources/hashtags.js';\nimport type { NotificationsResource } from '../resources/notifications.js';\nimport type { PlatformResource } from '../resources/platform.js';\nimport type { PostsResource } from '../resources/posts.js';\nimport type { ReportsResource } from '../resources/reports.js';\nimport type { SearchResource } from '../resources/search.js';\nimport { createStatusFeature } from '../resources/status.js';\nimport type { SubscriptionResource } from '../resources/subscription.js';\nimport type { TelemetryResource } from '../resources/telemetry.js';\nimport type { UsersResource } from '../resources/users.js';\nimport type { VerificationResource } from '../resources/verification.js';\nimport { createResources, type RestResources } from './resources.js';\n\n/** Опции конструктора {@link ItdRestClient}. */\nexport interface RestClientOptions extends RuntimeOptions {\n /**\n * Авторизация. Строка — сокращение для {@link bearerToken}.\n *\n * Без неё доступны только публичные эндпоинты. Токен здесь считается готовым: продлевать\n * его клиент не умеет и на `401` отвечает ошибкой. Сессия, которая входит по паролю\n * и продлевает себя сама, живёт в полном `ItdClient`.\n */\n auth?: string | AuthProvider | undefined;\n}\n\n/**\n * Минимальный клиент REST API итд.com.\n *\n * Тот же конвейер запросов, что и у полного клиента, — с повторами, очередью, плагинами\n * и типизированными ошибками, — но без сессии, потока событий и нескольких аккаунтов.\n * Нужен там, где токен уже есть, а размер поставки важен: серверные интеграции, воркеры,\n * браузерные приложения.\n *\n * @example\n * ```ts\n * import { createRestClient } from 'itd-api/rest';\n *\n * const api = createRestClient({ auth: process.env.ITD_TOKEN });\n * const feed = await api.posts.list({ tab: 'popular' });\n * ```\n */\nexport class ItdRestClient {\n readonly #runtime: ClientRuntime;\n readonly #features: FeatureRegistry;\n readonly #resources: RestResources;\n /** Общий результат терминальной очистки для идемпотентных повторных вызовов. */\n #disposePromise: Promise<void> | undefined;\n #disposed = false;\n\n /** Профили, подписки, блокировки, приватность. */\n get users(): UsersResource {\n return this.#resources.users;\n }\n\n /** Лента, публикация, реакции, репосты, комментарии к постам. */\n get posts(): PostsResource {\n return this.#resources.posts;\n }\n\n /** Ответы на комментарии и действия над ними. */\n get comments(): CommentsResource {\n return this.#resources.comments;\n }\n\n /** Загрузка файлов и медиа. */\n get files(): FilesResource {\n return this.#resources.files;\n }\n\n /** Уведомления: список, счётчик, отметки о прочтении, настройки. */\n get notifications(): NotificationsResource {\n return this.#resources.notifications;\n }\n\n /** Хэштеги и посты по ним. */\n get hashtags(): HashtagsResource {\n return this.#resources.hashtags;\n }\n\n /** Глобальный поиск по пользователям и хэштегам. */\n get search(): SearchResource {\n return this.#resources.search;\n }\n\n /** Жалобы на контент и пользователей. */\n get reports(): ReportsResource {\n return this.#resources.reports;\n }\n\n /** Верификация профиля. */\n get verification(): VerificationResource {\n return this.#resources.verification;\n }\n\n /** Подписка и способы оплаты. */\n get subscription(): SubscriptionResource {\n return this.#resources.subscription;\n }\n\n /** Сведения о платформе: версии приложений, изменения, анонсы, баннер события. */\n get platform(): PlatformResource {\n return this.#resources.platform;\n }\n\n /** Телеметрия просмотров. */\n get telemetry(): TelemetryResource {\n return this.#resources.telemetry;\n }\n\n constructor(options: RestClientOptions = {}) {\n const { auth, ...runtimeOptions } = options;\n const catalog = new ExtensibleOperationCatalog(ITD_CATALOG);\n\n this.#runtime = createClientRuntime(runtimeOptions, {\n catalog,\n assertActive: (action) => this.#assertActive(action),\n auth: () => resolveAuthProvider(auth),\n });\n this.#features = new FeatureRegistry({\n http: this.#runtime.http,\n services: this.#runtime.services,\n serviceOverrides: this.#runtime.config.services,\n catalog,\n baseUrl: this.#runtime.config.baseUrl,\n clock: this.#runtime.config.clock,\n logger: this.#runtime.config.logger,\n assertActive: (action) => this.#assertActive(action),\n registerBucket: (name, definition) => this.#runtime.registerRateLimitBucket(name, definition),\n });\n const status = this.#features.install(createStatusFeature());\n this.#resources = createResources({\n http: this.#runtime.http,\n fetch: this.#runtime.config.fetch,\n status,\n });\n }\n\n #assertActive(action: string): void {\n if (!this.#disposed) return;\n throw new ItdStateError(\n `Клиент уже окончательно освобождён через dispose(); нельзя ${action}. Создайте новый клиент`,\n );\n }\n\n /** Базовый URL, к которому обращается клиент. */\n get baseUrl(): string {\n return this.#runtime.config.baseUrl;\n }\n\n /**\n * Выполняет произвольный запрос к API.\n *\n * Запасной путь для случаев, когда нужного метода ещё нет или ответ сервера разошёлся\n * с документацией. Проходит через ту же авторизацию, очередь и обработку ошибок.\n *\n * @throws {ItdStateError} если клиент уже освобождён через {@link dispose}\n */\n request<T = unknown>(options: RawRequestOptions): Promise<T> {\n return this.#runtime.http.request<T>({\n ...options,\n operationId: options.operationId ?? 'raw',\n });\n }\n\n /**\n * Остаток серверных лимитов по бакетам, через которые уже проходили запросы.\n *\n * Пустой массив при `rateLimit: false`.\n */\n rateLimitState(): RateLimitBucketState[] {\n return this.#runtime.rateLimitState();\n }\n\n /** Устанавливает REST feature поверх общего request pipeline клиента. */\n install<TApi>(feature: ClientFeature<TApi>): TApi {\n return this.#features.install(feature);\n }\n\n /** Устанавливает REST feature и публикует его API как readonly-свойство клиента. */\n withFeature<const K extends string, TApi>(\n key: K,\n feature: ClientFeature<TApi>,\n ): this & { readonly [P in K]: TApi } {\n this.#assertActive('установить feature');\n if (typeof key !== 'string' || key.trim() === '' || key !== key.trim()) {\n throw new ItdConfigError('Свойство feature должно иметь непустое имя без краевых пробелов');\n }\n if (key === 'then' || key in this) {\n throw new ItdConfigError(`Свойство клиента «${key}» уже занято или зарезервировано`);\n }\n if (!Object.isExtensible(this)) {\n throw new ItdConfigError('Нельзя опубликовать feature на нерасширяемом клиенте');\n }\n\n const api = this.install(feature);\n Object.defineProperty(this, key, {\n value: api,\n enumerable: true,\n configurable: false,\n writable: false,\n });\n return this as this & { readonly [P in K]: TApi };\n }\n\n /** Имена установленных feature в порядке установки. */\n featureNames(): string[] {\n return this.#features.names();\n }\n\n /** Установлен ли feature с таким именем. */\n hasFeature(name: string): boolean {\n return this.#features.has(name);\n }\n\n /**\n * Подключает плагин.\n *\n * Сессионная идентичность плагину не передаётся: у клиента с готовым токеном её нет.\n * Плагинам, которые изолируют состояние по аккаунту, нужен полный `ItdClient`.\n *\n * @throws {ItdConfigError} если плагин задан неверно или уже подключён\n * @throws {ItdStateError} если клиент уже освобождён через {@link dispose}\n */\n use(plugin: ClientPlugin): this {\n this.#assertActive('подключить плагин');\n this.#runtime.plugins.add(plugin, {\n baseUrl: this.#runtime.config.baseUrl,\n logger: this.#runtime.config.logger,\n });\n return this;\n }\n\n /**\n * Отключает плагин и освобождает заведённые им ресурсы.\n *\n * @returns `false`, если такого плагина не было\n * @throws {ItdConfigError} если от плагина зависит другой подключённый плагин\n */\n unuse(name: string): Promise<boolean> {\n return this.#runtime.plugins.remove(name);\n }\n\n /** Имена подключённых плагинов в фактическом порядке выполнения обёрток. */\n pluginNames(): string[] {\n return this.#runtime.plugins.names();\n }\n\n /** Подключён ли плагин с таким именем. */\n hasPlugin(name: string): boolean {\n return this.#runtime.plugins.has(name);\n }\n\n /**\n * Регистрирует сервис платформы — домен, отличный от основного.\n *\n * @throws {ItdConfigError} если определение неверно или имя уже занято\n * @throws {ItdStateError} если клиент уже освобождён через {@link dispose}\n */\n defineService(definition: ServiceDefinition): this {\n this.#assertActive('зарегистрировать сервис');\n this.#runtime.services.define(definition);\n return this;\n }\n\n /**\n * Отправляет открытые накопители {@link telemetry} и останавливает очередь запросов.\n *\n * После вызова клиентом можно пользоваться снова. Терминальное освобождение —\n * это {@link dispose}.\n */\n async close(): Promise<void> {\n const errors: unknown[] = [];\n try {\n try {\n await this.#features.close();\n } catch (error) {\n errors.push(error);\n }\n try {\n await this.#resources.closeTelemetry(false);\n } catch (error) {\n errors.push(error);\n }\n } finally {\n this.#runtime.close();\n }\n if (errors.length === 1) throw errors[0];\n if (errors.length > 1) throw new AggregateError(errors, 'Не удалось закрыть клиент');\n }\n\n /**\n * Окончательно освобождает клиент: выполняет {@link close}, отменяет незавершённые\n * запросы и отключает все плагины.\n *\n * Терминальное состояние устанавливается сразу при первом вызове; повторные вызовы\n * возвращают тот же результат очистки.\n *\n * @example\n * ```ts\n * await using api = createRestClient({ auth: token });\n * ```\n */\n dispose(): Promise<void> {\n if (this.#disposePromise) return this.#disposePromise;\n this.#disposed = true;\n this.#disposePromise = this.#dispose();\n return this.#disposePromise;\n }\n\n async #dispose(): Promise<void> {\n const errors: unknown[] = [];\n // Телеметрия уходит через ещё установленный plugin pipeline и мимо проверки состояния.\n this.#resources.prepareTelemetryClose();\n try {\n await this.#features.close();\n } catch (error) {\n errors.push(error);\n }\n try {\n await this.#resources.closeTelemetry(true);\n } catch (error) {\n errors.push(error);\n }\n try {\n await this.#features.dispose();\n } catch (error) {\n errors.push(error);\n }\n try {\n this.#runtime.close();\n await this.#runtime.dispose();\n } catch (error) {\n errors.push(error);\n }\n if (errors.length > 0) throw new AggregateError(errors, 'Не удалось освободить клиент');\n }\n\n /** Позволяет использовать клиент с `await using`. */\n [Symbol.asyncDispose](): Promise<void> {\n return this.dispose();\n }\n\n static {\n installAsyncDisposeFallback(ItdRestClient);\n }\n}\n\n/** Приводит опцию `auth` к провайдеру конвейера. */\nfunction resolveAuthProvider(auth: RestClientOptions['auth']): AuthProvider {\n if (auth === undefined) return anonymousAuth();\n return typeof auth === 'string' ? bearerToken(auth) : auth;\n}\n\n/**\n * Создаёт минимальный клиент REST API. Равнозначно конструктору {@link ItdRestClient}.\n *\n * @example\n * ```ts\n * const api = createRestClient({ auth: token, rateLimit: { concurrency: 4 } });\n * ```\n */\nexport function createRestClient(options: RestClientOptions = {}): ItdRestClient {\n return new ItdRestClient(options);\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","names":["#runtime","#features","#resources","ExtensibleOperationCatalog","ITD_CATALOG","createClientRuntime","#assertActive","createFeatureHost","createStatusFeature","createResources","NotificationsResource","#disposed","ItdStateError","ItdConfigError","#disposePromise","#dispose","anonymousAuth","bearerToken"],"sources":["../../src/rest/client.ts"],"sourcesContent":["import { installAsyncDisposeFallback } from '../core/async-dispose.js';\nimport { type AuthProvider, anonymousAuth, bearerToken } from '../core/auth-provider.js';\nimport { ItdConfigError, ItdStateError } from '../core/errors.js';\nimport { type ClientRuntime, createClientRuntime } from '../core/execution/client-runtime.js';\nimport { ExtensibleOperationCatalog } from '../core/feature-catalog.js';\nimport { type ClientFeatureHost, createFeatureHost } from '../core/feature-host.js';\nimport type { ClientFeature } from '../core/features.js';\nimport type { RawRequestOptions, RuntimeOptions } from '../core/options.js';\nimport type { ClientPlugin } from '../core/plugins/contracts.js';\nimport type { RateLimitBucketState } from '../core/scheduling/rate-limit.js';\nimport type { ServiceDefinition } from '../core/services.js';\nimport { ITD_CATALOG } from '../domain/catalog.js';\nimport type { CommentsResource } from '../resources/comments.js';\nimport type { FilesResource } from '../resources/files.js';\nimport type { HashtagsResource } from '../resources/hashtags.js';\nimport { NotificationsResource } from '../resources/notifications.js';\nimport type { PlatformResource } from '../resources/platform.js';\nimport type { PostsResource } from '../resources/posts.js';\nimport type { ReportsResource } from '../resources/reports.js';\nimport type { SearchResource } from '../resources/search.js';\nimport type { ShopResource } from '../resources/shop.js';\nimport { createStatusFeature } from '../resources/status.js';\nimport type { SubscriptionResource } from '../resources/subscription.js';\nimport type { TelemetryResource } from '../resources/telemetry.js';\nimport type { UsersResource } from '../resources/users.js';\nimport type { VerificationResource } from '../resources/verification.js';\nimport { createResources, type RestResources } from './resources.js';\n\n/** Опции конструктора {@link ItdRestClient}. */\nexport interface RestClientOptions extends RuntimeOptions {\n /**\n * Авторизация. Строка — сокращение для {@link bearerToken}.\n *\n * Без неё доступны только публичные эндпоинты. Токен здесь считается готовым: продлевать\n * его клиент не умеет и на `401` отвечает ошибкой. Сессия, которая входит по паролю\n * и продлевает себя сама, живёт в полном `ItdClient`.\n */\n auth?: string | AuthProvider | undefined;\n}\n\n/**\n * Минимальный клиент REST API итд.com.\n *\n * Тот же конвейер запросов, что и у полного клиента, — с повторами, очередью, плагинами\n * и типизированными ошибками, — но без сессии, потока событий и нескольких аккаунтов.\n * Нужен там, где токен уже есть, а размер поставки важен: серверные интеграции, воркеры,\n * браузерные приложения.\n *\n * @example\n * ```ts\n * import { createRestClient } from 'itd-api/rest';\n *\n * const api = createRestClient({ auth: process.env.ITD_TOKEN });\n * const feed = await api.posts.list({ tab: 'popular' });\n * ```\n */\nexport class ItdRestClient {\n readonly #runtime: ClientRuntime;\n readonly #features: ClientFeatureHost;\n readonly #resources: RestResources;\n /** Общий результат терминальной очистки для идемпотентных повторных вызовов. */\n #disposePromise: Promise<void> | undefined;\n #disposed = false;\n\n /** Профили, подписки, блокировки, приватность. */\n get users(): UsersResource {\n return this.#resources.users;\n }\n\n /** Лента, публикация, реакции, репосты, комментарии к постам. */\n get posts(): PostsResource {\n return this.#resources.posts;\n }\n\n /** Ответы на комментарии и действия над ними. */\n get comments(): CommentsResource {\n return this.#resources.comments;\n }\n\n /** Загрузка файлов и медиа. */\n get files(): FilesResource {\n return this.#resources.files;\n }\n\n /** Уведомления: список, счётчик, отметки о прочтении, настройки. */\n get notifications(): NotificationsResource {\n return this.#resources.notifications;\n }\n\n /** Хэштеги и посты по ним. */\n get hashtags(): HashtagsResource {\n return this.#resources.hashtags;\n }\n\n /** Глобальный поиск по пользователям и хэштегам. */\n get search(): SearchResource {\n return this.#resources.search;\n }\n\n /** Каталог, доставка и заказы магазина ИТД. */\n get shop(): ShopResource {\n return this.#resources.shop;\n }\n\n /** Жалобы на контент и пользователей. */\n get reports(): ReportsResource {\n return this.#resources.reports;\n }\n\n /** Верификация профиля. */\n get verification(): VerificationResource {\n return this.#resources.verification;\n }\n\n /** Подписка и способы оплаты. */\n get subscription(): SubscriptionResource {\n return this.#resources.subscription;\n }\n\n /** Сведения о платформе: версии приложений, изменения, анонсы, баннер события. */\n get platform(): PlatformResource {\n return this.#resources.platform;\n }\n\n /** Телеметрия просмотров. */\n get telemetry(): TelemetryResource {\n return this.#resources.telemetry;\n }\n\n constructor(options: RestClientOptions = {}) {\n const { auth, ...runtimeOptions } = options;\n const catalog = new ExtensibleOperationCatalog(ITD_CATALOG);\n\n this.#runtime = createClientRuntime(runtimeOptions, {\n catalog,\n assertActive: (action) => this.#assertActive(action),\n auth: () => resolveAuthProvider(auth),\n });\n this.#features = createFeatureHost(this.#runtime, {\n catalog,\n assertActive: (action) => this.#assertActive(action),\n });\n const status = this.#features.install(createStatusFeature());\n this.#resources = createResources({\n http: this.#runtime.http,\n files: this.#features.files,\n status,\n createNotifications: (http) => new NotificationsResource(http),\n });\n }\n\n #assertActive(action: string): void {\n if (!this.#disposed) return;\n throw new ItdStateError(\n `Клиент уже окончательно освобождён через dispose(); нельзя ${action}. Создайте новый клиент`,\n );\n }\n\n /** Базовый URL, к которому обращается клиент. */\n get baseUrl(): string {\n return this.#runtime.config.baseUrl;\n }\n\n /**\n * Выполняет произвольный запрос к API.\n *\n * Запасной путь для случаев, когда нужного метода ещё нет или ответ сервера разошёлся\n * с документацией. Проходит через ту же авторизацию, очередь и обработку ошибок.\n *\n * @throws {ItdStateError} если клиент уже освобождён через {@link dispose}\n */\n request<T = unknown>(options: RawRequestOptions): Promise<T> {\n return this.#runtime.http.request<T>({\n ...options,\n operationId: options.operationId ?? 'raw',\n });\n }\n\n /**\n * Остаток серверных лимитов по бакетам, через которые уже проходили запросы.\n *\n * Пустой массив при `rateLimit: false`.\n */\n rateLimitState(): RateLimitBucketState[] {\n return this.#runtime.rateLimitState();\n }\n\n /** Устанавливает REST-модуль с общей обработкой запросов клиента. */\n install<TApi>(feature: ClientFeature<TApi>): TApi {\n return this.#features.install(feature);\n }\n\n /** Устанавливает REST-модуль и добавляет его API в свойство только для чтения. */\n withFeature<const K extends string, TApi>(\n key: K,\n feature: ClientFeature<TApi>,\n ): this & { readonly [P in K]: TApi } {\n this.#assertActive('установить feature');\n if (typeof key !== 'string' || key.trim() === '' || key !== key.trim()) {\n throw new ItdConfigError('Свойство feature должно иметь непустое имя без краевых пробелов');\n }\n if (key === 'then' || key in this) {\n throw new ItdConfigError(`Свойство клиента «${key}» уже занято или зарезервировано`);\n }\n if (!Object.isExtensible(this)) {\n throw new ItdConfigError('Нельзя опубликовать feature на нерасширяемом клиенте');\n }\n\n const api = this.install(feature);\n Object.defineProperty(this, key, {\n value: api,\n enumerable: true,\n configurable: false,\n writable: false,\n });\n return this as this & { readonly [P in K]: TApi };\n }\n\n /** Имена установленных модулей в порядке установки. */\n featureNames(): string[] {\n return this.#features.names();\n }\n\n /** Установлен ли модуль с таким именем. */\n hasFeature(name: string): boolean {\n return this.#features.has(name);\n }\n\n /**\n * Подключает плагин.\n *\n * Сессионная идентичность плагину не передаётся: у клиента с готовым токеном её нет.\n * Плагинам, которые изолируют состояние по аккаунту, нужен полный `ItdClient`.\n *\n * @throws {ItdConfigError} если плагин задан неверно или уже подключён\n * @throws {ItdStateError} если клиент уже освобождён через {@link dispose}\n */\n use(plugin: ClientPlugin): this {\n this.#assertActive('подключить плагин');\n this.#runtime.plugins.add(plugin, {\n baseUrl: this.#runtime.config.baseUrl,\n logger: this.#runtime.config.logger,\n });\n return this;\n }\n\n /**\n * Отключает плагин и освобождает заведённые им ресурсы.\n *\n * @returns `false`, если такого плагина не было\n * @throws {ItdConfigError} если от плагина зависит другой подключённый плагин\n */\n unuse(name: string): Promise<boolean> {\n return this.#runtime.plugins.remove(name);\n }\n\n /** Имена подключённых плагинов в фактическом порядке выполнения обёрток. */\n pluginNames(): string[] {\n return this.#runtime.plugins.names();\n }\n\n /** Подключён ли плагин с таким именем. */\n hasPlugin(name: string): boolean {\n return this.#runtime.plugins.has(name);\n }\n\n /**\n * Регистрирует сервис платформы — домен, отличный от основного.\n *\n * @throws {ItdConfigError} если определение неверно или имя уже занято\n * @throws {ItdStateError} если клиент уже освобождён через {@link dispose}\n */\n defineService(definition: ServiceDefinition): this {\n this.#assertActive('зарегистрировать сервис');\n this.#runtime.services.define(definition);\n return this;\n }\n\n /**\n * Отправляет открытые накопители {@link telemetry} и останавливает очередь запросов.\n *\n * После вызова клиентом можно пользоваться снова. Терминальное освобождение —\n * это {@link dispose}.\n */\n async close(): Promise<void> {\n const errors: unknown[] = [];\n try {\n try {\n await this.#features.close();\n } catch (error) {\n errors.push(error);\n }\n try {\n await this.#resources.closeTelemetry(false);\n } catch (error) {\n errors.push(error);\n }\n } finally {\n this.#runtime.close();\n }\n if (errors.length === 1) throw errors[0];\n if (errors.length > 1) throw new AggregateError(errors, 'Не удалось закрыть клиент');\n }\n\n /**\n * Окончательно освобождает клиент: выполняет {@link close}, отменяет незавершённые\n * запросы и отключает все плагины.\n *\n * Терминальное состояние устанавливается сразу при первом вызове; повторные вызовы\n * возвращают тот же результат очистки.\n *\n * @example\n * ```ts\n * await using api = createRestClient({ auth: token });\n * ```\n */\n dispose(): Promise<void> {\n if (this.#disposePromise) return this.#disposePromise;\n this.#disposed = true;\n this.#disposePromise = this.#dispose();\n return this.#disposePromise;\n }\n\n async #dispose(): Promise<void> {\n const errors: unknown[] = [];\n // Телеметрия уходит через ещё установленные плагины и мимо проверки состояния.\n this.#resources.prepareTelemetryClose();\n try {\n await this.#features.close();\n } catch (error) {\n errors.push(error);\n }\n try {\n await this.#resources.closeTelemetry(true);\n } catch (error) {\n errors.push(error);\n }\n try {\n await this.#features.dispose();\n } catch (error) {\n errors.push(error);\n }\n try {\n this.#runtime.close();\n await this.#runtime.dispose();\n } catch (error) {\n errors.push(error);\n }\n if (errors.length > 0) throw new AggregateError(errors, 'Не удалось освободить клиент');\n }\n\n /** Позволяет использовать клиент с `await using`. */\n [Symbol.asyncDispose](): Promise<void> {\n return this.dispose();\n }\n\n static {\n installAsyncDisposeFallback(ItdRestClient);\n }\n}\n\n/** Приводит опцию `auth` к провайдеру конвейера. */\nfunction resolveAuthProvider(auth: RestClientOptions['auth']): AuthProvider {\n if (auth === undefined) return anonymousAuth();\n return typeof auth === 'string' ? bearerToken(auth) : auth;\n}\n\n/**\n * Создаёт минимальный клиент REST API. Равнозначно конструктору {@link ItdRestClient}.\n *\n * @example\n * ```ts\n * const api = createRestClient({ auth: token, rateLimit: { concurrency: 4 } });\n * ```\n */\nexport function createRestClient(options: RestClientOptions = {}): ItdRestClient {\n return new ItdRestClient(options);\n}\n"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
- import { $ as UserSummary, $t as RateLimitPacing, A as isItdFileError, B as Notification, Bt as RateLimitOptions, C as ItdStateError, Ct as ReportReason, D as isItdAuthError, Dt as ViewReason, E as isItdApiError, Et as SpanType, F as isItdServerError, Ft as Logger, G as FollowResult, Gt as ResponseContext, H as Actor, Ht as RequestContext, I as isItdStateError, It as OperationRequestOptions, J as PinsResult, Jt as RetryOptions, K as MyProfile, Kt as RetryContext, L as isItdValidationError, Lt as PaginationOptions, M as isItdNotFoundError, Mt as Unsubscribe, N as isItdPhoneVerificationError, Nt as ClientHooks, O as isItdConflictError, Ot as ViewSource, P as isItdRateLimitError, Pt as ErrorContextHook, Q as SubscriptionState, Qt as ServiceDefinition, R as NotificationEvent, Rt as RateLimitBucketContext, S as ItdServerError, T as ItdValidationError, Tt as ServiceState, Ut as RequestExtensions, V as NotificationSettings, Vt as RawRequestOptions, W as Author, Wt as RequestOptions, X as Profile, Xt as QueryParams, Y as PrivacySettings, Yt as RuntimeOptions, Z as PublicProfile, Zt as QueryValue, _ as ItdForbiddenError, _n as RetrySafety, _t as InteractionType, a as ItdAbortError, an as ItdOperationDefinition, at as DEFAULT_BASE_URL, b as ItdPhoneVerificationError, bt as Loose, c as ItdApiErrorKind, cn as isBuiltInOperationId, ct as IsoDate, d as ItdConflictError, dn as operationRetrySafety, dt as UserRef, en as RuntimeMode, f as ItdError, fn as BUCKET_LIMITS, ft as AccessType, g as ItdFileErrorReason, gn as OperationMethod, gt as IncidentKind, h as ItdFileError, hn as FeatureOperationId, ht as FeedTab, i as formatNotificationText, in as CustomOperationId, it as tokenProvider, j as isItdForbiddenError, jt as Listener, k as isItdError, kt as WallAccess, l as ItdAuthError, ln as operationBucket, lt as Span, m as ItdFieldErrors, mn as RateLimitBucket, mt as CommentSort, n as canonicalNotificationType, nn as systemClock, nt as anonymousAuth, o as ItdApiError, on as OPERATIONS, ot as STATUS_SERVICE, p as ItdErrorKind, pn as DEFAULT_RATE_LIMIT_BUCKET, pt as AttachmentType, q as Pin, qt as RetryDecisionContext, r as isKnownNotificationType, rn as BuiltInOperationId, rt as bearerToken, s as ItdApiErrorInit, sn as OperationId, st as LIBRARY_VERSION, t as resolveNotificationUrl, tn as ItdClock, tt as AuthProvider, u as ItdConfigError, un as operationMethod, ut as UserId, v as ItdNetworkError, vt as ItdErrorCode, w as ItdTimeoutError, wt as ReportTargetType, x as ItdRateLimitError, xt as NotificationType, y as ItdNotFoundError, yt as LikesVisibility, z as normalizeNotification, zt as RateLimitBucketOverride } from "../shared/url-DTfZ2toq.cjs";
2
- import { $ as poll, $t as CreatePostData, A as TelemetryResource, At as FilesResource, B as ReportInput, Bt as PinPostResult, C as DwellEntry, Cn as FeatureBucketDefinition, Ct as Report, D as TelemetryBatchOptions, Dn as FeatureRequestOptions, Dt as UpdateNotificationSettingsInput, E as TelemetryBatch, En as FeatureOperationDefinition, Et as NotificationsResource, F as SubscriptionResource, Ft as Attachment, G as UserPostsParams, Gt as CommentBuilder, H as CommentsParams, Ht as PollOption, I as SearchResource, It as Comment, J as PostInput, Jt as BuilderInput, K as CreatePostInput, Kt as CommentInput, L as SearchResult, Lt as CommentReplyTo, M as ViewTracker, Mt as UploadedFile, N as ViewTrackerInput, Nt as CommentsResource, O as TelemetryClock, Ot as HashtagPostsParams, P as ViewTrackerOptions, Pt as RepliesParams, Q as PollInput, Qt as CreatePollInput, R as ReportsResource, Rt as Hashtag, S as UsersResource, Sn as ClientFeature, St as Portal, T as PhotoOpenInput, Tn as FeatureInstallation, Tt as NotificationListParams, U as FeedParams, Ut as Post, V as report, Vt as Poll, W as PostsResource, Wt as PostStats, X as post, Xt as isBuilder, Y as PostUpdateInput, Yt as ItdBuilder, Z as PollBuilder, Zt as CreateCommentInput, _ as fromUrl, _n as ClientPlugin, _t as StatusIncidentLine, a as isMyProfile, an as PaginationMode, at as MarkupContent, b as UpdateProfileInput, bn as PluginApi, bt as ChangelogEntry, c as ALLOWED_MIME_TYPES, cn as mapPage, ct as TextMarkup, d as AudioMimeType, dn as Subscription, dt as PlatformClientVersion, en as CreateReportInput, et as ParseMarkupOptions, f as IMAGE_MIME_TYPES, fn as RateLimitBucketState, ft as PlatformResource, g as fromStream, gn as AttemptNext, gt as StatusDay, h as VideoMimeType, hn as AttemptInterceptor, ht as ServiceStatus, i as statusDays, in as PageState, it as MarkupBuilder, j as VideoProgressInput, jt as UploadOptions, k as TelemetryOptions, kt as HashtagsResource, l as AUDIO_MIME_TYPES, ln as PaymentMethod, lt as autoSpans, m as VIDEO_MIME_TYPES, mn as AttemptExtensions, mt as PlatformStatus, n as SpanRenderFormat, nt as parseMarkdown, o as toDate, on as Paginator, ot as MarkupInput, p as ImageMimeType, pn as AttemptContext, pt as PlatformVersions, q as PostBuilder, qt as comment, r as renderSpans, rn as Page, rt as AutoSpansOptions, s as utcStampToIso, sn as PaginatorOptions, st as MarkupSpan, t as RenderSpansOptions, tn as UpdatePostInput, tt as parseHtml, u as AllowedMimeType, un as Session, ut as markup, v as VerificationResource, vn as OperationExtensions, vt as Announcement, w as InteractionEntry, wn as FeatureContext, wt as VerificationStatus, x as UserListParams, xn as PluginTeardown, xt as Clan, y as UpdatePrivacyInput, yn as OperationTransformer, yt as AnnouncementButton, z as ReportBuilder, zt as LikeResult } from "../shared/render-DO0F5YSm.cjs";
1
+ import { $ as isItdValidationError, $t as RateLimitBucket, A as ItdFieldErrors, At as ResponseContext, B as ItdTimeoutError, Bt as ItdClock, C as ItdApiErrorInit, Ct as RateLimitBucketContext, D as ItdConflictError, Dt as RequestContext, E as ItdConfigError, Et as RawRequestOptions, F as ItdNotFoundError, Ft as QueryParams, G as isItdError, Gt as OPERATIONS, H as isItdApiError, Ht as BuiltInOperationId, I as ItdPhoneVerificationError, It as QueryValue, J as isItdNotFoundError, Jt as operationBucket, K as isItdFileError, Kt as OperationId, L as ItdRateLimitError, Lt as ServiceDefinition, M as ItdFileErrorReason, Mt as RetryDecisionContext, N as ItdForbiddenError, Nt as RetryOptions, O as ItdError, Ot as RequestExtensions, P as ItdNetworkError, Pt as RuntimeOptions, Q as isItdStateError, Qt as DEFAULT_RATE_LIMIT_BUCKET, R as ItdServerError, Rt as RateLimitPacing, S as ItdApiError, St as PaginationOptions, T as ItdAuthError, Tt as RateLimitOptions, U as isItdAuthError, Ut as CustomOperationId, V as ItdValidationError, Vt as systemClock, W as isItdConflictError, Wt as ItdOperationDefinition, X as isItdRateLimitError, Xt as operationRetrySafety, Y as isItdPhoneVerificationError, Yt as operationMethod, Z as isItdServerError, Zt as BUCKET_LIMITS, _ as Profile, _n as ServiceState, _t as RetrySafety, a as NotificationEvent, an as AttachmentType, at as tokenProvider, b as UserSummary, bn as ViewSource, bt as Logger, c as NotificationSettings, cn as FeedTab, ct as Unsubscribe, d as Author, dn as ItdErrorCode, dt as LIBRARY_VERSION, en as IsoDate, et as ClientConnection, f as FollowResult, fn as LikesVisibility, ft as FeatureOperationId, g as PrivacySettings, gn as ReportTargetType, gt as OperationMethod, h as PinsResult, hn as ReportReason, ht as OperationMetadata, i as formatNotificationText, in as AccessType, it as bearerToken, j as ItdFileError, jt as RetryContext, k as ItdErrorKind, kt as RequestOptions, l as Actor, ln as IncidentKind, lt as DEFAULT_BASE_URL, m as Pin, mn as NotificationType, n as canonicalNotificationType, nn as UserId, nt as AuthProvider, o as normalizeNotification, on as CommentSort, p as MyProfile, pn as Loose, pt as OperationAnnotations, q as isItdForbiddenError, qt as isBuiltInOperationId, r as isKnownNotificationType, rn as UserRef, rt as anonymousAuth, s as Notification, st as Listener, t as resolveNotificationUrl, tn as Span, un as InteractionType, ut as STATUS_SERVICE, v as PublicProfile, vn as SpanType, vt as ClientHooks, w as ItdApiErrorKind, wt as RateLimitBucketOverride, x as ItdAbortError, xn as WallAccess, xt as OperationRequestOptions, y as SubscriptionState, yn as ViewReason, yt as ErrorContextHook, z as ItdStateError, zt as RuntimeMode } from "../shared/url-XBsMdAcv.cjs";
2
+ import { $ as ShopConsent, $n as Paginator, $t as autoSpans, A as UsersResource, An as Post, At as ReportInput, B as ViewTracker, Bn as CreatePostData, Bt as post, C as VideoMimeType, Cn as Comment, Cr as OperationTransformer, Ct as ShopRecipient, D as UpdatePrivacyInput, Dn as PinPostResult, Dt as SearchResult, E as VerificationResource, En as LikeResult, Et as SearchResource, F as TelemetryBatchOptions, Fn as BuilderInput, Ft as UserPostsParams, G as PayShopOrderOptions, Gn as Subscription, Gt as parseHtml, H as ViewTrackerOptions, Hn as UpdatePostInput, Ht as PollInput, I as TelemetryClock, In as ItdBuilder, It as CreatePostInput, J as ShopOrderRequestOptions, Jn as UpdateNotificationSettingsInput, Jt as MarkupBuilder, K as ShopConsentsResource, Kn as NotificationListParams, Kt as parseMarkdown, L as TelemetryOptions, Ln as isBuilder, Lt as PostBuilder, M as InteractionEntry, Mn as CommentBuilder, Mt as CommentsParams, N as PhotoOpenInput, Nn as CommentInput, Nt as FeedParams, O as UpdateProfileInput, On as Poll, Ot as ReportsResource, P as TelemetryBatch, Pn as comment, Pt as PostsResource, Q as CreateShopOrderInput, Qn as PaginationMode, Qt as TextMarkup, R as TelemetryResource, Rn as CreateCommentInput, Rt as PostInput, S as VIDEO_MIME_TYPES, Sn as Attachment, Sr as OperationExtensions, St as ShopProductStatus, T as fromUrl, Tn as Hashtag, Tr as PluginTeardown, Tt as ShopSizeChartRow, U as SubscriptionResource, Un as PaymentMethod, Ut as poll, V as ViewTrackerInput, Vn as CreateReportInput, Vt as PollBuilder, W as CreateShopOrderOptions, Wn as Session, Wt as ParseMarkupOptions, X as ShopProductsResource, Xn as Page, Xt as MarkupInput, Y as ShopOrdersResource, Yt as MarkupContent, Z as ShopResource, Zn as PageState, Zt as MarkupSpan, _ as AUDIO_MIME_TYPES, _n as FilesResource, _r as AttemptContext, _t as ShopPayment, a as ShopFeatureOptions, an as ServiceStatus, ar as FeatureContext, at as ShopDeliveryCountry, b as IMAGE_MIME_TYPES, bn as CommentsResource, br as AttemptNext, bt as ShopProductColor, c as ShopOrderAccessStorage, cn as Announcement, cr as FeatureRequestOptions, ct as ShopOrder, d as createShopOrderAccessStorage, dn as Clan, dr as PreparedBufferSource, dt as ShopOrderDelivery, en as markup, er as PaginatorOptions, et as ShopConsentContext, f as statusDays, fn as Portal, fr as PreparedFileSource, ft as ShopOrderItem, g as ALLOWED_MIME_TYPES, gn as HashtagsResource, gt as ShopOrderSupport, h as utcStampToIso, hn as HashtagPostsParams, hr as ResolveFileOptions, ht as ShopOrderSummary, i as ShopFeatureApi, in as PlatformStatus, ir as FeatureBucketDefinition, it as ShopDeliveryCity, j as DwellEntry, jn as PostStats, jt as report, k as UserListParams, kn as PollOption, kt as ReportBuilder, l as ShopOrderAccessStorageAdapterOptions, ln as AnnouncementButton, lr as ManagedClientResource, lt as ShopOrderAccessSession, m as toDate, mn as VerificationStatus, mr as ResolveFileContext, mt as ShopOrderStatus, n as SpanRenderFormat, nn as PlatformResource, nr as RateLimitBucketState, nt as ShopCreatedOrder, o as createShopFeature, on as StatusDay, or as FeatureInstallation, ot as ShopDeliveryDestination, p as isMyProfile, pn as Report, pr as PreparedStreamSource, pt as ShopOrderItemInput, q as ShopDeliveryResource, qn as NotificationsResource, qt as AutoSpansOptions, r as renderSpans, rn as PlatformVersions, rr as ClientFeature, rt as ShopDeliveryCalculation, s as MemoryShopOrderAccessStorage, sn as StatusIncidentLine, sr as FeatureOperationDefinition, st as ShopDeliveryPoint, t as RenderSpansOptions, tn as PlatformClientVersion, tr as mapPage, tt as ShopConsentKind, u as createMemoryShopOrderAccessStorage, un as ChangelogEntry, ur as FileResolver, ut as ShopOrderAccessVerification, v as AllowedMimeType, vn as UploadOptions, vr as AttemptExtensions, vt as ShopProduct, w as fromStream, wn as CommentReplyTo, wr as PluginApi, wt as ShopSizeChart, x as ImageMimeType, xn as RepliesParams, xr as ClientPlugin, xt as ShopProductSpec, y as AudioMimeType, yn as UploadedFile, yr as AttemptInterceptor, yt as ShopProductCategory, z as VideoProgressInput, zn as CreatePollInput, zt as PostUpdateInput } from "../shared/render-DDwy2Ame.cjs";
3
3
  import { a as FileStreamOptions, c as LazyFile, d as UrlFileOptions, i as FileStreamContent, l as StreamFile, n as FileContext, o as FileTransferMode, r as FileInput, s as FromStreamOptions, t as FileContent, u as UrlFile } from "../shared/contracts-BoT7msmq.cjs";
4
4
  //#region src/rest/client.d.ts
5
5
  /** Опции конструктора {@link ItdRestClient}. */
@@ -45,6 +45,8 @@ declare class ItdRestClient {
45
45
  get hashtags(): HashtagsResource;
46
46
  /** Глобальный поиск по пользователям и хэштегам. */
47
47
  get search(): SearchResource;
48
+ /** Каталог, доставка и заказы магазина ИТД. */
49
+ get shop(): ShopResource;
48
50
  /** Жалобы на контент и пользователей. */
49
51
  get reports(): ReportsResource;
50
52
  /** Верификация профиля. */
@@ -73,13 +75,13 @@ declare class ItdRestClient {
73
75
  * Пустой массив при `rateLimit: false`.
74
76
  */
75
77
  rateLimitState(): RateLimitBucketState[];
76
- /** Устанавливает REST feature поверх общего request pipeline клиента. */
78
+ /** Устанавливает REST-модуль с общей обработкой запросов клиента. */
77
79
  install<TApi>(feature: ClientFeature<TApi>): TApi;
78
- /** Устанавливает REST feature и публикует его API как readonly-свойство клиента. */
80
+ /** Устанавливает REST-модуль и добавляет его API в свойство только для чтения. */
79
81
  withFeature<const K extends string, TApi>(key: K, feature: ClientFeature<TApi>): this & { readonly [P in K]: TApi; };
80
- /** Имена установленных feature в порядке установки. */
82
+ /** Имена установленных модулей в порядке установки. */
81
83
  featureNames(): string[];
82
- /** Установлен ли feature с таким именем. */
84
+ /** Установлен ли модуль с таким именем. */
83
85
  hasFeature(name: string): boolean;
84
86
  /**
85
87
  * Подключает плагин.
@@ -142,5 +144,5 @@ declare class ItdRestClient {
142
144
  */
143
145
  declare function createRestClient(options?: RestClientOptions): ItdRestClient;
144
146
  //#endregion
145
- export { ALLOWED_MIME_TYPES, AUDIO_MIME_TYPES, AccessType, type Actor, type AllowedMimeType, type Announcement, type AnnouncementButton, type Attachment, AttachmentType, type AttemptContext, type AttemptExtensions, type AttemptInterceptor, type AttemptNext, type AudioMimeType, type AuthProvider, type Author, type AutoSpansOptions, BUCKET_LIMITS, type BuilderInput, type BuiltInOperationId, type ChangelogEntry, type Clan, type ClientFeature, type ClientHooks, type ClientPlugin, type Comment, type CommentBuilder, type CommentInput, type CommentReplyTo, CommentSort, type CommentsParams, type CommentsResource, type CreateCommentInput, type CreatePollInput, type CreatePostData, type CreatePostInput, type CreateReportInput, type CustomOperationId, DEFAULT_BASE_URL, DEFAULT_RATE_LIMIT_BUCKET, type DwellEntry, type ErrorContextHook, type FeatureBucketDefinition, type FeatureContext, type FeatureInstallation, type FeatureOperationDefinition, type FeatureOperationId, type FeatureRequestOptions, type FeedParams, FeedTab, type FileContent, type FileContext, type FileInput, type FileStreamContent, type FileStreamOptions, FileTransferMode, type FilesResource, type FollowResult, type FromStreamOptions, type Hashtag, type HashtagPostsParams, type HashtagsResource, IMAGE_MIME_TYPES, type ImageMimeType, IncidentKind, type InteractionEntry, InteractionType, type IsoDate, ItdAbortError, ItdApiError, type ItdApiErrorInit, ItdApiErrorKind, ItdAuthError, type ItdBuilder, type ItdClock, ItdConfigError, ItdConflictError, ItdError, ItdErrorCode, ItdErrorKind, type ItdFieldErrors, ItdFileError, ItdFileErrorReason, ItdForbiddenError, ItdNetworkError, ItdNotFoundError, ItdPhoneVerificationError, ItdRateLimitError, ItdRestClient, ItdServerError, ItdStateError, ItdTimeoutError, ItdValidationError, LIBRARY_VERSION, type LazyFile, type LikeResult, LikesVisibility, type Listener, type Logger, type Loose, type MarkupBuilder, type MarkupContent, type MarkupInput, type MarkupSpan, type MyProfile, type Notification, type NotificationEvent, type NotificationListParams, type NotificationSettings, NotificationType, type NotificationsResource, OPERATIONS, type ItdOperationDefinition as OperationDefinition, type OperationExtensions, type OperationId, type OperationMethod, type OperationRequestOptions, type OperationTransformer, type Page, type PageState, PaginationMode, type PaginationOptions, Paginator, type PaginatorOptions, type ParseMarkupOptions, type PaymentMethod, type PhotoOpenInput, type Pin, type PinPostResult, type PinsResult, type PlatformClientVersion, type PlatformResource, type PlatformStatus, type PlatformVersions, type PluginApi, type PluginTeardown, type Poll, type PollBuilder, type PollInput, type PollOption, type Portal, type Post, type PostBuilder, type PostInput, type PostStats, type PostUpdateInput, type PostsResource, type PrivacySettings, type Profile, type PublicProfile, type QueryParams, type QueryValue, type RateLimitBucket, type RateLimitBucketContext, type RateLimitBucketOverride, type RateLimitBucketState, type RateLimitOptions, RateLimitPacing, type RawRequestOptions, type RenderSpansOptions, type RepliesParams, type Report, type ReportBuilder, type ReportInput, ReportReason, ReportTargetType, type ReportsResource, type RequestContext, type RequestExtensions, type RequestOptions, type ResponseContext, type RestClientOptions, type RetryContext, type RetryDecisionContext, type RetryOptions, RetrySafety, RuntimeMode, type RuntimeOptions, STATUS_SERVICE, type SearchResource, type SearchResult, type ServiceDefinition, ServiceState, type ServiceStatus, type Session, type Span, SpanRenderFormat, SpanType, type StatusDay, type StatusIncidentLine, type StreamFile, type Subscription, type SubscriptionResource, type SubscriptionState, type TelemetryBatch, type TelemetryBatchOptions, type TelemetryClock, type TelemetryOptions, type TelemetryResource, type TextMarkup, type Unsubscribe, type UpdateNotificationSettingsInput, type UpdatePostInput, type UpdatePrivacyInput, type UpdateProfileInput, type UploadOptions, type UploadedFile, type UrlFile, type UrlFileOptions, type UserId, type UserListParams, type UserPostsParams, type UserRef, type UserSummary, type UsersResource, VIDEO_MIME_TYPES, type VerificationResource, type VerificationStatus, type VideoMimeType, type VideoProgressInput, ViewReason, ViewSource, type ViewTracker, type ViewTrackerInput, type ViewTrackerOptions, WallAccess, anonymousAuth, autoSpans, bearerToken, canonicalNotificationType, comment, createRestClient, formatNotificationText, fromStream, fromUrl, isBuilder, isBuiltInOperationId, isItdApiError, isItdAuthError, isItdConflictError, isItdError, isItdFileError, isItdForbiddenError, isItdNotFoundError, isItdPhoneVerificationError, isItdRateLimitError, isItdServerError, isItdStateError, isItdValidationError, isKnownNotificationType, isMyProfile, mapPage, markup, normalizeNotification, operationBucket, operationMethod, operationRetrySafety, parseHtml, parseMarkdown, poll, post, renderSpans, report, resolveNotificationUrl, statusDays, systemClock, toDate, tokenProvider, utcStampToIso };
147
+ export { ALLOWED_MIME_TYPES, AUDIO_MIME_TYPES, AccessType, type Actor, type AllowedMimeType, type Announcement, type AnnouncementButton, type Attachment, AttachmentType, type AttemptContext, type AttemptExtensions, type AttemptInterceptor, type AttemptNext, type AudioMimeType, type AuthProvider, type Author, type AutoSpansOptions, BUCKET_LIMITS, type BuilderInput, type BuiltInOperationId, type ChangelogEntry, type Clan, type ClientConnection, type ClientFeature, type ClientHooks, type ClientPlugin, type Comment, type CommentBuilder, type CommentInput, type CommentReplyTo, CommentSort, type CommentsParams, type CommentsResource, type CreateCommentInput, type CreatePollInput, type CreatePostData, type CreatePostInput, type CreateReportInput, type CreateShopOrderInput, type CreateShopOrderOptions, type CustomOperationId, DEFAULT_BASE_URL, DEFAULT_RATE_LIMIT_BUCKET, type DwellEntry, type ErrorContextHook, type FeatureBucketDefinition, type FeatureContext, type FeatureInstallation, type FeatureOperationDefinition, type FeatureOperationId, type FeatureRequestOptions, type FeedParams, FeedTab, type FileContent, type FileContext, type FileInput, type FileResolver, type FileStreamContent, type FileStreamOptions, FileTransferMode, type FilesResource, type FollowResult, type FromStreamOptions, type Hashtag, type HashtagPostsParams, type HashtagsResource, IMAGE_MIME_TYPES, type ImageMimeType, IncidentKind, type InteractionEntry, InteractionType, type IsoDate, ItdAbortError, ItdApiError, type ItdApiErrorInit, ItdApiErrorKind, ItdAuthError, type ItdBuilder, type ItdClock, ItdConfigError, ItdConflictError, ItdError, ItdErrorCode, ItdErrorKind, type ItdFieldErrors, ItdFileError, ItdFileErrorReason, ItdForbiddenError, ItdNetworkError, ItdNotFoundError, ItdPhoneVerificationError, ItdRateLimitError, ItdRestClient, ItdServerError, ItdStateError, ItdTimeoutError, ItdValidationError, LIBRARY_VERSION, type LazyFile, type LikeResult, LikesVisibility, type Listener, type Logger, type Loose, type ManagedClientResource, type MarkupBuilder, type MarkupContent, type MarkupInput, type MarkupSpan, MemoryShopOrderAccessStorage, type MyProfile, type Notification, type NotificationEvent, type NotificationListParams, type NotificationSettings, NotificationType, type NotificationsResource, OPERATIONS, type OperationAnnotations, type ItdOperationDefinition as OperationDefinition, type OperationExtensions, type OperationId, type OperationMetadata, type OperationMethod, type OperationRequestOptions, type OperationTransformer, type Page, type PageState, PaginationMode, type PaginationOptions, Paginator, type PaginatorOptions, type ParseMarkupOptions, type PayShopOrderOptions, type PaymentMethod, type PhotoOpenInput, type Pin, type PinPostResult, type PinsResult, type PlatformClientVersion, type PlatformResource, type PlatformStatus, type PlatformVersions, type PluginApi, type PluginTeardown, type Poll, type PollBuilder, type PollInput, type PollOption, type Portal, type Post, type PostBuilder, type PostInput, type PostStats, type PostUpdateInput, type PostsResource, type PreparedBufferSource, type PreparedFileSource, type PreparedStreamSource, type PrivacySettings, type Profile, type PublicProfile, type QueryParams, type QueryValue, type RateLimitBucket, type RateLimitBucketContext, type RateLimitBucketOverride, type RateLimitBucketState, type RateLimitOptions, RateLimitPacing, type RawRequestOptions, type RenderSpansOptions, type RepliesParams, type Report, type ReportBuilder, type ReportInput, ReportReason, ReportTargetType, type ReportsResource, type RequestContext, type RequestExtensions, type RequestOptions, type ResolveFileContext, type ResolveFileOptions, type ResponseContext, type RestClientOptions, type RetryContext, type RetryDecisionContext, type RetryOptions, RetrySafety, RuntimeMode, type RuntimeOptions, STATUS_SERVICE, type SearchResource, type SearchResult, type ServiceDefinition, ServiceState, type ServiceStatus, type Session, type ShopConsent, type ShopConsentContext, ShopConsentKind, type ShopConsentsResource, type ShopCreatedOrder, type ShopDeliveryCalculation, type ShopDeliveryCity, type ShopDeliveryCountry, type ShopDeliveryDestination, type ShopDeliveryPoint, type ShopDeliveryResource, type ShopFeatureApi, type ShopFeatureOptions, type ShopOrder, type ShopOrderAccessSession, type ShopOrderAccessStorage, type ShopOrderAccessStorageAdapterOptions, type ShopOrderAccessVerification, type ShopOrderDelivery, type ShopOrderItem, type ShopOrderItemInput, type ShopOrderRequestOptions, ShopOrderStatus, type ShopOrderSummary, type ShopOrderSupport, type ShopOrdersResource, type ShopPayment, type ShopProduct, ShopProductCategory, type ShopProductColor, type ShopProductSpec, ShopProductStatus, type ShopProductsResource, type ShopRecipient, type ShopResource, type ShopSizeChart, type ShopSizeChartRow, type Span, SpanRenderFormat, SpanType, type StatusDay, type StatusIncidentLine, type StreamFile, type Subscription, type SubscriptionResource, type SubscriptionState, type TelemetryBatch, type TelemetryBatchOptions, type TelemetryClock, type TelemetryOptions, type TelemetryResource, type TextMarkup, type Unsubscribe, type UpdateNotificationSettingsInput, type UpdatePostInput, type UpdatePrivacyInput, type UpdateProfileInput, type UploadOptions, type UploadedFile, type UrlFile, type UrlFileOptions, type UserId, type UserListParams, type UserPostsParams, type UserRef, type UserSummary, type UsersResource, VIDEO_MIME_TYPES, type VerificationResource, type VerificationStatus, type VideoMimeType, type VideoProgressInput, ViewReason, ViewSource, type ViewTracker, type ViewTrackerInput, type ViewTrackerOptions, WallAccess, anonymousAuth, autoSpans, bearerToken, canonicalNotificationType, comment, createMemoryShopOrderAccessStorage, createRestClient, createShopFeature, createShopOrderAccessStorage, formatNotificationText, fromStream, fromUrl, isBuilder, isBuiltInOperationId, isItdApiError, isItdAuthError, isItdConflictError, isItdError, isItdFileError, isItdForbiddenError, isItdNotFoundError, isItdPhoneVerificationError, isItdRateLimitError, isItdServerError, isItdStateError, isItdValidationError, isKnownNotificationType, isMyProfile, mapPage, markup, normalizeNotification, operationBucket, operationMethod, operationRetrySafety, parseHtml, parseMarkdown, poll, post, renderSpans, report, resolveNotificationUrl, statusDays, systemClock, toDate, tokenProvider, utcStampToIso };
146
148
  //# sourceMappingURL=index.d.cts.map