@hubspot/cli 7.0.1-experimental.0 → 7.0.2-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/README.md +3 -2
- package/bin/cli.js +30 -3
- package/commands/customObject/create.js +4 -1
- package/commands/hubdb/create.js +2 -2
- package/commands/project/deploy.js +1 -1
- package/commands/project/dev.js +4 -3
- package/commands/sandbox/create.js +5 -10
- package/commands/theme/preview.js +3 -2
- package/lang/en.lyaml +6 -2
- package/lib/DevServerManager.d.ts +40 -1
- package/lib/DevServerManager.js +39 -30
- package/lib/LocalDevManager.js +7 -6
- package/lib/buildAccount.js +3 -3
- package/lib/commonOpts.d.ts +0 -7
- package/lib/commonOpts.js +0 -14
- package/lib/dependencyManagement.d.ts +9 -4
- package/lib/dependencyManagement.js +45 -49
- package/lib/errorHandlers/index.js +5 -2
- package/lib/localDev.js +1 -7
- package/lib/projects/structure.d.ts +2 -71
- package/lib/projects/structure.js +6 -10
- package/lib/projects/upload.js +2 -1
- package/lib/projects/watch.d.ts +3 -0
- package/lib/projects/watch.js +73 -70
- package/lib/sandboxSync.d.ts +4 -1
- package/lib/sandboxSync.js +67 -68
- package/lib/sandboxes.d.ts +20 -1
- package/lib/sandboxes.js +77 -175
- package/package.json +10 -9
- package/types/Projects.d.ts +68 -0
- package/types/Projects.js +7 -0
- package/types/Sandboxes.d.ts +3 -0
- package/types/Sandboxes.js +2 -0
|
@@ -1,32 +1,36 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
2
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
6
|
exports.isGloballyInstalled = isGloballyInstalled;
|
|
4
7
|
exports.getLatestCliVersion = getLatestCliVersion;
|
|
8
|
+
exports.installPackages = installPackages;
|
|
9
|
+
exports.getProjectPackageJsonLocations = getProjectPackageJsonLocations;
|
|
5
10
|
exports.hasMissingPackages = hasMissingPackages;
|
|
6
|
-
|
|
7
|
-
const
|
|
8
|
-
const
|
|
9
|
-
const
|
|
10
|
-
const
|
|
11
|
-
const
|
|
12
|
-
const
|
|
13
|
-
const
|
|
14
|
-
const
|
|
15
|
-
const
|
|
16
|
-
const
|
|
17
|
-
const pkg = require('../package.json');
|
|
11
|
+
const logger_1 = require("@hubspot/local-dev-lib/logger");
|
|
12
|
+
const projects_1 = require("./projects");
|
|
13
|
+
const child_process_1 = require("child_process");
|
|
14
|
+
const fs_1 = require("@hubspot/local-dev-lib/fs");
|
|
15
|
+
const path_1 = __importDefault(require("path"));
|
|
16
|
+
const ui_1 = require("./ui");
|
|
17
|
+
const util_1 = __importDefault(require("util"));
|
|
18
|
+
const lang_1 = require("./lang");
|
|
19
|
+
const SpinniesManager_1 = __importDefault(require("./ui/SpinniesManager"));
|
|
20
|
+
const fs_2 = __importDefault(require("fs"));
|
|
21
|
+
const package_json_1 = __importDefault(require("../package.json"));
|
|
18
22
|
const DEFAULT_PACKAGE_MANAGER = 'npm';
|
|
19
23
|
const i18nKey = `commands.project.subcommands.installDeps`;
|
|
20
24
|
class NoPackageJsonFilesError extends Error {
|
|
21
25
|
constructor(projectName) {
|
|
22
|
-
super(i18n(`${i18nKey}.noPackageJsonInProject`, {
|
|
26
|
+
super((0, lang_1.i18n)(`${i18nKey}.noPackageJsonInProject`, {
|
|
23
27
|
projectName,
|
|
24
|
-
link: uiLink('Learn how to create a project from scratch.', 'https://developers.hubspot.com/beta-docs/guides/crm/intro/create-a-project'),
|
|
28
|
+
link: (0, ui_1.uiLink)('Learn how to create a project from scratch.', 'https://developers.hubspot.com/beta-docs/guides/crm/intro/create-a-project'),
|
|
25
29
|
}));
|
|
26
30
|
}
|
|
27
31
|
}
|
|
28
32
|
async function isGloballyInstalled(command) {
|
|
29
|
-
const exec =
|
|
33
|
+
const exec = util_1.default.promisify(child_process_1.exec);
|
|
30
34
|
try {
|
|
31
35
|
await exec(`${command} --version`);
|
|
32
36
|
return true;
|
|
@@ -36,28 +40,28 @@ async function isGloballyInstalled(command) {
|
|
|
36
40
|
}
|
|
37
41
|
}
|
|
38
42
|
async function getLatestCliVersion() {
|
|
39
|
-
const exec =
|
|
40
|
-
const { stdout } = await exec(`npm info ${
|
|
43
|
+
const exec = util_1.default.promisify(child_process_1.exec);
|
|
44
|
+
const { stdout } = await exec(`npm info ${package_json_1.default.name} dist-tags --json`);
|
|
41
45
|
const { latest, next } = JSON.parse(stdout);
|
|
42
46
|
return { latest, next };
|
|
43
47
|
}
|
|
44
|
-
async function installPackages({ packages, installLocations }) {
|
|
48
|
+
async function installPackages({ packages, installLocations, }) {
|
|
45
49
|
const installDirs = installLocations || (await getProjectPackageJsonLocations());
|
|
46
50
|
await Promise.all(installDirs.map(async (dir) => {
|
|
47
|
-
await installPackagesInDirectory(
|
|
51
|
+
await installPackagesInDirectory(dir, packages);
|
|
48
52
|
}));
|
|
49
53
|
}
|
|
50
|
-
async function installPackagesInDirectory(
|
|
54
|
+
async function installPackagesInDirectory(directory, packages) {
|
|
51
55
|
const spinner = `installingDependencies-${directory}`;
|
|
52
|
-
const relativeDir =
|
|
53
|
-
|
|
54
|
-
|
|
56
|
+
const relativeDir = path_1.default.relative(process.cwd(), directory);
|
|
57
|
+
SpinniesManager_1.default.init();
|
|
58
|
+
SpinniesManager_1.default.add(spinner, {
|
|
55
59
|
text: packages && packages.length
|
|
56
|
-
? i18n(`${i18nKey}.addingDependenciesToLocation`, {
|
|
60
|
+
? (0, lang_1.i18n)(`${i18nKey}.addingDependenciesToLocation`, {
|
|
57
61
|
dependencies: `[${packages.join(', ')}]`,
|
|
58
62
|
directory: relativeDir,
|
|
59
63
|
})
|
|
60
|
-
: i18n(`${i18nKey}.installingDependencies`, {
|
|
64
|
+
: (0, lang_1.i18n)(`${i18nKey}.installingDependencies`, {
|
|
61
65
|
directory: relativeDir,
|
|
62
66
|
}),
|
|
63
67
|
});
|
|
@@ -65,23 +69,23 @@ async function installPackagesInDirectory(packages, directory) {
|
|
|
65
69
|
if (packages) {
|
|
66
70
|
installCommand = `${installCommand} ${packages.join(' ')}`;
|
|
67
71
|
}
|
|
68
|
-
logger.debug(`Running ${installCommand}`);
|
|
72
|
+
logger_1.logger.debug(`Running ${installCommand}`);
|
|
69
73
|
try {
|
|
70
|
-
const exec =
|
|
74
|
+
const exec = util_1.default.promisify(child_process_1.exec);
|
|
71
75
|
await exec(installCommand, { cwd: directory });
|
|
72
|
-
|
|
73
|
-
text: i18n(`${i18nKey}.installationSuccessful`, {
|
|
76
|
+
SpinniesManager_1.default.succeed(spinner, {
|
|
77
|
+
text: (0, lang_1.i18n)(`${i18nKey}.installationSuccessful`, {
|
|
74
78
|
directory: relativeDir,
|
|
75
79
|
}),
|
|
76
80
|
});
|
|
77
81
|
}
|
|
78
82
|
catch (e) {
|
|
79
|
-
|
|
80
|
-
text: i18n(`${i18nKey}.installingDependenciesFailed`, {
|
|
83
|
+
SpinniesManager_1.default.fail(spinner, {
|
|
84
|
+
text: (0, lang_1.i18n)(`${i18nKey}.installingDependenciesFailed`, {
|
|
81
85
|
directory: relativeDir,
|
|
82
86
|
}),
|
|
83
87
|
});
|
|
84
|
-
throw new Error(i18n(`${i18nKey}.installingDependenciesFailed`, {
|
|
88
|
+
throw new Error((0, lang_1.i18n)(`${i18nKey}.installingDependenciesFailed`, {
|
|
85
89
|
directory: relativeDir,
|
|
86
90
|
}), {
|
|
87
91
|
cause: e,
|
|
@@ -89,24 +93,24 @@ async function installPackagesInDirectory(packages, directory) {
|
|
|
89
93
|
}
|
|
90
94
|
}
|
|
91
95
|
async function getProjectPackageJsonLocations() {
|
|
92
|
-
const projectConfig = await getProjectConfig();
|
|
96
|
+
const projectConfig = await (0, projects_1.getProjectConfig)();
|
|
93
97
|
if (!projectConfig ||
|
|
94
98
|
!projectConfig.projectDir ||
|
|
95
99
|
!projectConfig.projectConfig) {
|
|
96
|
-
throw new Error(i18n(`${i18nKey}.noProjectConfig`));
|
|
100
|
+
throw new Error((0, lang_1.i18n)(`${i18nKey}.noProjectConfig`));
|
|
97
101
|
}
|
|
98
102
|
const { projectDir, projectConfig: { srcDir, name }, } = projectConfig;
|
|
99
103
|
if (!(await isGloballyInstalled(DEFAULT_PACKAGE_MANAGER))) {
|
|
100
|
-
throw new Error(i18n(`${i18nKey}.packageManagerNotInstalled`, {
|
|
104
|
+
throw new Error((0, lang_1.i18n)(`${i18nKey}.packageManagerNotInstalled`, {
|
|
101
105
|
packageManager: DEFAULT_PACKAGE_MANAGER,
|
|
102
|
-
link: uiLink(DEFAULT_PACKAGE_MANAGER, 'https://docs.npmjs.com/downloading-and-installing-node-js-and-npm'),
|
|
106
|
+
link: (0, ui_1.uiLink)(DEFAULT_PACKAGE_MANAGER, 'https://docs.npmjs.com/downloading-and-installing-node-js-and-npm'),
|
|
103
107
|
}));
|
|
104
108
|
}
|
|
105
|
-
if (!
|
|
106
|
-
!
|
|
109
|
+
if (!fs_2.default.existsSync(projectConfig.projectDir) ||
|
|
110
|
+
!fs_2.default.existsSync(path_1.default.join(projectDir, srcDir))) {
|
|
107
111
|
throw new NoPackageJsonFilesError(name);
|
|
108
112
|
}
|
|
109
|
-
const packageJsonFiles = (await walk(
|
|
113
|
+
const packageJsonFiles = (await (0, fs_1.walk)(path_1.default.join(projectDir, srcDir))).filter(file => file.includes('package.json') &&
|
|
110
114
|
!file.includes('node_modules') &&
|
|
111
115
|
!file.includes('.vite'));
|
|
112
116
|
if (packageJsonFiles.length === 0) {
|
|
@@ -114,23 +118,15 @@ async function getProjectPackageJsonLocations() {
|
|
|
114
118
|
}
|
|
115
119
|
const packageParentDirs = [];
|
|
116
120
|
packageJsonFiles.forEach(packageJsonFile => {
|
|
117
|
-
const parentDir =
|
|
121
|
+
const parentDir = path_1.default.dirname(packageJsonFile);
|
|
118
122
|
packageParentDirs.push(parentDir);
|
|
119
123
|
});
|
|
120
124
|
return packageParentDirs;
|
|
121
125
|
}
|
|
122
126
|
async function hasMissingPackages(directory) {
|
|
123
|
-
const exec =
|
|
127
|
+
const exec = util_1.default.promisify(child_process_1.exec);
|
|
124
128
|
const { stdout } = await exec(`npm install --ignore-scripts --dry-run`, {
|
|
125
129
|
cwd: directory,
|
|
126
130
|
});
|
|
127
131
|
return !stdout?.includes('up to date in');
|
|
128
132
|
}
|
|
129
|
-
module.exports = {
|
|
130
|
-
isGloballyInstalled,
|
|
131
|
-
installPackages,
|
|
132
|
-
DEFAULT_PACKAGE_MANAGER,
|
|
133
|
-
getProjectPackageJsonLocations,
|
|
134
|
-
getLatestCliVersion,
|
|
135
|
-
hasMissingPackages,
|
|
136
|
-
};
|
|
@@ -11,6 +11,7 @@ const index_1 = require("@hubspot/local-dev-lib/errors/index");
|
|
|
11
11
|
const suppressError_1 = require("./suppressError");
|
|
12
12
|
const lang_1 = require("../lang");
|
|
13
13
|
const util_1 = __importDefault(require("util"));
|
|
14
|
+
const axios_1 = require("axios");
|
|
14
15
|
const i18nKey = 'lib.errorHandlers.index';
|
|
15
16
|
function logError(error, context) {
|
|
16
17
|
debugError(error, context);
|
|
@@ -49,9 +50,11 @@ function debugError(error, context) {
|
|
|
49
50
|
else {
|
|
50
51
|
logger_1.logger.debug((0, lang_1.i18n)(`${i18nKey}.errorOccurred`, { error: String(error) }));
|
|
51
52
|
}
|
|
52
|
-
if (error instanceof Error) {
|
|
53
|
+
if (error instanceof Error && error.cause) {
|
|
53
54
|
logger_1.logger.debug((0, lang_1.i18n)(`${i18nKey}.errorCause`, {
|
|
54
|
-
cause:
|
|
55
|
+
cause: (0, axios_1.isAxiosError)(error.cause)
|
|
56
|
+
? `${error.cause}`
|
|
57
|
+
: util_1.default.inspect(error.cause, false, null, true),
|
|
55
58
|
}));
|
|
56
59
|
}
|
|
57
60
|
if (context) {
|
package/lib/localDev.js
CHANGED
|
@@ -142,13 +142,7 @@ const createSandboxForLocalDev = async (accountId, accountConfig, env) => {
|
|
|
142
142
|
const sandboxAccountConfig = getAccountConfig(result.sandbox.sandboxHubId);
|
|
143
143
|
const syncTasks = await getAvailableSyncTypes(accountConfig, sandboxAccountConfig);
|
|
144
144
|
// For v1 sandboxes, keep sync here. Once we migrate to v2, this will be handled by BE automatically
|
|
145
|
-
await syncSandbox(
|
|
146
|
-
accountConfig: sandboxAccountConfig,
|
|
147
|
-
parentAccountConfig: accountConfig,
|
|
148
|
-
env,
|
|
149
|
-
syncTasks,
|
|
150
|
-
slimInfoMessage: true,
|
|
151
|
-
});
|
|
145
|
+
await syncSandbox(sandboxAccountConfig, accountConfig, env, syncTasks, true);
|
|
152
146
|
return targetAccountId;
|
|
153
147
|
}
|
|
154
148
|
catch (err) {
|
|
@@ -1,78 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export type Component = {
|
|
3
|
-
type: ComponentTypes;
|
|
4
|
-
config: object;
|
|
5
|
-
runnable: boolean;
|
|
6
|
-
path: string;
|
|
7
|
-
};
|
|
8
|
-
type PrivateAppComponentConfig = {
|
|
9
|
-
name: string;
|
|
10
|
-
description: string;
|
|
11
|
-
uid: string;
|
|
12
|
-
scopes: Array<string>;
|
|
13
|
-
public: boolean;
|
|
14
|
-
extensions?: {
|
|
15
|
-
crm: {
|
|
16
|
-
cards: Array<{
|
|
17
|
-
file: string;
|
|
18
|
-
}>;
|
|
19
|
-
};
|
|
20
|
-
};
|
|
21
|
-
};
|
|
22
|
-
type PublicAppComponentConfig = {
|
|
23
|
-
name: string;
|
|
24
|
-
uid: string;
|
|
25
|
-
description: string;
|
|
26
|
-
allowedUrls: Array<string>;
|
|
27
|
-
auth: {
|
|
28
|
-
redirectUrls: Array<string>;
|
|
29
|
-
requiredScopes: Array<string>;
|
|
30
|
-
optionalScopes: Array<string>;
|
|
31
|
-
conditionallyRequiredScopes: Array<string>;
|
|
32
|
-
};
|
|
33
|
-
support: {
|
|
34
|
-
supportEmail: string;
|
|
35
|
-
documentationUrl: string;
|
|
36
|
-
supportUrl: string;
|
|
37
|
-
supportPhone: string;
|
|
38
|
-
};
|
|
39
|
-
extensions?: {
|
|
40
|
-
crm: {
|
|
41
|
-
cards: Array<{
|
|
42
|
-
file: string;
|
|
43
|
-
}>;
|
|
44
|
-
};
|
|
45
|
-
};
|
|
46
|
-
webhooks?: {
|
|
47
|
-
file: string;
|
|
48
|
-
};
|
|
49
|
-
};
|
|
50
|
-
type AppCardComponentConfig = {
|
|
51
|
-
type: 'crm-card';
|
|
52
|
-
data: {
|
|
53
|
-
title: string;
|
|
54
|
-
uid: string;
|
|
55
|
-
location: string;
|
|
56
|
-
module: {
|
|
57
|
-
file: string;
|
|
58
|
-
};
|
|
59
|
-
objectTypes: Array<{
|
|
60
|
-
name: string;
|
|
61
|
-
}>;
|
|
62
|
-
};
|
|
63
|
-
};
|
|
64
|
-
export declare const COMPONENT_TYPES: {
|
|
65
|
-
readonly privateApp: "private-app";
|
|
66
|
-
readonly publicApp: "public-app";
|
|
67
|
-
readonly hublTheme: "hubl-theme";
|
|
68
|
-
};
|
|
69
|
-
type ComponentTypes = ValueOf<typeof COMPONENT_TYPES>;
|
|
1
|
+
import { ComponentTypes, Component, PublicAppComponentConfig, PrivateAppComponentConfig, AppCardComponentConfig } from '../../types/Projects';
|
|
70
2
|
export declare const CONFIG_FILES: {
|
|
71
|
-
[k in
|
|
3
|
+
[k in ComponentTypes]: string;
|
|
72
4
|
};
|
|
73
5
|
export declare function getAppCardConfigs(appConfig: PublicAppComponentConfig | PrivateAppComponentConfig, appPath: string): Array<AppCardComponentConfig>;
|
|
74
6
|
export declare function findProjectComponents(projectSourceDir: string): Promise<Array<Component>>;
|
|
75
7
|
export declare function getProjectComponentTypes(components: Array<Component>): {
|
|
76
8
|
[key in ComponentTypes]?: boolean;
|
|
77
9
|
};
|
|
78
|
-
export {};
|
|
@@ -33,7 +33,7 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.CONFIG_FILES =
|
|
36
|
+
exports.CONFIG_FILES = void 0;
|
|
37
37
|
exports.getAppCardConfigs = getAppCardConfigs;
|
|
38
38
|
exports.findProjectComponents = findProjectComponents;
|
|
39
39
|
exports.getProjectComponentTypes = getProjectComponentTypes;
|
|
@@ -42,15 +42,11 @@ const path = __importStar(require("path"));
|
|
|
42
42
|
const fs_1 = require("@hubspot/local-dev-lib/fs");
|
|
43
43
|
const logger_1 = require("@hubspot/local-dev-lib/logger");
|
|
44
44
|
const index_1 = require("../errorHandlers/index");
|
|
45
|
-
|
|
46
|
-
privateApp: 'private-app',
|
|
47
|
-
publicApp: 'public-app',
|
|
48
|
-
hublTheme: 'hubl-theme',
|
|
49
|
-
};
|
|
45
|
+
const Projects_1 = require("../../types/Projects");
|
|
50
46
|
exports.CONFIG_FILES = {
|
|
51
|
-
[
|
|
52
|
-
[
|
|
53
|
-
[
|
|
47
|
+
[Projects_1.ComponentTypes.PrivateApp]: 'app.json',
|
|
48
|
+
[Projects_1.ComponentTypes.PublicApp]: 'public-app.json',
|
|
49
|
+
[Projects_1.ComponentTypes.HublTheme]: 'theme.json',
|
|
54
50
|
};
|
|
55
51
|
function getComponentTypeFromConfigFile(configFile) {
|
|
56
52
|
let key;
|
|
@@ -129,7 +125,7 @@ async function findProjectComponents(projectSourceDir) {
|
|
|
129
125
|
const parsedConfig = loadConfigFile(projectFile);
|
|
130
126
|
if (parsedConfig) {
|
|
131
127
|
const isLegacy = getIsLegacyApp(parsedConfig, dir);
|
|
132
|
-
const isHublTheme = base === exports.CONFIG_FILES[
|
|
128
|
+
const isHublTheme = base === exports.CONFIG_FILES[Projects_1.ComponentTypes.HublTheme];
|
|
133
129
|
const componentType = getComponentTypeFromConfigFile(base);
|
|
134
130
|
if (componentType) {
|
|
135
131
|
components.push({
|
package/lib/projects/upload.js
CHANGED
|
@@ -17,6 +17,7 @@ const lang_1 = require("../lang");
|
|
|
17
17
|
const exitCodes_1 = require("../enums/exitCodes");
|
|
18
18
|
const project_parsing_lib_1 = require("@hubspot/project-parsing-lib");
|
|
19
19
|
const errorHandlers_1 = require("../errorHandlers");
|
|
20
|
+
const node_util_1 = __importDefault(require("node:util"));
|
|
20
21
|
const i18nKey = 'lib.projectUpload';
|
|
21
22
|
async function uploadProjectFiles(accountId, projectName, filePath, uploadMessage, platformVersion, intermediateRepresentation) {
|
|
22
23
|
SpinniesManager_1.default.init({});
|
|
@@ -85,6 +86,7 @@ async function handleProjectUpload(accountId, projectConfig, projectDir, callbac
|
|
|
85
86
|
platformVersion: projectConfig.platformVersion,
|
|
86
87
|
accountId,
|
|
87
88
|
});
|
|
89
|
+
logger_1.logger.debug(node_util_1.default.inspect(intermediateRepresentation, false, null, true));
|
|
88
90
|
}
|
|
89
91
|
catch (e) {
|
|
90
92
|
if ((0, project_parsing_lib_1.isTranslationError)(e)) {
|
|
@@ -98,7 +100,6 @@ async function handleProjectUpload(accountId, projectConfig, projectDir, callbac
|
|
|
98
100
|
}
|
|
99
101
|
const { buildId, error } = await uploadProjectFiles(accountId, projectConfig.name, tempFile.name, uploadMessage, projectConfig.platformVersion, intermediateRepresentation);
|
|
100
102
|
if (error) {
|
|
101
|
-
console.log(error);
|
|
102
103
|
uploadResult = { uploadError: error };
|
|
103
104
|
}
|
|
104
105
|
else if (callbackFunc) {
|
package/lib/projects/watch.d.ts
CHANGED
|
@@ -1 +1,4 @@
|
|
|
1
|
+
import { ProjectConfig } from '../../types/Projects';
|
|
2
|
+
type ProjectWatchHandlerFunction = (accountId: number, projectName: string, currentBuildId: number) => Promise<void>;
|
|
3
|
+
export declare function createWatcher(accountId: number, projectConfig: ProjectConfig, projectDir: string, handleBuildStatusFn: ProjectWatchHandlerFunction, handleUserInputFn: ProjectWatchHandlerFunction): Promise<void>;
|
|
1
4
|
export {};
|
package/lib/projects/watch.js
CHANGED
|
@@ -1,124 +1,130 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
2
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
|
|
4
|
-
const
|
|
5
|
-
const
|
|
6
|
-
const
|
|
7
|
-
const
|
|
8
|
-
const
|
|
9
|
-
const
|
|
10
|
-
const
|
|
11
|
-
const
|
|
12
|
-
const
|
|
13
|
-
const
|
|
14
|
-
const
|
|
15
|
-
const
|
|
6
|
+
exports.createWatcher = createWatcher;
|
|
7
|
+
const chokidar_1 = __importDefault(require("chokidar"));
|
|
8
|
+
const path_1 = __importDefault(require("path"));
|
|
9
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
10
|
+
const p_queue_1 = __importDefault(require("p-queue"));
|
|
11
|
+
const logger_1 = require("@hubspot/local-dev-lib/logger");
|
|
12
|
+
const path_2 = require("@hubspot/local-dev-lib/path");
|
|
13
|
+
const extensions_1 = require("@hubspot/local-dev-lib/constants/extensions");
|
|
14
|
+
const ignoreRules_1 = require("@hubspot/local-dev-lib/ignoreRules");
|
|
15
|
+
const projects_1 = require("@hubspot/local-dev-lib/api/projects");
|
|
16
|
+
const index_1 = require("@hubspot/local-dev-lib/errors/index");
|
|
17
|
+
const errorHandlers_1 = require("../errorHandlers");
|
|
18
|
+
const lang_1 = require("../lang");
|
|
19
|
+
const constants_1 = require("../constants");
|
|
16
20
|
const i18nKey = 'commands.project.subcommands.watch';
|
|
17
|
-
const queue = new
|
|
21
|
+
const queue = new p_queue_1.default({
|
|
18
22
|
concurrency: 10,
|
|
19
23
|
});
|
|
20
|
-
const
|
|
21
|
-
let currentBuildId
|
|
22
|
-
let handleBuildStatus
|
|
24
|
+
const standbyQueue = [];
|
|
25
|
+
let currentBuildId;
|
|
26
|
+
let handleBuildStatus;
|
|
27
|
+
let handleUserInput;
|
|
23
28
|
let timer;
|
|
24
|
-
|
|
25
|
-
queue.addAll(
|
|
29
|
+
async function processStandByQueue(accountId, projectName, platformVersion) {
|
|
30
|
+
queue.addAll(standbyQueue.map(({ filePath, remotePath, action }) => {
|
|
26
31
|
return async () => {
|
|
27
32
|
queueFileOrFolder(accountId, projectName, platformVersion, filePath, remotePath, action);
|
|
28
33
|
};
|
|
29
34
|
}));
|
|
30
|
-
|
|
35
|
+
standbyQueue.length = 0;
|
|
31
36
|
debounceQueueBuild(accountId, projectName, platformVersion);
|
|
32
|
-
}
|
|
33
|
-
|
|
37
|
+
}
|
|
38
|
+
async function createNewStagingBuild(accountId, projectName, platformVersion) {
|
|
34
39
|
currentBuildId = await createNewBuild(accountId, projectName, platformVersion);
|
|
35
40
|
handleUserInput(accountId, projectName, currentBuildId);
|
|
36
|
-
}
|
|
37
|
-
|
|
41
|
+
}
|
|
42
|
+
function debounceQueueBuild(accountId, projectName, platformVersion) {
|
|
38
43
|
if (timer) {
|
|
39
44
|
clearTimeout(timer);
|
|
40
45
|
}
|
|
41
46
|
timer = setTimeout(async () => {
|
|
42
|
-
logger.debug(i18n(`${i18nKey}.debug.pause`, { projectName }));
|
|
47
|
+
logger_1.logger.debug((0, lang_1.i18n)(`${i18nKey}.debug.pause`, { projectName }));
|
|
43
48
|
queue.pause();
|
|
44
49
|
await queue.onIdle();
|
|
45
50
|
try {
|
|
46
|
-
await queueBuild(accountId, projectName, platformVersion);
|
|
47
|
-
logger.debug(i18n(`${i18nKey}.debug.buildStarted`, { projectName }));
|
|
51
|
+
await (0, projects_1.queueBuild)(accountId, projectName, platformVersion);
|
|
52
|
+
logger_1.logger.debug((0, lang_1.i18n)(`${i18nKey}.debug.buildStarted`, { projectName }));
|
|
48
53
|
}
|
|
49
54
|
catch (err) {
|
|
50
|
-
if (isSpecifiedError(err, {
|
|
51
|
-
subCategory: PROJECT_ERROR_TYPES.MISSING_PROJECT_PROVISION,
|
|
55
|
+
if ((0, index_1.isSpecifiedError)(err, {
|
|
56
|
+
subCategory: constants_1.PROJECT_ERROR_TYPES.MISSING_PROJECT_PROVISION,
|
|
52
57
|
})) {
|
|
53
|
-
logger.log(i18n(`${i18nKey}.logs.watchCancelledFromUi`));
|
|
58
|
+
logger_1.logger.log((0, lang_1.i18n)(`${i18nKey}.logs.watchCancelledFromUi`));
|
|
54
59
|
process.exit(0);
|
|
55
60
|
}
|
|
56
61
|
else {
|
|
57
|
-
logError(err, new ApiErrorContext({ accountId }));
|
|
62
|
+
(0, errorHandlers_1.logError)(err, new errorHandlers_1.ApiErrorContext({ accountId }));
|
|
58
63
|
}
|
|
59
64
|
return;
|
|
60
65
|
}
|
|
61
66
|
await handleBuildStatus(accountId, projectName, currentBuildId);
|
|
62
67
|
await createNewStagingBuild(accountId, projectName, platformVersion);
|
|
63
|
-
if (
|
|
68
|
+
if (standbyQueue.length > 0) {
|
|
64
69
|
await processStandByQueue(accountId, projectName, platformVersion);
|
|
65
70
|
}
|
|
66
71
|
queue.start();
|
|
67
|
-
logger.log(i18n(`${i18nKey}.logs.resuming`));
|
|
68
|
-
logger.log(`\n> Press ${
|
|
72
|
+
logger_1.logger.log((0, lang_1.i18n)(`${i18nKey}.logs.resuming`));
|
|
73
|
+
logger_1.logger.log(`\n> Press ${chalk_1.default.bold('q')} to quit watching\n`);
|
|
69
74
|
}, 2000);
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
if (action === 'upload' &&
|
|
73
|
-
|
|
75
|
+
}
|
|
76
|
+
async function queueFileOrFolder(accountId, projectName, platformVersion, filePath, remotePath, action) {
|
|
77
|
+
if (action === 'upload' &&
|
|
78
|
+
!(0, path_2.isAllowedExtension)(filePath, Array.from(extensions_1.JSR_ALLOWED_EXTENSIONS))) {
|
|
79
|
+
logger_1.logger.debug((0, lang_1.i18n)(`${i18nKey}.debug.extensionNotAllowed`, { filePath }));
|
|
74
80
|
return;
|
|
75
81
|
}
|
|
76
|
-
if (shouldIgnoreFile(filePath, true)) {
|
|
77
|
-
logger.debug(i18n(`${i18nKey}.debug.ignored`, { filePath }));
|
|
82
|
+
if ((0, ignoreRules_1.shouldIgnoreFile)(filePath, true)) {
|
|
83
|
+
logger_1.logger.debug((0, lang_1.i18n)(`${i18nKey}.debug.ignored`, { filePath }));
|
|
78
84
|
return;
|
|
79
85
|
}
|
|
80
86
|
if (!queue.isPaused) {
|
|
81
87
|
debounceQueueBuild(accountId, projectName, platformVersion);
|
|
82
88
|
}
|
|
83
|
-
logger.debug(i18n(`${i18nKey}.debug.uploading`, { filePath, remotePath }));
|
|
89
|
+
logger_1.logger.debug((0, lang_1.i18n)(`${i18nKey}.debug.uploading`, { filePath, remotePath }));
|
|
84
90
|
return queue.add(async () => {
|
|
85
91
|
try {
|
|
86
92
|
if (action === 'upload') {
|
|
87
|
-
await uploadFileToBuild(accountId, projectName, filePath, remotePath);
|
|
93
|
+
await (0, projects_1.uploadFileToBuild)(accountId, projectName, filePath, remotePath);
|
|
88
94
|
}
|
|
89
95
|
else if (action === 'deleteFile' || action === 'deleteFolder') {
|
|
90
|
-
await deleteFileFromBuild(accountId, projectName, remotePath);
|
|
96
|
+
await (0, projects_1.deleteFileFromBuild)(accountId, projectName, remotePath);
|
|
91
97
|
}
|
|
92
|
-
logger.log(i18n(`${i18nKey}.logs.${action}Succeeded`, { filePath, remotePath }));
|
|
98
|
+
logger_1.logger.log((0, lang_1.i18n)(`${i18nKey}.logs.${action}Succeeded`, { filePath, remotePath }));
|
|
93
99
|
}
|
|
94
100
|
catch (err) {
|
|
95
|
-
logger.debug(i18n(`${i18nKey}.errors.${action}Failed`, { filePath, remotePath }));
|
|
101
|
+
logger_1.logger.debug((0, lang_1.i18n)(`${i18nKey}.errors.${action}Failed`, { filePath, remotePath }));
|
|
96
102
|
}
|
|
97
103
|
});
|
|
98
|
-
}
|
|
99
|
-
|
|
104
|
+
}
|
|
105
|
+
async function createNewBuild(accountId, projectName, platformVersion) {
|
|
100
106
|
try {
|
|
101
|
-
logger.debug(i18n(`${i18nKey}.debug.attemptNewBuild`));
|
|
102
|
-
const { data: { buildId }, } = await provisionBuild(accountId, projectName, platformVersion);
|
|
107
|
+
logger_1.logger.debug((0, lang_1.i18n)(`${i18nKey}.debug.attemptNewBuild`));
|
|
108
|
+
const { data: { buildId }, } = await (0, projects_1.provisionBuild)(accountId, projectName, platformVersion);
|
|
103
109
|
return buildId;
|
|
104
110
|
}
|
|
105
111
|
catch (err) {
|
|
106
|
-
logError(err, new ApiErrorContext({ accountId }));
|
|
107
|
-
if (isSpecifiedError(err, { subCategory: PROJECT_ERROR_TYPES.PROJECT_LOCKED })) {
|
|
108
|
-
await cancelStagedBuild(accountId, projectName);
|
|
109
|
-
logger.log(i18n(`${i18nKey}.logs.previousStagingBuildCancelled`));
|
|
112
|
+
(0, errorHandlers_1.logError)(err, new errorHandlers_1.ApiErrorContext({ accountId }));
|
|
113
|
+
if ((0, index_1.isSpecifiedError)(err, { subCategory: constants_1.PROJECT_ERROR_TYPES.PROJECT_LOCKED })) {
|
|
114
|
+
await (0, projects_1.cancelStagedBuild)(accountId, projectName);
|
|
115
|
+
logger_1.logger.log((0, lang_1.i18n)(`${i18nKey}.logs.previousStagingBuildCancelled`));
|
|
110
116
|
}
|
|
111
117
|
process.exit(1);
|
|
112
118
|
}
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
const remotePath =
|
|
119
|
+
}
|
|
120
|
+
async function handleWatchEvent(accountId, projectName, platformVersion, projectSourceDir, filePath, action = 'upload') {
|
|
121
|
+
const remotePath = path_1.default.relative(projectSourceDir, filePath);
|
|
116
122
|
if (queue.isPaused) {
|
|
117
|
-
if (
|
|
118
|
-
logger.debug(i18n(`${i18nKey}.debug.fileAlreadyQueued`, { filePath }));
|
|
123
|
+
if (standbyQueue.find(file => file.filePath === filePath)) {
|
|
124
|
+
logger_1.logger.debug((0, lang_1.i18n)(`${i18nKey}.debug.fileAlreadyQueued`, { filePath }));
|
|
119
125
|
}
|
|
120
126
|
else {
|
|
121
|
-
|
|
127
|
+
standbyQueue.push({
|
|
122
128
|
filePath,
|
|
123
129
|
remotePath,
|
|
124
130
|
action,
|
|
@@ -128,19 +134,19 @@ const handleWatchEvent = async (accountId, projectName, platformVersion, project
|
|
|
128
134
|
else {
|
|
129
135
|
await queueFileOrFolder(accountId, projectName, platformVersion, filePath, remotePath, action);
|
|
130
136
|
}
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
const projectSourceDir =
|
|
137
|
+
}
|
|
138
|
+
async function createWatcher(accountId, projectConfig, projectDir, handleBuildStatusFn, handleUserInputFn) {
|
|
139
|
+
const projectSourceDir = path_1.default.join(projectDir, projectConfig.srcDir);
|
|
134
140
|
handleBuildStatus = handleBuildStatusFn;
|
|
135
141
|
handleUserInput = handleUserInputFn;
|
|
136
142
|
await createNewStagingBuild(accountId, projectConfig.name, projectConfig.platformVersion);
|
|
137
|
-
const watcher =
|
|
143
|
+
const watcher = chokidar_1.default.watch(projectSourceDir, {
|
|
138
144
|
ignoreInitial: true,
|
|
139
|
-
ignored: file => shouldIgnoreFile(file),
|
|
145
|
+
ignored: file => (0, ignoreRules_1.shouldIgnoreFile)(file),
|
|
140
146
|
});
|
|
141
147
|
watcher.on('ready', async () => {
|
|
142
|
-
logger.log(i18n(`${i18nKey}.logs.watching`, { projectDir }));
|
|
143
|
-
logger.log(`\n> Press ${
|
|
148
|
+
logger_1.logger.log((0, lang_1.i18n)(`${i18nKey}.logs.watching`, { projectDir }));
|
|
149
|
+
logger_1.logger.log(`\n> Press ${chalk_1.default.bold('q')} to quit watching\n`);
|
|
144
150
|
});
|
|
145
151
|
watcher.on('add', async (path) => {
|
|
146
152
|
handleWatchEvent(accountId, projectConfig.name, projectConfig.platformVersion, projectSourceDir, path);
|
|
@@ -154,7 +160,4 @@ const createWatcher = async (accountId, projectConfig, projectDir, handleBuildSt
|
|
|
154
160
|
watcher.on('unlinkDir', async (path) => {
|
|
155
161
|
handleWatchEvent(accountId, projectConfig.name, projectConfig.platformVersion, projectSourceDir, path, 'deleteFolder');
|
|
156
162
|
});
|
|
157
|
-
}
|
|
158
|
-
module.exports = {
|
|
159
|
-
createWatcher,
|
|
160
|
-
};
|
|
163
|
+
}
|
package/lib/sandboxSync.d.ts
CHANGED
|
@@ -1 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
import { CLIAccount } from '@hubspot/local-dev-lib/types/Accounts';
|
|
2
|
+
import { Environment } from '@hubspot/local-dev-lib/types/Config';
|
|
3
|
+
import { SandboxSyncTask } from '../types/Sandboxes';
|
|
4
|
+
export declare function syncSandbox(accountConfig: CLIAccount, parentAccountConfig: CLIAccount, env: Environment, syncTasks: Array<SandboxSyncTask>, slimInfoMessage?: boolean): Promise<void>;
|