Skip to content

Commit afbf140

Browse files
chore(internal): codegen related update (#206)
1 parent 373e288 commit afbf140

38 files changed

Lines changed: 933 additions & 904 deletions

MIGRATION.md

Lines changed: 36 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -286,49 +286,48 @@ The `headers` property on `APIError` objects is now an instance of the Web [Head
286286

287287
### Removed exports
288288

289-
#### `Response`
290-
291-
```typescript
292-
// Before
293-
import { Response } from 'writer-sdk';
294-
295-
// After
296-
// `Response` must now come from the builtin types
297-
```
298-
299289
#### Resource classes
300290

301-
If you were importing resource classes from the root package then you must now import them from the file they are defined in:
291+
If you were importing resource classes from the root package then you must now import them from the file they are defined in.
292+
This was never valid at the type level and only worked in CommonJS files.
302293

303294
```typescript
304295
// Before
305-
import { Applications } from 'writer-sdk';
296+
const { Applications } = require('writer-sdk');
306297

307298
// After
308-
import { Applications } from 'writer-sdk/resources/applications/applications';
299+
const { Writer } = require('writer-sdk');
300+
Writer.Applications; // or import directly from writer-sdk/resources/applications/applications
309301
```
310302

311-
#### `writer-sdk/core`
303+
#### Refactor of `writer-sdk/core`, `error`, `pagination`, `resource`, `streaming` and `uploads`
312304

313-
The `writer-sdk/core` file was intended to be internal-only but it was publicly accessible, as such it has been refactored and split up into internal files.
305+
Much of the `writer-sdk/core` file was intended to be internal-only but it was publicly accessible, as such it has been refactored and split up into internal and public files, with public-facing code moved to a new `core` folder and internal code moving to the private `internal` folder.
314306

315-
If you were relying on anything that was only exported from `writer-sdk/core` and is also not accessible anywhere else, please open an issue and we'll consider adding it to the public API.
316-
317-
#### `APIClient`
318-
319-
The `APIClient` base client class has been removed as it is no longer needed. If you were importing this class then you must now import the main client class:
307+
At the same time, we moved some public-facing files which were previously at the top level into `core` to make the file structure cleaner and more clear:
320308

321309
```typescript
322310
// Before
323-
import { APIClient } from 'writer-sdk/core';
311+
import 'writer-sdk/error';
312+
import 'writer-sdk/pagination';
313+
import 'writer-sdk/resource';
314+
import 'writer-sdk/streaming';
315+
import 'writer-sdk/uploads';
324316

325317
// After
326-
import { Writer } from 'writer-sdk';
318+
import 'writer-sdk/core/error';
319+
import 'writer-sdk/core/pagination';
320+
import 'writer-sdk/core/resource';
321+
import 'writer-sdk/core/streaming';
322+
import 'writer-sdk/core/uploads';
327323
```
328324

329-
#### Cleaned up `writer-sdk/uploads` exports
325+
If you were relying on anything that was only exported from `writer-sdk/core` and is also not accessible anywhere else, please open an issue and we'll consider adding it to the public API.
326+
327+
#### Cleaned up `uploads` exports
330328

331-
The following exports have been removed from `writer-sdk/uploads` as they were not intended to be a part of the public API:
329+
As part of the `core` refactor, `writer-sdk/uploads` was moved to `writer-sdk/core/uploads`
330+
and the following exports were removed, as they were not intended to be a part of the public API:
332331

333332
- `fileFromPath`
334333
- `BlobPart`
@@ -347,5 +346,17 @@ The following exports have been removed from `writer-sdk/uploads` as they were n
347346
Note that `Uploadable` & `toFile` **are** still exported:
348347

349348
```typescript
350-
import { type Uploadable, toFile } from 'writer-sdk/uploads';
349+
import { type Uploadable, toFile } from 'writer-sdk/core/uploads';
350+
```
351+
352+
#### `APIClient`
353+
354+
The `APIClient` base client class has been removed as it is no longer needed. If you were importing this class then you must now import the main client class:
355+
356+
```typescript
357+
// Before
358+
import { APIClient } from 'writer-sdk/core';
359+
360+
// After
361+
import { Writer } from 'writer-sdk';
351362
```

src/api-promise.ts

Lines changed: 2 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -1,92 +1,2 @@
1-
// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2-
3-
import { type Writer } from './client';
4-
5-
import { type PromiseOrValue } from './internal/types';
6-
import { APIResponseProps, defaultParseResponse } from './internal/parse';
7-
8-
/**
9-
* A subclass of `Promise` providing additional helper methods
10-
* for interacting with the SDK.
11-
*/
12-
export class APIPromise<T> extends Promise<T> {
13-
private parsedPromise: Promise<T> | undefined;
14-
#client: Writer;
15-
16-
constructor(
17-
client: Writer,
18-
private responsePromise: Promise<APIResponseProps>,
19-
private parseResponse: (
20-
client: Writer,
21-
props: APIResponseProps,
22-
) => PromiseOrValue<T> = defaultParseResponse,
23-
) {
24-
super((resolve) => {
25-
// this is maybe a bit weird but this has to be a no-op to not implicitly
26-
// parse the response body; instead .then, .catch, .finally are overridden
27-
// to parse the response
28-
resolve(null as any);
29-
});
30-
this.#client = client;
31-
}
32-
33-
_thenUnwrap<U>(transform: (data: T, props: APIResponseProps) => U): APIPromise<U> {
34-
return new APIPromise(this.#client, this.responsePromise, async (client, props) =>
35-
transform(await this.parseResponse(client, props), props),
36-
);
37-
}
38-
39-
/**
40-
* Gets the raw `Response` instance instead of parsing the response
41-
* data.
42-
*
43-
* If you want to parse the response body but still get the `Response`
44-
* instance, you can use {@link withResponse()}.
45-
*
46-
* 👋 Getting the wrong TypeScript type for `Response`?
47-
* Try setting `"moduleResolution": "NodeNext"` or add `"lib": ["DOM"]`
48-
* to your `tsconfig.json`.
49-
*/
50-
asResponse(): Promise<Response> {
51-
return this.responsePromise.then((p) => p.response);
52-
}
53-
54-
/**
55-
* Gets the parsed response data and the raw `Response` instance.
56-
*
57-
* If you just want to get the raw `Response` instance without parsing it,
58-
* you can use {@link asResponse()}.
59-
*
60-
* 👋 Getting the wrong TypeScript type for `Response`?
61-
* Try setting `"moduleResolution": "NodeNext"` or add `"lib": ["DOM"]`
62-
* to your `tsconfig.json`.
63-
*/
64-
async withResponse(): Promise<{ data: T; response: Response }> {
65-
const [data, response] = await Promise.all([this.parse(), this.asResponse()]);
66-
return { data, response };
67-
}
68-
69-
private parse(): Promise<T> {
70-
if (!this.parsedPromise) {
71-
this.parsedPromise = this.responsePromise.then((data) => this.parseResponse(this.#client, data));
72-
}
73-
return this.parsedPromise;
74-
}
75-
76-
override then<TResult1 = T, TResult2 = never>(
77-
onfulfilled?: ((value: T) => TResult1 | PromiseLike<TResult1>) | undefined | null,
78-
onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | undefined | null,
79-
): Promise<TResult1 | TResult2> {
80-
return this.parse().then(onfulfilled, onrejected);
81-
}
82-
83-
override catch<TResult = never>(
84-
onrejected?: ((reason: any) => TResult | PromiseLike<TResult>) | undefined | null,
85-
): Promise<T | TResult> {
86-
return this.parse().catch(onrejected);
87-
}
88-
89-
override finally(onfinally?: (() => void) | undefined | null): Promise<T> {
90-
return this.parse().finally(onfinally);
91-
}
92-
}
1+
/** @deprecated Import from ./core/api-promise instead */
2+
export * from './core/api-promise';

src/client.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,18 +13,18 @@ import { getPlatformHeaders } from './internal/detect-platform';
1313
import * as Shims from './internal/shims';
1414
import * as Opts from './internal/request-options';
1515
import { VERSION } from './version';
16-
import * as Errors from './error';
17-
import * as Pagination from './pagination';
16+
import * as Errors from './core/error';
17+
import * as Pagination from './core/pagination';
1818
import {
1919
AbstractPage,
2020
type ApplicationJobsOffsetParams,
2121
ApplicationJobsOffsetResponse,
2222
type CursorPageParams,
2323
CursorPageResponse,
24-
} from './pagination';
25-
import * as Uploads from './uploads';
24+
} from './core/pagination';
25+
import * as Uploads from './core/uploads';
2626
import * as API from './resources/index';
27-
import { APIPromise } from './api-promise';
27+
import { APIPromise } from './core/api-promise';
2828
import { type Fetch } from './internal/builtin-types';
2929
import { HeadersLike, NullableHeaders, buildHeaders } from './internal/headers';
3030
import { FinalRequestOptions, RequestOptions } from './internal/request-options';

src/core/README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# `core`
2+
3+
This directory holds public modules implementing non-resource-specific SDK functionality.

src/core/api-promise.ts

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2+
3+
import { type Writer } from '../client';
4+
5+
import { type PromiseOrValue } from '../internal/types';
6+
import { APIResponseProps, defaultParseResponse } from '../internal/parse';
7+
8+
/**
9+
* A subclass of `Promise` providing additional helper methods
10+
* for interacting with the SDK.
11+
*/
12+
export class APIPromise<T> extends Promise<T> {
13+
private parsedPromise: Promise<T> | undefined;
14+
#client: Writer;
15+
16+
constructor(
17+
client: Writer,
18+
private responsePromise: Promise<APIResponseProps>,
19+
private parseResponse: (
20+
client: Writer,
21+
props: APIResponseProps,
22+
) => PromiseOrValue<T> = defaultParseResponse,
23+
) {
24+
super((resolve) => {
25+
// this is maybe a bit weird but this has to be a no-op to not implicitly
26+
// parse the response body; instead .then, .catch, .finally are overridden
27+
// to parse the response
28+
resolve(null as any);
29+
});
30+
this.#client = client;
31+
}
32+
33+
_thenUnwrap<U>(transform: (data: T, props: APIResponseProps) => U): APIPromise<U> {
34+
return new APIPromise(this.#client, this.responsePromise, async (client, props) =>
35+
transform(await this.parseResponse(client, props), props),
36+
);
37+
}
38+
39+
/**
40+
* Gets the raw `Response` instance instead of parsing the response
41+
* data.
42+
*
43+
* If you want to parse the response body but still get the `Response`
44+
* instance, you can use {@link withResponse()}.
45+
*
46+
* 👋 Getting the wrong TypeScript type for `Response`?
47+
* Try setting `"moduleResolution": "NodeNext"` or add `"lib": ["DOM"]`
48+
* to your `tsconfig.json`.
49+
*/
50+
asResponse(): Promise<Response> {
51+
return this.responsePromise.then((p) => p.response);
52+
}
53+
54+
/**
55+
* Gets the parsed response data and the raw `Response` instance.
56+
*
57+
* If you just want to get the raw `Response` instance without parsing it,
58+
* you can use {@link asResponse()}.
59+
*
60+
* 👋 Getting the wrong TypeScript type for `Response`?
61+
* Try setting `"moduleResolution": "NodeNext"` or add `"lib": ["DOM"]`
62+
* to your `tsconfig.json`.
63+
*/
64+
async withResponse(): Promise<{ data: T; response: Response }> {
65+
const [data, response] = await Promise.all([this.parse(), this.asResponse()]);
66+
return { data, response };
67+
}
68+
69+
private parse(): Promise<T> {
70+
if (!this.parsedPromise) {
71+
this.parsedPromise = this.responsePromise.then((data) => this.parseResponse(this.#client, data));
72+
}
73+
return this.parsedPromise;
74+
}
75+
76+
override then<TResult1 = T, TResult2 = never>(
77+
onfulfilled?: ((value: T) => TResult1 | PromiseLike<TResult1>) | undefined | null,
78+
onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | undefined | null,
79+
): Promise<TResult1 | TResult2> {
80+
return this.parse().then(onfulfilled, onrejected);
81+
}
82+
83+
override catch<TResult = never>(
84+
onrejected?: ((reason: any) => TResult | PromiseLike<TResult>) | undefined | null,
85+
): Promise<T | TResult> {
86+
return this.parse().catch(onrejected);
87+
}
88+
89+
override finally(onfinally?: (() => void) | undefined | null): Promise<T> {
90+
return this.parse().finally(onfinally);
91+
}
92+
}

0 commit comments

Comments
 (0)