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.
- package/README.md +148 -0
- package/dist/cli/commands/generate.d.ts +10 -0
- package/dist/cli/commands/generate.d.ts.map +1 -0
- package/dist/cli/commands/generate.js +64 -0
- package/dist/cli/commands/generate.js.map +1 -0
- package/dist/cli/commands/init.d.ts +14 -0
- package/dist/cli/commands/init.d.ts.map +1 -0
- package/dist/cli/commands/init.js +95 -0
- package/dist/cli/commands/init.js.map +1 -0
- package/dist/cli/commands/scan.d.ts +20 -0
- package/dist/cli/commands/scan.d.ts.map +1 -0
- package/dist/cli/commands/scan.js +182 -0
- package/dist/cli/commands/scan.js.map +1 -0
- package/dist/cli/commands/validate.d.ts +10 -0
- package/dist/cli/commands/validate.d.ts.map +1 -0
- package/dist/cli/commands/validate.js +65 -0
- package/dist/cli/commands/validate.js.map +1 -0
- package/dist/cli/index.d.ts +88 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +43 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/plugin-commands.d.ts +17 -0
- package/dist/cli/plugin-commands.d.ts.map +1 -0
- package/dist/cli/plugin-commands.js +45 -0
- package/dist/cli/plugin-commands.js.map +1 -0
- package/dist/config/index.d.ts +11 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +9 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/index.spec.d.ts +5 -0
- package/dist/config/index.spec.d.ts.map +1 -0
- package/dist/config/index.spec.js +142 -0
- package/dist/config/index.spec.js.map +1 -0
- package/dist/config/loader.d.ts +7 -0
- package/dist/config/loader.d.ts.map +1 -0
- package/dist/config/loader.js +85 -0
- package/dist/config/loader.js.map +1 -0
- package/dist/config/merger.d.ts +27 -0
- package/dist/config/merger.d.ts.map +1 -0
- package/dist/config/merger.js +41 -0
- package/dist/config/merger.js.map +1 -0
- package/dist/config/resolver.d.ts +28 -0
- package/dist/config/resolver.d.ts.map +1 -0
- package/dist/config/resolver.js +165 -0
- package/dist/config/resolver.js.map +1 -0
- package/dist/config/schema.d.ts +53 -0
- package/dist/config/schema.d.ts.map +1 -0
- package/dist/config/schema.js +42 -0
- package/dist/config/schema.js.map +1 -0
- package/dist/config/types.d.ts +17 -0
- package/dist/config/types.d.ts.map +1 -0
- package/dist/config/types.js +5 -0
- package/dist/config/types.js.map +1 -0
- package/dist/config/validator.d.ts +6 -0
- package/dist/config/validator.d.ts.map +1 -0
- package/dist/config/validator.js +17 -0
- package/dist/config/validator.js.map +1 -0
- package/dist/extractors/index.d.ts +9 -0
- package/dist/extractors/index.d.ts.map +1 -0
- package/dist/extractors/index.js +9 -0
- package/dist/extractors/index.js.map +1 -0
- package/dist/extractors/loader.d.ts +19 -0
- package/dist/extractors/loader.d.ts.map +1 -0
- package/dist/extractors/loader.js +120 -0
- package/dist/extractors/loader.js.map +1 -0
- package/dist/extractors/meta-yml-fn.d.ts +19 -0
- package/dist/extractors/meta-yml-fn.d.ts.map +1 -0
- package/dist/extractors/meta-yml-fn.js +66 -0
- package/dist/extractors/meta-yml-fn.js.map +1 -0
- package/dist/extractors/meta-yml.d.ts +24 -0
- package/dist/extractors/meta-yml.d.ts.map +1 -0
- package/dist/extractors/meta-yml.js +65 -0
- package/dist/extractors/meta-yml.js.map +1 -0
- package/dist/extractors/registry.d.ts +58 -0
- package/dist/extractors/registry.d.ts.map +1 -0
- package/dist/extractors/registry.js +114 -0
- package/dist/extractors/registry.js.map +1 -0
- package/dist/extractors/registry.spec.d.ts +2 -0
- package/dist/extractors/registry.spec.d.ts.map +1 -0
- package/dist/extractors/registry.spec.js +102 -0
- package/dist/extractors/registry.spec.js.map +1 -0
- package/dist/extractors/types.d.ts +34 -0
- package/dist/extractors/types.d.ts.map +1 -0
- package/dist/extractors/types.js +8 -0
- package/dist/extractors/types.js.map +1 -0
- package/dist/extractors/yaml-frontmatter-fn.d.ts +18 -0
- package/dist/extractors/yaml-frontmatter-fn.d.ts.map +1 -0
- package/dist/extractors/yaml-frontmatter-fn.js +73 -0
- package/dist/extractors/yaml-frontmatter-fn.js.map +1 -0
- package/dist/extractors/yaml-frontmatter.d.ts +22 -0
- package/dist/extractors/yaml-frontmatter.d.ts.map +1 -0
- package/dist/extractors/yaml-frontmatter.js +83 -0
- package/dist/extractors/yaml-frontmatter.js.map +1 -0
- package/dist/extractors/yaml-frontmatter.spec.d.ts +2 -0
- package/dist/extractors/yaml-frontmatter.spec.d.ts.map +1 -0
- package/dist/extractors/yaml-frontmatter.spec.js +134 -0
- package/dist/extractors/yaml-frontmatter.spec.js.map +1 -0
- package/dist/files/index.d.ts +5 -0
- package/dist/files/index.d.ts.map +1 -0
- package/dist/files/index.js +5 -0
- package/dist/files/index.js.map +1 -0
- package/dist/files/reader.d.ts +50 -0
- package/dist/files/reader.d.ts.map +1 -0
- package/dist/files/reader.js +62 -0
- package/dist/files/reader.js.map +1 -0
- package/dist/index.d.ts +29 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +22 -0
- package/dist/index.js.map +1 -0
- package/dist/plugins/index.d.ts +4 -0
- package/dist/plugins/index.d.ts.map +1 -0
- package/dist/plugins/index.js +4 -0
- package/dist/plugins/index.js.map +1 -0
- package/dist/plugins/pipeline.d.ts +11 -0
- package/dist/plugins/pipeline.d.ts.map +1 -0
- package/dist/plugins/pipeline.js +24 -0
- package/dist/plugins/pipeline.js.map +1 -0
- package/dist/plugins/registry.d.ts +57 -0
- package/dist/plugins/registry.d.ts.map +1 -0
- package/dist/plugins/registry.js +93 -0
- package/dist/plugins/registry.js.map +1 -0
- package/dist/plugins/validation.d.ts +64 -0
- package/dist/plugins/validation.d.ts.map +1 -0
- package/dist/plugins/validation.js +55 -0
- package/dist/plugins/validation.js.map +1 -0
- package/dist/regions/index.d.ts +7 -0
- package/dist/regions/index.d.ts.map +1 -0
- package/dist/regions/index.js +6 -0
- package/dist/regions/index.js.map +1 -0
- package/dist/regions/languages.d.ts +15 -0
- package/dist/regions/languages.d.ts.map +1 -0
- package/dist/regions/languages.js +182 -0
- package/dist/regions/languages.js.map +1 -0
- package/dist/regions/parser.d.ts +63 -0
- package/dist/regions/parser.d.ts.map +1 -0
- package/dist/regions/parser.js +175 -0
- package/dist/regions/parser.js.map +1 -0
- package/dist/regions/parser.spec.d.ts +2 -0
- package/dist/regions/parser.spec.d.ts.map +1 -0
- package/dist/regions/parser.spec.js +190 -0
- package/dist/regions/parser.spec.js.map +1 -0
- package/dist/regions/types.d.ts +37 -0
- package/dist/regions/types.d.ts.map +1 -0
- package/dist/regions/types.js +5 -0
- package/dist/regions/types.js.map +1 -0
- package/dist/scanner/candidates.d.ts +24 -0
- package/dist/scanner/candidates.d.ts.map +1 -0
- package/dist/scanner/candidates.js +83 -0
- package/dist/scanner/candidates.js.map +1 -0
- package/dist/scanner/index.d.ts +8 -0
- package/dist/scanner/index.d.ts.map +1 -0
- package/dist/scanner/index.js +6 -0
- package/dist/scanner/index.js.map +1 -0
- package/dist/scanner/scan.d.ts +40 -0
- package/dist/scanner/scan.d.ts.map +1 -0
- package/dist/scanner/scan.js +44 -0
- package/dist/scanner/scan.js.map +1 -0
- package/dist/scanner/scanner.d.ts +29 -0
- package/dist/scanner/scanner.d.ts.map +1 -0
- package/dist/scanner/scanner.js +296 -0
- package/dist/scanner/scanner.js.map +1 -0
- package/dist/scanner/scanner.spec.d.ts +2 -0
- package/dist/scanner/scanner.spec.d.ts.map +1 -0
- package/dist/scanner/scanner.spec.js +262 -0
- package/dist/scanner/scanner.spec.js.map +1 -0
- package/dist/scanner/types.d.ts +43 -0
- package/dist/scanner/types.d.ts.map +1 -0
- package/dist/scanner/types.js +5 -0
- package/dist/scanner/types.js.map +1 -0
- package/dist/schema/index.d.ts +4 -0
- package/dist/schema/index.d.ts.map +1 -0
- package/dist/schema/index.js +4 -0
- package/dist/schema/index.js.map +1 -0
- package/dist/schema/merger.d.ts +35 -0
- package/dist/schema/merger.d.ts.map +1 -0
- package/dist/schema/merger.js +161 -0
- package/dist/schema/merger.js.map +1 -0
- package/dist/schema/typegen.d.ts +13 -0
- package/dist/schema/typegen.d.ts.map +1 -0
- package/dist/schema/typegen.js +125 -0
- package/dist/schema/typegen.js.map +1 -0
- package/dist/schema/validator.d.ts +7 -0
- package/dist/schema/validator.d.ts.map +1 -0
- package/dist/schema/validator.js +32 -0
- package/dist/schema/validator.js.map +1 -0
- package/dist/types/default-map.d.ts +21 -0
- package/dist/types/default-map.d.ts.map +1 -0
- package/dist/types/default-map.js +32 -0
- package/dist/types/default-map.js.map +1 -0
- package/dist/types/extended-iterable.d.ts +197 -0
- package/dist/types/extended-iterable.d.ts.map +1 -0
- package/dist/types/extended-iterable.js +769 -0
- package/dist/types/extended-iterable.js.map +1 -0
- package/dist/types/guards.d.ts +2 -0
- package/dist/types/guards.d.ts.map +1 -0
- package/dist/types/guards.js +2 -0
- package/dist/types/guards.js.map +1 -0
- package/dist/types/index.d.ts +11 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +10 -0
- package/dist/types/index.js.map +1 -0
- package/package.json +61 -0
package/README.md
ADDED
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
# functional-examples
|
|
2
|
+
|
|
3
|
+
A language-agnostic library for treating code examples as first-class citizens.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **Pluggable metadata extraction**: YAML frontmatter and meta.yml built-in
|
|
8
|
+
- **Language-aware region parsing**: Extracts code regions with comment-style detection
|
|
9
|
+
- **Flexible scanning**: Directory-based and file-based example discovery
|
|
10
|
+
- **Type-safe API**: Full TypeScript support with generic metadata types
|
|
11
|
+
|
|
12
|
+
## Installation
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
npm install functional-examples
|
|
16
|
+
# or
|
|
17
|
+
pnpm add functional-examples
|
|
18
|
+
# or
|
|
19
|
+
yarn add functional-examples
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Quick Start
|
|
23
|
+
|
|
24
|
+
### Scanning for Examples
|
|
25
|
+
|
|
26
|
+
```typescript
|
|
27
|
+
import { scanExamples } from 'functional-examples';
|
|
28
|
+
|
|
29
|
+
const { examples, errors } = await scanExamples('./examples');
|
|
30
|
+
|
|
31
|
+
for (const example of examples) {
|
|
32
|
+
console.log(example.metadata.title);
|
|
33
|
+
console.log(example.files.map(f => f.path));
|
|
34
|
+
}
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### Extracting Code Regions
|
|
38
|
+
|
|
39
|
+
```typescript
|
|
40
|
+
import { extractRegion, parseRegions } from 'functional-examples';
|
|
41
|
+
|
|
42
|
+
// Extract a specific region
|
|
43
|
+
const setupCode = extractRegion(code, 'setup', { extension: 'ts' });
|
|
44
|
+
|
|
45
|
+
// Get all regions
|
|
46
|
+
const regions = parseRegions(code, { extension: 'py' });
|
|
47
|
+
console.log(regions['main']?.content);
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Example Formats
|
|
51
|
+
|
|
52
|
+
### Directory-based (meta.yml)
|
|
53
|
+
|
|
54
|
+
```
|
|
55
|
+
examples/
|
|
56
|
+
my-example/
|
|
57
|
+
meta.yml
|
|
58
|
+
main.ts
|
|
59
|
+
helper.ts
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
**meta.yml:**
|
|
63
|
+
```yaml
|
|
64
|
+
id: my-example
|
|
65
|
+
title: My Example
|
|
66
|
+
description: Demonstrates something useful
|
|
67
|
+
entryPoint: main.ts
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### File-based (YAML frontmatter)
|
|
71
|
+
|
|
72
|
+
```typescript
|
|
73
|
+
// ---
|
|
74
|
+
// title: My Example
|
|
75
|
+
// description: A single-file example
|
|
76
|
+
// ---
|
|
77
|
+
|
|
78
|
+
console.log('Hello, world!');
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## Region Markers
|
|
82
|
+
|
|
83
|
+
Mark regions in your code for extraction:
|
|
84
|
+
|
|
85
|
+
```typescript
|
|
86
|
+
// #region setup
|
|
87
|
+
const db = createDatabase();
|
|
88
|
+
// #endregion setup
|
|
89
|
+
|
|
90
|
+
// #region main
|
|
91
|
+
await db.query('SELECT * FROM users');
|
|
92
|
+
// #endregion main
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
Supports 30+ languages with automatic comment syntax detection.
|
|
96
|
+
|
|
97
|
+
## Custom Extractors
|
|
98
|
+
|
|
99
|
+
```typescript
|
|
100
|
+
import { ExtractorRegistry, MetadataExtractor } from 'functional-examples';
|
|
101
|
+
|
|
102
|
+
class TomlExtractor implements MetadataExtractor {
|
|
103
|
+
readonly name = 'toml';
|
|
104
|
+
|
|
105
|
+
canExtract(context) {
|
|
106
|
+
return context.entries?.includes('meta.toml') ?? false;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
async extract(context) {
|
|
110
|
+
// Custom extraction logic
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
const registry = new ExtractorRegistry()
|
|
115
|
+
.register(new TomlExtractor());
|
|
116
|
+
|
|
117
|
+
const scanner = new ExampleScanner({ extractors: registry });
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
## API Reference
|
|
121
|
+
|
|
122
|
+
### Scanner
|
|
123
|
+
|
|
124
|
+
- `scanExamples(directory, options?)` - Scan a directory for examples
|
|
125
|
+
- `ExampleScanner` - Class for customized scanning
|
|
126
|
+
|
|
127
|
+
### Extractors
|
|
128
|
+
|
|
129
|
+
- `createDefaultRegistry()` - Create registry with built-in extractors
|
|
130
|
+
- `YamlFrontmatterExtractor` - Single-file YAML frontmatter
|
|
131
|
+
- `MetaYmlExtractor` - Directory-based meta.yml
|
|
132
|
+
|
|
133
|
+
### Regions
|
|
134
|
+
|
|
135
|
+
- `parseRegions(code, options?)` - Parse all regions
|
|
136
|
+
- `extractRegion(code, regionId, options?)` - Extract single region
|
|
137
|
+
- `stripRegionMarkers(code, options?)` - Remove all markers
|
|
138
|
+
- `listRegions(code, options?)` - List region IDs
|
|
139
|
+
- `LANGUAGE_CONFIGS` - Language comment syntax mappings
|
|
140
|
+
|
|
141
|
+
### File Helpers
|
|
142
|
+
|
|
143
|
+
- `readExampleFile(path, options?)` - Read file with optional region
|
|
144
|
+
- `readExampleFiles(directory, files)` - Read multiple files
|
|
145
|
+
|
|
146
|
+
## License
|
|
147
|
+
|
|
148
|
+
MIT
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generate command - create JSON Schema and TypeScript types
|
|
3
|
+
*/
|
|
4
|
+
export declare const generateCommand: import("cli-forge").CLI<{
|
|
5
|
+
unmatched: string[];
|
|
6
|
+
'--'?: string[];
|
|
7
|
+
} & {
|
|
8
|
+
output?: string;
|
|
9
|
+
} & {}, Promise<void>, {}, undefined>;
|
|
10
|
+
//# sourceMappingURL=generate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/generate.ts"],"names":[],"mappings":"AAAA;;GAEG;AAcH,eAAO,MAAM,eAAe;;;;;qCAwE1B,CAAC"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generate command - create JSON Schema and TypeScript types
|
|
3
|
+
*/
|
|
4
|
+
import { cli } from 'cli-forge';
|
|
5
|
+
import { mkdir, writeFile } from 'node:fs/promises';
|
|
6
|
+
import path from 'node:path';
|
|
7
|
+
import { mergeConfigSchema, mergeMetadataSchemas, } from '../../schema/merger.js';
|
|
8
|
+
import { generateMetadataTypes } from '../../schema/typegen.js';
|
|
9
|
+
const DEFAULT_OUTPUT_DIR = '.functional-examples';
|
|
10
|
+
export const generateCommand = cli('generate', {
|
|
11
|
+
description: 'Generate JSON Schema and TypeScript types from config and plugins',
|
|
12
|
+
builder: (cmd) => cmd.option('output', {
|
|
13
|
+
type: 'string',
|
|
14
|
+
alias: ['o'],
|
|
15
|
+
description: 'Output directory',
|
|
16
|
+
default: DEFAULT_OUTPUT_DIR,
|
|
17
|
+
}),
|
|
18
|
+
handler: async (options) => {
|
|
19
|
+
try {
|
|
20
|
+
// Load and resolve config
|
|
21
|
+
const opts = options;
|
|
22
|
+
const resolved = opts.resolvedConfig;
|
|
23
|
+
// Get schemas from all plugins
|
|
24
|
+
const pluginSchemas = resolved.registry.getSchemas();
|
|
25
|
+
// Determine output directory
|
|
26
|
+
const outputDir = path.resolve(resolved.root, options.output ?? resolved.generate?.outputDir ?? DEFAULT_OUTPUT_DIR);
|
|
27
|
+
await mkdir(outputDir, { recursive: true });
|
|
28
|
+
// Generate config schema (for IDE autocomplete of config file)
|
|
29
|
+
const configSchema = mergeConfigSchema({ pluginSchemas });
|
|
30
|
+
const schemaPath = path.join(outputDir, 'schema.json');
|
|
31
|
+
await writeFile(schemaPath, JSON.stringify(configSchema, null, 2));
|
|
32
|
+
console.log(`✓ Generated ${schemaPath}`);
|
|
33
|
+
// Merge metadata schemas (config takes priority over plugins)
|
|
34
|
+
const mergedMetadataSchema = mergeMetadataSchemas({
|
|
35
|
+
configSchema: resolved.metadata,
|
|
36
|
+
pluginSchemas,
|
|
37
|
+
});
|
|
38
|
+
// Generate metadata types from merged schema
|
|
39
|
+
const metadataTypes = generateMetadataTypes({
|
|
40
|
+
mergedSchema: mergedMetadataSchema,
|
|
41
|
+
});
|
|
42
|
+
const typesPath = path.join(outputDir, 'metadata.d.ts');
|
|
43
|
+
await writeFile(typesPath, metadataTypes);
|
|
44
|
+
console.log(`✓ Generated ${typesPath}`);
|
|
45
|
+
// Also output the merged metadata schema for reference
|
|
46
|
+
const metadataSchemaPath = path.join(outputDir, 'metadata.schema.json');
|
|
47
|
+
await writeFile(metadataSchemaPath, JSON.stringify(mergedMetadataSchema, null, 2));
|
|
48
|
+
console.log(`✓ Generated ${metadataSchemaPath}`);
|
|
49
|
+
const outputDirName = options.output ?? DEFAULT_OUTPUT_DIR;
|
|
50
|
+
console.log('\nDone! To enable type-safe metadata:');
|
|
51
|
+
console.log('');
|
|
52
|
+
console.log('1. Add to your tsconfig.json include:');
|
|
53
|
+
console.log(` "${outputDirName}/**/*.d.ts"`);
|
|
54
|
+
console.log('');
|
|
55
|
+
console.log('2. Add to your config file for IDE autocomplete:');
|
|
56
|
+
console.log(` "$schema": "./${outputDirName}/schema.json"`);
|
|
57
|
+
}
|
|
58
|
+
catch (error) {
|
|
59
|
+
console.error('Error:', error instanceof Error ? error.message : String(error));
|
|
60
|
+
process.exit(1);
|
|
61
|
+
}
|
|
62
|
+
},
|
|
63
|
+
});
|
|
64
|
+
//# sourceMappingURL=generate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generate.js","sourceRoot":"","sources":["../../../src/cli/commands/generate.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Init command - create a configuration file
|
|
3
|
+
*/
|
|
4
|
+
export declare const initCommand: import("cli-forge").CLI<{
|
|
5
|
+
unmatched: string[];
|
|
6
|
+
'--'?: string[];
|
|
7
|
+
} & {
|
|
8
|
+
format?: "ts" | "json";
|
|
9
|
+
} & {} & {
|
|
10
|
+
output?: string;
|
|
11
|
+
} & {} & {
|
|
12
|
+
force?: boolean;
|
|
13
|
+
} & {}, Promise<void>, {}, undefined>;
|
|
14
|
+
//# sourceMappingURL=init.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/init.ts"],"names":[],"mappings":"AAAA;;GAEG;AA2CH,eAAO,MAAM,WAAW;;;;;;;;;qCAuDtB,CAAC"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Init command - create a configuration file
|
|
3
|
+
*/
|
|
4
|
+
import { cli } from 'cli-forge';
|
|
5
|
+
import { existsSync } from 'node:fs';
|
|
6
|
+
import { writeFile } from 'node:fs/promises';
|
|
7
|
+
import path from 'node:path';
|
|
8
|
+
import { findConfigFile } from '../../config/loader.js';
|
|
9
|
+
const TS_CONFIG_TEMPLATE = `import type { Config } from 'functional-examples';
|
|
10
|
+
|
|
11
|
+
const config: Config = {
|
|
12
|
+
// Extractors to use (auto-detected if not specified)
|
|
13
|
+
// extractors: [
|
|
14
|
+
// '@functional-examples/extractor-frontmatter',
|
|
15
|
+
// '@functional-examples/yaml-manifest',
|
|
16
|
+
// ],
|
|
17
|
+
|
|
18
|
+
// Scan configuration
|
|
19
|
+
scan: {
|
|
20
|
+
// Include patterns (applied after extraction)
|
|
21
|
+
// include: ['*'],
|
|
22
|
+
// Exclude patterns
|
|
23
|
+
// exclude: ['**/node_modules/**', '**/dist/**', '**/.git/**'],
|
|
24
|
+
},
|
|
25
|
+
|
|
26
|
+
// Path mappings for conflict resolution
|
|
27
|
+
// pathMappings: [
|
|
28
|
+
// { pattern: 'legacy/**', extractor: 'frontmatter' },
|
|
29
|
+
// ],
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
export default config;
|
|
33
|
+
`;
|
|
34
|
+
const JSON_CONFIG_TEMPLATE = `{
|
|
35
|
+
"$schema": "./.functional-examples/schema.json",
|
|
36
|
+
"scan": {
|
|
37
|
+
// "include": ["**/*"],
|
|
38
|
+
// "exclude": ["**/node_modules/**", "**/dist/**", "**/.git/**"]
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
`;
|
|
42
|
+
export const initCommand = cli('init', {
|
|
43
|
+
description: 'Create a new configuration file',
|
|
44
|
+
builder: (cmd) => cmd
|
|
45
|
+
.option('format', {
|
|
46
|
+
type: 'string',
|
|
47
|
+
alias: ['f'],
|
|
48
|
+
description: 'Output format',
|
|
49
|
+
choices: ['ts', 'json'],
|
|
50
|
+
default: 'ts',
|
|
51
|
+
})
|
|
52
|
+
.option('output', {
|
|
53
|
+
type: 'string',
|
|
54
|
+
alias: ['o'],
|
|
55
|
+
description: 'Output file path (auto-generated if not specified)',
|
|
56
|
+
})
|
|
57
|
+
.option('force', {
|
|
58
|
+
type: 'boolean',
|
|
59
|
+
description: 'Overwrite existing config file',
|
|
60
|
+
default: false,
|
|
61
|
+
}),
|
|
62
|
+
handler: async (options) => {
|
|
63
|
+
const outputPath = options.output ?? getDefaultOutputPath(options.format);
|
|
64
|
+
const absolutePath = path.resolve(outputPath);
|
|
65
|
+
if (!options.force) {
|
|
66
|
+
const existingConfig = await findConfigFile();
|
|
67
|
+
if (existingConfig) {
|
|
68
|
+
console.log(`Configuration file already exists: ${existingConfig}`);
|
|
69
|
+
console.log('Use --force to overwrite.');
|
|
70
|
+
process.exit(1);
|
|
71
|
+
}
|
|
72
|
+
if (existsSync(absolutePath)) {
|
|
73
|
+
console.log(`File already exists: ${absolutePath}`);
|
|
74
|
+
console.log('Use --force to overwrite.');
|
|
75
|
+
process.exit(1);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
const content = options.format === 'ts' ? TS_CONFIG_TEMPLATE : JSON_CONFIG_TEMPLATE;
|
|
79
|
+
await writeFile(absolutePath, content, 'utf-8');
|
|
80
|
+
console.log(`Created configuration file: ${outputPath}`);
|
|
81
|
+
console.log('');
|
|
82
|
+
console.log('Next steps:');
|
|
83
|
+
console.log(' 1. Install extractors:');
|
|
84
|
+
console.log(' pnpm add @functional-examples/extractor-frontmatter');
|
|
85
|
+
console.log(' pnpm add @functional-examples/yaml-manifest');
|
|
86
|
+
console.log('');
|
|
87
|
+
console.log(' 2. Run the scanner:');
|
|
88
|
+
console.log(' functional-examples scan ./examples');
|
|
89
|
+
},
|
|
90
|
+
});
|
|
91
|
+
function getDefaultOutputPath(format) {
|
|
92
|
+
const ext = format === 'ts' ? '.ts' : '.json';
|
|
93
|
+
return `functional-examples.config${ext}`;
|
|
94
|
+
}
|
|
95
|
+
//# sourceMappingURL=init.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../../src/cli/commands/init.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Scan command - discover examples in a directory
|
|
3
|
+
*/
|
|
4
|
+
export declare const scanCommand: import("cli-forge").CLI<{
|
|
5
|
+
unmatched: string[];
|
|
6
|
+
'--'?: string[];
|
|
7
|
+
} & {
|
|
8
|
+
directory?: string;
|
|
9
|
+
} & {} & {
|
|
10
|
+
config?: string;
|
|
11
|
+
} & {} & {
|
|
12
|
+
format?: "yaml" | "json" | "table";
|
|
13
|
+
} & {} & {
|
|
14
|
+
output?: string;
|
|
15
|
+
} & {} & {
|
|
16
|
+
include?: string[];
|
|
17
|
+
} & {} & {
|
|
18
|
+
exclude?: string[];
|
|
19
|
+
} & {}, Promise<void>, {}, undefined>;
|
|
20
|
+
//# sourceMappingURL=scan.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scan.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/scan.ts"],"names":[],"mappings":"AAAA;;GAEG;AASH,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;qCAiFtB,CAAC"}
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Scan command - discover examples in a directory
|
|
3
|
+
*/
|
|
4
|
+
import { cli } from 'cli-forge';
|
|
5
|
+
import { writeFile } from 'node:fs/promises';
|
|
6
|
+
import path from 'node:path';
|
|
7
|
+
import { scanExamples } from '../../scanner/index.js';
|
|
8
|
+
export const scanCommand = cli('scan', {
|
|
9
|
+
description: 'Scan a directory for code examples',
|
|
10
|
+
builder: (cmd) => cmd
|
|
11
|
+
.option('directory', {
|
|
12
|
+
type: 'string',
|
|
13
|
+
description: 'Directory to scan',
|
|
14
|
+
required: true,
|
|
15
|
+
default: '.',
|
|
16
|
+
})
|
|
17
|
+
.option('config', {
|
|
18
|
+
type: 'string',
|
|
19
|
+
alias: ['c'],
|
|
20
|
+
description: 'Path to config file',
|
|
21
|
+
})
|
|
22
|
+
.option('format', {
|
|
23
|
+
type: 'string',
|
|
24
|
+
alias: ['f'],
|
|
25
|
+
description: 'Output format',
|
|
26
|
+
choices: ['table', 'json', 'yaml'],
|
|
27
|
+
default: 'table',
|
|
28
|
+
})
|
|
29
|
+
.option('output', {
|
|
30
|
+
type: 'string',
|
|
31
|
+
alias: ['o'],
|
|
32
|
+
description: 'Write output to file',
|
|
33
|
+
})
|
|
34
|
+
.option('include', {
|
|
35
|
+
type: 'array',
|
|
36
|
+
items: 'string',
|
|
37
|
+
description: 'Include pattern (can be repeated)',
|
|
38
|
+
default: [],
|
|
39
|
+
})
|
|
40
|
+
.option('exclude', {
|
|
41
|
+
type: 'array',
|
|
42
|
+
items: 'string',
|
|
43
|
+
description: 'Exclude pattern (can be repeated)',
|
|
44
|
+
default: [],
|
|
45
|
+
}),
|
|
46
|
+
handler: async (options) => {
|
|
47
|
+
const directory = options.directory ?? '.';
|
|
48
|
+
const opts = options;
|
|
49
|
+
const config = opts.resolvedConfig;
|
|
50
|
+
if (config.extractors.length === 0) {
|
|
51
|
+
console.error('No extractors available.');
|
|
52
|
+
console.error('Install an extractor package:');
|
|
53
|
+
console.error(' pnpm add @functional-examples/extractor-frontmatter');
|
|
54
|
+
console.error(' pnpm add @functional-examples/yaml-manifest');
|
|
55
|
+
process.exit(1);
|
|
56
|
+
}
|
|
57
|
+
// Use config root when scanning from '.' (default), otherwise use specified directory
|
|
58
|
+
const scanRoot = directory === '.' ? config.root : path.resolve(config.root, directory);
|
|
59
|
+
const result = await scanExamples({
|
|
60
|
+
...config,
|
|
61
|
+
root: scanRoot,
|
|
62
|
+
scan: {
|
|
63
|
+
...config.scan,
|
|
64
|
+
include: options.include.length > 0 ? options.include : config.scan.include,
|
|
65
|
+
exclude: options.exclude.length > 0 ? options.exclude : config.scan.exclude,
|
|
66
|
+
},
|
|
67
|
+
});
|
|
68
|
+
const output = formatOutput(result, options.format);
|
|
69
|
+
if (options.output) {
|
|
70
|
+
await writeFile(options.output, output);
|
|
71
|
+
console.log(`Results written to ${options.output}`);
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
console.log(output);
|
|
75
|
+
}
|
|
76
|
+
if (result.errors.length > 0) {
|
|
77
|
+
process.exit(1);
|
|
78
|
+
}
|
|
79
|
+
},
|
|
80
|
+
});
|
|
81
|
+
function formatOutput(result, format) {
|
|
82
|
+
switch (format) {
|
|
83
|
+
case 'json':
|
|
84
|
+
return JSON.stringify({
|
|
85
|
+
examples: result.examples.map(serializeExample),
|
|
86
|
+
errors: result.errors,
|
|
87
|
+
stats: result.stats,
|
|
88
|
+
}, null, 2);
|
|
89
|
+
case 'yaml':
|
|
90
|
+
return formatYaml(result);
|
|
91
|
+
case 'table':
|
|
92
|
+
default:
|
|
93
|
+
return formatTable(result);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
function serializeExample(example) {
|
|
97
|
+
return {
|
|
98
|
+
id: example.id,
|
|
99
|
+
title: example.title,
|
|
100
|
+
description: example.description,
|
|
101
|
+
rootPath: example.rootPath,
|
|
102
|
+
files: example.files.map((f) => f.relativePath),
|
|
103
|
+
extractorName: example.extractorName,
|
|
104
|
+
metadata: example.metadata,
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
function formatTable(result) {
|
|
108
|
+
const lines = [];
|
|
109
|
+
lines.push(`Found ${result.examples.length} example(s)`);
|
|
110
|
+
lines.push('');
|
|
111
|
+
if (result.examples.length > 0) {
|
|
112
|
+
lines.push(padRight('ID', 30) +
|
|
113
|
+
padRight('Title', 40) +
|
|
114
|
+
padRight('Files', 10) +
|
|
115
|
+
'Extractor');
|
|
116
|
+
lines.push('-'.repeat(90));
|
|
117
|
+
for (const example of result.examples) {
|
|
118
|
+
lines.push(padRight(truncate(example.id, 28), 30) +
|
|
119
|
+
padRight(truncate(example.title, 38), 40) +
|
|
120
|
+
padRight(String(example.files.length), 10) +
|
|
121
|
+
example.extractorName);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
if (result.errors.length > 0) {
|
|
125
|
+
lines.push('');
|
|
126
|
+
lines.push(`Errors (${result.errors.length}):`);
|
|
127
|
+
for (const error of result.errors) {
|
|
128
|
+
lines.push(` - ${error.path}: ${error.message}`);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
if (result.conflicts.length > 0) {
|
|
132
|
+
lines.push('');
|
|
133
|
+
lines.push(`Conflicts (${result.conflicts.length}):`);
|
|
134
|
+
for (const conflict of result.conflicts) {
|
|
135
|
+
const status = conflict.resolution === 'path-mapping' ? '(resolved)' : '(ERROR)';
|
|
136
|
+
lines.push(` - ${conflict.filePath}: claimed by ${conflict.claimants.join(', ')} ${status}`);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
lines.push('');
|
|
140
|
+
lines.push(`Scan completed in ${result.stats.durationMs}ms`);
|
|
141
|
+
return lines.join('\n');
|
|
142
|
+
}
|
|
143
|
+
function formatYaml(result) {
|
|
144
|
+
const lines = [];
|
|
145
|
+
lines.push('examples:');
|
|
146
|
+
for (const example of result.examples) {
|
|
147
|
+
lines.push(` - id: ${example.id}`);
|
|
148
|
+
lines.push(` title: "${example.title}"`);
|
|
149
|
+
if (example.description) {
|
|
150
|
+
lines.push(` description: "${example.description}"`);
|
|
151
|
+
}
|
|
152
|
+
lines.push(` rootPath: ${example.rootPath}`);
|
|
153
|
+
lines.push(` extractor: ${example.extractorName}`);
|
|
154
|
+
lines.push(` files:`);
|
|
155
|
+
for (const file of example.files) {
|
|
156
|
+
lines.push(` - ${file.relativePath}`);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
if (result.errors.length > 0) {
|
|
160
|
+
lines.push('');
|
|
161
|
+
lines.push('errors:');
|
|
162
|
+
for (const error of result.errors) {
|
|
163
|
+
lines.push(` - path: ${error.path}`);
|
|
164
|
+
lines.push(` message: "${error.message}"`);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
lines.push('');
|
|
168
|
+
lines.push('stats:');
|
|
169
|
+
lines.push(` examplesFound: ${result.stats.examplesFound}`);
|
|
170
|
+
lines.push(` filesClaimed: ${result.stats.filesClaimed}`);
|
|
171
|
+
lines.push(` durationMs: ${result.stats.durationMs}`);
|
|
172
|
+
return lines.join('\n');
|
|
173
|
+
}
|
|
174
|
+
function padRight(str, width) {
|
|
175
|
+
return str + ' '.repeat(Math.max(0, width - str.length));
|
|
176
|
+
}
|
|
177
|
+
function truncate(str, maxLength) {
|
|
178
|
+
if (str.length <= maxLength)
|
|
179
|
+
return str;
|
|
180
|
+
return str.slice(0, maxLength - 2) + '..';
|
|
181
|
+
}
|
|
182
|
+
//# sourceMappingURL=scan.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scan.js","sourceRoot":"","sources":["../../../src/cli/commands/scan.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Validate command - validate configuration file
|
|
3
|
+
*/
|
|
4
|
+
export declare const validateCommand: import("cli-forge").CLI<{
|
|
5
|
+
unmatched: string[];
|
|
6
|
+
'--'?: string[];
|
|
7
|
+
} & {
|
|
8
|
+
strict?: boolean;
|
|
9
|
+
} & {}, Promise<void>, {}, undefined>;
|
|
10
|
+
//# sourceMappingURL=validate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/validate.ts"],"names":[],"mappings":"AAAA;;GAEG;AAMH,eAAO,MAAM,eAAe;;;;;qCAkE1B,CAAC"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Validate command - validate configuration file
|
|
3
|
+
*/
|
|
4
|
+
import { cli } from 'cli-forge';
|
|
5
|
+
import { resolveConfig } from '../../config/resolver.js';
|
|
6
|
+
import { validateConfig } from '../../config/validator.js';
|
|
7
|
+
export const validateCommand = cli('validate', {
|
|
8
|
+
description: 'Validate the configuration file',
|
|
9
|
+
builder: (cmd) => cmd.option('strict', {
|
|
10
|
+
type: 'boolean',
|
|
11
|
+
description: 'Treat warnings as errors',
|
|
12
|
+
default: false,
|
|
13
|
+
}),
|
|
14
|
+
handler: async (options) => {
|
|
15
|
+
const opts = options;
|
|
16
|
+
const config = opts.resolvedConfig;
|
|
17
|
+
const configPath = config.root;
|
|
18
|
+
if (!configPath) {
|
|
19
|
+
console.log('No configuration file found.');
|
|
20
|
+
console.log('Run "functional-examples init" to create one.');
|
|
21
|
+
process.exit(0);
|
|
22
|
+
}
|
|
23
|
+
console.log(`Validating: ${configPath}`);
|
|
24
|
+
console.log('');
|
|
25
|
+
const errors = validateConfig(config);
|
|
26
|
+
if (errors.length > 0) {
|
|
27
|
+
console.error('Configuration errors:');
|
|
28
|
+
for (const error of errors) {
|
|
29
|
+
console.error(` - ${error.path}: ${error.message}`);
|
|
30
|
+
}
|
|
31
|
+
process.exit(1);
|
|
32
|
+
}
|
|
33
|
+
try {
|
|
34
|
+
const resolved = await resolveConfig(config);
|
|
35
|
+
console.log('Configuration is valid!');
|
|
36
|
+
console.log('');
|
|
37
|
+
console.log(`Extractors: ${resolved.extractors.length}`);
|
|
38
|
+
for (const extractor of resolved.extractors) {
|
|
39
|
+
console.log(` - ${extractor.name}`);
|
|
40
|
+
}
|
|
41
|
+
if (resolved.pathMappings.length > 0) {
|
|
42
|
+
console.log('');
|
|
43
|
+
console.log(`Path mappings: ${resolved.pathMappings.length}`);
|
|
44
|
+
for (const mapping of resolved.pathMappings) {
|
|
45
|
+
console.log(` - ${mapping.pattern} -> ${mapping.extractor}`);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
console.log('');
|
|
49
|
+
console.log('Scan config:');
|
|
50
|
+
console.log(` include: ${resolved.scan.include.join(', ') || '(all)'}`);
|
|
51
|
+
console.log(` exclude: ${resolved.scan.exclude.join(', ') || '(none)'}`);
|
|
52
|
+
if (resolved.extractors.length === 0 && options.strict) {
|
|
53
|
+
console.error('');
|
|
54
|
+
console.error('Warning: No extractors could be loaded.');
|
|
55
|
+
process.exit(1);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
catch (error) {
|
|
59
|
+
console.error('Failed to resolve configuration:');
|
|
60
|
+
console.error(` ${error.message}`);
|
|
61
|
+
process.exit(1);
|
|
62
|
+
}
|
|
63
|
+
},
|
|
64
|
+
});
|
|
65
|
+
//# sourceMappingURL=validate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate.js","sourceRoot":"","sources":["../../../src/cli/commands/validate.ts"],"names":[],"mappings":"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"}
|