@hubspot/cli 7.10.0 → 7.11.0-experimental.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 +5 -4
- package/commands/__tests__/getStarted.test.js +10 -0
- package/commands/__tests__/project.test.js +3 -0
- package/commands/account/__tests__/rename.test.js +10 -3
- package/commands/account/auth.js +10 -14
- package/commands/account/clean.js +11 -19
- package/commands/account/createOverride.js +15 -11
- package/commands/account/info.js +8 -5
- package/commands/account/list.js +15 -19
- package/commands/account/remove.js +23 -22
- package/commands/account/removeOverride.js +6 -6
- package/commands/account/rename.js +2 -2
- package/commands/account/use.js +19 -8
- package/commands/app/__tests__/migrate.test.js +8 -4
- package/commands/app/migrate.js +2 -2
- package/commands/auth.js +18 -14
- package/commands/config/migrate.js +5 -5
- package/commands/customObject/createSchema.js +2 -3
- package/commands/customObject/updateSchema.js +2 -3
- package/commands/getStarted.js +2 -3
- package/commands/hubdb/__tests__/list.test.js +1 -0
- package/commands/hubdb/list.js +2 -2
- package/commands/init.js +36 -32
- package/commands/project/__tests__/deploy.test.js +15 -10
- package/commands/project/__tests__/devUnifiedFlow.test.js +6 -4
- package/commands/project/__tests__/lint.test.js +709 -0
- package/commands/project/__tests__/logs.test.js +4 -0
- package/commands/project/__tests__/validate.test.js +2 -2
- package/commands/project/cloneApp.js +2 -2
- package/commands/project/create.js +20 -14
- package/commands/project/deploy.js +2 -2
- package/commands/project/dev/deprecatedFlow.js +4 -5
- package/commands/project/dev/index.js +6 -3
- package/commands/project/dev/unifiedFlow.js +11 -6
- package/commands/project/lint.d.ts +6 -0
- package/commands/project/lint.js +178 -0
- package/commands/project/logs.js +2 -3
- package/commands/project/migrate.js +4 -13
- package/commands/project/profile/add.js +6 -7
- package/commands/project/profile/delete.js +2 -2
- package/commands/project/upload.js +2 -2
- package/commands/project/validate.js +2 -2
- package/commands/project.js +2 -0
- package/commands/sandbox/__tests__/create.test.js +14 -5
- package/commands/sandbox/create.js +4 -5
- package/commands/sandbox/delete.js +23 -20
- package/commands/testAccount/create.js +2 -2
- package/commands/testAccount/delete.js +9 -8
- package/lang/en.d.ts +53 -12
- package/lang/en.js +63 -16
- package/lib/__tests__/buildAccount.test.js +22 -30
- package/lib/__tests__/commonOpts.test.js +9 -13
- package/lib/__tests__/developerTestAccounts.test.js +29 -17
- package/lib/__tests__/importData.test.js +20 -10
- package/lib/__tests__/oauth.test.js +19 -8
- package/lib/__tests__/sandboxSync.test.js +33 -11
- package/lib/__tests__/sandboxes.test.js +30 -19
- package/lib/__tests__/usageTracking.test.js +10 -10
- package/lib/__tests__/validation.test.js +32 -32
- package/lib/accountTypes.d.ts +9 -9
- package/lib/accountTypes.js +2 -4
- package/lib/app/__tests__/migrate.test.js +15 -0
- package/lib/app/__tests__/migrate_legacy.test.js +9 -0
- package/lib/app/migrate_legacy.d.ts +2 -2
- package/lib/buildAccount.d.ts +4 -4
- package/lib/buildAccount.js +7 -14
- package/lib/commonOpts.js +3 -3
- package/lib/configMigrate.d.ts +2 -2
- package/lib/configMigrate.js +42 -18
- package/lib/configOptions.js +3 -2
- package/lib/developerTestAccounts.d.ts +3 -3
- package/lib/developerTestAccounts.js +4 -7
- package/lib/doctor/DiagnosticInfoBuilder.d.ts +1 -1
- package/lib/doctor/DiagnosticInfoBuilder.js +9 -6
- package/lib/doctor/Doctor.js +4 -3
- package/lib/doctor/__tests__/Diagnosis.test.js +4 -3
- package/lib/doctor/__tests__/DiagnosticInfoBuilder.test.js +17 -9
- package/lib/doctor/__tests__/Doctor.test.js +14 -0
- package/lib/errorHandlers/index.js +8 -3
- package/lib/importData.js +8 -7
- package/lib/links.js +5 -5
- package/lib/middleware/{__test__ → __tests__}/commandTargetingUtils.test.js +3 -3
- package/lib/middleware/{__test__ → __tests__}/configMiddleware.test.js +23 -22
- package/lib/middleware/{__test__ → __tests__}/gitMiddleware.test.js +9 -7
- package/lib/middleware/autoUpdateMiddleware.js +34 -23
- package/lib/middleware/commandTargetingUtils.js +3 -2
- package/lib/middleware/configMiddleware.d.ts +6 -1
- package/lib/middleware/configMiddleware.js +36 -15
- package/lib/middleware/fireAlarmMiddleware.js +4 -15
- package/lib/middleware/gitMiddleware.js +8 -4
- package/lib/oauth.d.ts +2 -2
- package/lib/oauth.js +8 -10
- package/lib/projects/__tests__/AppDevModeInterface.test.js +17 -6
- package/lib/projects/__tests__/DevServerManager.test.js +1 -0
- package/lib/projects/__tests__/LocalDevProcess.test.js +1 -0
- package/lib/projects/__tests__/components.test.js +2 -22
- package/lib/projects/__tests__/deploy.test.js +16 -13
- package/lib/projects/__tests__/uieLinting.test.js +640 -0
- package/lib/projects/add/__tests__/legacyAddComponent.test.js +1 -1
- package/lib/projects/add/__tests__/v2AddComponent.test.js +30 -4
- package/lib/projects/add/legacyAddComponent.js +1 -1
- package/lib/projects/add/v2AddComponent.js +16 -5
- package/lib/projects/components.d.ts +8 -1
- package/lib/projects/components.js +91 -8
- package/lib/projects/create/__tests__/v2.test.js +11 -0
- package/lib/projects/deploy.js +21 -8
- package/lib/projects/localDev/AppDevModeInterface.js +2 -2
- package/lib/projects/localDev/DevServerManager_DEPRECATED.js +11 -3
- package/lib/projects/localDev/LocalDevLogger.js +4 -4
- package/lib/projects/localDev/LocalDevManager_DEPRECATED.js +3 -3
- package/lib/projects/localDev/helpers/account.d.ts +10 -10
- package/lib/projects/localDev/helpers/account.js +6 -11
- package/lib/projects/localDev/helpers/process.js +5 -3
- package/lib/projects/uieLinting.d.ts +33 -0
- package/lib/projects/uieLinting.js +222 -0
- package/lib/projects/urls.js +5 -6
- package/lib/prompts/__tests__/downloadProjectPrompt.test.js +7 -5
- package/lib/prompts/accountNamePrompt.js +3 -3
- package/lib/prompts/accountsPrompt.d.ts +1 -1
- package/lib/prompts/accountsPrompt.js +6 -7
- package/lib/prompts/confirmImportDataPrompt.js +2 -2
- package/lib/prompts/downloadProjectPrompt.d.ts +1 -0
- package/lib/prompts/downloadProjectPrompt.js +5 -2
- package/lib/prompts/importDataTestAccountSelectPrompt.js +4 -5
- package/lib/prompts/personalAccessKeyPrompt.js +2 -2
- package/lib/prompts/projectDevTargetAccountPrompt.d.ts +3 -3
- package/lib/prompts/projectDevTargetAccountPrompt.js +5 -7
- package/lib/prompts/sandboxesPrompt.js +7 -8
- package/lib/prompts/setAsDefaultAccountPrompt.js +7 -6
- package/lib/sandboxSync.d.ts +2 -2
- package/lib/sandboxSync.js +3 -9
- package/lib/sandboxes.d.ts +4 -4
- package/lib/sandboxes.js +6 -11
- package/lib/serverlessLogs.js +2 -2
- package/lib/theme/__tests__/migrate.test.js +15 -0
- package/lib/ui/SpinniesManager.d.ts +5 -7
- package/lib/ui/SpinniesManager.js +9 -12
- package/lib/ui/__tests__/SpinniesManager.test.d.ts +1 -0
- package/lib/ui/__tests__/SpinniesManager.test.js +489 -0
- package/lib/ui/index.js +6 -3
- package/lib/usageTracking.js +15 -8
- package/lib/validation.js +13 -11
- package/mcp-server/tools/cms/HsCreateFunctionTool.js +4 -2
- package/mcp-server/tools/cms/HsCreateModuleTool.js +4 -2
- package/mcp-server/tools/cms/HsCreateTemplateTool.js +4 -2
- package/mcp-server/tools/cms/HsFunctionLogsTool.js +4 -2
- package/mcp-server/tools/cms/HsListFunctionsTool.js +3 -1
- package/mcp-server/tools/cms/HsListTool.js +3 -1
- package/mcp-server/tools/cms/__tests__/HsCreateFunctionTool.test.js +1 -0
- package/mcp-server/tools/index.js +4 -0
- package/mcp-server/tools/project/AddFeatureToProjectTool.js +4 -2
- package/mcp-server/tools/project/CreateProjectTool.js +4 -2
- package/mcp-server/tools/project/CreateTestAccountTool.js +17 -7
- package/mcp-server/tools/project/DeployProjectTool.js +3 -1
- package/mcp-server/tools/project/DocFetchTool.js +6 -4
- package/mcp-server/tools/project/DocsSearchTool.d.ts +1 -1
- package/mcp-server/tools/project/DocsSearchTool.js +10 -8
- package/mcp-server/tools/project/GetApiUsagePatternsByAppIdTool.d.ts +1 -1
- package/mcp-server/tools/project/GetApiUsagePatternsByAppIdTool.js +9 -7
- package/mcp-server/tools/project/GetApplicationInfoTool.js +8 -6
- package/mcp-server/tools/project/GetBuildLogsTool.d.ts +26 -0
- package/mcp-server/tools/project/GetBuildLogsTool.js +125 -0
- package/mcp-server/tools/project/GetBuildStatusTool.d.ts +26 -0
- package/mcp-server/tools/project/GetBuildStatusTool.js +166 -0
- package/mcp-server/tools/project/GetConfigValuesTool.d.ts +1 -1
- package/mcp-server/tools/project/GetConfigValuesTool.js +9 -7
- package/mcp-server/tools/project/GuidedWalkthroughTool.d.ts +1 -1
- package/mcp-server/tools/project/GuidedWalkthroughTool.js +5 -3
- package/mcp-server/tools/project/UploadProjectTools.js +3 -1
- package/mcp-server/tools/project/ValidateProjectTool.js +4 -2
- package/mcp-server/tools/project/__tests__/CreateTestAccountTool.test.js +12 -2
- package/mcp-server/tools/project/__tests__/DocFetchTool.test.js +5 -1
- package/mcp-server/tools/project/__tests__/DocsSearchTool.test.js +23 -11
- package/mcp-server/tools/project/__tests__/GetApiUsagePatternsByAppIdTool.test.js +7 -5
- package/mcp-server/tools/project/__tests__/GetApplicationInfoTool.test.js +7 -5
- package/mcp-server/tools/project/__tests__/GetBuildLogsTool.test.d.ts +1 -0
- package/mcp-server/tools/project/__tests__/GetBuildLogsTool.test.js +305 -0
- package/mcp-server/tools/project/__tests__/GetBuildStatusTool.test.d.ts +1 -0
- package/mcp-server/tools/project/__tests__/GetBuildStatusTool.test.js +240 -0
- package/mcp-server/tools/project/__tests__/GetConfigValuesTool.test.js +8 -6
- package/mcp-server/utils/__tests__/content.test.js +21 -20
- package/mcp-server/utils/__tests__/feedbackTracking.test.js +34 -28
- package/mcp-server/utils/config.d.ts +1 -0
- package/mcp-server/utils/config.js +10 -0
- package/mcp-server/utils/content.d.ts +1 -1
- package/mcp-server/utils/content.js +2 -2
- package/mcp-server/utils/feedbackTracking.d.ts +1 -1
- package/mcp-server/utils/feedbackTracking.js +3 -3
- package/mcp-server/utils/toolUsageTracking.js +4 -3
- package/package.json +9 -9
- package/ui/components/BoxWithTitle.d.ts +2 -1
- package/ui/components/BoxWithTitle.js +2 -2
- package/ui/components/StatusMessageBoxes.d.ts +5 -4
- package/ui/components/StatusMessageBoxes.js +8 -8
- package/lib/middleware/__test__/notificationsMiddleware.test.js +0 -8
- package/lib/middleware/notificationsMiddleware.d.ts +0 -1
- package/lib/middleware/notificationsMiddleware.js +0 -28
- package/lib/ui/boxen.d.ts +0 -5
- package/lib/ui/boxen.js +0 -26
- package/mcp-server/utils/__tests__/cliConfig.test.js +0 -110
- package/mcp-server/utils/cliConfig.d.ts +0 -1
- package/mcp-server/utils/cliConfig.js +0 -12
- /package/{lib/middleware/__test__/commandTargetingUtils.test.d.ts → commands/project/__tests__/lint.test.d.ts} +0 -0
- /package/lib/middleware/{__test__/configMiddleware.test.d.ts → __tests__/commandTargetingUtils.test.d.ts} +0 -0
- /package/lib/middleware/{__test__/gitMiddleware.test.d.ts → __tests__/configMiddleware.test.d.ts} +0 -0
- /package/lib/middleware/{__test__/notificationsMiddleware.test.d.ts → __tests__/gitMiddleware.test.d.ts} +0 -0
- /package/lib/middleware/{__test__ → __tests__}/requestMiddleware.test.d.ts +0 -0
- /package/lib/middleware/{__test__ → __tests__}/requestMiddleware.test.js +0 -0
- /package/lib/middleware/{__test__ → __tests__}/yargsChecksMiddleware.test.d.ts +0 -0
- /package/lib/middleware/{__test__ → __tests__}/yargsChecksMiddleware.test.js +0 -0
- /package/{mcp-server/utils/__tests__/cliConfig.test.d.ts → lib/projects/__tests__/uieLinting.test.d.ts} +0 -0
|
@@ -3,19 +3,19 @@ import * as gitUI from '../../ui/git.js';
|
|
|
3
3
|
import { checkAndWarnGitInclusionMiddleware } from '../gitMiddleware.js';
|
|
4
4
|
vi.mock('@hubspot/local-dev-lib/config');
|
|
5
5
|
vi.mock('../../ui/git');
|
|
6
|
-
const
|
|
6
|
+
const getConfigFilePathSpy = vi.spyOn(config, 'getConfigFilePath');
|
|
7
7
|
const checkAndWarnGitInclusionSpy = vi.spyOn(gitUI, 'checkAndWarnGitInclusion');
|
|
8
8
|
describe('lib/middleware/gitMiddleware', () => {
|
|
9
9
|
describe('checkAndWarnGitInclusionMiddleware()', () => {
|
|
10
10
|
it('should call checkAndWarnGitInclusion when command is provided and config path exists', () => {
|
|
11
11
|
const mockConfigPath = '/path/to/config.js';
|
|
12
|
-
|
|
12
|
+
getConfigFilePathSpy.mockReturnValue(mockConfigPath);
|
|
13
13
|
const argv = {
|
|
14
14
|
_: ['some-command'],
|
|
15
15
|
$0: 'hs',
|
|
16
16
|
};
|
|
17
17
|
checkAndWarnGitInclusionMiddleware(argv);
|
|
18
|
-
expect(
|
|
18
|
+
expect(getConfigFilePathSpy).toHaveBeenCalledTimes(1);
|
|
19
19
|
expect(checkAndWarnGitInclusionSpy).toHaveBeenCalledWith(mockConfigPath);
|
|
20
20
|
});
|
|
21
21
|
it('should not call checkAndWarnGitInclusion when no command is provided', () => {
|
|
@@ -24,17 +24,19 @@ describe('lib/middleware/gitMiddleware', () => {
|
|
|
24
24
|
$0: 'hs',
|
|
25
25
|
};
|
|
26
26
|
checkAndWarnGitInclusionMiddleware(argv);
|
|
27
|
-
expect(
|
|
27
|
+
expect(getConfigFilePathSpy).not.toHaveBeenCalled();
|
|
28
28
|
expect(checkAndWarnGitInclusionSpy).not.toHaveBeenCalled();
|
|
29
29
|
});
|
|
30
|
-
it('should not call checkAndWarnGitInclusion when config path
|
|
31
|
-
|
|
30
|
+
it('should not call checkAndWarnGitInclusion when config path does not exist', () => {
|
|
31
|
+
getConfigFilePathSpy.mockImplementation(() => {
|
|
32
|
+
throw new Error('Config path does not exist');
|
|
33
|
+
});
|
|
32
34
|
const argv = {
|
|
33
35
|
_: ['some-command'],
|
|
34
36
|
$0: 'hs',
|
|
35
37
|
};
|
|
36
38
|
checkAndWarnGitInclusionMiddleware(argv);
|
|
37
|
-
expect(
|
|
39
|
+
expect(getConfigFilePathSpy).toHaveBeenCalledTimes(1);
|
|
38
40
|
expect(checkAndWarnGitInclusionSpy).not.toHaveBeenCalled();
|
|
39
41
|
});
|
|
40
42
|
});
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import updateNotifier from 'update-notifier';
|
|
2
|
-
import {
|
|
2
|
+
import { getConfig } from '@hubspot/local-dev-lib/config';
|
|
3
3
|
import { pkg } from '../jsonLoader.js';
|
|
4
|
-
import { UI_COLORS } from '../ui/index.js';
|
|
5
4
|
import SpinniesManager from '../ui/SpinniesManager.js';
|
|
6
5
|
import { lib } from '../../lang/en.js';
|
|
7
6
|
import { DEFAULT_PACKAGE_MANAGER, isGloballyInstalled, executeInstall, } from '../npm.js';
|
|
8
7
|
import { debugError } from '../errorHandlers/index.js';
|
|
9
8
|
import { uiLogger } from '../ui/logger.js';
|
|
10
9
|
import { isTargetedCommand } from './commandTargetingUtils.js';
|
|
10
|
+
import { renderInline } from '../../ui/index.js';
|
|
11
|
+
import { getWarningBox } from '../../ui/components/StatusMessageBoxes.js';
|
|
11
12
|
// Default behavior is to check for notifications at most once per day
|
|
12
13
|
// update-notifier stores the last checked date in the user's home directory
|
|
13
14
|
const notifier = updateNotifier({
|
|
@@ -16,23 +17,16 @@ const notifier = updateNotifier({
|
|
|
16
17
|
shouldNotifyInNpmScript: true,
|
|
17
18
|
});
|
|
18
19
|
const CMS_CLI_PACKAGE_NAME = '@hubspot/cms-cli';
|
|
19
|
-
function updateNotification() {
|
|
20
|
-
|
|
20
|
+
async function updateNotification(currentVersion, latestVersion, updateCommand) {
|
|
21
|
+
await renderInline(getWarningBox({
|
|
22
|
+
title: pkg.name === CMS_CLI_PACKAGE_NAME
|
|
23
|
+
? ''
|
|
24
|
+
: lib.middleware.updateNotification.notifyTitle,
|
|
21
25
|
message: pkg.name === CMS_CLI_PACKAGE_NAME
|
|
22
26
|
? lib.middleware.updateNotification.cmsUpdateNotification(CMS_CLI_PACKAGE_NAME)
|
|
23
|
-
: lib.middleware.updateNotification.cliUpdateNotification,
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
borderColor: UI_COLORS.MARIGOLD_DARK,
|
|
27
|
-
margin: 1,
|
|
28
|
-
padding: 1,
|
|
29
|
-
textAlignment: 'center',
|
|
30
|
-
borderStyle: 'round',
|
|
31
|
-
title: pkg.name === CMS_CLI_PACKAGE_NAME
|
|
32
|
-
? undefined
|
|
33
|
-
: lib.middleware.updateNotification.notifyTitle,
|
|
34
|
-
},
|
|
35
|
-
});
|
|
27
|
+
: lib.middleware.updateNotification.cliUpdateNotification(currentVersion, updateCommand, latestVersion),
|
|
28
|
+
textCentered: true,
|
|
29
|
+
}));
|
|
36
30
|
}
|
|
37
31
|
const SKIP_AUTO_UPDATE_COMMANDS = {
|
|
38
32
|
config: {
|
|
@@ -43,13 +37,28 @@ const preventAutoUpdateForCommand = (commandParts) => {
|
|
|
43
37
|
return isTargetedCommand(commandParts, SKIP_AUTO_UPDATE_COMMANDS);
|
|
44
38
|
};
|
|
45
39
|
export async function autoUpdateCLI(argv) {
|
|
46
|
-
// This lets us back to default update-notifier behavior
|
|
47
40
|
let showManualInstallHelp = true;
|
|
41
|
+
let isGlobalInstall = null;
|
|
42
|
+
const checkGlobalInstall = async () => {
|
|
43
|
+
if (isGlobalInstall === null) {
|
|
44
|
+
isGlobalInstall =
|
|
45
|
+
(await isGloballyInstalled(DEFAULT_PACKAGE_MANAGER)) &&
|
|
46
|
+
(await isGloballyInstalled('hs'));
|
|
47
|
+
}
|
|
48
|
+
return isGlobalInstall;
|
|
49
|
+
};
|
|
50
|
+
let config;
|
|
51
|
+
try {
|
|
52
|
+
config = getConfig();
|
|
53
|
+
}
|
|
54
|
+
catch (e) {
|
|
55
|
+
debugError(e);
|
|
56
|
+
}
|
|
48
57
|
if (notifier &&
|
|
49
58
|
notifier.update &&
|
|
50
59
|
!argv.useEnv &&
|
|
51
60
|
!process.env.SKIP_HUBSPOT_CLI_AUTO_UPDATES &&
|
|
52
|
-
|
|
61
|
+
config?.allowAutoUpdates !== false &&
|
|
53
62
|
!preventAutoUpdateForCommand(argv._)) {
|
|
54
63
|
// Ignore all update notifications if the current version is a pre-release
|
|
55
64
|
if (!notifier.update.current.includes('-')) {
|
|
@@ -63,8 +72,7 @@ export async function autoUpdateCLI(argv) {
|
|
|
63
72
|
text: lib.middleware.autoUpdateCLI.updateAvailable(notifier.update.latest),
|
|
64
73
|
});
|
|
65
74
|
try {
|
|
66
|
-
if (
|
|
67
|
-
(await isGloballyInstalled('hs'))) {
|
|
75
|
+
if (await checkGlobalInstall()) {
|
|
68
76
|
await executeInstall(['@hubspot/cli@latest'], '-g');
|
|
69
77
|
showManualInstallHelp = false;
|
|
70
78
|
SpinniesManager.succeed('cliAutoUpdate', {
|
|
@@ -87,7 +95,10 @@ export async function autoUpdateCLI(argv) {
|
|
|
87
95
|
}
|
|
88
96
|
}
|
|
89
97
|
}
|
|
90
|
-
if (showManualInstallHelp
|
|
91
|
-
|
|
98
|
+
if (showManualInstallHelp &&
|
|
99
|
+
notifier.update &&
|
|
100
|
+
process.stdout.isTTY &&
|
|
101
|
+
!notifier.update.current.includes('-')) {
|
|
102
|
+
await updateNotification(notifier.update.current, notifier.update.latest, `npm i ${(await checkGlobalInstall()) ? '-g' : ''} @hubspot/cli`);
|
|
92
103
|
}
|
|
93
104
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { globalConfigFileExists } from '@hubspot/local-dev-lib/config';
|
|
2
2
|
export function isTargetedCommand(commandParts, targetCommandMap) {
|
|
3
3
|
const currentCommandPart = commandParts[0];
|
|
4
4
|
if (!targetCommandMap[currentCommandPart]) {
|
|
@@ -20,10 +20,11 @@ export function isTargetedCommand(commandParts, targetCommandMap) {
|
|
|
20
20
|
const SKIP_CONFIG_LOADING_COMMANDS = {
|
|
21
21
|
init: true,
|
|
22
22
|
feedback: true,
|
|
23
|
+
mcp: { start: true },
|
|
23
24
|
};
|
|
24
25
|
// Returns true if the command requires a config file to be present
|
|
25
26
|
export function shouldLoadConfigForCommand(commandParts) {
|
|
26
|
-
const globalConfigExists =
|
|
27
|
+
const globalConfigExists = globalConfigFileExists();
|
|
27
28
|
// the user is trying to migrate the global config
|
|
28
29
|
const isGlobalConfigMigration = !globalConfigExists &&
|
|
29
30
|
isTargetedCommand(commandParts, {
|
|
@@ -3,11 +3,16 @@ import { CLIOptions } from '@hubspot/local-dev-lib/types/CLIOptions';
|
|
|
3
3
|
export declare function handleDeprecatedEnvVariables(argv: Arguments<{
|
|
4
4
|
useEnv?: boolean;
|
|
5
5
|
}>): void;
|
|
6
|
+
export declare function handleCustomConfigLocationMiddleware(argv: Arguments<{
|
|
7
|
+
useEnv?: boolean;
|
|
8
|
+
config?: string;
|
|
9
|
+
}>): void;
|
|
6
10
|
/**
|
|
7
11
|
* Auto-injects the derivedAccountId flag into all commands
|
|
8
12
|
*/
|
|
9
13
|
export declare function injectAccountIdMiddleware(argv: Arguments<{
|
|
10
14
|
account?: string;
|
|
15
|
+
config?: string;
|
|
11
16
|
}>): Promise<void>;
|
|
12
|
-
export declare function
|
|
17
|
+
export declare function validateConfigMiddleware(argv: Arguments<CLIOptions>): Promise<void>;
|
|
13
18
|
export declare function validateAccountOptions(argv: Arguments): Promise<void>;
|
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
import
|
|
1
|
+
import path from 'path';
|
|
2
|
+
import { getConfigAccountIfExists, validateConfig, getConfigDefaultAccountIfExists, configFileExists, } from '@hubspot/local-dev-lib/config';
|
|
3
|
+
import { getCwd } from '@hubspot/local-dev-lib/path';
|
|
2
4
|
import { validateAccount } from '../validation.js';
|
|
3
5
|
import { EXIT_CODES } from '../enums/exitCodes.js';
|
|
4
6
|
import { commands } from '../../lang/en.js';
|
|
5
7
|
import { uiDeprecatedTag } from '../ui/index.js';
|
|
6
|
-
import {
|
|
8
|
+
import { shouldLoadConfigForCommand, shouldRunAccountValidationForCommand, shouldRunConfigValidationForCommand, } from './commandTargetingUtils.js';
|
|
7
9
|
import { parseStringToNumber } from '../parsing.js';
|
|
8
10
|
import { uiLogger } from '../ui/logger.js';
|
|
9
11
|
import { lib } from '../../lang/en.js';
|
|
@@ -17,6 +19,18 @@ export function handleDeprecatedEnvVariables(argv) {
|
|
|
17
19
|
process.env.HUBSPOT_ACCOUNT_ID = process.env.HUBSPOT_PORTAL_ID;
|
|
18
20
|
}
|
|
19
21
|
}
|
|
22
|
+
export function handleCustomConfigLocationMiddleware(argv) {
|
|
23
|
+
const { useEnv, config } = argv;
|
|
24
|
+
if (useEnv) {
|
|
25
|
+
process.env.USE_ENVIRONMENT_HUBSPOT_CONFIG = 'true';
|
|
26
|
+
}
|
|
27
|
+
else if (config && typeof config === 'string') {
|
|
28
|
+
const absoluteConfigPath = path.isAbsolute(config)
|
|
29
|
+
? config
|
|
30
|
+
: path.join(getCwd(), config);
|
|
31
|
+
process.env.HUBSPOT_CONFIG_PATH = absoluteConfigPath;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
20
34
|
/**
|
|
21
35
|
* Auto-injects the derivedAccountId flag into all commands
|
|
22
36
|
*/
|
|
@@ -33,10 +47,23 @@ export async function injectAccountIdMiddleware(argv) {
|
|
|
33
47
|
}
|
|
34
48
|
}
|
|
35
49
|
else {
|
|
36
|
-
|
|
50
|
+
// Wrap in try-catch to handle cases where config file doesn't exist yet (e.g., during hs init)
|
|
51
|
+
try {
|
|
52
|
+
let accountInConfig = account
|
|
53
|
+
? getConfigAccountIfExists(account)
|
|
54
|
+
: undefined;
|
|
55
|
+
if (!accountInConfig) {
|
|
56
|
+
accountInConfig = getConfigDefaultAccountIfExists();
|
|
57
|
+
}
|
|
58
|
+
argv.derivedAccountId = accountInConfig?.accountId;
|
|
59
|
+
}
|
|
60
|
+
catch (err) {
|
|
61
|
+
// Config file doesn't exist yet, which is fine for commands like hs init
|
|
62
|
+
argv.derivedAccountId = undefined;
|
|
63
|
+
}
|
|
37
64
|
}
|
|
38
65
|
}
|
|
39
|
-
export async function
|
|
66
|
+
export async function validateConfigMiddleware(argv) {
|
|
40
67
|
// Skip this when no command is provided
|
|
41
68
|
if (!argv._.length || argv.help) {
|
|
42
69
|
return;
|
|
@@ -45,23 +72,17 @@ export async function loadAndValidateConfigMiddleware(argv) {
|
|
|
45
72
|
if (!shouldLoadConfigForCommand(argv._)) {
|
|
46
73
|
return;
|
|
47
74
|
}
|
|
48
|
-
// If the config file exists and the --config flag is used, exit with an error
|
|
49
|
-
if (configFileExists(true) &&
|
|
50
|
-
argv.config &&
|
|
51
|
-
!isTargetedCommand(argv._, { config: { migrate: true } })) {
|
|
52
|
-
uiLogger.error(commands.generalErrors.loadConfigMiddleware.configFileExists(getConfigPath()));
|
|
53
|
-
process.exit(EXIT_CODES.ERROR);
|
|
54
|
-
}
|
|
55
|
-
const config = loadConfig(argv.config, argv);
|
|
56
75
|
// We don't run validation for auth because users should be able to run it when
|
|
57
76
|
// no accounts are configured, but we still want to exit if the config file is not found
|
|
58
|
-
if (
|
|
77
|
+
if (!process.env.USE_ENVIRONMENT_HUBSPOT_CONFIG && !configFileExists()) {
|
|
78
|
+
console.error('Config file not found, run hs account auth to configure your account');
|
|
59
79
|
process.exit(EXIT_CODES.ERROR);
|
|
60
80
|
}
|
|
61
81
|
// Only validate the config if the command requires it
|
|
62
82
|
if (shouldRunConfigValidationForCommand(argv._)) {
|
|
63
|
-
const
|
|
64
|
-
if (!
|
|
83
|
+
const { isValid, errors } = validateConfig();
|
|
84
|
+
if (!isValid) {
|
|
85
|
+
uiLogger.error(commands.generalErrors.validateConfigMiddleware.configValidationFailed(errors));
|
|
65
86
|
process.exit(EXIT_CODES.ERROR);
|
|
66
87
|
}
|
|
67
88
|
}
|
|
@@ -2,7 +2,6 @@ import chalk from 'chalk';
|
|
|
2
2
|
import { fetchFireAlarms } from '@hubspot/local-dev-lib/api/fireAlarm';
|
|
3
3
|
import { debugError } from '../errorHandlers/index.js';
|
|
4
4
|
import { pkg } from '../jsonLoader.js';
|
|
5
|
-
import { logInBox } from '../ui/boxen.js';
|
|
6
5
|
import { renderInline } from '../../ui/index.js';
|
|
7
6
|
import { getWarningBox } from '../../ui/components/StatusMessageBoxes.js';
|
|
8
7
|
/*
|
|
@@ -100,20 +99,10 @@ async function logFireAlarms(accountId, command, version) {
|
|
|
100
99
|
}
|
|
101
100
|
return acc;
|
|
102
101
|
}, '');
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
title: 'Notifications',
|
|
108
|
-
},
|
|
109
|
-
});
|
|
110
|
-
}
|
|
111
|
-
else {
|
|
112
|
-
await renderInline(getWarningBox({
|
|
113
|
-
title: 'Notifications',
|
|
114
|
-
message: notifications,
|
|
115
|
-
}));
|
|
116
|
-
}
|
|
102
|
+
await renderInline(getWarningBox({
|
|
103
|
+
title: 'Notifications',
|
|
104
|
+
message: notifications,
|
|
105
|
+
}));
|
|
117
106
|
}
|
|
118
107
|
}
|
|
119
108
|
export async function checkFireAlarms(argv) {
|
|
@@ -1,15 +1,19 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { getConfigFilePath, globalConfigFileExists, } from '@hubspot/local-dev-lib/config';
|
|
2
2
|
import { checkAndWarnGitInclusion } from '../ui/git.js';
|
|
3
|
+
import { debugError } from '../errorHandlers/index.js';
|
|
3
4
|
export function checkAndWarnGitInclusionMiddleware(argv) {
|
|
4
5
|
// Skip this when no command is provided
|
|
5
6
|
if (argv._.length) {
|
|
6
7
|
// Skip if using global config
|
|
7
|
-
if (
|
|
8
|
+
if (globalConfigFileExists()) {
|
|
8
9
|
return;
|
|
9
10
|
}
|
|
10
|
-
|
|
11
|
-
|
|
11
|
+
try {
|
|
12
|
+
const configPath = getConfigFilePath();
|
|
12
13
|
checkAndWarnGitInclusion(configPath);
|
|
13
14
|
}
|
|
15
|
+
catch (error) {
|
|
16
|
+
debugError(error);
|
|
17
|
+
}
|
|
14
18
|
}
|
|
15
19
|
}
|
package/lib/oauth.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export declare function authenticateWithOauth(accountConfig:
|
|
1
|
+
import { OAuthConfigAccount } from '@hubspot/local-dev-lib/types/Accounts';
|
|
2
|
+
export declare function authenticateWithOauth(accountConfig: OAuthConfigAccount): Promise<void>;
|
package/lib/oauth.js
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import express from 'express';
|
|
2
2
|
import open from 'open';
|
|
3
3
|
import { OAuth2Manager } from '@hubspot/local-dev-lib/models/OAuth2Manager';
|
|
4
|
-
import {
|
|
5
|
-
import { getAccountIdentifier } from '@hubspot/local-dev-lib/config/getAccountIdentifier';
|
|
4
|
+
import { getConfigAccountById } from '@hubspot/local-dev-lib/config';
|
|
6
5
|
import { addOauthToAccountConfig } from '@hubspot/local-dev-lib/oauth';
|
|
7
6
|
import { getHubSpotWebsiteOrigin } from '@hubspot/local-dev-lib/urls';
|
|
8
7
|
import { uiLogger } from './ui/logger.js';
|
|
@@ -14,15 +13,15 @@ import { EXIT_CODES } from './enums/exitCodes.js';
|
|
|
14
13
|
const PORT = 3000;
|
|
15
14
|
const redirectUri = `http://localhost:${PORT}/oauth-callback`;
|
|
16
15
|
function buildAuthUrl(oauthManager) {
|
|
17
|
-
const { env: accountEnv,
|
|
16
|
+
const { env: accountEnv, auth } = oauthManager.account;
|
|
18
17
|
const env = accountEnv || ENVIRONMENTS.PROD;
|
|
19
|
-
const scopes =
|
|
20
|
-
if (!clientId) {
|
|
18
|
+
const scopes = auth.scopes.length > 0 ? auth.scopes : DEFAULT_OAUTH_SCOPES;
|
|
19
|
+
if (!auth.clientId) {
|
|
21
20
|
uiLogger.error(lib.oauth.missingClientId);
|
|
22
21
|
process.exit(EXIT_CODES.ERROR);
|
|
23
22
|
}
|
|
24
23
|
return (`${getHubSpotWebsiteOrigin(env)}/oauth/${oauthManager.account.accountId}/authorize` +
|
|
25
|
-
`?client_id=${encodeURIComponent(clientId)}` + // app's client ID
|
|
24
|
+
`?client_id=${encodeURIComponent(auth.clientId)}` + // app's client ID
|
|
26
25
|
`&scope=${encodeURIComponent(scopes.join(' '))}` + // scopes being requested by the app
|
|
27
26
|
`&redirect_uri=${encodeURIComponent(redirectUri)}` // where to send the user after the consent page
|
|
28
27
|
);
|
|
@@ -45,8 +44,8 @@ async function authorize(oauthManager) {
|
|
|
45
44
|
if (req.query.code) {
|
|
46
45
|
const authCodeProof = {
|
|
47
46
|
grant_type: 'authorization_code',
|
|
48
|
-
client_id: oauthManager.account.clientId,
|
|
49
|
-
client_secret: oauthManager.account.clientSecret,
|
|
47
|
+
client_id: oauthManager.account.auth.clientId,
|
|
48
|
+
client_secret: oauthManager.account.auth.clientSecret,
|
|
50
49
|
redirect_uri: redirectUri,
|
|
51
50
|
code: req.query.code,
|
|
52
51
|
};
|
|
@@ -82,8 +81,7 @@ async function authorize(oauthManager) {
|
|
|
82
81
|
});
|
|
83
82
|
}
|
|
84
83
|
function setupOauth(accountConfig) {
|
|
85
|
-
const
|
|
86
|
-
const config = getAccountConfig(accountId);
|
|
84
|
+
const config = getConfigAccountById(accountConfig.accountId);
|
|
87
85
|
return new OAuth2Manager({
|
|
88
86
|
...accountConfig,
|
|
89
87
|
env: accountConfig.env || config?.env || ENVIRONMENTS.PROD,
|
|
@@ -12,7 +12,7 @@ vi.mock('@hubspot/ui-extensions-dev-server', () => {
|
|
|
12
12
|
});
|
|
13
13
|
import { fetchAppInstallationData } from '@hubspot/local-dev-lib/api/localDevAuth';
|
|
14
14
|
import { fetchAppMetadataByUid, fetchPublicAppProductionInstallCounts, installStaticAuthAppOnTestAccount, } from '@hubspot/local-dev-lib/api/appsDev';
|
|
15
|
-
import {
|
|
15
|
+
import { getConfigAccountById } from '@hubspot/local-dev-lib/config';
|
|
16
16
|
import AppDevModeInterface from '../localDev/AppDevModeInterface.js';
|
|
17
17
|
import LocalDevState from '../localDev/LocalDevState.js';
|
|
18
18
|
import LocalDevLogger from '../localDev/LocalDevLogger.js';
|
|
@@ -121,7 +121,7 @@ describe('AppDevModeInterface', () => {
|
|
|
121
121
|
previouslyAuthorizedScopeGroups: [],
|
|
122
122
|
},
|
|
123
123
|
});
|
|
124
|
-
|
|
124
|
+
getConfigAccountById.mockReturnValue({
|
|
125
125
|
parentAccountId: 12345,
|
|
126
126
|
});
|
|
127
127
|
isDeveloperTestAccount.mockReturnValue(true);
|
|
@@ -290,13 +290,14 @@ describe('AppDevModeInterface', () => {
|
|
|
290
290
|
});
|
|
291
291
|
it('should handle app reinstallation', async () => {
|
|
292
292
|
// Set up conditions for non-automatic installation
|
|
293
|
-
getAccountConfig.mockReturnValue(null);
|
|
294
293
|
fetchAppInstallationData.mockResolvedValue({
|
|
295
294
|
data: {
|
|
296
295
|
isInstalledWithScopeGroups: false,
|
|
297
296
|
previouslyAuthorizedScopeGroups: ['old-scope'],
|
|
298
297
|
},
|
|
299
298
|
});
|
|
299
|
+
// Make it not automatically installable by making it not a test account
|
|
300
|
+
isDeveloperTestAccount.mockReturnValue(false);
|
|
300
301
|
await appDevModeInterface.setup();
|
|
301
302
|
expect(installAppBrowserPrompt).toHaveBeenCalledWith('http://static-install-url', true);
|
|
302
303
|
});
|
|
@@ -308,7 +309,7 @@ describe('AppDevModeInterface', () => {
|
|
|
308
309
|
});
|
|
309
310
|
it('should exit if user declines auto-install', async () => {
|
|
310
311
|
// Set up conditions for automatic installation
|
|
311
|
-
|
|
312
|
+
getConfigAccountById.mockReturnValue({
|
|
312
313
|
parentAccountId: 12345, // matches targetProjectAccountId
|
|
313
314
|
});
|
|
314
315
|
isDeveloperTestAccount.mockReturnValue(true);
|
|
@@ -375,6 +376,15 @@ describe('AppDevModeInterface', () => {
|
|
|
375
376
|
data: { uniquePortalInstallCount: 5 },
|
|
376
377
|
});
|
|
377
378
|
getStaticAuthAppInstallUrl.mockReturnValue('http://static-install-url');
|
|
379
|
+
getConfigAccountById.mockReturnValue({
|
|
380
|
+
parentAccountId: 12345,
|
|
381
|
+
});
|
|
382
|
+
isDeveloperTestAccount.mockReturnValue(true);
|
|
383
|
+
isSandbox.mockReturnValue(false);
|
|
384
|
+
installAppAutoPrompt.mockResolvedValue(true);
|
|
385
|
+
confirmPrompt.mockResolvedValue(true);
|
|
386
|
+
installStaticAuthAppOnTestAccount.mockResolvedValue(undefined);
|
|
387
|
+
isServerRunningAtUrl.mockResolvedValue(true);
|
|
378
388
|
installAppBrowserPrompt.mockImplementation(async () => {
|
|
379
389
|
const addListenerCall = mockLocalDevState.addListener.mock.calls.find(call => call[0] === 'devServerMessage');
|
|
380
390
|
if (addListenerCall) {
|
|
@@ -387,8 +397,8 @@ describe('AppDevModeInterface', () => {
|
|
|
387
397
|
mockLocalDevState.getAppDataByUid = vi.fn().mockReturnValue(mockAppData);
|
|
388
398
|
mockLocalDevState.setAppDataForUid = vi.fn();
|
|
389
399
|
mockLocalDevState.addListener = vi.fn();
|
|
390
|
-
// Target account config is missing
|
|
391
|
-
|
|
400
|
+
// Target account config is missing - make it not a test account so isAutomaticallyInstallable returns false
|
|
401
|
+
isDeveloperTestAccount.mockReturnValue(false);
|
|
392
402
|
// App is not installed
|
|
393
403
|
fetchAppInstallationData.mockResolvedValue({
|
|
394
404
|
data: {
|
|
@@ -401,6 +411,7 @@ describe('AppDevModeInterface', () => {
|
|
|
401
411
|
localDevState: mockLocalDevState,
|
|
402
412
|
localDevLogger: mockLocalDevLogger,
|
|
403
413
|
});
|
|
414
|
+
// Remove the spy to see if that's causing the timeout
|
|
404
415
|
await newAppDevModeInterface.setup();
|
|
405
416
|
expect(installAppBrowserPrompt).toHaveBeenCalled();
|
|
406
417
|
});
|
|
@@ -28,6 +28,7 @@ vi.mock('@hubspot/local-dev-lib/config', () => ({
|
|
|
28
28
|
getAccountId: vi.fn().mockReturnValue(123),
|
|
29
29
|
hasLocalStateFlag: vi.fn().mockReturnValue(false),
|
|
30
30
|
getConfigDefaultAccount: vi.fn().mockReturnValue({ accountId: 123 }),
|
|
31
|
+
globalConfigFileExists: vi.fn().mockReturnValue(true),
|
|
31
32
|
}));
|
|
32
33
|
vi.mock('@hubspot/local-dev-lib/urls', () => ({
|
|
33
34
|
getHubSpotApiOrigin: vi.fn().mockReturnValue('https://api.hubspot.com'),
|
|
@@ -26,6 +26,7 @@ vi.mock('../deploy');
|
|
|
26
26
|
vi.mock('../config');
|
|
27
27
|
vi.mock('@hubspot/local-dev-lib/api/projects');
|
|
28
28
|
vi.mock('@hubspot/local-dev-lib/errors/index');
|
|
29
|
+
vi.mock('@hubspot/local-dev-lib/config');
|
|
29
30
|
vi.mock('../localDev/LocalDevLogger');
|
|
30
31
|
vi.mock('../localDev/DevServerManager');
|
|
31
32
|
// Tests for LocalDevProcess and LocalDevState
|
|
@@ -13,20 +13,6 @@ vi.mock('@hubspot/project-parsing-lib', () => ({
|
|
|
13
13
|
vi.mock('@hubspot/project-parsing-lib/src/lib/constants.js', () => ({
|
|
14
14
|
AppKey: 'app',
|
|
15
15
|
}));
|
|
16
|
-
vi.mock('../../../lang/en.js', () => ({
|
|
17
|
-
lib: {
|
|
18
|
-
projects: {
|
|
19
|
-
updateHsMetaFilesWithAutoGeneratedFields: {
|
|
20
|
-
header: 'Updating component metadata files...',
|
|
21
|
-
applicationLog: (type, uid, name) => `Updated ${type} component with uid: ${uid} and name: ${name}`,
|
|
22
|
-
componentLog: (type, uid) => `Updated ${type} component with uid: ${uid}`,
|
|
23
|
-
},
|
|
24
|
-
generateSafeFilenameDifferentiator: {
|
|
25
|
-
failedToCheckFiles: 'Failed to check files for filename differentiator. Falling back to timestamp.',
|
|
26
|
-
},
|
|
27
|
-
},
|
|
28
|
-
},
|
|
29
|
-
}));
|
|
30
16
|
const mockedFs = vi.mocked(fs);
|
|
31
17
|
const mockCoerceToValidUid = vi.mocked(coerceToValidUid);
|
|
32
18
|
const mockedFileExists = vi.mocked(fileExists);
|
|
@@ -247,7 +233,6 @@ describe('lib/projects/components', () => {
|
|
|
247
233
|
});
|
|
248
234
|
});
|
|
249
235
|
describe('updateHsMetaFilesWithAutoGeneratedFields()', () => {
|
|
250
|
-
const mockUiLogger = vi.mocked(uiLogger);
|
|
251
236
|
beforeEach(() => {
|
|
252
237
|
vi.resetAllMocks();
|
|
253
238
|
mockCoerceToValidUid.mockImplementation((input) => input);
|
|
@@ -282,6 +267,8 @@ describe('lib/projects/components', () => {
|
|
|
282
267
|
updateHsMetaFilesWithAutoGeneratedFields(projectName, hsMetaFilePaths);
|
|
283
268
|
expect(mockCoerceToValidUid).toHaveBeenCalledWith('my-project_card');
|
|
284
269
|
expect(mockCoerceToValidUid).toHaveBeenCalledWith('my-project_function');
|
|
270
|
+
expect(mockCoerceToValidUid).toHaveBeenCalledWith('my-project_card');
|
|
271
|
+
expect(mockCoerceToValidUid).toHaveBeenCalledWith('my-project_function');
|
|
285
272
|
expect(mockedFs.writeFileSync).toHaveBeenCalledWith('/path/to/component1.meta.json', JSON.stringify({
|
|
286
273
|
type: 'card',
|
|
287
274
|
uid: 'card_my_project',
|
|
@@ -293,9 +280,6 @@ describe('lib/projects/components', () => {
|
|
|
293
280
|
type: 'function',
|
|
294
281
|
uid: 'function_my_project',
|
|
295
282
|
}, null, 2));
|
|
296
|
-
expect(mockUiLogger.log).toHaveBeenCalledWith('Updating component metadata files...');
|
|
297
|
-
expect(mockUiLogger.log).toHaveBeenCalledWith('Updated card component with uid: card_my_project');
|
|
298
|
-
expect(mockUiLogger.log).toHaveBeenCalledWith('Updated function component with uid: function_my_project');
|
|
299
283
|
});
|
|
300
284
|
it('handles app components by updating both uid and config.name', () => {
|
|
301
285
|
const projectName = 'test-app';
|
|
@@ -321,7 +305,6 @@ describe('lib/projects/components', () => {
|
|
|
321
305
|
other: 'property',
|
|
322
306
|
},
|
|
323
307
|
}, null, 2));
|
|
324
|
-
expect(mockUiLogger.log).toHaveBeenCalledWith('Updated app component with uid: app_test_app and name: test-app-Application');
|
|
325
308
|
});
|
|
326
309
|
it('handles UID collisions by using differentiators', () => {
|
|
327
310
|
const projectName = 'collision-project';
|
|
@@ -366,8 +349,6 @@ describe('lib/projects/components', () => {
|
|
|
366
349
|
updateHsMetaFilesWithAutoGeneratedFields(projectName, hsMetaFilePaths);
|
|
367
350
|
expect(mockedFs.readFileSync).not.toHaveBeenCalled();
|
|
368
351
|
expect(mockedFs.writeFileSync).not.toHaveBeenCalled();
|
|
369
|
-
expect(mockUiLogger.log).toHaveBeenCalledWith('Updating component metadata files...');
|
|
370
|
-
expect(mockUiLogger.log).toHaveBeenCalledWith('');
|
|
371
352
|
});
|
|
372
353
|
it('handles components without config property for app type', () => {
|
|
373
354
|
const projectName = 'no-config-project';
|
|
@@ -386,7 +367,6 @@ describe('lib/projects/components', () => {
|
|
|
386
367
|
type: 'app',
|
|
387
368
|
uid: 'app_no_config_project',
|
|
388
369
|
}, null, 2));
|
|
389
|
-
expect(mockUiLogger.log).toHaveBeenCalledWith('Updated app component with uid: app_no_config_project');
|
|
390
370
|
});
|
|
391
371
|
it('replaces hyphens with underscores in coerced UIDs', () => {
|
|
392
372
|
const projectName = 'my-project';
|