feat: wip: desktop version

release/desktop
moonrailgun 3 years ago
parent dc5c27afd6
commit 1913c9d9bc

@ -0,0 +1,12 @@
root = true
[*]
indent_style = space
indent_size = 2
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
[*.md]
trim_trailing_whitespace = false

@ -0,0 +1,7 @@
{
"rules": {
"no-console": "off",
"global-require": "off",
"import/no-dynamic-require": "off"
}
}

@ -0,0 +1,11 @@
import webWebpackConfig from '../../../web/build/webpack.config';
import type { Configuration } from 'webpack';
export function getWebTailchatWebpackConfig(): Configuration {
return {
...webWebpackConfig,
plugins: webWebpackConfig.plugins?.filter(
(p) => !['GenerateSW'].includes(p.constructor.name)
),
};
}

@ -0,0 +1,62 @@
/**
* Base webpack config used across other specific configs
*/
import webpack from 'webpack';
import webpackPaths from './webpack.paths';
import { dependencies as externals } from '../../release/app/package.json';
const configuration: webpack.Configuration = {
externals: [...Object.keys(externals || {})],
stats: 'errors-only',
module: {
rules: [
{
test: /\.[jt]sx?$/,
exclude: /node_modules/,
use: {
loader: 'ts-loader',
options: {
// Remove this line to enable type checking in webpack builds
transpileOnly: true,
},
},
},
],
},
output: {
path: webpackPaths.srcPath,
// https://github.com/webpack/webpack/issues/1114
library: {
type: 'commonjs2',
},
},
/**
* Determine the array of extensions that should be used to resolve modules.
*/
resolve: {
extensions: ['.js', '.jsx', '.json', '.ts', '.tsx'],
modules: [webpackPaths.srcPath, 'node_modules'],
fallback: {
crypto: require.resolve('crypto-browserify'),
http: require.resolve('stream-http'),
https: require.resolve('https-browserify'),
path: require.resolve('path-browserify'),
stream: require.resolve('stream-browserify'),
url: require.resolve('url/'),
fs: false,
},
},
plugins: [
new webpack.EnvironmentPlugin({
NODE_ENV: 'production',
}),
],
};
export default configuration;

@ -0,0 +1,3 @@
/* eslint import/no-unresolved: off, import/no-self-import: off */
module.exports = require('./webpack.config.renderer.dev').default;

@ -0,0 +1,82 @@
/**
* Webpack config for production electron main process
*/
import path from 'path';
import webpack from 'webpack';
import { merge } from 'webpack-merge';
import TerserPlugin from 'terser-webpack-plugin';
import { BundleAnalyzerPlugin } from 'webpack-bundle-analyzer';
import baseConfig from './webpack.config.base';
import webpackPaths from './webpack.paths';
import checkNodeEnv from '../scripts/check-node-env';
import deleteSourceMaps from '../scripts/delete-source-maps';
checkNodeEnv('production');
deleteSourceMaps();
const devtoolsConfig =
process.env.DEBUG_PROD === 'true'
? {
devtool: 'source-map',
}
: {};
const configuration: webpack.Configuration = {
...devtoolsConfig,
mode: 'production',
target: 'electron-main',
entry: {
main: path.join(webpackPaths.srcMainPath, 'main.ts'),
preload: path.join(webpackPaths.srcMainPath, 'preload.ts'),
},
output: {
path: webpackPaths.distMainPath,
filename: '[name].js',
},
optimization: {
minimizer: [
new TerserPlugin({
parallel: true,
}),
],
},
plugins: [
new BundleAnalyzerPlugin({
analyzerMode: process.env.ANALYZE === 'true' ? 'server' : 'disabled',
}),
/**
* Create global constants which can be configured at compile time.
*
* Useful for allowing different behaviour between development builds and
* release builds
*
* NODE_ENV should be production so that modules do not perform certain
* development checks
*/
new webpack.EnvironmentPlugin({
NODE_ENV: 'production',
DEBUG_PROD: false,
START_MINIMIZED: false,
}),
],
/**
* Disables webpack processing of __dirname and __filename.
* If you run the bundle in node.js it falls back to these values of node.js.
* https://github.com/webpack/webpack/issues/2010
*/
node: {
__dirname: false,
__filename: false,
},
};
export default merge(baseConfig, configuration);

@ -0,0 +1,68 @@
import path from 'path';
import webpack from 'webpack';
import { merge } from 'webpack-merge';
import { BundleAnalyzerPlugin } from 'webpack-bundle-analyzer';
import baseConfig from './webpack.config.base';
import webpackPaths from './webpack.paths';
import checkNodeEnv from '../scripts/check-node-env';
// When an ESLint server is running, we can't set the NODE_ENV so we'll check if it's
// at the dev webpack config is not accidentally run in a production environment
if (process.env.NODE_ENV === 'production') {
checkNodeEnv('development');
}
const configuration: webpack.Configuration = {
devtool: 'inline-source-map',
mode: 'development',
target: 'electron-preload',
entry: path.join(webpackPaths.srcMainPath, 'preload.ts'),
output: {
path: webpackPaths.dllPath,
filename: 'preload.js',
},
plugins: [
new BundleAnalyzerPlugin({
analyzerMode: process.env.ANALYZE === 'true' ? 'server' : 'disabled',
}),
/**
* Create global constants which can be configured at compile time.
*
* Useful for allowing different behaviour between development builds and
* release builds
*
* NODE_ENV should be production so that modules do not perform certain
* development checks
*
* By default, use 'development' as NODE_ENV. This can be overriden with
* 'staging', for example, by changing the ENV variables in the npm scripts
*/
new webpack.EnvironmentPlugin({
NODE_ENV: 'development',
}),
new webpack.LoaderOptionsPlugin({
debug: true,
}),
],
/**
* Disables webpack processing of __dirname and __filename.
* If you run the bundle in node.js it falls back to these values of node.js.
* https://github.com/webpack/webpack/issues/2010
*/
node: {
__dirname: false,
__filename: false,
},
watch: true,
};
export default merge(baseConfig, configuration);

@ -0,0 +1,62 @@
import 'webpack-dev-server';
import type { Configuration } from 'webpack';
import { spawn } from 'child_process';
import { getWebTailchatWebpackConfig } from './utils';
require('dotenv').config();
const port = process.env.PORT || 1212;
const webWebpackConfig = getWebTailchatWebpackConfig();
const configuration: Configuration = {
...webWebpackConfig,
entry: [
`webpack-dev-server/client?http://localhost:${port}/dist`,
'webpack/hot/only-dev-server',
webWebpackConfig.entry?.['app'],
],
resolveLoader: {
alias: {
'source-ref-loader': require.resolve(
'../../../packages/source-ref-loader/src/index.ts'
),
},
},
target: ['web', 'electron-renderer'],
devServer: {
port,
compress: true,
hot: true,
headers: { 'Access-Control-Allow-Origin': '*' },
static: {
publicPath: '/',
},
historyApiFallback: {
verbose: true,
},
setupMiddlewares(middlewares) {
console.log('Starting preload.js builder...');
const preloadProcess = spawn('npm', ['run', 'start:preload'], {
shell: true,
stdio: 'inherit',
})
.on('close', (code: number) => process.exit(code!))
.on('error', (spawnError) => console.error(spawnError));
console.log('Starting Main Process...');
spawn('npm', ['run', 'start:main'], {
shell: true,
stdio: 'inherit',
})
.on('close', (code: number) => {
preloadProcess.kill();
process.exit(code!);
})
.on('error', (spawnError) => console.error(spawnError));
return middlewares;
},
},
};
export default configuration;

@ -0,0 +1,18 @@
import type { Configuration } from 'webpack';
import { getWebTailchatWebpackConfig } from './utils';
const webWebpackConfig = getWebTailchatWebpackConfig();
const configuration: Configuration = {
...webWebpackConfig,
resolveLoader: {
alias: {
'source-ref-loader': require.resolve(
'../../../packages/source-ref-loader/src/index.ts'
),
},
},
target: 'electron-renderer',
};
export default configuration;

@ -0,0 +1,42 @@
const path = require('path');
const rootPath = path.join(__dirname, '../..');
const dllPath = path.join(__dirname, '../dll');
const srcPath = path.join(rootPath, 'src');
const srcMainPath = path.join(srcPath, 'main');
const srcRendererPath = path.join(srcPath, 'renderer');
const srcPublicPath = path.join(rootPath, '../app/public');
const releasePath = path.join(rootPath, 'release');
const appPath = path.join(releasePath, 'app');
const appPackagePath = path.join(appPath, 'package.json');
const appNodeModulesPath = path.join(appPath, 'node_modules');
const srcNodeModulesPath = path.join(srcPath, 'node_modules');
const distPath = path.join(appPath, 'dist');
const distMainPath = path.join(distPath, 'main');
const distRendererPath = path.join(distPath, 'renderer');
const distPublicPath = path.join(distRendererPath, 'public');
const buildPath = path.join(releasePath, 'build');
export default {
rootPath,
dllPath,
srcPath,
srcMainPath,
srcRendererPath,
releasePath,
appPath,
appPackagePath,
appNodeModulesPath,
srcNodeModulesPath,
distPath,
distMainPath,
distRendererPath,
buildPath,
srcPublicPath,
distPublicPath,
};

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

@ -0,0 +1 @@
export default 'test-file-stub';

@ -0,0 +1,8 @@
{
"rules": {
"no-console": "off",
"global-require": "off",
"import/no-dynamic-require": "off",
"import/no-extraneous-dependencies": "off"
}
}

@ -0,0 +1,24 @@
// Check if the renderer and main bundles are built
import path from 'path';
import chalk from 'chalk';
import fs from 'fs';
import webpackPaths from '../configs/webpack.paths';
const mainPath = path.join(webpackPaths.distMainPath, 'main.js');
const rendererPath = path.join(webpackPaths.distRendererPath, 'renderer.js');
if (!fs.existsSync(mainPath)) {
throw new Error(
chalk.whiteBright.bgRed.bold(
'The main process is not built yet. Build it by running "npm run build:main"'
)
);
}
if (!fs.existsSync(rendererPath)) {
throw new Error(
chalk.whiteBright.bgRed.bold(
'The renderer process is not built yet. Build it by running "npm run build:renderer"'
)
);
}

@ -0,0 +1,54 @@
import fs from 'fs';
import chalk from 'chalk';
import { execSync } from 'child_process';
import { dependencies } from '../../package.json';
if (dependencies) {
const dependenciesKeys = Object.keys(dependencies);
const nativeDeps = fs
.readdirSync('node_modules')
.filter((folder) => fs.existsSync(`node_modules/${folder}/binding.gyp`));
if (nativeDeps.length === 0) {
process.exit(0);
}
try {
// Find the reason for why the dependency is installed. If it is installed
// because of a devDependency then that is okay. Warn when it is installed
// because of a dependency
const { dependencies: dependenciesObject } = JSON.parse(
execSync(`npm ls ${nativeDeps.join(' ')} --json`).toString()
);
const rootDependencies = Object.keys(dependenciesObject);
const filteredRootDependencies = rootDependencies.filter((rootDependency) =>
dependenciesKeys.includes(rootDependency)
);
if (filteredRootDependencies.length > 0) {
const plural = filteredRootDependencies.length > 1;
console.log(`
${chalk.whiteBright.bgYellow.bold(
'Webpack does not work with native dependencies.'
)}
${chalk.bold(filteredRootDependencies.join(', '))} ${
plural ? 'are native dependencies' : 'is a native dependency'
} and should be installed inside of the "./release/app" folder.
First, uninstall the packages from "./package.json":
${chalk.whiteBright.bgGreen.bold('npm uninstall your-package')}
${chalk.bold(
'Then, instead of installing the package to the root "./package.json":'
)}
${chalk.whiteBright.bgRed.bold('npm install your-package')}
${chalk.bold('Install the package to "./release/app/package.json"')}
${chalk.whiteBright.bgGreen.bold(
'cd ./release/app && npm install your-package'
)}
Read more about native dependencies at:
${chalk.bold(
'https://electron-react-boilerplate.js.org/docs/adding-dependencies/#module-structure'
)}
`);
process.exit(1);
}
} catch (e) {
console.log('Native dependencies could not be checked');
}
}

@ -0,0 +1,16 @@
import chalk from 'chalk';
export default function checkNodeEnv(expectedEnv) {
if (!expectedEnv) {
throw new Error('"expectedEnv" not set');
}
if (process.env.NODE_ENV !== expectedEnv) {
console.log(
chalk.whiteBright.bgRed.bold(
`"process.env.NODE_ENV" must be "${expectedEnv}" to use this webpack config`
)
);
process.exit(2);
}
}

@ -0,0 +1,16 @@
import chalk from 'chalk';
import detectPort from 'detect-port';
const port = process.env.PORT || '1212';
detectPort(port, (err, availablePort) => {
if (port !== String(availablePort)) {
throw new Error(
chalk.whiteBright.bgRed.bold(
`Port "${port}" on "localhost" is already in use. Please use another port. ex: PORT=4343 npm start`
)
);
} else {
process.exit(0);
}
});

@ -0,0 +1,17 @@
import rimraf from 'rimraf';
import process from 'process';
import webpackPaths from '../configs/webpack.paths';
const args = process.argv.slice(2);
const commandMap = {
dist: webpackPaths.distPath,
release: webpackPaths.releasePath,
dll: webpackPaths.dllPath,
};
args.forEach((x) => {
const pathToRemove = commandMap[x];
if (pathToRemove !== undefined) {
rimraf.sync(pathToRemove);
}
});

@ -0,0 +1,8 @@
import path from 'path';
import rimraf from 'rimraf';
import webpackPaths from '../configs/webpack.paths';
export default function deleteSourceMaps() {
rimraf.sync(path.join(webpackPaths.distMainPath, '*.js.map'));
rimraf.sync(path.join(webpackPaths.distRendererPath, '*.js.map'));
}

@ -0,0 +1,20 @@
import { execSync } from 'child_process';
import fs from 'fs';
import { dependencies } from '../../release/app/package.json';
import webpackPaths from '../configs/webpack.paths';
if (
Object.keys(dependencies || {}).length > 0 &&
fs.existsSync(webpackPaths.appNodeModulesPath)
) {
const electronRebuildCmd =
'../../node_modules/.bin/electron-rebuild --force --types prod,dev,optional --module-dir .';
const cmd =
process.platform === 'win32'
? electronRebuildCmd.replace(/\//g, '\\')
: electronRebuildCmd;
execSync(cmd, {
cwd: webpackPaths.appPath,
stdio: 'inherit',
});
}

@ -0,0 +1,9 @@
import fs from 'fs';
import webpackPaths from '../configs/webpack.paths';
const { srcNodeModulesPath } = webpackPaths;
const { appNodeModulesPath } = webpackPaths;
if (!fs.existsSync(srcNodeModulesPath) && fs.existsSync(appNodeModulesPath)) {
fs.symlinkSync(appNodeModulesPath, srcNodeModulesPath, 'junction');
}

@ -0,0 +1,30 @@
const { notarize } = require('electron-notarize');
const { build } = require('../../package.json');
exports.default = async function notarizeMacos(context) {
const { electronPlatformName, appOutDir } = context;
if (electronPlatformName !== 'darwin') {
return;
}
if (process.env.CI !== 'true') {
console.warn('Skipping notarizing step. Packaging is not running in CI');
return;
}
if (!('APPLE_ID' in process.env && 'APPLE_ID_PASS' in process.env)) {
console.warn(
'Skipping notarizing step. APPLE_ID and APPLE_ID_PASS env variables must be set'
);
return;
}
const appName = context.packager.appInfo.productFilename;
await notarize({
appBundleId: build.appId,
appPath: `${appOutDir}/${appName}.app`,
appleId: process.env.APPLE_ID,
appleIdPassword: process.env.APPLE_ID_PASS,
});
};

@ -0,0 +1,12 @@
* text eol=lf
*.exe binary
*.png binary
*.jpg binary
*.jpeg binary
*.ico binary
*.icns binary
*.eot binary
*.otf binary
*.ttf binary
*.woff binary
*.woff2 binary

@ -0,0 +1,46 @@
name: Publish
on:
push:
branches:
- main
jobs:
publish:
# To enable auto publishing to github, update your electron publisher
# config in package.json > "build" and remove the conditional below
if: ${{ github.repository_owner == 'electron-react-boilerplate' }}
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [macos-latest]
steps:
- name: Checkout git repo
uses: actions/checkout@v1
- name: Install Node and NPM
uses: actions/setup-node@v1
with:
node-version: 16
cache: npm
- name: Install dependencies
run: |
npm install
- name: Publish releases
env:
# These values are used for auto updates signing
APPLE_ID: ${{ secrets.APPLE_ID }}
APPLE_ID_PASS: ${{ secrets.APPLE_ID_PASS }}
CSC_LINK: ${{ secrets.CSC_LINK }}
CSC_KEY_PASSWORD: ${{ secrets.CSC_KEY_PASSWORD }}
# This is used for uploading release assets to github
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
npm run postinstall
npm run build
npm exec electron-builder -- --publish always --win --mac --linux

@ -0,0 +1,34 @@
name: Test
on: [push, pull_request]
jobs:
test:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [macos-latest, windows-latest, ubuntu-latest]
steps:
- name: Check out Git repository
uses: actions/checkout@v1
- name: Install Node.js and NPM
uses: actions/setup-node@v2
with:
node-version: 16
cache: npm
- name: npm install
run: |
npm install
- name: npm test
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
npm run package
npm run lint
npm exec tsc
npm test

32
desktop/.gitignore vendored

@ -0,0 +1,32 @@
# Logs
logs
*.log
# Runtime data
pids
*.pid
*.seed
# Coverage directory used by tools like istanbul
coverage
.eslintcache
# Dependency directory
# https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git
node_modules
# OSX
.DS_Store
release/app/dist
release/app/public
release/build
.erb/dll
.idea
npm-debug.log.*
*.css.d.ts
*.sass.d.ts
*.scss.d.ts
src/renderer/config/index.ts

@ -0,0 +1,3 @@
# https://npmmirror.com/
registry = https://registry.npmmirror.com
electron_mirror = https://npmmirror.com/mirrors/electron/

@ -0,0 +1,3 @@
{
"recommendations": ["dbaeumer.vscode-eslint", "EditorConfig.EditorConfig"]
}

@ -0,0 +1,30 @@
{
"version": "0.2.0",
"configurations": [
{
"name": "Electron: Main",
"type": "node",
"request": "launch",
"protocol": "inspector",
"runtimeExecutable": "npm",
"runtimeArgs": [
"run start:main --inspect=5858 --remote-debugging-port=9223"
],
"preLaunchTask": "Start Webpack Dev"
},
{
"name": "Electron: Renderer",
"type": "chrome",
"request": "attach",
"port": 9223,
"webRoot": "${workspaceFolder}",
"timeout": 15000
}
],
"compounds": [
{
"name": "Electron: All",
"configurations": ["Electron: Main", "Electron: Renderer"]
}
]
}

@ -0,0 +1,30 @@
{
"files.associations": {
".eslintrc": "jsonc",
".prettierrc": "jsonc",
".eslintignore": "ignore"
},
"eslint.validate": [
"javascript",
"javascriptreact",
"html",
"typescriptreact"
],
"javascript.validate.enable": false,
"javascript.format.enable": false,
"typescript.format.enable": false,
"search.exclude": {
".git": true,
".eslintcache": true,
".erb/dll": true,
"release/{build,app/dist}": true,
"node_modules": true,
"npm-debug.log.*": true,
"test/**/__snapshots__": true,
"package-lock.json": true,
"*.{css,sass,scss}.d.ts": true
}
}

@ -0,0 +1,25 @@
{
"version": "2.0.0",
"tasks": [
{
"type": "npm",
"label": "Start Webpack Dev",
"script": "start:renderer",
"options": {
"cwd": "${workspaceFolder}"
},
"isBackground": true,
"problemMatcher": {
"owner": "custom",
"pattern": {
"regexp": "____________"
},
"background": {
"activeOnStart": true,
"beginsPattern": "Compiling\\.\\.\\.$",
"endsPattern": "(Compiled successfully|Failed to compile)\\.$"
}
}
}
]
}

@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2015-present Electron React Boilerplate
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

@ -0,0 +1,153 @@
<img src=".erb/img/erb-banner.svg" width="100%" />
<br>
<p>
Electron React Boilerplate uses <a href="https://electron.atom.io/">Electron</a>, <a href="https://facebook.github.io/react/">React</a>, <a href="https://github.com/reactjs/react-router">React Router</a>, <a href="https://webpack.js.org/">Webpack</a> and <a href="https://www.npmjs.com/package/react-refresh">React Fast Refresh</a>.
</p>
<br>
<div align="center">
[![Build Status][github-actions-status]][github-actions-url]
[![Github Tag][github-tag-image]][github-tag-url]
[![Discord](https://badgen.net/badge/icon/discord?icon=discord&label)](https://discord.gg/Fjy3vfgy5q)
[![OpenCollective](https://opencollective.com/electron-react-boilerplate-594/backers/badge.svg)](#backers)
[![OpenCollective](https://opencollective.com/electron-react-boilerplate-594/sponsors/badge.svg)](#sponsors)
[![StackOverflow][stackoverflow-img]][stackoverflow-url]
</div>
## Install
Clone the repo and install dependencies:
```bash
git clone --depth 1 --branch main https://github.com/electron-react-boilerplate/electron-react-boilerplate.git your-project-name
cd your-project-name
npm install
```
**Having issues installing? See our [debugging guide](https://github.com/electron-react-boilerplate/electron-react-boilerplate/issues/400)**
## Starting Development
Start the app in the `dev` environment:
```bash
npm start
```
## Packaging for Production
To package apps for the local platform:
```bash
npm run package
```
## Docs
See our [docs and guides here](https://electron-react-boilerplate.js.org/docs/installation)
## Community
Join our Discord: https://discord.gg/Fjy3vfgy5q
## Donations
**Donations will ensure the following:**
- 🔨 Long term maintenance of the project
- 🛣 Progress on the [roadmap](https://electron-react-boilerplate.js.org/docs/roadmap)
- 🐛 Quick responses to bug reports and help requests
## Backers
Support us with a monthly donation and help us continue our activities. [[Become a backer](https://opencollective.com/electron-react-boilerplate-594#backer)]
<a href="https://opencollective.com/electron-react-boilerplate-594/backer/0/website" target="_blank"><img src="https://opencollective.com/electron-react-boilerplate-594/backer/0/avatar.svg"></a>
<a href="https://opencollective.com/electron-react-boilerplate-594/backer/1/website" target="_blank"><img src="https://opencollective.com/electron-react-boilerplate-594/backer/1/avatar.svg"></a>
<a href="https://opencollective.com/electron-react-boilerplate-594/backer/2/website" target="_blank"><img src="https://opencollective.com/electron-react-boilerplate-594/backer/2/avatar.svg"></a>
<a href="https://opencollective.com/electron-react-boilerplate-594/backer/3/website" target="_blank"><img src="https://opencollective.com/electron-react-boilerplate-594/backer/3/avatar.svg"></a>
<a href="https://opencollective.com/electron-react-boilerplate-594/backer/4/website" target="_blank"><img src="https://opencollective.com/electron-react-boilerplate-594/backer/4/avatar.svg"></a>
<a href="https://opencollective.com/electron-react-boilerplate-594/backer/5/website" target="_blank"><img src="https://opencollective.com/electron-react-boilerplate-594/backer/5/avatar.svg"></a>
<a href="https://opencollective.com/electron-react-boilerplate-594/backer/6/website" target="_blank"><img src="https://opencollective.com/electron-react-boilerplate-594/backer/6/avatar.svg"></a>
<a href="https://opencollective.com/electron-react-boilerplate-594/backer/7/website" target="_blank"><img src="https://opencollective.com/electron-react-boilerplate-594/backer/7/avatar.svg"></a>
<a href="https://opencollective.com/electron-react-boilerplate-594/backer/8/website" target="_blank"><img src="https://opencollective.com/electron-react-boilerplate-594/backer/8/avatar.svg"></a>
<a href="https://opencollective.com/electron-react-boilerplate-594/backer/9/website" target="_blank"><img src="https://opencollective.com/electron-react-boilerplate-594/backer/9/avatar.svg"></a>
<a href="https://opencollective.com/electron-react-boilerplate-594/backer/10/website" target="_blank"><img src="https://opencollective.com/electron-react-boilerplate-594/backer/10/avatar.svg"></a>
<a href="https://opencollective.com/electron-react-boilerplate-594/backer/11/website" target="_blank"><img src="https://opencollective.com/electron-react-boilerplate-594/backer/11/avatar.svg"></a>
<a href="https://opencollective.com/electron-react-boilerplate-594/backer/12/website" target="_blank"><img src="https://opencollective.com/electron-react-boilerplate-594/backer/12/avatar.svg"></a>
<a href="https://opencollective.com/electron-react-boilerplate-594/backer/13/website" target="_blank"><img src="https://opencollective.com/electron-react-boilerplate-594/backer/13/avatar.svg"></a>
<a href="https://opencollective.com/electron-react-boilerplate-594/backer/14/website" target="_blank"><img src="https://opencollective.com/electron-react-boilerplate-594/backer/14/avatar.svg"></a>
<a href="https://opencollective.com/electron-react-boilerplate-594/backer/15/website" target="_blank"><img src="https://opencollective.com/electron-react-boilerplate-594/backer/15/avatar.svg"></a>
<a href="https://opencollective.com/electron-react-boilerplate-594/backer/16/website" target="_blank"><img src="https://opencollective.com/electron-react-boilerplate-594/backer/16/avatar.svg"></a>
<a href="https://opencollective.com/electron-react-boilerplate-594/backer/17/website" target="_blank"><img src="https://opencollective.com/electron-react-boilerplate-594/backer/17/avatar.svg"></a>
<a href="https://opencollective.com/electron-react-boilerplate-594/backer/18/website" target="_blank"><img src="https://opencollective.com/electron-react-boilerplate-594/backer/18/avatar.svg"></a>
<a href="https://opencollective.com/electron-react-boilerplate-594/backer/19/website" target="_blank"><img src="https://opencollective.com/electron-react-boilerplate-594/backer/19/avatar.svg"></a>
<a href="https://opencollective.com/electron-react-boilerplate-594/backer/20/website" target="_blank"><img src="https://opencollective.com/electron-react-boilerplate-594/backer/20/avatar.svg"></a>
<a href="https://opencollective.com/electron-react-boilerplate-594/backer/21/website" target="_blank"><img src="https://opencollective.com/electron-react-boilerplate-594/backer/21/avatar.svg"></a>
<a href="https://opencollective.com/electron-react-boilerplate-594/backer/22/website" target="_blank"><img src="https://opencollective.com/electron-react-boilerplate-594/backer/22/avatar.svg"></a>
<a href="https://opencollective.com/electron-react-boilerplate-594/backer/23/website" target="_blank"><img src="https://opencollective.com/electron-react-boilerplate-594/backer/23/avatar.svg"></a>
<a href="https://opencollective.com/electron-react-boilerplate-594/backer/24/website" target="_blank"><img src="https://opencollective.com/electron-react-boilerplate-594/backer/24/avatar.svg"></a>
<a href="https://opencollective.com/electron-react-boilerplate-594/backer/25/website" target="_blank"><img src="https://opencollective.com/electron-react-boilerplate-594/backer/25/avatar.svg"></a>
<a href="https://opencollective.com/electron-react-boilerplate-594/backer/26/website" target="_blank"><img src="https://opencollective.com/electron-react-boilerplate-594/backer/26/avatar.svg"></a>
<a href="https://opencollective.com/electron-react-boilerplate-594/backer/27/website" target="_blank"><img src="https://opencollective.com/electron-react-boilerplate-594/backer/27/avatar.svg"></a>
<a href="https://opencollective.com/electron-react-boilerplate-594/backer/28/website" target="_blank"><img src="https://opencollective.com/electron-react-boilerplate-594/backer/28/avatar.svg"></a>
<a href="https://opencollective.com/electron-react-boilerplate-594/backer/29/website" target="_blank"><img src="https://opencollective.com/electron-react-boilerplate-594/backer/29/avatar.svg"></a>
## Sponsors
Become a sponsor and get your logo on our README on Github with a link to your site. [[Become a sponsor](https://opencollective.com/electron-react-boilerplate-594-594#sponsor)]
<a href="https://opencollective.com/electron-react-boilerplate-594/sponsor/0/website" target="_blank"><img src="https://opencollective.com/electron-react-boilerplate-594/sponsor/0/avatar.svg"></a>
<a href="https://opencollective.com/electron-react-boilerplate-594/sponsor/1/website" target="_blank"><img src="https://opencollective.com/electron-react-boilerplate-594/sponsor/1/avatar.svg"></a>
<a href="https://opencollective.com/electron-react-boilerplate-594/sponsor/2/website" target="_blank"><img src="https://opencollective.com/electron-react-boilerplate-594/sponsor/2/avatar.svg"></a>
<a href="https://opencollective.com/electron-react-boilerplate-594/sponsor/3/website" target="_blank"><img src="https://opencollective.com/electron-react-boilerplate-594/sponsor/3/avatar.svg"></a>
<a href="https://opencollective.com/electron-react-boilerplate-594/sponsor/4/website" target="_blank"><img src="https://opencollective.com/electron-react-boilerplate-594/sponsor/4/avatar.svg"></a>
<a href="https://opencollective.com/electron-react-boilerplate-594/sponsor/5/website" target="_blank"><img src="https://opencollective.com/electron-react-boilerplate-594/sponsor/5/avatar.svg"></a>
<a href="https://opencollective.com/electron-react-boilerplate-594/sponsor/6/website" target="_blank"><img src="https://opencollective.com/electron-react-boilerplate-594/sponsor/6/avatar.svg"></a>
<a href="https://opencollective.com/electron-react-boilerplate-594/sponsor/7/website" target="_blank"><img src="https://opencollective.com/electron-react-boilerplate-594/sponsor/7/avatar.svg"></a>
<a href="https://opencollective.com/electron-react-boilerplate-594/sponsor/8/website" target="_blank"><img src="https://opencollective.com/electron-react-boilerplate-594/sponsor/8/avatar.svg"></a>
<a href="https://opencollective.com/electron-react-boilerplate-594/sponsor/9/website" target="_blank"><img src="https://opencollective.com/electron-react-boilerplate-594/sponsor/9/avatar.svg"></a>
<a href="https://opencollective.com/electron-react-boilerplate-594/sponsor/10/website" target="_blank"><img src="https://opencollective.com/electron-react-boilerplate-594/sponsor/10/avatar.svg"></a>
<a href="https://opencollective.com/electron-react-boilerplate-594/sponsor/11/website" target="_blank"><img src="https://opencollective.com/electron-react-boilerplate-594/sponsor/11/avatar.svg"></a>
<a href="https://opencollective.com/electron-react-boilerplate-594/sponsor/12/website" target="_blank"><img src="https://opencollective.com/electron-react-boilerplate-594/sponsor/12/avatar.svg"></a>
<a href="https://opencollective.com/electron-react-boilerplate-594/sponsor/13/website" target="_blank"><img src="https://opencollective.com/electron-react-boilerplate-594/sponsor/13/avatar.svg"></a>
<a href="https://opencollective.com/electron-react-boilerplate-594/sponsor/14/website" target="_blank"><img src="https://opencollective.com/electron-react-boilerplate-594/sponsor/14/avatar.svg"></a>
<a href="https://opencollective.com/electron-react-boilerplate-594/sponsor/15/website" target="_blank"><img src="https://opencollective.com/electron-react-boilerplate-594/sponsor/15/avatar.svg"></a>
<a href="https://opencollective.com/electron-react-boilerplate-594/sponsor/16/website" target="_blank"><img src="https://opencollective.com/electron-react-boilerplate-594/sponsor/16/avatar.svg"></a>
<a href="https://opencollective.com/electron-react-boilerplate-594/sponsor/17/website" target="_blank"><img src="https://opencollective.com/electron-react-boilerplate-594/sponsor/17/avatar.svg"></a>
<a href="https://opencollective.com/electron-react-boilerplate-594/sponsor/18/website" target="_blank"><img src="https://opencollective.com/electron-react-boilerplate-594/sponsor/18/avatar.svg"></a>
<a href="https://opencollective.com/electron-react-boilerplate-594/sponsor/19/website" target="_blank"><img src="https://opencollective.com/electron-react-boilerplate-594/sponsor/19/avatar.svg"></a>
<a href="https://opencollective.com/electron-react-boilerplate-594/sponsor/20/website" target="_blank"><img src="https://opencollective.com/electron-react-boilerplate-594/sponsor/20/avatar.svg"></a>
<a href="https://opencollective.com/electron-react-boilerplate-594/sponsor/21/website" target="_blank"><img src="https://opencollective.com/electron-react-boilerplate-594/sponsor/21/avatar.svg"></a>
<a href="https://opencollective.com/electron-react-boilerplate-594/sponsor/22/website" target="_blank"><img src="https://opencollective.com/electron-react-boilerplate-594/sponsor/22/avatar.svg"></a>
<a href="https://opencollective.com/electron-react-boilerplate-594/sponsor/23/website" target="_blank"><img src="https://opencollective.com/electron-react-boilerplate-594/sponsor/23/avatar.svg"></a>
<a href="https://opencollective.com/electron-react-boilerplate-594/sponsor/24/website" target="_blank"><img src="https://opencollective.com/electron-react-boilerplate-594/sponsor/24/avatar.svg"></a>
<a href="https://opencollective.com/electron-react-boilerplate-594/sponsor/25/website" target="_blank"><img src="https://opencollective.com/electron-react-boilerplate-594/sponsor/25/avatar.svg"></a>
<a href="https://opencollective.com/electron-react-boilerplate-594/sponsor/26/website" target="_blank"><img src="https://opencollective.com/electron-react-boilerplate-594/sponsor/26/avatar.svg"></a>
<a href="https://opencollective.com/electron-react-boilerplate-594/sponsor/27/website" target="_blank"><img src="https://opencollective.com/electron-react-boilerplate-594/sponsor/27/avatar.svg"></a>
<a href="https://opencollective.com/electron-react-boilerplate-594/sponsor/28/website" target="_blank"><img src="https://opencollective.com/electron-react-boilerplate-594/sponsor/28/avatar.svg"></a>
<a href="https://opencollective.com/electron-react-boilerplate-594/sponsor/29/website" target="_blank"><img src="https://opencollective.com/electron-react-boilerplate-594/sponsor/29/avatar.svg"></a>
## Maintainers
- [Amila Welihinda](https://github.com/amilajack)
- [John Tran](https://github.com/jooohhn)
- [C. T. Lin](https://github.com/chentsulin)
- [Jhen-Jie Hong](https://github.com/jhen0409)
## License
MIT © [Electron React Boilerplate](https://github.com/electron-react-boilerplate)
[github-actions-status]: https://github.com/electron-react-boilerplate/electron-react-boilerplate/workflows/Test/badge.svg
[github-actions-url]: https://github.com/electron-react-boilerplate/electron-react-boilerplate/actions
[github-tag-image]: https://img.shields.io/github/tag/electron-react-boilerplate/electron-react-boilerplate.svg?label=version
[github-tag-url]: https://github.com/electron-react-boilerplate/electron-react-boilerplate/releases/latest
[stackoverflow-img]: https://img.shields.io/badge/stackoverflow-electron_react_boilerplate-blue.svg
[stackoverflow-url]: https://stackoverflow.com/questions/tagged/electron-react-boilerplate

@ -0,0 +1,31 @@
type Styles = Record<string, string>;
declare module '*.svg' {
const content: string;
export default content;
}
declare module '*.png' {
const content: string;
export default content;
}
declare module '*.jpg' {
const content: string;
export default content;
}
declare module '*.scss' {
const content: Styles;
export default content;
}
declare module '*.sass' {
const content: Styles;
export default content;
}
declare module '*.css' {
const content: Styles;
export default content;
}

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.cs.allow-unsigned-executable-memory</key>
<true/>
<key>com.apple.security.cs.allow-jit</key>
<true/>
</dict>
</plist>

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 126 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 16 KiB

@ -0,0 +1,46 @@
productName: Tailchat
appId: com.msgbyte.tailchat
asar: true
asarUnpack: '**\*.{node,dll}'
files:
- dist
- node_modules
- package.json
afterSign: .erb/scripts/notarize.js
mac:
target:
target: default
arch:
- arm64
- x64
type: distribution
hardenedRuntime: true
entitlements: assets/entitlements.mac.plist
entitlementsInherit: assets/entitlements.mac.plist
gatekeeperAssess: false
dmg:
contents:
- x: 130
y: 220
- x: 410
y: 220
type: link
path: /Applications
win:
target:
- zip
# - nsis
linux:
target:
- AppImage
category: Development
directories:
app: release/app
buildResources: assets
output: release/build
extraResources:
- ./assets/**
publish:
provider: github
owner: msgbyte
repo: tailchat

@ -0,0 +1,213 @@
{
"description": "A foundation for scalable desktop apps",
"private": true,
"keywords": [
"electron",
"boilerplate",
"react",
"typescript",
"ts",
"sass",
"webpack",
"hot",
"reload"
],
"homepage": "https://github.com/electron-react-boilerplate/electron-react-boilerplate#readme",
"bugs": {
"url": "https://github.com/electron-react-boilerplate/electron-react-boilerplate/issues"
},
"repository": {
"type": "git",
"url": "git+https://github.com/electron-react-boilerplate/electron-react-boilerplate.git"
},
"license": "MIT",
"author": {
"name": "moonrailgun",
"email": "moonrailgun@gmail.com",
"url": "https://github.com/moonrailgun"
},
"contributors": [
{
"name": "Amila Welihinda",
"email": "amilajack@gmail.com",
"url": "https://github.com/amilajack"
}
],
"main": "./src/main/main.ts",
"scripts": {
"build": "concurrently \"npm run build:main\" \"npm run build:renderer\"",
"build:main": "cross-env NODE_ENV=production TS_NODE_TRANSPILE_ONLY=true webpack --config ./.erb/configs/webpack.config.main.prod.ts",
"build:renderer": "cross-env NODE_ENV=production TS_NODE_TRANSPILE_ONLY=true webpack --config ./.erb/configs/webpack.config.renderer.prod.ts",
"postinstall": "ts-node .erb/scripts/check-native-dep.js && electron-builder install-app-deps",
"lint": "cross-env NODE_ENV=development eslint . --ext .js,.jsx,.ts,.tsx",
"package": "ts-node ./.erb/scripts/clean.js dist && npm run build && electron-builder build --publish never",
"package:debug": "cross-env DEBUG_PROD=true yarn package",
"rebuild": "electron-rebuild --parallel --types prod,dev,optional --module-dir release/app",
"start": "ts-node ./.erb/scripts/check-port-in-use.js && npm run start:renderer",
"start:main": "cross-env NODE_ENV=development electronmon -r ts-node/register/transpile-only .",
"start:preload": "cross-env NODE_ENV=development TS_NODE_TRANSPILE_ONLY=true webpack --config ./.erb/configs/webpack.config.preload.dev.ts",
"start:renderer": "cross-env NODE_ENV=development TS_NODE_TRANSPILE_ONLY=true webpack serve --config ./.erb/configs/webpack.config.renderer.dev.ts",
"test": "jest"
},
"lint-staged": {
"*.{js,jsx,ts,tsx}": [
"cross-env NODE_ENV=development eslint --cache"
],
"*.json,.{eslintrc,prettierrc}": [
"prettier --ignore-path .eslintignore --parser json --write"
],
"*.{css,scss}": [
"prettier --ignore-path .eslintignore --single-quote --write"
],
"*.{html,md,yml}": [
"prettier --ignore-path .eslintignore --single-quote --write"
]
},
"browserslist": [],
"prettier": {
"singleQuote": true,
"overrides": [
{
"files": [
".prettierrc",
".eslintrc"
],
"options": {
"parser": "json"
}
}
]
},
"jest": {
"moduleDirectories": [
"node_modules",
"release/app/node_modules"
],
"moduleFileExtensions": [
"js",
"jsx",
"ts",
"tsx",
"json"
],
"moduleNameMapper": {
"\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/.erb/mocks/fileMock.js",
"\\.(css|less|sass|scss)$": "identity-obj-proxy"
},
"setupFiles": [
"./.erb/scripts/check-build-exists.ts"
],
"testEnvironment": "jsdom",
"testEnvironmentOptions": {
"url": "http://localhost/"
},
"testPathIgnorePatterns": [
"release/app/dist"
],
"transform": {
"\\.(ts|tsx|js|jsx)$": "ts-jest"
}
},
"dependencies": {
"electron-debug": "^3.2.0",
"electron-log": "^4.4.7",
"electron-serve": "^1.1.0",
"electron-updater": "^5.0.1",
"electron-window-state": "^5.0.3",
"react": "^18.1.0",
"react-dom": "^18.1.0",
"react-router-dom": "^6.3.0"
},
"devDependencies": {
"@pmmmwh/react-refresh-webpack-plugin": "^0.5.6",
"@svgr/webpack": "^6.2.1",
"@teamsupercell/typings-for-css-modules-loader": "^2.5.1",
"@testing-library/jest-dom": "^5.16.4",
"@testing-library/react": "^13.2.0",
"@types/jest": "^27.5.1",
"@types/node": "^17.0.42",
"@types/react": "^18.0.9",
"@types/react-dom": "^18.0.4",
"@types/react-test-renderer": "^18.0.0",
"@types/terser-webpack-plugin": "^5.0.4",
"@types/webpack-bundle-analyzer": "^4.4.1",
"@typescript-eslint/eslint-plugin": "^5.23.0",
"@typescript-eslint/parser": "^5.23.0",
"autoprefixer": "^10.4.7",
"browserslist-config-erb": "^0.0.3",
"chalk": "^4.1.2",
"concurrently": "^7.1.0",
"copy-webpack-plugin": "^11.0.0",
"core-js": "^3.22.5",
"cross-env": "^7.0.3",
"crypto-browserify": "^3.12.0",
"css-loader": "^6.7.1",
"css-minimizer-webpack-plugin": "^3.4.1",
"detect-port": "^1.3.0",
"dotenv": "^16.0.1",
"electron": "^18.2.3",
"electron-builder": "^23.0.3",
"electron-devtools-installer": "^3.2.0",
"electron-notarize": "^1.2.1",
"electron-rebuild": "^3.2.7",
"electronmon": "^2.0.2",
"esbuild-loader": "^2.19.0",
"eslint": "^8.15.0",
"eslint-config-airbnb-base": "^15.0.0",
"eslint-config-erb": "^4.0.3",
"eslint-import-resolver-typescript": "^2.7.1",
"eslint-import-resolver-webpack": "^0.13.2",
"eslint-plugin-compat": "^4.0.2",
"eslint-plugin-import": "^2.26.0",
"eslint-plugin-jest": "^26.2.2",
"eslint-plugin-jsx-a11y": "^6.5.1",
"eslint-plugin-promise": "^6.0.0",
"eslint-plugin-react": "^7.29.4",
"eslint-plugin-react-hooks": "^4.5.0",
"file-loader": "^6.2.0",
"html-webpack-plugin": "^5.5.0",
"https-browserify": "^1.0.0",
"identity-obj-proxy": "^3.0.0",
"jest": "^28.1.0",
"jest-environment-jsdom": "^28.1.0",
"less": "^4.1.3",
"less-loader": "^11.0.0",
"lint-staged": "^12.4.1",
"mini-css-extract-plugin": "^2.6.0",
"path-browserify": "^1.0.1",
"postcss-loader": "^7.0.0",
"prettier": "^2.6.2",
"react-refresh": "^0.13.0",
"react-test-renderer": "^18.1.0",
"rimraf": "^3.0.2",
"sass": "^1.51.0",
"sass-loader": "^12.6.0",
"stream-browserify": "^3.0.0",
"stream-http": "^3.2.0",
"style-loader": "^3.3.1",
"tailwindcss": "^3.1.2",
"terser-webpack-plugin": "^5.3.1",
"ts-jest": "^28.0.2",
"ts-loader": "^9.3.0",
"ts-node": "^10.7.0",
"typescript": "^4.6.4",
"url": "^0.11.0",
"url-loader": "^4.1.1",
"webpack": "5.73.0",
"webpack-bundle-analyzer": "^4.5.0",
"webpack-cli": "^4.9.2",
"webpack-dev-server": "^4.9.0",
"webpack-merge": "^5.8.0"
},
"devEngines": {
"node": ">=14.x",
"npm": ">=7.x"
},
"electronmon": {
"patterns": [
"!**/**",
"src/main/*"
],
"logLevel": "quiet"
}
}

@ -0,0 +1,18 @@
{
"name": "tailchat-meeting",
"version": "0.0.1",
"description": "A foundation for scalable desktop apps",
"license": "MIT",
"author": {
"name": "moonrailgun",
"email": "moonrailgun@gmail.com",
"url": "https://github.com/moonrailgun"
},
"main": "./dist/main/main.js",
"scripts": {
"electron-rebuild": "node -r ts-node/register ../../.erb/scripts/electron-rebuild.js",
"postinstall": "npm run electron-rebuild && npm run link-modules",
"link-modules": "node -r ts-node/register ../../.erb/scripts/link-modules.ts"
},
"dependencies": {}
}

@ -0,0 +1,4 @@
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1

@ -0,0 +1,9 @@
import '@testing-library/jest-dom';
import { render } from '@testing-library/react';
import App from '../renderer/App';
describe('App', () => {
it('should render', () => {
expect(render(<App />)).toBeTruthy();
});
});

@ -0,0 +1,163 @@
/* eslint global-require: off, no-console: off, promise/always-return: off */
/**
* This module executes inside of electron's main process. You can start
* electron renderer process from here and communicate with the other processes
* through IPC.
*
* When running `npm run build` or `npm run build:main`, this file is compiled to
* `./src/main.js` using webpack. This gives us some performance wins.
*/
import path from 'path';
import { app, BrowserWindow, shell, ipcMain } from 'electron';
import { autoUpdater } from 'electron-updater';
import log from 'electron-log';
import MenuBuilder from './menu';
import { resolveHtmlPath } from './util';
import windowStateKeeper from 'electron-window-state';
log.info('Start...');
export default class AppUpdater {
constructor() {
log.transports.file.level = 'info';
autoUpdater.logger = log;
autoUpdater.checkForUpdatesAndNotify();
}
}
ipcMain.on('ipc-example', async (event, arg) => {
const msgTemplate = (pingPong: string) => `IPC test: ${pingPong}`;
console.log(msgTemplate(arg));
event.reply('ipc-example', msgTemplate('pong'));
});
if (process.env.NODE_ENV === 'production') {
const sourceMapSupport = require('source-map-support');
sourceMapSupport.install();
}
const isDebug =
process.env.NODE_ENV === 'development' || process.env.DEBUG_PROD === 'true';
if (isDebug) {
require('electron-debug')();
}
if (app.isPackaged) {
log.info('auto catch errors and overwrite default `console.log` functions');
log.catchErrors();
Object.assign(console, log.functions);
}
const installExtensions = async () => {
const installer = require('electron-devtools-installer');
const forceDownload = !!process.env.UPGRADE_EXTENSIONS;
const extensions = ['REACT_DEVELOPER_TOOLS'];
return installer
.default(
extensions.map((name) => installer[name]),
forceDownload
)
.catch(console.log);
};
let mainWindow: BrowserWindow | null = null;
const createWindow = async () => {
try {
log.info('Create window');
if (isDebug) {
log.info('Install extensions');
await installExtensions();
}
const RESOURCES_PATH = app.isPackaged
? path.join(process.resourcesPath, 'assets')
: path.join(__dirname, '../../assets');
log.info('parse resolve path:', RESOURCES_PATH);
const mainWindowState = windowStateKeeper({
defaultWidth: 1024,
defaultHeight: 728,
});
log.info('load window state with:', mainWindow);
const getAssetPath = (...paths: string[]): string => {
return path.join(RESOURCES_PATH, ...paths);
};
mainWindow = new BrowserWindow({
show: false,
x: mainWindowState.x,
y: mainWindowState.y,
height: mainWindowState.height,
width: mainWindowState.width,
icon: getAssetPath('icon.png'),
webPreferences: {
preload: app.isPackaged
? path.join(__dirname, 'preload.js')
: path.join(__dirname, '../../.erb/dll/preload.js'),
},
});
const url = resolveHtmlPath('index.html');
log.info('loadUrl:', url);
mainWindow.loadURL(url);
mainWindow.on('ready-to-show', () => {
if (!mainWindow) {
throw new Error('"mainWindow" is not defined');
}
if (process.env.START_MINIMIZED) {
mainWindow.minimize();
} else {
mainWindow.show();
}
});
mainWindow.on('closed', () => {
mainWindow = null;
});
log.info('Build menu');
const menuBuilder = new MenuBuilder(mainWindow);
menuBuilder.buildMenu();
// Open urls in the user's browser
mainWindow.webContents.setWindowOpenHandler((edata) => {
shell.openExternal(edata.url);
return { action: 'deny' };
});
// Remove this if your app does not use auto updates
// eslint-disable-next-line
new AppUpdater();
} catch (err) {
log.error('createWindow error:', err);
}
};
/**
* Add event listeners...
*/
app.on('window-all-closed', () => {
// Respect the OSX convention of having the application in memory even
// after all windows have been closed
if (process.platform !== 'darwin') {
app.quit();
}
});
app
.whenReady()
.then(() => {
createWindow();
app.on('activate', () => {
// On macOS it's common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open.
if (mainWindow === null) createWindow();
});
})
.catch(log.error);

@ -0,0 +1,290 @@
import {
app,
Menu,
shell,
BrowserWindow,
MenuItemConstructorOptions,
} from 'electron';
interface DarwinMenuItemConstructorOptions extends MenuItemConstructorOptions {
selector?: string;
submenu?: DarwinMenuItemConstructorOptions[] | Menu;
}
export default class MenuBuilder {
mainWindow: BrowserWindow;
constructor(mainWindow: BrowserWindow) {
this.mainWindow = mainWindow;
}
buildMenu(): Menu {
if (
process.env.NODE_ENV === 'development' ||
process.env.DEBUG_PROD === 'true'
) {
this.setupDevelopmentEnvironment();
}
const template =
process.platform === 'darwin'
? this.buildDarwinTemplate()
: this.buildDefaultTemplate();
const menu = Menu.buildFromTemplate(template);
Menu.setApplicationMenu(menu);
return menu;
}
setupDevelopmentEnvironment(): void {
this.mainWindow.webContents.on('context-menu', (_, props) => {
const { x, y } = props;
Menu.buildFromTemplate([
{
label: 'Inspect element',
click: () => {
this.mainWindow.webContents.inspectElement(x, y);
},
},
]).popup({ window: this.mainWindow });
});
}
buildDarwinTemplate(): MenuItemConstructorOptions[] {
const subMenuAbout: DarwinMenuItemConstructorOptions = {
label: 'Electron',
submenu: [
{
label: 'About ElectronReact',
selector: 'orderFrontStandardAboutPanel:',
},
{ type: 'separator' },
{ label: 'Services', submenu: [] },
{ type: 'separator' },
{
label: 'Hide ElectronReact',
accelerator: 'Command+H',
selector: 'hide:',
},
{
label: 'Hide Others',
accelerator: 'Command+Shift+H',
selector: 'hideOtherApplications:',
},
{ label: 'Show All', selector: 'unhideAllApplications:' },
{ type: 'separator' },
{
label: 'Quit',
accelerator: 'Command+Q',
click: () => {
app.quit();
},
},
],
};
const subMenuEdit: DarwinMenuItemConstructorOptions = {
label: 'Edit',
submenu: [
{ label: 'Undo', accelerator: 'Command+Z', selector: 'undo:' },
{ label: 'Redo', accelerator: 'Shift+Command+Z', selector: 'redo:' },
{ type: 'separator' },
{ label: 'Cut', accelerator: 'Command+X', selector: 'cut:' },
{ label: 'Copy', accelerator: 'Command+C', selector: 'copy:' },
{ label: 'Paste', accelerator: 'Command+V', selector: 'paste:' },
{
label: 'Select All',
accelerator: 'Command+A',
selector: 'selectAll:',
},
],
};
const subMenuViewDev: MenuItemConstructorOptions = {
label: 'View',
submenu: [
{
label: 'Reload',
accelerator: 'Command+R',
click: () => {
this.mainWindow.webContents.reload();
},
},
{
label: 'Toggle Full Screen',
accelerator: 'Ctrl+Command+F',
click: () => {
this.mainWindow.setFullScreen(!this.mainWindow.isFullScreen());
},
},
{
label: 'Toggle Developer Tools',
accelerator: 'Alt+Command+I',
click: () => {
this.mainWindow.webContents.toggleDevTools();
},
},
],
};
const subMenuViewProd: MenuItemConstructorOptions = {
label: 'View',
submenu: [
{
label: 'Toggle Full Screen',
accelerator: 'Ctrl+Command+F',
click: () => {
this.mainWindow.setFullScreen(!this.mainWindow.isFullScreen());
},
},
],
};
const subMenuWindow: DarwinMenuItemConstructorOptions = {
label: 'Window',
submenu: [
{
label: 'Minimize',
accelerator: 'Command+M',
selector: 'performMiniaturize:',
},
{ label: 'Close', accelerator: 'Command+W', selector: 'performClose:' },
{ type: 'separator' },
{ label: 'Bring All to Front', selector: 'arrangeInFront:' },
],
};
const subMenuHelp: MenuItemConstructorOptions = {
label: 'Help',
submenu: [
{
label: 'Learn More',
click() {
shell.openExternal('https://electronjs.org');
},
},
{
label: 'Documentation',
click() {
shell.openExternal(
'https://github.com/electron/electron/tree/main/docs#readme'
);
},
},
{
label: 'Community Discussions',
click() {
shell.openExternal('https://www.electronjs.org/community');
},
},
{
label: 'Search Issues',
click() {
shell.openExternal('https://github.com/electron/electron/issues');
},
},
],
};
const subMenuView =
process.env.NODE_ENV === 'development' ||
process.env.DEBUG_PROD === 'true'
? subMenuViewDev
: subMenuViewProd;
return [subMenuAbout, subMenuEdit, subMenuView, subMenuWindow, subMenuHelp];
}
buildDefaultTemplate() {
const templateDefault = [
{
label: '&File',
submenu: [
{
label: '&Open',
accelerator: 'Ctrl+O',
},
{
label: '&Close',
accelerator: 'Ctrl+W',
click: () => {
this.mainWindow.close();
},
},
],
},
{
label: '&View',
submenu:
process.env.NODE_ENV === 'development' ||
process.env.DEBUG_PROD === 'true'
? [
{
label: '&Reload',
accelerator: 'Ctrl+R',
click: () => {
this.mainWindow.webContents.reload();
},
},
{
label: 'Toggle &Full Screen',
accelerator: 'F11',
click: () => {
this.mainWindow.setFullScreen(
!this.mainWindow.isFullScreen()
);
},
},
{
label: 'Toggle &Developer Tools',
accelerator: 'Alt+Ctrl+I',
click: () => {
this.mainWindow.webContents.toggleDevTools();
},
},
]
: [
{
label: 'Toggle &Full Screen',
accelerator: 'F11',
click: () => {
this.mainWindow.setFullScreen(
!this.mainWindow.isFullScreen()
);
},
},
],
},
{
label: 'Help',
submenu: [
{
label: 'Learn More',
click() {
shell.openExternal('https://electronjs.org');
},
},
{
label: 'Documentation',
click() {
shell.openExternal(
'https://github.com/electron/electron/tree/main/docs#readme'
);
},
},
{
label: 'Community Discussions',
click() {
shell.openExternal('https://www.electronjs.org/community');
},
},
{
label: 'Search Issues',
click() {
shell.openExternal('https://github.com/electron/electron/issues');
},
},
],
},
];
return templateDefault;
}
}

@ -0,0 +1,21 @@
import { contextBridge, ipcRenderer, IpcRendererEvent } from 'electron';
export type Channels = 'ipc-example';
contextBridge.exposeInMainWorld('electron', {
ipcRenderer: {
sendMessage(channel: Channels, args: unknown[]) {
ipcRenderer.send(channel, args);
},
on(channel: Channels, func: (...args: unknown[]) => void) {
const subscription = (_event: IpcRendererEvent, ...args: unknown[]) =>
func(...args);
ipcRenderer.on(channel, subscription);
return () => ipcRenderer.removeListener(channel, subscription);
},
once(channel: Channels, func: (...args: unknown[]) => void) {
ipcRenderer.once(channel, (_event, ...args) => func(...args));
},
},
});

@ -0,0 +1,18 @@
/* eslint import/prefer-default-export: off, import/no-mutable-exports: off */
import { URL } from 'url';
import path from 'path';
export let resolveHtmlPath: (htmlFileName: string) => string;
if (process.env.NODE_ENV === 'development') {
const port = process.env.PORT || 1212;
resolveHtmlPath = (htmlFileName: string) => {
const url = new URL(`http://localhost:${port}`);
url.pathname = htmlFileName;
return url.href;
};
} else {
resolveHtmlPath = (htmlFileName: string) => {
return `file://${path.resolve(__dirname, '../renderer/', htmlFileName)}`;
};
}

@ -0,0 +1,62 @@
/*
* @NOTE: Prepend a `~` to css file paths that are in your node_modules
* See https://github.com/webpack-contrib/sass-loader#imports
*/
body {
position: relative;
color: white;
height: 100vh;
background: linear-gradient(
200.96deg,
#fedc2a -29.09%,
#dd5789 51.77%,
#7a2c9e 129.35%
);
font-family: sans-serif;
overflow-y: hidden;
display: flex;
justify-content: center;
align-items: center;
}
button {
background-color: white;
padding: 10px 20px;
border-radius: 10px;
border: none;
appearance: none;
font-size: 1.3rem;
box-shadow: 0px 8px 28px -6px rgba(24, 39, 75, 0.12),
0px 18px 88px -4px rgba(24, 39, 75, 0.14);
transition: all ease-in 0.1s;
cursor: pointer;
opacity: 0.9;
}
button:hover {
transform: scale(1.05);
opacity: 1;
}
li {
list-style: none;
}
a {
text-decoration: none;
height: fit-content;
width: fit-content;
margin: 10px;
}
a:hover {
opacity: 1;
text-decoration: none;
}
.Hello {
display: flex;
justify-content: center;
align-items: center;
margin: 20px 0;
}

@ -0,0 +1,50 @@
import { MemoryRouter as Router, Routes, Route } from 'react-router-dom';
import icon from '../../assets/icon.svg';
import './App.css';
const Hello = () => {
return (
<div>
<div className="Hello">
<img width="200px" alt="icon" src={icon} />
</div>
<h1>electron-react-boilerplate</h1>
<div className="Hello">
<a
href="https://electron-react-boilerplate.js.org/"
target="_blank"
rel="noreferrer"
>
<button type="button">
<span role="img" aria-label="books">
📚
</span>
Read our docs
</button>
</a>
<a
href="https://github.com/sponsors/electron-react-boilerplate"
target="_blank"
rel="noreferrer"
>
<button type="button">
<span role="img" aria-label="books">
🙏
</span>
Donate
</button>
</a>
</div>
</div>
);
};
export default function App() {
return (
<Router>
<Routes>
<Route path="/" element={<Hello />} />
</Routes>
</Router>
);
}

@ -0,0 +1,14 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta
http-equiv="Content-Security-Policy"
content="script-src 'self' 'unsafe-inline'"
/>
<title>Tailchat</title>
</head>
<body>
<div id="tailchat"></div>
</body>
</html>

@ -0,0 +1,15 @@
import '../../../web/src/index';
// import { createRoot } from 'react-dom/client';
// import App from './App';
// const container = document.getElementById('root')!;
// const root = createRoot(container);
// root.render(<App />);
// // calling IPC exposed from preload script
// window.electron.ipcRenderer.once('ipc-example', (arg) => {
// // eslint-disable-next-line no-console
// console.log(arg);
// });
// window.electron.ipcRenderer.sendMessage('ipc-example', ['ping']);

@ -0,0 +1,18 @@
import { Channels } from 'main/preload';
declare global {
interface Window {
electron: {
ipcRenderer: {
sendMessage(channel: Channels, args: unknown[]): void;
on(
channel: string,
func: (...args: unknown[]) => void
): (() => void) | undefined;
once(channel: string, func: (...args: unknown[]) => void): void;
};
};
}
}
export {};

@ -0,0 +1 @@
module.exports = require('../web/tailwind.config');

@ -0,0 +1,25 @@
{
"compilerOptions": {
"target": "es2021",
"module": "commonjs",
"lib": ["dom", "es2021"],
"declaration": true,
"declarationMap": true,
"jsx": "react-jsx",
"strict": true,
"pretty": true,
"sourceMap": true,
"baseUrl": "./src",
"noUnusedLocals": true,
"noUnusedParameters": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"moduleResolution": "node",
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"resolveJsonModule": true,
"allowJs": true,
"outDir": "release/app/dist"
},
"exclude": ["test", "release/build", "release/app/dist", ".erb/dll"]
}

File diff suppressed because it is too large Load Diff

@ -363,7 +363,7 @@ importers:
typescript: ^4.5.2
url: ^0.11.0
url-loader: ^4.1.1
webpack: ^5.72.0
webpack: 5.73.0
webpack-bundle-analyzer: ^4.5.0
webpack-cli: ^4.9.1
webpack-dev-server: ^4.3.1
@ -432,44 +432,44 @@ importers:
'@types/react-virtualized-auto-sizer': 1.0.1
'@types/webpack': 5.28.0_webpack-cli@4.9.2
'@types/webpack-bundle-analyzer': 4.4.1_webpack-cli@4.9.2
'@types/webpack-dev-server': 4.7.2_smhu6mcfcg7aivfsuosc335k3u
'@types/webpack-dev-server': 4.7.2_gkh3o7gdsall36kyfdv2sybo54
autoprefixer: 10.4.7_postcss@8.4.13
bundle-stats-webpack-plugin: 3.3.8_webpack@5.72.1
copy-webpack-plugin: 9.1.0_webpack@5.72.1
bundle-stats-webpack-plugin: 3.3.8_webpack@5.73.0
copy-webpack-plugin: 9.1.0_webpack@5.73.0
cross-env: 7.0.3
css-loader: 5.2.7_webpack@5.72.1
css-loader: 5.2.7_webpack@5.73.0
dotenv: 10.0.0
dts-generator: 3.0.0
esbuild-loader: 2.18.0_webpack@5.72.1
esbuild-loader: 2.18.0_webpack@5.73.0
execa: 5.1.1
file-loader: 6.2.0_webpack@5.72.1
file-loader: 6.2.0_webpack@5.73.0
glob: 7.2.0
html-webpack-plugin: 5.5.0_webpack@5.72.1
html-webpack-plugin: 5.5.0_webpack@5.73.0
jest: 27.5.1_ts-node@10.7.0
less: 4.1.2
less-loader: 10.2.0_less@4.1.2+webpack@5.72.1
mini-css-extract-plugin: 1.6.2_webpack@5.72.1
less-loader: 10.2.0_less@4.1.2+webpack@5.73.0
mini-css-extract-plugin: 1.6.2_webpack@5.73.0
postcss: 8.4.13
postcss-loader: 6.2.1_yokl3cbwhadljnh75p6ymh6bce
postcss-loader: 6.2.1_antlv5ffwu5b3l6qf5ix53g2p4
rimraf: 3.0.2
rollup-plugin-copy: 3.4.0
rollup-plugin-replace: 2.2.0
rollup-plugin-source-ref: link:../packages/rollup-plugin-source-ref
source-ref-loader: link:../packages/source-ref-loader
style-loader: 3.3.1_webpack@5.72.1
style-loader: 3.3.1_webpack@5.73.0
tailchat-plugin-declaration-generator: link:../packages/plugin-declaration-generator
ts-jest: 27.1.4_ibhx3ehxrt2kgmkik4bkzmyeei
ts-node: 10.7.0_ixcth6kbstn6no7hiktnzckliq
tsconfig-paths: 3.14.1
tsconfig-paths-webpack-plugin: 3.5.2
typescript: 4.6.4
url-loader: 4.1.1_4spiask3fd7dtsm35bmnngyscq
webpack: 5.72.1_webpack-cli@4.9.2
url-loader: 4.1.1_ljnyroaqobwke7fusd7ro2cgzm
webpack: 5.73.0_webpack-cli@4.9.2
webpack-bundle-analyzer: 4.5.0
webpack-cli: 4.9.2_dm2ytpn7fgyd7euodvcejn2hda
webpack-dev-server: 4.9.0_smhu6mcfcg7aivfsuosc335k3u
webpackbar: 5.0.2_webpack@5.72.1
workbox-webpack-plugin: 6.5.3_webpack@5.72.1
webpack-cli: 4.9.2_w5nksobufzg2ereh4ivwj2odyu
webpack-dev-server: 4.9.0_gkh3o7gdsall36kyfdv2sybo54
webpackbar: 5.0.2_webpack@5.73.0
workbox-webpack-plugin: 6.5.3_webpack@5.73.0
web/plugins/com.msgbyte.bbcode:
specifiers:
@ -4533,7 +4533,7 @@ packages:
dependencies:
'@types/node': 17.0.4
tapable: 2.2.1
webpack: 5.72.1_webpack-cli@4.9.2
webpack: 5.73.0_webpack-cli@4.9.2
transitivePeerDependencies:
- '@swc/core'
- esbuild
@ -4719,7 +4719,7 @@ packages:
dependencies:
'@types/node': 17.0.4
tapable: 2.2.1
webpack: 5.72.1_webpack-cli@4.9.2
webpack: 5.73.0_webpack-cli@4.9.2
transitivePeerDependencies:
- '@swc/core'
- esbuild
@ -4958,7 +4958,7 @@ packages:
dependencies:
'@types/node': 17.0.4
tapable: 2.2.1
webpack: 5.72.1_webpack-cli@4.9.2
webpack: 5.73.0_webpack-cli@4.9.2
transitivePeerDependencies:
- '@swc/core'
- esbuild
@ -4966,11 +4966,11 @@ packages:
- webpack-cli
dev: true
/@types/webpack-dev-server/4.7.2_smhu6mcfcg7aivfsuosc335k3u:
/@types/webpack-dev-server/4.7.2_gkh3o7gdsall36kyfdv2sybo54:
resolution: {integrity: sha512-Y3p0Fmfvp0MHBDoCzo+xFJaWTw0/z37mWIo6P15j+OtmUDLvznJWdZNeD7Q004R+MpQlys12oXbXsrXRmxwg4Q==}
deprecated: This is a stub types definition. webpack-dev-server provides its own type definitions, so you do not need this installed.
dependencies:
webpack-dev-server: 4.9.0_smhu6mcfcg7aivfsuosc335k3u
webpack-dev-server: 4.9.0_gkh3o7gdsall36kyfdv2sybo54
transitivePeerDependencies:
- bufferutil
- debug
@ -5404,14 +5404,14 @@ packages:
'@xtuc/long': 4.2.2
dev: true
/@webpack-cli/configtest/1.1.1_smhu6mcfcg7aivfsuosc335k3u:
/@webpack-cli/configtest/1.1.1_gkh3o7gdsall36kyfdv2sybo54:
resolution: {integrity: sha512-1FBc1f9G4P/AxMqIgfZgeOTuRnwZMten8E7zap5zgpPInnCrP8D4Q81+4CWIch8i/Nf7nXjP0v6CjjbHOrXhKg==}
peerDependencies:
webpack: 4.x.x || 5.x.x
webpack-cli: 4.x.x
dependencies:
webpack: 5.72.1_webpack-cli@4.9.2
webpack-cli: 4.9.2_dm2ytpn7fgyd7euodvcejn2hda
webpack: 5.73.0_webpack-cli@4.9.2
webpack-cli: 4.9.2_w5nksobufzg2ereh4ivwj2odyu
dev: true
/@webpack-cli/info/1.4.1_webpack-cli@4.9.2:
@ -5420,7 +5420,7 @@ packages:
webpack-cli: 4.x.x
dependencies:
envinfo: 7.8.1
webpack-cli: 4.9.2_dm2ytpn7fgyd7euodvcejn2hda
webpack-cli: 4.9.2_w5nksobufzg2ereh4ivwj2odyu
dev: true
/@webpack-cli/serve/1.6.1_efhxflzxrvzsrtpw5o3zelaodm:
@ -5432,8 +5432,8 @@ packages:
webpack-dev-server:
optional: true
dependencies:
webpack-cli: 4.9.2_dm2ytpn7fgyd7euodvcejn2hda
webpack-dev-server: 4.9.0_smhu6mcfcg7aivfsuosc335k3u
webpack-cli: 4.9.2_w5nksobufzg2ereh4ivwj2odyu
webpack-dev-server: 4.9.0_gkh3o7gdsall36kyfdv2sybo54
dev: true
/@xtuc/ieee754/1.2.0:
@ -6665,7 +6665,7 @@ packages:
resolution: {integrity: sha512-HpGFw18DgFWlncDfjTa2rcQ4W88O1mC8e8yZ2AvQY5KDaktSTwo+KRf6nHK6FRI5FyRyb/5T6+TSxfP7QyGsmQ==}
dev: true
/bundle-stats-webpack-plugin/3.3.8_webpack@5.72.1:
/bundle-stats-webpack-plugin/3.3.8_webpack@5.73.0:
resolution: {integrity: sha512-z+IeVieDY749Jg7ai9pvTwFqAylZnTfDYF3/r1B6aFnwDEAjDetC60XuIqSs0F30EWow5v/1mkKBCdyiLWIrQw==}
engines: {node: '>= 12.0'}
peerDependencies:
@ -6675,7 +6675,7 @@ packages:
'@bundle-stats/utils': 3.3.8_xqc3ywgrobkwiqao2oqbih6pzm
core-js: 3.22.5
lodash: 4.17.21
webpack: 5.72.1_webpack-cli@4.9.2
webpack: 5.73.0_webpack-cli@4.9.2
dev: true
/bytes/3.0.0:
@ -7422,7 +7422,7 @@ packages:
dependencies:
toggle-selection: 1.0.6
/copy-webpack-plugin/9.1.0_webpack@5.72.1:
/copy-webpack-plugin/9.1.0_webpack@5.73.0:
resolution: {integrity: sha512-rxnR7PaGigJzhqETHGmAcxKnLZSR5u1Y3/bcIv/1FnqXedcL/E2ewK7ZCNrArJKCiSv8yVXhTqetJh8inDvfsA==}
engines: {node: '>= 12.13.0'}
peerDependencies:
@ -7434,7 +7434,7 @@ packages:
normalize-path: 3.0.0
schema-utils: 3.1.1
serialize-javascript: 6.0.0
webpack: 5.72.1_webpack-cli@4.9.2
webpack: 5.73.0_webpack-cli@4.9.2
dev: true
/core-js-compat/3.22.5:
@ -7650,7 +7650,7 @@ packages:
webpack: 4.46.0
dev: true
/css-loader/5.2.7_webpack@5.72.1:
/css-loader/5.2.7_webpack@5.73.0:
resolution: {integrity: sha512-Q7mOvpBNBG7YrVGMxRxcBJZFL75o+cH2abNASdibkj/fffYD8qWbInZrD0S9ccI6vZclF3DsHE7njGlLtaHbhg==}
engines: {node: '>= 10.13.0'}
peerDependencies:
@ -7666,7 +7666,7 @@ packages:
postcss-value-parser: 4.2.0
schema-utils: 3.1.1
semver: 7.3.7
webpack: 5.72.1_webpack-cli@4.9.2
webpack: 5.73.0_webpack-cli@4.9.2
dev: true
/css-select-base-adapter/0.1.1:
@ -8651,7 +8651,7 @@ packages:
dev: true
optional: true
/esbuild-loader/2.18.0_webpack@5.72.1:
/esbuild-loader/2.18.0_webpack@5.73.0:
resolution: {integrity: sha512-AKqxM3bI+gvGPV8o6NAhR+cBxVO8+dh+O0OXBHIXXwuSGumckbPWHzZ17subjBGI2YEGyJ1STH7Haj8aCrwL/w==}
peerDependencies:
webpack: ^4.40.0 || ^5.0.0
@ -8661,7 +8661,7 @@ packages:
json5: 2.2.1
loader-utils: 2.0.2
tapable: 2.2.1
webpack: 5.72.1_webpack-cli@4.9.2
webpack: 5.73.0_webpack-cli@4.9.2
webpack-sources: 2.3.1
dev: true
@ -9279,7 +9279,7 @@ packages:
webpack: 4.46.0
dev: true
/file-loader/6.2.0_webpack@5.72.1:
/file-loader/6.2.0_webpack@5.73.0:
resolution: {integrity: sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw==}
engines: {node: '>= 10.13.0'}
peerDependencies:
@ -9287,7 +9287,7 @@ packages:
dependencies:
loader-utils: 2.0.2
schema-utils: 3.1.1
webpack: 5.72.1_webpack-cli@4.9.2
webpack: 5.73.0_webpack-cli@4.9.2
dev: true
/file-system-cache/1.0.5:
@ -10268,7 +10268,7 @@ packages:
webpack: 4.46.0
dev: true
/html-webpack-plugin/5.5.0_webpack@5.72.1:
/html-webpack-plugin/5.5.0_webpack@5.73.0:
resolution: {integrity: sha512-sy88PC2cRTVxvETRgUHFrL4No3UxvcH8G1NepGhqaTT+GXN2kTamqasot0inS5hXeg1cMbFDt27zzo9p35lZVw==}
engines: {node: '>=10.13.0'}
peerDependencies:
@ -10279,7 +10279,7 @@ packages:
lodash: 4.17.21
pretty-error: 4.0.0
tapable: 2.2.1
webpack: 5.72.1_webpack-cli@4.9.2
webpack: 5.73.0_webpack-cli@4.9.2
dev: true
/htmlparser2/6.1.0:
@ -11977,7 +11977,7 @@ packages:
flush-write-stream: 1.1.1
dev: true
/less-loader/10.2.0_less@4.1.2+webpack@5.72.1:
/less-loader/10.2.0_less@4.1.2+webpack@5.73.0:
resolution: {integrity: sha512-AV5KHWvCezW27GT90WATaDnfXBv99llDbtaj4bshq6DvAihMdNjaPDcUMa6EXKLRF+P2opFenJp89BXg91XLYg==}
engines: {node: '>= 12.13.0'}
peerDependencies:
@ -11986,7 +11986,7 @@ packages:
dependencies:
klona: 2.0.5
less: 4.1.2
webpack: 5.72.1_webpack-cli@4.9.2
webpack: 5.73.0_webpack-cli@4.9.2
dev: true
/less/4.1.2:
@ -12559,7 +12559,7 @@ packages:
tiny-warning: 1.0.3
dev: false
/mini-css-extract-plugin/1.6.2_webpack@5.72.1:
/mini-css-extract-plugin/1.6.2_webpack@5.73.0:
resolution: {integrity: sha512-WhDvO3SjGm40oV5y26GjMJYjd2UMqrLAGKy5YS2/3QKJy2F7jgynuHTir/tgUUOiNQu5saXHdc8reo7YuhhT4Q==}
engines: {node: '>= 10.13.0'}
peerDependencies:
@ -12567,7 +12567,7 @@ packages:
dependencies:
loader-utils: 2.0.2
schema-utils: 3.1.1
webpack: 5.72.1_webpack-cli@4.9.2
webpack: 5.73.0_webpack-cli@4.9.2
webpack-sources: 1.4.3
dev: true
@ -13708,7 +13708,7 @@ packages:
webpack: 4.46.0
dev: true
/postcss-loader/6.2.1_yokl3cbwhadljnh75p6ymh6bce:
/postcss-loader/6.2.1_antlv5ffwu5b3l6qf5ix53g2p4:
resolution: {integrity: sha512-WbbYpmAaKcux/P66bZ40bpWsBucjx/TTgVVzRZ9yUO8yQfVBlameJ0ZGVaPfH64hNSBh63a+ICP5nqOpBA0w+Q==}
engines: {node: '>= 12.13.0'}
peerDependencies:
@ -13719,7 +13719,7 @@ packages:
klona: 2.0.5
postcss: 8.4.13
semver: 7.3.7
webpack: 5.72.1_webpack-cli@4.9.2
webpack: 5.73.0_webpack-cli@4.9.2
dev: true
/postcss-merge-longhand/4.0.11:
@ -16791,13 +16791,13 @@ packages:
webpack: 4.46.0
dev: true
/style-loader/3.3.1_webpack@5.72.1:
/style-loader/3.3.1_webpack@5.73.0:
resolution: {integrity: sha512-GPcQ+LDJbrcxHORTRes6Jy2sfvK2kS6hpSfI/fXhPt+spVzxF6LJ1dHLN9zIGmVaaP044YKaIatFaufENRiDoQ==}
engines: {node: '>= 12.13.0'}
peerDependencies:
webpack: ^5.0.0
dependencies:
webpack: 5.72.1_webpack-cli@4.9.2
webpack: 5.73.0_webpack-cli@4.9.2
dev: true
/style-to-js/1.1.0:
@ -17086,7 +17086,31 @@ packages:
serialize-javascript: 6.0.0
source-map: 0.6.1
terser: 5.13.1
webpack: 5.72.1_webpack-cli@4.9.2
webpack: 5.72.1
dev: true
/terser-webpack-plugin/5.3.1_webpack@5.73.0:
resolution: {integrity: sha512-GvlZdT6wPQKbDNW/GDQzZFg/j4vKU96yl2q6mcUkzKOgW4gwf1Z8cZToUCrz31XHlPWH8MVb1r2tFtdDtTGJ7g==}
engines: {node: '>= 10.13.0'}
peerDependencies:
'@swc/core': '*'
esbuild: '*'
uglify-js: '*'
webpack: ^5.1.0
peerDependenciesMeta:
'@swc/core':
optional: true
esbuild:
optional: true
uglify-js:
optional: true
dependencies:
jest-worker: 27.5.1
schema-utils: 3.1.1
serialize-javascript: 6.0.0
source-map: 0.6.1
terser: 5.13.1
webpack: 5.73.0_webpack-cli@4.9.2
dev: true
/terser/4.8.0:
@ -17729,7 +17753,7 @@ packages:
deprecated: Please see https://github.com/lydell/urix#deprecated
dev: true
/url-loader/4.1.1_4spiask3fd7dtsm35bmnngyscq:
/url-loader/4.1.1_lit45vopotvaqup7lrvlnvtxwy:
resolution: {integrity: sha512-3BTV812+AVHHOJQO8O5MkWgZ5aosP7GnROJwvzLS9hWDj00lZ6Z0wNak423Lp9PBZN05N+Jk/N5Si8jRAlGyWA==}
engines: {node: '>= 10.13.0'}
peerDependencies:
@ -17739,14 +17763,14 @@ packages:
file-loader:
optional: true
dependencies:
file-loader: 6.2.0_webpack@5.72.1
file-loader: 6.2.0_webpack@4.46.0
loader-utils: 2.0.2
mime-types: 2.1.35
schema-utils: 3.1.1
webpack: 5.72.1_webpack-cli@4.9.2
webpack: 4.46.0
dev: true
/url-loader/4.1.1_lit45vopotvaqup7lrvlnvtxwy:
/url-loader/4.1.1_ljnyroaqobwke7fusd7ro2cgzm:
resolution: {integrity: sha512-3BTV812+AVHHOJQO8O5MkWgZ5aosP7GnROJwvzLS9hWDj00lZ6Z0wNak423Lp9PBZN05N+Jk/N5Si8jRAlGyWA==}
engines: {node: '>= 10.13.0'}
peerDependencies:
@ -17756,11 +17780,11 @@ packages:
file-loader:
optional: true
dependencies:
file-loader: 6.2.0_webpack@4.46.0
file-loader: 6.2.0_webpack@5.73.0
loader-utils: 2.0.2
mime-types: 2.1.35
schema-utils: 3.1.1
webpack: 4.46.0
webpack: 5.73.0_webpack-cli@4.9.2
dev: true
/url-regex/5.0.0:
@ -18102,7 +18126,7 @@ packages:
- utf-8-validate
dev: true
/webpack-cli/4.9.2_dm2ytpn7fgyd7euodvcejn2hda:
/webpack-cli/4.9.2_w5nksobufzg2ereh4ivwj2odyu:
resolution: {integrity: sha512-m3/AACnBBzK/kMTcxWHcZFPrw/eQuY4Df1TxvIWfWM2x7mRqBQCqKEd96oCUa9jkapLBaFfRce33eGDb4Pr7YQ==}
engines: {node: '>=10.13.0'}
hasBin: true
@ -18123,7 +18147,7 @@ packages:
optional: true
dependencies:
'@discoveryjs/json-ext': 0.5.7
'@webpack-cli/configtest': 1.1.1_smhu6mcfcg7aivfsuosc335k3u
'@webpack-cli/configtest': 1.1.1_gkh3o7gdsall36kyfdv2sybo54
'@webpack-cli/info': 1.4.1_webpack-cli@4.9.2
'@webpack-cli/serve': 1.6.1_efhxflzxrvzsrtpw5o3zelaodm
colorette: 2.0.16
@ -18133,9 +18157,9 @@ packages:
import-local: 3.1.0
interpret: 2.2.0
rechoir: 0.7.1
webpack: 5.72.1_webpack-cli@4.9.2
webpack: 5.73.0_webpack-cli@4.9.2
webpack-bundle-analyzer: 4.5.0
webpack-dev-server: 4.9.0_smhu6mcfcg7aivfsuosc335k3u
webpack-dev-server: 4.9.0_gkh3o7gdsall36kyfdv2sybo54
webpack-merge: 5.8.0
dev: true
@ -18153,7 +18177,7 @@ packages:
webpack-log: 2.0.0
dev: true
/webpack-dev-middleware/5.3.1_webpack@5.72.1:
/webpack-dev-middleware/5.3.1_webpack@5.73.0:
resolution: {integrity: sha512-81EujCKkyles2wphtdrnPg/QqegC/AtqNH//mQkBYSMqwFVCQrxM6ktB2O/SPlZy7LqeEfTbV3cZARGQz6umhg==}
engines: {node: '>= 12.13.0'}
peerDependencies:
@ -18164,10 +18188,10 @@ packages:
mime-types: 2.1.35
range-parser: 1.2.1
schema-utils: 4.0.0
webpack: 5.72.1_webpack-cli@4.9.2
webpack: 5.73.0_webpack-cli@4.9.2
dev: true
/webpack-dev-server/4.9.0_smhu6mcfcg7aivfsuosc335k3u:
/webpack-dev-server/4.9.0_gkh3o7gdsall36kyfdv2sybo54:
resolution: {integrity: sha512-+Nlb39iQSOSsFv0lWUuUTim3jDQO8nhK3E68f//J2r5rIcp4lULHXz2oZ0UVdEeWXEh5lSzYUlzarZhDAeAVQw==}
engines: {node: '>= 12.13.0'}
hasBin: true
@ -18204,9 +18228,9 @@ packages:
serve-index: 1.9.1
sockjs: 0.3.24
spdy: 4.0.2
webpack: 5.72.1_webpack-cli@4.9.2
webpack-cli: 4.9.2_dm2ytpn7fgyd7euodvcejn2hda
webpack-dev-middleware: 5.3.1_webpack@5.72.1
webpack: 5.73.0_webpack-cli@4.9.2
webpack-cli: 4.9.2_w5nksobufzg2ereh4ivwj2odyu
webpack-dev-middleware: 5.3.1_webpack@5.73.0
ws: 8.6.0
transitivePeerDependencies:
- bufferutil
@ -18401,7 +18425,48 @@ packages:
tapable: 2.2.1
terser-webpack-plugin: 5.3.1_webpack@5.72.1
watchpack: 2.3.1
webpack-cli: 4.9.2_dm2ytpn7fgyd7euodvcejn2hda
webpack-cli: 4.9.2_w5nksobufzg2ereh4ivwj2odyu
webpack-sources: 3.2.3
transitivePeerDependencies:
- '@swc/core'
- esbuild
- uglify-js
dev: true
/webpack/5.73.0_webpack-cli@4.9.2:
resolution: {integrity: sha512-svjudQRPPa0YiOYa2lM/Gacw0r6PvxptHj4FuEKQ2kX05ZLkjbVc5MnPs6its5j7IZljnIqSVo/OsY2X0IpHGA==}
engines: {node: '>=10.13.0'}
hasBin: true
peerDependencies:
webpack-cli: '*'
peerDependenciesMeta:
webpack-cli:
optional: true
dependencies:
'@types/eslint-scope': 3.7.3
'@types/estree': 0.0.51
'@webassemblyjs/ast': 1.11.1
'@webassemblyjs/wasm-edit': 1.11.1
'@webassemblyjs/wasm-parser': 1.11.1
acorn: 8.7.1
acorn-import-assertions: 1.8.0_acorn@8.7.1
browserslist: 4.20.3
chrome-trace-event: 1.0.3
enhanced-resolve: 5.9.3
es-module-lexer: 0.9.3
eslint-scope: 5.1.1
events: 3.3.0
glob-to-regexp: 0.4.1
graceful-fs: 4.2.10
json-parse-even-better-errors: 2.3.1
loader-runner: 4.3.0
mime-types: 2.1.35
neo-async: 2.6.2
schema-utils: 3.1.1
tapable: 2.2.1
terser-webpack-plugin: 5.3.1_webpack@5.73.0
watchpack: 2.3.1
webpack-cli: 4.9.2_w5nksobufzg2ereh4ivwj2odyu
webpack-sources: 3.2.3
transitivePeerDependencies:
- '@swc/core'
@ -18409,7 +18474,7 @@ packages:
- uglify-js
dev: true
/webpackbar/5.0.2_webpack@5.72.1:
/webpackbar/5.0.2_webpack@5.73.0:
resolution: {integrity: sha512-BmFJo7veBDgQzfWXl/wwYXr/VFus0614qZ8i9znqcl9fnEdiVkdbi0TedLQ6xAK92HZHDJ0QmyQ0fmuZPAgCYQ==}
engines: {node: '>=12'}
peerDependencies:
@ -18419,7 +18484,7 @@ packages:
consola: 2.15.3
pretty-time: 1.1.0
std-env: 3.1.1
webpack: 5.72.1_webpack-cli@4.9.2
webpack: 5.73.0_webpack-cli@4.9.2
dev: true
/websocket-driver/0.7.4:
@ -18658,7 +18723,7 @@ packages:
resolution: {integrity: sha512-BQBzm092w+NqdIEF2yhl32dERt9j9MDGUTa2Eaa+o3YKL4Qqw55W9yQC6f44FdAHdAJrJvp0t+HVrfh8AiGj8A==}
dev: true
/workbox-webpack-plugin/6.5.3_webpack@5.72.1:
/workbox-webpack-plugin/6.5.3_webpack@5.73.0:
resolution: {integrity: sha512-Es8Xr02Gi6Kc3zaUwR691ZLy61hz3vhhs5GztcklQ7kl5k2qAusPh0s6LF3wEtlpfs9ZDErnmy5SErwoll7jBA==}
engines: {node: '>=10.0.0'}
peerDependencies:
@ -18667,7 +18732,7 @@ packages:
fast-json-stable-stringify: 2.1.0
pretty-bytes: 5.6.0
upath: 1.2.0
webpack: 5.72.1_webpack-cli@4.9.2
webpack: 5.73.0_webpack-cli@4.9.2
webpack-sources: 1.4.3
workbox-build: 6.5.3
transitivePeerDependencies:

@ -118,7 +118,7 @@
"tsconfig-paths-webpack-plugin": "^3.5.1",
"typescript": "^4.5.2",
"url-loader": "^4.1.1",
"webpack": "^5.72.0",
"webpack": "5.73.0",
"webpack-bundle-analyzer": "^4.5.0",
"webpack-cli": "^4.9.1",
"webpack-dev-server": "^4.3.1",

Loading…
Cancel
Save