fix(tlon): Fix Zod v4 record() and @urbit/aura v3 API changes (#1631)
* fix(tlon): Fix Zod v4 record() and @urbit/aura v3 API changes
- Fix Zod v4.3.6 bug: single-arg z.record() fails with toJSONSchema()
- Use two-arg form: z.record(z.string(), schema)
- Fixes 'Cannot read properties of undefined (reading _zod)' error
- Fix @urbit/aura v3.0.0 API migration:
- unixToDa() → da.fromUnix()
- formatUd() → scot('ud', ...)
- Fixes '(0 , _aura.unixToDa) is not a function' error
These were blocking Tlon plugin loading and outbound messaging.
* fix: add tlon schema/aura tests (#1631) (thanks @arthyn)
---------
Co-authored-by: Peter Steinberger <steipete@gmail.com>
This commit is contained in:
@@ -14,6 +14,7 @@ Docs: https://docs.clawd.bot
|
||||
- Web UI: hide internal `message_id` hints in chat bubbles.
|
||||
- Heartbeat: normalize target identifiers for consistent routing.
|
||||
- Gateway: reduce log noise for late invokes + remote node probes; debounce skills refresh. (#1607) Thanks @petter-b.
|
||||
- Tlon: fix Zod v4 record keys + aura v3 DM ids. (#1631) Thanks @arthyn.
|
||||
|
||||
## 2026.1.23-1
|
||||
|
||||
|
||||
32
extensions/tlon/src/config-schema.test.ts
Normal file
32
extensions/tlon/src/config-schema.test.ts
Normal file
@@ -0,0 +1,32 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
import { TlonAuthorizationSchema, TlonConfigSchema } from "./config-schema.js";
|
||||
|
||||
describe("Tlon config schema", () => {
|
||||
it("accepts channelRules with string keys", () => {
|
||||
const parsed = TlonAuthorizationSchema.parse({
|
||||
channelRules: {
|
||||
"chat/~zod/test": {
|
||||
mode: "open",
|
||||
allowedShips: ["~zod"],
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
expect(parsed.channelRules?.["chat/~zod/test"]?.mode).toBe("open");
|
||||
});
|
||||
|
||||
it("accepts accounts with string keys", () => {
|
||||
const parsed = TlonConfigSchema.parse({
|
||||
accounts: {
|
||||
primary: {
|
||||
ship: "~zod",
|
||||
url: "https://example.com",
|
||||
code: "code-123",
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
expect(parsed.accounts?.primary?.ship).toBe("~zod");
|
||||
});
|
||||
});
|
||||
@@ -10,7 +10,7 @@ export const TlonChannelRuleSchema = z.object({
|
||||
});
|
||||
|
||||
export const TlonAuthorizationSchema = z.object({
|
||||
channelRules: z.record(TlonChannelRuleSchema).optional(),
|
||||
channelRules: z.record(z.string(), TlonChannelRuleSchema).optional(),
|
||||
});
|
||||
|
||||
export const TlonAccountSchema = z.object({
|
||||
@@ -37,7 +37,7 @@ export const TlonConfigSchema = z.object({
|
||||
showModelSignature: z.boolean().optional(),
|
||||
authorization: TlonAuthorizationSchema.optional(),
|
||||
defaultAuthorizedShips: z.array(ShipSchema).optional(),
|
||||
accounts: z.record(TlonAccountSchema).optional(),
|
||||
accounts: z.record(z.string(), TlonAccountSchema).optional(),
|
||||
});
|
||||
|
||||
export const tlonChannelConfigSchema = buildChannelConfigSchema(TlonConfigSchema);
|
||||
|
||||
38
extensions/tlon/src/urbit/send.test.ts
Normal file
38
extensions/tlon/src/urbit/send.test.ts
Normal file
@@ -0,0 +1,38 @@
|
||||
import { afterEach, describe, expect, it, vi } from "vitest";
|
||||
|
||||
vi.mock("@urbit/aura", () => ({
|
||||
scot: vi.fn(() => "mocked-ud"),
|
||||
da: {
|
||||
fromUnix: vi.fn(() => 123n),
|
||||
},
|
||||
}));
|
||||
|
||||
describe("sendDm", () => {
|
||||
afterEach(() => {
|
||||
vi.restoreAllMocks();
|
||||
});
|
||||
|
||||
it("uses aura v3 helpers for the DM id", async () => {
|
||||
const { sendDm } = await import("./send.js");
|
||||
const aura = await import("@urbit/aura");
|
||||
const scot = vi.mocked(aura.scot);
|
||||
const fromUnix = vi.mocked(aura.da.fromUnix);
|
||||
|
||||
const sentAt = 1_700_000_000_000;
|
||||
vi.spyOn(Date, "now").mockReturnValue(sentAt);
|
||||
|
||||
const poke = vi.fn(async () => ({}));
|
||||
|
||||
const result = await sendDm({
|
||||
api: { poke },
|
||||
fromShip: "~zod",
|
||||
toShip: "~nec",
|
||||
text: "hi",
|
||||
});
|
||||
|
||||
expect(fromUnix).toHaveBeenCalledWith(sentAt);
|
||||
expect(scot).toHaveBeenCalledWith("ud", 123n);
|
||||
expect(poke).toHaveBeenCalledTimes(1);
|
||||
expect(result.messageId).toBe("~zod/mocked-ud");
|
||||
});
|
||||
});
|
||||
@@ -1,4 +1,4 @@
|
||||
import { unixToDa, formatUd } from "@urbit/aura";
|
||||
import { scot, da } from "@urbit/aura";
|
||||
|
||||
export type TlonPokeApi = {
|
||||
poke: (params: { app: string; mark: string; json: unknown }) => Promise<unknown>;
|
||||
@@ -14,7 +14,7 @@ type SendTextParams = {
|
||||
export async function sendDm({ api, fromShip, toShip, text }: SendTextParams) {
|
||||
const story = [{ inline: [text] }];
|
||||
const sentAt = Date.now();
|
||||
const idUd = formatUd(unixToDa(sentAt));
|
||||
const idUd = scot('ud', da.fromUnix(sentAt));
|
||||
const id = `${fromShip}/${idUd}`;
|
||||
|
||||
const delta = {
|
||||
|
||||
Reference in New Issue
Block a user