Skip to content

Commit bcfae7d

Browse files
committed
feat(graphql): integrate mutation engine and TypeMaps into emitter
1 parent 1e07021 commit bcfae7d

3 files changed

Lines changed: 40 additions & 16 deletions

File tree

packages/graphql/src/schema-emitter.ts

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@ import {
1111
import { GraphQLSchema, validateSchema } from "graphql";
1212
import { type GraphQLEmitterOptions } from "./lib.js";
1313
import type { Schema } from "./lib/schema.js";
14+
import {
15+
createGraphQLMutationEngine,
16+
type GraphQLMutationEngine,
17+
} from "./mutation-engine/index.js";
1418
import { GraphQLTypeRegistry } from "./registry.js";
1519

1620
class GraphQLSchemaEmitter {
@@ -19,26 +23,29 @@ class GraphQLSchemaEmitter {
1923
private options: GraphQLEmitterOptions;
2024
private diagnostics: DiagnosticCollector;
2125
private registry: GraphQLTypeRegistry;
26+
private engine: GraphQLMutationEngine;
27+
2228
constructor(
2329
tspSchema: Schema,
2430
context: EmitContext<GraphQLEmitterOptions>,
2531
options: GraphQLEmitterOptions,
2632
) {
27-
// Initialize any properties if needed, including the registry
2833
this.tspSchema = tspSchema;
2934
this.context = context;
3035
this.options = options;
3136
this.diagnostics = createDiagnosticCollector();
3237
this.registry = new GraphQLTypeRegistry();
38+
this.engine = createGraphQLMutationEngine(context.program, tspSchema.type);
3339
}
3440

3541
async emitSchema(): Promise<[GraphQLSchema, Readonly<Diagnostic[]>] | undefined> {
36-
const schemaNamespace = this.tspSchema.type;
37-
// Logic to emit the GraphQL schema
38-
navigateTypesInNamespace(schemaNamespace, this.semanticNodeListener());
42+
// Navigate the original namespace, mutate on-demand via engine
43+
navigateTypesInNamespace(this.tspSchema.type, this.semanticNodeListener());
44+
3945
const schemaConfig = this.registry.materializeSchemaConfig();
4046
const schema = new GraphQLSchema(schemaConfig);
41-
// validate the schema
47+
48+
// Validate the schema
4249
const validationErrors = validateSchema(schema);
4350
validationErrors.forEach((error) => {
4451
this.diagnostics.add({
@@ -52,20 +59,23 @@ class GraphQLSchemaEmitter {
5259
}
5360

5461
semanticNodeListener() {
55-
// TODO: Add GraphQL types to registry as the TSP nodes are visited
5662
return {
5763
enum: (node: Enum) => {
58-
this.registry.addEnum(node);
64+
const mutation = this.engine.mutateEnum(node);
65+
this.registry.addEnum(mutation.mutatedType);
5966
},
6067
model: (node: Model) => {
61-
// TODO: Determine usageFlag from mutation engine or usage tracking
62-
this.registry.addModel(node, UsageFlags.Output);
68+
const mutation = this.engine.mutateModel(node);
69+
// TODO: Handle input/output variants
70+
this.registry.addModel(mutation.mutatedType, UsageFlags.Output);
6371
},
6472
exitEnum: (node: Enum) => {
65-
this.registry.materializeEnum(node.name);
73+
const mutation = this.engine.mutateEnum(node);
74+
this.registry.materializeEnum(mutation.mutatedType.name);
6675
},
6776
exitModel: (node: Model) => {
68-
this.registry.materializeModel(node.name);
77+
const mutation = this.engine.mutateModel(node);
78+
this.registry.materializeModel(mutation.mutatedType.name);
6979
},
7080
};
7181
}
@@ -76,7 +86,6 @@ export function createSchemaEmitter(
7686
context: EmitContext<GraphQLEmitterOptions>,
7787
options: GraphQLEmitterOptions,
7888
): GraphQLSchemaEmitter {
79-
// Placeholder for creating a GraphQL schema emitter
8089
return new GraphQLSchemaEmitter(schema, context, options);
8190
}
8291

packages/graphql/test/emitter.test.ts

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,16 @@ import { strictEqual } from "node:assert";
22
import { describe, it } from "vitest";
33
import { emitSingleSchema } from "./test-host.js";
44

5-
const expectedGraphQLSchema = `type Book {
5+
// Expected output with models and enums. Note: field types are placeholders (String) until
6+
// type resolution is fully implemented.
7+
const expectedGraphQLSchema = `enum Genre {
8+
_Fiction_
9+
NonFiction
10+
Mystery
11+
Fantasy
12+
}
13+
14+
type Book {
615
name: String
716
page_count: String
817
published: String
@@ -21,8 +30,8 @@ type Query {
2130
_: Boolean
2231
}`;
2332

24-
describe("name", () => {
25-
it("Emits a schema.graphql file with placeholder text", async () => {
33+
describe("emitter", () => {
34+
it("emits models and enums with mutations applied", async () => {
2635
const code = `
2736
@schema
2837
namespace TestNamespace {
@@ -36,6 +45,12 @@ describe("name", () => {
3645
name: string;
3746
books: Book[];
3847
}
48+
enum Genre {
49+
$Fiction$,
50+
NonFiction,
51+
Mystery,
52+
Fantasy,
53+
}
3954
op getBooks(): Book[];
4055
op getAuthors(): Author[];
4156
}

packages/graphql/test/main.tsp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ namespace MyLibrary {
1919
}
2020

2121
enum Genre {
22-
Fiction,
22+
$Fiction$,
2323
NonFiction,
2424
Mystery,
2525
Fantasy,

0 commit comments

Comments
 (0)