Skip to content

Commit e05816f

Browse files
committed
Add warning for creating subscription
Signed-off-by: Alan Cha <[email protected]>
1 parent f5049bc commit e05816f

File tree

7 files changed

+119
-58
lines changed

7 files changed

+119
-58
lines changed

packages/openapi-to-graphql/lib/preprocessor.js

Lines changed: 30 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/openapi-to-graphql/lib/preprocessor.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/openapi-to-graphql/lib/utils.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ export declare const mitigations: {
2121
UNRESOLVABLE_SCHEMA: string;
2222
UNSUPPORTED_HTTP_SECURITY_SCHEME: string;
2323
UNSUPPORTED_JSON_SCHEMA_KEYWORD: string;
24+
CALLBACKS_MULTIPLE_OPERATION_OBJECTS: string;
2425
AMBIGUOUS_LINK: string;
2526
LINK_NAME_COLLISION: string;
2627
UNRESOLVABLE_LINK: string;

packages/openapi-to-graphql/lib/utils.js

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/openapi-to-graphql/lib/utils.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/openapi-to-graphql/src/preprocessor.ts

Lines changed: 84 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,20 @@ import { GraphQLOperationType } from './types/graphql'
2929

3030
const preprocessingLog = debug('preprocessing')
3131

32+
/**
33+
* Given an operation object from the OAS, create an Operation, which contains
34+
* the necessary data to create a GraphQL wrapper for said operation object.
35+
*
36+
* @param path The path of the operation object
37+
* @param method The method of the operation object
38+
* @param operationString A string representation of the path and the method (and the OAS title if applicable)
39+
* @param operationType Whether the operation should be turned into a Query/Mutation/Subscription operation
40+
* @param operation The operation object from the OAS
41+
* @param pathItem The path item object from the OAS from which the operation object is derived from
42+
* @param oas The OAS from which the path item and operation object are derived from
43+
* @param data An assortment of data which at this point is mainly used enable logging
44+
* @param options The options passed by the user
45+
*/
3246
function processOperation(
3347
path: string,
3448
method: string,
@@ -305,7 +319,10 @@ export function preprocessOas(
305319
}
306320

307321
// Process all callbacks
308-
if (operation.callbacks) {
322+
if (
323+
data.options.createSubscriptionsFromCallbacks &&
324+
operation.callbacks
325+
) {
309326
Object.entries(operation.callbacks).forEach(
310327
([callbackName, callback]) => {
311328
const resolvedCallback = !('$ref' in callback)
@@ -323,59 +340,75 @@ export function preprocessOas(
323340
? callbackPathItem
324341
: Oas3Tools.resolveRef(callbackPathItem['$ref'], oas)
325342

326-
Object.keys(resolvedCallbackPathItem)
327-
.filter(objectKey => {
343+
const callbackOperationObjectMethods = Object.keys(
344+
resolvedCallbackPathItem
345+
).filter(objectKey => {
346+
/**
347+
* Get only fields that contain operation objects
348+
*
349+
* Can also contain other fields such as summary or description
350+
*/
351+
return Oas3Tools.isOperation(objectKey)
352+
})
353+
354+
if (callbackOperationObjectMethods.length > 0) {
355+
if (callbackOperationObjectMethods.length > 1) {
356+
handleWarning({
357+
typeKey:
358+
'CALLBACKS_MULTIPLE_OPERATION_OBJECT_METHODS',
359+
message: `Callback '${callbackExpression}' on operation '${operationString}' has multiple operation objects with the methods '${callbackOperationObjectMethods}'. OpenAPI-to-GraphQL can only utilize one of these operation objects.`,
360+
mitigationAddendum: `The operation with the method '${callbackOperationObjectMethods[0]}' will be selected and all others will be ignored.`,
361+
data,
362+
log: preprocessingLog
363+
})
364+
}
365+
366+
// Select only one of the operation object methods
367+
const callbackMethod = callbackOperationObjectMethods[0]
368+
369+
const callbackOperationString = Oas3Tools.formatOperationString(
370+
method,
371+
callbackName
372+
)
373+
374+
const callbackOperation = processOperation(
375+
callbackExpression,
376+
callbackMethod,
377+
callbackOperationString,
378+
GraphQLOperationType.Subscription,
379+
resolvedCallbackPathItem[callbackMethod],
380+
callbackPathItem,
381+
oas,
382+
data,
383+
options
384+
)
385+
386+
if (callbackOperation) {
328387
/**
329-
* Get only fields that contain operation objects
330-
*
331-
* Can also contain other fields such as summary or description
388+
* Handle operationId property name collision
389+
* May occur if multiple OAS are provided
332390
*/
333-
return Oas3Tools.isOperation(objectKey)
334-
})
335-
.forEach(callbackMethod => {
336-
const callbackOperationString = Oas3Tools.formatOperationString(
337-
method,
338-
callbackName
339-
)
340-
341-
const callbackOperation = processOperation(
342-
callbackExpression,
343-
callbackMethod,
344-
callbackOperationString,
345-
GraphQLOperationType.Subscription,
346-
resolvedCallbackPathItem[callbackMethod],
347-
callbackPathItem,
348-
oas,
349-
data,
350-
options
351-
)
352-
353-
if (callbackOperation) {
354-
/**
355-
* Handle operationId property name collision
356-
* May occur if multiple OAS are provided
357-
*/
358-
if (
359-
callbackOperation &&
360-
!(
361-
callbackOperation.operationId in
362-
data.callbackOperations
363-
)
364-
) {
365-
data.callbackOperations[
366-
callbackOperation.operationId
367-
] = callbackOperation
368-
} else {
369-
handleWarning({
370-
typeKey: 'DUPLICATE_OPERATIONID',
371-
message: `Multiple OASs share callback operations with the same operationId '${callbackOperation.operationId}'`,
372-
mitigationAddendum: `The callback operation from the OAS '${operationData.oas.info.title}' will be ignored`,
373-
data,
374-
log: preprocessingLog
375-
})
376-
}
391+
if (
392+
callbackOperation &&
393+
!(
394+
callbackOperation.operationId in
395+
data.callbackOperations
396+
)
397+
) {
398+
data.callbackOperations[
399+
callbackOperation.operationId
400+
] = callbackOperation
401+
} else {
402+
handleWarning({
403+
typeKey: 'DUPLICATE_OPERATIONID',
404+
message: `Multiple OASs share callback operations with the same operationId '${callbackOperation.operationId}'`,
405+
mitigationAddendum: `The callback operation from the OAS '${operationData.oas.info.title}' will be ignored`,
406+
data,
407+
log: preprocessingLog
408+
})
377409
}
378-
})
410+
}
411+
}
379412
}
380413
)
381414
}

packages/openapi-to-graphql/src/utils.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ export const mitigations = {
3030
UNRESOLVABLE_SCHEMA: `Ignore and continue. May lead to unexpected behavior.`,
3131
UNSUPPORTED_HTTP_SECURITY_SCHEME: `Ignore security scheme.`,
3232
UNSUPPORTED_JSON_SCHEMA_KEYWORD: `Ignore keyword and continue.`,
33+
CALLBACKS_MULTIPLE_OPERATION_OBJECTS: `Select arbitrary operation object`,
3334

3435
// Links
3536
AMBIGUOUS_LINK: `Use first occurance of '#/'.`,

0 commit comments

Comments
 (0)