sovr-patch 0.2.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.
Potentially problematic release.
This version of sovr-patch might be problematic. Click here for more details.
- package/LICENSE +66 -0
- package/README.md +112 -0
- package/dist/audit/engine.js +140 -0
- package/dist/audit/engine.js.map +1 -0
- package/dist/audit/packs.js +21 -0
- package/dist/audit/packs.js.map +1 -0
- package/dist/audit/report.js +79 -0
- package/dist/audit/report.js.map +1 -0
- package/dist/audit/types.js +5 -0
- package/dist/audit/types.js.map +1 -0
- package/dist/cli/help.js +108 -0
- package/dist/cli/help.js.map +1 -0
- package/dist/cli/parse-argv.js +73 -0
- package/dist/cli/parse-argv.js.map +1 -0
- package/dist/commands/activate.js +179 -0
- package/dist/commands/activate.js.map +1 -0
- package/dist/commands/audit.js +89 -0
- package/dist/commands/audit.js.map +1 -0
- package/dist/commands/ci-gate.js +239 -0
- package/dist/commands/ci-gate.js.map +1 -0
- package/dist/commands/list-rules.js +11 -0
- package/dist/commands/list-rules.js.map +1 -0
- package/dist/commands/run.js +107 -0
- package/dist/commands/run.js.map +1 -0
- package/dist/commands/status.js +174 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/core/engine.js +68 -0
- package/dist/core/engine.js.map +1 -0
- package/dist/core/license.js +243 -0
- package/dist/core/license.js.map +1 -0
- package/dist/core/load-project.js +41 -0
- package/dist/core/load-project.js.map +1 -0
- package/dist/core/report.js +68 -0
- package/dist/core/report.js.map +1 -0
- package/dist/core/rollback.js +160 -0
- package/dist/core/rollback.js.map +1 -0
- package/dist/core/safe-apply.js +75 -0
- package/dist/core/safe-apply.js.map +1 -0
- package/dist/core/types.js +3 -0
- package/dist/core/types.js.map +1 -0
- package/dist/core/update-check.js +162 -0
- package/dist/core/update-check.js.map +1 -0
- package/dist/core/verify.js +32 -0
- package/dist/core/verify.js.map +1 -0
- package/dist/index.js +124 -0
- package/dist/index.js.map +1 -0
- package/dist/patch/apply.js +14 -0
- package/dist/patch/apply.js.map +1 -0
- package/dist/patch/overlap.js +12 -0
- package/dist/patch/overlap.js.map +1 -0
- package/dist/patch/preview.js +48 -0
- package/dist/patch/preview.js.map +1 -0
- package/dist/rules/design-token/classify.js +16 -0
- package/dist/rules/design-token/classify.js.map +1 -0
- package/dist/rules/design-token/locate.js +113 -0
- package/dist/rules/design-token/locate.js.map +1 -0
- package/dist/rules/design-token/presets.js +53 -0
- package/dist/rules/design-token/presets.js.map +1 -0
- package/dist/rules/design-token/rule.js +13 -0
- package/dist/rules/design-token/rule.js.map +1 -0
- package/dist/rules/design-token/schema.js +84 -0
- package/dist/rules/design-token/schema.js.map +1 -0
- package/dist/rules/design-token/transform.js +27 -0
- package/dist/rules/design-token/transform.js.map +1 -0
- package/dist/rules/field-rename/classify.js +77 -0
- package/dist/rules/field-rename/classify.js.map +1 -0
- package/dist/rules/field-rename/locate.js +294 -0
- package/dist/rules/field-rename/locate.js.map +1 -0
- package/dist/rules/field-rename/rule.js +13 -0
- package/dist/rules/field-rename/rule.js.map +1 -0
- package/dist/rules/field-rename/schema.js +35 -0
- package/dist/rules/field-rename/schema.js.map +1 -0
- package/dist/rules/field-rename/transform.js +160 -0
- package/dist/rules/field-rename/transform.js.map +1 -0
- package/dist/rules/inline-style/classify.js +17 -0
- package/dist/rules/inline-style/classify.js.map +1 -0
- package/dist/rules/inline-style/locate.js +163 -0
- package/dist/rules/inline-style/locate.js.map +1 -0
- package/dist/rules/inline-style/presets.js +71 -0
- package/dist/rules/inline-style/presets.js.map +1 -0
- package/dist/rules/inline-style/rule.js +13 -0
- package/dist/rules/inline-style/rule.js.map +1 -0
- package/dist/rules/inline-style/schema.js +97 -0
- package/dist/rules/inline-style/schema.js.map +1 -0
- package/dist/rules/inline-style/transform.js +52 -0
- package/dist/rules/inline-style/transform.js.map +1 -0
- package/dist/rules/nullish-fallback/classify.js +22 -0
- package/dist/rules/nullish-fallback/classify.js.map +1 -0
- package/dist/rules/nullish-fallback/locate.js +175 -0
- package/dist/rules/nullish-fallback/locate.js.map +1 -0
- package/dist/rules/nullish-fallback/rule.js +13 -0
- package/dist/rules/nullish-fallback/rule.js.map +1 -0
- package/dist/rules/nullish-fallback/schema.js +10 -0
- package/dist/rules/nullish-fallback/schema.js.map +1 -0
- package/dist/rules/nullish-fallback/transform.js +49 -0
- package/dist/rules/nullish-fallback/transform.js.map +1 -0
- package/dist/rules/registry.js +21 -0
- package/dist/rules/registry.js.map +1 -0
- package/dist/rules/types.js +2 -0
- package/dist/rules/types.js.map +1 -0
- package/license.json +13 -0
- package/package.json +64 -0
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import { execSync } from "node:child_process";
|
|
2
|
+
import fs from "node:fs";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
/**
|
|
5
|
+
* Create a rollback checkpoint before applying patches.
|
|
6
|
+
*
|
|
7
|
+
* Strategy 1 (git-stash): If the repo is a git repo with no uncommitted changes,
|
|
8
|
+
* we use `git stash push` to save the current state. This is the cleanest approach.
|
|
9
|
+
*
|
|
10
|
+
* Strategy 2 (backup-dir): If git is not available or there are uncommitted changes,
|
|
11
|
+
* we copy the affected files to a .sovr-patch-backup/ directory.
|
|
12
|
+
*/
|
|
13
|
+
export function createRollbackCheckpoint(repoPath, changedFiles) {
|
|
14
|
+
const timestamp = new Date().toISOString().replace(/[:.]/g, "-");
|
|
15
|
+
// Try git-stash first
|
|
16
|
+
if (isGitRepo(repoPath)) {
|
|
17
|
+
try {
|
|
18
|
+
const stashMessage = `sovr-patch-checkpoint-${timestamp}`;
|
|
19
|
+
// Stage the files that will be changed
|
|
20
|
+
for (const file of changedFiles) {
|
|
21
|
+
const absPath = path.resolve(repoPath, file);
|
|
22
|
+
if (fs.existsSync(absPath)) {
|
|
23
|
+
execSync(`git add "${file}"`, { cwd: repoPath, stdio: "pipe" });
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
// Create a stash entry
|
|
27
|
+
const result = execSync(`git stash push -m "${stashMessage}" -- ${changedFiles.map(f => `"${f}"`).join(" ")}`, { cwd: repoPath, stdio: "pipe", encoding: "utf8" });
|
|
28
|
+
// Check if stash was actually created
|
|
29
|
+
if (!result.includes("No local changes")) {
|
|
30
|
+
// Immediately pop the stash to restore working state
|
|
31
|
+
// The stash ref is kept for rollback
|
|
32
|
+
execSync("git stash pop", { cwd: repoPath, stdio: "pipe" });
|
|
33
|
+
return {
|
|
34
|
+
strategy: "git-stash",
|
|
35
|
+
repoPath,
|
|
36
|
+
stashRef: stashMessage,
|
|
37
|
+
changedFiles,
|
|
38
|
+
timestamp,
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
// Fall through to backup-dir strategy
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
// Fallback: backup-dir
|
|
47
|
+
const backupDir = path.join(repoPath, ".sovr-patch-backup", timestamp);
|
|
48
|
+
fs.mkdirSync(backupDir, { recursive: true });
|
|
49
|
+
for (const file of changedFiles) {
|
|
50
|
+
const srcPath = path.resolve(repoPath, file);
|
|
51
|
+
const destPath = path.join(backupDir, file);
|
|
52
|
+
if (fs.existsSync(srcPath)) {
|
|
53
|
+
fs.mkdirSync(path.dirname(destPath), { recursive: true });
|
|
54
|
+
fs.copyFileSync(srcPath, destPath);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
// Write metadata
|
|
58
|
+
const meta = {
|
|
59
|
+
timestamp,
|
|
60
|
+
changedFiles,
|
|
61
|
+
strategy: "backup-dir",
|
|
62
|
+
};
|
|
63
|
+
fs.writeFileSync(path.join(backupDir, ".sovr-meta.json"), JSON.stringify(meta, null, 2), "utf8");
|
|
64
|
+
return {
|
|
65
|
+
strategy: "backup-dir",
|
|
66
|
+
repoPath,
|
|
67
|
+
backupDir,
|
|
68
|
+
changedFiles,
|
|
69
|
+
timestamp,
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Rollback changes using the handle from createRollbackCheckpoint.
|
|
74
|
+
*/
|
|
75
|
+
export function rollback(handle) {
|
|
76
|
+
if (handle.strategy === "backup-dir" && handle.backupDir) {
|
|
77
|
+
if (!fs.existsSync(handle.backupDir)) {
|
|
78
|
+
return { restored: false, message: `Backup directory not found: ${handle.backupDir}` };
|
|
79
|
+
}
|
|
80
|
+
let restoredCount = 0;
|
|
81
|
+
for (const file of handle.changedFiles) {
|
|
82
|
+
const backupPath = path.join(handle.backupDir, file);
|
|
83
|
+
const targetPath = path.resolve(handle.repoPath, file);
|
|
84
|
+
if (fs.existsSync(backupPath)) {
|
|
85
|
+
fs.copyFileSync(backupPath, targetPath);
|
|
86
|
+
restoredCount += 1;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
return {
|
|
90
|
+
restored: true,
|
|
91
|
+
message: `Restored ${restoredCount} files from backup: ${handle.backupDir}`,
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
if (handle.strategy === "git-stash") {
|
|
95
|
+
try {
|
|
96
|
+
// For git-stash strategy, we use git checkout to restore the original files
|
|
97
|
+
for (const file of handle.changedFiles) {
|
|
98
|
+
execSync(`git checkout HEAD -- "${file}"`, {
|
|
99
|
+
cwd: handle.repoPath,
|
|
100
|
+
stdio: "pipe",
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
return {
|
|
104
|
+
restored: true,
|
|
105
|
+
message: `Restored ${handle.changedFiles.length} files via git checkout`,
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
catch (err) {
|
|
109
|
+
return {
|
|
110
|
+
restored: false,
|
|
111
|
+
message: `Git rollback failed: ${err instanceof Error ? err.message : String(err)}`,
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
return { restored: false, message: "Unknown rollback strategy" };
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* List all available backup checkpoints in a repo.
|
|
119
|
+
*/
|
|
120
|
+
export function listCheckpoints(repoPath) {
|
|
121
|
+
const backupRoot = path.join(repoPath, ".sovr-patch-backup");
|
|
122
|
+
if (!fs.existsSync(backupRoot)) {
|
|
123
|
+
return [];
|
|
124
|
+
}
|
|
125
|
+
const handles = [];
|
|
126
|
+
for (const entry of fs.readdirSync(backupRoot, { withFileTypes: true })) {
|
|
127
|
+
if (!entry.isDirectory())
|
|
128
|
+
continue;
|
|
129
|
+
const metaPath = path.join(backupRoot, entry.name, ".sovr-meta.json");
|
|
130
|
+
if (!fs.existsSync(metaPath))
|
|
131
|
+
continue;
|
|
132
|
+
try {
|
|
133
|
+
const meta = JSON.parse(fs.readFileSync(metaPath, "utf8"));
|
|
134
|
+
handles.push({
|
|
135
|
+
strategy: "backup-dir",
|
|
136
|
+
repoPath,
|
|
137
|
+
backupDir: path.join(backupRoot, entry.name),
|
|
138
|
+
changedFiles: meta.changedFiles ?? [],
|
|
139
|
+
timestamp: meta.timestamp ?? entry.name,
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
catch {
|
|
143
|
+
// Skip malformed metadata
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
return handles.sort((a, b) => b.timestamp.localeCompare(a.timestamp));
|
|
147
|
+
}
|
|
148
|
+
function isGitRepo(repoPath) {
|
|
149
|
+
try {
|
|
150
|
+
execSync("git rev-parse --is-inside-work-tree", {
|
|
151
|
+
cwd: repoPath,
|
|
152
|
+
stdio: "pipe",
|
|
153
|
+
});
|
|
154
|
+
return true;
|
|
155
|
+
}
|
|
156
|
+
catch {
|
|
157
|
+
return false;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
//# sourceMappingURL=rollback.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rollback.js","sourceRoot":"","sources":["../../src/core/rollback.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import os from "node:os";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { previewPatchedFiles, buildDiffFromPreview } from "../patch/preview.js";
|
|
5
|
+
import { writePreviewToRepo } from "../patch/apply.js";
|
|
6
|
+
import { verifyRepoWithTsc } from "./verify.js";
|
|
7
|
+
function copyDirRecursive(src, dest) {
|
|
8
|
+
fs.mkdirSync(dest, { recursive: true });
|
|
9
|
+
for (const entry of fs.readdirSync(src, { withFileTypes: true })) {
|
|
10
|
+
const srcPath = path.join(src, entry.name);
|
|
11
|
+
const destPath = path.join(dest, entry.name);
|
|
12
|
+
if (entry.isDirectory()) {
|
|
13
|
+
if (entry.name === ".git")
|
|
14
|
+
continue;
|
|
15
|
+
if (entry.name === "node_modules")
|
|
16
|
+
continue;
|
|
17
|
+
copyDirRecursive(srcPath, destPath);
|
|
18
|
+
continue;
|
|
19
|
+
}
|
|
20
|
+
fs.copyFileSync(srcPath, destPath);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
function writePreviewToTempRepo(tempRepoPath, previewMap) {
|
|
24
|
+
for (const [relativeFilePath, preview] of previewMap.entries()) {
|
|
25
|
+
if (preview.before === preview.after)
|
|
26
|
+
continue;
|
|
27
|
+
const absoluteFilePath = path.resolve(tempRepoPath, relativeFilePath);
|
|
28
|
+
fs.mkdirSync(path.dirname(absoluteFilePath), { recursive: true });
|
|
29
|
+
fs.writeFileSync(absoluteFilePath, preview.after, "utf8");
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
export function safeApplyWithVerify(loaded, patches) {
|
|
33
|
+
const previewMap = previewPatchedFiles(loaded, patches);
|
|
34
|
+
const summary = buildDiffFromPreview(previewMap);
|
|
35
|
+
const tempRoot = fs.mkdtempSync(path.join(os.tmpdir(), "sovr-patch-"));
|
|
36
|
+
const tempRepoPath = path.join(tempRoot, "repo");
|
|
37
|
+
copyDirRecursive(loaded.repoPath, tempRepoPath);
|
|
38
|
+
// Symlink node_modules into temp repo so tsc can resolve all types
|
|
39
|
+
const realNodeModules = path.resolve(loaded.repoPath, "node_modules");
|
|
40
|
+
const tempNodeModules = path.join(tempRepoPath, "node_modules");
|
|
41
|
+
if (fs.existsSync(realNodeModules)) {
|
|
42
|
+
fs.symlinkSync(realNodeModules, tempNodeModules, "dir");
|
|
43
|
+
}
|
|
44
|
+
const relativeTsconfig = path.relative(loaded.repoPath, loaded.tsconfigPath);
|
|
45
|
+
const tempTsconfigPath = path.resolve(tempRepoPath, relativeTsconfig);
|
|
46
|
+
writePreviewToTempRepo(tempRepoPath, previewMap);
|
|
47
|
+
/**
|
|
48
|
+
* Key design:
|
|
49
|
+
* tsc binary comes from temp repo's symlinked node_modules/.bin/tsc,
|
|
50
|
+
* tsconfig points to temp directory.
|
|
51
|
+
* node_modules shared via symlink, not copied.
|
|
52
|
+
*/
|
|
53
|
+
const verify = verifyRepoWithTsc({
|
|
54
|
+
repoPath: tempRepoPath,
|
|
55
|
+
tsconfigPath: tempTsconfigPath,
|
|
56
|
+
});
|
|
57
|
+
if (!verify.passed) {
|
|
58
|
+
return {
|
|
59
|
+
applied: false,
|
|
60
|
+
changedFiles: summary.changedFiles,
|
|
61
|
+
diffText: summary.diffText,
|
|
62
|
+
verify,
|
|
63
|
+
tempRepoPath,
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
const changedFiles = writePreviewToRepo(loaded, previewMap);
|
|
67
|
+
return {
|
|
68
|
+
applied: true,
|
|
69
|
+
changedFiles,
|
|
70
|
+
diffText: summary.diffText,
|
|
71
|
+
verify,
|
|
72
|
+
tempRepoPath,
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=safe-apply.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"safe-apply.js","sourceRoot":"","sources":["../../src/core/safe-apply.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/core/types.ts"],"names":[],"mappings":"AAAA,kEAAkE"}
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SOVR Patch — Auto-Update Check
|
|
3
|
+
*
|
|
4
|
+
* Checks npm registry for newer versions and prompts the user.
|
|
5
|
+
* Non-blocking: runs after command execution, cached for 24h.
|
|
6
|
+
* No telemetry. No data sent. Just a GET to registry.npmjs.org.
|
|
7
|
+
*
|
|
8
|
+
* Disable: set SOVR_NO_UPDATE_CHECK=1
|
|
9
|
+
* Cache: ~/.sovr-patch/.update-check
|
|
10
|
+
*/
|
|
11
|
+
import fs from "node:fs";
|
|
12
|
+
import path from "node:path";
|
|
13
|
+
import os from "node:os";
|
|
14
|
+
import https from "node:https";
|
|
15
|
+
// ─── Config ────────────────────────────────────────────────────
|
|
16
|
+
const PACKAGE_NAME = "sovr-patch";
|
|
17
|
+
const CHECK_INTERVAL_MS = 24 * 60 * 60 * 1000; // 24 hours
|
|
18
|
+
const REQUEST_TIMEOUT_MS = 3000; // 3 seconds — never block the user
|
|
19
|
+
// ─── Paths ─────────────────────────────────────────────────────
|
|
20
|
+
function getCachePath() {
|
|
21
|
+
return path.join(os.homedir(), ".sovr-patch", ".update-check");
|
|
22
|
+
}
|
|
23
|
+
function getCurrentVersion() {
|
|
24
|
+
// Read from package.json at build time — this gets inlined by esbuild
|
|
25
|
+
// Fallback: read from the installed package
|
|
26
|
+
try {
|
|
27
|
+
const pkgPath = path.resolve(__dirname, "..", "package.json");
|
|
28
|
+
if (fs.existsSync(pkgPath)) {
|
|
29
|
+
const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf-8"));
|
|
30
|
+
return pkg.version ?? "0.0.0";
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
// ignore
|
|
35
|
+
}
|
|
36
|
+
// Fallback: try reading from the source root
|
|
37
|
+
try {
|
|
38
|
+
const srcPkgPath = path.resolve(__dirname, "..", "..", "package.json");
|
|
39
|
+
if (fs.existsSync(srcPkgPath)) {
|
|
40
|
+
const pkg = JSON.parse(fs.readFileSync(srcPkgPath, "utf-8"));
|
|
41
|
+
return pkg.version ?? "0.0.0";
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
// ignore
|
|
46
|
+
}
|
|
47
|
+
return "0.0.0";
|
|
48
|
+
}
|
|
49
|
+
// ─── Semver comparison (simple: major.minor.patch) ─────────────
|
|
50
|
+
function isNewer(latest, current) {
|
|
51
|
+
const parse = (v) => v.replace(/^v/, "").split(".").map(Number);
|
|
52
|
+
const [lMaj, lMin, lPat] = parse(latest);
|
|
53
|
+
const [cMaj, cMin, cPat] = parse(current);
|
|
54
|
+
if (lMaj !== cMaj)
|
|
55
|
+
return lMaj > cMaj;
|
|
56
|
+
if (lMin !== cMin)
|
|
57
|
+
return lMin > cMin;
|
|
58
|
+
return lPat > cPat;
|
|
59
|
+
}
|
|
60
|
+
// ─── Read/write cache ──────────────────────────────────────────
|
|
61
|
+
function readCache() {
|
|
62
|
+
try {
|
|
63
|
+
const cachePath = getCachePath();
|
|
64
|
+
if (!fs.existsSync(cachePath))
|
|
65
|
+
return null;
|
|
66
|
+
const raw = fs.readFileSync(cachePath, "utf-8");
|
|
67
|
+
return JSON.parse(raw);
|
|
68
|
+
}
|
|
69
|
+
catch {
|
|
70
|
+
return null;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
function writeCache(cache) {
|
|
74
|
+
try {
|
|
75
|
+
const cachePath = getCachePath();
|
|
76
|
+
const dir = path.dirname(cachePath);
|
|
77
|
+
if (!fs.existsSync(dir)) {
|
|
78
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
79
|
+
}
|
|
80
|
+
fs.writeFileSync(cachePath, JSON.stringify(cache), "utf-8");
|
|
81
|
+
}
|
|
82
|
+
catch {
|
|
83
|
+
// Non-critical — silently ignore
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
// ─── Fetch latest version from npm ─────────────────────────────
|
|
87
|
+
function fetchLatestVersion() {
|
|
88
|
+
return new Promise((resolve) => {
|
|
89
|
+
const req = https.get(`https://registry.npmjs.org/${PACKAGE_NAME}/latest`, { timeout: REQUEST_TIMEOUT_MS }, (res) => {
|
|
90
|
+
if (res.statusCode !== 200) {
|
|
91
|
+
resolve(null);
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
let data = "";
|
|
95
|
+
res.on("data", (chunk) => {
|
|
96
|
+
data += chunk.toString();
|
|
97
|
+
});
|
|
98
|
+
res.on("end", () => {
|
|
99
|
+
try {
|
|
100
|
+
const parsed = JSON.parse(data);
|
|
101
|
+
resolve(parsed.version ?? null);
|
|
102
|
+
}
|
|
103
|
+
catch {
|
|
104
|
+
resolve(null);
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
});
|
|
108
|
+
req.on("error", () => resolve(null));
|
|
109
|
+
req.on("timeout", () => {
|
|
110
|
+
req.destroy();
|
|
111
|
+
resolve(null);
|
|
112
|
+
});
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
// ─── Main: check for updates (non-blocking) ────────────────────
|
|
116
|
+
export async function checkForUpdates() {
|
|
117
|
+
// Respect opt-out
|
|
118
|
+
if (process.env.SOVR_NO_UPDATE_CHECK === "1")
|
|
119
|
+
return;
|
|
120
|
+
const currentVersion = getCurrentVersion();
|
|
121
|
+
if (currentVersion === "0.0.0")
|
|
122
|
+
return; // dev mode, skip
|
|
123
|
+
// Check cache — only hit npm once per 24h
|
|
124
|
+
const cache = readCache();
|
|
125
|
+
if (cache && Date.now() - cache.lastCheck < CHECK_INTERVAL_MS) {
|
|
126
|
+
// Use cached result
|
|
127
|
+
if (isNewer(cache.latestVersion, currentVersion)) {
|
|
128
|
+
printUpdateNotice(currentVersion, cache.latestVersion);
|
|
129
|
+
}
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
// Fetch from npm (async, non-blocking)
|
|
133
|
+
const latestVersion = await fetchLatestVersion();
|
|
134
|
+
if (!latestVersion)
|
|
135
|
+
return; // Network error — silently skip
|
|
136
|
+
// Update cache
|
|
137
|
+
writeCache({ lastCheck: Date.now(), latestVersion });
|
|
138
|
+
// Compare
|
|
139
|
+
if (isNewer(latestVersion, currentVersion)) {
|
|
140
|
+
printUpdateNotice(currentVersion, latestVersion);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
// ─── Print the update notice ───────────────────────────────────
|
|
144
|
+
function printUpdateNotice(current, latest) {
|
|
145
|
+
const border = "─".repeat(52);
|
|
146
|
+
console.log("");
|
|
147
|
+
console.log(` \x1b[33m╭${border}╮\x1b[0m`);
|
|
148
|
+
console.log(` \x1b[33m│\x1b[0m \x1b[33m│\x1b[0m`);
|
|
149
|
+
console.log(` \x1b[33m│\x1b[0m Update available: \x1b[31m${current}\x1b[0m → \x1b[32m${latest}\x1b[0m${" ".repeat(Math.max(0, 24 - current.length - latest.length))}\x1b[33m│\x1b[0m`);
|
|
150
|
+
console.log(` \x1b[33m│\x1b[0m \x1b[33m│\x1b[0m`);
|
|
151
|
+
console.log(` \x1b[33m│\x1b[0m Run: \x1b[36mnpm install -g sovr-patch\x1b[0m \x1b[33m│\x1b[0m`);
|
|
152
|
+
console.log(` \x1b[33m│\x1b[0m Or: \x1b[36mnpx sovr-patch@latest\x1b[0m \x1b[33m│\x1b[0m`);
|
|
153
|
+
console.log(` \x1b[33m│\x1b[0m \x1b[33m│\x1b[0m`);
|
|
154
|
+
console.log(` \x1b[33m│\x1b[0m Changelog: \x1b[4mhttps://sovr.app/patch/changelog\x1b[0m \x1b[33m│\x1b[0m`);
|
|
155
|
+
console.log(` \x1b[33m│\x1b[0m Disable: SOVR_NO_UPDATE_CHECK=1 \x1b[33m│\x1b[0m`);
|
|
156
|
+
console.log(` \x1b[33m│\x1b[0m \x1b[33m│\x1b[0m`);
|
|
157
|
+
console.log(` \x1b[33m╰${border}╯\x1b[0m`);
|
|
158
|
+
console.log("");
|
|
159
|
+
}
|
|
160
|
+
// ─── Export for testing ────────────────────────────────────────
|
|
161
|
+
export { getCurrentVersion, isNewer, fetchLatestVersion };
|
|
162
|
+
//# sourceMappingURL=update-check.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"update-check.js","sourceRoot":"","sources":["../../src/core/update-check.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import { spawnSync } from "node:child_process";
|
|
3
|
+
function resolveTscBin(repoPath) {
|
|
4
|
+
if (process.platform === "win32") {
|
|
5
|
+
return path.resolve(repoPath, "node_modules", ".bin", "tsc.cmd");
|
|
6
|
+
}
|
|
7
|
+
return path.resolve(repoPath, "node_modules", ".bin", "tsc");
|
|
8
|
+
}
|
|
9
|
+
export function verifyRepoWithTsc(params) {
|
|
10
|
+
const localTsc = resolveTscBin(params.repoPath);
|
|
11
|
+
const bin = localTsc;
|
|
12
|
+
const args = ["--noEmit", "-p", params.tsconfigPath];
|
|
13
|
+
const result = spawnSync(bin, args, {
|
|
14
|
+
cwd: params.repoPath,
|
|
15
|
+
encoding: "utf8",
|
|
16
|
+
shell: false,
|
|
17
|
+
});
|
|
18
|
+
return {
|
|
19
|
+
passed: result.status === 0,
|
|
20
|
+
exitCode: result.status ?? 1,
|
|
21
|
+
stdout: result.stdout ?? "",
|
|
22
|
+
stderr: result.stderr ?? "",
|
|
23
|
+
command: [bin, ...args].join(" "),
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
export function verifyWithTsc(loaded) {
|
|
27
|
+
return verifyRepoWithTsc({
|
|
28
|
+
repoPath: loaded.repoPath,
|
|
29
|
+
tsconfigPath: loaded.tsconfigPath,
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=verify.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verify.js","sourceRoot":"","sources":["../../src/core/verify.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAG/C,SAAS,aAAa,CAAC,QAAgB;IACrC,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;QACjC,OAAO,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,cAAc,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC;IACnE,CAAC;IAED,OAAO,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,cAAc,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC;AAC/D,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,MAGjC;IACC,MAAM,QAAQ,GAAG,aAAa,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IAChD,MAAM,GAAG,GAAG,QAAQ,CAAC;IACrB,MAAM,IAAI,GAAG,CAAC,UAAU,EAAE,IAAI,EAAE,MAAM,CAAC,YAAY,CAAC,CAAC;IAErD,MAAM,MAAM,GAAG,SAAS,CAAC,GAAG,EAAE,IAAI,EAAE;QAClC,GAAG,EAAE,MAAM,CAAC,QAAQ;QACpB,QAAQ,EAAE,MAAM;QAChB,KAAK,EAAE,KAAK;KACb,CAAC,CAAC;IAEH,OAAO;QACL,MAAM,EAAE,MAAM,CAAC,MAAM,KAAK,CAAC;QAC3B,QAAQ,EAAE,MAAM,CAAC,MAAM,IAAI,CAAC;QAC5B,MAAM,EAAE,MAAM,CAAC,MAAM,IAAI,EAAE;QAC3B,MAAM,EAAE,MAAM,CAAC,MAAM,IAAI,EAAE;QAC3B,OAAO,EAAE,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;KAClC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,MAAqB;IACjD,OAAO,iBAAiB,CAAC;QACvB,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,YAAY,EAAE,MAAM,CAAC,YAAY;KAClC,CAAC,CAAC;AACL,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import process from "node:process";
|
|
4
|
+
import { parseCli } from "./cli/parse-argv.js";
|
|
5
|
+
import { printHelp } from "./cli/help.js";
|
|
6
|
+
import { runCommand } from "./commands/run.js";
|
|
7
|
+
import { listRulesCommand } from "./commands/list-rules.js";
|
|
8
|
+
import { ciGateCommand } from "./commands/ci-gate.js";
|
|
9
|
+
import { activateCommand } from "./commands/activate.js";
|
|
10
|
+
import { auditCommand } from "./commands/audit.js";
|
|
11
|
+
import { statusCommand } from "./commands/status.js";
|
|
12
|
+
import { checkForUpdates } from "./core/update-check.js";
|
|
13
|
+
import { listCheckpoints, rollback as executeRollback, } from "./core/rollback.js";
|
|
14
|
+
// ─── Legacy rollback command (kept for backward compat) ─────────
|
|
15
|
+
function runRollback(argv) {
|
|
16
|
+
const repoArg = argv.indexOf("--repo");
|
|
17
|
+
const repoPath = path.resolve(repoArg !== -1 ? (argv[repoArg + 1] ?? ".") : ".");
|
|
18
|
+
const list = argv.includes("--list");
|
|
19
|
+
const json = argv.includes("--json");
|
|
20
|
+
const cpArg = argv.indexOf("--checkpoint");
|
|
21
|
+
const checkpoint = cpArg !== -1 ? argv[cpArg + 1] : undefined;
|
|
22
|
+
if (list) {
|
|
23
|
+
const checkpoints = listCheckpoints(repoPath);
|
|
24
|
+
if (json) {
|
|
25
|
+
console.log(JSON.stringify(checkpoints, null, 2));
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
if (checkpoints.length === 0) {
|
|
29
|
+
console.log("No rollback checkpoints found.");
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
console.log(`Found ${checkpoints.length} checkpoint(s):`);
|
|
33
|
+
console.log("");
|
|
34
|
+
for (const cp of checkpoints) {
|
|
35
|
+
console.log(` ${cp.timestamp} (${cp.strategy}) ${cp.changedFiles.length} files`);
|
|
36
|
+
for (const f of cp.changedFiles) {
|
|
37
|
+
console.log(` - ${f}`);
|
|
38
|
+
}
|
|
39
|
+
console.log("");
|
|
40
|
+
}
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
if (checkpoint) {
|
|
44
|
+
const checkpoints = listCheckpoints(repoPath);
|
|
45
|
+
const target = checkpoints.find((cp) => cp.timestamp === checkpoint);
|
|
46
|
+
if (!target) {
|
|
47
|
+
console.error(`Checkpoint not found: ${checkpoint}`);
|
|
48
|
+
console.error(`Use --list to see available checkpoints.`);
|
|
49
|
+
process.exit(1);
|
|
50
|
+
}
|
|
51
|
+
const result = executeRollback(target);
|
|
52
|
+
if (json) {
|
|
53
|
+
console.log(JSON.stringify(result, null, 2));
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
if (result.restored) {
|
|
57
|
+
console.log(`Rollback successful: ${result.message}`);
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
console.error(`Rollback failed: ${result.message}`);
|
|
61
|
+
process.exit(1);
|
|
62
|
+
}
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
console.error("rollback requires --list or --checkpoint <timestamp>");
|
|
66
|
+
process.exit(1);
|
|
67
|
+
}
|
|
68
|
+
// ─── Main ───────────────────────────────────────────────────────
|
|
69
|
+
async function main() {
|
|
70
|
+
const argv = process.argv;
|
|
71
|
+
// Show help if no args or --help
|
|
72
|
+
if (argv.length <= 2 || argv.includes("--help") || argv.includes("-h")) {
|
|
73
|
+
printHelp();
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
const command = argv[2];
|
|
77
|
+
// Handle activate command
|
|
78
|
+
if (command === "activate") {
|
|
79
|
+
await activateCommand(argv);
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
// Handle status command
|
|
83
|
+
if (command === "status") {
|
|
84
|
+
statusCommand(argv);
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
// Handle audit command
|
|
88
|
+
if (command === "audit") {
|
|
89
|
+
await auditCommand(argv);
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
// Handle ci-gate command (Enterprise)
|
|
93
|
+
if (command === "ci-gate") {
|
|
94
|
+
await ciGateCommand(argv);
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
// Handle rollback separately (legacy)
|
|
98
|
+
if (command === "rollback") {
|
|
99
|
+
runRollback(argv);
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
try {
|
|
103
|
+
const args = parseCli(argv);
|
|
104
|
+
if (args.command === "list-rules") {
|
|
105
|
+
listRulesCommand();
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
if (args.command === "scan" || args.command === "run") {
|
|
109
|
+
await runCommand(args);
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
throw new Error(`unsupported command: "${args.command}". Use --help for usage.`);
|
|
113
|
+
}
|
|
114
|
+
catch (error) {
|
|
115
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
116
|
+
console.error(`Error: ${message}`);
|
|
117
|
+
process.exit(1);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
main().finally(() => {
|
|
121
|
+
// Non-blocking update check — runs after command completes
|
|
122
|
+
checkForUpdates().catch(() => { });
|
|
123
|
+
});
|
|
124
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
export function writePreviewToRepo(loaded, previewMap) {
|
|
4
|
+
const changedFiles = [];
|
|
5
|
+
for (const [filePath, preview] of previewMap.entries()) {
|
|
6
|
+
if (preview.before === preview.after)
|
|
7
|
+
continue;
|
|
8
|
+
const absolute = path.resolve(loaded.repoPath, filePath);
|
|
9
|
+
fs.writeFileSync(absolute, preview.after, "utf8");
|
|
10
|
+
changedFiles.push(filePath);
|
|
11
|
+
}
|
|
12
|
+
return changedFiles;
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=apply.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"apply.js","sourceRoot":"","sources":["../../src/patch/apply.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAG7B,MAAM,UAAU,kBAAkB,CAChC,MAAqB,EACrB,UAAoC;IAEpC,MAAM,YAAY,GAAa,EAAE,CAAC;IAElC,KAAK,MAAM,CAAC,QAAQ,EAAE,OAAO,CAAC,IAAI,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC;QACvD,IAAI,OAAO,CAAC,MAAM,KAAK,OAAO,CAAC,KAAK;YAAE,SAAS;QAE/C,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;QACzD,EAAE,CAAC,aAAa,CAAC,QAAQ,EAAE,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;QAClD,YAAY,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC9B,CAAC;IAED,OAAO,YAAY,CAAC;AACtB,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export function detectOverlaps(patches) {
|
|
2
|
+
const sorted = [...patches].sort((a, b) => a.start - b.start);
|
|
3
|
+
for (let i = 1; i < sorted.length; i += 1) {
|
|
4
|
+
const prev = sorted[i - 1];
|
|
5
|
+
const current = sorted[i];
|
|
6
|
+
if (current.start < prev.end) {
|
|
7
|
+
throw new Error(`overlapping patches detected in ${current.filePath}: ` +
|
|
8
|
+
`[${prev.start}, ${prev.end}) overlaps with [${current.start}, ${current.end})`);
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=overlap.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"overlap.js","sourceRoot":"","sources":["../../src/patch/overlap.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,cAAc,CAAC,OAAkB;IAC/C,MAAM,MAAM,GAAG,CAAC,GAAG,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC;IAE9D,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QAC1C,MAAM,IAAI,GAAG,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QAC3B,MAAM,OAAO,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;QAE1B,IAAI,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YAC7B,MAAM,IAAI,KAAK,CACb,mCAAmC,OAAO,CAAC,QAAQ,IAAI;gBACrD,IAAI,IAAI,CAAC,KAAK,KAAK,IAAI,CAAC,GAAG,oBAAoB,OAAO,CAAC,KAAK,KAAK,OAAO,CAAC,GAAG,GAAG,CAClF,CAAC;QACJ,CAAC;IACH,CAAC;AACH,CAAC"}
|