graphql-data-generator 0.4.1-alpha.6 → 0.4.1

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
@@ -262,6 +262,9 @@ const serializeType = (type, variables = false, depth = 0) => {
262
262
  ...ands.slice(1),
263
263
  ].filter(Boolean).join(" & ")}${type.optional ? " | null" : ""}`;
264
264
  }
265
+ case "Union":
266
+ return type.value.map(member => serializeType(member, variables, depth)).join(" | ") +
267
+ (type.optional ? " | null" : "");
265
268
  case "StringLiteral":
266
269
  return `"${type.value}"`;
267
270
  }
@@ -296,6 +299,11 @@ const fillOutInput = (input, inputs, references) => {
296
299
  return input;
297
300
  return serializeInput(def[0].fields ?? [], input.optional, inputs, references);
298
301
  }
302
+ case "Union":
303
+ return {
304
+ ...input,
305
+ value: input.value.map(member => fillOutInput(member, inputs, references))
306
+ };
299
307
  case "StringLiteral":
300
308
  return input;
301
309
  }
@@ -565,31 +573,97 @@ ${usedTypes.map(([name]) => ` ${name}: ${rename(name)};`).join("\n")}
565
573
  // Generate types for fragments
566
574
  const fragmentTypes = Object.entries(fragments).map(([fragmentName, fragment]) => {
567
575
  const fragmentSelections = getSelectionsType(fragment.typeCondition.name.value, fragment.selectionSet.selections, types, fragments, references, includeTypenames);
568
- const fragmentFields = fragmentSelections.reduce((fields, [name, type]) => {
569
- fields[name] = type;
570
- return fields;
571
- }, {});
572
- // Add __typename for object types
573
- const baseTypeDef = types[fragment.typeCondition.name.value];
574
- if (includeTypenames && baseTypeDef?.[0].kind === "ObjectTypeDefinition") {
575
- Object.defineProperty(fragmentFields, "__typename", {
576
- enumerable: true,
577
- value: {
578
- kind: "StringLiteral",
579
- value: fragment.typeCondition.name.value,
576
+ // Check if fragment is on a union type by looking for grouped selections (inline fragments)
577
+ const groupedSelections = new Map();
578
+ for (const [name, type, group] of fragmentSelections) {
579
+ if (!groupedSelections.has(group)) {
580
+ groupedSelections.set(group, []);
581
+ }
582
+ groupedSelections.get(group).push([name, type]);
583
+ }
584
+ // If we have multiple groups, this is a union fragment
585
+ const hasMultipleGroups = groupedSelections.size > 1 ||
586
+ (groupedSelections.size === 1 && !groupedSelections.has(undefined));
587
+ if (hasMultipleGroups) {
588
+ // Generate discriminated union for union fragments
589
+ const unionMembers = [];
590
+ for (const [group, selections] of groupedSelections) {
591
+ if (group) {
592
+ // This is an inline fragment group - create an object type for it
593
+ const memberFields = selections.reduce((fields, [name, type]) => {
594
+ fields[name] = type;
595
+ return fields;
596
+ }, {});
597
+ // Add __typename for the specific union member type
598
+ if (includeTypenames) {
599
+ Object.defineProperty(memberFields, "__typename", {
600
+ enumerable: true,
601
+ value: {
602
+ kind: "StringLiteral",
603
+ value: group.split(':')[0], // Handle nested groups
604
+ optional: false,
605
+ },
606
+ });
607
+ }
608
+ unionMembers.push({
609
+ kind: "Object",
610
+ value: memberFields,
611
+ optional: false,
612
+ });
613
+ }
614
+ else {
615
+ // Fields without group (shouldn't happen in union fragments, but handle gracefully)
616
+ const sharedFields = selections.reduce((fields, [name, type]) => {
617
+ fields[name] = type;
618
+ return fields;
619
+ }, {});
620
+ if (Object.keys(sharedFields).length > 0) {
621
+ unionMembers.push({
622
+ kind: "Object",
623
+ value: sharedFields,
624
+ optional: false,
625
+ });
626
+ }
627
+ }
628
+ }
629
+ return [
630
+ fragmentName,
631
+ {
632
+ kind: "Union",
633
+ value: unionMembers,
580
634
  optional: false,
581
635
  },
582
- });
636
+ [...new Set(fragmentSelections.map(([name]) => name))]
637
+ ];
638
+ }
639
+ else {
640
+ // Regular object fragment (not on union type)
641
+ const fragmentFields = fragmentSelections.reduce((fields, [name, type]) => {
642
+ fields[name] = type;
643
+ return fields;
644
+ }, {});
645
+ // Add __typename for object types
646
+ const baseTypeDef = types[fragment.typeCondition.name.value];
647
+ if (includeTypenames && baseTypeDef?.[0].kind === "ObjectTypeDefinition") {
648
+ Object.defineProperty(fragmentFields, "__typename", {
649
+ enumerable: true,
650
+ value: {
651
+ kind: "StringLiteral",
652
+ value: fragment.typeCondition.name.value,
653
+ optional: false,
654
+ },
655
+ });
656
+ }
657
+ return [
658
+ fragmentName,
659
+ {
660
+ kind: "Object",
661
+ value: fragmentFields,
662
+ optional: false,
663
+ },
664
+ [...new Set(fragmentSelections.map(([name]) => name))]
665
+ ];
583
666
  }
584
- return [
585
- fragmentName,
586
- {
587
- kind: "Object",
588
- value: fragmentFields,
589
- optional: false,
590
- },
591
- [...new Set(fragmentSelections.map(([name]) => name))]
592
- ];
593
667
  });
594
668
  if (fragmentTypes.length) {
595
669
  serializedTypes.unshift(...fragmentTypes.map(([name, type, _fields]) => `${exports.includes("types") ? "export " : ""}type ${name} = ${serializeType(type, false)};`).filter(filterOutputTypes));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "graphql-data-generator",
3
- "version": "0.4.1-alpha.6",
3
+ "version": "0.4.1",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/voces/graphql-data-generator.git"
package/script/codegen.js CHANGED
@@ -268,6 +268,9 @@ const serializeType = (type, variables = false, depth = 0) => {
268
268
  ...ands.slice(1),
269
269
  ].filter(Boolean).join(" & ")}${type.optional ? " | null" : ""}`;
270
270
  }
271
+ case "Union":
272
+ return type.value.map(member => serializeType(member, variables, depth)).join(" | ") +
273
+ (type.optional ? " | null" : "");
271
274
  case "StringLiteral":
272
275
  return `"${type.value}"`;
273
276
  }
@@ -302,6 +305,11 @@ const fillOutInput = (input, inputs, references) => {
302
305
  return input;
303
306
  return serializeInput(def[0].fields ?? [], input.optional, inputs, references);
304
307
  }
308
+ case "Union":
309
+ return {
310
+ ...input,
311
+ value: input.value.map(member => fillOutInput(member, inputs, references))
312
+ };
305
313
  case "StringLiteral":
306
314
  return input;
307
315
  }
@@ -571,31 +579,97 @@ ${usedTypes.map(([name]) => ` ${name}: ${rename(name)};`).join("\n")}
571
579
  // Generate types for fragments
572
580
  const fragmentTypes = Object.entries(fragments).map(([fragmentName, fragment]) => {
573
581
  const fragmentSelections = getSelectionsType(fragment.typeCondition.name.value, fragment.selectionSet.selections, types, fragments, references, includeTypenames);
574
- const fragmentFields = fragmentSelections.reduce((fields, [name, type]) => {
575
- fields[name] = type;
576
- return fields;
577
- }, {});
578
- // Add __typename for object types
579
- const baseTypeDef = types[fragment.typeCondition.name.value];
580
- if (includeTypenames && baseTypeDef?.[0].kind === "ObjectTypeDefinition") {
581
- Object.defineProperty(fragmentFields, "__typename", {
582
- enumerable: true,
583
- value: {
584
- kind: "StringLiteral",
585
- value: fragment.typeCondition.name.value,
582
+ // Check if fragment is on a union type by looking for grouped selections (inline fragments)
583
+ const groupedSelections = new Map();
584
+ for (const [name, type, group] of fragmentSelections) {
585
+ if (!groupedSelections.has(group)) {
586
+ groupedSelections.set(group, []);
587
+ }
588
+ groupedSelections.get(group).push([name, type]);
589
+ }
590
+ // If we have multiple groups, this is a union fragment
591
+ const hasMultipleGroups = groupedSelections.size > 1 ||
592
+ (groupedSelections.size === 1 && !groupedSelections.has(undefined));
593
+ if (hasMultipleGroups) {
594
+ // Generate discriminated union for union fragments
595
+ const unionMembers = [];
596
+ for (const [group, selections] of groupedSelections) {
597
+ if (group) {
598
+ // This is an inline fragment group - create an object type for it
599
+ const memberFields = selections.reduce((fields, [name, type]) => {
600
+ fields[name] = type;
601
+ return fields;
602
+ }, {});
603
+ // Add __typename for the specific union member type
604
+ if (includeTypenames) {
605
+ Object.defineProperty(memberFields, "__typename", {
606
+ enumerable: true,
607
+ value: {
608
+ kind: "StringLiteral",
609
+ value: group.split(':')[0], // Handle nested groups
610
+ optional: false,
611
+ },
612
+ });
613
+ }
614
+ unionMembers.push({
615
+ kind: "Object",
616
+ value: memberFields,
617
+ optional: false,
618
+ });
619
+ }
620
+ else {
621
+ // Fields without group (shouldn't happen in union fragments, but handle gracefully)
622
+ const sharedFields = selections.reduce((fields, [name, type]) => {
623
+ fields[name] = type;
624
+ return fields;
625
+ }, {});
626
+ if (Object.keys(sharedFields).length > 0) {
627
+ unionMembers.push({
628
+ kind: "Object",
629
+ value: sharedFields,
630
+ optional: false,
631
+ });
632
+ }
633
+ }
634
+ }
635
+ return [
636
+ fragmentName,
637
+ {
638
+ kind: "Union",
639
+ value: unionMembers,
586
640
  optional: false,
587
641
  },
588
- });
642
+ [...new Set(fragmentSelections.map(([name]) => name))]
643
+ ];
644
+ }
645
+ else {
646
+ // Regular object fragment (not on union type)
647
+ const fragmentFields = fragmentSelections.reduce((fields, [name, type]) => {
648
+ fields[name] = type;
649
+ return fields;
650
+ }, {});
651
+ // Add __typename for object types
652
+ const baseTypeDef = types[fragment.typeCondition.name.value];
653
+ if (includeTypenames && baseTypeDef?.[0].kind === "ObjectTypeDefinition") {
654
+ Object.defineProperty(fragmentFields, "__typename", {
655
+ enumerable: true,
656
+ value: {
657
+ kind: "StringLiteral",
658
+ value: fragment.typeCondition.name.value,
659
+ optional: false,
660
+ },
661
+ });
662
+ }
663
+ return [
664
+ fragmentName,
665
+ {
666
+ kind: "Object",
667
+ value: fragmentFields,
668
+ optional: false,
669
+ },
670
+ [...new Set(fragmentSelections.map(([name]) => name))]
671
+ ];
589
672
  }
590
- return [
591
- fragmentName,
592
- {
593
- kind: "Object",
594
- value: fragmentFields,
595
- optional: false,
596
- },
597
- [...new Set(fragmentSelections.map(([name]) => name))]
598
- ];
599
673
  });
600
674
  if (fragmentTypes.length) {
601
675
  serializedTypes.unshift(...fragmentTypes.map(([name, type, _fields]) => `${exports.includes("types") ? "export " : ""}type ${name} = ${serializeType(type, false)};`).filter(filterOutputTypes));