@lmthing/repl 0.0.1
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/crypto-BTVPQPPV.js +45 -0
- package/dist/csv-3IL3IKAY.js +115 -0
- package/dist/date-DL6PIRCI.js +56 -0
- package/dist/db-IVNVHDFE.js +68 -0
- package/dist/env-PPLEQ47H.js +47 -0
- package/dist/fetch-TN4ZJVQW.js +118 -0
- package/dist/fs-QRXDDXB5.js +127 -0
- package/dist/image-FGNY3CMJ.js +56 -0
- package/dist/index.d.ts +1691 -0
- package/dist/index.js +3809 -0
- package/dist/json-VPTMTXR6.js +113 -0
- package/dist/path-K3VLZVTH.js +54 -0
- package/dist/shell-NAGRIUA4.js +102 -0
- package/package.json +39 -0
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
// src/catalog/json.ts
|
|
2
|
+
function queryPath(data, path) {
|
|
3
|
+
const parts = path.replace(/^\$\.?/, "").split(".").filter(Boolean);
|
|
4
|
+
let current = data;
|
|
5
|
+
for (const part of parts) {
|
|
6
|
+
if (current == null) return void 0;
|
|
7
|
+
const arrayMatch = part.match(/^(\w+)\[(\*|\d+)\]$/);
|
|
8
|
+
if (arrayMatch) {
|
|
9
|
+
const [, key, index] = arrayMatch;
|
|
10
|
+
current = current[key];
|
|
11
|
+
if (!Array.isArray(current)) return void 0;
|
|
12
|
+
if (index === "*") return current;
|
|
13
|
+
current = current[parseInt(index, 10)];
|
|
14
|
+
} else {
|
|
15
|
+
current = current[part];
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
return current;
|
|
19
|
+
}
|
|
20
|
+
function deepMerge(...objects) {
|
|
21
|
+
const result = {};
|
|
22
|
+
for (const obj of objects) {
|
|
23
|
+
if (obj && typeof obj === "object" && !Array.isArray(obj)) {
|
|
24
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
25
|
+
if (typeof value === "object" && value !== null && !Array.isArray(value) && typeof result[key] === "object" && result[key] !== null && !Array.isArray(result[key])) {
|
|
26
|
+
result[key] = deepMerge(result[key], value);
|
|
27
|
+
} else {
|
|
28
|
+
result[key] = value;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
return result;
|
|
34
|
+
}
|
|
35
|
+
function diff(a, b, path = "$") {
|
|
36
|
+
const diffs = [];
|
|
37
|
+
if (a === b) return diffs;
|
|
38
|
+
if (typeof a !== typeof b || a === null || b === null || typeof a !== "object") {
|
|
39
|
+
diffs.push({ path, type: "changed", oldValue: a, newValue: b });
|
|
40
|
+
return diffs;
|
|
41
|
+
}
|
|
42
|
+
const aObj = a;
|
|
43
|
+
const bObj = b;
|
|
44
|
+
const allKeys = /* @__PURE__ */ new Set([...Object.keys(aObj), ...Object.keys(bObj)]);
|
|
45
|
+
for (const key of allKeys) {
|
|
46
|
+
if (!(key in aObj)) {
|
|
47
|
+
diffs.push({ path: `${path}.${key}`, type: "added", newValue: bObj[key] });
|
|
48
|
+
} else if (!(key in bObj)) {
|
|
49
|
+
diffs.push({ path: `${path}.${key}`, type: "removed", oldValue: aObj[key] });
|
|
50
|
+
} else {
|
|
51
|
+
diffs.push(...diff(aObj[key], bObj[key], `${path}.${key}`));
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return diffs;
|
|
55
|
+
}
|
|
56
|
+
var jsonModule = {
|
|
57
|
+
id: "json",
|
|
58
|
+
description: "JSON manipulation utilities",
|
|
59
|
+
functions: [
|
|
60
|
+
{
|
|
61
|
+
name: "jsonParse",
|
|
62
|
+
description: "Parse JSON with better error messages",
|
|
63
|
+
signature: "(text: string) => any",
|
|
64
|
+
fn: (text) => {
|
|
65
|
+
try {
|
|
66
|
+
return JSON.parse(text);
|
|
67
|
+
} catch (e) {
|
|
68
|
+
const err = e;
|
|
69
|
+
throw new Error(`JSON parse error: ${err.message}`);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
name: "jsonQuery",
|
|
75
|
+
description: "JSONPath query",
|
|
76
|
+
signature: "(data: any, path: string) => any",
|
|
77
|
+
fn: (data, path) => queryPath(data, path)
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
name: "jsonTransform",
|
|
81
|
+
description: "Map over arrays/objects",
|
|
82
|
+
signature: "(data: any, fn: (item: any) => any) => any",
|
|
83
|
+
fn: (data, fn) => {
|
|
84
|
+
const mapper = fn;
|
|
85
|
+
if (Array.isArray(data)) return data.map(mapper);
|
|
86
|
+
if (typeof data === "object" && data !== null) {
|
|
87
|
+
const result = {};
|
|
88
|
+
for (const [k, v] of Object.entries(data)) {
|
|
89
|
+
result[k] = mapper(v);
|
|
90
|
+
}
|
|
91
|
+
return result;
|
|
92
|
+
}
|
|
93
|
+
return mapper(data);
|
|
94
|
+
}
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
name: "jsonMerge",
|
|
98
|
+
description: "Deep merge objects",
|
|
99
|
+
signature: "(...objects: any[]) => any",
|
|
100
|
+
fn: (...objects) => deepMerge(...objects)
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
name: "jsonDiff",
|
|
104
|
+
description: "Structural diff between two objects",
|
|
105
|
+
signature: "(a: any, b: any) => Diff[]",
|
|
106
|
+
fn: (a, b) => diff(a, b)
|
|
107
|
+
}
|
|
108
|
+
]
|
|
109
|
+
};
|
|
110
|
+
var json_default = jsonModule;
|
|
111
|
+
export {
|
|
112
|
+
json_default as default
|
|
113
|
+
};
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
// src/catalog/path.ts
|
|
2
|
+
import nodePath from "path";
|
|
3
|
+
var pathModule = {
|
|
4
|
+
id: "path",
|
|
5
|
+
description: "Path manipulation utilities",
|
|
6
|
+
functions: [
|
|
7
|
+
{
|
|
8
|
+
name: "joinPath",
|
|
9
|
+
description: "Join path segments",
|
|
10
|
+
signature: "(...segments: string[]) => string",
|
|
11
|
+
fn: (...segments) => nodePath.join(...segments)
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
name: "resolvePath",
|
|
15
|
+
description: "Resolve to absolute path",
|
|
16
|
+
signature: "(...segments: string[]) => string",
|
|
17
|
+
fn: (...segments) => nodePath.resolve(...segments)
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
name: "relativePath",
|
|
21
|
+
description: "Relative path between two paths",
|
|
22
|
+
signature: "(from: string, to: string) => string",
|
|
23
|
+
fn: (from, to) => nodePath.relative(from, to)
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
name: "parsePath",
|
|
27
|
+
description: "Parse path components",
|
|
28
|
+
signature: "(p: string) => { dir: string, base: string, ext: string, name: string }",
|
|
29
|
+
fn: (p) => nodePath.parse(p)
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
name: "dirname",
|
|
33
|
+
description: "Directory name",
|
|
34
|
+
signature: "(p: string) => string",
|
|
35
|
+
fn: (p) => nodePath.dirname(p)
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
name: "basename",
|
|
39
|
+
description: "Base name",
|
|
40
|
+
signature: "(p: string, ext?: string) => string",
|
|
41
|
+
fn: (p, ext) => nodePath.basename(p, ext)
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
name: "extname",
|
|
45
|
+
description: "Extension",
|
|
46
|
+
signature: "(p: string) => string",
|
|
47
|
+
fn: (p) => nodePath.extname(p)
|
|
48
|
+
}
|
|
49
|
+
]
|
|
50
|
+
};
|
|
51
|
+
var path_default = pathModule;
|
|
52
|
+
export {
|
|
53
|
+
path_default as default
|
|
54
|
+
};
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
// src/catalog/shell.ts
|
|
2
|
+
import { execFile, spawn } from "child_process";
|
|
3
|
+
import { promisify } from "util";
|
|
4
|
+
var execFileAsync = promisify(execFile);
|
|
5
|
+
var shellCwd = process.cwd();
|
|
6
|
+
function setShellCwd(dir) {
|
|
7
|
+
shellCwd = dir;
|
|
8
|
+
}
|
|
9
|
+
var shellModule = {
|
|
10
|
+
id: "shell",
|
|
11
|
+
description: "Shell command execution",
|
|
12
|
+
functions: [
|
|
13
|
+
{
|
|
14
|
+
name: "exec",
|
|
15
|
+
description: "Run shell command",
|
|
16
|
+
signature: "(command: string, options?: { cwd?: string, timeout?: number }) => Promise<{ stdout: string, stderr: string, exitCode: number }>",
|
|
17
|
+
fn: async (command, options) => {
|
|
18
|
+
const opts = options;
|
|
19
|
+
const args = command.split(" ");
|
|
20
|
+
const cmd = args[0];
|
|
21
|
+
const cmdArgs = args.slice(1);
|
|
22
|
+
try {
|
|
23
|
+
const { stdout, stderr } = await execFileAsync(cmd, cmdArgs, {
|
|
24
|
+
cwd: opts?.cwd ?? shellCwd,
|
|
25
|
+
timeout: opts?.timeout ?? 3e4
|
|
26
|
+
});
|
|
27
|
+
return { stdout, stderr, exitCode: 0 };
|
|
28
|
+
} catch (err) {
|
|
29
|
+
return {
|
|
30
|
+
stdout: err.stdout ?? "",
|
|
31
|
+
stderr: err.stderr ?? err.message,
|
|
32
|
+
exitCode: err.code ?? 1
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
name: "execLive",
|
|
39
|
+
description: "Streaming command output",
|
|
40
|
+
signature: "(command: string, options?: { cwd?: string, timeout?: number }) => AsyncIterable<{ stream: 'stdout' | 'stderr', data: string }>",
|
|
41
|
+
fn: (command, options) => {
|
|
42
|
+
const opts = options;
|
|
43
|
+
const args = command.split(" ");
|
|
44
|
+
const cmd = args[0];
|
|
45
|
+
const cmdArgs = args.slice(1);
|
|
46
|
+
return {
|
|
47
|
+
async *[Symbol.asyncIterator]() {
|
|
48
|
+
const child = spawn(cmd, cmdArgs, {
|
|
49
|
+
cwd: opts?.cwd ?? shellCwd,
|
|
50
|
+
timeout: opts?.timeout ?? 3e4
|
|
51
|
+
});
|
|
52
|
+
const chunks = [];
|
|
53
|
+
let resolve = null;
|
|
54
|
+
let done = false;
|
|
55
|
+
child.stdout?.on("data", (data) => {
|
|
56
|
+
chunks.push({ stream: "stdout", data: data.toString() });
|
|
57
|
+
resolve?.();
|
|
58
|
+
});
|
|
59
|
+
child.stderr?.on("data", (data) => {
|
|
60
|
+
chunks.push({ stream: "stderr", data: data.toString() });
|
|
61
|
+
resolve?.();
|
|
62
|
+
});
|
|
63
|
+
child.on("close", () => {
|
|
64
|
+
done = true;
|
|
65
|
+
resolve?.();
|
|
66
|
+
});
|
|
67
|
+
child.on("error", () => {
|
|
68
|
+
done = true;
|
|
69
|
+
resolve?.();
|
|
70
|
+
});
|
|
71
|
+
while (!done || chunks.length > 0) {
|
|
72
|
+
if (chunks.length === 0 && !done) {
|
|
73
|
+
await new Promise((r) => {
|
|
74
|
+
resolve = r;
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
while (chunks.length > 0) yield chunks.shift();
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
name: "which",
|
|
85
|
+
description: "Find binary in PATH",
|
|
86
|
+
signature: "(binary: string) => Promise<string | null>",
|
|
87
|
+
fn: async (binary) => {
|
|
88
|
+
try {
|
|
89
|
+
const { stdout } = await execFileAsync("which", [binary]);
|
|
90
|
+
return stdout.trim() || null;
|
|
91
|
+
} catch {
|
|
92
|
+
return null;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
]
|
|
97
|
+
};
|
|
98
|
+
var shell_default = shellModule;
|
|
99
|
+
export {
|
|
100
|
+
shell_default as default,
|
|
101
|
+
setShellCwd
|
|
102
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@lmthing/repl",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"exports": {
|
|
6
|
+
".": {
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"import": "./dist/index.js"
|
|
9
|
+
}
|
|
10
|
+
},
|
|
11
|
+
"files": [
|
|
12
|
+
"dist"
|
|
13
|
+
],
|
|
14
|
+
"scripts": {
|
|
15
|
+
"build": "tsup",
|
|
16
|
+
"prepublishOnly": "pnpm build",
|
|
17
|
+
"test": "vitest run",
|
|
18
|
+
"test:watch": "vitest",
|
|
19
|
+
"typecheck": "tsc --noEmit"
|
|
20
|
+
},
|
|
21
|
+
"dependencies": {
|
|
22
|
+
"ai": "^6.0.86",
|
|
23
|
+
"react": "^19.0.0",
|
|
24
|
+
"typescript": "^5.7.0",
|
|
25
|
+
"zod": "^4.1.13"
|
|
26
|
+
},
|
|
27
|
+
"optionalDependencies": {
|
|
28
|
+
"better-sqlite3": "^11.0.0",
|
|
29
|
+
"sharp": "^0.33.0"
|
|
30
|
+
},
|
|
31
|
+
"devDependencies": {
|
|
32
|
+
"@swc/core": "^1.10.0",
|
|
33
|
+
"@types/node": "^22.0.0",
|
|
34
|
+
"@types/react": "^19.0.0",
|
|
35
|
+
"tsup": "^8.0.0",
|
|
36
|
+
"tsx": "^4.0.0",
|
|
37
|
+
"vitest": "catalog:"
|
|
38
|
+
}
|
|
39
|
+
}
|