quickblox 2.23.0 → 2.23.1-beta.4

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.
@@ -0,0 +1,340 @@
1
+ # SDK fix plan — unhandled TypeError in `_getStats` (`s.remote[mediaType].bitrate`)
2
+
3
+ **Клон:** `C:\___QuickBlox\05-quickblox-javascript-sdk-internal`
4
+ **База:** ветка `develop`, версия **`2.23.0-beta.3`** (= версия, опубликованная на проекте
5
+ Q-Consultation; именно она крашится в логе QC-1682).
6
+ **Целевая ветка фикса:** отдельная от `develop` (имя создаёт пользователь; Claude
7
+ объявляет «приступаю к ветке X» → пользователь создаёт → «начинай»).
8
+ **Файл:** `src/modules/webrtc/qbRTCPeerConnection.js`
9
+ **Происхождение:** диагностика логов QC-1682 (P2P web-провайдер, видео отсутствует).
10
+ Полный разбор лога — `03-q-consultation-premium/__ai-work-log/bug-batch-2026-05-28-brightside/logs/QC-1682-log-analysis-2026-05-30.md`.
11
+
12
+ > Примечание: ранняя версия этого плана была сохранена в клоне 01
13
+ > (`__getStats-mediaType-guard-fix-plan.md`, ветка `rc/...-QC-1454`, beta.2). Она
14
+ > устарела — выполняем в клоне 05. Тот файл можно удалить отдельно.
15
+
16
+ ---
17
+
18
+ ## 1. Симптом (из лога QC-1682)
19
+
20
+ В консоли web-провайдера 7 раз подряд:
21
+ ```
22
+ [Error] Unhandled Promise Rejection: TypeError: undefined is not an object
23
+ (evaluating '(e=s.remote[r.mediaType]).bitrate=c(r,a,!1)')
24
+ (anonymous function) (vendors...js:2:2190970)
25
+ forEach
26
+ forEachWrapper
27
+ forEach
28
+ ```
29
+
30
+ ## 2. Точное место (верифицировано в клоне 05)
31
+
32
+ `src/modules/webrtc/qbRTCPeerConnection.js`, функция `_getStats` (объявлена строкой 521),
33
+ внутри `peer.getStats(null).then(... results.forEach(function (result) {...}))`.
34
+ Строки **547-564** в клоне 05 **идентичны** клону 01 (сверено 2026-05-30).
35
+
36
+ ```js
37
+ // строки 522-533 — заранее заведённые ключи:
38
+ var statistic = {
39
+ 'local': { 'audio': {}, 'video': {}, 'candidate': {} },
40
+ 'remote': { 'audio': {}, 'video': {}, 'candidate': {} }
41
+ };
42
+ ...
43
+ // строки 547-555 — падающая ветка (remote / inbound-rtp):
44
+ if (result.bytesReceived && result.type === 'inbound-rtp') {
45
+ item = statistic.remote[result.mediaType]; // ← (1) item может стать undefined
46
+ item.bitrate = _getBitratePerSecond(result, lastResults, false); // ← (2) КРАШ: (undefined).bitrate
47
+ item.bytesReceived = result.bytesReceived;
48
+ item.packetsReceived = result.packetsReceived;
49
+ item.timestamp = result.timestamp;
50
+ if (result.mediaType === 'video' && result.framerateMean) {
51
+ item.framesPerSecond = Math.round(result.framerateMean * 10) / 10;
52
+ }
53
+ }
54
+ // строки 556-564 — симметричная local / outbound-rtp ветка с тем же дефектом:
55
+ else if (result.bytesSent && result.type === 'outbound-rtp') {
56
+ item = statistic.local[result.mediaType]; // ← тот же риск
57
+ item.bitrate = _getBitratePerSecond(result, lastResults, true);
58
+ ...
59
+ }
60
+ ```
61
+
62
+ Сопоставление с минифик-стеком (1:1): `s`=`statistic`, `r`=`result`,
63
+ `c`=`_getBitratePerSecond`, `a`=`lastResults`, `!1`=`false`, внешний `forEach` = `results.forEach`.
64
+
65
+ ## 3. Корневая причина (верифицировано)
66
+
67
+ `statistic.remote` содержит **только** ключи `audio` / `video` / `candidate` (строки 528-532).
68
+ В ветке `inbound-rtp` код индексирует `statistic.remote[result.mediaType]` **без проверки**,
69
+ что `result.mediaType` — один из этих ключей. Если у inbound-rtp report
70
+ `result.mediaType` равен `undefined` или нестандартному значению — `statistic.remote[undefined]`
71
+ === `undefined`, и следующая строка делает `(undefined).bitrate = ...` → `TypeError`.
72
+
73
+ **Почему mediaType бывает undefined:** поле `RTCStats.mediaType` устаревшее и заменено на
74
+ `kind` в современном webrtc-stats. Safari/iOS WebKit может не заполнять `mediaType` в
75
+ inbound-rtp статистике → индекс по `undefined`. В логе QC-1682 ровно этот сценарий
76
+ (P2P web↔iOS-mobile).
77
+
78
+ Это **НЕ корень отсутствия видео** в QC-1682 (тот корень — отсутствие H.264 в SDP,
79
+ backend-задача). Это **самостоятельный дефект getStats SDK**: краш при отсутствующем/
80
+ нестандартном `mediaType`. Он будет всплывать в любом звонке, где это поле не заполнено,
81
+ и при этом **прерывает весь `forEach` и роняет промис** (`getStats(null).then(...)` без
82
+ catch на этом уровне → unhandled rejection) — то есть теряется ВЕСЬ stats-репорт за тик,
83
+ не только проблемный трек. Это затрагивает и потребителей `_onCallStatsReport` (на нём
84
+ у Q-Consultation построены QC-1645/QC-1475 — оценка «живости» видео).
85
+
86
+ **Стабильность кода:** строка `item = statistic.remote[result.mediaType]` присутствует
87
+ минимум с релиза 2.12.5 и не менялась. Guard никогда не добавлялся.
88
+
89
+ **Допущение про beta.3 — СНЯТО.** Клон 05 = ровно `2.23.0-beta.3` (версия с бага), код
90
+ строк 547-564 подтверждён идентичным. В клоне 01 (beta.2) это было непроверенным риском —
91
+ здесь его нет.
92
+
93
+ ## 4. План правки (РЕШЕНО 2026-05-30: guard + `kind`-fallback, вариант 1)
94
+
95
+ **Scope:** guard (убрать краш) + `mediaType || kind` fallback (заполнить Safari-stats).
96
+ Оба изменения — в одном `[QC-1682]`-PR.
97
+
98
+ > **СОСТОЯНИЕ КОДА на 2026-05-31 (сверено с `qbRTCPeerConnection.js`):** другой агент уже
99
+ > применил БОЛЬШУЮ часть: (1) логика вынесена из inline-`forEach` в отдельную функцию
100
+ > `_applyStatReport(statistic, result, lastResults)` (строка 551) — это и есть T2-рефактор,
101
+ > делающий код тестируемым; (2) **guard `if (item) {...} else { traceWarning }` уже стоит**
102
+ > в обеих ветках (inbound строки 557-567, outbound 571-581). **ОСТАЛОСЬ ТОЛЬКО `kind`-fallback.**
103
+ > Блоки кода ниже — это ЦЕЛЕВОЕ состояние; фактическая правка = добавить fallback к уже
104
+ > существующему `_applyStatReport`, а не писать guard заново.
105
+
106
+ ### Ключевая деталь fallback — нормализовать тип ОДИН раз в локальную переменную
107
+
108
+ `result.mediaType` используется в обеих ветках **дважды**: для индексации
109
+ (`statistic.remote[result.mediaType]`) И для проверки framerate
110
+ (`result.mediaType === 'video'`, строки 114/137 исходника). Если применить fallback только
111
+ к индексации, то на Safari (где есть только `result.kind`) индекс заработает, а проверка
112
+ `result.mediaType === 'video'` останется ложной → `framesPerSecond` не запишется.
113
+ Поэтому fallback вычисляем **один раз** в `var mediaType` и используем его в обоих местах:
114
+
115
+ ```js
116
+ var mediaType = result.mediaType || result.kind; // ← в начале forEach-колбэка, рядом с `var item;`
117
+ ```
118
+
119
+ (`var item;` уже объявлен в `_applyStatReport` строкой 552 — добавляем `mediaType` туда же.)
120
+
121
+ ### Фактическая правка в `_applyStatReport` (4 точечных замены)
122
+
123
+ В существующей функции `_applyStatReport` (строка 551):
124
+
125
+ 1. **Строка 552** — добавить вычисление `mediaType` сразу после `var item;`:
126
+ ```js
127
+ var item;
128
+ var mediaType = result.mediaType || result.kind;
129
+ ```
130
+ 2. **Строка 555** (inbound индексация): `statistic.remote[result.mediaType]`
131
+ → `statistic.remote[mediaType]`
132
+ 3. **Строка 562** (inbound framerate): `if (result.mediaType === 'video' ...`
133
+ → `if (mediaType === 'video' ...`
134
+ 4. **Строка 569** (outbound индексация): `statistic.local[result.mediaType]`
135
+ → `statistic.local[mediaType]`
136
+ 5. **Строка 576** (outbound framerate): `if (result.mediaType === 'video' ...`
137
+ → `if (mediaType === 'video' ...`
138
+ 6. (косметика, опц.) traceWarning-строки 566/580: текст `unknown mediaType:` +
139
+ `result.mediaType` → `unknown mediaType/kind:` + `mediaType` (чтобы лог показывал
140
+ уже нормализованное значение).
141
+
142
+ **Целевое состояние inbound-ветки (557-567):**
143
+ ```js
144
+ if (result.bytesReceived && result.type === 'inbound-rtp') {
145
+ item = statistic.remote[mediaType];
146
+
147
+ if (item) {
148
+ item.bitrate = _getBitratePerSecond(result, lastResults, false);
149
+ item.bytesReceived = result.bytesReceived;
150
+ item.packetsReceived = result.packetsReceived;
151
+ item.timestamp = result.timestamp;
152
+ if (mediaType === 'video' && result.framerateMean) {
153
+ item.framesPerSecond = Math.round(result.framerateMean * 10) / 10;
154
+ }
155
+ } else {
156
+ Helpers.traceWarning('_getStats: skipping inbound-rtp report with unknown mediaType/kind: ' + mediaType);
157
+ }
158
+ }
159
+ ```
160
+ Outbound-ветка (568-581) — симметрично (`statistic.local[mediaType]`,
161
+ `mediaType === 'video'`, `isLocal=true`).
162
+
163
+ **Эффект fallback:** на Safari/iOS (`result.mediaType === undefined`, но
164
+ `result.kind === 'video'/'audio'`) `mediaType` теперь резолвится в корректный ключ →
165
+ `statistic.remote.video` / `.audio` заполняются → QC-1645/QC-1475 получают stats.
166
+ **guard остаётся** как страховка: если у report'а нет ни `mediaType`, ни `kind` (или
167
+ значение нестандартное, напр. `'data'`/`'application'`) — `item` будет `undefined`, и
168
+ тело пропускается с diagnostic-warn вместо краша.
169
+
170
+ **Почему `Helpers.traceWarning`, а не свой `if (config.debug) console.warn`:**
171
+ - Файл уже импортирует `Helpers = require('./qbWebRTCHelpers')` (строка 2 в require-блоке),
172
+ `traceWarning` используется в SDK широко.
173
+ - `traceWarning` сам гейтит на `config.debug` (qbWebRTCHelpers.js:26-29) — в production
174
+ под `config.debug=false` лог молчит, никакого шума.
175
+ - В debug-сессиях (диагностика следующих QC-инцидентов) команда сразу увидит причину
176
+ пропуска report без поиска guard'а в коде.
177
+
178
+ ### Что НЕ трогаем
179
+
180
+ - Ветки `local-candidate` / `remote-candidate` / `track` (565-593) — там `item`
181
+ присваивается фиксированным ключам (`statistic.local.candidate`, `statistic.remote.video`),
182
+ всегда существующим. Краш невозможен — guard не нужен. **(Утверждение
183
+ предварительное; перед началом реализации перечитать строки 565-593 и явно
184
+ подтвердить в commit-сообщении.)**
185
+ - `_getBitratePerSecond` / `_getFramesPerSecond` — не меняем.
186
+ - `package.json` версию — НЕ бамаем без отдельного решения (правило DO NOT).
187
+ - Грязные в `develop` файлы (`STATE.md`, `DECISIONS.md`, `__ai-work-log/assessments/`) —
188
+ не трогаем, они не относятся к фиксу (AI-tooling). Их не коммитим в ветку фикса.
189
+
190
+ ### Что НЕ делаем в этом PR (зафиксировано как follow-up)
191
+
192
+ - **`result.mediaType || result.kind` fallback** — отдельный follow-up SDK-тикет.
193
+ Контекст: поле `mediaType` deprecated в текущем W3C WebRTC stats spec, заменено на
194
+ `kind` (значения те же — `'audio'`/`'video'`). Старые Chrome/FF отдавали `mediaType`,
195
+ современные браузеры отдают оба ради backward-compat, **Safari/WebKit в части report'ов
196
+ отдаёт только `kind`** — это и есть истинная причина `mediaType === undefined` в логе
197
+ QC-1682. Текущий guard устраняет краш и unhandled rejection (P0), но Safari-stats
198
+ по-прежнему будут пустыми (P1 — функциональная потеря для QC-1645/QC-1475 «оценка
199
+ живости видео», которые читают `_onCallStatsReport`).
200
+ - Почему не делаем сейчас: fallback **меняет наблюдаемое поведение**
201
+ (`statistic.remote.video` для Safari начнёт заполняться там, где раньше был
202
+ `undefined`), а guard — нет (для валидного `mediaType` идентичный путь). Это разный
203
+ риск, разный scope, разный test plan. Не смешиваем.
204
+ - Что делаем: **РЕШЕНИЕ (2026-05-30): отдельного тикета НЕТ — всё в рамках QC-1682.**
205
+ Если fallback тоже делаем (см. §8 п.1), он идёт тем же `[QC-1682]`-коммитом/в том же
206
+ PR, что и guard. Если откладываем — фиксируем как follow-up внутри QC-1682, без
207
+ нового номера.
208
+
209
+ ## 5. Тестирование — реалистичная оценка (ВАЖНО, честно)
210
+
211
+ `_getStats` — **приватная функция** (`function _getStats(...)` в модуле, НЕ на прототипе,
212
+ НЕ экспортируется). `QB-WebRTCSpec.js` (79 строк) — **integration-тест**: реальный
213
+ `QB.init` + `QB.chat.connect` к серверу (креды из `spec/config`), и почти всё `pending()`
214
+ под Node (`WebRTC API isn't supported outside of the browser`). getStats там НЕ покрыт.
215
+
216
+ Из этого следует: **изолированный юнит-тест на `_getStats` без вмешательства в файл
217
+ или новой dev-зависимости невозможен**, а integration-путь требует браузера + живого
218
+ `RTCPeerConnection` и не воспроизводит `mediaType=undefined` детерминированно. Варианты,
219
+ что реально доступно:
220
+
221
+ - **Вариант T1 (минимум, рекомендую для этого точечного guard'а):** без нового авто-теста.
222
+ Обоснование: правка — чистый guard + warn, не меняет поведение для валидных `mediaType`
223
+ (`item` существует → идентичный путь); меняет только путь `mediaType ∉ {audio,video}`
224
+ (раньше краш → теперь skip + traceWarning). Проверка — `lint` + существующие
225
+ `test:pr` (регрессия, что ничего не сломали) + ручная сверка `git diff`.
226
+ - **Вариант T1.5 (рассмотреть, если когда-то понадобится покрытие `_getStats`):** юнит-тест
227
+ через `rewire` / `proxyquire` — эти библиотеки умеют доставать приватные функции из
228
+ модуля через `__get__` API, **не меняя production-код**. Файл `qbRTCPeerConnection.js`
229
+ не модифицируется, тест получает реальный `_getStats` и проверяет его на fake-peer'е
230
+ с `getStats: () => Promise.resolve([{ type: 'inbound-rtp', bytesReceived: 100,
231
+ mediaType: undefined }])`. Покрытие 100% настоящего кода без рефактора. **Цена:**
232
+ `rewire` — новая dev-зависимость, требует отдельного approval (CLAUDE.md DO NOT
233
+ запрещает `npm install` без подтверждения). **Не для этого PR**: если ставим rewire —
234
+ это отдельный шаг «инфраструктура тестов», не часть guard-фикса.
235
+ - **Вариант T2 (если нужен авто-тест без новых dev-зависимостей):** вынести «нормализатор
236
+ одного stats-report» в чистую экспортируемую утилиту (напр.
237
+ `applyStatReport(statistic, result, lastResults)`), написать на неё jasmine-тест в Node
238
+ (без браузера) с кейсами `mediaType: 'video' | 'audio' | undefined | 'application'`.
239
+ Это уже **рефактор-фикс**, шире guard'а — отдельное решение пользователя (риск задеть
240
+ рабочий код ради тестируемости).
241
+
242
+ **Рекомендация:** **T1** для самого фикса. T1.5 — кандидат на будущий PR (`mediaType ||
243
+ kind` fallback из §4), там покрытие важнее и rewire оправдан. T2 — только если команда
244
+ SDK хочет покрытие, но без новых dev-зависимостей.
245
+
246
+ ### Сравнительная таблица
247
+
248
+ | Вариант | Меняет prod-код | Новые deps | Покрытие настоящего `_getStats` | Риск регрессии |
249
+ |---|---|---|---|---|
250
+ | T1 (рекомендую) | Нет | Нет | 0% (только lint + regression) | Минимальный |
251
+ | T1.5 (rewire) | Нет | +rewire (требует approval) | 100% | Минимальный |
252
+ | T2 (рефактор) | Да | Нет | 100% | Средний (риск задеть смежное) |
253
+
254
+ ## 6. Сборка / проверка (клон 05)
255
+
256
+ `node_modules` на месте — `npm i` не требуется. Скрипты (из package.json):
257
+ 1. `git diff` — только строки 547-564 (2 блока).
258
+ 2. `npm run lint` (jshint) — должно быть чисто.
259
+ 3. `npm run test:pr` (jasmine PR-набор, включает `QB-WebRTCSpec.js`) — регрессия зелёная.
260
+ 4. (опц.) `npm run test:node-regression` (`spec/phase-a-upgrade-check.js`).
261
+ 5. `npm run build` НЕ обязателен для PR кода (dist собирается отдельно), но если нужен
262
+ собранный артефакт для проверки на проекте — `npm run build` (lint+gulp+minify).
263
+
264
+ ## 7. Definition of Done
265
+
266
+ - [x] Логика вынесена в `_applyStatReport` (T2-рефактор) — уже сделано другим агентом.
267
+ - [x] Guard + `traceWarning` в обеих ветках — уже сделано другим агентом.
268
+ - [ ] **`kind`-fallback добавлен** (`var mediaType = result.mediaType || result.kind` +
269
+ 4 замены `result.mediaType` → `mediaType`, см. §4) — ОСТАВШАЯСЯ работа.
270
+ - [ ] `git diff` чист (только функция `_applyStatReport`, файл
271
+ `src/modules/webrtc/qbRTCPeerConnection.js`).
272
+ - [ ] Подтверждено перечитыванием candidate/`track`-веток (после 581), что они используют
273
+ фиксированные ключи (`statistic.*.candidate`, `statistic.remote.video` по
274
+ `remoteSource`) и fallback/guard им не нужен.
275
+ - [ ] `npm run lint` зелёный.
276
+ - [ ] `npm run test:pr` зелёный (регрессия).
277
+ - [ ] **Авто-тест на `_applyStatReport`** (теперь реалистичен — функция выделена; см. §5):
278
+ кейсы `mediaType:'video'` / `kind:'video'` без mediaType (Safari) / ни того ни
279
+ другого (skip+warn). Решить T1 (без теста) vs тест на `_applyStatReport` — §8 п.2.
280
+ - [ ] Префикс коммита — `[QC-1682]` (РЕШЕНИЕ 2026-05-30: отдельного тикета нет, всё в
281
+ рамках QC-1682). Связь отражена в коммите/PR: это побочный SDK-дефект из диагностики
282
+ QC-1682, НЕ чинит само отсутствие видео (корень — H.264/backend). Шаблон сообщения:
283
+ «Surfaced while diagnosing QC-1682. Not the root cause of QC-1682 video absence —
284
+ that is backend H.264 negotiation.»
285
+ - [ ] Коммит/пуш — только после явного approval пользователя; Claude готовит текст
286
+ коммита (1-2 строки), пользователь коммитит.
287
+
288
+ ## 8. Решения и открытые вопросы
289
+
290
+ **РЕШЕНО (2026-05-30):**
291
+ - **Доставка — вариант A:** фикс в SDK (клон 05) → бамп версии + build + `npm publish`
292
+ → перевод Q-Consultation на новую версию. Полный релизный цикл. Детали — §9.
293
+ - **Без отдельного Jira-тикета:** всё в рамках **QC-1682**. Префикс коммита `[QC-1682]`.
294
+
295
+ - **Scope — РЕШЕНО (вариант 1): guard + `kind`-fallback.** Закрывает и краш, и пустую
296
+ Safari-статистику (QC-1645/QC-1475). Оба в одном `[QC-1682]`-PR. Guard уже в коде;
297
+ остался fallback (§4).
298
+
299
+ **ОТКРЫТО (нужно решение перед финальной правкой):**
300
+ 1. **Авто-тест на `_applyStatReport`?** Функция уже выделена другим агентом, поэтому
301
+ юнит-тест без новых dev-зависимостей теперь возможен (jasmine, Node): передать
302
+ fake-`statistic` + fake-`result` с разными `mediaType`/`kind`, проверить заполнение и
303
+ skip. Варианты: **T-да** (написать тест — рекомендую, раз функция уже тестопригодна) /
304
+ **T-нет** (только lint+test:pr регрессия). Цена T-да минимальна (функция чистая).
305
+
306
+ ## 9. Доставка фикса до прода — вариант A (РЕШЕНО 2026-05-30)
307
+
308
+ Полный релизный цикл: SDK → npm → Q-Consultation. Всё под `[QC-1682]`.
309
+
310
+ ### Этап 1 — фикс в SDK (клон 05, отдельная ветка от `develop`)
311
+ Реализация по §4 (другой агент), проверка по §6 (`lint` + `test:pr`). Коммит — пользователь,
312
+ после approval, текст готовит Claude (1-2 строки, префикс `[QC-1682]`).
313
+
314
+ ### Этап 2 — версия + публикация в npm ⚠️ финансово/инфраструктурно значимо
315
+ - **Бамп версии** в `package.json` SDK: `2.23.0-beta.3` → `2.23.0-beta.4` (или по
316
+ конвенции релизов QuickBlox — уточнить у владельца релиза SDK). Это и есть «отдельное
317
+ решение», которое снимает запрет §4 «версию не бамаем».
318
+ - **Сборка `dist/`:** `npm run build` (lint + gulp + minify) — npm-пакет содержит
319
+ собранный код, не `src/`.
320
+ - **`npm publish`** под нужным dist-tag (вероятно `beta`). Выполняет **ПОЛЬЗОВАТЕЛЬ**
321
+ (или CI/релиз-процесс). Claude НЕ имеет и не должен иметь доступа к npm-аккаунту
322
+ QuickBlox (security-baseline §5 «НИКОГДА npm publish»). Claude только готовит шаги.
323
+ - Проверить, что новая версия реально появилась в npm registry перед этапом 3.
324
+
325
+ ### Этап 3 — перевод Q-Consultation на новую версию
326
+ Клон проекта: `C:\___QuickBlox\0X-q-consultation-premium` (тот, где будем переключать —
327
+ уточнить какой; текущая работа шла в `03-`).
328
+ - `packages/quickblox/package.json`: `"quickblox": "2.23.0-beta.3"` → новая версия.
329
+ (Проверено 2026-05-30: зависимость объявлена именно там; `yarn.lock` резолвит из npm.)
330
+ - `yarn install` — обновит `yarn.lock` (пользователь разрешил install объявленного без
331
+ отдельного спроса; но смена версии пакета — это уже изменение зависимости, спросить).
332
+ - Пересборка зависимых пакетов: `@qc/quickblox`, `@qc/conference` (зависят от `quickblox`).
333
+ - Проверка: tsc (provider/client/api) + vitest + Playwright + dev-test реального звонка
334
+ (web↔Safari/iOS, чтобы убедиться: краш `bitrate` ушёл; если делали `kind`-fallback —
335
+ что Safari-stats заполняются).
336
+
337
+ ### Что подтвердить ПЕРЕД этапом 3
338
+ - Версию (`beta.4`?) и dist-tag — согласовать с владельцем релиза SDK.
339
+ - Не сломает ли смена версии SDK другие клоны Q-Consultation (01/02/04) — они на той же
340
+ зависимости; менять только целевой клон или все — отдельное решение.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "quickblox",
3
3
  "description": "QuickBlox JavaScript SDK",
4
- "version": "2.23.0",
4
+ "version": "2.23.1-beta.4",
5
5
  "homepage": "https://quickblox.com/developers/Javascript",
6
6
  "main": "src/qbMain.js",
7
7
  "types": "quickblox.d.ts",
@@ -83,6 +83,9 @@
83
83
  "lint": "jshint src --reporter=node_modules/jshint-stylish",
84
84
  "test:node-regression": "node spec/phase-a-upgrade-check.js",
85
85
  "test:regression": "npm run test:node-regression && npm test",
86
+ "test:pr": "jasmine --config=spec/support/jasmine.pr.json",
87
+ "test:full": "jasmine --config=spec/support/jasmine.full.json",
88
+ "test:ci": "npm run lint && npm run test:node-regression && npm run test:pr",
86
89
  "build": "cross-env NODE_ENV=production npm run lint && gulp build && gulp minify",
87
90
  "buildNotMinified": "npm run lint && gulp build",
88
91
  "generateBuildVersion": "gulp generate-build_version",