Skip to content

Commit 66d404b

Browse files
committed
address reviewer comments
1 parent 4f87c12 commit 66d404b

3 files changed

Lines changed: 34 additions & 5 deletions

File tree

CONTRIBUTING.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -153,8 +153,8 @@ And then:
153153
Currently, only the Auth, Database, and Firestore test suites work. Some test cases
154154
will be automatically skipped due to lack of emulator support.
155155

156-
You can also run the Data Connect test suite against the emulators using the same command,
157-
but you must run only the dataconnect tests, using a config file specific to Data Connect
156+
**Note:** You can also run the Data Connect test suite against the emulators using the same command.
157+
However, you must isolate the Data Connect tests by using a configuration file specific to Data Connect
158158
emulator testing:
159159

160160
```bash

src/data-connect/data-connect-api-client-internal.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -645,14 +645,18 @@ export function getFieldsString(data: unknown): string {
645645
return serializeFieldNode(root);
646646
}
647647

648-
function mergeFieldsIntoTree(data: unknown, node: FieldNode): void {
648+
function mergeFieldsIntoTree(data: unknown, node: FieldNode, visited: Set<unknown> = new Set<unknown>()): void {
649649
if (validator.isArray(data)) {
650-
data.forEach((item) => mergeFieldsIntoTree(item, node));
650+
data.forEach((item) => mergeFieldsIntoTree(item, node, visited));
651651
return;
652652
}
653653
if (!validator.isNonNullObject(data) || data instanceof Date) {
654654
return;
655655
}
656+
if (visited.has(data)) {
657+
throw new Error('Circular reference detected in input.');
658+
}
659+
visited.add(data);
656660
const record = data as Record<string, unknown>;
657661
for (const [key, val] of Object.entries(record)) {
658662
if (val === undefined) {
@@ -664,9 +668,10 @@ function mergeFieldsIntoTree(data: unknown, node: FieldNode): void {
664668
node.children.set(key, childNode);
665669
}
666670
if (key.includes('_on_')) {
667-
mergeFieldsIntoTree(val, childNode);
671+
mergeFieldsIntoTree(val, childNode, visited);
668672
}
669673
}
674+
visited.delete(data);
670675
}
671676

672677
function serializeFieldNode(node: FieldNode): string {

test/unit/data-connect/data-connect-api-client-internal.spec.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -775,6 +775,30 @@ describe('DataConnectApiClient CRUD helpers', () => {
775775
const fields = getFieldsString(dataWithUndefined);
776776
expect(fields).to.equal('director extras genre ratings title');
777777
});
778+
779+
it('should allow duplicate object references in different sibling branches (non-circular DAG)', () => {
780+
const shared = { name: 'shared' };
781+
const data = {
782+
child1_on_foo: shared,
783+
child2_on_bar: shared,
784+
};
785+
const fields = getFieldsString(data);
786+
expect(fields).to.equal('child1_on_foo { name } child2_on_bar { name }');
787+
});
788+
789+
it('should throw an error if a direct circular reference is detected', () => {
790+
const data: any = { id: 'abc' };
791+
data.direct_circular_on_reference = data;
792+
expect(() => getFieldsString(data)).to.throw('Circular reference detected in input.');
793+
});
794+
795+
it('should throw an error if an indirect circular reference is detected', () => {
796+
const data: any = { id: 'abc' };
797+
data.indirect_circular_on_reference = {
798+
circular_on_reference: data,
799+
};
800+
expect(() => getFieldsString(data)).to.throw('Circular reference detected in input.');
801+
});
778802
});
779803

780804
describe('array of objects', () => {

0 commit comments

Comments
 (0)