@hubspot/cli 5.0.2-beta.0 → 5.0.2-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/commands/customObject/schema/list.js +1 -1
- package/commands/functions/list.js +1 -1
- package/commands/init.js +1 -1
- package/commands/lint.js +2 -4
- package/commands/project/dev.js +1 -1
- package/commands/project/watch.js +2 -2
- package/lang/en.lyaml +22 -2
- package/lib/LocalDevManager.js +7 -2
- package/lib/getFunctionArrays.js +18 -0
- package/lib/hublValidate.js +32 -0
- package/lib/oauth.js +1 -1
- package/lib/process.js +42 -0
- package/lib/projects.js +21 -3
- package/lib/projectsWatch.js +225 -0
- package/lib/sandboxes.js +1 -1
- package/lib/schema.js +31 -0
- package/lib/serverlessLogs.js +1 -1
- package/package.json +5 -3
|
@@ -4,7 +4,7 @@ const { logErrorInstance } = require('@hubspot/cli-lib/errorHandlers');
|
|
|
4
4
|
const { loadAndValidateOptions } = require('../../../lib/validation');
|
|
5
5
|
const { trackCommandUsage } = require('../../../lib/usageTracking');
|
|
6
6
|
const { getAccountId } = require('../../../lib/commonOpts');
|
|
7
|
-
const { listSchemas } = require('
|
|
7
|
+
const { listSchemas } = require('../../../lib/schema');
|
|
8
8
|
const { i18n } = require('../../../lib/lang');
|
|
9
9
|
|
|
10
10
|
const i18nKey = 'cli.commands.customObject.subcommands.schema.subcommands.list';
|
|
@@ -4,7 +4,7 @@ const {
|
|
|
4
4
|
logApiErrorInstance,
|
|
5
5
|
ApiErrorContext,
|
|
6
6
|
} = require('@hubspot/cli-lib/errorHandlers');
|
|
7
|
-
const { getFunctionArrays } = require('
|
|
7
|
+
const { getFunctionArrays } = require('../../lib/getFunctionArrays');
|
|
8
8
|
const {
|
|
9
9
|
getTableContents,
|
|
10
10
|
getTableHeader,
|
package/commands/init.js
CHANGED
|
@@ -7,7 +7,7 @@ const {
|
|
|
7
7
|
updateDefaultAccount,
|
|
8
8
|
} = require('@hubspot/cli-lib/lib/config');
|
|
9
9
|
const { addConfigOptions } = require('../lib/commonOpts');
|
|
10
|
-
const { handleExit } = require('
|
|
10
|
+
const { handleExit } = require('../lib/process');
|
|
11
11
|
const { checkAndUpdateGitignore } = require('@hubspot/cli-lib/lib/git');
|
|
12
12
|
const { logErrorInstance } = require('@hubspot/cli-lib/errorHandlers');
|
|
13
13
|
const {
|
package/commands/lint.js
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
|
-
const {
|
|
2
|
-
|
|
3
|
-
printHublValidationResult,
|
|
4
|
-
} = require('@hubspot/cli-lib/validate');
|
|
1
|
+
const { lint } = require('@hubspot/cli-lib/validate');
|
|
2
|
+
const { printHublValidationResult } = require('../lib/hublValidate');
|
|
5
3
|
const { logger } = require('@hubspot/cli-lib/logger');
|
|
6
4
|
const { logErrorInstance } = require('@hubspot/cli-lib/errorHandlers');
|
|
7
5
|
|
package/commands/project/dev.js
CHANGED
|
@@ -10,11 +10,11 @@ const {
|
|
|
10
10
|
trackCommandMetadataUsage,
|
|
11
11
|
} = require('../../lib/usageTracking');
|
|
12
12
|
const { loadAndValidateOptions } = require('../../lib/validation');
|
|
13
|
+
const { handleExit } = require('../../lib/process');
|
|
13
14
|
const { i18n } = require('../../lib/lang');
|
|
14
15
|
const { logger } = require('@hubspot/cli-lib/logger');
|
|
15
16
|
const { getConfigAccounts } = require('@hubspot/cli-lib/lib/config');
|
|
16
17
|
const { createProject, fetchProject } = require('@hubspot/cli-lib/api/dfs');
|
|
17
|
-
const { handleExit } = require('@hubspot/cli-lib/lib/process');
|
|
18
18
|
const {
|
|
19
19
|
getProjectConfig,
|
|
20
20
|
ensureProjectExists,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
const { i18n } = require('../../lib/lang');
|
|
2
|
-
const { createWatcher } = require('
|
|
2
|
+
const { createWatcher } = require('../../lib/projectsWatch');
|
|
3
3
|
const {
|
|
4
4
|
logApiErrorInstance,
|
|
5
5
|
ApiErrorContext,
|
|
@@ -30,7 +30,7 @@ const {
|
|
|
30
30
|
} = require('@hubspot/cli-lib/api/dfs');
|
|
31
31
|
const { loadAndValidateOptions } = require('../../lib/validation');
|
|
32
32
|
const { EXIT_CODES } = require('../../lib/enums/exitCodes');
|
|
33
|
-
const { handleKeypress, handleExit } = require('
|
|
33
|
+
const { handleKeypress, handleExit } = require('../../lib/process');
|
|
34
34
|
|
|
35
35
|
const i18nKey = 'cli.commands.project.subcommands.watch';
|
|
36
36
|
|
package/lang/en.lyaml
CHANGED
|
@@ -587,12 +587,31 @@ en:
|
|
|
587
587
|
default: "Watch a project within the myProjectFolder folder"
|
|
588
588
|
logs:
|
|
589
589
|
processExited: "Stopping watcher..."
|
|
590
|
+
watchCancelledFromUi: "The watch process has been cancelled from the UI. Any changes made since cancelling have not been uploaded. To resume watching, rerun {{#yellow}}`hs project watch`{{/yellow}}."
|
|
591
|
+
resuming: "Resuming watcher..."
|
|
592
|
+
uploadSucceeded: "Uploaded file \"{{ filePath }}\" to \"{{ remotePath }}\""
|
|
593
|
+
deleteFileSucceeded: "Deleted file \"{{ remotePath }}\""
|
|
594
|
+
deleteFolderSucceeded: "Deleted folder \"{{ remotePath }}\""
|
|
595
|
+
watching: "Watcher is ready and watching \"{{ projectDir }}\". Any changes detected will be automatically uploaded."
|
|
596
|
+
previousStagingBuildCancelled: "Killed the previous watch process. Please try running `hs project watch` again"
|
|
590
597
|
positionals:
|
|
591
598
|
path:
|
|
592
599
|
describe: "Path to a project folder"
|
|
593
600
|
options:
|
|
594
601
|
initialUpload:
|
|
595
602
|
describe: "Upload directory before watching for updates"
|
|
603
|
+
debug:
|
|
604
|
+
pause: "Pausing watcher, attempting to queue build"
|
|
605
|
+
buildStarted: "Build queued."
|
|
606
|
+
extensionNotAllowed: "Skipping \"{{ filePath }}\" due to unsupported extension"
|
|
607
|
+
ignored: "Skipping \"{{ filePath }}\" due to an ignore rule"
|
|
608
|
+
uploading: "Attempting to upload file \"{{ filePath }}\" to \"{{ remotePath }}\""
|
|
609
|
+
attemptNewBuild: "Attempting to create a new build"
|
|
610
|
+
fileAlreadyQueued: "File \"{{ filePath }}\" is already queued for upload"
|
|
611
|
+
errors:
|
|
612
|
+
uploadFailed: "Failed to upload file \"{{ filePath }}\" to \"{{ remotePath }}\""
|
|
613
|
+
deleteFileFailed: "Failed to delete file \"{{ remotePath }}\""
|
|
614
|
+
deleteFolderFailed: "Failed to delete folder \"{{ remotePath }}\""
|
|
596
615
|
download:
|
|
597
616
|
describe: "Download your project files from HubSpot and write to a path on your computer"
|
|
598
617
|
examples:
|
|
@@ -874,7 +893,7 @@ en:
|
|
|
874
893
|
failedToInitialize: "Missing required arguments to initialize Local Dev"
|
|
875
894
|
noDeployedBuild: "There is no deployed build for this project in {{ accountIdentifier }}. Run {{ uploadCommand }} to upload and deploy your project."
|
|
876
895
|
noComponents: "There are no components in this project."
|
|
877
|
-
noRunnableComponents: "
|
|
896
|
+
noRunnableComponents: "No supported components were found under {{#bold}}{{ projectSourceDir }}{{/bold}}. Run {{ command }} to see a list of available components."
|
|
878
897
|
betaMessage: "HubSpot projects local development"
|
|
879
898
|
running: "Running {{#bold}}{{ projectName }}{{/bold}} locally on {{ accountIdentifier }}, waiting for changes ..."
|
|
880
899
|
quitHelper: "Press {{#bold}}'q'{{/bold}} to stop the local dev server"
|
|
@@ -885,7 +904,7 @@ en:
|
|
|
885
904
|
uploadWarning:
|
|
886
905
|
appLabel: "[App]"
|
|
887
906
|
uiExtensionLabel: "[UI Extension]"
|
|
888
|
-
missingComponents: "
|
|
907
|
+
missingComponents: "Couldn't find the following components in the deployed build for this project: {{#bold}}'{{ missingComponents }}'{{/bold}}. This may cause issues in local development."
|
|
889
908
|
defaultWarning: "Changing project configuration requires a new project build."
|
|
890
909
|
header: "{{ warning }} To reflect these changes and continue testing:"
|
|
891
910
|
stopDev: " * Stop {{ command }}"
|
|
@@ -907,6 +926,7 @@ en:
|
|
|
907
926
|
emptySource: "Source directory \"{{ srcDir }}\" is empty. Add files to your project and rerun `{{#yellow}}hs project upload{{/yellow}}` to upload them to HubSpot."
|
|
908
927
|
compressed: "Project files compressed: {{ byteCount }} bytes"
|
|
909
928
|
compressing: "Compressing build files to \"{{ path }}\""
|
|
929
|
+
fileFiltered: "Ignore rule triggered for \"{{ filename }}\""
|
|
910
930
|
ensureProjectExists:
|
|
911
931
|
createPrompt: "The project {{ projectName }} does not exist in {{ accountIdentifier }}. Would you like to create it?"
|
|
912
932
|
createSuccess: "New project {{#bold}}{{ projectName }}{{/bold}} successfully created in {{#bold}}{{ accountIdentifier }}{{/bold}}."
|
package/lib/LocalDevManager.js
CHANGED
|
@@ -2,8 +2,8 @@ const path = require('path');
|
|
|
2
2
|
const chokidar = require('chokidar');
|
|
3
3
|
const chalk = require('chalk');
|
|
4
4
|
const { i18n } = require('./lang');
|
|
5
|
+
const { handleKeypress } = require('./process');
|
|
5
6
|
const { logger } = require('@hubspot/cli-lib/logger');
|
|
6
|
-
const { handleKeypress } = require('@hubspot/cli-lib/lib/process');
|
|
7
7
|
const {
|
|
8
8
|
getAccountId,
|
|
9
9
|
getConfigDefaultAccount,
|
|
@@ -89,7 +89,12 @@ class LocalDevManager {
|
|
|
89
89
|
|
|
90
90
|
// The project does not contain any components that support local development
|
|
91
91
|
if (!runnableComponents.length) {
|
|
92
|
-
logger.error(
|
|
92
|
+
logger.error(
|
|
93
|
+
i18n(`${i18nKey}.noRunnableComponents`, {
|
|
94
|
+
projectSourceDir: this.projectSourceDir,
|
|
95
|
+
command: uiCommandReference('hs project add'),
|
|
96
|
+
})
|
|
97
|
+
);
|
|
93
98
|
process.exit(EXIT_CODES.SUCCESS);
|
|
94
99
|
}
|
|
95
100
|
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
const moment = require('moment');
|
|
2
|
+
|
|
3
|
+
const getFunctionArrays = resp => {
|
|
4
|
+
return resp.objects.map(func => {
|
|
5
|
+
const { route, method, created, updated, secretNames } = func;
|
|
6
|
+
return [
|
|
7
|
+
route,
|
|
8
|
+
method,
|
|
9
|
+
secretNames.join(', '),
|
|
10
|
+
moment(created).format(),
|
|
11
|
+
moment(updated).format(),
|
|
12
|
+
];
|
|
13
|
+
});
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
module.exports = {
|
|
17
|
+
getFunctionArrays,
|
|
18
|
+
};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
const { logger } = require('@hubspot/cli-lib/logger');
|
|
2
|
+
|
|
3
|
+
const getErrorsFromHublValidationObject = validation =>
|
|
4
|
+
(validation && validation.meta && validation.meta.template_errors) || [];
|
|
5
|
+
|
|
6
|
+
function printHublValidationError(err) {
|
|
7
|
+
const { severity, message, lineno, startPosition } = err;
|
|
8
|
+
const method = severity === 'FATAL' ? 'error' : 'warn';
|
|
9
|
+
logger[method]('[%d, %d]: %s', lineno, startPosition, message);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
function printHublValidationResult({ file, validation }) {
|
|
13
|
+
let count = 0;
|
|
14
|
+
const errors = getErrorsFromHublValidationObject(validation);
|
|
15
|
+
if (!errors.length) {
|
|
16
|
+
return count;
|
|
17
|
+
}
|
|
18
|
+
logger.group(file);
|
|
19
|
+
errors.forEach(err => {
|
|
20
|
+
if (err.reason !== 'SYNTAX_ERROR') {
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
++count;
|
|
24
|
+
printHublValidationError(err);
|
|
25
|
+
});
|
|
26
|
+
logger.groupEnd(file);
|
|
27
|
+
return count;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
module.exports = {
|
|
31
|
+
printHublValidationResult,
|
|
32
|
+
};
|
package/lib/oauth.js
CHANGED
|
@@ -3,7 +3,7 @@ const open = require('open');
|
|
|
3
3
|
const OAuth2Manager = require('@hubspot/cli-lib/lib/models/OAuth2Manager');
|
|
4
4
|
const { getAccountConfig } = require('@hubspot/cli-lib/lib/config');
|
|
5
5
|
const { addOauthToAccountConfig } = require('@hubspot/cli-lib/oauth');
|
|
6
|
-
const { handleExit } = require('
|
|
6
|
+
const { handleExit } = require('./process');
|
|
7
7
|
const { getHubSpotWebsiteOrigin } = require('@hubspot/cli-lib/lib/urls');
|
|
8
8
|
const { logger } = require('@hubspot/cli-lib/logger');
|
|
9
9
|
const { ENVIRONMENTS } = require('@hubspot/cli-lib/lib/constants');
|
package/lib/process.js
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
const readline = require('readline');
|
|
2
|
+
|
|
3
|
+
const handleExit = callback => {
|
|
4
|
+
const terminationSignals = [
|
|
5
|
+
'beforeExit',
|
|
6
|
+
'SIGINT',
|
|
7
|
+
'SIGUSR1',
|
|
8
|
+
'SIGUSR2',
|
|
9
|
+
'uncaughtException',
|
|
10
|
+
'SIGTERM',
|
|
11
|
+
'SIGHUP',
|
|
12
|
+
];
|
|
13
|
+
terminationSignals.forEach(signal => {
|
|
14
|
+
process.removeAllListeners(signal);
|
|
15
|
+
|
|
16
|
+
process.on(signal, async () => {
|
|
17
|
+
await callback();
|
|
18
|
+
});
|
|
19
|
+
});
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
const handleKeypress = callback => {
|
|
23
|
+
readline.createInterface(process.stdin, process.stdout);
|
|
24
|
+
readline.emitKeypressEvents(process.stdin);
|
|
25
|
+
|
|
26
|
+
if (process.stdin.isTTY) {
|
|
27
|
+
process.stdin.setRawMode(true);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
process.stdin.removeAllListeners('keypress');
|
|
31
|
+
|
|
32
|
+
process.stdin.on('keypress', (str, key) => {
|
|
33
|
+
if (key) {
|
|
34
|
+
callback(key);
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
module.exports = {
|
|
40
|
+
handleExit,
|
|
41
|
+
handleKeypress,
|
|
42
|
+
};
|
package/lib/projects.js
CHANGED
|
@@ -522,9 +522,27 @@ const handleProjectUpload = async (
|
|
|
522
522
|
|
|
523
523
|
archive.pipe(output);
|
|
524
524
|
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
525
|
+
let loggedIgnoredNodeModule = false;
|
|
526
|
+
|
|
527
|
+
archive.directory(srcDir, false, file => {
|
|
528
|
+
const ignored = shouldIgnoreFile(file.name, true);
|
|
529
|
+
if (ignored) {
|
|
530
|
+
const isNodeModule = file.name.includes('node_modules');
|
|
531
|
+
|
|
532
|
+
if (!isNodeModule || !loggedIgnoredNodeModule) {
|
|
533
|
+
logger.debug(
|
|
534
|
+
i18n(`${i18nKey}.handleProjectUpload.fileFiltered`, {
|
|
535
|
+
filename: file.name,
|
|
536
|
+
})
|
|
537
|
+
);
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
if (isNodeModule && !loggedIgnoredNodeModule) {
|
|
541
|
+
loggedIgnoredNodeModule = true;
|
|
542
|
+
}
|
|
543
|
+
}
|
|
544
|
+
return ignored ? false : file;
|
|
545
|
+
});
|
|
528
546
|
|
|
529
547
|
archive.finalize();
|
|
530
548
|
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
const chokidar = require('chokidar');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const chalk = require('chalk');
|
|
4
|
+
const { default: PQueue } = require('p-queue');
|
|
5
|
+
const {
|
|
6
|
+
logApiErrorInstance,
|
|
7
|
+
ApiErrorContext,
|
|
8
|
+
} = require('@hubspot/cli-lib/errorHandlers');
|
|
9
|
+
const { i18n } = require('@hubspot/cli-lib/lib/lang');
|
|
10
|
+
const { logger } = require('@hubspot/cli-lib/logger');
|
|
11
|
+
const { isAllowedExtension } = require('@hubspot/cli-lib/path');
|
|
12
|
+
const { shouldIgnoreFile } = require('@hubspot/cli-lib/ignoreRules');
|
|
13
|
+
const {
|
|
14
|
+
cancelStagedBuild,
|
|
15
|
+
provisionBuild,
|
|
16
|
+
uploadFileToBuild,
|
|
17
|
+
deleteFileFromBuild,
|
|
18
|
+
queueBuild,
|
|
19
|
+
} = require('@hubspot/cli-lib/api/dfs');
|
|
20
|
+
const { ERROR_TYPES } = require('@hubspot/cli-lib/lib/constants');
|
|
21
|
+
|
|
22
|
+
const i18nKey = 'cli.commands.project.subcommands.watch';
|
|
23
|
+
|
|
24
|
+
const queue = new PQueue({
|
|
25
|
+
concurrency: 10,
|
|
26
|
+
});
|
|
27
|
+
const standbyeQueue = [];
|
|
28
|
+
let currentBuildId = null;
|
|
29
|
+
let handleBuildStatus, handleUserInput;
|
|
30
|
+
let timer;
|
|
31
|
+
|
|
32
|
+
const processStandByQueue = async (accountId, projectName) => {
|
|
33
|
+
queue.addAll(
|
|
34
|
+
standbyeQueue.map(({ filePath, remotePath, action }) => {
|
|
35
|
+
return async () => {
|
|
36
|
+
queueFileOrFolder(accountId, projectName, filePath, remotePath, action);
|
|
37
|
+
};
|
|
38
|
+
})
|
|
39
|
+
);
|
|
40
|
+
standbyeQueue.length = 0;
|
|
41
|
+
debounceQueueBuild(accountId, projectName);
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
const createNewStagingBuild = async (accountId, projectName) => {
|
|
45
|
+
currentBuildId = await createNewBuild(accountId, projectName);
|
|
46
|
+
|
|
47
|
+
handleUserInput(accountId, projectName, currentBuildId);
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
const debounceQueueBuild = (accountId, projectName) => {
|
|
51
|
+
if (timer) {
|
|
52
|
+
clearTimeout(timer);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
timer = setTimeout(async () => {
|
|
56
|
+
logger.debug(i18n(`${i18nKey}.debug.pause`, { projectName }));
|
|
57
|
+
queue.pause();
|
|
58
|
+
await queue.onIdle();
|
|
59
|
+
|
|
60
|
+
try {
|
|
61
|
+
await queueBuild(accountId, projectName);
|
|
62
|
+
logger.debug(i18n(`${i18nKey}.debug.buildStarted`, { projectName }));
|
|
63
|
+
} catch (err) {
|
|
64
|
+
if (
|
|
65
|
+
err.error &&
|
|
66
|
+
err.error.subCategory === ERROR_TYPES.MISSING_PROJECT_PROVISION
|
|
67
|
+
) {
|
|
68
|
+
logger.log(i18n(`${i18nKey}.logs.watchCancelledFromUi`));
|
|
69
|
+
process.exit(0);
|
|
70
|
+
} else {
|
|
71
|
+
logApiErrorInstance(
|
|
72
|
+
err,
|
|
73
|
+
new ApiErrorContext({ accountId, projectName })
|
|
74
|
+
);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
await handleBuildStatus(accountId, projectName, currentBuildId);
|
|
81
|
+
|
|
82
|
+
await createNewStagingBuild(accountId, projectName);
|
|
83
|
+
|
|
84
|
+
if (standbyeQueue.length > 0) {
|
|
85
|
+
await processStandByQueue(accountId, projectName);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
queue.start();
|
|
89
|
+
logger.log(i18n(`${i18nKey}.logs.resuming`));
|
|
90
|
+
logger.log(`\n> Press ${chalk.bold('q')} to quit watching\n`);
|
|
91
|
+
}, 2000);
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
const queueFileOrFolder = async (
|
|
95
|
+
accountId,
|
|
96
|
+
projectName,
|
|
97
|
+
filePath,
|
|
98
|
+
remotePath,
|
|
99
|
+
action
|
|
100
|
+
) => {
|
|
101
|
+
if (action === 'upload' && !isAllowedExtension(filePath)) {
|
|
102
|
+
logger.debug(i18n(`${i18nKey}.debug.extensionNotAllowed`, { filePath }));
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
if (shouldIgnoreFile(filePath, true)) {
|
|
106
|
+
logger.debug(i18n(`${i18nKey}.debug.ignored`, { filePath }));
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
if (!queue.isPaused) {
|
|
110
|
+
debounceQueueBuild(accountId, projectName);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
logger.debug(i18n(`${i18nKey}.debug.uploading`, { filePath, remotePath }));
|
|
114
|
+
|
|
115
|
+
return queue.add(async () => {
|
|
116
|
+
try {
|
|
117
|
+
if (action === 'upload') {
|
|
118
|
+
await uploadFileToBuild(accountId, projectName, filePath, remotePath);
|
|
119
|
+
} else if (action === 'deleteFile' || action === 'deleteFolder') {
|
|
120
|
+
await deleteFileFromBuild(accountId, projectName, remotePath);
|
|
121
|
+
}
|
|
122
|
+
logger.log(
|
|
123
|
+
i18n(`${i18nKey}.logs.${action}Succeeded`, { filePath, remotePath })
|
|
124
|
+
);
|
|
125
|
+
} catch (err) {
|
|
126
|
+
logger.debug(
|
|
127
|
+
i18n(`${i18nKey}.errors.${action}Failed`, { filePath, remotePath })
|
|
128
|
+
);
|
|
129
|
+
}
|
|
130
|
+
});
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
const createNewBuild = async (accountId, projectName) => {
|
|
134
|
+
try {
|
|
135
|
+
logger.debug(i18n(`${i18nKey}.debug.attemptNewBuild`));
|
|
136
|
+
const { buildId } = await provisionBuild(accountId, projectName);
|
|
137
|
+
return buildId;
|
|
138
|
+
} catch (err) {
|
|
139
|
+
logApiErrorInstance(err, new ApiErrorContext({ accountId, projectName }));
|
|
140
|
+
if (err.error.subCategory !== ERROR_TYPES.PROJECT_LOCKED) {
|
|
141
|
+
await cancelStagedBuild(accountId, projectName);
|
|
142
|
+
logger.log(i18n(`${i18nKey}.logs.previousStagingBuildCancelled`));
|
|
143
|
+
}
|
|
144
|
+
process.exit(1);
|
|
145
|
+
}
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
const handleWatchEvent = async (
|
|
149
|
+
accountId,
|
|
150
|
+
projectName,
|
|
151
|
+
projectSourceDir,
|
|
152
|
+
filePath,
|
|
153
|
+
action = 'upload'
|
|
154
|
+
) => {
|
|
155
|
+
const remotePath = path.relative(projectSourceDir, filePath);
|
|
156
|
+
if (queue.isPaused) {
|
|
157
|
+
standbyeQueue.find(file => file.filePath === filePath)
|
|
158
|
+
? logger.debug(i18n(`${i18nKey}.debug.fileAlreadyQueued`, { filePath }))
|
|
159
|
+
: standbyeQueue.push({
|
|
160
|
+
filePath,
|
|
161
|
+
remotePath,
|
|
162
|
+
action,
|
|
163
|
+
});
|
|
164
|
+
} else {
|
|
165
|
+
await queueFileOrFolder(
|
|
166
|
+
accountId,
|
|
167
|
+
projectName,
|
|
168
|
+
filePath,
|
|
169
|
+
remotePath,
|
|
170
|
+
action
|
|
171
|
+
);
|
|
172
|
+
}
|
|
173
|
+
};
|
|
174
|
+
|
|
175
|
+
const createWatcher = async (
|
|
176
|
+
accountId,
|
|
177
|
+
projectConfig,
|
|
178
|
+
projectDir,
|
|
179
|
+
handleBuildStatusFn,
|
|
180
|
+
handleUserInputFn
|
|
181
|
+
) => {
|
|
182
|
+
const projectSourceDir = path.join(projectDir, projectConfig.srcDir);
|
|
183
|
+
|
|
184
|
+
handleBuildStatus = handleBuildStatusFn;
|
|
185
|
+
handleUserInput = handleUserInputFn;
|
|
186
|
+
|
|
187
|
+
await createNewStagingBuild(accountId, projectConfig.name);
|
|
188
|
+
|
|
189
|
+
const watcher = chokidar.watch(projectSourceDir, {
|
|
190
|
+
ignoreInitial: true,
|
|
191
|
+
ignored: file => shouldIgnoreFile(file),
|
|
192
|
+
});
|
|
193
|
+
watcher.on('ready', async () => {
|
|
194
|
+
logger.log(i18n(`${i18nKey}.logs.watching`, { projectDir }));
|
|
195
|
+
logger.log(`\n> Press ${chalk.bold('q')} to quit watching\n`);
|
|
196
|
+
});
|
|
197
|
+
watcher.on('add', async path => {
|
|
198
|
+
handleWatchEvent(accountId, projectConfig.name, projectSourceDir, path);
|
|
199
|
+
});
|
|
200
|
+
watcher.on('change', async path => {
|
|
201
|
+
handleWatchEvent(accountId, projectConfig.name, projectSourceDir, path);
|
|
202
|
+
});
|
|
203
|
+
watcher.on('unlink', async path => {
|
|
204
|
+
handleWatchEvent(
|
|
205
|
+
accountId,
|
|
206
|
+
projectConfig.name,
|
|
207
|
+
projectSourceDir,
|
|
208
|
+
path,
|
|
209
|
+
'deleteFile'
|
|
210
|
+
);
|
|
211
|
+
});
|
|
212
|
+
watcher.on('unlinkDir', async path => {
|
|
213
|
+
handleWatchEvent(
|
|
214
|
+
accountId,
|
|
215
|
+
projectConfig.name,
|
|
216
|
+
projectSourceDir,
|
|
217
|
+
path,
|
|
218
|
+
'deleteFolder'
|
|
219
|
+
);
|
|
220
|
+
});
|
|
221
|
+
};
|
|
222
|
+
|
|
223
|
+
module.exports = {
|
|
224
|
+
createWatcher,
|
|
225
|
+
};
|
package/lib/sandboxes.js
CHANGED
|
@@ -6,6 +6,7 @@ const {
|
|
|
6
6
|
} = require('@hubspot/cli-lib');
|
|
7
7
|
const chalk = require('chalk');
|
|
8
8
|
const { i18n } = require('./lang');
|
|
9
|
+
const { handleExit, handleKeypress } = require('./process');
|
|
9
10
|
const { logger } = require('@hubspot/cli-lib/logger');
|
|
10
11
|
const {
|
|
11
12
|
updateConfigWithPersonalAccessKey,
|
|
@@ -17,7 +18,6 @@ const {
|
|
|
17
18
|
fetchTypes,
|
|
18
19
|
getSandboxUsageLimits,
|
|
19
20
|
} = require('@hubspot/cli-lib/sandboxes');
|
|
20
|
-
const { handleExit, handleKeypress } = require('@hubspot/cli-lib/lib/process');
|
|
21
21
|
const { accountNameExistsInConfig } = require('@hubspot/cli-lib/lib/config');
|
|
22
22
|
const CliProgressMultibarManager = require('./CliProgressMultibarManager');
|
|
23
23
|
const { promptUser } = require('./prompts/promptUtils');
|
package/lib/schema.js
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
const chalk = require('chalk');
|
|
2
|
+
const { logger } = require('@hubspot/cli-lib/logger');
|
|
3
|
+
const { table, getBorderCharacters } = require('table');
|
|
4
|
+
const { fetchSchemas } = require('@hubspot/cli-lib/api/schema');
|
|
5
|
+
|
|
6
|
+
const logSchemas = schemas => {
|
|
7
|
+
const data = schemas
|
|
8
|
+
.map(r => [r.labels.singular, r.name, r.objectTypeId || ''])
|
|
9
|
+
.sort((a, b) => (a[1] > b[1] ? 1 : -1));
|
|
10
|
+
data.unshift([
|
|
11
|
+
chalk.bold('Label'),
|
|
12
|
+
chalk.bold('Name'),
|
|
13
|
+
chalk.bold('objectTypeId'),
|
|
14
|
+
]);
|
|
15
|
+
|
|
16
|
+
const tableConfig = {
|
|
17
|
+
singleLine: true,
|
|
18
|
+
border: getBorderCharacters('honeywell'),
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
logger.log(data.length ? table(data, tableConfig) : 'No Schemas were found');
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
const listSchemas = async accountId => {
|
|
25
|
+
const response = await fetchSchemas(accountId);
|
|
26
|
+
logSchemas(response.results);
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
module.exports = {
|
|
30
|
+
listSchemas,
|
|
31
|
+
};
|
package/lib/serverlessLogs.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
const https = require('https');
|
|
2
2
|
const SpinniesManager = require('./SpinniesManager');
|
|
3
|
+
const { handleExit, handleKeypress } = require('./process');
|
|
3
4
|
const chalk = require('chalk');
|
|
4
5
|
const { logger } = require('@hubspot/cli-lib/logger');
|
|
5
6
|
const { outputLogs } = require('@hubspot/cli-lib/lib/logs');
|
|
@@ -9,7 +10,6 @@ const {
|
|
|
9
10
|
ApiErrorContext,
|
|
10
11
|
} = require('@hubspot/cli-lib/errorHandlers');
|
|
11
12
|
const { base64EncodeString } = require('@hubspot/cli-lib/lib/encoding');
|
|
12
|
-
const { handleExit, handleKeypress } = require('@hubspot/cli-lib/lib/process');
|
|
13
13
|
|
|
14
14
|
const { EXIT_CODES } = require('../lib/enums/exitCodes');
|
|
15
15
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hubspot/cli",
|
|
3
|
-
"version": "5.0.2-beta.
|
|
3
|
+
"version": "5.0.2-beta.1",
|
|
4
4
|
"description": "CLI for working with HubSpot",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
"dependencies": {
|
|
11
11
|
"@hubspot/cli-lib": "^5.0.1",
|
|
12
12
|
"@hubspot/serverless-dev-runtime": "4.2.1-beta.3",
|
|
13
|
-
"@hubspot/ui-extensions-dev-server": "^0.
|
|
13
|
+
"@hubspot/ui-extensions-dev-server": "^0.8.0",
|
|
14
14
|
"archiver": "^5.3.0",
|
|
15
15
|
"chalk": "^4.1.2",
|
|
16
16
|
"chokidar": "^3.0.1",
|
|
@@ -24,7 +24,9 @@
|
|
|
24
24
|
"moment": "^2.29.1",
|
|
25
25
|
"open": "^7.0.3",
|
|
26
26
|
"ora": "^4.0.3",
|
|
27
|
+
"p-queue": "^6.0.2",
|
|
27
28
|
"strip-ansi": "^5.2.0",
|
|
29
|
+
"table": "^6.6.0",
|
|
28
30
|
"tmp": "^0.2.1",
|
|
29
31
|
"update-notifier": "^5.1.0",
|
|
30
32
|
"yargs": "15.4.1"
|
|
@@ -42,5 +44,5 @@
|
|
|
42
44
|
"publishConfig": {
|
|
43
45
|
"access": "public"
|
|
44
46
|
},
|
|
45
|
-
"gitHead": "
|
|
47
|
+
"gitHead": "ffa9b2bd4597057e8b0c640c9ceb9c37a12df19c"
|
|
46
48
|
}
|