Skip to content

Commit 1704900

Browse files
committed
refactor(graphql): use EnumTypeMap in registry
1 parent 6962916 commit 1704900

2 files changed

Lines changed: 22 additions & 51 deletions

File tree

packages/graphql/src/registry.ts

Lines changed: 21 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,13 @@
1-
import { UsageFlags, type Enum, type Model } from "@typespec/compiler";
1+
import { UsageFlags, type Enum } from "@typespec/compiler";
22
import {
33
GraphQLBoolean,
44
GraphQLEnumType,
55
GraphQLObjectType,
66
type GraphQLNamedType,
77
type GraphQLSchemaConfig,
88
} from "graphql";
9-
10-
// The TSPTypeContext interface represents the intermediate TSP type information before materialization.
11-
// It stores the raw TSP type and any extracted metadata relevant for GraphQL generation.
12-
interface TSPTypeContext {
13-
tspType: Enum | Model; // Extend with other TSP types like Operation, Interface, TSP Union, etc.
14-
name: string;
15-
usageFlags?: Set<UsageFlags>;
16-
// TODO: Add any other TSP-specific metadata here.
17-
}
9+
import { type TypeKey } from "./type-maps.js";
10+
import { EnumTypeMap } from "./type-maps/index.js";
1811
/**
1912
* GraphQLTypeRegistry manages the registration and materialization of TypeSpec (TSP)
2013
* types into their corresponding GraphQL type definitions.
@@ -39,61 +32,39 @@ interface TSPTypeContext {
3932
* by using thunks for fields/arguments.
4033
*/
4134
export class GraphQLTypeRegistry {
42-
// Stores intermediate TSP type information, keyed by TSP type name.
43-
// TODO: make this more of a seen set
44-
private TSPTypeContextRegistry: Map<string, TSPTypeContext> = new Map();
35+
// TypeMap for enum types
36+
private enumTypeMap = new EnumTypeMap();
4537

46-
// Stores materialized GraphQL types, keyed by their GraphQL name.
47-
private materializedGraphQLTypes: Map<string, GraphQLNamedType> = new Map();
38+
// Track all registered names to detect cross-TypeMap name collisions
39+
private allRegisteredNames = new Set<string>();
4840

4941
addEnum(tspEnum: Enum): void {
5042
const enumName = tspEnum.name;
51-
if (this.TSPTypeContextRegistry.has(enumName)) {
52-
// Optionally, log a warning or update if new information is more complete.
43+
44+
// Check for duplicate names across all type maps
45+
if (this.allRegisteredNames.has(enumName)) {
46+
// Already registered (could be same enum or name collision)
47+
// TODO: Add a warning to the diagnostics
5348
return;
5449
}
5550

56-
this.TSPTypeContextRegistry.set(enumName, {
57-
tspType: tspEnum,
58-
name: enumName,
59-
// TODO: Populate usageFlags based on TSP context and other decorator context.
51+
this.enumTypeMap.register({
52+
type: tspEnum,
53+
usageFlag: UsageFlags.Output, // Enums are same for input/output
6054
});
55+
this.allRegisteredNames.add(enumName);
6156
}
6257

6358
// Materializes a TSP Enum into a GraphQLEnumType.
6459
materializeEnum(enumName: string): GraphQLEnumType | undefined {
65-
// Check if the GraphQL type is already materialized.
66-
if (this.materializedGraphQLTypes.has(enumName)) {
67-
return this.materializedGraphQLTypes.get(enumName) as GraphQLEnumType;
68-
}
69-
70-
const context = this.TSPTypeContextRegistry.get(enumName);
71-
if (!context || context.tspType.kind !== "Enum") {
72-
// TODO: Handle error or warning for missing context.
73-
return undefined;
74-
}
75-
76-
const tspEnum = context.tspType as Enum;
77-
78-
const gqlEnum = new GraphQLEnumType({
79-
name: context.name,
80-
values: Object.fromEntries(
81-
Array.from(tspEnum.members.values()).map((member) => [
82-
member.name,
83-
{
84-
value: member.value ?? member.name,
85-
},
86-
]),
87-
),
88-
});
89-
90-
this.materializedGraphQLTypes.set(enumName, gqlEnum);
91-
return gqlEnum;
60+
return this.enumTypeMap.get(enumName as TypeKey);
9261
}
9362

9463
materializeSchemaConfig(): GraphQLSchemaConfig {
95-
const allMaterializedGqlTypes = Array.from(this.materializedGraphQLTypes.values());
96-
let queryType = this.materializedGraphQLTypes.get("Query") as GraphQLObjectType | undefined;
64+
// Collect all materialized types from all TypeMaps
65+
const allMaterializedGqlTypes: GraphQLNamedType[] = [...this.enumTypeMap.getAllMaterialized()];
66+
// TODO: Query type will come from operations
67+
let queryType: GraphQLObjectType | undefined = undefined;
9768
if (!queryType) {
9869
queryType = new GraphQLObjectType({
9970
name: "Query",

packages/graphql/src/type-maps.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import type { GraphQLType } from "graphql";
66
* @template T - The TypeSpec type
77
*/
88
export interface TSPContext<T extends Type> {
9-
type: T; // The TypeSpec type
9+
type: T; // The TypeSpec type (mutations should have already been applied)
1010
usageFlag: UsageFlags; // How the type is being used (input, output, etc.)
1111
metadata?: Record<string, any>; // Optional additional metadata
1212
}

0 commit comments

Comments
 (0)