Repository: pmcelhaney/counterfact
Pull request #373 (2023-01-20 17:48:14)

support for encoding enums

changeset-bot[bot]: ###  ⚠️  No Changeset found

Latest commit: 562209092720df98a6f9b004006680551f0cd6a0

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. **If these changes should result in a version bump, you need to add a changeset.**

<details><summary>This PR includes no changesets</summary>

  When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

</details>

[Click here to learn what changesets are, and how to add one](https://github.com/changesets/changesets/blob/master/docs/adding-a-changeset.md).

[Click here if you're a maintainer who wants to add a changeset to this PR](https://github.com/pmcelhaney/counterfact/new/support-for-enums?filename=.changeset/angry-spoons-relate.md&value=---%0A%22counterfact%22%3A%20patch%0A---%0A%0Asupport%20for%20encoding%20enums%0A)



Patch:
diff --git a/.changeset/gold-mirrors-draw.md b/.changeset/gold-mirrors-draw.md
new file mode 100644
index 0000000..9787971
--- /dev/null
+++ b/.changeset/gold-mirrors-draw.md
@@ -0,0 +1,5 @@
+---
+"counterfact": minor
+---
+
+support for enum values in schemas
diff --git a/src/typescript-generator/schema-type-coder.js b/src/typescript-generator/schema-type-coder.js
index 40a5aab..9b73a7a 100644
--- a/src/typescript-generator/schema-type-coder.js
+++ b/src/typescript-generator/schema-type-coder.js
@@ -93,6 +93,12 @@ export class SchemaTypeCoder extends Coder {
     return types.join(allOf ? " & " : " | ");
   }
 
+  writeEnum(script, requirement) {
+    return requirement.data
+      .map((item) => (typeof item === "string" ? `"${item}"` : item))
+      .join(" | ");
+  }
+
   modulePath() {
     return `components/${this.requirement.data.$ref.split("/").at(-1)}.ts`;
   }
@@ -108,6 +114,10 @@ export class SchemaTypeCoder extends Coder {
       return this.writeGroup(script, { allOf, anyOf, oneOf });
     }
 
+    if (this.requirement.has("enum")) {
+      return this.writeEnum(script, this.requirement.get("enum"));
+    }
+
     return this.writeType(script, type);
   }
 }


Test patch:
diff --git a/test/typescript-generator/__snapshots__/end-to-end.test.js.snap b/test/typescript-generator/__snapshots__/end-to-end.test.js.snap
index 75c15cd..fb1bde6 100644
--- a/test/typescript-generator/__snapshots__/end-to-end.test.js.snap
+++ b/test/typescript-generator/__snapshots__/end-to-end.test.js.snap
@@ -202,7 +202,7 @@ class Context {
                 "exports": Map {
                   "Pet" => Object {
                     "beforeExport": "",
-                    "code": "{id?: number,name: string,category?: Category,photoUrls: Array<string>,tags?: Array<Tag>,status?: string}",
+                    "code": "{id?: number,name: string,category?: Category,photoUrls: Array<string>,tags?: Array<Tag>,status?: \\"available\\" | \\"pending\\" | \\"sold\\"}",
                     "done": true,
                     "id": "SchemaTypeCoder@undefined",
                     "isDefault": false,
@@ -457,7 +457,7 @@ class Context {
                 "exports": Map {
                   "Pet" => Object {
                     "beforeExport": "",
-                    "code": "{id?: number,name: string,category?: Category,photoUrls: Array<string>,tags?: Array<Tag>,status?: string}",
+                    "code": "{id?: number,name: string,category?: Category,photoUrls: Array<string>,tags?: Array<Tag>,status?: \\"available\\" | \\"pending\\" | \\"sold\\"}",
                     "done": true,
                     "id": "SchemaTypeCoder@undefined",
                     "isDefault": false,
@@ -716,7 +716,7 @@ class Context {
           "exports": Map {
             "Pet" => Object {
               "beforeExport": "",
-              "code": "{id?: number,name: string,category?: Category,photoUrls: Array<string>,tags?: Array<Tag>,status?: string}",
+              "code": "{id?: number,name: string,category?: Category,photoUrls: Array<string>,tags?: Array<Tag>,status?: \\"available\\" | \\"pending\\" | \\"sold\\"}",
               "done": true,
               "id": "SchemaTypeCoder@undefined",
               "isDefault": false,
@@ -842,7 +842,7 @@ class Context {
           "exports": Map {
             "HTTP_GET" => Object {
               "beforeExport": "",
-              "code": "({ query, path, header, body, context, proxy }: { query: {status?: string}, path: never, header: never, body: undefined, context: typeof Context, response: ResponseBuilderFactory<{
+              "code": "({ query, path, header, body, context, proxy }: { query: {status?: \\"available\\" | \\"pending\\" | \\"sold\\"}, path: never, header: never, body: undefined, context: typeof Context, response: ResponseBuilderFactory<{
 200: {
           headers: {};
           content: {
@@ -944,7 +944,7 @@ class Context {
                 "exports": Map {
                   "Pet" => Object {
                     "beforeExport": "",
-                    "code": "{id?: number,name: string,category?: Category,photoUrls: Array<string>,tags?: Array<Tag>,status?: string}",
+                    "code": "{id?: number,name: string,category?: Category,photoUrls: Array<string>,tags?: Array<Tag>,status?: \\"available\\" | \\"pending\\" | \\"sold\\"}",
                     "done": true,
                     "id": "SchemaTypeCoder@undefined",
                     "isDefault": false,
@@ -1053,7 +1053,7 @@ class Context {
     "exports": Map {
       "HTTP_GET" => Object {
         "beforeExport": "",
-        "code": "({ query, path, header, body, context, proxy }: { query: {status?: string}, path: never, header: never, body: undefined, context: typeof Context, response: ResponseBuilderFactory<{
+        "code": "({ query, path, header, body, context, proxy }: { query: {status?: \\"available\\" | \\"pending\\" | \\"sold\\"}, path: never, header: never, body: undefined, context: typeof Context, response: ResponseBuilderFactory<{
 200: {
           headers: {};
           content: {
@@ -1155,7 +1155,7 @@ class Context {
           "exports": Map {
             "Pet" => Object {
               "beforeExport": "",
-              "code": "{id?: number,name: string,category?: Category,photoUrls: Array<string>,tags?: Array<Tag>,status?: string}",
+              "code": "{id?: number,name: string,category?: Category,photoUrls: Array<string>,tags?: Array<Tag>,status?: \\"available\\" | \\"pending\\" | \\"sold\\"}",
               "done": true,
               "id": "SchemaTypeCoder@undefined",
               "isDefault": false,
@@ -1383,7 +1383,7 @@ class Context {
                 "exports": Map {
                   "Pet" => Object {
                     "beforeExport": "",
-                    "code": "{id?: number,name: string,category?: Category,photoUrls: Array<string>,tags?: Array<Tag>,status?: string}",
+                    "code": "{id?: number,name: string,category?: Category,photoUrls: Array<string>,tags?: Array<Tag>,status?: \\"available\\" | \\"pending\\" | \\"sold\\"}",
                     "done": true,
                     "id": "SchemaTypeCoder@undefined",
                     "isDefault": false,
@@ -1594,7 +1594,7 @@ class Context {
           "exports": Map {
             "Pet" => Object {
               "beforeExport": "",
-              "code": "{id?: number,name: string,category?: Category,photoUrls: Array<string>,tags?: Array<Tag>,status?: string}",
+              "code": "{id?: number,name: string,category?: Category,photoUrls: Array<string>,tags?: Array<Tag>,status?: \\"available\\" | \\"pending\\" | \\"sold\\"}",
               "done": true,
               "id": "SchemaTypeCoder@undefined",
               "isDefault": false,
@@ -1892,7 +1892,7 @@ class Context {
                 "exports": Map {
                   "Pet" => Object {
                     "beforeExport": "",
-                    "code": "{id?: number,name: string,category?: Category,photoUrls: Array<string>,tags?: Array<Tag>,status?: string}",
+                    "code": "{id?: number,name: string,category?: Category,photoUrls: Array<string>,tags?: Array<Tag>,status?: \\"available\\" | \\"pending\\" | \\"sold\\"}",
                     "done": true,
                     "id": "SchemaTypeCoder@undefined",
                     "isDefault": false,
@@ -2143,7 +2143,7 @@ class Context {
                 "exports": Map {
                   "Pet" => Object {
                     "beforeExport": "",
-                    "code": "{id?: number,name: string,category?: Category,photoUrls: Array<string>,tags?: Array<Tag>,status?: string}",
+                    "code": "{id?: number,name: string,category?: Category,photoUrls: Array<string>,tags?: Array<Tag>,status?: \\"available\\" | \\"pending\\" | \\"sold\\"}",
                     "done": true,
                     "id": "SchemaTypeCoder@undefined",
                     "isDefault": false,
@@ -2394,7 +2394,7 @@ class Context {
                 "exports": Map {
                   "Pet" => Object {
                     "beforeExport": "",
-                    "code": "{id?: number,name: string,category?: Category,photoUrls: Array<string>,tags?: Array<Tag>,status?: string}",
+                    "code": "{id?: number,name: string,category?: Category,photoUrls: Array<string>,tags?: Array<Tag>,status?: \\"available\\" | \\"pending\\" | \\"sold\\"}",
                     "done": true,
                     "id": "SchemaTypeCoder@undefined",
                     "isDefault": false,
@@ -2649,7 +2649,7 @@ class Context {
           "exports": Map {
             "Pet" => Object {
               "beforeExport": "",
-              "code": "{id?: number,name: string,category?: Category,photoUrls: Array<string>,tags?: Array<Tag>,status?: string}",
+              "code": "{id?: number,name: string,category?: Category,photoUrls: Array<string>,tags?: Array<Tag>,status?: \\"available\\" | \\"pending\\" | \\"sold\\"}",
               "done": true,
               "id": "SchemaTypeCoder@undefined",
               "isDefault": false,
@@ -3370,7 +3370,7 @@ class Context {
                 "exports": Map {
                   "Order" => Object {
                     "beforeExport": "",
-                    "code": "{id?: number,petId?: number,quantity?: number,shipDate?: string,status?: string,complete?: boolean}",
+                    "code": "{id?: number,petId?: number,quantity?: number,shipDate?: string,status?: \\"placed\\" | \\"approved\\" | \\"delivered\\",complete?: boolean}",
                     "done": true,
                     "id": "SchemaTypeCoder@undefined",
                     "isDefault": false,
@@ -3509,7 +3509,7 @@ class Context {
           "exports": Map {
             "Order" => Object {
               "beforeExport": "",
-              "code": "{id?: number,petId?: number,quantity?: number,shipDate?: string,status?: string,complete?: boolean}",
+              "code": "{id?: number,petId?: number,quantity?: number,shipDate?: string,status?: \\"placed\\" | \\"approved\\" | \\"delivered\\",complete?: boolean}",
               "done": true,
               "id": "SchemaTypeCoder@undefined",
               "isDefault": false,
@@ -3716,7 +3716,7 @@ class Context {
                 "exports": Map {
                   "Order" => Object {
                     "beforeExport": "",
-                    "code": "{id?: number,petId?: number,quantity?: number,shipDate?: string,status?: string,complete?: boolean}",
+                    "code": "{id?: number,petId?: number,quantity?: number,shipDate?: string,status?: \\"placed\\" | \\"approved\\" | \\"delivered\\",complete?: boolean}",
                     "done": true,
                     "id": "SchemaTypeCoder@undefined",
                     "isDefault": false,
@@ -3889,7 +3889,7 @@ class Context {
                 "exports": Map {
                   "Order" => Object {
                     "beforeExport": "",
-                    "code": "{id?: number,petId?: number,quantity?: number,shipDate?: string,status?: string,complete?: boolean}",
+                    "code": "{id?: number,petId?: number,quantity?: number,shipDate?: string,status?: \\"placed\\" | \\"approved\\" | \\"delivered\\",complete?: boolean}",
                     "done": true,
                     "id": "SchemaTypeCoder@undefined",
                     "isDefault": false,
@@ -4066,7 +4066,7 @@ class Context {
           "exports": Map {
             "Order" => Object {
               "beforeExport": "",
-              "code": "{id?: number,petId?: number,quantity?: number,shipDate?: string,status?: string,complete?: boolean}",
+              "code": "{id?: number,petId?: number,quantity?: number,shipDate?: string,status?: \\"placed\\" | \\"approved\\" | \\"delivered\\",complete?: boolean}",
               "done": true,
               "id": "SchemaTypeCoder@undefined",
               "isDefault": false,
@@ -6019,7 +6019,7 @@ class Context {
     "exports": Map {
       "Pet" => Object {
         "beforeExport": "",
-        "code": "{id?: number,name: string,category?: Category,photoUrls: Array<string>,tags?: Array<Tag>,status?: string}",
+        "code": "{id?: number,name: string,category?: Category,photoUrls: Array<string>,tags?: Array<Tag>,status?: \\"available\\" | \\"pending\\" | \\"sold\\"}",
         "done": true,
         "id": "SchemaTypeCoder@undefined",
         "isDefault": false,
@@ -6257,7 +6257,7 @@ class Context {
     "exports": Map {
       "Order" => Object {
         "beforeExport": "",
-        "code": "{id?: number,petId?: number,quantity?: number,shipDate?: string,status?: string,complete?: boolean}",
+        "code": "{id?: number,petId?: number,quantity?: number,shipDate?: string,status?: \\"placed\\" | \\"approved\\" | \\"delivered\\",complete?: boolean}",
         "done": true,
         "id": "SchemaTypeCoder@undefined",
         "isDefault": false,
diff --git a/test/typescript-generator/schema-type-coder.test.js b/test/typescript-generator/schema-type-coder.test.js
index eb2df09..76940df 100644
--- a/test/typescript-generator/schema-type-coder.test.js
+++ b/test/typescript-generator/schema-type-coder.test.js
@@ -259,6 +259,18 @@ describe("a SchemaTypeCoder", () => {
     expect(format(`type x = ${coder.write()}`)).toStrictEqual(expected);
   });
 
+  it("generates a type declaration for enum", () => {
+    const coder = new SchemaTypeCoder(
+      new Requirement({
+        enum: [1, "two"],
+      })
+    );
+
+    const expected = format('type x = 1 | "two";');
+
+    expect(format(`type x = ${coder.write()}`)).toStrictEqual(expected);
+  });
+
   it("has type JSONSchema6", () => {
     const coder = new SchemaTypeCoder(
       new Requirement({