@axiom-lattice/core 3.1.1 → 3.1.2
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/dist/index.d.mts +4 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +54 -49
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +54 -49
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -17030,6 +17030,51 @@ var FilesystemBackend = class {
|
|
|
17030
17030
|
throw new Error(`Path: ${resolvedPath} outside root directory: ${this.cwd}`);
|
|
17031
17031
|
}
|
|
17032
17032
|
}
|
|
17033
|
+
async assertVirtualOpenedFileContained(resolvedPath, openedStat) {
|
|
17034
|
+
if (!this.virtualMode) {
|
|
17035
|
+
return;
|
|
17036
|
+
}
|
|
17037
|
+
const [rootPath, realFilePath] = await Promise.all([
|
|
17038
|
+
fs2.realpath(this.cwd),
|
|
17039
|
+
fs2.realpath(resolvedPath)
|
|
17040
|
+
]);
|
|
17041
|
+
const relative4 = path4.relative(rootPath, realFilePath);
|
|
17042
|
+
if (relative4 === ".." || relative4.startsWith(`..${path4.sep}`) || path4.isAbsolute(relative4)) {
|
|
17043
|
+
throw new Error(`Path: ${resolvedPath} outside root directory: ${this.cwd}`);
|
|
17044
|
+
}
|
|
17045
|
+
const realPathStat = await fs2.stat(realFilePath);
|
|
17046
|
+
if (realPathStat.dev !== openedStat.dev || realPathStat.ino !== openedStat.ino) {
|
|
17047
|
+
throw new Error(`File changed during secure read: ${resolvedPath}`);
|
|
17048
|
+
}
|
|
17049
|
+
}
|
|
17050
|
+
async readFileBuffer(filePath) {
|
|
17051
|
+
const resolvedPath = this.resolvePath(filePath);
|
|
17052
|
+
await this.assertVirtualParentContained(resolvedPath);
|
|
17053
|
+
if (!SUPPORTS_NOFOLLOW) {
|
|
17054
|
+
const initialStat = await fs2.lstat(resolvedPath);
|
|
17055
|
+
if (initialStat.isSymbolicLink()) {
|
|
17056
|
+
throw new Error(`Symlinks are not allowed: ${filePath}`);
|
|
17057
|
+
}
|
|
17058
|
+
}
|
|
17059
|
+
const flags = SUPPORTS_NOFOLLOW ? fsSync.constants.O_RDONLY | fsSync.constants.O_NOFOLLOW : fsSync.constants.O_RDONLY;
|
|
17060
|
+
const fd = await fs2.open(resolvedPath, flags);
|
|
17061
|
+
try {
|
|
17062
|
+
const stat4 = await fd.stat();
|
|
17063
|
+
if (!stat4.isFile()) {
|
|
17064
|
+
throw new Error(`File '${filePath}' not found`);
|
|
17065
|
+
}
|
|
17066
|
+
await this.assertVirtualOpenedFileContained(resolvedPath, stat4);
|
|
17067
|
+
if (!SUPPORTS_NOFOLLOW) {
|
|
17068
|
+
const finalStat = await fs2.lstat(resolvedPath);
|
|
17069
|
+
if (finalStat.isSymbolicLink() || finalStat.dev !== stat4.dev || finalStat.ino !== stat4.ino) {
|
|
17070
|
+
throw new Error(`File changed during secure read: ${resolvedPath}`);
|
|
17071
|
+
}
|
|
17072
|
+
}
|
|
17073
|
+
return { content: await fd.readFile(), stat: stat4 };
|
|
17074
|
+
} finally {
|
|
17075
|
+
await fd.close();
|
|
17076
|
+
}
|
|
17077
|
+
}
|
|
17033
17078
|
validateDeleteTarget(filePath, stat4) {
|
|
17034
17079
|
if (stat4.isSymbolicLink()) {
|
|
17035
17080
|
return `Error: Cannot delete '${filePath}': symlinks are not allowed`;
|
|
@@ -17129,32 +17174,8 @@ var FilesystemBackend = class {
|
|
|
17129
17174
|
*/
|
|
17130
17175
|
async read(filePath, offset = 0, limit = 2e3) {
|
|
17131
17176
|
try {
|
|
17132
|
-
const
|
|
17133
|
-
|
|
17134
|
-
if (SUPPORTS_NOFOLLOW) {
|
|
17135
|
-
const stat4 = await fs2.stat(resolvedPath);
|
|
17136
|
-
if (!stat4.isFile()) {
|
|
17137
|
-
return `Error: File '${filePath}' not found`;
|
|
17138
|
-
}
|
|
17139
|
-
const fd = await fs2.open(
|
|
17140
|
-
resolvedPath,
|
|
17141
|
-
fsSync.constants.O_RDONLY | fsSync.constants.O_NOFOLLOW
|
|
17142
|
-
);
|
|
17143
|
-
try {
|
|
17144
|
-
content = await fd.readFile({ encoding: "utf-8" });
|
|
17145
|
-
} finally {
|
|
17146
|
-
await fd.close();
|
|
17147
|
-
}
|
|
17148
|
-
} else {
|
|
17149
|
-
const stat4 = await fs2.lstat(resolvedPath);
|
|
17150
|
-
if (stat4.isSymbolicLink()) {
|
|
17151
|
-
return `Error: Symlinks are not allowed: ${filePath}`;
|
|
17152
|
-
}
|
|
17153
|
-
if (!stat4.isFile()) {
|
|
17154
|
-
return `Error: File '${filePath}' not found`;
|
|
17155
|
-
}
|
|
17156
|
-
content = await fs2.readFile(resolvedPath, "utf-8");
|
|
17157
|
-
}
|
|
17177
|
+
const { content: buffer2 } = await this.readFileBuffer(filePath);
|
|
17178
|
+
const content = buffer2.toString("utf-8");
|
|
17158
17179
|
const emptyMsg = checkEmptyContent(content);
|
|
17159
17180
|
if (emptyMsg) {
|
|
17160
17181
|
return emptyMsg;
|
|
@@ -17178,35 +17199,19 @@ var FilesystemBackend = class {
|
|
|
17178
17199
|
* @returns Raw file content as FileData
|
|
17179
17200
|
*/
|
|
17180
17201
|
async readRaw(filePath) {
|
|
17181
|
-
const
|
|
17182
|
-
|
|
17183
|
-
let stat4;
|
|
17184
|
-
if (SUPPORTS_NOFOLLOW) {
|
|
17185
|
-
stat4 = await fs2.stat(resolvedPath);
|
|
17186
|
-
if (!stat4.isFile()) throw new Error(`File '${filePath}' not found`);
|
|
17187
|
-
const fd = await fs2.open(
|
|
17188
|
-
resolvedPath,
|
|
17189
|
-
fsSync.constants.O_RDONLY | fsSync.constants.O_NOFOLLOW
|
|
17190
|
-
);
|
|
17191
|
-
try {
|
|
17192
|
-
content = await fd.readFile({ encoding: "utf-8" });
|
|
17193
|
-
} finally {
|
|
17194
|
-
await fd.close();
|
|
17195
|
-
}
|
|
17196
|
-
} else {
|
|
17197
|
-
stat4 = await fs2.lstat(resolvedPath);
|
|
17198
|
-
if (stat4.isSymbolicLink()) {
|
|
17199
|
-
throw new Error(`Symlinks are not allowed: ${filePath}`);
|
|
17200
|
-
}
|
|
17201
|
-
if (!stat4.isFile()) throw new Error(`File '${filePath}' not found`);
|
|
17202
|
-
content = await fs2.readFile(resolvedPath, "utf-8");
|
|
17203
|
-
}
|
|
17202
|
+
const { content: buffer2, stat: stat4 } = await this.readFileBuffer(filePath);
|
|
17203
|
+
const content = buffer2.toString("utf-8");
|
|
17204
17204
|
return {
|
|
17205
17205
|
content: content.split("\n"),
|
|
17206
17206
|
created_at: stat4.ctime.toISOString(),
|
|
17207
17207
|
modified_at: stat4.mtime.toISOString()
|
|
17208
17208
|
};
|
|
17209
17209
|
}
|
|
17210
|
+
/** Read file content as raw bytes without following symbolic links. */
|
|
17211
|
+
async readBinary(filePath) {
|
|
17212
|
+
const { content } = await this.readFileBuffer(filePath);
|
|
17213
|
+
return content;
|
|
17214
|
+
}
|
|
17210
17215
|
/**
|
|
17211
17216
|
* Create a new file with content.
|
|
17212
17217
|
* Returns WriteResult. External storage sets filesUpdate=null.
|