@adobe/aio-cli-plugin-app 9.1.1 → 9.2.0-pre.2022-09-27.805ee90c
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/README.md +18 -19
- package/oclif.manifest.json +1 -1
- package/package.json +9 -4
- package/schema/config.schema.json +22 -2
- package/src/AddCommand.js +1 -7
- package/src/TemplatesCommand.js +246 -0
- package/src/commands/app/add/action.js +80 -31
- package/src/commands/app/add/extension.js +27 -77
- package/src/commands/app/add/web-assets.js +29 -27
- package/src/commands/app/delete/extension.js +7 -8
- package/src/commands/app/deploy.js +25 -3
- package/src/commands/app/init.js +165 -144
- package/src/lib/defaults.js +1 -32
|
@@ -55,6 +55,7 @@ class Deploy extends BuildCommand {
|
|
|
55
55
|
|
|
56
56
|
try {
|
|
57
57
|
const aioConfig = this.getFullConfig().aio
|
|
58
|
+
|
|
58
59
|
// 1. update log forwarding configuration
|
|
59
60
|
// note: it is possible that .aio file does not exist, which means there is no local lg config
|
|
60
61
|
if (aioConfig &&
|
|
@@ -83,7 +84,18 @@ class Deploy extends BuildCommand {
|
|
|
83
84
|
throw error
|
|
84
85
|
}
|
|
85
86
|
}
|
|
86
|
-
|
|
87
|
+
|
|
88
|
+
// 2. Bail if workspace is production and application status is PUBLISHED, honor force-deploy
|
|
89
|
+
if (aioConfig.project.workspace.name === 'Production' && !flags['force-deploy']) {
|
|
90
|
+
const extension = await this.getApplicationExtension(libConsoleCLI, aioConfig)
|
|
91
|
+
spinner.info(chalk.dim(JSON.stringify(extension)))
|
|
92
|
+
if (extension && extension.status === 'PUBLISHED') {
|
|
93
|
+
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.'))
|
|
94
|
+
return
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// 3. deploy actions and web assets for each extension
|
|
87
99
|
// Possible improvements:
|
|
88
100
|
// - parallelize
|
|
89
101
|
// - break into smaller pieces deploy, allowing to first deploy all actions then all web assets
|
|
@@ -93,7 +105,7 @@ class Deploy extends BuildCommand {
|
|
|
93
105
|
await this.deploySingleConfig(k, v, flags, spinner)
|
|
94
106
|
}
|
|
95
107
|
|
|
96
|
-
//
|
|
108
|
+
// 4. deploy extension manifest
|
|
97
109
|
if (flags.publish) {
|
|
98
110
|
const payload = await this.publishExtensionPoints(libConsoleCLI, deployConfigs, aioConfig, flags['force-publish'])
|
|
99
111
|
this.log(chalk.blue(chalk.bold(`New Extension Point(s) in Workspace '${aioConfig.project.workspace.name}': '${Object.keys(payload.endpoints)}'`)))
|
|
@@ -249,6 +261,12 @@ class Deploy extends BuildCommand {
|
|
|
249
261
|
newPayload = await libConsoleCLI.updateExtensionPointsWithoutOverwrites(aioConfig.project.org, aioConfig.project, aioConfig.project.workspace, payload)
|
|
250
262
|
return newPayload
|
|
251
263
|
}
|
|
264
|
+
|
|
265
|
+
async getApplicationExtension (libConsoleCLI, aioConfig) {
|
|
266
|
+
const { appId } = await libConsoleCLI.getProject(aioConfig.project.org.id, aioConfig.project.id)
|
|
267
|
+
const applicationExtensions = await libConsoleCLI.getApplicationExtensions(aioConfig.project.org.id, appId)
|
|
268
|
+
return applicationExtensions.find(extension => extension.appId === appId)
|
|
269
|
+
}
|
|
252
270
|
}
|
|
253
271
|
|
|
254
272
|
Deploy.description = `Build and deploy an Adobe I/O App
|
|
@@ -322,8 +340,12 @@ Deploy.flags = {
|
|
|
322
340
|
default: true,
|
|
323
341
|
exclusive: ['action']
|
|
324
342
|
}),
|
|
343
|
+
'force-deploy': Flags.boolean({
|
|
344
|
+
description: '[default: false] Force deploy changes, regardless of production Workspace being published in Exchange.',
|
|
345
|
+
default: false
|
|
346
|
+
}),
|
|
325
347
|
'force-publish': Flags.boolean({
|
|
326
|
-
description: 'Force publish extension(s) to Exchange, delete previously published extension points',
|
|
348
|
+
description: '[default: false] Force publish extension(s) to Exchange, delete previously published extension points',
|
|
327
349
|
default: false,
|
|
328
350
|
exclusive: ['action', 'publish'] // no-publish is excluded
|
|
329
351
|
}),
|
package/src/commands/app/init.js
CHANGED
|
@@ -9,26 +9,24 @@ OF ANY KIND, either express or implied. See the License for the specific languag
|
|
|
9
9
|
governing permissions and limitations under the License.
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
|
-
const
|
|
12
|
+
const TemplatesCommand = require('../../TemplatesCommand')
|
|
13
13
|
const yeoman = require('yeoman-environment')
|
|
14
14
|
const path = require('path')
|
|
15
15
|
const fs = require('fs-extra')
|
|
16
16
|
const ora = require('ora')
|
|
17
17
|
const chalk = require('chalk')
|
|
18
|
-
// const aioLogger = require('@adobe/aio-lib-core-logging')('@adobe/aio-cli-plugin-app:init', { provider: 'debug' })
|
|
19
18
|
const { Flags } = require('@oclif/core')
|
|
20
19
|
const generators = require('@adobe/generator-aio-app')
|
|
20
|
+
const TemplateRegistryAPI = require('@adobe/aio-lib-templates')
|
|
21
|
+
const inquirer = require('inquirer')
|
|
21
22
|
const hyperlinker = require('hyperlinker')
|
|
22
23
|
|
|
23
24
|
const { loadAndValidateConfigFile, importConfigJson } = require('../../lib/import')
|
|
24
|
-
const {
|
|
25
|
-
|
|
26
|
-
const { ENTP_INT_CERTS_FOLDER, SERVICE_API_KEY_ENV, implPromptChoices } = require('../../lib/defaults')
|
|
27
|
-
const cloneDeep = require('lodash.clonedeep')
|
|
25
|
+
const { SERVICE_API_KEY_ENV } = require('../../lib/defaults')
|
|
28
26
|
|
|
29
27
|
const DEFAULT_WORKSPACE = 'Stage'
|
|
30
28
|
|
|
31
|
-
class InitCommand extends
|
|
29
|
+
class InitCommand extends TemplatesCommand {
|
|
32
30
|
async run () {
|
|
33
31
|
const { args, flags } = await this.parse(InitCommand)
|
|
34
32
|
|
|
@@ -36,19 +34,26 @@ class InitCommand extends AddCommand {
|
|
|
36
34
|
this.error('--no-login and --workspace flags cannot be used together.')
|
|
37
35
|
}
|
|
38
36
|
|
|
37
|
+
// check that the template plugin has been installed
|
|
38
|
+
const command = await this.config.findCommand('templates:install')
|
|
39
|
+
if (!command) {
|
|
40
|
+
this.error('aio-cli plugin @adobe/aio-cli-plugin-app-templates was not found. This plugin is required to install templates.')
|
|
41
|
+
}
|
|
42
|
+
|
|
39
43
|
if (flags.import) {
|
|
40
44
|
// resolve to absolute path before any chdir
|
|
41
45
|
flags.import = path.resolve(flags.import)
|
|
42
46
|
}
|
|
43
47
|
|
|
44
|
-
|
|
45
|
-
|
|
48
|
+
const destDir = this.destDir(args)
|
|
49
|
+
if (destDir !== '.') {
|
|
46
50
|
fs.ensureDirSync(destDir)
|
|
47
51
|
process.chdir(destDir)
|
|
48
52
|
}
|
|
49
53
|
|
|
50
54
|
const spinner = ora()
|
|
51
|
-
|
|
55
|
+
const noLogin = flags.import || !flags.login
|
|
56
|
+
if (noLogin) {
|
|
52
57
|
// import a console config - no login required!
|
|
53
58
|
await this.initNoLogin(flags)
|
|
54
59
|
} else {
|
|
@@ -60,7 +65,32 @@ class InitCommand extends AddCommand {
|
|
|
60
65
|
await this.runInstallPackages(flags, spinner)
|
|
61
66
|
|
|
62
67
|
this.log(chalk.bold(chalk.green('✔ App initialization finished!')))
|
|
63
|
-
this.log(
|
|
68
|
+
this.log(`> Tip: you can add more actions, web-assets and events to your project via the '${this.config.bin} app add' commands`)
|
|
69
|
+
|
|
70
|
+
if (noLogin) {
|
|
71
|
+
this.log(`> Run '${this.config.bin} templates info --required-services' to list the required services for the installed templates`)
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
getInitialGenerators (flags) {
|
|
76
|
+
// TODO read from config to override
|
|
77
|
+
const initialGenerators = ['base-app', 'add-ci']
|
|
78
|
+
|
|
79
|
+
if (flags['standalone-app']) {
|
|
80
|
+
initialGenerators.push('application')
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
return initialGenerators
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/** @private */
|
|
87
|
+
destDir (args) {
|
|
88
|
+
let destDir = '.'
|
|
89
|
+
if (args.path !== '.') {
|
|
90
|
+
destDir = path.resolve(args.path)
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
return destDir
|
|
64
94
|
}
|
|
65
95
|
|
|
66
96
|
/** @private */
|
|
@@ -72,24 +102,24 @@ class InitCommand extends AddCommand {
|
|
|
72
102
|
this.log(chalk.green(`Loaded Adobe Developer Console configuration file for the Project '${consoleConfig.project.title}' in the Organization '${consoleConfig.project.org.name}'`))
|
|
73
103
|
}
|
|
74
104
|
|
|
75
|
-
// 2. prompt for
|
|
76
|
-
const
|
|
105
|
+
// 2. prompt for templates to be installed
|
|
106
|
+
const templates = await this.getTemplatesForFlags(flags)
|
|
77
107
|
|
|
78
|
-
// 3. run
|
|
108
|
+
// 3. run base code generators
|
|
79
109
|
const projectName = (consoleConfig && consoleConfig.project.name) || path.basename(process.cwd())
|
|
80
|
-
await this.runCodeGenerators(flags,
|
|
110
|
+
await this.runCodeGenerators(this.getInitialGenerators(flags), flags.yes, projectName)
|
|
111
|
+
|
|
112
|
+
// 4. install templates
|
|
113
|
+
await this.installTemplates({
|
|
114
|
+
useDefaultValues: flags.yes,
|
|
115
|
+
installNpm: flags.install,
|
|
116
|
+
templates
|
|
117
|
+
})
|
|
81
118
|
|
|
82
|
-
//
|
|
119
|
+
// 5. import config - if any
|
|
83
120
|
if (flags.import) {
|
|
84
121
|
await this.importConsoleConfig(consoleConfig)
|
|
85
122
|
}
|
|
86
|
-
|
|
87
|
-
// 5. This flow supports non logged in users so we can't now for sure if the project has
|
|
88
|
-
// required services installed. So we output a note on required services instead.
|
|
89
|
-
const requiredServices = this.getAllRequiredServicesFromExtPoints(extensionPoints)
|
|
90
|
-
if (requiredServices.length > 0) {
|
|
91
|
-
this.log(chalk.bold(`Please ensure the following service(s) are enabled in the Organization and added to the Console Workspace: '${requiredServices}'`))
|
|
92
|
-
}
|
|
93
123
|
}
|
|
94
124
|
|
|
95
125
|
async initWithLogin (flags) {
|
|
@@ -104,31 +134,56 @@ class InitCommand extends AddCommand {
|
|
|
104
134
|
const project = await this.selectOrCreateConsoleProject(consoleCLI, org)
|
|
105
135
|
// 4. retrieve workspace details, defaults to Stage
|
|
106
136
|
const workspace = await this.retrieveWorkspaceFromName(consoleCLI, org, project, flags)
|
|
107
|
-
// 5. ask for exensionPoints, only allow selection for extensions that have services enabled in Org
|
|
108
|
-
const extensionPoints = await this.selectExtensionPoints(flags, orgSupportedServices)
|
|
109
|
-
// 6. add any required services to Workspace
|
|
110
|
-
const requiredServices = this.getAllRequiredServicesFromExtPoints(extensionPoints)
|
|
111
|
-
await this.addServices(
|
|
112
|
-
consoleCLI,
|
|
113
|
-
org,
|
|
114
|
-
project,
|
|
115
|
-
workspace,
|
|
116
|
-
orgSupportedServices,
|
|
117
|
-
requiredServices
|
|
118
|
-
)
|
|
119
137
|
|
|
120
|
-
//
|
|
138
|
+
// 5. get list of templates to install
|
|
139
|
+
const templates = await this.getTemplatesForFlags(flags, orgSupportedServices)
|
|
140
|
+
|
|
141
|
+
// 6. download workspace config
|
|
121
142
|
const consoleConfig = await consoleCLI.getWorkspaceConfig(org.id, project.id, workspace.id, orgSupportedServices)
|
|
122
143
|
|
|
123
|
-
//
|
|
124
|
-
await this.runCodeGenerators(flags,
|
|
144
|
+
// 7. run base code generators
|
|
145
|
+
await this.runCodeGenerators(this.getInitialGenerators(flags), flags.yes, consoleConfig.project.name)
|
|
125
146
|
|
|
126
|
-
//
|
|
147
|
+
// 8. import config
|
|
127
148
|
await this.importConsoleConfig(consoleConfig)
|
|
128
149
|
|
|
150
|
+
// 9. install templates
|
|
151
|
+
await this.installTemplates({
|
|
152
|
+
useDefaultValues: flags.yes,
|
|
153
|
+
installNpm: flags.install,
|
|
154
|
+
templates
|
|
155
|
+
})
|
|
156
|
+
|
|
129
157
|
this.log(chalk.blue(chalk.bold(`Project initialized for Workspace ${workspace.name}, you can run 'aio app use -w <workspace>' to switch workspace.`)))
|
|
130
158
|
}
|
|
131
159
|
|
|
160
|
+
async getTemplatesForFlags (flags, orgSupportedServices = null) {
|
|
161
|
+
if (flags.template) {
|
|
162
|
+
return flags.template
|
|
163
|
+
} else if (flags.extension) {
|
|
164
|
+
const { notFound, templates: extensionTemplates } = await this.getTemplatesByExtensionPointIds(flags.extension)
|
|
165
|
+
if (notFound.length > 0) {
|
|
166
|
+
this.error(`Extension(s) '${notFound.join(', ')}' not found in the Template Registry.`)
|
|
167
|
+
}
|
|
168
|
+
return extensionTemplates.map(t => t.name)
|
|
169
|
+
} else if (!flags['standalone-app']) {
|
|
170
|
+
const noLogin = flags.import || !flags.login
|
|
171
|
+
let [searchCriteria, orderByCriteria] = await this.getSearchCriteria(orgSupportedServices)
|
|
172
|
+
if (noLogin) {
|
|
173
|
+
searchCriteria = {
|
|
174
|
+
[TemplateRegistryAPI.SEARCH_CRITERIA_STATUSES]: TemplateRegistryAPI.TEMPLATE_STATUS_APPROVED,
|
|
175
|
+
[TemplateRegistryAPI.SEARCH_CRITERIA_CATEGORIES]: TemplateRegistryAPI.SEARCH_CRITERIA_FILTER_NOT + 'helper-template'
|
|
176
|
+
}
|
|
177
|
+
orderByCriteria = {
|
|
178
|
+
[TemplateRegistryAPI.ORDER_BY_CRITERIA_PUBLISH_DATE]: TemplateRegistryAPI.ORDER_BY_CRITERIA_SORT_DESC
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
return this.selectTemplates(searchCriteria, orderByCriteria)
|
|
182
|
+
} else {
|
|
183
|
+
return []
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
132
187
|
async ensureDevTermAccepted (consoleCLI, orgId) {
|
|
133
188
|
const isTermAccepted = await consoleCLI.checkDevTermsForOrg(orgId)
|
|
134
189
|
if (!isTermAccepted) {
|
|
@@ -147,40 +202,65 @@ class InitCommand extends AddCommand {
|
|
|
147
202
|
}
|
|
148
203
|
}
|
|
149
204
|
|
|
150
|
-
async
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
205
|
+
async getSearchCriteria (orgSupportedServices) {
|
|
206
|
+
const choices = [
|
|
207
|
+
{
|
|
208
|
+
name: 'All Templates',
|
|
209
|
+
value: 'allTemplates',
|
|
210
|
+
checked: true
|
|
211
|
+
},
|
|
212
|
+
{
|
|
213
|
+
name: 'All Extension Points',
|
|
214
|
+
value: 'allExtensionPoints',
|
|
215
|
+
checked: false
|
|
158
216
|
}
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
217
|
+
]
|
|
218
|
+
|
|
219
|
+
if (orgSupportedServices) {
|
|
220
|
+
choices.push({
|
|
221
|
+
name: 'Only Templates Supported By My Org',
|
|
222
|
+
value: 'orgTemplates',
|
|
223
|
+
checked: false
|
|
224
|
+
})
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
const { components: selection } = await inquirer.prompt([
|
|
228
|
+
{
|
|
229
|
+
type: 'list',
|
|
230
|
+
name: 'components',
|
|
231
|
+
message: 'What templates do you want to search for?',
|
|
232
|
+
loop: false,
|
|
233
|
+
choices
|
|
234
|
+
}
|
|
235
|
+
])
|
|
236
|
+
|
|
237
|
+
const searchCriteria = {
|
|
238
|
+
[TemplateRegistryAPI.SEARCH_CRITERIA_STATUSES]: TemplateRegistryAPI.TEMPLATE_STATUS_APPROVED,
|
|
239
|
+
[TemplateRegistryAPI.SEARCH_CRITERIA_CATEGORIES]: TemplateRegistryAPI.SEARCH_CRITERIA_FILTER_NOT + 'helper-template'
|
|
240
|
+
}
|
|
162
241
|
|
|
163
|
-
|
|
164
|
-
|
|
242
|
+
switch (selection) {
|
|
243
|
+
case 'orgTemplates': {
|
|
165
244
|
const supportedServiceCodes = new Set(orgSupportedServices.map(s => s.code))
|
|
166
|
-
|
|
167
|
-
choices.forEach(c => {
|
|
168
|
-
const missingServices = c.value.requiredServices.filter(s => !supportedServiceCodes.has(s))
|
|
169
|
-
if (missingServices.length > 0) {
|
|
170
|
-
c.disabled = true
|
|
171
|
-
c.name = `${c.name}: missing service(s) in Org: '${missingServices}'`
|
|
172
|
-
}
|
|
173
|
-
})
|
|
245
|
+
searchCriteria[TemplateRegistryAPI.SEARCH_CRITERIA_APIS] = Array.from(supportedServiceCodes)
|
|
174
246
|
}
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
247
|
+
break
|
|
248
|
+
case 'allExtensionPoints':
|
|
249
|
+
searchCriteria[TemplateRegistryAPI.SEARCH_CRITERIA_EXTENSIONS] = TemplateRegistryAPI.SEARCH_CRITERIA_FILTER_ANY
|
|
250
|
+
break
|
|
251
|
+
case 'allTemplates':
|
|
252
|
+
default:
|
|
253
|
+
break
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
const { name: selectionLabel } = choices.find(item => item.value === selection)
|
|
257
|
+
|
|
258
|
+
// an optional OrderBy Criteria object
|
|
259
|
+
const orderByCriteria = {
|
|
260
|
+
[TemplateRegistryAPI.ORDER_BY_CRITERIA_PUBLISH_DATE]: TemplateRegistryAPI.ORDER_BY_CRITERIA_SORT_DESC
|
|
183
261
|
}
|
|
262
|
+
|
|
263
|
+
return [searchCriteria, orderByCriteria, selection, selectionLabel]
|
|
184
264
|
}
|
|
185
265
|
|
|
186
266
|
async selectConsoleOrg (consoleCLI) {
|
|
@@ -227,84 +307,20 @@ class InitCommand extends AddCommand {
|
|
|
227
307
|
return workspace
|
|
228
308
|
}
|
|
229
309
|
|
|
230
|
-
async
|
|
231
|
-
|
|
232
|
-
const currServiceProperties = await consoleCLI.getServicePropertiesFromWorkspace(
|
|
233
|
-
org.id,
|
|
234
|
-
project.id,
|
|
235
|
-
workspace,
|
|
236
|
-
orgSupportedServices
|
|
237
|
-
)
|
|
238
|
-
const serviceCodesToAdd = requiredServices.filter(s => !currServiceProperties.some(sp => sp.sdkCode === s))
|
|
239
|
-
if (serviceCodesToAdd.length > 0) {
|
|
240
|
-
const servicePropertiesToAdd = serviceCodesToAdd
|
|
241
|
-
.map(s => {
|
|
242
|
-
// previous check ensures orgSupportedServices has required services
|
|
243
|
-
const orgServiceDefinition = orgSupportedServices.find(os => os.code === s)
|
|
244
|
-
return {
|
|
245
|
-
sdkCode: s,
|
|
246
|
-
name: orgServiceDefinition.name,
|
|
247
|
-
roles: orgServiceDefinition.properties.roles,
|
|
248
|
-
// add all licenseConfigs
|
|
249
|
-
licenseConfigs: orgServiceDefinition.properties.licenseConfigs
|
|
250
|
-
}
|
|
251
|
-
})
|
|
252
|
-
await consoleCLI.subscribeToServices(
|
|
253
|
-
org.id,
|
|
254
|
-
project,
|
|
255
|
-
workspace,
|
|
256
|
-
// certDir if need to create integration
|
|
257
|
-
path.join(this.config.dataDir, ENTP_INT_CERTS_FOLDER),
|
|
258
|
-
// new service properties
|
|
259
|
-
currServiceProperties.concat(servicePropertiesToAdd)
|
|
260
|
-
)
|
|
261
|
-
}
|
|
262
|
-
return workspace
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
getAllRequiredServicesFromExtPoints (extensionPoints) {
|
|
266
|
-
const requiredServicesWithDuplicates = extensionPoints
|
|
267
|
-
.map(e => e.requiredServices)
|
|
268
|
-
// flat not supported in node 10
|
|
269
|
-
.reduce((res, arr) => res.concat(arr), [])
|
|
270
|
-
return [...new Set(requiredServicesWithDuplicates)]
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
async runCodeGenerators (flags, extensionPoints, projectName) {
|
|
274
|
-
let env = yeoman.createEnv()
|
|
275
|
-
// by default yeoman runs the install, we control installation from the app plugin
|
|
310
|
+
async runCodeGenerators (generatorNames, skipPrompt, projectName) {
|
|
311
|
+
const env = yeoman.createEnv()
|
|
276
312
|
env.options = { skipInstall: true }
|
|
277
|
-
|
|
313
|
+
|
|
278
314
|
// first run app generator that will generate the root skeleton + ci
|
|
279
|
-
for (const generatorKey of
|
|
315
|
+
for (const generatorKey of generatorNames) {
|
|
280
316
|
const appGen = env.instantiate(generators[generatorKey], {
|
|
281
317
|
options: {
|
|
282
|
-
'skip-prompt':
|
|
318
|
+
'skip-prompt': skipPrompt,
|
|
283
319
|
'project-name': projectName
|
|
284
320
|
}
|
|
285
321
|
})
|
|
286
322
|
await env.runGenerator(appGen)
|
|
287
323
|
}
|
|
288
|
-
|
|
289
|
-
// Creating new Yeoman env here to workaround an issue where yeoman reuses the conflicter from previous environment.
|
|
290
|
-
// https://github.com/yeoman/environment/issues/324
|
|
291
|
-
|
|
292
|
-
env = yeoman.createEnv()
|
|
293
|
-
// by default yeoman runs the install, we control installation from the app plugin
|
|
294
|
-
env.options = { skipInstall: true }
|
|
295
|
-
// try to use appGen.composeWith
|
|
296
|
-
for (let i = 0; i < extensionPoints.length; ++i) {
|
|
297
|
-
const extGen = env.instantiate(
|
|
298
|
-
extensionPoints[i].generator,
|
|
299
|
-
{
|
|
300
|
-
options: {
|
|
301
|
-
'skip-prompt': flags.yes,
|
|
302
|
-
// do not prompt for overwrites
|
|
303
|
-
force: true
|
|
304
|
-
}
|
|
305
|
-
})
|
|
306
|
-
await env.runGenerator(extGen)
|
|
307
|
-
}
|
|
308
324
|
}
|
|
309
325
|
|
|
310
326
|
// console config is already loaded into object
|
|
@@ -329,7 +345,7 @@ InitCommand.description = `Create a new Adobe I/O App
|
|
|
329
345
|
`
|
|
330
346
|
|
|
331
347
|
InitCommand.flags = {
|
|
332
|
-
...
|
|
348
|
+
...TemplatesCommand.flags,
|
|
333
349
|
yes: Flags.boolean({
|
|
334
350
|
description: 'Skip questions, and use all default values',
|
|
335
351
|
default: false,
|
|
@@ -344,16 +360,21 @@ InitCommand.flags = {
|
|
|
344
360
|
default: true,
|
|
345
361
|
allowNo: true
|
|
346
362
|
}),
|
|
347
|
-
extensions: Flags.boolean({
|
|
348
|
-
description: 'Use --no-extensions to create a blank application that does not integrate with Exchange',
|
|
349
|
-
default: true,
|
|
350
|
-
allowNo: true
|
|
351
|
-
}),
|
|
352
363
|
extension: Flags.string({
|
|
353
364
|
description: 'Extension point(s) to implement',
|
|
354
365
|
char: 'e',
|
|
355
366
|
multiple: true,
|
|
356
|
-
exclusive: ['
|
|
367
|
+
exclusive: ['template']
|
|
368
|
+
}),
|
|
369
|
+
'standalone-app': Flags.boolean({
|
|
370
|
+
description: 'Create a stand-alone application',
|
|
371
|
+
default: false,
|
|
372
|
+
exclusive: ['template']
|
|
373
|
+
}),
|
|
374
|
+
template: Flags.string({
|
|
375
|
+
description: 'Specify a link to a template that will be installed',
|
|
376
|
+
char: 't',
|
|
377
|
+
multiple: true
|
|
357
378
|
}),
|
|
358
379
|
workspace: Flags.string({
|
|
359
380
|
description: 'Specify the Adobe Developer Console Workspace to init from, defaults to Stage',
|
package/src/lib/defaults.js
CHANGED
|
@@ -10,7 +10,6 @@ governing permissions and limitations under the License.
|
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
12
|
// defaults & constants
|
|
13
|
-
const generators = require('@adobe/generator-aio-app')
|
|
14
13
|
|
|
15
14
|
module.exports = {
|
|
16
15
|
defaultAppHostname: 'adobeio-static.net',
|
|
@@ -35,35 +34,5 @@ module.exports = {
|
|
|
35
34
|
LEGACY_RUNTIME_MANIFEST: 'manifest.yml',
|
|
36
35
|
INCLUDE_DIRECTIVE: '$include',
|
|
37
36
|
APPLICATION_CONFIG_KEY: 'application',
|
|
38
|
-
EXTENSIONS_CONFIG_KEY: 'extensions'
|
|
39
|
-
|
|
40
|
-
implPromptChoices: [
|
|
41
|
-
// we abuse the extension command to also let users add a standalone app
|
|
42
|
-
{
|
|
43
|
-
name: 'Standalone Application',
|
|
44
|
-
value: {
|
|
45
|
-
name: 'application',
|
|
46
|
-
generator: generators.application,
|
|
47
|
-
requiredServices: [] // TODO required services should be filled based on selected actions
|
|
48
|
-
}
|
|
49
|
-
},
|
|
50
|
-
// extensions
|
|
51
|
-
// TODO this list should not be hardcoded but fetched from xt reg
|
|
52
|
-
{
|
|
53
|
-
name: 'DX Experience Cloud SPA v1',
|
|
54
|
-
value: {
|
|
55
|
-
name: 'dx/excshell/1',
|
|
56
|
-
generator: generators.extensions['dx/excshell/1'],
|
|
57
|
-
requiredServices: []
|
|
58
|
-
}
|
|
59
|
-
},
|
|
60
|
-
{
|
|
61
|
-
name: 'DX Asset Compute Worker v1',
|
|
62
|
-
value: {
|
|
63
|
-
name: 'dx/asset-compute/worker/1',
|
|
64
|
-
generator: generators.extensions['dx/asset-compute/worker/1'],
|
|
65
|
-
requiredServices: ['AssetComputeSDK']
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
]
|
|
37
|
+
EXTENSIONS_CONFIG_KEY: 'extensions'
|
|
69
38
|
}
|