Skip to content

Commit 6e91dff

Browse files
committed
add maxCount to array bulk insert variables
1 parent 1451bba commit 6e91dff

2 files changed

Lines changed: 29 additions & 16 deletions

File tree

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

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,8 @@ const EXECUTE_GRAPH_QL_READ_ENDPOINT = 'executeGraphqlRead';
6767
const IMPERSONATE_QUERY_ENDPOINT = 'impersonateQuery';
6868
const IMPERSONATE_MUTATION_ENDPOINT = 'impersonateMutation';
6969

70+
/** @internal The maximum number of items allowed in the @allow directive's maxCount argument. */
71+
export const ALLOW_DIRECTIVE_MAX_COUNT = 10_000;
7072

7173
function getHeaders(isUsingGen: boolean): { [key: string]: string } {
7274
const headerValue = {
@@ -614,18 +616,18 @@ export class DataConnectApiClient {
614616
message: `\`data\` must be a non-empty array for ${operationType}.`
615617
});
616618
}
617-
if (data.length > 10000) {
619+
if (data.length > ALLOW_DIRECTIVE_MAX_COUNT) {
618620
throw new FirebaseDataConnectError({
619621
code: DATA_CONNECT_ERROR_CODE_MAPPING.INVALID_ARGUMENT,
620-
message: '`data` array exceeds the maximum limit of 10,000 items.'
622+
message: `\`data\` array exceeds the maximum limit of ${ALLOW_DIRECTIVE_MAX_COUNT} items.`
621623
});
622624
}
623625

624626
try {
625627
const { capitalized, camelCase } = this.getTableNames(tableName);
626628
const keys = this.getFieldsString(data);
627629
const mutation =
628-
`mutation($data: [${capitalized}_Data!]! @allow(fields: "${keys}")) {
630+
`mutation($data: [${capitalized}_Data!]! @allow(fields: "${keys}", maxCount: ${ALLOW_DIRECTIVE_MAX_COUNT})) {
629631
${camelCase}_${operationType}(data: $data)
630632
}`;
631633

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

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,10 @@ import {
2424
} from '../../../src/utils/api-request';
2525
import * as utils from '../utils';
2626
import * as mocks from '../../resources/mocks';
27-
import { DataConnectApiClient } from '../../../src/data-connect/data-connect-api-client-internal';
27+
import {
28+
ALLOW_DIRECTIVE_MAX_COUNT,
29+
DataConnectApiClient
30+
} from '../../../src/data-connect/data-connect-api-client-internal';
2831
import {
2932
FirebaseDataConnectError,
3033
DATA_CONNECT_ERROR_CODE_MAPPING,
@@ -64,8 +67,8 @@ describe('DataConnectApiClient', () => {
6467
};
6568

6669
const noProjectId = 'Failed to determine project ID. Initialize the SDK with service '
67-
+ 'account credentials or set project ID as an app option. Alternatively, set the '
68-
+ 'GOOGLE_CLOUD_PROJECT environment variable.';
70+
+ 'account credentials or set project ID as an app option. Alternatively, set the '
71+
+ 'GOOGLE_CLOUD_PROJECT environment variable.';
6972

7073
const TEST_RESPONSE = {
7174
data: {
@@ -861,7 +864,7 @@ describe('DataConnectApiClient CRUD helpers', () => {
861864
tableNames.forEach((tableName, index) => {
862865
const capitalizedTable = capitalize(formatedTableNames[index]);
863866
const expectedMutation = `
864-
mutation($data: [${capitalizedTable}_Data!]! @allow(fields: "name")) {
867+
mutation($data: [${capitalizedTable}_Data!]! @allow(fields: "name", maxCount: ${ALLOW_DIRECTIVE_MAX_COUNT})) {
865868
${formatedTableNames[index]}_insertMany(data: $data)
866869
}`;
867870
it(`should use the formatted tableName in the gql query: "${tableName}" as "${formatedTableNames[index]}"`,
@@ -874,7 +877,7 @@ describe('DataConnectApiClient CRUD helpers', () => {
874877
it('should call executeGraphql with the correct mutation for simple data array', async () => {
875878
const simpleDataArray = [{ name: 'test1' }, { name: 'test2', value: 456 }];
876879
const expectedMutation = `
877-
mutation($data: [TestTable_Data!]! @allow(fields: "name value")) {
880+
mutation($data: [TestTable_Data!]! @allow(fields: "name value", maxCount: ${ALLOW_DIRECTIVE_MAX_COUNT})) {
878881
${formatedTableName}_insertMany(data: $data)
879882
}`;
880883
await apiClient.insertMany(tableName, simpleDataArray);
@@ -901,10 +904,14 @@ describe('DataConnectApiClient CRUD helpers', () => {
901904
.to.be.rejectedWith(FirebaseDataConnectError, /`data` must be a non-empty array for insertMany./);
902905
});
903906

904-
it('should throw FirebaseDataConnectError if the data array length exceeds 10,000', async () => {
905-
const oversizedArray = new Array(10001).fill({ name: 'a' });
907+
// eslint-disable-next-line max-len
908+
it(`should throw FirebaseDataConnectError if the data array length exceeds ${ALLOW_DIRECTIVE_MAX_COUNT}`, async () => {
909+
const oversizedArray = new Array(ALLOW_DIRECTIVE_MAX_COUNT + 1).fill({ name: 'a' });
906910
await expect(apiClient.insertMany(tableName, oversizedArray))
907-
.to.be.rejectedWith(FirebaseDataConnectError, /`data` array exceeds the maximum limit of 10,000 items./);
911+
.to.be.rejectedWith(
912+
FirebaseDataConnectError,
913+
new RegExp(`^\`data\` array exceeds the maximum limit of ${ALLOW_DIRECTIVE_MAX_COUNT} items.$`)
914+
);
908915
});
909916

910917
it('should amend the message for query errors', async () => {
@@ -976,7 +983,7 @@ describe('DataConnectApiClient CRUD helpers', () => {
976983
tableNames.forEach((tableName, index) => {
977984
const capitalizedTable = capitalize(formatedTableNames[index]);
978985
const expectedMutation = `
979-
mutation($data: [${capitalizedTable}_Data!]! @allow(fields: "name")) {
986+
mutation($data: [${capitalizedTable}_Data!]! @allow(fields: "name", maxCount: ${ALLOW_DIRECTIVE_MAX_COUNT})) {
980987
${formatedTableNames[index]}_upsertMany(data: $data)
981988
}`;
982989
it(`should use the formatted tableName in the gql query: "${tableName}" as "${formatedTableNames[index]}"`,
@@ -989,7 +996,7 @@ describe('DataConnectApiClient CRUD helpers', () => {
989996
it('should call executeGraphql with the correct mutation for simple data array', async () => {
990997
const simpleDataArray = [{ id: 'k1' }, { id: 'k2', value: 99 }];
991998
const expectedMutation = `
992-
mutation($data: [TestTable_Data!]! @allow(fields: "id value")) {
999+
mutation($data: [TestTable_Data!]! @allow(fields: "id value", maxCount: ${ALLOW_DIRECTIVE_MAX_COUNT})) {
9931000
${formatedTableName}_upsertMany(data: $data)
9941001
}`;
9951002
await apiClient.upsertMany(tableName, simpleDataArray);
@@ -1016,10 +1023,14 @@ describe('DataConnectApiClient CRUD helpers', () => {
10161023
.to.be.rejectedWith(FirebaseDataConnectError, /`data` must be a non-empty array for upsertMany./);
10171024
});
10181025

1019-
it('should throw FirebaseDataConnectError if the data array length exceeds 10,000', async () => {
1020-
const oversizedArray = new Array(10001).fill({ name: 'a' });
1026+
// eslint-disable-next-line max-len
1027+
it(`should throw FirebaseDataConnectError if the data array length exceeds ${ALLOW_DIRECTIVE_MAX_COUNT}`, async () => {
1028+
const oversizedArray = new Array(ALLOW_DIRECTIVE_MAX_COUNT + 1).fill({ name: 'a' });
10211029
await expect(apiClient.upsertMany(tableName, oversizedArray))
1022-
.to.be.rejectedWith(FirebaseDataConnectError, /`data` array exceeds the maximum limit of 10,000 items./);
1030+
.to.be.rejectedWith(
1031+
FirebaseDataConnectError,
1032+
new RegExp(`^\`data\` array exceeds the maximum limit of ${ALLOW_DIRECTIVE_MAX_COUNT} items.$`)
1033+
);
10231034
});
10241035

10251036
it('should amend the message for query errors', async () => {

0 commit comments

Comments
 (0)