@@ -146,13 +146,60 @@ pattern change_completion_try_catch() {
146
146
}
147
147
}
148
148
149
+ pattern openai_v4_exports() {
150
+ or {
151
+ "ClientOptions",
152
+ "OpenAI",
153
+ "toFile",
154
+ "fileFromPath",
155
+ "APIError",
156
+ "APIConnectionError",
157
+ "APIConnectionTimeoutError",
158
+ "APIUserAbortError",
159
+ "NotFoundError",
160
+ "ConflictError",
161
+ "RateLimitError",
162
+ "BadRequestError",
163
+ "AuthenticationError",
164
+ "InternalServerError",
165
+ "PermissionDeniedError",
166
+ "UnprocessableEntityError",
167
+ }
168
+ }
169
+
149
170
pattern change_imports() {
150
171
or {
151
- `import $old from $src`,
152
- `$old = require($src)`
153
- } where {
154
- $src <: `"openai"`,
155
- $old => `OpenAI`
172
+ `import $old from $src` where {
173
+ $src <: `"openai"`,
174
+ $old <: or {
175
+ import_clause(name = named_imports($imports)) where {
176
+ if ($imports <: not contains $import_name where $import_name <: openai_v4_exports()) {
177
+ $old => js"OpenAI",
178
+ } else {
179
+ $imports <: some bubble $name => . where {
180
+ $name <: not openai_v4_exports(),
181
+ },
182
+ if ($old <: not contains js"OpenAI") {
183
+ $old => js"OpenAI, $old",
184
+ }
185
+ }
186
+ }
187
+ },
188
+ },
189
+ `$old = require($src)` as $require where {
190
+ $old <: object_pattern($properties) where {
191
+ if ($properties <: not contains $import_name where $import_name <: openai_v4_exports()) {
192
+ $old => js"OpenAI",
193
+ } else {
194
+ $properties <: some bubble $name => . where {
195
+ $name <: not openai_v4_exports(),
196
+ },
197
+ if ($program <: not contains `OpenAI = require($src)`) {
198
+ $require => `OpenAI = require($src);\nconst $require`
199
+ }
200
+ }
201
+ }
202
+ }
156
203
}
157
204
}
158
205
@@ -188,8 +235,12 @@ pattern fix_types() {
188
235
`FineTuneEvent` => `OpenAI.FineTuneEvent`,
189
236
`ImagesResponse` => `OpenAI.ImagesResponse`,
190
237
`OpenAIFile` => `OpenAI.FileObject`,
191
- } as $thing where {
192
- $thing <: imported_from(from=`"openai"`)
238
+ } as $thing where or {
239
+ $thing <: imported_from(from=`"openai"`),
240
+ $program <: contains `$old = require($from)` where {
241
+ $from <: `"openai"`,
242
+ $old <: contains $thing,
243
+ },
193
244
}
194
245
}
195
246
@@ -204,7 +255,12 @@ file(body = program($statements)) where $statements <: and {
204
255
contains openai_misc_renames(),
205
256
contains change_completion_try_catch(),
206
257
contains change_imports(),
207
- contains fix_types()
258
+ contains fix_types() until or {
259
+ import_statement(),
260
+ variable_declarator($value) where {
261
+ $value <: call_expression(function="require")
262
+ }
263
+ },
208
264
}
209
265
}
210
266
```
@@ -455,3 +511,98 @@ const response: OpenAI.Chat.Completions.ChatCompletion = 3;
455
511
// should not be changed because not imported from 'openai'
456
512
const fineTune: FineTune = 4 ;
457
513
```
514
+
515
+ ## Preserves v4 OpenAI ESM imports
516
+
517
+ ``` ts
518
+ import {
519
+ ChatCompletionRequestMessage ,
520
+ CreateChatCompletionRequest ,
521
+ CreateChatCompletionResponse ,
522
+ toFile ,
523
+ } from ' openai' ;
524
+
525
+ // imported, so should change
526
+ const messages: ChatCompletionRequestMessage = 1 ;
527
+ const request: CreateChatCompletionRequest = 2 ;
528
+ const response: CreateChatCompletionResponse = 3 ;
529
+
530
+ // should not be changed because not imported from 'openai'
531
+ const fineTune: FineTune = 4 ;
532
+ ```
533
+
534
+ ``` ts
535
+ import OpenAI , { toFile } from ' openai' ;
536
+
537
+ // imported, so should change
538
+ const messages: OpenAI .Chat .CreateChatCompletionRequestMessage = 1 ;
539
+ const request: OpenAI .Chat .CompletionCreateParamsNonStreaming = 2 ;
540
+ const response: OpenAI .Chat .Completions .ChatCompletion = 3 ;
541
+
542
+ // should not be changed because not imported from 'openai'
543
+ const fineTune: FineTune = 4 ;
544
+ ```
545
+
546
+ ## Does not double import OpenAI
547
+
548
+ ``` ts
549
+ import OpenAI , {
550
+ ChatCompletionRequestMessage ,
551
+ CreateChatCompletionRequest ,
552
+ CreateChatCompletionResponse ,
553
+ toFile ,
554
+ } from ' openai' ;
555
+
556
+ // imported, so should change
557
+ const messages: ChatCompletionRequestMessage = 1 ;
558
+ const request: CreateChatCompletionRequest = 2 ;
559
+ const response: CreateChatCompletionResponse = 3 ;
560
+
561
+ // should not be changed because not imported from 'openai'
562
+ const fineTune: FineTune = 4 ;
563
+ ```
564
+
565
+ ``` ts
566
+ import OpenAI , { toFile } from ' openai' ;
567
+
568
+ // imported, so should change
569
+ const messages: OpenAI .Chat .CreateChatCompletionRequestMessage = 1 ;
570
+ const request: OpenAI .Chat .CompletionCreateParamsNonStreaming = 2 ;
571
+ const response: OpenAI .Chat .Completions .ChatCompletion = 3 ;
572
+
573
+ // should not be changed because not imported from 'openai'
574
+ const fineTune: FineTune = 4 ;
575
+ ```
576
+
577
+ ## Preserves v4 OpenAI CommonJS imports
578
+
579
+ ``` ts
580
+ const {
581
+ ChatCompletionRequestMessage,
582
+ CreateChatCompletionRequest,
583
+ CreateChatCompletionResponse,
584
+ Configuration,
585
+ toFile,
586
+ } = require (' openai' );
587
+
588
+ // imported, so should change
589
+ const messages: ChatCompletionRequestMessage = 1 ;
590
+ const request: CreateChatCompletionRequest = 2 ;
591
+ const response: CreateChatCompletionResponse = 3 ;
592
+
593
+ // should not be changed because not imported from 'openai'
594
+ const fineTune: FineTune = 4 ;
595
+ ```
596
+
597
+ ``` ts
598
+ const OpenAI = require (' openai' );
599
+ const { toFile } = require (' openai' );
600
+
601
+ // imported, so should change
602
+ const messages: OpenAI .Chat .CreateChatCompletionRequestMessage = 1 ;
603
+ const request: OpenAI .Chat .CompletionCreateParamsNonStreaming = 2 ;
604
+ const response: OpenAI .Chat .Completions .ChatCompletion = 3 ;
605
+
606
+ // should not be changed because not imported from 'openai'
607
+ const fineTune: FineTune = 4 ;
608
+ ```
0 commit comments