Skip to content

Commit ba555f4

Browse files
feat(api): update via SDK Studio (#15)
1 parent d3451a2 commit ba555f4

7 files changed

Lines changed: 236 additions & 3 deletions

File tree

.stats.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
configured_endpoints: 3
2-
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/grid%2Fspreadsheet-api-4f7e4249cd44e912120dd6531cc506a8c0c0e3e3b5f0c91b18c37177b850b590.yml
1+
configured_endpoints: 5
2+
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/grid%2Fspreadsheet-api-cf876af98da268e94e99a8b5e9b92deb5ce68bf70db902e211d89c8eda5eecf1.yml

README.md

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,50 @@ main();
5353

5454
Documentation for each method, request param, and response field are available in docstrings and will appear on hover in most modern editors.
5555

56+
## File uploads
57+
58+
Request parameters that correspond to file uploads can be passed in many different forms:
59+
60+
- `File` (or an object with the same structure)
61+
- a `fetch` `Response` (or an object with the same structure)
62+
- an `fs.ReadStream`
63+
- the return value of our `toFile` helper
64+
65+
```ts
66+
import fs from 'fs';
67+
import Grid, { toFile } from '@grid-is/api';
68+
69+
const client = new Grid();
70+
71+
// If you have access to Node `fs` we recommend using `fs.createReadStream()`:
72+
await client.workbooks.upload({
73+
body: fs.createReadStream('/path/to/file'),
74+
'X-Uploaded-Filename': 'X-Uploaded-Filename',
75+
});
76+
77+
// Or if you have the web `File` API you can pass a `File` instance:
78+
await client.workbooks.upload({
79+
body: new File(['my bytes'], 'file'),
80+
'X-Uploaded-Filename': 'X-Uploaded-Filename',
81+
});
82+
83+
// You can also pass a `fetch` `Response`:
84+
await client.workbooks.upload({
85+
body: await fetch('https://somesite/file'),
86+
'X-Uploaded-Filename': 'X-Uploaded-Filename',
87+
});
88+
89+
// Finally, if none of the above are convenient, you can use our `toFile` helper:
90+
await client.workbooks.upload({
91+
body: await toFile(Buffer.from('my bytes'), 'file'),
92+
'X-Uploaded-Filename': 'X-Uploaded-Filename',
93+
});
94+
await client.workbooks.upload({
95+
body: await toFile(new Uint8Array([0, 1, 2]), 'file'),
96+
'X-Uploaded-Filename': 'X-Uploaded-Filename',
97+
});
98+
```
99+
56100
## Handling errors
57101

58102
When the library is unable to connect to the API,

api.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,14 @@
22

33
Types:
44

5+
- <code><a href="./src/resources/workbooks.ts">WorkbookListResponse</a></code>
56
- <code><a href="./src/resources/workbooks.ts">WorkbookQueryResponse</a></code>
7+
- <code><a href="./src/resources/workbooks.ts">WorkbookUploadResponse</a></code>
68

79
Methods:
810

11+
- <code title="get /v1/workbooks">client.workbooks.<a href="./src/resources/workbooks.ts">list</a>({ ...params }) -> WorkbookListResponse</code>
912
- <code title="post /v1/workbooks/{id}/export">client.workbooks.<a href="./src/resources/workbooks.ts">export</a>(id, { ...params }) -> Response</code>
1013
- <code title="post /v1/workbooks/{id}/query">client.workbooks.<a href="./src/resources/workbooks.ts">query</a>(id, { ...params }) -> WorkbookQueryResponse</code>
1114
- <code title="post /v1/workbooks/{id}/chart">client.workbooks.<a href="./src/resources/workbooks.ts">renderChart</a>(id, { ...params }) -> Response</code>
15+
- <code title="post /v1/workbooks">client.workbooks.<a href="./src/resources/workbooks.ts">upload</a>({ ...params }) -> WorkbookUploadResponse</code>

src/client.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,13 @@ import { HeadersLike, NullableHeaders, buildHeaders } from './internal/headers';
2020
import { FinalRequestOptions, RequestOptions } from './internal/request-options';
2121
import {
2222
WorkbookExportParams,
23+
WorkbookListParams,
24+
WorkbookListResponse,
2325
WorkbookQueryParams,
2426
WorkbookQueryResponse,
2527
WorkbookRenderChartParams,
28+
WorkbookUploadParams,
29+
WorkbookUploadResponse,
2630
Workbooks,
2731
} from './resources/workbooks';
2832
import { readEnv } from './internal/utils/env';
@@ -731,9 +735,13 @@ export declare namespace Grid {
731735

732736
export {
733737
Workbooks as Workbooks,
738+
type WorkbookListResponse as WorkbookListResponse,
734739
type WorkbookQueryResponse as WorkbookQueryResponse,
740+
type WorkbookUploadResponse as WorkbookUploadResponse,
741+
type WorkbookListParams as WorkbookListParams,
735742
type WorkbookExportParams as WorkbookExportParams,
736743
type WorkbookQueryParams as WorkbookQueryParams,
737744
type WorkbookRenderChartParams as WorkbookRenderChartParams,
745+
type WorkbookUploadParams as WorkbookUploadParams,
738746
};
739747
}

src/resources/index.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,12 @@
22

33
export {
44
Workbooks,
5+
type WorkbookListResponse,
56
type WorkbookQueryResponse,
7+
type WorkbookUploadResponse,
8+
type WorkbookListParams,
69
type WorkbookExportParams,
710
type WorkbookQueryParams,
811
type WorkbookRenderChartParams,
12+
type WorkbookUploadParams,
913
} from './workbooks';

src/resources/workbooks.ts

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,18 @@ import { RequestOptions } from '../internal/request-options';
77
import { path } from '../internal/utils/path';
88

99
export class Workbooks extends APIResource {
10+
/**
11+
* List the workbooks linked to an account.
12+
*
13+
* This endpoint returns a paginated list of workbooks.
14+
*/
15+
list(
16+
query: WorkbookListParams | null | undefined = {},
17+
options?: RequestOptions,
18+
): APIPromise<WorkbookListResponse> {
19+
return this._client.get('/v1/workbooks', { query, ...options });
20+
}
21+
1022
/**
1123
* Export a workbook as an .xlsx file. Cells can be updated before the workbook is
1224
* exported.
@@ -44,6 +56,88 @@ export class Workbooks extends APIResource {
4456
__binaryResponse: true,
4557
});
4658
}
59+
60+
/**
61+
* Upload an Excel workbook file and make it available in the API.
62+
*
63+
* The workbook will be processed in the background. Once it's processed
64+
* successfully it will be available for querying and exporting.
65+
*/
66+
upload(params: WorkbookUploadParams, options?: RequestOptions): APIPromise<WorkbookUploadResponse> {
67+
const { body, 'X-Uploaded-Filename': xUploadedFilename } = params;
68+
return this._client.post('/v1/workbooks', {
69+
body: body,
70+
...options,
71+
headers: buildHeaders([
72+
{ 'Content-Type': 'application/octet-stream', 'X-Uploaded-Filename': xUploadedFilename },
73+
options?.headers,
74+
]),
75+
});
76+
}
77+
}
78+
79+
export interface WorkbookListResponse {
80+
items: Array<WorkbookListResponse.Item>;
81+
82+
pagination: WorkbookListResponse.Pagination;
83+
}
84+
85+
export namespace WorkbookListResponse {
86+
export interface Item {
87+
/**
88+
* A workbook's unique identifier
89+
*/
90+
id: string;
91+
92+
/**
93+
* The date/time the workbook was created
94+
*/
95+
created: string;
96+
97+
/**
98+
* The defect that was found in the most recent version of the workbook, if any
99+
*/
100+
defect:
101+
| ''
102+
| 'too_big'
103+
| 'converted_workbook_too_big'
104+
| 'unrecognized_format'
105+
| 'cannot_fetch_from_remote'
106+
| 'processing_timeout'
107+
| 'conversion_error';
108+
109+
/**
110+
* The original filename of the uploaded workbook
111+
*/
112+
filename: string;
113+
114+
/**
115+
* The date/time the workbook was last modified
116+
*/
117+
modified: string;
118+
119+
/**
120+
* The current state of the most recent version of the workbook
121+
*/
122+
state: 'processing' | 'ready' | 'error';
123+
124+
/**
125+
* The most recent version of the workbook
126+
*/
127+
version: number;
128+
129+
/**
130+
* The latest version of the workbook that has a 'ready' state
131+
*/
132+
latest_ready_version?: number | null;
133+
}
134+
135+
export interface Pagination {
136+
/**
137+
* The cursor to pass on as query parameter for the next batch of items, if any
138+
*/
139+
next_cursor?: string | null;
140+
}
47141
}
48142

49143
/**
@@ -393,6 +487,26 @@ export namespace WorkbookQueryResponse {
393487
}
394488
}
395489

490+
export interface WorkbookUploadResponse {
491+
/**
492+
* The id of the newly uploaded workbook
493+
*/
494+
id: string;
495+
}
496+
497+
export interface WorkbookListParams {
498+
/**
499+
* Cursor for the next page of items. If not provided, the first batch of items
500+
* will be returned.
501+
*/
502+
cursor?: string;
503+
504+
/**
505+
* Number of items to return per page
506+
*/
507+
limit?: number;
508+
}
509+
396510
export interface WorkbookExportParams {
397511
/**
398512
* Cells to update before exporting
@@ -611,11 +725,27 @@ export namespace WorkbookRenderChartParams {
611725
}
612726
}
613727

728+
export interface WorkbookUploadParams {
729+
/**
730+
* Body param:
731+
*/
732+
body: string | ArrayBuffer | ArrayBufferView | Blob | DataView;
733+
734+
/**
735+
* Header param: The name of the workbook file
736+
*/
737+
'X-Uploaded-Filename': string;
738+
}
739+
614740
export declare namespace Workbooks {
615741
export {
742+
type WorkbookListResponse as WorkbookListResponse,
616743
type WorkbookQueryResponse as WorkbookQueryResponse,
744+
type WorkbookUploadResponse as WorkbookUploadResponse,
745+
type WorkbookListParams as WorkbookListParams,
617746
type WorkbookExportParams as WorkbookExportParams,
618747
type WorkbookQueryParams as WorkbookQueryParams,
619748
type WorkbookRenderChartParams as WorkbookRenderChartParams,
749+
type WorkbookUploadParams as WorkbookUploadParams,
620750
};
621751
}

tests/api-resources/workbooks.test.ts

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,33 @@
11
// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
22

3-
import Grid from '@grid-is/api';
3+
import Grid, { toFile } from '@grid-is/api';
44

55
const client = new Grid({
66
bearerToken: 'My Bearer Token',
77
baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010',
88
});
99

1010
describe('resource workbooks', () => {
11+
// skipped: tests are disabled for the time being
12+
test.skip('list', async () => {
13+
const responsePromise = client.workbooks.list();
14+
const rawResponse = await responsePromise.asResponse();
15+
expect(rawResponse).toBeInstanceOf(Response);
16+
const response = await responsePromise;
17+
expect(response).not.toBeInstanceOf(Response);
18+
const dataAndResponse = await responsePromise.withResponse();
19+
expect(dataAndResponse.data).toBe(response);
20+
expect(dataAndResponse.response).toBe(rawResponse);
21+
});
22+
23+
// skipped: tests are disabled for the time being
24+
test.skip('list: request options and params are passed correctly', async () => {
25+
// ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error
26+
await expect(
27+
client.workbooks.list({ cursor: 'cursor', limit: 0 }, { path: '/_stainless_unknown_path' }),
28+
).rejects.toThrow(Grid.NotFoundError);
29+
});
30+
1131
// skipped: tests are disabled for the time being
1232
test.skip('query: only required params', async () => {
1333
const responsePromise = client.workbooks.query('id', { read: ['A1', 'Sheet2!B3', '=SUM(A1:A4)'] });
@@ -37,4 +57,27 @@ describe('resource workbooks', () => {
3757
apply: [{ target: 'A2', value: 1234 }],
3858
});
3959
});
60+
61+
// skipped: tests are disabled for the time being
62+
test.skip('upload: only required params', async () => {
63+
const responsePromise = client.workbooks.upload({
64+
body: await toFile(Buffer.from('# my file contents'), 'README.md'),
65+
'X-Uploaded-Filename': 'X-Uploaded-Filename',
66+
});
67+
const rawResponse = await responsePromise.asResponse();
68+
expect(rawResponse).toBeInstanceOf(Response);
69+
const response = await responsePromise;
70+
expect(response).not.toBeInstanceOf(Response);
71+
const dataAndResponse = await responsePromise.withResponse();
72+
expect(dataAndResponse.data).toBe(response);
73+
expect(dataAndResponse.response).toBe(rawResponse);
74+
});
75+
76+
// skipped: tests are disabled for the time being
77+
test.skip('upload: required and optional params', async () => {
78+
const response = await client.workbooks.upload({
79+
body: await toFile(Buffer.from('# my file contents'), 'README.md'),
80+
'X-Uploaded-Filename': 'X-Uploaded-Filename',
81+
});
82+
});
4083
});

0 commit comments

Comments
 (0)