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 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, bold, code } from 'prose-writer';
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, bold } from 'prose-writer';
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, bold, code } from 'prose-writer';
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)` - `![alt](url)`
203
271
 
204
272
  ```typescript
205
- import { write, bold, italic, code, link } from 'prose-writer';
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, code } from 'prose-writer';
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, bold } from 'prose-writer';
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, italic } from 'prose-writer';
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, strike } from 'prose-writer';
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, link } from 'prose-writer';
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, bold } from 'prose-writer';
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 { bold, code, image, inline, italic, link, ProseWriter, strike, write, } from './prose-writer';
1
+ export { ProseWriter, write } from './prose-writer';
package/dist/index.js CHANGED
@@ -1,81 +1,95 @@
1
1
  // @bun
2
- class E{parts=[];_skipNextPadding=!1;constructor(z){if(z!==void 0)this.parts.push(z.endsWith(`
3
- `)?z:z+`
4
- `)}write(...z){let A=z.map((D)=>{if(D instanceof E)return D.toString().trimEnd();return String(D)}).join(" ");if(this.parts.length===0&&A.length===0)return this;let B=this.padding;return this.parts.push(B+A+`
5
- `),this}nextLine(){return this._skipNextPadding=!0,this}unorderedList(...z){if(z.length===1&&typeof z[0]==="function"){let{builder:D,getItems:F}=this.createListBuilder();return z[0](D),this.unorderedList(...F())}let B=z.map((D)=>{if(D instanceof E)return D.toString().trimEnd().split(`
6
- `).map((F)=>` ${F}`).join(`
7
- `);return`- ${D}`}).join(`
8
- `);return this.parts.push(`${this.padding}${B}
9
-
10
- `),this}list(...z){if(z.length===1&&typeof z[0]==="function")return this.unorderedList(z[0]);return this.unorderedList(...z)}orderedList(...z){if(z.length===1&&typeof z[0]==="function"){let{builder:F,getItems:G}=this.createListBuilder();return z[0](F),this.orderedList(...G())}let A=1,D=z.map((F)=>{if(F instanceof E)return F.toString().trimEnd().split(`
11
- `).map((G)=>` ${G}`).join(`
12
- `);return`${A++}. ${F}`}).join(`
13
- `);return this.parts.push(`${this.padding}${D}
14
-
15
- `),this}tasks(...z){if(z.length===1&&typeof z[0]==="function"){let{builder:D,getItems:F}=this.createListBuilder();z[0](D);let H=F().map((J)=>{if(J instanceof E)return J.toString().trimEnd().split(`
16
- `).map((K)=>` ${K}`).join(`
17
- `);return`- ${J}`}).join(`
18
- `);return this.parts.push(`${this.padding}${H}
2
+ class T{value;constructor(F){this.value=F}toString(){return this.value}valueOf(){return this.value}}var k=(F)=>F.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;"),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(`![${N}](${K})`)},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 B=z.map((D)=>{if(Array.isArray(D)&&D.length===2&&typeof D[1]==="boolean"){let[H,J]=D,K=J?"[x] ":"[ ] ",Y=M(H).toString().trimEnd();return K+Y}let F="[ ] ",G=M(D).toString().trimEnd();return F+G}).map((D)=>`- ${D}`).join(`
21
- `);return this.parts.push(`${this.padding}${B}
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}callout(z,A){let B;if(typeof A==="function"){let H=new E;A(H.enhanced),B=H.toString().trimEnd()}else B=A;let D=B.split(`
24
- `),G=[`[!${z.toUpperCase()}]`,...D].map((H)=>`> ${H}`).join(`
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}heading(z,...A){let B="#".repeat(z),D=A.join(" ");return this.parts.push(`${this.padding}${B} ${D}
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(...z){let A=z.map((B)=>`> ${B}`).join(`
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}${A}
45
+ `);return this.parts.push(`${this.padding}${H}
32
46
 
33
- `),this}codeblock(z,A){let B;if(typeof A==="function"){let D=new E;A(D.enhanced),B=D.toString().trim()}else B=A;return this.parts.push(`${this.padding}\`\`\`${z}
34
- ${B}
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(z){let A=typeof z==="string"?z:JSON.stringify(z,null,2);return this.codeblock("json",A)}append(z){let A=z.toString();if(A.length>0)this.parts.push(this.padding+A);return this}get enhanced(){let z={bold:O,italic:Q,code:N,inline:X,link:U,strike:T,image:V};return new Proxy(this,{get(A,B){if(typeof B==="string"&&B in z)return z[B];let D=Reflect.get(A,B,A);if(typeof D==="function")return D.bind(A);return D}})}when(z,A){if(z)A(this.enhanced);return this}with(z){return z(this.enhanced),this}tag(z,A){let B;if(typeof A==="function"){let D=new E;A(D.enhanced),B=D.toString()}else B=A instanceof E?A.toString():A;return this.parts.push(`${this.padding}<${z}>
40
- ${B.trimEnd()}
41
- </${z}>
42
- `),this}code(z){return this.parts.push(this.padding+N(z)+`
43
- `),this}fill(z){let B=this.toString().replace(/\{\{(\w+)\}\}/g,(D,F)=>{return z[F]??D});return new E(B)}section(z,A,B=2){let D=new E;A(D.enhanced);let F="#".repeat(B);return this.parts.push(`${this.padding}${F} ${z}
44
-
45
- ${D.toString()}`),this}clone(){let z=new E;return z.parts=[...this.parts],z}table(z,A){let B=`| ${z.join(" | ")} |`,D=`| ${z.map(()=>"---").join(" | ")} |`,F=A.map((G)=>{return`| ${(Array.isArray(G)?G:z.map((J)=>{let K=G[J];if(K instanceof E)return K.toPlainText();return String(K??"")})).join(" | ")} |`}).join(`
46
- `);return this.parts.push(`${this.padding}${B}
47
- ${D}
48
- ${F}
49
-
50
- `),this}definitions(z){let A=Object.entries(z).map(([B,D])=>`**${B}**: ${D}`).join(`
51
- `);return this.parts.push(`${this.padding}${A}
52
-
53
- `),this}bold(z){return this.parts.push(this.padding+O(z)+`
54
- `),this}italic(z){return this.parts.push(this.padding+Q(z)+`
55
- `),this}strike(z){return this.parts.push(this.padding+T(z)+`
56
- `),this}raw(z){return this.parts.push(z),this}link(z,A){return this.parts.push(this.padding+U(z,A)+`
57
- `),this}image(z,A){return this.parts.push(this.padding+V(z,A)+`
58
- `),this}comment(z){return this.parts.push(`${this.padding}<!-- ${z} -->
59
-
60
- `),this}yaml(z){let A=typeof z==="string"?z:this.toYamlString(z);return this.codeblock("yaml",A)}toYamlString(z,A=0){let B=" ".repeat(A);if(z===null||z===void 0)return"null";if(typeof z==="string"){if(/[:\n#"']/.test(z)||z==="")return`"${z.replace(/"/g,"\\\"")}"`;return z}if(typeof z==="number"||typeof z==="boolean")return String(z);if(Array.isArray(z)){if(z.length===0)return"[]";return z.map((D)=>`${B}- ${this.toYamlString(D,A+1)}`).join(`
61
- `)}if(typeof z==="object"){let D=Object.entries(z);if(D.length===0)return"{}";return D.map(([F,G])=>{let H=this.toYamlString(G,A+1);if(typeof G==="object"&&G!==null&&!Array.isArray(G))return`${B}${F}:
62
- ${H}`;if(Array.isArray(G))return`${B}${F}:
63
- ${H}`;return`${B}${F}: ${H}`}).join(`
64
- `)}return JSON.stringify(z)??"null"}delimit(z,A,B){let D=B instanceof E?B.toString():B;return this.parts.push(`${this.padding}${z}
65
- ${D}
66
- ${A}
67
- `),this}compact(){let z=this.toString().replace(/\n{3,}/g,`
68
-
69
- `);return new E(z)}trim(){let z=this.toString().trim();return new E(z)}tokens(z){let A=this.toString();if(z)return z(A);return Math.ceil(A.length/4)}each(z,A){return z.forEach((B,D)=>{A(B,this.enhanced,D)}),this}toPlainText(){let z=this.toString();return z=z.replace(/```[\s\S]*?```/g,(A)=>{return A.split(`
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
- `)}),z=z.replace(/`([^`]+)`/g,"$1"),z=z.replace(/^#{1,6}\s+(.*)$/gm,"$1"),z=z.replace(/\*\*([^*]+)\*\*/g,"$1"),z=z.replace(/\*([^*]+)\*/g,"$1"),z=z.replace(/\[([^\]]+)\]\([^)]+\)/g,"$1"),z=z.replace(/^>\s?/gm,""),z=z.replace(/^---$/gm,""),z=z.replace(/^[-*]\s+/gm,""),z=z.replace(/^\d+\.\s+/gm,""),z=z.replace(/<[^>]+>/g,""),z=z.replace(/\|/g," "),z=z.replace(/^[\s-]+$/gm,""),z=z.replace(/ {2,}/g," "),z=z.replace(/\n{3,}/g,`
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
- `),z.trim()}get padding(){if(this._skipNextPadding||this.parts.length===0)return this._skipNextPadding=!1,"";let z=this.parts[this.parts.length-1];if(z.endsWith(`
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(z.endsWith(`
89
+ `))return"";if(F.endsWith(`
76
90
  `))return`
77
91
  `;return`
78
92
 
79
- `}createListBuilder(){let z=[],A={item:(...B)=>{return z.push(M(...B).toString().trimEnd()),A},task:(B,...D)=>{let F=B?"[x] ":"[ ] ",G=M(...D).toString().trimEnd();return z.push(F+G),A},todo:(...B)=>A.task(!1,...B),done:(...B)=>A.task(!0,...B),unorderedList:(...B)=>{let D=new E;if(B.length===1&&typeof B[0]==="function")D.unorderedList(B[0]);else D.unorderedList(...B);return z.push(D),A},list:(...B)=>{let D=new E;if(B.length===1&&typeof B[0]==="function")D.list(B[0]);else D.list(...B);return z.push(D),A},orderedList:(...B)=>{let D=new E;if(B.length===1&&typeof B[0]==="function")D.orderedList(B[0]);else D.orderedList(...B);return z.push(D),A},comment:(B)=>{let D=new E;return D.comment(B),z.push(D),A},bold:O,italic:Q,code:N,inline:X,strike:T,link:U,image:V};return{builder:A,getItems:()=>z}}static empty(){return new E}static join(...z){let A=new E;for(let B of z)A.parts.push(B.toString());return A}static fromTemplate(z){return new E(z)}toString(){return this.parts.join("")}[Symbol.toPrimitive](z){if(z==="number")return Number.NaN;return this.toString()}get[Symbol.toStringTag](){return"ProseWriter"}}var M=Object.assign((...z)=>{return new E().write(...z)},{with:(z)=>{return new E().with(z)},unorderedList:(...z)=>{let A=new E;if(z.length===1&&typeof z[0]==="function")return A.unorderedList(z[0]);return A.unorderedList(...z)},list:(...z)=>{let A=new E;if(z.length===1&&typeof z[0]==="function")return A.list(z[0]);return A.list(...z)},orderedList:(...z)=>{let A=new E;if(z.length===1&&typeof z[0]==="function")return A.orderedList(z[0]);return A.orderedList(...z)},tasks:(...z)=>{let A=new E;if(z.length===1&&typeof z[0]==="function")return A.tasks(z[0]);return A.tasks(...z)},callout:(z,A)=>{return new E().callout(z,A)}}),O=(z)=>`**${z instanceof E?z.toString().trim():z}**`,Q=(z)=>`*${z instanceof E?z.toString().trim():z}*`,N=(z)=>`\`${z instanceof E?z.toString().trim():z}\``,X=N,T=(z)=>`~~${z instanceof E?z.toString().trim():z}~~`,U=(z,A)=>`[${z instanceof E?z.toString().trim():z}](${A})`,V=(z,A)=>`![${z instanceof E?z.toString().trim():z}](${A})`;export{M as write,T as strike,U as link,Q as italic,X as inline,V as image,N as code,O as bold,E as ProseWriter};
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)=>`![${F instanceof Q?F.toString().trim():F}](${H})`;export{x as write,Q as ProseWriter};
80
94
 
81
- //# debugId=C38FBEE8EEEC812064756E2164756E21
95
+ //# debugId=ECE9ECE86506912164756E2164756E21