From 5df483d250c37d15cdec5578637d92e230ce6d30 Mon Sep 17 00:00:00 2001 From: Shazron Abdullah Date: Wed, 21 May 2025 00:42:46 +0800 Subject: [PATCH 1/6] add DeployServiceCommand, DEPLOY_SERVICE_URL and USE_RUNTIME_AUTH env vars --- src/DeployServiceCommand.js | 60 +++++++++++++++++++++++++ src/RuntimeBaseCommand.js | 23 ++++------ src/commands/runtime/action/create.js | 7 +-- src/commands/runtime/action/delete.js | 6 +-- src/commands/runtime/api/create.js | 6 +-- src/commands/runtime/api/delete.js | 6 +-- src/commands/runtime/deploy/index.js | 2 +- src/commands/runtime/deploy/sync.js | 8 ++-- src/commands/runtime/deploy/undeploy.js | 2 +- src/commands/runtime/rule/create.js | 6 +-- src/commands/runtime/rule/delete.js | 6 +-- src/commands/runtime/rule/disable.js | 6 +-- src/commands/runtime/rule/enable.js | 6 +-- src/commands/runtime/trigger/create.js | 6 +-- src/commands/runtime/trigger/delete.js | 6 +-- src/properties.js | 2 +- 16 files changed, 106 insertions(+), 52 deletions(-) create mode 100644 src/DeployServiceCommand.js diff --git a/src/DeployServiceCommand.js b/src/DeployServiceCommand.js new file mode 100644 index 00000000..eb30dd9a --- /dev/null +++ b/src/DeployServiceCommand.js @@ -0,0 +1,60 @@ +/* +Copyright 2019 Adobe Inc. All rights reserved. +This file is licensed to you under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. You may obtain a copy +of the License at http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed under +the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS +OF ANY KIND, either express or implied. See the License for the specific language +governing permissions and limitations under the License. +*/ + +const { Flags } = require('@oclif/core') + +const { PropertyDefault } = require('./properties') +const runtimeLib = require('@adobe/aio-lib-runtime') +const { getToken, context, CLI } = require('@adobe/aio-lib-ims') +const { getCliEnv } = require('@adobe/aio-lib-env') +const RuntimeBaseCommand = require('./RuntimeBaseCommand') + +class DeployServiceCommand extends RuntimeBaseCommand { + + getAuthHandler () { + return { + getAuthHeader: async () => { + await context.setCli({ 'cli.bare-output': true }, false) // set this globally + const env = getCliEnv() + this.debug(`Retrieving CLI Token using env=${env}`) + const accessToken = await getToken(CLI) + + return `Bearer ${accessToken}` + } + } + } + + async setRuntimeApiHostAndAuthHandler(options) { + if (!options.useRuntimeAuth) { + options.apihost = process.env.DEPLOY_SERVICE_URL ?? PropertyDefault.DEPLOYSERVICEURL + options.auth_handler = this.getAuthHandler() + } + + return options + } + + async wsk (options) { + if (!options) { + options = await super.getOptions() + options =await this.setRuntimeApiHostAndAuthHandler(options) + } + return runtimeLib.init(options) + } + +} + +DeployServiceCommand.flags = { + ...RuntimeBaseCommand.flags, + useRuntimeAuth: Flags.boolean({ char: 'r', description: 'use Runtime auth [default: false]', default: false }) +} + +module.exports = DeployServiceCommand diff --git a/src/RuntimeBaseCommand.js b/src/RuntimeBaseCommand.js index 5395022f..6704594a 100644 --- a/src/RuntimeBaseCommand.js +++ b/src/RuntimeBaseCommand.js @@ -22,6 +22,12 @@ const { getToken, context } = require('@adobe/aio-lib-ims') const { getCliEnv } = require('@adobe/aio-lib-env') const { CLI } = require('@adobe/aio-lib-ims/src/context') +/** + * @typedef {Object} WskCreateOptions + * @property {boolean} [useRuntimeAuth=false] - Whether to use Runtime authentication + * @property {Object} [wskClientOptions] - The options to pass to the wsk client. If not provided, will be generated from getOptions() + */ + class RuntimeBaseCommand extends Command { async getOptions () { const { flags } = await this.parse(this.constructor) @@ -34,7 +40,8 @@ class RuntimeBaseCommand extends Command { apihost: flags.apihost || config.get('runtime.apihost') || properties.get('APIHOST') || PropertyDefault.APIHOST, namespace: config.get('runtime.namespace') || properties.get('NAMESPACE'), api_key: flags.auth || config.get('runtime.auth') || properties.get('AUTH'), - ignore_certs: flags.insecure || config.get('runtime.insecure') + ignore_certs: flags.insecure || config.get('runtime.insecure'), + useRuntimeAuth: process.env.USE_RUNTIME_AUTH || flags.useRuntimeAuth } // remove any null or undefined keys @@ -67,21 +74,7 @@ class RuntimeBaseCommand extends Command { async wsk (options) { if (!options) { - const authHandler = { - getAuthHeader: async () => { - await context.setCli({ 'cli.bare-output': true }, false) // set this globally - const env = getCliEnv() - console.debug(`Retrieving CLI Token using env=${env}`) - const accessToken = await getToken(CLI) - - return `Bearer ${accessToken}` - } - } options = await this.getOptions() - if (process.env.IS_DEPLOY_SERVICE_ENABLED === 'true') { - options.auth_handler = authHandler - options.apihost = options.apihost ?? PropertyDefault.DEPLOYSERVICEURL - } } return runtimeLib.init(options) } diff --git a/src/commands/runtime/action/create.js b/src/commands/runtime/action/create.js index 6991d6de..85e3d0b2 100644 --- a/src/commands/runtime/action/create.js +++ b/src/commands/runtime/action/create.js @@ -14,9 +14,9 @@ const fs = require('fs') const { createKeyValueArrayFromFlag, createKeyValueArrayFromFile, createComponentsfromSequence, getKeyValueArrayFromMergedParameters } = require('@adobe/aio-lib-runtime').utils const { kindForFileExtension } = require('../../../kinds') const { Flags } = require('@oclif/core') -const RuntimeBaseCommand = require('../../../RuntimeBaseCommand') +const DeployServiceCommand = require('../../../DeployServiceCommand') -class ActionCreate extends RuntimeBaseCommand { +class ActionCreate extends DeployServiceCommand { isUpdate () { return false } async run () { @@ -235,7 +235,8 @@ ActionCreate.args = [ ] ActionCreate.flags = { - ...RuntimeBaseCommand.flags, + ...DeployServiceCommand.flags, + param: Flags.string({ char: 'p', description: 'parameter values in KEY VALUE format', // help description for flag diff --git a/src/commands/runtime/action/delete.js b/src/commands/runtime/action/delete.js index 31532a2e..4d69aad5 100644 --- a/src/commands/runtime/action/delete.js +++ b/src/commands/runtime/action/delete.js @@ -10,10 +10,10 @@ OF ANY KIND, either express or implied. See the License for the specific languag governing permissions and limitations under the License. */ -const RuntimeBaseCommand = require('../../../RuntimeBaseCommand') +const DeployServiceCommand = require('../../../DeployServiceCommand') const { Flags } = require('@oclif/core') -class ActionDelete extends RuntimeBaseCommand { +class ActionDelete extends DeployServiceCommand { async run () { const { flags, args } = await this.parse(ActionDelete) const name = args.actionName @@ -37,7 +37,7 @@ ActionDelete.args = [ ] ActionDelete.flags = { - ...RuntimeBaseCommand.flags, + ...DeployServiceCommand.flags, json: Flags.boolean({ description: 'output raw json' }) diff --git a/src/commands/runtime/api/create.js b/src/commands/runtime/api/create.js index e6a2794c..4d8de262 100644 --- a/src/commands/runtime/api/create.js +++ b/src/commands/runtime/api/create.js @@ -9,11 +9,11 @@ OF ANY KIND, either express or implied. See the License for the specific languag governing permissions and limitations under the License. */ -const RuntimeBaseCommand = require('../../../RuntimeBaseCommand') +const DeployServiceCommand = require('../../../DeployServiceCommand') const { Flags } = require('@oclif/core') const fs = require('fs') -class ApiCreate extends RuntimeBaseCommand { +class ApiCreate extends DeployServiceCommand { async run () { const { args, flags } = await this.parse(ApiCreate) @@ -73,7 +73,7 @@ ApiCreate.args = [ ] ApiCreate.flags = { - ...RuntimeBaseCommand.flags, + ...DeployServiceCommand.flags, apiname: Flags.string({ char: 'n', description: 'Friendly name of the API; ignored when CFG_FILE is specified (default BASE_PATH)', diff --git a/src/commands/runtime/api/delete.js b/src/commands/runtime/api/delete.js index 2f3d08e6..df0acc91 100644 --- a/src/commands/runtime/api/delete.js +++ b/src/commands/runtime/api/delete.js @@ -9,10 +9,10 @@ OF ANY KIND, either express or implied. See the License for the specific languag governing permissions and limitations under the License. */ -const RuntimeBaseCommand = require('../../../RuntimeBaseCommand') +const DeployServiceCommand = require('../../../DeployServiceCommand') // eslint-disable-next-line no-unused-vars -class ApiDelete extends RuntimeBaseCommand { +class ApiDelete extends DeployServiceCommand { async run () { const { args } = await this.parse(ApiDelete) @@ -49,7 +49,7 @@ ApiDelete.args = [ ] ApiDelete.flags = { - ...RuntimeBaseCommand.flags + ...DeployServiceCommand.flags } ApiDelete.description = 'delete an API' diff --git a/src/commands/runtime/deploy/index.js b/src/commands/runtime/deploy/index.js index dcff4571..b2533abc 100644 --- a/src/commands/runtime/deploy/index.js +++ b/src/commands/runtime/deploy/index.js @@ -28,7 +28,7 @@ class IndexCommand extends RuntimeBaseCommand { const params = getKeyValueObjectFromMergedParameters(flags.param, flags['param-file']) const options = await this.getOptions() const entities = processPackage(packages, deploymentPackages, deploymentTriggers, params, false, options) - const ow = await this.wsk(options) + const ow = await this.wsk() const logger = this.log await deployPackage(entities, ow, logger.bind(this), this.getImsOrgId()) } catch (err) { diff --git a/src/commands/runtime/deploy/sync.js b/src/commands/runtime/deploy/sync.js index 437dffc5..cfd3d9b3 100644 --- a/src/commands/runtime/deploy/sync.js +++ b/src/commands/runtime/deploy/sync.js @@ -10,11 +10,11 @@ OF ANY KIND, either express or implied. See the License for the specific languag governing permissions and limitations under the License. */ -const RuntimeBaseCommand = require('../../../RuntimeBaseCommand') +const DeployServiceCommand = require('../../../DeployServiceCommand') const { setPaths, processPackage, syncProject } = require('@adobe/aio-lib-runtime').utils const { Flags } = require('@oclif/core') -class DeploySync extends RuntimeBaseCommand { +class DeploySync extends DeployServiceCommand { async run () { const { flags } = await this.parse(DeploySync) try { @@ -29,7 +29,7 @@ class DeploySync extends RuntimeBaseCommand { const params = {} const options = await this.getOptions() const entities = processPackage(packages, deploymentPackages, deploymentTriggers, params, false, options) - const ow = await this.wsk(options) + const ow = await this.wsk() const logger = this.log await syncProject(components.projectName, components.manifestPath, components.manifestContent, entities, ow, logger.bind(this), this.getImsOrgId()) } catch (err) { @@ -39,7 +39,7 @@ class DeploySync extends RuntimeBaseCommand { } DeploySync.flags = { - ...RuntimeBaseCommand.flags, + ...DeployServiceCommand.flags, manifest: Flags.string({ char: 'm', description: 'the manifest file location' // help description for flag diff --git a/src/commands/runtime/deploy/undeploy.js b/src/commands/runtime/deploy/undeploy.js index 5275a514..08410ba8 100644 --- a/src/commands/runtime/deploy/undeploy.js +++ b/src/commands/runtime/deploy/undeploy.js @@ -19,7 +19,7 @@ class DeployUndeploy extends RuntimeBaseCommand { const { flags } = await this.parse(DeployUndeploy) try { const options = await this.getOptions() - const ow = await this.wsk(options) + const ow = await this.wsk() const logger = this.log let entities diff --git a/src/commands/runtime/rule/create.js b/src/commands/runtime/rule/create.js index b01d4d47..e4b29152 100644 --- a/src/commands/runtime/rule/create.js +++ b/src/commands/runtime/rule/create.js @@ -9,10 +9,10 @@ OF ANY KIND, either express or implied. See the License for the specific languag governing permissions and limitations under the License. */ -const RuntimeBaseCommand = require('../../../RuntimeBaseCommand') +const DeployServiceCommand = require('../../../DeployServiceCommand') const { Flags } = require('@oclif/core') -class RuleCreate extends RuntimeBaseCommand { +class RuleCreate extends DeployServiceCommand { isUpdate () { return false } async run () { @@ -53,7 +53,7 @@ RuleCreate.args = [ ] RuleCreate.flags = { - ...RuntimeBaseCommand.flags, + ...DeployServiceCommand.flags, json: Flags.boolean({ description: 'output raw json' }) diff --git a/src/commands/runtime/rule/delete.js b/src/commands/runtime/rule/delete.js index fd8e7a2e..bce60716 100644 --- a/src/commands/runtime/rule/delete.js +++ b/src/commands/runtime/rule/delete.js @@ -9,10 +9,10 @@ OF ANY KIND, either express or implied. See the License for the specific languag governing permissions and limitations under the License. */ -const RuntimeBaseCommand = require('../../../RuntimeBaseCommand') +const DeployServiceCommand = require('../../../DeployServiceCommand') const { Flags } = require('@oclif/core') -class RuleDelete extends RuntimeBaseCommand { +class RuleDelete extends DeployServiceCommand { async run () { const { flags, args } = await this.parse(RuleDelete) try { @@ -39,7 +39,7 @@ RuleDelete.args = [ ] RuleDelete.flags = { - ...RuntimeBaseCommand.flags, + ...DeployServiceCommand.flags, json: Flags.boolean({ description: 'output raw json' }) diff --git a/src/commands/runtime/rule/disable.js b/src/commands/runtime/rule/disable.js index 5f28ec40..ac23bb2f 100644 --- a/src/commands/runtime/rule/disable.js +++ b/src/commands/runtime/rule/disable.js @@ -9,9 +9,9 @@ OF ANY KIND, either express or implied. See the License for the specific languag governing permissions and limitations under the License. */ -const RuntimeBaseCommand = require('../../../RuntimeBaseCommand') +const DeployServiceCommand = require('../../../DeployServiceCommand') -class RuleDisable extends RuntimeBaseCommand { +class RuleDisable extends DeployServiceCommand { async run () { const { args } = await this.parse(RuleDisable) try { @@ -36,7 +36,7 @@ RuleDisable.args = [ ] RuleDisable.flags = { - ...RuntimeBaseCommand.flags + ...DeployServiceCommand.flags } RuleDisable.aliases = [ diff --git a/src/commands/runtime/rule/enable.js b/src/commands/runtime/rule/enable.js index 916125ad..04d10955 100644 --- a/src/commands/runtime/rule/enable.js +++ b/src/commands/runtime/rule/enable.js @@ -9,9 +9,9 @@ OF ANY KIND, either express or implied. See the License for the specific languag governing permissions and limitations under the License. */ -const RuntimeBaseCommand = require('../../../RuntimeBaseCommand') +const DeployServiceCommand = require('../../../DeployServiceCommand') -class RuleEnable extends RuntimeBaseCommand { +class RuleEnable extends DeployServiceCommand { async run () { const { args } = await this.parse(RuleEnable) try { @@ -36,7 +36,7 @@ RuleEnable.args = [ ] RuleEnable.flags = { - ...RuntimeBaseCommand.flags + ...DeployServiceCommand.flags } RuleEnable.aliases = [ diff --git a/src/commands/runtime/trigger/create.js b/src/commands/runtime/trigger/create.js index 16022071..5878a66a 100644 --- a/src/commands/runtime/trigger/create.js +++ b/src/commands/runtime/trigger/create.js @@ -10,11 +10,11 @@ OF ANY KIND, either express or implied. See the License for the specific languag governing permissions and limitations under the License. */ -const RuntimeBaseCommand = require('../../../RuntimeBaseCommand') +const DeployServiceCommand = require('../../../DeployServiceCommand') const { getKeyValueArrayFromMergedParameters } = require('@adobe/aio-lib-runtime').utils const { Flags } = require('@oclif/core') -class TriggerCreate extends RuntimeBaseCommand { +class TriggerCreate extends DeployServiceCommand { isUpdate () { return false } async run () { @@ -62,7 +62,7 @@ TriggerCreate.args = [ ] TriggerCreate.flags = { - ...RuntimeBaseCommand.flags, + ...DeployServiceCommand.flags, param: Flags.string({ char: 'p', description: 'parameter values in KEY VALUE format', // help description for flag diff --git a/src/commands/runtime/trigger/delete.js b/src/commands/runtime/trigger/delete.js index 9d56e45e..39b22bdd 100644 --- a/src/commands/runtime/trigger/delete.js +++ b/src/commands/runtime/trigger/delete.js @@ -10,10 +10,10 @@ OF ANY KIND, either express or implied. See the License for the specific languag governing permissions and limitations under the License. */ -const RuntimeBaseCommand = require('../../../RuntimeBaseCommand') +const DeployServiceCommand = require('../../../DeployServiceCommand') const { parsePathPattern } = require('@adobe/aio-lib-runtime').utils -class TriggerDelete extends RuntimeBaseCommand { +class TriggerDelete extends DeployServiceCommand { async run () { const { args } = await this.parse(TriggerDelete) const triggerPath = args.triggerPath @@ -38,7 +38,7 @@ TriggerDelete.args = [ ] TriggerDelete.flags = { - ...RuntimeBaseCommand.flags + ...DeployServiceCommand.flags } TriggerDelete.description = 'Delete a trigger for Adobe I/O Runtime' diff --git a/src/properties.js b/src/properties.js index 40cd7964..8fe5edd9 100644 --- a/src/properties.js +++ b/src/properties.js @@ -35,7 +35,7 @@ const PropertyEnv = { const PropertyDefault = { AUTH: '', APIHOST: 'https://adobeioruntime.net', - DEPLOYSERVICEURL: 'https://adobeioruntime.net', + DEPLOYSERVICEURL: 'https://deploy-service.app-builder.adp.adobe.io/runtime', APIVERSION: 'v1', NAMESPACE: '_', CERT: '', From 07e46f4f814a7c90608c622b7b3a7675ef54b572 Mon Sep 17 00:00:00 2001 From: Shazron Abdullah Date: Wed, 21 May 2025 15:02:21 +0800 Subject: [PATCH 2/6] support current ims context for getting access token (for tech acct token support) --- src/DeployServiceCommand.js | 42 +++++++++++++++++++++++++++++++++++-- src/properties.js | 2 +- 2 files changed, 41 insertions(+), 3 deletions(-) diff --git a/src/DeployServiceCommand.js b/src/DeployServiceCommand.js index eb30dd9a..976fa3dd 100644 --- a/src/DeployServiceCommand.js +++ b/src/DeployServiceCommand.js @@ -20,13 +20,50 @@ const RuntimeBaseCommand = require('./RuntimeBaseCommand') class DeployServiceCommand extends RuntimeBaseCommand { +/** + * Retrieves an access token for Adobe I/O CLI authentication. + * This function handles both CLI and custom contexts, setting up the appropriate + * authentication context and retrieving the corresponding access token. + * + * @async + * @function getAccessToken + * @param {Object} [options] - Options for token retrieval + * @param {boolean} [options.useCachedToken=false] - Whether to use a cached token instead of requesting a new one + * @returns {Promise<{accessToken: string|null, env: string}>} An object containing: + * - accessToken: The retrieved access token for authentication, or null if token retrieval failed + * - env: The current CLI environment (e.g. 'prod', 'stage') + * @throws {Error} If token retrieval fails or context setup fails + */ +async getAccessToken({ useCachedToken = false } = {}) { + const env = getCliEnv() + let contextName = CLI // default + const currentContext = await context.getCurrent() // potential override + + if (currentContext !== CLI) { + contextName = currentContext + } else { + await context.setCli({ 'cli.bare-output': true }, false) // set this globally + } + + let accessToken = null + if (useCachedToken) { + const contextConfig = await context.get(contextName) + accessToken = contextConfig?.access_token?.token + } else { + accessToken = await getToken(contextName) + } + + return { accessToken, env } +} + + getAuthHandler () { return { getAuthHeader: async () => { await context.setCli({ 'cli.bare-output': true }, false) // set this globally const env = getCliEnv() this.debug(`Retrieving CLI Token using env=${env}`) - const accessToken = await getToken(CLI) + const { accessToken } = await this.getAccessToken() return `Bearer ${accessToken}` } @@ -35,7 +72,8 @@ class DeployServiceCommand extends RuntimeBaseCommand { async setRuntimeApiHostAndAuthHandler(options) { if (!options.useRuntimeAuth) { - options.apihost = process.env.DEPLOY_SERVICE_URL ?? PropertyDefault.DEPLOYSERVICEURL + const endpoint = process.env.AIO_DEPLOY_SERVICE_URL ?? PropertyDefault.DEPLOYSERVICEURL + options.apihost = `${endpoint}/runtime` options.auth_handler = this.getAuthHandler() } diff --git a/src/properties.js b/src/properties.js index 8fe5edd9..613b83ce 100644 --- a/src/properties.js +++ b/src/properties.js @@ -35,7 +35,7 @@ const PropertyEnv = { const PropertyDefault = { AUTH: '', APIHOST: 'https://adobeioruntime.net', - DEPLOYSERVICEURL: 'https://deploy-service.app-builder.adp.adobe.io/runtime', + DEPLOYSERVICEURL: 'https://deploy-service.app-builder.adp.adobe.io', APIVERSION: 'v1', NAMESPACE: '_', CERT: '', From aba23bc8574a8c293536d79efad50d0387060219 Mon Sep 17 00:00:00 2001 From: Shazron Abdullah Date: Wed, 21 May 2025 15:22:50 +0800 Subject: [PATCH 3/6] remove redundant code --- src/DeployServiceCommand.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/DeployServiceCommand.js b/src/DeployServiceCommand.js index 976fa3dd..046cb854 100644 --- a/src/DeployServiceCommand.js +++ b/src/DeployServiceCommand.js @@ -60,8 +60,6 @@ async getAccessToken({ useCachedToken = false } = {}) { getAuthHandler () { return { getAuthHeader: async () => { - await context.setCli({ 'cli.bare-output': true }, false) // set this globally - const env = getCliEnv() this.debug(`Retrieving CLI Token using env=${env}`) const { accessToken } = await this.getAccessToken() From b48ef2753ac16355c62a3bef2c3e482d9e931f84 Mon Sep 17 00:00:00 2001 From: Shazron Abdullah Date: Thu, 22 May 2025 16:53:38 +0800 Subject: [PATCH 4/6] fix issues with env undefined, cloned options so a function doesn't mutate its inputs --- package.json | 5 +-- src/DeployServiceCommand.js | 71 +++++++++++++++++++------------------ src/RuntimeBaseCommand.js | 7 ++-- 3 files changed, 41 insertions(+), 42 deletions(-) diff --git a/package.json b/package.json index fcd62413..9069b80c 100644 --- a/package.json +++ b/package.json @@ -70,8 +70,9 @@ }, "repository": "adobe/aio-cli-plugin-runtime", "scripts": { - "eslint-fix": "eslint src test e2e --fix", - "posttest": "eslint src test e2e", + "lint-fix": "eslint src test e2e --fix", + "lint": "eslint src test e2e", + "posttest": "npm run lint", "test": "npm run unit-tests", "unit-tests": "jest --ci", "prepack": "oclif manifest && oclif readme --no-aliases", diff --git a/src/DeployServiceCommand.js b/src/DeployServiceCommand.js index 046cb854..285292b3 100644 --- a/src/DeployServiceCommand.js +++ b/src/DeployServiceCommand.js @@ -19,73 +19,74 @@ const { getCliEnv } = require('@adobe/aio-lib-env') const RuntimeBaseCommand = require('./RuntimeBaseCommand') class DeployServiceCommand extends RuntimeBaseCommand { - /** * Retrieves an access token for Adobe I/O CLI authentication. * This function handles both CLI and custom contexts, setting up the appropriate * authentication context and retrieving the corresponding access token. - * + * * @async * @function getAccessToken - * @param {Object} [options] - Options for token retrieval - * @param {boolean} [options.useCachedToken=false] - Whether to use a cached token instead of requesting a new one + * @param {object} [options] - Options for token retrieval + * @param {string} [options.env] - The environment to use (e.g. 'prod', 'stage') + * @param {boolean} [options.useCachedToken] - Whether to use a cached token instead of requesting a new one * @returns {Promise<{accessToken: string|null, env: string}>} An object containing: * - accessToken: The retrieved access token for authentication, or null if token retrieval failed - * - env: The current CLI environment (e.g. 'prod', 'stage') + * - env: The current CLI environment * @throws {Error} If token retrieval fails or context setup fails */ -async getAccessToken({ useCachedToken = false } = {}) { - const env = getCliEnv() - let contextName = CLI // default - const currentContext = await context.getCurrent() // potential override + async getAccessToken ({ env = getCliEnv(), useCachedToken = false } = {}) { + let contextName = CLI // default + const currentContext = await context.getCurrent() // potential override + + if (currentContext !== CLI) { + contextName = currentContext + } else { + await context.setCli({ 'cli.bare-output': true }, false) // set this globally + } - if (currentContext !== CLI) { - contextName = currentContext - } else { - await context.setCli({ 'cli.bare-output': true }, false) // set this globally - } + let accessToken = null + if (useCachedToken) { + const contextConfig = await context.get(contextName) + accessToken = contextConfig?.access_token?.token + } else { + accessToken = await getToken(contextName) + } - let accessToken = null - if (useCachedToken) { - const contextConfig = await context.get(contextName) - accessToken = contextConfig?.access_token?.token - } else { - accessToken = await getToken(contextName) + return { accessToken, env } } - return { accessToken, env } -} - - getAuthHandler () { + const env = getCliEnv() return { getAuthHeader: async () => { this.debug(`Retrieving CLI Token using env=${env}`) - const { accessToken } = await this.getAccessToken() + const { accessToken } = await this.getAccessToken({ env }) return `Bearer ${accessToken}` } } } - async setRuntimeApiHostAndAuthHandler(options) { - if (!options.useRuntimeAuth) { + async setRuntimeApiHostAndAuthHandler (options) { + let _options = structuredClone(options) + if (!_options?.useRuntimeAuth) { const endpoint = process.env.AIO_DEPLOY_SERVICE_URL ?? PropertyDefault.DEPLOYSERVICEURL - options.apihost = `${endpoint}/runtime` - options.auth_handler = this.getAuthHandler() + _options = _options ?? {} + _options.apihost = `${endpoint}/runtime` + _options.auth_handler = this.getAuthHandler() } - return options + return _options } async wsk (options) { - if (!options) { - options = await super.getOptions() - options =await this.setRuntimeApiHostAndAuthHandler(options) + let _options = structuredClone(options) + if (!_options) { + _options = await super.getOptions() + _options = await this.setRuntimeApiHostAndAuthHandler(_options) } - return runtimeLib.init(options) + return runtimeLib.init(_options) } - } DeployServiceCommand.flags = { diff --git a/src/RuntimeBaseCommand.js b/src/RuntimeBaseCommand.js index 6704594a..2a453279 100644 --- a/src/RuntimeBaseCommand.js +++ b/src/RuntimeBaseCommand.js @@ -18,14 +18,11 @@ const debug = createDebug('aio-cli-plugin-runtime') const http = require('http') const runtimeLib = require('@adobe/aio-lib-runtime') const config = require('@adobe/aio-lib-core-config') -const { getToken, context } = require('@adobe/aio-lib-ims') -const { getCliEnv } = require('@adobe/aio-lib-env') -const { CLI } = require('@adobe/aio-lib-ims/src/context') /** - * @typedef {Object} WskCreateOptions + * @typedef {object} WskCreateOptions * @property {boolean} [useRuntimeAuth=false] - Whether to use Runtime authentication - * @property {Object} [wskClientOptions] - The options to pass to the wsk client. If not provided, will be generated from getOptions() + * @property {object} [wskClientOptions] - The options to pass to the wsk client. If not provided, will be generated from getOptions() */ class RuntimeBaseCommand extends Command { From 6898463f6be3bb802c0463d8f6a463fd6342c3c4 Mon Sep 17 00:00:00 2001 From: Shazron Abdullah Date: Thu, 22 May 2025 17:17:12 +0800 Subject: [PATCH 5/6] fix unit tests --- src/RuntimeBaseCommand.js | 7 +- test/DeployServiceCommand.test.js | 178 ++++++++++++++++++++++++++++++ test/RuntimeBaseCommand.test.js | 171 +++------------------------- 3 files changed, 196 insertions(+), 160 deletions(-) create mode 100644 test/DeployServiceCommand.test.js diff --git a/src/RuntimeBaseCommand.js b/src/RuntimeBaseCommand.js index 2a453279..605cc10e 100644 --- a/src/RuntimeBaseCommand.js +++ b/src/RuntimeBaseCommand.js @@ -70,10 +70,11 @@ class RuntimeBaseCommand extends Command { } async wsk (options) { - if (!options) { - options = await this.getOptions() + let _options = structuredClone(options) + if (!_options) { + _options = await this.getOptions() } - return runtimeLib.init(options) + return runtimeLib.init(_options) } getImsOrgId () { diff --git a/test/DeployServiceCommand.test.js b/test/DeployServiceCommand.test.js new file mode 100644 index 00000000..59c30ced --- /dev/null +++ b/test/DeployServiceCommand.test.js @@ -0,0 +1,178 @@ +/* +Copyright 2025 Adobe Inc. All rights reserved. +This file is licensed to you under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. You may obtain a copy +of the License at http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed under +the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS +OF ANY KIND, either express or implied. See the License for the specific language +governing permissions and limitations under the License. +*/ + +const TheCommand = require('../src/DeployServiceCommand.js') +const { Command } = require('@oclif/core') +const { PropertyDefault } = require('../src/properties') +const RuntimeLib = require('@adobe/aio-lib-runtime') +const { getToken, context, CLI } = require('@adobe/aio-lib-ims') +const { getCliEnv } = require('@adobe/aio-lib-env') + +jest.mock('@adobe/aio-lib-ims', () => ({ + getToken: jest.fn(), + context: { + getCurrent: jest.fn(), + setCli: jest.fn(), + get: jest.fn() + }, + CLI: 'cli' +})) + +jest.mock('@adobe/aio-lib-env', () => ({ + getCliEnv: jest.fn() +})) + +jest.mock('@adobe/aio-lib-runtime', () => ({ + init: jest.fn() +})) + +describe('DeployServiceCommand', () => { + let command + + beforeEach(() => { + command = new TheCommand([]) + jest.clearAllMocks() + }) + + test('exports', async () => { + expect(typeof TheCommand).toEqual('function') + expect(TheCommand.prototype).toBeInstanceOf(Command) + }) + + test('flags', async () => { + expect(Object.keys(TheCommand.flags)).toEqual(expect.arrayContaining([ + 'useRuntimeAuth' + ])) + }) + + describe('getAccessToken', () => { + const mockToken = 'mock-token' + const mockEnv = 'prod' + + beforeEach(() => { + getCliEnv.mockReturnValue(mockEnv) + }) + + test('should use CLI context by default', async () => { + context.getCurrent.mockResolvedValue(CLI) + getToken.mockResolvedValue(mockToken) + + const result = await command.getAccessToken() + + expect(context.getCurrent).toHaveBeenCalled() + expect(context.setCli).toHaveBeenCalledWith({ 'cli.bare-output': true }, false) + expect(getToken).toHaveBeenCalledWith(CLI) + expect(result).toEqual({ + accessToken: mockToken, + env: mockEnv + }) + }) + + test('should use custom context when available', async () => { + const customContext = 'custom-context' + context.getCurrent.mockResolvedValue(customContext) + getToken.mockResolvedValue(mockToken) + + const result = await command.getAccessToken() + + expect(context.getCurrent).toHaveBeenCalled() + expect(context.setCli).not.toHaveBeenCalled() + expect(getToken).toHaveBeenCalledWith(customContext) + expect(result).toEqual({ + accessToken: mockToken, + env: mockEnv + }) + }) + + test('should use cached token when requested', async () => { + context.getCurrent.mockResolvedValue(CLI) + context.get.mockResolvedValue({ + access_token: { token: mockToken } + }) + + const result = await command.getAccessToken({ useCachedToken: true }) + + expect(context.get).toHaveBeenCalledWith(CLI) + expect(getToken).not.toHaveBeenCalled() + expect(result).toEqual({ + accessToken: mockToken, + env: mockEnv + }) + }) + }) + + describe('getAuthHandler', () => { + test('should return auth handler with correct header', async () => { + const mockToken = 'mock-token' + const mockEnv = 'prod' + getCliEnv.mockReturnValue(mockEnv) + context.getCurrent.mockResolvedValue(CLI) + getToken.mockResolvedValue(mockToken) + + const authHandler = command.getAuthHandler() + const header = await authHandler.getAuthHeader() + + expect(header).toBe(`Bearer ${mockToken}`) + }) + }) + + describe('setRuntimeApiHostAndAuthHandler', () => { + test('if options is not defined (set auth handler)', async () => { + const mockOptions = null + const result = await command.setRuntimeApiHostAndAuthHandler(mockOptions) + + expect(result.apihost).toBe(`${PropertyDefault.DEPLOYSERVICEURL}/runtime`) + expect(result.auth_handler).toBeDefined() + }) + + test('should set runtime API host and auth handler when useRuntimeAuth is false', async () => { + const mockOptions = { someOption: 'value' } + const result = await command.setRuntimeApiHostAndAuthHandler(mockOptions) + + expect(result.apihost).toBe(`${PropertyDefault.DEPLOYSERVICEURL}/runtime`) + expect(result.auth_handler).toBeDefined() + }) + + test('should not modify options when useRuntimeAuth is true', async () => { + const mockOptions = { useRuntimeAuth: true, someOption: 'value' } + const result = await command.setRuntimeApiHostAndAuthHandler(mockOptions) + + expect(result).toEqual(mockOptions) + }) + + test('should use custom deploy service URL from environment', async () => { + const customUrl = 'https://custom-deploy-service.com' + process.env.AIO_DEPLOY_SERVICE_URL = customUrl + + const mockOptions = { someOption: 'value' } + const result = await command.setRuntimeApiHostAndAuthHandler(mockOptions) + + expect(result.apihost).toBe(`${customUrl}/runtime`) + delete process.env.AIO_DEPLOY_SERVICE_URL + }) + }) + + describe('wsk', () => { + test('should initialize runtime with correct options', async () => { + const mockOptions = { someOption: 'value' } + await command.wsk(mockOptions) + + expect(RuntimeLib.init).toHaveBeenCalled() + }) + + test('should get options from parent class when not provided', async () => { + await command.wsk() + + expect(RuntimeLib.init).toHaveBeenCalled() + }) + }) +}) diff --git a/test/RuntimeBaseCommand.test.js b/test/RuntimeBaseCommand.test.js index 208bad92..fa9d578a 100644 --- a/test/RuntimeBaseCommand.test.js +++ b/test/RuntimeBaseCommand.test.js @@ -15,8 +15,6 @@ const { Command } = require('@oclif/core') const { PropertyEnv } = require('../src/properties') const RuntimeLib = require('@adobe/aio-lib-runtime') const OpenWhiskError = require('openwhisk/lib/openwhisk_error') -const { getToken, context } = require('@adobe/aio-lib-ims') -const { getCliEnv } = require('@adobe/aio-lib-env') jest.mock('@adobe/aio-lib-ims', () => ({ getToken: jest.fn(), @@ -223,13 +221,26 @@ describe('instance methods', () => { }) describe('ow', () => { + beforeEach(() => { + RuntimeLib.init.mockClear() + }) + test('is a function', async () => { expect(command.wsk).toBeInstanceOf(Function) }) test('returns a promise', () => { + RuntimeLib.init.mockReturnValue({}) return command.wsk().then((ow) => { - expect(ow).toBe(ow) + expect(ow).toBeDefined() + }) + }) + + test('returns a promise (pass options)', () => { + RuntimeLib.init.mockReturnValue({}) + const options = { useRuntimeAuth: true } + return command.wsk(options).then((ow) => { + expect(ow).toBeDefined() }) }) @@ -334,158 +345,4 @@ describe('instance methods', () => { expect(command.error).toHaveBeenCalledWith('msg' + suffix) }) }) - - describe('authHandler', () => { - describe('when IS_DEPLOY_SERVICE_ENABLED = true', () => { - beforeEach(() => { - process.env.IS_DEPLOY_SERVICE_ENABLED = true - }) - - afterEach(() => { - process.env.IS_DEPLOY_SERVICE_ENABLED = false - }) - test('No Options : should return the correct Authorization header using getAuthHeader', async () => { - const mockToken = 'mock-access-token' - getToken.mockResolvedValue(mockToken) - - // Spy on runtimeLib.init to capture options before it's used - let capturedOptions - RuntimeLib.init.mockImplementation(async (options) => { - capturedOptions = options // Store options for later verification - return {} // Mock runtimeLib.init() return value - }) - - // Call wsk() which internally sets auth_handler - await command.wsk() - - // Ensure options were captured - expect(capturedOptions).toBeDefined() - expect(capturedOptions.auth_handler).toBeDefined() - expect(capturedOptions.apihost).toBeDefined() - expect(capturedOptions.apihost).toBe('some.host') - - // Call getAuthHeader() from captured options - const authHeader = await capturedOptions.auth_handler.getAuthHeader() - - expect(context.setCli).toHaveBeenCalledWith({ 'cli.bare-output': true }, false) - expect(getCliEnv).toHaveBeenCalled() - expect(getToken).toHaveBeenCalled() - expect(authHeader).toBe(`Bearer ${mockToken}`) - }) - - test('With Options : should return the correct Authorization header using getAuthHeader', async () => { - const mockToken = 'mock-access-token' - getToken.mockResolvedValue(mockToken) - - const options = { - auth_handler: { - getAuthHeader: async () => `Bearer ${mockToken}` - }, - apihost: 'https://custom-api.adobe.com' - } - - await command.wsk(options) // Call wsk() with an existing options object - - expect(RuntimeLib.init).toHaveBeenCalledWith(options) - }) - - test('Default OW Host testing', async () => { - delete process.env[PropertyEnv.APIHOST] - - const mockToken = 'mock-access-token' - getToken.mockResolvedValue(mockToken) - - command.getOptions = jest.fn().mockResolvedValue({}) - - // Mock runtimeLib.init to track its calls - const mockInit = jest.fn().mockResolvedValue({}) - RuntimeLib.init = mockInit - - // Call wsk() without options - await command.wsk() - - // Assertions - expect(RuntimeLib.init).toHaveBeenCalled() - - // Verify the passed options contain the default apihost - const optionsPassedToInit = mockInit.mock.calls[0][0] // Get the options passed to init - expect(optionsPassedToInit.apihost).toBe('https://adobeioruntime.net') - - // Ensure the Authorization header is set correctly - expect(optionsPassedToInit.auth_handler).toBeDefined() - const authHeader = await optionsPassedToInit.auth_handler.getAuthHeader() - expect(authHeader).toBe(`Bearer ${mockToken}`) - }) - }) - - describe('when IS_DEPLOY_SERVICE_ENABLED = false', () => { - beforeEach(() => { - process.env.IS_DEPLOY_SERVICE_ENABLED = false - }) - - test('No Options : should return the correct Authorization header using getAuthHeader', async () => { - const mockToken = 'mock-access-token' - getToken.mockResolvedValue(mockToken) - - // Spy on runtimeLib.init to capture options before it's used - let capturedOptions - RuntimeLib.init.mockImplementation(async (options) => { - capturedOptions = options // Store options for later verification - return {} // Mock runtimeLib.init() return value - }) - - // Call wsk() which internally sets auth_handler - await command.wsk() - - // Ensure options were captured - expect(capturedOptions).toBeDefined() - expect(capturedOptions.auth_handler).not.toBeDefined() - expect(capturedOptions.apihost).toBeDefined() - expect(capturedOptions.apihost).toBe('some.host') - }) - - test('With Options : should return the correct Authorization header using getAuthHeader', async () => { - const mockToken = 'mock-access-token' - getToken.mockResolvedValue(mockToken) - - const options = { - auth_handler: { - getAuthHeader: async () => `Bearer ${mockToken}` - }, - apihost: 'https://custom-api.adobe.com' - } - - await command.wsk(options) // Call wsk() with an existing options object - - expect(RuntimeLib.init).toHaveBeenCalledWith(options) - }) - - test('Default OW Host testing', async () => { - delete process.env[PropertyEnv.APIHOST] - - const mockToken = 'mock-access-token' - getToken.mockResolvedValue(mockToken) - - // command.getOptions = jest.fn().mockResolvedValue({}) - - // Mock runtimeLib.init to track its calls - const mockInit = jest.fn().mockResolvedValue({}) - RuntimeLib.init = mockInit - - // Call wsk() without options - await command.wsk() - - // Assertions - expect(RuntimeLib.init).toHaveBeenCalled() - - // Verify the passed options contain the default apihost - const optionsPassedToInit = mockInit.mock.calls[0][0] // Get the options passed to init - expect(optionsPassedToInit.apihost).toBe('some.host') - expect(optionsPassedToInit.namespace).toBe('some_namespace') - - // Ensure the Authorization header is set correctly - expect(optionsPassedToInit.auth_handler).not.toBeDefined() - }) - }) - }) }) From 7c9060c367e7a22ccd5440094c362f6867415a27 Mon Sep 17 00:00:00 2001 From: Shazron Abdullah Date: Thu, 22 May 2025 22:28:30 +0800 Subject: [PATCH 6/6] change flag useRuntimeAuth from camelCase to kebabCase use-runtime-auth, add undeploy as a DeployServiceCommand --- src/DeployServiceCommand.js | 4 ++-- src/RuntimeBaseCommand.js | 8 +------- src/commands/runtime/deploy/sync.js | 1 + src/commands/runtime/deploy/undeploy.js | 7 ++++--- test/DeployServiceCommand.test.js | 8 ++++---- test/RuntimeBaseCommand.test.js | 2 +- test/commands/runtime/deploy/undeploy.test.js | 18 +++++++++++++++--- 7 files changed, 28 insertions(+), 20 deletions(-) diff --git a/src/DeployServiceCommand.js b/src/DeployServiceCommand.js index 285292b3..cdba96e4 100644 --- a/src/DeployServiceCommand.js +++ b/src/DeployServiceCommand.js @@ -69,7 +69,7 @@ class DeployServiceCommand extends RuntimeBaseCommand { async setRuntimeApiHostAndAuthHandler (options) { let _options = structuredClone(options) - if (!_options?.useRuntimeAuth) { + if (!_options?.['use-runtime-auth']) { const endpoint = process.env.AIO_DEPLOY_SERVICE_URL ?? PropertyDefault.DEPLOYSERVICEURL _options = _options ?? {} _options.apihost = `${endpoint}/runtime` @@ -91,7 +91,7 @@ class DeployServiceCommand extends RuntimeBaseCommand { DeployServiceCommand.flags = { ...RuntimeBaseCommand.flags, - useRuntimeAuth: Flags.boolean({ char: 'r', description: 'use Runtime auth [default: false]', default: false }) + 'use-runtime-auth': Flags.boolean({ char: 'r', description: 'use Runtime auth [default: false]', default: false }) } module.exports = DeployServiceCommand diff --git a/src/RuntimeBaseCommand.js b/src/RuntimeBaseCommand.js index 605cc10e..70189ebd 100644 --- a/src/RuntimeBaseCommand.js +++ b/src/RuntimeBaseCommand.js @@ -19,12 +19,6 @@ const http = require('http') const runtimeLib = require('@adobe/aio-lib-runtime') const config = require('@adobe/aio-lib-core-config') -/** - * @typedef {object} WskCreateOptions - * @property {boolean} [useRuntimeAuth=false] - Whether to use Runtime authentication - * @property {object} [wskClientOptions] - The options to pass to the wsk client. If not provided, will be generated from getOptions() - */ - class RuntimeBaseCommand extends Command { async getOptions () { const { flags } = await this.parse(this.constructor) @@ -38,7 +32,7 @@ class RuntimeBaseCommand extends Command { namespace: config.get('runtime.namespace') || properties.get('NAMESPACE'), api_key: flags.auth || config.get('runtime.auth') || properties.get('AUTH'), ignore_certs: flags.insecure || config.get('runtime.insecure'), - useRuntimeAuth: process.env.USE_RUNTIME_AUTH || flags.useRuntimeAuth + 'use-runtime-auth': process.env.USE_RUNTIME_AUTH || flags['use-runtime-auth'] } // remove any null or undefined keys diff --git a/src/commands/runtime/deploy/sync.js b/src/commands/runtime/deploy/sync.js index cfd3d9b3..a72912e5 100644 --- a/src/commands/runtime/deploy/sync.js +++ b/src/commands/runtime/deploy/sync.js @@ -28,6 +28,7 @@ class DeploySync extends DeployServiceCommand { } const params = {} const options = await this.getOptions() + delete options['use-runtime-auth'] const entities = processPackage(packages, deploymentPackages, deploymentTriggers, params, false, options) const ow = await this.wsk() const logger = this.log diff --git a/src/commands/runtime/deploy/undeploy.js b/src/commands/runtime/deploy/undeploy.js index 08410ba8..b1dd0e75 100644 --- a/src/commands/runtime/deploy/undeploy.js +++ b/src/commands/runtime/deploy/undeploy.js @@ -10,15 +10,16 @@ OF ANY KIND, either express or implied. See the License for the specific languag governing permissions and limitations under the License. */ -const RuntimeBaseCommand = require('../../../RuntimeBaseCommand') +const DeployServiceCommand = require('../../../DeployServiceCommand') const { getProjectEntities, undeployPackage, processPackage, setPaths } = require('@adobe/aio-lib-runtime').utils const { Flags } = require('@oclif/core') -class DeployUndeploy extends RuntimeBaseCommand { +class DeployUndeploy extends DeployServiceCommand { async run () { const { flags } = await this.parse(DeployUndeploy) try { const options = await this.getOptions() + delete options['use-runtime-auth'] const ow = await this.wsk() const logger = this.log @@ -44,7 +45,7 @@ class DeployUndeploy extends RuntimeBaseCommand { } DeployUndeploy.flags = { - ...RuntimeBaseCommand.flags, + ...DeployServiceCommand.flags, manifest: Flags.string({ char: 'm', description: 'the manifest file location' // help description for flag diff --git a/test/DeployServiceCommand.test.js b/test/DeployServiceCommand.test.js index 59c30ced..0189204b 100644 --- a/test/DeployServiceCommand.test.js +++ b/test/DeployServiceCommand.test.js @@ -50,7 +50,7 @@ describe('DeployServiceCommand', () => { test('flags', async () => { expect(Object.keys(TheCommand.flags)).toEqual(expect.arrayContaining([ - 'useRuntimeAuth' + 'use-runtime-auth' ])) }) @@ -134,7 +134,7 @@ describe('DeployServiceCommand', () => { expect(result.auth_handler).toBeDefined() }) - test('should set runtime API host and auth handler when useRuntimeAuth is false', async () => { + test('should set runtime API host and auth handler when use-runtime-auth is false', async () => { const mockOptions = { someOption: 'value' } const result = await command.setRuntimeApiHostAndAuthHandler(mockOptions) @@ -142,8 +142,8 @@ describe('DeployServiceCommand', () => { expect(result.auth_handler).toBeDefined() }) - test('should not modify options when useRuntimeAuth is true', async () => { - const mockOptions = { useRuntimeAuth: true, someOption: 'value' } + test('should not modify options when use-runtime-auth is true', async () => { + const mockOptions = { 'use-runtime-auth': true, someOption: 'value' } const result = await command.setRuntimeApiHostAndAuthHandler(mockOptions) expect(result).toEqual(mockOptions) diff --git a/test/RuntimeBaseCommand.test.js b/test/RuntimeBaseCommand.test.js index fa9d578a..4bab89b0 100644 --- a/test/RuntimeBaseCommand.test.js +++ b/test/RuntimeBaseCommand.test.js @@ -238,7 +238,7 @@ describe('instance methods', () => { test('returns a promise (pass options)', () => { RuntimeLib.init.mockReturnValue({}) - const options = { useRuntimeAuth: true } + const options = {} return command.wsk(options).then((ow) => { expect(ow).toBeDefined() }) diff --git a/test/commands/runtime/deploy/undeploy.test.js b/test/commands/runtime/deploy/undeploy.test.js index 1f1b55d8..cea598ad 100644 --- a/test/commands/runtime/deploy/undeploy.test.js +++ b/test/commands/runtime/deploy/undeploy.test.js @@ -41,7 +41,12 @@ test('flags', async () => { // some expected fake values const expectedEntities = { fake: 'entities' } const expectedEntitiesFromGet = { fakeGet: 'getentities' } -const expectedOWOptions = { api_key: 'some-gibberish-not-a-real-key', apihost: 'some.host', apiversion: 'v1', namespace: 'some_namespace' } +const expectedOWOptions = { + api_key: 'some-gibberish-not-a-real-key', + apihost: 'some.host', + apiversion: 'v1', + namespace: 'some_namespace' +} const expectedDepPackages = { fake: 'dep-packages' } const expectedDepTriggers = [{ fake: 'dep-triggers' }] const expectedPackages = { fake: 'packages' } @@ -75,7 +80,10 @@ describe('instance methods', () => { test('run with no flags', async () => { command.argv = [] await command.run() - expect(utils.setPaths).toHaveBeenCalledWith({ useragent: pkgNameVersion }) + expect(utils.setPaths).toHaveBeenCalledWith({ + 'use-runtime-auth': false, + useragent: pkgNameVersion + }) expect(utils.processPackage).toHaveBeenCalledWith(expectedPackages, {}, {}, {}, true, expectedOWOptions) expect(utils.getProjectEntities).not.toHaveBeenCalled() @@ -88,7 +96,11 @@ describe('instance methods', () => { test('run with manifest flag', async () => { command.argv = ['-m', 'fake-manifest.yml'] await command.run() - expect(utils.setPaths).toHaveBeenCalledWith({ manifest: 'fake-manifest.yml', useragent: pkgNameVersion }) + expect(utils.setPaths).toHaveBeenCalledWith({ + 'use-runtime-auth': false, + manifest: 'fake-manifest.yml', + useragent: pkgNameVersion + }) expect(utils.processPackage).toHaveBeenCalledWith(expectedPackages, {}, {}, {}, true, expectedOWOptions) expect(utils.getProjectEntities).not.toHaveBeenCalled()