Skip to content

Commit

Permalink
Merge pull request #16 from ErikWittern/listsize-directive
Browse files Browse the repository at this point in the history
Add slicing args defined in @listsize directive
  • Loading branch information
Alan-Cha authored Aug 27, 2020
2 parents 3d746e5 + cfee11d commit 70a4be3
Show file tree
Hide file tree
Showing 7 changed files with 302 additions and 15 deletions.
56 changes: 51 additions & 5 deletions lib/generate-query.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion lib/generate-query.js.map

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion lib/provide-variables.js.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 7 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
"@types/graphql": "^14.5.0",
"@types/jest": "^26.0.10",
"@types/node": "^13.13.4",
"dedent": "^0.7.0",
"husky": "^4.2.5",
"jest": "^26.4.2",
"prettier": "^2.0.5",
Expand Down
77 changes: 70 additions & 7 deletions src/generate-query.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ import {
Kind,
InlineFragmentNode,
GraphQLObjectType,
print
print,
StringValueNode
} from 'graphql'

import * as seedrandom from 'seedrandom'
Expand Down Expand Up @@ -454,10 +455,68 @@ function getNextNodefactor(variableValues: { [name: string]: any }): number {
return 1
}

/**
* Returns the first slicing argument defined in the field's @listSize
* directive, if:
* - The @listSize directive is indeed present, and defines slicing arguments
* - The requiredArguments do not already include any of the defined slicing
* arguments
* - The @listSize diretcive doesn't also set requireOneSlicingArgument to
* false
*
* TODO: add link to specification / documentation of @listSize directive
*/
function getMissingSlicingArg(
requiredArguments: InputValueDefinitionNode[],
field: FieldDefinitionNode
): InputValueDefinitionNode {
// Return null if there is no @listSize directive:
const listSizeDirective = field.directives.find(
(dir) => dir.name.value === 'listSize'
)
if (typeof listSizeDirective === 'undefined') return null

// Return null if @listSize directive defines no slicing arguments:
const slicingArgumentsArg = listSizeDirective.arguments.find(
(arg) => arg.name.value === 'slicingArguments'
)
if (
typeof slicingArgumentsArg === 'undefined' ||
slicingArgumentsArg.value.kind !== 'ListValue'
)
return null

// Return null if requireOneSlicingArgument is set to false:
const requireOneSlicingArg = listSizeDirective.arguments.find(
(arg) => arg.name.value === 'requireOneSlicingArgument'
)
if (
typeof requireOneSlicingArg !== 'undefined' &&
requireOneSlicingArg.value.kind === 'BooleanValue' &&
requireOneSlicingArg.value.value === false
)
return null

// Return null if a slicing argument is already used:
const slicingArguments = slicingArgumentsArg.value.values
.filter((value) => value.kind === 'StringValue')
.map((value) => (value as StringValueNode).value)
const usesSlicingArg = slicingArguments.some((slicingArg) =>
requiredArguments
.map((existing) => existing.name.value)
.includes(slicingArg)
)
if (usesSlicingArg) return null

// Return the first slicing arguments:
return field.arguments.find((arg) =>
slicingArguments.includes(arg.name.value)
)
}

function getArgsAndVars(
allArgs: ReadonlyArray<InputValueDefinitionNode>,
field: FieldDefinitionNode,
nodeName: string,
fieldName: string,
config: InternalConfiguration,
schema: GraphQLSchema,
providedValues: { [varName: string]: any }
Expand All @@ -466,6 +525,8 @@ function getArgsAndVars(
variableDefinitionsMap: { [varName: string]: VariableDefinitionNode }
variableValues: { [varName: string]: any }
} {
const fieldName = field.name.value
const allArgs = field.arguments
const args: ArgumentNode[] = []

const variableDefinitionsMap: {
Expand All @@ -474,6 +535,10 @@ function getArgsAndVars(
const requiredArguments = allArgs.filter((arg) =>
considerArgument(arg, config)
)
// Check for slicing arguments defined in a @listSize directive that should
// be present:
const missingSlicingArg = getMissingSlicingArg(requiredArguments, field)
if (missingSlicingArg) requiredArguments.push(missingSlicingArg)
requiredArguments.forEach((arg) => {
const varName = `${nodeName}__${fieldName}__${arg.name.value}`
args.push(getVariable(arg.name.value, varName))
Expand Down Expand Up @@ -598,9 +663,8 @@ function getSelectionSetAndVars(
}

const avs = getArgsAndVars(
field.arguments,
field,
node.name.value,
field.name.value,
config,
schema,
variableValues
Expand Down Expand Up @@ -642,9 +706,8 @@ function getSelectionSetAndVars(
}

const avs = getArgsAndVars(
field.arguments,
field,
node.name.value,
field.name.value,
config,
schema,
variableValues
Expand Down
Loading

0 comments on commit 70a4be3

Please sign in to comment.