@hubspot/cli 7.7.19-experimental.3 → 7.7.20-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/api/__tests__/migrate.test.d.ts +1 -0
- package/api/__tests__/migrate.test.js +183 -0
- package/commands/__tests__/account.test.d.ts +1 -0
- package/commands/__tests__/account.test.js +74 -0
- package/commands/__tests__/auth.test.d.ts +1 -0
- package/commands/__tests__/auth.test.js +43 -0
- package/commands/__tests__/cms.test.d.ts +1 -0
- package/commands/__tests__/cms.test.js +49 -0
- package/commands/__tests__/config.test.d.ts +1 -0
- package/commands/__tests__/config.test.js +49 -0
- package/commands/__tests__/create.test.d.ts +1 -0
- package/commands/__tests__/create.test.js +38 -0
- package/commands/__tests__/customObject.test.d.ts +1 -0
- package/commands/__tests__/customObject.test.js +54 -0
- package/commands/__tests__/doctor.test.d.ts +1 -0
- package/commands/__tests__/doctor.test.js +139 -0
- package/commands/__tests__/feedback.test.d.ts +1 -0
- package/commands/__tests__/feedback.test.js +62 -0
- package/commands/__tests__/fetch.test.d.ts +1 -0
- package/commands/__tests__/fetch.test.js +56 -0
- package/commands/__tests__/filemanager.test.d.ts +1 -0
- package/commands/__tests__/filemanager.test.js +50 -0
- package/commands/__tests__/function.test.d.ts +1 -0
- package/commands/__tests__/function.test.js +51 -0
- package/commands/__tests__/getStarted.test.d.ts +1 -0
- package/commands/__tests__/getStarted.test.js +170 -0
- package/commands/__tests__/hubdb.test.d.ts +1 -0
- package/commands/__tests__/hubdb.test.js +55 -0
- package/commands/__tests__/init.test.d.ts +1 -0
- package/commands/__tests__/init.test.js +47 -0
- package/commands/__tests__/lint.test.d.ts +1 -0
- package/commands/__tests__/lint.test.js +38 -0
- package/commands/__tests__/list.test.d.ts +1 -0
- package/commands/__tests__/list.test.js +47 -0
- package/commands/__tests__/logs.test.d.ts +1 -0
- package/commands/__tests__/logs.test.js +70 -0
- package/commands/__tests__/mcp.test.d.ts +1 -0
- package/commands/__tests__/mcp.test.js +51 -0
- package/commands/__tests__/mv.test.d.ts +1 -0
- package/commands/__tests__/mv.test.js +84 -0
- package/commands/__tests__/open.test.d.ts +1 -0
- package/commands/__tests__/open.test.js +96 -0
- package/commands/__tests__/project.test.d.ts +1 -0
- package/commands/__tests__/project.test.js +100 -0
- package/commands/__tests__/remove.test.d.ts +1 -0
- package/commands/__tests__/remove.test.js +77 -0
- package/commands/__tests__/sandbox.test.d.ts +1 -0
- package/commands/__tests__/sandbox.test.js +49 -0
- package/commands/__tests__/secret.test.d.ts +1 -0
- package/commands/__tests__/secret.test.js +54 -0
- package/commands/__tests__/testAccount.test.d.ts +1 -0
- package/commands/__tests__/testAccount.test.js +60 -0
- package/commands/__tests__/theme.test.d.ts +1 -0
- package/commands/__tests__/theme.test.js +52 -0
- package/commands/account/__tests__/auth.test.d.ts +1 -0
- package/commands/account/__tests__/auth.test.js +31 -0
- package/commands/account/__tests__/clean.test.d.ts +1 -0
- package/commands/account/__tests__/clean.test.js +33 -0
- package/commands/account/__tests__/createOverride.test.d.ts +1 -0
- package/commands/account/__tests__/createOverride.test.js +37 -0
- package/commands/account/__tests__/info.test.d.ts +1 -0
- package/commands/account/__tests__/info.test.js +33 -0
- package/commands/account/__tests__/list.test.d.ts +1 -0
- package/commands/account/__tests__/list.test.js +33 -0
- package/commands/account/__tests__/remove.test.d.ts +1 -0
- package/commands/account/__tests__/remove.test.js +41 -0
- package/commands/account/__tests__/removeOverride.d.ts +1 -0
- package/commands/account/__tests__/removeOverride.js +30 -0
- package/commands/account/__tests__/rename.test.d.ts +1 -0
- package/commands/account/__tests__/rename.test.js +47 -0
- package/commands/account/__tests__/use.test.d.ts +1 -0
- package/commands/account/__tests__/use.test.js +37 -0
- package/commands/app/__tests__/migrate.test.d.ts +1 -0
- package/commands/app/__tests__/migrate.test.js +129 -0
- package/commands/app/secret/__tests__/add.test.d.ts +1 -0
- package/commands/app/secret/__tests__/add.test.js +33 -0
- package/commands/app/secret/__tests__/delete.test.d.ts +1 -0
- package/commands/app/secret/__tests__/delete.test.js +33 -0
- package/commands/app/secret/__tests__/list.test.d.ts +1 -0
- package/commands/app/secret/__tests__/list.test.js +30 -0
- package/commands/app/secret/__tests__/update.test.d.ts +1 -0
- package/commands/app/secret/__tests__/update.test.js +33 -0
- package/commands/app.js +1 -6
- package/commands/customObject/__tests__/create.test.d.ts +1 -0
- package/commands/customObject/__tests__/create.test.js +45 -0
- package/commands/customObject/__tests__/schema.test.d.ts +1 -0
- package/commands/customObject/__tests__/schema.test.js +58 -0
- package/commands/customObject/schema/__tests__/create.test.d.ts +1 -0
- package/commands/customObject/schema/__tests__/create.test.js +33 -0
- package/commands/customObject/schema/__tests__/delete.test.d.ts +1 -0
- package/commands/customObject/schema/__tests__/delete.test.js +47 -0
- package/commands/customObject/schema/__tests__/fetch-all.test.d.ts +1 -0
- package/commands/customObject/schema/__tests__/fetch-all.test.js +46 -0
- package/commands/customObject/schema/__tests__/fetch.test.d.ts +1 -0
- package/commands/customObject/schema/__tests__/fetch.test.js +50 -0
- package/commands/customObject/schema/__tests__/list.test.d.ts +1 -0
- package/commands/customObject/schema/__tests__/list.test.js +34 -0
- package/commands/customObject/schema/__tests__/update.test.d.ts +1 -0
- package/commands/customObject/schema/__tests__/update.test.js +45 -0
- package/commands/fetch.js +0 -1
- package/commands/filemanager/__tests__/fetch.test.d.ts +1 -0
- package/commands/filemanager/__tests__/fetch.test.js +37 -0
- package/commands/filemanager/__tests__/upload.test.d.ts +1 -0
- package/commands/filemanager/__tests__/upload.test.js +35 -0
- package/commands/hubdb/__tests__/clear.test.d.ts +1 -0
- package/commands/hubdb/__tests__/clear.test.js +33 -0
- package/commands/hubdb/__tests__/create.test.d.ts +1 -0
- package/commands/hubdb/__tests__/create.test.js +33 -0
- package/commands/hubdb/__tests__/delete.test.d.ts +1 -0
- package/commands/hubdb/__tests__/delete.test.js +33 -0
- package/commands/hubdb/__tests__/fetch.test.d.ts +1 -0
- package/commands/hubdb/__tests__/fetch.test.js +33 -0
- package/commands/hubdb/__tests__/list.test.d.ts +1 -0
- package/commands/hubdb/__tests__/list.test.js +101 -0
- package/commands/logs.js +0 -1
- package/commands/mcp/__tests__/setup.test.d.ts +1 -0
- package/commands/mcp/__tests__/setup.test.js +31 -0
- package/commands/mcp/__tests__/start.test.d.ts +1 -0
- package/commands/mcp/__tests__/start.test.js +32 -0
- package/commands/project/__tests__/add.test.d.ts +1 -0
- package/commands/project/__tests__/add.test.js +48 -0
- package/commands/project/__tests__/create.test.d.ts +1 -0
- package/commands/project/__tests__/create.test.js +45 -0
- package/commands/project/__tests__/deploy.test.d.ts +1 -0
- package/commands/project/__tests__/deploy.test.js +344 -0
- package/commands/project/__tests__/devUnifiedFlow.test.d.ts +1 -0
- package/commands/project/__tests__/devUnifiedFlow.test.js +419 -0
- package/commands/project/__tests__/download.test.d.ts +1 -0
- package/commands/project/__tests__/download.test.js +44 -0
- package/commands/project/__tests__/fixtures/exampleProject.json +33 -0
- package/commands/project/__tests__/installDeps.test.d.ts +1 -0
- package/commands/project/__tests__/installDeps.test.js +180 -0
- package/commands/project/__tests__/listBuilds.test.d.ts +1 -0
- package/commands/project/__tests__/listBuilds.test.js +43 -0
- package/commands/project/__tests__/logs.test.d.ts +1 -0
- package/commands/project/__tests__/logs.test.js +246 -0
- package/commands/project/__tests__/migrate.test.d.ts +1 -0
- package/commands/project/__tests__/migrate.test.js +116 -0
- package/commands/project/__tests__/migrateApp.test.d.ts +1 -0
- package/commands/project/__tests__/migrateApp.test.js +87 -0
- package/commands/project/__tests__/open.test.d.ts +1 -0
- package/commands/project/__tests__/open.test.js +44 -0
- package/commands/project/__tests__/profile.test.d.ts +1 -0
- package/commands/project/__tests__/profile.test.js +47 -0
- package/commands/project/__tests__/upload.test.d.ts +1 -0
- package/commands/project/__tests__/upload.test.js +48 -0
- package/commands/project/__tests__/watch.test.d.ts +1 -0
- package/commands/project/__tests__/watch.test.js +40 -0
- package/commands/project/dev/unifiedFlow.js +1 -1
- package/commands/sandbox/__tests__/create.test.d.ts +1 -0
- package/commands/sandbox/__tests__/create.test.js +36 -0
- package/commands/sandbox/__tests__/delete.test.d.ts +1 -0
- package/commands/sandbox/__tests__/delete.test.js +36 -0
- package/commands/secret/__tests__/addSecret.test.d.ts +1 -0
- package/commands/secret/__tests__/addSecret.test.js +34 -0
- package/commands/secret/__tests__/deleteSecret.test.d.ts +1 -0
- package/commands/secret/__tests__/deleteSecret.test.js +46 -0
- package/commands/secret/__tests__/listSecret.test.d.ts +1 -0
- package/commands/secret/__tests__/listSecret.test.js +34 -0
- package/commands/secret/__tests__/updateSecret.test.d.ts +1 -0
- package/commands/secret/__tests__/updateSecret.test.js +34 -0
- package/commands/testAccount/__tests__/create.test.d.ts +1 -0
- package/commands/testAccount/__tests__/create.test.js +38 -0
- package/commands/testAccount/__tests__/createConfig.test.d.ts +1 -0
- package/commands/testAccount/__tests__/createConfig.test.js +40 -0
- package/commands/testAccount/__tests__/delete.test.d.ts +1 -0
- package/commands/testAccount/__tests__/delete.test.js +36 -0
- package/commands/testAccount/create.js +24 -14
- package/commands/theme/__tests__/generate-selectors.test.d.ts +1 -0
- package/commands/theme/__tests__/generate-selectors.test.js +33 -0
- package/commands/theme/__tests__/marketplace-validate.test.d.ts +1 -0
- package/commands/theme/__tests__/marketplace-validate.test.js +41 -0
- package/commands/theme/__tests__/preview.test.d.ts +1 -0
- package/commands/theme/__tests__/preview.test.js +65 -0
- package/lang/en.d.ts +6 -65
- package/lang/en.js +6 -65
- package/lib/__tests__/accountTypes.test.d.ts +1 -0
- package/lib/__tests__/accountTypes.test.js +100 -0
- package/lib/__tests__/buildAccount.test.d.ts +1 -0
- package/lib/__tests__/buildAccount.test.js +231 -0
- package/lib/__tests__/commonOpts.test.d.ts +1 -0
- package/lib/__tests__/commonOpts.test.js +87 -0
- package/lib/__tests__/dependencyManagement.test.d.ts +1 -0
- package/lib/__tests__/dependencyManagement.test.js +180 -0
- package/lib/__tests__/developerTestAccounts.test.d.ts +1 -0
- package/lib/__tests__/developerTestAccounts.test.js +180 -0
- package/lib/__tests__/hasFeature.test.d.ts +1 -0
- package/lib/__tests__/hasFeature.test.js +37 -0
- package/lib/__tests__/npm.test.d.ts +1 -0
- package/lib/__tests__/npm.test.js +62 -0
- package/lib/__tests__/oauth.test.d.ts +1 -0
- package/lib/__tests__/oauth.test.js +113 -0
- package/lib/__tests__/parsing.test.d.ts +1 -0
- package/lib/__tests__/parsing.test.js +36 -0
- package/lib/__tests__/polling.test.d.ts +1 -0
- package/lib/__tests__/polling.test.js +78 -0
- package/lib/__tests__/process.test.d.ts +1 -0
- package/lib/__tests__/process.test.js +90 -0
- package/lib/__tests__/projectProfiles.test.d.ts +1 -0
- package/lib/__tests__/projectProfiles.test.js +134 -0
- package/lib/__tests__/sandboxSync.test.d.ts +1 -0
- package/lib/__tests__/sandboxSync.test.js +131 -0
- package/lib/__tests__/sandboxes.test.d.ts +1 -0
- package/lib/__tests__/sandboxes.test.js +148 -0
- package/lib/__tests__/serverlessLogs.test.d.ts +1 -0
- package/lib/__tests__/serverlessLogs.test.js +154 -0
- package/lib/__tests__/usageTracking.test.d.ts +1 -0
- package/lib/__tests__/usageTracking.test.js +171 -0
- package/lib/__tests__/validation.test.d.ts +1 -0
- package/lib/__tests__/validation.test.js +145 -0
- package/lib/__tests__/yargsUtils.test.d.ts +1 -0
- package/lib/__tests__/yargsUtils.test.js +74 -0
- package/lib/app/__tests__/migrate.test.d.ts +1 -0
- package/lib/app/__tests__/migrate.test.js +495 -0
- package/lib/app/__tests__/migrate_legacy.test.d.ts +1 -0
- package/lib/app/__tests__/migrate_legacy.test.js +136 -0
- package/lib/buildAccount.d.ts +1 -7
- package/lib/buildAccount.js +4 -54
- package/lib/doctor/Diagnosis.js +11 -11
- package/lib/doctor/Doctor.js +42 -42
- package/lib/doctor/__tests__/Diagnosis.test.d.ts +1 -0
- package/lib/doctor/__tests__/Diagnosis.test.js +87 -0
- package/lib/doctor/__tests__/DiagnosticInfoBuilder.test.d.ts +1 -0
- package/lib/doctor/__tests__/DiagnosticInfoBuilder.test.js +172 -0
- package/lib/doctor/__tests__/Doctor.test.d.ts +1 -0
- package/lib/doctor/__tests__/Doctor.test.js +398 -0
- package/lib/mcp/setup.js +18 -2
- package/lib/middleware/__test__/configMiddleware.test.js +12 -12
- package/lib/middleware/__test__/gitMiddleware.test.js +4 -4
- package/lib/middleware/__test__/notificationsMiddleware.test.js +2 -2
- package/lib/middleware/__test__/requestMiddleware.test.js +2 -2
- package/lib/middleware/__test__/yargsChecksMiddleware.test.js +7 -7
- package/lib/middleware/notificationsMiddleware.js +16 -13
- package/lib/projects/__tests__/AppDevModeInterface.test.d.ts +1 -0
- package/lib/projects/__tests__/AppDevModeInterface.test.js +517 -0
- package/lib/projects/__tests__/LocalDevProcess.test.d.ts +1 -0
- package/lib/projects/__tests__/LocalDevProcess.test.js +314 -0
- package/lib/projects/__tests__/LocalDevWebsocketServer.test.d.ts +1 -0
- package/lib/projects/__tests__/LocalDevWebsocketServer.test.js +175 -0
- package/lib/projects/__tests__/ProjectLogsManager.test.d.ts +1 -0
- package/lib/projects/__tests__/ProjectLogsManager.test.js +191 -0
- package/lib/projects/__tests__/buildAndDeploy.test.d.ts +1 -0
- package/lib/projects/__tests__/buildAndDeploy.test.js +25 -0
- package/lib/projects/__tests__/components.test.d.ts +1 -0
- package/lib/projects/__tests__/components.test.js +186 -0
- package/lib/projects/__tests__/projects.test.d.ts +1 -0
- package/lib/projects/__tests__/projects.test.js +89 -0
- package/lib/projects/__tests__/structure.test.d.ts +1 -0
- package/lib/projects/__tests__/structure.test.js +249 -0
- package/lib/projects/add/__tests__/legacyAddComponent.test.d.ts +1 -0
- package/lib/projects/add/__tests__/legacyAddComponent.test.js +206 -0
- package/lib/projects/add/__tests__/v3AddComponent.test.d.ts +1 -0
- package/lib/projects/add/__tests__/v3AddComponent.test.js +190 -0
- package/lib/projects/create/__tests__/legacy.test.d.ts +1 -0
- package/lib/projects/create/__tests__/legacy.test.js +126 -0
- package/lib/projects/create/__tests__/v3.test.d.ts +1 -0
- package/lib/projects/create/__tests__/v3.test.js +80 -0
- package/lib/projects/localDev/DevServerManager.js +0 -1
- package/lib/projects/localDev/helpers.d.ts +1 -1
- package/lib/projects/localDev/helpers.js +2 -2
- package/lib/projects/structure.d.ts +2 -2
- package/lib/projects/upload.d.ts +1 -2
- package/lib/projects/upload.js +0 -1
- package/lib/prompts/__tests__/downloadProjectPrompt.test.d.ts +1 -0
- package/lib/prompts/__tests__/downloadProjectPrompt.test.js +30 -0
- package/lib/prompts/__tests__/projectsLogsPrompt.test.d.ts +1 -0
- package/lib/prompts/__tests__/projectsLogsPrompt.test.js +42 -0
- package/lib/prompts/createDeveloperTestAccountConfigPrompt.d.ts +10 -9
- package/lib/prompts/createDeveloperTestAccountConfigPrompt.js +43 -81
- package/lib/schema.js +5 -1
- package/lib/ui/SpinniesManager.js +0 -1
- package/lib/ui/supportHyperlinks.js +2 -2
- package/lib/ui/supportsColor.js +2 -2
- package/lib/utils/hasFlag.d.ts +1 -0
- package/lib/utils/hasFlag.js +15 -0
- package/lib/yargsUtils.d.ts +2 -1
- package/lib/yargsUtils.js +3 -13
- package/mcp-server/tools/project/__tests__/AddFeatureToProject.test.d.ts +1 -0
- package/mcp-server/tools/project/__tests__/AddFeatureToProject.test.js +152 -0
- package/mcp-server/tools/project/__tests__/CreateProjectTool.test.d.ts +1 -0
- package/mcp-server/tools/project/__tests__/CreateProjectTool.test.js +129 -0
- package/mcp-server/tools/project/__tests__/DeployProject.test.d.ts +1 -0
- package/mcp-server/tools/project/__tests__/DeployProject.test.js +120 -0
- package/mcp-server/tools/project/__tests__/GuidedWalkthroughTool.test.d.ts +1 -0
- package/mcp-server/tools/project/__tests__/GuidedWalkthroughTool.test.js +127 -0
- package/mcp-server/tools/project/__tests__/UploadProjectTools.test.d.ts +1 -0
- package/mcp-server/tools/project/__tests__/UploadProjectTools.test.js +108 -0
- package/mcp-server/tools/project/__tests__/ValidateProjectTool.test.d.ts +1 -0
- package/mcp-server/tools/project/__tests__/ValidateProjectTool.test.js +111 -0
- package/mcp-server/utils/__tests__/command.test.d.ts +1 -0
- package/mcp-server/utils/__tests__/command.test.js +47 -0
- package/mcp-server/utils/__tests__/project.test.d.ts +1 -0
- package/mcp-server/utils/__tests__/project.test.js +81 -0
- package/package.json +8 -8
- package/commands/app/install.d.ts +0 -8
- package/commands/app/install.js +0 -127
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const util_1 = __importDefault(require("util"));
|
|
7
|
+
const vitest_1 = require("vitest");
|
|
8
|
+
vitest_1.vi.mock('@hubspot/local-dev-lib/fs');
|
|
9
|
+
vitest_1.vi.mock('@hubspot/local-dev-lib/config');
|
|
10
|
+
vitest_1.vi.mock('@hubspot/local-dev-lib/personalAccessKey');
|
|
11
|
+
vitest_1.vi.mock('../../projects/config');
|
|
12
|
+
vitest_1.vi.mock('@hubspot/local-dev-lib/api/projects');
|
|
13
|
+
vitest_1.vi.mock('util');
|
|
14
|
+
vitest_1.vi.mock('../../../package.json', () => {
|
|
15
|
+
return {
|
|
16
|
+
default: {
|
|
17
|
+
version: '1.0.0',
|
|
18
|
+
},
|
|
19
|
+
};
|
|
20
|
+
});
|
|
21
|
+
const DiagnosticInfoBuilder_1 = require("../DiagnosticInfoBuilder");
|
|
22
|
+
const config_1 = require("@hubspot/local-dev-lib/config");
|
|
23
|
+
const personalAccessKey_1 = require("@hubspot/local-dev-lib/personalAccessKey");
|
|
24
|
+
const fs_1 = require("@hubspot/local-dev-lib/fs");
|
|
25
|
+
const config_2 = require("../../projects/config");
|
|
26
|
+
const projects_1 = require("@hubspot/local-dev-lib/api/projects");
|
|
27
|
+
const walk = fs_1.walk;
|
|
28
|
+
const getAccessToken = personalAccessKey_1.getAccessToken;
|
|
29
|
+
const getAccountConfig = config_1.getAccountConfig;
|
|
30
|
+
const getConfigPath = config_1.getConfigPath;
|
|
31
|
+
const getDefaultAccountOverrideFilePath = config_1.getDefaultAccountOverrideFilePath;
|
|
32
|
+
const getAccountId = config_1.getAccountId;
|
|
33
|
+
const getProjectConfig = config_2.getProjectConfig;
|
|
34
|
+
const isConfigFlagEnabled = config_1.isConfigFlagEnabled;
|
|
35
|
+
const fetchProject = projects_1.fetchProject;
|
|
36
|
+
const mockPromisifyImpl = vitest_1.vi.fn();
|
|
37
|
+
const utilPromisify = vitest_1.vi.fn(() => mockPromisifyImpl);
|
|
38
|
+
util_1.default.promisify = utilPromisify;
|
|
39
|
+
describe('lib/doctor/DiagnosticInfo', () => {
|
|
40
|
+
const accountId = 898989;
|
|
41
|
+
const accountConfig = {
|
|
42
|
+
env: 'prod',
|
|
43
|
+
authType: 'personalaccesskey',
|
|
44
|
+
accountType: 'STANDARD',
|
|
45
|
+
personalAccessKey: 'super-secret-key',
|
|
46
|
+
};
|
|
47
|
+
const nodeVersion = 'v18.17.0';
|
|
48
|
+
const processInfo = {
|
|
49
|
+
platform: 'darwin',
|
|
50
|
+
arch: 'x64',
|
|
51
|
+
versions: { node: nodeVersion },
|
|
52
|
+
mainModule: { path: '/path/to/main/module' },
|
|
53
|
+
};
|
|
54
|
+
const projectDir = '/Users/test/project';
|
|
55
|
+
const projectFiles = [
|
|
56
|
+
`${projectDir}/.gitignore`,
|
|
57
|
+
`${projectDir}/README.md`,
|
|
58
|
+
// Config files
|
|
59
|
+
`${projectDir}/hsproject.json`,
|
|
60
|
+
`${projectDir}/src/app/app.json`,
|
|
61
|
+
`${projectDir}/src/app/public-app.json`,
|
|
62
|
+
// Serverless files
|
|
63
|
+
`${projectDir}/src/app/app.functions/.env`,
|
|
64
|
+
`${projectDir}/src/app/app.functions/function.js`,
|
|
65
|
+
`${projectDir}/src/app/app.functions/serverless.json`,
|
|
66
|
+
`${projectDir}/src/app/app.functions/package.json`,
|
|
67
|
+
`${projectDir}/src/app/app.functions/package-lock.json`,
|
|
68
|
+
// Extension files
|
|
69
|
+
`${projectDir}/src/app/extensions/extension.js`,
|
|
70
|
+
`${projectDir}/src/app/extensions/extension.json`,
|
|
71
|
+
`${projectDir}/src/app/extensions/package.json`,
|
|
72
|
+
`${projectDir}/src/app/extension/package-lock.json`,
|
|
73
|
+
`${projectDir}/src/app/app.functions/node_modules/axios`,
|
|
74
|
+
];
|
|
75
|
+
const npmVersion = 'v8.17.0';
|
|
76
|
+
const configPath = '/path/to/config';
|
|
77
|
+
const defaultAccountOverrideFile = 'path/to/default/account/override/.hsaccount';
|
|
78
|
+
beforeEach(() => {
|
|
79
|
+
getAccountId.mockReturnValue(accountId);
|
|
80
|
+
getAccountConfig.mockReturnValue(accountConfig);
|
|
81
|
+
walk.mockResolvedValue(projectFiles);
|
|
82
|
+
isConfigFlagEnabled.mockReturnValue(false);
|
|
83
|
+
mockPromisifyImpl.mockResolvedValue(npmVersion);
|
|
84
|
+
});
|
|
85
|
+
it('should initialize the required state on creation', () => {
|
|
86
|
+
const builder = new DiagnosticInfoBuilder_1.DiagnosticInfoBuilder(processInfo);
|
|
87
|
+
expect(getAccountId).toHaveBeenCalledTimes(1);
|
|
88
|
+
expect(getAccountConfig).toHaveBeenCalledTimes(1);
|
|
89
|
+
expect(builder.accountId).toEqual(accountId);
|
|
90
|
+
expect(builder.env).toEqual(accountConfig.env);
|
|
91
|
+
expect(builder.authType).toEqual(accountConfig.authType);
|
|
92
|
+
expect(builder.accountType).toEqual(accountConfig.accountType);
|
|
93
|
+
expect(builder.personalAccessKey).toEqual(accountConfig.personalAccessKey);
|
|
94
|
+
expect(builder.processInfo).toEqual(processInfo);
|
|
95
|
+
});
|
|
96
|
+
describe('generateDiagnosticInfo', () => {
|
|
97
|
+
let builder;
|
|
98
|
+
let projectConfig;
|
|
99
|
+
let projectDetails;
|
|
100
|
+
let accessToken;
|
|
101
|
+
beforeEach(() => {
|
|
102
|
+
builder = new DiagnosticInfoBuilder_1.DiagnosticInfoBuilder(processInfo);
|
|
103
|
+
projectConfig = {
|
|
104
|
+
projectDir,
|
|
105
|
+
projectConfig: {
|
|
106
|
+
name: 'My project',
|
|
107
|
+
srcDir: 'project-dir',
|
|
108
|
+
platformVersion: 'test',
|
|
109
|
+
},
|
|
110
|
+
};
|
|
111
|
+
projectDetails = {
|
|
112
|
+
createdAt: 12345,
|
|
113
|
+
deletedAt: 0,
|
|
114
|
+
deployedBuildId: 1,
|
|
115
|
+
id: 8989898,
|
|
116
|
+
isLocked: false,
|
|
117
|
+
name: projectConfig.projectConfig.name,
|
|
118
|
+
portalId: accountId,
|
|
119
|
+
updatedAt: 12345,
|
|
120
|
+
};
|
|
121
|
+
accessToken = {
|
|
122
|
+
accessToken: 'super-secret-dont-put-this-in-a-unit-test',
|
|
123
|
+
accountType: 'STANDARD',
|
|
124
|
+
encodedOAuthRefreshToken: '',
|
|
125
|
+
expiresAt: '',
|
|
126
|
+
hubName: projectConfig.projectConfig.name,
|
|
127
|
+
portalId: accountId,
|
|
128
|
+
scopeGroups: [],
|
|
129
|
+
enabledFeatures: {},
|
|
130
|
+
};
|
|
131
|
+
getProjectConfig.mockResolvedValue(projectConfig);
|
|
132
|
+
// @ts-expect-error - Mocking AxiosResponse
|
|
133
|
+
fetchProject.mockResolvedValue({
|
|
134
|
+
data: projectDetails,
|
|
135
|
+
});
|
|
136
|
+
getAccessToken.mockResolvedValue(accessToken);
|
|
137
|
+
getConfigPath.mockReturnValue(configPath);
|
|
138
|
+
getDefaultAccountOverrideFilePath.mockReturnValue(defaultAccountOverrideFile);
|
|
139
|
+
});
|
|
140
|
+
it('should gather the required data and generate the diagnostic', async () => {
|
|
141
|
+
const diagnosticInfo = await builder.generateDiagnosticInfo();
|
|
142
|
+
expect(getProjectConfig).toHaveBeenCalledTimes(1);
|
|
143
|
+
expect(fetchProject).toHaveBeenCalledTimes(1);
|
|
144
|
+
expect(fetchProject).toHaveBeenCalledWith(accountId, projectConfig.projectConfig.name);
|
|
145
|
+
expect(getAccessToken).toHaveBeenCalledTimes(1);
|
|
146
|
+
expect(getAccessToken).toHaveBeenCalledWith(accountConfig.personalAccessKey, accountConfig.env, accountId);
|
|
147
|
+
// @ts-expect-error Accessing private field
|
|
148
|
+
expect(builder._projectConfig).toEqual(projectConfig);
|
|
149
|
+
expect(diagnosticInfo).toMatchSnapshot();
|
|
150
|
+
});
|
|
151
|
+
it('should handle errors when fetching project details', async () => {
|
|
152
|
+
fetchProject.mockRejectedValue(new Error('Failed to fetch project details'));
|
|
153
|
+
const diagnosticInfo = await builder.generateDiagnosticInfo();
|
|
154
|
+
expect(fetchProject).toHaveBeenCalledTimes(1);
|
|
155
|
+
expect(diagnosticInfo.project.details).toBeUndefined();
|
|
156
|
+
});
|
|
157
|
+
it('should handle errors when fetching access token', async () => {
|
|
158
|
+
getAccessToken.mockRejectedValue(new Error('Failed to fetch access token'));
|
|
159
|
+
const diagnosticInfo = await builder.generateDiagnosticInfo();
|
|
160
|
+
expect(getAccessToken).toHaveBeenCalledTimes(1);
|
|
161
|
+
expect(diagnosticInfo.account.name).toBeUndefined();
|
|
162
|
+
expect(diagnosticInfo.account.scopeGroups).toBeUndefined();
|
|
163
|
+
expect(diagnosticInfo.account.enabledFeatures).toBeUndefined();
|
|
164
|
+
});
|
|
165
|
+
it('should handle errors when fetching project filenames', async () => {
|
|
166
|
+
walk.mockRejectedValue(new Error('Failed to walk project directory'));
|
|
167
|
+
const diagnosticInfo = await builder.generateDiagnosticInfo();
|
|
168
|
+
expect(walk).toHaveBeenCalledTimes(1);
|
|
169
|
+
expect(diagnosticInfo.files).toEqual([]);
|
|
170
|
+
});
|
|
171
|
+
});
|
|
172
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,398 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const Doctor_1 = require("../Doctor");
|
|
4
|
+
const dependencyManagement_1 = require("../../dependencyManagement");
|
|
5
|
+
const portManager_1 = require("@hubspot/local-dev-lib/portManager");
|
|
6
|
+
const personalAccessKey_1 = require("@hubspot/local-dev-lib/personalAccessKey");
|
|
7
|
+
const HubSpotHttpError_1 = require("@hubspot/local-dev-lib/models/HubSpotHttpError");
|
|
8
|
+
const axios_1 = require("axios");
|
|
9
|
+
const index_1 = require("@hubspot/local-dev-lib/errors/index");
|
|
10
|
+
const util_1 = require("util");
|
|
11
|
+
vi.mock('@hubspot/local-dev-lib/logger');
|
|
12
|
+
vi.mock('../Diagnosis');
|
|
13
|
+
vi.mock('../../ui/SpinniesManager');
|
|
14
|
+
vi.mock('../DiagnosticInfoBuilder');
|
|
15
|
+
vi.mock('../../dependencyManagement');
|
|
16
|
+
vi.mock('../../npm');
|
|
17
|
+
vi.mock('@hubspot/local-dev-lib/portManager');
|
|
18
|
+
vi.mock('@hubspot/local-dev-lib/personalAccessKey');
|
|
19
|
+
vi.mock('@hubspot/local-dev-lib/errors/index');
|
|
20
|
+
vi.mock('util');
|
|
21
|
+
const hasMissingPackages = vi.mocked(dependencyManagement_1.hasMissingPackages);
|
|
22
|
+
const isPortManagerPortAvailable = vi.mocked(portManager_1.isPortManagerPortAvailable);
|
|
23
|
+
const utilPromisify = vi.mocked(util_1.promisify);
|
|
24
|
+
const accessTokenForPersonalAccessKey = vi.mocked(personalAccessKey_1.accessTokenForPersonalAccessKey);
|
|
25
|
+
const authorizedScopesForPortalAndUser = vi.mocked(personalAccessKey_1.authorizedScopesForPortalAndUser);
|
|
26
|
+
const scopesOnAccessToken = vi.mocked(personalAccessKey_1.scopesOnAccessToken);
|
|
27
|
+
const isSpecifiedError = vi.mocked(index_1.isSpecifiedError);
|
|
28
|
+
describe('lib/doctor/Doctor', () => {
|
|
29
|
+
let doctor;
|
|
30
|
+
// @ts-ignore
|
|
31
|
+
const diagnosticInfo = {
|
|
32
|
+
account: {},
|
|
33
|
+
arch: 'x64',
|
|
34
|
+
config: 'path/to/config',
|
|
35
|
+
configSettings: { httpUseLocalhost: false },
|
|
36
|
+
configFiles: ['src/serverless.json'],
|
|
37
|
+
diagnosis: '',
|
|
38
|
+
envFiles: [],
|
|
39
|
+
files: [],
|
|
40
|
+
jsonFiles: ['src/serverless.json', 'src/extension.json'],
|
|
41
|
+
packageFiles: ['src/package.json'],
|
|
42
|
+
packageLockFiles: ['src/package-lock.json'],
|
|
43
|
+
path: '',
|
|
44
|
+
platform: 'darwin',
|
|
45
|
+
project: {
|
|
46
|
+
config: {
|
|
47
|
+
projectDir: '/path/to/project',
|
|
48
|
+
projectConfig: {
|
|
49
|
+
name: 'my-project',
|
|
50
|
+
srcDir: '/path/to/project',
|
|
51
|
+
platformVersion: 'test',
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
versions: {
|
|
56
|
+
node: '18.1.2',
|
|
57
|
+
'@hubspot/cli': '6.0.0',
|
|
58
|
+
npm: '6.14.13',
|
|
59
|
+
},
|
|
60
|
+
};
|
|
61
|
+
beforeEach(() => {
|
|
62
|
+
doctor = new Doctor_1.Doctor({
|
|
63
|
+
generateDiagnosticInfo: vi.fn().mockResolvedValue({
|
|
64
|
+
...diagnosticInfo,
|
|
65
|
+
}),
|
|
66
|
+
});
|
|
67
|
+
utilPromisify.mockReturnValue(vi.fn().mockImplementation((filename) => {
|
|
68
|
+
if (filename.includes('invalid')) {
|
|
69
|
+
return 'not-valid-json';
|
|
70
|
+
}
|
|
71
|
+
return JSON.stringify({ valid: true });
|
|
72
|
+
}));
|
|
73
|
+
});
|
|
74
|
+
afterEach(() => {
|
|
75
|
+
vi.clearAllMocks();
|
|
76
|
+
});
|
|
77
|
+
describe('CLI Checks', () => {
|
|
78
|
+
describe('node version', () => {
|
|
79
|
+
it('should add success section if node version is valid', async () => {
|
|
80
|
+
await doctor.diagnose();
|
|
81
|
+
// @ts-expect-error Testing private method
|
|
82
|
+
expect(doctor.diagnosis.addCliSection).toHaveBeenCalledWith({
|
|
83
|
+
type: 'success',
|
|
84
|
+
message: `node v${diagnosticInfo.versions.node} is installed`,
|
|
85
|
+
});
|
|
86
|
+
});
|
|
87
|
+
it('should add error section if node version is not available', async () => {
|
|
88
|
+
doctor = new Doctor_1.Doctor({
|
|
89
|
+
generateDiagnosticInfo: vi.fn().mockResolvedValue({
|
|
90
|
+
...diagnosticInfo,
|
|
91
|
+
versions: {},
|
|
92
|
+
}),
|
|
93
|
+
});
|
|
94
|
+
await doctor.diagnose();
|
|
95
|
+
// @ts-expect-error Testing private method
|
|
96
|
+
expect(doctor.diagnosis.addCliSection).toHaveBeenCalledWith({
|
|
97
|
+
type: 'error',
|
|
98
|
+
message: 'Unable to determine what version of node is installed',
|
|
99
|
+
});
|
|
100
|
+
});
|
|
101
|
+
it('should add error section if minimum node version is not met', async () => {
|
|
102
|
+
doctor = new Doctor_1.Doctor({
|
|
103
|
+
generateDiagnosticInfo: vi.fn().mockResolvedValue({
|
|
104
|
+
...diagnosticInfo,
|
|
105
|
+
versions: { node: '1.0.0' },
|
|
106
|
+
}),
|
|
107
|
+
});
|
|
108
|
+
await doctor.diagnose();
|
|
109
|
+
// @ts-expect-error Testing private method
|
|
110
|
+
expect(doctor.diagnosis.addCliSection).toHaveBeenCalledWith({
|
|
111
|
+
type: 'warning',
|
|
112
|
+
message: expect.stringMatching(/Minimum Node version is not met/),
|
|
113
|
+
});
|
|
114
|
+
});
|
|
115
|
+
});
|
|
116
|
+
describe('npm version', () => {
|
|
117
|
+
it('should add success section if npm is installed', async () => {
|
|
118
|
+
await doctor.diagnose();
|
|
119
|
+
// @ts-expect-error Testing private method
|
|
120
|
+
expect(doctor.diagnosis.addCliSection).toHaveBeenCalledWith({
|
|
121
|
+
type: 'success',
|
|
122
|
+
message: `npm v${diagnosticInfo.versions.npm} is installed`,
|
|
123
|
+
});
|
|
124
|
+
});
|
|
125
|
+
it('should add error section if npm is not installed', async () => {
|
|
126
|
+
doctor = new Doctor_1.Doctor({
|
|
127
|
+
generateDiagnosticInfo: vi.fn().mockResolvedValue({
|
|
128
|
+
...diagnosticInfo,
|
|
129
|
+
versions: {},
|
|
130
|
+
}),
|
|
131
|
+
});
|
|
132
|
+
await doctor.diagnose();
|
|
133
|
+
// @ts-expect-error Testing private method
|
|
134
|
+
expect(doctor.diagnosis.addCliSection).toHaveBeenCalledWith({
|
|
135
|
+
type: 'error',
|
|
136
|
+
message: expect.any(String),
|
|
137
|
+
});
|
|
138
|
+
});
|
|
139
|
+
});
|
|
140
|
+
});
|
|
141
|
+
describe('CLI Config Checks', () => {
|
|
142
|
+
describe('Personal Access Key', () => {
|
|
143
|
+
it('should add success sections if the access token is valid', async () => {
|
|
144
|
+
scopesOnAccessToken.mockResolvedValueOnce(['scope1']);
|
|
145
|
+
authorizedScopesForPortalAndUser.mockResolvedValueOnce([
|
|
146
|
+
{
|
|
147
|
+
scopeGroup: {
|
|
148
|
+
name: 'scope1',
|
|
149
|
+
shortDescription: 'scope1',
|
|
150
|
+
longDescription: 'scope1',
|
|
151
|
+
},
|
|
152
|
+
portalAuthorized: true,
|
|
153
|
+
userAuthorized: true,
|
|
154
|
+
},
|
|
155
|
+
]);
|
|
156
|
+
await doctor.diagnose();
|
|
157
|
+
// @ts-expect-error Testing private method
|
|
158
|
+
expect(doctor.diagnosis.addCLIConfigSection).toHaveBeenCalledWith({
|
|
159
|
+
type: 'success',
|
|
160
|
+
message: 'Default account active',
|
|
161
|
+
});
|
|
162
|
+
// @ts-expect-error Testing private method
|
|
163
|
+
expect(doctor.diagnosis.addCLIConfigSection).toHaveBeenCalledWith({
|
|
164
|
+
type: 'success',
|
|
165
|
+
message: expect.stringMatching(/Personal Access Key is valid./),
|
|
166
|
+
});
|
|
167
|
+
});
|
|
168
|
+
it('should add an error section if it is unable to determine if the portal is active', async () => {
|
|
169
|
+
accessTokenForPersonalAccessKey.mockRejectedValueOnce(new HubSpotHttpError_1.HubSpotHttpError('Invalid token', { cause: new axios_1.AxiosError() }));
|
|
170
|
+
await doctor.diagnose();
|
|
171
|
+
// @ts-expect-error Testing private method
|
|
172
|
+
expect(doctor.diagnosis.addCLIConfigSection).toHaveBeenCalledWith({
|
|
173
|
+
type: 'error',
|
|
174
|
+
message: 'Unable to determine if the portal is active',
|
|
175
|
+
});
|
|
176
|
+
});
|
|
177
|
+
it('should add an error section if the portal is inactive', async () => {
|
|
178
|
+
accessTokenForPersonalAccessKey.mockRejectedValueOnce(new HubSpotHttpError_1.HubSpotHttpError('Invalid token'));
|
|
179
|
+
isSpecifiedError.mockImplementation((err, fields) => {
|
|
180
|
+
return (fields.statusCode === 401 &&
|
|
181
|
+
fields.category === 'INVALID_AUTHENTICATION' &&
|
|
182
|
+
fields?.subCategory === 'LocalDevAuthErrorType.PORTAL_NOT_ACTIVE');
|
|
183
|
+
});
|
|
184
|
+
await doctor.diagnose();
|
|
185
|
+
// @ts-expect-error Testing private method
|
|
186
|
+
expect(doctor.diagnosis.addCLIConfigSection).toHaveBeenCalledWith({
|
|
187
|
+
type: 'error',
|
|
188
|
+
message: "Default account isn't active",
|
|
189
|
+
secondaryMessaging: expect.stringMatching(/to remove inactive accounts from your CLI config/),
|
|
190
|
+
});
|
|
191
|
+
});
|
|
192
|
+
it('should add an error section if the portal is not found', async () => {
|
|
193
|
+
accessTokenForPersonalAccessKey.mockRejectedValueOnce(new HubSpotHttpError_1.HubSpotHttpError('Not found'));
|
|
194
|
+
isSpecifiedError.mockImplementation((err, fields) => {
|
|
195
|
+
return (fields.statusCode === 404 &&
|
|
196
|
+
fields.category === 'INVALID_AUTHENTICATION' &&
|
|
197
|
+
fields?.subCategory === 'LocalDevAuthErrorType.INVALID_PORTAL_ID');
|
|
198
|
+
});
|
|
199
|
+
await doctor.diagnose();
|
|
200
|
+
// @ts-expect-error Testing private method
|
|
201
|
+
expect(doctor.diagnosis.addCLIConfigSection).toHaveBeenCalledWith({
|
|
202
|
+
type: 'error',
|
|
203
|
+
message: "Default account isn't active",
|
|
204
|
+
secondaryMessaging: expect.stringMatching(/to remove inactive accounts from your CLI config/),
|
|
205
|
+
});
|
|
206
|
+
});
|
|
207
|
+
it('should add multiple sections if token is invalid but the portal is active', async () => {
|
|
208
|
+
accessTokenForPersonalAccessKey.mockRejectedValueOnce(new HubSpotHttpError_1.HubSpotHttpError('Not found'));
|
|
209
|
+
isSpecifiedError.mockImplementation((err, fields) => {
|
|
210
|
+
return (fields.statusCode === 401 &&
|
|
211
|
+
fields.category === 'INVALID_AUTHENTICATION' &&
|
|
212
|
+
fields?.subCategory ===
|
|
213
|
+
'LocalDevAuthErrorType.FAILED_TO_SIGN_REFRESH_TOKEN_DECODE');
|
|
214
|
+
});
|
|
215
|
+
await doctor.diagnose();
|
|
216
|
+
// @ts-expect-error Testing private method
|
|
217
|
+
expect(doctor.diagnosis.addCLIConfigSection).toHaveBeenCalledWith({
|
|
218
|
+
type: 'success',
|
|
219
|
+
message: 'Default account active',
|
|
220
|
+
});
|
|
221
|
+
// @ts-expect-error Testing private method
|
|
222
|
+
expect(doctor.diagnosis.addCLIConfigSection).toHaveBeenCalledWith({
|
|
223
|
+
type: 'error',
|
|
224
|
+
message: 'Personal access key is invalid',
|
|
225
|
+
secondaryMessaging: expect.stringMatching(/To get a new key, run/),
|
|
226
|
+
});
|
|
227
|
+
});
|
|
228
|
+
it('should add an error section if we are unable to determine if the portal is active', async () => {
|
|
229
|
+
accessTokenForPersonalAccessKey.mockRejectedValueOnce(new HubSpotHttpError_1.HubSpotHttpError('Not found'));
|
|
230
|
+
isSpecifiedError.mockReturnValue(false);
|
|
231
|
+
await doctor.diagnose();
|
|
232
|
+
// @ts-expect-error Testing private method
|
|
233
|
+
expect(doctor.diagnosis.addCLIConfigSection).toHaveBeenCalledWith({
|
|
234
|
+
type: 'error',
|
|
235
|
+
message: 'Unable to determine if the portal is active',
|
|
236
|
+
});
|
|
237
|
+
});
|
|
238
|
+
it('should warn when there are missing authorized scopes', async () => {
|
|
239
|
+
scopesOnAccessToken.mockResolvedValueOnce(['scope1', 'scope2']);
|
|
240
|
+
authorizedScopesForPortalAndUser.mockResolvedValueOnce([
|
|
241
|
+
{
|
|
242
|
+
scopeGroup: {
|
|
243
|
+
name: 'scope1',
|
|
244
|
+
shortDescription: 'scope1',
|
|
245
|
+
longDescription: 'scope1',
|
|
246
|
+
},
|
|
247
|
+
portalAuthorized: true,
|
|
248
|
+
userAuthorized: true,
|
|
249
|
+
},
|
|
250
|
+
{
|
|
251
|
+
scopeGroup: {
|
|
252
|
+
name: 'scope2',
|
|
253
|
+
shortDescription: 'scope2',
|
|
254
|
+
longDescription: 'scope2',
|
|
255
|
+
},
|
|
256
|
+
portalAuthorized: true,
|
|
257
|
+
userAuthorized: true,
|
|
258
|
+
},
|
|
259
|
+
{
|
|
260
|
+
scopeGroup: {
|
|
261
|
+
name: 'scope3',
|
|
262
|
+
shortDescription: 'scope3',
|
|
263
|
+
longDescription: 'scope3',
|
|
264
|
+
},
|
|
265
|
+
portalAuthorized: true,
|
|
266
|
+
userAuthorized: true,
|
|
267
|
+
},
|
|
268
|
+
]);
|
|
269
|
+
await doctor.diagnose();
|
|
270
|
+
expect(doctor['diagnosis']?.addCLIConfigSection).toHaveBeenCalledWith({
|
|
271
|
+
type: 'warning',
|
|
272
|
+
message: 'Personal access key is valid, but there are more scopes available to your user that are not included in your key.',
|
|
273
|
+
secondaryMessaging: expect.any(String),
|
|
274
|
+
});
|
|
275
|
+
});
|
|
276
|
+
it('should not warn when the missing scope is not authorized', async () => {
|
|
277
|
+
scopesOnAccessToken.mockResolvedValueOnce(['scope1']);
|
|
278
|
+
authorizedScopesForPortalAndUser.mockResolvedValueOnce([
|
|
279
|
+
{
|
|
280
|
+
scopeGroup: {
|
|
281
|
+
name: 'scope1',
|
|
282
|
+
shortDescription: 'scope1',
|
|
283
|
+
longDescription: 'scope1',
|
|
284
|
+
},
|
|
285
|
+
portalAuthorized: true,
|
|
286
|
+
userAuthorized: true,
|
|
287
|
+
},
|
|
288
|
+
{
|
|
289
|
+
scopeGroup: {
|
|
290
|
+
name: 'scope2',
|
|
291
|
+
shortDescription: 'scope2',
|
|
292
|
+
longDescription: 'scope2',
|
|
293
|
+
},
|
|
294
|
+
portalAuthorized: true,
|
|
295
|
+
userAuthorized: false,
|
|
296
|
+
},
|
|
297
|
+
]);
|
|
298
|
+
await doctor.diagnose();
|
|
299
|
+
expect(doctor['diagnosis']?.addCLIConfigSection).toHaveBeenCalledWith({
|
|
300
|
+
type: 'success',
|
|
301
|
+
message: expect.stringMatching(/Personal Access Key is valid./),
|
|
302
|
+
});
|
|
303
|
+
});
|
|
304
|
+
});
|
|
305
|
+
});
|
|
306
|
+
describe('Project Checks', () => {
|
|
307
|
+
describe('Dependencies', () => {
|
|
308
|
+
it('should add warning section if dependencies are missing', async () => {
|
|
309
|
+
hasMissingPackages.mockResolvedValue(true);
|
|
310
|
+
await doctor.diagnose();
|
|
311
|
+
// @ts-expect-error Testing private method
|
|
312
|
+
expect(doctor.diagnosis.addProjectSection).toHaveBeenCalledWith({
|
|
313
|
+
type: 'warning',
|
|
314
|
+
message: expect.stringMatching(/missing dependencies in/),
|
|
315
|
+
secondaryMessaging: expect.stringMatching(/to install all project dependencies locally/),
|
|
316
|
+
});
|
|
317
|
+
});
|
|
318
|
+
it('should add success section if no dependencies are missing', async () => {
|
|
319
|
+
hasMissingPackages.mockResolvedValue(false);
|
|
320
|
+
await doctor.diagnose();
|
|
321
|
+
// @ts-expect-error Testing private method
|
|
322
|
+
expect(doctor.diagnosis.addProjectSection).toHaveBeenCalledWith({
|
|
323
|
+
type: 'success',
|
|
324
|
+
message: 'App dependencies are installed and up to date',
|
|
325
|
+
});
|
|
326
|
+
});
|
|
327
|
+
it('should add error section if the package.json file is invalid JSON', async () => {
|
|
328
|
+
hasMissingPackages.mockImplementationOnce(() => {
|
|
329
|
+
throw new Error('Uh oh');
|
|
330
|
+
});
|
|
331
|
+
utilPromisify.mockReturnValueOnce(vi.fn().mockImplementation((filename) => {
|
|
332
|
+
if (filename.endsWith('package.json')) {
|
|
333
|
+
return 'not-valid-json';
|
|
334
|
+
}
|
|
335
|
+
return JSON.stringify({ valid: true });
|
|
336
|
+
}));
|
|
337
|
+
await doctor.diagnose();
|
|
338
|
+
// @ts-expect-error Testing private method
|
|
339
|
+
expect(doctor.diagnosis.addProjectSection).toHaveBeenCalledWith({
|
|
340
|
+
type: 'error',
|
|
341
|
+
message: expect.stringMatching(/invalid JSON in/),
|
|
342
|
+
});
|
|
343
|
+
});
|
|
344
|
+
it('should add error section if it is unable to determine if dependencies need installed', async () => {
|
|
345
|
+
hasMissingPackages.mockImplementationOnce(() => {
|
|
346
|
+
throw new Error('Uh oh');
|
|
347
|
+
});
|
|
348
|
+
await doctor.diagnose();
|
|
349
|
+
// @ts-expect-error Testing private method
|
|
350
|
+
expect(doctor.diagnosis.addProjectSection).toHaveBeenCalledWith({
|
|
351
|
+
type: 'error',
|
|
352
|
+
message: expect.stringMatching(/Unable to determine if dependencies are installed/),
|
|
353
|
+
});
|
|
354
|
+
});
|
|
355
|
+
});
|
|
356
|
+
describe('Port', () => {
|
|
357
|
+
it('should add warning section if port is in use', async () => {
|
|
358
|
+
isPortManagerPortAvailable.mockResolvedValue(false);
|
|
359
|
+
await doctor.diagnose();
|
|
360
|
+
// @ts-expect-error Testing private method
|
|
361
|
+
expect(doctor.diagnosis?.addProjectSection).toHaveBeenCalledWith({
|
|
362
|
+
type: 'warning',
|
|
363
|
+
message: 'Port 8080 is in use',
|
|
364
|
+
secondaryMessaging: expect.stringMatching(/Make sure it is available if before running/),
|
|
365
|
+
});
|
|
366
|
+
});
|
|
367
|
+
it('should add success section if port is available', async () => {
|
|
368
|
+
isPortManagerPortAvailable.mockResolvedValue(true);
|
|
369
|
+
await doctor.diagnose();
|
|
370
|
+
// @ts-expect-error Testing private method
|
|
371
|
+
expect(doctor.diagnosis.addProjectSection).toHaveBeenCalledWith({
|
|
372
|
+
type: 'success',
|
|
373
|
+
message: 'Port 8080 available for local development',
|
|
374
|
+
});
|
|
375
|
+
});
|
|
376
|
+
});
|
|
377
|
+
describe('JSON Files', () => {
|
|
378
|
+
it('should add success section if project json files are valid', async () => {
|
|
379
|
+
utilPromisify.mockReturnValueOnce(vi.fn().mockResolvedValue(JSON.stringify({ valid: true })));
|
|
380
|
+
await doctor.diagnose();
|
|
381
|
+
// @ts-expect-error Testing private method
|
|
382
|
+
expect(doctor.diagnosis.addProjectSection).toHaveBeenCalledWith({
|
|
383
|
+
type: 'success',
|
|
384
|
+
message: 'JSON files valid',
|
|
385
|
+
});
|
|
386
|
+
});
|
|
387
|
+
it('should add error section if project json files are invalid', async () => {
|
|
388
|
+
utilPromisify.mockReturnValueOnce(vi.fn().mockResolvedValue('not-valid-json'));
|
|
389
|
+
await doctor.diagnose();
|
|
390
|
+
// @ts-expect-error Testing private method
|
|
391
|
+
expect(doctor.diagnosis.addProjectSection).toHaveBeenCalledWith({
|
|
392
|
+
type: 'error',
|
|
393
|
+
message: expect.stringMatching(/invalid JSON in/),
|
|
394
|
+
});
|
|
395
|
+
});
|
|
396
|
+
});
|
|
397
|
+
});
|
|
398
|
+
});
|
package/lib/mcp/setup.js
CHANGED
|
@@ -112,9 +112,9 @@ function setupMcpConfigFile(config) {
|
|
|
112
112
|
fs_extra_1.default.writeFileSync(config.configPath, JSON.stringify({}, null, 2));
|
|
113
113
|
}
|
|
114
114
|
let mcpConfig = {};
|
|
115
|
+
let configContent;
|
|
115
116
|
try {
|
|
116
|
-
|
|
117
|
-
mcpConfig = JSON.parse(configContent);
|
|
117
|
+
configContent = fs_extra_1.default.readFileSync(config.configPath, 'utf8');
|
|
118
118
|
}
|
|
119
119
|
catch (error) {
|
|
120
120
|
SpinniesManager_1.default.fail('spinner', {
|
|
@@ -123,6 +123,22 @@ function setupMcpConfigFile(config) {
|
|
|
123
123
|
(0, errorHandlers_1.logError)(error);
|
|
124
124
|
return false;
|
|
125
125
|
}
|
|
126
|
+
try {
|
|
127
|
+
// In the event the file exists, but is empty, initialize it to and empty object
|
|
128
|
+
if (configContent.trim() === '') {
|
|
129
|
+
mcpConfig = {};
|
|
130
|
+
}
|
|
131
|
+
else {
|
|
132
|
+
mcpConfig = JSON.parse(configContent);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
catch (error) {
|
|
136
|
+
SpinniesManager_1.default.fail('spinner', {
|
|
137
|
+
text: config.failedMessage,
|
|
138
|
+
});
|
|
139
|
+
logger_1.uiLogger.error(en_1.commands.mcp.setup.errors.errorParsingJsonFIle(config.configPath, error instanceof Error ? error.message : `${error}`));
|
|
140
|
+
return false;
|
|
141
|
+
}
|
|
126
142
|
// Initialize mcpServers if it doesn't exist
|
|
127
143
|
if (!mcpConfig.mcpServers) {
|
|
128
144
|
mcpConfig.mcpServers = {};
|
|
@@ -38,21 +38,21 @@ const cliConfig = __importStar(require("@hubspot/local-dev-lib/config"));
|
|
|
38
38
|
const validation = __importStar(require("../../validation"));
|
|
39
39
|
const exitCodes_1 = require("../../enums/exitCodes");
|
|
40
40
|
const configMiddleware_1 = require("../configMiddleware");
|
|
41
|
-
|
|
41
|
+
vi.mock('@hubspot/local-dev-lib/logger', () => ({
|
|
42
42
|
logger: {
|
|
43
|
-
error:
|
|
44
|
-
log:
|
|
43
|
+
error: vi.fn(),
|
|
44
|
+
log: vi.fn(),
|
|
45
45
|
},
|
|
46
46
|
}));
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
const validateAccountSpy =
|
|
50
|
-
const loadConfigSpy =
|
|
51
|
-
const getAccountIdSpy =
|
|
52
|
-
const configFileExistsSpy =
|
|
53
|
-
const getConfigPathSpy =
|
|
54
|
-
const validateConfigSpy =
|
|
55
|
-
const processExitSpy =
|
|
47
|
+
vi.mock('@hubspot/local-dev-lib/config');
|
|
48
|
+
vi.mock('../../validation');
|
|
49
|
+
const validateAccountSpy = vi.spyOn(validation, 'validateAccount');
|
|
50
|
+
const loadConfigSpy = vi.spyOn(cliConfig, 'loadConfig');
|
|
51
|
+
const getAccountIdSpy = vi.spyOn(cliConfig, 'getAccountId');
|
|
52
|
+
const configFileExistsSpy = vi.spyOn(cliConfig, 'configFileExists');
|
|
53
|
+
const getConfigPathSpy = vi.spyOn(cliConfig, 'getConfigPath');
|
|
54
|
+
const validateConfigSpy = vi.spyOn(cliConfig, 'validateConfig');
|
|
55
|
+
const processExitSpy = vi.spyOn(process, 'exit');
|
|
56
56
|
describe('lib/middleware/configMiddleware', () => {
|
|
57
57
|
beforeEach(() => {
|
|
58
58
|
processExitSpy.mockImplementation(code => {
|
|
@@ -36,10 +36,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
36
36
|
const config = __importStar(require("@hubspot/local-dev-lib/config"));
|
|
37
37
|
const gitUI = __importStar(require("../../ui/git"));
|
|
38
38
|
const gitMiddleware_1 = require("../gitMiddleware");
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
const getConfigPathSpy =
|
|
42
|
-
const checkAndWarnGitInclusionSpy =
|
|
39
|
+
vi.mock('@hubspot/local-dev-lib/config');
|
|
40
|
+
vi.mock('../../ui/git');
|
|
41
|
+
const getConfigPathSpy = vi.spyOn(config, 'getConfigPath');
|
|
42
|
+
const checkAndWarnGitInclusionSpy = vi.spyOn(gitUI, 'checkAndWarnGitInclusion');
|
|
43
43
|
describe('lib/middleware/gitMiddleware', () => {
|
|
44
44
|
describe('checkAndWarnGitInclusionMiddleware()', () => {
|
|
45
45
|
it('should call checkAndWarnGitInclusion when command is provided and config path exists', () => {
|