@valkyrianlabs/payload-markdown-docs 0.1.0-canary.0

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.
Files changed (204) hide show
  1. package/README.md +195 -0
  2. package/dist/admin/DocsSetManager.d.ts +2 -0
  3. package/dist/admin/DocsSetManager.js +298 -0
  4. package/dist/admin/DocsSetManager.js.map +1 -0
  5. package/dist/admin/docsSetManagerData.d.ts +25 -0
  6. package/dist/admin/docsSetManagerData.js +266 -0
  7. package/dist/admin/docsSetManagerData.js.map +1 -0
  8. package/dist/admin/docsSetManagerTypes.d.ts +103 -0
  9. package/dist/admin/docsSetManagerTypes.js +3 -0
  10. package/dist/admin/docsSetManagerTypes.js.map +1 -0
  11. package/dist/admin/index.d.ts +3 -0
  12. package/dist/admin/index.js +4 -0
  13. package/dist/admin/index.js.map +1 -0
  14. package/dist/cli/commands/install.d.ts +2 -0
  15. package/dist/cli/commands/install.js +211 -0
  16. package/dist/cli/commands/install.js.map +1 -0
  17. package/dist/cli/commands/keygen.d.ts +2 -0
  18. package/dist/cli/commands/keygen.js +89 -0
  19. package/dist/cli/commands/keygen.js.map +1 -0
  20. package/dist/cli/commands/manifest.d.ts +2 -0
  21. package/dist/cli/commands/manifest.js +50 -0
  22. package/dist/cli/commands/manifest.js.map +1 -0
  23. package/dist/cli/commands/plan.d.ts +2 -0
  24. package/dist/cli/commands/plan.js +110 -0
  25. package/dist/cli/commands/plan.js.map +1 -0
  26. package/dist/cli/commands/push.d.ts +3 -0
  27. package/dist/cli/commands/push.js +308 -0
  28. package/dist/cli/commands/push.js.map +1 -0
  29. package/dist/cli/commands/validate.d.ts +3 -0
  30. package/dist/cli/commands/validate.js +109 -0
  31. package/dist/cli/commands/validate.js.map +1 -0
  32. package/dist/cli/filesystem.d.ts +20 -0
  33. package/dist/cli/filesystem.js +96 -0
  34. package/dist/cli/filesystem.js.map +1 -0
  35. package/dist/cli/format.d.ts +35 -0
  36. package/dist/cli/format.js +76 -0
  37. package/dist/cli/format.js.map +1 -0
  38. package/dist/cli/http.d.ts +19 -0
  39. package/dist/cli/http.js +39 -0
  40. package/dist/cli/http.js.map +1 -0
  41. package/dist/cli/index.d.ts +3 -0
  42. package/dist/cli/index.js +214 -0
  43. package/dist/cli/index.js.map +1 -0
  44. package/dist/cli/parseArgs.d.ts +5 -0
  45. package/dist/cli/parseArgs.js +219 -0
  46. package/dist/cli/parseArgs.js.map +1 -0
  47. package/dist/cli/types.d.ts +51 -0
  48. package/dist/cli/types.js +3 -0
  49. package/dist/cli/types.js.map +1 -0
  50. package/dist/collections/docs.d.ts +9 -0
  51. package/dist/collections/docs.js +168 -0
  52. package/dist/collections/docs.js.map +1 -0
  53. package/dist/collections/docsGroups.d.ts +5 -0
  54. package/dist/collections/docsGroups.js +57 -0
  55. package/dist/collections/docsGroups.js.map +1 -0
  56. package/dist/collections/docsSets.d.ts +8 -0
  57. package/dist/collections/docsSets.js +158 -0
  58. package/dist/collections/docsSets.js.map +1 -0
  59. package/dist/collections/index.d.ts +10 -0
  60. package/dist/collections/index.js +7 -0
  61. package/dist/collections/index.js.map +1 -0
  62. package/dist/collections/nonces.d.ts +6 -0
  63. package/dist/collections/nonces.js +57 -0
  64. package/dist/collections/nonces.js.map +1 -0
  65. package/dist/collections/syncRuns.d.ts +5 -0
  66. package/dist/collections/syncRuns.js +139 -0
  67. package/dist/collections/syncRuns.js.map +1 -0
  68. package/dist/constants.d.ts +21 -0
  69. package/dist/constants.js +23 -0
  70. package/dist/constants.js.map +1 -0
  71. package/dist/endpoints/index.d.ts +2 -0
  72. package/dist/endpoints/index.js +3 -0
  73. package/dist/endpoints/index.js.map +1 -0
  74. package/dist/endpoints/sync.d.ts +47 -0
  75. package/dist/endpoints/sync.js +616 -0
  76. package/dist/endpoints/sync.js.map +1 -0
  77. package/dist/index.d.ts +9 -0
  78. package/dist/index.js +7 -0
  79. package/dist/index.js.map +1 -0
  80. package/dist/next/PayloadMarkdownDocsPage.d.ts +7 -0
  81. package/dist/next/PayloadMarkdownDocsPage.js +142 -0
  82. package/dist/next/PayloadMarkdownDocsPage.js.map +1 -0
  83. package/dist/next/index.d.ts +9 -0
  84. package/dist/next/index.js +7 -0
  85. package/dist/next/index.js.map +1 -0
  86. package/dist/next/markdown.d.ts +14 -0
  87. package/dist/next/markdown.js +232 -0
  88. package/dist/next/markdown.js.map +1 -0
  89. package/dist/next/metadata.d.ts +3 -0
  90. package/dist/next/metadata.js +33 -0
  91. package/dist/next/metadata.js.map +1 -0
  92. package/dist/next/records.d.ts +14 -0
  93. package/dist/next/records.js +146 -0
  94. package/dist/next/records.js.map +1 -0
  95. package/dist/next/route.d.ts +6 -0
  96. package/dist/next/route.js +271 -0
  97. package/dist/next/route.js.map +1 -0
  98. package/dist/next/sidebar.d.ts +15 -0
  99. package/dist/next/sidebar.js +137 -0
  100. package/dist/next/sidebar.js.map +1 -0
  101. package/dist/next/types.d.ts +117 -0
  102. package/dist/next/types.js +3 -0
  103. package/dist/next/types.js.map +1 -0
  104. package/dist/payload/applyDocsSync.d.ts +54 -0
  105. package/dist/payload/applyDocsSync.js +176 -0
  106. package/dist/payload/applyDocsSync.js.map +1 -0
  107. package/dist/payload/docsConflicts.d.ts +12 -0
  108. package/dist/payload/docsConflicts.js +34 -0
  109. package/dist/payload/docsConflicts.js.map +1 -0
  110. package/dist/payload/docsData.d.ts +23 -0
  111. package/dist/payload/docsData.js +59 -0
  112. package/dist/payload/docsData.js.map +1 -0
  113. package/dist/payload/docsSets.d.ts +38 -0
  114. package/dist/payload/docsSets.js +57 -0
  115. package/dist/payload/docsSets.js.map +1 -0
  116. package/dist/payload/existingDocs.d.ts +43 -0
  117. package/dist/payload/existingDocs.js +97 -0
  118. package/dist/payload/existingDocs.js.map +1 -0
  119. package/dist/payload/index.d.ts +15 -0
  120. package/dist/payload/index.js +10 -0
  121. package/dist/payload/index.js.map +1 -0
  122. package/dist/payload/routeCollisions.d.ts +31 -0
  123. package/dist/payload/routeCollisions.js +104 -0
  124. package/dist/payload/routeCollisions.js.map +1 -0
  125. package/dist/payload/syncRuns.d.ts +60 -0
  126. package/dist/payload/syncRuns.js +53 -0
  127. package/dist/payload/syncRuns.js.map +1 -0
  128. package/dist/plugin.d.ts +3 -0
  129. package/dist/plugin.js +165 -0
  130. package/dist/plugin.js.map +1 -0
  131. package/dist/routing/index.d.ts +3 -0
  132. package/dist/routing/index.js +4 -0
  133. package/dist/routing/index.js.map +1 -0
  134. package/dist/routing/paths.d.ts +7 -0
  135. package/dist/routing/paths.js +23 -0
  136. package/dist/routing/paths.js.map +1 -0
  137. package/dist/routing/reservations.d.ts +37 -0
  138. package/dist/routing/reservations.js +79 -0
  139. package/dist/routing/reservations.js.map +1 -0
  140. package/dist/security/canonical.d.ts +12 -0
  141. package/dist/security/canonical.js +24 -0
  142. package/dist/security/canonical.js.map +1 -0
  143. package/dist/security/githubOidc.d.ts +45 -0
  144. package/dist/security/githubOidc.js +177 -0
  145. package/dist/security/githubOidc.js.map +1 -0
  146. package/dist/security/headers.d.ts +22 -0
  147. package/dist/security/headers.js +44 -0
  148. package/dist/security/headers.js.map +1 -0
  149. package/dist/security/index.d.ts +15 -0
  150. package/dist/security/index.js +9 -0
  151. package/dist/security/index.js.map +1 -0
  152. package/dist/security/jwks.d.ts +20 -0
  153. package/dist/security/jwks.js +40 -0
  154. package/dist/security/jwks.js.map +1 -0
  155. package/dist/security/jwt.d.ts +10 -0
  156. package/dist/security/jwt.js +42 -0
  157. package/dist/security/jwt.js.map +1 -0
  158. package/dist/security/nonce.d.ts +34 -0
  159. package/dist/security/nonce.js +43 -0
  160. package/dist/security/nonce.js.map +1 -0
  161. package/dist/security/sign.d.ts +13 -0
  162. package/dist/security/sign.js +39 -0
  163. package/dist/security/sign.js.map +1 -0
  164. package/dist/security/verify.d.ts +28 -0
  165. package/dist/security/verify.js +54 -0
  166. package/dist/security/verify.js.map +1 -0
  167. package/dist/skills/codex/SKILL.md +173 -0
  168. package/dist/skills/codex/examples/docs-page.md +42 -0
  169. package/dist/skills/codex/examples/github-actions.md +64 -0
  170. package/dist/skills/codex/reference/admin.md +28 -0
  171. package/dist/skills/codex/reference/frontmatter.md +39 -0
  172. package/dist/skills/codex/reference/payload-markdown-directives.md +77 -0
  173. package/dist/skills/codex/reference/routing.md +35 -0
  174. package/dist/skills/codex/reference/sync.md +35 -0
  175. package/dist/skills/codex/reference/troubleshooting.md +53 -0
  176. package/dist/skills/codex/reference/workflow.md +39 -0
  177. package/dist/sync/aiExportManifest.d.ts +58 -0
  178. package/dist/sync/aiExportManifest.js +430 -0
  179. package/dist/sync/aiExportManifest.js.map +1 -0
  180. package/dist/sync/frontmatter.d.ts +28 -0
  181. package/dist/sync/frontmatter.js +210 -0
  182. package/dist/sync/frontmatter.js.map +1 -0
  183. package/dist/sync/hash.d.ts +1 -0
  184. package/dist/sync/hash.js +8 -0
  185. package/dist/sync/hash.js.map +1 -0
  186. package/dist/sync/index.d.ts +12 -0
  187. package/dist/sync/index.js +9 -0
  188. package/dist/sync/index.js.map +1 -0
  189. package/dist/sync/manifest.d.ts +58 -0
  190. package/dist/sync/manifest.js +21 -0
  191. package/dist/sync/manifest.js.map +1 -0
  192. package/dist/sync/paths.d.ts +16 -0
  193. package/dist/sync/paths.js +116 -0
  194. package/dist/sync/paths.js.map +1 -0
  195. package/dist/sync/plan.d.ts +29 -0
  196. package/dist/sync/plan.js +72 -0
  197. package/dist/sync/plan.js.map +1 -0
  198. package/dist/sync/validate.d.ts +26 -0
  199. package/dist/sync/validate.js +308 -0
  200. package/dist/sync/validate.js.map +1 -0
  201. package/dist/types.d.ts +84 -0
  202. package/dist/types.js +3 -0
  203. package/dist/types.js.map +1 -0
  204. package/package.json +143 -0
@@ -0,0 +1,58 @@
1
+ import type { DocsValidationIssue } from './validate.js';
2
+ export declare const AI_MARKDOWN_EXPORT_MANIFEST_FILENAMES: readonly ["index.ai.yml", "index.ai.yaml"];
3
+ export type DocsAiExportHeadingMode = 'normalize' | 'preserve';
4
+ export type DocsAiExportOrphans = 'append' | 'ignore';
5
+ export type DocsAiExportManifest = {
6
+ canonical?: string;
7
+ description?: string;
8
+ exclude: string[];
9
+ headingMode: DocsAiExportHeadingMode;
10
+ order: string[];
11
+ orphans: DocsAiExportOrphans;
12
+ output?: string;
13
+ preamble?: string;
14
+ sourcePath: string;
15
+ title?: string;
16
+ version: 1;
17
+ };
18
+ export type DocsAiExportManifestInput = {
19
+ canonical?: unknown;
20
+ description?: unknown;
21
+ exclude?: unknown;
22
+ headingMode?: unknown;
23
+ order?: unknown;
24
+ orphans?: unknown;
25
+ output?: unknown;
26
+ preamble?: unknown;
27
+ sourcePath?: unknown;
28
+ title?: unknown;
29
+ version?: unknown;
30
+ };
31
+ export type DocsAiExportManifestValidationOptions = {
32
+ knownDocsPaths?: Iterable<string>;
33
+ sourcePath?: string;
34
+ };
35
+ export type DocsAiExportManifestValidationResult = {
36
+ issues: DocsValidationIssue[];
37
+ manifest: DocsAiExportManifest;
38
+ ok: true;
39
+ warnings: DocsValidationIssue[];
40
+ } | {
41
+ issues: DocsValidationIssue[];
42
+ ok: false;
43
+ warnings: DocsValidationIssue[];
44
+ };
45
+ export declare const isAiMarkdownExportManifestPath: (sourcePath: string) => boolean;
46
+ export declare const parseDocsAiExportManifestYaml: ({ content, sourcePath, }: {
47
+ content: string;
48
+ sourcePath: string;
49
+ }) => DocsAiExportManifestValidationResult;
50
+ export declare const validateDocsAiExportManifest: (manifest: unknown, options?: DocsAiExportManifestValidationOptions) => DocsAiExportManifestValidationResult;
51
+ export declare const matchesAiExportExcludePattern: ({ pattern, sourcePath, }: {
52
+ pattern: string;
53
+ sourcePath: string;
54
+ }) => boolean;
55
+ export declare const isExcludedFromAiExport: ({ exclude, sourcePath, }: {
56
+ exclude: string[];
57
+ sourcePath: string;
58
+ }) => boolean;
@@ -0,0 +1,430 @@
1
+ import { normalizeRoutePath } from '../routing/index.js';
2
+ import { normalizeDocsPath } from './paths.js';
3
+ export const AI_MARKDOWN_EXPORT_MANIFEST_FILENAMES = [
4
+ 'index.ai.yml',
5
+ 'index.ai.yaml'
6
+ ];
7
+ const createIssue = ({ message, path })=>({
8
+ code: 'invalid_ai_export_manifest',
9
+ message,
10
+ path
11
+ });
12
+ export const isAiMarkdownExportManifestPath = (sourcePath)=>{
13
+ const normalized = sourcePath.split('\\').join('/').replace(/^\.?\//, '');
14
+ return AI_MARKDOWN_EXPORT_MANIFEST_FILENAMES.includes(normalized);
15
+ };
16
+ const trimComment = (value)=>{
17
+ const commentIndex = value.search(/\s+#/);
18
+ return commentIndex === -1 ? value : value.slice(0, commentIndex).trimEnd();
19
+ };
20
+ const unquote = (value)=>{
21
+ const trimmed = trimComment(value.trim());
22
+ if (trimmed.startsWith('"') && trimmed.endsWith('"') || trimmed.startsWith("'") && trimmed.endsWith("'")) {
23
+ return trimmed.slice(1, -1);
24
+ }
25
+ return trimmed;
26
+ };
27
+ const parseScalar = (value)=>{
28
+ const cleaned = unquote(value);
29
+ if (/^-?\d+$/.test(cleaned)) {
30
+ return Number(cleaned);
31
+ }
32
+ return cleaned;
33
+ };
34
+ const parseInlineArray = (value)=>{
35
+ const cleaned = trimComment(value.trim());
36
+ if (!cleaned.startsWith('[') || !cleaned.endsWith(']')) {
37
+ return undefined;
38
+ }
39
+ const body = cleaned.slice(1, -1).trim();
40
+ if (!body) {
41
+ return [];
42
+ }
43
+ return body.split(',').map((item)=>unquote(item));
44
+ };
45
+ const getTopLevelKeyLine = (line)=>{
46
+ if (/^\s/.test(line)) {
47
+ return undefined;
48
+ }
49
+ const trimmed = line.trimEnd();
50
+ const separatorIndex = trimmed.indexOf(':');
51
+ if (separatorIndex <= 0) {
52
+ return undefined;
53
+ }
54
+ const key = trimmed.slice(0, separatorIndex);
55
+ if (!/^[a-z][a-z0-9]*$/i.test(key)) {
56
+ return undefined;
57
+ }
58
+ return {
59
+ key,
60
+ value: trimmed.slice(separatorIndex + 1).trimStart()
61
+ };
62
+ };
63
+ const stripCommonIndent = (lines)=>{
64
+ const indents = lines.filter((line)=>line.trim() !== '').map((line)=>line.match(/^ */)?.[0].length ?? 0);
65
+ const commonIndent = indents.length > 0 ? Math.min(...indents) : 0;
66
+ return lines.map((line)=>line.slice(commonIndent));
67
+ };
68
+ const stripOuterBlankLines = (lines)=>{
69
+ const stripped = [
70
+ ...lines
71
+ ];
72
+ while(stripped[0]?.trim() === ''){
73
+ stripped.shift();
74
+ }
75
+ while(stripped.at(-1)?.trim() === ''){
76
+ stripped.pop();
77
+ }
78
+ return stripped;
79
+ };
80
+ const foldBlockLines = (lines)=>{
81
+ const paragraphs = [];
82
+ let current = [];
83
+ for (const line of lines){
84
+ if (line.trim() === '') {
85
+ if (current.length > 0) {
86
+ paragraphs.push(current.join(' '));
87
+ current = [];
88
+ }
89
+ paragraphs.push('');
90
+ continue;
91
+ }
92
+ current.push(line.trim());
93
+ }
94
+ if (current.length > 0) {
95
+ paragraphs.push(current.join(' '));
96
+ }
97
+ return paragraphs.join('\n').trim();
98
+ };
99
+ const collectBlock = ({ lines, startIndex, style })=>{
100
+ const blockLines = [];
101
+ let index = startIndex;
102
+ while(index < lines.length){
103
+ const line = lines[index] ?? '';
104
+ if (getTopLevelKeyLine(line)) {
105
+ break;
106
+ }
107
+ blockLines.push(line);
108
+ index += 1;
109
+ }
110
+ const stripped = stripOuterBlankLines(stripCommonIndent(blockLines));
111
+ return {
112
+ nextIndex: index,
113
+ value: style === '|' ? stripped.join('\n').trimEnd() : foldBlockLines(stripped)
114
+ };
115
+ };
116
+ const collectList = ({ lines, startIndex })=>{
117
+ const values = [];
118
+ let index = startIndex;
119
+ let sawList = false;
120
+ while(index < lines.length){
121
+ const line = lines[index] ?? '';
122
+ if (line.trim() === '') {
123
+ index += 1;
124
+ continue;
125
+ }
126
+ if (getTopLevelKeyLine(line)) {
127
+ break;
128
+ }
129
+ const trimmed = line.trimStart();
130
+ const marker = trimmed[0];
131
+ if (marker !== '-' && marker !== '*' || trimmed[1] !== ' ') {
132
+ break;
133
+ }
134
+ sawList = true;
135
+ values.push(unquote(trimmed.slice(2)));
136
+ index += 1;
137
+ }
138
+ return {
139
+ nextIndex: sawList ? index : startIndex,
140
+ values: sawList ? values : undefined
141
+ };
142
+ };
143
+ export const parseDocsAiExportManifestYaml = ({ content, sourcePath })=>{
144
+ const parsed = {
145
+ sourcePath
146
+ };
147
+ const lines = content.replace(/\r\n?/g, '\n').split('\n');
148
+ let index = 0;
149
+ while(index < lines.length){
150
+ const line = lines[index] ?? '';
151
+ if (line.trim() === '' || line.trimStart().startsWith('#')) {
152
+ index += 1;
153
+ continue;
154
+ }
155
+ const keyLine = getTopLevelKeyLine(line);
156
+ if (!keyLine) {
157
+ return {
158
+ issues: [
159
+ createIssue({
160
+ message: `Could not parse AI export manifest line: ${line.trim()}`,
161
+ path: sourcePath
162
+ })
163
+ ],
164
+ ok: false,
165
+ warnings: []
166
+ };
167
+ }
168
+ const rawValue = keyLine.value.trim();
169
+ if (rawValue === '|' || rawValue === '>') {
170
+ const block = collectBlock({
171
+ lines,
172
+ startIndex: index + 1,
173
+ style: rawValue
174
+ });
175
+ parsed[keyLine.key] = block.value;
176
+ index = block.nextIndex;
177
+ continue;
178
+ }
179
+ const inlineArray = parseInlineArray(rawValue);
180
+ if (inlineArray) {
181
+ parsed[keyLine.key] = inlineArray;
182
+ index += 1;
183
+ continue;
184
+ }
185
+ if (rawValue === '') {
186
+ const list = collectList({
187
+ lines,
188
+ startIndex: index + 1
189
+ });
190
+ if (list.values) {
191
+ parsed[keyLine.key] = list.values;
192
+ index = list.nextIndex;
193
+ continue;
194
+ }
195
+ }
196
+ parsed[keyLine.key] = parseScalar(rawValue);
197
+ index += 1;
198
+ }
199
+ return validateDocsAiExportManifest(parsed, {
200
+ sourcePath
201
+ });
202
+ };
203
+ const getOptionalString = ({ issues, key, manifest, path })=>{
204
+ const value = manifest[key];
205
+ if (value === undefined) {
206
+ return undefined;
207
+ }
208
+ if (typeof value === 'string') {
209
+ return value.trim() === '' ? undefined : value;
210
+ }
211
+ issues.push(createIssue({
212
+ message: `AI export manifest field "${key}" must be a string.`,
213
+ path
214
+ }));
215
+ return undefined;
216
+ };
217
+ const getStringArray = ({ issues, key, manifest, path })=>{
218
+ const value = manifest[key];
219
+ if (value === undefined) {
220
+ return [];
221
+ }
222
+ if (Array.isArray(value) && value.every((item)=>typeof item === 'string')) {
223
+ return value;
224
+ }
225
+ issues.push(createIssue({
226
+ message: `AI export manifest field "${key}" must be a list of strings.`,
227
+ path
228
+ }));
229
+ return [];
230
+ };
231
+ const normalizeManifestDocsPath = ({ issues, path, sourcePath })=>{
232
+ const trimmed = path.trim().replace(/\\/g, '/').replace(/^\.\//, '');
233
+ const normalized = normalizeDocsPath(trimmed);
234
+ if (!normalized.ok) {
235
+ issues.push(createIssue({
236
+ message: `AI export manifest order path "${path}" is invalid: ${normalized.message}`,
237
+ path: sourcePath
238
+ }));
239
+ return undefined;
240
+ }
241
+ return normalized.path;
242
+ };
243
+ const normalizeExcludePattern = ({ issues, pattern, sourcePath })=>{
244
+ const trimmed = pattern.trim().replace(/\\/g, '/').replace(/^\.\//, '');
245
+ if (!trimmed || trimmed.includes('..') || trimmed.startsWith('/')) {
246
+ issues.push(createIssue({
247
+ message: `AI export manifest exclude pattern "${pattern}" is invalid.`,
248
+ path: sourcePath
249
+ }));
250
+ return undefined;
251
+ }
252
+ return trimmed;
253
+ };
254
+ const normalizeRouteLikePath = (value)=>{
255
+ if (!value) {
256
+ return undefined;
257
+ }
258
+ if (/^[a-z][a-z0-9+.-]*:\/\//i.test(value)) {
259
+ return value;
260
+ }
261
+ return normalizeRoutePath(value);
262
+ };
263
+ export const validateDocsAiExportManifest = (manifest, options = {})=>{
264
+ const issues = [];
265
+ const warnings = [];
266
+ const sourcePath = options.sourcePath ?? (typeof manifest?.sourcePath === 'string' ? String(manifest.sourcePath) : AI_MARKDOWN_EXPORT_MANIFEST_FILENAMES[0]);
267
+ if (typeof manifest !== 'object' || manifest === null || Array.isArray(manifest)) {
268
+ return {
269
+ issues: [
270
+ createIssue({
271
+ message: 'AI export manifest must be an object.',
272
+ path: sourcePath
273
+ })
274
+ ],
275
+ ok: false,
276
+ warnings
277
+ };
278
+ }
279
+ const input = manifest;
280
+ if (input.version !== 1) {
281
+ issues.push(createIssue({
282
+ message: 'AI export manifest version must be 1.',
283
+ path: sourcePath
284
+ }));
285
+ }
286
+ const orphans = input.orphans === undefined ? 'append' : input.orphans === 'append' || input.orphans === 'ignore' ? input.orphans : undefined;
287
+ if (!orphans) {
288
+ issues.push(createIssue({
289
+ message: 'AI export manifest orphans must be "append" or "ignore".',
290
+ path: sourcePath
291
+ }));
292
+ }
293
+ const headingMode = input.headingMode === undefined ? 'normalize' : input.headingMode === 'normalize' || input.headingMode === 'preserve' ? input.headingMode : undefined;
294
+ if (!headingMode) {
295
+ issues.push(createIssue({
296
+ message: 'AI export manifest headingMode must be "normalize" or "preserve".',
297
+ path: sourcePath
298
+ }));
299
+ }
300
+ const order = getStringArray({
301
+ issues,
302
+ key: 'order',
303
+ manifest: input,
304
+ path: sourcePath
305
+ }).map((item)=>normalizeManifestDocsPath({
306
+ issues,
307
+ path: item,
308
+ sourcePath
309
+ })).filter((item)=>item !== undefined);
310
+ const exclude = getStringArray({
311
+ issues,
312
+ key: 'exclude',
313
+ manifest: input,
314
+ path: sourcePath
315
+ }).map((item)=>normalizeExcludePattern({
316
+ issues,
317
+ pattern: item,
318
+ sourcePath
319
+ })).filter((item)=>item !== undefined);
320
+ const knownDocsPaths = options.knownDocsPaths ? new Set(options.knownDocsPaths) : undefined;
321
+ if (knownDocsPaths) {
322
+ for (const orderedPath of order){
323
+ if (!knownDocsPaths.has(orderedPath)) {
324
+ warnings.push({
325
+ code: 'missing_ai_export_order_path',
326
+ message: `AI export manifest order path "${orderedPath}" does not exist in the docs files.`,
327
+ path: sourcePath
328
+ });
329
+ }
330
+ }
331
+ }
332
+ const title = getOptionalString({
333
+ issues,
334
+ key: 'title',
335
+ manifest: input,
336
+ path: sourcePath
337
+ });
338
+ const canonical = normalizeRouteLikePath(getOptionalString({
339
+ issues,
340
+ key: 'canonical',
341
+ manifest: input,
342
+ path: sourcePath
343
+ }));
344
+ const output = normalizeRouteLikePath(getOptionalString({
345
+ issues,
346
+ key: 'output',
347
+ manifest: input,
348
+ path: sourcePath
349
+ }));
350
+ const description = getOptionalString({
351
+ issues,
352
+ key: 'description',
353
+ manifest: input,
354
+ path: sourcePath
355
+ });
356
+ const preamble = getOptionalString({
357
+ issues,
358
+ key: 'preamble',
359
+ manifest: input,
360
+ path: sourcePath
361
+ });
362
+ if (issues.length > 0 || !orphans || !headingMode) {
363
+ return {
364
+ issues,
365
+ ok: false,
366
+ warnings
367
+ };
368
+ }
369
+ return {
370
+ issues,
371
+ manifest: {
372
+ ...canonical ? {
373
+ canonical
374
+ } : {},
375
+ ...description ? {
376
+ description
377
+ } : {},
378
+ exclude,
379
+ headingMode,
380
+ order,
381
+ orphans,
382
+ ...output ? {
383
+ output
384
+ } : {},
385
+ ...preamble ? {
386
+ preamble
387
+ } : {},
388
+ sourcePath,
389
+ ...title ? {
390
+ title
391
+ } : {},
392
+ version: 1
393
+ },
394
+ ok: true,
395
+ warnings
396
+ };
397
+ };
398
+ const escapeRegex = (value)=>value.replace(/[|\\{}()[\]^$+?.]/g, '\\$&');
399
+ const globPatternToRegex = (pattern)=>{
400
+ let regex = '^';
401
+ for(let index = 0; index < pattern.length; index += 1){
402
+ const char = pattern[index];
403
+ const next = pattern[index + 1];
404
+ if (char === '*' && next === '*') {
405
+ regex += '.*';
406
+ index += 1;
407
+ continue;
408
+ }
409
+ if (char === '*') {
410
+ regex += '[^/]*';
411
+ continue;
412
+ }
413
+ regex += escapeRegex(char ?? '');
414
+ }
415
+ return new RegExp(`${regex}$`);
416
+ };
417
+ export const matchesAiExportExcludePattern = ({ pattern, sourcePath })=>{
418
+ const normalizedPattern = pattern.replace(/^\.\//, '');
419
+ const normalizedSourcePath = sourcePath.replace(/^\.\//, '');
420
+ if (!normalizedPattern.includes('*')) {
421
+ return normalizedPattern === normalizedSourcePath;
422
+ }
423
+ return globPatternToRegex(normalizedPattern).test(normalizedSourcePath);
424
+ };
425
+ export const isExcludedFromAiExport = ({ exclude, sourcePath })=>isAiMarkdownExportManifestPath(sourcePath) || exclude.some((pattern)=>matchesAiExportExcludePattern({
426
+ pattern,
427
+ sourcePath
428
+ }));
429
+
430
+ //# sourceMappingURL=aiExportManifest.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/sync/aiExportManifest.ts"],"sourcesContent":["import type { DocsValidationIssue } from './validate.js'\n\nimport { normalizeRoutePath } from '../routing/index.js'\nimport { normalizeDocsPath } from './paths.js'\n\nexport const AI_MARKDOWN_EXPORT_MANIFEST_FILENAMES = [\n 'index.ai.yml',\n 'index.ai.yaml',\n] as const\n\nexport type DocsAiExportHeadingMode = 'normalize' | 'preserve'\n\nexport type DocsAiExportOrphans = 'append' | 'ignore'\n\nexport type DocsAiExportManifest = {\n canonical?: string\n description?: string\n exclude: string[]\n headingMode: DocsAiExportHeadingMode\n order: string[]\n orphans: DocsAiExportOrphans\n output?: string\n preamble?: string\n sourcePath: string\n title?: string\n version: 1\n}\n\nexport type DocsAiExportManifestInput = {\n canonical?: unknown\n description?: unknown\n exclude?: unknown\n headingMode?: unknown\n order?: unknown\n orphans?: unknown\n output?: unknown\n preamble?: unknown\n sourcePath?: unknown\n title?: unknown\n version?: unknown\n}\n\nexport type DocsAiExportManifestValidationOptions = {\n knownDocsPaths?: Iterable<string>\n sourcePath?: string\n}\n\nexport type DocsAiExportManifestValidationResult =\n | {\n issues: DocsValidationIssue[]\n manifest: DocsAiExportManifest\n ok: true\n warnings: DocsValidationIssue[]\n }\n | {\n issues: DocsValidationIssue[]\n ok: false\n warnings: DocsValidationIssue[]\n }\n\nconst createIssue = ({\n message,\n path,\n}: {\n message: string\n path?: string\n}): DocsValidationIssue => ({\n code: 'invalid_ai_export_manifest',\n message,\n path,\n})\n\nexport const isAiMarkdownExportManifestPath = (sourcePath: string): boolean => {\n const normalized = sourcePath.split('\\\\').join('/').replace(/^\\.?\\//, '')\n\n return AI_MARKDOWN_EXPORT_MANIFEST_FILENAMES.includes(\n normalized as (typeof AI_MARKDOWN_EXPORT_MANIFEST_FILENAMES)[number],\n )\n}\n\nconst trimComment = (value: string): string => {\n const commentIndex = value.search(/\\s+#/)\n\n return commentIndex === -1 ? value : value.slice(0, commentIndex).trimEnd()\n}\n\nconst unquote = (value: string): string => {\n const trimmed = trimComment(value.trim())\n\n if (\n (trimmed.startsWith('\"') && trimmed.endsWith('\"')) ||\n (trimmed.startsWith(\"'\") && trimmed.endsWith(\"'\"))\n ) {\n return trimmed.slice(1, -1)\n }\n\n return trimmed\n}\n\nconst parseScalar = (value: string): unknown => {\n const cleaned = unquote(value)\n\n if (/^-?\\d+$/.test(cleaned)) {\n return Number(cleaned)\n }\n\n return cleaned\n}\n\nconst parseInlineArray = (value: string): string[] | undefined => {\n const cleaned = trimComment(value.trim())\n\n if (!cleaned.startsWith('[') || !cleaned.endsWith(']')) {\n return undefined\n }\n\n const body = cleaned.slice(1, -1).trim()\n\n if (!body) {\n return []\n }\n\n return body.split(',').map((item) => unquote(item))\n}\n\nconst getTopLevelKeyLine = (\n line: string,\n): { key: string; value: string } | undefined => {\n if (/^\\s/.test(line)) {\n return undefined\n }\n\n const trimmed = line.trimEnd()\n const separatorIndex = trimmed.indexOf(':')\n\n if (separatorIndex <= 0) {\n return undefined\n }\n\n const key = trimmed.slice(0, separatorIndex)\n\n if (!/^[a-z][a-z0-9]*$/i.test(key)) {\n return undefined\n }\n\n return {\n key,\n value: trimmed.slice(separatorIndex + 1).trimStart(),\n }\n}\n\nconst stripCommonIndent = (lines: string[]): string[] => {\n const indents = lines\n .filter((line) => line.trim() !== '')\n .map((line) => line.match(/^ */)?.[0].length ?? 0)\n const commonIndent = indents.length > 0 ? Math.min(...indents) : 0\n\n return lines.map((line) => line.slice(commonIndent))\n}\n\nconst stripOuterBlankLines = (lines: string[]): string[] => {\n const stripped = [...lines]\n\n while (stripped[0]?.trim() === '') {\n stripped.shift()\n }\n\n while (stripped.at(-1)?.trim() === '') {\n stripped.pop()\n }\n\n return stripped\n}\n\nconst foldBlockLines = (lines: string[]): string => {\n const paragraphs: string[] = []\n let current: string[] = []\n\n for (const line of lines) {\n if (line.trim() === '') {\n if (current.length > 0) {\n paragraphs.push(current.join(' '))\n current = []\n }\n paragraphs.push('')\n continue\n }\n\n current.push(line.trim())\n }\n\n if (current.length > 0) {\n paragraphs.push(current.join(' '))\n }\n\n return paragraphs.join('\\n').trim()\n}\n\nconst collectBlock = ({\n lines,\n startIndex,\n style,\n}: {\n lines: string[]\n startIndex: number\n style: '>' | '|'\n}): {\n nextIndex: number\n value: string\n} => {\n const blockLines: string[] = []\n let index = startIndex\n\n while (index < lines.length) {\n const line = lines[index] ?? ''\n\n if (getTopLevelKeyLine(line)) {\n break\n }\n\n blockLines.push(line)\n index += 1\n }\n\n const stripped = stripOuterBlankLines(stripCommonIndent(blockLines))\n\n return {\n nextIndex: index,\n value: style === '|' ? stripped.join('\\n').trimEnd() : foldBlockLines(stripped),\n }\n}\n\nconst collectList = ({\n lines,\n startIndex,\n}: {\n lines: string[]\n startIndex: number\n}): {\n nextIndex: number\n values?: string[]\n} => {\n const values: string[] = []\n let index = startIndex\n let sawList = false\n\n while (index < lines.length) {\n const line = lines[index] ?? ''\n\n if (line.trim() === '') {\n index += 1\n continue\n }\n\n if (getTopLevelKeyLine(line)) {\n break\n }\n\n const trimmed = line.trimStart()\n const marker = trimmed[0]\n\n if ((marker !== '-' && marker !== '*') || trimmed[1] !== ' ') {\n break\n }\n\n sawList = true\n values.push(unquote(trimmed.slice(2)))\n index += 1\n }\n\n return {\n nextIndex: sawList ? index : startIndex,\n values: sawList ? values : undefined,\n }\n}\n\nexport const parseDocsAiExportManifestYaml = ({\n content,\n sourcePath,\n}: {\n content: string\n sourcePath: string\n}): DocsAiExportManifestValidationResult => {\n const parsed: Record<string, unknown> = {\n sourcePath,\n }\n const lines = content.replace(/\\r\\n?/g, '\\n').split('\\n')\n let index = 0\n\n while (index < lines.length) {\n const line = lines[index] ?? ''\n\n if (line.trim() === '' || line.trimStart().startsWith('#')) {\n index += 1\n continue\n }\n\n const keyLine = getTopLevelKeyLine(line)\n\n if (!keyLine) {\n return {\n issues: [\n createIssue({\n message: `Could not parse AI export manifest line: ${line.trim()}`,\n path: sourcePath,\n }),\n ],\n ok: false,\n warnings: [],\n }\n }\n\n const rawValue = keyLine.value.trim()\n\n if (rawValue === '|' || rawValue === '>') {\n const block = collectBlock({\n lines,\n startIndex: index + 1,\n style: rawValue,\n })\n\n parsed[keyLine.key] = block.value\n index = block.nextIndex\n continue\n }\n\n const inlineArray = parseInlineArray(rawValue)\n\n if (inlineArray) {\n parsed[keyLine.key] = inlineArray\n index += 1\n continue\n }\n\n if (rawValue === '') {\n const list = collectList({\n lines,\n startIndex: index + 1,\n })\n\n if (list.values) {\n parsed[keyLine.key] = list.values\n index = list.nextIndex\n continue\n }\n }\n\n parsed[keyLine.key] = parseScalar(rawValue)\n index += 1\n }\n\n return validateDocsAiExportManifest(parsed, {\n sourcePath,\n })\n}\n\nconst getOptionalString = ({\n issues,\n key,\n manifest,\n path,\n}: {\n issues: DocsValidationIssue[]\n key: keyof DocsAiExportManifestInput\n manifest: DocsAiExportManifestInput\n path?: string\n}): string | undefined => {\n const value = manifest[key]\n\n if (value === undefined) {\n return undefined\n }\n\n if (typeof value === 'string') {\n return value.trim() === '' ? undefined : value\n }\n\n issues.push(\n createIssue({\n message: `AI export manifest field \"${key}\" must be a string.`,\n path,\n }),\n )\n\n return undefined\n}\n\nconst getStringArray = ({\n issues,\n key,\n manifest,\n path,\n}: {\n issues: DocsValidationIssue[]\n key: 'exclude' | 'order'\n manifest: DocsAiExportManifestInput\n path?: string\n}): string[] => {\n const value = manifest[key]\n\n if (value === undefined) {\n return []\n }\n\n if (Array.isArray(value) && value.every((item) => typeof item === 'string')) {\n return value\n }\n\n issues.push(\n createIssue({\n message: `AI export manifest field \"${key}\" must be a list of strings.`,\n path,\n }),\n )\n\n return []\n}\n\nconst normalizeManifestDocsPath = ({\n issues,\n path,\n sourcePath,\n}: {\n issues: DocsValidationIssue[]\n path: string\n sourcePath?: string\n}): string | undefined => {\n const trimmed = path.trim().replace(/\\\\/g, '/').replace(/^\\.\\//, '')\n const normalized = normalizeDocsPath(trimmed)\n\n if (!normalized.ok) {\n issues.push(\n createIssue({\n message: `AI export manifest order path \"${path}\" is invalid: ${normalized.message}`,\n path: sourcePath,\n }),\n )\n return undefined\n }\n\n return normalized.path\n}\n\nconst normalizeExcludePattern = ({\n issues,\n pattern,\n sourcePath,\n}: {\n issues: DocsValidationIssue[]\n pattern: string\n sourcePath?: string\n}): string | undefined => {\n const trimmed = pattern.trim().replace(/\\\\/g, '/').replace(/^\\.\\//, '')\n\n if (!trimmed || trimmed.includes('..') || trimmed.startsWith('/')) {\n issues.push(\n createIssue({\n message: `AI export manifest exclude pattern \"${pattern}\" is invalid.`,\n path: sourcePath,\n }),\n )\n return undefined\n }\n\n return trimmed\n}\n\nconst normalizeRouteLikePath = (value: string | undefined): string | undefined => {\n if (!value) {\n return undefined\n }\n\n if (/^[a-z][a-z0-9+.-]*:\\/\\//i.test(value)) {\n return value\n }\n\n return normalizeRoutePath(value)\n}\n\nexport const validateDocsAiExportManifest = (\n manifest: unknown,\n options: DocsAiExportManifestValidationOptions = {},\n): DocsAiExportManifestValidationResult => {\n const issues: DocsValidationIssue[] = []\n const warnings: DocsValidationIssue[] = []\n const sourcePath =\n options.sourcePath ??\n (typeof (manifest as DocsAiExportManifestInput | undefined)?.sourcePath === 'string'\n ? String((manifest as DocsAiExportManifestInput).sourcePath)\n : AI_MARKDOWN_EXPORT_MANIFEST_FILENAMES[0])\n\n if (typeof manifest !== 'object' || manifest === null || Array.isArray(manifest)) {\n return {\n issues: [\n createIssue({\n message: 'AI export manifest must be an object.',\n path: sourcePath,\n }),\n ],\n ok: false,\n warnings,\n }\n }\n\n const input = manifest as DocsAiExportManifestInput\n\n if (input.version !== 1) {\n issues.push(\n createIssue({\n message: 'AI export manifest version must be 1.',\n path: sourcePath,\n }),\n )\n }\n\n const orphans =\n input.orphans === undefined\n ? 'append'\n : input.orphans === 'append' || input.orphans === 'ignore'\n ? input.orphans\n : undefined\n\n if (!orphans) {\n issues.push(\n createIssue({\n message: 'AI export manifest orphans must be \"append\" or \"ignore\".',\n path: sourcePath,\n }),\n )\n }\n\n const headingMode =\n input.headingMode === undefined\n ? 'normalize'\n : input.headingMode === 'normalize' || input.headingMode === 'preserve'\n ? input.headingMode\n : undefined\n\n if (!headingMode) {\n issues.push(\n createIssue({\n message:\n 'AI export manifest headingMode must be \"normalize\" or \"preserve\".',\n path: sourcePath,\n }),\n )\n }\n\n const order = getStringArray({\n issues,\n key: 'order',\n manifest: input,\n path: sourcePath,\n })\n .map((item) =>\n normalizeManifestDocsPath({\n issues,\n path: item,\n sourcePath,\n }),\n )\n .filter((item): item is string => item !== undefined)\n const exclude = getStringArray({\n issues,\n key: 'exclude',\n manifest: input,\n path: sourcePath,\n })\n .map((item) =>\n normalizeExcludePattern({\n issues,\n pattern: item,\n sourcePath,\n }),\n )\n .filter((item): item is string => item !== undefined)\n const knownDocsPaths = options.knownDocsPaths\n ? new Set(options.knownDocsPaths)\n : undefined\n\n if (knownDocsPaths) {\n for (const orderedPath of order) {\n if (!knownDocsPaths.has(orderedPath)) {\n warnings.push({\n code: 'missing_ai_export_order_path',\n message: `AI export manifest order path \"${orderedPath}\" does not exist in the docs files.`,\n path: sourcePath,\n })\n }\n }\n }\n\n const title = getOptionalString({\n issues,\n key: 'title',\n manifest: input,\n path: sourcePath,\n })\n const canonical = normalizeRouteLikePath(\n getOptionalString({\n issues,\n key: 'canonical',\n manifest: input,\n path: sourcePath,\n }),\n )\n const output = normalizeRouteLikePath(\n getOptionalString({\n issues,\n key: 'output',\n manifest: input,\n path: sourcePath,\n }),\n )\n const description = getOptionalString({\n issues,\n key: 'description',\n manifest: input,\n path: sourcePath,\n })\n const preamble = getOptionalString({\n issues,\n key: 'preamble',\n manifest: input,\n path: sourcePath,\n })\n\n if (issues.length > 0 || !orphans || !headingMode) {\n return {\n issues,\n ok: false,\n warnings,\n }\n }\n\n return {\n issues,\n manifest: {\n ...(canonical ? { canonical } : {}),\n ...(description ? { description } : {}),\n exclude,\n headingMode,\n order,\n orphans,\n ...(output ? { output } : {}),\n ...(preamble ? { preamble } : {}),\n sourcePath,\n ...(title ? { title } : {}),\n version: 1,\n },\n ok: true,\n warnings,\n }\n}\n\nconst escapeRegex = (value: string): string =>\n value.replace(/[|\\\\{}()[\\]^$+?.]/g, '\\\\$&')\n\nconst globPatternToRegex = (pattern: string): RegExp => {\n let regex = '^'\n\n for (let index = 0; index < pattern.length; index += 1) {\n const char = pattern[index]\n const next = pattern[index + 1]\n\n if (char === '*' && next === '*') {\n regex += '.*'\n index += 1\n continue\n }\n\n if (char === '*') {\n regex += '[^/]*'\n continue\n }\n\n regex += escapeRegex(char ?? '')\n }\n\n return new RegExp(`${regex}$`)\n}\n\nexport const matchesAiExportExcludePattern = ({\n pattern,\n sourcePath,\n}: {\n pattern: string\n sourcePath: string\n}): boolean => {\n const normalizedPattern = pattern.replace(/^\\.\\//, '')\n const normalizedSourcePath = sourcePath.replace(/^\\.\\//, '')\n\n if (!normalizedPattern.includes('*')) {\n return normalizedPattern === normalizedSourcePath\n }\n\n return globPatternToRegex(normalizedPattern).test(normalizedSourcePath)\n}\n\nexport const isExcludedFromAiExport = ({\n exclude,\n sourcePath,\n}: {\n exclude: string[]\n sourcePath: string\n}): boolean =>\n isAiMarkdownExportManifestPath(sourcePath) ||\n exclude.some((pattern) =>\n matchesAiExportExcludePattern({\n pattern,\n sourcePath,\n }),\n )\n"],"names":["normalizeRoutePath","normalizeDocsPath","AI_MARKDOWN_EXPORT_MANIFEST_FILENAMES","createIssue","message","path","code","isAiMarkdownExportManifestPath","sourcePath","normalized","split","join","replace","includes","trimComment","value","commentIndex","search","slice","trimEnd","unquote","trimmed","trim","startsWith","endsWith","parseScalar","cleaned","test","Number","parseInlineArray","undefined","body","map","item","getTopLevelKeyLine","line","separatorIndex","indexOf","key","trimStart","stripCommonIndent","lines","indents","filter","match","length","commonIndent","Math","min","stripOuterBlankLines","stripped","shift","at","pop","foldBlockLines","paragraphs","current","push","collectBlock","startIndex","style","blockLines","index","nextIndex","collectList","values","sawList","marker","parseDocsAiExportManifestYaml","content","parsed","keyLine","issues","ok","warnings","rawValue","block","inlineArray","list","validateDocsAiExportManifest","getOptionalString","manifest","getStringArray","Array","isArray","every","normalizeManifestDocsPath","normalizeExcludePattern","pattern","normalizeRouteLikePath","options","String","input","version","orphans","headingMode","order","exclude","knownDocsPaths","Set","orderedPath","has","title","canonical","output","description","preamble","escapeRegex","globPatternToRegex","regex","char","next","RegExp","matchesAiExportExcludePattern","normalizedPattern","normalizedSourcePath","isExcludedFromAiExport","some"],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ import type { DocsValidationIssue } from './validate.js';
2
+ export type DocsFrontmatter = {
3
+ description?: string;
4
+ draft?: boolean;
5
+ navTitle?: string;
6
+ order?: number;
7
+ redirectFrom?: string[];
8
+ slug?: string;
9
+ status?: 'draft' | 'published';
10
+ tags?: string[];
11
+ title?: string;
12
+ };
13
+ export type ParseDocsFrontmatterResult = {
14
+ content: string;
15
+ frontmatter: DocsFrontmatter;
16
+ issues: DocsValidationIssue[];
17
+ warnings: DocsValidationIssue[];
18
+ };
19
+ export declare const parseDocsFrontmatter: (markdown: string, options?: {
20
+ path?: string;
21
+ }) => ParseDocsFrontmatterResult;
22
+ export declare const inferTitleFromMarkdown: (content: string) => string | undefined;
23
+ export declare const titleFromSourcePath: (sourcePath: string) => string;
24
+ export declare const resolveDocsTitle: ({ content, frontmatter, sourcePath, }: {
25
+ content: string;
26
+ frontmatter: DocsFrontmatter;
27
+ sourcePath: string;
28
+ }) => string;