inup 1.5.5 → 1.6.0

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 (75) hide show
  1. package/README.md +53 -10
  2. package/dist/cli.js +53 -31
  3. package/dist/config/constants.js +4 -6
  4. package/dist/config/package-meta.js +10 -0
  5. package/dist/config/project-config.js +11 -1
  6. package/dist/core/package-detector.js +37 -5
  7. package/dist/core/upgrade-runner.js +8 -10
  8. package/dist/core/upgrader.js +15 -11
  9. package/dist/features/changelog/clients/github-client.js +5 -6
  10. package/dist/features/changelog/services/changelog-service.js +2 -4
  11. package/dist/features/changelog/services/package-metadata-service.js +7 -23
  12. package/dist/features/changelog/services/release-notes-service.js +4 -29
  13. package/dist/features/debug/services/performance-tracker.js +6 -8
  14. package/dist/features/headless/headless-runner.js +53 -0
  15. package/dist/features/headless/index.js +27 -0
  16. package/dist/features/headless/report.js +64 -0
  17. package/dist/features/headless/types.js +6 -0
  18. package/dist/features/headless/vulnerability-audit.js +106 -0
  19. package/dist/index.js +1 -2
  20. package/dist/interactive-ui.js +15 -606
  21. package/dist/services/background-audit.js +3 -5
  22. package/dist/services/cache-manager.js +5 -7
  23. package/dist/services/http/inflight.js +22 -0
  24. package/dist/services/http/retry.js +30 -0
  25. package/dist/services/index.js +0 -1
  26. package/dist/services/npm-registry.js +20 -97
  27. package/dist/services/package-manager-detector.js +6 -3
  28. package/dist/services/persistent-cache.js +8 -13
  29. package/dist/types/domain.js +3 -0
  30. package/dist/types/streaming.js +3 -0
  31. package/dist/types/ui.js +3 -0
  32. package/dist/types.js +17 -0
  33. package/dist/ui/controllers/package-info-modal-controller.js +22 -31
  34. package/dist/ui/controllers/vulnerability-audit-controller.js +17 -8
  35. package/dist/ui/index.js +3 -0
  36. package/dist/ui/input-handler.js +58 -75
  37. package/dist/ui/keymap.js +208 -0
  38. package/dist/ui/modal/package-info-sections/release-notes.js +161 -0
  39. package/dist/ui/modal/package-info-sections/sections.js +174 -0
  40. package/dist/ui/modal/package-info-sections/text.js +75 -0
  41. package/dist/ui/modal/package-info-sections.js +15 -369
  42. package/dist/ui/modal/package-info.js +1 -1
  43. package/dist/ui/presenters/health.js +24 -0
  44. package/dist/ui/renderer/help-modal.js +75 -0
  45. package/dist/ui/renderer/index.js +2 -5
  46. package/dist/ui/renderer/package-list/interface.js +184 -0
  47. package/dist/ui/renderer/package-list/rows.js +177 -0
  48. package/dist/ui/renderer/package-list.js +15 -455
  49. package/dist/ui/session/action-dispatcher.js +233 -0
  50. package/dist/ui/session/index.js +13 -0
  51. package/dist/ui/session/interactive-session.js +280 -0
  52. package/dist/ui/session/selection-state-builder.js +149 -0
  53. package/dist/ui/state/filter-manager.js +17 -6
  54. package/dist/ui/state/modal-manager.js +35 -0
  55. package/dist/ui/state/navigation-manager.js +33 -4
  56. package/dist/ui/state/state-manager.js +68 -3
  57. package/dist/ui/state/theme-manager.js +1 -0
  58. package/dist/ui/themes-colors.js +16 -4
  59. package/dist/ui/themes.js +11 -19
  60. package/dist/ui/utils/cursor.js +12 -7
  61. package/dist/ui/utils/index.js +6 -1
  62. package/dist/ui/utils/text.js +3 -2
  63. package/dist/ui/utils/version.js +60 -86
  64. package/dist/utils/color.js +38 -0
  65. package/dist/utils/config.js +13 -1
  66. package/dist/utils/engines.js +63 -0
  67. package/dist/utils/filesystem/io.js +103 -0
  68. package/dist/utils/filesystem/paths.js +19 -0
  69. package/dist/utils/filesystem/scan.js +280 -0
  70. package/dist/utils/filesystem.js +17 -335
  71. package/dist/utils/index.js +3 -0
  72. package/dist/utils/manifest.js +35 -0
  73. package/dist/utils/version.js +38 -1
  74. package/package.json +8 -7
  75. package/dist/services/jsdelivr-registry.js +0 -395
@@ -0,0 +1,75 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.renderHelpModal = renderHelpModal;
7
+ const chalk_1 = __importDefault(require("chalk"));
8
+ const modal_1 = require("../modal");
9
+ const keymap_1 = require("../keymap");
10
+ const themes_colors_1 = require("../themes-colors");
11
+ const KEY_COLUMN_WIDTH = 9;
12
+ /**
13
+ * Render the `?` help overlay with a pinned title + scrollable body, identical
14
+ * in structure to the performance panel so it handles small terminals gracefully.
15
+ */
16
+ function renderHelpModal(terminalWidth, terminalHeight, scrollOffset = 0) {
17
+ const modalWidth = (0, modal_1.getModalWidth)(terminalWidth, 54, 76);
18
+ const padding = Math.floor((terminalWidth - modalWidth) / 2);
19
+ const fixedModalHeight = Math.max(10, terminalHeight - 2);
20
+ // ── Pinned header (title) ──────────────────────────────────────────────────
21
+ const pinnedRows = [chalk_1.default.bold((0, themes_colors_1.getThemeColor)('primary')('Keyboard Shortcuts'))];
22
+ const pinnedRowCount = pinnedRows.length;
23
+ // ── Scrollable body (groups → bindings) ───────────────────────────────────
24
+ const bodyRows = [];
25
+ for (const { group, bindings } of (0, keymap_1.getHelpGroups)()) {
26
+ if (bodyRows.length > 0)
27
+ bodyRows.push('');
28
+ bodyRows.push((0, themes_colors_1.getThemeColor)('textSecondary')(group));
29
+ for (const binding of bindings) {
30
+ bodyRows.push(' ' +
31
+ chalk_1.default.bold.white(binding.displayKeys.padEnd(KEY_COLUMN_WIDTH)) +
32
+ (0, themes_colors_1.getThemeColor)('textSecondary')(binding.help));
33
+ }
34
+ }
35
+ // ── Scroll math (mirrors renderPerformanceModal) ───────────────────────────
36
+ // frame = top border + pinned rows + separator + body rows + bottom border
37
+ const availableForBody = Math.max(3, fixedModalHeight - 2 - pinnedRowCount - 1);
38
+ const totalScrollableRows = bodyRows.length;
39
+ const needsScroll = totalScrollableRows > availableForBody;
40
+ const visibleBodyRows = needsScroll ? Math.max(1, availableForBody - 1) : availableForBody;
41
+ const maxScroll = Math.max(0, totalScrollableRows - visibleBodyRows);
42
+ const clampedOffset = Math.min(Math.max(0, scrollOffset), maxScroll);
43
+ const visibleSlice = bodyRows.slice(clampedOffset, clampedOffset + visibleBodyRows);
44
+ // ── Render ─────────────────────────────────────────────────────────────────
45
+ const lines = [];
46
+ const topPadding = Math.max(0, Math.floor((terminalHeight - fixedModalHeight) / 2));
47
+ for (let i = 0; i < topPadding; i++)
48
+ lines.push('');
49
+ lines.push(' '.repeat(padding) + chalk_1.default.gray('╭' + '─'.repeat(modalWidth - 2) + '╮'));
50
+ for (const row of pinnedRows) {
51
+ lines.push((0, modal_1.renderModalRow)(padding, modalWidth, row));
52
+ }
53
+ lines.push((0, modal_1.renderModalSeparator)(padding, modalWidth));
54
+ for (const row of visibleSlice) {
55
+ lines.push((0, modal_1.renderModalRow)(padding, modalWidth, row));
56
+ }
57
+ const footer = needsScroll
58
+ ? chalk_1.default.gray(`Lines ${clampedOffset + 1}-${Math.min(clampedOffset + visibleBodyRows, totalScrollableRows)} of ${totalScrollableRows}`)
59
+ : null;
60
+ const usedContentRows = pinnedRowCount + 1 + visibleSlice.length + (footer ? 1 : 0);
61
+ const totalContentSlots = fixedModalHeight - 2;
62
+ const emptyRows = Math.max(0, totalContentSlots - usedContentRows);
63
+ for (let i = 0; i < emptyRows; i++)
64
+ lines.push((0, modal_1.renderModalRow)(padding, modalWidth, ''));
65
+ if (footer)
66
+ lines.push((0, modal_1.renderModalRow)(padding, modalWidth, footer));
67
+ lines.push(' '.repeat(padding) + chalk_1.default.gray('╰' + '─'.repeat(modalWidth - 2) + '╯'));
68
+ return {
69
+ lines,
70
+ maxScrollOffset: maxScroll,
71
+ totalContentRows: totalScrollableRows,
72
+ usesInternalScroll: needsScroll,
73
+ };
74
+ }
75
+ //# sourceMappingURL=help-modal.js.map
@@ -44,17 +44,14 @@ const Modal = __importStar(require("../modal"));
44
44
  * Main UI renderer class that composes all rendering parts
45
45
  */
46
46
  class UIRenderer {
47
- renderPackageLine(state, index, isCurrentRow, options) {
48
- return PackageList.renderPackageLine(state, index, isCurrentRow, 80, options);
49
- }
50
47
  renderSectionHeader(title, sectionType) {
51
48
  return PackageList.renderSectionHeader(title, sectionType);
52
49
  }
53
50
  renderSpacer() {
54
51
  return PackageList.renderSpacer();
55
52
  }
56
- renderInterface(states, currentRow, scrollOffset, maxVisibleItems, forceFullRender, renderableItems, activeFilterLabel, packageManager, filterMode, filterQuery, totalPackagesBeforeFilter, terminalWidth = 80, loadingProgress, auditProgress, options) {
57
- return PackageList.renderInterface(states, currentRow, scrollOffset, maxVisibleItems, forceFullRender, renderableItems, activeFilterLabel, packageManager, filterMode, filterQuery, totalPackagesBeforeFilter, terminalWidth, loadingProgress, auditProgress, options);
53
+ renderInterface(states, currentRow, scrollOffset, maxVisibleItems, forceFullRender, renderableItems, activeFilterLabel, packageManager, filterMode, filterQuery, totalPackagesBeforeFilter, terminalWidth = 80, loadingProgress, auditProgress, options, notice) {
54
+ return PackageList.renderInterface(states, currentRow, scrollOffset, maxVisibleItems, forceFullRender, renderableItems, activeFilterLabel, packageManager, filterMode, filterQuery, totalPackagesBeforeFilter, terminalWidth, loadingProgress, auditProgress, options, notice);
58
55
  }
59
56
  renderPackagesTable(packages) {
60
57
  return PackageList.renderPackagesTable(packages);
@@ -0,0 +1,184 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.renderInterface = renderInterface;
7
+ exports.renderPackagesTable = renderPackagesTable;
8
+ const chalk_1 = __importDefault(require("chalk"));
9
+ const utils_1 = require("../../utils");
10
+ const themes_colors_1 = require("../../themes-colors");
11
+ const config_1 = require("../../../config");
12
+ const rows_1 = require("./rows");
13
+ const keymap_1 = require("../../keymap");
14
+ function renderInterface(states, currentRow, scrollOffset, maxVisibleItems, _forceFullRender, renderableItems, activeFilterLabel, packageManager, filterMode, filterQuery, totalPackagesBeforeFilter, terminalWidth = 80, loadingProgress, auditProgress, options = {}, notice) {
15
+ const output = [];
16
+ if (packageManager) {
17
+ const colorMap = {
18
+ npm: chalk_1.default.red,
19
+ yarn: chalk_1.default.blue,
20
+ pnpm: chalk_1.default.yellow,
21
+ bun: chalk_1.default.magenta,
22
+ };
23
+ const pmColor = colorMap[packageManager.name] || packageManager.color;
24
+ const headerLine = ' ' +
25
+ chalk_1.default.bold(pmColor('🚀')) +
26
+ ' ' +
27
+ (0, themes_colors_1.coloredInupLogo)() +
28
+ (0, themes_colors_1.getThemeColor)('textSecondary')(` (${packageManager.displayName})`);
29
+ const fullHeaderLine = activeFilterLabel
30
+ ? headerLine +
31
+ (0, themes_colors_1.getThemeColor)('textSecondary')(' - ') +
32
+ (0, themes_colors_1.getThemeColor)('primary')(activeFilterLabel)
33
+ : headerLine;
34
+ const headerPadding = Math.max(0, terminalWidth - utils_1.VersionUtils.getVisualLength(fullHeaderLine));
35
+ output.push(fullHeaderLine + ' '.repeat(headerPadding));
36
+ }
37
+ else {
38
+ const headerLine = ' ' + chalk_1.default.bold.blue('🚀 ') + (0, themes_colors_1.coloredInupLogo)();
39
+ const fullHeaderLine = activeFilterLabel
40
+ ? headerLine +
41
+ (0, themes_colors_1.getThemeColor)('textSecondary')(' - ') +
42
+ (0, themes_colors_1.getThemeColor)('primary')(activeFilterLabel)
43
+ : headerLine;
44
+ const headerPadding = Math.max(0, terminalWidth - utils_1.VersionUtils.getVisualLength(fullHeaderLine));
45
+ output.push(fullHeaderLine + ' '.repeat(headerPadding));
46
+ }
47
+ output.push('');
48
+ if (filterMode) {
49
+ const filterDisplay = ' ' +
50
+ chalk_1.default.bold.white('Search: ') +
51
+ (0, themes_colors_1.getThemeColor)('primary')(filterQuery || '') +
52
+ (0, themes_colors_1.getThemeColor)('border')('█');
53
+ const padding = Math.max(0, terminalWidth - utils_1.VersionUtils.getVisualLength(filterDisplay));
54
+ output.push(filterDisplay + ' '.repeat(padding));
55
+ }
56
+ else if (filterQuery) {
57
+ const filterDisplay = ' ' +
58
+ chalk_1.default.bold.white('Search: ') +
59
+ (0, themes_colors_1.getThemeColor)('primary')(filterQuery) +
60
+ (0, themes_colors_1.getThemeColor)('textSecondary')(' (press / to edit)');
61
+ const padding = Math.max(0, terminalWidth - utils_1.VersionUtils.getVisualLength(filterDisplay));
62
+ output.push(filterDisplay + ' '.repeat(padding));
63
+ }
64
+ else {
65
+ const hintLine = (0, keymap_1.getFooterHints)()
66
+ .map(({ keyLabel, label }) => chalk_1.default.bold.white(keyLabel + ' ') + (0, themes_colors_1.getThemeColor)('textSecondary')(label))
67
+ .join(' ');
68
+ output.push(' ' + hintLine);
69
+ }
70
+ const totalPackages = states.length;
71
+ const totalBeforeFilter = totalPackagesBeforeFilter || totalPackages;
72
+ const totalVisualItems = renderableItems && renderableItems.length > 0 ? renderableItems.length : totalPackages;
73
+ const startItem = scrollOffset + 1;
74
+ const endItem = Math.min(scrollOffset + maxVisibleItems, totalVisualItems);
75
+ let statusLine = '';
76
+ if (filterMode) {
77
+ if (totalPackages === 0) {
78
+ statusLine =
79
+ (0, themes_colors_1.getThemeColor)('warning')(`No matches found`) +
80
+ ' ' +
81
+ chalk_1.default.bold.white('Esc ') +
82
+ chalk_1.default.gray('Clear');
83
+ }
84
+ else if (totalVisualItems > maxVisibleItems) {
85
+ statusLine =
86
+ (0, themes_colors_1.getThemeColor)('textSecondary')(`Showing ${chalk_1.default.white(startItem)}-${chalk_1.default.white(endItem)} of ${chalk_1.default.white(totalPackages)} matches`) +
87
+ ' ' +
88
+ chalk_1.default.bold.white('Enter ') +
89
+ chalk_1.default.gray('Apply') +
90
+ ' ' +
91
+ chalk_1.default.bold.white('Esc ') +
92
+ chalk_1.default.gray('Clear');
93
+ }
94
+ else {
95
+ statusLine =
96
+ (0, themes_colors_1.getThemeColor)('textSecondary')(`Showing all ${chalk_1.default.white(totalPackages)} matches`) +
97
+ ' ' +
98
+ chalk_1.default.bold.white('Enter ') +
99
+ chalk_1.default.gray('Apply') +
100
+ ' ' +
101
+ chalk_1.default.bold.white('Esc ') +
102
+ chalk_1.default.gray('Clear');
103
+ }
104
+ }
105
+ else if (totalPackages < totalBeforeFilter) {
106
+ // Footer already lists D/P/O, M, L, U — status line just shows count + Esc.
107
+ const matchCount = totalVisualItems > maxVisibleItems
108
+ ? (0, themes_colors_1.getThemeColor)('textSecondary')(`Showing ${chalk_1.default.white(startItem)}-${chalk_1.default.white(endItem)} of ${chalk_1.default.white(totalPackages)} matches`)
109
+ : (0, themes_colors_1.getThemeColor)('textSecondary')(`Showing all ${chalk_1.default.white(totalPackages)} matches`);
110
+ statusLine =
111
+ matchCount + ' ' + chalk_1.default.bold.white('Esc ') + chalk_1.default.gray('Clear filter');
112
+ }
113
+ else {
114
+ if (totalVisualItems > maxVisibleItems) {
115
+ statusLine =
116
+ chalk_1.default.gray(`Showing ${chalk_1.default.white(startItem)}-${chalk_1.default.white(endItem)} of ${chalk_1.default.white(totalPackages)} packages`) +
117
+ ' ' +
118
+ chalk_1.default.bold.white('Enter ') +
119
+ chalk_1.default.gray('Confirm');
120
+ }
121
+ else {
122
+ statusLine =
123
+ chalk_1.default.gray(`Showing all ${chalk_1.default.white(totalPackages)} packages`) +
124
+ ' ' +
125
+ chalk_1.default.bold.white('Enter ') +
126
+ chalk_1.default.gray('Confirm');
127
+ }
128
+ }
129
+ if (auditProgress && auditProgress.total > 0) {
130
+ const auditLabel = auditProgress.isRunning
131
+ ? `Audit ${auditProgress.completed}/${auditProgress.total}`
132
+ : `Audit ${auditProgress.total}/${auditProgress.total}`;
133
+ statusLine += ' ' + (0, themes_colors_1.getThemeColor)('textSecondary')(auditLabel);
134
+ }
135
+ // A one-shot notice (e.g. "nothing selected") replaces the status line for a
136
+ // single render so the layout height stays constant.
137
+ const statusContent = notice ? (0, themes_colors_1.getThemeColor)('warning')(notice) : statusLine;
138
+ const statusLineFull = ' ' + statusContent;
139
+ const statusPadding = Math.max(0, terminalWidth - utils_1.VersionUtils.getVisualLength(statusLineFull));
140
+ output.push(statusLineFull + ' '.repeat(statusPadding));
141
+ output.push('');
142
+ if (renderableItems && renderableItems.length > 0) {
143
+ for (let i = scrollOffset; i < Math.min(scrollOffset + maxVisibleItems, renderableItems.length); i++) {
144
+ const item = renderableItems[i];
145
+ if (item.type === 'header') {
146
+ output.push((0, rows_1.renderSectionHeader)(item.title, item.sectionType));
147
+ }
148
+ else if (item.type === 'spacer') {
149
+ output.push((0, rows_1.renderSpacer)());
150
+ }
151
+ else if (item.type === 'package') {
152
+ const line = (0, rows_1.renderPackageLine)(item.state, item.originalIndex, item.originalIndex === currentRow, terminalWidth, options);
153
+ output.push(line);
154
+ }
155
+ }
156
+ }
157
+ else {
158
+ for (let i = scrollOffset; i < Math.min(scrollOffset + maxVisibleItems, states.length); i++) {
159
+ const line = (0, rows_1.renderPackageLine)(states[i], i, i === currentRow, terminalWidth, options);
160
+ output.push(line);
161
+ }
162
+ }
163
+ if (loadingProgress?.isLoading) {
164
+ const loadingLabel = `Loading packages... (${loadingProgress.resolved}/${loadingProgress.total} checked)`;
165
+ const failedLabel = loadingProgress.failed > 0 ? ` ${loadingProgress.failed} unavailable` : '';
166
+ const loadingLine = ' ' +
167
+ (0, themes_colors_1.getThemeColor)('textSecondary')(loadingLabel) +
168
+ (failedLabel ? chalk_1.default.yellow(failedLabel) : '');
169
+ const loadingPadding = Math.max(0, terminalWidth - utils_1.VersionUtils.getVisualLength(loadingLine));
170
+ output.push(loadingLine + ' '.repeat(loadingPadding));
171
+ }
172
+ return output.map((line) => (0, rows_1.padLineToWidth)(line, terminalWidth));
173
+ }
174
+ function renderPackagesTable(packages) {
175
+ if (packages.length === 0) {
176
+ return chalk_1.default.green('✅ All packages are up to date!');
177
+ }
178
+ const outdatedPackages = packages.filter((p) => p.isOutdated);
179
+ if (outdatedPackages.length === 0) {
180
+ return chalk_1.default.green('✅ All packages are up to date!');
181
+ }
182
+ return chalk_1.default.bold.blue(`🚀 ${config_1.PACKAGE_NAME}\n`);
183
+ }
184
+ //# sourceMappingURL=interface.js.map
@@ -0,0 +1,177 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.padLineToWidth = padLineToWidth;
7
+ exports.renderPackageLine = renderPackageLine;
8
+ exports.renderSectionHeader = renderSectionHeader;
9
+ exports.renderSpacer = renderSpacer;
10
+ const chalk_1 = __importDefault(require("chalk"));
11
+ const utils_1 = require("../../utils");
12
+ const themes_colors_1 = require("../../themes-colors");
13
+ const vulnerability_1 = require("../../presenters/vulnerability");
14
+ const health_1 = require("../../presenters/health");
15
+ function padLineToWidth(line, terminalWidth) {
16
+ const padding = Math.max(0, terminalWidth - utils_1.VersionUtils.getVisualLength(line));
17
+ return line + ' '.repeat(padding);
18
+ }
19
+ function getTypeBadge(type) {
20
+ switch (type) {
21
+ case 'devDependencies':
22
+ return (0, themes_colors_1.getThemeColor)('textSecondary')('[D]');
23
+ case 'peerDependencies':
24
+ return (0, themes_colors_1.getThemeColor)('textSecondary')('[P]');
25
+ case 'optionalDependencies':
26
+ return (0, themes_colors_1.getThemeColor)('textSecondary')('[O]');
27
+ case 'dependencies':
28
+ default:
29
+ return '';
30
+ }
31
+ }
32
+ function renderPackageLine(state, _index, isCurrentRow, terminalWidth = 80, options = {}) {
33
+ const prefix = isCurrentRow ? (0, themes_colors_1.getThemeColor)('success')('❯ ') : ' ';
34
+ let packageName;
35
+ if (state.name.startsWith('@')) {
36
+ const parts = state.name.split('/');
37
+ if (parts.length >= 2) {
38
+ const author = parts[0];
39
+ const packagePart = parts.slice(1).join('/');
40
+ if (isCurrentRow) {
41
+ packageName =
42
+ chalk_1.default.bold((0, themes_colors_1.getThemeColor)('packageAuthor')(author)) +
43
+ (0, themes_colors_1.getThemeColor)('packageName')('/' + packagePart);
44
+ }
45
+ else {
46
+ packageName = chalk_1.default.bold.white(author) + chalk_1.default.white('/' + packagePart);
47
+ }
48
+ }
49
+ else {
50
+ packageName = isCurrentRow
51
+ ? (0, themes_colors_1.getThemeColor)('packageName')(state.name)
52
+ : chalk_1.default.white(state.name);
53
+ }
54
+ }
55
+ else {
56
+ packageName = isCurrentRow ? (0, themes_colors_1.getThemeColor)('packageName')(state.name) : chalk_1.default.white(state.name);
57
+ }
58
+ const isCurrentSelected = state.selectedOption === 'none';
59
+ const isRangeSelected = state.selectedOption === 'range';
60
+ const isLatestSelected = state.selectedOption === 'latest';
61
+ const isPending = state.loadState === 'pending';
62
+ const isFailed = state.loadState === 'failed';
63
+ const currentDot = isCurrentSelected ? (0, themes_colors_1.getThemeColor)('dot')('●') : (0, themes_colors_1.getThemeColor)('dotEmpty')('○');
64
+ const currentVersion = chalk_1.default.white(state.currentVersionSpecifier);
65
+ let rangeDot = '';
66
+ let rangeVersionText = '';
67
+ if (isPending) {
68
+ rangeDot = (0, themes_colors_1.getThemeColor)('dotEmpty')('◌');
69
+ rangeVersionText = chalk_1.default.gray('loading');
70
+ }
71
+ else if (isFailed) {
72
+ rangeDot = (0, themes_colors_1.getThemeColor)('dotEmpty')('◌');
73
+ rangeVersionText = chalk_1.default.gray('unavailable');
74
+ }
75
+ else if (state.hasRangeUpdate) {
76
+ rangeDot = isRangeSelected ? (0, themes_colors_1.getThemeColor)('dot')('●') : (0, themes_colors_1.getThemeColor)('dotEmpty')('○');
77
+ const rangeVersionWithPrefix = utils_1.VersionUtils.applyVersionPrefix(state.currentVersionSpecifier, state.rangeVersion);
78
+ rangeVersionText = (0, themes_colors_1.getThemeColor)('versionRange')(rangeVersionWithPrefix);
79
+ }
80
+ else {
81
+ rangeDot = (0, themes_colors_1.getThemeColor)('dotEmpty')('○');
82
+ rangeVersionText = '';
83
+ }
84
+ let latestDot = '';
85
+ let latestVersionText = '';
86
+ if (isPending) {
87
+ latestDot = (0, themes_colors_1.getThemeColor)('dotEmpty')('◌');
88
+ latestVersionText = chalk_1.default.gray('loading');
89
+ }
90
+ else if (isFailed) {
91
+ latestDot = (0, themes_colors_1.getThemeColor)('dotEmpty')('◌');
92
+ latestVersionText = chalk_1.default.gray('unavailable');
93
+ }
94
+ else if (state.hasMajorUpdate) {
95
+ latestDot = isLatestSelected ? (0, themes_colors_1.getThemeColor)('dot')('●') : (0, themes_colors_1.getThemeColor)('dotEmpty')('○');
96
+ const latestVersionWithPrefix = utils_1.VersionUtils.applyVersionPrefix(state.currentVersionSpecifier, state.latestVersion);
97
+ latestVersionText = (0, themes_colors_1.getThemeColor)('versionLatest')(latestVersionWithPrefix);
98
+ }
99
+ else {
100
+ latestDot = (0, themes_colors_1.getThemeColor)('dotEmpty')('○');
101
+ latestVersionText = '';
102
+ }
103
+ const currentColumnWidth = 16;
104
+ const rangeColumnWidth = 16;
105
+ const latestColumnWidth = 16;
106
+ const spacingWidth = 3;
107
+ const maxPackageNameWidth = 50;
108
+ const minPackageNameWidth = 24;
109
+ const otherColumnsWidth = currentColumnWidth + rangeColumnWidth + latestColumnWidth + spacingWidth * 3;
110
+ const prefixWidth = 2;
111
+ const availableForPackageName = terminalWidth - prefixWidth - otherColumnsWidth - 1;
112
+ const packageNameWidth = Math.min(maxPackageNameWidth, Math.max(minPackageNameWidth, availableForPackageName));
113
+ const badgeWidth = state.type === 'dependencies' ? 0 : 3;
114
+ const truncatedName = utils_1.VersionUtils.truncateMiddle(state.name, packageNameWidth - 1 - badgeWidth);
115
+ const shouldShowDashes = (paddingAmount) => paddingAmount > 2;
116
+ const dashColor = isCurrentRow ? chalk_1.default.white : chalk_1.default.gray;
117
+ const displayName = truncatedName !== state.name ? truncatedName : packageName;
118
+ const typeBadge = getTypeBadge(state.type);
119
+ const shouldShowVulnerability = (0, vulnerability_1.shouldDisplayVulnerabilityForDependency)(state.type, options);
120
+ const vulnBadge = shouldShowVulnerability ? (0, vulnerability_1.getVulnerabilityBadge)(state.vulnerability) : '';
121
+ const vulnBadgeWidth = vulnBadge ? utils_1.VersionUtils.getVisualLength(vulnBadge) + 1 : 0;
122
+ // Deprecation / engines-incompatibility marker (independent of dep type).
123
+ const healthBadge = (0, health_1.getHealthBadge)(state);
124
+ const healthBadgeWidth = healthBadge ? utils_1.VersionUtils.getVisualLength(healthBadge) + 1 : 0;
125
+ const nameLength = utils_1.VersionUtils.getVisualLength(truncatedName);
126
+ const namePadding = Math.max(0, packageNameWidth - nameLength - 1 - badgeWidth - vulnBadgeWidth - healthBadgeWidth);
127
+ const nameDashes = shouldShowDashes(namePadding)
128
+ ? dashColor('-').repeat(namePadding)
129
+ : ' '.repeat(namePadding);
130
+ const vulnSuffix = vulnBadge ? ` ${vulnBadge}` : '';
131
+ const healthSuffix = healthBadge ? ` ${healthBadge}` : '';
132
+ const packageNameSection = typeBadge
133
+ ? `${displayName} ${nameDashes}${vulnSuffix}${healthSuffix}${typeBadge}`
134
+ : `${displayName} ${nameDashes}${vulnSuffix}${healthSuffix}`;
135
+ const currentSection = `${currentDot} ${currentVersion}`;
136
+ const currentSectionLength = utils_1.VersionUtils.getVisualLength(currentSection) + 1;
137
+ const currentPadding = Math.max(0, currentColumnWidth - currentSectionLength);
138
+ const currentPaddingText = shouldShowDashes(currentPadding)
139
+ ? dashColor('-').repeat(currentPadding)
140
+ : ' '.repeat(currentPadding);
141
+ const currentWithPadding = currentSection + ' ' + currentPaddingText;
142
+ let rangeSection = '';
143
+ if (isPending || isFailed || state.hasRangeUpdate) {
144
+ rangeSection = `${rangeDot} ${rangeVersionText}`;
145
+ const rangeSectionLength = utils_1.VersionUtils.getVisualLength(rangeSection) + 1;
146
+ const rangePadding = Math.max(0, rangeColumnWidth - rangeSectionLength);
147
+ const rangePaddingText = shouldShowDashes(rangePadding)
148
+ ? dashColor('-').repeat(rangePadding)
149
+ : ' '.repeat(rangePadding);
150
+ rangeSection += ' ' + rangePaddingText;
151
+ }
152
+ else {
153
+ rangeSection = ' '.repeat(rangeColumnWidth);
154
+ }
155
+ let latestSection = '';
156
+ if (isPending || isFailed || state.hasMajorUpdate) {
157
+ latestSection = `${latestDot} ${latestVersionText}`;
158
+ const latestSectionLength = utils_1.VersionUtils.getVisualLength(latestSection) + 1;
159
+ const latestPadding = Math.max(0, latestColumnWidth - latestSectionLength);
160
+ const latestPaddingText = shouldShowDashes(latestPadding)
161
+ ? dashColor('-').repeat(latestPadding)
162
+ : ' '.repeat(latestPadding);
163
+ latestSection += ' ' + latestPaddingText;
164
+ }
165
+ else {
166
+ latestSection = ' '.repeat(latestColumnWidth);
167
+ }
168
+ return `${prefix}${packageNameSection} ${currentWithPadding} ${rangeSection} ${latestSection}`;
169
+ }
170
+ function renderSectionHeader(title, sectionType) {
171
+ const colorFn = sectionType === 'main' ? chalk_1.default.cyan : sectionType === 'peer' ? chalk_1.default.magenta : chalk_1.default.yellow;
172
+ return ' ' + colorFn.bold(title);
173
+ }
174
+ function renderSpacer() {
175
+ return '';
176
+ }
177
+ //# sourceMappingURL=rows.js.map