import { invariant } from '../jsutils/invariant.ts';
import { OperationTypeNode } from '../language/ast.ts';
import { GraphQLStreamDirective } from '../type/directives.ts';
import type { FieldDetailsList } from './collectFields.ts';
import type { ValidatedExecutionArgs } from './ExecutionArgs.ts';
import { getDirectiveValues } from './values.ts';
export interface StreamUsage {
label: string | undefined;
initialCount: number;
fieldDetailsList: FieldDetailsList;
}
export function getStreamUsage(
validatedExecutionArgs: ValidatedExecutionArgs,
fieldDetailsList: FieldDetailsList,
): StreamUsage | undefined {
const { operation, variableValues } = validatedExecutionArgs;
const stream = getDirectiveValues(
GraphQLStreamDirective,
fieldDetailsList[0].node,
variableValues,
fieldDetailsList[0].fragmentVariableValues,
);
if (!stream) {
return;
}
if (stream.if === false) {
return;
}
invariant(
typeof stream.initialCount === 'number',
'initialCount must be a number',
);
invariant(
stream.initialCount >= 0,
'initialCount must be a positive integer',
);
invariant(
operation.operation !== OperationTypeNode.SUBSCRIPTION,
'`@stream` directive not supported on subscription operations. Disable `@stream` by setting the `if` argument to `false`.',
);
const streamedFieldDetailsList: FieldDetailsList = fieldDetailsList.map(
(fieldDetails) => ({
node: fieldDetails.node,
deferUsage: undefined,
fragmentVariableValues: fieldDetails.fragmentVariableValues,
}),
);
return {
initialCount: stream.initialCount,
label: typeof stream.label === 'string' ? stream.label : undefined,
fieldDetailsList: streamedFieldDetailsList,
};
}