Skip to content

Commit 38c9d54

Browse files
stainless-app[bot]RobertCraigie
authored andcommitted
chore(client): move misc public files to new core/ directory, deprecate old paths
1 parent 0c21914 commit 38c9d54

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

61 files changed

+969
-940
lines changed

MIGRATION.md

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

322322
### Removed exports
323323

324-
#### `Response`
325-
326-
```typescript
327-
// Before
328-
import { Response } from 'openai';
329-
330-
// After
331-
// `Response` must now come from the builtin types
332-
```
333-
334324
#### Resource classes
335325

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

338329
```typescript
339330
// Before
340-
import { Completions } from 'openai';
331+
const { Completions } = require('openai');
341332

342333
// After
343-
import { Completions } from 'openai/resources/completions';
334+
const { OpenAI } = require('openai');
335+
OpenAI.Completions; // or import directly from openai/resources/completions
344336
```
345337

346-
#### `openai/core`
338+
#### Refactor of `openai/core`, `error`, `pagination`, `resource`, `streaming` and `uploads`
347339

348-
The `openai/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.
340+
Much of the `openai/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.
349341

350-
If you were relying on anything that was only exported from `openai/core` and is also not accessible anywhere else, please open an issue and we'll consider adding it to the public API.
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:
342+
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:
355343

356344
```typescript
357345
// Before
358-
import { APIClient } from 'openai/core';
346+
import 'openai/error';
347+
import 'openai/pagination';
348+
import 'openai/resource';
349+
import 'openai/streaming';
350+
import 'openai/uploads';
359351

360352
// After
361-
import { OpenAI } from 'openai';
353+
import 'openai/core/error';
354+
import 'openai/core/pagination';
355+
import 'openai/core/resource';
356+
import 'openai/core/streaming';
357+
import 'openai/core/uploads';
362358
```
363359

364-
#### Cleaned up `openai/uploads` exports
360+
If you were relying on anything that was only exported from `openai/core` and is also not accessible anywhere else, please open an issue and we'll consider adding it to the public API.
361+
362+
#### Cleaned up `uploads` exports
365363

366-
The following exports have been removed from `openai/uploads` as they were not intended to be a part of the public API:
364+
As part of the `core` refactor, `openai/uploads` was moved to `openai/core/uploads`
365+
and the following exports were removed, as they were not intended to be a part of the public API:
367366

368367
- `fileFromPath`
369368
- `BlobPart`
@@ -382,5 +381,17 @@ The following exports have been removed from `openai/uploads` as they were not i
382381
Note that `Uploadable` & `toFile` **are** still exported:
383382

384383
```typescript
385-
import { type Uploadable, toFile } from 'openai/uploads';
384+
import { type Uploadable, toFile } from 'openai/core/uploads';
385+
```
386+
387+
#### `APIClient`
388+
389+
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:
390+
391+
```typescript
392+
// Before
393+
import { APIClient } from 'openai/core';
394+
395+
// After
396+
import { OpenAI } from 'openai';
386397
```

src/api-promise.ts

Lines changed: 2 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -1,101 +1,2 @@
1-
// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2-
3-
import { type OpenAI } from './client';
4-
5-
import { type PromiseOrValue } from './internal/types';
6-
import {
7-
type APIResponseProps,
8-
defaultParseResponse,
9-
type WithRequestID,
10-
addRequestID,
11-
} from './internal/parse';
12-
13-
/**
14-
* A subclass of `Promise` providing additional helper methods
15-
* for interacting with the SDK.
16-
*/
17-
export class APIPromise<T> extends Promise<WithRequestID<T>> {
18-
private parsedPromise: Promise<WithRequestID<T>> | undefined;
19-
#client: OpenAI;
20-
21-
constructor(
22-
client: OpenAI,
23-
private responsePromise: Promise<APIResponseProps>,
24-
private parseResponse: (
25-
client: OpenAI,
26-
props: APIResponseProps,
27-
) => PromiseOrValue<WithRequestID<T>> = defaultParseResponse,
28-
) {
29-
super((resolve) => {
30-
// this is maybe a bit weird but this has to be a no-op to not implicitly
31-
// parse the response body; instead .then, .catch, .finally are overridden
32-
// to parse the response
33-
resolve(null as any);
34-
});
35-
this.#client = client;
36-
}
37-
38-
_thenUnwrap<U>(transform: (data: T, props: APIResponseProps) => U): APIPromise<U> {
39-
return new APIPromise(this.#client, this.responsePromise, async (client, props) =>
40-
addRequestID(transform(await this.parseResponse(client, props), props), props.response),
41-
);
42-
}
43-
44-
/**
45-
* Gets the raw `Response` instance instead of parsing the response
46-
* data.
47-
*
48-
* If you want to parse the response body but still get the `Response`
49-
* instance, you can use {@link withResponse()}.
50-
*
51-
* 👋 Getting the wrong TypeScript type for `Response`?
52-
* Try setting `"moduleResolution": "NodeNext"` or add `"lib": ["DOM"]`
53-
* to your `tsconfig.json`.
54-
*/
55-
asResponse(): Promise<Response> {
56-
return this.responsePromise.then((p) => p.response);
57-
}
58-
59-
/**
60-
* Gets the parsed response data, the raw `Response` instance and the ID of the request,
61-
* returned via the X-Request-ID header which is useful for debugging requests and reporting
62-
* issues to OpenAI.
63-
*
64-
* If you just want to get the raw `Response` instance without parsing it,
65-
* you can use {@link asResponse()}.
66-
*
67-
* 👋 Getting the wrong TypeScript type for `Response`?
68-
* Try setting `"moduleResolution": "NodeNext"` or add `"lib": ["DOM"]`
69-
* to your `tsconfig.json`.
70-
*/
71-
async withResponse(): Promise<{ data: T; response: Response; request_id: string | null }> {
72-
const [data, response] = await Promise.all([this.parse(), this.asResponse()]);
73-
return { data, response, request_id: response.headers.get('x-request-id') };
74-
}
75-
76-
private parse(): Promise<WithRequestID<T>> {
77-
if (!this.parsedPromise) {
78-
this.parsedPromise = this.responsePromise.then((data) =>
79-
this.parseResponse(this.#client, data),
80-
) as any as Promise<WithRequestID<T>>;
81-
}
82-
return this.parsedPromise;
83-
}
84-
85-
override then<TResult1 = WithRequestID<T>, TResult2 = never>(
86-
onfulfilled?: ((value: WithRequestID<T>) => TResult1 | PromiseLike<TResult1>) | undefined | null,
87-
onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | undefined | null,
88-
): Promise<TResult1 | TResult2> {
89-
return this.parse().then(onfulfilled, onrejected);
90-
}
91-
92-
override catch<TResult = never>(
93-
onrejected?: ((reason: any) => TResult | PromiseLike<TResult>) | undefined | null,
94-
): Promise<WithRequestID<T> | TResult> {
95-
return this.parse().catch(onrejected);
96-
}
97-
98-
override finally(onfinally?: (() => void) | undefined | null): Promise<WithRequestID<T>> {
99-
return this.parse().finally(onfinally);
100-
}
101-
}
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
@@ -14,12 +14,12 @@ import * as Shims from './internal/shims';
1414
import * as Opts from './internal/request-options';
1515
import * as qs from './internal/qs';
1616
import { VERSION } from './version';
17-
import * as Errors from './error';
18-
import * as Pagination from './pagination';
19-
import { AbstractPage, type CursorPageParams, CursorPageResponse, PageResponse } from './pagination';
20-
import * as Uploads from './uploads';
17+
import * as Errors from './core/error';
18+
import * as Pagination from './core/pagination';
19+
import { AbstractPage, type CursorPageParams, CursorPageResponse, PageResponse } from './core/pagination';
20+
import * as Uploads from './core/uploads';
2121
import * as API from './resources/index';
22-
import { APIPromise } from './api-promise';
22+
import { APIPromise } from './core/api-promise';
2323
import { type Fetch } from './internal/builtin-types';
2424
import { isRunningInBrowser } from './internal/detect-platform';
2525
import { HeadersLike, NullableHeaders, buildHeaders } from './internal/headers';

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

0 commit comments

Comments
 (0)