From 8c3e89887c2440b2c31436e97bd23f538518fb6b Mon Sep 17 00:00:00 2001
From: donpetry-bot <281750570+donpetry-bot@users.noreply.github.com>
Date: Tue, 21 Jul 2026 19:50:43 +0000
Subject: [PATCH 1/3] =?UTF-8?q?feat:=20implement=20issue=20#428=20?=
=?UTF-8?q?=E2=80=94=20SonarCloud:=20JavaScript/TypeScript=20code=20qualit?=
=?UTF-8?q?y?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
deploy/index.html | 47 ++++++++++---------
deploy/tests/ui.spec.js | 8 +++-
gas-installer/Index.html | 8 ++--
gas-installer/src/index.js | 7 ++-
scripts/check-coverage.js | 8 ++--
src/calendar-to-briefing-doc/src/index.js | 10 ++--
.../tests/index.test.js | 37 +++++----------
src/calendar-to-sheets/src/index.js | 9 ++--
src/deploy/index.js | 2 +-
src/gas-utils.js | 16 +++----
src/gmail-to-drive-by-labels/src/index.js | 14 +++---
.../tests/code.test.js | 16 +++++--
.../tests/gas-utils.test.js | 11 +++++
test-utils/mocks.js | 6 +--
test-utils/setup.js | 2 +-
15 files changed, 104 insertions(+), 97 deletions(-)
diff --git a/deploy/index.html b/deploy/index.html
index 1fac2f82..2703d3f2 100644
--- a/deploy/index.html
+++ b/deploy/index.html
@@ -651,7 +651,6 @@
3 Configure your scripts
} catch {
// best-effort; ignore storage errors
}
- const safeId = escapeHtml(scriptId)
const section = document.getElementById('setup-section-' + scriptId)
if (section) {
section.innerHTML = `⏱ Trigger previously activated.
`
@@ -667,7 +666,7 @@ 3 Configure your scripts
* to activate the hourly trigger.
*/
function buildSetupSource(triggerFn) {
- if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(triggerFn)) {
+ if (!/^[a-zA-Z_]\w*$/.test(triggerFn)) {
throw new Error(
'Invalid trigger function name: ' + JSON.stringify(triggerFn)
)
@@ -1189,14 +1188,11 @@ 3 Configure your scripts
'At approximately ' +
'' +
Array.from({ length: 24 }, (_, h) => {
- const label =
- h === 0
- ? '12 AM'
- : h < 12
- ? h + ' AM'
- : h === 12
- ? '12 PM'
- : h - 12 + ' PM'
+ let label
+ if (h === 0) label = '12 AM'
+ else if (h < 12) label = h + ' AM'
+ else if (h === 12) label = '12 PM'
+ else label = h - 12 + ' PM'
return (
'3Configure your scripts
fields.email ? [fields.email] : []
)
const subject = JSON.stringify(fields.subject || 'Weekly Briefing')
- const lookahead = parseInt(fields.lookaheadDays, 10) || 7
+ const lookahead = Number.parseInt(fields.lookaheadDays, 10) || 7
const freq = JSON.stringify(fields.frequency || 'weekly')
const day = JSON.stringify(fields.triggerDay || 'MONDAY')
- const hour = parseInt(fields.triggerHour, 10) || 7
- const interval = parseInt(fields.triggerInterval, 10) || 1
+ const hour = Number.parseInt(fields.triggerHour, 10) || 7
+ const interval = Number.parseInt(fields.triggerInterval, 10) || 1
let scheduleLines =
' scheduleFrequency: ' +
freq +
@@ -1675,11 +1671,11 @@ 3 Configure your scripts
function escapeHtml(str) {
return String(str == null ? '' : str)
- .replace(/&/g, '&')
- .replace(//g, '>')
- .replace(/"/g, '"')
- .replace(/'/g, ''')
+ .replaceAll('&', '&')
+ .replaceAll('<', '<')
+ .replaceAll('>', '>')
+ .replaceAll('"', '"')
+ .replaceAll("'", ''')
}
/**
@@ -1975,9 +1971,13 @@ 3 Configure your scripts
})
.join('')
+ const deployHeadline =
+ deployedProjects.length === 1
+ ? 'Script deployed!'
+ : `${deployedProjects.length} scripts deployed!`
showStatus(
'ok',
- `✅ ${deployedProjects.length === 1 ? 'Script deployed!' : `${deployedProjects.length} scripts deployed!`} ` +
+ `✅ ${deployHeadline} ` +
`` +
`Now configure each script below, then activate the trigger. ` +
projectLinksHtml
@@ -2047,7 +2047,7 @@ 3 Configure your scripts
headers: {
Authorization: `Bearer ${accessToken}`,
'Content-Type': 'application/json',
- ...(options.headers || {}),
+ ...options.headers,
},
})
if (!res.ok) {
@@ -2062,8 +2062,11 @@ 3 Configure your scripts
? `${json.error.message} — ${JSON.stringify(json.error.details)}`
: json.error.message
}
- } catch (_) {
- /* ignore parse errors */
+ } catch (parseError) {
+ console.debug(
+ 'apiFetch: response body was not valid JSON',
+ parseError
+ )
}
const err = new Error(message)
err.httpStatus = res.status
diff --git a/deploy/tests/ui.spec.js b/deploy/tests/ui.spec.js
index 8001ba55..fb0f3222 100644
--- a/deploy/tests/ui.spec.js
+++ b/deploy/tests/ui.spec.js
@@ -272,9 +272,13 @@ test.describe('deploy index.html', () => {
test('Step 3 stays hidden after sign-in when no projects in Drive', async ({
page,
}) => {
+ // Default mock returns empty files array; wait for the Drive lookup to
+ // actually complete rather than sleeping for a fixed interval.
+ const driveLookup = page.waitForResponse((resp) =>
+ resp.url().includes('drive/v3/files')
+ )
await signIn(page)
- // Default mock returns empty files array
- await page.waitForTimeout(500)
+ await driveLookup
await expect(page.locator('#step3-card')).toBeHidden()
})
diff --git a/gas-installer/Index.html b/gas-installer/Index.html
index 84f1b3b0..5276cc6e 100644
--- a/gas-installer/Index.html
+++ b/gas-installer/Index.html
@@ -371,10 +371,10 @@ 2 Name your project
function escapeHtml(str) {
return String(str)
- .replace(/&/g, '&')
- .replace(//g, '>')
- .replace(/"/g, '"')
+ .replaceAll('&', '&')
+ .replaceAll('<', '<')
+ .replaceAll('>', '>')
+ .replaceAll('"', '"')
}