import * as unified from 'unified'; import * as hast from 'hast'; import * as mdast from 'mdast'; import { HookifiedOptions, Hookified } from 'hookified'; import { HTMLReactParserOptions } from 'html-react-parser'; import React from 'react'; import { CacheableMemory } from 'cacheable'; import { LanguageModel } from 'ai'; /** * Writr options. * @typedef {Object} WritrOptions * @property {RenderOptions} [renderOptions] - Default render options (default: undefined) */ type WritrOptions = { renderOptions?: RenderOptions; ai?: WritrAIOptions; } & HookifiedOptions; /** * Render options. * @typedef {Object} RenderOptions * @property {boolean} [emoji] - Emoji support (default: true) * @property {boolean} [toc] - Table of contents generation (default: true) * @property {boolean} [slug] - Slug generation (default: true) * @property {boolean} [highlight] - Code highlighting (default: true) * @property {boolean} [gfm] - Github flavor markdown (default: true) * @property {boolean} [math] - Math support (default: true) * @property {boolean} [mdx] - MDX support (default: false) * @property {boolean} [rawHtml] - Raw HTML passthrough (default: false) * @property {boolean} [caching] - Caching (default: true) */ type RenderOptions = { emoji?: boolean; toc?: boolean; slug?: boolean; highlight?: boolean; gfm?: boolean; math?: boolean; mdx?: boolean; rawHtml?: boolean; caching?: boolean; }; /** * Validation result. * @typedef {Object} WritrValidateResult * @property {boolean} valid - Whether the markdown is valid * @property {Error} [error] - Error if validation failed */ type WritrValidateResult = { valid: boolean; error?: Error; }; declare enum WritrHooks { beforeRender = "beforeRender", afterRender = "afterRender", saveToFile = "saveToFile", renderToFile = "renderToFile", loadFromFile = "loadFromFile" } /** * Metadata generated for a markdown document. */ type WritrMetadata = { /** * The best-fit title for the document. */ title?: string; /** * Human-friendly labels for organizing the document. */ tags?: string[]; /** * Search-oriented terms related to the document. */ keywords?: string[]; /** * A concise meta-style description of the document. */ description?: string; /** * A short teaser or preview of the content. */ preview?: string; /** * A slightly longer overview of the document. */ summary?: string; /** * A broad grouping for the document such as "docs", "guide", or "blog". */ category?: string; /** * The primary subject the document is about. */ topic?: string; /** * The intended audience for the document. */ audience?: string; /** * The estimated skill level required to understand the document. */ difficulty?: "beginner" | "intermediate" | "advanced"; /** * Estimated reading time in minutes. */ readingTime?: number; /** * Total number of words in the document. */ wordCount?: number; }; /** * Search and social metadata for a markdown document. */ type WritrSEO = { /** * A URL-safe identifier for the document. */ slug?: string; /** * Open Graph metadata used by social platforms. */ openGraph?: { /** * The social sharing title for the document. */ title?: string; /** * The social sharing description for the document. */ description?: string; /** * The image URL to use when the document is shared socially. */ image?: string; }; }; /** * A valid metadata key from {@link WritrMetadata}. */ type WritrMetadataKey = keyof WritrMetadata; /** * Custom prompt templates used by WritrAI. */ type WritrAIPrompts = { /** * Custom prompt template used for metadata generation. */ metadata?: string; /** * Custom prompt template used for SEO generation. */ seo?: string; /** * Custom prompt template used for translation. */ translation?: string; }; /** * Options used to configure a {@link WritrAI} instance. */ type WritrAIOptions = { /** * The AI SDK model instance used for generation. * Example: `openai("gpt-4.1-mini")`. */ model: LanguageModel; /** * Enables the in-memory AI cache when true. */ cache?: boolean; /** * Optional prompt overrides for metadata, SEO, and translation. */ prompts?: WritrAIPrompts; }; /** * Controls which metadata fields should be generated. * When omitted, WritrAI generates all supported metadata fields. */ type WritrGetMetadataOptions = { /** * Generate a title for the document. */ title?: boolean; /** * Generate tags for the document. */ tags?: boolean; /** * Generate keywords for the document. */ keywords?: boolean; /** * Generate a meta-style description for the document. */ description?: boolean; /** * Generate a short teaser or preview for the document. */ preview?: boolean; /** * Generate a longer summary for the document. */ summary?: boolean; /** * Generate a broad category for the document. */ category?: boolean; /** * Generate the primary topic for the document. */ topic?: boolean; /** * Generate the intended audience for the document. */ audience?: boolean; /** * Generate a difficulty level for the document. */ difficulty?: boolean; /** * Include a deterministic reading time estimate. */ readingTime?: boolean; /** * Include a deterministic word count. */ wordCount?: boolean; }; /** * Controls which SEO fields should be generated. * When omitted, WritrAI generates all supported SEO fields. */ type WritrGetSEOOptions = { /** * Generate a URL-safe slug. */ slug?: boolean; /** * Generate Open Graph metadata for the document. */ openGraph?: boolean; }; /** * Options used when generating a translated document. */ type WritrTranslationOptions = { /** * The target language or locale to translate the document into. */ to: string; /** * The source language or locale of the document when known. */ from?: string; /** * When true, frontmatter string values may also be translated. */ translateFrontMatter?: boolean; }; /** * Options used when applying generated metadata to frontmatter. */ type WritrApplyMetadataOptions = { /** * Controls overwrite behavior for existing frontmatter values. * * - `true` overwrites all generated fields. * - `false` or `undefined` fills only missing fields. * - `WritrMetadataKey[]` overwrites only the specified fields. */ overwrite?: boolean | WritrMetadataKey[]; /** * Maps metadata keys to custom frontmatter field names. */ fieldMap?: Partial>; /** * Controls which metadata fields should be generated before applying them. */ generate?: WritrGetMetadataOptions; }; /** * Result returned after metadata has been applied to frontmatter. */ type WritrApplyMetadataResult = { /** * The Writr instance after metadata application. */ writr: Writr; /** * The full metadata object that was generated during this operation. */ generated: WritrMetadata; /** * Metadata fields that were newly written because they were missing. */ applied: WritrMetadataKey[]; /** * Metadata fields that replaced existing frontmatter values. */ overwritten: WritrMetadataKey[]; /** * Metadata fields that were generated but not written because * they already existed and were not allowed to be overwritten. */ skipped: WritrMetadataKey[]; }; declare class WritrCache { private readonly _store; private readonly _hashStore; private readonly _hash; get store(): CacheableMemory; get hashStore(): CacheableMemory; get(markdown: string, options?: RenderOptions): string | undefined; set(markdown: string, value: string, options?: RenderOptions): void; clear(): void; hash(markdown: string, options?: RenderOptions): string; /** * Sanitizes render options to only include serializable properties for caching. * This prevents issues with structuredClone when options contain Promises, functions, or circular references. * @param {RenderOptions} [options] The render options to sanitize * @returns {RenderOptions | undefined} A new object with only the known RenderOptions properties */ private sanitizeOptions; } declare class WritrAICache { private readonly _store; private readonly _hashStore; private readonly _hash; get store(): CacheableMemory; get hashStore(): CacheableMemory; get(key: string, context: string): T | undefined; set(key: string, context: string, value: T): void; hash(key: string, context: string): string; clear(): void; } /** * AI companion for a {@link Writr} instance. * * WritrAI provides metadata generation, SEO generation, * translation, and metadata application for markdown documents. */ declare class WritrAI { readonly writr: Writr; /** * The AI SDK model used for all generation requests. */ model: LanguageModel; /** * The prompt templates used by this WritrAI instance. */ prompts: WritrAIPrompts; /** * Optional in-memory cache for generated AI results. */ cache?: WritrAICache; /** * Creates a new WritrAI instance bound to a specific Writr document. * * @param writr - The base Writr instance this AI helper operates on. * @param options - The AI model and optional cache/prompt settings. */ constructor(writr: Writr, options: WritrAIOptions); /** * Generates metadata for the current markdown document. * * @param options - Controls which metadata fields should be generated. * @returns A metadata object for the current document. */ getMetadata(options?: WritrGetMetadataOptions): Promise; /** * Generates SEO metadata for the current markdown document. * * @param options - Controls which SEO fields should be generated. * @returns An SEO metadata object for the current document. */ getSEO(options?: WritrGetSEOOptions): Promise; /** * Generates a translated version of the current document. * * @param options - Translation settings including target locale. * @returns A new translated Writr instance. */ getTranslation(options: WritrTranslationOptions): Promise; /** * Generates metadata and applies it to the document frontmatter. * * @param options - Controls generation, overwrite behavior, and field mapping. * @returns A result object describing what metadata was generated and applied. */ applyMetadata(options?: WritrApplyMetadataOptions): Promise; private resolveMetadataFields; private resolveSEOFields; private buildMetadataSchema; private buildSEOSchema; private computeWordCount; private computeReadingTime; private stripCodeFence; } declare class Writr extends Hookified { engine: unified.Processor; private readonly _options; private _content; private readonly _cache; private _ai?; /** * Initialize Writr. Accepts a string or options object. * @param {string | WritrOptions} [arguments1] If you send in a string, it will be used as the markdown content. If you send in an object, it will be used as the options. * @param {WritrOptions} [arguments2] This is if you send in the content in the first argument and also want to send in options. * * @example * const writr = new Writr('Hello, world!', {caching: false}); */ constructor(arguments1?: string | WritrOptions, arguments2?: WritrOptions); /** * Get the options. * @type {WritrOptions} */ get options(): WritrOptions; /** * Get the WritrAI instance if AI options were provided. * @type {WritrAI | undefined} */ get ai(): WritrAI | undefined; /** * Get the Content. This is the markdown content and front matter if it exists. * @type {WritrOptions} */ get content(): string; /** * Set the Content. This is the markdown content and front matter if it exists. * @type {WritrOptions} */ set content(value: string); /** * Get the cache. * @type {WritrCache} */ get cache(): WritrCache; /** * Get the front matter raw content. * @type {string} The front matter content including the delimiters. */ get frontMatterRaw(): string; /** * Get the body content without the front matter. * @type {string} The markdown content without the front matter. */ get body(): string; /** * Get the markdown content. This is an alias for the body property. * @type {string} The markdown content. */ get markdown(): string; /** * Get the front matter content as an object. * @type {Record} The front matter content as an object. */ get frontMatter(): Record; /** * Set the front matter content as an object. * @type {Record} The front matter content as an object. */ set frontMatter(data: Record); /** * Get the front matter value for a key. * @param {string} key The key to get the value for. * @returns {T} The value for the key. */ getFrontMatterValue(key: string): T; /** * Render the markdown content to HTML. * @param {RenderOptions} [options] The render options. * @returns {Promise} The rendered HTML content. */ render(options?: RenderOptions): Promise; /** * Render the markdown content to HTML synchronously. * @param {RenderOptions} [options] The render options. * @returns {string} The rendered HTML content. */ renderSync(options?: RenderOptions): string; /** * Validate the markdown content by attempting to render it. * @param {string} [content] The markdown content to validate. If not provided, uses the current content. * @param {RenderOptions} [options] The render options. * @returns {Promise} An object with a valid boolean and optional error. */ validate(content?: string, options?: RenderOptions): Promise; /** * Validate the markdown content by attempting to render it synchronously. * @param {string} [content] The markdown content to validate. If not provided, uses the current content. * @param {RenderOptions} [options] The render options. * @returns {WritrValidateResult} An object with a valid boolean and optional error. */ validateSync(content?: string, options?: RenderOptions): WritrValidateResult; /** * Render the markdown content and save it to a file. If the directory doesn't exist it will be created. * @param {string} filePath The file path to save the rendered markdown content to. * @param {RenderOptions} [options] the render options. */ renderToFile(filePath: string, options?: RenderOptions): Promise; /** * Render the markdown content and save it to a file synchronously. If the directory doesn't exist it will be created. * @param {string} filePath The file path to save the rendered markdown content to. * @param {RenderOptions} [options] the render options. */ renderToFileSync(filePath: string, options?: RenderOptions): void; /** * Render the markdown content to React. * @param {RenderOptions} [options] The render options. * @param {HTMLReactParserOptions} [reactParseOptions] The HTML React parser options. * @returns {Promise} The rendered React content. */ renderReact(options?: RenderOptions, reactParseOptions?: HTMLReactParserOptions): Promise; /** * Render the markdown content to React synchronously. * @param {RenderOptions} [options] The render options. * @param {HTMLReactParserOptions} [reactParseOptions] The HTML React parser options. * @returns {string | React.JSX.Element | React.JSX.Element[]} The rendered React content. */ renderReactSync(options?: RenderOptions, reactParseOptions?: HTMLReactParserOptions): string | React.JSX.Element | React.JSX.Element[]; /** * Load markdown content from a file. * @param {string} filePath The file path to load the markdown content from. * @returns {Promise} */ loadFromFile(filePath: string): Promise; /** * Load markdown content from a file synchronously. * @param {string} filePath The file path to load the markdown content from. * @returns {void} */ loadFromFileSync(filePath: string): void; /** * Save the markdown content to a file. If the directory doesn't exist it will be created. * @param {string} filePath The file path to save the markdown content to. * @returns {Promise} */ saveToFile(filePath: string): Promise; /** * Save the markdown content to a file synchronously. If the directory doesn't exist it will be created. * @param {string} filePath The file path to save the markdown content to. * @returns {void} */ saveToFileSync(filePath: string): void; mergeOptions(current: WritrOptions, options: WritrOptions): WritrOptions; private isCacheEnabled; private createProcessor; private mergeRenderOptions; } export { type RenderOptions, Writr, WritrAI, WritrAICache, type WritrAIOptions, type WritrAIPrompts, type WritrApplyMetadataOptions, type WritrApplyMetadataResult, type WritrGetMetadataOptions, type WritrGetSEOOptions, WritrHooks, type WritrMetadata, type WritrMetadataKey, type WritrOptions, type WritrSEO, type WritrTranslationOptions, type WritrValidateResult };