【发布时间】:2021-08-03 20:51:21
【问题描述】:
PS.:我已经阅读了很多类似的主题,但没有一个可以解决我的问题,已经尝试为 ormconfig.js 和其他东西更改实体上的正则表达式模式。
好吧,几天前我能够成功执行这个 ExpressJS 应用程序,没有出现任何错误。但是现在,它才刚刚开始抛出EntityMetadataNotFound: No metadata for "User" was found.。
这是项目的存储库:https://github.com/joaocasarin/gittin
如您所见,我的 entities 和 migrations 分别指向 dist/entities/*.js 和 dist/database/migrations/*.js,因为我读过 TypeORM 在打字稿中无法使用它们(使用 ts-node-dev要运行应用程序,如果实体在 .ts 中,我会收到错误消息,说我不能在纯 javascript 文件上使用来自 ES6+ 的导入和东西。如果我使用 .ts 文件运行迁移,则找不到运行迁移.)。此外,您会看到我的实体、存储库、服务和控制器都是正确的(我看不到它们有任何问题),但是当我尝试与数据库进行交互时仍然出现该错误。
失眠请求正文:
/POST http://localhost:3000/api/users
{
"name": "123",
"password": "123",
"email": "docker@123.com",
"admin": true
}
回复:
{
"error": {
"name": "EntityMetadataNotFound",
"message": "No metadata for \"User\" was found."
}
}
终端错误:
EntityMetadataNotFound: No metadata for "User" was found.
at new EntityMetadataNotFoundError (C:\Users\joaov\Documents\gittin\src\error\EntityMetadataNotFoundError.ts:10:9)
at Connection.getMetadata (C:\Users\joaov\Documents\gittin\src\connection\Connection.ts:337:19)
at EntityManager.getCustomRepository (C:\Users\joaov\Documents\gittin\src\entity-manager\EntityManager.ts:976:86)
at Connection.getCustomRepository (C:\Users\joaov\Documents\gittin\src\connection\Connection.ts:372:29)
at Object.getCustomRepository (C:\Users\joaov\Documents\gittin\src\index.ts:298:55)
at CreateUserService.<anonymous> (C:\Users\joaov\Documents\gittin\src\services\CreateUserService.ts:14:37)
at step (C:\Users\joaov\Documents\gittin\src\services\CreateUserService.ts:33:23)
at Object.next (C:\Users\joaov\Documents\gittin\src\services\CreateUserService.ts:14:53)
at C:\Users\joaov\Documents\gittin\src\services\CreateUserService.ts:8:71
at new Promise (<anonymous>)
为了方便起见,这些是我认为的相关文件。请告诉我是否还有其他相关文件:
package.json:
{
"name": "gittin",
"version": "1.0.0",
"main": "./dist/index.js",
"repository": "https://github.com/joaocasarin/gittin.git",
"author": "Joao Casarin <joaovitorcasarin@hotmail.com>",
"license": "MIT",
"scripts": {
"db": "docker-compose -f ./docker-compose.db.yml up --build -d",
"docker:dev": "docker-compose -f ./docker-compose.dev.yml up --build -d",
"docker:prod": "docker-compose -f ./docker-compose.yml up --build -d",
"docker:clear": "docker-compose down -v --rmi local",
"docker:stop": "docker-compose down",
"dev": "ts-node-dev ./src/index.ts",
"test": "jest",
"migration:run": "ts-node-dev ./node_modules/typeorm/cli.js migration:run",
"migration:create": "ts-node-dev ./node_modules/typeorm/cli.js migration:create",
"entity:create": "ts-node-dev ./node_modules/typeorm/cli.js entity:create",
"build": "tsc",
"start": "node ."
},
"dependencies": {
"axios": "^0.21.1",
"bcryptjs": "^2.4.3",
"class-transformer": "^0.4.0",
"cors": "^2.8.5",
"dotenv": "^10.0.0",
"express": "^4.17.1",
"express-async-errors": "^3.1.1",
"jsonwebtoken": "^8.5.1",
"pg": "^8.6.0",
"reflect-metadata": "^0.1.13",
"typeorm": "^0.2.34",
"uuid": "^8.3.2"
},
"devDependencies": {
"@types/babel__core": "^7.1.15",
"@types/bcryptjs": "^2.4.2",
"@types/cors": "^2.8.10",
"@types/express": "^4.17.12",
"@types/jest": "^26.0.23",
"@types/jsonwebtoken": "^8.5.4",
"@types/node": "^15.12.4",
"@types/supertest": "^2.0.11",
"@types/uuid": "^8.3.1",
"jest": "^27.0.5",
"supertest": "^6.1.3",
"ts-jest": "^27.0.3",
"ts-node-dev": "^1.1.6",
"typescript": "^4.3.4"
}
}
ormconfig.js:
module.exports = {
"type": "postgres",
"ssl": process.env.NODE_ENV === 'production'
&& process.env.DATABASE_URL !== 'postgres://postgres:docker@localhost:5432/gittin'
&& process.env.DATABASE_URL !== 'postgres://postgres:docker@db:5432/gittin' ? { rejectUnauthorized: false } : false,
"url": process.env.DATABASE_URL,
"entities": ["dist/entities/*.js"], // typeorm loads entities from this directory
"migrations": ["dist/database/migrations/*.js"], // typeorm loads migrations from the directory
"dropSchema": process.env.NODE_ENV === 'test' ? true : false,
"migrationsRun": process.env.NODE_ENV !== 'production' ? true : false,
"cli": {
"migrationsDir": "src/database/migrations", // typeorm creates migrations in this directory
"entitiesDir": "src/entities" // typeorm creates entities in this directory
}
}
src/entities/User.ts:
import { Entity, PrimaryColumn, Column, CreateDateColumn, UpdateDateColumn } from "typeorm";
import { Exclude } from "class-transformer";
import { v4 as uuid } from "uuid";
@Entity("users")
class User {
@PrimaryColumn()
readonly id: string;
@Column()
name: string;
@Column()
email: string;
@Column()
admin: boolean;
@Exclude()
@Column()
password: string;
@CreateDateColumn()
created_at: Date;
@UpdateDateColumn()
updated_at: Date;
constructor() {
if (!this.id) {
this.id = uuid();
}
}
}
export { User };
src/repositories/UserRepositories.ts:
import { EntityRepository, Repository } from "typeorm";
import { User } from "../entities/User";
@EntityRepository(User)
class UsersRepositories extends Repository<User> {}
export { UsersRepositories };
src/services/CreateUserService.ts:
import { getCustomRepository } from "typeorm";
import { UsersRepositories } from "../repositories/UsersRepositories";
import { hash } from "bcryptjs";
interface IUserRequest {
name: string;
email: string;
admin?: boolean;
password: string;
}
class CreateUserService {
async execute({ name, email, admin = false, password }: IUserRequest) {
const usersRepository = getCustomRepository(UsersRepositories);
if(!email) {
throw new Error('Incorrect e-mail.');
}
const userAlreadyExists = await usersRepository.findOne({ email });
if(userAlreadyExists) {
throw new Error('User already exists.');
}
const passwordHash = await hash(password, 8);
const user = usersRepository.create({ name, email, admin, password: passwordHash });
await usersRepository.save(user);
return user;
}
}
export { CreateUserService };
src/controllers/CreateUserController.ts:
import { Request, Response } from "express";
import { CreateUserService } from "../services/CreateUserService";
class CreateUserController {
async handle(request: Request, response: Response) {
try {
const { name, email, admin, password } = request.body;
const createUserService = new CreateUserService();
const user = await createUserService.execute({ name, email, admin, password });
return response.send(user);
} catch (error) {
return response.send({ error });
}
}
}
export { CreateUserController };
src/routes/index.ts:
import { Router, Request, Response, NextFunction } from "express";
import { CreateUserController } from "../controllers/CreateUserController";
const router = Router();
const createUserController = new CreateUserController();
router.post('/users', createUserController.handle);
export default router;
【问题讨论】:
标签: javascript node.js typescript typeorm