Skip to content

Commit 8f9eae1

Browse files
Merge remote-tracking branch 'origin/main' into beta-releases
2 parents f7d0135 + a024f5f commit 8f9eae1

File tree

19 files changed

+135
-99
lines changed

19 files changed

+135
-99
lines changed

.github/workflows/codeql.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ jobs:
6262
- '**/*.spec.ts'
6363
- '**/*.test.tsx'
6464
- '**/*.spec.tsx'
65+
- 'scripts/**'
6566
6667
# Autobuild attempts to build any compiled languages (C/C++, C#, Go, Java, or Swift).
6768
# If this step fails, then you should remove it and run the build manually (see below)

THIRD-PARTY-NOTICES.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
The following third-party software is used by and included in **Mongodb Compass**.
2-
This document was automatically generated on Thu Dec 14 2023.
2+
This document was automatically generated on Sun Dec 17 2023.
33

44
## List of dependencies
55

packages/compass-aggregations/src/components/stage-wizard/index.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,9 @@ export default connect(
289289
return { name, type };
290290
});
291291
const previousStageFieldsWithSchema = getSchema(
292-
previousStage?.previewDocs ?? []
292+
previousStage?.previewDocs?.map((doc) => {
293+
return doc.generateObject();
294+
}) ?? []
293295
);
294296

295297
const fields =

packages/compass-aggregations/src/utils/get-schema.spec.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,4 +189,22 @@ describe('get schema', function () {
189189
expect(getSchema(input)).to.deep.equal(output);
190190
});
191191
});
192+
193+
it("doesn't break when getting schema from recursive object", function () {
194+
const a = {
195+
b: {
196+
c: {
197+
get a() {
198+
return a;
199+
},
200+
},
201+
},
202+
};
203+
204+
expect(getSchema([a])).to.deep.eq([
205+
{ name: 'b', type: 'Object' },
206+
{ name: 'b.c', type: 'Object' },
207+
{ name: 'b.c.a', type: 'Object' },
208+
]);
209+
});
192210
});

packages/compass-aggregations/src/utils/get-schema.ts

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,17 +22,28 @@ const toFieldSchemaWithPrefix = (prefix: string) => {
2222
});
2323
};
2424

25-
const getSchemaForObject = (document: Document): DocumentSchema => {
25+
const getSchemaForObject = (
26+
document: Document,
27+
seen = new WeakSet()
28+
): DocumentSchema => {
2629
const schema: DocumentSchema = [];
30+
31+
if (seen.has(document)) {
32+
return schema;
33+
}
34+
35+
seen.add(document);
36+
2737
for (const key in document) {
2838
const value = document[key];
39+
2940
schema.push({
3041
name: key,
3142
type: TypeChecker.type(value),
3243
});
3344

3445
if (Array.isArray(value)) {
35-
const valueSchema = getSchemaForArray(value).map(
46+
const valueSchema = getSchemaForArray(value, seen).map(
3647
toFieldSchemaWithPrefix(key)
3748
);
3849
schema.push(...valueSchema);
@@ -41,7 +52,7 @@ const getSchemaForObject = (document: Document): DocumentSchema => {
4152
value !== null &&
4253
!value._bsontype
4354
) {
44-
const valueSchema = getSchemaForObject(value).map(
55+
const valueSchema = getSchemaForObject(value, seen).map(
4556
toFieldSchemaWithPrefix(key)
4657
);
4758
schema.push(...valueSchema);
@@ -50,18 +61,21 @@ const getSchemaForObject = (document: Document): DocumentSchema => {
5061
return schema;
5162
};
5263

53-
const getSchemaForArray = (records: Document[]): DocumentSchema => {
64+
const getSchemaForArray = (
65+
records: Document[],
66+
seen = new WeakSet()
67+
): DocumentSchema => {
5468
const schema: DocumentSchema = [];
5569

5670
for (const record of records) {
5771
if (Array.isArray(record)) {
58-
schema.push(...getSchemaForArray(record));
72+
schema.push(...getSchemaForArray(record, seen));
5973
} else if (
6074
typeof record === 'object' &&
6175
record !== null &&
6276
!record._bsontype
6377
) {
64-
schema.push(...getSchemaForObject(record));
78+
schema.push(...getSchemaForObject(record, seen));
6579
}
6680
}
6781

packages/compass-crud/src/actions/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ const configureActions = () => {
55
'addColumn',
66
'cleanCols',
77
'closeInsertDocumentDialog',
8-
'closeBulkUpdateDialog',
8+
'closeBulkUpdateModal',
99
'copyToClipboard',
1010
'documentRemoved',
1111
'drillDown',
@@ -19,7 +19,7 @@ const configureActions = () => {
1919
'toggleInsertDocumentView',
2020
'toggleInsertDocument',
2121
'openInsertDocumentDialog',
22-
'openBulkUpdateDialog',
22+
'openBulkUpdateModal',
2323
'updateBulkUpdatePreview',
2424
'runBulkUpdate',
2525
'openExportFileDialog',

packages/compass-crud/src/components/bulk-delete-modal.spec.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ function renderBulkDeleteModal(
1212
<BulkDeleteModal
1313
open={true}
1414
documentCount={0}
15-
filterQuery="{ a: 1 }"
15+
filter={{ a: 1 }}
1616
namespace="mydb.mycoll"
1717
sampleDocuments={[]}
1818
onCancel={() => {}}
@@ -68,9 +68,9 @@ describe('BulkDeleteModal Component', function () {
6868
});
6969

7070
it('shows the provided query', function () {
71-
renderBulkDeleteModal({ filterQuery: '{ a: 1 }' });
71+
renderBulkDeleteModal({ filter: { a: 1 } });
7272
expect(screen.getByTestId('readonly-filter').textContent).to.equal(
73-
'{ a: 1 }'
73+
'{\n a: 1\n}'
7474
);
7575
});
7676

packages/compass-crud/src/components/bulk-delete-modal.tsx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ import {
1212
spacing,
1313
useId,
1414
} from '@mongodb-js/compass-components';
15+
import type { BSONObject } from '../stores/crud-store';
16+
import { toJSString } from 'mongodb-query-parser';
1517
import { ReadonlyFilter } from './readonly-filter';
1618
import ReadonlyDocument from './readonly-document';
1719

@@ -59,7 +61,7 @@ const exportToLanguageButtonStyles = css({
5961
type BulkDeleteModalProps = {
6062
open: boolean;
6163
documentCount?: number;
62-
filterQuery: string;
64+
filter: BSONObject;
6365
namespace: string;
6466
sampleDocuments: Document[];
6567
onCancel: () => void;
@@ -70,7 +72,7 @@ type BulkDeleteModalProps = {
7072
const BulkDeleteModal: React.FunctionComponent<BulkDeleteModalProps> = ({
7173
open,
7274
documentCount,
73-
filterQuery,
75+
filter,
7476
namespace,
7577
sampleDocuments,
7678
onCancel,
@@ -106,7 +108,7 @@ const BulkDeleteModal: React.FunctionComponent<BulkDeleteModalProps> = ({
106108
/>
107109
<ModalBody variant={'danger'} className={modalBodySpacingStyles}>
108110
<div className={queryBarStyles}>
109-
<ReadonlyFilter queryLabel="Filter" filterQuery={filterQuery} />
111+
<ReadonlyFilter filterQuery={toJSString(filter) ?? ''} />
110112
<Button
111113
className={exportToLanguageButtonStyles}
112114
variant="primaryOutline"

packages/compass-crud/src/components/bulk-update-dialog.spec.tsx renamed to packages/compass-crud/src/components/bulk-update-modal.spec.tsx

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,13 @@ import { expect } from 'chai';
33
import sinon from 'sinon';
44
import { render, screen, cleanup, waitFor } from '@testing-library/react';
55
import userEvent from '@testing-library/user-event';
6-
import BulkUpdateDialog from './bulk-update-dialog';
6+
import BulkUpdateModal from './bulk-update-modal';
77

8-
function renderBulkUpdateDialog(
9-
props?: Partial<React.ComponentProps<typeof BulkUpdateDialog>>
8+
function renderBulkUpdateModal(
9+
props?: Partial<React.ComponentProps<typeof BulkUpdateModal>>
1010
) {
1111
return render(
12-
<BulkUpdateDialog
12+
<BulkUpdateModal
1313
isOpen={true}
1414
ns="mydb.mycoll"
1515
filter={{ a: 1 }}
@@ -24,7 +24,7 @@ function renderBulkUpdateDialog(
2424
],
2525
}}
2626
enablePreview={true}
27-
closeBulkUpdateDialog={() => {}}
27+
closeBulkUpdateModal={() => {}}
2828
updateBulkUpdatePreview={() => {}}
2929
runBulkUpdate={() => {}}
3030
saveUpdateQuery={() => {}}
@@ -33,18 +33,18 @@ function renderBulkUpdateDialog(
3333
);
3434
}
3535

36-
describe('BulkUpdateDialog Component', function () {
36+
describe('BulkUpdateModal Component', function () {
3737
afterEach(function () {
3838
cleanup();
3939
});
4040

4141
it('does not render if closed', function () {
42-
renderBulkUpdateDialog({ isOpen: false });
42+
renderBulkUpdateModal({ isOpen: false });
4343
expect(screen.queryByText(/Update/)).to.not.exist;
4444
});
4545

4646
it('renders if open', function () {
47-
renderBulkUpdateDialog({ count: 42 });
47+
renderBulkUpdateModal({ count: 42 });
4848

4949
expect(screen.getByTestId('modal-title').textContent).to.equal(
5050
'Update 42 documents'
@@ -72,7 +72,7 @@ describe('BulkUpdateDialog Component', function () {
7272
});
7373

7474
it('hides document count if count is N/A', function () {
75-
renderBulkUpdateDialog({ count: undefined });
75+
renderBulkUpdateModal({ count: undefined });
7676

7777
expect(screen.getByTestId('modal-title').textContent).to.equal(
7878
'Update documents'
@@ -82,7 +82,7 @@ describe('BulkUpdateDialog Component', function () {
8282
});
8383

8484
it('use singular if count is 1', function () {
85-
renderBulkUpdateDialog({ count: 1 });
85+
renderBulkUpdateModal({ count: 1 });
8686
expect(screen.getByTestId('modal-title').textContent).to.equal(
8787
'Update 1 document'
8888
);
@@ -91,17 +91,17 @@ describe('BulkUpdateDialog Component', function () {
9191
});
9292

9393
it('renders the empty state if the count is 0', function () {
94-
renderBulkUpdateDialog({ count: 0 });
94+
renderBulkUpdateModal({ count: 0 });
9595
expect(screen.getByTestId('bulk-update-preview-empty-state')).to.exist;
9696
});
9797

9898
it('resets if the modal is re-opened', async function () {
9999
// initial open
100-
const { rerender } = renderBulkUpdateDialog({ isOpen: true });
100+
const { rerender } = renderBulkUpdateModal({ isOpen: true });
101101

102102
// close
103103
rerender(
104-
<BulkUpdateDialog
104+
<BulkUpdateModal
105105
isOpen={false}
106106
ns="mydb.mycoll"
107107
filter={{ a: 1 }}
@@ -115,7 +115,7 @@ describe('BulkUpdateDialog Component', function () {
115115
},
116116
],
117117
}}
118-
closeBulkUpdateDialog={() => {}}
118+
closeBulkUpdateModal={() => {}}
119119
updateBulkUpdatePreview={() => {}}
120120
runBulkUpdate={() => {}}
121121
saveUpdateQuery={() => {}}
@@ -124,7 +124,7 @@ describe('BulkUpdateDialog Component', function () {
124124

125125
// re-open
126126
rerender(
127-
<BulkUpdateDialog
127+
<BulkUpdateModal
128128
isOpen={true}
129129
ns="mydb.mycoll"
130130
filter={{ a: 1 }}
@@ -138,7 +138,7 @@ describe('BulkUpdateDialog Component', function () {
138138
},
139139
],
140140
}}
141-
closeBulkUpdateDialog={() => {}}
141+
closeBulkUpdateModal={() => {}}
142142
updateBulkUpdatePreview={() => {}}
143143
runBulkUpdate={() => {}}
144144
saveUpdateQuery={() => {}}
@@ -156,15 +156,15 @@ describe('BulkUpdateDialog Component', function () {
156156

157157
it('closes the modal when the close button is clicked', function () {
158158
const onCloseSpy = sinon.spy();
159-
renderBulkUpdateDialog({ closeBulkUpdateDialog: onCloseSpy });
159+
renderBulkUpdateModal({ closeBulkUpdateModal: onCloseSpy });
160160

161161
userEvent.click(screen.getByRole('button', { name: 'Cancel' }));
162162
expect(onCloseSpy).to.have.been.calledOnce;
163163
});
164164

165165
it('runs the update when the update button is clicked (preview supported)', function () {
166166
const onUpdateSpy = sinon.spy();
167-
renderBulkUpdateDialog({
167+
renderBulkUpdateModal({
168168
enablePreview: true,
169169
runBulkUpdate: onUpdateSpy,
170170
count: 60,
@@ -183,7 +183,7 @@ describe('BulkUpdateDialog Component', function () {
183183

184184
it('runs the update when the update button is clicked (preview unsupported)', function () {
185185
const onUpdateSpy = sinon.spy();
186-
renderBulkUpdateDialog({
186+
renderBulkUpdateModal({
187187
enablePreview: false,
188188
runBulkUpdate: onUpdateSpy,
189189
count: 60,
@@ -202,7 +202,7 @@ describe('BulkUpdateDialog Component', function () {
202202

203203
it('saves the query when a name is provided', function () {
204204
const saveUpdateQuerySpy = sinon.spy();
205-
renderBulkUpdateDialog({ saveUpdateQuery: saveUpdateQuerySpy });
205+
renderBulkUpdateModal({ saveUpdateQuery: saveUpdateQuerySpy });
206206

207207
userEvent.click(screen.getByTestId('inline-save-query-modal-opener'));
208208
userEvent.type(

0 commit comments

Comments
 (0)