npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@denisnp/vkui-connect-helper

v0.1.9

Published

Promise-based vkui-connect mock with advanced functionality

Downloads

65

Readme

vkui-connect-helper

npm version

Описание

Библиотека-обёртка вокруг vk-bridge, которая при недоступности модуля VK Bridge будет выполнять все те же самые вызовы иными способами.

Таким образом, разработчик практически на живых данных без необходимости создавать объекты-пустышки получает возможность отладки прямо в окне браузера за пределами сайта VK.

  1. Не отвлекают уведомления и интерфейс сайта
  2. Возможность использовать hot reload
  3. Возможность использовать имитацию мобильного интерфейса в Chrome DevTools
  4. Нет лишних вызовов в Network, относящихся к ВКонтакте, а не к вашему приложению
  5. Возможность использовать расширения для разработки, такие как Vue DevTools и React DevTools

Установка и подключение

npm install --save @denisnp/vkui-connect-helper
import VKC from '@denisnp/vkui-connect-helper';

Инициализация

VKC.init(options); // эта функция автоматически вызывает VKWebAppInit

options

Поле | Тип | Описание | Обязательное ли | По-умолачнию -- | -- | -- | -- | -- appId | string или int | Идентификатор приложения VK Apps. Сюда не нужно вводить id Standalone-приложения, в котором вы получили токен. | да | 0 accessToken | string | Токен разработчика для вызова методов, полученный с помощью Standalone API, см. ниже подробнее. | да для работы в браузере с GetUserInfo и CallAPIMethod | empty string communityToken | string | Токен сообщества для работы соответствующих событий | нет | empty string mode | MODE_PROD, MODE_AUTO, MODE_DEV | Режим работы библиотеки, смотрите ниже в примере инициализации. | нет | MODE_AUTO apiVersion | string | Версия API ВКонтакте для передачи в вызовы методов. | нет | 5.120 enableLog | boolean | Вести ли лог вызовов к VKConnect в консоли. | нет | true corsAddress | string | Адрес сервера для обхода CORS к api.vk.com, см. ниже подробнее. | нет | https://cors-anywhere.herokuapp.com/ asyncStyle | boolean | Использовать ли специальный синтаксис для получения ошибок в режиме async/await, см. подробнее ниже. | нет | false defaultScope | string | scope который будет передаваться в VK API для автоматический авторизации, если вы хотите сразу вызывать методы API без предварительной отправки события VKWebAppGetAuthToken | empty string disableAutoTheme | boolean | Если true, то будет выключен автоматический перехват события VKWebAppUpdateConfig для установки альтернативной темы (при использовании VKUI) | нет | true

Пример инициализации

Режим | Описание --- | --- MODE_DEV | Режим, в котором библиотека будет считать, что модуля VKUIConnect нет, все запросы пойдут напрямую через API, а неподдерживаемые события не будут работать. Для реализации каких-то событий кроме списка поддерживаемых вы можете использовать фунцию VKC.define, см ниже подробнее. MODE_PROD | Режим, в котором библиотека будет все события пытаться отправлять через VKUIConnect. Если он не подключен, программа перестанет выполняться в этом месте (промис от VKUIConnect не вызовет ни успех, ни ошибку). Собственно, это поведение и вдохновило меня на написание vkui-connect-helper. MODE_AUTO | Настройка по-умолчанию, программа сама определит, в каком режиме работать по наличию переданного accessToken, поэтому важно передавать его только из переменных окружения на комьпютере разработчика и не держать в коде клиента.

import VKC, { MODE_PROD, MODE_AUTO } from '@denisnp/vkui-connect-helper';

VKC.init({
  appId: 123456,
  accessToken: process.env.REACT_APP_VK_TOKEN, // инструкция по получению такого ключа ниже
  corsAddress: 'https://my-own-server.ru/cors/', // https://github.com/marcus2vinicius/cors-anywhere
  asyncStyle: true, // см ниже
}); 

Работа с библиотекой

Promise-режим

Библиотека почти повторяет интерфейс vkui-connect. То есть в обычном режиме можно вызвать в любом месте функцию VKC.send(event, params) или VKC.sendPromise(event, params) (в библиотеке эти функции эквивалентны) и получить в ответ Promise. Например:

VKC.send('VKWebAppGetUserInfo', {})
  .then((userData) => {
    // делаем что нужно с данными пользователя
    // userData = { first_name: ..., last_name: ..., ... }
  })
  .catch((error) => {
    // произошла ошибка при вызове события
    // error = { ...some error data... }
  });

Async-режим

Мы всегда можем использовать синтаксис async/await для получения результата, но в такой ситуации для поимки ошибки нам придётся оборачивать код в try/catch. Чтобы избежать этого, в функцию VKC.init() можно передать параметр asyncMode: true. Тогда результат работы методов будет такой:

VKC.init({
  ...
  asyncStyle: true,
}); 

// some async block
const [data, error] = await VKC.send('VKWebAppCallAPIMethod', { method: 'friends.get' });

if (data) {
  // в объекте data всегда успешный ответ от метода
  // при этом error = null
} else {
  // если data = null, значит произошла ошибка, можно её вывести
  console.log(error);
}

Вызов методов API

События VKWebAppGetUserInfo и VKWebAppCallAPIMethod в отсутствии VKUIConnect производят запрос к https://api.vk.com. Для правильности работы этих методов нужно передать в options параметр accessToken, который в целях разработки можно получить, создав Standalone-приложение.

После создания Standaone-приложения вызовите в браузере следующую ссылку:

https://oauth.vk.com/authorize?client_id=CLIENT_ID&display=page&redirect_uri=&scope=SCOPE&response_type=token&v=5.92&state=123456

Где

  • CLIENT_ID — это app_id только что созданного приложения
  • SCOPE — желаемые уровни доступа для разработки, например friends,offline,wall

ВНИМАНИЕ! Никому не давайте этот токен. Не допускайте, чтобы токен попал в production-сборку приложения или в публичный репозиторий. Лучше всего настроить webpack использовать переменные окружения соответствующим образом.

CORS

На сайте api.vk.com не прописаны нужные заголовки, поэтому вызывать методы из браузера вне ВК придётся с помощью CORS-прокси. Быстрый и удобный прокси с открытым исходным кодом есть вот тут: https://github.com/marcus2vinicius/cors-anywhere, а его демонстрационная версия доступна по адресу https://cors-anywhere.herokuapp.com/. Настоятельно рекомендую вам поднять копию у себя, потому что при частых запросах демо-прокси будет вас отключать.

В параметр corsAddress передаётся строка, которая будет подставлена перед полным адресом вызова. Например:

https://api.vk.com/method/users.get?user_ids=1

Будет заменено на:

https://cors-anywhere.herokuapp.com/https://api.vk.com/method/users.get?user_ids=1

Не забывайте про / в конце corsAddress.

Поддерживаемые события

Идеология этой библиотеки в том, чтобы создать ситуацию, максимально близкую к живым данным. На текущий момент реализована поддержка следующих событий:

  • VKWebAppInit — отправляется автоматически при инициализации библиотеки
  • VKWebAppGetUserInfo — получает данные владельца токена с помощью API
  • VKWebAppGetAuthToken — в DEV-режиме это событие ничего не делает, но вызов его обязателен, о чём библиотека предупреждает, чтобы не забыть вызвать его в основном режиме. Обратите внимание, scope, который передан сюда, будет актуален только в PROD-режиме. В DEV-режиме будет использоваться scope, полученный при создании токена
  • VKWebAppCallAPIMethod — вызывает настоящий метод API ВК, возвращает результат или ошибку
  • VKWebAppGetGeodata — вызывает функцию браузера о получении координат, после ответа пользователя возвращает результат или ошибку
  • VKWebAppCopyText — текст копируется в буфер обмена браузерным методом
  • VKWebAppGetCommunityAuthToken — возвращается токен, переданный в options.communityToken
  • VKWebAppShare — открывается переданная ссылка в новом окне
  • VKWebAppShowCommunityWidgetPreviewBox — код виджета проверяется на валидность и выводится в консоль
  • VKWebAppShowWallPostBoxвызывается метод API wall.post с вашим options.accessToken
  • VKWebAppAllowNotifications — вызывается браузерный метод запроса уведомлений, результат всегда true
  • VKWebAppStorageGetKeys — весь блок Storage работает с localStorage
  • VKWebAppStorageGet — весь блок Storage работает с localStorage
  • VKWebAppStorageSet — весь блок Storage работает с localStorage
  • VKWebAppShowStoryBox — выдаёт данные Истории в консоль

Проверить наличие поддержки нужного события можно с помощью

VKC.supports('VKWebAppGetUserInfo'); // возвращает true

Собственные функции для реакции на события

Можно задать собственную функцию для ответа на событие, если встроенная вас не устраивает, или если событие ещё не поддерживается библиотекой. Функция должна возвращать Promise. На вход она принимает:

  • params — объект который будет потом передан в событие
  • options — текущие опции библиотеки Обратите внимание, после загрузки библиотеки переданный в инициализацию параметр MODE_AUTO меняется либо на MODE_DEV, либо на MODE_PROD.
import { MODE_DEV } from '@denisnp/vkui-connect-helper';

VKC.define('VKWebAppGetEmail', (params, options) => {
  // в options.mode хранится текущий режим MODE_DEV или MODE_PROD
  return new Promise((resolve, reject) => {
    if (options.mode === MODE_DEV) {
        resolve({
          type: 'VKWebAppGetEmailResult',
          data: { 
            email: '[email protected]',
            sign: ''
          },
        });
    }
  });
});

Шорткаты

Для некоторых распространённых событий есть шорткаты

Авторизация

Библиотека сама примет и сохранит access_token, полученный при авторизации. В дальнейшем вы сможете вызывать методы API без передачи в параметры access_token.

VKC.auth(scope); // аналог VKC.send('VKWebAppGetAuthToken', { scope: ... } );

// Не забываем, что это промис, и нужно обработать ответ:
VKC.auth('friends,photos').then((authData) => {
  if (authData.data.scope.indexOf('friends') >= 0) {
    // пользователь дал нам друзей
  }
});

Есть специальная константа SCOPE_EMPTY, которая показывает скоуп "Общая информация".

import { SCOPE_EMPTY } from '@denisnp/vkui-connect-helper';

Вызов API

Если была вызвана авторизация, то становится доступна отправка события VKWebAppCallAPIMethod. Можно не передавать в параметры поля v и access_token, библиотека сделает это за вас.

// в async-режиме
const [result, fail] = await VKC.api('friends.get', { fields: 'sex' }); // это аналог вызова VKC.send('VKWebAppCallAPIMethod'...)

if (result) {
  const firstFriendSex = result.data.items[0].sex;
}

Вызов с автоматической авторизацией

Если была передана options.defaultScope то перед вызовом API библиотека пытается авторизоваться автоматически с этим scope. Если нужно авторизовывать пользователя по частям, то можно добавить нужный scope третьим параметром в VKC.api():

// VKC.api(method, params, scope);
const [result, fail] = await VKC.api('photos.get', { album_id: 'wall' }, 'photos');

Загрузка фото на стену

const [result, fail] = await VKC.uploadWallPhoto(file, groupId, caption, scope);

В поле file нужно передавать результат работы <input type="file"/>. В result приходит ответ от метода photos.saveWallPhoto, если всё прошло хорошо. Поле scope нужно для того, чтобы использовать автоматическую авторизацию, если это требуется.

Подписка на события

Функция полностью аналогична такой функции в VKBridge

VKC.subscribe((e) => {
    const { type, data } = e.detail;
    if (type === 'VKWebAppOpenCodeReaderResult') {
       // Reading result of the Code Reader
       console.log(data.code_data);
    }
});

Прочие вызовы

В целом экземпляр VKBridge можно вызвать с помощью

const bridge = VKC.bridge();
bridge.send(...);

Поддержка остальных событий и участие в разработке

Если кто-то возьмётся за реализацию ещё каких-то событий, присылайте пулл-реквесты. Не забывайте проверить свой код на соответствие правилам, в этом проекте я использую code-style от Airbnb с отступом 4 пробела.

npm run lint

Напоминаю, что идея библиотеки в приближённости к настоящим данным. И, если некоторые значения получить из ВК в принципе невозможно (например, email пользователя), то вместо других можно написать работоспособную замену.