generated from salesforcecli/plugin-template
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcreate.ts
153 lines (143 loc) · 6.11 KB
/
create.ts
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
/*
* Copyright (c) 2021, salesforce.com, inc.
* All rights reserved.
* Licensed under the BSD 3-Clause license.
* For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
*/
import { promises as fs } from 'fs';
import { EOL } from 'os';
import { flags, SfdxCommand } from '@salesforce/command';
import { Messages, Org, SfdxError } from '@salesforce/core';
import Folder, { CreateAppBody } from '../../../lib/analytics/app/folder';
import AppStreaming from '../../../lib/analytics/event/appStreaming';
import { DEF_APP_CREATE_UPDATE_TIMEOUT } from '../../../lib/analytics/constants';
import WaveTemplate from '../../../lib/analytics/template/wavetemplate';
Messages.importMessagesDirectory(__dirname);
const messages = Messages.loadMessages('@salesforce/analytics', 'app');
export default class Create extends SfdxCommand {
public static description = messages.getMessage('createCommandDescription');
public static longDescription = messages.getMessage('createCommandLongDescription');
public static examples = [
'$ sfdx analytics:app:create -t templateid -n appname',
'$ sfdx analytics:app:create -m templatename',
'$ sfdx analytics:app:create -f path_to_json_file'
];
protected static flagsConfig = {
definitionfile: flags.filepath({
char: 'f',
description: messages.getMessage('appDefinitionFileFlagDescription'),
longDescription: messages.getMessage('appDefinitionFileFlagLongDescription'),
exclusive: ['templatename', 'templateid']
}),
templateid: flags.string({
char: 't',
description: messages.getMessage('templateidFlagDescriptionForCreate'),
longDescription: messages.getMessage('templateidFlagLongDescriptionForCreate'),
exclusive: ['templatename', 'definitionfile']
}),
templatename: flags.string({
char: 'm',
description: messages.getMessage('templatenameFlagDescription'),
longDescription: messages.getMessage('templatenameFlagLongDescription'),
exclusive: ['templateid', 'definitionfile']
}),
appname: flags.string({
char: 'n',
description: messages.getMessage('appnameFlagDescription'),
longDescription: messages.getMessage('appnameFlagLongDescription')
}),
async: flags.boolean({
char: 'a',
description: messages.getMessage('appCreateAsyncDescription'),
longDescription: messages.getMessage('appCreateAsyncLongDescription')
}),
allevents: flags.boolean({
char: 'v',
description: messages.getMessage('appCreateAllEventsDescription'),
longDescription: messages.getMessage('appCreateAllEventsLongDescription')
}),
wait: flags.number({
char: 'w',
description: messages.getMessage('streamingWaitDescription'),
longDescription: messages.getMessage('streamingWaitLongDescription', [DEF_APP_CREATE_UPDATE_TIMEOUT]),
min: 0,
default: DEF_APP_CREATE_UPDATE_TIMEOUT
})
};
protected static requiresUsername = true;
protected static requiresProject = false;
public async run() {
const folder = new Folder(this.org as Org);
const body = await this.generateCreateAppBody();
const appStreaming = new AppStreaming(
this.org as Org,
this.flags.allEvents as boolean,
this.flags.wait as number,
this.ux
);
// if they're not creating from a template (i.e. an empty app), then don't listen for events since there won't be
// any and this will just hang until the timeout
if (this.flags.async || this.flags.wait <= 0 || !body.templateSourceId) {
const waveAppId = await appStreaming.createApp(folder, body);
this.ux.log(messages.getMessage('createAppSuccessAsync', [waveAppId]));
return { id: waveAppId };
} else {
const waveAppId = await appStreaming.streamCreateEvent(folder, body);
return { id: waveAppId, events: appStreaming.getStreamingResults() };
}
}
private async generateCreateAppBody(): Promise<CreateAppBody> {
if (this.flags.templateid || this.flags.templatename) {
const templateSvc = new WaveTemplate(this.org as Org);
const matchedTemplate = this.flags.templateid
? await templateSvc.fetch(this.flags.templateid as string)
: (await templateSvc.list()).find(
template => template.name === this.flags.templatename || template.label === this.flags.templatename
);
if (!matchedTemplate) {
throw new SfdxError(`Template '${this.flags.templateid || this.flags.templatename}' not found.`);
}
return {
description: matchedTemplate.description,
label: (this.flags.appname || matchedTemplate.label) as string,
templateSourceId: matchedTemplate.id,
assetIcon: '16.png',
templateValues: {},
name: (this.flags.appname || matchedTemplate.name) as string
};
} else if (this.flags.definitionfile) {
const path = String(this.flags.definitionfile);
let json: unknown;
try {
json = JSON.parse(await fs.readFile(path, 'utf8'));
} catch (e) {
throw new SfdxError(
`Error parsing ${path}`,
undefined,
undefined,
undefined,
e instanceof Error ? e : new Error(e ? String(e) : '<unknown>')
);
}
if (typeof json !== 'object') {
throw new SfdxError(`Invalid json in ${path}, expected an object, found a ${typeof json}`);
}
const body = json as CreateAppBody;
// if they didn't put a name in the defintion file json but did on the command line, squish it into the json
if (this.flags.appname && (!body.name || !body.label)) {
body.name = (body.name || this.flags.appname) as string;
body.label = (body.label || this.flags.appname) as string;
}
return body;
} else {
throw new SfdxError(
// this is similar to what sfdx prints out if use required: true on a missing flag
`Missing one of the following required flags:${EOL}` +
` -f, --definitionfile DEFINITIONFILE${EOL}` +
` -t, --templateid TEMPLATEID${EOL}` +
` -m, --templatename TEMPLATENAME${EOL}` +
'See more help with --help'
);
}
}
}