Files
openclaw-openclaw/test/plugin-npm-runtime-build.test.ts
Sulaga 2b51c255f8 feat(tencent): add Tencent Hy3 provider (TokenHub and TokenPlan) (#99076)
Summary:
- Merged feat(tencent): add Tencent Hy3 provider (TokenHub and TokenPlan) after ClawSweeper review.

Automerge notes:
- Ran the ClawSweeper repair loop before final review.
- Included post-review commit in the final squash: fix(tencent): preserve TokenHub auth compatibility
- Included post-review commit in the final squash: refactor(tencent): unify TokenPlan env/flag naming with TokenHub
- Included post-review commit in the final squash: docs: refresh Tencent provider docs metadata
- Included post-review commit in the final squash: fix: allow TokenPlan provider config overlays
- Included post-review commit in the final squash: docs: dedupe Tencent provider glossary labels
- Included post-review commit in the final squash: fix(tencent): repair TokenHub model defaults

Validation:
- ClawSweeper review passed for head 30c9fc130f.
- Required merge gates passed before the squash merge.

Prepared head SHA: 30c9fc130f
Review: https://github.com/openclaw/openclaw/pull/99076#issuecomment-4888527271

Co-authored-by: leisang <leisang@tencent.com>
Co-authored-by: Mason Huang <masonxhuang@tencent.com>
Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com>
Approved-by: hxy91819
2026-07-06 04:29:48 +00:00

124 lines
5.0 KiB
TypeScript

// Plugin npm runtime build tests validate plugin runtime package builds.
import path from "node:path";
import { describe, expect, it } from "vitest";
import {
listPublishablePluginPackageDirs,
resolvePluginNpmRuntimeBuildPlan,
} from "../scripts/lib/plugin-npm-runtime-build.mjs";
const repoRoot = path.resolve(import.meta.dirname, "..");
type PluginNpmRuntimeBuildPlan = NonNullable<ReturnType<typeof resolvePluginNpmRuntimeBuildPlan>>;
function expectDistRelativePaths(paths: string[]) {
expect(paths.every((entry) => entry.startsWith("./dist/"))).toBe(true);
}
function expectPluginNpmRuntimeBuildPlan(
plan: ReturnType<typeof resolvePluginNpmRuntimeBuildPlan>,
): PluginNpmRuntimeBuildPlan {
if (!plan) {
throw new Error("expected plugin npm runtime build plan");
}
return plan;
}
describe("plugin npm runtime build planning", () => {
it("plans package-local runtime entries for every publishable plugin package", () => {
const packageDirs = listPublishablePluginPackageDirs({ repoRoot });
expect(packageDirs.length).toBeGreaterThan(0);
const plans = packageDirs.map((packageDir) =>
resolvePluginNpmRuntimeBuildPlan({
repoRoot,
packageDir,
}),
);
const resolvedPlans = plans.map(expectPluginNpmRuntimeBuildPlan);
expect(resolvedPlans.map((plan) => plan.pluginDir)).toEqual(
packageDirs.map((packageDir) => path.basename(packageDir)),
);
for (const plan of resolvedPlans) {
expect(plan.outDir).toBe(path.join(plan.packageDir, "dist"));
expectDistRelativePaths(plan.runtimeExtensions);
expectDistRelativePaths(plan.runtimeBuildOutputs);
expect(plan.packageFiles).toContain("dist/**");
expect(plan.packagePeerMetadata.peerDependencies.openclaw).toBe(
plan.packageJson.openclaw.compat.pluginApi,
);
expect(plan.packagePeerMetadata.peerDependenciesMeta.openclaw.optional).toBe(true);
}
});
it("includes top-level public runtime surfaces and root-build-excluded plugins", () => {
const qqbotPlan = resolvePluginNpmRuntimeBuildPlan({
repoRoot,
packageDir: path.join(repoRoot, "extensions", "qqbot"),
});
const qqbotRuntimePlan = expectPluginNpmRuntimeBuildPlan(qqbotPlan);
expect(qqbotRuntimePlan.entry).toEqual({
api: path.join(repoRoot, "extensions", "qqbot", "api.ts"),
"channel-entry-api": path.join(repoRoot, "extensions", "qqbot", "channel-entry-api.ts"),
"channel-plugin-api": path.join(repoRoot, "extensions", "qqbot", "channel-plugin-api.ts"),
"doctor-contract-api": path.join(repoRoot, "extensions", "qqbot", "doctor-contract-api.ts"),
index: path.join(repoRoot, "extensions", "qqbot", "index.ts"),
"runtime-api": path.join(repoRoot, "extensions", "qqbot", "runtime-api.ts"),
"secret-contract-api": path.join(repoRoot, "extensions", "qqbot", "secret-contract-api.ts"),
"setup-entry": path.join(repoRoot, "extensions", "qqbot", "setup-entry.ts"),
"setup-plugin-api": path.join(repoRoot, "extensions", "qqbot", "setup-plugin-api.ts"),
"tools-api": path.join(repoRoot, "extensions", "qqbot", "tools-api.ts"),
});
expect(qqbotRuntimePlan.runtimeExtensions).toEqual(["./dist/index.js"]);
expect(qqbotRuntimePlan.runtimeSetupEntry).toBe("./dist/setup-entry.js");
const diffsPlan = resolvePluginNpmRuntimeBuildPlan({
repoRoot,
packageDir: path.join(repoRoot, "extensions", "diffs"),
});
const diffsRuntimePlan = expectPluginNpmRuntimeBuildPlan(diffsPlan);
expect(diffsRuntimePlan.entry).toEqual({
api: path.join(repoRoot, "extensions", "diffs", "api.ts"),
index: path.join(repoRoot, "extensions", "diffs", "index.ts"),
"runtime-api": path.join(repoRoot, "extensions", "diffs", "runtime-api.ts"),
});
expect(diffsRuntimePlan.packageFiles).toEqual([
"dist/**",
"openclaw.plugin.json",
"npm-shrinkwrap.json",
"README.md",
"skills/**",
]);
});
it("builds doctor contract surfaces for publishable channel plugins", () => {
for (const pluginDir of ["msteams", "nostr"]) {
const plan = expectPluginNpmRuntimeBuildPlan(
resolvePluginNpmRuntimeBuildPlan({
repoRoot,
packageDir: path.join(repoRoot, "extensions", pluginDir),
}),
);
expect(plan.entry["doctor-contract-api"]).toBe(
path.join(repoRoot, "extensions", pluginDir, "doctor-contract-api.ts"),
);
expect(plan.runtimeBuildOutputs).toContain("./dist/doctor-contract-api.js");
expect(plan.packageFiles).toContain("dist/**");
}
});
it("builds Tencent setup metadata for installed-package migrations", () => {
const plan = expectPluginNpmRuntimeBuildPlan(
resolvePluginNpmRuntimeBuildPlan({
repoRoot,
packageDir: path.join(repoRoot, "extensions", "tencent"),
}),
);
expect(plan.entry["setup-api"]).toBe(
path.join(repoRoot, "extensions", "tencent", "setup-api.ts"),
);
expect(plan.runtimeSetupEntry).toBe("./dist/setup-api.js");
expect(plan.runtimeBuildOutputs).toContain("./dist/setup-api.js");
});
});