@creator.co/wapi 1.2.1-beta5 → 1.2.2

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 (127) hide show
  1. package/.github/workflows/npmpublish.yml +11 -19
  2. package/.github/workflows/prs.yml +13 -0
  3. package/jest.config.ts +39 -0
  4. package/package.json +15 -4
  5. package/src/API/Request.ts +120 -10
  6. package/src/API/Response.ts +236 -8
  7. package/src/API/Utils.ts +56 -1
  8. package/src/BaseEvent/EventProcessor.ts +84 -11
  9. package/src/BaseEvent/Process.ts +62 -1
  10. package/src/BaseEvent/Transaction.ts +5 -8
  11. package/src/Config/Configuration.ts +111 -5
  12. package/src/Config/EnvironmentVar.ts +90 -1
  13. package/src/Crypto/Crypto.ts +77 -18
  14. package/src/Crypto/JWT.ts +49 -3
  15. package/src/Globals.ts +141 -3
  16. package/src/Logger/Logger.ts +173 -19
  17. package/src/Mailer/Mailer.ts +95 -0
  18. package/src/Publisher/Publisher.ts +50 -4
  19. package/src/Server/RouteResolver.ts +142 -0
  20. package/src/Server/Router.ts +77 -0
  21. package/src/Server/lib/ContainerServer.ts +48 -1
  22. package/src/Server/lib/Server.ts +78 -38
  23. package/src/Server/lib/container/GenericHandler.ts +7 -5
  24. package/src/Server/lib/container/GenericHandlerEvent.ts +59 -17
  25. package/src/Server/lib/container/HealthHandler.ts +1 -1
  26. package/src/Server/lib/container/Proxy.ts +92 -11
  27. package/src/Server/lib/container/Utils.ts +16 -25
  28. package/src/Validation/Validator.ts +18 -2
  29. package/tests/API/Request.test.ts +263 -0
  30. package/tests/API/Response.test.ts +372 -0
  31. package/tests/API/Utils.test.ts +157 -0
  32. package/tests/BaseEvent/EventProcessor.test.ts +278 -0
  33. package/tests/BaseEvent/Process.test.ts +49 -0
  34. package/tests/BaseEvent/Transaction.test.ts +231 -0
  35. package/tests/Config/Config.test.ts +193 -0
  36. package/tests/Config/EnvironmentVar.test.ts +223 -0
  37. package/tests/Crypto/Crypto.test.ts +90 -0
  38. package/tests/Crypto/JWT.test.ts +92 -0
  39. package/tests/Logger/Logger.test.ts +108 -0
  40. package/tests/Mailer/Mailer.test.ts +67 -0
  41. package/tests/Publisher/Publisher.test.ts +60 -0
  42. package/tests/Server/RouteResolver.test.ts +106 -0
  43. package/tests/Server/Router.test.ts +38 -0
  44. package/tests/Server/lib/ContainerServer.test.ts +329 -0
  45. package/tests/Server/lib/Server.test.ts +12 -0
  46. package/tests/Server/lib/container/GenericHandler.test.ts +141 -0
  47. package/tests/Server/lib/container/GenericHandlerEvent.test.ts +103 -0
  48. package/tests/Server/lib/container/HealthHandler.test.ts +30 -0
  49. package/tests/Server/lib/container/Proxy.test.ts +278 -0
  50. package/tests/Server/lib/container/Utils.test.ts +48 -0
  51. package/tests/Test.utils.ts +95 -0
  52. package/tests/Validation/Validator.test.ts +88 -0
  53. package/tests/main.test.ts +15 -0
  54. package/tsconfig.json +1 -0
  55. package/dist/index.d.ts +0 -11
  56. package/dist/index.js +0 -24
  57. package/dist/index.js.map +0 -1
  58. package/dist/package.json +0 -53
  59. package/dist/src/API/Request.d.ts +0 -21
  60. package/dist/src/API/Request.js +0 -86
  61. package/dist/src/API/Request.js.map +0 -1
  62. package/dist/src/API/Response.d.ts +0 -39
  63. package/dist/src/API/Response.js +0 -232
  64. package/dist/src/API/Response.js.map +0 -1
  65. package/dist/src/API/Utils.d.ts +0 -8
  66. package/dist/src/API/Utils.js +0 -49
  67. package/dist/src/API/Utils.js.map +0 -1
  68. package/dist/src/BaseEvent/EventProcessor.d.ts +0 -13
  69. package/dist/src/BaseEvent/EventProcessor.js +0 -151
  70. package/dist/src/BaseEvent/EventProcessor.js.map +0 -1
  71. package/dist/src/BaseEvent/Process.d.ts +0 -12
  72. package/dist/src/BaseEvent/Process.js +0 -114
  73. package/dist/src/BaseEvent/Process.js.map +0 -1
  74. package/dist/src/BaseEvent/Transaction.d.ts +0 -29
  75. package/dist/src/BaseEvent/Transaction.js +0 -248
  76. package/dist/src/BaseEvent/Transaction.js.map +0 -1
  77. package/dist/src/Config/Configuration.d.ts +0 -34
  78. package/dist/src/Config/Configuration.js +0 -93
  79. package/dist/src/Config/Configuration.js.map +0 -1
  80. package/dist/src/Config/EnvironmentVar.d.ts +0 -17
  81. package/dist/src/Config/EnvironmentVar.js +0 -152
  82. package/dist/src/Config/EnvironmentVar.js.map +0 -1
  83. package/dist/src/Crypto/Crypto.d.ts +0 -8
  84. package/dist/src/Crypto/Crypto.js +0 -84
  85. package/dist/src/Crypto/Crypto.js.map +0 -1
  86. package/dist/src/Crypto/JWT.d.ts +0 -16
  87. package/dist/src/Crypto/JWT.js +0 -49
  88. package/dist/src/Crypto/JWT.js.map +0 -1
  89. package/dist/src/Globals.d.ts +0 -21
  90. package/dist/src/Globals.js +0 -35
  91. package/dist/src/Globals.js.map +0 -1
  92. package/dist/src/Logger/Logger.d.ts +0 -34
  93. package/dist/src/Logger/Logger.js +0 -345
  94. package/dist/src/Logger/Logger.js.map +0 -1
  95. package/dist/src/Mailer/Mailer.d.ts +0 -12
  96. package/dist/src/Mailer/Mailer.js +0 -234
  97. package/dist/src/Mailer/Mailer.js.map +0 -1
  98. package/dist/src/Publisher/Publisher.d.ts +0 -10
  99. package/dist/src/Publisher/Publisher.js +0 -109
  100. package/dist/src/Publisher/Publisher.js.map +0 -1
  101. package/dist/src/Server/Router.d.ts +0 -27
  102. package/dist/src/Server/Router.js +0 -22
  103. package/dist/src/Server/Router.js.map +0 -1
  104. package/dist/src/Server/lib/ContainerServer.d.ts +0 -11
  105. package/dist/src/Server/lib/ContainerServer.js +0 -103
  106. package/dist/src/Server/lib/ContainerServer.js.map +0 -1
  107. package/dist/src/Server/lib/Server.d.ts +0 -9
  108. package/dist/src/Server/lib/Server.js +0 -141
  109. package/dist/src/Server/lib/Server.js.map +0 -1
  110. package/dist/src/Server/lib/container/GenericHandler.d.ts +0 -4
  111. package/dist/src/Server/lib/container/GenericHandler.js +0 -136
  112. package/dist/src/Server/lib/container/GenericHandler.js.map +0 -1
  113. package/dist/src/Server/lib/container/GenericHandlerEvent.d.ts +0 -14
  114. package/dist/src/Server/lib/container/GenericHandlerEvent.js +0 -164
  115. package/dist/src/Server/lib/container/GenericHandlerEvent.js.map +0 -1
  116. package/dist/src/Server/lib/container/HealthHandler.d.ts +0 -3
  117. package/dist/src/Server/lib/container/HealthHandler.js +0 -44
  118. package/dist/src/Server/lib/container/HealthHandler.js.map +0 -1
  119. package/dist/src/Server/lib/container/Proxy.d.ts +0 -15
  120. package/dist/src/Server/lib/container/Proxy.js +0 -157
  121. package/dist/src/Server/lib/container/Proxy.js.map +0 -1
  122. package/dist/src/Server/lib/container/Utils.d.ts +0 -6
  123. package/dist/src/Server/lib/container/Utils.js +0 -109
  124. package/dist/src/Server/lib/container/Utils.js.map +0 -1
  125. package/dist/src/Validation/Validator.d.ts +0 -5
  126. package/dist/src/Validation/Validator.js +0 -31
  127. package/dist/src/Validation/Validator.js.map +0 -1
package/src/API/Utils.ts CHANGED
@@ -1,14 +1,52 @@
1
+ /**
2
+ * ${1:Description placeholder}
3
+ *
4
+ * @export
5
+ * @class Utils
6
+ * @typedef {Utils}
7
+ */
1
8
  export default class Utils {
9
+ /**
10
+ * ${1:Description placeholder}
11
+ *
12
+ * @public
13
+ * @static
14
+ * @returns {boolean}
15
+ */
2
16
  public static isHybridlessContainer(): boolean {
3
- return !!process.env.HYBRIDLESS_RUNTIME
17
+ return process.env.HYBRIDLESS_RUNTIME == "true"
4
18
  }
19
+ /**
20
+ * ${1:Description placeholder}
21
+ *
22
+ * @public
23
+ * @static
24
+ * @param {string} string
25
+ * @returns {boolean}
26
+ */
5
27
  public static isValidString(string: string): boolean {
6
28
  return string?.length > 0 && !Array.isArray(string)
7
29
  }
30
+ /**
31
+ * ${1:Description placeholder}
32
+ *
33
+ * @public
34
+ * @static
35
+ * @param {string} string
36
+ * @returns {(number | null)}
37
+ */
8
38
  public static parseIntNullIfNaN(string: string): number | null {
9
39
  const n = parseInt(string)
10
40
  return isNaN(n) ? null : n
11
41
  }
42
+ /**
43
+ * ${1:Description placeholder}
44
+ *
45
+ * @public
46
+ * @static
47
+ * @param {string} string
48
+ * @returns {(any | null)}
49
+ */
12
50
  public static parseObjectNullIfEmpty(string: string): any | null {
13
51
  let o = null
14
52
  try {
@@ -19,6 +57,14 @@ export default class Utils {
19
57
  }
20
58
  return o
21
59
  }
60
+ /**
61
+ * ${1:Description placeholder}
62
+ *
63
+ * @public
64
+ * @static
65
+ * @param {string} number
66
+ * @returns {boolean}
67
+ */
22
68
  public static isValidNumber(number: string): boolean {
23
69
  let validNumb = NaN
24
70
  try {
@@ -28,6 +74,15 @@ export default class Utils {
28
74
  }
29
75
  return !isNaN(validNumb) && !Array.isArray(number)
30
76
  }
77
+ /**
78
+ * ${1:Description placeholder}
79
+ *
80
+ * @public
81
+ * @static
82
+ * @param {*} obj
83
+ * @param {string} key
84
+ * @returns {(any | null)}
85
+ */
31
86
  public static caseInsensitiveObjectForKey(obj: any, key: string): any | null {
32
87
  if (!obj) return null
33
88
  const insensitiveKey = Object.keys(obj).find(
@@ -5,29 +5,93 @@ import Response, { ResponseErrorType } from "../API/Response"
5
5
  import Globals from "../Globals"
6
6
 
7
7
  // Handler
8
- export type EventProcessorExecution = (
9
- transaction: Transaction<null, ResponseErrorType, SQSBatchResponse>,
8
+ /**
9
+ * ${1:Description placeholder}
10
+ *
11
+ * @export
12
+ * @typedef {EventProcessorExecution}
13
+ * @template ResponseInnerType
14
+ */
15
+ export type EventProcessorExecution<ResponseInnerType> = (
16
+ transaction: Transaction<
17
+ null,
18
+ ResponseInnerType | ResponseErrorType,
19
+ SQSBatchResponse
20
+ >,
10
21
  recordContent: string | object,
11
- ) => Promise<Response | SQSBatchResponse>
22
+ ) => Promise<Response<ResponseInnerType | ResponseErrorType> | SQSBatchResponse>
12
23
 
13
- export default class EventProcessor {
24
+ /**
25
+ * ${1:Description placeholder}
26
+ *
27
+ * @export
28
+ * @class EventProcessor
29
+ * @typedef {EventProcessor}
30
+ * @template ResponseInnerType
31
+ */
32
+ export default class EventProcessor<ResponseInnerType> {
33
+ /**
34
+ * ${1:Description placeholder}
35
+ *
36
+ * @private
37
+ * @readonly
38
+ * @type {boolean}
39
+ */
14
40
  private readonly _allowFailure: boolean
41
+ /**
42
+ * ${1:Description placeholder}
43
+ *
44
+ * @private
45
+ * @readonly
46
+ * @type {TransactionConfig}
47
+ */
15
48
  private readonly _apiConfig: TransactionConfig
49
+ /**
50
+ * ${1:Description placeholder}
51
+ *
52
+ * @private
53
+ * @readonly
54
+ * @type {Context}
55
+ */
16
56
  private readonly _context: Context
57
+ /**
58
+ * ${1:Description placeholder}
59
+ *
60
+ * @private
61
+ * @readonly
62
+ * @type {SQSEvent}
63
+ */
17
64
  private readonly _event: SQSEvent
65
+ /**
66
+ * Creates an instance of EventProcessor.
67
+ *
68
+ * @constructor
69
+ * @param {SQSEvent} event
70
+ * @param {Context} context
71
+ * @param {?TransactionConfig} [config]
72
+ * @param {?boolean} [allowFailure]
73
+ */
18
74
  constructor(
19
75
  event: SQSEvent,
20
76
  context: Context,
21
- config: TransactionConfig,
77
+ config?: TransactionConfig,
22
78
  allowFailure?: boolean,
23
79
  ) {
24
80
  this._event = event
25
81
  this._context = context
26
- this._apiConfig = config
82
+ this._apiConfig = config || {}
27
83
  this._allowFailure = allowFailure
28
84
  }
85
+ /**
86
+ * ${1:Description placeholder}
87
+ *
88
+ * @async
89
+ * @param {EventProcessorExecution<ResponseInnerType>} execution
90
+ * @param {?boolean} [doNotDecodeMessage]
91
+ * @returns {(Promise<Response<ResponseErrorType> | null | SQSBatchResponse>)}
92
+ */
29
93
  async processEvent(
30
- execution: EventProcessorExecution,
94
+ execution: EventProcessorExecution<ResponseInnerType>,
31
95
  doNotDecodeMessage?: boolean,
32
96
  ): Promise<Response<ResponseErrorType> | null | SQSBatchResponse> {
33
97
  const resp = await this._processRawEvent(execution, !!doNotDecodeMessage)
@@ -37,12 +101,20 @@ export default class EventProcessor {
37
101
  resp instanceof Response &&
38
102
  !(resp.getCode() >= 200 && resp.getCode() < 300)
39
103
  )
40
- throw new Error(JSON.stringify(resp.getBody()))
104
+ throw new Error(JSON.stringify(resp.getBody() || {}))
41
105
  else if (resp) return resp
42
106
  return null
43
107
  }
108
+ /**
109
+ * ${1:Description placeholder}
110
+ *
111
+ * @async
112
+ * @param {EventProcessorExecution<ResponseInnerType>} execution
113
+ * @param {boolean} doNotDecodeMessage
114
+ * @returns {(Promise<Response<ResponseErrorType> | null | SQSBatchResponse>)}
115
+ */
44
116
  async _processRawEvent(
45
- execution: EventProcessorExecution,
117
+ execution: EventProcessorExecution<ResponseInnerType>,
46
118
  doNotDecodeMessage: boolean,
47
119
  ): Promise<Response<ResponseErrorType> | null | SQSBatchResponse> {
48
120
  if (this._event.Records && this._event.Records.length > 0) {
@@ -73,8 +145,9 @@ export default class EventProcessor {
73
145
  const resp = await execution(transaction, eventRecord)
74
146
  //check for failure
75
147
  if (
76
- resp instanceof Response &&
77
- !(resp.getCode() >= 200 && resp.getCode() < 300)
148
+ !resp ||
149
+ (resp instanceof Response &&
150
+ !(resp?.getCode() >= 200 && resp?.getCode() < 300))
78
151
  ) {
79
152
  //response with failures or fail hard at first
80
153
  if (this._allowFailure) failureIDs.push(message.messageId)
@@ -3,16 +3,63 @@ import Logger from "../Logger/Logger"
3
3
  import Publisher from "../Publisher/Publisher"
4
4
 
5
5
  // Config
6
+ /**
7
+ * ${1:Description placeholder}
8
+ *
9
+ * @export
10
+ * @typedef {ProcessConfig}
11
+ */
6
12
  export type ProcessConfig = Omit<
7
13
  TransactionConfig,
8
14
  "throwOnErrors" | "syncReturn"
9
15
  >
10
16
 
17
+ /**
18
+ * ${1:Description placeholder}
19
+ *
20
+ * @export
21
+ * @class Process
22
+ * @typedef {Process}
23
+ */
11
24
  export default class Process {
25
+ /**
26
+ * ${1:Description placeholder}
27
+ *
28
+ * @private
29
+ * @type {number}
30
+ */
12
31
  private _interval: number
13
32
  //
33
+ /**
34
+ * ${1:Description placeholder}
35
+ *
36
+ * @public
37
+ * @readonly
38
+ * @type {Logger}
39
+ */
14
40
  public readonly logger: Logger
41
+ /**
42
+ * ${1:Description placeholder}
43
+ *
44
+ * @public
45
+ * @readonly
46
+ * @type {Publisher}
47
+ */
15
48
  public readonly publisher: Publisher
49
+ /**
50
+ * ${1:Description placeholder}
51
+ *
52
+ * @public
53
+ * @type {NodeJS.Timeout}
54
+ */
55
+ public interval: NodeJS.Timeout
56
+ /**
57
+ * Creates an instance of Process.
58
+ *
59
+ * @constructor
60
+ * @param {ProcessConfig} config
61
+ * @param {number} interval
62
+ */
16
63
  constructor(config: ProcessConfig, interval: number) {
17
64
  this._interval = interval
18
65
  this.logger = new Logger(config.logger, "long-running-process")
@@ -20,16 +67,30 @@ export default class Process {
20
67
  }
21
68
 
22
69
  //Main interface
70
+ /**
71
+ * ${1:Description placeholder}
72
+ *
73
+ * @async
74
+ * @param {*} executionFunc
75
+ * @returns {*}
76
+ */
23
77
  async execute(executionFunc) {
24
78
  this.logger.debug("Starting main process code")
25
79
  //Connect DB
26
80
  // if (this.db) await this.db.connect();
27
81
  //Program loop
28
- setInterval(async () => {
82
+ this.interval = setInterval(async () => {
29
83
  await this._execute(executionFunc)
30
84
  }, this._interval)
31
85
  }
32
86
  //Executions
87
+ /**
88
+ * ${1:Description placeholder}
89
+ *
90
+ * @async
91
+ * @param {*} executionFunc
92
+ * @returns {unknown}
93
+ */
33
94
  async _execute(executionFunc) {
34
95
  let executionFailed = true //failled til we say no!
35
96
  //safe execution handler
@@ -126,13 +126,11 @@ export default class Transaction<
126
126
  //retrow?
127
127
  if (this.retrowErrors) throw e
128
128
  //envelope exception?
129
- if (executionFailed) {
130
- this.response = this.getErrorResponse(
131
- Globals.ErrorResponseUnhandledError,
132
- Globals.ErrorCode_APIError,
133
- )
134
- await this.response.build(this.context, this, this.syncReturn)
135
- }
129
+ this.response = this.getErrorResponse(
130
+ Globals.ErrorResponseUnhandledError,
131
+ Globals.ErrorCode_APIError,
132
+ )
133
+ await this.response.build(this.context, this, this.syncReturn)
136
134
  }
137
135
  return executionFailed
138
136
  }
@@ -164,7 +162,6 @@ export default class Transaction<
164
162
  private async executeLoggerFlush(safeExecution) {
165
163
  try {
166
164
  await safeExecution()
167
- await this.logger.flushLogs()
168
165
  } catch (e) {
169
166
  this.logger.error("Exception when flushing logs.")
170
167
  this.logger.exception(e)
@@ -4,8 +4,20 @@ import * as DurationParser from "parse-duration"
4
4
  import EnvironmentVar, { EnvironmentType } from "./EnvironmentVar"
5
5
 
6
6
  // Hold cached values at nodeVM level
7
- const cacheStore = new MemCache()
7
+ // eslint-disable-next-line no-var
8
+ /**
9
+ * ${1:Description placeholder}
10
+ *
11
+ * @type {*}
12
+ */
13
+ let cacheStore = new MemCache()
8
14
 
15
+ /**
16
+ * ${1:Description placeholder}
17
+ *
18
+ * @export
19
+ * @typedef {ConfigurationSchema}
20
+ */
9
21
  export type ConfigurationSchema = {
10
22
  [name: string]: {
11
23
  isLocal?: boolean
@@ -16,6 +28,12 @@ export type ConfigurationSchema = {
16
28
  }
17
29
 
18
30
  // runtime type infer to ConfigurationSchema keys, which type is remote
31
+ /**
32
+ * ${1:Description placeholder}
33
+ *
34
+ * @typedef {ExtractRemote}
35
+ * @template Type
36
+ */
19
37
  type ExtractRemote<Type> = {
20
38
  [Property in keyof Type]-?: Type[Property] extends {
21
39
  isRemote: true
@@ -24,6 +42,12 @@ type ExtractRemote<Type> = {
24
42
  : null
25
43
  }
26
44
  // runtime type infer to ConfigurationSchema keys, which type is local
45
+ /**
46
+ * ${1:Description placeholder}
47
+ *
48
+ * @typedef {ExtractLocal}
49
+ * @template Type
50
+ */
27
51
  type ExtractLocal<Type> = {
28
52
  [Property in keyof Type]-?: Type[Property] extends {
29
53
  isLocal: true
@@ -33,25 +57,75 @@ type ExtractLocal<Type> = {
33
57
  }
34
58
 
35
59
  // Helpers to filter null keys
60
+ /**
61
+ * ${1:Description placeholder}
62
+ *
63
+ * @typedef {OmitKeysByValueType}
64
+ * @template T
65
+ * @template U
66
+ */
36
67
  type OmitKeysByValueType<T, U> = {
37
68
  [P in keyof T]: T[P] extends U ? never : P
38
69
  }[keyof T]
39
70
 
40
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
41
- type OmitByValueType<T, V> = T extends infer _
71
+ /**
72
+ * ${1:Description placeholder}
73
+ *
74
+ * @typedef {OmitByValueType}
75
+ * @template T
76
+ * @template V
77
+ */
78
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars, prettier/prettier
79
+ type OmitByValueType<T, V> = T extends infer _
42
80
  ? {
43
81
  [key in OmitKeysByValueType<T, V>]: T[key]
44
82
  }
45
83
  : never
46
84
 
85
+ /**
86
+ * ${1:Description placeholder}
87
+ *
88
+ * @export
89
+ * @class Configuration
90
+ * @typedef {Configuration}
91
+ * @template {ConfigurationSchema} T
92
+ */
47
93
  export default class Configuration<T extends ConfigurationSchema> {
94
+ /**
95
+ * ${1:Description placeholder}
96
+ *
97
+ * @private
98
+ * @readonly
99
+ * @type {T}
100
+ */
48
101
  private readonly schema: T
102
+ /**
103
+ * ${1:Description placeholder}
104
+ *
105
+ * @private
106
+ * @readonly
107
+ * @type {string}
108
+ */
49
109
  private readonly remotePrefix: string
110
+ /**
111
+ * Creates an instance of Configuration.
112
+ *
113
+ * @constructor
114
+ * @param {T} schema
115
+ * @param {string} remotePrefix
116
+ */
50
117
  constructor(schema: T, remotePrefix: string) {
51
118
  this.schema = schema
52
119
  this.remotePrefix = remotePrefix
53
120
  }
54
121
 
122
+ /**
123
+ * ${1:Description placeholder}
124
+ *
125
+ * @public
126
+ * @param {keyof OmitByValueType<ExtractLocal<T>, null>} propName
127
+ * @returns {*}
128
+ */
55
129
  public get(propName: keyof OmitByValueType<ExtractLocal<T>, null>): any {
56
130
  const propString = propName as string
57
131
  const propSchema = this.schema[propString]
@@ -61,12 +135,20 @@ export default class Configuration<T extends ConfigurationSchema> {
61
135
  new EnvironmentVar<string>(
62
136
  propString,
63
137
  EnvironmentType.Local,
64
- propSchema.required,
138
+ !propSchema.required,
65
139
  this.remotePrefix,
66
140
  ).syncResolve()
67
141
  this.cacheValue(propString, v, propSchema.cachingPolicy)
68
142
  return v
69
143
  }
144
+ /**
145
+ * ${1:Description placeholder}
146
+ *
147
+ * @public
148
+ * @async
149
+ * @param {keyof OmitByValueType<ExtractRemote<T>, null>} propName
150
+ * @returns {Promise<any>}
151
+ */
70
152
  public async asyncGet(
71
153
  propName: keyof OmitByValueType<ExtractRemote<T>, null>,
72
154
  ): Promise<any> {
@@ -78,16 +160,31 @@ export default class Configuration<T extends ConfigurationSchema> {
78
160
  (await new EnvironmentVar<string>(
79
161
  propString,
80
162
  EnvironmentType.PlainRemote,
81
- propSchema.required,
163
+ !propSchema.required,
82
164
  this.remotePrefix,
83
165
  ).resolve())
84
166
  this.cacheValue(propString, v, propSchema.cachingPolicy)
85
167
  return v
86
168
  }
87
169
  // caching layer
170
+ /**
171
+ * ${1:Description placeholder}
172
+ *
173
+ * @private
174
+ * @param {string} valueKey
175
+ * @returns {*}
176
+ */
88
177
  private getCachedValue(valueKey: string): any {
89
178
  return cacheStore.get(valueKey)
90
179
  }
180
+ /**
181
+ * ${1:Description placeholder}
182
+ *
183
+ * @private
184
+ * @param {string} valueKey
185
+ * @param {*} value
186
+ * @param {string} [policy="1d"]
187
+ */
91
188
  private cacheValue(
92
189
  valueKey: string,
93
190
  value: any,
@@ -95,4 +192,13 @@ export default class Configuration<T extends ConfigurationSchema> {
95
192
  ): void {
96
193
  cacheStore.set(valueKey, value, DurationParser(policy, "s"))
97
194
  }
195
+ // unit-test support
196
+ /**
197
+ * ${1:Description placeholder}
198
+ *
199
+ * @private
200
+ */
201
+ private resetCache() {
202
+ cacheStore = new MemCache()
203
+ }
98
204
  }
@@ -7,19 +7,75 @@ import { SSMClient, GetParameterCommand } from "@aws-sdk/client-ssm"
7
7
  // Explicity setting VM level variables in order to persist
8
8
  // client across different important and instances.
9
9
  // eslint-disable-next-line no-var
10
- var ssmClient = null,
10
+ /**
11
+ * ${1:Description placeholder}
12
+ *
13
+ * @type {*}
14
+ */
15
+ let ssmClient = null,
11
16
  secretsClient = null
12
17
 
18
+ /**
19
+ * ${1:Description placeholder}
20
+ *
21
+ * @export
22
+ * @enum {number}
23
+ */
13
24
  export enum EnvironmentType {
14
25
  PlainRemote,
15
26
  SecureRemote,
16
27
  Local,
17
28
  }
29
+ /**
30
+ * ${1:Description placeholder}
31
+ *
32
+ * @export
33
+ * @class EnvironmentVar
34
+ * @typedef {EnvironmentVar}
35
+ * @template T
36
+ */
18
37
  export default class EnvironmentVar<T> {
38
+ /**
39
+ * ${1:Description placeholder}
40
+ *
41
+ * @private
42
+ * @readonly
43
+ * @type {string}
44
+ */
19
45
  private readonly paramName: string
46
+ /**
47
+ * ${1:Description placeholder}
48
+ *
49
+ * @private
50
+ * @readonly
51
+ * @type {EnvironmentType}
52
+ */
20
53
  private readonly type: EnvironmentType
54
+ /**
55
+ * ${1:Description placeholder}
56
+ *
57
+ * @private
58
+ * @readonly
59
+ * @type {boolean}
60
+ */
21
61
  private readonly optional: boolean
62
+ /**
63
+ * ${1:Description placeholder}
64
+ *
65
+ * @private
66
+ * @readonly
67
+ * @type {string}
68
+ */
22
69
  private readonly paramPrefix: string
70
+ /**
71
+ * Creates an instance of EnvironmentVar.
72
+ *
73
+ * @constructor
74
+ * @param {string} paramName
75
+ * @param {EnvironmentType} type
76
+ * @param {?boolean} [optional]
77
+ * @param {string} [paramPrefix=`/creatorco-api-\${process.env.STAGE\}/env/`]
78
+ */
23
79
  constructor(
24
80
  paramName: string,
25
81
  type: EnvironmentType,
@@ -32,6 +88,12 @@ export default class EnvironmentVar<T> {
32
88
  this.paramPrefix = paramPrefix
33
89
  }
34
90
 
91
+ /**
92
+ * ${1:Description placeholder}
93
+ *
94
+ * @public
95
+ * @returns {T}
96
+ */
35
97
  public syncResolve(): T {
36
98
  if (this.type == EnvironmentType.Local) return this.getLocalValue()
37
99
  else {
@@ -40,6 +102,13 @@ export default class EnvironmentVar<T> {
40
102
  )
41
103
  }
42
104
  }
105
+ /**
106
+ * ${1:Description placeholder}
107
+ *
108
+ * @public
109
+ * @async
110
+ * @returns {unknown}
111
+ */
43
112
  public async resolve() {
44
113
  if (this.type == EnvironmentType.Local) return this.getLocalValue()
45
114
  else if (this.type == EnvironmentType.SecureRemote)
@@ -47,6 +116,12 @@ export default class EnvironmentVar<T> {
47
116
  else return this.getPlainValue()
48
117
  }
49
118
 
119
+ /**
120
+ * ${1:Description placeholder}
121
+ *
122
+ * @private
123
+ * @returns {T}
124
+ */
50
125
  private getLocalValue(): T {
51
126
  const value = process.env[this.paramName]
52
127
  if (!value && !this.optional) {
@@ -56,6 +131,13 @@ export default class EnvironmentVar<T> {
56
131
  }
57
132
  return value as T
58
133
  }
134
+ /**
135
+ * ${1:Description placeholder}
136
+ *
137
+ * @private
138
+ * @async
139
+ * @returns {Promise<T>}
140
+ */
59
141
  private async getPlainValue(): Promise<T> {
60
142
  if (!ssmClient) ssmClient = new SSMClient()
61
143
  const pName = `${this.paramPrefix}${this.paramName}`
@@ -72,6 +154,13 @@ export default class EnvironmentVar<T> {
72
154
  throw new Error(`Unable to retrieve plain remote env value: ${pName}`)
73
155
  }
74
156
  }
157
+ /**
158
+ * ${1:Description placeholder}
159
+ *
160
+ * @private
161
+ * @async
162
+ * @returns {Promise<T>}
163
+ */
75
164
  private async getSecureValue(): Promise<T> {
76
165
  if (!secretsClient) secretsClient = new SecretsManagerClient()
77
166
  const pName = `${this.paramPrefix}${this.paramName}`