Skip to content

Commit

Permalink
feat(context): Use middleware to fill context
Browse files Browse the repository at this point in the history
Added middleware function (using yargs middlewares) to build the context by checking if the management-token, space-id, environment-id and host are set in the .contentfulrc.json or passed into the command via flags.
  • Loading branch information
Johann authored Jun 27, 2019
1 parent 075527a commit 3a48664
Show file tree
Hide file tree
Showing 81 changed files with 1,371 additions and 745 deletions.
18 changes: 6 additions & 12 deletions lib/cli.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,14 @@
import yargs from 'yargs'
import {log} from './utils/log'
import {buildContext} from './utils/middlewares'
import {version} from '../package.json'

// Workaround to remove display of script name in help. See:
// * https://github.com/yargs/yargs/pull/1143
// * https://github.com/yargs/yargs/issues/1065
// * https://github.com/yargs/yargs/issues/1048
function fixHelp (output) {
return output.replace(/( +)contentful\.js/g, '$1')
}

yargs.usage('\nUsage: contentful <cmd> [args]')
.commandDir('cmds')
.middleware([
buildContext
])
.scriptName('')
.demandCommand(4, 'Please specify a command.')
.help('h')
.alias('h', 'help')
Expand All @@ -28,14 +25,11 @@ yargs.usage('\nUsage: contentful <cmd> [args]')
.epilog('Copyright 2018 Contentful, this is a BETA release')
.fail(function (msg, err, yargs) {
if (err) throw err
console.error(fixHelp(yargs.help()))
console.error(yargs.help())
console.error(msg)
process.exit(1)
})
.parse(process.argv.slice(2), (_, argv, output) => {
if (argv.help || argv.h) {
output = fixHelp(output)
}
if (argv.version === true && !argv._.length) {
log(version)
} else {
Expand Down
14 changes: 8 additions & 6 deletions lib/cmds/boilerplate.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import markdown from 'markdown-cli'

import { handleAsyncError as handle } from '../utils/async'
import { log, success } from '../utils/log'
import normalizer from '../utils/normalizer'
import { successEmoji } from '../utils/emojis'
import { frame } from '../utils/text'
import { accessTokenCreate } from './space_cmds/accesstoken_cmds/create'
Expand Down Expand Up @@ -46,9 +45,10 @@ async function getBoilerplates () {
}

export async function downloadBoilerplate (argv) {
await assertLoggedIn(argv)
await assertSpaceIdProvided(argv)
const { spaceId } = await normalizer(argv)
const { context } = argv
await assertLoggedIn(context)
await assertSpaceIdProvided(context)
const { activeSpaceId } = context

const boilerplatesResult = await getBoilerplates()

Expand Down Expand Up @@ -78,7 +78,9 @@ export async function downloadBoilerplate (argv) {
ctx.accessToken = await accessTokenCreate({
name: `Boilerplate CDA access token`,
description: `This token was generated for the ${boilerplate.name}`,
spaceId,
context: {
activeSpaceId
},
silent: true
})
}
Expand All @@ -87,7 +89,7 @@ export async function downloadBoilerplate (argv) {
title: `Downloading ${boilerplate.name} boilerplate`,
task: async (ctx) => {
const response = await axios({
url: `https://tools.contentful.com/boilerplates/${boilerplate.sys.id}/download?space_id=${spaceId}&access_token=${ctx.accessToken.accessToken}`,
url: `https://tools.contentful.com/boilerplates/${boilerplate.sys.id}/download?space_id=${activeSpaceId}&access_token=${ctx.accessToken.accessToken}`,
responseType: 'stream'
})
ctx.data = response.data
Expand Down
7 changes: 1 addition & 6 deletions lib/cmds/config_cmds/add.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { isEmpty, pickBy } from 'lodash'

import { setContext, getContext, storeRuntimeConfig } from '../../context'
import { setContext, storeRuntimeConfig } from '../../context'
import { handleAsyncError as handle } from '../../utils/async'
import { InvalidConfigOptionsError } from '../../utils/error'
import { successEmoji } from '../../utils/emojis.js'
Expand Down Expand Up @@ -48,7 +48,6 @@ export const addHandler = async (argv) => {
const opts = pickBy(argv, (value, key) => optionsToPick.includes(key) && value !== undefined)
validateOptions(opts)
const configs = transform(opts)
await getContext()
setContext(configs)
await storeRuntimeConfig()
success(`${successEmoji} config added successfully`)
Expand All @@ -69,10 +68,6 @@ function validateOptions (opts) {
}

function transform (opts) {
if (opts.managementToken) {
opts.cmaToken = opts.managementToken
delete opts.managementToken
}
if (opts.proxy) {
opts.proxy = proxyStringToObject(opts.proxy)
}
Expand Down
10 changes: 4 additions & 6 deletions lib/cmds/config_cmds/list.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { handleAsyncError as handle } from '../../utils/async'
import { getContext } from '../../context'
import emojic from 'emojic'
import { frame } from '../../utils/text'
import { success } from '../../utils/log'
Expand All @@ -15,13 +14,12 @@ export const builder = (yargs) => {
}

export const aliases = ['ls']
export const listHandler = async (argv) => {
const ctx = await getContext()
const configList = Object.keys(ctx).map((key) => {
export const listHandler = async ({context}) => {
const configList = Object.keys(context).map((key) => {
if (key === 'proxy') {
return `${emojic.gear} ${key}: ${proxyObjectToString(ctx[key])}`
return `${emojic.gear} ${key}: ${proxyObjectToString(context[key])}`
} else {
return `${emojic.gear} ${key}: ${ctx[key]}`
return `${emojic.gear} ${key}: ${context[key]}`
}
})
success(frame(configList.join('\n')))
Expand Down
25 changes: 11 additions & 14 deletions lib/cmds/config_cmds/remove.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { handleAsyncError as handle } from '../../utils/async'
import { success } from '../../utils/log'
import { successEmoji } from '../../utils/emojis.js'
import { setContext, getContext, emptyContext, storeRuntimeConfig } from '../../context'
import { pick } from 'lodash'
import { setContext, emptyContext, storeRuntimeConfig } from '../../context'
export const command = 'remove'

export const desc = 'Removes a config from ~/.contentfulrc.json'
Expand Down Expand Up @@ -49,21 +48,19 @@ export const builder = (yargs) => {
}

export const removeHandler = async (argv) => {
let context = await getContext()
const optionsToPick = ['cmaToken', 'proxy', 'activeSpaceId']
let options = pick(context, optionsToPick)
let options = {...argv.context}
if (argv.all) {
options = {}
} else {
if (argv.managementToken) {
delete options['cmaToken']
}
if (argv.activeSpaceId) {
delete options['activeSpaceId']
}
if (argv.proxy) {
delete options['proxy']
}
const contextKeys = [
'managementToken',
'activeSpaceId',
'activeEnvironmentId',
'proxy',
'rawProxy',
'host'
]
contextKeys.forEach(key => argv[key] && delete options[key])
}
emptyContext()
setContext(options)
Expand Down
15 changes: 6 additions & 9 deletions lib/cmds/content-type_cmds/get.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import Table from 'cli-table3'

import { getContext } from '../../context'
import { createManagementClient } from '../../utils/contentful-clients'
import { assertLoggedIn, assertSpaceIdProvided } from '../../utils/assertions'
import { log } from '../../utils/log'
Expand All @@ -21,22 +20,20 @@ export const builder = (yargs) => {
}

async function ctShow (argv) {
await assertLoggedIn(argv)
await assertSpaceIdProvided(argv)
const { context } = argv
await assertLoggedIn(context)
await assertSpaceIdProvided(context)

const contentTypeId = getId(argv)
const { cmaToken, activeSpaceId, activeEnvironmentId } = await getContext()
const managementToken = argv.managementToken || cmaToken
const spaceId = argv.spaceId || activeSpaceId
const environmentId = argv.environmentId || activeEnvironmentId
const { managementToken, activeSpaceId, activeEnvironmentId } = context

const client = await createManagementClient({
accessToken: managementToken,
feature: 'content_type-get'
})

const space = await client.getSpace(spaceId)
const environment = await space.getEnvironment(environmentId)
const space = await client.getSpace(activeSpaceId)
const environment = await space.getEnvironment(activeEnvironmentId)
const result = await environment.getContentType(contentTypeId)

const { sys, name, displayField, fields } = result
Expand Down
18 changes: 7 additions & 11 deletions lib/cmds/content-type_cmds/list.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import Table from 'cli-table3'

import { getContext } from '../../context'
import { createManagementClient } from '../../utils/contentful-clients'
import { assertLoggedIn, assertSpaceIdProvided } from '../../utils/assertions'
import { handleAsyncError as handle } from '../../utils/async'
Expand Down Expand Up @@ -31,24 +30,21 @@ export const builder = yargs => {
.epilog('Copyright 2018 Contentful, this is a BETA release')
}

async function ctList (argv) {
await assertLoggedIn(argv)
await assertSpaceIdProvided(argv)
async function ctList ({context}) {
await assertLoggedIn(context)
await assertSpaceIdProvided(context)

const { cmaToken, activeSpaceId, activeEnvironmentId } = await getContext()
const managementToken = argv.managementToken || cmaToken
const spaceId = argv.spaceId || activeSpaceId
const environmentId = argv.environmentId || activeEnvironmentId || 'master'
const { managementToken, activeSpaceId, activeEnvironmentId } = context

const client = await createManagementClient({
accessToken: managementToken,
feature: 'content_type-list'
})

const space = await client.getSpace(spaceId)
const environment = await space.getEnvironment(environmentId)
const space = await client.getSpace(activeSpaceId)
const environment = await space.getEnvironment(activeEnvironmentId)

log(highlightStyle(`Environment: "${environmentId}"`))
log(highlightStyle(`Environment: "${activeEnvironmentId}"`))

const result = await paginate({
client: environment,
Expand Down
18 changes: 8 additions & 10 deletions lib/cmds/extension_cmds/create.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { getContext } from '../../context'
import { assertLoggedIn, assertSpaceIdProvided } from '../../utils/assertions'
import { handleAsyncError as handle } from '../../utils/async'
import { createManagementClient } from '../../utils/contentful-clients'
Expand Down Expand Up @@ -54,8 +53,9 @@ export async function createExtension (environment, data) {
}

export async function createExtensionHandler (argv) {
await assertLoggedIn(argv)
await assertSpaceIdProvided(argv)
const { context } = argv
await assertLoggedIn(context)
await assertSpaceIdProvided(context)

const data = await prepareData(argv)

Expand All @@ -65,23 +65,21 @@ export async function createExtensionHandler (argv) {
await readSrcDocFile(data.extension)
}

const { cmaToken, activeSpaceId, activeEnvironmentId } = await getContext()
const spaceId = argv.spaceId || activeSpaceId
const environmentId = argv.environmentId || activeEnvironmentId || 'master'
const { managementToken, activeSpaceId, activeEnvironmentId } = context

const client = await createManagementClient({
accessToken: argv.managementToken || cmaToken,
accessToken: managementToken,
feature: 'extension-create'
})

const space = await client.getSpace(spaceId)
const environment = await space.getEnvironment(environmentId)
const space = await client.getSpace(activeSpaceId)
const environment = await space.getEnvironment(activeEnvironmentId)

const extension = await createExtension(environment, data)

success(`${successEmoji} Successfully created extension:\n`)

logExtension(extension, spaceId, environmentId)
logExtension(extension, activeSpaceId, activeEnvironmentId)
}

export const handler = handle(createExtensionHandler)
20 changes: 9 additions & 11 deletions lib/cmds/extension_cmds/delete.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { getContext } from '../../context'
import { assertLoggedIn, assertSpaceIdProvided } from '../../utils/assertions'
import { handleAsyncError as handle } from '../../utils/async'
import { createManagementClient } from '../../utils/contentful-clients'
Expand Down Expand Up @@ -29,27 +28,26 @@ export const builder = (yargs) => {
}

export async function deleteExtension (argv) {
await assertLoggedIn(argv)
await assertSpaceIdProvided(argv)
const {context, id} = argv
await assertLoggedIn(context)
await assertSpaceIdProvided(context)

const { cmaToken, activeSpaceId, activeEnvironmentId } = await getContext()
const spaceId = argv.spaceId || activeSpaceId
const environmentId = argv.environmentId || activeEnvironmentId || 'master'
const { managementToken, activeSpaceId, activeEnvironmentId } = context

const client = await createManagementClient({
accessToken: argv.managementToken || cmaToken,
accessToken: managementToken,
feature: 'extension-delete'
})

const space = await client.getSpace(spaceId)
const environment = await space.getEnvironment(environmentId)
const extension = await environment.getUiExtension(argv.id)
const space = await client.getSpace(activeSpaceId)
const environment = await space.getEnvironment(activeEnvironmentId)
const extension = await environment.getUiExtension(id)

await assertForceOrCorrectVersionProvided(argv, extension.sys.version)

await extension.delete()

success(`${successEmoji} Successfully deleted extension with ID ${argv.id}`)
success(`${successEmoji} Successfully deleted extension with ID ${id}`)
}

export const handler = handle(deleteExtension)
20 changes: 9 additions & 11 deletions lib/cmds/extension_cmds/get.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { getContext } from '../../context'
import { createManagementClient } from '../../utils/contentful-clients'
import { assertLoggedIn, assertSpaceIdProvided } from '../../utils/assertions'
import { handleAsyncError as handle } from '../../utils/async'
Expand All @@ -18,23 +17,22 @@ export const builder = (yargs) => {
}

async function getExtension (argv) {
await assertLoggedIn(argv)
await assertSpaceIdProvided(argv)
const {context, id} = argv
await assertLoggedIn(context)
await assertSpaceIdProvided(context)

const { cmaToken, activeSpaceId, activeEnvironmentId } = await getContext()
const spaceId = argv.spaceId || activeSpaceId
const environmentId = argv.environmentId || activeEnvironmentId || 'master'
const { managementToken, activeSpaceId, activeEnvironmentId } = context

const client = await createManagementClient({
accessToken: argv.managementToken || cmaToken,
accessToken: managementToken,
feature: 'extension-get'
})

const space = await client.getSpace(spaceId)
const environment = await space.getEnvironment(environmentId)
const extension = await environment.getUiExtension(argv.id)
const space = await client.getSpace(activeSpaceId)
const environment = await space.getEnvironment(activeEnvironmentId)
const extension = await environment.getUiExtension(id)

logExtension(extension, spaceId, environmentId)
logExtension(extension, activeSpaceId, activeEnvironmentId)
}

export const handler = handle(getExtension)
Loading

0 comments on commit 3a48664

Please sign in to comment.