@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.
Files changed (70) hide show
  1. package/README.md +53 -0
  2. package/dist/default-registry.d.ts +19 -0
  3. package/dist/default-registry.d.ts.map +1 -0
  4. package/dist/default-registry.js +28 -0
  5. package/dist/default-registry.js.map +1 -0
  6. package/dist/detect.d.ts +16 -0
  7. package/dist/detect.d.ts.map +1 -0
  8. package/dist/detect.js +32 -0
  9. package/dist/detect.js.map +1 -0
  10. package/dist/index.d.ts +18 -0
  11. package/dist/index.d.ts.map +1 -0
  12. package/dist/index.js +23 -0
  13. package/dist/index.js.map +1 -0
  14. package/dist/loader.d.ts +31 -0
  15. package/dist/loader.d.ts.map +1 -0
  16. package/dist/loader.js +45 -0
  17. package/dist/loader.js.map +1 -0
  18. package/dist/parser-plugin.d.ts +23 -0
  19. package/dist/parser-plugin.d.ts.map +1 -0
  20. package/dist/parser-plugin.js +8 -0
  21. package/dist/parser-plugin.js.map +1 -0
  22. package/dist/parsers/json-parser.d.ts +35 -0
  23. package/dist/parsers/json-parser.d.ts.map +1 -0
  24. package/dist/parsers/json-parser.js +46 -0
  25. package/dist/parsers/json-parser.js.map +1 -0
  26. package/dist/parsers/markdown-parser.d.ts +41 -0
  27. package/dist/parsers/markdown-parser.d.ts.map +1 -0
  28. package/dist/parsers/markdown-parser.js +606 -0
  29. package/dist/parsers/markdown-parser.js.map +1 -0
  30. package/dist/parsers/structured-mapper.d.ts +22 -0
  31. package/dist/parsers/structured-mapper.d.ts.map +1 -0
  32. package/dist/parsers/structured-mapper.js +214 -0
  33. package/dist/parsers/structured-mapper.js.map +1 -0
  34. package/dist/parsers/yaml-parser.d.ts +35 -0
  35. package/dist/parsers/yaml-parser.d.ts.map +1 -0
  36. package/dist/parsers/yaml-parser.js +47 -0
  37. package/dist/parsers/yaml-parser.js.map +1 -0
  38. package/dist/registry.d.ts +57 -0
  39. package/dist/registry.d.ts.map +1 -0
  40. package/dist/registry.js +80 -0
  41. package/dist/registry.js.map +1 -0
  42. package/dist/types.d.ts +85 -0
  43. package/dist/types.d.ts.map +1 -0
  44. package/dist/types.js +8 -0
  45. package/dist/types.js.map +1 -0
  46. package/dist/validate-stage.d.ts +18 -0
  47. package/dist/validate-stage.d.ts.map +1 -0
  48. package/dist/validate-stage.js +24 -0
  49. package/dist/validate-stage.js.map +1 -0
  50. package/dist/validation-types.d.ts +46 -0
  51. package/dist/validation-types.d.ts.map +1 -0
  52. package/dist/validation-types.js +9 -0
  53. package/dist/validation-types.js.map +1 -0
  54. package/dist/validators/completeness-checker.d.ts +29 -0
  55. package/dist/validators/completeness-checker.d.ts.map +1 -0
  56. package/dist/validators/completeness-checker.js +127 -0
  57. package/dist/validators/completeness-checker.js.map +1 -0
  58. package/dist/validators/cross-reference-validator.d.ts +17 -0
  59. package/dist/validators/cross-reference-validator.d.ts.map +1 -0
  60. package/dist/validators/cross-reference-validator.js +150 -0
  61. package/dist/validators/cross-reference-validator.js.map +1 -0
  62. package/dist/validators/schema-validator.d.ts +16 -0
  63. package/dist/validators/schema-validator.d.ts.map +1 -0
  64. package/dist/validators/schema-validator.js +146 -0
  65. package/dist/validators/schema-validator.js.map +1 -0
  66. package/dist/validators/spec-validator.d.ts +15 -0
  67. package/dist/validators/spec-validator.d.ts.map +1 -0
  68. package/dist/validators/spec-validator.js +52 -0
  69. package/dist/validators/spec-validator.js.map +1 -0
  70. package/package.json +29 -0
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Types for specification validation reports.
3
+ *
4
+ * Validation produces a structured {@link ValidationReport} containing
5
+ * individual {@link ValidationFinding} entries from schema, completeness,
6
+ * and cross-reference checks.
7
+ */
8
+ /** Severity level of a validation finding. */
9
+ export type ValidationSeverity = 'error' | 'warning' | 'info';
10
+ /** Category of validation check that produced the finding. */
11
+ export type ValidationCategory = 'schema' | 'completeness' | 'cross-reference' | 'consistency';
12
+ /** A single validation finding with remediation guidance. */
13
+ export interface ValidationFinding {
14
+ /** Finding identifier (e.g. `VAL-001`). */
15
+ id: string;
16
+ /** Severity level. */
17
+ severity: ValidationSeverity;
18
+ /** Category of the check that produced this finding. */
19
+ category: ValidationCategory;
20
+ /** Human-readable description of the issue. */
21
+ message: string;
22
+ /** Guidance on how to fix the issue. */
23
+ remediation: string;
24
+ /** Optional location reference (section, entity, or requirement). */
25
+ location?: string | undefined;
26
+ }
27
+ /** Aggregated validation report for a parsed specification. */
28
+ export interface ValidationReport {
29
+ /** Path to the specification file that was validated. */
30
+ specPath: string;
31
+ /** `true` if no error-severity findings exist (warnings are acceptable). */
32
+ valid: boolean;
33
+ /** Completeness score from 0.0 (empty) to 1.0 (fully complete). */
34
+ completenessScore: number;
35
+ /** All findings from schema, completeness, and cross-reference checks. */
36
+ findings: ValidationFinding[];
37
+ /** Summary counts by severity. */
38
+ summary: {
39
+ errors: number;
40
+ warnings: number;
41
+ info: number;
42
+ };
43
+ /** ISO 8601 timestamp when the validation was performed. */
44
+ checkedAt: string;
45
+ }
46
+ //# sourceMappingURL=validation-types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validation-types.d.ts","sourceRoot":"","sources":["../src/validation-types.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAMH,8CAA8C;AAC9C,MAAM,MAAM,kBAAkB,GAAG,OAAO,GAAG,SAAS,GAAG,MAAM,CAAC;AAE9D,8DAA8D;AAC9D,MAAM,MAAM,kBAAkB,GAC1B,QAAQ,GACR,cAAc,GACd,iBAAiB,GACjB,aAAa,CAAC;AAElB,6DAA6D;AAC7D,MAAM,WAAW,iBAAiB;IAChC,2CAA2C;IAC3C,EAAE,EAAE,MAAM,CAAC;IACX,sBAAsB;IACtB,QAAQ,EAAE,kBAAkB,CAAC;IAC7B,wDAAwD;IACxD,QAAQ,EAAE,kBAAkB,CAAC;IAC7B,+CAA+C;IAC/C,OAAO,EAAE,MAAM,CAAC;IAChB,wCAAwC;IACxC,WAAW,EAAE,MAAM,CAAC;IACpB,qEAAqE;IACrE,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC/B;AAMD,+DAA+D;AAC/D,MAAM,WAAW,gBAAgB;IAC/B,yDAAyD;IACzD,QAAQ,EAAE,MAAM,CAAC;IACjB,4EAA4E;IAC5E,KAAK,EAAE,OAAO,CAAC;IACf,mEAAmE;IACnE,iBAAiB,EAAE,MAAM,CAAC;IAC1B,0EAA0E;IAC1E,QAAQ,EAAE,iBAAiB,EAAE,CAAC;IAC9B,kCAAkC;IAClC,OAAO,EAAE;QACP,MAAM,EAAE,MAAM,CAAC;QACf,QAAQ,EAAE,MAAM,CAAC;QACjB,IAAI,EAAE,MAAM,CAAC;KACd,CAAC;IACF,4DAA4D;IAC5D,SAAS,EAAE,MAAM,CAAC;CACnB"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Types for specification validation reports.
3
+ *
4
+ * Validation produces a structured {@link ValidationReport} containing
5
+ * individual {@link ValidationFinding} entries from schema, completeness,
6
+ * and cross-reference checks.
7
+ */
8
+ export {};
9
+ //# sourceMappingURL=validation-types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validation-types.js","sourceRoot":"","sources":["../src/validation-types.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Completeness checker — analyses how thoroughly a specification covers
3
+ * the expected dimensions and produces a score with findings.
4
+ */
5
+ import type { ParsedSpecification } from '../types.js';
6
+ import type { ValidationFinding } from '../validation-types.js';
7
+ /** Result of a completeness check. */
8
+ export interface CompletenessResult {
9
+ /** Completeness score from 0.0 to 1.0. */
10
+ score: number;
11
+ /** Findings for missing or incomplete dimensions. */
12
+ findings: ValidationFinding[];
13
+ }
14
+ /**
15
+ * Analyse specification completeness across multiple dimensions.
16
+ *
17
+ * Dimensions (each contributes equally to the score):
18
+ * 1. Has requirements
19
+ * 2. Has entities
20
+ * 3. Has workflows
21
+ * 4. Has acceptance criteria on at least one requirement
22
+ * 5. All entities have at least one field
23
+ * 6. All requirements have non-empty descriptions
24
+ *
25
+ * @param spec - The parsed specification to analyse
26
+ * @returns Score and findings
27
+ */
28
+ export declare function checkCompleteness(spec: ParsedSpecification): CompletenessResult;
29
+ //# sourceMappingURL=completeness-checker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"completeness-checker.d.ts","sourceRoot":"","sources":["../../src/validators/completeness-checker.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AACvD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAEhE,sCAAsC;AACtC,MAAM,WAAW,kBAAkB;IACjC,0CAA0C;IAC1C,KAAK,EAAE,MAAM,CAAC;IACd,qDAAqD;IACrD,QAAQ,EAAE,iBAAiB,EAAE,CAAC;CAC/B;AAKD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,mBAAmB,GACxB,kBAAkB,CA0HpB"}
@@ -0,0 +1,127 @@
1
+ /**
2
+ * Completeness checker — analyses how thoroughly a specification covers
3
+ * the expected dimensions and produces a score with findings.
4
+ */
5
+ /** Total number of completeness dimensions evaluated. */
6
+ const TOTAL_DIMENSIONS = 6;
7
+ /**
8
+ * Analyse specification completeness across multiple dimensions.
9
+ *
10
+ * Dimensions (each contributes equally to the score):
11
+ * 1. Has requirements
12
+ * 2. Has entities
13
+ * 3. Has workflows
14
+ * 4. Has acceptance criteria on at least one requirement
15
+ * 5. All entities have at least one field
16
+ * 6. All requirements have non-empty descriptions
17
+ *
18
+ * @param spec - The parsed specification to analyse
19
+ * @returns Score and findings
20
+ */
21
+ export function checkCompleteness(spec) {
22
+ const findings = [];
23
+ let counter = 0;
24
+ let coveredDimensions = 0;
25
+ function nextId() {
26
+ counter++;
27
+ return `VAL-C${String(counter).padStart(3, '0')}`;
28
+ }
29
+ // --- Dimension 1: Has requirements ---
30
+ if (spec.requirements.length > 0) {
31
+ coveredDimensions++;
32
+ }
33
+ else {
34
+ findings.push({
35
+ id: nextId(),
36
+ severity: 'warning',
37
+ category: 'completeness',
38
+ message: 'No requirements defined in specification.',
39
+ remediation: 'Add requirements describing expected functionality to improve specification completeness.',
40
+ });
41
+ }
42
+ // --- Dimension 2: Has entities ---
43
+ if (spec.entities.length > 0) {
44
+ coveredDimensions++;
45
+ }
46
+ else {
47
+ findings.push({
48
+ id: nextId(),
49
+ severity: 'warning',
50
+ category: 'completeness',
51
+ message: 'No entities defined in specification.',
52
+ remediation: 'Add entities describing the data model to improve specification completeness.',
53
+ });
54
+ }
55
+ // --- Dimension 3: Has workflows ---
56
+ if (spec.workflows.length > 0) {
57
+ coveredDimensions++;
58
+ }
59
+ else {
60
+ findings.push({
61
+ id: nextId(),
62
+ severity: 'warning',
63
+ category: 'completeness',
64
+ message: 'No workflows defined in specification.',
65
+ remediation: 'Add workflows describing user flows or use cases to improve specification completeness.',
66
+ });
67
+ }
68
+ // --- Dimension 4: At least one requirement has acceptance criteria ---
69
+ const hasAnyCriteria = spec.requirements.some((r) => r.acceptanceCriteria.length > 0);
70
+ if (hasAnyCriteria) {
71
+ coveredDimensions++;
72
+ }
73
+ else if (spec.requirements.length > 0) {
74
+ findings.push({
75
+ id: nextId(),
76
+ severity: 'warning',
77
+ category: 'completeness',
78
+ message: 'No requirements have acceptance criteria defined.',
79
+ remediation: 'Add acceptance criteria to at least one requirement to clarify expected behaviour.',
80
+ });
81
+ }
82
+ // --- Dimension 5: All entities have at least one field ---
83
+ if (spec.entities.length > 0) {
84
+ const allHaveFields = spec.entities.every((e) => e.fields.length > 0);
85
+ if (allHaveFields) {
86
+ coveredDimensions++;
87
+ }
88
+ else {
89
+ const incomplete = spec.entities
90
+ .filter((e) => e.fields.length === 0)
91
+ .map((e) => e.name || '(unnamed)');
92
+ for (const name of incomplete) {
93
+ findings.push({
94
+ id: nextId(),
95
+ severity: 'warning',
96
+ category: 'completeness',
97
+ message: `Entity '${name}' has no fields defined.`,
98
+ remediation: `Add fields to entity '${name}' describing its data structure.`,
99
+ location: `entity:${name}`,
100
+ });
101
+ }
102
+ }
103
+ }
104
+ // --- Dimension 6: All requirements have descriptions ---
105
+ if (spec.requirements.length > 0) {
106
+ const allDescribed = spec.requirements.every((r) => r.description.trim().length > 0);
107
+ if (allDescribed) {
108
+ coveredDimensions++;
109
+ }
110
+ else {
111
+ const missing = spec.requirements.filter((r) => !r.description.trim());
112
+ for (const req of missing) {
113
+ findings.push({
114
+ id: nextId(),
115
+ severity: 'info',
116
+ category: 'completeness',
117
+ message: `Requirement '${req.id || '(no id)'}' has no description.`,
118
+ remediation: `Add a description to requirement '${req.id || '(no id)'}' explaining its intent.`,
119
+ location: `requirement:${req.id}`,
120
+ });
121
+ }
122
+ }
123
+ }
124
+ const score = TOTAL_DIMENSIONS > 0 ? coveredDimensions / TOTAL_DIMENSIONS : 0;
125
+ return { score, findings };
126
+ }
127
+ //# sourceMappingURL=completeness-checker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"completeness-checker.js","sourceRoot":"","sources":["../../src/validators/completeness-checker.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Cross-reference validator — checks referential integrity within a
3
+ * parsed specification.
4
+ *
5
+ * Validates that relationship targets exist, workflow step text references
6
+ * known entities, and that identifiers are unique.
7
+ */
8
+ import type { ParsedSpecification } from '../types.js';
9
+ import type { ValidationFinding } from '../validation-types.js';
10
+ /**
11
+ * Validate cross-references and referential integrity within a specification.
12
+ *
13
+ * @param spec - The parsed specification to validate
14
+ * @returns Array of findings (empty if all references are valid)
15
+ */
16
+ export declare function validateCrossReferences(spec: ParsedSpecification): ValidationFinding[];
17
+ //# sourceMappingURL=cross-reference-validator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cross-reference-validator.d.ts","sourceRoot":"","sources":["../../src/validators/cross-reference-validator.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AACvD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAEhE;;;;;GAKG;AACH,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,mBAAmB,GACxB,iBAAiB,EAAE,CA+HrB"}
@@ -0,0 +1,150 @@
1
+ /**
2
+ * Cross-reference validator — checks referential integrity within a
3
+ * parsed specification.
4
+ *
5
+ * Validates that relationship targets exist, workflow step text references
6
+ * known entities, and that identifiers are unique.
7
+ */
8
+ /**
9
+ * Validate cross-references and referential integrity within a specification.
10
+ *
11
+ * @param spec - The parsed specification to validate
12
+ * @returns Array of findings (empty if all references are valid)
13
+ */
14
+ export function validateCrossReferences(spec) {
15
+ const findings = [];
16
+ let counter = 0;
17
+ function nextId() {
18
+ counter++;
19
+ return `VAL-X${String(counter).padStart(3, '0')}`;
20
+ }
21
+ const entityNames = new Set(spec.entities.map((e) => e.name.toLowerCase()));
22
+ // --- Entity relationship targets ---
23
+ for (const entity of spec.entities) {
24
+ for (const rel of entity.relationships) {
25
+ // Check singular and plural forms
26
+ const target = rel.target.toLowerCase();
27
+ const targetSingular = target.endsWith('s')
28
+ ? target.slice(0, -1)
29
+ : target;
30
+ if (!entityNames.has(target) &&
31
+ !entityNames.has(targetSingular)) {
32
+ findings.push({
33
+ id: nextId(),
34
+ severity: 'error',
35
+ category: 'cross-reference',
36
+ message: `Entity '${entity.name}' has a relationship targeting '${rel.target}', but no entity with that name exists.`,
37
+ remediation: `Define an entity named '${rel.target}' or correct the relationship target in entity '${entity.name}'.`,
38
+ location: `entity:${entity.name}.relationship:${rel.target}`,
39
+ });
40
+ }
41
+ }
42
+ }
43
+ // --- Workflow entity references (heuristic) ---
44
+ for (const workflow of spec.workflows) {
45
+ const stepText = workflow.steps
46
+ .map((s) => s.action)
47
+ .join(' ');
48
+ for (const entity of spec.entities) {
49
+ if (!entity.name)
50
+ continue;
51
+ // Check if entity name appears in workflow steps but entity
52
+ // is not in the defined list — this is already covered above.
53
+ // Instead, flag entity names mentioned in workflows where
54
+ // the entity is referenced by a name that doesn't match any
55
+ // known entity (for non-defined entities mentioned in text).
56
+ }
57
+ // Scan for capitalized words that look like entity names but
58
+ // aren't defined
59
+ const wordPattern = /\b([A-Z][a-z]+(?:[A-Z][a-z]+)*)\b/g;
60
+ let match;
61
+ const seen = new Set();
62
+ while ((match = wordPattern.exec(stepText)) !== null) {
63
+ const word = match[1];
64
+ const lower = word.toLowerCase();
65
+ // Skip common non-entity words
66
+ if (isCommonWord(lower))
67
+ continue;
68
+ // Skip already seen
69
+ if (seen.has(lower))
70
+ continue;
71
+ seen.add(lower);
72
+ // Only flag if there are defined entities to compare against
73
+ // and the word looks like it could be an entity reference
74
+ if (spec.entities.length > 0 &&
75
+ !entityNames.has(lower) &&
76
+ !entityNames.has(lower.endsWith('s') ? lower.slice(0, -1) : lower)) {
77
+ // Heuristic: only warn, don't error
78
+ // Skip — too many false positives from actor names and
79
+ // generic words. Only flag if an entity section explicitly
80
+ // references it.
81
+ }
82
+ }
83
+ }
84
+ // --- Duplicate requirement IDs ---
85
+ const reqIdCounts = new Map();
86
+ for (const req of spec.requirements) {
87
+ if (!req.id)
88
+ continue;
89
+ reqIdCounts.set(req.id, (reqIdCounts.get(req.id) ?? 0) + 1);
90
+ }
91
+ for (const [id, count] of reqIdCounts) {
92
+ if (count > 1) {
93
+ findings.push({
94
+ id: nextId(),
95
+ severity: 'error',
96
+ category: 'cross-reference',
97
+ message: `Duplicate requirement ID '${id}' found ${String(count)} times.`,
98
+ remediation: `Assign unique IDs to each requirement. Rename duplicates of '${id}'.`,
99
+ location: `requirement:${id}`,
100
+ });
101
+ }
102
+ }
103
+ // --- Duplicate entity names ---
104
+ const entityNameCounts = new Map();
105
+ for (const entity of spec.entities) {
106
+ if (!entity.name)
107
+ continue;
108
+ const key = entity.name.toLowerCase();
109
+ entityNameCounts.set(key, (entityNameCounts.get(key) ?? 0) + 1);
110
+ }
111
+ for (const [name, count] of entityNameCounts) {
112
+ if (count > 1) {
113
+ findings.push({
114
+ id: nextId(),
115
+ severity: 'error',
116
+ category: 'cross-reference',
117
+ message: `Duplicate entity name '${name}' found ${String(count)} times.`,
118
+ remediation: `Rename duplicate entities so each has a unique name.`,
119
+ location: `entity:${name}`,
120
+ });
121
+ }
122
+ }
123
+ return findings;
124
+ }
125
+ /** Common words that should not be flagged as potential entity references. */
126
+ function isCommonWord(word) {
127
+ const common = new Set([
128
+ 'user',
129
+ 'system',
130
+ 'admin',
131
+ 'client',
132
+ 'server',
133
+ 'the',
134
+ 'form',
135
+ 'page',
136
+ 'data',
137
+ 'input',
138
+ 'output',
139
+ 'error',
140
+ 'success',
141
+ 'task',
142
+ 'step',
143
+ 'action',
144
+ 'result',
145
+ 'request',
146
+ 'response',
147
+ ]);
148
+ return common.has(word);
149
+ }
150
+ //# sourceMappingURL=cross-reference-validator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cross-reference-validator.js","sourceRoot":"","sources":["../../src/validators/cross-reference-validator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Schema validator — validates the structural integrity of a
3
+ * {@link ParsedSpecification}.
4
+ *
5
+ * Checks required fields, non-empty values, and structural constraints.
6
+ */
7
+ import type { ParsedSpecification } from '../types.js';
8
+ import type { ValidationFinding } from '../validation-types.js';
9
+ /**
10
+ * Validate the structural integrity of a parsed specification.
11
+ *
12
+ * @param spec - The parsed specification to validate
13
+ * @returns Array of findings (empty if fully valid)
14
+ */
15
+ export declare function validateSchema(spec: ParsedSpecification): ValidationFinding[];
16
+ //# sourceMappingURL=schema-validator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema-validator.d.ts","sourceRoot":"","sources":["../../src/validators/schema-validator.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AACvD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAEhE;;;;;GAKG;AACH,wBAAgB,cAAc,CAC5B,IAAI,EAAE,mBAAmB,GACxB,iBAAiB,EAAE,CAiKrB"}
@@ -0,0 +1,146 @@
1
+ /**
2
+ * Schema validator — validates the structural integrity of a
3
+ * {@link ParsedSpecification}.
4
+ *
5
+ * Checks required fields, non-empty values, and structural constraints.
6
+ */
7
+ /**
8
+ * Validate the structural integrity of a parsed specification.
9
+ *
10
+ * @param spec - The parsed specification to validate
11
+ * @returns Array of findings (empty if fully valid)
12
+ */
13
+ export function validateSchema(spec) {
14
+ const findings = [];
15
+ let counter = 0;
16
+ function nextId() {
17
+ counter++;
18
+ return `VAL-S${String(counter).padStart(3, '0')}`;
19
+ }
20
+ // --- Metadata checks ---
21
+ if (!spec.metadata.title) {
22
+ findings.push({
23
+ id: nextId(),
24
+ severity: 'error',
25
+ category: 'schema',
26
+ message: 'Specification metadata is missing a title.',
27
+ remediation: 'Add a non-empty title to the specification metadata (frontmatter or top-level field).',
28
+ location: 'metadata.title',
29
+ });
30
+ }
31
+ if (!spec.metadata.sourcePath) {
32
+ findings.push({
33
+ id: nextId(),
34
+ severity: 'error',
35
+ category: 'schema',
36
+ message: 'Specification metadata is missing a source path.',
37
+ remediation: 'Ensure the specification is loaded from a valid file path.',
38
+ location: 'metadata.sourcePath',
39
+ });
40
+ }
41
+ // --- Collection-level checks ---
42
+ if (spec.requirements.length === 0) {
43
+ findings.push({
44
+ id: nextId(),
45
+ severity: 'warning',
46
+ category: 'schema',
47
+ message: 'Specification has no requirements defined.',
48
+ remediation: 'Add at least one requirement to the specification to describe expected functionality.',
49
+ });
50
+ }
51
+ if (spec.entities.length === 0) {
52
+ findings.push({
53
+ id: nextId(),
54
+ severity: 'warning',
55
+ category: 'schema',
56
+ message: 'Specification has no entities defined.',
57
+ remediation: 'Add at least one entity to the specification to describe the data model.',
58
+ });
59
+ }
60
+ // --- Requirement-level checks ---
61
+ for (let i = 0; i < spec.requirements.length; i++) {
62
+ const req = spec.requirements[i];
63
+ const loc = `requirements[${String(i)}]`;
64
+ if (!req.id) {
65
+ findings.push({
66
+ id: nextId(),
67
+ severity: 'error',
68
+ category: 'schema',
69
+ message: `Requirement at index ${String(i)} is missing an id.`,
70
+ remediation: 'Assign a unique identifier to this requirement (e.g. REQ-001).',
71
+ location: `${loc}.id`,
72
+ });
73
+ }
74
+ if (!req.title) {
75
+ findings.push({
76
+ id: nextId(),
77
+ severity: 'error',
78
+ category: 'schema',
79
+ message: `Requirement '${req.id || `[index ${String(i)}]`}' is missing a title.`,
80
+ remediation: 'Add a non-empty title summarising this requirement.',
81
+ location: `${loc}.title`,
82
+ });
83
+ }
84
+ if (!req.description) {
85
+ findings.push({
86
+ id: nextId(),
87
+ severity: 'error',
88
+ category: 'schema',
89
+ message: `Requirement '${req.id || `[index ${String(i)}]`}' is missing a description.`,
90
+ remediation: 'Add a non-empty description explaining this requirement.',
91
+ location: `${loc}.description`,
92
+ });
93
+ }
94
+ }
95
+ // --- Entity-level checks ---
96
+ for (let i = 0; i < spec.entities.length; i++) {
97
+ const entity = spec.entities[i];
98
+ const loc = `entities[${String(i)}]`;
99
+ if (!entity.name) {
100
+ findings.push({
101
+ id: nextId(),
102
+ severity: 'error',
103
+ category: 'schema',
104
+ message: `Entity at index ${String(i)} is missing a name.`,
105
+ remediation: 'Assign a name to this entity.',
106
+ location: `${loc}.name`,
107
+ });
108
+ }
109
+ if (entity.fields.length === 0) {
110
+ findings.push({
111
+ id: nextId(),
112
+ severity: 'error',
113
+ category: 'schema',
114
+ message: `Entity '${entity.name || `[index ${String(i)}]`}' has no fields defined.`,
115
+ remediation: 'Add at least one field to this entity describing its data structure.',
116
+ location: `${loc}.fields`,
117
+ });
118
+ }
119
+ for (let j = 0; j < entity.fields.length; j++) {
120
+ const field = entity.fields[j];
121
+ const fieldLoc = `${loc}.fields[${String(j)}]`;
122
+ if (!field.name) {
123
+ findings.push({
124
+ id: nextId(),
125
+ severity: 'error',
126
+ category: 'schema',
127
+ message: `Field at index ${String(j)} in entity '${entity.name || `[index ${String(i)}]`}' is missing a name.`,
128
+ remediation: 'Assign a name to this field.',
129
+ location: `${fieldLoc}.name`,
130
+ });
131
+ }
132
+ if (!field.type) {
133
+ findings.push({
134
+ id: nextId(),
135
+ severity: 'error',
136
+ category: 'schema',
137
+ message: `Field '${field.name || `[index ${String(j)}]`}' in entity '${entity.name || `[index ${String(i)}]`}' is missing a type.`,
138
+ remediation: 'Specify a data type for this field (e.g. string, number, uuid).',
139
+ location: `${fieldLoc}.type`,
140
+ });
141
+ }
142
+ }
143
+ }
144
+ return findings;
145
+ }
146
+ //# sourceMappingURL=schema-validator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema-validator.js","sourceRoot":"","sources":["../../src/validators/schema-validator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Main specification validator — orchestrates all validators and produces
3
+ * a complete {@link ValidationReport}.
4
+ */
5
+ import type { ParsedSpecification } from '../types.js';
6
+ import type { ValidationReport } from '../validation-types.js';
7
+ /**
8
+ * Validate a parsed specification across all dimensions: schema,
9
+ * completeness, and cross-references.
10
+ *
11
+ * @param spec - The parsed specification to validate
12
+ * @returns A complete validation report
13
+ */
14
+ export declare function validateSpec(spec: ParsedSpecification): ValidationReport;
15
+ //# sourceMappingURL=spec-validator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spec-validator.d.ts","sourceRoot":"","sources":["../../src/validators/spec-validator.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AACvD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAK/D;;;;;;GAMG;AACH,wBAAgB,YAAY,CAC1B,IAAI,EAAE,mBAAmB,GACxB,gBAAgB,CAuClB"}