Skip to content

Commit

Permalink
chore(linting): Enabled tslint and fixed errors
Browse files Browse the repository at this point in the history
  • Loading branch information
Jake Ginnivan committed Dec 31, 2018
1 parent 9cf6527 commit 6a76def
Show file tree
Hide file tree
Showing 8 changed files with 206 additions and 151 deletions.
4 changes: 4 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
"scripts": {
"prepack": "yarn verify && yarn build",
"build": "tsc -p tsconfig.build.json",
"lint": "yarn tslint --project tsconfig.build.json",
"test": "jest",
"verify": "yarn tsc -p tsconfig.json && yarn test && yarn lint",
"cz": "git-cz"
Expand All @@ -25,6 +26,9 @@
"mock-knex": "^0.4.3",
"semantic-release": "^15.13.2",
"ts-jest": "^23.10.5",
"tslint": "^5.12.0",
"tslint-config-prettier": "^1.17.0",
"tslint-eslint-rules": "^5.4.0",
"typescript": "^3.2.2"
},
"peerDependencies": {
Expand Down
118 changes: 9 additions & 109 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import * as Knex from 'knex'
import { QueryExecutor } from './query-executor'
import { ReadQueryExecutor } from './read-query-executor'
import { UnitOfWorkQueryExecutor } from './unit-of-work-query-executor'

export const REDIRECT = 'Redirect'
export { QueryExecutor, ReadQueryExecutor, UnitOfWorkQueryExecutor }

export type Tables<TTableNames extends string> = {
[table in TTableNames]: () => Knex.QueryBuilder
Expand Down Expand Up @@ -28,16 +31,14 @@ type QueryOptions<
tableNames: TableNames<TTableNames>
queryExecutor: QueryExecutor<TTableNames, Services>
}
export interface Query<
export type Query<
QueryArguments,
QueryResult,
TableNames extends string,
TTableNames extends string,
Services extends object
> {
(options: QueryOptions<QueryArguments, TableNames, Services>): PromiseLike<
QueryResult
>
}
> = (
options: QueryOptions<QueryArguments, TTableNames, Services>
) => PromiseLike<QueryResult>

export interface ExecuteResult<Args, Result> {
withArgs: (args: Args) => Promise<Result>
Expand All @@ -47,104 +48,3 @@ export interface QueryWrapper {
(builder: Knex.QueryBuilder): Knex.QueryBuilder
(builder: Knex.Raw): Knex.Raw
}

export class QueryExecutor<
TTableNames extends string,
Services extends object
> {
protected tables: Tables<TTableNames>
private wrap: QueryWrapper

constructor(
public kind: 'read-query-executor' | 'unit-of-work-query-executor',
protected knex: Knex | Knex.Transaction,
protected services: Services,
protected tableNames: TableNames<TTableNames>,
wrapQuery?: QueryWrapper
) {
this.wrap = wrapQuery || ((b: any) => b)

this.tables = Object.keys(tableNames).reduce<any>((acc, tableName) => {
acc[tableName] = () => this.wrap(knex(tableName))

return acc
}, {})
}

/** Helper to create type safe queries */
createQuery<QueryArguments, QueryResult>(
query: Query<QueryArguments, QueryResult, TTableNames, Services>
): Query<QueryArguments, QueryResult, TTableNames, Services> {
return query
}

execute<Args, Result>(
query: Query<Args, Result, TTableNames, Services>
): ExecuteResult<Args, Result> {
return {
withArgs: async args =>
await query({
query: createQuery =>
this.wrap(createQuery(this.knex) as any),
queryExecutor: this,
wrapQuery: (builder: Knex.QueryBuilder) =>
this.wrap(builder),
tables: this.tables,
args,
tableNames: this.tableNames,
...this.services
})
}
}
}

export class UnitOfWorkQueryExecutor<
TTableNames extends string,
Services extends object
> extends QueryExecutor<TTableNames, Services> {
// Unit of work executor can be used as a normal query executor
kind!: 'unit-of-work-query-executor'

constructor(
protected knex: Knex.Transaction,
services: Services,
tableNames: TableNames<TTableNames>
) {
super('unit-of-work-query-executor', knex, services, tableNames)
}
}

export class ReadQueryExecutor<
TTableNames extends string,
Services extends object
> extends QueryExecutor<TTableNames, Services> {
kind!: 'read-query-executor'

constructor(
knex: Knex,
services: Services,
tableNames: TableNames<TTableNames>
) {
super('read-query-executor', knex, services, tableNames)
}

/**
* Executes some work inside a transaction
* @param work a callback which contains the unit to be executed
* The transaction will be commited if promise resolves, rolled back if rejected
* @example executor.unitOfWork(unit => unit.executeQuery(insertBlah, blah))
*/
unitOfWork<T>(
work: (
executor: UnitOfWorkQueryExecutor<TTableNames, Services>
) => Promise<T>
): PromiseLike<any> {
return this.knex.transaction(trx => {
// knex is aware of promises, and will automatically commit
// or reject based on this callback promise
return work(
new UnitOfWorkQueryExecutor(trx, this.services, this.tableNames)
)
})
}
}
2 changes: 1 addition & 1 deletion src/mock-query-executor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import {
ExecuteResult,
UnitOfWorkQueryExecutor,
TableNames
} from './index'
} from '.'

export const NoMatch = Symbol('no match')

Expand Down
53 changes: 53 additions & 0 deletions src/query-executor.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import * as Knex from 'knex'

import { Tables, QueryWrapper, TableNames, Query, ExecuteResult } from '.'

export class QueryExecutor<
TTableNames extends string,
Services extends object
> {
protected tables: Tables<TTableNames>
private wrap: QueryWrapper

constructor(
public kind: 'read-query-executor' | 'unit-of-work-query-executor',
protected knex: Knex | Knex.Transaction,
protected services: Services,
protected tableNames: TableNames<TTableNames>,
wrapQuery?: QueryWrapper
) {
this.wrap = wrapQuery || ((b: any) => b)

this.tables = Object.keys(tableNames).reduce<any>((acc, tableName) => {
acc[tableName] = () => this.wrap(knex(tableName))

return acc
}, {})
}

/** Helper to create type safe queries */
createQuery<QueryArguments, QueryResult>(
query: Query<QueryArguments, QueryResult, TTableNames, Services>
): Query<QueryArguments, QueryResult, TTableNames, Services> {
return query
}

execute<Args, Result>(
query: Query<Args, Result, TTableNames, Services>
): ExecuteResult<Args, Result> {
return {
withArgs: async args =>
query({
query: createQuery =>
this.wrap(createQuery(this.knex) as any),
queryExecutor: this,
wrapQuery: (builder: Knex.QueryBuilder) =>
this.wrap(builder),
tables: this.tables,
args,
tableNames: this.tableNames,
...this.services
})
}
}
}
38 changes: 38 additions & 0 deletions src/read-query-executor.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import * as Knex from 'knex'
import { QueryExecutor, TableNames } from '.'
import { UnitOfWorkQueryExecutor } from './unit-of-work-query-executor'

export class ReadQueryExecutor<
TTableNames extends string,
Services extends object
> extends QueryExecutor<TTableNames, Services> {
kind!: 'read-query-executor'

constructor(
knex: Knex,
services: Services,
tableNames: TableNames<TTableNames>
) {
super('read-query-executor', knex, services, tableNames)
}

/**
* Executes some work inside a transaction
* @param work a callback which contains the unit to be executed
* The transaction will be commited if promise resolves, rolled back if rejected
* @example executor.unitOfWork(unit => unit.executeQuery(insertBlah, blah))
*/
unitOfWork<T>(
work: (
executor: UnitOfWorkQueryExecutor<TTableNames, Services>
) => Promise<T>
): PromiseLike<any> {
return this.knex.transaction(trx => {
// knex is aware of promises, and will automatically commit
// or reject based on this callback promise
return work(
new UnitOfWorkQueryExecutor(trx, this.services, this.tableNames)
)
})
}
}
18 changes: 18 additions & 0 deletions src/unit-of-work-query-executor.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import * as Knex from 'knex'
import { TableNames, QueryExecutor } from '.'

export class UnitOfWorkQueryExecutor<
TTableNames extends string,
Services extends object
> extends QueryExecutor<TTableNames, Services> {
// Unit of work executor can be used as a normal query executor
kind!: 'unit-of-work-query-executor'

constructor(
protected knex: Knex.Transaction,
services: Services,
tableNames: TableNames<TTableNames>
) {
super('unit-of-work-query-executor', knex, services, tableNames)
}
}
10 changes: 10 additions & 0 deletions tslint.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"extends": ["tslint:latest", "tslint-eslint-rules", "tslint-config-prettier"],
"rules": {
"ordered-imports": false,
"member-ordering": false,
"object-literal-sort-keys": false,
"member-access": false,
"interface-name": false
}
}
Loading

0 comments on commit 6a76def

Please sign in to comment.