functional-examples 0.0.0-alpha.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.
Files changed (202) hide show
  1. package/README.md +148 -0
  2. package/dist/cli/commands/generate.d.ts +10 -0
  3. package/dist/cli/commands/generate.d.ts.map +1 -0
  4. package/dist/cli/commands/generate.js +64 -0
  5. package/dist/cli/commands/generate.js.map +1 -0
  6. package/dist/cli/commands/init.d.ts +14 -0
  7. package/dist/cli/commands/init.d.ts.map +1 -0
  8. package/dist/cli/commands/init.js +95 -0
  9. package/dist/cli/commands/init.js.map +1 -0
  10. package/dist/cli/commands/scan.d.ts +20 -0
  11. package/dist/cli/commands/scan.d.ts.map +1 -0
  12. package/dist/cli/commands/scan.js +182 -0
  13. package/dist/cli/commands/scan.js.map +1 -0
  14. package/dist/cli/commands/validate.d.ts +10 -0
  15. package/dist/cli/commands/validate.d.ts.map +1 -0
  16. package/dist/cli/commands/validate.js +65 -0
  17. package/dist/cli/commands/validate.js.map +1 -0
  18. package/dist/cli/index.d.ts +88 -0
  19. package/dist/cli/index.d.ts.map +1 -0
  20. package/dist/cli/index.js +43 -0
  21. package/dist/cli/index.js.map +1 -0
  22. package/dist/cli/plugin-commands.d.ts +17 -0
  23. package/dist/cli/plugin-commands.d.ts.map +1 -0
  24. package/dist/cli/plugin-commands.js +45 -0
  25. package/dist/cli/plugin-commands.js.map +1 -0
  26. package/dist/config/index.d.ts +11 -0
  27. package/dist/config/index.d.ts.map +1 -0
  28. package/dist/config/index.js +9 -0
  29. package/dist/config/index.js.map +1 -0
  30. package/dist/config/index.spec.d.ts +5 -0
  31. package/dist/config/index.spec.d.ts.map +1 -0
  32. package/dist/config/index.spec.js +142 -0
  33. package/dist/config/index.spec.js.map +1 -0
  34. package/dist/config/loader.d.ts +7 -0
  35. package/dist/config/loader.d.ts.map +1 -0
  36. package/dist/config/loader.js +85 -0
  37. package/dist/config/loader.js.map +1 -0
  38. package/dist/config/merger.d.ts +27 -0
  39. package/dist/config/merger.d.ts.map +1 -0
  40. package/dist/config/merger.js +41 -0
  41. package/dist/config/merger.js.map +1 -0
  42. package/dist/config/resolver.d.ts +28 -0
  43. package/dist/config/resolver.d.ts.map +1 -0
  44. package/dist/config/resolver.js +165 -0
  45. package/dist/config/resolver.js.map +1 -0
  46. package/dist/config/schema.d.ts +53 -0
  47. package/dist/config/schema.d.ts.map +1 -0
  48. package/dist/config/schema.js +42 -0
  49. package/dist/config/schema.js.map +1 -0
  50. package/dist/config/types.d.ts +17 -0
  51. package/dist/config/types.d.ts.map +1 -0
  52. package/dist/config/types.js +5 -0
  53. package/dist/config/types.js.map +1 -0
  54. package/dist/config/validator.d.ts +6 -0
  55. package/dist/config/validator.d.ts.map +1 -0
  56. package/dist/config/validator.js +17 -0
  57. package/dist/config/validator.js.map +1 -0
  58. package/dist/extractors/index.d.ts +9 -0
  59. package/dist/extractors/index.d.ts.map +1 -0
  60. package/dist/extractors/index.js +9 -0
  61. package/dist/extractors/index.js.map +1 -0
  62. package/dist/extractors/loader.d.ts +19 -0
  63. package/dist/extractors/loader.d.ts.map +1 -0
  64. package/dist/extractors/loader.js +120 -0
  65. package/dist/extractors/loader.js.map +1 -0
  66. package/dist/extractors/meta-yml-fn.d.ts +19 -0
  67. package/dist/extractors/meta-yml-fn.d.ts.map +1 -0
  68. package/dist/extractors/meta-yml-fn.js +66 -0
  69. package/dist/extractors/meta-yml-fn.js.map +1 -0
  70. package/dist/extractors/meta-yml.d.ts +24 -0
  71. package/dist/extractors/meta-yml.d.ts.map +1 -0
  72. package/dist/extractors/meta-yml.js +65 -0
  73. package/dist/extractors/meta-yml.js.map +1 -0
  74. package/dist/extractors/registry.d.ts +58 -0
  75. package/dist/extractors/registry.d.ts.map +1 -0
  76. package/dist/extractors/registry.js +114 -0
  77. package/dist/extractors/registry.js.map +1 -0
  78. package/dist/extractors/registry.spec.d.ts +2 -0
  79. package/dist/extractors/registry.spec.d.ts.map +1 -0
  80. package/dist/extractors/registry.spec.js +102 -0
  81. package/dist/extractors/registry.spec.js.map +1 -0
  82. package/dist/extractors/types.d.ts +34 -0
  83. package/dist/extractors/types.d.ts.map +1 -0
  84. package/dist/extractors/types.js +8 -0
  85. package/dist/extractors/types.js.map +1 -0
  86. package/dist/extractors/yaml-frontmatter-fn.d.ts +18 -0
  87. package/dist/extractors/yaml-frontmatter-fn.d.ts.map +1 -0
  88. package/dist/extractors/yaml-frontmatter-fn.js +73 -0
  89. package/dist/extractors/yaml-frontmatter-fn.js.map +1 -0
  90. package/dist/extractors/yaml-frontmatter.d.ts +22 -0
  91. package/dist/extractors/yaml-frontmatter.d.ts.map +1 -0
  92. package/dist/extractors/yaml-frontmatter.js +83 -0
  93. package/dist/extractors/yaml-frontmatter.js.map +1 -0
  94. package/dist/extractors/yaml-frontmatter.spec.d.ts +2 -0
  95. package/dist/extractors/yaml-frontmatter.spec.d.ts.map +1 -0
  96. package/dist/extractors/yaml-frontmatter.spec.js +134 -0
  97. package/dist/extractors/yaml-frontmatter.spec.js.map +1 -0
  98. package/dist/files/index.d.ts +5 -0
  99. package/dist/files/index.d.ts.map +1 -0
  100. package/dist/files/index.js +5 -0
  101. package/dist/files/index.js.map +1 -0
  102. package/dist/files/reader.d.ts +50 -0
  103. package/dist/files/reader.d.ts.map +1 -0
  104. package/dist/files/reader.js +62 -0
  105. package/dist/files/reader.js.map +1 -0
  106. package/dist/index.d.ts +29 -0
  107. package/dist/index.d.ts.map +1 -0
  108. package/dist/index.js +22 -0
  109. package/dist/index.js.map +1 -0
  110. package/dist/plugins/index.d.ts +4 -0
  111. package/dist/plugins/index.d.ts.map +1 -0
  112. package/dist/plugins/index.js +4 -0
  113. package/dist/plugins/index.js.map +1 -0
  114. package/dist/plugins/pipeline.d.ts +11 -0
  115. package/dist/plugins/pipeline.d.ts.map +1 -0
  116. package/dist/plugins/pipeline.js +24 -0
  117. package/dist/plugins/pipeline.js.map +1 -0
  118. package/dist/plugins/registry.d.ts +57 -0
  119. package/dist/plugins/registry.d.ts.map +1 -0
  120. package/dist/plugins/registry.js +93 -0
  121. package/dist/plugins/registry.js.map +1 -0
  122. package/dist/plugins/validation.d.ts +64 -0
  123. package/dist/plugins/validation.d.ts.map +1 -0
  124. package/dist/plugins/validation.js +55 -0
  125. package/dist/plugins/validation.js.map +1 -0
  126. package/dist/regions/index.d.ts +7 -0
  127. package/dist/regions/index.d.ts.map +1 -0
  128. package/dist/regions/index.js +6 -0
  129. package/dist/regions/index.js.map +1 -0
  130. package/dist/regions/languages.d.ts +15 -0
  131. package/dist/regions/languages.d.ts.map +1 -0
  132. package/dist/regions/languages.js +182 -0
  133. package/dist/regions/languages.js.map +1 -0
  134. package/dist/regions/parser.d.ts +63 -0
  135. package/dist/regions/parser.d.ts.map +1 -0
  136. package/dist/regions/parser.js +175 -0
  137. package/dist/regions/parser.js.map +1 -0
  138. package/dist/regions/parser.spec.d.ts +2 -0
  139. package/dist/regions/parser.spec.d.ts.map +1 -0
  140. package/dist/regions/parser.spec.js +190 -0
  141. package/dist/regions/parser.spec.js.map +1 -0
  142. package/dist/regions/types.d.ts +37 -0
  143. package/dist/regions/types.d.ts.map +1 -0
  144. package/dist/regions/types.js +5 -0
  145. package/dist/regions/types.js.map +1 -0
  146. package/dist/scanner/candidates.d.ts +24 -0
  147. package/dist/scanner/candidates.d.ts.map +1 -0
  148. package/dist/scanner/candidates.js +83 -0
  149. package/dist/scanner/candidates.js.map +1 -0
  150. package/dist/scanner/index.d.ts +8 -0
  151. package/dist/scanner/index.d.ts.map +1 -0
  152. package/dist/scanner/index.js +6 -0
  153. package/dist/scanner/index.js.map +1 -0
  154. package/dist/scanner/scan.d.ts +40 -0
  155. package/dist/scanner/scan.d.ts.map +1 -0
  156. package/dist/scanner/scan.js +44 -0
  157. package/dist/scanner/scan.js.map +1 -0
  158. package/dist/scanner/scanner.d.ts +29 -0
  159. package/dist/scanner/scanner.d.ts.map +1 -0
  160. package/dist/scanner/scanner.js +296 -0
  161. package/dist/scanner/scanner.js.map +1 -0
  162. package/dist/scanner/scanner.spec.d.ts +2 -0
  163. package/dist/scanner/scanner.spec.d.ts.map +1 -0
  164. package/dist/scanner/scanner.spec.js +262 -0
  165. package/dist/scanner/scanner.spec.js.map +1 -0
  166. package/dist/scanner/types.d.ts +43 -0
  167. package/dist/scanner/types.d.ts.map +1 -0
  168. package/dist/scanner/types.js +5 -0
  169. package/dist/scanner/types.js.map +1 -0
  170. package/dist/schema/index.d.ts +4 -0
  171. package/dist/schema/index.d.ts.map +1 -0
  172. package/dist/schema/index.js +4 -0
  173. package/dist/schema/index.js.map +1 -0
  174. package/dist/schema/merger.d.ts +35 -0
  175. package/dist/schema/merger.d.ts.map +1 -0
  176. package/dist/schema/merger.js +161 -0
  177. package/dist/schema/merger.js.map +1 -0
  178. package/dist/schema/typegen.d.ts +13 -0
  179. package/dist/schema/typegen.d.ts.map +1 -0
  180. package/dist/schema/typegen.js +125 -0
  181. package/dist/schema/typegen.js.map +1 -0
  182. package/dist/schema/validator.d.ts +7 -0
  183. package/dist/schema/validator.d.ts.map +1 -0
  184. package/dist/schema/validator.js +32 -0
  185. package/dist/schema/validator.js.map +1 -0
  186. package/dist/types/default-map.d.ts +21 -0
  187. package/dist/types/default-map.d.ts.map +1 -0
  188. package/dist/types/default-map.js +32 -0
  189. package/dist/types/default-map.js.map +1 -0
  190. package/dist/types/extended-iterable.d.ts +197 -0
  191. package/dist/types/extended-iterable.d.ts.map +1 -0
  192. package/dist/types/extended-iterable.js +769 -0
  193. package/dist/types/extended-iterable.js.map +1 -0
  194. package/dist/types/guards.d.ts +2 -0
  195. package/dist/types/guards.d.ts.map +1 -0
  196. package/dist/types/guards.js +2 -0
  197. package/dist/types/guards.js.map +1 -0
  198. package/dist/types/index.d.ts +11 -0
  199. package/dist/types/index.d.ts.map +1 -0
  200. package/dist/types/index.js +10 -0
  201. package/dist/types/index.js.map +1 -0
  202. package/package.json +61 -0
@@ -0,0 +1,134 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { YamlFrontmatterExtractor } from './yaml-frontmatter.js';
3
+ describe('YamlFrontmatterExtractor', () => {
4
+ const extractor = new YamlFrontmatterExtractor();
5
+ describe('canExtract', () => {
6
+ it('returns true for file with frontmatter', () => {
7
+ const context = {
8
+ path: '/test/example.ts',
9
+ isDirectory: false,
10
+ content: `// ---
11
+ // title: Test
12
+ // ---
13
+ console.log('hello');`,
14
+ };
15
+ expect(extractor.canExtract(context)).toBe(true);
16
+ });
17
+ it('returns false for file without frontmatter', () => {
18
+ const context = {
19
+ path: '/test/example.ts',
20
+ isDirectory: false,
21
+ content: `console.log('hello');`,
22
+ };
23
+ expect(extractor.canExtract(context)).toBe(false);
24
+ });
25
+ it('returns false for directories', () => {
26
+ const context = {
27
+ path: '/test/example',
28
+ isDirectory: true,
29
+ entries: ['meta.yml'],
30
+ };
31
+ expect(extractor.canExtract(context)).toBe(false);
32
+ });
33
+ it('returns false for empty content', () => {
34
+ const context = {
35
+ path: '/test/example.ts',
36
+ isDirectory: false,
37
+ content: '',
38
+ };
39
+ expect(extractor.canExtract(context)).toBe(false);
40
+ });
41
+ });
42
+ describe('extract', () => {
43
+ it('extracts metadata from frontmatter', async () => {
44
+ const context = {
45
+ path: '/test/example.ts',
46
+ isDirectory: false,
47
+ content: `// ---
48
+ // title: My Example
49
+ // description: A test example
50
+ // ---
51
+ console.log('hello');`,
52
+ };
53
+ const result = await extractor.extract(context);
54
+ expect(result.metadata.id).toBe('example');
55
+ expect(result.metadata.title).toBe('My Example');
56
+ expect(result.metadata.description).toBe('A test example');
57
+ expect(result.strippedContent).toBe("console.log('hello');");
58
+ });
59
+ it('generates id from filename if not provided', async () => {
60
+ const context = {
61
+ path: '/test/my-cool-example.ts',
62
+ isDirectory: false,
63
+ content: `// ---
64
+ // title: Cool Example
65
+ // ---
66
+ code();`,
67
+ };
68
+ const result = await extractor.extract(context);
69
+ expect(result.metadata.id).toBe('my-cool-example');
70
+ });
71
+ it('uses provided id over generated one', async () => {
72
+ const context = {
73
+ path: '/test/example.ts',
74
+ isDirectory: false,
75
+ content: `// ---
76
+ // id: custom-id
77
+ // title: Example
78
+ // ---
79
+ code();`,
80
+ };
81
+ const result = await extractor.extract(context);
82
+ expect(result.metadata.id).toBe('custom-id');
83
+ });
84
+ it('handles multiline description', async () => {
85
+ const context = {
86
+ path: '/test/example.ts',
87
+ isDirectory: false,
88
+ content: `// ---
89
+ // title: Example
90
+ // description: |
91
+ // This is a multiline
92
+ // description
93
+ // ---
94
+ code();`,
95
+ };
96
+ const result = await extractor.extract(context);
97
+ expect(result.metadata.description).toContain('multiline');
98
+ });
99
+ it('preserves extra metadata fields', async () => {
100
+ const context = {
101
+ path: '/test/example.ts',
102
+ isDirectory: false,
103
+ content: `// ---
104
+ // title: Example
105
+ // customField: custom value
106
+ // tags:
107
+ // - tag1
108
+ // - tag2
109
+ // ---
110
+ code();`,
111
+ };
112
+ const result = await extractor.extract(context);
113
+ // Extra fields are preserved in metadata
114
+ const metadata = result.metadata;
115
+ expect(metadata.customField).toBe('custom value');
116
+ expect(metadata.tags).toEqual(['tag1', 'tag2']);
117
+ });
118
+ it('creates file entry with stripped content', async () => {
119
+ const context = {
120
+ path: '/test/example.ts',
121
+ isDirectory: false,
122
+ content: `// ---
123
+ // title: Example
124
+ // ---
125
+ const x = 1;`,
126
+ };
127
+ const result = await extractor.extract(context);
128
+ expect(result.files).toHaveLength(1);
129
+ expect(result.files[0].path).toBe('example.ts');
130
+ expect(result.files[0].contents).toBe('const x = 1;');
131
+ });
132
+ });
133
+ });
134
+ //# sourceMappingURL=yaml-frontmatter.spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"yaml-frontmatter.spec.js","sourceRoot":"","sources":["../../src/extractors/yaml-frontmatter.spec.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * File reading helpers
3
+ */
4
+ export { readExampleFile, readExampleFiles } from './reader.js';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/files/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * File reading helpers
3
+ */
4
+ export { readExampleFile, readExampleFiles } from './reader.js';
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/files/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC"}
@@ -0,0 +1,50 @@
1
+ /**
2
+ * File reading utilities for examples
3
+ */
4
+ import type { ExampleFile } from '../types/index.js';
5
+ /**
6
+ * Options for reading an example file
7
+ */
8
+ export interface ReadFileOptions {
9
+ /** Extract only this region from the file */
10
+ region?: string;
11
+ /** File extension override for region parsing */
12
+ extension?: string;
13
+ }
14
+ /**
15
+ * Read an example file, optionally extracting a specific region.
16
+ *
17
+ * @param filePath - Path to the file to read
18
+ * @param options - Options including optional region extraction
19
+ * @returns The file contents (or region contents if specified)
20
+ *
21
+ * @example
22
+ * ```typescript
23
+ * // Read entire file
24
+ * const content = await readExampleFile('./examples/basic/main.ts');
25
+ *
26
+ * // Read specific region
27
+ * const setup = await readExampleFile('./examples/basic/main.ts', {
28
+ * region: 'setup'
29
+ * });
30
+ * ```
31
+ */
32
+ export declare function readExampleFile(filePath: string, options?: ReadFileOptions): Promise<string>;
33
+ /**
34
+ * Read multiple files from an example directory.
35
+ *
36
+ * @param directory - Base directory for the example
37
+ * @param files - Array of relative file paths to read
38
+ * @returns Array of ExampleFile objects
39
+ *
40
+ * @example
41
+ * ```typescript
42
+ * const files = await readExampleFiles('./examples/multi-file', [
43
+ * 'main.ts',
44
+ * 'helper.ts',
45
+ * 'config.json'
46
+ * ]);
47
+ * ```
48
+ */
49
+ export declare function readExampleFiles(directory: string, files: string[]): Promise<ExampleFile[]>;
50
+ //# sourceMappingURL=reader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reader.d.ts","sourceRoot":"","sources":["../../src/files/reader.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAErD;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,6CAA6C;IAC7C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,iDAAiD;IACjD,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAsB,eAAe,CACnC,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,eAAoB,GAC5B,OAAO,CAAC,MAAM,CAAC,CASjB;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,gBAAgB,CACpC,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,MAAM,EAAE,GACd,OAAO,CAAC,WAAW,EAAE,CAAC,CAcxB"}
@@ -0,0 +1,62 @@
1
+ /**
2
+ * File reading utilities for examples
3
+ */
4
+ import fs from 'node:fs/promises';
5
+ import path from 'node:path';
6
+ import { extractRegion } from '../regions/index.js';
7
+ /**
8
+ * Read an example file, optionally extracting a specific region.
9
+ *
10
+ * @param filePath - Path to the file to read
11
+ * @param options - Options including optional region extraction
12
+ * @returns The file contents (or region contents if specified)
13
+ *
14
+ * @example
15
+ * ```typescript
16
+ * // Read entire file
17
+ * const content = await readExampleFile('./examples/basic/main.ts');
18
+ *
19
+ * // Read specific region
20
+ * const setup = await readExampleFile('./examples/basic/main.ts', {
21
+ * region: 'setup'
22
+ * });
23
+ * ```
24
+ */
25
+ export async function readExampleFile(filePath, options = {}) {
26
+ const content = await fs.readFile(filePath, 'utf-8');
27
+ if (options.region) {
28
+ const ext = options.extension ?? path.extname(filePath).slice(1);
29
+ return extractRegion(content, options.region, { extension: ext });
30
+ }
31
+ return content;
32
+ }
33
+ /**
34
+ * Read multiple files from an example directory.
35
+ *
36
+ * @param directory - Base directory for the example
37
+ * @param files - Array of relative file paths to read
38
+ * @returns Array of ExampleFile objects
39
+ *
40
+ * @example
41
+ * ```typescript
42
+ * const files = await readExampleFiles('./examples/multi-file', [
43
+ * 'main.ts',
44
+ * 'helper.ts',
45
+ * 'config.json'
46
+ * ]);
47
+ * ```
48
+ */
49
+ export async function readExampleFiles(directory, files) {
50
+ const results = [];
51
+ for (const relativePath of files) {
52
+ const fullPath = path.join(directory, relativePath);
53
+ const raw = await fs.readFile(fullPath, 'utf-8');
54
+ results.push({
55
+ absolutePath: path.resolve(fullPath),
56
+ relativePath,
57
+ raw,
58
+ });
59
+ }
60
+ return results;
61
+ }
62
+ //# sourceMappingURL=reader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reader.js","sourceRoot":"","sources":["../../src/files/reader.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAapD;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,QAAgB,EAChB,UAA2B,EAAE;IAE7B,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAErD,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;QACnB,MAAM,GAAG,GAAG,OAAO,CAAC,SAAS,IAAI,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QACjE,OAAO,aAAa,CAAC,OAAO,EAAE,OAAO,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,GAAG,EAAE,CAAC,CAAC;IACpE,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,SAAiB,EACjB,KAAe;IAEf,MAAM,OAAO,GAAkB,EAAE,CAAC;IAElC,KAAK,MAAM,YAAY,IAAI,KAAK,EAAE,CAAC;QACjC,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC;QACpD,MAAM,GAAG,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QACjD,OAAO,CAAC,IAAI,CAAC;YACX,YAAY,EAAE,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC;YACpC,YAAY;YACZ,GAAG;SACJ,CAAC,CAAC;IACL,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * functional-examples - A language-agnostic library for code examples
3
+ *
4
+ * @packageDocumentation
5
+ */
6
+ export type { BaseMetadata, Example, ExampleFile, ExampleMetadata, ExampleMetadataRegistry, Extractor, ExtractorFactory, ExtractorError, ExtractorOptions, ExtractorResult, ScannedExample, } from './types/index.js';
7
+ export type { Plugin, PluginCommands, FileContentsParser, FileParseContext, ParsedRegion, PluginSchemas, PluginValidators, } from './types/index.js';
8
+ export type { ValidationResult, ValidationError, } from './types/index.js';
9
+ export { scanExamples } from './scanner/index.js';
10
+ export { scan } from './scanner/index.js';
11
+ export type { ScanOptions } from './scanner/index.js';
12
+ export type { FileConflict, PathMapping, ScanResult, } from './scanner/index.js';
13
+ export type { RegionInfo, RegionMap, RegionOptions } from './regions/index.js';
14
+ export { parseRegions, extractRegion, stripRegionMarkers, listRegions, LANGUAGE_CONFIGS, } from './regions/index.js';
15
+ export { readExampleFile, readExampleFiles } from './files/index.js';
16
+ export type { Config, ExtractorConfig, ExtractorConfigOrFunction, ExtractorReference, ScanConfig, } from './config/types.js';
17
+ export type { ConfigValidationError, ResolvedConfig, } from './types/index.js';
18
+ export { findConfigFile, loadConfig } from './config/loader.js';
19
+ export { mergeConfigs } from './config/merger.js';
20
+ export { resolveConfig } from './config/resolver.js';
21
+ export { validateConfig } from './config/validator.js';
22
+ export { PluginRegistry, runParsePipeline, createInitialContext, } from './plugins/index.js';
23
+ export { validatePluginOptions, validateExampleMetadata, } from './plugins/validation.js';
24
+ export type { PluginValidator, PluginSchemaEntry, } from './plugins/registry.js';
25
+ export type { PluginOptionsValidationContext, MetadataValidationContext, OptionsValidationResult, MetadataValidationResult, OptionsValidationError, MetadataValidationError, } from './plugins/validation.js';
26
+ export { mergeConfigSchema, mergeMetadataSchemas, generateMetadataTypes, } from './schema/index.js';
27
+ export type { JSONSchema, MergeConfigSchemaOptions, MergeMetadataSchemasOptions, GenerateMetadataTypesOptions, } from './schema/index.js';
28
+ export type { JSONSchemaObject, GenerateConfig, } from './config/types.js';
29
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,YAAY,EACV,YAAY,EACZ,OAAO,EACP,WAAW,EACX,eAAe,EACf,uBAAuB,EACvB,SAAS,EACT,gBAAgB,EAChB,cAAc,EACd,gBAAgB,EAChB,eAAe,EACf,cAAc,GACf,MAAM,kBAAkB,CAAC;AAG1B,YAAY,EACV,MAAM,EACN,cAAc,EACd,kBAAkB,EAClB,gBAAgB,EAChB,YAAY,EACZ,aAAa,EACb,gBAAgB,GACjB,MAAM,kBAAkB,CAAC;AAG1B,YAAY,EACV,gBAAgB,EAChB,eAAe,GAChB,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAC1C,YAAY,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACtD,YAAY,EACV,YAAY,EACZ,WAAW,EACX,UAAU,GACX,MAAM,oBAAoB,CAAC;AAG5B,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAC/E,OAAO,EACL,YAAY,EACZ,aAAa,EACb,kBAAkB,EAClB,WAAW,EACX,gBAAgB,GACjB,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAGrE,YAAY,EACV,MAAM,EACN,eAAe,EACf,yBAAyB,EACzB,kBAAkB,EAClB,UAAU,GACX,MAAM,mBAAmB,CAAC;AAC3B,YAAY,EACV,qBAAqB,EACrB,cAAc,GACf,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChE,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAGvD,OAAO,EACL,cAAc,EACd,gBAAgB,EAChB,oBAAoB,GACrB,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EACL,qBAAqB,EACrB,uBAAuB,GACxB,MAAM,yBAAyB,CAAC;AACjC,YAAY,EACV,eAAe,EACf,iBAAiB,GAClB,MAAM,uBAAuB,CAAC;AAC/B,YAAY,EACV,8BAA8B,EAC9B,yBAAyB,EACzB,uBAAuB,EACvB,wBAAwB,EACxB,sBAAsB,EACtB,uBAAuB,GACxB,MAAM,yBAAyB,CAAC;AAGjC,OAAO,EACL,iBAAiB,EACjB,oBAAoB,EACpB,qBAAqB,GACtB,MAAM,mBAAmB,CAAC;AAC3B,YAAY,EACV,UAAU,EACV,wBAAwB,EACxB,2BAA2B,EAC3B,4BAA4B,GAC7B,MAAM,mBAAmB,CAAC;AAG3B,YAAY,EACV,gBAAgB,EAChB,cAAc,GACf,MAAM,mBAAmB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,22 @@
1
+ /**
2
+ * functional-examples - A language-agnostic library for code examples
3
+ *
4
+ * @packageDocumentation
5
+ */
6
+ // Scanner
7
+ export { scanExamples } from './scanner/index.js';
8
+ export { scan } from './scanner/index.js';
9
+ export { parseRegions, extractRegion, stripRegionMarkers, listRegions, LANGUAGE_CONFIGS, } from './regions/index.js';
10
+ // File helpers
11
+ export { readExampleFile, readExampleFiles } from './files/index.js';
12
+ export { findConfigFile, loadConfig } from './config/loader.js';
13
+ export { mergeConfigs } from './config/merger.js';
14
+ export { resolveConfig } from './config/resolver.js';
15
+ export { validateConfig } from './config/validator.js';
16
+ // Plugin system
17
+ export { PluginRegistry, runParsePipeline, createInitialContext, } from './plugins/index.js';
18
+ // Plugin validation
19
+ export { validatePluginOptions, validateExampleMetadata, } from './plugins/validation.js';
20
+ // Schema utilities
21
+ export { mergeConfigSchema, mergeMetadataSchemas, generateMetadataTypes, } from './schema/index.js';
22
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAkCH,UAAU;AACV,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAU1C,OAAO,EACL,YAAY,EACZ,aAAa,EACb,kBAAkB,EAClB,WAAW,EACX,gBAAgB,GACjB,MAAM,oBAAoB,CAAC;AAE5B,eAAe;AACf,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAcrE,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChE,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAEvD,gBAAgB;AAChB,OAAO,EACL,cAAc,EACd,gBAAgB,EAChB,oBAAoB,GACrB,MAAM,oBAAoB,CAAC;AAE5B,oBAAoB;AACpB,OAAO,EACL,qBAAqB,EACrB,uBAAuB,GACxB,MAAM,yBAAyB,CAAC;AAcjC,mBAAmB;AACnB,OAAO,EACL,iBAAiB,EACjB,oBAAoB,EACpB,qBAAqB,GACtB,MAAM,mBAAmB,CAAC"}
@@ -0,0 +1,4 @@
1
+ export { PluginRegistry, type PluginValidator, type PluginSchemaEntry, } from './registry.js';
2
+ export { runParsePipeline, createInitialContext } from './pipeline.js';
3
+ export { validatePluginOptions, validateExampleMetadata, type PluginOptionsValidationContext, type MetadataValidationContext, type OptionsValidationResult, type MetadataValidationResult, type OptionsValidationError, type MetadataValidationError, } from './validation.js';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/plugins/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,EACd,KAAK,eAAe,EACpB,KAAK,iBAAiB,GACvB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AACvE,OAAO,EACL,qBAAqB,EACrB,uBAAuB,EACvB,KAAK,8BAA8B,EACnC,KAAK,yBAAyB,EAC9B,KAAK,uBAAuB,EAC5B,KAAK,wBAAwB,EAC7B,KAAK,sBAAsB,EAC3B,KAAK,uBAAuB,GAC7B,MAAM,iBAAiB,CAAC"}
@@ -0,0 +1,4 @@
1
+ export { PluginRegistry, } from './registry.js';
2
+ export { runParsePipeline, createInitialContext } from './pipeline.js';
3
+ export { validatePluginOptions, validateExampleMetadata, } from './validation.js';
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/plugins/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,GAGf,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AACvE,OAAO,EACL,qBAAqB,EACrB,uBAAuB,GAOxB,MAAM,iBAAiB,CAAC"}
@@ -0,0 +1,11 @@
1
+ import type { FileContentsParser, FileParseContext } from '../types/index.js';
2
+ /**
3
+ * Create the initial parse context for a file.
4
+ */
5
+ export declare function createInitialContext(filePath: string, content: string): FileParseContext;
6
+ /**
7
+ * Run file content through a parser pipeline.
8
+ * Parsers execute in order, each receiving the output of the previous.
9
+ */
10
+ export declare function runParsePipeline(context: FileParseContext, parsers: FileContentsParser[]): Promise<FileParseContext>;
11
+ //# sourceMappingURL=pipeline.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pipeline.d.ts","sourceRoot":"","sources":["../../src/plugins/pipeline.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAE9E;;GAEG;AACH,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,GACd,gBAAgB,CAQlB;AAED;;;GAGG;AACH,wBAAsB,gBAAgB,CACpC,OAAO,EAAE,gBAAgB,EACzB,OAAO,EAAE,kBAAkB,EAAE,GAC5B,OAAO,CAAC,gBAAgB,CAAC,CAQ3B"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Create the initial parse context for a file.
3
+ */
4
+ export function createInitialContext(filePath, content) {
5
+ return {
6
+ raw: content,
7
+ parsed: content,
8
+ hunks: [],
9
+ metadata: {},
10
+ filePath,
11
+ };
12
+ }
13
+ /**
14
+ * Run file content through a parser pipeline.
15
+ * Parsers execute in order, each receiving the output of the previous.
16
+ */
17
+ export async function runParsePipeline(context, parsers) {
18
+ let result = context;
19
+ for (const parser of parsers) {
20
+ result = await parser.parse(result);
21
+ }
22
+ return result;
23
+ }
24
+ //# sourceMappingURL=pipeline.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pipeline.js","sourceRoot":"","sources":["../../src/plugins/pipeline.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,MAAM,UAAU,oBAAoB,CAClC,QAAgB,EAChB,OAAe;IAEf,OAAO;QACL,GAAG,EAAE,OAAO;QACZ,MAAM,EAAE,OAAO;QACf,KAAK,EAAE,EAAE;QACT,QAAQ,EAAE,EAAE;QACZ,QAAQ;KACT,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,OAAyB,EACzB,OAA6B;IAE7B,IAAI,MAAM,GAAG,OAAO,CAAC;IAErB,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,MAAM,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IACtC,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -0,0 +1,57 @@
1
+ import type { Plugin, Extractor, FileContentsParser, ValidationResult } from '../types/index.js';
2
+ /**
3
+ * Wrapper for a plugin's validator function with plugin name context.
4
+ */
5
+ export interface PluginValidator<T = unknown> {
6
+ pluginName: string;
7
+ validate: (value: T) => ValidationResult;
8
+ }
9
+ /**
10
+ * Schema entry from a plugin with plugin name context.
11
+ */
12
+ export interface PluginSchemaEntry {
13
+ pluginName: string;
14
+ options?: string;
15
+ metadata?: string;
16
+ }
17
+ /**
18
+ * Registry for plugins with extension-based lookup.
19
+ */
20
+ export declare class PluginRegistry {
21
+ private plugins;
22
+ private extensionMap;
23
+ /**
24
+ * Register a plugin.
25
+ * @throws If plugin with same name already registered
26
+ */
27
+ register(plugin: Plugin): void;
28
+ /**
29
+ * Get all registered plugins.
30
+ */
31
+ getPlugins(): readonly Plugin[];
32
+ /**
33
+ * Get plugins registered for a file extension.
34
+ */
35
+ getPluginsForExtension(extension: string): Plugin[];
36
+ /**
37
+ * Get all extractors from registered plugins.
38
+ */
39
+ getExtractors(): Extractor[];
40
+ /**
41
+ * Get parsers for files with given extension, in registration order.
42
+ */
43
+ getParsersForExtension(extension: string): FileContentsParser[];
44
+ /**
45
+ * Get all options validators from registered plugins.
46
+ */
47
+ getOptionsValidators(): PluginValidator<unknown>[];
48
+ /**
49
+ * Get all metadata validators from registered plugins.
50
+ */
51
+ getMetadataValidators(): PluginValidator[];
52
+ /**
53
+ * Get all schemas from registered plugins.
54
+ */
55
+ getSchemas(): PluginSchemaEntry[];
56
+ }
57
+ //# sourceMappingURL=registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/plugins/registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,MAAM,EACN,SAAS,EACT,kBAAkB,EAClB,gBAAgB,EACjB,MAAM,mBAAmB,CAAC;AAE3B;;GAEG;AACH,MAAM,WAAW,eAAe,CAAC,CAAC,GAAG,OAAO;IAC1C,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,gBAAgB,CAAC;CAC1C;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,OAAO,CAAgB;IAC/B,OAAO,CAAC,YAAY,CAAoC;IAExD;;;OAGG;IACH,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAiB9B;;OAEG;IACH,UAAU,IAAI,SAAS,MAAM,EAAE;IAI/B;;OAEG;IACH,sBAAsB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,EAAE;IAInD;;OAEG;IACH,aAAa,IAAI,SAAS,EAAE;IAQ5B;;OAEG;IACH,sBAAsB,CAAC,SAAS,EAAE,MAAM,GAAG,kBAAkB,EAAE;IAS/D;;OAEG;IACH,oBAAoB,IAAI,eAAe,CAAC,OAAO,CAAC,EAAE;IAQlD;;OAEG;IACH,qBAAqB,IAAI,eAAe,EAAE;IAQ1C;;OAEG;IACH,UAAU,IAAI,iBAAiB,EAAE;CAalC"}
@@ -0,0 +1,93 @@
1
+ /**
2
+ * Registry for plugins with extension-based lookup.
3
+ */
4
+ export class PluginRegistry {
5
+ plugins = [];
6
+ extensionMap = new Map();
7
+ /**
8
+ * Register a plugin.
9
+ * @throws If plugin with same name already registered
10
+ */
11
+ register(plugin) {
12
+ if (this.plugins.some((p) => p.name === plugin.name)) {
13
+ throw new Error(`Plugin "${plugin.name}" is already registered`);
14
+ }
15
+ this.plugins.push(plugin);
16
+ // Index by extensions
17
+ if (plugin.extensions) {
18
+ for (const ext of plugin.extensions) {
19
+ const existing = this.extensionMap.get(ext) ?? [];
20
+ existing.push(plugin);
21
+ this.extensionMap.set(ext, existing);
22
+ }
23
+ }
24
+ }
25
+ /**
26
+ * Get all registered plugins.
27
+ */
28
+ getPlugins() {
29
+ return this.plugins;
30
+ }
31
+ /**
32
+ * Get plugins registered for a file extension.
33
+ */
34
+ getPluginsForExtension(extension) {
35
+ return this.extensionMap.get(extension) ?? [];
36
+ }
37
+ /**
38
+ * Get all extractors from registered plugins.
39
+ */
40
+ getExtractors() {
41
+ return this.plugins
42
+ .filter((p) => p.extractor !== undefined)
43
+ .map((p) => p.extractor);
44
+ }
45
+ /**
46
+ * Get parsers for files with given extension, in registration order.
47
+ */
48
+ getParsersForExtension(extension) {
49
+ return this.getPluginsForExtension(extension)
50
+ .filter((p) => p.fileContentsParser !== undefined)
51
+ .map((p) => p.fileContentsParser);
52
+ }
53
+ /**
54
+ * Get all options validators from registered plugins.
55
+ */
56
+ getOptionsValidators() {
57
+ return this.plugins.flatMap((p) => {
58
+ const validator = p.validators?.options;
59
+ if (!validator)
60
+ return [];
61
+ return [{ pluginName: p.name, validate: validator }];
62
+ });
63
+ }
64
+ /**
65
+ * Get all metadata validators from registered plugins.
66
+ */
67
+ getMetadataValidators() {
68
+ return this.plugins.flatMap((p) => {
69
+ const validator = p.validators?.metadata;
70
+ if (!validator)
71
+ return [];
72
+ return [{ pluginName: p.name, validate: validator }];
73
+ });
74
+ }
75
+ /**
76
+ * Get all schemas from registered plugins.
77
+ */
78
+ getSchemas() {
79
+ return this.plugins.flatMap((p) => {
80
+ const schemas = p.schemas;
81
+ if (!schemas)
82
+ return [];
83
+ return [
84
+ {
85
+ pluginName: p.name,
86
+ options: schemas.options,
87
+ metadata: schemas.metadata,
88
+ },
89
+ ];
90
+ });
91
+ }
92
+ }
93
+ //# sourceMappingURL=registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/plugins/registry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,64 @@
1
+ import type { PluginValidator } from './registry.js';
2
+ /**
3
+ * Error from options validation with plugin context.
4
+ */
5
+ export interface OptionsValidationError {
6
+ pluginName: string;
7
+ path: string;
8
+ message: string;
9
+ }
10
+ /**
11
+ * Result of validating plugin options.
12
+ */
13
+ export interface OptionsValidationResult {
14
+ success: boolean;
15
+ errors: OptionsValidationError[];
16
+ }
17
+ /**
18
+ * Context for validating plugin options.
19
+ */
20
+ export interface PluginOptionsValidationContext {
21
+ validators: PluginValidator<unknown>[];
22
+ pluginOptions: Map<string, unknown>;
23
+ }
24
+ /**
25
+ * Validate plugin options before extraction.
26
+ * Runs each plugin's options validator against its configured options.
27
+ */
28
+ export declare function validatePluginOptions(context: PluginOptionsValidationContext): OptionsValidationResult;
29
+ /**
30
+ * Error from metadata validation with example context.
31
+ */
32
+ export interface MetadataValidationError {
33
+ exampleId: string;
34
+ pluginName: string;
35
+ path: string;
36
+ message: string;
37
+ }
38
+ /**
39
+ * Result of validating example metadata.
40
+ */
41
+ export interface MetadataValidationResult {
42
+ success: boolean;
43
+ errors: MetadataValidationError[];
44
+ }
45
+ /**
46
+ * Minimal example shape for validation.
47
+ */
48
+ export interface ExampleForValidation {
49
+ id: string;
50
+ metadata: Record<string, unknown>;
51
+ }
52
+ /**
53
+ * Context for validating example metadata.
54
+ */
55
+ export interface MetadataValidationContext {
56
+ validators: PluginValidator[];
57
+ examples: ExampleForValidation[];
58
+ }
59
+ /**
60
+ * Validate example metadata after extraction.
61
+ * Runs all metadata validators against each example's metadata.
62
+ */
63
+ export declare function validateExampleMetadata(context: MetadataValidationContext): MetadataValidationResult;
64
+ //# sourceMappingURL=validation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../src/plugins/validation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAErD;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,sBAAsB,EAAE,CAAC;CAClC;AAED;;GAEG;AACH,MAAM,WAAW,8BAA8B;IAC7C,UAAU,EAAE,eAAe,CAAC,OAAO,CAAC,EAAE,CAAC;IACvC,aAAa,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACrC;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,8BAA8B,GACtC,uBAAuB,CA4BzB;AAED;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACvC,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,uBAAuB,EAAE,CAAC;CACnC;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC;AAED;;GAEG;AACH,MAAM,WAAW,yBAAyB;IACxC,UAAU,EAAE,eAAe,EAAE,CAAC;IAC9B,QAAQ,EAAE,oBAAoB,EAAE,CAAC;CAClC;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,yBAAyB,GACjC,wBAAwB,CAwB1B"}