@adobe/aio-cli-plugin-app 11.1.0 → 12.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -18,7 +18,7 @@ const chalk = require('chalk')
18
18
  const coreConfig = require('@adobe/aio-lib-core-config')
19
19
  const DEFAULT_LAUNCH_PREFIX = 'https://experience.adobe.com/?devMode=true#/custom-apps/?localDevUrl='
20
20
  const STAGE_LAUNCH_PREFIX = 'https://experience-stage.adobe.com/?devMode=true#/custom-apps/?localDevUrl='
21
- const loadConfig = require('@adobe/aio-cli-lib-app-config')
21
+ const appConfig = require('@adobe/aio-cli-lib-app-config')
22
22
  const inquirer = require('inquirer')
23
23
  const { CONSOLE_API_KEYS, APPLICATION_CONFIG_KEY, EXTENSIONS_CONFIG_KEY } = require('./lib/defaults')
24
24
  const { getCliInfo } = require('./lib/app-helper')
@@ -35,20 +35,7 @@ class BaseCommand extends Command {
35
35
  async catch (error) {
36
36
  const { flags } = await this.parse(this.prototype)
37
37
  aioLogger.error(error) // debug log
38
- this.handleError(error, flags.verbose)
39
- }
40
-
41
- handleError (error, verbose) {
42
- const errorMessages = ['no such file or directory', 'find configuration']
43
- if (errorMessages.find(msg => error.message.includes(msg))) {
44
- const errorList = [
45
- 'Not a valid application root folder.',
46
- 'Please run \'aio app\' commands from a folder generated by aio app init',
47
- verbose ? error.stack : error.message
48
- ]
49
- this.error(errorList.join('\n'))
50
- }
51
- this.error(error.message)
38
+ this.error(flags.verbose ? error.stack : error.message)
52
39
  }
53
40
 
54
41
  async init () {
@@ -71,8 +58,8 @@ class BaseCommand extends Command {
71
58
  LibConsoleCLI.cleanStdOut()
72
59
  }
73
60
 
74
- getAppExtConfigs (flags, options = {}) {
75
- const all = this.getFullConfig(options).all
61
+ async getAppExtConfigs (flags, options = {}) {
62
+ const all = (await this.getFullConfig(options)).all
76
63
 
77
64
  // default case: no flags, return all
78
65
  let ret = all
@@ -102,41 +89,41 @@ class BaseCommand extends Command {
102
89
  return ret
103
90
  }
104
91
 
105
- getRuntimeManifestConfigFile (implName) {
92
+ async getRuntimeManifestConfigFile (implName) {
106
93
  let configKey
107
94
  if (implName === APPLICATION_CONFIG_KEY) {
108
95
  configKey = APPLICATION_CONFIG_KEY
109
96
  } else {
110
97
  configKey = `${EXTENSIONS_CONFIG_KEY}.${implName}`
111
98
  }
112
- let configData = this.getConfigFileForKey(`${configKey}.runtimeManifest`)
99
+ let configData = await this.getConfigFileForKey(`${configKey}.runtimeManifest`)
113
100
  if (!configData.file) {
114
101
  // first action manifest is not defined
115
- configData = this.getConfigFileForKey(`${configKey}`)
102
+ configData = await this.getConfigFileForKey(`${configKey}`)
116
103
  configData.key = configData.key + '.runtimeManifest'
117
104
  }
118
105
  return configData
119
106
  }
120
107
 
121
- getEventsConfigFile (implName) {
108
+ async getEventsConfigFile (implName) {
122
109
  let configKey
123
110
  if (implName === APPLICATION_CONFIG_KEY) {
124
111
  configKey = APPLICATION_CONFIG_KEY
125
112
  } else {
126
113
  configKey = `${EXTENSIONS_CONFIG_KEY}.${implName}`
127
114
  }
128
- let configData = this.getConfigFileForKey(`${configKey}.events`)
115
+ let configData = await this.getConfigFileForKey(`${configKey}.events`)
129
116
  if (!configData.file) {
130
117
  // first events manifest is not defined
131
- configData = this.getConfigFileForKey(`${configKey}`)
118
+ configData = await this.getConfigFileForKey(`${configKey}`)
132
119
  configData.key = configData.key + '.events'
133
120
  }
134
121
  return configData
135
122
  }
136
123
 
137
- getConfigFileForKey (fullKey) {
124
+ async getConfigFileForKey (fullKey) {
138
125
  // NOTE: the index returns undefined if the key is loaded from a legacy configuration file
139
- const fullConfig = this.getFullConfig()
126
+ const fullConfig = await this.getFullConfig()
140
127
  // full key like 'extensions.dx/excshell/1.runtimeManifest'
141
128
  // returns { key: relKey, file: configFile}
142
129
  const configData = fullConfig.includeIndex[fullKey]
@@ -148,9 +135,13 @@ class BaseCommand extends Command {
148
135
  return configData || {}
149
136
  }
150
137
 
151
- getFullConfig (options = {}) {
138
+ async getFullConfig (options = {}) {
139
+ // validate appConfig defaults to false for now
140
+ const validateAppConfig = options.validateAppConfig === true
141
+
152
142
  if (!this.appConfig) {
153
- this.appConfig = loadConfig(options)
143
+ // this will explicitly set validateAppConfig=false if not set
144
+ this.appConfig = await appConfig.load({ ...options, validateAppConfig })
154
145
  }
155
146
  return this.appConfig
156
147
  }
@@ -24,7 +24,7 @@ class AddActionCommand extends TemplatesCommand {
24
24
  aioLogger.debug(`add actions with flags: ${JSON.stringify(flags)}`)
25
25
 
26
26
  // guaranteed to have at least one, otherwise would throw in config load or in matching the ext name
27
- const entries = Object.entries(this.getAppExtConfigs(flags))
27
+ const entries = Object.entries(await this.getAppExtConfigs(flags))
28
28
  if (entries.length > 1) {
29
29
  this.error('Please use the \'-e\' flag to specify to which implementation you want to add actions to.')
30
30
  }
@@ -32,7 +32,7 @@ class AddActionCommand extends TemplatesCommand {
32
32
  const config = entries[0][1]
33
33
 
34
34
  const actionFolder = path.relative(config.root, config.actions.src)
35
- const configData = this.getRuntimeManifestConfigFile(configName)
35
+ const configData = await this.getRuntimeManifestConfigFile(configName)
36
36
 
37
37
  const projectOrgId = aioConfigLoader.get('project.org.id')
38
38
  if (!projectOrgId) {
@@ -23,7 +23,7 @@ class AddEventCommand extends TemplatesCommand {
23
23
  aioLogger.debug(`add events with flags: ${JSON.stringify(flags)}`)
24
24
 
25
25
  // guaranteed to have at least one, otherwise would throw in config load or in matching the ext name
26
- const entries = Object.entries(this.getAppExtConfigs(flags))
26
+ const entries = Object.entries(await this.getAppExtConfigs(flags))
27
27
  if (entries.length > 1) {
28
28
  this.error('Please use the \'-e\' flag to specify to which implementation you want to add events to.')
29
29
  }
@@ -31,8 +31,8 @@ class AddEventCommand extends TemplatesCommand {
31
31
  const configName = entries[0][0]
32
32
  const config = entries[0][1]
33
33
  const actionFolder = path.relative(config.root, config.actions.src)
34
- const runtimeManifestData = this.getRuntimeManifestConfigFile(configName)
35
- const eventsData = this.getEventsConfigFile(configName)
34
+ const runtimeManifestData = await this.getRuntimeManifestConfigFile(configName)
35
+ const eventsData = await this.getEventsConfigFile(configName)
36
36
  const templateOptions = {
37
37
  'skip-prompt': false,
38
38
  'action-folder': actionFolder,
@@ -24,7 +24,7 @@ class AddExtensionCommand extends TemplatesCommand {
24
24
  this.error('--extension= must also be provided when using --yes')
25
25
  }
26
26
 
27
- const fullConfig = this.getFullConfig({ allowNoImpl: true })
27
+ const fullConfig = await this.getFullConfig({ allowNoImpl: true })
28
28
  const alreadyImplemented = fullConfig.implements
29
29
 
30
30
  if (flags.extension) {
@@ -19,9 +19,9 @@ class AddWebAssetsCommand extends TemplatesCommand {
19
19
  const { flags } = await this.parse(AddWebAssetsCommand)
20
20
  aioLogger.debug(`add web-assets with flags: ${JSON.stringify(flags)}`)
21
21
 
22
- const projectName = this.getFullConfig().packagejson.name
22
+ const projectName = (await this.getFullConfig()).packagejson.name
23
23
  // guaranteed to have at least one, otherwise would throw in config load or in matching the ext name
24
- const entries = Object.entries(this.getAppExtConfigs(flags))
24
+ const entries = Object.entries(await this.getAppExtConfigs(flags))
25
25
  if (entries.length > 1) {
26
26
  this.error('Please use the \'-e\' flag to specify to which implementation you want to add web-assets to.')
27
27
  }
@@ -28,7 +28,7 @@ class Build extends BaseCommand {
28
28
  // flags
29
29
  flags['web-assets'] = flags['web-assets'] && !flags.action
30
30
 
31
- const buildConfigs = this.getAppExtConfigs(flags)
31
+ const buildConfigs = await this.getAppExtConfigs(flags)
32
32
 
33
33
  // 1. build actions and web assets for each extension
34
34
  const keys = Object.keys(buildConfigs)
@@ -116,6 +116,8 @@ class Build extends BaseCommand {
116
116
  shouldOptimize: flags['web-optimize'],
117
117
  logLevel: flags.verbose ? 'verbose' : 'warn'
118
118
  }
119
+ // empty the dist folder to prevent an S3 explosion
120
+ fs.emptyDirSync(config.web.distProd)
119
121
  const bundler = await bundle(entries, config.web.distProd, bundleOptions, onProgress)
120
122
  await bundler.run()
121
123
  spinner.succeed(chalk.green(`Building web assets for '${name}'`))
@@ -30,7 +30,7 @@ class ErrorsCommand extends BaseCommand {
30
30
  }
31
31
 
32
32
  async getLogForwarding () {
33
- const runtimeConfig = this.getFullConfig().aio.runtime
33
+ const runtimeConfig = (await this.getFullConfig()).aio.runtime
34
34
  rtLib.utils.checkOpenWhiskCredentials({ ow: runtimeConfig })
35
35
  const rt = await rtLib.init({
36
36
  ...runtimeConfig,
@@ -14,7 +14,7 @@ const LogForwarding = require('../../../../lib/log-forwarding')
14
14
 
15
15
  class LogForwardingCommand extends BaseCommand {
16
16
  async run () {
17
- const lf = await LogForwarding.init(this.getFullConfig().aio)
17
+ const lf = await LogForwarding.init(await this.getFullConfig().aio)
18
18
 
19
19
  const localConfig = lf.getLocalConfig()
20
20
  const serverConfig = await lf.getServerConfig()
@@ -11,10 +11,11 @@ governing permissions and limitations under the License.
11
11
 
12
12
  const BaseCommand = require('../../../../BaseCommand')
13
13
  const LogForwarding = require('../../../../lib/log-forwarding')
14
+ const aioLogger = require('@adobe/aio-lib-core-logging')('@adobe/aio-cli-plugin-app:lf:set', { provider: 'debug' })
14
15
 
15
16
  class LogForwardingCommand extends BaseCommand {
16
17
  async run () {
17
- const lf = await LogForwarding.init(this.getFullConfig().aio)
18
+ const lf = await LogForwarding.init((await this.getFullConfig()).aio)
18
19
 
19
20
  const destination = await this.promptDestination(lf.getSupportedDestinations())
20
21
  const destinationSettingsConfig = lf.getSettingsConfig(destination)
@@ -25,8 +26,12 @@ class LogForwardingCommand extends BaseCommand {
25
26
  this.log(`Log forwarding is set to '${destination}'`)
26
27
 
27
28
  const fullSanitizedConfig = lfConfig.getMergedConfig(lf.getConfigFromJson(res))
28
- await lf.updateLocalConfig(fullSanitizedConfig)
29
- this.log('Log forwarding settings are saved to the local configuration')
29
+ lf.updateLocalConfig(fullSanitizedConfig).then(() => {
30
+ this.log('Log forwarding settings are saved to the local configuration')
31
+ }).catch(e => {
32
+ this.warn('Log forwarding settings could not be saved to the local configuration.')
33
+ aioLogger.error(e.message)
34
+ })
30
35
  }
31
36
 
32
37
  async promptDestination (supportedDestinations) {
@@ -30,8 +30,8 @@ class DeleteActionCommand extends BaseCommand {
30
30
  this.error('<action-name> must also be provided when using --yes')
31
31
  }
32
32
 
33
- const fullConfig = this.getFullConfig()
34
- const { actions, actionsByImpl } = this.getAllActions(fullConfig)
33
+ const fullConfig = await this.getFullConfig()
34
+ const { actions, actionsByImpl } = await this.getAllActions(fullConfig)
35
35
  if (actions.length <= 0) {
36
36
  this.error('There are no actions in this project!')
37
37
  }
@@ -108,17 +108,20 @@ class DeleteActionCommand extends BaseCommand {
108
108
  )))
109
109
  }
110
110
 
111
- getAllActions (config) {
111
+ async getAllActions (config) {
112
112
  const actions = []
113
113
  const actionsByImpl = {}
114
- Object.entries(config.all).forEach(([implName, implConfig]) => {
114
+ const allConfigEntries = Object.entries(config.all)
115
+ for (const [implName, implConfig] of allConfigEntries) {
115
116
  if (implConfig.app.hasBackend) {
116
117
  actionsByImpl[implName] = []
117
- Object.entries(implConfig.manifest.full.packages).forEach(([pkgName, pkg]) => {
118
- Object.entries(pkg.actions).forEach(([actionName, action]) => {
118
+ const allPackagesEntries = Object.entries(implConfig.manifest.full.packages)
119
+ for (const [pkgName, pkg] of allPackagesEntries) {
120
+ const actionEntries = Object.entries(pkg.actions)
121
+ for (const [actionName, action] of actionEntries) {
119
122
  const fullActionName = `${pkgName}/${actionName}`
120
123
  const startKey = implName === 'application' ? 'application' : `extensions.${implName}`
121
- const configData = this.getConfigFileForKey(`${startKey}.runtimeManifest.packages.${pkgName}.actions.${actionName}`)
124
+ const configData = await this.getConfigFileForKey(`${startKey}.runtimeManifest.packages.${pkgName}.actions.${actionName}`)
122
125
  const actionObj = {
123
126
  // assumes path is not relative
124
127
  path: action.function,
@@ -131,12 +134,12 @@ class DeleteActionCommand extends BaseCommand {
131
134
  }
132
135
  actions.push(actionObj)
133
136
  actionsByImpl[implName].push(actionObj)
134
- })
135
- })
137
+ }
138
+ }
136
139
  } else {
137
140
  aioLogger.debug(`'${implName}' .app.hasBackend is not true`)
138
141
  }
139
- })
142
+ }
140
143
  return { actions, actionsByImpl }
141
144
  }
142
145
  }
@@ -28,7 +28,7 @@ class DeleteExtensionCommand extends BaseCommand {
28
28
  this.error('--extension= must also be provided when using --yes')
29
29
  }
30
30
 
31
- const fullConfig = this.getFullConfig({ allowNoImpl: true })
31
+ const fullConfig = await this.getFullConfig({ allowNoImpl: true })
32
32
  const configs = await this.selectOrGetConfigsToDelete(flags, fullConfig)
33
33
 
34
34
  const resConfirm = await this.prompt([
@@ -68,11 +68,11 @@ class DeleteExtensionCommand extends BaseCommand {
68
68
  }])
69
69
  flags.extension = answers.res
70
70
  }
71
- return this.getAppExtConfigs(flags)
71
+ return await this.getAppExtConfigs(flags)
72
72
  }
73
73
 
74
- deleteImplementations (configs) {
75
- Object.entries(configs).forEach(([id, c]) => {
74
+ async deleteImplementations (configs) {
75
+ for (const [id, c] of Object.entries(configs)) {
76
76
  // delete actions
77
77
  if (c.app.hasBackend) {
78
78
  fs.removeSync(c.actions.src)
@@ -89,14 +89,14 @@ class DeleteExtensionCommand extends BaseCommand {
89
89
  // delete config
90
90
  // try to find another config file => case of init extension in another folder
91
91
  const configKey = id === 'application' ? 'application' : `extensions.${id}`
92
- const configDataOp = this.getConfigFileForKey(configKey + '.operations')
92
+ const configDataOp = await this.getConfigFileForKey(configKey + '.operations')
93
93
  if (configDataOp.file) {
94
94
  fs.removeSync(configDataOp.file)
95
95
  }
96
96
  // delete config in parent config file
97
- const configData = this.getConfigFileForKey(configKey)
97
+ const configData = await this.getConfigFileForKey(configKey)
98
98
  deleteUserConfig(configData)
99
- })
99
+ }
100
100
  }
101
101
  }
102
102
 
@@ -25,7 +25,7 @@ class DeleteWebAssetsCommand extends BaseCommand {
25
25
 
26
26
  aioLogger.debug(`deleting web assets from the project, using flags: ${JSON.stringify(flags)}`)
27
27
 
28
- const fullConfig = this.getFullConfig()
28
+ const fullConfig = await this.getFullConfig()
29
29
  const webAssetsByImpl = this.getAllWebAssets(fullConfig)
30
30
  if (!webAssetsByImpl) {
31
31
  this.error('web-assets not found')
@@ -34,7 +34,7 @@ class Deploy extends BuildCommand {
34
34
  flags['web-assets'] = flags['web-assets'] && !flags.action
35
35
  flags.publish = flags.publish && !flags.action
36
36
 
37
- const deployConfigs = this.getAppExtConfigs(flags)
37
+ const deployConfigs = await this.getAppExtConfigs(flags)
38
38
  const keys = Object.keys(deployConfigs)
39
39
  const values = Object.values(deployConfigs)
40
40
  const isStandaloneApp = (keys.length === 1 && keys[0] === 'application')
@@ -55,7 +55,7 @@ class Deploy extends BuildCommand {
55
55
  const spinner = ora()
56
56
 
57
57
  try {
58
- const aioConfig = this.getFullConfig().aio
58
+ const aioConfig = (await this.getFullConfig()).aio
59
59
 
60
60
  // 1. update log forwarding configuration
61
61
  // note: it is possible that .aio file does not exist, which means there is no local lg config
@@ -84,13 +84,16 @@ class Deploy extends BuildCommand {
84
84
  }
85
85
  }
86
86
 
87
- // 2. Bail if workspace is production and application status is PUBLISHED, honor force-deploy
88
- if (!isStandaloneApp && aioConfig?.project?.workspace?.name === 'Production' && !flags['force-deploy']) {
87
+ // 2. If workspace is prod and has extensions, check if the app is published
88
+ if (!isStandaloneApp && aioConfig?.project?.workspace?.name === 'Production') {
89
89
  const extension = await this.getApplicationExtension(libConsoleCLI, aioConfig)
90
- spinner.info(chalk.dim(JSON.stringify(extension)))
91
90
  if (extension && extension.status === 'PUBLISHED') {
92
- spinner.info(chalk.red('This application is published and the current workspace is Production, deployment will be skipped. You must first retract this application in Adobe Exchange to deploy updates.'))
93
- return
91
+ flags.publish = false // if the app is production and published, then skip publish later on
92
+ // if the app is published and no force-deploy flag is set, then skip deployment
93
+ if (!flags['force-deploy']) {
94
+ spinner.info(chalk.red('This application is published and the current workspace is Production, deployment will be skipped. You must first retract this application in Adobe Exchange to deploy updates.'))
95
+ return
96
+ }
94
97
  }
95
98
  }
96
99
 
@@ -342,7 +345,8 @@ Deploy.flags = {
342
345
  }),
343
346
  'force-deploy': Flags.boolean({
344
347
  description: '[default: false] Force deploy changes, regardless of production Workspace being published in Exchange.',
345
- default: false
348
+ default: false,
349
+ exclusive: ['publish', 'force-publish'] // publish is skipped if force-deploy is set and prod app is published
346
350
  }),
347
351
  'force-publish': Flags.boolean({
348
352
  description: '[default: false] Force publish extension(s) to Exchange, delete previously published extension points',
@@ -31,7 +31,7 @@ class GetUrlCommand extends BaseCommand {
31
31
  options.cdn = flags.cdn
32
32
 
33
33
  const urls = {}
34
- const fullConfig = this.getFullConfig()
34
+ const fullConfig = await this.getFullConfig()
35
35
  if (options.action) {
36
36
  let action
37
37
  // search for action
@@ -19,7 +19,7 @@ class Info extends BaseCommand {
19
19
  async run () {
20
20
  // cli input
21
21
  const { flags } = await this.parse(Info)
22
- const appConfig = deepCopy(this.getFullConfig({ allowNoImpl: true }))
22
+ const appConfig = deepCopy(await this.getFullConfig({ allowNoImpl: true }))
23
23
 
24
24
  // includes .env secret delete all aio config for now
25
25
  delete appConfig.aio
@@ -104,7 +104,7 @@ class InitCommand extends TemplatesCommand {
104
104
  }
105
105
 
106
106
  if (flags.repo) {
107
- await this.withQuickstart(flags.repo)
107
+ await this.withQuickstart(flags.repo, flags['github-pat'])
108
108
  } else {
109
109
  // 2. prompt for templates to be installed
110
110
  const templates = await this.getTemplatesForFlags(flags)
@@ -134,7 +134,7 @@ class InitCommand extends TemplatesCommand {
134
134
 
135
135
  async initWithLogin (flags) {
136
136
  if (flags.repo) {
137
- await this.withQuickstart(flags.repo)
137
+ await this.withQuickstart(flags.repo, flags['github-pat'])
138
138
  }
139
139
  // this will trigger a login
140
140
  const consoleCLI = await this.getLibConsoleCLI()
@@ -367,9 +367,10 @@ class InitCommand extends TemplatesCommand {
367
367
  )
368
368
  }
369
369
 
370
- async withQuickstart (fullRepo) {
370
+ async withQuickstart (fullRepo, githubPat) {
371
371
  const octokit = new Octokit({
372
- auth: ''
372
+ auth: githubPat ?? '',
373
+ userAgent: 'ADP App Builder v1'
373
374
  })
374
375
  const spinner = ora('Downloading quickstart repo').start()
375
376
  /** @private */
@@ -468,8 +469,9 @@ InitCommand.flags = {
468
469
  exclusive: ['import'] // also no-login
469
470
  }),
470
471
  'confirm-new-workspace': Flags.boolean({
471
- description: 'Skip and confirm prompt for creating a new workspace',
472
- default: false
472
+ description: 'Prompt to confirm before creating a new workspace',
473
+ default: true,
474
+ allowNo: true
473
475
  }),
474
476
  repo: Flags.string({
475
477
  description: 'Init from gh quick-start repo. Expected to be of the form <owner>/<repo>/<path>',
@@ -478,6 +480,10 @@ InitCommand.flags = {
478
480
  'use-jwt': Flags.boolean({
479
481
  description: 'if the config has both jwt and OAuth Server to Server Credentials (while migrating), prefer the JWT credentials',
480
482
  default: false
483
+ }),
484
+ 'github-pat': Flags.string({
485
+ description: 'github personal access token to use for downloading private quickstart repos',
486
+ dependsOn: ['repo']
481
487
  })
482
488
  }
483
489
 
@@ -21,17 +21,14 @@ const { validateJsonWithSchema } = require('../../lib/install-helper')
21
21
  const jsYaml = require('js-yaml')
22
22
  const { USER_CONFIG_FILE, DEPLOY_CONFIG_FILE } = require('../../lib/defaults')
23
23
  const ora = require('ora')
24
- const chalk = require('chalk')
25
24
 
26
25
  // eslint-disable-next-line node/no-missing-require
27
- const libConfigNext = require('@adobe/aio-cli-lib-app-config-next')
26
+ const libConfig = require('@adobe/aio-cli-lib-app-config')
28
27
 
29
28
  class InstallCommand extends BaseCommand {
30
29
  async run () {
31
30
  const { args, flags } = await this.parse(InstallCommand)
32
31
 
33
- this.preRelease()
34
-
35
32
  aioLogger.debug(`flags: ${JSON.stringify(flags, null, 2)}`)
36
33
  aioLogger.debug(`args: ${JSON.stringify(args, null, 2)}`)
37
34
 
@@ -55,7 +52,9 @@ class InstallCommand extends BaseCommand {
55
52
  await this.validateAppConfig(outputPath, USER_CONFIG_FILE)
56
53
  await this.validateDeployConfig(outputPath, DEPLOY_CONFIG_FILE)
57
54
  await this.npmInstall(flags.verbose)
58
- await this.runTests()
55
+ if (flags.tests) {
56
+ await this.runTests()
57
+ }
59
58
  this.spinner.succeed('Install done.')
60
59
  } catch (e) {
61
60
  this.spinner.fail(e.message)
@@ -114,8 +113,8 @@ class InstallCommand extends BaseCommand {
114
113
  this.spinner.start(`Validating ${configFileName}...`)
115
114
  aioLogger.debug(`validateConfig: ${configFileName} at ${configFilePath}`)
116
115
  // first coalesce the app config (resolving $include files), then validate it
117
- const config = (await libConfigNext.coalesce(configFilePath)).config
118
- await libConfigNext.validate(config, { throws: true }) // throws on error
116
+ const config = (await libConfig.coalesce(configFilePath)).config
117
+ await libConfig.validate(config, { throws: true }) // throws on error
119
118
  this.spinner.succeed(`Validated ${configFileName}`)
120
119
  }
121
120
 
@@ -153,10 +152,8 @@ class InstallCommand extends BaseCommand {
153
152
  }
154
153
  }
155
154
 
156
- InstallCommand.hidden = true // hide from help for pre-release
157
-
158
- InstallCommand.description = chalk.yellow(`(Pre-release) This command will support installing apps packaged by '<%= config.bin %> app pack'.
159
- `)
155
+ InstallCommand.description = `This command will support installing apps packaged by '<%= config.bin %> app pack'.
156
+ `
160
157
 
161
158
  InstallCommand.flags = {
162
159
  ...BaseCommand.flags,
@@ -164,6 +161,11 @@ InstallCommand.flags = {
164
161
  description: 'The packaged app output folder path',
165
162
  char: 'o',
166
163
  default: '.'
164
+ }),
165
+ tests: Flags.boolean({
166
+ description: 'Run packaged app unit tests (e.g. aio app:test)',
167
+ default: true,
168
+ allowNo: true
167
169
  })
168
170
  }
169
171
 
@@ -22,7 +22,7 @@ class ListExtensionPointsCommand extends BaseCommand {
22
22
  const { flags } = await this.parse(ListExtensionPointsCommand)
23
23
  aioLogger.debug(`list all extensions points with flags: ${JSON.stringify(flags)}`)
24
24
 
25
- const extConfig = this.getAppExtConfigs(flags)
25
+ const extConfig = await this.getAppExtConfigs(flags)
26
26
  const extPointList = {}
27
27
 
28
28
  Object.keys(extConfig).forEach(name => {
@@ -22,7 +22,7 @@ class ListExtensionCommand extends BaseCommand {
22
22
  const { flags } = await this.parse(ListExtensionCommand)
23
23
  aioLogger.debug(`list extensions with flags: ${JSON.stringify(flags)}`)
24
24
 
25
- const extConfig = this.getAppExtConfigs(flags)
25
+ const extConfig = await this.getAppExtConfigs(flags)
26
26
  const extSummary = {}
27
27
 
28
28
  Object.keys(extConfig).forEach(extPoint => {
@@ -36,7 +36,7 @@ class Logs extends BaseCommand {
36
36
 
37
37
  async run () {
38
38
  const { flags } = await this.parse(Logs)
39
- const fullConfig = this.getFullConfig()
39
+ const fullConfig = await this.getFullConfig()
40
40
 
41
41
  // has any backend
42
42
  const hasAnyBackend = Object.values(fullConfig.all).reduce((hasBackend, config) => hasBackend && config.app.hasBackend, true)
@@ -20,11 +20,10 @@ const execa = require('execa')
20
20
  const { loadConfigFile, writeFile } = require('../../lib/import-helper')
21
21
  const { getObjectValue } = require('../../lib/app-helper')
22
22
  const ora = require('ora')
23
- const chalk = require('chalk')
24
23
  const junk = require('junk')
25
24
 
26
25
  // eslint-disable-next-line node/no-missing-require
27
- const libConfigNext = require('@adobe/aio-cli-lib-app-config-next')
26
+ const libConfig = require('@adobe/aio-cli-lib-app-config')
28
27
 
29
28
  const DIST_FOLDER = 'dist'
30
29
  const DEFAULTS = {
@@ -37,13 +36,11 @@ class Pack extends BaseCommand {
37
36
  async run () {
38
37
  const { args, flags } = await this.parse(Pack)
39
38
 
40
- this.preRelease()
41
-
42
39
  aioLogger.debug(`flags: ${JSON.stringify(flags, null, 2)}`)
43
40
  aioLogger.debug(`args: ${JSON.stringify(args, null, 2)}`)
44
41
 
45
42
  // this will also validate the app.config.yaml
46
- const appConfig = await libConfigNext.load()
43
+ const appConfig = await libConfig.load({ validateAppConfig: true })
47
44
 
48
45
  // resolve to absolute path before any chdir
49
46
  const outputZipFile = path.resolve(flags.output)
@@ -356,10 +353,8 @@ class Pack extends BaseCommand {
356
353
  }
357
354
  }
358
355
 
359
- Pack.hidden = true // hide from help for pre-release
360
-
361
- Pack.description = chalk.yellow(`(Pre-release) This command will support packaging apps for redistribution.
362
- `)
356
+ Pack.description = `This command will support packaging apps for redistribution.
357
+ `
363
358
 
364
359
  Pack.flags = {
365
360
  ...BaseCommand.flags,
@@ -37,7 +37,7 @@ class Run extends BaseCommand {
37
37
 
38
38
  const spinner = ora()
39
39
 
40
- const runConfigs = this.getAppExtConfigs(flags)
40
+ const runConfigs = await this.getAppExtConfigs(flags)
41
41
  const entries = Object.entries(runConfigs)
42
42
  if (entries.length > 1) {
43
43
  this.error('Your app implements multiple extensions. You can only run one at the time, please select which extension to run with the \'-e\' flag.')
@@ -31,7 +31,7 @@ class Test extends BaseCommand {
31
31
  unit = true
32
32
  }
33
33
 
34
- const buildConfigs = this.getAppExtConfigs({ extension })
34
+ const buildConfigs = await this.getAppExtConfigs({ extension })
35
35
  aioLogger.debug(`run buildConfigs:${JSON.stringify(buildConfigs, null, 2)}`)
36
36
 
37
37
  const totalResults = []
@@ -25,7 +25,7 @@ class Undeploy extends BaseCommand {
25
25
  // cli input
26
26
  const { flags } = await this.parse(Undeploy)
27
27
 
28
- const undeployConfigs = this.getAppExtConfigs(flags)
28
+ const undeployConfigs = await this.getAppExtConfigs(flags)
29
29
  let libConsoleCLI
30
30
  if (flags.unpublish) {
31
31
  // force login at beginning (if required)
@@ -51,7 +51,7 @@ class Undeploy extends BaseCommand {
51
51
  }
52
52
  // 2. unpublish extension manifest
53
53
  if (flags.unpublish && !(keys.length === 1 && keys[0] === 'application')) {
54
- const aioConfig = this.getFullConfig().aio
54
+ const aioConfig = (await this.getFullConfig()).aio
55
55
  const payload = await this.unpublishExtensionPoints(libConsoleCLI, undeployConfigs, aioConfig, flags['force-unpublish'])
56
56
  this.log(chalk.blue(chalk.bold(`New Extension Point(s) in Workspace '${aioConfig.project.workspace.name}': '${Object.keys(payload.endpoints)}'`)))
57
57
  } else {