feat: OpsxDB 桌面数据库客户端首版入库
含工作台/连库多引擎字段与 SSH·SSL、结果编辑、Redis 键浏览、 Tauri 桌面与 docs/落地页;排除本地构建产物与 sidecar 二进制。
This commit is contained in:
commit
f8740d27f7
240 files changed
+21625
No files matched your search
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"name": "@opsxdb/core",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"main": "./src/index.ts",
|
||||
"types": "./src/index.ts",
|
||||
"exports": {
|
||||
".": "./src/index.ts"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "vitest run",
|
||||
"test:watch": "vitest"
|
||||
},
|
||||
"devDependencies": {
|
||||
"typescript": "^5.8.2",
|
||||
"vitest": "^3.0.9"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
export type {
|
||||
HttpMethod,
|
||||
HttpSpec,
|
||||
WsSpec,
|
||||
HttpResult,
|
||||
WsSession,
|
||||
Transport,
|
||||
} from "./types";
|
||||
|
||||
export { replaceVariables, replaceVariablesInSpec } from "./replaceVariables";
|
||||
@@ -0,0 +1,29 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { replaceVariables, replaceVariablesInSpec } from "./replaceVariables";
|
||||
|
||||
describe("replaceVariables", () => {
|
||||
it("replaces Postman-style {{var}}", () => {
|
||||
expect(replaceVariables("{{baseUrl}}/api", { baseUrl: "https://x.test" })).toBe(
|
||||
"https://x.test/api",
|
||||
);
|
||||
});
|
||||
|
||||
it("leaves unknown vars intact", () => {
|
||||
expect(replaceVariables("hello {{missing}}", {})).toBe("hello {{missing}}");
|
||||
});
|
||||
|
||||
it("supports multiple and spaced keys", () => {
|
||||
expect(
|
||||
replaceVariables("{{ host }}/{{path}}", { host: "h", path: "p" }),
|
||||
).toBe("h/p");
|
||||
});
|
||||
|
||||
it("replaceVariablesInSpec walks nested strings", () => {
|
||||
const out = replaceVariablesInSpec(
|
||||
{ url: "{{baseUrl}}/v1", headers: { Authorization: "Bearer {{token}}" } },
|
||||
{ baseUrl: "http://a", token: "t" },
|
||||
);
|
||||
expect(out.url).toBe("http://a/v1");
|
||||
expect(out.headers.Authorization).toBe("Bearer t");
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,35 @@
|
||||
/**
|
||||
* Postman-style {{var}} replacement.
|
||||
* Unknown variables are left as-is.
|
||||
*/
|
||||
export function replaceVariables(
|
||||
input: string,
|
||||
env: Record<string, string>,
|
||||
): string {
|
||||
if (!input) return input;
|
||||
return input.replace(/\{\{\s*([a-zA-Z0-9_.-]+)\s*\}\}/g, (match, key: string) => {
|
||||
if (Object.prototype.hasOwnProperty.call(env, key)) {
|
||||
return env[key] ?? "";
|
||||
}
|
||||
return match;
|
||||
});
|
||||
}
|
||||
|
||||
export function replaceVariablesInSpec<T extends Record<string, unknown>>(
|
||||
spec: T,
|
||||
env: Record<string, string>,
|
||||
): T {
|
||||
const walk = (v: unknown): unknown => {
|
||||
if (typeof v === "string") return replaceVariables(v, env);
|
||||
if (Array.isArray(v)) return v.map(walk);
|
||||
if (v && typeof v === "object") {
|
||||
const out: Record<string, unknown> = {};
|
||||
for (const [k, val] of Object.entries(v as Record<string, unknown>)) {
|
||||
out[k] = walk(val);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
return v;
|
||||
};
|
||||
return walk(spec) as T;
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
export type HttpMethod = "GET" | "POST" | "PUT" | "PATCH" | "DELETE";
|
||||
|
||||
export type HttpSpec = {
|
||||
method: HttpMethod;
|
||||
url: string;
|
||||
headers: Record<string, string>;
|
||||
query?: Record<string, string>;
|
||||
body?: {
|
||||
mode: "none" | "json" | "raw" | "form" | "urlencoded";
|
||||
raw?: string;
|
||||
};
|
||||
timeoutMs?: number;
|
||||
};
|
||||
|
||||
export type WsSpec = {
|
||||
url: string;
|
||||
protocols?: string[];
|
||||
headers?: Record<string, string>;
|
||||
};
|
||||
|
||||
export type HttpResult = {
|
||||
status: number;
|
||||
headers: Record<string, string>;
|
||||
body: string;
|
||||
timeMs: number;
|
||||
size: number;
|
||||
};
|
||||
|
||||
export interface WsSession {
|
||||
onMessage(cb: (data: string) => void): void;
|
||||
onStatus(cb: (s: string) => void): void;
|
||||
send(data: string): void;
|
||||
close(): void;
|
||||
}
|
||||
|
||||
export interface Transport {
|
||||
http(spec: HttpSpec): Promise<HttpResult>;
|
||||
ws(spec: WsSpec): WsSession;
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"extends": "../../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "dist",
|
||||
"rootDir": "src"
|
||||
},
|
||||
"include": [
|
||||
"src"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
import { defineConfig } from "vitest/config";
|
||||
|
||||
export default defineConfig({
|
||||
test: {
|
||||
environment: "node",
|
||||
},
|
||||
});
|
||||
Reference in new issue
Block a user