@tryfinch/finch-api 1.0.0 → 1.1.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/.github/workflows/publish-npm.yml +1 -1
- package/.prettierignore +1 -0
- package/.release-please-manifest.json +1 -1
- package/CHANGELOG.md +33 -0
- package/README.md +1 -2
- package/api.md +1 -1
- package/core.ts +20 -55
- package/dist/cjs/core.d.ts +16 -8
- package/dist/cjs/core.d.ts.map +1 -1
- package/dist/cjs/core.js +25 -69
- package/dist/cjs/core.js.map +1 -1
- package/dist/cjs/index.d.ts +3 -0
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js +6 -1
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/resources/hris/individuals/employment-data.d.ts +0 -8
- package/dist/cjs/resources/hris/individuals/employment-data.d.ts.map +1 -1
- package/dist/cjs/resources/hris/individuals/individuals.d.ts +0 -6
- package/dist/cjs/resources/hris/individuals/individuals.d.ts.map +1 -1
- package/dist/cjs/resources/hris/pay-statements.d.ts +0 -14
- package/dist/cjs/resources/hris/pay-statements.d.ts.map +1 -1
- package/dist/cjs/streaming.d.ts +13 -0
- package/dist/cjs/streaming.d.ts.map +1 -0
- package/dist/cjs/streaming.js +220 -0
- package/dist/cjs/streaming.js.map +1 -0
- package/dist/cjs/tests/api-resources/hris/benefits/individuals.test.js +9 -1
- package/dist/cjs/tests/api-resources/hris/benefits/individuals.test.js.map +1 -1
- package/dist/cjs/tests/index.test.js +31 -0
- package/dist/cjs/tests/index.test.js.map +1 -1
- package/dist/cjs/version.d.ts +1 -1
- package/dist/cjs/version.js +1 -1
- package/index.ts +7 -0
- package/package.json +1 -1
- package/release-please-config.json +53 -4
- package/resources/hris/individuals/employment-data.ts +0 -9
- package/resources/hris/individuals/individuals.ts +0 -8
- package/resources/hris/pay-statements.ts +0 -17
- package/streaming.ts +122 -0
- package/tests/api-resources/hris/benefits/individuals.test.ts +9 -1
- package/tests/index.test.ts +38 -0
- package/version.ts +1 -1
package/streaming.ts
ADDED
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import type { Response } from 'node-fetch';
|
|
2
|
+
import { APIResponse, Headers, createResponseHeaders } from '~/core';
|
|
3
|
+
|
|
4
|
+
type ServerSentEvent = {
|
|
5
|
+
event: string | null;
|
|
6
|
+
data: string;
|
|
7
|
+
raw: string[];
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
class SSEDecoder {
|
|
11
|
+
private data: string[];
|
|
12
|
+
private event: string | null;
|
|
13
|
+
private chunks: string[];
|
|
14
|
+
|
|
15
|
+
constructor() {
|
|
16
|
+
this.event = null;
|
|
17
|
+
this.data = [];
|
|
18
|
+
this.chunks = [];
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
decode(line: string) {
|
|
22
|
+
if (line.endsWith('\r')) {
|
|
23
|
+
line = line.substring(0, line.length - 1);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
if (!line) {
|
|
27
|
+
// empty line and we didn't previously encounter any messages
|
|
28
|
+
if (!this.event && !this.data.length) return null;
|
|
29
|
+
|
|
30
|
+
const sse: ServerSentEvent = {
|
|
31
|
+
event: this.event,
|
|
32
|
+
data: this.data.join('\n'),
|
|
33
|
+
raw: this.chunks,
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
this.event = null;
|
|
37
|
+
this.data = [];
|
|
38
|
+
this.chunks = [];
|
|
39
|
+
|
|
40
|
+
return sse;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
this.chunks.push(line);
|
|
44
|
+
|
|
45
|
+
if (line.startsWith(':')) {
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
let [fieldname, _, value] = partition(line, ':');
|
|
50
|
+
|
|
51
|
+
if (value.startsWith(' ')) {
|
|
52
|
+
value = value.substring(1);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
if (fieldname === 'event') {
|
|
56
|
+
this.event = value;
|
|
57
|
+
} else if (fieldname === 'data') {
|
|
58
|
+
this.data.push(value);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export class Stream<Item> implements AsyncIterable<Item>, APIResponse<Stream<Item>> {
|
|
66
|
+
response: Response;
|
|
67
|
+
responseHeaders: Headers;
|
|
68
|
+
controller: AbortController;
|
|
69
|
+
|
|
70
|
+
private decoder: SSEDecoder;
|
|
71
|
+
|
|
72
|
+
constructor(response: Response, controller: AbortController) {
|
|
73
|
+
this.response = response;
|
|
74
|
+
this.controller = controller;
|
|
75
|
+
this.decoder = new SSEDecoder();
|
|
76
|
+
this.responseHeaders = createResponseHeaders(response.headers);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
private async *iterMessages(): AsyncGenerator<ServerSentEvent, void, unknown> {
|
|
80
|
+
if (!this.response.body) {
|
|
81
|
+
this.controller.abort();
|
|
82
|
+
throw new Error(`Attempted to iterate over a response with no body`);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
for await (const chunk of this.response.body) {
|
|
86
|
+
let text;
|
|
87
|
+
if (chunk instanceof Buffer) {
|
|
88
|
+
text = chunk.toString();
|
|
89
|
+
} else {
|
|
90
|
+
text = chunk;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
for (let line of text.split('\n')) {
|
|
94
|
+
const sse = this.decoder.decode(line);
|
|
95
|
+
if (sse) yield sse;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
this.controller.abort();
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
async *[Symbol.asyncIterator](): AsyncIterator<Item, any, undefined> {
|
|
103
|
+
for await (const sse of this.iterMessages()) {
|
|
104
|
+
try {
|
|
105
|
+
yield JSON.parse(sse.data);
|
|
106
|
+
} catch (e) {
|
|
107
|
+
console.error(`Could not parse message into JSON:`, sse.data);
|
|
108
|
+
console.error(`From chunk:`, sse.raw);
|
|
109
|
+
throw e;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
function partition(str: string, delimiter: string): [string, string, string] {
|
|
116
|
+
const index = str.indexOf(delimiter);
|
|
117
|
+
if (index !== -1) {
|
|
118
|
+
return [str.substring(0, index), delimiter, str.substring(index + delimiter.length)];
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
return [str, '', ''];
|
|
122
|
+
}
|
|
@@ -5,10 +5,18 @@ import Finch from '~/index';
|
|
|
5
5
|
const finch = new Finch({ accessToken: 'something1234', baseURL: 'http://127.0.0.1:4010' });
|
|
6
6
|
|
|
7
7
|
describe('resource individuals', () => {
|
|
8
|
-
test('enrollMany', async () => {
|
|
8
|
+
test('enrollMany: only required params', async () => {
|
|
9
9
|
const response = await finch.hris.benefits.individuals.enrollMany('string', [{}, {}, {}]);
|
|
10
10
|
});
|
|
11
11
|
|
|
12
|
+
test('enrollMany: required and optional params', async () => {
|
|
13
|
+
const response = await finch.hris.benefits.individuals.enrollMany('string', [
|
|
14
|
+
{ individual_id: 'string' },
|
|
15
|
+
{ individual_id: 'string' },
|
|
16
|
+
{ individual_id: 'string' },
|
|
17
|
+
]);
|
|
18
|
+
});
|
|
19
|
+
|
|
12
20
|
test('enrolledIds', async () => {
|
|
13
21
|
const response = await finch.hris.benefits.individuals.enrolledIds('string');
|
|
14
22
|
});
|
package/tests/index.test.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
// File generated from our OpenAPI spec by Stainless.
|
|
2
2
|
|
|
3
|
+
import { Headers } from '~/core';
|
|
3
4
|
import Finch from '../index';
|
|
4
5
|
|
|
5
6
|
describe('instantiate client', () => {
|
|
@@ -16,6 +17,43 @@ describe('instantiate client', () => {
|
|
|
16
17
|
process.env = env;
|
|
17
18
|
});
|
|
18
19
|
|
|
20
|
+
test('defaultHeaders are passed through', () => {
|
|
21
|
+
const client = new Finch({
|
|
22
|
+
defaultHeaders: { 'X-My-Default-Header': '2' },
|
|
23
|
+
accessToken: 'my access token',
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
const { req } = client.buildRequest({ path: '/foo', method: 'post' });
|
|
27
|
+
expect((req.headers as Headers)['X-My-Default-Header']).toEqual('2');
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
describe('baseUrl', () => {
|
|
31
|
+
test('trailing slash', () => {
|
|
32
|
+
const client = new Finch({
|
|
33
|
+
baseURL: 'http://localhost:5000/custom/path/',
|
|
34
|
+
accessToken: 'my access token',
|
|
35
|
+
});
|
|
36
|
+
expect(client.buildURL('/foo', null)).toEqual('http://localhost:5000/custom/path/foo');
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
test('no trailing slash', () => {
|
|
40
|
+
const client = new Finch({
|
|
41
|
+
baseURL: 'http://localhost:5000/custom/path',
|
|
42
|
+
accessToken: 'my access token',
|
|
43
|
+
});
|
|
44
|
+
expect(client.buildURL('/foo', null)).toEqual('http://localhost:5000/custom/path/foo');
|
|
45
|
+
});
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
test('maxRetries option is correctly set', () => {
|
|
49
|
+
const client = new Finch({ maxRetries: 1, accessToken: 'my access token' });
|
|
50
|
+
expect(client.maxRetries).toEqual(1);
|
|
51
|
+
|
|
52
|
+
// default
|
|
53
|
+
const client2 = new Finch({ accessToken: 'my access token' });
|
|
54
|
+
expect(client2.maxRetries).toEqual(2);
|
|
55
|
+
});
|
|
56
|
+
|
|
19
57
|
test('with accessToken argument', () => {
|
|
20
58
|
const client = new Finch({ accessToken: 'another access token' });
|
|
21
59
|
expect(client.accessToken).toBe('another access token');
|
package/version.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const VERSION = '1.
|
|
1
|
+
export const VERSION = '1.1.0'; // x-release-please-version
|