chore: convert some server files to TypeScript to progressivly migrate (#32828)

This commit is contained in:
Bill Glesias
2025-10-27 20:03:46 -04:00
committed by GitHub
parent 6439042dfb
commit 4ea36d4d8d
24 changed files with 151 additions and 174 deletions
@@ -1,33 +1,38 @@
const _write = process.stdout.write
// @ts-expect-error - process.log is not defined in the type system
const _log = process.log
const restore = function () {
export const restore = function () {
// restore to the originals
process.stdout.write = _write
// @ts-expect-error
process.log = _log
}
const stdout = function () {
const logs = []
export const stdout = function () {
const logs: string[] = []
// lazily backup write to enable injection
const { write } = process.stdout
// @ts-expect-error
const { log } = process
// electron adds a new process.log
// method for windows instead of process.stdout.write
// https://github.com/cypress-io/cypress/issues/977
if (log) {
process.log = function (str) {
// @ts-expect-error
process.log = function (str: string) {
logs.push(str)
return log.apply(this, arguments)
}
}
process.stdout.write = function (str) {
process.stdout.write = function (str: string) {
logs.push(str)
// @ts-expect-error
return write.apply(this, arguments)
}
@@ -41,9 +46,3 @@ const stdout = function () {
restore,
}
}
module.exports = {
stdout,
restore,
}
+21 -20
View File
@@ -1,25 +1,26 @@
import { cache } from './cache'
import type { Cohort } from '@packages/types'
const debug = require('debug')('cypress:server:cohorts')
import debugModule from 'debug'
const debug = debugModule('cypress:server:cohorts')
export = {
get: (): Promise<Record<string, Cohort>> => {
debug('Get cohorts')
export const get = async (): Promise<Record<string, Cohort>> => {
debug('Get cohorts')
return cache.getCohorts()
},
getByName: (name: string): Promise<Cohort> => {
debug('Get cohort name:', name)
return cache.getCohorts().then((cohorts) => {
debug('Get cohort returning:', cohorts[name])
return cohorts[name]
})
},
set: (cohort: Cohort) => {
debug('Set cohort', cohort)
return cache.insertCohort(cohort)
},
return cache.getCohorts()
}
export const getByName = async (name: string): Promise<Cohort> => {
debug('Get cohort name:', name)
return cache.getCohorts().then((cohorts) => {
debug('Get cohort returning:', cohorts[name])
return cohorts[name]
})
}
export const set = async (cohort: Cohort): Promise<void> => {
debug('Set cohort', cohort)
return cache.insertCohort(cohort)
}
+3 -3
View File
@@ -1,6 +1,6 @@
import _ from 'lodash'
import path from 'path'
import cwd from '../cwd'
import { getCwd } from '../cwd'
import Debug from 'debug'
import { escapeFilenameInUrl } from '../util/escape_filename'
import { getCtx } from '@packages/data-context'
@@ -15,7 +15,7 @@ export = {
async handleIframe (req: any, res: any, config: Cfg, remoteStates: RemoteStates, extraOptions: any) {
const test = req.params[0]
const iframePath: string = cwd('lib', 'html', 'iframe.html')
const iframePath: string = getCwd('lib', 'html', 'iframe.html')
const specFilter = _.get(extraOptions, 'specFilter')
debug('handle iframe %o', { test, specFilter, config })
@@ -59,7 +59,7 @@ export = {
},
async handleCrossOriginIframe (req: any, res: any, config: Cfg) {
const iframePath: string = cwd('lib', 'html', 'spec-bridge-iframe.html')
const iframePath: string = getCwd('lib', 'html', 'spec-bridge-iframe.html')
const documentDomainInjection = DocumentDomainInjection.InjectionBehavior(config)
const superDomain = documentDomainInjection.shouldInjectDocumentDomain(req.proxiedUrl) ?
documentDomainInjection.getHostname(req.proxiedUrl) :
-7
View File
@@ -1,7 +0,0 @@
const path = require('path')
const serverPath = path.join(__dirname, '..')
module.exports = (...args) => {
return path.join(serverPath, ...args)
}
+5
View File
@@ -0,0 +1,5 @@
import path from 'path'
export const getCwd = (...args: string[]) => {
return path.join(__dirname, '..', ...args)
}
+2 -1
View File
@@ -14,6 +14,7 @@ import argsUtils from './util/args'
import { telemetry } from '@packages/telemetry'
import { getCtx, hasCtx } from '@packages/data-context'
import { warning as errorsWarning } from './errors'
import { getCwd } from './cwd'
import type { CypressError } from '@packages/errors'
import { toNumber } from 'lodash'
const debug = Debug('cypress:server:cypress')
@@ -139,7 +140,7 @@ export = {
debug('electron open arguments %o', args)
// const mainEntryFile = require.main.filename
const serverMain = require('./cwd')()
const serverMain = getCwd()
return cypressElectron.open(serverMain, args, fn)
})
-72
View File
@@ -1,72 +0,0 @@
const Promise = require('bluebird')
const execa = require('execa')
const shellEnv = require('shell-env')
const _ = require('lodash')
const log = require('debug')('cypress:server:exec')
const utils = require('./util/shell')
const pickMainProps = (val) => _.pick(val, ['stdout', 'stderr', 'exitCode'])
const trimStdio = (val) => {
const result = { ...val }
if (_.isString(val.stdout)) {
result.stdout = val.stdout.trim()
}
if (_.isString(val.stderr)) {
result.stderr = val.stderr.trim()
}
return result
}
module.exports = {
run (projectRoot, options) {
let {
cmd,
} = options
const shellCommand = function (cmd, cwd, env, shell) {
log('cy.exec found shell', shell)
log('and is running command:', options.cmd)
log('in folder:', projectRoot)
return execa(cmd, { cwd, env, shell: shell || true })
.then((result) => {
// do we want to return all fields returned by execa?
result.shell = shell
result.cmd = cmd
return result
}).then(pickMainProps)
.catch(pickMainProps) // transform rejection into an object
.then(trimStdio)
}
const run = () => {
return shellEnv()
.then((shellVariables) => {
const env = _.merge({}, shellVariables, process.env, options.env)
return utils.getShell(env.SHELL)
.then((shell) => {
cmd = utils.sourceShellCommand(options.cmd, shell)
return shellCommand(cmd, projectRoot, env, shell)
})
})
}
return Promise
.try(run)
.timeout(options.timeout)
.catch(Promise.TimeoutError, () => {
const msg = `Process timed out\ncommand: ${options.cmd}`
const err = new Error(msg)
err.timedOut = true
throw err
})
},
}
+69
View File
@@ -0,0 +1,69 @@
import Promise from 'bluebird'
import execa from 'execa'
import shellEnv from 'shell-env'
import _ from 'lodash'
import debugModule from 'debug'
const log = debugModule('cypress:server:exec')
import * as utils from './util/shell'
const pickMainProps = (val) => _.pick(val, ['stdout', 'stderr', 'exitCode'])
const trimStdio = (val) => {
const result = { ...val }
if (_.isString(val.stdout)) {
result.stdout = val.stdout.trim()
}
if (_.isString(val.stderr)) {
result.stderr = val.stderr.trim()
}
return result
}
export const run = (projectRoot: string, options: any) => {
let {
cmd,
} = options
const shellCommand = function (cmd, cwd, env, shell) {
log('cy.exec found shell', shell)
log('and is running command:', options.cmd)
log('in folder:', projectRoot)
return execa(cmd, { cwd, env, shell: shell || true })
.then((result: any) => {
// do we want to return all fields returned by execa?
result.shell = shell
result.cmd = cmd
return result
}).then(pickMainProps)
.catch(pickMainProps) // transform rejection into an object
.then(trimStdio)
}
const run = async () => {
const shellVariables = await shellEnv()
const env = _.merge({}, shellVariables, process.env, options.env)
const shell = await utils.getShell(env.SHELL)
cmd = utils.sourceShellCommand(options.cmd, shell)
return shellCommand(cmd, projectRoot, env, shell)
}
return Promise
.try(run)
.timeout(options.timeout)
.catch(Promise.TimeoutError, () => {
const msg = `Process timed out\ncommand: ${options.cmd}`
const err = new Error(msg)
// @ts-expect-error
err.timedOut = true
throw err
})
}
+1 -1
View File
@@ -18,7 +18,7 @@ import type {
import browserUtils from './browsers/utils'
import auth from './cloud/auth'
import user from './cloud/user'
import cohorts from './cohorts'
import * as cohorts from './cohorts'
import { openProject } from './open_project'
import { cache } from './cache'
import { graphqlSchema } from '@packages/data-context/graphql/schema'
+2 -2
View File
@@ -14,7 +14,7 @@ import exception from '../cloud/exception'
import { getError } from '@packages/errors'
import type { AllCypressErrorNames } from '@packages/errors'
import { get as getErrors, warning as errorsWarning, throwErr } from '../errors'
import capture from '../capture'
import * as capture from '../capture'
import { getResolvedRuntimeConfig } from '../config'
import env from '../util/env'
import ciProvider from '../util/ci_provider'
@@ -642,7 +642,7 @@ const createRunAndRecordSpecs = (options: any = {}) => {
const { runUrl, runId, machineId, groupId } = resp
const protocolCaptureMeta = resp.capture || {}
let captured = null
let captured: ReturnType<typeof capture.stdout> | null = null
let instanceId = null
const beforeSpecRun = () => {
@@ -1,5 +1,3 @@
import '../cwd'
import { EventEmitter } from 'events'
import debug from 'debug'
import * as plugins from '../plugins'
@@ -1,5 +1,3 @@
import '../cwd'
import _ from 'lodash'
import { EventEmitter } from 'events'
import path from 'path'
@@ -3,7 +3,7 @@ import os from 'os'
import path from 'path'
import { v4 as uuidv4 } from 'uuid'
import exec from '../exec'
import * as exec from '../exec'
import files from '../files'
import { fs } from '../util/fs'
import task from '../task'
+6 -6
View File
@@ -3,7 +3,7 @@ import path from 'path'
import Debug from 'debug'
import Bluebird from 'bluebird'
import appData from './util/app_data'
import cwd from './cwd'
import { getCwd } from './cwd'
import FileUtil from './util/file'
import { fs } from './util/fs'
import { AllowedState, allowedKeys } from '@packages/types'
@@ -16,7 +16,7 @@ const stateFiles: Record<string, typeof FileUtil> = {}
export const formStatePath = (projectRoot?: string) => {
return Bluebird.try(() => {
debug('making saved state from %s', cwd())
debug('making saved state from %s', getCwd())
if (projectRoot) {
debug('for project path %s', projectRoot)
@@ -26,25 +26,25 @@ export const formStatePath = (projectRoot?: string) => {
debug('missing project path, looking for project here')
let cypressConfigPath = cwd('cypress.config.js')
let cypressConfigPath = getCwd('cypress.config.js')
return fs.pathExistsAsync(cypressConfigPath)
.then((found) => {
if (found) {
debug('found cypress file %s', cypressConfigPath)
projectRoot = cwd()
projectRoot = getCwd()
return
}
cypressConfigPath = cwd('cypress.config.ts')
cypressConfigPath = getCwd('cypress.config.ts')
return fs.pathExistsAsync(cypressConfigPath)
})
.then((found) => {
if (found) {
debug('found cypress file %s', cypressConfigPath)
projectRoot = cwd()
projectRoot = getCwd()
}
return projectRoot
-1
View File
@@ -1,4 +1,3 @@
import './cwd'
import Bluebird from 'bluebird'
import compression from 'compression'
import Debug from 'debug'
+1 -1
View File
@@ -7,7 +7,7 @@ const check = require('check-more-types')
const log = require('debug')('cypress:server:appdata')
const pkg = require('@packages/root')
const { fs } = require('../util/fs')
const cwd = require('../cwd')
const cwd = require('../cwd').getCwd
const md5 = require('md5')
const sanitize = require('sanitize-filename')
const replace = require('lodash/replace')
+1 -1
View File
@@ -4,7 +4,7 @@ import debugModule from 'debug'
import type { Editor, EditorsResult } from '@packages/types'
import { getEnvEditors } from './env-editors'
import shell from './shell'
import * as shell from './shell'
import * as savedState from '../saved_state'
export const osFileSystemExplorer = {
@@ -1,9 +1,10 @@
const _ = require('lodash')
const Promise = require('bluebird')
const execa = require('execa')
const os = require('os')
const commandExistsModule = require('command-exists')
const log = require('debug')('cypress:server:util:shell')
import _ from 'lodash'
import Promise from 'bluebird'
import execa from 'execa'
import os from 'os'
import commandExistsModule from 'command-exists'
import debugModule from 'debug'
const log = debugModule('cypress:server:util:shell')
const isWindows = () => {
return os.platform() === 'win32'
@@ -17,18 +18,18 @@ const profiles = {
'~/.config/fish/config.fish': /\/fish$/,
}
let sourcedProfiles = []
let sourcedProfiles: string[] = []
// returns true if Cypress application has been started from
// the terminal shell.
// returns false if Cypress application has been started
// from the Finder / Windows Explorer list
// by double clicking its icon
const startedNormally = () => {
export const startedNormally = () => {
return Boolean(process.env._)
}
const getProfilePath = function (shellPath) {
export const getProfilePath = function (shellPath: string) {
for (let profilePath in profiles) {
const regex = profiles[profilePath]
@@ -36,9 +37,11 @@ const getProfilePath = function (shellPath) {
return profilePath
}
}
return undefined
}
const sourceShellCommand = function (cmd, shell) {
export const sourceShellCommand = function (cmd, shell) {
if (!shell) {
return cmd
}
@@ -46,7 +49,7 @@ const sourceShellCommand = function (cmd, shell) {
const profilePath = getProfilePath(shell)
log('shell %s profile %s', shell, profilePath)
if (sourcedProfiles.includes(profilePath)) {
if (sourcedProfiles.includes(profilePath as string)) {
log('profile has already been sourced')
return cmd
@@ -59,7 +62,7 @@ const sourceShellCommand = function (cmd, shell) {
// IF THE APP HAS NOT BEEN STARTED BY
// DOUBLE CLICKING IT FROM FINDER / WINDOWS EXPLORER
// OTHERWISE NEED TO SOURCE EVERY COMMAND
sourcedProfiles.push(profilePath)
sourcedProfiles.push(profilePath as string)
}
// sourcing the profile can output un-needed garbage,
@@ -68,12 +71,12 @@ const sourceShellCommand = function (cmd, shell) {
return `source ${profilePath} > /dev/null 2>&1; ${cmd}`
}
const findBash = () => {
export const findBash = () => {
return execa('which bash', { shell: true })
.then((val) => val.stdout)
}
const getShell = function (shell) {
export const getShell = function (shell) {
if (shell) {
return Promise.resolve(shell)
}
@@ -95,7 +98,7 @@ const getShell = function (shell) {
return findBash()
}
const commandExists = (command) => {
export const commandExists = (command) => {
return Promise.resolve(commandExistsModule(command))
.return(true)
// commandExists rejects with no error if command does not exist
@@ -104,16 +107,6 @@ const commandExists = (command) => {
}
// for testing
const reset = () => {
export const reset = () => {
return sourcedProfiles = []
}
module.exports = {
reset,
findBash,
getShell,
getProfilePath,
sourceShellCommand,
startedNormally,
commandExists,
}
@@ -25,7 +25,7 @@ const settings = require(`../../lib/util/settings`)
const Windows = require(`../../lib/gui/windows`)
const interactiveMode = require(`../../lib/modes/interactive`)
const api = require(`../../lib/cloud/api`).default
const cwd = require(`../../lib/cwd`)
const cwd = require(`../../lib/cwd`).getCwd
const user = require(`../../lib/cloud/user`)
const cache = require(`../../lib/cache`).cache
const errors = require(`../../lib/errors`)
@@ -1,9 +1,6 @@
require('../spec_helper')
require(`../../lib/cwd`)
const Promise = require('bluebird')
const cache = require(`../../lib/cache`).cache
const { fs } = require(`../../lib/util/fs`)
import Promise from 'bluebird'
import { cache } from '../../lib/cache'
import { fs } from '../../lib/util/fs'
describe('lib/cache', () => {
beforeEach(async () => {
@@ -1,7 +1,5 @@
/* eslint-disable no-console */
require('../spec_helper')
const capture = require(`../../lib/capture`)
import * as capture from '../../lib/capture'
describe('lib/capture', () => {
afterEach(() => {
+1 -1
View File
@@ -2,7 +2,7 @@ require('../spec_helper')
import { Cohort } from '@packages/types'
import { cache } from '../../lib/cache'
import cohorts from '../../lib/cohorts'
import * as cohorts from '../../lib/cohorts'
describe('lib/cohort', () => {
context('.get', () => {
@@ -1,8 +1,6 @@
require('../spec_helper')
const _ = require('lodash')
const os = require('os')
const exec = require(`../../lib/exec`)
import _ from 'lodash'
import os from 'os'
import * as exec from '../../lib/exec'
const isWindows = () => {
return os.platform() === 'win32'
@@ -5,7 +5,7 @@ import chaiSubset from 'chai-subset'
import sinonChai from '@cypress/sinon-chai'
import sinon from 'sinon'
import shellUtil from '../../../lib/util/shell.js'
import * as shellUtil from '../../../lib/util/shell'
import * as envEditors from '../../../lib/util/env-editors'
import * as savedState from '../../../lib/saved_state'