@interactive-inc/docs-client 1.0.18 → 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 +852 -240
- package/build/index.js +1394 -236
- package/package.json +3 -2
package/build/index.js
CHANGED
|
@@ -4255,11 +4255,23 @@ var DocDirectoryReference = class _DocDirectoryReference {
|
|
|
4255
4255
|
get config() {
|
|
4256
4256
|
return this.props.config;
|
|
4257
4257
|
}
|
|
4258
|
-
get
|
|
4258
|
+
get path() {
|
|
4259
4259
|
return this.props.path;
|
|
4260
4260
|
}
|
|
4261
|
+
/**
|
|
4262
|
+
* @deprecated
|
|
4263
|
+
*/
|
|
4264
|
+
get relativePath() {
|
|
4265
|
+
return this.path;
|
|
4266
|
+
}
|
|
4267
|
+
get fullPath() {
|
|
4268
|
+
return this.pathSystem.join(this.basePath, this.path);
|
|
4269
|
+
}
|
|
4270
|
+
/**
|
|
4271
|
+
* @deprecated
|
|
4272
|
+
*/
|
|
4261
4273
|
get absolutePath() {
|
|
4262
|
-
return this.
|
|
4274
|
+
return this.fullPath;
|
|
4263
4275
|
}
|
|
4264
4276
|
get indexFileName() {
|
|
4265
4277
|
return this.props.indexFileName;
|
|
@@ -4275,7 +4287,7 @@ var DocDirectoryReference = class _DocDirectoryReference {
|
|
|
4275
4287
|
return this.props.archiveDirectoryName;
|
|
4276
4288
|
}
|
|
4277
4289
|
get name() {
|
|
4278
|
-
return this.pathSystem.basename(this.
|
|
4290
|
+
return this.pathSystem.basename(this.path);
|
|
4279
4291
|
}
|
|
4280
4292
|
async fileNames() {
|
|
4281
4293
|
const filePaths = await this.fileSystem.readDirectoryFilePaths(
|
|
@@ -5126,9 +5138,9 @@ var DocClient = class {
|
|
|
5126
5138
|
}
|
|
5127
5139
|
};
|
|
5128
5140
|
|
|
5129
|
-
// lib/doc-file-system.ts
|
|
5141
|
+
// lib/doc-file-system-read.ts
|
|
5130
5142
|
import * as fs from "fs/promises";
|
|
5131
|
-
var
|
|
5143
|
+
var DocFileSystemRead = class {
|
|
5132
5144
|
basePath;
|
|
5133
5145
|
pathSystem;
|
|
5134
5146
|
constructor(props) {
|
|
@@ -5148,32 +5160,6 @@ var DocFileSystem = class {
|
|
|
5148
5160
|
return error instanceof Error ? error : new Error(`Failed to read file at ${relativePath}`);
|
|
5149
5161
|
}
|
|
5150
5162
|
}
|
|
5151
|
-
/**
|
|
5152
|
-
* Write content to file at the specified path (creates directory if needed)
|
|
5153
|
-
*/
|
|
5154
|
-
async writeFile(relativePath, content) {
|
|
5155
|
-
try {
|
|
5156
|
-
const fullPath = this.pathSystem.join(this.basePath, relativePath);
|
|
5157
|
-
const dirPath = this.pathSystem.dirname(fullPath);
|
|
5158
|
-
await fs.mkdir(dirPath, { recursive: true });
|
|
5159
|
-
await fs.writeFile(fullPath, content, "utf-8");
|
|
5160
|
-
return null;
|
|
5161
|
-
} catch (error) {
|
|
5162
|
-
return error instanceof Error ? error : new Error(`Failed to write file at ${relativePath}`);
|
|
5163
|
-
}
|
|
5164
|
-
}
|
|
5165
|
-
/**
|
|
5166
|
-
* Delete file at the specified path
|
|
5167
|
-
*/
|
|
5168
|
-
async deleteFile(relativePath) {
|
|
5169
|
-
try {
|
|
5170
|
-
const fullPath = this.pathSystem.join(this.basePath, relativePath);
|
|
5171
|
-
await fs.unlink(fullPath);
|
|
5172
|
-
return null;
|
|
5173
|
-
} catch (error) {
|
|
5174
|
-
return new Error(`Failed to delete file at ${relativePath}: ${error}`);
|
|
5175
|
-
}
|
|
5176
|
-
}
|
|
5177
5163
|
/**
|
|
5178
5164
|
* Get file name from path
|
|
5179
5165
|
*/
|
|
@@ -5277,27 +5263,90 @@ var DocFileSystem = class {
|
|
|
5277
5263
|
return this.pathSystem.join(this.basePath, relativePath);
|
|
5278
5264
|
}
|
|
5279
5265
|
/**
|
|
5280
|
-
*
|
|
5266
|
+
* Get file size in bytes
|
|
5281
5267
|
*/
|
|
5282
|
-
async
|
|
5268
|
+
async getFileSize(relativePath) {
|
|
5283
5269
|
try {
|
|
5284
5270
|
const fullPath = this.pathSystem.join(this.basePath, relativePath);
|
|
5285
|
-
await fs.
|
|
5286
|
-
return
|
|
5271
|
+
const stats = await fs.stat(fullPath);
|
|
5272
|
+
return stats.size;
|
|
5287
5273
|
} catch (error) {
|
|
5288
|
-
return error instanceof Error ? error : new Error(`Failed to
|
|
5274
|
+
return error instanceof Error ? error : new Error(`Failed to get file size at ${relativePath}`);
|
|
5289
5275
|
}
|
|
5290
5276
|
}
|
|
5291
5277
|
/**
|
|
5292
|
-
* Get file
|
|
5278
|
+
* Get file last modified time
|
|
5293
5279
|
*/
|
|
5294
|
-
async
|
|
5280
|
+
async getFileModifiedTime(relativePath) {
|
|
5295
5281
|
try {
|
|
5296
5282
|
const fullPath = this.pathSystem.join(this.basePath, relativePath);
|
|
5297
5283
|
const stats = await fs.stat(fullPath);
|
|
5298
|
-
return stats.
|
|
5284
|
+
return stats.mtime;
|
|
5299
5285
|
} catch (error) {
|
|
5300
|
-
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}`);
|
|
5301
5350
|
}
|
|
5302
5351
|
}
|
|
5303
5352
|
/**
|
|
@@ -5305,12 +5354,16 @@ var DocFileSystem = class {
|
|
|
5305
5354
|
*/
|
|
5306
5355
|
async ensureDirectoryExists(relativePath) {
|
|
5307
5356
|
try {
|
|
5308
|
-
if (
|
|
5309
|
-
const
|
|
5310
|
-
if (
|
|
5311
|
-
return
|
|
5357
|
+
if (this.reader) {
|
|
5358
|
+
const exists = await this.reader.exists(relativePath);
|
|
5359
|
+
if (exists) {
|
|
5360
|
+
return null;
|
|
5312
5361
|
}
|
|
5313
5362
|
}
|
|
5363
|
+
const result = await this.createDirectory(relativePath);
|
|
5364
|
+
if (result instanceof Error) {
|
|
5365
|
+
return result;
|
|
5366
|
+
}
|
|
5314
5367
|
return null;
|
|
5315
5368
|
} catch (error) {
|
|
5316
5369
|
return error instanceof Error ? error : new Error(`Failed to ensure directory exists at ${relativePath}`);
|
|
@@ -5323,7 +5376,7 @@ var DocFileSystem = class {
|
|
|
5323
5376
|
try {
|
|
5324
5377
|
const sourceFullPath = this.pathSystem.join(this.basePath, sourcePath);
|
|
5325
5378
|
const destFullPath = this.pathSystem.join(this.basePath, destinationPath);
|
|
5326
|
-
await
|
|
5379
|
+
await fs2.copyFile(sourceFullPath, destFullPath);
|
|
5327
5380
|
return null;
|
|
5328
5381
|
} catch (error) {
|
|
5329
5382
|
return error instanceof Error ? error : new Error(
|
|
@@ -5338,7 +5391,7 @@ var DocFileSystem = class {
|
|
|
5338
5391
|
try {
|
|
5339
5392
|
const sourceFullPath = this.pathSystem.join(this.basePath, sourcePath);
|
|
5340
5393
|
const destFullPath = this.pathSystem.join(this.basePath, destinationPath);
|
|
5341
|
-
await
|
|
5394
|
+
await fs2.rename(sourceFullPath, destFullPath);
|
|
5342
5395
|
return null;
|
|
5343
5396
|
} catch (error) {
|
|
5344
5397
|
return error instanceof Error ? error : new Error(
|
|
@@ -5346,144 +5399,776 @@ var DocFileSystem = class {
|
|
|
5346
5399
|
);
|
|
5347
5400
|
}
|
|
5348
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
|
+
}
|
|
5349
5423
|
/**
|
|
5350
|
-
*
|
|
5424
|
+
* Read file content at the specified path
|
|
5351
5425
|
*/
|
|
5352
|
-
async
|
|
5353
|
-
|
|
5354
|
-
const fullPath = this.pathSystem.join(this.basePath, relativePath);
|
|
5355
|
-
const stats = await fs.stat(fullPath);
|
|
5356
|
-
return stats.mtime;
|
|
5357
|
-
} catch (error) {
|
|
5358
|
-
return error instanceof Error ? error : new Error(`Failed to get file modified time at ${relativePath}`);
|
|
5359
|
-
}
|
|
5426
|
+
async readFile(relativePath) {
|
|
5427
|
+
return this.reader.readFile(relativePath);
|
|
5360
5428
|
}
|
|
5361
5429
|
/**
|
|
5362
|
-
*
|
|
5430
|
+
* Write content to file at the specified path (creates directory if needed)
|
|
5363
5431
|
*/
|
|
5364
|
-
async
|
|
5365
|
-
|
|
5366
|
-
const fullPath = this.pathSystem.join(this.basePath, relativePath);
|
|
5367
|
-
const stats = await fs.stat(fullPath);
|
|
5368
|
-
return stats.birthtime;
|
|
5369
|
-
} catch (error) {
|
|
5370
|
-
return error instanceof Error ? error : new Error(`Failed to get file created time at ${relativePath}`);
|
|
5371
|
-
}
|
|
5432
|
+
async writeFile(relativePath, content) {
|
|
5433
|
+
return this.writer.writeFile(relativePath, content);
|
|
5372
5434
|
}
|
|
5373
|
-
|
|
5374
|
-
|
|
5375
|
-
|
|
5376
|
-
|
|
5377
|
-
|
|
5378
|
-
icon: \u{1F4DA}
|
|
5379
|
-
---
|
|
5380
|
-
|
|
5381
|
-
# Documentation
|
|
5382
|
-
|
|
5383
|
-
Welcome to the documentation!`,
|
|
5384
|
-
"docs/guide/index.md": `---
|
|
5385
|
-
icon: \u{1F4D6}
|
|
5386
|
-
---
|
|
5387
|
-
|
|
5388
|
-
# Guide
|
|
5389
|
-
|
|
5390
|
-
This is a guide.`,
|
|
5391
|
-
"docs/guide/getting-started.md": `# Getting Started
|
|
5392
|
-
|
|
5393
|
-
Let's get started!`,
|
|
5394
|
-
"docs/guide/advanced.md": `# Advanced
|
|
5395
|
-
|
|
5396
|
-
Advanced topics here.`,
|
|
5397
|
-
"docs/api/index.md": `---
|
|
5398
|
-
icon: \u{1F527}
|
|
5399
|
-
---
|
|
5400
|
-
|
|
5401
|
-
# API
|
|
5402
|
-
|
|
5403
|
-
API documentation.`,
|
|
5404
|
-
"docs/api/reference.md": `# API Reference
|
|
5405
|
-
|
|
5406
|
-
Complete API reference.`
|
|
5407
|
-
};
|
|
5408
|
-
var DocFileSystemMock = class _DocFileSystemMock extends DocFileSystem {
|
|
5409
|
-
files = /* @__PURE__ */ new Map();
|
|
5410
|
-
_pathSystem;
|
|
5411
|
-
_basePath;
|
|
5412
|
-
constructor(props) {
|
|
5413
|
-
super(props);
|
|
5414
|
-
this._pathSystem = props.pathSystem;
|
|
5415
|
-
this._basePath = props.basePath.endsWith("/") ? props.basePath.slice(0, -1) : props.basePath;
|
|
5416
|
-
if (!props.skipDefaultFiles) {
|
|
5417
|
-
this.setupTestFiles(mockDirectoryData);
|
|
5418
|
-
}
|
|
5419
|
-
Object.freeze(this);
|
|
5435
|
+
/**
|
|
5436
|
+
* Delete file at the specified path
|
|
5437
|
+
*/
|
|
5438
|
+
async deleteFile(relativePath) {
|
|
5439
|
+
return this.writer.deleteFile(relativePath);
|
|
5420
5440
|
}
|
|
5421
5441
|
/**
|
|
5422
|
-
*
|
|
5442
|
+
* Get file name from path
|
|
5423
5443
|
*/
|
|
5424
|
-
|
|
5425
|
-
return this.
|
|
5444
|
+
readFileName(relativePath) {
|
|
5445
|
+
return this.reader.readFileName(relativePath);
|
|
5426
5446
|
}
|
|
5427
5447
|
/**
|
|
5428
|
-
*
|
|
5448
|
+
* Get file extension from path
|
|
5429
5449
|
*/
|
|
5430
|
-
|
|
5431
|
-
|
|
5432
|
-
return filePath;
|
|
5433
|
-
}
|
|
5434
|
-
const cleanPath = filePath.startsWith("/") ? filePath.slice(1) : filePath;
|
|
5435
|
-
return `${this._basePath}/${cleanPath}`;
|
|
5450
|
+
readFileExtension(relativePath) {
|
|
5451
|
+
return this.reader.readFileExtension(relativePath);
|
|
5436
5452
|
}
|
|
5437
5453
|
/**
|
|
5438
|
-
*
|
|
5454
|
+
* Get directory path where the file exists
|
|
5439
5455
|
*/
|
|
5440
|
-
|
|
5441
|
-
|
|
5442
|
-
return new _DocFileSystemMock({ basePath, pathSystem });
|
|
5456
|
+
readFileDirectory(relativePath) {
|
|
5457
|
+
return this.reader.readFileDirectory(relativePath);
|
|
5443
5458
|
}
|
|
5444
5459
|
/**
|
|
5445
|
-
*
|
|
5460
|
+
* Get list of entries in directory
|
|
5446
5461
|
*/
|
|
5447
|
-
|
|
5448
|
-
|
|
5449
|
-
const basePath = props.basePath ?? "/test";
|
|
5450
|
-
const fileSystem = new _DocFileSystemMock({
|
|
5451
|
-
basePath,
|
|
5452
|
-
pathSystem,
|
|
5453
|
-
skipDefaultFiles: true
|
|
5454
|
-
});
|
|
5455
|
-
if (props.fileContents) {
|
|
5456
|
-
const now = /* @__PURE__ */ new Date();
|
|
5457
|
-
for (const [path, content] of Object.entries(props.fileContents)) {
|
|
5458
|
-
const cleanPath = path.startsWith("/") ? path.slice(1) : path;
|
|
5459
|
-
const normalizedPath = path.startsWith(basePath) ? path : `${basePath}/${cleanPath}`;
|
|
5460
|
-
fileSystem.files.set(normalizedPath, {
|
|
5461
|
-
content,
|
|
5462
|
-
modifiedTime: now,
|
|
5463
|
-
createdTime: now,
|
|
5464
|
-
size: new TextEncoder().encode(content).length
|
|
5465
|
-
});
|
|
5466
|
-
}
|
|
5467
|
-
}
|
|
5468
|
-
return fileSystem;
|
|
5462
|
+
async readDirectoryFileNames(relativePath = "") {
|
|
5463
|
+
return this.reader.readDirectoryFileNames(relativePath);
|
|
5469
5464
|
}
|
|
5470
|
-
async
|
|
5471
|
-
|
|
5472
|
-
const normalizedPath = this.normalizePath(filePath);
|
|
5473
|
-
const file = this.files.get(normalizedPath);
|
|
5474
|
-
return file ? file.content : null;
|
|
5475
|
-
} catch (error) {
|
|
5476
|
-
return error instanceof Error ? error : new Error(`Failed to read file at ${filePath}`);
|
|
5477
|
-
}
|
|
5465
|
+
async readDirectoryFilePaths(relativePath) {
|
|
5466
|
+
return this.reader.readDirectoryFilePaths(relativePath);
|
|
5478
5467
|
}
|
|
5479
|
-
|
|
5480
|
-
|
|
5481
|
-
|
|
5482
|
-
|
|
5483
|
-
|
|
5484
|
-
|
|
5485
|
-
|
|
5486
|
-
|
|
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,
|
|
5487
6172
|
createdTime: existing?.createdTime ?? now,
|
|
5488
6173
|
size: new TextEncoder().encode(content).length
|
|
5489
6174
|
});
|
|
@@ -5609,64 +6294,288 @@ var DocFileSystemMock = class _DocFileSystemMock extends DocFileSystem {
|
|
|
5609
6294
|
return error instanceof Error ? error : new Error(`Failed to get file size at ${filePath}`);
|
|
5610
6295
|
}
|
|
5611
6296
|
}
|
|
5612
|
-
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 = "") {
|
|
5613
6498
|
try {
|
|
5614
|
-
const
|
|
5615
|
-
const
|
|
5616
|
-
|
|
5617
|
-
|
|
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);
|
|
5618
6508
|
}
|
|
5619
|
-
return
|
|
6509
|
+
return new Error(`Path ${relativePath} is not a directory`);
|
|
5620
6510
|
} catch (error) {
|
|
5621
|
-
return error instanceof Error ? error : new Error(`Failed to
|
|
6511
|
+
return error instanceof Error ? error : new Error(`Failed to read directory at ${relativePath}`);
|
|
5622
6512
|
}
|
|
5623
6513
|
}
|
|
5624
|
-
|
|
6514
|
+
/**
|
|
6515
|
+
* Get list of file paths in directory
|
|
6516
|
+
*/
|
|
6517
|
+
async readDirectoryFilePaths(relativePath) {
|
|
5625
6518
|
try {
|
|
5626
|
-
const
|
|
5627
|
-
|
|
5628
|
-
|
|
5629
|
-
return new Error(`File not found: ${normalizedPath}`);
|
|
6519
|
+
const fileNames = await this.readDirectoryFileNames(relativePath);
|
|
6520
|
+
if (fileNames instanceof Error) {
|
|
6521
|
+
return fileNames;
|
|
5630
6522
|
}
|
|
5631
|
-
return
|
|
6523
|
+
return fileNames.map(
|
|
6524
|
+
(fileName) => this.pathSystem.join(relativePath, fileName)
|
|
6525
|
+
);
|
|
5632
6526
|
} catch (error) {
|
|
5633
|
-
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}`);
|
|
5634
6528
|
}
|
|
5635
6529
|
}
|
|
6530
|
+
/**
|
|
6531
|
+
* Check if path is a directory
|
|
6532
|
+
*/
|
|
5636
6533
|
async isDirectory(relativePath) {
|
|
5637
|
-
|
|
5638
|
-
|
|
5639
|
-
|
|
5640
|
-
|
|
5641
|
-
|
|
5642
|
-
|
|
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;
|
|
5643
6545
|
}
|
|
5644
|
-
return false;
|
|
5645
6546
|
}
|
|
6547
|
+
/**
|
|
6548
|
+
* Check if path is a file
|
|
6549
|
+
*/
|
|
5646
6550
|
async isFile(relativePath) {
|
|
5647
|
-
|
|
5648
|
-
|
|
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
|
+
}
|
|
5649
6563
|
}
|
|
5650
6564
|
/**
|
|
5651
|
-
*
|
|
6565
|
+
* Check if file or directory exists
|
|
5652
6566
|
*/
|
|
5653
|
-
async
|
|
6567
|
+
async exists(relativePath) {
|
|
5654
6568
|
try {
|
|
5655
|
-
const
|
|
5656
|
-
|
|
5657
|
-
|
|
5658
|
-
|
|
5659
|
-
|
|
5660
|
-
|
|
5661
|
-
|
|
5662
|
-
|
|
5663
|
-
|
|
5664
|
-
|
|
5665
|
-
}
|
|
5666
|
-
}
|
|
5667
|
-
return Array.from(entries).sort();
|
|
5668
|
-
} catch (error) {
|
|
5669
|
-
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;
|
|
5670
6579
|
}
|
|
5671
6580
|
}
|
|
5672
6581
|
/**
|
|
@@ -5682,62 +6591,303 @@ var DocFileSystemMock = class _DocFileSystemMock extends DocFileSystem {
|
|
|
5682
6591
|
return this.isFile(relativePath);
|
|
5683
6592
|
}
|
|
5684
6593
|
/**
|
|
5685
|
-
*
|
|
6594
|
+
* Get base path
|
|
5686
6595
|
*/
|
|
5687
|
-
|
|
5688
|
-
return
|
|
6596
|
+
getBasePath() {
|
|
6597
|
+
return this.basePath;
|
|
5689
6598
|
}
|
|
5690
6599
|
/**
|
|
5691
|
-
*
|
|
6600
|
+
* Convert relative path to absolute path
|
|
5692
6601
|
*/
|
|
5693
|
-
|
|
5694
|
-
this.
|
|
6602
|
+
resolve(relativePath) {
|
|
6603
|
+
return this.pathSystem.join(this.basePath, relativePath);
|
|
5695
6604
|
}
|
|
5696
6605
|
/**
|
|
5697
|
-
*
|
|
6606
|
+
* Get file size in bytes
|
|
5698
6607
|
*/
|
|
5699
|
-
|
|
5700
|
-
|
|
5701
|
-
|
|
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
|
+
}
|
|
5702
6628
|
}
|
|
5703
6629
|
/**
|
|
5704
|
-
* Get file
|
|
6630
|
+
* Get file last modified time
|
|
5705
6631
|
*/
|
|
5706
|
-
|
|
5707
|
-
|
|
5708
|
-
|
|
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
|
+
}
|
|
5709
6648
|
}
|
|
5710
6649
|
/**
|
|
5711
|
-
* Get
|
|
6650
|
+
* Get file creation time (first commit)
|
|
5712
6651
|
*/
|
|
5713
|
-
|
|
5714
|
-
|
|
5715
|
-
|
|
5716
|
-
|
|
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
|
+
}
|
|
5717
6668
|
}
|
|
5718
6669
|
/**
|
|
5719
|
-
* Get
|
|
6670
|
+
* Get cached SHA for a file
|
|
5720
6671
|
*/
|
|
5721
|
-
|
|
5722
|
-
|
|
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);
|
|
5723
6697
|
}
|
|
5724
6698
|
/**
|
|
5725
|
-
*
|
|
6699
|
+
* Write content to file in GitHub repository
|
|
5726
6700
|
*/
|
|
5727
|
-
|
|
5728
|
-
|
|
5729
|
-
|
|
5730
|
-
const
|
|
5731
|
-
|
|
5732
|
-
|
|
5733
|
-
|
|
5734
|
-
|
|
5735
|
-
|
|
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
|
|
5736
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
|
+
);
|
|
5737
6841
|
}
|
|
5738
6842
|
}
|
|
5739
6843
|
};
|
|
5740
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
|
+
|
|
5741
6891
|
// lib/doc-path-system-mock.ts
|
|
5742
6892
|
var DocPathSystemMock = class _DocPathSystemMock extends DocPathSystem {
|
|
5743
6893
|
_separator;
|
|
@@ -6378,7 +7528,15 @@ export {
|
|
|
6378
7528
|
DocFilePathValue,
|
|
6379
7529
|
DocFileRelationReference,
|
|
6380
7530
|
DocFileSystem,
|
|
7531
|
+
DocFileSystemJson,
|
|
7532
|
+
DocFileSystemJsonRead,
|
|
7533
|
+
DocFileSystemJsonWrite,
|
|
6381
7534
|
DocFileSystemMock,
|
|
7535
|
+
DocFileSystemOctokit,
|
|
7536
|
+
DocFileSystemOctokitRead,
|
|
7537
|
+
DocFileSystemOctokitWrite,
|
|
7538
|
+
DocFileSystemRead,
|
|
7539
|
+
DocFileSystemWrite,
|
|
6382
7540
|
DocFileTreeSystem,
|
|
6383
7541
|
DocFileUnknownEntity,
|
|
6384
7542
|
DocFileUnknownReference,
|