@hstm-labs/forge-spec-parser 0.1.2
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 +53 -0
- package/dist/default-registry.d.ts +19 -0
- package/dist/default-registry.d.ts.map +1 -0
- package/dist/default-registry.js +28 -0
- package/dist/default-registry.js.map +1 -0
- package/dist/detect.d.ts +16 -0
- package/dist/detect.d.ts.map +1 -0
- package/dist/detect.js +32 -0
- package/dist/detect.js.map +1 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +23 -0
- package/dist/index.js.map +1 -0
- package/dist/loader.d.ts +31 -0
- package/dist/loader.d.ts.map +1 -0
- package/dist/loader.js +45 -0
- package/dist/loader.js.map +1 -0
- package/dist/parser-plugin.d.ts +23 -0
- package/dist/parser-plugin.d.ts.map +1 -0
- package/dist/parser-plugin.js +8 -0
- package/dist/parser-plugin.js.map +1 -0
- package/dist/parsers/json-parser.d.ts +35 -0
- package/dist/parsers/json-parser.d.ts.map +1 -0
- package/dist/parsers/json-parser.js +46 -0
- package/dist/parsers/json-parser.js.map +1 -0
- package/dist/parsers/markdown-parser.d.ts +41 -0
- package/dist/parsers/markdown-parser.d.ts.map +1 -0
- package/dist/parsers/markdown-parser.js +606 -0
- package/dist/parsers/markdown-parser.js.map +1 -0
- package/dist/parsers/structured-mapper.d.ts +22 -0
- package/dist/parsers/structured-mapper.d.ts.map +1 -0
- package/dist/parsers/structured-mapper.js +214 -0
- package/dist/parsers/structured-mapper.js.map +1 -0
- package/dist/parsers/yaml-parser.d.ts +35 -0
- package/dist/parsers/yaml-parser.d.ts.map +1 -0
- package/dist/parsers/yaml-parser.js +47 -0
- package/dist/parsers/yaml-parser.js.map +1 -0
- package/dist/registry.d.ts +57 -0
- package/dist/registry.d.ts.map +1 -0
- package/dist/registry.js +80 -0
- package/dist/registry.js.map +1 -0
- package/dist/types.d.ts +85 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +8 -0
- package/dist/types.js.map +1 -0
- package/dist/validate-stage.d.ts +18 -0
- package/dist/validate-stage.d.ts.map +1 -0
- package/dist/validate-stage.js +24 -0
- package/dist/validate-stage.js.map +1 -0
- package/dist/validation-types.d.ts +46 -0
- package/dist/validation-types.d.ts.map +1 -0
- package/dist/validation-types.js +9 -0
- package/dist/validation-types.js.map +1 -0
- package/dist/validators/completeness-checker.d.ts +29 -0
- package/dist/validators/completeness-checker.d.ts.map +1 -0
- package/dist/validators/completeness-checker.js +127 -0
- package/dist/validators/completeness-checker.js.map +1 -0
- package/dist/validators/cross-reference-validator.d.ts +17 -0
- package/dist/validators/cross-reference-validator.d.ts.map +1 -0
- package/dist/validators/cross-reference-validator.js +150 -0
- package/dist/validators/cross-reference-validator.js.map +1 -0
- package/dist/validators/schema-validator.d.ts +16 -0
- package/dist/validators/schema-validator.d.ts.map +1 -0
- package/dist/validators/schema-validator.js +146 -0
- package/dist/validators/schema-validator.js.map +1 -0
- package/dist/validators/spec-validator.d.ts +15 -0
- package/dist/validators/spec-validator.d.ts.map +1 -0
- package/dist/validators/spec-validator.js +52 -0
- package/dist/validators/spec-validator.js.map +1 -0
- package/package.json +29 -0
package/README.md
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# @hstm-labs/forge-spec-parser
|
|
2
|
+
|
|
3
|
+
Specification parsing and validation for Forge — reads product specifications in Markdown, YAML, or JSON format and produces a canonical `ParsedSpecification` model with completeness scoring and cross-reference validation.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @hstm-labs/forge-spec-parser
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Public API
|
|
12
|
+
|
|
13
|
+
### Parsing
|
|
14
|
+
|
|
15
|
+
- `parseSpec(content, format)` — parse specification content into canonical model
|
|
16
|
+
- `loadSpecFile(path)` — load and parse a specification file
|
|
17
|
+
- `detectFormat(path)` — auto-detect specification format
|
|
18
|
+
- `ParserRegistry` — plugin registry for format parsers
|
|
19
|
+
- `createDefaultRegistry()` — factory for registry with all built-in parsers
|
|
20
|
+
|
|
21
|
+
### Parser Plugins
|
|
22
|
+
|
|
23
|
+
- `MarkdownParserPlugin` — GFM Markdown with entity/requirement extraction
|
|
24
|
+
- `YamlParserPlugin` — structured YAML specifications
|
|
25
|
+
- `JsonParserPlugin` — structured JSON specifications
|
|
26
|
+
- `mapStructuredSpec()` — shared mapper for YAML/JSON formats
|
|
27
|
+
|
|
28
|
+
### Validation
|
|
29
|
+
|
|
30
|
+
- `validateSpec(spec)` — full validation (schema + completeness + cross-references)
|
|
31
|
+
- `validateSchema(spec)` — schema validation
|
|
32
|
+
- `checkCompleteness(spec)` — 6-dimension completeness scoring
|
|
33
|
+
- `validateCrossReferences(spec)` — entity/requirement reference integrity
|
|
34
|
+
|
|
35
|
+
### Types
|
|
36
|
+
|
|
37
|
+
- `ParsedSpecification` — canonical specification model
|
|
38
|
+
- `SpecRequirement`, `SpecEntity`, `SpecWorkflow` — specification components
|
|
39
|
+
- `ValidationReport`, `ValidationFinding` — validation output
|
|
40
|
+
|
|
41
|
+
## Usage
|
|
42
|
+
|
|
43
|
+
```typescript
|
|
44
|
+
import { loadSpecFile, validateSpec } from '@hstm-labs/forge-spec-parser';
|
|
45
|
+
|
|
46
|
+
const spec = await loadSpecFile('specs/product-spec.md');
|
|
47
|
+
const report = validateSpec(spec);
|
|
48
|
+
console.log(`Completeness: ${report.completeness.overall}%`);
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## License
|
|
52
|
+
|
|
53
|
+
[MIT](../../LICENSE)
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Factory for creating a pre-configured parser registry.
|
|
3
|
+
*
|
|
4
|
+
* Returns a {@link ParserRegistry} with all built-in parser plugins
|
|
5
|
+
* registered, ready for use with {@link parseSpec}.
|
|
6
|
+
*/
|
|
7
|
+
import { ParserRegistry } from './registry.js';
|
|
8
|
+
/**
|
|
9
|
+
* Create a parser registry pre-loaded with all built-in parser plugins.
|
|
10
|
+
*
|
|
11
|
+
* Currently registers:
|
|
12
|
+
* - {@link MarkdownParserPlugin} — `.md` files
|
|
13
|
+
* - {@link YamlParserPlugin} — `.yaml`, `.yml` files
|
|
14
|
+
* - {@link JsonParserPlugin} — `.json` files
|
|
15
|
+
*
|
|
16
|
+
* @returns A fully-configured {@link ParserRegistry}
|
|
17
|
+
*/
|
|
18
|
+
export declare function createDefaultRegistry(): ParserRegistry;
|
|
19
|
+
//# sourceMappingURL=default-registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"default-registry.d.ts","sourceRoot":"","sources":["../src/default-registry.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAK/C;;;;;;;;;GASG;AACH,wBAAgB,qBAAqB,IAAI,cAAc,CAMtD"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Factory for creating a pre-configured parser registry.
|
|
3
|
+
*
|
|
4
|
+
* Returns a {@link ParserRegistry} with all built-in parser plugins
|
|
5
|
+
* registered, ready for use with {@link parseSpec}.
|
|
6
|
+
*/
|
|
7
|
+
import { ParserRegistry } from './registry.js';
|
|
8
|
+
import { MarkdownParserPlugin } from './parsers/markdown-parser.js';
|
|
9
|
+
import { YamlParserPlugin } from './parsers/yaml-parser.js';
|
|
10
|
+
import { JsonParserPlugin } from './parsers/json-parser.js';
|
|
11
|
+
/**
|
|
12
|
+
* Create a parser registry pre-loaded with all built-in parser plugins.
|
|
13
|
+
*
|
|
14
|
+
* Currently registers:
|
|
15
|
+
* - {@link MarkdownParserPlugin} — `.md` files
|
|
16
|
+
* - {@link YamlParserPlugin} — `.yaml`, `.yml` files
|
|
17
|
+
* - {@link JsonParserPlugin} — `.json` files
|
|
18
|
+
*
|
|
19
|
+
* @returns A fully-configured {@link ParserRegistry}
|
|
20
|
+
*/
|
|
21
|
+
export function createDefaultRegistry() {
|
|
22
|
+
const registry = new ParserRegistry();
|
|
23
|
+
registry.register(new MarkdownParserPlugin());
|
|
24
|
+
registry.register(new YamlParserPlugin());
|
|
25
|
+
registry.register(new JsonParserPlugin());
|
|
26
|
+
return registry;
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=default-registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"default-registry.js","sourceRoot":"","sources":["../src/default-registry.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AACpE,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAE5D;;;;;;;;;GASG;AACH,MAAM,UAAU,qBAAqB;IACnC,MAAM,QAAQ,GAAG,IAAI,cAAc,EAAE,CAAC;IACtC,QAAQ,CAAC,QAAQ,CAAC,IAAI,oBAAoB,EAAE,CAAC,CAAC;IAC9C,QAAQ,CAAC,QAAQ,CAAC,IAAI,gBAAgB,EAAE,CAAC,CAAC;IAC1C,QAAQ,CAAC,QAAQ,CAAC,IAAI,gBAAgB,EAAE,CAAC,CAAC;IAC1C,OAAO,QAAQ,CAAC;AAClB,CAAC"}
|
package/dist/detect.d.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Format auto-detection for specification files.
|
|
3
|
+
*
|
|
4
|
+
* Determines the {@link SpecFormat} of a specification file based on its
|
|
5
|
+
* file extension.
|
|
6
|
+
*/
|
|
7
|
+
import type { SpecFormat } from './types.js';
|
|
8
|
+
/**
|
|
9
|
+
* Detect the specification format from a file's extension.
|
|
10
|
+
*
|
|
11
|
+
* @param filePath - Path to the specification file
|
|
12
|
+
* @returns The detected specification format
|
|
13
|
+
* @throws {@link ForgeError} with code `FORGE-SPEC-001` if the extension is unsupported
|
|
14
|
+
*/
|
|
15
|
+
export declare function detectFormat(filePath: string): SpecFormat;
|
|
16
|
+
//# sourceMappingURL=detect.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"detect.d.ts","sourceRoot":"","sources":["../src/detect.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAa7C;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,UAAU,CAWzD"}
|
package/dist/detect.js
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Format auto-detection for specification files.
|
|
3
|
+
*
|
|
4
|
+
* Determines the {@link SpecFormat} of a specification file based on its
|
|
5
|
+
* file extension.
|
|
6
|
+
*/
|
|
7
|
+
import path from 'node:path';
|
|
8
|
+
import { ForgeError, ErrorCodes } from '@hstm-labs/forge-common';
|
|
9
|
+
/** Map of file extensions to specification formats. */
|
|
10
|
+
const EXTENSION_MAP = new Map([
|
|
11
|
+
['.md', 'markdown'],
|
|
12
|
+
['.yaml', 'yaml'],
|
|
13
|
+
['.yml', 'yaml'],
|
|
14
|
+
['.json', 'json'],
|
|
15
|
+
]);
|
|
16
|
+
/**
|
|
17
|
+
* Detect the specification format from a file's extension.
|
|
18
|
+
*
|
|
19
|
+
* @param filePath - Path to the specification file
|
|
20
|
+
* @returns The detected specification format
|
|
21
|
+
* @throws {@link ForgeError} with code `FORGE-SPEC-001` if the extension is unsupported
|
|
22
|
+
*/
|
|
23
|
+
export function detectFormat(filePath) {
|
|
24
|
+
const ext = path.extname(filePath).toLowerCase();
|
|
25
|
+
const format = EXTENSION_MAP.get(ext);
|
|
26
|
+
if (!format) {
|
|
27
|
+
throw new ForgeError(ErrorCodes.SPEC.PARSE_FAILURE, `Unsupported specification format: '${ext || '(no extension)'}'. ` +
|
|
28
|
+
`Supported: .md, .yaml, .yml, .json`);
|
|
29
|
+
}
|
|
30
|
+
return format;
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=detect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"detect.js","sourceRoot":"","sources":["../src/detect.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAGjE,uDAAuD;AACvD,MAAM,aAAa,GAAoC,IAAI,GAAG,CAG5D;IACA,CAAC,KAAK,EAAE,UAAU,CAAC;IACnB,CAAC,OAAO,EAAE,MAAM,CAAC;IACjB,CAAC,MAAM,EAAE,MAAM,CAAC;IAChB,CAAC,OAAO,EAAE,MAAM,CAAC;CAClB,CAAC,CAAC;AAEH;;;;;;GAMG;AACH,MAAM,UAAU,YAAY,CAAC,QAAgB;IAC3C,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,WAAW,EAAE,CAAC;IACjD,MAAM,MAAM,GAAG,aAAa,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACtC,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,UAAU,CAClB,UAAU,CAAC,IAAI,CAAC,aAAa,EAC7B,sCAAsC,GAAG,IAAI,gBAAgB,KAAK;YAChE,oCAAoC,CACvC,CAAC;IACJ,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export type { SpecFormat, ParsedSpecification, SpecMetadata, SpecSection, SpecRequirement, SpecEntity, EntityField, EntityRelationship, SpecWorkflow, WorkflowStep, } from './types.js';
|
|
2
|
+
export type { SpecParserPlugin } from './parser-plugin.js';
|
|
3
|
+
export { ParserRegistry } from './registry.js';
|
|
4
|
+
export { detectFormat } from './detect.js';
|
|
5
|
+
export { loadSpecFile, parseSpec } from './loader.js';
|
|
6
|
+
export { MarkdownParserPlugin } from './parsers/markdown-parser.js';
|
|
7
|
+
export { YamlParserPlugin } from './parsers/yaml-parser.js';
|
|
8
|
+
export { JsonParserPlugin } from './parsers/json-parser.js';
|
|
9
|
+
export { mapStructuredSpec } from './parsers/structured-mapper.js';
|
|
10
|
+
export { createDefaultRegistry } from './default-registry.js';
|
|
11
|
+
export type { ValidationSeverity, ValidationCategory, ValidationFinding, ValidationReport, } from './validation-types.js';
|
|
12
|
+
export { validateSchema } from './validators/schema-validator.js';
|
|
13
|
+
export { checkCompleteness } from './validators/completeness-checker.js';
|
|
14
|
+
export type { CompletenessResult } from './validators/completeness-checker.js';
|
|
15
|
+
export { validateCrossReferences } from './validators/cross-reference-validator.js';
|
|
16
|
+
export { validateSpec } from './validators/spec-validator.js';
|
|
17
|
+
export { executeValidateStage } from './validate-stage.js';
|
|
18
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,YAAY,EACV,UAAU,EACV,mBAAmB,EACnB,YAAY,EACZ,WAAW,EACX,eAAe,EACf,UAAU,EACV,WAAW,EACX,kBAAkB,EAClB,YAAY,EACZ,YAAY,GACb,MAAM,YAAY,CAAC;AAGpB,YAAY,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAG3D,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAG/C,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAG3C,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAGtD,OAAO,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AACpE,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAG5D,OAAO,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAC;AAGnE,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAG9D,YAAY,EACV,kBAAkB,EAClB,kBAAkB,EAClB,iBAAiB,EACjB,gBAAgB,GACjB,MAAM,uBAAuB,CAAC;AAG/B,OAAO,EAAE,cAAc,EAAE,MAAM,kCAAkC,CAAC;AAClE,OAAO,EAAE,iBAAiB,EAAE,MAAM,sCAAsC,CAAC;AACzE,YAAY,EAAE,kBAAkB,EAAE,MAAM,sCAAsC,CAAC;AAC/E,OAAO,EAAE,uBAAuB,EAAE,MAAM,2CAA2C,CAAC;AACpF,OAAO,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC;AAG9D,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
// @hstm-labs/forge-spec-parser public API
|
|
2
|
+
// Parser registry
|
|
3
|
+
export { ParserRegistry } from './registry.js';
|
|
4
|
+
// Format detection
|
|
5
|
+
export { detectFormat } from './detect.js';
|
|
6
|
+
// File loading and parse entry point
|
|
7
|
+
export { loadSpecFile, parseSpec } from './loader.js';
|
|
8
|
+
// Parser plugins
|
|
9
|
+
export { MarkdownParserPlugin } from './parsers/markdown-parser.js';
|
|
10
|
+
export { YamlParserPlugin } from './parsers/yaml-parser.js';
|
|
11
|
+
export { JsonParserPlugin } from './parsers/json-parser.js';
|
|
12
|
+
// Shared structured mapper
|
|
13
|
+
export { mapStructuredSpec } from './parsers/structured-mapper.js';
|
|
14
|
+
// Default registry factory
|
|
15
|
+
export { createDefaultRegistry } from './default-registry.js';
|
|
16
|
+
// Validators
|
|
17
|
+
export { validateSchema } from './validators/schema-validator.js';
|
|
18
|
+
export { checkCompleteness } from './validators/completeness-checker.js';
|
|
19
|
+
export { validateCrossReferences } from './validators/cross-reference-validator.js';
|
|
20
|
+
export { validateSpec } from './validators/spec-validator.js';
|
|
21
|
+
// Validate stage integration
|
|
22
|
+
export { executeValidateStage } from './validate-stage.js';
|
|
23
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,0CAA0C;AAmB1C,kBAAkB;AAClB,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAE/C,mBAAmB;AACnB,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,qCAAqC;AACrC,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAEtD,iBAAiB;AACjB,OAAO,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AACpE,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAE5D,2BAA2B;AAC3B,OAAO,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAC;AAEnE,2BAA2B;AAC3B,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAU9D,aAAa;AACb,OAAO,EAAE,cAAc,EAAE,MAAM,kCAAkC,CAAC;AAClE,OAAO,EAAE,iBAAiB,EAAE,MAAM,sCAAsC,CAAC;AAEzE,OAAO,EAAE,uBAAuB,EAAE,MAAM,2CAA2C,CAAC;AACpF,OAAO,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC;AAE9D,6BAA6B;AAC7B,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC"}
|
package/dist/loader.d.ts
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Specification file loader and primary parse entry point.
|
|
3
|
+
*
|
|
4
|
+
* Provides {@link loadSpecFile} for reading raw file content and
|
|
5
|
+
* {@link parseSpec} as the main public API for parsing a specification
|
|
6
|
+
* file into the canonical {@link ParsedSpecification} model.
|
|
7
|
+
*/
|
|
8
|
+
import type { ParsedSpecification } from './types.js';
|
|
9
|
+
import type { ParserRegistry } from './registry.js';
|
|
10
|
+
/**
|
|
11
|
+
* Read the content of a specification file from disk.
|
|
12
|
+
*
|
|
13
|
+
* @param filePath - Absolute or relative path to the specification file
|
|
14
|
+
* @returns The file content as a UTF-8 string
|
|
15
|
+
* @throws {@link ForgeError} with code `FORGE-SPEC-001` if the file cannot be read
|
|
16
|
+
*/
|
|
17
|
+
export declare function loadSpecFile(filePath: string): string;
|
|
18
|
+
/**
|
|
19
|
+
* Parse a specification file into the canonical model.
|
|
20
|
+
*
|
|
21
|
+
* Detects the file format, selects the appropriate parser plugin from the
|
|
22
|
+
* registry, reads the file content, and delegates to the plugin's `parse`
|
|
23
|
+
* method.
|
|
24
|
+
*
|
|
25
|
+
* @param filePath - Path to the specification file
|
|
26
|
+
* @param registry - Parser registry with registered format plugins
|
|
27
|
+
* @returns Parsed specification
|
|
28
|
+
* @throws {@link ForgeError} with code `FORGE-SPEC-001` if format detection, file reading, or parsing fails
|
|
29
|
+
*/
|
|
30
|
+
export declare function parseSpec(filePath: string, registry: ParserRegistry): ParsedSpecification;
|
|
31
|
+
//# sourceMappingURL=loader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../src/loader.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAEtD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAEpD;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAWrD;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,SAAS,CACvB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,cAAc,GACvB,mBAAmB,CAKrB"}
|
package/dist/loader.js
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Specification file loader and primary parse entry point.
|
|
3
|
+
*
|
|
4
|
+
* Provides {@link loadSpecFile} for reading raw file content and
|
|
5
|
+
* {@link parseSpec} as the main public API for parsing a specification
|
|
6
|
+
* file into the canonical {@link ParsedSpecification} model.
|
|
7
|
+
*/
|
|
8
|
+
import fs from 'node:fs';
|
|
9
|
+
import { ForgeError, ErrorCodes } from '@hstm-labs/forge-common';
|
|
10
|
+
import { detectFormat } from './detect.js';
|
|
11
|
+
/**
|
|
12
|
+
* Read the content of a specification file from disk.
|
|
13
|
+
*
|
|
14
|
+
* @param filePath - Absolute or relative path to the specification file
|
|
15
|
+
* @returns The file content as a UTF-8 string
|
|
16
|
+
* @throws {@link ForgeError} with code `FORGE-SPEC-001` if the file cannot be read
|
|
17
|
+
*/
|
|
18
|
+
export function loadSpecFile(filePath) {
|
|
19
|
+
try {
|
|
20
|
+
return fs.readFileSync(filePath, 'utf-8');
|
|
21
|
+
}
|
|
22
|
+
catch (error) {
|
|
23
|
+
throw new ForgeError(ErrorCodes.SPEC.PARSE_FAILURE, `Failed to read specification file '${filePath}'. ` +
|
|
24
|
+
`Ensure the file exists and is readable, then retry.`, error instanceof Error ? { cause: error } : {});
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Parse a specification file into the canonical model.
|
|
29
|
+
*
|
|
30
|
+
* Detects the file format, selects the appropriate parser plugin from the
|
|
31
|
+
* registry, reads the file content, and delegates to the plugin's `parse`
|
|
32
|
+
* method.
|
|
33
|
+
*
|
|
34
|
+
* @param filePath - Path to the specification file
|
|
35
|
+
* @param registry - Parser registry with registered format plugins
|
|
36
|
+
* @returns Parsed specification
|
|
37
|
+
* @throws {@link ForgeError} with code `FORGE-SPEC-001` if format detection, file reading, or parsing fails
|
|
38
|
+
*/
|
|
39
|
+
export function parseSpec(filePath, registry) {
|
|
40
|
+
const format = detectFormat(filePath);
|
|
41
|
+
const plugin = registry.getParser(format);
|
|
42
|
+
const content = loadSpecFile(filePath);
|
|
43
|
+
return plugin.parse(content, filePath);
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=loader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loader.js","sourceRoot":"","sources":["../src/loader.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAEjE,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAG3C;;;;;;GAMG;AACH,MAAM,UAAU,YAAY,CAAC,QAAgB;IAC3C,IAAI,CAAC;QACH,OAAO,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAC5C,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,UAAU,CAClB,UAAU,CAAC,IAAI,CAAC,aAAa,EAC7B,sCAAsC,QAAQ,KAAK;YACjD,qDAAqD,EACvD,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAC/C,CAAC;IACJ,CAAC;AACH,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,SAAS,CACvB,QAAgB,EAChB,QAAwB;IAExB,MAAM,MAAM,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAC;IACtC,MAAM,MAAM,GAAG,QAAQ,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;IAC1C,MAAM,OAAO,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAC;IACvC,OAAO,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;AACzC,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Plugin interface for format-specific specification parsers.
|
|
3
|
+
*
|
|
4
|
+
* Each plugin handles a single {@link SpecFormat} and converts raw file
|
|
5
|
+
* content into the canonical {@link ParsedSpecification} model.
|
|
6
|
+
*/
|
|
7
|
+
import type { ParsedSpecification, SpecFormat } from './types.js';
|
|
8
|
+
/** Contract that all format-specific parsers must implement. */
|
|
9
|
+
export interface SpecParserPlugin {
|
|
10
|
+
/** Format this plugin handles. */
|
|
11
|
+
readonly format: SpecFormat;
|
|
12
|
+
/** File extensions this plugin handles (e.g. `['.md']`). */
|
|
13
|
+
readonly extensions: string[];
|
|
14
|
+
/**
|
|
15
|
+
* Parse raw content into the canonical specification model.
|
|
16
|
+
*
|
|
17
|
+
* @param content - Raw file content as a string
|
|
18
|
+
* @param sourcePath - Original file path (used for metadata)
|
|
19
|
+
* @returns Parsed specification
|
|
20
|
+
*/
|
|
21
|
+
parse(content: string, sourcePath: string): ParsedSpecification;
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=parser-plugin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parser-plugin.d.ts","sourceRoot":"","sources":["../src/parser-plugin.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,mBAAmB,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAElE,gEAAgE;AAChE,MAAM,WAAW,gBAAgB;IAC/B,kCAAkC;IAClC,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;IAE5B,4DAA4D;IAC5D,QAAQ,CAAC,UAAU,EAAE,MAAM,EAAE,CAAC;IAE9B;;;;;;OAMG;IACH,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,mBAAmB,CAAC;CACjE"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Plugin interface for format-specific specification parsers.
|
|
3
|
+
*
|
|
4
|
+
* Each plugin handles a single {@link SpecFormat} and converts raw file
|
|
5
|
+
* content into the canonical {@link ParsedSpecification} model.
|
|
6
|
+
*/
|
|
7
|
+
export {};
|
|
8
|
+
//# sourceMappingURL=parser-plugin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parser-plugin.js","sourceRoot":"","sources":["../src/parser-plugin.ts"],"names":[],"mappings":"AAAA;;;;;GAKG"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* JSON specification parser plugin.
|
|
3
|
+
*
|
|
4
|
+
* Parses structured JSON specification files into the canonical
|
|
5
|
+
* {@link ParsedSpecification} model by delegating to the shared
|
|
6
|
+
* structured mapper after JSON parsing.
|
|
7
|
+
*/
|
|
8
|
+
import type { SpecParserPlugin } from '../parser-plugin.js';
|
|
9
|
+
import type { ParsedSpecification, SpecFormat } from '../types.js';
|
|
10
|
+
/**
|
|
11
|
+
* Parser plugin for JSON specification files (`.json`).
|
|
12
|
+
*
|
|
13
|
+
* Expects a structured JSON object with top-level fields matching
|
|
14
|
+
* the {@link ParsedSpecification} shape (title, requirements, entities, etc.).
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```ts
|
|
18
|
+
* const plugin = new JsonParserPlugin();
|
|
19
|
+
* const spec = plugin.parse(jsonContent, '/path/to/spec.json');
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
export declare class JsonParserPlugin implements SpecParserPlugin {
|
|
23
|
+
readonly format: SpecFormat;
|
|
24
|
+
readonly extensions: string[];
|
|
25
|
+
/**
|
|
26
|
+
* Parse JSON specification content into the canonical model.
|
|
27
|
+
*
|
|
28
|
+
* @param content - Raw JSON content
|
|
29
|
+
* @param sourcePath - Original file path
|
|
30
|
+
* @returns Parsed specification
|
|
31
|
+
* @throws {@link ForgeError} with code `FORGE-SPEC-001` if JSON parsing fails or title is missing
|
|
32
|
+
*/
|
|
33
|
+
parse(content: string, sourcePath: string): ParsedSpecification;
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=json-parser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"json-parser.d.ts","sourceRoot":"","sources":["../../src/parsers/json-parser.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,KAAK,EAAE,mBAAmB,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAGnE;;;;;;;;;;;GAWG;AACH,qBAAa,gBAAiB,YAAW,gBAAgB;IACvD,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAU;IACrC,QAAQ,CAAC,UAAU,EAAE,MAAM,EAAE,CAAa;IAE1C;;;;;;;OAOG;IACH,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,mBAAmB;CAgBhE"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* JSON specification parser plugin.
|
|
3
|
+
*
|
|
4
|
+
* Parses structured JSON specification files into the canonical
|
|
5
|
+
* {@link ParsedSpecification} model by delegating to the shared
|
|
6
|
+
* structured mapper after JSON parsing.
|
|
7
|
+
*/
|
|
8
|
+
import { ForgeError, ErrorCodes } from '@hstm-labs/forge-common';
|
|
9
|
+
import { mapStructuredSpec } from './structured-mapper.js';
|
|
10
|
+
/**
|
|
11
|
+
* Parser plugin for JSON specification files (`.json`).
|
|
12
|
+
*
|
|
13
|
+
* Expects a structured JSON object with top-level fields matching
|
|
14
|
+
* the {@link ParsedSpecification} shape (title, requirements, entities, etc.).
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```ts
|
|
18
|
+
* const plugin = new JsonParserPlugin();
|
|
19
|
+
* const spec = plugin.parse(jsonContent, '/path/to/spec.json');
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
export class JsonParserPlugin {
|
|
23
|
+
format = 'json';
|
|
24
|
+
extensions = ['.json'];
|
|
25
|
+
/**
|
|
26
|
+
* Parse JSON specification content into the canonical model.
|
|
27
|
+
*
|
|
28
|
+
* @param content - Raw JSON content
|
|
29
|
+
* @param sourcePath - Original file path
|
|
30
|
+
* @returns Parsed specification
|
|
31
|
+
* @throws {@link ForgeError} with code `FORGE-SPEC-001` if JSON parsing fails or title is missing
|
|
32
|
+
*/
|
|
33
|
+
parse(content, sourcePath) {
|
|
34
|
+
let data;
|
|
35
|
+
try {
|
|
36
|
+
data = JSON.parse(content);
|
|
37
|
+
}
|
|
38
|
+
catch (error) {
|
|
39
|
+
throw new ForgeError(ErrorCodes.SPEC.PARSE_FAILURE, `Invalid JSON in specification file '${sourcePath}': ` +
|
|
40
|
+
`${error instanceof Error ? error.message : String(error)}. ` +
|
|
41
|
+
`Verify the file contains valid JSON.`, error instanceof Error ? { cause: error } : {});
|
|
42
|
+
}
|
|
43
|
+
return mapStructuredSpec(data, sourcePath, 'json');
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=json-parser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"json-parser.js","sourceRoot":"","sources":["../../src/parsers/json-parser.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAGjE,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAE3D;;;;;;;;;;;GAWG;AACH,MAAM,OAAO,gBAAgB;IAClB,MAAM,GAAe,MAAM,CAAC;IAC5B,UAAU,GAAa,CAAC,OAAO,CAAC,CAAC;IAE1C;;;;;;;OAOG;IACH,KAAK,CAAC,OAAe,EAAE,UAAkB;QACvC,IAAI,IAAa,CAAC;QAClB,IAAI,CAAC;YACH,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAY,CAAC;QACxC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,IAAI,UAAU,CAClB,UAAU,CAAC,IAAI,CAAC,aAAa,EAC7B,uCAAuC,UAAU,KAAK;gBACpD,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI;gBAC7D,sCAAsC,EACxC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAC/C,CAAC;QACJ,CAAC;QAED,OAAO,iBAAiB,CAAC,IAAI,EAAE,UAAU,EAAE,MAAM,CAAC,CAAC;IACrD,CAAC;CACF"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Markdown specification parser plugin.
|
|
3
|
+
*
|
|
4
|
+
* Converts rich Markdown specification documents into the canonical
|
|
5
|
+
* {@link ParsedSpecification} model using a two-phase pipeline:
|
|
6
|
+
* 1. Markdown → mdast (Abstract Syntax Tree) via unified/remark
|
|
7
|
+
* 2. mdast → ParsedSpecification via AST walking and extraction
|
|
8
|
+
*/
|
|
9
|
+
import type { SpecParserPlugin } from '../parser-plugin.js';
|
|
10
|
+
import type { ParsedSpecification, SpecFormat } from '../types.js';
|
|
11
|
+
/**
|
|
12
|
+
* Parser plugin for Markdown specification files.
|
|
13
|
+
*
|
|
14
|
+
* Implements the two-phase Markdown → AST → ParsedSpecification pipeline.
|
|
15
|
+
* Supports YAML frontmatter, GFM tables, task lists, and ordered lists.
|
|
16
|
+
*/
|
|
17
|
+
export declare class MarkdownParserPlugin implements SpecParserPlugin {
|
|
18
|
+
readonly format: SpecFormat;
|
|
19
|
+
readonly extensions: string[];
|
|
20
|
+
/**
|
|
21
|
+
* Parse a Markdown specification into the canonical model.
|
|
22
|
+
*
|
|
23
|
+
* @param content - Raw Markdown content
|
|
24
|
+
* @param sourcePath - Original file path
|
|
25
|
+
* @returns Parsed specification
|
|
26
|
+
*/
|
|
27
|
+
parse(content: string, sourcePath: string): ParsedSpecification;
|
|
28
|
+
private extractMetadata;
|
|
29
|
+
private extractSections;
|
|
30
|
+
private extractRequirements;
|
|
31
|
+
private listItemToRequirement;
|
|
32
|
+
private extractEntities;
|
|
33
|
+
private extractEntitiesFromNodes;
|
|
34
|
+
private buildEntity;
|
|
35
|
+
private parseTableFields;
|
|
36
|
+
private parseListFields;
|
|
37
|
+
private extractWorkflows;
|
|
38
|
+
private buildWorkflow;
|
|
39
|
+
private detectApiStyle;
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=markdown-parser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"markdown-parser.d.ts","sourceRoot":"","sources":["../../src/parsers/markdown-parser.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAkBH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,KAAK,EACV,mBAAmB,EASnB,UAAU,EACX,MAAM,aAAa,CAAC;AA6OrB;;;;;GAKG;AACH,qBAAa,oBAAqB,YAAW,gBAAgB;IAC3D,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAc;IACzC,QAAQ,CAAC,UAAU,EAAE,MAAM,EAAE,CAAW;IAExC;;;;;;OAMG;IACH,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,mBAAmB;IAmC/D,OAAO,CAAC,eAAe;IA0DvB,OAAO,CAAC,eAAe;IAwDvB,OAAO,CAAC,mBAAmB;IAqB3B,OAAO,CAAC,qBAAqB;IAmD7B,OAAO,CAAC,eAAe;IAavB,OAAO,CAAC,wBAAwB;IAsEhC,OAAO,CAAC,WAAW;IAenB,OAAO,CAAC,gBAAgB;IAsDxB,OAAO,CAAC,eAAe;IAyCvB,OAAO,CAAC,gBAAgB;IA6CxB,OAAO,CAAC,aAAa;IA2DrB,OAAO,CAAC,cAAc;CAUvB"}
|