@visulima/vis 1.0.0-alpha.3 → 1.0.0-alpha.5
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/CHANGELOG.md +151 -24
- package/LICENSE.md +27 -0
- package/README.md +15 -9
- package/dist/audit-config.d.ts +24 -0
- package/dist/bin.js +784 -70
- package/dist/catalog.d.ts +37 -11
- package/dist/commands/add.d.ts +3 -0
- package/dist/commands/approve-builds.d.ts +3 -0
- package/dist/commands/audit.d.ts +23 -0
- package/dist/commands/clean.d.ts +3 -0
- package/dist/commands/create/discovery.d.ts +42 -0
- package/dist/commands/create/index.d.ts +13 -0
- package/dist/commands/create/prompts.d.ts +31 -0
- package/dist/commands/create/random-name.d.ts +15 -0
- package/dist/commands/create/templates/builtin.d.ts +15 -0
- package/dist/commands/create/templates/generator.d.ts +14 -0
- package/dist/commands/create/templates/index.d.ts +13 -0
- package/dist/commands/create/templates/monorepo.d.ts +16 -0
- package/dist/commands/create/templates/remote.d.ts +41 -0
- package/dist/commands/create/templates/types.d.ts +46 -0
- package/dist/commands/create/utils.d.ts +42 -0
- package/dist/commands/dedupe.d.ts +3 -0
- package/dist/commands/devcontainer.d.ts +3 -0
- package/dist/commands/dlx.d.ts +3 -0
- package/dist/commands/doctor.d.ts +15 -0
- package/dist/commands/exec.d.ts +3 -0
- package/dist/commands/implode.d.ts +3 -0
- package/dist/commands/init.d.ts +14 -0
- package/dist/commands/install.d.ts +3 -0
- package/dist/commands/link.d.ts +3 -0
- package/dist/commands/optimize.d.ts +38 -0
- package/dist/commands/pm.d.ts +3 -0
- package/dist/commands/remove.d.ts +3 -0
- package/dist/commands/sort-package-json.d.ts +3 -0
- package/dist/commands/unlink.d.ts +3 -0
- package/dist/commands/upgrade.d.ts +3 -0
- package/dist/commands/why.d.ts +3 -0
- package/dist/config.d.ts +38 -11
- package/dist/config.js +1 -1
- package/dist/native-binding.d.ts +151 -0
- package/dist/output.d.ts +40 -0
- package/dist/overrides.d.ts +82 -0
- package/dist/plugins/config-loader.d.ts +3 -0
- package/dist/plugins/post-command.d.ts +3 -0
- package/dist/plugins/security-enforcement.d.ts +3 -0
- package/dist/pm-runner.d.ts +23 -0
- package/dist/security.d.ts +64 -0
- package/dist/socket-security.d.ts +129 -0
- package/dist/tips.d.ts +41 -0
- package/dist/tui/components/CheckProgressApp.d.ts +6 -0
- package/dist/tui/components/CommandSummary.d.ts +17 -0
- package/dist/tui/components/Header.d.ts +13 -0
- package/dist/tui/components/OutputPanel.d.ts +16 -0
- package/dist/tui/components/QuitDialog.d.ts +15 -0
- package/dist/tui/components/TaskListPanel.d.ts +19 -0
- package/dist/tui/components/TaskRow.d.ts +12 -0
- package/dist/tui/components/TaskStore.d.ts +80 -0
- package/dist/tui/components/VisTaskRunnerApp.d.ts +17 -0
- package/dist/tui/components/devcontainer/DevcontainerStore.d.ts +66 -0
- package/dist/tui/components/devcontainer/VisDevcontainerApp.d.ts +9 -0
- package/dist/tui/components/devcontainer/catalogs/extensions.d.ts +8 -0
- package/dist/tui/components/devcontainer/catalogs/features.d.ts +8 -0
- package/dist/tui/components/devcontainer/catalogs/filters.d.ts +4 -0
- package/dist/tui/components/devcontainer/catalogs/mount-suggestions.d.ts +19 -0
- package/dist/tui/components/devcontainer/catalogs/templates.d.ts +8 -0
- package/dist/tui/components/devcontainer/devcontainer-io.d.ts +14 -0
- package/dist/tui/components/devcontainer/sections/DockerComposeSection.d.ts +11 -0
- package/dist/tui/components/devcontainer/sections/EnvironmentSection.d.ts +16 -0
- package/dist/tui/components/devcontainer/sections/ExtensionsSection.d.ts +11 -0
- package/dist/tui/components/devcontainer/sections/FeaturesSection.d.ts +11 -0
- package/dist/tui/components/devcontainer/sections/GeneralSection.d.ts +12 -0
- package/dist/tui/components/devcontainer/sections/LifecycleSection.d.ts +13 -0
- package/dist/tui/components/devcontainer/sections/MountsSection.d.ts +16 -0
- package/dist/tui/components/devcontainer/sections/PortsSection.d.ts +10 -0
- package/dist/tui/components/devcontainer/sections/PreviewPanel.d.ts +11 -0
- package/dist/tui/components/devcontainer/types.d.ts +53 -0
- package/dist/tui/components/devcontainer/validate.d.ts +16 -0
- package/dist/tui/components/graph/GraphStore.d.ts +42 -0
- package/dist/tui/components/graph/ProjectDetailPanel.d.ts +10 -0
- package/dist/tui/components/graph/ProjectListPanel.d.ts +20 -0
- package/dist/tui/components/graph/VisGraphApp.d.ts +8 -0
- package/dist/tui/components/optimize/OptimizeDetailPanel.d.ts +9 -0
- package/dist/tui/components/optimize/OptimizeListPanel.d.ts +16 -0
- package/dist/tui/components/optimize/OptimizeStore.d.ts +50 -0
- package/dist/tui/components/optimize/VisOptimizeApp.d.ts +8 -0
- package/dist/tui/components/optimize/constants.d.ts +7 -0
- package/dist/tui/components/update/PackageDetailPanel.d.ts +12 -0
- package/dist/tui/components/update/PackageListPanel.d.ts +21 -0
- package/dist/tui/components/update/UpdateStore.d.ts +62 -0
- package/dist/tui/components/update/VisUpdateApp.d.ts +18 -0
- package/dist/tui/dynamic-life-cycle.d.ts +21 -0
- package/dist/tui/formatting-utils.d.ts +17 -0
- package/dist/tui/pretty-time.d.ts +8 -0
- package/dist/tui/static-life-cycle.d.ts +22 -0
- package/dist/tui/status-utils.d.ts +20 -0
- package/dist/tui/symbols.d.ts +7 -0
- package/dist/tui/types.d.ts +11 -0
- package/dist/typosquats.d.ts +70 -0
- package/dist/upgrade-check.d.ts +30 -0
- package/dist/utils.d.ts +22 -0
- package/dist/workspace.d.ts +302 -5
- package/index.js +600 -0
- package/package.json +34 -11
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/** An optimization entry that can be either an e18e module replacement or a Socket.dev override. */
|
|
2
|
+
interface OptimizeEntry {
|
|
3
|
+
/** Category for filtering and display. */
|
|
4
|
+
category: "micro-utility" | "native" | "preferred" | "socket";
|
|
5
|
+
/** Whether a codemod is available for this entry (e18e only). */
|
|
6
|
+
hasCodemod: boolean;
|
|
7
|
+
/** The override spec for socket entries (e.g., "npm:@socketregistry/is-regex@^1"). */
|
|
8
|
+
overrideSpec?: string;
|
|
9
|
+
/** The original package name. */
|
|
10
|
+
packageName: string;
|
|
11
|
+
/** Human-readable replacement target description. */
|
|
12
|
+
replacement: string;
|
|
13
|
+
}
|
|
14
|
+
type FilterType = "all" | "micro-utility" | "native" | "preferred" | "socket";
|
|
15
|
+
interface OptimizeState {
|
|
16
|
+
applyProgress: {
|
|
17
|
+
current: number;
|
|
18
|
+
total: number;
|
|
19
|
+
} | null;
|
|
20
|
+
checkedEntries: Set<string>;
|
|
21
|
+
entries: OptimizeEntry[];
|
|
22
|
+
error: string | null;
|
|
23
|
+
filterActive: boolean;
|
|
24
|
+
filterText: string;
|
|
25
|
+
filterType: FilterType;
|
|
26
|
+
focusedPanel: "detail" | "list";
|
|
27
|
+
phase: "applying" | "browsing" | "done" | "error";
|
|
28
|
+
selectedIndex: number;
|
|
29
|
+
}
|
|
30
|
+
type Listener = () => void;
|
|
31
|
+
declare class OptimizeStore {
|
|
32
|
+
#private;
|
|
33
|
+
constructor(entries: OptimizeEntry[]);
|
|
34
|
+
getSnapshot: () => OptimizeState;
|
|
35
|
+
subscribe: (listener: Listener) => () => void;
|
|
36
|
+
getFilteredEntries: () => OptimizeEntry[];
|
|
37
|
+
select(index: number): void;
|
|
38
|
+
toggleCheck(packageName: string): void;
|
|
39
|
+
toggleAll(): void;
|
|
40
|
+
setFilter(type: FilterType): void;
|
|
41
|
+
setFilterText(text: string): void;
|
|
42
|
+
setFilterActive(active: boolean): void;
|
|
43
|
+
setFocusedPanel(panel: "detail" | "list"): void;
|
|
44
|
+
setPhase(phase: OptimizeState["phase"]): void;
|
|
45
|
+
setProgress(current: number, total: number): void;
|
|
46
|
+
setError(error: string): void;
|
|
47
|
+
getCheckedEntries(): OptimizeEntry[];
|
|
48
|
+
}
|
|
49
|
+
export type { FilterType, OptimizeEntry, OptimizeState };
|
|
50
|
+
export { OptimizeStore };
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import type { OptimizeStore } from "./OptimizeStore.d.ts";
|
|
3
|
+
interface VisOptimizeAppProps {
|
|
4
|
+
isDryRun: boolean;
|
|
5
|
+
store: OptimizeStore;
|
|
6
|
+
}
|
|
7
|
+
declare const VisOptimizeApp: ({ isDryRun, store }: VisOptimizeAppProps) => React.JSX.Element;
|
|
8
|
+
export default VisOptimizeApp;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/** Category colors for the optimize TUI — shared between list and detail panels. */
|
|
2
|
+
declare const CATEGORY_COLORS: Record<string, string>;
|
|
3
|
+
/** Short labels for category badges in the list panel. */
|
|
4
|
+
declare const CATEGORY_LABELS: Record<string, string>;
|
|
5
|
+
/** Human-readable descriptions for each optimization category. */
|
|
6
|
+
declare const CATEGORY_DESCRIPTIONS: Record<string, string>;
|
|
7
|
+
export { CATEGORY_COLORS, CATEGORY_DESCRIPTIONS, CATEGORY_LABELS };
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { ScrollViewRef } from "@visulima/tui";
|
|
2
|
+
import type { AiRecommendation } from "../../../ai-analysis.d.ts";
|
|
3
|
+
import type { OutdatedEntry } from "../../../catalog.d.ts";
|
|
4
|
+
interface PackageDetailPanelProps {
|
|
5
|
+
changelogUrl?: string;
|
|
6
|
+
entry: OutdatedEntry | null;
|
|
7
|
+
focused: boolean;
|
|
8
|
+
recommendation?: AiRecommendation;
|
|
9
|
+
scrollRef?: React.RefObject<ScrollViewRef>;
|
|
10
|
+
}
|
|
11
|
+
declare const PackageDetailPanel: ({ changelogUrl, entry, focused, recommendation, scrollRef }: PackageDetailPanelProps) => React.JSX.Element;
|
|
12
|
+
export default PackageDetailPanel;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { OutdatedEntry } from "../../../catalog.d.ts";
|
|
2
|
+
import type { FilterType } from "./UpdateStore.d.ts";
|
|
3
|
+
interface PackageListPanelProps {
|
|
4
|
+
checkedEntries: Set<string>;
|
|
5
|
+
entries: OutdatedEntry[];
|
|
6
|
+
filterActive: boolean;
|
|
7
|
+
filterText: string;
|
|
8
|
+
filterType: FilterType;
|
|
9
|
+
filteredOutCount: number;
|
|
10
|
+
focused: boolean;
|
|
11
|
+
groupedByCatalog: Map<string, OutdatedEntry[]>;
|
|
12
|
+
isDryRun: boolean;
|
|
13
|
+
scrollOffset: number;
|
|
14
|
+
selectedIndex: number;
|
|
15
|
+
totalCatalogEntries: number;
|
|
16
|
+
totalChecked: number;
|
|
17
|
+
totalEntries: number;
|
|
18
|
+
viewportHeight: number;
|
|
19
|
+
}
|
|
20
|
+
declare const PackageListPanel: ({ checkedEntries, entries, filterActive, filterText, filterType, filteredOutCount, focused, groupedByCatalog, isDryRun, scrollOffset, selectedIndex, totalCatalogEntries, totalChecked, totalEntries, viewportHeight, }: PackageListPanelProps) => React.JSX.Element;
|
|
21
|
+
export default PackageListPanel;
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import type { AiAnalysisResult, AiRecommendation } from "../../../ai-analysis.d.ts";
|
|
2
|
+
import type { OutdatedEntry } from "../../../catalog.d.ts";
|
|
3
|
+
export type FilterType = "all" | "major" | "minor" | "patch" | "security";
|
|
4
|
+
export type UpdatePhase = "applying" | "browsing" | "done" | "error";
|
|
5
|
+
export interface UpdateState {
|
|
6
|
+
/** AI analysis result (null if not requested). */
|
|
7
|
+
aiResult: AiAnalysisResult | null;
|
|
8
|
+
/** Whether all visible entries are checked. */
|
|
9
|
+
allChecked: boolean;
|
|
10
|
+
/** Progress during apply phase. */
|
|
11
|
+
applyProgress: {
|
|
12
|
+
current: number;
|
|
13
|
+
total: number;
|
|
14
|
+
} | null;
|
|
15
|
+
/** Set of checked package names for selective apply. */
|
|
16
|
+
checkedEntries: Set<string>;
|
|
17
|
+
/** All outdated entries. */
|
|
18
|
+
entries: OutdatedEntry[];
|
|
19
|
+
/** Error message if apply failed. */
|
|
20
|
+
error: string | null;
|
|
21
|
+
/** Whether the text filter input is active. */
|
|
22
|
+
filterActive: boolean;
|
|
23
|
+
/** Current filter text (empty = no filter). */
|
|
24
|
+
filterText: string;
|
|
25
|
+
/** Filter by update type. */
|
|
26
|
+
filterType: FilterType;
|
|
27
|
+
/** Which panel has keyboard focus. */
|
|
28
|
+
focusedPanel: "detail" | "list";
|
|
29
|
+
/** Entries grouped by catalog name. */
|
|
30
|
+
groupedByCatalog: Map<string, OutdatedEntry[]>;
|
|
31
|
+
/** Current lifecycle phase. */
|
|
32
|
+
phase: UpdatePhase;
|
|
33
|
+
/** Currently highlighted entry index in the filtered list. */
|
|
34
|
+
selectedIndex: number;
|
|
35
|
+
}
|
|
36
|
+
type Listener = () => void;
|
|
37
|
+
export declare class UpdateStore {
|
|
38
|
+
#private;
|
|
39
|
+
constructor(entries: OutdatedEntry[], aiResult?: AiAnalysisResult | null);
|
|
40
|
+
getSnapshot: () => UpdateState;
|
|
41
|
+
subscribe: (listener: Listener) => () => void;
|
|
42
|
+
/** Get the currently filtered + visible entries. */
|
|
43
|
+
getFilteredEntries(): OutdatedEntry[];
|
|
44
|
+
/** Get AI recommendation for a specific package. */
|
|
45
|
+
getRecommendation(packageName: string): AiRecommendation | undefined;
|
|
46
|
+
/** Get the list of checked entries (for apply). */
|
|
47
|
+
getCheckedEntries(): OutdatedEntry[];
|
|
48
|
+
setSelectedIndex(index: number): void;
|
|
49
|
+
setFocusedPanel(panel: "detail" | "list"): void;
|
|
50
|
+
setFilterType(type: FilterType): void;
|
|
51
|
+
setFilter(text: string): void;
|
|
52
|
+
setFilterActive(active: boolean): void;
|
|
53
|
+
toggleCheck(packageName: string): void;
|
|
54
|
+
checkAll(): void;
|
|
55
|
+
uncheckAll(): void;
|
|
56
|
+
toggleAll(): void;
|
|
57
|
+
startApply(): void;
|
|
58
|
+
updateApplyProgress(current: number): void;
|
|
59
|
+
markDone(): void;
|
|
60
|
+
setError(error: string): void;
|
|
61
|
+
}
|
|
62
|
+
export {};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import type { OutdatedEntry } from "../../../catalog.d.ts";
|
|
3
|
+
import type { UpdateStore } from "./UpdateStore.d.ts";
|
|
4
|
+
interface VisUpdateAppProps {
|
|
5
|
+
/** 0 = no auto-exit (default), >0 = countdown seconds */
|
|
6
|
+
autoExitSeconds?: number;
|
|
7
|
+
changelogUrls?: Map<string, string>;
|
|
8
|
+
/** Total unique packages checked by the registry. */
|
|
9
|
+
checkedCount?: number;
|
|
10
|
+
/** Total catalog entries (before deduplication). */
|
|
11
|
+
totalCatalogEntries?: number;
|
|
12
|
+
/** Packages that have newer versions but were filtered out by the target constraint. */
|
|
13
|
+
filteredOutEntries?: OutdatedEntry[];
|
|
14
|
+
isDryRun: boolean;
|
|
15
|
+
store: UpdateStore;
|
|
16
|
+
}
|
|
17
|
+
declare const VisUpdateApp: ({ autoExitSeconds, changelogUrls, checkedCount, filteredOutEntries, isDryRun, store, totalCatalogEntries }: VisUpdateAppProps) => React.JSX.Element;
|
|
18
|
+
export default VisUpdateApp;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { LifeCycleInterface, Task } from "@visulima/task-runner";
|
|
2
|
+
import { TaskStore } from "./components/TaskStore.d.ts";
|
|
3
|
+
interface DynamicOutputOptions {
|
|
4
|
+
args: {
|
|
5
|
+
parallel?: boolean | number;
|
|
6
|
+
targets: string[];
|
|
7
|
+
};
|
|
8
|
+
/** Auto-exit config: false = stay open, true = 3s countdown, number = custom seconds */
|
|
9
|
+
autoExit?: boolean | number;
|
|
10
|
+
projectNames: string[];
|
|
11
|
+
/** Registry of writable stdin entries keyed by task ID, for interactive input. */
|
|
12
|
+
stdinRegistry?: Map<string, import("./types").StdinEntry>;
|
|
13
|
+
tasks: Task[];
|
|
14
|
+
}
|
|
15
|
+
interface DynamicOutputResult {
|
|
16
|
+
lifeCycle: LifeCycleInterface;
|
|
17
|
+
renderIsDone: Promise<void>;
|
|
18
|
+
store: TaskStore;
|
|
19
|
+
}
|
|
20
|
+
export declare const createDynamicOutputRenderer: (options: DynamicOutputOptions) => DynamicOutputResult;
|
|
21
|
+
export {};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { Task } from "@visulima/task-runner";
|
|
2
|
+
/**
|
|
3
|
+
* Formats a CLI flag for display output.
|
|
4
|
+
* @param leftPad Padding string
|
|
5
|
+
* @param flag The flag name
|
|
6
|
+
* @param value The flag value
|
|
7
|
+
*/
|
|
8
|
+
export declare const formatFlags: (leftPad: string, flag: string, value: unknown) => string;
|
|
9
|
+
/**
|
|
10
|
+
* Generates a human-readable description of the targets and projects being executed.
|
|
11
|
+
*
|
|
12
|
+
* Examples:
|
|
13
|
+
* - "target build for project my-app"
|
|
14
|
+
* - "targets build, test for 5 projects"
|
|
15
|
+
* - "target build for 3 projects and 2 tasks they depend on"
|
|
16
|
+
*/
|
|
17
|
+
export declare const formatTargetsAndProjects: (projectNames: string[], targets: string[], tasks: Task[]) => string;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Formats a process.hrtime() tuple into a compact string like "1s 234ms".
|
|
3
|
+
*/
|
|
4
|
+
export declare const formatHrtime: (hrtime: [number, number]) => string;
|
|
5
|
+
/**
|
|
6
|
+
* Formats milliseconds into a compact string like "1s 300ms", "340ms", "1m 5s".
|
|
7
|
+
*/
|
|
8
|
+
export declare const formatMs: (ms: number) => string;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { LifeCycleInterface, Task, TaskResult, TaskStatus } from "@visulima/task-runner";
|
|
2
|
+
interface StaticOutputOptions {
|
|
3
|
+
args: {
|
|
4
|
+
targets: string[];
|
|
5
|
+
};
|
|
6
|
+
projectNames: string[];
|
|
7
|
+
tasks: Task[];
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* A lifecycle handler for CI environments that produces static, append-only output.
|
|
11
|
+
* No cursor manipulation — just linear log lines.
|
|
12
|
+
*/
|
|
13
|
+
export declare class StaticOutputLifeCycle implements LifeCycleInterface {
|
|
14
|
+
#private;
|
|
15
|
+
constructor(options: StaticOutputOptions);
|
|
16
|
+
startCommand(): void;
|
|
17
|
+
startTasks(tasks: Task[]): void;
|
|
18
|
+
endTasks(taskResults: TaskResult[]): void;
|
|
19
|
+
printTaskTerminalOutput(task: Task, status: TaskStatus, terminalOutput: string): void;
|
|
20
|
+
endCommand(): void;
|
|
21
|
+
}
|
|
22
|
+
export {};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { TaskStatus } from "@visulima/task-runner";
|
|
2
|
+
export declare const isCacheStatus: (status: string) => boolean;
|
|
3
|
+
export interface StatusInfo {
|
|
4
|
+
color: string;
|
|
5
|
+
icon: string;
|
|
6
|
+
}
|
|
7
|
+
export declare const getStatusInfo: (status: TaskStatus) => StatusInfo;
|
|
8
|
+
/**
|
|
9
|
+
* Returns the colored status icon as an ANSI string (for raw stdout writes).
|
|
10
|
+
*/
|
|
11
|
+
export declare const getStatusIcon: (status: TaskStatus) => string;
|
|
12
|
+
/**
|
|
13
|
+
* Returns a colored prefix string for a status (for raw stdout writes).
|
|
14
|
+
*/
|
|
15
|
+
export declare const getStatusPrefix: (status: TaskStatus) => string;
|
|
16
|
+
/**
|
|
17
|
+
* Logs task terminal output with formatting.
|
|
18
|
+
* Uses GitHub Actions grouping when available.
|
|
19
|
+
*/
|
|
20
|
+
export declare const logCommandOutputCI: (taskId: string, status: TaskStatus, output: string) => void;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Represents a writable stdin entry for interactive PTY input.
|
|
3
|
+
*/
|
|
4
|
+
export interface StdinEntry {
|
|
5
|
+
/** Kill the child process/PTY. */
|
|
6
|
+
kill?: (signal?: string) => void;
|
|
7
|
+
/** Resize the child's PTY (only available for PTY-backed processes). */
|
|
8
|
+
resize?: (cols: number, rows: number) => void;
|
|
9
|
+
/** Write data to the child's stdin or PTY. */
|
|
10
|
+
write: (data: string) => void;
|
|
11
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Typosquat detection for package names.
|
|
3
|
+
*
|
|
4
|
+
* Uses a curated blocklist of known typosquats (data/typosquats.json) and
|
|
5
|
+
* runtime heuristics (character substitution, transposition, omission) to
|
|
6
|
+
* warn users before they install a potentially malicious package.
|
|
7
|
+
*/
|
|
8
|
+
export type Blocklist = Record<string, string[]>;
|
|
9
|
+
export interface TyposquatMatch {
|
|
10
|
+
/** The package name that was checked. */
|
|
11
|
+
input: string;
|
|
12
|
+
/** The legitimate package this appears to be a typosquat of. */
|
|
13
|
+
legitimate: string;
|
|
14
|
+
/** How the match was detected: "blocklist" (exact match in JSON) or "heuristic" (generated variant). */
|
|
15
|
+
method: "blocklist" | "heuristic";
|
|
16
|
+
}
|
|
17
|
+
export interface TyposquatCheckResult {
|
|
18
|
+
/** Whether the operation should proceed. */
|
|
19
|
+
ok: boolean;
|
|
20
|
+
/**
|
|
21
|
+
* The (possibly corrected) package names to use.
|
|
22
|
+
* When the user chooses "use suggested name", the typosquat names are
|
|
23
|
+
* replaced with their legitimate counterparts.
|
|
24
|
+
*/
|
|
25
|
+
packages: string[];
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Generates typosquat variants of a package name using common attack patterns:
|
|
29
|
+
* - Character omission (dropping one character)
|
|
30
|
+
* - Adjacent character transposition (swapping neighbors)
|
|
31
|
+
* - Character duplication (repeating one character)
|
|
32
|
+
* - Homoglyph / keyboard substitution
|
|
33
|
+
* - Separator manipulation (dash/dot/underscore swaps)
|
|
34
|
+
* - Common suffixes (-js, -node)
|
|
35
|
+
*
|
|
36
|
+
* Separators (`-`, `.`, `_`) are preserved during omission and duplication passes.
|
|
37
|
+
* Transposition is skipped when either character is a separator.
|
|
38
|
+
* Names shorter than 3 characters return an empty set.
|
|
39
|
+
* @param name The package name to generate variants for.
|
|
40
|
+
* @returns A set of unique variant strings (never includes the original name).
|
|
41
|
+
*/
|
|
42
|
+
export declare const generateVariants: (name: string) => Set<string>;
|
|
43
|
+
/**
|
|
44
|
+
* Check a single package name against the typosquat blocklist.
|
|
45
|
+
* Returns a match if the name is a known typosquat, or `undefined` if safe.
|
|
46
|
+
*/
|
|
47
|
+
export declare const checkTyposquat: (packageName: string) => TyposquatMatch | undefined;
|
|
48
|
+
/** Check multiple package names. Returns only the matches (empty if all safe). */
|
|
49
|
+
export declare const checkTyposquats: (packageNames: string[], allowlist?: string[]) => TyposquatMatch[];
|
|
50
|
+
/**
|
|
51
|
+
* Display typosquat warnings and prompt the user.
|
|
52
|
+
*
|
|
53
|
+
* Choices:
|
|
54
|
+
* - **S** (suggested): replace the typosquat names with the correct packages and continue
|
|
55
|
+
* - **y** (yes): continue with the original (potentially dangerous) names
|
|
56
|
+
* - **N** (no, default): abort the operation
|
|
57
|
+
*
|
|
58
|
+
* Non-interactive mode always aborts.
|
|
59
|
+
*/
|
|
60
|
+
export declare const runTyposquatCheck: (packageNames: string[], allowlist?: string[]) => Promise<TyposquatCheckResult>;
|
|
61
|
+
/**
|
|
62
|
+
* Scan package.json dependencies for potential typosquats.
|
|
63
|
+
*
|
|
64
|
+
* Unlike `runTyposquatCheck` (used by `add`), this cannot replace names because
|
|
65
|
+
* they live in package.json. It warns the user and asks whether to proceed.
|
|
66
|
+
*
|
|
67
|
+
* In non-interactive mode, always aborts.
|
|
68
|
+
* @returns `true` to proceed, `false` to abort.
|
|
69
|
+
*/
|
|
70
|
+
export declare const scanDepsForTyposquats: (cwd: string, allowlist?: string[]) => Promise<boolean>;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Background upgrade check - non-intrusive update notification.
|
|
3
|
+
*
|
|
4
|
+
* Per vite-plus upgrade-check RFC:
|
|
5
|
+
* - Spawns async registry check while command runs (no latency impact)
|
|
6
|
+
* - Shows single-line notice at most once per 24 hours
|
|
7
|
+
* - Cached at ~/.vis/.upgrade-check.json
|
|
8
|
+
* - Skipped in CI, test, quiet, non-TTY, and excluded commands
|
|
9
|
+
* - 500ms timeout prevents network from delaying exit
|
|
10
|
+
*/
|
|
11
|
+
/** Commands that should NOT trigger upgrade checks. */
|
|
12
|
+
declare const EXCLUDED_COMMANDS: Set<string>;
|
|
13
|
+
/**
|
|
14
|
+
* Compares two semver version strings.
|
|
15
|
+
* Returns true if `latest` is newer than `current`.
|
|
16
|
+
*/
|
|
17
|
+
declare const isNewerVersion: (current: string, latest: string) => boolean;
|
|
18
|
+
/**
|
|
19
|
+
* Determines if the upgrade check should run for this invocation.
|
|
20
|
+
*/
|
|
21
|
+
declare const shouldCheck: (command: string) => boolean;
|
|
22
|
+
/**
|
|
23
|
+
* Runs the background upgrade check. Non-blocking.
|
|
24
|
+
*
|
|
25
|
+
* 1. Check if we need to query the registry (24h cooldown)
|
|
26
|
+
* 2. If yes, fetch latest version asynchronously
|
|
27
|
+
* 3. Return a promise that resolves with the check function to call after command
|
|
28
|
+
*/
|
|
29
|
+
declare const startUpgradeCheck: (currentVersion: string, command: string) => (() => void) | undefined;
|
|
30
|
+
export { EXCLUDED_COMMANDS, isNewerVersion, shouldCheck, startUpgradeCheck };
|
package/dist/utils.d.ts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared utility for option parsing across command handlers.
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Converts a CLI option value (which may be undefined, a single string,
|
|
6
|
+
* or an array of strings) into a normalized string array.
|
|
7
|
+
*/
|
|
8
|
+
declare const toStringArray: (value: unknown) => string[];
|
|
9
|
+
/**
|
|
10
|
+
* Safely extracts an error message from an unknown caught value.
|
|
11
|
+
* Handles Error instances, strings, and other types.
|
|
12
|
+
*/
|
|
13
|
+
declare const errorMessage: (error: unknown) => string;
|
|
14
|
+
/**
|
|
15
|
+
* Extracts the package name and optional version specifier from a CLI argument
|
|
16
|
+
* like "react", "react@19", "@scope/pkg@^2".
|
|
17
|
+
*/
|
|
18
|
+
declare const parsePackageArgument: (argument: string) => {
|
|
19
|
+
name: string;
|
|
20
|
+
versionSpec: string | undefined;
|
|
21
|
+
};
|
|
22
|
+
export { errorMessage, parsePackageArgument, toStringArray };
|