bcherny/json-schema-to-typescript

Comments on individual enum values

a0js opened this issue ยท 2 comments

a0js commented

Hi! ๐Ÿ‘‹

Firstly, thanks for your work on this project! ๐Ÿ™‚

Today I used patch-package to patch json-schema-to-typescript@14.0.5 for the project I'm working on.

I needed a way to add JSDoc descriptions for each enum value in a named enum. I'd be happy to open a PR for adding this functionality, if you think it would be worth doing.

Here is the diff that solved my problem:

diff --git a/node_modules/json-schema-to-typescript/dist/src/generator.js b/node_modules/json-schema-to-typescript/dist/src/generator.js
index ec79bd0..3120d24 100644
--- a/node_modules/json-schema-to-typescript/dist/src/generator.js
+++ b/node_modules/json-schema-to-typescript/dist/src/generator.js
@@ -280,7 +280,10 @@ function generateStandaloneEnum(ast, options) {
         (options.enableConstEnums ? 'const ' : '') +
         `enum ${(0, utils_1.toSafeString)(ast.standaloneName)} {` +
         '\n' +
-        ast.params.map(({ ast, keyName }) => keyName + ' = ' + (0, exports.generateType)(ast, options)).join(',\n') +
+        ast.params.map(({ ast, keyName }) => (
+            ((0, AST_1.hasComment)(ast) ? generateComment(ast.comment, ast.deprecated) + '\n' : '') +
+            keyName + ' = ' + (0, exports.generateType)(ast, options)
+        )).join(',\n') +
         '\n' +
         '}');
 }
diff --git a/node_modules/json-schema-to-typescript/dist/src/parser.js b/node_modules/json-schema-to-typescript/dist/src/parser.js
index 2b44435..a4077ef 100644
--- a/node_modules/json-schema-to-typescript/dist/src/parser.js
+++ b/node_modules/json-schema-to-typescript/dist/src/parser.js
@@ -123,7 +123,7 @@ function parseNonLiteral(schema, type, options, keyName, processed, usedNames) {
                 keyName,
                 standaloneName: standaloneName(schema, keyNameFromDefinition !== null && keyNameFromDefinition !== void 0 ? keyNameFromDefinition : keyName, usedNames, options),
                 params: schema.enum.map((_, n) => ({
-                    ast: parseLiteral(_, undefined),
+                    ast: {...parseLiteral(_, undefined), comment: schema.tsEnumComments?.[n] },
                     keyName: schema.tsEnumNames[n],
                 })),
                 type: 'ENUM',
diff --git a/node_modules/json-schema-to-typescript/src/generator.ts b/node_modules/json-schema-to-typescript/src/generator.ts
index fb8d23b..9de2efb 100644
--- a/node_modules/json-schema-to-typescript/src/generator.ts
+++ b/node_modules/json-schema-to-typescript/src/generator.ts
@@ -335,7 +335,10 @@ function generateStandaloneEnum(ast: TEnum, options: Options): string {
     (options.enableConstEnums ? 'const ' : '') +
     `enum ${toSafeString(ast.standaloneName)} {` +
     '\n' +
-    ast.params.map(({ast, keyName}) => keyName + ' = ' + generateType(ast, options)).join(',\n') +
+    ast.params.map(({ast, keyName}) => (
+      (hasComment(ast) ? generateComment(ast.comment, ast.deprecated) + '\n' : '') +
+      keyName + ' = ' + generateType(ast, options)
+    )).join(',\n')} +
     '\n' +
     '}'
   )
diff --git a/node_modules/json-schema-to-typescript/src/parser.ts b/node_modules/json-schema-to-typescript/src/parser.ts
index 7e82d7f..7e92970 100644
--- a/node_modules/json-schema-to-typescript/src/parser.ts
+++ b/node_modules/json-schema-to-typescript/src/parser.ts
@@ -192,7 +192,7 @@ function parseNonLiteral(
         keyName,
         standaloneName: standaloneName(schema, keyNameFromDefinition ?? keyName, usedNames, options)!,
         params: schema.enum!.map((_, n) => ({
-          ast: parseLiteral(_, undefined),
+          ast: {...parseLiteral(_, undefined), comment: schema.tsEnumComments?.[n]},
           keyName: schema.tsEnumNames![n],
         })),
         type: 'ENUM',
diff --git a/node_modules/json-schema-to-typescript/src/types/JSONSchema.ts b/node_modules/json-schema-to-typescript/src/types/JSONSchema.ts
index 4c644f3..4e9f5db 100644
--- a/node_modules/json-schema-to-typescript/src/types/JSONSchema.ts
+++ b/node_modules/json-schema-to-typescript/src/types/JSONSchema.ts
@@ -37,7 +37,11 @@ export interface JSONSchema extends JSONSchema4 {
   /**
    * property exists at least in https://json-schema.org/draft/2019-09/json-schema-validation.html#rfc.section.9.3
    */
-  deprecated?: boolean
+  deprecated?: boolean,
+  /**
+   * schema extension to support enum value descriptions
+   */
+  tsEnumComments?: string[]
 }
 
 export const Parent = Symbol('Parent')

This issue body was partially generated by patch-package.

I like this idea (although I'm not a maintainer of this project).

Although, it might be cool to instead using the meta:enum syntax that the https://github.com/adobe/jsonschema2md library already supports for documenting enums.

It might help for projects that use both this library and that library!

For reference, the syntax is instead an object of enum value to enum description, e.g. (adapted from https://github.com/adobe/jsonschema2md/blob/e6c52a8e1d5806717f3070adda67bd9173613056/test/fixtures/enums/enum-meta-enum.schema.json):

{
      "type": "string",
      "enum": [
        "baa",
        "bad",
        "bag",
        "bah",
        "bam",
        "ban",
        "bap",
        "bas",
        "bat",
        "bay"
      ],
      "meta:enum": {
        "baa": "the sounds of sheeps",
        "bad": "German bathroom",
        "bag": "holding device",
        "bah": "humbug!",
        "bam": "a loud sound",
        "ban": "don't do this",
        "bap": "a British soft bread roll",
        "bas": "from ancient Egyptian religion, an aspect of the soul",
        "bat": "โ€ฆout of hell",
        "bay": ", sitting by the dock of the"
      }
}

Is there a reason you need enum comments specifically? JSON-Schema supports this today, you just need to express it a little differently, using anyOf and const. See https://stackoverflow.com/a/64296043/435124.