Skip to content

Commit 8f8b04f

Browse files
authored
Release v1.49.0 (#1136)
chore: new landing page refactor chore: set ioredis config to resend failed command chore: order excel single row output chore: allow lookup for blank cells in Excel actions chore: bump axios and multer fix: warn for unsaved changes on delete step fix: warn for unsaved changes on publish fix: remove deleted FormSG attachments from email step parameters fix: postman attachments selector
2 parents 3042376 + 28f5903 commit 8f8b04f

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

70 files changed

+1471
-1039
lines changed

package-lock.json

Lines changed: 12 additions & 12 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@
2424
"packages/*"
2525
]
2626
},
27+
"overrides": {
28+
"axios": "1.11.0"
29+
},
2730
"devDependencies": {
2831
"@eddeee888/gcg-typescript-resolver-files": "0.7.2",
2932
"@graphql-codegen/cli": "5.0.6",

packages/backend/package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141
"@taskforcesh/bullmq-pro": "7.7.1",
4242
"ajv-formats": "^2.1.1",
4343
"async-mutex": "0.4.0",
44-
"axios": "1.8.3",
44+
"axios": "1.11.0",
4545
"big.js": "6.2.1",
4646
"cookie-parser": "1.4.6",
4747
"copyfiles": "^2.4.1",
@@ -69,7 +69,7 @@
6969
"lottie-web": "5.12.2",
7070
"luxon": "2.5.2",
7171
"morgan": "^1.10.0",
72-
"multer": "2.0.1",
72+
"multer": "2.0.2",
7373
"nanoid": "3.3.8",
7474
"objection": "^3.0.0",
7575
"p-limit": "3.1.0",
@@ -108,5 +108,5 @@
108108
"tsconfig-paths": "^4.2.0",
109109
"type-fest": "4.10.3"
110110
},
111-
"version": "1.48.1"
111+
"version": "1.49.0"
112112
}

packages/backend/src/apps/m365-excel/__tests__/actions/get-table-rows.itest.ts

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,9 @@ describe('getTableRowsAction', () => {
8383
['non-matching', 'data1'],
8484
['test-value', 'data2'],
8585
['test-value', 'data3'],
86+
['', 'data4'],
87+
['row5', ''],
88+
['', 'data6'],
8689
],
8790
headerSheetRowIndex: 0,
8891
})
@@ -202,6 +205,56 @@ describe('getTableRowsAction', () => {
202205
expect(rowData[1].data[getHexEncodedColumnName('Column2')]).toBe('data3')
203206
})
204207

208+
it('should return matching rows when lookup value is empty', async () => {
209+
$.step.parameters.lookupValue = ''
210+
await getTableRowsAction.run($)
211+
212+
expect($.setActionItem).toHaveBeenCalledWith({
213+
raw: expect.objectContaining({
214+
rowsFound: 2,
215+
data: {
216+
columns: expect.arrayContaining([
217+
expect.objectContaining({
218+
id: getHexEncodedColumnName('Column1'),
219+
name: 'Column1',
220+
value: `data.rows.*.data.${getHexEncodedColumnName('Column1')}`,
221+
}),
222+
expect.objectContaining({
223+
id: getHexEncodedColumnName('Column2'),
224+
name: 'Column2',
225+
value: `data.rows.*.data.${getHexEncodedColumnName('Column2')}`,
226+
}),
227+
]),
228+
rows: expect.arrayContaining([
229+
expect.objectContaining({
230+
data: {
231+
[getHexEncodedColumnName('Column1')]: '',
232+
[getHexEncodedColumnName('Column2')]: 'data4',
233+
},
234+
}),
235+
expect.objectContaining({
236+
data: {
237+
[getHexEncodedColumnName('Column1')]: '',
238+
[getHexEncodedColumnName('Column2')]: 'data6',
239+
},
240+
}),
241+
]),
242+
inputSource: FOR_EACH_INPUT_SOURCE.M365_EXCEL,
243+
},
244+
}),
245+
})
246+
247+
// Verify the rowData contains the expected rows
248+
const call = ($.setActionItem as ReturnType<typeof vi.fn>).mock.calls[0][0]
249+
const rowData = call.raw.data.rows
250+
251+
expect(rowData).toHaveLength(2)
252+
expect(rowData[0].data[getHexEncodedColumnName('Column1')]).toBe('')
253+
expect(rowData[0].data[getHexEncodedColumnName('Column2')]).toBe('data4')
254+
expect(rowData[1].data[getHexEncodedColumnName('Column1')]).toBe('')
255+
expect(rowData[1].data[getHexEncodedColumnName('Column2')]).toBe('data6')
256+
})
257+
205258
it('should handle invalid parameters', async () => {
206259
$.step.parameters.fileId = ''
207260
await expect(getTableRowsAction.run($)).rejects.toThrow(StepError)

packages/backend/src/apps/m365-excel/actions/get-table-row/get-data-out-metadata.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,21 @@ async function getDataOutMetadata(
2121
return metadata
2222
}
2323

24+
// hide column array from the output, its only used to order the row data
25+
metadata.columns =
26+
dataOut?.columns?.map((column) => ({
27+
type: 'text',
28+
label: column,
29+
isHidden: true,
30+
})) || []
31+
2432
metadata.rowData = Object.create(null)
2533
for (const [key, datum] of Object.entries(dataOut.rowData)) {
2634
metadata.rowData[key] = {
2735
value: {
2836
type: 'text',
2937
label: datum.columnName,
38+
order: (dataOut?.columns?.indexOf(datum.columnName) ?? 0) + 1,
3039
},
3140
columnName: {
3241
isHidden: true,
@@ -57,5 +66,6 @@ export default getDataOutMetadata
5766
// value: '5',
5867
// },
5968
// },
60-
// sheetRowNumber: 3
69+
// sheetRowNumber: 3,
70+
// columns: ['Item', 'Unit Price'],
6171
// }

packages/backend/src/apps/m365-excel/actions/get-table-row/index.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,9 +104,9 @@ const action: IRawAction = {
104104
// weird (e.g. currency cells have a trailing space), and will lead to too
105105
// much user confusion.
106106
description:
107-
'Case sensitive and should not include units. E.g. $5.20 → 5.2',
107+
'Case sensitive and should not include units (e.g., $5.20 → 5.2). Leave blank to search for empty cells.',
108108
type: 'string' as const,
109-
required: true,
109+
required: false,
110110
variables: true,
111111
hiddenIf: {
112112
fieldKey: 'tableId',
@@ -174,6 +174,7 @@ const action: IRawAction = {
174174
columns,
175175
}),
176176
sheetRowNumber,
177+
columns,
177178
} satisfies DataOut,
178179
})
179180
},

packages/backend/src/apps/m365-excel/actions/get-table-row/schemas.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ export const parametersSchema = z.object({
1717
}),
1818
// * We don't trim as we want to match _exactly_ on the user's input.
1919
// * We allow empty strings to support optional form fields.
20-
lookupValue: z.string(),
20+
lookupValue: z.string().default(''),
2121
})
2222

2323
export const dataOutSchema = z.discriminatedUnion('foundRow', [
@@ -26,5 +26,7 @@ export const dataOutSchema = z.discriminatedUnion('foundRow', [
2626
foundRow: z.literal(true),
2727
rowData: hexEncodedRowRecordSchema,
2828
sheetRowNumber: z.number(),
29+
// optional for backward compatibility
30+
columns: z.array(z.string()).optional(),
2931
}),
3032
])

packages/backend/src/apps/m365-excel/actions/get-table-rows/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,9 +103,9 @@ const action: IRawAction = {
103103
// weird (e.g. currency cells have a trailing space), and will lead to too
104104
// much user confusion.
105105
description:
106-
'Case sensitive and should not include units. E.g. $5.20 → 5.2',
106+
'Case sensitive and should not include units (e.g., $5.20 → 5.2). Leave blank to search for empty cells.',
107107
type: 'string' as const,
108-
required: true,
108+
required: false,
109109
variables: true,
110110
},
111111
],

packages/backend/src/apps/m365-excel/actions/get-table-rows/schemas.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ export const parametersSchema = z.object({
1717
}),
1818
// * We don't trim as we want to match _exactly_ on the user's input.
1919
// * We allow empty strings to support optional form fields.
20-
lookupValue: z.string(),
20+
lookupValue: z.string().default(''),
2121
})
2222

2323
export const dataOutSchema = z.object({

packages/backend/src/config/redis.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ export const REDIS_DB_INDEX = {
1010
RATE_LIMIT: 1,
1111
PIPE_ERRORS: 2,
1212
APP_DATA: 3,
13-
GLOBAL_DATA: 4,
1413
}
1514

1615
function reconnectOnError(err: Error) {
@@ -19,7 +18,9 @@ function reconnectOnError(err: Error) {
1918
if (err.message.includes(targetError)) {
2019
// Only reconnect when the error contains "READONLY"
2120
// during node failover, this is thrown: 149: -READONLY You can't write against a read only replica.
22-
return true
21+
// Using reconnectOnError, we can force the connection to reconnect on this error in order to connect to the new master.
22+
// We return 2 so that ioredis will resend the failed command after reconnecting.
23+
return 2
2324
}
2425
return false
2526
}

0 commit comments

Comments
 (0)