@adobe/aio-cli-plugin-app 14.5.1 → 14.5.2-pre.2026-03-11.sha-58926dfa

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.
package/package.json CHANGED
@@ -1,21 +1,22 @@
1
1
  {
2
2
  "name": "@adobe/aio-cli-plugin-app",
3
3
  "description": "Create, Build and Deploy Adobe I/O Applications",
4
- "version": "14.5.1",
4
+ "version": "14.5.2-pre.2026-03-11.sha-58926dfa",
5
5
  "author": "Adobe Inc.",
6
6
  "bugs": "https://github.com/adobe/aio-cli-plugin-app/issues",
7
7
  "dependencies": {
8
- "@adobe/aio-cli-lib-app-config": "^4.0.3",
9
- "@adobe/aio-cli-lib-console": "^5.0.3",
10
- "@adobe/aio-lib-core-config": "^5",
11
- "@adobe/aio-lib-core-logging": "^3",
12
- "@adobe/aio-lib-core-networking": "^5",
13
- "@adobe/aio-lib-env": "^3",
14
- "@adobe/aio-lib-ims": "^7",
15
- "@adobe/aio-lib-runtime": "^7.1.3",
8
+ "@adobe/aio-cli-lib-app-config": "next",
9
+ "@adobe/aio-cli-lib-console": "next",
10
+ "@adobe/aio-lib-core-config": "next",
11
+ "@adobe/aio-lib-core-logging": "next",
12
+ "@adobe/aio-lib-core-networking": "next",
13
+ "@adobe/aio-lib-db": "^0.2.0-beta.1",
14
+ "@adobe/aio-lib-env": "next",
15
+ "@adobe/aio-lib-ims": "next",
16
+ "@adobe/aio-lib-runtime": "next",
16
17
  "@adobe/aio-lib-templates": "^3",
17
- "@adobe/aio-lib-web": "^7.0.6",
18
- "@adobe/generator-aio-app": "^9",
18
+ "@adobe/aio-lib-web": "next",
19
+ "@adobe/generator-aio-app": "next",
19
20
  "@adobe/generator-app-common-lib": "^3",
20
21
  "@adobe/inquirer-table-checkbox": "^2",
21
22
  "@oclif/core": "^2.11.6",
@@ -103,5 +104,6 @@
103
104
  },
104
105
  "bin": {
105
106
  "aio-next": "./bin/run"
106
- }
107
- }
107
+ },
108
+ "prereleaseSha": "58926dfa0a67e1a957eaa48a777e0eae8a93fad4"
109
+ }
@@ -24,6 +24,8 @@ const {
24
24
  getFilesCountWithExtension
25
25
  } = require('../../lib/app-helper')
26
26
  const rtLib = require('@adobe/aio-lib-runtime')
27
+ const dbLib = require('@adobe/aio-lib-db')
28
+ const { DB_STATUS } = require('../../lib/defaults')
27
29
  const LogForwarding = require('../../lib/log-forwarding')
28
30
  const { sendAppAssetsDeployedAuditLog, sendAppDeployAuditLog } = require('../../lib/audit-logger')
29
31
  const { setRuntimeApiHostAndAuthHandler, getAccessToken } = require('../../lib/auth-helper')
@@ -133,7 +135,7 @@ class Deploy extends BuildCommand {
133
135
  const v = {
134
136
  ...setRuntimeApiHostAndAuthHandler(values[i])
135
137
  }
136
- await this.deploySingleConfig({ name: k, config: v, originalConfig: values[i], flags, spinner })
138
+ await this.deploySingleConfig({ name: k, config: v, originalConfig: values[i], flags, spinner, accessToken: cliDetails?.accessToken })
137
139
  if (cliDetails?.accessToken && v.app.hasFrontend && flags['web-assets']) {
138
140
  const opItems = getFilesCountWithExtension(v.web.distProd)
139
141
  try {
@@ -172,7 +174,7 @@ class Deploy extends BuildCommand {
172
174
  this.log(chalk.green(chalk.bold('Successful deployment 🏄')))
173
175
  }
174
176
 
175
- async deploySingleConfig ({ name, config, originalConfig, flags, spinner }) {
177
+ async deploySingleConfig ({ name, config, originalConfig, flags, spinner, accessToken }) {
176
178
  const onProgress = !flags.verbose
177
179
  ? info => {
178
180
  spinner.text = info
@@ -204,6 +206,11 @@ class Deploy extends BuildCommand {
204
206
  this.error(err)
205
207
  }
206
208
 
209
+ // provision database if configured
210
+ if (config.manifest?.full?.database?.['auto-provision'] === true) {
211
+ await this.provisionDatabase(config, spinner, flags, accessToken)
212
+ }
213
+
207
214
  if (flags.actions) {
208
215
  if (config.app.hasBackend) {
209
216
  let filterEntities
@@ -300,6 +307,79 @@ class Deploy extends BuildCommand {
300
307
  }
301
308
  }
302
309
 
310
+ async provisionDatabase (config, spinner, flags, accessToken) {
311
+ const { namespace } = config.ow || {}
312
+ if (!(namespace)) {
313
+ throw new Error('Database deployment requires OW namespace configuration.')
314
+ }
315
+ if (!accessToken) {
316
+ throw new Error('Database deployment requires an IMS access token.')
317
+ }
318
+
319
+ const region = config.manifest?.full?.database?.region
320
+ const regionMess = region ? `'${region}'` : 'default'
321
+
322
+ const progress = ({ next = undefined, status = undefined, verboseOnly = false }, statusMethod = spinner.info) => {
323
+ if (flags.verbose) {
324
+ const method = statusMethod.bind(spinner)
325
+ method(status)
326
+ spinner.start(next)
327
+ } else if (next && !verboseOnly) {
328
+ spinner.text = next
329
+ }
330
+ }
331
+
332
+ let provRes
333
+ try {
334
+ spinner.start(`Deploying database in the ${regionMess} region...`)
335
+
336
+ const db = await dbLib.init({ ow: { namespace }, region, token: accessToken })
337
+
338
+ progress({ next: 'Checking existing database deployment status...', verboseOnly: true })
339
+
340
+ let prevStatus
341
+ let statusRegion
342
+ const next = `Submitting database provisioning request in the ${regionMess} region...`
343
+ try {
344
+ const statusRes = await db.provisionStatus()
345
+ prevStatus = statusRes.status.toUpperCase()
346
+ statusRegion = statusRes.region
347
+ const regionMessage = statusRegion ? ` in region '${statusRegion}'` : ''
348
+ progress({ status: chalk.dim(`Existing database provisioning status: ${prevStatus}${regionMessage}`), next })
349
+ } catch (err) {
350
+ progress({ status: chalk.red(`Database status check failed: ${err.message}`), next }, spinner.warn)
351
+ prevStatus = null
352
+ }
353
+
354
+ if (prevStatus === DB_STATUS.PROVISIONED) {
355
+ spinner.succeed(chalk.green(`Database is deployed and ready for use in the '${statusRegion}' region`))
356
+ return
357
+ } else if (prevStatus === DB_STATUS.REQUESTED || prevStatus === DB_STATUS.PROCESSING) {
358
+ spinner.succeed(chalk.green(`Database provisioning request has already been submitted in the '${statusRegion}' region and is pending`))
359
+ return
360
+ }
361
+
362
+ provRes = await db.provisionRequest()
363
+ progress({ status: chalk.dim(`Database provisioning result:\n${JSON.stringify(provRes, null, 2)}`) })
364
+ } catch (error) {
365
+ spinner.fail(chalk.red('Database deployment failed'))
366
+ throw error
367
+ }
368
+
369
+ const resultStatus = provRes?.status?.toUpperCase() || DB_STATUS.UNKNOWN
370
+ if (resultStatus === DB_STATUS.PROVISIONED) {
371
+ spinner.succeed(chalk.green(`Database is deployed and ready for use in the '${provRes.region}' region`))
372
+ } else if (resultStatus === DB_STATUS.REQUESTED || resultStatus === DB_STATUS.PROCESSING) {
373
+ spinner.succeed(chalk.green(`Database provisioning request submitted in the '${provRes.region}' region, database deployment is now pending`))
374
+ } else if (resultStatus === DB_STATUS.FAILED || resultStatus === DB_STATUS.REJECTED) {
375
+ const message = `Database provisioning request failed with status '${resultStatus}'`
376
+ spinner.fail(chalk.red(message))
377
+ throw new Error(`${message}: ${provRes.message || 'Unknown error'}`)
378
+ } else {
379
+ spinner.warn(chalk.yellow(`Database provisioning request returned unexpected status '${resultStatus}', an update to the aio cli tool may be necessary.`))
380
+ }
381
+ }
382
+
303
383
  async publishExtensionPoints (deployConfigs, aioConfig, force) {
304
384
  const libConsoleCLI = await this.getLibConsoleCLI()
305
385
 
@@ -50,65 +50,60 @@ class Undeploy extends BaseCommand {
50
50
  }
51
51
 
52
52
  const spinner = ora()
53
- try {
54
- const { aio: aioConfig, packagejson: packageJson } = await this.getFullConfig({}, flags)
55
- const cliDetails = await getAccessToken({ useCachedToken: !flags.unpublish })
56
- const appInfo = {
57
- name: packageJson.name,
58
- version: packageJson.version,
59
- project: aioConfig?.project,
60
- runtimeNamespace: aioConfig?.runtime?.namespace
53
+
54
+ const { aio: aioConfig, packagejson: packageJson } = await this.getFullConfig({}, flags)
55
+ const cliDetails = await getAccessToken({ useCachedToken: !flags.unpublish })
56
+ const appInfo = {
57
+ name: packageJson.name,
58
+ version: packageJson.version,
59
+ project: aioConfig?.project,
60
+ runtimeNamespace: aioConfig?.runtime?.namespace
61
+ }
62
+
63
+ if (cliDetails?.accessToken) {
64
+ try {
65
+ // send audit log at start (don't wait for deployment to finish)
66
+ await sendAppUndeployAuditLog({
67
+ accessToken: cliDetails?.accessToken,
68
+ cliCommandFlags: flags,
69
+ appInfo,
70
+ env: cliDetails.env
71
+ })
72
+ } catch (error) {
73
+ if (flags.verbose) {
74
+ this.warn('Error: Audit Log Service Error: Failed to send audit log event for deployment.')
75
+ this.warn(error.message)
76
+ }
61
77
  }
78
+ }
62
79
 
80
+ for (let i = 0; i < keys.length; ++i) {
81
+ const k = keys[i]
82
+ // TODO: remove this check once the deploy service is enabled by default
83
+ const v = setRuntimeApiHostAndAuthHandler(values[i])
84
+
85
+ await this.undeployOneExt(k, v, flags, spinner)
63
86
  if (cliDetails?.accessToken) {
87
+ // send logs for case of web-assets undeployment
64
88
  try {
65
- // send audit log at start (don't wait for deployment to finish)
66
- await sendAppUndeployAuditLog({
89
+ await sendAppAssetsUndeployedAuditLog({
67
90
  accessToken: cliDetails?.accessToken,
68
91
  cliCommandFlags: flags,
69
92
  appInfo,
70
93
  env: cliDetails.env
71
94
  })
72
95
  } catch (error) {
73
- if (flags.verbose) {
74
- this.warn('Error: Audit Log Service Error: Failed to send audit log event for deployment.')
75
- this.warn(error.message)
76
- }
77
- }
78
- }
79
-
80
- for (let i = 0; i < keys.length; ++i) {
81
- const k = keys[i]
82
- // TODO: remove this check once the deploy service is enabled by default
83
- const v = setRuntimeApiHostAndAuthHandler(values[i])
84
-
85
- await this.undeployOneExt(k, v, flags, spinner)
86
- if (cliDetails?.accessToken) {
87
- // send logs for case of web-assets undeployment
88
- try {
89
- await sendAppAssetsUndeployedAuditLog({
90
- accessToken: cliDetails?.accessToken,
91
- cliCommandFlags: flags,
92
- appInfo,
93
- env: cliDetails.env
94
- })
95
- } catch (error) {
96
- this.warn('Warning: Audit Log Service Error: Failed to send audit log event for un-deployment.')
97
- }
96
+ this.warn('Warning: Audit Log Service Error: Failed to send audit log event for un-deployment.')
98
97
  }
99
98
  }
99
+ }
100
100
 
101
- // 1.2. unpublish extension manifest
102
- if (flags.unpublish) {
103
- const payload = await this.unpublishExtensionPoints(libConsoleCLI, undeployConfigs, aioConfig, flags['force-unpublish'])
104
- this.log(chalk.blue(chalk.bold(`New Extension Point(s) in Workspace '${aioConfig.project.workspace.name}': '${Object.keys(payload.endpoints)}'`)))
105
- } else {
106
- this.log('skipping unpublish phase...')
107
- }
108
- } catch (error) {
109
- spinner.stop()
110
- // delegate to top handler
111
- throw error
101
+ // 1.2. unpublish extension manifest
102
+ if (flags.unpublish) {
103
+ const payload = await this.unpublishExtensionPoints(libConsoleCLI, undeployConfigs, aioConfig, flags['force-unpublish'])
104
+ this.log(chalk.blue(chalk.bold(`New Extension Point(s) in Workspace '${aioConfig.project.workspace.name}': '${Object.keys(payload.endpoints)}'`)))
105
+ } else {
106
+ this.log('skipping unpublish phase...')
112
107
  }
113
108
 
114
109
  const command = await this.config.findCommand('app:clean')
@@ -151,8 +146,7 @@ class Undeploy extends BaseCommand {
151
146
  }
152
147
  spinner.succeed(chalk.green(`Un-deploying actions for ${extName}`))
153
148
  } catch (err) {
154
- spinner.fail(chalk.green(`Un-deploying actions for ${extName}`))
155
- throw err
149
+ spinner.warn(chalk.yellow(`Error when un-deploying actions for ${extName}: ${err.message}`))
156
150
  }
157
151
  } else {
158
152
  this.log('no manifest file, skipping action undeploy')
@@ -168,8 +162,7 @@ class Undeploy extends BaseCommand {
168
162
 
169
163
  spinner.succeed(chalk.green(`Un-Deploying web assets for ${extName}`))
170
164
  } catch (err) {
171
- spinner.fail(chalk.green(`Un-Deploying web assets for ${extName}`))
172
- throw err
165
+ spinner.warn(chalk.yellow(`Error when un-deploying web assets for ${extName}: ${err.message}`))
173
166
  }
174
167
  } else {
175
168
  this.log('no frontend, skipping frontend undeploy')
@@ -41,5 +41,16 @@ module.exports = {
41
41
  EXTENSIONS_CONFIG_KEY: 'extensions',
42
42
  // Adding tracking file constants
43
43
  LAST_BUILT_ACTIONS_FILENAME: 'last-built-actions.json',
44
- LAST_DEPLOYED_ACTIONS_FILENAME: 'last-deployed-actions.json'
44
+ LAST_DEPLOYED_ACTIONS_FILENAME: 'last-deployed-actions.json',
45
+ // Database constants
46
+ DB_STATUS: {
47
+ PROVISIONED: 'PROVISIONED',
48
+ REQUESTED: 'REQUESTED',
49
+ PROCESSING: 'PROCESSING',
50
+ FAILED: 'FAILED',
51
+ REJECTED: 'REJECTED',
52
+ NOT_PROVISIONED: 'NOT_PROVISIONED',
53
+ DELETED: 'DELETED',
54
+ UNKNOWN: 'UNKNOWN'
55
+ }
45
56
  }