@hs-x/cli 0.4.2-next.1 → 0.4.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/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +4 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/command-catalog.d.ts +2 -2
- package/dist/command-catalog.d.ts.map +1 -1
- package/dist/command-catalog.js +1 -0
- package/dist/command-catalog.js.map +1 -1
- package/dist/commands/deploy.d.ts +7 -0
- package/dist/commands/deploy.d.ts.map +1 -1
- package/dist/commands/deploy.js +39 -5
- package/dist/commands/deploy.js.map +1 -1
- package/dist/commands/dev.d.ts.map +1 -1
- package/dist/commands/dev.js +96 -21
- package/dist/commands/dev.js.map +1 -1
- package/dist/commands/help-command.d.ts.map +1 -1
- package/dist/commands/help-command.js +164 -0
- package/dist/commands/help-command.js.map +1 -1
- package/dist/commands/react-health.js +6 -10
- package/dist/commands/react-health.js.map +1 -1
- package/dist/commands/react.js +2 -2
- package/dist/commands/sync.d.ts +129 -0
- package/dist/commands/sync.d.ts.map +1 -0
- package/dist/commands/sync.js +771 -0
- package/dist/commands/sync.js.map +1 -0
- package/dist/constants.d.ts +1 -1
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +1 -1
- package/dist/constants.js.map +1 -1
- package/dist/dev/compat-shim.d.ts +36 -0
- package/dist/dev/compat-shim.d.ts.map +1 -1
- package/dist/dev/compat-shim.js +36 -1
- package/dist/dev/compat-shim.js.map +1 -1
- package/dist/dev/component-selection.d.ts +18 -1
- package/dist/dev/component-selection.d.ts.map +1 -1
- package/dist/dev/component-selection.js +53 -5
- package/dist/dev/component-selection.js.map +1 -1
- package/dist/dev/hubspot-logs-poller.d.ts +6 -0
- package/dist/dev/hubspot-logs-poller.d.ts.map +1 -1
- package/dist/dev/hubspot-logs-poller.js +36 -10
- package/dist/dev/hubspot-logs-poller.js.map +1 -1
- package/dist/dev/hubspot-token-repair.d.ts +36 -0
- package/dist/dev/hubspot-token-repair.d.ts.map +1 -0
- package/dist/dev/hubspot-token-repair.js +88 -0
- package/dist/dev/hubspot-token-repair.js.map +1 -0
- package/dist/dev/session-manager.d.ts +19 -0
- package/dist/dev/session-manager.d.ts.map +1 -1
- package/dist/dev/session-manager.js +41 -8
- package/dist/dev/session-manager.js.map +1 -1
- package/dist/errors-registry.d.ts.map +1 -1
- package/dist/errors-registry.js +8 -0
- package/dist/errors-registry.js.map +1 -1
- package/dist/prompt.d.ts +2 -0
- package/dist/prompt.d.ts.map +1 -1
- package/dist/prompt.js +6 -0
- package/dist/prompt.js.map +1 -1
- package/package.json +8 -8
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dev.d.ts","sourceRoot":"","sources":["../../src/commands/dev.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,OAAO,MAAM,qBAAqB,CAAC;AAI/C,OAAO,EAAU,MAAM,EAAE,MAAM,QAAQ,CAAC;AACxC,OAAO,EAAE,KAAK,QAAQ,EAAY,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"dev.d.ts","sourceRoot":"","sources":["../../src/commands/dev.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,OAAO,MAAM,qBAAqB,CAAC;AAI/C,OAAO,EAAU,MAAM,EAAE,MAAM,QAAQ,CAAC;AACxC,OAAO,EAAE,KAAK,QAAQ,EAAY,MAAM,iBAAiB,CAAC;AA2C1D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,GAAG,EAAE,MAAM,oBAAoB,CAAC;AAuzBzC,wBAAsB,UAAU,CAAC,EAC/B,IAAI,EACJ,IAAI,EACJ,IAAI,EACJ,QAAQ,GACT,EAAE;IACD,QAAQ,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,QAAQ,CAAC,EAAE,QAAQ,CAAC;CAC9B,GAAG,OAAO,CAAC,SAAS,CAAC,CAuErB;AAmnFD,eAAO,MAAM,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAiJlB,CAAC"}
|
package/dist/commands/dev.js
CHANGED
|
@@ -16,7 +16,7 @@ import { formatConfigUrl, loadCliConfig } from '../config.js';
|
|
|
16
16
|
import { CLI_VERSION } from '../constants.js';
|
|
17
17
|
import { controlPlaneAuthHeaders } from '../control-plane-fetch.js';
|
|
18
18
|
import { selectHubSpotDirectDevAccounts } from '../dev/account-selection.js';
|
|
19
|
-
import { listHubSpotDevComponentCandidates, resolveHubSpotDevComponentSelectors, } from '../dev/component-selection.js';
|
|
19
|
+
import { listHubSpotDevComponentCandidates, resolveHubSpotDevComponentSelectors, resolveHubSpotDevSessionApp, } from '../dev/component-selection.js';
|
|
20
20
|
import { createManagedDevEventWriter, createManagedDevSession, markManagedDevSessionReady, markManagedDevSessionState, prepareManagedDevSessionRestart, publicManagedDevSession, readManagedDevEvents, readManagedDevSession, reconcileManagedDevSession, setManagedDevSessionPid, stopManagedDevSessionProcess, waitForManagedDevSessionOwner, } from '../dev/managed-session.js';
|
|
21
21
|
import { findListeningProcess, isHubSpotDevPortConflict, stopProcessCommand, terminateProcessGracefully, } from '../dev/port-process.js';
|
|
22
22
|
import { executeCliHttp } from '../effect-http.js';
|
|
@@ -44,6 +44,22 @@ function isRecord(value) {
|
|
|
44
44
|
function isErrnoException(value) {
|
|
45
45
|
return value instanceof Error && typeof value.code === 'string';
|
|
46
46
|
}
|
|
47
|
+
/**
|
|
48
|
+
* One heartbeat failure is noise (HubSpot hiccups; the next tick retries).
|
|
49
|
+
* Three in a row is ~90s of a session HubSpot no longer acknowledges, which is
|
|
50
|
+
* when cards stop loading — say so once, then again every ten ticks so a long
|
|
51
|
+
* outage keeps getting a line without flooding the stream.
|
|
52
|
+
*/
|
|
53
|
+
function describeHeartbeatFailure(failure, portalId) {
|
|
54
|
+
const streak = failure.consecutiveFailures;
|
|
55
|
+
if (streak < 3 || (streak > 3 && (streak - 3) % 10 !== 0))
|
|
56
|
+
return undefined;
|
|
57
|
+
const detail = failure.status !== undefined ? `HTTP ${failure.status}` : failure.message;
|
|
58
|
+
const hint = failure.status === 401 || failure.status === 403
|
|
59
|
+
? `HubSpot rejected the credential for testing account ${portalId} — run \`hs account auth\` for that account, then restart \`hs-x dev\`.`
|
|
60
|
+
: `HubSpot may have dropped session ${failure.sessionId}; restart \`hs-x dev\` if cards stop loading.`;
|
|
61
|
+
return `HubSpot dev-session heartbeat failed ${streak} times in a row (${detail}). ${hint}`;
|
|
62
|
+
}
|
|
47
63
|
function describeDevSessionFailure(cause) {
|
|
48
64
|
const error = isRecord(cause) ? cause : undefined;
|
|
49
65
|
const message = cause instanceof Error ? cause.message : String(cause);
|
|
@@ -385,17 +401,29 @@ async function hubSpotDirectDevCommand({ argv, root, json, }) {
|
|
|
385
401
|
});
|
|
386
402
|
const requestedComponents = resolveFlags(argv, '--component');
|
|
387
403
|
const resolvedComponents = resolveHubSpotDevComponentSelectors(uiExtensionNodes?.candidates ?? [], requestedComponents);
|
|
388
|
-
|
|
404
|
+
const requestedAppCheck = resolvedComponents.ok && requestedComponents.length > 0
|
|
405
|
+
? resolveHubSpotDevSessionApp(uiExtensionNodes?.candidates ?? [], resolvedComponents.uids)
|
|
406
|
+
: undefined;
|
|
407
|
+
const componentsProblem = !resolvedComponents.ok
|
|
408
|
+
? { code: 'HSX_E_DEV_SESSION_NO_NODES', message: resolvedComponents.message }
|
|
409
|
+
: requestedAppCheck && !requestedAppCheck.ok
|
|
410
|
+
? { code: 'HSX_E_DEV_SESSION_MULTI_APP', message: requestedAppCheck.message }
|
|
411
|
+
: undefined;
|
|
412
|
+
if (componentsProblem || !resolvedComponents.ok) {
|
|
413
|
+
const problem = componentsProblem ?? {
|
|
414
|
+
code: 'HSX_E_DEV_SESSION_NO_NODES',
|
|
415
|
+
message: 'No HubSpot dev components resolved.',
|
|
416
|
+
};
|
|
389
417
|
if (json) {
|
|
390
418
|
write(`${JSON.stringify({
|
|
391
419
|
schema_version: 1,
|
|
392
420
|
command: 'dev',
|
|
393
421
|
ok: false,
|
|
394
|
-
error: { code:
|
|
422
|
+
error: { code: problem.code, message: problem.message },
|
|
395
423
|
}, null, 2)}\n`);
|
|
396
424
|
}
|
|
397
425
|
else {
|
|
398
|
-
reporter.error(
|
|
426
|
+
reporter.error(problem.code, problem.message);
|
|
399
427
|
reporter.done(undefined, 1);
|
|
400
428
|
}
|
|
401
429
|
return { exitCode: 1 };
|
|
@@ -408,11 +436,16 @@ async function hubSpotDirectDevCommand({ argv, root, json, }) {
|
|
|
408
436
|
uiExtensionNodes.candidates.length > 1 &&
|
|
409
437
|
!json &&
|
|
410
438
|
isInteractive()) {
|
|
439
|
+
const pickerCandidates = uiExtensionNodes.candidates;
|
|
411
440
|
const picked = await promptMultiSelect({
|
|
412
441
|
message: `Which HubSpot components should run in dev mode? (testing account ${testingAccount.portalId})`,
|
|
413
442
|
initial: [],
|
|
414
443
|
minSelected: 1,
|
|
415
|
-
|
|
444
|
+
validate: (selection) => {
|
|
445
|
+
const check = resolveHubSpotDevSessionApp(pickerCandidates, selection);
|
|
446
|
+
return check.ok ? undefined : check.message;
|
|
447
|
+
},
|
|
448
|
+
options: pickerCandidates.map((candidate) => ({
|
|
416
449
|
value: candidate.uid,
|
|
417
450
|
label: candidate.label,
|
|
418
451
|
description: candidate.description,
|
|
@@ -462,6 +495,23 @@ async function hubSpotDirectDevCommand({ argv, root, json, }) {
|
|
|
462
495
|
projectDir: root,
|
|
463
496
|
...(selectedNodeUids ? { selectedNodeUids } : {}),
|
|
464
497
|
...(profile ? { profile } : {}),
|
|
498
|
+
onHeartbeatError: (failure) => {
|
|
499
|
+
const warning = describeHeartbeatFailure(failure, testingAccount.portalId);
|
|
500
|
+
if (!warning)
|
|
501
|
+
return;
|
|
502
|
+
if (directDevLogStream) {
|
|
503
|
+
directDevLogStream.bus.emit({
|
|
504
|
+
lane: 'hubspot',
|
|
505
|
+
level: 'warn',
|
|
506
|
+
ts: failure.at.getTime(),
|
|
507
|
+
msg: warning,
|
|
508
|
+
source: 'dev-session',
|
|
509
|
+
});
|
|
510
|
+
}
|
|
511
|
+
else if (!json) {
|
|
512
|
+
reporter.warn('HSX_W_DEV_SESSION_HEARTBEAT', warning);
|
|
513
|
+
}
|
|
514
|
+
},
|
|
465
515
|
...(directDevLogStream
|
|
466
516
|
? {
|
|
467
517
|
onFrontendLog: (entry) => {
|
|
@@ -615,6 +665,13 @@ async function hubSpotDirectDevCommand({ argv, root, json, }) {
|
|
|
615
665
|
try {
|
|
616
666
|
await session.cleanup();
|
|
617
667
|
}
|
|
668
|
+
catch (error) {
|
|
669
|
+
// Shutdown is best-effort: a HubSpot-side failure (an expired token
|
|
670
|
+
// on the session delete, say) is worth one line, not a crash trace.
|
|
671
|
+
if (!json) {
|
|
672
|
+
reporter.warn('HSX_W_DEV_SESSION_CLEANUP', `HubSpot dev session was not cleaned up: ${describeDevSessionFailure(error)} HubSpot expires idle sessions on its own.`);
|
|
673
|
+
}
|
|
674
|
+
}
|
|
618
675
|
finally {
|
|
619
676
|
try {
|
|
620
677
|
await directDevLogStream?.cleanup();
|
|
@@ -753,17 +810,24 @@ async function devCommandCore({ argv, root, json, }) {
|
|
|
753
810
|
}
|
|
754
811
|
const workers = await discoverWorkerManifests(root);
|
|
755
812
|
await generateProjectArtifacts({ root, workers });
|
|
756
|
-
|
|
813
|
+
const noHubSpot = argv.includes('--no-hubspot');
|
|
814
|
+
// `--no-hubspot` is an explicit local-only posture. It must win over both
|
|
815
|
+
// an accidental --portal flag and any account discovered from local CLI
|
|
816
|
+
// state, otherwise dev tries to register a provider override before the
|
|
817
|
+
// existing HubSpot dev-session guard gets a chance to skip that work.
|
|
818
|
+
let portalId = noHubSpot ? undefined : resolveFlag(argv, '--portal');
|
|
757
819
|
const targetOrigin = resolveFlag(argv, '--target-origin');
|
|
758
820
|
const telemetryOrigin = resolveFlag(argv, '--telemetry-origin');
|
|
759
821
|
const forceDevOverride = argv.includes('--force');
|
|
760
|
-
const resolvedDevAcct =
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
822
|
+
const resolvedDevAcct = noHubSpot
|
|
823
|
+
? undefined
|
|
824
|
+
: await resolveAccountIdOrPrompt({
|
|
825
|
+
argv,
|
|
826
|
+
json,
|
|
827
|
+
purpose: 'this dev session',
|
|
828
|
+
root,
|
|
829
|
+
});
|
|
830
|
+
const accountId = resolvedDevAcct?.accountId;
|
|
767
831
|
const devCliConfig = loadCliConfig(argv);
|
|
768
832
|
// Portal id: HubSpot account ids in our store look like `portal-46993937`;
|
|
769
833
|
// strip the prefix when the user didn't pass --portal explicitly.
|
|
@@ -806,16 +870,18 @@ async function devCommandCore({ argv, root, json, }) {
|
|
|
806
870
|
reporter.done(undefined, 10);
|
|
807
871
|
return { exitCode: 10 };
|
|
808
872
|
}
|
|
809
|
-
if (!portalId) {
|
|
873
|
+
if (!noHubSpot && !portalId) {
|
|
810
874
|
portalId = await resolveDefaultPortalId({ root, accountId });
|
|
811
875
|
}
|
|
812
876
|
// Probe the HubSpot project IR up front so the picker can show UI-extension
|
|
813
877
|
// nodes alongside HS-X capabilities. No-op if hsproject.json isn't present.
|
|
814
|
-
const uiExtensionNodes =
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
878
|
+
const uiExtensionNodes = noHubSpot
|
|
879
|
+
? undefined
|
|
880
|
+
: await probeHubSpotUiNodes({
|
|
881
|
+
root,
|
|
882
|
+
portalIdFlag: portalId,
|
|
883
|
+
accountId,
|
|
884
|
+
});
|
|
819
885
|
let capabilityIds = selectedCapabilities.length > 0 ? selectedCapabilities : allCapabilityIds;
|
|
820
886
|
let selectedUiNodeUids = uiExtensionNodes && uiExtensionNodes.uids.length > 0 ? uiExtensionNodes.uids : undefined;
|
|
821
887
|
// Unified picker: ask once over HS-X capabilities + HubSpot UI nodes.
|
|
@@ -845,6 +911,10 @@ async function devCommandCore({ argv, root, json, }) {
|
|
|
845
911
|
message: `Which components should run in dev mode? (portal ${portalId})`,
|
|
846
912
|
initial,
|
|
847
913
|
minSelected: 1,
|
|
914
|
+
validate: (selection) => {
|
|
915
|
+
const check = resolveHubSpotDevSessionApp(uiExtensionNodes?.candidates ?? [], selection.filter((v) => v.startsWith(UI_PREFIX)).map((v) => v.slice(UI_PREFIX.length)));
|
|
916
|
+
return check.ok ? undefined : check.message;
|
|
917
|
+
},
|
|
848
918
|
options,
|
|
849
919
|
});
|
|
850
920
|
if (picked === undefined)
|
|
@@ -861,7 +931,7 @@ async function devCommandCore({ argv, root, json, }) {
|
|
|
861
931
|
// We register a dev override whenever the user has a HubSpot portal in
|
|
862
932
|
// play. `hs-x connect` gives us the portal id implicitly; only edge cases
|
|
863
933
|
// (no connected account, no --portal flag) skip registration.
|
|
864
|
-
const shouldRegisterOverride = Boolean(portalId);
|
|
934
|
+
const shouldRegisterOverride = !noHubSpot && Boolean(portalId);
|
|
865
935
|
if (shouldRegisterOverride) {
|
|
866
936
|
const portalIdForOverride = portalId;
|
|
867
937
|
if (!portalIdForOverride) {
|
|
@@ -1317,7 +1387,7 @@ async function devCommandCore({ argv, root, json, }) {
|
|
|
1317
1387
|
? [{ status: 'ok', key: 'telemetry', value: telemetryOrigin }]
|
|
1318
1388
|
: []),
|
|
1319
1389
|
]);
|
|
1320
|
-
if (!portalId) {
|
|
1390
|
+
if (!noHubSpot && !portalId) {
|
|
1321
1391
|
reporter.info('No HubSpot portal found — running local-only. Pass `--portal <id>` (or set a default with `hs auth` / `hs-x login`) to mirror a live portal.');
|
|
1322
1392
|
}
|
|
1323
1393
|
// The pinned status line carries the key map (incl. quit); repeating it in
|
|
@@ -2145,6 +2215,11 @@ async function maybeStartHubSpotDevSession(input) {
|
|
|
2145
2215
|
projectDir: input.root,
|
|
2146
2216
|
selectedNodeUids: input.selectedNodeUids,
|
|
2147
2217
|
...(profile ? { profile } : {}),
|
|
2218
|
+
onHeartbeatError: (failure) => {
|
|
2219
|
+
const warning = describeHeartbeatFailure(failure, portalId);
|
|
2220
|
+
if (warning && !input.json)
|
|
2221
|
+
input.reporter.warn('HSX_W_DEV_SESSION_HEARTBEAT', warning);
|
|
2222
|
+
},
|
|
2148
2223
|
});
|
|
2149
2224
|
input.reporter
|
|
2150
2225
|
.step('HubSpot UI-extension session')
|