mirror of
https://github.com/louislam/uptime-kuma.git
synced 2025-09-13 23:17:00 +08:00
Compare commits
4 Commits
fix-check-
...
fix-knex
Author | SHA1 | Date | |
---|---|---|---|
|
fb4f51c7ea | ||
|
60d65b18b7 | ||
|
3a20e4726d | ||
|
0c820a9d5b |
@@ -1,4 +1,4 @@
|
|||||||
name: validate
|
name: json-yaml-validate
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
@@ -26,8 +26,7 @@ jobs:
|
|||||||
comment: "true" # enable comment mode
|
comment: "true" # enable comment mode
|
||||||
exclude_file: ".github/config/exclude.txt" # gitignore style file for exclusions
|
exclude_file: ".github/config/exclude.txt" # gitignore style file for exclusions
|
||||||
|
|
||||||
# General validations
|
check-lang-json:
|
||||||
validate:
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
@@ -35,9 +34,4 @@ jobs:
|
|||||||
uses: actions/setup-node@v4
|
uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version: 20
|
node-version: 20
|
||||||
|
- run: node ./extra/check-lang-json.js
|
||||||
- name: Validate language JSON files
|
|
||||||
run: node ./extra/check-lang-json.js
|
|
||||||
|
|
||||||
- name: Validate knex migrations filename
|
|
||||||
run: node ./extra/check-knex-filenames.mjs
|
|
@@ -1,72 +0,0 @@
|
|||||||
import fs from "fs";
|
|
||||||
const dir = "./db/knex_migrations";
|
|
||||||
|
|
||||||
// Get the file list (ending with .js) from the directory
|
|
||||||
const files = fs.readdirSync(dir).filter((file) => file !== "README.md");
|
|
||||||
|
|
||||||
// They are wrong, but they had been merged, so allowed.
|
|
||||||
const exceptionList = [
|
|
||||||
"2024-08-24-000-add-cache-bust.js",
|
|
||||||
"2024-10-1315-rabbitmq-monitor.js",
|
|
||||||
];
|
|
||||||
|
|
||||||
// Correct format: YYYY-MM-DD-HHmm-description.js
|
|
||||||
|
|
||||||
for (const file of files) {
|
|
||||||
if (exceptionList.includes(file)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check ending with .js
|
|
||||||
if (!file.endsWith(".js")) {
|
|
||||||
console.error(`It should end with .js: ${file}`);
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
const parts = file.split("-");
|
|
||||||
|
|
||||||
// Should be at least 5 parts
|
|
||||||
if (parts.length < 5) {
|
|
||||||
console.error(`Invalid format: ${file}`);
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// First part should be a year >= 2024
|
|
||||||
const year = parseInt(parts[0], 10);
|
|
||||||
if (isNaN(year) || year < 2023) {
|
|
||||||
console.error(`Invalid year: ${file}`);
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Second part should be a month
|
|
||||||
const month = parseInt(parts[1], 10);
|
|
||||||
if (isNaN(month) || month < 1 || month > 12) {
|
|
||||||
console.error(`Invalid month: ${file}`);
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Third part should be a day
|
|
||||||
const day = parseInt(parts[2], 10);
|
|
||||||
if (isNaN(day) || day < 1 || day > 31) {
|
|
||||||
console.error(`Invalid day: ${file}`);
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fourth part should be HHmm
|
|
||||||
const time = parts[3];
|
|
||||||
|
|
||||||
// Check length is 4
|
|
||||||
if (time.length !== 4) {
|
|
||||||
console.error(`Invalid time: ${file}`);
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
const hour = parseInt(time.substring(0, 2), 10);
|
|
||||||
const minute = parseInt(time.substring(2), 10);
|
|
||||||
if (isNaN(hour) || hour < 0 || hour > 23 || isNaN(minute) || minute < 0 || minute > 59) {
|
|
||||||
console.error(`Invalid time: ${file}`);
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log("All knex filenames are correct.");
|
|
62
package-lock.json
generated
62
package-lock.json
generated
@@ -46,7 +46,7 @@
|
|||||||
"jsonwebtoken": "~9.0.0",
|
"jsonwebtoken": "~9.0.0",
|
||||||
"jwt-decode": "~3.1.2",
|
"jwt-decode": "~3.1.2",
|
||||||
"kafkajs": "^2.2.4",
|
"kafkajs": "^2.2.4",
|
||||||
"knex": "^2.4.2",
|
"knex": "~3.1.0",
|
||||||
"limiter": "~2.1.0",
|
"limiter": "~2.1.0",
|
||||||
"liquidjs": "^10.7.0",
|
"liquidjs": "^10.7.0",
|
||||||
"marked": "^14.0.0",
|
"marked": "^14.0.0",
|
||||||
@@ -54,7 +54,7 @@
|
|||||||
"mongodb": "~4.17.1",
|
"mongodb": "~4.17.1",
|
||||||
"mqtt": "~4.3.7",
|
"mqtt": "~4.3.7",
|
||||||
"mssql": "~11.0.0",
|
"mssql": "~11.0.0",
|
||||||
"mysql2": "~3.9.6",
|
"mysql2": "~3.11.3",
|
||||||
"nanoid": "~3.3.4",
|
"nanoid": "~3.3.4",
|
||||||
"net-snmp": "^3.11.2",
|
"net-snmp": "^3.11.2",
|
||||||
"node-cloudflared-tunnel": "~1.0.9",
|
"node-cloudflared-tunnel": "~1.0.9",
|
||||||
@@ -5655,6 +5655,15 @@
|
|||||||
"integrity": "sha512-aDczADvlvTGajTDjcjpJMqRkOF6Qdz3YbPZm/PyW6tKPkx2hlYBzxMhEywM/tU72HrVZjgl5VCdRuMlA7pZ8Gw==",
|
"integrity": "sha512-aDczADvlvTGajTDjcjpJMqRkOF6Qdz3YbPZm/PyW6tKPkx2hlYBzxMhEywM/tU72HrVZjgl5VCdRuMlA7pZ8Gw==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/aws-ssl-profiles": {
|
||||||
|
"version": "1.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/aws-ssl-profiles/-/aws-ssl-profiles-1.1.2.tgz",
|
||||||
|
"integrity": "sha512-NZKeq9AfyQvEeNlN0zSYAaWrmBffJh3IELMZfRpJVWgrpEbtEpnjvzqBPf+mxoI287JohRDoa+/nsfqqiZmF6g==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 6.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/axios": {
|
"node_modules/axios": {
|
||||||
"version": "0.28.1",
|
"version": "0.28.1",
|
||||||
"resolved": "https://registry.npmjs.org/axios/-/axios-0.28.1.tgz",
|
"resolved": "https://registry.npmjs.org/axios/-/axios-0.28.1.tgz",
|
||||||
@@ -10915,9 +10924,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/knex": {
|
"node_modules/knex": {
|
||||||
"version": "2.5.1",
|
"version": "3.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/knex/-/knex-2.5.1.tgz",
|
"resolved": "https://registry.npmjs.org/knex/-/knex-3.1.0.tgz",
|
||||||
"integrity": "sha512-z78DgGKUr4SE/6cm7ku+jHvFT0X97aERh/f0MUKAKgFnwCYBEW4TFBqtHWFYiJFid7fMrtpZ/gxJthvz5mEByA==",
|
"integrity": "sha512-GLoII6hR0c4ti243gMs5/1Rb3B+AjwMOfjYm97pu0FOQa7JH56hgBxYf5WK2525ceSbBY1cjeZ9yk99GPMB6Kw==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"colorette": "2.0.19",
|
"colorette": "2.0.19",
|
||||||
@@ -10929,7 +10938,7 @@
|
|||||||
"getopts": "2.3.0",
|
"getopts": "2.3.0",
|
||||||
"interpret": "^2.2.0",
|
"interpret": "^2.2.0",
|
||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
"pg-connection-string": "2.6.1",
|
"pg-connection-string": "2.6.2",
|
||||||
"rechoir": "^0.8.0",
|
"rechoir": "^0.8.0",
|
||||||
"resolve-from": "^5.0.0",
|
"resolve-from": "^5.0.0",
|
||||||
"tarn": "^3.0.2",
|
"tarn": "^3.0.2",
|
||||||
@@ -10939,7 +10948,7 @@
|
|||||||
"knex": "bin/cli.js"
|
"knex": "bin/cli.js"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=12"
|
"node": ">=16"
|
||||||
},
|
},
|
||||||
"peerDependenciesMeta": {
|
"peerDependenciesMeta": {
|
||||||
"better-sqlite3": {
|
"better-sqlite3": {
|
||||||
@@ -10989,9 +10998,9 @@
|
|||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/knex/node_modules/pg-connection-string": {
|
"node_modules/knex/node_modules/pg-connection-string": {
|
||||||
"version": "2.6.1",
|
"version": "2.6.2",
|
||||||
"resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.6.1.tgz",
|
"resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.6.2.tgz",
|
||||||
"integrity": "sha512-w6ZzNu6oMmIzEAYVw+RLK0+nqHPt8K3ZnknKi+g48Ak2pr3dtljJW3o+D/n2zzCG07Zoe9VOX3aiKpj+BN0pjg==",
|
"integrity": "sha512-ch6OwaeaPYcova4kKZ15sbJ2hKb/VP48ZD2gE7i1J+L4MspCtBMAx8nMgz7bksc7IojCIIWuEhHibSMFH8m8oA==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/knex/node_modules/resolve-from": {
|
"node_modules/knex/node_modules/resolve-from": {
|
||||||
@@ -11242,6 +11251,21 @@
|
|||||||
"node": ">=10"
|
"node": ">=10"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/lru.min": {
|
||||||
|
"version": "1.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/lru.min/-/lru.min-1.1.1.tgz",
|
||||||
|
"integrity": "sha512-FbAj6lXil6t8z4z3j0E5mfRlPzxkySotzUHwRXjlpRh10vc6AI6WN62ehZj82VG7M20rqogJ0GLwar2Xa05a8Q==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"bun": ">=1.0.0",
|
||||||
|
"deno": ">=1.30.0",
|
||||||
|
"node": ">=8.0.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/wellwelwel"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/magic-string": {
|
"node_modules/magic-string": {
|
||||||
"version": "0.30.12",
|
"version": "0.30.12",
|
||||||
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.12.tgz",
|
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.12.tgz",
|
||||||
@@ -11917,16 +11941,17 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/mysql2": {
|
"node_modules/mysql2": {
|
||||||
"version": "3.9.9",
|
"version": "3.11.3",
|
||||||
"resolved": "https://registry.npmjs.org/mysql2/-/mysql2-3.9.9.tgz",
|
"resolved": "https://registry.npmjs.org/mysql2/-/mysql2-3.11.3.tgz",
|
||||||
"integrity": "sha512-Qtb2RUxwWMFkWXqF7Rd/7ySkupbQnNY7O0zQuQYgPcuJZ06M36JG3HIDEh/pEeq7LImcvA6O3lOVQ9XQK+HEZg==",
|
"integrity": "sha512-Qpu2ADfbKzyLdwC/5d4W7+5Yz7yBzCU05YWt5npWzACST37wJsB23wgOSo00qi043urkiRwXtEvJc9UnuLX/MQ==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"aws-ssl-profiles": "^1.1.1",
|
||||||
"denque": "^2.1.0",
|
"denque": "^2.1.0",
|
||||||
"generate-function": "^2.3.1",
|
"generate-function": "^2.3.1",
|
||||||
"iconv-lite": "^0.6.3",
|
"iconv-lite": "^0.6.3",
|
||||||
"long": "^5.2.1",
|
"long": "^5.2.1",
|
||||||
"lru-cache": "^8.0.0",
|
"lru.min": "^1.0.0",
|
||||||
"named-placeholders": "^1.1.3",
|
"named-placeholders": "^1.1.3",
|
||||||
"seq-queue": "^0.0.5",
|
"seq-queue": "^0.0.5",
|
||||||
"sqlstring": "^2.3.2"
|
"sqlstring": "^2.3.2"
|
||||||
@@ -11935,15 +11960,6 @@
|
|||||||
"node": ">= 8.0"
|
"node": ">= 8.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/mysql2/node_modules/lru-cache": {
|
|
||||||
"version": "8.0.5",
|
|
||||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-8.0.5.tgz",
|
|
||||||
"integrity": "sha512-MhWWlVnuab1RG5/zMRRcVGXZLCXrZTgfwMikgzCegsPnG62yDQo5JnqKkrK4jO5iKqDAZGItAqN5CtKBCBWRUA==",
|
|
||||||
"license": "ISC",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=16.14"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/named-placeholders": {
|
"node_modules/named-placeholders": {
|
||||||
"version": "1.1.3",
|
"version": "1.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/named-placeholders/-/named-placeholders-1.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/named-placeholders/-/named-placeholders-1.1.3.tgz",
|
||||||
|
@@ -109,7 +109,7 @@
|
|||||||
"jsonwebtoken": "~9.0.0",
|
"jsonwebtoken": "~9.0.0",
|
||||||
"jwt-decode": "~3.1.2",
|
"jwt-decode": "~3.1.2",
|
||||||
"kafkajs": "^2.2.4",
|
"kafkajs": "^2.2.4",
|
||||||
"knex": "^2.4.2",
|
"knex": "~3.1.0",
|
||||||
"limiter": "~2.1.0",
|
"limiter": "~2.1.0",
|
||||||
"liquidjs": "^10.7.0",
|
"liquidjs": "^10.7.0",
|
||||||
"marked": "^14.0.0",
|
"marked": "^14.0.0",
|
||||||
@@ -117,7 +117,7 @@
|
|||||||
"mongodb": "~4.17.1",
|
"mongodb": "~4.17.1",
|
||||||
"mqtt": "~4.3.7",
|
"mqtt": "~4.3.7",
|
||||||
"mssql": "~11.0.0",
|
"mssql": "~11.0.0",
|
||||||
"mysql2": "~3.9.6",
|
"mysql2": "~3.11.3",
|
||||||
"nanoid": "~3.3.4",
|
"nanoid": "~3.3.4",
|
||||||
"net-snmp": "^3.11.2",
|
"net-snmp": "^3.11.2",
|
||||||
"node-cloudflared-tunnel": "~1.0.9",
|
"node-cloudflared-tunnel": "~1.0.9",
|
||||||
|
@@ -10,6 +10,7 @@ const { Settings } = require("./settings");
|
|||||||
const { UptimeCalculator } = require("./uptime-calculator");
|
const { UptimeCalculator } = require("./uptime-calculator");
|
||||||
const dayjs = require("dayjs");
|
const dayjs = require("dayjs");
|
||||||
const { SimpleMigrationServer } = require("./utils/simple-migration-server");
|
const { SimpleMigrationServer } = require("./utils/simple-migration-server");
|
||||||
|
const KumaColumnCompiler = require("./utils/knex/lib/dialects/mysql2/schema/mysql2-columncompiler");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Database & App Data Folder
|
* Database & App Data Folder
|
||||||
@@ -198,6 +199,14 @@ class Database {
|
|||||||
* @returns {Promise<void>}
|
* @returns {Promise<void>}
|
||||||
*/
|
*/
|
||||||
static async connect(testMode = false, autoloadModels = true, noLog = false) {
|
static async connect(testMode = false, autoloadModels = true, noLog = false) {
|
||||||
|
// Patch "mysql2" knex client
|
||||||
|
// Workaround: Tried extending the ColumnCompiler class, but it didn't work for unknown reasons, so I override the function via prototype
|
||||||
|
const { getDialectByNameOrAlias } = require("knex/lib/dialects");
|
||||||
|
const mysql2 = getDialectByNameOrAlias("mysql2");
|
||||||
|
mysql2.prototype.columnCompiler = function () {
|
||||||
|
return new KumaColumnCompiler(this, ...arguments);
|
||||||
|
};
|
||||||
|
|
||||||
const acquireConnectionTimeout = 120 * 1000;
|
const acquireConnectionTimeout = 120 * 1000;
|
||||||
let dbConfig;
|
let dbConfig;
|
||||||
try {
|
try {
|
||||||
|
@@ -0,0 +1,22 @@
|
|||||||
|
const ColumnCompilerMySQL = require("knex/lib/dialects/mysql/schema/mysql-columncompiler");
|
||||||
|
const { formatDefault } = require("knex/lib/formatter/formatterUtils");
|
||||||
|
const { log } = require("../../../../../../../src/util");
|
||||||
|
|
||||||
|
class KumaColumnCompiler extends ColumnCompilerMySQL {
|
||||||
|
/**
|
||||||
|
* Override defaultTo method to handle default value for TEXT fields
|
||||||
|
* @param {any} value Value
|
||||||
|
* @returns {string|void} Default value (Don't understand why it can return void or string, but it's the original code, lol)
|
||||||
|
*/
|
||||||
|
defaultTo(value) {
|
||||||
|
if (this.type === "text" && typeof value === "string") {
|
||||||
|
log.debug("defaultTo", `${this.args[0]}: ${this.type} ${value} ${typeof value}`);
|
||||||
|
// MySQL 8.0 is required and only if the value is written as an expression: https://dev.mysql.com/doc/refman/8.0/en/data-type-defaults.html
|
||||||
|
// MariaDB 10.2 is required: https://mariadb.com/kb/en/text/
|
||||||
|
return `default (${formatDefault(value, this.type, this.client)})`;
|
||||||
|
}
|
||||||
|
return super.defaultTo.apply(this, arguments);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = KumaColumnCompiler;
|
Reference in New Issue
Block a user