@hubspot/cli 5.0.2-beta.0 → 5.0.2

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.
Files changed (62) hide show
  1. package/bin/cli.js +1 -1
  2. package/commands/accounts/clean.js +1 -1
  3. package/commands/auth.js +1 -1
  4. package/commands/config/set/defaultMode.js +1 -1
  5. package/commands/create.js +1 -1
  6. package/commands/customObject/create.js +1 -1
  7. package/commands/customObject/schema/create.js +3 -1
  8. package/commands/customObject/schema/delete.js +3 -1
  9. package/commands/customObject/schema/fetch-all.js +3 -1
  10. package/commands/customObject/schema/fetch.js +3 -1
  11. package/commands/customObject/schema/list.js +4 -2
  12. package/commands/customObject/schema/update.js +3 -1
  13. package/commands/filemanager/upload.js +2 -2
  14. package/commands/functions/deploy.js +1 -1
  15. package/commands/functions/list.js +2 -2
  16. package/commands/hubdb/clear.js +1 -1
  17. package/commands/hubdb/create.js +1 -1
  18. package/commands/hubdb/delete.js +1 -1
  19. package/commands/hubdb/fetch.js +1 -1
  20. package/commands/init.js +2 -2
  21. package/commands/lint.js +3 -5
  22. package/commands/list.js +1 -1
  23. package/commands/mv.js +1 -1
  24. package/commands/project/add.js +1 -1
  25. package/commands/project/create.js +1 -0
  26. package/commands/project/deploy.js +1 -1
  27. package/commands/project/dev.js +6 -7
  28. package/commands/project/download.js +1 -1
  29. package/commands/project/listBuilds.js +1 -1
  30. package/commands/project/logs.js +1 -1
  31. package/commands/project/upload.js +2 -4
  32. package/commands/project/watch.js +3 -3
  33. package/commands/remove.js +1 -1
  34. package/commands/sandbox/create.js +2 -4
  35. package/commands/sandbox/delete.js +7 -6
  36. package/commands/sandbox/sync.js +2 -6
  37. package/commands/secrets/addSecret.js +1 -1
  38. package/commands/secrets/deleteSecret.js +1 -1
  39. package/commands/secrets/listSecrets.js +1 -1
  40. package/commands/secrets/updateSecret.js +1 -1
  41. package/commands/upload.js +2 -2
  42. package/lang/en.lyaml +57 -2
  43. package/lib/LocalDevManager.js +7 -2
  44. package/lib/errorHandlers/apiErrors.js +352 -0
  45. package/lib/errorHandlers/fileSystemErrors.js +55 -0
  46. package/lib/errorHandlers/standardErrors.js +95 -0
  47. package/lib/getFunctionArrays.js +18 -0
  48. package/lib/hublValidate.js +32 -0
  49. package/lib/oauth.js +1 -1
  50. package/lib/process.js +42 -0
  51. package/lib/projects.js +24 -8
  52. package/lib/projectsWatch.js +225 -0
  53. package/lib/prompts/downloadProjectPrompt.js +1 -1
  54. package/lib/prompts/projectsLogsPrompt.js +1 -1
  55. package/lib/sandbox-create.js +2 -2
  56. package/lib/sandbox-sync.js +5 -5
  57. package/lib/sandboxes.js +1 -1
  58. package/lib/schema.js +31 -0
  59. package/lib/serverlessLogs.js +2 -2
  60. package/lib/ui.js +1 -0
  61. package/lib/validation.js +1 -1
  62. package/package.json +7 -4
@@ -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('./errorHandlers/apiErrors');
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
+ };
@@ -4,7 +4,7 @@ const { fetchProjects } = require('@hubspot/cli-lib/api/dfs');
4
4
  const {
5
5
  logApiErrorInstance,
6
6
  ApiErrorContext,
7
- } = require('@hubspot/cli-lib/errorHandlers');
7
+ } = require('../../lib/errorHandlers/apiErrors');
8
8
  const { EXIT_CODES } = require('../enums/exitCodes');
9
9
  const { i18n } = require('../lang');
10
10
 
@@ -6,7 +6,7 @@ const { getProjectConfig, ensureProjectExists } = require('../projects');
6
6
  const {
7
7
  logApiErrorInstance,
8
8
  ApiErrorContext,
9
- } = require('@hubspot/cli-lib/errorHandlers');
9
+ } = require('../../lib/errorHandlers/apiErrors');
10
10
  const { logger } = require('@hubspot/cli-lib/logger');
11
11
  const { EXIT_CODES } = require('../enums/exitCodes');
12
12
 
@@ -12,11 +12,11 @@ const { logger } = require('@hubspot/cli-lib/logger');
12
12
  const {
13
13
  debugErrorAndContext,
14
14
  logErrorInstance,
15
- } = require('@hubspot/cli-lib/errorHandlers/standardErrors');
15
+ } = require('./errorHandlers/standardErrors');
16
16
  const {
17
17
  isMissingScopeError,
18
18
  isSpecifiedError,
19
- } = require('@hubspot/cli-lib/errorHandlers/apiErrors');
19
+ } = require('./errorHandlers/apiErrors');
20
20
  const { getHubSpotWebsiteOrigin } = require('@hubspot/cli-lib/lib/urls');
21
21
  const { getEnv, getAccountId } = require('@hubspot/cli-lib');
22
22
  const { createSandbox } = require('@hubspot/cli-lib/sandboxes');
@@ -11,17 +11,17 @@ const {
11
11
  syncTypes,
12
12
  } = require('./sandboxes');
13
13
  const { initiateSync } = require('@hubspot/cli-lib/sandboxes');
14
- const { logErrorInstance } = require('@hubspot/cli-lib/errorHandlers');
14
+ const {
15
+ debugErrorAndContext,
16
+ logErrorInstance,
17
+ } = require('./errorHandlers/standardErrors');
15
18
  const {
16
19
  isSpecifiedError,
17
20
  isMissingScopeError,
18
- } = require('@hubspot/cli-lib/errorHandlers/apiErrors');
21
+ } = require('./errorHandlers/apiErrors');
19
22
  const { getSandboxTypeAsString } = require('./sandboxes');
20
23
  const { getAccountId } = require('@hubspot/cli-lib');
21
24
  const { uiAccountDescription } = require('./ui');
22
- const {
23
- debugErrorAndContext,
24
- } = require('@hubspot/cli-lib/errorHandlers/standardErrors');
25
25
 
26
26
  const i18nKey = 'cli.lib.sandbox.sync';
27
27
 
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
+ };
@@ -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');
@@ -7,9 +8,8 @@ const {
7
8
  logServerlessFunctionApiErrorInstance,
8
9
  logApiErrorInstance,
9
10
  ApiErrorContext,
10
- } = require('@hubspot/cli-lib/errorHandlers');
11
+ } = require('./errorHandlers/apiErrors');
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/lib/ui.js CHANGED
@@ -106,6 +106,7 @@ const uiFeatureHighlight = (commands, title) => {
106
106
  const commandKey = `${i18nKey}.commandKeys.${c}`;
107
107
  const message = i18n(`${commandKey}.message`, {
108
108
  command: uiCommandReference(i18n(`${commandKey}.command`)),
109
+ link: uiLink(i18n(`${commandKey}.linkText`), i18n(`${commandKey}.url`)),
109
110
  });
110
111
  if (i !== 0) {
111
112
  logger.log('');
package/lib/validation.js CHANGED
@@ -13,7 +13,7 @@ const {
13
13
  OAUTH_AUTH_METHOD,
14
14
  PERSONAL_ACCESS_KEY_AUTH_METHOD,
15
15
  } = require('@hubspot/cli-lib/lib/constants');
16
- const { commaSeparatedValues } = require('@hubspot/cli-lib/lib/text');
16
+ const { commaSeparatedValues } = require('@hubspot/local-dev-lib/text');
17
17
  const { getAbsoluteFilePath } = require('@hubspot/cli-lib/path');
18
18
  const { getOauthManager } = require('@hubspot/cli-lib/oauth');
19
19
  const {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hubspot/cli",
3
- "version": "5.0.2-beta.0",
3
+ "version": "5.0.2",
4
4
  "description": "CLI for working with HubSpot",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -9,8 +9,9 @@
9
9
  },
10
10
  "dependencies": {
11
11
  "@hubspot/cli-lib": "^5.0.1",
12
- "@hubspot/serverless-dev-runtime": "4.2.1-beta.3",
13
- "@hubspot/ui-extensions-dev-server": "^0.7.2",
12
+ "@hubspot/local-dev-lib": "^0.0.7",
13
+ "@hubspot/serverless-dev-runtime": "5.0.2",
14
+ "@hubspot/ui-extensions-dev-server": "^0.8.0",
14
15
  "archiver": "^5.3.0",
15
16
  "chalk": "^4.1.2",
16
17
  "chokidar": "^3.0.1",
@@ -24,7 +25,9 @@
24
25
  "moment": "^2.29.1",
25
26
  "open": "^7.0.3",
26
27
  "ora": "^4.0.3",
28
+ "p-queue": "^6.0.2",
27
29
  "strip-ansi": "^5.2.0",
30
+ "table": "^6.6.0",
28
31
  "tmp": "^0.2.1",
29
32
  "update-notifier": "^5.1.0",
30
33
  "yargs": "15.4.1"
@@ -42,5 +45,5 @@
42
45
  "publishConfig": {
43
46
  "access": "public"
44
47
  },
45
- "gitHead": "539e279526f9554f840b857bf4873a3b856684a3"
48
+ "gitHead": "44cbdf6dae130e268015d3e9afb612729b539915"
46
49
  }