diff --git a/src/commands/build/build.ts b/src/commands/build/build.ts index a7e839806f9..2ba657edd8d 100644 --- a/src/commands/build/build.ts +++ b/src/commands/build/build.ts @@ -1,4 +1,5 @@ import { OptionValues } from 'commander' +import type { NetlifyAPI } from 'netlify' import { getBuildOptions, runBuild } from '../../lib/build.js' import { detectFrameworkSettings } from '../../utils/build-info.js' @@ -23,8 +24,20 @@ export const checkOptions = ({ cachedConfig: { siteInfo = {} }, token }) => { } } -// @ts-expect-error TS(7006) FIXME: Parameter 'command' implicitly has an 'any' type. -const injectEnv = async function (command, { api, buildOptions, context, siteInfo }) { +// eslint-disable-next-line @typescript-eslint/no-explicit-any +type $FIXME = any + +export const injectEnv = async function ({ + api, + buildOptions, + context, + siteInfo, +}: { + api: NetlifyAPI + buildOptions: ReturnType + context: string + siteInfo: $FIXME +}) { const isUsingEnvelope = siteInfo && siteInfo.use_envelope const { env } = buildOptions.cachedConfig @@ -37,31 +50,32 @@ export const build = async (options: OptionValues, command: BaseCommand) => { const { cachedConfig, siteInfo } = command.netlify command.setAnalyticsPayload({ dry: options.dry }) // Retrieve Netlify Build options - // @ts-expect-error TS(2554) FIXME: Expected 1 arguments, but got 0. const [token] = await getToken() const settings = await detectFrameworkSettings(command, 'build') + if (!token) { + throw new Error('Could not find the access token. Please run netlify login.') + } + // override the build command with the detection result if no command is specified through the config if (!cachedConfig.config.build.command) { cachedConfig.config.build.command = settings?.buildCommand cachedConfig.config.build.commandOrigin = 'heuristics' } - const buildOptions = await getBuildOptions({ + const buildOptions = getBuildOptions({ cachedConfig, packagePath: command.workspacePackage, currentDir: command.workingDir, token, - // @ts-expect-error TS(2740) options, }) if (!options.offline) { checkOptions(buildOptions) - const { api, site } = command.netlify + const { api } = command.netlify const { context } = options - // @ts-expect-error TS(2345) FIXME: Argument of type '{ api: any; buildOptions: { cach... Remove this comment to see the full error message - await injectEnv(command, { api, buildOptions, context, site, siteInfo }) + await injectEnv({ api, buildOptions, context, siteInfo }) } const { exitCode } = await runBuild(buildOptions) diff --git a/src/commands/deploy/deploy.ts b/src/commands/deploy/deploy.ts index a4299b5ce07..102adbc9e42 100644 --- a/src/commands/deploy/deploy.ts +++ b/src/commands/deploy/deploy.ts @@ -6,6 +6,7 @@ import { OptionValues } from 'commander' import inquirer from 'inquirer' import isEmpty from 'lodash/isEmpty.js' import isObject from 'lodash/isObject.js' +import type { NetlifyAPI } from 'netlify' import { parseAllHeaders } from 'netlify-headers-parser' import { parseAllRedirects } from 'netlify-redirect-parser' import prettyjson from 'prettyjson' @@ -35,6 +36,7 @@ import { getEnvelopeEnv } from '../../utils/env/index.js' import { getFunctionsManifestPath, getInternalFunctionsDir } from '../../utils/functions/index.js' import openBrowser from '../../utils/open-browser.js' import BaseCommand from '../base-command.js' +import { checkOptions, injectEnv } from '../build/build.js' import { link } from '../link/link.js' import { sitesCreate } from '../sites/sites-create.js' @@ -428,7 +430,7 @@ const runDeploy = async ({ fnDir: functionDirectories, functionsConfig, // @ts-expect-error TS(2322) FIXME: Type '(event: any) => void' is not assignable to t... Remove this comment to see the full error message - statusCb: silent ? () => {} : deployProgressCb(), + statusCb: silent ? undefined : deployProgressCb(), deployTimeout, syncFileLimit: SYNC_FILE_LIMIT, // pass an existing deployId to update @@ -467,24 +469,35 @@ const runDeploy = async ({ } } -/** - * - * @param {object} config - * @param {*} config.cachedConfig - * @param {string} [config.packagePath] - * @param {*} config.deployHandler - * @param {string} config.currentDir - * @param {import('commander').OptionValues} config.options The options of the command - * @returns - */ -// @ts-expect-error TS(7031) FIXME: Binding element 'cachedConfig' implicitly has an '... Remove this comment to see the full error message -const handleBuild = async ({ cachedConfig, currentDir, deployHandler, options, packagePath }) => { +// eslint-disable-next-line @typescript-eslint/no-explicit-any +type $FIXME = any + +const handleBuild = async ({ + api, + cachedConfig, + currentDir, + deployHandler, + options, + packagePath, + siteInfo, +}: { + api: NetlifyAPI + packagePath: string + deployHandler?: $FIXME + options: OptionValues + currentDir: string + cachedConfig: $FIXME + siteInfo: $FIXME +}) => { if (!options.build) { return {} } - // @ts-expect-error TS(2554) FIXME: Expected 1 arguments, but got 0. const [token] = await getToken() - const resolvedOptions = await getBuildOptions({ + if (!token) { + throw new Error('Could not find the auth token. Please run netlify login.') + } + + const buildOptions = getBuildOptions({ cachedConfig, packagePath, token, @@ -492,7 +505,13 @@ const handleBuild = async ({ cachedConfig, currentDir, deployHandler, options, p currentDir, deployHandler, }) - const { configMutations, exitCode, newConfig } = await runBuild(resolvedOptions) + + if (!options.offline) { + checkOptions(buildOptions) + await injectEnv({ api, buildOptions, context: options.context, siteInfo }) + } + + const { configMutations, exitCode, newConfig } = await runBuild(buildOptions) if (exitCode !== 0) { exit(exitCode) } @@ -510,9 +529,9 @@ const bundleEdgeFunctions = async (options, command) => { // eslint-disable-next-line n/prefer-global/process, unicorn/prefer-set-has const argv = process.argv.slice(2) const statusCb = - options.silent || argv.includes('--json') || argv.includes('--silent') ? () => {} : deployProgressCb() + options.silent || argv.includes('--json') || argv.includes('--silent') ? undefined : deployProgressCb() - statusCb({ + statusCb?.({ type: 'edge-functions-bundling', msg: 'Bundling edge functions...\n', phase: 'start', @@ -527,7 +546,7 @@ const bundleEdgeFunctions = async (options, command) => { }) if (!success) { - statusCb({ + statusCb?.({ type: 'edge-functions-bundling', msg: 'Deploy aborted due to error while bundling edge functions', phase: 'error', @@ -536,7 +555,7 @@ const bundleEdgeFunctions = async (options, command) => { exit(severityCode) } - statusCb({ + statusCb?.({ type: 'edge-functions-bundling', msg: 'Finished bundling edge functions', phase: 'stop', @@ -767,6 +786,8 @@ export const deploy = async (options: OptionValues, command: BaseCommand) => { if (options.build) { await handleBuild({ + api: command.netlify.api, + siteInfo: command.netlify.siteInfo, packagePath: command.workspacePackage, cachedConfig: command.netlify.cachedConfig, currentDir: command.workingDir, diff --git a/src/commands/integration/deploy.ts b/src/commands/integration/deploy.ts index d9e4da3806d..fd7057ae704 100644 --- a/src/commands/integration/deploy.ts +++ b/src/commands/integration/deploy.ts @@ -396,15 +396,14 @@ export const getConfiguration = (workingDir) => { export const deploy = async (options: OptionValues, command: BaseCommand) => { const { api, cachedConfig, site, siteInfo } = command.netlify const { id: siteId } = site - // @ts-expect-error TS(2554) FIXME: Expected 1 arguments, but got 0. const [token] = await getToken() + if (!token) throw new Error('Could not find auth token. Please run netlify login.') const workingDir = resolve(command.workingDir) - const buildOptions = await getBuildOptions({ + const buildOptions = getBuildOptions({ cachedConfig, packagePath: command.workspacePackage, currentDir: command.workingDir, token, - // @ts-expect-error TS(2740) options, }) diff --git a/src/commands/login/login.ts b/src/commands/login/login.ts index 4917460434e..8cb1af10714 100644 --- a/src/commands/login/login.ts +++ b/src/commands/login/login.ts @@ -18,7 +18,6 @@ const msg = function (location) { } export const login = async (options: OptionValues, command: BaseCommand) => { - // @ts-expect-error TS(2554) FIXME: Expected 1 arguments, but got 0. const [accessToken, location] = await getToken() command.setAnalyticsPayload({ new: options.new }) diff --git a/src/commands/logout/logout.ts b/src/commands/logout/logout.ts index f6abe875b6d..03881179654 100644 --- a/src/commands/logout/logout.ts +++ b/src/commands/logout/logout.ts @@ -5,7 +5,6 @@ import { track } from '../../utils/telemetry/index.js' import BaseCommand from '../base-command.js' export const logout = async (options: OptionValues, command: BaseCommand) => { - // @ts-expect-error TS(2554) FIXME: Expected 1 arguments, but got 0. const [accessToken, location] = await getToken() if (!accessToken) { diff --git a/src/commands/status/status.ts b/src/commands/status/status.ts index 15cf6b745f5..4d247b90bfa 100644 --- a/src/commands/status/status.ts +++ b/src/commands/status/status.ts @@ -8,7 +8,6 @@ import BaseCommand from '../base-command.js' export const status = async (options: OptionValues, command: BaseCommand) => { const { api, globalConfig, site, siteInfo } = command.netlify const current = globalConfig.get('userId') - // @ts-expect-error TS(2554) FIXME: Expected 1 arguments, but got 0. const [accessToken] = await getToken() if (!accessToken) { @@ -54,7 +53,7 @@ export const status = async (options: OptionValues, command: BaseCommand) => { // @ts-expect-error TS(2339) FIXME: Property 'Teams' does not exist on type '{ Name: a... Remove this comment to see the full error message accountData.Teams = teamsData - // @ts-expect-error + // @ts-expect-error FIXME clean-deep has no types const cleanAccountData = clean(accountData) log(prettyjson.render(cleanAccountData)) diff --git a/src/lib/build.ts b/src/lib/build.ts index 7291ad3a699..124b115bfc8 100644 --- a/src/lib/build.ts +++ b/src/lib/build.ts @@ -2,6 +2,7 @@ import fs from 'fs' import process from 'process' import build from '@netlify/build' +import type { OptionValues } from 'commander' // @ts-expect-error TS(7016) FIXME: Could not find a declaration file for module 'toml... Remove this comment to see the full error message import tomlify from 'tomlify-j0.4' @@ -10,6 +11,20 @@ import { isFeatureFlagEnabled } from '../utils/feature-flags.js' import { getBootstrapURL } from './edge-functions/bootstrap.js' import { featureFlags as edgeFunctionsFeatureFlags } from './edge-functions/consts.js' +// eslint-disable-next-line @typescript-eslint/no-explicit-any +type $FIXME = any + +interface EventHandler { + handler: $FIXME + description: string +} + +const getFeatureFlagsFromSiteInfo = (siteInfo: $FIXME): Record => ({ + ...siteInfo.feature_flags, + // see https://github.com/netlify/pod-dev-foundations/issues/581#issuecomment-1731022753 + zisi_golang_use_al2: isFeatureFlagEnabled('cli_golang_use_al2', siteInfo), +}) + /** * The buildConfig + a missing cachedConfig * @typedef BuildConfig @@ -19,32 +34,22 @@ import { featureFlags as edgeFunctionsFeatureFlags } from './edge-functions/cons // We have already resolved the configuration using `@netlify/config` // This is stored as `netlify.cachedConfig` and can be passed to // `@netlify/build --cachedConfig`. -/** - * - * @param {object} config - * @param {*} config.cachedConfig - * @param {string} [config.packagePath] - * @param {string} config.currentDir - * @param {string} config.token - * @param {import('commander').OptionValues} config.options - * @param {*} config.deployHandler - * @returns {BuildConfig} - */ export const getBuildOptions = ({ - // @ts-expect-error TS(7031) FIXME: Binding element 'cachedConfig' implicitly has an '... Remove this comment to see the full error message cachedConfig, - // @ts-expect-error TS(7031) FIXME: Binding element 'currentDir' implicitly has an 'an... Remove this comment to see the full error message currentDir, - // @ts-expect-error TS(7031) FIXME: Binding element 'deployHandler' implicitly has an ... Remove this comment to see the full error message deployHandler, - // @ts-expect-error TS(7031) FIXME: Binding element 'context' implicitly has an 'any' ... Remove this comment to see the full error message options: { context, cwd, debug, dry, json, offline, silent }, - // @ts-expect-error TS(7031) FIXME: Binding element 'packagePath' implicitly has an 'a... Remove this comment to see the full error message packagePath, - // @ts-expect-error TS(7031) FIXME: Binding element 'token' implicitly has an 'any' ty... Remove this comment to see the full error message token, +}: { + options: OptionValues + cachedConfig: $FIXME + currentDir: string + deployHandler?: $FIXME + packagePath: string + token: string }) => { - const eventHandlers = { + const eventHandlers: { onEnd: EventHandler; onPostBuild?: EventHandler } = { onEnd: { // @ts-expect-error TS(7031) FIXME: Binding element 'netlifyConfig' implicitly has an ... Remove this comment to see the full error message handler: ({ netlifyConfig }) => { @@ -62,7 +67,6 @@ export const getBuildOptions = ({ } if (deployHandler) { - // @ts-expect-error TS(2339) FIXME: Property 'onPostBuild' does not exist on type '{ o... Remove this comment to see the full error message eventHandlers.onPostBuild = { handler: deployHandler, description: 'Deploy Site', @@ -90,27 +94,10 @@ export const getBuildOptions = ({ }, eventHandlers, edgeFunctionsBootstrapURL: getBootstrapURL(), - } + } as const } -/** - * @param {*} siteInfo - * @returns {Record} - */ -// @ts-expect-error TS(7006) FIXME: Parameter 'siteInfo' implicitly has an 'any' type. -const getFeatureFlagsFromSiteInfo = (siteInfo) => ({ - ...siteInfo.feature_flags, - // see https://github.com/netlify/pod-dev-foundations/issues/581#issuecomment-1731022753 - zisi_golang_use_al2: isFeatureFlagEnabled('cli_golang_use_al2', siteInfo), -}) - -/** - * run the build command - * @param {BuildConfig} options - * @returns - */ -// @ts-expect-error TS(7006) FIXME: Parameter 'options' implicitly has an 'any' type. -export const runBuild = async (options) => { +export const runBuild = async (options: ReturnType) => { // If netlify NETLIFY_API_URL is set we need to pass this information to @netlify/build // TODO don't use testOpts, but add real properties to do this. if (process.env.NETLIFY_API_URL) { @@ -119,6 +106,7 @@ export const runBuild = async (options) => { scheme: apiUrl.protocol.slice(0, -1), host: apiUrl.host, } + // @ts-expect-error TS(2554) FIXME options = { ...options, testOpts } } diff --git a/src/utils/command-helpers.ts b/src/utils/command-helpers.ts index ee53421d7f8..9266812945f 100644 --- a/src/utils/command-helpers.ts +++ b/src/utils/command-helpers.ts @@ -5,9 +5,11 @@ import { format, inspect } from 'util' import { Chalk } from 'chalk' import chokidar from 'chokidar' +import type { Option } from 'commander' import decache from 'decache' import WSL from 'is-wsl' import debounce from 'lodash/debounce.js' +import type { NetlifyAPI } from 'netlify' import terminalLink from 'terminal-link' import { clearSpinner, startSpinner } from '../lib/spinner.js' @@ -66,33 +68,19 @@ export const BANG = process.platform === 'win32' ? '»' : '›' /** * Sorts two options so that the base flags are at the bottom of the list - * @param {import('commander').Option} optionA - * @param {import('commander').Option} optionB - * @returns {number} - * @example - * options.sort(sortOptions) */ -// @ts-expect-error TS(7006) FIXME: Parameter 'optionA' implicitly has an 'any' type. -export const sortOptions = (optionA, optionB) => { +export const sortOptions = (optionA: Option, optionB: Option) => { // base flags should be always at the bottom - if (BASE_FLAGS.has(optionA.long) || BASE_FLAGS.has(optionB.long)) { + if (BASE_FLAGS.has(optionA.long!) || BASE_FLAGS.has(optionB.long!)) { return -1 } - return optionA.long.localeCompare(optionB.long) + return optionA.long!.localeCompare(optionB.long!) } // Poll Token timeout 5 Minutes const TOKEN_TIMEOUT = 3e5 -/** - * - * @param {object} config - * @param {import('netlify').NetlifyAPI} config.api - * @param {object} config.ticket - * @returns - */ -// @ts-expect-error TS(7031) FIXME: Binding element 'api' implicitly has an 'any' type... Remove this comment to see the full error message -export const pollForToken = async ({ api, ticket }) => { +export const pollForToken = async ({ api, ticket }: { api: NetlifyAPI; ticket: object }) => { const spinner = startSpinner({ text: 'Waiting for authorization...' }) try { const accessToken = await api.getAccessToken(ticket, { timeout: TOKEN_TIMEOUT }) @@ -121,11 +109,11 @@ export const pollForToken = async ({ api, ticket }) => { /** * Get a netlify token - * @param {string} [tokenFromOptions] optional token from the provided --auth options - * @returns {Promise<[null|string, 'flag' | 'env' |'config' |'not found']>} + * @param tokenFromOptions optional token from the provided --auth options */ -// @ts-expect-error TS(7006) FIXME: Parameter 'tokenFromOptions' implicitly has an 'an... Remove this comment to see the full error message -export const getToken = async (tokenFromOptions) => { +export const getToken = async ( + tokenFromOptions?: string, +): Promise<[null | string, 'flag' | 'env' | 'config' | 'not found']> => { // 1. First honor command flag --auth if (tokenFromOptions) { return [tokenFromOptions, 'flag']