/
create.js
192 lines (165 loc) · 5.97 KB
/
create.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
const Command = require('@netlify/cli-utils')
const { getAddons, createAddon } = require('netlify/src/addons')
const { parseRawFlags } = require('../../utils/parse-raw-flags')
const getAddonManifest = require('../../utils/addons/api')
const { requiredConfigValues, missingConfigValues, updateConfigValues } = require('../../utils/addons/validation')
const generatePrompts = require('../../utils/addons/prompts')
const render = require('../../utils/addons/render')
const chalk = require('chalk')
const inquirer = require('inquirer')
class AddonsCreateCommand extends Command {
async run() {
const accessToken = await this.authenticate()
const { args, raw } = this.parse(AddonsCreateCommand)
const { api, site } = this.netlify
const addonName = args.name
if (!addonName) {
this.log('Please provide an add-on name to provision')
this.exit()
}
const siteId = site.id
if (!siteId) {
this.log('No site id found, please run inside a site folder or `netlify link`')
return false
}
const siteData = await api.getSite({ siteId })
const addons = await getAddons(siteId, accessToken)
if (typeof addons === 'object' && addons.error) {
this.log('API Error', addons)
return false
}
// Filter down addons to current args.name
const currentAddon = addons.find(addon => addon.service_path === `/.netlify/${addonName}`)
// GET flags from `raw` data
const rawFlags = parseRawFlags(raw)
if (currentAddon && currentAddon.id) {
this.log(`The "${addonName} add-on" already exists for ${siteData.name}`)
this.log()
const cmd = chalk.cyan(`\`netlify addons:config ${addonName}\``)
this.log(`- To update this add-on run: ${cmd}`)
const deleteCmd = chalk.cyan(`\`netlify addons:delete ${addonName}\``)
this.log(`- To remove this add-on run: ${deleteCmd}`)
this.log()
return false
}
const manifest = await getAddonManifest(addonName, accessToken)
const hasConfig = manifest.config && Object.keys(manifest.config).length
let configValues = rawFlags
await this.config.runHook('analytics', {
eventName: 'command',
payload: {
command: 'addons:create'
}
})
if (hasConfig) {
const required = requiredConfigValues(manifest.config)
const missingValues = missingConfigValues(required, rawFlags)
this.log(`Starting the setup for "${addonName} add-on"`)
this.log()
if (Object.keys(rawFlags).length) {
const newConfig = updateConfigValues(manifest.config, {}, rawFlags)
if (missingValues.length) {
/* Warn user of missing required values */
this.log(
`${chalk.redBright.underline.bold(`Error: Missing required configuration for "${addonName} add-on"`)}`
)
this.log()
render.missingValues(missingValues, manifest)
this.log()
const msg = `netlify addons:create ${addonName}`
this.log(`Please supply the configuration values as CLI flags`)
this.log()
this.log(`Alternatively, you can run ${chalk.cyan(msg)} with no flags to walk through the setup steps`)
this.log()
return false
}
await createSiteAddon(
{
addonName,
settings: {
siteId: siteId,
addon: addonName,
config: newConfig
},
accessToken,
siteData,
error: this.error
},
this.log
)
return false
}
const words = `The ${addonName} add-on has the following configurable options:`
this.log(` ${chalk.yellowBright.bold(words)}`)
render.configValues(addonName, manifest.config)
this.log()
this.log(` ${chalk.greenBright.bold('Lets configure those!')}`)
this.log()
this.log(` - Hit ${chalk.white.bold('enter')} to confirm value or set empty value`)
this.log(` - Hit ${chalk.white.bold('ctrl + C')} to cancel & exit configuration`)
this.log()
const prompts = generatePrompts({
config: manifest.config,
configValues: rawFlags
})
const userInput = await inquirer.prompt(prompts)
// Merge user input with the flags specified
configValues = updateConfigValues(manifest.config, rawFlags, userInput)
const missingRequiredValues = missingConfigValues(required, configValues)
if (missingRequiredValues && missingRequiredValues.length) {
missingRequiredValues.forEach(val => {
this.log(`Missing required value "${val}". Please run the command again`)
})
return false
}
}
await createSiteAddon(
{
addonName,
settings: {
siteId: siteId,
addon: addonName,
config: configValues
},
accessToken,
siteData,
error: this.error
},
this.log
)
}
}
async function createSiteAddon({ addonName, settings, accessToken, siteData, error }, logger) {
let addonResponse
try {
// TODO update to https://open-api.netlify.com/#operation/createServiceInstance
addonResponse = await createAddon(settings, accessToken)
} catch (e) {
error(e.message)
}
if (addonResponse.code === 404) {
logger(`No add-on "${addonName}" found. Please double check your add-on name and try again`)
return false
}
logger(`Add-on "${addonName}" created for ${siteData.name}`)
if (addonResponse.config && addonResponse.config.message) {
logger()
logger(`${addonResponse.config.message}`)
}
return addonResponse
}
AddonsCreateCommand.description = `Add an add-on extension to your site
...
Add-ons are a way to extend the functionality of your Netlify site
`
AddonsCreateCommand.aliases = ['addon:create']
AddonsCreateCommand.args = [
{
name: 'name',
required: true,
description: 'Add-on namespace'
}
]
// allow for any flags. Handy for variadic configuration options
AddonsCreateCommand.strict = false
module.exports = AddonsCreateCommand