@toa.io/extensions.exposition 1.0.0-alpha.197 → 1.0.0-alpha.198

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.
@@ -54,3 +54,34 @@ Feature: Dev
54
54
 
55
55
  "Invalid sleep duration"
56
56
  """
57
+
58
+ Scenario: Faulty mode
59
+ Given the annotation:
60
+ """yaml
61
+ /:
62
+ io:output: true
63
+ anonymous: true
64
+ dev:faulty: 1
65
+ GET:
66
+ dev:stub: hello
67
+ """
68
+ # CORS permission
69
+ When the following request is received:
70
+ """
71
+ OPTIONS / HTTP/1.1
72
+ origin: http://example.com
73
+ """
74
+ Then the following reply is sent:
75
+ """
76
+ 204 No Content
77
+ access-control-allow-headers: accept, authorization, content-type, if-match, if-none-match, faulty
78
+ """
79
+ When the following request is received:
80
+ """
81
+ GET / HTTP/1.1
82
+ faulty: 1
83
+ """
84
+ Then the following reply is sent:
85
+ """
86
+ 503 Service Unavailable
87
+ """
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@toa.io/extensions.exposition",
3
- "version": "1.0.0-alpha.197",
3
+ "version": "1.0.0-alpha.198",
4
4
  "description": "Toa Exposition",
5
5
  "author": "temich <tema.gurtovoy@gmail.com>",
6
6
  "homepage": "https://github.com/toa-io/toa#readme",
@@ -61,5 +61,5 @@
61
61
  },
62
62
  "testEnvironment": "node"
63
63
  },
64
- "gitHead": "630fc3af7de745d97f5c06a6c1b204f0cdf7d4c7"
64
+ "gitHead": "9138736f36096cb210f00056cf62fa25cb3eaca7"
65
65
  }
@@ -83,3 +83,9 @@ export class TooManyRequests extends ClientError {
83
83
  super(429)
84
84
  }
85
85
  }
86
+
87
+ export class ServiceUnavailable extends Exception {
88
+ public constructor (body?: any) {
89
+ super(503, body)
90
+ }
91
+ }
@@ -1,6 +1,7 @@
1
1
  import { Stub } from './Stub'
2
2
  import { Throw } from './Throw'
3
3
  import { Sleep } from './Sleep'
4
+ import { Faulty } from './Faulty'
4
5
  import { type Directive } from './types'
5
6
  import type { Input, Output } from '../../io'
6
7
  import type { DirectiveFamily } from '../../RTD'
@@ -36,5 +37,6 @@ export class Development implements DirectiveFamily<Directive> {
36
37
  const constructors: Record<string, new (value: any) => Directive> = {
37
38
  stub: Stub,
38
39
  throw: Throw,
39
- sleep: Sleep
40
+ sleep: Sleep,
41
+ faulty: Faulty
40
42
  }
@@ -0,0 +1,26 @@
1
+ import assert from 'node:assert'
2
+ import type { Directive } from './types'
3
+ import { ServiceUnavailable } from '../../HTTP'
4
+ import { Output } from '../../io'
5
+ import { cors } from '../cors'
6
+
7
+ export class Faulty implements Directive {
8
+ private static warned = false
9
+ private readonly probability: number
10
+
11
+ public constructor (probability: number) {
12
+ assert.ok(typeof probability === 'number', '`dev:faulty` directive value must be a number')
13
+ assert.ok(probability > 0 && probability <= 1, '`dev:faulty` directive value must be in the range (0, 1]')
14
+
15
+ this.probability = probability
16
+
17
+ cors.allow('faulty')
18
+ }
19
+
20
+ public async apply (): Promise<Output> {
21
+ if (Math.random() > this.probability)
22
+ return null
23
+
24
+ throw new ServiceUnavailable()
25
+ }
26
+ }