feat: richText

This commit is contained in:
Shibo Lyu 2025-02-16 22:44:37 +08:00
parent 36c2184784
commit a270d634f2
9 changed files with 97 additions and 1 deletions

View file

@ -15,7 +15,7 @@
"build:npm": "deno run -A ./scripts/build_npm.ts"
},
"publish": {
"include": ["LICENSE", "README.md", "crypto", "identity"],
"include": ["LICENSE", "README.md", "crypto", "identity", "richText"],
"exclude": ["**/*.test.ts"]
},
"test": {

33
richText/mod.ts Normal file
View file

@ -0,0 +1,33 @@
/**
* `richText` defines the structure of rich text used through out Blah.
*
* Note that this module only defines a single block of rich text. That is, we only deal with "inline" elements.
*
* @module
*/
import type z from "zod";
import {
type BlahRichTextSpan,
type BlahRichTextSpanAttributes,
blahRichTextSpanAttributesSchema as internalBlahRichTextSpanAttributesSchema,
blahRichTextSpanSchema as internalBlahRichTextSpanSchema,
} from "./span.ts";
const blahRichTextSpanAttributesSchema: z.ZodType<BlahRichTextSpanAttributes> =
internalBlahRichTextSpanAttributesSchema;
const blahRichTextSpanSchema: z.ZodType<BlahRichTextSpan> =
internalBlahRichTextSpanSchema;
export {
type BlahRichTextSpan,
type BlahRichTextSpanAttributes,
blahRichTextSpanAttributesSchema,
blahRichTextSpanSchema,
};
import {
type BlahRichText,
blahRichTextSchema as internalBlahRichTextSchema,
} from "./richText.ts";
const blahRichTextSchema: z.ZodType<BlahRichText> = internalBlahRichTextSchema;
export { type BlahRichText, blahRichTextSchema };

View file

@ -0,0 +1,8 @@
import { assertTypeMatchesZodSchema } from "../test/utils.ts";
import { type BlahRichText, blahRichTextSchema } from "./richText.ts";
Deno.test("type BlahRichText is accurate", () => {
assertTypeMatchesZodSchema<BlahRichText>(
blahRichTextSchema,
);
});

5
richText/richText.ts Normal file
View file

@ -0,0 +1,5 @@
import { z } from "zod";
import { type BlahRichTextSpan, blahRichTextSpanSchema } from "./span.ts";
export const blahRichTextSchema = z.array(blahRichTextSpanSchema);
export type BlahRichText = Array<BlahRichTextSpan>;

8
richText/span.test.ts Normal file
View file

@ -0,0 +1,8 @@
import { assertTypeMatchesZodSchema } from "../test/utils.ts";
import { type BlahRichTextSpan, blahRichTextSpanSchema } from "./span.ts";
Deno.test("type BlahRichTextSpan is accurate", () => {
assertTypeMatchesZodSchema<BlahRichTextSpan>(
blahRichTextSpanSchema,
);
});

27
richText/span.ts Normal file
View file

@ -0,0 +1,27 @@
import { z } from "zod";
export const blahRichTextSpanAttributesSchema = z.object({
b: z.boolean().default(false),
i: z.boolean().default(false),
u: z.boolean().default(false),
s: z.boolean().default(false),
m: z.boolean().default(false),
tag: z.boolean().default(false),
link: z.string().url().optional(),
});
export type BlahRichTextSpanAttributes = {
b?: boolean;
i?: boolean;
u?: boolean;
s?: boolean;
m?: boolean;
tag?: boolean;
link?: string | undefined;
};
export const blahRichTextSpanSchema = z.union([
z.string(),
z.tuple([z.string(), blahRichTextSpanAttributesSchema]),
]);
export type BlahRichTextSpan = string | [string, BlahRichTextSpanAttributes];

View file

@ -0,0 +1,8 @@
import { expect } from "@std/expect";
import type { BlahRichText } from "./mod.ts";
import { toPlainText } from "./toPlainText.ts";
Deno.test("toPlainText", () => {
const richText: BlahRichText = ["hello ", ["world", { b: true }]];
expect(toPlainText(richText)).toBe("hello world");
});

6
richText/toPlainText.ts Normal file
View file

@ -0,0 +1,6 @@
import type { BlahRichText } from "./richText.ts";
export function toPlainText(richText: BlahRichText): string {
return richText.map((span) => (typeof span === "string" ? span : span[0]))
.join("");
}

View file

@ -7,6 +7,7 @@ await build({
entryPoints: [
{ name: "./crypto", path: "crypto/mod.ts" },
{ name: "./identity", path: "identity/mod.ts" },
{ name: "./richText", path: "richText/mod.ts" },
],
outDir: "./npm",
importMap: "deno.json",