Adds local storage provider

This commit is contained in:
Chris Anderson 2023-03-06 20:44:12 -06:00
parent 11ffbc85c8
commit e60641960f
11 changed files with 441 additions and 177 deletions

View file

@ -2,6 +2,8 @@ name: Create & Publish Docker Image
on:
push:
branches:
- "feat/local-storage"
tags:
- "v*.*.*"

View file

@ -107,3 +107,6 @@ build
# VS Code
.DS_Store
# Uploads
/public/uploads

View file

@ -13,6 +13,7 @@ COPY --from=compile /usr/src/app/apps/platform/package*.json ./
COPY --from=compile /usr/src/app/apps/platform/build ./
COPY --from=compile /usr/src/app/apps/platform/db ./db
COPY --from=compile /usr/src/app/apps/platform/scripts ./scripts
COPY --from=compile /usr/src/app/apps/platform/public ./public
RUN npm ci --only=production
# --------------> The production image

View file

@ -30,6 +30,7 @@
"koa": "^2.13.4",
"koa-body": "5.0.0",
"koa-jwt": "^4.0.3",
"koa-static": "^5.0.0",
"mysql2": "^2.3.3",
"node-pushnotifications": "^2.0.3",
"node-schedule": "^2.1.0",
@ -54,6 +55,7 @@
"@types/jsonwebtoken": "^8.5.9",
"@types/koa__cors": "^3.3.0",
"@types/koa__router": "^8.0.11",
"@types/koa-static": "^4.0.2",
"@types/node": "^18.7.18",
"@types/node-pushnotifications": "^1.0.4",
"@types/node-schedule": "^2.1.0",

View file

@ -1,6 +1,7 @@
import Koa from 'koa'
import koaBody from 'koa-body'
import cors from '@koa/cors'
import serve from 'koa-static'
import controllers from './config/controllers'
import { RequestError } from './core/errors'
@ -18,6 +19,10 @@ export default class Api extends Koa {
ctx.state.app = this.app
return next()
})
.use(serve('./public', {
hidden: true,
defer: true,
}))
this.use(async (ctx, next) => {
try {

View file

@ -53,19 +53,20 @@ export default (type?: EnvType): Env => {
},
}),
}),
storage: {
baseUrl: process.env.STORAGE_BASE_URL!,
...driver<Omit<StorageConfig, 'baseUrl'>>(process.env.STORAGE_DRIVER, {
s3: () => ({
bucket: process.env.AWS_S3_BUCKET!,
region: process.env.AWS_REGION!,
credentials: {
accessKeyId: process.env.AWS_ACCESS_KEY_ID!,
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY!,
},
}),
storage: driver<StorageConfig>(process.env.STORAGE_DRIVER ?? 'local', {
s3: () => ({
baseUrl: process.env.STORAGE_BASE_URL!,
bucket: process.env.AWS_S3_BUCKET!,
region: process.env.AWS_REGION!,
credentials: {
accessKeyId: process.env.AWS_ACCESS_KEY_ID!,
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY!,
},
}),
},
local: () => ({
baseUrl: process.env.BASE_URL!,
}),
}),
baseUrl: process.env.BASE_URL!,
port: parseInt(process.env.PORT!),
secret: process.env.APP_SECRET!,

View file

@ -0,0 +1,26 @@
import fs from 'fs/promises'
import path from 'path'
import { StorageTypeConfig } from './Storage'
import { ImageUploadTask, StorageProvider } from './StorageProvider'
export interface LocalConfig extends StorageTypeConfig {
driver: 'local'
}
export class LocalStorageProvider implements StorageProvider {
path(filename: string) {
return path.join(process.cwd(), 'public', 'uploads', filename)
}
async upload(task: ImageUploadTask) {
await fs.writeFile(
task.url,
task.stream,
)
}
async delete(filename: string): Promise<void> {
await fs.unlink(filename)
}
}

View file

@ -6,6 +6,7 @@ import { StorageTypeConfig } from './Storage'
import { ImageUploadTask, StorageProvider } from './StorageProvider'
export interface S3Config extends StorageTypeConfig, AWSConfig {
driver: 's3'
bucket: string
}
@ -17,6 +18,10 @@ export class S3StorageProvider implements StorageProvider {
this.config = config
}
path(filename: string) {
return filename
}
async upload(task: ImageUploadTask) {
const pass = new PassThrough()
const s3 = new S3(this.config)

View file

@ -8,10 +8,12 @@ import { combineURLs, uuid } from '../utilities'
import { InternalError } from '../core/errors'
import StorageError from './StorageError'
import App from '../app'
import { LocalConfig, LocalStorageProvider } from './LocalStorageProvider'
export type StorageConfig = S3Config & { baseUrl: string }
export type StorageConfig = S3Config | LocalConfig
export interface StorageTypeConfig extends DriverConfig {
driver: StorageProviderName
baseUrl: string
}
export interface ImageUpload {
@ -24,6 +26,8 @@ export default class Storage {
constructor(config?: StorageConfig) {
if (config?.driver === 's3') {
this.provider = new S3StorageProvider(config)
} else if (config?.driver === 'local') {
this.provider = new LocalStorageProvider()
} else {
throw new InternalError(StorageError.UndefinedStorageMethod)
}
@ -34,7 +38,7 @@ export default class Storage {
const originalPath = path.parse(image.metadata.fileName)
const extension = originalPath.ext
const fileName = originalPath.name
const url = `${key}${extension}`
const url = this.provider.path(`${key}${extension}`)
await this.upload({
stream: image.file,

View file

@ -1,6 +1,6 @@
import { Stream } from 'stream'
export type StorageProviderName = 's3'
export type StorageProviderName = 's3' | 'local'
export interface ImageUploadTask {
stream: Stream
@ -8,6 +8,7 @@ export interface ImageUploadTask {
}
export interface StorageProvider {
path(filename: string): string
upload(task: ImageUploadTask): Promise<void>
delete(filename: string): Promise<void>
}

538
package-lock.json generated
View file

@ -43,6 +43,7 @@
"koa": "^2.13.4",
"koa-body": "5.0.0",
"koa-jwt": "^4.0.3",
"koa-static": "^5.0.0",
"mysql2": "^2.3.3",
"node-pushnotifications": "^2.0.3",
"node-schedule": "^2.1.0",
@ -58,6 +59,7 @@
"@types/jsonwebtoken": "^8.5.9",
"@types/koa__cors": "^3.3.0",
"@types/koa__router": "^8.0.11",
"@types/koa-static": "^4.0.2",
"@types/node": "^18.7.18",
"@types/node-pushnotifications": "^1.0.4",
"@types/node-schedule": "^2.1.0",
@ -2531,14 +2533,6 @@
"dev": true,
"license": "MIT"
},
"apps/platform/node_modules/@types/accepts": {
"version": "1.3.5",
"dev": true,
"license": "MIT",
"dependencies": {
"@types/node": "*"
}
},
"apps/platform/node_modules/@types/babel__core": {
"version": "7.1.20",
"dev": true,
@ -2584,22 +2578,6 @@
"@types/node": "*"
}
},
"apps/platform/node_modules/@types/content-disposition": {
"version": "0.5.5",
"dev": true,
"license": "MIT"
},
"apps/platform/node_modules/@types/cookies": {
"version": "0.7.7",
"dev": true,
"license": "MIT",
"dependencies": {
"@types/connect": "*",
"@types/express": "*",
"@types/keygrip": "*",
"@types/node": "*"
}
},
"apps/platform/node_modules/@types/formidable": {
"version": "2.0.5",
"license": "MIT",
@ -2615,16 +2593,6 @@
"@types/node": "*"
}
},
"apps/platform/node_modules/@types/http-assert": {
"version": "1.5.3",
"dev": true,
"license": "MIT"
},
"apps/platform/node_modules/@types/http-errors": {
"version": "2.0.1",
"dev": true,
"license": "MIT"
},
"apps/platform/node_modules/@types/istanbul-lib-coverage": {
"version": "2.0.4",
"dev": true,
@ -2679,26 +2647,6 @@
"@types/node": "*"
}
},
"apps/platform/node_modules/@types/keygrip": {
"version": "1.0.2",
"dev": true,
"license": "MIT"
},
"apps/platform/node_modules/@types/koa": {
"version": "2.13.5",
"dev": true,
"license": "MIT",
"dependencies": {
"@types/accepts": "*",
"@types/content-disposition": "*",
"@types/cookies": "*",
"@types/http-assert": "*",
"@types/http-errors": "*",
"@types/keygrip": "*",
"@types/koa-compose": "*",
"@types/node": "*"
}
},
"apps/platform/node_modules/@types/koa__cors": {
"version": "3.3.0",
"dev": true,
@ -2715,14 +2663,6 @@
"@types/koa": "*"
}
},
"apps/platform/node_modules/@types/koa-compose": {
"version": "3.2.5",
"dev": true,
"license": "MIT",
"dependencies": {
"@types/koa": "*"
}
},
"apps/platform/node_modules/@types/node-pushnotifications": {
"version": "1.0.4",
"dev": true,
@ -8621,10 +8561,6 @@
"node": ">=0.10.0"
}
},
"apps/platform/node_modules/setprototypeof": {
"version": "1.2.0",
"license": "ISC"
},
"apps/platform/node_modules/side-channel": {
"version": "1.0.4",
"license": "MIT",
@ -9294,13 +9230,6 @@
"node": ">=0.10.0"
}
},
"apps/platform/node_modules/toidentifier": {
"version": "1.0.1",
"license": "MIT",
"engines": {
"node": ">=0.6"
}
},
"apps/platform/node_modules/touch": {
"version": "3.1.0",
"dev": true,
@ -9864,7 +9793,6 @@
"@types/uuid": "^9.0.0",
"autoprefixer": "^10.4.12",
"axios": "0.27.2",
"bootstrap-icons": "1.10.3",
"clsx": "^1.2.1",
"date-fns": "^2.29.3",
"date-fns-tz": "^1.3.7",
@ -14674,10 +14602,6 @@
"version": "1.0.0",
"license": "ISC"
},
"apps/ui/node_modules/bootstrap-icons": {
"version": "1.10.3",
"license": "MIT"
},
"apps/ui/node_modules/browser-process-hrtime": {
"version": "1.0.0",
"license": "BSD-2-Clause"
@ -21468,10 +21392,6 @@
"node": ">= 0.8.0"
}
},
"apps/ui/node_modules/setprototypeof": {
"version": "1.2.0",
"license": "ISC"
},
"apps/ui/node_modules/shell-quote": {
"version": "1.7.4",
"license": "MIT",
@ -22096,13 +22016,6 @@
"version": "1.0.6",
"license": "MIT"
},
"apps/ui/node_modules/toidentifier": {
"version": "1.0.1",
"license": "MIT",
"engines": {
"node": ">=0.6"
}
},
"apps/ui/node_modules/tough-cookie": {
"version": "4.1.2",
"license": "BSD-3-Clause",
@ -24818,6 +24731,15 @@
"node": ">= 10"
}
},
"node_modules/@types/accepts": {
"version": "1.3.5",
"resolved": "https://registry.npmjs.org/@types/accepts/-/accepts-1.3.5.tgz",
"integrity": "sha512-jOdnI/3qTpHABjM5cx1Hc0sKsPoYCp+DP/GJRGtDlPd7fiV9oXGGIcjW/ZOxLIvjGz8MA+uMZI9metHlgqbgwQ==",
"dev": true,
"dependencies": {
"@types/node": "*"
}
},
"node_modules/@types/body-parser": {
"version": "1.19.2",
"resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz",
@ -24835,6 +24757,24 @@
"@types/node": "*"
}
},
"node_modules/@types/content-disposition": {
"version": "0.5.5",
"resolved": "https://registry.npmjs.org/@types/content-disposition/-/content-disposition-0.5.5.tgz",
"integrity": "sha512-v6LCdKfK6BwcqMo+wYW05rLS12S0ZO0Fl4w1h4aaZMD7bqT3gVUns6FvLJKGZHQmYn3SX55JWGpziwJRwVgutA==",
"dev": true
},
"node_modules/@types/cookies": {
"version": "0.7.7",
"resolved": "https://registry.npmjs.org/@types/cookies/-/cookies-0.7.7.tgz",
"integrity": "sha512-h7BcvPUogWbKCzBR2lY4oqaZbO3jXZksexYJVFvkrFeLgbZjQkU4x8pRq6eg2MHXQhY0McQdqmmsxRWlVAHooA==",
"dev": true,
"dependencies": {
"@types/connect": "*",
"@types/express": "*",
"@types/keygrip": "*",
"@types/node": "*"
}
},
"node_modules/@types/debug": {
"version": "4.1.7",
"resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.7.tgz",
@ -24864,6 +24804,68 @@
"@types/range-parser": "*"
}
},
"node_modules/@types/http-assert": {
"version": "1.5.3",
"resolved": "https://registry.npmjs.org/@types/http-assert/-/http-assert-1.5.3.tgz",
"integrity": "sha512-FyAOrDuQmBi8/or3ns4rwPno7/9tJTijVW6aQQjK02+kOQ8zmoNg2XJtAuQhvQcy1ASJq38wirX5//9J1EqoUA==",
"dev": true
},
"node_modules/@types/http-errors": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.1.tgz",
"integrity": "sha512-/K3ds8TRAfBvi5vfjuz8y6+GiAYBZ0x4tXv1Av6CWBWn0IlADc+ZX9pMq7oU0fNQPnBwIZl3rmeLp6SBApbxSQ==",
"dev": true
},
"node_modules/@types/keygrip": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/@types/keygrip/-/keygrip-1.0.2.tgz",
"integrity": "sha512-GJhpTepz2udxGexqos8wgaBx4I/zWIDPh/KOGEwAqtuGDkOUJu5eFvwmdBX4AmB8Odsr+9pHCQqiAqDL/yKMKw==",
"dev": true
},
"node_modules/@types/koa": {
"version": "2.13.5",
"resolved": "https://registry.npmjs.org/@types/koa/-/koa-2.13.5.tgz",
"integrity": "sha512-HSUOdzKz3by4fnqagwthW/1w/yJspTgppyyalPVbgZf8jQWvdIXcVW5h2DGtw4zYntOaeRGx49r1hxoPWrD4aA==",
"dev": true,
"dependencies": {
"@types/accepts": "*",
"@types/content-disposition": "*",
"@types/cookies": "*",
"@types/http-assert": "*",
"@types/http-errors": "*",
"@types/keygrip": "*",
"@types/koa-compose": "*",
"@types/node": "*"
}
},
"node_modules/@types/koa-compose": {
"version": "3.2.5",
"resolved": "https://registry.npmjs.org/@types/koa-compose/-/koa-compose-3.2.5.tgz",
"integrity": "sha512-B8nG/OoE1ORZqCkBVsup/AKcvjdgoHnfi4pZMn5UwAPCbhk/96xyv284eBYW8JlQbQ7zDmnpFr68I/40mFoIBQ==",
"dev": true,
"dependencies": {
"@types/koa": "*"
}
},
"node_modules/@types/koa-send": {
"version": "4.1.3",
"resolved": "https://registry.npmjs.org/@types/koa-send/-/koa-send-4.1.3.tgz",
"integrity": "sha512-daaTqPZlgjIJycSTNjKpHYuKhXYP30atFc1pBcy6HHqB9+vcymDgYTguPdx9tO4HMOqNyz6bz/zqpxt5eLR+VA==",
"dev": true,
"dependencies": {
"@types/koa": "*"
}
},
"node_modules/@types/koa-static": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/@types/koa-static/-/koa-static-4.0.2.tgz",
"integrity": "sha512-ns/zHg+K6XVPMuohjpOlpkR1WLa4VJ9czgUP9bxkCDn0JZBtUWbD/wKDZzPGDclkQK1bpAEScufCHOy8cbfL0w==",
"dev": true,
"dependencies": {
"@types/koa": "*",
"@types/koa-send": "*"
}
},
"node_modules/@types/mime": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/@types/mime/-/mime-3.0.1.tgz",
@ -25934,7 +25936,6 @@
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
"integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==",
"dev": true,
"engines": {
"node": ">= 0.6"
}
@ -26733,6 +26734,21 @@
"integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==",
"dev": true
},
"node_modules/http-errors": {
"version": "1.8.1",
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz",
"integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==",
"dependencies": {
"depd": "~1.1.2",
"inherits": "2.0.4",
"setprototypeof": "1.2.0",
"statuses": ">= 1.5.0 < 2",
"toidentifier": "1.0.1"
},
"engines": {
"node": ">= 0.6"
}
},
"node_modules/http-proxy-agent": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz",
@ -27335,6 +27351,39 @@
"node": ">=0.10.0"
}
},
"node_modules/koa-send": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/koa-send/-/koa-send-5.0.1.tgz",
"integrity": "sha512-tmcyQ/wXXuxpDxyNXv5yNNkdAMdFRqwtegBXUaowiQzUKqJehttS0x2j0eOZDQAyloAth5w6wwBImnFzkUz3pQ==",
"dependencies": {
"debug": "^4.1.1",
"http-errors": "^1.7.3",
"resolve-path": "^1.4.0"
},
"engines": {
"node": ">= 8"
}
},
"node_modules/koa-static": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/koa-static/-/koa-static-5.0.0.tgz",
"integrity": "sha512-UqyYyH5YEXaJrf9S8E23GoJFQZXkBVJ9zYYMPGz919MSX1KuvAcycIuS0ci150HCoPf4XQVhQ84Qf8xRPWxFaQ==",
"dependencies": {
"debug": "^3.1.0",
"koa-send": "^5.0.0"
},
"engines": {
"node": ">= 7.6.0"
}
},
"node_modules/koa-static/node_modules/debug": {
"version": "3.2.7",
"resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
"integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
"dependencies": {
"ms": "^2.1.1"
}
},
"node_modules/lerna": {
"version": "6.4.1",
"resolved": "https://registry.npmjs.org/lerna/-/lerna-6.4.1.tgz",
@ -29485,6 +29534,42 @@
"node": ">=8"
}
},
"node_modules/resolve-path": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/resolve-path/-/resolve-path-1.4.0.tgz",
"integrity": "sha512-i1xevIst/Qa+nA9olDxLWnLk8YZbi8R/7JPbCMcgyWaFR6bKWaexgJgEB5oc2PKMjYdrHynyz0NY+if+H98t1w==",
"dependencies": {
"http-errors": "~1.6.2",
"path-is-absolute": "1.0.1"
},
"engines": {
"node": ">= 0.8"
}
},
"node_modules/resolve-path/node_modules/http-errors": {
"version": "1.6.3",
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz",
"integrity": "sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==",
"dependencies": {
"depd": "~1.1.2",
"inherits": "2.0.3",
"setprototypeof": "1.1.0",
"statuses": ">= 1.4.0 < 2"
},
"engines": {
"node": ">= 0.6"
}
},
"node_modules/resolve-path/node_modules/inherits": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
"integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw=="
},
"node_modules/resolve-path/node_modules/setprototypeof": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz",
"integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ=="
},
"node_modules/restore-cursor": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz",
@ -29657,6 +29742,11 @@
"integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==",
"dev": true
},
"node_modules/setprototypeof": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
"integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="
},
"node_modules/shallow-clone": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz",
@ -29841,6 +29931,14 @@
"node": "^12.13.0 || ^14.15.0 || >=16.0.0"
}
},
"node_modules/statuses": {
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
"integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/string_decoder": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
@ -30037,6 +30135,14 @@
"node": ">=8.0"
}
},
"node_modules/toidentifier": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
"integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==",
"engines": {
"node": ">=0.6"
}
},
"node_modules/tr46": {
"version": "0.0.3",
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
@ -31936,6 +32042,15 @@
"integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==",
"dev": true
},
"@types/accepts": {
"version": "1.3.5",
"resolved": "https://registry.npmjs.org/@types/accepts/-/accepts-1.3.5.tgz",
"integrity": "sha512-jOdnI/3qTpHABjM5cx1Hc0sKsPoYCp+DP/GJRGtDlPd7fiV9oXGGIcjW/ZOxLIvjGz8MA+uMZI9metHlgqbgwQ==",
"dev": true,
"requires": {
"@types/node": "*"
}
},
"@types/body-parser": {
"version": "1.19.2",
"resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz",
@ -31953,6 +32068,24 @@
"@types/node": "*"
}
},
"@types/content-disposition": {
"version": "0.5.5",
"resolved": "https://registry.npmjs.org/@types/content-disposition/-/content-disposition-0.5.5.tgz",
"integrity": "sha512-v6LCdKfK6BwcqMo+wYW05rLS12S0ZO0Fl4w1h4aaZMD7bqT3gVUns6FvLJKGZHQmYn3SX55JWGpziwJRwVgutA==",
"dev": true
},
"@types/cookies": {
"version": "0.7.7",
"resolved": "https://registry.npmjs.org/@types/cookies/-/cookies-0.7.7.tgz",
"integrity": "sha512-h7BcvPUogWbKCzBR2lY4oqaZbO3jXZksexYJVFvkrFeLgbZjQkU4x8pRq6eg2MHXQhY0McQdqmmsxRWlVAHooA==",
"dev": true,
"requires": {
"@types/connect": "*",
"@types/express": "*",
"@types/keygrip": "*",
"@types/node": "*"
}
},
"@types/debug": {
"version": "4.1.7",
"resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.7.tgz",
@ -31982,6 +32115,68 @@
"@types/range-parser": "*"
}
},
"@types/http-assert": {
"version": "1.5.3",
"resolved": "https://registry.npmjs.org/@types/http-assert/-/http-assert-1.5.3.tgz",
"integrity": "sha512-FyAOrDuQmBi8/or3ns4rwPno7/9tJTijVW6aQQjK02+kOQ8zmoNg2XJtAuQhvQcy1ASJq38wirX5//9J1EqoUA==",
"dev": true
},
"@types/http-errors": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.1.tgz",
"integrity": "sha512-/K3ds8TRAfBvi5vfjuz8y6+GiAYBZ0x4tXv1Av6CWBWn0IlADc+ZX9pMq7oU0fNQPnBwIZl3rmeLp6SBApbxSQ==",
"dev": true
},
"@types/keygrip": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/@types/keygrip/-/keygrip-1.0.2.tgz",
"integrity": "sha512-GJhpTepz2udxGexqos8wgaBx4I/zWIDPh/KOGEwAqtuGDkOUJu5eFvwmdBX4AmB8Odsr+9pHCQqiAqDL/yKMKw==",
"dev": true
},
"@types/koa": {
"version": "2.13.5",
"resolved": "https://registry.npmjs.org/@types/koa/-/koa-2.13.5.tgz",
"integrity": "sha512-HSUOdzKz3by4fnqagwthW/1w/yJspTgppyyalPVbgZf8jQWvdIXcVW5h2DGtw4zYntOaeRGx49r1hxoPWrD4aA==",
"dev": true,
"requires": {
"@types/accepts": "*",
"@types/content-disposition": "*",
"@types/cookies": "*",
"@types/http-assert": "*",
"@types/http-errors": "*",
"@types/keygrip": "*",
"@types/koa-compose": "*",
"@types/node": "*"
}
},
"@types/koa-compose": {
"version": "3.2.5",
"resolved": "https://registry.npmjs.org/@types/koa-compose/-/koa-compose-3.2.5.tgz",
"integrity": "sha512-B8nG/OoE1ORZqCkBVsup/AKcvjdgoHnfi4pZMn5UwAPCbhk/96xyv284eBYW8JlQbQ7zDmnpFr68I/40mFoIBQ==",
"dev": true,
"requires": {
"@types/koa": "*"
}
},
"@types/koa-send": {
"version": "4.1.3",
"resolved": "https://registry.npmjs.org/@types/koa-send/-/koa-send-4.1.3.tgz",
"integrity": "sha512-daaTqPZlgjIJycSTNjKpHYuKhXYP30atFc1pBcy6HHqB9+vcymDgYTguPdx9tO4HMOqNyz6bz/zqpxt5eLR+VA==",
"dev": true,
"requires": {
"@types/koa": "*"
}
},
"@types/koa-static": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/@types/koa-static/-/koa-static-4.0.2.tgz",
"integrity": "sha512-ns/zHg+K6XVPMuohjpOlpkR1WLa4VJ9czgUP9bxkCDn0JZBtUWbD/wKDZzPGDclkQK1bpAEScufCHOy8cbfL0w==",
"dev": true,
"requires": {
"@types/koa": "*",
"@types/koa-send": "*"
}
},
"@types/mime": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/@types/mime/-/mime-3.0.1.tgz",
@ -32823,8 +33018,7 @@
"depd": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
"integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==",
"dev": true
"integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ=="
},
"deprecation": {
"version": "2.3.1",
@ -33438,6 +33632,18 @@
"integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==",
"dev": true
},
"http-errors": {
"version": "1.8.1",
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz",
"integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==",
"requires": {
"depd": "~1.1.2",
"inherits": "2.0.4",
"setprototypeof": "1.2.0",
"statuses": ">= 1.5.0 < 2",
"toidentifier": "1.0.1"
}
},
"http-proxy-agent": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz",
@ -33883,6 +34089,35 @@
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
"integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw=="
},
"koa-send": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/koa-send/-/koa-send-5.0.1.tgz",
"integrity": "sha512-tmcyQ/wXXuxpDxyNXv5yNNkdAMdFRqwtegBXUaowiQzUKqJehttS0x2j0eOZDQAyloAth5w6wwBImnFzkUz3pQ==",
"requires": {
"debug": "^4.1.1",
"http-errors": "^1.7.3",
"resolve-path": "^1.4.0"
}
},
"koa-static": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/koa-static/-/koa-static-5.0.0.tgz",
"integrity": "sha512-UqyYyH5YEXaJrf9S8E23GoJFQZXkBVJ9zYYMPGz919MSX1KuvAcycIuS0ci150HCoPf4XQVhQ84Qf8xRPWxFaQ==",
"requires": {
"debug": "^3.1.0",
"koa-send": "^5.0.0"
},
"dependencies": {
"debug": {
"version": "3.2.7",
"resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
"integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
"requires": {
"ms": "^2.1.1"
}
}
}
},
"lerna": {
"version": "6.4.1",
"resolved": "https://registry.npmjs.org/lerna/-/lerna-6.4.1.tgz",
@ -35149,6 +35384,7 @@
"@types/jsonwebtoken": "^8.5.9",
"@types/koa__cors": "^3.3.0",
"@types/koa__router": "^8.0.11",
"@types/koa-static": "^4.0.2",
"@types/node": "^18.7.18",
"@types/node-pushnotifications": "^1.0.4",
"@types/node-schedule": "^2.1.0",
@ -35175,6 +35411,7 @@
"koa": "^2.13.4",
"koa-body": "5.0.0",
"koa-jwt": "^4.0.3",
"koa-static": "^5.0.0",
"mysql2": "^2.3.3",
"node-pushnotifications": "^2.0.3",
"node-schedule": "^2.1.0",
@ -36969,13 +37206,6 @@
"version": "1.0.3",
"dev": true
},
"@types/accepts": {
"version": "1.3.5",
"dev": true,
"requires": {
"@types/node": "*"
}
},
"@types/babel__core": {
"version": "7.1.20",
"dev": true,
@ -37016,20 +37246,6 @@
"@types/node": "*"
}
},
"@types/content-disposition": {
"version": "0.5.5",
"dev": true
},
"@types/cookies": {
"version": "0.7.7",
"dev": true,
"requires": {
"@types/connect": "*",
"@types/express": "*",
"@types/keygrip": "*",
"@types/node": "*"
}
},
"@types/formidable": {
"version": "2.0.5",
"requires": {
@ -37043,14 +37259,6 @@
"@types/node": "*"
}
},
"@types/http-assert": {
"version": "1.5.3",
"dev": true
},
"@types/http-errors": {
"version": "2.0.1",
"dev": true
},
"@types/istanbul-lib-coverage": {
"version": "2.0.4",
"dev": true
@ -37097,24 +37305,6 @@
"@types/node": "*"
}
},
"@types/keygrip": {
"version": "1.0.2",
"dev": true
},
"@types/koa": {
"version": "2.13.5",
"dev": true,
"requires": {
"@types/accepts": "*",
"@types/content-disposition": "*",
"@types/cookies": "*",
"@types/http-assert": "*",
"@types/http-errors": "*",
"@types/keygrip": "*",
"@types/koa-compose": "*",
"@types/node": "*"
}
},
"@types/koa__cors": {
"version": "3.3.0",
"dev": true,
@ -37129,13 +37319,6 @@
"@types/koa": "*"
}
},
"@types/koa-compose": {
"version": "3.2.5",
"dev": true,
"requires": {
"@types/koa": "*"
}
},
"@types/node-pushnotifications": {
"version": "1.0.4",
"dev": true,
@ -40908,9 +41091,6 @@
"split-string": "^3.0.1"
}
},
"setprototypeof": {
"version": "1.2.0"
},
"side-channel": {
"version": "1.0.4",
"requires": {
@ -41367,9 +41547,6 @@
}
}
},
"toidentifier": {
"version": "1.0.1"
},
"touch": {
"version": "3.1.0",
"dev": true,
@ -42071,6 +42248,38 @@
"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
"integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw=="
},
"resolve-path": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/resolve-path/-/resolve-path-1.4.0.tgz",
"integrity": "sha512-i1xevIst/Qa+nA9olDxLWnLk8YZbi8R/7JPbCMcgyWaFR6bKWaexgJgEB5oc2PKMjYdrHynyz0NY+if+H98t1w==",
"requires": {
"http-errors": "~1.6.2",
"path-is-absolute": "1.0.1"
},
"dependencies": {
"http-errors": {
"version": "1.6.3",
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz",
"integrity": "sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==",
"requires": {
"depd": "~1.1.2",
"inherits": "2.0.3",
"setprototypeof": "1.1.0",
"statuses": ">= 1.4.0 < 2"
}
},
"inherits": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
"integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw=="
},
"setprototypeof": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz",
"integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ=="
}
}
},
"restore-cursor": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz",
@ -42185,6 +42394,11 @@
"integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==",
"dev": true
},
"setprototypeof": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
"integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="
},
"shallow-clone": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz",
@ -42330,6 +42544,11 @@
"minipass": "^3.1.1"
}
},
"statuses": {
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
"integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA=="
},
"string_decoder": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
@ -42477,6 +42696,11 @@
"is-number": "^7.0.0"
}
},
"toidentifier": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
"integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA=="
},
"tr46": {
"version": "0.0.3",
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
@ -42570,7 +42794,6 @@
"@typescript-eslint/eslint-plugin": "^5.43.0",
"autoprefixer": "^10.4.12",
"axios": "0.27.2",
"bootstrap-icons": "1.10.3",
"clsx": "^1.2.1",
"date-fns": "^2.29.3",
"date-fns-tz": "^1.3.7",
@ -45433,9 +45656,6 @@
"boolbase": {
"version": "1.0.0"
},
"bootstrap-icons": {
"version": "1.10.3"
},
"browser-process-hrtime": {
"version": "1.0.0"
},
@ -49415,9 +49635,6 @@
"send": "0.18.0"
}
},
"setprototypeof": {
"version": "1.2.0"
},
"shell-quote": {
"version": "1.7.4"
},
@ -49811,9 +50028,6 @@
"toggle-selection": {
"version": "1.0.6"
},
"toidentifier": {
"version": "1.0.1"
},
"tough-cookie": {
"version": "4.1.2",
"requires": {