mirror of
https://github.com/linux-odyssey/linux-odyssey.git
synced 2026-11-05 19:20:12 +08:00
Add logger in backend (#69)
* Replace `console.log` `console.error` with Winston logger * Add ESLint warning of `console`
This commit is contained in:
22 files changed
+241
-41
No files matched your search
+1
-1
@@ -17,7 +17,7 @@ module.exports = {
|
||||
sourceType: 'module',
|
||||
},
|
||||
rules: {
|
||||
'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
|
||||
'no-console': 'warn',
|
||||
'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
|
||||
'import/extensions': 'off',
|
||||
camelcase: ['error', { properties: 'never', ignoreDestructuring: true }],
|
||||
|
||||
@@ -28,6 +28,7 @@ services:
|
||||
- players
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock
|
||||
- ./logs:/app/logs
|
||||
env_file:
|
||||
- .env
|
||||
environment:
|
||||
|
||||
@@ -41,6 +41,7 @@ services:
|
||||
- players
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock
|
||||
- ./logs:/app/logs
|
||||
environment:
|
||||
- BASE_URL=http://localhost:5173
|
||||
- MONGO_URL=mongodb://user:user-password@db-test:27017/odyssey-test
|
||||
|
||||
@@ -33,6 +33,7 @@ services:
|
||||
- ./server/swagger.yaml:/app/server/swagger.yaml
|
||||
- ./packages:/app/packages
|
||||
- ./quests:/app/quests
|
||||
- ./logs:/app/logs
|
||||
environment:
|
||||
- BASE_URL=http://localhost:5173
|
||||
- MONGO_URL=mongodb://db:27017/odyssey-test
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
"socket.io": "^4.7.1",
|
||||
"swagger-ui-express": "^5.0.0",
|
||||
"validator": "^13.11.0",
|
||||
"winston": "^3.11.0",
|
||||
"yaml": "^2.3.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
@@ -2,6 +2,7 @@ import { matchedData } from 'express-validator'
|
||||
import { genJWT } from '../../utils/auth.js'
|
||||
import { createUser } from '../../models/userManager.js'
|
||||
import { asyncHandler } from '../../middleware/error.js'
|
||||
import logger from '../../utils/logger.js'
|
||||
|
||||
export const issueToken = asyncHandler(async (req, res) => {
|
||||
const { user } = req
|
||||
@@ -31,7 +32,7 @@ export const register = asyncHandler(async (req, res, next) => {
|
||||
export function logout(req, res) {
|
||||
req.logout((err) => {
|
||||
if (err) {
|
||||
console.error(err)
|
||||
logger.error(err)
|
||||
res.status(500).json({
|
||||
message: 'error logging out',
|
||||
})
|
||||
|
||||
@@ -4,6 +4,7 @@ import { Session } from '@linux-odyssey/models'
|
||||
import { getAndStartContainer, attachContainer } from '../containers/docker.js'
|
||||
import SessionMiddleware from '../middleware/session.js'
|
||||
import { genJWT } from '../utils/auth.js'
|
||||
import logger from '../utils/logger.js'
|
||||
|
||||
const sessions = new Map()
|
||||
|
||||
@@ -37,7 +38,7 @@ async function connectContainer(socket, next) {
|
||||
// console.log(socket.handshake)
|
||||
const { sessionId } = socket.handshake.query
|
||||
if (!(sessionId && validator.isMongoId(sessionId))) {
|
||||
console.warn('Invalid Session ID.', sessionId)
|
||||
logger.warn('Invalid Session ID.', user.username, sessionId)
|
||||
next(new Error('Invalid Session ID.'))
|
||||
return
|
||||
}
|
||||
@@ -71,8 +72,6 @@ function onConnect(socket) {
|
||||
socket.emit('terminal', chunk.toString())
|
||||
})
|
||||
|
||||
socket.on('message', console.log)
|
||||
|
||||
socket.on('terminal', function incoming(message) {
|
||||
stream.socket.write(message)
|
||||
})
|
||||
@@ -98,6 +97,6 @@ export default (server) => {
|
||||
|
||||
io.on('connection', onConnect)
|
||||
io.on('connect_error', (err) => {
|
||||
console.error(err)
|
||||
logger.error('Socket connect error: ', err)
|
||||
})
|
||||
}
|
||||
@@ -4,6 +4,7 @@ import passwordStrategy from './passwordStrategy.js'
|
||||
import jwtStrategy from './jwtStrategy.js'
|
||||
import googleStrategy from './googleStrategy.js'
|
||||
import githubStrategy from './githubStrategy.js'
|
||||
import logger from '../utils/logger.js'
|
||||
|
||||
passport.use(passwordStrategy)
|
||||
passport.use(jwtStrategy)
|
||||
@@ -14,7 +15,7 @@ const enabledMethods = {
|
||||
github: githubStrategy !== null,
|
||||
}
|
||||
|
||||
console.log('Enabled login methods', enabledMethods)
|
||||
logger.info('Enabled login methods', enabledMethods)
|
||||
|
||||
if (enabledMethods.google) {
|
||||
passport.use(googleStrategy)
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
import { getQuestDockerfiles } from '../utils/quest.js'
|
||||
import { buildQuestImage } from '../containers/docker.js'
|
||||
import logger from '../utils/logger.js'
|
||||
|
||||
async function buildImages() {
|
||||
const quests = await getQuestDockerfiles()
|
||||
console.log(`Building ${quests.length} images`)
|
||||
logger.info(`Building ${quests.length} images`)
|
||||
return Promise.all(
|
||||
quests.map(({ id, questPath }) => {
|
||||
console.log(`Building image for ${id}`)
|
||||
logger.info(`Building image for ${id}`)
|
||||
return buildQuestImage(questPath, id)
|
||||
})
|
||||
)
|
||||
@@ -14,11 +15,11 @@ async function buildImages() {
|
||||
|
||||
buildImages()
|
||||
.then((result) => {
|
||||
console.log(result)
|
||||
console.log('Done!')
|
||||
logger.info(result)
|
||||
logger.info('Done!')
|
||||
process.exit(0)
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error(err)
|
||||
logger.error(err)
|
||||
process.exit(1)
|
||||
})
|
||||
@@ -1,6 +1,7 @@
|
||||
import connectDB from '@linux-odyssey/models'
|
||||
import { removeExpired } from '../containers/expiryChecker.js'
|
||||
import config from '../config.js'
|
||||
import logger from '../utils/logger.js'
|
||||
|
||||
connectDB(config.db)
|
||||
.then(removeExpired)
|
||||
@@ -8,6 +9,6 @@ connectDB(config.db)
|
||||
process.exit(0)
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error(err)
|
||||
logger.error(err)
|
||||
process.exit(1)
|
||||
})
|
||||
@@ -1,3 +1,4 @@
|
||||
/* eslint-disable no-console */
|
||||
import { genSecret } from '../utils/env.js'
|
||||
|
||||
function setup() {
|
||||
|
||||
@@ -46,6 +46,10 @@ const config = {
|
||||
imagePrefix: get('DOCKER_PREFIX', 'linuxodyssey/quest-'),
|
||||
mountQuest: get('MOUNT_QUEST', ''),
|
||||
},
|
||||
|
||||
log: {
|
||||
path: get('LOG_PATH', '../logs'),
|
||||
},
|
||||
}
|
||||
|
||||
config.baseUrl = get('BASE_URL', `http://${config.host}:${config.port}`)
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import Docker from 'dockerode'
|
||||
import config, { getQuestImage } from '../config.js'
|
||||
import logger from '../utils/logger.js'
|
||||
|
||||
const engine = new Docker()
|
||||
|
||||
@@ -33,7 +34,7 @@ export function createContainer(name, questId) {
|
||||
}
|
||||
|
||||
export async function getAndStartContainer(id) {
|
||||
console.log(`Getting container: ${id}`)
|
||||
logger.debug(`Getting container: ${id}`)
|
||||
const container = engine.getContainer(id)
|
||||
if (!container) {
|
||||
throw new Error(`Container ${id} not found`)
|
||||
@@ -74,7 +75,7 @@ export async function deleteContainer(id) {
|
||||
try {
|
||||
await container.stop()
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
logger.warn(error)
|
||||
}
|
||||
await container.remove()
|
||||
}
|
||||
@@ -99,21 +100,21 @@ export function buildQuestImage(questPath, questId) {
|
||||
// Process the data (this could be Docker build output)
|
||||
const { stream, error } = JSON.parse(data.toString())
|
||||
if (stream) {
|
||||
console.log(stream)
|
||||
logger.info(stream)
|
||||
}
|
||||
if (error) {
|
||||
console.error(error)
|
||||
logger.error(error)
|
||||
reject(error)
|
||||
}
|
||||
})
|
||||
|
||||
response.on('end', () => {
|
||||
console.log(`Build completed for ${questId}`)
|
||||
logger.info(`Build completed for ${questId}`)
|
||||
resolve(questId)
|
||||
})
|
||||
|
||||
response.on('error', (error) => {
|
||||
console.error(`Build failed for ${questId}:`, error)
|
||||
logger.error(`Build failed for ${questId}:`, error)
|
||||
reject(error)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -2,19 +2,19 @@ import schedule from 'node-schedule'
|
||||
import { Session } from '@linux-odyssey/models'
|
||||
import config from '../config.js'
|
||||
import { deleteContainer } from './docker.js'
|
||||
import logger from '../utils/logger.js'
|
||||
|
||||
export async function removeExpired() {
|
||||
// Find all sessions that are containerId is not null and lastActivityAt is
|
||||
// less than the current time minus the expiry time
|
||||
try {
|
||||
console.log('Checking for expired sessions')
|
||||
const sessions = await Session.find({
|
||||
containerId: { $ne: null },
|
||||
lastActivityAt: { $lt: new Date(Date.now() - config.containerExpiry) },
|
||||
})
|
||||
await Promise.all(
|
||||
sessions.map(async (session) => {
|
||||
console.log('Expiring session: ', session._id, session.containerId)
|
||||
logger.info('Expiring session: ', session._id, session.containerId)
|
||||
try {
|
||||
await deleteContainer(session.containerId)
|
||||
} catch (err) {
|
||||
@@ -29,9 +29,8 @@ export async function removeExpired() {
|
||||
await session.save()
|
||||
})
|
||||
)
|
||||
console.log('Done checking for expired sessions')
|
||||
} catch (err) {
|
||||
console.error(err)
|
||||
logger.error(err)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ import { Quest } from '@linux-odyssey/models'
|
||||
import { pushToSession } from '../api/socket.js'
|
||||
import SessionHandler from './sessionHandler.js'
|
||||
import { checkFile } from '../containers/cli.js'
|
||||
import logger from '../utils/logger.js'
|
||||
|
||||
// 檢查 pattern 是否符合 input
|
||||
const checkMatch = (pattern, input) => {
|
||||
@@ -101,7 +102,7 @@ export default class CommandHandler extends SessionHandler {
|
||||
this.quest = await Quest.findById(this.session.quest)
|
||||
const stages = this.getStages()
|
||||
if (stages.length === 0) {
|
||||
console.error('stage not found', this.session.tasks)
|
||||
logger.warn('stage not found', this.session.tasks)
|
||||
return {}
|
||||
}
|
||||
|
||||
|
||||
+8
-8
@@ -16,21 +16,21 @@ import { globalRateLimit } from './middleware/rateLimiter.js'
|
||||
import sessionMiddleware from './middleware/session.js'
|
||||
import expiryRemovalScheduler from './containers/expiryChecker.js'
|
||||
import setupTest from './utils/setupTest.js'
|
||||
import logger from './utils/logger.js'
|
||||
|
||||
async function main() {
|
||||
if (!config.secret) {
|
||||
console.warn(
|
||||
'No SECRET_KEY found in .env! To set up a persistent key, please run the setup script:'
|
||||
logger.error(
|
||||
'No SECRET_KEY found in .env! To set up a persistent key, please run `yarn setup`:'
|
||||
)
|
||||
console.warn('yarn setup')
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
try {
|
||||
await connectDB(config.db)
|
||||
console.log('Connected to MongoDB')
|
||||
logger.info('Connected to MongoDB')
|
||||
} catch (err) {
|
||||
console.error(err)
|
||||
logger.error(err)
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
@@ -53,7 +53,7 @@ async function main() {
|
||||
'uniquelocal',
|
||||
...config.trustedProxies,
|
||||
])
|
||||
console.log('Trusted proxies:', config.trustedProxies)
|
||||
logger.info('Trusted proxies:', config.trustedProxies)
|
||||
app.use(globalRateLimit)
|
||||
app.use(sessionMiddleware)
|
||||
app.use(passport.session())
|
||||
@@ -74,8 +74,8 @@ async function main() {
|
||||
app.use(errorHandler)
|
||||
|
||||
server.listen(config.port, config.host, () => {
|
||||
console.log(`Server listening at ${config.baseUrl}`)
|
||||
logger.info(`Server listening at ${config.baseUrl}`)
|
||||
})
|
||||
}
|
||||
|
||||
main().catch((err) => console.log(err))
|
||||
main().catch((err) => logger.error(err))
|
||||
@@ -1,3 +1,5 @@
|
||||
import logger from '../utils/logger.js'
|
||||
|
||||
export function asyncHandler(fn) {
|
||||
return (req, res, next) => {
|
||||
fn(req, res, next).catch(next)
|
||||
@@ -6,6 +8,6 @@ export function asyncHandler(fn) {
|
||||
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
export default function errorHandler(err, req, res, next) {
|
||||
console.error(err.stack) // Log error stack trace to the console
|
||||
logger.error(err) // Log error stack trace to the console
|
||||
res.status(500).send({ message: 'Something broke!' }) // Send error response
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
import { Session, Quest, UserProfile } from '@linux-odyssey/models'
|
||||
import { createContainer, deleteContainer } from '../containers/docker.js'
|
||||
import SessionHandler from '../game/sessionHandler.js'
|
||||
import logger from '../utils/logger.js'
|
||||
|
||||
async function deactivateSessions(user, quest) {
|
||||
const sessions = await Session.find({
|
||||
@@ -11,7 +12,7 @@ async function deactivateSessions(user, quest) {
|
||||
return Promise.all(
|
||||
sessions.map((session) => {
|
||||
return deleteContainer(session.containerId)
|
||||
.catch(console.error)
|
||||
.catch(logger.error)
|
||||
.finally(() => {
|
||||
session.status = 'inactive'
|
||||
session.containerId = null
|
||||
@@ -29,7 +30,7 @@ export async function createNewSession(user, questId) {
|
||||
|
||||
// deactivate all active sessions
|
||||
deactivateSessions(user._id, quest._id).catch((err) => {
|
||||
console.error(err)
|
||||
logger.error(err)
|
||||
})
|
||||
|
||||
const container = await createContainer(
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
import winston from 'winston'
|
||||
import config from '../config.js'
|
||||
|
||||
const logger = winston.createLogger({
|
||||
level: 'info',
|
||||
format: winston.format.json(),
|
||||
defaultMeta: { service: 'backend', timestamp: new Date().toISOString() },
|
||||
transports: [
|
||||
//
|
||||
// - Write all logs with importance level of `error` or less to `error.log`
|
||||
// - Write all logs with importance level of `info` or less to `combined.log`
|
||||
//
|
||||
new winston.transports.File({
|
||||
dirname: config.log.path,
|
||||
filename: 'error.log',
|
||||
level: 'error',
|
||||
}),
|
||||
new winston.transports.File({
|
||||
dirname: config.log.path,
|
||||
filename: 'combined.log',
|
||||
}),
|
||||
],
|
||||
})
|
||||
|
||||
//
|
||||
// If we're not in production then log to the `console` with the format:
|
||||
// `${info.level}: ${info.message} JSON.stringify({ ...rest }) `
|
||||
//
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
logger.add(
|
||||
new winston.transports.Console({
|
||||
format: winston.format.simple(),
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
export default logger
|
||||
@@ -3,6 +3,7 @@ import path from 'path'
|
||||
import yaml from 'yaml'
|
||||
|
||||
import { Quest } from '@linux-odyssey/models'
|
||||
import logger from './logger.js'
|
||||
|
||||
const questDirectory = path.join(process.cwd(), '..', 'quests')
|
||||
|
||||
@@ -50,7 +51,7 @@ export function loadAndUpdateQuests() {
|
||||
}
|
||||
)
|
||||
} catch (error) {
|
||||
console.error(`Error parsing quest ${id}:`, error)
|
||||
logger.error(`Error parsing quest ${id}:`, error)
|
||||
throw error
|
||||
}
|
||||
})
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import { User } from '@linux-odyssey/models'
|
||||
import config from '../config.js'
|
||||
import { createUser } from '../models/userManager.js'
|
||||
import logger from './logger.js'
|
||||
|
||||
export default async function setupTest() {
|
||||
console.log('Setting up test account')
|
||||
logger.info('Setting up test account')
|
||||
if (!(config.testing.username && config.testing.password)) {
|
||||
throw new Error(
|
||||
'No testing account found! Please set TESTING_USERNAME and TESTING_PASSWORD in .env'
|
||||
@@ -13,10 +14,10 @@ export default async function setupTest() {
|
||||
const email = `${username}@example.com`
|
||||
|
||||
if (await User.exists({ username })) {
|
||||
console.log('Testing account already exists')
|
||||
logger.info('Testing account already exists')
|
||||
return
|
||||
}
|
||||
|
||||
await createUser(username, email, { password })
|
||||
console.log('Created testing account')
|
||||
logger.info('Created testing account')
|
||||
}
|
||||
@@ -397,6 +397,11 @@
|
||||
resolved "https://registry.yarnpkg.com/@colors/colors/-/colors-1.5.0.tgz#bb504579c1cae923e6576a4f5da43d25f97bdbd9"
|
||||
integrity sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==
|
||||
|
||||
"@colors/colors@1.6.0", "@colors/colors@^1.6.0":
|
||||
version "1.6.0"
|
||||
resolved "https://registry.yarnpkg.com/@colors/colors/-/colors-1.6.0.tgz#ec6cd237440700bc23ca23087f513c75508958b0"
|
||||
integrity sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA==
|
||||
|
||||
"@cypress/request@^3.0.0":
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@cypress/request/-/request-3.0.1.tgz#72d7d5425236a2413bd3d8bb66d02d9dc3168960"
|
||||
@@ -429,6 +434,15 @@
|
||||
debug "^3.1.0"
|
||||
lodash.once "^4.1.1"
|
||||
|
||||
"@dabh/diagnostics@^2.0.2":
|
||||
version "2.0.3"
|
||||
resolved "https://registry.yarnpkg.com/@dabh/diagnostics/-/diagnostics-2.0.3.tgz#7f7e97ee9a725dffc7808d93668cc984e1dc477a"
|
||||
integrity sha512-hrlQOIi7hAfzsMqlGSFyVucrx38O+j6wiGOf//H2ecvIEqYN4ADBSS2iLMh5UFyDunCNniUIPk/q3riFv45xRA==
|
||||
dependencies:
|
||||
colorspace "1.1.x"
|
||||
enabled "2.0.x"
|
||||
kuler "^2.0.0"
|
||||
|
||||
"@esbuild/android-arm64@0.18.12":
|
||||
version "0.18.12"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.18.12.tgz#d2b7408f2d2fe6ad93877d90ebb18e0d2648828c"
|
||||
@@ -1102,6 +1116,11 @@
|
||||
resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.1.tgz#20f18294f797f2209b5f65c8e3b5c8e8261d127c"
|
||||
integrity sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==
|
||||
|
||||
"@types/triple-beam@^1.3.2":
|
||||
version "1.3.5"
|
||||
resolved "https://registry.yarnpkg.com/@types/triple-beam/-/triple-beam-1.3.5.tgz#74fef9ffbaa198eb8b588be029f38b00299caa2c"
|
||||
integrity sha512-6WaYesThRMCl19iryMYP7/x2OVgCtbIVflDGFpWnb9irXI3UjYE4AzmYuiUKY1AJstGijoY+MgUszMgRxIYTYw==
|
||||
|
||||
"@types/webidl-conversions@*":
|
||||
version "7.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/webidl-conversions/-/webidl-conversions-7.0.0.tgz#2b8e60e33906459219aa587e9d1a612ae994cfe7"
|
||||
@@ -1467,6 +1486,11 @@ async@^3.2.0:
|
||||
resolved "https://registry.yarnpkg.com/async/-/async-3.2.4.tgz#2d22e00f8cddeb5fde5dd33522b56d1cf569a81c"
|
||||
integrity sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==
|
||||
|
||||
async@^3.2.3:
|
||||
version "3.2.5"
|
||||
resolved "https://registry.yarnpkg.com/async/-/async-3.2.5.tgz#ebd52a8fdaf7a2289a24df399f8d8485c8a46b66"
|
||||
integrity sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==
|
||||
|
||||
asynckit@^0.4.0:
|
||||
version "0.4.0"
|
||||
resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
|
||||
@@ -1930,7 +1954,7 @@ collect-v8-coverage@^1.0.0:
|
||||
resolved "https://registry.yarnpkg.com/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz#c0b29bcd33bcd0779a1344c2136051e6afd3d9e9"
|
||||
integrity sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==
|
||||
|
||||
color-convert@^1.9.0:
|
||||
color-convert@^1.9.0, color-convert@^1.9.3:
|
||||
version "1.9.3"
|
||||
resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8"
|
||||
integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==
|
||||
@@ -1949,21 +1973,45 @@ color-name@1.1.3:
|
||||
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25"
|
||||
integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==
|
||||
|
||||
color-name@~1.1.4:
|
||||
color-name@^1.0.0, color-name@~1.1.4:
|
||||
version "1.1.4"
|
||||
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2"
|
||||
integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
|
||||
|
||||
color-string@^1.6.0:
|
||||
version "1.9.1"
|
||||
resolved "https://registry.yarnpkg.com/color-string/-/color-string-1.9.1.tgz#4467f9146f036f855b764dfb5bf8582bf342c7a4"
|
||||
integrity sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==
|
||||
dependencies:
|
||||
color-name "^1.0.0"
|
||||
simple-swizzle "^0.2.2"
|
||||
|
||||
color-support@^1.1.2:
|
||||
version "1.1.3"
|
||||
resolved "https://registry.yarnpkg.com/color-support/-/color-support-1.1.3.tgz#93834379a1cc9a0c61f82f52f0d04322251bd5a2"
|
||||
integrity sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==
|
||||
|
||||
color@^3.1.3:
|
||||
version "3.2.1"
|
||||
resolved "https://registry.yarnpkg.com/color/-/color-3.2.1.tgz#3544dc198caf4490c3ecc9a790b54fe9ff45e164"
|
||||
integrity sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==
|
||||
dependencies:
|
||||
color-convert "^1.9.3"
|
||||
color-string "^1.6.0"
|
||||
|
||||
colorette@^2.0.16:
|
||||
version "2.0.20"
|
||||
resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.20.tgz#9eb793e6833067f7235902fcd3b09917a000a95a"
|
||||
integrity sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==
|
||||
|
||||
colorspace@1.1.x:
|
||||
version "1.1.4"
|
||||
resolved "https://registry.yarnpkg.com/colorspace/-/colorspace-1.1.4.tgz#8d442d1186152f60453bf8070cd66eb364e59243"
|
||||
integrity sha512-BgvKJiuVu1igBUF2kEjRCZXol6wiiGbY5ipL/oVPwm0BL9sIpMIzM8IK7vwuxIIzOXMV3Ey5w+vxhm0rR/TN8w==
|
||||
dependencies:
|
||||
color "^3.1.3"
|
||||
text-hex "1.0.x"
|
||||
|
||||
combined-stream@^1.0.6, combined-stream@^1.0.8, combined-stream@~1.0.6:
|
||||
version "1.0.8"
|
||||
resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f"
|
||||
@@ -2400,6 +2448,11 @@ emoji-regex@^9.2.2:
|
||||
resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72"
|
||||
integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==
|
||||
|
||||
enabled@2.0.x:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/enabled/-/enabled-2.0.0.tgz#f9dd92ec2d6f4bbc0d5d1e64e21d61cd4665e7c2"
|
||||
integrity sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ==
|
||||
|
||||
encodeurl@~1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59"
|
||||
@@ -3023,6 +3076,11 @@ fd-slicer@~1.1.0:
|
||||
dependencies:
|
||||
pend "~1.2.0"
|
||||
|
||||
fecha@^4.2.0:
|
||||
version "4.2.3"
|
||||
resolved "https://registry.yarnpkg.com/fecha/-/fecha-4.2.3.tgz#4d9ccdbc61e8629b259fdca67e65891448d569fd"
|
||||
integrity sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw==
|
||||
|
||||
figures@^3.2.0:
|
||||
version "3.2.0"
|
||||
resolved "https://registry.yarnpkg.com/figures/-/figures-3.2.0.tgz#625c18bd293c604dc4a8ddb2febf0c88341746af"
|
||||
@@ -3086,6 +3144,11 @@ flatted@^3.1.0:
|
||||
resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.7.tgz#609f39207cb614b89d0765b477cb2d437fbf9787"
|
||||
integrity sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==
|
||||
|
||||
fn.name@1.x.x:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/fn.name/-/fn.name-1.1.0.tgz#26cad8017967aea8731bc42961d04a3d5988accc"
|
||||
integrity sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==
|
||||
|
||||
follow-redirects@^1.15.0:
|
||||
version "1.15.2"
|
||||
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.2.tgz#b460864144ba63f2681096f274c4e57026da2c13"
|
||||
@@ -3618,6 +3681,11 @@ is-arrayish@^0.2.1:
|
||||
resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d"
|
||||
integrity sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==
|
||||
|
||||
is-arrayish@^0.3.1:
|
||||
version "0.3.2"
|
||||
resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.3.2.tgz#4574a2ae56f7ab206896fb431eaeed066fdf8f03"
|
||||
integrity sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==
|
||||
|
||||
is-bigint@^1.0.1:
|
||||
version "1.0.4"
|
||||
resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.0.4.tgz#08147a1875bc2b32005d41ccd8291dffc6691df3"
|
||||
@@ -4408,6 +4476,11 @@ kruptein@^3.0.0:
|
||||
dependencies:
|
||||
asn1.js "^5.4.1"
|
||||
|
||||
kuler@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/kuler/-/kuler-2.0.0.tgz#e2c570a3800388fb44407e851531c1d670b061b3"
|
||||
integrity sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A==
|
||||
|
||||
lazy-ass@^1.6.0:
|
||||
version "1.6.0"
|
||||
resolved "https://registry.yarnpkg.com/lazy-ass/-/lazy-ass-1.6.0.tgz#7999655e8646c17f089fdd187d150d3324d54513"
|
||||
@@ -4527,6 +4600,18 @@ log-update@^4.0.0:
|
||||
slice-ansi "^4.0.0"
|
||||
wrap-ansi "^6.2.0"
|
||||
|
||||
logform@^2.3.2, logform@^2.4.0:
|
||||
version "2.6.0"
|
||||
resolved "https://registry.yarnpkg.com/logform/-/logform-2.6.0.tgz#8c82a983f05d6eaeb2d75e3decae7a768b2bf9b5"
|
||||
integrity sha512-1ulHeNPp6k/LD8H91o7VYFBng5i1BDE7HoKxVbZiGFidS1Rj65qcywLxX+pVfAPoQJEjRdvKcusKwOupHCVOVQ==
|
||||
dependencies:
|
||||
"@colors/colors" "1.6.0"
|
||||
"@types/triple-beam" "^1.3.2"
|
||||
fecha "^4.2.0"
|
||||
ms "^2.1.1"
|
||||
safe-stable-stringify "^2.3.1"
|
||||
triple-beam "^1.3.0"
|
||||
|
||||
long-timeout@0.1.1:
|
||||
version "0.1.1"
|
||||
resolved "https://registry.yarnpkg.com/long-timeout/-/long-timeout-0.1.1.tgz#9721d788b47e0bcb5a24c2e2bee1a0da55dab514"
|
||||
@@ -5005,6 +5090,13 @@ once@^1.3.0, once@^1.3.1, once@^1.4.0:
|
||||
dependencies:
|
||||
wrappy "1"
|
||||
|
||||
one-time@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/one-time/-/one-time-1.0.0.tgz#e06bc174aed214ed58edede573b433bbf827cb45"
|
||||
integrity sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g==
|
||||
dependencies:
|
||||
fn.name "1.x.x"
|
||||
|
||||
onetime@^5.1.0, onetime@^5.1.2:
|
||||
version "5.1.2"
|
||||
resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e"
|
||||
@@ -5622,6 +5714,11 @@ safe-regex-test@^1.0.0:
|
||||
get-intrinsic "^1.1.3"
|
||||
is-regex "^1.1.4"
|
||||
|
||||
safe-stable-stringify@^2.3.1:
|
||||
version "2.4.3"
|
||||
resolved "https://registry.yarnpkg.com/safe-stable-stringify/-/safe-stable-stringify-2.4.3.tgz#138c84b6f6edb3db5f8ef3ef7115b8f55ccbf886"
|
||||
integrity sha512-e2bDA2WJT0wxseVd4lsDP4+3ONX6HpMXQa1ZhFQ7SU+GjvORCmShbCMltrtIDfkYhVHrOcPtj+KhmDBdPdZD1g==
|
||||
|
||||
"safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0:
|
||||
version "2.1.2"
|
||||
resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
|
||||
@@ -5740,6 +5837,13 @@ signal-exit@^4.0.1:
|
||||
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-4.1.0.tgz#952188c1cbd546070e2dd20d0f41c0ae0530cb04"
|
||||
integrity sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==
|
||||
|
||||
simple-swizzle@^0.2.2:
|
||||
version "0.2.2"
|
||||
resolved "https://registry.yarnpkg.com/simple-swizzle/-/simple-swizzle-0.2.2.tgz#a4da6b635ffcccca33f70d17cb92592de95e557a"
|
||||
integrity sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==
|
||||
dependencies:
|
||||
is-arrayish "^0.3.1"
|
||||
|
||||
simple-update-notifier@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz#d70b92bdab7d6d90dfd73931195a30b6e3d7cebb"
|
||||
@@ -5892,6 +5996,11 @@ sshpk@^1.14.1:
|
||||
safer-buffer "^2.0.2"
|
||||
tweetnacl "~0.14.0"
|
||||
|
||||
stack-trace@0.0.x:
|
||||
version "0.0.10"
|
||||
resolved "https://registry.yarnpkg.com/stack-trace/-/stack-trace-0.0.10.tgz#547c70b347e8d32b4e108ea1a2a159e5fdde19c0"
|
||||
integrity sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==
|
||||
|
||||
stack-utils@^2.0.3:
|
||||
version "2.0.6"
|
||||
resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-2.0.6.tgz#aaf0748169c02fc33c8232abccf933f54a1cc34f"
|
||||
@@ -6139,6 +6248,11 @@ test-exclude@^6.0.0:
|
||||
glob "^7.1.4"
|
||||
minimatch "^3.0.4"
|
||||
|
||||
text-hex@1.0.x:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/text-hex/-/text-hex-1.0.0.tgz#69dc9c1b17446ee79a92bf5b884bb4b9127506f5"
|
||||
integrity sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg==
|
||||
|
||||
text-table@^0.2.0:
|
||||
version "0.2.0"
|
||||
resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4"
|
||||
@@ -6231,6 +6345,11 @@ tr46@~0.0.3:
|
||||
resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a"
|
||||
integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==
|
||||
|
||||
triple-beam@^1.3.0:
|
||||
version "1.4.1"
|
||||
resolved "https://registry.yarnpkg.com/triple-beam/-/triple-beam-1.4.1.tgz#6fde70271dc6e5d73ca0c3b24e2d92afb7441984"
|
||||
integrity sha512-aZbgViZrg1QNcG+LULa7nhZpJTZSLm/mXnHXnbAbjmN5aSa0y7V+wvv6+4WaBtpISJzThKy+PIPxc1Nq1EJ9mg==
|
||||
|
||||
ts-interface-checker@^0.1.9:
|
||||
version "0.1.13"
|
||||
resolved "https://registry.yarnpkg.com/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz#784fd3d679722bc103b1b4b8030bcddb5db2a699"
|
||||
@@ -6579,6 +6698,32 @@ wide-align@^1.1.2:
|
||||
dependencies:
|
||||
string-width "^1.0.2 || 2 || 3 || 4"
|
||||
|
||||
winston-transport@^4.5.0:
|
||||
version "4.6.0"
|
||||
resolved "https://registry.yarnpkg.com/winston-transport/-/winston-transport-4.6.0.tgz#f1c1a665ad1b366df72199e27892721832a19e1b"
|
||||
integrity sha512-wbBA9PbPAHxKiygo7ub7BYRiKxms0tpfU2ljtWzb3SjRjv5yl6Ozuy/TkXf00HTAt+Uylo3gSkNwzc4ME0wiIg==
|
||||
dependencies:
|
||||
logform "^2.3.2"
|
||||
readable-stream "^3.6.0"
|
||||
triple-beam "^1.3.0"
|
||||
|
||||
winston@^3.11.0:
|
||||
version "3.11.0"
|
||||
resolved "https://registry.yarnpkg.com/winston/-/winston-3.11.0.tgz#2d50b0a695a2758bb1c95279f0a88e858163ed91"
|
||||
integrity sha512-L3yR6/MzZAOl0DsysUXHVjOwv8mKZ71TrA/41EIduGpOOV5LQVodqN+QdQ6BS6PJ/RdIshZhq84P/fStEZkk7g==
|
||||
dependencies:
|
||||
"@colors/colors" "^1.6.0"
|
||||
"@dabh/diagnostics" "^2.0.2"
|
||||
async "^3.2.3"
|
||||
is-stream "^2.0.0"
|
||||
logform "^2.4.0"
|
||||
one-time "^1.0.0"
|
||||
readable-stream "^3.4.0"
|
||||
safe-stable-stringify "^2.3.1"
|
||||
stack-trace "0.0.x"
|
||||
triple-beam "^1.3.0"
|
||||
winston-transport "^4.5.0"
|
||||
|
||||
wordwrap@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb"
|
||||
|
||||
Reference in new issue
Block a user