Skip to content

Commit

Permalink
Simplify new and login commands
Browse files Browse the repository at this point in the history
  • Loading branch information
motdotla committed Jun 6, 2022
1 parent 3338904 commit 86230e2
Show file tree
Hide file tree
Showing 5 changed files with 163 additions and 213 deletions.
55 changes: 55 additions & 0 deletions src/services/abort-service.ts
@@ -0,0 +1,55 @@
import chalk from 'chalk'
import {vars} from '../vars'
import {LogService} from '../services/log-service'

interface AbortServiceAttrs {
cmd;
}

class AbortService {
public cmd;
public log;

constructor(attrs: AbortServiceAttrs = {} as AbortServiceAttrs) {
this.cmd = attrs.cmd
this.log = new LogService({cmd: attrs.cmd})
}

missingEnvVault(): void {
this.log.plain(`${chalk.red('x')} Aborted.`)
this.cmd.error(`Missing ${vars.vaultFilename} (${vars.vaultKey}).`, {
code: 'MISSING_DOTENV_VAULT',
ref: '',
suggestions: [`Missing ${vars.vaultFilename} (${vars.vaultKey}). To create it, run: npx dotenv-vault@latest new`],
})
}

emptyEnvVault(): void {
this.log.plain(`${chalk.red('x')} Aborted.`)
this.cmd.error(`Empty ${vars.vaultFilename} (${vars.vaultKey}).`, {
code: 'EMPTY_DOTENV_VAULT',
ref: '',
suggestions: [`Empty ${vars.vaultFilename} (${vars.vaultKey}). To fix it, run: npx dotenv-vault@latest new`],
})
}

invalidEnvVault(): void {
this.log.plain(`${chalk.red('x')} Aborted.`)
this.cmd.error(`Invalid ${vars.vaultFilename} (${vars.vaultKey}).`, {
code: 'INVALID_DOTENV_VAULT',
ref: '',
suggestions: [`Invalid ${vars.vaultFilename} (${vars.vaultKey}). To fix it, run: npx dotenv-vault@latest new`],
})
}

existingEnvVault(): void {
this.log.plain(`${chalk.red('x')} Aborted.`)
this.cmd.error(`Existing ${vars.vaultFilename} (${vars.vaultKey}).`, {
code: 'EXISTING_DOTENV_VAULT',
ref: '',
suggestions: [`Existing ${vars.vaultFilename} (${vars.vaultKey}). To fix it, delete ${vars.vaultFilename} and then run: npx dotenv-vault@latest new`],
})
}
}

export {AbortService}
40 changes: 20 additions & 20 deletions src/services/login-service.ts
@@ -1,49 +1,50 @@
import * as crypto from 'node:crypto'
import chalk from 'chalk'
import axios, {AxiosRequestConfig} from 'axios'
import {writeFileSync} from 'node:fs'
import {existsSync, writeFileSync} from 'node:fs'
import {vars} from '../vars'
import {CliUx} from '@oclif/core'
import {AppendToDockerignoreService} from '../services/append-to-dockerignore-service'
import {AppendToGitignoreService} from '../services/append-to-gitignore-service'
import {AppendToNpmignoreService} from '../services/append-to-npmignore-service'
import {LogService} from '../services/log-service'
import {AbortService} from '../services/abort-service'

interface LoginServiceAttrs {
cmd;
}

class LoginService {
public cmd;
public log;
public requestUid;
public controller;
public abort;

constructor(attrs: LoginServiceAttrs = {} as LoginServiceAttrs) {
this.cmd = attrs.cmd
this.log = new LogService({cmd: attrs.cmd})
this.abort = new AbortService({cmd: attrs.cmd})

const rand = crypto.randomBytes(32).toString('hex')
this.requestUid = `req_${rand}`
}

async run(): Promise<void> {
this.log.local(chalk.dim('⬢ dotenv-vault login'))

new AppendToDockerignoreService().run()
new AppendToGitignoreService().run()
new AppendToNpmignoreService().run()

// Step 1
this.log.local('')
this.log.local(chalk.dim('▼ step 1: open url'))
this.log.local(`opened ${chalk.blue.underline(this.loginUrl)}`)

CliUx.ux.open(this.loginUrl)
if (vars.missingEnvVault) {
this.abort.missingEnvVault()
}

// Step 2
this.log.local('')
this.log.local(chalk.dim('▼ step 2: wait for login'))
if (vars.emptyEnvVault) {
this.abort.emptyEnvVault()
}

CliUx.ux.action.start(`${chalk.dim(this.log.pretextLocal)}waiting for login`)
CliUx.ux.open(this.loginUrl)
CliUx.ux.action.start(`${chalk.dim(this.log.pretextLocal)}Waiting for login`)
this.check()
}

Expand Down Expand Up @@ -74,16 +75,11 @@ class LoginService {
if (resp.status < 300) {
// Step 3
CliUx.ux.action.stop()
this.log.local('')
this.log.local(chalk.dim('▼ step 3: generate .env.me credential'))

const meUid = resp.data.data.meUid
writeFileSync('.env.me', `DOTENV_ME=${meUid}`)

this.log.local(`generated .env.me credential with DOTENV_ME=${meUid.slice(0, 9)}...`)
this.log.local('')
this.log.plain(`${chalk.green('✓')} Done.`)
this.log.local(`Logged in as .env.me (DOTENV_ME=${meUid.slice(0, 9)}...)`)
this.log.plain('')
this.log.plain(`Next run ${chalk.bold('npx dotenv-vault@latest pull')} or ${chalk.bold('npx dotenv-vault@latest push')}`)
} else {
// 404 - keep trying
await CliUx.ux.wait(2000) // check every 2 seconds
Expand All @@ -99,6 +95,10 @@ class LoginService {
get checkUrl(): string {
return `${vars.apiUrl}/check?vaultUid=${vars.vaultValue}&requestUid=${this.requestUid}`
}

get existingEnvVault(): boolean {
return existsSync(vars.vaultFilename)
}
}

export {LoginService}
140 changes: 28 additions & 112 deletions src/services/new-service.ts
@@ -1,12 +1,12 @@
import * as dotenv from 'dotenv'
import chalk from 'chalk'
import {vars} from '../vars'
import {existsSync, writeFileSync} from 'node:fs'
import {writeFileSync} from 'node:fs'
import {CliUx} from '@oclif/core'
import {AppendToDockerignoreService} from '../services/append-to-dockerignore-service'
import {AppendToGitignoreService} from '../services/append-to-gitignore-service'
import {AppendToNpmignoreService} from '../services/append-to-npmignore-service'
import {LogService} from '../services/log-service'
import {AbortService} from '../services/abort-service'

interface NewServiceAttrs {
cmd;
Expand All @@ -17,86 +17,61 @@ class NewService {
public cmd;
public dotenvProject;
public log;
public abort;

constructor(attrs: NewServiceAttrs = {} as NewServiceAttrs) {
this.cmd = attrs.cmd
this.dotenvProject = attrs.dotenvProject
this.log = new LogService({cmd: attrs.cmd})
this.abort = new AbortService({cmd: attrs.cmd})
}

async run(): Promise<void> {
this.log.local(chalk.dim('⬢ dotenv-vault new'))

new AppendToDockerignoreService().run()
new AppendToGitignoreService().run()
new AppendToNpmignoreService().run()

// Step 1
this.log.local('')
this.log.local(chalk.dim('▼ step 1: check for files'))

if (this.existingEnv) {
this.log.local(`.env ${chalk.dim('(exists)')}`)
} else {
this.log.local(`.env ${chalk.green('(created)')}`)
this._writeEnv()
}

if (this.existingEnvVault) {
this.log.local(`${vars.vaultFilename} ${chalk.dim('(exists)')}`)
} else {
this.log.local(`${vars.vaultFilename} ${chalk.green('(created)')}`)
this._writeEnvVault()
if (vars.missingEnvVault) {
writeFileSync(vars.vaultFilename, `${vars.vaultKey}= # Generate vault identifiers at ${this.url}`)
}

// Step 2 B
if (this.dotenvProject) {
// Step 2 A
this.log.local('')
this.log.local(chalk.dim('▼ step 2: open url'))
this.log.local('Skipping')

// Step 3
this.log.local('')
this.log.local(chalk.dim(`▼ step 3: enter ${vars.vaultFilename} identifier`))
this.log.local('Adding')

if (this.invalidIdentifier(this.dotenvProject)) {
this.abortWithInvalidIdentifier()
if (vars.invalidVaultValue(this.dotenvProject)) {
this.abort.invalidEnvVault()
}

this._logWritingEnvVault()
CliUx.ux.action.start(`${chalk.dim(this.log.pretextLocal)}Adding ${vars.vaultFilename} (${vars.vaultKey})`)
await CliUx.ux.wait(1000)
CliUx.ux.action.stop()
writeFileSync(vars.vaultFilename, `${vars.vaultKey}=${this.dotenvProject}`)
this._logCompleted()
this.log.local(`Added to .env.project (${vars.vaultKey}=${this.dotenvProject.slice(0, 9)}...)`)
this.log.plain('')
this.log.plain(`Next run ${chalk.bold('npx dotenv-vault@latest login')}`)

return
}

// Step 2 A
this.log.local('')
this.log.local(chalk.dim('▼ step 2: open url'))
this.log.local(`Open ${chalk.blue.underline(this.urlWithProjectName)} in your browser`)

// Step 3
this.log.local('')
this.log.local(chalk.dim(`▼ step 3: enter ${vars.vaultFilename} identifier`))

// Step 3 check - when .env.vault already exists with value
if (this.vaultValue.length === 68) {
this.abortWithAlreadyExistingVault()
if (vars.existingVaultValue) {
this.abort.existingEnvVault()
}

const dotenvProject = await CliUx.ux.prompt(`${chalk.dim(this.log.pretextLocal)}What is your ${vars.vaultFilename} identifier? ${vars.vaultKey}=`, {type: 'mask'})
if (this.invalidIdentifier(dotenvProject)) {
this.abortWithInvalidIdentifier()
CliUx.ux.open(this.urlWithProjectName)
const dotenvProject = await CliUx.ux.prompt(`${chalk.dim(this.log.pretextLocal)}Enter the ${vars.vaultFilename} identifier? ${vars.vaultKey}=`)
if (vars.invalidVaultValue(dotenvProject)) {
this.abort.invalidEnvVault()
}

this._logWritingEnvVault()
CliUx.ux.action.start(`${chalk.dim(this.log.pretextLocal)}Adding ${vars.vaultFilename} (${vars.vaultKey})`)
await CliUx.ux.wait(1000)
CliUx.ux.action.stop()
writeFileSync(vars.vaultFilename, `${vars.vaultKey}=${dotenvProject}`)
this._logCompleted()
}
this.log.local(`Added to .env.project (${vars.vaultKey}=${dotenvProject.slice(0, 9)}...)`)
this.log.plain('')
this.log.plain(`Next run ${chalk.bold('npx dotenv-vault@latest login')}`)

get vaultValue(): string {
return (dotenv.config({path: vars.vaultFilename}).parsed || {})[vars.vaultKey]
writeFileSync(vars.vaultFilename, `${vars.vaultKey}=${dotenvProject}`)
}

get url(): string {
Expand All @@ -110,65 +85,6 @@ class NewService {

return `${this.url}?project_name=${projectName}`
}

get existingEnv(): boolean {
return existsSync('.env')
}

get existingEnvVault(): boolean {
return existsSync(vars.vaultFilename)
}

abortWithInvalidIdentifier(): void {
this.log.plain(`${chalk.red('x')} Aborted.`)

this.cmd.error(`Invalid ${vars.vaultFilename} identifier.`, {
code: 'IDENTIFIER_ERR',
ref: '',
suggestions: [`Generate vault identifiers at ${this.url}`],
})
}

abortWithAlreadyExistingVault(): void {
this.log.plain(`${chalk.red('x')} Aborted.`)

this.cmd.error(`Invalid ${vars.vaultFilename} identifier.`, {
code: 'IDENTIFIER_EXISTS',
ref: '',
suggestions: [`Identifier already exists for this project. To override it, delete ${vars.vaultFilename} and try again.`],
})
}

validIdentifier(identifier: string | any): boolean {
return identifier && identifier.length === 68
}

invalidIdentifier(identifier: string | any): boolean {
return !this.validIdentifier(identifier)
}

_logWritingEnvVault(): void {
this.log.local(chalk.green(`Added successfully to ${vars.vaultFilename}`))
this.log.local('')
}

_writeEnv(): void {
writeFileSync('.env', 'HELLO=world')
}

_writeEnvVault(): void {
writeFileSync(vars.vaultFilename, `${vars.vaultKey}= # Generate vault identifiers at ${this.url}`)
}

_logCompleted(): void {
this.log.plain(`${chalk.green('✓')} Done.`)
this.log.plain('')
this.log.plain(`Next, commit ${vars.vaultFilename} to git and run npx dotenv-vault push`)
this.log.plain('')
this.log.plain(` $ git add ${vars.vaultFilename} .gitignore`)
this.log.plain(` $ git commit -am 'Add ${vars.vaultFilename}'`)
this.log.plain(' $ npx dotenv-vault push')
}
}

export {NewService}

0 comments on commit 86230e2

Please sign in to comment.