@hubspot/cli 7.0.1-experimental.0 → 7.0.2-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -2
- package/bin/cli.js +37 -5
- package/commands/account/info.d.ts +7 -0
- package/commands/account/info.js +28 -25
- package/commands/account/remove.js +4 -4
- package/commands/account/use.js +3 -3
- package/commands/auth.js +3 -3
- package/commands/customObject/create.js +4 -1
- package/commands/function/deploy.js +1 -1
- package/commands/hubdb/create.js +2 -2
- package/commands/init.js +1 -1
- package/commands/logs.js +1 -7
- package/commands/project/cloneApp.js +1 -1
- package/commands/project/create.js +6 -0
- package/commands/project/deploy.js +1 -1
- package/commands/project/dev.js +4 -3
- package/commands/project/installDeps.js +2 -4
- package/commands/project/migrateApp.js +1 -1
- package/commands/project/upload.js +5 -10
- package/commands/project/watch.js +4 -4
- package/commands/sandbox/create.js +7 -18
- package/commands/sandbox/delete.js +6 -10
- package/commands/theme/preview.js +3 -2
- package/lang/en.lyaml +15 -6
- package/lib/DevServerManager.d.ts +40 -1
- package/lib/DevServerManager.js +39 -30
- package/lib/LocalDevManager.d.ts +58 -1
- package/lib/LocalDevManager.js +162 -121
- package/lib/buildAccount.d.ts +12 -0
- package/lib/buildAccount.js +110 -95
- package/lib/commonOpts.d.ts +4 -15
- package/lib/commonOpts.js +2 -28
- package/lib/constants.d.ts +1 -7
- package/lib/constants.js +2 -8
- package/lib/dependencyManagement.d.ts +9 -4
- package/lib/dependencyManagement.js +45 -49
- package/lib/developerTestAccounts.d.ts +1 -0
- package/lib/developerTestAccounts.js +1 -0
- package/lib/errorHandlers/index.js +5 -2
- package/lib/localDev.d.ts +17 -1
- package/lib/localDev.js +203 -203
- package/lib/polling.d.ts +13 -5
- package/lib/polling.js +21 -7
- package/lib/projects/buildAndDeploy.d.ts +1 -7
- package/lib/projects/buildAndDeploy.js +3 -3
- package/lib/projects/index.js +9 -4
- package/lib/projects/structure.d.ts +5 -71
- package/lib/projects/structure.js +27 -10
- package/lib/projects/upload.d.ts +4 -3
- package/lib/projects/upload.js +7 -30
- package/lib/projects/watch.d.ts +3 -0
- package/lib/projects/watch.js +73 -70
- package/lib/prompts/createProjectPrompt.js +8 -1
- package/lib/prompts/installPublicAppPrompt.d.ts +1 -1
- package/lib/prompts/personalAccessKeyPrompt.d.ts +1 -1
- package/lib/prompts/projectDevTargetAccountPrompt.d.ts +2 -2
- 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/lib/serverlessLogs.d.ts +4 -1
- package/lib/serverlessLogs.js +64 -60
- package/lib/ui/serverlessFunctionLogs.d.ts +8 -0
- package/lib/ui/serverlessFunctionLogs.js +1 -3
- package/lib/validation.d.ts +2 -0
- package/lib/validation.js +5 -8
- package/package.json +9 -9
- package/types/Projects.d.ts +74 -0
- package/types/Projects.js +7 -0
- package/types/Sandboxes.d.ts +3 -0
- package/types/Sandboxes.js +2 -0
- package/types/Yargs.d.ts +14 -0
- package/types/Yargs.js +2 -0
|
@@ -197,13 +197,13 @@ function makePollTaskStatusFunc({ statusFn, structureFn, statusText, statusStrin
|
|
|
197
197
|
resolve(taskStatus);
|
|
198
198
|
}
|
|
199
199
|
}
|
|
200
|
-
}, constants_1.
|
|
200
|
+
}, constants_1.DEFAULT_POLLING_DELAY);
|
|
201
201
|
});
|
|
202
202
|
};
|
|
203
203
|
}
|
|
204
204
|
function pollBuildAutodeployStatus(accountId, taskName, buildId) {
|
|
205
205
|
return new Promise((resolve, reject) => {
|
|
206
|
-
let maxIntervals = (30 * 1000) / constants_1.
|
|
206
|
+
let maxIntervals = (30 * 1000) / constants_1.DEFAULT_POLLING_DELAY; // Num of intervals in ~30s
|
|
207
207
|
const pollInterval = setInterval(async () => {
|
|
208
208
|
let build;
|
|
209
209
|
try {
|
|
@@ -224,7 +224,7 @@ function pollBuildAutodeployStatus(accountId, taskName, buildId) {
|
|
|
224
224
|
else {
|
|
225
225
|
maxIntervals -= 1;
|
|
226
226
|
}
|
|
227
|
-
}, constants_1.
|
|
227
|
+
}, constants_1.DEFAULT_POLLING_DELAY);
|
|
228
228
|
});
|
|
229
229
|
}
|
|
230
230
|
exports.pollBuildStatus = makePollTaskStatusFunc({
|
package/lib/projects/index.js
CHANGED
|
@@ -20,7 +20,6 @@ const github_1 = require("@hubspot/local-dev-lib/github");
|
|
|
20
20
|
const projects_1 = require("@hubspot/local-dev-lib/api/projects");
|
|
21
21
|
const index_1 = require("@hubspot/local-dev-lib/errors/index");
|
|
22
22
|
const path_2 = require("@hubspot/local-dev-lib/path");
|
|
23
|
-
const github_2 = require("@hubspot/local-dev-lib/github");
|
|
24
23
|
const constants_1 = require("../constants");
|
|
25
24
|
const promptUtils_1 = require("../prompts/promptUtils");
|
|
26
25
|
const exitCodes_1 = require("../enums/exitCodes");
|
|
@@ -96,7 +95,10 @@ async function createProjectConfig(projectPath, projectName, template, templateS
|
|
|
96
95
|
const projectConfigPath = path_1.default.join(projectPath, constants_1.PROJECT_CONFIG_FILE);
|
|
97
96
|
logger_1.logger.log(`Creating project config in ${projectPath ? projectPath : 'the current folder'}`);
|
|
98
97
|
const hasCustomTemplateSource = Boolean(templateSource);
|
|
99
|
-
await (0,
|
|
98
|
+
await (0, github_1.cloneGithubRepo)(templateSource || constants_1.HUBSPOT_PROJECT_COMPONENTS_GITHUB_PATH, projectPath, {
|
|
99
|
+
sourceDir: template.path,
|
|
100
|
+
tag: hasCustomTemplateSource ? undefined : githubRef,
|
|
101
|
+
});
|
|
100
102
|
const _config = JSON.parse(fs_extra_1.default.readFileSync(projectConfigPath).toString());
|
|
101
103
|
writeProjectConfig(projectConfigPath, {
|
|
102
104
|
..._config,
|
|
@@ -169,7 +171,7 @@ async function pollFetchProject(accountId, projectName) {
|
|
|
169
171
|
reject(err);
|
|
170
172
|
}
|
|
171
173
|
}
|
|
172
|
-
}, constants_1.
|
|
174
|
+
}, constants_1.DEFAULT_POLLING_DELAY);
|
|
173
175
|
});
|
|
174
176
|
}
|
|
175
177
|
async function ensureProjectExists(accountId, projectName, { forceCreate = false, allowCreate = true, noLogs = false, withPolling = false, uploadCommand = false, } = {}) {
|
|
@@ -248,7 +250,10 @@ async function createProjectComponent(component, name, projectComponentsVersion)
|
|
|
248
250
|
process.exit(exitCodes_1.EXIT_CODES.ERROR);
|
|
249
251
|
}
|
|
250
252
|
const componentPath = path_1.default.join(configInfo.projectDir, configInfo.projectConfig.srcDir, component.insertPath, componentName);
|
|
251
|
-
await (0,
|
|
253
|
+
await (0, github_1.cloneGithubRepo)(constants_1.HUBSPOT_PROJECT_COMPONENTS_GITHUB_PATH, componentPath, {
|
|
254
|
+
sourceDir: component.path,
|
|
255
|
+
tag: projectComponentsVersion,
|
|
256
|
+
});
|
|
252
257
|
}
|
|
253
258
|
async function getProjectComponentsByVersion(projectComponentsVersion) {
|
|
254
259
|
const config = await (0, github_1.fetchFileFromRepository)(constants_1.HUBSPOT_PROJECT_COMPONENTS_GITHUB_PATH, 'config.json', projectComponentsVersion);
|
|
@@ -1,78 +1,12 @@
|
|
|
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
|
|
10
|
+
export declare function getComponentUid(component?: Component | null): string | null;
|
|
11
|
+
export declare function componentIsApp(component?: Component | null): component is Component<PublicAppComponentConfig | PrivateAppComponentConfig>;
|
|
12
|
+
export declare function componentIsPublicApp(component?: Component | null): component is Component<PublicAppComponentConfig>;
|
|
@@ -33,24 +33,23 @@ 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;
|
|
40
|
+
exports.getComponentUid = getComponentUid;
|
|
41
|
+
exports.componentIsApp = componentIsApp;
|
|
42
|
+
exports.componentIsPublicApp = componentIsPublicApp;
|
|
40
43
|
const fs = __importStar(require("fs"));
|
|
41
44
|
const path = __importStar(require("path"));
|
|
42
45
|
const fs_1 = require("@hubspot/local-dev-lib/fs");
|
|
43
46
|
const logger_1 = require("@hubspot/local-dev-lib/logger");
|
|
44
47
|
const index_1 = require("../errorHandlers/index");
|
|
45
|
-
|
|
46
|
-
privateApp: 'private-app',
|
|
47
|
-
publicApp: 'public-app',
|
|
48
|
-
hublTheme: 'hubl-theme',
|
|
49
|
-
};
|
|
48
|
+
const Projects_1 = require("../../types/Projects");
|
|
50
49
|
exports.CONFIG_FILES = {
|
|
51
|
-
[
|
|
52
|
-
[
|
|
53
|
-
[
|
|
50
|
+
[Projects_1.ComponentTypes.PrivateApp]: 'app.json',
|
|
51
|
+
[Projects_1.ComponentTypes.PublicApp]: 'public-app.json',
|
|
52
|
+
[Projects_1.ComponentTypes.HublTheme]: 'theme.json',
|
|
54
53
|
};
|
|
55
54
|
function getComponentTypeFromConfigFile(configFile) {
|
|
56
55
|
let key;
|
|
@@ -129,7 +128,7 @@ async function findProjectComponents(projectSourceDir) {
|
|
|
129
128
|
const parsedConfig = loadConfigFile(projectFile);
|
|
130
129
|
if (parsedConfig) {
|
|
131
130
|
const isLegacy = getIsLegacyApp(parsedConfig, dir);
|
|
132
|
-
const isHublTheme = base === exports.CONFIG_FILES[
|
|
131
|
+
const isHublTheme = base === exports.CONFIG_FILES[Projects_1.ComponentTypes.HublTheme];
|
|
133
132
|
const componentType = getComponentTypeFromConfigFile(base);
|
|
134
133
|
if (componentType) {
|
|
135
134
|
components.push({
|
|
@@ -149,3 +148,21 @@ function getProjectComponentTypes(components) {
|
|
|
149
148
|
components.forEach(({ type }) => (projectContents[type] = true));
|
|
150
149
|
return projectContents;
|
|
151
150
|
}
|
|
151
|
+
function getComponentUid(component) {
|
|
152
|
+
if (!component) {
|
|
153
|
+
return null;
|
|
154
|
+
}
|
|
155
|
+
else if ('uid' in component.config) {
|
|
156
|
+
return component.config.uid;
|
|
157
|
+
}
|
|
158
|
+
else {
|
|
159
|
+
return component.config.data.uid;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
function componentIsApp(component) {
|
|
163
|
+
return (component?.type === Projects_1.ComponentTypes.PublicApp ||
|
|
164
|
+
component?.type === Projects_1.ComponentTypes.PrivateApp);
|
|
165
|
+
}
|
|
166
|
+
function componentIsPublicApp(component) {
|
|
167
|
+
return component?.type === Projects_1.ComponentTypes.PublicApp;
|
|
168
|
+
}
|
package/lib/projects/upload.d.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { FileResult } from 'tmp';
|
|
2
2
|
import { ProjectConfig } from '../../types/Projects';
|
|
3
|
-
type ProjectUploadCallbackFunction<T> = (accountId: number, projectConfig: ProjectConfig, tempFile: FileResult, buildId?: number) => Promise<T
|
|
4
|
-
type
|
|
3
|
+
type ProjectUploadCallbackFunction<T> = (accountId: number, projectConfig: ProjectConfig, tempFile: FileResult, buildId?: number) => Promise<T>;
|
|
4
|
+
type ProjectUploadResult<T> = {
|
|
5
|
+
result?: T;
|
|
5
6
|
uploadError?: unknown;
|
|
6
7
|
};
|
|
7
|
-
export declare function handleProjectUpload<T
|
|
8
|
+
export declare function handleProjectUpload<T>(accountId: number, projectConfig: ProjectConfig, projectDir: string, callbackFunc: ProjectUploadCallbackFunction<T>, uploadMessage: string): Promise<ProjectUploadResult<T>>;
|
|
8
9
|
export {};
|
package/lib/projects/upload.js
CHANGED
|
@@ -15,10 +15,8 @@ const SpinniesManager_1 = __importDefault(require("../ui/SpinniesManager"));
|
|
|
15
15
|
const ui_1 = require("../ui");
|
|
16
16
|
const lang_1 = require("../lang");
|
|
17
17
|
const exitCodes_1 = require("../enums/exitCodes");
|
|
18
|
-
const project_parsing_lib_1 = require("@hubspot/project-parsing-lib");
|
|
19
|
-
const errorHandlers_1 = require("../errorHandlers");
|
|
20
18
|
const i18nKey = 'lib.projectUpload';
|
|
21
|
-
async function uploadProjectFiles(accountId, projectName, filePath, uploadMessage, platformVersion
|
|
19
|
+
async function uploadProjectFiles(accountId, projectName, filePath, uploadMessage, platformVersion) {
|
|
22
20
|
SpinniesManager_1.default.init({});
|
|
23
21
|
const accountIdentifier = (0, ui_1.uiAccountDescription)(accountId);
|
|
24
22
|
SpinniesManager_1.default.add('upload', {
|
|
@@ -31,7 +29,7 @@ async function uploadProjectFiles(accountId, projectName, filePath, uploadMessag
|
|
|
31
29
|
let buildId;
|
|
32
30
|
let error;
|
|
33
31
|
try {
|
|
34
|
-
const { data: upload } = await (0, projects_1.uploadProject)(accountId, projectName, filePath, uploadMessage, platformVersion
|
|
32
|
+
const { data: upload } = await (0, projects_1.uploadProject)(accountId, projectName, filePath, uploadMessage, platformVersion);
|
|
35
33
|
buildId = upload.buildId;
|
|
36
34
|
SpinniesManager_1.default.succeed('upload', {
|
|
37
35
|
text: (0, lang_1.i18n)(`${i18nKey}.uploadProjectFiles.succeed`, {
|
|
@@ -57,7 +55,7 @@ async function uploadProjectFiles(accountId, projectName, filePath, uploadMessag
|
|
|
57
55
|
}
|
|
58
56
|
return { buildId, error };
|
|
59
57
|
}
|
|
60
|
-
async function handleProjectUpload(accountId, projectConfig, projectDir, callbackFunc, uploadMessage
|
|
58
|
+
async function handleProjectUpload(accountId, projectConfig, projectDir, callbackFunc, uploadMessage) {
|
|
61
59
|
const srcDir = path_1.default.resolve(projectDir, projectConfig.srcDir);
|
|
62
60
|
const filenames = fs_extra_1.default.readdirSync(srcDir);
|
|
63
61
|
if (!filenames || filenames.length === 0) {
|
|
@@ -73,38 +71,17 @@ async function handleProjectUpload(accountId, projectConfig, projectDir, callbac
|
|
|
73
71
|
const output = fs_extra_1.default.createWriteStream(tempFile.name);
|
|
74
72
|
const archive = (0, archiver_1.default)('zip');
|
|
75
73
|
const result = new Promise(resolve => output.on('close', async function () {
|
|
76
|
-
let uploadResult;
|
|
77
74
|
logger_1.logger.debug((0, lang_1.i18n)(`${i18nKey}.handleProjectUpload.compressed`, {
|
|
78
75
|
byteCount: archive.pointer(),
|
|
79
76
|
}));
|
|
80
|
-
|
|
81
|
-
if (sendIR) {
|
|
82
|
-
try {
|
|
83
|
-
intermediateRepresentation = await (0, project_parsing_lib_1.translate)({
|
|
84
|
-
projectSourceDir: path_1.default.join(projectDir, projectConfig.srcDir),
|
|
85
|
-
platformVersion: projectConfig.platformVersion,
|
|
86
|
-
accountId,
|
|
87
|
-
});
|
|
88
|
-
}
|
|
89
|
-
catch (e) {
|
|
90
|
-
if ((0, project_parsing_lib_1.isTranslationError)(e)) {
|
|
91
|
-
logger_1.logger.error(e.toString());
|
|
92
|
-
}
|
|
93
|
-
else {
|
|
94
|
-
(0, errorHandlers_1.logError)(e);
|
|
95
|
-
}
|
|
96
|
-
return process.exit(exitCodes_1.EXIT_CODES.ERROR);
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
const { buildId, error } = await uploadProjectFiles(accountId, projectConfig.name, tempFile.name, uploadMessage, projectConfig.platformVersion, intermediateRepresentation);
|
|
77
|
+
const { buildId, error } = await uploadProjectFiles(accountId, projectConfig.name, tempFile.name, uploadMessage, projectConfig.platformVersion);
|
|
100
78
|
if (error) {
|
|
101
|
-
|
|
102
|
-
uploadResult = { uploadError: error };
|
|
79
|
+
resolve({ uploadError: error });
|
|
103
80
|
}
|
|
104
81
|
else if (callbackFunc) {
|
|
105
|
-
uploadResult = await callbackFunc(accountId, projectConfig, tempFile, buildId);
|
|
82
|
+
const uploadResult = await callbackFunc(accountId, projectConfig, tempFile, buildId);
|
|
83
|
+
resolve({ result: uploadResult });
|
|
106
84
|
}
|
|
107
|
-
resolve(uploadResult || {});
|
|
108
85
|
}));
|
|
109
86
|
archive.pipe(output);
|
|
110
87
|
let loggedIgnoredNodeModule = false;
|
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
|
+
}
|
|
@@ -23,7 +23,14 @@ async function createTemplateOptions(templateSource, githubRef) {
|
|
|
23
23
|
const branch = hasCustomTemplateSource
|
|
24
24
|
? constants_1.DEFAULT_PROJECT_TEMPLATE_BRANCH
|
|
25
25
|
: githubRef;
|
|
26
|
-
|
|
26
|
+
let config;
|
|
27
|
+
try {
|
|
28
|
+
config = await (0, github_1.fetchFileFromRepository)(templateSource || constants_1.HUBSPOT_PROJECT_COMPONENTS_GITHUB_PATH, 'config.json', branch);
|
|
29
|
+
}
|
|
30
|
+
catch (e) {
|
|
31
|
+
logger_1.logger.error((0, lang_1.i18n)(`${i18nKey}.errors.missingConfigFileTemplateSource`));
|
|
32
|
+
process.exit(exitCodes_1.EXIT_CODES.ERROR);
|
|
33
|
+
}
|
|
27
34
|
if (!config || !config[constants_1.PROJECT_COMPONENT_TYPES.PROJECTS]) {
|
|
28
35
|
logger_1.logger.error((0, lang_1.i18n)(`${i18nKey}.errors.noProjectsInConfig`));
|
|
29
36
|
process.exit(exitCodes_1.EXIT_CODES.ERROR);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare function installPublicAppPrompt(env: string, targetAccountId: number, clientId:
|
|
1
|
+
export declare function installPublicAppPrompt(env: string, targetAccountId: number, clientId: string, scopes: string[], redirectUrls: string[], isReinstall?: boolean): Promise<void>;
|
|
@@ -21,7 +21,7 @@ type ScopesPromptResponse = {
|
|
|
21
21
|
*/
|
|
22
22
|
export declare function personalAccessKeyPrompt({ env, account, }: {
|
|
23
23
|
env: string;
|
|
24
|
-
account?:
|
|
24
|
+
account?: number;
|
|
25
25
|
}): Promise<PersonalAccessKeyPromptResponse>;
|
|
26
26
|
export declare const OAUTH_FLOW: (PromptConfig<{
|
|
27
27
|
name: string;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { CLIAccount
|
|
1
|
+
import { CLIAccount } from '@hubspot/local-dev-lib/types/Accounts';
|
|
2
2
|
import { DeveloperTestAccount } from '@hubspot/local-dev-lib/types/developerTestAccounts';
|
|
3
3
|
export declare function selectSandboxTargetAccountPrompt(accounts: CLIAccount[], defaultAccountConfig: CLIAccount): Promise<DeveloperTestAccount | CLIAccount>;
|
|
4
4
|
export declare function selectDeveloperTestTargetAccountPrompt(accounts: CLIAccount[], defaultAccountConfig: CLIAccount): Promise<DeveloperTestAccount | CLIAccount>;
|
|
5
|
-
export declare function confirmDefaultAccountPrompt(accountName: string, accountType:
|
|
5
|
+
export declare function confirmDefaultAccountPrompt(accountName: string, accountType: string): Promise<boolean>;
|
|
6
6
|
export declare function confirmUseExistingDeveloperTestAccountPrompt(account: DeveloperTestAccount): Promise<boolean>;
|
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>;
|