writr 6.1.1 → 6.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +50 -0
- package/dist/writr.d.mts +592 -0
- package/dist/writr.mjs +848 -0
- package/package.json +35 -30
- package/dist/writr.d.ts +0 -559
- package/dist/writr.js +0 -1031
package/README.md
CHANGED
|
@@ -67,6 +67,7 @@
|
|
|
67
67
|
- [AI Provider Configuration](#ai-provider-configuration)
|
|
68
68
|
- [Metadata](#metadata)
|
|
69
69
|
- [Generating Metadata](#generating-metadata)
|
|
70
|
+
- [Constraining Generated Values](#constraining-generated-values)
|
|
70
71
|
- [Applying Metadata to Frontmatter](#applying-metadata-to-frontmatter)
|
|
71
72
|
- [Overwrite](#overwrite)
|
|
72
73
|
- [Field Mapping](#field-mapping)
|
|
@@ -867,6 +868,55 @@ const partial = await writr.ai.getMetadata({
|
|
|
867
868
|
| `readingTime` | `number` | Estimated reading time in minutes (computed, not AI-generated). |
|
|
868
869
|
| `wordCount` | `number` | Total word count of the document (computed, not AI-generated). |
|
|
869
870
|
|
|
871
|
+
### Constraining Generated Values
|
|
872
|
+
|
|
873
|
+
When you have a controlled vocabulary — for example a CMS taxonomy, a fixed set of categories, or an SEO keyword list — pass `allowedTags`, `allowedKeywords`, or `allowedCategories` and the AI will pick only from that list. When omitted, the AI generates freely.
|
|
874
|
+
|
|
875
|
+
```typescript
|
|
876
|
+
const metadata = await writr.ai.getMetadata({
|
|
877
|
+
allowedTags: ['javascript', 'typescript', 'python', 'rust'],
|
|
878
|
+
allowedKeywords: ['async', 'promises', 'callbacks'],
|
|
879
|
+
allowedCategories: ['tutorial', 'guide', 'reference', 'blog'],
|
|
880
|
+
});
|
|
881
|
+
|
|
882
|
+
// metadata.tags is guaranteed to be a subset of allowedTags
|
|
883
|
+
// metadata.category is guaranteed to be one of allowedCategories
|
|
884
|
+
```
|
|
885
|
+
|
|
886
|
+
| Option | Type | Description |
|
|
887
|
+
|--------|------|-------------|
|
|
888
|
+
| `allowedTags` | `string[]` | Constrains AI-generated tags to this list. A non-empty array implicitly enables `tags`. |
|
|
889
|
+
| `allowedKeywords` | `string[]` | Constrains AI-generated keywords to this list. A non-empty array implicitly enables `keywords`. |
|
|
890
|
+
| `allowedCategories` | `string[]` | Constrains AI-generated category to one of these values. A non-empty array implicitly enables `category`. |
|
|
891
|
+
|
|
892
|
+
**How the constraint is enforced**
|
|
893
|
+
|
|
894
|
+
The constraint is applied on three reinforcing layers, so the model both *knows about* and is *prevented from violating* the list:
|
|
895
|
+
|
|
896
|
+
1. **Schema enforcement (the hard guarantee).** The Zod response schema uses `z.array(z.enum(allowedTags))` for tags, `z.array(z.enum(allowedKeywords))` for keywords, and `z.enum(allowedCategories)` for category. The AI SDK's structured-output mode forces the model to return values from the enum — it literally cannot produce anything outside the list.
|
|
897
|
+
2. **Prompt instruction.** A `Constraints:` block is appended to the prompt with lines like `Tags must be selected from: foo, bar, baz` and `Category must be one of: tutorial, guide, reference`, so the model also sees the list in natural language.
|
|
898
|
+
3. **Schema field description.** The Zod field description is rewritten to inline the allowed values (e.g. `Human-friendly labels selected from: foo, bar, baz`), which most providers surface to the model alongside the schema.
|
|
899
|
+
|
|
900
|
+
**Behavior notes**
|
|
901
|
+
|
|
902
|
+
- Providing a **non-empty** `allowed*` array implicitly enables the corresponding field — you don't also need `tags: true`.
|
|
903
|
+
- Setting the field explicitly to `false` disables it even when an `allowed*` list is provided.
|
|
904
|
+
- An **empty** array (`allowedTags: []`) does **not** implicitly enable the field. If you want unconstrained generation, either omit the option or pair the empty array with the explicit flag (e.g. `{ tags: true, allowedTags: [] }`) — `z.enum` requires at least one value, so the empty-array path uses `z.string()` and drops the prompt constraint.
|
|
905
|
+
- These also work via `applyMetadata({ generate: { allowedTags: [...] } })`.
|
|
906
|
+
|
|
907
|
+
```typescript
|
|
908
|
+
// Implicit enablement: tags is generated, even without `tags: true`
|
|
909
|
+
const metadata = await writr.ai.getMetadata({
|
|
910
|
+
allowedTags: ['docs', 'guide', 'blog'],
|
|
911
|
+
});
|
|
912
|
+
|
|
913
|
+
// Explicit `false` wins: tags is not generated
|
|
914
|
+
const metadata = await writr.ai.getMetadata({
|
|
915
|
+
tags: false,
|
|
916
|
+
allowedTags: ['docs', 'guide', 'blog'],
|
|
917
|
+
});
|
|
918
|
+
```
|
|
919
|
+
|
|
870
920
|
### Applying Metadata to Frontmatter
|
|
871
921
|
|
|
872
922
|
`applyMetadata()` generates metadata and writes it into the document's frontmatter. The result tells you exactly what happened:
|
package/dist/writr.d.mts
ADDED
|
@@ -0,0 +1,592 @@
|
|
|
1
|
+
import { Hookified, HookifiedOptions } from "hookified";
|
|
2
|
+
import { HTMLReactParserOptions } from "html-react-parser";
|
|
3
|
+
import { Processor } from "unified";
|
|
4
|
+
import { CacheableMemory } from "cacheable";
|
|
5
|
+
import { LanguageModel } from "ai";
|
|
6
|
+
import React from "react";
|
|
7
|
+
|
|
8
|
+
//#region src/types.d.ts
|
|
9
|
+
/**
|
|
10
|
+
* Writr options.
|
|
11
|
+
* @typedef {Object} WritrOptions
|
|
12
|
+
* @property {RenderOptions} [renderOptions] - Default render options (default: undefined)
|
|
13
|
+
*/
|
|
14
|
+
type WritrOptions = {
|
|
15
|
+
renderOptions?: RenderOptions;
|
|
16
|
+
ai?: WritrAIOptions;
|
|
17
|
+
} & HookifiedOptions;
|
|
18
|
+
/**
|
|
19
|
+
* Render options.
|
|
20
|
+
* @typedef {Object} RenderOptions
|
|
21
|
+
* @property {boolean} [emoji] - Emoji support (default: true)
|
|
22
|
+
* @property {boolean} [toc] - Table of contents generation (default: true)
|
|
23
|
+
* @property {boolean} [slug] - Slug generation (default: true)
|
|
24
|
+
* @property {boolean} [highlight] - Code highlighting (default: true)
|
|
25
|
+
* @property {boolean} [gfm] - Github flavor markdown (default: true)
|
|
26
|
+
* @property {boolean} [math] - Math support (default: true)
|
|
27
|
+
* @property {boolean} [mdx] - MDX support (default: false)
|
|
28
|
+
* @property {boolean} [rawHtml] - Raw HTML passthrough (default: false)
|
|
29
|
+
* @property {boolean} [caching] - Caching (default: true)
|
|
30
|
+
*/
|
|
31
|
+
type RenderOptions = {
|
|
32
|
+
emoji?: boolean;
|
|
33
|
+
toc?: boolean;
|
|
34
|
+
slug?: boolean;
|
|
35
|
+
highlight?: boolean;
|
|
36
|
+
gfm?: boolean;
|
|
37
|
+
math?: boolean;
|
|
38
|
+
mdx?: boolean;
|
|
39
|
+
rawHtml?: boolean;
|
|
40
|
+
caching?: boolean;
|
|
41
|
+
};
|
|
42
|
+
/**
|
|
43
|
+
* Validation result.
|
|
44
|
+
* @typedef {Object} WritrValidateResult
|
|
45
|
+
* @property {boolean} valid - Whether the markdown is valid
|
|
46
|
+
* @property {Error} [error] - Error if validation failed
|
|
47
|
+
*/
|
|
48
|
+
type WritrValidateResult = {
|
|
49
|
+
valid: boolean;
|
|
50
|
+
error?: Error;
|
|
51
|
+
};
|
|
52
|
+
declare enum WritrHooks {
|
|
53
|
+
beforeRender = "beforeRender",
|
|
54
|
+
afterRender = "afterRender",
|
|
55
|
+
saveToFile = "saveToFile",
|
|
56
|
+
renderToFile = "renderToFile",
|
|
57
|
+
loadFromFile = "loadFromFile"
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Metadata generated for a markdown document.
|
|
61
|
+
*/
|
|
62
|
+
type WritrMetadata = {
|
|
63
|
+
/**
|
|
64
|
+
* The best-fit title for the document.
|
|
65
|
+
*/
|
|
66
|
+
title?: string;
|
|
67
|
+
/**
|
|
68
|
+
* Human-friendly labels for organizing the document.
|
|
69
|
+
*/
|
|
70
|
+
tags?: string[];
|
|
71
|
+
/**
|
|
72
|
+
* Search-oriented terms related to the document.
|
|
73
|
+
*/
|
|
74
|
+
keywords?: string[];
|
|
75
|
+
/**
|
|
76
|
+
* A concise meta-style description of the document.
|
|
77
|
+
*/
|
|
78
|
+
description?: string;
|
|
79
|
+
/**
|
|
80
|
+
* A short teaser or preview of the content.
|
|
81
|
+
*/
|
|
82
|
+
preview?: string;
|
|
83
|
+
/**
|
|
84
|
+
* A slightly longer overview of the document.
|
|
85
|
+
*/
|
|
86
|
+
summary?: string;
|
|
87
|
+
/**
|
|
88
|
+
* A broad grouping for the document such as "docs", "guide", or "blog".
|
|
89
|
+
*/
|
|
90
|
+
category?: string;
|
|
91
|
+
/**
|
|
92
|
+
* The primary subject the document is about.
|
|
93
|
+
*/
|
|
94
|
+
topic?: string;
|
|
95
|
+
/**
|
|
96
|
+
* The intended audience for the document.
|
|
97
|
+
*/
|
|
98
|
+
audience?: string;
|
|
99
|
+
/**
|
|
100
|
+
* The estimated skill level required to understand the document.
|
|
101
|
+
*/
|
|
102
|
+
difficulty?: "beginner" | "intermediate" | "advanced";
|
|
103
|
+
/**
|
|
104
|
+
* Estimated reading time in minutes.
|
|
105
|
+
*/
|
|
106
|
+
readingTime?: number;
|
|
107
|
+
/**
|
|
108
|
+
* Total number of words in the document.
|
|
109
|
+
*/
|
|
110
|
+
wordCount?: number;
|
|
111
|
+
};
|
|
112
|
+
/**
|
|
113
|
+
* Search and social metadata for a markdown document.
|
|
114
|
+
*/
|
|
115
|
+
type WritrSEO = {
|
|
116
|
+
/**
|
|
117
|
+
* A URL-safe identifier for the document.
|
|
118
|
+
*/
|
|
119
|
+
slug?: string;
|
|
120
|
+
/**
|
|
121
|
+
* Open Graph metadata used by social platforms.
|
|
122
|
+
*/
|
|
123
|
+
openGraph?: {
|
|
124
|
+
/**
|
|
125
|
+
* The social sharing title for the document.
|
|
126
|
+
*/
|
|
127
|
+
title?: string;
|
|
128
|
+
/**
|
|
129
|
+
* The social sharing description for the document.
|
|
130
|
+
*/
|
|
131
|
+
description?: string;
|
|
132
|
+
/**
|
|
133
|
+
* The image URL to use when the document is shared socially.
|
|
134
|
+
*/
|
|
135
|
+
image?: string;
|
|
136
|
+
};
|
|
137
|
+
};
|
|
138
|
+
/**
|
|
139
|
+
* A valid metadata key from {@link WritrMetadata}.
|
|
140
|
+
*/
|
|
141
|
+
type WritrMetadataKey = keyof WritrMetadata;
|
|
142
|
+
/**
|
|
143
|
+
* Custom prompt templates used by WritrAI.
|
|
144
|
+
*/
|
|
145
|
+
type WritrAIPrompts = {
|
|
146
|
+
/**
|
|
147
|
+
* Custom prompt template used for metadata generation.
|
|
148
|
+
*/
|
|
149
|
+
metadata?: string;
|
|
150
|
+
/**
|
|
151
|
+
* Custom prompt template used for SEO generation.
|
|
152
|
+
*/
|
|
153
|
+
seo?: string;
|
|
154
|
+
/**
|
|
155
|
+
* Custom prompt template used for translation.
|
|
156
|
+
*/
|
|
157
|
+
translation?: string;
|
|
158
|
+
};
|
|
159
|
+
/**
|
|
160
|
+
* Options used to configure a {@link WritrAI} instance.
|
|
161
|
+
*/
|
|
162
|
+
type WritrAIOptions = {
|
|
163
|
+
/**
|
|
164
|
+
* The AI SDK model instance used for generation.
|
|
165
|
+
* Example: `openai("gpt-4.1-mini")`.
|
|
166
|
+
*/
|
|
167
|
+
model: LanguageModel;
|
|
168
|
+
/**
|
|
169
|
+
* Enables the in-memory AI cache when true.
|
|
170
|
+
*/
|
|
171
|
+
cache?: boolean;
|
|
172
|
+
/**
|
|
173
|
+
* Optional prompt overrides for metadata, SEO, and translation.
|
|
174
|
+
*/
|
|
175
|
+
prompts?: WritrAIPrompts;
|
|
176
|
+
};
|
|
177
|
+
/**
|
|
178
|
+
* Controls which metadata fields should be generated.
|
|
179
|
+
* When omitted, WritrAI generates all supported metadata fields.
|
|
180
|
+
*/
|
|
181
|
+
type WritrGetMetadataOptions = {
|
|
182
|
+
/**
|
|
183
|
+
* Generate a title for the document.
|
|
184
|
+
*/
|
|
185
|
+
title?: boolean;
|
|
186
|
+
/**
|
|
187
|
+
* Generate tags for the document.
|
|
188
|
+
*/
|
|
189
|
+
tags?: boolean;
|
|
190
|
+
/**
|
|
191
|
+
* Generate keywords for the document.
|
|
192
|
+
*/
|
|
193
|
+
keywords?: boolean;
|
|
194
|
+
/**
|
|
195
|
+
* Generate a meta-style description for the document.
|
|
196
|
+
*/
|
|
197
|
+
description?: boolean;
|
|
198
|
+
/**
|
|
199
|
+
* Generate a short teaser or preview for the document.
|
|
200
|
+
*/
|
|
201
|
+
preview?: boolean;
|
|
202
|
+
/**
|
|
203
|
+
* Generate a longer summary for the document.
|
|
204
|
+
*/
|
|
205
|
+
summary?: boolean;
|
|
206
|
+
/**
|
|
207
|
+
* Generate a broad category for the document.
|
|
208
|
+
*/
|
|
209
|
+
category?: boolean;
|
|
210
|
+
/**
|
|
211
|
+
* Generate the primary topic for the document.
|
|
212
|
+
*/
|
|
213
|
+
topic?: boolean;
|
|
214
|
+
/**
|
|
215
|
+
* Generate the intended audience for the document.
|
|
216
|
+
*/
|
|
217
|
+
audience?: boolean;
|
|
218
|
+
/**
|
|
219
|
+
* Generate a difficulty level for the document.
|
|
220
|
+
*/
|
|
221
|
+
difficulty?: boolean;
|
|
222
|
+
/**
|
|
223
|
+
* Include a deterministic reading time estimate.
|
|
224
|
+
*/
|
|
225
|
+
readingTime?: boolean;
|
|
226
|
+
/**
|
|
227
|
+
* Include a deterministic word count.
|
|
228
|
+
*/
|
|
229
|
+
wordCount?: boolean;
|
|
230
|
+
/**
|
|
231
|
+
* When provided, constrains AI-generated tags to only values from this list.
|
|
232
|
+
* Has no effect when `tags` is explicitly `false`.
|
|
233
|
+
*/
|
|
234
|
+
allowedTags?: string[];
|
|
235
|
+
/**
|
|
236
|
+
* When provided, constrains AI-generated keywords to only values from this list.
|
|
237
|
+
* Has no effect when `keywords` is explicitly `false`.
|
|
238
|
+
*/
|
|
239
|
+
allowedKeywords?: string[];
|
|
240
|
+
/**
|
|
241
|
+
* When provided, constrains the AI-generated category to only values from this list.
|
|
242
|
+
* Has no effect when `category` is explicitly `false`.
|
|
243
|
+
*/
|
|
244
|
+
allowedCategories?: string[];
|
|
245
|
+
};
|
|
246
|
+
/**
|
|
247
|
+
* Controls which SEO fields should be generated.
|
|
248
|
+
* When omitted, WritrAI generates all supported SEO fields.
|
|
249
|
+
*/
|
|
250
|
+
type WritrGetSEOOptions = {
|
|
251
|
+
/**
|
|
252
|
+
* Generate a URL-safe slug.
|
|
253
|
+
*/
|
|
254
|
+
slug?: boolean;
|
|
255
|
+
/**
|
|
256
|
+
* Generate Open Graph metadata for the document.
|
|
257
|
+
*/
|
|
258
|
+
openGraph?: boolean;
|
|
259
|
+
};
|
|
260
|
+
/**
|
|
261
|
+
* Options used when generating a translated document.
|
|
262
|
+
*/
|
|
263
|
+
type WritrTranslationOptions = {
|
|
264
|
+
/**
|
|
265
|
+
* The target language or locale to translate the document into.
|
|
266
|
+
*/
|
|
267
|
+
to: string;
|
|
268
|
+
/**
|
|
269
|
+
* The source language or locale of the document when known.
|
|
270
|
+
*/
|
|
271
|
+
from?: string;
|
|
272
|
+
/**
|
|
273
|
+
* When true, frontmatter string values may also be translated.
|
|
274
|
+
*/
|
|
275
|
+
translateFrontMatter?: boolean;
|
|
276
|
+
};
|
|
277
|
+
/**
|
|
278
|
+
* Options used when applying generated metadata to frontmatter.
|
|
279
|
+
*/
|
|
280
|
+
type WritrApplyMetadataOptions = {
|
|
281
|
+
/**
|
|
282
|
+
* Controls overwrite behavior for existing frontmatter values.
|
|
283
|
+
*
|
|
284
|
+
* - `true` overwrites all generated fields.
|
|
285
|
+
* - `false` or `undefined` fills only missing fields.
|
|
286
|
+
* - `WritrMetadataKey[]` overwrites only the specified fields.
|
|
287
|
+
*/
|
|
288
|
+
overwrite?: boolean | WritrMetadataKey[];
|
|
289
|
+
/**
|
|
290
|
+
* Maps metadata keys to custom frontmatter field names.
|
|
291
|
+
*/
|
|
292
|
+
fieldMap?: Partial<Record<WritrMetadataKey, string>>;
|
|
293
|
+
/**
|
|
294
|
+
* Controls which metadata fields should be generated before applying them.
|
|
295
|
+
*/
|
|
296
|
+
generate?: WritrGetMetadataOptions;
|
|
297
|
+
};
|
|
298
|
+
/**
|
|
299
|
+
* Result returned after metadata has been applied to frontmatter.
|
|
300
|
+
*/
|
|
301
|
+
type WritrApplyMetadataResult = {
|
|
302
|
+
/**
|
|
303
|
+
* The Writr instance after metadata application.
|
|
304
|
+
*/
|
|
305
|
+
writr: Writr;
|
|
306
|
+
/**
|
|
307
|
+
* The full metadata object that was generated during this operation.
|
|
308
|
+
*/
|
|
309
|
+
generated: WritrMetadata;
|
|
310
|
+
/**
|
|
311
|
+
* Metadata fields that were newly written because they were missing.
|
|
312
|
+
*/
|
|
313
|
+
applied: WritrMetadataKey[];
|
|
314
|
+
/**
|
|
315
|
+
* Metadata fields that replaced existing frontmatter values.
|
|
316
|
+
*/
|
|
317
|
+
overwritten: WritrMetadataKey[];
|
|
318
|
+
/**
|
|
319
|
+
* Metadata fields that were generated but not written because
|
|
320
|
+
* they already existed and were not allowed to be overwritten.
|
|
321
|
+
*/
|
|
322
|
+
skipped: WritrMetadataKey[];
|
|
323
|
+
};
|
|
324
|
+
//#endregion
|
|
325
|
+
//#region src/writr-cache.d.ts
|
|
326
|
+
declare class WritrCache {
|
|
327
|
+
private readonly _store;
|
|
328
|
+
private readonly _hashStore;
|
|
329
|
+
private readonly _hash;
|
|
330
|
+
get store(): CacheableMemory;
|
|
331
|
+
get hashStore(): CacheableMemory;
|
|
332
|
+
get(markdown: string, options?: RenderOptions): string | undefined;
|
|
333
|
+
set(markdown: string, value: string, options?: RenderOptions): void;
|
|
334
|
+
clear(): void;
|
|
335
|
+
hash(markdown: string, options?: RenderOptions): string;
|
|
336
|
+
/**
|
|
337
|
+
* Sanitizes render options to only include serializable properties for caching.
|
|
338
|
+
* This prevents issues with structuredClone when options contain Promises, functions, or circular references.
|
|
339
|
+
* @param {RenderOptions} [options] The render options to sanitize
|
|
340
|
+
* @returns {RenderOptions | undefined} A new object with only the known RenderOptions properties
|
|
341
|
+
*/
|
|
342
|
+
private sanitizeOptions;
|
|
343
|
+
}
|
|
344
|
+
//#endregion
|
|
345
|
+
//#region src/writr-ai-cache.d.ts
|
|
346
|
+
declare class WritrAICache {
|
|
347
|
+
private readonly _store;
|
|
348
|
+
private readonly _hashStore;
|
|
349
|
+
private readonly _hash;
|
|
350
|
+
get store(): CacheableMemory;
|
|
351
|
+
get hashStore(): CacheableMemory;
|
|
352
|
+
get<T>(key: string, context: string): T | undefined;
|
|
353
|
+
set<T>(key: string, context: string, value: T): void;
|
|
354
|
+
hash(key: string, context: string): string;
|
|
355
|
+
clear(): void;
|
|
356
|
+
}
|
|
357
|
+
//#endregion
|
|
358
|
+
//#region src/writr-ai.d.ts
|
|
359
|
+
/**
|
|
360
|
+
* AI companion for a {@link Writr} instance.
|
|
361
|
+
*
|
|
362
|
+
* WritrAI provides metadata generation, SEO generation,
|
|
363
|
+
* translation, and metadata application for markdown documents.
|
|
364
|
+
*/
|
|
365
|
+
declare class WritrAI {
|
|
366
|
+
readonly writr: Writr;
|
|
367
|
+
/**
|
|
368
|
+
* The AI SDK model used for all generation requests.
|
|
369
|
+
*/
|
|
370
|
+
model: LanguageModel;
|
|
371
|
+
/**
|
|
372
|
+
* The prompt templates used by this WritrAI instance.
|
|
373
|
+
*/
|
|
374
|
+
prompts: WritrAIPrompts;
|
|
375
|
+
/**
|
|
376
|
+
* Optional in-memory cache for generated AI results.
|
|
377
|
+
*/
|
|
378
|
+
cache?: WritrAICache;
|
|
379
|
+
/**
|
|
380
|
+
* Creates a new WritrAI instance bound to a specific Writr document.
|
|
381
|
+
*
|
|
382
|
+
* @param writr - The base Writr instance this AI helper operates on.
|
|
383
|
+
* @param options - The AI model and optional cache/prompt settings.
|
|
384
|
+
*/
|
|
385
|
+
constructor(writr: Writr, options: WritrAIOptions);
|
|
386
|
+
/**
|
|
387
|
+
* Generates metadata for the current markdown document.
|
|
388
|
+
*
|
|
389
|
+
* Pass `allowedTags`, `allowedKeywords`, or `allowedCategories` to constrain the
|
|
390
|
+
* AI to a controlled vocabulary — values are enforced via a Zod response schema
|
|
391
|
+
* (`z.array(z.enum(...))` for tags/keywords, `z.enum(...)` for category) so the
|
|
392
|
+
* model cannot return anything outside the list. Providing a non-empty `allowed*`
|
|
393
|
+
* array also implicitly enables its corresponding field.
|
|
394
|
+
*
|
|
395
|
+
* @param options - Controls which metadata fields should be generated.
|
|
396
|
+
* @returns A metadata object for the current document.
|
|
397
|
+
*
|
|
398
|
+
* @example
|
|
399
|
+
* ```typescript
|
|
400
|
+
* const metadata = await writr.ai.getMetadata({
|
|
401
|
+
* allowedTags: ['javascript', 'typescript', 'python'],
|
|
402
|
+
* allowedCategories: ['tutorial', 'guide', 'blog'],
|
|
403
|
+
* });
|
|
404
|
+
* // metadata.tags ⊆ allowedTags, metadata.category ∈ allowedCategories
|
|
405
|
+
* ```
|
|
406
|
+
*/
|
|
407
|
+
getMetadata(options?: WritrGetMetadataOptions): Promise<WritrMetadata>;
|
|
408
|
+
/**
|
|
409
|
+
* Generates SEO metadata for the current markdown document.
|
|
410
|
+
*
|
|
411
|
+
* @param options - Controls which SEO fields should be generated.
|
|
412
|
+
* @returns An SEO metadata object for the current document.
|
|
413
|
+
*/
|
|
414
|
+
getSEO(options?: WritrGetSEOOptions): Promise<WritrSEO>;
|
|
415
|
+
/**
|
|
416
|
+
* Generates a translated version of the current document.
|
|
417
|
+
*
|
|
418
|
+
* @param options - Translation settings including target locale.
|
|
419
|
+
* @returns A new translated Writr instance.
|
|
420
|
+
*/
|
|
421
|
+
getTranslation(options: WritrTranslationOptions): Promise<Writr>;
|
|
422
|
+
/**
|
|
423
|
+
* Generates metadata and applies it to the document frontmatter.
|
|
424
|
+
*
|
|
425
|
+
* @param options - Controls generation, overwrite behavior, and field mapping.
|
|
426
|
+
* @returns A result object describing what metadata was generated and applied.
|
|
427
|
+
*/
|
|
428
|
+
applyMetadata(options?: WritrApplyMetadataOptions): Promise<WritrApplyMetadataResult>;
|
|
429
|
+
private resolveMetadataFields;
|
|
430
|
+
private resolveSEOFields;
|
|
431
|
+
private buildMetadataSchema;
|
|
432
|
+
private buildSEOSchema;
|
|
433
|
+
private computeWordCount;
|
|
434
|
+
private computeReadingTime;
|
|
435
|
+
private stripCodeFence;
|
|
436
|
+
}
|
|
437
|
+
//#endregion
|
|
438
|
+
//#region src/writr.d.ts
|
|
439
|
+
declare class Writr extends Hookified {
|
|
440
|
+
engine: Processor<any, any, any, any, any>;
|
|
441
|
+
private readonly _options;
|
|
442
|
+
private _content;
|
|
443
|
+
private readonly _cache;
|
|
444
|
+
private _ai?;
|
|
445
|
+
/**
|
|
446
|
+
* Initialize Writr. Accepts a string or options object.
|
|
447
|
+
* @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.
|
|
448
|
+
* @param {WritrOptions} [arguments2] This is if you send in the content in the first argument and also want to send in options.
|
|
449
|
+
*
|
|
450
|
+
* @example
|
|
451
|
+
* const writr = new Writr('Hello, world!', {caching: false});
|
|
452
|
+
*/
|
|
453
|
+
constructor(arguments1?: string | WritrOptions, arguments2?: WritrOptions);
|
|
454
|
+
/**
|
|
455
|
+
* Get the options.
|
|
456
|
+
* @type {WritrOptions}
|
|
457
|
+
*/
|
|
458
|
+
get options(): WritrOptions;
|
|
459
|
+
/**
|
|
460
|
+
* Get the WritrAI instance if AI options were provided.
|
|
461
|
+
* @type {WritrAI | undefined}
|
|
462
|
+
*/
|
|
463
|
+
get ai(): WritrAI | undefined;
|
|
464
|
+
/**
|
|
465
|
+
* Get the Content. This is the markdown content and front matter if it exists.
|
|
466
|
+
* @type {WritrOptions}
|
|
467
|
+
*/
|
|
468
|
+
get content(): string;
|
|
469
|
+
/**
|
|
470
|
+
* Set the Content. This is the markdown content and front matter if it exists.
|
|
471
|
+
* @type {WritrOptions}
|
|
472
|
+
*/
|
|
473
|
+
set content(value: string);
|
|
474
|
+
/**
|
|
475
|
+
* Get the cache.
|
|
476
|
+
* @type {WritrCache}
|
|
477
|
+
*/
|
|
478
|
+
get cache(): WritrCache;
|
|
479
|
+
/**
|
|
480
|
+
* Get the front matter raw content.
|
|
481
|
+
* @type {string} The front matter content including the delimiters.
|
|
482
|
+
*/
|
|
483
|
+
get frontMatterRaw(): string;
|
|
484
|
+
/**
|
|
485
|
+
* Get the body content without the front matter.
|
|
486
|
+
* @type {string} The markdown content without the front matter.
|
|
487
|
+
*/
|
|
488
|
+
get body(): string;
|
|
489
|
+
/**
|
|
490
|
+
* Get the markdown content. This is an alias for the body property.
|
|
491
|
+
* @type {string} The markdown content.
|
|
492
|
+
*/
|
|
493
|
+
get markdown(): string;
|
|
494
|
+
/**
|
|
495
|
+
* Get the front matter content as an object.
|
|
496
|
+
* @type {Record<string, any>} The front matter content as an object.
|
|
497
|
+
*/
|
|
498
|
+
get frontMatter(): Record<string, any>;
|
|
499
|
+
/**
|
|
500
|
+
* Set the front matter content as an object.
|
|
501
|
+
* @type {Record<string, any>} The front matter content as an object.
|
|
502
|
+
*/
|
|
503
|
+
set frontMatter(data: Record<string, any>);
|
|
504
|
+
/**
|
|
505
|
+
* Get the front matter value for a key.
|
|
506
|
+
* @param {string} key The key to get the value for.
|
|
507
|
+
* @returns {T} The value for the key.
|
|
508
|
+
*/
|
|
509
|
+
getFrontMatterValue<T>(key: string): T;
|
|
510
|
+
/**
|
|
511
|
+
* Render the markdown content to HTML.
|
|
512
|
+
* @param {RenderOptions} [options] The render options.
|
|
513
|
+
* @returns {Promise<string>} The rendered HTML content.
|
|
514
|
+
*/
|
|
515
|
+
render(options?: RenderOptions): Promise<string>;
|
|
516
|
+
/**
|
|
517
|
+
* Render the markdown content to HTML synchronously.
|
|
518
|
+
* @param {RenderOptions} [options] The render options.
|
|
519
|
+
* @returns {string} The rendered HTML content.
|
|
520
|
+
*/
|
|
521
|
+
renderSync(options?: RenderOptions): string;
|
|
522
|
+
/**
|
|
523
|
+
* Validate the markdown content by attempting to render it.
|
|
524
|
+
* @param {string} [content] The markdown content to validate. If not provided, uses the current content.
|
|
525
|
+
* @param {RenderOptions} [options] The render options.
|
|
526
|
+
* @returns {Promise<WritrValidateResult>} An object with a valid boolean and optional error.
|
|
527
|
+
*/
|
|
528
|
+
validate(content?: string, options?: RenderOptions): Promise<WritrValidateResult>;
|
|
529
|
+
/**
|
|
530
|
+
* Validate the markdown content by attempting to render it synchronously.
|
|
531
|
+
* @param {string} [content] The markdown content to validate. If not provided, uses the current content.
|
|
532
|
+
* @param {RenderOptions} [options] The render options.
|
|
533
|
+
* @returns {WritrValidateResult} An object with a valid boolean and optional error.
|
|
534
|
+
*/
|
|
535
|
+
validateSync(content?: string, options?: RenderOptions): WritrValidateResult;
|
|
536
|
+
/**
|
|
537
|
+
* Render the markdown content and save it to a file. If the directory doesn't exist it will be created.
|
|
538
|
+
* @param {string} filePath The file path to save the rendered markdown content to.
|
|
539
|
+
* @param {RenderOptions} [options] the render options.
|
|
540
|
+
*/
|
|
541
|
+
renderToFile(filePath: string, options?: RenderOptions): Promise<void>;
|
|
542
|
+
/**
|
|
543
|
+
* Render the markdown content and save it to a file synchronously. If the directory doesn't exist it will be created.
|
|
544
|
+
* @param {string} filePath The file path to save the rendered markdown content to.
|
|
545
|
+
* @param {RenderOptions} [options] the render options.
|
|
546
|
+
*/
|
|
547
|
+
renderToFileSync(filePath: string, options?: RenderOptions): void;
|
|
548
|
+
/**
|
|
549
|
+
* Render the markdown content to React.
|
|
550
|
+
* @param {RenderOptions} [options] The render options.
|
|
551
|
+
* @param {HTMLReactParserOptions} [reactParseOptions] The HTML React parser options.
|
|
552
|
+
* @returns {Promise<string | React.JSX.Element | React.JSX.Element[]>} The rendered React content.
|
|
553
|
+
*/
|
|
554
|
+
renderReact(options?: RenderOptions, reactParseOptions?: HTMLReactParserOptions): Promise<string | React.JSX.Element | React.JSX.Element[]>;
|
|
555
|
+
/**
|
|
556
|
+
* Render the markdown content to React synchronously.
|
|
557
|
+
* @param {RenderOptions} [options] The render options.
|
|
558
|
+
* @param {HTMLReactParserOptions} [reactParseOptions] The HTML React parser options.
|
|
559
|
+
* @returns {string | React.JSX.Element | React.JSX.Element[]} The rendered React content.
|
|
560
|
+
*/
|
|
561
|
+
renderReactSync(options?: RenderOptions, reactParseOptions?: HTMLReactParserOptions): string | React.JSX.Element | React.JSX.Element[];
|
|
562
|
+
/**
|
|
563
|
+
* Load markdown content from a file.
|
|
564
|
+
* @param {string} filePath The file path to load the markdown content from.
|
|
565
|
+
* @returns {Promise<void>}
|
|
566
|
+
*/
|
|
567
|
+
loadFromFile(filePath: string): Promise<void>;
|
|
568
|
+
/**
|
|
569
|
+
* Load markdown content from a file synchronously.
|
|
570
|
+
* @param {string} filePath The file path to load the markdown content from.
|
|
571
|
+
* @returns {void}
|
|
572
|
+
*/
|
|
573
|
+
loadFromFileSync(filePath: string): void;
|
|
574
|
+
/**
|
|
575
|
+
* Save the markdown content to a file. If the directory doesn't exist it will be created.
|
|
576
|
+
* @param {string} filePath The file path to save the markdown content to.
|
|
577
|
+
* @returns {Promise<void>}
|
|
578
|
+
*/
|
|
579
|
+
saveToFile(filePath: string): Promise<void>;
|
|
580
|
+
/**
|
|
581
|
+
* Save the markdown content to a file synchronously. If the directory doesn't exist it will be created.
|
|
582
|
+
* @param {string} filePath The file path to save the markdown content to.
|
|
583
|
+
* @returns {void}
|
|
584
|
+
*/
|
|
585
|
+
saveToFileSync(filePath: string): void;
|
|
586
|
+
mergeOptions(current: WritrOptions, options: WritrOptions): WritrOptions;
|
|
587
|
+
private isCacheEnabled;
|
|
588
|
+
private createProcessor;
|
|
589
|
+
private mergeRenderOptions;
|
|
590
|
+
}
|
|
591
|
+
//#endregion
|
|
592
|
+
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 };
|