@creator.co/wapi 1.7.1-alpha3 → 1.7.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 (114) hide show
  1. package/.eslintignore +3 -0
  2. package/.eslintrc.cjs +60 -0
  3. package/.github/workflows/npmpublish.yml +11 -0
  4. package/.github/workflows/prs.yml +13 -0
  5. package/dist/package-lock.json +2 -2
  6. package/dist/package.json +1 -1
  7. package/jest.config.ts +33 -0
  8. package/jest.smoke.config.ts +35 -0
  9. package/package.json +1 -1
  10. package/tests/API/Request.test.ts +273 -0
  11. package/tests/API/Response.test.ts +367 -0
  12. package/tests/API/Utils.test.ts +167 -0
  13. package/tests/BaseEvent/EventProcessor.test.ts +261 -0
  14. package/tests/BaseEvent/Process.test.ts +49 -0
  15. package/tests/BaseEvent/Transaction.test.ts +408 -0
  16. package/tests/Cache/Redis-client.test.ts +90 -0
  17. package/tests/Cache/Redis-cluster.test.ts +100 -0
  18. package/tests/Config/Config.test.ts +205 -0
  19. package/tests/Config/EnvironmentVar.test.ts +250 -0
  20. package/tests/Crypto/Crypto.test.ts +88 -0
  21. package/tests/Crypto/JWT.test.ts +92 -0
  22. package/tests/Database/DatabaseManager.test.ts +71 -0
  23. package/tests/Database/integrations/knex/KnexDatabase.test.ts +76 -0
  24. package/tests/Database/integrations/knex/KnexTransaction.test.ts +149 -0
  25. package/tests/Database/integrations/kysely/KyselyDatabase.test.ts +113 -0
  26. package/tests/Database/integrations/kysely/KyselyTransaction.test.ts +119 -0
  27. package/tests/Database/integrations/pg/PostgresDatabase.test.ts +76 -0
  28. package/tests/Database/integrations/pg/PostgresTransaction.test.ts +118 -0
  29. package/tests/Logger/Logger.test.ts +219 -0
  30. package/tests/Mailer/Mailer.test.ts +59 -0
  31. package/tests/Publisher/Publisher.test.ts +94 -0
  32. package/tests/Server/RouteResolver.test.ts +102 -0
  33. package/tests/Server/Router.test.ts +39 -0
  34. package/tests/Server/lib/ContainerServer.test.ts +531 -0
  35. package/tests/Server/lib/Server.test.ts +12 -0
  36. package/tests/Server/lib/container/GenericHandler.test.ts +131 -0
  37. package/tests/Server/lib/container/GenericHandlerEvent.test.ts +103 -0
  38. package/tests/Server/lib/container/HealthHandler.test.ts +30 -0
  39. package/tests/Server/lib/container/Proxy.test.ts +268 -0
  40. package/tests/Server/lib/container/Utils.test.ts +47 -0
  41. package/tests/Test.utils.ts +74 -0
  42. package/tests/Validation/Validator.test.ts +76 -0
  43. package/tsconfig.json +26 -0
  44. package/tsconfig.smoke.json +26 -0
  45. package/coverage/clover.xml +0 -1088
  46. package/coverage/coverage/coverage.txt +0 -40
  47. package/coverage/coverage-final.json +0 -37
  48. package/coverage/coverage-summary.json +0 -38
  49. package/coverage/coverage.txt +0 -59
  50. package/coverage/lcov-report/base.css +0 -224
  51. package/coverage/lcov-report/block-navigation.js +0 -87
  52. package/coverage/lcov-report/favicon.png +0 -0
  53. package/coverage/lcov-report/index.html +0 -371
  54. package/coverage/lcov-report/prettify.css +0 -1
  55. package/coverage/lcov-report/prettify.js +0 -2
  56. package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  57. package/coverage/lcov-report/sorter.js +0 -196
  58. package/coverage/lcov-report/src/API/Request.ts.html +0 -727
  59. package/coverage/lcov-report/src/API/Response.ts.html +0 -1189
  60. package/coverage/lcov-report/src/API/Utils.ts.html +0 -313
  61. package/coverage/lcov-report/src/API/index.html +0 -131
  62. package/coverage/lcov-report/src/BaseEvent/EventProcessor.ts.html +0 -496
  63. package/coverage/lcov-report/src/BaseEvent/Process.ts.html +0 -346
  64. package/coverage/lcov-report/src/BaseEvent/Transaction.ts.html +0 -1015
  65. package/coverage/lcov-report/src/BaseEvent/index.html +0 -146
  66. package/coverage/lcov-report/src/Cache/Redis.ts.html +0 -367
  67. package/coverage/lcov-report/src/Cache/index.html +0 -116
  68. package/coverage/lcov-report/src/Config/Configuration.ts.html +0 -700
  69. package/coverage/lcov-report/src/Config/EnvironmentVar.ts.html +0 -526
  70. package/coverage/lcov-report/src/Config/index.html +0 -131
  71. package/coverage/lcov-report/src/Crypto/Crypto.ts.html +0 -352
  72. package/coverage/lcov-report/src/Crypto/JWT.ts.html +0 -337
  73. package/coverage/lcov-report/src/Crypto/index.html +0 -131
  74. package/coverage/lcov-report/src/Database/Database.ts.html +0 -151
  75. package/coverage/lcov-report/src/Database/DatabaseManager.ts.html +0 -289
  76. package/coverage/lcov-report/src/Database/DatabaseTransaction.ts.html +0 -595
  77. package/coverage/lcov-report/src/Database/index.html +0 -161
  78. package/coverage/lcov-report/src/Database/index.ts.html +0 -169
  79. package/coverage/lcov-report/src/Database/integrations/knex/KnexDatabase.ts.html +0 -283
  80. package/coverage/lcov-report/src/Database/integrations/knex/KnexTransaction.ts.html +0 -337
  81. package/coverage/lcov-report/src/Database/integrations/knex/index.html +0 -131
  82. package/coverage/lcov-report/src/Database/integrations/kysely/KyselyDatabase.ts.html +0 -376
  83. package/coverage/lcov-report/src/Database/integrations/kysely/KyselyTransaction.ts.html +0 -601
  84. package/coverage/lcov-report/src/Database/integrations/kysely/index.html +0 -131
  85. package/coverage/lcov-report/src/Database/integrations/pgsql/PostgresDatabase.ts.html +0 -250
  86. package/coverage/lcov-report/src/Database/integrations/pgsql/PostgresTransaction.ts.html +0 -346
  87. package/coverage/lcov-report/src/Database/integrations/pgsql/index.html +0 -131
  88. package/coverage/lcov-report/src/Database/types.d.ts.html +0 -232
  89. package/coverage/lcov-report/src/Globals.ts.html +0 -394
  90. package/coverage/lcov-report/src/Logger/Logger.ts.html +0 -1138
  91. package/coverage/lcov-report/src/Logger/index.html +0 -116
  92. package/coverage/lcov-report/src/Mailer/Mailer.ts.html +0 -754
  93. package/coverage/lcov-report/src/Mailer/index.html +0 -116
  94. package/coverage/lcov-report/src/Publisher/Publisher.ts.html +0 -460
  95. package/coverage/lcov-report/src/Publisher/index.html +0 -116
  96. package/coverage/lcov-report/src/Server/RouteResolver.ts.html +0 -442
  97. package/coverage/lcov-report/src/Server/Router.ts.html +0 -616
  98. package/coverage/lcov-report/src/Server/index.html +0 -131
  99. package/coverage/lcov-report/src/Server/lib/ContainerServer.ts.html +0 -280
  100. package/coverage/lcov-report/src/Server/lib/Server.ts.html +0 -403
  101. package/coverage/lcov-report/src/Server/lib/container/GenericHandler.ts.html +0 -331
  102. package/coverage/lcov-report/src/Server/lib/container/GenericHandlerEvent.ts.html +0 -547
  103. package/coverage/lcov-report/src/Server/lib/container/HealthHandler.ts.html +0 -118
  104. package/coverage/lcov-report/src/Server/lib/container/Proxy.ts.html +0 -619
  105. package/coverage/lcov-report/src/Server/lib/container/Utils.ts.html +0 -184
  106. package/coverage/lcov-report/src/Server/lib/container/index.html +0 -176
  107. package/coverage/lcov-report/src/Server/lib/index.html +0 -131
  108. package/coverage/lcov-report/src/Util/AsyncSingleton.ts.html +0 -343
  109. package/coverage/lcov-report/src/Util/Utils.ts.html +0 -313
  110. package/coverage/lcov-report/src/Util/index.html +0 -131
  111. package/coverage/lcov-report/src/Validation/Validator.ts.html +0 -217
  112. package/coverage/lcov-report/src/Validation/index.html +0 -116
  113. package/coverage/lcov-report/src/index.html +0 -116
  114. package/coverage/lcov.info +0 -2326
@@ -0,0 +1,119 @@
1
+ import { jest } from '@jest/globals'
2
+ import { Kysely, Transaction } from 'kysely'
3
+
4
+ import type { DbConfig } from '../../../../src/Database'
5
+ import { KyselyDatabase } from '../../../../src/Database/integrations/kysely/KyselyDatabase'
6
+ import { KyselyTransactionImpl } from '../../../../src/Database/integrations/kysely/KyselyTransaction'
7
+
8
+ const testResources = async (config: Partial<DbConfig<'kysely'>>) => {
9
+ type DB = {
10
+ view: {
11
+ id: number
12
+ }
13
+ secondView: {
14
+ title: string
15
+ }
16
+ }
17
+
18
+ const database = {
19
+ config: {
20
+ autoCommit: true,
21
+ ...config,
22
+ } as DbConfig<'kysely'>,
23
+ } as KyselyDatabase<DB>
24
+
25
+ const transaction = jest.fn().mockImplementation(() => {
26
+ return {
27
+ execute: jest.fn(async (cb: any) => {
28
+ try {
29
+ await cb(transaction)
30
+ } catch (e) {
31
+ /* empty */
32
+ }
33
+ }),
34
+ executeQuery: jest.fn(),
35
+ }
36
+ })() as any as Transaction<DB>
37
+
38
+ const writer = jest.fn().mockImplementation(() => {
39
+ return {
40
+ transaction: jest.fn(() => transaction),
41
+ }
42
+ })() as any as Kysely<DB>
43
+
44
+ return {
45
+ transaction,
46
+ writer,
47
+ underTest: await KyselyTransactionImpl.newTransaction(writer, database),
48
+ }
49
+ }
50
+
51
+ describe('KyselyTransaction', () => {
52
+ test('Transaction starts opened', async () => {
53
+ const { transaction, underTest } = await testResources({})
54
+ expect(underTest.isOpen()).toBe(true)
55
+ expect(transaction['execute']).toHaveBeenCalledTimes(1)
56
+
57
+ await expect(underTest.begin).rejects.toThrowError(
58
+ 'Cannot begin, transaction is already opened!'
59
+ )
60
+ })
61
+
62
+ test('Can only commit once', async () => {
63
+ const { underTest } = await testResources({})
64
+ await underTest.commit()
65
+ expect(underTest.isOpen()).toBe(false)
66
+
67
+ await expect(underTest.commit).rejects.toThrowError(
68
+ 'Cannot commit, transaction is already closed!'
69
+ )
70
+ })
71
+
72
+ test('Can only rollback once', async () => {
73
+ const { underTest } = await testResources({})
74
+ await underTest.rollback()
75
+ expect(underTest.isOpen()).toBe(false)
76
+ await expect(underTest.rollback).rejects.toThrowError(
77
+ 'Cannot rollback, transaction is already closed!'
78
+ )
79
+ })
80
+
81
+ test("Can't open transaction twice", async () => {
82
+ const { underTest } = await testResources({})
83
+ expect(underTest.isOpen()).toBe(true)
84
+
85
+ await expect(underTest.begin).rejects.toThrowError(
86
+ 'Cannot begin, transaction is already opened!'
87
+ )
88
+ })
89
+
90
+ test('Can commit, begin and commit again ', async () => {
91
+ const { underTest } = await testResources({})
92
+ await underTest.commit()
93
+ expect(underTest.isOpen()).toBe(false)
94
+ await underTest.begin()
95
+ expect(underTest.isOpen()).toBe(true)
96
+ await underTest.commit()
97
+ expect(underTest.isOpen()).toBe(false)
98
+ })
99
+
100
+ test('Can commit, begin and rollback ', async () => {
101
+ const { underTest } = await testResources({})
102
+ await underTest.commit()
103
+ expect(underTest.isOpen()).toBe(false)
104
+ await underTest.begin()
105
+ expect(underTest.isOpen()).toBe(true)
106
+ await underTest.rollback()
107
+ expect(underTest.isOpen()).toBe(false)
108
+ })
109
+
110
+ test('Can rollback, begin and commit ', async () => {
111
+ const { underTest } = await testResources({})
112
+ await underTest.rollback()
113
+ expect(underTest.isOpen()).toBe(false)
114
+ await underTest.begin()
115
+ expect(underTest.isOpen()).toBe(true)
116
+ await underTest.commit()
117
+ expect(underTest.isOpen()).toBe(false)
118
+ })
119
+ })
@@ -0,0 +1,76 @@
1
+ import { jest } from '@jest/globals'
2
+ import * as pg from 'pg'
3
+
4
+ import type { DbConfig } from '../../../../src/Database'
5
+ import { PostgresDatabase } from '../../../../src/Database/integrations/pgsql/PostgresDatabase'
6
+
7
+ const config: DbConfig<'pg'> = {
8
+ type: 'pg',
9
+ username: 'username',
10
+ password: 'password',
11
+ host: 'host',
12
+ port: 1234,
13
+ database: 'database',
14
+ maxConnections: 1,
15
+ autoCommit: true,
16
+ }
17
+
18
+ const config2: DbConfig<'pg'> = {
19
+ ...config,
20
+ readReplica: config,
21
+ }
22
+
23
+ const expectedImplConfig = {
24
+ host: config.host,
25
+ port: config.port,
26
+ user: config.username,
27
+ password: config.password,
28
+ database: config.database,
29
+ max: config.maxConnections,
30
+ }
31
+
32
+ describe('PostgresDatabase', () => {
33
+ let mockTrans
34
+ let mockClient
35
+ beforeEach(() => {
36
+ mockTrans = {
37
+ query: jest.fn(() => {}),
38
+ } as any
39
+ mockClient = jest.fn(
40
+ () =>
41
+ ({
42
+ connect: async () => mockTrans,
43
+ }) as pg.PoolClient
44
+ )
45
+ PostgresDatabase['pgProvider'] = mockClient as any
46
+ })
47
+
48
+ test('PostgresDatabase', async () => {
49
+ const underTest = new PostgresDatabase(config)
50
+ expect(mockClient).toHaveBeenNthCalledWith(1, expectedImplConfig)
51
+
52
+ const trans = await underTest.transaction()
53
+
54
+ expect(mockTrans.query).toBeCalledWith('BEGIN')
55
+ expect(trans.reader).toBeUndefined()
56
+ expect(trans.writer).toBeInstanceOf(Object)
57
+ expect(trans.writer.connect).toBeInstanceOf(Function)
58
+ expect(trans).toBeInstanceOf(Function)
59
+ expect(trans['transaction']).toBe(mockTrans)
60
+ })
61
+
62
+ test('PostgresDatabase - read replica', async () => {
63
+ const underTest = new PostgresDatabase(config2)
64
+ expect(mockClient).toHaveBeenNthCalledWith(2, expectedImplConfig)
65
+
66
+ const trans = await underTest.transaction()
67
+
68
+ expect(mockTrans.query).toBeCalledWith('BEGIN')
69
+ expect(trans.reader).toBeInstanceOf(Object)
70
+ expect(trans.reader.connect).toBeInstanceOf(Function)
71
+ expect(trans.writer).toBeInstanceOf(Object)
72
+ expect(trans.writer.connect).toBeInstanceOf(Function)
73
+ expect(trans).toBeInstanceOf(Function)
74
+ expect(trans['transaction']).toBe(mockTrans)
75
+ })
76
+ })
@@ -0,0 +1,118 @@
1
+ import { jest } from '@jest/globals'
2
+ import * as pg from 'pg'
3
+
4
+ import type { DbConfig } from '../../../../src/Database'
5
+ import { PostgresDatabase } from '../../../../src/Database/integrations/pgsql/PostgresDatabase'
6
+ import { PostgresTransactionImpl } from '../../../../src/Database/integrations/pgsql/PostgresTransaction'
7
+
8
+ const testResources = async (config: Partial<DbConfig<'pg'>>) => {
9
+ const database = {
10
+ config: {
11
+ autoCommit: true,
12
+ ...config,
13
+ } as DbConfig<'pg'>,
14
+ } as PostgresDatabase
15
+
16
+ const transaction = jest.fn().mockImplementation(() => {
17
+ return {
18
+ commit: jest.fn(),
19
+ rollback: jest.fn(),
20
+ query: jest.fn(),
21
+ }
22
+ })() as any as pg.PoolClient
23
+
24
+ const writer = jest.fn().mockImplementation(() => {
25
+ return {
26
+ connect: jest.fn(() => transaction),
27
+ }
28
+ })() as any as pg.Pool
29
+
30
+ return {
31
+ transaction,
32
+ writer,
33
+ underTest: await PostgresTransactionImpl.newTransaction(writer, database),
34
+ }
35
+ }
36
+
37
+ describe('PostgresTransaction', () => {
38
+ test('Transaction starts opened', async () => {
39
+ const { transaction, underTest } = await testResources({})
40
+ expect(underTest.isOpen()).toBe(true)
41
+ expect(transaction.query).toHaveBeenNthCalledWith(1, 'BEGIN')
42
+
43
+ await expect(underTest.begin).rejects.toThrowError(
44
+ 'Cannot begin, transaction is already opened!'
45
+ )
46
+ })
47
+
48
+ test('Can only commit once', async () => {
49
+ const { transaction, underTest } = await testResources({})
50
+ await underTest.commit()
51
+ expect(underTest.isOpen()).toBe(false)
52
+ expect(transaction.query).toBeCalledWith('COMMIT')
53
+
54
+ await expect(underTest.commit).rejects.toThrowError(
55
+ 'Cannot commit, transaction is already closed!'
56
+ )
57
+ })
58
+
59
+ test('Can only rollback once', async () => {
60
+ const { transaction, underTest } = await testResources({})
61
+ await underTest.rollback()
62
+ expect(underTest.isOpen()).toBe(false)
63
+ expect(transaction.query).toBeCalledWith('ROLLBACK')
64
+
65
+ await expect(underTest.rollback).rejects.toThrowError(
66
+ 'Cannot rollback, transaction is already closed!'
67
+ )
68
+ })
69
+
70
+ test("Can't open transaction twice", async () => {
71
+ const { transaction, underTest } = await testResources({})
72
+ expect(underTest.isOpen()).toBe(true)
73
+ expect(transaction.query).toHaveBeenNthCalledWith(1, 'BEGIN')
74
+
75
+ await expect(underTest.begin).rejects.toThrowError(
76
+ 'Cannot begin, transaction is already opened!'
77
+ )
78
+ })
79
+
80
+ test('Can commit, begin and commit again ', async () => {
81
+ const { transaction, underTest } = await testResources({})
82
+ await underTest.commit()
83
+ expect(underTest.isOpen()).toBe(false)
84
+ expect(transaction.query).toBeCalledWith('COMMIT')
85
+ await underTest.begin()
86
+ expect(underTest.isOpen()).toBe(true)
87
+ expect(transaction.query).toHaveBeenNthCalledWith(3, 'BEGIN')
88
+ await underTest.commit()
89
+ expect(underTest.isOpen()).toBe(false)
90
+ expect(transaction.query).toHaveBeenNthCalledWith(4, 'COMMIT')
91
+ })
92
+
93
+ test('Can commit, begin and rollback ', async () => {
94
+ const { transaction, underTest } = await testResources({})
95
+ await underTest.commit()
96
+ expect(underTest.isOpen()).toBe(false)
97
+ expect(transaction.query).toBeCalledWith('COMMIT')
98
+ await underTest.begin()
99
+ expect(underTest.isOpen()).toBe(true)
100
+ expect(transaction.query).toHaveBeenNthCalledWith(3, 'BEGIN')
101
+ await underTest.rollback()
102
+ expect(underTest.isOpen()).toBe(false)
103
+ expect(transaction.query).toHaveBeenNthCalledWith(4, 'ROLLBACK')
104
+ })
105
+
106
+ test('Can rollback, begin and commit ', async () => {
107
+ const { transaction, underTest } = await testResources({})
108
+ await underTest.rollback()
109
+ expect(underTest.isOpen()).toBe(false)
110
+ expect(transaction.query).toBeCalledWith('ROLLBACK')
111
+ await underTest.begin()
112
+ expect(underTest.isOpen()).toBe(true)
113
+ expect(transaction.query).toHaveBeenNthCalledWith(3, 'BEGIN')
114
+ await underTest.commit()
115
+ expect(underTest.isOpen()).toBe(false)
116
+ expect(transaction.query).toHaveBeenNthCalledWith(4, 'COMMIT')
117
+ })
118
+ })
@@ -0,0 +1,219 @@
1
+ import { jest } from '@jest/globals'
2
+ import { expect as c_expect } from 'chai'
3
+
4
+ // get console ref and mock before logger import
5
+ const consoleProxy = console
6
+ const mock = jest.spyOn(consoleProxy, 'log')
7
+ // import logger after first ref
8
+ import Logger from '../../src/Logger/Logger'
9
+ // get console reference after logger import
10
+ const transactionID = '123-456'
11
+
12
+ function setContainerFlag(isContainer: boolean) {
13
+ if (isContainer) {
14
+ process.env['HYBRIDLESS_RUNTIME'] = 'true'
15
+ } else {
16
+ process.env['HYBRIDLESS_RUNTIME'] = undefined
17
+ }
18
+ }
19
+
20
+ function fixLogTypePrefix(logType: string) {
21
+ if (logType == 'exception') return 'error'
22
+ if (logType == 'warning') return 'warn'
23
+ if (logType == 'log') return 'info'
24
+ return logType
25
+ }
26
+
27
+ function randomDeepObject(count, endKey) {
28
+ if (count <= 1) return { [endKey]: 'value' }
29
+ const object = {}
30
+ for (let i = 0; i < count; i++) {
31
+ const key = (+new Date() * Math.random()).toString(36).substring(0, 6)
32
+ object[key] = randomDeepObject(Math.floor(Math.random() * (count / 2)), endKey)
33
+ }
34
+ return object
35
+ }
36
+
37
+ function testLogs(isContainer: boolean, provider?: Logger) {
38
+ const type = isContainer ? 'container' : 'serverless'
39
+ const loggerType = !provider ? 'Console' : 'Logger'
40
+ const localProvider = provider || console
41
+
42
+ test(`${type} - ${loggerType} Log - Suppress sensitive info`, async () => {
43
+ setContainerFlag(isContainer)
44
+ localProvider.log('my password is 123')
45
+ expect(consoleProxy.log).toHaveBeenNthCalledWith(
46
+ 1,
47
+ expect.stringContaining((isContainer ? `${transactionID} ` : '') + '[INFO] [Logger.test.ts:')
48
+ )
49
+ expect(consoleProxy.log).toHaveBeenNthCalledWith(
50
+ 1,
51
+ expect.stringContaining('] my password is 123')
52
+ )
53
+ })
54
+
55
+ test(`${type} - ${loggerType} Log - Suppress sensitive info (object)`, async () => {
56
+ setContainerFlag(isContainer)
57
+ const object = { password: '123' }
58
+ localProvider.log('TEST', object)
59
+ expect(consoleProxy.log).toHaveBeenNthCalledWith(
60
+ 1,
61
+ expect.stringContaining((isContainer ? `${transactionID} ` : '') + '[INFO] [Logger.test.ts:')
62
+ )
63
+ expect(consoleProxy.log).toHaveBeenNthCalledWith(
64
+ 1,
65
+ expect.stringContaining('] TEST {\n "password": "**SUPPRESSED_SENSITIVE_DATA** (3 len)"\n}')
66
+ )
67
+ // test if object is not mutate
68
+ c_expect(object.password).to.be.equals('123')
69
+ })
70
+
71
+ test(`${type} - ${loggerType} Log - Suppress sensitive info (long-object)`, async () => {
72
+ setContainerFlag(isContainer)
73
+ const object = randomDeepObject(99, 'password')
74
+ localProvider.log('TEST', object)
75
+ expect(consoleProxy.log).toHaveBeenNthCalledWith(
76
+ 1,
77
+ expect.stringContaining((isContainer ? `${transactionID} ` : '') + '[INFO] [Logger.test.ts:')
78
+ )
79
+ expect(consoleProxy.log).toHaveBeenNthCalledWith(1, expect.stringContaining('] TEST'))
80
+ expect(consoleProxy.log).toHaveBeenNthCalledWith(
81
+ 1,
82
+ expect.stringContaining('"password": "**SUPPRESSED_SENSITIVE_DATA** (5 len)"')
83
+ )
84
+ })
85
+
86
+ test(`${type} - ${loggerType} Log - Suppress sensitive info (object with sensitive string)`, async () => {
87
+ setContainerFlag(isContainer)
88
+ localProvider.log({ object: JSON.stringify({ password: '123' }) })
89
+ expect(consoleProxy.log).toHaveBeenNthCalledWith(
90
+ 1,
91
+ expect.stringContaining((isContainer ? `${transactionID} ` : '') + '[INFO] [Logger.test.ts:')
92
+ )
93
+ expect(consoleProxy.log).toHaveBeenNthCalledWith(
94
+ 1,
95
+ expect.stringContaining(
96
+ '] {\n "object": {\n "password": "**SUPPRESSED_SENSITIVE_DATA** (3 len)"\n }\n}'
97
+ )
98
+ )
99
+ })
100
+
101
+ test(`${type} - ${loggerType} Log - Suppress sensitive info (object with sensitive number)`, async () => {
102
+ setContainerFlag(isContainer)
103
+ localProvider.log({ object: JSON.stringify({ password: 123 }) })
104
+ expect(consoleProxy.log).toHaveBeenNthCalledWith(
105
+ 1,
106
+ expect.stringContaining((isContainer ? `${transactionID} ` : '') + '[INFO] [Logger.test.ts:')
107
+ )
108
+ expect(consoleProxy.log).toHaveBeenNthCalledWith(
109
+ 1,
110
+ expect.stringContaining(
111
+ '] {\n "object": {\n "password": "**SUPPRESSED_SENSITIVE_DATA** (3 len)"\n }\n}'
112
+ )
113
+ )
114
+ })
115
+
116
+ test(`${type} - ${loggerType} Log - Suppress sensitive info (null key)`, async () => {
117
+ setContainerFlag(isContainer)
118
+ localProvider.log({ object: JSON.stringify({ password: null }) })
119
+ expect(consoleProxy.log).toHaveBeenNthCalledWith(
120
+ 1,
121
+ expect.stringContaining((isContainer ? `${transactionID} ` : '') + '[INFO] [Logger.test.ts:')
122
+ )
123
+ expect(consoleProxy.log).toHaveBeenNthCalledWith(
124
+ 1,
125
+ expect.stringContaining('] {\n "object": {\n "password": null\n }\n}')
126
+ )
127
+ })
128
+
129
+ test(`${type} - ${loggerType} Log - Suppress sensitive info (null)`, async () => {
130
+ setContainerFlag(isContainer)
131
+ localProvider.log(null)
132
+ expect(consoleProxy.log).toHaveBeenNthCalledWith(
133
+ 1,
134
+ expect.stringContaining((isContainer ? `${transactionID} ` : '') + '[INFO] [Logger.test.ts:')
135
+ )
136
+ expect(consoleProxy.log).toHaveBeenNthCalledWith(1, expect.stringContaining('] '))
137
+ })
138
+
139
+ test(`${type} - ${loggerType} Log - Suppress sensitive info (array)`, async () => {
140
+ setContainerFlag(isContainer)
141
+ localProvider.log('TEST2', [{ password: '1234' }])
142
+ expect(consoleProxy.log).toHaveBeenNthCalledWith(
143
+ 1,
144
+ expect.stringContaining((isContainer ? `${transactionID} ` : '') + '[INFO] [Logger.test.ts:')
145
+ )
146
+ expect(consoleProxy.log).toHaveBeenNthCalledWith(
147
+ 1,
148
+ expect.stringContaining(
149
+ '] TEST2 [\n {\n "password": "**SUPPRESSED_SENSITIVE_DATA** (4 len)"\n }\n]'
150
+ )
151
+ )
152
+ })
153
+
154
+ test(`${type} - ${loggerType} Log - Circular reference (Error)`, async () => {
155
+ setContainerFlag(isContainer)
156
+ class SelfRefError extends Error {
157
+ self: SelfRefError
158
+ constructor() {
159
+ super()
160
+ this.self = this
161
+ }
162
+ }
163
+ localProvider.log(new SelfRefError())
164
+ expect(consoleProxy.log).toHaveBeenNthCalledWith(
165
+ 1,
166
+ expect.stringContaining((isContainer ? `${transactionID} ` : '') + '[INFO] [Logger.test.ts:')
167
+ )
168
+ expect(consoleProxy.log).toHaveBeenNthCalledWith(
169
+ 1,
170
+ expect.stringContaining('[INFO] [Logger.test.ts:')
171
+ )
172
+ expect(consoleProxy.log).toHaveBeenNthCalledWith(
173
+ 1,
174
+ expect.stringContaining('] {\n' + ' "self": "[Circular ~]"\n' + '}')
175
+ )
176
+ })
177
+
178
+ for (const logType of ['log', 'debug', 'info', 'warn', 'warning', 'error', 'exception']) {
179
+ test(`${type} - ${loggerType} ${logType}`, async () => {
180
+ setContainerFlag(isContainer)
181
+ localProvider[logType](logType.toUpperCase())
182
+ // alias
183
+ const logTypePrefix = fixLogTypePrefix(logType)
184
+ expect(consoleProxy.log).toHaveBeenNthCalledWith(
185
+ 1,
186
+ expect.stringContaining(
187
+ (isContainer ? `${transactionID} ` : '') +
188
+ `[${logTypePrefix.toUpperCase()}] [Logger.test.ts:`
189
+ )
190
+ )
191
+ expect(consoleProxy.log).toHaveBeenNthCalledWith(
192
+ 1,
193
+ expect.stringContaining(`] ${logType.toUpperCase()}`)
194
+ )
195
+ })
196
+ }
197
+ }
198
+
199
+ describe('Logger', () => {
200
+ beforeEach(() => {
201
+ mock.mockClear()
202
+ })
203
+ const provider = new Logger(
204
+ {
205
+ logLevel: 'DEBUG',
206
+ sensitiveFilteringKeywords: true,
207
+ },
208
+ transactionID
209
+ )
210
+ provider.notGlobalLogger()
211
+ // Test serverless logs
212
+ testLogs(false, provider)
213
+ testLogs(false)
214
+ // Test container logs
215
+ testLogs(true, provider)
216
+ testLogs(true)
217
+ })
218
+
219
+ export {}
@@ -0,0 +1,59 @@
1
+ import { SESClient, SendRawEmailCommand } from '@aws-sdk/client-ses'
2
+ import { mockClient } from 'aws-sdk-client-mock'
3
+ import { expect } from 'chai'
4
+
5
+ import Mailer from '../../src/Mailer/Mailer'
6
+
7
+ const SESMock = mockClient(SESClient)
8
+
9
+ describe('SendRaw', () => {
10
+ // reset mock
11
+ beforeEach(() => {
12
+ SESMock.reset()
13
+ })
14
+
15
+ const provider = new Mailer('dev+tests@creator.co', 'ca-central-1')
16
+
17
+ test('Send raw with success', async () => {
18
+ const messageId = 'id-123'
19
+ SESMock.on(SendRawEmailCommand).resolves({
20
+ MessageId: messageId,
21
+ })
22
+ const res = await provider.sendRawEmail('test@test.com', 'My message', 'My subject')
23
+ expect(res).is.not.null
24
+ console.log(res)
25
+ })
26
+
27
+ test('Send raw with success', async () => {
28
+ const messageId = 'id-123'
29
+ const from = 'test@test.com'
30
+ const to = 'test@test2.com'
31
+ const msg = 'My message'
32
+ const subject = 'My subject'
33
+ const cc = 'test@test3.com'
34
+ const replyTo = 'test@test4.com'
35
+ SESMock.on(SendRawEmailCommand).resolves({
36
+ MessageId: messageId,
37
+ })
38
+ const res = await provider.sendRawEmail(to, msg, subject, cc, from, replyTo)
39
+ expect(res).is.not.null
40
+ console.log(res)
41
+ })
42
+
43
+ test('Send raw with failure', async () => {
44
+ SESMock.on(SendRawEmailCommand).rejects(new Error('failed!'))
45
+ let res: any = null,
46
+ err: any = null
47
+ try {
48
+ res = await provider.sendRawEmail('test@test.com', 'My message', 'My subject')
49
+ } catch (e) {
50
+ err = e
51
+ }
52
+ expect(res).is.null
53
+ expect(err?.message).to.be.equals('failed!')
54
+ expect(res).is.null
55
+ console.log(res)
56
+ })
57
+ })
58
+
59
+ export {}
@@ -0,0 +1,94 @@
1
+ import { SNSClient, PublishCommand } from '@aws-sdk/client-sns'
2
+ import { mockClient } from 'aws-sdk-client-mock'
3
+ import { expect } from 'chai'
4
+
5
+ import Publisher from '../../src/Publisher/Publisher'
6
+
7
+ const SNSMock = mockClient(SNSClient)
8
+
9
+ describe('SNS Pub-Sub', () => {
10
+ // reset mock
11
+ beforeEach(() => {
12
+ SNSMock.reset()
13
+ })
14
+
15
+ const provider = new Publisher({
16
+ region: 'ca-central-1',
17
+ })
18
+
19
+ test('Publishes with success', async () => {
20
+ const msg = { text: '123' }
21
+ const topic = '123'
22
+ const messageId = 'id-123'
23
+ SNSMock.on(PublishCommand, {
24
+ Message: JSON.stringify(msg),
25
+ TopicArn: topic,
26
+ }).resolves({
27
+ MessageId: messageId,
28
+ })
29
+ const res = await provider.publishOnTopic(msg, topic)
30
+ expect(res).is.not.null
31
+ expect(res?.MessageId).to.be.equals(messageId)
32
+ })
33
+
34
+ test('Publishes with success (additional props)', async () => {
35
+ const msg = { text: '123' }
36
+ const topic = '123'
37
+ const messageId = 'id-123'
38
+ SNSMock.on(PublishCommand, {
39
+ Message: JSON.stringify(msg),
40
+ TopicArn: topic,
41
+ }).resolves({
42
+ MessageId: messageId,
43
+ })
44
+ const res = await provider.publishOnTopic(msg, topic, {
45
+ FifoGroup: 123,
46
+ })
47
+ expect(res).is.not.null
48
+ expect(res?.MessageId).to.be.equals(messageId)
49
+ })
50
+
51
+ test('Publish failure', async () => {
52
+ const msg = { text: '123' }
53
+ const topic = '123'
54
+ SNSMock.on(PublishCommand).rejects(new Error('failed!'))
55
+ const res = await provider.publishOnTopic(msg, topic)
56
+ expect(res).is.undefined
57
+ })
58
+ })
59
+
60
+ describe('SNS SMS', () => {
61
+ // reset mock
62
+ beforeEach(() => {
63
+ SNSMock.reset()
64
+ })
65
+
66
+ const provider = new Publisher({
67
+ region: 'ca-central-1',
68
+ })
69
+
70
+ test('Publishes with success', async () => {
71
+ const msg = 'hello world'
72
+ const phoneNumber = '+16042001234'
73
+ const messageId = 'id-123'
74
+ SNSMock.on(PublishCommand, {
75
+ Message: msg,
76
+ PhoneNumber: phoneNumber,
77
+ }).resolves({
78
+ MessageId: messageId,
79
+ })
80
+ const res = await provider.publishSMS(msg, phoneNumber)
81
+ expect(res).is.not.null
82
+ expect(res?.MessageId).to.be.equals(messageId)
83
+ })
84
+
85
+ test('Publish failure', async () => {
86
+ const msg = 'hello world'
87
+ const phoneNumber = '+16042001234'
88
+ SNSMock.on(PublishCommand).rejects(new Error('failed!'))
89
+ const res = await provider.publishSMS(msg, phoneNumber)
90
+ expect(res).is.undefined
91
+ })
92
+ })
93
+
94
+ export {}