diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json index 646426373..6a5d84375 100644 --- a/npm-shrinkwrap.json +++ b/npm-shrinkwrap.json @@ -108,7 +108,7 @@ "vip-wp": "dist/bin/vip-wp.js" }, "devDependencies": { - "@automattic/eslint-plugin-wpvip": "0.11.0", + "@automattic/eslint-plugin-wpvip": "0.12.0", "@babel/cli": "7.24.7", "@babel/core": "7.24.7", "@babel/preset-env": "7.24.7", @@ -206,9 +206,9 @@ } }, "node_modules/@automattic/eslint-plugin-wpvip": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/@automattic/eslint-plugin-wpvip/-/eslint-plugin-wpvip-0.11.0.tgz", - "integrity": "sha512-GfSGo2KbrRSPmmklL5YRiVONCFDQidF6agv7x9xU8UEmEw6jPNgndrD4yO7KCoEXX4OUYRDi9bZx1afky1TYng==", + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/@automattic/eslint-plugin-wpvip/-/eslint-plugin-wpvip-0.12.0.tgz", + "integrity": "sha512-ARF+Nj0HBHeaTPoWDA+BynaEergBrtHKDoYqIHtLWJEe7xMNRedB3Q4+lo1OuTZGA3ggBwMmOy5OU0izQwPpog==", "dev": true, "dependencies": { "@babel/eslint-parser": "7.24.5", @@ -13585,9 +13585,9 @@ } }, "@automattic/eslint-plugin-wpvip": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/@automattic/eslint-plugin-wpvip/-/eslint-plugin-wpvip-0.11.0.tgz", - "integrity": "sha512-GfSGo2KbrRSPmmklL5YRiVONCFDQidF6agv7x9xU8UEmEw6jPNgndrD4yO7KCoEXX4OUYRDi9bZx1afky1TYng==", + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/@automattic/eslint-plugin-wpvip/-/eslint-plugin-wpvip-0.12.0.tgz", + "integrity": "sha512-ARF+Nj0HBHeaTPoWDA+BynaEergBrtHKDoYqIHtLWJEe7xMNRedB3Q4+lo1OuTZGA3ggBwMmOy5OU0izQwPpog==", "dev": true, "requires": { "@babel/eslint-parser": "7.24.5", diff --git a/package.json b/package.json index 59f8d30b3..c6156ff72 100644 --- a/package.json +++ b/package.json @@ -107,7 +107,7 @@ }, "homepage": "https://github.com/Automattic/vip#readme", "devDependencies": { - "@automattic/eslint-plugin-wpvip": "0.11.0", + "@automattic/eslint-plugin-wpvip": "0.12.0", "@babel/cli": "7.24.7", "@babel/core": "7.24.7", "@babel/preset-env": "7.24.7", diff --git a/src/commands/backup-db.ts b/src/commands/backup-db.ts index d1a66ca05..c28477c0b 100644 --- a/src/commands/backup-db.ts +++ b/src/commands/backup-db.ts @@ -87,18 +87,18 @@ async function createBackupJob( appId: number, envId: number ) { // Library for a possible command in the future: vip backup db @app.env export class BackupDBCommand { - app: App; - env: AppEnvironment; - job?: Job; - jobStatus?: string; - jobAge?: number; - backupName?: string; - silent?: boolean; - steps = { + public app: App; + public env: AppEnvironment; + public job?: Job; + public jobStatus?: string; + public jobAge?: number; + public backupName?: string; + public silent?: boolean; + public steps = { PREPARE: 'prepare', GENERATE: 'generate', }; - track: CommandTracker; + public track: CommandTracker; private progressTracker: ProgressTracker; constructor( app: App, env: AppEnvironment, trackerFn: CommandTracker = async () => {} ) { @@ -111,14 +111,14 @@ export class BackupDBCommand { this.track = trackerFn; } - log( msg: string ) { + public log( msg: string ) { if ( this.silent ) { return; } console.log( msg ); } - isDone( job?: Job ) { + private isDone( job?: Job ) { return ! job?.inProgressLock; } @@ -127,12 +127,12 @@ export class BackupDBCommand { * * @return {void} */ - stopProgressTracker() { + private stopProgressTracker() { this.progressTracker.print(); this.progressTracker.stopPrinting(); } - async loadBackupJob() { + public async loadBackupJob() { this.job = await getBackupJob( this.app.id ?? 0, this.env.id ?? 0 ); this.backupName = this.job?.metadata?.find( meta => meta?.name === 'backupName' )?.value ?? 'Unknown'; @@ -148,7 +148,7 @@ export class BackupDBCommand { return this.job; } - async run( silent = false ) { + public async run( silent = false ) { this.silent = silent; await this.loadBackupJob(); diff --git a/src/commands/phpmyadmin.ts b/src/commands/phpmyadmin.ts index eb3a8889c..20a72e9cf 100644 --- a/src/commands/phpmyadmin.ts +++ b/src/commands/phpmyadmin.ts @@ -118,11 +118,11 @@ async function getPhpMyAdminStatus( appId: number, envId: number ): Promise< str } export class PhpMyAdminCommand { - app: App; - env: AppEnvironment; - silent?: boolean; - track: CommandTracker; - steps = { + private app: App; + private env: AppEnvironment; + private silent?: boolean; + private track: CommandTracker; + private steps = { ENABLE: 'enable', GENERATE: 'generate', }; @@ -138,28 +138,28 @@ export class PhpMyAdminCommand { ] ); } - log( msg: string ): void { + private log( msg: string ): void { if ( this.silent ) { return; } console.log( msg ); } - stopProgressTracker(): void { + private stopProgressTracker(): void { this.progressTracker.print(); this.progressTracker.stopPrinting(); } - async openUrl( url: string ): Promise< void > { + public async openUrl( url: string ): Promise< void > { const { default: open } = await import( 'open' ); void open( url, { wait: false } ); } - async getStatus(): Promise< string > { + public async getStatus(): Promise< string > { return await getPhpMyAdminStatus( this.app.id as number, this.env.id as number ); } - async maybeEnablePhpMyAdmin(): Promise< void > { + private async maybeEnablePhpMyAdmin(): Promise< void > { const status = await this.getStatus(); if ( ! [ 'running', 'enabled' ].includes( status ) ) { await enablePhpMyAdmin( this.env.id as number ); @@ -170,7 +170,7 @@ export class PhpMyAdminCommand { } } - async run( silent = false ): Promise< void > { + public async run( silent = false ): Promise< void > { this.silent = silent; if ( ! this.app.id ) { diff --git a/src/lib/analytics/clients/pendo.ts b/src/lib/analytics/clients/pendo.ts index 72dba8374..c6671ba97 100644 --- a/src/lib/analytics/clients/pendo.ts +++ b/src/lib/analytics/clients/pendo.ts @@ -23,7 +23,7 @@ export default class Pendo implements AnalyticsClient { private userId: string; private context: Env & Record< string, unknown > & { userId?: string }; - static readonly ENDPOINT = '/pendo'; + public static readonly ENDPOINT = '/pendo'; constructor( options: PendoOptions ) { this.eventPrefix = options.eventPrefix; @@ -32,7 +32,7 @@ export default class Pendo implements AnalyticsClient { this.context = { ...options.env }; } - async trackEvent( + public async trackEvent( eventName: string, eventProps: Record< string, unknown > = {} ): Promise< Response | false > { @@ -58,7 +58,10 @@ export default class Pendo implements AnalyticsClient { } } - async send( eventName: string, eventProps: Record< string, unknown > ): Promise< Response > { + public async send( + eventName: string, + eventProps: Record< string, unknown > + ): Promise< Response > { const body = { context: this.context, event: eventName, diff --git a/src/lib/analytics/clients/tracks.ts b/src/lib/analytics/clients/tracks.ts index e6b156090..9fa49e62a 100644 --- a/src/lib/analytics/clients/tracks.ts +++ b/src/lib/analytics/clients/tracks.ts @@ -30,7 +30,7 @@ export default class Tracks implements AnalyticsClient { private userAgent: string; private baseParams: BaseParams; - static readonly ENDPOINT = 'https://public-api.wordpress.com/rest/v1.1/tracks/record'; + public static readonly ENDPOINT = 'https://public-api.wordpress.com/rest/v1.1/tracks/record'; constructor( userId: string, userType: string, eventPrefix: string, env: Env ) { this.eventPrefix = eventPrefix; @@ -44,7 +44,7 @@ export default class Tracks implements AnalyticsClient { }; } - async trackEvent( + public async trackEvent( name: string, eventProps: Record< string, unknown > = {} ): Promise< Response | false > { @@ -111,7 +111,7 @@ export default class Tracks implements AnalyticsClient { return false; } - send( extraParams: Record< string, unknown > ): Promise< Response > { + public send( extraParams: Record< string, unknown > ): Promise< Response > { const params = { ...this.baseParams, ...extraParams }; const method = 'POST'; diff --git a/src/lib/analytics/index.ts b/src/lib/analytics/index.ts index ec3e49ad1..24e73e615 100644 --- a/src/lib/analytics/index.ts +++ b/src/lib/analytics/index.ts @@ -23,7 +23,7 @@ export default class Analytics { this.clients = clients; } - async trackEvent( + public async trackEvent( name: string, props: Record< string, unknown > = {} ): Promise< ( Response | false )[] > { diff --git a/src/lib/backup-storage-availability/backup-storage-availability.ts b/src/lib/backup-storage-availability/backup-storage-availability.ts index 8ee1d7b3a..fc5dce4bc 100644 --- a/src/lib/backup-storage-availability/backup-storage-availability.ts +++ b/src/lib/backup-storage-availability/backup-storage-availability.ts @@ -17,13 +17,13 @@ export interface PromptStatus { } export class BackupStorageAvailability { - archiveSize: number; + private archiveSize: number; constructor( archiveSize: number ) { this.archiveSize = archiveSize; } - static createFromDbCopyJob( job: Job ): BackupStorageAvailability { + public static createFromDbCopyJob( job: Job ): BackupStorageAvailability { const bytesWrittenMeta = job.metadata?.find( meta => meta?.name === 'bytesWritten' ); if ( ! bytesWrittenMeta?.value ) { throw new Error( 'Meta not found' ); @@ -32,7 +32,7 @@ export class BackupStorageAvailability { return new BackupStorageAvailability( Number( bytesWrittenMeta.value ) ); } - getDockerStorageKiBRaw(): string | undefined { + public getDockerStorageKiBRaw(): string | undefined { return exec( `docker run --rm alpine df -k`, { silent: true } ) .grep( /\/dev\/vda1/ ) .head( { '-n': 1 } ) @@ -40,7 +40,7 @@ export class BackupStorageAvailability { .split( ' ' )[ 3 ]; } - getDockerStorageAvailable(): number { + public getDockerStorageAvailable(): number { const kiBLeft = this.getDockerStorageKiBRaw(); if ( ! kiBLeft || Number.isNaN( Number( kiBLeft ) ) ) { @@ -50,48 +50,48 @@ export class BackupStorageAvailability { return Number( kiBLeft ) * 1024; } - bytesToHuman( bytes: number ) { + public bytesToHuman( bytes: number ) { return formatMetricBytes( bytes ); } - async getStorageAvailableInVipPath() { + public async getStorageAvailableInVipPath() { const vipDir = path.join( xdgBasedir.data ?? os.tmpdir(), 'vip' ); const diskSpace = await checkDiskSpace( vipDir ); return diskSpace.free; } - getReserveSpace(): number { + public getReserveSpace(): number { return oneGiBInBytes; } - getSqlSize(): number { + public getSqlSize(): number { // We estimated that it'd be about 3.5x the archive size. return this.archiveSize * 3.5; } - getArchiveSize(): number { + public getArchiveSize(): number { return this.archiveSize; } - getStorageRequiredInMainMachine(): number { + public getStorageRequiredInMainMachine(): number { return this.getArchiveSize() + this.getSqlSize() + this.getReserveSpace(); } - getStorageRequiredInDockerMachine(): number { + public getStorageRequiredInDockerMachine(): number { return this.getSqlSize() + this.getReserveSpace(); } - async isStorageAvailableInMainMachine(): Promise< boolean > { + public async isStorageAvailableInMainMachine(): Promise< boolean > { return ( await this.getStorageAvailableInVipPath() ) > this.getStorageRequiredInMainMachine(); } - isStorageAvailableInDockerMachine(): boolean { + public isStorageAvailableInDockerMachine(): boolean { return this.getDockerStorageAvailable() > this.getStorageRequiredInDockerMachine(); } // eslint-disable-next-line id-length - async validateAndPromptDiskSpaceWarningForBackupImport(): Promise< PromptStatus > { + public async validateAndPromptDiskSpaceWarningForBackupImport(): Promise< PromptStatus > { const isStorageAvailable = ( await this.getStorageAvailableInVipPath() ) > this.getArchiveSize(); if ( ! isStorageAvailable ) { @@ -115,7 +115,7 @@ export class BackupStorageAvailability { } // eslint-disable-next-line id-length - async validateAndPromptDiskSpaceWarningForDevEnvBackupImport(): Promise< PromptStatus > { + public async validateAndPromptDiskSpaceWarningForDevEnvBackupImport(): Promise< PromptStatus > { let storageAvailableInMainMachinePrompted = false; // there's two prompts, so as long as one prompt is shown, we need to set isPromptShown diff --git a/src/lib/cli/format.ts b/src/lib/cli/format.ts index b269be9fe..370a0dc2d 100644 --- a/src/lib/cli/format.ts +++ b/src/lib/cli/format.ts @@ -177,19 +177,19 @@ export function capitalize( str: unknown ): string { export const RUNNING_SPRITE_GLYPHS = [ '⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏' ]; export class RunningSprite { - count: number; + private count: number; constructor() { this.count = 0; } - next() { + public next() { if ( ++this.count >= RUNNING_SPRITE_GLYPHS.length ) { this.count = 0; } } - toString() { + public toString() { const glyph = RUNNING_SPRITE_GLYPHS[ this.count ]; this.next(); // TODO: throttle return glyph; diff --git a/src/lib/cli/progress.ts b/src/lib/cli/progress.ts index 309be2b5f..26ab8dc36 100644 --- a/src/lib/cli/progress.ts +++ b/src/lib/cli/progress.ts @@ -31,22 +31,22 @@ export interface StepFromServer { } export class ProgressTracker { - hasFailure: boolean; - hasPrinted: boolean; - printInterval: NodeJS.Timeout | undefined; + public hasFailure: boolean; + public hasPrinted: boolean; + public printInterval: NodeJS.Timeout | undefined; // Track the state of each step - stepsFromCaller: Map< string, Step >; - stepsFromServer: Map< string, Step >; + public stepsFromCaller: Map< string, Step >; + public stepsFromServer: Map< string, Step >; // Spinnerz go brrrr - runningSprite: RunningSprite; + public runningSprite: RunningSprite; // This gets printed before the step status - prefix: string; + public prefix: string; // This gets printed after the step status - suffix: string; + public suffix: string; /** * This determines from which step should we display the steps @@ -55,7 +55,7 @@ export class ProgressTracker { * * And we don't want to repeatedly display the steps that has finished. */ - displayFromStep = 0; + public displayFromStep = 0; constructor( steps: StepConstructorParam[] ) { this.runningSprite = new RunningSprite(); @@ -67,18 +67,18 @@ export class ProgressTracker { this.suffix = ''; } - getSteps(): Map< string, Step > { + public getSteps(): Map< string, Step > { return new Map( [ ...this.stepsFromCaller, ...this.stepsFromServer ] ); } - mapSteps( steps: StepConstructorParam[] ): Map< string, Step > { + public mapSteps( steps: StepConstructorParam[] ): Map< string, Step > { return steps.reduce( ( map, { id, name, status } ) => { map.set( id, { id, name, status: status ?? StepStatus.PENDING } ); return map; }, new Map< string, Step >() ); } - setUploadPercentage( percentage: string ) { + public setUploadPercentage( percentage: string ) { const uploadStep = this.stepsFromCaller.get( 'upload' ); if ( ! uploadStep ) { return; @@ -86,7 +86,7 @@ export class ProgressTracker { this.stepsFromCaller.set( 'upload', { ...uploadStep, percentage } ); } - setProgress( progress: string ) { + public setProgress( progress: string ) { const step = this.getCurrentStep(); if ( ! step ) { return; @@ -95,7 +95,7 @@ export class ProgressTracker { this.stepsFromCaller.set( step.id, { ...step, progress } ); } - setStepsFromServer( steps: StepFromServer[] ) { + public setStepsFromServer( steps: StepFromServer[] ) { const formattedSteps: Step[] = steps.map( ( { name, status }, index ) => ( { id: `server-${ index }-${ name }`, name, @@ -116,7 +116,7 @@ export class ProgressTracker { this.stepsFromServer = this.mapSteps( formattedSteps ); } - getNextStep(): Step | undefined { + public getNextStep(): Step | undefined { if ( this.allStepsSucceeded() ) { return undefined; } @@ -124,7 +124,7 @@ export class ProgressTracker { return steps.find( ( { status } ) => status === StepStatus.PENDING ); } - getCurrentStep(): Step | undefined { + public getCurrentStep(): Step | undefined { if ( this.allStepsSucceeded() ) { return undefined; } @@ -133,19 +133,19 @@ export class ProgressTracker { return steps.find( ( { status } ) => status === StepStatus.RUNNING ); } - stepRunning( stepId: string ): void { + public stepRunning( stepId: string ): void { this.setStatusForStepId( stepId, StepStatus.RUNNING ); } - stepFailed( stepId: string ): void { + public stepFailed( stepId: string ): void { this.setStatusForStepId( stepId, StepStatus.FAILED ); } - stepSkipped( stepId: string ): void { + public stepSkipped( stepId: string ): void { this.setStatusForStepId( stepId, StepStatus.SKIPPED ); } - stepSuccess( stepId: string ) { + public stepSuccess( stepId: string ) { this.setStatusForStepId( stepId, StepStatus.SUCCESS ); // The stepSuccess helper automatically sets the next step to "running" const nextStep = this.getNextStep(); @@ -154,11 +154,11 @@ export class ProgressTracker { } } - allStepsSucceeded(): boolean { + public allStepsSucceeded(): boolean { return [ ...this.getSteps().values() ].every( ( { status } ) => status === StepStatus.SUCCESS ); } - setStatusForStepId( stepId: string, status: StepStatus ) { + public setStatusForStepId( stepId: string, status: StepStatus ) { const step = this.stepsFromCaller.get( stepId ); if ( ! step ) { // Only allowed to update existing steps with this method @@ -179,20 +179,20 @@ export class ProgressTracker { } ); } - startPrinting( prePrintCallback: () => unknown = () => {} ): void { + public startPrinting( prePrintCallback: () => unknown = () => {} ): void { this.printInterval = setInterval( () => { prePrintCallback(); this.print(); }, PRINT_INTERVAL ); } - stopPrinting(): void { + public stopPrinting(): void { if ( this.printInterval ) { clearInterval( this.printInterval ); } } - async handleContinuePrompt< PromptReturn >( + public async handleContinuePrompt< PromptReturn >( prompt: ( setPromptShown: () => void ) => Promise< PromptReturn > ): Promise< PromptReturn > { this.print(); @@ -242,7 +242,7 @@ export class ProgressTracker { return returnValue; } - print( { clearAfter = false }: { clearAfter?: boolean } = {} ): void { + public print( { clearAfter = false }: { clearAfter?: boolean } = {} ): void { if ( ! this.hasPrinted ) { this.hasPrinted = true; singleLogLine.clear(); diff --git a/src/lib/keychain/insecure.ts b/src/lib/keychain/insecure.ts index 94aa7338f..c9c045e37 100644 --- a/src/lib/keychain/insecure.ts +++ b/src/lib/keychain/insecure.ts @@ -12,7 +12,7 @@ export default class Insecure implements Keychain { this.configstore = new Configstore( this.file ); } - getPassword( service: string ): Promise< string | null > { + public getPassword( service: string ): Promise< string | null > { try { const value: unknown = this.configstore.get( service ); if ( null === value || undefined === value ) { @@ -22,25 +22,25 @@ export default class Insecure implements Keychain { // eslint-disable-next-line @typescript-eslint/no-base-to-string return Promise.resolve( value.toString() ); // NOSONAR } catch ( err ) { - return Promise.reject( err ); + return Promise.reject( err as Error ); } } - setPassword( service: string, password: string ): Promise< boolean > { + public setPassword( service: string, password: string ): Promise< boolean > { try { this.configstore.set( service, password ); return Promise.resolve( true ); } catch ( err ) { - return Promise.reject( err ); + return Promise.reject( err as Error ); } } - deletePassword( service: string ): Promise< boolean > { + public deletePassword( service: string ): Promise< boolean > { try { this.configstore.delete( service ); return Promise.resolve( true ); } catch ( err ) { - return Promise.reject( err ); + return Promise.reject( err as Error ); } } } diff --git a/src/lib/keychain/secure.ts b/src/lib/keychain/secure.ts index 5dda77355..f18297de7 100644 --- a/src/lib/keychain/secure.ts +++ b/src/lib/keychain/secure.ts @@ -3,16 +3,16 @@ import keytar from '@postman/node-keytar'; import type { Keychain } from './keychain'; export default class Secure implements Keychain { - getPassword( service: string ): Promise< string | null > { + public getPassword( service: string ): Promise< string | null > { return keytar.getPassword( service, service ); } - async setPassword( service: string, password: string ): Promise< boolean > { + public async setPassword( service: string, password: string ): Promise< boolean > { await keytar.setPassword( service, service, password ); return true; } - deletePassword( service: string ): Promise< boolean > { + public deletePassword( service: string ): Promise< boolean > { return keytar.deletePassword( service, service ); } } diff --git a/src/lib/media-import/progress.ts b/src/lib/media-import/progress.ts index e8739a9dd..7b9788d10 100644 --- a/src/lib/media-import/progress.ts +++ b/src/lib/media-import/progress.ts @@ -12,19 +12,19 @@ type MediaImportStatus = Pick< >; export class MediaImportProgressTracker { - hasFailure: boolean; - hasPrinted: boolean; - printInterval: NodeJS.Timeout | undefined; - status: MediaImportStatus; + public hasFailure: boolean; + public hasPrinted: boolean; + public printInterval: NodeJS.Timeout | undefined; + public status: MediaImportStatus; // Spinnerz go brrrr - runningSprite: RunningSprite; + public runningSprite: RunningSprite; // This gets printed before the step status - prefix: string; + public prefix: string; // This gets printed after the step status - suffix: string; + public suffix: string; constructor( status: MediaImportStatus ) { this.runningSprite = new RunningSprite(); @@ -35,27 +35,27 @@ export class MediaImportProgressTracker { this.hasPrinted = false; } - setStatus( status: MediaImportStatus ) { + public setStatus( status: MediaImportStatus ) { if ( 'FAILED' === status.status ) { this.hasFailure = true; } this.status = { ...status }; } - startPrinting( prePrintCallback = (): void => {} ): void { + public startPrinting( prePrintCallback = (): void => {} ): void { this.printInterval = setInterval( () => { prePrintCallback(); this.print(); }, PRINT_INTERVAL ); } - stopPrinting(): void { + public stopPrinting(): void { if ( this.printInterval ) { clearInterval( this.printInterval ); } } - print( { clearAfter = false }: { clearAfter?: boolean } = {} ): void { + public print( { clearAfter = false }: { clearAfter?: boolean } = {} ): void { if ( ! this.hasPrinted ) { this.hasPrinted = true; singleLogLine.clear(); diff --git a/src/lib/token.ts b/src/lib/token.ts index 0168db7bd..c6b56c099 100644 --- a/src/lib/token.ts +++ b/src/lib/token.ts @@ -44,7 +44,7 @@ export default class Token { } } - valid(): boolean { + public valid(): boolean { if ( ! this._id ) { return false; } @@ -61,7 +61,7 @@ export default class Token { return now > this.iat && now < this.exp; } - expired(): boolean { + public expired(): boolean { if ( ! this.exp ) { return false; } @@ -70,15 +70,15 @@ export default class Token { return now > this.exp; } - get id(): number { + public get id(): number { return this._id ?? NaN; } - get raw(): string { + public get raw(): string { return this._raw ?? ''; } - static async uuid(): Promise< string > { + public static async uuid(): Promise< string > { const service = Token.getServiceName( '-uuid' ); let _uuid = await keychain.getPassword( service ); @@ -90,31 +90,31 @@ export default class Token { return _uuid; } - static async setUuid( _uuid: string ): Promise< void > { + public static async setUuid( _uuid: string ): Promise< void > { const service = Token.getServiceName( '-uuid' ); await keychain.setPassword( service, _uuid ); } - static set( token: string ): Promise< boolean > { + public static set( token: string ): Promise< boolean > { const service = Token.getServiceName(); return keychain.setPassword( service, token ); } - static async get(): Promise< Token > { + public static async get(): Promise< Token > { const service = Token.getServiceName(); const token = ( await keychain.getPassword( service ) ) ?? ''; return new Token( token ); } - static purge(): Promise< boolean > { + public static purge(): Promise< boolean > { const service = Token.getServiceName(); return keychain.deletePassword( service ); } - static getServiceName( modifier: string = '' ): string { + public static getServiceName( modifier: string = '' ): string { let service = SERVICE; if ( PRODUCTION_API_HOST !== API_HOST ) {