Skip to content

Commit

Permalink
refactor: refactor typescript types from build-info and related parts (
Browse files Browse the repository at this point in the history
  • Loading branch information
lukasholzer authored Dec 20, 2023
1 parent 6014df5 commit 9eb8dc0
Show file tree
Hide file tree
Showing 19 changed files with 57 additions and 134 deletions.
4 changes: 0 additions & 4 deletions src/commands/functions/functions-create.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ import { fileExistsAsync } from '../../lib/fs.js'
import { getAddons, getCurrentAddon, getSiteData } from '../../utils/addons/prepare.js'
import { NETLIFYDEVERR, NETLIFYDEVLOG, NETLIFYDEVWARN, chalk, error, log } from '../../utils/command-helpers.js'
import { getDotEnvVariables, injectEnvVariables } from '../../utils/dev.js'
// @ts-expect-error TS(7034) FIXME: Variable 'execa' implicitly has type 'any' in some... Remove this comment to see the full error message
import execa from '../../utils/execa.js'
import { readRepoURL, validateRepoURL } from '../../utils/read-repo-url.js'
import BaseCommand from '../base-command.js'
Expand Down Expand Up @@ -441,7 +440,6 @@ const installDeps = async ({ functionPackageJson, functionPath, functionsDir })
// of keeping that file in the function directory and running `npm install`
// from there.
if (!sitePackageJson) {
// @ts-expect-error TS(7005) FIXME: Variable 'execa' implicitly has an 'any' type.
await execa('npm', ['i', ...npmInstallFlags], { cwd: functionPath })

return
Expand All @@ -453,12 +451,10 @@ const installDeps = async ({ functionPackageJson, functionPath, functionsDir })
const npmInstallPath = path.dirname(sitePackageJson)

if (dependencies.length !== 0) {
// @ts-expect-error TS(7005) FIXME: Variable 'execa' implicitly has an 'any' type.
await execa('npm', ['i', ...dependencies, '--save', ...npmInstallFlags], { cwd: npmInstallPath })
}

if (devDependencies.length !== 0) {
// @ts-expect-error TS(7005) FIXME: Variable 'execa' implicitly has an 'any' type.
await execa('npm', ['i', ...devDependencies, '--save-dev', ...npmInstallFlags], { cwd: npmInstallPath })
}

Expand Down
2 changes: 0 additions & 2 deletions src/commands/lm/lm-setup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { OptionValues } from 'commander'
import { Listr } from 'listr2'

import { error } from '../../utils/command-helpers.js'
// @ts-expect-error TS(7034) FIXME: Variable 'execa' implicitly has type 'any' in some... Remove this comment to see the full error message
import execa from '../../utils/execa.js'
import { installPlatform } from '../../utils/lm/install.js'
import { checkHelperVersion } from '../../utils/lm/requirements.js'
Expand Down Expand Up @@ -53,7 +52,6 @@ const configureLFSURL = async function (siteId, api) {
const siteInfo = await api.getSite({ siteId })
const url = `https://${siteInfo.id_domain}/.netlify/large-media`

// @ts-expect-error TS(7005) FIXME: Variable 'execa' implicitly has an 'any' type.
return execa('git', ['config', '-f', '.lfsconfig', 'lfs.url', url])
}

Expand Down
2 changes: 0 additions & 2 deletions src/commands/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import { closest } from 'fastest-levenshtein'
import inquirer from 'inquirer'

import { BANG, chalk, error, exit, log, NETLIFY_CYAN, USER_AGENT, warn } from '../utils/command-helpers.js'
// @ts-expect-error TS(7034) FIXME: Variable 'execa' implicitly has type 'any' in some... Remove this comment to see the full error message
import execa from '../utils/execa.js'
import getGlobalConfig from '../utils/get-global-config.js'
import getPackageJson from '../utils/get-package-json.js'
Expand Down Expand Up @@ -177,7 +176,6 @@ const mainCommand = async function (options, command) {
error(`Run ${NETLIFY_CYAN(`${command.name()} help`)} for a list of available commands.`)
}

// @ts-expect-error TS(7005) FIXME: Variable 'execa' implicitly has an 'any' type.
await execa(process.argv[0], [process.argv[1], suggestion], { stdio: 'inherit' })
}

Expand Down
5 changes: 1 addition & 4 deletions src/commands/sites/sites-create-template.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import parseGitHubUrl from 'parse-github-url'
import { render } from 'prettyjson'

import { chalk, error, getTerminalLink, log, logJson, warn } from '../../utils/command-helpers.js'
// @ts-expect-error TS(7034) FIXME: Variable 'execa' implicitly has type 'any' in some... Remove this comment to see the full error message
import execa from '../../utils/execa.js'
import getRepoData from '../../utils/get-repo-data.js'
import { getGitHubToken } from '../../utils/init/config-github.js'
Expand Down Expand Up @@ -117,7 +116,7 @@ export const sitesCreateTemplate = async (repository: string, options: OptionVal

const { name: nameFlag } = options
let site
let repoResp
let repoResp: Awaited<ReturnType<typeof createRepo>>

// Allow the user to reenter site name if selected one isn't available
// @ts-expect-error TS(7006) FIXME: Parameter 'name' implicitly has an 'any' type.
Expand Down Expand Up @@ -207,9 +206,7 @@ export const sitesCreateTemplate = async (repository: string, options: OptionVal
})
if (cloneConfirm) {
log()
// @ts-expect-error TS(7005) FIXME: Variable 'execa' implicitly has an 'any' type.
await execa('git', ['clone', repoResp.clone_url, `${repoResp.name}`])
// @ts-expect-error TS(2532) FIXME: Object is possibly 'undefined'.
log(`🚀 Repository cloned successfully. You can find it under the ${chalk.magenta(repoResp.name)} folder`)
}

Expand Down
2 changes: 0 additions & 2 deletions src/lib/exec-fetcher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import { fetchLatest, fetchVersion, newerVersion, updateAvailable } from 'gh-rel
import isExe from 'isexe'

import { NETLIFYDEVWARN, error, getTerminalLink, log } from '../utils/command-helpers.js'
// @ts-expect-error TS(7034) FIXME: Variable 'execa' implicitly has type 'any' in some... Remove this comment to see the full error message
import execa from '../utils/execa.js'

const isWindows = () => process.platform === 'win32'
Expand Down Expand Up @@ -58,7 +57,6 @@ export const shouldFetchLatestVersion = async ({
return true
}

// @ts-expect-error TS(7005) FIXME: Variable 'execa' implicitly has an 'any' type.
const { stdout } = await execa(execPath, execArgs)

if (!stdout) {
Expand Down
4 changes: 1 addition & 3 deletions src/lib/functions/local-proxy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { stdout } from 'process'
// @ts-expect-error TS(7016) FIXME: Could not find a declaration file for module '@net... Remove this comment to see the full error message
import { getBinaryPath as getFunctionsProxyPath } from '@netlify/local-functions-proxy'

// @ts-expect-error TS(7034) FIXME: Variable 'execa' implicitly has type 'any' in some... Remove this comment to see the full error message
import execa from '../../utils/execa.js'

// @ts-expect-error TS(7031) FIXME: Binding element 'binaryPath' implicitly has an 'an... Remove this comment to see the full error message
Expand Down Expand Up @@ -39,10 +38,9 @@ export const runFunctionsProxy = ({ binaryPath, context, directory, event, name,
'--timeout',
`${timeout}s`,
]
// @ts-expect-error TS(7005) FIXME: Variable 'execa' implicitly has an 'any' type.
const proxyProcess = execa(functionsProxyPath, parameters)

proxyProcess.stderr.pipe(stdout)
proxyProcess.stderr?.pipe(stdout)

return proxyProcess
}
3 changes: 0 additions & 3 deletions src/lib/functions/runtimes/go/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { platform } from 'process'

import { temporaryFile } from 'tempy'

// @ts-expect-error TS(7034) FIXME: Variable 'execa' implicitly has type 'any' in some... Remove this comment to see the full error message
import execa from '../../../../utils/execa.js'
import { runFunctionsProxy } from '../../local-proxy.js'

Expand All @@ -14,7 +13,6 @@ export const name = 'go'
// @ts-expect-error TS(7031) FIXME: Binding element 'binaryPath' implicitly has an 'an... Remove this comment to see the full error message
const build = async ({ binaryPath, functionDirectory }) => {
try {
// @ts-expect-error TS(7005) FIXME: Variable 'execa' implicitly has an 'any' type.
await execa('go', ['build', '-o', binaryPath], { cwd: functionDirectory })

return { binaryPath, srcFiles: [functionDirectory] }
Expand All @@ -34,7 +32,6 @@ const build = async ({ binaryPath, functionDirectory }) => {
// @ts-expect-error TS(7031) FIXME: Binding element 'cwd' implicitly has an 'any' type... Remove this comment to see the full error message
const checkGoInstallation = async ({ cwd }) => {
try {
// @ts-expect-error TS(7005) FIXME: Variable 'execa' implicitly has an 'any' type.
await execa('go', ['version'], { cwd })

return true
Expand Down
2 changes: 0 additions & 2 deletions src/lib/functions/runtimes/js/builders/netlify-lambda.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { resolve } from 'path'

import { program } from 'commander'

// @ts-expect-error TS(7034) FIXME: Variable 'execa' implicitly has type 'any' in some... Remove this comment to see the full error message
import execa from '../../../../../utils/execa.js'
import { fileExistsAsync } from '../../../../fs.js'
import { memoizedBuild } from '../../../memoized-build.js'
Expand Down Expand Up @@ -36,7 +35,6 @@ export const detectNetlifyLambda = async function ({ packageJson } = {}) {
const srcFiles = [resolve(functionDirectories[0])]

const yarnExists = await fileExistsAsync('yarn.lock')
// @ts-expect-error TS(7005) FIXME: Variable 'execa' implicitly has an 'any' type.
const buildCommand = () => execa(yarnExists ? 'yarn' : 'npm', ['run', key])

return {
Expand Down
2 changes: 0 additions & 2 deletions src/lib/functions/runtimes/rust/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import { platform } from 'process'
import { findUp } from 'find-up'
import toml from 'toml'

// @ts-expect-error TS(7034) FIXME: Variable 'execa' implicitly has type 'any' in some... Remove this comment to see the full error message
import execa from '../../../../utils/execa.js'
import { SERVE_FUNCTIONS_FOLDER } from '../../../../utils/functions/functions.js'
import { getPathInProject } from '../../../settings.js'
Expand All @@ -24,7 +23,6 @@ const build = async ({ func }) => {
const binaryName = `${crateName}${isWindows ? '.exe' : ''}`
const binaryPath = join(targetDirectory, 'debug', binaryName)

// @ts-expect-error TS(7005) FIXME: Variable 'execa' implicitly has an 'any' type.
await execa('cargo', ['build', '--target-dir', targetDirectory], {
cwd: functionDirectory,
})
Expand Down
5 changes: 2 additions & 3 deletions src/utils/banner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@ import boxen from 'boxen'

import { chalk, log, NETLIFYDEVLOG } from './command-helpers.js'

// @ts-expect-error TS(7031) FIXME: Binding element 'url' implicitly has an 'any' type... Remove this comment to see the full error message
export const printBanner = ({ url }) => {
const banner = chalk.bold(`${NETLIFYDEVLOG} Server now ready on ${url}`)
export const printBanner = (options: { url: string }): void => {
const banner = chalk.bold(`${NETLIFYDEVLOG} Server now ready on ${options.url}`)

log(
boxen(banner, {
Expand Down
84 changes: 36 additions & 48 deletions src/utils/build-info.ts
Original file line number Diff line number Diff line change
@@ -1,36 +1,32 @@
import { Settings } from '@netlify/build-info'
import fuzzy from 'fuzzy'
import inquirer from 'inquirer'

import BaseCommand from '../commands/base-command.js'

import { chalk, log } from './command-helpers.js'

/**
* Filters the inquirer settings based on the input
* @param {ReturnType<typeof formatSettingsArrForInquirer>} scriptInquirerOptions
* @param {string} input
*/
// @ts-expect-error TS(7006) FIXME: Parameter 'scriptInquirerOptions' implicitly has a... Remove this comment to see the full error message
const filterSettings = function (scriptInquirerOptions, input) {
// @ts-expect-error TS(7006) FIXME: Parameter 'scriptInquirerOption' implicitly has an... Remove this comment to see the full error message
const filterSettings = function (
scriptInquirerOptions: ReturnType<typeof formatSettingsArrForInquirer>,
input: string,
) {
const filterOptions = scriptInquirerOptions.map((scriptInquirerOption) => scriptInquirerOption.name)
// TODO: remove once https://github.com/sindresorhus/eslint-plugin-unicorn/issues/1394 is fixed
// eslint-disable-next-line unicorn/no-array-method-this-argument
const filteredSettings = fuzzy.filter(input, filterOptions)
const filteredSettingNames = new Set(
filteredSettings.map((filteredSetting) => (input ? filteredSetting.string : filteredSetting)),
)
// @ts-expect-error TS(7006) FIXME: Parameter 't' implicitly has an 'any' type.
return scriptInquirerOptions.filter((t) => filteredSettingNames.has(t.name))
}

/** @typedef {import('@netlify/build-info').Settings} Settings */

/**
* @param {Settings[]} settings
* @param {'dev' | 'build'} type The type of command (dev or build)
* Formats the settings to present it as an array for the inquirer input so that it can choose one
*/
// @ts-expect-error TS(7006) FIXME: Parameter 'settings' implicitly has an 'any' type.
const formatSettingsArrForInquirer = function (settings, type = 'dev') {
// @ts-expect-error TS(7006) FIXME: Parameter 'setting' implicitly has an 'any' type.
const formatSettingsArrForInquirer = function (settings: Settings[], type = 'dev') {
return settings.map((setting) => {
const cmd = type === 'dev' ? setting.devCommand : setting.buildCommand
return {
Expand All @@ -42,31 +38,46 @@ const formatSettingsArrForInquirer = function (settings, type = 'dev') {
}

/**
* Uses @netlify/build-info to detect the dev settings and port based on the framework
* Detects and filters the build setting for a project and a command
*/
export async function detectBuildSettings(command: BaseCommand): Promise<Settings[]> {
const { project, workspacePackage } = command
const buildSettings = await project.getBuildSettings(project.workspace ? workspacePackage : '')
return buildSettings
.filter((setting) => {
if (project.workspace && project.relativeBaseDirectory && setting.packagePath) {
return project.relativeBaseDirectory.startsWith(setting.packagePath)
}
return true
})
.filter((setting) => setting.devCommand)
}

/**
* Uses `@netlify/build-info` to detect the dev settings and port based on the framework
* and the build system that is used.
* @param {import('../commands/base-command.js').default} command
* @param {'dev' | 'build'} type The type of command (dev or build)
* @returns {Promise<Settings | undefined>}
* @param command The base command
* @param type The type of command (dev or build)
*/
// @ts-expect-error TS(7006) FIXME: Parameter 'command' implicitly has an 'any' type.
export const detectFrameworkSettings = async (command, type = 'dev') => {
export const detectFrameworkSettings = async (
command: BaseCommand,
type: 'dev' | 'build' = 'dev',
): Promise<Settings | undefined> => {
const { relConfigFilePath } = command.netlify
const settings = await detectBuildSettings(command)
if (settings.length === 1) {
return settings[0]
}

if (settings.length > 1) {
/** multiple matching detectors, make the user choose */
// multiple matching detectors, make the user choose
const scriptInquirerOptions = formatSettingsArrForInquirer(settings, type)
/** @type {{chosenSettings: Settings}} */
const { chosenSettings } = await inquirer.prompt({
const { chosenSettings } = await inquirer.prompt<{ chosenSettings: Settings }>({
name: 'chosenSettings',
message: `Multiple possible ${type} commands found`,
// @ts-expect-error TS(2769) FIXME: No overload matches this call.
// @ts-expect-error is not known by the types as it uses the autocomplete plugin
type: 'autocomplete',
// @ts-expect-error TS(7006) FIXME: Parameter '_' implicitly has an 'any' type.
source(/** @type {string} */ _, input = '') {
source(_: string, input = '') {
if (!input) return scriptInquirerOptions
// only show filtered results
return filterSettings(scriptInquirerOptions, input)
Expand All @@ -86,26 +97,3 @@ command = "${chosenSettings.devCommand}"
return chosenSettings
}
}

/**
* Detects and filters the build setting for a project and a command
* @param {import('../commands/base-command.js').default} command
*/
// @ts-expect-error TS(7006) FIXME: Parameter 'command' implicitly has an 'any' type.
export const detectBuildSettings = async (command) => {
const { project, workspacePackage } = command
const buildSettings = await project.getBuildSettings(project.workspace ? workspacePackage : '')
return (
buildSettings
// @ts-expect-error TS(7006) FIXME: Parameter 'setting' implicitly has an 'any' type.
.filter((setting) => {
if (project.workspace && project.relativeBaseDirectory && setting.packagePath) {
return project.relativeBaseDirectory.startsWith(setting.packagePath)
}

return true
})
// @ts-expect-error TS(7006) FIXME: Parameter 'setting' implicitly has an 'any' type.
.filter((setting) => setting.devCommand)
)
}
7 changes: 2 additions & 5 deletions src/utils/execa.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,10 @@ import execaLib from 'execa'

// This is a thin layer on top of `execa` that allows consumers to provide an
// alternative path to the module location, making it easier to mock its logic
// in tests (see `tests/utils/mock-execa.js`).
// in tests (see `tests/utils/moc

/**
* @type {import('execa')}
*/
// eslint-disable-next-line import/no-mutable-exports
let execa
let execa: typeof execaLib

if (env.NETLIFY_CLI_EXECA_PATH) {
const execaMock = await import(env.NETLIFY_CLI_EXECA_PATH)
Expand Down
9 changes: 2 additions & 7 deletions src/utils/feature-flags.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,9 @@
* Instead, we return that the feature flag is enabled if it isn't
* specifically set to false in the response
* @param {*} siteInfo
* @param {string} flagName
*
* @returns {boolean}
*/
// @ts-expect-error TS(7006) FIXME: Parameter 'flagName' implicitly has an 'any' type.
export const isFeatureFlagEnabled = (flagName, siteInfo) => {
if (siteInfo.feature_flags && siteInfo.feature_flags[flagName] !== false) {
return true
}
return false
}
export const isFeatureFlagEnabled = (flagName: string, siteInfo): boolean =>
Boolean(siteInfo.feature_flags && siteInfo.feature_flags[flagName] !== false)
17 changes: 5 additions & 12 deletions src/utils/init/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import cleanDeep from 'clean-deep'
import inquirer from 'inquirer'

import BaseCommand from '../../commands/base-command.js'
import { $TSFixMe } from '../../commands/types.js'
import { fileExistsAsync } from '../../lib/fs.js'
import { normalizeBackslash } from '../../lib/path.js'
import { detectBuildSettings } from '../build-info.js'
Expand Down Expand Up @@ -41,9 +42,8 @@ export const getPluginsToAutoInstall = (
[] as string[],
)
}
/**
*/
const normalizeSettings = (settings: Settings, config: NetlifyConfig, command: BaseCommand) => {

const normalizeSettings = (settings: Partial<Settings>, config: NetlifyConfig, command: BaseCommand) => {
const plugins = getPluginsToAutoInstall(command, settings.plugins_from_config_file, settings.plugins_recommended)
const recommendedPlugins = getRecommendPlugins(plugins, config)

Expand Down Expand Up @@ -94,18 +94,11 @@ const getPromptInputs = ({ defaultBaseDir, defaultBuildCmd, defaultBuildDir }) =
return inputs.filter(Boolean)
}

/**
* @param {object} param0
* @param {*} param0.config
* @param {import('../../commands/base-command.js').default} param0.command
*/
// @ts-expect-error TS(7031) FIXME: Binding element 'command' implicitly has an 'any' ... Remove this comment to see the full error message
export const getBuildSettings = async ({ command, config }) => {
export const getBuildSettings = async ({ command, config }: { command: BaseCommand; config: $TSFixMe }) => {
const settings = await detectBuildSettings(command)
// TODO: add prompt for asking to choose the build command
/** @type {Partial<import('@netlify/build-info').Settings>} */
// eslint-disable-next-line unicorn/explicit-length-check
const setting = settings.length > 0 ? settings[0] : {}
const setting: Partial<Settings> = settings.length > 0 ? settings[0] : {}
const { defaultBaseDir, defaultBuildCmd, defaultBuildDir, defaultFunctionsDir, recommendedPlugins } =
await normalizeSettings(setting, config, command)

Expand Down
Loading

1 comment on commit 9eb8dc0

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📊 Benchmark results

  • Dependency count: 1,399
  • Package size: 405 MB
  • Number of ts-expect-error directives: 1,231

Please sign in to comment.