@hstm-labs/forge-api-generator 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 ADDED
@@ -0,0 +1,38 @@
1
+ # @hstm-labs/forge-api-generator
2
+
3
+ API layer generation stage for Forge — produces endpoint definitions, request/response handlers, type definitions, and API contracts from architecture output.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @hstm-labs/forge-api-generator
9
+ ```
10
+
11
+ ## Public API
12
+
13
+ ### Types
14
+
15
+ - `ApiArtifact` — complete API layer output
16
+ - `ApiEndpoint` — route definition with method, path, parameters
17
+ - `ApiHandler` — request handler implementation
18
+ - `ApiTypeDefinition` — shared type/interface definitions
19
+ - `ApiContract` — API contract (OpenAPI-style) metadata
20
+
21
+ ### Classes
22
+
23
+ - `ApiGenerateStage` — pipeline stage implementing `PipelineStage` interface
24
+ - `ApiOutputValidator` — validates LLM-produced API output
25
+
26
+ ## Usage
27
+
28
+ ```typescript
29
+ import { ApiGenerateStage } from '@hstm-labs/forge-api-generator';
30
+
31
+ const stage = new ApiGenerateStage();
32
+ const result = await stage.execute(input);
33
+ // result.data contains ApiArtifact
34
+ ```
35
+
36
+ ## License
37
+
38
+ [MIT](../../LICENSE)
@@ -0,0 +1,48 @@
1
+ /**
2
+ * API generation pipeline stage.
3
+ *
4
+ * Produces routes/resolvers, handlers, type definitions, and a contract
5
+ * artifact (OpenAPI/GraphQL schema) from specification, architecture, and
6
+ * profile. Follows the same stage implementation pattern established by
7
+ * {@link ArchitectStage} in Task 5.1.
8
+ *
9
+ * In API mode, renders prompt templates, calls the LLM via
10
+ * {@link ApiStageExecutor}, validates the output, unpacks individual
11
+ * files, and returns the parsed {@link ApiArtifact} in the stage output data.
12
+ *
13
+ * In agent mode, the pipeline runner intercepts before calling
14
+ * `execute()` and exports a prompt via {@link AgentStageExecutor}.
15
+ */
16
+ import type { StageName } from '@hstm-labs/forge-common';
17
+ import type { PipelineStage, PipelineStageInput, PipelineStageOutput, PipelineContext } from '@hstm-labs/forge-core';
18
+ /**
19
+ * Pipeline stage that generates the API layer.
20
+ *
21
+ * Produces an {@link ApiArtifact} containing endpoint definitions, handler
22
+ * source files, type definitions, and a contract artifact. Each handler
23
+ * and type definition is written as a separate file artifact.
24
+ *
25
+ * @example
26
+ * ```ts
27
+ * const stage = new ApiGenerateStage();
28
+ * const output = await stage.execute(input, context);
29
+ * const api = output.data?.api as ApiArtifact;
30
+ * ```
31
+ */
32
+ export declare class ApiGenerateStage implements PipelineStage {
33
+ readonly name: StageName;
34
+ readonly dependsOn: StageName[];
35
+ readonly requiresLLM = true;
36
+ /**
37
+ * Execute the API generation stage.
38
+ *
39
+ * @param input - Input from prior stages (expects validate + architect output)
40
+ * @param context - Pipeline context with config, workspace, and adapter
41
+ * @returns Stage output with API artifacts and parsed ApiArtifact in data
42
+ * @throws {ForgeError} FORGE-PIPE-003 if dependency stage output is missing
43
+ * @throws {ForgeError} FORGE-PIPE-001 if adapter is missing
44
+ * @throws {ForgeError} FORGE-GEN-003 if max retries exhausted
45
+ */
46
+ execute(input: PipelineStageInput, context: PipelineContext): Promise<PipelineStageOutput>;
47
+ }
48
+ //# sourceMappingURL=api-generate-stage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-generate-stage.d.ts","sourceRoot":"","sources":["../src/api-generate-stage.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAIH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAEzD,OAAO,KAAK,EACV,aAAa,EACb,kBAAkB,EAClB,mBAAmB,EACnB,eAAe,EAEhB,MAAM,uBAAuB,CAAC;AAW/B;;;;;;;;;;;;;GAaG;AACH,qBAAa,gBAAiB,YAAW,aAAa;IACpD,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAkB;IAC1C,QAAQ,CAAC,SAAS,EAAE,SAAS,EAAE,CAAiB;IAChD,QAAQ,CAAC,WAAW,QAAQ;IAE5B;;;;;;;;;OASG;IACG,OAAO,CACX,KAAK,EAAE,kBAAkB,EACzB,OAAO,EAAE,eAAe,GACvB,OAAO,CAAC,mBAAmB,CAAC;CAmKhC"}
@@ -0,0 +1,164 @@
1
+ /**
2
+ * API generation pipeline stage.
3
+ *
4
+ * Produces routes/resolvers, handlers, type definitions, and a contract
5
+ * artifact (OpenAPI/GraphQL schema) from specification, architecture, and
6
+ * profile. Follows the same stage implementation pattern established by
7
+ * {@link ArchitectStage} in Task 5.1.
8
+ *
9
+ * In API mode, renders prompt templates, calls the LLM via
10
+ * {@link ApiStageExecutor}, validates the output, unpacks individual
11
+ * files, and returns the parsed {@link ApiArtifact} in the stage output data.
12
+ *
13
+ * In agent mode, the pipeline runner intercepts before calling
14
+ * `execute()` and exports a prompt via {@link AgentStageExecutor}.
15
+ */
16
+ import { join } from 'node:path';
17
+ import { writeFileSync, mkdirSync } from 'node:fs';
18
+ import { ForgeError, ErrorCodes, hashContent } from '@hstm-labs/forge-common';
19
+ import { ApiStageExecutor } from '@hstm-labs/forge-core';
20
+ import { resolveApiStyle } from '@hstm-labs/forge-architect';
21
+ import { loadProfile } from '@hstm-labs/forge-profiles';
22
+ import { loadTemplate, renderTemplate } from '@hstm-labs/forge-templates';
23
+ import { ApiOutputValidator } from './validator.js';
24
+ /**
25
+ * Pipeline stage that generates the API layer.
26
+ *
27
+ * Produces an {@link ApiArtifact} containing endpoint definitions, handler
28
+ * source files, type definitions, and a contract artifact. Each handler
29
+ * and type definition is written as a separate file artifact.
30
+ *
31
+ * @example
32
+ * ```ts
33
+ * const stage = new ApiGenerateStage();
34
+ * const output = await stage.execute(input, context);
35
+ * const api = output.data?.api as ApiArtifact;
36
+ * ```
37
+ */
38
+ export class ApiGenerateStage {
39
+ name = 'api-generate';
40
+ dependsOn = ['architect'];
41
+ requiresLLM = true;
42
+ /**
43
+ * Execute the API generation stage.
44
+ *
45
+ * @param input - Input from prior stages (expects validate + architect output)
46
+ * @param context - Pipeline context with config, workspace, and adapter
47
+ * @returns Stage output with API artifacts and parsed ApiArtifact in data
48
+ * @throws {ForgeError} FORGE-PIPE-003 if dependency stage output is missing
49
+ * @throws {ForgeError} FORGE-PIPE-001 if adapter is missing
50
+ * @throws {ForgeError} FORGE-GEN-003 if max retries exhausted
51
+ */
52
+ async execute(input, context) {
53
+ // 1. Get parsed spec from validate stage output
54
+ const validateOutput = input['validate'];
55
+ if (validateOutput === undefined) {
56
+ throw new ForgeError(ErrorCodes.PIPE.DEPENDENCY_UNMET, "API generate stage requires 'validate' stage output, but it was not found. " +
57
+ 'Ensure the validate stage runs before the api-generate stage.');
58
+ }
59
+ const parsedSpec = validateOutput.data?.['parsedSpec'];
60
+ if (parsedSpec === undefined) {
61
+ throw new ForgeError(ErrorCodes.PIPE.STAGE_FAILURE, 'Validate stage did not produce a parsed specification in its output data. ' +
62
+ 'Ensure the validate stage includes parsedSpec in its data output.');
63
+ }
64
+ // 2. Get architecture from architect stage output
65
+ const architectOutput = input['architect'];
66
+ if (architectOutput === undefined) {
67
+ throw new ForgeError(ErrorCodes.PIPE.DEPENDENCY_UNMET, "API generate stage requires 'architect' stage output, but it was not found. " +
68
+ 'Ensure the architect stage runs before the api-generate stage.');
69
+ }
70
+ const architecture = architectOutput.data?.['architecture'];
71
+ if (architecture === undefined) {
72
+ throw new ForgeError(ErrorCodes.PIPE.STAGE_FAILURE, 'Architect stage did not produce an architecture in its output data. ' +
73
+ 'Ensure the architect stage includes architecture in its data output.');
74
+ }
75
+ // 3. Load profile, resolve API style
76
+ const profile = loadProfile(context.config.profileName, context.workspace.rootDir);
77
+ const resolvedApiStyle = resolveApiStyle(parsedSpec, profile);
78
+ // 4. Compute output directory
79
+ const outputDir = join(context.workspace.forgeDir, 'runs', context.runId, 'stages', 'api-generate', 'artifacts');
80
+ // 5. Load and render templates
81
+ const systemTemplate = loadTemplate('api-generate-system', context.workspace.rootDir);
82
+ const userTemplate = loadTemplate('api-generate-user', context.workspace.rootDir);
83
+ const templateContext = {
84
+ spec: parsedSpec,
85
+ profile: profile,
86
+ architecture: architecture,
87
+ stage: {
88
+ resolvedApiStyle,
89
+ outputDir,
90
+ },
91
+ };
92
+ const systemPrompt = renderTemplate(systemTemplate, templateContext);
93
+ const userPrompt = renderTemplate(userTemplate, templateContext);
94
+ // 6. Execute via API mode StageExecutor
95
+ if (context.adapter === undefined) {
96
+ throw new ForgeError(ErrorCodes.PIPE.STAGE_FAILURE, 'API generate stage requires an LLM adapter in API mode, but none was provided. ' +
97
+ 'Configure an LLM provider in forge.config.json or use agent mode.');
98
+ }
99
+ const validator = new ApiOutputValidator(architecture.dataModel);
100
+ const executor = new ApiStageExecutor({
101
+ adapter: context.adapter,
102
+ validator,
103
+ retryPolicy: {
104
+ maxRetries: 3,
105
+ backoffMs: 1000,
106
+ includeErrorInRetry: true,
107
+ },
108
+ });
109
+ const result = await executor.execute({
110
+ prompt: userPrompt.content,
111
+ systemPrompt: systemPrompt.content,
112
+ stageName: 'api-generate',
113
+ outputDir,
114
+ runId: context.runId,
115
+ mode: 'api',
116
+ outputSchema: { format: 'json' },
117
+ });
118
+ // 7. Parse ApiArtifact from LLM output
119
+ const rawContent = result.artifacts[0]?.content ?? '';
120
+ const apiArtifact = JSON.parse(rawContent);
121
+ // 8. Write individual files to artifacts directory
122
+ mkdirSync(outputDir, { recursive: true });
123
+ const artifacts = [];
124
+ // Write handler files
125
+ for (const handler of apiArtifact.handlers) {
126
+ const filePath = handler.fileName;
127
+ writeFileSync(join(outputDir, filePath), handler.content, 'utf-8');
128
+ artifacts.push({
129
+ filePath,
130
+ content: handler.content,
131
+ contentHash: hashContent(handler.content),
132
+ sizeBytes: Buffer.byteLength(handler.content, 'utf-8'),
133
+ });
134
+ }
135
+ // Write type definition files
136
+ for (const typeDef of apiArtifact.types) {
137
+ const filePath = typeDef.fileName;
138
+ writeFileSync(join(outputDir, filePath), typeDef.content, 'utf-8');
139
+ artifacts.push({
140
+ filePath,
141
+ content: typeDef.content,
142
+ contentHash: hashContent(typeDef.content),
143
+ sizeBytes: Buffer.byteLength(typeDef.content, 'utf-8'),
144
+ });
145
+ }
146
+ // Write contract artifact
147
+ const contractPath = apiArtifact.contract.fileName;
148
+ writeFileSync(join(outputDir, contractPath), apiArtifact.contract.content, 'utf-8');
149
+ artifacts.push({
150
+ filePath: contractPath,
151
+ content: apiArtifact.contract.content,
152
+ contentHash: hashContent(apiArtifact.contract.content),
153
+ sizeBytes: Buffer.byteLength(apiArtifact.contract.content, 'utf-8'),
154
+ });
155
+ // 9. Return PipelineStageOutput with all artifacts and data
156
+ return {
157
+ artifacts,
158
+ data: {
159
+ api: apiArtifact,
160
+ },
161
+ };
162
+ }
163
+ }
164
+ //# sourceMappingURL=api-generate-stage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-generate-stage.js","sourceRoot":"","sources":["../src/api-generate-stage.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ export type { ApiArtifact, ApiEndpoint, ApiHandler, ApiTypeDefinition, ApiContract, } from './types.js';
2
+ export { ApiGenerateStage } from './api-generate-stage.js';
3
+ export { ApiOutputValidator } from './validator.js';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,YAAY,EACV,WAAW,EACX,WAAW,EACX,UAAU,EACV,iBAAiB,EACjB,WAAW,GACZ,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAE3D,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,4 @@
1
+ // @hstm-labs/forge-api-generator public API
2
+ export { ApiGenerateStage } from './api-generate-stage.js';
3
+ export { ApiOutputValidator } from './validator.js';
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,4CAA4C;AAU5C,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAE3D,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC"}
@@ -0,0 +1,61 @@
1
+ /**
2
+ * API artifact type definitions for the Forge API generation stage.
3
+ *
4
+ * Defines the output schema produced by the API generation stage,
5
+ * including endpoints, handlers, type definitions, and the contract
6
+ * artifact (OpenAPI or GraphQL schema).
7
+ */
8
+ /** Complete API layer output produced by the api-generate stage. */
9
+ export interface ApiArtifact {
10
+ /** Resolved API style for this generation. */
11
+ apiStyle: 'rest' | 'graphql' | 'grpc';
12
+ /** Generated route/resolver definitions. */
13
+ endpoints: ApiEndpoint[];
14
+ /** Generated handler implementations (source code). */
15
+ handlers: ApiHandler[];
16
+ /** Type/schema definitions. */
17
+ types: ApiTypeDefinition[];
18
+ /** Contract artifact content. */
19
+ contract: ApiContract;
20
+ }
21
+ /** A single API endpoint or resolver definition. */
22
+ export interface ApiEndpoint {
23
+ /** Entity or resource this endpoint covers. */
24
+ entity: string;
25
+ /** HTTP method (REST) or operation type (GraphQL: query/mutation). */
26
+ method: string;
27
+ /** Route path (REST: /api/pets) or field name (GraphQL: pets). */
28
+ path: string;
29
+ /** Handler function name. */
30
+ handler: string;
31
+ /** Description. */
32
+ description: string;
33
+ }
34
+ /** A generated handler source file. */
35
+ export interface ApiHandler {
36
+ /** File name (e.g., "pet-router.ts", "pet-resolver.ts"). */
37
+ fileName: string;
38
+ /** File content (source code). */
39
+ content: string;
40
+ /** Entity this handler covers. */
41
+ entity: string;
42
+ }
43
+ /** A generated TypeScript type/interface definition file. */
44
+ export interface ApiTypeDefinition {
45
+ /** Type name. */
46
+ name: string;
47
+ /** File name. */
48
+ fileName: string;
49
+ /** File content. */
50
+ content: string;
51
+ }
52
+ /** The API contract artifact (OpenAPI spec or GraphQL schema). */
53
+ export interface ApiContract {
54
+ /** Contract format. */
55
+ format: 'openapi' | 'graphql';
56
+ /** File name (openapi.json or schema.graphql). */
57
+ fileName: string;
58
+ /** Contract content (JSON string or GraphQL SDL). */
59
+ content: string;
60
+ }
61
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAMH,oEAAoE;AACpE,MAAM,WAAW,WAAW;IAC1B,8CAA8C;IAC9C,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAAC;IACtC,4CAA4C;IAC5C,SAAS,EAAE,WAAW,EAAE,CAAC;IACzB,uDAAuD;IACvD,QAAQ,EAAE,UAAU,EAAE,CAAC;IACvB,+BAA+B;IAC/B,KAAK,EAAE,iBAAiB,EAAE,CAAC;IAC3B,iCAAiC;IACjC,QAAQ,EAAE,WAAW,CAAC;CACvB;AAMD,oDAAoD;AACpD,MAAM,WAAW,WAAW;IAC1B,+CAA+C;IAC/C,MAAM,EAAE,MAAM,CAAC;IACf,sEAAsE;IACtE,MAAM,EAAE,MAAM,CAAC;IACf,kEAAkE;IAClE,IAAI,EAAE,MAAM,CAAC;IACb,6BAA6B;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,mBAAmB;IACnB,WAAW,EAAE,MAAM,CAAC;CACrB;AAMD,uCAAuC;AACvC,MAAM,WAAW,UAAU;IACzB,4DAA4D;IAC5D,QAAQ,EAAE,MAAM,CAAC;IACjB,kCAAkC;IAClC,OAAO,EAAE,MAAM,CAAC;IAChB,kCAAkC;IAClC,MAAM,EAAE,MAAM,CAAC;CAChB;AAMD,6DAA6D;AAC7D,MAAM,WAAW,iBAAiB;IAChC,iBAAiB;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,iBAAiB;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,oBAAoB;IACpB,OAAO,EAAE,MAAM,CAAC;CACjB;AAMD,kEAAkE;AAClE,MAAM,WAAW,WAAW;IAC1B,uBAAuB;IACvB,MAAM,EAAE,SAAS,GAAG,SAAS,CAAC;IAC9B,kDAAkD;IAClD,QAAQ,EAAE,MAAM,CAAC;IACjB,qDAAqD;IACrD,OAAO,EAAE,MAAM,CAAC;CACjB"}
package/dist/types.js ADDED
@@ -0,0 +1,9 @@
1
+ /**
2
+ * API artifact type definitions for the Forge API generation stage.
3
+ *
4
+ * Defines the output schema produced by the API generation stage,
5
+ * including endpoints, handlers, type definitions, and the contract
6
+ * artifact (OpenAPI or GraphQL schema).
7
+ */
8
+ export {};
9
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG"}
@@ -0,0 +1,42 @@
1
+ /**
2
+ * API output validator for the Forge API generation stage.
3
+ *
4
+ * Validates LLM-generated API output against the
5
+ * {@link ApiArtifact} schema with structural and semantic checks.
6
+ */
7
+ import type { OutputValidator, OutputSchema, ValidationResult } from '@hstm-labs/forge-core';
8
+ import type { DataModelEntity } from '@hstm-labs/forge-architect';
9
+ /**
10
+ * Validator for API generation stage output.
11
+ *
12
+ * Performs the following checks:
13
+ * 1. JSON parse validation
14
+ * 2. Required top-level keys
15
+ * 3. Non-empty endpoints with required fields
16
+ * 4. Entity coverage (every data model entity has endpoints)
17
+ * 5. Contract presence with valid format, fileName, and content
18
+ * 6. Contract format matches apiStyle
19
+ * 7. Non-empty handlers with fileName and content
20
+ *
21
+ * @example
22
+ * ```ts
23
+ * const validator = new ApiOutputValidator(dataModelEntities);
24
+ * const result = validator.validate(llmOutput, { format: 'json' });
25
+ * ```
26
+ */
27
+ export declare class ApiOutputValidator implements OutputValidator {
28
+ private readonly dataModelEntities;
29
+ /**
30
+ * @param dataModelEntities - Data model entities to verify endpoint coverage
31
+ */
32
+ constructor(dataModelEntities: DataModelEntity[]);
33
+ /**
34
+ * Validate API output against the ApiArtifact schema.
35
+ *
36
+ * @param output - Raw LLM output text
37
+ * @param _schema - Output schema (format expected to be 'json')
38
+ * @returns Validation result with descriptive errors
39
+ */
40
+ validate(output: string, _schema: OutputSchema): ValidationResult;
41
+ }
42
+ //# sourceMappingURL=validator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validator.d.ts","sourceRoot":"","sources":["../src/validator.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EACV,eAAe,EACf,YAAY,EACZ,gBAAgB,EAEjB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAuBlE;;;;;;;;;;;;;;;;;GAiBG;AACH,qBAAa,kBAAmB,YAAW,eAAe;IACxD,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAoB;IAEtD;;OAEG;gBACS,iBAAiB,EAAE,eAAe,EAAE;IAIhD;;;;;;OAMG;IAEH,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY,GAAG,gBAAgB;CAiMlE"}
@@ -0,0 +1,236 @@
1
+ /**
2
+ * API output validator for the Forge API generation stage.
3
+ *
4
+ * Validates LLM-generated API output against the
5
+ * {@link ApiArtifact} schema with structural and semantic checks.
6
+ */
7
+ // ---------------------------------------------------------------------------
8
+ // Contract format mapping
9
+ // ---------------------------------------------------------------------------
10
+ const API_STYLE_TO_CONTRACT_FORMAT = {
11
+ rest: 'openapi',
12
+ graphql: 'graphql',
13
+ };
14
+ const REQUIRED_TOP_LEVEL_KEYS = [
15
+ 'apiStyle',
16
+ 'endpoints',
17
+ 'handlers',
18
+ 'types',
19
+ 'contract',
20
+ ];
21
+ // ---------------------------------------------------------------------------
22
+ // Implementation
23
+ // ---------------------------------------------------------------------------
24
+ /**
25
+ * Validator for API generation stage output.
26
+ *
27
+ * Performs the following checks:
28
+ * 1. JSON parse validation
29
+ * 2. Required top-level keys
30
+ * 3. Non-empty endpoints with required fields
31
+ * 4. Entity coverage (every data model entity has endpoints)
32
+ * 5. Contract presence with valid format, fileName, and content
33
+ * 6. Contract format matches apiStyle
34
+ * 7. Non-empty handlers with fileName and content
35
+ *
36
+ * @example
37
+ * ```ts
38
+ * const validator = new ApiOutputValidator(dataModelEntities);
39
+ * const result = validator.validate(llmOutput, { format: 'json' });
40
+ * ```
41
+ */
42
+ export class ApiOutputValidator {
43
+ dataModelEntities;
44
+ /**
45
+ * @param dataModelEntities - Data model entities to verify endpoint coverage
46
+ */
47
+ constructor(dataModelEntities) {
48
+ this.dataModelEntities = dataModelEntities;
49
+ }
50
+ /**
51
+ * Validate API output against the ApiArtifact schema.
52
+ *
53
+ * @param output - Raw LLM output text
54
+ * @param _schema - Output schema (format expected to be 'json')
55
+ * @returns Validation result with descriptive errors
56
+ */
57
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
58
+ validate(output, _schema) {
59
+ const errors = [];
60
+ // 1. Parse as JSON
61
+ let parsed;
62
+ try {
63
+ parsed = JSON.parse(output);
64
+ }
65
+ catch {
66
+ errors.push({
67
+ message: 'API output is not valid JSON. Ensure the LLM produces only raw JSON without markdown fences or explanatory text.',
68
+ severity: 'error',
69
+ });
70
+ return { valid: false, errors };
71
+ }
72
+ if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {
73
+ errors.push({
74
+ message: 'API output must be a JSON object, not an array or primitive.',
75
+ severity: 'error',
76
+ });
77
+ return { valid: false, errors };
78
+ }
79
+ const obj = parsed;
80
+ // 2. Verify required top-level keys
81
+ for (const key of REQUIRED_TOP_LEVEL_KEYS) {
82
+ if (!(key in obj)) {
83
+ errors.push({
84
+ message: `Missing required top-level key: '${key}'.`,
85
+ path: key,
86
+ severity: 'error',
87
+ });
88
+ }
89
+ }
90
+ if (errors.length > 0) {
91
+ return { valid: false, errors };
92
+ }
93
+ // 3. Verify endpoints is non-empty array with required fields
94
+ const endpoints = obj['endpoints'];
95
+ if (!Array.isArray(endpoints) || endpoints.length === 0) {
96
+ errors.push({
97
+ message: "Key 'endpoints' must be a non-empty array of endpoint definitions.",
98
+ path: 'endpoints',
99
+ severity: 'error',
100
+ });
101
+ }
102
+ else {
103
+ for (let i = 0; i < endpoints.length; i++) {
104
+ const ep = endpoints[i];
105
+ if (ep === undefined || typeof ep !== 'object' || ep === null) {
106
+ errors.push({
107
+ message: `endpoints[${String(i)}] is not a valid object.`,
108
+ path: `endpoints[${String(i)}]`,
109
+ severity: 'error',
110
+ });
111
+ continue;
112
+ }
113
+ if (typeof ep['entity'] !== 'string' || ep['entity'].length === 0) {
114
+ errors.push({
115
+ message: `endpoints[${String(i)}] is missing required field 'entity'.`,
116
+ path: `endpoints[${String(i)}].entity`,
117
+ severity: 'error',
118
+ });
119
+ }
120
+ if (typeof ep['method'] !== 'string' || ep['method'].length === 0) {
121
+ errors.push({
122
+ message: `endpoints[${String(i)}] is missing required field 'method'.`,
123
+ path: `endpoints[${String(i)}].method`,
124
+ severity: 'error',
125
+ });
126
+ }
127
+ if (typeof ep['path'] !== 'string' || ep['path'].length === 0) {
128
+ errors.push({
129
+ message: `endpoints[${String(i)}] is missing required field 'path'.`,
130
+ path: `endpoints[${String(i)}].path`,
131
+ severity: 'error',
132
+ });
133
+ }
134
+ }
135
+ }
136
+ // 4. Entity coverage — every data model entity has at least one endpoint
137
+ if (Array.isArray(endpoints) && endpoints.length > 0) {
138
+ const endpointEntities = new Set(endpoints
139
+ .filter((ep) => typeof ep['entity'] === 'string')
140
+ .map((ep) => ep['entity'].toLowerCase()));
141
+ for (const entity of this.dataModelEntities) {
142
+ if (!endpointEntities.has(entity.name.toLowerCase())) {
143
+ errors.push({
144
+ message: `Data model entity '${entity.name}' has no corresponding endpoints. Every entity must have API coverage.`,
145
+ path: 'endpoints',
146
+ severity: 'error',
147
+ });
148
+ }
149
+ }
150
+ }
151
+ // 5. Verify contract has valid format, fileName, and non-empty content
152
+ const contract = obj['contract'];
153
+ if (typeof contract !== 'object' || contract === null || Array.isArray(contract)) {
154
+ errors.push({
155
+ message: "Key 'contract' must be an object with format, fileName, and content.",
156
+ path: 'contract',
157
+ severity: 'error',
158
+ });
159
+ }
160
+ else {
161
+ const c = contract;
162
+ if (typeof c['format'] !== 'string' || c['format'].length === 0) {
163
+ errors.push({
164
+ message: "Contract is missing required field 'format'.",
165
+ path: 'contract.format',
166
+ severity: 'error',
167
+ });
168
+ }
169
+ if (typeof c['fileName'] !== 'string' || c['fileName'].length === 0) {
170
+ errors.push({
171
+ message: "Contract is missing required field 'fileName'.",
172
+ path: 'contract.fileName',
173
+ severity: 'error',
174
+ });
175
+ }
176
+ if (typeof c['content'] !== 'string' || c['content'].length === 0) {
177
+ errors.push({
178
+ message: "Contract is missing required field 'content' (must be non-empty).",
179
+ path: 'contract.content',
180
+ severity: 'error',
181
+ });
182
+ }
183
+ // 6. Verify contract format matches apiStyle
184
+ const apiStyle = obj['apiStyle'];
185
+ if (typeof apiStyle === 'string' &&
186
+ typeof c['format'] === 'string') {
187
+ const expectedFormat = API_STYLE_TO_CONTRACT_FORMAT[apiStyle];
188
+ if (expectedFormat !== undefined && c['format'] !== expectedFormat) {
189
+ errors.push({
190
+ message: `Contract format '${c['format']}' does not match API style '${apiStyle}'. Expected '${expectedFormat}'.`,
191
+ path: 'contract.format',
192
+ severity: 'error',
193
+ });
194
+ }
195
+ }
196
+ }
197
+ // 7. Verify handlers is non-empty array with fileName and content
198
+ const handlers = obj['handlers'];
199
+ if (!Array.isArray(handlers) || handlers.length === 0) {
200
+ errors.push({
201
+ message: "Key 'handlers' must be a non-empty array of handler definitions.",
202
+ path: 'handlers',
203
+ severity: 'error',
204
+ });
205
+ }
206
+ else {
207
+ for (let i = 0; i < handlers.length; i++) {
208
+ const h = handlers[i];
209
+ if (h === undefined || typeof h !== 'object' || h === null) {
210
+ errors.push({
211
+ message: `handlers[${String(i)}] is not a valid object.`,
212
+ path: `handlers[${String(i)}]`,
213
+ severity: 'error',
214
+ });
215
+ continue;
216
+ }
217
+ if (typeof h['fileName'] !== 'string' || h['fileName'].length === 0) {
218
+ errors.push({
219
+ message: `handlers[${String(i)}] is missing required field 'fileName'.`,
220
+ path: `handlers[${String(i)}].fileName`,
221
+ severity: 'error',
222
+ });
223
+ }
224
+ if (typeof h['content'] !== 'string' || h['content'].length === 0) {
225
+ errors.push({
226
+ message: `handlers[${String(i)}] is missing required field 'content'.`,
227
+ path: `handlers[${String(i)}].content`,
228
+ severity: 'error',
229
+ });
230
+ }
231
+ }
232
+ }
233
+ return { valid: errors.length === 0, errors };
234
+ }
235
+ }
236
+ //# sourceMappingURL=validator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validator.js","sourceRoot":"","sources":["../src/validator.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,26 @@
1
+ {
2
+ "name": "@hstm-labs/forge-api-generator",
3
+ "version": "0.1.2",
4
+ "type": "module",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "files": [
8
+ "dist"
9
+ ],
10
+ "publishConfig": {
11
+ "access": "public"
12
+ },
13
+ "scripts": {
14
+ "build": "tsc",
15
+ "test": "vitest run",
16
+ "prepublishOnly": "npm run build"
17
+ },
18
+ "dependencies": {
19
+ "@hstm-labs/forge-common": "0.1.2",
20
+ "@hstm-labs/forge-core": "0.1.2",
21
+ "@hstm-labs/forge-architect": "0.1.2",
22
+ "@hstm-labs/forge-spec-parser": "0.1.2",
23
+ "@hstm-labs/forge-profiles": "0.1.2",
24
+ "@hstm-labs/forge-templates": "0.1.2"
25
+ }
26
+ }