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

Configure Feed

Select the types of activity you want to include in your feed.

feat: make patch.schemas callbacks async-compatible

- Updated type definition to allow Promise<void> return type for both Record and bulk callback
- Updated implementation to await all schema callback invocations (v2 and v3)
- Added comprehensive tests for async bulk callbacks and async Record-based callbacks
- Verified with manual CLI test that async operations work correctly

Co-authored-by: mrlubos <12529395+mrlubos@users.noreply.github.com>

+140 -6
+2 -2
packages/shared/src/config/parser/patch.ts
··· 170 170 | OpenApiSchemaObject.V2_0_X 171 171 | OpenApiSchemaObject.V3_0_X 172 172 | OpenApiSchemaObject.V3_1_X, 173 - ) => void 173 + ) => void | Promise<void> 174 174 > 175 175 | (( 176 176 name: string, ··· 178 178 | OpenApiSchemaObject.V2_0_X 179 179 | OpenApiSchemaObject.V3_0_X 180 180 | OpenApiSchemaObject.V3_1_X, 181 - ) => void); 181 + ) => void | Promise<void>); 182 182 /** 183 183 * Patch the OpenAPI version string. The function receives the current version and should return the new version string. 184 184 * Useful for normalizing or overriding the version value before further processing.
+134
packages/shared/src/openApi/shared/utils/__tests__/patch.test.ts
··· 989 989 expect(fn).toHaveBeenCalledOnce(); 990 990 expect(fn).toHaveBeenCalledWith('Qux', { type: 'string' }); 991 991 }); 992 + 993 + it('supports async bulk callback', async () => { 994 + const spec: OpenApi.V3_1_X = { 995 + ...specMetadataV3, 996 + components: { 997 + schemas: { 998 + Bar: { 999 + description: 'Bar schema', 1000 + type: 'object', 1001 + }, 1002 + Foo: { 1003 + description: 'Foo schema', 1004 + type: 'string', 1005 + }, 1006 + }, 1007 + }, 1008 + }; 1009 + 1010 + await patchOpenApiSpec({ 1011 + patchOptions: { 1012 + schemas: async (name, schema) => { 1013 + // Simulate async operation 1014 + await Promise.resolve(); 1015 + schema.description = `${schema.description} - async patched`; 1016 + }, 1017 + }, 1018 + spec, 1019 + }); 1020 + 1021 + expect(spec.components?.schemas?.Bar!.description).toBe('Bar schema - async patched'); 1022 + expect(spec.components?.schemas?.Foo!.description).toBe('Foo schema - async patched'); 1023 + }); 1024 + 1025 + it('supports async Record-based callbacks', async () => { 1026 + const spec: OpenApi.V3_1_X = { 1027 + ...specMetadataV3, 1028 + components: { 1029 + schemas: { 1030 + Bar: { 1031 + description: 'Bar schema', 1032 + type: 'object', 1033 + }, 1034 + Foo: { 1035 + description: 'Foo schema', 1036 + type: 'string', 1037 + }, 1038 + }, 1039 + }, 1040 + }; 1041 + 1042 + await patchOpenApiSpec({ 1043 + patchOptions: { 1044 + schemas: { 1045 + Bar: async (schema) => { 1046 + await Promise.resolve(); 1047 + schema.description = `${schema.description} - async`; 1048 + }, 1049 + Foo: async (schema) => { 1050 + await Promise.resolve(); 1051 + schema.description = `${schema.description} - async`; 1052 + }, 1053 + }, 1054 + }, 1055 + spec, 1056 + }); 1057 + 1058 + expect(spec.components?.schemas?.Bar!.description).toBe('Bar schema - async'); 1059 + expect(spec.components?.schemas?.Foo!.description).toBe('Foo schema - async'); 1060 + }); 992 1061 }); 993 1062 994 1063 describe('OpenAPI v2', () => { ··· 1301 1370 1302 1371 expect(fn).toHaveBeenCalledOnce(); 1303 1372 expect(fn).toHaveBeenCalledWith('Qux', { type: 'string' }); 1373 + }); 1374 + 1375 + it('supports async bulk callback', async () => { 1376 + const spec: OpenApi.V2_0_X = { 1377 + ...specMetadataV2, 1378 + definitions: { 1379 + Bar: { 1380 + description: 'Bar schema', 1381 + type: 'object', 1382 + }, 1383 + Foo: { 1384 + description: 'Foo schema', 1385 + type: 'string', 1386 + }, 1387 + }, 1388 + }; 1389 + 1390 + await patchOpenApiSpec({ 1391 + patchOptions: { 1392 + schemas: async (name, schema) => { 1393 + // Simulate async operation 1394 + await Promise.resolve(); 1395 + schema.description = `${schema.description} - async patched`; 1396 + }, 1397 + }, 1398 + spec, 1399 + }); 1400 + 1401 + expect(spec.definitions?.Bar!.description).toBe('Bar schema - async patched'); 1402 + expect(spec.definitions?.Foo!.description).toBe('Foo schema - async patched'); 1403 + }); 1404 + 1405 + it('supports async Record-based callbacks', async () => { 1406 + const spec: OpenApi.V2_0_X = { 1407 + ...specMetadataV2, 1408 + definitions: { 1409 + Bar: { 1410 + description: 'Bar schema', 1411 + type: 'object', 1412 + }, 1413 + Foo: { 1414 + description: 'Foo schema', 1415 + type: 'string', 1416 + }, 1417 + }, 1418 + }; 1419 + 1420 + await patchOpenApiSpec({ 1421 + patchOptions: { 1422 + schemas: { 1423 + Bar: async (schema) => { 1424 + await Promise.resolve(); 1425 + schema.description = `${schema.description} - async`; 1426 + }, 1427 + Foo: async (schema) => { 1428 + await Promise.resolve(); 1429 + schema.description = `${schema.description} - async`; 1430 + }, 1431 + }, 1432 + }, 1433 + spec, 1434 + }); 1435 + 1436 + expect(spec.definitions?.Bar!.description).toBe('Bar schema - async'); 1437 + expect(spec.definitions?.Foo!.description).toBe('Foo schema - async'); 1304 1438 }); 1305 1439 }); 1306 1440
+4 -4
packages/shared/src/openApi/shared/utils/patch.ts
··· 40 40 if (typeof patchOptions.schemas === 'function') { 41 41 for (const [key, schema] of Object.entries(spec.definitions)) { 42 42 if (schema && typeof schema === 'object') { 43 - patchOptions.schemas(key, schema); 43 + await patchOptions.schemas(key, schema); 44 44 } 45 45 } 46 46 } else { ··· 49 49 if (!schema || typeof schema !== 'object') continue; 50 50 51 51 const patchFn = patchOptions.schemas[key]!; 52 - patchFn(schema); 52 + await patchFn(schema); 53 53 } 54 54 } 55 55 } ··· 91 91 if (typeof patchOptions.schemas === 'function') { 92 92 for (const [key, schema] of Object.entries(spec.components.schemas)) { 93 93 if (schema && typeof schema === 'object') { 94 - patchOptions.schemas(key, schema as Parameters<typeof patchOptions.schemas>[1]); 94 + await patchOptions.schemas(key, schema as Parameters<typeof patchOptions.schemas>[1]); 95 95 } 96 96 } 97 97 } else { ··· 100 100 if (!schema || typeof schema !== 'object') continue; 101 101 102 102 const patchFn = patchOptions.schemas[key]!; 103 - patchFn(schema as Parameters<typeof patchFn>[0]); 103 + await patchFn(schema as Parameters<typeof patchFn>[0]); 104 104 } 105 105 } 106 106 }