@hubspot/cli 8.0.10-experimental.7 → 8.0.11-experimental.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/account/auth.js +12 -22
- package/commands/account/clean.js +5 -6
- package/commands/account/createOverride.js +7 -7
- package/commands/account/info.js +2 -1
- package/commands/account/list.js +3 -5
- package/commands/account/remove.js +2 -3
- package/commands/account/removeOverride.js +8 -10
- package/commands/account/rename.js +5 -6
- package/commands/account/use.js +8 -19
- package/commands/api.d.ts +10 -0
- package/commands/api.js +164 -0
- package/commands/app/migrate.js +8 -8
- package/commands/app/secret/add.js +6 -7
- package/commands/app/secret/delete.js +9 -10
- package/commands/app/secret/list.js +6 -7
- package/commands/app/secret/update.js +8 -9
- package/commands/auth.js +12 -12
- package/commands/cms/app/create.js +9 -5
- package/commands/cms/convertFields.js +8 -8
- package/commands/cms/delete.js +2 -3
- package/commands/cms/fetch.js +7 -7
- package/commands/cms/function/create.js +9 -5
- package/commands/cms/function/deploy.js +2 -3
- package/commands/cms/function/list.js +11 -7
- package/commands/cms/function/logs.js +17 -23
- package/commands/cms/function/server.js +2 -3
- package/commands/cms/getReactModule.js +7 -8
- package/commands/cms/lighthouseScore.js +25 -24
- package/commands/cms/lint.js +4 -5
- package/commands/cms/list.js +5 -6
- package/commands/cms/module/create.js +9 -5
- package/commands/cms/module/marketplace-validate.js +7 -8
- package/commands/cms/mv.js +2 -3
- package/commands/cms/template/create.js +10 -6
- package/commands/cms/theme/create.js +5 -5
- package/commands/cms/theme/generate-selectors.js +5 -4
- package/commands/cms/theme/marketplace-validate.js +8 -9
- package/commands/cms/theme/preview.js +16 -8
- package/commands/cms/upload.js +15 -12
- package/commands/cms/watch.js +5 -5
- package/commands/cms/webpack/create.js +5 -5
- package/commands/completion.js +3 -5
- package/commands/config/migrate.js +6 -7
- package/commands/config/set.js +5 -6
- package/commands/customObject/create.js +4 -5
- package/commands/customObject/createSchema.js +4 -5
- package/commands/customObject/deleteSchema.js +4 -5
- package/commands/customObject/fetchAllSchemas.js +2 -3
- package/commands/customObject/fetchSchema.js +2 -3
- package/commands/customObject/listSchemas.js +2 -3
- package/commands/customObject/updateSchema.js +4 -5
- package/commands/doctor.js +8 -8
- package/commands/feedback.js +6 -4
- package/commands/filemanager/fetch.js +5 -6
- package/commands/filemanager/upload.js +5 -5
- package/commands/getStarted.js +14 -16
- package/commands/hubdb/clear.js +5 -6
- package/commands/hubdb/create.js +4 -5
- package/commands/hubdb/delete.js +8 -9
- package/commands/hubdb/fetch.js +5 -6
- package/commands/hubdb/list.js +16 -14
- package/commands/init.js +14 -17
- package/commands/mcp/setup.js +5 -6
- package/commands/mcp/start.js +2 -3
- package/commands/open.js +4 -5
- package/commands/project/add.js +10 -5
- package/commands/project/create.js +10 -10
- package/commands/project/delete.d.ts +7 -0
- package/commands/project/delete.js +74 -0
- package/commands/project/deploy.js +36 -34
- package/commands/project/dev/deprecatedFlow.js +42 -15
- package/commands/project/dev/index.d.ts +3 -3
- package/commands/project/dev/index.js +24 -30
- package/commands/project/dev/unifiedFlow.js +37 -14
- package/commands/project/download.js +10 -11
- package/commands/project/info.d.ts +4 -0
- package/commands/project/info.js +67 -0
- package/commands/project/installDeps.js +9 -6
- package/commands/project/lint.js +11 -8
- package/commands/project/list.js +14 -14
- package/commands/project/listBuilds.js +8 -6
- package/commands/project/logs.js +5 -6
- package/commands/project/migrate.js +8 -8
- package/commands/project/open.js +5 -6
- package/commands/project/profile/add.js +12 -8
- package/commands/project/profile/delete.js +15 -11
- package/commands/project/updateDeps.js +9 -6
- package/commands/project/upload.js +31 -17
- package/commands/project/validate.js +11 -11
- package/commands/project/watch.js +20 -20
- package/commands/project.js +4 -0
- package/commands/sandbox/create.js +15 -15
- package/commands/sandbox/delete.js +13 -14
- package/commands/secret/addSecret.js +6 -7
- package/commands/secret/deleteSecret.js +5 -6
- package/commands/secret/listSecret.js +2 -3
- package/commands/secret/updateSecret.js +4 -5
- package/commands/testAccount/create.d.ts +1 -1
- package/commands/testAccount/create.js +20 -16
- package/commands/testAccount/createConfig.js +7 -8
- package/commands/testAccount/delete.js +27 -18
- package/commands/testAccount/importData.js +6 -7
- package/commands/upgrade.js +9 -10
- package/lang/en.d.ts +123 -5
- package/lang/en.js +121 -6
- package/lib/accountAuth.js +2 -2
- package/lib/buildAccount.js +3 -3
- package/lib/constants.d.ts +0 -1
- package/lib/constants.js +0 -1
- package/lib/doctor/Diagnosis.js +5 -5
- package/lib/errorHandlers/index.js +4 -3
- package/lib/errorHandlers/suppressError.js +4 -0
- package/lib/errors/PromptExitError.d.ts +4 -2
- package/lib/errors/PromptExitError.js +3 -0
- package/lib/hasFeature.js +1 -2
- package/lib/middleware/autoUpdateMiddleware.js +6 -3
- package/lib/process.d.ts +1 -1
- package/lib/process.js +10 -3
- package/lib/projects/create/v2.js +1 -2
- package/lib/projects/delete.d.ts +13 -0
- package/lib/projects/delete.js +193 -0
- package/lib/projects/localDev/AppDevModeInterface.js +11 -11
- package/lib/projects/localDev/DevServerManager_DEPRECATED.d.ts +3 -1
- package/lib/projects/localDev/DevServerManager_DEPRECATED.js +2 -2
- package/lib/projects/localDev/DevSessionManager.d.ts +6 -3
- package/lib/projects/localDev/DevSessionManager.js +31 -19
- package/lib/projects/localDev/LocalDevManager_DEPRECATED.d.ts +3 -0
- package/lib/projects/localDev/LocalDevManager_DEPRECATED.js +16 -12
- package/lib/projects/localDev/LocalDevProcess.js +6 -5
- package/lib/projects/localDev/LocalDevState.d.ts +3 -2
- package/lib/projects/localDev/LocalDevState.js +3 -1
- package/lib/projects/localDev/helpers/account.d.ts +4 -3
- package/lib/projects/localDev/helpers/account.js +16 -19
- package/lib/projects/localDev/helpers/process.d.ts +1 -1
- package/lib/projects/localDev/helpers/process.js +4 -10
- package/lib/projects/localDev/helpers/project.d.ts +4 -3
- package/lib/projects/localDev/helpers/project.js +31 -15
- package/lib/projects/projectInfo.d.ts +5 -0
- package/lib/projects/projectInfo.js +82 -0
- package/lib/projects/projectProfiles.d.ts +1 -2
- package/lib/projects/projectProfiles.js +5 -17
- package/lib/projects/upload.js +19 -0
- package/lib/projects/workspaces.d.ts +42 -0
- package/lib/projects/workspaces.js +350 -0
- package/lib/prompts/createApiSamplePrompt.js +4 -0
- package/lib/prompts/projectProfilePrompt.d.ts +2 -0
- package/lib/prompts/projectProfilePrompt.js +46 -0
- package/lib/prompts/promptUtils.js +3 -2
- package/lib/prompts/selectHubDBTablePrompt.js +2 -2
- package/lib/prompts/selectPublicAppForMigrationPrompt.js +2 -2
- package/lib/theme/cmsDevServerProcess.d.ts +2 -0
- package/lib/theme/cmsDevServerProcess.js +7 -6
- package/lib/ui/SpinniesManager.d.ts +1 -0
- package/lib/ui/SpinniesManager.js +20 -6
- package/lib/ui/spinniesUtils.d.ts +0 -1
- package/lib/ui/spinniesUtils.js +6 -16
- package/lib/usageTracking.d.ts +3 -4
- package/lib/yargs/makeYargsBuilder.d.ts +13 -0
- package/lib/yargs/makeYargsBuilder.js +33 -0
- package/lib/yargs/makeYargsHandlerWithUsageTracking.d.ts +3 -0
- package/lib/yargs/makeYargsHandlerWithUsageTracking.js +95 -0
- package/lib/yargs/strictEnforceBoolean.d.ts +1 -0
- package/lib/yargs/strictEnforceBoolean.js +13 -0
- package/lib/yargsUtils.d.ts +3 -16
- package/lib/yargsUtils.js +3 -48
- package/package.json +5 -4
- package/types/LocalDev.d.ts +5 -0
- package/types/Projects.d.ts +19 -0
- package/types/Yargs.d.ts +18 -1
package/commands/mcp/setup.js
CHANGED
|
@@ -1,20 +1,19 @@
|
|
|
1
1
|
import { EXIT_CODES } from '../../lib/enums/exitCodes.js';
|
|
2
2
|
import { makeYargsBuilder } from '../../lib/yargsUtils.js';
|
|
3
3
|
import { commands } from '../../lang/en.js';
|
|
4
|
+
import { makeYargsHandlerWithUsageTracking } from '../../lib/yargs/makeYargsHandlerWithUsageTracking.js';
|
|
4
5
|
import { addMcpServerToConfig, supportedTools } from '../../lib/mcp/setup.js';
|
|
5
|
-
import { trackCommandUsage } from '../../lib/usageTracking.js';
|
|
6
6
|
const command = ['setup'];
|
|
7
7
|
const describe = commands.mcp.setup.describe;
|
|
8
8
|
async function handler(args) {
|
|
9
|
-
const {
|
|
10
|
-
await trackCommandUsage('mcp-setup', {}, derivedAccountId);
|
|
9
|
+
const { exit } = args;
|
|
11
10
|
try {
|
|
12
11
|
await addMcpServerToConfig(args.client);
|
|
13
12
|
}
|
|
14
13
|
catch (e) {
|
|
15
|
-
|
|
14
|
+
return exit(EXIT_CODES.ERROR);
|
|
16
15
|
}
|
|
17
|
-
|
|
16
|
+
return exit(EXIT_CODES.SUCCESS);
|
|
18
17
|
}
|
|
19
18
|
function setupBuilder(yargs) {
|
|
20
19
|
yargs.option('client', {
|
|
@@ -30,7 +29,7 @@ const builder = makeYargsBuilder(setupBuilder, command, describe, {
|
|
|
30
29
|
const mcpSetupCommand = {
|
|
31
30
|
command,
|
|
32
31
|
describe,
|
|
33
|
-
handler,
|
|
32
|
+
handler: makeYargsHandlerWithUsageTracking('mcp-setup', handler),
|
|
34
33
|
builder,
|
|
35
34
|
};
|
|
36
35
|
export default mcpSetupCommand;
|
package/commands/mcp/start.js
CHANGED
|
@@ -7,14 +7,13 @@ import { uiLogger } from '../../lib/ui/logger.js';
|
|
|
7
7
|
import { logError } from '../../lib/errorHandlers/index.js';
|
|
8
8
|
import { commands } from '../../lang/en.js';
|
|
9
9
|
import { handleExit } from '../../lib/process.js';
|
|
10
|
-
import {
|
|
10
|
+
import { makeYargsHandlerWithUsageTracking } from '../../lib/yargs/makeYargsHandlerWithUsageTracking.js';
|
|
11
11
|
import { fileURLToPath } from 'url';
|
|
12
12
|
const command = 'start';
|
|
13
13
|
const describe = undefined; // Leave hidden for now
|
|
14
14
|
const __filename = fileURLToPath(import.meta.url);
|
|
15
15
|
const __dirname = path.dirname(__filename);
|
|
16
16
|
async function handler(args) {
|
|
17
|
-
trackCommandUsage('mcp-start', {}, args.derivedAccountId);
|
|
18
17
|
await startMcpServer(args.aiAgent);
|
|
19
18
|
}
|
|
20
19
|
async function startMcpServer(aiAgent) {
|
|
@@ -66,7 +65,7 @@ const builder = makeYargsBuilder(startBuilder, command, describe, {
|
|
|
66
65
|
const mcpStartCommand = {
|
|
67
66
|
command,
|
|
68
67
|
describe,
|
|
69
|
-
handler,
|
|
68
|
+
handler: makeYargsHandlerWithUsageTracking('mcp-start', handler),
|
|
70
69
|
builder,
|
|
71
70
|
};
|
|
72
71
|
export default mcpStartCommand;
|
package/commands/open.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { trackCommandUsage } from '../lib/usageTracking.js';
|
|
2
1
|
import { logSiteLinks, getSiteLinksAsArray, openLink } from '../lib/links.js';
|
|
3
2
|
import { promptUser } from '../lib/prompts/promptUtils.js';
|
|
4
3
|
import { commands } from '../lang/en.js';
|
|
5
4
|
import { EXIT_CODES } from '../lib/enums/exitCodes.js';
|
|
5
|
+
import { makeYargsHandlerWithUsageTracking } from '../lib/yargs/makeYargsHandlerWithUsageTracking.js';
|
|
6
6
|
import { makeYargsBuilder } from '../lib/yargsUtils.js';
|
|
7
7
|
const separator = ' => ';
|
|
8
8
|
async function createListPrompt(accountId) {
|
|
@@ -22,8 +22,7 @@ async function createListPrompt(accountId) {
|
|
|
22
22
|
const command = 'open [shortcut]';
|
|
23
23
|
const describe = commands.open.describe;
|
|
24
24
|
async function handler(args) {
|
|
25
|
-
const { shortcut, list, derivedAccountId } = args;
|
|
26
|
-
trackCommandUsage('open', undefined, derivedAccountId);
|
|
25
|
+
const { shortcut, list, derivedAccountId, exit } = args;
|
|
27
26
|
if (shortcut === undefined && !list) {
|
|
28
27
|
const { open } = await createListPrompt(derivedAccountId);
|
|
29
28
|
openLink(derivedAccountId, open);
|
|
@@ -34,7 +33,7 @@ async function handler(args) {
|
|
|
34
33
|
else if (shortcut) {
|
|
35
34
|
openLink(derivedAccountId, shortcut);
|
|
36
35
|
}
|
|
37
|
-
|
|
36
|
+
return exit(EXIT_CODES.SUCCESS);
|
|
38
37
|
}
|
|
39
38
|
function openBuilder(yargs) {
|
|
40
39
|
yargs.positional('[shortcut]', {
|
|
@@ -64,7 +63,7 @@ const builder = makeYargsBuilder(openBuilder, command, describe, {
|
|
|
64
63
|
const openCommand = {
|
|
65
64
|
command,
|
|
66
65
|
describe,
|
|
67
|
-
handler,
|
|
66
|
+
handler: makeYargsHandlerWithUsageTracking('open', handler),
|
|
68
67
|
builder,
|
|
69
68
|
};
|
|
70
69
|
export default openCommand;
|
package/commands/project/add.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { logError } from '../../lib/errorHandlers/index.js';
|
|
2
2
|
import { getProjectConfig } from '../../lib/projects/config.js';
|
|
3
3
|
import { EXIT_CODES } from '../../lib/enums/exitCodes.js';
|
|
4
|
+
import { isPromptExitError } from '../../lib/errors/PromptExitError.js';
|
|
5
|
+
import { makeYargsHandlerWithUsageTracking } from '../../lib/yargs/makeYargsHandlerWithUsageTracking.js';
|
|
4
6
|
import { makeYargsBuilder } from '../../lib/yargsUtils.js';
|
|
5
7
|
import { commands } from '../../lang/en.js';
|
|
6
8
|
import { isV2Project } from '../../lib/projects/platformVersion.js';
|
|
@@ -11,12 +13,12 @@ import { uiLogger } from '../../lib/ui/logger.js';
|
|
|
11
13
|
const command = 'add';
|
|
12
14
|
const describe = commands.project.add.describe;
|
|
13
15
|
async function handler(args) {
|
|
16
|
+
const { derivedAccountId, exit } = args;
|
|
14
17
|
try {
|
|
15
|
-
const { derivedAccountId } = args;
|
|
16
18
|
const { projectConfig, projectDir } = await getProjectConfig();
|
|
17
19
|
if (!projectDir || !projectConfig) {
|
|
18
20
|
uiLogger.error(commands.project.add.error.locationInProject);
|
|
19
|
-
|
|
21
|
+
return exit(EXIT_CODES.ERROR);
|
|
20
22
|
}
|
|
21
23
|
const isV2ProjectCreate = isV2Project(projectConfig.platformVersion);
|
|
22
24
|
if (isV2ProjectCreate) {
|
|
@@ -27,10 +29,13 @@ async function handler(args) {
|
|
|
27
29
|
}
|
|
28
30
|
}
|
|
29
31
|
catch (e) {
|
|
32
|
+
if (isPromptExitError(e)) {
|
|
33
|
+
throw e;
|
|
34
|
+
}
|
|
30
35
|
logError(e);
|
|
31
|
-
|
|
36
|
+
return exit(EXIT_CODES.ERROR);
|
|
32
37
|
}
|
|
33
|
-
|
|
38
|
+
return exit(EXIT_CODES.SUCCESS);
|
|
34
39
|
}
|
|
35
40
|
function projectAddBuilder(yargs) {
|
|
36
41
|
yargs.options({
|
|
@@ -73,7 +78,7 @@ const builder = makeYargsBuilder(projectAddBuilder, command, describe, {
|
|
|
73
78
|
const projectAddCommand = {
|
|
74
79
|
command,
|
|
75
80
|
describe,
|
|
76
|
-
handler,
|
|
81
|
+
handler: makeYargsHandlerWithUsageTracking('project-add', handler),
|
|
77
82
|
builder,
|
|
78
83
|
};
|
|
79
84
|
export default projectAddCommand;
|
|
@@ -2,7 +2,6 @@ import path from 'path';
|
|
|
2
2
|
import fs from 'fs-extra';
|
|
3
3
|
import { cloneGithubRepo } from '@hubspot/local-dev-lib/github';
|
|
4
4
|
import { getCwd } from '@hubspot/local-dev-lib/path';
|
|
5
|
-
import { trackCommandUsage } from '../../lib/usageTracking.js';
|
|
6
5
|
import { writeProjectConfig, getProjectConfig, } from '../../lib/projects/config.js';
|
|
7
6
|
import { EMPTY_PROJECT_TEMPLATE_NAME } from '../../lib/projects/create/legacy.js';
|
|
8
7
|
import { generateComponentPaths } from '../../lib/projects/create/v2.js';
|
|
@@ -10,6 +9,7 @@ import { PROJECT_WITH_APP, EMPTY_PROJECT } from '../../lib/constants.js';
|
|
|
10
9
|
import { debugError, logError } from '../../lib/errorHandlers/index.js';
|
|
11
10
|
import { EXIT_CODES } from '../../lib/enums/exitCodes.js';
|
|
12
11
|
import { PROJECT_CONFIG_FILE, HUBSPOT_PROJECT_COMPONENTS_GITHUB_PATH, marketplaceDistribution, privateDistribution, oAuth, staticAuth, DEFAULT_PROJECT_TEMPLATE_BRANCH, } from '../../lib/constants.js';
|
|
12
|
+
import { makeYargsHandlerWithUsageTracking } from '../../lib/yargs/makeYargsHandlerWithUsageTracking.js';
|
|
13
13
|
import { makeYargsBuilder } from '../../lib/yargsUtils.js';
|
|
14
14
|
import { PLATFORM_VERSIONS } from '@hubspot/local-dev-lib/constants/projects';
|
|
15
15
|
import { commands } from '../../lang/en.js';
|
|
@@ -22,10 +22,10 @@ const command = ['create', 'init'];
|
|
|
22
22
|
const describe = commands.project.create.describe;
|
|
23
23
|
const { v2025_1, v2025_2, v2026_03_beta, v2026_03 } = PLATFORM_VERSIONS;
|
|
24
24
|
async function handler(args) {
|
|
25
|
-
const {
|
|
25
|
+
const { platformVersion, templateSource, exit, addUsageMetadata } = args;
|
|
26
26
|
if (templateSource && !templateSource.includes('/')) {
|
|
27
27
|
uiLogger.error(commands.project.create.errors.invalidTemplateSource);
|
|
28
|
-
|
|
28
|
+
return exit(EXIT_CODES.ERROR);
|
|
29
29
|
}
|
|
30
30
|
const repo = templateSource || HUBSPOT_PROJECT_COMPONENTS_GITHUB_PATH;
|
|
31
31
|
let handleResult;
|
|
@@ -34,16 +34,16 @@ async function handler(args) {
|
|
|
34
34
|
}
|
|
35
35
|
catch (error) {
|
|
36
36
|
logError(error);
|
|
37
|
-
|
|
37
|
+
return exit(EXIT_CODES.ERROR);
|
|
38
38
|
}
|
|
39
39
|
const { authType, distribution, repoConfig, projectContents, selectProjectTemplatePromptResponse, projectNameAndDestPromptResponse, } = handleResult;
|
|
40
|
-
|
|
40
|
+
addUsageMetadata({
|
|
41
41
|
type: selectProjectTemplatePromptResponse.projectTemplate?.name ||
|
|
42
42
|
(selectProjectTemplatePromptResponse.componentTemplates || [])
|
|
43
43
|
// @ts-expect-error
|
|
44
44
|
.map((item) => item.type)
|
|
45
45
|
.join(','),
|
|
46
|
-
}
|
|
46
|
+
});
|
|
47
47
|
const projectDest = path.resolve(getCwd(), projectNameAndDestPromptResponse.dest);
|
|
48
48
|
const { projectConfig: existingProjectConfig, projectDir: existingProjectDir, } = await getProjectConfig(projectDest);
|
|
49
49
|
// Exit if the target destination is within an existing project
|
|
@@ -51,7 +51,7 @@ async function handler(args) {
|
|
|
51
51
|
existingProjectDir &&
|
|
52
52
|
projectDest.startsWith(existingProjectDir)) {
|
|
53
53
|
uiLogger.error(commands.project.create.errors.cannotNestProjects(existingProjectDir));
|
|
54
|
-
|
|
54
|
+
return exit(EXIT_CODES.ERROR);
|
|
55
55
|
}
|
|
56
56
|
const components = generateComponentPaths({
|
|
57
57
|
selectProjectTemplatePromptResponse,
|
|
@@ -79,7 +79,7 @@ async function handler(args) {
|
|
|
79
79
|
});
|
|
80
80
|
debugError(err);
|
|
81
81
|
uiLogger.error(commands.project.create.errors.failedToDownloadProject);
|
|
82
|
-
|
|
82
|
+
return exit(EXIT_CODES.ERROR);
|
|
83
83
|
}
|
|
84
84
|
const projectConfigPath = path.join(projectDest, PROJECT_CONFIG_FILE);
|
|
85
85
|
const parsedConfigFile = JSON.parse(fs.readFileSync(projectConfigPath).toString());
|
|
@@ -102,7 +102,7 @@ async function handler(args) {
|
|
|
102
102
|
if (isProjectEmpty) {
|
|
103
103
|
fs.ensureDirSync(path.join(projectDest, 'src'));
|
|
104
104
|
}
|
|
105
|
-
|
|
105
|
+
return exit(EXIT_CODES.SUCCESS);
|
|
106
106
|
}
|
|
107
107
|
function projectCreateBuilder(yargs) {
|
|
108
108
|
yargs.options({
|
|
@@ -169,7 +169,7 @@ const builder = makeYargsBuilder(projectCreateBuilder, command, describe, {
|
|
|
169
169
|
const projectCreateCommand = {
|
|
170
170
|
command,
|
|
171
171
|
describe,
|
|
172
|
-
handler,
|
|
172
|
+
handler: makeYargsHandlerWithUsageTracking('project-create', handler),
|
|
173
173
|
builder,
|
|
174
174
|
};
|
|
175
175
|
export default projectCreateCommand;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { AccountArgs, CommonArgs, ConfigArgs, YargsCommandModule } from '../../types/Yargs.js';
|
|
2
|
+
export type ProjectDeleteArgs = CommonArgs & ConfigArgs & AccountArgs & {
|
|
3
|
+
projectName?: string;
|
|
4
|
+
force: boolean;
|
|
5
|
+
};
|
|
6
|
+
declare const projectDeleteCommand: YargsCommandModule<unknown, ProjectDeleteArgs>;
|
|
7
|
+
export default projectDeleteCommand;
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { makeYargsBuilder } from '../../lib/yargsUtils.js';
|
|
2
|
+
import { makeYargsHandlerWithUsageTracking } from '../../lib/yargs/makeYargsHandlerWithUsageTracking.js';
|
|
3
|
+
import { logError } from '../../lib/errorHandlers/index.js';
|
|
4
|
+
import { EXIT_CODES } from '../../lib/enums/exitCodes.js';
|
|
5
|
+
import { renderInline } from '../../ui/render.js';
|
|
6
|
+
import { getWarningBox } from '../../ui/components/StatusMessageBoxes.js';
|
|
7
|
+
import { commands } from '../../lang/en.js';
|
|
8
|
+
import { isV2Project } from '../../lib/projects/platformVersion.js';
|
|
9
|
+
import { isPromptExitError } from '../../lib/errors/PromptExitError.js';
|
|
10
|
+
import { resolveProjectName, checkDeployedComponents, deleteDeployedComponents, confirmDeletion, handleProjectDeletion, } from '../../lib/projects/delete.js';
|
|
11
|
+
const command = 'delete';
|
|
12
|
+
const describe = commands.project.delete.describe;
|
|
13
|
+
const verboseDescribe = commands.project.delete.verboseDescribe;
|
|
14
|
+
async function handler(args) {
|
|
15
|
+
const { derivedAccountId, projectName: projectNameArg, force, exit } = args;
|
|
16
|
+
await renderInline(getWarningBox({
|
|
17
|
+
title: commands.project.delete.warnings.irreversibleTitle,
|
|
18
|
+
message: commands.project.delete.warnings.irreversible,
|
|
19
|
+
}));
|
|
20
|
+
try {
|
|
21
|
+
const projectName = await resolveProjectName(derivedAccountId, projectNameArg);
|
|
22
|
+
const { platformVersion, hasUnifiedComponents, projectId } = await checkDeployedComponents(derivedAccountId, projectName);
|
|
23
|
+
if (!force) {
|
|
24
|
+
await confirmDeletion(projectName, derivedAccountId, projectId);
|
|
25
|
+
}
|
|
26
|
+
if (isV2Project(platformVersion) && hasUnifiedComponents) {
|
|
27
|
+
await deleteDeployedComponents(derivedAccountId, projectName);
|
|
28
|
+
}
|
|
29
|
+
await handleProjectDeletion(derivedAccountId, projectName);
|
|
30
|
+
}
|
|
31
|
+
catch (e) {
|
|
32
|
+
if (isPromptExitError(e)) {
|
|
33
|
+
throw e;
|
|
34
|
+
}
|
|
35
|
+
logError(e);
|
|
36
|
+
return exit(EXIT_CODES.ERROR);
|
|
37
|
+
}
|
|
38
|
+
return exit(EXIT_CODES.SUCCESS);
|
|
39
|
+
}
|
|
40
|
+
function projectDeleteBuilder(yargs) {
|
|
41
|
+
yargs.option('project-name', {
|
|
42
|
+
describe: commands.project.delete.options.project,
|
|
43
|
+
type: 'string',
|
|
44
|
+
});
|
|
45
|
+
yargs.option('force', {
|
|
46
|
+
describe: commands.project.delete.options.force,
|
|
47
|
+
type: 'boolean',
|
|
48
|
+
default: false,
|
|
49
|
+
});
|
|
50
|
+
yargs.example([
|
|
51
|
+
[
|
|
52
|
+
'$0 project delete --project-name=my-project',
|
|
53
|
+
'Delete a project in the current account named "my-project"',
|
|
54
|
+
],
|
|
55
|
+
[
|
|
56
|
+
'$0 project delete --project-name=my-project --force',
|
|
57
|
+
'Delete and skip confirmation prompt',
|
|
58
|
+
],
|
|
59
|
+
]);
|
|
60
|
+
return yargs;
|
|
61
|
+
}
|
|
62
|
+
const builder = makeYargsBuilder(projectDeleteBuilder, command, verboseDescribe, {
|
|
63
|
+
useGlobalOptions: true,
|
|
64
|
+
useConfigOptions: true,
|
|
65
|
+
useAccountOptions: true,
|
|
66
|
+
useEnvironmentOptions: true,
|
|
67
|
+
});
|
|
68
|
+
const projectDeleteCommand = {
|
|
69
|
+
command,
|
|
70
|
+
describe,
|
|
71
|
+
handler: makeYargsHandlerWithUsageTracking('project-delete', handler),
|
|
72
|
+
builder,
|
|
73
|
+
};
|
|
74
|
+
export default projectDeleteCommand;
|
|
@@ -2,56 +2,58 @@ import { fetchProject } from '@hubspot/local-dev-lib/api/projects';
|
|
|
2
2
|
import { getConfigAccountById } from '@hubspot/local-dev-lib/config';
|
|
3
3
|
import { isHubSpotHttpError } from '@hubspot/local-dev-lib/errors/index';
|
|
4
4
|
import { isV2Project } from '../../lib/projects/platformVersion.js';
|
|
5
|
-
import { trackCommandUsage } from '../../lib/usageTracking.js';
|
|
6
5
|
import { logError, ApiErrorContext } from '../../lib/errorHandlers/index.js';
|
|
7
|
-
import { getProjectConfig } from '../../lib/projects/config.js';
|
|
6
|
+
import { getProjectConfig, validateProjectConfig, } from '../../lib/projects/config.js';
|
|
8
7
|
import { projectNamePrompt } from '../../lib/prompts/projectNamePrompt.js';
|
|
8
|
+
import { projectProfilePrompt } from '../../lib/prompts/projectProfilePrompt.js';
|
|
9
9
|
import { promptUser } from '../../lib/prompts/promptUtils.js';
|
|
10
10
|
import { EXIT_CODES } from '../../lib/enums/exitCodes.js';
|
|
11
11
|
import { uiLogger } from '../../lib/ui/logger.js';
|
|
12
|
+
import { makeYargsHandlerWithUsageTracking } from '../../lib/yargs/makeYargsHandlerWithUsageTracking.js';
|
|
12
13
|
import { makeYargsBuilder } from '../../lib/yargsUtils.js';
|
|
13
|
-
import { loadProfile
|
|
14
|
+
import { loadProfile } from '../../lib/projects/projectProfiles.js';
|
|
14
15
|
import { PROJECT_DEPLOY_TEXT } from '../../lib/constants.js';
|
|
15
16
|
import { commands } from '../../lang/en.js';
|
|
16
17
|
import { handleProjectDeploy, validateBuildIdForDeploy, logDeployErrors, } from '../../lib/projects/deploy.js';
|
|
17
18
|
const command = 'deploy';
|
|
18
19
|
const describe = commands.project.deploy.describe;
|
|
19
20
|
async function handler(args) {
|
|
20
|
-
const { derivedAccountId, project: projectOption, buildId: buildIdOption, force: forceOption, deployLatestBuild: deployLatestBuildOption, json: formatOutputAsJson, } = args;
|
|
21
|
+
const { derivedAccountId, project: projectOption, buildId: buildIdOption, force: forceOption, deployLatestBuild: deployLatestBuildOption, json: formatOutputAsJson, profile: profileOption, useEnv: useEnvOption, exit, addUsageMetadata, } = args;
|
|
21
22
|
const accountConfig = getConfigAccountById(derivedAccountId);
|
|
22
23
|
const accountType = accountConfig && accountConfig.accountType;
|
|
23
24
|
let targetAccountId;
|
|
24
25
|
const jsonOutput = {};
|
|
25
26
|
const { projectConfig, projectDir } = await getProjectConfig();
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
27
|
+
let isInProjectDirectory = false;
|
|
28
|
+
// Validate project config, but it's valid to run this command from outside a project dir
|
|
29
|
+
try {
|
|
30
|
+
validateProjectConfig(projectConfig, projectDir);
|
|
31
|
+
isInProjectDirectory = true;
|
|
32
|
+
}
|
|
33
|
+
catch (e) { }
|
|
34
|
+
if (isInProjectDirectory && isV2Project(projectConfig?.platformVersion)) {
|
|
35
|
+
try {
|
|
36
|
+
const profileName = await projectProfilePrompt(projectDir, projectConfig, profileOption, !!useEnvOption);
|
|
37
|
+
if (profileName) {
|
|
38
|
+
// Use loadProfile instead of loadAndValidateProfile because the local
|
|
39
|
+
// profile does not need to be valid to successfully deploy
|
|
40
|
+
const profile = loadProfile(projectConfig, projectDir, profileName);
|
|
41
|
+
targetAccountId = profile.accountId;
|
|
42
|
+
uiLogger.log(commands.project.deploy.profileMessage(profileName, targetAccountId));
|
|
43
|
+
uiLogger.log('');
|
|
36
44
|
}
|
|
37
|
-
targetAccountId = profile.accountId;
|
|
38
|
-
logProfileFooter(profile);
|
|
39
45
|
}
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
await enforceProfileUsage(projectConfig, projectDir);
|
|
44
|
-
}
|
|
45
|
-
catch (error) {
|
|
46
|
-
logError(error);
|
|
47
|
-
process.exit(EXIT_CODES.ERROR);
|
|
48
|
-
}
|
|
46
|
+
catch (error) {
|
|
47
|
+
logError(error);
|
|
48
|
+
return exit(EXIT_CODES.ERROR);
|
|
49
49
|
}
|
|
50
50
|
}
|
|
51
51
|
if (!targetAccountId) {
|
|
52
52
|
targetAccountId = derivedAccountId;
|
|
53
53
|
}
|
|
54
|
-
|
|
54
|
+
if (accountType) {
|
|
55
|
+
addUsageMetadata({ type: accountType });
|
|
56
|
+
}
|
|
55
57
|
let projectName = projectOption;
|
|
56
58
|
if (!projectOption && projectConfig) {
|
|
57
59
|
projectName = projectConfig.name;
|
|
@@ -66,13 +68,13 @@ async function handler(args) {
|
|
|
66
68
|
const { data: { latestBuild, deployedBuildId }, } = await fetchProject(targetAccountId, projectName);
|
|
67
69
|
if (!latestBuild || !latestBuild.buildId) {
|
|
68
70
|
uiLogger.error(commands.project.deploy.errors.noBuilds);
|
|
69
|
-
return
|
|
71
|
+
return exit(EXIT_CODES.ERROR);
|
|
70
72
|
}
|
|
71
73
|
if (buildIdToDeploy) {
|
|
72
74
|
const validationResult = validateBuildIdForDeploy(buildIdToDeploy, deployedBuildId, latestBuild.buildId, projectName, targetAccountId);
|
|
73
75
|
if (validationResult !== true) {
|
|
74
76
|
uiLogger.error(validationResult.toString());
|
|
75
|
-
return
|
|
77
|
+
return exit(EXIT_CODES.ERROR);
|
|
76
78
|
}
|
|
77
79
|
}
|
|
78
80
|
else {
|
|
@@ -93,11 +95,11 @@ async function handler(args) {
|
|
|
93
95
|
}
|
|
94
96
|
if (!buildIdToDeploy) {
|
|
95
97
|
uiLogger.error(commands.project.deploy.errors.noBuildId);
|
|
96
|
-
return
|
|
98
|
+
return exit(EXIT_CODES.ERROR);
|
|
97
99
|
}
|
|
98
100
|
const deployResult = await handleProjectDeploy(targetAccountId, projectName, buildIdToDeploy, isV2Project(projectConfig?.platformVersion), forceOption);
|
|
99
101
|
if (!deployResult) {
|
|
100
|
-
return
|
|
102
|
+
return exit(EXIT_CODES.ERROR);
|
|
101
103
|
}
|
|
102
104
|
else if (formatOutputAsJson) {
|
|
103
105
|
jsonOutput.deployId = deployResult.deployId;
|
|
@@ -124,16 +126,16 @@ async function handler(args) {
|
|
|
124
126
|
request: 'project deploy',
|
|
125
127
|
}));
|
|
126
128
|
}
|
|
127
|
-
return
|
|
129
|
+
return exit(EXIT_CODES.ERROR);
|
|
128
130
|
}
|
|
129
131
|
if (formatOutputAsJson) {
|
|
130
132
|
uiLogger.json(jsonOutput);
|
|
131
133
|
}
|
|
132
134
|
if (deploySuccess) {
|
|
133
|
-
|
|
135
|
+
return exit(EXIT_CODES.SUCCESS);
|
|
134
136
|
}
|
|
135
137
|
else {
|
|
136
|
-
|
|
138
|
+
return exit(EXIT_CODES.ERROR);
|
|
137
139
|
}
|
|
138
140
|
}
|
|
139
141
|
function projectDeployBuilder(yargs) {
|
|
@@ -191,6 +193,6 @@ const projectDeployCommand = {
|
|
|
191
193
|
command,
|
|
192
194
|
describe,
|
|
193
195
|
builder,
|
|
194
|
-
handler,
|
|
196
|
+
handler: makeYargsHandlerWithUsageTracking('project-deploy', handler),
|
|
195
197
|
};
|
|
196
198
|
export default projectDeployCommand;
|
|
@@ -8,10 +8,11 @@ import LocalDevManager_DEPRECATED from '../../../lib/projects/localDev/LocalDevM
|
|
|
8
8
|
import { confirmDefaultAccountIsTarget, suggestRecommendedNestedAccount, checkIfAccountFlagIsSupported, checkIfDefaultAccountIsSupported, createSandboxForLocalDev, createDeveloperTestAccountForLocalDev, useExistingDevTestAccount, checkIfParentAccountIsAuthed, hasSandboxes, } from '../../../lib/projects/localDev/helpers/account.js';
|
|
9
9
|
import { createInitialBuildForNewProject, createNewProjectForLocalDev, } from '../../../lib/projects/localDev/helpers/project.js';
|
|
10
10
|
import { handleExit } from '../../../lib/process.js';
|
|
11
|
+
import { getErrorMessage } from '../../../lib/errorHandlers/index.js';
|
|
11
12
|
import { isSandbox, isDeveloperTestAccount, } from '../../../lib/accountTypes.js';
|
|
12
13
|
import { ensureProjectExists } from '../../../lib/projects/ensureProjectExists.js';
|
|
13
14
|
export async function deprecatedProjectDevFlow({ args, accountId, projectConfig, projectDir, }) {
|
|
14
|
-
const { userProvidedAccount, derivedAccountId } = args;
|
|
15
|
+
const { userProvidedAccount, derivedAccountId, exit } = args;
|
|
15
16
|
const env = getConfigAccountEnvironment(derivedAccountId);
|
|
16
17
|
const components = await findProjectComponents(projectDir);
|
|
17
18
|
const runnableComponents = components.filter(component => component.runnable);
|
|
@@ -21,20 +22,20 @@ export async function deprecatedProjectDevFlow({ args, accountId, projectConfig,
|
|
|
21
22
|
const accountConfig = getConfigAccountById(accountId);
|
|
22
23
|
if (!accountConfig) {
|
|
23
24
|
uiLogger.error(commands.project.dev.errors.noAccount(accountId));
|
|
24
|
-
|
|
25
|
+
return exit(EXIT_CODES.ERROR);
|
|
25
26
|
}
|
|
26
27
|
if (runnableComponents.length === 0) {
|
|
27
28
|
uiLogger.error(commands.project.dev.errors.noRunnableComponents);
|
|
28
|
-
|
|
29
|
+
return exit(EXIT_CODES.SUCCESS);
|
|
29
30
|
}
|
|
30
31
|
else if (hasPrivateApps && hasPublicApps) {
|
|
31
32
|
uiLogger.error(commands.project.dev.errors.invalidProjectComponents);
|
|
32
|
-
|
|
33
|
+
return exit(EXIT_CODES.SUCCESS);
|
|
33
34
|
}
|
|
34
35
|
const accounts = getAllConfigAccounts();
|
|
35
36
|
if (!accounts) {
|
|
36
37
|
uiLogger.error(commands.project.dev.errors.noAccountsInConfig);
|
|
37
|
-
|
|
38
|
+
return exit(EXIT_CODES.ERROR);
|
|
38
39
|
}
|
|
39
40
|
let bypassRecommendedAccountPrompt = false;
|
|
40
41
|
if (isDeveloperTestAccount(accountConfig)) {
|
|
@@ -54,20 +55,32 @@ export async function deprecatedProjectDevFlow({ args, accountId, projectConfig,
|
|
|
54
55
|
let targetTestingAccountId = userProvidedAccount ? derivedAccountId : null;
|
|
55
56
|
// Check that the default account or flag option is valid for the type of app in this project
|
|
56
57
|
if (userProvidedAccount) {
|
|
57
|
-
|
|
58
|
+
try {
|
|
59
|
+
checkIfAccountFlagIsSupported(accountConfig, hasPublicApps);
|
|
60
|
+
}
|
|
61
|
+
catch (e) {
|
|
62
|
+
uiLogger.error(getErrorMessage(e));
|
|
63
|
+
return exit(EXIT_CODES.SUCCESS);
|
|
64
|
+
}
|
|
58
65
|
if (hasPublicApps) {
|
|
59
66
|
targetProjectAccountId = accountConfig.parentAccountId || null;
|
|
60
67
|
}
|
|
61
68
|
}
|
|
62
69
|
else {
|
|
63
|
-
await checkIfDefaultAccountIsSupported(accountConfig, hasPublicApps);
|
|
70
|
+
await checkIfDefaultAccountIsSupported(accountConfig, hasPublicApps, exit);
|
|
64
71
|
}
|
|
65
72
|
// The user is targeting an account type that we recommend developing on
|
|
66
73
|
if (!targetProjectAccountId && bypassRecommendedAccountPrompt) {
|
|
67
74
|
targetTestingAccountId = derivedAccountId;
|
|
68
|
-
await confirmDefaultAccountIsTarget(accountConfig);
|
|
75
|
+
await confirmDefaultAccountIsTarget(accountConfig, exit);
|
|
69
76
|
if (hasPublicApps) {
|
|
70
|
-
|
|
77
|
+
try {
|
|
78
|
+
checkIfParentAccountIsAuthed(accountConfig);
|
|
79
|
+
}
|
|
80
|
+
catch (e) {
|
|
81
|
+
uiLogger.error(getErrorMessage(e));
|
|
82
|
+
return exit(EXIT_CODES.SUCCESS);
|
|
83
|
+
}
|
|
71
84
|
targetProjectAccountId = accountConfig.parentAccountId || null;
|
|
72
85
|
}
|
|
73
86
|
else {
|
|
@@ -84,23 +97,36 @@ export async function deprecatedProjectDevFlow({ args, accountId, projectConfig,
|
|
|
84
97
|
targetTestingAccountId = targetAccountId;
|
|
85
98
|
// Only used for developer test accounts that are not yet in the config
|
|
86
99
|
if (notInConfigAccount) {
|
|
87
|
-
await useExistingDevTestAccount(env, notInConfigAccount);
|
|
100
|
+
const accountAdded = await useExistingDevTestAccount(env, notInConfigAccount);
|
|
101
|
+
if (!accountAdded) {
|
|
102
|
+
return exit(EXIT_CODES.SUCCESS);
|
|
103
|
+
}
|
|
88
104
|
}
|
|
89
105
|
createNewSandbox = hasPrivateApps && createNestedAccount;
|
|
90
106
|
createNewDeveloperTestAccount = hasPublicApps && createNestedAccount;
|
|
91
107
|
}
|
|
92
108
|
if (createNewSandbox) {
|
|
93
|
-
|
|
109
|
+
try {
|
|
110
|
+
targetProjectAccountId = await createSandboxForLocalDev(derivedAccountId, accountConfig, env);
|
|
111
|
+
}
|
|
112
|
+
catch {
|
|
113
|
+
return exit(EXIT_CODES.ERROR);
|
|
114
|
+
}
|
|
94
115
|
// We will be running our tests against this new sandbox account
|
|
95
116
|
targetTestingAccountId = targetProjectAccountId;
|
|
96
117
|
}
|
|
97
118
|
if (createNewDeveloperTestAccount) {
|
|
98
|
-
|
|
119
|
+
try {
|
|
120
|
+
targetTestingAccountId = await createDeveloperTestAccountForLocalDev(derivedAccountId, accountConfig, env, false);
|
|
121
|
+
}
|
|
122
|
+
catch {
|
|
123
|
+
return exit(EXIT_CODES.ERROR);
|
|
124
|
+
}
|
|
99
125
|
targetProjectAccountId = derivedAccountId;
|
|
100
126
|
}
|
|
101
127
|
if (!targetProjectAccountId || !targetTestingAccountId) {
|
|
102
128
|
uiLogger.error(commands.project.dev.errors.noAccount(accountId));
|
|
103
|
-
|
|
129
|
+
return exit(EXIT_CODES.ERROR);
|
|
104
130
|
}
|
|
105
131
|
// eslint-disable-next-line prefer-const
|
|
106
132
|
let { projectExists, project } = await ensureProjectExists(targetProjectAccountId, projectConfig.name, {
|
|
@@ -115,8 +141,8 @@ export async function deprecatedProjectDevFlow({ args, accountId, projectConfig,
|
|
|
115
141
|
isGithubLinked = Boolean(project.sourceIntegration && project.sourceIntegration.source === 'GITHUB');
|
|
116
142
|
}
|
|
117
143
|
else {
|
|
118
|
-
project = await createNewProjectForLocalDev(projectConfig, targetProjectAccountId, createNewSandbox, hasPublicApps);
|
|
119
|
-
deployedBuild = await createInitialBuildForNewProject(projectConfig, projectDir, targetProjectAccountId);
|
|
144
|
+
project = await createNewProjectForLocalDev(projectConfig, targetProjectAccountId, createNewSandbox, hasPublicApps, exit);
|
|
145
|
+
deployedBuild = await createInitialBuildForNewProject(projectConfig, projectDir, targetProjectAccountId, exit);
|
|
120
146
|
}
|
|
121
147
|
const LocalDev = new LocalDevManager_DEPRECATED({
|
|
122
148
|
runnableComponents,
|
|
@@ -129,6 +155,7 @@ export async function deprecatedProjectDevFlow({ args, accountId, projectConfig,
|
|
|
129
155
|
projectId: project.id,
|
|
130
156
|
targetAccountId: targetTestingAccountId,
|
|
131
157
|
env,
|
|
158
|
+
exit,
|
|
132
159
|
});
|
|
133
160
|
await LocalDev.start();
|
|
134
161
|
handleExit(({ isSIGHUP }) => LocalDev.stop(!isSIGHUP));
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Argv
|
|
2
|
-
import { ProjectDevArgs } from '../../../types/Yargs.js';
|
|
1
|
+
import { Argv } from 'yargs';
|
|
2
|
+
import { ProjectDevArgs, YargsCommandModule } from '../../../types/Yargs.js';
|
|
3
3
|
export declare const builder: (yargs: Argv) => Promise<Argv<ProjectDevArgs>>;
|
|
4
|
-
declare const projectDevCommand:
|
|
4
|
+
declare const projectDevCommand: YargsCommandModule<unknown, ProjectDevArgs>;
|
|
5
5
|
export default projectDevCommand;
|