* 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>
115 lines
2.4 KiB
TypeScript
115 lines
2.4 KiB
TypeScript
import { scot, da } from "@urbit/aura";
|
|
|
|
export type TlonPokeApi = {
|
|
poke: (params: { app: string; mark: string; json: unknown }) => Promise<unknown>;
|
|
};
|
|
|
|
type SendTextParams = {
|
|
api: TlonPokeApi;
|
|
fromShip: string;
|
|
toShip: string;
|
|
text: string;
|
|
};
|
|
|
|
export async function sendDm({ api, fromShip, toShip, text }: SendTextParams) {
|
|
const story = [{ inline: [text] }];
|
|
const sentAt = Date.now();
|
|
const idUd = scot('ud', da.fromUnix(sentAt));
|
|
const id = `${fromShip}/${idUd}`;
|
|
|
|
const delta = {
|
|
add: {
|
|
memo: {
|
|
content: story,
|
|
author: fromShip,
|
|
sent: sentAt,
|
|
},
|
|
kind: null,
|
|
time: null,
|
|
},
|
|
};
|
|
|
|
const action = {
|
|
ship: toShip,
|
|
diff: { id, delta },
|
|
};
|
|
|
|
await api.poke({
|
|
app: "chat",
|
|
mark: "chat-dm-action",
|
|
json: action,
|
|
});
|
|
|
|
return { channel: "tlon", messageId: id };
|
|
}
|
|
|
|
type SendGroupParams = {
|
|
api: TlonPokeApi;
|
|
fromShip: string;
|
|
hostShip: string;
|
|
channelName: string;
|
|
text: string;
|
|
replyToId?: string | null;
|
|
};
|
|
|
|
export async function sendGroupMessage({
|
|
api,
|
|
fromShip,
|
|
hostShip,
|
|
channelName,
|
|
text,
|
|
replyToId,
|
|
}: SendGroupParams) {
|
|
const story = [{ inline: [text] }];
|
|
const sentAt = Date.now();
|
|
|
|
const action = {
|
|
channel: {
|
|
nest: `chat/${hostShip}/${channelName}`,
|
|
action: replyToId
|
|
? {
|
|
reply: {
|
|
id: replyToId,
|
|
delta: {
|
|
add: {
|
|
memo: {
|
|
content: story,
|
|
author: fromShip,
|
|
sent: sentAt,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
: {
|
|
post: {
|
|
add: {
|
|
content: story,
|
|
author: fromShip,
|
|
sent: sentAt,
|
|
kind: "/chat",
|
|
blob: null,
|
|
meta: null,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
};
|
|
|
|
await api.poke({
|
|
app: "channels",
|
|
mark: "channel-action-1",
|
|
json: action,
|
|
});
|
|
|
|
return { channel: "tlon", messageId: `${fromShip}/${sentAt}` };
|
|
}
|
|
|
|
export function buildMediaText(text: string | undefined, mediaUrl: string | undefined): string {
|
|
const cleanText = text?.trim() ?? "";
|
|
const cleanUrl = mediaUrl?.trim() ?? "";
|
|
if (cleanText && cleanUrl) return `${cleanText}\n${cleanUrl}`;
|
|
if (cleanUrl) return cleanUrl;
|
|
return cleanText;
|
|
}
|