@lepid-labs/weft-core 0.1.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 (266) hide show
  1. package/LICENSE +21 -0
  2. package/dist/anchors/__tests__/markdown.test.d.ts +2 -0
  3. package/dist/anchors/__tests__/markdown.test.d.ts.map +1 -0
  4. package/dist/anchors/__tests__/markdown.test.js +130 -0
  5. package/dist/anchors/__tests__/markdown.test.js.map +1 -0
  6. package/dist/anchors/__tests__/openapi.test.d.ts +2 -0
  7. package/dist/anchors/__tests__/openapi.test.d.ts.map +1 -0
  8. package/dist/anchors/__tests__/openapi.test.js +115 -0
  9. package/dist/anchors/__tests__/openapi.test.js.map +1 -0
  10. package/dist/anchors/index.d.ts +35 -0
  11. package/dist/anchors/index.d.ts.map +1 -0
  12. package/dist/anchors/index.js +68 -0
  13. package/dist/anchors/index.js.map +1 -0
  14. package/dist/anchors/markdown.d.ts +15 -0
  15. package/dist/anchors/markdown.d.ts.map +1 -0
  16. package/dist/anchors/markdown.js +71 -0
  17. package/dist/anchors/markdown.js.map +1 -0
  18. package/dist/anchors/openapi.d.ts +24 -0
  19. package/dist/anchors/openapi.d.ts.map +1 -0
  20. package/dist/anchors/openapi.js +75 -0
  21. package/dist/anchors/openapi.js.map +1 -0
  22. package/dist/browser.d.ts +10 -0
  23. package/dist/browser.d.ts.map +1 -0
  24. package/dist/browser.js +8 -0
  25. package/dist/browser.js.map +1 -0
  26. package/dist/config.d.ts +47 -0
  27. package/dist/config.d.ts.map +1 -0
  28. package/dist/config.js +393 -0
  29. package/dist/config.js.map +1 -0
  30. package/dist/config.test.d.ts +2 -0
  31. package/dist/config.test.d.ts.map +1 -0
  32. package/dist/config.test.js +454 -0
  33. package/dist/config.test.js.map +1 -0
  34. package/dist/content.d.ts +37 -0
  35. package/dist/content.d.ts.map +1 -0
  36. package/dist/content.js +57 -0
  37. package/dist/content.js.map +1 -0
  38. package/dist/content.test.d.ts +2 -0
  39. package/dist/content.test.d.ts.map +1 -0
  40. package/dist/content.test.js +100 -0
  41. package/dist/content.test.js.map +1 -0
  42. package/dist/contributions.d.ts +64 -0
  43. package/dist/contributions.d.ts.map +1 -0
  44. package/dist/contributions.js +184 -0
  45. package/dist/contributions.js.map +1 -0
  46. package/dist/contributions.test.d.ts +2 -0
  47. package/dist/contributions.test.d.ts.map +1 -0
  48. package/dist/contributions.test.js +202 -0
  49. package/dist/contributions.test.js.map +1 -0
  50. package/dist/fetch/auth.d.ts +15 -0
  51. package/dist/fetch/auth.d.ts.map +1 -0
  52. package/dist/fetch/auth.js +38 -0
  53. package/dist/fetch/auth.js.map +1 -0
  54. package/dist/fetch/cache.d.ts +25 -0
  55. package/dist/fetch/cache.d.ts.map +1 -0
  56. package/dist/fetch/cache.js +68 -0
  57. package/dist/fetch/cache.js.map +1 -0
  58. package/dist/fetch/cache.test.d.ts +2 -0
  59. package/dist/fetch/cache.test.d.ts.map +1 -0
  60. package/dist/fetch/cache.test.js +73 -0
  61. package/dist/fetch/cache.test.js.map +1 -0
  62. package/dist/fetch/clone.d.ts +26 -0
  63. package/dist/fetch/clone.d.ts.map +1 -0
  64. package/dist/fetch/clone.js +105 -0
  65. package/dist/fetch/clone.js.map +1 -0
  66. package/dist/fetch/fetch.test.d.ts +2 -0
  67. package/dist/fetch/fetch.test.d.ts.map +1 -0
  68. package/dist/fetch/fetch.test.js +167 -0
  69. package/dist/fetch/fetch.test.js.map +1 -0
  70. package/dist/fetch/resolve.d.ts +34 -0
  71. package/dist/fetch/resolve.d.ts.map +1 -0
  72. package/dist/fetch/resolve.js +59 -0
  73. package/dist/fetch/resolve.js.map +1 -0
  74. package/dist/freshness.d.ts +29 -0
  75. package/dist/freshness.d.ts.map +1 -0
  76. package/dist/freshness.js +170 -0
  77. package/dist/freshness.js.map +1 -0
  78. package/dist/freshness.test.d.ts +2 -0
  79. package/dist/freshness.test.d.ts.map +1 -0
  80. package/dist/freshness.test.js +209 -0
  81. package/dist/freshness.test.js.map +1 -0
  82. package/dist/frontmatter.d.ts +15 -0
  83. package/dist/frontmatter.d.ts.map +1 -0
  84. package/dist/frontmatter.js +24 -0
  85. package/dist/frontmatter.js.map +1 -0
  86. package/dist/frontmatter.test.d.ts +2 -0
  87. package/dist/frontmatter.test.d.ts.map +1 -0
  88. package/dist/frontmatter.test.js +54 -0
  89. package/dist/frontmatter.test.js.map +1 -0
  90. package/dist/git.d.ts +55 -0
  91. package/dist/git.d.ts.map +1 -0
  92. package/dist/git.js +127 -0
  93. package/dist/git.js.map +1 -0
  94. package/dist/git.test.d.ts +2 -0
  95. package/dist/git.test.d.ts.map +1 -0
  96. package/dist/git.test.js +198 -0
  97. package/dist/git.test.js.map +1 -0
  98. package/dist/includes.d.ts +53 -0
  99. package/dist/includes.d.ts.map +1 -0
  100. package/dist/includes.js +73 -0
  101. package/dist/includes.js.map +1 -0
  102. package/dist/includes.test.d.ts +2 -0
  103. package/dist/includes.test.d.ts.map +1 -0
  104. package/dist/includes.test.js +106 -0
  105. package/dist/includes.test.js.map +1 -0
  106. package/dist/index.d.ts +33 -0
  107. package/dist/index.d.ts.map +1 -0
  108. package/dist/index.js +23 -0
  109. package/dist/index.js.map +1 -0
  110. package/dist/links/__tests__/markdown.test.d.ts +2 -0
  111. package/dist/links/__tests__/markdown.test.d.ts.map +1 -0
  112. package/dist/links/__tests__/markdown.test.js +173 -0
  113. package/dist/links/__tests__/markdown.test.js.map +1 -0
  114. package/dist/links/__tests__/sidecar.test.d.ts +2 -0
  115. package/dist/links/__tests__/sidecar.test.d.ts.map +1 -0
  116. package/dist/links/__tests__/sidecar.test.js +238 -0
  117. package/dist/links/__tests__/sidecar.test.js.map +1 -0
  118. package/dist/links/index.d.ts +3 -0
  119. package/dist/links/index.d.ts.map +1 -0
  120. package/dist/links/index.js +3 -0
  121. package/dist/links/index.js.map +1 -0
  122. package/dist/links/markdown.d.ts +13 -0
  123. package/dist/links/markdown.d.ts.map +1 -0
  124. package/dist/links/markdown.js +93 -0
  125. package/dist/links/markdown.js.map +1 -0
  126. package/dist/links/sidecar.d.ts +12 -0
  127. package/dist/links/sidecar.d.ts.map +1 -0
  128. package/dist/links/sidecar.js +88 -0
  129. package/dist/links/sidecar.js.map +1 -0
  130. package/dist/manifest.d.ts +45 -0
  131. package/dist/manifest.d.ts.map +1 -0
  132. package/dist/manifest.js +269 -0
  133. package/dist/manifest.js.map +1 -0
  134. package/dist/manifest.test.d.ts +2 -0
  135. package/dist/manifest.test.d.ts.map +1 -0
  136. package/dist/manifest.test.js +625 -0
  137. package/dist/manifest.test.js.map +1 -0
  138. package/dist/multi-repo.test.d.ts +2 -0
  139. package/dist/multi-repo.test.d.ts.map +1 -0
  140. package/dist/multi-repo.test.js +179 -0
  141. package/dist/multi-repo.test.js.map +1 -0
  142. package/dist/node-path.d.ts +13 -0
  143. package/dist/node-path.d.ts.map +1 -0
  144. package/dist/node-path.js +21 -0
  145. package/dist/node-path.js.map +1 -0
  146. package/dist/node-path.test.d.ts +2 -0
  147. package/dist/node-path.test.d.ts.map +1 -0
  148. package/dist/node-path.test.js +29 -0
  149. package/dist/node-path.test.js.map +1 -0
  150. package/dist/published-links.d.ts +16 -0
  151. package/dist/published-links.d.ts.map +1 -0
  152. package/dist/published-links.js +59 -0
  153. package/dist/published-links.js.map +1 -0
  154. package/dist/published-links.test.d.ts +2 -0
  155. package/dist/published-links.test.d.ts.map +1 -0
  156. package/dist/published-links.test.js +82 -0
  157. package/dist/published-links.test.js.map +1 -0
  158. package/dist/repos.d.ts +32 -0
  159. package/dist/repos.d.ts.map +1 -0
  160. package/dist/repos.js +46 -0
  161. package/dist/repos.js.map +1 -0
  162. package/dist/repos.test.d.ts +2 -0
  163. package/dist/repos.test.d.ts.map +1 -0
  164. package/dist/repos.test.js +61 -0
  165. package/dist/repos.test.js.map +1 -0
  166. package/dist/scalar-source.d.ts +15 -0
  167. package/dist/scalar-source.d.ts.map +1 -0
  168. package/dist/scalar-source.js +21 -0
  169. package/dist/scalar-source.js.map +1 -0
  170. package/dist/search.d.ts +14 -0
  171. package/dist/search.d.ts.map +1 -0
  172. package/dist/search.js +59 -0
  173. package/dist/search.js.map +1 -0
  174. package/dist/service-concurrency.test.d.ts +2 -0
  175. package/dist/service-concurrency.test.d.ts.map +1 -0
  176. package/dist/service-concurrency.test.js +89 -0
  177. package/dist/service-concurrency.test.js.map +1 -0
  178. package/dist/service-history.test.d.ts +2 -0
  179. package/dist/service-history.test.d.ts.map +1 -0
  180. package/dist/service-history.test.js +76 -0
  181. package/dist/service-history.test.js.map +1 -0
  182. package/dist/service.d.ts +118 -0
  183. package/dist/service.d.ts.map +1 -0
  184. package/dist/service.js +347 -0
  185. package/dist/service.js.map +1 -0
  186. package/dist/service.test.d.ts +2 -0
  187. package/dist/service.test.d.ts.map +1 -0
  188. package/dist/service.test.js +313 -0
  189. package/dist/service.test.js.map +1 -0
  190. package/dist/types.d.ts +403 -0
  191. package/dist/types.d.ts.map +1 -0
  192. package/dist/types.js +2 -0
  193. package/dist/types.js.map +1 -0
  194. package/dist/validate/__tests__/artifacts.test.d.ts +2 -0
  195. package/dist/validate/__tests__/artifacts.test.d.ts.map +1 -0
  196. package/dist/validate/__tests__/artifacts.test.js +167 -0
  197. package/dist/validate/__tests__/artifacts.test.js.map +1 -0
  198. package/dist/validate/__tests__/assertions.test.d.ts +2 -0
  199. package/dist/validate/__tests__/assertions.test.d.ts.map +1 -0
  200. package/dist/validate/__tests__/assertions.test.js +254 -0
  201. package/dist/validate/__tests__/assertions.test.js.map +1 -0
  202. package/dist/validate/__tests__/duplicates.test.d.ts +2 -0
  203. package/dist/validate/__tests__/duplicates.test.d.ts.map +1 -0
  204. package/dist/validate/__tests__/duplicates.test.js +130 -0
  205. package/dist/validate/__tests__/duplicates.test.js.map +1 -0
  206. package/dist/validate/__tests__/edge-resolution.test.d.ts +2 -0
  207. package/dist/validate/__tests__/edge-resolution.test.d.ts.map +1 -0
  208. package/dist/validate/__tests__/edge-resolution.test.js +279 -0
  209. package/dist/validate/__tests__/edge-resolution.test.js.map +1 -0
  210. package/dist/validate/__tests__/history.test.d.ts +2 -0
  211. package/dist/validate/__tests__/history.test.d.ts.map +1 -0
  212. package/dist/validate/__tests__/history.test.js +93 -0
  213. package/dist/validate/__tests__/history.test.js.map +1 -0
  214. package/dist/validate/__tests__/includes.test.d.ts +2 -0
  215. package/dist/validate/__tests__/includes.test.d.ts.map +1 -0
  216. package/dist/validate/__tests__/includes.test.js +93 -0
  217. package/dist/validate/__tests__/includes.test.js.map +1 -0
  218. package/dist/validate/__tests__/registry.test.d.ts +2 -0
  219. package/dist/validate/__tests__/registry.test.d.ts.map +1 -0
  220. package/dist/validate/__tests__/registry.test.js +78 -0
  221. package/dist/validate/__tests__/registry.test.js.map +1 -0
  222. package/dist/validate/__tests__/run.test.d.ts +2 -0
  223. package/dist/validate/__tests__/run.test.d.ts.map +1 -0
  224. package/dist/validate/__tests__/run.test.js +215 -0
  225. package/dist/validate/__tests__/run.test.js.map +1 -0
  226. package/dist/validate/history.d.ts +23 -0
  227. package/dist/validate/history.d.ts.map +1 -0
  228. package/dist/validate/history.js +45 -0
  229. package/dist/validate/history.js.map +1 -0
  230. package/dist/validate/index.d.ts +10 -0
  231. package/dist/validate/index.d.ts.map +1 -0
  232. package/dist/validate/index.js +9 -0
  233. package/dist/validate/index.js.map +1 -0
  234. package/dist/validate/registry.d.ts +27 -0
  235. package/dist/validate/registry.d.ts.map +1 -0
  236. package/dist/validate/registry.js +67 -0
  237. package/dist/validate/registry.js.map +1 -0
  238. package/dist/validate/rules/artifacts.d.ts +25 -0
  239. package/dist/validate/rules/artifacts.d.ts.map +1 -0
  240. package/dist/validate/rules/artifacts.js +87 -0
  241. package/dist/validate/rules/artifacts.js.map +1 -0
  242. package/dist/validate/rules/assertions.d.ts +19 -0
  243. package/dist/validate/rules/assertions.d.ts.map +1 -0
  244. package/dist/validate/rules/assertions.js +149 -0
  245. package/dist/validate/rules/assertions.js.map +1 -0
  246. package/dist/validate/rules/duplicates.d.ts +20 -0
  247. package/dist/validate/rules/duplicates.d.ts.map +1 -0
  248. package/dist/validate/rules/duplicates.js +0 -0
  249. package/dist/validate/rules/duplicates.js.map +1 -0
  250. package/dist/validate/rules/edge-resolution.d.ts +15 -0
  251. package/dist/validate/rules/edge-resolution.d.ts.map +1 -0
  252. package/dist/validate/rules/edge-resolution.js +185 -0
  253. package/dist/validate/rules/edge-resolution.js.map +1 -0
  254. package/dist/validate/rules/includes.d.ts +21 -0
  255. package/dist/validate/rules/includes.d.ts.map +1 -0
  256. package/dist/validate/rules/includes.js +112 -0
  257. package/dist/validate/rules/includes.js.map +1 -0
  258. package/dist/validate/run.d.ts +20 -0
  259. package/dist/validate/run.d.ts.map +1 -0
  260. package/dist/validate/run.js +90 -0
  261. package/dist/validate/run.js.map +1 -0
  262. package/dist/validate/types.d.ts +101 -0
  263. package/dist/validate/types.d.ts.map +1 -0
  264. package/dist/validate/types.js +2 -0
  265. package/dist/validate/types.js.map +1 -0
  266. package/package.json +54 -0
package/dist/git.d.ts ADDED
@@ -0,0 +1,55 @@
1
+ /** What a single history walk yields. Empty throughout when git cannot answer. */
2
+ export interface FileHistory {
3
+ /** When each path last changed, as an ISO 8601 timestamp with offset. */
4
+ dates: Map<string, string>;
5
+ /**
6
+ * Every blob a path has ever held, under the name it goes by now.
7
+ *
8
+ * Two paths whose sets intersect held identical content at some point, which
9
+ * is what makes divergence detectable after the copies stop matching — the
10
+ * moment a plain hash comparison goes quiet.
11
+ */
12
+ blobs: Map<string, Set<string>>;
13
+ /**
14
+ * Where a path moved to, resolved through the whole chain: a file renamed
15
+ * twice maps straight to its current name rather than to the intermediate.
16
+ */
17
+ renames: Map<string, string>;
18
+ }
19
+ /**
20
+ * Read `git log --raw` output into a file history.
21
+ *
22
+ * Split from the subprocess so the parse is testable without a repository.
23
+ * Paths arrive relative to the directory the log was run in, with forward
24
+ * slashes on every platform.
25
+ *
26
+ * The walk is newest-first, which is what makes the rename handling work: by
27
+ * the time an older commit mentions a path under its former name, the rename
28
+ * that renamed it has already been seen, so its blobs can be filed under the
29
+ * name the path goes by today.
30
+ */
31
+ export declare function parseGitLog(output: string): FileHistory;
32
+ /**
33
+ * How much of a walk to pay for.
34
+ *
35
+ * Rename detection compares file content across every commit, and dates do not
36
+ * need it: a rename names its destination path whether or not git pairs it with
37
+ * the source, so the newest commit touching a path is the same commit either
38
+ * way. `"dates"` skips `-M` and leaves {@link FileHistory.renames} empty;
39
+ * `"full"` pays it for the renames and cross-rename blob attribution that
40
+ * validation wants.
41
+ */
42
+ export type HistoryDepth = "dates" | "full";
43
+ /**
44
+ * What git knows about the files under `dir`, keyed by path relative to it.
45
+ *
46
+ * One history walk rather than a command per file or per question: the indexer
47
+ * wants a date for every document, and validation wants blobs and renames for
48
+ * all of them at once. Anything that stops git answering — no repository, no git
49
+ * on PATH, a directory outside the work tree — yields an empty history rather
50
+ * than an error, since none of this is worth failing an index over.
51
+ */
52
+ export declare function fileHistory(dir: string, depth?: HistoryDepth): Promise<FileHistory>;
53
+ /** When each file under `dir` was last committed. A view of {@link fileHistory}. */
54
+ export declare function lastCommitDates(dir: string): Promise<Map<string, string>>;
55
+ //# sourceMappingURL=git.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"git.d.ts","sourceRoot":"","sources":["../src/git.ts"],"names":[],"mappings":"AAmBA,kFAAkF;AAClF,MAAM,WAAW,WAAW;IAC3B,yEAAyE;IACzE,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC3B;;;;;;OAMG;IACH,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;IAChC;;;OAGG;IACH,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC7B;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,WAAW,CA4DvD;AAED;;;;;;;;;GASG;AACH,MAAM,MAAM,YAAY,GAAG,OAAO,GAAG,MAAM,CAAC;AAE5C;;;;;;;;GAQG;AACH,wBAAsB,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,GAAE,YAAqB,GAAG,OAAO,CAAC,WAAW,CAAC,CAiCjG;AAED,oFAAoF;AACpF,wBAAsB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAE/E"}
package/dist/git.js ADDED
@@ -0,0 +1,127 @@
1
+ import { execFile } from "node:child_process";
2
+ import { promisify } from "node:util";
3
+ const run = promisify(execFile);
4
+ /**
5
+ * Marks a commit line in the log output.
6
+ *
7
+ * A NUL, because it is the one byte a path cannot contain: with a printable
8
+ * prefix, a document called `commit notes.md` would be read as a date.
9
+ */
10
+ const DATE_MARK = String.fromCharCode(0);
11
+ /** History can be long, and a truncated log would silently lose dates. */
12
+ const MAX_OUTPUT_BYTES = 64 * 1024 * 1024;
13
+ /** An all-zero object id, which `--raw` writes for the missing side of an add or a delete. */
14
+ const ABSENT_BLOB = /^0+$/;
15
+ /**
16
+ * Read `git log --raw` output into a file history.
17
+ *
18
+ * Split from the subprocess so the parse is testable without a repository.
19
+ * Paths arrive relative to the directory the log was run in, with forward
20
+ * slashes on every platform.
21
+ *
22
+ * The walk is newest-first, which is what makes the rename handling work: by
23
+ * the time an older commit mentions a path under its former name, the rename
24
+ * that renamed it has already been seen, so its blobs can be filed under the
25
+ * name the path goes by today.
26
+ */
27
+ export function parseGitLog(output) {
28
+ const dates = new Map();
29
+ const blobs = new Map();
30
+ const renames = new Map();
31
+ let date;
32
+ /** The name a path goes by now, following any renames already seen. */
33
+ const currentName = (path) => renames.get(path) ?? path;
34
+ const record = (path, ...candidates) => {
35
+ if (!date)
36
+ return;
37
+ const name = currentName(path);
38
+ // git walks newest first, so the first commit naming a path is the one
39
+ // that last touched it.
40
+ if (!dates.has(name))
41
+ dates.set(name, date);
42
+ let held = blobs.get(name);
43
+ if (!held) {
44
+ held = new Set();
45
+ blobs.set(name, held);
46
+ }
47
+ for (const blob of candidates) {
48
+ if (blob && !ABSENT_BLOB.test(blob))
49
+ held.add(blob);
50
+ }
51
+ };
52
+ for (const line of output.split("\n")) {
53
+ const text = line.replace(/\r$/, "");
54
+ if (!text)
55
+ continue;
56
+ if (text.startsWith(DATE_MARK)) {
57
+ date = text.slice(DATE_MARK.length);
58
+ continue;
59
+ }
60
+ // Anything else is a --raw entry:
61
+ // :<mode> <mode> <old blob> <new blob> <status>\t<path>
62
+ // with a second path appended for a rename.
63
+ if (!text.startsWith(":"))
64
+ continue;
65
+ const fields = text.split("\t");
66
+ const [, , oldBlob, newBlob] = fields[0].split(" ");
67
+ const from = fields[1];
68
+ const to = fields[2];
69
+ if (!from)
70
+ continue;
71
+ if (to) {
72
+ // Note the rename before recording anything, so every older commit
73
+ // still to come under the source name files its blobs against the
74
+ // destination. That is what carries a document's history across a
75
+ // rename instead of stranding it under a path nothing points at.
76
+ // Resolving the destination first collapses a chain of renames.
77
+ renames.set(from, currentName(to));
78
+ }
79
+ record(to ?? from, oldBlob, newBlob);
80
+ }
81
+ return { dates, blobs, renames };
82
+ }
83
+ /**
84
+ * What git knows about the files under `dir`, keyed by path relative to it.
85
+ *
86
+ * One history walk rather than a command per file or per question: the indexer
87
+ * wants a date for every document, and validation wants blobs and renames for
88
+ * all of them at once. Anything that stops git answering — no repository, no git
89
+ * on PATH, a directory outside the work tree — yields an empty history rather
90
+ * than an error, since none of this is worth failing an index over.
91
+ */
92
+ export async function fileHistory(dir, depth = "full") {
93
+ try {
94
+ const { stdout } = await run("git", [
95
+ // Without this, a path with a non-ASCII character comes back quoted
96
+ // and escaped, and would never match the file it names.
97
+ "-c",
98
+ "core.quotepath=false",
99
+ "log",
100
+ // Author date rather than committer date: a rebase or a cherry-pick
101
+ // rewrites the latter to the moment it ran, which would report every
102
+ // document on the branch as having changed today.
103
+ "--format=%x00%aI",
104
+ // Blob ids in full rather than abbreviated so two paths that held
105
+ // one blob compare equal.
106
+ "--raw",
107
+ "--no-abbrev",
108
+ // `--no-renames` rather than merely omitting `-M`: `diff.renames`
109
+ // defaults on, so a dates walk has to opt out explicitly to skip
110
+ // the content comparison it is trying not to pay for.
111
+ ...(depth === "full" ? ["-M"] : ["--no-renames"]),
112
+ // Paths relative to this directory, and only the ones under it.
113
+ "--relative",
114
+ "--",
115
+ ".",
116
+ ], { cwd: dir, maxBuffer: MAX_OUTPUT_BYTES, windowsHide: true });
117
+ return parseGitLog(stdout);
118
+ }
119
+ catch {
120
+ return { dates: new Map(), blobs: new Map(), renames: new Map() };
121
+ }
122
+ }
123
+ /** When each file under `dir` was last committed. A view of {@link fileHistory}. */
124
+ export async function lastCommitDates(dir) {
125
+ return (await fileHistory(dir, "dates")).dates;
126
+ }
127
+ //# sourceMappingURL=git.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"git.js","sourceRoot":"","sources":["../src/git.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=git.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"git.test.d.ts","sourceRoot":"","sources":["../src/git.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,198 @@
1
+ import { execFileSync } from "node:child_process";
2
+ import { mkdtempSync, rmSync, writeFileSync } from "node:fs";
3
+ import { tmpdir } from "node:os";
4
+ import { join } from "node:path";
5
+ import { afterAll, beforeAll, describe, expect, it } from "vitest";
6
+ import { fileHistory, lastCommitDates, parseGitLog } from "./git.js";
7
+ /** The NUL the log format writes before each commit's date. */
8
+ const MARK = String.fromCharCode(0);
9
+ /** A readable stand-in for an object id. */
10
+ const sha = (char) => char.repeat(40);
11
+ const ZERO = sha("0");
12
+ /** One `--raw` entry. A rename passes both paths. */
13
+ function change(status, oldBlob, newBlob, ...paths) {
14
+ return `:100644 100644 ${oldBlob} ${newBlob} ${status}\t${paths.join("\t")}`;
15
+ }
16
+ function commit(date, ...entries) {
17
+ return [`${MARK}${date}`, "", ...entries].join("\n");
18
+ }
19
+ /** Commits are written newest-first, as git emits them. */
20
+ function log(...commits) {
21
+ return `${commits.join("\n")}\n`;
22
+ }
23
+ const DAY = "2026-07-30T00:00:00Z";
24
+ const EARLIER = "2026-01-02T00:00:00Z";
25
+ describe("parseGitLog (dates)", () => {
26
+ it("maps each path to the commit that touched it", () => {
27
+ const { dates } = parseGitLog(log(commit(DAY, change("M", sha("a"), sha("b"), "README.md"), change("M", sha("c"), sha("d"), "guide.md"))));
28
+ expect(dates.get("README.md")).toBe(DAY);
29
+ expect(dates.get("guide.md")).toBe(DAY);
30
+ });
31
+ it("keeps the most recent commit for a path changed more than once", () => {
32
+ // git walks newest first, so the first commit naming a path wins.
33
+ const { dates } = parseGitLog(log(commit(DAY, change("M", sha("b"), sha("c"), "guide.md")), commit(EARLIER, change("M", sha("a"), sha("b"), "guide.md"), change("A", ZERO, sha("e"), "old.md"))));
34
+ expect(dates.get("guide.md")).toBe(DAY);
35
+ expect(dates.get("old.md")).toBe(EARLIER);
36
+ });
37
+ it("returns nothing for an empty log", () => {
38
+ expect(parseGitLog("").dates.size).toBe(0);
39
+ });
40
+ it("ignores entries listed before any commit", () => {
41
+ expect(parseGitLog(`${change("M", sha("a"), sha("b"), "stray.md")}\n`).dates.size).toBe(0);
42
+ });
43
+ it("reads a path that would look like a commit line under a printable marker", () => {
44
+ // The marker is a NUL precisely so a document called "commit notes.md"
45
+ // cannot be mistaken for one.
46
+ const { dates } = parseGitLog(log(commit(DAY, change("M", sha("a"), sha("b"), "commit notes.md"))));
47
+ expect(dates.get("commit notes.md")).toBe(DAY);
48
+ });
49
+ it("tolerates CRLF line endings", () => {
50
+ const crlf = log(commit(DAY, change("M", sha("a"), sha("b"), "guide.md"))).replace(/\n/g, "\r\n");
51
+ expect(parseGitLog(crlf).dates.get("guide.md")).toBe(DAY);
52
+ });
53
+ it("keeps a path with a space in it whole", () => {
54
+ const { dates } = parseGitLog(log(commit(DAY, change("M", sha("a"), sha("b"), "release notes/v2 draft.md"))));
55
+ expect(dates.has("release notes/v2 draft.md")).toBe(true);
56
+ });
57
+ });
58
+ describe("parseGitLog (blobs)", () => {
59
+ it("records both sides of a change, so a path's whole history is present", () => {
60
+ const { blobs } = parseGitLog(log(commit(DAY, change("M", sha("a"), sha("b"), "guide.md"))));
61
+ expect([...(blobs.get("guide.md") ?? [])].sort()).toEqual([sha("a"), sha("b")]);
62
+ });
63
+ it("accumulates across commits", () => {
64
+ const { blobs } = parseGitLog(log(commit(DAY, change("M", sha("b"), sha("c"), "guide.md")), commit(EARLIER, change("A", ZERO, sha("b"), "guide.md"))));
65
+ expect([...(blobs.get("guide.md") ?? [])].sort()).toEqual([sha("b"), sha("c")]);
66
+ });
67
+ it("ignores the all-zero id an add or a delete writes", () => {
68
+ const { blobs } = parseGitLog(log(commit(DAY, change("A", ZERO, sha("a"), "guide.md"))));
69
+ expect([...(blobs.get("guide.md") ?? [])]).toEqual([sha("a")]);
70
+ });
71
+ it("lets two paths that held one blob be told apart from two that never did", () => {
72
+ const { blobs } = parseGitLog(log(commit(DAY, change("M", sha("a"), sha("b"), "copy.md"), change("M", sha("a"), sha("c"), "original.md")), commit(EARLIER, change("M", sha("z"), sha("y"), "unrelated.md"))));
73
+ const copy = blobs.get("copy.md") ?? new Set();
74
+ const original = blobs.get("original.md") ?? new Set();
75
+ const unrelated = blobs.get("unrelated.md") ?? new Set();
76
+ expect([...copy].filter((b) => original.has(b))).toEqual([sha("a")]);
77
+ expect([...copy].filter((b) => unrelated.has(b))).toEqual([]);
78
+ });
79
+ });
80
+ describe("parseGitLog (renames)", () => {
81
+ it("records where a path moved to", () => {
82
+ const { renames } = parseGitLog(log(commit(DAY, change("R100", sha("a"), sha("a"), "old.md", "new.md"))));
83
+ expect(renames.get("old.md")).toBe("new.md");
84
+ });
85
+ it("collapses a chain of renames to the current name", () => {
86
+ // Newest first: b -> c is seen before a -> b, so a resolves straight to c.
87
+ const { renames } = parseGitLog(log(commit(DAY, change("R100", sha("b"), sha("b"), "b.md", "c.md")), commit(EARLIER, change("R100", sha("a"), sha("a"), "a.md", "b.md"))));
88
+ expect(renames.get("a.md")).toBe("c.md");
89
+ expect(renames.get("b.md")).toBe("c.md");
90
+ });
91
+ it("files a renamed path's earlier blobs under the name it goes by now", () => {
92
+ // Without this a moved document loses everything it was before the move,
93
+ // which is exactly the history divergence detection needs.
94
+ const { blobs } = parseGitLog(log(commit(DAY, change("R100", sha("b"), sha("b"), "old.md", "new.md")), commit(EARLIER, change("A", ZERO, sha("b"), "old.md"))));
95
+ expect(blobs.get("new.md")?.has(sha("b"))).toBe(true);
96
+ expect(blobs.has("old.md")).toBe(false);
97
+ });
98
+ it("dates a renamed path under its current name", () => {
99
+ const { dates } = parseGitLog(log(commit(DAY, change("R100", sha("b"), sha("b"), "old.md", "new.md")), commit(EARLIER, change("A", ZERO, sha("b"), "old.md"))));
100
+ expect(dates.get("new.md")).toBe(DAY);
101
+ expect(dates.has("old.md")).toBe(false);
102
+ });
103
+ });
104
+ describe("fileHistory", () => {
105
+ let repo;
106
+ beforeAll(() => {
107
+ repo = mkdtempSync(join(tmpdir(), "weft-git-"));
108
+ const git = (...args) => execFileSync("git", args, { cwd: repo, stdio: "ignore" });
109
+ git("init", "-q");
110
+ git("config", "user.email", "test@example.com");
111
+ git("config", "user.name", "Test");
112
+ git("config", "commit.gpgsign", "false");
113
+ // Dates are set explicitly: two commits made a moment apart would
114
+ // otherwise share a timestamp and prove nothing about which is newer.
115
+ writeFileSync(join(repo, "guide.md"), "# Guide\n");
116
+ git("add", "guide.md");
117
+ git("commit", "-q", "-m", "add guide", "--date", "2026-01-02T00:00:00+00:00");
118
+ writeFileSync(join(repo, "spec.md"), "# Spec\n");
119
+ git("add", "spec.md");
120
+ git("commit", "-q", "-m", "add spec", "--date", "2026-07-30T00:00:00+00:00");
121
+ // A real rename, so rename detection is exercised rather than simulated.
122
+ git("mv", "guide.md", "handbook.md");
123
+ git("commit", "-q", "-m", "rename guide", "--date", "2026-07-31T00:00:00+00:00");
124
+ });
125
+ afterAll(() => rmSync(repo, { recursive: true, force: true }));
126
+ it("dates every committed file", async () => {
127
+ const { dates } = await fileHistory(repo);
128
+ expect(dates.has("handbook.md")).toBe(true);
129
+ expect(dates.has("spec.md")).toBe(true);
130
+ });
131
+ it("gives a date that parses as a real instant", async () => {
132
+ const { dates } = await fileHistory(repo);
133
+ expect(Number.isNaN(Date.parse(dates.get("spec.md")))).toBe(false);
134
+ });
135
+ it("has no date for an uncommitted file", async () => {
136
+ writeFileSync(join(repo, "draft.md"), "# Draft\n");
137
+ expect((await fileHistory(repo)).dates.has("draft.md")).toBe(false);
138
+ });
139
+ it("records a real blob for every tracked file", async () => {
140
+ const { blobs } = await fileHistory(repo);
141
+ expect(blobs.get("spec.md")?.size).toBeGreaterThan(0);
142
+ for (const blob of blobs.get("spec.md") ?? [])
143
+ expect(blob).toMatch(/^[0-9a-f]{40}$/);
144
+ });
145
+ it("detects a rename git performed", async () => {
146
+ const { renames } = await fileHistory(repo);
147
+ expect(renames.get("guide.md")).toBe("handbook.md");
148
+ });
149
+ it("carries a renamed file's earlier history onto its new name", async () => {
150
+ const { blobs, dates } = await fileHistory(repo);
151
+ // The file existed as guide.md before the move; that history belongs to
152
+ // handbook.md now, and nothing should still be filed under the old name.
153
+ expect(blobs.has("guide.md")).toBe(false);
154
+ expect(dates.has("guide.md")).toBe(false);
155
+ expect(blobs.get("handbook.md")?.size).toBeGreaterThan(0);
156
+ });
157
+ it("dates a renamed file identically at either depth", async () => {
158
+ // A rename commit names its destination path whether or not git pairs it
159
+ // with the source, so skipping rename detection must not change a date.
160
+ const shallow = await fileHistory(repo, "dates");
161
+ const full = await fileHistory(repo, "full");
162
+ expect(shallow.dates.get("handbook.md")).toBe(full.dates.get("handbook.md"));
163
+ expect(shallow.dates.get("spec.md")).toBe(full.dates.get("spec.md"));
164
+ });
165
+ it("reports no renames at dates depth", async () => {
166
+ const { renames } = await fileHistory(repo, "dates");
167
+ expect(renames.size).toBe(0);
168
+ });
169
+ it("returns an empty history outside a repository rather than failing", async () => {
170
+ // A modification date is metadata worth having, never a reason to fail an
171
+ // index — a docs set unpacked from a tarball still has to build.
172
+ const loose = mkdtempSync(join(tmpdir(), "weft-nogit-"));
173
+ try {
174
+ const history = await fileHistory(loose);
175
+ expect(history.dates.size).toBe(0);
176
+ expect(history.blobs.size).toBe(0);
177
+ expect(history.renames.size).toBe(0);
178
+ }
179
+ finally {
180
+ rmSync(loose, { recursive: true, force: true });
181
+ }
182
+ });
183
+ it("returns an empty history for a directory that does not exist", async () => {
184
+ expect((await fileHistory(join(repo, "nope"))).dates.size).toBe(0);
185
+ });
186
+ });
187
+ describe("lastCommitDates", () => {
188
+ it("is the dates half of a file history", async () => {
189
+ const loose = mkdtempSync(join(tmpdir(), "weft-nogit-"));
190
+ try {
191
+ expect(await lastCommitDates(loose)).toEqual(new Map());
192
+ }
193
+ finally {
194
+ rmSync(loose, { recursive: true, force: true });
195
+ }
196
+ });
197
+ });
198
+ //# sourceMappingURL=git.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"git.test.js","sourceRoot":"","sources":["../src/git.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,53 @@
1
+ import type { IncludeContributes, IncludeDefaults, IncludeHeadingShift, WeftEdge } from "./types.js";
2
+ /**
3
+ * The edge type that means "this document renders that one inline".
4
+ *
5
+ * A convention rather than a new mechanism, like `DERIVES_FROM` — any string has
6
+ * always been a valid edge type. What it gains here is defined semantics: the
7
+ * renderer expands an edge of this type at render time, and `include-cycle`
8
+ * checks the graph they form stays acyclic.
9
+ */
10
+ export declare const INCLUDES = "includes";
11
+ export declare const HEADING_SHIFTS: readonly IncludeHeadingShift[];
12
+ export declare const CONTRIBUTES_MODES: readonly IncludeContributes[];
13
+ /**
14
+ * What an include edge means when it says nothing: headings fold into the
15
+ * including document's outline, and content is searchable only at its source.
16
+ */
17
+ export declare const INCLUDE_DEFAULTS: Required<IncludeDefaults>;
18
+ /**
19
+ * Stamp resolved include semantics onto every `includes` edge.
20
+ *
21
+ * Run at manifest build time so the defaults are resolved exactly once. A
22
+ * consumer of the manifest — the UI most of all, which has no config access —
23
+ * reads the edge and never has to know what the project's defaults were.
24
+ */
25
+ export declare function applyIncludeDefaults(edges: WeftEdge[], defaults?: IncludeDefaults): WeftEdge[];
26
+ /** An anchor-bounded slice of a Markdown document. */
27
+ export interface SectionRange {
28
+ /** The sliced source text, ready to render. */
29
+ text: string;
30
+ /**
31
+ * Heading level the range starts at: the selected heading's level, or the
32
+ * shallowest heading in the document for a whole-document range. Absent when
33
+ * the document has no headings — there is nothing for `headingShift` to move.
34
+ */
35
+ baseLevel?: number;
36
+ }
37
+ /**
38
+ * Extract the section of a Markdown document an anchor selects.
39
+ *
40
+ * The range runs from the anchored heading to the next heading of the same or
41
+ * shallower level, exclusive — the section as a reader understands it. No
42
+ * anchor selects the whole document, the degenerate case of the same idea.
43
+ *
44
+ * Lives in core rather than the UI because a static `weft build` will need the
45
+ * identical slice server-side; the extraction has one home so the two renderers
46
+ * cannot disagree about where a section ends.
47
+ *
48
+ * Returns undefined when the anchor names no heading in the document. That the
49
+ * anchor is broken is `edge-anchor-missing`'s finding — the caller only needs
50
+ * to know there is nothing to expand.
51
+ */
52
+ export declare function extractSection(content: string, anchor?: string): SectionRange | undefined;
53
+ //# sourceMappingURL=includes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"includes.d.ts","sourceRoot":"","sources":["../src/includes.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACX,kBAAkB,EAClB,eAAe,EACf,mBAAmB,EACnB,QAAQ,EACR,MAAM,YAAY,CAAC;AAEpB;;;;;;;GAOG;AACH,eAAO,MAAM,QAAQ,aAAa,CAAC;AAEnC,eAAO,MAAM,cAAc,EAAE,SAAS,mBAAmB,EAAqB,CAAC;AAC/E,eAAO,MAAM,iBAAiB,EAAE,SAAS,kBAAkB,EAAyB,CAAC;AAErF;;;GAGG;AACH,eAAO,MAAM,gBAAgB,EAAE,QAAQ,CAAC,eAAe,CAGtD,CAAC;AAEF;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,QAAQ,EAAE,EAAE,QAAQ,CAAC,EAAE,eAAe,GAAG,QAAQ,EAAE,CAS9F;AAED,sDAAsD;AACtD,MAAM,WAAW,YAAY;IAC5B,+CAA+C;IAC/C,IAAI,EAAE,MAAM,CAAC;IACb;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS,CAuBzF"}
@@ -0,0 +1,73 @@
1
+ import { extractMarkdownAnchors } from "./anchors/markdown.js";
2
+ /**
3
+ * The edge type that means "this document renders that one inline".
4
+ *
5
+ * A convention rather than a new mechanism, like `DERIVES_FROM` — any string has
6
+ * always been a valid edge type. What it gains here is defined semantics: the
7
+ * renderer expands an edge of this type at render time, and `include-cycle`
8
+ * checks the graph they form stays acyclic.
9
+ */
10
+ export const INCLUDES = "includes";
11
+ export const HEADING_SHIFTS = ["auto", "none"];
12
+ export const CONTRIBUTES_MODES = ["source", "inline"];
13
+ /**
14
+ * What an include edge means when it says nothing: headings fold into the
15
+ * including document's outline, and content is searchable only at its source.
16
+ */
17
+ export const INCLUDE_DEFAULTS = {
18
+ headingShift: "auto",
19
+ contributes: "source",
20
+ };
21
+ /**
22
+ * Stamp resolved include semantics onto every `includes` edge.
23
+ *
24
+ * Run at manifest build time so the defaults are resolved exactly once. A
25
+ * consumer of the manifest — the UI most of all, which has no config access —
26
+ * reads the edge and never has to know what the project's defaults were.
27
+ */
28
+ export function applyIncludeDefaults(edges, defaults) {
29
+ return edges.map((edge) => {
30
+ if (edge.type !== INCLUDES)
31
+ return edge;
32
+ return {
33
+ ...edge,
34
+ headingShift: edge.headingShift ?? defaults?.headingShift ?? INCLUDE_DEFAULTS.headingShift,
35
+ contributes: edge.contributes ?? defaults?.contributes ?? INCLUDE_DEFAULTS.contributes,
36
+ };
37
+ });
38
+ }
39
+ /**
40
+ * Extract the section of a Markdown document an anchor selects.
41
+ *
42
+ * The range runs from the anchored heading to the next heading of the same or
43
+ * shallower level, exclusive — the section as a reader understands it. No
44
+ * anchor selects the whole document, the degenerate case of the same idea.
45
+ *
46
+ * Lives in core rather than the UI because a static `weft build` will need the
47
+ * identical slice server-side; the extraction has one home so the two renderers
48
+ * cannot disagree about where a section ends.
49
+ *
50
+ * Returns undefined when the anchor names no heading in the document. That the
51
+ * anchor is broken is `edge-anchor-missing`'s finding — the caller only needs
52
+ * to know there is nothing to expand.
53
+ */
54
+ export function extractSection(content, anchor) {
55
+ const headings = extractMarkdownAnchors(content).filter((a) => a.level !== undefined);
56
+ if (anchor === undefined || anchor === "" || anchor === "#") {
57
+ const levels = headings.map((h) => h.level);
58
+ return {
59
+ text: content,
60
+ ...(levels.length ? { baseLevel: Math.min(...levels) } : {}),
61
+ };
62
+ }
63
+ const slug = anchor.startsWith("#") ? anchor : `#${anchor}`;
64
+ const start = headings.find((h) => h.slug === slug);
65
+ if (!start || !start.line)
66
+ return undefined;
67
+ const level = start.level;
68
+ const next = headings.find((h) => h.line > start.line && h.level <= level);
69
+ const lines = content.split(/\r?\n/);
70
+ const text = lines.slice(start.line - 1, next?.line ? next.line - 1 : undefined).join("\n");
71
+ return { text, baseLevel: level };
72
+ }
73
+ //# sourceMappingURL=includes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"includes.js","sourceRoot":"","sources":["../src/includes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAQ/D;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAG,UAAU,CAAC;AAEnC,MAAM,CAAC,MAAM,cAAc,GAAmC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAC/E,MAAM,CAAC,MAAM,iBAAiB,GAAkC,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;AAErF;;;GAGG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAA8B;IAC1D,YAAY,EAAE,MAAM;IACpB,WAAW,EAAE,QAAQ;CACrB,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,UAAU,oBAAoB,CAAC,KAAiB,EAAE,QAA0B;IACjF,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;QACzB,IAAI,IAAI,CAAC,IAAI,KAAK,QAAQ;YAAE,OAAO,IAAI,CAAC;QACxC,OAAO;YACN,GAAG,IAAI;YACP,YAAY,EAAE,IAAI,CAAC,YAAY,IAAI,QAAQ,EAAE,YAAY,IAAI,gBAAgB,CAAC,YAAY;YAC1F,WAAW,EAAE,IAAI,CAAC,WAAW,IAAI,QAAQ,EAAE,WAAW,IAAI,gBAAgB,CAAC,WAAW;SACtF,CAAC;IACH,CAAC,CAAC,CAAC;AACJ,CAAC;AAcD;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,cAAc,CAAC,OAAe,EAAE,MAAe;IAC9D,MAAM,QAAQ,GAAG,sBAAsB,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC;IAEtF,IAAI,MAAM,KAAK,SAAS,IAAI,MAAM,KAAK,EAAE,IAAI,MAAM,KAAK,GAAG,EAAE,CAAC;QAC7D,MAAM,MAAM,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAe,CAAC,CAAC;QACtD,OAAO;YACN,IAAI,EAAE,OAAO;YACb,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAC5D,CAAC;IACH,CAAC;IAED,MAAM,IAAI,GAAG,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,MAAM,EAAE,CAAC;IAC5D,MAAM,KAAK,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;IACpD,IAAI,CAAC,KAAK,IAAI,CAAC,KAAK,CAAC,IAAI;QAAE,OAAO,SAAS,CAAC;IAE5C,MAAM,KAAK,GAAG,KAAK,CAAC,KAAe,CAAC;IACpC,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CACzB,CAAC,CAAC,EAAE,EAAE,CAAE,CAAC,CAAC,IAAe,GAAI,KAAK,CAAC,IAAe,IAAK,CAAC,CAAC,KAAgB,IAAI,KAAK,CAClF,CAAC;IAEF,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IACrC,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,GAAG,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC5F,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;AACnC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=includes.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"includes.test.d.ts","sourceRoot":"","sources":["../src/includes.test.ts"],"names":[],"mappings":""}