graphql-data-generator 0.4.1-alpha.2 → 0.4.1-alpha.3

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/esm/codegen.js CHANGED
@@ -24,10 +24,20 @@ const getType = ({ type, ...props }) => {
24
24
  group ??= type.name.value;
25
25
  if (!union[group]) {
26
26
  union[group] = {};
27
+ // Extract the actual type name from compound group names (e.g., "User:DelegationSubject" -> "DelegationSubject")
28
+ const actualTypeName = group.includes(":")
29
+ ? group.split(":").pop()
30
+ : group;
31
+ const shouldIncludeTypename = props.includeTypenames &&
32
+ props.definitions[actualTypeName]?.[0].kind ===
33
+ "ObjectTypeDefinition";
27
34
  Object.defineProperty(union[group], "__typename", {
28
- enumerable: props.includeTypenames &&
29
- props.definitions[group]?.[0].kind === "ObjectTypeDefinition",
30
- value: { kind: "StringLiteral", value: group, optional: false },
35
+ enumerable: shouldIncludeTypename,
36
+ value: {
37
+ kind: "StringLiteral",
38
+ value: actualTypeName,
39
+ optional: false,
40
+ },
31
41
  });
32
42
  }
33
43
  union[group][name] = value;
@@ -47,7 +57,8 @@ const getType = ({ type, ...props }) => {
47
57
  delete groupedValues[type.name.value];
48
58
  if (def?.[0].kind === "UnionTypeDefinition") {
49
59
  def[1].add(type.name.value);
50
- // Handle interface fields for union types while preserving discrimination
60
+ // This is a terrible solution and we should instead produce a tree that
61
+ // is simplified
51
62
  let iface = props.definitions[def[0].types?.[0]?.name.value ?? ""]?.[0];
52
63
  if (iface && "interfaces" in iface) {
53
64
  iface = props.definitions[iface.interfaces?.[0]?.name.value ?? ""]?.[0];
@@ -55,17 +66,10 @@ const getType = ({ type, ...props }) => {
55
66
  const interfaceName = iface?.kind === "InterfaceTypeDefinition"
56
67
  ? iface.name.value
57
68
  : undefined;
58
- // Only merge interface fields if ALL union types are exhaustively covered
59
- // AND the interface fragment is used alongside union type fragments
60
69
  if (interfaceName &&
61
70
  groupedValues[interfaceName] &&
62
71
  Object.keys(groupedValues).every((k) => k === interfaceName ||
63
- def[0].types?.some((t) => t.name.value === k)) &&
64
- // Ensure we have union type fragments - don't merge if only interface fragment
65
- Object.keys(groupedValues).some((k) => k !== interfaceName &&
66
72
  def[0].types?.some((t) => t.name.value === k))) {
67
- // Instead of merging into base value, move interface fields to base
68
- // This preserves union discrimination while sharing common interface fields
69
73
  Object.assign(value, groupedValues[interfaceName]);
70
74
  delete groupedValues[interfaceName];
71
75
  }
@@ -74,7 +78,12 @@ const getType = ({ type, ...props }) => {
74
78
  def[1].add(type.name.value);
75
79
  }
76
80
  const nonExhaustive = implementations
77
- .filter((o) => !(o[0].name.value in groupedValues)).map((o) => o[0].name.value);
81
+ .filter((o) => {
82
+ const typeName = o[0].name.value;
83
+ // Check if this type is covered either directly or in compound groups
84
+ return !(typeName in groupedValues) &&
85
+ !Object.keys(groupedValues).some((key) => key.includes(":") && key.endsWith(":" + typeName));
86
+ }).map((o) => o[0].name.value);
78
87
  return {
79
88
  kind: "Object",
80
89
  value,
@@ -116,7 +125,7 @@ const getSelectionsType = (name, selections, definitions, fragments, references,
116
125
  case "Field": {
117
126
  const selectionType = definitions[name];
118
127
  if (!selectionType) {
119
- throw new Error(`Could not find type '${selection.name.value}'`);
128
+ throw new Error(`Could not find type '${selection.name.value}' in '${name}'`);
120
129
  }
121
130
  switch (selectionType[0].kind) {
122
131
  case "ObjectTypeDefinition":
@@ -166,7 +175,11 @@ const getSelectionsType = (name, selections, definitions, fragments, references,
166
175
  if (!fragment) {
167
176
  throw new Error(`Could not find fragment '${selection.name.value}' in '${name}'`);
168
177
  }
169
- selectionTypes.push(...getSelectionsType(fragment.typeCondition.name.value, fragment.selectionSet.selections, definitions, fragments, references, includeTypenames).map(([name, type]) => [name, type, fragment.typeCondition.name.value]));
178
+ selectionTypes.push(...getSelectionsType(fragment.typeCondition.name.value, fragment.selectionSet.selections, definitions, fragments, references, includeTypenames).map(([name, type, group]) => [
179
+ name,
180
+ type,
181
+ group || fragment.typeCondition.name.value,
182
+ ]));
170
183
  break;
171
184
  }
172
185
  default:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "graphql-data-generator",
3
- "version": "0.4.1-alpha.2",
3
+ "version": "0.4.1-alpha.3",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/voces/graphql-data-generator.git"
package/script/codegen.js CHANGED
@@ -30,10 +30,20 @@ const getType = ({ type, ...props }) => {
30
30
  group ??= type.name.value;
31
31
  if (!union[group]) {
32
32
  union[group] = {};
33
+ // Extract the actual type name from compound group names (e.g., "User:DelegationSubject" -> "DelegationSubject")
34
+ const actualTypeName = group.includes(":")
35
+ ? group.split(":").pop()
36
+ : group;
37
+ const shouldIncludeTypename = props.includeTypenames &&
38
+ props.definitions[actualTypeName]?.[0].kind ===
39
+ "ObjectTypeDefinition";
33
40
  Object.defineProperty(union[group], "__typename", {
34
- enumerable: props.includeTypenames &&
35
- props.definitions[group]?.[0].kind === "ObjectTypeDefinition",
36
- value: { kind: "StringLiteral", value: group, optional: false },
41
+ enumerable: shouldIncludeTypename,
42
+ value: {
43
+ kind: "StringLiteral",
44
+ value: actualTypeName,
45
+ optional: false,
46
+ },
37
47
  });
38
48
  }
39
49
  union[group][name] = value;
@@ -53,7 +63,8 @@ const getType = ({ type, ...props }) => {
53
63
  delete groupedValues[type.name.value];
54
64
  if (def?.[0].kind === "UnionTypeDefinition") {
55
65
  def[1].add(type.name.value);
56
- // Handle interface fields for union types while preserving discrimination
66
+ // This is a terrible solution and we should instead produce a tree that
67
+ // is simplified
57
68
  let iface = props.definitions[def[0].types?.[0]?.name.value ?? ""]?.[0];
58
69
  if (iface && "interfaces" in iface) {
59
70
  iface = props.definitions[iface.interfaces?.[0]?.name.value ?? ""]?.[0];
@@ -61,17 +72,10 @@ const getType = ({ type, ...props }) => {
61
72
  const interfaceName = iface?.kind === "InterfaceTypeDefinition"
62
73
  ? iface.name.value
63
74
  : undefined;
64
- // Only merge interface fields if ALL union types are exhaustively covered
65
- // AND the interface fragment is used alongside union type fragments
66
75
  if (interfaceName &&
67
76
  groupedValues[interfaceName] &&
68
77
  Object.keys(groupedValues).every((k) => k === interfaceName ||
69
- def[0].types?.some((t) => t.name.value === k)) &&
70
- // Ensure we have union type fragments - don't merge if only interface fragment
71
- Object.keys(groupedValues).some((k) => k !== interfaceName &&
72
78
  def[0].types?.some((t) => t.name.value === k))) {
73
- // Instead of merging into base value, move interface fields to base
74
- // This preserves union discrimination while sharing common interface fields
75
79
  Object.assign(value, groupedValues[interfaceName]);
76
80
  delete groupedValues[interfaceName];
77
81
  }
@@ -80,7 +84,12 @@ const getType = ({ type, ...props }) => {
80
84
  def[1].add(type.name.value);
81
85
  }
82
86
  const nonExhaustive = implementations
83
- .filter((o) => !(o[0].name.value in groupedValues)).map((o) => o[0].name.value);
87
+ .filter((o) => {
88
+ const typeName = o[0].name.value;
89
+ // Check if this type is covered either directly or in compound groups
90
+ return !(typeName in groupedValues) &&
91
+ !Object.keys(groupedValues).some((key) => key.includes(":") && key.endsWith(":" + typeName));
92
+ }).map((o) => o[0].name.value);
84
93
  return {
85
94
  kind: "Object",
86
95
  value,
@@ -122,7 +131,7 @@ const getSelectionsType = (name, selections, definitions, fragments, references,
122
131
  case "Field": {
123
132
  const selectionType = definitions[name];
124
133
  if (!selectionType) {
125
- throw new Error(`Could not find type '${selection.name.value}'`);
134
+ throw new Error(`Could not find type '${selection.name.value}' in '${name}'`);
126
135
  }
127
136
  switch (selectionType[0].kind) {
128
137
  case "ObjectTypeDefinition":
@@ -172,7 +181,11 @@ const getSelectionsType = (name, selections, definitions, fragments, references,
172
181
  if (!fragment) {
173
182
  throw new Error(`Could not find fragment '${selection.name.value}' in '${name}'`);
174
183
  }
175
- selectionTypes.push(...getSelectionsType(fragment.typeCondition.name.value, fragment.selectionSet.selections, definitions, fragments, references, includeTypenames).map(([name, type]) => [name, type, fragment.typeCondition.name.value]));
184
+ selectionTypes.push(...getSelectionsType(fragment.typeCondition.name.value, fragment.selectionSet.selections, definitions, fragments, references, includeTypenames).map(([name, type, group]) => [
185
+ name,
186
+ type,
187
+ group || fragment.typeCondition.name.value,
188
+ ]));
176
189
  break;
177
190
  }
178
191
  default: