@functional-examples/yaml-manifest 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/dist/extractor.d.ts +53 -0
- package/dist/extractor.d.ts.map +1 -0
- package/dist/extractor.js +156 -0
- package/dist/extractor.js.map +1 -0
- package/dist/extractor.spec.d.ts +1 -0
- package/dist/index.d.ts +32 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +39 -0
- package/dist/index.js.map +1 -0
- package/package.json +51 -0
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Meta.yml extractor for multi-file examples
|
|
3
|
+
*
|
|
4
|
+
* Receives candidates (files and directories) and looks for meta.yml files.
|
|
5
|
+
* Each folder with meta.yml is treated as a multi-file example,
|
|
6
|
+
* where all files in the folder belong to that example.
|
|
7
|
+
*/
|
|
8
|
+
import type { Extractor } from '@functional-examples/devkit';
|
|
9
|
+
/**
|
|
10
|
+
* Options for creating a meta.yml extractor
|
|
11
|
+
*/
|
|
12
|
+
export interface MetaYmlExtractorOptions {
|
|
13
|
+
/**
|
|
14
|
+
* Name of the metadata file to look for.
|
|
15
|
+
* @default 'meta.yml'
|
|
16
|
+
*/
|
|
17
|
+
metaFileName?: string;
|
|
18
|
+
/**
|
|
19
|
+
* Files to exclude from the example (besides the meta file).
|
|
20
|
+
* @default []
|
|
21
|
+
*/
|
|
22
|
+
excludeFiles?: string[];
|
|
23
|
+
/**
|
|
24
|
+
* Patterns to exclude from file collection within examples.
|
|
25
|
+
* @default ['node_modules/**', '.git/**']
|
|
26
|
+
*/
|
|
27
|
+
excludePatterns?: string[];
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Create a meta.yml extractor.
|
|
31
|
+
*
|
|
32
|
+
* Scans for directories containing meta.yml files. Each such directory
|
|
33
|
+
* is treated as a multi-file example with all its contents.
|
|
34
|
+
*
|
|
35
|
+
* @example
|
|
36
|
+
* ```typescript
|
|
37
|
+
* import { createMetaYmlExtractor } from '@functional-examples/yaml-manifest';
|
|
38
|
+
*
|
|
39
|
+
* const extractor = createMetaYmlExtractor({
|
|
40
|
+
* metaFileName: 'meta.yaml', // use different filename
|
|
41
|
+
* });
|
|
42
|
+
*
|
|
43
|
+
* // Use with scanExamples
|
|
44
|
+
* import { scanExamples } from 'functional-examples';
|
|
45
|
+
*
|
|
46
|
+
* const result = await scanExamples({
|
|
47
|
+
* root: './examples',
|
|
48
|
+
* extractors: [extractor],
|
|
49
|
+
* });
|
|
50
|
+
* ```
|
|
51
|
+
*/
|
|
52
|
+
export declare function createMetaYmlExtractor(opts?: MetaYmlExtractorOptions): Extractor;
|
|
53
|
+
//# sourceMappingURL=extractor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extractor.d.ts","sourceRoot":"","sources":["../src/extractor.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAGV,SAAS,EAIV,MAAM,6BAA6B,CAAC;AAMrC;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IAExB;;;OAGG;IACH,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;CAC5B;AAQD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,sBAAsB,CACpC,IAAI,CAAC,EAAE,uBAAuB,GAC7B,SAAS,CA+FX"}
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Meta.yml extractor for multi-file examples
|
|
3
|
+
*
|
|
4
|
+
* Receives candidates (files and directories) and looks for meta.yml files.
|
|
5
|
+
* Each folder with meta.yml is treated as a multi-file example,
|
|
6
|
+
* where all files in the folder belong to that example.
|
|
7
|
+
*/
|
|
8
|
+
import { parseYaml } from '@functional-examples/devkit';
|
|
9
|
+
import { readFile, readdir } from 'node:fs/promises';
|
|
10
|
+
import path from 'node:path';
|
|
11
|
+
const DEFAULT_OPTIONS = {
|
|
12
|
+
metaFileName: 'meta.yml',
|
|
13
|
+
excludeFiles: [],
|
|
14
|
+
excludePatterns: ['node_modules/**', '.git/**'],
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* Create a meta.yml extractor.
|
|
18
|
+
*
|
|
19
|
+
* Scans for directories containing meta.yml files. Each such directory
|
|
20
|
+
* is treated as a multi-file example with all its contents.
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* ```typescript
|
|
24
|
+
* import { createMetaYmlExtractor } from '@functional-examples/yaml-manifest';
|
|
25
|
+
*
|
|
26
|
+
* const extractor = createMetaYmlExtractor({
|
|
27
|
+
* metaFileName: 'meta.yaml', // use different filename
|
|
28
|
+
* });
|
|
29
|
+
*
|
|
30
|
+
* // Use with scanExamples
|
|
31
|
+
* import { scanExamples } from 'functional-examples';
|
|
32
|
+
*
|
|
33
|
+
* const result = await scanExamples({
|
|
34
|
+
* root: './examples',
|
|
35
|
+
* extractors: [extractor],
|
|
36
|
+
* });
|
|
37
|
+
* ```
|
|
38
|
+
*/
|
|
39
|
+
export function createMetaYmlExtractor(opts) {
|
|
40
|
+
const options = { ...DEFAULT_OPTIONS, ...opts };
|
|
41
|
+
async function extractFromManifest(metaPath, exampleDir) {
|
|
42
|
+
const metaContent = await readFile(metaPath, 'utf-8');
|
|
43
|
+
const metadata = (await parseYaml(metaContent));
|
|
44
|
+
const dirName = path.basename(exampleDir);
|
|
45
|
+
const id = metadata.id ?? dirName;
|
|
46
|
+
const files = await collectFiles(exampleDir, [...options.excludeFiles, options.metaFileName], options.excludePatterns);
|
|
47
|
+
const claimedFiles = [metaPath, ...files.map((f) => f.absolutePath)];
|
|
48
|
+
return {
|
|
49
|
+
example: {
|
|
50
|
+
id,
|
|
51
|
+
title: metadata.title ?? dirName,
|
|
52
|
+
description: metadata.description,
|
|
53
|
+
rootPath: exampleDir,
|
|
54
|
+
files,
|
|
55
|
+
metadata,
|
|
56
|
+
extractorName: 'meta-yml',
|
|
57
|
+
},
|
|
58
|
+
claimedFiles,
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
return {
|
|
62
|
+
name: 'meta-yml',
|
|
63
|
+
async extract(candidates, extractorOpts) {
|
|
64
|
+
const examples = [];
|
|
65
|
+
const errors = [];
|
|
66
|
+
const claimedFiles = new Set();
|
|
67
|
+
// Track processed directories to avoid duplicate extraction
|
|
68
|
+
// (when both directory and meta file are candidates)
|
|
69
|
+
const processedDirs = new Set();
|
|
70
|
+
for (const candidate of candidates) {
|
|
71
|
+
if (extractorOpts.signal?.aborted)
|
|
72
|
+
break;
|
|
73
|
+
const fullPath = path.join(candidate.parentPath, candidate.name);
|
|
74
|
+
// File candidate: check if it's our meta file
|
|
75
|
+
if (candidate.isFile() && candidate.name === options.metaFileName) {
|
|
76
|
+
const exampleDir = path.dirname(fullPath);
|
|
77
|
+
// Skip if we already processed this directory
|
|
78
|
+
if (processedDirs.has(exampleDir))
|
|
79
|
+
continue;
|
|
80
|
+
try {
|
|
81
|
+
const result = await extractFromManifest(fullPath, exampleDir);
|
|
82
|
+
examples.push(result.example);
|
|
83
|
+
result.claimedFiles.forEach((f) => claimedFiles.add(f));
|
|
84
|
+
processedDirs.add(exampleDir);
|
|
85
|
+
}
|
|
86
|
+
catch (error) {
|
|
87
|
+
errors.push({
|
|
88
|
+
path: fullPath,
|
|
89
|
+
message: error.message,
|
|
90
|
+
cause: error,
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
continue;
|
|
94
|
+
}
|
|
95
|
+
// Directory candidate: look for meta file inside
|
|
96
|
+
if (candidate.isDirectory()) {
|
|
97
|
+
// Skip if we already processed this directory
|
|
98
|
+
if (processedDirs.has(fullPath))
|
|
99
|
+
continue;
|
|
100
|
+
const metaPath = path.join(fullPath, options.metaFileName);
|
|
101
|
+
try {
|
|
102
|
+
const result = await extractFromManifest(metaPath, fullPath);
|
|
103
|
+
examples.push(result.example);
|
|
104
|
+
result.claimedFiles.forEach((f) => claimedFiles.add(f));
|
|
105
|
+
processedDirs.add(fullPath);
|
|
106
|
+
}
|
|
107
|
+
catch {
|
|
108
|
+
// No meta file in this directory, skip silently
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
return { examples, errors, claimedFiles };
|
|
113
|
+
},
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Recursively collect all files in a directory
|
|
118
|
+
*/
|
|
119
|
+
async function collectFiles(dir, excludeNames, excludePatterns) {
|
|
120
|
+
const files = [];
|
|
121
|
+
async function walk(currentDir, baseDir) {
|
|
122
|
+
const entries = await readdir(currentDir, { withFileTypes: true });
|
|
123
|
+
for (const entry of entries) {
|
|
124
|
+
// Skip excluded files by name
|
|
125
|
+
if (excludeNames.includes(entry.name))
|
|
126
|
+
continue;
|
|
127
|
+
const fullPath = path.join(currentDir, entry.name);
|
|
128
|
+
const relativePath = path.relative(baseDir, fullPath);
|
|
129
|
+
// Check exclude patterns
|
|
130
|
+
if (excludePatterns.some((pattern) => {
|
|
131
|
+
// Simple glob matching
|
|
132
|
+
const regex = new RegExp(pattern
|
|
133
|
+
.replace(/\*\*/g, '<<GLOBSTAR>>')
|
|
134
|
+
.replace(/\*/g, '[^/]*')
|
|
135
|
+
.replace(/<<GLOBSTAR>>/g, '.*'));
|
|
136
|
+
return regex.test(relativePath);
|
|
137
|
+
})) {
|
|
138
|
+
continue;
|
|
139
|
+
}
|
|
140
|
+
if (entry.isDirectory()) {
|
|
141
|
+
await walk(fullPath, baseDir);
|
|
142
|
+
}
|
|
143
|
+
else {
|
|
144
|
+
const raw = await readFile(fullPath, 'utf-8');
|
|
145
|
+
files.push({
|
|
146
|
+
absolutePath: fullPath,
|
|
147
|
+
relativePath,
|
|
148
|
+
raw,
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
await walk(dir, dir);
|
|
154
|
+
return files;
|
|
155
|
+
}
|
|
156
|
+
//# sourceMappingURL=extractor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extractor.js","sourceRoot":"","sources":["../src/extractor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @functional-examples/yaml-manifest
|
|
3
|
+
*
|
|
4
|
+
* YAML manifest plugin for multi-file examples.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* ```typescript
|
|
8
|
+
* import { createYamlManifestPlugin } from '@functional-examples/yaml-manifest';
|
|
9
|
+
* import { scanExamples } from 'functional-examples';
|
|
10
|
+
*
|
|
11
|
+
* const result = await scanExamples({
|
|
12
|
+
* root: './examples',
|
|
13
|
+
* plugins: [createYamlManifestPlugin()],
|
|
14
|
+
* });
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
import type { Plugin } from '@functional-examples/devkit';
|
|
18
|
+
import { createMetaYmlExtractor, type MetaYmlExtractorOptions } from './extractor.js';
|
|
19
|
+
export { createMetaYmlExtractor, type MetaYmlExtractorOptions, } from './extractor.js';
|
|
20
|
+
export declare const createYamlManifestExtractor: typeof createMetaYmlExtractor;
|
|
21
|
+
export type YamlManifestExtractorOptions = MetaYmlExtractorOptions;
|
|
22
|
+
/**
|
|
23
|
+
* Create a YAML manifest plugin for functional-examples.
|
|
24
|
+
*
|
|
25
|
+
* This plugin scans for directories containing meta.yml files,
|
|
26
|
+
* treating each as a multi-file example.
|
|
27
|
+
*
|
|
28
|
+
* Unlike language plugins, this has no extensions (not file-type specific)
|
|
29
|
+
* and no fileContentsParser (manifest is separate from content).
|
|
30
|
+
*/
|
|
31
|
+
export declare function createYamlManifestPlugin(options?: MetaYmlExtractorOptions): Plugin;
|
|
32
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,6BAA6B,CAAC;AAC1D,OAAO,EACL,sBAAsB,EACtB,KAAK,uBAAuB,EAC7B,MAAM,gBAAgB,CAAC;AAGxB,OAAO,EACL,sBAAsB,EACtB,KAAK,uBAAuB,GAC7B,MAAM,gBAAgB,CAAC;AAGxB,eAAO,MAAM,2BAA2B,+BAAyB,CAAC;AAClE,MAAM,MAAM,4BAA4B,GAAG,uBAAuB,CAAC;AAEnE;;;;;;;;GAQG;AACH,wBAAgB,wBAAwB,CACtC,OAAO,CAAC,EAAE,uBAAuB,GAChC,MAAM,CAOR"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @functional-examples/yaml-manifest
|
|
3
|
+
*
|
|
4
|
+
* YAML manifest plugin for multi-file examples.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* ```typescript
|
|
8
|
+
* import { createYamlManifestPlugin } from '@functional-examples/yaml-manifest';
|
|
9
|
+
* import { scanExamples } from 'functional-examples';
|
|
10
|
+
*
|
|
11
|
+
* const result = await scanExamples({
|
|
12
|
+
* root: './examples',
|
|
13
|
+
* plugins: [createYamlManifestPlugin()],
|
|
14
|
+
* });
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
import { createMetaYmlExtractor, } from './extractor.js';
|
|
18
|
+
// Re-export for backward compatibility
|
|
19
|
+
export { createMetaYmlExtractor, } from './extractor.js';
|
|
20
|
+
// New name alias
|
|
21
|
+
export const createYamlManifestExtractor = createMetaYmlExtractor;
|
|
22
|
+
/**
|
|
23
|
+
* Create a YAML manifest plugin for functional-examples.
|
|
24
|
+
*
|
|
25
|
+
* This plugin scans for directories containing meta.yml files,
|
|
26
|
+
* treating each as a multi-file example.
|
|
27
|
+
*
|
|
28
|
+
* Unlike language plugins, this has no extensions (not file-type specific)
|
|
29
|
+
* and no fileContentsParser (manifest is separate from content).
|
|
30
|
+
*/
|
|
31
|
+
export function createYamlManifestPlugin(options) {
|
|
32
|
+
return {
|
|
33
|
+
name: 'yaml-manifest',
|
|
34
|
+
extractor: createMetaYmlExtractor(options),
|
|
35
|
+
// No extensions - not file-type specific
|
|
36
|
+
// No fileContentsParser - manifest is separate from content
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAGH,OAAO,EACL,sBAAsB,GAEvB,MAAM,gBAAgB,CAAC;AAExB,uCAAuC;AACvC,OAAO,EACL,sBAAsB,GAEvB,MAAM,gBAAgB,CAAC;AAExB,iBAAiB;AACjB,MAAM,CAAC,MAAM,2BAA2B,GAAG,sBAAsB,CAAC;AAGlE;;;;;;;;GAQG;AACH,MAAM,UAAU,wBAAwB,CACtC,OAAiC;IAEjC,OAAO;QACL,IAAI,EAAE,eAAe;QACrB,SAAS,EAAE,sBAAsB,CAAC,OAAO,CAAC;QAC1C,yCAAyC;QACzC,4DAA4D;KAC7D,CAAC;AACJ,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@functional-examples/yaml-manifest",
|
|
3
|
+
"version": "0.0.0-alpha.1",
|
|
4
|
+
"description": "YAML manifest plugin for multi-file examples in functional-examples",
|
|
5
|
+
"author": {
|
|
6
|
+
"name": "Craigory Coppola",
|
|
7
|
+
"url": "https://craigory.dev"
|
|
8
|
+
},
|
|
9
|
+
"publishConfig": {
|
|
10
|
+
"access": "public"
|
|
11
|
+
},
|
|
12
|
+
"license": "MIT",
|
|
13
|
+
"type": "module",
|
|
14
|
+
"main": "./dist/index.js",
|
|
15
|
+
"types": "./dist/index.d.ts",
|
|
16
|
+
"exports": {
|
|
17
|
+
".": {
|
|
18
|
+
"import": "./dist/index.js",
|
|
19
|
+
"types": "./dist/index.d.ts",
|
|
20
|
+
"default": "./dist/index.js"
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
"dependencies": {
|
|
24
|
+
"yaml": "^2.7.1",
|
|
25
|
+
"@functional-examples/devkit": "0.0.0-alpha.1"
|
|
26
|
+
},
|
|
27
|
+
"devDependencies": {
|
|
28
|
+
"@types/node": "22.19.8",
|
|
29
|
+
"typescript": "^5.7.2",
|
|
30
|
+
"vitest": "^1.3.1",
|
|
31
|
+
"@functional-examples/devkit": "0.0.0-alpha.1"
|
|
32
|
+
},
|
|
33
|
+
"files": [
|
|
34
|
+
"dist",
|
|
35
|
+
"README.md"
|
|
36
|
+
],
|
|
37
|
+
"homepage": "https://craigory.dev/functional-examples",
|
|
38
|
+
"repository": {
|
|
39
|
+
"type": "git",
|
|
40
|
+
"url": "https://github.com/AgentEnder/functional-examples.git"
|
|
41
|
+
},
|
|
42
|
+
"bugs": {
|
|
43
|
+
"url": "https://github.com/AgentEnder/functional-examples/issues"
|
|
44
|
+
},
|
|
45
|
+
"scripts": {
|
|
46
|
+
"build": "tsc -p tsconfig.lib.json",
|
|
47
|
+
"test": "vitest run",
|
|
48
|
+
"test:watch": "vitest",
|
|
49
|
+
"lint": "eslint ."
|
|
50
|
+
}
|
|
51
|
+
}
|