From cc5c1c7212f441171ea4f8288041e3fcdc69da62 Mon Sep 17 00:00:00 2001 From: expressgy Date: Thu, 24 Apr 2025 18:15:06 +0800 Subject: [PATCH] =?UTF-8?q?=E5=87=86=E5=A4=87=E5=86=99=E6=8E=A5=E5=8F=A3?= =?UTF-8?q?=EF=BC=8C=E4=BA=86=E8=A7=A3=E4=BA=86nuxt=E8=AF=B7=E6=B1=82?= =?UTF-8?q?=E7=9A=84=E7=94=9F=E5=91=BD=E5=91=A8=E6=9C=9F=EF=BC=8C=E4=B8=8D?= =?UTF-8?q?=E8=A6=81=E5=B0=9D=E8=AF=95=E5=9C=A8=E4=B8=AD=E9=97=B4=E4=BB=B6?= =?UTF-8?q?=E4=B8=AD=E7=AD=89=E8=AF=B7=E6=B1=82=E4=BD=93=E8=BF=94=E5=9B=9E?= =?UTF-8?q?=E5=90=8E=E5=A4=84=E7=90=86=E6=95=B0=E6=8D=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 4 + docs/001-博客设计思路.md | 28 + drizzle.config.js | 22 + drizzle/0000_fuzzy_lenny_balinger.sql | 23 + drizzle/customType.js | 27 + drizzle/schema.ts | 28 + drizzle/starwrit.sql | 51 ++ nuxt.config.ts | 63 +- package-lock.json | 606 +++++++++++++++++++- package.json | 10 +- server/api/blog/blogMenu/[blogId].delete.ts | 3 + server/api/blog/blogMenu/[blogId].patch.ts | 3 + server/api/blog/blogMenu/[blogId].put.ts | 3 + server/api/blog/blogMenu/index.get.ts | 3 + server/api/blog/blogMenu/index.post.ts | 3 + server/api/hello.ts | 8 +- server/api/home.ts | 12 + server/middleware/01-logger.ts | 7 +- server/middleware/02.auth.ts | 29 + server/plugins/mysql.ts | 8 +- server/plugins/redis.ts | 2 +- server/routes/home.ts | 12 + server/utils/entity.ts | 4 + server/utils/jwt.ts | 21 + types/nuxt.config.d.ts | 11 + 25 files changed, 953 insertions(+), 38 deletions(-) create mode 100644 docs/001-博客设计思路.md create mode 100644 drizzle.config.js create mode 100644 drizzle/0000_fuzzy_lenny_balinger.sql create mode 100644 drizzle/customType.js create mode 100644 drizzle/schema.ts create mode 100644 drizzle/starwrit.sql create mode 100644 server/api/blog/blogMenu/[blogId].delete.ts create mode 100644 server/api/blog/blogMenu/[blogId].patch.ts create mode 100644 server/api/blog/blogMenu/[blogId].put.ts create mode 100644 server/api/blog/blogMenu/index.get.ts create mode 100644 server/api/blog/blogMenu/index.post.ts create mode 100644 server/api/home.ts create mode 100644 server/middleware/02.auth.ts create mode 100644 server/routes/home.ts create mode 100644 server/utils/entity.ts create mode 100644 server/utils/jwt.ts create mode 100644 types/nuxt.config.d.ts diff --git a/.gitignore b/.gitignore index 4a7f73a..0cdff89 100644 --- a/.gitignore +++ b/.gitignore @@ -22,3 +22,7 @@ logs .env .env.* !.env.example + +# drizzle schema +drizzle/meta +drizzle/relations.ts diff --git a/docs/001-博客设计思路.md b/docs/001-博客设计思路.md new file mode 100644 index 0000000..5230420 --- /dev/null +++ b/docs/001-博客设计思路.md @@ -0,0 +1,28 @@ +# 博客设计思路 + +## 目录结构 + +- 可建立多级子目录 + +## 目录属性 + +- 目录名称: name +- 上级目录: pid +- 目录图标: icon +- 目录标签: label +- 排序: sort +- 阅读量: read +- 点赞量: like +- 是否公开: public +- 是否删除: deleted +- 创建时间: createtime +- 修改时间: updatetime +- 创建人: createuser + +## 目录接口 + +- 获取用户目录 blog/blogMenu.get +- 删除目录-》存在子集要提示 blog/blogMenu.[blogId].delete +- 创建目录 blog/blogMenu.post +- 修改目录名称或图标 blog/blogMenu.[blogId].update +- 修改目录顺序 blog/blogMenu.[blogId].patch diff --git a/drizzle.config.js b/drizzle.config.js new file mode 100644 index 0000000..d4b602b --- /dev/null +++ b/drizzle.config.js @@ -0,0 +1,22 @@ +import dotenv from 'dotenv'; + +dotenv.config({ path: '.env' }); + +export default { + schema: './drizzle/schema.ts', + out: './drizzle', + dialect: 'mysql', + dbCredentials: { + host: process.env.DB_HOST, + port: Number(process.env.DB_PORT), + user: process.env.DB_USER, + password: process.env.DB_PASSWORD, + database: process.env.DB_NAME, + }, + verbose: true, + strict: true, + introspect: { + // 启用驼峰命名 + casing: 'camel', + }, +}; diff --git a/drizzle/0000_fuzzy_lenny_balinger.sql b/drizzle/0000_fuzzy_lenny_balinger.sql new file mode 100644 index 0000000..cb24c07 --- /dev/null +++ b/drizzle/0000_fuzzy_lenny_balinger.sql @@ -0,0 +1,23 @@ +CREATE TABLE `blog_menu` ( + `id` bigint NOT NULL, + `pid` bigint NOT NULL, + `name` varchar(255) NOT NULL, + `desc` varchar(255), + `icon` varchar(255) NOT NULL DEFAULT '', + `label` varchar(255), + `background` varchar(255), + `sort` int NOT NULL DEFAULT 0, + `read` int NOT NULL DEFAULT 0, + `like` int NOT NULL DEFAULT 0, + `public` tinyint NOT NULL DEFAULT 1, + `deleted` tinyint NOT NULL DEFAULT 0, + `created_at` datetime NOT NULL DEFAULT (CURRENT_TIMESTAMP), + `updated_at` datetime NOT NULL DEFAULT (CURRENT_TIMESTAMP), + `deleted_at` varchar(255), + `created_by` bigint NOT NULL, + CONSTRAINT `blog_menu_id` PRIMARY KEY(`id`), + CONSTRAINT `unique_checkname` UNIQUE(`pid`,`name`,`deleted_at`) +); +--> statement-breakpoint +CREATE INDEX `create_at` ON `blog_menu` (`created_at`);--> statement-breakpoint +CREATE INDEX `name` ON `blog_menu` (`name`); \ No newline at end of file diff --git a/drizzle/customType.js b/drizzle/customType.js new file mode 100644 index 0000000..190fc37 --- /dev/null +++ b/drizzle/customType.js @@ -0,0 +1,27 @@ +// | ------------------------------------------------------------ +// | @版本: version 0.1 +// | @创建人: 【Nie-x7129】 +// | @E-mail: x71291@outlook.com +// | @所在项目: pac-auth +// | @文件描述: customType.ts - +// | @创建时间: 2024-06-04 16:27 +// | @更新时间: 2024-06-04 16:27 +// | @修改记录: +// | -*-*-*- (时间--修改人--修改说明) -*-*-*- +// | = +// | ------------------------------------------------------------ +// 定义自定义类型 +import { customType } from 'drizzle-orm/mysql-core'; + +// 写入读取是将bigint转化为string +export const bigintString = customType({ + dataType() { + return 'bigint'; + }, + fromDriver(value) { // 数据库 -> JS + return value?.toString(); // 处理 null 值 + }, + toDriver(value) { // JS -> 数据库 + return BigInt(value); // 确保写入时为数字类型 + } +}); \ No newline at end of file diff --git a/drizzle/schema.ts b/drizzle/schema.ts new file mode 100644 index 0000000..30e7ccd --- /dev/null +++ b/drizzle/schema.ts @@ -0,0 +1,28 @@ +import { mysqlTable, index, primaryKey, unique, varchar, int, tinyint, datetime } from "drizzle-orm/mysql-core" +import { sql } from "drizzle-orm" +import { bigintString } from './customType.js'; +const bigint = bigintString; +export const blogMenu = mysqlTable("blog_menu", { + id: bigint({ mode: "number" }).notNull(), + pid: bigint({ mode: "number" }).notNull(), + name: varchar({ length: 255 }).notNull(), + desc: varchar({ length: 255 }), + icon: varchar({ length: 255 }).default("").notNull(), + label: varchar({ length: 255 }), + background: varchar({ length: 255 }), + sort: int().default(0).notNull(), + read: int().default(0).notNull(), + like: int().default(0).notNull(), + public: tinyint().default(1).notNull(), + deleted: tinyint().default(0).notNull(), + createdAt: datetime("created_at", { mode: 'string'}).default(sql`(CURRENT_TIMESTAMP)`).notNull(), + updatedAt: datetime("updated_at", { mode: 'string'}).default(sql`(CURRENT_TIMESTAMP)`), + deletedAt: varchar("deleted_at", { length: 255 }), + createdBy: bigint("created_by", { mode: "number" }).notNull(), +}, +(table) => [ + index("create_at").on(table.createdAt), + index("name").on(table.name), + primaryKey({ columns: [table.id], name: "blog_menu_id"}), + unique("unique_checkname").on(table.pid, table.name, table.deletedAt), +]); diff --git a/drizzle/starwrit.sql b/drizzle/starwrit.sql new file mode 100644 index 0000000..f29f474 --- /dev/null +++ b/drizzle/starwrit.sql @@ -0,0 +1,51 @@ +/* + Navicat Premium Data Transfer + + Source Server : 172root + Source Server Type : MySQL + Source Server Version : 80403 (8.4.3) + Source Host : 172.16.1.10:3306 + Source Schema : starwrit + + Target Server Type : MySQL + Target Server Version : 80403 (8.4.3) + File Encoding : 65001 + + Date: 24/04/2025 18:13:26 +*/ + +SET NAMES utf8mb4; +SET FOREIGN_KEY_CHECKS = 0; + +-- ---------------------------- +-- Table structure for blog_menu +-- ---------------------------- +DROP TABLE IF EXISTS `blog_menu`; +CREATE TABLE `blog_menu` ( + `id` bigint NOT NULL COMMENT 'menuId', + `pid` bigint NOT NULL DEFAULT 0 COMMENT '上级ID', + `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '目录名', + `desc` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '描述', + `icon` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT '' COMMENT '图标', + `label` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '标签', + `background` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '背景', + `sort` int NOT NULL DEFAULT 0 COMMENT '排序', + `read` int NOT NULL DEFAULT 0 COMMENT '阅读量', + `like` int NOT NULL DEFAULT 0 COMMENT '喜欢', + `public` tinyint NOT NULL DEFAULT 1 COMMENT '公开', + `deleted` tinyint NOT NULL DEFAULT 0 COMMENT '删除', + `created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建者', + `updated_at` datetime NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '创建时间', + `deleted_at` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '删除时间', + `created_by` bigint NOT NULL COMMENT '修改时间', + PRIMARY KEY (`id`) USING BTREE, + UNIQUE INDEX `unique_checkname`(`pid` ASC, `name` ASC, `deleted_at` ASC) USING BTREE COMMENT '重名', + INDEX `name`(`name` ASC) USING BTREE COMMENT '名称搜索优化', + INDEX `create_at`(`created_at` ASC) USING BTREE COMMENT '创建人搜索优化' +) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of blog_menu +-- ---------------------------- + +SET FOREIGN_KEY_CHECKS = 1; diff --git a/nuxt.config.ts b/nuxt.config.ts index 03c389a..c0c6a43 100644 --- a/nuxt.config.ts +++ b/nuxt.config.ts @@ -11,6 +11,7 @@ export default defineNuxtConfig({ modules: ['@nuxt/eslint', '@nuxtjs/tailwindcss'], devServer: { host: '0.0.0.0', + port: 3000, }, css: [ '~/assets/css/style.css', @@ -55,30 +56,42 @@ export default defineNuxtConfig({ }, }, runtimeConfig: { - server: { - redis: { - host: process.env.REDIS_HOST || '127.0.0.1', - port: Number(process.env.REDIS_PORT) || 6379, - connectName: 'star-writ', - database: Number(process.env.REDIS_DB) || 9, - username: 'default', - password: process.env.REDIS_PASSWORD || 'Hxl1314521', - }, - mysql:{ - host: process.env.DB_HOST || '127.0.0.1', - port: process.env.DB_PORT || 3306, - user: process.env.DB_USER || 'root', - password: process.env.DB_PASSWORD, - database: process.env.DB_NAME || 'yuheng', - ssl: - process.env.NODE_ENV === 'production' - ? { - rejectUnauthorized: false, - servername: '', // 明确置空servername参数 - } - : null, - } - } + redis: { + host: process.env.REDIS_HOST || '127.0.0.1', + port: Number(process.env.REDIS_PORT) || 6379, + connectName: 'star-writ', + database: Number(process.env.REDIS_DB) || 9, + username: 'default', + password: process.env.REDIS_PASSWORD || 'Hxl1314521', + }, + mysql:{ + host: process.env.DB_HOST || '127.0.0.1', + port: Number(process.env.DB_PORT) || 3306, + user: process.env.DB_USER || 'root', + password: process.env.DB_PASSWORD, + database: process.env.DB_NAME || 'yuheng', + // ssl: + // process.env.NODE_ENV === 'production' + // ? { + // rejectUnauthorized: false, + // servername: '', // 明确置空servername参数 + // } + // : null, + }, + jwt: { + secret: process.env.JWT_SECRET || 'Hxl1314521', + accessExpiresIn: process.env.JWT_ACCESS_EXPIRES || '20m', + refreshExpiresIn: process.env.JWT_REFRESH_EXPIRES || '14d', + whitelist: [ + '/user/login', + '/user/register', + '/user/refreshToken', + '/', + // '/module', + '/docs*', + '/docs/json' + ], + }, }, }) @@ -122,4 +135,4 @@ async function startBroswer(address: AddressInfo | string | null) { process.env.START = String(true) } } -} \ No newline at end of file +} diff --git a/package-lock.json b/package-lock.json index ed08bf6..4f051ab 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,8 +9,10 @@ "dependencies": { "@nuxt/eslint": "^1.3.0", "consola": "^3.4.2", + "dayjs": "^1.11.13", "drizzle-orm": "^0.42.0", "eslint": "^9.25.0", + "jsonwebtoken": "^9.0.2", "mysql2": "^3.14.0", "nuxt": "^3.16.2", "redis": "^4.7.0", @@ -19,7 +21,9 @@ }, "devDependencies": { "@nuxtjs/tailwindcss": "^6.13.2", + "@types/jsonwebtoken": "^9.0.9", "autoprefixer": "^10.4.21", + "drizzle-kit": "^0.31.0", "open": "^10.1.1", "postcss": "^8.5.3", "sass": "^1.86.3", @@ -609,6 +613,13 @@ "node": ">=14" } }, + "node_modules/@drizzle-team/brocli": { + "version": "0.10.2", + "resolved": "https://registry.npmmirror.com/@drizzle-team/brocli/-/brocli-0.10.2.tgz", + "integrity": "sha512-z33Il7l5dKjUgGULTqBsQBQwckHh5AbIuxhdsIxDDiZAzBOrZO6q9ogcWC65kU382AfynTfgNumVcNIjuIua6w==", + "dev": true, + "license": "Apache-2.0" + }, "node_modules/@emnapi/core": { "version": "1.4.3", "resolved": "https://registry.npmmirror.com/@emnapi/core/-/core-1.4.3.tgz", @@ -654,6 +665,442 @@ "node": ">=16" } }, + "node_modules/@esbuild-kit/core-utils": { + "version": "3.3.2", + "resolved": "https://registry.npmmirror.com/@esbuild-kit/core-utils/-/core-utils-3.3.2.tgz", + "integrity": "sha512-sPRAnw9CdSsRmEtnsl2WXWdyquogVpB3yZ3dgwJfe8zrOzTsV7cJvmwrKVa+0ma5BoiGJ+BoqkMvawbayKUsqQ==", + "deprecated": "Merged into tsx: https://tsx.is", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "~0.18.20", + "source-map-support": "^0.5.21" + } + }, + "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/android-arm": { + "version": "0.18.20", + "resolved": "https://registry.npmmirror.com/@esbuild/android-arm/-/android-arm-0.18.20.tgz", + "integrity": "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/android-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmmirror.com/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz", + "integrity": "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/android-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmmirror.com/@esbuild/android-x64/-/android-x64-0.18.20.tgz", + "integrity": "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/darwin-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmmirror.com/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz", + "integrity": "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/darwin-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmmirror.com/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz", + "integrity": "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/freebsd-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmmirror.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz", + "integrity": "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/freebsd-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmmirror.com/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz", + "integrity": "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/linux-arm": { + "version": "0.18.20", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz", + "integrity": "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/linux-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz", + "integrity": "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/linux-ia32": { + "version": "0.18.20", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz", + "integrity": "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/linux-loong64": { + "version": "0.18.20", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz", + "integrity": "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/linux-mips64el": { + "version": "0.18.20", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz", + "integrity": "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/linux-ppc64": { + "version": "0.18.20", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz", + "integrity": "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/linux-riscv64": { + "version": "0.18.20", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz", + "integrity": "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/linux-s390x": { + "version": "0.18.20", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz", + "integrity": "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/linux-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz", + "integrity": "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/netbsd-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmmirror.com/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz", + "integrity": "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/openbsd-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmmirror.com/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz", + "integrity": "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/sunos-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmmirror.com/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz", + "integrity": "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/win32-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmmirror.com/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz", + "integrity": "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/win32-ia32": { + "version": "0.18.20", + "resolved": "https://registry.npmmirror.com/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz", + "integrity": "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/win32-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmmirror.com/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz", + "integrity": "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild-kit/core-utils/node_modules/esbuild": { + "version": "0.18.20", + "resolved": "https://registry.npmmirror.com/esbuild/-/esbuild-0.18.20.tgz", + "integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/android-arm": "0.18.20", + "@esbuild/android-arm64": "0.18.20", + "@esbuild/android-x64": "0.18.20", + "@esbuild/darwin-arm64": "0.18.20", + "@esbuild/darwin-x64": "0.18.20", + "@esbuild/freebsd-arm64": "0.18.20", + "@esbuild/freebsd-x64": "0.18.20", + "@esbuild/linux-arm": "0.18.20", + "@esbuild/linux-arm64": "0.18.20", + "@esbuild/linux-ia32": "0.18.20", + "@esbuild/linux-loong64": "0.18.20", + "@esbuild/linux-mips64el": "0.18.20", + "@esbuild/linux-ppc64": "0.18.20", + "@esbuild/linux-riscv64": "0.18.20", + "@esbuild/linux-s390x": "0.18.20", + "@esbuild/linux-x64": "0.18.20", + "@esbuild/netbsd-x64": "0.18.20", + "@esbuild/openbsd-x64": "0.18.20", + "@esbuild/sunos-x64": "0.18.20", + "@esbuild/win32-arm64": "0.18.20", + "@esbuild/win32-ia32": "0.18.20", + "@esbuild/win32-x64": "0.18.20" + } + }, + "node_modules/@esbuild-kit/esm-loader": { + "version": "2.6.5", + "resolved": "https://registry.npmmirror.com/@esbuild-kit/esm-loader/-/esm-loader-2.6.5.tgz", + "integrity": "sha512-FxEMIkJKnodyA1OaCUoEvbYRkoZlLZ4d/eXFu9Fh8CbBBgP5EmZxrfTRyN0qpXZ4vOvqnE5YdRdcrmUUXuU+dA==", + "deprecated": "Merged into tsx: https://tsx.is", + "dev": true, + "license": "MIT", + "dependencies": { + "@esbuild-kit/core-utils": "^3.3.2", + "get-tsconfig": "^4.7.0" + } + }, "node_modules/@esbuild/aix-ppc64": { "version": "0.25.2", "resolved": "https://registry.npmmirror.com/@esbuild/aix-ppc64/-/aix-ppc64-0.25.2.tgz", @@ -4103,12 +4550,30 @@ "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", "license": "MIT" }, + "node_modules/@types/jsonwebtoken": { + "version": "9.0.9", + "resolved": "https://registry.npmmirror.com/@types/jsonwebtoken/-/jsonwebtoken-9.0.9.tgz", + "integrity": "sha512-uoe+GxEuHbvy12OUQct2X9JenKM3qAscquYymuQN4fMWG9DBQtykrQEFcAbVACF7qaLw9BePSodUL0kquqBJpQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/ms": "*", + "@types/node": "*" + } + }, + "node_modules/@types/ms": { + "version": "2.1.0", + "resolved": "https://registry.npmmirror.com/@types/ms/-/ms-2.1.0.tgz", + "integrity": "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/node": { "version": "22.14.1", "resolved": "https://registry.npmmirror.com/@types/node/-/node-22.14.1.tgz", "integrity": "sha512-u0HuPQwe/dHrItgHHpmw3N2fYCR6x4ivMNbPHRkBVP4CvN+kiRrKHWk3i8tXiO/joPwXLMYvF9TTF0eqgHIuOw==", + "devOptional": true, "license": "MIT", - "optional": true, "dependencies": { "undici-types": "~6.21.0" } @@ -5867,6 +6332,12 @@ "node": ">=8.0.0" } }, + "node_modules/buffer-equal-constant-time": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", + "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==", + "license": "BSD-3-Clause" + }, "node_modules/buffer-from": { "version": "1.1.2", "resolved": "https://registry.npmmirror.com/buffer-from/-/buffer-from-1.1.2.tgz", @@ -6791,6 +7262,12 @@ "node": ">= 12" } }, + "node_modules/dayjs": { + "version": "1.11.13", + "resolved": "https://registry.npmmirror.com/dayjs/-/dayjs-1.11.13.tgz", + "integrity": "sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==", + "license": "MIT" + }, "node_modules/db0": { "version": "0.3.2", "resolved": "https://registry.npmmirror.com/db0/-/db0-0.3.2.tgz", @@ -7223,6 +7700,22 @@ "url": "https://dotenvx.com" } }, + "node_modules/drizzle-kit": { + "version": "0.31.0", + "resolved": "https://registry.npmmirror.com/drizzle-kit/-/drizzle-kit-0.31.0.tgz", + "integrity": "sha512-pcKVT+GbfPA+bUovPIilgVOoq+onNBo/YQBG86sf3/GFHkN6lRJPm1l7dKN0IMAk57RQoIm4GUllRrasLlcaSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@drizzle-team/brocli": "^0.10.2", + "@esbuild-kit/esm-loader": "^2.5.5", + "esbuild": "^0.25.2", + "esbuild-register": "^3.5.0" + }, + "bin": { + "drizzle-kit": "bin.cjs" + } + }, "node_modules/drizzle-orm": { "version": "0.42.0", "resolved": "https://registry.npmjs.org/drizzle-orm/-/drizzle-orm-0.42.0.tgz", @@ -7370,6 +7863,15 @@ "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", "license": "MIT" }, + "node_modules/ecdsa-sig-formatter": { + "version": "1.0.11", + "resolved": "https://registry.npmmirror.com/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", + "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", + "license": "Apache-2.0", + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, "node_modules/ee-first": { "version": "1.1.1", "resolved": "https://registry.npmmirror.com/ee-first/-/ee-first-1.1.1.tgz", @@ -7540,6 +8042,19 @@ "@esbuild/win32-x64": "0.25.2" } }, + "node_modules/esbuild-register": { + "version": "3.6.0", + "resolved": "https://registry.npmmirror.com/esbuild-register/-/esbuild-register-3.6.0.tgz", + "integrity": "sha512-H2/S7Pm8a9CL1uhp9OvjwrBh5Pvx0H8qVOxNu8Wed9Y7qv56MPtq+GGM8RJpq6glYJn9Wspr8uw7l55uyinNeg==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.3.4" + }, + "peerDependencies": { + "esbuild": ">=0.12 <1" + } + }, "node_modules/escalade": { "version": "3.2.0", "resolved": "https://registry.npmmirror.com/escalade/-/escalade-3.2.0.tgz", @@ -9864,6 +10379,28 @@ "graceful-fs": "^4.1.6" } }, + "node_modules/jsonwebtoken": { + "version": "9.0.2", + "resolved": "https://registry.npmmirror.com/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz", + "integrity": "sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==", + "license": "MIT", + "dependencies": { + "jws": "^3.2.2", + "lodash.includes": "^4.3.0", + "lodash.isboolean": "^3.0.3", + "lodash.isinteger": "^4.0.4", + "lodash.isnumber": "^3.0.3", + "lodash.isplainobject": "^4.0.6", + "lodash.isstring": "^4.0.1", + "lodash.once": "^4.0.0", + "ms": "^2.1.1", + "semver": "^7.5.4" + }, + "engines": { + "node": ">=12", + "npm": ">=6" + } + }, "node_modules/junk": { "version": "4.0.1", "resolved": "https://registry.npmmirror.com/junk/-/junk-4.0.1.tgz", @@ -9876,6 +10413,27 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/jwa": { + "version": "1.4.1", + "resolved": "https://registry.npmmirror.com/jwa/-/jwa-1.4.1.tgz", + "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", + "license": "MIT", + "dependencies": { + "buffer-equal-constant-time": "1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/jws": { + "version": "3.2.2", + "resolved": "https://registry.npmmirror.com/jws/-/jws-3.2.2.tgz", + "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", + "license": "MIT", + "dependencies": { + "jwa": "^1.4.1", + "safe-buffer": "^5.0.1" + } + }, "node_modules/jwt-decode": { "version": "4.0.0", "resolved": "https://registry.npmmirror.com/jwt-decode/-/jwt-decode-4.0.0.tgz", @@ -10328,12 +10886,48 @@ "integrity": "sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==", "license": "MIT" }, + "node_modules/lodash.includes": { + "version": "4.3.0", + "resolved": "https://registry.npmmirror.com/lodash.includes/-/lodash.includes-4.3.0.tgz", + "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==", + "license": "MIT" + }, "node_modules/lodash.isarguments": { "version": "3.1.0", "resolved": "https://registry.npmmirror.com/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz", "integrity": "sha512-chi4NHZlZqZD18a0imDHnZPrDeBbTtVN7GXMwuGdRH9qotxAjYs3aVLKc7zNOG9eddR5Ksd8rvFEBc9SsggPpg==", "license": "MIT" }, + "node_modules/lodash.isboolean": { + "version": "3.0.3", + "resolved": "https://registry.npmmirror.com/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", + "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==", + "license": "MIT" + }, + "node_modules/lodash.isinteger": { + "version": "4.0.4", + "resolved": "https://registry.npmmirror.com/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", + "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==", + "license": "MIT" + }, + "node_modules/lodash.isnumber": { + "version": "3.0.3", + "resolved": "https://registry.npmmirror.com/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", + "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==", + "license": "MIT" + }, + "node_modules/lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmmirror.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==", + "license": "MIT" + }, + "node_modules/lodash.isstring": { + "version": "4.0.1", + "resolved": "https://registry.npmmirror.com/lodash.isstring/-/lodash.isstring-4.0.1.tgz", + "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==", + "license": "MIT" + }, "node_modules/lodash.memoize": { "version": "4.1.2", "resolved": "https://registry.npmmirror.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz", @@ -10346,6 +10940,12 @@ "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", "license": "MIT" }, + "node_modules/lodash.once": { + "version": "4.1.1", + "resolved": "https://registry.npmmirror.com/lodash.once/-/lodash.once-4.1.1.tgz", + "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==", + "license": "MIT" + }, "node_modules/lodash.uniq": { "version": "4.5.0", "resolved": "https://registry.npmmirror.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz", @@ -14863,8 +15463,8 @@ "version": "6.21.0", "resolved": "https://registry.npmmirror.com/undici-types/-/undici-types-6.21.0.tgz", "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", - "license": "MIT", - "optional": true + "devOptional": true, + "license": "MIT" }, "node_modules/unenv": { "version": "2.0.0-rc.15", diff --git a/package.json b/package.json index 17104b4..a65c748 100644 --- a/package.json +++ b/package.json @@ -7,13 +7,19 @@ "dev": "nuxt dev", "generate": "nuxt generate", "preview": "nuxt preview --port 4000", - "postinstall": "nuxt prepare" + "postinstall": "nuxt prepare", + "makeSQL": "drizzle-kit generate", + "makeEntity": "drizzle-kit introspect", + "syncDB": "drizzle-kit migrate", + "sqlV": "drizzle-kit studio" }, "dependencies": { "@nuxt/eslint": "^1.3.0", "consola": "^3.4.2", + "dayjs": "^1.11.13", "drizzle-orm": "^0.42.0", "eslint": "^9.25.0", + "jsonwebtoken": "^9.0.2", "mysql2": "^3.14.0", "nuxt": "^3.16.2", "redis": "^4.7.0", @@ -22,7 +28,9 @@ }, "devDependencies": { "@nuxtjs/tailwindcss": "^6.13.2", + "@types/jsonwebtoken": "^9.0.9", "autoprefixer": "^10.4.21", + "drizzle-kit": "^0.31.0", "open": "^10.1.1", "postcss": "^8.5.3", "sass": "^1.86.3", diff --git a/server/api/blog/blogMenu/[blogId].delete.ts b/server/api/blog/blogMenu/[blogId].delete.ts new file mode 100644 index 0000000..675cda1 --- /dev/null +++ b/server/api/blog/blogMenu/[blogId].delete.ts @@ -0,0 +1,3 @@ +export default defineEventHandler(event => { + return 'Hello blog/blogMenu.[blogId].delete' + event.context.params.blogId; +}) diff --git a/server/api/blog/blogMenu/[blogId].patch.ts b/server/api/blog/blogMenu/[blogId].patch.ts new file mode 100644 index 0000000..0fc841f --- /dev/null +++ b/server/api/blog/blogMenu/[blogId].patch.ts @@ -0,0 +1,3 @@ +export default defineEventHandler(event => { + return 'Hello blog/blogMenu.[blogId].patch' + event.context.params.blogId; +}) diff --git a/server/api/blog/blogMenu/[blogId].put.ts b/server/api/blog/blogMenu/[blogId].put.ts new file mode 100644 index 0000000..41ca639 --- /dev/null +++ b/server/api/blog/blogMenu/[blogId].put.ts @@ -0,0 +1,3 @@ +export default defineEventHandler(event => { + return 'Hello blog/blogMenu.[blogId].update' + event.context.params.blogId; +}) diff --git a/server/api/blog/blogMenu/index.get.ts b/server/api/blog/blogMenu/index.get.ts new file mode 100644 index 0000000..62b16e8 --- /dev/null +++ b/server/api/blog/blogMenu/index.get.ts @@ -0,0 +1,3 @@ +export default defineEventHandler(event => { + return 'Hello blog/blogMenu.get' +}) diff --git a/server/api/blog/blogMenu/index.post.ts b/server/api/blog/blogMenu/index.post.ts new file mode 100644 index 0000000..4df4c78 --- /dev/null +++ b/server/api/blog/blogMenu/index.post.ts @@ -0,0 +1,3 @@ +export default defineEventHandler(event => { + return 'Hello blog/blogMenu.post' +}) diff --git a/server/api/hello.ts b/server/api/hello.ts index 03ad681..2736958 100644 --- a/server/api/hello.ts +++ b/server/api/hello.ts @@ -1,6 +1,12 @@ +import consola from "consola"; + export default defineEventHandler(async event => { // console.log(await event.context.redis.get('SI HI')) + consola.info('API') + await new Promise(resolve => setTimeout(resolve, 1000)); + consola.info('API TimeOut') + const result = await event.context.redis.get('SI HI'); return { - 'SI HI': await event.context.redis.get('SI HI') + 'SI HI': result } }) diff --git a/server/api/home.ts b/server/api/home.ts new file mode 100644 index 0000000..1205bb0 --- /dev/null +++ b/server/api/home.ts @@ -0,0 +1,12 @@ +import consola from "consola"; + +export default defineEventHandler(async event => { + // console.log(await event.context.redis.get('SI HI')) + consola.info('API') + await new Promise(resolve => setTimeout(resolve, 1000)); + consola.info('API TimeOut') + const result = await event.context.redis.get('SI HI'); + return { + 'HOME': result + } +}) diff --git a/server/middleware/01-logger.ts b/server/middleware/01-logger.ts index 5310421..f8c399f 100644 --- a/server/middleware/01-logger.ts +++ b/server/middleware/01-logger.ts @@ -1,4 +1,5 @@ - -export default defineEventHandler(event => { - +import consola from "consola"; +import dayjs from "dayjs"; +export default defineEventHandler(async event => { + consola.info(dayjs().format('YYYY-MM-DD HH:mm:ss'), event.node.req.method, event.node.req.url); }) diff --git a/server/middleware/02.auth.ts b/server/middleware/02.auth.ts new file mode 100644 index 0000000..8d831b5 --- /dev/null +++ b/server/middleware/02.auth.ts @@ -0,0 +1,29 @@ +import consola from "consola"; +export default defineEventHandler(event => { + // 跳过无需验证的路由 + if (event.path?.startsWith('/api/auth')) return + + const token = getHeader(event, 'Authorization')?.split('Bearer ')[1]; + const t = generateAccessToken({ + name: event.path, + }) + consola.info(`Token ${t}`); + + if (!t) { + throw createError({ + statusCode: 401, + statusMessage: '未提供认证Token' + }) + } + + try { + // 验证JWT(示例使用jsonwebtoken) + const verified = verifyToken(t) // 你的验证逻辑 + event.context.auth = verified // 将用户信息挂载到上下文 + } catch (e) { + throw createError({ + statusCode: 401, + statusMessage: '无效Token' + }) + } +}) diff --git a/server/plugins/mysql.ts b/server/plugins/mysql.ts index 1625659..93f8532 100644 --- a/server/plugins/mysql.ts +++ b/server/plugins/mysql.ts @@ -5,7 +5,7 @@ import type { PoolOptions, Pool} from 'mysql2/promise'; import consola from "consola"; export default defineNitroPlugin(async nitroApp => { - const {server: {mysql: config}} = useRuntimeConfig() + const {mysql: config} = useRuntimeConfig() consola.info('MySQL ...'); // 配置数据库 const poolOptions: PoolOptions = { @@ -48,14 +48,14 @@ export default defineNitroPlugin(async nitroApp => { } } }); - const [result] = await db.execute(sql`SHOW TABLES`); + const result = await db.execute(sql`SHOW TABLES`); const tableList = result.map(row => Object.values(row)[0]); - consola.info('TableList', tableList) + consola.info('TableList', tableList.length) // 将连接池添加到 Nitro 应用上下文 nitroApp.hooks.hook('request', async (event) => { event.context.mysql = db }) nitroApp.hooks.hook('error', async () => { - db.close(); + pool.end(); }) }) diff --git a/server/plugins/redis.ts b/server/plugins/redis.ts index ad34174..bff0a76 100644 --- a/server/plugins/redis.ts +++ b/server/plugins/redis.ts @@ -2,7 +2,7 @@ import { createClient } from 'redis'; import consola from 'consola' export default defineNitroPlugin(async (nitroApp) => { - const {server: {redis: config}} = useRuntimeConfig() + const {redis: config} = useRuntimeConfig() consola.info('Redis ...'); const redisConnect = createClient({ name: config.connectName, diff --git a/server/routes/home.ts b/server/routes/home.ts new file mode 100644 index 0000000..c6e9f7f --- /dev/null +++ b/server/routes/home.ts @@ -0,0 +1,12 @@ +import consola from "consola"; + +export default defineEventHandler(async event => { + // console.log(await event.context.redis.get('SI HI')) + consola.info('API') + await new Promise(resolve => setTimeout(resolve, 1000)); + consola.info('API TimeOut') + const result = await event.context.redis.get('SI HI'); + return { + 'HOME': result + } +}) diff --git a/server/utils/entity.ts b/server/utils/entity.ts new file mode 100644 index 0000000..67d56b8 --- /dev/null +++ b/server/utils/entity.ts @@ -0,0 +1,4 @@ +import * as schema from "../../drizzle/schema"; +export function entity() { + return schema +} diff --git a/server/utils/jwt.ts b/server/utils/jwt.ts new file mode 100644 index 0000000..5da12be --- /dev/null +++ b/server/utils/jwt.ts @@ -0,0 +1,21 @@ +import jwt from 'jsonwebtoken' +import type {StringValue} from "ms"; +const {sign, verify} = jwt +console.log(jwt) +// export function jwt() {} + + +export const generateAccessToken = (payload: object) => { + const {jwt: config} = useRuntimeConfig() + return sign(payload, config.secret, { expiresIn: config.accessExpiresIn as StringValue }) +} + +export const generateRefreshToken = (payload: object) => { + const {jwt: config} = useRuntimeConfig() + return sign(payload, config.secret, { expiresIn: config.refreshExpiresIn as StringValue }) +} + +export const verifyToken = (token: string) => { + const {jwt: config} = useRuntimeConfig() + return verify(token, config.secret) // 返回解码后的payload +} diff --git a/types/nuxt.config.d.ts b/types/nuxt.config.d.ts new file mode 100644 index 0000000..9569a23 --- /dev/null +++ b/types/nuxt.config.d.ts @@ -0,0 +1,11 @@ +// declare module 'nuxt/schema' { +// interface RuntimeConfig { +// // 私有配置(仅服务端) +// jwt: { +// secret: string, +// accessExpiresIn: string, +// refreshExpiresIn: string, +// whitelist: string[] +// }, +// } +// }