@creator.co/wapi 1.2.11 → 1.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/dist/index.d.ts +2 -1
  2. package/dist/index.js +3 -1
  3. package/dist/index.js.map +1 -1
  4. package/dist/package.json +2 -1
  5. package/dist/src/API/Request.d.ts +26 -18
  6. package/dist/src/API/Request.js +27 -14
  7. package/dist/src/API/Request.js.map +1 -1
  8. package/dist/src/API/Response.d.ts +1 -1
  9. package/dist/src/API/Response.js.map +1 -1
  10. package/dist/src/BaseEvent/Transaction.d.ts +9 -3
  11. package/dist/src/BaseEvent/Transaction.js.map +1 -1
  12. package/dist/src/Database/Database.d.ts +1 -1
  13. package/dist/src/Database/index.d.ts +7 -0
  14. package/dist/src/Database/index.js +10 -0
  15. package/dist/src/Database/index.js.map +1 -0
  16. package/dist/src/Database/integrations/knex/KnexDatabase.d.ts +1 -0
  17. package/dist/src/Database/integrations/knex/KnexDatabase.js +9 -4
  18. package/dist/src/Database/integrations/knex/KnexDatabase.js.map +1 -1
  19. package/dist/src/Database/types.d.ts +47 -0
  20. package/dist/src/Database/types.js +3 -0
  21. package/dist/src/Database/types.js.map +1 -0
  22. package/dist/src/Server/Router.d.ts +18 -8
  23. package/dist/src/Server/Router.js.map +1 -1
  24. package/dist/src/Server/lib/Server.js +15 -1
  25. package/dist/src/Server/lib/Server.js.map +1 -1
  26. package/dist/src/Server/lib/container/GenericHandlerEvent.js +1 -3
  27. package/dist/src/Server/lib/container/GenericHandlerEvent.js.map +1 -1
  28. package/index.ts +2 -0
  29. package/package.json +2 -1
  30. package/src/API/Request.ts +38 -21
  31. package/src/API/Response.ts +1 -1
  32. package/src/BaseEvent/Transaction.ts +16 -4
  33. package/src/Database/Database.ts +1 -1
  34. package/src/Database/index.ts +15 -0
  35. package/src/Database/integrations/knex/KnexDatabase.ts +10 -2
  36. package/src/Database/{types.d.ts → types.ts} +7 -2
  37. package/src/Server/Router.ts +29 -8
  38. package/src/Server/lib/Server.ts +18 -1
  39. package/src/Server/lib/container/GenericHandlerEvent.ts +1 -3
  40. package/tests/API/Request.test.ts +8 -2
  41. package/tests/API/Utils.test.ts +10 -0
  42. package/tests/Database/integrations/knex/KnexDatabase.test.ts +23 -0
  43. package/tests/Database/integrations/knex/KnexTransaction.test.ts +1 -1
  44. package/tests/Server/lib/ContainerServer.test.ts +219 -1
@@ -1 +1 @@
1
- {"version":3,"file":"GenericHandlerEvent.js","sourceRoot":"","sources":["../../../../../src/Server/lib/container/GenericHandlerEvent.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"GenericHandlerEvent.js","sourceRoot":"","sources":["../../../../../src/Server/lib/container/GenericHandlerEvent.ts"],"names":[],"mappings":"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"}
package/index.ts CHANGED
@@ -7,6 +7,7 @@ import Transaction from './src/BaseEvent/Transaction'
7
7
  import Configuration from './src/Config/Configuration'
8
8
  import Crypto from './src/Crypto/Crypto'
9
9
  import JWT from './src/Crypto/JWT'
10
+ import * as Database from './src/Database'
10
11
  import Mailer from './src/Mailer/Mailer'
11
12
  import Router, { Route } from './src/Server/Router'
12
13
 
@@ -44,4 +45,5 @@ export {
44
45
  // Misc types
45
46
  ResponseErrorType,
46
47
  HttpMethod,
48
+ Database,
47
49
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@creator.co/wapi",
3
- "version": "1.2.11",
3
+ "version": "1.3.1",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -34,6 +34,7 @@
34
34
  "json-stringify-safe": "^5.0.1",
35
35
  "jsonwebtoken": "^9.0.2",
36
36
  "knex": "^3.0.1",
37
+ "knex-stringcase": "^1.4.6",
37
38
  "node-cache": "^5.1.2",
38
39
  "object-hash": "^3.0.0",
39
40
  "parse-duration": "^1.1.0",
@@ -4,10 +4,13 @@ import Utils from './Utils'
4
4
  import Logger from '../Logger/Logger'
5
5
 
6
6
  /**
7
- * Represents a request object with utility methods for accessing request information.
8
- * @template InputType - The type of the request body.
7
+ * Represents a request object with generic types for input, query parameters, and path parameters.
8
+ * @class Request
9
+ * @template InputType - The type of the input data for the request.
10
+ * @template PathParamsType - The type of the path parameters for the request.
11
+ * @template QueryParamsType - The type of the query parameters for the request.
9
12
  */
10
- export default class Request<InputType> {
13
+ export default class Request<InputType, PathParamsType, QueryParamsType> {
11
14
  /**
12
15
  * Represents an API Gateway event for a request.
13
16
  * @type {APIGatewayEvent}
@@ -33,22 +36,25 @@ export default class Request<InputType> {
33
36
  }
34
37
 
35
38
  /**
36
- * Checks if the given query parameter exists and has a valid value.
37
- * @param {string} paramName - The name of the query parameter to check.
39
+ * Checks if the specified query parameter exists and has a valid value.
40
+ * @param {keyof QueryParamsType} paramName - The name of the query parameter to check.
38
41
  * @returns {boolean} - True if the query parameter exists and has a valid value, false otherwise.
39
42
  */
40
- public containsQueryParam(paramName: string): boolean {
43
+ public containsQueryParam(paramName: keyof QueryParamsType): boolean {
41
44
  const val = this.getQueryParam(paramName)
42
45
  return !!val && (Utils.isValidString(val) || Utils.isValidNumber(val))
43
46
  }
44
47
 
45
48
  /**
46
- * Retrieves the value of a query parameter from the request event's query string parameters.
47
- * @param {string} paramName - The name of the query parameter to retrieve.
49
+ * Retrieves the value of a query parameter from the URL.
50
+ * @param {keyof QueryParamsType} paramName - The name of the query parameter to retrieve.
48
51
  * @returns {string | null} The value of the query parameter, or null if it does not exist.
49
52
  */
50
- public getQueryParam(paramName: string): string | null {
51
- return Utils.caseInsensitiveObjectForKey(this.requestEvent.queryStringParameters, paramName)
53
+ public getQueryParam(paramName: keyof QueryParamsType): string | null {
54
+ return Utils.caseInsensitiveObjectForKey(
55
+ this.requestEvent.queryStringParameters,
56
+ String(paramName)
57
+ )
52
58
  }
53
59
 
54
60
  /**
@@ -70,22 +76,22 @@ export default class Request<InputType> {
70
76
  }
71
77
 
72
78
  /**
73
- * Checks if the given parameter name exists in the path parameters and if its value is a valid string or number.
74
- * @param {string} paramName - The name of the parameter to check.
75
- * @returns {boolean} - True if the parameter exists and its value is a valid string or number, false otherwise.
79
+ * Checks if the given parameter name exists in the PathParamsType object.
80
+ * @param {keyof PathParamsType} paramName - The name of the parameter to check.
81
+ * @returns {boolean} - True if the parameter exists, false otherwise.
76
82
  */
77
- public containsPathParam(paramName: string): boolean {
83
+ public containsPathParam(paramName: keyof PathParamsType): boolean {
78
84
  const val = this.getPathParam(paramName)
79
85
  return !!val && (Utils.isValidString(val) || Utils.isValidNumber(val))
80
86
  }
81
87
 
82
88
  /**
83
- * Retrieves the value of a path parameter from the request event.
84
- * @param {string} paramName - The name of the path parameter to retrieve.
89
+ * Retrieves the value of a specific path parameter from the URL.
90
+ * @param {keyof PathParamsType} paramName - The name of the path parameter to retrieve.
85
91
  * @returns {string | null} The value of the path parameter, or null if it does not exist.
86
92
  */
87
- public getPathParam(paramName: string): string | null {
88
- return Utils.caseInsensitiveObjectForKey(this.requestEvent.pathParameters, paramName)
93
+ public getPathParam(paramName: keyof PathParamsType): string | null {
94
+ return Utils.caseInsensitiveObjectForKey(this.requestEvent.pathParameters, String(paramName))
89
95
  }
90
96
 
91
97
  /**
@@ -128,10 +134,21 @@ export default class Request<InputType> {
128
134
 
129
135
  /**
130
136
  * Retrieves the path parameters from the request event.
131
- * @returns {object | null} - The path parameters object, or null if not found.
137
+ * @returns {PathParamsType | null} - The path parameters object, or null if not found.
132
138
  */
133
- public getPathParams(): object | null {
134
- return this.requestEvent.pathParameters
139
+ public getPathParams(): PathParamsType | null {
140
+ // type conversion guaranteed by validation
141
+ return this.requestEvent.pathParameters as PathParamsType
142
+ }
143
+
144
+ /**
145
+ * Retrieves the query parameters from the request event.
146
+ * @returns {QueryParamsType | null} - The query parameters object, or null if not found.
147
+ */
148
+ public getQueryParams(): QueryParamsType | null {
149
+ // type conversion guaranteed by validation
150
+ console.log(this.requestEvent.queryStringParameters)
151
+ return this.requestEvent.queryStringParameters as QueryParamsType
135
152
  }
136
153
 
137
154
  /**
@@ -161,7 +161,7 @@ export default class Response<BodyType = null> {
161
161
  */
162
162
  public async build(
163
163
  context: Context,
164
- transaction: Transaction<any, any, any>,
164
+ transaction: Transaction<any, any, any, any, any>,
165
165
  optDoNotCallContext: boolean
166
166
  ): Promise<void> {
167
167
  //Stream support
@@ -17,6 +17,7 @@ import Publisher, { PublisherConfig } from '../Publisher/Publisher'
17
17
  export type TransactionExecution<TransactionType, ResponseInnerType, MiscRespType = null> = (
18
18
  transaction: TransactionType
19
19
  ) => Promise<Response<ResponseInnerType> | Response<ResponseErrorType> | MiscRespType>
20
+
20
21
  /**
21
22
  * Represents the configuration options for a transaction.
22
23
  * @typedef {Object} TransactionConfig
@@ -33,6 +34,11 @@ export type TransactionConfig = {
33
34
  publisher?: PublisherConfig
34
35
  }
35
36
 
37
+ /**
38
+ * Represents a simple string dictionary with string values
39
+ */
40
+ export type StringMap = { [key: string]: string | null }
41
+
36
42
  /**
37
43
  * Represents a transaction object that handles the execution of a request and manages the response.
38
44
  * @template InputType - The type of the input data for the transaction.
@@ -43,6 +49,8 @@ export default class Transaction<
43
49
  InputType = object,
44
50
  ResponseInnerType = null,
45
51
  MiscRespType = null,
52
+ QueryParamsType = StringMap,
53
+ PathParamsType = StringMap,
46
54
  > {
47
55
  /**
48
56
  * The instance of the DatabaseManager class used for managing the database.
@@ -87,7 +95,7 @@ export default class Transaction<
87
95
  * The request object for making a request of type InputType.
88
96
  * @readonly
89
97
  */
90
- public readonly request: Request<InputType>
98
+ public readonly request: Request<InputType, PathParamsType, QueryParamsType>
91
99
  /**
92
100
  * The publisher of the content.
93
101
  */
@@ -123,7 +131,11 @@ export default class Transaction<
123
131
  this.retrowErrors = !!config?.throwOnErrors /* retrow internal errors */
124
132
  // components
125
133
  this.logger = new Logger(config?.logger, transactionId)
126
- this.request = new Request<InputType>(this.event, this.context, this.logger)
134
+ this.request = new Request<InputType, PathParamsType, QueryParamsType>(
135
+ this.event,
136
+ this.context,
137
+ this.logger
138
+ )
127
139
  this.publisher = new Publisher(config?.publisher)
128
140
  }
129
141
 
@@ -135,7 +147,7 @@ export default class Transaction<
135
147
  */
136
148
  public async execute(
137
149
  executionFunc: TransactionExecution<
138
- Transaction<InputType, ResponseInnerType, MiscRespType>,
150
+ Transaction<InputType, ResponseInnerType, MiscRespType, QueryParamsType, PathParamsType>,
139
151
  ResponseInnerType,
140
152
  MiscRespType
141
153
  >
@@ -158,7 +170,7 @@ export default class Transaction<
158
170
  */
159
171
  private async iexecute(
160
172
  executionFunc: TransactionExecution<
161
- Transaction<InputType, ResponseInnerType, MiscRespType>,
173
+ Transaction<InputType, ResponseInnerType, MiscRespType, QueryParamsType, PathParamsType>,
162
174
  ResponseInnerType,
163
175
  MiscRespType
164
176
  >
@@ -1,5 +1,5 @@
1
1
  import { DatabaseTransaction } from './DatabaseTransaction'
2
- import type { DbConfig } from './types'
2
+ import { DbConfig } from './types'
3
3
 
4
4
  /**
5
5
  * Abstract class representing a database.
@@ -0,0 +1,15 @@
1
+ import { Database } from './Database'
2
+ import { DatabaseManager } from './DatabaseManager'
3
+ import { DatabaseTransaction } from './DatabaseTransaction'
4
+ import { KnexTransaction } from './integrations/knex/KnexTransaction'
5
+ import { PostgresTransaction } from './integrations/pgsql/PostgresTransaction'
6
+ import { DbConfig } from './types'
7
+
8
+ export {
9
+ DatabaseTransaction,
10
+ DbConfig,
11
+ KnexTransaction,
12
+ PostgresTransaction,
13
+ DatabaseManager,
14
+ Database,
15
+ }
@@ -1,4 +1,5 @@
1
1
  import knex, { Knex } from 'knex'
2
+ import * as knexStringcase from 'knex-stringcase'
2
3
 
3
4
  import { KnexTransaction, KnexTransactionImpl } from './KnexTransaction'
4
5
  import { Database } from '../../Database'
@@ -20,7 +21,12 @@ export class KnexDatabase extends Database<KnexTransaction> {
20
21
  */
21
22
  public constructor(config: DbConfig<'knex'>) {
22
23
  super(config)
23
- this.client = KnexDatabase.knexProvider({
24
+
25
+ this.client = KnexDatabase.knexProvider(this.constructConfig(config))
26
+ }
27
+
28
+ private constructConfig(config: DbConfig<'knex'>) {
29
+ const knexConfig = {
24
30
  client: config.driver,
25
31
  connection: {
26
32
  host: config.host,
@@ -33,7 +39,9 @@ export class KnexDatabase extends Database<KnexTransaction> {
33
39
  min: 1,
34
40
  max: config.maxConnections,
35
41
  },
36
- })
42
+ }
43
+
44
+ return config.convertCamelToSnake ? knexStringcase(knexConfig) : knexConfig
37
45
  }
38
46
 
39
47
  /**
@@ -34,9 +34,10 @@ export type DatabaseTransactionType<Type extends DatabaseType> =
34
34
  * @property {string} database - The name of the database to connect to.
35
35
  * @property {boolean} autoCommit - Whether or not to automatically commit transactions.
36
36
  * @property {number} maxConnections - The maximum number of connections to the database.
37
+ * @property {boolean} [convertCamelToSnake] - Whether or not to convert camel case to snake case for column names.
37
38
  * @returns The transaction type associated with the specified database type.
38
39
  */
39
- export interface DbConfig<S extends DatabaseType> {
40
+ export type DbConfig<S extends DatabaseType> = {
40
41
  type: S
41
42
  driver: string
42
43
  host: string
@@ -46,4 +47,8 @@ export interface DbConfig<S extends DatabaseType> {
46
47
  database: string
47
48
  autoCommit: boolean
48
49
  maxConnections: number
49
- }
50
+ } & (S extends 'knex'
51
+ ? {
52
+ convertCamelToSnake?: boolean
53
+ }
54
+ : any)
@@ -8,7 +8,11 @@ import Server from './lib/Server'
8
8
  import { HttpMethod } from '../API/Request'
9
9
  import { ResponseErrorType } from '../API/Response'
10
10
  import Utils from '../API/Utils'
11
- import Transaction, { TransactionConfig, TransactionExecution } from '../BaseEvent/Transaction'
11
+ import Transaction, {
12
+ TransactionConfig,
13
+ TransactionExecution,
14
+ StringMap,
15
+ } from '../BaseEvent/Transaction'
12
16
 
13
17
  /**
14
18
  * Represents a route in an API.
@@ -19,7 +23,12 @@ import Transaction, { TransactionConfig, TransactionExecution } from '../BaseEve
19
23
  * @property {TransactionExecution<Transaction<InputType, OutputType | ResponseErrorType>, OutputType | ResponseErrorType>} handler - The handler function for the route.
20
24
  * @property {z.ZodObject<any>} [inputSchema] - The input schema for validating the input data.
21
25
  */
22
- export interface Route<InputType = any, OutputType = any> {
26
+ export interface Route<
27
+ InputType = any,
28
+ OutputType = any,
29
+ PathParamsType = StringMap,
30
+ QueryParamsType = StringMap,
31
+ > {
23
32
  /**
24
33
  * Represents a file path as a string.
25
34
  * @param {string} path - The file path.
@@ -39,24 +48,36 @@ export interface Route<InputType = any, OutputType = any> {
39
48
  */
40
49
  /**
41
50
  * Represents a handler for executing a transaction with the given input type and output type.
42
- * @param {Transaction<InputType, OutputType | ResponseErrorType>} transaction - The transaction to execute.
51
+ * @param {Transaction<InputType, OutputType | ResponseErrorType, PathParamsType, QueryParamsType>} transaction - The transaction to execute.
43
52
  * @param {OutputType | ResponseErrorType} - The output type or response error type of the transaction.
44
53
  */
45
54
  handler: TransactionExecution<
46
- Transaction<InputType, OutputType | ResponseErrorType>,
55
+ Transaction<InputType, OutputType | ResponseErrorType, null, PathParamsType, QueryParamsType>,
47
56
  OutputType | ResponseErrorType
48
57
  >
49
58
  /**
50
- <<<<<<< HEAD
51
59
  * An optional input schema for validating the structure of the input data.
52
- * @type {z.ZodObject<any>}
53
- =======
54
60
  * Description placeholder
55
61
  *
56
62
  * @type {?z.ZodObject<any> | z.ZodUnion<any>}
57
- >>>>>>> 65ffb67 (Improve syntax with tighther eslint, fix lots of test errors, new proxy containerSetupHook and improved validation type)
58
63
  */
59
64
  inputSchema?: z.ZodObject<any> | z.ZodUnion<any>
65
+
66
+ /**
67
+ * An optional input schema for validating the structure of the path params.
68
+ * Description placeholder
69
+ *
70
+ * @type {?z.ZodObject<any> | z.ZodUnion<any>}
71
+ */
72
+ pathSchema?: z.ZodObject<any> | z.ZodUnion<any>
73
+
74
+ /**
75
+ * An optional input schema for validating the structure of the query params.
76
+ * Description placeholder
77
+ *
78
+ * @type {?z.ZodObject<any> | z.ZodUnion<any>}
79
+ */
80
+ querySchema?: z.ZodObject<any> | z.ZodUnion<any>
60
81
  }
61
82
 
62
83
  /**
@@ -62,7 +62,24 @@ export default class Server {
62
62
  if (validationResp && validationResp instanceof Response) return validationResp
63
63
  }
64
64
 
65
+ // Validate query
66
+ if (route.querySchema) {
67
+ const validationResp = Validator.validateSchema(
68
+ request.getQueryParams(),
69
+ route.querySchema
70
+ )
71
+ if (validationResp && validationResp instanceof Response) return validationResp
72
+ }
73
+
74
+ // parse before validating
65
75
  this.parsePathParams(request, route.path)
76
+ // Validate path
77
+ if (route.pathSchema) {
78
+ console.log('VVVV', request.getPathParams())
79
+ const validationResp = Validator.validateSchema(request.getPathParams(), route.pathSchema)
80
+ if (validationResp && validationResp instanceof Response) return validationResp
81
+ }
82
+
66
83
  // Continue to route handler
67
84
  return await route.handler(transaction)
68
85
  }
@@ -77,7 +94,7 @@ export default class Server {
77
94
  * @param {string} routePath - The route path pattern to match against.
78
95
  * @returns None
79
96
  */
80
- private parsePathParams(req: Request<any>, routePath: string) {
97
+ private parsePathParams(req: Request<any, any, any>, routePath: string) {
81
98
  const path = req.getPath()
82
99
  const keys = []
83
100
  const result = pathToRegexp(routePath, keys).exec(path)
@@ -76,9 +76,7 @@ export default class GenericHandlerEvent {
76
76
  multiValueQueryStringParameters: parseMultiValueQueryStringParameters(this.request.url),
77
77
  path: this.request.path,
78
78
  pathParameters: null,
79
- queryStringParameters: this.request.query
80
- ? parseQueryStringParameters(this.request.query)
81
- : null,
79
+ queryStringParameters: this.request.url ? parseQueryStringParameters(this.request.url) : null,
82
80
  requestContext: {
83
81
  accountId: process.env.AWS_ACCOUNT_ID || 'undefined',
84
82
  apiId: '',
@@ -11,7 +11,11 @@ function newReq(event: any, context?: any) {
11
11
  },
12
12
  '123-456'
13
13
  )
14
- return new Request(<APIGatewayEvent>(<unknown>event), <Context>context ? context : {}, logger)
14
+ return new Request<any, any, any>(
15
+ <APIGatewayEvent>(<unknown>event),
16
+ <Context>context ? context : {},
17
+ logger
18
+ )
15
19
  }
16
20
 
17
21
  describe('Request querystring', () => {
@@ -32,11 +36,13 @@ describe('Request querystring', () => {
32
36
  })
33
37
 
34
38
  test('Valid query string', () => {
39
+ const v = { '123': 'abc' }
35
40
  const r = newReq({
36
- queryStringParameters: { '123': 'abc' },
41
+ queryStringParameters: v,
37
42
  })
38
43
  expect(r.containsQueryParam('123')).to.be.true
39
44
  expect(r.getQueryParam('123')).to.be.equals('abc')
45
+ expect(r.getQueryParams()).to.be.deep.equal(v)
40
46
  })
41
47
 
42
48
  test('Valid query string number', () => {
@@ -114,6 +114,16 @@ describe('isValidNumber', () => {
114
114
  expect(v).to.be.false
115
115
  })
116
116
 
117
+ test('Not a valid number if causes a crash on conversion', () => {
118
+ // @ts-ignore
119
+ const v = Utils.isValidNumber({
120
+ toString: () => {
121
+ throw new Error('Evil object')
122
+ },
123
+ })
124
+ expect(v).to.be.false
125
+ })
126
+
117
127
  test('Valid number if numbers and chars after', () => {
118
128
  const v = Utils.isValidNumber('123abc')
119
129
  expect(v).to.be.true
@@ -50,4 +50,27 @@ describe('KnexDatabase', () => {
50
50
  expect(trans).toBeInstanceOf(KnexTransactionImpl)
51
51
  expect(trans['delegate']).toBe(mockTrans)
52
52
  })
53
+
54
+ test('KnexDatabase - convert camel to snake', async () => {
55
+ const mockTrans = { a: 'b' } as any
56
+ const mockClient = jest.fn(
57
+ () =>
58
+ ({
59
+ transaction: async () => mockTrans,
60
+ }) as Knex
61
+ )
62
+ KnexDatabase['knexProvider'] = mockClient
63
+
64
+ const underTest = new KnexDatabase({ ...config, convertCamelToSnake: true })
65
+ expect(mockClient).toBeCalledWith({
66
+ ...expectedImplConfig,
67
+ postProcessResponse: expect.any(Function),
68
+ wrapIdentifier: expect.any(Function),
69
+ })
70
+
71
+ const trans = await underTest.transaction()
72
+
73
+ expect(trans).toBeInstanceOf(KnexTransactionImpl)
74
+ expect(trans['delegate']).toBe(mockTrans)
75
+ })
53
76
  })
@@ -1,8 +1,8 @@
1
1
  import { Knex } from 'knex'
2
2
 
3
+ import { DbConfig } from '../../../../src/Database'
3
4
  import { KnexDatabase } from '../../../../src/Database/integrations/knex/KnexDatabase'
4
5
  import { KnexTransactionImpl } from '../../../../src/Database/integrations/knex/KnexTransaction'
5
- import type { DbConfig } from '../../../../src/Database/types'
6
6
 
7
7
  const testResources = (config: Partial<DbConfig<'knex'>>) => {
8
8
  const database = {