Add --bitgate-* theme tokens and a build-injected VERSION.

Widget styles now prefer --bitgate-* custom properties, falling back to the
deprecated --gov-* names and then the existing defaults so current pages and
overrides keep working. Browser bundles and ESM entry points expose VERSION
(and window.bitgate.version) from package.json. Document allowlist on the
widget policy preset list. Sync the lockfile so npm ci sees @bitgate/standalone.

Co-authored-by: thePR0M3TH3AN <[email protected]>
This commit is contained in:
Cursor AgentandthePR0M3TH3AN committed 2026-10-08 19:14:44 +00:00
1 parent 90d4290989
commit 9e6f6c659e
24 files changed
+369 -22

No files matched your search

@@ -0,0 +1,27 @@
import { dirname, join } from "node:path";
import { fileURLToPath } from "node:url";
import { build } from "esbuild";
import { describe, expect, it } from "vitest";
import { bitgateVersionPlugin, readLibraryVersion } from "../../../scripts/esbuild-bitgate-version.mjs";
const HERE = dirname(fileURLToPath(import.meta.url));
const versionJs = join(HERE, "..", "..", "core", "src", "version.js");
describe("build-time version injection", () => {
it("replaces the version module with package.json's version", async () => {
const version = readLibraryVersion();
const result = await build({
entryPoints: [versionJs],
bundle: true,
write: false,
format: "esm",
platform: "neutral",
plugins: [bitgateVersionPlugin(version)],
});
const bundled = result.outputFiles[0].text;
expect(bundled).toContain(`VERSION = ${JSON.stringify(version)}`);
expect(bundled).not.toContain("Keep this string in lockstep");
});
});
+6
View File
@@ -135,6 +135,11 @@ describe("<bitgate-provider>", () => {
expect(provider.runtime.policies.policy.id).toBe("bitgate-commerce");
});
it("accepts the allowlist policy preset", async () => {
const provider = await mountProvider({ policy: "allowlist" });
expect(provider.runtime.policies.policy.id).toBe("bitgate-allowlist");
});
it("defaults to administrative-only governance", async () => {
const provider = await mountProvider({ policy: null });
expect(provider.runtime.policies.policy.id).toBe("bitgate-admin-only");
@@ -154,6 +159,7 @@ describe("<bitgate-provider>", () => {
const provider = await mountProvider({ policy: "invented" });
expect(provider.runtime).toBeNull();
expect(provider.getAttribute("data-error")).toMatch(/Unknown policy preset/);
expect(provider.getAttribute("data-error")).toMatch(/allowlist/);
});
it("reports a missing relays attribute", async () => {
+31
View File
@@ -0,0 +1,31 @@
import { describe, expect, it } from "vitest";
import { BASE_STYLES, THEME_DEFAULTS, themeVar } from "../src/base.js";
describe("theme tokens", () => {
it("resolves --bitgate-* first, then deprecated --gov-*, then the default", () => {
for (const name of Object.keys(THEME_DEFAULTS)) {
expect(themeVar(/** @type {keyof typeof THEME_DEFAULTS} */ (name))).toBe(
`var(--bitgate-${name}, var(--gov-${name}, ${THEME_DEFAULTS[name]}))`,
);
}
});
it("keeps --gov-* host defaults so existing overrides still apply", () => {
for (const [name, value] of Object.entries(THEME_DEFAULTS)) {
expect(BASE_STYLES).toContain(`--gov-${name}: ${value}`);
}
});
it("does not assign --bitgate-* on :host (that would shadow --gov-* overrides)", () => {
expect(BASE_STYLES).not.toMatch(/--bitgate-[a-z]+:/);
});
it("uses the fallback chain at every painted token", () => {
expect(BASE_STYLES).toContain(themeVar("fg"));
expect(BASE_STYLES).toContain(themeVar("muted"));
expect(BASE_STYLES).toContain(themeVar("border"));
expect(BASE_STYLES).toContain(themeVar("surface"));
expect(BASE_STYLES).toContain(themeVar("radius"));
});
});
+28
View File
@@ -0,0 +1,28 @@
// @vitest-environment happy-dom
import { readFileSync } from "node:fs";
import { dirname, join } from "node:path";
import { fileURLToPath } from "node:url";
import { describe, expect, it } from "vitest";
import { VERSION, exposeBitGateVersion } from "../src/index.js";
const HERE = dirname(fileURLToPath(import.meta.url));
const rootPkg = JSON.parse(readFileSync(join(HERE, "..", "..", "..", "package.json"), "utf8"));
describe("VERSION", () => {
it("matches package.json", () => {
expect(VERSION).toBe(rootPkg.version);
});
it("is published on window.bitgate when the widget is imported", () => {
expect(/** @type {any} */ (window).bitgate.version).toBe(VERSION);
});
it("writes version onto an existing window.bitgate object", () => {
const target = { bitgate: { extra: true } };
exposeBitGateVersion(target);
expect(target.bitgate.version).toBe(VERSION);
expect(target.bitgate.extra).toBe(true);
});
});