@hubspot/cli 6.3.0 → 6.4.0-beta.1
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 +2 -0
- package/commands/doctor.d.ts +8 -0
- package/commands/doctor.js +60 -0
- package/commands/init.js +20 -7
- package/commands/lint.d.ts +4 -1
- package/commands/lint.js +11 -2
- package/commands/project/installDeps.js +5 -5
- package/commands/project/logs.js +1 -1
- package/commands/theme/preview.js +38 -20
- package/lang/en.lyaml +68 -0
- package/lib/DevServerManager.js +2 -5
- package/lib/commonOpts.d.ts +3 -2
- package/lib/commonOpts.js +2 -2
- package/lib/dependencyManagement.d.ts +3 -1
- package/lib/dependencyManagement.js +19 -0
- package/lib/doctor/Diagnosis.d.ts +27 -0
- package/lib/doctor/Diagnosis.js +119 -0
- package/lib/doctor/DiagnosticInfoBuilder.d.ts +61 -0
- package/lib/doctor/DiagnosticInfoBuilder.js +158 -0
- package/lib/doctor/Doctor.d.ts +21 -0
- package/lib/doctor/Doctor.js +328 -0
- package/lib/errorHandlers/index.d.ts +14 -1
- package/lib/errorHandlers/index.js +43 -50
- package/lib/errorHandlers/suppressError.d.ts +2 -1
- package/lib/errorHandlers/suppressError.js +32 -37
- package/lib/interpolation.d.ts +3 -0
- package/lib/interpolation.js +4 -3
- package/lib/links.d.ts +9 -0
- package/lib/links.js +99 -97
- package/lib/projects.d.ts +4 -1
- package/lib/projects.js +5 -3
- package/lib/ui/SpinniesManager.d.ts +39 -1
- package/lib/ui/SpinniesManager.js +66 -35
- package/lib/ui/git.d.ts +1 -1
- package/lib/ui/git.js +17 -17
- package/lib/ui/index.d.ts +16 -1
- package/lib/ui/index.js +87 -114
- package/lib/ui/serverlessFunctionLogs.js +28 -19
- package/lib/ui/spinniesUtils.d.ts +31 -0
- package/lib/ui/spinniesUtils.js +45 -31
- package/lib/ui/supportHyperlinks.d.ts +6 -0
- package/lib/ui/supportHyperlinks.js +10 -10
- package/lib/ui/supportsColor.d.ts +16 -0
- package/lib/ui/supportsColor.js +19 -17
- package/lib/ui/table.d.ts +3 -1
- package/lib/ui/table.js +17 -11
- package/lib/usageTracking.d.ts +2 -1
- package/lib/usageTracking.js +2 -0
- package/package.json +10 -5
package/bin/cli.js
CHANGED
|
@@ -38,6 +38,7 @@ const accountsCommand = require('../commands/accounts');
|
|
|
38
38
|
const sandboxesCommand = require('../commands/sandbox');
|
|
39
39
|
const cmsCommand = require('../commands/cms');
|
|
40
40
|
const feedbackCommand = require('../commands/feedback');
|
|
41
|
+
const doctorCommand = require('../commands/doctor');
|
|
41
42
|
const notifier = updateNotifier({
|
|
42
43
|
pkg: { ...pkg, name: '@hubspot/cli' },
|
|
43
44
|
distTag: 'latest',
|
|
@@ -167,6 +168,7 @@ const argv = yargs
|
|
|
167
168
|
.command(accountsCommand)
|
|
168
169
|
.command(sandboxesCommand)
|
|
169
170
|
.command(feedbackCommand)
|
|
171
|
+
.command(doctorCommand)
|
|
170
172
|
.help()
|
|
171
173
|
.recommendCommands()
|
|
172
174
|
.demandCommand(1, '')
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { ArgumentsCamelCase, BuilderCallback } from 'yargs';
|
|
2
|
+
export interface DoctorOptions {
|
|
3
|
+
'output-dir'?: string;
|
|
4
|
+
}
|
|
5
|
+
export declare const command = "doctor";
|
|
6
|
+
export declare const describe: any;
|
|
7
|
+
export declare const handler: ({ outputDir, }: ArgumentsCamelCase<DoctorOptions>) => Promise<never>;
|
|
8
|
+
export declare const builder: BuilderCallback<DoctorOptions, DoctorOptions>;
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.builder = exports.handler = exports.describe = exports.command = void 0;
|
|
7
|
+
const usageTracking_1 = require("../lib/usageTracking");
|
|
8
|
+
const logger_1 = require("@hubspot/local-dev-lib/logger");
|
|
9
|
+
const fs_1 = __importDefault(require("fs"));
|
|
10
|
+
const Doctor_1 = require("../lib/doctor/Doctor");
|
|
11
|
+
const exitCodes_1 = require("../lib/enums/exitCodes");
|
|
12
|
+
const path_1 = __importDefault(require("path"));
|
|
13
|
+
const path_2 = require("@hubspot/local-dev-lib/path");
|
|
14
|
+
const { i18n } = require('../lib/lang');
|
|
15
|
+
const i18nKey = 'commands.doctor';
|
|
16
|
+
exports.command = 'doctor';
|
|
17
|
+
exports.describe = i18n(`${i18nKey}.describe`);
|
|
18
|
+
const handler = async ({ outputDir, }) => {
|
|
19
|
+
const doctor = new Doctor_1.Doctor();
|
|
20
|
+
(0, usageTracking_1.trackCommandUsage)(exports.command, undefined, doctor.accountId);
|
|
21
|
+
const output = await doctor.diagnose();
|
|
22
|
+
const totalCount = (output?.errorCount || 0) + (output?.warningCount || 0);
|
|
23
|
+
if (totalCount > 0) {
|
|
24
|
+
(0, usageTracking_1.trackCommandMetadataUsage)(exports.command, { success: false, type: totalCount }, doctor.accountId);
|
|
25
|
+
}
|
|
26
|
+
if (!outputDir) {
|
|
27
|
+
if (output?.diagnosis) {
|
|
28
|
+
logger_1.logger.log(output.diagnosis);
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
logger_1.logger.error(i18n(`${i18nKey}.errors.generatingDiagnosis`));
|
|
32
|
+
return process.exit(exitCodes_1.EXIT_CODES.ERROR);
|
|
33
|
+
}
|
|
34
|
+
return process.exit(exitCodes_1.EXIT_CODES.SUCCESS);
|
|
35
|
+
}
|
|
36
|
+
if (!path_1.default.isAbsolute(outputDir)) {
|
|
37
|
+
outputDir = path_1.default.join((0, path_2.getCwd)(), outputDir);
|
|
38
|
+
}
|
|
39
|
+
const outputFile = path_1.default.join(outputDir, `hubspot-doctor-${new Date().toISOString()}.json`);
|
|
40
|
+
try {
|
|
41
|
+
fs_1.default.writeFileSync(outputFile, JSON.stringify(output, null, 4));
|
|
42
|
+
logger_1.logger.success(i18n(`${i18nKey}.outputWritten`, { filename: outputFile }));
|
|
43
|
+
}
|
|
44
|
+
catch (e) {
|
|
45
|
+
logger_1.logger.error(i18n(`${i18nKey}.errors.unableToWriteOutputFile`, {
|
|
46
|
+
file: outputFile,
|
|
47
|
+
errorMessage: e instanceof Error ? e.message : e,
|
|
48
|
+
}));
|
|
49
|
+
return process.exit(exitCodes_1.EXIT_CODES.ERROR);
|
|
50
|
+
}
|
|
51
|
+
return process.exit(exitCodes_1.EXIT_CODES.SUCCESS);
|
|
52
|
+
};
|
|
53
|
+
exports.handler = handler;
|
|
54
|
+
const builder = yargs => {
|
|
55
|
+
yargs.option('output-dir', {
|
|
56
|
+
describe: i18n(`${i18nKey}.options.outputDir`),
|
|
57
|
+
type: 'string',
|
|
58
|
+
});
|
|
59
|
+
};
|
|
60
|
+
exports.builder = builder;
|
package/commands/init.js
CHANGED
|
@@ -67,12 +67,14 @@ exports.describe = i18n(`${i18nKey}.describe`, {
|
|
|
67
67
|
configName: DEFAULT_HUBSPOT_CONFIG_YAML_FILE_NAME,
|
|
68
68
|
});
|
|
69
69
|
exports.handler = async (options) => {
|
|
70
|
-
const { auth: authType = PERSONAL_ACCESS_KEY_AUTH_METHOD.value, c, account: optionalAccount, } = options;
|
|
70
|
+
const { auth: authType = PERSONAL_ACCESS_KEY_AUTH_METHOD.value, c, account: optionalAccount, disableTracking, } = options;
|
|
71
71
|
const configPath = (c && path.join(getCwd(), c)) || getConfigPath();
|
|
72
72
|
setLogLevel(options);
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
73
|
+
if (!disableTracking) {
|
|
74
|
+
trackCommandUsage('init', {
|
|
75
|
+
authType,
|
|
76
|
+
});
|
|
77
|
+
}
|
|
76
78
|
const env = options.qa ? ENVIRONMENTS.QA : ENVIRONMENTS.PROD;
|
|
77
79
|
if (fs.existsSync(configPath)) {
|
|
78
80
|
logger.error(i18n(`${i18nKey}.errors.configFileExists`, {
|
|
@@ -81,7 +83,9 @@ exports.handler = async (options) => {
|
|
|
81
83
|
logger.info(i18n(`${i18nKey}.logs.updateConfig`));
|
|
82
84
|
process.exit(EXIT_CODES.ERROR);
|
|
83
85
|
}
|
|
84
|
-
|
|
86
|
+
if (!disableTracking) {
|
|
87
|
+
await trackAuthAction('init', authType, TRACKING_STATUS.STARTED);
|
|
88
|
+
}
|
|
85
89
|
createEmptyConfigFile({ path: configPath });
|
|
86
90
|
handleExit(deleteEmptyConfigFile);
|
|
87
91
|
try {
|
|
@@ -102,12 +106,16 @@ exports.handler = async (options) => {
|
|
|
102
106
|
account: name || accountId,
|
|
103
107
|
}));
|
|
104
108
|
uiFeatureHighlight(['helpCommand', 'authCommand', 'accountsListCommand']);
|
|
105
|
-
|
|
109
|
+
if (!disableTracking) {
|
|
110
|
+
await trackAuthAction('init', authType, TRACKING_STATUS.COMPLETE, accountId);
|
|
111
|
+
}
|
|
106
112
|
process.exit(EXIT_CODES.SUCCESS);
|
|
107
113
|
}
|
|
108
114
|
catch (err) {
|
|
109
115
|
logError(err);
|
|
110
|
-
|
|
116
|
+
if (!disableTracking) {
|
|
117
|
+
await trackAuthAction('init', authType, TRACKING_STATUS.ERROR);
|
|
118
|
+
}
|
|
111
119
|
process.exit(EXIT_CODES.ERROR);
|
|
112
120
|
}
|
|
113
121
|
};
|
|
@@ -129,6 +137,11 @@ exports.builder = yargs => {
|
|
|
129
137
|
describe: i18n(`${i18nKey}.options.account.describe`),
|
|
130
138
|
type: 'string',
|
|
131
139
|
},
|
|
140
|
+
'disable-tracking': {
|
|
141
|
+
type: 'boolean',
|
|
142
|
+
hidden: true,
|
|
143
|
+
default: false,
|
|
144
|
+
},
|
|
132
145
|
});
|
|
133
146
|
addConfigOptions(yargs);
|
|
134
147
|
addTestingOptions(yargs);
|
package/commands/lint.d.ts
CHANGED
package/commands/lint.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.builder = exports.handler = exports.describe = exports.command = void 0;
|
|
3
4
|
// @ts-nocheck
|
|
4
5
|
const { lint } = require('@hubspot/local-dev-lib/cms/validate');
|
|
5
6
|
const { logger } = require('@hubspot/local-dev-lib/logger');
|
|
@@ -42,7 +43,7 @@ function printHublValidationResult({ file, validation }) {
|
|
|
42
43
|
logger.groupEnd();
|
|
43
44
|
return count;
|
|
44
45
|
}
|
|
45
|
-
|
|
46
|
+
const handler = async (options) => {
|
|
46
47
|
const { path: lintPath } = options;
|
|
47
48
|
await loadAndValidateOptions(options);
|
|
48
49
|
const accountId = getAccountId(options);
|
|
@@ -68,7 +69,8 @@ exports.handler = async (options) => {
|
|
|
68
69
|
count,
|
|
69
70
|
}));
|
|
70
71
|
};
|
|
71
|
-
exports.
|
|
72
|
+
exports.handler = handler;
|
|
73
|
+
const builder = yargs => {
|
|
72
74
|
addConfigOptions(yargs);
|
|
73
75
|
addAccountOptions(yargs);
|
|
74
76
|
yargs.positional('path', {
|
|
@@ -77,3 +79,10 @@ exports.builder = yargs => {
|
|
|
77
79
|
});
|
|
78
80
|
return yargs;
|
|
79
81
|
};
|
|
82
|
+
exports.builder = builder;
|
|
83
|
+
module.exports = {
|
|
84
|
+
builder: exports.builder,
|
|
85
|
+
handler: exports.handler,
|
|
86
|
+
command: exports.command,
|
|
87
|
+
describe: exports.describe,
|
|
88
|
+
};
|
|
@@ -10,14 +10,14 @@ const path = require('path');
|
|
|
10
10
|
const { i18n } = require('../../lib/lang');
|
|
11
11
|
const { trackCommandUsage } = require('../../lib/usageTracking');
|
|
12
12
|
const { getAccountId } = require('../../lib/commonOpts');
|
|
13
|
+
const { uiBetaTag } = require('../../lib/ui');
|
|
13
14
|
const i18nKey = `commands.project.subcommands.installDeps`;
|
|
14
15
|
exports.command = 'install-deps [packages..]';
|
|
15
|
-
|
|
16
|
-
exports.
|
|
17
|
-
|
|
18
|
-
exports.handler = async ({ packages }) => {
|
|
16
|
+
exports.describe = uiBetaTag(i18n(`${i18nKey}.help.describe`), false);
|
|
17
|
+
exports.handler = async (options) => {
|
|
18
|
+
const { packages } = options || {};
|
|
19
19
|
try {
|
|
20
|
-
const accountId = getAccountId();
|
|
20
|
+
const accountId = getAccountId(options);
|
|
21
21
|
trackCommandUsage('project-install-deps', null, accountId);
|
|
22
22
|
const projectConfig = await getProjectConfig();
|
|
23
23
|
if (!projectConfig || !projectConfig.projectDir) {
|
package/commands/project/logs.js
CHANGED
|
@@ -7,7 +7,6 @@ const { i18n } = require('../../lib/lang');
|
|
|
7
7
|
const { logger } = require('@hubspot/local-dev-lib/logger');
|
|
8
8
|
const { addAccountOptions, addConfigOptions, getAccountId, } = require('../../lib/commonOpts');
|
|
9
9
|
const { getCwd } = require('@hubspot/local-dev-lib/path');
|
|
10
|
-
const { preview } = require('@hubspot/theme-preview-dev-server');
|
|
11
10
|
const { getUploadableFileList } = require('../../lib/upload');
|
|
12
11
|
const { trackCommandUsage } = require('../../lib/usageTracking');
|
|
13
12
|
const { loadAndValidateOptions } = require('../../lib/validation');
|
|
@@ -20,6 +19,8 @@ const { handleExit, handleKeypress } = require('../../lib/process');
|
|
|
20
19
|
const { getThemeJSONPath } = require('@hubspot/local-dev-lib/cms/themes');
|
|
21
20
|
const { getProjectConfig } = require('../../lib/projects');
|
|
22
21
|
const { findProjectComponents, COMPONENT_TYPES, } = require('../../lib/projectStructure');
|
|
22
|
+
const { preview } = require('@hubspot/theme-preview-dev-server');
|
|
23
|
+
const { hasFeature } = require('../../lib/hasFeature');
|
|
23
24
|
const i18nKey = 'commands.theme.subcommands.preview';
|
|
24
25
|
exports.command = 'preview [--src] [--dest]';
|
|
25
26
|
exports.describe = i18n(`${i18nKey}.describe`);
|
|
@@ -89,7 +90,7 @@ const determineSrcAndDest = async (options) => {
|
|
|
89
90
|
return { absoluteSrc, dest };
|
|
90
91
|
};
|
|
91
92
|
exports.handler = async (options) => {
|
|
92
|
-
const { notify,
|
|
93
|
+
const { notify, noSsl, resetSession, port, generateFieldsTypes } = options;
|
|
93
94
|
await loadAndValidateOptions(options);
|
|
94
95
|
const accountId = getAccountId(options);
|
|
95
96
|
const { absoluteSrc, dest } = await determineSrcAndDest(options);
|
|
@@ -144,17 +145,39 @@ exports.handler = async (options) => {
|
|
|
144
145
|
return uploadOptions;
|
|
145
146
|
};
|
|
146
147
|
trackCommandUsage('preview', accountId);
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
148
|
+
let createUnifiedDevServer;
|
|
149
|
+
try {
|
|
150
|
+
require.resolve('@hubspot/cms-dev-server');
|
|
151
|
+
const { createDevServer } = await import('@hubspot/cms-dev-server');
|
|
152
|
+
createUnifiedDevServer = createDevServer;
|
|
153
|
+
}
|
|
154
|
+
catch (e) {
|
|
155
|
+
logger.warn('Unified dev server requires node 20 to run. Defaulting to legacy preview.');
|
|
156
|
+
}
|
|
157
|
+
const isUngatedForUnified = await hasFeature(accountId, 'cms:react:unifiedThemePreview');
|
|
158
|
+
if (isUngatedForUnified && createUnifiedDevServer) {
|
|
159
|
+
if (port) {
|
|
160
|
+
process.env['PORT'] = port;
|
|
161
|
+
}
|
|
162
|
+
createUnifiedDevServer(absoluteSrc, false, false, false, !noSsl, generateFieldsTypes, {
|
|
163
|
+
filePaths,
|
|
164
|
+
resetSession,
|
|
165
|
+
startProgressBar,
|
|
166
|
+
handleUserInput,
|
|
167
|
+
dest,
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
else {
|
|
171
|
+
preview(accountId, absoluteSrc, dest, {
|
|
172
|
+
notify,
|
|
173
|
+
filePaths,
|
|
174
|
+
noSsl,
|
|
175
|
+
port,
|
|
176
|
+
resetSession,
|
|
177
|
+
startProgressBar,
|
|
178
|
+
handleUserInput,
|
|
179
|
+
});
|
|
180
|
+
}
|
|
158
181
|
};
|
|
159
182
|
exports.builder = yargs => {
|
|
160
183
|
addConfigOptions(yargs);
|
|
@@ -183,16 +206,11 @@ exports.builder = yargs => {
|
|
|
183
206
|
describe: i18n(`${i18nKey}.options.port.describe`),
|
|
184
207
|
type: 'number',
|
|
185
208
|
});
|
|
186
|
-
yargs.option('
|
|
187
|
-
describe: false,
|
|
188
|
-
type: 'boolean',
|
|
189
|
-
});
|
|
190
|
-
yargs.option('skipUpload', {
|
|
191
|
-
alias: 'skip',
|
|
209
|
+
yargs.option('resetSession', {
|
|
192
210
|
describe: false,
|
|
193
211
|
type: 'boolean',
|
|
194
212
|
});
|
|
195
|
-
yargs.option('
|
|
213
|
+
yargs.option('generateFieldsTypes', {
|
|
196
214
|
describe: false,
|
|
197
215
|
type: 'boolean',
|
|
198
216
|
});
|
package/lang/en.lyaml
CHANGED
|
@@ -275,6 +275,14 @@ en:
|
|
|
275
275
|
success:
|
|
276
276
|
update: "Your schema has been updated in account \"{{ accountId }}\""
|
|
277
277
|
viewAtUrl: "Schema can be viewed at {{ url }}"
|
|
278
|
+
doctor:
|
|
279
|
+
describe: "Retrieve diagnostic information about your local HubSpot configurations."
|
|
280
|
+
options:
|
|
281
|
+
outputDir: "Directory to save a detailed diagnosis JSON file in"
|
|
282
|
+
errors:
|
|
283
|
+
generatingDiagnosis: "Error generating diagnosis"
|
|
284
|
+
unableToWriteOutputFile: "Unable to write output to {{#bold}}{{ file }}{{/bold}}, {{ errorMessage }}"
|
|
285
|
+
outputWritten: "Output written to {{#bold}}{{ filename }}{{/bold}}"
|
|
278
286
|
fetch:
|
|
279
287
|
describe: "Fetch a file, directory or module from HubSpot and write to a path on your computer."
|
|
280
288
|
errors:
|
|
@@ -1135,6 +1143,7 @@ en:
|
|
|
1135
1143
|
checkFailed: "Unable to determine if config file is properly ignored by git."
|
|
1136
1144
|
serverlessFunctionLogs:
|
|
1137
1145
|
unableToProcessLog: "Unable to process log {{ log }}"
|
|
1146
|
+
noLogsFound: "No logs found."
|
|
1138
1147
|
commonOpts:
|
|
1139
1148
|
options:
|
|
1140
1149
|
portal:
|
|
@@ -1418,3 +1427,62 @@ en:
|
|
|
1418
1427
|
portalMissingScope: "Your account does not have access to this action. Talk to an account admin to request it."
|
|
1419
1428
|
userMissingScope: "You don't have access to this action. Ask an account admin to change your permissions in Users & Teams settings."
|
|
1420
1429
|
genericMissingScope: "Your access key does not allow this action. Please generate a new access key by running `hs auth personalaccesskey`."
|
|
1430
|
+
doctor:
|
|
1431
|
+
runningDiagnostics: "Running diagnostics..."
|
|
1432
|
+
diagnosticsComplete: "Diagnostics complete"
|
|
1433
|
+
accountChecks:
|
|
1434
|
+
active: "Default account active"
|
|
1435
|
+
inactive: "Default account isn't active"
|
|
1436
|
+
inactiveSecondary: "Run {{ command }} to remove inactive accounts from your CLI config"
|
|
1437
|
+
unableToDetermine: "Unable to determine if the portal is active"
|
|
1438
|
+
pak:
|
|
1439
|
+
invalid: "Personal access key is invalid"
|
|
1440
|
+
invalidSecondary: "To get a new key, run {{ command }}, deactivate your access key, and generate a new one. Then use that new key to authenticate your account."
|
|
1441
|
+
valid: "Personal Access Key is valid. {{ link }}"
|
|
1442
|
+
viewScopes: "View selected scopes"
|
|
1443
|
+
nodeChecks:
|
|
1444
|
+
unableToDetermine: "Unable to determine what version of node is installed"
|
|
1445
|
+
minimumNotMet: "Minimum Node version is not met. Upgrade to {{ nodeVersion }} or higher"
|
|
1446
|
+
success: "node v{{ nodeVersion }} is installed"
|
|
1447
|
+
npmChecks:
|
|
1448
|
+
notInstalled: "npm is not installed"
|
|
1449
|
+
installed: "npm v{{ npmVersion }} is installed"
|
|
1450
|
+
unableToDetermine: "Unable to determine if npm is installed"
|
|
1451
|
+
hsChecks:
|
|
1452
|
+
notLatest: "Version {{ hsVersion }} outdated"
|
|
1453
|
+
notLatestSecondary: "Run {{ command }} to upgrade to the latest version {{ hsVersion }}"
|
|
1454
|
+
latest: "HubSpot CLI v{{ hsVersion }} up to date"
|
|
1455
|
+
unableToDetermine: "Unable to determine if HubSpot CLI is up to date."
|
|
1456
|
+
unableToDetermineSecondary: "Run {{ command }} to check your installed version; then visit the {{ link }} to validate whether you have the latest version"
|
|
1457
|
+
unableToDetermineSecondaryLink: "npm HubSpot CLI version history"
|
|
1458
|
+
projectDependenciesChecks:
|
|
1459
|
+
missingDependencies: "missing dependencies in {{#bold}}{{ dir }}{{/bold}}"
|
|
1460
|
+
missingDependenciesSecondary: "Run {{ command }} to install all project dependencies locally"
|
|
1461
|
+
unableToDetermine: "Unable to determine if dependencies are installed {{ dir }}"
|
|
1462
|
+
success: "App dependencies are installed and up to date"
|
|
1463
|
+
files:
|
|
1464
|
+
invalidJson: "invalid JSON in {{#bold}}{{ filename }}{{/bold}}"
|
|
1465
|
+
validJson: "JSON files valid"
|
|
1466
|
+
port:
|
|
1467
|
+
inUse: "Port {{ port }} is in use"
|
|
1468
|
+
inUseSecondary: "Make sure it is available if before running {{ command }}"
|
|
1469
|
+
available: "Port {{ port }} available for local development"
|
|
1470
|
+
diagnosis:
|
|
1471
|
+
cli:
|
|
1472
|
+
header: "HubSpot CLI install"
|
|
1473
|
+
cliConfig:
|
|
1474
|
+
header: "CLI configuration"
|
|
1475
|
+
configFileSubHeader: "Config File: {{#bold}}{{ filename }}{{/bold}}"
|
|
1476
|
+
defaultAccountSubHeader: "Default Account: {{accountDetails}}"
|
|
1477
|
+
noConfigFile: "CLI configuration not found"
|
|
1478
|
+
noConfigFileSecondary: "Run {{command}} and follow the prompts to create your CLI configuration file and connect it to your HubSpot account"
|
|
1479
|
+
projectConfig:
|
|
1480
|
+
header: "Project configuration"
|
|
1481
|
+
projectDirSubHeader: "Project dir: {{#bold}}{{ projectDir }}{{/bold}}"
|
|
1482
|
+
projectNameSubHeader: "Project name: {{#bold}}{{ projectName }}{{/bold}}"
|
|
1483
|
+
counts:
|
|
1484
|
+
errors: '{{#bold}}Errors:{{/bold}} {{ count }}'
|
|
1485
|
+
warnings: "{{#bold}}Warning:{{/bold}} {{ count }}"
|
|
1486
|
+
|
|
1487
|
+
|
|
1488
|
+
|
package/lib/DevServerManager.js
CHANGED
|
@@ -6,7 +6,7 @@ const { COMPONENT_TYPES } = require('./projectStructure');
|
|
|
6
6
|
const { i18n } = require('./lang');
|
|
7
7
|
const { promptUser } = require('./prompts/promptUtils');
|
|
8
8
|
const { DevModeInterface } = require('@hubspot/ui-extensions-dev-server');
|
|
9
|
-
const { startPortManagerServer,
|
|
9
|
+
const { startPortManagerServer, stopPortManagerServer, requestPorts, } = require('@hubspot/local-dev-lib/portManager');
|
|
10
10
|
const { getHubSpotApiOrigin, getHubSpotWebsiteOrigin, } = require('@hubspot/local-dev-lib/urls');
|
|
11
11
|
const { getAccountConfig } = require('@hubspot/local-dev-lib/config');
|
|
12
12
|
const i18nKey = 'lib.DevServerManager';
|
|
@@ -109,10 +109,7 @@ class DevServerManager {
|
|
|
109
109
|
await serverInterface.cleanup();
|
|
110
110
|
}
|
|
111
111
|
});
|
|
112
|
-
|
|
113
|
-
if (!hasActiveServers) {
|
|
114
|
-
await stopPortManagerServer();
|
|
115
|
-
}
|
|
112
|
+
await stopPortManagerServer();
|
|
116
113
|
}
|
|
117
114
|
}
|
|
118
115
|
}
|
package/lib/commonOpts.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Argv, Arguments } from 'yargs';
|
|
2
|
+
import { Mode } from '@hubspot/local-dev-lib/types/Files';
|
|
2
3
|
export declare function addAccountOptions(yargs: Argv): Argv;
|
|
3
4
|
export declare function addConfigOptions(yargs: Argv): Argv;
|
|
4
5
|
export declare function addOverwriteOptions(yargs: Argv): Argv;
|
|
@@ -22,5 +23,5 @@ export declare function getAccountId(options: Arguments<{
|
|
|
22
23
|
account?: number | string;
|
|
23
24
|
}>): number | null;
|
|
24
25
|
export declare function getMode(options: Arguments<{
|
|
25
|
-
mode?:
|
|
26
|
-
}>):
|
|
26
|
+
mode?: Mode;
|
|
27
|
+
}>): Mode;
|
package/lib/commonOpts.js
CHANGED
|
@@ -76,8 +76,8 @@ function getCommandName(argv) {
|
|
|
76
76
|
* Obtains accountId using supplied --account flag or from environment variables
|
|
77
77
|
*/
|
|
78
78
|
function getAccountId(options) {
|
|
79
|
-
const { portal, account } = options;
|
|
80
|
-
if (options
|
|
79
|
+
const { portal, account } = options || {};
|
|
80
|
+
if (options?.useEnv && process.env.HUBSPOT_PORTAL_ID) {
|
|
81
81
|
return parseInt(process.env.HUBSPOT_PORTAL_ID, 10);
|
|
82
82
|
}
|
|
83
83
|
return (0, config_1.getAccountId)(portal || account);
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isGloballyInstalled = isGloballyInstalled;
|
|
4
|
+
exports.getLatestCliVersion = getLatestCliVersion;
|
|
5
|
+
exports.hasMissingPackages = hasMissingPackages;
|
|
3
6
|
// @ts-nocheck
|
|
4
7
|
const { logger } = require('@hubspot/local-dev-lib/logger');
|
|
5
8
|
const { getProjectConfig } = require('./projects');
|
|
@@ -11,6 +14,7 @@ const util = require('util');
|
|
|
11
14
|
const { i18n } = require('./lang');
|
|
12
15
|
const SpinniesManager = require('./ui/SpinniesManager');
|
|
13
16
|
const fs = require('fs');
|
|
17
|
+
const pkg = require('../package.json');
|
|
14
18
|
const DEFAULT_PACKAGE_MANAGER = 'npm';
|
|
15
19
|
const i18nKey = `commands.project.subcommands.installDeps`;
|
|
16
20
|
class NoPackageJsonFilesError extends Error {
|
|
@@ -31,6 +35,12 @@ async function isGloballyInstalled(command) {
|
|
|
31
35
|
return false;
|
|
32
36
|
}
|
|
33
37
|
}
|
|
38
|
+
async function getLatestCliVersion() {
|
|
39
|
+
const exec = util.promisify(execAsync);
|
|
40
|
+
const { stdout } = await exec(`npm info ${pkg.name} dist-tags --json`);
|
|
41
|
+
const { latest } = JSON.parse(stdout);
|
|
42
|
+
return latest;
|
|
43
|
+
}
|
|
34
44
|
async function installPackages({ packages, installLocations }) {
|
|
35
45
|
const installDirs = installLocations || (await getProjectPackageJsonLocations());
|
|
36
46
|
await Promise.all(installDirs.map(async (dir) => {
|
|
@@ -109,9 +119,18 @@ async function getProjectPackageJsonLocations() {
|
|
|
109
119
|
});
|
|
110
120
|
return packageParentDirs;
|
|
111
121
|
}
|
|
122
|
+
async function hasMissingPackages(directory) {
|
|
123
|
+
const exec = util.promisify(execAsync);
|
|
124
|
+
const { stdout } = await exec(`npm install --ignore-scripts --dry-run`, {
|
|
125
|
+
cwd: directory,
|
|
126
|
+
});
|
|
127
|
+
return !stdout?.includes('up to date in');
|
|
128
|
+
}
|
|
112
129
|
module.exports = {
|
|
113
130
|
isGloballyInstalled,
|
|
114
131
|
installPackages,
|
|
115
132
|
DEFAULT_PACKAGE_MANAGER,
|
|
116
133
|
getProjectPackageJsonLocations,
|
|
134
|
+
getLatestCliVersion,
|
|
135
|
+
hasMissingPackages,
|
|
117
136
|
};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { DiagnosticInfo } from './DiagnosticInfoBuilder';
|
|
2
|
+
interface DiagnosisOptions {
|
|
3
|
+
diagnosticInfo: DiagnosticInfo;
|
|
4
|
+
accountId: number | null;
|
|
5
|
+
}
|
|
6
|
+
interface Section {
|
|
7
|
+
type: 'error' | 'warning' | 'success';
|
|
8
|
+
message: string;
|
|
9
|
+
secondaryMessaging?: string;
|
|
10
|
+
}
|
|
11
|
+
export declare class Diagnosis {
|
|
12
|
+
private readonly prefixes;
|
|
13
|
+
private readonly diagnosis;
|
|
14
|
+
private readonly indentation;
|
|
15
|
+
private errorCount;
|
|
16
|
+
private warningCount;
|
|
17
|
+
constructor({ diagnosticInfo, accountId }: DiagnosisOptions);
|
|
18
|
+
private indent;
|
|
19
|
+
getErrorCount(): number;
|
|
20
|
+
getWarningCount(): number;
|
|
21
|
+
addCliSection(section: Section): void;
|
|
22
|
+
addProjectSection(section: Section): void;
|
|
23
|
+
addCLIConfigSection(section: Section): void;
|
|
24
|
+
toString(): string;
|
|
25
|
+
private generateSections;
|
|
26
|
+
}
|
|
27
|
+
export {};
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Diagnosis = void 0;
|
|
4
|
+
const spinniesUtils_1 = require("../ui/spinniesUtils");
|
|
5
|
+
const chalk_1 = require("chalk");
|
|
6
|
+
const interpolation_1 = require("../interpolation");
|
|
7
|
+
const ui_1 = require("../ui");
|
|
8
|
+
const { i18n } = require('../lang');
|
|
9
|
+
const i18nKey = `lib.doctor.diagnosis`;
|
|
10
|
+
class Diagnosis {
|
|
11
|
+
prefixes;
|
|
12
|
+
diagnosis;
|
|
13
|
+
indentation = ' ';
|
|
14
|
+
errorCount = 0;
|
|
15
|
+
warningCount = 0;
|
|
16
|
+
constructor({ diagnosticInfo, accountId }) {
|
|
17
|
+
const { succeedPrefix, failPrefix } = (0, spinniesUtils_1.prefixOptions)({});
|
|
18
|
+
this.prefixes = {
|
|
19
|
+
success: (0, chalk_1.green)(succeedPrefix),
|
|
20
|
+
error: (0, chalk_1.red)(failPrefix),
|
|
21
|
+
warning: interpolation_1.helpers.orange('!'),
|
|
22
|
+
};
|
|
23
|
+
this.diagnosis = {
|
|
24
|
+
cli: {
|
|
25
|
+
header: i18n(`${i18nKey}.cli.header`),
|
|
26
|
+
sections: [],
|
|
27
|
+
},
|
|
28
|
+
cliConfig: {
|
|
29
|
+
header: i18n(`${i18nKey}.cliConfig.header`),
|
|
30
|
+
sections: [],
|
|
31
|
+
},
|
|
32
|
+
project: {
|
|
33
|
+
header: i18n(`${i18nKey}.projectConfig.header`),
|
|
34
|
+
subheaders: [
|
|
35
|
+
i18n(`${i18nKey}.projectConfig.projectDirSubHeader`, {
|
|
36
|
+
projectDir: diagnosticInfo.project?.config?.projectDir,
|
|
37
|
+
}),
|
|
38
|
+
i18n(`${i18nKey}.projectConfig.projectNameSubHeader`, {
|
|
39
|
+
projectName: diagnosticInfo.project?.config?.projectConfig?.name,
|
|
40
|
+
}),
|
|
41
|
+
],
|
|
42
|
+
sections: [],
|
|
43
|
+
},
|
|
44
|
+
};
|
|
45
|
+
if (diagnosticInfo.config) {
|
|
46
|
+
this.diagnosis.cliConfig.subheaders = [
|
|
47
|
+
i18n(`${i18nKey}.cliConfig.configFileSubHeader`, {
|
|
48
|
+
filename: diagnosticInfo.config,
|
|
49
|
+
}),
|
|
50
|
+
i18n(`${i18nKey}.cliConfig.defaultAccountSubHeader`, {
|
|
51
|
+
accountDetails: (0, ui_1.uiAccountDescription)(accountId),
|
|
52
|
+
}),
|
|
53
|
+
];
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
indent(level) {
|
|
57
|
+
return this.indentation.repeat(level);
|
|
58
|
+
}
|
|
59
|
+
getErrorCount() {
|
|
60
|
+
return this.errorCount;
|
|
61
|
+
}
|
|
62
|
+
getWarningCount() {
|
|
63
|
+
return this.warningCount;
|
|
64
|
+
}
|
|
65
|
+
addCliSection(section) {
|
|
66
|
+
this.diagnosis.cli.sections.push(section);
|
|
67
|
+
}
|
|
68
|
+
addProjectSection(section) {
|
|
69
|
+
this.diagnosis.project.sections.push(section);
|
|
70
|
+
}
|
|
71
|
+
addCLIConfigSection(section) {
|
|
72
|
+
this.diagnosis.cliConfig.sections.push(section);
|
|
73
|
+
}
|
|
74
|
+
toString() {
|
|
75
|
+
const output = [];
|
|
76
|
+
for (const value of Object.values(this.diagnosis)) {
|
|
77
|
+
const section = this.generateSections(value);
|
|
78
|
+
if (section) {
|
|
79
|
+
output.push(section);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
if (output.length === 0) {
|
|
83
|
+
return '';
|
|
84
|
+
}
|
|
85
|
+
output.push('');
|
|
86
|
+
output.push(i18n(`${i18nKey}.counts.errors`, {
|
|
87
|
+
count: this.errorCount,
|
|
88
|
+
}));
|
|
89
|
+
output.push(i18n(`${i18nKey}.counts.warnings`, {
|
|
90
|
+
count: this.warningCount,
|
|
91
|
+
}));
|
|
92
|
+
output.push('');
|
|
93
|
+
return output.join('\n');
|
|
94
|
+
}
|
|
95
|
+
generateSections(category) {
|
|
96
|
+
const output = [];
|
|
97
|
+
if (category.sections && category.sections.length === 0) {
|
|
98
|
+
return '';
|
|
99
|
+
}
|
|
100
|
+
output.push(`\n${(0, chalk_1.bold)(category.header)}`);
|
|
101
|
+
(category.subheaders || []).forEach(subheader => {
|
|
102
|
+
output.push(`${subheader}`);
|
|
103
|
+
});
|
|
104
|
+
category.sections.forEach(section => {
|
|
105
|
+
if (section.type === 'error') {
|
|
106
|
+
this.errorCount++;
|
|
107
|
+
}
|
|
108
|
+
else if (section.type === 'warning') {
|
|
109
|
+
this.warningCount++;
|
|
110
|
+
}
|
|
111
|
+
output.push(`${this.indent(1)}${this.prefixes[section.type]} ${section.message}`);
|
|
112
|
+
if (section.secondaryMessaging) {
|
|
113
|
+
output.push(`${this.indent(2)}- ${section.secondaryMessaging}`);
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
return output.join('\n');
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
exports.Diagnosis = Diagnosis;
|