From 9c9c41aeafff24782a7ccaeccd7bbfcc123b06dc Mon Sep 17 00:00:00 2001 From: Jerko Steiner Date: Wed, 18 Sep 2019 12:43:46 +0700 Subject: [PATCH] Extract packages/server/src/database to packages/{db,db-typeorm} --- TODO.md | 6 ++-- package.json | 6 ++-- packages/db-typeorm/jest.config.js | 16 +++++++++++ packages/db-typeorm/jest.setup.js | 4 +++ packages/db-typeorm/package-lock.json | 4 +++ packages/db-typeorm/package.json | 14 ++++++++++ .../src/TypeORMDatabase.ts} | 16 ++++++----- .../src/TypeORMLogger.ts} | 15 +++++----- .../src/TypeORMTransactionManager.ts} | 11 ++++---- packages/db-typeorm/src/index.ts | 3 ++ packages/db-typeorm/tsconfig.esm.json | 14 ++++++++++ packages/db-typeorm/tsconfig.json | 11 ++++++++ packages/db/jest.config.js | 16 +++++++++++ packages/db/jest.setup.js | 4 +++ packages/db/package-lock.json | 4 +++ packages/db/package.json | 14 ++++++++++ packages/db/src/Database.ts | 14 ++++++++++ packages/db/src/TransactionManager.ts | 12 ++++++++ packages/db/src/constants.ts | 4 +++ packages/db/src/index.ts | 3 ++ packages/db/tsconfig.esm.json | 7 +++++ packages/db/tsconfig.json | 9 ++++++ packages/server/config/default.yml | 4 +-- .../server/src/application/Application.ts | 4 +-- packages/server/src/application/Bootstrap.ts | 10 +++---- .../server/src/application/ServerBootstrap.ts | 15 +++++----- .../server/src/application/ServerConfig.ts | 8 +++--- .../server/src/application/configureServer.ts | 12 ++++---- .../server/src/application/processArgs.ts | 0 packages/server/src/database/Database.ts | 15 ---------- .../server/src/database/TransactionManager.ts | 28 ------------------- packages/server/src/database/index.ts | 4 --- packages/server/src/index.ts | 1 - packages/server/src/logger/index.ts | 1 - .../src/middleware/SessionMiddleware.ts | 4 +-- .../TransactionMiddleware.test.ts} | 12 ++++---- .../server/src/router/TransactionalRouter.ts | 2 +- packages/server/src/rpc/SQLTeamService.ts | 4 +-- packages/server/src/rpc/SQLUserService.ts | 4 +-- .../server/src/services/SQLAuthService.ts | 6 ++-- .../server/src/services/SQLUserPermissions.ts | 4 +-- packages/server/src/test-utils/TestUtils.ts | 9 +++--- packages/server/tsconfig.esm.json | 6 ++++ packages/server/tsconfig.json | 4 ++- 44 files changed, 242 insertions(+), 122 deletions(-) create mode 100644 packages/db-typeorm/jest.config.js create mode 100644 packages/db-typeorm/jest.setup.js create mode 100644 packages/db-typeorm/package-lock.json create mode 100644 packages/db-typeorm/package.json rename packages/{server/src/database/SQLDatabase.ts => db-typeorm/src/TypeORMDatabase.ts} (71%) rename packages/{server/src/logger/SqlLogger.ts => db-typeorm/src/TypeORMLogger.ts} (85%) rename packages/{server/src/database/SQLTransactionManager.ts => db-typeorm/src/TypeORMTransactionManager.ts} (85%) create mode 100644 packages/db-typeorm/src/index.ts create mode 100644 packages/db-typeorm/tsconfig.esm.json create mode 100644 packages/db-typeorm/tsconfig.json create mode 100644 packages/db/jest.config.js create mode 100644 packages/db/jest.setup.js create mode 100644 packages/db/package-lock.json create mode 100644 packages/db/package.json create mode 100644 packages/db/src/Database.ts create mode 100644 packages/db/src/TransactionManager.ts create mode 100644 packages/db/src/constants.ts create mode 100644 packages/db/src/index.ts create mode 100644 packages/db/tsconfig.esm.json create mode 100644 packages/db/tsconfig.json delete mode 100644 packages/server/src/application/processArgs.ts delete mode 100644 packages/server/src/database/Database.ts delete mode 100644 packages/server/src/database/TransactionManager.ts delete mode 100644 packages/server/src/database/index.ts rename packages/server/src/{database/index.test.ts => middleware/TransactionMiddleware.test.ts} (89%) diff --git a/TODO.md b/TODO.md index ec19bd3..a441778 100644 --- a/TODO.md +++ b/TODO.md @@ -10,13 +10,15 @@ - [ ] Add React error boundaries - [ ] Use strings as ids for big decimals - [ ] Integrate Google (and other social fb/twitter) logins -- [ ] Framewor development +- [ ] Framework development - [ ] Improve comments - [ ] Generate docs using using `typedoc` - [ ] Generate framework website using Docusaurus - [ ] Split framework projects and actual projects - [ ] Experiment with styled components -- [ ] Replace tslint with eslint: +- [ ] Use JSON schema instead of @Entity decorators +- [x] Extract database into a separate module +- [x] Replace tslint with eslint: https://github.com/typescript-eslint/typescript-eslint # JSONRPC diff --git a/package.json b/package.json index 6df3c49..f3389b1 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,9 @@ "@rondo.dev/server": "file:packages/server", "@rondo.dev/tasq": "file:packages/tasq", "@rondo.dev/test-utils": "file:packages/test-utils", - "@rondo.dev/validator": "file:packages/validator" + "@rondo.dev/validator": "file:packages/validator", + "@rondo.dev/db": "file:packages/db", + "@rondo.dev/db-typeorm": "file:packages/db-typeorm" }, "devDependencies": { "@typescript-eslint/eslint-plugin": "^2.2.0", @@ -101,4 +103,4 @@ "watchify": "^3.11.1" }, "name": "node" -} +} \ No newline at end of file diff --git a/packages/db-typeorm/jest.config.js b/packages/db-typeorm/jest.config.js new file mode 100644 index 0000000..4c0cf86 --- /dev/null +++ b/packages/db-typeorm/jest.config.js @@ -0,0 +1,16 @@ +module.exports = { + roots: [ + '/src', + ], + transform: { + '^.+\\.tsx?$': 'ts-jest', + }, + testRegex: '(/__tests__/.*|\\.(test|spec))\\.tsx?$', + moduleFileExtensions: [ + 'ts', + 'tsx', + 'js', + 'jsx', + ], + setupFiles: ['/jest.setup.js'], +} diff --git a/packages/db-typeorm/jest.setup.js b/packages/db-typeorm/jest.setup.js new file mode 100644 index 0000000..a952c9b --- /dev/null +++ b/packages/db-typeorm/jest.setup.js @@ -0,0 +1,4 @@ +if (!process.env.LOG) { + process.env.LOG = 'sql:warn' +} +process.chdir(__dirname) diff --git a/packages/db-typeorm/package-lock.json b/packages/db-typeorm/package-lock.json new file mode 100644 index 0000000..6431a37 --- /dev/null +++ b/packages/db-typeorm/package-lock.json @@ -0,0 +1,4 @@ +{ + "name": "@rondo.dev/db-typeorm", + "lockfileVersion": 1 +} diff --git a/packages/db-typeorm/package.json b/packages/db-typeorm/package.json new file mode 100644 index 0000000..546c430 --- /dev/null +++ b/packages/db-typeorm/package.json @@ -0,0 +1,14 @@ +{ + "name": "@rondo.dev/db-typeorm", + "private": true, + "scripts": { + "test": "jest", + "lint": "tslint --project .", + "compile": "tsc", + "clean": "rm -rf lib/" + }, + "dependencies": {}, + "main": "lib/index.js", + "module": "esm/index.js", + "types": "lib/index.d.ts" +} diff --git a/packages/server/src/database/SQLDatabase.ts b/packages/db-typeorm/src/TypeORMDatabase.ts similarity index 71% rename from packages/server/src/database/SQLDatabase.ts rename to packages/db-typeorm/src/TypeORMDatabase.ts index b071a16..961e639 100644 --- a/packages/server/src/database/SQLDatabase.ts +++ b/packages/db-typeorm/src/TypeORMDatabase.ts @@ -1,19 +1,20 @@ +import { Database } from '@rondo.dev/db' import { Namespace } from 'cls-hooked' -import { Connection, ConnectionOptions, createConnection, EntitySchema, Logger, ObjectType, Repository } from 'typeorm' -import { Database } from './Database' -import { SQLTransactionManager } from './SQLTransactionManager' -import { TransactionManager } from './TransactionManager' +import { Connection, ConnectionOptions, createConnection, EntityManager, EntitySchema, Logger, ObjectType, Repository } from 'typeorm' +import { TypeORMTransactionManager } from './TypeORMTransactionManager' -export class SQLDatabase implements Database { +export class TypeORMDatabase implements Database< + Connection, EntityManager, TypeORMTransactionManager> +{ protected connection?: Connection - transactionManager: TransactionManager + transactionManager: TypeORMTransactionManager constructor( readonly namespace: Namespace, protected readonly logger: Logger, protected readonly options: ConnectionOptions, ) { - this.transactionManager = new SQLTransactionManager( + this.transactionManager = new TypeORMTransactionManager( namespace, this.getConnection, ) @@ -49,3 +50,4 @@ export class SQLDatabase implements Database { } } + diff --git a/packages/server/src/logger/SqlLogger.ts b/packages/db-typeorm/src/TypeORMLogger.ts similarity index 85% rename from packages/server/src/logger/SqlLogger.ts rename to packages/db-typeorm/src/TypeORMLogger.ts index 698bc35..8878b8c 100644 --- a/packages/server/src/logger/SqlLogger.ts +++ b/packages/db-typeorm/src/TypeORMLogger.ts @@ -1,16 +1,15 @@ +import { CORRELATION_ID, TRANSACTION_ID } from '@rondo.dev/db' import { Logger } from '@rondo.dev/logger' import { Namespace } from 'cls-hooked' -import { Logger as TypeORMLogger, QueryRunner } from 'typeorm' -import { TRANSACTION_ID } from '../database' -import { CORRELATION_ID } from '../middleware/TransactionMiddleware' +import { Logger as TLogger, QueryRunner } from 'typeorm' -export class SQLLogger implements TypeORMLogger { +export class TypeORMLogger implements TLogger { constructor( protected readonly logger: Logger, protected readonly ns: Namespace, ) {} - logQuery(query: string, parameters?: any[], queryRunner?: QueryRunner): any { + logQuery(query: string, parameters?: unknown[], queryRunner?: QueryRunner) { const correlationId = this.getCorrelationId() if (parameters) { this.logger.info('%s %s -- %s', correlationId, query, parameters) @@ -24,7 +23,7 @@ export class SQLLogger implements TypeORMLogger { logQueryError( error: string, query: string, - parameters?: any[], + parameters?: unknown[], queryRunner?: QueryRunner, ) { const correlationId = this.getCorrelationId() @@ -40,7 +39,7 @@ export class SQLLogger implements TypeORMLogger { */ logQuerySlow( time: number, query: string, - parameters?: any[], + parameters?: unknown[], queryRunner?: QueryRunner, ) { const correlationId = this.getCorrelationId() @@ -70,7 +69,7 @@ export class SQLLogger implements TypeORMLogger { */ log( level: 'log' | 'info' | 'warn', - message: any, + message: unknown, queryRunner?: QueryRunner, ) { const correlationId = this.getCorrelationId() diff --git a/packages/server/src/database/SQLTransactionManager.ts b/packages/db-typeorm/src/TypeORMTransactionManager.ts similarity index 85% rename from packages/server/src/database/SQLTransactionManager.ts rename to packages/db-typeorm/src/TypeORMTransactionManager.ts index 460d45e..f8d089d 100644 --- a/packages/server/src/database/SQLTransactionManager.ts +++ b/packages/db-typeorm/src/TypeORMTransactionManager.ts @@ -1,21 +1,22 @@ +import { TRANSACTION, TransactionManager, TRANSACTION_ID } from '@rondo.dev/db' import loggerFactory from '@rondo.dev/logger' import { Namespace } from 'cls-hooked' import shortid from 'shortid' import { Connection, EntityManager, EntitySchema, ObjectType, Repository } from 'typeorm' -import { ENTITY_MANAGER, TransactionManager, TRANSACTION_ID } from './TransactionManager' const log = loggerFactory.getLogger('db') export type GetConnection = () => Connection -export class SQLTransactionManager implements TransactionManager { +export class TypeORMTransactionManager +implements TransactionManager { constructor( readonly ns: Namespace, readonly getConnection: GetConnection, ) {} getEntityManager = (): EntityManager => { - const entityManager = this.ns.get(ENTITY_MANAGER) as EntityManager + const entityManager = this.ns.get(TRANSACTION) as EntityManager if (entityManager) { return entityManager } @@ -29,7 +30,7 @@ export class SQLTransactionManager implements TransactionManager { } isInTransaction = (): boolean => { - return !!this.ns.get(ENTITY_MANAGER) + return !!this.ns.get(TRANSACTION) } async doInTransaction(fn: (em: EntityManager) => Promise) { @@ -67,6 +68,6 @@ export class SQLTransactionManager implements TransactionManager { } protected setEntityManager(entityManager: EntityManager | undefined) { - this.ns.set(ENTITY_MANAGER, entityManager) + this.ns.set(TRANSACTION, entityManager) } } diff --git a/packages/db-typeorm/src/index.ts b/packages/db-typeorm/src/index.ts new file mode 100644 index 0000000..6e65a27 --- /dev/null +++ b/packages/db-typeorm/src/index.ts @@ -0,0 +1,3 @@ +export * from './TypeORMDatabase' +export * from './TypeORMLogger' +export * from './TypeORMTransactionManager' diff --git a/packages/db-typeorm/tsconfig.esm.json b/packages/db-typeorm/tsconfig.esm.json new file mode 100644 index 0000000..2f612d2 --- /dev/null +++ b/packages/db-typeorm/tsconfig.esm.json @@ -0,0 +1,14 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "esm" + }, + "references": [ + { + "path": "../db/tsconfig.esm.json" + }, + { + "path": "../logger/tsconfig.esm.json" + } + ] +} \ No newline at end of file diff --git a/packages/db-typeorm/tsconfig.json b/packages/db-typeorm/tsconfig.json new file mode 100644 index 0000000..3e564a4 --- /dev/null +++ b/packages/db-typeorm/tsconfig.json @@ -0,0 +1,11 @@ +{ + "extends": "../tsconfig.common.json", + "compilerOptions": { + "outDir": "lib", + "rootDir": "src" + }, + "references": [ + {"path": "../db"}, + {"path": "../logger"} + ] +} diff --git a/packages/db/jest.config.js b/packages/db/jest.config.js new file mode 100644 index 0000000..4c0cf86 --- /dev/null +++ b/packages/db/jest.config.js @@ -0,0 +1,16 @@ +module.exports = { + roots: [ + '/src', + ], + transform: { + '^.+\\.tsx?$': 'ts-jest', + }, + testRegex: '(/__tests__/.*|\\.(test|spec))\\.tsx?$', + moduleFileExtensions: [ + 'ts', + 'tsx', + 'js', + 'jsx', + ], + setupFiles: ['/jest.setup.js'], +} diff --git a/packages/db/jest.setup.js b/packages/db/jest.setup.js new file mode 100644 index 0000000..a952c9b --- /dev/null +++ b/packages/db/jest.setup.js @@ -0,0 +1,4 @@ +if (!process.env.LOG) { + process.env.LOG = 'sql:warn' +} +process.chdir(__dirname) diff --git a/packages/db/package-lock.json b/packages/db/package-lock.json new file mode 100644 index 0000000..4eb78d9 --- /dev/null +++ b/packages/db/package-lock.json @@ -0,0 +1,4 @@ +{ + "name": "@rondo.dev/db", + "lockfileVersion": 1 +} diff --git a/packages/db/package.json b/packages/db/package.json new file mode 100644 index 0000000..78e2547 --- /dev/null +++ b/packages/db/package.json @@ -0,0 +1,14 @@ +{ + "name": "@rondo.dev/db", + "private": true, + "scripts": { + "test": "jest", + "lint": "tslint --project .", + "compile": "tsc", + "clean": "rm -rf lib/" + }, + "dependencies": {}, + "main": "lib/index.js", + "module": "esm/index.js", + "types": "lib/index.d.ts" +} \ No newline at end of file diff --git a/packages/db/src/Database.ts b/packages/db/src/Database.ts new file mode 100644 index 0000000..1e987f1 --- /dev/null +++ b/packages/db/src/Database.ts @@ -0,0 +1,14 @@ +import { Namespace } from "cls-hooked"; +import { TransactionManager } from "./TransactionManager"; + +export interface Database< + Connection, + Transaction, + TM extends TransactionManager, +> { + namespace: Namespace + transactionManager: TM + connect(): Promise + getConnection(): Connection + close(): Promise +} diff --git a/packages/db/src/TransactionManager.ts b/packages/db/src/TransactionManager.ts new file mode 100644 index 0000000..1b0523e --- /dev/null +++ b/packages/db/src/TransactionManager.ts @@ -0,0 +1,12 @@ +export interface TransactionManager { + isInTransaction: () => boolean + /** + * Start a new or reuse an existing transaction. + */ + doInTransaction: (fn: (t: Transaction) => Promise) => Promise + /** + * Always start a new transaction, regardless if there is one already in + * progress in the current context. + */ + doInNewTransaction: (fn: (t: Transaction) => Promise) => Promise +} diff --git a/packages/db/src/constants.ts b/packages/db/src/constants.ts new file mode 100644 index 0000000..47c9540 --- /dev/null +++ b/packages/db/src/constants.ts @@ -0,0 +1,4 @@ +export const CORRELATION_ID = 'CORRELATION_ID' +export const TRANSACTION_ID = 'TRANSACTION_ID' +export const TRANSACTION = 'TRANSACTION' + diff --git a/packages/db/src/index.ts b/packages/db/src/index.ts new file mode 100644 index 0000000..98d590a --- /dev/null +++ b/packages/db/src/index.ts @@ -0,0 +1,3 @@ +export * from './constants' +export * from './Database' +export * from './TransactionManager' diff --git a/packages/db/tsconfig.esm.json b/packages/db/tsconfig.esm.json new file mode 100644 index 0000000..d54bfbf --- /dev/null +++ b/packages/db/tsconfig.esm.json @@ -0,0 +1,7 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "esm" + }, + "references": [] +} \ No newline at end of file diff --git a/packages/db/tsconfig.json b/packages/db/tsconfig.json new file mode 100644 index 0000000..94e864b --- /dev/null +++ b/packages/db/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "../tsconfig.common.json", + "compilerOptions": { + "outDir": "lib", + "rootDir": "src" + }, + "references": [ + ] +} diff --git a/packages/server/config/default.yml b/packages/server/config/default.yml index 44164f9..5d0c863 100644 --- a/packages/server/config/default.yml +++ b/packages/server/config/default.yml @@ -19,9 +19,9 @@ app: migrationsRun: false logging: true entities: - - src/entities/*.ts + - src/entities/index.ts migrations: - - src/migrations/*.ts + - src/migrations/index.ts cli: migrationsDir: src/migrations entitiesDir: src/entities diff --git a/packages/server/src/application/Application.ts b/packages/server/src/application/Application.ts index 2495d5c..5808dd4 100644 --- a/packages/server/src/application/Application.ts +++ b/packages/server/src/application/Application.ts @@ -1,7 +1,7 @@ -import { Database } from '../database/Database' import { AppServer } from './AppServer' +import { TypeORMDatabase } from '@rondo.dev/db-typeorm'; export interface Application { readonly server: AppServer - readonly database: Database + readonly database: TypeORMDatabase } diff --git a/packages/server/src/application/Bootstrap.ts b/packages/server/src/application/Bootstrap.ts index 621f947..99d09cb 100644 --- a/packages/server/src/application/Bootstrap.ts +++ b/packages/server/src/application/Bootstrap.ts @@ -1,11 +1,11 @@ -import {AddressInfo} from 'net' -import {Application} from './Application' -import {Database} from '../database/Database' -import {Config} from './Config' +import { AddressInfo } from 'net' +import { Application } from './Application' +import { Config } from './Config' +import { TypeORMDatabase } from '@rondo.dev/db-typeorm' export interface Bootstrap { readonly application: Application - readonly database: Database + readonly database: TypeORMDatabase getConfig(): Config listen(port?: number | string, hostname?: string): Promise getAddress(): AddressInfo | string diff --git a/packages/server/src/application/ServerBootstrap.ts b/packages/server/src/application/ServerBootstrap.ts index efab0cf..99fa1a0 100644 --- a/packages/server/src/application/ServerBootstrap.ts +++ b/packages/server/src/application/ServerBootstrap.ts @@ -2,13 +2,13 @@ import assert from 'assert' import { createNamespace, Namespace } from 'cls-hooked' import { Server } from 'http' import { AddressInfo } from 'net' -import { Database, SQLDatabase } from '../database' -import { loggerFactory, SQLLogger } from '../logger' +import { loggerFactory } from '../logger' import { Application } from './Application' import { Bootstrap } from './Bootstrap' import { Config } from './Config' import { ServerConfigurator } from './configureServer' import { createServer } from './createServer' +import { TypeORMDatabase, TypeORMLogger } from '@rondo.dev/db-typeorm' export interface ServerBootstrapParams { readonly config: Config @@ -35,7 +35,7 @@ export class ServerBootstrap implements Bootstrap { protected server?: Server protected inUse = false readonly application: Application - readonly database: Database + readonly database: TypeORMDatabase constructor(params: ServerBootstrapParams) { this.config = { @@ -65,13 +65,14 @@ export class ServerBootstrap implements Bootstrap { return this.config } - protected createDatabase(): Database { + protected createDatabase(): TypeORMDatabase { const {namespace} = this - const sqlLogger = new SQLLogger(loggerFactory.getLogger('sql'), namespace) - return new SQLDatabase(namespace, sqlLogger, this.getConfig().app.db) + const sqlLogger = new TypeORMLogger( + loggerFactory.getLogger('sql'), namespace) + return new TypeORMDatabase(namespace, sqlLogger, this.getConfig().app.db) } - protected createApplication(database: Database): Application { + protected createApplication(database: TypeORMDatabase): Application { const {configureServer} = this return createServer(configureServer(this.getConfig(), database)) } diff --git a/packages/server/src/application/ServerConfig.ts b/packages/server/src/application/ServerConfig.ts index b98219e..28eeca6 100644 --- a/packages/server/src/application/ServerConfig.ts +++ b/packages/server/src/application/ServerConfig.ts @@ -1,8 +1,8 @@ -import { Config } from './Config' -import { Database } from '../database' +import { TypeORMDatabase } from '@rondo.dev/db-typeorm' import { Logger } from '@rondo.dev/logger' +import { ErrorRequestHandler, RequestHandlerParams } from 'express-serve-static-core' +import { Config } from './Config' import { Services } from './Services' -import { RequestHandlerParams, ErrorRequestHandler } from 'express-serve-static-core' export interface ServerMiddleware { path: string @@ -12,7 +12,7 @@ export interface ServerMiddleware { export interface ServerConfig { readonly config: Config - readonly database: Database + readonly database: TypeORMDatabase readonly logger: Logger readonly services: Services readonly globalErrorHandler: ErrorRequestHandler diff --git a/packages/server/src/application/configureServer.ts b/packages/server/src/application/configureServer.ts index 18e4a25..e87ccb0 100644 --- a/packages/server/src/application/configureServer.ts +++ b/packages/server/src/application/configureServer.ts @@ -1,25 +1,25 @@ +import { TypeORMDatabase } from '@rondo.dev/db-typeorm' +import { Routes } from '@rondo.dev/http-types' import { bulkjsonrpc, jsonrpc } from '@rondo.dev/jsonrpc' import { json } from 'body-parser' import cookieParser from 'cookie-parser' -import { Database } from '../database' import { loggerFactory } from '../logger' import * as Middleware from '../middleware' +import { CSRFMiddleware, RequestLogger, TransactionMiddleware } from '../middleware' import { TransactionalRouter } from '../router' import * as routes from '../routes' -import { SQLTeamService, SQLUserService, Context } from '../rpc' +import { configureAuthRoutes } from '../routes/configureAuthRoutes' +import { Context, SQLTeamService, SQLUserService } from '../rpc' import { SQLAuthService, SQLUserPermissions } from '../services' import { Config } from './Config' import { ServerConfig } from './ServerConfig' import { Services } from './Services' -import { Routes } from '@rondo.dev/http-types' -import { configureAuthRoutes } from '../routes/configureAuthRoutes' -import { TransactionMiddleware, CSRFMiddleware, RequestLogger } from '../middleware' export type ServerConfigurator< T extends ServerConfig = ServerConfig > = ( config: Config, - database: Database, + database: TypeORMDatabase, ) => T export const configureServer: ServerConfigurator = (config, database) => { diff --git a/packages/server/src/application/processArgs.ts b/packages/server/src/application/processArgs.ts deleted file mode 100644 index e69de29..0000000 diff --git a/packages/server/src/database/Database.ts b/packages/server/src/database/Database.ts deleted file mode 100644 index cbd6d10..0000000 --- a/packages/server/src/database/Database.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { Namespace } from 'cls-hooked' -import { Connection, EntityManager, EntitySchema, ObjectType, Repository } from 'typeorm' -import { TransactionManager } from './TransactionManager' - -export interface Database { - namespace: Namespace - transactionManager: TransactionManager - connect(): Promise - getConnection(): Connection - getEntityManager(): EntityManager - getRepository( - target: ObjectType | EntitySchema | string, - ): Repository - close(): Promise -} diff --git a/packages/server/src/database/TransactionManager.ts b/packages/server/src/database/TransactionManager.ts deleted file mode 100644 index 51cb91c..0000000 --- a/packages/server/src/database/TransactionManager.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { - EntityManager, - EntitySchema, - ObjectType, - Repository, -} from 'typeorm' - -export const ENTITY_MANAGER = 'ENTITY_MANAGER' -export const TRANSACTION_ID = 'TRANSACTION_ID' - -export interface TransactionManager { - getEntityManager: () => EntityManager - getRepository: ( - target: ObjectType | EntitySchema | string, - ) => Repository - isInTransaction: () => boolean - /** - * Start a new or reuse an existing transaction. - */ - doInTransaction: ( - fn: (entityManager: EntityManager) => Promise) => Promise - /** - * Always start a new transaction, regardless if there is one already in - * progress in the current context. - */ - doInNewTransaction: ( - fn: (entityManager: EntityManager) => Promise) => Promise -} diff --git a/packages/server/src/database/index.ts b/packages/server/src/database/index.ts deleted file mode 100644 index 8d23dba..0000000 --- a/packages/server/src/database/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -export * from './TransactionManager' -export * from './SQLTransactionManager' -export * from './Database' -export * from './SQLDatabase' diff --git a/packages/server/src/index.ts b/packages/server/src/index.ts index 6a93d84..568ba5b 100644 --- a/packages/server/src/index.ts +++ b/packages/server/src/index.ts @@ -5,7 +5,6 @@ if (require.main === module) { } export * from './application' export * from './cli' -export * from './database' export * from './entities' export * from './error' export * from './logger' diff --git a/packages/server/src/logger/index.ts b/packages/server/src/logger/index.ts index d60685c..185fd93 100644 --- a/packages/server/src/logger/index.ts +++ b/packages/server/src/logger/index.ts @@ -1,4 +1,3 @@ -export * from './SQLLogger' import loggerFactory from '@rondo.dev/logger' export { loggerFactory } diff --git a/packages/server/src/middleware/SessionMiddleware.ts b/packages/server/src/middleware/SessionMiddleware.ts index acf0f9d..6cbdf3a 100644 --- a/packages/server/src/middleware/SessionMiddleware.ts +++ b/packages/server/src/middleware/SessionMiddleware.ts @@ -1,15 +1,15 @@ import ExpressSession from 'express-session' import { UrlWithStringQuery } from 'url' -import { TransactionManager } from '../database' import { Session as SessionEntity } from '../entities/Session' import { apiLogger } from '../logger' import { SessionStore } from '../session/SessionStore' import { Handler } from './Handler' import { Middleware } from './Middleware' import { DefaultSession } from '../session' +import { TypeORMTransactionManager } from '@rondo.dev/db-typeorm' export interface SessionMiddlewareParams { - transactionManager: TransactionManager + transactionManager: TypeORMTransactionManager baseUrl: UrlWithStringQuery sessionName: string sessionSecret: string | string[] diff --git a/packages/server/src/database/index.test.ts b/packages/server/src/middleware/TransactionMiddleware.test.ts similarity index 89% rename from packages/server/src/database/index.test.ts rename to packages/server/src/middleware/TransactionMiddleware.test.ts index dfdb721..82b0590 100644 --- a/packages/server/src/database/index.test.ts +++ b/packages/server/src/middleware/TransactionMiddleware.test.ts @@ -1,16 +1,16 @@ +import { TRANSACTION } from '@rondo.dev/db' +import { TypeORMDatabase, TypeORMLogger } from '@rondo.dev/db-typeorm' import { createNamespace } from 'cls-hooked' import express, { NextFunction, Request, Response } from 'express' import request from 'supertest' import { config } from '../config' -import { loggerFactory, SQLLogger } from '../logger' +import { loggerFactory } from '../logger' import { CORRELATION_ID, TransactionMiddleware } from '../middleware' -import { ENTITY_MANAGER } from './' -import { SQLDatabase } from './SQLDatabase' const ns = createNamespace('clsify-test') -const database = new SQLDatabase( +const database = new TypeORMDatabase( ns, - new SQLLogger(loggerFactory.getLogger('sql'), ns), + new TypeORMLogger(loggerFactory.getLogger('sql'), ns), config.app.db, ) @@ -65,7 +65,7 @@ describe('doInTransaction', () => { app.use(new TransactionMiddleware(ns).handle) app.use('/', (req, res, next) => { if (entityManager) { - ns.set(ENTITY_MANAGER, entityManager) + ns.set(TRANSACTION, entityManager) } next() }) diff --git a/packages/server/src/router/TransactionalRouter.ts b/packages/server/src/router/TransactionalRouter.ts index 281dcde..04f0793 100644 --- a/packages/server/src/router/TransactionalRouter.ts +++ b/packages/server/src/router/TransactionalRouter.ts @@ -1,6 +1,6 @@ +import { TransactionManager } from '@rondo.dev/db' import { Method, Routes } from '@rondo.dev/http-types' import express from 'express' -import { TransactionManager } from '../database/TransactionManager' import { AsyncRouter } from './AsyncRouter' import { TypedHandler } from './TypedHandler' diff --git a/packages/server/src/rpc/SQLTeamService.ts b/packages/server/src/rpc/SQLTeamService.ts index 2edfe2e..6a49b3c 100644 --- a/packages/server/src/rpc/SQLTeamService.ts +++ b/packages/server/src/rpc/SQLTeamService.ts @@ -1,15 +1,15 @@ import { TeamAddUserParams, TeamCreateParams, TeamRemoveParams, TeamService, TeamUpdateParams, trim, UserPermissions } from '@rondo.dev/common' import { UserInTeam } from '@rondo.dev/common/lib/team/UserInTeam' import Validator from '@rondo.dev/validator' -import { Database } from '../database/Database' import { Team } from '../entities/Team' import { UserTeam } from '../entities/UserTeam' import { ensureLoggedIn, Context, RPC } from './RPC' +import { TypeORMDatabase } from '@rondo.dev/db-typeorm' @ensureLoggedIn export class SQLTeamService implements RPC { constructor( - protected readonly db: Database, + protected readonly db: TypeORMDatabase, protected readonly permissions: UserPermissions, ) {} diff --git a/packages/server/src/rpc/SQLUserService.ts b/packages/server/src/rpc/SQLUserService.ts index 862c43f..0a1d099 100644 --- a/packages/server/src/rpc/SQLUserService.ts +++ b/packages/server/src/rpc/SQLUserService.ts @@ -1,6 +1,6 @@ import { UserService } from '@rondo.dev/common' +import { TypeORMDatabase } from '@rondo.dev/db-typeorm' import { hash } from 'bcrypt' -import { Database } from '../database/Database' import { User } from '../entities/User' import { UserEmail } from '../entities/UserEmail' import { Context, ensureLoggedIn, RPC } from './RPC' @@ -10,7 +10,7 @@ const SALT_ROUNDS = 10 @ensureLoggedIn export class SQLUserService implements RPC { - constructor(protected readonly db: Database) {} + constructor(protected readonly db: TypeORMDatabase) {} async getProfile(context: Context) { const userId = context.user!.id diff --git a/packages/server/src/services/SQLAuthService.ts b/packages/server/src/services/SQLAuthService.ts index e78f94f..90b8432 100644 --- a/packages/server/src/services/SQLAuthService.ts +++ b/packages/server/src/services/SQLAuthService.ts @@ -1,9 +1,9 @@ -import { AuthService, Credentials, NewUser, UserProfile, trim } from '@rondo.dev/common' +import { AuthService, Credentials, NewUser, trim, UserProfile } from '@rondo.dev/common' +import { TypeORMDatabase } from '@rondo.dev/db-typeorm' import Validator from '@rondo.dev/validator' import { compare, hash } from 'bcrypt' import { validate as validateEmail } from 'email-validator' import createError from 'http-errors' -import { Database } from '../database/Database' import { User } from '../entities/User' import { UserEmail } from '../entities/UserEmail' @@ -11,7 +11,7 @@ const SALT_ROUNDS = 10 const MIN_PASSWORD_LENGTH = 10 export class SQLAuthService implements AuthService { - constructor(protected readonly db: Database) {} + constructor(protected readonly db: TypeORMDatabase) {} async createUser(payload: NewUser): Promise { const newUser = { diff --git a/packages/server/src/services/SQLUserPermissions.ts b/packages/server/src/services/SQLUserPermissions.ts index 203f9f3..99583ca 100644 --- a/packages/server/src/services/SQLUserPermissions.ts +++ b/packages/server/src/services/SQLUserPermissions.ts @@ -1,10 +1,10 @@ import { UserPermissions } from '@rondo.dev/common' import createError from 'http-errors' -import { Database } from '../database/Database' import { UserTeam } from '../entities/UserTeam' +import { TypeORMDatabase } from '@rondo.dev/db-typeorm' export class SQLUserPermissions implements UserPermissions { - constructor(protected readonly db: Database) {} + constructor(protected readonly db: TypeORMDatabase) {} async belongsToTeam(params: {userId: number, teamId: number}) { const {userId, teamId} = params diff --git a/packages/server/src/test-utils/TestUtils.ts b/packages/server/src/test-utils/TestUtils.ts index 08dcb79..7563120 100644 --- a/packages/server/src/test-utils/TestUtils.ts +++ b/packages/server/src/test-utils/TestUtils.ts @@ -8,9 +8,10 @@ import supertest from 'supertest' import { Connection, QueryRunner } from 'typeorm' import { AppServer } from '../application/AppServer' import { Bootstrap } from '../application/Bootstrap' -import { ENTITY_MANAGER, TransactionManager, TRANSACTION_ID } from '../database/TransactionManager' import { Role } from '../entities/Role' import { RequestTester } from './RequestTester' +import { TypeORMTransactionManager } from '@rondo.dev/db-typeorm' +import { TRANSACTION_ID, TRANSACTION } from '@rondo.dev/db' export class TestUtils { readonly username = this.createTestUsername() @@ -18,7 +19,7 @@ export class TestUtils { readonly app: AppServer readonly context: string - readonly transactionManager: TransactionManager + readonly transactionManager: TypeORMTransactionManager constructor(readonly bootstrap: Bootstrap) { this.app = bootstrap.application.server @@ -54,7 +55,7 @@ export class TestUtils { await queryRunner.connect() namespace.set(TRANSACTION_ID, shortid()) await queryRunner.startTransaction() - namespace.set(ENTITY_MANAGER, queryRunner.manager) + namespace.set(TRANSACTION, queryRunner.manager) }) afterEach(async () => { @@ -64,7 +65,7 @@ export class TestUtils { } await queryRunner.release() namespace.set(TRANSACTION_ID, undefined) - namespace.set(ENTITY_MANAGER, undefined); + namespace.set(TRANSACTION, undefined); (namespace as any).exit(context) }) diff --git a/packages/server/tsconfig.esm.json b/packages/server/tsconfig.esm.json index 01405c2..0e8587c 100644 --- a/packages/server/tsconfig.esm.json +++ b/packages/server/tsconfig.esm.json @@ -33,6 +33,12 @@ }, { "path": "../validator/tsconfig.esm.json" + }, + { + "path": "../db/tsconfig.esm.json" + }, + { + "path": "../db-typeorm/tsconfig.esm.json" } ] } \ No newline at end of file diff --git a/packages/server/tsconfig.json b/packages/server/tsconfig.json index be10daf..610557c 100644 --- a/packages/server/tsconfig.json +++ b/packages/server/tsconfig.json @@ -14,6 +14,8 @@ {"path": "../tasq"}, {"path": "../http-client"}, {"path": "../http-types"}, - {"path": "../validator"} + {"path": "../validator"}, + {"path": "../db"}, + {"path": "../db-typeorm"} ] }