browser-git-ops 0.0.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.
- package/LICENSE +21 -0
- package/README.md +146 -0
- package/dist/git/adapter.d.ts +16 -0
- package/dist/git/adapter.d.ts.map +1 -0
- package/dist/git/adapter.js +2 -0
- package/dist/git/githubAdapter.d.ts +50 -0
- package/dist/git/githubAdapter.d.ts.map +1 -0
- package/dist/git/githubAdapter.js +179 -0
- package/dist/git/gitlabAdapter.d.ts +91 -0
- package/dist/git/gitlabAdapter.d.ts.map +1 -0
- package/dist/git/gitlabAdapter.js +182 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +14 -0
- package/dist/test/e2e/github.spec.d.ts +2 -0
- package/dist/test/e2e/github.spec.d.ts.map +1 -0
- package/dist/test/e2e/github.spec.js +47 -0
- package/dist/test/e2e/gitlab.spec.d.ts +2 -0
- package/dist/test/e2e/gitlab.spec.d.ts.map +1 -0
- package/dist/test/e2e/gitlab.spec.js +34 -0
- package/dist/test/e2e/virtualfs.spec.d.ts +2 -0
- package/dist/test/e2e/virtualfs.spec.d.ts.map +1 -0
- package/dist/test/e2e/virtualfs.spec.js +409 -0
- package/dist/virtualfs/persistence.d.ts +149 -0
- package/dist/virtualfs/persistence.d.ts.map +1 -0
- package/dist/virtualfs/persistence.js +294 -0
- package/dist/virtualfs/types.d.ts +46 -0
- package/dist/virtualfs/types.d.ts.map +1 -0
- package/dist/virtualfs/types.js +2 -0
- package/dist/virtualfs/virtualfs.d.ts +189 -0
- package/dist/virtualfs/virtualfs.d.ts.map +1 -0
- package/dist/virtualfs/virtualfs.js +496 -0
- package/package.json +47 -0
|
@@ -0,0 +1,294 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.BrowserStorage = exports.NodeFsStorage = void 0;
|
|
7
|
+
const promises_1 = __importDefault(require("fs/promises"));
|
|
8
|
+
const path_1 = __importDefault(require("path"));
|
|
9
|
+
/**
|
|
10
|
+
* ファイルシステム上にデータを永続化する実装
|
|
11
|
+
*/
|
|
12
|
+
class NodeFsStorage {
|
|
13
|
+
dir;
|
|
14
|
+
indexPath;
|
|
15
|
+
/**
|
|
16
|
+
* NodeFsStorage を初期化します。
|
|
17
|
+
* @param {string} dir 永続化ディレクトリ
|
|
18
|
+
*/
|
|
19
|
+
constructor(dir) {
|
|
20
|
+
this.dir = dir;
|
|
21
|
+
this.indexPath = path_1.default.join(this.dir, 'index.json');
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* ストレージ用ディレクトリを作成します。
|
|
25
|
+
* @returns {Promise<void>}
|
|
26
|
+
*/
|
|
27
|
+
async init() {
|
|
28
|
+
await promises_1.default.mkdir(this.dir, { recursive: true });
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* index.json を読み込みます。存在しなければ null を返します。
|
|
32
|
+
* @returns {Promise<IndexFile|null>} 読み込んだ Index ファイル、または null
|
|
33
|
+
*/
|
|
34
|
+
async readIndex() {
|
|
35
|
+
try {
|
|
36
|
+
const raw = await promises_1.default.readFile(this.indexPath, 'utf8');
|
|
37
|
+
return JSON.parse(raw);
|
|
38
|
+
}
|
|
39
|
+
catch (err) {
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* index.json を書き込みます。
|
|
45
|
+
* @param {IndexFile} index 書き込む Index データ
|
|
46
|
+
* @returns {Promise<void>}
|
|
47
|
+
*/
|
|
48
|
+
async writeIndex(index) {
|
|
49
|
+
const data = JSON.stringify(index, null, 2);
|
|
50
|
+
await promises_1.default.writeFile(this.indexPath, data, 'utf8');
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* 指定パスへファイルを保存します。
|
|
54
|
+
* @param {string} filepath ファイルパス
|
|
55
|
+
* @param {string} content ファイル内容
|
|
56
|
+
* @returns {Promise<void>}
|
|
57
|
+
*/
|
|
58
|
+
async writeBlob(filepath, content) {
|
|
59
|
+
const full = path_1.default.join(this.dir, filepath);
|
|
60
|
+
await promises_1.default.mkdir(path_1.default.dirname(full), { recursive: true });
|
|
61
|
+
await promises_1.default.writeFile(full, content, 'utf8');
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* 指定パスのファイルを読み出します。存在しなければ null を返します。
|
|
65
|
+
* @param {string} filepath ファイルパス
|
|
66
|
+
* @returns {Promise<string|null>} ファイル内容または null
|
|
67
|
+
*/
|
|
68
|
+
async readBlob(filepath) {
|
|
69
|
+
try {
|
|
70
|
+
const full = path_1.default.join(this.dir, filepath);
|
|
71
|
+
return await promises_1.default.readFile(full, 'utf8');
|
|
72
|
+
}
|
|
73
|
+
catch (err) {
|
|
74
|
+
return null;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* 指定パスのファイルを削除します。存在しない場合は無視されます。
|
|
79
|
+
* @param {string} filepath ファイルパス
|
|
80
|
+
* @returns {Promise<void>}
|
|
81
|
+
*/
|
|
82
|
+
async deleteBlob(filepath) {
|
|
83
|
+
try {
|
|
84
|
+
const full = path_1.default.join(this.dir, filepath);
|
|
85
|
+
await promises_1.default.unlink(full);
|
|
86
|
+
}
|
|
87
|
+
catch (err) {
|
|
88
|
+
// ignore
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
exports.NodeFsStorage = NodeFsStorage;
|
|
93
|
+
// BrowserStorage: use OPFS when available, otherwise IndexedDB
|
|
94
|
+
/**
|
|
95
|
+
* ブラウザ環境向けの永続化実装: OPFS を優先し、無ければ IndexedDB を使用する
|
|
96
|
+
*/
|
|
97
|
+
class BrowserStorage {
|
|
98
|
+
dbName = 'apigit_storage';
|
|
99
|
+
dbPromise;
|
|
100
|
+
/**
|
|
101
|
+
* BrowserStorage を初期化します。内部で IndexedDB 接続を開始します。
|
|
102
|
+
*/
|
|
103
|
+
constructor() {
|
|
104
|
+
this.dbPromise = this.openDb();
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* 初期化を待機します(IndexedDB の準備完了を待つ)。
|
|
108
|
+
* @returns {Promise<void>}
|
|
109
|
+
*/
|
|
110
|
+
async init() {
|
|
111
|
+
await this.dbPromise;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* IndexedDB を開き、データベースインスタンスを返します。
|
|
115
|
+
* @returns {Promise<IDBDatabase>}
|
|
116
|
+
*/
|
|
117
|
+
openDb() {
|
|
118
|
+
return new Promise((resolve, reject) => {
|
|
119
|
+
const idb = globalThis.indexedDB;
|
|
120
|
+
if (!idb)
|
|
121
|
+
return reject(new Error('IndexedDB is not available'));
|
|
122
|
+
const req = idb.open(this.dbName, 1);
|
|
123
|
+
/**
|
|
124
|
+
* データベーススキーマの初期化
|
|
125
|
+
*/
|
|
126
|
+
req.onupgradeneeded = (ev) => {
|
|
127
|
+
const db = ev.target.result;
|
|
128
|
+
if (!db.objectStoreNames.contains('blobs'))
|
|
129
|
+
db.createObjectStore('blobs');
|
|
130
|
+
if (!db.objectStoreNames.contains('index'))
|
|
131
|
+
db.createObjectStore('index');
|
|
132
|
+
};
|
|
133
|
+
// 成功時ハンドラ
|
|
134
|
+
/**
|
|
135
|
+
* ハンドラ(成功時) - 戻り値なし
|
|
136
|
+
* @returns {void}
|
|
137
|
+
*/
|
|
138
|
+
req.onsuccess = () => resolve(req.result);
|
|
139
|
+
// エラー時ハンドラ
|
|
140
|
+
/**
|
|
141
|
+
* ハンドラ(エラー時) - 戻り値なし
|
|
142
|
+
* @returns {void}
|
|
143
|
+
*/
|
|
144
|
+
req.onerror = () => reject(req.error);
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* IndexedDB トランザクションをラップしてコールバックを実行します。
|
|
149
|
+
* @param {string} storeName ストア名
|
|
150
|
+
* @param {IDBTransactionMode} mode トランザクションモード
|
|
151
|
+
* @param {(store: IDBObjectStore)=>void|Promise<void>} cb 実行コールバック
|
|
152
|
+
* @returns {Promise<void>}
|
|
153
|
+
*/
|
|
154
|
+
async tx(storeName, mode, cb) {
|
|
155
|
+
const db = await this.dbPromise;
|
|
156
|
+
return new Promise((resolve, reject) => {
|
|
157
|
+
const tx = db.transaction(storeName, mode);
|
|
158
|
+
const storeObj = tx.objectStore(storeName);
|
|
159
|
+
Promise.resolve(cb(storeObj)).then(() => {
|
|
160
|
+
// トランザクション完了時ハンドラ
|
|
161
|
+
/**
|
|
162
|
+
* トランザクション完了時のコールバック(内部処理)
|
|
163
|
+
* @returns {void}
|
|
164
|
+
*/
|
|
165
|
+
tx.oncomplete = () => resolve();
|
|
166
|
+
// トランザクションエラー時ハンドラ
|
|
167
|
+
/**
|
|
168
|
+
* トランザクションエラー時のコールバック(内部処理)
|
|
169
|
+
* @returns {void}
|
|
170
|
+
*/
|
|
171
|
+
tx.onerror = () => reject(tx.error);
|
|
172
|
+
}).catch(reject);
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* index を IndexedDB から読み出します。
|
|
177
|
+
* @returns {Promise<IndexFile|null>} 読み込んだ Index ファイル、または null
|
|
178
|
+
*/
|
|
179
|
+
async readIndex() {
|
|
180
|
+
const db = await this.dbPromise;
|
|
181
|
+
return new Promise((resolve, reject) => {
|
|
182
|
+
const tx = db.transaction('index', 'readonly');
|
|
183
|
+
const store = tx.objectStore('index');
|
|
184
|
+
const req = store.get('index');
|
|
185
|
+
// onsuccess handler
|
|
186
|
+
/**
|
|
187
|
+
* onsuccess ハンドラ(内部処理) - 戻り値なし
|
|
188
|
+
* @returns {void}
|
|
189
|
+
*/
|
|
190
|
+
req.onsuccess = () => resolve(req.result ?? null);
|
|
191
|
+
// onerror handler
|
|
192
|
+
/**
|
|
193
|
+
* onerror ハンドラ(内部処理) - 戻り値なし
|
|
194
|
+
* @returns {void}
|
|
195
|
+
*/
|
|
196
|
+
req.onerror = () => reject(req.error);
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* index を IndexedDB に書き込みます。
|
|
201
|
+
* @param {IndexFile} index 書き込むデータ
|
|
202
|
+
* @returns {Promise<void>}
|
|
203
|
+
*/
|
|
204
|
+
async writeIndex(index) {
|
|
205
|
+
await this.tx('index', 'readwrite', (store) => { store.put(index, 'index'); });
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* blob を書き込みます。OPFS がある場合は OPFS を優先して使用します。
|
|
209
|
+
* @param {string} filepath ファイルパス
|
|
210
|
+
* @param {string} content ファイル内容
|
|
211
|
+
* @returns {Promise<void>}
|
|
212
|
+
*/
|
|
213
|
+
async writeBlob(filepath, content) {
|
|
214
|
+
// try OPFS if available
|
|
215
|
+
// @ts-ignore
|
|
216
|
+
const opfs = globalThis.originPrivateFileSystem;
|
|
217
|
+
if (opfs && opfs.getFileHandle) {
|
|
218
|
+
try {
|
|
219
|
+
// naive OPFS write
|
|
220
|
+
// @ts-ignore
|
|
221
|
+
const root = await opfs.getDirectory();
|
|
222
|
+
const parts = filepath.split('/');
|
|
223
|
+
let dir = root;
|
|
224
|
+
for (let i = 0; i < parts.length - 1; i++) {
|
|
225
|
+
dir = await dir.getDirectory(parts[i]);
|
|
226
|
+
}
|
|
227
|
+
const fh = await dir.getFileHandle(parts[parts.length - 1], { create: true });
|
|
228
|
+
const writable = await fh.createWritable();
|
|
229
|
+
await writable.write(content);
|
|
230
|
+
await writable.close();
|
|
231
|
+
return;
|
|
232
|
+
}
|
|
233
|
+
catch (e) {
|
|
234
|
+
// fallthrough to indexeddb
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
await this.tx('blobs', 'readwrite', (store) => { store.put(content, filepath); });
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* 指定パスの blob を読み出します。存在しなければ null を返します。
|
|
241
|
+
* @param {string} filepath ファイルパス
|
|
242
|
+
* @returns {Promise<string|null>} ファイル内容または null
|
|
243
|
+
*/
|
|
244
|
+
async readBlob(filepath) {
|
|
245
|
+
// try OPFS read
|
|
246
|
+
// @ts-ignore
|
|
247
|
+
const opfs = globalThis.originPrivateFileSystem;
|
|
248
|
+
if (opfs && opfs.getFileHandle) {
|
|
249
|
+
try {
|
|
250
|
+
// @ts-ignore
|
|
251
|
+
const root = await opfs.getDirectory();
|
|
252
|
+
const parts = filepath.split('/');
|
|
253
|
+
let dir = root;
|
|
254
|
+
for (let i = 0; i < parts.length - 1; i++) {
|
|
255
|
+
dir = await dir.getDirectory(parts[i]);
|
|
256
|
+
}
|
|
257
|
+
const fh = await dir.getFileHandle(parts[parts.length - 1]);
|
|
258
|
+
const file = await fh.getFile();
|
|
259
|
+
return await file.text();
|
|
260
|
+
}
|
|
261
|
+
catch (e) {
|
|
262
|
+
// fallback
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
const db = await this.dbPromise;
|
|
266
|
+
return new Promise((resolve, reject) => {
|
|
267
|
+
const tx = db.transaction('blobs', 'readonly');
|
|
268
|
+
const store = tx.objectStore('blobs');
|
|
269
|
+
const req = store.get(filepath);
|
|
270
|
+
// onsuccess handler
|
|
271
|
+
/**
|
|
272
|
+
* onsuccess ハンドラ(内部処理) - 戻り値なし
|
|
273
|
+
* @returns {void}
|
|
274
|
+
*/
|
|
275
|
+
req.onsuccess = () => resolve(req.result ?? null);
|
|
276
|
+
// onerror handler
|
|
277
|
+
/**
|
|
278
|
+
* onerror ハンドラ(内部処理) - 戻り値なし
|
|
279
|
+
* @returns {void}
|
|
280
|
+
*/
|
|
281
|
+
req.onerror = () => reject(req.error);
|
|
282
|
+
});
|
|
283
|
+
}
|
|
284
|
+
/**
|
|
285
|
+
* 指定パスの blob を削除します。
|
|
286
|
+
* @param {string} filepath ファイルパス
|
|
287
|
+
* @returns {Promise<void>}
|
|
288
|
+
*/
|
|
289
|
+
async deleteBlob(filepath) {
|
|
290
|
+
// delete from IndexedDB
|
|
291
|
+
await this.tx('blobs', 'readwrite', (store) => { store.delete(filepath); });
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
exports.BrowserStorage = BrowserStorage;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
export type FileState = 'base' | 'modified' | 'added' | 'deleted' | 'conflict';
|
|
2
|
+
export interface IndexEntry {
|
|
3
|
+
path: string;
|
|
4
|
+
state: FileState;
|
|
5
|
+
baseSha?: string;
|
|
6
|
+
workspaceSha?: string;
|
|
7
|
+
updatedAt: number;
|
|
8
|
+
}
|
|
9
|
+
export interface IndexFile {
|
|
10
|
+
head: string;
|
|
11
|
+
lastCommitKey?: string;
|
|
12
|
+
entries: Record<string, IndexEntry>;
|
|
13
|
+
}
|
|
14
|
+
export interface TombstoneEntry {
|
|
15
|
+
path: string;
|
|
16
|
+
baseSha: string;
|
|
17
|
+
deletedAt: number;
|
|
18
|
+
}
|
|
19
|
+
export interface ConflictEntry {
|
|
20
|
+
path: string;
|
|
21
|
+
baseSha?: string;
|
|
22
|
+
remoteSha?: string;
|
|
23
|
+
workspaceSha?: string;
|
|
24
|
+
}
|
|
25
|
+
export type Change = {
|
|
26
|
+
type: 'create';
|
|
27
|
+
path: string;
|
|
28
|
+
content: string;
|
|
29
|
+
} | {
|
|
30
|
+
type: 'update';
|
|
31
|
+
path: string;
|
|
32
|
+
content: string;
|
|
33
|
+
baseSha: string;
|
|
34
|
+
} | {
|
|
35
|
+
type: 'delete';
|
|
36
|
+
path: string;
|
|
37
|
+
baseSha: string;
|
|
38
|
+
};
|
|
39
|
+
export interface CommitInput {
|
|
40
|
+
message: string;
|
|
41
|
+
parentSha: string;
|
|
42
|
+
changes: Change[];
|
|
43
|
+
ref?: string;
|
|
44
|
+
commitKey?: string;
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/virtualfs/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,UAAU,GAAG,OAAO,GAAG,SAAS,GAAG,UAAU,CAAA;AAE9E,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,SAAS,CAAA;IAChB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,SAAS,EAAE,MAAM,CAAA;CAClB;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAA;IAEZ,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAA;CACpC;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAA;IACf,SAAS,EAAE,MAAM,CAAA;CAClB;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB;AAED,MAAM,MAAM,MAAM,GACd;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GACjD;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAClE;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAA;AAErD,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAA;IACf,SAAS,EAAE,MAAM,CAAA;IACjB,OAAO,EAAE,MAAM,EAAE,CAAA;IACjB,GAAG,CAAC,EAAE,MAAM,CAAA;IAEZ,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB"}
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
import { IndexFile, TombstoneEntry } from './types';
|
|
2
|
+
import { StorageBackend } from './persistence';
|
|
3
|
+
/**
|
|
4
|
+
*
|
|
5
|
+
*/
|
|
6
|
+
export declare class VirtualFS {
|
|
7
|
+
private storageDir;
|
|
8
|
+
private base;
|
|
9
|
+
private workspace;
|
|
10
|
+
private tombstones;
|
|
11
|
+
private index;
|
|
12
|
+
private backend;
|
|
13
|
+
/**
|
|
14
|
+
*
|
|
15
|
+
*/
|
|
16
|
+
constructor(options?: {
|
|
17
|
+
storageDir?: string;
|
|
18
|
+
backend?: StorageBackend;
|
|
19
|
+
});
|
|
20
|
+
/**
|
|
21
|
+
* コンテンツから SHA1 を計算します。
|
|
22
|
+
* @param {string} content コンテンツ
|
|
23
|
+
* @returns {string} 計算された SHA
|
|
24
|
+
*/
|
|
25
|
+
private shaOf;
|
|
26
|
+
/**
|
|
27
|
+
* VirtualFS の初期化を行います(バックエンド初期化と index 読み込み)。
|
|
28
|
+
* @returns {Promise<void>}
|
|
29
|
+
*/
|
|
30
|
+
init(): Promise<void>;
|
|
31
|
+
/**
|
|
32
|
+
* 永続化レイヤーから index を読み込み、内部マップを初期化します。
|
|
33
|
+
* @returns {Promise<void>}
|
|
34
|
+
*/
|
|
35
|
+
private loadIndex;
|
|
36
|
+
/**
|
|
37
|
+
* 内部インデックスを永続化します。
|
|
38
|
+
* @returns {Promise<void>}
|
|
39
|
+
*/
|
|
40
|
+
private saveIndex;
|
|
41
|
+
/**
|
|
42
|
+
*
|
|
43
|
+
*/
|
|
44
|
+
/**
|
|
45
|
+
* ワークスペースにファイルを書き込みます(ローカル編集)。
|
|
46
|
+
* @param {string} filepath ファイルパス
|
|
47
|
+
* @param {string} content コンテンツ
|
|
48
|
+
* @returns {Promise<void>}
|
|
49
|
+
*/
|
|
50
|
+
writeWorkspace(filepath: string, content: string): Promise<void>;
|
|
51
|
+
/**
|
|
52
|
+
* ワークスペース上のファイルを削除します(トゥームストーン作成を含む)。
|
|
53
|
+
* @param {string} filepath ファイルパス
|
|
54
|
+
* @returns {Promise<void>}
|
|
55
|
+
*/
|
|
56
|
+
deleteWorkspace(filepath: string): Promise<void>;
|
|
57
|
+
/**
|
|
58
|
+
* rename を delete + create の合成で行うヘルパ
|
|
59
|
+
* @param from 元パス
|
|
60
|
+
* @param to 新パス
|
|
61
|
+
*/
|
|
62
|
+
renameWorkspace(from: string, to: string): Promise<void>;
|
|
63
|
+
/**
|
|
64
|
+
* ワークスペース/ベースからファイル内容を読み出します。
|
|
65
|
+
* @param {string} filepath ファイルパス
|
|
66
|
+
* @returns {Promise<string|null>} ファイル内容または null
|
|
67
|
+
*/
|
|
68
|
+
readWorkspace(filepath: string): Promise<string | null>;
|
|
69
|
+
/**
|
|
70
|
+
* リモートのベーススナップショットを適用します。
|
|
71
|
+
* @param {{[path:string]:string}} snapshot path->content のマップ
|
|
72
|
+
* @param {string} headSha リモート HEAD
|
|
73
|
+
* @returns {Promise<void>}
|
|
74
|
+
*/
|
|
75
|
+
applyBaseSnapshot(snapshot: Record<string, string>, headSha: string): Promise<void>;
|
|
76
|
+
/**
|
|
77
|
+
* インデックス情報を返します。
|
|
78
|
+
* @returns {IndexFile}
|
|
79
|
+
*/
|
|
80
|
+
getIndex(): IndexFile;
|
|
81
|
+
/**
|
|
82
|
+
* 登録されているパス一覧を返します。
|
|
83
|
+
* @returns {string[]}
|
|
84
|
+
*/
|
|
85
|
+
listPaths(): string[];
|
|
86
|
+
/**
|
|
87
|
+
* tombstone を返します。
|
|
88
|
+
* @returns {TombstoneEntry[]}
|
|
89
|
+
*/
|
|
90
|
+
getTombstones(): TombstoneEntry[];
|
|
91
|
+
/**
|
|
92
|
+
* tombstone を返します。
|
|
93
|
+
* @returns {TombstoneEntry[]}
|
|
94
|
+
*/
|
|
95
|
+
/**
|
|
96
|
+
*
|
|
97
|
+
*/
|
|
98
|
+
getChangeSet(): Promise<({
|
|
99
|
+
type: 'create';
|
|
100
|
+
path: string;
|
|
101
|
+
content: string;
|
|
102
|
+
} | {
|
|
103
|
+
type: 'update';
|
|
104
|
+
path: string;
|
|
105
|
+
content: string;
|
|
106
|
+
baseSha?: string | undefined;
|
|
107
|
+
} | {
|
|
108
|
+
type: 'delete';
|
|
109
|
+
path: string;
|
|
110
|
+
baseSha: string;
|
|
111
|
+
})[]>;
|
|
112
|
+
/**
|
|
113
|
+
* tombstone からの削除変更リストを生成します。
|
|
114
|
+
* @returns {Array<{type:'delete',path:string,baseSha:string}>}
|
|
115
|
+
*/
|
|
116
|
+
private _changesFromTombstones;
|
|
117
|
+
/**
|
|
118
|
+
* index entries から create/update の変更リストを生成します。
|
|
119
|
+
* @returns {Array<{type:'create'|'update',path:string,content:string,baseSha?:string}>}
|
|
120
|
+
*/
|
|
121
|
+
private _changesFromIndexEntries;
|
|
122
|
+
/**
|
|
123
|
+
* 追加状態のエントリから create 変更を生成します。
|
|
124
|
+
* @returns {Array<{type:'create',path:string,content:string}>}
|
|
125
|
+
*/
|
|
126
|
+
private _changesFromAddedEntries;
|
|
127
|
+
/**
|
|
128
|
+
* 変更状態のエントリから update 変更を生成します。
|
|
129
|
+
* @returns {Array<{type:'update',path:string,content:string,baseSha:string}>}
|
|
130
|
+
*/
|
|
131
|
+
private _changesFromModifiedEntries;
|
|
132
|
+
/**
|
|
133
|
+
* リモートスナップショットからの差分取り込み時に、単一パスを評価して
|
|
134
|
+
* 必要なら conflicts に追加、もしくは base を更新します。
|
|
135
|
+
* @returns {Promise<void>}
|
|
136
|
+
*/
|
|
137
|
+
private _handleRemotePath;
|
|
138
|
+
/**
|
|
139
|
+
* リモートに存在するがローカルにないパスを処理します。
|
|
140
|
+
* @returns {Promise<void>}
|
|
141
|
+
*/
|
|
142
|
+
private _handleRemoteNew;
|
|
143
|
+
/**
|
|
144
|
+
* リモートに存在し、かつローカルにエントリがあるパスを処理します。
|
|
145
|
+
* @returns {Promise<void>}
|
|
146
|
+
*/
|
|
147
|
+
private _handleRemoteExisting;
|
|
148
|
+
/**
|
|
149
|
+
* ローカルに対する変更(create/update/delete)を適用するヘルパー
|
|
150
|
+
* @param {any} ch 変更オブジェクト
|
|
151
|
+
* @returns {Promise<void>}
|
|
152
|
+
*/
|
|
153
|
+
private _applyChangeLocally;
|
|
154
|
+
/**
|
|
155
|
+
* リモート側で削除されたエントリをローカルに反映します。
|
|
156
|
+
* @returns {Promise<void>}
|
|
157
|
+
*/
|
|
158
|
+
private _handleRemoteDeletion;
|
|
159
|
+
/**
|
|
160
|
+
* GitLab 風の actions ベースコミットフローで push を実行します。
|
|
161
|
+
* @returns {Promise<{commitSha:string}>}
|
|
162
|
+
*/
|
|
163
|
+
private _pushWithActions;
|
|
164
|
+
/**
|
|
165
|
+
* GitHub 風の blob/tree/commit フローで push を実行します。
|
|
166
|
+
* @returns {Promise<{commitSha:string}>}
|
|
167
|
+
*/
|
|
168
|
+
private _pushWithGitHubFlow;
|
|
169
|
+
/**
|
|
170
|
+
* リモートのスナップショットを取り込み、コンフリクト情報を返します。
|
|
171
|
+
* @param {string} remoteHead リモート HEAD
|
|
172
|
+
* @param {{[path:string]:string}} baseSnapshot path->content マップ
|
|
173
|
+
* @returns {Promise<{conflicts:Array<import('./types').ConflictEntry>}>}
|
|
174
|
+
*/
|
|
175
|
+
pull(remoteHead: string, baseSnapshot: Record<string, string>): Promise<{
|
|
176
|
+
conflicts: import("./types").ConflictEntry[];
|
|
177
|
+
}>;
|
|
178
|
+
/**
|
|
179
|
+
* 変更をコミットしてリモートへ反映します。adapter が無ければローカルシミュレーションします。
|
|
180
|
+
* @param {import('./types').CommitInput} input コミット入力
|
|
181
|
+
* @param {import('../git/adapter').GitAdapter} [adapter] 任意のアダプタ
|
|
182
|
+
* @returns {Promise<{commitSha:string}>}
|
|
183
|
+
*/
|
|
184
|
+
push(input: import('./types').CommitInput, adapter?: import('../git/adapter').GitAdapter): Promise<{
|
|
185
|
+
commitSha: any;
|
|
186
|
+
}>;
|
|
187
|
+
}
|
|
188
|
+
export default VirtualFS;
|
|
189
|
+
//# sourceMappingURL=virtualfs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"virtualfs.d.ts","sourceRoot":"","sources":["../../src/virtualfs/virtualfs.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,SAAS,CAAA;AACnD,OAAO,EAAE,cAAc,EAAiB,MAAM,eAAe,CAAA;AAE7D;;GAEG;AACH,qBAAa,SAAS;IACpB,OAAO,CAAC,UAAU,CAAoB;IACtC,OAAO,CAAC,IAAI,CAAsD;IAClE,OAAO,CAAC,SAAS,CAAsD;IACvE,OAAO,CAAC,UAAU,CAAoC;IACtD,OAAO,CAAC,KAAK,CAAuC;IACpD,OAAO,CAAC,OAAO,CAAgB;IAE/B;;OAEG;gBACS,OAAO,CAAC,EAAE;QAAE,UAAU,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,cAAc,CAAA;KAAE;IAOvE;;;;OAIG;IACH,OAAO,CAAC,KAAK;IAIb;;;OAGG;IACG,IAAI;IAKV;;;OAGG;YACW,SAAS;IAmBvB;;;OAGG;YACW,SAAS;IAIvB;;OAEG;IACH;;;;;OAKG;IACG,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM;IAkBtD;;;;OAIG;IACG,eAAe,CAAC,QAAQ,EAAE,MAAM;IAqBtC;;;;OAIG;IACG,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM;IAa9C;;;;OAIG;IACG,aAAa,CAAC,QAAQ,EAAE,MAAM;IAWpC;;;;;OAKG;IACG,iBAAiB,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,MAAM;IA2BzE;;;OAGG;IACH,QAAQ,IAAI,SAAS;IAIrB;;;OAGG;IACH,SAAS,IAAI,MAAM,EAAE;IAIrB;;;OAGG;IACH,aAAa,IAAI,cAAc,EAAE;IAIjC;;;OAGG;IAEH;;OAEG;IACG,YAAY;cAGJ,QAAQ;cAAQ,MAAM;iBAAW,MAAM;;cACvC,QAAQ;cAAQ,MAAM;iBAAW,MAAM;;;cACvC,QAAQ;cAAQ,MAAM;iBAAW,MAAM;;IAQrD;;;OAGG;IACH,OAAO,CAAC,sBAAsB;IAM9B;;;OAGG;IACH,OAAO,CAAC,wBAAwB;IAOhC;;;OAGG;IACH,OAAO,CAAC,wBAAwB;IAWhC;;;OAGG;IACH,OAAO,CAAC,2BAA2B;IAWnC;;;;OAIG;YACW,iBAAiB;IAS/B;;;OAGG;YACW,gBAAgB;IAa9B;;;OAGG;YACW,qBAAqB;IAkBnC;;;;OAIG;YACW,mBAAmB;IAqBjC;;;OAGG;YACW,qBAAqB;IAYnC;;;OAGG;YACW,gBAAgB;IAe9B;;;OAGG;YACW,mBAAmB;IAkBjC;;;;;OAKG;IACG,IAAI,CAAC,UAAU,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;;;IA6BnE;;;;;OAKG;IACG,IAAI,CAAC,KAAK,EAAE,OAAO,SAAS,EAAE,WAAW,EAAE,OAAO,CAAC,EAAE,OAAO,gBAAgB,EAAE,UAAU;;;CAkD/F;AAED,eAAe,SAAS,CAAA"}
|