{"id":13755003,"url":"https://github.com/vitalets/alice-asset-manager","last_synced_at":"2026-02-08T03:33:52.349Z","repository":{"id":36745564,"uuid":"227985690","full_name":"vitalets/alice-asset-manager","owner":"vitalets","description":"Node.js API для загрузки изображений и звуков в навык Алисы.","archived":false,"fork":false,"pushed_at":"2022-12-30T19:20:26.000Z","size":749,"stargazers_count":3,"open_issues_count":8,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-10-04T11:17:08.194Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/vitalets.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-12-14T07:47:31.000Z","updated_at":"2025-03-29T02:28:52.000Z","dependencies_parsed_at":"2023-01-17T04:29:34.093Z","dependency_job_id":null,"html_url":"https://github.com/vitalets/alice-asset-manager","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/vitalets/alice-asset-manager","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vitalets%2Falice-asset-manager","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vitalets%2Falice-asset-manager/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vitalets%2Falice-asset-manager/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vitalets%2Falice-asset-manager/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/vitalets","download_url":"https://codeload.github.com/vitalets/alice-asset-manager/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vitalets%2Falice-asset-manager/sbom","scorecard":{"id":923900,"data":{"date":"2025-08-11","repo":{"name":"github.com/vitalets/alice-asset-manager","commit":"950216404e5fd300052556c664893d1d8376a69c"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":1.3,"checks":[{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Code-Review","score":0,"reason":"Found 0/30 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"SAST","score":0,"reason":"no SAST tool detected","details":["Warn: no pull requests merged into dev branch"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"License","score":0,"reason":"license file not detected","details":["Warn: project does not have a license file"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Vulnerabilities","score":0,"reason":"32 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GHSA-968p-4wvh-cqc8","Warn: Project is vulnerable to: GHSA-6chw-6frg-f759","Warn: Project is vulnerable to: GHSA-v88g-cgmw-v5xw","Warn: Project is vulnerable to: GHSA-93q8-gq69-wqmw","Warn: Project is vulnerable to: GHSA-v6h2-p8h4-qcjw","Warn: Project is vulnerable to: GHSA-grv7-fg5c-xmjg","Warn: Project is vulnerable to: GHSA-3xgq-45jj-v275","Warn: Project is vulnerable to: GHSA-gxpj-cx7g-858c","Warn: Project is vulnerable to: GHSA-2j2x-2gpw-g8fm","Warn: Project is vulnerable to: GHSA-fjxv-7rqg-78g4","Warn: Project is vulnerable to: GHSA-4q6p-r6v2-jvc5","Warn: Project is vulnerable to: GHSA-ww39-953v-wcq6","Warn: Project is vulnerable to: GHSA-6c8f-qphg-qjgp","Warn: Project is vulnerable to: GHSA-p6mc-m468-83gw","Warn: Project is vulnerable to: GHSA-29mw-wpgm-hmr9","Warn: Project is vulnerable to: GHSA-35jh-r3h4-6jhm","Warn: Project is vulnerable to: GHSA-952p-6rrq-rcjv","Warn: Project is vulnerable to: GHSA-f8q6-p94x-37v3","Warn: Project is vulnerable to: GHSA-vh95-rmgr-6w4m","Warn: Project is vulnerable to: GHSA-xvch-5gv4-984h","Warn: Project is vulnerable to: GHSA-w7rc-rwvf-8q5r","Warn: Project is vulnerable to: GHSA-r683-j2x4-v87g","Warn: Project is vulnerable to: GHSA-9wv6-86v2-598j","Warn: Project is vulnerable to: GHSA-g6ww-v8xp-vmwg","Warn: Project is vulnerable to: GHSA-c2qf-rxjj-qqgw","Warn: Project is vulnerable to: GHSA-44c6-4v22-4mhx","Warn: Project is vulnerable to: GHSA-4x5v-gmq8-25ch","Warn: Project is vulnerable to: GHSA-jv35-xqg7-f92r","Warn: Project is vulnerable to: GHSA-52f5-9888-hmc6","Warn: Project is vulnerable to: GHSA-j8xg-fqg3-53r7","Warn: Project is vulnerable to: GHSA-c4w7-xm78-47vh","Warn: Project is vulnerable to: GHSA-p9pc-299p-vxgp"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-25T08:44:52.790Z","repository_id":36745564,"created_at":"2025-08-25T08:44:52.790Z","updated_at":"2025-08-25T08:44:52.790Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29219274,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-08T03:18:47.732Z","status":"ssl_error","status_checked_at":"2026-02-08T03:15:31.985Z","response_time":57,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-03T10:00:38.958Z","updated_at":"2026-02-08T03:33:52.332Z","avatar_url":"https://github.com/vitalets.png","language":"JavaScript","funding_links":[],"categories":["Прочее"],"sub_categories":["Open-source навыки"],"readme":"# alice-asset-manager\n\n[![npm](https://img.shields.io/npm/v/alice-asset-manager.svg)](https://www.npmjs.com/package/alice-asset-manager)\n[![license](https://img.shields.io/npm/l/alice-asset-manager.svg)](https://www.npmjs.com/package/alice-asset-manager)\n\nNode.js API для загрузки изображений и звуков в навык Алисы.\n\nПозволяет:\n* загружать/удалять изображения и звуки\n* в режиме синхронизации загружать только измененные файлы и удалять неиспользуемые файлы с сервера\n* просматривать загруженные изображения/звуки на реальном устройстве через встроенный навык\n\n## Содержание\n\n\u003c!-- toc --\u003e\n\n- [Установка](#%D1%83%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0)\n- [Изображения](#%D0%B8%D0%B7%D0%BE%D0%B1%D1%80%D0%B0%D0%B6%D0%B5%D0%BD%D0%B8%D1%8F)\n  * [new ImageManager()](#new-imagemanager)\n  * [.getQuota()](#getquota)\n  * [.upload()](#upload)\n  * [.getItems()](#getitems)\n  * [.getItem()](#getitem)\n  * [.getUrl()](#geturl)\n  * [.delete()](#delete)\n  * [.uploadChanged()](#uploadchanged)\n  * [.deleteUnused()](#deleteunused)\n  * [.createViewServer()](#createviewserver)\n- [Звуки](#%D0%B7%D0%B2%D1%83%D0%BA%D0%B8)\n  * [new SoundManager()](#new-soundmanager)\n  * [.getQuota()](#getquota-1)\n  * [.upload()](#upload-1)\n  * [.getItems()](#getitems-1)\n  * [.getItem()](#getitem-1)\n  * [.getUrl()](#geturl-1)\n  * [.getTts()](#gettts)\n  * [.delete()](#delete-1)\n  * [.uploadChanged()](#uploadchanged-1)\n  * [.deleteUnused()](#deleteunused-1)\n  * [.createViewServer()](#createviewserver-1)\n- [Лицензия](#%D0%BB%D0%B8%D1%86%D0%B5%D0%BD%D0%B7%D0%B8%D1%8F)\n\n\u003c!-- tocstop --\u003e\n\n## Установка\n```bash\nnpm i alice-asset-manager --save-dev\n```\n\n## Изображения\n\n### new ImageManager()\nСоздает инстанс менеджера изображений.\n\nПараметры:\n```js\n  /**\n   * @param {string} token OAuth-токен\n   * @param {string} skillId идентификатор навыка\n   */\n```\nКак получить `token` и `skillId` - описано в [документации](https://yandex.ru/dev/dialogs/alice/doc/resource-upload-docpage/#http-load).\n\nПример:\n```js\nconst { ImageManager } = require('alice-asset-manager');\n\nconst imageManager = new ImageManager({\n  token: 'TOKEN',\n  skillId: 'SKILL_ID',\n});\n```\n\n### .getQuota()\nПолучить данные о занятом месте.\n```js\nawait imageManager.getQuota();\n/*\n{\n  total: 104857600,\n  used: 379850\n}\n*/\n```\n\n### .upload()\nЗагрузить изображение из файла.\n\nПараметры:\n```js\n  /**\n   * @param {string} filePath путь до файла\n   * @returns {Promise}\n   */\n```\n\nПример:\n```js\nawait imageManager.upload('images/test.jpg');\n/*\n{\n  id: '213044/aef2a365f198b4435611',\n  size: 8596,\n  createdAt: '2019-12-09T06:05:35.035Z',\n  url: 'https://avatars.mds.yandex.net/get-dialogs-skill-card/213044/aef2a365f198b4435611/orig'\n}\n*/\n```\n\n### .getItems()\nПолучить список всех изображений на сервере.\n```js\nawait imageManager.getItems();\n/*\n[\n  {\n    id: '213044/aef2a365f198b4435611',\n    origUrl: null,\n    size: 8596,\n    createdAt: '2019-12-09T06:05:35.035Z',\n    url: 'https://avatars.mds.yandex.net/get-dialogs-skill-card/213044/aef2a365f198b4435611/orig'\n  }\n  ...\n]\n*/\n```\n\n### .getItem()\nПолучить данные об отдельном изображении.\n\nПараметры:\n```js\n  /**\n   * @param {string} imageId\n   * @returns {Promise}\n   */\n```\n\nПример:\n```js\nawait imageManager.getItem('213044/aef2a365f198b4435611');\n/*\n{\n  id: '213044/aef2a365f198b4435611',\n  origUrl: null,\n  size: 8596,\n  createdAt: '2019-12-09T06:05:35.035Z',\n  url: 'https://avatars.mds.yandex.net/get-dialogs-skill-card/213044/aef2a365f198b4435611/orig'\n}\n*/\n```\n\n### .getUrl()\nПолучить ссылку на изображение.\n\nПараметры:\n```js\n  /**\n   * @param {string} imageId\n   * @returns {string}\n   */\n```\n\nПример:\n```js\nimageManager.getUrl('213044/aef2a365f198b4435611');\n/*\n'https://avatars.mds.yandex.net/get-dialogs-skill-card/213044/aef2a365f198b4435611/orig'\n*/\n```\n\n### .delete()\nУдалить изображение с сервера.\n\nПараметры:\n```js\n  /**\n   * @param {string} imageId\n   * @returns {Promise}\n   */\n```\n\nПример:\n```js\nawait imageManager.delete('213044/aef2a365f198b4435611');\n```\n\n### .uploadChanged()\nЗагрузить новые и измененные изображения на сервер.\n\nПараметры:\n```js\n  /**\n   * @param {string} pattern путь/паттерн до папки с изображениями\n   * @param {string} dbFile путь до файла с данными о загрузках\n   * @param {function} [getLocalId] функция вычисления localId по имени файла\n   * @param {function} [transform] функция обработки файлов (buffer, filepath) =\u003e buffer\n   * @param {boolean} [dryRun=false] запуск без фактической загрузки файлов\n   * @returns {Promise}\n   */\n```\n\n**Как это работает:**\n\nПри каждом вызове `uploadChanged()` сохраняет результаты загрузки во вспомогательный файл\nи при последующих вызовах использует сохраненную информацию, чтобы определить файлы для загрузки.\n\nЧтобы избежать повторной загрузки файла при переименовании,\nдля каждого файла вычисляется `localId` - уникальный идентификатор,\nкоторый должен сохраняться при переименовании.\nПо умолчанию `localId` ищется в квадратных скобках `[]` в имени файла:\n```\nimage[foo].png -\u003e foo\n```\n\n**Пример:**\n\nВ папке `images` лежат два изображения `my_image_1[alice].png` и `my_image_2[bob].png`.\n\nИх `localId` следующие:\n```\nmy_image_1[alice].png -\u003e alice\nmy_image_2[bob].png -\u003e bob\n```\n\nЗапускаем первую зарузку - на сервер загрузятся оба файла:\n```js\nawait imageManager.uploadChanged({\n  pattern: 'images/*.png', // путь/паттерн до папки с изображениями\n  dbFile: 'images.json',   // путь до файла с данными о загрузках (изначально файла нет)\n});\n/*\nuploaded: 'images/my_image_1[alice].png', 'images/my_image_2[bob].png'\nskipped: 0\n*/\n```\n\nВ `images.json` запишется примерно следующее:\n```json\n{\n  \"ids\": {\n    \"alice\": \"213044/aef2a365f198b4435611\",\n    \"bob\": \"834732/sdg3s44fjh234524j2h4\"\n  },\n  \"meta\": {\n    \"alice\": {\n      \"file\": \"images/my_image_1[alice].png\",\n      \"url\": \"https://avatars.mds.yandex.net/get-dialogs-skill-card/213044/aef2a365f198b4435611/orig\",\n      \"mtimeMs\": 1576249136829.0754\n    },\n    \"bob\": {\n      \"file\": \"images/my_image_2[bob].png\",\n      \"url\": \"https://avatars.mds.yandex.net/get-dialogs-skill-card/834732/sdg3s44fjh234524j2h4/orig\",\n      \"mtimeMs\": 1576249136830.0842\n    }\n  }\n}\n```\n\nФайл `images.json` удобно использовать в коде вашего навыка, вставляя изображения по их `localId`.\nГлавный плюс в том, что при изменении изображения и получении нового `image_id` на сервере,\nв коде навыка ничего менять не нужно - новый `image_id` подтянется по `localId` автоматически:\n```js\nconst images = require('./images.json').ids;\n// ...\nresponse.card.image_id = images.alice;\n```\n\nЕсли повторно вызвать `uploadChanged()` ничего не меняя, то загрузок не произойдет,\nт.к. файлы не изменились и уже загружены на сервер:\n```js\nawait imageManager.uploadChanged({\n  pattern: 'images/*.png',\n  dbFile: 'images.json',\n});\n/*\nuploaded: 0\nskipped: 'images/my_image_1[alice].png', 'images/my_image_2[bob].png'\n*/\n```\n\nЕсли изменить в фоторедакторе один из файлов (например `my_image_1[alice].png`),\nто при вызове `uploadChanged()` загрузится только этот измененный файл:\n```js\nawait imageManager.uploadChanged({\n  pattern: 'images/*.png',\n  dbFile: 'images.json',\n});\n/*\nuploaded: 'images/my_image_1[alice].png'\nskipped: 'images/my_image_2[bob].png'\n*/\n```\nИнформация в `images.json` также обновится - туда запишется новый `image_id` для `my_image_1[alice].png`.\nИспользование в коде навыка останется прежним:\n```js\nconst images = require('./images.json').ids;\n// ...\nresponse.card.image_id = images.alice;\n```\n\nДля обработки загружаемых файлов (например изменения размеров изображений) можно использовать параметр `transform`.\nВот готовый пример кода для подгона изображений под размер `776х344` с использованием библиотеки [Jimp](https://github.com/oliver-moran/jimp):\n```js\nawait imageManager.uploadChanged({\n  pattern: 'images/*.png',\n  dbFile: 'images.json',\n  transform: async buffer =\u003e {\n    const image = await Jimp.read(buffer);\n    return image\n       .normalize()\n       .background(0xFFFFFFFF)\n       .contain(776, 344)\n       .quality(75)\n       .getBufferAsync(Jimp.AUTO);\n  }\n});\n```\n\n### .deleteUnused()\nУдалить неиспользуемые изображения с сервера.\n\nПараметры:\n```js\n  /**\n   * @param {string} dbFile путь до файла с данными о загрузках, созданный методом uploadChanged()\n   * @param {boolean} [dryRun=false] запуск без фактического удаления изображений\n   * @returns {Promise}\n   */\n```\n\nРаботает только в связке с `.uploadChanged()`.\nПри частых изменениях файлов и многократных вызовах `.uploadChanged()`\nна сервере накапливаются неиспользуемые изображения.\nИх нужно периодически удалять, чтобы освободить место.\nМетод `.deleteUnused()` сравнивает то, что записано в `dbFile` с тем что лежит на сервере, и удаляет с сервера лишнее.\n\n**Пример:**\n\nВ навыке используются два изображения `my_image_1[alice].png` и `my_image_2[bob].png`.\nОни были загружены на сервер через `.uploadChanged()` и информация сохранена в `dbFile: 'images.json'`.\n\nВ новой версии навыка файл `my_image_1[alice].png` не используется и был удален.\nПосле вызова `.uploadChanged()` в `images.json` останется только запись про второй файл `images/my_image_2[bob].png`:\n```json\n{\n  \"ids\": {\n    \"bob\": \"834732/sdg3s44fjh234524j2h4\"\n  },\n  \"meta\": {\n    \"bob\": {\n      \"file\": \"images/my_image_2[bob].png\",\n      \"url\": \"https://avatars.mds.yandex.net/get-dialogs-skill-card/834732/sdg3s44fjh234524j2h4/orig\",\n      \"mtimeMs\": 1576249136830.0842\n    }\n  }\n}\n```\nНо на сервере все еще лежат два файла.\nЭто нужно для того, чтобы текущая версия навыка продолжала нормально работать.\nКогда новая версия навыка выкатится, запись про `my_image_1[alice].png` можно удалить с сервера:\n```js\nawait imageManager.deleteUnused({\n  dbFile: 'images.json',\n});\n/*\n{\n  deleted: [ '213044/aef2a365f198b4435611' ],\n  used: [ 'images/my_image_2[bob].png' ]\n}\n*/\n```\nЧтобы предварительно посмотреть, какие изображения будут удалены с сервера - можно вызвать метод\nс параметром `dryRun: true`:\n```js\nawait imageManager.deleteUnused({\n  dbFile: 'images.json',\n  dryRun: true\n});\n/*\n{\n  deleted: [ '213044/aef2a365f198b4435611' ],\n  used: [ 'images/my_image_2[bob].png' ]\n}\n*/\n```\n### .createViewServer()\nСоздает HTTP-сервер для просмотра загруженных изображений через навык.\n\nПараметры:\n```js\n  /**\n   * @param {string} [dbFile] путь до файла с данными о загрузках, созданный методом uploadChanged()\n   */\n```\n\nСоздаваемый HTTP-сервер позволяет быстро посмотреть загруженные изображения на экране смартфона.\n\nПример:\n```js\nconst server = imageManager.createViewServer();\nserver.listen(3000);\n```\nКогда сервер запустился на `3000` порту, можно используя любой прокси-навык\n(например [alice-dev.vitalets.xyz](https://alice-dev.vitalets.xyz/)) проверить все изображения на смартфоне.\nИзображения в навыке отсортированы по дате загрузки, поэтому в первую очередь будут показаны недавно измененные файлы.\n\nЧтобы рядом с изображениями дополнительно выводилось имя файла и localId, нужно указать в параметрах `dbFile`:\n```js\nconst server = imageManager.createViewServer({\n  dbFile: 'images.json'\n});\nserver.listen(3000);\n```\nЧтобы сервер автоматически перезапускался при изменениях `images.json`\nможно использовать [nodemon](https://github.com/remy/nodemon):\n```bash\nnodemon ./image-server.js --watch ./images.json\n```\n\n## Звуки\n\n### new SoundManager()\nСоздает инстанс менеджера звуков.\n\nПараметры:\n```js\n  /**\n   * @param {string} token OAuth-токен\n   * @param {string} skillId идентификатор навыка\n   */\n```\nКак получить `token` и `skillId` - описано в [документации](https://yandex.ru/dev/dialogs/alice/doc/resource-sounds-upload-docpage/#http-load).\n\nПример:\n```js\nconst { SoundManager } = require('alice-asset-manager');\n\nconst soundManager = new SoundManager({\n  token: 'TOKEN',\n  skillId: 'SKILL_ID',\n});\n```\n\n### .getQuota()\nПолучить данные о занятом месте.\n```js\nawait soundManager.getQuota();\n/*\n{\n  total: 104857600,\n  used: 379850\n}\n*/\n```\n\n### .upload()\nЗагрузить звук из файла.\n\nПараметры:\n```js\n  /**\n   * @param {string} filePath путь до файла\n   * @returns {Promise}\n   */\n```\n\nПример:\n```js\nawait soundManager.upload('images/test.mp3');\n/*\n{\n  id: 'c72463ae-01b5-48a1-a7f2-e657e4594166',\n  skillId: 'SKILL_ID',\n  size: null,\n  originalName: 'test.mp3',\n  createdAt: '2019-12-09T06:13:49.595Z',\n  isProcessed: false,\n  error: null,\n  url: 'https://yastatic.net/s3/dialogs/dialogs-upload/sounds/opus/SKILL_ID/c72463ae-01b5-48a1-a7f2-e657e4594166.opus'\n}\n*/\n```\n\n### .getItems()\nПолучить список всех звуков на сервере.\n```js\nawait soundManager.getItems();\n/*\n[\n  {\n    id: 'c72463ae-01b5-48a1-a7f2-e657e4594166',\n    skillId: 'SKILL_ID',\n    size: 24915,\n    originalName: 'test.mp3',\n    createdAt: '2019-12-09T06:19:48.317Z',\n    isProcessed: true,\n    error: null,\n    url: 'https://yastatic.net/s3/dialogs/dialogs-upload/sounds/opus/SKILL_ID/c72463ae-01b5-48a1-a7f2-e657e4594166.opus'\n  }\n  ...\n]\n*/\n```\n\n### .getItem()\nПолучить данные об отдельном звуке на сервере.\n\nПараметры:\n```js\n  /**\n   * @param {string} soundId\n   * @returns {Promise}\n   */\n```\n\nПример:\n```js\nawait soundManager.getItem('c72463ae-01b5-48a1-a7f2-e657e4594166');\n/*\n{\n  id: 'c72463ae-01b5-48a1-a7f2-e657e4594166',\n  skillId: 'SKILL_ID',\n  size: 24915,\n  originalName: 'test.mp3',\n  createdAt: '2019-12-09T06:19:48.317Z',\n  isProcessed: true,\n  error: null,\n  url: 'https://yastatic.net/s3/dialogs/dialogs-upload/sounds/opus/SKILL_ID/c72463ae-01b5-48a1-a7f2-e657e4594166.opus'\n}\n*/\n```\n\n### .getUrl()\nПолучить ссылку на звук.\n\nПараметры:\n```js\n  /**\n   * @param {string} soundId\n   * @returns {string}\n   */\n```\n\nПример:\n```js\nsoundManager.getUrl('c72463ae-01b5-48a1-a7f2-e657e4594166');\n/*\n'https://yastatic.net/s3/dialogs/dialogs-upload/sounds/opus/SKILL_ID/c72463ae-01b5-48a1-a7f2-e657e4594166.opus'\n*/\n```\n\n### .getTts()\nПолучить tts для вставки звука в ответ навыка.\n\nПараметры:\n```js\n  /**\n   * @param {string} soundId\n   * @returns {string}\n   */\n```\n\nПример:\n```js\nsoundManager.getTts('c72463ae-01b5-48a1-a7f2-e657e4594166');\n/*\n'\u003cspeaker audio=\"dialogs-upload/SKILL_ID/c72463ae-01b5-48a1-a7f2-e657e4594166.opus\"\u003e'\n*/\n```\n\n### .delete()\nУдалить звук с сервера.\n\nПараметры:\n```js\n  /**\n   * @param {string} soundId\n   * @returns {Promise}\n   */\n```\n\nПример:\n```js\nawait soundManager.delete('213044/aef2a365f198b4435611');\n```\n\n### .uploadChanged()\nЗагрузить новые и измененные звуки на сервер.\n\nПараметры:\n```js\n  /**\n   * @param {string} pattern путь/паттерн до папки со звуками\n   * @param {string} dbFile путь до файла с данными о загрузках\n   * @param {function} [getLocalId] функция вычисления localId по имени файла\n   * @param {boolean} [dryRun=false] запуск без зфактической загрузки файлов\n   * @returns {Promise}\n   */\n```\nВсе работает аналогично методу [.uploadChanged()](#uploadchanged) для изображений.\n\n### .deleteUnused()\nУдалить неиспользуемые звуки с сервера.\n\nПараметры:\n```js\n  /**\n   * @param {string} dbFile путь до файла с данными о загрузках, созданный методом uploadChanged()\n   * @param {boolean} [dryRun=false] запуск без фактического удаления звуков\n   * @returns {Promise}\n   */\n```\nВсе работает аналогично методу [.deleteUnused()](#deleteunused) для изображений.\n\n### .createViewServer()\nСоздает HTTP-сервер для прослушивания загруженных звуков через навык.\n\nПараметры:\n```js\n  /**\n   * @param {string} [dbFile] путь до файла с данными о загрузках, созданный методом uploadChanged()\n   */\n```\nВсе работает аналогично методу [.createViewServer()](#createviewserver) для изображений.\n\n\n## Лицензия\nMIT @ [Vitaliy Potapov](https://github.com/vitalets)\n\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvitalets%2Falice-asset-manager","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvitalets%2Falice-asset-manager","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvitalets%2Falice-asset-manager/lists"}