Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

babel plugin: support input object literals #894

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion scripts/babel-relay-plugin/lib/HASH
Original file line number Diff line number Diff line change
@@ -1 +1 @@
isftDgu2uVYHE61WqmtgLAW/fxE=
Bymfx+W0wVxiTT8S4zaiyJVbRhM=
45 changes: 31 additions & 14 deletions scripts/babel-relay-plugin/lib/RelayQLAST.js
Original file line number Diff line number Diff line change
Expand Up @@ -431,21 +431,13 @@ var RelayQLArgument = (function () {

invariant(!this.isVariable(), 'Cannot get value of an argument variable.');
var value = this.ast.value;
switch (value.kind) {
case 'IntValue':
return parseInt(value.value, 10);
case 'FloatValue':
return parseFloat(value.value);
case 'StringValue':
case 'BooleanValue':
case 'EnumValue':
return value.value;
case 'ListValue':
return value.values.map(function (value) {
return new RelayQLArgument(_this6.context, _extends({}, _this6.ast, { value: value }), _this6.type.ofType());
});
if (value.kind === 'ListValue') {
return value.values.map(function (value) {
return new RelayQLArgument(_this6.context, _extends({}, _this6.ast, { value: value }), _this6.type.ofType());
});
} else {
return getLiteralValue(value);
}
invariant(false, 'Unexpected argument kind: %s', value.kind);
}
}]);

Expand Down Expand Up @@ -815,6 +807,31 @@ function stripMarkerTypes(schemaModifiedType) {
return { isListType: isListType, isNonNullType: isNonNullType, schemaUnmodifiedType: schemaUnmodifiedType };
}

function getLiteralValue(value) {
switch (value.kind) {
case 'IntValue':
return parseInt(value.value, 10);
case 'FloatValue':
return parseFloat(value.value);
case 'StringValue':
case 'BooleanValue':
case 'EnumValue':
return value.value;
case 'ListValue':
return value.values.map(getLiteralValue);
case 'ObjectValue':
var object = {};
value.fields.forEach(function (field) {
object[field.name.value] = getLiteralValue(field.value);
});
return object;
case 'Variable':
invariant(false, 'Unexpected nested variable `%s`; variables are supported as top-' + 'level arguments - `node(id: $id)` - or directly within lists - ' + '`nodes(ids: [$id])`.', value.name.value);
default:
invariant(false, 'Unexpected value kind: %s', value.kind);
}
}

module.exports = {
RelayQLArgument: RelayQLArgument,
RelayQLArgumentType: RelayQLArgumentType,
Expand Down
23 changes: 22 additions & 1 deletion scripts/babel-relay-plugin/lib/RelayQLPrinter.js
Original file line number Diff line number Diff line change
Expand Up @@ -456,7 +456,7 @@ module.exports = function (t, options) {
}
return codify({
kind: t.valueToNode('CallValue'),
callValue: t.valueToNode(value)
callValue: printLiteralValue(value)
});
}
}, {
Expand Down Expand Up @@ -617,6 +617,27 @@ module.exports = function (t, options) {
return t.objectProperty(t.identifier(name), value);
}

function printLiteralValue(value) {
if (value == null) {
return NULL;
} else if (Array.isArray(value)) {
return t.arrayExpression(value.map(printLiteralValue));
} else if (typeof value === 'object' && value != null) {
var _ret2 = (function () {
var objectValue = value;
return {
v: t.objectExpression(Object.keys(objectValue).map(function (key) {
return property(key, printLiteralValue(objectValue[key]));
}))
};
})();

if (typeof _ret2 === 'object') return _ret2.v;
} else {
return t.valueToNode(value);
}
}

function shallowFlatten(arr) {
return t.callExpression(t.memberExpression(t.memberExpression(EMPTY_ARRAY, t.identifier('concat')), t.identifier('apply')), [EMPTY_ARRAY, arr]);
}
Expand Down
64 changes: 46 additions & 18 deletions scripts/babel-relay-plugin/src/RelayQLAST.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import type {
FragmentSpread as GraphQLFragmentSpread,
InlineFragment as GraphQLInlineFragment,
OperationDefinition as GraphQLOperationDefinition,
Value as GraphQLValue,
} from 'GraphQLAST';

// TODO: Import types from `graphql`.
Expand Down Expand Up @@ -379,25 +380,17 @@ class RelayQLArgument {
'Cannot get value of an argument variable.'
);
const value = this.ast.value;
switch (value.kind) {
case 'IntValue':
return parseInt(value.value, 10);
case 'FloatValue':
return parseFloat(value.value);
case 'StringValue':
case 'BooleanValue':
case 'EnumValue':
return value.value;
case 'ListValue':
return value.values.map(
value => new RelayQLArgument(
this.context,
{...this.ast, value},
this.type.ofType()
)
);
if (value.kind === 'ListValue') {
return value.values.map(
value => new RelayQLArgument(
this.context,
{...this.ast, value},
this.type.ofType()
)
);
} else {
return getLiteralValue(value);
}
invariant(false, 'Unexpected argument kind: %s', value.kind);
}
}

Expand Down Expand Up @@ -767,6 +760,41 @@ function stripMarkerTypes(schemaModifiedType: GraphQLSchemaType): {
return {isListType, isNonNullType, schemaUnmodifiedType};
}

function getLiteralValue(value: GraphQLValue): mixed {
switch (value.kind) {
case 'IntValue':
return parseInt(value.value, 10);
case 'FloatValue':
return parseFloat(value.value);
case 'StringValue':
case 'BooleanValue':
case 'EnumValue':
return value.value;
case 'ListValue':
return value.values.map(getLiteralValue);
case 'ObjectValue':
const object = {};
value.fields.forEach(field => {
object[field.name.value] = getLiteralValue(field.value);
});
return object;
case 'Variable':
invariant(
false,
'Unexpected nested variable `%s`; variables are supported as top-' +
'level arguments - `node(id: $id)` - or directly within lists - ' +
'`nodes(ids: [$id])`.',
value.name.value
);
default:
invariant(
false,
'Unexpected value kind: %s',
value.kind
);
}
}

module.exports = {
RelayQLArgument,
RelayQLArgumentType,
Expand Down
17 changes: 16 additions & 1 deletion scripts/babel-relay-plugin/src/RelayQLPrinter.js
Original file line number Diff line number Diff line change
Expand Up @@ -537,7 +537,7 @@ module.exports = function(t: any, options: PrinterOptions): Function {
}
return codify({
kind: t.valueToNode('CallValue'),
callValue: t.valueToNode(value),
callValue: printLiteralValue(value),
});
}

Expand Down Expand Up @@ -795,6 +795,21 @@ module.exports = function(t: any, options: PrinterOptions): Function {
return t.objectProperty(t.identifier(name), value);
}

function printLiteralValue(value: mixed): Printable {
if (value == null) {
return NULL;
} else if (Array.isArray(value)) {
return t.arrayExpression(value.map(printLiteralValue));
} else if (typeof value === 'object' && value != null) {
const objectValue = value;
return t.objectExpression(Object.keys(objectValue).map(key =>
property(key, printLiteralValue(objectValue[key]))
));
} else {
return t.valueToNode(value);
}
}

function shallowFlatten(arr: mixed) {
return t.callExpression(
t.memberExpression(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
Input:
var Relay = require('Relay');
var q = Relay.QL`
query {
searchAll(queries: [$query]) {
title,
},
}
`;

Output:
var Relay = require('Relay');
var q = (function () {
return {
calls: [{
kind: 'Call',
metadata: {
type: '[SearchInput!]!'
},
name: 'queries',
value: [{
kind: 'CallVariable',
callVariableName: 'query'
}]
}],
children: [{
fieldName: 'title',
kind: 'Field',
metadata: {},
type: 'String'
}],
fieldName: 'searchAll',
kind: 'Query',
metadata: {
isPlural: true,
identifyingArgName: 'queries',
identifyingArgType: '[SearchInput!]!'
},
name: 'QueryWithArrayObjectArg',
type: 'SearchResult'
};
})();
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
Input:
var Relay = require('Relay');
var q = Relay.QL`
query {
searchAll(queries: [{queryText: $query}]) {
title,
},
}
`;

Output:
var Relay = require('Relay');
var q = (function () {
throw new Error('GraphQL validation/transform error ``Unexpected nested variable `query`; variables are supported as top-level arguments - `node(id: $id)` - or directly within lists - `nodes(ids: [$id])`.`` in file `queryWithArrayObjectNestedVariable.fixture`.');
})();
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
Input:
var Relay = require('Relay');
var q = Relay.QL`
query {
searchAll(queries: [{queryText: "Relay"}]) {
title,
},
}
`;

Output:
var Relay = require('Relay');
var q = (function () {
return {
calls: [{
kind: 'Call',
metadata: {
type: '[SearchInput!]!'
},
name: 'queries',
value: [{
kind: 'CallValue',
callValue: {
queryText: 'Relay'
}
}]
}],
children: [{
fieldName: 'title',
kind: 'Field',
metadata: {},
type: 'String'
}],
fieldName: 'searchAll',
kind: 'Query',
metadata: {
isPlural: true,
identifyingArgName: 'queries',
identifyingArgType: '[SearchInput!]!'
},
name: 'QueryWithArrayObjectValue',
type: 'SearchResult'
};
})();
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ var q = (function () {
calls: [{
kind: 'Call',
metadata: {
type: '[SearchInput!]'
type: 'SearchInput!'
},
name: 'query',
value: {
Expand All @@ -34,7 +34,7 @@ var q = (function () {
metadata: {
isPlural: true,
identifyingArgName: 'query',
identifyingArgType: '[SearchInput!]'
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

scripts/babel-relay-plugin/src/tests/testschema.rfc.json

identifyingArgType: 'SearchInput!'
},
name: 'QueryWithObjectArg',
type: 'SearchResult'
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
Input:
var Relay = require('Relay');
var q = Relay.QL`
query {
search(query: {queryText: $query}) {
title,
},
}
`;

Output:
var Relay = require('Relay');
var q = (function () {
throw new Error('GraphQL validation/transform error ``Unexpected nested variable `query`; variables are supported as top-level arguments - `node(id: $id)` - or directly within lists - `nodes(ids: [$id])`.`` in file `queryWithObjectArgNestedVariable.fixture`.');
})();
Loading