diff --git a/docker-compose-dev.yaml b/docker-compose-dev.yaml index 114361f..c99ea0f 100644 --- a/docker-compose-dev.yaml +++ b/docker-compose-dev.yaml @@ -24,8 +24,8 @@ services: image: node-badges:latest command: "npm run dev" env_file: ${SETTINGS:-settings.env.example} - #environment: - # DEBUG: "express:*" + environment: + DEBUG: "app:*" deploy: replicas: 1 resources: diff --git a/package-lock.json b/package-lock.json index 0cb6364..0e03789 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,6 +14,7 @@ "camelcase": "^8.0.0", "chroma-js": "^3.1.2", "cors": "^2.8.5", + "debug": "^4.4.3", "express": "^5.1.0", "jsonpath": "^1.1.1", "lucide-static": "^0.548.0", diff --git a/package.json b/package.json index 92f9047..00b2f76 100644 --- a/package.json +++ b/package.json @@ -20,6 +20,7 @@ "camelcase": "^8.0.0", "chroma-js": "^3.1.2", "cors": "^2.8.5", + "debug": "^4.4.3", "express": "^5.1.0", "jsonpath": "^1.1.1", "lucide-static": "^0.548.0", diff --git a/render.yaml b/render.yaml index 30a1756..cb06c9d 100644 --- a/render.yaml +++ b/render.yaml @@ -2,9 +2,11 @@ services: - type: web name: node-badges plan: free - runtime: image - image: - url: ghcr.io/smashedr/node-badges:latest + previews: + generation: automatic + runtime: docker + repo: https://github.com/smashedr/node-badges + autoDeployTrigger: off dockerCommand: npm start healthCheckPath: /app-health-check envVars: diff --git a/src/api.js b/src/api.js index ae1bd50..cf80642 100644 --- a/src/api.js +++ b/src/api.js @@ -1,5 +1,7 @@ import axios from 'axios' +import createDebug from 'debug' import jp from 'jsonpath' + // noinspection JSUnresolvedReference import { Buffer } from 'node:buffer' import { createClient } from 'redis' @@ -8,6 +10,8 @@ import { parse } from 'yaml' import { VTApi } from './virustotal.js' import { InfluxDB, Point } from '@influxdata/influxdb-client' +const debug = createDebug('app:api') + const redisUrl = process.env.REDIS_URL || 'redis://redis:6379' console.log(`REDIS_URL: ${redisUrl}`) // NOTE: Increase connectTimeout for Render, consider using reconnectStrategy... @@ -23,7 +27,7 @@ if (process.env.INFLUX_URL && process.env.INFLUX_TOKEN) { }) } -export class GhcrApi { +export class GHCRApi { /** * GHCR API * @param {String} packageOwner @@ -54,7 +58,7 @@ export class GhcrApi { const key = `ghcr/tags/${url}` const cached = await cacheGet(key) if (cached) return cached - console.log(`-- CACHE MISS: ${key}`) + debug(`-- CACHE MISS: ${key}`) const response = await this.client.get(url) await cacheSet(key, response.data.tags) @@ -69,10 +73,10 @@ export class GhcrApi { const key = `ghcr/size/${this.packageOwner}/${this.packageName}/${tag}` const cached = await cacheGet(key) if (cached) return cached - console.log(`-- CACHE MISS: ${key}`) + debug(`-- CACHE MISS: ${key}`) const indexManifest = await this.getManifest(tag) - console.log('mediaType:', indexManifest.mediaType) + debug('mediaType:', indexManifest.mediaType) let totalSize = 0 @@ -80,26 +84,26 @@ export class GhcrApi { !indexManifest.mediaType.includes('list') && !indexManifest.mediaType.includes('index') ) { - // console.log('indexManifest - !list + !index:', indexManifest) + // debug('indexManifest - !list + !index:', indexManifest) const size = indexManifest.layers.reduce((sum, layer) => sum + layer.size, 0) totalSize = size + (indexManifest.config.size || 0) - // console.log('totalSize:', totalSize) + // debug('totalSize:', totalSize) await cacheSet(key, totalSize) return totalSize } - console.log('indexManifest.manifests?.length:', indexManifest.manifests?.length) + debug('indexManifest.manifests?.length:', indexManifest.manifests?.length) for (const m of indexManifest.manifests) { await new Promise((resolve) => setTimeout(resolve, 50)) const manifest = await this.getManifest(m.digest) const configSize = manifest.config?.size || 0 - // console.log('configSize:', configSize) + // debug('configSize:', configSize) // noinspection JSUnresolvedReference const layerSize = manifest.layers?.reduce((a, l) => a + (l.size || 0), 0) || 0 - // console.log('layerSize:', layerSize) + // debug('layerSize:', layerSize) totalSize += configSize + layerSize } - // console.log('totalSize:', totalSize) + // debug('totalSize:', totalSize) await cacheSet(key, totalSize, 60 * 60 * 4) return totalSize } @@ -110,7 +114,7 @@ export class GhcrApi { */ async getManifest(tag = 'latest') { const url = `${this.packageOwner}/${this.packageName}/manifests/${tag}` - // console.log('url:', url) + // debug('url:', url) const response = await this.client.get(url) return response.data } @@ -128,14 +132,14 @@ export class GhcrApi { export async function getVTReleaseStats(req) { const tag = req.params.tag || 'latest' const key = `${req.params.owner}/${req.params.repo}/${req.params.asset}/${tag}` - console.log('key:', key) + debug('key:', key) // NOTE: Duplicate Code - 5 lines const cached = await cacheGet(key) if (cached) { if (cached.errorMessage) throw new Error(cached.errorMessage) return cached } - console.log(`-- CACHE MISS: ${key}`) + debug(`-- CACHE MISS: ${key}`) const gh = new GitHubApi(process.env.GITHUB_TOKEN) let release @@ -144,17 +148,17 @@ export async function getVTReleaseStats(req) { } else { release = await gh.getReleaseByTag(req.params.owner, req.params.repo, tag) } - // console.log('release?.assets:', release?.assets) + // debug('release?.assets:', release?.assets) if (!release) await cacheError(key, 'Release Not Found') const asset = release.assets.find((a) => a.name === req.params.asset) - // console.log('asset:', asset) + // debug('asset:', asset) if (!asset) await cacheError(key, 'Asset Not Found') - // console.log('asset?.digest:', asset?.digest) + // debug('asset?.digest:', asset?.digest) if (!asset?.digest) await cacheError(key, 'Digest Not Found') const hash = asset.digest.split(':')[1] - // console.log('hash:', hash) + // debug('hash:', hash) const stats = await getVTStats(hash) - // console.log('last_analysis_stats:', stats) + // debug('last_analysis_stats:', stats) if (!stats) await cacheError(key, 'VT Stats Not Found') await cacheSet(key, stats) return stats @@ -167,26 +171,26 @@ export async function getVTReleaseStats(req) { */ export async function getVTStats(hash) { const key = `/vt/id/${hash}` - console.log('key:', key) + debug('key:', key) // NOTE: Duplicate Code - 5 lines const cached = await cacheGet(key) if (cached) { if (cached.errorMessage) throw new Error(cached.errorMessage) return cached } - console.log(`-- CACHE MISS: ${key}`) + debug(`-- CACHE MISS: ${key}`) const vt = new VTApi(process.env.VT_API_KEY) let stats if (hash.endsWith('==')) { - console.log('DEPRECATED - getAnalysis') // TODO: Deprecated + debug('DEPRECATED - getAnalysis') // TODO: Deprecated const data = await vt.getAnalysis(hash) - // console.log('data:', JSON.stringify(data, null, 2)) + // debug('data:', JSON.stringify(data, null, 2)) // noinspection JSUnresolvedReference stats = data?.data?.attributes?.stats } else { - // console.log('getReport') + // debug('getReport') const data = await vt.getReport(hash) - // console.log('data:', JSON.stringify(data, null, 2)) + // debug('data:', JSON.stringify(data, null, 2)) // noinspection JSUnresolvedReference stats = data?.data?.attributes?.last_analysis_stats } @@ -203,24 +207,24 @@ export async function getVTStats(hash) { export async function getJSONPath(req) { const key = req.path const cached = await cacheGet(key) - // console.log('cached:', cached) + // debug('cached:', cached) if (cached) return cached - console.log(`-- CACHE MISS: ${key}`) + debug(`-- CACHE MISS: ${key}`) const url = new URL(req.params.url) - console.log('url.href:', url.href) + debug('url.href:', url.href) const response = await fetch(url) - // console.log('response:', response) - // console.log('response.status:', response.status) + // debug('response:', response) + // debug('response.status:', response.status) // const length = response.headers.get('content-length') - // console.log('content-length:', length) + // debug('content-length:', length) const text = await response.text() - // console.log('text.length:', text.length) + // debug('text.length:', text.length) // const encoder = new TextEncoder().encode(text) - // console.log('encoder.length:', encoder.length) + // debug('encoder.length:', encoder.length) let data if (req.params.type === 'yaml') { @@ -228,14 +232,14 @@ export async function getJSONPath(req) { } else { data = JSON.parse(text) } - // console.log('data:', data) + // debug('data:', data) let result = jp.query(data, req.params.path)[0] - console.log('result:', result) + debug('result:', result) if (req.query.split) { const split = result.split(req.query.split) result = split[req.query.index || 0] - console.log('result:', result) + debug('result:', result) } if (!result) { throw new Error('No Result for Query') @@ -262,7 +266,7 @@ export async function cacheDelete(key) { } async function cacheError(key, errorMessage, EX = 60 * 10) { - console.log(`cacheError: ${key}`, errorMessage) + debug(`cacheError: ${key}`, errorMessage) await cacheSet(key, { errorMessage }, EX) throw new Error(errorMessage) } @@ -272,8 +276,8 @@ export async function incrBadge() { } export async function sendInflux() { - if (!influxClient) return console.log('InfluxDB Not Configured.') - console.log(`Processing Influx: ${new Date().toLocaleString()}`) + if (!influxClient) return debug('InfluxDB Not Configured.') + debug(`Processing Influx: ${new Date().toLocaleString()}`) const org = process.env.INFLUX_ORG || 'cssnr' const bucket = process.env.INFLUX_BUCKET || 'general' @@ -282,15 +286,15 @@ export async function sendInflux() { const measurementName = 'node_badges' const badgesTotal = await cacheGet('badges_total', 0) - // console.log('badgesTotal:', badgesTotal, typeof badgesTotal) + // debug('badgesTotal:', badgesTotal, typeof badgesTotal) writeApi.writePoint(new Point(measurementName).intField('badges_total', badgesTotal)) const appUptime = Math.floor(process.uptime()) - // console.log('appUptime:', appUptime, typeof appUptime) + // debug('appUptime:', appUptime, typeof appUptime) writeApi.writePoint(new Point(measurementName).intField('app_uptime', appUptime)) const redisKeys = await client.dbSize() - // console.log('redisKeys:', redisKeys, typeof redisKeys) + // debug('redisKeys:', redisKeys, typeof redisKeys) writeApi.writePoint(new Point(measurementName).intField('redis_keys', redisKeys)) await writeApi.close() diff --git a/src/app.js b/src/app.js index 764c138..9caa1b5 100644 --- a/src/app.js +++ b/src/app.js @@ -4,6 +4,7 @@ import express from 'express' import cors from 'cors' import camelCase from 'camelcase' +import createDebug from 'debug' import chroma from 'chroma-js' import lucide from 'lucide-static' import schedule from 'node-schedule' @@ -17,7 +18,7 @@ import { getJSONPath, getVTReleaseStats, getVTStats, - GhcrApi, + GHCRApi, incrBadge, sendInflux, } from './api.js' @@ -27,6 +28,8 @@ if (process.env.SENTRY_URL) { Sentry = await import('@sentry/node') } +const debug = createDebug('app:app') + const app = express() const port = process.env.PORT || 3000 @@ -41,6 +44,7 @@ app.disable('x-powered-by') console.log(`APP_VERSION: ${process.env.APP_VERSION}`) console.log(`GITHUB_TOKEN: ${process.env.GITHUB_TOKEN ? 'Loaded' : 'MISSING'}`) console.log(`VT_API_KEY: ${process.env.VT_API_KEY ? 'Loaded' : 'MISSING'}`) +console.log(`DEBUG: ${process.env.DEBUG || 'LOGGING OFF'}`) schedule.scheduleJob('*/5 * * * *', function () { sendInflux().catch(console.error) @@ -90,20 +94,20 @@ app.get('/', async (req, res) => { // res.sendStatus(200) // // const total = await cacheGet('badges_total') -// console.log('badges_total:', total) +// debug('badges_total:', total) // // if (req.params.extra) { -// console.log('req.params.extra:', req.params.extra) +// debug('req.params.extra:', req.params.extra) // sendInflux().catch(console.error) // } // }) app.get('/colors{/:index}', async (req, res) => { - console.log(req.originalUrl) + debug(req.originalUrl) const index = req.params.index || 0 - console.log('index:', index) + debug('index:', index) const color = getRangedColor(req, index) - console.log('color:', color) + debug('color:', color) res.send(``) }) @@ -115,8 +119,8 @@ app.get('/colors{/:index}', async (req, res) => { // app.use((req, res, next) => { // if (req.method === 'PURGE') { -// console.log('PURGE request for URL:', req.originalUrl) -// console.log('req:', req) +// debug('PURGE request for URL:', req.originalUrl) +// debug('req:', req) // res.status(200).send('PURGE received') // return // } @@ -125,12 +129,12 @@ app.get('/colors{/:index}', async (req, res) => { app.all('/vt/:type/:hash', async (req, res, next) => { if (req.method === 'PURGE') { - console.log('PURGE:', req.originalUrl) + debug('PURGE:', req.originalUrl) if (!['id', 'sha'].includes(req.params.type)) return next() const hash = req.params.hash.includes(':') ? req.params.hash.split(':')[1] : req.params.hash - // console.log('hash:', hash) + // debug('hash:', hash) const key = `/vt/id/${hash}` return purgeKey(res, key) } @@ -140,20 +144,20 @@ app.all('/vt/:type/:hash', async (req, res, next) => { app.get( '/vt/:type/:hash', errorBadgeHandler(async (req, res) => { - console.log(req.originalUrl) - // console.log('req.params.type:', req.params.type) + debug(req.originalUrl) + // debug('req.params.type:', req.params.type) if (!['id', 'sha'].includes(req.params.type)) return res.sendStatus(404) if (!process.env.VT_API_KEY) throw new Error('Missing VT API Key') const hash = req.params.hash.includes(':') ? req.params.hash.split(':')[1] : req.params.hash - // console.log('hash:', hash) + // debug('hash:', hash) const stats = await getVTStats(hash) - // console.log('stats:', stats) + // debug('stats:', stats) const message = `${stats.malicious}/${stats.suspicious}/${stats.undetected}` - // console.log('message:', message) + // debug('message:', message) const color = getRangedColor(req, stats.malicious + stats.suspicious) const options = { label: hash.slice(0, 6), icon: 'virustotal', color } getBadge(message, req.query, options, res) @@ -162,7 +166,7 @@ app.get( app.all('/vt/:owner/:repo/:asset{/:tag}', async (req, res, next) => { if (req.method === 'PURGE') { - console.log('PURGE:', req.originalUrl) + debug('PURGE:', req.originalUrl) const tag = req.params.tag || 'latest' const key = `${req.params.owner}/${req.params.repo}/${req.params.asset}/${tag}` return purgeKey(res, key) @@ -173,12 +177,12 @@ app.all('/vt/:owner/:repo/:asset{/:tag}', async (req, res, next) => { app.get( '/vt/:owner/:repo/:asset{/:tag}', errorBadgeHandler(async (req, res) => { - console.log(req.originalUrl) + debug(req.originalUrl) if (!process.env.VT_API_KEY) throw new Error('Missing VT API Key') const stats = await getVTReleaseStats(req) - // console.log('stats:', stats) + // debug('stats:', stats) const message = `${stats.malicious}/${stats.suspicious}/${stats.undetected}` - // console.log('message:', message) + // debug('message:', message) const color = getRangedColor(req, stats.malicious + stats.suspicious) const options = { label: req.params.asset, icon: 'virustotal', color } getBadge(message, req.query, options, res) @@ -187,7 +191,7 @@ app.get( app.all('/ghcr/tags/:owner/:package{/:latest}', async (req, res, next) => { if (req.method === 'PURGE') { - console.log('PURGE:', req.originalUrl) + debug('PURGE:', req.originalUrl) const key = `ghcr/tags/${req.params.owner}/${req.params.package}/tags/list` return purgeKey(res, key) } @@ -197,14 +201,14 @@ app.all('/ghcr/tags/:owner/:package{/:latest}', async (req, res, next) => { app.get( '/ghcr/tags/:owner/:package{/:latest}', errorBadgeHandler(async (req, res) => { - console.log(req.originalUrl) + debug(req.originalUrl) if (req.params.latest && req.params.latest !== 'latest') { return res.sendStatus(404) } const count = Number.parseInt(req.query.n) || 3 - // console.log('count:', count) + // debug('count:', count) - const api = new GhcrApi(req.params.owner, req.params.package) + const api = new GHCRApi(req.params.owner, req.params.package) let tags = await api.getImageTags() tags = tags.filter((tag) => tag !== 'latest') tags = tags.toReversed() @@ -218,7 +222,7 @@ app.get( if (req.params.latest) { const message = tags.at(-1) - // console.log('latest - message:', message) + // debug('latest - message:', message) return getBadge(message, req.query, { label: 'latest', lucide: 'tag' }, res) } @@ -227,14 +231,14 @@ app.get( } const message = tags.join(` ${req.query.sep || '|'} `) - // console.log('tags - message:', message) + // debug('tags - message:', message) getBadge(message, req.query, { label: 'tags', lucide: 'tags' }, res) }) ) app.all('/ghcr/size/:owner/:package{/:tag}', async (req, res, next) => { if (req.method === 'PURGE') { - console.log('PURGE:', req.originalUrl) + debug('PURGE:', req.originalUrl) const tag = req.params.tag ? req.params.tag : 'latest' const key = `ghcr/size/${req.params.owner}/${req.params.package}/${tag}` return purgeKey(res, key) @@ -245,15 +249,15 @@ app.all('/ghcr/size/:owner/:package{/:tag}', async (req, res, next) => { app.get( '/ghcr/size/:owner/:package{/:tag}', errorBadgeHandler(async (req, res) => { - console.log(req.originalUrl) + debug(req.originalUrl) - const api = new GhcrApi(req.params.owner, req.params.package) + const api = new GHCRApi(req.params.owner, req.params.package) const tag = req.params.tag || 'latest' const total = await api.getImageSize(tag) - // console.log('getImageSize - total:', total) + // debug('getImageSize - total:', total) const message = formatSize(total) - // console.log('message:', message) + // debug('message:', message) getBadge(message, req.query, { label: 'size', lucide: 'container' }, res) }) ) @@ -261,15 +265,15 @@ app.get( app.get( '/static/:message{/:label}', errorBadgeHandler(async (req, res) => { - console.log(req.originalUrl) - // console.log(`message/label: ${req.params.message} / ${req.params.label}`) + debug(req.originalUrl) + // debug(`message/label: ${req.params.message} / ${req.params.label}`) // NOTE: This endpoint uses custom logic to make a "static" badge // This needs to be fixed, the icon does not show up like shields const query = structuredClone(req.query) if (!req.params.label && !query.label && !query.labelColor) { query.labelColor = query.color || 'brightgreen' } - // console.log('query:', query) + // debug('query:', query) getBadge(req.params.message, query, { label: req.params.label }, res) }) ) @@ -277,7 +281,7 @@ app.get( app.all('/:type/:url/:path', async (req, res, next) => { if (!['yaml', 'json'].includes(req.params.type)) return next() if (req.method === 'PURGE') { - console.log('PURGE:', req.originalUrl) + debug('PURGE:', req.originalUrl) return purgeKey(res, req.path) } next() @@ -286,12 +290,12 @@ app.all('/:type/:url/:path', async (req, res, next) => { app.get( '/:type/:url/:path', errorBadgeHandler(async (req, res) => { - console.log(req.originalUrl) - // console.log('req.params.type:', req.params.type) + debug(req.originalUrl) + // debug('req.params.type:', req.params.type) if (!['yaml', 'json'].includes(req.params.type)) return res.sendStatus(404) const message = await getJSONPath(req) - // console.log('message:', message) + // debug('message:', message) getBadge(message, req.query, { label: 'result', lucide: 'code-xml' }, res) }) ) @@ -299,22 +303,22 @@ app.get( app.get( '/uptime', errorBadgeHandler(async (req, res) => { - console.log(req.originalUrl) + debug(req.originalUrl) const message = getUptime() - // console.log('message:', message) + // debug('message:', message) getBadge(message, req.query, { label: 'uptime', lucide: 'clock-arrow-up' }, res) }) ) // Handler 404 app.use((req, res) => { - console.log('404:', req.originalUrl) + debug('404:', req.originalUrl) const data = { message: '404 - URL Not Found', color: 'red', style: req.query.style || 'flat', } - // console.log('404 data:', data) + debug('404 data:', data) // noinspection JSCheckFunctionSignatures const badge = makeBadge(data) sendBadge(res, badge, 404) @@ -329,13 +333,13 @@ function errorBadgeHandler(handler) { await handler(req, res) } catch (error) { console.error(error) - console.log('errorBadgeHandler:', error.message) + debug('errorBadgeHandler:', error.message) const data = { message: error.message || 'Unknown Error', color: 'red', style: req.query.style || 'flat', } - // console.log('data:', data) + debug('data:', data) const badge = makeBadge(data) if (res) sendBadge(res, badge) } @@ -372,7 +376,7 @@ function sendBadge(res, badge, status = 200) { */ function getBadge(message, query = {}, options = {}, res = null) { const opts = { color: '', label: '', icon: '', lucide: '', ...options } - // console.log('--- opts:', opts) + // debug('--- opts:', opts) const data = { message: message.toString(), color: query.color || opts.color || 'brightgreen', @@ -385,7 +389,7 @@ function getBadge(message, query = {}, options = {}, res = null) { data.logoBase64 = `data:image/svg+xml;base64,${logo}` data.labelColor = query.labelColor || '#555' } - // console.log('data:', data) + // debug('data:', data) const badge = makeBadge(data) if (res) sendBadge(res, badge) incrBadge().catch(console.error) @@ -400,22 +404,22 @@ function getBadge(message, query = {}, options = {}, res = null) { * @return {String} */ function getLogo(query, opts, color = '#fff') { - // console.log('query.icon:', query.icon) + // debug('query.icon:', query.icon) if (query.icon !== undefined && !query.icon) return '' const iconName = query.icon || query.lucide || opts.icon || opts.lucide - // console.log('iconName:', iconName) + // debug('iconName:', iconName) const name = camelCase(iconName, { pascalCase: true }) - // console.log('name:', name) + // debug('name:', name) if (!name) return '' let svg, colorType if ((query.icon || opts.icon) && !query.lucide) { - // console.log('Simple Icons') + // debug('Simple Icons') svg = icons[`si${name}`]?.svg colorType = 'fill' } else { - // console.log('Lucide Icon') + // debug('Lucide Icon') svg = lucide[name] colorType = 'color' } @@ -426,9 +430,9 @@ function getLogo(query, opts, color = '#fff') { } const iconColor = query.iconColor || color - // console.log('iconColor:', iconColor) + // debug('iconColor:', iconColor) const result = svg.replace('} */ async function purgeKey(res, key) { - console.log(`purgeKey: ${key}`) + debug(`purgeKey: ${key}`) const result = await cacheDelete(key) - console.log('result:', result) + debug('result:', result) res.send(result.toString()) } @@ -488,9 +492,9 @@ function getRangedColor(req, index, options = {}) { .scale([opts.start, opts.end]) .mode('lab') .colors(opts.total + 1) - // console.log('colors:', colors) - // colors.forEach((color) => console.log(color)) + // debug('colors:', colors) + // colors.forEach((color) => debug(color)) const idx = Math.max(0, Math.min(opts.total, index)) - // console.log(`index: ${idx} / ${colors.length - 1}`) + // debug(`index: ${idx} / ${colors.length - 1}`) return colors[idx] } diff --git a/src/github.js b/src/github.js index 5123a3d..00ead7a 100644 --- a/src/github.js +++ b/src/github.js @@ -1,5 +1,8 @@ +import createDebug from 'debug' import { Octokit } from '@octokit/rest' +export const debug = createDebug('app:api') + export class GitHubApi { /** * GitHub Api @@ -17,12 +20,12 @@ export class GitHubApi { // * @return {Promise} // */ // async getRelease(release_id) { - // console.log('getRelease:', release_id) + // debug('getRelease:', release_id) // const response = await this.octokit.rest.repos.getRelease({ // ...github.context.repo, // release_id, // }) - // console.log('response.status:', response.status) + // debug('response.status:', response.status) // return response.data // } @@ -34,13 +37,13 @@ export class GitHubApi { * @return {Promise} */ async getReleaseByTag(owner, repo, tag) { - console.log('getReleaseByTag:', tag) + debug('getReleaseByTag:', tag) const response = await this.octokit.rest.repos.getReleaseByTag({ owner, repo, tag, }) - console.log('response.status:', response.status) + debug('response.status:', response.status) return response.data } @@ -51,16 +54,16 @@ export class GitHubApi { * @return {Promise} */ async getLatestRelease(owner, repo) { - console.log('getLatestRelease:', owner, repo) + debug('getLatestRelease:', owner, repo) try { const response = await this.octokit.rest.repos.getLatestRelease({ owner, repo, }) - console.log('response.status:', response.status) + debug('response.status:', response.status) return response.data } catch (error) { - console.log('error:', error) + console.error('error:', error) } } } diff --git a/src/virustotal.js b/src/virustotal.js index 1569db0..6871259 100644 --- a/src/virustotal.js +++ b/src/virustotal.js @@ -1,4 +1,7 @@ import axios from 'axios' +import createDebug from 'debug' + +const debug = createDebug('app:api') export class VTApi { /** @@ -20,10 +23,10 @@ export class VTApi { async getReport(id) { try { const response = await this.client.get(`/files/${id}`) - console.log('getReport: response.status:', response.status) + debug('getReport: response.status:', response.status) return response.data } catch (error) { - console.log('error:', error) + console.error('error:', error) } } @@ -35,10 +38,10 @@ export class VTApi { async getAnalysis(id) { try { const response = await this.client.get(`/analyses/${id}`) - console.log('getReport: response.status:', response.status) + debug('getReport: response.status:', response.status) return response.data } catch (error) { - console.log('error:', error) + console.error('error:', error) } } }