@hs-x/cli 0.4.2-next.1 → 0.4.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 (56) hide show
  1. package/dist/cli/index.d.ts.map +1 -1
  2. package/dist/cli/index.js +4 -0
  3. package/dist/cli/index.js.map +1 -1
  4. package/dist/command-catalog.d.ts +2 -2
  5. package/dist/command-catalog.d.ts.map +1 -1
  6. package/dist/command-catalog.js +1 -0
  7. package/dist/command-catalog.js.map +1 -1
  8. package/dist/commands/deploy.d.ts +7 -0
  9. package/dist/commands/deploy.d.ts.map +1 -1
  10. package/dist/commands/deploy.js +26 -4
  11. package/dist/commands/deploy.js.map +1 -1
  12. package/dist/commands/dev.d.ts.map +1 -1
  13. package/dist/commands/dev.js +71 -5
  14. package/dist/commands/dev.js.map +1 -1
  15. package/dist/commands/help-command.d.ts.map +1 -1
  16. package/dist/commands/help-command.js +164 -0
  17. package/dist/commands/help-command.js.map +1 -1
  18. package/dist/commands/react-health.js +6 -10
  19. package/dist/commands/react-health.js.map +1 -1
  20. package/dist/commands/react.js +2 -2
  21. package/dist/commands/sync.d.ts +129 -0
  22. package/dist/commands/sync.d.ts.map +1 -0
  23. package/dist/commands/sync.js +771 -0
  24. package/dist/commands/sync.js.map +1 -0
  25. package/dist/constants.d.ts +1 -1
  26. package/dist/constants.d.ts.map +1 -1
  27. package/dist/constants.js +1 -1
  28. package/dist/constants.js.map +1 -1
  29. package/dist/dev/compat-shim.d.ts +36 -0
  30. package/dist/dev/compat-shim.d.ts.map +1 -1
  31. package/dist/dev/compat-shim.js +36 -1
  32. package/dist/dev/compat-shim.js.map +1 -1
  33. package/dist/dev/component-selection.d.ts +18 -1
  34. package/dist/dev/component-selection.d.ts.map +1 -1
  35. package/dist/dev/component-selection.js +53 -5
  36. package/dist/dev/component-selection.js.map +1 -1
  37. package/dist/dev/hubspot-logs-poller.d.ts +6 -0
  38. package/dist/dev/hubspot-logs-poller.d.ts.map +1 -1
  39. package/dist/dev/hubspot-logs-poller.js +36 -10
  40. package/dist/dev/hubspot-logs-poller.js.map +1 -1
  41. package/dist/dev/hubspot-token-repair.d.ts +36 -0
  42. package/dist/dev/hubspot-token-repair.d.ts.map +1 -0
  43. package/dist/dev/hubspot-token-repair.js +88 -0
  44. package/dist/dev/hubspot-token-repair.js.map +1 -0
  45. package/dist/dev/session-manager.d.ts +19 -0
  46. package/dist/dev/session-manager.d.ts.map +1 -1
  47. package/dist/dev/session-manager.js +41 -8
  48. package/dist/dev/session-manager.js.map +1 -1
  49. package/dist/errors-registry.d.ts.map +1 -1
  50. package/dist/errors-registry.js +8 -0
  51. package/dist/errors-registry.js.map +1 -1
  52. package/dist/prompt.d.ts +2 -0
  53. package/dist/prompt.d.ts.map +1 -1
  54. package/dist/prompt.js +6 -0
  55. package/dist/prompt.js.map +1 -1
  56. 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;AA0C1D,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;AAyvBzC,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;AA+lFD,eAAO,MAAM,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAiJlB,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;AA0mFD,eAAO,MAAM,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAiJlB,CAAC"}
@@ -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
- if (!resolvedComponents.ok) {
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: 'HSX_E_DEV_SESSION_NO_NODES', message: resolvedComponents.message },
422
+ error: { code: problem.code, message: problem.message },
395
423
  }, null, 2)}\n`);
396
424
  }
397
425
  else {
398
- reporter.error('HSX_E_DEV_SESSION_NO_NODES', resolvedComponents.message);
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
- options: uiExtensionNodes.candidates.map((candidate) => ({
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();
@@ -845,6 +902,10 @@ async function devCommandCore({ argv, root, json, }) {
845
902
  message: `Which components should run in dev mode? (portal ${portalId})`,
846
903
  initial,
847
904
  minSelected: 1,
905
+ validate: (selection) => {
906
+ const check = resolveHubSpotDevSessionApp(uiExtensionNodes?.candidates ?? [], selection.filter((v) => v.startsWith(UI_PREFIX)).map((v) => v.slice(UI_PREFIX.length)));
907
+ return check.ok ? undefined : check.message;
908
+ },
848
909
  options,
849
910
  });
850
911
  if (picked === undefined)
@@ -2145,6 +2206,11 @@ async function maybeStartHubSpotDevSession(input) {
2145
2206
  projectDir: input.root,
2146
2207
  selectedNodeUids: input.selectedNodeUids,
2147
2208
  ...(profile ? { profile } : {}),
2209
+ onHeartbeatError: (failure) => {
2210
+ const warning = describeHeartbeatFailure(failure, portalId);
2211
+ if (warning && !input.json)
2212
+ input.reporter.warn('HSX_W_DEV_SESSION_HEARTBEAT', warning);
2213
+ },
2148
2214
  });
2149
2215
  input.reporter
2150
2216
  .step('HubSpot UI-extension session')