Skip to content

Commit

Permalink
Disallow user defined object to be used as key in useFragment
Browse files Browse the repository at this point in the history
Reviewed By: jstejada

Differential Revision: D20497252

fbshipit-source-id: 5d7cfeb181480710fb32c9cb3d8ab6db0c979131
  • Loading branch information
tyao1 authored and facebook-github-bot committed Mar 17, 2020
1 parent 0c58ca3 commit b1442b9
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 6 deletions.
10 changes: 10 additions & 0 deletions packages/relay-experimental/__flowtests__/useFragment-flowtest.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import {
keyNonNullablePlural,
keyNullable,
keyNullablePlural,
fragmentData,
} from './utils';
import type {
NonNullableData,
Expand Down Expand Up @@ -52,4 +53,13 @@ import type {
// $FlowExpectedError: Key should be one of the generated types
(useFragment(fragmentInput, 'INVALID_KEY'): NullableData);

// $FlowExpectedError: Key should not be a user provided object
(useFragment(fragmentInput, {a: 123}): NullableData);

// $FlowExpectedError: Key should not be an empty object
(useFragment(fragmentInput, {}): NullableData);

// $FlowExpectedError: Key should be the `<name>$key` type from generated flow
(useFragment(fragmentInput, fragmentData): NullableData);

/* eslint-enable react-hooks/rules-of-hooks */
5 changes: 5 additions & 0 deletions packages/relay-experimental/__flowtests__/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,11 @@ declare export var keyAnotherNullable: ?{
...
};

declare export var fragmentData: {
+$refType: FragmentReference,
...
};

export type QueryOperation = {|
+variables: QueryVariables,
+response: {...},
Expand Down
1 change: 1 addition & 0 deletions packages/relay-experimental/__tests__/useFragment-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ describe('useFragment', () => {
let ContextProvider;

function useFragment(fragmentNode, fragmentRef) {
// $FlowFixMe non-generated fragmentRef is disallowd
const data = useFragmentOriginal(fragmentNode, fragmentRef);
renderSpy(data);
return data;
Expand Down
28 changes: 22 additions & 6 deletions packages/relay-experimental/useFragment.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ const useStaticFragmentNodeWarning = require('./useStaticFragmentNodeWarning');
const {useTrackLoadQueryInRender} = require('./loadQuery');
const {getFragment} = require('relay-runtime');

import type {GraphQLTaggedNode} from 'relay-runtime';
import type {GraphQLTaggedNode, FragmentReference} from 'relay-runtime';

// NOTE: These declares ensure that the type of the returned data is:
// - non-nullable if the provided ref type is non-nullable
Expand All @@ -28,20 +28,30 @@ import type {GraphQLTaggedNode} from 'relay-runtime';
// non-nullable refs
// - array of nullable if the privoided ref type is an array of nullable refs

declare function useFragment<TKey: {+$data?: mixed, ...}>(
declare function useFragment<
TKey: {+$data?: mixed, +$fragmentRefs: FragmentReference, ...},
>(
fragmentInput: GraphQLTaggedNode,
fragmentRef: TKey,
): $Call<<TFragmentData>({+$data?: TFragmentData, ...}) => TFragmentData, TKey>;

declare function useFragment<TKey: ?{+$data?: mixed, ...}>(
declare function useFragment<
TKey: ?{+$data?: mixed, +$fragmentRefs: FragmentReference, ...},
>(
fragmentInput: GraphQLTaggedNode,
fragmentRef: TKey,
): $Call<
<TFragmentData>(?{+$data?: TFragmentData, ...}) => ?TFragmentData,
TKey,
>;

declare function useFragment<TKey: $ReadOnlyArray<{+$data?: mixed, ...}>>(
declare function useFragment<
TKey: $ReadOnlyArray<{
+$data?: mixed,
+$fragmentRefs: FragmentReference,
...
}>,
>(
fragmentInput: GraphQLTaggedNode,
fragmentRef: TKey,
): $Call<
Expand All @@ -51,7 +61,13 @@ declare function useFragment<TKey: $ReadOnlyArray<{+$data?: mixed, ...}>>(
TKey,
>;

declare function useFragment<TKey: ?$ReadOnlyArray<{+$data?: mixed, ...}>>(
declare function useFragment<
TKey: ?$ReadOnlyArray<{
+$data?: mixed,
+$fragmentRefs: FragmentReference,
...
}>,
>(
fragmentInput: GraphQLTaggedNode,
fragmentRef: TKey,
): $Call<
Expand All @@ -63,7 +79,7 @@ declare function useFragment<TKey: ?$ReadOnlyArray<{+$data?: mixed, ...}>>(

function useFragment(
fragmentInput: GraphQLTaggedNode,
fragmentRef: ?$ReadOnlyArray<{+$data?: mixed, ...}> | ?{+$data?: mixed, ...},
fragmentRef: mixed,
): mixed {
// We need to use this hook in order to be able to track if
// loadQuery was called during render
Expand Down

0 comments on commit b1442b9

Please sign in to comment.