fork of hey-api/openapi-ts because I need some additional things

Merge pull request #910 from hey-api/fix/prerequisite-checks

fix: throw if prerequisite checks are not met

authored by

Lubos and committed by
GitHub
a13f7349 5161e1aa

+1128 -36
+5
.changeset/brown-weeks-dream.md
··· 1 + --- 2 + '@hey-api/openapi-ts': patch 3 + --- 4 + 5 + fix: throw if prerequisite checks are not met
+1 -1
packages/openapi-ts/src/generate/__tests__/index.spec.ts
··· 43 43 }), 44 44 types: new TypeScriptFile({ 45 45 dir: '/', 46 - name: 'models.ts', 46 + name: 'types.ts', 47 47 }), 48 48 }; 49 49
+21
packages/openapi-ts/src/generate/__tests__/services.spec.ts
··· 3 3 4 4 import { describe, expect, it, vi } from 'vitest'; 5 5 6 + import { TypeScriptFile } from '../../compiler'; 6 7 import type { Operation } from '../../openApi'; 7 8 import type { Files } from '../../types/utils'; 8 9 import { setConfig } from '../../utils/config'; ··· 72 73 }; 73 74 74 75 const files: Files = {}; 76 + 77 + files.types = new TypeScriptFile({ 78 + dir: '/', 79 + name: 'types.ts', 80 + }); 75 81 76 82 await generateServices({ client, files }); 77 83 ··· 148 154 }); 149 155 150 156 const files: Files = {}; 157 + 158 + files.types = new TypeScriptFile({ 159 + dir: '/', 160 + name: 'types.ts', 161 + }); 151 162 152 163 await generateServices({ client, files }); 153 164 ··· 187 198 188 199 const files: Files = {}; 189 200 201 + files.types = new TypeScriptFile({ 202 + dir: '/', 203 + name: 'types.ts', 204 + }); 205 + 190 206 await generateServices({ client, files }); 191 207 192 208 files.services.write(); ··· 226 242 }); 227 243 228 244 const files: Files = {}; 245 + 246 + files.types = new TypeScriptFile({ 247 + dir: '/', 248 + name: 'types.ts', 249 + }); 229 250 230 251 await generateServices({ client, files }); 231 252
+2 -2
packages/openapi-ts/src/generate/__tests__/types.spec.ts
··· 68 68 const files = { 69 69 types: new TypeScriptFile({ 70 70 dir: '/', 71 - name: 'models.ts', 71 + name: 'types.ts', 72 72 }), 73 73 }; 74 74 ··· 80 80 files.types.write(); 81 81 82 82 expect(writeFileSync).toHaveBeenCalledWith( 83 - path.resolve('/models.gen.ts'), 83 + path.resolve('/types.gen.ts'), 84 84 expect.anything(), 85 85 ); 86 86 });
+12 -9
packages/openapi-ts/src/generate/plugins.ts
··· 50 50 return; 51 51 } 52 52 53 - for (const plugin of config.plugins) { 53 + config.plugins.forEach((plugin) => { 54 54 const outputParts = plugin.output.split('/'); 55 55 const outputDir = path.resolve( 56 56 config.output.path, ··· 66 66 plugin.name === '@tanstack/react-query' || 67 67 plugin.name === '@tanstack/vue-query' 68 68 ) { 69 - const paginationWordsRegExp = /^(cursor|offset|page|start)/; 69 + const checkPrerequisites = ({ files }: { files: Files }) => { 70 + if (!files.services) { 71 + throw new Error( 72 + '🚫 services need to be exported to use TanStack Query plugin - enable service generation', 73 + ); 74 + } 75 + }; 76 + 77 + checkPrerequisites({ files }); 70 78 71 - if (!files.services) { 72 - // TODO: throw 73 - } 74 - if (!files.types) { 75 - // TODO: throw 76 - } 79 + const paginationWordsRegExp = /^(cursor|offset|page|start)/; 77 80 78 81 file.import({ 79 82 asType: true, ··· 935 938 } 936 939 } 937 940 } 938 - } 941 + }); 939 942 };
+17 -3
packages/openapi-ts/src/generate/services.ts
··· 701 701 onNode(statement); 702 702 }; 703 703 704 + const checkPrerequisites = ({ files }: { files: Files }) => { 705 + const config = getConfig(); 706 + 707 + if (!config.client.name) { 708 + throw new Error( 709 + '🚫 client needs to be set to generate services - which HTTP client do you want to use?', 710 + ); 711 + } 712 + 713 + if (!files.types) { 714 + throw new Error( 715 + '🚫 types need to be exported to generate services - enable type generation', 716 + ); 717 + } 718 + }; 719 + 704 720 export const generateServices = async ({ 705 721 client, 706 722 files, ··· 714 730 return; 715 731 } 716 732 717 - if (!files.types) { 718 - // TODO: throw 719 - } 733 + checkPrerequisites({ files }); 720 734 721 735 const isStandalone = isStandaloneClient(config); 722 736
+2 -8
packages/openapi-ts/src/index.ts
··· 100 100 const getClient = (userConfig: ClientConfig): Config['client'] => { 101 101 let client: Config['client'] = { 102 102 bundle: false, 103 - // @ts-ignore 104 103 name: '', 105 104 }; 106 105 if (typeof userConfig.client === 'string') { ··· 261 260 262 261 const client = getClient(userConfig); 263 262 264 - if (!client.name) { 265 - throw new Error( 266 - '🚫 missing client - which HTTP client do you want to generate?', 267 - ); 268 - } 269 - 270 263 if (!useOptions) { 271 264 console.warn( 272 265 '⚠️ Deprecation warning: useOptions set to false. This setting will be removed in future versions. Please migrate useOptions to true https://heyapi.vercel.app/openapi-ts/migrating.html#v0-27-38', ··· 286 279 configFile, 287 280 debug, 288 281 dryRun, 289 - exportCore: isStandaloneClient(client) ? false : exportCore, 282 + exportCore: 283 + isStandaloneClient(client) || !client.name ? false : exportCore, 290 284 input, 291 285 name, 292 286 output,
+2 -1
packages/openapi-ts/src/types/config.ts
··· 9 9 | 'axios' 10 10 | 'fetch' 11 11 | 'node' 12 - | 'xhr'; 12 + | 'xhr' 13 + | ''; 13 14 14 15 export interface ClientConfig { 15 16 /**
+2 -1
packages/openapi-ts/test/__snapshots__/test/generated/v3_services_filter/index.ts.snap
··· 1 1 // This file is auto-generated by @hey-api/openapi-ts 2 - export * from './services.gen'; 2 + export * from './services.gen'; 3 + export * from './types.gen';
+1054
packages/openapi-ts/test/__snapshots__/test/generated/v3_services_filter/types.gen.ts.snap
··· 1 + // This file is auto-generated by @hey-api/openapi-ts 2 + 3 + /** 4 + * Model with number-only name 5 + */ 6 + export type _400 = string; 7 + 8 + /** 9 + * Testing multiline comments in string: First line 10 + * Second line 11 + * 12 + * Fourth line 13 + */ 14 + export type camelCaseCommentWithBreaks = number; 15 + 16 + /** 17 + * Testing multiline comments in string: First line 18 + * Second line 19 + * 20 + * Fourth line 21 + */ 22 + export type CommentWithBreaks = number; 23 + 24 + /** 25 + * Testing backticks in string: `backticks` and ```multiple backticks``` should work 26 + */ 27 + export type CommentWithBackticks = number; 28 + 29 + /** 30 + * Testing backticks and quotes in string: `backticks`, 'quotes', "double quotes" and ```multiple backticks``` should work 31 + */ 32 + export type CommentWithBackticksAndQuotes = number; 33 + 34 + /** 35 + * Testing slashes in string: \backwards\\\ and /forwards/// should work 36 + */ 37 + export type CommentWithSlashes = number; 38 + 39 + /** 40 + * Testing expression placeholders in string: ${expression} should work 41 + */ 42 + export type CommentWithExpressionPlaceholders = number; 43 + 44 + /** 45 + * Testing quotes in string: 'single quote''' and "double quotes""" should work 46 + */ 47 + export type CommentWithQuotes = number; 48 + 49 + /** 50 + * Testing reserved characters in string: * inline * and ** inline ** should work 51 + */ 52 + export type CommentWithReservedCharacters = number; 53 + 54 + /** 55 + * This is a simple number 56 + */ 57 + export type SimpleInteger = number; 58 + 59 + /** 60 + * This is a simple boolean 61 + */ 62 + export type SimpleBoolean = boolean; 63 + 64 + /** 65 + * This is a simple string 66 + */ 67 + export type SimpleString = string; 68 + 69 + /** 70 + * A string with non-ascii (unicode) characters valid in typescript identifiers (æøåÆØÅöÔèÈ字符串) 71 + */ 72 + export type NonAsciiStringæøåÆØÅöôêÊ字符串 = string; 73 + 74 + /** 75 + * This is a simple file 76 + */ 77 + export type SimpleFile = (Blob | File); 78 + 79 + /** 80 + * This is a simple reference 81 + */ 82 + export type SimpleReference = ModelWithString; 83 + 84 + /** 85 + * This is a simple string 86 + */ 87 + export type SimpleStringWithPattern = string | null; 88 + 89 + /** 90 + * This is a simple enum with strings 91 + */ 92 + export type EnumWithStrings = 'Success' | 'Warning' | 'Error' | "'Single Quote'" | '"Double Quotes"' | 'Non-ascii: øæåôöØÆÅÔÖ字符串'; 93 + 94 + /** 95 + * This is a simple enum with strings 96 + */ 97 + export const EnumWithStrings = { 98 + SUCCESS: 'Success', 99 + WARNING: 'Warning', 100 + ERROR: 'Error', 101 + _SINGLE_QUOTE_: "'Single Quote'", 102 + _DOUBLE_QUOTES_: '"Double Quotes"', 103 + NON_ASCII__ØÆÅÔÖ_ØÆÅÔÖ字符串: 'Non-ascii: øæåôöØÆÅÔÖ字符串' 104 + } as const; 105 + 106 + export type EnumWithReplacedCharacters = "'Single Quote'" | '"Double Quotes"' | 'øæåôöØÆÅÔÖ字符串' | 3.1 | ''; 107 + 108 + export const EnumWithReplacedCharacters = { 109 + _SINGLE_QUOTE_: "'Single Quote'", 110 + _DOUBLE_QUOTES_: '"Double Quotes"', 111 + ØÆÅÔÖ_ØÆÅÔÖ字符串: 'øæåôöØÆÅÔÖ字符串', 112 + '_3.1': 3.1, 113 + EMPTY_STRING: '' 114 + } as const; 115 + 116 + /** 117 + * This is a simple enum with numbers 118 + */ 119 + export type EnumWithNumbers = 1 | 2 | 3 | 1.1 | 1.2 | 1.3 | 100 | 200 | 300 | -100 | -200 | -300 | -1.1 | -1.2 | -1.3; 120 + 121 + /** 122 + * This is a simple enum with numbers 123 + */ 124 + export const EnumWithNumbers = { 125 + '_1': 1, 126 + '_2': 2, 127 + '_3': 3, 128 + '_1.1': 1.1, 129 + '_1.2': 1.2, 130 + '_1.3': 1.3, 131 + '_100': 100, 132 + '_200': 200, 133 + '_300': 300, 134 + '_-100': -100, 135 + '_-200': -200, 136 + '_-300': -300, 137 + '_-1.1': -1.1, 138 + '_-1.2': -1.2, 139 + '_-1.3': -1.3 140 + } as const; 141 + 142 + /** 143 + * Success=1,Warning=2,Error=3 144 + */ 145 + export type EnumFromDescription = number; 146 + 147 + /** 148 + * This is a simple enum with numbers 149 + */ 150 + export type EnumWithExtensions = 200 | 400 | 500; 151 + 152 + /** 153 + * This is a simple enum with numbers 154 + */ 155 + export const EnumWithExtensions = { 156 + /** 157 + * Used when the status of something is successful 158 + */ 159 + CUSTOM_SUCCESS: 200, 160 + /** 161 + * Used when the status of something has a warning 162 + */ 163 + CUSTOM_WARNING: 400, 164 + /** 165 + * Used when the status of something has an error 166 + */ 167 + CUSTOM_ERROR: 500 168 + } as const; 169 + 170 + export type EnumWithXEnumNames = 0 | 1 | 2; 171 + 172 + export const EnumWithXEnumNames = { 173 + zero: 0, 174 + one: 1, 175 + two: 2 176 + } as const; 177 + 178 + /** 179 + * This is a simple array with numbers 180 + */ 181 + export type ArrayWithNumbers = Array<(number)>; 182 + 183 + /** 184 + * This is a simple array with booleans 185 + */ 186 + export type ArrayWithBooleans = Array<(boolean)>; 187 + 188 + /** 189 + * This is a simple array with strings 190 + */ 191 + export type ArrayWithStrings = Array<(string)>; 192 + 193 + /** 194 + * This is a simple array with references 195 + */ 196 + export type ArrayWithReferences = Array<ModelWithString>; 197 + 198 + /** 199 + * This is a simple array containing an array 200 + */ 201 + export type ArrayWithArray = Array<Array<ModelWithString>>; 202 + 203 + /** 204 + * This is a simple array with properties 205 + */ 206 + export type ArrayWithProperties = Array<{ 207 + '16x16'?: camelCaseCommentWithBreaks; 208 + bar?: string; 209 + }>; 210 + 211 + /** 212 + * This is a simple array with any of properties 213 + */ 214 + export type ArrayWithAnyOfProperties = Array<({ 215 + foo?: string; 216 + } | { 217 + bar?: string; 218 + })>; 219 + 220 + export type AnyOfAnyAndNull = { 221 + data?: unknown | null; 222 + }; 223 + 224 + /** 225 + * This is a simple array with any of properties 226 + */ 227 + export type AnyOfArrays = { 228 + results?: Array<({ 229 + foo?: string; 230 + } | { 231 + bar?: string; 232 + })>; 233 + }; 234 + 235 + /** 236 + * This is a string dictionary 237 + */ 238 + export type DictionaryWithString = { 239 + [key: string]: (string); 240 + }; 241 + 242 + export type DictionaryWithPropertiesAndAdditionalProperties = { 243 + foo?: number; 244 + bar?: boolean; 245 + [key: string]: (string | number | boolean) | undefined; 246 + }; 247 + 248 + /** 249 + * This is a string reference 250 + */ 251 + export type DictionaryWithReference = { 252 + [key: string]: ModelWithString; 253 + }; 254 + 255 + /** 256 + * This is a complex dictionary 257 + */ 258 + export type DictionaryWithArray = { 259 + [key: string]: Array<ModelWithString>; 260 + }; 261 + 262 + /** 263 + * This is a string dictionary 264 + */ 265 + export type DictionaryWithDictionary = { 266 + [key: string]: { 267 + [key: string]: (string); 268 + }; 269 + }; 270 + 271 + /** 272 + * This is a complex dictionary 273 + */ 274 + export type DictionaryWithProperties = { 275 + [key: string]: { 276 + foo?: string; 277 + bar?: string; 278 + }; 279 + }; 280 + 281 + /** 282 + * This is a model with one number property 283 + */ 284 + export type ModelWithInteger = { 285 + /** 286 + * This is a simple number property 287 + */ 288 + prop?: number; 289 + }; 290 + 291 + /** 292 + * This is a model with one boolean property 293 + */ 294 + export type ModelWithBoolean = { 295 + /** 296 + * This is a simple boolean property 297 + */ 298 + prop?: boolean; 299 + }; 300 + 301 + /** 302 + * This is a model with one string property 303 + */ 304 + export type ModelWithString = { 305 + /** 306 + * This is a simple string property 307 + */ 308 + prop?: string; 309 + }; 310 + 311 + /** 312 + * This is a model with one string property 313 + */ 314 + export type ModelWithStringError = { 315 + /** 316 + * This is a simple string property 317 + */ 318 + prop?: string; 319 + }; 320 + 321 + /** 322 + * `Comment` or `VoiceComment`. The JSON object for adding voice comments to tickets is different. See [Adding voice comments to tickets](/documentation/ticketing/managing-tickets/adding-voice-comments-to-tickets) 323 + */ 324 + export type Model_From_Zendesk = string; 325 + 326 + /** 327 + * This is a model with one string property 328 + */ 329 + export type ModelWithNullableString = { 330 + /** 331 + * This is a simple string property 332 + */ 333 + nullableProp1?: string | null; 334 + /** 335 + * This is a simple string property 336 + */ 337 + nullableRequiredProp1: string | null; 338 + /** 339 + * This is a simple string property 340 + */ 341 + nullableProp2?: string | null; 342 + /** 343 + * This is a simple string property 344 + */ 345 + nullableRequiredProp2: string | null; 346 + /** 347 + * This is a simple enum with strings 348 + */ 349 + 'foo_bar-enum'?: 'Success' | 'Warning' | 'Error' | 'ØÆÅ字符串'; 350 + }; 351 + 352 + /** 353 + * This is a simple enum with strings 354 + */ 355 + export type foo_bar_enum = 'Success' | 'Warning' | 'Error' | 'ØÆÅ字符串'; 356 + 357 + /** 358 + * This is a simple enum with strings 359 + */ 360 + export const foo_bar_enum = { 361 + SUCCESS: 'Success', 362 + WARNING: 'Warning', 363 + ERROR: 'Error', 364 + ØÆÅ字符串: 'ØÆÅ字符串' 365 + } as const; 366 + 367 + /** 368 + * This is a model with one enum 369 + */ 370 + export type ModelWithEnum = { 371 + /** 372 + * This is a simple enum with strings 373 + */ 374 + 'foo_bar-enum'?: 'Success' | 'Warning' | 'Error' | 'ØÆÅ字符串'; 375 + /** 376 + * These are the HTTP error code enums 377 + */ 378 + statusCode?: '100' | '200 FOO' | '300 FOO_BAR' | '400 foo-bar' | '500 foo.bar' | '600 foo&bar'; 379 + /** 380 + * Simple boolean enum 381 + */ 382 + bool?: boolean; 383 + }; 384 + 385 + /** 386 + * These are the HTTP error code enums 387 + */ 388 + export type statusCode = '100' | '200 FOO' | '300 FOO_BAR' | '400 foo-bar' | '500 foo.bar' | '600 foo&bar'; 389 + 390 + /** 391 + * These are the HTTP error code enums 392 + */ 393 + export const statusCode = { 394 + _100: '100', 395 + _200_FOO: '200 FOO', 396 + _300_FOO_BAR: '300 FOO_BAR', 397 + _400_FOO_BAR: '400 foo-bar', 398 + _500_FOO_BAR: '500 foo.bar', 399 + _600_FOO_BAR: '600 foo&bar' 400 + } as const; 401 + 402 + /** 403 + * This is a model with one enum with escaped name 404 + */ 405 + export type ModelWithEnumWithHyphen = { 406 + 'foo-bar-baz-qux'?: '3.0'; 407 + }; 408 + 409 + export type foo_bar_baz_qux = '3.0'; 410 + 411 + export const foo_bar_baz_qux = { 412 + _3_0: '3.0' 413 + } as const; 414 + 415 + /** 416 + * This is a model with one enum 417 + */ 418 + export type ModelWithEnumFromDescription = { 419 + /** 420 + * Success=1,Warning=2,Error=3 421 + */ 422 + test?: number; 423 + }; 424 + 425 + /** 426 + * This is a model with nested enums 427 + */ 428 + export type ModelWithNestedEnums = { 429 + dictionaryWithEnum?: { 430 + [key: string]: ('Success' | 'Warning' | 'Error'); 431 + }; 432 + dictionaryWithEnumFromDescription?: { 433 + [key: string]: (number); 434 + }; 435 + arrayWithEnum?: Array<('Success' | 'Warning' | 'Error')>; 436 + arrayWithDescription?: Array<(number)>; 437 + /** 438 + * This is a simple enum with strings 439 + */ 440 + 'foo_bar-enum'?: 'Success' | 'Warning' | 'Error' | 'ØÆÅ字符串'; 441 + }; 442 + 443 + /** 444 + * This is a model with one property containing a reference 445 + */ 446 + export type ModelWithReference = { 447 + prop?: ModelWithProperties; 448 + }; 449 + 450 + /** 451 + * This is a model with one property containing an array 452 + */ 453 + export type ModelWithArrayReadOnlyAndWriteOnly = { 454 + prop?: Array<ModelWithReadOnlyAndWriteOnly>; 455 + propWithFile?: Array<((Blob | File))>; 456 + propWithNumber?: Array<(number)>; 457 + }; 458 + 459 + /** 460 + * This is a model with one property containing an array 461 + */ 462 + export type ModelWithArray = { 463 + prop?: Array<ModelWithString>; 464 + propWithFile?: Array<((Blob | File))>; 465 + propWithNumber?: Array<(number)>; 466 + }; 467 + 468 + /** 469 + * This is a model with one property containing a dictionary 470 + */ 471 + export type ModelWithDictionary = { 472 + prop?: { 473 + [key: string]: (string); 474 + }; 475 + }; 476 + 477 + /** 478 + * This is a deprecated model with a deprecated property 479 + * @deprecated 480 + */ 481 + export type DeprecatedModel = { 482 + /** 483 + * This is a deprecated property 484 + * @deprecated 485 + */ 486 + prop?: string; 487 + }; 488 + 489 + /** 490 + * This is a model with one property containing a circular reference 491 + */ 492 + export type ModelWithCircularReference = { 493 + prop?: ModelWithCircularReference; 494 + }; 495 + 496 + /** 497 + * This is a model with one property with a 'one of' relationship 498 + */ 499 + export type CompositionWithOneOf = { 500 + propA?: ModelWithString | ModelWithEnum | ModelWithArray | ModelWithDictionary; 501 + }; 502 + 503 + /** 504 + * This is a model with one property with a 'one of' relationship where the options are not $ref 505 + */ 506 + export type CompositionWithOneOfAnonymous = { 507 + propA?: { 508 + propA?: string; 509 + } | string | number; 510 + }; 511 + 512 + /** 513 + * Circle 514 + */ 515 + export type ModelCircle = { 516 + kind: 'circle'; 517 + radius?: number; 518 + }; 519 + 520 + /** 521 + * Square 522 + */ 523 + export type ModelSquare = { 524 + kind: 'square'; 525 + sideLength?: number; 526 + }; 527 + 528 + /** 529 + * This is a model with one property with a 'one of' relationship where the options are not $ref 530 + */ 531 + export type CompositionWithOneOfDiscriminator = ModelCircle | ModelSquare; 532 + 533 + /** 534 + * This is a model with one property with a 'any of' relationship 535 + */ 536 + export type CompositionWithAnyOf = { 537 + propA?: ModelWithString | ModelWithEnum | ModelWithArray | ModelWithDictionary; 538 + }; 539 + 540 + /** 541 + * This is a model with one property with a 'any of' relationship where the options are not $ref 542 + */ 543 + export type CompositionWithAnyOfAnonymous = { 544 + propA?: { 545 + propA?: string; 546 + } | string | number; 547 + }; 548 + 549 + /** 550 + * This is a model with nested 'any of' property with a type null 551 + */ 552 + export type CompositionWithNestedAnyAndTypeNull = { 553 + propA?: Array<(ModelWithDictionary | null)> | Array<(ModelWithArray | null)>; 554 + }; 555 + 556 + export type _3e_num_1Период = 'Bird' | 'Dog'; 557 + 558 + export const _3e_num_1Период = { 559 + BIRD: 'Bird', 560 + DOG: 'Dog' 561 + } as const; 562 + 563 + export type ConstValue = "ConstValue"; 564 + 565 + /** 566 + * This is a model with one property with a 'any of' relationship where the options are not $ref 567 + */ 568 + export type CompositionWithNestedAnyOfAndNull = { 569 + propA?: Array<(_3e_num_1Период | ConstValue)> | null; 570 + }; 571 + 572 + /** 573 + * This is a model with one property with a 'one of' relationship 574 + */ 575 + export type CompositionWithOneOfAndNullable = { 576 + propA?: { 577 + boolean?: boolean; 578 + } | ModelWithEnum | ModelWithArray | ModelWithDictionary | null; 579 + }; 580 + 581 + /** 582 + * This is a model that contains a simple dictionary within composition 583 + */ 584 + export type CompositionWithOneOfAndSimpleDictionary = { 585 + propA?: boolean | { 586 + [key: string]: (number); 587 + }; 588 + }; 589 + 590 + /** 591 + * This is a model that contains a dictionary of simple arrays within composition 592 + */ 593 + export type CompositionWithOneOfAndSimpleArrayDictionary = { 594 + propA?: boolean | { 595 + [key: string]: Array<(boolean)>; 596 + }; 597 + }; 598 + 599 + /** 600 + * This is a model that contains a dictionary of complex arrays (composited) within composition 601 + */ 602 + export type CompositionWithOneOfAndComplexArrayDictionary = { 603 + propA?: boolean | { 604 + [key: string]: Array<(number | string)>; 605 + }; 606 + }; 607 + 608 + /** 609 + * This is a model with one property with a 'all of' relationship 610 + */ 611 + export type CompositionWithAllOfAndNullable = { 612 + propA?: ({ 613 + boolean?: boolean; 614 + } & ModelWithEnum & ModelWithArray & ModelWithDictionary) | null; 615 + }; 616 + 617 + /** 618 + * This is a model with one property with a 'any of' relationship 619 + */ 620 + export type CompositionWithAnyOfAndNullable = { 621 + propA?: { 622 + boolean?: boolean; 623 + } | ModelWithEnum | ModelWithArray | ModelWithDictionary | null; 624 + }; 625 + 626 + /** 627 + * This is a base model with two simple optional properties 628 + */ 629 + export type CompositionBaseModel = { 630 + firstName?: string; 631 + lastname?: string; 632 + }; 633 + 634 + /** 635 + * This is a model that extends the base model 636 + */ 637 + export type CompositionExtendedModel = CompositionBaseModel & { 638 + firstName: string; 639 + lastname: string; 640 + age: number; 641 + }; 642 + 643 + /** 644 + * This is a model with one nested property 645 + */ 646 + export type ModelWithProperties = { 647 + required: string; 648 + readonly requiredAndReadOnly: string; 649 + requiredAndNullable: string | null; 650 + string?: string; 651 + number?: number; 652 + boolean?: boolean; 653 + reference?: ModelWithString; 654 + 'property with space'?: string; 655 + default?: string; 656 + try?: string; 657 + readonly '@namespace.string'?: string; 658 + readonly '@namespace.integer'?: number; 659 + }; 660 + 661 + /** 662 + * This is a model with one nested property 663 + */ 664 + export type ModelWithNestedProperties = { 665 + readonly first: { 666 + readonly second: { 667 + readonly third: string | null; 668 + } | null; 669 + } | null; 670 + }; 671 + 672 + /** 673 + * This is a model with duplicated properties 674 + */ 675 + export type ModelWithDuplicateProperties = { 676 + prop?: ModelWithString; 677 + }; 678 + 679 + /** 680 + * This is a model with ordered properties 681 + */ 682 + export type ModelWithOrderedProperties = { 683 + zebra?: string; 684 + apple?: string; 685 + hawaii?: string; 686 + }; 687 + 688 + /** 689 + * This is a model with duplicated imports 690 + */ 691 + export type ModelWithDuplicateImports = { 692 + propA?: ModelWithString; 693 + propB?: ModelWithString; 694 + propC?: ModelWithString; 695 + }; 696 + 697 + /** 698 + * This is a model that extends another model 699 + */ 700 + export type ModelThatExtends = ModelWithString & { 701 + propExtendsA?: string; 702 + propExtendsB?: ModelWithString; 703 + }; 704 + 705 + /** 706 + * This is a model that extends another model 707 + */ 708 + export type ModelThatExtendsExtends = ModelWithString & ModelThatExtends & { 709 + propExtendsC?: string; 710 + propExtendsD?: ModelWithString; 711 + }; 712 + 713 + /** 714 + * This is a model that contains a some patterns 715 + */ 716 + export type ModelWithPattern = { 717 + key: string; 718 + name: string; 719 + readonly enabled?: boolean; 720 + readonly modified?: string; 721 + id?: string; 722 + text?: string; 723 + patternWithSingleQuotes?: string; 724 + patternWithNewline?: string; 725 + patternWithBacktick?: string; 726 + }; 727 + 728 + export type File = { 729 + readonly id?: string; 730 + readonly updated_at?: string; 731 + readonly created_at?: string; 732 + mime: string; 733 + readonly file?: string; 734 + }; 735 + 736 + export type _default = { 737 + name?: string; 738 + }; 739 + 740 + export type Pageable = { 741 + page?: number; 742 + size?: number; 743 + sort?: Array<(string)>; 744 + }; 745 + 746 + /** 747 + * This is a free-form object without additionalProperties. 748 + */ 749 + export type FreeFormObjectWithoutAdditionalProperties = { 750 + [key: string]: unknown; 751 + }; 752 + 753 + /** 754 + * This is a free-form object with additionalProperties: true. 755 + */ 756 + export type FreeFormObjectWithAdditionalPropertiesEqTrue = { 757 + [key: string]: unknown; 758 + }; 759 + 760 + /** 761 + * This is a free-form object with additionalProperties: {}. 762 + */ 763 + export type FreeFormObjectWithAdditionalPropertiesEqEmptyObject = { 764 + [key: string]: unknown; 765 + }; 766 + 767 + export type ModelWithConst = { 768 + String?: "String"; 769 + number?: 0; 770 + null?: null; 771 + withType?: "Some string"; 772 + }; 773 + 774 + /** 775 + * This is a model with one property and additionalProperties: true 776 + */ 777 + export type ModelWithAdditionalPropertiesEqTrue = { 778 + /** 779 + * This is a simple string property 780 + */ 781 + prop?: string; 782 + [key: string]: unknown | string; 783 + }; 784 + 785 + export type NestedAnyOfArraysNullable = { 786 + nullableArray?: Array<(string | boolean)> | null; 787 + }; 788 + 789 + export type CompositionWithOneOfAndProperties = { 790 + foo: ParameterSimpleParameter; 791 + } | { 792 + bar: NonAsciiStringæøåÆØÅöôêÊ字符串; 793 + } & { 794 + baz: number | null; 795 + qux: number; 796 + }; 797 + 798 + /** 799 + * An object that can be null 800 + */ 801 + export type NullableObject = { 802 + foo?: string; 803 + } | null; 804 + 805 + /** 806 + * Some % character 807 + */ 808 + export type CharactersInDescription = string; 809 + 810 + export type ModelWithNullableObject = { 811 + data?: NullableObject; 812 + }; 813 + 814 + export type ModelWithOneOfEnum = { 815 + foo: 'Bar'; 816 + } | { 817 + foo: 'Baz'; 818 + } | { 819 + foo: 'Qux'; 820 + } | { 821 + content: string; 822 + foo: 'Quux'; 823 + } | { 824 + content: [ 825 + string, 826 + string 827 + ]; 828 + foo: 'Corge'; 829 + }; 830 + 831 + export type foo = 'Bar'; 832 + 833 + export const foo = { 834 + BAR: 'Bar' 835 + } as const; 836 + 837 + export type ModelWithNestedArrayEnumsDataFoo = 'foo' | 'bar'; 838 + 839 + export const ModelWithNestedArrayEnumsDataFoo = { 840 + FOO: 'foo', 841 + BAR: 'bar' 842 + } as const; 843 + 844 + export type ModelWithNestedArrayEnumsDataBar = 'baz' | 'qux'; 845 + 846 + export const ModelWithNestedArrayEnumsDataBar = { 847 + BAZ: 'baz', 848 + QUX: 'qux' 849 + } as const; 850 + 851 + export type ModelWithNestedArrayEnumsData = { 852 + foo?: Array<ModelWithNestedArrayEnumsDataFoo>; 853 + bar?: Array<ModelWithNestedArrayEnumsDataBar>; 854 + }; 855 + 856 + export type ModelWithNestedArrayEnums = { 857 + array_strings?: Array<(string)>; 858 + data?: ModelWithNestedArrayEnumsData; 859 + }; 860 + 861 + export type ModelWithNestedCompositionEnums = { 862 + foo?: ModelWithNestedArrayEnumsDataFoo; 863 + }; 864 + 865 + export type ModelWithReadOnlyAndWriteOnly = { 866 + foo: string; 867 + readonly bar: string; 868 + baz: string; 869 + }; 870 + 871 + export type ModelWithConstantSizeArray = [ 872 + number, 873 + number 874 + ]; 875 + 876 + export type ModelWithAnyOfConstantSizeArray = [ 877 + number | string, 878 + number | string, 879 + number | string 880 + ]; 881 + 882 + export type ModelWithPrefixItemsConstantSizeArray = [ 883 + ModelWithInteger, 884 + number | string, 885 + string 886 + ]; 887 + 888 + export type ModelWithAnyOfConstantSizeArrayNullable = [ 889 + number | null | string, 890 + number | null | string, 891 + number | null | string 892 + ]; 893 + 894 + export type ModelWithAnyOfConstantSizeArrayWithNSizeAndOptions = [ 895 + number | _import, 896 + number | _import 897 + ]; 898 + 899 + export type ModelWithAnyOfConstantSizeArrayAndIntersect = [ 900 + number & string, 901 + number & string 902 + ]; 903 + 904 + export type ModelWithNumericEnumUnion = { 905 + /** 906 + * Период 907 + */ 908 + value?: -10 | -1 | 0 | 1 | 3 | 6 | 12; 909 + }; 910 + 911 + /** 912 + * Период 913 + */ 914 + export type value = -10 | -1 | 0 | 1 | 3 | 6 | 12; 915 + 916 + /** 917 + * Период 918 + */ 919 + export const value = { 920 + '_-10': -10, 921 + '_-1': -1, 922 + '_0': 0, 923 + '_1': 1, 924 + '_3': 3, 925 + '_6': 6, 926 + '_12': 12 927 + } as const; 928 + 929 + /** 930 + * Some description with `back ticks` 931 + */ 932 + export type ModelWithBackticksInDescription = { 933 + /** 934 + * The template `that` should be used for parsing and importing the contents of the CSV file. 935 + * 936 + * <br/><p>There is one placeholder currently supported:<ul> <li><b>${x}</b> - refers to the n-th column in the CSV file, e.g. ${1}, ${2}, ...)</li></ul><p>Example of a correct JSON template:</p> 937 + * <pre> 938 + * [ 939 + * { 940 + * "resourceType": "Asset", 941 + * "identifier": { 942 + * "name": "${1}", 943 + * "domain": { 944 + * "name": "${2}", 945 + * "community": { 946 + * "name": "Some Community" 947 + * } 948 + * } 949 + * }, 950 + * "attributes" : { 951 + * "00000000-0000-0000-0000-000000003115" : [ { 952 + * "value" : "${3}" 953 + * } ], 954 + * "00000000-0000-0000-0000-000000000222" : [ { 955 + * "value" : "${4}" 956 + * } ] 957 + * } 958 + * } 959 + * ] 960 + * </pre> 961 + */ 962 + template?: string; 963 + }; 964 + 965 + export type ModelWithOneOfAndProperties = ParameterSimpleParameter | NonAsciiStringæøåÆØÅöôêÊ字符串 & { 966 + baz: number | null; 967 + qux: number; 968 + }; 969 + 970 + /** 971 + * Model used to test deduplication strategy (unused) 972 + */ 973 + export type ParameterSimpleParameterUnused = string; 974 + 975 + /** 976 + * Model used to test deduplication strategy 977 + */ 978 + export type PostServiceWithEmptyTagResponse = string; 979 + 980 + /** 981 + * Model used to test deduplication strategy 982 + */ 983 + export type PostServiceWithEmptyTagResponse2 = string; 984 + 985 + /** 986 + * Model used to test deduplication strategy 987 + */ 988 + export type DeleteFooData = string; 989 + 990 + /** 991 + * Model used to test deduplication strategy 992 + */ 993 + export type DeleteFooData2 = string; 994 + 995 + /** 996 + * Model with restricted keyword name 997 + */ 998 + export type _import = string; 999 + 1000 + export type SchemaWithFormRestrictedKeys = { 1001 + description?: string; 1002 + 'x-enum-descriptions'?: string; 1003 + 'x-enum-varnames'?: string; 1004 + 'x-enumNames'?: string; 1005 + title?: string; 1006 + object?: { 1007 + description?: string; 1008 + 'x-enum-descriptions'?: string; 1009 + 'x-enum-varnames'?: string; 1010 + 'x-enumNames'?: string; 1011 + title?: string; 1012 + }; 1013 + array?: Array<({ 1014 + description?: string; 1015 + 'x-enum-descriptions'?: string; 1016 + 'x-enum-varnames'?: string; 1017 + 'x-enumNames'?: string; 1018 + title?: string; 1019 + })>; 1020 + }; 1021 + 1022 + /** 1023 + * This schema was giving PascalCase transformations a hard time 1024 + */ 1025 + export type io_k8s_apimachinery_pkg_apis_meta_v1_DeleteOptions = { 1026 + /** 1027 + * Must be fulfilled before a deletion is carried out. If not possible, a 409 Conflict status will be returned. 1028 + */ 1029 + preconditions?: io_k8s_apimachinery_pkg_apis_meta_v1_Preconditions; 1030 + }; 1031 + 1032 + /** 1033 + * This schema was giving PascalCase transformations a hard time 1034 + */ 1035 + export type io_k8s_apimachinery_pkg_apis_meta_v1_Preconditions = { 1036 + /** 1037 + * Specifies the target ResourceVersion 1038 + */ 1039 + resourceVersion?: string; 1040 + /** 1041 + * Specifies the target UID. 1042 + */ 1043 + uid?: string; 1044 + }; 1045 + 1046 + /** 1047 + * This is a reusable parameter 1048 + */ 1049 + export type ParameterSimpleParameter = string; 1050 + 1051 + /** 1052 + * Parameter with illegal characters 1053 + */ 1054 + export type Parameterx_Foo_Bar = ModelWithString;
-1
packages/openapi-ts/test/index.spec.ts
··· 321 321 services: { 322 322 filter: '^\\w+ /api/v{api-version}/simple$', 323 323 }, 324 - types: false, 325 324 }), 326 325 description: 'generate services with specific endpoints', 327 326 name: 'v3_services_filter',
+10 -10
packages/openapi-ts/test/sample.cjs
··· 17 17 output: { 18 18 path: './test/generated/sample/', 19 19 }, 20 - // plugins: [ 21 - // { 22 - // // infiniteQueryOptions: false, 23 - // // mutationOptions: false, 24 - // name: '@tanstack/react-query', 25 - // // queryOptions: false, 26 - // }, 27 - // ], 20 + plugins: [ 21 + { 22 + // infiniteQueryOptions: false, 23 + // mutationOptions: false, 24 + name: '@tanstack/react-query', 25 + // queryOptions: false, 26 + }, 27 + ], 28 28 schemas: { 29 29 export: false, 30 30 }, 31 31 services: { 32 - export: false, 32 + // export: false, 33 33 // asClass: true, 34 34 // filter: '^POST /api/v{api-version}/upload$', 35 35 // export: false, ··· 42 42 // include: 43 43 // '^(_400|CompositionWithOneOfAndProperties)', 44 44 // name: 'PascalCase', 45 - tree: false, 45 + // tree: false, 46 46 }, 47 47 // useOptions: false, 48 48 };