@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.
- package/dist/index.d.ts +2 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/package.json +2 -1
- package/dist/src/API/Request.d.ts +26 -18
- package/dist/src/API/Request.js +27 -14
- package/dist/src/API/Request.js.map +1 -1
- package/dist/src/API/Response.d.ts +1 -1
- package/dist/src/API/Response.js.map +1 -1
- package/dist/src/BaseEvent/Transaction.d.ts +9 -3
- package/dist/src/BaseEvent/Transaction.js.map +1 -1
- package/dist/src/Database/Database.d.ts +1 -1
- package/dist/src/Database/index.d.ts +7 -0
- package/dist/src/Database/index.js +10 -0
- package/dist/src/Database/index.js.map +1 -0
- package/dist/src/Database/integrations/knex/KnexDatabase.d.ts +1 -0
- package/dist/src/Database/integrations/knex/KnexDatabase.js +9 -4
- package/dist/src/Database/integrations/knex/KnexDatabase.js.map +1 -1
- package/dist/src/Database/types.d.ts +47 -0
- package/dist/src/Database/types.js +3 -0
- package/dist/src/Database/types.js.map +1 -0
- package/dist/src/Server/Router.d.ts +18 -8
- package/dist/src/Server/Router.js.map +1 -1
- package/dist/src/Server/lib/Server.js +15 -1
- package/dist/src/Server/lib/Server.js.map +1 -1
- package/dist/src/Server/lib/container/GenericHandlerEvent.js +1 -3
- package/dist/src/Server/lib/container/GenericHandlerEvent.js.map +1 -1
- package/index.ts +2 -0
- package/package.json +2 -1
- package/src/API/Request.ts +38 -21
- package/src/API/Response.ts +1 -1
- package/src/BaseEvent/Transaction.ts +16 -4
- package/src/Database/Database.ts +1 -1
- package/src/Database/index.ts +15 -0
- package/src/Database/integrations/knex/KnexDatabase.ts +10 -2
- package/src/Database/{types.d.ts → types.ts} +7 -2
- package/src/Server/Router.ts +29 -8
- package/src/Server/lib/Server.ts +18 -1
- package/src/Server/lib/container/GenericHandlerEvent.ts +1 -3
- package/tests/API/Request.test.ts +8 -2
- package/tests/API/Utils.test.ts +10 -0
- package/tests/Database/integrations/knex/KnexDatabase.test.ts +23 -0
- package/tests/Database/integrations/knex/KnexTransaction.test.ts +1 -1
- 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":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AACA,2BAA4B;AAG5B,iCAA0F;AAC1F,4CAAsC;AAWtC;;GAEG;AACH;IAaE;;;;;OAKG;IACH,6BAAY,OAAgB,EAAE,iBAAkD;QAC9E,IAAI,CAAC,OAAO,GAAG,OAAO,CAAA;QACtB,IAAI,CAAC,iBAAiB,GAAG,iBAAiB,CAAA;IAC5C,CAAC;IAED;;;OAGG;IACU,oCAAM,GAAnB;;;;gBACE,qDAAqD;gBACrD,sBAAO,IAAI,OAAO,CAAC,UAAO,OAAO,EAAE,MAAM;;;;;;oCAG/B,UAAQ,IAAI,CAAC,UAAU,EAAE,CAAA;oCACzB,OAAO,GAAG,IAAI,CAAC,YAAY,CAAC,OAAK,EAAE,UAAC,GAAoB,EAAE,IAAU;wCACxE,OAAO,CAAC,EAAE,GAAG,KAAA,EAAE,IAAI,MAAA,EAAE,CAAC,CAAA;oCACxB,CAAC,CAAC,CAAA;oCACF,SAAS;oCACT,qBAAM,IAAI,CAAC,iBAAiB,CAAC,OAAK,EAAE,OAAO,CAAC,EAAA;;oCAD5C,SAAS;oCACT,SAA4C,CAAA;;;;oCAE5C,MAAM,CAAC,GAAC,CAAC,CAAA,CAAC,oBAAoB;;;;;yBAEjC,CAAC,EAAA;;;KACH;IAED;;;OAGG;IACK,wCAAU,GAAlB;;QACE,OAAO;YACL,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,IAAI,IAAI,IAAI;YAC/B,OAAO,EAAO,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,IAAI,EAAE,CAAC;YAC1C,UAAU,EAAE,MAAA,IAAI,CAAC,OAAO,CAAC,MAAM,0CAAE,WAAW,EAAE;YAC9C,eAAe,EAAE,KAAK;YACtB,iBAAiB,EAAO,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,IAAI,EAAE,CAAC;YACpD,+BAA+B,EAAE,IAAA,4CAAoC,EAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC;YACvF,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,IAAI;YACvB,cAAc,EAAE,IAAI;YACpB,qBAAqB,EAAE,IAAI,CAAC,OAAO,CAAC,
|
|
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.
|
|
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",
|
package/src/API/Request.ts
CHANGED
|
@@ -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
|
|
8
|
-
* @
|
|
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
|
|
37
|
-
* @param {
|
|
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:
|
|
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
|
|
47
|
-
* @param {
|
|
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:
|
|
51
|
-
return Utils.caseInsensitiveObjectForKey(
|
|
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
|
|
74
|
-
* @param {
|
|
75
|
-
* @returns {boolean} - True if the parameter exists
|
|
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:
|
|
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
|
|
84
|
-
* @param {
|
|
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:
|
|
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 {
|
|
137
|
+
* @returns {PathParamsType | null} - The path parameters object, or null if not found.
|
|
132
138
|
*/
|
|
133
|
-
public getPathParams():
|
|
134
|
-
|
|
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
|
/**
|
package/src/API/Response.ts
CHANGED
|
@@ -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
|
|
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
|
>
|
package/src/Database/Database.ts
CHANGED
|
@@ -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
|
-
|
|
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
|
|
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)
|
package/src/Server/Router.ts
CHANGED
|
@@ -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, {
|
|
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<
|
|
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
|
/**
|
package/src/Server/lib/Server.ts
CHANGED
|
@@ -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.
|
|
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
|
|
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:
|
|
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', () => {
|
package/tests/API/Utils.test.ts
CHANGED
|
@@ -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 = {
|