Skip to content
Merged
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
22 changes: 12 additions & 10 deletions API_DOCS.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ resources:
nestedPath: ?string (can only use if isBatchResource=true)
commaSeparatedBatchKey: ?string (can only use if isBatchResource=true)
isResponseDictionary: ?boolean (can only use if isBatchResource=true)
isBatchKeyASet: ?boolean (can only use if isBatchResource=true)

typings:
language: flow
Expand All @@ -113,16 +114,17 @@ Describes the shape and behaviour of the resources object you will pass to `getL

#### `resources` Parameters

| Key | Value Description |
| ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `isBatchResource` | Is this a batch resource? (Can you pass it a list of keys and get a list of results back?) |
| `docsLink` | The URL for the documentation of the resource. Useful for others to verify information is correct, and may be used in stack traces. |
| `batchKey` | The argument to the resource that represents the list of entities we want to fetch. (e.g. 'user_ids') |
| `newKey` | The argument we'll replace the batchKey with - should be a singular version of the `batchKey` (e.g. 'user_id') |
| `reorderResultsByKey` | (Optional) If the resource itself does not guarantee ordering, use this to specify which key in the response objects corresponds to an element in `batchKey`. Transforms and re-order the response to the same order as requested from the DataLoaders. |
| `nestedPath` | (Optional) If the resource returns the list of results in a nested path (e.g. `{ results: [ 1, 2, 3 ] }`), this tells the DataLoader where in the response to find the results. (e.g. 'results'). |
| `commaSeparatedBatchKey` | (Optional) Set to true if the interface of the resource takes the batch key as a comma separated list (rather than an array of IDs, as is more common). Default: false |
| `isResponseDictionary` | (Optional) Set to true if the batch resource returns the results as a dictionary with key mapped to values (instead of a list of items). If this option is supplied `reorderResultsByKey` should not be. Default: false |
| Key | Value Description |
| ------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `isBatchResource` | Is this a batch resource? (Can you pass it a list of keys and get a list of results back?) |
| `docsLink` | The URL for the documentation of the resource. Useful for others to verify information is correct, and may be used in stack traces. |
| `batchKey` | The argument to the resource that represents the list of entities we want to fetch. (e.g. 'user_ids') |
| `newKey` | The argument we'll replace the batchKey with - should be a singular version of the `batchKey` (e.g. 'user_id') |
| `reorderResultsByKey` | (Optional) If the resource itself does not guarantee ordering, use this to specify which key in the response objects corresponds to an element in `batchKey`. Transforms and re-order the response to the same order as requested from the DataLoaders. |
| `nestedPath` | (Optional) If the resource returns the list of results in a nested path (e.g. `{ results: [ 1, 2, 3 ] }`), this tells the DataLoader where in the response to find the results. (e.g. 'results'). |
| `commaSeparatedBatchKey` | (Optional) Set to true if the interface of the resource takes the batch key as a comma separated list (rather than an array of IDs, as is more common). Default: false |
| `isResponseDictionary` | (Optional) Set to true if the batch resource returns the results as a dictionary with key mapped to values (instead of a list of items). If this option is supplied `reorderResultsByKey` should not be. Default: false |
| `isBatchKeyASet` | (Optional) Set to true if the interface of the resource takes the batch key as a set (rather than an array). For example, when using a generated clientlib based on swagger where `uniqueItems: true` is set for the batchKey parameter. Default: false. |

### `typings`

Expand Down
15 changes: 14 additions & 1 deletion __tests__/genTypeFlow.test.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,20 @@
import { getResourceTypeReference } from '../src/genTypeFlow';
import { getResourceTypeReference, getNewKeyTypeFromBatchKeySetType } from '../src/genTypeFlow';

it('getResourceTypeReference converts a resource path to a valid reference', () => {
expect(getResourceTypeReference(null, ['foo', 'bar', 'baz'])).toBe(
"$PropertyType<$PropertyType<$PropertyType<ResourcesType, 'foo'>, 'bar'>, 'baz'>",
);
});

it('getNewKeyTypeFromBatchKeySetType returns a newKey type with a valid value', () => {
expect(
getNewKeyTypeFromBatchKeySetType(
'bKey',
"$PropertyType<$PropertyType<$PropertyType<ResourcesType, 'foo'>, 'bar'>, 'baz'>",
),
).toBe(`\
$Call<
ExtractArg,
[$PropertyType<$PropertyType<$PropertyType<$PropertyType<$PropertyType<ResourcesType, 'foo'>, 'bar'>, 'baz'>, 'bKey'>, 'has'>]
>`);
});
53 changes: 53 additions & 0 deletions __tests__/implementation.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -843,6 +843,59 @@ test('batch endpoint with isResponseDictionary handles a response that returns a
});
});

test('batch endpoint with isBatchKeyASet handles a response', async () => {
const config = {
resources: {
foo: {
isBatchResource: true,
docsLink: 'example.com/docs/bar',
batchKey: 'foo_ids',
newKey: 'foo_id',
isBatchKeyASet: true,
},
},
};

const resources = {
foo: ({ foo_ids, include_extra_info }) => {
if (_.isEqual(foo_ids, [1, 2])) {
expect(include_extra_info).toBe(false);
return Promise.resolve([
{ foo_id: 1, foo_value: 'hello' },
{ foo_id: 2, foo_value: 'world' },
]);
}

if (_.isEqual(foo_ids, [3])) {
expect(include_extra_info).toBe(true);
return Promise.resolve([
{
foo_id: 3,
foo_value: 'greetings',
extra_stuff: 'lorem ipsum',
},
]);
}
},
};

await createDataLoaders(config, async (getLoaders) => {
const loaders = getLoaders(resources);

const results = await loaders.foo.loadMany([
{ foo_id: 1, include_extra_info: false },
{ foo_id: 2, include_extra_info: false },
{ foo_id: 3, include_extra_info: true },
]);

expect(results).toEqual([
{ foo_id: 1, foo_value: 'hello' },
{ foo_id: 2, foo_value: 'world' },
{ foo_id: 3, foo_value: 'greetings', extra_stuff: 'lorem ipsum' },
]);
});
});

test('batch endpoint with isResponseDictionary handles a response that returns a dictionary, with a missing item', async () => {
const config = {
resources: {
Expand Down
Loading