mirror of
https://github.com/chuot/rdio-scanner.git
synced 2026-08-13 08:33:00 -06:00
Version 4.8.0
This commit is contained in:
parent
41e31c5d41
commit
45edec5931
|
|
@ -1,3 +1,12 @@
|
|||
# Version 4.8
|
||||
|
||||
- Add downstream.system.id_as property to allow export system with a different id.
|
||||
- Add system.order for system list ordering on the client side.
|
||||
- Fix client main screen unscrollable overflow while in landscape.
|
||||
- Fix issue 26 - date in documentation for mask isn't clear.
|
||||
- The skip button now also allows you to skip the one second delay between calls.
|
||||
- Node modules update.
|
||||
|
||||
# Version 4.7
|
||||
|
||||
- New dirWatch.type='sdr-trunk'.
|
||||
|
|
|
|||
941
client/package-lock.json
generated
941
client/package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
|
@ -1,29 +1,29 @@
|
|||
{
|
||||
"author": "Chrystian Huot <chrystian.huot@saubeo.solutions>",
|
||||
"dependencies": {
|
||||
"@angular/animations": "^10.1.5",
|
||||
"@angular/cdk": "^10.2.4",
|
||||
"@angular/common": "~10.1.5",
|
||||
"@angular/compiler": "~10.1.5",
|
||||
"@angular/core": "~10.1.5",
|
||||
"@angular/forms": "~10.1.5",
|
||||
"@angular/material": "^10.2.4",
|
||||
"@angular/platform-browser": "~10.1.5",
|
||||
"@angular/platform-browser-dynamic": "~10.1.5",
|
||||
"@angular/service-worker": "~10.1.5",
|
||||
"@angular/animations": "^10.2.0",
|
||||
"@angular/cdk": "^10.2.5",
|
||||
"@angular/common": "~10.2.0",
|
||||
"@angular/compiler": "~10.2.0",
|
||||
"@angular/core": "~10.2.0",
|
||||
"@angular/forms": "~10.2.0",
|
||||
"@angular/material": "^10.2.5",
|
||||
"@angular/platform-browser": "~10.2.0",
|
||||
"@angular/platform-browser-dynamic": "~10.2.0",
|
||||
"@angular/service-worker": "~10.2.0",
|
||||
"rxjs": "~6.6.3",
|
||||
"tslib": "^2.0.3",
|
||||
"zone.js": "~0.10.3"
|
||||
"zone.js": "~0.11.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@angular-devkit/build-angular": "~0.1001.6",
|
||||
"@angular/cli": "^10.1.6",
|
||||
"@angular/compiler-cli": "~10.1.5",
|
||||
"@types/node": "~14.11.8",
|
||||
"@angular-devkit/build-angular": "~0.1002.0",
|
||||
"@angular/cli": "^10.2.0",
|
||||
"@angular/compiler-cli": "~10.2.0",
|
||||
"@types/node": "~14.14.2",
|
||||
"codelyzer": "^6.0.1",
|
||||
"ts-node": "~9.0.0",
|
||||
"tslint": "~6.1.3",
|
||||
"typescript": "~3.9.7"
|
||||
"typescript": "~4.0.3"
|
||||
},
|
||||
"license": "LICENSE",
|
||||
"name": "rdio-scanner-client",
|
||||
|
|
@ -32,5 +32,5 @@
|
|||
"build": "ng build --base-href ./ --prod",
|
||||
"start": "ng serve"
|
||||
},
|
||||
"version": "4.7.6"
|
||||
"version": "4.8.0"
|
||||
}
|
||||
|
|
|
|||
20
client/src/app/components/rdio-scanner/index.ts
Normal file
20
client/src/app/components/rdio-scanner/index.ts
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
* *****************************************************************************
|
||||
* Copyright (C) 2019-2020 Chrystian Huot
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
* ****************************************************************************
|
||||
*/
|
||||
|
||||
export * from './rdio-scanner.module';
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
:host {
|
||||
box-sizing: border-box;
|
||||
display: block;
|
||||
max-height: 100%;
|
||||
max-width: 640px;
|
||||
min-width: 0;
|
||||
padding: 24px;
|
||||
|
|
|
|||
|
|
@ -17,7 +17,8 @@
|
|||
* ****************************************************************************
|
||||
*/
|
||||
|
||||
import { Component, ElementRef, EventEmitter, HostListener, OnDestroy, Output } from '@angular/core';
|
||||
import { Component, ElementRef, HostListener, OnDestroy, ViewChild } from '@angular/core';
|
||||
import { MatSidenav } from '@angular/material/sidenav';
|
||||
import { RdioScannerEvent, RdioScannerLivefeedMode } from './rdio-scanner';
|
||||
import { AppRdioScannerService } from './rdio-scanner.service';
|
||||
|
||||
|
|
@ -27,12 +28,14 @@ import { AppRdioScannerService } from './rdio-scanner.service';
|
|||
templateUrl: './rdio-scanner.component.html',
|
||||
})
|
||||
export class AppRdioScannerComponent implements OnDestroy {
|
||||
@Output() readonly live = new EventEmitter<boolean>();
|
||||
|
||||
private eventSubscription = this.appRdioScannerService.event.subscribe((event: RdioScannerEvent) => this.eventHandler(event));
|
||||
|
||||
private livefeedMode: RdioScannerLivefeedMode = RdioScannerLivefeedMode.Offline;
|
||||
|
||||
@ViewChild('searchPanel') private searchPanel: MatSidenav | undefined;
|
||||
|
||||
@ViewChild('selectPanel') private selectPanel: MatSidenav | undefined;
|
||||
|
||||
constructor(
|
||||
private appRdioScannerService: AppRdioScannerService,
|
||||
private ngElementRef: ElementRef,
|
||||
|
|
@ -47,10 +50,20 @@ export class AppRdioScannerComponent implements OnDestroy {
|
|||
}
|
||||
}
|
||||
|
||||
start(): void {
|
||||
this.appRdioScannerService.startLivefeed();
|
||||
}
|
||||
|
||||
stop(): void {
|
||||
this.appRdioScannerService.stopLivefeed();
|
||||
|
||||
this.searchPanel?.close();
|
||||
|
||||
this.selectPanel?.close();
|
||||
}
|
||||
|
||||
ngOnDestroy(): void {
|
||||
this.eventSubscription.unsubscribe();
|
||||
|
||||
this.live.complete();
|
||||
}
|
||||
|
||||
toggleFullscreen(): void {
|
||||
|
|
@ -64,10 +77,13 @@ export class AppRdioScannerComponent implements OnDestroy {
|
|||
|
||||
if (el.exitFullscreen) {
|
||||
el.exitFullscreen();
|
||||
|
||||
} else if (el.mozCancelFullScreen) {
|
||||
el.mozCancelFullScreen();
|
||||
|
||||
} else if (el.msExitFullscreen) {
|
||||
el.msExitFullscreen();
|
||||
|
||||
} else if (el.webkitExitFullscreen) {
|
||||
el.webkitExitFullscreen();
|
||||
}
|
||||
|
|
@ -77,10 +93,13 @@ export class AppRdioScannerComponent implements OnDestroy {
|
|||
|
||||
if (el.requestFullscreen) {
|
||||
el.requestFullscreen();
|
||||
|
||||
} else if (el.mozRequestFullScreen) {
|
||||
el.mozRequestFullScreen();
|
||||
|
||||
} else if (el.msRequestFullscreen) {
|
||||
el.msRequestFullscreen();
|
||||
|
||||
} else if (el.webkitRequestFullscreen) {
|
||||
el.webkitRequestFullscreen();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@
|
|||
*/
|
||||
|
||||
import { DOCUMENT } from '@angular/common';
|
||||
import { EventEmitter, Inject, Injectable, OnDestroy } from '@angular/core';
|
||||
import { EventEmitter, Inject, Injectable, OnDestroy, SystemJsNgModuleLoader } from '@angular/core';
|
||||
import { interval, Subscription, timer } from 'rxjs';
|
||||
import { takeWhile } from 'rxjs/operators';
|
||||
import {
|
||||
|
|
@ -209,7 +209,7 @@ export class AppRdioScannerService implements OnDestroy {
|
|||
});
|
||||
}
|
||||
|
||||
holdSystem(options?: { resubscribe: boolean }): void {
|
||||
holdSystem(options?: { resubscribe?: boolean }): void {
|
||||
const call = this.call || this.callPrevious;
|
||||
|
||||
if (call && this.livefeedMap) {
|
||||
|
|
@ -263,7 +263,7 @@ export class AppRdioScannerService implements OnDestroy {
|
|||
}
|
||||
}
|
||||
|
||||
holdTalkgroup(options?: { resubscribe: boolean }): void {
|
||||
holdTalkgroup(options?: { resubscribe?: boolean }): void {
|
||||
const call = this.call || this.callPrevious;
|
||||
|
||||
if (call && this.livefeedMap) {
|
||||
|
|
@ -345,6 +345,14 @@ export class AppRdioScannerService implements OnDestroy {
|
|||
if (this.livefeedMode === RdioScannerLivefeedMode.Offline) {
|
||||
this.livefeedMode = RdioScannerLivefeedMode.Playback;
|
||||
|
||||
if (this.livefeedMapPriorToHoldSystem) {
|
||||
this.holdSystem({ resubscribe: false });
|
||||
}
|
||||
|
||||
if (this.livefeedMapPriorToHoldTalkgroup) {
|
||||
this.holdTalkgroup({ resubscribe: false });
|
||||
}
|
||||
|
||||
this.event.emit({ livefeedMode: this.livefeedMode, playbackPending: id });
|
||||
|
||||
} else if (this.livefeedMode === RdioScannerLivefeedMode.Playback) {
|
||||
|
|
@ -489,10 +497,24 @@ export class AppRdioScannerService implements OnDestroy {
|
|||
});
|
||||
|
||||
} else {
|
||||
if (this.skipDelay) {
|
||||
this.skipDelay?.unsubscribe();
|
||||
|
||||
this.skipDelay = undefined;
|
||||
}
|
||||
|
||||
play();
|
||||
}
|
||||
}
|
||||
|
||||
startLivefeed(): void {
|
||||
this.livefeedMode = RdioScannerLivefeedMode.Online;
|
||||
|
||||
this.event.emit({ livefeedMode: this.livefeedMode });
|
||||
|
||||
this.sendtoWebsocket(WebsocketCommand.LivefeedMap, this.livefeedMap);
|
||||
}
|
||||
|
||||
stop(options?: { emit?: boolean }): void {
|
||||
if (this.audioSource) {
|
||||
this.audioSource.onended = null;
|
||||
|
|
@ -513,6 +535,18 @@ export class AppRdioScannerService implements OnDestroy {
|
|||
}
|
||||
}
|
||||
|
||||
stopLivefeed(): void {
|
||||
this.livefeedMode = RdioScannerLivefeedMode.Offline;
|
||||
|
||||
this.clearQueue();
|
||||
|
||||
this.event.emit({ livefeedMode: this.livefeedMode, queue: 0 });
|
||||
|
||||
this.stop();
|
||||
|
||||
this.sendtoWebsocket(WebsocketCommand.LivefeedMap, null);
|
||||
}
|
||||
|
||||
stopPlaybackMode(): void {
|
||||
this.livefeedMode = RdioScannerLivefeedMode.Offline;
|
||||
|
||||
|
|
@ -745,7 +779,7 @@ export class AppRdioScannerService implements OnDestroy {
|
|||
dimmerDelay: typeof config.dimmerDelay === 'number' ? config.dimmerDelay : 5000,
|
||||
groups: typeof config.groups !== null && typeof config.groups === 'object' ? config.groups : {},
|
||||
keypadBeeps: config.keypadBeeps !== null && typeof config.keypadBeeps === 'object' ? config.keypadBeeps : {},
|
||||
systems: Array.isArray(config.systems) ? config.systems : [],
|
||||
systems: Array.isArray(config.systems) ? config.systems.slice() : [],
|
||||
tags: typeof config.tags !== null && typeof config.tags === 'object' ? config.tags : {},
|
||||
};
|
||||
|
||||
|
|
@ -905,26 +939,6 @@ export class AppRdioScannerService implements OnDestroy {
|
|||
}
|
||||
}
|
||||
|
||||
private startLivefeed(): void {
|
||||
this.livefeedMode = RdioScannerLivefeedMode.Online;
|
||||
|
||||
this.event.emit({ livefeedMode: this.livefeedMode });
|
||||
|
||||
this.sendtoWebsocket(WebsocketCommand.LivefeedMap, this.livefeedMap);
|
||||
}
|
||||
|
||||
private stopLivefeed(): void {
|
||||
this.livefeedMode = RdioScannerLivefeedMode.Offline;
|
||||
|
||||
this.clearQueue();
|
||||
|
||||
this.event.emit({ livefeedMode: this.livefeedMode, queue: 0 });
|
||||
|
||||
this.stop();
|
||||
|
||||
this.sendtoWebsocket(WebsocketCommand.LivefeedMap, null);
|
||||
}
|
||||
|
||||
private storeLivefeedMap(): void {
|
||||
window?.localStorage?.setItem(AppRdioScannerService.LOCAL_STORAGE_KEY, JSON.stringify(this.livefeedMap));
|
||||
}
|
||||
|
|
@ -933,6 +947,10 @@ export class AppRdioScannerService implements OnDestroy {
|
|||
if (Array.isArray(this.config?.systems)) {
|
||||
call.systemData = this.config.systems.find((system) => system.id === call.system);
|
||||
|
||||
if (!call.systemData) {
|
||||
console.log(call.system, call.systemData);
|
||||
}
|
||||
|
||||
if (Array.isArray(call.systemData?.talkgroups)) {
|
||||
call.talkgroupData = call.systemData?.talkgroups.find((talkgroup) => talkgroup.id === call.talkgroup);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -146,6 +146,7 @@ export interface RdioScannerSystem {
|
|||
id: number;
|
||||
label: string;
|
||||
led?: 'blue' | 'cyan' | 'green' | 'magenta' | 'red' | 'white' | 'yellow';
|
||||
order?: number;
|
||||
talkgroups: RdioScannerTalkgroup[];
|
||||
units?: RdioScannerUnit[];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ export class AppRdioScannerSelectComponent implements OnDestroy {
|
|||
|
||||
private eventHandler(event: RdioScannerEvent): void {
|
||||
if (event.config) {
|
||||
this.systems = event.config.systems;
|
||||
this.systems = this.sortSystems(event.config.systems);
|
||||
}
|
||||
|
||||
if (event.groups) {
|
||||
|
|
@ -71,4 +71,21 @@ export class AppRdioScannerSelectComponent implements OnDestroy {
|
|||
this.map = event.map;
|
||||
}
|
||||
}
|
||||
|
||||
private sortSystems(systems: RdioScannerSystem[]): RdioScannerSystem[] {
|
||||
return systems.sort((sysA, sysB) => {
|
||||
if (typeof sysA.order === 'number' && typeof sysB.order !== 'number') {
|
||||
return -1;
|
||||
|
||||
} else if (typeof sysA.order !== 'number' && typeof sysB.order === 'number') {
|
||||
return 1;
|
||||
|
||||
} else if (typeof sysA.order === 'number' && typeof sysB.order === 'number') {
|
||||
return sysA.order - sysB.order;
|
||||
|
||||
} else {
|
||||
return sysA.id - sysB.id;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -322,7 +322,7 @@ dirWatch: {
|
|||
- **frequency** - You may want to fake the frequency which will be displayed on _Rdio Scanner_. Let say that you are recording an AM frequency from _RTLSDR-Airband_, here you would put that frequency.
|
||||
- **frequency** - You may want to simulate the frequency that will be displayed. Say you are recording an AM frequency from _RTLSDR-Airband_, here you would put that frequency.
|
||||
- **mask** - Some metadata can be extracted from the file name of the audio file using specific META tags. You may define a simple mask for the dirWatch or an array of masks. Here is the list of possible META tags:
|
||||
- **#DATE** - extract the date like _20200608_ or _2020-06-08_.
|
||||
- **#DATE** - extract the date like _20201231 (YYYYMMMDD)_ or _2020-12-31 (YYYY-MM-DD)_.
|
||||
- **#HZ** - extract the frequency in hertz like _119100000_.
|
||||
- **#KHZ** - extract the frequency in kilohertz like _119100_.
|
||||
- **#MHZ** - extract the frequency in megahertz like _119.100_.
|
||||
|
|
@ -407,16 +407,24 @@ downstreams: {
|
|||
disabled: boolean;
|
||||
systems: number | number[] | {
|
||||
id: number;
|
||||
talkgroups: number | number[] | "*" | undefined;
|
||||
id_as: number | undefined; // optional, downstream as a dirrerent system.id
|
||||
talkgroups: number | number[] | {
|
||||
id: number,
|
||||
id_as: number, // optional, downstream as a dirrerent talkgroup.id
|
||||
} | "*";
|
||||
} | {
|
||||
id: number;
|
||||
talkgroups: number | number[];
|
||||
}[] | "*" | undefined;
|
||||
id_as: number | undefined; // optional, downstream as a different system.id
|
||||
talkgroups: number | number[] | {
|
||||
id: number,
|
||||
id_as: number, // optional, downstream as a dirrerent talkgroup.id
|
||||
} | "*";
|
||||
}[] | "*";
|
||||
url: string;
|
||||
}[]
|
||||
```
|
||||
|
||||
Default value is an empty array `[]` .
|
||||
Default value is an empty array `[]`.
|
||||
|
||||
**Examples**
|
||||
|
||||
|
|
@ -428,6 +436,7 @@ Default value is an empty array `[]` .
|
|||
"systems": [
|
||||
{
|
||||
"id": 11,
|
||||
"id_as": 7537,
|
||||
"talkgroups": [
|
||||
54241,
|
||||
54125
|
||||
|
|
@ -442,6 +451,7 @@ Default value is an empty array `[]` .
|
|||
},
|
||||
{
|
||||
"id": 21,
|
||||
"id_as": 8086,
|
||||
"talkgroups": [
|
||||
60040,
|
||||
60041,
|
||||
|
|
@ -603,6 +613,7 @@ systems: {
|
|||
id: number;
|
||||
label: string;
|
||||
led?: 'blue' | 'cyan' | 'green' | 'magenta' | 'red' | 'white' | 'yellow';
|
||||
order?: number;
|
||||
talkgroups: {
|
||||
id: number;
|
||||
label: string;
|
||||
|
|
@ -621,7 +632,8 @@ systems: {
|
|||
|
||||
- **id** - System ID.
|
||||
- **label** - System label shown on the left side of second row.
|
||||
- **led** - Optional LED color for the whole system. By default the LED is _green_.
|
||||
- **led** - Optional, LED color for the whole system. By default the LED is _green_.
|
||||
- **order** - Optional, sort order with which systems are displayed on the client side.
|
||||
- **talkgroups** - Talkgroups for the system.
|
||||
- **id** - Talkgroup ID.
|
||||
- **label** - Talkgroup label shown on the left side of third row.
|
||||
|
|
|
|||
|
|
@ -10,5 +10,5 @@
|
|||
"start": "node run",
|
||||
"update": "node update"
|
||||
},
|
||||
"version": "4.7.6"
|
||||
"version": "4.8.0"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -839,6 +839,10 @@ function parseConfig(config) {
|
|||
system.led = ledColors.includes(system.led) ? system.led : 'green';
|
||||
}
|
||||
|
||||
if (system.order !== undefined && typeof system.order !== 'number') {
|
||||
delete system.order;
|
||||
}
|
||||
|
||||
if (!Array.isArray(system.talkgroups)) {
|
||||
system.talkgroups = [];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -133,8 +133,8 @@ class Downstream {
|
|||
}
|
||||
|
||||
form.append('sources', JSON.stringify(call.sources));
|
||||
form.append('system', call.system);
|
||||
form.append('talkgroup', call.talkgroup);
|
||||
form.append('system', this.getSystemId(call, downstream));
|
||||
form.append('talkgroup', this.getTalkgroupId(call, downstream));
|
||||
|
||||
form.submit(apiUrl, (error, response) => {
|
||||
const message = `Downstream: system=${call.system} talkgroup=${call.talkgroup} file=${call.audioName} to=${downstream.url}`;
|
||||
|
|
@ -150,6 +150,56 @@ class Downstream {
|
|||
}
|
||||
});
|
||||
}
|
||||
|
||||
getSystemId(call, downstream) {
|
||||
const parseSystem = (system) => {
|
||||
if (Array.isArray(system)) {
|
||||
system = system.find((sys) => sys !== null && typeof sys === 'object' && sys.id === call.system);
|
||||
|
||||
return system ? parseSystem(system) : call.system;
|
||||
|
||||
} else if (system !== null && typeof system === 'object') {
|
||||
return typeof system.id_as === 'number' && system.id === call.system ? system.id_as : call.system;
|
||||
|
||||
} else {
|
||||
return call.system;
|
||||
}
|
||||
}
|
||||
|
||||
return parseSystem(downstream.systems);
|
||||
}
|
||||
|
||||
getTalkgroupId(call, downstream) {
|
||||
const parseSystem = (system) => {
|
||||
const parseTalkgroup = (talkgroup) => {
|
||||
if (Array.isArray(talkgroup)) {
|
||||
talkgroup = talkgroup.find((tg) => tg !== null && typeof tg === 'object' && tg.id === call.talkgroup);
|
||||
|
||||
return talkgroup ? parseTalkgroup(talkgroup) : call.talkgroup;
|
||||
|
||||
} else if (talkgroup !== null && typeof talkgroup === 'object') {
|
||||
return typeof talkgroup.id_as === 'number' && talkgroup.id === call.talkgroup ? talkgroup.id_as : talkgroup.id;
|
||||
|
||||
} else {
|
||||
return call.talkgroup;
|
||||
}
|
||||
}
|
||||
|
||||
if (Array.isArray(system)) {
|
||||
system = system.find((sys) => sys !== null && typeof sys === 'object' && sys.id === call.system);
|
||||
|
||||
return system ? parseSystem(system) : call.system;
|
||||
|
||||
} else if (system !== null && typeof system === 'object') {
|
||||
return system.id === call.system ? parseTalkgroup(system.talkgroups) : call.talkgroup;
|
||||
|
||||
} else {
|
||||
return call.system;
|
||||
}
|
||||
}
|
||||
|
||||
return parseSystem(downstream.systems);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Downstream;
|
||||
|
|
|
|||
|
|
@ -53,6 +53,10 @@ rdioScannerSystemFactory.Schema = {
|
|||
type: DataTypes.STRING,
|
||||
allowNull: true,
|
||||
},
|
||||
order: {
|
||||
type: DataTypes.INTEGER,
|
||||
allowNull: true,
|
||||
},
|
||||
talkgroups: {
|
||||
type: DataTypes.JSON,
|
||||
defaultValue: [],
|
||||
|
|
|
|||
5536
server/package-lock.json
generated
5536
server/package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
|
@ -1,17 +1,17 @@
|
|||
{
|
||||
"author": "Chrystian Huot <chrystian.huot@saubeo.solutions>",
|
||||
"dependencies": {
|
||||
"chokidar": "^3.4.2",
|
||||
"chokidar": "^3.4.3",
|
||||
"cors": "^2.8.5",
|
||||
"dotenv": "^8.2.0",
|
||||
"express": "^4.17.1",
|
||||
"form-data": "^3.0.0",
|
||||
"helmet": "^4.1.1",
|
||||
"mariadb": "^2.4.2",
|
||||
"mariadb": "^2.5.1",
|
||||
"mime-types": "^2.1.27",
|
||||
"multer": "^1.4.2",
|
||||
"mysql2": "^2.2.5",
|
||||
"nodemon": "^2.0.4",
|
||||
"nodemon": "^2.0.6",
|
||||
"pg": "^8.4.1",
|
||||
"sequelize": "^6.3.5",
|
||||
"sqlite3": "^5.0.0",
|
||||
|
|
@ -20,9 +20,9 @@
|
|||
"ws": "^7.3.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"eslint": "^7.11.0",
|
||||
"webpack": "^5.0.0",
|
||||
"webpack-cli": "^4.0.0",
|
||||
"eslint": "^7.12.0",
|
||||
"webpack": "^5.2.0",
|
||||
"webpack-cli": "^4.1.0",
|
||||
"webpack-node-externals": "^2.5.2"
|
||||
},
|
||||
"license": "LICENSE",
|
||||
|
|
@ -39,5 +39,5 @@
|
|||
"build": "webpack",
|
||||
"start": "nodemon"
|
||||
},
|
||||
"version": "4.7.6"
|
||||
"version": "4.8.0"
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue