@interactive-inc/docs-client 1.0.19 → 1.0.20
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/.env.local +3 -0
- package/build/index.d.ts +847 -243
- package/build/index.js +1386 -240
- package/package.json +3 -2
package/build/index.js
CHANGED
|
@@ -5138,9 +5138,9 @@ var DocClient = class {
|
|
|
5138
5138
|
}
|
|
5139
5139
|
};
|
|
5140
5140
|
|
|
5141
|
-
// lib/doc-file-system.ts
|
|
5141
|
+
// lib/doc-file-system-read.ts
|
|
5142
5142
|
import * as fs from "fs/promises";
|
|
5143
|
-
var
|
|
5143
|
+
var DocFileSystemRead = class {
|
|
5144
5144
|
basePath;
|
|
5145
5145
|
pathSystem;
|
|
5146
5146
|
constructor(props) {
|
|
@@ -5160,32 +5160,6 @@ var DocFileSystem = class {
|
|
|
5160
5160
|
return error instanceof Error ? error : new Error(`Failed to read file at ${relativePath}`);
|
|
5161
5161
|
}
|
|
5162
5162
|
}
|
|
5163
|
-
/**
|
|
5164
|
-
* Write content to file at the specified path (creates directory if needed)
|
|
5165
|
-
*/
|
|
5166
|
-
async writeFile(relativePath, content) {
|
|
5167
|
-
try {
|
|
5168
|
-
const fullPath = this.pathSystem.join(this.basePath, relativePath);
|
|
5169
|
-
const dirPath = this.pathSystem.dirname(fullPath);
|
|
5170
|
-
await fs.mkdir(dirPath, { recursive: true });
|
|
5171
|
-
await fs.writeFile(fullPath, content, "utf-8");
|
|
5172
|
-
return null;
|
|
5173
|
-
} catch (error) {
|
|
5174
|
-
return error instanceof Error ? error : new Error(`Failed to write file at ${relativePath}`);
|
|
5175
|
-
}
|
|
5176
|
-
}
|
|
5177
|
-
/**
|
|
5178
|
-
* Delete file at the specified path
|
|
5179
|
-
*/
|
|
5180
|
-
async deleteFile(relativePath) {
|
|
5181
|
-
try {
|
|
5182
|
-
const fullPath = this.pathSystem.join(this.basePath, relativePath);
|
|
5183
|
-
await fs.unlink(fullPath);
|
|
5184
|
-
return null;
|
|
5185
|
-
} catch (error) {
|
|
5186
|
-
return new Error(`Failed to delete file at ${relativePath}: ${error}`);
|
|
5187
|
-
}
|
|
5188
|
-
}
|
|
5189
5163
|
/**
|
|
5190
5164
|
* Get file name from path
|
|
5191
5165
|
*/
|
|
@@ -5289,27 +5263,90 @@ var DocFileSystem = class {
|
|
|
5289
5263
|
return this.pathSystem.join(this.basePath, relativePath);
|
|
5290
5264
|
}
|
|
5291
5265
|
/**
|
|
5292
|
-
*
|
|
5266
|
+
* Get file size in bytes
|
|
5293
5267
|
*/
|
|
5294
|
-
async
|
|
5268
|
+
async getFileSize(relativePath) {
|
|
5295
5269
|
try {
|
|
5296
5270
|
const fullPath = this.pathSystem.join(this.basePath, relativePath);
|
|
5297
|
-
await fs.
|
|
5298
|
-
return
|
|
5271
|
+
const stats = await fs.stat(fullPath);
|
|
5272
|
+
return stats.size;
|
|
5299
5273
|
} catch (error) {
|
|
5300
|
-
return error instanceof Error ? error : new Error(`Failed to
|
|
5274
|
+
return error instanceof Error ? error : new Error(`Failed to get file size at ${relativePath}`);
|
|
5301
5275
|
}
|
|
5302
5276
|
}
|
|
5303
5277
|
/**
|
|
5304
|
-
* Get file
|
|
5278
|
+
* Get file last modified time
|
|
5305
5279
|
*/
|
|
5306
|
-
async
|
|
5280
|
+
async getFileModifiedTime(relativePath) {
|
|
5307
5281
|
try {
|
|
5308
5282
|
const fullPath = this.pathSystem.join(this.basePath, relativePath);
|
|
5309
5283
|
const stats = await fs.stat(fullPath);
|
|
5310
|
-
return stats.
|
|
5284
|
+
return stats.mtime;
|
|
5311
5285
|
} catch (error) {
|
|
5312
|
-
return error instanceof Error ? error : new Error(`Failed to get file
|
|
5286
|
+
return error instanceof Error ? error : new Error(`Failed to get file modified time at ${relativePath}`);
|
|
5287
|
+
}
|
|
5288
|
+
}
|
|
5289
|
+
/**
|
|
5290
|
+
* Get file creation time
|
|
5291
|
+
*/
|
|
5292
|
+
async getFileCreatedTime(relativePath) {
|
|
5293
|
+
try {
|
|
5294
|
+
const fullPath = this.pathSystem.join(this.basePath, relativePath);
|
|
5295
|
+
const stats = await fs.stat(fullPath);
|
|
5296
|
+
return stats.birthtime;
|
|
5297
|
+
} catch (error) {
|
|
5298
|
+
return error instanceof Error ? error : new Error(`Failed to get file created time at ${relativePath}`);
|
|
5299
|
+
}
|
|
5300
|
+
}
|
|
5301
|
+
};
|
|
5302
|
+
|
|
5303
|
+
// lib/doc-file-system-write.ts
|
|
5304
|
+
import * as fs2 from "fs/promises";
|
|
5305
|
+
var DocFileSystemWrite = class {
|
|
5306
|
+
basePath;
|
|
5307
|
+
pathSystem;
|
|
5308
|
+
reader;
|
|
5309
|
+
constructor(props) {
|
|
5310
|
+
this.basePath = props.basePath;
|
|
5311
|
+
this.pathSystem = props.pathSystem ?? new DocPathSystem();
|
|
5312
|
+
this.reader = props.reader;
|
|
5313
|
+
}
|
|
5314
|
+
/**
|
|
5315
|
+
* Write content to file at the specified path (creates directory if needed)
|
|
5316
|
+
*/
|
|
5317
|
+
async writeFile(relativePath, content) {
|
|
5318
|
+
try {
|
|
5319
|
+
const fullPath = this.pathSystem.join(this.basePath, relativePath);
|
|
5320
|
+
const dirPath = this.pathSystem.dirname(fullPath);
|
|
5321
|
+
await fs2.mkdir(dirPath, { recursive: true });
|
|
5322
|
+
await fs2.writeFile(fullPath, content, "utf-8");
|
|
5323
|
+
return null;
|
|
5324
|
+
} catch (error) {
|
|
5325
|
+
return error instanceof Error ? error : new Error(`Failed to write file at ${relativePath}`);
|
|
5326
|
+
}
|
|
5327
|
+
}
|
|
5328
|
+
/**
|
|
5329
|
+
* Delete file at the specified path
|
|
5330
|
+
*/
|
|
5331
|
+
async deleteFile(relativePath) {
|
|
5332
|
+
try {
|
|
5333
|
+
const fullPath = this.pathSystem.join(this.basePath, relativePath);
|
|
5334
|
+
await fs2.unlink(fullPath);
|
|
5335
|
+
return null;
|
|
5336
|
+
} catch (error) {
|
|
5337
|
+
return new Error(`Failed to delete file at ${relativePath}: ${error}`);
|
|
5338
|
+
}
|
|
5339
|
+
}
|
|
5340
|
+
/**
|
|
5341
|
+
* Create directory
|
|
5342
|
+
*/
|
|
5343
|
+
async createDirectory(relativePath) {
|
|
5344
|
+
try {
|
|
5345
|
+
const fullPath = this.pathSystem.join(this.basePath, relativePath);
|
|
5346
|
+
await fs2.mkdir(fullPath, { recursive: true });
|
|
5347
|
+
return null;
|
|
5348
|
+
} catch (error) {
|
|
5349
|
+
return error instanceof Error ? error : new Error(`Failed to create directory at ${relativePath}`);
|
|
5313
5350
|
}
|
|
5314
5351
|
}
|
|
5315
5352
|
/**
|
|
@@ -5317,12 +5354,16 @@ var DocFileSystem = class {
|
|
|
5317
5354
|
*/
|
|
5318
5355
|
async ensureDirectoryExists(relativePath) {
|
|
5319
5356
|
try {
|
|
5320
|
-
if (
|
|
5321
|
-
const
|
|
5322
|
-
if (
|
|
5323
|
-
return
|
|
5357
|
+
if (this.reader) {
|
|
5358
|
+
const exists = await this.reader.exists(relativePath);
|
|
5359
|
+
if (exists) {
|
|
5360
|
+
return null;
|
|
5324
5361
|
}
|
|
5325
5362
|
}
|
|
5363
|
+
const result = await this.createDirectory(relativePath);
|
|
5364
|
+
if (result instanceof Error) {
|
|
5365
|
+
return result;
|
|
5366
|
+
}
|
|
5326
5367
|
return null;
|
|
5327
5368
|
} catch (error) {
|
|
5328
5369
|
return error instanceof Error ? error : new Error(`Failed to ensure directory exists at ${relativePath}`);
|
|
@@ -5335,7 +5376,7 @@ var DocFileSystem = class {
|
|
|
5335
5376
|
try {
|
|
5336
5377
|
const sourceFullPath = this.pathSystem.join(this.basePath, sourcePath);
|
|
5337
5378
|
const destFullPath = this.pathSystem.join(this.basePath, destinationPath);
|
|
5338
|
-
await
|
|
5379
|
+
await fs2.copyFile(sourceFullPath, destFullPath);
|
|
5339
5380
|
return null;
|
|
5340
5381
|
} catch (error) {
|
|
5341
5382
|
return error instanceof Error ? error : new Error(
|
|
@@ -5350,7 +5391,7 @@ var DocFileSystem = class {
|
|
|
5350
5391
|
try {
|
|
5351
5392
|
const sourceFullPath = this.pathSystem.join(this.basePath, sourcePath);
|
|
5352
5393
|
const destFullPath = this.pathSystem.join(this.basePath, destinationPath);
|
|
5353
|
-
await
|
|
5394
|
+
await fs2.rename(sourceFullPath, destFullPath);
|
|
5354
5395
|
return null;
|
|
5355
5396
|
} catch (error) {
|
|
5356
5397
|
return error instanceof Error ? error : new Error(
|
|
@@ -5358,151 +5399,783 @@ var DocFileSystem = class {
|
|
|
5358
5399
|
);
|
|
5359
5400
|
}
|
|
5360
5401
|
}
|
|
5402
|
+
};
|
|
5403
|
+
|
|
5404
|
+
// lib/doc-file-system.ts
|
|
5405
|
+
var DocFileSystem = class {
|
|
5406
|
+
reader;
|
|
5407
|
+
writer;
|
|
5408
|
+
basePath;
|
|
5409
|
+
pathSystem;
|
|
5410
|
+
constructor(props) {
|
|
5411
|
+
this.basePath = props.basePath;
|
|
5412
|
+
this.pathSystem = props.pathSystem ?? new DocPathSystem();
|
|
5413
|
+
this.reader = props.reader ?? new DocFileSystemRead({
|
|
5414
|
+
basePath: this.basePath,
|
|
5415
|
+
pathSystem: this.pathSystem
|
|
5416
|
+
});
|
|
5417
|
+
this.writer = props.writer ?? new DocFileSystemWrite({
|
|
5418
|
+
basePath: this.basePath,
|
|
5419
|
+
pathSystem: this.pathSystem,
|
|
5420
|
+
reader: this.reader
|
|
5421
|
+
});
|
|
5422
|
+
}
|
|
5361
5423
|
/**
|
|
5362
|
-
*
|
|
5424
|
+
* Read file content at the specified path
|
|
5363
5425
|
*/
|
|
5364
|
-
async
|
|
5365
|
-
|
|
5366
|
-
const fullPath = this.pathSystem.join(this.basePath, relativePath);
|
|
5367
|
-
const stats = await fs.stat(fullPath);
|
|
5368
|
-
return stats.mtime;
|
|
5369
|
-
} catch (error) {
|
|
5370
|
-
return error instanceof Error ? error : new Error(`Failed to get file modified time at ${relativePath}`);
|
|
5371
|
-
}
|
|
5426
|
+
async readFile(relativePath) {
|
|
5427
|
+
return this.reader.readFile(relativePath);
|
|
5372
5428
|
}
|
|
5373
5429
|
/**
|
|
5374
|
-
*
|
|
5430
|
+
* Write content to file at the specified path (creates directory if needed)
|
|
5375
5431
|
*/
|
|
5376
|
-
async
|
|
5377
|
-
|
|
5378
|
-
const fullPath = this.pathSystem.join(this.basePath, relativePath);
|
|
5379
|
-
const stats = await fs.stat(fullPath);
|
|
5380
|
-
return stats.birthtime;
|
|
5381
|
-
} catch (error) {
|
|
5382
|
-
return error instanceof Error ? error : new Error(`Failed to get file created time at ${relativePath}`);
|
|
5383
|
-
}
|
|
5432
|
+
async writeFile(relativePath, content) {
|
|
5433
|
+
return this.writer.writeFile(relativePath, content);
|
|
5384
5434
|
}
|
|
5385
|
-
|
|
5386
|
-
|
|
5387
|
-
|
|
5388
|
-
|
|
5389
|
-
|
|
5390
|
-
icon: \u{1F4DA}
|
|
5391
|
-
---
|
|
5392
|
-
|
|
5393
|
-
# Documentation
|
|
5394
|
-
|
|
5395
|
-
Welcome to the documentation!`,
|
|
5396
|
-
"docs/guide/index.md": `---
|
|
5397
|
-
icon: \u{1F4D6}
|
|
5398
|
-
---
|
|
5399
|
-
|
|
5400
|
-
# Guide
|
|
5401
|
-
|
|
5402
|
-
This is a guide.`,
|
|
5403
|
-
"docs/guide/getting-started.md": `# Getting Started
|
|
5404
|
-
|
|
5405
|
-
Let's get started!`,
|
|
5406
|
-
"docs/guide/advanced.md": `# Advanced
|
|
5407
|
-
|
|
5408
|
-
Advanced topics here.`,
|
|
5409
|
-
"docs/api/index.md": `---
|
|
5410
|
-
icon: \u{1F527}
|
|
5411
|
-
---
|
|
5412
|
-
|
|
5413
|
-
# API
|
|
5414
|
-
|
|
5415
|
-
API documentation.`,
|
|
5416
|
-
"docs/api/reference.md": `# API Reference
|
|
5417
|
-
|
|
5418
|
-
Complete API reference.`
|
|
5419
|
-
};
|
|
5420
|
-
var DocFileSystemMock = class _DocFileSystemMock extends DocFileSystem {
|
|
5421
|
-
files = /* @__PURE__ */ new Map();
|
|
5422
|
-
_pathSystem;
|
|
5423
|
-
_basePath;
|
|
5424
|
-
constructor(props) {
|
|
5425
|
-
super(props);
|
|
5426
|
-
this._pathSystem = props.pathSystem;
|
|
5427
|
-
this._basePath = props.basePath.endsWith("/") ? props.basePath.slice(0, -1) : props.basePath;
|
|
5428
|
-
if (!props.skipDefaultFiles) {
|
|
5429
|
-
this.setupTestFiles(mockDirectoryData);
|
|
5430
|
-
}
|
|
5431
|
-
Object.freeze(this);
|
|
5435
|
+
/**
|
|
5436
|
+
* Delete file at the specified path
|
|
5437
|
+
*/
|
|
5438
|
+
async deleteFile(relativePath) {
|
|
5439
|
+
return this.writer.deleteFile(relativePath);
|
|
5432
5440
|
}
|
|
5433
5441
|
/**
|
|
5434
|
-
*
|
|
5442
|
+
* Get file name from path
|
|
5435
5443
|
*/
|
|
5436
|
-
|
|
5437
|
-
return this.
|
|
5444
|
+
readFileName(relativePath) {
|
|
5445
|
+
return this.reader.readFileName(relativePath);
|
|
5438
5446
|
}
|
|
5439
5447
|
/**
|
|
5440
|
-
*
|
|
5448
|
+
* Get file extension from path
|
|
5441
5449
|
*/
|
|
5442
|
-
|
|
5443
|
-
|
|
5444
|
-
return filePath;
|
|
5445
|
-
}
|
|
5446
|
-
const cleanPath = filePath.startsWith("/") ? filePath.slice(1) : filePath;
|
|
5447
|
-
return `${this._basePath}/${cleanPath}`;
|
|
5450
|
+
readFileExtension(relativePath) {
|
|
5451
|
+
return this.reader.readFileExtension(relativePath);
|
|
5448
5452
|
}
|
|
5449
5453
|
/**
|
|
5450
|
-
*
|
|
5454
|
+
* Get directory path where the file exists
|
|
5451
5455
|
*/
|
|
5452
|
-
|
|
5453
|
-
|
|
5454
|
-
return new _DocFileSystemMock({ basePath, pathSystem });
|
|
5456
|
+
readFileDirectory(relativePath) {
|
|
5457
|
+
return this.reader.readFileDirectory(relativePath);
|
|
5455
5458
|
}
|
|
5456
5459
|
/**
|
|
5457
|
-
*
|
|
5460
|
+
* Get list of entries in directory
|
|
5458
5461
|
*/
|
|
5459
|
-
|
|
5460
|
-
|
|
5461
|
-
const basePath = props.basePath ?? "/test";
|
|
5462
|
-
const fileSystem = new _DocFileSystemMock({
|
|
5463
|
-
basePath,
|
|
5464
|
-
pathSystem,
|
|
5465
|
-
skipDefaultFiles: true
|
|
5466
|
-
});
|
|
5467
|
-
if (props.fileContents) {
|
|
5468
|
-
const now = /* @__PURE__ */ new Date();
|
|
5469
|
-
for (const [path, content] of Object.entries(props.fileContents)) {
|
|
5470
|
-
const cleanPath = path.startsWith("/") ? path.slice(1) : path;
|
|
5471
|
-
const normalizedPath = path.startsWith(basePath) ? path : `${basePath}/${cleanPath}`;
|
|
5472
|
-
fileSystem.files.set(normalizedPath, {
|
|
5473
|
-
content,
|
|
5474
|
-
modifiedTime: now,
|
|
5475
|
-
createdTime: now,
|
|
5476
|
-
size: new TextEncoder().encode(content).length
|
|
5477
|
-
});
|
|
5478
|
-
}
|
|
5479
|
-
}
|
|
5480
|
-
return fileSystem;
|
|
5462
|
+
async readDirectoryFileNames(relativePath = "") {
|
|
5463
|
+
return this.reader.readDirectoryFileNames(relativePath);
|
|
5481
5464
|
}
|
|
5482
|
-
async
|
|
5483
|
-
|
|
5484
|
-
const normalizedPath = this.normalizePath(filePath);
|
|
5485
|
-
const file = this.files.get(normalizedPath);
|
|
5486
|
-
return file ? file.content : null;
|
|
5487
|
-
} catch (error) {
|
|
5488
|
-
return error instanceof Error ? error : new Error(`Failed to read file at ${filePath}`);
|
|
5489
|
-
}
|
|
5465
|
+
async readDirectoryFilePaths(relativePath) {
|
|
5466
|
+
return this.reader.readDirectoryFilePaths(relativePath);
|
|
5490
5467
|
}
|
|
5491
|
-
|
|
5492
|
-
|
|
5493
|
-
|
|
5494
|
-
|
|
5495
|
-
|
|
5496
|
-
|
|
5497
|
-
|
|
5498
|
-
|
|
5499
|
-
|
|
5500
|
-
|
|
5501
|
-
|
|
5502
|
-
|
|
5503
|
-
|
|
5504
|
-
|
|
5505
|
-
|
|
5468
|
+
/**
|
|
5469
|
+
* Check if path is a directory
|
|
5470
|
+
*/
|
|
5471
|
+
async isDirectory(relativePath) {
|
|
5472
|
+
return this.reader.isDirectory(relativePath);
|
|
5473
|
+
}
|
|
5474
|
+
/**
|
|
5475
|
+
* Check if path is a file
|
|
5476
|
+
*/
|
|
5477
|
+
async isFile(relativePath) {
|
|
5478
|
+
return this.reader.isFile(relativePath);
|
|
5479
|
+
}
|
|
5480
|
+
/**
|
|
5481
|
+
* Check if file or directory exists
|
|
5482
|
+
*/
|
|
5483
|
+
async exists(relativePath) {
|
|
5484
|
+
return this.reader.exists(relativePath);
|
|
5485
|
+
}
|
|
5486
|
+
/**
|
|
5487
|
+
* Check if directory exists
|
|
5488
|
+
*/
|
|
5489
|
+
async directoryExists(relativePath) {
|
|
5490
|
+
return this.reader.directoryExists(relativePath);
|
|
5491
|
+
}
|
|
5492
|
+
/**
|
|
5493
|
+
* Check if file exists
|
|
5494
|
+
*/
|
|
5495
|
+
async fileExists(relativePath) {
|
|
5496
|
+
return this.reader.fileExists(relativePath);
|
|
5497
|
+
}
|
|
5498
|
+
/**
|
|
5499
|
+
* Get base path
|
|
5500
|
+
*/
|
|
5501
|
+
getBasePath() {
|
|
5502
|
+
return this.reader.getBasePath();
|
|
5503
|
+
}
|
|
5504
|
+
/**
|
|
5505
|
+
* Convert relative path to absolute path
|
|
5506
|
+
*/
|
|
5507
|
+
resolve(relativePath) {
|
|
5508
|
+
return this.reader.resolve(relativePath);
|
|
5509
|
+
}
|
|
5510
|
+
/**
|
|
5511
|
+
* Create directory
|
|
5512
|
+
*/
|
|
5513
|
+
async createDirectory(relativePath) {
|
|
5514
|
+
return this.writer.createDirectory(relativePath);
|
|
5515
|
+
}
|
|
5516
|
+
/**
|
|
5517
|
+
* Get file size in bytes
|
|
5518
|
+
*/
|
|
5519
|
+
async getFileSize(relativePath) {
|
|
5520
|
+
return this.reader.getFileSize(relativePath);
|
|
5521
|
+
}
|
|
5522
|
+
/**
|
|
5523
|
+
* Create directory if it doesn't exist
|
|
5524
|
+
*/
|
|
5525
|
+
async ensureDirectoryExists(relativePath) {
|
|
5526
|
+
return this.writer.ensureDirectoryExists(relativePath);
|
|
5527
|
+
}
|
|
5528
|
+
/**
|
|
5529
|
+
* Copy file
|
|
5530
|
+
*/
|
|
5531
|
+
async copyFile(sourcePath, destinationPath) {
|
|
5532
|
+
return this.writer.copyFile(sourcePath, destinationPath);
|
|
5533
|
+
}
|
|
5534
|
+
/**
|
|
5535
|
+
* Move file
|
|
5536
|
+
*/
|
|
5537
|
+
async moveFile(sourcePath, destinationPath) {
|
|
5538
|
+
return this.writer.moveFile(sourcePath, destinationPath);
|
|
5539
|
+
}
|
|
5540
|
+
/**
|
|
5541
|
+
* Get file last modified time
|
|
5542
|
+
*/
|
|
5543
|
+
async getFileModifiedTime(relativePath) {
|
|
5544
|
+
return this.reader.getFileModifiedTime(relativePath);
|
|
5545
|
+
}
|
|
5546
|
+
/**
|
|
5547
|
+
* Get file creation time
|
|
5548
|
+
*/
|
|
5549
|
+
async getFileCreatedTime(relativePath) {
|
|
5550
|
+
return this.reader.getFileCreatedTime(relativePath);
|
|
5551
|
+
}
|
|
5552
|
+
};
|
|
5553
|
+
|
|
5554
|
+
// lib/doc-file-system-json.ts
|
|
5555
|
+
import { z as z4 } from "zod";
|
|
5556
|
+
|
|
5557
|
+
// lib/doc-file-system-json-read.ts
|
|
5558
|
+
import { z as z2 } from "zod";
|
|
5559
|
+
var zJsonDocumentData = z2.record(z2.string(), z2.string());
|
|
5560
|
+
function parseJsonDocumentData(data) {
|
|
5561
|
+
try {
|
|
5562
|
+
return zJsonDocumentData.parse(data);
|
|
5563
|
+
} catch (error) {
|
|
5564
|
+
return error instanceof Error ? error : new Error("Failed to parse JSON document data");
|
|
5565
|
+
}
|
|
5566
|
+
}
|
|
5567
|
+
var DocFileSystemJsonRead = class {
|
|
5568
|
+
data;
|
|
5569
|
+
basePath;
|
|
5570
|
+
pathSystem;
|
|
5571
|
+
constructor(props) {
|
|
5572
|
+
const parsed = parseJsonDocumentData(props.data);
|
|
5573
|
+
if (parsed instanceof Error) {
|
|
5574
|
+
throw parsed;
|
|
5575
|
+
}
|
|
5576
|
+
this.data = parsed;
|
|
5577
|
+
this.basePath = props.basePath ?? "json://";
|
|
5578
|
+
this.pathSystem = props.pathSystem ?? new DocPathSystem();
|
|
5579
|
+
Object.freeze(this);
|
|
5580
|
+
}
|
|
5581
|
+
/**
|
|
5582
|
+
* Read file content from JSON data
|
|
5583
|
+
*/
|
|
5584
|
+
async readFile(relativePath) {
|
|
5585
|
+
try {
|
|
5586
|
+
const normalizedPath = this.normalizePath(relativePath);
|
|
5587
|
+
const content = this.data[normalizedPath];
|
|
5588
|
+
return content ?? null;
|
|
5589
|
+
} catch (error) {
|
|
5590
|
+
return error instanceof Error ? error : new Error(`Failed to read file at ${relativePath}`);
|
|
5591
|
+
}
|
|
5592
|
+
}
|
|
5593
|
+
/**
|
|
5594
|
+
* Get file name from path
|
|
5595
|
+
*/
|
|
5596
|
+
readFileName(relativePath) {
|
|
5597
|
+
return this.pathSystem.basename(relativePath);
|
|
5598
|
+
}
|
|
5599
|
+
/**
|
|
5600
|
+
* Get file extension from path
|
|
5601
|
+
*/
|
|
5602
|
+
readFileExtension(relativePath) {
|
|
5603
|
+
return this.pathSystem.extname(relativePath);
|
|
5604
|
+
}
|
|
5605
|
+
/**
|
|
5606
|
+
* Get directory path where the file exists
|
|
5607
|
+
*/
|
|
5608
|
+
readFileDirectory(relativePath) {
|
|
5609
|
+
return this.pathSystem.dirname(relativePath);
|
|
5610
|
+
}
|
|
5611
|
+
/**
|
|
5612
|
+
* Get list of file names in directory
|
|
5613
|
+
*/
|
|
5614
|
+
async readDirectoryFileNames(relativePath = "") {
|
|
5615
|
+
try {
|
|
5616
|
+
const normalizedDir = this.normalizePath(relativePath);
|
|
5617
|
+
const fileNames = /* @__PURE__ */ new Set();
|
|
5618
|
+
for (const filePath of Object.keys(this.data)) {
|
|
5619
|
+
if (this.isFileInDirectory(filePath, normalizedDir)) {
|
|
5620
|
+
const relativePart = this.getRelativePartFromDirectory(
|
|
5621
|
+
filePath,
|
|
5622
|
+
normalizedDir
|
|
5623
|
+
);
|
|
5624
|
+
const segments = relativePart.split("/").filter(Boolean);
|
|
5625
|
+
if (segments.length > 0) {
|
|
5626
|
+
fileNames.add(segments[0]);
|
|
5627
|
+
}
|
|
5628
|
+
}
|
|
5629
|
+
}
|
|
5630
|
+
return Array.from(fileNames).sort();
|
|
5631
|
+
} catch (error) {
|
|
5632
|
+
return error instanceof Error ? error : new Error(`Failed to read directory at ${relativePath}`);
|
|
5633
|
+
}
|
|
5634
|
+
}
|
|
5635
|
+
/**
|
|
5636
|
+
* Get list of file paths in directory
|
|
5637
|
+
*/
|
|
5638
|
+
async readDirectoryFilePaths(relativePath) {
|
|
5639
|
+
try {
|
|
5640
|
+
const fileNames = await this.readDirectoryFileNames(relativePath);
|
|
5641
|
+
if (fileNames instanceof Error) {
|
|
5642
|
+
return fileNames;
|
|
5643
|
+
}
|
|
5644
|
+
return fileNames.map(
|
|
5645
|
+
(fileName) => this.pathSystem.join(relativePath, fileName)
|
|
5646
|
+
);
|
|
5647
|
+
} catch (error) {
|
|
5648
|
+
return error instanceof Error ? error : new Error(`Failed to read directory file paths at ${relativePath}`);
|
|
5649
|
+
}
|
|
5650
|
+
}
|
|
5651
|
+
/**
|
|
5652
|
+
* Check if path is a directory
|
|
5653
|
+
*/
|
|
5654
|
+
async isDirectory(relativePath) {
|
|
5655
|
+
try {
|
|
5656
|
+
const normalizedPath = this.normalizePath(relativePath);
|
|
5657
|
+
for (const filePath of Object.keys(this.data)) {
|
|
5658
|
+
if (filePath.startsWith(`${normalizedPath}/`)) {
|
|
5659
|
+
return true;
|
|
5660
|
+
}
|
|
5661
|
+
}
|
|
5662
|
+
return false;
|
|
5663
|
+
} catch {
|
|
5664
|
+
return false;
|
|
5665
|
+
}
|
|
5666
|
+
}
|
|
5667
|
+
/**
|
|
5668
|
+
* Check if path is a file
|
|
5669
|
+
*/
|
|
5670
|
+
async isFile(relativePath) {
|
|
5671
|
+
try {
|
|
5672
|
+
const normalizedPath = this.normalizePath(relativePath);
|
|
5673
|
+
return normalizedPath in this.data;
|
|
5674
|
+
} catch {
|
|
5675
|
+
return false;
|
|
5676
|
+
}
|
|
5677
|
+
}
|
|
5678
|
+
/**
|
|
5679
|
+
* Check if file or directory exists
|
|
5680
|
+
*/
|
|
5681
|
+
async exists(relativePath) {
|
|
5682
|
+
const isFile = await this.isFile(relativePath);
|
|
5683
|
+
if (isFile) return true;
|
|
5684
|
+
const isDir = await this.isDirectory(relativePath);
|
|
5685
|
+
return isDir;
|
|
5686
|
+
}
|
|
5687
|
+
/**
|
|
5688
|
+
* Check if directory exists
|
|
5689
|
+
*/
|
|
5690
|
+
async directoryExists(relativePath) {
|
|
5691
|
+
return this.isDirectory(relativePath);
|
|
5692
|
+
}
|
|
5693
|
+
/**
|
|
5694
|
+
* Check if file exists
|
|
5695
|
+
*/
|
|
5696
|
+
async fileExists(relativePath) {
|
|
5697
|
+
return this.isFile(relativePath);
|
|
5698
|
+
}
|
|
5699
|
+
/**
|
|
5700
|
+
* Get base path
|
|
5701
|
+
*/
|
|
5702
|
+
getBasePath() {
|
|
5703
|
+
return this.basePath;
|
|
5704
|
+
}
|
|
5705
|
+
/**
|
|
5706
|
+
* Convert relative path to absolute path
|
|
5707
|
+
*/
|
|
5708
|
+
resolve(relativePath) {
|
|
5709
|
+
return this.pathSystem.join(this.basePath, relativePath);
|
|
5710
|
+
}
|
|
5711
|
+
/**
|
|
5712
|
+
* Get file size in bytes
|
|
5713
|
+
*/
|
|
5714
|
+
async getFileSize(relativePath) {
|
|
5715
|
+
try {
|
|
5716
|
+
const content = await this.readFile(relativePath);
|
|
5717
|
+
if (content instanceof Error) {
|
|
5718
|
+
return content;
|
|
5719
|
+
}
|
|
5720
|
+
if (content === null) {
|
|
5721
|
+
return new Error(`File not found: ${relativePath}`);
|
|
5722
|
+
}
|
|
5723
|
+
return Buffer.byteLength(content, "utf8");
|
|
5724
|
+
} catch (error) {
|
|
5725
|
+
return error instanceof Error ? error : new Error(`Failed to get file size at ${relativePath}`);
|
|
5726
|
+
}
|
|
5727
|
+
}
|
|
5728
|
+
/**
|
|
5729
|
+
* Get file last modified time (not available for JSON data)
|
|
5730
|
+
*/
|
|
5731
|
+
async getFileModifiedTime(_relativePath) {
|
|
5732
|
+
return new Error("File modified time not available for JSON data");
|
|
5733
|
+
}
|
|
5734
|
+
/**
|
|
5735
|
+
* Get file creation time (not available for JSON data)
|
|
5736
|
+
*/
|
|
5737
|
+
async getFileCreatedTime(_relativePath) {
|
|
5738
|
+
return new Error("File creation time not available for JSON data");
|
|
5739
|
+
}
|
|
5740
|
+
/**
|
|
5741
|
+
* Get all file paths in the JSON data
|
|
5742
|
+
*/
|
|
5743
|
+
getAllFilePaths() {
|
|
5744
|
+
return Object.keys(this.data);
|
|
5745
|
+
}
|
|
5746
|
+
/**
|
|
5747
|
+
* Get the raw JSON data
|
|
5748
|
+
*/
|
|
5749
|
+
getRawData() {
|
|
5750
|
+
return { ...this.data };
|
|
5751
|
+
}
|
|
5752
|
+
/**
|
|
5753
|
+
* Normalize path by removing leading/trailing slashes
|
|
5754
|
+
*/
|
|
5755
|
+
normalizePath(path) {
|
|
5756
|
+
return path.replace(/^\/+|\/+$/g, "");
|
|
5757
|
+
}
|
|
5758
|
+
/**
|
|
5759
|
+
* Check if a file path is within a directory
|
|
5760
|
+
*/
|
|
5761
|
+
isFileInDirectory(filePath, dirPath) {
|
|
5762
|
+
if (dirPath === "") {
|
|
5763
|
+
return true;
|
|
5764
|
+
}
|
|
5765
|
+
return filePath.startsWith(`${dirPath}/`) || filePath === dirPath;
|
|
5766
|
+
}
|
|
5767
|
+
/**
|
|
5768
|
+
* Get the relative part of a file path from a directory
|
|
5769
|
+
*/
|
|
5770
|
+
getRelativePartFromDirectory(filePath, dirPath) {
|
|
5771
|
+
if (dirPath === "") {
|
|
5772
|
+
return filePath;
|
|
5773
|
+
}
|
|
5774
|
+
if (filePath.startsWith(`${dirPath}/`)) {
|
|
5775
|
+
return filePath.slice(dirPath.length + 1);
|
|
5776
|
+
}
|
|
5777
|
+
return "";
|
|
5778
|
+
}
|
|
5779
|
+
};
|
|
5780
|
+
|
|
5781
|
+
// lib/doc-file-system-json-write.ts
|
|
5782
|
+
import { z as z3 } from "zod";
|
|
5783
|
+
var zJsonDocumentData2 = z3.record(z3.string(), z3.string());
|
|
5784
|
+
function parseJsonDocumentData2(data) {
|
|
5785
|
+
try {
|
|
5786
|
+
return zJsonDocumentData2.parse(data);
|
|
5787
|
+
} catch (error) {
|
|
5788
|
+
return error instanceof Error ? error : new Error("Failed to parse JSON document data");
|
|
5789
|
+
}
|
|
5790
|
+
}
|
|
5791
|
+
var DocFileSystemJsonWrite = class {
|
|
5792
|
+
data;
|
|
5793
|
+
basePath;
|
|
5794
|
+
pathSystem;
|
|
5795
|
+
reader;
|
|
5796
|
+
onDataChange;
|
|
5797
|
+
constructor(props = {}) {
|
|
5798
|
+
if (props.data !== void 0) {
|
|
5799
|
+
const parsed = parseJsonDocumentData2(props.data);
|
|
5800
|
+
if (parsed instanceof Error) {
|
|
5801
|
+
throw parsed;
|
|
5802
|
+
}
|
|
5803
|
+
this.data = parsed;
|
|
5804
|
+
} else {
|
|
5805
|
+
this.data = {};
|
|
5806
|
+
}
|
|
5807
|
+
this.basePath = props.basePath ?? "json://";
|
|
5808
|
+
this.pathSystem = props.pathSystem ?? new DocPathSystem();
|
|
5809
|
+
this.reader = props.reader;
|
|
5810
|
+
this.onDataChange = props.onDataChange;
|
|
5811
|
+
}
|
|
5812
|
+
/**
|
|
5813
|
+
* Write content to JSON data
|
|
5814
|
+
*/
|
|
5815
|
+
async writeFile(relativePath, content) {
|
|
5816
|
+
try {
|
|
5817
|
+
const normalizedPath = this.normalizePath(relativePath);
|
|
5818
|
+
this.data[normalizedPath] = content;
|
|
5819
|
+
this.notifyDataChange();
|
|
5820
|
+
return null;
|
|
5821
|
+
} catch (error) {
|
|
5822
|
+
return error instanceof Error ? error : new Error(`Failed to write file at ${relativePath}`);
|
|
5823
|
+
}
|
|
5824
|
+
}
|
|
5825
|
+
/**
|
|
5826
|
+
* Delete file from JSON data
|
|
5827
|
+
*/
|
|
5828
|
+
async deleteFile(relativePath) {
|
|
5829
|
+
try {
|
|
5830
|
+
const normalizedPath = this.normalizePath(relativePath);
|
|
5831
|
+
if (!(normalizedPath in this.data)) {
|
|
5832
|
+
return new Error(`File not found: ${relativePath}`);
|
|
5833
|
+
}
|
|
5834
|
+
delete this.data[normalizedPath];
|
|
5835
|
+
this.notifyDataChange();
|
|
5836
|
+
return null;
|
|
5837
|
+
} catch (error) {
|
|
5838
|
+
return error instanceof Error ? error : new Error(`Failed to delete file at ${relativePath}`);
|
|
5839
|
+
}
|
|
5840
|
+
}
|
|
5841
|
+
/**
|
|
5842
|
+
* Create directory (creates a placeholder entry)
|
|
5843
|
+
*/
|
|
5844
|
+
async createDirectory(relativePath) {
|
|
5845
|
+
try {
|
|
5846
|
+
const normalizedPath = this.normalizePath(relativePath);
|
|
5847
|
+
const gitkeepPath = this.pathSystem.join(normalizedPath, ".gitkeep");
|
|
5848
|
+
const normalizedGitkeepPath = this.normalizePath(gitkeepPath);
|
|
5849
|
+
this.data[normalizedGitkeepPath] = "";
|
|
5850
|
+
this.notifyDataChange();
|
|
5851
|
+
return null;
|
|
5852
|
+
} catch (error) {
|
|
5853
|
+
return error instanceof Error ? error : new Error(`Failed to create directory at ${relativePath}`);
|
|
5854
|
+
}
|
|
5855
|
+
}
|
|
5856
|
+
/**
|
|
5857
|
+
* Create directory if it doesn't exist
|
|
5858
|
+
*/
|
|
5859
|
+
async ensureDirectoryExists(relativePath) {
|
|
5860
|
+
try {
|
|
5861
|
+
if (this.reader) {
|
|
5862
|
+
const exists = await this.reader.exists(relativePath);
|
|
5863
|
+
if (exists) {
|
|
5864
|
+
return null;
|
|
5865
|
+
}
|
|
5866
|
+
} else {
|
|
5867
|
+
if (await this.directoryExistsInData(relativePath)) {
|
|
5868
|
+
return null;
|
|
5869
|
+
}
|
|
5870
|
+
}
|
|
5871
|
+
return await this.createDirectory(relativePath);
|
|
5872
|
+
} catch (error) {
|
|
5873
|
+
return error instanceof Error ? error : new Error(`Failed to ensure directory exists at ${relativePath}`);
|
|
5874
|
+
}
|
|
5875
|
+
}
|
|
5876
|
+
/**
|
|
5877
|
+
* Copy file within JSON data
|
|
5878
|
+
*/
|
|
5879
|
+
async copyFile(sourcePath, destinationPath) {
|
|
5880
|
+
try {
|
|
5881
|
+
const normalizedSourcePath = this.normalizePath(sourcePath);
|
|
5882
|
+
const normalizedDestPath = this.normalizePath(destinationPath);
|
|
5883
|
+
if (this.reader) {
|
|
5884
|
+
const content = await this.reader.readFile(sourcePath);
|
|
5885
|
+
if (content instanceof Error) {
|
|
5886
|
+
return content;
|
|
5887
|
+
}
|
|
5888
|
+
if (content === null) {
|
|
5889
|
+
return new Error(`Source file not found: ${sourcePath}`);
|
|
5890
|
+
}
|
|
5891
|
+
this.data[normalizedDestPath] = content;
|
|
5892
|
+
} else {
|
|
5893
|
+
if (!(normalizedSourcePath in this.data)) {
|
|
5894
|
+
return new Error(`Source file not found: ${sourcePath}`);
|
|
5895
|
+
}
|
|
5896
|
+
this.data[normalizedDestPath] = this.data[normalizedSourcePath];
|
|
5897
|
+
}
|
|
5898
|
+
this.notifyDataChange();
|
|
5899
|
+
return null;
|
|
5900
|
+
} catch (error) {
|
|
5901
|
+
return error instanceof Error ? error : new Error(
|
|
5902
|
+
`Failed to copy file from ${sourcePath} to ${destinationPath}`
|
|
5903
|
+
);
|
|
5904
|
+
}
|
|
5905
|
+
}
|
|
5906
|
+
/**
|
|
5907
|
+
* Move file within JSON data
|
|
5908
|
+
*/
|
|
5909
|
+
async moveFile(sourcePath, destinationPath) {
|
|
5910
|
+
try {
|
|
5911
|
+
const copyResult = await this.copyFile(sourcePath, destinationPath);
|
|
5912
|
+
if (copyResult !== null) {
|
|
5913
|
+
return copyResult;
|
|
5914
|
+
}
|
|
5915
|
+
return await this.deleteFile(sourcePath);
|
|
5916
|
+
} catch (error) {
|
|
5917
|
+
return error instanceof Error ? error : new Error(
|
|
5918
|
+
`Failed to move file from ${sourcePath} to ${destinationPath}`
|
|
5919
|
+
);
|
|
5920
|
+
}
|
|
5921
|
+
}
|
|
5922
|
+
/**
|
|
5923
|
+
* Get the current JSON data
|
|
5924
|
+
*/
|
|
5925
|
+
getData() {
|
|
5926
|
+
return { ...this.data };
|
|
5927
|
+
}
|
|
5928
|
+
/**
|
|
5929
|
+
* Update the entire JSON data
|
|
5930
|
+
*/
|
|
5931
|
+
setData(data) {
|
|
5932
|
+
try {
|
|
5933
|
+
const parsed = parseJsonDocumentData2(data);
|
|
5934
|
+
if (parsed instanceof Error) {
|
|
5935
|
+
return parsed;
|
|
5936
|
+
}
|
|
5937
|
+
this.data = parsed;
|
|
5938
|
+
this.notifyDataChange();
|
|
5939
|
+
return null;
|
|
5940
|
+
} catch (error) {
|
|
5941
|
+
return error instanceof Error ? error : new Error("Failed to set JSON data");
|
|
5942
|
+
}
|
|
5943
|
+
}
|
|
5944
|
+
/**
|
|
5945
|
+
* Clear all data
|
|
5946
|
+
*/
|
|
5947
|
+
clear() {
|
|
5948
|
+
this.data = {};
|
|
5949
|
+
this.notifyDataChange();
|
|
5950
|
+
}
|
|
5951
|
+
/**
|
|
5952
|
+
* Get all file paths in the JSON data
|
|
5953
|
+
*/
|
|
5954
|
+
getAllFilePaths() {
|
|
5955
|
+
return Object.keys(this.data);
|
|
5956
|
+
}
|
|
5957
|
+
/**
|
|
5958
|
+
* Normalize path by removing leading/trailing slashes
|
|
5959
|
+
*/
|
|
5960
|
+
normalizePath(path) {
|
|
5961
|
+
return path.replace(/^\/+|\/+$/g, "");
|
|
5962
|
+
}
|
|
5963
|
+
/**
|
|
5964
|
+
* Check if directory exists in data
|
|
5965
|
+
*/
|
|
5966
|
+
async directoryExistsInData(relativePath) {
|
|
5967
|
+
const normalizedPath = this.normalizePath(relativePath);
|
|
5968
|
+
for (const filePath of Object.keys(this.data)) {
|
|
5969
|
+
if (filePath.startsWith(`${normalizedPath}/`)) {
|
|
5970
|
+
return true;
|
|
5971
|
+
}
|
|
5972
|
+
}
|
|
5973
|
+
return false;
|
|
5974
|
+
}
|
|
5975
|
+
/**
|
|
5976
|
+
* Notify data change callback
|
|
5977
|
+
*/
|
|
5978
|
+
notifyDataChange() {
|
|
5979
|
+
if (this.onDataChange) {
|
|
5980
|
+
this.onDataChange({ ...this.data });
|
|
5981
|
+
}
|
|
5982
|
+
}
|
|
5983
|
+
};
|
|
5984
|
+
|
|
5985
|
+
// lib/doc-file-system-json.ts
|
|
5986
|
+
var zJsonDocumentData3 = z4.record(z4.string(), z4.string());
|
|
5987
|
+
var DocFileSystemJson = class _DocFileSystemJson extends DocFileSystem {
|
|
5988
|
+
jsonReader;
|
|
5989
|
+
jsonWriter;
|
|
5990
|
+
constructor(props = {}) {
|
|
5991
|
+
const reader = new DocFileSystemJsonRead({
|
|
5992
|
+
data: props.data,
|
|
5993
|
+
basePath: props.basePath,
|
|
5994
|
+
pathSystem: props.pathSystem
|
|
5995
|
+
});
|
|
5996
|
+
const writer = new DocFileSystemJsonWrite({
|
|
5997
|
+
data: props.data,
|
|
5998
|
+
basePath: props.basePath,
|
|
5999
|
+
pathSystem: props.pathSystem,
|
|
6000
|
+
reader,
|
|
6001
|
+
onDataChange: props.onDataChange
|
|
6002
|
+
});
|
|
6003
|
+
super({
|
|
6004
|
+
basePath: props.basePath ?? "json://",
|
|
6005
|
+
pathSystem: props.pathSystem,
|
|
6006
|
+
reader,
|
|
6007
|
+
writer
|
|
6008
|
+
});
|
|
6009
|
+
this.jsonReader = reader;
|
|
6010
|
+
this.jsonWriter = writer;
|
|
6011
|
+
Object.freeze(this);
|
|
6012
|
+
}
|
|
6013
|
+
/**
|
|
6014
|
+
* Get the current JSON data
|
|
6015
|
+
*/
|
|
6016
|
+
getData() {
|
|
6017
|
+
return this.jsonWriter.getData();
|
|
6018
|
+
}
|
|
6019
|
+
/**
|
|
6020
|
+
* Update the entire JSON data
|
|
6021
|
+
*/
|
|
6022
|
+
setData(data) {
|
|
6023
|
+
return this.jsonWriter.setData(data);
|
|
6024
|
+
}
|
|
6025
|
+
/**
|
|
6026
|
+
* Clear all data
|
|
6027
|
+
*/
|
|
6028
|
+
clear() {
|
|
6029
|
+
this.jsonWriter.clear();
|
|
6030
|
+
}
|
|
6031
|
+
/**
|
|
6032
|
+
* Get all file paths in the JSON data
|
|
6033
|
+
*/
|
|
6034
|
+
getAllFilePaths() {
|
|
6035
|
+
return this.jsonReader.getAllFilePaths();
|
|
6036
|
+
}
|
|
6037
|
+
/**
|
|
6038
|
+
* Get the raw JSON data (read-only copy)
|
|
6039
|
+
*/
|
|
6040
|
+
getRawData() {
|
|
6041
|
+
return this.jsonReader.getRawData();
|
|
6042
|
+
}
|
|
6043
|
+
/**
|
|
6044
|
+
* Create from docs-to-json format
|
|
6045
|
+
*/
|
|
6046
|
+
static fromDocsToJson(data, options = {}) {
|
|
6047
|
+
return new _DocFileSystemJson({
|
|
6048
|
+
...options,
|
|
6049
|
+
data
|
|
6050
|
+
});
|
|
6051
|
+
}
|
|
6052
|
+
/**
|
|
6053
|
+
* Export to docs-to-json format
|
|
6054
|
+
*/
|
|
6055
|
+
toDocsToJson() {
|
|
6056
|
+
return this.getData();
|
|
6057
|
+
}
|
|
6058
|
+
};
|
|
6059
|
+
|
|
6060
|
+
// lib/doc-file-system-mock.ts
|
|
6061
|
+
var mockDirectoryData = {
|
|
6062
|
+
"docs/index.md": `---
|
|
6063
|
+
icon: \u{1F4DA}
|
|
6064
|
+
---
|
|
6065
|
+
|
|
6066
|
+
# Documentation
|
|
6067
|
+
|
|
6068
|
+
Welcome to the documentation!`,
|
|
6069
|
+
"docs/guide/index.md": `---
|
|
6070
|
+
icon: \u{1F4D6}
|
|
6071
|
+
---
|
|
6072
|
+
|
|
6073
|
+
# Guide
|
|
6074
|
+
|
|
6075
|
+
This is a guide.`,
|
|
6076
|
+
"docs/guide/getting-started.md": `# Getting Started
|
|
6077
|
+
|
|
6078
|
+
Let's get started!`,
|
|
6079
|
+
"docs/guide/advanced.md": `# Advanced
|
|
6080
|
+
|
|
6081
|
+
Advanced topics here.`,
|
|
6082
|
+
"docs/api/index.md": `---
|
|
6083
|
+
icon: \u{1F527}
|
|
6084
|
+
---
|
|
6085
|
+
|
|
6086
|
+
# API
|
|
6087
|
+
|
|
6088
|
+
API documentation.`,
|
|
6089
|
+
"docs/api/reference.md": `# API Reference
|
|
6090
|
+
|
|
6091
|
+
Complete API reference.`
|
|
6092
|
+
};
|
|
6093
|
+
var DocFileSystemMock = class _DocFileSystemMock extends DocFileSystem {
|
|
6094
|
+
files = /* @__PURE__ */ new Map();
|
|
6095
|
+
_pathSystem;
|
|
6096
|
+
_basePath;
|
|
6097
|
+
constructor(props) {
|
|
6098
|
+
super(props);
|
|
6099
|
+
this._pathSystem = props.pathSystem;
|
|
6100
|
+
this._basePath = props.basePath.endsWith("/") ? props.basePath.slice(0, -1) : props.basePath;
|
|
6101
|
+
if (!props.skipDefaultFiles) {
|
|
6102
|
+
this.setupTestFiles(mockDirectoryData);
|
|
6103
|
+
}
|
|
6104
|
+
Object.freeze(this);
|
|
6105
|
+
}
|
|
6106
|
+
/**
|
|
6107
|
+
* PathSystem accessor (for testing)
|
|
6108
|
+
*/
|
|
6109
|
+
getPathSystem() {
|
|
6110
|
+
return this._pathSystem;
|
|
6111
|
+
}
|
|
6112
|
+
/**
|
|
6113
|
+
* Normalize path using basePath
|
|
6114
|
+
*/
|
|
6115
|
+
normalizePath(filePath) {
|
|
6116
|
+
if (filePath.startsWith(this._basePath)) {
|
|
6117
|
+
return filePath;
|
|
6118
|
+
}
|
|
6119
|
+
const cleanPath = filePath.startsWith("/") ? filePath.slice(1) : filePath;
|
|
6120
|
+
return `${this._basePath}/${cleanPath}`;
|
|
6121
|
+
}
|
|
6122
|
+
/**
|
|
6123
|
+
* Create instance (mock data is automatically loaded)
|
|
6124
|
+
*/
|
|
6125
|
+
static create(basePath = "/test") {
|
|
6126
|
+
const pathSystem = new DocPathSystem();
|
|
6127
|
+
return new _DocFileSystemMock({ basePath, pathSystem });
|
|
6128
|
+
}
|
|
6129
|
+
/**
|
|
6130
|
+
* Factory method for testing
|
|
6131
|
+
*/
|
|
6132
|
+
static createWithFiles(props) {
|
|
6133
|
+
const pathSystem = new DocPathSystem();
|
|
6134
|
+
const basePath = props.basePath ?? "/test";
|
|
6135
|
+
const fileSystem = new _DocFileSystemMock({
|
|
6136
|
+
basePath,
|
|
6137
|
+
pathSystem,
|
|
6138
|
+
skipDefaultFiles: true
|
|
6139
|
+
});
|
|
6140
|
+
if (props.fileContents) {
|
|
6141
|
+
const now = /* @__PURE__ */ new Date();
|
|
6142
|
+
for (const [path, content] of Object.entries(props.fileContents)) {
|
|
6143
|
+
const cleanPath = path.startsWith("/") ? path.slice(1) : path;
|
|
6144
|
+
const normalizedPath = path.startsWith(basePath) ? path : `${basePath}/${cleanPath}`;
|
|
6145
|
+
fileSystem.files.set(normalizedPath, {
|
|
6146
|
+
content,
|
|
6147
|
+
modifiedTime: now,
|
|
6148
|
+
createdTime: now,
|
|
6149
|
+
size: new TextEncoder().encode(content).length
|
|
6150
|
+
});
|
|
6151
|
+
}
|
|
6152
|
+
}
|
|
6153
|
+
return fileSystem;
|
|
6154
|
+
}
|
|
6155
|
+
async readFile(filePath) {
|
|
6156
|
+
try {
|
|
6157
|
+
const normalizedPath = this.normalizePath(filePath);
|
|
6158
|
+
const file = this.files.get(normalizedPath);
|
|
6159
|
+
return file ? file.content : null;
|
|
6160
|
+
} catch (error) {
|
|
6161
|
+
return error instanceof Error ? error : new Error(`Failed to read file at ${filePath}`);
|
|
6162
|
+
}
|
|
6163
|
+
}
|
|
6164
|
+
async writeFile(filePath, content) {
|
|
6165
|
+
try {
|
|
6166
|
+
const normalizedPath = this.normalizePath(filePath);
|
|
6167
|
+
const now = /* @__PURE__ */ new Date();
|
|
6168
|
+
const existing = this.files.get(normalizedPath);
|
|
6169
|
+
this.files.set(normalizedPath, {
|
|
6170
|
+
content,
|
|
6171
|
+
modifiedTime: now,
|
|
6172
|
+
createdTime: existing?.createdTime ?? now,
|
|
6173
|
+
size: new TextEncoder().encode(content).length
|
|
6174
|
+
});
|
|
6175
|
+
return null;
|
|
6176
|
+
} catch (error) {
|
|
6177
|
+
return error instanceof Error ? error : new Error(`Failed to write file at ${filePath}`);
|
|
6178
|
+
}
|
|
5506
6179
|
}
|
|
5507
6180
|
async deleteFile(filePath) {
|
|
5508
6181
|
try {
|
|
@@ -5621,64 +6294,288 @@ var DocFileSystemMock = class _DocFileSystemMock extends DocFileSystem {
|
|
|
5621
6294
|
return error instanceof Error ? error : new Error(`Failed to get file size at ${filePath}`);
|
|
5622
6295
|
}
|
|
5623
6296
|
}
|
|
5624
|
-
async getFileModifiedTime(filePath) {
|
|
6297
|
+
async getFileModifiedTime(filePath) {
|
|
6298
|
+
try {
|
|
6299
|
+
const normalizedPath = this.normalizePath(filePath);
|
|
6300
|
+
const file = this.files.get(normalizedPath);
|
|
6301
|
+
if (!file) {
|
|
6302
|
+
return new Error(`File not found: ${normalizedPath}`);
|
|
6303
|
+
}
|
|
6304
|
+
return file.modifiedTime;
|
|
6305
|
+
} catch (error) {
|
|
6306
|
+
return error instanceof Error ? error : new Error(`Failed to get file modified time at ${filePath}`);
|
|
6307
|
+
}
|
|
6308
|
+
}
|
|
6309
|
+
async getFileCreatedTime(filePath) {
|
|
6310
|
+
try {
|
|
6311
|
+
const normalizedPath = this.normalizePath(filePath);
|
|
6312
|
+
const file = this.files.get(normalizedPath);
|
|
6313
|
+
if (!file) {
|
|
6314
|
+
return new Error(`File not found: ${normalizedPath}`);
|
|
6315
|
+
}
|
|
6316
|
+
return file.createdTime;
|
|
6317
|
+
} catch (error) {
|
|
6318
|
+
return error instanceof Error ? error : new Error(`Failed to get file created time at ${filePath}`);
|
|
6319
|
+
}
|
|
6320
|
+
}
|
|
6321
|
+
async isDirectory(relativePath) {
|
|
6322
|
+
const normalizedPath = this.normalizePath(relativePath);
|
|
6323
|
+
const dirPath = normalizedPath.endsWith("/") ? normalizedPath : `${normalizedPath}/`;
|
|
6324
|
+
for (const path of this.files.keys()) {
|
|
6325
|
+
if (path.startsWith(dirPath)) {
|
|
6326
|
+
return true;
|
|
6327
|
+
}
|
|
6328
|
+
}
|
|
6329
|
+
return false;
|
|
6330
|
+
}
|
|
6331
|
+
async isFile(relativePath) {
|
|
6332
|
+
const normalizedPath = this.normalizePath(relativePath);
|
|
6333
|
+
return this.files.has(normalizedPath);
|
|
6334
|
+
}
|
|
6335
|
+
/**
|
|
6336
|
+
* Get list of entries in directory
|
|
6337
|
+
*/
|
|
6338
|
+
async readDirectoryFileNames(directoryPath = "") {
|
|
6339
|
+
try {
|
|
6340
|
+
const normalizedDir = directoryPath === "" ? this._basePath : this.normalizePath(directoryPath);
|
|
6341
|
+
const dirPath = normalizedDir.endsWith("/") ? normalizedDir : `${normalizedDir}/`;
|
|
6342
|
+
const entries = /* @__PURE__ */ new Set();
|
|
6343
|
+
for (const path of this.files.keys()) {
|
|
6344
|
+
if (path.startsWith(dirPath)) {
|
|
6345
|
+
const relativePath = path.slice(dirPath.length);
|
|
6346
|
+
const firstSegment = relativePath.split("/")[0];
|
|
6347
|
+
if (firstSegment) {
|
|
6348
|
+
entries.add(firstSegment);
|
|
6349
|
+
}
|
|
6350
|
+
}
|
|
6351
|
+
}
|
|
6352
|
+
return Array.from(entries).sort();
|
|
6353
|
+
} catch (error) {
|
|
6354
|
+
return error instanceof Error ? error : new Error(`Failed to read directory at ${directoryPath}`);
|
|
6355
|
+
}
|
|
6356
|
+
}
|
|
6357
|
+
/**
|
|
6358
|
+
* Check if directory exists
|
|
6359
|
+
*/
|
|
6360
|
+
async directoryExists(relativePath) {
|
|
6361
|
+
return this.isDirectory(relativePath);
|
|
6362
|
+
}
|
|
6363
|
+
/**
|
|
6364
|
+
* Check if file exists
|
|
6365
|
+
*/
|
|
6366
|
+
async fileExists(relativePath) {
|
|
6367
|
+
return this.isFile(relativePath);
|
|
6368
|
+
}
|
|
6369
|
+
/**
|
|
6370
|
+
* Create directory if it doesn't exist
|
|
6371
|
+
*/
|
|
6372
|
+
async ensureDirectoryExists(_relativePath) {
|
|
6373
|
+
return null;
|
|
6374
|
+
}
|
|
6375
|
+
/**
|
|
6376
|
+
* Clear all files
|
|
6377
|
+
*/
|
|
6378
|
+
clear() {
|
|
6379
|
+
this.files.clear();
|
|
6380
|
+
}
|
|
6381
|
+
/**
|
|
6382
|
+
* Check file existence (for testing)
|
|
6383
|
+
*/
|
|
6384
|
+
hasFile(filePath) {
|
|
6385
|
+
const normalizedPath = this.normalizePath(filePath);
|
|
6386
|
+
return this.files.has(normalizedPath);
|
|
6387
|
+
}
|
|
6388
|
+
/**
|
|
6389
|
+
* Get file content (sync version, for testing)
|
|
6390
|
+
*/
|
|
6391
|
+
getFileContent(filePath) {
|
|
6392
|
+
const normalizedPath = this.normalizePath(filePath);
|
|
6393
|
+
return this.files.get(normalizedPath)?.content;
|
|
6394
|
+
}
|
|
6395
|
+
/**
|
|
6396
|
+
* Get all file paths (for testing)
|
|
6397
|
+
*/
|
|
6398
|
+
getAllFilePaths() {
|
|
6399
|
+
return Array.from(this.files.keys()).map((path) => {
|
|
6400
|
+
return path.startsWith(`${this._basePath}/`) ? path.slice(this._basePath.length + 1) : path;
|
|
6401
|
+
}).sort();
|
|
6402
|
+
}
|
|
6403
|
+
/**
|
|
6404
|
+
* Get file count (for testing)
|
|
6405
|
+
*/
|
|
6406
|
+
getFileCount() {
|
|
6407
|
+
return this.files.size;
|
|
6408
|
+
}
|
|
6409
|
+
/**
|
|
6410
|
+
* Setup test data
|
|
6411
|
+
*/
|
|
6412
|
+
setupTestFiles(files) {
|
|
6413
|
+
const now = /* @__PURE__ */ new Date();
|
|
6414
|
+
for (const [path, content] of Object.entries(files)) {
|
|
6415
|
+
const normalizedPath = this.normalizePath(path);
|
|
6416
|
+
this.files.set(normalizedPath, {
|
|
6417
|
+
content,
|
|
6418
|
+
modifiedTime: now,
|
|
6419
|
+
createdTime: now,
|
|
6420
|
+
size: new TextEncoder().encode(content).length
|
|
6421
|
+
});
|
|
6422
|
+
}
|
|
6423
|
+
}
|
|
6424
|
+
};
|
|
6425
|
+
|
|
6426
|
+
// lib/doc-file-system-octokit-read.ts
|
|
6427
|
+
import { Octokit } from "@octokit/rest";
|
|
6428
|
+
var DocFileSystemOctokitRead = class {
|
|
6429
|
+
octokit;
|
|
6430
|
+
owner;
|
|
6431
|
+
repo;
|
|
6432
|
+
branch;
|
|
6433
|
+
pathSystem;
|
|
6434
|
+
basePath;
|
|
6435
|
+
fileCache = /* @__PURE__ */ new Map();
|
|
6436
|
+
constructor(props) {
|
|
6437
|
+
this.owner = props.owner;
|
|
6438
|
+
this.repo = props.repo;
|
|
6439
|
+
this.branch = props.branch ?? "main";
|
|
6440
|
+
this.basePath = props.basePath;
|
|
6441
|
+
this.pathSystem = props.pathSystem ?? new DocPathSystem();
|
|
6442
|
+
this.octokit = new Octokit({ auth: props.token });
|
|
6443
|
+
Object.freeze(this);
|
|
6444
|
+
}
|
|
6445
|
+
/**
|
|
6446
|
+
* Read file content from GitHub repository
|
|
6447
|
+
*/
|
|
6448
|
+
async readFile(relativePath) {
|
|
6449
|
+
try {
|
|
6450
|
+
const fullPath = this.pathSystem.join(this.basePath, relativePath);
|
|
6451
|
+
const response = await this.octokit.repos.getContent({
|
|
6452
|
+
owner: this.owner,
|
|
6453
|
+
repo: this.repo,
|
|
6454
|
+
path: fullPath,
|
|
6455
|
+
ref: this.branch
|
|
6456
|
+
});
|
|
6457
|
+
if ("type" in response.data && response.data.type === "file") {
|
|
6458
|
+
const content = Buffer.from(response.data.content, "base64").toString(
|
|
6459
|
+
"utf-8"
|
|
6460
|
+
);
|
|
6461
|
+
this.fileCache.set(fullPath, {
|
|
6462
|
+
sha: response.data.sha,
|
|
6463
|
+
content,
|
|
6464
|
+
size: response.data.size
|
|
6465
|
+
});
|
|
6466
|
+
return content;
|
|
6467
|
+
}
|
|
6468
|
+
return new Error(`Path ${relativePath} is not a file`);
|
|
6469
|
+
} catch (error) {
|
|
6470
|
+
if (error && typeof error === "object" && "status" in error && error.status === 404) {
|
|
6471
|
+
return null;
|
|
6472
|
+
}
|
|
6473
|
+
return error instanceof Error ? error : new Error(`Failed to read file at ${relativePath}`);
|
|
6474
|
+
}
|
|
6475
|
+
}
|
|
6476
|
+
/**
|
|
6477
|
+
* Get file name from path
|
|
6478
|
+
*/
|
|
6479
|
+
readFileName(relativePath) {
|
|
6480
|
+
return this.pathSystem.basename(relativePath);
|
|
6481
|
+
}
|
|
6482
|
+
/**
|
|
6483
|
+
* Get file extension from path
|
|
6484
|
+
*/
|
|
6485
|
+
readFileExtension(relativePath) {
|
|
6486
|
+
return this.pathSystem.extname(relativePath);
|
|
6487
|
+
}
|
|
6488
|
+
/**
|
|
6489
|
+
* Get directory path where the file exists
|
|
6490
|
+
*/
|
|
6491
|
+
readFileDirectory(relativePath) {
|
|
6492
|
+
return this.pathSystem.dirname(relativePath);
|
|
6493
|
+
}
|
|
6494
|
+
/**
|
|
6495
|
+
* Get list of file names in directory
|
|
6496
|
+
*/
|
|
6497
|
+
async readDirectoryFileNames(relativePath = "") {
|
|
5625
6498
|
try {
|
|
5626
|
-
const
|
|
5627
|
-
const
|
|
5628
|
-
|
|
5629
|
-
|
|
6499
|
+
const fullPath = relativePath ? this.pathSystem.join(this.basePath, relativePath) : this.basePath;
|
|
6500
|
+
const response = await this.octokit.repos.getContent({
|
|
6501
|
+
owner: this.owner,
|
|
6502
|
+
repo: this.repo,
|
|
6503
|
+
path: fullPath,
|
|
6504
|
+
ref: this.branch
|
|
6505
|
+
});
|
|
6506
|
+
if (Array.isArray(response.data)) {
|
|
6507
|
+
return response.data.map((item) => item.name);
|
|
5630
6508
|
}
|
|
5631
|
-
return
|
|
6509
|
+
return new Error(`Path ${relativePath} is not a directory`);
|
|
5632
6510
|
} catch (error) {
|
|
5633
|
-
return error instanceof Error ? error : new Error(`Failed to
|
|
6511
|
+
return error instanceof Error ? error : new Error(`Failed to read directory at ${relativePath}`);
|
|
5634
6512
|
}
|
|
5635
6513
|
}
|
|
5636
|
-
|
|
6514
|
+
/**
|
|
6515
|
+
* Get list of file paths in directory
|
|
6516
|
+
*/
|
|
6517
|
+
async readDirectoryFilePaths(relativePath) {
|
|
5637
6518
|
try {
|
|
5638
|
-
const
|
|
5639
|
-
|
|
5640
|
-
|
|
5641
|
-
return new Error(`File not found: ${normalizedPath}`);
|
|
6519
|
+
const fileNames = await this.readDirectoryFileNames(relativePath);
|
|
6520
|
+
if (fileNames instanceof Error) {
|
|
6521
|
+
return fileNames;
|
|
5642
6522
|
}
|
|
5643
|
-
return
|
|
6523
|
+
return fileNames.map(
|
|
6524
|
+
(fileName) => this.pathSystem.join(relativePath, fileName)
|
|
6525
|
+
);
|
|
5644
6526
|
} catch (error) {
|
|
5645
|
-
return error instanceof Error ? error : new Error(`Failed to
|
|
6527
|
+
return error instanceof Error ? error : new Error(`Failed to read directory file paths at ${relativePath}`);
|
|
5646
6528
|
}
|
|
5647
6529
|
}
|
|
6530
|
+
/**
|
|
6531
|
+
* Check if path is a directory
|
|
6532
|
+
*/
|
|
5648
6533
|
async isDirectory(relativePath) {
|
|
5649
|
-
|
|
5650
|
-
|
|
5651
|
-
|
|
5652
|
-
|
|
5653
|
-
|
|
5654
|
-
|
|
6534
|
+
try {
|
|
6535
|
+
const fullPath = this.pathSystem.join(this.basePath, relativePath);
|
|
6536
|
+
const response = await this.octokit.repos.getContent({
|
|
6537
|
+
owner: this.owner,
|
|
6538
|
+
repo: this.repo,
|
|
6539
|
+
path: fullPath,
|
|
6540
|
+
ref: this.branch
|
|
6541
|
+
});
|
|
6542
|
+
return Array.isArray(response.data);
|
|
6543
|
+
} catch {
|
|
6544
|
+
return false;
|
|
5655
6545
|
}
|
|
5656
|
-
return false;
|
|
5657
6546
|
}
|
|
6547
|
+
/**
|
|
6548
|
+
* Check if path is a file
|
|
6549
|
+
*/
|
|
5658
6550
|
async isFile(relativePath) {
|
|
5659
|
-
|
|
5660
|
-
|
|
6551
|
+
try {
|
|
6552
|
+
const fullPath = this.pathSystem.join(this.basePath, relativePath);
|
|
6553
|
+
const response = await this.octokit.repos.getContent({
|
|
6554
|
+
owner: this.owner,
|
|
6555
|
+
repo: this.repo,
|
|
6556
|
+
path: fullPath,
|
|
6557
|
+
ref: this.branch
|
|
6558
|
+
});
|
|
6559
|
+
return !Array.isArray(response.data) && response.data.type === "file";
|
|
6560
|
+
} catch {
|
|
6561
|
+
return false;
|
|
6562
|
+
}
|
|
5661
6563
|
}
|
|
5662
6564
|
/**
|
|
5663
|
-
*
|
|
6565
|
+
* Check if file or directory exists
|
|
5664
6566
|
*/
|
|
5665
|
-
async
|
|
6567
|
+
async exists(relativePath) {
|
|
5666
6568
|
try {
|
|
5667
|
-
const
|
|
5668
|
-
|
|
5669
|
-
|
|
5670
|
-
|
|
5671
|
-
|
|
5672
|
-
|
|
5673
|
-
|
|
5674
|
-
|
|
5675
|
-
|
|
5676
|
-
|
|
5677
|
-
}
|
|
5678
|
-
}
|
|
5679
|
-
return Array.from(entries).sort();
|
|
5680
|
-
} catch (error) {
|
|
5681
|
-
return error instanceof Error ? error : new Error(`Failed to read directory at ${directoryPath}`);
|
|
6569
|
+
const fullPath = this.pathSystem.join(this.basePath, relativePath);
|
|
6570
|
+
await this.octokit.repos.getContent({
|
|
6571
|
+
owner: this.owner,
|
|
6572
|
+
repo: this.repo,
|
|
6573
|
+
path: fullPath,
|
|
6574
|
+
ref: this.branch
|
|
6575
|
+
});
|
|
6576
|
+
return true;
|
|
6577
|
+
} catch {
|
|
6578
|
+
return false;
|
|
5682
6579
|
}
|
|
5683
6580
|
}
|
|
5684
6581
|
/**
|
|
@@ -5694,62 +6591,303 @@ var DocFileSystemMock = class _DocFileSystemMock extends DocFileSystem {
|
|
|
5694
6591
|
return this.isFile(relativePath);
|
|
5695
6592
|
}
|
|
5696
6593
|
/**
|
|
5697
|
-
*
|
|
6594
|
+
* Get base path
|
|
5698
6595
|
*/
|
|
5699
|
-
|
|
5700
|
-
return
|
|
6596
|
+
getBasePath() {
|
|
6597
|
+
return this.basePath;
|
|
5701
6598
|
}
|
|
5702
6599
|
/**
|
|
5703
|
-
*
|
|
6600
|
+
* Convert relative path to absolute path
|
|
5704
6601
|
*/
|
|
5705
|
-
|
|
5706
|
-
this.
|
|
6602
|
+
resolve(relativePath) {
|
|
6603
|
+
return this.pathSystem.join(this.basePath, relativePath);
|
|
5707
6604
|
}
|
|
5708
6605
|
/**
|
|
5709
|
-
*
|
|
6606
|
+
* Get file size in bytes
|
|
5710
6607
|
*/
|
|
5711
|
-
|
|
5712
|
-
|
|
5713
|
-
|
|
6608
|
+
async getFileSize(relativePath) {
|
|
6609
|
+
try {
|
|
6610
|
+
const fullPath = this.pathSystem.join(this.basePath, relativePath);
|
|
6611
|
+
const cached = this.fileCache.get(fullPath);
|
|
6612
|
+
if (cached) {
|
|
6613
|
+
return cached.size;
|
|
6614
|
+
}
|
|
6615
|
+
const response = await this.octokit.repos.getContent({
|
|
6616
|
+
owner: this.owner,
|
|
6617
|
+
repo: this.repo,
|
|
6618
|
+
path: fullPath,
|
|
6619
|
+
ref: this.branch
|
|
6620
|
+
});
|
|
6621
|
+
if ("size" in response.data) {
|
|
6622
|
+
return response.data.size;
|
|
6623
|
+
}
|
|
6624
|
+
return new Error(`Cannot get size for ${relativePath}`);
|
|
6625
|
+
} catch (error) {
|
|
6626
|
+
return error instanceof Error ? error : new Error(`Failed to get file size at ${relativePath}`);
|
|
6627
|
+
}
|
|
5714
6628
|
}
|
|
5715
6629
|
/**
|
|
5716
|
-
* Get file
|
|
6630
|
+
* Get file last modified time
|
|
5717
6631
|
*/
|
|
5718
|
-
|
|
5719
|
-
|
|
5720
|
-
|
|
6632
|
+
async getFileModifiedTime(relativePath) {
|
|
6633
|
+
try {
|
|
6634
|
+
const commits = await this.octokit.repos.listCommits({
|
|
6635
|
+
owner: this.owner,
|
|
6636
|
+
repo: this.repo,
|
|
6637
|
+
path: relativePath,
|
|
6638
|
+
sha: this.branch,
|
|
6639
|
+
per_page: 1
|
|
6640
|
+
});
|
|
6641
|
+
if (commits.data.length > 0 && commits.data[0].commit.author?.date) {
|
|
6642
|
+
return new Date(commits.data[0].commit.author.date);
|
|
6643
|
+
}
|
|
6644
|
+
return new Error(`No commits found for ${relativePath}`);
|
|
6645
|
+
} catch (error) {
|
|
6646
|
+
return error instanceof Error ? error : new Error(`Failed to get file modified time at ${relativePath}`);
|
|
6647
|
+
}
|
|
5721
6648
|
}
|
|
5722
6649
|
/**
|
|
5723
|
-
* Get
|
|
6650
|
+
* Get file creation time (first commit)
|
|
5724
6651
|
*/
|
|
5725
|
-
|
|
5726
|
-
|
|
5727
|
-
|
|
5728
|
-
|
|
6652
|
+
async getFileCreatedTime(relativePath) {
|
|
6653
|
+
try {
|
|
6654
|
+
const commits = await this.octokit.repos.listCommits({
|
|
6655
|
+
owner: this.owner,
|
|
6656
|
+
repo: this.repo,
|
|
6657
|
+
path: relativePath,
|
|
6658
|
+
sha: this.branch
|
|
6659
|
+
});
|
|
6660
|
+
const lastCommit = commits.data[commits.data.length - 1];
|
|
6661
|
+
if (lastCommit?.commit.author?.date) {
|
|
6662
|
+
return new Date(lastCommit.commit.author.date);
|
|
6663
|
+
}
|
|
6664
|
+
return new Error(`No commits found for ${relativePath}`);
|
|
6665
|
+
} catch (error) {
|
|
6666
|
+
return error instanceof Error ? error : new Error(`Failed to get file created time at ${relativePath}`);
|
|
6667
|
+
}
|
|
5729
6668
|
}
|
|
5730
6669
|
/**
|
|
5731
|
-
* Get
|
|
6670
|
+
* Get cached SHA for a file
|
|
5732
6671
|
*/
|
|
5733
|
-
|
|
5734
|
-
|
|
6672
|
+
getCachedSha(relativePath) {
|
|
6673
|
+
const fullPath = this.pathSystem.join(this.basePath, relativePath);
|
|
6674
|
+
return this.fileCache.get(fullPath)?.sha;
|
|
6675
|
+
}
|
|
6676
|
+
};
|
|
6677
|
+
|
|
6678
|
+
// lib/doc-file-system-octokit-write.ts
|
|
6679
|
+
import { Octokit as Octokit2 } from "@octokit/rest";
|
|
6680
|
+
var DocFileSystemOctokitWrite = class {
|
|
6681
|
+
octokit;
|
|
6682
|
+
owner;
|
|
6683
|
+
repo;
|
|
6684
|
+
basePath;
|
|
6685
|
+
branch;
|
|
6686
|
+
pathSystem;
|
|
6687
|
+
reader;
|
|
6688
|
+
constructor(props) {
|
|
6689
|
+
this.owner = props.owner;
|
|
6690
|
+
this.repo = props.repo;
|
|
6691
|
+
this.basePath = props.basePath;
|
|
6692
|
+
this.branch = props.branch ?? "main";
|
|
6693
|
+
this.pathSystem = props.pathSystem ?? new DocPathSystem();
|
|
6694
|
+
this.octokit = new Octokit2({ auth: props.token });
|
|
6695
|
+
this.reader = props.reader;
|
|
6696
|
+
Object.freeze(this);
|
|
5735
6697
|
}
|
|
5736
6698
|
/**
|
|
5737
|
-
*
|
|
6699
|
+
* Write content to file in GitHub repository
|
|
5738
6700
|
*/
|
|
5739
|
-
|
|
5740
|
-
|
|
5741
|
-
|
|
5742
|
-
const
|
|
5743
|
-
|
|
5744
|
-
|
|
5745
|
-
|
|
5746
|
-
|
|
5747
|
-
|
|
6701
|
+
async writeFile(relativePath, content) {
|
|
6702
|
+
try {
|
|
6703
|
+
const fullPath = this.pathSystem.join(this.basePath, relativePath);
|
|
6704
|
+
const encodedContent = Buffer.from(content).toString("base64");
|
|
6705
|
+
let sha;
|
|
6706
|
+
if (this.reader && "getCachedSha" in this.reader) {
|
|
6707
|
+
sha = this.reader.getCachedSha(
|
|
6708
|
+
relativePath
|
|
6709
|
+
);
|
|
6710
|
+
}
|
|
6711
|
+
if (!sha) {
|
|
6712
|
+
try {
|
|
6713
|
+
const existing = await this.octokit.repos.getContent({
|
|
6714
|
+
owner: this.owner,
|
|
6715
|
+
repo: this.repo,
|
|
6716
|
+
path: fullPath,
|
|
6717
|
+
ref: this.branch
|
|
6718
|
+
});
|
|
6719
|
+
if ("sha" in existing.data) {
|
|
6720
|
+
sha = existing.data.sha;
|
|
6721
|
+
}
|
|
6722
|
+
} catch {
|
|
6723
|
+
}
|
|
6724
|
+
}
|
|
6725
|
+
await this.octokit.repos.createOrUpdateFileContents({
|
|
6726
|
+
owner: this.owner,
|
|
6727
|
+
repo: this.repo,
|
|
6728
|
+
path: fullPath,
|
|
6729
|
+
message: `Update ${fullPath}`,
|
|
6730
|
+
content: encodedContent,
|
|
6731
|
+
branch: this.branch,
|
|
6732
|
+
sha
|
|
6733
|
+
});
|
|
6734
|
+
return null;
|
|
6735
|
+
} catch (error) {
|
|
6736
|
+
return error instanceof Error ? error : new Error(`Failed to write file at ${relativePath}`);
|
|
6737
|
+
}
|
|
6738
|
+
}
|
|
6739
|
+
/**
|
|
6740
|
+
* Delete file from GitHub repository
|
|
6741
|
+
*/
|
|
6742
|
+
async deleteFile(relativePath) {
|
|
6743
|
+
try {
|
|
6744
|
+
const fullPath = this.pathSystem.join(this.basePath, relativePath);
|
|
6745
|
+
let sha;
|
|
6746
|
+
if (this.reader && "getCachedSha" in this.reader) {
|
|
6747
|
+
sha = this.reader.getCachedSha(
|
|
6748
|
+
relativePath
|
|
6749
|
+
);
|
|
6750
|
+
}
|
|
6751
|
+
if (!sha) {
|
|
6752
|
+
const existing = await this.octokit.repos.getContent({
|
|
6753
|
+
owner: this.owner,
|
|
6754
|
+
repo: this.repo,
|
|
6755
|
+
path: fullPath,
|
|
6756
|
+
ref: this.branch
|
|
6757
|
+
});
|
|
6758
|
+
if ("sha" in existing.data) {
|
|
6759
|
+
sha = existing.data.sha;
|
|
6760
|
+
}
|
|
6761
|
+
}
|
|
6762
|
+
if (!sha) {
|
|
6763
|
+
return new Error(`Cannot delete file at ${relativePath}: SHA not found`);
|
|
6764
|
+
}
|
|
6765
|
+
await this.octokit.repos.deleteFile({
|
|
6766
|
+
owner: this.owner,
|
|
6767
|
+
repo: this.repo,
|
|
6768
|
+
path: fullPath,
|
|
6769
|
+
message: `Delete ${fullPath}`,
|
|
6770
|
+
sha,
|
|
6771
|
+
branch: this.branch
|
|
5748
6772
|
});
|
|
6773
|
+
return null;
|
|
6774
|
+
} catch (error) {
|
|
6775
|
+
return error instanceof Error ? error : new Error(`Failed to delete file at ${relativePath}`);
|
|
6776
|
+
}
|
|
6777
|
+
}
|
|
6778
|
+
/**
|
|
6779
|
+
* Create directory by creating a .gitkeep file
|
|
6780
|
+
*/
|
|
6781
|
+
async createDirectory(relativePath) {
|
|
6782
|
+
try {
|
|
6783
|
+
const gitkeepPath = this.pathSystem.join(relativePath, ".gitkeep");
|
|
6784
|
+
return await this.writeFile(gitkeepPath, "");
|
|
6785
|
+
} catch (error) {
|
|
6786
|
+
return error instanceof Error ? error : new Error(`Failed to create directory at ${relativePath}`);
|
|
6787
|
+
}
|
|
6788
|
+
}
|
|
6789
|
+
/**
|
|
6790
|
+
* Create directory if it doesn't exist
|
|
6791
|
+
*/
|
|
6792
|
+
async ensureDirectoryExists(relativePath) {
|
|
6793
|
+
try {
|
|
6794
|
+
if (this.reader) {
|
|
6795
|
+
const exists = await this.reader.exists(relativePath);
|
|
6796
|
+
if (exists) {
|
|
6797
|
+
return null;
|
|
6798
|
+
}
|
|
6799
|
+
}
|
|
6800
|
+
return await this.createDirectory(relativePath);
|
|
6801
|
+
} catch (error) {
|
|
6802
|
+
return error instanceof Error ? error : new Error(`Failed to ensure directory exists at ${relativePath}`);
|
|
6803
|
+
}
|
|
6804
|
+
}
|
|
6805
|
+
/**
|
|
6806
|
+
* Copy file to new location
|
|
6807
|
+
*/
|
|
6808
|
+
async copyFile(sourcePath, destinationPath) {
|
|
6809
|
+
try {
|
|
6810
|
+
if (!this.reader) {
|
|
6811
|
+
return new Error("Reader is required for copy operation");
|
|
6812
|
+
}
|
|
6813
|
+
const content = await this.reader.readFile(sourcePath);
|
|
6814
|
+
if (content instanceof Error) {
|
|
6815
|
+
return content;
|
|
6816
|
+
}
|
|
6817
|
+
if (content === null) {
|
|
6818
|
+
return new Error(`Source file ${sourcePath} does not exist`);
|
|
6819
|
+
}
|
|
6820
|
+
return await this.writeFile(destinationPath, content);
|
|
6821
|
+
} catch (error) {
|
|
6822
|
+
return error instanceof Error ? error : new Error(
|
|
6823
|
+
`Failed to copy file from ${sourcePath} to ${destinationPath}`
|
|
6824
|
+
);
|
|
6825
|
+
}
|
|
6826
|
+
}
|
|
6827
|
+
/**
|
|
6828
|
+
* Move file to new location
|
|
6829
|
+
*/
|
|
6830
|
+
async moveFile(sourcePath, destinationPath) {
|
|
6831
|
+
try {
|
|
6832
|
+
const copyResult = await this.copyFile(sourcePath, destinationPath);
|
|
6833
|
+
if (copyResult !== null) {
|
|
6834
|
+
return copyResult;
|
|
6835
|
+
}
|
|
6836
|
+
return await this.deleteFile(sourcePath);
|
|
6837
|
+
} catch (error) {
|
|
6838
|
+
return error instanceof Error ? error : new Error(
|
|
6839
|
+
`Failed to move file from ${sourcePath} to ${destinationPath}`
|
|
6840
|
+
);
|
|
5749
6841
|
}
|
|
5750
6842
|
}
|
|
5751
6843
|
};
|
|
5752
6844
|
|
|
6845
|
+
// lib/doc-file-system-octokit.ts
|
|
6846
|
+
var DocFileSystemOctokit = class extends DocFileSystem {
|
|
6847
|
+
owner;
|
|
6848
|
+
repo;
|
|
6849
|
+
branch;
|
|
6850
|
+
constructor(props) {
|
|
6851
|
+
const reader = new DocFileSystemOctokitRead({
|
|
6852
|
+
owner: props.owner,
|
|
6853
|
+
repo: props.repo,
|
|
6854
|
+
basePath: props.basePath,
|
|
6855
|
+
branch: props.branch,
|
|
6856
|
+
token: props.token,
|
|
6857
|
+
pathSystem: props.pathSystem
|
|
6858
|
+
});
|
|
6859
|
+
const writer = new DocFileSystemOctokitWrite({
|
|
6860
|
+
owner: props.owner,
|
|
6861
|
+
repo: props.repo,
|
|
6862
|
+
basePath: props.basePath,
|
|
6863
|
+
branch: props.branch,
|
|
6864
|
+
token: props.token,
|
|
6865
|
+
pathSystem: props.pathSystem,
|
|
6866
|
+
reader
|
|
6867
|
+
});
|
|
6868
|
+
super({
|
|
6869
|
+
basePath: props.basePath,
|
|
6870
|
+
pathSystem: props.pathSystem,
|
|
6871
|
+
reader,
|
|
6872
|
+
writer
|
|
6873
|
+
});
|
|
6874
|
+
this.owner = props.owner;
|
|
6875
|
+
this.repo = props.repo;
|
|
6876
|
+
this.branch = props.branch ?? "main";
|
|
6877
|
+
Object.freeze(this);
|
|
6878
|
+
}
|
|
6879
|
+
/**
|
|
6880
|
+
* Get repository information
|
|
6881
|
+
*/
|
|
6882
|
+
getRepositoryInfo() {
|
|
6883
|
+
return {
|
|
6884
|
+
owner: this.owner,
|
|
6885
|
+
repo: this.repo,
|
|
6886
|
+
branch: this.branch
|
|
6887
|
+
};
|
|
6888
|
+
}
|
|
6889
|
+
};
|
|
6890
|
+
|
|
5753
6891
|
// lib/doc-path-system-mock.ts
|
|
5754
6892
|
var DocPathSystemMock = class _DocPathSystemMock extends DocPathSystem {
|
|
5755
6893
|
_separator;
|
|
@@ -6390,7 +7528,15 @@ export {
|
|
|
6390
7528
|
DocFilePathValue,
|
|
6391
7529
|
DocFileRelationReference,
|
|
6392
7530
|
DocFileSystem,
|
|
7531
|
+
DocFileSystemJson,
|
|
7532
|
+
DocFileSystemJsonRead,
|
|
7533
|
+
DocFileSystemJsonWrite,
|
|
6393
7534
|
DocFileSystemMock,
|
|
7535
|
+
DocFileSystemOctokit,
|
|
7536
|
+
DocFileSystemOctokitRead,
|
|
7537
|
+
DocFileSystemOctokitWrite,
|
|
7538
|
+
DocFileSystemRead,
|
|
7539
|
+
DocFileSystemWrite,
|
|
6394
7540
|
DocFileTreeSystem,
|
|
6395
7541
|
DocFileUnknownEntity,
|
|
6396
7542
|
DocFileUnknownReference,
|