feat: prepare TypeORM support for Postgres db calls

This commit is contained in:
2025-12-01 01:48:24 +01:00
parent 7dd1025aef
commit 56975a0e92
12 changed files with 2970 additions and 0 deletions

18
src/data-source.ts Normal file
View File

@@ -0,0 +1,18 @@
import "reflect-metadata"
import { DataSource } from "typeorm"
import * as dotenv from "dotenv";
dotenv.config();
export const AppDataSource = new DataSource({
type: "postgres",
host: process.env.PG_HOST ?? "localhost",
port: parseInt(process.env.PG_PORT, 10) || 5432,
username: process.env.PG_USER ?? "kitty",
password: process.env.PG_PASS ?? "CHANGEME", // Please change your password inside of the .env file!
database: process.env.PG_DB ?? "kittyurl",
synchronize: false,
logging: false,
entities: [__dirname + '/entities/*.ts'],
migrations: [__dirname + '/migrations/*.ts'],
subscribers: [],
})

31
src/entities/Link.ts Normal file
View File

@@ -0,0 +1,31 @@
import { Entity, PrimaryGeneratedColumn, Column, ManyToOne, JoinTable } from "typeorm"
import { User } from "./User"
@Entity("links")
export class Link {
@PrimaryGeneratedColumn()
id: number
@Column({ nullable: true })
subdomain: string
@Column()
shortUri: string
@Column()
fullUrl: string
@Column()
role: string
@Column('bigint')
createDate: number
@Column('bigint')
expiryDate: number
@ManyToOne(() => User, (user) => user.links)
@JoinTable()
author: User
}

24
src/entities/User.ts Normal file
View File

@@ -0,0 +1,24 @@
import { Entity, PrimaryGeneratedColumn, Column, OneToMany } from "typeorm"
import { Link } from "./Link"
@Entity("users")
export class User {
@PrimaryGeneratedColumn()
id: number
@Column({ unique: true })
name: string
@Column()
passwordHash: string
@Column()
role: string
@Column('bigint')
createdAt: number
@OneToMany(() => Link, (link) => link.author)
links: Link[];
}

25
src/index.ts Normal file
View File

@@ -0,0 +1,25 @@
import { AppDataSource } from "./data-source"
import { User } from "./entities/User"
import { smokeTest } from "./smoke-test";
AppDataSource.initialize().then(async () => {
// console.log("Inserting a new user into the database...");
// const user = new User();
// // user.firstName = "Timber";
// // user.lastName = "Saw";
// // user.age = 25;
// await AppDataSource.manager.save(user);
// console.log("Saved a new user with id: " + user.id);
// console.log("Loading users from the database...");
// const users = await AppDataSource.manager.find(User);
// console.log("Loaded users: ", users);
// console.log("Here you can setup and run express / fastify / any other framework.");
await AppDataSource.runMigrations();
await smokeTest(AppDataSource);
}).catch(error => console.log(error))

View File

@@ -0,0 +1,49 @@
import { MigrationInterface, QueryRunner } from "typeorm";
export class InitialMigration1764549652720 implements MigrationInterface {
name = 'InitialMigration1764549652720'
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`
CREATE TABLE "links" (
"id" SERIAL NOT NULL,
"subdomain" character varying,
"shortUri" character varying NOT NULL,
"fullUrl" character varying NOT NULL,
"role" character varying NOT NULL,
"createDate" bigint NOT NULL,
"expiryDate" bigint NOT NULL,
"authorId" integer,
CONSTRAINT "PK_ecf17f4a741d3c5ba0b4c5ab4b6" PRIMARY KEY ("id")
)
`);
await queryRunner.query(`
CREATE TABLE "users" (
"id" SERIAL NOT NULL,
"name" character varying NOT NULL,
"passwordHash" character varying NOT NULL,
"role" character varying NOT NULL,
"createdAt" bigint NOT NULL,
CONSTRAINT "UQ_51b8b26ac168fbe7d6f5653e6cf" UNIQUE ("name"),
CONSTRAINT "PK_a3ffb1c0c8416b9fc6f907b7433" PRIMARY KEY ("id")
)
`);
await queryRunner.query(`
ALTER TABLE "links"
ADD CONSTRAINT "FK_c5287c1e74cbb62159104715543" FOREIGN KEY ("authorId") REFERENCES "users"("id") ON DELETE NO ACTION ON UPDATE NO ACTION
`);
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`
ALTER TABLE "links" DROP CONSTRAINT "FK_c5287c1e74cbb62159104715543"
`);
await queryRunner.query(`
DROP TABLE "users"
`);
await queryRunner.query(`
DROP TABLE "links"
`);
}
}

13
src/smoke-test.ts Normal file
View File

@@ -0,0 +1,13 @@
import { Connection } from "typeorm";
import { User } from "./entities/User";
export async function smokeTest(connection: Connection) {
const user = new User();
user.name = "admin";
user.role = "admin";
user.createdAt = Date.now();
user.passwordHash = "pretend this is a hash";
await connection.manager.save(user);
}