@bagelink/sdk 1.12.47 → 1.12.51
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +48 -5
- package/dist/index.d.cts +12 -1
- package/dist/index.d.mts +12 -1
- package/dist/index.d.ts +12 -1
- package/dist/index.mjs +48 -6
- package/package.json +1 -1
- package/src/openAPITools/functionGenerator.ts +34 -20
- package/src/openAPITools/streamDetector.ts +30 -0
package/dist/index.cjs
CHANGED
|
@@ -60,6 +60,24 @@ function extractSSEEventTypes(operation) {
|
|
|
60
60
|
}
|
|
61
61
|
return types.size > 0 ? Array.from(types).sort() : void 0;
|
|
62
62
|
}
|
|
63
|
+
function extractSSEEventSchemas(operation) {
|
|
64
|
+
const responses = operation.responses || {};
|
|
65
|
+
for (const [statusCode, response] of Object.entries(responses)) {
|
|
66
|
+
if (!statusCode.startsWith("2")) continue;
|
|
67
|
+
if ("$ref" in response) continue;
|
|
68
|
+
const eventStream = response.content?.["text/event-stream"];
|
|
69
|
+
const schemas = eventStream?.["x-event-schemas"];
|
|
70
|
+
if (schemas && Object.keys(schemas).length > 0) {
|
|
71
|
+
return Object.fromEntries(
|
|
72
|
+
Object.entries(schemas).map(([event, ref]) => [
|
|
73
|
+
event,
|
|
74
|
+
ref.replace(/^#\/components\/schemas\//, "")
|
|
75
|
+
])
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return void 0;
|
|
80
|
+
}
|
|
63
81
|
function extractSSEEventInfo(operation) {
|
|
64
82
|
const description = operation.description || "";
|
|
65
83
|
const eventInfos = [];
|
|
@@ -397,6 +415,7 @@ const functionsInventory = {};
|
|
|
397
415
|
const pathOperations = [];
|
|
398
416
|
const streamEventTypes = {};
|
|
399
417
|
const streamEventInfo = {};
|
|
418
|
+
const streamEventSchemas = {};
|
|
400
419
|
function collectTypeForImportStatement(typeName) {
|
|
401
420
|
typeName = typeName.trim().replace("[]", "");
|
|
402
421
|
if (typeName.includes("|")) {
|
|
@@ -603,6 +622,8 @@ function generateStreamFunction(method, path, formattedPath, allParams, requestB
|
|
|
603
622
|
* .on('${t}', (data) => console.log(data))`).join("") : "\n * .on('message', (data) => console.log(data))";
|
|
604
623
|
const typeAnnotation = eventTypes?.length ? `StreamController<${streamTypeName}>` : "StreamController";
|
|
605
624
|
const pathForUrl = formattedPath.startsWith("`") ? formattedPath.slice(1, -1) : formattedPath.slice(1, -1);
|
|
625
|
+
const streamParams = allParams ? `${allParams}, options?: SSEStreamOptions` : `options?: SSEStreamOptions`;
|
|
626
|
+
const regularParams = allParams;
|
|
606
627
|
if (method === "post") {
|
|
607
628
|
return `{
|
|
608
629
|
/**
|
|
@@ -616,14 +637,14 @@ function generateStreamFunction(method, path, formattedPath, allParams, requestB
|
|
|
616
637
|
* // Close stream when needed
|
|
617
638
|
* stream.close()
|
|
618
639
|
*/
|
|
619
|
-
stream: (${
|
|
640
|
+
stream: (${streamParams}): ${typeAnnotation} => {
|
|
620
641
|
const url = \`\${${baseUrlRef}}${pathForUrl}\`
|
|
621
642
|
return createSSEStreamPost<${streamTypeName}>(url, ${bodyVar}, options)
|
|
622
643
|
},
|
|
623
644
|
/**
|
|
624
645
|
* Regular POST request (non-streaming)
|
|
625
646
|
*/
|
|
626
|
-
post: async (${
|
|
647
|
+
post: async (${regularParams}): Promise<AxiosResponse<any>> => {
|
|
627
648
|
return axios.post(${formattedPath}, ${bodyVar})
|
|
628
649
|
}
|
|
629
650
|
}`;
|
|
@@ -640,14 +661,14 @@ function generateStreamFunction(method, path, formattedPath, allParams, requestB
|
|
|
640
661
|
* // Close stream when needed
|
|
641
662
|
* stream.close()
|
|
642
663
|
*/
|
|
643
|
-
stream: (${
|
|
664
|
+
stream: (${streamParams}): ${typeAnnotation} => {
|
|
644
665
|
const url = \`\${${baseUrlRef}}${pathForUrl}\`
|
|
645
666
|
return createSSEStream<${streamTypeName}>(url, options)
|
|
646
667
|
},
|
|
647
668
|
/**
|
|
648
669
|
* Regular GET request (non-streaming)
|
|
649
670
|
*/
|
|
650
|
-
get: async (${
|
|
671
|
+
get: async (${regularParams}): Promise<AxiosResponse<any>> => {
|
|
651
672
|
return axios.get(${formattedPath})
|
|
652
673
|
}
|
|
653
674
|
}`;
|
|
@@ -751,10 +772,15 @@ function generateFunctionForOperation(method, path, operation) {
|
|
|
751
772
|
if (isStream) {
|
|
752
773
|
const eventTypes = extractSSEEventTypes(operation);
|
|
753
774
|
const eventInfo = extractSSEEventInfo(operation);
|
|
775
|
+
const eventSchemas = extractSSEEventSchemas(operation);
|
|
754
776
|
const streamTypeName = generateStreamTypeName(path);
|
|
755
777
|
if (eventInfo?.length) {
|
|
756
778
|
streamEventInfo[streamTypeName] = eventInfo;
|
|
757
779
|
}
|
|
780
|
+
if (eventSchemas && Object.keys(eventSchemas).length > 0) {
|
|
781
|
+
streamEventSchemas[streamTypeName] = eventSchemas;
|
|
782
|
+
Object.values(eventSchemas).forEach((tsType) => collectTypeForImportStatement(tsType));
|
|
783
|
+
}
|
|
758
784
|
return functionComment + generateStreamFunction(
|
|
759
785
|
method,
|
|
760
786
|
path,
|
|
@@ -878,6 +904,7 @@ function generateStreamEventTypeDefinitions() {
|
|
|
878
904
|
typeDefs += "// ============================================================================\n\n";
|
|
879
905
|
for (const [typeName, events] of Object.entries(streamEventTypes)) {
|
|
880
906
|
const eventInfo = streamEventInfo[typeName];
|
|
907
|
+
const eventSchemas = streamEventSchemas[typeName];
|
|
881
908
|
typeDefs += `/**
|
|
882
909
|
* Event types for ${typeName.replace("StreamEvents", "")} stream
|
|
883
910
|
`;
|
|
@@ -895,7 +922,22 @@ function generateStreamEventTypeDefinitions() {
|
|
|
895
922
|
`;
|
|
896
923
|
typeDefs += `export interface ${typeName} {
|
|
897
924
|
`;
|
|
898
|
-
if (
|
|
925
|
+
if (eventSchemas && Object.keys(eventSchemas).length > 0) {
|
|
926
|
+
for (const event of events) {
|
|
927
|
+
const tsType = eventSchemas[event];
|
|
928
|
+
if (tsType) {
|
|
929
|
+
typeDefs += ` /** ${event} event \u2014 payload shape defined by ${tsType} */
|
|
930
|
+
`;
|
|
931
|
+
typeDefs += ` ${event}: ${tsType}
|
|
932
|
+
`;
|
|
933
|
+
} else {
|
|
934
|
+
typeDefs += ` /** ${event} event data */
|
|
935
|
+
`;
|
|
936
|
+
typeDefs += ` ${event}: any
|
|
937
|
+
`;
|
|
938
|
+
}
|
|
939
|
+
}
|
|
940
|
+
} else if (eventInfo?.length) {
|
|
899
941
|
for (const info of eventInfo) {
|
|
900
942
|
typeDefs += ` /**
|
|
901
943
|
* ${info.description || info.name}
|
|
@@ -1976,6 +2018,7 @@ exports.createSSEStream = createSSEStream;
|
|
|
1976
2018
|
exports.createSSEStreamPost = createSSEStreamPost;
|
|
1977
2019
|
exports.dereference = dereference;
|
|
1978
2020
|
exports.extractSSEEventInfo = extractSSEEventInfo;
|
|
2021
|
+
exports.extractSSEEventSchemas = extractSSEEventSchemas;
|
|
1979
2022
|
exports.extractSSEEventTypes = extractSSEEventTypes;
|
|
1980
2023
|
exports.formatAPIErrorMessage = formatAPIErrorMessage;
|
|
1981
2024
|
exports.formatFieldErrors = formatFieldErrors;
|
package/dist/index.d.cts
CHANGED
|
@@ -480,6 +480,17 @@ interface SSEEventTypeInfo {
|
|
|
480
480
|
* @returns Array of event types or undefined
|
|
481
481
|
*/
|
|
482
482
|
declare function extractSSEEventTypes(operation: OperationObject): string[] | undefined;
|
|
483
|
+
/**
|
|
484
|
+
* Extracts typed schema refs from the x-event-schemas OpenAPI extension.
|
|
485
|
+
*
|
|
486
|
+
* Server sets this via sse_openapi_response(event_types={"created": MyModel}).
|
|
487
|
+
* Returns a map of { event_name: TypeScript type name } derived from the $ref,
|
|
488
|
+
* e.g. { "connection_created": "ConferenceConnectionOut" }.
|
|
489
|
+
*
|
|
490
|
+
* @param operation - The OpenAPI operation object
|
|
491
|
+
* @returns Map of event name → TS type name, or undefined if not present
|
|
492
|
+
*/
|
|
493
|
+
declare function extractSSEEventSchemas(operation: OperationObject): Record<string, string> | undefined;
|
|
483
494
|
/**
|
|
484
495
|
* Extracts detailed SSE event information including field definitions
|
|
485
496
|
*
|
|
@@ -790,5 +801,5 @@ declare function createOptionsGetter<T>(fetchFn: () => Promise<T[]>, mapFn?: (it
|
|
|
790
801
|
value: string;
|
|
791
802
|
}[]>;
|
|
792
803
|
|
|
793
|
-
export { ApiResponse, Bagel, StreamController, createOptionsGetter, createSSEStream, createSSEStreamPost, dereference, extractSSEEventInfo, extractSSEEventTypes, formatAPIErrorMessage, formatFieldErrors, getPath, isReferenceObject, isSSEStream, isSchemaObject, _default as openAPI, parseApiError, unwrap, useApiRequest, useCancellableRequest, wrapApiForDirectReturn };
|
|
804
|
+
export { ApiResponse, Bagel, StreamController, createOptionsGetter, createSSEStream, createSSEStreamPost, dereference, extractSSEEventInfo, extractSSEEventSchemas, extractSSEEventTypes, formatAPIErrorMessage, formatFieldErrors, getPath, isReferenceObject, isSSEStream, isSchemaObject, _default as openAPI, parseApiError, unwrap, useApiRequest, useCancellableRequest, wrapApiForDirectReturn };
|
|
794
805
|
export type { ApiConfig, ApiRequestState, BaseParameterObject, CallbackObject, CallbacksObject, ComponentsObject, ContactObject, ContentObject, DiscriminatorObject, EncodingObject, EncodingPropertyObject, ExampleObject, ExamplesObject, ExternalDocumentationObject, FastAPIErrorResponse, FastAPIValidationError, HeaderObject, HeadersObject, InfoObject, LicenseObject, LinkObject, LinkParametersObject, LinksObject, MediaTypeObject, OAuthFlowObject, OAuthFlowsObject, OpenAPIObject, OperationObject, ParameterLocation, ParameterObject, ParameterStyle, ParsedError, PathItemObject, PathsObject, ReferenceObject, RequestBodyObject, RequestInterceptor, ResponseInterceptor, ResponseMetadata, ResponseObject, ResponsesObject, SSEEventTypeInfo, SSEStreamOptions, SchemaObject, SchemaObjectType, SchemasObject, ScopesObject, SecurityRequirementObject, SecuritySchemeObject, SecuritySchemeType, ServerObject, ServerVariableObject, StreamEventMap, TableToTypeMapping, Tables, TagObject, TypeFormatT, Unwrap, Unwrapped, UploadOptions, User, XmlObject };
|
package/dist/index.d.mts
CHANGED
|
@@ -480,6 +480,17 @@ interface SSEEventTypeInfo {
|
|
|
480
480
|
* @returns Array of event types or undefined
|
|
481
481
|
*/
|
|
482
482
|
declare function extractSSEEventTypes(operation: OperationObject): string[] | undefined;
|
|
483
|
+
/**
|
|
484
|
+
* Extracts typed schema refs from the x-event-schemas OpenAPI extension.
|
|
485
|
+
*
|
|
486
|
+
* Server sets this via sse_openapi_response(event_types={"created": MyModel}).
|
|
487
|
+
* Returns a map of { event_name: TypeScript type name } derived from the $ref,
|
|
488
|
+
* e.g. { "connection_created": "ConferenceConnectionOut" }.
|
|
489
|
+
*
|
|
490
|
+
* @param operation - The OpenAPI operation object
|
|
491
|
+
* @returns Map of event name → TS type name, or undefined if not present
|
|
492
|
+
*/
|
|
493
|
+
declare function extractSSEEventSchemas(operation: OperationObject): Record<string, string> | undefined;
|
|
483
494
|
/**
|
|
484
495
|
* Extracts detailed SSE event information including field definitions
|
|
485
496
|
*
|
|
@@ -790,5 +801,5 @@ declare function createOptionsGetter<T>(fetchFn: () => Promise<T[]>, mapFn?: (it
|
|
|
790
801
|
value: string;
|
|
791
802
|
}[]>;
|
|
792
803
|
|
|
793
|
-
export { ApiResponse, Bagel, StreamController, createOptionsGetter, createSSEStream, createSSEStreamPost, dereference, extractSSEEventInfo, extractSSEEventTypes, formatAPIErrorMessage, formatFieldErrors, getPath, isReferenceObject, isSSEStream, isSchemaObject, _default as openAPI, parseApiError, unwrap, useApiRequest, useCancellableRequest, wrapApiForDirectReturn };
|
|
804
|
+
export { ApiResponse, Bagel, StreamController, createOptionsGetter, createSSEStream, createSSEStreamPost, dereference, extractSSEEventInfo, extractSSEEventSchemas, extractSSEEventTypes, formatAPIErrorMessage, formatFieldErrors, getPath, isReferenceObject, isSSEStream, isSchemaObject, _default as openAPI, parseApiError, unwrap, useApiRequest, useCancellableRequest, wrapApiForDirectReturn };
|
|
794
805
|
export type { ApiConfig, ApiRequestState, BaseParameterObject, CallbackObject, CallbacksObject, ComponentsObject, ContactObject, ContentObject, DiscriminatorObject, EncodingObject, EncodingPropertyObject, ExampleObject, ExamplesObject, ExternalDocumentationObject, FastAPIErrorResponse, FastAPIValidationError, HeaderObject, HeadersObject, InfoObject, LicenseObject, LinkObject, LinkParametersObject, LinksObject, MediaTypeObject, OAuthFlowObject, OAuthFlowsObject, OpenAPIObject, OperationObject, ParameterLocation, ParameterObject, ParameterStyle, ParsedError, PathItemObject, PathsObject, ReferenceObject, RequestBodyObject, RequestInterceptor, ResponseInterceptor, ResponseMetadata, ResponseObject, ResponsesObject, SSEEventTypeInfo, SSEStreamOptions, SchemaObject, SchemaObjectType, SchemasObject, ScopesObject, SecurityRequirementObject, SecuritySchemeObject, SecuritySchemeType, ServerObject, ServerVariableObject, StreamEventMap, TableToTypeMapping, Tables, TagObject, TypeFormatT, Unwrap, Unwrapped, UploadOptions, User, XmlObject };
|
package/dist/index.d.ts
CHANGED
|
@@ -480,6 +480,17 @@ interface SSEEventTypeInfo {
|
|
|
480
480
|
* @returns Array of event types or undefined
|
|
481
481
|
*/
|
|
482
482
|
declare function extractSSEEventTypes(operation: OperationObject): string[] | undefined;
|
|
483
|
+
/**
|
|
484
|
+
* Extracts typed schema refs from the x-event-schemas OpenAPI extension.
|
|
485
|
+
*
|
|
486
|
+
* Server sets this via sse_openapi_response(event_types={"created": MyModel}).
|
|
487
|
+
* Returns a map of { event_name: TypeScript type name } derived from the $ref,
|
|
488
|
+
* e.g. { "connection_created": "ConferenceConnectionOut" }.
|
|
489
|
+
*
|
|
490
|
+
* @param operation - The OpenAPI operation object
|
|
491
|
+
* @returns Map of event name → TS type name, or undefined if not present
|
|
492
|
+
*/
|
|
493
|
+
declare function extractSSEEventSchemas(operation: OperationObject): Record<string, string> | undefined;
|
|
483
494
|
/**
|
|
484
495
|
* Extracts detailed SSE event information including field definitions
|
|
485
496
|
*
|
|
@@ -790,5 +801,5 @@ declare function createOptionsGetter<T>(fetchFn: () => Promise<T[]>, mapFn?: (it
|
|
|
790
801
|
value: string;
|
|
791
802
|
}[]>;
|
|
792
803
|
|
|
793
|
-
export { ApiResponse, Bagel, StreamController, createOptionsGetter, createSSEStream, createSSEStreamPost, dereference, extractSSEEventInfo, extractSSEEventTypes, formatAPIErrorMessage, formatFieldErrors, getPath, isReferenceObject, isSSEStream, isSchemaObject, _default as openAPI, parseApiError, unwrap, useApiRequest, useCancellableRequest, wrapApiForDirectReturn };
|
|
804
|
+
export { ApiResponse, Bagel, StreamController, createOptionsGetter, createSSEStream, createSSEStreamPost, dereference, extractSSEEventInfo, extractSSEEventSchemas, extractSSEEventTypes, formatAPIErrorMessage, formatFieldErrors, getPath, isReferenceObject, isSSEStream, isSchemaObject, _default as openAPI, parseApiError, unwrap, useApiRequest, useCancellableRequest, wrapApiForDirectReturn };
|
|
794
805
|
export type { ApiConfig, ApiRequestState, BaseParameterObject, CallbackObject, CallbacksObject, ComponentsObject, ContactObject, ContentObject, DiscriminatorObject, EncodingObject, EncodingPropertyObject, ExampleObject, ExamplesObject, ExternalDocumentationObject, FastAPIErrorResponse, FastAPIValidationError, HeaderObject, HeadersObject, InfoObject, LicenseObject, LinkObject, LinkParametersObject, LinksObject, MediaTypeObject, OAuthFlowObject, OAuthFlowsObject, OpenAPIObject, OperationObject, ParameterLocation, ParameterObject, ParameterStyle, ParsedError, PathItemObject, PathsObject, ReferenceObject, RequestBodyObject, RequestInterceptor, ResponseInterceptor, ResponseMetadata, ResponseObject, ResponsesObject, SSEEventTypeInfo, SSEStreamOptions, SchemaObject, SchemaObjectType, SchemasObject, ScopesObject, SecurityRequirementObject, SecuritySchemeObject, SecuritySchemeType, ServerObject, ServerVariableObject, StreamEventMap, TableToTypeMapping, Tables, TagObject, TypeFormatT, Unwrap, Unwrapped, UploadOptions, User, XmlObject };
|
package/dist/index.mjs
CHANGED
|
@@ -54,6 +54,24 @@ function extractSSEEventTypes(operation) {
|
|
|
54
54
|
}
|
|
55
55
|
return types.size > 0 ? Array.from(types).sort() : void 0;
|
|
56
56
|
}
|
|
57
|
+
function extractSSEEventSchemas(operation) {
|
|
58
|
+
const responses = operation.responses || {};
|
|
59
|
+
for (const [statusCode, response] of Object.entries(responses)) {
|
|
60
|
+
if (!statusCode.startsWith("2")) continue;
|
|
61
|
+
if ("$ref" in response) continue;
|
|
62
|
+
const eventStream = response.content?.["text/event-stream"];
|
|
63
|
+
const schemas = eventStream?.["x-event-schemas"];
|
|
64
|
+
if (schemas && Object.keys(schemas).length > 0) {
|
|
65
|
+
return Object.fromEntries(
|
|
66
|
+
Object.entries(schemas).map(([event, ref]) => [
|
|
67
|
+
event,
|
|
68
|
+
ref.replace(/^#\/components\/schemas\//, "")
|
|
69
|
+
])
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return void 0;
|
|
74
|
+
}
|
|
57
75
|
function extractSSEEventInfo(operation) {
|
|
58
76
|
const description = operation.description || "";
|
|
59
77
|
const eventInfos = [];
|
|
@@ -391,6 +409,7 @@ const functionsInventory = {};
|
|
|
391
409
|
const pathOperations = [];
|
|
392
410
|
const streamEventTypes = {};
|
|
393
411
|
const streamEventInfo = {};
|
|
412
|
+
const streamEventSchemas = {};
|
|
394
413
|
function collectTypeForImportStatement(typeName) {
|
|
395
414
|
typeName = typeName.trim().replace("[]", "");
|
|
396
415
|
if (typeName.includes("|")) {
|
|
@@ -597,6 +616,8 @@ function generateStreamFunction(method, path, formattedPath, allParams, requestB
|
|
|
597
616
|
* .on('${t}', (data) => console.log(data))`).join("") : "\n * .on('message', (data) => console.log(data))";
|
|
598
617
|
const typeAnnotation = eventTypes?.length ? `StreamController<${streamTypeName}>` : "StreamController";
|
|
599
618
|
const pathForUrl = formattedPath.startsWith("`") ? formattedPath.slice(1, -1) : formattedPath.slice(1, -1);
|
|
619
|
+
const streamParams = allParams ? `${allParams}, options?: SSEStreamOptions` : `options?: SSEStreamOptions`;
|
|
620
|
+
const regularParams = allParams;
|
|
600
621
|
if (method === "post") {
|
|
601
622
|
return `{
|
|
602
623
|
/**
|
|
@@ -610,14 +631,14 @@ function generateStreamFunction(method, path, formattedPath, allParams, requestB
|
|
|
610
631
|
* // Close stream when needed
|
|
611
632
|
* stream.close()
|
|
612
633
|
*/
|
|
613
|
-
stream: (${
|
|
634
|
+
stream: (${streamParams}): ${typeAnnotation} => {
|
|
614
635
|
const url = \`\${${baseUrlRef}}${pathForUrl}\`
|
|
615
636
|
return createSSEStreamPost<${streamTypeName}>(url, ${bodyVar}, options)
|
|
616
637
|
},
|
|
617
638
|
/**
|
|
618
639
|
* Regular POST request (non-streaming)
|
|
619
640
|
*/
|
|
620
|
-
post: async (${
|
|
641
|
+
post: async (${regularParams}): Promise<AxiosResponse<any>> => {
|
|
621
642
|
return axios.post(${formattedPath}, ${bodyVar})
|
|
622
643
|
}
|
|
623
644
|
}`;
|
|
@@ -634,14 +655,14 @@ function generateStreamFunction(method, path, formattedPath, allParams, requestB
|
|
|
634
655
|
* // Close stream when needed
|
|
635
656
|
* stream.close()
|
|
636
657
|
*/
|
|
637
|
-
stream: (${
|
|
658
|
+
stream: (${streamParams}): ${typeAnnotation} => {
|
|
638
659
|
const url = \`\${${baseUrlRef}}${pathForUrl}\`
|
|
639
660
|
return createSSEStream<${streamTypeName}>(url, options)
|
|
640
661
|
},
|
|
641
662
|
/**
|
|
642
663
|
* Regular GET request (non-streaming)
|
|
643
664
|
*/
|
|
644
|
-
get: async (${
|
|
665
|
+
get: async (${regularParams}): Promise<AxiosResponse<any>> => {
|
|
645
666
|
return axios.get(${formattedPath})
|
|
646
667
|
}
|
|
647
668
|
}`;
|
|
@@ -745,10 +766,15 @@ function generateFunctionForOperation(method, path, operation) {
|
|
|
745
766
|
if (isStream) {
|
|
746
767
|
const eventTypes = extractSSEEventTypes(operation);
|
|
747
768
|
const eventInfo = extractSSEEventInfo(operation);
|
|
769
|
+
const eventSchemas = extractSSEEventSchemas(operation);
|
|
748
770
|
const streamTypeName = generateStreamTypeName(path);
|
|
749
771
|
if (eventInfo?.length) {
|
|
750
772
|
streamEventInfo[streamTypeName] = eventInfo;
|
|
751
773
|
}
|
|
774
|
+
if (eventSchemas && Object.keys(eventSchemas).length > 0) {
|
|
775
|
+
streamEventSchemas[streamTypeName] = eventSchemas;
|
|
776
|
+
Object.values(eventSchemas).forEach((tsType) => collectTypeForImportStatement(tsType));
|
|
777
|
+
}
|
|
752
778
|
return functionComment + generateStreamFunction(
|
|
753
779
|
method,
|
|
754
780
|
path,
|
|
@@ -872,6 +898,7 @@ function generateStreamEventTypeDefinitions() {
|
|
|
872
898
|
typeDefs += "// ============================================================================\n\n";
|
|
873
899
|
for (const [typeName, events] of Object.entries(streamEventTypes)) {
|
|
874
900
|
const eventInfo = streamEventInfo[typeName];
|
|
901
|
+
const eventSchemas = streamEventSchemas[typeName];
|
|
875
902
|
typeDefs += `/**
|
|
876
903
|
* Event types for ${typeName.replace("StreamEvents", "")} stream
|
|
877
904
|
`;
|
|
@@ -889,7 +916,22 @@ function generateStreamEventTypeDefinitions() {
|
|
|
889
916
|
`;
|
|
890
917
|
typeDefs += `export interface ${typeName} {
|
|
891
918
|
`;
|
|
892
|
-
if (
|
|
919
|
+
if (eventSchemas && Object.keys(eventSchemas).length > 0) {
|
|
920
|
+
for (const event of events) {
|
|
921
|
+
const tsType = eventSchemas[event];
|
|
922
|
+
if (tsType) {
|
|
923
|
+
typeDefs += ` /** ${event} event \u2014 payload shape defined by ${tsType} */
|
|
924
|
+
`;
|
|
925
|
+
typeDefs += ` ${event}: ${tsType}
|
|
926
|
+
`;
|
|
927
|
+
} else {
|
|
928
|
+
typeDefs += ` /** ${event} event data */
|
|
929
|
+
`;
|
|
930
|
+
typeDefs += ` ${event}: any
|
|
931
|
+
`;
|
|
932
|
+
}
|
|
933
|
+
}
|
|
934
|
+
} else if (eventInfo?.length) {
|
|
893
935
|
for (const info of eventInfo) {
|
|
894
936
|
typeDefs += ` /**
|
|
895
937
|
* ${info.description || info.name}
|
|
@@ -1962,4 +2004,4 @@ function createOptionsGetter(fetchFn, mapFn) {
|
|
|
1962
2004
|
};
|
|
1963
2005
|
}
|
|
1964
2006
|
|
|
1965
|
-
export { ApiResponse, Bagel, StreamController, createOptionsGetter, createSSEStream, createSSEStreamPost, dereference, extractSSEEventInfo, extractSSEEventTypes, formatAPIErrorMessage, formatFieldErrors, getPath, isReferenceObject, isSSEStream, isSchemaObject, index as openAPI, parseApiError, unwrap, useApiRequest, useCancellableRequest, wrapApiForDirectReturn };
|
|
2007
|
+
export { ApiResponse, Bagel, StreamController, createOptionsGetter, createSSEStream, createSSEStreamPost, dereference, extractSSEEventInfo, extractSSEEventSchemas, extractSSEEventTypes, formatAPIErrorMessage, formatFieldErrors, getPath, isReferenceObject, isSSEStream, isSchemaObject, index as openAPI, parseApiError, unwrap, useApiRequest, useCancellableRequest, wrapApiForDirectReturn };
|
package/package.json
CHANGED
|
@@ -1,8 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
/* eslint-disable ts/no-unnecessary-condition */
|
|
3
|
-
/* eslint-disable jsdoc/check-param-names */
|
|
4
|
-
/* eslint-disable ts/no-non-null-assertion */
|
|
5
|
-
/* eslint-disable prefer-destructuring */
|
|
1
|
+
|
|
6
2
|
import type { SSEEventTypeInfo } from './streamDetector'
|
|
7
3
|
import type {
|
|
8
4
|
OperationObject as OpenAPIOperation,
|
|
@@ -14,7 +10,7 @@ import type {
|
|
|
14
10
|
ReferenceObject,
|
|
15
11
|
SchemaObject,
|
|
16
12
|
} from './types'
|
|
17
|
-
import { isSSEStream, extractSSEEventTypes, extractSSEEventInfo } from './streamDetector'
|
|
13
|
+
import { isSSEStream, extractSSEEventTypes, extractSSEEventInfo, extractSSEEventSchemas } from './streamDetector'
|
|
18
14
|
import { dereference, isReferenceObject } from './types/utils'
|
|
19
15
|
import {
|
|
20
16
|
cleanPath,
|
|
@@ -63,6 +59,7 @@ const functionsInventory: Record<string, string> = {}
|
|
|
63
59
|
const pathOperations: PathOperation[] = []
|
|
64
60
|
const streamEventTypes: Record<string, string[]> = {} // Track stream endpoints and their event types
|
|
65
61
|
const streamEventInfo: Record<string, SSEEventTypeInfo[]> = {} // Track detailed event info for type generation
|
|
62
|
+
const streamEventSchemas: Record<string, Record<string, string>> = {} // Track typed schemas: streamTypeName → {event → TSType}
|
|
66
63
|
|
|
67
64
|
/**
|
|
68
65
|
* Collects non-primitive types for import statements
|
|
@@ -448,6 +445,9 @@ function generateStreamFunction(
|
|
|
448
445
|
? formattedPath.slice(1, -1) // Remove backticks to get the content
|
|
449
446
|
: formattedPath.slice(1, -1) // Remove quotes to get the content
|
|
450
447
|
|
|
448
|
+
const streamParams = allParams ? `${allParams}, options?: SSEStreamOptions` : `options?: SSEStreamOptions`
|
|
449
|
+
const regularParams = allParams
|
|
450
|
+
|
|
451
451
|
if (method === 'post') {
|
|
452
452
|
return `{
|
|
453
453
|
/**
|
|
@@ -461,14 +461,14 @@ function generateStreamFunction(
|
|
|
461
461
|
* // Close stream when needed
|
|
462
462
|
* stream.close()
|
|
463
463
|
*/
|
|
464
|
-
stream: (${
|
|
464
|
+
stream: (${streamParams}): ${typeAnnotation} => {
|
|
465
465
|
const url = \`\${${baseUrlRef}}${pathForUrl}\`
|
|
466
466
|
return createSSEStreamPost<${streamTypeName}>(url, ${bodyVar}, options)
|
|
467
467
|
},
|
|
468
468
|
/**
|
|
469
469
|
* Regular POST request (non-streaming)
|
|
470
470
|
*/
|
|
471
|
-
post: async (${
|
|
471
|
+
post: async (${regularParams}): Promise<AxiosResponse<any>> => {
|
|
472
472
|
return axios.post(${formattedPath}, ${bodyVar})
|
|
473
473
|
}
|
|
474
474
|
}`
|
|
@@ -485,14 +485,14 @@ function generateStreamFunction(
|
|
|
485
485
|
* // Close stream when needed
|
|
486
486
|
* stream.close()
|
|
487
487
|
*/
|
|
488
|
-
stream: (${
|
|
488
|
+
stream: (${streamParams}): ${typeAnnotation} => {
|
|
489
489
|
const url = \`\${${baseUrlRef}}${pathForUrl}\`
|
|
490
490
|
return createSSEStream<${streamTypeName}>(url, options)
|
|
491
491
|
},
|
|
492
492
|
/**
|
|
493
493
|
* Regular GET request (non-streaming)
|
|
494
494
|
*/
|
|
495
|
-
get: async (${
|
|
495
|
+
get: async (${regularParams}): Promise<AxiosResponse<any>> => {
|
|
496
496
|
return axios.get(${formattedPath})
|
|
497
497
|
}
|
|
498
498
|
}`
|
|
@@ -677,12 +677,18 @@ function generateFunctionForOperation(
|
|
|
677
677
|
if (isStream) {
|
|
678
678
|
const eventTypes = extractSSEEventTypes(operation)
|
|
679
679
|
const eventInfo = extractSSEEventInfo(operation)
|
|
680
|
+
const eventSchemas = extractSSEEventSchemas(operation)
|
|
680
681
|
|
|
681
|
-
// Store detailed event info for type generation
|
|
682
|
+
// Store detailed event info and typed schemas for type generation
|
|
682
683
|
const streamTypeName = generateStreamTypeName(path)
|
|
683
684
|
if (eventInfo?.length) {
|
|
684
685
|
streamEventInfo[streamTypeName] = eventInfo
|
|
685
686
|
}
|
|
687
|
+
if (eventSchemas && Object.keys(eventSchemas).length > 0) {
|
|
688
|
+
streamEventSchemas[streamTypeName] = eventSchemas
|
|
689
|
+
// Collect schema type names for import statements
|
|
690
|
+
Object.values(eventSchemas).forEach(tsType => collectTypeForImportStatement(tsType))
|
|
691
|
+
}
|
|
686
692
|
|
|
687
693
|
return functionComment + generateStreamFunction(
|
|
688
694
|
method,
|
|
@@ -895,11 +901,11 @@ function generateStreamEventTypeDefinitions(): string {
|
|
|
895
901
|
|
|
896
902
|
for (const [typeName, events] of Object.entries(streamEventTypes)) {
|
|
897
903
|
const eventInfo = streamEventInfo[typeName]
|
|
904
|
+
const eventSchemas = streamEventSchemas[typeName] // {event_name: "TSTypeName"} or undefined
|
|
898
905
|
|
|
899
906
|
typeDefs += `/**\n * Event types for ${typeName.replace('StreamEvents', '')} stream\n`
|
|
900
907
|
typeDefs += ` * Events: ${events.map(e => `"${e}"`).join(', ')}\n`
|
|
901
908
|
|
|
902
|
-
// Add event descriptions if available
|
|
903
909
|
if (eventInfo?.length) {
|
|
904
910
|
typeDefs += ` *\n`
|
|
905
911
|
for (const info of eventInfo) {
|
|
@@ -910,20 +916,28 @@ function generateStreamEventTypeDefinitions(): string {
|
|
|
910
916
|
typeDefs += ` */\n`
|
|
911
917
|
typeDefs += `export interface ${typeName} {\n`
|
|
912
918
|
|
|
913
|
-
|
|
914
|
-
|
|
919
|
+
if (eventSchemas && Object.keys(eventSchemas).length > 0) {
|
|
920
|
+
// Fully typed: each event maps to its Pydantic model's TypeScript type
|
|
921
|
+
for (const event of events) {
|
|
922
|
+
const tsType = eventSchemas[event]
|
|
923
|
+
if (tsType) {
|
|
924
|
+
typeDefs += ` /** ${event} event — payload shape defined by ${tsType} */\n`
|
|
925
|
+
typeDefs += ` ${event}: ${tsType}\n`
|
|
926
|
+
} else {
|
|
927
|
+
typeDefs += ` /** ${event} event data */\n`
|
|
928
|
+
typeDefs += ` ${event}: any\n`
|
|
929
|
+
}
|
|
930
|
+
}
|
|
931
|
+
} else if (eventInfo?.length) {
|
|
932
|
+
// Field-level info from markdown docs but no schema refs
|
|
915
933
|
for (const info of eventInfo) {
|
|
916
934
|
typeDefs += ` /**\n * ${info.description || info.name}\n`
|
|
917
|
-
|
|
918
935
|
if (info.fields?.length) {
|
|
919
|
-
info.fields.forEach(
|
|
936
|
+
info.fields.forEach(field => {
|
|
920
937
|
typeDefs += ` * - \`${field.name}\`: ${field.description || 'Field data'}\n`
|
|
921
938
|
})
|
|
922
939
|
}
|
|
923
|
-
|
|
924
940
|
typeDefs += ` */\n`
|
|
925
|
-
|
|
926
|
-
// Generate interface for this event
|
|
927
941
|
if (info.fields?.length) {
|
|
928
942
|
typeDefs += ` ${info.name}: {\n`
|
|
929
943
|
for (const field of info.fields) {
|
|
@@ -936,7 +950,7 @@ function generateStreamEventTypeDefinitions(): string {
|
|
|
936
950
|
}
|
|
937
951
|
}
|
|
938
952
|
} else {
|
|
939
|
-
// Fallback:
|
|
953
|
+
// Fallback: no type info at all
|
|
940
954
|
for (const event of events) {
|
|
941
955
|
typeDefs += ` /** ${event} event data */\n`
|
|
942
956
|
typeDefs += ` ${event}: any\n`
|
|
@@ -122,6 +122,36 @@ export function extractSSEEventTypes(operation: OpenAPIOperation): string[] | un
|
|
|
122
122
|
return types.size > 0 ? Array.from(types).sort() : undefined
|
|
123
123
|
}
|
|
124
124
|
|
|
125
|
+
/**
|
|
126
|
+
* Extracts typed schema refs from the x-event-schemas OpenAPI extension.
|
|
127
|
+
*
|
|
128
|
+
* Server sets this via sse_openapi_response(event_types={"created": MyModel}).
|
|
129
|
+
* Returns a map of { event_name: TypeScript type name } derived from the $ref,
|
|
130
|
+
* e.g. { "connection_created": "ConferenceConnectionOut" }.
|
|
131
|
+
*
|
|
132
|
+
* @param operation - The OpenAPI operation object
|
|
133
|
+
* @returns Map of event name → TS type name, or undefined if not present
|
|
134
|
+
*/
|
|
135
|
+
export function extractSSEEventSchemas(operation: OpenAPIOperation): Record<string, string> | undefined {
|
|
136
|
+
const responses = operation.responses || {}
|
|
137
|
+
for (const [statusCode, response] of Object.entries(responses)) {
|
|
138
|
+
if (!statusCode.startsWith('2')) continue
|
|
139
|
+
if ('$ref' in response) continue
|
|
140
|
+
const eventStream = (response as any).content?.['text/event-stream']
|
|
141
|
+
const schemas = eventStream?.['x-event-schemas'] as Record<string, string> | undefined
|
|
142
|
+
if (schemas && Object.keys(schemas).length > 0) {
|
|
143
|
+
// Convert $ref paths like "#/components/schemas/MyModel" → "MyModel"
|
|
144
|
+
return Object.fromEntries(
|
|
145
|
+
Object.entries(schemas).map(([event, ref]) => [
|
|
146
|
+
event,
|
|
147
|
+
ref.replace(/^#\/components\/schemas\//, ''),
|
|
148
|
+
])
|
|
149
|
+
)
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
return undefined
|
|
153
|
+
}
|
|
154
|
+
|
|
125
155
|
/**
|
|
126
156
|
* Extracts detailed SSE event information including field definitions
|
|
127
157
|
*
|