refactor(store): return type annotations (#7890)

This commit is contained in:
Khải
2024-04-10 20:22:48 +07:00
committed by GitHub
parent 1cf763da04
commit a9d02ddc61
29 changed files with 74 additions and 66 deletions

View File

@@ -46,7 +46,7 @@ export function addFilesFromDir (
for (const { absolutePath, relativePath, stat } of files) {
const buffer = gfs.readFileSync(absolutePath)
if (opts.readManifest && relativePath === 'package.json') {
manifest = parseJsonBufferSync(buffer)
manifest = parseJsonBufferSync(buffer) as DependencyManifest
}
filesIndex[relativePath] = {
mode: stat.mode,
@@ -73,7 +73,7 @@ function findFiles (
filesList: File[],
dir: string,
relativeDir = ''
) {
): void {
const files = fs.readdirSync(dir, { withFileTypes: true })
for (const file of files) {
const relativeSubdir = `${relativeDir}${relativeDir ? '/' : ''}${file.name}`

View File

@@ -3,6 +3,7 @@ import {
type FilesIndex,
type FileWriteResult,
} from '@pnpm/cafs-types'
import { type DependencyManifest } from '@pnpm/types'
import isGzip from 'is-gzip'
import { gunzipSync } from 'zlib'
import { parseJsonBufferSync } from './parseJson'
@@ -35,6 +36,6 @@ export function addFilesFromTarball (
}
return {
filesIndex,
manifest: manifestBuffer ? parseJsonBufferSync(manifestBuffer) : undefined,
manifest: manifestBuffer ? parseJsonBufferSync(manifestBuffer) as DependencyManifest : undefined,
}
}

View File

@@ -113,7 +113,7 @@ function verifyFile (
if (readManifest) {
return {
passed: true,
manifest: parseJsonBufferSync(gfs.readFileSync(filename)),
manifest: parseJsonBufferSync(gfs.readFileSync(filename)) as DependencyManifest,
}
}
// If a file was not edited, we are skipping integrity check.
@@ -137,7 +137,7 @@ export function verifyFileIntegrity (
} else if (readManifest) {
return {
passed,
manifest: parseJsonBufferSync(data),
manifest: parseJsonBufferSync(data) as DependencyManifest,
}
}
return { passed }
@@ -154,7 +154,7 @@ export function verifyFileIntegrity (
}
}
function checkFile (filename: string, checkedAt?: number) {
function checkFile (filename: string, checkedAt?: number): { isModified: boolean, size: number } | null {
try {
const { mtimeMs, size } = fs.statSync(filename)
return {

View File

@@ -9,7 +9,7 @@ export function getFilePathByModeInCafs (
cafsDir: string,
integrity: string | IntegrityLike,
mode: number
) {
): string {
const fileType = modeIsExecutable(mode) ? 'exec' : 'nonexec'
return path.join(cafsDir, contentPathFromIntegrity(integrity, fileType))
}
@@ -18,19 +18,19 @@ export function getFilePathInCafs (
cafsDir: string,
integrity: string | IntegrityLike,
fileType: FileType
) {
): string {
return path.join(cafsDir, contentPathFromIntegrity(integrity, fileType))
}
function contentPathFromIntegrity (
integrity: string | IntegrityLike,
fileType: FileType
) {
): string {
const sri = ssri.parse(integrity, { single: true })
return contentPathFromHex(fileType, sri.hexDigest())
}
export function contentPathFromHex (fileType: FileType, hex: string) {
export function contentPathFromHex (fileType: FileType, hex: string): string {
const p = path.join(hex.slice(0, 2), hex.slice(2))
switch (fileType) {
case 'exec':

View File

@@ -1,5 +1,5 @@
import stripBom from 'strip-bom'
export function parseJsonBufferSync (buffer: Buffer) {
export function parseJsonBufferSync (buffer: Buffer): unknown {
return JSON.parse(stripBom(buffer.toString()))
}

View File

@@ -268,14 +268,14 @@ export function parseTarball (buffer: Buffer): IParseResult {
// eslint-enable no-var
}
function indexOf (block: Buffer, num: number, offset: number, end: number) {
function indexOf (block: Buffer, num: number, offset: number, end: number): number {
for (; offset < end; offset++) {
if (block[offset] === num) return offset
}
return end
}
function clamp (index: number, len: number, defaultValue: number) {
function clamp (index: number, len: number, defaultValue: number): number {
if (typeof index !== 'number') return defaultValue
index = ~~index // Coerce to integer.
if (index >= len) return len

View File

@@ -1,13 +1,14 @@
import gfs from '@pnpm/graceful-fs'
import { type PackageManifest } from '@pnpm/types'
import { type PackageFilesIndex } from './checkPkgFilesIntegrity'
import { getFilePathByModeInCafs } from './getFilePathInCafs'
import { parseJsonBufferSync } from './parseJson'
export function readManifestFromStore (cafsDir: string, pkgIndex: PackageFilesIndex) {
export function readManifestFromStore (cafsDir: string, pkgIndex: PackageFilesIndex): PackageManifest | undefined {
const pkg = pkgIndex.files['package.json']
if (pkg) {
const fileName = getFilePathByModeInCafs(cafsDir, pkg.integrity, pkg.mode)
return parseJsonBufferSync(gfs.readFileSync(fileName))
return parseJsonBufferSync(gfs.readFileSync(fileName)) as PackageManifest
}
return undefined
}

View File

@@ -55,7 +55,7 @@ export function writeBufferToCafs (
}
}
export function optimisticRenameOverwrite (temp: string, fileDest: string) {
export function optimisticRenameOverwrite (temp: string, fileDest: string): void {
try {
renameOverwrite.sync(temp, fileDest)
} catch (err: unknown) {
@@ -94,7 +94,7 @@ function removeSuffix (filePath: string): string {
return withoutSuffix
}
function existsSame (filename: string, integrity: ssri.IntegrityLike) {
function existsSame (filename: string, integrity: ssri.IntegrityLike): boolean {
const existingFile = fs.statSync(filename, { throwIfNoEntry: false })
if (!existingFile) return false
return verifyFileIntegrity(filename, {

View File

@@ -7,12 +7,12 @@ export function writeFile (
fileDest: string,
buffer: Buffer,
mode?: number
) {
): void {
makeDirForFile(fileDest)
fs.writeFileSync(fileDest, buffer, { mode })
}
function makeDirForFile (fileDest: string) {
function makeDirForFile (fileDest: string): void {
const dir = path.dirname(fileDest)
if (!dirs.has(dir)) {
fs.mkdirSync(dir, { recursive: true })

View File

@@ -65,7 +65,7 @@ export function createPackageStore (
upload,
}
async function upload (builtPkgLocation: string, opts: { filesIndexFile: string, sideEffectsCacheKey: string }) {
async function upload (builtPkgLocation: string, opts: { filesIndexFile: string, sideEffectsCacheKey: string }): Promise<void> {
await addFilesFromDir({
cafsDir: cafs.cafsDir,
dir: builtPkgLocation,

View File

@@ -13,7 +13,7 @@ export interface PruneOptions {
storeDir: string
}
export async function prune ({ cacheDir, storeDir }: PruneOptions, removeAlienFiles?: boolean) {
export async function prune ({ cacheDir, storeDir }: PruneOptions, removeAlienFiles?: boolean): Promise<void> {
const cafsDir = path.join(storeDir, 'files')
await Promise.all([
rimraf(path.join(cacheDir, 'metadata')),

View File

@@ -11,7 +11,7 @@ import { stop } from './stop'
export const rcOptionsTypes = cliOptionsTypes
export function cliOptionsTypes () {
export function cliOptionsTypes (): Record<string, unknown> {
return {
...pick([
'store',
@@ -27,7 +27,7 @@ export function cliOptionsTypes () {
export const commandNames = ['server']
export function help () {
export function help (): string {
return renderHelp({
description: 'Manage a store server',
descriptionLists: [
@@ -103,7 +103,7 @@ export function handler (
unstoppable?: boolean
},
params: string[]
) {
): Promise<void> | undefined {
// We can only support TCP at the moment because node-fetch does not support IPC
opts.protocol = 'tcp'
switch (params[0]) {

View File

@@ -37,7 +37,7 @@ export async function start (
ignoreStopRequests?: boolean
ignoreUploadRequests?: boolean
}
) {
): Promise<void> {
if (opts.protocol === 'ipc' && opts.port) {
throw new Error('Port cannot be selected when server communicates via IPC')
}
@@ -126,18 +126,19 @@ export async function start (
await server.waitForClose
}
interface ServerOptions {
hostname?: string
port?: number
path?: string
}
async function getServerOptions (
connectionInfoDir: string,
opts: {
protocol: 'auto' | 'tcp' | 'ipc'
port?: number
}
): Promise<(
{
hostname: string
port: number
} | { path: string }
) & { hostname?: string, port?: number, path?: string }> {
): Promise<ServerOptions> {
switch (opts.protocol) {
case 'tcp':
return getTcpOptions()
@@ -162,7 +163,7 @@ async function getServerOptions (
}
}
function getIpcOptions () {
function getIpcOptions (): ServerOptions {
return {
path: path.join(connectionInfoDir, 'socket'),
}

View File

@@ -6,7 +6,7 @@ import { getStorePath } from '@pnpm/store-path'
export async function status (
opts: Pick<Config, 'dir' | 'pnpmHomeDir' | 'storeDir'>
) {
): Promise<void> {
const storeDir = await getStorePath({
pkgRoot: opts.dir,
storePath: opts.storeDir,

View File

@@ -16,7 +16,7 @@ export async function stop (
dir: string
pnpmHomeDir: string
}
) {
): Promise<void> {
const storeDir = await getStorePath({
pkgRoot: opts.dir,
storePath: opts.storeDir,
@@ -43,7 +43,7 @@ export async function stop (
globalInfo('Server process terminated')
}
async function serverGracefullyStops (pid: number) {
async function serverGracefullyStops (pid: number): Promise<boolean> {
if (!await processExists(pid)) return true
await delay(5000)

View File

@@ -14,11 +14,11 @@ export const commandNames = ['cat-file']
export const rcOptionsTypes = cliOptionsTypes
export function cliOptionsTypes () {
export function cliOptionsTypes (): Record<string, unknown> {
return {}
}
export function help () {
export function help (): string {
return renderHelp({
description:
'Prints the contents of a file based on the hash value stored in the index file.',
@@ -29,7 +29,7 @@ export function help () {
export type CatFileCommandOptions = Pick<Config, 'storeDir' | 'pnpmHomeDir'>
export async function handler (opts: CatFileCommandOptions, params: string[]) {
export async function handler (opts: CatFileCommandOptions, params: string[]): Promise<string> {
if (!params || params.length === 0) {
throw new PnpmError('MISSING_HASH', 'Missing file hash', {
hint: help(),

View File

@@ -22,7 +22,7 @@ export function cliOptionsTypes () {
return {}
}
export function help () {
export function help (): string {
return renderHelp({
description: 'Prints the index file of a specific package from the store.',
descriptionLists: [],
@@ -42,7 +42,7 @@ Config,
| 'sslConfigs'
>
export async function handler (opts: CatIndexCommandOptions, params: string[]) {
export async function handler (opts: CatIndexCommandOptions, params: string[]): Promise<string> {
if (!params || params.length === 0) {
throw new PnpmError(
'MISSING_PACKAGE_NAME',

View File

@@ -17,11 +17,11 @@ export const commandNames = ['find-hash']
export const rcOptionsTypes = cliOptionsTypes
export function cliOptionsTypes () {
export function cliOptionsTypes (): Record<string, unknown> {
return {}
}
export function help () {
export function help (): string {
return renderHelp({
description:
'Experimental! Lists the packages that include the file with the specified hash.',
@@ -37,7 +37,7 @@ export interface FindHashResult {
filesIndexFile: string
}
export async function handler (opts: FindHashCommandOptions, params: string[]) {
export async function handler (opts: FindHashCommandOptions, params: string[]): Promise<string> {
if (!params || params.length === 0) {
throw new PnpmError('MISSING_HASH', '`pnpm find-hash` requires the hash')
}

View File

@@ -12,7 +12,7 @@ import { storeStatus } from './storeStatus'
export const rcOptionsTypes = cliOptionsTypes
export function cliOptionsTypes () {
export function cliOptionsTypes (): Record<string, unknown> {
return pick([
'registry',
'store',
@@ -23,7 +23,7 @@ export function cliOptionsTypes () {
export const commandNames = ['store']
export function help () {
export function help (): string {
return renderHelp({
description: 'Reads and performs actions on pnpm store that is on the current filesystem.',
descriptionLists: [
@@ -77,11 +77,11 @@ export type StoreCommandOptions = Pick<Config, 'dir' | 'registries' | 'tag' | 's
reporter?: (logObj: LogBase) => void
}
export async function handler (opts: StoreCommandOptions, params: string[]) {
export async function handler (opts: StoreCommandOptions, params: string[]): Promise<string | undefined> {
let store
switch (params[0]) {
case 'status':
return statusCmd(opts)
return statusCmd(opts) as Promise<undefined>
case 'path':
return getStorePath({
pkgRoot: opts.dir,
@@ -97,7 +97,7 @@ export async function handler (opts: StoreCommandOptions, params: string[]) {
cacheDir: opts.cacheDir,
dlxCacheMaxAge: opts.dlxCacheMaxAge,
})
return storePrune(storePruneOptions)
return storePrune(storePruneOptions) as Promise<undefined>
}
case 'add':
store = await createOrConnectStoreController(opts)
@@ -107,13 +107,13 @@ export async function handler (opts: StoreCommandOptions, params: string[]) {
reporter: opts.reporter,
storeController: store.ctrl,
tag: opts.tag,
})
}) as Promise<undefined>
default:
return help()
}
}
async function statusCmd (opts: StoreCommandOptions) {
async function statusCmd (opts: StoreCommandOptions): Promise<void> {
const modifiedPkgs = await storeStatus(Object.assign(opts, {
storeDir: await getStorePath({
pkgRoot: opts.dir,

View File

@@ -16,7 +16,7 @@ export async function storeAdd (
tag?: string
supportedArchitectures?: SupportedArchitectures
}
) {
): Promise<void> {
const reporter = opts?.reporter
if ((reporter != null) && typeof reporter === 'function') {
streamParser.on('data', reporter)

View File

@@ -11,7 +11,7 @@ export async function storePrune (
cacheDir: string
dlxCacheMaxAge: number
}
) {
): Promise<void> {
const reporter = opts?.reporter
if ((reporter != null) && typeof reporter === 'function') {
streamParser.on('data', reporter)

View File

@@ -25,7 +25,7 @@ export interface StrictStoreStatusOptions {
export type StoreStatusOptions = Partial<StrictStoreStatusOptions> &
Pick<StrictStoreStatusOptions, 'storeDir'>
const defaults = async (opts: StoreStatusOptions) => {
const defaults = async (opts: StoreStatusOptions): Promise<StrictStoreStatusOptions> => {
const dir = opts.dir ?? process.cwd()
const lockfileDir = opts.lockfileDir ?? dir
return {

View File

@@ -16,7 +16,7 @@ import {
} from './extendStoreStatusOptions'
import { type TarballResolution } from '@pnpm/store-controller-types'
export async function storeStatus (maybeOpts: StoreStatusOptions) {
export async function storeStatus (maybeOpts: StoreStatusOptions): Promise<string[]> {
const reporter = maybeOpts?.reporter
if ((reporter != null) && typeof reporter === 'function') {
streamParser.on('data', reporter)

View File

@@ -26,6 +26,11 @@ interface RequestBody {
searchQueries: string[]
}
export interface StoreServerHandle {
close: () => Promise<void>
waitForClose: Promise<void>
}
export function createServer (
store: StoreController,
opts: {
@@ -35,7 +40,7 @@ export function createServer (
ignoreStopRequests?: boolean
ignoreUploadRequests?: boolean
}
) {
): StoreServerHandle {
const filesPromises: Record<string, () => Promise<PkgRequestFetchResult>> = {}
// eslint-disable-next-line @typescript-eslint/no-invalid-void-type
@@ -176,7 +181,7 @@ export function createServer (
return { close, waitForClose }
async function close () {
async function close (): Promise<void> {
listener.close()
return store.close()
}

View File

@@ -1,7 +1,7 @@
import { promises as fs } from 'fs'
import { createClient, type ClientOptions } from '@pnpm/client'
import { type Config } from '@pnpm/config'
import { createPackageStore, type CafsLocker } from '@pnpm/package-store'
import { createPackageStore, type CafsLocker, type StoreController } from '@pnpm/package-store'
import { packageManager } from '@pnpm/cli-meta'
type CreateResolverOptions = Pick<Config,
@@ -48,7 +48,7 @@ export type CreateNewStoreControllerOptions = CreateResolverOptions & Pick<Confi
export async function createNewStoreController (
opts: CreateNewStoreControllerOptions
) {
): Promise<{ ctrl: StoreController, dir: string }> {
const fullMetadata = opts.resolutionMode === 'time-based' && !opts.registrySupportsTimeField
const { resolve, fetchers } = createClient({
customFetchers: opts.hooks?.fetchers,

View File

@@ -27,7 +27,7 @@ export type CreateStoreControllerOptions = Omit<CreateNewStoreControllerOptions,
export async function createOrConnectStoreControllerCached (
storeControllerCache: Map<string, Promise<{ ctrl: StoreController, dir: string }>>,
opts: CreateStoreControllerOptions
) {
): Promise<{ ctrl: StoreController, dir: string }> {
const storeDir = await getStorePath({
pkgRoot: opts.dir,
storePath: opts.storeDir,

View File

@@ -2,7 +2,7 @@ import { PnpmError } from '@pnpm/error'
// cspell:ignore diable
import diable from '@zkochan/diable'
export function runServerInBackground (storePath: string) {
export function runServerInBackground (storePath: string): void {
if (require.main == null) {
throw new PnpmError('CANNOT_START_SERVER', 'pnpm server cannot be started when pnpm is streamed to Node.js')
}

View File

@@ -1,5 +1,5 @@
import path from 'path'
export function serverConnectionInfoDir (storePath: string) {
export function serverConnectionInfoDir (storePath: string): string {
return path.join(storePath, 'server')
}

View File

@@ -77,7 +77,7 @@ async function storePathRelativeToHome (pkgRoot: string, relStore: string, homed
}
}
async function canLinkToSubdir (fileToLink: string, dir: string) {
async function canLinkToSubdir (fileToLink: string, dir: string): Promise<boolean> {
let result = false
const tmpDir = pathTemp(dir)
try {
@@ -91,7 +91,7 @@ async function canLinkToSubdir (fileToLink: string, dir: string) {
return result
}
async function safeRmdir (dir: string) {
async function safeRmdir (dir: string): Promise<void> {
try {
// We cannot use just fs.rmdir here because can-link
// sometimes might not remove the temporary file in time
@@ -102,16 +102,16 @@ async function safeRmdir (dir: string) {
}
}
function dirsAreEqual (dir1: string, dir2: string) {
function dirsAreEqual (dir1: string, dir2: string): boolean {
return path.relative(dir1, dir2) === '.'
}
function getHomedir () {
function getHomedir (): string {
const home = os.homedir()
if (!home) throw new Error('Could not find the homedir')
return home
}
function isHomepath (filepath: string) {
function isHomepath (filepath: string): boolean {
return filepath.indexOf('~/') === 0 || filepath.indexOf('~\\') === 0
}