mirror of
https://github.com/purrgrammer/grimoire.git
synced 2026-04-11 07:56:50 +02:00
feat(nip-transformer): add support for hex NIPs like NIP-C7
- Extend pattern to match hex NIP identifiers (NIP-C7, NIP-C0, NIP-A0) - Normalize hex NIPs to uppercase (nip-c7 -> C7) - Add tests for hex NIP parsing and normalization
This commit is contained in:
@@ -174,4 +174,70 @@ describe("nipReferences transformer", () => {
|
||||
expect(nips[1].number).toBe("999");
|
||||
});
|
||||
});
|
||||
|
||||
describe("hex NIP support", () => {
|
||||
it("should parse hex NIP-C7", () => {
|
||||
const tree = createTree("Code snippets are defined in NIP-C7");
|
||||
const transformer = nipReferences();
|
||||
transformer(tree);
|
||||
|
||||
const nips = getNodesOfType<NipNode>(tree, "nip");
|
||||
expect(nips).toHaveLength(1);
|
||||
expect(nips[0].number).toBe("C7");
|
||||
expect(nips[0].raw).toBe("NIP-C7");
|
||||
});
|
||||
|
||||
it("should parse lowercase hex nip-c7", () => {
|
||||
const tree = createTree("See nip-c7 for code snippets");
|
||||
const transformer = nipReferences();
|
||||
transformer(tree);
|
||||
|
||||
const nips = getNodesOfType<NipNode>(tree, "nip");
|
||||
expect(nips).toHaveLength(1);
|
||||
expect(nips[0].number).toBe("C7"); // Normalized to uppercase
|
||||
expect(nips[0].raw).toBe("nip-c7");
|
||||
});
|
||||
|
||||
it("should parse NIP-C0", () => {
|
||||
const tree = createTree("NIP-C0 defines something");
|
||||
const transformer = nipReferences();
|
||||
transformer(tree);
|
||||
|
||||
const nips = getNodesOfType<NipNode>(tree, "nip");
|
||||
expect(nips).toHaveLength(1);
|
||||
expect(nips[0].number).toBe("C0");
|
||||
});
|
||||
|
||||
it("should parse NIP-A0", () => {
|
||||
const tree = createTree("Check NIP-A0");
|
||||
const transformer = nipReferences();
|
||||
transformer(tree);
|
||||
|
||||
const nips = getNodesOfType<NipNode>(tree, "nip");
|
||||
expect(nips).toHaveLength(1);
|
||||
expect(nips[0].number).toBe("A0");
|
||||
});
|
||||
|
||||
it("should handle mixed decimal and hex NIPs", () => {
|
||||
const tree = createTree("NIP-01, NIP-C7, and NIP-19 together");
|
||||
const transformer = nipReferences();
|
||||
transformer(tree);
|
||||
|
||||
const nips = getNodesOfType<NipNode>(tree, "nip");
|
||||
expect(nips).toHaveLength(3);
|
||||
expect(nips[0].number).toBe("01");
|
||||
expect(nips[1].number).toBe("C7");
|
||||
expect(nips[2].number).toBe("19");
|
||||
});
|
||||
|
||||
it("should normalize mixed case hex to uppercase", () => {
|
||||
const tree = createTree("nip-c7 NIP-C7 nip-C7 NIP-c7");
|
||||
const transformer = nipReferences();
|
||||
transformer(tree);
|
||||
|
||||
const nips = getNodesOfType<NipNode>(tree, "nip");
|
||||
expect(nips).toHaveLength(4);
|
||||
expect(nips.every((n) => n.number === "C7")).toBe(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -6,15 +6,36 @@ import type { Root, Content } from "applesauce-content/nast";
|
||||
*/
|
||||
export interface NipNode {
|
||||
type: "nip";
|
||||
/** The NIP number (e.g., "01", "19", "30") */
|
||||
/** The NIP number/identifier (e.g., "01", "19", "C7") */
|
||||
number: string;
|
||||
/** The raw matched text (e.g., "NIP-01", "nip-19") */
|
||||
/** The raw matched text (e.g., "NIP-01", "nip-19", "NIP-C7") */
|
||||
raw: string;
|
||||
}
|
||||
|
||||
// Match NIP-xx patterns (case insensitive, 1-3 digits)
|
||||
// Supports: NIP-01, NIP-1, nip-19, NIP-100, etc.
|
||||
const NIP_PATTERN = /\bNIP-(\d{1,3})\b/gi;
|
||||
// Match NIP-xx patterns (case insensitive)
|
||||
// Supports both decimal (NIP-01, NIP-19, NIP-100) and hex (NIP-C7, NIP-C0, NIP-A0)
|
||||
// Pattern: 1-3 hex characters (which includes pure decimal)
|
||||
const NIP_PATTERN = /\bNIP-([0-9A-Fa-f]{1,3})\b/gi;
|
||||
|
||||
/**
|
||||
* Check if a NIP identifier is purely decimal
|
||||
*/
|
||||
function isDecimalNip(nip: string): boolean {
|
||||
return /^\d+$/.test(nip);
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalize a NIP identifier:
|
||||
* - Decimal NIPs: pad to 2 digits (1 -> 01, 19 -> 19)
|
||||
* - Hex NIPs: uppercase (c7 -> C7)
|
||||
*/
|
||||
function normalizeNip(nip: string): string {
|
||||
if (isDecimalNip(nip)) {
|
||||
return nip.padStart(2, "0");
|
||||
}
|
||||
// Hex NIP - uppercase it
|
||||
return nip.toUpperCase();
|
||||
}
|
||||
|
||||
/**
|
||||
* Transformer that finds NIP-xx references and converts them to nip nodes.
|
||||
@@ -26,8 +47,7 @@ export function nipReferences() {
|
||||
[
|
||||
NIP_PATTERN,
|
||||
(full, number) => {
|
||||
// Normalize to 2 digits with leading zero for consistency
|
||||
const normalized = number.padStart(2, "0");
|
||||
const normalized = normalizeNip(number);
|
||||
// Cast to Content since we're extending with a custom node type
|
||||
return {
|
||||
type: "nip",
|
||||
|
||||
Reference in New Issue
Block a user