mirror of
https://github.com/purrgrammer/grimoire.git
synced 2026-04-10 15:36:53 +02:00
feat: support raw coordinate format (kind:pubkey:d) in -e flag
The -e flag now accepts raw a-tag coordinates like `30023:pubkey:article` in addition to naddr bech32 encoding. Both route to #a tag filtering. Examples: - req -e 30023:abc123...:my-article # Raw coordinate - req -e naddr1... # Bech32 encoded (same effect)
This commit is contained in:
@@ -363,6 +363,93 @@ describe("parseReqCommand", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("raw coordinate support (kind:pubkey:d)", () => {
|
||||
it("should parse raw coordinate and populate filter['#a']", () => {
|
||||
const pubkey = "a".repeat(64);
|
||||
const coordinate = `30023:${pubkey}:my-article`;
|
||||
const result = parseReqCommand(["-e", coordinate]);
|
||||
|
||||
expect(result.filter["#a"]).toBeDefined();
|
||||
expect(result.filter["#a"]).toHaveLength(1);
|
||||
expect(result.filter["#a"]).toEqual([coordinate]);
|
||||
expect(result.filter["#e"]).toBeUndefined();
|
||||
});
|
||||
|
||||
it("should normalize pubkey to lowercase", () => {
|
||||
const pubkey = "A".repeat(64);
|
||||
const coordinate = `30023:${pubkey}:my-article`;
|
||||
const result = parseReqCommand(["-e", coordinate]);
|
||||
|
||||
expect(result.filter["#a"]).toEqual([
|
||||
`30023:${"a".repeat(64)}:my-article`,
|
||||
]);
|
||||
});
|
||||
|
||||
it("should handle empty d-tag identifier", () => {
|
||||
const pubkey = "a".repeat(64);
|
||||
const coordinate = `30023:${pubkey}:`;
|
||||
const result = parseReqCommand(["-e", coordinate]);
|
||||
|
||||
expect(result.filter["#a"]).toEqual([coordinate]);
|
||||
});
|
||||
|
||||
it("should handle d-tag with special characters", () => {
|
||||
const pubkey = "a".repeat(64);
|
||||
const coordinate = `30023:${pubkey}:my-article/with:special-chars`;
|
||||
const result = parseReqCommand(["-e", coordinate]);
|
||||
|
||||
expect(result.filter["#a"]).toEqual([coordinate]);
|
||||
});
|
||||
|
||||
it("should handle different kind numbers", () => {
|
||||
const pubkey = "a".repeat(64);
|
||||
const result = parseReqCommand([
|
||||
"-e",
|
||||
`0:${pubkey}:,30000:${pubkey}:list,30023:${pubkey}:article`,
|
||||
]);
|
||||
|
||||
expect(result.filter["#a"]).toHaveLength(3);
|
||||
expect(result.filter["#a"]).toContain(`0:${pubkey}:`);
|
||||
expect(result.filter["#a"]).toContain(`30000:${pubkey}:list`);
|
||||
expect(result.filter["#a"]).toContain(`30023:${pubkey}:article`);
|
||||
});
|
||||
|
||||
it("should combine with naddr coordinates", () => {
|
||||
const pubkey = "a".repeat(64);
|
||||
const rawCoord = `30023:${pubkey}:raw-article`;
|
||||
const naddr = nip19.naddrEncode({
|
||||
kind: 30023,
|
||||
pubkey: pubkey,
|
||||
identifier: "encoded-article",
|
||||
});
|
||||
|
||||
const result = parseReqCommand(["-e", `${rawCoord},${naddr}`]);
|
||||
|
||||
expect(result.filter["#a"]).toHaveLength(2);
|
||||
expect(result.filter["#a"]).toContain(rawCoord);
|
||||
expect(result.filter["#a"]).toContain(
|
||||
`30023:${pubkey}:encoded-article`,
|
||||
);
|
||||
});
|
||||
|
||||
it("should ignore invalid coordinate formats", () => {
|
||||
// Missing parts
|
||||
const result1 = parseReqCommand(["-e", "30023:abc"]);
|
||||
expect(result1.filter["#a"]).toBeUndefined();
|
||||
|
||||
// Invalid pubkey (not 64 hex chars)
|
||||
const result2 = parseReqCommand(["-e", "30023:abc123:article"]);
|
||||
expect(result2.filter["#a"]).toBeUndefined();
|
||||
|
||||
// Invalid kind (not a number)
|
||||
const result3 = parseReqCommand([
|
||||
"-e",
|
||||
`abc:${"a".repeat(64)}:article`,
|
||||
]);
|
||||
expect(result3.filter["#a"]).toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
||||
describe("mixed format support", () => {
|
||||
it("should handle comma-separated mix of all formats (all to tags)", () => {
|
||||
const hex = "a".repeat(64);
|
||||
|
||||
@@ -679,6 +679,20 @@ function parseEventIdentifier(value: string): ParsedEventIdentifier | null {
|
||||
};
|
||||
}
|
||||
|
||||
// Raw coordinate: kind:pubkey:identifier → #a tag
|
||||
// Format: <kind>:<pubkey>:<d-tag> (e.g., 30023:abc123...:article-name)
|
||||
const coordinateMatch = value.match(/^(\d+):([a-fA-F0-9]{64}):(.*)$/);
|
||||
if (coordinateMatch) {
|
||||
const [, kindStr, pubkey, identifier] = coordinateMatch;
|
||||
const kind = parseInt(kindStr, 10);
|
||||
if (!isNaN(kind)) {
|
||||
return {
|
||||
type: "tag-address",
|
||||
value: `${kind}:${pubkey.toLowerCase()}:${identifier}`,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -181,9 +181,9 @@ export const manPages: Record<string, ManPageEntry> = {
|
||||
"Direct event lookup by ID (filter.ids). Fetch specific events by their ID. Supports note1, nevent1 (with relay hints), or raw hex. Comma-separated values supported: -i note1...,nevent1...,abc123...",
|
||||
},
|
||||
{
|
||||
flag: "-e <note|nevent|naddr|hex>",
|
||||
flag: "-e <note|nevent|naddr|coordinate|hex>",
|
||||
description:
|
||||
"Tag-based filtering (#e/#a tags). Find events that reference the specified events or addresses. Supports note1, nevent1, naddr1, or raw hex. Comma-separated values supported: -e note1...,naddr1...",
|
||||
"Tag-based filtering (#e/#a tags). Find events that reference the specified events or addresses. Supports note1, nevent1, naddr1, raw coordinates (kind:pubkey:d-tag), or hex. Comma-separated values supported: -e note1...,30023:pubkey:article",
|
||||
},
|
||||
{
|
||||
flag: "-p <npub|hex|nip05|$me|$contacts>",
|
||||
@@ -264,6 +264,7 @@ export const manPages: Record<string, ManPageEntry> = {
|
||||
"req -i note1abc123... Direct lookup: fetch event by ID",
|
||||
"req -i nevent1... Direct lookup: fetch event by nevent (uses relay hints)",
|
||||
"req -e note1abc123... -k 1 Tag filtering: find notes that reply to or reference event",
|
||||
"req -e 30023:pubkey...:article-name -k 1,7 Tag filtering: find events referencing addressable event",
|
||||
"req -t nostr,grimoire,bitcoin -l 50 Get 50 events tagged #nostr, #grimoire, or #bitcoin",
|
||||
"req --tag a 30023:7fa56f5d6962ab1e3cd424e758c3002b8665f7b0d8dcee9fe9e288d7751ac194:grimoire Get events referencing addressable event (#a tag)",
|
||||
"req -T r grimoire.rocks Get events referencing URL (#r tag)",
|
||||
|
||||
Reference in New Issue
Block a user