@hubspot/cli 4.2.1-beta.1 → 4.2.1-beta.3
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/bin/cli.js +1 -1
- package/commands/accounts/clean.js +139 -0
- package/commands/accounts/list.js +1 -1
- package/commands/accounts.js +2 -0
- package/commands/project/add.js +1 -1
- package/commands/project/dev.js +84 -98
- package/commands/project/download.js +10 -19
- package/commands/project/listBuilds.js +4 -1
- package/commands/project/upload.js +3 -0
- package/commands/project/watch.js +3 -0
- package/commands/project.js +9 -6
- package/commands/sandbox/create.js +10 -1
- package/commands/sandbox/delete.js +8 -12
- package/commands/sandbox.js +3 -2
- package/lang/en.lyaml +55 -59
- package/lib/DevServerManager.js +82 -80
- package/lib/LocalDevManager.js +240 -561
- package/lib/SpinniesManager.js +2 -82
- package/lib/projectStructure.js +107 -0
- package/lib/projects.js +70 -22
- package/lib/prompts/downloadProjectPrompt.js +1 -4
- package/lib/prompts/projectDevTargetAccountPrompt.js +15 -0
- package/lib/ui.js +13 -1
- package/lib/usageTracking.js +57 -0
- package/package.json +5 -8
- package/lib/LocalDevManagerV2.js +0 -129
|
@@ -28,8 +28,8 @@ const { promptUser } = require('../../lib/prompts/promptUtils');
|
|
|
28
28
|
const { getHubSpotWebsiteOrigin } = require('@hubspot/cli-lib/lib/urls');
|
|
29
29
|
const {
|
|
30
30
|
isSpecifiedError,
|
|
31
|
+
isSpecifiedHubSpotAuthError,
|
|
31
32
|
} = require('@hubspot/cli-lib/errorHandlers/apiErrors');
|
|
32
|
-
const { HubSpotAuthError } = require('@hubspot/cli-lib/lib/models/Errors');
|
|
33
33
|
const { getAccountName } = require('../../lib/sandboxes');
|
|
34
34
|
const { getValidEnv } = require('@hubspot/cli-lib/lib/environment');
|
|
35
35
|
|
|
@@ -168,19 +168,15 @@ exports.handler = async options => {
|
|
|
168
168
|
} catch (err) {
|
|
169
169
|
debugErrorAndContext(err);
|
|
170
170
|
|
|
171
|
-
if (err
|
|
171
|
+
if (isSpecifiedHubSpotAuthError(err, { statusCode: 401 })) {
|
|
172
172
|
// Intercept invalid key error
|
|
173
173
|
// This command uses the parent portal PAK to delete a sandbox, so we must specify which account needs a new key
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
account: getAccountName(parentAccount),
|
|
181
|
-
})
|
|
182
|
-
);
|
|
183
|
-
}
|
|
174
|
+
logger.log('');
|
|
175
|
+
logger.error(
|
|
176
|
+
i18n(`${i18nKey}.failure.invalidKey`, {
|
|
177
|
+
account: getAccountName(parentAccount),
|
|
178
|
+
})
|
|
179
|
+
);
|
|
184
180
|
} else if (
|
|
185
181
|
isSpecifiedError(err, {
|
|
186
182
|
statusCode: 403,
|
package/commands/sandbox.js
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
const { addConfigOptions, addAccountOptions } = require('../lib/commonOpts');
|
|
2
|
+
const { i18n } = require('../lib/lang');
|
|
2
3
|
const create = require('./sandbox/create');
|
|
3
4
|
const del = require('./sandbox/delete');
|
|
4
5
|
const sync = require('./sandbox/sync');
|
|
5
6
|
|
|
6
|
-
|
|
7
|
+
const i18nKey = 'cli.commands.sandbox';
|
|
7
8
|
|
|
8
9
|
exports.command = 'sandbox';
|
|
9
|
-
exports.describe =
|
|
10
|
+
exports.describe = i18n(`${i18nKey}.describe`);
|
|
10
11
|
|
|
11
12
|
exports.builder = yargs => {
|
|
12
13
|
addConfigOptions(yargs, true);
|
package/lang/en.lyaml
CHANGED
|
@@ -67,6 +67,18 @@ en:
|
|
|
67
67
|
nameBased: "Print information for the account in the config with name equal to \"MyAccount\""
|
|
68
68
|
name: "{{#bold}}Account name{{/bold}}: {{ name }}"
|
|
69
69
|
scopeGroups: "{{#bold}}Scopes available{{/bold}}:"
|
|
70
|
+
clean:
|
|
71
|
+
describe: "Checks for inactive accounts and removes them from the CLI config"
|
|
72
|
+
noResults: "No inactive accounts found to remove."
|
|
73
|
+
loading:
|
|
74
|
+
add: "Looking for inactive accounts…"
|
|
75
|
+
inactiveAccountsFound:
|
|
76
|
+
one: "1 inactive account found:"
|
|
77
|
+
other: "{{ count }} inactive accounts found:"
|
|
78
|
+
confirm:
|
|
79
|
+
one: "Remove 1 inactive account from the CLI config?"
|
|
80
|
+
other: "Remove {{ count }} inactive accounts from the CLI config?"
|
|
81
|
+
removeSuccess: "Removed {{ accountName }} from the CLI config."
|
|
70
82
|
auth:
|
|
71
83
|
describe: "Configure authentication for a HubSpot account. Supported authentication protocols are {{ supportedProtocols }}."
|
|
72
84
|
errors:
|
|
@@ -444,9 +456,10 @@ en:
|
|
|
444
456
|
describe: "Shortcut of the link you'd like to open"
|
|
445
457
|
selectLink: "Select a link to open"
|
|
446
458
|
project:
|
|
459
|
+
describe: "{{#bold}}[beta]{{/bold}} Commands for working with projects. For more information, visit our documentation: https://developers.hubspot.com/docs/platform/build-and-deploy-using-hubspot-projects"
|
|
447
460
|
subcommands:
|
|
448
461
|
dev:
|
|
449
|
-
describe: "Start local dev for the current project"
|
|
462
|
+
describe: "{{#bold}}[beta]{{/bold}} Start local dev for the current project"
|
|
450
463
|
logs:
|
|
451
464
|
betaMessage: "HubSpot projects local development"
|
|
452
465
|
nonSandboxWarning: "Testing in a sandbox is strongly recommended. To switch the target account, select an option below or run {{#bold}}`hs accounts use`{{/bold}} before running the command again."
|
|
@@ -454,24 +467,20 @@ en:
|
|
|
454
467
|
projectMustExistExplanation: "The project {{ projectName }} does not exist in the target account {{ accountIdentifier}}. This command requires the project to exist in the target account."
|
|
455
468
|
choseNotToCreateProject: "Exiting because this command requires the project to exist in the target account."
|
|
456
469
|
initialUploadMessage: "HubSpot Local Dev Server Startup"
|
|
470
|
+
declineDefaultSandboxExplanation: "To develop on a different account, run {{ useCommand }} to change your default account, then re-run {{ devCommand }}."
|
|
457
471
|
status:
|
|
458
472
|
creatingProject: "Creating project {{ projectName }} in {{ accountIdentifier }}"
|
|
459
473
|
createdProject: "Created project {{ projectName }} in {{ accountIdentifier }}"
|
|
460
474
|
failedToCreateProject: "Failed to create project in the target account."
|
|
461
|
-
startupMessage: "Starting local dev server for {{#bold}}{{ projectName }}{{/bold}} ..."
|
|
462
475
|
prompt:
|
|
463
476
|
createProject: "Create new project {{ projectName}} in {{#bold}}[{{ accountIdentifier }}]{{/bold}}?"
|
|
464
|
-
targetNonSandbox: "Continue testing in a non-sandbox account?"
|
|
465
|
-
options:
|
|
466
|
-
extension:
|
|
467
|
-
describe: "The extension that you would like to run locally"
|
|
468
477
|
errors:
|
|
469
478
|
noProjectConfig: "No project detected. Please run this command again from a project directory."
|
|
470
|
-
projectLockedError: "Your project is locked. This may mean that another user is running the {{#bold}}`hs project
|
|
479
|
+
projectLockedError: "Your project is locked. This may mean that another user is running the {{#bold}}`hs project watch`{{/bold}} command for this project. If this is you, unlock the project in Projects UI."
|
|
471
480
|
examples:
|
|
472
481
|
default: "Start local dev for the current project"
|
|
473
482
|
create:
|
|
474
|
-
describe: "Create a new project"
|
|
483
|
+
describe: "{{#bold}}[beta]{{/bold}} Create a new project"
|
|
475
484
|
logs:
|
|
476
485
|
welcomeMessage: "Welcome to HubSpot Developer Projects!"
|
|
477
486
|
examples:
|
|
@@ -486,7 +495,7 @@ en:
|
|
|
486
495
|
templateSource:
|
|
487
496
|
describe: "Path to custom GitHub repository from which to create project template"
|
|
488
497
|
add:
|
|
489
|
-
describe: "Create a new component within a project"
|
|
498
|
+
describe: "{{#bold}}[beta]{{/bold}} Create a new component within a project"
|
|
490
499
|
options:
|
|
491
500
|
name:
|
|
492
501
|
describe: "Component name"
|
|
@@ -501,7 +510,7 @@ en:
|
|
|
501
510
|
examples:
|
|
502
511
|
default: "Create a component within your project"
|
|
503
512
|
deploy:
|
|
504
|
-
describe: "Deploy a project build"
|
|
513
|
+
describe: "{{#bold}}[beta]{{/bold}} Deploy a project build"
|
|
505
514
|
debug:
|
|
506
515
|
deploying: "Deploying project at path: {{ path }}"
|
|
507
516
|
errors:
|
|
@@ -516,8 +525,10 @@ en:
|
|
|
516
525
|
describe: "Project build ID to be deployed"
|
|
517
526
|
project:
|
|
518
527
|
describe: "Project name"
|
|
528
|
+
listBuilds:
|
|
529
|
+
describe: "{{#bold}}[beta]{{/bold}} List the project's builds"
|
|
519
530
|
logs:
|
|
520
|
-
describe: "Get execution logs for a serverless function within a project"
|
|
531
|
+
describe: "{{#bold}}[beta]{{/bold}} Get execution logs for a serverless function within a project"
|
|
521
532
|
errors:
|
|
522
533
|
invalidAppName: "Could not find app with name \"{{ appName }}\" in project \"{{ projectName }}\""
|
|
523
534
|
logs:
|
|
@@ -552,7 +563,7 @@ en:
|
|
|
552
563
|
endpoint:
|
|
553
564
|
describe: "Public endpoint path"
|
|
554
565
|
upload:
|
|
555
|
-
describe: "Upload your project files and create a new build"
|
|
566
|
+
describe: "{{#bold}}[beta]{{/bold}} Upload your project files and create a new build"
|
|
556
567
|
examples:
|
|
557
568
|
default: "Upload a project"
|
|
558
569
|
logs:
|
|
@@ -570,7 +581,7 @@ en:
|
|
|
570
581
|
path:
|
|
571
582
|
describe: "Path to a project folder"
|
|
572
583
|
watch:
|
|
573
|
-
describe: "Watch your local project for changes and automatically upload changed files to a new build in HubSpot"
|
|
584
|
+
describe: "{{#bold}}[beta]{{/bold}} Watch your local project for changes and automatically upload changed files to a new build in HubSpot"
|
|
574
585
|
examples:
|
|
575
586
|
default: "Watch a project within the myProjectFolder folder"
|
|
576
587
|
logs:
|
|
@@ -582,7 +593,7 @@ en:
|
|
|
582
593
|
initialUpload:
|
|
583
594
|
describe: "Upload directory before watching for updates"
|
|
584
595
|
download:
|
|
585
|
-
describe: "Download your project files from HubSpot and write to a path on your computer"
|
|
596
|
+
describe: "{{#bold}}[beta]{{/bold}} Download your project files from HubSpot and write to a path on your computer"
|
|
586
597
|
examples:
|
|
587
598
|
default: "Download the project myProject into myProjectFolder folder"
|
|
588
599
|
logs:
|
|
@@ -591,6 +602,8 @@ en:
|
|
|
591
602
|
errors:
|
|
592
603
|
downloadFailed: "Something went wrong downloading the project"
|
|
593
604
|
projectNotFound: "Your project {{ projectName }} could not be found in {{ accountId }}"
|
|
605
|
+
warnings:
|
|
606
|
+
cannotDownloadWithinProject: "Cancelling project download. Please run the command again outside the context of an existing project."
|
|
594
607
|
options:
|
|
595
608
|
buildNumber:
|
|
596
609
|
describe: "The build number to download"
|
|
@@ -599,7 +612,7 @@ en:
|
|
|
599
612
|
dest:
|
|
600
613
|
describe: "Destination folder for the project"
|
|
601
614
|
open:
|
|
602
|
-
describe: "Open
|
|
615
|
+
describe: "{{#bold}}[beta]{{/bold}} Open the specified project's details page in the browser"
|
|
603
616
|
options:
|
|
604
617
|
project:
|
|
605
618
|
describe: "Name of project to open"
|
|
@@ -848,58 +861,35 @@ en:
|
|
|
848
861
|
lib:
|
|
849
862
|
DevServerManager:
|
|
850
863
|
portConflict: "The port {{ port }} is already in use."
|
|
851
|
-
|
|
864
|
+
notInitialized: "The Dev Server Manager must be initialized before it is started."
|
|
865
|
+
noCompatibleComponents: "Skipping call to {{ serverKey }} because there are no compatible components in the project."
|
|
866
|
+
LocalDevManager:
|
|
852
867
|
failedToInitialize: "Missing required arguments to initialize Local Dev"
|
|
868
|
+
noComponents: "There are no components in this project."
|
|
869
|
+
noDeployedBuild: "There is no deployed build for this project in {{ accountIdentifier }}."
|
|
870
|
+
noRunnableComponents: "There are no components in this project that support local development."
|
|
853
871
|
betaMessage: "HubSpot projects local development"
|
|
854
872
|
running: "Running {{#bold}}{{ projectName }}{{/bold}} locally on {{ accountIdentifier }}, waiting for changes ..."
|
|
855
873
|
quitHelper: "Press {{#bold}}'q'{{/bold}} to stop the local dev server"
|
|
856
|
-
viewInHubSpotLink: "View in HubSpot"
|
|
874
|
+
viewInHubSpotLink: "View project in HubSpot"
|
|
857
875
|
exitingStart: "Stopping local dev server ..."
|
|
858
876
|
exitingSucceed: "Successfully exited"
|
|
859
877
|
exitingFail: "Failed to cleanup before exiting"
|
|
878
|
+
uploadWarning:
|
|
879
|
+
appLabel: "[App]"
|
|
880
|
+
uiExtensionLabel: "[UI Extension]"
|
|
881
|
+
configEdit: "You edited the configuration file {{#bold}}{{ path }}{{/bold}}. Changes to configuration files cannot be handled by the local dev server."
|
|
882
|
+
missingComponents: "The deployed build for this project does not contain {{#bold}}'{{ missingComponents }}'{{/bold}}. This may cause issues in local development."
|
|
883
|
+
header: "{{ reason }} To reflect these changes:"
|
|
884
|
+
stopDev: " * Stop {{ command }}"
|
|
885
|
+
runUpload: " * Run {{ command }}"
|
|
886
|
+
runUploadWithAccount: " * Run {{ command }}"
|
|
887
|
+
restartDev: " * Re-run {{ command }}"
|
|
860
888
|
devServer:
|
|
861
889
|
cleanupError: "Failed to cleanup local dev server: {{ message }}"
|
|
890
|
+
setupError: "Failed to setup local dev server: {{ message }}"
|
|
862
891
|
startError: "Failed to start local dev server: {{ message }}"
|
|
863
|
-
|
|
864
|
-
failedToInitialize: "Missing required arguments to initialize Local Dev Manager"
|
|
865
|
-
exitingStart: "Stopping local dev server ..."
|
|
866
|
-
exitingSucceed: "Successfully exited"
|
|
867
|
-
exitingFail: "Failed to clean up before exiting"
|
|
868
|
-
previousStagingBuildCancelled: "Failed to create a staging build because the project was already locked. It is now unlocked. Run the command again."
|
|
869
|
-
cancelledFromUI: "The dev process has been cancelled from the UI. Any changes made since cancelling have not been uploaded. To resume dev mode, rerun {{#yellow}}`hs project dev`{{/yellow}}."
|
|
870
|
-
header:
|
|
871
|
-
betaMessage: "{{#yellow}}{{#bold}}[beta]{{/bold}}{{/yellow}} HubSpot projects local development"
|
|
872
|
-
running: "Running {{#bold}}{{ projectName }}{{/bold}} locally on {{ accountIdentifier }}, waiting for changes ..."
|
|
873
|
-
quitHelper: "Press {{#bold}}'q'{{/bold}} to stop the local dev server"
|
|
874
|
-
viewInHubSpotLink: "View in HubSpot"
|
|
875
|
-
status:
|
|
876
|
-
clean: "{{#bold}}Status:{{/bold}} {{#green}}Everything up to date{{/green}}"
|
|
877
|
-
buildError: "{{#bold}}Status:{{/bold}} {{#red}}Latest build failed{{/red}}"
|
|
878
|
-
deployError: "{{#bold}}Status:{{/bold}} {{#red}}Latest deploy failed{{/red}}"
|
|
879
|
-
uploadPending: "{{#bold}}Status:{{/bold}} {{#yellow}}Upload is pending{{/yellow}}"
|
|
880
|
-
noUploadsAllowed: "{{#bold}}Status:{{/bold}} {{#red}}Change requires upload, but uploads are not allowed{{/red}}"
|
|
881
|
-
manualUploadRequired: "{{#bold}}Status:{{/bold}} {{#yellow}}Change requires manual upload{{/yellow}}"
|
|
882
|
-
manualUpload: "{{#bold}}Status:{{/bold}} {{#green}}Manually uploading pending changes{{/green}}"
|
|
883
|
-
upload:
|
|
884
|
-
noUploadsAllowed: "The change to {{ filePath }} requires an upload, but the CLI cannot upload to a project that is using a github integration."
|
|
885
|
-
manualUploadSkipped: "Manually upload and deploy project to production account: {{#green}}(n){{/green}}"
|
|
886
|
-
manualUploadConfirmed: "Manually upload and deploy project to production account: {{#green}}(Y){{/green}}"
|
|
887
|
-
manualUploadRequired: "Project file changes require a manual upload and deploy ..."
|
|
888
|
-
manualUploadExplanation1: "{{#yellow}}> Dev server is running on a {{#bold}}non-sandbox account{{/bold}}.{{/yellow}}"
|
|
889
|
-
manualUploadExplanation2: "{{#yellow}}> Uploading changes may overwrite production data.{{/yellow}}"
|
|
890
|
-
manualUploadPrompt: "? Manually upload and deploy project? {{#green}}Y/n{{/green}}"
|
|
891
|
-
extensionNotAllowed: "Extension not allowed for {{ filePath }}"
|
|
892
|
-
fileIgnored: "File ignored: {{ filePath }}"
|
|
893
|
-
uploadingAddChange: "[INFO] Uploading {{ filePath }}"
|
|
894
|
-
uploadedAddChange: "[INFO] Uploaded {{ filePath }}"
|
|
895
|
-
uploadingRemoveChange: "[INFO] Removing {{ filePath }}"
|
|
896
|
-
uploadedRemoveChange: "[INFO] Removed {{ filePath }}"
|
|
897
|
-
uploadingChanges: "{{#bold}}Building #{{ buildId }} and deploying recent changes on {{ accountIdentifier }}{{/bold}}"
|
|
898
|
-
uploadedChangesSucceeded: "{{#bold}}Built #{{ buildId }} and deployed recent changes on {{ accountIdentifier }}{{/bold}}"
|
|
899
|
-
uploadedChangesFailed: "{{#bold}}Failed to build #{{ buildId }} and deploy recent changes on {{ accountIdentifier }}{{/bold}}"
|
|
900
|
-
devServer:
|
|
901
|
-
startError: "{{#red}}[ERROR]{{/red}} Failed to start local dev server"
|
|
902
|
-
cleanupError: "{{#red}}[ERROR]{{/red}} Failed to cleanup local dev server"
|
|
892
|
+
fileChangeError: "Failed to notify local dev server of file change: {{ message }}"
|
|
903
893
|
projects:
|
|
904
894
|
uploadProjectFiles:
|
|
905
895
|
add: "Uploading {{#bold}}{{ projectName }}{{/bold}} project files to {{ accountIdentifier }}"
|
|
@@ -914,6 +904,8 @@ en:
|
|
|
914
904
|
createPrompt: "The project {{ projectName }} does not exist in {{ accountIdentifier }}. Would you like to create it?"
|
|
915
905
|
createSuccess: "New project {{#bold}}{{ projectName }}{{/bold}} successfully created in {{#bold}}{{ accountIdentifier }}{{/bold}}."
|
|
916
906
|
notFound: "Your project {{#bold}}{{ projectName }}{{/bold}} could not be found in {{#bold}}{{ accountIdentifier }}{{/bold}}."
|
|
907
|
+
pollFetchProject:
|
|
908
|
+
checkingProject: "Checking if project exists in {{ accountIdentifier }}"
|
|
917
909
|
makePollTaskStatusFunc:
|
|
918
910
|
componentCountSingular: "Found 1 component in this project"
|
|
919
911
|
componentCount: "Found {{ numComponents }} components in this project"
|
|
@@ -925,8 +917,11 @@ en:
|
|
|
925
917
|
logFeedbackMessage:
|
|
926
918
|
feedbackHeader: "We'd love to hear your feedback!"
|
|
927
919
|
feedbackMessage: "How are you liking the new projects and developer tools? \n > Run `{{#yellow}}hs feedback{{/yellow}}` to let us know what you think!\n"
|
|
920
|
+
showPlatformVersionWarning:
|
|
921
|
+
noPlatformVersion: "No platformVersion found in hsproject.json. Falling back to version \"{{ defaultVersion }}\"."
|
|
922
|
+
noPlatformVersionAlt: "No platformVersion found in hsproject.json. Falling back to default version."
|
|
928
923
|
ui:
|
|
929
|
-
betaTag: "{{#bold}}[
|
|
924
|
+
betaTag: "{{#bold}}[BETA]{{/bold}}"
|
|
930
925
|
betaWarning:
|
|
931
926
|
header: "{{#yellow}}***************************** WARNING ****************************{{/yellow}}"
|
|
932
927
|
footer: "{{#yellow}}******************************************************************{{/yellow}}"
|
|
@@ -992,9 +987,10 @@ en:
|
|
|
992
987
|
prompts:
|
|
993
988
|
projectDevTargetAccountPrompt:
|
|
994
989
|
createNewSandboxOption: "<Test on a new development sandbox>"
|
|
995
|
-
chooseDefaultAccountOption: "<{{#bold}}
|
|
990
|
+
chooseDefaultAccountOption: "<{{#bold}}\U00002757{{/bold}} Test on this production account {{#bold}}\U00002757{{/bold}}>"
|
|
996
991
|
promptMessage: "[--account] Choose a sandbox under {{ accountIdentifier }} to test with:"
|
|
997
992
|
sandboxLimit: "You’ve reached the limit of {{ limit }} development sandboxes"
|
|
993
|
+
confirmDefaultSandboxAccount: "Continue testing on {{#bold}}{{ accountName }} ({{ accountType }}){{/bold}}? (Y/n)"
|
|
998
994
|
projectLogsPrompt:
|
|
999
995
|
projectName:
|
|
1000
996
|
message: "[--project] Enter the project name:"
|
package/lib/DevServerManager.js
CHANGED
|
@@ -1,31 +1,30 @@
|
|
|
1
|
-
const
|
|
2
|
-
const bodyParser = require('body-parser');
|
|
3
|
-
const cors = require('cors');
|
|
4
|
-
const { walk } = require('@hubspot/cli-lib/lib/walk');
|
|
5
|
-
const { getProjectDetailUrl } = require('./projects');
|
|
6
|
-
const { i18n } = require('./lang');
|
|
7
|
-
const { EXIT_CODES } = require('./enums/exitCodes');
|
|
1
|
+
const httpClient = require('@hubspot/cli-lib/http');
|
|
8
2
|
const { logger } = require('@hubspot/cli-lib/logger');
|
|
3
|
+
const { COMPONENT_TYPES } = require('./projectStructure');
|
|
4
|
+
const { i18n } = require('./lang');
|
|
5
|
+
const { promptUser } = require('./prompts/promptUtils');
|
|
6
|
+
const { DevModeInterface } = require('@hubspot/ui-extensions-dev-server');
|
|
9
7
|
|
|
10
8
|
const i18nKey = 'cli.lib.DevServerManager';
|
|
11
9
|
|
|
12
|
-
const
|
|
10
|
+
const SERVER_KEYS = {
|
|
11
|
+
app: 'app',
|
|
12
|
+
};
|
|
13
13
|
|
|
14
14
|
class DevServerManager {
|
|
15
15
|
constructor() {
|
|
16
16
|
this.initialized = false;
|
|
17
|
+
this.started = false;
|
|
18
|
+
this.componentsByType = {};
|
|
17
19
|
this.server = null;
|
|
18
20
|
this.path = null;
|
|
19
|
-
this.devServers = {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
} catch (e) {
|
|
27
|
-
logger.debug('Failed to load dev server interface: ', e);
|
|
28
|
-
}
|
|
21
|
+
this.devServers = {
|
|
22
|
+
[SERVER_KEYS.app]: {
|
|
23
|
+
componentType: COMPONENT_TYPES.app,
|
|
24
|
+
serverInterface: DevModeInterface,
|
|
25
|
+
},
|
|
26
|
+
};
|
|
27
|
+
this.debug = false;
|
|
29
28
|
}
|
|
30
29
|
|
|
31
30
|
async iterateDevServers(callback) {
|
|
@@ -33,84 +32,87 @@ class DevServerManager {
|
|
|
33
32
|
|
|
34
33
|
for (let i = 0; i < serverKeys.length; i++) {
|
|
35
34
|
const serverKey = serverKeys[i];
|
|
36
|
-
const
|
|
37
|
-
|
|
35
|
+
const devServer = this.devServers[serverKey];
|
|
36
|
+
|
|
37
|
+
const compatibleComponents =
|
|
38
|
+
this.componentsByType[devServer.componentType] || {};
|
|
39
|
+
|
|
40
|
+
if (Object.keys(compatibleComponents).length) {
|
|
41
|
+
await callback(devServer.serverInterface, compatibleComponents);
|
|
42
|
+
} else {
|
|
43
|
+
logger.debug(i18n(`${i18nKey}.noCompatibleComponents`, { serverKey }));
|
|
44
|
+
}
|
|
38
45
|
}
|
|
39
46
|
}
|
|
40
47
|
|
|
41
|
-
|
|
42
|
-
return
|
|
48
|
+
arrangeComponentsByType(components) {
|
|
49
|
+
return components.reduce((acc, component) => {
|
|
50
|
+
if (!acc[component.type]) {
|
|
51
|
+
acc[component.type] = {};
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
acc[component.type][component.config.name] = component;
|
|
55
|
+
|
|
56
|
+
return acc;
|
|
57
|
+
}, {});
|
|
43
58
|
}
|
|
44
59
|
|
|
45
|
-
async
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
// Configure
|
|
60
|
-
app.set('trust proxy', true);
|
|
61
|
-
|
|
62
|
-
// Initialize a base route
|
|
63
|
-
app.get('/', (req, res) => {
|
|
64
|
-
res.send('HubSpot local dev server');
|
|
65
|
-
});
|
|
66
|
-
|
|
67
|
-
// Initialize URL redirects
|
|
68
|
-
app.get('/hs/project', (req, res) => {
|
|
69
|
-
res.redirect(getProjectDetailUrl(projectConfig.name, accountId));
|
|
70
|
-
});
|
|
71
|
-
|
|
72
|
-
// Start server
|
|
73
|
-
this.server = await app.listen(DEFAULT_PORT).on('error', err => {
|
|
74
|
-
if (err.code === 'EADDRINUSE') {
|
|
75
|
-
logger.error(i18n(`${i18nKey}.portConflict`, { port: DEFAULT_PORT }));
|
|
76
|
-
logger.log();
|
|
77
|
-
process.exit(EXIT_CODES.ERROR);
|
|
78
|
-
}
|
|
79
|
-
});
|
|
80
|
-
|
|
81
|
-
const projectFiles = await walk(projectSourceDir);
|
|
82
|
-
|
|
83
|
-
// Initialize component servers
|
|
84
|
-
await this.iterateDevServers(async serverInterface => {
|
|
85
|
-
if (serverInterface.start) {
|
|
86
|
-
await serverInterface.start({
|
|
87
|
-
accountId,
|
|
88
|
-
debug,
|
|
89
|
-
extension,
|
|
90
|
-
projectConfig,
|
|
91
|
-
projectFiles,
|
|
92
|
-
});
|
|
60
|
+
async setup({ components, debug, onUploadRequired }) {
|
|
61
|
+
this.debug = debug;
|
|
62
|
+
this.componentsByType = this.arrangeComponentsByType(components);
|
|
63
|
+
|
|
64
|
+
await this.iterateDevServers(
|
|
65
|
+
async (serverInterface, compatibleComponents) => {
|
|
66
|
+
if (serverInterface.setup) {
|
|
67
|
+
await serverInterface.setup({
|
|
68
|
+
components: compatibleComponents,
|
|
69
|
+
debug,
|
|
70
|
+
onUploadRequired,
|
|
71
|
+
promptUser,
|
|
72
|
+
});
|
|
73
|
+
}
|
|
93
74
|
}
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
this.path = this.server.address()
|
|
97
|
-
? `http://localhost:${this.server.address().port}`
|
|
98
|
-
: null;
|
|
75
|
+
);
|
|
99
76
|
|
|
100
77
|
this.initialized = true;
|
|
101
78
|
}
|
|
102
79
|
|
|
103
|
-
async
|
|
80
|
+
async start({ accountId, projectConfig }) {
|
|
104
81
|
if (this.initialized) {
|
|
82
|
+
await this.iterateDevServers(async serverInterface => {
|
|
83
|
+
if (serverInterface.start) {
|
|
84
|
+
await serverInterface.start({
|
|
85
|
+
accountId,
|
|
86
|
+
debug: this.debug,
|
|
87
|
+
httpClient,
|
|
88
|
+
projectConfig,
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
} else {
|
|
93
|
+
throw new Error(i18n(`${i18nKey}.notInitialized`));
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
this.started = true;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
fileChange({ filePath, event }) {
|
|
100
|
+
if (this.started) {
|
|
101
|
+
this.iterateDevServers(async serverInterface => {
|
|
102
|
+
if (serverInterface.fileChange) {
|
|
103
|
+
await serverInterface.fileChange(filePath, event);
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
async cleanup() {
|
|
110
|
+
if (this.started) {
|
|
105
111
|
await this.iterateDevServers(async serverInterface => {
|
|
106
112
|
if (serverInterface.cleanup) {
|
|
107
113
|
await serverInterface.cleanup();
|
|
108
114
|
}
|
|
109
115
|
});
|
|
110
|
-
|
|
111
|
-
if (this.server) {
|
|
112
|
-
await this.server.close();
|
|
113
|
-
}
|
|
114
116
|
}
|
|
115
117
|
}
|
|
116
118
|
}
|