Skip to content

Commit

Permalink
chore: fix some more types
Browse files Browse the repository at this point in the history
  • Loading branch information
Skn0tt committed Dec 14, 2023
1 parent e2536db commit 455040f
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 103 deletions.
154 changes: 57 additions & 97 deletions src/utils/detect-server-settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { readFile } from 'fs/promises'
import { EOL } from 'os'
import { dirname, relative, resolve } from 'path'

import { getFramework, getSettings } from '@netlify/build-info'
import { Project, Settings, getFramework, getSettings } from '@netlify/build-info'
import { OptionValues } from 'commander'
import getPort from 'get-port'

Expand All @@ -13,23 +13,15 @@ import { detectFrameworkSettings } from './build-info.js'
import { NETLIFYDEVWARN, chalk, log } from './command-helpers.js'
import { acquirePort } from './dev.js'
import { getPluginsToAutoInstall } from './init/utils.js'
import { ServerSettings } from './types.js'
import { BaseServerSettings, ServerSettings } from './types.js'

/** @param {string} str */
// @ts-expect-error TS(7006) FIXME: Parameter 'str' implicitly has an 'any' type.
const formatProperty = (str) => chalk.magenta(`'${str}'`)
/** @param {string} str */
// @ts-expect-error TS(7006) FIXME: Parameter 'str' implicitly has an 'any' type.
const formatValue = (str) => chalk.green(`'${str}'`)
const formatProperty = (str: string) => chalk.magenta(`'${str}'`)
const formatValue = (str: string) => chalk.green(`'${str}'`)

/**
* @param {object} options
* @param {string} options.keyFile
* @param {string} options.certFile
* @returns {Promise<{ key: string, cert: string, keyFilePath: string, certFilePath: string }>}
*/
// @ts-expect-error TS(7006) FIXME: Parameter 'options' implicitly has an 'any' type.
const readHttpsSettings = async (options) => {
const readHttpsSettings = async (options: {
keyFile: string
certFile: string
}): Promise<{ key: string; cert: string; keyFilePath: string; certFilePath: string }> => {
if (typeof options !== 'object' || !options.keyFile || !options.certFile) {
throw new TypeError(
`https options should be an object with ${formatProperty('keyFile')} and ${formatProperty(
Expand Down Expand Up @@ -60,12 +52,8 @@ const readHttpsSettings = async (options) => {

/**
* Validates a property inside the devConfig to be of a given type
* @param {import('../commands/dev/types.js').DevConfig} devConfig The devConfig
* @param {keyof import('../commands/dev/types.js').DevConfig} property The property to validate
* @param {'string' | 'number'} type The type it should have
*/
// @ts-expect-error TS(7006) FIXME: Parameter 'devConfig' implicitly has an 'any' type... Remove this comment to see the full error message
function validateProperty(devConfig, property, type) {
function validateProperty(devConfig: DevConfig, property: keyof DevConfig, type: 'string' | 'number') {
if (devConfig[property] && typeof devConfig[property] !== type) {
const formattedProperty = formatProperty(property)
throw new TypeError(
Expand All @@ -74,13 +62,7 @@ function validateProperty(devConfig, property, type) {
}
}

/**
*
* @param {object} config
* @param {import('../commands/dev/types.js').DevConfig} config.devConfig
*/
// @ts-expect-error TS(7031) FIXME: Binding element 'devConfig' implicitly has an 'any... Remove this comment to see the full error message
const validateFrameworkConfig = ({ devConfig }) => {
const validateFrameworkConfig = ({ devConfig }: { devConfig: DevConfig }) => {
validateProperty(devConfig, 'command', 'string')
validateProperty(devConfig, 'port', 'number')
validateProperty(devConfig, 'targetPort', 'number')
Expand All @@ -94,13 +76,7 @@ const validateFrameworkConfig = ({ devConfig }) => {
}
}

/**
* @param {object} config
* @param {import('../commands/dev/types.js').DevConfig} config.devConfig
* @param {number=} config.detectedPort
*/
// @ts-expect-error TS(7031) FIXME: Binding element 'detectedPort' implicitly has an '... Remove this comment to see the full error message
const validateConfiguredPort = ({ detectedPort, devConfig }) => {
const validateConfiguredPort = ({ detectedPort, devConfig }: { detectedPort?: number; devConfig: DevConfig }) => {
if (devConfig.port && devConfig.port === detectedPort) {
const formattedPort = formatProperty('port')
throw new Error(
Expand All @@ -114,23 +90,15 @@ const DEFAULT_STATIC_PORT = 3999

/**
* Logs a message that it was unable to determine the dist directory and falls back to the workingDir
* @param {string} workingDir
*/
// @ts-expect-error TS(7006) FIXME: Parameter 'workingDir' implicitly has an 'any' typ... Remove this comment to see the full error message
const getDefaultDist = (workingDir) => {
const getDefaultDist = (workingDir: string) => {
log(`${NETLIFYDEVWARN} Unable to determine public folder to serve files from. Using current working directory`)
log(`${NETLIFYDEVWARN} Setup a netlify.toml file with a [dev] section to specify your dev server settings.`)
log(`${NETLIFYDEVWARN} See docs at: https://cli.netlify.com/netlify-dev#project-detection`)
return workingDir
}

/**
* @param {object} config
* @param {import('../commands/dev/types.js').DevConfig} config.devConfig
* @returns {Promise<number>}
*/
// @ts-expect-error TS(7031) FIXME: Binding element 'devConfig' implicitly has an 'any... Remove this comment to see the full error message
const getStaticServerPort = async ({ devConfig }) => {
const getStaticServerPort = async ({ devConfig }: { devConfig: DevConfig }): Promise<number> => {
const port = await acquirePort({
configuredPort: devConfig.staticServerPort,
defaultPort: DEFAULT_STATIC_PORT,
Expand All @@ -140,16 +108,15 @@ const getStaticServerPort = async ({ devConfig }) => {
return port
}

/**
*
* @param {object} config
* @param {import('../commands/dev/types.js').DevConfig} config.devConfig
* @param {import('commander').OptionValues} config.flags
* @param {string} config.workingDir
* @returns {Promise<Omit<import('./types.js').BaseServerSettings, 'command'> & {command?: string}>}
*/
// @ts-expect-error TS(7031) FIXME: Binding element 'devConfig' implicitly has an 'any... Remove this comment to see the full error message
const handleStaticServer = async ({ devConfig, flags, workingDir }) => {
const handleStaticServer = async ({
devConfig,
flags,
workingDir,
}: {
devConfig: DevConfig
flags: OptionValues
workingDir: string
}): Promise<Omit<BaseServerSettings, 'command'> & { command?: string }> => {
validateProperty(devConfig, 'staticServerPort', 'number')

if (flags.dir) {
Expand Down Expand Up @@ -184,11 +151,8 @@ const handleStaticServer = async ({ devConfig, flags, workingDir }) => {

/**
* Retrieves the settings from a framework
* @param {import('@netlify/build-info').Settings} [settings]
* @returns {import('./types.js').BaseServerSettings | undefined}
*/
// @ts-expect-error TS(7006) FIXME: Parameter 'settings' implicitly has an 'any' type.
const getSettingsFromDetectedSettings = (settings) => {
const getSettingsFromDetectedSettings = (settings: Settings): BaseServerSettings | undefined => {
if (!settings) {
return
}
Expand All @@ -204,21 +168,18 @@ const getSettingsFromDetectedSettings = (settings) => {
}
}

/**
* @param {import('../commands/dev/types.js').DevConfig} devConfig
*/
// @ts-expect-error TS(7006) FIXME: Parameter 'devConfig' implicitly has an 'any' type... Remove this comment to see the full error message
const hasCommandAndTargetPort = (devConfig) => devConfig.command && devConfig.targetPort
const hasCommandAndTargetPort = (devConfig: DevConfig) => devConfig.command && devConfig.targetPort

/**
* Creates settings for the custom framework
* @param {object} config
* @param {import('../commands/dev/types.js').DevConfig} config.devConfig
* @param {string} config.workingDir
* @returns {import('./types.js').BaseServerSettings}
*/
// @ts-expect-error TS(7031) FIXME: Binding element 'devConfig' implicitly has an 'any... Remove this comment to see the full error message
const handleCustomFramework = ({ devConfig, workingDir }) => {
const handleCustomFramework = ({
devConfig,
workingDir,
}: {
devConfig: DevConfig
workingDir: string
}): BaseServerSettings => {
if (!hasCommandAndTargetPort(devConfig)) {
throw new Error(
`${formatProperty('command')} and ${formatProperty('targetPort')} properties are required when ${formatProperty(
Expand All @@ -237,47 +198,46 @@ const handleCustomFramework = ({ devConfig, workingDir }) => {

/**
* Merges the framework settings with the devConfig
* @param {object} config
* @param {import('../commands/dev/types.js').DevConfig} config.devConfig
* @param {string} config.workingDir
* @param {Partial<import('./types.js').BaseServerSettings>=} config.frameworkSettings
*/
// @ts-expect-error TS(7031) FIXME: Binding element 'devConfig' implicitly has an 'any... Remove this comment to see the full error message
const mergeSettings = async ({ devConfig, frameworkSettings = {}, workingDir }) => {
// @ts-expect-error TS(2339) FIXME: Property 'command' does not exist on type '{}'.
const mergeSettings = async ({
devConfig,
frameworkSettings = {},
workingDir,
}: {
devConfig: DevConfig
frameworkSettings?: BaseServerSettings
workingDir: string
}) => {
const command = devConfig.command || frameworkSettings.command
// @ts-expect-error TS(2339) FIXME: Property 'frameworkPort' does not exist on type '{... Remove this comment to see the full error message
const frameworkPort = devConfig.targetPort || frameworkSettings.frameworkPort
// if the framework doesn't start a server, we use a static one
const useStaticServer = !(command && frameworkPort)
return {
// @ts-expect-error TS(2339) FIXME: Property 'baseDirectory' does not exist on type '{... Remove this comment to see the full error message
baseDirectory: devConfig.base || frameworkSettings.baseDirectory,
command,
frameworkPort: useStaticServer ? await getStaticServerPort({ devConfig }) : frameworkPort,
// @ts-expect-error TS(2339) FIXME: Property 'dist' does not exist on type '{}'.
dist: devConfig.publish || frameworkSettings.dist || getDefaultDist(workingDir),
// @ts-expect-error TS(2339) FIXME: Property 'framework' does not exist on type '{}'.
framework: frameworkSettings.framework,
// @ts-expect-error TS(2339) FIXME: Property 'env' does not exist on type '{}'.
env: frameworkSettings.env,
// @ts-expect-error TS(2339) FIXME: Property 'pollingStrategies' does not exist on typ... Remove this comment to see the full error message
pollingStrategies: frameworkSettings.pollingStrategies || [],
useStaticServer,
}
}

/**
* Handles a forced framework and retrieves the settings for it
* @param {object} config
* @param {import('../commands/dev/types.js').DevConfig} config.devConfig
* @param {import('@netlify/build-info').Project} config.project
* @param {string} config.workingDir
* @param {string=} config.workspacePackage
* @returns {Promise<import('./types.js').BaseServerSettings>}
*/
// @ts-expect-error TS(7031) FIXME: Binding element 'devConfig' implicitly has an 'any... Remove this comment to see the full error message
const handleForcedFramework = async ({ devConfig, project, workingDir, workspacePackage }) => {
const handleForcedFramework = async ({
devConfig,
project,
workingDir,
workspacePackage,
}: {
devConfig: DevConfig
project: Project
workingDir: string
workspacePackage?: string
}): Promise<BaseServerSettings> => {
// this throws if `devConfig.framework` is not a supported framework
const framework = await getFramework(devConfig.framework, project)
const settings = await getSettings(framework, project, workspacePackage || '')
Expand All @@ -289,7 +249,11 @@ const handleForcedFramework = async ({ devConfig, project, workingDir, workspace
* Get the server settings based on the flags and the devConfig
*/

const detectServerSettings = async (devConfig: DevConfig, flags: OptionValues, command: BaseCommand): Promise<ServerSettings> => {
const detectServerSettings = async (
devConfig: DevConfig,
flags: OptionValues,
command: BaseCommand,
): Promise<ServerSettings> => {
validateProperty(devConfig, 'framework', 'string')

/** @type {Partial<import('./types.js').BaseServerSettings>} */
Expand Down Expand Up @@ -356,12 +320,9 @@ const detectServerSettings = async (devConfig: DevConfig, flags: OptionValues, c
/**
* Returns a copy of the provided config with any plugins provided by the
* server settings
* @param {*} config
* @param {Partial<import('./types.js').ServerSettings>} settings
* @returns {*} Modified config
*/
// @ts-expect-error TS(7006) FIXME: Parameter 'config' implicitly has an 'any' type.
export const getConfigWithPlugins = (config, settings) => {
export const getConfigWithPlugins = (config, settings: ServerSettings) => {
if (!settings.plugins) {
return config
}
Expand All @@ -374,7 +335,6 @@ export const getConfigWithPlugins = (config, settings) => {
// @ts-expect-error TS(7006) FIXME: Parameter 'plugin' implicitly has an 'any' type.
const existingPluginNames = new Set(existingPlugins.map((plugin) => plugin.package))
const newPlugins = settings.plugins
// @ts-expect-error TS(7006) FIXME: Parameter 'pluginName' implicitly has an 'any' typ... Remove this comment to see the full error message
.map((pluginName) => {
if (existingPluginNames.has(pluginName)) {
return
Expand Down
8 changes: 2 additions & 6 deletions src/utils/init/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,12 @@ const pluginsToAlwaysInstall = new Set(['@netlify/plugin-nextjs'])

/**
* Retrieve a list of plugins to auto install
* @param {string[]=} pluginsInstalled
* @param {string[]=} pluginsRecommended
* @returns
*/
export const getPluginsToAutoInstall = (pluginsInstalled = [], pluginsRecommended = []) =>
export const getPluginsToAutoInstall = (pluginsInstalled: string[] = [], pluginsRecommended: string[] = []) =>
pluginsRecommended.reduce(
(acc, plugin) =>
pluginsInstalled.includes(plugin) && !pluginsToAlwaysInstall.has(plugin) ? acc : [...acc, plugin],

/** @type {string[]} */ [],
[] as string[],
)

/**
Expand Down

0 comments on commit 455040f

Please sign in to comment.