shell-dsl 0.0.32 → 0.0.34
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/README.md +130 -0
- package/dist/cjs/package.json +1 -1
- package/dist/cjs/src/index.cjs +3 -1
- package/dist/cjs/src/index.cjs.map +3 -3
- package/dist/cjs/src/vcs/diff.cjs +107 -0
- package/dist/cjs/src/vcs/diff.cjs.map +10 -0
- package/dist/cjs/src/vcs/index.cjs +47 -0
- package/dist/cjs/src/vcs/index.cjs.map +10 -0
- package/dist/cjs/src/vcs/match.cjs +106 -0
- package/dist/cjs/src/vcs/match.cjs.map +10 -0
- package/dist/cjs/src/vcs/rules.cjs +180 -0
- package/dist/cjs/src/vcs/rules.cjs.map +10 -0
- package/dist/cjs/src/vcs/snapshot.cjs +228 -0
- package/dist/cjs/src/vcs/snapshot.cjs.map +10 -0
- package/dist/cjs/src/vcs/storage.cjs +120 -0
- package/dist/cjs/src/vcs/storage.cjs.map +10 -0
- package/dist/cjs/src/vcs/types.cjs +30 -0
- package/dist/cjs/src/vcs/types.cjs.map +9 -0
- package/dist/cjs/src/vcs/vcs.cjs +322 -0
- package/dist/cjs/src/vcs/vcs.cjs.map +10 -0
- package/dist/cjs/src/vcs/walk.cjs +89 -0
- package/dist/cjs/src/vcs/walk.cjs.map +10 -0
- package/dist/mjs/package.json +1 -1
- package/dist/mjs/src/index.mjs +3 -1
- package/dist/mjs/src/index.mjs.map +3 -3
- package/dist/mjs/src/vcs/diff.mjs +67 -0
- package/dist/mjs/src/vcs/diff.mjs.map +10 -0
- package/dist/mjs/src/vcs/index.mjs +7 -0
- package/dist/mjs/src/vcs/index.mjs.map +10 -0
- package/dist/mjs/src/vcs/match.mjs +66 -0
- package/dist/mjs/src/vcs/match.mjs.map +10 -0
- package/dist/mjs/src/vcs/rules.mjs +140 -0
- package/dist/mjs/src/vcs/rules.mjs.map +10 -0
- package/dist/mjs/src/vcs/snapshot.mjs +188 -0
- package/dist/mjs/src/vcs/snapshot.mjs.map +10 -0
- package/dist/mjs/src/vcs/storage.mjs +79 -0
- package/dist/mjs/src/vcs/storage.mjs.map +10 -0
- package/dist/mjs/src/vcs/types.mjs +2 -0
- package/dist/mjs/src/vcs/types.mjs.map +9 -0
- package/dist/mjs/src/vcs/vcs.mjs +282 -0
- package/dist/mjs/src/vcs/vcs.mjs.map +10 -0
- package/dist/mjs/src/vcs/walk.mjs +49 -0
- package/dist/mjs/src/vcs/walk.mjs.map +10 -0
- package/dist/types/src/index.d.ts +2 -0
- package/dist/types/src/vcs/diff.d.ts +11 -0
- package/dist/types/src/vcs/index.d.ts +2 -0
- package/dist/types/src/vcs/match.d.ts +5 -0
- package/dist/types/src/vcs/rules.d.ts +23 -0
- package/dist/types/src/vcs/snapshot.d.ts +26 -0
- package/dist/types/src/vcs/storage.d.ts +22 -0
- package/dist/types/src/vcs/types.d.ts +99 -0
- package/dist/types/src/vcs/vcs.d.ts +35 -0
- package/dist/types/src/vcs/walk.d.ts +19 -0
- package/package.json +1 -1
|
@@ -0,0 +1,322 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
|
+
function __accessProp(key) {
|
|
6
|
+
return this[key];
|
|
7
|
+
}
|
|
8
|
+
var __toCommonJS = (from) => {
|
|
9
|
+
var entry = (__moduleCache ??= new WeakMap).get(from), desc;
|
|
10
|
+
if (entry)
|
|
11
|
+
return entry;
|
|
12
|
+
entry = __defProp({}, "__esModule", { value: true });
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (var key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(entry, key))
|
|
16
|
+
__defProp(entry, key, {
|
|
17
|
+
get: __accessProp.bind(from, key),
|
|
18
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
__moduleCache.set(from, entry);
|
|
22
|
+
return entry;
|
|
23
|
+
};
|
|
24
|
+
var __moduleCache;
|
|
25
|
+
var __returnValue = (v) => v;
|
|
26
|
+
function __exportSetter(name, newValue) {
|
|
27
|
+
this[name] = __returnValue.bind(null, newValue);
|
|
28
|
+
}
|
|
29
|
+
var __export = (target, all) => {
|
|
30
|
+
for (var name in all)
|
|
31
|
+
__defProp(target, name, {
|
|
32
|
+
get: all[name],
|
|
33
|
+
enumerable: true,
|
|
34
|
+
configurable: true,
|
|
35
|
+
set: __exportSetter.bind(all, name)
|
|
36
|
+
});
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
// src/vcs/vcs.ts
|
|
40
|
+
var exports_vcs = {};
|
|
41
|
+
__export(exports_vcs, {
|
|
42
|
+
VersionControlSystem: () => VersionControlSystem
|
|
43
|
+
});
|
|
44
|
+
module.exports = __toCommonJS(exports_vcs);
|
|
45
|
+
var import_storage = require("./storage.cjs");
|
|
46
|
+
var import_diff = require("./diff.cjs");
|
|
47
|
+
var import_rules = require("./rules.cjs");
|
|
48
|
+
var import_snapshot = require("./snapshot.cjs");
|
|
49
|
+
|
|
50
|
+
class VersionControlSystem {
|
|
51
|
+
workFs;
|
|
52
|
+
workPath;
|
|
53
|
+
storage;
|
|
54
|
+
vcsInternalPath;
|
|
55
|
+
rules;
|
|
56
|
+
constructor(config) {
|
|
57
|
+
this.workFs = config.fs;
|
|
58
|
+
this.workPath = config.fs.resolve(config.path);
|
|
59
|
+
const metaFs = config.vcsPath?.fs ?? config.fs;
|
|
60
|
+
const metaPath = config.vcsPath?.path ?? metaFs.resolve(config.path, ".vcs");
|
|
61
|
+
this.storage = new import_storage.VCSStorage(metaFs, metaPath);
|
|
62
|
+
this.vcsInternalPath = resolveInternalPath(config.fs, metaFs, this.workPath, metaPath);
|
|
63
|
+
this.rules = new import_rules.VCSRules({
|
|
64
|
+
internalPath: this.vcsInternalPath,
|
|
65
|
+
ignore: config.ignore,
|
|
66
|
+
attributes: config.attributes
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
async init() {
|
|
70
|
+
if (await this.storage.isInitialized())
|
|
71
|
+
return;
|
|
72
|
+
await this.storage.initialize();
|
|
73
|
+
}
|
|
74
|
+
async ensureInit() {
|
|
75
|
+
if (!await this.storage.isInitialized()) {
|
|
76
|
+
await this.init();
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
async resolveHead() {
|
|
80
|
+
const head = await this.storage.readHead();
|
|
81
|
+
if (head.revision !== undefined) {
|
|
82
|
+
return { branch: null, revision: head.revision };
|
|
83
|
+
}
|
|
84
|
+
if (head.ref) {
|
|
85
|
+
const branchName = head.ref.replace("refs/heads/", "");
|
|
86
|
+
const branchRef = await this.storage.readBranch(branchName);
|
|
87
|
+
return { branch: branchName, revision: branchRef?.revision ?? null };
|
|
88
|
+
}
|
|
89
|
+
return { branch: null, revision: null };
|
|
90
|
+
}
|
|
91
|
+
async headManifest() {
|
|
92
|
+
const { revision } = await this.resolveHead();
|
|
93
|
+
if (revision === null)
|
|
94
|
+
return {};
|
|
95
|
+
const rev = await this.storage.readRevision(revision);
|
|
96
|
+
return rev.tree;
|
|
97
|
+
}
|
|
98
|
+
async commit(message, opts) {
|
|
99
|
+
await this.ensureInit();
|
|
100
|
+
const { branch, revision: parentId } = await this.resolveHead();
|
|
101
|
+
const parentManifest = parentId !== null ? (await this.storage.readRevision(parentId)).tree : {};
|
|
102
|
+
let newTree;
|
|
103
|
+
let changes;
|
|
104
|
+
if (opts?.paths && opts.paths.length > 0) {
|
|
105
|
+
const fullManifest = await import_snapshot.buildTreeManifest(this.workFs, this.workPath, {
|
|
106
|
+
rules: this.rules,
|
|
107
|
+
trackedPaths: Object.keys(parentManifest)
|
|
108
|
+
});
|
|
109
|
+
const matchedPaths = filterPathsByGlobs(Object.keys(fullManifest), opts.paths);
|
|
110
|
+
newTree = { ...parentManifest };
|
|
111
|
+
const parentMatchedPaths = filterPathsByGlobs(Object.keys(parentManifest), opts.paths);
|
|
112
|
+
for (const p of parentMatchedPaths) {
|
|
113
|
+
if (!fullManifest[p]) {
|
|
114
|
+
delete newTree[p];
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
for (const p of matchedPaths) {
|
|
118
|
+
newTree[p] = fullManifest[p];
|
|
119
|
+
}
|
|
120
|
+
const relevantBefore = {};
|
|
121
|
+
const relevantAfter = {};
|
|
122
|
+
const allRelevant = new Set([...matchedPaths, ...parentMatchedPaths]);
|
|
123
|
+
for (const p of allRelevant) {
|
|
124
|
+
if (parentManifest[p])
|
|
125
|
+
relevantBefore[p] = parentManifest[p];
|
|
126
|
+
if (newTree[p])
|
|
127
|
+
relevantAfter[p] = newTree[p];
|
|
128
|
+
}
|
|
129
|
+
changes = import_diff.diffManifests(relevantBefore, relevantAfter, this.rules);
|
|
130
|
+
} else {
|
|
131
|
+
newTree = await import_snapshot.buildTreeManifest(this.workFs, this.workPath, {
|
|
132
|
+
rules: this.rules,
|
|
133
|
+
trackedPaths: Object.keys(parentManifest)
|
|
134
|
+
});
|
|
135
|
+
changes = import_diff.diffManifests(parentManifest, newTree, this.rules);
|
|
136
|
+
}
|
|
137
|
+
if (changes.length === 0) {
|
|
138
|
+
throw new Error("nothing to commit");
|
|
139
|
+
}
|
|
140
|
+
const id = await this.storage.nextRevisionId();
|
|
141
|
+
const rev = {
|
|
142
|
+
id,
|
|
143
|
+
parent: parentId,
|
|
144
|
+
branch: branch ?? "detached",
|
|
145
|
+
message,
|
|
146
|
+
timestamp: new Date().toISOString(),
|
|
147
|
+
changes,
|
|
148
|
+
tree: newTree
|
|
149
|
+
};
|
|
150
|
+
await this.storage.writeRevision(rev);
|
|
151
|
+
if (branch) {
|
|
152
|
+
await this.storage.writeBranch(branch, { revision: id });
|
|
153
|
+
} else {
|
|
154
|
+
await this.storage.writeHead({ revision: id });
|
|
155
|
+
}
|
|
156
|
+
return rev;
|
|
157
|
+
}
|
|
158
|
+
async checkout(target, opts) {
|
|
159
|
+
await this.ensureInit();
|
|
160
|
+
const isPartial = opts?.paths && opts.paths.length > 0;
|
|
161
|
+
let targetRevision;
|
|
162
|
+
let targetBranch = null;
|
|
163
|
+
if (typeof target === "string") {
|
|
164
|
+
const branchRef = await this.storage.readBranch(target);
|
|
165
|
+
if (branchRef) {
|
|
166
|
+
targetBranch = target;
|
|
167
|
+
targetRevision = branchRef.revision;
|
|
168
|
+
} else {
|
|
169
|
+
throw new Error(`unknown branch or revision: "${target}"`);
|
|
170
|
+
}
|
|
171
|
+
} else {
|
|
172
|
+
targetRevision = target;
|
|
173
|
+
}
|
|
174
|
+
let rev;
|
|
175
|
+
try {
|
|
176
|
+
rev = await this.storage.readRevision(targetRevision);
|
|
177
|
+
} catch {
|
|
178
|
+
throw new Error(`revision ${targetRevision} not found`);
|
|
179
|
+
}
|
|
180
|
+
const currentManifest = await this.headManifest();
|
|
181
|
+
if (isPartial) {
|
|
182
|
+
await import_snapshot.restoreTree(this.workFs, this.workPath, rev.tree, {
|
|
183
|
+
fullRestore: false,
|
|
184
|
+
paths: opts.paths,
|
|
185
|
+
rules: this.rules,
|
|
186
|
+
trackedPaths: Object.keys(currentManifest)
|
|
187
|
+
});
|
|
188
|
+
} else {
|
|
189
|
+
if (!opts?.force) {
|
|
190
|
+
const changes = await this.status();
|
|
191
|
+
if (changes.length > 0) {
|
|
192
|
+
throw new Error("working tree has uncommitted changes (use force to discard)");
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
await import_snapshot.restoreTree(this.workFs, this.workPath, rev.tree, {
|
|
196
|
+
fullRestore: true,
|
|
197
|
+
rules: this.rules,
|
|
198
|
+
trackedPaths: Object.keys(currentManifest)
|
|
199
|
+
});
|
|
200
|
+
if (targetBranch) {
|
|
201
|
+
await this.storage.writeHead({ ref: `refs/heads/${targetBranch}` });
|
|
202
|
+
} else {
|
|
203
|
+
await this.storage.writeHead({ revision: targetRevision });
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
async branch(name) {
|
|
208
|
+
await this.ensureInit();
|
|
209
|
+
const existing = await this.storage.readBranch(name);
|
|
210
|
+
if (existing) {
|
|
211
|
+
throw new Error(`branch "${name}" already exists`);
|
|
212
|
+
}
|
|
213
|
+
const { revision } = await this.resolveHead();
|
|
214
|
+
if (revision === null) {
|
|
215
|
+
throw new Error("cannot create branch: no commits yet");
|
|
216
|
+
}
|
|
217
|
+
await this.storage.writeBranch(name, { revision });
|
|
218
|
+
}
|
|
219
|
+
async branches() {
|
|
220
|
+
await this.ensureInit();
|
|
221
|
+
const names = await this.storage.listBranches();
|
|
222
|
+
const head = await this.resolveHead();
|
|
223
|
+
const result = [];
|
|
224
|
+
for (const name of names) {
|
|
225
|
+
const ref = await this.storage.readBranch(name);
|
|
226
|
+
if (ref) {
|
|
227
|
+
result.push({
|
|
228
|
+
name,
|
|
229
|
+
revision: ref.revision,
|
|
230
|
+
current: head.branch === name
|
|
231
|
+
});
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
return result.sort((a, b) => a.name.localeCompare(b.name));
|
|
235
|
+
}
|
|
236
|
+
async log(opts) {
|
|
237
|
+
await this.ensureInit();
|
|
238
|
+
let startRevision;
|
|
239
|
+
if (opts?.branch) {
|
|
240
|
+
const branchRef = await this.storage.readBranch(opts.branch);
|
|
241
|
+
if (!branchRef)
|
|
242
|
+
throw new Error(`branch "${opts.branch}" not found`);
|
|
243
|
+
startRevision = branchRef.revision;
|
|
244
|
+
} else {
|
|
245
|
+
const { revision } = await this.resolveHead();
|
|
246
|
+
startRevision = revision;
|
|
247
|
+
}
|
|
248
|
+
if (startRevision === null)
|
|
249
|
+
return [];
|
|
250
|
+
const entries = [];
|
|
251
|
+
let currentId = startRevision;
|
|
252
|
+
while (currentId !== null) {
|
|
253
|
+
if (opts?.limit && entries.length >= opts.limit)
|
|
254
|
+
break;
|
|
255
|
+
let rev;
|
|
256
|
+
try {
|
|
257
|
+
rev = await this.storage.readRevision(currentId);
|
|
258
|
+
} catch {
|
|
259
|
+
break;
|
|
260
|
+
}
|
|
261
|
+
const changedPaths = rev.changes.map((c) => c.path);
|
|
262
|
+
if (opts?.path) {
|
|
263
|
+
const matchesPath = changedPaths.some((p) => import_rules.matchVCSPath(opts.path, p));
|
|
264
|
+
if (matchesPath) {
|
|
265
|
+
entries.push({
|
|
266
|
+
id: rev.id,
|
|
267
|
+
parent: rev.parent,
|
|
268
|
+
branch: rev.branch,
|
|
269
|
+
message: rev.message,
|
|
270
|
+
timestamp: rev.timestamp,
|
|
271
|
+
paths: changedPaths
|
|
272
|
+
});
|
|
273
|
+
}
|
|
274
|
+
} else {
|
|
275
|
+
entries.push({
|
|
276
|
+
id: rev.id,
|
|
277
|
+
parent: rev.parent,
|
|
278
|
+
branch: rev.branch,
|
|
279
|
+
message: rev.message,
|
|
280
|
+
timestamp: rev.timestamp,
|
|
281
|
+
paths: changedPaths
|
|
282
|
+
});
|
|
283
|
+
}
|
|
284
|
+
currentId = rev.parent;
|
|
285
|
+
}
|
|
286
|
+
return entries;
|
|
287
|
+
}
|
|
288
|
+
async status() {
|
|
289
|
+
await this.ensureInit();
|
|
290
|
+
const manifest = await this.headManifest();
|
|
291
|
+
return import_diff.diffWorkingTree(this.workFs, this.workPath, manifest, this.rules);
|
|
292
|
+
}
|
|
293
|
+
async diff(revA, revB) {
|
|
294
|
+
await this.ensureInit();
|
|
295
|
+
const a = await this.storage.readRevision(revA);
|
|
296
|
+
const b = await this.storage.readRevision(revB);
|
|
297
|
+
return import_diff.diffManifests(a.tree, b.tree, this.rules);
|
|
298
|
+
}
|
|
299
|
+
async head() {
|
|
300
|
+
await this.ensureInit();
|
|
301
|
+
return this.resolveHead();
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
function filterPathsByGlobs(paths, patterns) {
|
|
305
|
+
return paths.filter((filePath) => patterns.some((pattern) => import_rules.matchVCSPath(pattern, filePath)));
|
|
306
|
+
}
|
|
307
|
+
function resolveInternalPath(workFs, metaFs, workPath, metaPath) {
|
|
308
|
+
if (workFs !== metaFs)
|
|
309
|
+
return "";
|
|
310
|
+
const normalizedWork = normalizeFsPath(workPath);
|
|
311
|
+
const normalizedMeta = normalizeFsPath(metaFs.resolve(metaPath));
|
|
312
|
+
if (normalizedMeta === normalizedWork)
|
|
313
|
+
return "";
|
|
314
|
+
if (!normalizedMeta.startsWith(`${normalizedWork}/`))
|
|
315
|
+
return "";
|
|
316
|
+
return normalizedMeta.slice(normalizedWork.length + 1);
|
|
317
|
+
}
|
|
318
|
+
function normalizeFsPath(path) {
|
|
319
|
+
return path.replace(/\\/g, "/").replace(/\/+$/, "");
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
//# debugId=B3A44192C38E782A64756E2164756E21
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/vcs/vcs.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"import type { VirtualFS } from \"../types.cjs\";\nimport type {\n VCSConfig,\n Revision,\n DiffEntry,\n TreeManifest,\n CommitOptions,\n CheckoutOptions,\n LogOptions,\n LogEntry,\n BranchInfo,\n} from \"./types.cjs\";\nimport { VCSStorage } from \"./storage.cjs\";\nimport { diffManifests, diffWorkingTree } from \"./diff.cjs\";\nimport { matchVCSPath, VCSRules } from \"./rules.cjs\";\nimport { buildTreeManifest, restoreTree } from \"./snapshot.cjs\";\n\nexport class VersionControlSystem {\n private readonly workFs: VirtualFS;\n private readonly workPath: string;\n private readonly storage: VCSStorage;\n private readonly vcsInternalPath: string;\n private readonly rules: VCSRules;\n\n constructor(config: VCSConfig) {\n this.workFs = config.fs;\n this.workPath = config.fs.resolve(config.path);\n\n const metaFs = config.vcsPath?.fs ?? config.fs;\n const metaPath = config.vcsPath?.path ?? metaFs.resolve(config.path, \".vcs\");\n this.storage = new VCSStorage(metaFs, metaPath);\n\n this.vcsInternalPath = resolveInternalPath(config.fs, metaFs, this.workPath, metaPath);\n\n this.rules = new VCSRules({\n internalPath: this.vcsInternalPath,\n ignore: config.ignore,\n attributes: config.attributes,\n });\n }\n\n /** Initialize the .vcs directory. Called automatically on first operation if needed. */\n async init(): Promise<void> {\n if (await this.storage.isInitialized()) return;\n await this.storage.initialize();\n }\n\n private async ensureInit(): Promise<void> {\n if (!(await this.storage.isInitialized())) {\n await this.init();\n }\n }\n\n /** Get the current HEAD revision number, or null if no commits yet. */\n private async resolveHead(): Promise<{ branch: string | null; revision: number | null }> {\n const head = await this.storage.readHead();\n if (head.revision !== undefined) {\n return { branch: null, revision: head.revision };\n }\n if (head.ref) {\n const branchName = head.ref.replace(\"refs/heads/\", \"\");\n const branchRef = await this.storage.readBranch(branchName);\n return { branch: branchName, revision: branchRef?.revision ?? null };\n }\n return { branch: null, revision: null };\n }\n\n /** Get current HEAD manifest, or empty if no commits. */\n private async headManifest(): Promise<TreeManifest> {\n const { revision } = await this.resolveHead();\n if (revision === null) return {};\n const rev = await this.storage.readRevision(revision);\n return rev.tree;\n }\n\n /** Commit all pending changes, or selective changes if paths are provided. */\n async commit(message: string, opts?: CommitOptions): Promise<Revision> {\n await this.ensureInit();\n\n const { branch, revision: parentId } = await this.resolveHead();\n const parentManifest = parentId !== null\n ? (await this.storage.readRevision(parentId)).tree\n : {};\n\n let newTree: TreeManifest;\n let changes: DiffEntry[];\n\n if (opts?.paths && opts.paths.length > 0) {\n // Selective commit: only include matching files\n const fullManifest = await buildTreeManifest(this.workFs, this.workPath, {\n rules: this.rules,\n trackedPaths: Object.keys(parentManifest),\n });\n const matchedPaths = filterPathsByGlobs(Object.keys(fullManifest), opts.paths);\n\n // Start with parent manifest, overlay matched files from working tree\n newTree = { ...parentManifest };\n\n // Also check for deletions: files in parent that match patterns but are gone from working tree\n const parentMatchedPaths = filterPathsByGlobs(Object.keys(parentManifest), opts.paths);\n for (const p of parentMatchedPaths) {\n if (!fullManifest[p]) {\n delete newTree[p]; // file was deleted\n }\n }\n\n for (const p of matchedPaths) {\n newTree[p] = fullManifest[p]!;\n }\n\n // Compute changes only for matched paths\n const relevantBefore: TreeManifest = {};\n const relevantAfter: TreeManifest = {};\n const allRelevant = new Set([...matchedPaths, ...parentMatchedPaths]);\n for (const p of allRelevant) {\n if (parentManifest[p]) relevantBefore[p] = parentManifest[p]!;\n if (newTree[p]) relevantAfter[p] = newTree[p]!;\n }\n changes = diffManifests(relevantBefore, relevantAfter, this.rules);\n } else {\n // Full commit\n newTree = await buildTreeManifest(this.workFs, this.workPath, {\n rules: this.rules,\n trackedPaths: Object.keys(parentManifest),\n });\n changes = diffManifests(parentManifest, newTree, this.rules);\n }\n\n if (changes.length === 0) {\n throw new Error(\"nothing to commit\");\n }\n\n const id = await this.storage.nextRevisionId();\n const rev: Revision = {\n id,\n parent: parentId,\n branch: branch ?? \"detached\",\n message,\n timestamp: new Date().toISOString(),\n changes,\n tree: newTree,\n };\n\n await this.storage.writeRevision(rev);\n\n // Update branch ref or HEAD\n if (branch) {\n await this.storage.writeBranch(branch, { revision: id });\n } else {\n await this.storage.writeHead({ revision: id });\n }\n\n return rev;\n }\n\n /** Checkout a revision number or branch name. */\n async checkout(target: string | number, opts?: CheckoutOptions): Promise<void> {\n await this.ensureInit();\n\n const isPartial = opts?.paths && opts.paths.length > 0;\n\n let targetRevision: number;\n let targetBranch: string | null = null;\n\n if (typeof target === \"string\") {\n // Check if it's a branch name\n const branchRef = await this.storage.readBranch(target);\n if (branchRef) {\n targetBranch = target;\n targetRevision = branchRef.revision;\n } else {\n throw new Error(`unknown branch or revision: \"${target}\"`);\n }\n } else {\n targetRevision = target;\n }\n\n // Verify revision exists\n let rev: Revision;\n try {\n rev = await this.storage.readRevision(targetRevision);\n } catch {\n throw new Error(`revision ${targetRevision} not found`);\n }\n\n const currentManifest = await this.headManifest();\n\n if (isPartial) {\n // Partial checkout: restore specific files, don't update HEAD\n await restoreTree(this.workFs, this.workPath, rev.tree, {\n fullRestore: false,\n paths: opts!.paths!,\n rules: this.rules,\n trackedPaths: Object.keys(currentManifest),\n });\n } else {\n // Full checkout\n if (!opts?.force) {\n const changes = await this.status();\n if (changes.length > 0) {\n throw new Error(\"working tree has uncommitted changes (use force to discard)\");\n }\n }\n\n await restoreTree(this.workFs, this.workPath, rev.tree, {\n fullRestore: true,\n rules: this.rules,\n trackedPaths: Object.keys(currentManifest),\n });\n\n // Update HEAD\n if (targetBranch) {\n await this.storage.writeHead({ ref: `refs/heads/${targetBranch}` });\n } else {\n await this.storage.writeHead({ revision: targetRevision });\n }\n }\n }\n\n /** Create a new branch at HEAD. */\n async branch(name: string): Promise<void> {\n await this.ensureInit();\n\n const existing = await this.storage.readBranch(name);\n if (existing) {\n throw new Error(`branch \"${name}\" already exists`);\n }\n\n const { revision } = await this.resolveHead();\n if (revision === null) {\n throw new Error(\"cannot create branch: no commits yet\");\n }\n\n await this.storage.writeBranch(name, { revision });\n }\n\n /** List all branches. */\n async branches(): Promise<BranchInfo[]> {\n await this.ensureInit();\n\n const names = await this.storage.listBranches();\n const head = await this.resolveHead();\n const result: BranchInfo[] = [];\n\n for (const name of names) {\n const ref = await this.storage.readBranch(name);\n if (ref) {\n result.push({\n name,\n revision: ref.revision,\n current: head.branch === name,\n });\n }\n }\n\n return result.sort((a, b) => a.name.localeCompare(b.name));\n }\n\n /** Get revision history. */\n async log(opts?: LogOptions): Promise<LogEntry[]> {\n await this.ensureInit();\n\n let startRevision: number | null;\n\n if (opts?.branch) {\n const branchRef = await this.storage.readBranch(opts.branch);\n if (!branchRef) throw new Error(`branch \"${opts.branch}\" not found`);\n startRevision = branchRef.revision;\n } else {\n const { revision } = await this.resolveHead();\n startRevision = revision;\n }\n\n if (startRevision === null) return [];\n\n const entries: LogEntry[] = [];\n let currentId: number | null = startRevision;\n\n while (currentId !== null) {\n if (opts?.limit && entries.length >= opts.limit) break;\n\n let rev: Revision;\n try {\n rev = await this.storage.readRevision(currentId);\n } catch {\n break;\n }\n\n const changedPaths = rev.changes.map((c) => c.path);\n\n if (opts?.path) {\n // Filter: only include if this revision touches the specified path\n const matchesPath = changedPaths.some((p) => matchVCSPath(opts.path!, p));\n if (matchesPath) {\n entries.push({\n id: rev.id,\n parent: rev.parent,\n branch: rev.branch,\n message: rev.message,\n timestamp: rev.timestamp,\n paths: changedPaths,\n });\n }\n } else {\n entries.push({\n id: rev.id,\n parent: rev.parent,\n branch: rev.branch,\n message: rev.message,\n timestamp: rev.timestamp,\n paths: changedPaths,\n });\n }\n\n currentId = rev.parent;\n }\n\n return entries;\n }\n\n /** Get uncommitted changes as DiffEntry[]. */\n async status(): Promise<DiffEntry[]> {\n await this.ensureInit();\n const manifest = await this.headManifest();\n return diffWorkingTree(this.workFs, this.workPath, manifest, this.rules);\n }\n\n /** Diff between two revisions. */\n async diff(revA: number, revB: number): Promise<DiffEntry[]> {\n await this.ensureInit();\n const a = await this.storage.readRevision(revA);\n const b = await this.storage.readRevision(revB);\n return diffManifests(a.tree, b.tree, this.rules);\n }\n\n /** Get current HEAD info. */\n async head(): Promise<{ branch: string | null; revision: number | null }> {\n await this.ensureInit();\n return this.resolveHead();\n }\n}\n\n/**\n * Filter a list of paths to only those matching any of the given glob patterns.\n * Patterns may start with `/` which is stripped before matching.\n */\nfunction filterPathsByGlobs(paths: string[], patterns: string[]): string[] {\n return paths.filter((filePath) =>\n patterns.some((pattern) => matchVCSPath(pattern, filePath)),\n );\n}\n\nfunction resolveInternalPath(\n workFs: VirtualFS,\n metaFs: VirtualFS,\n workPath: string,\n metaPath: string,\n): string {\n if (workFs !== metaFs) return \"\";\n\n const normalizedWork = normalizeFsPath(workPath);\n const normalizedMeta = normalizeFsPath(metaFs.resolve(metaPath));\n\n if (normalizedMeta === normalizedWork) return \"\";\n if (!normalizedMeta.startsWith(`${normalizedWork}/`)) return \"\";\n\n return normalizedMeta.slice(normalizedWork.length + 1);\n}\n\nfunction normalizeFsPath(path: string): string {\n return path.replace(/\\\\/g, \"/\").replace(/\\/+$/, \"\");\n}\n"
|
|
6
|
+
],
|
|
7
|
+
"mappings": "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",
|
|
8
|
+
"debugId": "B3A44192C38E782A64756E2164756E21",
|
|
9
|
+
"names": []
|
|
10
|
+
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
|
+
function __accessProp(key) {
|
|
6
|
+
return this[key];
|
|
7
|
+
}
|
|
8
|
+
var __toCommonJS = (from) => {
|
|
9
|
+
var entry = (__moduleCache ??= new WeakMap).get(from), desc;
|
|
10
|
+
if (entry)
|
|
11
|
+
return entry;
|
|
12
|
+
entry = __defProp({}, "__esModule", { value: true });
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (var key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(entry, key))
|
|
16
|
+
__defProp(entry, key, {
|
|
17
|
+
get: __accessProp.bind(from, key),
|
|
18
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
__moduleCache.set(from, entry);
|
|
22
|
+
return entry;
|
|
23
|
+
};
|
|
24
|
+
var __moduleCache;
|
|
25
|
+
var __returnValue = (v) => v;
|
|
26
|
+
function __exportSetter(name, newValue) {
|
|
27
|
+
this[name] = __returnValue.bind(null, newValue);
|
|
28
|
+
}
|
|
29
|
+
var __export = (target, all) => {
|
|
30
|
+
for (var name in all)
|
|
31
|
+
__defProp(target, name, {
|
|
32
|
+
get: all[name],
|
|
33
|
+
enumerable: true,
|
|
34
|
+
configurable: true,
|
|
35
|
+
set: __exportSetter.bind(all, name)
|
|
36
|
+
});
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
// src/vcs/walk.ts
|
|
40
|
+
var exports_walk = {};
|
|
41
|
+
__export(exports_walk, {
|
|
42
|
+
walkTreeEntries: () => walkTreeEntries,
|
|
43
|
+
walkTree: () => walkTree
|
|
44
|
+
});
|
|
45
|
+
module.exports = __toCommonJS(exports_walk);
|
|
46
|
+
async function walkTree(fs, root, options = {}) {
|
|
47
|
+
const results = await walkTreeEntries(fs, root, options);
|
|
48
|
+
return results.filter((entry) => entry.kind === "file").map((entry) => entry.path);
|
|
49
|
+
}
|
|
50
|
+
async function walkTreeEntries(fs, root, options = {}) {
|
|
51
|
+
const results = [];
|
|
52
|
+
await walkDir(fs, root, "", options, results);
|
|
53
|
+
return results.sort((a, b) => a.path.localeCompare(b.path));
|
|
54
|
+
}
|
|
55
|
+
async function walkDir(fs, dir, relativeDir, options, results) {
|
|
56
|
+
let entries;
|
|
57
|
+
try {
|
|
58
|
+
entries = await fs.readdir(dir);
|
|
59
|
+
} catch {
|
|
60
|
+
return false;
|
|
61
|
+
}
|
|
62
|
+
for (const entry of entries) {
|
|
63
|
+
const fullPath = fs.resolve(dir, entry);
|
|
64
|
+
let stat;
|
|
65
|
+
try {
|
|
66
|
+
stat = await fs.stat(fullPath);
|
|
67
|
+
} catch {
|
|
68
|
+
continue;
|
|
69
|
+
}
|
|
70
|
+
const relative = relativeDir ? `${relativeDir}/${entry}` : entry;
|
|
71
|
+
if (stat.isDirectory()) {
|
|
72
|
+
if (options.enterDirectory && !await options.enterDirectory(relative)) {
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
const empty = await walkDir(fs, fullPath, relative, options, results);
|
|
76
|
+
if (options.includeDirectory && await options.includeDirectory(relative, { empty })) {
|
|
77
|
+
results.push({ path: relative, kind: "directory" });
|
|
78
|
+
}
|
|
79
|
+
} else if (stat.isFile()) {
|
|
80
|
+
if (options.includeFile && !await options.includeFile(relative)) {
|
|
81
|
+
continue;
|
|
82
|
+
}
|
|
83
|
+
results.push({ path: relative, kind: "file" });
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
return entries.length === 0;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
//# debugId=25C7BCDB4757CEFB64756E2164756E21
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/vcs/walk.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"import type { VirtualFS } from \"../types.cjs\";\n\ninterface WalkTreeOptions {\n enterDirectory?: (relPath: string) => boolean | Promise<boolean>;\n includeFile?: (relPath: string) => boolean | Promise<boolean>;\n includeDirectory?: (\n relPath: string,\n info: { empty: boolean },\n ) => boolean | Promise<boolean>;\n}\n\nexport interface WalkTreeEntry {\n path: string;\n kind: \"file\" | \"directory\";\n}\n\n/**\n * Recursively walk a directory tree and return all file paths\n * relative to the given root.\n */\nexport async function walkTree(\n fs: VirtualFS,\n root: string,\n options: WalkTreeOptions = {},\n): Promise<string[]> {\n const results = await walkTreeEntries(fs, root, options);\n return results\n .filter((entry) => entry.kind === \"file\")\n .map((entry) => entry.path);\n}\n\nexport async function walkTreeEntries(\n fs: VirtualFS,\n root: string,\n options: WalkTreeOptions = {},\n): Promise<WalkTreeEntry[]> {\n const results: WalkTreeEntry[] = [];\n await walkDir(fs, root, \"\", options, results);\n return results.sort((a, b) => a.path.localeCompare(b.path));\n}\n\nasync function walkDir(\n fs: VirtualFS,\n dir: string,\n relativeDir: string,\n options: WalkTreeOptions,\n results: WalkTreeEntry[],\n): Promise<boolean> {\n let entries: string[];\n try {\n entries = await fs.readdir(dir);\n } catch {\n return false;\n }\n\n for (const entry of entries) {\n const fullPath = fs.resolve(dir, entry);\n let stat;\n try {\n stat = await fs.stat(fullPath);\n } catch {\n continue;\n }\n\n const relative = relativeDir ? `${relativeDir}/${entry}` : entry;\n\n if (stat.isDirectory()) {\n if (options.enterDirectory && !(await options.enterDirectory(relative))) {\n continue;\n }\n const empty = await walkDir(fs, fullPath, relative, options, results);\n if (options.includeDirectory && (await options.includeDirectory(relative, { empty }))) {\n results.push({ path: relative, kind: \"directory\" });\n }\n } else if (stat.isFile()) {\n if (options.includeFile && !(await options.includeFile(relative))) {\n continue;\n }\n results.push({ path: relative, kind: \"file\" });\n }\n }\n\n return entries.length === 0;\n}\n"
|
|
6
|
+
],
|
|
7
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAoBA,eAAsB,QAAQ,CAC5B,IACA,MACA,UAA2B,CAAC,GACT;AAAA,EACnB,MAAM,UAAU,MAAM,gBAAgB,IAAI,MAAM,OAAO;AAAA,EACvD,OAAO,QACJ,OAAO,CAAC,UAAU,MAAM,SAAS,MAAM,EACvC,IAAI,CAAC,UAAU,MAAM,IAAI;AAAA;AAG9B,eAAsB,eAAe,CACnC,IACA,MACA,UAA2B,CAAC,GACF;AAAA,EAC1B,MAAM,UAA2B,CAAC;AAAA,EAClC,MAAM,QAAQ,IAAI,MAAM,IAAI,SAAS,OAAO;AAAA,EAC5C,OAAO,QAAQ,KAAK,CAAC,GAAG,MAAM,EAAE,KAAK,cAAc,EAAE,IAAI,CAAC;AAAA;AAG5D,eAAe,OAAO,CACpB,IACA,KACA,aACA,SACA,SACkB;AAAA,EAClB,IAAI;AAAA,EACJ,IAAI;AAAA,IACF,UAAU,MAAM,GAAG,QAAQ,GAAG;AAAA,IAC9B,MAAM;AAAA,IACN,OAAO;AAAA;AAAA,EAGT,WAAW,SAAS,SAAS;AAAA,IAC3B,MAAM,WAAW,GAAG,QAAQ,KAAK,KAAK;AAAA,IACtC,IAAI;AAAA,IACJ,IAAI;AAAA,MACF,OAAO,MAAM,GAAG,KAAK,QAAQ;AAAA,MAC7B,MAAM;AAAA,MACN;AAAA;AAAA,IAGF,MAAM,WAAW,cAAc,GAAG,eAAe,UAAU;AAAA,IAE3D,IAAI,KAAK,YAAY,GAAG;AAAA,MACtB,IAAI,QAAQ,kBAAkB,CAAE,MAAM,QAAQ,eAAe,QAAQ,GAAI;AAAA,QACvE;AAAA,MACF;AAAA,MACA,MAAM,QAAQ,MAAM,QAAQ,IAAI,UAAU,UAAU,SAAS,OAAO;AAAA,MACpE,IAAI,QAAQ,oBAAqB,MAAM,QAAQ,iBAAiB,UAAU,EAAE,MAAM,CAAC,GAAI;AAAA,QACrF,QAAQ,KAAK,EAAE,MAAM,UAAU,MAAM,YAAY,CAAC;AAAA,MACpD;AAAA,IACF,EAAO,SAAI,KAAK,OAAO,GAAG;AAAA,MACxB,IAAI,QAAQ,eAAe,CAAE,MAAM,QAAQ,YAAY,QAAQ,GAAI;AAAA,QACjE;AAAA,MACF;AAAA,MACA,QAAQ,KAAK,EAAE,MAAM,UAAU,MAAM,OAAO,CAAC;AAAA,IAC/C;AAAA,EACF;AAAA,EAEA,OAAO,QAAQ,WAAW;AAAA;",
|
|
8
|
+
"debugId": "25C7BCDB4757CEFB64756E2164756E21",
|
|
9
|
+
"names": []
|
|
10
|
+
}
|
package/dist/mjs/package.json
CHANGED
package/dist/mjs/src/index.mjs
CHANGED
|
@@ -34,6 +34,7 @@ import {
|
|
|
34
34
|
import { createStdin, StdinImpl } from "./io/index.mjs";
|
|
35
35
|
import { createStdout, createStderr, createPipe, OutputCollectorImpl, PipeBuffer } from "./io/index.mjs";
|
|
36
36
|
import { escape, escapeForInterpolation, globVirtualFS } from "./utils/index.mjs";
|
|
37
|
+
import { VersionControlSystem } from "./vcs/index.mjs";
|
|
37
38
|
export {
|
|
38
39
|
tokenToString,
|
|
39
40
|
parse,
|
|
@@ -66,6 +67,7 @@ export {
|
|
|
66
67
|
createShellDSL,
|
|
67
68
|
createPipe,
|
|
68
69
|
WebFileSystem,
|
|
70
|
+
VersionControlSystem,
|
|
69
71
|
StdinImpl,
|
|
70
72
|
ShellPromise,
|
|
71
73
|
ShellError,
|
|
@@ -83,4 +85,4 @@ export {
|
|
|
83
85
|
BreakException
|
|
84
86
|
};
|
|
85
87
|
|
|
86
|
-
//# debugId=
|
|
88
|
+
//# debugId=A64F16175D95758364756E2164756E21
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/index.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
|
-
"// Main class exports\nexport { ShellDSL, createShellDSL, type Program } from \"./shell-dsl.mjs\";\nexport { ShellPromise, type ShellPromiseOptions } from \"./shell-promise.mjs\";\n\n// Types\nexport type {\n VirtualFS,\n FileStat,\n Command,\n CommandContext,\n Stdin,\n Stdout,\n Stderr,\n OutputCollector,\n ExecResult,\n ShellConfig,\n RawValue,\n} from \"./types.mjs\";\nexport { isRawValue } from \"./types.mjs\";\n\n// Errors\nexport { ShellError, LexError, ParseError } from \"./errors.mjs\";\n\n// Lexer\nexport { Lexer, lex, tokenToString } from \"./lexer/index.mjs\";\nexport type { Token, RedirectMode } from \"./lexer/index.mjs\";\n\n// Parser\nexport { Parser, parse } from \"./parser/index.mjs\";\nexport type {\n ASTNode,\n Redirect,\n CommandNode,\n PipelineNode,\n AndNode,\n OrNode,\n SequenceNode,\n LiteralNode,\n VariableNode,\n SubstitutionNode,\n GlobNode,\n ConcatNode,\n IfNode,\n ForNode,\n WhileNode,\n UntilNode,\n CaseNode,\n CaseClause,\n ArithmeticNode,\n} from \"./parser/index.mjs\";\nexport {\n isCommandNode,\n isPipelineNode,\n isAndNode,\n isOrNode,\n isSequenceNode,\n isLiteralNode,\n isVariableNode,\n isSubstitutionNode,\n isGlobNode,\n isConcatNode,\n isIfNode,\n isForNode,\n isWhileNode,\n isUntilNode,\n isCaseNode,\n isArithmeticNode,\n} from \"./parser/index.mjs\";\n\n// Interpreter\nexport { Interpreter, type InterpreterOptions, BreakException, ContinueException } from \"./interpreter/index.mjs\";\n\n// Filesystem\nexport { createVirtualFS } from \"./fs/index.mjs\";\nexport {\n FileSystem,\n ReadOnlyFileSystem,\n WebFileSystem,\n createWebUnderlyingFS,\n type PathOps,\n type Permission,\n type PermissionRules,\n type UnderlyingFS,\n} from \"./fs/index.mjs\";\n\n// I/O\nexport { createStdin, StdinImpl } from \"./io/index.mjs\";\nexport { createStdout, createStderr, createPipe, OutputCollectorImpl, PipeBuffer } from \"./io/index.mjs\";\n\n// Utilities\nexport { escape, escapeForInterpolation, globVirtualFS } from \"./utils/index.mjs\";\nexport type { GlobVirtualFS, GlobOptions } from \"./utils/index.mjs\";\n"
|
|
5
|
+
"// Main class exports\nexport { ShellDSL, createShellDSL, type Program } from \"./shell-dsl.mjs\";\nexport { ShellPromise, type ShellPromiseOptions } from \"./shell-promise.mjs\";\n\n// Types\nexport type {\n VirtualFS,\n FileStat,\n Command,\n CommandContext,\n Stdin,\n Stdout,\n Stderr,\n OutputCollector,\n ExecResult,\n ShellConfig,\n RawValue,\n} from \"./types.mjs\";\nexport { isRawValue } from \"./types.mjs\";\n\n// Errors\nexport { ShellError, LexError, ParseError } from \"./errors.mjs\";\n\n// Lexer\nexport { Lexer, lex, tokenToString } from \"./lexer/index.mjs\";\nexport type { Token, RedirectMode } from \"./lexer/index.mjs\";\n\n// Parser\nexport { Parser, parse } from \"./parser/index.mjs\";\nexport type {\n ASTNode,\n Redirect,\n CommandNode,\n PipelineNode,\n AndNode,\n OrNode,\n SequenceNode,\n LiteralNode,\n VariableNode,\n SubstitutionNode,\n GlobNode,\n ConcatNode,\n IfNode,\n ForNode,\n WhileNode,\n UntilNode,\n CaseNode,\n CaseClause,\n ArithmeticNode,\n} from \"./parser/index.mjs\";\nexport {\n isCommandNode,\n isPipelineNode,\n isAndNode,\n isOrNode,\n isSequenceNode,\n isLiteralNode,\n isVariableNode,\n isSubstitutionNode,\n isGlobNode,\n isConcatNode,\n isIfNode,\n isForNode,\n isWhileNode,\n isUntilNode,\n isCaseNode,\n isArithmeticNode,\n} from \"./parser/index.mjs\";\n\n// Interpreter\nexport { Interpreter, type InterpreterOptions, BreakException, ContinueException } from \"./interpreter/index.mjs\";\n\n// Filesystem\nexport { createVirtualFS } from \"./fs/index.mjs\";\nexport {\n FileSystem,\n ReadOnlyFileSystem,\n WebFileSystem,\n createWebUnderlyingFS,\n type PathOps,\n type Permission,\n type PermissionRules,\n type UnderlyingFS,\n} from \"./fs/index.mjs\";\n\n// I/O\nexport { createStdin, StdinImpl } from \"./io/index.mjs\";\nexport { createStdout, createStderr, createPipe, OutputCollectorImpl, PipeBuffer } from \"./io/index.mjs\";\n\n// Utilities\nexport { escape, escapeForInterpolation, globVirtualFS } from \"./utils/index.mjs\";\nexport type { GlobVirtualFS, GlobOptions } from \"./utils/index.mjs\";\n\n// Version Control\nexport { VersionControlSystem } from \"./vcs/index.mjs\";\nexport type {\n VCSConfig,\n VCSAttributeRule,\n VCSResolvedAttributes,\n VCSDiffMode,\n Revision,\n DiffEntry,\n TreeManifest,\n TreeEntry,\n FileEntry,\n DirectoryEntry,\n CommitOptions,\n CheckoutOptions,\n LogOptions,\n LogEntry,\n BranchInfo,\n} from \"./vcs/index.mjs\";\n"
|
|
6
6
|
],
|
|
7
|
-
"mappings": ";AACA;AACA;AAgBA;AAGA;AAGA;AAIA;AAsBA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAoBA;AAGA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAYA;AACA;AAGA;",
|
|
8
|
-
"debugId": "
|
|
7
|
+
"mappings": ";AACA;AACA;AAgBA;AAGA;AAGA;AAIA;AAsBA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAoBA;AAGA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAYA;AACA;AAGA;AAIA;",
|
|
8
|
+
"debugId": "A64F16175D95758364756E2164756E21",
|
|
9
9
|
"names": []
|
|
10
10
|
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
// src/vcs/diff.ts
|
|
2
|
+
import { VCSRules } from "./rules.mjs";
|
|
3
|
+
import { buildTreeManifest } from "./snapshot.mjs";
|
|
4
|
+
function diffManifests(before, after, rules = new VCSRules) {
|
|
5
|
+
const entries = [];
|
|
6
|
+
const allPaths = new Set([...Object.keys(before), ...Object.keys(after)]);
|
|
7
|
+
for (const path of allPaths) {
|
|
8
|
+
const prev = before[path];
|
|
9
|
+
const curr = after[path];
|
|
10
|
+
if (!prev && curr) {
|
|
11
|
+
entries.push(createDiffEntry("add", path, curr, undefined, rules));
|
|
12
|
+
} else if (prev && !curr) {
|
|
13
|
+
entries.push(createDiffEntry("delete", path, undefined, prev, rules));
|
|
14
|
+
} else if (prev && curr && !entriesEqual(prev, curr)) {
|
|
15
|
+
entries.push(createDiffEntry("modify", path, curr, prev, rules));
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
return entries.sort((a, b) => a.path.localeCompare(b.path));
|
|
19
|
+
}
|
|
20
|
+
async function diffWorkingTree(fs, rootPath, manifest, rules = new VCSRules({ internalDirName: ".vcs" })) {
|
|
21
|
+
const workingManifest = await buildTreeManifest(fs, rootPath, {
|
|
22
|
+
rules,
|
|
23
|
+
trackedPaths: Object.keys(manifest)
|
|
24
|
+
});
|
|
25
|
+
return diffManifests(manifest, workingManifest, rules);
|
|
26
|
+
}
|
|
27
|
+
function createDiffEntry(type, path, current, previous, rules) {
|
|
28
|
+
const attributes = rules.resolveAttributes(path);
|
|
29
|
+
const entryKind = getEntryKind(current ?? previous);
|
|
30
|
+
const previousEntryKind = previous ? getEntryKind(previous) : undefined;
|
|
31
|
+
const entry = {
|
|
32
|
+
type,
|
|
33
|
+
path,
|
|
34
|
+
binary: attributes.binary,
|
|
35
|
+
diff: attributes.diff,
|
|
36
|
+
entryKind,
|
|
37
|
+
previousEntryKind
|
|
38
|
+
};
|
|
39
|
+
if (attributes.diff !== "none") {
|
|
40
|
+
if (isFileEntry(current)) {
|
|
41
|
+
entry.content = current.content;
|
|
42
|
+
}
|
|
43
|
+
if (isFileEntry(previous)) {
|
|
44
|
+
entry.previousContent = previous.content;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return entry;
|
|
48
|
+
}
|
|
49
|
+
function entriesEqual(a, b) {
|
|
50
|
+
if (getEntryKind(a) !== getEntryKind(b))
|
|
51
|
+
return false;
|
|
52
|
+
if (!isFileEntry(a) || !isFileEntry(b))
|
|
53
|
+
return true;
|
|
54
|
+
return a.content === b.content;
|
|
55
|
+
}
|
|
56
|
+
function getEntryKind(entry) {
|
|
57
|
+
return entry?.kind === "directory" ? "directory" : "file";
|
|
58
|
+
}
|
|
59
|
+
function isFileEntry(entry) {
|
|
60
|
+
return !!entry && entry.kind !== "directory";
|
|
61
|
+
}
|
|
62
|
+
export {
|
|
63
|
+
diffWorkingTree,
|
|
64
|
+
diffManifests
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
//# debugId=E1AC85757DDF65ED64756E2164756E21
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/vcs/diff.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"import type { VirtualFS } from \"../types.mjs\";\nimport type { TreeManifest, DiffEntry, TreeEntry } from \"./types.mjs\";\nimport { VCSRules } from \"./rules.mjs\";\nimport { buildTreeManifest } from \"./snapshot.mjs\";\n\n/**\n * Compute diff entries between two tree manifests.\n */\nexport function diffManifests(\n before: TreeManifest,\n after: TreeManifest,\n rules: VCSRules = new VCSRules(),\n): DiffEntry[] {\n const entries: DiffEntry[] = [];\n const allPaths = new Set([...Object.keys(before), ...Object.keys(after)]);\n\n for (const path of allPaths) {\n const prev = before[path];\n const curr = after[path];\n\n if (!prev && curr) {\n entries.push(createDiffEntry(\"add\", path, curr, undefined, rules));\n } else if (prev && !curr) {\n entries.push(createDiffEntry(\"delete\", path, undefined, prev, rules));\n } else if (prev && curr && !entriesEqual(prev, curr)) {\n entries.push(createDiffEntry(\"modify\", path, curr, prev, rules));\n }\n }\n\n return entries.sort((a, b) => a.path.localeCompare(b.path));\n}\n\n/**\n * Compute diff between a tree manifest and the current working tree.\n */\nexport async function diffWorkingTree(\n fs: VirtualFS,\n rootPath: string,\n manifest: TreeManifest,\n rules: VCSRules = new VCSRules({ internalDirName: \".vcs\" }),\n): Promise<DiffEntry[]> {\n const workingManifest = await buildTreeManifest(fs, rootPath, {\n rules,\n trackedPaths: Object.keys(manifest),\n });\n return diffManifests(manifest, workingManifest, rules);\n}\n\nfunction createDiffEntry(\n type: DiffEntry[\"type\"],\n path: string,\n current: TreeEntry | undefined,\n previous: TreeEntry | undefined,\n rules: VCSRules,\n): DiffEntry {\n const attributes = rules.resolveAttributes(path);\n const entryKind = getEntryKind(current ?? previous);\n const previousEntryKind = previous ? getEntryKind(previous) : undefined;\n const entry: DiffEntry = {\n type,\n path,\n binary: attributes.binary,\n diff: attributes.diff,\n entryKind,\n previousEntryKind,\n };\n\n if (attributes.diff !== \"none\") {\n if (isFileEntry(current)) {\n entry.content = current.content;\n }\n if (isFileEntry(previous)) {\n entry.previousContent = previous.content;\n }\n }\n\n return entry;\n}\n\nfunction entriesEqual(a: TreeEntry, b: TreeEntry): boolean {\n if (getEntryKind(a) !== getEntryKind(b)) return false;\n if (!isFileEntry(a) || !isFileEntry(b)) return true;\n return a.content === b.content;\n}\n\nfunction getEntryKind(entry: TreeEntry | undefined): \"file\" | \"directory\" {\n return entry?.kind === \"directory\" ? \"directory\" : \"file\";\n}\n\nfunction isFileEntry(entry: TreeEntry | undefined): entry is Extract<TreeEntry, { kind?: \"file\" }> {\n return !!entry && entry.kind !== \"directory\";\n}\n"
|
|
6
|
+
],
|
|
7
|
+
"mappings": ";AAEA;AACA;AAKO,SAAS,aAAa,CAC3B,QACA,OACA,QAAkB,IAAI,UACT;AAAA,EACb,MAAM,UAAuB,CAAC;AAAA,EAC9B,MAAM,WAAW,IAAI,IAAI,CAAC,GAAG,OAAO,KAAK,MAAM,GAAG,GAAG,OAAO,KAAK,KAAK,CAAC,CAAC;AAAA,EAExE,WAAW,QAAQ,UAAU;AAAA,IAC3B,MAAM,OAAO,OAAO;AAAA,IACpB,MAAM,OAAO,MAAM;AAAA,IAEnB,IAAI,CAAC,QAAQ,MAAM;AAAA,MACjB,QAAQ,KAAK,gBAAgB,OAAO,MAAM,MAAM,WAAW,KAAK,CAAC;AAAA,IACnE,EAAO,SAAI,QAAQ,CAAC,MAAM;AAAA,MACxB,QAAQ,KAAK,gBAAgB,UAAU,MAAM,WAAW,MAAM,KAAK,CAAC;AAAA,IACtE,EAAO,SAAI,QAAQ,QAAQ,CAAC,aAAa,MAAM,IAAI,GAAG;AAAA,MACpD,QAAQ,KAAK,gBAAgB,UAAU,MAAM,MAAM,MAAM,KAAK,CAAC;AAAA,IACjE;AAAA,EACF;AAAA,EAEA,OAAO,QAAQ,KAAK,CAAC,GAAG,MAAM,EAAE,KAAK,cAAc,EAAE,IAAI,CAAC;AAAA;AAM5D,eAAsB,eAAe,CACnC,IACA,UACA,UACA,QAAkB,IAAI,SAAS,EAAE,iBAAiB,OAAO,CAAC,GACpC;AAAA,EACtB,MAAM,kBAAkB,MAAM,kBAAkB,IAAI,UAAU;AAAA,IAC5D;AAAA,IACA,cAAc,OAAO,KAAK,QAAQ;AAAA,EACpC,CAAC;AAAA,EACD,OAAO,cAAc,UAAU,iBAAiB,KAAK;AAAA;AAGvD,SAAS,eAAe,CACtB,MACA,MACA,SACA,UACA,OACW;AAAA,EACX,MAAM,aAAa,MAAM,kBAAkB,IAAI;AAAA,EAC/C,MAAM,YAAY,aAAa,WAAW,QAAQ;AAAA,EAClD,MAAM,oBAAoB,WAAW,aAAa,QAAQ,IAAI;AAAA,EAC9D,MAAM,QAAmB;AAAA,IACvB;AAAA,IACA;AAAA,IACA,QAAQ,WAAW;AAAA,IACnB,MAAM,WAAW;AAAA,IACjB;AAAA,IACA;AAAA,EACF;AAAA,EAEA,IAAI,WAAW,SAAS,QAAQ;AAAA,IAC9B,IAAI,YAAY,OAAO,GAAG;AAAA,MACxB,MAAM,UAAU,QAAQ;AAAA,IAC1B;AAAA,IACA,IAAI,YAAY,QAAQ,GAAG;AAAA,MACzB,MAAM,kBAAkB,SAAS;AAAA,IACnC;AAAA,EACF;AAAA,EAEA,OAAO;AAAA;AAGT,SAAS,YAAY,CAAC,GAAc,GAAuB;AAAA,EACzD,IAAI,aAAa,CAAC,MAAM,aAAa,CAAC;AAAA,IAAG,OAAO;AAAA,EAChD,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,YAAY,CAAC;AAAA,IAAG,OAAO;AAAA,EAC/C,OAAO,EAAE,YAAY,EAAE;AAAA;AAGzB,SAAS,YAAY,CAAC,OAAoD;AAAA,EACxE,OAAO,OAAO,SAAS,cAAc,cAAc;AAAA;AAGrD,SAAS,WAAW,CAAC,OAA8E;AAAA,EACjG,OAAO,CAAC,CAAC,SAAS,MAAM,SAAS;AAAA;",
|
|
8
|
+
"debugId": "E1AC85757DDF65ED64756E2164756E21",
|
|
9
|
+
"names": []
|
|
10
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/vcs/index.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"export { VersionControlSystem } from \"./vcs.mjs\";\nexport type {\n VCSConfig,\n VCSAttributeRule,\n VCSResolvedAttributes,\n VCSDiffMode,\n Revision,\n DiffEntry,\n TreeManifest,\n TreeEntry,\n FileEntry,\n DirectoryEntry,\n CommitOptions,\n CheckoutOptions,\n LogOptions,\n LogEntry,\n BranchInfo,\n} from \"./types.mjs\";\n"
|
|
6
|
+
],
|
|
7
|
+
"mappings": ";AAAA;",
|
|
8
|
+
"debugId": "D3267E53BCD7103264756E2164756E21",
|
|
9
|
+
"names": []
|
|
10
|
+
}
|