1
1
mirror of https://github.com/n8n-io/n8n.git synced 2024-08-16 08:30:26 +03:00

fix(Google Sheets Node): Append fails if cells have some default values added by data validation rules (#9950)

This commit is contained in:
Michael Kret 2024-07-06 01:05:08 +03:00 committed by GitHub
parent b910ed6847
commit d1821eba92
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 216 additions and 161 deletions

View File

@ -304,11 +304,11 @@ describe('Test Google Sheets, lookupValues', () => {
const googleSheet = new GoogleSheet('spreadsheetId', fakeExecuteFunction); const googleSheet = new GoogleSheet('spreadsheetId', fakeExecuteFunction);
const result = await googleSheet.lookupValues( const result = await googleSheet.lookupValues({
inputData, inputData,
0, keyRowIndex: 0,
1, dataStartRowIndex: 1,
[ lookupValues: [
{ {
lookupColumn: 'num', lookupColumn: 'num',
lookupValue: '1', lookupValue: '1',
@ -318,9 +318,9 @@ describe('Test Google Sheets, lookupValues', () => {
lookupValue: 'foo', lookupValue: 'foo',
}, },
], ],
true, returnAllMatches: true,
'OR', combineFilters: 'OR',
); });
expect(result).toBeDefined(); expect(result).toBeDefined();
expect(result).toEqual([ expect(result).toEqual([
@ -366,11 +366,11 @@ describe('Test Google Sheets, lookupValues', () => {
const googleSheet = new GoogleSheet('spreadsheetId', fakeExecuteFunction); const googleSheet = new GoogleSheet('spreadsheetId', fakeExecuteFunction);
const result = await googleSheet.lookupValues( const result = await googleSheet.lookupValues({
inputData, inputData,
0, keyRowIndex: 0,
1, dataStartRowIndex: 1,
[ lookupValues: [
{ {
lookupColumn: 'num', lookupColumn: 'num',
lookupValue: '1', lookupValue: '1',
@ -380,9 +380,9 @@ describe('Test Google Sheets, lookupValues', () => {
lookupValue: 'baz', lookupValue: 'baz',
}, },
], ],
true, returnAllMatches: true,
'AND', combineFilters: 'AND',
); });
expect(result).toBeDefined(); expect(result).toBeDefined();
expect(result).toEqual([ expect(result).toEqual([

View File

@ -213,7 +213,7 @@ export const description: SheetProperties = [
export async function execute( export async function execute(
this: IExecuteFunctions, this: IExecuteFunctions,
sheet: GoogleSheet, sheet: GoogleSheet,
sheetName: string, range: string,
sheetId: string, sheetId: string,
): Promise<INodeExecutionData[]> { ): Promise<INodeExecutionData[]> {
const items = this.getInputData(); const items = this.getInputData();
@ -228,57 +228,62 @@ export async function execute(
const options = this.getNodeParameter('options', 0, {}); const options = this.getNodeParameter('options', 0, {});
const locationDefine = (options.locationDefine as IDataObject)?.values as IDataObject; const locationDefine = (options.locationDefine as IDataObject)?.values as IDataObject;
let headerRow = 1; let keyRowIndex = 1;
if (locationDefine?.headerRow) { if (locationDefine?.headerRow) {
headerRow = locationDefine.headerRow as number; keyRowIndex = locationDefine.headerRow as number;
} }
const sheetData = await sheet.getData(range, 'FORMATTED_VALUE');
if (nodeVersion >= 4.4 && dataMode !== 'autoMapInputData') { if (nodeVersion >= 4.4 && dataMode !== 'autoMapInputData') {
//not possible to refresh columns when mode is autoMapInputData //not possible to refresh columns when mode is autoMapInputData
const sheetData = await sheet.getData(sheetName, 'FORMATTED_VALUE'); if (sheetData?.[keyRowIndex - 1] === undefined) {
if (sheetData?.[headerRow - 1] === undefined) {
throw new NodeOperationError( throw new NodeOperationError(
this.getNode(), this.getNode(),
`Could not retrieve the column names from row ${headerRow}`, `Could not retrieve the column names from row ${keyRowIndex}`,
); );
} }
const schema = this.getNodeParameter('columns.schema', 0) as ResourceMapperField[]; const schema = this.getNodeParameter('columns.schema', 0) as ResourceMapperField[];
checkForSchemaChanges(this.getNode(), sheetData[headerRow - 1], schema); checkForSchemaChanges(this.getNode(), sheetData[keyRowIndex - 1], schema);
} }
let setData: IDataObject[] = []; let inputData: IDataObject[] = [];
if (dataMode === 'autoMapInputData') { if (dataMode === 'autoMapInputData') {
setData = await autoMapInputData.call(this, sheetName, sheet, items, options); inputData = await autoMapInputData.call(this, range, sheet, items, options);
} else { } else {
setData = mapFields.call(this, items.length); inputData = mapFields.call(this, items.length);
} }
if (setData.length === 0) { if (inputData.length === 0) {
return []; return [];
} else if (options.useAppend) { }
await sheet.appendSheetData(
setData, const valueInputMode = (options.cellFormat as ValueInputOption) || cellFormatDefault(nodeVersion);
sheetName, const useAppend = options.useAppend as boolean;
headerRow,
(options.cellFormat as ValueInputOption) || cellFormatDefault(nodeVersion), if (options.useAppend) {
false, await sheet.appendSheetData({
undefined, inputData,
undefined, range,
options.useAppend as boolean, keyRowIndex,
); valueInputMode,
useAppend,
});
} else { } else {
//if no trailing empty row exists in the sheet update operation will fail
await sheet.appendEmptyRowsOrColumns(sheetId, 1, 0); await sheet.appendEmptyRowsOrColumns(sheetId, 1, 0);
await sheet.appendSheetData( const lastRow = (sheetData ?? []).length + 1;
setData,
sheetName, await sheet.appendSheetData({
headerRow, inputData,
(options.cellFormat as ValueInputOption) || cellFormatDefault(nodeVersion), range,
false, keyRowIndex,
); valueInputMode,
lastRow,
});
} }
if (nodeVersion < 4 || dataMode === 'autoMapInputData') { if (nodeVersion < 4 || dataMode === 'autoMapInputData') {
@ -288,7 +293,7 @@ export async function execute(
}); });
} else { } else {
const returnData: INodeExecutionData[] = []; const returnData: INodeExecutionData[] = [];
for (const [index, entry] of setData.entries()) { for (const [index, entry] of inputData.entries()) {
returnData.push({ returnData.push({
json: entry, json: entry,
pairedItem: { item: index }, pairedItem: { item: index },

View File

@ -246,15 +246,15 @@ export async function execute(
const locationDefineOption = (options.locationDefine as IDataObject)?.values as IDataObject; const locationDefineOption = (options.locationDefine as IDataObject)?.values as IDataObject;
let headerRow = 0; let keyRowIndex = 0;
let firstDataRow = 1; let dataStartRowIndex = 1;
if (locationDefineOption) { if (locationDefineOption) {
if (locationDefineOption.headerRow) { if (locationDefineOption.headerRow) {
headerRow = parseInt(locationDefineOption.headerRow as string, 10) - 1; keyRowIndex = parseInt(locationDefineOption.headerRow as string, 10) - 1;
} }
if (locationDefineOption.firstDataRow) { if (locationDefineOption.firstDataRow) {
firstDataRow = parseInt(locationDefineOption.firstDataRow as string, 10) - 1; dataStartRowIndex = parseInt(locationDefineOption.firstDataRow as string, 10) - 1;
} }
} }
@ -267,14 +267,14 @@ export async function execute(
const sheetData = (await sheet.getData(sheetName, 'FORMATTED_VALUE')) ?? []; const sheetData = (await sheet.getData(sheetName, 'FORMATTED_VALUE')) ?? [];
if (!sheetData[headerRow] && dataMode !== 'autoMapInputData') { if (!sheetData[keyRowIndex] && dataMode !== 'autoMapInputData') {
throw new NodeOperationError( throw new NodeOperationError(
this.getNode(), this.getNode(),
`Could not retrieve the column names from row ${headerRow + 1}`, `Could not retrieve the column names from row ${keyRowIndex + 1}`,
); );
} }
columnNames = sheetData[headerRow] ?? []; columnNames = sheetData[keyRowIndex] ?? [];
if (nodeVersion >= 4.4) { if (nodeVersion >= 4.4) {
const schema = this.getNodeParameter('columns.schema', 0) as ResourceMapperField[]; const schema = this.getNodeParameter('columns.schema', 0) as ResourceMapperField[];
@ -291,13 +291,13 @@ export async function execute(
// TODO: Add support for multiple columns to match on in the next overhaul // TODO: Add support for multiple columns to match on in the next overhaul
const keyIndex = columnNames.indexOf(columnsToMatchOn[0]); const keyIndex = columnNames.indexOf(columnsToMatchOn[0]);
const columnValues = await sheet.getColumnValues( const columnValuesList = await sheet.getColumnValues({
range, range,
keyIndex, keyIndex,
firstDataRow, dataStartRowIndex,
valueRenderMode, valueRenderMode,
sheetData, sheetData,
); });
const updateData: ISheetUpdateData[] = []; const updateData: ISheetUpdateData[] = [];
const appendData: IDataObject[] = []; const appendData: IDataObject[] = [];
@ -321,20 +321,20 @@ export async function execute(
for (let i = 0; i < items.length; i++) { for (let i = 0; i < items.length; i++) {
if (dataMode === 'nothing') continue; if (dataMode === 'nothing') continue;
const data: IDataObject[] = []; const inputData: IDataObject[] = [];
if (dataMode === 'autoMapInputData') { if (dataMode === 'autoMapInputData') {
const handlingExtraDataOption = (options.handlingExtraData as string) || 'insertInNewColumn'; const handlingExtraDataOption = (options.handlingExtraData as string) || 'insertInNewColumn';
if (handlingExtraDataOption === 'ignoreIt') { if (handlingExtraDataOption === 'ignoreIt') {
data.push(items[i].json); inputData.push(items[i].json);
} }
if (handlingExtraDataOption === 'error') { if (handlingExtraDataOption === 'error') {
Object.keys(items[i].json).forEach((key) => errorOnUnexpectedColumn(key, i)); Object.keys(items[i].json).forEach((key) => errorOnUnexpectedColumn(key, i));
data.push(items[i].json); inputData.push(items[i].json);
} }
if (handlingExtraDataOption === 'insertInNewColumn') { if (handlingExtraDataOption === 'insertInNewColumn') {
Object.keys(items[i].json).forEach(addNewColumn); Object.keys(items[i].json).forEach(addNewColumn);
data.push(items[i].json); inputData.push(items[i].json);
} }
} else { } else {
const valueToMatchOn = const valueToMatchOn =
@ -364,7 +364,7 @@ export async function execute(
return acc; return acc;
}, {} as IDataObject); }, {} as IDataObject);
fields[columnsToMatchOn[0]] = valueToMatchOn; fields[columnsToMatchOn[0]] = valueToMatchOn;
data.push(fields); inputData.push(fields);
} else { } else {
const mappingValues = this.getNodeParameter('columns.value', i) as IDataObject; const mappingValues = this.getNodeParameter('columns.value', i) as IDataObject;
if (Object.keys(mappingValues).length === 0) { if (Object.keys(mappingValues).length === 0) {
@ -379,7 +379,7 @@ export async function execute(
mappingValues[key] = ''; mappingValues[key] = '';
} }
}); });
data.push(mappingValues); inputData.push(mappingValues);
mappedValues.push(mappingValues); mappedValues.push(mappingValues);
} }
} }
@ -390,56 +390,60 @@ export async function execute(
sheetName, sheetName,
[newColumnNames], [newColumnNames],
(options.cellFormat as ValueInputOption) || cellFormatDefault(nodeVersion), (options.cellFormat as ValueInputOption) || cellFormatDefault(nodeVersion),
headerRow + 1, keyRowIndex + 1,
); );
columnNames = newColumnNames; columnNames = newColumnNames;
sheetData[headerRow] = newColumnNames; sheetData[keyRowIndex] = newColumnNames;
newColumns.clear(); newColumns.clear();
} }
const preparedData = await sheet.prepareDataForUpdateOrUpsert( const indexKey = columnsToMatchOn[0];
data,
columnsToMatchOn[0], const preparedData = await sheet.prepareDataForUpdateOrUpsert({
inputData,
indexKey,
range, range,
headerRow, keyRowIndex,
firstDataRow, dataStartRowIndex,
valueRenderMode, valueRenderMode,
true, upsert: true,
[columnNames.concat([...newColumns])], columnNamesList: [columnNames.concat([...newColumns])],
columnValues, columnValuesList,
); });
updateData.push(...preparedData.updateData); updateData.push(...preparedData.updateData);
appendData.push(...preparedData.appendData); appendData.push(...preparedData.appendData);
} }
const columnNamesList = [columnNames.concat([...newColumns])];
if (updateData.length) { if (updateData.length) {
await sheet.batchUpdate(updateData, valueInputMode); await sheet.batchUpdate(updateData, valueInputMode);
} }
if (appendData.length) { if (appendData.length) {
const lastRow = sheetData.length + 1; const lastRow = sheetData.length + 1;
const useAppend = options.useAppend as boolean;
if (options.useAppend) { if (options.useAppend) {
await sheet.appendSheetData( await sheet.appendSheetData({
appendData, inputData: appendData,
range, range,
headerRow + 1, keyRowIndex: keyRowIndex + 1,
valueInputMode, valueInputMode,
false, columnNamesList,
[columnNames.concat([...newColumns])],
lastRow, lastRow,
options.useAppend as boolean, useAppend,
); });
} else { } else {
await sheet.appendEmptyRowsOrColumns(sheetId, 1, 0); await sheet.appendEmptyRowsOrColumns(sheetId, 1, 0);
await sheet.appendSheetData( await sheet.appendSheetData({
appendData, inputData: appendData,
range, range,
headerRow + 1, keyRowIndex: keyRowIndex + 1,
valueInputMode, valueInputMode,
false, columnNamesList,
[columnNames.concat([...newColumns])],
lastRow, lastRow,
); });
} }
} }

View File

@ -202,10 +202,11 @@ export async function execute(
return []; return [];
} }
const { data, headerRow, firstDataRow } = prepareSheetData( const {
sheetData, data,
dataLocationOnSheetOptions, headerRow: keyRowIndex,
); firstDataRow: dataStartRowIndex,
} = prepareSheetData(sheetData, dataLocationOnSheetOptions);
let responseData = []; let responseData = [];
@ -215,6 +216,8 @@ export async function execute(
[], [],
) as ILookupValues[]; ) as ILookupValues[];
const inputData = data as string[][];
if (lookupValues.length) { if (lookupValues.length) {
const returnAllMatches = options.returnAllMatches === 'returnAllMatches' ? true : false; const returnAllMatches = options.returnAllMatches === 'returnAllMatches' ? true : false;
@ -235,16 +238,16 @@ export async function execute(
| 'AND' | 'AND'
| 'OR'; | 'OR';
responseData = await sheet.lookupValues( responseData = await sheet.lookupValues({
data as string[][], inputData,
headerRow, keyRowIndex,
firstDataRow, dataStartRowIndex,
lookupValues, lookupValues,
returnAllMatches, returnAllMatches,
combineFilters, combineFilters,
); });
} else { } else {
responseData = sheet.structureArrayDataByColumn(data as string[][], headerRow, firstDataRow); responseData = sheet.structureArrayDataByColumn(inputData, keyRowIndex, dataStartRowIndex);
} }
returnData.push( returnData.push(

View File

@ -237,15 +237,15 @@ export async function execute(
const locationDefineOptions = (options.locationDefine as IDataObject)?.values as IDataObject; const locationDefineOptions = (options.locationDefine as IDataObject)?.values as IDataObject;
let headerRow = 0; let keyRowIndex = 0;
let firstDataRow = 1; let dataStartRowIndex = 1;
if (locationDefineOptions) { if (locationDefineOptions) {
if (locationDefineOptions.headerRow) { if (locationDefineOptions.headerRow) {
headerRow = parseInt(locationDefineOptions.headerRow as string, 10) - 1; keyRowIndex = parseInt(locationDefineOptions.headerRow as string, 10) - 1;
} }
if (locationDefineOptions.firstDataRow) { if (locationDefineOptions.firstDataRow) {
firstDataRow = parseInt(locationDefineOptions.firstDataRow as string, 10) - 1; dataStartRowIndex = parseInt(locationDefineOptions.firstDataRow as string, 10) - 1;
} }
} }
@ -253,14 +253,14 @@ export async function execute(
const sheetData = await sheet.getData(sheetName, 'FORMATTED_VALUE'); const sheetData = await sheet.getData(sheetName, 'FORMATTED_VALUE');
if (sheetData?.[headerRow] === undefined) { if (sheetData?.[keyRowIndex] === undefined) {
throw new NodeOperationError( throw new NodeOperationError(
this.getNode(), this.getNode(),
`Could not retrieve the column names from row ${headerRow + 1}`, `Could not retrieve the column names from row ${keyRowIndex + 1}`,
); );
} }
columnNames = sheetData[headerRow]; columnNames = sheetData[keyRowIndex];
if (nodeVersion >= 4.4) { if (nodeVersion >= 4.4) {
const schema = this.getNodeParameter('columns.schema', 0) as ResourceMapperField[]; const schema = this.getNodeParameter('columns.schema', 0) as ResourceMapperField[];
@ -283,13 +283,13 @@ export async function execute(
const keyIndex = columnNames.indexOf(columnsToMatchOn[0]); const keyIndex = columnNames.indexOf(columnsToMatchOn[0]);
//not used when updating row //not used when updating row
const columnValues = await sheet.getColumnValues( const columnValuesList = await sheet.getColumnValues({
range, range,
keyIndex, keyIndex,
firstDataRow, dataStartRowIndex,
valueRenderMode, valueRenderMode,
sheetData, sheetData,
); });
const updateData: ISheetUpdateData[] = []; const updateData: ISheetUpdateData[] = [];
@ -313,20 +313,20 @@ export async function execute(
for (let i = 0; i < items.length; i++) { for (let i = 0; i < items.length; i++) {
if (dataMode === 'nothing') continue; if (dataMode === 'nothing') continue;
const data: IDataObject[] = []; const inputData: IDataObject[] = [];
if (dataMode === 'autoMapInputData') { if (dataMode === 'autoMapInputData') {
const handlingExtraDataOption = (options.handlingExtraData as string) || 'insertInNewColumn'; const handlingExtraDataOption = (options.handlingExtraData as string) || 'insertInNewColumn';
if (handlingExtraDataOption === 'ignoreIt') { if (handlingExtraDataOption === 'ignoreIt') {
data.push(items[i].json); inputData.push(items[i].json);
} }
if (handlingExtraDataOption === 'error' && columnsToMatchOn[0] !== 'row_number') { if (handlingExtraDataOption === 'error' && columnsToMatchOn[0] !== 'row_number') {
Object.keys(items[i].json).forEach((key) => errorOnUnexpectedColumn(key, i)); Object.keys(items[i].json).forEach((key) => errorOnUnexpectedColumn(key, i));
data.push(items[i].json); inputData.push(items[i].json);
} }
if (handlingExtraDataOption === 'insertInNewColumn' && columnsToMatchOn[0] !== 'row_number') { if (handlingExtraDataOption === 'insertInNewColumn' && columnsToMatchOn[0] !== 'row_number') {
Object.keys(items[i].json).forEach(addNewColumn); Object.keys(items[i].json).forEach(addNewColumn);
data.push(items[i].json); inputData.push(items[i].json);
} }
} else { } else {
const valueToMatchOn = const valueToMatchOn =
@ -360,7 +360,7 @@ export async function execute(
fields[columnsToMatchOn[0]] = valueToMatchOn; fields[columnsToMatchOn[0]] = valueToMatchOn;
data.push(fields); inputData.push(fields);
} else { } else {
const mappingValues = this.getNodeParameter('columns.value', i) as IDataObject; const mappingValues = this.getNodeParameter('columns.value', i) as IDataObject;
if (Object.keys(mappingValues).length === 0) { if (Object.keys(mappingValues).length === 0) {
@ -375,7 +375,7 @@ export async function execute(
mappingValues[key] = ''; mappingValues[key] = '';
} }
}); });
data.push(mappingValues); inputData.push(mappingValues);
mappedValues.push(mappingValues); mappedValues.push(mappingValues);
} }
} }
@ -386,29 +386,30 @@ export async function execute(
sheetName, sheetName,
[newColumnNames], [newColumnNames],
(options.cellFormat as ValueInputOption) || cellFormatDefault(nodeVersion), (options.cellFormat as ValueInputOption) || cellFormatDefault(nodeVersion),
headerRow + 1, keyRowIndex + 1,
); );
columnNames = newColumnNames; columnNames = newColumnNames;
newColumns.clear(); newColumns.clear();
} }
let preparedData; let preparedData;
const columnNamesList = [columnNames.concat([...newColumns])];
if (columnsToMatchOn[0] === 'row_number') { if (columnsToMatchOn[0] === 'row_number') {
preparedData = sheet.prepareDataForUpdatingByRowNumber(data, range, [ preparedData = sheet.prepareDataForUpdatingByRowNumber(inputData, range, columnNamesList);
columnNames.concat([...newColumns]),
]);
} else { } else {
preparedData = await sheet.prepareDataForUpdateOrUpsert( const indexKey = columnsToMatchOn[0];
data,
columnsToMatchOn[0], preparedData = await sheet.prepareDataForUpdateOrUpsert({
inputData,
indexKey,
range, range,
headerRow, keyRowIndex,
firstDataRow, dataStartRowIndex,
valueRenderMode, valueRenderMode,
false, columnNamesList,
[columnNames.concat([...newColumns])], columnValuesList,
columnValues, });
);
} }
updateData.push(...preparedData.updateData); updateData.push(...preparedData.updateData);

View File

@ -17,6 +17,16 @@ export const versionDescription: INodeTypeDescription = {
}, },
inputs: ['main'], inputs: ['main'],
outputs: ['main'], outputs: ['main'],
hints: [
{
message:
"Use the 'Use Append' option for greater efficiency if your sheet is uniformly formatted without gaps between columns or rows",
displayCondition:
'={{$parameter["operation"] === "append" && !$parameter["options"]["useAppend"]}}',
whenToDisplay: 'beforeExecution',
location: 'outputPane',
},
],
credentials: [ credentials: [
{ {
name: 'googleApi', name: 'googleApi',

View File

@ -380,16 +380,25 @@ export class GoogleSheet {
return keys; return keys;
} }
async appendSheetData( async appendSheetData({
inputData: IDataObject[], inputData,
range: string, range,
keyRowIndex: number, keyRowIndex,
valueInputMode: ValueInputOption, valueInputMode,
usePathForKeyRow: boolean, usePathForKeyRow,
columnNamesList?: string[][], columnNamesList,
lastRow?: number, lastRow,
useAppend?: boolean, useAppend,
): Promise<string[][]> { }: {
inputData: IDataObject[];
range: string;
keyRowIndex: number;
valueInputMode: ValueInputOption;
usePathForKeyRow?: boolean;
columnNamesList?: string[][];
lastRow?: number;
useAppend?: boolean;
}): Promise<string[][]> {
const data = await this.convertObjectArrayToSheetDataArray( const data = await this.convertObjectArrayToSheetDataArray(
inputData, inputData,
range, range,
@ -406,13 +415,19 @@ export class GoogleSheet {
return xlsxUtils.encode_col(columnIndex); return xlsxUtils.encode_col(columnIndex);
} }
async getColumnValues( async getColumnValues({
range: string, range,
keyIndex: number, keyIndex,
dataStartRowIndex: number, dataStartRowIndex,
valueRenderMode: ValueRenderOption, valueRenderMode,
sheetData?: string[][], sheetData,
): Promise<string[]> { }: {
range: string;
keyIndex: number;
dataStartRowIndex: number;
valueRenderMode: ValueRenderOption;
sheetData?: string[][];
}): Promise<string[]> {
let columnValuesList; let columnValuesList;
if (sheetData) { if (sheetData) {
columnValuesList = sheetData.slice(dataStartRowIndex - 1).map((row) => row[keyIndex]); columnValuesList = sheetData.slice(dataStartRowIndex - 1).map((row) => row[keyIndex]);
@ -448,17 +463,27 @@ export class GoogleSheet {
* @returns {Promise<string[][]>} * @returns {Promise<string[][]>}
* @memberof GoogleSheet * @memberof GoogleSheet
*/ */
async prepareDataForUpdateOrUpsert( async prepareDataForUpdateOrUpsert({
inputData: IDataObject[], inputData,
indexKey: string, indexKey,
range: string, range,
keyRowIndex: number, keyRowIndex,
dataStartRowIndex: number, dataStartRowIndex,
valueRenderMode: ValueRenderOption, valueRenderMode,
upsert = false, upsert = false,
columnNamesList?: string[][], columnNamesList,
columnValuesList?: string[], columnValuesList,
) { }: {
inputData: IDataObject[];
indexKey: string;
range: string;
keyRowIndex: number;
dataStartRowIndex: number;
valueRenderMode: ValueRenderOption;
upsert?: boolean;
columnNamesList?: string[][];
columnValuesList?: string[];
}) {
const decodedRange = this.getDecodedSheetRange(range); const decodedRange = this.getDecodedSheetRange(range);
// prettier-ignore // prettier-ignore
const keyRowRange = `${decodedRange.name}!${decodedRange.start?.column || ''}${keyRowIndex + 1}:${decodedRange.end?.column || ''}${keyRowIndex + 1}`; const keyRowRange = `${decodedRange.name}!${decodedRange.start?.column || ''}${keyRowIndex + 1}:${decodedRange.end?.column || ''}${keyRowIndex + 1}`;
@ -485,7 +510,7 @@ export class GoogleSheet {
const columnValues: Array<string | number> = const columnValues: Array<string | number> =
columnValuesList || columnValuesList ||
(await this.getColumnValues(range, keyIndex, dataStartRowIndex, valueRenderMode)); (await this.getColumnValues({ range, keyIndex, dataStartRowIndex, valueRenderMode }));
const updateData: ISheetUpdateData[] = []; const updateData: ISheetUpdateData[] = [];
const appendData: IDataObject[] = []; const appendData: IDataObject[] = [];
@ -620,14 +645,21 @@ export class GoogleSheet {
* @returns {Promise<IDataObject[]>} * @returns {Promise<IDataObject[]>}
* @memberof GoogleSheet * @memberof GoogleSheet
*/ */
async lookupValues( async lookupValues({
inputData: string[][], inputData,
keyRowIndex: number, keyRowIndex,
dataStartRowIndex: number, dataStartRowIndex,
lookupValues: ILookupValues[], lookupValues,
returnAllMatches?: boolean, returnAllMatches,
combineFilters: 'AND' | 'OR' = 'OR', combineFilters = 'OR',
): Promise<IDataObject[]> { }: {
inputData: string[][];
keyRowIndex: number;
dataStartRowIndex: number;
lookupValues: ILookupValues[];
returnAllMatches?: boolean;
combineFilters?: 'AND' | 'OR';
}): Promise<IDataObject[]> {
const keys: string[] = []; const keys: string[] = [];
if (keyRowIndex < 0 || dataStartRowIndex < keyRowIndex || keyRowIndex >= inputData.length) { if (keyRowIndex < 0 || dataStartRowIndex < keyRowIndex || keyRowIndex >= inputData.length) {
@ -740,7 +772,7 @@ export class GoogleSheet {
inputData: IDataObject[], inputData: IDataObject[],
range: string, range: string,
keyRowIndex: number, keyRowIndex: number,
usePathForKeyRow: boolean, usePathForKeyRow?: boolean,
columnNamesList?: string[][], columnNamesList?: string[][],
emptyValue: string | null = '', emptyValue: string | null = '',
): Promise<string[][]> { ): Promise<string[][]> {