Skip to content

Commit

Permalink
only allow first level properties to be promises
Browse files Browse the repository at this point in the history
  • Loading branch information
yaacovCR committed Sep 29, 2021
1 parent 9aa2d88 commit e619b78
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 19 deletions.
47 changes: 31 additions & 16 deletions packages/stitching-directives/src/properties.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,31 @@ export function getProperty(object: Record<string, any>, path: Array<string>): a
return getProperty(prop, newPath);
}

export function getProperties(object: Record<string, any>, propertyTree: PropertyTree): any {
if (object == null) {
return object;
}

const newObject = Object.create(null);

for (const key in propertyTree) {
const subKey = propertyTree[key];

if (subKey == null) {
newObject[key] = object[key];
continue;
}

const prop = object[key];

newObject[key] = deepMap(prop, function deepMapFn(item) {
return getProperties(item, subKey);
});
}

return newObject;
}

// c.f. https://github.com/graphql/graphql-js/blob/main/src/jsutils/promiseForObject.ts
export function getResolvedPropertiesOrPromise(
object: Record<string, any>,
Expand All @@ -60,13 +85,9 @@ export function getResolvedPropertiesOrPromise(
return;
}

return deepMap(value, function deepMapFn(item) {
return getResolvedPropertiesOrPromise(item, subKey).resolve();
})
.then(mappedValue => {
newObject[key] = mappedValue;
})
.resolve();
newObject[key] = deepMap(value, function deepMapFn(item) {
return getProperties(item, subKey);
});
})
)
).then(() => newObject);
Expand All @@ -80,16 +101,10 @@ export function propertyTreeFromPaths(paths: Array<Array<string>>): PropertyTree
return propertyTree;
}

function deepMap(arrayOrItem: any, fn: (item: any) => any | Promise<any>): ValueOrPromise<any> {
function deepMap(arrayOrItem: any, fn: (item: any) => any): any {
if (Array.isArray(arrayOrItem)) {
return ValueOrPromise.all(
arrayOrItem.map(nestedArrayOrItem =>
new ValueOrPromise(() => nestedArrayOrItem).then(resolvedNestedArrayOrItem =>
deepMap(resolvedNestedArrayOrItem, fn).resolve()
)
)
);
return arrayOrItem.map(nestedArrayOrItem => deepMap(nestedArrayOrItem, fn));
}

return new ValueOrPromise(() => fn(arrayOrItem));
return fn(arrayOrItem);
}
34 changes: 31 additions & 3 deletions packages/stitching-directives/tests/properties.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { addProperty, getResolvedPropertiesOrPromise } from "../src/properties";
import { addProperty, getProperties, getResolvedPropertiesOrPromise } from "../src/properties";

describe('addProperty', () => {
test('can add a key to an object', () => {
Expand Down Expand Up @@ -28,13 +28,41 @@ describe('addProperty', () => {
});
});

describe('getProperties', () => {
test('can getProperties', async () => {
const object = {
field1: 'value1',
field2: {
subfieldA: 'valueA',
subfieldB: 'valueB',
},
}

const extracted = getProperties(object, {
field1: null,
field2: {
subfieldA: null,
}
});

const expectedExtracted = {
field1: 'value1',
field2: {
subfieldA: 'valueA',
}
}

expect(extracted).toEqual(expectedExtracted);
});
});

describe('getResolvedPropertiesOrPromise', () => {
test('can getResolvedPropertiesOrPromise', async () => {
const object = {
field1: 'value1',
field2: Promise.resolve({
subfieldA: Promise.resolve('valueA'),
subfieldB: Promise.resolve('valueB'),
subfieldA: 'valueA',
subfieldB: 'valueB',
}),
}

Expand Down

0 comments on commit e619b78

Please sign in to comment.