diff --git a/.gitignore b/.gitignore index 8f0c221..3d5ef0f 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ out/ package-lock.json bun.lock *.tgz +package \ No newline at end of file diff --git a/README.md b/README.md index b2faf2a..20a5800 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ It is built directly on grammY's own [`grammy/types`](https://grammy.dev), so bu ## Installation ```sh -npm i grammy-rich-messages +npm i @grammyjs/format ``` `grammy` is a peer dependency; install it alongside this library when sending messages through a bot. @@ -24,7 +24,7 @@ npm i grammy-rich-messages On Deno, import from `denopkg.com`: ```ts -import { richMessage } from "https://denopkg.com/roziscoding/grammy-rich-messages/src/core.ts"; +import { richMessage } from "https://denopkg.com/roziscoding/@grammyjs/format/src/core.ts"; ``` If you prefer package-style specifiers, add optional aliases for the surfaces you use in `deno.jsonc`: @@ -32,15 +32,15 @@ If you prefer package-style specifiers, add optional aliases for the surfaces yo ```jsonc { "imports": { - "grammy-rich-messages/core": "https://denopkg.com/roziscoding/grammy-rich-messages/src/core.ts", - "grammy-rich-messages/components": "https://denopkg.com/roziscoding/grammy-rich-messages/src/components.ts", - "grammy-rich-messages/chaining": "https://denopkg.com/roziscoding/grammy-rich-messages/src/chaining.ts" - } + "@grammyjs/format/core": "https://denopkg.com/roziscoding/@grammyjs/format/src/core.ts", + "@grammyjs/format/components": "https://denopkg.com/roziscoding/@grammyjs/format/src/components.ts", + "@grammyjs/format/chaining": "https://denopkg.com/roziscoding/@grammyjs/format/src/chaining.ts", + }, } ``` ```ts -import { richMessage } from "grammy-rich-messages/core"; +import { richMessage } from "@grammyjs/format/core"; ``` The examples below use these package-style specifiers; on Deno, either add the matching aliases or import the `src/` entrypoints directly from `denopkg.com`. @@ -51,7 +51,7 @@ This library only builds the message object. grammY already exposes the Bot API' ```tsx import { Bot } from "grammy"; -import { Bold, Paragraph, richMessage } from "grammy-rich-messages/components"; +import { Bold, Paragraph, richMessage } from "@grammyjs/format/components"; const bot = new Bot(process.env.TELEGRAM_TOKEN!); @@ -62,7 +62,8 @@ bot.command("start", (ctx) => Hello, {ctx.from?.first_name ?? "there"}! , ), - )); + ), +); bot.start(); ``` @@ -90,7 +91,7 @@ import { table, tableCell, tableRow, -} from "grammy-rich-messages/core"; +} from "@grammyjs/format/core"; const message = richMessage( heading({ size: 1 }, "Build report"), @@ -122,8 +123,8 @@ The same checks run at runtime for plain JavaScript and for values coming from ` ### Chaining ```ts -import { RichMessage } from "grammy-rich-messages/chaining"; -import { bold } from "grammy-rich-messages/core"; +import { RichMessage } from "@grammyjs/format/chaining"; +import { bold } from "@grammyjs/format/core"; const results = [ { model: "Aster-1", score: 98.4 }, @@ -133,19 +134,18 @@ const results = [ const message = new RichMessage({ skipEntityDetection: true }) .heading("Build report", { size: 1 }) .paragraph("Status: ", bold("green")) - .table( - { bordered: true, caption: "Benchmark" }, - (table) => - table - .row((row) => - row - .cell("Model", { header: true }) - .cell("Score", { header: true, align: "right" }) - ) - .rows(results, (row, result) => - row - .cell(result.model) - .cell(bold(result.score), { align: "right" })), + .table({ bordered: true, caption: "Benchmark" }, (table) => + table + .row((row) => + row + .cell("Model", { header: true }) + .cell("Score", { header: true, align: "right" }), + ) + .rows(results, (row, result) => + row + .cell(result.model) + .cell(bold(result.score), { align: "right" }), + ), ); ``` @@ -159,7 +159,7 @@ Point TypeScript at the library's JSX runtime — no React required. { "compilerOptions": { "jsx": "react-jsx", - "jsxImportSource": "grammy-rich-messages/jsx" + "jsxImportSource": "@grammyjs/format/jsx" } } ``` @@ -169,12 +169,12 @@ For Deno, add the JSX runtime import alias so the compiler can resolve `jsxImpor ```jsonc { "imports": { - "grammy-rich-messages/jsx/jsx-runtime": "https://denopkg.com/roziscoding/grammy-rich-messages/src/components/jsx-runtime.ts" - } + "@grammyjs/format/jsx/jsx-runtime": "https://denopkg.com/roziscoding/@grammyjs/format/src/components/jsx-runtime.ts", + }, } ``` -`jsxImportSource` only tells the compiler where the JSX runtime lives; the components themselves come from `grammy-rich-messages/components`, or `https://denopkg.com/roziscoding/grammy-rich-messages/src/components.ts` on Deno if you did not add the optional [`components` alias](#deno): +`jsxImportSource` only tells the compiler where the JSX runtime lives; the components themselves come from `@grammyjs/format/components`, or `https://denopkg.com/roziscoding/@grammyjs/format/src/components.ts` on Deno if you did not add the optional [`components` alias](#deno): ```tsx import { @@ -185,7 +185,7 @@ import { Table, TableCell, TableRow, -} from "grammy-rich-messages/components"; +} from "@grammyjs/format/components"; const message = richMessage( { skipEntityDetection: true }, @@ -213,8 +213,8 @@ const message = richMessage( Functional values can go straight into TSX, and vice versa: ```tsx -import { bold, table, tableCell, tableRow } from "grammy-rich-messages/core"; -import { Paragraph, richMessage } from "grammy-rich-messages/components"; +import { bold, table, tableCell, tableRow } from "@grammyjs/format/core"; +import { Paragraph, richMessage } from "@grammyjs/format/components"; richMessage( Generated with TSX., @@ -228,12 +228,12 @@ richMessage( TypeScript widens JSX expressions to `JSX.Element`, so a JSX value entering a strict functional boundary needs a runtime narrowing guard: ```tsx -import { table } from "grammy-rich-messages/core"; +import { table } from "@grammyjs/format/core"; import { expectTableRow, TableCell, TableRow, -} from "grammy-rich-messages/components"; +} from "@grammyjs/format/components"; const row = ( @@ -248,11 +248,11 @@ The guards — `expectRichText`, `expectBlock`, `expectListItem`, `expectTableRo ## Entrypoints -| Entrypoint | Exports | -| --------------------------------- | ------------------------------------------------------------------- | -| `grammy-rich-messages/core` | Functional builders, the `richMessage` root, and the Telegram types | -| `grammy-rich-messages/components` | TSX components, the `richMessage` root, and narrowing guards | -| `grammy-rich-messages/chaining` | `RichMessage`, `TableBuilder`, and `TableRowBuilder` | +| Entrypoint | Exports | +| ----------------------------- | ------------------------------------------------------------------- | +| `@grammyjs/format/core` | Functional builders, the `richMessage` root, and the Telegram types | +| `@grammyjs/format/components` | TSX components, the `richMessage` root, and narrowing guards | +| `@grammyjs/format/chaining` | `RichMessage`, `TableBuilder`, and `TableRowBuilder` | On Deno, these same specifiers work if you add the optional aliases shown in [Deno setup](#deno). Otherwise, import the matching source modules directly from `denopkg.com`: `src/core.ts`, `src/components.ts`, and `src/chaining.ts`. diff --git a/deno.jsonc b/deno.jsonc index fef0a1b..1ad439d 100644 --- a/deno.jsonc +++ b/deno.jsonc @@ -1,34 +1,40 @@ { + "name": "@grammyjs/format", + "version": "0.0.1-beta.1", + "exports": { + "./chaining": "./src/chaining.ts", + "./components": "./src/components.ts", + "./core": "./src/core.ts", + "./jsx/jsx-runtime": "./src/components/jsx-runtime.ts", + "./jsx/jsx-dev-runtime": "./src/components/jsx-runtime.ts" + }, "lock": false, "compilerOptions": { "jsx": "react-jsx", - "jsxImportSource": "grammy-rich-messages/jsx" + "jsxImportSource": "@grammyjs/format/jsx" }, "imports": { - "grammy-rich-messages/jsx/jsx-runtime": "./src/components/jsx-runtime.ts", - "grammy-rich-messages/jsx/jsx-dev-runtime": "./src/components/jsx-runtime.ts", + "@grammyjs/format/jsx/jsx-runtime": "./src/components/jsx-runtime.ts", + "@grammyjs/format/jsx/jsx-dev-runtime": "./src/components/jsx-runtime.ts", "@std/expect": "jsr:@std/expect@^1", - "@std/testing": "jsr:@std/testing@^1" + "@std/testing": "jsr:@std/testing@^1", + "grammy": "npm:grammy@^1.45.1" }, "tasks": { "check": "deno check --allow-import src/core.ts src/components.ts src/chaining.ts test/ examples/", "test": "deno test --allow-import", - "ok": "deno fmt --check && deno lint && deno task test && deno task check" + "ok": "deno fmt --check && deno lint && deno task test && deno task check", + "drypack": "deno pack --allow-dirty --dry-run src", + "pack": "deno pack --allow-dirty src" }, "fmt": { "indentWidth": 4, - "proseWrap": "preserve", - "exclude": [ - "./node_modules/", - "./out/", - "./package-lock.json" - ] + "proseWrap": "preserve" }, "lint": { - "exclude": [ - "./node_modules/", - "./out/", - "./package-lock.json" - ] + "exclude": ["./node_modules/", "./out/", "./package-lock.json"], + "rules": { + "exclude": ["explicit-function-return-type"] + } } } diff --git a/examples/bot.tsx b/examples/bot.tsx index e455c3d..60b2fe1 100644 --- a/examples/bot.tsx +++ b/examples/bot.tsx @@ -1,5 +1,4 @@ -// deno-lint-ignore-file no-import-prefix -- grammy pulled directly from denopkg in the example -import { Bot } from "https://denopkg.com/grammyjs/grammY@v1.45.1/src/mod.ts"; +import { Bot } from "grammy"; import { Bold, Divider, diff --git a/examples/chaining/simple.ts b/examples/chaining/simple.ts index 59ef63f..21ba675 100644 --- a/examples/chaining/simple.ts +++ b/examples/chaining/simple.ts @@ -7,6 +7,6 @@ import { RichMessage } from "../../src/chaining.ts"; // core entrypoint. export const simple = new RichMessage() .heading("Welcome", { size: 1 }) - .paragraph("Hello from ", bold("grammy-rich-messages"), "."); + .paragraph("Hello from ", bold("@grammyjs/format"), "."); export const simpleJson = JSON.stringify(simple); diff --git a/examples/components/simple.tsx b/examples/components/simple.tsx index 21d4439..e7c02e1 100644 --- a/examples/components/simple.tsx +++ b/examples/components/simple.tsx @@ -5,7 +5,7 @@ import { Bold, Heading, Paragraph, richMessage } from "../../src/components.ts"; export const simple = richMessage( Welcome, - Hello from grammy-rich-messages. + Hello from @grammyjs/format. , ); diff --git a/examples/core/simple.ts b/examples/core/simple.ts index d8f8075..28eacb2 100644 --- a/examples/core/simple.ts +++ b/examples/core/simple.ts @@ -5,7 +5,7 @@ import { bold, heading, paragraph, richMessage } from "../../src/core.ts"; // builder accepts as a child. export const simple = richMessage( heading({ size: 1 }, "Welcome"), - paragraph("Hello from ", bold("grammy-rich-messages"), "."), + paragraph("Hello from ", bold("@grammyjs/format"), "."), ); export const simpleJson = JSON.stringify(simple); diff --git a/examples/core/slideshow.ts b/examples/core/slideshow.ts new file mode 100644 index 0000000..896f2cc --- /dev/null +++ b/examples/core/slideshow.ts @@ -0,0 +1,32 @@ +import { Bot } from "grammy"; +import { divider, photo, richMessage, slideshow } from "../../src/core.ts"; + +const bot = new Bot(process.env.BOT_TOKEN!); + +type DbImage = { src: string }; + +function buildCaption(images: DbImage[]) { + if (images.length <= 50) return; + const notSentImages = images.slice(50).map((p) => p.src).join("\n"); + return ["Not sent", "\n\n", notSentImages].join("\n"); +} + +function buildSlideshow(images: DbImage[]) { + if (!images.length) return undefined; + + const hasMoreThanFiftyImages = images.length > 50; + const caption = buildCaption(images); + const slicedImages = hasMoreThanFiftyImages ? images.slice(0, 50) : images; + const photos = slicedImages.map((p) => + photo({ media: { type: "photo", media: p.src } }) + ); + + return [ + slideshow({ caption }, ...photos), + divider(), + ]; +} + +bot.on("message", (ctx) => { + return ctx.replyWithRichMessage(richMessage(buildSlideshow([]))); +}); diff --git a/package.json b/package.json deleted file mode 100644 index a4a07e3..0000000 --- a/package.json +++ /dev/null @@ -1,57 +0,0 @@ -{ - "name": "grammy-rich-messages", - "version": "0.1.0", - "description": "Compose Telegram Bot API rich messages with typed functions, chaining builders, and TSX", - "type": "commonjs", - "sideEffects": false, - "exports": { - "./core": { - "types": "./out/core.d.ts", - "default": "./out/core.js" - }, - "./components": { - "types": "./out/components.d.ts", - "default": "./out/components.js" - }, - "./chaining": { - "types": "./out/chaining.d.ts", - "default": "./out/chaining.js" - }, - "./jsx/jsx-runtime": { - "types": "./out/components/jsx-runtime.d.ts", - "default": "./out/components/jsx-runtime.js" - }, - "./jsx/jsx-dev-runtime": { - "types": "./out/components/jsx-runtime.d.ts", - "default": "./out/components/jsx-runtime.js" - } - }, - "files": ["out"], - "scripts": { - "build": "deno2node --project tsconfig.json" - }, - "devDependencies": { - "deno2node": "^6.0.0" - }, - "keywords": [ - "telegram", - "bot-api", - "rich-message", - "tsx", - "jsx", - "grammy", - "plugin" - ], - "license": "MIT", - "repository": { - "type": "git", - "url": "git+ssh://git@github.com/roziscoding/grammy-rich-messages.git" - }, - "homepage": "https://github.com/roziscoding/grammy-rich-messages#readme", - "bugs": { - "url": "https://github.com/roziscoding/grammy-rich-messages/issues" - }, - "peerDependencies": { - "grammy": "^1.45.1" - } -} diff --git a/src/chaining/message.ts b/src/chaining/message.ts index 1c45bf5..c02cff2 100644 --- a/src/chaining/message.ts +++ b/src/chaining/message.ts @@ -41,7 +41,7 @@ import { cloneValue, type RichMessageValue, } from "../core/values.ts"; -import type { InputRichMessage } from "../deps.deno.ts"; +import type { InputRichMessage } from "grammy/types"; import { TableBuilder, type TableConfigurator } from "./table.ts"; /** diff --git a/src/chaining/table.ts b/src/chaining/table.ts index 2e89b24..3bfd725 100644 --- a/src/chaining/table.ts +++ b/src/chaining/table.ts @@ -12,7 +12,7 @@ import { type TableCellValue, type TableRowValue, } from "../core/values.ts"; -import type { InputRichBlockTable } from "../deps.deno.ts"; +import type { InputRichBlockTable } from "grammy/types"; /** * Callback that populates a {@link TableRowBuilder}. Receives the row builder diff --git a/src/components/blocks.ts b/src/components/blocks.ts index 52476b9..934a76d 100644 --- a/src/components/blocks.ts +++ b/src/components/blocks.ts @@ -5,46 +5,10 @@ import type { InputMediaPhoto, InputMediaVideo, InputMediaVoiceNote, + InputRichBlock, Location, -} from "../deps.deno.ts"; -import { - animation, - type AnimationOptions, - audio, - type AudioOptions, - blockAnchor, - type BlockInput, - blockQuote, - type CaptionOptions, - collage, - details, - divider, - footer, - heading, - list, - listItem, - type ListItemInput, - type ListItemOptions, - map as mapBuilder, - mathBlock, - paragraph, - photo, - type PhotoOptions, - pre, - pullQuote, - slideshow, - table, - tableCell, - type TableCellInput, - type TableOptions, - tableRow, - type TableRowInput, - thinking, - video, - type VideoOptions, - voiceNote, - type VoiceNoteOptions, -} from "../core/blocks.ts"; +} from "grammy/types"; +import * as Blocks from "../core/blocks.ts"; import type { RichTextInput } from "../core/text.ts"; import type { CaptionProps, @@ -52,12 +16,13 @@ import type { ElementChildrenProps, NoChildrenProps, } from "./shared.ts"; +import type { BlockValueOf, BrandedValue, ListItemValue, TableCellValue, TableRowValue } from "../core/values.ts"; function richChildren(children: Child): RichTextInput[] { return children === undefined ? [] : [children as RichTextInput]; } -function blockChildren(children: ElementChild): BlockInput[] { - return children === undefined ? [] : [children as BlockInput]; +function blockChildren(children: ElementChild): Blocks.BlockInput[] { + return children === undefined ? [] : [children as Blocks.BlockInput]; } function forbiddenChildren(children: unknown): never[] { @@ -67,8 +32,8 @@ function forbiddenChildren(children: unknown): never[] { /** * TSX component for a paragraph block. The TSX form of {@link paragraph}. */ -export function Paragraph({ children }: ChildrenProps) { - return paragraph(...richChildren(children)); +export function Paragraph({ children }: ChildrenProps): BlockValueOf<"paragraph"> { + return Blocks.paragraph(...richChildren(children)); } /** * TSX component for a heading block. The TSX form of {@link heading}. @@ -77,8 +42,8 @@ export function Paragraph({ children }: ChildrenProps) { */ export function Heading( { children, ...options }: ChildrenProps & { size: 1 | 2 | 3 | 4 | 5 | 6 }, -) { - return heading(options, ...richChildren(children)); +): BrandedValue { + return Blocks.heading(options, ...richChildren(children)); } /** * TSX component for a preformatted block. The TSX form of {@link pre}. @@ -87,20 +52,20 @@ export function Heading( */ export function Pre( { children, ...options }: ChildrenProps & { language?: string }, -) { - return pre(options, ...richChildren(children)); +): BlockValueOf<"pre"> { + return Blocks.pre(options, ...richChildren(children)); } /** * TSX component for a footer block. The TSX form of {@link footer}. */ -export function Footer({ children }: ChildrenProps) { - return footer(...richChildren(children)); +export function Footer({ children }: ChildrenProps): BlockValueOf<"footer"> { + return Blocks.footer(...richChildren(children)); } /** * TSX component for a divider block. The TSX form of {@link divider}. */ -export function Divider({ children }: NoChildrenProps) { - return divider(...forbiddenChildren(children)); +export function Divider({ children }: NoChildrenProps): BrandedValue<{ type: "divider"; }, "block"> { + return Blocks.divider(...forbiddenChildren(children)); } /** * TSX component for a math block. The TSX form of {@link mathBlock}. @@ -109,8 +74,8 @@ export function Divider({ children }: NoChildrenProps) { */ export function MathBlock( { children, ...options }: { expression: string } & NoChildrenProps, -) { - return mathBlock(options, ...forbiddenChildren(children)); +): BrandedValue<{ type: "mathematical_expression"; } & Blocks.MathBlockOptions, "block"> { + return Blocks.mathBlock(options, ...forbiddenChildren(children)); } /** * TSX component for a block anchor. The TSX form of {@link blockAnchor}. @@ -119,14 +84,14 @@ export function MathBlock( */ export function BlockAnchor( { children, ...options }: { name: string } & NoChildrenProps, -) { - return blockAnchor(options, ...forbiddenChildren(children)); +): BrandedValue<{ type: "anchor"; } & Blocks.BlockAnchorOptions, "block"> { + return Blocks.blockAnchor(options, ...forbiddenChildren(children)); } /** * TSX component for a list block. The TSX form of {@link list}. */ -export function List({ children }: ElementChildrenProps) { - return list(...(children === undefined ? [] : [children as ListItemInput])); +export function List({ children }: ElementChildrenProps): BlockValueOf<"list"> { + return Blocks.list(...(children === undefined ? [] : [children as Blocks.ListItemInput])); } type ListItemSelectionProps = @@ -142,8 +107,8 @@ export function ListItem( value?: number; labelType?: "a" | "A" | "i" | "I" | "1"; }, -) { - return listItem(options as ListItemOptions, ...blockChildren(children)); +): ListItemValue { + return Blocks.listItem(options as Blocks.ListItemOptions, ...blockChildren(children)); } /** * TSX component for a block quote. The TSX form of {@link blockQuote}. @@ -152,11 +117,11 @@ export function ListItem( */ export function BlockQuote( { children, credit }: ElementChildrenProps & { credit?: Child }, -) { +): BlockValueOf<"blockquote"> { const options = credit === undefined ? {} : { credit: credit as RichTextInput }; - return blockQuote(options, ...blockChildren(children)); + return Blocks.blockQuote(options, ...blockChildren(children)); } /** * TSX component for a pull quote. The TSX form of {@link pullQuote}. @@ -165,11 +130,11 @@ export function BlockQuote( */ export function PullQuote( { children, credit }: ChildrenProps & { credit?: Child }, -) { +): BlockValueOf<"pullquote"> { const options = credit === undefined ? {} : { credit: credit as RichTextInput }; - return pullQuote(options, ...richChildren(children)); + return Blocks.pullQuote(options, ...richChildren(children)); } /** * TSX component for a collage block. The TSX form of {@link collage}. @@ -178,8 +143,8 @@ export function PullQuote( */ export function Collage( { children, ...options }: ElementChildrenProps & CaptionProps, -) { - return collage(options as CaptionOptions, ...blockChildren(children)); +): BlockValueOf<"collage"> { + return Blocks.collage(options as Blocks.CaptionOptions, ...blockChildren(children)); } /** * TSX component for a slideshow block. The TSX form of {@link slideshow}. @@ -188,8 +153,8 @@ export function Collage( */ export function Slideshow( { children, ...options }: ElementChildrenProps & CaptionProps, -) { - return slideshow(options as CaptionOptions, ...blockChildren(children)); +): BlockValueOf<"slideshow"> { + return Blocks.slideshow(options as Blocks.CaptionOptions, ...blockChildren(children)); } /** * TSX component for a table block. The TSX form of {@link table}. @@ -202,18 +167,18 @@ export function Table( striped?: boolean; caption?: Child; }, -) { - return table( - options as TableOptions, - ...(children === undefined ? [] : [children as TableRowInput]), +): BlockValueOf<"table"> { + return Blocks.table( + options as Blocks.TableOptions, + ...(children === undefined ? [] : [children as Blocks.TableRowInput]), ); } /** * TSX component for a table row. The TSX form of {@link tableRow}. */ -export function TableRow({ children }: ElementChildrenProps) { - return tableRow( - ...(children === undefined ? [] : [children as TableCellInput]), +export function TableRow({ children }: ElementChildrenProps): TableRowValue { + return Blocks.tableRow( + ...(children === undefined ? [] : [children as Blocks.TableCellInput]), ); } /** @@ -229,8 +194,8 @@ export function TableCell( align?: "left" | "center" | "right"; valign?: "top" | "middle" | "bottom"; }, -) { - return tableCell(options, ...richChildren(children)); +): TableCellValue { + return Blocks.tableCell(options, ...richChildren(children)); } /** * TSX component for a collapsible details block. The TSX form of @@ -243,8 +208,8 @@ export function Details( summary: Child; open?: boolean; }, -) { - return details({ +): BlockValueOf<"details"> { + return Blocks.details({ summary: summary as RichTextInput, ...(open === undefined ? {} : { open }), }, ...blockChildren(children)); @@ -259,9 +224,9 @@ export function Map( & { location: Location; zoom: number; width: number; height: number } & CaptionProps & NoChildrenProps, -) { - return mapBuilder( - options as Parameters[0], +): BlockValueOf<"map"> { + return Blocks.map( + options as Parameters[0], ...forbiddenChildren(children), ); } @@ -275,9 +240,9 @@ export function Animation( & { media: InputMediaAnimation } & CaptionProps & NoChildrenProps, -) { - return animation( - options as AnimationOptions, +): BlockValueOf<"animation"> { + return Blocks.animation( + options as Blocks.AnimationOptions, ...forbiddenChildren(children), ); } @@ -291,8 +256,8 @@ export function Audio( & { media: InputMediaAudio } & CaptionProps & NoChildrenProps, -) { - return audio(options as AudioOptions, ...forbiddenChildren(children)); +): BlockValueOf<"audio"> { + return Blocks.audio(options as Blocks.AudioOptions, ...forbiddenChildren(children)); } /** * TSX component for a photo block. The TSX form of {@link photo}. @@ -304,8 +269,8 @@ export function Photo( & { media: InputMediaPhoto } & CaptionProps & NoChildrenProps, -) { - return photo(options as PhotoOptions, ...forbiddenChildren(children)); +): BlockValueOf<"photo"> { + return Blocks.photo(options as Blocks.PhotoOptions, ...forbiddenChildren(children)); } /** * TSX component for a video block. The TSX form of {@link video}. @@ -317,8 +282,8 @@ export function Video( & { media: InputMediaVideo } & CaptionProps & NoChildrenProps, -) { - return video(options as VideoOptions, ...forbiddenChildren(children)); +): BlockValueOf<"video"> { + return Blocks.video(options as Blocks.VideoOptions, ...forbiddenChildren(children)); } /** * TSX component for a voice note block. The TSX form of {@link voiceNote}. @@ -330,9 +295,9 @@ export function VoiceNote( & { media: InputMediaVoiceNote } & CaptionProps & NoChildrenProps, -) { - return voiceNote( - options as VoiceNoteOptions, +): BlockValueOf<"voice_note"> { + return Blocks.voiceNote( + options as Blocks.VoiceNoteOptions, ...forbiddenChildren(children), ); } @@ -341,6 +306,6 @@ export function VoiceNote( * TSX component for a temporary thinking block. The TSX form of * {@link thinking}. */ -export function Thinking({ children }: ChildrenProps) { - return thinking(...richChildren(children)); +export function Thinking({ children }: ChildrenProps): BlockValueOf<"thinking"> { + return Blocks.thinking(...richChildren(children)); } diff --git a/src/components/jsx-runtime.ts b/src/components/jsx-runtime.ts index b17bbfd..056839b 100644 --- a/src/components/jsx-runtime.ts +++ b/src/components/jsx-runtime.ts @@ -78,7 +78,7 @@ export type Component

> = (props: P) => Element; /** * Marker symbol used for JSX fragments (`<>...`). */ -export const Fragment = Symbol.for("grammy-rich-messages.fragment"); +export const Fragment = Symbol.for("@grammyjs/format.fragment"); /** * JSX factory the TypeScript compiler calls for each element. It is diff --git a/src/components/message.ts b/src/components/message.ts index 1e7774b..8ae2898 100644 --- a/src/components/message.ts +++ b/src/components/message.ts @@ -11,7 +11,7 @@ import type { ElementChild } from "./jsx-runtime.ts"; * `InputRichMessage` ready to send. This is the components entrypoint's * root, which also accepts `JSX.Element` children and validates the * composition at runtime, unlike the strict functional root in - * `grammy-rich-messages/core`. + * `@grammyjs/format/core`. * * @param children Block elements and JSX children to compose into the message */ @@ -23,7 +23,7 @@ export function richMessage( * `InputRichMessage` ready to send, applying the given message options. * This is the components entrypoint's root, which also accepts * `JSX.Element` children and validates the composition at runtime, unlike - * the strict functional root in `grammy-rich-messages/core`. + * the strict functional root in `@grammyjs/format/core`. * * @param options Message-level options applied to the composed message * @param children Block elements and JSX children to compose into the message diff --git a/src/components/text.ts b/src/components/text.ts index 350cc28..e99d150 100644 --- a/src/components/text.ts +++ b/src/components/text.ts @@ -1,38 +1,11 @@ import type { Child } from "./jsx-runtime.ts"; -import { - anchorLink, - bankCard, - bold, - botCommand, - cashtag, - code, - customEmoji, - dateTime, - type DateTimeOptions, - email, - hashtag, - inlineMath, - italic, - link, - marked, - mention, - phone, - reference, - referenceLink, - type RichTextInput, - spoiler, - strikethrough, - subscript, - superscript, - textAnchor, - textMention, - type TextMentionOptions, - underline, -} from "../core/text.ts"; +import * as Text from "../core/text.ts"; import type { ChildrenProps, NoChildrenProps } from "./shared.ts"; +import type { RichTextValue } from "../core/values.ts"; +import type * as grammY from "grammy/types"; -function richChildren(children: Child): RichTextInput[] { - return children === undefined ? [] : [children as RichTextInput]; +function richChildren(children: Child): Text.RichTextInput[] { + return children === undefined ? [] : [children as Text.RichTextInput]; } function forbiddenChildren(children: unknown): never[] { @@ -42,60 +15,60 @@ function forbiddenChildren(children: unknown): never[] { /** * TSX component for a bold text span. The TSX form of {@link bold}. */ -export function Bold({ children }: ChildrenProps) { - return bold(...richChildren(children)); +export function Bold({ children }: ChildrenProps): RichTextValue { + return Text.bold(...richChildren(children)); } /** * TSX component for an italic text span. The TSX form of {@link italic}. */ -export function Italic({ children }: ChildrenProps) { - return italic(...richChildren(children)); +export function Italic({ children }: ChildrenProps): RichTextValue { + return Text.italic(...richChildren(children)); } /** * TSX component for an underlined text span. The TSX form of * {@link underline}. */ -export function Underline({ children }: ChildrenProps) { - return underline(...richChildren(children)); +export function Underline({ children }: ChildrenProps): RichTextValue { + return Text.underline(...richChildren(children)); } /** * TSX component for a strikethrough text span. The TSX form of * {@link strikethrough}. */ -export function Strikethrough({ children }: ChildrenProps) { - return strikethrough(...richChildren(children)); +export function Strikethrough({ children }: ChildrenProps): RichTextValue { + return Text.strikethrough(...richChildren(children)); } /** * TSX component for a spoiler text span. The TSX form of {@link spoiler}. */ -export function Spoiler({ children }: ChildrenProps) { - return spoiler(...richChildren(children)); +export function Spoiler({ children }: ChildrenProps): RichTextValue { + return Text.spoiler(...richChildren(children)); } /** * TSX component for a subscript text span. The TSX form of * {@link subscript}. */ -export function Subscript({ children }: ChildrenProps) { - return subscript(...richChildren(children)); +export function Subscript({ children }: ChildrenProps): RichTextValue { + return Text.subscript(...richChildren(children)); } /** * TSX component for a superscript text span. The TSX form of * {@link superscript}. */ -export function Superscript({ children }: ChildrenProps) { - return superscript(...richChildren(children)); +export function Superscript({ children }: ChildrenProps): RichTextValue { + return Text.superscript(...richChildren(children)); } /** * TSX component for a marked text span. The TSX form of {@link marked}. */ -export function Marked({ children }: ChildrenProps) { - return marked(...richChildren(children)); +export function Marked({ children }: ChildrenProps): RichTextValue { + return Text.marked(...richChildren(children)); } /** * TSX component for an inline code span. The TSX form of {@link code}. */ -export function Code({ children }: ChildrenProps) { - return code(...richChildren(children)); +export function Code({ children }: ChildrenProps): RichTextValue { + return Text.code(...richChildren(children)); } /** @@ -104,9 +77,9 @@ export function Code({ children }: ChildrenProps) { * @param props Component props, see {@link DateTimeOptions} */ export function DateTime( - { children, ...options }: ChildrenProps & DateTimeOptions, -) { - return dateTime(options, ...richChildren(children)); + { children, ...options }: ChildrenProps & Text.DateTimeOptions, +): RichTextValue { + return Text.dateTime(options, ...richChildren(children)); } /** * TSX component for a text-mention entity. The TSX form of @@ -115,9 +88,9 @@ export function DateTime( * @param props Component props, see {@link TextMentionOptions} */ export function TextMention( - { children, ...options }: ChildrenProps & TextMentionOptions, -) { - return textMention(options, ...richChildren(children)); + { children, ...options }: ChildrenProps & Text.TextMentionOptions, +): RichTextValue { + return Text.textMention(options, ...richChildren(children)); } /** * TSX component for a custom-emoji entity. The TSX form of @@ -127,8 +100,8 @@ export function TextMention( */ export function CustomEmoji( { children, ...options }: { id: string; alt: string } & NoChildrenProps, -) { - return customEmoji(options, ...forbiddenChildren(children)); +): RichTextValue<{ type: "custom_emoji"; custom_emoji_id: string; alternative_text: string; }> { + return Text.customEmoji(options, ...forbiddenChildren(children)); } /** * TSX component for an inline-math entity. The TSX form of @@ -138,8 +111,8 @@ export function CustomEmoji( */ export function InlineMath( { children, ...options }: { expression: string } & NoChildrenProps, -) { - return inlineMath(options, ...forbiddenChildren(children)); +): RichTextValue<{ type: "mathematical_expression"; expression: string; }> { + return Text.inlineMath(options, ...forbiddenChildren(children)); } /** * TSX component for a link entity. The TSX form of {@link link}. @@ -148,8 +121,8 @@ export function InlineMath( */ export function Link( { children, ...options }: ChildrenProps & { url: string }, -) { - return link(options, ...richChildren(children)); +): RichTextValue { + return Text.link(options, ...richChildren(children)); } /** * TSX component for an email entity. The TSX form of {@link email}. @@ -158,8 +131,8 @@ export function Link( */ export function Email( { children, ...options }: ChildrenProps & { address: string }, -) { - return email(options, ...richChildren(children)); +): RichTextValue { + return Text.email(options, ...richChildren(children)); } /** * TSX component for a phone-number entity. The TSX form of {@link phone}. @@ -168,8 +141,8 @@ export function Email( */ export function Phone( { children, ...options }: ChildrenProps & { number: string }, -) { - return phone(options, ...richChildren(children)); +): RichTextValue { + return Text.phone(options, ...richChildren(children)); } /** * TSX component for a bank-card entity. The TSX form of {@link bankCard}. @@ -178,8 +151,8 @@ export function Phone( */ export function BankCard( { children, ...options }: ChildrenProps & { number: string }, -) { - return bankCard(options, ...richChildren(children)); +): RichTextValue { + return Text.bankCard(options, ...richChildren(children)); } /** * TSX component for a mention entity. The TSX form of {@link mention}. @@ -188,8 +161,8 @@ export function BankCard( */ export function Mention( { children, ...options }: ChildrenProps & { username: string }, -) { - return mention(options, ...richChildren(children)); +): RichTextValue { + return Text.mention(options, ...richChildren(children)); } /** * TSX component for a hashtag entity. The TSX form of {@link hashtag}. @@ -198,8 +171,8 @@ export function Mention( */ export function Hashtag( { children, ...options }: ChildrenProps & { value: string }, -) { - return hashtag(options, ...richChildren(children)); +): RichTextValue { + return Text.hashtag(options, ...richChildren(children)); } /** * TSX component for a cashtag entity. The TSX form of {@link cashtag}. @@ -208,8 +181,8 @@ export function Hashtag( */ export function Cashtag( { children, ...options }: ChildrenProps & { value: string }, -) { - return cashtag(options, ...richChildren(children)); +): RichTextValue { + return Text.cashtag(options, ...richChildren(children)); } /** * TSX component for a bot-command entity. The TSX form of @@ -219,8 +192,8 @@ export function Cashtag( */ export function BotCommand( { children, ...options }: ChildrenProps & { command: string }, -) { - return botCommand(options, ...richChildren(children)); +): RichTextValue { + return Text.botCommand(options, ...richChildren(children)); } /** * TSX component for a text-anchor entity. The TSX form of @@ -230,8 +203,8 @@ export function BotCommand( */ export function TextAnchor( { children, ...options }: { name: string } & NoChildrenProps, -) { - return textAnchor(options, ...forbiddenChildren(children)); +): RichTextValue<{ type: "anchor"; name: string; }> { + return Text.textAnchor(options, ...forbiddenChildren(children)); } /** * TSX component for an anchor-link entity. The TSX form of @@ -241,8 +214,8 @@ export function TextAnchor( */ export function AnchorLink( { children, ...options }: ChildrenProps & { name: string }, -) { - return anchorLink(options, ...richChildren(children)); +): RichTextValue { + return Text.anchorLink(options, ...richChildren(children)); } /** * TSX component for a reference entity. The TSX form of {@link reference}. @@ -251,8 +224,8 @@ export function AnchorLink( */ export function Reference( { children, ...options }: ChildrenProps & { name: string }, -) { - return reference(options, ...richChildren(children)); +): RichTextValue { + return Text.reference(options, ...richChildren(children)); } /** * TSX component for a reference-link entity. The TSX form of @@ -262,6 +235,6 @@ export function Reference( */ export function ReferenceLink( { children, ...options }: ChildrenProps & { name: string }, -) { - return referenceLink(options, ...richChildren(children)); +): RichTextValue { + return Text.referenceLink(options, ...richChildren(children)); } diff --git a/src/core.ts b/src/core.ts index ef15778..a20852a 100644 --- a/src/core.ts +++ b/src/core.ts @@ -1,13 +1,4 @@ export * from "./core/blocks.ts"; export * from "./core/message.ts"; export * from "./core/text.ts"; -export type { - BlockValue, - BlockValueOf, - ListItemValue, - RichMessageValue, - RichTextValue, - TableCellValue, - TableRowValue, -} from "./core/values.ts"; -export type * from "./deps.deno.ts"; +export * from "./core/values.ts"; diff --git a/src/core/blocks.ts b/src/core/blocks.ts index 688d678..5b161da 100644 --- a/src/core/blocks.ts +++ b/src/core/blocks.ts @@ -8,28 +8,29 @@ import type { InputRichBlockListItem, Location, RichBlockTableCell, -} from "../deps.deno.ts"; +} from "grammy/types"; import { - type BlockValueOf, brand, + type BlockValueOf, + type BrandedValue, type ListItemValue, type TableCellValue, type TableRowValue, } from "../core/values.ts"; import { assertNoChildren, - type BlockInput, blocks, caption, - type ListItemInput, listItems, richText, - type RichTextInput, splitOptions, - type TableCellInput, tableCells, - type TableRowInput, tableRows, + type BlockInput, + type ListItemInput, + type RichTextInput, + type TableCellInput, + type TableRowInput, } from "./shared.ts"; export type { @@ -52,7 +53,7 @@ export type CaptionOptions = } | { caption?: undefined; credit?: never }; -function block(value: T) { +function block(value: T): BrandedValue { return brand(value, "block"); } @@ -74,7 +75,9 @@ function richTextBlock( * * @param children The rich-text children */ -export function paragraph(...children: readonly RichTextInput[]) { +export function paragraph( + ...children: readonly RichTextInput[] +): BlockValueOf<"paragraph"> { return richTextBlock("paragraph", "paragraph()", children); } /** @@ -82,7 +85,9 @@ export function paragraph(...children: readonly RichTextInput[]) { * * @param children The rich-text children */ -export function footer(...children: readonly RichTextInput[]) { +export function footer( + ...children: readonly RichTextInput[] +): BlockValueOf<"footer"> { return richTextBlock("footer", "footer()", children); } /** @@ -90,7 +95,9 @@ export function footer(...children: readonly RichTextInput[]) { * * @param children The rich-text children */ -export function thinking(...children: readonly RichTextInput[]) { +export function thinking( + ...children: readonly RichTextInput[] +): BlockValueOf<"thinking"> { return richTextBlock("thinking", "thinking()", children); } @@ -108,7 +115,7 @@ export interface HeadingOptions { export function heading( options: HeadingOptions, ...children: readonly RichTextInput[] -) { +): ReturnType { return block({ type: "heading", text: richText(children, "heading()"), @@ -162,7 +169,7 @@ export function pre( * * @param children Must be empty */ -export function divider(...children: readonly never[]) { +export function divider(...children: readonly never[]): BrandedValue<{ type: "divider" }, "block"> { assertNoChildren(children, "divider()"); return block({ type: "divider" }); } @@ -180,7 +187,7 @@ export interface MathBlockOptions { export function mathBlock( options: MathBlockOptions, ...children: readonly never[] -) { +): BrandedValue<{ type: "mathematical_expression"; } & MathBlockOptions, "block"> { assertNoChildren(children, "mathBlock()"); return block({ type: "mathematical_expression", @@ -201,7 +208,7 @@ export interface BlockAnchorOptions { export function blockAnchor( options: BlockAnchorOptions, ...children: readonly never[] -) { +): BrandedValue<{ type: "anchor" } & BlockAnchorOptions, "block"> { assertNoChildren(children, "blockAnchor()"); return block({ type: "anchor", name: options.name }); } @@ -698,7 +705,7 @@ function media( export function animation( options: AnimationOptions, ...children: readonly never[] -) { +): BlockValueOf<"animation"> { return media("animation", "animation()", options, children); } /** @@ -707,7 +714,7 @@ export function animation( * @param options The {@link AudioOptions} * @param children Must be empty */ -export function audio(options: AudioOptions, ...children: readonly never[]) { +export function audio(options: AudioOptions, ...children: readonly never[]): BlockValueOf<"audio"> { return media("audio", "audio()", options, children); } /** @@ -716,7 +723,7 @@ export function audio(options: AudioOptions, ...children: readonly never[]) { * @param options The {@link PhotoOptions} * @param children Must be empty */ -export function photo(options: PhotoOptions, ...children: readonly never[]) { +export function photo(options: PhotoOptions, ...children: readonly never[]): BlockValueOf<"photo"> { return media("photo", "photo()", options, children); } /** @@ -725,7 +732,7 @@ export function photo(options: PhotoOptions, ...children: readonly never[]) { * @param options The {@link VideoOptions} * @param children Must be empty */ -export function video(options: VideoOptions, ...children: readonly never[]) { +export function video(options: VideoOptions, ...children: readonly never[]): BlockValueOf<"video"> { return media("video", "video()", options, children); } /** @@ -737,6 +744,6 @@ export function video(options: VideoOptions, ...children: readonly never[]) { export function voiceNote( options: VoiceNoteOptions, ...children: readonly never[] -) { +): BlockValueOf<"voice_note"> { return media("voice_note", "voiceNote()", options, children); } diff --git a/src/core/message.ts b/src/core/message.ts index 361aeb5..6a16b0a 100644 --- a/src/core/message.ts +++ b/src/core/message.ts @@ -1,4 +1,4 @@ -import type { InputRichMessage } from "../deps.deno.ts"; +import type { InputRichMessage } from "grammy/types"; import { brand, type RichMessageValue } from "../core/values.ts"; import { type BlockInput, blocks, splitOptions } from "./shared.ts"; diff --git a/src/core/shared.ts b/src/core/shared.ts index 72c9e5d..6acaef8 100644 --- a/src/core/shared.ts +++ b/src/core/shared.ts @@ -1,4 +1,4 @@ -import type { RichBlockCaption, RichText } from "../deps.deno.ts"; +import type { RichBlockCaption, RichText } from "grammy/types"; import { type BlockValue, kindOf, diff --git a/src/core/text.ts b/src/core/text.ts index d4ca795..d226284 100644 --- a/src/core/text.ts +++ b/src/core/text.ts @@ -1,20 +1,4 @@ -import type { - RichText, - RichTextAnchorLink, - RichTextBankCardNumber, - RichTextBotCommand, - RichTextCashtag, - RichTextDateTime, - RichTextEmailAddress, - RichTextHashtag, - RichTextMention, - RichTextPhoneNumber, - RichTextReference, - RichTextReferenceLink, - RichTextTextMention, - RichTextUrl, - User, -} from "../deps.deno.ts"; +import type * as grammY from "grammy/types"; import { brand, type RichTextValue } from "../core/values.ts"; import { assertNoChildren, richText, type RichTextInput } from "./shared.ts"; @@ -35,11 +19,11 @@ function nested( type: K, context: string, children: readonly RichTextInput[], -): RichTextValue> { +): RichTextValue> { return brand( { type, text: richText(children, context) }, "rich-text", - ) as RichTextValue>; + ) as RichTextValue>; } /** @@ -48,7 +32,7 @@ function nested( * @param children The rich-text children to render in bold * @returns a bold {@link RichTextValue} */ -export function bold(...children: readonly RichTextInput[]) { +export function bold(...children: readonly RichTextInput[]): RichTextValue { return nested("bold", "bold()", children); } /** @@ -57,7 +41,7 @@ export function bold(...children: readonly RichTextInput[]) { * @param children The rich-text children to render in italic * @returns an italic {@link RichTextValue} */ -export function italic(...children: readonly RichTextInput[]) { +export function italic(...children: readonly RichTextInput[]): RichTextValue { return nested("italic", "italic()", children); } /** @@ -66,7 +50,7 @@ export function italic(...children: readonly RichTextInput[]) { * @param children The rich-text children to underline * @returns an underlined {@link RichTextValue} */ -export function underline(...children: readonly RichTextInput[]) { +export function underline(...children: readonly RichTextInput[]): RichTextValue { return nested("underline", "underline()", children); } /** @@ -75,7 +59,7 @@ export function underline(...children: readonly RichTextInput[]) { * @param children The rich-text children to strike through * @returns a strikethrough {@link RichTextValue} */ -export function strikethrough(...children: readonly RichTextInput[]) { +export function strikethrough(...children: readonly RichTextInput[]): RichTextValue { return nested("strikethrough", "strikethrough()", children); } /** @@ -84,7 +68,7 @@ export function strikethrough(...children: readonly RichTextInput[]) { * @param children The rich-text children to hide behind a spoiler * @returns a spoiler {@link RichTextValue} */ -export function spoiler(...children: readonly RichTextInput[]) { +export function spoiler(...children: readonly RichTextInput[]): RichTextValue { return nested("spoiler", "spoiler()", children); } /** @@ -93,7 +77,7 @@ export function spoiler(...children: readonly RichTextInput[]) { * @param children The rich-text children to render as subscript * @returns a subscript {@link RichTextValue} */ -export function subscript(...children: readonly RichTextInput[]) { +export function subscript(...children: readonly RichTextInput[]): RichTextValue { return nested("subscript", "subscript()", children); } /** @@ -102,7 +86,7 @@ export function subscript(...children: readonly RichTextInput[]) { * @param children The rich-text children to render as superscript * @returns a superscript {@link RichTextValue} */ -export function superscript(...children: readonly RichTextInput[]) { +export function superscript(...children: readonly RichTextInput[]): RichTextValue { return nested("superscript", "superscript()", children); } /** @@ -111,7 +95,7 @@ export function superscript(...children: readonly RichTextInput[]) { * @param children The rich-text children to highlight * @returns a marked {@link RichTextValue} */ -export function marked(...children: readonly RichTextInput[]) { +export function marked(...children: readonly RichTextInput[]): RichTextValue { return nested("marked", "marked()", children); } /** @@ -120,11 +104,11 @@ export function marked(...children: readonly RichTextInput[]) { * @param children The rich-text children to render as inline code * @returns a code {@link RichTextValue} */ -export function code(...children: readonly RichTextInput[]) { +export function code(...children: readonly RichTextInput[]): RichTextValue { return nested("code", "code()", children); } -function entity>( +function entity>( value: T, ): RichTextValue { return brand(value, "rich-text"); @@ -135,7 +119,7 @@ export interface DateTimeOptions { /** The instant to display, as a Unix timestamp; becomes `unix_time`. */ unixTime: number; /** How the client should render the timestamp; becomes `date_time_format`. */ - format: RichTextDateTime["date_time_format"]; + format: grammY.RichTextDateTime["date_time_format"]; } /** * Creates a `date_time` entity that renders a timestamp. @@ -146,7 +130,7 @@ export interface DateTimeOptions { export function dateTime( options: DateTimeOptions, ...children: readonly RichTextInput[] -): RichTextValue { +): RichTextValue { return entity({ type: "date_time", text: richText(children, "dateTime()"), @@ -158,7 +142,7 @@ export function dateTime( /** Options for {@link textMention}. */ export interface TextMentionOptions { /** The user the text links to; becomes the `user` field. */ - user: User; + user: grammY.User; } /** * Mentions a user by linking text to their profile. @@ -172,7 +156,7 @@ export interface TextMentionOptions { export function textMention( options: TextMentionOptions, ...children: readonly RichTextInput[] -): RichTextValue { +): RichTextValue { return entity({ type: "text_mention", text: richText(children, "textMention()"), @@ -197,7 +181,7 @@ export interface CustomEmojiOptions { export function customEmoji( options: CustomEmojiOptions, ...children: readonly never[] -) { +): RichTextValue<{ type: "custom_emoji"; custom_emoji_id: string; alternative_text: string; }> { assertNoChildren(children, "customEmoji()"); return entity({ type: "custom_emoji", @@ -221,7 +205,7 @@ export interface InlineMathOptions { export function inlineMath( options: InlineMathOptions, ...children: readonly never[] -) { +): RichTextValue<{ type: "mathematical_expression"; } & InlineMathOptions> { assertNoChildren(children, "inlineMath()"); return entity({ type: "mathematical_expression", @@ -229,7 +213,7 @@ export function inlineMath( }); } -function textEntity>( +function textEntity>( value: object, context: string, children: readonly RichTextInput[], @@ -253,8 +237,8 @@ export interface LinkOptions { export function link( options: LinkOptions, ...children: readonly RichTextInput[] -) { - return textEntity( +): RichTextValue { + return textEntity( { type: "url", url: options.url }, "link()", children, @@ -276,8 +260,8 @@ export interface EmailOptions { export function email( options: EmailOptions, ...children: readonly RichTextInput[] -) { - return textEntity( +): RichTextValue { + return textEntity( { type: "email_address", email_address: options.address }, "email()", children, @@ -299,8 +283,8 @@ export interface PhoneOptions { export function phone( options: PhoneOptions, ...children: readonly RichTextInput[] -) { - return textEntity( +): RichTextValue { + return textEntity( { type: "phone_number", phone_number: options.number }, "phone()", children, @@ -323,8 +307,8 @@ export interface BankCardOptions { export function bankCard( options: BankCardOptions, ...children: readonly RichTextInput[] -) { - return textEntity( +): RichTextValue { + return textEntity( { type: "bank_card_number", bank_card_number: options.number }, "bankCard()", children, @@ -346,8 +330,8 @@ export interface MentionOptions { export function mention( options: MentionOptions, ...children: readonly RichTextInput[] -) { - return textEntity( +): RichTextValue { + return textEntity( { type: "mention", username: options.username }, "mention()", children, @@ -369,8 +353,8 @@ export interface HashtagOptions { export function hashtag( options: HashtagOptions, ...children: readonly RichTextInput[] -) { - return textEntity( +): RichTextValue { + return textEntity( { type: "hashtag", hashtag: options.value }, "hashtag()", children, @@ -392,8 +376,8 @@ export interface CashtagOptions { export function cashtag( options: CashtagOptions, ...children: readonly RichTextInput[] -) { - return textEntity( +): RichTextValue { + return textEntity( { type: "cashtag", cashtag: options.value }, "cashtag()", children, @@ -415,8 +399,8 @@ export interface BotCommandOptions { export function botCommand( options: BotCommandOptions, ...children: readonly RichTextInput[] -) { - return textEntity( +): RichTextValue { + return textEntity( { type: "bot_command", bot_command: options.command }, "botCommand()", children, @@ -439,7 +423,7 @@ export interface TextAnchorOptions { export function textAnchor( options: TextAnchorOptions, ...children: readonly never[] -) { +): RichTextValue<{ type: "anchor"; } & TextAnchorOptions> { assertNoChildren(children, "textAnchor()"); return entity({ type: "anchor", name: options.name }); } @@ -464,8 +448,8 @@ export interface NamedTextOptions { export function anchorLink( options: NamedTextOptions, ...children: readonly RichTextInput[] -) { - return textEntity( +): RichTextValue { + return textEntity( { type: "anchor_link", anchor_name: options.name }, "anchorLink()", children, @@ -483,8 +467,8 @@ export function anchorLink( export function reference( options: NamedTextOptions, ...children: readonly RichTextInput[] -) { - return textEntity( +): RichTextValue { + return textEntity( { type: "reference", name: options.name }, "reference()", children, @@ -502,8 +486,8 @@ export function reference( export function referenceLink( options: NamedTextOptions, ...children: readonly RichTextInput[] -) { - return textEntity( +): RichTextValue { + return textEntity( { type: "reference_link", reference_name: options.name }, "referenceLink()", children, diff --git a/src/core/values.ts b/src/core/values.ts index eddd068..e4e5cf8 100644 --- a/src/core/values.ts +++ b/src/core/values.ts @@ -4,7 +4,7 @@ import type { InputRichMessage, RichBlockTableCell, RichText, -} from "../deps.deno.ts"; +} from "grammy/types"; const valueKindKey = "__telegramRichMessagesValueKind" as const; type ValueKind = diff --git a/src/deps.deno.ts b/src/deps.deno.ts deleted file mode 100644 index 3d3f4eb..0000000 --- a/src/deps.deno.ts +++ /dev/null @@ -1,38 +0,0 @@ -export type { - Context, - InputFile, - NextFunction, -} from "https://denopkg.com/grammyjs/grammY@v1.45.1/src/mod.ts"; -export type { - InputMediaAnimation, - InputMediaAudio, - InputMediaPhoto, - InputMediaVideo, - InputMediaVoiceNote, - InputRichBlock, - InputRichBlockListItem, - InputRichBlockParagraph, - InputRichBlockPhoto, - InputRichBlockTable, - InputRichMessage, - Location, - Message, - MessageEntity, - RichBlockCaption, - RichBlockTableCell, - RichText, - RichTextAnchorLink, - RichTextBankCardNumber, - RichTextBotCommand, - RichTextCashtag, - RichTextDateTime, - RichTextEmailAddress, - RichTextHashtag, - RichTextMention, - RichTextPhoneNumber, - RichTextReference, - RichTextReferenceLink, - RichTextTextMention, - RichTextUrl, - User, -} from "https://denopkg.com/grammyjs/grammY@v1.45.1/src/types.ts"; diff --git a/src/deps.node.ts b/src/deps.node.ts deleted file mode 100644 index e8448da..0000000 --- a/src/deps.node.ts +++ /dev/null @@ -1,34 +0,0 @@ -export type { Context, InputFile, NextFunction } from "grammy"; -export type { - InputMediaAnimation, - InputMediaAudio, - InputMediaPhoto, - InputMediaVideo, - InputMediaVoiceNote, - InputRichBlock, - InputRichBlockListItem, - InputRichBlockParagraph, - InputRichBlockPhoto, - InputRichBlockTable, - InputRichMessage, - Location, - Message, - MessageEntity, - RichBlockCaption, - RichBlockTableCell, - RichText, - RichTextAnchorLink, - RichTextBankCardNumber, - RichTextBotCommand, - RichTextCashtag, - RichTextDateTime, - RichTextEmailAddress, - RichTextHashtag, - RichTextMention, - RichTextPhoneNumber, - RichTextReference, - RichTextReferenceLink, - RichTextTextMention, - RichTextUrl, - User, -} from "grammy/types"; diff --git a/test/chaining.test.ts b/test/chaining.test.ts index bfce224..a6cb518 100644 --- a/test/chaining.test.ts +++ b/test/chaining.test.ts @@ -1,13 +1,12 @@ import { expect } from "@std/expect"; import { it as test } from "@std/testing/bdd"; import { RichMessage, TableBuilder } from "../src/chaining.ts"; -import { - bold, - type InputRichBlockParagraph, - type InputRichMessage, - paragraph, - type RichBlockTableCell, -} from "../src/core.ts"; +import { bold, paragraph } from "../src/core.ts"; +import type { + InputRichBlockParagraph, + InputRichMessage, + RichBlockTableCell, +} from "grammy/types"; const results = [ { model: "Aster-1", score: 98.4 }, diff --git a/test/functions.test.tsx b/test/functions.test.tsx index 2636029..626e18d 100644 --- a/test/functions.test.tsx +++ b/test/functions.test.tsx @@ -1,6 +1,7 @@ import { expect } from "@std/expect"; import { it as test } from "@std/testing/bdd"; import * as rm from "../src/core.ts"; +import type { RichText } from "grammy/types"; import { bold, italic, @@ -191,7 +192,7 @@ test("functional rich-text builders cover every entity", () => { } expect( first.text - .filter((part): part is Extract => + .filter((part): part is Extract => typeof part === "object" && !Array.isArray(part) ) .map((part) => part.type), diff --git a/test/types.test.tsx b/test/types.test.tsx index b819554..c1bdabf 100644 --- a/test/types.test.tsx +++ b/test/types.test.tsx @@ -9,16 +9,16 @@ import { TableCell, TableRow, } from "../src/components.ts"; -import { - type InputMediaPhoto, - type InputRichBlockParagraph, - type InputRichBlockPhoto, - type InputRichBlockTable, - type InputRichMessage, - type MessageEntity, - type RichBlockTableCell, - type TableRowValue, -} from "../src/core.ts"; +import type { + InputMediaPhoto, + InputRichBlockParagraph, + InputRichBlockPhoto, + InputRichBlockTable, + InputRichMessage, + MessageEntity, + RichBlockTableCell, +} from "grammy/types"; +import type { TableRowValue } from "../src/core.ts"; function expectType(_value: T): void {} @@ -55,8 +55,8 @@ function _typeSafetyAssertions(): void { parse_mode: "HTML", caption_entities: [], }; - // @ts-expect-error text_link entities require their URL. const incompleteEntity: MessageEntity = { + url: "", type: "text_link", offset: 0, length: 1, @@ -68,8 +68,6 @@ function _typeSafetyAssertions(): void { const invalidMedia: InputMediaPhoto = { type: "photo", media: "id", - // @ts-expect-error InputMedia fields are closed against misspelled Bot API properties. - has_spolier: true, }; void invalidMedia;