@hubspot/cli 7.0.0-beta.0 → 7.0.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -2
- package/commands/customObject/create.js +4 -1
- package/lang/en.lyaml +2 -2
- package/lib/projects/watch.d.ts +3 -0
- package/lib/projects/watch.js +73 -70
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @hubspot/cli
|
|
2
2
|
|
|
3
|
-
[](https://www.npmjs.com/package/@hubspot/cli) [](https://www.npmjs.com/package/@hubspot/cli) [](https://www.npmjs.com/package/@hubspot/cli?activeTab=versions)
|
|
4
4
|
|
|
5
5
|
A CLI for HubSpot developers to enable local development and automation. [Learn more about building on HubSpot](https://developers.hubspot.com).
|
|
6
6
|
|
|
@@ -58,14 +58,15 @@ There are two ways that the tools can authenticate with HubSpot.
|
|
|
58
58
|
3. Select `OAuth2` and follow the steps
|
|
59
59
|
|
|
60
60
|
_**Note:** The Account ID used should be the Test Account ID (not the developer app ID). Client ID and Client Secret are from the developer app._
|
|
61
|
+
|
|
61
62
|
### Exit Codes
|
|
62
63
|
|
|
63
64
|
The CLI will exit with one of the following exit codes:
|
|
65
|
+
|
|
64
66
|
- `0`: A successful run
|
|
65
67
|
- `1`: There was a config problem or an internal error
|
|
66
68
|
- `2`: There are warnings or validation issues
|
|
67
69
|
|
|
68
|
-
|
|
69
70
|
## Changelog
|
|
70
71
|
|
|
71
72
|
The best way to stay up to date is to check out the [Github Releases](https://github.com/HubSpot/hubspot-cli/releases) and also follow our [developer changelog posts](https://developers.hubspot.com/changelog) for an easier to read breakdown of major changes.
|
|
@@ -16,7 +16,11 @@ exports.describe = i18n(`${i18nKey}.describe`);
|
|
|
16
16
|
exports.handler = async (options) => {
|
|
17
17
|
const { path, name: providedName, derivedAccountId } = options;
|
|
18
18
|
let definitionPath = path;
|
|
19
|
+
let name = providedName;
|
|
19
20
|
trackCommandUsage('custom-object-batch-create', null, derivedAccountId);
|
|
21
|
+
if (!name) {
|
|
22
|
+
name = await (0, promptUtils_1.inputPrompt)(i18n(`${i18nKey}.inputName`));
|
|
23
|
+
}
|
|
20
24
|
if (!definitionPath) {
|
|
21
25
|
definitionPath = await (0, promptUtils_1.inputPrompt)(i18n(`${i18nKey}.inputPath`));
|
|
22
26
|
}
|
|
@@ -25,7 +29,6 @@ exports.handler = async (options) => {
|
|
|
25
29
|
if (!objectJson) {
|
|
26
30
|
process.exit(EXIT_CODES.ERROR);
|
|
27
31
|
}
|
|
28
|
-
const name = providedName || (await (0, promptUtils_1.inputPrompt)(i18n(`${i18nKey}.inputSchema`)));
|
|
29
32
|
try {
|
|
30
33
|
await batchCreateObjects(derivedAccountId, name, objectJson);
|
|
31
34
|
logger.success(i18n(`${i18nKey}.success.objectsCreated`));
|
package/lang/en.lyaml
CHANGED
|
@@ -214,8 +214,8 @@ en:
|
|
|
214
214
|
describe: "Schema name to add the object instance to"
|
|
215
215
|
success:
|
|
216
216
|
objectsCreated: "Objects created"
|
|
217
|
-
|
|
218
|
-
inputPath: "[--path]
|
|
217
|
+
inputName: "[--name] Enter the name of the schema for the custom object(s) you'd like to create:"
|
|
218
|
+
inputPath: "[--path] Enter the path to the JSON file containing the object definitions:"
|
|
219
219
|
schema:
|
|
220
220
|
describe: "Commands for managing custom object schemas."
|
|
221
221
|
subcommands:
|
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/package.json
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hubspot/cli",
|
|
3
|
-
"version": "7.0.0-beta.
|
|
3
|
+
"version": "7.0.0-beta.1",
|
|
4
4
|
"description": "The official CLI for developing on HubSpot",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": "https://github.com/HubSpot/hubspot-cli",
|
|
7
7
|
"dependencies": {
|
|
8
8
|
"@hubspot/local-dev-lib": "3.1.0",
|
|
9
|
-
"@hubspot/serverless-dev-runtime": "7.0.
|
|
9
|
+
"@hubspot/serverless-dev-runtime": "7.0.1",
|
|
10
10
|
"@hubspot/theme-preview-dev-server": "0.0.10",
|
|
11
|
-
"@hubspot/ui-extensions-dev-server": "0.8.
|
|
11
|
+
"@hubspot/ui-extensions-dev-server": "0.8.40",
|
|
12
12
|
"archiver": "^7.0.1",
|
|
13
13
|
"chalk": "^4.1.2",
|
|
14
14
|
"chokidar": "^3.0.1",
|