@hubspot/cli 4.2.1-beta.2 → 4.2.1-beta.4
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/bin/cli.js +5 -2
- package/commands/accounts/clean.js +139 -0
- package/commands/accounts.js +2 -0
- package/commands/project/create.js +1 -1
- package/commands/project/dev.js +68 -111
- package/commands/project/download.js +10 -19
- package/commands/sandbox/delete.js +2 -2
- package/commands/sandbox.js +3 -2
- package/lang/en.lyaml +33 -57
- package/lib/DevServerManager.js +18 -67
- package/lib/LocalDevManager.js +235 -569
- package/lib/SpinniesManager.js +2 -82
- package/lib/projectStructure.js +1 -0
- package/lib/projects.js +45 -35
- package/lib/prompts/downloadProjectPrompt.js +1 -4
- package/lib/prompts/projectDevTargetAccountPrompt.js +20 -1
- package/lib/ui.js +9 -2
- package/package.json +5 -8
- package/lib/LocalDevManagerV2.js +0 -239
package/lib/SpinniesManager.js
CHANGED
|
@@ -60,30 +60,6 @@ class SpinniesManager {
|
|
|
60
60
|
this.stream = process.stderr;
|
|
61
61
|
this.lineCount = 0;
|
|
62
62
|
this.currentFrameIndex = 0;
|
|
63
|
-
|
|
64
|
-
// Custom fields
|
|
65
|
-
this.parentSpinnerName = null;
|
|
66
|
-
this.categories = {};
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
addSpinnerToCategory(name, category) {
|
|
70
|
-
if (!this.categories[category]) {
|
|
71
|
-
this.categories[category] = {};
|
|
72
|
-
}
|
|
73
|
-
this.categories[category][name] = true;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
getSpinnerCategory(name) {
|
|
77
|
-
return Object.keys(this.categories).find(
|
|
78
|
-
category => !!this.categories[category][name]
|
|
79
|
-
);
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
removeSpinnerFromCategory(name) {
|
|
83
|
-
const category = this.getSpinnerCategory(name);
|
|
84
|
-
if (category) {
|
|
85
|
-
delete this.categories[category][name];
|
|
86
|
-
}
|
|
87
63
|
}
|
|
88
64
|
|
|
89
65
|
pick(name) {
|
|
@@ -91,40 +67,24 @@ class SpinniesManager {
|
|
|
91
67
|
}
|
|
92
68
|
|
|
93
69
|
add(name, options = {}) {
|
|
94
|
-
const { category, isParent, noIndent, ...spinnerOptions } = options;
|
|
95
|
-
|
|
96
70
|
// Support adding generic spinnies lines without specifying a name
|
|
97
71
|
const resolvedName = name || `${Date.now()}-${Math.random()}`;
|
|
98
72
|
|
|
99
|
-
if (category) {
|
|
100
|
-
this.addSpinnerToCategory(resolvedName, category);
|
|
101
|
-
}
|
|
102
|
-
|
|
103
73
|
if (!options.text) {
|
|
104
|
-
|
|
74
|
+
options.text = resolvedName;
|
|
105
75
|
}
|
|
106
76
|
|
|
107
|
-
const originalIndent = spinnerOptions.indent || 0;
|
|
108
|
-
|
|
109
77
|
const spinnerProperties = {
|
|
110
78
|
...colorOptions(this.options),
|
|
111
79
|
succeedPrefix: this.options.succeedPrefix,
|
|
112
80
|
failPrefix: this.options.failPrefix,
|
|
113
81
|
status: 'spinning',
|
|
114
|
-
...purgeSpinnerOptions(
|
|
115
|
-
indent:
|
|
116
|
-
this.parentSpinnerName && !noIndent
|
|
117
|
-
? originalIndent + 1
|
|
118
|
-
: originalIndent,
|
|
82
|
+
...purgeSpinnerOptions(options),
|
|
119
83
|
};
|
|
120
84
|
|
|
121
85
|
this.spinners[resolvedName] = spinnerProperties;
|
|
122
86
|
this.updateSpinnerState();
|
|
123
87
|
|
|
124
|
-
if (isParent) {
|
|
125
|
-
this.parentSpinnerName = resolvedName;
|
|
126
|
-
}
|
|
127
|
-
|
|
128
88
|
return { name: resolvedName, ...spinnerProperties };
|
|
129
89
|
}
|
|
130
90
|
|
|
@@ -136,20 +96,6 @@ class SpinniesManager {
|
|
|
136
96
|
return this.spinners[name];
|
|
137
97
|
}
|
|
138
98
|
|
|
139
|
-
// TODO there is an issue here with the usage of "non-spinnable"
|
|
140
|
-
// The spinnies lib automatically removes any non-active spinners
|
|
141
|
-
// after adding a new spinner (add -> updateSpinnerState -> checkIfActiveSpinners)
|
|
142
|
-
// so "pick" is telling us that these newly-added spinners don't exist.
|
|
143
|
-
addOrUpdate(name, options = {}) {
|
|
144
|
-
const spinner = this.pick(name);
|
|
145
|
-
|
|
146
|
-
if (spinner) {
|
|
147
|
-
this.update(name, options);
|
|
148
|
-
} else {
|
|
149
|
-
this.add(name, options);
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
|
|
153
99
|
succeed(name, options = {}) {
|
|
154
100
|
this.setSpinnerProperties(name, options, 'succeed');
|
|
155
101
|
this.updateSpinnerState();
|
|
@@ -169,37 +115,11 @@ class SpinniesManager {
|
|
|
169
115
|
throw Error('A spinner reference name must be specified');
|
|
170
116
|
}
|
|
171
117
|
|
|
172
|
-
if (name === this.parentSpinnerName) {
|
|
173
|
-
this.parentSpinnerName = null;
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
this.removeSpinnerFromCategory(name);
|
|
177
|
-
|
|
178
118
|
const spinner = this.spinners[name];
|
|
179
119
|
delete this.spinners[name];
|
|
180
120
|
return spinner;
|
|
181
121
|
}
|
|
182
122
|
|
|
183
|
-
/**
|
|
184
|
-
* Removes all spinnies instances
|
|
185
|
-
* @param {string} targetCategory - remove all spinnies with a matching category
|
|
186
|
-
* @param {string} preserveCategory - do not remove spinnies with a matching category
|
|
187
|
-
*/
|
|
188
|
-
removeAll({ preserveCategory = null, targetCategory = null } = {}) {
|
|
189
|
-
Object.keys(this.spinners).forEach(name => {
|
|
190
|
-
if (targetCategory) {
|
|
191
|
-
if (this.getSpinnerCategory(name) === targetCategory) {
|
|
192
|
-
this.remove(name);
|
|
193
|
-
}
|
|
194
|
-
} else if (
|
|
195
|
-
!preserveCategory ||
|
|
196
|
-
this.getSpinnerCategory(name) !== preserveCategory
|
|
197
|
-
) {
|
|
198
|
-
this.remove(name);
|
|
199
|
-
}
|
|
200
|
-
});
|
|
201
|
-
}
|
|
202
|
-
|
|
203
123
|
stopAll(newStatus = 'stopped') {
|
|
204
124
|
Object.keys(this.spinners).forEach(name => {
|
|
205
125
|
const { status: currentStatus } = this.spinners[name];
|
package/lib/projectStructure.js
CHANGED
package/lib/projects.js
CHANGED
|
@@ -43,6 +43,7 @@ const { i18n } = require('./lang');
|
|
|
43
43
|
const SpinniesManager = require('./SpinniesManager');
|
|
44
44
|
const {
|
|
45
45
|
isSpecifiedError,
|
|
46
|
+
isSpecifiedHubSpotAuthError,
|
|
46
47
|
} = require('@hubspot/cli-lib/errorHandlers/apiErrors');
|
|
47
48
|
|
|
48
49
|
const i18nKey = 'cli.lib.projects';
|
|
@@ -132,24 +133,15 @@ const createProjectConfig = async (
|
|
|
132
133
|
}`
|
|
133
134
|
);
|
|
134
135
|
|
|
136
|
+
await downloadGitHubRepoContents(templateSource, template.path, projectPath);
|
|
137
|
+
const _config = JSON.parse(fs.readFileSync(projectConfigPath));
|
|
138
|
+
writeProjectConfig(projectConfigPath, {
|
|
139
|
+
..._config,
|
|
140
|
+
name: projectName,
|
|
141
|
+
});
|
|
142
|
+
|
|
135
143
|
if (template.name === 'no-template') {
|
|
136
144
|
fs.ensureDirSync(path.join(projectPath, 'src'));
|
|
137
|
-
|
|
138
|
-
writeProjectConfig(projectConfigPath, {
|
|
139
|
-
name: projectName,
|
|
140
|
-
srcDir: 'src',
|
|
141
|
-
});
|
|
142
|
-
} else {
|
|
143
|
-
await downloadGitHubRepoContents(
|
|
144
|
-
templateSource,
|
|
145
|
-
template.path,
|
|
146
|
-
projectPath
|
|
147
|
-
);
|
|
148
|
-
const _config = JSON.parse(fs.readFileSync(projectConfigPath));
|
|
149
|
-
writeProjectConfig(projectConfigPath, {
|
|
150
|
-
..._config,
|
|
151
|
-
name: projectName,
|
|
152
|
-
});
|
|
153
145
|
}
|
|
154
146
|
|
|
155
147
|
return true;
|
|
@@ -184,7 +176,9 @@ const pollFetchProject = async (accountId, projectName) => {
|
|
|
184
176
|
let pollCount = 0;
|
|
185
177
|
SpinniesManager.init();
|
|
186
178
|
SpinniesManager.add('pollFetchProject', {
|
|
187
|
-
text:
|
|
179
|
+
text: i18n(`${i18nKey}.pollFetchProject.checkingProject`, {
|
|
180
|
+
accountIdentifier: uiAccountDescription(accountId),
|
|
181
|
+
}),
|
|
188
182
|
});
|
|
189
183
|
const pollInterval = setInterval(async () => {
|
|
190
184
|
try {
|
|
@@ -200,14 +194,10 @@ const pollFetchProject = async (accountId, projectName) => {
|
|
|
200
194
|
statusCode: 403,
|
|
201
195
|
category: 'GATED',
|
|
202
196
|
subCategory: 'BuildPipelineErrorType.PORTAL_GATED',
|
|
203
|
-
})
|
|
197
|
+
}) &&
|
|
198
|
+
pollCount < 15
|
|
204
199
|
) {
|
|
205
200
|
pollCount += 1;
|
|
206
|
-
} else if (pollCount >= 15) {
|
|
207
|
-
// Poll up to max 30s
|
|
208
|
-
SpinniesManager.remove('pollFetchProject');
|
|
209
|
-
clearInterval(pollInterval);
|
|
210
|
-
reject(err);
|
|
211
201
|
} else {
|
|
212
202
|
SpinniesManager.remove('pollFetchProject');
|
|
213
203
|
clearInterval(pollInterval);
|
|
@@ -280,6 +270,14 @@ const ensureProjectExists = async (
|
|
|
280
270
|
return false;
|
|
281
271
|
}
|
|
282
272
|
}
|
|
273
|
+
if (
|
|
274
|
+
isSpecifiedHubSpotAuthError(err, {
|
|
275
|
+
statusCode: 401,
|
|
276
|
+
})
|
|
277
|
+
) {
|
|
278
|
+
logger.error(err.message);
|
|
279
|
+
process.exit(EXIT_CODES.ERROR);
|
|
280
|
+
}
|
|
283
281
|
logApiErrorInstance(err, new ApiErrorContext({ accountId, projectName }));
|
|
284
282
|
process.exit(EXIT_CODES.ERROR);
|
|
285
283
|
}
|
|
@@ -566,7 +564,6 @@ const makePollTaskStatusFunc = ({
|
|
|
566
564
|
succeedColor: 'white',
|
|
567
565
|
failColor: 'white',
|
|
568
566
|
failPrefix: chalk.bold('!'),
|
|
569
|
-
category: 'projectPollStatus',
|
|
570
567
|
});
|
|
571
568
|
|
|
572
569
|
const [
|
|
@@ -608,7 +605,10 @@ const makePollTaskStatusFunc = ({
|
|
|
608
605
|
) + '\n';
|
|
609
606
|
|
|
610
607
|
SpinniesManager.update(overallTaskSpinniesKey, {
|
|
611
|
-
text: `${statusStrings.INITIALIZE(
|
|
608
|
+
text: `${statusStrings.INITIALIZE(
|
|
609
|
+
taskName,
|
|
610
|
+
displayId
|
|
611
|
+
)}\n${componentCountText}`,
|
|
612
612
|
});
|
|
613
613
|
|
|
614
614
|
if (!silenceLogs) {
|
|
@@ -627,7 +627,6 @@ const makePollTaskStatusFunc = ({
|
|
|
627
627
|
indent,
|
|
628
628
|
succeedColor: 'white',
|
|
629
629
|
failColor: 'white',
|
|
630
|
-
category: 'projectPollStatus',
|
|
631
630
|
});
|
|
632
631
|
};
|
|
633
632
|
|
|
@@ -688,11 +687,11 @@ const makePollTaskStatusFunc = ({
|
|
|
688
687
|
if (isTaskComplete(taskStatus)) {
|
|
689
688
|
if (status === statusText.STATES.SUCCESS) {
|
|
690
689
|
SpinniesManager.succeed(overallTaskSpinniesKey, {
|
|
691
|
-
text: statusStrings.SUCCESS(taskName),
|
|
690
|
+
text: statusStrings.SUCCESS(taskName, displayId),
|
|
692
691
|
});
|
|
693
692
|
} else if (status === statusText.STATES.FAILURE) {
|
|
694
693
|
SpinniesManager.fail(overallTaskSpinniesKey, {
|
|
695
|
-
text: statusStrings.FAIL(taskName),
|
|
694
|
+
text: statusStrings.FAIL(taskName, displayId),
|
|
696
695
|
});
|
|
697
696
|
|
|
698
697
|
if (!silenceLogs) {
|
|
@@ -712,7 +711,13 @@ const makePollTaskStatusFunc = ({
|
|
|
712
711
|
logger.log('See below for a summary of errors.');
|
|
713
712
|
uiLine();
|
|
714
713
|
|
|
715
|
-
failedSubtasks.
|
|
714
|
+
const displayErrors = failedSubtasks.filter(
|
|
715
|
+
subtask =>
|
|
716
|
+
subtask.standardError.subCategory !==
|
|
717
|
+
'BuildPipelineErrorType.DEPENDENT_SUBBUILD_FAILED'
|
|
718
|
+
);
|
|
719
|
+
|
|
720
|
+
displayErrors.forEach(subTask => {
|
|
716
721
|
logger.log(
|
|
717
722
|
`\n--- ${chalk.bold(
|
|
718
723
|
subTask[statusText.SUBTASK_NAME_KEY]
|
|
@@ -749,9 +754,9 @@ const pollBuildStatus = makePollTaskStatusFunc({
|
|
|
749
754
|
structureFn: getBuildStructure,
|
|
750
755
|
statusText: PROJECT_BUILD_TEXT,
|
|
751
756
|
statusStrings: {
|
|
752
|
-
INITIALIZE: name => `Building ${chalk.bold(name)}`,
|
|
753
|
-
SUCCESS: name => `Built ${chalk.bold(name)}`,
|
|
754
|
-
FAIL: name => `Failed to build ${chalk.bold(name)}`,
|
|
757
|
+
INITIALIZE: (name, buildId) => `Building ${chalk.bold(name)} #${buildId}`,
|
|
758
|
+
SUCCESS: (name, buildId) => `Built ${chalk.bold(name)} #${buildId}`,
|
|
759
|
+
FAIL: (name, buildId) => `Failed to build ${chalk.bold(name)} #${buildId}`,
|
|
755
760
|
SUBTASK_FAIL: (buildId, name) =>
|
|
756
761
|
`Build #${buildId} failed because there was a problem\nbuilding ${chalk.bold(
|
|
757
762
|
name
|
|
@@ -769,9 +774,12 @@ const pollDeployStatus = makePollTaskStatusFunc({
|
|
|
769
774
|
structureFn: getDeployStructure,
|
|
770
775
|
statusText: PROJECT_DEPLOY_TEXT,
|
|
771
776
|
statusStrings: {
|
|
772
|
-
INITIALIZE: name =>
|
|
773
|
-
|
|
774
|
-
|
|
777
|
+
INITIALIZE: (name, buildId) =>
|
|
778
|
+
`Deploying build #${buildId} in ${chalk.bold(name)}`,
|
|
779
|
+
SUCCESS: (name, buildId) =>
|
|
780
|
+
`Deployed build #${buildId} in ${chalk.bold(name)}`,
|
|
781
|
+
FAIL: (name, buildId) =>
|
|
782
|
+
`Failed to deploy build #${buildId} in ${chalk.bold(name)}`,
|
|
775
783
|
SUBTASK_FAIL: (deployedBuildId, name) =>
|
|
776
784
|
`Deploy for build #${deployedBuildId} failed because there was a\nproblem deploying ${chalk.bold(
|
|
777
785
|
name
|
|
@@ -825,11 +833,13 @@ const showPlatformVersionWarning = async (accountId, projectConfig) => {
|
|
|
825
833
|
defaultVersion,
|
|
826
834
|
})
|
|
827
835
|
);
|
|
836
|
+
logger.log('');
|
|
828
837
|
} catch (e) {
|
|
829
838
|
logger.log('');
|
|
830
839
|
logger.warn(
|
|
831
840
|
i18n(`${i18nKey}.showPlatformVersionWarning.noPlatformVersionAlt`)
|
|
832
841
|
);
|
|
842
|
+
logger.log('');
|
|
833
843
|
logger.debug(e.error);
|
|
834
844
|
}
|
|
835
845
|
}
|
|
@@ -5,7 +5,6 @@ const {
|
|
|
5
5
|
logApiErrorInstance,
|
|
6
6
|
ApiErrorContext,
|
|
7
7
|
} = require('@hubspot/cli-lib/errorHandlers');
|
|
8
|
-
const { getProjectConfig } = require('../projects');
|
|
9
8
|
const { EXIT_CODES } = require('../enums/exitCodes');
|
|
10
9
|
const { i18n } = require('../lang');
|
|
11
10
|
|
|
@@ -13,14 +12,12 @@ const i18nKey = 'cli.lib.prompts.downloadProjectPrompt';
|
|
|
13
12
|
|
|
14
13
|
const createProjectsList = async () => {
|
|
15
14
|
const accountId = getAccountId();
|
|
16
|
-
const { projectConfig } = await getProjectConfig();
|
|
17
|
-
const projectName = projectConfig.name;
|
|
18
15
|
|
|
19
16
|
try {
|
|
20
17
|
const projects = await fetchProjects(accountId);
|
|
21
18
|
return projects.results;
|
|
22
19
|
} catch (e) {
|
|
23
|
-
logApiErrorInstance(e, new ApiErrorContext({ accountId
|
|
20
|
+
logApiErrorInstance(e, new ApiErrorContext({ accountId }));
|
|
24
21
|
process.exit(EXIT_CODES.ERROR);
|
|
25
22
|
}
|
|
26
23
|
};
|
|
@@ -26,7 +26,11 @@ const selectTargetAccountPrompt = async (accounts, defaultAccountConfig) => {
|
|
|
26
26
|
logger.debug('Unable to fetch sandbox usage limits: ', err);
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
-
const sandboxAccounts = accounts
|
|
29
|
+
const sandboxAccounts = accounts
|
|
30
|
+
.reverse()
|
|
31
|
+
.filter(
|
|
32
|
+
config => isSandbox(config) && config.parentAccountId === defaultAccountId
|
|
33
|
+
);
|
|
30
34
|
let disabledMessage = false;
|
|
31
35
|
|
|
32
36
|
if (sandboxUsage['DEVELOPER'] && sandboxUsage['DEVELOPER'].available === 0) {
|
|
@@ -74,6 +78,21 @@ const selectTargetAccountPrompt = async (accounts, defaultAccountConfig) => {
|
|
|
74
78
|
return targetAccountInfo;
|
|
75
79
|
};
|
|
76
80
|
|
|
81
|
+
const confirmDefaultSandboxAccountPrompt = async (accountName, accountType) => {
|
|
82
|
+
const { useDefaultAccount } = await promptUser([
|
|
83
|
+
{
|
|
84
|
+
name: 'useDefaultAccount',
|
|
85
|
+
type: 'confirm',
|
|
86
|
+
message: i18n(`${i18nKey}.confirmDefaultSandboxAccount`, {
|
|
87
|
+
accountName,
|
|
88
|
+
accountType,
|
|
89
|
+
}),
|
|
90
|
+
},
|
|
91
|
+
]);
|
|
92
|
+
return useDefaultAccount;
|
|
93
|
+
};
|
|
94
|
+
|
|
77
95
|
module.exports = {
|
|
78
96
|
selectTargetAccountPrompt,
|
|
97
|
+
confirmDefaultSandboxAccountPrompt,
|
|
79
98
|
};
|
package/lib/ui.js
CHANGED
|
@@ -7,7 +7,9 @@ const { i18n } = require('./lang');
|
|
|
7
7
|
const { logger } = require('@hubspot/cli-lib/logger');
|
|
8
8
|
|
|
9
9
|
const UI_COLORS = {
|
|
10
|
-
|
|
10
|
+
SORBET: '#FF8F59',
|
|
11
|
+
MARIGOLD: '#f5c26b',
|
|
12
|
+
MARIGOLD_DARK: '#dbae60',
|
|
11
13
|
};
|
|
12
14
|
|
|
13
15
|
/**
|
|
@@ -92,6 +94,10 @@ const uiInfoSection = (title, logContent) => {
|
|
|
92
94
|
uiLine();
|
|
93
95
|
};
|
|
94
96
|
|
|
97
|
+
const uiCommandReference = command => {
|
|
98
|
+
return chalk.bold(chalk.hex(UI_COLORS.MARIGOLD_DARK)(`\`${command}\``));
|
|
99
|
+
};
|
|
100
|
+
|
|
95
101
|
const uiFeatureHighlight = (commands, title) => {
|
|
96
102
|
const i18nKey = 'cli.lib.ui.featureHighlight';
|
|
97
103
|
|
|
@@ -112,7 +118,7 @@ const uiFeatureHighlight = (commands, title) => {
|
|
|
112
118
|
const uiBetaMessage = message => {
|
|
113
119
|
const i18nKey = 'cli.lib.ui';
|
|
114
120
|
|
|
115
|
-
logger.log(chalk.hex(UI_COLORS.
|
|
121
|
+
logger.log(chalk.hex(UI_COLORS.SORBET)(i18n(`${i18nKey}.betaTag`)), message);
|
|
116
122
|
};
|
|
117
123
|
|
|
118
124
|
const uiBetaWarning = logMessage => {
|
|
@@ -126,6 +132,7 @@ const uiBetaWarning = logMessage => {
|
|
|
126
132
|
module.exports = {
|
|
127
133
|
UI_COLORS,
|
|
128
134
|
uiAccountDescription,
|
|
135
|
+
uiCommandReference,
|
|
129
136
|
uiBetaMessage,
|
|
130
137
|
uiBetaWarning,
|
|
131
138
|
uiFeatureHighlight,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hubspot/cli",
|
|
3
|
-
"version": "4.2.1-beta.
|
|
3
|
+
"version": "4.2.1-beta.4",
|
|
4
4
|
"description": "CLI for working with HubSpot",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|
|
@@ -8,16 +8,14 @@
|
|
|
8
8
|
"url": "https://github.com/HubSpot/hubspot-cms-tools"
|
|
9
9
|
},
|
|
10
10
|
"dependencies": {
|
|
11
|
-
"@hubspot/cli-lib": "^4.2.
|
|
12
|
-
"@hubspot/serverless-dev-runtime": "4.2.1-beta.
|
|
13
|
-
"@hubspot/ui-extensions-dev-server": "^0.
|
|
11
|
+
"@hubspot/cli-lib": "^4.2.2",
|
|
12
|
+
"@hubspot/serverless-dev-runtime": "4.2.1-beta.3",
|
|
13
|
+
"@hubspot/ui-extensions-dev-server": "^0.7.2",
|
|
14
14
|
"archiver": "^5.3.0",
|
|
15
|
-
"body-parser": "^1.19.0",
|
|
16
15
|
"chalk": "^4.1.2",
|
|
17
16
|
"chokidar": "^3.0.1",
|
|
18
17
|
"cli-cursor": "^3.1.0",
|
|
19
18
|
"cli-progress": "^3.11.2",
|
|
20
|
-
"cors": "^2.8.5",
|
|
21
19
|
"express": "^4.17.1",
|
|
22
20
|
"findup-sync": "^4.0.0",
|
|
23
21
|
"fs-extra": "^8.1.0",
|
|
@@ -26,7 +24,6 @@
|
|
|
26
24
|
"moment": "^2.29.1",
|
|
27
25
|
"open": "^7.0.3",
|
|
28
26
|
"ora": "^4.0.3",
|
|
29
|
-
"p-queue": "^6.0.2",
|
|
30
27
|
"strip-ansi": "^5.2.0",
|
|
31
28
|
"tmp": "^0.2.1",
|
|
32
29
|
"update-notifier": "^5.1.0",
|
|
@@ -45,5 +42,5 @@
|
|
|
45
42
|
"publishConfig": {
|
|
46
43
|
"access": "public"
|
|
47
44
|
},
|
|
48
|
-
"gitHead": "
|
|
45
|
+
"gitHead": "24d48c93e04bacc5db761cc15489b5bc82e17847"
|
|
49
46
|
}
|
package/lib/LocalDevManagerV2.js
DELETED
|
@@ -1,239 +0,0 @@
|
|
|
1
|
-
const path = require('path');
|
|
2
|
-
const chalk = require('chalk');
|
|
3
|
-
const { i18n } = require('./lang');
|
|
4
|
-
const { logger } = require('@hubspot/cli-lib/logger');
|
|
5
|
-
const { handleKeypress } = require('@hubspot/cli-lib/lib/process');
|
|
6
|
-
const {
|
|
7
|
-
getAccountId,
|
|
8
|
-
getConfigDefaultAccount,
|
|
9
|
-
} = require('@hubspot/cli-lib/lib/config');
|
|
10
|
-
const SpinniesManager = require('./SpinniesManager');
|
|
11
|
-
const DevServerManager = require('./DevServerManager');
|
|
12
|
-
const { EXIT_CODES } = require('./enums/exitCodes');
|
|
13
|
-
const { getProjectDetailUrl } = require('./projects');
|
|
14
|
-
const {
|
|
15
|
-
COMPONENT_TYPES,
|
|
16
|
-
findProjectComponents,
|
|
17
|
-
getAppCardConfigs,
|
|
18
|
-
} = require('./projectStructure');
|
|
19
|
-
const {
|
|
20
|
-
UI_COLORS,
|
|
21
|
-
uiAccountDescription,
|
|
22
|
-
uiBetaMessage,
|
|
23
|
-
uiLink,
|
|
24
|
-
uiLine,
|
|
25
|
-
} = require('./ui');
|
|
26
|
-
|
|
27
|
-
const i18nKey = 'cli.lib.LocalDevManagerV2';
|
|
28
|
-
|
|
29
|
-
class LocalDevManagerV2 {
|
|
30
|
-
constructor(options) {
|
|
31
|
-
this.targetAccountId = options.targetAccountId;
|
|
32
|
-
this.projectConfig = options.projectConfig;
|
|
33
|
-
this.projectDir = options.projectDir;
|
|
34
|
-
this.debug = options.debug || false;
|
|
35
|
-
this.alpha = options.alpha;
|
|
36
|
-
this.deployedBuild = options.deployedBuild;
|
|
37
|
-
|
|
38
|
-
this.projectSourceDir = path.join(
|
|
39
|
-
this.projectDir,
|
|
40
|
-
this.projectConfig.srcDir
|
|
41
|
-
);
|
|
42
|
-
|
|
43
|
-
if (!this.targetAccountId || !this.projectConfig || !this.projectDir) {
|
|
44
|
-
logger.log(i18n(`${i18nKey}.failedToInitialize`));
|
|
45
|
-
process.exit(EXIT_CODES.ERROR);
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
async start() {
|
|
50
|
-
SpinniesManager.removeAll();
|
|
51
|
-
SpinniesManager.init();
|
|
52
|
-
|
|
53
|
-
const components = await findProjectComponents(this.projectSourceDir);
|
|
54
|
-
|
|
55
|
-
if (!components.length) {
|
|
56
|
-
logger.log();
|
|
57
|
-
logger.error(i18n(`${i18nKey}.noComponents`));
|
|
58
|
-
process.exit(EXIT_CODES.SUCCESS);
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
const runnableComponents = components.filter(
|
|
62
|
-
component => component.runnable
|
|
63
|
-
);
|
|
64
|
-
|
|
65
|
-
if (!runnableComponents.length) {
|
|
66
|
-
logger.log();
|
|
67
|
-
logger.error(i18n(`${i18nKey}.noRunnableComponents`));
|
|
68
|
-
process.exit(EXIT_CODES.SUCCESS);
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
logger.log();
|
|
72
|
-
const setupSucceeded = await this.devServerSetup(runnableComponents);
|
|
73
|
-
|
|
74
|
-
if (setupSucceeded || !this.debug) {
|
|
75
|
-
console.clear();
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
uiBetaMessage(i18n(`${i18nKey}.betaMessage`));
|
|
79
|
-
logger.log();
|
|
80
|
-
logger.log(
|
|
81
|
-
chalk.hex(UI_COLORS.orange)(
|
|
82
|
-
i18n(`${i18nKey}.running`, {
|
|
83
|
-
accountIdentifier: uiAccountDescription(this.targetAccountId),
|
|
84
|
-
projectName: this.projectConfig.name,
|
|
85
|
-
})
|
|
86
|
-
)
|
|
87
|
-
);
|
|
88
|
-
logger.log(
|
|
89
|
-
uiLink(
|
|
90
|
-
i18n(`${i18nKey}.viewInHubSpotLink`),
|
|
91
|
-
getProjectDetailUrl(this.projectConfig.name, this.targetAccountId)
|
|
92
|
-
)
|
|
93
|
-
);
|
|
94
|
-
logger.log();
|
|
95
|
-
logger.log(i18n(`${i18nKey}.quitHelper`));
|
|
96
|
-
uiLine();
|
|
97
|
-
logger.log();
|
|
98
|
-
|
|
99
|
-
await this.devServerStart();
|
|
100
|
-
|
|
101
|
-
this.updateKeypressListeners();
|
|
102
|
-
|
|
103
|
-
this.compareLocalProjectToDeployed(runnableComponents);
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
async stop() {
|
|
107
|
-
SpinniesManager.add('cleanupMessage', {
|
|
108
|
-
text: i18n(`${i18nKey}.exitingStart`),
|
|
109
|
-
});
|
|
110
|
-
|
|
111
|
-
const cleanupSucceeded = await this.devServerCleanup();
|
|
112
|
-
|
|
113
|
-
if (!cleanupSucceeded) {
|
|
114
|
-
SpinniesManager.fail('cleanupMessage', {
|
|
115
|
-
text: i18n(`${i18nKey}.exitingFail`),
|
|
116
|
-
});
|
|
117
|
-
process.exit(EXIT_CODES.ERROR);
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
SpinniesManager.succeed('cleanupMessage', {
|
|
121
|
-
text: i18n(`${i18nKey}.exitingSucceed`),
|
|
122
|
-
});
|
|
123
|
-
process.exit(EXIT_CODES.SUCCESS);
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
updateKeypressListeners() {
|
|
127
|
-
handleKeypress(async key => {
|
|
128
|
-
if ((key.ctrl && key.name === 'c') || key.name === 'q') {
|
|
129
|
-
this.stop();
|
|
130
|
-
}
|
|
131
|
-
});
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
logUploadWarning(reason) {
|
|
135
|
-
const currentDefaultAccount = getConfigDefaultAccount();
|
|
136
|
-
const defaultAccountId = getAccountId(currentDefaultAccount);
|
|
137
|
-
|
|
138
|
-
logger.log();
|
|
139
|
-
logger.warn(i18n(`${i18nKey}.uploadWarning.header`, { reason }));
|
|
140
|
-
logger.log(i18n(`${i18nKey}.uploadWarning.stopDev`));
|
|
141
|
-
if (this.targetAccountId !== defaultAccountId) {
|
|
142
|
-
logger.log(
|
|
143
|
-
i18n(`${i18nKey}.uploadWarning.runUploadWithAccount`, {
|
|
144
|
-
accountId: this.targetAccountId,
|
|
145
|
-
})
|
|
146
|
-
);
|
|
147
|
-
} else {
|
|
148
|
-
logger.log(i18n(`${i18nKey}.uploadWarning.runUpload`));
|
|
149
|
-
}
|
|
150
|
-
logger.log(i18n(`${i18nKey}.uploadWarning.restartDev`));
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
compareLocalProjectToDeployed(runnableComponents) {
|
|
154
|
-
const deployedComponentNames = this.deployedBuild.subbuildStatuses.map(
|
|
155
|
-
subbuildStatus => subbuildStatus.buildName
|
|
156
|
-
);
|
|
157
|
-
|
|
158
|
-
let missingComponents = [];
|
|
159
|
-
|
|
160
|
-
runnableComponents.forEach(({ type, config, path }) => {
|
|
161
|
-
if (type === COMPONENT_TYPES.app) {
|
|
162
|
-
const cardConfigs = getAppCardConfigs(config, path);
|
|
163
|
-
|
|
164
|
-
cardConfigs.forEach(cardConfig => {
|
|
165
|
-
if (
|
|
166
|
-
cardConfig.data &&
|
|
167
|
-
cardConfig.data.title &&
|
|
168
|
-
!deployedComponentNames.includes(cardConfig.data.title)
|
|
169
|
-
) {
|
|
170
|
-
missingComponents.push(cardConfig.data.title);
|
|
171
|
-
}
|
|
172
|
-
});
|
|
173
|
-
}
|
|
174
|
-
});
|
|
175
|
-
|
|
176
|
-
if (missingComponents.length) {
|
|
177
|
-
this.logUploadWarning(
|
|
178
|
-
i18n(`${i18nKey}.uploadWarning.missingComponents`, {
|
|
179
|
-
missingComponents: missingComponents.join(','),
|
|
180
|
-
})
|
|
181
|
-
);
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
async devServerSetup(components) {
|
|
186
|
-
try {
|
|
187
|
-
await DevServerManager.setup({
|
|
188
|
-
alpha: this.alpha,
|
|
189
|
-
components,
|
|
190
|
-
debug: this.debug,
|
|
191
|
-
onUploadRequired: this.logUploadWarning.bind(this),
|
|
192
|
-
});
|
|
193
|
-
return true;
|
|
194
|
-
} catch (e) {
|
|
195
|
-
if (this.debug) {
|
|
196
|
-
logger.error(e);
|
|
197
|
-
}
|
|
198
|
-
logger.error(
|
|
199
|
-
i18n(`${i18nKey}.devServer.setupError`, { message: e.message })
|
|
200
|
-
);
|
|
201
|
-
return false;
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
async devServerStart() {
|
|
206
|
-
try {
|
|
207
|
-
await DevServerManager.start({
|
|
208
|
-
alpha: this.alpha,
|
|
209
|
-
accountId: this.targetAccountId,
|
|
210
|
-
projectConfig: this.projectConfig,
|
|
211
|
-
});
|
|
212
|
-
} catch (e) {
|
|
213
|
-
if (this.debug) {
|
|
214
|
-
logger.error(e);
|
|
215
|
-
}
|
|
216
|
-
logger.error(
|
|
217
|
-
i18n(`${i18nKey}.devServer.startError`, { message: e.message })
|
|
218
|
-
);
|
|
219
|
-
process.exit(EXIT_CODES.ERROR);
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
async devServerCleanup() {
|
|
224
|
-
try {
|
|
225
|
-
await DevServerManager.cleanup();
|
|
226
|
-
return true;
|
|
227
|
-
} catch (e) {
|
|
228
|
-
if (this.debug) {
|
|
229
|
-
logger.error(e);
|
|
230
|
-
}
|
|
231
|
-
logger.error(
|
|
232
|
-
i18n(`${i18nKey}.devServer.cleanupError`, { message: e.message })
|
|
233
|
-
);
|
|
234
|
-
return false;
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
module.exports = LocalDevManagerV2;
|