test
This commit is contained in:
5
.env.example
Normal file
5
.env.example
Normal file
@@ -0,0 +1,5 @@
|
||||
MONGODB_HOST=light.xiongxiao.me
|
||||
MONGODB_PORT=9997
|
||||
MONGODB_DBNAME=*
|
||||
MONGODB_USERNAME=root
|
||||
MONGODB_PASSWORD=*
|
||||
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
node_modules
|
||||
|
||||
.env
|
||||
!.env*.example
|
||||
89
README.md
Normal file
89
README.md
Normal file
@@ -0,0 +1,89 @@
|
||||
# MongoDB 连接测试项目
|
||||
|
||||
这个项目包含了 MongoDB 数据库连接的配置和测试代码。
|
||||
|
||||
## 配置
|
||||
|
||||
### 1. 修改连接信息
|
||||
|
||||
编辑 `src/connect.ts` 文件中的用户名和密码:
|
||||
|
||||
```typescript
|
||||
const username = 'your_username'; // 替换为您的用户名
|
||||
const password = 'your_password'; // 替换为您的密码
|
||||
```
|
||||
|
||||
### 2. 安装依赖
|
||||
|
||||
```bash
|
||||
pnpm install
|
||||
```
|
||||
|
||||
## 运行测试
|
||||
|
||||
### 方式一:直接运行 TypeScript 文件
|
||||
|
||||
```bash
|
||||
# 测试连接
|
||||
pnpm test
|
||||
|
||||
# 或者
|
||||
pnpm dev
|
||||
```
|
||||
|
||||
### 方式二:编译后运行
|
||||
|
||||
```bash
|
||||
# 编译 TypeScript
|
||||
pnpm build
|
||||
|
||||
# 运行编译后的 JavaScript
|
||||
node dist/connect.js
|
||||
```
|
||||
|
||||
### 方式三:运行示例程序
|
||||
|
||||
```bash
|
||||
# 运行包含数据库操作的示例
|
||||
tsx src/example.ts
|
||||
```
|
||||
|
||||
## 项目结构
|
||||
|
||||
```
|
||||
├── src/
|
||||
│ ├── connect.ts # MongoDB 连接配置和测试函数
|
||||
│ └── example.ts # 使用示例
|
||||
├── package.json # 项目配置
|
||||
├── tsconfig.json # TypeScript 配置
|
||||
└── README.md # 说明文档
|
||||
```
|
||||
|
||||
## 功能说明
|
||||
|
||||
### `connectToDatabase()`
|
||||
- 连接到 MongoDB 数据库
|
||||
- 返回数据库实例用于后续操作
|
||||
|
||||
### `testConnection()`
|
||||
- 测试 MongoDB 连接是否正常
|
||||
- 列出可用的数据库
|
||||
- 返回连接状态(成功/失败)
|
||||
|
||||
## 注意事项
|
||||
|
||||
1. 请确保 MongoDB 服务器正在运行
|
||||
2. 检查网络连接和防火墙设置
|
||||
3. 确认用户名、密码和数据库权限正确
|
||||
4. 如果连接失败,检查服务器地址和端口是否正确
|
||||
|
||||
## 连接字符串格式
|
||||
|
||||
```
|
||||
mongodb://username:password@host:port/?authSource=authDatabase
|
||||
```
|
||||
|
||||
当前配置:
|
||||
- 主机:light.xiongxiao.me
|
||||
- 端口:9997
|
||||
- 认证数据库:admin
|
||||
29
package.json
Normal file
29
package.json
Normal file
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"name": "test_mongo",
|
||||
"version": "0.0.1",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"build": "tsc",
|
||||
"dev": "tsx src/connect.ts",
|
||||
"test": "tsx src/connect.ts",
|
||||
"test-connection": "node test-connection.js",
|
||||
"test-mongoose": "tsx src/mongoose-example.ts",
|
||||
"demo-mongoose": "tsx src/mongoose-demo.ts"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "abearxiong <xiongxiao@xiongxiao.me> (https://www.xiongxiao.me)",
|
||||
"license": "MIT",
|
||||
"packageManager": "pnpm@10.19.0",
|
||||
"type": "module",
|
||||
"dependencies": {
|
||||
"dotenv": "^17.2.3",
|
||||
"mongodb": "^6.20.0",
|
||||
"mongoose": "^8.19.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^24.9.2",
|
||||
"tsx": "^4.20.6",
|
||||
"typescript": "^5.9.3"
|
||||
}
|
||||
}
|
||||
533
pnpm-lock.yaml
generated
Normal file
533
pnpm-lock.yaml
generated
Normal file
@@ -0,0 +1,533 @@
|
||||
lockfileVersion: '9.0'
|
||||
|
||||
settings:
|
||||
autoInstallPeers: true
|
||||
excludeLinksFromLockfile: false
|
||||
|
||||
importers:
|
||||
|
||||
.:
|
||||
dependencies:
|
||||
dotenv:
|
||||
specifier: ^17.2.3
|
||||
version: 17.2.3
|
||||
mongodb:
|
||||
specifier: ^6.20.0
|
||||
version: 6.20.0
|
||||
mongoose:
|
||||
specifier: ^8.19.2
|
||||
version: 8.19.2
|
||||
devDependencies:
|
||||
'@types/node':
|
||||
specifier: ^24.9.2
|
||||
version: 24.9.2
|
||||
tsx:
|
||||
specifier: ^4.20.6
|
||||
version: 4.20.6
|
||||
typescript:
|
||||
specifier: ^5.9.3
|
||||
version: 5.9.3
|
||||
|
||||
packages:
|
||||
|
||||
'@esbuild/aix-ppc64@0.25.11':
|
||||
resolution: {integrity: sha512-Xt1dOL13m8u0WE8iplx9Ibbm+hFAO0GsU2P34UNoDGvZYkY8ifSiy6Zuc1lYxfG7svWE2fzqCUmFp5HCn51gJg==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [ppc64]
|
||||
os: [aix]
|
||||
|
||||
'@esbuild/android-arm64@0.25.11':
|
||||
resolution: {integrity: sha512-9slpyFBc4FPPz48+f6jyiXOx/Y4v34TUeDDXJpZqAWQn/08lKGeD8aDp9TMn9jDz2CiEuHwfhRmGBvpnd/PWIQ==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [arm64]
|
||||
os: [android]
|
||||
|
||||
'@esbuild/android-arm@0.25.11':
|
||||
resolution: {integrity: sha512-uoa7dU+Dt3HYsethkJ1k6Z9YdcHjTrSb5NUy66ZfZaSV8hEYGD5ZHbEMXnqLFlbBflLsl89Zke7CAdDJ4JI+Gg==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [arm]
|
||||
os: [android]
|
||||
|
||||
'@esbuild/android-x64@0.25.11':
|
||||
resolution: {integrity: sha512-Sgiab4xBjPU1QoPEIqS3Xx+R2lezu0LKIEcYe6pftr56PqPygbB7+szVnzoShbx64MUupqoE0KyRlN7gezbl8g==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [x64]
|
||||
os: [android]
|
||||
|
||||
'@esbuild/darwin-arm64@0.25.11':
|
||||
resolution: {integrity: sha512-VekY0PBCukppoQrycFxUqkCojnTQhdec0vevUL/EDOCnXd9LKWqD/bHwMPzigIJXPhC59Vd1WFIL57SKs2mg4w==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [arm64]
|
||||
os: [darwin]
|
||||
|
||||
'@esbuild/darwin-x64@0.25.11':
|
||||
resolution: {integrity: sha512-+hfp3yfBalNEpTGp9loYgbknjR695HkqtY3d3/JjSRUyPg/xd6q+mQqIb5qdywnDxRZykIHs3axEqU6l1+oWEQ==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [x64]
|
||||
os: [darwin]
|
||||
|
||||
'@esbuild/freebsd-arm64@0.25.11':
|
||||
resolution: {integrity: sha512-CmKjrnayyTJF2eVuO//uSjl/K3KsMIeYeyN7FyDBjsR3lnSJHaXlVoAK8DZa7lXWChbuOk7NjAc7ygAwrnPBhA==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [arm64]
|
||||
os: [freebsd]
|
||||
|
||||
'@esbuild/freebsd-x64@0.25.11':
|
||||
resolution: {integrity: sha512-Dyq+5oscTJvMaYPvW3x3FLpi2+gSZTCE/1ffdwuM6G1ARang/mb3jvjxs0mw6n3Lsw84ocfo9CrNMqc5lTfGOw==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [x64]
|
||||
os: [freebsd]
|
||||
|
||||
'@esbuild/linux-arm64@0.25.11':
|
||||
resolution: {integrity: sha512-Qr8AzcplUhGvdyUF08A1kHU3Vr2O88xxP0Tm8GcdVOUm25XYcMPp2YqSVHbLuXzYQMf9Bh/iKx7YPqECs6ffLA==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
|
||||
'@esbuild/linux-arm@0.25.11':
|
||||
resolution: {integrity: sha512-TBMv6B4kCfrGJ8cUPo7vd6NECZH/8hPpBHHlYI3qzoYFvWu2AdTvZNuU/7hsbKWqu/COU7NIK12dHAAqBLLXgw==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [arm]
|
||||
os: [linux]
|
||||
|
||||
'@esbuild/linux-ia32@0.25.11':
|
||||
resolution: {integrity: sha512-TmnJg8BMGPehs5JKrCLqyWTVAvielc615jbkOirATQvWWB1NMXY77oLMzsUjRLa0+ngecEmDGqt5jiDC6bfvOw==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [ia32]
|
||||
os: [linux]
|
||||
|
||||
'@esbuild/linux-loong64@0.25.11':
|
||||
resolution: {integrity: sha512-DIGXL2+gvDaXlaq8xruNXUJdT5tF+SBbJQKbWy/0J7OhU8gOHOzKmGIlfTTl6nHaCOoipxQbuJi7O++ldrxgMw==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [loong64]
|
||||
os: [linux]
|
||||
|
||||
'@esbuild/linux-mips64el@0.25.11':
|
||||
resolution: {integrity: sha512-Osx1nALUJu4pU43o9OyjSCXokFkFbyzjXb6VhGIJZQ5JZi8ylCQ9/LFagolPsHtgw6himDSyb5ETSfmp4rpiKQ==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [mips64el]
|
||||
os: [linux]
|
||||
|
||||
'@esbuild/linux-ppc64@0.25.11':
|
||||
resolution: {integrity: sha512-nbLFgsQQEsBa8XSgSTSlrnBSrpoWh7ioFDUmwo158gIm5NNP+17IYmNWzaIzWmgCxq56vfr34xGkOcZ7jX6CPw==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [ppc64]
|
||||
os: [linux]
|
||||
|
||||
'@esbuild/linux-riscv64@0.25.11':
|
||||
resolution: {integrity: sha512-HfyAmqZi9uBAbgKYP1yGuI7tSREXwIb438q0nqvlpxAOs3XnZ8RsisRfmVsgV486NdjD7Mw2UrFSw51lzUk1ww==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [riscv64]
|
||||
os: [linux]
|
||||
|
||||
'@esbuild/linux-s390x@0.25.11':
|
||||
resolution: {integrity: sha512-HjLqVgSSYnVXRisyfmzsH6mXqyvj0SA7pG5g+9W7ESgwA70AXYNpfKBqh1KbTxmQVaYxpzA/SvlB9oclGPbApw==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [s390x]
|
||||
os: [linux]
|
||||
|
||||
'@esbuild/linux-x64@0.25.11':
|
||||
resolution: {integrity: sha512-HSFAT4+WYjIhrHxKBwGmOOSpphjYkcswF449j6EjsjbinTZbp8PJtjsVK1XFJStdzXdy/jaddAep2FGY+wyFAQ==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
|
||||
'@esbuild/netbsd-arm64@0.25.11':
|
||||
resolution: {integrity: sha512-hr9Oxj1Fa4r04dNpWr3P8QKVVsjQhqrMSUzZzf+LZcYjZNqhA3IAfPQdEh1FLVUJSiu6sgAwp3OmwBfbFgG2Xg==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [arm64]
|
||||
os: [netbsd]
|
||||
|
||||
'@esbuild/netbsd-x64@0.25.11':
|
||||
resolution: {integrity: sha512-u7tKA+qbzBydyj0vgpu+5h5AeudxOAGncb8N6C9Kh1N4n7wU1Xw1JDApsRjpShRpXRQlJLb9wY28ELpwdPcZ7A==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [x64]
|
||||
os: [netbsd]
|
||||
|
||||
'@esbuild/openbsd-arm64@0.25.11':
|
||||
resolution: {integrity: sha512-Qq6YHhayieor3DxFOoYM1q0q1uMFYb7cSpLD2qzDSvK1NAvqFi8Xgivv0cFC6J+hWVw2teCYltyy9/m/14ryHg==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [arm64]
|
||||
os: [openbsd]
|
||||
|
||||
'@esbuild/openbsd-x64@0.25.11':
|
||||
resolution: {integrity: sha512-CN+7c++kkbrckTOz5hrehxWN7uIhFFlmS/hqziSFVWpAzpWrQoAG4chH+nN3Be+Kzv/uuo7zhX716x3Sn2Jduw==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [x64]
|
||||
os: [openbsd]
|
||||
|
||||
'@esbuild/openharmony-arm64@0.25.11':
|
||||
resolution: {integrity: sha512-rOREuNIQgaiR+9QuNkbkxubbp8MSO9rONmwP5nKncnWJ9v5jQ4JxFnLu4zDSRPf3x4u+2VN4pM4RdyIzDty/wQ==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [arm64]
|
||||
os: [openharmony]
|
||||
|
||||
'@esbuild/sunos-x64@0.25.11':
|
||||
resolution: {integrity: sha512-nq2xdYaWxyg9DcIyXkZhcYulC6pQ2FuCgem3LI92IwMgIZ69KHeY8T4Y88pcwoLIjbed8n36CyKoYRDygNSGhA==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [x64]
|
||||
os: [sunos]
|
||||
|
||||
'@esbuild/win32-arm64@0.25.11':
|
||||
resolution: {integrity: sha512-3XxECOWJq1qMZ3MN8srCJ/QfoLpL+VaxD/WfNRm1O3B4+AZ/BnLVgFbUV3eiRYDMXetciH16dwPbbHqwe1uU0Q==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [arm64]
|
||||
os: [win32]
|
||||
|
||||
'@esbuild/win32-ia32@0.25.11':
|
||||
resolution: {integrity: sha512-3ukss6gb9XZ8TlRyJlgLn17ecsK4NSQTmdIXRASVsiS2sQ6zPPZklNJT5GR5tE/MUarymmy8kCEf5xPCNCqVOA==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [ia32]
|
||||
os: [win32]
|
||||
|
||||
'@esbuild/win32-x64@0.25.11':
|
||||
resolution: {integrity: sha512-D7Hpz6A2L4hzsRpPaCYkQnGOotdUpDzSGRIv9I+1ITdHROSFUWW95ZPZWQmGka1Fg7W3zFJowyn9WGwMJ0+KPA==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [x64]
|
||||
os: [win32]
|
||||
|
||||
'@mongodb-js/saslprep@1.3.2':
|
||||
resolution: {integrity: sha512-QgA5AySqB27cGTXBFmnpifAi7HxoGUeezwo6p9dI03MuDB6Pp33zgclqVb6oVK3j6I9Vesg0+oojW2XxB59SGg==}
|
||||
|
||||
'@types/node@24.9.2':
|
||||
resolution: {integrity: sha512-uWN8YqxXxqFMX2RqGOrumsKeti4LlmIMIyV0lgut4jx7KQBcBiW6vkDtIBvHnHIquwNfJhk8v2OtmO8zXWHfPA==}
|
||||
|
||||
'@types/webidl-conversions@7.0.3':
|
||||
resolution: {integrity: sha512-CiJJvcRtIgzadHCYXw7dqEnMNRjhGZlYK05Mj9OyktqV8uVT8fD2BFOB7S1uwBE3Kj2Z+4UyPmFw/Ixgw/LAlA==}
|
||||
|
||||
'@types/whatwg-url@11.0.5':
|
||||
resolution: {integrity: sha512-coYR071JRaHa+xoEvvYqvnIHaVqaYrLPbsufM9BF63HkwI5Lgmy2QR8Q5K/lYDYo5AK82wOvSOS0UsLTpTG7uQ==}
|
||||
|
||||
bson@6.10.4:
|
||||
resolution: {integrity: sha512-WIsKqkSC0ABoBJuT1LEX+2HEvNmNKKgnTAyd0fL8qzK4SH2i9NXg+t08YtdZp/V9IZ33cxe3iV4yM0qg8lMQng==}
|
||||
engines: {node: '>=16.20.1'}
|
||||
|
||||
debug@4.4.3:
|
||||
resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==}
|
||||
engines: {node: '>=6.0'}
|
||||
peerDependencies:
|
||||
supports-color: '*'
|
||||
peerDependenciesMeta:
|
||||
supports-color:
|
||||
optional: true
|
||||
|
||||
dotenv@17.2.3:
|
||||
resolution: {integrity: sha512-JVUnt+DUIzu87TABbhPmNfVdBDt18BLOWjMUFJMSi/Qqg7NTYtabbvSNJGOJ7afbRuv9D/lngizHtP7QyLQ+9w==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
esbuild@0.25.11:
|
||||
resolution: {integrity: sha512-KohQwyzrKTQmhXDW1PjCv3Tyspn9n5GcY2RTDqeORIdIJY8yKIF7sTSopFmn/wpMPW4rdPXI0UE5LJLuq3bx0Q==}
|
||||
engines: {node: '>=18'}
|
||||
hasBin: true
|
||||
|
||||
fsevents@2.3.3:
|
||||
resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==}
|
||||
engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
|
||||
os: [darwin]
|
||||
|
||||
get-tsconfig@4.13.0:
|
||||
resolution: {integrity: sha512-1VKTZJCwBrvbd+Wn3AOgQP/2Av+TfTCOlE4AcRJE72W1ksZXbAx8PPBR9RzgTeSPzlPMHrbANMH3LbltH73wxQ==}
|
||||
|
||||
kareem@2.6.3:
|
||||
resolution: {integrity: sha512-C3iHfuGUXK2u8/ipq9LfjFfXFxAZMQJJq7vLS45r3D9Y2xQ/m4S8zaR4zMLFWh9AsNPXmcFfUDhTEO8UIC/V6Q==}
|
||||
engines: {node: '>=12.0.0'}
|
||||
|
||||
memory-pager@1.5.0:
|
||||
resolution: {integrity: sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==}
|
||||
|
||||
mongodb-connection-string-url@3.0.2:
|
||||
resolution: {integrity: sha512-rMO7CGo/9BFwyZABcKAWL8UJwH/Kc2x0g72uhDWzG48URRax5TCIcJ7Rc3RZqffZzO/Gwff/jyKwCU9TN8gehA==}
|
||||
|
||||
mongodb@6.20.0:
|
||||
resolution: {integrity: sha512-Tl6MEIU3K4Rq3TSHd+sZQqRBoGlFsOgNrH5ltAcFBV62Re3Fd+FcaVf8uSEQFOJ51SDowDVttBTONMfoYWrWlQ==}
|
||||
engines: {node: '>=16.20.1'}
|
||||
peerDependencies:
|
||||
'@aws-sdk/credential-providers': ^3.188.0
|
||||
'@mongodb-js/zstd': ^1.1.0 || ^2.0.0
|
||||
gcp-metadata: ^5.2.0
|
||||
kerberos: ^2.0.1
|
||||
mongodb-client-encryption: '>=6.0.0 <7'
|
||||
snappy: ^7.3.2
|
||||
socks: ^2.7.1
|
||||
peerDependenciesMeta:
|
||||
'@aws-sdk/credential-providers':
|
||||
optional: true
|
||||
'@mongodb-js/zstd':
|
||||
optional: true
|
||||
gcp-metadata:
|
||||
optional: true
|
||||
kerberos:
|
||||
optional: true
|
||||
mongodb-client-encryption:
|
||||
optional: true
|
||||
snappy:
|
||||
optional: true
|
||||
socks:
|
||||
optional: true
|
||||
|
||||
mongoose@8.19.2:
|
||||
resolution: {integrity: sha512-ww2T4dBV+suCbOfG5YPwj9pLCfUVyj8FEA1D3Ux1HHqutpLxGyOYEPU06iPRBW4cKr3PJfOSYsIpHWPTkz5zig==}
|
||||
engines: {node: '>=16.20.1'}
|
||||
|
||||
mpath@0.9.0:
|
||||
resolution: {integrity: sha512-ikJRQTk8hw5DEoFVxHG1Gn9T/xcjtdnOKIU1JTmGjZZlg9LST2mBLmcX3/ICIbgJydT2GOc15RnNy5mHmzfSew==}
|
||||
engines: {node: '>=4.0.0'}
|
||||
|
||||
mquery@5.0.0:
|
||||
resolution: {integrity: sha512-iQMncpmEK8R8ncT8HJGsGc9Dsp8xcgYMVSbs5jgnm1lFHTZqMJTUWTDx1LBO8+mK3tPNZWFLBghQEIOULSTHZg==}
|
||||
engines: {node: '>=14.0.0'}
|
||||
|
||||
ms@2.1.3:
|
||||
resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
|
||||
|
||||
punycode@2.3.1:
|
||||
resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==}
|
||||
engines: {node: '>=6'}
|
||||
|
||||
resolve-pkg-maps@1.0.0:
|
||||
resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==}
|
||||
|
||||
sift@17.1.3:
|
||||
resolution: {integrity: sha512-Rtlj66/b0ICeFzYTuNvX/EF1igRbbnGSvEyT79McoZa/DeGhMyC5pWKOEsZKnpkqtSeovd5FL/bjHWC3CIIvCQ==}
|
||||
|
||||
sparse-bitfield@3.0.3:
|
||||
resolution: {integrity: sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ==}
|
||||
|
||||
tr46@5.1.1:
|
||||
resolution: {integrity: sha512-hdF5ZgjTqgAntKkklYw0R03MG2x/bSzTtkxmIRw/sTNV8YXsCJ1tfLAX23lhxhHJlEf3CRCOCGGWw3vI3GaSPw==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
tsx@4.20.6:
|
||||
resolution: {integrity: sha512-ytQKuwgmrrkDTFP4LjR0ToE2nqgy886GpvRSpU0JAnrdBYppuY5rLkRUYPU1yCryb24SsKBTL/hlDQAEFVwtZg==}
|
||||
engines: {node: '>=18.0.0'}
|
||||
hasBin: true
|
||||
|
||||
typescript@5.9.3:
|
||||
resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==}
|
||||
engines: {node: '>=14.17'}
|
||||
hasBin: true
|
||||
|
||||
undici-types@7.16.0:
|
||||
resolution: {integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==}
|
||||
|
||||
webidl-conversions@7.0.0:
|
||||
resolution: {integrity: sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
whatwg-url@14.2.0:
|
||||
resolution: {integrity: sha512-De72GdQZzNTUBBChsXueQUnPKDkg/5A5zp7pFDuQAj5UFoENpiACU0wlCvzpAGnTkj++ihpKwKyYewn/XNUbKw==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
snapshots:
|
||||
|
||||
'@esbuild/aix-ppc64@0.25.11':
|
||||
optional: true
|
||||
|
||||
'@esbuild/android-arm64@0.25.11':
|
||||
optional: true
|
||||
|
||||
'@esbuild/android-arm@0.25.11':
|
||||
optional: true
|
||||
|
||||
'@esbuild/android-x64@0.25.11':
|
||||
optional: true
|
||||
|
||||
'@esbuild/darwin-arm64@0.25.11':
|
||||
optional: true
|
||||
|
||||
'@esbuild/darwin-x64@0.25.11':
|
||||
optional: true
|
||||
|
||||
'@esbuild/freebsd-arm64@0.25.11':
|
||||
optional: true
|
||||
|
||||
'@esbuild/freebsd-x64@0.25.11':
|
||||
optional: true
|
||||
|
||||
'@esbuild/linux-arm64@0.25.11':
|
||||
optional: true
|
||||
|
||||
'@esbuild/linux-arm@0.25.11':
|
||||
optional: true
|
||||
|
||||
'@esbuild/linux-ia32@0.25.11':
|
||||
optional: true
|
||||
|
||||
'@esbuild/linux-loong64@0.25.11':
|
||||
optional: true
|
||||
|
||||
'@esbuild/linux-mips64el@0.25.11':
|
||||
optional: true
|
||||
|
||||
'@esbuild/linux-ppc64@0.25.11':
|
||||
optional: true
|
||||
|
||||
'@esbuild/linux-riscv64@0.25.11':
|
||||
optional: true
|
||||
|
||||
'@esbuild/linux-s390x@0.25.11':
|
||||
optional: true
|
||||
|
||||
'@esbuild/linux-x64@0.25.11':
|
||||
optional: true
|
||||
|
||||
'@esbuild/netbsd-arm64@0.25.11':
|
||||
optional: true
|
||||
|
||||
'@esbuild/netbsd-x64@0.25.11':
|
||||
optional: true
|
||||
|
||||
'@esbuild/openbsd-arm64@0.25.11':
|
||||
optional: true
|
||||
|
||||
'@esbuild/openbsd-x64@0.25.11':
|
||||
optional: true
|
||||
|
||||
'@esbuild/openharmony-arm64@0.25.11':
|
||||
optional: true
|
||||
|
||||
'@esbuild/sunos-x64@0.25.11':
|
||||
optional: true
|
||||
|
||||
'@esbuild/win32-arm64@0.25.11':
|
||||
optional: true
|
||||
|
||||
'@esbuild/win32-ia32@0.25.11':
|
||||
optional: true
|
||||
|
||||
'@esbuild/win32-x64@0.25.11':
|
||||
optional: true
|
||||
|
||||
'@mongodb-js/saslprep@1.3.2':
|
||||
dependencies:
|
||||
sparse-bitfield: 3.0.3
|
||||
|
||||
'@types/node@24.9.2':
|
||||
dependencies:
|
||||
undici-types: 7.16.0
|
||||
|
||||
'@types/webidl-conversions@7.0.3': {}
|
||||
|
||||
'@types/whatwg-url@11.0.5':
|
||||
dependencies:
|
||||
'@types/webidl-conversions': 7.0.3
|
||||
|
||||
bson@6.10.4: {}
|
||||
|
||||
debug@4.4.3:
|
||||
dependencies:
|
||||
ms: 2.1.3
|
||||
|
||||
dotenv@17.2.3: {}
|
||||
|
||||
esbuild@0.25.11:
|
||||
optionalDependencies:
|
||||
'@esbuild/aix-ppc64': 0.25.11
|
||||
'@esbuild/android-arm': 0.25.11
|
||||
'@esbuild/android-arm64': 0.25.11
|
||||
'@esbuild/android-x64': 0.25.11
|
||||
'@esbuild/darwin-arm64': 0.25.11
|
||||
'@esbuild/darwin-x64': 0.25.11
|
||||
'@esbuild/freebsd-arm64': 0.25.11
|
||||
'@esbuild/freebsd-x64': 0.25.11
|
||||
'@esbuild/linux-arm': 0.25.11
|
||||
'@esbuild/linux-arm64': 0.25.11
|
||||
'@esbuild/linux-ia32': 0.25.11
|
||||
'@esbuild/linux-loong64': 0.25.11
|
||||
'@esbuild/linux-mips64el': 0.25.11
|
||||
'@esbuild/linux-ppc64': 0.25.11
|
||||
'@esbuild/linux-riscv64': 0.25.11
|
||||
'@esbuild/linux-s390x': 0.25.11
|
||||
'@esbuild/linux-x64': 0.25.11
|
||||
'@esbuild/netbsd-arm64': 0.25.11
|
||||
'@esbuild/netbsd-x64': 0.25.11
|
||||
'@esbuild/openbsd-arm64': 0.25.11
|
||||
'@esbuild/openbsd-x64': 0.25.11
|
||||
'@esbuild/openharmony-arm64': 0.25.11
|
||||
'@esbuild/sunos-x64': 0.25.11
|
||||
'@esbuild/win32-arm64': 0.25.11
|
||||
'@esbuild/win32-ia32': 0.25.11
|
||||
'@esbuild/win32-x64': 0.25.11
|
||||
|
||||
fsevents@2.3.3:
|
||||
optional: true
|
||||
|
||||
get-tsconfig@4.13.0:
|
||||
dependencies:
|
||||
resolve-pkg-maps: 1.0.0
|
||||
|
||||
kareem@2.6.3: {}
|
||||
|
||||
memory-pager@1.5.0: {}
|
||||
|
||||
mongodb-connection-string-url@3.0.2:
|
||||
dependencies:
|
||||
'@types/whatwg-url': 11.0.5
|
||||
whatwg-url: 14.2.0
|
||||
|
||||
mongodb@6.20.0:
|
||||
dependencies:
|
||||
'@mongodb-js/saslprep': 1.3.2
|
||||
bson: 6.10.4
|
||||
mongodb-connection-string-url: 3.0.2
|
||||
|
||||
mongoose@8.19.2:
|
||||
dependencies:
|
||||
bson: 6.10.4
|
||||
kareem: 2.6.3
|
||||
mongodb: 6.20.0
|
||||
mpath: 0.9.0
|
||||
mquery: 5.0.0
|
||||
ms: 2.1.3
|
||||
sift: 17.1.3
|
||||
transitivePeerDependencies:
|
||||
- '@aws-sdk/credential-providers'
|
||||
- '@mongodb-js/zstd'
|
||||
- gcp-metadata
|
||||
- kerberos
|
||||
- mongodb-client-encryption
|
||||
- snappy
|
||||
- socks
|
||||
- supports-color
|
||||
|
||||
mpath@0.9.0: {}
|
||||
|
||||
mquery@5.0.0:
|
||||
dependencies:
|
||||
debug: 4.4.3
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
ms@2.1.3: {}
|
||||
|
||||
punycode@2.3.1: {}
|
||||
|
||||
resolve-pkg-maps@1.0.0: {}
|
||||
|
||||
sift@17.1.3: {}
|
||||
|
||||
sparse-bitfield@3.0.3:
|
||||
dependencies:
|
||||
memory-pager: 1.5.0
|
||||
|
||||
tr46@5.1.1:
|
||||
dependencies:
|
||||
punycode: 2.3.1
|
||||
|
||||
tsx@4.20.6:
|
||||
dependencies:
|
||||
esbuild: 0.25.11
|
||||
get-tsconfig: 4.13.0
|
||||
optionalDependencies:
|
||||
fsevents: 2.3.3
|
||||
|
||||
typescript@5.9.3: {}
|
||||
|
||||
undici-types@7.16.0: {}
|
||||
|
||||
webidl-conversions@7.0.0: {}
|
||||
|
||||
whatwg-url@14.2.0:
|
||||
dependencies:
|
||||
tr46: 5.1.1
|
||||
webidl-conversions: 7.0.0
|
||||
105
src/connect.ts
Normal file
105
src/connect.ts
Normal file
@@ -0,0 +1,105 @@
|
||||
import { MongoClient } from 'mongodb';
|
||||
import mongoose from 'mongoose';
|
||||
import dotenv from 'dotenv';
|
||||
dotenv.config();
|
||||
// MongoDB 连接配置
|
||||
const username = process.env.MONGODB_USERNAME; // 替换为您的用户名
|
||||
const password = process.env.MONGODB_PASSWORD; // 替换为您的密码
|
||||
const host = process.env.MONGODB_HOST; // 替换为您的主机
|
||||
const port = process.env.MONGODB_PORT; // 替换为您的端口
|
||||
const dbName = process.env.MONGODB_DBNAME; // 替换为您的数据库名
|
||||
const authSource = 'admin'; // 认证数据库,通常是 admin
|
||||
|
||||
const uri = `mongodb://${username}:${password}@${host}:${port}/?authSource=${authSource}`;
|
||||
|
||||
const client = new MongoClient(uri, {
|
||||
dbName: dbName,
|
||||
maxPoolSize: 10, // 连接池最大连接数
|
||||
serverSelectionTimeoutMS: 5000, // 服务器选择超时时间
|
||||
socketTimeoutMS: 45000, // Socket 超时时间
|
||||
} as any); // 临时解决类型问题
|
||||
|
||||
export async function connectToDatabase() {
|
||||
try {
|
||||
await client.connect();
|
||||
console.log('Connected to MongoDB');
|
||||
return client.db('test'); // Replace 'test' with your database name
|
||||
} catch (error) {
|
||||
console.error('Error connecting to MongoDB:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
// 测试连接函数
|
||||
export async function testConnection() {
|
||||
try {
|
||||
console.log('正在测试 MongoDB 连接...');
|
||||
await client.connect();
|
||||
|
||||
// 测试数据库连接
|
||||
const adminDb = client.db().admin();
|
||||
const result = await adminDb.ping();
|
||||
console.log('MongoDB 连接测试成功!', result);
|
||||
|
||||
// 列出可用的数据库
|
||||
const dbs = await adminDb.listDatabases();
|
||||
console.log('可用的数据库:', dbs.databases.map(db => db.name));
|
||||
|
||||
return true;
|
||||
} catch (error) {
|
||||
console.error('MongoDB 连接测试失败:', error);
|
||||
return false;
|
||||
} finally {
|
||||
await client.close();
|
||||
}
|
||||
}
|
||||
|
||||
// 主函数 - 用于直接运行测试
|
||||
export async function main() {
|
||||
const success = await testConnection();
|
||||
if (success) {
|
||||
console.log('✅ 数据库连接测试通过');
|
||||
process.exit(0);
|
||||
} else {
|
||||
console.log('❌ 数据库连接测试失败');
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
// 检查是否直接运行此文件
|
||||
if (import.meta.url === `file://${process.argv[1]}`) {
|
||||
main().catch((error) => {
|
||||
console.error('测试过程中发生错误:', error);
|
||||
process.exit(1);
|
||||
});
|
||||
}
|
||||
|
||||
// Mongoose 连接函数
|
||||
export async function connectMongoose() {
|
||||
try {
|
||||
const mongooseUri = `mongodb://${username}:${password}@${host}:${port}/${dbName}?authSource=${authSource}`;
|
||||
|
||||
await mongoose.connect(mongooseUri, {
|
||||
maxPoolSize: 10,
|
||||
serverSelectionTimeoutMS: 5000,
|
||||
socketTimeoutMS: 45000,
|
||||
} as any);
|
||||
|
||||
console.log('Connected to MongoDB via Mongoose');
|
||||
return mongoose.connection;
|
||||
} catch (error) {
|
||||
console.error('Error connecting to MongoDB via Mongoose:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
// 断开 Mongoose 连接
|
||||
export async function disconnectMongoose() {
|
||||
try {
|
||||
await mongoose.disconnect();
|
||||
console.log('Disconnected from MongoDB via Mongoose');
|
||||
} catch (error) {
|
||||
console.error('Error disconnecting from MongoDB via Mongoose:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
129
src/example.ts
Normal file
129
src/example.ts
Normal file
@@ -0,0 +1,129 @@
|
||||
import { connectToDatabase, testConnection } from './connect.js';
|
||||
import { testAModel, TestADocument } from './models/test.js';
|
||||
|
||||
// 创建示例数据
|
||||
async function createSampleData() {
|
||||
console.log('=== 创建示例数据 ===');
|
||||
|
||||
const sampleData = [
|
||||
{
|
||||
title: '学习TypeScript',
|
||||
description: '学习TypeScript的基础语法和高级特性,掌握类型系统的使用方法。'
|
||||
},
|
||||
{
|
||||
title: 'MongoDB数据库设计',
|
||||
description: '设计MongoDB的集合结构,了解文档数据库的特点和最佳实践。'
|
||||
},
|
||||
{
|
||||
title: 'Node.js后端开发',
|
||||
description: '使用Node.js开发后端API,集成MongoDB数据库进行数据操作。'
|
||||
},
|
||||
{
|
||||
title: '前端项目优化',
|
||||
description: '优化前端项目性能,包括代码分割、懒加载和缓存策略。'
|
||||
},
|
||||
{
|
||||
title: 'DevOps自动化部署',
|
||||
description: '建立CI/CD流水线,实现项目的自动化测试和部署。'
|
||||
}
|
||||
];
|
||||
|
||||
const createdDocuments: TestADocument[] = [];
|
||||
|
||||
for (const data of sampleData) {
|
||||
try {
|
||||
const doc = await testAModel.create(data);
|
||||
createdDocuments.push(doc);
|
||||
console.log(`✅ 创建文档: ${doc.title}`);
|
||||
} catch (error) {
|
||||
console.error(`❌ 创建文档失败: ${data.title}`, error);
|
||||
}
|
||||
}
|
||||
|
||||
return createdDocuments;
|
||||
}
|
||||
|
||||
// 演示所有操作
|
||||
async function demonstrateOperations() {
|
||||
console.log('\n=== 演示 TestA 表操作 ===');
|
||||
|
||||
// 查询所有数据
|
||||
console.log('\n--- 查询所有数据 ---');
|
||||
const allDocs = await testAModel.findAll();
|
||||
console.log(`总共找到 ${allDocs.length} 条记录:`);
|
||||
allDocs.forEach((doc, index) => {
|
||||
console.log(`${index + 1}. ${doc.title}: ${doc.description}`);
|
||||
});
|
||||
|
||||
if (allDocs.length > 0) {
|
||||
// 根据ID查询
|
||||
console.log('\n--- 根据ID查询 ---');
|
||||
const firstDoc = await testAModel.findById(allDocs[0]._id!);
|
||||
if (firstDoc) {
|
||||
console.log(`找到文档: ${firstDoc.title}`);
|
||||
}
|
||||
|
||||
// 根据标题搜索
|
||||
console.log('\n--- 根据标题搜索 ---');
|
||||
const searchResults = await testAModel.findByTitle('TypeScript');
|
||||
console.log(`搜索 "TypeScript" 找到 ${searchResults.length} 条记录:`);
|
||||
searchResults.forEach(doc => {
|
||||
console.log(`- ${doc.title}`);
|
||||
});
|
||||
|
||||
// 更新文档
|
||||
console.log('\n--- 更新文档 ---');
|
||||
const updated = await testAModel.updateById(allDocs[0]._id!, {
|
||||
description: allDocs[0].description + ' [已更新]'
|
||||
});
|
||||
if (updated) {
|
||||
console.log(`✅ 更新成功: ${updated.title}`);
|
||||
}
|
||||
}
|
||||
|
||||
// 统计记录数
|
||||
console.log('\n--- 统计信息 ---');
|
||||
const count = await testAModel.count();
|
||||
console.log(`数据库中共有 ${count} 条 TestA 记录`);
|
||||
}
|
||||
|
||||
// 使用示例
|
||||
async function example() {
|
||||
try {
|
||||
// 1. 测试连接
|
||||
console.log('=== 测试连接 ===');
|
||||
const isConnected = await testConnection();
|
||||
|
||||
if (!isConnected) {
|
||||
console.log('连接失败,退出程序');
|
||||
return;
|
||||
}
|
||||
|
||||
// 2. 初始化 TestA 模型
|
||||
console.log('\n=== 初始化 TestA 模型 ===');
|
||||
await testAModel.initialize();
|
||||
console.log('TestA 模型初始化成功');
|
||||
|
||||
// 3. 清空现有数据(可选)
|
||||
const existingCount = await testAModel.count();
|
||||
if (existingCount > 0) {
|
||||
console.log(`\n发现 ${existingCount} 条现有记录,是否清空?`);
|
||||
await testAModel.deleteAll();
|
||||
console.log('已清空现有数据');
|
||||
}
|
||||
|
||||
// 4. 创建示例数据
|
||||
await createSampleData();
|
||||
|
||||
// 5. 演示各种操作
|
||||
await demonstrateOperations();
|
||||
|
||||
} catch (error) {
|
||||
console.error('操作失败:', error);
|
||||
}
|
||||
}
|
||||
|
||||
// 运行示例
|
||||
if (import.meta.url === `file://${process.argv[1]}`) {
|
||||
example().catch(console.error);
|
||||
}
|
||||
216
src/models/test-mongoose.ts
Normal file
216
src/models/test-mongoose.ts
Normal file
@@ -0,0 +1,216 @@
|
||||
import mongoose, { Schema, Document, Model } from 'mongoose';
|
||||
|
||||
// TestA 文档接口(继承 mongoose Document)
|
||||
export interface ITestA extends Document {
|
||||
_id: mongoose.Types.ObjectId;
|
||||
title: string;
|
||||
description: string;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
}
|
||||
|
||||
// TestA Schema 定义
|
||||
const testASchema: Schema<ITestA> = new Schema(
|
||||
{
|
||||
title: {
|
||||
type: String,
|
||||
required: [true, 'Title is required'],
|
||||
trim: true,
|
||||
maxlength: [100, 'Title cannot be more than 100 characters']
|
||||
},
|
||||
description: {
|
||||
type: String,
|
||||
required: [true, 'Description is required'],
|
||||
trim: true,
|
||||
maxlength: [500, 'Description cannot be more than 500 characters']
|
||||
}
|
||||
},
|
||||
{
|
||||
timestamps: true, // 自动添加 createdAt 和 updatedAt
|
||||
collection: 'test_a' // 指定集合名称
|
||||
}
|
||||
);
|
||||
|
||||
// 添加索引
|
||||
testASchema.index({ title: 1 });
|
||||
testASchema.index({ createdAt: -1 });
|
||||
|
||||
// 添加实例方法
|
||||
testASchema.methods.toJSON = function() {
|
||||
const obj = this.toObject();
|
||||
obj.id = obj._id;
|
||||
delete obj._id;
|
||||
delete obj.__v;
|
||||
return obj;
|
||||
};
|
||||
|
||||
// 添加静态方法
|
||||
testASchema.statics.findByTitle = function(title: string) {
|
||||
return this.find({ title: { $regex: title, $options: 'i' } });
|
||||
};
|
||||
|
||||
// 创建并导出模型
|
||||
export const TestAModel: Model<ITestA> = mongoose.model<ITestA>('TestA', testASchema);
|
||||
|
||||
// TestA 服务类 - 封装常用操作
|
||||
export class TestAService {
|
||||
|
||||
// 创建新的 TestA 记录
|
||||
static async create(data: Pick<ITestA, 'title' | 'description'>): Promise<ITestA> {
|
||||
try {
|
||||
const testA = new TestAModel(data);
|
||||
return await testA.save();
|
||||
} catch (error) {
|
||||
console.error('Error creating TestA:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
// 查找所有 TestA 记录
|
||||
static async findAll(limit: number = 50, skip: number = 0): Promise<ITestA[]> {
|
||||
try {
|
||||
return await TestAModel
|
||||
.find({})
|
||||
.sort({ createdAt: -1 })
|
||||
.limit(limit)
|
||||
.skip(skip)
|
||||
.exec();
|
||||
} catch (error) {
|
||||
console.error('Error finding all TestA:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
// 根据 ID 查找 TestA 记录
|
||||
static async findById(id: string): Promise<ITestA | null> {
|
||||
try {
|
||||
if (!mongoose.Types.ObjectId.isValid(id)) {
|
||||
throw new Error('Invalid ObjectId');
|
||||
}
|
||||
return await TestAModel.findById(id).exec();
|
||||
} catch (error) {
|
||||
console.error('Error finding TestA by ID:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
// 根据标题查找 TestA 记录
|
||||
static async findByTitle(title: string): Promise<ITestA[]> {
|
||||
try {
|
||||
return await (TestAModel as any).findByTitle(title);
|
||||
} catch (error) {
|
||||
console.error('Error finding TestA by title:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
// 更新 TestA 记录
|
||||
static async updateById(
|
||||
id: string,
|
||||
updateData: Partial<Pick<ITestA, 'title' | 'description'>>
|
||||
): Promise<ITestA | null> {
|
||||
try {
|
||||
if (!mongoose.Types.ObjectId.isValid(id)) {
|
||||
throw new Error('Invalid ObjectId');
|
||||
}
|
||||
|
||||
return await TestAModel.findByIdAndUpdate(
|
||||
id,
|
||||
{ $set: updateData },
|
||||
{
|
||||
new: true, // 返回更新后的文档
|
||||
runValidators: true // 运行验证器
|
||||
}
|
||||
).exec();
|
||||
} catch (error) {
|
||||
console.error('Error updating TestA:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
// 删除 TestA 记录
|
||||
static async deleteById(id: string): Promise<boolean> {
|
||||
try {
|
||||
if (!mongoose.Types.ObjectId.isValid(id)) {
|
||||
throw new Error('Invalid ObjectId');
|
||||
}
|
||||
|
||||
const result = await TestAModel.findByIdAndDelete(id).exec();
|
||||
return !!result;
|
||||
} catch (error) {
|
||||
console.error('Error deleting TestA:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
// 删除所有 TestA 记录
|
||||
static async deleteAll(): Promise<number> {
|
||||
try {
|
||||
const result = await TestAModel.deleteMany({}).exec();
|
||||
return result.deletedCount || 0;
|
||||
} catch (error) {
|
||||
console.error('Error deleting all TestA:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
// 统计 TestA 记录总数
|
||||
static async count(): Promise<number> {
|
||||
try {
|
||||
return await TestAModel.countDocuments().exec();
|
||||
} catch (error) {
|
||||
console.error('Error counting TestA:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
// 搜索 TestA 记录(标题或描述包含关键词)
|
||||
static async search(keyword: string, limit: number = 20): Promise<ITestA[]> {
|
||||
try {
|
||||
const regex = new RegExp(keyword, 'i');
|
||||
return await TestAModel
|
||||
.find({
|
||||
$or: [
|
||||
{ title: { $regex: regex } },
|
||||
{ description: { $regex: regex } }
|
||||
]
|
||||
})
|
||||
.sort({ createdAt: -1 })
|
||||
.limit(limit)
|
||||
.exec();
|
||||
} catch (error) {
|
||||
console.error('Error searching TestA:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
// 分页查询
|
||||
static async paginate(page: number = 1, limit: number = 10) {
|
||||
try {
|
||||
const skip = (page - 1) * limit;
|
||||
const [items, total] = await Promise.all([
|
||||
TestAModel.find({})
|
||||
.sort({ createdAt: -1 })
|
||||
.limit(limit)
|
||||
.skip(skip)
|
||||
.exec(),
|
||||
TestAModel.countDocuments().exec()
|
||||
]);
|
||||
|
||||
return {
|
||||
items,
|
||||
total,
|
||||
page,
|
||||
limit,
|
||||
pages: Math.ceil(total / limit),
|
||||
hasNext: page * limit < total,
|
||||
hasPrev: page > 1
|
||||
};
|
||||
} catch (error) {
|
||||
console.error('Error paginating TestA:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default TestAService;
|
||||
116
src/models/test.ts
Normal file
116
src/models/test.ts
Normal file
@@ -0,0 +1,116 @@
|
||||
import { MongoClient, Db, Collection, ObjectId } from 'mongodb';
|
||||
import { connectToDatabase } from '../connect.js';
|
||||
|
||||
// TestA 数据模型接口
|
||||
export interface TestADocument {
|
||||
_id?: ObjectId;
|
||||
title: string;
|
||||
description: string;
|
||||
createdAt?: Date;
|
||||
updatedAt?: Date;
|
||||
}
|
||||
|
||||
// TestA 集合操作类
|
||||
export class TestAModel {
|
||||
private db: Db | null = null;
|
||||
private collection: Collection<TestADocument> | null = null;
|
||||
|
||||
constructor() {}
|
||||
|
||||
// 初始化数据库连接
|
||||
async initialize(): Promise<void> {
|
||||
this.db = await connectToDatabase();
|
||||
this.collection = this.db.collection<TestADocument>('test_a');
|
||||
}
|
||||
|
||||
// 确保集合已初始化
|
||||
private ensureInitialized(): void {
|
||||
if (!this.collection) {
|
||||
throw new Error('TestA model not initialized. Call initialize() first.');
|
||||
}
|
||||
}
|
||||
|
||||
// 创建新的 TestA 记录
|
||||
async create(data: Omit<TestADocument, '_id' | 'createdAt' | 'updatedAt'>): Promise<TestADocument> {
|
||||
this.ensureInitialized();
|
||||
|
||||
const now = new Date();
|
||||
const document: TestADocument = {
|
||||
...data,
|
||||
createdAt: now,
|
||||
updatedAt: now
|
||||
};
|
||||
|
||||
const result = await this.collection!.insertOne(document);
|
||||
return {
|
||||
...document,
|
||||
_id: result.insertedId
|
||||
};
|
||||
}
|
||||
|
||||
// 查找所有 TestA 记录
|
||||
async findAll(): Promise<TestADocument[]> {
|
||||
this.ensureInitialized();
|
||||
return await this.collection!.find({}).toArray();
|
||||
}
|
||||
|
||||
// 根据 ID 查找 TestA 记录
|
||||
async findById(id: string | ObjectId): Promise<TestADocument | null> {
|
||||
this.ensureInitialized();
|
||||
const objectId = typeof id === 'string' ? new ObjectId(id) : id;
|
||||
return await this.collection!.findOne({ _id: objectId });
|
||||
}
|
||||
|
||||
// 根据标题查找 TestA 记录
|
||||
async findByTitle(title: string): Promise<TestADocument[]> {
|
||||
this.ensureInitialized();
|
||||
return await this.collection!.find({ title: { $regex: title, $options: 'i' } }).toArray();
|
||||
}
|
||||
|
||||
// 更新 TestA 记录
|
||||
async updateById(
|
||||
id: string | ObjectId,
|
||||
updateData: Partial<Omit<TestADocument, '_id' | 'createdAt'>>
|
||||
): Promise<TestADocument | null> {
|
||||
this.ensureInitialized();
|
||||
|
||||
const objectId = typeof id === 'string' ? new ObjectId(id) : id;
|
||||
const updateDoc = {
|
||||
...updateData,
|
||||
updatedAt: new Date()
|
||||
};
|
||||
|
||||
const result = await this.collection!.findOneAndUpdate(
|
||||
{ _id: objectId },
|
||||
{ $set: updateDoc },
|
||||
{ returnDocument: 'after' }
|
||||
);
|
||||
|
||||
return result || null;
|
||||
}
|
||||
|
||||
// 删除 TestA 记录
|
||||
async deleteById(id: string | ObjectId): Promise<boolean> {
|
||||
this.ensureInitialized();
|
||||
|
||||
const objectId = typeof id === 'string' ? new ObjectId(id) : id;
|
||||
const result = await this.collection!.deleteOne({ _id: objectId });
|
||||
return result.deletedCount > 0;
|
||||
}
|
||||
|
||||
// 删除所有 TestA 记录
|
||||
async deleteAll(): Promise<number> {
|
||||
this.ensureInitialized();
|
||||
const result = await this.collection!.deleteMany({});
|
||||
return result.deletedCount;
|
||||
}
|
||||
|
||||
// 统计 TestA 记录总数
|
||||
async count(): Promise<number> {
|
||||
this.ensureInitialized();
|
||||
return await this.collection!.countDocuments();
|
||||
}
|
||||
}
|
||||
|
||||
// 导出单例实例
|
||||
export const testAModel = new TestAModel();
|
||||
106
src/mongoose-demo.ts
Normal file
106
src/mongoose-demo.ts
Normal file
@@ -0,0 +1,106 @@
|
||||
import mongoose from 'mongoose';
|
||||
import TestAService, { TestAModel, ITestA } from './models/test-mongoose.js';
|
||||
|
||||
// 简单的 Mongoose 模型使用演示(不需要实际数据库连接)
|
||||
async function demonstrateModelDefinition() {
|
||||
console.log('🚀 Mongoose TestA 模型定义演示\n');
|
||||
console.log('=' .repeat(50));
|
||||
|
||||
// 1. 显示模型信息
|
||||
console.log('📋 TestA 模型信息:');
|
||||
console.log(' - 模型名称:', TestAModel.modelName);
|
||||
console.log(' - 集合名称:', TestAModel.collection.name);
|
||||
|
||||
// 2. 显示 Schema 字段
|
||||
console.log('\n📝 Schema 字段定义:');
|
||||
const schemaFields = TestAModel.schema.paths;
|
||||
Object.keys(schemaFields).forEach(field => {
|
||||
if (!field.startsWith('_')) {
|
||||
const fieldDef = schemaFields[field];
|
||||
console.log(` - ${field}: ${fieldDef.instance || 'Mixed'}`);
|
||||
}
|
||||
});
|
||||
|
||||
// 3. 创建一个文档实例(不保存到数据库)
|
||||
console.log('\n🔧 创建文档实例(内存中):');
|
||||
const testDoc = new TestAModel({
|
||||
title: '测试标题',
|
||||
description: '这是一个测试描述,用于演示 Mongoose 模型的基本功能。'
|
||||
});
|
||||
|
||||
console.log(' 创建的文档:', testDoc.toJSON());
|
||||
|
||||
// 4. 验证文档
|
||||
console.log('\n✅ 验证文档:');
|
||||
const validationError = testDoc.validateSync();
|
||||
if (validationError) {
|
||||
console.log(' 验证失败:', validationError.message);
|
||||
} else {
|
||||
console.log(' 验证通过!');
|
||||
}
|
||||
|
||||
// 5. 测试无效数据
|
||||
console.log('\n❌ 测试无效数据:');
|
||||
const invalidDoc = new TestAModel({
|
||||
title: '', // 空标题应该失败
|
||||
description: 'A'.repeat(501) // 超长描述应该失败
|
||||
});
|
||||
|
||||
const invalidValidation = invalidDoc.validateSync();
|
||||
if (invalidValidation) {
|
||||
console.log(' 预期的验证错误:');
|
||||
Object.keys(invalidValidation.errors).forEach(field => {
|
||||
console.log(` - ${field}: ${invalidValidation.errors[field].message}`);
|
||||
});
|
||||
}
|
||||
|
||||
// 6. 展示 TestAService 的方法
|
||||
console.log('\n🛠️ TestAService 可用方法:');
|
||||
const serviceMethods = [
|
||||
'create', 'findAll', 'findById', 'findByTitle',
|
||||
'updateById', 'deleteById', 'deleteAll', 'count',
|
||||
'search', 'paginate'
|
||||
];
|
||||
serviceMethods.forEach(method => {
|
||||
console.log(` - TestAService.${method}()`);
|
||||
});
|
||||
|
||||
// 7. 展示如何使用(伪代码)
|
||||
console.log('\n📖 使用示例 (伪代码):');
|
||||
console.log(`
|
||||
// 连接数据库
|
||||
await connectMongoose();
|
||||
|
||||
// 创建记录
|
||||
const record = await TestAService.create({
|
||||
title: '新标题',
|
||||
description: '新描述'
|
||||
});
|
||||
|
||||
// 查询记录
|
||||
const allRecords = await TestAService.findAll();
|
||||
const foundRecord = await TestAService.findById(record._id);
|
||||
|
||||
// 更新记录
|
||||
const updated = await TestAService.updateById(record._id, {
|
||||
title: '更新的标题'
|
||||
});
|
||||
|
||||
// 删除记录
|
||||
const deleted = await TestAService.deleteById(record._id);
|
||||
|
||||
// 断开连接
|
||||
await disconnectMongoose();
|
||||
`);
|
||||
|
||||
console.log('\n✨ 模型定义演示完成!');
|
||||
console.log('\n💡 提示:');
|
||||
console.log(' 1. 确保 MongoDB 服务正在运行');
|
||||
console.log(' 2. 配置正确的 .env 文件');
|
||||
console.log(' 3. 使用 connectMongoose() 连接数据库');
|
||||
console.log(' 4. 使用 TestAService 的静态方法操作数据');
|
||||
console.log(' 5. 记得在操作完成后调用 disconnectMongoose()');
|
||||
}
|
||||
|
||||
// 运行演示
|
||||
demonstrateModelDefinition().catch(console.error);
|
||||
214
src/mongoose-example.ts
Normal file
214
src/mongoose-example.ts
Normal file
@@ -0,0 +1,214 @@
|
||||
import { connectMongoose, disconnectMongoose } from './connect.js';
|
||||
import TestAService, { TestAModel, ITestA } from './models/test-mongoose.js';
|
||||
|
||||
// 演示 Mongoose TestA 模型的使用
|
||||
async function demonstrateTestAModel() {
|
||||
try {
|
||||
// 连接到 MongoDB
|
||||
console.log('🔌 正在连接到 MongoDB...');
|
||||
await connectMongoose();
|
||||
console.log('✅ 已连接到 MongoDB');
|
||||
|
||||
// 1. 创建新记录
|
||||
console.log('\n📝 创建新的 TestA 记录...');
|
||||
const newRecord = await TestAService.create({
|
||||
title: 'Mongoose 测试记录',
|
||||
description: '这是使用 Mongoose 创建的测试记录,包含完整的 CRUD 操作演示。'
|
||||
});
|
||||
console.log('✅ 创建成功:', newRecord.toJSON());
|
||||
|
||||
// 2. 再创建几条记录用于测试
|
||||
const records = await Promise.all([
|
||||
TestAService.create({
|
||||
title: 'Node.js 学习笔记',
|
||||
description: 'Node.js 后端开发的学习心得和实践经验总结。'
|
||||
}),
|
||||
TestAService.create({
|
||||
title: 'MongoDB 数据库教程',
|
||||
description: '详细介绍 MongoDB 的安装、配置和基本使用方法。'
|
||||
}),
|
||||
TestAService.create({
|
||||
title: 'TypeScript 项目实战',
|
||||
description: '使用 TypeScript 开发大型项目的最佳实践和注意事项。'
|
||||
})
|
||||
]);
|
||||
console.log(`✅ 批量创建了 ${records.length} 条记录`);
|
||||
|
||||
// 3. 查询所有记录
|
||||
console.log('\n🔍 查询所有 TestA 记录...');
|
||||
const allRecords = await TestAService.findAll(10);
|
||||
console.log(`✅ 查询到 ${allRecords.length} 条记录:`);
|
||||
allRecords.forEach((record: ITestA, index: number) => {
|
||||
console.log(` ${index + 1}. ${record.title} (ID: ${record._id})`);
|
||||
});
|
||||
|
||||
// 4. 根据 ID 查询
|
||||
console.log('\n🔍 根据 ID 查询记录...');
|
||||
const foundRecord = await TestAService.findById(newRecord._id.toString());
|
||||
if (foundRecord) {
|
||||
console.log('✅ 查询成功:', foundRecord.toJSON());
|
||||
} else {
|
||||
console.log('❌ 未找到记录');
|
||||
}
|
||||
|
||||
// 5. 根据标题搜索
|
||||
console.log('\n🔍 根据标题搜索记录...');
|
||||
const searchResults = await TestAService.findByTitle('Mongoose');
|
||||
console.log(`✅ 搜索到 ${searchResults.length} 条包含 "Mongoose" 的记录:`);
|
||||
searchResults.forEach((record: ITestA) => {
|
||||
console.log(` - ${record.title}`);
|
||||
});
|
||||
|
||||
// 6. 全文搜索
|
||||
console.log('\n🔍 全文搜索记录...');
|
||||
const fullTextResults = await TestAService.search('Node.js');
|
||||
console.log(`✅ 搜索到 ${fullTextResults.length} 条包含 "Node.js" 的记录:`);
|
||||
fullTextResults.forEach((record: ITestA) => {
|
||||
console.log(` - ${record.title}: ${record.description.substring(0, 50)}...`);
|
||||
});
|
||||
|
||||
// 7. 分页查询
|
||||
console.log('\n📄 分页查询记录...');
|
||||
const paginatedResults = await TestAService.paginate(1, 2);
|
||||
console.log('✅ 分页查询结果:');
|
||||
console.log(` 总记录数: ${paginatedResults.total}`);
|
||||
console.log(` 当前页: ${paginatedResults.page}/${paginatedResults.pages}`);
|
||||
console.log(` 当前页记录:`);
|
||||
paginatedResults.items.forEach((record: ITestA, index: number) => {
|
||||
console.log(` ${index + 1}. ${record.title}`);
|
||||
});
|
||||
|
||||
// 8. 更新记录
|
||||
console.log('\n✏️ 更新记录...');
|
||||
const updatedRecord = await TestAService.updateById(
|
||||
newRecord._id.toString(),
|
||||
{
|
||||
title: '更新后的 Mongoose 测试记录',
|
||||
description: '这条记录已经被更新了,演示了 Mongoose 的更新功能。'
|
||||
}
|
||||
);
|
||||
if (updatedRecord) {
|
||||
console.log('✅ 更新成功:', updatedRecord.toJSON());
|
||||
} else {
|
||||
console.log('❌ 更新失败');
|
||||
}
|
||||
|
||||
// 9. 统计记录数量
|
||||
console.log('\n📊 统计记录数量...');
|
||||
const totalCount = await TestAService.count();
|
||||
console.log(`✅ 总记录数: ${totalCount}`);
|
||||
|
||||
// 10. 删除单条记录
|
||||
console.log('\n🗑️ 删除单条记录...');
|
||||
const deleteSuccess = await TestAService.deleteById(newRecord._id.toString());
|
||||
if (deleteSuccess) {
|
||||
console.log('✅ 删除成功');
|
||||
} else {
|
||||
console.log('❌ 删除失败');
|
||||
}
|
||||
|
||||
// 11. 验证删除结果
|
||||
console.log('\n🔍 验证删除结果...');
|
||||
const afterDeleteCount = await TestAService.count();
|
||||
console.log(`✅ 删除后总记录数: ${afterDeleteCount}`);
|
||||
|
||||
// 12. 使用原始 Mongoose 模型操作
|
||||
console.log('\n🔧 使用原始 Mongoose 模型操作...');
|
||||
const directRecord = new TestAModel({
|
||||
title: '直接使用 Model 创建',
|
||||
description: '这是直接使用 TestAModel 创建的记录。'
|
||||
});
|
||||
await directRecord.save();
|
||||
console.log('✅ 直接创建成功:', directRecord.toJSON());
|
||||
|
||||
// 使用 Mongoose 查询构建器
|
||||
const queryBuilderResults = await TestAModel
|
||||
.find({ title: { $regex: '直接', $options: 'i' } })
|
||||
.select('title createdAt')
|
||||
.sort({ createdAt: -1 })
|
||||
.limit(5)
|
||||
.exec();
|
||||
|
||||
console.log('✅ 查询构建器结果:');
|
||||
queryBuilderResults.forEach((record: ITestA) => {
|
||||
console.log(` - ${record.title} (${record.createdAt})`);
|
||||
});
|
||||
|
||||
// 13. 清理测试数据(可选)
|
||||
console.log('\n🧹 清理测试数据...');
|
||||
const deletedCount = await TestAService.deleteAll();
|
||||
console.log(`✅ 清理完成,删除了 ${deletedCount} 条记录`);
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ 演示过程中发生错误:', error);
|
||||
} finally {
|
||||
// 断开连接
|
||||
console.log('\n🔌 正在断开 MongoDB 连接...');
|
||||
await disconnectMongoose();
|
||||
console.log('✅ 已断开 MongoDB 连接');
|
||||
}
|
||||
}
|
||||
|
||||
// 错误处理演示
|
||||
async function demonstrateErrorHandling() {
|
||||
try {
|
||||
await connectMongoose();
|
||||
|
||||
console.log('\n🚨 错误处理演示:');
|
||||
|
||||
// 1. 无效的 ObjectId
|
||||
try {
|
||||
await TestAService.findById('invalid-id');
|
||||
} catch (error) {
|
||||
console.log('✅ 捕获到无效 ObjectId 错误:', (error as Error).message);
|
||||
}
|
||||
|
||||
// 2. 验证错误
|
||||
try {
|
||||
await TestAService.create({
|
||||
title: '', // 空标题会触发验证错误
|
||||
description: 'Valid description'
|
||||
});
|
||||
} catch (error) {
|
||||
console.log('✅ 捕获到验证错误:', (error as any).message);
|
||||
}
|
||||
|
||||
// 3. 字段长度超限
|
||||
try {
|
||||
await TestAService.create({
|
||||
title: 'A'.repeat(101), // 超过 100 字符限制
|
||||
description: 'Valid description'
|
||||
});
|
||||
} catch (error) {
|
||||
console.log('✅ 捕获到长度限制错误:', (error as any).message);
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ 错误处理演示失败:', error);
|
||||
} finally {
|
||||
await disconnectMongoose();
|
||||
}
|
||||
}
|
||||
|
||||
// 主函数
|
||||
async function main() {
|
||||
console.log('🚀 开始 Mongoose TestA 模型演示\n');
|
||||
console.log('=' .repeat(50));
|
||||
|
||||
await demonstrateTestAModel();
|
||||
|
||||
console.log('\n' + '='.repeat(50));
|
||||
await demonstrateErrorHandling();
|
||||
|
||||
console.log('\n✨ 演示完成!');
|
||||
}
|
||||
|
||||
// 检查是否直接运行此文件
|
||||
if (import.meta.url === `file://${process.argv[1]}`) {
|
||||
main().catch((error) => {
|
||||
console.error('💥 主程序执行失败:', error);
|
||||
process.exit(1);
|
||||
});
|
||||
}
|
||||
|
||||
export { demonstrateTestAModel, demonstrateErrorHandling };
|
||||
41
src/test-simple.ts
Normal file
41
src/test-simple.ts
Normal file
@@ -0,0 +1,41 @@
|
||||
import { testAModel } from './models/test.js';
|
||||
|
||||
// 简单的测试函数
|
||||
async function simpleTest() {
|
||||
try {
|
||||
console.log('🚀 开始测试 TestA 表...');
|
||||
|
||||
// 初始化模型
|
||||
await testAModel.initialize();
|
||||
console.log('✅ TestA 模型初始化成功');
|
||||
|
||||
// 创建一条测试记录
|
||||
const testDoc = await testAModel.create({
|
||||
title: '测试标题',
|
||||
description: '这是一个测试描述,用于验证 TestA 表的功能。'
|
||||
});
|
||||
console.log('✅ 创建测试记录成功:', testDoc.title);
|
||||
|
||||
// 查询所有记录
|
||||
const allDocs = await testAModel.findAll();
|
||||
console.log(`✅ 查询成功,共找到 ${allDocs.length} 条记录`);
|
||||
|
||||
// 显示记录详情
|
||||
allDocs.forEach((doc, index) => {
|
||||
console.log(`${index + 1}. 标题: ${doc.title}`);
|
||||
console.log(` 描述: ${doc.description}`);
|
||||
console.log(` 创建时间: ${doc.createdAt}`);
|
||||
console.log('');
|
||||
});
|
||||
|
||||
console.log('🎉 TestA 表测试完成!');
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ 测试失败:', error);
|
||||
}
|
||||
}
|
||||
|
||||
// 运行测试
|
||||
if (import.meta.url === `file://${process.argv[1]}`) {
|
||||
simpleTest().catch(console.error);
|
||||
}
|
||||
15
test-connection.js
Normal file
15
test-connection.js
Normal file
@@ -0,0 +1,15 @@
|
||||
// 简单的 JavaScript 测试脚本
|
||||
const { testConnection } = require('./dist/connect.js');
|
||||
|
||||
console.log('开始测试 MongoDB 连接...');
|
||||
testConnection()
|
||||
.then((success) => {
|
||||
if (success) {
|
||||
console.log('✅ 数据库连接测试通过');
|
||||
} else {
|
||||
console.log('❌ 数据库连接测试失败');
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('测试过程中发生错误:', error);
|
||||
});
|
||||
24
tsconfig.json
Normal file
24
tsconfig.json
Normal file
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2020",
|
||||
"module": "ESNext",
|
||||
"moduleResolution": "node",
|
||||
"esModuleInterop": true,
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"strict": true,
|
||||
"skipLibCheck": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"outDir": "./dist",
|
||||
"rootDir": "./src",
|
||||
"declaration": true,
|
||||
"declarationMap": true,
|
||||
"sourceMap": true
|
||||
},
|
||||
"include": [
|
||||
"src/**/*"
|
||||
],
|
||||
"exclude": [
|
||||
"node_modules",
|
||||
"dist"
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user