mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-12 21:53:00 -06:00
84c7d45f15
* refactor(qqbot): remove bundled extension source Mechanical deletion half of the #107295 squashed rebase; the catalog repoint and host integration land in the follow-up commit. Co-authored-by: sliverp <870080352@qq.com> * refactor(qqbot): install plugin from Tencent package Squashed rebase of #107295 onto current main. Repoints the official external channel catalog at @tencent-connect/openclaw-qqbot@2.0.1 and adapts onboarding, doctor migrations, secrets, build guards, and tests. Documents the known limitation that the external package does not support structured SecretRef clientSecret values; operators move those to QQBOT_CLIENT_SECRET or clientSecretFile before upgrading. Co-authored-by: sliverp <870080352@qq.com> * fix(doctor): reuse shared hasOwnKey record helper The rebased QQBot migration carried its own hasOwnKey export, colliding with the one main now ships in legacy-config-record-shared.ts. Co-authored-by: sliverp <870080352@qq.com> * fix(plugins): carry catalog integrity through the update bridge The externalized-bundled-plugin bridge dropped the official catalog's expectedIntegrity pin, so bundled-user updates installed the external npm package without integrity verification. The bridge now carries the pin for the catalog's exact npm spec and both bridge install calls pass it through; update-channel spec overrides intentionally skip the pin since it only covers the pinned version. Co-authored-by: sliverp <870080352@qq.com> * chore(plugin-sdk): refresh per-entrypoint API baselines The QQBot compat export and bundled-type removal shift 26 entrypoint closure hashes in the new split baseline layout. Co-authored-by: sliverp <870080352@qq.com> * refactor(qqbot): drop helper reintroduced during rebase Main's coercion consolidation added this file after the deletion commit's base; its only consumers were the removed qqbot sources. Co-authored-by: sliverp <870080352@qq.com> --------- Co-authored-by: Peter Steinberger <steipete@gmail.com>
69 lines
2.8 KiB
TypeScript
69 lines
2.8 KiB
TypeScript
// Ts Guard Utils tests cover ts guard utils script behavior.
|
|
import { existsSync, mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
|
|
import { tmpdir } from "node:os";
|
|
import path from "node:path";
|
|
import { pathToFileURL } from "node:url";
|
|
import { describe, expect, it } from "vitest";
|
|
import { resolveRepoRoot } from "../../scripts/lib/repo-root.mjs";
|
|
|
|
/**
|
|
* Regression tests for resolveRepoRoot().
|
|
*
|
|
* The original implementation went up exactly two levels from the caller's
|
|
* import.meta.url, which broke for scripts at scripts/*.mjs (one level below
|
|
* root) — it overshot to the repo's parent directory.
|
|
*/
|
|
describe("resolveRepoRoot", () => {
|
|
it("resolves correctly from a scripts/lib/*.mjs path (two levels below root)", () => {
|
|
const fakeUrl = pathToFileURL(path.resolve("scripts", "lib", "some-guard-utils.mjs")).href;
|
|
const root = resolveRepoRoot(fakeUrl);
|
|
|
|
expect(existsSync(path.join(root, ".git"))).toBe(true);
|
|
expect(existsSync(path.join(root, "package.json"))).toBe(true);
|
|
});
|
|
|
|
it("resolves correctly from a scripts/*.mjs path (one level below root)", () => {
|
|
const fakeUrl = pathToFileURL(path.resolve("scripts", "check-no-raw-channel-fetch.mts")).href;
|
|
const root = resolveRepoRoot(fakeUrl);
|
|
|
|
expect(existsSync(path.join(root, ".git"))).toBe(true);
|
|
expect(existsSync(path.join(root, "package.json"))).toBe(true);
|
|
});
|
|
|
|
it("resolves correctly from a deeply nested extension path", () => {
|
|
const fakeUrl = pathToFileURL(
|
|
path.resolve("extensions", "telegram", "src", "utils", "hypothetical.mjs"),
|
|
).href;
|
|
const root = resolveRepoRoot(fakeUrl);
|
|
|
|
expect(existsSync(path.join(root, ".git"))).toBe(true);
|
|
expect(existsSync(path.join(root, "package.json"))).toBe(true);
|
|
});
|
|
|
|
it("all caller depths resolve to the same root", () => {
|
|
const fromLib = resolveRepoRoot(pathToFileURL(path.resolve("scripts", "lib", "a.mjs")).href);
|
|
const fromScripts = resolveRepoRoot(pathToFileURL(path.resolve("scripts", "b.mjs")).href);
|
|
const fromExtension = resolveRepoRoot(
|
|
pathToFileURL(path.resolve("extensions", "telegram", "c.mjs")).href,
|
|
);
|
|
|
|
expect(fromLib).toBe(fromScripts);
|
|
expect(fromScripts).toBe(fromExtension);
|
|
});
|
|
|
|
it("resolves an unpacked workspace without git metadata", () => {
|
|
const root = mkdtempSync(path.join(tmpdir(), "openclaw-repo-root-"));
|
|
try {
|
|
mkdirSync(path.join(root, "scripts", "nested"), { recursive: true });
|
|
writeFileSync(path.join(root, "package.json"), '{"name":"openclaw"}\n');
|
|
writeFileSync(path.join(root, "pnpm-workspace.yaml"), "packages: []\n");
|
|
|
|
expect(
|
|
resolveRepoRoot(pathToFileURL(path.join(root, "scripts", "nested", "tool.mjs")).href),
|
|
).toBe(root);
|
|
} finally {
|
|
rmSync(root, { recursive: true, force: true });
|
|
}
|
|
});
|
|
});
|