inibase 1.0.0-rc.102 → 1.0.0-rc.104
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/file.d.ts +1 -0
- package/dist/file.js +25 -11
- package/package.json +2 -2
package/dist/file.d.ts
CHANGED
|
@@ -3,6 +3,7 @@ export declare const lock: (folderPath: string, prefix?: string) => Promise<void
|
|
|
3
3
|
export declare const unlock: (folderPath: string, prefix?: string) => Promise<void>;
|
|
4
4
|
export declare const write: (filePath: string, data: any) => Promise<void>;
|
|
5
5
|
export declare const read: (filePath: string) => Promise<string>;
|
|
6
|
+
export declare function escapeShellPath(filePath: string): string;
|
|
6
7
|
/**
|
|
7
8
|
* Checks if a file or directory exists at the specified path.
|
|
8
9
|
*
|
package/dist/file.js
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { createWriteStream } from "node:fs";
|
|
2
2
|
import { access, appendFile, copyFile, constants as fsConstants, open, readFile, unlink, writeFile, } from "node:fs/promises";
|
|
3
|
-
import { join } from "node:path";
|
|
3
|
+
import { join, resolve } from "node:path";
|
|
4
4
|
import { createInterface } from "node:readline";
|
|
5
5
|
import { Transform } from "node:stream";
|
|
6
6
|
import { pipeline } from "node:stream/promises";
|
|
7
7
|
import { createGunzip, createGzip } from "node:zlib";
|
|
8
|
+
import { spawn as spawnSync } from "node:child_process";
|
|
8
9
|
import Inison from "inison";
|
|
9
10
|
import { detectFieldType, isArrayOfObjects, isStringified, isNumber, isObject, } from "./utils.js";
|
|
10
11
|
import { compare, encodeID, exec, gunzip, gzip } from "./utils.server.js";
|
|
11
|
-
import { spawn } from "node:child_process";
|
|
12
12
|
export const lock = async (folderPath, prefix) => {
|
|
13
13
|
let lockFile = null;
|
|
14
14
|
const lockFilePath = join(folderPath, `${prefix ?? ""}.locked`);
|
|
@@ -36,6 +36,12 @@ export const write = async (filePath, data) => {
|
|
|
36
36
|
export const read = async (filePath) => filePath.endsWith(".gz")
|
|
37
37
|
? (await gunzip(await readFile(filePath, "utf8"))).toString()
|
|
38
38
|
: await readFile(filePath, "utf8");
|
|
39
|
+
export function escapeShellPath(filePath) {
|
|
40
|
+
// Resolve the path to avoid relative path issues
|
|
41
|
+
const resolvedPath = resolve(filePath);
|
|
42
|
+
// Escape double quotes and special shell characters
|
|
43
|
+
return resolvedPath.replace(/(["\\$`])/g, "\\$1");
|
|
44
|
+
}
|
|
39
45
|
const _pipeline = async (filePath, rl, writeStream, transform) => {
|
|
40
46
|
if (filePath.endsWith(".gz"))
|
|
41
47
|
await pipeline(rl, transform, createGzip(), writeStream);
|
|
@@ -194,9 +200,10 @@ export async function get(filePath, lineNumbers, fieldType, fieldChildrenType, s
|
|
|
194
200
|
}
|
|
195
201
|
}
|
|
196
202
|
else if (lineNumbers == -1) {
|
|
203
|
+
const escapedFilePath = `${escapeShellPath(filePath)}`;
|
|
197
204
|
const command = filePath.endsWith(".gz")
|
|
198
|
-
? `zcat ${
|
|
199
|
-
: `sed -n '$p' ${
|
|
205
|
+
? `zcat ${escapedFilePath} | sed -n '$p'`
|
|
206
|
+
: `sed -n '$p' ${escapedFilePath}`, foundedLine = (await exec(command)).stdout.trimEnd();
|
|
200
207
|
if (foundedLine)
|
|
201
208
|
lines[linesCount] = decode(foundedLine, fieldType, fieldChildrenType, secretKey);
|
|
202
209
|
}
|
|
@@ -215,9 +222,10 @@ export async function get(filePath, lineNumbers, fieldType, fieldChildrenType, s
|
|
|
215
222
|
}
|
|
216
223
|
return [lines, linesCount];
|
|
217
224
|
}
|
|
225
|
+
const escapedFilePath = `${escapeShellPath(filePath)}`;
|
|
218
226
|
const command = filePath.endsWith(".gz")
|
|
219
|
-
? `zcat ${
|
|
220
|
-
: `sed -n '${lineNumbers.join("p;")}p' ${
|
|
227
|
+
? `zcat "${escapedFilePath}" | sed -n '${lineNumbers.join("p;")}p'`
|
|
228
|
+
: `sed -n '${lineNumbers.join("p;")}p' "${escapedFilePath}"`, foundedLines = (await exec(command)).stdout.trimEnd().split("\n");
|
|
221
229
|
let index = 0;
|
|
222
230
|
for (const line of foundedLines) {
|
|
223
231
|
lines[lineNumbers[index]] = decode(line, fieldType, fieldChildrenType, secretKey);
|
|
@@ -278,7 +286,7 @@ export const replace = async (filePath, replacements, totalItems) => {
|
|
|
278
286
|
}
|
|
279
287
|
else {
|
|
280
288
|
return new Promise((resolve) => {
|
|
281
|
-
const sedProcess =
|
|
289
|
+
const sedProcess = spawnSync("sed", [
|
|
282
290
|
"-e",
|
|
283
291
|
`s/.*/${replacements}/`,
|
|
284
292
|
"-e",
|
|
@@ -347,9 +355,10 @@ export const append = async (filePath, data) => {
|
|
|
347
355
|
await appendFile(fileTempPath, `${Array.isArray(data) ? data.join("\n") : data}\n`);
|
|
348
356
|
}
|
|
349
357
|
else {
|
|
358
|
+
const escapedFileTempPath = `${escapeShellPath(fileTempPath)}`;
|
|
350
359
|
await exec(`echo $'${(Array.isArray(data) ? data.join("\n") : data)
|
|
351
360
|
.toString()
|
|
352
|
-
.replace(/'/g, "\\'")}' | gzip - >> ${
|
|
361
|
+
.replace(/'/g, "\\'")}' | gzip - >> ${escapedFileTempPath}`);
|
|
353
362
|
}
|
|
354
363
|
}
|
|
355
364
|
else
|
|
@@ -402,7 +411,10 @@ export const prepend = async (filePath, data) => {
|
|
|
402
411
|
const fileChildTempPath = filePath.replace(/([^/]+)\/?$/, ".tmp/tmp_$1");
|
|
403
412
|
try {
|
|
404
413
|
await write(fileChildTempPath, `${Array.isArray(data) ? data.join("\n") : data}\n`);
|
|
405
|
-
|
|
414
|
+
const escapedFilePath = `${escapeShellPath(filePath)}`;
|
|
415
|
+
const escapedFileTempPath = `${escapeShellPath(fileTempPath)}`;
|
|
416
|
+
const escapedFileChildTempPath = `${escapeShellPath(fileChildTempPath)}`;
|
|
417
|
+
await exec(`cat ${escapedFileChildTempPath} ${escapedFilePath} > ${escapedFileTempPath}`);
|
|
406
418
|
}
|
|
407
419
|
catch {
|
|
408
420
|
return [fileTempPath, null];
|
|
@@ -439,9 +451,11 @@ export const remove = async (filePath, linesToDelete) => {
|
|
|
439
451
|
throw new Error("UNVALID_LINE_NUMBERS");
|
|
440
452
|
const fileTempPath = filePath.replace(/([^/]+)\/?$/, ".tmp/$1");
|
|
441
453
|
try {
|
|
454
|
+
const escapedFilePath = `${escapeShellPath(filePath)}`;
|
|
455
|
+
const escapedFileTempPath = `${escapeShellPath(fileTempPath)}`;
|
|
442
456
|
const command = filePath.endsWith(".gz")
|
|
443
|
-
? `zcat ${
|
|
444
|
-
: `sed "${linesToDelete.join("d;")}d" ${
|
|
457
|
+
? `zcat ${escapedFilePath} | sed "${linesToDelete.join("d;")}d" | gzip > ${fileTempPath}`
|
|
458
|
+
: `sed "${linesToDelete.join("d;")}d" ${escapedFilePath} > ${escapedFileTempPath}`;
|
|
445
459
|
await exec(command);
|
|
446
460
|
return [fileTempPath, filePath];
|
|
447
461
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "inibase",
|
|
3
|
-
"version": "1.0.0-rc.
|
|
3
|
+
"version": "1.0.0-rc.104",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Karim Amahtil",
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
},
|
|
20
20
|
"description": "A file-based & memory-efficient, serverless, ACID compliant, relational database management system",
|
|
21
21
|
"engines": {
|
|
22
|
-
"node": ">=
|
|
22
|
+
"node": ">=22"
|
|
23
23
|
},
|
|
24
24
|
"files": [
|
|
25
25
|
"/dist"
|