From bbaa958c419fb1e3bd179a9351c13cd65b5c8b0a Mon Sep 17 00:00:00 2001
From: Philippe Serhal
Date: Tue, 1 Apr 2025 16:58:22 -0400
Subject: [PATCH 1/4] fix: actually populate auth `user` field
We were reading from the wrong property.
---
src/utils/build-info.ts | 3 +--
src/utils/gh-auth.ts | 5 +++--
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/src/utils/build-info.ts b/src/utils/build-info.ts
index 6edcabaec99..7eca80bb0e1 100644
--- a/src/utils/build-info.ts
+++ b/src/utils/build-info.ts
@@ -4,9 +4,8 @@ import fuzzy from 'fuzzy'
import inquirer from 'inquirer'
import type BaseCommand from '../commands/base-command.js'
-import type { DefaultConfig } from '../lib/build.js'
-
import { chalk, log } from './command-helpers.js'
+import type { DefaultConfig } from '../lib/build.js'
/**
* Filters the inquirer settings based on the input
diff --git a/src/utils/gh-auth.ts b/src/utils/gh-auth.ts
index 9c6b52ff7fa..ec5ee491352 100644
--- a/src/utils/gh-auth.ts
+++ b/src/utils/gh-auth.ts
@@ -105,8 +105,9 @@ const authWithToken = async (): Promise => {
}
const octokit = new Octokit({ auth: `token ${token}` })
- // @ts-expect-error -- XXX(serhalp): actual bug - fixed in stacked PR
- const { login: user } = await octokit.users.getAuthenticated()
+ const {
+ data: { login: user },
+ } = await octokit.users.getAuthenticated()
return { token, user, provider: 'github' }
}
From 66b24927c5119996973c8588bb2ad41a6317db1d Mon Sep 17 00:00:00 2001
From: Philippe Serhal
Date: Wed, 9 Apr 2025 08:55:45 -0400
Subject: [PATCH 2/4] build: fix suppressed eslint errors
---
eslint_temporary_suppressions.js | 11 -----------
src/commands/base-command.ts | 2 +-
src/utils/gh-auth.ts | 20 ++++++++++----------
3 files changed, 11 insertions(+), 22 deletions(-)
diff --git a/eslint_temporary_suppressions.js b/eslint_temporary_suppressions.js
index 3076d862193..618d1722ec8 100644
--- a/eslint_temporary_suppressions.js
+++ b/eslint_temporary_suppressions.js
@@ -952,17 +952,6 @@ export default [
'@typescript-eslint/restrict-template-expressions': 'off',
},
},
- {
- files: ['src/utils/gh-auth.ts'],
- rules: {
- '@typescript-eslint/no-unsafe-assignment': 'off',
- '@typescript-eslint/restrict-template-expressions': 'off',
- '@typescript-eslint/prefer-nullish-coalescing': 'off',
- '@typescript-eslint/no-unsafe-return': 'off',
- '@typescript-eslint/no-unsafe-call': 'off',
- '@typescript-eslint/no-unsafe-member-access': 'off',
- },
- },
{
files: ['src/utils/gitignore.ts'],
rules: {
diff --git a/src/commands/base-command.ts b/src/commands/base-command.ts
index 9637e1df2cd..482a4457505 100644
--- a/src/commands/base-command.ts
+++ b/src/commands/base-command.ts
@@ -401,7 +401,7 @@ export default class BaseCommand extends Command {
}
async expensivelyAuthenticate() {
- const webUI = process.env.NETLIFY_WEB_UI || 'https://app.netlify.com'
+ const webUI = process.env.NETLIFY_WEB_UI ?? 'https://app.netlify.com'
log(`Logging into your Netlify account...`)
// Create ticket for auth
diff --git a/src/utils/gh-auth.ts b/src/utils/gh-auth.ts
index ec5ee491352..7140e77fa8f 100644
--- a/src/utils/gh-auth.ts
+++ b/src/utils/gh-auth.ts
@@ -21,9 +21,9 @@ export interface Token {
const promptForAuthMethod = async () => {
const authChoiceNetlify = 'Authorize with GitHub through app.netlify.com'
const authChoiceToken = 'Authorize with a GitHub personal access token'
- const authChoices = [authChoiceNetlify, authChoiceToken]
+ const authChoices = [authChoiceNetlify, authChoiceToken] as const
- const { authMethod } = await inquirer.prompt([
+ const { authMethod } = (await inquirer.prompt([
{
type: 'list',
name: 'authMethod',
@@ -32,7 +32,7 @@ const promptForAuthMethod = async () => {
'What would you like to do?',
choices: authChoices,
},
- ])
+ ])) as { authMethod: typeof authChoices[number] }
return authMethod === authChoiceNetlify
}
@@ -53,7 +53,7 @@ export const authWithNetlify = async (): Promise => {
`${
"Logged in" +
"Logged in
You're now logged into Netlify CLI with your "
- }${parameters.get('provider')} credentials. Please close this window.
`,
+ }${parameters.get('provider') ?? ''} credentials. Please close this window.
`,
)
server.close()
return
@@ -70,9 +70,9 @@ export const authWithNetlify = async (): Promise => {
})
})
- const webUI = process.env.NETLIFY_WEB_UI || 'https://app.netlify.com'
+ const webUI = process.env.NETLIFY_WEB_UI ?? 'https://app.netlify.com'
const urlParams = new URLSearchParams({
- host: `http://localhost:${port}`,
+ host: `http://localhost:${port.toString()}`,
provider: 'github',
})
const url = `${webUI}/cli?${urlParams.toString()}`
@@ -82,15 +82,15 @@ export const authWithNetlify = async (): Promise => {
return deferredPromise
}
-const getPersonalAccessToken = async () => {
- const { token } = await inquirer.prompt([
+const getPersonalAccessToken = async (): Promise<{ token: string }> => {
+ const { token } = (await inquirer.prompt([
{
type: 'password',
name: 'token',
message: 'Your GitHub personal access token:',
- filter: (input) => input.trim(),
+ filter: (input: string) => input.trim(),
},
- ])
+ ])) as { token: string }
return { token }
}
From c264287d3f7ded1b3407872e49f50dfb34e8e55f Mon Sep 17 00:00:00 2001
From: Philippe Serhal
Date: Mon, 14 Apr 2025 17:32:32 -0400
Subject: [PATCH 3/4] fix: revert change of empty string `NETLIFY_WEB_UI`
handling
---
src/commands/base-command.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/commands/base-command.ts b/src/commands/base-command.ts
index 482a4457505..9637e1df2cd 100644
--- a/src/commands/base-command.ts
+++ b/src/commands/base-command.ts
@@ -401,7 +401,7 @@ export default class BaseCommand extends Command {
}
async expensivelyAuthenticate() {
- const webUI = process.env.NETLIFY_WEB_UI ?? 'https://app.netlify.com'
+ const webUI = process.env.NETLIFY_WEB_UI || 'https://app.netlify.com'
log(`Logging into your Netlify account...`)
// Create ticket for auth
From fa9d57c2552cafea1799a4de629df730ba1eecec Mon Sep 17 00:00:00 2001
From: Philippe Serhal
Date: Tue, 15 Apr 2025 11:53:06 -0400
Subject: [PATCH 4/4] refactor: use inquirer.prompt generic
---
src/commands/init/init.ts | 10 +++++-----
src/utils/gh-auth.ts | 8 ++++----
src/utils/init/config-manual.ts | 8 ++++----
src/utils/init/utils.ts | 8 ++++++--
4 files changed, 19 insertions(+), 15 deletions(-)
diff --git a/src/commands/init/init.ts b/src/commands/init/init.ts
index c2481b16264..a0968358ff3 100644
--- a/src/commands/init/init.ts
+++ b/src/commands/init/init.ts
@@ -114,14 +114,14 @@ git remote add origin https://github.com/YourUserName/RepoName.git
const NEW_SITE_NO_GIT = 'Yes, create and deploy site manually'
const NO_ABORT = 'No, I will connect this directory with GitHub first'
- const { noGitRemoteChoice } = (await inquirer.prompt([
+ const { noGitRemoteChoice } = await inquirer.prompt<{ noGitRemoteChoice: typeof NEW_SITE_NO_GIT | typeof NO_ABORT }>([
{
type: 'list',
name: 'noGitRemoteChoice',
message: 'Do you want to create a Netlify site without a git repository?',
choices: [NEW_SITE_NO_GIT, NO_ABORT],
},
- ])) as { noGitRemoteChoice: typeof NEW_SITE_NO_GIT | typeof NO_ABORT }
+ ])
if (noGitRemoteChoice === NEW_SITE_NO_GIT) {
return await createNewSiteAndExit({ state, command })
@@ -138,15 +138,15 @@ const createOrLinkSiteToRepo = async (command: BaseCommand) => {
const initializeOpts = [EXISTING_SITE, NEW_SITE] as const
- const { initChoice } = (await inquirer.prompt([
+ // TODO(serhalp): inquirer should infer the choice type here, but doesn't. Fix.
+ const { initChoice } = await inquirer.prompt<{ initChoice: typeof initializeOpts[number] }>([
{
type: 'list',
name: 'initChoice',
message: 'What would you like to do?',
choices: initializeOpts,
},
- // TODO(serhalp): inquirer should infer the choice type here, but doesn't. Fix.
- ])) as { initChoice: typeof initializeOpts[number] }
+ ])
// create site or search for one
if (initChoice === NEW_SITE) {
diff --git a/src/utils/gh-auth.ts b/src/utils/gh-auth.ts
index 7140e77fa8f..7d8c5d07b59 100644
--- a/src/utils/gh-auth.ts
+++ b/src/utils/gh-auth.ts
@@ -23,7 +23,7 @@ const promptForAuthMethod = async () => {
const authChoiceToken = 'Authorize with a GitHub personal access token'
const authChoices = [authChoiceNetlify, authChoiceToken] as const
- const { authMethod } = (await inquirer.prompt([
+ const { authMethod } = await inquirer.prompt<{ authMethod: typeof authChoices[number] }>([
{
type: 'list',
name: 'authMethod',
@@ -32,7 +32,7 @@ const promptForAuthMethod = async () => {
'What would you like to do?',
choices: authChoices,
},
- ])) as { authMethod: typeof authChoices[number] }
+ ])
return authMethod === authChoiceNetlify
}
@@ -83,14 +83,14 @@ export const authWithNetlify = async (): Promise => {
}
const getPersonalAccessToken = async (): Promise<{ token: string }> => {
- const { token } = (await inquirer.prompt([
+ const { token } = await inquirer.prompt<{ token: string }>([
{
type: 'password',
name: 'token',
message: 'Your GitHub personal access token:',
filter: (input: string) => input.trim(),
},
- ])) as { token: string }
+ ])
return { token }
}
diff --git a/src/utils/init/config-manual.ts b/src/utils/init/config-manual.ts
index 7ebdffd332e..0b1011b50c8 100644
--- a/src/utils/init/config-manual.ts
+++ b/src/utils/init/config-manual.ts
@@ -28,7 +28,7 @@ const addDeployKey = async (deployKey: DeployKey) => {
}
const getRepoPath = async ({ repoData }: { repoData: RepoData }): Promise => {
- const { repoPath } = (await inquirer.prompt([
+ const { repoPath } = await inquirer.prompt<{ repoPath: string }>([
{
type: 'input',
name: 'repoPath',
@@ -36,7 +36,7 @@ const getRepoPath = async ({ repoData }: { repoData: RepoData }): Promise (SSH_URL_REGEXP.test(url) ? true : 'The URL provided does not use the SSH protocol'),
},
- ])) as { repoPath: string }
+ ])
return repoPath
}
@@ -44,14 +44,14 @@ const getRepoPath = async ({ repoData }: { repoData: RepoData }): Promise => {
log('\nConfigure the following webhook for your repository:\n')
log(`\n${deployHook}\n\n`)
- const { deployHookAdded } = (await inquirer.prompt([
+ const { deployHookAdded } = await inquirer.prompt<{ deployHookAdded: boolean }>([
{
type: 'confirm',
name: 'deployHookAdded',
message: 'Continue?',
default: true,
},
- ])) as { deployHookAdded: boolean }
+ ])
return deployHookAdded
}
diff --git a/src/utils/init/utils.ts b/src/utils/init/utils.ts
index 95a39e33ae9..3d15fd02580 100644
--- a/src/utils/init/utils.ts
+++ b/src/utils/init/utils.ts
@@ -105,13 +105,17 @@ export const getBuildSettings = async ({
log()
}
- const { baseDir, buildCmd, buildDir } = (await inquirer.prompt(
+ const { baseDir, buildCmd, buildDir } = await inquirer.prompt<{
+ baseDir?: string | undefined
+ buildCmd: string
+ buildDir: string
+ }>(
getPromptInputs({
defaultBaseDir,
defaultBuildCmd,
defaultBuildDir,
}),
- )) as { baseDir?: string | undefined; buildCmd: string; buildDir: string }
+ )
const pluginsToInstall = recommendedPlugins.map((plugin) => ({ package: plugin }))
const normalizedBaseDir = baseDir ? normalizeBackslash(baseDir) : undefined