@kravc/dos 1.4.13 → 1.6.0

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kravc/dos",
3
- "version": "1.4.13",
3
+ "version": "1.6.0",
4
4
  "description": "Convention-based, easy-to-use library for building API-driven serverless services.",
5
5
  "keywords": [
6
6
  "Service",
@@ -25,10 +25,10 @@
25
25
  "author": "Alexander Kravets <a@kra.vc>",
26
26
  "license": "ISC",
27
27
  "dependencies": {
28
- "@kravc/schema": "^2.3.4",
28
+ "@kravc/schema": "^2.4.0",
29
29
  "cookie": "^0.5.0",
30
30
  "js-yaml": "^4.1.0",
31
- "jsonwebtoken": "^9.0.0",
31
+ "jsonwebtoken": "^9.0.2",
32
32
  "lodash.capitalize": "^4.2.1",
33
33
  "lodash.clonedeep": "^4.5.0",
34
34
  "lodash.compact": "^3.0.1",
@@ -44,12 +44,12 @@
44
44
  "lodash.uniq": "^4.5.0",
45
45
  "pluralize": "^8.0.0",
46
46
  "ulid": "^2.3.0",
47
- "uuid": "^9.0.0",
48
- "z-schema": "^5.0.5"
47
+ "uuid": "^9.0.1",
48
+ "z-schema": "^6.0.1"
49
49
  },
50
50
  "devDependencies": {
51
- "chai": "^4.3.7",
52
- "eslint": "^8.35.0",
51
+ "chai": "^4.3.10",
52
+ "eslint": "^8.51.0",
53
53
  "mocha": "^10.2.0",
54
54
  "nyc": "^15.1.0"
55
55
  },
package/src/Component.js CHANGED
@@ -1,5 +1,7 @@
1
1
  'use strict'
2
2
 
3
+ const asSafeClass = require('./helpers/asSafeClass')
4
+
3
5
  class Component {
4
6
  static get id() {
5
7
  return this.name
@@ -21,6 +23,8 @@ class Component {
21
23
  if (!this._validator) {
22
24
  throw new Error(`Validator is undefined for "${this.componentId}:${this.id}"`)
23
25
  }
26
+
27
+ return asSafeClass(this)
24
28
  }
25
29
 
26
30
  get context() {
@@ -52,4 +52,14 @@ describe('Component', () => {
52
52
  ).to.throw('"Profile" validation failed')
53
53
  })
54
54
  })
55
+
56
+ describe('.undefined', () => {
57
+ it('throw error if attributes or method is not defined by a class', () => {
58
+ const profile = new Profile({ validator }, { ...attributes, id: null })
59
+
60
+ expect(
61
+ () => profile.sex
62
+ ).to.throw('Undefined property or method: sex')
63
+ })
64
+ })
55
65
  })
package/src/Operation.js CHANGED
@@ -1,10 +1,12 @@
1
1
  'use strict'
2
2
 
3
- const isEmpty = require('lodash.isempty')
4
- const cloneDeep = require('lodash.clonedeep')
5
- const defaultId = require('./helpers/defaultId')
6
- const { Schema } = require('@kravc/schema')
7
- const defaultTags = require('./helpers/defaultTags')
3
+ const isEmpty = require('lodash.isempty')
4
+ const cloneDeep = require('lodash.clonedeep')
5
+ const { Schema } = require('@kravc/schema')
6
+
7
+ const defaultId = require('./helpers/defaultId')
8
+ const defaultTags = require('./helpers/defaultTags')
9
+ const asSafeClass = require('./helpers/asSafeClass')
8
10
  const defaultSummary = require('./helpers/defaultSummary')
9
11
 
10
12
  class Operation {
@@ -180,17 +182,20 @@ class Operation {
180
182
 
181
183
  constructor(context) {
182
184
  this._context = context
185
+
186
+ this._headers = {}
187
+ this._multiValueHeaders = {}
188
+
189
+ return asSafeClass(this)
183
190
  }
184
191
 
185
192
  setHeader(name, value, isMultiValue = false) {
186
193
  if (isMultiValue) {
187
- this._multiValueHeaders = this._headers || {}
188
194
  this._multiValueHeaders[name.toLowerCase()] = value
189
195
 
190
196
  return
191
197
  }
192
198
 
193
- this._headers = this._headers || {}
194
199
  this._headers[name.toLowerCase()] = value
195
200
  }
196
201
 
@@ -198,40 +203,56 @@ class Operation {
198
203
  return this._context
199
204
  }
200
205
 
206
+ before() {
207
+ return
208
+ }
209
+
201
210
  async action(parameters) {
202
211
  const { Component } = this.constructor
203
212
 
204
- if (!Component) { return }
213
+ if (!Component) {
214
+ return {}
215
+ }
205
216
 
206
217
  const { componentActionMethod } = this.constructor
207
218
 
208
219
  const { mutation, ...query } = parameters
209
220
 
210
- const data = await (mutation ?
211
- componentActionMethod(this.context, query, mutation) :
212
- componentActionMethod(this.context, query)
221
+ const data = await (mutation
222
+ ? componentActionMethod(this.context, query, mutation)
223
+ : componentActionMethod(this.context, query)
213
224
  )
214
225
 
215
226
  return { data }
216
227
  }
217
228
 
229
+ after() {
230
+ return
231
+ }
232
+
218
233
  async exec(_parameters) {
219
234
  let parameters = cloneDeep(_parameters)
220
235
  let result
221
236
 
222
- if (this.before) {
223
- const _ = await this.before(parameters)
224
- parameters = _ ? _ : parameters
225
- }
237
+ const beforeResult = await this.before(parameters)
238
+
239
+ parameters = beforeResult
240
+ ? beforeResult
241
+ : parameters
226
242
 
227
243
  result = await this.action(parameters)
228
244
 
229
- if (this.after) {
230
- const _ = await this.after(parameters, result.data || result)
231
- result = _ ? ( result.data ? { ...result, data: _ } : _ ) : result
232
- }
245
+ const afterResult = await this.after(parameters, result.data || result)
233
246
 
234
- return { result, headers: this._headers, multiValueHeaders: this._multiValueHeaders }
247
+ result = afterResult
248
+ ? ( result.data ? { ...result, data: afterResult } : afterResult )
249
+ : result
250
+
251
+ return {
252
+ result,
253
+ headers: this._headers,
254
+ multiValueHeaders: this._multiValueHeaders
255
+ }
235
256
  }
236
257
  }
237
258
 
@@ -468,7 +468,7 @@ describe('Operation', () => {
468
468
  it('supports dummy mode without defined "Component"', async () => {
469
469
  const { result } = await new Operation().exec()
470
470
 
471
- expect(result).to.not.exist
471
+ expect(result).to.be.empty
472
472
  })
473
473
  })
474
474
  })
@@ -0,0 +1,23 @@
1
+ 'use strict'
2
+
3
+ const asSafeClass = classTarget => {
4
+ // eslint-disable-next-line no-undef
5
+ return new Proxy(classTarget, {
6
+ get(target, prop) {
7
+ const isPropertyDefined = (prop in target)
8
+ const isThen = prop === 'then'
9
+
10
+ if (isThen) {
11
+ return undefined
12
+ }
13
+
14
+ if (!isPropertyDefined) {
15
+ throw new Error(`Undefined property or method: ${prop}`)
16
+ }
17
+
18
+ return target[prop]
19
+ }
20
+ })
21
+ }
22
+
23
+ module.exports = asSafeClass