@hubspot/cli 5.3.1 → 5.4.1-beta.0
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 +24 -5
- package/commands/__tests__/projects.test.js +105 -0
- package/commands/accounts/clean.js +1 -1
- package/commands/cms/convertFields.js +13 -7
- package/commands/project/__tests__/deploy.test.js +1 -1
- package/commands/project/__tests__/installDeps.test.js +168 -0
- package/commands/project/__tests__/logs.test.js +305 -0
- package/commands/project/add.js +24 -12
- package/commands/project/cloneApp.js +13 -21
- package/commands/project/deploy.js +4 -1
- package/commands/project/dev.js +22 -11
- package/commands/project/download.js +6 -3
- package/commands/project/installDeps.js +78 -0
- package/commands/project/logs.js +80 -242
- package/commands/project/migrateApp.js +8 -9
- package/commands/project/upload.js +5 -3
- package/commands/project/watch.js +3 -9
- package/commands/project.js +2 -0
- package/commands/sandbox/create.js +1 -0
- package/commands/sandbox.js +0 -2
- package/lang/en.lyaml +40 -75
- package/lib/LocalDevManager.js +1 -22
- package/lib/__tests__/dependencyManagement.test.js +245 -0
- package/lib/__tests__/projectLogsManager.test.js +210 -0
- package/lib/dependencyManagement.js +157 -0
- package/lib/errorHandlers/apiErrors.js +1 -3
- package/lib/errorHandlers/overrideErrors.js +57 -36
- package/lib/localDev.js +25 -16
- package/lib/projectLogsManager.js +144 -0
- package/lib/projects.js +17 -7
- package/lib/projectsWatch.js +2 -5
- package/lib/prompts/__tests__/projectsLogsPrompt.test.js +46 -0
- package/lib/prompts/createProjectPrompt.js +4 -0
- package/lib/prompts/projectAddPrompt.js +4 -21
- package/lib/prompts/projectDevTargetAccountPrompt.js +16 -25
- package/lib/prompts/projectsLogsPrompt.js +17 -108
- package/lib/sandboxSync.js +13 -15
- package/package.json +6 -6
- package/commands/sandbox/sync.js +0 -225
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
const { getProjectConfig, ensureProjectExists } = require('./projects');
|
|
2
|
+
const {
|
|
3
|
+
fetchProjectComponentsMetadata,
|
|
4
|
+
} = require('@hubspot/local-dev-lib/api/projects');
|
|
5
|
+
const { i18n } = require('./lang');
|
|
6
|
+
const { uiLink } = require('./ui');
|
|
7
|
+
|
|
8
|
+
const i18nKey = 'commands.project.subcommands.logs';
|
|
9
|
+
|
|
10
|
+
class ProjectLogsManager {
|
|
11
|
+
reset() {
|
|
12
|
+
Object.keys(this).forEach(key => {
|
|
13
|
+
if (Object.hasOwn(this, key)) {
|
|
14
|
+
this[key] = undefined;
|
|
15
|
+
}
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
async init(accountId) {
|
|
20
|
+
const { projectConfig } = await getProjectConfig();
|
|
21
|
+
|
|
22
|
+
if (!projectConfig || !projectConfig.name) {
|
|
23
|
+
throw new Error(i18n(`${i18nKey}.errors.noProjectConfig`));
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const { name: projectName } = projectConfig;
|
|
27
|
+
|
|
28
|
+
this.projectName = projectName;
|
|
29
|
+
this.accountId = accountId;
|
|
30
|
+
this.functions = [];
|
|
31
|
+
|
|
32
|
+
const { project } = await ensureProjectExists(
|
|
33
|
+
this.accountId,
|
|
34
|
+
this.projectName,
|
|
35
|
+
{
|
|
36
|
+
allowCreate: false,
|
|
37
|
+
}
|
|
38
|
+
);
|
|
39
|
+
|
|
40
|
+
if (
|
|
41
|
+
!project ||
|
|
42
|
+
!project.deployedBuild ||
|
|
43
|
+
!project.deployedBuild.subbuildStatuses
|
|
44
|
+
) {
|
|
45
|
+
throw new Error(i18n(`${i18nKey}.errors.failedToFetchProjectDetails`));
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
this.projectId = project.id;
|
|
49
|
+
await this.fetchFunctionDetails();
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
async fetchFunctionDetails() {
|
|
53
|
+
if (!this.projectId) {
|
|
54
|
+
throw new Error(i18n(`${i18nKey}.errors.noProjectConfig`));
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const { topLevelComponentMetadata } = await fetchProjectComponentsMetadata(
|
|
58
|
+
this.accountId,
|
|
59
|
+
this.projectId
|
|
60
|
+
);
|
|
61
|
+
|
|
62
|
+
const apps = topLevelComponentMetadata.filter(componentMetadata => {
|
|
63
|
+
const { type } = componentMetadata;
|
|
64
|
+
return type && type.name === 'PRIVATE_APP';
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
if (!this.functions) {
|
|
68
|
+
this.functions = [];
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
apps.forEach(app => {
|
|
72
|
+
this.functions.push(
|
|
73
|
+
...app.featureComponents.filter(
|
|
74
|
+
component => component.type.name === 'APP_FUNCTION'
|
|
75
|
+
)
|
|
76
|
+
);
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
if (this.functions.length === 0) {
|
|
80
|
+
throw new Error(
|
|
81
|
+
i18n(`${i18nKey}.errors.noFunctionsInProject`, {
|
|
82
|
+
link: uiLink(
|
|
83
|
+
i18n(`${i18nKey}.errors.noFunctionsLinkText`),
|
|
84
|
+
'https://developers.hubspot.com/docs/platform/serverless-functions'
|
|
85
|
+
),
|
|
86
|
+
})
|
|
87
|
+
);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
getFunctionNames() {
|
|
92
|
+
if (!this.functions) {
|
|
93
|
+
return [];
|
|
94
|
+
}
|
|
95
|
+
return this.functions.map(
|
|
96
|
+
serverlessFunction => serverlessFunction.componentName
|
|
97
|
+
);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
setFunction(functionName) {
|
|
101
|
+
if (!this.functions) {
|
|
102
|
+
throw new Error(
|
|
103
|
+
i18n(`${i18nKey}.errors.noFunctionsInProject`, {
|
|
104
|
+
link: uiLink(
|
|
105
|
+
i18n(`${i18nKey}.errors.noFunctionsLinkText`),
|
|
106
|
+
'https://developers.hubspot.com/docs/platform/serverless-functions'
|
|
107
|
+
),
|
|
108
|
+
}),
|
|
109
|
+
{
|
|
110
|
+
projectName: this.projectName,
|
|
111
|
+
}
|
|
112
|
+
);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
this.selectedFunction = this.functions.find(
|
|
116
|
+
serverlessFunction => serverlessFunction.componentName === functionName
|
|
117
|
+
);
|
|
118
|
+
|
|
119
|
+
if (!this.selectedFunction) {
|
|
120
|
+
throw new Error(
|
|
121
|
+
i18n(`${i18nKey}.errors.noFunctionWithName`, { name: functionName })
|
|
122
|
+
);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
this.functionName = functionName;
|
|
126
|
+
|
|
127
|
+
if (!this.selectedFunction.deployOutput) {
|
|
128
|
+
throw new Error(
|
|
129
|
+
i18n(`${i18nKey}.errors.functionNotDeployed`, { name: functionName })
|
|
130
|
+
);
|
|
131
|
+
}
|
|
132
|
+
this.appId = this.selectedFunction.deployOutput.appId;
|
|
133
|
+
|
|
134
|
+
if (this.selectedFunction.deployOutput.endpoint) {
|
|
135
|
+
this.endpointName = this.selectedFunction.deployOutput.endpoint.path;
|
|
136
|
+
this.method = this.selectedFunction.deployOutput.endpoint.method;
|
|
137
|
+
this.isPublicFunction = true;
|
|
138
|
+
} else {
|
|
139
|
+
this.isPublicFunction = false;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
module.exports = new ProjectLogsManager();
|
package/lib/projects.js
CHANGED
|
@@ -7,6 +7,7 @@ const findup = require('findup-sync');
|
|
|
7
7
|
const { logger } = require('@hubspot/local-dev-lib/logger');
|
|
8
8
|
const { getEnv } = require('@hubspot/local-dev-lib/config');
|
|
9
9
|
const { getHubSpotWebsiteOrigin } = require('@hubspot/local-dev-lib/urls');
|
|
10
|
+
const { fetchFileFromRepository } = require('@hubspot/local-dev-lib/github');
|
|
10
11
|
const {
|
|
11
12
|
ENVIRONMENTS,
|
|
12
13
|
} = require('@hubspot/local-dev-lib/constants/environments');
|
|
@@ -18,6 +19,8 @@ const {
|
|
|
18
19
|
PROJECT_CONFIG_FILE,
|
|
19
20
|
PROJECT_TASK_TYPES,
|
|
20
21
|
PROJECT_ERROR_TYPES,
|
|
22
|
+
HUBSPOT_PROJECT_COMPONENTS_GITHUB_PATH,
|
|
23
|
+
PROJECT_COMPONENT_TYPES,
|
|
21
24
|
} = require('./constants');
|
|
22
25
|
const {
|
|
23
26
|
createProject,
|
|
@@ -46,7 +49,6 @@ const {
|
|
|
46
49
|
logApiErrorInstance,
|
|
47
50
|
ApiErrorContext,
|
|
48
51
|
} = require('./errorHandlers/apiErrors');
|
|
49
|
-
const { HUBSPOT_PROJECT_COMPONENTS_GITHUB_PATH } = require('./constants');
|
|
50
52
|
|
|
51
53
|
const i18nKey = 'lib.projects';
|
|
52
54
|
|
|
@@ -285,10 +287,7 @@ const ensureProjectExists = async (
|
|
|
285
287
|
);
|
|
286
288
|
return { projectExists: true, project };
|
|
287
289
|
} catch (err) {
|
|
288
|
-
return logApiErrorInstance(
|
|
289
|
-
err,
|
|
290
|
-
new ApiErrorContext({ accountId, projectName })
|
|
291
|
-
);
|
|
290
|
+
return logApiErrorInstance(err, new ApiErrorContext({ accountId }));
|
|
292
291
|
}
|
|
293
292
|
} else {
|
|
294
293
|
if (!noLogs) {
|
|
@@ -310,7 +309,7 @@ const ensureProjectExists = async (
|
|
|
310
309
|
logger.error(err.message);
|
|
311
310
|
process.exit(EXIT_CODES.ERROR);
|
|
312
311
|
}
|
|
313
|
-
logApiErrorInstance(err, new ApiErrorContext({ accountId
|
|
312
|
+
logApiErrorInstance(err, new ApiErrorContext({ accountId }));
|
|
314
313
|
process.exit(EXIT_CODES.ERROR);
|
|
315
314
|
}
|
|
316
315
|
};
|
|
@@ -570,7 +569,7 @@ const handleProjectUpload = async (
|
|
|
570
569
|
buildId
|
|
571
570
|
);
|
|
572
571
|
}
|
|
573
|
-
resolve(uploadResult);
|
|
572
|
+
resolve(uploadResult || {});
|
|
574
573
|
})
|
|
575
574
|
);
|
|
576
575
|
|
|
@@ -1002,6 +1001,16 @@ const displayWarnLogs = async (
|
|
|
1002
1001
|
}
|
|
1003
1002
|
};
|
|
1004
1003
|
|
|
1004
|
+
const getProjectComponentsByVersion = async projectComponentsVersion => {
|
|
1005
|
+
const config = await fetchFileFromRepository(
|
|
1006
|
+
HUBSPOT_PROJECT_COMPONENTS_GITHUB_PATH,
|
|
1007
|
+
'config.json',
|
|
1008
|
+
projectComponentsVersion
|
|
1009
|
+
);
|
|
1010
|
+
|
|
1011
|
+
return config[PROJECT_COMPONENT_TYPES.COMPONENTS];
|
|
1012
|
+
};
|
|
1013
|
+
|
|
1005
1014
|
module.exports = {
|
|
1006
1015
|
writeProjectConfig,
|
|
1007
1016
|
getProjectConfig,
|
|
@@ -1019,4 +1028,5 @@ module.exports = {
|
|
|
1019
1028
|
logFeedbackMessage,
|
|
1020
1029
|
createProjectComponent,
|
|
1021
1030
|
displayWarnLogs,
|
|
1031
|
+
getProjectComponentsByVersion,
|
|
1022
1032
|
};
|
package/lib/projectsWatch.js
CHANGED
|
@@ -85,10 +85,7 @@ const debounceQueueBuild = (accountId, projectName, platformVersion) => {
|
|
|
85
85
|
logger.log(i18n(`${i18nKey}.logs.watchCancelledFromUi`));
|
|
86
86
|
process.exit(0);
|
|
87
87
|
} else {
|
|
88
|
-
logApiErrorInstance(
|
|
89
|
-
err,
|
|
90
|
-
new ApiErrorContext({ accountId, projectName })
|
|
91
|
-
);
|
|
88
|
+
logApiErrorInstance(err, new ApiErrorContext({ accountId }));
|
|
92
89
|
}
|
|
93
90
|
|
|
94
91
|
return;
|
|
@@ -158,7 +155,7 @@ const createNewBuild = async (accountId, projectName, platformVersion) => {
|
|
|
158
155
|
);
|
|
159
156
|
return buildId;
|
|
160
157
|
} catch (err) {
|
|
161
|
-
logApiErrorInstance(err, new ApiErrorContext({ accountId
|
|
158
|
+
logApiErrorInstance(err, new ApiErrorContext({ accountId }));
|
|
162
159
|
if (
|
|
163
160
|
isSpecifiedError(err, { subCategory: PROJECT_ERROR_TYPES.PROJECT_LOCKED })
|
|
164
161
|
) {
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
const { projectLogsPrompt } = require('../projectsLogsPrompt');
|
|
2
|
+
|
|
3
|
+
jest.mock('../promptUtils');
|
|
4
|
+
const { promptUser } = require('../promptUtils');
|
|
5
|
+
const chalk = require('chalk');
|
|
6
|
+
|
|
7
|
+
describe('prompts/projectsLogsPrompt', () => {
|
|
8
|
+
it('should return undefined functionName when functionChoices is nullable', async () => {
|
|
9
|
+
const actual = await projectLogsPrompt({ functionChoices: null });
|
|
10
|
+
expect(actual).toEqual({});
|
|
11
|
+
expect(promptUser).not.toHaveBeenCalled();
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
it('should return the functionName without prompting when there is only one functionChoice', async () => {
|
|
15
|
+
const functionChoice = 'this-is-the-only-function';
|
|
16
|
+
const { functionName } = await projectLogsPrompt({
|
|
17
|
+
functionChoices: [functionChoice],
|
|
18
|
+
});
|
|
19
|
+
expect(functionName).toEqual(functionChoice);
|
|
20
|
+
expect(promptUser).not.toHaveBeenCalled();
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
it('should prompt the user if there is more than one choice', async () => {
|
|
24
|
+
const functionChoices = ['choice 1', 'choice 2'];
|
|
25
|
+
const projectName = 'my cool project';
|
|
26
|
+
await projectLogsPrompt({
|
|
27
|
+
functionChoices,
|
|
28
|
+
projectName,
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
expect(promptUser).toHaveBeenCalledTimes(1);
|
|
32
|
+
expect(promptUser).toHaveBeenLastCalledWith(
|
|
33
|
+
expect.arrayContaining([
|
|
34
|
+
expect.objectContaining({
|
|
35
|
+
name: 'functionName',
|
|
36
|
+
type: 'list',
|
|
37
|
+
message: `[--function] Select function in ${chalk.bold(
|
|
38
|
+
projectName
|
|
39
|
+
)} project`,
|
|
40
|
+
when: expect.any(Function),
|
|
41
|
+
choices: functionChoices,
|
|
42
|
+
}),
|
|
43
|
+
])
|
|
44
|
+
);
|
|
45
|
+
});
|
|
46
|
+
});
|
|
@@ -4,6 +4,7 @@ const {
|
|
|
4
4
|
getCwd,
|
|
5
5
|
sanitizeFileName,
|
|
6
6
|
isValidPath,
|
|
7
|
+
untildify,
|
|
7
8
|
} = require('@hubspot/local-dev-lib/path');
|
|
8
9
|
const { PROJECT_COMPONENT_TYPES } = require('../../lib/constants');
|
|
9
10
|
const { promptUser } = require('./promptUtils');
|
|
@@ -100,6 +101,9 @@ const createProjectPrompt = async (
|
|
|
100
101
|
}
|
|
101
102
|
return true;
|
|
102
103
|
},
|
|
104
|
+
filter: input => {
|
|
105
|
+
return untildify(input);
|
|
106
|
+
},
|
|
103
107
|
},
|
|
104
108
|
{
|
|
105
109
|
name: 'template',
|
|
@@ -1,32 +1,15 @@
|
|
|
1
1
|
const { promptUser } = require('./promptUtils');
|
|
2
|
-
const { fetchFileFromRepository } = require('@hubspot/local-dev-lib/github');
|
|
3
2
|
const { i18n } = require('../lang');
|
|
4
|
-
const { HUBSPOT_PROJECT_COMPONENTS_GITHUB_PATH } = require('../constants');
|
|
5
|
-
const { PROJECT_COMPONENT_TYPES } = require('../constants');
|
|
6
3
|
|
|
7
4
|
const i18nKey = 'lib.prompts.projectAddPrompt';
|
|
8
5
|
|
|
9
|
-
const
|
|
10
|
-
const config = await fetchFileFromRepository(
|
|
11
|
-
HUBSPOT_PROJECT_COMPONENTS_GITHUB_PATH,
|
|
12
|
-
'config.json',
|
|
13
|
-
projectComponentsVersion
|
|
14
|
-
);
|
|
15
|
-
|
|
16
|
-
return config[PROJECT_COMPONENT_TYPES.COMPONENTS];
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
const projectAddPrompt = async (
|
|
20
|
-
projectComponentsVersion,
|
|
21
|
-
promptOptions = {}
|
|
22
|
-
) => {
|
|
23
|
-
const components = await createTypeOptions(projectComponentsVersion);
|
|
6
|
+
const projectAddPrompt = async (components, promptOptions = {}) => {
|
|
24
7
|
return promptUser([
|
|
25
8
|
{
|
|
26
|
-
name: '
|
|
9
|
+
name: 'component',
|
|
27
10
|
message: () => {
|
|
28
11
|
return promptOptions.type &&
|
|
29
|
-
!components.find(t => t.path === promptOptions.type
|
|
12
|
+
!components.find(t => t.path === promptOptions.type)
|
|
30
13
|
? i18n(`${i18nKey}.errors.invalidType`, {
|
|
31
14
|
type: promptOptions.type,
|
|
32
15
|
})
|
|
@@ -34,7 +17,7 @@ const projectAddPrompt = async (
|
|
|
34
17
|
},
|
|
35
18
|
when:
|
|
36
19
|
!promptOptions.type ||
|
|
37
|
-
!components.find(t => t.path === promptOptions.type
|
|
20
|
+
!components.find(t => t.path === promptOptions.type),
|
|
38
21
|
type: 'list',
|
|
39
22
|
choices: components.map(type => {
|
|
40
23
|
return {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
const { promptUser } = require('./promptUtils');
|
|
2
2
|
const { i18n } = require('../lang');
|
|
3
3
|
const { uiAccountDescription, uiCommandReference } = require('../ui');
|
|
4
|
-
const { isSandbox
|
|
4
|
+
const { isSandbox } = require('../accountTypes');
|
|
5
5
|
const { getAccountId } = require('@hubspot/local-dev-lib/config');
|
|
6
6
|
const { getSandboxUsageLimits } = require('@hubspot/local-dev-lib/sandboxes');
|
|
7
7
|
const {
|
|
@@ -99,7 +99,6 @@ const selectDeveloperTestTargetAccountPrompt = async (
|
|
|
99
99
|
defaultAccountConfig
|
|
100
100
|
) => {
|
|
101
101
|
const defaultAccountId = getAccountId(defaultAccountConfig.name);
|
|
102
|
-
let choices = [];
|
|
103
102
|
let devTestAccountsResponse = undefined;
|
|
104
103
|
try {
|
|
105
104
|
devTestAccountsResponse = await fetchDeveloperTestAccounts(
|
|
@@ -109,13 +108,6 @@ const selectDeveloperTestTargetAccountPrompt = async (
|
|
|
109
108
|
logger.debug('Unable to fetch developer test account usage limits: ', err);
|
|
110
109
|
}
|
|
111
110
|
|
|
112
|
-
const devTestAccounts = accounts
|
|
113
|
-
.reverse()
|
|
114
|
-
.filter(
|
|
115
|
-
config =>
|
|
116
|
-
isDeveloperTestAccount(config) &&
|
|
117
|
-
config.parentAccountId === defaultAccountId
|
|
118
|
-
);
|
|
119
111
|
let disabledMessage = false;
|
|
120
112
|
if (
|
|
121
113
|
devTestAccountsResponse &&
|
|
@@ -128,27 +120,26 @@ const selectDeveloperTestTargetAccountPrompt = async (
|
|
|
128
120
|
});
|
|
129
121
|
}
|
|
130
122
|
|
|
131
|
-
|
|
123
|
+
const devTestAccounts = [];
|
|
132
124
|
if (devTestAccountsResponse && devTestAccountsResponse.results) {
|
|
133
|
-
const
|
|
125
|
+
const accountIds = accounts.map(account => account.portalId);
|
|
126
|
+
|
|
134
127
|
devTestAccountsResponse.results.forEach(acct => {
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
}
|
|
128
|
+
const inConfig = accountIds.includes(acct.id);
|
|
129
|
+
devTestAccounts.push({
|
|
130
|
+
name: getNonConfigDeveloperTestAccountName(acct),
|
|
131
|
+
value: {
|
|
132
|
+
targetAccountId: acct.id,
|
|
133
|
+
createdNestedAccount: false,
|
|
134
|
+
parentAccountId: defaultAccountId,
|
|
135
|
+
notInConfigAccount: inConfig ? null : acct,
|
|
136
|
+
},
|
|
137
|
+
});
|
|
146
138
|
});
|
|
147
139
|
}
|
|
148
140
|
|
|
149
|
-
choices = [
|
|
150
|
-
...devTestAccounts
|
|
151
|
-
...devTestAccountsNotInConfig,
|
|
141
|
+
const choices = [
|
|
142
|
+
...devTestAccounts,
|
|
152
143
|
{
|
|
153
144
|
name: i18n(`${i18nKey}.createNewDeveloperTestAccountOption`),
|
|
154
145
|
value: {
|
|
@@ -1,120 +1,29 @@
|
|
|
1
1
|
const { i18n } = require('../lang');
|
|
2
|
-
const { fetchProject } = require('@hubspot/local-dev-lib/api/projects');
|
|
3
2
|
const { promptUser } = require('./promptUtils');
|
|
4
|
-
const { getAccountId } = require('../commonOpts');
|
|
5
|
-
const { getProjectConfig, ensureProjectExists } = require('../projects');
|
|
6
|
-
const {
|
|
7
|
-
logApiErrorInstance,
|
|
8
|
-
ApiErrorContext,
|
|
9
|
-
} = require('../../lib/errorHandlers/apiErrors');
|
|
10
|
-
const { logger } = require('@hubspot/local-dev-lib/logger');
|
|
11
|
-
const { EXIT_CODES } = require('../enums/exitCodes');
|
|
12
3
|
|
|
13
4
|
const i18nKey = 'lib.prompts.projectLogsPrompt';
|
|
14
5
|
|
|
15
|
-
const
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
}
|
|
6
|
+
const projectLogsPrompt = async ({
|
|
7
|
+
functionChoices,
|
|
8
|
+
promptOptions,
|
|
9
|
+
projectName = {},
|
|
10
|
+
}) => {
|
|
11
|
+
if (!functionChoices) {
|
|
12
|
+
return {};
|
|
13
|
+
}
|
|
14
|
+
if (functionChoices && functionChoices.length === 1) {
|
|
15
|
+
return { functionName: functionChoices[0] };
|
|
16
|
+
}
|
|
19
17
|
|
|
20
|
-
const projectLogsPrompt = (accountId, promptOptions = {}) => {
|
|
21
18
|
return promptUser([
|
|
22
|
-
{
|
|
23
|
-
name: 'projectName',
|
|
24
|
-
message: i18n(`${i18nKey}.projectName.message`),
|
|
25
|
-
when: !promptOptions.project,
|
|
26
|
-
default: async () => {
|
|
27
|
-
const { projectConfig } = await getProjectConfig();
|
|
28
|
-
return projectConfig && projectConfig.name ? projectConfig.name : null;
|
|
29
|
-
},
|
|
30
|
-
validate: name =>
|
|
31
|
-
!name.length ? i18n(`${i18nKey}.projectName.error`) : true,
|
|
32
|
-
},
|
|
33
|
-
{
|
|
34
|
-
name: 'logType',
|
|
35
|
-
type: 'list',
|
|
36
|
-
message: i18n(`${i18nKey}.logType.message`),
|
|
37
|
-
when:
|
|
38
|
-
!promptOptions.app &&
|
|
39
|
-
!promptOptions.function &&
|
|
40
|
-
!promptOptions.endpoint,
|
|
41
|
-
choices: [
|
|
42
|
-
{
|
|
43
|
-
name: i18n(`${i18nKey}.logType.function`),
|
|
44
|
-
value: SERVERLESS_FUNCTION_TYPES.APP_FUNCTION,
|
|
45
|
-
},
|
|
46
|
-
{
|
|
47
|
-
name: i18n(`${i18nKey}.logType.endpoint`),
|
|
48
|
-
value: SERVERLESS_FUNCTION_TYPES.PUBLIC_ENDPOINT,
|
|
49
|
-
},
|
|
50
|
-
],
|
|
51
|
-
},
|
|
52
|
-
{
|
|
53
|
-
name: 'appName',
|
|
54
|
-
type: 'list',
|
|
55
|
-
message: i18n(`${i18nKey}.appName`),
|
|
56
|
-
when: ({ logType }) => {
|
|
57
|
-
return (
|
|
58
|
-
(promptOptions.function ||
|
|
59
|
-
logType === SERVERLESS_FUNCTION_TYPES.APP_FUNCTION) &&
|
|
60
|
-
!promptOptions.app &&
|
|
61
|
-
!promptOptions.endpoint
|
|
62
|
-
);
|
|
63
|
-
},
|
|
64
|
-
choices: async ({ projectName }) => {
|
|
65
|
-
const name = projectName || promptOptions.project;
|
|
66
|
-
|
|
67
|
-
try {
|
|
68
|
-
await ensureProjectExists(accountId, name, {
|
|
69
|
-
allowCreate: false,
|
|
70
|
-
});
|
|
71
|
-
const { deployedBuild } = await fetchProject(accountId, name);
|
|
72
|
-
|
|
73
|
-
if (deployedBuild && deployedBuild.subbuildStatuses) {
|
|
74
|
-
return deployedBuild.subbuildStatuses
|
|
75
|
-
.filter(subbuild => subbuild.buildType === 'PRIVATE_APP')
|
|
76
|
-
.map(subbuild => ({
|
|
77
|
-
name: subbuild.buildName,
|
|
78
|
-
value: subbuild.buildName,
|
|
79
|
-
}));
|
|
80
|
-
} else {
|
|
81
|
-
logger.debug('Failed to fetch project');
|
|
82
|
-
process.exit(EXIT_CODES.ERROR);
|
|
83
|
-
}
|
|
84
|
-
} catch (e) {
|
|
85
|
-
const { projectConfig } = await getProjectConfig();
|
|
86
|
-
const projectName = projectConfig.name;
|
|
87
|
-
|
|
88
|
-
logApiErrorInstance(
|
|
89
|
-
e,
|
|
90
|
-
new ApiErrorContext({ accountId: getAccountId(), projectName })
|
|
91
|
-
);
|
|
92
|
-
process.exit(EXIT_CODES.ERROR);
|
|
93
|
-
}
|
|
94
|
-
},
|
|
95
|
-
},
|
|
96
19
|
{
|
|
97
20
|
name: 'functionName',
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
!promptOptions.endpoint
|
|
105
|
-
);
|
|
106
|
-
},
|
|
107
|
-
},
|
|
108
|
-
{
|
|
109
|
-
name: 'endpointName',
|
|
110
|
-
message: i18n(`${i18nKey}.endpointName`),
|
|
111
|
-
when: ({ logType }) => {
|
|
112
|
-
return (
|
|
113
|
-
logType === SERVERLESS_FUNCTION_TYPES.PUBLIC_ENDPOINT &&
|
|
114
|
-
!promptOptions.function &&
|
|
115
|
-
!promptOptions.endpoint
|
|
116
|
-
);
|
|
117
|
-
},
|
|
21
|
+
type: 'list',
|
|
22
|
+
message: i18n(`${i18nKey}.functionName`, { projectName }),
|
|
23
|
+
when: () =>
|
|
24
|
+
(!promptOptions || !promptOptions.function) &&
|
|
25
|
+
functionChoices.length > 0,
|
|
26
|
+
choices: functionChoices,
|
|
118
27
|
},
|
|
119
28
|
]);
|
|
120
29
|
};
|
package/lib/sandboxSync.js
CHANGED
|
@@ -4,14 +4,12 @@ const { logger } = require('@hubspot/local-dev-lib/logger');
|
|
|
4
4
|
const { i18n } = require('./lang');
|
|
5
5
|
const { getAvailableSyncTypes } = require('./sandboxes');
|
|
6
6
|
const { initiateSync } = require('@hubspot/local-dev-lib/sandboxes');
|
|
7
|
+
const { debugErrorAndContext } = require('./errorHandlers/standardErrors');
|
|
7
8
|
const {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
} = require('./errorHandlers/
|
|
11
|
-
const {
|
|
12
|
-
isSpecifiedError,
|
|
13
|
-
isMissingScopeError,
|
|
14
|
-
} = require('@hubspot/local-dev-lib/errors/apiErrors');
|
|
9
|
+
logApiErrorInstance,
|
|
10
|
+
ApiErrorContext,
|
|
11
|
+
} = require('./errorHandlers/apiErrors');
|
|
12
|
+
const { isSpecifiedError } = require('@hubspot/local-dev-lib/errors/apiErrors');
|
|
15
13
|
const { getSandboxTypeAsString } = require('./sandboxes');
|
|
16
14
|
const { getAccountId } = require('@hubspot/local-dev-lib/config');
|
|
17
15
|
const {
|
|
@@ -97,13 +95,7 @@ const syncSandbox = async ({
|
|
|
97
95
|
});
|
|
98
96
|
|
|
99
97
|
logger.log('');
|
|
100
|
-
if (
|
|
101
|
-
logger.error(
|
|
102
|
-
i18n(`${i18nKey}.failure.missingScopes`, {
|
|
103
|
-
accountName: uiAccountDescription(parentAccountId),
|
|
104
|
-
})
|
|
105
|
-
);
|
|
106
|
-
} else if (
|
|
98
|
+
if (
|
|
107
99
|
isSpecifiedError(err, {
|
|
108
100
|
statusCode: 403,
|
|
109
101
|
category: 'BANNED',
|
|
@@ -163,7 +155,13 @@ const syncSandbox = async ({
|
|
|
163
155
|
'https://app.hubspot.com/l/docs/guides/crm/project-cli-commands#developer-projects-cli-commands-beta'
|
|
164
156
|
);
|
|
165
157
|
} else {
|
|
166
|
-
|
|
158
|
+
logApiErrorInstance(
|
|
159
|
+
err,
|
|
160
|
+
new ApiErrorContext({
|
|
161
|
+
accountId: parentAccountId,
|
|
162
|
+
request: 'sandbox sync',
|
|
163
|
+
})
|
|
164
|
+
);
|
|
167
165
|
}
|
|
168
166
|
logger.log('');
|
|
169
167
|
throw err;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hubspot/cli",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.4.1-beta.0",
|
|
4
4
|
"description": "CLI for working with HubSpot",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|
|
@@ -8,10 +8,10 @@
|
|
|
8
8
|
"url": "https://github.com/HubSpot/hubspot-cms-tools"
|
|
9
9
|
},
|
|
10
10
|
"dependencies": {
|
|
11
|
-
"@hubspot/local-dev-lib": "1.
|
|
12
|
-
"@hubspot/serverless-dev-runtime": "5.
|
|
11
|
+
"@hubspot/local-dev-lib": "1.13.0",
|
|
12
|
+
"@hubspot/serverless-dev-runtime": "5.4.1-beta.0",
|
|
13
13
|
"@hubspot/theme-preview-dev-server": "0.0.7",
|
|
14
|
-
"@hubspot/ui-extensions-dev-server": "0.8.
|
|
14
|
+
"@hubspot/ui-extensions-dev-server": "0.8.33",
|
|
15
15
|
"archiver": "^5.3.0",
|
|
16
16
|
"chalk": "^4.1.2",
|
|
17
17
|
"chokidar": "^3.0.1",
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
"mock-stdin": "^1.0.0"
|
|
38
38
|
},
|
|
39
39
|
"engines": {
|
|
40
|
-
"node": ">=
|
|
40
|
+
"node": ">=18"
|
|
41
41
|
},
|
|
42
42
|
"bin": {
|
|
43
43
|
"hs": "./bin/hs",
|
|
@@ -46,5 +46,5 @@
|
|
|
46
46
|
"publishConfig": {
|
|
47
47
|
"access": "public"
|
|
48
48
|
},
|
|
49
|
-
"gitHead": "
|
|
49
|
+
"gitHead": "bce14e5b832d387f2d1166a587c57f50242a65d7"
|
|
50
50
|
}
|