chore: update dependencies and refactor build script

pull/270/head
dessant 4 years ago
parent ce2d9424f5
commit 2bdabf122e

@ -19,24 +19,17 @@ jobs:
with: with:
node-version: ${{ steps.nvm.outputs.NODE_VERSION }} node-version: ${{ steps.nvm.outputs.NODE_VERSION }}
- name: Install dependencies - name: Install dependencies
run: | run: yarn
sudo apt install rename
yarn
- name: Build artifacts - name: Build artifacts
run: yarn build:prod:zip:all run: yarn build:prod:zip:all
- name: Prepare artifacts
run: |
rename 's|artifacts/(.*)/(.*)\.zip$|artifacts/$2-$1\.zip|' artifacts/*/*.zip
rm -rf artifacts/*/
if: startsWith(github.ref, 'refs/tags/v')
- name: Hash artifacts - name: Hash artifacts
run: sha256sum artifacts/* run: sha256sum artifacts/*/*
if: startsWith(github.ref, 'refs/tags/v') if: startsWith(github.ref, 'refs/tags/v')
- name: Upload artifacts - name: Upload artifacts
uses: actions/upload-artifact@v2 uses: actions/upload-artifact@v2
if: startsWith(github.ref, 'refs/tags/v') if: startsWith(github.ref, 'refs/tags/v')
with: with:
name: buster name: artifacts
path: artifacts/ path: artifacts/
release: release:
name: Release on GitHub name: Release on GitHub
@ -52,10 +45,10 @@ jobs:
- name: Download artifacts - name: Download artifacts
uses: actions/download-artifact@v2 uses: actions/download-artifact@v2
with: with:
name: buster name: artifacts
path: artifacts/ path: artifacts/
- name: Hash artifacts - name: Hash artifacts
run: sha256sum artifacts/* run: sha256sum artifacts/*/*
- name: Create GitHub release - name: Create GitHub release
id: create_release id: create_release
uses: actions/create-release@v1 uses: actions/create-release@v1
@ -75,7 +68,7 @@ jobs:
GITHUB_TOKEN: ${{ github.token }} GITHUB_TOKEN: ${{ github.token }}
with: with:
upload_url: ${{ steps.create_release.outputs.upload_url }} upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: artifacts/buster_captcha_solver_for_humans-${{ steps.release_info.outputs.VERSION }}-chrome.zip asset_path: artifacts/chrome/buster_captcha_solver_for_humans-${{ steps.release_info.outputs.VERSION }}-chrome.zip
asset_name: buster_captcha_solver_for_humans-${{ steps.release_info.outputs.VERSION }}-chrome.zip asset_name: buster_captcha_solver_for_humans-${{ steps.release_info.outputs.VERSION }}-chrome.zip
asset_content_type: application/octet-stream asset_content_type: application/octet-stream
- name: Upload GitHub release assets - name: Upload GitHub release assets
@ -84,7 +77,7 @@ jobs:
GITHUB_TOKEN: ${{ github.token }} GITHUB_TOKEN: ${{ github.token }}
with: with:
upload_url: ${{ steps.create_release.outputs.upload_url }} upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: artifacts/buster_captcha_solver_for_humans-${{ steps.release_info.outputs.VERSION }}-edge.zip asset_path: artifacts/edge/buster_captcha_solver_for_humans-${{ steps.release_info.outputs.VERSION }}-edge.zip
asset_name: buster_captcha_solver_for_humans-${{ steps.release_info.outputs.VERSION }}-edge.zip asset_name: buster_captcha_solver_for_humans-${{ steps.release_info.outputs.VERSION }}-edge.zip
asset_content_type: application/octet-stream asset_content_type: application/octet-stream
- name: Upload GitHub release assets - name: Upload GitHub release assets
@ -93,7 +86,7 @@ jobs:
GITHUB_TOKEN: ${{ github.token }} GITHUB_TOKEN: ${{ github.token }}
with: with:
upload_url: ${{ steps.create_release.outputs.upload_url }} upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: artifacts/buster_captcha_solver_for_humans-${{ steps.release_info.outputs.VERSION }}-firefox.zip asset_path: artifacts/firefox/buster_captcha_solver_for_humans-${{ steps.release_info.outputs.VERSION }}-firefox.zip
asset_name: buster_captcha_solver_for_humans-${{ steps.release_info.outputs.VERSION }}-firefox.zip asset_name: buster_captcha_solver_for_humans-${{ steps.release_info.outputs.VERSION }}-firefox.zip
asset_content_type: application/octet-stream asset_content_type: application/octet-stream
- name: Upload GitHub release assets - name: Upload GitHub release assets
@ -102,6 +95,6 @@ jobs:
GITHUB_TOKEN: ${{ github.token }} GITHUB_TOKEN: ${{ github.token }}
with: with:
upload_url: ${{ steps.create_release.outputs.upload_url }} upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: artifacts/buster_captcha_solver_for_humans-${{ steps.release_info.outputs.VERSION }}-opera.zip asset_path: artifacts/opera/buster_captcha_solver_for_humans-${{ steps.release_info.outputs.VERSION }}-opera.zip
asset_name: buster_captcha_solver_for_humans-${{ steps.release_info.outputs.VERSION }}-opera.zip asset_name: buster_captcha_solver_for_humans-${{ steps.release_info.outputs.VERSION }}-opera.zip
asset_content_type: application/octet-stream asset_content_type: application/octet-stream

@ -1 +1 @@
12.14.1 12.18.4

@ -1,2 +1,4 @@
singleQuote: true singleQuote: true
bracketSpacing: false bracketSpacing: false
arrowParens: 'avoid'
trailingComma: 'none'

@ -2,28 +2,27 @@ const path = require('path');
const {exec} = require('child_process'); const {exec} = require('child_process');
const {lstatSync, readdirSync, readFileSync, writeFileSync} = require('fs'); const {lstatSync, readdirSync, readFileSync, writeFileSync} = require('fs');
const {ensureDirSync} = require('fs-extra'); const {series, parallel, src, dest} = require('gulp');
const gulp = require('gulp');
const htmlmin = require('gulp-htmlmin');
const svgmin = require('gulp-svgmin');
const babel = require('gulp-babel'); const babel = require('gulp-babel');
const postcss = require('gulp-postcss'); const postcss = require('gulp-postcss');
const gulpif = require('gulp-if'); const gulpif = require('gulp-if');
const del = require('del');
const jsonMerge = require('gulp-merge-json'); const jsonMerge = require('gulp-merge-json');
const jsonmin = require('gulp-jsonmin'); const jsonmin = require('gulp-jsonmin');
const svg2png = require('svg2png'); const htmlmin = require('gulp-htmlmin');
const imagemin = require('gulp-imagemin'); const imagemin = require('gulp-imagemin');
const del = require('del');
const {ensureDirSync} = require('fs-extra');
const sharp = require('sharp');
const targetEnv = process.env.TARGET_ENV || 'firefox'; const targetEnv = process.env.TARGET_ENV || 'firefox';
const isProduction = process.env.NODE_ENV === 'production'; const isProduction = process.env.NODE_ENV === 'production';
const distDir = path.join('dist', targetEnv); const distDir = path.join('dist', targetEnv);
gulp.task('clean', function() { function clean() {
return del([distDir]); return del([distDir]);
}); }
gulp.task('js:webpack', function(done) { function jsWebpack(done) {
exec('webpack-cli --display-error-details --bail --colors', function( exec('webpack-cli --display-error-details --bail --colors', function(
err, err,
stdout, stdout,
@ -33,109 +32,116 @@ gulp.task('js:webpack', function(done) {
console.log(stderr); console.log(stderr);
done(err); done(err);
}); });
}); }
gulp.task('js:babel', function(done) { function jsBabel() {
gulp return src(['src/content/**/*.js'], {base: '.'})
.src(['src/content/**/*.js'], {base: '.'})
.pipe(babel()) .pipe(babel())
.pipe(gulp.dest(distDir)); .pipe(dest(distDir));
done(); }
});
gulp.task('js', gulp.parallel('js:webpack', 'js:babel')); const js = parallel(jsWebpack, jsBabel);
gulp.task('html', function(done) { function html() {
gulp return src('src/**/*.html', {base: '.'})
.src('src/**/*.html', {base: '.'})
.pipe(gulpif(isProduction, htmlmin({collapseWhitespace: true}))) .pipe(gulpif(isProduction, htmlmin({collapseWhitespace: true})))
.pipe(gulp.dest(distDir)); .pipe(dest(distDir));
done(); }
});
function css() {
gulp.task('css', function(done) { return src(['src/solve/style.css'], {
gulp base: '.'
.src(['src/solve/style.css'], { })
base: '.'
})
.pipe(postcss()) .pipe(postcss())
.pipe(gulp.dest(distDir)); .pipe(dest(distDir));
done(); }
});
gulp.task('icons', async function(done) { async function images(done) {
ensureDirSync(`${distDir}/src/icons/app`); ensureDirSync(path.join(distDir, 'src/icons/app'));
const iconSvg = readFileSync('src/icons/app/icon.svg'); const appIconSvg = readFileSync('src/icons/app/icon.svg');
const appIconSizes = [16, 19, 24, 32, 38, 48, 64, 96, 128]; const appIconSizes = [16, 19, 24, 32, 38, 48, 64, 96, 128];
for (const size of appIconSizes) { for (const size of appIconSizes) {
const pngBuffer = await svg2png(iconSvg, {width: size, height: size}); await sharp(appIconSvg, {density: (72 * size) / 24})
writeFileSync(`${distDir}/src/icons/app/icon-${size}.png`, pngBuffer); .resize(size)
.toFile(path.join(distDir, `src/icons/app/icon-${size}.png`));
} }
// Chrome Web Store does not correctly display optimized icons
if (isProduction) { if (isProduction && targetEnv !== 'chrome') {
gulp await new Promise(resolve => {
.src(`${distDir}/src/icons/**/*.png`, {base: '.'}) src(path.join(distDir, 'src/icons/app/*.png'), {base: '.'})
.pipe(imagemin()) .pipe(imagemin())
.pipe(gulp.dest('.')); .pipe(dest('.'))
.on('error', done)
.on('finish', resolve);
});
} }
gulp await new Promise(resolve => {
.src('node_modules/ext-contribute/src/assets/*.svg') src('node_modules/ext-contribute/src/assets/*.@(jpg|png|svg)')
.pipe(gulpif(isProduction, svgmin())) .pipe(gulpif(isProduction, imagemin()))
.pipe(gulp.dest(`${distDir}/src/contribute/assets`)); .pipe(dest(path.join(distDir, 'src/contribute/assets')))
done(); .on('error', done)
}); .on('finish', resolve);
});
}
async function fonts(done) {
await new Promise(resolve => {
src('src/fonts/roboto.css', {base: '.'})
.pipe(postcss())
.pipe(dest(distDir))
.on('error', done)
.on('finish', resolve);
});
gulp.task('fonts', function(done) { await new Promise(resolve => {
gulp src('node_modules/fontsource-roboto/files/roboto-latin-@(400|500|700)-normal.woff2')
.src('src/fonts/roboto.css', {base: '.'}) .pipe(dest(path.join(distDir, 'src/fonts/files')))
.pipe(postcss()) .on('error', done)
.pipe(gulp.dest(distDir)); .on('finish', resolve);
gulp });
.src('node_modules/typeface-roboto/files/roboto-latin-@(400|500|700).woff2') }
.pipe(gulp.dest(`${distDir}/src/fonts/files`));
done(); async function locale(done) {
});
gulp.task('locale', function(done) {
const localesRootDir = path.join(__dirname, 'src/_locales'); const localesRootDir = path.join(__dirname, 'src/_locales');
const localeDirs = readdirSync(localesRootDir).filter(function(file) { const localeDirs = readdirSync(localesRootDir).filter(function(file) {
return lstatSync(path.join(localesRootDir, file)).isDirectory(); return lstatSync(path.join(localesRootDir, file)).isDirectory();
}); });
localeDirs.forEach(function(localeDir) { for (const localeDir of localeDirs) {
const localePath = path.join(localesRootDir, localeDir); const localePath = path.join(localesRootDir, localeDir);
gulp await new Promise(resolve => {
.src( src(
[ [
path.join(localePath, 'messages.json'), path.join(localePath, 'messages.json'),
path.join(localePath, `messages-${targetEnv}.json`) path.join(localePath, `messages-${targetEnv}.json`)
], ],
{allowEmpty: true} {allowEmpty: true}
) )
.pipe( .pipe(
jsonMerge({ jsonMerge({
fileName: 'messages.json', fileName: 'messages.json',
edit: (parsedJson, file) => { edit: (parsedJson, file) => {
if (isProduction) { if (isProduction) {
for (let [key, value] of Object.entries(parsedJson)) { for (let [key, value] of Object.entries(parsedJson)) {
if (value.hasOwnProperty('description')) { if (value.hasOwnProperty('description')) {
delete parsedJson[key].description; delete parsedJson[key].description;
}
} }
} }
return parsedJson;
} }
return parsedJson; })
} )
}) .pipe(gulpif(isProduction, jsonmin()))
) .pipe(dest(path.join(distDir, '_locales', localeDir)))
.pipe(gulpif(isProduction, jsonmin())) .on('error', done)
.pipe(gulp.dest(path.join(distDir, '_locales', localeDir))); .on('finish', resolve);
}); });
done(); }
}); }
gulp.task('manifest', function(done) { function manifest() {
gulp return src('src/manifest.json')
.src('src/manifest.json')
.pipe( .pipe(
jsonMerge({ jsonMerge({
fileName: 'manifest.json', fileName: 'manifest.json',
@ -163,13 +169,12 @@ gulp.task('manifest', function(done) {
}) })
) )
.pipe(gulpif(isProduction, jsonmin())) .pipe(gulpif(isProduction, jsonmin()))
.pipe(gulp.dest(distDir)); .pipe(dest(distDir));
done(); }
});
gulp.task('license', function(done) { function license() {
let year = 2018; let year = '2018';
const currentYear = new Date().getFullYear(); const currentYear = new Date().getFullYear().toString();
if (year !== currentYear) { if (year !== currentYear) {
year = `${year}-${currentYear}`; year = `${year}-${currentYear}`;
} }
@ -181,48 +186,22 @@ This software is released under the terms of the GNU General Public License v3.0
See the LICENSE file for further information. See the LICENSE file for further information.
`; `;
writeFileSync(`${distDir}/NOTICE`, notice); writeFileSync(path.join(distDir, 'NOTICE'), notice);
gulp.src(['LICENSE']).pipe(gulp.dest(distDir)); return src(['LICENSE']).pipe(dest(distDir));
done(); }
});
gulp.task('copy', function(done) {
gulp
.src('node_modules/ext-contribute/src/assets/*.@(jpg|png)')
.pipe(gulp.dest(`${distDir}/src/contribute/assets`));
done();
});
gulp.task(
'build',
gulp.series(
'clean',
gulp.parallel(
'js',
'html',
'css',
'icons',
'fonts',
'locale',
'manifest',
'license'
),
'copy'
)
);
gulp.task('zip', function(done) { function zip(done) {
exec( exec(
`web-ext build -s dist/${targetEnv} -a artifacts/${targetEnv} --overwrite-dest`, `web-ext build -s dist/${targetEnv} -a artifacts/${targetEnv} -n '{name}-{version}-${targetEnv}.zip' --overwrite-dest`,
function(err, stdout, stderr) { function(err, stdout, stderr) {
console.log(stdout); console.log(stdout);
console.log(stderr); console.log(stderr);
done(err); done(err);
} }
); );
}); }
gulp.task('inspect', function(done) { function inspect(done) {
exec( exec(
`webpack --profile --json > report.json && webpack-bundle-analyzer report.json dist/firefox/src && sleep 10 && rm report.{json,html}`, `webpack --profile --json > report.json && webpack-bundle-analyzer report.json dist/firefox/src && sleep 10 && rm report.{json,html}`,
function(err, stdout, stderr) { function(err, stdout, stderr) {
@ -231,6 +210,11 @@ gulp.task('inspect', function(done) {
done(err); done(err);
} }
); );
}); }
gulp.task('default', gulp.series('build')); exports.build = series(
clean,
parallel(js, html, css, images, fonts, locale, manifest, license)
);
exports.zip = zip;
exports.inspect = inspect;

@ -5,13 +5,13 @@
"repository": "https://github.com/dessant/buster", "repository": "https://github.com/dessant/buster",
"license": "GPL-3.0-only", "license": "GPL-3.0-only",
"scripts": { "scripts": {
"_build": "cross-env NODE_ENV=development gulp", "_build": "cross-env NODE_ENV=development gulp build",
"build:chrome": "cross-env TARGET_ENV=chrome yarn _build", "build:chrome": "cross-env TARGET_ENV=chrome yarn _build",
"build:edge": "cross-env TARGET_ENV=edge yarn _build", "build:edge": "cross-env TARGET_ENV=edge yarn _build",
"build:firefox": "cross-env TARGET_ENV=firefox yarn _build", "build:firefox": "cross-env TARGET_ENV=firefox yarn _build",
"build:opera": "cross-env TARGET_ENV=opera yarn _build", "build:opera": "cross-env TARGET_ENV=opera yarn _build",
"build:all": "run-s 'build:@(chrome|edge|firefox|opera)'", "build:all": "run-s 'build:@(chrome|edge|firefox|opera)'",
"_build:prod": "cross-env NODE_ENV=production gulp", "_build:prod": "cross-env NODE_ENV=production gulp build",
"build:prod:chrome": "cross-env TARGET_ENV=chrome yarn _build:prod", "build:prod:chrome": "cross-env TARGET_ENV=chrome yarn _build:prod",
"build:prod:edge": "cross-env TARGET_ENV=edge yarn _build:prod", "build:prod:edge": "cross-env TARGET_ENV=edge yarn _build:prod",
"build:prod:firefox": "cross-env TARGET_ENV=firefox yarn _build:prod", "build:prod:firefox": "cross-env TARGET_ENV=firefox yarn _build:prod",
@ -27,7 +27,7 @@
"start:firefox": "web-ext run -s dist/firefox -t firefox-desktop", "start:firefox": "web-ext run -s dist/firefox -t firefox-desktop",
"start:android": "web-ext run -s dist/firefox -t firefox-android", "start:android": "web-ext run -s dist/firefox -t firefox-android",
"inspect": "cross-env NODE_ENV=production gulp inspect", "inspect": "cross-env NODE_ENV=production gulp inspect",
"update": "ncu --upgrade && yarn", "update": "ncu --upgrade",
"push": "git push --follow-tags origin master", "push": "git push --follow-tags origin master",
"release": "standard-version" "release": "standard-version"
}, },
@ -41,53 +41,52 @@
"@material/theme": "^4.0.0", "@material/theme": "^4.0.0",
"@material/typography": "^4.0.0", "@material/typography": "^4.0.0",
"audiobuffer-to-wav": "^1.0.0", "audiobuffer-to-wav": "^1.0.0",
"bowser": "^2.9.0", "bowser": "^2.11.0",
"core-js": "^3.6.4", "core-js": "^3.6.5",
"ext-components": "dessant/ext-components#^0.4.0", "ext-components": "dessant/ext-components#^0.4.0",
"ext-contribute": "dessant/ext-contribute#^0.3.3", "ext-contribute": "dessant/ext-contribute#^0.3.3",
"fontsource-roboto": "^3.0.3",
"storage-versions": "dessant/storage-versions#^0.2.6", "storage-versions": "dessant/storage-versions#^0.2.6",
"typeface-roboto": "^0.0.75", "uuid": "^8.3.1",
"uuid": "^3.4.0", "vue": "^2.6.12",
"vue": "^2.6.11",
"webextension-polyfill": "^0.6.0" "webextension-polyfill": "^0.6.0"
}, },
"devDependencies": { "devDependencies": {
"@babel/core": "^7.8.4", "@babel/core": "^7.11.6",
"@babel/preset-env": "^7.8.4", "@babel/preset-env": "^7.11.5",
"autoprefixer": "^9.7.4", "autoprefixer": "^9.8.6",
"babel-loader": "^8.0.6", "babel-loader": "^8.1.0",
"babel-plugin-lodash": "^3.3.4", "babel-plugin-lodash": "^3.3.4",
"babel-preset-minify": "^0.5.1", "babel-preset-minify": "^0.5.1",
"cross-env": "^7.0.0", "cross-env": "^7.0.2",
"css-loader": "^3.4.2", "css-loader": "^4.3.0",
"cssnano": "^4.1.10", "cssnano": "^4.1.10",
"del": "^5.1.0", "del": "^6.0.0",
"fs-extra": "^8.1.0", "fs-extra": "^9.0.1",
"gulp": "^4.0.2", "gulp": "^4.0.2",
"gulp-babel": "^8.0.0", "gulp-babel": "^8.0.0",
"gulp-htmlmin": "^5.0.1", "gulp-htmlmin": "^5.0.1",
"gulp-if": "^3.0.0", "gulp-if": "^3.0.0",
"gulp-imagemin": "^7.1.0", "gulp-imagemin": "^7.1.0",
"gulp-jsonmin": "^1.2.0", "gulp-jsonmin": "^1.2.0",
"gulp-merge-json": "^2.0.0", "gulp-merge-json": "^2.1.1",
"gulp-postcss": "^8.0.0", "gulp-postcss": "^8.0.0",
"gulp-svgmin": "^2.2.0",
"lodash-webpack-plugin": "^0.11.5", "lodash-webpack-plugin": "^0.11.5",
"mini-css-extract-plugin": "^0.9.0", "mini-css-extract-plugin": "^0.12.0",
"npm-check-updates": "^4.0.1", "npm-check-updates": "^9.0.4",
"npm-run-all": "^4.1.5", "npm-run-all": "^4.1.5",
"postcss-loader": "^3.0.0", "postcss-loader": "^3.0.0",
"prettier": "^1.19.1", "prettier": "^2.1.2",
"sass": "^1.25.0", "sass": "^1.26.12",
"sass-loader": "^8.0.2", "sass-loader": "^10.0.2",
"standard-version": "^7.1.0", "sharp": "^0.26.1",
"svg2png": "^4.1.1", "standard-version": "^9.0.0",
"vue-loader": "^15.8.3", "vue-loader": "^15.9.3",
"vue-template-compiler": "^2.6.11", "vue-template-compiler": "^2.6.12",
"web-ext": "^4.0.0", "web-ext": "^5.2.0",
"webpack": "^4.41.6", "webpack": "^4.44.2",
"webpack-bundle-analyzer": "^3.6.0", "webpack-bundle-analyzer": "^3.9.0",
"webpack-cli": "^3.3.11" "webpack-cli": "^3.3.12"
}, },
"private": true "private": true
} }

@ -3,7 +3,7 @@
font-style: normal; font-style: normal;
font-weight: 400; font-weight: 400;
src: local('Roboto'), local('Roboto-Regular'), src: local('Roboto'), local('Roboto-Regular'),
url('./files/roboto-latin-400.woff2') format('woff2'); url('./files/roboto-latin-400-normal.woff2') format('woff2');
} }
@font-face { @font-face {
@ -11,7 +11,7 @@
font-style: normal; font-style: normal;
font-weight: 500; font-weight: 500;
src: local('Roboto Medium'), local('Roboto-Medium'), src: local('Roboto Medium'), local('Roboto-Medium'),
url('./files/roboto-latin-500.woff2') format('woff2'); url('./files/roboto-latin-500-normal.woff2') format('woff2');
} }
@font-face { @font-face {
@ -19,5 +19,5 @@
font-style: normal; font-style: normal;
font-weight: 700; font-weight: 700;
src: local('Roboto Bold'), local('Roboto-Bold'), src: local('Roboto Bold'), local('Roboto-Bold'),
url('./files/roboto-latin-700.woff2') format('woff2'); url('./files/roboto-latin-700-normal.woff2') format('woff2');
} }

@ -1,5 +1,5 @@
import browser from 'webextension-polyfill'; import browser from 'webextension-polyfill';
import uuidV4 from 'uuid/v4'; import {v4 as uuidv4} from 'uuid';
import { import {
getText, getText,
@ -48,13 +48,13 @@ async function showContributePage(action = false) {
} }
function meanSleep(ms) { function meanSleep(ms) {
const maxDeviation = (10 / 100) * ms; const maxDeviation = 0.1 * ms;
return sleep(getRandomInt(ms - maxDeviation, ms + maxDeviation)); return sleep(getRandomInt(ms - maxDeviation, ms + maxDeviation));
} }
function sendNativeMessage(port, message, {timeout = 10000} = {}) { function sendNativeMessage(port, message, {timeout = 10000} = {}) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
const id = uuidV4(); const id = uuidv4();
message.id = id; message.id = id;
const messageCallback = function(msg) { const messageCallback = function(msg) {

File diff suppressed because it is too large Load Diff
Loading…
Cancel
Save