@open-nav/mock-server 0.1.0 → 0.1.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/server.d.ts +15 -0
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +14 -0
- package/dist/server.js.map +1 -1
- package/dist/state.d.ts +2 -0
- package/dist/state.d.ts.map +1 -1
- package/dist/state.js +1 -0
- package/dist/state.js.map +1 -1
- package/package.json +3 -3
- package/src/server.ts +32 -0
- package/src/state.ts +3 -0
package/dist/server.d.ts
CHANGED
|
@@ -21,6 +21,21 @@ export interface MockServerOptions {
|
|
|
21
21
|
pollsBeforeDone?: number;
|
|
22
22
|
/** Validate submitted invoices and abort the invalid ones. Default true. */
|
|
23
23
|
validate?: boolean;
|
|
24
|
+
/**
|
|
25
|
+
* Turn away the first N HTTP requests with a throttle response, so a client's
|
|
26
|
+
* retry and backoff can be exercised end to end. NAV rate limits per
|
|
27
|
+
* taxpayer, and a bulk download makes one request per invoice, so recovering
|
|
28
|
+
* from a throttle is the difference between a pull that finishes and one that
|
|
29
|
+
* dies partway.
|
|
30
|
+
*/
|
|
31
|
+
throttle?: {
|
|
32
|
+
/** How many requests to turn away before serving normally. */
|
|
33
|
+
times: number;
|
|
34
|
+
/** Status to answer with. 429 (Too Many Requests) by default; 503 also retried. */
|
|
35
|
+
status?: 429 | 503;
|
|
36
|
+
/** Seconds to advertise in a `Retry-After` header, if any. */
|
|
37
|
+
retryAfterSeconds?: number;
|
|
38
|
+
};
|
|
24
39
|
/** Injectable clock. */
|
|
25
40
|
now?: () => Date;
|
|
26
41
|
}
|
package/dist/server.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,KAAK,MAAM,EAAE,MAAM,WAAW,CAAC;AAEtD,OAAO,EAAoC,KAAK,WAAW,EAAE,MAAM,gBAAgB,CAAC;AACpF,OAAO,EAKL,KAAK,eAAe,EACrB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAe,KAAK,SAAS,EAAE,KAAK,YAAY,EAAE,MAAM,YAAY,CAAC;AAE5E,MAAM,WAAW,iBAAiB;IAChC,4EAA4E;IAC5E,WAAW,EAAE,eAAe,CAAC;IAC7B;;;;;OAKG;IACH,eAAe,CAAC,EAAE,WAAW,EAAE,CAAC;IAChC,6CAA6C;IAC7C,SAAS,CAAC,EAAE,YAAY,EAAE,CAAC;IAC3B,2DAA2D;IAC3D,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,+DAA+D;IAC/D,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,4EAA4E;IAC5E,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,wBAAwB;IACxB,GAAG,CAAC,EAAE,MAAM,IAAI,CAAC;CAClB;AAED,MAAM,WAAW,UAAU;IACzB,qEAAqE;IACrE,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,wDAAwD;IACxD,KAAK,EAAE,SAAS,CAAC;IACjB,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3B,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,eAAe,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,UAAU,CAAC,
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,KAAK,MAAM,EAAE,MAAM,WAAW,CAAC;AAEtD,OAAO,EAAoC,KAAK,WAAW,EAAE,MAAM,gBAAgB,CAAC;AACpF,OAAO,EAKL,KAAK,eAAe,EACrB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAe,KAAK,SAAS,EAAE,KAAK,YAAY,EAAE,MAAM,YAAY,CAAC;AAE5E,MAAM,WAAW,iBAAiB;IAChC,4EAA4E;IAC5E,WAAW,EAAE,eAAe,CAAC;IAC7B;;;;;OAKG;IACH,eAAe,CAAC,EAAE,WAAW,EAAE,CAAC;IAChC,6CAA6C;IAC7C,SAAS,CAAC,EAAE,YAAY,EAAE,CAAC;IAC3B,2DAA2D;IAC3D,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,+DAA+D;IAC/D,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,4EAA4E;IAC5E,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE;QACT,8DAA8D;QAC9D,KAAK,EAAE,MAAM,CAAC;QACd,mFAAmF;QACnF,MAAM,CAAC,EAAE,GAAG,GAAG,GAAG,CAAC;QACnB,8DAA8D;QAC9D,iBAAiB,CAAC,EAAE,MAAM,CAAC;KAC5B,CAAC;IACF,wBAAwB;IACxB,GAAG,CAAC,EAAE,MAAM,IAAI,CAAC;CAClB;AAED,MAAM,WAAW,UAAU;IACzB,qEAAqE;IACrE,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,wDAAwD;IACxD,KAAK,EAAE,SAAS,CAAC;IACjB,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3B,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,eAAe,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,UAAU,CAAC,CA6DrF"}
|
package/dist/server.js
CHANGED
|
@@ -25,11 +25,25 @@ export async function startMockServer(options) {
|
|
|
25
25
|
validate: options.validate ?? true,
|
|
26
26
|
now: options.now ?? (() => new Date()),
|
|
27
27
|
};
|
|
28
|
+
let throttleRemaining = options.throttle?.times ?? 0;
|
|
28
29
|
const server = createServer((request, response) => {
|
|
29
30
|
const chunks = [];
|
|
30
31
|
request.on('data', (chunk) => chunks.push(chunk));
|
|
31
32
|
request.on('end', () => {
|
|
32
33
|
const body = Buffer.concat(chunks).toString('utf8');
|
|
34
|
+
if (throttleRemaining > 0) {
|
|
35
|
+
throttleRemaining -= 1;
|
|
36
|
+
state.throttled += 1;
|
|
37
|
+
const headers = {
|
|
38
|
+
'content-type': 'application/xml; charset=utf-8',
|
|
39
|
+
};
|
|
40
|
+
if (options.throttle?.retryAfterSeconds !== undefined) {
|
|
41
|
+
headers['retry-after'] = String(options.throttle.retryAfterSeconds);
|
|
42
|
+
}
|
|
43
|
+
response.writeHead(options.throttle?.status ?? 429, headers);
|
|
44
|
+
response.end(errorResponse(config, 'RATE_LIMITED', 'request limit exceeded, retry later'));
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
33
47
|
const { status, body: responseBody } = dispatch(request.method ?? '', request.url ?? '', body, config, state);
|
|
34
48
|
response.writeHead(status, { 'content-type': 'application/xml; charset=utf-8' });
|
|
35
49
|
response.end(responseBody);
|
package/dist/server.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAe,MAAM,WAAW,CAAC;AAEtD,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAoB,MAAM,gBAAgB,CAAC;AACpF,OAAO,EACL,QAAQ,EACR,SAAS,EACT,aAAa,GAGd,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,WAAW,EAAqC,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
|
package/dist/state.d.ts
CHANGED
package/dist/state.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../src/state.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAErE;;;;;GAKG;AACH,MAAM,WAAW,SAAS;IACxB,kDAAkD;IAClD,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IACrC,8DAA8D;IAC9D,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IACpC,6CAA6C;IAC7C,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;IAC7C,gEAAgE;IAChE,UAAU,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACxB,gDAAgD;IAChD,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IAC1D,wEAAwE;IACxE,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;IACrC,sDAAsD;IACtD,QAAQ,EAAE,KAAK,CAAC;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../src/state.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAErE;;;;;GAKG;AACH,MAAM,WAAW,SAAS;IACxB,kDAAkD;IAClD,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IACrC,8DAA8D;IAC9D,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IACpC,6CAA6C;IAC7C,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;IAC7C,gEAAgE;IAChE,UAAU,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACxB,gDAAgD;IAChD,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IAC1D,wEAAwE;IACxE,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;IACrC,sDAAsD;IACtD,QAAQ,EAAE,KAAK,CAAC;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACxE,iEAAiE;IACjE,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,aAAa;IAC5B,aAAa,EAAE,MAAM,CAAC;IACtB,sCAAsC;IACtC,SAAS,EAAE,MAAM,CAAC;IAClB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,sDAAsD;IACtD,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,OAAO,CAAC;IACpB,OAAO,EAAE,WAAW,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,iBAAiB;IAChC,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,4DAA4D;IAC5D,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,KAAK,CAAC;QACb,KAAK,EAAE,MAAM,CAAC;QACd,aAAa,EAAE,iBAAiB,CAAC;QACjC,6EAA6E;QAC7E,0BAA0B,EAAE,KAAK,CAAC;YAChC,oBAAoB,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,CAAC;YAChD,mBAAmB,CAAC,EAAE,MAAM,CAAC;YAC7B,OAAO,CAAC,EAAE,MAAM,CAAC;SAClB,CAAC,CAAC;KACJ,CAAC,CAAC;IACH,6DAA6D;IAC7D,aAAa,EAAE,iBAAiB,EAAE,CAAC;CACpC;AAED,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,OAAO,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,wBAAgB,WAAW,CAAC,SAAS,GAAE,YAAY,EAAO,GAAG,SAAS,CAWrE"}
|
package/dist/state.js
CHANGED
package/dist/state.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"state.js","sourceRoot":"","sources":["../src/state.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"state.js","sourceRoot":"","sources":["../src/state.ts"],"names":[],"mappings":"AAuEA,MAAM,UAAU,WAAW,CAAC,YAA4B,EAAE;IACxD,OAAO;QACL,QAAQ,EAAE,IAAI,GAAG,EAAE;QACnB,OAAO,EAAE,IAAI,GAAG,EAAE;QAClB,YAAY,EAAE,IAAI,GAAG,EAAE;QACvB,UAAU,EAAE,IAAI,GAAG,EAAE;QACrB,MAAM,EAAE,IAAI,GAAG,EAAE;QACjB,SAAS,EAAE,IAAI,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC,CAAC;QAC/E,QAAQ,EAAE,EAAE;QACZ,SAAS,EAAE,CAAC;KACb,CAAC;AACJ,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@open-nav/mock-server",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "A local stand-in for the NAV Online Számla invoice service, for testing without credentials",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"nav",
|
|
@@ -47,10 +47,10 @@
|
|
|
47
47
|
"access": "public"
|
|
48
48
|
},
|
|
49
49
|
"dependencies": {
|
|
50
|
-
"@open-nav/core": "^0.1.
|
|
50
|
+
"@open-nav/core": "^0.1.1"
|
|
51
51
|
},
|
|
52
52
|
"devDependencies": {
|
|
53
|
-
"@open-nav/client": "^0.1.
|
|
53
|
+
"@open-nav/client": "^0.1.1"
|
|
54
54
|
},
|
|
55
55
|
"scripts": {
|
|
56
56
|
"build": "tsc -b"
|
package/src/server.ts
CHANGED
|
@@ -29,6 +29,21 @@ export interface MockServerOptions {
|
|
|
29
29
|
pollsBeforeDone?: number;
|
|
30
30
|
/** Validate submitted invoices and abort the invalid ones. Default true. */
|
|
31
31
|
validate?: boolean;
|
|
32
|
+
/**
|
|
33
|
+
* Turn away the first N HTTP requests with a throttle response, so a client's
|
|
34
|
+
* retry and backoff can be exercised end to end. NAV rate limits per
|
|
35
|
+
* taxpayer, and a bulk download makes one request per invoice, so recovering
|
|
36
|
+
* from a throttle is the difference between a pull that finishes and one that
|
|
37
|
+
* dies partway.
|
|
38
|
+
*/
|
|
39
|
+
throttle?: {
|
|
40
|
+
/** How many requests to turn away before serving normally. */
|
|
41
|
+
times: number;
|
|
42
|
+
/** Status to answer with. 429 (Too Many Requests) by default; 503 also retried. */
|
|
43
|
+
status?: 429 | 503;
|
|
44
|
+
/** Seconds to advertise in a `Retry-After` header, if any. */
|
|
45
|
+
retryAfterSeconds?: number;
|
|
46
|
+
};
|
|
32
47
|
/** Injectable clock. */
|
|
33
48
|
now?: () => Date;
|
|
34
49
|
}
|
|
@@ -67,11 +82,28 @@ export async function startMockServer(options: MockServerOptions): Promise<MockS
|
|
|
67
82
|
now: options.now ?? (() => new Date()),
|
|
68
83
|
};
|
|
69
84
|
|
|
85
|
+
let throttleRemaining = options.throttle?.times ?? 0;
|
|
86
|
+
|
|
70
87
|
const server = createServer((request, response) => {
|
|
71
88
|
const chunks: Buffer[] = [];
|
|
72
89
|
request.on('data', (chunk: Buffer) => chunks.push(chunk));
|
|
73
90
|
request.on('end', () => {
|
|
74
91
|
const body = Buffer.concat(chunks).toString('utf8');
|
|
92
|
+
|
|
93
|
+
if (throttleRemaining > 0) {
|
|
94
|
+
throttleRemaining -= 1;
|
|
95
|
+
state.throttled += 1;
|
|
96
|
+
const headers: Record<string, string> = {
|
|
97
|
+
'content-type': 'application/xml; charset=utf-8',
|
|
98
|
+
};
|
|
99
|
+
if (options.throttle?.retryAfterSeconds !== undefined) {
|
|
100
|
+
headers['retry-after'] = String(options.throttle.retryAfterSeconds);
|
|
101
|
+
}
|
|
102
|
+
response.writeHead(options.throttle?.status ?? 429, headers);
|
|
103
|
+
response.end(errorResponse(config, 'RATE_LIMITED', 'request limit exceeded, retry later'));
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
|
|
75
107
|
const { status, body: responseBody } = dispatch(
|
|
76
108
|
request.method ?? '',
|
|
77
109
|
request.url ?? '',
|
package/src/state.ts
CHANGED
|
@@ -21,6 +21,8 @@ export interface MockState {
|
|
|
21
21
|
taxpayers: Map<string, MockTaxpayer>;
|
|
22
22
|
/** Requests received, newest last, for assertions. */
|
|
23
23
|
requests: Array<{ operation: string; requestId: string; body: string }>;
|
|
24
|
+
/** HTTP requests turned away by the throttle, for assertions. */
|
|
25
|
+
throttled: number;
|
|
24
26
|
}
|
|
25
27
|
|
|
26
28
|
export interface StoredInvoice {
|
|
@@ -76,5 +78,6 @@ export function createState(taxpayers: MockTaxpayer[] = []): MockState {
|
|
|
76
78
|
tokens: new Map(),
|
|
77
79
|
taxpayers: new Map(taxpayers.map((taxpayer) => [taxpayer.taxNumber, taxpayer])),
|
|
78
80
|
requests: [],
|
|
81
|
+
throttled: 0,
|
|
79
82
|
};
|
|
80
83
|
}
|