Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 0 additions & 32 deletions .circleci/config.yml

This file was deleted.

24 changes: 0 additions & 24 deletions .eslintrc

This file was deleted.

39 changes: 39 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
module.exports = {
extends: [
'oclif',
'oclif-typescript',
],
overrides: [
{
files: ['test/**/*.ts', 'test/**/*.js'],
rules: {
'prefer-arrow-callback': 'off',
'unicorn/consistent-destructuring': 'warn',
},
},
{
files: ['examples/**/*.ts', 'examples/**/*.js'],
rules: {
'unicorn/prefer-module': 'off',
'unicorn/prefer-top-level-await': 'off',
},
},
],
plugins: ['import'],
rules: {
'@typescript-eslint/no-explicit-any': 'warn',
camelcase: 'off',
'import/namespace': 'warn',
indent: ['error', 2, {MemberExpression: 1}],
'no-useless-constructor': 'warn',
'unicorn/consistent-function-scoping': 'off',
'unicorn/import-style': 'warn',
'unicorn/no-array-for-each': 'off',
'unicorn/no-array-push-push': 'warn',
'unicorn/no-static-only-class': 'off',
'unicorn/numeric-separators-style': 'off',
'unicorn/prefer-array-some': 'warn',
'unicorn/prefer-node-protocol': 'warn',
'unicorn/prefer-string-replace-all': 'off',
},
}
1 change: 1 addition & 0 deletions .github/CODEOWNERS
35 changes: 26 additions & 9 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -1,12 +1,29 @@
# To get started with Dependabot version updates, you'll need to specify which
# package ecosystems to update and where the package manifests are located.
# Please see the documentation for all configuration options:
# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates

version: 2
updates:
- package-ecosystem: "npm"
directory: "/"
open-pull-requests-limit: 5
schedule:
- package-ecosystem: "github-actions"
directory: "/"
open-pull-requests-limit: 5
schedule:
interval: "weekly"
time: "12:00"
day: "sunday"
timezone: "America/Los_Angeles"
- package-ecosystem: "npm"
directory: "/"
open-pull-requests-limit: 5
schedule:
interval: "weekly"
time: "12:00"
day: "sunday"
timezone: "America/Los_Angeles"
groups:
dev-deps:
dependency-type: "development"
patch-dependencies:
update-types:
- "patch"
ignore:
- dependency-name: "@oclif/core"
update-types: ["version-update:semver-major"]
- dependency-name: "typescript"
update-types: ["version-update:semver-major"]
12 changes: 5 additions & 7 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,8 @@ jobs:
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
cache: yarn
- run: yarn --frozen-lockfile --network-timeout 1000000
env:
CI: true
- run: yarn test
env:
CI: true
- run: npm ci
- name: unit tests
run: npm test
- name: linting
run: npm run lint
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@
/tmp
lib/
node_modules/
package-lock.json
yarn.lock
.idea/
2 changes: 1 addition & 1 deletion .tool-versions
Original file line number Diff line number Diff line change
@@ -1 +1 @@
nodejs 20.18.3
nodejs 22.15.0
10 changes: 8 additions & 2 deletions CODEOWNERS
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
# All files require review from the Heroku Front-End Dev Tools team.

# Comment line immediately above ownership line is reserved for related GUS information.
# Please exercise caution while editing.

#GUSINFO: Heroku FE Dev Tools,Heroku CLI & Plugins
* @heroku/frontend-dev-tooling

#ECCN:Open Source
#GUSINFO:Heroku FE Dev Tools,Heroku CLI & Plugins
* @heroku/front-end
51 changes: 51 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,54 @@ Base class for Heroku CLI commands. Built off of [oclif](https://oclif.io).
[![Known Vulnerabilities](https://snyk.io/test/npm/@heroku-cli/command/badge.svg)](https://snyk.io/test/npm/@heroku-cli/command)
[![Downloads/week](https://img.shields.io/npm/dw/@heroku-cli/command.svg)](https://npmjs.org/package/@heroku-cli/command)
[![License](https://img.shields.io/npm/l/@heroku-cli/command.svg)](https://github.com/heroku/heroku-cli-command/blob/master/package.json)

## Overview

This package provides the core functionality for Heroku CLI commands, including a comprehensive set of completion handlers for various Heroku resources. It serves as the foundation for building Heroku CLI commands with built-in support for command-line completion.

## Features

### Completion Handlers

The package includes completion handlers for various Heroku resources:

- **Apps**: Autocomplete for Heroku application names
- **Addons**: Autocomplete for add-ons associated with specific apps
- **Dynos**: Autocomplete for dyno names within apps
- **Buildpacks**: Common Heroku buildpack options
- **Dyno Sizes**: Available dyno size options
- **Files**: Local file system completion
- **Pipelines**: Heroku pipeline names
- **Process Types**: Process types from Procfile
- **Regions**: Available Heroku regions
- **Git Remotes**: Git remote names
- **Roles**: User role options (admin, collaborator, member, owner)
- **Scopes**: Permission scope options
- **Spaces**: Heroku Private Spaces
- **Stacks**: Available Heroku stacks
- **Stages**: Pipeline stage options
- **Teams**: Heroku team names

### APIClient

The package includes a built-in `APIClient` for making authenticated requests to the Heroku Platform API:

- Handles authentication and request formatting
- Provides a simple interface for making GET requests to Heroku resources
- Automatically parses JSON responses
- Used internally by completion handlers to fetch resource lists
- Supports configurable request options through the CLI config

Example usage:
```typescript
const heroku = new APIClient(config)
const {body: resources} = await heroku.get('/apps')
```

## Usage

This package is primarily used as a dependency in other Heroku CLI plugins and commands. It provides the base functionality needed to implement Heroku CLI commands with proper completion support.

## Development

Built with TypeScript and uses the [oclif](https://oclif.io) framework for CLI command development.
30 changes: 30 additions & 0 deletions examples/favorites.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import {ux} from '@oclif/core'

import {Command} from '../src'

type Favorite = {
id: string;
resource_id: string;
resource_name: string;
type: string;
}

type Favorites = Favorite[]

class FavoritesCommand extends Command {
async run() {
const {body: favorites} = await this.heroku.get<Favorites>(
'/favorites?type=app',
{hostname: 'particleboard.heroku.com'},
)

ux.stdout('Favorited Apps')
ux.stdout('')
for (const f of favorites) {
ux.stdout(f.resource_name)
}
}
}

(FavoritesCommand.run([]) as any)

Check warning on line 29 in examples/favorites.ts

View workflow job for this annotation

GitHub Actions / test (macos-latest, 22.x)

Unexpected any. Specify a different type

Check warning on line 29 in examples/favorites.ts

View workflow job for this annotation

GitHub Actions / test (macos-latest, 22.x)

Unexpected any. Specify a different type

Check warning on line 29 in examples/favorites.ts

View workflow job for this annotation

GitHub Actions / test (macos-latest, 20.x)

Unexpected any. Specify a different type

Check warning on line 29 in examples/favorites.ts

View workflow job for this annotation

GitHub Actions / test (macos-latest, 20.x)

Unexpected any. Specify a different type

Check warning on line 29 in examples/favorites.ts

View workflow job for this annotation

GitHub Actions / test (ubuntu-latest, 20.x)

Unexpected any. Specify a different type

Check warning on line 29 in examples/favorites.ts

View workflow job for this annotation

GitHub Actions / test (ubuntu-latest, 20.x)

Unexpected any. Specify a different type

Check warning on line 29 in examples/favorites.ts

View workflow job for this annotation

GitHub Actions / test (ubuntu-latest, 22.x)

Unexpected any. Specify a different type

Check warning on line 29 in examples/favorites.ts

View workflow job for this annotation

GitHub Actions / test (ubuntu-latest, 22.x)

Unexpected any. Specify a different type

Check warning on line 29 in examples/favorites.ts

View workflow job for this annotation

GitHub Actions / test (windows-latest, 20.x)

Unexpected any. Specify a different type

Check warning on line 29 in examples/favorites.ts

View workflow job for this annotation

GitHub Actions / test (windows-latest, 20.x)

Unexpected any. Specify a different type

Check warning on line 29 in examples/favorites.ts

View workflow job for this annotation

GitHub Actions / test (windows-latest, 22.x)

Unexpected any. Specify a different type

Check warning on line 29 in examples/favorites.ts

View workflow job for this annotation

GitHub Actions / test (windows-latest, 22.x)

Unexpected any. Specify a different type
.catch(require('@oclif/core').Errors.handle)
12 changes: 9 additions & 3 deletions examples/login.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
import {Command} from '../src'
import {Command, flags} from '../src'

class LoginCommand extends Command {
static flags = {
interactive: flags.boolean({char: 'i', description: 'login with username/password'}),
}

async run() {
const {flags} = await this.parse(LoginCommand)
this.log('logging in')
await this.heroku.login()
const interactive = (flags.interactive) ? 'interactive' : undefined
await this.heroku.login({method: interactive})
}
}

(LoginCommand.run([]) as any)
(LoginCommand.run(process.argv.slice(2)) as any)

Check warning on line 16 in examples/login.ts

View workflow job for this annotation

GitHub Actions / test (macos-latest, 22.x)

Unexpected any. Specify a different type

Check warning on line 16 in examples/login.ts

View workflow job for this annotation

GitHub Actions / test (macos-latest, 22.x)

Unexpected any. Specify a different type

Check warning on line 16 in examples/login.ts

View workflow job for this annotation

GitHub Actions / test (macos-latest, 20.x)

Unexpected any. Specify a different type

Check warning on line 16 in examples/login.ts

View workflow job for this annotation

GitHub Actions / test (macos-latest, 20.x)

Unexpected any. Specify a different type

Check warning on line 16 in examples/login.ts

View workflow job for this annotation

GitHub Actions / test (ubuntu-latest, 20.x)

Unexpected any. Specify a different type

Check warning on line 16 in examples/login.ts

View workflow job for this annotation

GitHub Actions / test (ubuntu-latest, 20.x)

Unexpected any. Specify a different type

Check warning on line 16 in examples/login.ts

View workflow job for this annotation

GitHub Actions / test (ubuntu-latest, 22.x)

Unexpected any. Specify a different type

Check warning on line 16 in examples/login.ts

View workflow job for this annotation

GitHub Actions / test (ubuntu-latest, 22.x)

Unexpected any. Specify a different type

Check warning on line 16 in examples/login.ts

View workflow job for this annotation

GitHub Actions / test (windows-latest, 20.x)

Unexpected any. Specify a different type

Check warning on line 16 in examples/login.ts

View workflow job for this annotation

GitHub Actions / test (windows-latest, 20.x)

Unexpected any. Specify a different type

Check warning on line 16 in examples/login.ts

View workflow job for this annotation

GitHub Actions / test (windows-latest, 22.x)

Unexpected any. Specify a different type

Check warning on line 16 in examples/login.ts

View workflow job for this annotation

GitHub Actions / test (windows-latest, 22.x)

Unexpected any. Specify a different type
.catch(require('@oclif/core').Errors.handle)
6 changes: 3 additions & 3 deletions examples/logout.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import {Command} from '../src'

class LoginCommand extends Command {
class LogoutCommand extends Command {
async run() {
this.log('logging out')
await this.heroku.logout()
}
}

LoginCommand.run([])
.catch(require('@oclif/errors/handle'))
(LogoutCommand.run([]) as any)

Check warning on line 10 in examples/logout.ts

View workflow job for this annotation

GitHub Actions / test (macos-latest, 22.x)

Unexpected any. Specify a different type

Check warning on line 10 in examples/logout.ts

View workflow job for this annotation

GitHub Actions / test (macos-latest, 22.x)

Unexpected any. Specify a different type

Check warning on line 10 in examples/logout.ts

View workflow job for this annotation

GitHub Actions / test (macos-latest, 20.x)

Unexpected any. Specify a different type

Check warning on line 10 in examples/logout.ts

View workflow job for this annotation

GitHub Actions / test (macos-latest, 20.x)

Unexpected any. Specify a different type

Check warning on line 10 in examples/logout.ts

View workflow job for this annotation

GitHub Actions / test (ubuntu-latest, 20.x)

Unexpected any. Specify a different type

Check warning on line 10 in examples/logout.ts

View workflow job for this annotation

GitHub Actions / test (ubuntu-latest, 20.x)

Unexpected any. Specify a different type

Check warning on line 10 in examples/logout.ts

View workflow job for this annotation

GitHub Actions / test (ubuntu-latest, 22.x)

Unexpected any. Specify a different type

Check warning on line 10 in examples/logout.ts

View workflow job for this annotation

GitHub Actions / test (ubuntu-latest, 22.x)

Unexpected any. Specify a different type

Check warning on line 10 in examples/logout.ts

View workflow job for this annotation

GitHub Actions / test (windows-latest, 20.x)

Unexpected any. Specify a different type

Check warning on line 10 in examples/logout.ts

View workflow job for this annotation

GitHub Actions / test (windows-latest, 20.x)

Unexpected any. Specify a different type

Check warning on line 10 in examples/logout.ts

View workflow job for this annotation

GitHub Actions / test (windows-latest, 22.x)

Unexpected any. Specify a different type

Check warning on line 10 in examples/logout.ts

View workflow job for this annotation

GitHub Actions / test (windows-latest, 22.x)

Unexpected any. Specify a different type
.catch(require('@oclif/core').Errors.handle)
16 changes: 16 additions & 0 deletions examples/run.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#!/bin/bash

if [ -z "$1" ]; then
echo "Please provide a command name (login or logout)"
exit 1
fi

COMMAND=$1
shift

if [ ! -f "examples/$COMMAND.ts" ]; then
echo "Command '$COMMAND' not found in examples directory"
exit 1
fi

./node_modules/.bin/ts-node "examples/$COMMAND.ts" "$@"
29 changes: 29 additions & 0 deletions examples/status.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import {HTTP} from '@heroku/http-call'
import {ux} from '@oclif/core'

import {Command} from '../src'

class StatusCommand extends Command {
async run() {
ux.stdout('Checking Heroku status...')

const {body: status} = await HTTP.get('https://status.heroku.com/api/v4/current-status')

if (Array.isArray(status) && status.length > 0) {
this.log('\nCurrent Heroku Incidents:')
for (const incident of status) {
this.log(`\n${incident.name}`)
this.log(`Status: ${incident.status}`)
this.log(`Created: ${new Date(incident.created_at).toLocaleString()}`)
if (incident.updated_at) {
this.log(`Updated: ${new Date(incident.updated_at).toLocaleString()}`)
}
}
} else {
this.log('\nNo current incidents reported.')
}
}
}

(StatusCommand.run([]) as any)

Check warning on line 28 in examples/status.ts

View workflow job for this annotation

GitHub Actions / test (macos-latest, 22.x)

Unexpected any. Specify a different type

Check warning on line 28 in examples/status.ts

View workflow job for this annotation

GitHub Actions / test (macos-latest, 22.x)

Unexpected any. Specify a different type

Check warning on line 28 in examples/status.ts

View workflow job for this annotation

GitHub Actions / test (macos-latest, 20.x)

Unexpected any. Specify a different type

Check warning on line 28 in examples/status.ts

View workflow job for this annotation

GitHub Actions / test (macos-latest, 20.x)

Unexpected any. Specify a different type

Check warning on line 28 in examples/status.ts

View workflow job for this annotation

GitHub Actions / test (ubuntu-latest, 20.x)

Unexpected any. Specify a different type

Check warning on line 28 in examples/status.ts

View workflow job for this annotation

GitHub Actions / test (ubuntu-latest, 20.x)

Unexpected any. Specify a different type

Check warning on line 28 in examples/status.ts

View workflow job for this annotation

GitHub Actions / test (ubuntu-latest, 22.x)

Unexpected any. Specify a different type

Check warning on line 28 in examples/status.ts

View workflow job for this annotation

GitHub Actions / test (ubuntu-latest, 22.x)

Unexpected any. Specify a different type

Check warning on line 28 in examples/status.ts

View workflow job for this annotation

GitHub Actions / test (windows-latest, 20.x)

Unexpected any. Specify a different type

Check warning on line 28 in examples/status.ts

View workflow job for this annotation

GitHub Actions / test (windows-latest, 20.x)

Unexpected any. Specify a different type

Check warning on line 28 in examples/status.ts

View workflow job for this annotation

GitHub Actions / test (windows-latest, 22.x)

Unexpected any. Specify a different type

Check warning on line 28 in examples/status.ts

View workflow job for this annotation

GitHub Actions / test (windows-latest, 22.x)

Unexpected any. Specify a different type
.catch(require('@oclif/core').Errors.handle)
26 changes: 26 additions & 0 deletions examples/whoami.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import * as Heroku from '@heroku-cli/schema'
import {ux} from '@oclif/core'

import {Command} from '../src'

class StatusCommand extends Command {
notloggedin() {
this.error('not logged in', {exit: 100})
}

async run() {
if (process.env.HEROKU_API_KEY) this.warn('HEROKU_API_KEY is set')
if (!this.heroku.auth) this.notloggedin()
try {
const {body: account} = await this.heroku.get<Heroku.Account>('/account', {retryAuth: false})
ux.stdout(account.email)
} catch (error: any) {

Check warning on line 17 in examples/whoami.ts

View workflow job for this annotation

GitHub Actions / test (macos-latest, 22.x)

Unexpected any. Specify a different type

Check warning on line 17 in examples/whoami.ts

View workflow job for this annotation

GitHub Actions / test (macos-latest, 22.x)

Unexpected any. Specify a different type

Check warning on line 17 in examples/whoami.ts

View workflow job for this annotation

GitHub Actions / test (macos-latest, 20.x)

Unexpected any. Specify a different type

Check warning on line 17 in examples/whoami.ts

View workflow job for this annotation

GitHub Actions / test (macos-latest, 20.x)

Unexpected any. Specify a different type

Check warning on line 17 in examples/whoami.ts

View workflow job for this annotation

GitHub Actions / test (ubuntu-latest, 20.x)

Unexpected any. Specify a different type

Check warning on line 17 in examples/whoami.ts

View workflow job for this annotation

GitHub Actions / test (ubuntu-latest, 20.x)

Unexpected any. Specify a different type

Check warning on line 17 in examples/whoami.ts

View workflow job for this annotation

GitHub Actions / test (ubuntu-latest, 22.x)

Unexpected any. Specify a different type

Check warning on line 17 in examples/whoami.ts

View workflow job for this annotation

GitHub Actions / test (ubuntu-latest, 22.x)

Unexpected any. Specify a different type

Check warning on line 17 in examples/whoami.ts

View workflow job for this annotation

GitHub Actions / test (windows-latest, 20.x)

Unexpected any. Specify a different type

Check warning on line 17 in examples/whoami.ts

View workflow job for this annotation

GitHub Actions / test (windows-latest, 20.x)

Unexpected any. Specify a different type

Check warning on line 17 in examples/whoami.ts

View workflow job for this annotation

GitHub Actions / test (windows-latest, 22.x)

Unexpected any. Specify a different type

Check warning on line 17 in examples/whoami.ts

View workflow job for this annotation

GitHub Actions / test (windows-latest, 22.x)

Unexpected any. Specify a different type
if (error.statusCode === 401) this.notloggedin()
throw error
}
}
}

(StatusCommand.run([]) as any)

Check warning on line 24 in examples/whoami.ts

View workflow job for this annotation

GitHub Actions / test (macos-latest, 22.x)

Unexpected any. Specify a different type

Check warning on line 24 in examples/whoami.ts

View workflow job for this annotation

GitHub Actions / test (macos-latest, 22.x)

Unexpected any. Specify a different type

Check warning on line 24 in examples/whoami.ts

View workflow job for this annotation

GitHub Actions / test (macos-latest, 20.x)

Unexpected any. Specify a different type

Check warning on line 24 in examples/whoami.ts

View workflow job for this annotation

GitHub Actions / test (macos-latest, 20.x)

Unexpected any. Specify a different type

Check warning on line 24 in examples/whoami.ts

View workflow job for this annotation

GitHub Actions / test (ubuntu-latest, 20.x)

Unexpected any. Specify a different type

Check warning on line 24 in examples/whoami.ts

View workflow job for this annotation

GitHub Actions / test (ubuntu-latest, 20.x)

Unexpected any. Specify a different type

Check warning on line 24 in examples/whoami.ts

View workflow job for this annotation

GitHub Actions / test (ubuntu-latest, 22.x)

Unexpected any. Specify a different type

Check warning on line 24 in examples/whoami.ts

View workflow job for this annotation

GitHub Actions / test (ubuntu-latest, 22.x)

Unexpected any. Specify a different type

Check warning on line 24 in examples/whoami.ts

View workflow job for this annotation

GitHub Actions / test (windows-latest, 20.x)

Unexpected any. Specify a different type

Check warning on line 24 in examples/whoami.ts

View workflow job for this annotation

GitHub Actions / test (windows-latest, 20.x)

Unexpected any. Specify a different type

Check warning on line 24 in examples/whoami.ts

View workflow job for this annotation

GitHub Actions / test (windows-latest, 22.x)

Unexpected any. Specify a different type

Check warning on line 24 in examples/whoami.ts

View workflow job for this annotation

GitHub Actions / test (windows-latest, 22.x)

Unexpected any. Specify a different type
.catch(require('@oclif/core').Errors.handle)

Loading