prose-writer 0.1.0 → 0.1.1
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 +166 -12
- package/dist/index.d.ts +1 -1
- package/dist/index.js +76 -62
- package/dist/index.js.map +3 -3
- package/dist/markdown.d.ts +1 -0
- package/dist/markdown.js +95 -0
- package/dist/markdown.js.map +10 -0
- package/dist/prose-writer.d.ts +70 -11
- package/dist/safe.d.ts +10 -0
- package/dist/safe.js +95 -0
- package/dist/safe.js.map +11 -0
- package/dist/schema.d.ts +1 -0
- package/dist/schema.js +3 -0
- package/dist/schema.js.map +9 -0
- package/dist/validation.d.ts +2 -0
- package/dist/validation.js +95 -0
- package/dist/validation.js.map +10 -0
- package/package.json +26 -2
package/README.md
CHANGED
|
@@ -52,7 +52,8 @@ const prompt = write(`You are a ${role}.`)
|
|
|
52
52
|
### Real-world example
|
|
53
53
|
|
|
54
54
|
```typescript
|
|
55
|
-
import { write
|
|
55
|
+
import { write } from 'prose-writer';
|
|
56
|
+
import { bold, code } from 'prose-writer/markdown';
|
|
56
57
|
|
|
57
58
|
// Define reusable components
|
|
58
59
|
const codeReviewPersona = write('You are a', bold('senior software engineer.')).write(
|
|
@@ -96,10 +97,47 @@ npm install prose-writer
|
|
|
96
97
|
pnpm add prose-writer
|
|
97
98
|
```
|
|
98
99
|
|
|
100
|
+
## Exports
|
|
101
|
+
|
|
102
|
+
Core:
|
|
103
|
+
|
|
104
|
+
```typescript
|
|
105
|
+
import { write, ProseWriter } from 'prose-writer';
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
Markdown utilities:
|
|
109
|
+
|
|
110
|
+
```typescript
|
|
111
|
+
import { bold, italic, code, strike, link, image } from 'prose-writer/markdown';
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
Validation helpers:
|
|
115
|
+
|
|
116
|
+
```typescript
|
|
117
|
+
import {
|
|
118
|
+
createJsonSchemaValidator,
|
|
119
|
+
createYamlParserAdapter,
|
|
120
|
+
ValidationError,
|
|
121
|
+
} from 'prose-writer/validation';
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
Schema types:
|
|
125
|
+
|
|
126
|
+
```typescript
|
|
127
|
+
import type { SchemaEmbedOptions } from 'prose-writer/schema';
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
Safe writer:
|
|
131
|
+
|
|
132
|
+
```typescript
|
|
133
|
+
import { write } from 'prose-writer/safe';
|
|
134
|
+
```
|
|
135
|
+
|
|
99
136
|
## Quick Start
|
|
100
137
|
|
|
101
138
|
```typescript
|
|
102
|
-
import { write
|
|
139
|
+
import { write } from 'prose-writer';
|
|
140
|
+
import { bold } from 'prose-writer/markdown';
|
|
103
141
|
|
|
104
142
|
const prompt = write('You are a', bold('helpful assistant.'))
|
|
105
143
|
.write('Please help the user with their request.')
|
|
@@ -122,7 +160,8 @@ Please help the user with their request.
|
|
|
122
160
|
Creates a new `ProseWriter` instance. Multiple arguments are joined with a space, and a newline is added at the end. Can be called with zero arguments to add a blank line between other `write()` calls.
|
|
123
161
|
|
|
124
162
|
```typescript
|
|
125
|
-
import { write
|
|
163
|
+
import { write } from 'prose-writer';
|
|
164
|
+
import { bold, code } from 'prose-writer/markdown';
|
|
126
165
|
|
|
127
166
|
const text = write('Hello', bold('World')).toString();
|
|
128
167
|
```
|
|
@@ -133,6 +172,35 @@ Output:
|
|
|
133
172
|
Hello **World**
|
|
134
173
|
```
|
|
135
174
|
|
|
175
|
+
### `write.safe(...content: string[])`
|
|
176
|
+
|
|
177
|
+
Creates a `ProseWriter` that escapes untrusted input. Safe mode:
|
|
178
|
+
|
|
179
|
+
- Escapes Markdown punctuation and line-leading markers (lists, headings, blockquotes)
|
|
180
|
+
- Escapes XML-sensitive characters (`&`, `<`, `>`) in text and tags
|
|
181
|
+
- Sanitizes link text + destinations
|
|
182
|
+
- Wraps inline code with a backtick fence that can't be broken by user input
|
|
183
|
+
|
|
184
|
+
Use this when inserting user-generated content. To intentionally include raw Markdown, pass a `ProseWriter` instance or call `.raw()` to bypass escaping.
|
|
185
|
+
In safe mode, `fill()` also escapes variable values.
|
|
186
|
+
If your template string is trusted (authored by you), use `write.safe.template(...)` to prevent the template itself from being escaped.
|
|
187
|
+
You can also import a safe-first writer: `import { write } from 'prose-writer/safe'`.
|
|
188
|
+
|
|
189
|
+
```typescript
|
|
190
|
+
const prompt = write.safe
|
|
191
|
+
.template('You are {{role}}!')
|
|
192
|
+
.fill({ role: userRole })
|
|
193
|
+
.toString();
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
```typescript
|
|
197
|
+
const prompt = write
|
|
198
|
+
.safe('User input:', userInput)
|
|
199
|
+
.tag('context', userInput)
|
|
200
|
+
.link('Source', userUrl)
|
|
201
|
+
.toString();
|
|
202
|
+
```
|
|
203
|
+
|
|
136
204
|
You can also start a chain using `write.with()` if you want to use the builder pattern immediately:
|
|
137
205
|
|
|
138
206
|
```typescript
|
|
@@ -202,7 +270,8 @@ The following utilities return formatted strings and can be used within `write()
|
|
|
202
270
|
- `image(alt: string, url: string)` - ``
|
|
203
271
|
|
|
204
272
|
```typescript
|
|
205
|
-
import { write
|
|
273
|
+
import { write } from 'prose-writer';
|
|
274
|
+
import { bold, italic, code, link } from 'prose-writer/markdown';
|
|
206
275
|
|
|
207
276
|
write(
|
|
208
277
|
'Check out',
|
|
@@ -552,7 +621,7 @@ Section 1
|
|
|
552
621
|
Section 2
|
|
553
622
|
```
|
|
554
623
|
|
|
555
|
-
### `.json(data: unknown)`
|
|
624
|
+
### `.json(data: unknown, options?: ValidationOptions)`
|
|
556
625
|
|
|
557
626
|
Appends a JSON code block. If the data is not a string, it will be stringified with formatting.
|
|
558
627
|
|
|
@@ -587,6 +656,17 @@ Output:
|
|
|
587
656
|
```
|
|
588
657
|
````
|
|
589
658
|
|
|
659
|
+
You can pass validation hooks via `options`:
|
|
660
|
+
|
|
661
|
+
```typescript
|
|
662
|
+
write('').json(data, {
|
|
663
|
+
schema: outputSchema,
|
|
664
|
+
validate: ({ format, data, schema }) => {
|
|
665
|
+
// return { valid: true } or { valid: false, issues: [...] }
|
|
666
|
+
},
|
|
667
|
+
});
|
|
668
|
+
```
|
|
669
|
+
|
|
590
670
|
### `.append(writer: ProseWriter)`
|
|
591
671
|
|
|
592
672
|
Appends the content from another `ProseWriter` instance. Enables composition of prompts from reusable pieces.
|
|
@@ -694,7 +774,8 @@ function.
|
|
|
694
774
|
// Recommended:
|
|
695
775
|
|
|
696
776
|
```typescript
|
|
697
|
-
import { write
|
|
777
|
+
import { write } from 'prose-writer';
|
|
778
|
+
import { code } from 'prose-writer/markdown';
|
|
698
779
|
write('Use the', code('calculateTotal'), 'function.').toString();
|
|
699
780
|
```
|
|
700
781
|
|
|
@@ -815,7 +896,8 @@ information.
|
|
|
815
896
|
// Recommended:
|
|
816
897
|
|
|
817
898
|
```typescript
|
|
818
|
-
import { write
|
|
899
|
+
import { write } from 'prose-writer';
|
|
900
|
+
import { bold } from 'prose-writer/markdown';
|
|
819
901
|
write('This is', bold('important'), 'information.').toString();
|
|
820
902
|
```
|
|
821
903
|
|
|
@@ -844,7 +926,8 @@ the following.
|
|
|
844
926
|
// Recommended:
|
|
845
927
|
|
|
846
928
|
```typescript
|
|
847
|
-
import { write
|
|
929
|
+
import { write } from 'prose-writer';
|
|
930
|
+
import { italic } from 'prose-writer/markdown';
|
|
848
931
|
write('Please', italic('note'), 'the following.').toString();
|
|
849
932
|
```
|
|
850
933
|
|
|
@@ -893,7 +976,8 @@ New
|
|
|
893
976
|
// Recommended:
|
|
894
977
|
|
|
895
978
|
```typescript
|
|
896
|
-
import { write
|
|
979
|
+
import { write } from 'prose-writer';
|
|
980
|
+
import { strike } from 'prose-writer/markdown';
|
|
897
981
|
write('Price:', strike('$100'), '$80').toString();
|
|
898
982
|
```
|
|
899
983
|
|
|
@@ -949,7 +1033,8 @@ for details.
|
|
|
949
1033
|
// Recommended:
|
|
950
1034
|
|
|
951
1035
|
```typescript
|
|
952
|
-
import { write
|
|
1036
|
+
import { write } from 'prose-writer';
|
|
1037
|
+
import { link } from 'prose-writer/markdown';
|
|
953
1038
|
write('See the', link('documentation', 'https://example.com'), 'for details.').toString();
|
|
954
1039
|
```
|
|
955
1040
|
|
|
@@ -959,7 +1044,7 @@ Output:
|
|
|
959
1044
|
See the [documentation](https://example.com) for details.
|
|
960
1045
|
```
|
|
961
1046
|
|
|
962
|
-
### `.yaml(data: unknown)`
|
|
1047
|
+
### `.yaml(data: unknown, options?: ValidationOptions)`
|
|
963
1048
|
|
|
964
1049
|
Appends a YAML code block. If data is not a string, it will be converted to YAML format.
|
|
965
1050
|
|
|
@@ -996,6 +1081,74 @@ Wraps content with custom delimiters. Useful for models that respond to specific
|
|
|
996
1081
|
write('Input:').delimit('###', '###', 'content here').toString();
|
|
997
1082
|
```
|
|
998
1083
|
|
|
1084
|
+
### Structured Output Validation
|
|
1085
|
+
|
|
1086
|
+
`json()` and `yaml()` accept a `validate` hook. If validation fails, a `ValidationError` is thrown with diagnostic details.
|
|
1087
|
+
When validating JSON, string inputs are parsed first and will throw a `ValidationError` if they are invalid JSON. For YAML, you can supply a parser via `parseYaml` to parse strings before validation.
|
|
1088
|
+
|
|
1089
|
+
```typescript
|
|
1090
|
+
import type { OutputValidator } from 'prose-writer/validation';
|
|
1091
|
+
|
|
1092
|
+
const validate: OutputValidator = ({ format, data, schema }) => {
|
|
1093
|
+
if (format !== 'json') return { valid: true };
|
|
1094
|
+
if (!schema) return { valid: true };
|
|
1095
|
+
// Your validation logic here
|
|
1096
|
+
return { valid: true };
|
|
1097
|
+
};
|
|
1098
|
+
|
|
1099
|
+
write('').json(payload, { schema: outputSchema, validate });
|
|
1100
|
+
```
|
|
1101
|
+
|
|
1102
|
+
For YAML string inputs, pass a parser adapter:
|
|
1103
|
+
|
|
1104
|
+
```typescript
|
|
1105
|
+
import { parse as parseYaml } from 'yaml';
|
|
1106
|
+
import { createYamlParserAdapter } from 'prose-writer/validation';
|
|
1107
|
+
|
|
1108
|
+
write('').yaml(payloadString, {
|
|
1109
|
+
validate,
|
|
1110
|
+
parseYaml: createYamlParserAdapter(parseYaml),
|
|
1111
|
+
});
|
|
1112
|
+
```
|
|
1113
|
+
|
|
1114
|
+
#### JSON Schema via Adapter
|
|
1115
|
+
|
|
1116
|
+
`prose-writer` stays zero-deps, but you can plug in Ajv (or any validator) through an adapter.
|
|
1117
|
+
|
|
1118
|
+
```typescript
|
|
1119
|
+
import Ajv from 'ajv';
|
|
1120
|
+
import { createJsonSchemaValidator } from 'prose-writer/validation';
|
|
1121
|
+
|
|
1122
|
+
const ajv = new Ajv();
|
|
1123
|
+
const validate = createJsonSchemaValidator((schema, data) => {
|
|
1124
|
+
const valid = ajv.validate(schema, data);
|
|
1125
|
+
if (valid) return { valid: true };
|
|
1126
|
+
return {
|
|
1127
|
+
valid: false,
|
|
1128
|
+
issues: (ajv.errors ?? []).map((error) => ({
|
|
1129
|
+
path: error.instancePath || '$',
|
|
1130
|
+
message: error.message ?? 'Invalid value',
|
|
1131
|
+
})),
|
|
1132
|
+
};
|
|
1133
|
+
});
|
|
1134
|
+
|
|
1135
|
+
write('').json(payload, { schema: outputSchema, validate });
|
|
1136
|
+
```
|
|
1137
|
+
|
|
1138
|
+
#### Embedding Schemas in Prompts
|
|
1139
|
+
|
|
1140
|
+
```typescript
|
|
1141
|
+
write('Return JSON that matches this schema:')
|
|
1142
|
+
.schema(outputSchema, { title: 'Output Schema', tag: 'output_schema' })
|
|
1143
|
+
.toString();
|
|
1144
|
+
```
|
|
1145
|
+
|
|
1146
|
+
Recommended usage:
|
|
1147
|
+
|
|
1148
|
+
- Prefer JSON Schema for structured output formats.
|
|
1149
|
+
- Store schemas alongside prompt builders and include them in the prompt with `.schema()`.
|
|
1150
|
+
- Validate the object you send or receive, not just the stringified output.
|
|
1151
|
+
|
|
999
1152
|
### `.compact()`
|
|
1000
1153
|
|
|
1001
1154
|
Returns a new ProseWriter with consecutive newlines (3+) collapsed to double newlines.
|
|
@@ -1080,7 +1233,8 @@ Features:
|
|
|
1080
1233
|
Converts the prose to plain text by stripping all markdown formatting.
|
|
1081
1234
|
|
|
1082
1235
|
```typescript
|
|
1083
|
-
import { write
|
|
1236
|
+
import { write } from 'prose-writer';
|
|
1237
|
+
import { bold } from 'prose-writer/markdown';
|
|
1084
1238
|
|
|
1085
1239
|
const prose = write('')
|
|
1086
1240
|
.heading(1, 'Title')
|
package/dist/index.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { ProseWriter, write } from './prose-writer';
|
package/dist/index.js
CHANGED
|
@@ -1,81 +1,95 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
class
|
|
3
|
-
`)
|
|
4
|
-
`)}
|
|
5
|
-
`)
|
|
6
|
-
`).
|
|
7
|
-
`)
|
|
8
|
-
`)
|
|
9
|
-
|
|
10
|
-
`)
|
|
11
|
-
`)
|
|
12
|
-
`);return`${
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
`)
|
|
16
|
-
`)
|
|
17
|
-
`);return
|
|
18
|
-
|
|
2
|
+
class T{value;constructor(F){this.value=F}toString(){return this.value}valueOf(){return this.value}}var k=(F)=>F.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">"),S=(F)=>{if(/^\s*#{1,6}\s/.test(F))return F.replace(/^(\s*)(#{1,6})/,"$1\\$2");if(/^\s*>/.test(F))return F.replace(/^(\s*)>/,"$1\\>");if(/^\s*([-+*])\s/.test(F))return F.replace(/^(\s*)([-+*])/,"$1\\$2");if(/^\s*\d+\.\s/.test(F))return F.replace(/^(\s*)(\d+)\./,"$1$2\\.");return F},Z=(F)=>{return k(F).replace(/([\\`*_~()|!])/g,"\\$1").replace(/\[/g,"\\[").replace(/\]/g,"\\]").split(`
|
|
3
|
+
`).map((G)=>S(G)).join(`
|
|
4
|
+
`)},W=(F)=>{let H=F.match(/`+/g),G=(H?Math.max(...H.map((O)=>O.length)):0)+1,J="`".repeat(G),K=/^\s|\s$/.test(F)?` ${F} `:F;return`${J}${K}${J}`},P=(F)=>{return encodeURI(F).replace(/[()]/g,"\\$&")},q=(F,H="none")=>{if(F instanceof T)return{value:F.toString(),isTrusted:!0};if(F instanceof Q){let G=F.toString();if(H==="end")return{value:G.trimEnd(),isTrusted:!0};if(H==="both")return{value:G.trim(),isTrusted:!0};return{value:G,isTrusted:!0}}return{value:String(F),isTrusted:!1}},b=(F)=>{let{value:H,isTrusted:G}=q(F,"both");return G?H:Z(H)},z=(F)=>new T(F),X=(F)=>z(`**${b(F)}**`),D=(F)=>z(`*${b(F)}*`),j=(F)=>z(`~~${b(F)}~~`),A=(F)=>{let{value:H}=q(F,"both");return z(W(H))},E=(F,H)=>{let{value:G,isTrusted:J}=q(F,"both"),N=J?G:Z(G),K=P(H);return z(`[${N}](${K})`)},L=(F,H)=>{let{value:G,isTrusted:J}=q(F,"both"),N=J?G:Z(G),K=P(H);return z(``)},v=(F)=>{if(F.length===0)return"No validation issues were provided.";return F.map((H,G)=>{let J=H.path?`${H.path}: `:"";return`${G+1}. ${J}${H.message}`}).join(`
|
|
5
|
+
`)};class R extends Error{format;issues;constructor(F,H,G){let J=G??`${F.toUpperCase()} validation failed`;super(`${J}
|
|
6
|
+
${v(H)}`);this.name="ValidationError",this.format=F,this.issues=H}}var p=(F)=>{return({format:H,data:G,schema:J})=>{if(H!=="json"||J===void 0)return{valid:!0};return F(J,G)}},m=(F)=>{return(H)=>F(H)};class Q{parts=[];_skipNextPadding=!1;safeMode;constructor(F,H={}){if(this.safeMode=H.safe??!1,F!==void 0)this.parts.push(F.endsWith(`
|
|
7
|
+
`)?F:F+`
|
|
8
|
+
`)}createChildWriter(){return new Q(void 0,{safe:this.safeMode})}write(...F){let H=F.map((J)=>{let{value:N,isTrusted:K}=q(J,"end");if(this.safeMode&&!K)return Z(N);return N}).join(" ");if(this.parts.length===0&&H.length===0)return this;let G=this.padding;return this.parts.push(G+H+`
|
|
9
|
+
`),this}nextLine(){return this._skipNextPadding=!0,this}unorderedList(...F){if(F.length===1&&typeof F[0]==="function"){let{builder:J,getItems:N}=this.createListBuilder();F[0](J);let O=N().map((Y)=>{if(Y instanceof Q)return Y.toString().trimEnd().split(`
|
|
10
|
+
`).map((_)=>` ${_}`).join(`
|
|
11
|
+
`);return`- ${Y}`}).join(`
|
|
12
|
+
`);return this.parts.push(`${this.padding}${O}
|
|
13
|
+
|
|
14
|
+
`),this}let G=F.map((J)=>{if(J instanceof Q)return J.toString().trimEnd().split(`
|
|
15
|
+
`).map((Y)=>` ${Y}`).join(`
|
|
16
|
+
`);let{value:N,isTrusted:K}=q(J);return`- ${this.safeMode&&!K?Z(N):N}`}).join(`
|
|
17
|
+
`);return this.parts.push(`${this.padding}${G}
|
|
18
|
+
|
|
19
|
+
`),this}list(...F){if(F.length===1&&typeof F[0]==="function")return this.unorderedList(F[0]);return this.unorderedList(...F)}orderedList(...F){if(F.length===1&&typeof F[0]==="function"){let{builder:N,getItems:K}=this.createListBuilder();F[0](N);let O=1,_=K().map(($)=>{if($ instanceof Q)return $.toString().trimEnd().split(`
|
|
20
|
+
`).map((U)=>` ${U}`).join(`
|
|
21
|
+
`);return`${O++}. ${$}`}).join(`
|
|
22
|
+
`);return this.parts.push(`${this.padding}${_}
|
|
19
23
|
|
|
20
|
-
`),this}let
|
|
21
|
-
`)
|
|
24
|
+
`),this}let H=1,J=F.map((N)=>{if(N instanceof Q)return N.toString().trimEnd().split(`
|
|
25
|
+
`).map((_)=>` ${_}`).join(`
|
|
26
|
+
`);let{value:K,isTrusted:O}=q(N),Y=this.safeMode&&!O?Z(K):K;return`${H++}. ${Y}`}).join(`
|
|
27
|
+
`);return this.parts.push(`${this.padding}${J}
|
|
22
28
|
|
|
23
|
-
`),this}
|
|
24
|
-
`)
|
|
29
|
+
`),this}tasks(...F){if(F.length===1&&typeof F[0]==="function"){let{builder:J,getItems:N}=this.createListBuilder();F[0](J);let O=N().map((Y)=>{if(Y instanceof Q)return Y.toString().trimEnd().split(`
|
|
30
|
+
`).map((_)=>` ${_}`).join(`
|
|
31
|
+
`);return`- ${Y}`}).join(`
|
|
32
|
+
`);return this.parts.push(`${this.padding}${O}
|
|
33
|
+
|
|
34
|
+
`),this}let G=F.map((J)=>{if(Array.isArray(J)&&J.length===2&&typeof J[1]==="boolean"){let[O,Y]=J,_=Y?"[x] ":"[ ] ",$=this.createChildWriter().write(O).toString().trimEnd();return _+$}let N="[ ] ",K=this.createChildWriter().write(J).toString().trimEnd();return N+K}).map((J)=>`- ${J}`).join(`
|
|
25
35
|
`);return this.parts.push(`${this.padding}${G}
|
|
26
36
|
|
|
27
|
-
`),this}
|
|
37
|
+
`),this}callout(F,H){let G;if(typeof H==="function"){let O=this.createChildWriter();H(O.enhanced),G=O.toString().trimEnd()}else{let{value:O,isTrusted:Y}=q(H);G=this.safeMode&&!Y?Z(O):O}let J=G.split(`
|
|
38
|
+
`),K=[`[!${F.toUpperCase()}]`,...J].map((O)=>`> ${O}`).join(`
|
|
39
|
+
`);return this.parts.push(`${this.padding}${K}
|
|
40
|
+
|
|
41
|
+
`),this}heading(F,...H){let G="#".repeat(F),J=H.map((N)=>{let{value:K,isTrusted:O}=q(N);if(this.safeMode&&!O)return Z(K);return K}).join(" ");return this.parts.push(`${this.padding}${G} ${J}
|
|
28
42
|
|
|
29
|
-
`),this}blockquote(...
|
|
43
|
+
`),this}blockquote(...F){let H=F.map((G)=>{let{value:J,isTrusted:N}=q(G);if(this.safeMode&&!N)return Z(J);return J}).map((G)=>`> ${G}`).join(`
|
|
30
44
|
>
|
|
31
|
-
`);return this.parts.push(`${this.padding}${
|
|
45
|
+
`);return this.parts.push(`${this.padding}${H}
|
|
32
46
|
|
|
33
|
-
`),this}codeblock(
|
|
34
|
-
${
|
|
47
|
+
`),this}codeblock(F,H){let G;if(typeof H==="function"){let J=new Q;H(J.enhanced),G=J.toString().trim()}else G=H;return this.parts.push(`${this.padding}\`\`\`${F}
|
|
48
|
+
${G}
|
|
35
49
|
\`\`\`
|
|
36
50
|
|
|
37
51
|
`),this}get separator(){return this.parts.push(`${this.padding}---
|
|
38
52
|
|
|
39
|
-
`),this}json(
|
|
40
|
-
${
|
|
41
|
-
</${
|
|
42
|
-
`),this}code(
|
|
43
|
-
`),this}fill(
|
|
44
|
-
|
|
45
|
-
${
|
|
46
|
-
`);return this.parts.push(`${this.padding}${
|
|
47
|
-
${
|
|
48
|
-
${
|
|
49
|
-
|
|
50
|
-
`),this}definitions(
|
|
51
|
-
`);return this.parts.push(`${this.padding}${
|
|
52
|
-
|
|
53
|
-
`),this}bold(
|
|
54
|
-
`),this}italic(
|
|
55
|
-
`),this}strike(
|
|
56
|
-
`),this}raw(
|
|
57
|
-
`),this}image(
|
|
58
|
-
`),this}comment(
|
|
59
|
-
|
|
60
|
-
`),this}yaml(
|
|
61
|
-
`)}if(typeof
|
|
62
|
-
${
|
|
63
|
-
${
|
|
64
|
-
`)}return JSON.stringify(
|
|
65
|
-
${
|
|
66
|
-
${
|
|
67
|
-
`),this}compact(){let
|
|
68
|
-
|
|
69
|
-
`);return new
|
|
53
|
+
`),this}json(F,H={}){this.validateOutput("json",F,H);let G=typeof F==="string"?F:JSON.stringify(F,null,2);return this.codeblock("json",G)}append(F){let H=F.toString();if(H.length>0)this.parts.push(this.padding+H);return this}get enhanced(){let F=this.safeMode?{bold:X,italic:D,code:A,inline:A,link:E,strike:j,image:L}:{bold:y,italic:V,code:B,inline:h,link:M,strike:I,image:C};return new Proxy(this,{get(H,G){if(typeof G==="string"&&G in F)return F[G];let J=Reflect.get(H,G,H);if(typeof J==="function")return J.bind(H);return J}})}when(F,H){if(F)H(this.enhanced);return this}with(F){return F(this.enhanced),this}tag(F,H){let G;if(typeof H==="function"){let J=this.createChildWriter();H(J.enhanced),G=J.toString()}else{let{value:J,isTrusted:N}=q(H);if(this.safeMode&&!N)G=k(J);else G=J}return this.parts.push(`${this.padding}<${F}>
|
|
54
|
+
${G.trimEnd()}
|
|
55
|
+
</${F}>
|
|
56
|
+
`),this}code(F){let H=this.safeMode?A(F):B(F);return this.parts.push(this.padding+H+`
|
|
57
|
+
`),this}fill(F){let G=this.toString().replace(/\{\{(\w+)\}\}/g,(J,N)=>{let K=F[N];if(K===void 0)return J;return this.safeMode?Z(K):K});return new Q(G,{safe:this.safeMode})}section(F,H,G=2){let J=this.createChildWriter();H(J.enhanced);let N="#".repeat(G),K=this.safeMode?Z(F):F;return this.parts.push(`${this.padding}${N} ${K}
|
|
58
|
+
|
|
59
|
+
${J.toString()}`),this}clone(){let F=new Q(void 0,{safe:this.safeMode});return F.parts=[...this.parts],F}table(F,H){let J=`| ${(this.safeMode?F.map((O)=>Z(O)):F).join(" | ")} |`,N=`| ${F.map(()=>"---").join(" | ")} |`,K=H.map((O)=>{return`| ${(Array.isArray(O)?O.map((_)=>{let $=String(_??"");return this.safeMode?Z($):$}):F.map((_)=>{let $=O[_];if($ instanceof Q)return $.toPlainText();let U=String($??"");return this.safeMode?Z(U):U})).join(" | ")} |`}).join(`
|
|
60
|
+
`);return this.parts.push(`${this.padding}${J}
|
|
61
|
+
${N}
|
|
62
|
+
${K}
|
|
63
|
+
|
|
64
|
+
`),this}definitions(F){let H=Object.entries(F).map(([G,J])=>{if(this.safeMode)return`${X(G)}: ${Z(J)}`;return`**${G}**: ${J}`}).join(`
|
|
65
|
+
`);return this.parts.push(`${this.padding}${H}
|
|
66
|
+
|
|
67
|
+
`),this}schema(F,H={}){let{format:G="json",title:J,level:N=2,tag:K}=H;if(J)this.heading(N,J);if(K){let O=this.createChildWriter();if(G==="json")O.json(F);else O.yaml(F);return this.tag(K,O)}if(G==="json")return this.json(F);return this.yaml(F)}bold(F){let H=this.safeMode?X(F):y(F);return this.parts.push(this.padding+H+`
|
|
68
|
+
`),this}italic(F){let H=this.safeMode?D(F):V(F);return this.parts.push(this.padding+H+`
|
|
69
|
+
`),this}strike(F){let H=this.safeMode?j(F):I(F);return this.parts.push(this.padding+H+`
|
|
70
|
+
`),this}raw(F){return this.parts.push(F),this}link(F,H){let G=this.safeMode?E(F,H):M(F,H);return this.parts.push(this.padding+G+`
|
|
71
|
+
`),this}image(F,H){let G=this.safeMode?L(F,H):C(F,H);return this.parts.push(this.padding+G+`
|
|
72
|
+
`),this}comment(F){return this.parts.push(`${this.padding}<!-- ${F} -->
|
|
73
|
+
|
|
74
|
+
`),this}yaml(F,H={}){this.validateOutput("yaml",F,H);let G=typeof F==="string"?F:this.toYamlString(F);return this.codeblock("yaml",G)}toYamlString(F,H=0){let G=" ".repeat(H);if(F===null||F===void 0)return"null";if(typeof F==="string"){if(/[:\n#"']/.test(F)||F==="")return`"${F.replace(/"/g,"\\\"")}"`;return F}if(typeof F==="number"||typeof F==="boolean")return String(F);if(Array.isArray(F)){if(F.length===0)return"[]";return F.map((J)=>`${G}- ${this.toYamlString(J,H+1)}`).join(`
|
|
75
|
+
`)}if(typeof F==="object"){let J=Object.entries(F);if(J.length===0)return"{}";return J.map(([N,K])=>{let O=this.toYamlString(K,H+1);if(typeof K==="object"&&K!==null&&!Array.isArray(K))return`${G}${N}:
|
|
76
|
+
${O}`;if(Array.isArray(K))return`${G}${N}:
|
|
77
|
+
${O}`;return`${G}${N}: ${O}`}).join(`
|
|
78
|
+
`)}return JSON.stringify(F)??"null"}delimit(F,H,G){let J=G instanceof Q?G.toString():G;return this.parts.push(`${this.padding}${F}
|
|
79
|
+
${J}
|
|
80
|
+
${H}
|
|
81
|
+
`),this}compact(){let F=this.toString().replace(/\n{3,}/g,`
|
|
82
|
+
|
|
83
|
+
`);return new Q(F,{safe:this.safeMode})}trim(){let F=this.toString().trim();return new Q(F,{safe:this.safeMode})}tokens(F){let H=this.toString();if(F)return F(H);return Math.ceil(H.length/4)}each(F,H){return F.forEach((G,J)=>{H(G,this.enhanced,J)}),this}toPlainText(){let F=this.toString();return F=F.replace(/```[\s\S]*?```/g,(H)=>{return H.split(`
|
|
70
84
|
`).slice(1,-1).join(`
|
|
71
|
-
`)}),
|
|
85
|
+
`)}),F=F.replace(/`([^`]+)`/g,"$1"),F=F.replace(/^#{1,6}\s+(.*)$/gm,"$1"),F=F.replace(/\*\*([^*]+)\*\*/g,"$1"),F=F.replace(/\*([^*]+)\*/g,"$1"),F=F.replace(/\[([^\]]+)\]\([^)]+\)/g,"$1"),F=F.replace(/^>\s?/gm,""),F=F.replace(/^---$/gm,""),F=F.replace(/^[-*]\s+/gm,""),F=F.replace(/^\d+\.\s+/gm,""),F=F.replace(/<[^>]+>/g,""),F=F.replace(/\|/g," "),F=F.replace(/^[\s-]+$/gm,""),F=F.replace(/ {2,}/g," "),F=F.replace(/\n{3,}/g,`
|
|
72
86
|
|
|
73
|
-
`),
|
|
87
|
+
`),F.trim()}validateOutput(F,H,G){if(!G.validate)return;let J=H;if(F==="json"&&typeof H==="string")try{J=JSON.parse(H)}catch(K){let O=K instanceof Error?K.message:"Invalid JSON string";throw new R(F,[{path:"$",message:`Invalid JSON string: ${O}`}],G.label)}if(F==="yaml"&&typeof H==="string"&&G.parseYaml)try{J=G.parseYaml(H)}catch(K){let O=K instanceof Error?K.message:"Invalid YAML string";throw new R(F,[{path:"$",message:`Invalid YAML string: ${O}`}],G.label)}let N=G.validate({format:F,data:J,schema:G.schema});if(N.valid)return;throw new R(F,N.issues??[],G.label)}get padding(){if(this._skipNextPadding||this.parts.length===0)return this._skipNextPadding=!1,"";let F=this.parts[this.parts.length-1];if(F.endsWith(`
|
|
74
88
|
|
|
75
|
-
`))return"";if(
|
|
89
|
+
`))return"";if(F.endsWith(`
|
|
76
90
|
`))return`
|
|
77
91
|
`;return`
|
|
78
92
|
|
|
79
|
-
`}createListBuilder(){let
|
|
93
|
+
`}createListBuilder(){let F=[],H={item:(...G)=>{return F.push(this.createChildWriter().write(...G).toString().trimEnd()),H},task:(G,...J)=>{let N=G?"[x] ":"[ ] ",K=this.createChildWriter().write(...J).toString().trimEnd();return F.push(N+K),H},todo:(...G)=>H.task(!1,...G),done:(...G)=>H.task(!0,...G),unorderedList:(...G)=>{let J=this.createChildWriter();if(G.length===1&&typeof G[0]==="function")J.unorderedList(G[0]);else J.unorderedList(...G);return F.push(J),H},list:(...G)=>{let J=this.createChildWriter();if(G.length===1&&typeof G[0]==="function")J.list(G[0]);else J.list(...G);return F.push(J),H},orderedList:(...G)=>{let J=this.createChildWriter();if(G.length===1&&typeof G[0]==="function")J.orderedList(G[0]);else J.orderedList(...G);return F.push(J),H},comment:(G)=>{let J=this.createChildWriter();return J.comment(G),F.push(J),H},bold:this.safeMode?X:y,italic:this.safeMode?D:V,code:this.safeMode?A:B,inline:this.safeMode?A:h,strike:this.safeMode?j:I,link:this.safeMode?E:M,image:this.safeMode?L:C};return{builder:H,getItems:()=>F}}static empty(){return new Q}static join(...F){let H=new Q;for(let G of F)H.parts.push(G.toString());return H}static fromTemplate(F){return new Q(F)}toString(){return this.parts.join("")}[Symbol.toPrimitive](F){if(F==="number")return Number.NaN;return this.toString()}get[Symbol.toStringTag](){return"ProseWriter"}}var w=(F)=>{let H=()=>new Q(void 0,{safe:F});return Object.assign((...G)=>{return H().write(...G)},{with:(G)=>{return H().with(G)},template:(G)=>{if(F)return H().write(z(G));return H().write(G)},unorderedList:(...G)=>{let J=H();if(G.length===1&&typeof G[0]==="function")return J.unorderedList(G[0]);return J.unorderedList(...G)},list:(...G)=>{let J=H();if(G.length===1&&typeof G[0]==="function")return J.list(G[0]);return J.list(...G)},orderedList:(...G)=>{let J=H();if(G.length===1&&typeof G[0]==="function")return J.orderedList(G[0]);return J.orderedList(...G)},tasks:(...G)=>{let J=H();if(G.length===1&&typeof G[0]==="function")return J.tasks(G[0]);return J.tasks(...G)},callout:(G,J)=>{return H().callout(G,J)},schema:(G,J)=>{return H().schema(G,J)}})},f=w(!0),x=Object.assign(w(!1),{safe:f}),y=(F)=>`**${F instanceof Q?F.toString().trim():F}**`,V=(F)=>`*${F instanceof Q?F.toString().trim():F}*`,B=(F)=>`\`${F instanceof Q?F.toString().trim():F}\``,h=B,I=(F)=>`~~${F instanceof Q?F.toString().trim():F}~~`,M=(F,H)=>`[${F instanceof Q?F.toString().trim():F}](${H})`,C=(F,H)=>``;export{x as write,Q as ProseWriter};
|
|
80
94
|
|
|
81
|
-
//# debugId=
|
|
95
|
+
//# debugId=ECE9ECE86506912164756E2164756E21
|