From d350ae96f8ec4dc72fec8b03a0ba2586070e33ab Mon Sep 17 00:00:00 2001 From: syi0808 Date: Wed, 16 Oct 2024 13:26:22 +0900 Subject: [PATCH] refactor: remove slow types --- src/cli.ts | 95 ++++++++++++----------- src/error.ts | 4 +- src/git.ts | 63 ++++++++------- src/index.ts | 2 +- src/registry/custom-registry.ts | 4 +- src/registry/index.ts | 4 +- src/registry/jsr.ts | 53 +++++++------ src/registry/npm.ts | 30 +++---- src/tasks/jsr.ts | 8 +- src/tasks/npm.ts | 2 +- src/tasks/prerequisites-check.ts | 12 +-- src/tasks/required-conditions-check.ts | 20 ++--- src/tasks/required-missing-information.ts | 10 +-- src/tasks/runner.ts | 18 ++--- src/utils/cli.ts | 2 +- src/utils/db.ts | 8 +- src/utils/engine-version.ts | 5 +- src/utils/listr.ts | 2 +- src/utils/notify-new-version.ts | 2 +- src/utils/package-name.ts | 12 +-- src/utils/package.ts | 25 ++++-- src/utils/rollback.ts | 4 +- tests/utils/cli.ts | 22 ++++-- 23 files changed, 220 insertions(+), 187 deletions(-) diff --git a/src/cli.ts b/src/cli.ts index 17b14e5..8bb6f23 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -141,59 +141,64 @@ function resolveCliOptions(options: CliOptions): Options { cli .command('[version]') - .action(async (nextVersion, options: Omit) => { - console.clear(); - - if (!isCI) { - await notifyNewVersion(); - } - - const context = { - version: nextVersion, - tag: options.tag, - }; - - try { - if (isCI) { - if (options.publishOnly) { - const git = new Git(); - const latestVersion = (await git.latestTag())?.slice(1); - - if (!latestVersion) { - throw new Error( - 'Cannot find the latest tag. Please ensure tags exist in the repository.', - ); - } + .action( + async ( + nextVersion, + options: Omit, + ): Promise => { + console.clear(); + + if (!isCI) { + await notifyNewVersion(); + } - if (!valid(latestVersion)) { + const context = { + version: nextVersion, + tag: options.tag, + }; + + try { + if (isCI) { + if (options.publishOnly) { + const git = new Git(); + const latestVersion = (await git.latestTag())?.slice(1); + + if (!latestVersion) { + throw new Error( + 'Cannot find the latest tag. Please ensure tags exist in the repository.', + ); + } + + if (!valid(latestVersion)) { + throw new Error( + 'Cannot parse the latest tag to a valid SemVer version. Please check the tag format.', + ); + } + + context.version = latestVersion; + } else { throw new Error( - 'Cannot parse the latest tag to a valid SemVer version. Please check the tag format.', + 'Version must be set in the CI environment. Please define the version before proceeding.', ); } - - context.version = latestVersion; } else { - throw new Error( - 'Version must be set in the CI environment. Please define the version before proceeding.', - ); + await requiredMissingInformationTasks().run(context); } - } else { - await requiredMissingInformationTasks().run(context); + + await pubm( + resolveCliOptions({ + ...options, + version: context.version, + tag: context.tag, + }), + ); + } catch (e) { + consoleError(e as Error); } + }, + ); - await pubm( - resolveCliOptions({ - ...options, - version: context.version, - tag: context.tag, - }), - ); - } catch (e) { - consoleError(e as Error); - } - }); - -cli.help((sections) => { +cli.help((sections): void => { sections[1].body += `\n\n Version can be:\n ${RELEASE_TYPES.join(' | ')} | 1.2.3`; sections.splice(2, 2); if (sections.at(2)) { diff --git a/src/error.ts b/src/error.ts index 4bbbf98..41a5670 100644 --- a/src/error.ts +++ b/src/error.ts @@ -11,7 +11,7 @@ export class AbstractError extends Error { } } -function replaceCode(code: string) { +function replaceCode(code: string): string { return code.replace(/`([^`].+)`/g, color.bold(color.underline('$1'))); } @@ -39,7 +39,7 @@ function formatError(error: AbstractError | string): string { return stringifyError; } -export function consoleError(error: string | Error) { +export function consoleError(error: string | Error): void { let errorText = '\n'; if (typeof error === 'string') { diff --git a/src/git.ts b/src/git.ts index 19d1939..0966757 100644 --- a/src/git.ts +++ b/src/git.ts @@ -7,7 +7,7 @@ class GitError extends AbstractError { } export class Git { - async git(args: string[]) { + async git(args: string[]): Promise { const { stdout, stderr } = await exec('git', args); if (stderr) throw stderr; @@ -15,7 +15,7 @@ export class Git { return stdout; } - async userName() { + async userName(): Promise { try { return (await this.git(['config', '--get', 'user.name'])).trim(); } catch (error) { @@ -25,7 +25,7 @@ export class Git { } } - async latestTag() { + async latestTag(): Promise { try { return (await this.git(['describe', '--tags', '--abbrev=0'])).trim(); } catch { @@ -33,7 +33,7 @@ export class Git { } } - async tags() { + async tags(): Promise { try { return (await this.git(['tag', '-l'])) .trim() @@ -47,17 +47,17 @@ export class Git { } } - async previousTag(tag: string) { + async previousTag(tag: string): Promise { try { const tags = await this.tags(); - return tags.at(tags.findIndex((t) => t === tag) - 1); + return tags.at(tags.findIndex((t) => t === tag) - 1) ?? null; } catch { return null; } } - async dryFetch() { + async dryFetch(): Promise { try { return await this.git(['fetch', '--dry-run']); } catch (error) { @@ -67,7 +67,7 @@ export class Git { } } - async fetch() { + async fetch(): Promise { try { await this.git(['fetch']); @@ -79,7 +79,7 @@ export class Git { } } - async pull() { + async pull(): Promise { try { await this.git(['pull']); @@ -91,9 +91,9 @@ export class Git { } } - async revisionDiffsCount() { + async revisionDiffsCount(): Promise { try { - return await Number.parseInt( + return Number.parseInt( await this.git(['rev-list', '@{u}...HEAD', '--count', '--left-only']), ); } catch (error) { @@ -104,7 +104,7 @@ export class Git { } } - async status() { + async status(): Promise { try { return (await this.git(['status', '--porcelain'])).trim(); } catch (error) { @@ -114,7 +114,10 @@ export class Git { } } - async commits(leftRev: string, rightRev: string) { + async commits( + leftRev: string, + rightRev: string, + ): Promise<{ id: string; message: string }[]> { try { const logs = await this.git([ 'log', @@ -137,9 +140,9 @@ export class Git { } } - async version() { + async version(): Promise { try { - return (await this.git(['--version'])).trim().match(/\d+\.\d+\.\d+/)?.[0]; + return `${(await this.git(['--version'])).trim().match(/\d+\.\d+\.\d+/)?.[0]}`; } catch (error) { throw new GitError('Failed to run `git --version`', { cause: error, @@ -147,7 +150,7 @@ export class Git { } } - async branch() { + async branch(): Promise { try { return (await this.git(['rev-parse', '--abbrev-ref', 'HEAD'])).trim(); } catch (error) { @@ -157,7 +160,7 @@ export class Git { } } - async switch(branch: string) { + async switch(branch: string): Promise { try { await this.git(['switch', branch]); @@ -169,7 +172,7 @@ export class Git { } } - async checkTagExist(tag: string) { + async checkTagExist(tag: string): Promise { try { return ( ( @@ -186,7 +189,7 @@ export class Git { } } - async deleteTag(tag: string) { + async deleteTag(tag: string): Promise { try { await this.git(['tag', '--delete', tag]); @@ -198,7 +201,7 @@ export class Git { } } - async stageAll() { + async stageAll(): Promise { try { await this.git(['add', '.']); @@ -210,7 +213,7 @@ export class Git { } } - async stash() { + async stash(): Promise { try { await this.git(['stash']); @@ -222,7 +225,7 @@ export class Git { } } - async popStash() { + async popStash(): Promise { try { await this.git(['stash', 'pop']); @@ -234,7 +237,7 @@ export class Git { } } - async stage(file: string) { + async stage(file: string): Promise { try { await this.git(['add', file]); @@ -246,7 +249,7 @@ export class Git { } } - async reset(rev?: string, option?: string) { + async reset(rev?: string, option?: string): Promise { const args = ['reset', rev, option].filter((v) => v) as string[]; try { @@ -260,7 +263,7 @@ export class Git { } } - async latestCommit() { + async latestCommit(): Promise { try { return (await this.git(['rev-parse', 'HEAD'])).trim(); } catch (error) { @@ -270,7 +273,7 @@ export class Git { } } - async firstCommit() { + async firstCommit(): Promise { try { return (await this.git(['rev-list', '--max-parents=0', 'HEAD'])).trim(); } catch (error) { @@ -280,7 +283,7 @@ export class Git { } } - async commit(message: string) { + async commit(message: string): Promise { try { await this.git(['commit', '-m', message]); @@ -292,7 +295,7 @@ export class Git { } } - async repository() { + async repository(): Promise { try { return (await this.git(['remote', 'get-url', 'origin'])).trim(); } catch (error) { @@ -302,7 +305,7 @@ export class Git { } } - async createTag(tag: string, commitRev?: string) { + async createTag(tag: string, commitRev?: string): Promise { const args = ['tag', tag, commitRev].filter((v) => v) as string[]; try { @@ -316,7 +319,7 @@ export class Git { } } - async push(options?: string) { + async push(options?: string): Promise { const args = ['push', options].filter((v) => v) as string[]; try { diff --git a/src/index.ts b/src/index.ts index 93a6713..cfc6f49 100644 --- a/src/index.ts +++ b/src/index.ts @@ -12,7 +12,7 @@ import type { Options } from './types/options.js'; * @async * @function */ -export async function pubm(options: Options) { +export async function pubm(options: Options): Promise { const resolvedOptions = resolveOptions({ ...options }); await run(resolvedOptions); diff --git a/src/registry/custom-registry.ts b/src/registry/custom-registry.ts index 589bbf9..858cbac 100644 --- a/src/registry/custom-registry.ts +++ b/src/registry/custom-registry.ts @@ -3,7 +3,7 @@ import { getPackageJson } from '../utils/package.js'; import { NpmRegistry } from './npm.js'; export class CustomRegistry extends NpmRegistry { - async npm(args: string[]) { + async npm(args: string[]): Promise { const { stdout, stderr } = await exec( 'npm', args.concat('--registry', this.registry), @@ -15,7 +15,7 @@ export class CustomRegistry extends NpmRegistry { } } -export async function customRegistry() { +export async function customRegistry(): Promise { const packageJson = await getPackageJson(); return new CustomRegistry(packageJson.name); diff --git a/src/registry/index.ts b/src/registry/index.ts index 8254bce..66484e7 100644 --- a/src/registry/index.ts +++ b/src/registry/index.ts @@ -9,7 +9,9 @@ const registryMap = { jsr: jsrRegistry, } as unknown as Record Promise>; -export async function getRegistry(registryKey: RegistryType) { +export async function getRegistry( + registryKey: RegistryType, +): Promise { const registry = registryMap[registryKey]; if (!registry) { diff --git a/src/registry/jsr.ts b/src/registry/jsr.ts index da5e771..9a532d3 100644 --- a/src/registry/jsr.ts +++ b/src/registry/jsr.ts @@ -14,7 +14,7 @@ class JsrError extends AbstractError { name = 'jsr Error'; } -function getApiEndpoint(registry: string) { +function getApiEndpoint(registry: string): string { const url = new URL(registry); url.host = `api.${url.host}`; @@ -32,7 +32,7 @@ export class JsrRegisry extends Registry { this.client = new JsrClient(getApiEndpoint(this.registry)); } - protected async jsr(args: string[]) { + protected async jsr(args: string[]): Promise { const { stdout, stderr } = await exec('jsr', args); if (stderr) throw stderr; @@ -40,7 +40,7 @@ export class JsrRegisry extends Registry { return stdout; } - async isInstalled() { + async isInstalled(): Promise { try { await this.jsr(['--help']); @@ -50,11 +50,11 @@ export class JsrRegisry extends Registry { } } - async distTags() { + async distTags(): Promise { return []; } - async ping() { + async ping(): Promise { try { const { stdout, stderr } = await exec('ping', [ new URL(this.registry).hostname, @@ -73,7 +73,7 @@ export class JsrRegisry extends Registry { } } - async publish() { + async publish(): Promise { try { await exec( 'jsr', @@ -94,11 +94,11 @@ export class JsrRegisry extends Registry { } } - async version() { + async version(): Promise { return await this.jsr(['--version']); } - async isPublished() { + async isPublished(): Promise { try { const response = await fetch(`${this.registry}/${this.packageName}`); @@ -111,13 +111,13 @@ export class JsrRegisry extends Registry { } } - async hasPermission() { + async hasPermission(): Promise { return ( this.client.scopePermission(`${getScope(this.packageName)}`) !== null ); } - async isPackageNameAvaliable() { + async isPackageNameAvaliable(): Promise { return isValidPackageName(this.packageName); } } @@ -127,7 +127,10 @@ export class JsrClient { constructor(public apiEndpoint: string) {} - protected async fetch(endpoint: string, init?: RequestInit) { + protected async fetch( + endpoint: string, + init?: RequestInit, + ): Promise { const pubmVersion = await version({ cwd: import.meta.dirname }); return fetch(new URL(endpoint, this.apiEndpoint), { @@ -140,13 +143,13 @@ export class JsrClient { }); } - async user() { + async user(): Promise { try { const response = await this.fetch('/user'); if (response.status === 401) return null; - return (await response.json()) as JsrApi.Users.User; + return await response.json(); } catch (error) { throw new JsrError(`Failed to fetch \`${this.apiEndpoint}/user\``, { cause: error, @@ -154,13 +157,15 @@ export class JsrClient { } } - async scopePermission(scope: string) { + async scopePermission( + scope: string, + ): Promise { try { const response = await this.fetch(`/user/member/${scope}`); if (response.status === 401) return null; - return (await response.json()) as JsrApi.Users.Scopes.Permission; + return await response.json(); } catch (error) { throw new JsrError( `Failed to fetch \`${this.apiEndpoint}/user/member/${scope}\``, @@ -190,13 +195,13 @@ export class JsrClient { } } - async package(packageName: string) { + async package(packageName: string): Promise { const [scope, name] = getScopeAndName(packageName); try { const response = await this.fetch(`/scopes/${scope}/packages/${name}`); - return (await response.json()) as JsrApi.Scopes.Packages.Package; + return await response.json(); } catch (error) { throw new JsrError( `Failed to fetch \`${this.apiEndpoint}/user/scopes\``, @@ -207,7 +212,7 @@ export class JsrClient { } } - async createScope(scope: string) { + async createScope(scope: string): Promise { try { const response = await this.fetch('/scopes', { method: 'POST', @@ -222,7 +227,7 @@ export class JsrClient { } } - async deleteScope(scope: string) { + async deleteScope(scope: string): Promise { try { const response = await this.fetch(`/scopes/${scope}`, { method: 'DELETE', @@ -239,7 +244,7 @@ export class JsrClient { } } - async createPackage(packageName: string) { + async createPackage(packageName: string): Promise { const [scope, name] = getScopeAndName(packageName); try { @@ -259,7 +264,7 @@ export class JsrClient { } } - async deletePackage(packageName: string) { + async deletePackage(packageName: string): Promise { const [scope, name] = getScopeAndName(packageName); try { @@ -278,11 +283,11 @@ export class JsrClient { } } - async searchPackage(query: string) { + async searchPackage(query: string): Promise { try { const response = await this.fetch(`/packages?query=${query}`); - return (await response.json()) as JsrApi.Packages; + return await response.json(); } catch (error) { throw new JsrError( `Failed to fetch \`${this.apiEndpoint}/packages?query=${query}\``, @@ -294,7 +299,7 @@ export class JsrClient { } } -export async function jsrRegistry() { +export async function jsrRegistry(): Promise { const jsrJson = await getJsrJson(); return new JsrRegisry(jsrJson.name); diff --git a/src/registry/npm.ts b/src/registry/npm.ts index 7ed729c..955478b 100644 --- a/src/registry/npm.ts +++ b/src/registry/npm.ts @@ -11,7 +11,7 @@ class NpmError extends AbstractError { export class NpmRegistry extends Registry { registry = 'https://registry.npmjs.org'; - protected async npm(args: string[]) { + protected async npm(args: string[]): Promise { const { stdout, stderr } = await exec('npm', args); if (stderr) throw stderr; @@ -19,7 +19,7 @@ export class NpmRegistry extends Registry { return stdout; } - async isInstalled() { + async isInstalled(): Promise { try { await this.npm(['--help']); @@ -29,7 +29,7 @@ export class NpmRegistry extends Registry { } } - async installGlobally(packageName: string) { + async installGlobally(packageName: string): Promise { try { await this.npm(['install', '-g', packageName]); @@ -41,7 +41,7 @@ export class NpmRegistry extends Registry { } } - async isPublished() { + async isPublished(): Promise { try { const response = await fetch(`${this.registry}/${this.packageName}`); @@ -54,7 +54,7 @@ export class NpmRegistry extends Registry { } } - async userName() { + async userName(): Promise { try { return (await this.npm(['whoami'])).trim(); } catch (error) { @@ -62,7 +62,7 @@ export class NpmRegistry extends Registry { } } - async isLoggedIn() { + async isLoggedIn(): Promise { try { await this.npm(['whoami']); @@ -76,7 +76,7 @@ export class NpmRegistry extends Registry { } } - async collaborators() { + async collaborators(): Promise> { try { return JSON.parse( await this.npm([ @@ -95,7 +95,7 @@ export class NpmRegistry extends Registry { } } - async hasPermission() { + async hasPermission(): Promise { const userName = await this.userName(); const collaborators = await this.collaborators(); @@ -103,7 +103,7 @@ export class NpmRegistry extends Registry { return !!collaborators[userName]?.includes('write'); } - async distTags() { + async distTags(): Promise { try { return Object.keys( JSON.parse( @@ -118,7 +118,7 @@ export class NpmRegistry extends Registry { } } - async version() { + async version(): Promise { try { return this.npm(['--version']); } catch (error) { @@ -126,7 +126,7 @@ export class NpmRegistry extends Registry { } } - async ping() { + async ping(): Promise { try { await exec('npm', ['ping'], { throwOnError: true }); @@ -136,7 +136,7 @@ export class NpmRegistry extends Registry { } } - async publishProvenance() { + async publishProvenance(): Promise { try { try { await this.npm(['publish', '--provenance', '--access', 'public']); @@ -157,7 +157,7 @@ export class NpmRegistry extends Registry { } } - async publish(otp?: string) { + async publish(otp?: string): Promise { const args = otp ? ['publish', '--otp', otp] : ['publish']; try { @@ -177,12 +177,12 @@ export class NpmRegistry extends Registry { } } - async isPackageNameAvaliable() { + async isPackageNameAvaliable(): Promise { return isValidPackageName(this.packageName); } } -export async function npmRegistry() { +export async function npmRegistry(): Promise { const packageJson = await getPackageJson(); return new NpmRegistry(packageJson.name); diff --git a/src/tasks/jsr.ts b/src/tasks/jsr.ts index 2daecae..2c0c923 100644 --- a/src/tasks/jsr.ts +++ b/src/tasks/jsr.ts @@ -23,16 +23,16 @@ class JsrAvailableError extends AbstractError { } interface JsrCtx extends Ctx { - scopeCreated: boolean; - packageCreated: boolean; + scopeCreated?: boolean; + packageCreated?: boolean; } export const jsrAvailableCheckTasks: ListrTask = { title: 'Checking jsr avaliable for publising', - task: async (ctx, task) => { + task: async (ctx, task): Promise => { const jsr = await jsrRegistry(); - addRollback(async (ctx) => { + addRollback(async (ctx): Promise => { if (ctx.packageCreated) { console.log(`Deleting jsr package ${jsr.packageName}...`); diff --git a/src/tasks/npm.ts b/src/tasks/npm.ts index e47e60d..4117c0f 100644 --- a/src/tasks/npm.ts +++ b/src/tasks/npm.ts @@ -19,7 +19,7 @@ class NpmAvailableError extends AbstractError { export const npmAvailableCheckTasks: ListrTask = { title: 'Checking npm avaliable for publising', skip: (ctx) => !!ctx.preview, - task: async () => { + task: async (): Promise => { const npm = await npmRegistry(); if (!(await npm.isLoggedIn())) { diff --git a/src/tasks/prerequisites-check.ts b/src/tasks/prerequisites-check.ts index 6e00887..77f1b06 100644 --- a/src/tasks/prerequisites-check.ts +++ b/src/tasks/prerequisites-check.ts @@ -16,9 +16,9 @@ class PrerequisitesCheckError extends AbstractError { } } -export const prerequisitesCheckTask: ( +export const prerequisitesCheckTask = ( options?: Omit, 'title' | 'task'>, -) => Listr = (options) => { +): Listr => { const git = new Git(); return createListr({ @@ -30,7 +30,7 @@ export const prerequisitesCheckTask: ( { skip: (ctx) => !!ctx.anyBranch, title: 'Verifying current branch is a release branch', - task: async (ctx, task) => { + task: async (ctx, task): Promise => { if ((await git.branch()) !== ctx.branch) { const swtichBranch = await task .prompt(ListrEnquirerPromptAdapter) @@ -54,7 +54,7 @@ export const prerequisitesCheckTask: ( }, { title: 'Checking if remote history is clean', - task: async (_, task) => { + task: async (_, task): Promise => { task.output = 'Checking for updates with `git fetch`'; if ((await git.dryFetch()).trim()) { @@ -101,7 +101,7 @@ export const prerequisitesCheckTask: ( }, { title: 'Checking if the local working tree is clean', - task: async (ctx, task) => { + task: async (ctx, task): Promise => { if (await git.status()) { task.output = 'Local working tree is not clean.'; @@ -152,7 +152,7 @@ export const prerequisitesCheckTask: ( }, { title: 'Checking git tag existence', - task: async (ctx, task) => { + task: async (ctx, task): Promise => { const gitTag = `v${ctx.version}`; if (await git.checkTagExist(gitTag)) { diff --git a/src/tasks/required-conditions-check.ts b/src/tasks/required-conditions-check.ts index 8388c16..e180e31 100644 --- a/src/tasks/required-conditions-check.ts +++ b/src/tasks/required-conditions-check.ts @@ -23,22 +23,22 @@ class RequiredConditionCheckError extends AbstractError { } } -export const requiredConditionsCheckTask: ( +export const requiredConditionsCheckTask = ( options?: Omit, 'title' | 'task'>, -) => Listr = (options) => +): Listr => createListr({ ...options, title: 'Required conditions check (for pubm tasks)', - task: (_, parentTask) => + task: (_, parentTask): Listr => parentTask.newListr( [ { title: 'Ping registries', - task: async (ctx, parentTask) => + task: (ctx, parentTask): Listr => parentTask.newListr( ctx.registries.map((registryKey) => ({ title: `Ping to ${registryKey}`, - task: async () => { + task: async (): Promise => { const registry = await getRegistry(registryKey); await registry.ping(); @@ -58,7 +58,7 @@ export const requiredConditionsCheckTask: ( enabled: (ctx) => ctx.registries.some((registry) => registry !== 'jsr'), title: 'Verifying if npm are installed', - task: async () => { + task: async (): Promise => { const npm = await npmRegistry(); if (!(await npm.isInstalled())) { @@ -72,7 +72,7 @@ export const requiredConditionsCheckTask: ( enabled: (ctx) => ctx.registries.some((registry) => registry === 'jsr'), title: 'Verifying if jsr are installed', - task: async (_, task) => { + task: async (_, task): Promise => { const jsr = await jsrRegistry(); if (!(await jsr.isInstalled())) { @@ -108,7 +108,7 @@ export const requiredConditionsCheckTask: ( { title: 'Checking if test and build scripts exist', skip: (ctx) => ctx.jsrOnly, - task: async (ctx) => { + task: async (ctx): Promise => { const { scripts } = await getPackageJson(); const errors: string[] = []; @@ -132,7 +132,7 @@ export const requiredConditionsCheckTask: ( }, { title: 'Checking git version', - task: async () => { + task: async (): Promise => { const git = new Git(); validateEngineVersion('git', `${await git.version()}`); @@ -140,7 +140,7 @@ export const requiredConditionsCheckTask: ( }, { title: 'Checking available registries for publishing', - task: async (ctx, parentTask) => + task: (ctx, parentTask): Listr => parentTask.newListr( ctx.registries.map((registryKey) => { switch (registryKey) { diff --git a/src/tasks/required-missing-information.ts b/src/tasks/required-missing-information.ts index 87ab77e..1a27c6c 100644 --- a/src/tasks/required-missing-information.ts +++ b/src/tasks/required-missing-information.ts @@ -14,18 +14,18 @@ interface Ctx { tag: string; } -export const requiredMissingInformationTasks: ( +export const requiredMissingInformationTasks = ( options?: Omit, 'title' | 'task'>, -) => Listr = (options) => +): Listr => createListr({ ...options, title: 'Checking required information', - task: (_, parentTask) => + task: (_, parentTask): Listr => parentTask.newListr([ { title: 'Checking version information', skip: (ctx) => !!ctx.version, - task: async (ctx, task) => { + task: async (ctx, task): Promise => { const currentVersion = await version(); let nextVersion = await task @@ -66,7 +66,7 @@ export const requiredMissingInformationTasks: ( title: 'Checking tag information', skip: (ctx) => !prerelease(`${ctx.version}`) && ctx.tag === defaultOptions.tag, - task: async (ctx, task) => { + task: async (ctx, task): Promise => { const npm = await npmRegistry(); const jsr = await jsrRegistry(); const distTags = [ diff --git a/src/tasks/runner.ts b/src/tasks/runner.ts index 21318ad..3ed4c8e 100644 --- a/src/tasks/runner.ts +++ b/src/tasks/runner.ts @@ -1,6 +1,6 @@ import process from 'node:process'; import npmCli from '@npmcli/promise-spawn'; -import { color } from 'listr2'; +import { color, type Listr } from 'listr2'; import SemVer from 'semver'; import { isCI } from 'std-env'; import { exec } from 'tinyexec'; @@ -31,7 +31,7 @@ export interface Ctx extends ResolvedOptions { cleanWorkingTree: boolean; } -export async function run(options: ResolvedOptions) { +export async function run(options: ResolvedOptions): Promise { const ctx = { ...options, promptEnabled: !isCI && process.stdin.isTTY, @@ -56,7 +56,7 @@ export async function run(options: ResolvedOptions) { options.publishOnly ? { title: 'Publishing', - task: (ctx, parentTask) => + task: (ctx, parentTask): Listr => parentTask.newListr( ctx.registries.map((registry) => { switch (registry) { @@ -75,7 +75,7 @@ export async function run(options: ResolvedOptions) { { skip: options.skipTests, title: 'Running tests', - task: async (ctx) => { + task: async (ctx): Promise => { const packageManager = await getPackageManager(); const { stderr } = await exec(packageManager, [ @@ -94,7 +94,7 @@ export async function run(options: ResolvedOptions) { { skip: options.skipBuild, title: 'Building the project', - task: async (ctx) => { + task: async (ctx): Promise => { const packageManager = await getPackageManager(); try { @@ -112,7 +112,7 @@ export async function run(options: ResolvedOptions) { { title: 'Bumping version', skip: (ctx) => !!ctx.preview, - task: async (ctx, task) => { + task: async (ctx, task): Promise => { const git = new Git(); let tagCreated = false; let commited = false; @@ -153,7 +153,7 @@ export async function run(options: ResolvedOptions) { { skip: (ctx) => options.skipPublish || !!ctx.preview, title: 'Publishing', - task: (ctx, parentTask) => + task: (ctx, parentTask): Listr => parentTask.newListr( ctx.registries.map((registry) => { switch (registry) { @@ -171,7 +171,7 @@ export async function run(options: ResolvedOptions) { { title: 'Pushing tags to GitHub', skip: (ctx) => !!ctx.preview, - task: async (_, task) => { + task: async (_, task): Promise => { const git = new Git(); const result = await git.push('--follow-tags'); @@ -187,7 +187,7 @@ export async function run(options: ResolvedOptions) { { skip: (ctx) => options.skipReleaseDraft || !!ctx.preview, title: 'Creating release draft on GitHub', - task: async (ctx, task) => { + task: async (ctx, task): Promise => { const git = new Git(); const repositoryUrl = await git.repository(); diff --git a/src/utils/cli.ts b/src/utils/cli.ts index 186a9ec..228614b 100644 --- a/src/utils/cli.ts +++ b/src/utils/cli.ts @@ -2,6 +2,6 @@ import { color } from 'listr2'; export const warningBadge = color.bgYellow(' Warning '); -export function link(text: string, url: string) { +export function link(text: string, url: string): string { return `\u001B]8;;${url}\u0007${text}\u001B]8;;\u0007`; } diff --git a/src/utils/db.ts b/src/utils/db.ts index 7b0a1bb..96ebcc1 100644 --- a/src/utils/db.ts +++ b/src/utils/db.ts @@ -7,12 +7,12 @@ const n = statSync(import.meta.dirname); const k = `${n.rdev}${n.birthtimeMs}${n.nlink}${n.gid}`; const l = createHash('md5').update(k).digest(); -function e(e: string, f: string) { +function e(e: string, f: string): string { const c = createCipheriv(a, createHash('sha-256').update(f).digest(), l); return c.update(e, 'utf8', 'hex') + c.final('hex'); } -function d(g: string, h: string) { +function d(g: string, h: string): string { const d = createDecipheriv(a, createHash('sha-256').update(h).digest(), l); return d.update(g, 'hex', 'utf8') + d.final('utf8'); } @@ -30,7 +30,7 @@ export class Db { } } - set(field: string, value: unknown) { + set(field: string, value: unknown): void { writeFileSync( path.resolve(this.path, Buffer.from(e(field, field)).toString('base64')), Buffer.from(e(`${value}`, field)), @@ -38,7 +38,7 @@ export class Db { ); } - get(field: string) { + get(field: string): string | null { try { return d( Buffer.from( diff --git a/src/utils/engine-version.ts b/src/utils/engine-version.ts index d8d44d7..aad1ca2 100644 --- a/src/utils/engine-version.ts +++ b/src/utils/engine-version.ts @@ -2,7 +2,10 @@ import { satisfies } from 'semver'; import type { Engine } from '../types/package-json.js'; import { getPackageJson } from './package.js'; -export async function validateEngineVersion(engine: Engine, version: string) { +export async function validateEngineVersion( + engine: Engine, + version: string, +): Promise { const { engines } = await getPackageJson({ cwd: import.meta.dirname, }); diff --git a/src/utils/listr.ts b/src/utils/listr.ts index cf80c78..781166d 100644 --- a/src/utils/listr.ts +++ b/src/utils/listr.ts @@ -3,7 +3,7 @@ import { rollback } from './rollback.js'; export function createListr( ...args: ConstructorParameters> -) { +): Listr { const listr = new Listr(...args); listr.isRoot = () => false; diff --git a/src/utils/notify-new-version.ts b/src/utils/notify-new-version.ts index 056250f..bbaaed3 100644 --- a/src/utils/notify-new-version.ts +++ b/src/utils/notify-new-version.ts @@ -3,7 +3,7 @@ import { exec } from 'tinyexec'; import { getScopeAndName } from './package-name.js'; import { findOutFile, getJsrJson, getPackageJson, version } from './package.js'; -export async function notifyNewVersion() { +export async function notifyNewVersion(): Promise { const currentVersion = await version({ cwd: import.meta.dirname }); await Promise.all([ diff --git a/src/utils/package-name.ts b/src/utils/package-name.ts index 8e47dbc..da2b9dc 100644 --- a/src/utils/package-name.ts +++ b/src/utils/package-name.ts @@ -1,19 +1,19 @@ import { builtinModules } from 'node:module'; -export function isScopedPackage(packageName: string) { +export function isScopedPackage(packageName: string): boolean { return /^@[^/]+\/[^@][\w.-]*$/.test(packageName); } -export function getScope(packageName: string) { - return packageName.match(/^@([^/]+)/)?.[1]; +export function getScope(packageName: string): string | null { + return packageName.match(/^@([^/]+)/)?.[1] ?? null; } -export function getScopeAndName(packageName: string) { +export function getScopeAndName(packageName: string): [string, string] { const matches = packageName.match(/^@([a-zA-Z0-9]+)\/([a-zA-Z0-9]+)$/); const scope = matches?.[1]; const name = matches?.[2]; - return [scope, name] as [string, string]; + return [`${scope}`, `${name}`]; } // Based on https://github.com/npm/validate-npm-package-name/blob/main/lib/index.js @@ -21,7 +21,7 @@ export function getScopeAndName(packageName: string) { const scopedPackagePattern = /^(?:@([^/]+?)[/])?([^/]+?)$/; const blacklist = ['node_modules', 'favicon.ico']; -export function isValidPackageName(packageName: string) { +export function isValidPackageName(packageName: string): boolean { if (packageName.length <= 0) return false; if (packageName.match(/^\./)) return false; diff --git a/src/utils/package.ts b/src/utils/package.ts index a20c2af..dab1788 100644 --- a/src/utils/package.ts +++ b/src/utils/package.ts @@ -14,14 +14,17 @@ const cachedJsrJson: Record = {}; // If the `name` field in the JSR JSON is not the scoped name from `package.json`, // update the cached JSR JSON accordingly. -export async function patchCachedJsrJson( +export function patchCachedJsrJson( contents: Partial, { cwd = process.cwd() } = {}, -) { +): void { cachedJsrJson[cwd] = { ...cachedJsrJson[cwd], ...contents }; } -export async function findOutFile(file: string, { cwd = process.cwd() } = {}) { +export async function findOutFile( + file: string, + { cwd = process.cwd() } = {}, +): Promise { let directory = cwd; let filePath = ''; const { root } = path.parse(cwd); @@ -124,7 +127,9 @@ export async function getJsrJson({ } } -export async function packageJsonToJsrJson(packageJson: PackageJson) { +export async function packageJsonToJsrJson( + packageJson: PackageJson, +): Promise { const ignore = (await findOutFile('.npmignore')) || (await findOutFile('.gitignore')); @@ -147,7 +152,9 @@ export async function packageJsonToJsrJson(packageJson: PackageJson) { }, }; - function convertExports(exports: string | PackageExportsEntryObject) { + function convertExports( + exports: string | PackageExportsEntryObject, + ): string | Record { if (typeof exports === 'string') return exports; const convertedExports: Record = @@ -168,7 +175,7 @@ export async function packageJsonToJsrJson(packageJson: PackageJson) { } } -export async function jsrJsonToPackageJson(jsrJson: JsrJson) { +export function jsrJsonToPackageJson(jsrJson: JsrJson): PackageJson { return { name: jsrJson.name, version: jsrJson.version, @@ -179,7 +186,9 @@ export async function jsrJsonToPackageJson(jsrJson: JsrJson) { exports: jsrJson.exports && convertExports(jsrJson.exports), }; - function convertExports(exports: string | Record) { + function convertExports( + exports: string | Record, + ): string | Record { if (typeof exports === 'string') return exports; const convertedExports: Record = {}; @@ -194,7 +203,7 @@ export async function jsrJsonToPackageJson(jsrJson: JsrJson) { } } -export async function version({ cwd = process.cwd() } = {}) { +export async function version({ cwd = process.cwd() } = {}): Promise { let version = (await getPackageJson({ cwd }))?.version; if (!version) { diff --git a/src/utils/rollback.ts b/src/utils/rollback.ts index 2d0e982..b8d4caa 100644 --- a/src/utils/rollback.ts +++ b/src/utils/rollback.ts @@ -6,13 +6,13 @@ const rollbacks: { fn: Rollback; ctx: unknown }[] = []; export function addRollback( rollback: Rollback, context: Ctx, -) { +): void { rollbacks.push({ fn: rollback, ctx: context }); } let called = false; -export async function rollback() { +export async function rollback(): Promise { if (called) return void 0; called = true; diff --git a/tests/utils/cli.ts b/tests/utils/cli.ts index 1bc2eed..1522864 100644 --- a/tests/utils/cli.ts +++ b/tests/utils/cli.ts @@ -43,7 +43,7 @@ export class CliController { } } - private capture(source: Source, data: unknown) { + private capture(source: Source, data: unknown): void { const msg = stripVTControlCharacters(`${data}`); this[source] += msg; @@ -52,7 +52,7 @@ export class CliController { } } - write(data: string) { + write(data: string): void { this.resetOutput(); if ((this.stdin as Readable).readable) { @@ -62,16 +62,16 @@ export class CliController { } } - resetOutput() { + resetOutput(): void { this.stdout = ''; this.stderr = ''; } - waitForStdout(expected: string) { + waitForStdout(expected: string): Promise { return this.waitForOutput(expected, 'stdout', this.waitForStdout); } - waitForStderr(expected: string) { + waitForStderr(expected: string): Promise { return this.waitForOutput(expected, 'stderr', this.waitForStderr); } @@ -79,7 +79,7 @@ export class CliController { expected: string, source: Source, caller: Parameters[1], - ) { + ): Promise { const error = new Error('Timeout'); Error.captureStackTrace(error, caller); @@ -120,7 +120,13 @@ export async function runPubmCli( command: string, _options?: Partial, ...args: string[] -) { +): Promise<{ + controller: CliController; + exitCode: number | undefined; + stdout: string; + stderr: string; + waitForClose: () => Promise; +}> { let options = _options; if (typeof _options === 'string') { @@ -149,7 +155,7 @@ export async function runPubmCli( function output() { return { controller, - exitCode: subprocess?.exitCode, + exitCode: subprocess?.exitCode ?? undefined, stdout: controller.stdout || '', stderr: controller.stderr || '', waitForClose: () => isDone,