Compare commits

..

26 Commits
v1.0.2 ... main

Author SHA1 Message Date
0a185a91fb Merge branch 'main' of https://github.com/woodchen-ink/Random-Api 2024-09-12 16:52:49 +08:00
43bc465cf7 取消自动部署 2024-09-12 16:52:46 +08:00
wood chen
4ae023afd7
Update app.js 2024-09-09 21:44:36 +08:00
wood chen
64dec23fb5
Merge pull request #1 from woodchen-ink/dependabot/npm_and_yarn/nodejs/lru-cache-11.0.1
Bump lru-cache from 6.0.0 to 11.0.1 in /nodejs
2024-09-09 21:35:31 +08:00
wood chen
8d9c0dfc87
Update app.js 2024-09-09 21:32:47 +08:00
wood chen
037dbb7127
Update package.json 2024-09-09 21:30:34 +08:00
wood chen
19a4c19a9b
Update app.js 2024-09-09 21:28:53 +08:00
dependabot[bot]
7a7e88940b
Bump lru-cache from 6.0.0 to 11.0.1 in /nodejs
Bumps [lru-cache](https://github.com/isaacs/node-lru-cache) from 6.0.0 to 11.0.1.
- [Changelog](https://github.com/isaacs/node-lru-cache/blob/main/CHANGELOG.md)
- [Commits](https://github.com/isaacs/node-lru-cache/compare/v6.0.0...v11.0.1)

---
updated-dependencies:
- dependency-name: lru-cache
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-09-09 13:25:17 +00:00
wood chen
9302434638
Merge pull request #2 from woodchen-ink/dependabot/npm_and_yarn/nodejs/winston-3.14.2
Bump winston from 3.13.1 to 3.14.2 in /nodejs
2024-09-09 21:24:26 +08:00
wood chen
c8807dcad8
Merge pull request #3 from woodchen-ink/dependabot/npm_and_yarn/nodejs/node-fetch-3.3.2
Bump node-fetch from 2.7.0 to 3.3.2 in /nodejs
2024-09-09 21:24:05 +08:00
dependabot[bot]
bc81974908
Bump node-fetch from 2.7.0 to 3.3.2 in /nodejs
Bumps [node-fetch](https://github.com/node-fetch/node-fetch) from 2.7.0 to 3.3.2.
- [Release notes](https://github.com/node-fetch/node-fetch/releases)
- [Commits](https://github.com/node-fetch/node-fetch/compare/v2.7.0...v3.3.2)

---
updated-dependencies:
- dependency-name: node-fetch
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-09-09 12:44:30 +00:00
dependabot[bot]
e20b894e4b
Bump winston from 3.13.1 to 3.14.2 in /nodejs
Bumps [winston](https://github.com/winstonjs/winston) from 3.13.1 to 3.14.2.
- [Release notes](https://github.com/winstonjs/winston/releases)
- [Changelog](https://github.com/winstonjs/winston/blob/master/CHANGELOG.md)
- [Commits](https://github.com/winstonjs/winston/compare/v3.13.1...v3.14.2)

---
updated-dependencies:
- dependency-name: winston
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-09-09 12:44:25 +00:00
wood chen
050309a7c7
Update dependabot.yml 2024-09-09 20:43:32 +08:00
wood chen
5e1ad34b55
Create dependabot.yml 2024-09-09 20:41:42 +08:00
fe40f62c46 czlwb添加一些图片 2024-08-19 17:59:06 +08:00
a63af76903 修改部分图片链接 2024-08-04 16:56:43 +08:00
99e7a738ef Merge branch 'main' of https://github.com/woodchen-ink/Random-Api 2024-08-04 16:50:28 +08:00
c63a9faeca 修改部分图片链接 2024-08-04 16:50:25 +08:00
wood chen
3d0e28633f
Update index.md 2024-07-28 23:02:16 +08:00
wood chen
6902af9182
Update deploy.yml 2024-07-28 22:59:47 +08:00
wood chen
84941aaaba
Update README.md 2024-07-28 22:55:24 +08:00
86b74150e0 目录写错了 2024-07-28 04:32:22 +08:00
d1d21d1d05 nodejs版本部署的方式,合并到一起,不需要部署两个站点了 2024-07-28 04:28:14 +08:00
af1a9472b6 更新下index.md 2024-07-21 20:14:50 +08:00
4b8750edc2 禁用日志压缩,日志内容排版 2024-07-21 20:11:37 +08:00
e986e12f37 优化nodejs方式的性能,日志每小时自动输出到文件 2024-07-21 03:04:13 +08:00
22 changed files with 2320 additions and 226 deletions

11
.github/dependabot.yml vendored Normal file
View File

@ -0,0 +1,11 @@
# To get started with Dependabot version updates, you'll need to specify which
# package ecosystems to update and where the package manifests are located.
# Please see the documentation for all configuration options:
# https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file
version: 2
updates:
- package-ecosystem: "npm" # See documentation for possible values
directory: "/nodejs" # Location of package manifests
schedule:
interval: "weekly"

View File

@ -1,52 +0,0 @@
name: Build and Deploy
on:
push:
branches:
- main # 或者您的主分支名称
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Create artifact
run: |
zip -r deployment.zip . -x "*.git*"
- name: Deploy to server
uses: appleboy/scp-action@master
with:
host: ${{ secrets.SERVER_HOST }}
username: root
key: ${{ secrets.SERVER_SSH_KEY }}
source: "deployment.zip"
target: "/tmp"
- name: Execute deployment commands
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.SERVER_HOST }}
username: root
key: ${{ secrets.SERVER_SSH_KEY }}
script: |
# 解压文件
unzip -o /tmp/deployment.zip -d /opt/1panel/apps/openresty/openresty/www/sites/random-api-file.czl.net/index2
# 删除 index 目录下的所有文件
rm -rf /opt/1panel/apps/openresty/openresty/www/sites/random-api-file.czl.net/index/*
# 移动文件,采用覆盖模式
mv -f /opt/1panel/apps/openresty/openresty/www/sites/random-api-file.czl.net/index2/* /opt/1panel/apps/openresty/openresty/www/sites/random-api-file.czl.net/index/
# 删除 index2 文件夹
rm -rf /opt/1panel/apps/openresty/openresty/www/sites/random-api-file.czl.net/index2
# 设置目录及其子文件的所有权和权限
chown -R 1000:1000 /opt/1panel/apps/openresty/openresty/www/sites/random-api-file.czl.net/index
chmod -R 0755 /opt/1panel/apps/openresty/openresty/www/sites/random-api-file.czl.net/index
# 清理临时文件
rm /tmp/deployment.zip

1592
.gitignore vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,19 +1,16 @@
# Random-Api 随机文件API # Random-Api 随机文件API
本项目已迁移至: [random-api-go](https://github.com/woodchen-ink/random-api-go)
**请给个star谢谢** **请给个star谢谢**
## 使用链接 ## 使用链接
[https://random-api.czl.net](https://random-api.czl.net) [https://random-api.czl.net](https://random-api.czl.net)
## 部署、更新和原理 ## 部署、更新
请见我的博客:[https://woodchen.ink/archives/1705367469203](https://woodchen.ink/archives/1705367469203) 请见我的帖子:[https://q58.org/questions/D1U1](https://q58.org/questions/D1U1)
## 更新
1. 新增使用腾讯Edgeone的边缘函数的实现方法使用`eo.js`即可。
2. 新增nodejs版本, 可以自行部署在国内服务器, 速度会快些.
## 提示 ## 提示

4
eo.js
View File

@ -1,5 +1,5 @@
// 外部 JSON 文件的 URL // 外部 JSON 文件的 URL
const CSV_PATHS_URL = 'https://random-api-file.czl.net/url.json'; const CSV_PATHS_URL = 'https://random-api.czl.net/url.json';
addEventListener('fetch', event => { addEventListener('fetch', event => {
event.respondWith(handleRequest(event.request)); event.respondWith(handleRequest(event.request));
@ -58,7 +58,7 @@ async function handleRequest(request) {
} }
} else { } else {
// 请求路径不在配置中,返回默认首页 // 请求路径不在配置中,返回默认首页
const indexHtmlResponse = await fetch('https://random-api-file.czl.net'); const indexHtmlResponse = await fetch('https://random-api.czl.net');
return new Response(indexHtmlResponse.body, { return new Response(indexHtmlResponse.body, {
headers: { 'Content-Type': 'text/html' }, headers: { 'Content-Type': 'text/html' },
}); });

View File

@ -1,92 +1,175 @@
const express = require('express'); import express from 'express';
const fetch = require('node-fetch'); import fetch from 'node-fetch';
import { LRUCache } from 'lru-cache'; // 使用命名导入
import compression from 'compression';
import winston from 'winston';
import 'winston-daily-rotate-file';
import cluster from 'cluster';
import { cpus } from 'os';
import path from 'path';
import { fileURLToPath } from 'url';
// 处理 __dirname
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const numCPUs = cpus().length;
const app = express(); const app = express();
const port = 5003; const port = 5003;
// 设置静态文件目录
app.use(express.static(path.join(__dirname, 'public')));
// 外部 JSON 文件的 URL // 外部 JSON 文件的 URL
const CSV_PATHS_URL = 'https://random-api-file.czl.net/url.json'; const CSV_PATHS_URL = 'https://random-api.czl.net/url.json';
// 设置缓存
let csvPathsCache = null;
let lastFetchTime = 0;
const CACHE_DURATION = 60 * 1000 * 60 * 24; // 24小时
// 使用新的 LRUCache 构造函数
const csvCache = new LRUCache({
max: 100, // 最多缓存100个CSV文件
ttl: 1000 * 60 * 60 * 24 // 缓存24小时
});
// 日志名称格式
const consoleFormat = winston.format.printf(({ level, message, timestamp }) => {
return `${timestamp} ${level}: ${message}`;
});
// 自定义日志格式
const customFormat = winston.format.printf(({ level, message, timestamp, ...metadata }) => {
let msg = `${timestamp} [${level}]: `;
if (typeof message === 'object') {
msg += JSON.stringify(message, null, 2);
} else {
msg += message;
}
if (metadata.logs) {
msg += '\n' + metadata.logs.map(log => JSON.stringify(log, null, 2)).join('\n');
}
return msg;
});
// 设置日志
const logger = winston.createLogger({
level: 'info',
format: winston.format.combine(
winston.format.timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }),
customFormat
),
transports: [
new winston.transports.Console(),
new winston.transports.DailyRotateFile({
filename: 'logs/application-%DATE%.log',
datePattern: 'YYYY-MM-DD-HH',
maxSize: '20m',
maxFiles: '7d', // 日志保存的时间,超过这个时间的会自动删除旧文件
zippedArchive: false // 禁用压缩
})
]
});
// 日志缓冲
let logBuffer = [];
// 增强的日志中间件 // 增强的日志中间件
app.use((req, res, next) => { app.use((req, res, next) => {
const ip = req.headers['x-forwarded-for'] || req.ip || req.connection.remoteAddress; const logEntry = {
const method = req.method; timestamp: new Date().toISOString(),
const path = req.originalUrl; ip: req.headers['x-forwarded-for'] || req.ip || req.connection.remoteAddress,
const userAgent = req.get('User-Agent'); method: req.method,
const referer = req.get('Referer') || 'N/A'; path: req.originalUrl,
const accept = req.get('Accept'); protocol: req.protocol,
const acceptEncoding = req.get('Accept-Encoding'); host: req.get('Host'),
const acceptLanguage = req.get('Accept-Language'); userAgent: req.get('User-Agent'),
const host = req.get('Host'); referer: req.get('Referer') || 'N/A',
const protocol = req.protocol; accept: req.get('Accept'),
acceptEncoding: req.get('Accept-Encoding'),
acceptLanguage: req.get('Accept-Language')
};
console.log(` // 立即输出到控制台
[${new Date().toISOString()}] logger.info(logEntry);
IP: ${ip}
Method: ${method} // 添加到缓冲区,用于每小时写入文件
Path: ${path} logBuffer.push(logEntry);
Protocol: ${protocol}
Host: ${host}
User-Agent: ${userAgent}
Referer: ${referer}
Accept: ${accept}
Accept-Encoding: ${acceptEncoding}
Accept-Language: ${acceptLanguage}
`);
next(); next();
}); });
/** // 每小时输出一次日志到文件
* 处理客户端请求并根据请求的URL路径获取对应的CSV文件中的随机一行的URL然后重定向到该URL setInterval(() => {
*/ if (logBuffer.length > 0) {
logger.info('Hourly log', { logs: logBuffer });
logBuffer = [];
}
}, 60 * 60 * 1000); // 每小时
async function getCsvPaths() {
const now = Date.now();
if (!csvPathsCache || now - lastFetchTime > CACHE_DURATION) {
const response = await fetch(CSV_PATHS_URL);
if (response.ok) {
csvPathsCache = await response.json();
lastFetchTime = now;
}
}
return csvPathsCache;
}
async function getCsvContent(url) {
if (csvCache.has(url)) {
return csvCache.get(url);
}
const response = await fetch(url);
if (response.ok) {
const content = await response.text();
csvCache.set(url, content);
return content;
}
return null;
}
async function handleRequest(req, res) { async function handleRequest(req, res) {
try { try {
// 从CSV_PATHS_URL获取CSV文件路径配置 const csvPaths = await getCsvPaths();
const csvPathsResponse = await fetch(CSV_PATHS_URL); if (!csvPaths) {
if (!csvPathsResponse.ok) {
return res.status(500).send('CSV paths configuration could not be fetched.'); return res.status(500).send('CSV paths configuration could not be fetched.');
} }
const csvPaths = await csvPathsResponse.json();
// 解析请求的URL路径 let path = req.path.slice(1);
let path = req.path.slice(1); // 移除路径前的斜杠 path = path.split('?')[0];
path = path.split('?')[0]; // 移除问号后的部分
if (path.endsWith('/')) { if (path.endsWith('/')) {
path = path.slice(0, -1); // 移除路径后的斜杠 path = path.slice(0, -1);
} }
// 分割路径为前缀和后缀
const pathSegments = path.split('/'); const pathSegments = path.split('/');
const prefix = pathSegments[0]; const prefix = pathSegments[0];
const suffix = pathSegments.slice(1).join('/'); const suffix = pathSegments.slice(1).join('/');
// 检查请求路径是否在CSV路径配置中
if (prefix in csvPaths && suffix in csvPaths[prefix]) { if (prefix in csvPaths && suffix in csvPaths[prefix]) {
// 根据配置获取对应的CSV文件URL
const csvUrl = csvPaths[prefix][suffix]; const csvUrl = csvPaths[prefix][suffix];
// 从CSV文件URL获取文件内容 const fileArrayText = await getCsvContent(csvUrl);
const fileArrayResponse = await fetch(csvUrl); if (fileArrayText) {
if (fileArrayResponse.ok) {
// 处理CSV文件内容过滤空行和注释行
const fileArrayText = await fileArrayResponse.text();
const fileArray = fileArrayText.split('\n').filter(line => Boolean(line) && !line.trim().startsWith('#')); const fileArray = fileArrayText.split('\n').filter(line => Boolean(line) && !line.trim().startsWith('#'));
const randomUrl = fileArray[Math.floor(Math.random() * fileArray.length)];
// 随机选择一行URL进行重定向
const randomIndex = Math.floor(Math.random() * fileArray.length);
const randomUrl = fileArray[randomIndex];
return res.redirect(302, randomUrl); return res.redirect(302, randomUrl);
} else { } else {
return res.status(500).send('CSV file could not be fetched.'); return res.status(500).send('CSV file could not be fetched.');
} }
} else { } else {
// 请求路径不在配置中,返回默认首页 const indexHtmlResponse = await fetch('https://random-api.czl.net');
const indexHtmlResponse = await fetch('https://random-api-file.czl.net');
const indexHtml = await indexHtmlResponse.text(); const indexHtml = await indexHtmlResponse.text();
return res.type('html').send(indexHtml); return res.type('html').send(indexHtml);
} }
} catch (error) { } catch (error) {
console.error('Error:', error); console.error('Error:', error);
logger.error('Error:', error);
res.status(500).send('Internal Server Error'); res.status(500).send('Internal Server Error');
} }
} }
@ -94,7 +177,22 @@ async function handleRequest(req, res) {
// 处理所有路由 // 处理所有路由
app.get('*', handleRequest); app.get('*', handleRequest);
// 启动服务器 // 使用 cluster 模块
app.listen(port, () => { if (cluster.isMaster) {
console.log(`Server running at http://localhost:${port}`); console.log(`Master ${process.pid} is running`);
});
// Fork workers.
for (let i = 0; i < numCPUs; i++) {
cluster.fork();
}
cluster.on('exit', (worker, code, signal) => {
console.log(`worker ${worker.process.pid} died`);
});
} else {
// Workers can share any TCP connection
// In this case it is an HTTP server
app.listen(port, () => {
console.log(`Worker ${process.pid} started on port ${port}`);
});
}

530
nodejs/package-lock.json generated
View File

@ -9,10 +9,37 @@
"version": "1.0.0", "version": "1.0.0",
"license": "ISC", "license": "ISC",
"dependencies": { "dependencies": {
"express": "^4.19.2", "compression": "^1.7.4",
"node-fetch": "^2.7.0" "express": "^4.17.1",
"lru-cache": "^11.0.1",
"node-fetch": "^3.3.2",
"winston": "^3.3.3",
"winston-daily-rotate-file": "^5.0.0"
} }
}, },
"node_modules/@colors/colors": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.6.0.tgz",
"integrity": "sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA==",
"engines": {
"node": ">=0.1.90"
}
},
"node_modules/@dabh/diagnostics": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/@dabh/diagnostics/-/diagnostics-2.0.3.tgz",
"integrity": "sha512-hrlQOIi7hAfzsMqlGSFyVucrx38O+j6wiGOf//H2ecvIEqYN4ADBSS2iLMh5UFyDunCNniUIPk/q3riFv45xRA==",
"dependencies": {
"colorspace": "1.1.x",
"enabled": "2.0.x",
"kuler": "^2.0.0"
}
},
"node_modules/@types/triple-beam": {
"version": "1.3.5",
"resolved": "https://registry.npmjs.org/@types/triple-beam/-/triple-beam-1.3.5.tgz",
"integrity": "sha512-6WaYesThRMCl19iryMYP7/x2OVgCtbIVflDGFpWnb9irXI3UjYE4AzmYuiUKY1AJstGijoY+MgUszMgRxIYTYw=="
},
"node_modules/accepts": { "node_modules/accepts": {
"version": "1.3.8", "version": "1.3.8",
"resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz",
@ -30,6 +57,11 @@
"resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
"integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg=="
}, },
"node_modules/async": {
"version": "3.2.5",
"resolved": "https://registry.npmjs.org/async/-/async-3.2.5.tgz",
"integrity": "sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg=="
},
"node_modules/body-parser": { "node_modules/body-parser": {
"version": "1.20.2", "version": "1.20.2",
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz",
@ -53,7 +85,7 @@
"npm": "1.2.8000 || >= 1.4.16" "npm": "1.2.8000 || >= 1.4.16"
} }
}, },
"node_modules/bytes": { "node_modules/body-parser/node_modules/bytes": {
"version": "3.1.2", "version": "3.1.2",
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
"integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==",
@ -61,6 +93,14 @@
"node": ">= 0.8" "node": ">= 0.8"
} }
}, },
"node_modules/bytes": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz",
"integrity": "sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==",
"engines": {
"node": ">= 0.8"
}
},
"node_modules/call-bind": { "node_modules/call-bind": {
"version": "1.0.7", "version": "1.0.7",
"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz",
@ -79,6 +119,74 @@
"url": "https://github.com/sponsors/ljharb" "url": "https://github.com/sponsors/ljharb"
} }
}, },
"node_modules/color": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/color/-/color-3.2.1.tgz",
"integrity": "sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==",
"dependencies": {
"color-convert": "^1.9.3",
"color-string": "^1.6.0"
}
},
"node_modules/color-convert": {
"version": "1.9.3",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
"integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
"dependencies": {
"color-name": "1.1.3"
}
},
"node_modules/color-name": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
"integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw=="
},
"node_modules/color-string": {
"version": "1.9.1",
"resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz",
"integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==",
"dependencies": {
"color-name": "^1.0.0",
"simple-swizzle": "^0.2.2"
}
},
"node_modules/colorspace": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/colorspace/-/colorspace-1.1.4.tgz",
"integrity": "sha512-BgvKJiuVu1igBUF2kEjRCZXol6wiiGbY5ipL/oVPwm0BL9sIpMIzM8IK7vwuxIIzOXMV3Ey5w+vxhm0rR/TN8w==",
"dependencies": {
"color": "^3.1.3",
"text-hex": "1.0.x"
}
},
"node_modules/compressible": {
"version": "2.0.18",
"resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz",
"integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==",
"dependencies": {
"mime-db": ">= 1.43.0 < 2"
},
"engines": {
"node": ">= 0.6"
}
},
"node_modules/compression": {
"version": "1.7.4",
"resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz",
"integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==",
"dependencies": {
"accepts": "~1.3.5",
"bytes": "3.0.0",
"compressible": "~2.0.16",
"debug": "2.6.9",
"on-headers": "~1.0.2",
"safe-buffer": "5.1.2",
"vary": "~1.1.2"
},
"engines": {
"node": ">= 0.8.0"
}
},
"node_modules/content-disposition": { "node_modules/content-disposition": {
"version": "0.5.4", "version": "0.5.4",
"resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz",
@ -90,6 +198,25 @@
"node": ">= 0.6" "node": ">= 0.6"
} }
}, },
"node_modules/content-disposition/node_modules/safe-buffer": {
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
"integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/feross"
},
{
"type": "patreon",
"url": "https://www.patreon.com/feross"
},
{
"type": "consulting",
"url": "https://feross.org/support"
}
]
},
"node_modules/content-type": { "node_modules/content-type": {
"version": "1.0.5", "version": "1.0.5",
"resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz",
@ -111,6 +238,14 @@
"resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
"integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ=="
}, },
"node_modules/data-uri-to-buffer": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz",
"integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==",
"engines": {
"node": ">= 12"
}
},
"node_modules/debug": { "node_modules/debug": {
"version": "2.6.9", "version": "2.6.9",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
@ -157,6 +292,11 @@
"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
"integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="
}, },
"node_modules/enabled": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/enabled/-/enabled-2.0.0.tgz",
"integrity": "sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ=="
},
"node_modules/encodeurl": { "node_modules/encodeurl": {
"version": "1.0.2", "version": "1.0.2",
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
@ -238,6 +378,60 @@
"node": ">= 0.10.0" "node": ">= 0.10.0"
} }
}, },
"node_modules/express/node_modules/safe-buffer": {
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
"integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/feross"
},
{
"type": "patreon",
"url": "https://www.patreon.com/feross"
},
{
"type": "consulting",
"url": "https://feross.org/support"
}
]
},
"node_modules/fecha": {
"version": "4.2.3",
"resolved": "https://registry.npmjs.org/fecha/-/fecha-4.2.3.tgz",
"integrity": "sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw=="
},
"node_modules/fetch-blob": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz",
"integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/jimmywarting"
},
{
"type": "paypal",
"url": "https://paypal.me/jimmywarting"
}
],
"dependencies": {
"node-domexception": "^1.0.0",
"web-streams-polyfill": "^3.0.3"
},
"engines": {
"node": "^12.20 || >= 14.13"
}
},
"node_modules/file-stream-rotator": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/file-stream-rotator/-/file-stream-rotator-0.6.1.tgz",
"integrity": "sha512-u+dBid4PvZw17PmDeRcNOtCP9CCK/9lRN2w+r1xIS7yOL9JFrIBKTvrYsxT4P0pGtThYTn++QS5ChHaUov3+zQ==",
"dependencies": {
"moment": "^2.29.1"
}
},
"node_modules/finalhandler": { "node_modules/finalhandler": {
"version": "1.2.0", "version": "1.2.0",
"resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz",
@ -255,6 +449,22 @@
"node": ">= 0.8" "node": ">= 0.8"
} }
}, },
"node_modules/fn.name": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/fn.name/-/fn.name-1.1.0.tgz",
"integrity": "sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw=="
},
"node_modules/formdata-polyfill": {
"version": "4.0.10",
"resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz",
"integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==",
"dependencies": {
"fetch-blob": "^3.1.2"
},
"engines": {
"node": ">=12.20.0"
}
},
"node_modules/forwarded": { "node_modules/forwarded": {
"version": "0.2.0", "version": "0.2.0",
"resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
@ -391,6 +601,56 @@
"node": ">= 0.10" "node": ">= 0.10"
} }
}, },
"node_modules/is-arrayish": {
"version": "0.3.2",
"resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz",
"integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ=="
},
"node_modules/is-stream": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
"integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==",
"engines": {
"node": ">=8"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/kuler": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/kuler/-/kuler-2.0.0.tgz",
"integrity": "sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A=="
},
"node_modules/logform": {
"version": "2.6.1",
"resolved": "https://registry.npmjs.org/logform/-/logform-2.6.1.tgz",
"integrity": "sha512-CdaO738xRapbKIMVn2m4F6KTj4j7ooJ8POVnebSgKo3KBz5axNXRAL7ZdRjIV6NOr2Uf4vjtRkxrFETOioCqSA==",
"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"
},
"engines": {
"node": ">= 12.0.0"
}
},
"node_modules/logform/node_modules/ms": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
},
"node_modules/lru-cache": {
"version": "11.0.1",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.0.1.tgz",
"integrity": "sha512-CgeuL5uom6j/ZVrg7G/+1IXqRY8JXX4Hghfy5YE0EhoYQWvndP1kufu58cmZLNIDKnRhZrXfdS9urVWx98AipQ==",
"engines": {
"node": "20 || >=22"
}
},
"node_modules/media-typer": { "node_modules/media-typer": {
"version": "0.3.0", "version": "0.3.0",
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
@ -424,9 +684,9 @@
} }
}, },
"node_modules/mime-db": { "node_modules/mime-db": {
"version": "1.52.0", "version": "1.53.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.53.0.tgz",
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", "integrity": "sha512-oHlN/w+3MQ3rba9rqFr6V/ypF10LSkdwUysQL7GkXoTgIWeV+tcXGA852TBxH+gsh8UWoyhR1hKcoMJTuWflpg==",
"engines": { "engines": {
"node": ">= 0.6" "node": ">= 0.6"
} }
@ -442,6 +702,22 @@
"node": ">= 0.6" "node": ">= 0.6"
} }
}, },
"node_modules/mime-types/node_modules/mime-db": {
"version": "1.52.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/moment": {
"version": "2.30.1",
"resolved": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz",
"integrity": "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==",
"engines": {
"node": "*"
}
},
"node_modules/ms": { "node_modules/ms": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
@ -455,23 +731,47 @@
"node": ">= 0.6" "node": ">= 0.6"
} }
}, },
"node_modules/node-domexception": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz",
"integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/jimmywarting"
},
{
"type": "github",
"url": "https://paypal.me/jimmywarting"
}
],
"engines": {
"node": ">=10.5.0"
}
},
"node_modules/node-fetch": { "node_modules/node-fetch": {
"version": "2.7.0", "version": "3.3.2",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz",
"integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==",
"dependencies": { "dependencies": {
"whatwg-url": "^5.0.0" "data-uri-to-buffer": "^4.0.0",
"fetch-blob": "^3.1.4",
"formdata-polyfill": "^4.0.10"
}, },
"engines": { "engines": {
"node": "4.x || >=6.0.0" "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
}, },
"peerDependencies": { "funding": {
"encoding": "^0.1.0" "type": "opencollective",
}, "url": "https://opencollective.com/node-fetch"
"peerDependenciesMeta": { }
"encoding": { },
"optional": true "node_modules/object-hash": {
} "version": "3.0.0",
"resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz",
"integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==",
"engines": {
"node": ">= 6"
} }
}, },
"node_modules/object-inspect": { "node_modules/object-inspect": {
@ -496,6 +796,22 @@
"node": ">= 0.8" "node": ">= 0.8"
} }
}, },
"node_modules/on-headers": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz",
"integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==",
"engines": {
"node": ">= 0.8"
}
},
"node_modules/one-time": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/one-time/-/one-time-1.0.0.tgz",
"integrity": "sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g==",
"dependencies": {
"fn.name": "1.x.x"
}
},
"node_modules/parseurl": { "node_modules/parseurl": {
"version": "1.3.3", "version": "1.3.3",
"resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
@ -557,24 +873,39 @@
"node": ">= 0.8" "node": ">= 0.8"
} }
}, },
"node_modules/raw-body/node_modules/bytes": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
"integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==",
"engines": {
"node": ">= 0.8"
}
},
"node_modules/readable-stream": {
"version": "3.6.2",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
"integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
"dependencies": {
"inherits": "^2.0.3",
"string_decoder": "^1.1.1",
"util-deprecate": "^1.0.1"
},
"engines": {
"node": ">= 6"
}
},
"node_modules/safe-buffer": { "node_modules/safe-buffer": {
"version": "5.2.1", "version": "5.1.2",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
"integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
"funding": [ },
{ "node_modules/safe-stable-stringify": {
"type": "github", "version": "2.4.3",
"url": "https://github.com/sponsors/feross" "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.4.3.tgz",
}, "integrity": "sha512-e2bDA2WJT0wxseVd4lsDP4+3ONX6HpMXQa1ZhFQ7SU+GjvORCmShbCMltrtIDfkYhVHrOcPtj+KhmDBdPdZD1g==",
{ "engines": {
"type": "patreon", "node": ">=10"
"url": "https://www.patreon.com/feross" }
},
{
"type": "consulting",
"url": "https://feross.org/support"
}
]
}, },
"node_modules/safer-buffer": { "node_modules/safer-buffer": {
"version": "2.1.2", "version": "2.1.2",
@ -661,6 +992,22 @@
"url": "https://github.com/sponsors/ljharb" "url": "https://github.com/sponsors/ljharb"
} }
}, },
"node_modules/simple-swizzle": {
"version": "0.2.2",
"resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz",
"integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==",
"dependencies": {
"is-arrayish": "^0.3.1"
}
},
"node_modules/stack-trace": {
"version": "0.0.10",
"resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz",
"integrity": "sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==",
"engines": {
"node": "*"
}
},
"node_modules/statuses": { "node_modules/statuses": {
"version": "2.0.1", "version": "2.0.1",
"resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
@ -669,6 +1016,38 @@
"node": ">= 0.8" "node": ">= 0.8"
} }
}, },
"node_modules/string_decoder": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
"integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
"dependencies": {
"safe-buffer": "~5.2.0"
}
},
"node_modules/string_decoder/node_modules/safe-buffer": {
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
"integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/feross"
},
{
"type": "patreon",
"url": "https://www.patreon.com/feross"
},
{
"type": "consulting",
"url": "https://feross.org/support"
}
]
},
"node_modules/text-hex": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/text-hex/-/text-hex-1.0.0.tgz",
"integrity": "sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg=="
},
"node_modules/toidentifier": { "node_modules/toidentifier": {
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
@ -677,10 +1056,13 @@
"node": ">=0.6" "node": ">=0.6"
} }
}, },
"node_modules/tr46": { "node_modules/triple-beam": {
"version": "0.0.3", "version": "1.4.1",
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", "resolved": "https://registry.npmjs.org/triple-beam/-/triple-beam-1.4.1.tgz",
"integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" "integrity": "sha512-aZbgViZrg1QNcG+LULa7nhZpJTZSLm/mXnHXnbAbjmN5aSa0y7V+wvv6+4WaBtpISJzThKy+PIPxc1Nq1EJ9mg==",
"engines": {
"node": ">= 14.0.0"
}
}, },
"node_modules/type-is": { "node_modules/type-is": {
"version": "1.6.18", "version": "1.6.18",
@ -702,6 +1084,11 @@
"node": ">= 0.8" "node": ">= 0.8"
} }
}, },
"node_modules/util-deprecate": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="
},
"node_modules/utils-merge": { "node_modules/utils-merge": {
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
@ -718,18 +1105,63 @@
"node": ">= 0.8" "node": ">= 0.8"
} }
}, },
"node_modules/webidl-conversions": { "node_modules/web-streams-polyfill": {
"version": "3.0.1", "version": "3.3.3",
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz",
"integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==",
"engines": {
"node": ">= 8"
}
}, },
"node_modules/whatwg-url": { "node_modules/winston": {
"version": "5.0.0", "version": "3.14.2",
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", "resolved": "https://registry.npmjs.org/winston/-/winston-3.14.2.tgz",
"integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", "integrity": "sha512-CO8cdpBB2yqzEf8v895L+GNKYJiEq8eKlHU38af3snQBQ+sdAIUepjMSguOIJC7ICbzm0ZI+Af2If4vIJrtmOg==",
"dependencies": { "dependencies": {
"tr46": "~0.0.3", "@colors/colors": "^1.6.0",
"webidl-conversions": "^3.0.0" "@dabh/diagnostics": "^2.0.2",
"async": "^3.2.3",
"is-stream": "^2.0.0",
"logform": "^2.6.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.7.0"
},
"engines": {
"node": ">= 12.0.0"
}
},
"node_modules/winston-daily-rotate-file": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/winston-daily-rotate-file/-/winston-daily-rotate-file-5.0.0.tgz",
"integrity": "sha512-JDjiXXkM5qvwY06733vf09I2wnMXpZEhxEVOSPenZMii+g7pcDcTBt2MRugnoi8BwVSuCT2jfRXBUy+n1Zz/Yw==",
"dependencies": {
"file-stream-rotator": "^0.6.1",
"object-hash": "^3.0.0",
"triple-beam": "^1.4.1",
"winston-transport": "^4.7.0"
},
"engines": {
"node": ">=8"
},
"peerDependencies": {
"winston": "^3"
}
},
"node_modules/winston-transport": {
"version": "4.7.1",
"resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.7.1.tgz",
"integrity": "sha512-wQCXXVgfv/wUPOfb2x0ruxzwkcZfxcktz6JIMUaPLmcNhO4bZTwA/WtDWK74xV3F2dKu8YadrFv0qhwYjVEwhA==",
"dependencies": {
"logform": "^2.6.1",
"readable-stream": "^3.6.2",
"triple-beam": "^1.3.0"
},
"engines": {
"node": ">= 12.0.0"
} }
} }
} }

View File

@ -4,13 +4,18 @@
"description": "", "description": "",
"main": "app.js", "main": "app.js",
"scripts": { "scripts": {
"test": "echo \"Error: no test specified\" && exit 1" "test": "node app.js"
}, },
"type": "module",
"keywords": [], "keywords": [],
"author": "", "author": "",
"license": "ISC", "license": "ISC",
"dependencies": { "dependencies": {
"express": "^4.19.2", "compression": "^1.7.4",
"node-fetch": "^2.7.0" "express": "^4.17.1",
"lru-cache": "^11.0.1",
"node-fetch": "^3.3.2",
"winston": "^3.3.3",
"winston-daily-rotate-file": "^5.0.0"
} }
} }

View File

@ -110,7 +110,7 @@
}); });
// 异步加载 index.md 文件内容 // 异步加载 index.md 文件内容
fetch('https://random-api-file.czl.net/index.md') fetch('./index.md')
.then(response => response.text()) .then(response => response.text())
.then(markdownText => { .then(markdownText => {
// 渲染 Markdown 内容 // 渲染 Markdown 内容

View File

@ -20,14 +20,13 @@
| 所有 | [https://random-api.czl.net/video/all](https://random-api.czl.net/video/all) | | 所有 | [https://random-api.czl.net/video/all](https://random-api.czl.net/video/all) |
## 部署、更新和原理 ## 部署和原理
请见我的博客:[https://woodchen.ink/archives/1705367469203](https://woodchen.ink/archives/1705367469203) 请见我的帖子:[https://q58.org/questions/D1U1](https://q58.org/questions/D1U1)
**2024.06.28更新** ## 讨论
1. md,eo边缘函数的SLA太低了,天天抽风,换nodejs部署了 请在帖子下留言,我看到后会回复,谢谢。
2. url走内网,一个外部调用的index.md也不用套cdn了
**永久可用** **永久可用**

15
nodejs/public/url.json Normal file
View File

@ -0,0 +1,15 @@
{
"pic": {
"all": "https://random-api.czl.net/url/pic/all.csv",
"fjht": "https://random-api.czl.net/url/pic/fjht.csv",
"czlwb": "https://random-api.czl.net/url/pic/czl-website-background.csv",
"truegirl": "https://random-api.czl.net/url/pic/truegirl.csv",
"ecy": "https://random-api.czl.net/url/pic/ecy.csv",
"ecy1": "https://random-api.czl.net/url/pic/ecy1.csv",
"ecy2": "https://random-api.czl.net/url/pic/ecy2.csv"
},
"video": {
"all": "https://random-api.czl.net/url/video/all.csv"
}
}

View File

@ -0,0 +1,46 @@
#春节背景
#https://webp-sh.czl.net/r2/2023/12/31/65916acb9634f.jpg
#飞机背景
https://webp-sh.czl.net/qiniu/2023/09/14/6501e735b146c.jpg
#CZL圣诞节背景
https://webp-sh.czl.net/r2/2023/12/16/657da9007191a.jpg
#bing图纸
https://webp-sh.czl.net/r2/2024/02/18/65d0f633bd52c.webp
https://webp-sh.czl.net/r2/2024/02/18/65d0f618dcfef.webp
https://webp-sh.czl.net/r2/2024/02/18/65d0f60f95d7e.webp
https://webp-sh.czl.net/r2/2024/02/18/65d0f5fbc8fcc.webp
https://webp-sh.czl.net/r2/2024/02/18/65d0f5f8dce59.webp
https://webp-sh.czl.net/r2/2024/02/19/65d31fcf48fb3.webp
https://webp-sh.czl.net/r2/2024/02/19/65d31fee5061c.webp
https://webp-sh.czl.net/r2/2024/02/20/65d462ce0f055.webp
https://webp-sh.czl.net/r2/2024/03/07/65e97f284274b.webp
https://webp-sh.czl.net/r2/2024/03/07/65e9808f5dc93.webp
https://webp-sh.czl.net/r2/2024/03/07/65e980dda4b08.webp
https://webp-sh.czl.net/r2/2024/03/07/65e981091a71b.webp
https://webp-sh.czl.net/r2/2024/03/25/6600f61b7c6d3.jpg
https://webp-sh.czl.net/r2/2024/03/25/6600f61b92497.jpg
https://webp-sh.czl.net/r2/2024/03/25/6600f61b748e6.jpg
https://webp-sh.czl.net/r2/2024/03/25/6600f61b740ad.jpg
https://webp-sh.czl.net/r2/2024/03/25/6600f61b722aa.jpg
https://webp-sh.czl.net/r2/2024/03/25/6600f61b9ae13.jpg
https://webp-sh.czl.net/r2/2024/03/25/6600f61b74fcf.jpg
https://webp-sh.czl.net/r2/2024/03/28/6604dc14ab33c.webp
#截止2024.04.26
# 2024.08.19自己拍的
https://cdn-oracle.czl.net/img/2024/08/66c312512be41.jpeg
https://webp-sh.czl.net/r2/img/2024/08/66c316ba5f036.jpeg
https://webp-sh.czl.net/r2/img/2024/08/66c316ba81938.jpeg
https://webp-sh.czl.net/r2/img/2024/08/66c316ba7323b.jpeg
https://webp-sh.czl.net/r2/img/2024/08/66c316ba689ea.jpeg
# 2024.08.19bing图纸
https://webp-sh.czl.net/r2/img/2024/08/66c3175e69bea.jpg
https://webp-sh.czl.net/r2/img/2024/08/66c3175e6369f.jpg
1 #春节背景
2 #https://webp-sh.czl.net/r2/2023/12/31/65916acb9634f.jpg
3 #飞机背景
4 https://webp-sh.czl.net/qiniu/2023/09/14/6501e735b146c.jpg
5 #CZL圣诞节背景
6 https://webp-sh.czl.net/r2/2023/12/16/657da9007191a.jpg
7 #bing图纸
8 https://webp-sh.czl.net/r2/2024/02/18/65d0f633bd52c.webp
9 https://webp-sh.czl.net/r2/2024/02/18/65d0f618dcfef.webp
10 https://webp-sh.czl.net/r2/2024/02/18/65d0f60f95d7e.webp
11 https://webp-sh.czl.net/r2/2024/02/18/65d0f5fbc8fcc.webp
12 https://webp-sh.czl.net/r2/2024/02/18/65d0f5f8dce59.webp
13 https://webp-sh.czl.net/r2/2024/02/19/65d31fcf48fb3.webp
14 https://webp-sh.czl.net/r2/2024/02/19/65d31fee5061c.webp
15 https://webp-sh.czl.net/r2/2024/02/20/65d462ce0f055.webp
16 https://webp-sh.czl.net/r2/2024/03/07/65e97f284274b.webp
17 https://webp-sh.czl.net/r2/2024/03/07/65e9808f5dc93.webp
18 https://webp-sh.czl.net/r2/2024/03/07/65e980dda4b08.webp
19 https://webp-sh.czl.net/r2/2024/03/07/65e981091a71b.webp
20 https://webp-sh.czl.net/r2/2024/03/25/6600f61b7c6d3.jpg
21 https://webp-sh.czl.net/r2/2024/03/25/6600f61b92497.jpg
22 https://webp-sh.czl.net/r2/2024/03/25/6600f61b748e6.jpg
23 https://webp-sh.czl.net/r2/2024/03/25/6600f61b740ad.jpg
24 https://webp-sh.czl.net/r2/2024/03/25/6600f61b722aa.jpg
25 https://webp-sh.czl.net/r2/2024/03/25/6600f61b9ae13.jpg
26 https://webp-sh.czl.net/r2/2024/03/25/6600f61b74fcf.jpg
27 https://webp-sh.czl.net/r2/2024/03/28/6604dc14ab33c.webp
28 #截止2024.04.26
29 # 2024.08.19自己拍的
30 https://cdn-oracle.czl.net/img/2024/08/66c312512be41.jpeg
31 https://webp-sh.czl.net/r2/img/2024/08/66c316ba5f036.jpeg
32 https://webp-sh.czl.net/r2/img/2024/08/66c316ba81938.jpeg
33 https://webp-sh.czl.net/r2/img/2024/08/66c316ba7323b.jpeg
34 https://webp-sh.czl.net/r2/img/2024/08/66c316ba689ea.jpeg
35 # 2024.08.19bing图纸
36 https://webp-sh.czl.net/r2/img/2024/08/66c3175e69bea.jpg
37 https://webp-sh.czl.net/r2/img/2024/08/66c3175e6369f.jpg

View File

@ -1,15 +0,0 @@
{
"pic": {
"all": "https://random-api-file.czl.net/url/pic/all.csv",
"fjht": "https://random-api-file.czl.net/url/pic/fjht.csv",
"czlwb": "https://random-api-file.czl.net/url/pic/czl-website-background.csv",
"truegirl": "https://random-api-file.czl.net/url/pic/truegirl.csv",
"ecy": "https://random-api-file.czl.net/url/pic/ecy.csv",
"ecy1": "https://random-api-file.czl.net/url/pic/ecy1.csv",
"ecy2": "https://random-api-file.czl.net/url/pic/ecy2.csv"
},
"video": {
"all": "https://random-api-file.czl.net/url/video/all.csv"
}
}

View File

@ -1,34 +0,0 @@
#春节背景
#https://cdn-r2.czl.net/2023/12/31/65916acb9634f.jpg
#飞机背景
https://cdn-qiniu.czl.net/2023/09/14/6501e735b146c.jpg
#CZL圣诞节背景
https://cdn-r2.czl.net/2023/12/16/657da9007191a.jpg
#bing图纸
https://cdn-r2.czl.net/2024/02/18/65d0f633bd52c.webp
https://cdn-r2.czl.net/2024/02/18/65d0f618dcfef.webp
https://cdn-r2.czl.net/2024/02/18/65d0f60f95d7e.webp
https://cdn-r2.czl.net/2024/02/18/65d0f5fbc8fcc.webp
https://cdn-r2.czl.net/2024/02/18/65d0f5f8dce59.webp
https://cdn-r2.czl.net/2024/02/19/65d31fcf48fb3.webp
https://cdn-r2.czl.net/2024/02/19/65d31fee5061c.webp
https://cdn-r2.czl.net/2024/02/20/65d462ce0f055.webp
https://cdn-r2.czl.net/2024/03/07/65e97f284274b.webp
https://cdn-r2.czl.net/2024/03/07/65e9808f5dc93.webp
https://cdn-r2.czl.net/2024/03/07/65e980dda4b08.webp
https://cdn-r2.czl.net/2024/03/07/65e981091a71b.webp
https://cdn-r2.czl.net/2024/03/25/6600f61b7c6d3.jpg
https://cdn-r2.czl.net/2024/03/25/6600f61b92497.jpg
https://cdn-r2.czl.net/2024/03/25/6600f61b748e6.jpg
https://cdn-r2.czl.net/2024/03/25/6600f61b740ad.jpg
https://cdn-r2.czl.net/2024/03/25/6600f61b722aa.jpg
https://cdn-r2.czl.net/2024/03/25/6600f61b9ae13.jpg
https://cdn-r2.czl.net/2024/03/25/6600f61b74fcf.jpg
https://cdn-r2.czl.net/2024/03/28/6604dc14ab33c.webp
#截止2024.04.26
1 #春节背景
2 #https://cdn-r2.czl.net/2023/12/31/65916acb9634f.jpg
3 #飞机背景
4 https://cdn-qiniu.czl.net/2023/09/14/6501e735b146c.jpg
5 #CZL圣诞节背景
6 https://cdn-r2.czl.net/2023/12/16/657da9007191a.jpg
7 #bing图纸
8 https://cdn-r2.czl.net/2024/02/18/65d0f633bd52c.webp
9 https://cdn-r2.czl.net/2024/02/18/65d0f618dcfef.webp
10 https://cdn-r2.czl.net/2024/02/18/65d0f60f95d7e.webp
11 https://cdn-r2.czl.net/2024/02/18/65d0f5fbc8fcc.webp
12 https://cdn-r2.czl.net/2024/02/18/65d0f5f8dce59.webp
13 https://cdn-r2.czl.net/2024/02/19/65d31fcf48fb3.webp
14 https://cdn-r2.czl.net/2024/02/19/65d31fee5061c.webp
15 https://cdn-r2.czl.net/2024/02/20/65d462ce0f055.webp
16 https://cdn-r2.czl.net/2024/03/07/65e97f284274b.webp
17 https://cdn-r2.czl.net/2024/03/07/65e9808f5dc93.webp
18 https://cdn-r2.czl.net/2024/03/07/65e980dda4b08.webp
19 https://cdn-r2.czl.net/2024/03/07/65e981091a71b.webp
20 https://cdn-r2.czl.net/2024/03/25/6600f61b7c6d3.jpg
21 https://cdn-r2.czl.net/2024/03/25/6600f61b92497.jpg
22 https://cdn-r2.czl.net/2024/03/25/6600f61b748e6.jpg
23 https://cdn-r2.czl.net/2024/03/25/6600f61b740ad.jpg
24 https://cdn-r2.czl.net/2024/03/25/6600f61b722aa.jpg
25 https://cdn-r2.czl.net/2024/03/25/6600f61b9ae13.jpg
26 https://cdn-r2.czl.net/2024/03/25/6600f61b74fcf.jpg
27 https://cdn-r2.czl.net/2024/03/28/6604dc14ab33c.webp
28 #截止2024.04.26

View File

@ -1,5 +1,5 @@
// 外部 JSON 文件的 URL // 外部 JSON 文件的 URL
const CSV_PATHS_URL = 'https://random-api-file.czl.net/url.json'; const CSV_PATHS_URL = 'https://random-api.czl.net/url.json';
addEventListener('fetch', event => { addEventListener('fetch', event => {
event.respondWith(handleRequest(event.request)); event.respondWith(handleRequest(event.request));
@ -58,7 +58,7 @@ async function handleRequest(request) {
} }
} else { } else {
// 请求路径不在配置中,返回默认首页 // 请求路径不在配置中,返回默认首页
const indexHtmlResponse = await fetch('https://random-api-file.czl.net'); const indexHtmlResponse = await fetch('https://random-api.czl.net');
return new Response(indexHtmlResponse.body, { return new Response(indexHtmlResponse.body, {
headers: { 'Content-Type': 'text/html' }, headers: { 'Content-Type': 'text/html' },
}); });