diff --git a/.github/workflows/push.yml b/.github/workflows/push.yml index 887ca5d..94c68bc 100644 --- a/.github/workflows/push.yml +++ b/.github/workflows/push.yml @@ -14,6 +14,10 @@ jobs: build: runs-on: ubuntu-latest + strategy: + matrix: + node-version: [16.x] + steps: - uses: actions/checkout@v1 - name: Use Node.js 16.x diff --git a/package.json b/package.json index 7f432b1..d12899e 100644 --- a/package.json +++ b/package.json @@ -68,13 +68,13 @@ "react": "^17.0.1", "ts-jest": "^26.5.6", "ts-loader": "^9.1.2", - "typescript": "3.8.3", + "typescript": "4.9.3", "webpack": "^5.36.2", "webpack-cli": "^4.7.0", "yarn-add-no-save": "^1.0.3" }, "peerDependencies": { - "typescript": ">= 3.x", + "typescript": ">= 4.x", "webpack": ">= 4" }, "lint-staged": { diff --git a/src/__tests__/__snapshots__/generateDocgenCodeBlock.test.ts.snap b/src/__tests__/__snapshots__/generateDocgenCodeBlock.test.ts.snap index 3371a7c..316ff3d 100644 --- a/src/__tests__/__snapshots__/generateDocgenCodeBlock.test.ts.snap +++ b/src/__tests__/__snapshots__/generateDocgenCodeBlock.test.ts.snap @@ -71,7 +71,7 @@ try { // @ts-ignore DefaultPropValueComponent.displayName = \\"DefaultPropValueComponent\\"; // @ts-ignore - DefaultPropValueComponent.__docgenInfo = { \\"description\\": \\"Component with a prop with a default value.\\", \\"displayName\\": \\"DefaultPropValueComponent\\", \\"props\\": { \\"color\\": { \\"defaultValue\\": null, \\"description\\": \\"Button color.\\", \\"name\\": \\"color\\", \\"required\\": true, \\"type\\": { \\"name\\": \\"\\\\\\"blue\\\\\\" | \\\\\\"green\\\\\\"\\" } }, \\"counter\\": { \\"defaultValue\\": { value: 123 }, \\"description\\": \\"Button counter.\\", \\"name\\": \\"counter\\", \\"required\\": false, \\"type\\": { \\"name\\": \\"number\\" } }, \\"disabled\\": { \\"defaultValue\\": { value: false }, \\"description\\": \\"Button disabled.\\", \\"name\\": \\"disabled\\", \\"required\\": false, \\"type\\": { \\"name\\": \\"boolean\\" } } } }; + DefaultPropValueComponent.__docgenInfo = { \\"description\\": \\"Component with a prop with a default value.\\", \\"displayName\\": \\"DefaultPropValueComponent\\", \\"props\\": { \\"color\\": { \\"defaultValue\\": { value: \\"blue\\" }, \\"description\\": \\"Button color.\\", \\"name\\": \\"color\\", \\"required\\": true, \\"type\\": { \\"name\\": \\"\\\\\\"blue\\\\\\" | \\\\\\"green\\\\\\"\\" } }, \\"counter\\": { \\"defaultValue\\": { value: 123 }, \\"description\\": \\"Button counter.\\", \\"name\\": \\"counter\\", \\"required\\": false, \\"type\\": { \\"name\\": \\"number\\" } }, \\"disabled\\": { \\"defaultValue\\": { value: false }, \\"description\\": \\"Button disabled.\\", \\"name\\": \\"disabled\\", \\"required\\": false, \\"type\\": { \\"name\\": \\"boolean\\" } } } }; } catch (__react_docgen_typescript_loader_error) { }" `; @@ -273,7 +273,7 @@ try { // @ts-ignore DefaultPropValueComponent.displayName = \\"DefaultPropValueComponent\\"; // @ts-ignore - DefaultPropValueComponent.__docgenInfo = { \\"description\\": \\"Component with a prop with a default value.\\", \\"displayName\\": \\"DefaultPropValueComponent\\", \\"props\\": { \\"color\\": { \\"defaultValue\\": null, \\"description\\": \\"Button color.\\", \\"name\\": \\"color\\", \\"required\\": true, \\"type\\": { \\"name\\": \\"enum\\", \\"value\\": [{ \\"value\\": \\"\\\\\\"blue\\\\\\"\\" }, { \\"value\\": \\"\\\\\\"green\\\\\\"\\" }] } }, \\"counter\\": { \\"defaultValue\\": { value: 123 }, \\"description\\": \\"Button counter.\\", \\"name\\": \\"counter\\", \\"required\\": false, \\"type\\": { \\"name\\": \\"number\\" } }, \\"disabled\\": { \\"defaultValue\\": { value: false }, \\"description\\": \\"Button disabled.\\", \\"name\\": \\"disabled\\", \\"required\\": false, \\"type\\": { \\"name\\": \\"boolean\\" } } } }; + DefaultPropValueComponent.__docgenInfo = { \\"description\\": \\"Component with a prop with a default value.\\", \\"displayName\\": \\"DefaultPropValueComponent\\", \\"props\\": { \\"color\\": { \\"defaultValue\\": { value: \\"blue\\" }, \\"description\\": \\"Button color.\\", \\"name\\": \\"color\\", \\"required\\": true, \\"type\\": { \\"name\\": \\"enum\\", \\"value\\": [{ \\"value\\": \\"\\\\\\"blue\\\\\\"\\" }, { \\"value\\": \\"\\\\\\"green\\\\\\"\\" }] } }, \\"counter\\": { \\"defaultValue\\": { value: 123 }, \\"description\\": \\"Button counter.\\", \\"name\\": \\"counter\\", \\"required\\": false, \\"type\\": { \\"name\\": \\"number\\" } }, \\"disabled\\": { \\"defaultValue\\": { value: false }, \\"description\\": \\"Button disabled.\\", \\"name\\": \\"disabled\\", \\"required\\": false, \\"type\\": { \\"name\\": \\"boolean\\" } } } }; } catch (__react_docgen_typescript_loader_error) { }" `; diff --git a/src/dependency.ts b/src/dependency.ts index 1db3bf3..20f9fb5 100644 --- a/src/dependency.ts +++ b/src/dependency.ts @@ -68,7 +68,7 @@ class DocGenTemplate extends NullDependency.Template } // eslint-disable-next-line -// @ts-ignore TODO: How to type this correctly? +// @ts-expect-error TODO: How to type this correctly? DocGenDependency.Template = DocGenTemplate; // Default imports are tricky with CommonJS diff --git a/src/generateDocgenCodeBlock.ts b/src/generateDocgenCodeBlock.ts index e425ba5..0aeec20 100644 --- a/src/generateDocgenCodeBlock.ts +++ b/src/generateDocgenCodeBlock.ts @@ -44,14 +44,14 @@ function insertTsIgnoreBeforeStatement(statement: ts.Statement): ts.Statement { */ function setDisplayName(d: ComponentDoc): ts.Statement { return insertTsIgnoreBeforeStatement( - ts.createExpressionStatement( - ts.createBinary( - ts.createPropertyAccess( - ts.createIdentifier(d.displayName), - ts.createIdentifier("displayName") + ts.factory.createExpressionStatement( + ts.factory.createBinaryExpression( + ts.factory.createPropertyAccessExpression( + ts.factory.createIdentifier(d.displayName), + ts.factory.createIdentifier("displayName") ), ts.SyntaxKind.EqualsToken, - ts.createLiteral(d.displayName) + ts.factory.createStringLiteral(d.displayName) ) ) ); @@ -93,8 +93,8 @@ function createPropDefinition( const setDefaultValue = ( defaultValue: { value: string | number | boolean } | null ) => - ts.createPropertyAssignment( - ts.createLiteral("defaultValue"), + ts.factory.createPropertyAssignment( + ts.factory.createStringLiteral("defaultValue"), // Use a more extensive check on defaultValue. Sometimes the parser // returns an empty object. defaultValue !== null && @@ -104,20 +104,28 @@ function createPropDefinition( (typeof defaultValue.value === "string" || typeof defaultValue.value === "number" || typeof defaultValue.value === "boolean") - ? ts.createObjectLiteral([ - ts.createPropertyAssignment( - ts.createIdentifier("value"), - ts.createLiteral(defaultValue.value) + ? ts.factory.createObjectLiteralExpression([ + ts.factory.createPropertyAssignment( + ts.factory.createIdentifier("value"), + // eslint-disable-next-line no-nested-ternary + typeof defaultValue.value === "string" + ? ts.factory.createStringLiteral(defaultValue.value) + : // eslint-disable-next-line no-nested-ternary + typeof defaultValue.value === "number" + ? ts.factory.createNumericLiteral(defaultValue.value) + : defaultValue.value + ? ts.factory.createTrue() + : ts.factory.createFalse() ), ]) - : ts.createNull() + : ts.factory.createNull() ); /** Set a property with a string value */ const setStringLiteralField = (fieldName: string, fieldValue: string) => - ts.createPropertyAssignment( - ts.createLiteral(fieldName), - ts.createLiteral(fieldValue) + ts.factory.createPropertyAssignment( + ts.factory.createStringLiteral(fieldName), + ts.factory.createStringLiteral(fieldValue) ); /** @@ -144,9 +152,9 @@ function createPropDefinition( * @param required Whether prop is required or not. */ const setRequired = (required: boolean) => - ts.createPropertyAssignment( - ts.createLiteral("required"), - required ? ts.createTrue() : ts.createFalse() + ts.factory.createPropertyAssignment( + ts.factory.createStringLiteral("required"), + required ? ts.factory.createTrue() : ts.factory.createFalse() ); /** @@ -161,11 +169,11 @@ function createPropDefinition( const setValue = (typeValue?: any[]) => Array.isArray(typeValue) && typeValue.every((value) => typeof value.value === "string") - ? ts.createPropertyAssignment( - ts.createLiteral("value"), - ts.createArrayLiteral( + ? ts.factory.createPropertyAssignment( + ts.factory.createStringLiteral("value"), + ts.factory.createArrayLiteralExpression( typeValue.map((value) => - ts.createObjectLiteral([ + ts.factory.createObjectLiteralExpression([ setStringLiteralField("value", value.value), ]) ) @@ -188,15 +196,15 @@ function createPropDefinition( objectFields.push(valueField); } - return ts.createPropertyAssignment( - ts.createLiteral(options.typePropName), - ts.createObjectLiteral(objectFields) + return ts.factory.createPropertyAssignment( + ts.factory.createStringLiteral(options.typePropName), + ts.factory.createObjectLiteralExpression(objectFields) ); }; - return ts.createPropertyAssignment( - ts.createLiteral(propName), - ts.createObjectLiteral([ + return ts.factory.createPropertyAssignment( + ts.factory.createStringLiteral(propName), + ts.factory.createObjectLiteralExpression([ setDefaultValue(prop.defaultValue), setDescription(prop.description), setName(prop.name), @@ -229,35 +237,35 @@ function insertDocgenIntoGlobalCollection( relativeFilename: string ): ts.Statement { return insertTsIgnoreBeforeStatement( - ts.createIf( - ts.createBinary( - ts.createTypeOf(ts.createIdentifier(docgenCollectionName)), + ts.factory.createIfStatement( + ts.factory.createBinaryExpression( + ts.factory.createTypeOfExpression(ts.factory.createIdentifier(docgenCollectionName)), ts.SyntaxKind.ExclamationEqualsEqualsToken, - ts.createLiteral("undefined") + ts.factory.createStringLiteral("undefined") ), insertTsIgnoreBeforeStatement( - ts.createStatement( - ts.createBinary( - ts.createElementAccess( - ts.createIdentifier(docgenCollectionName), - ts.createLiteral(`${relativeFilename}#${d.displayName}`) + ts.factory.createExpressionStatement( + ts.factory.createBinaryExpression( + ts.factory.createElementAccessExpression( + ts.factory.createIdentifier(docgenCollectionName), + ts.factory.createStringLiteral(`${relativeFilename}#${d.displayName}`) ), ts.SyntaxKind.EqualsToken, - ts.createObjectLiteral([ - ts.createPropertyAssignment( - ts.createIdentifier("docgenInfo"), - ts.createPropertyAccess( - ts.createIdentifier(d.displayName), - ts.createIdentifier("__docgenInfo") + ts.factory.createObjectLiteralExpression([ + ts.factory.createPropertyAssignment( + ts.factory.createIdentifier("docgenInfo"), + ts.factory.createPropertyAccessExpression( + ts.factory.createIdentifier(d.displayName), + ts.factory.createIdentifier("__docgenInfo") ) ), - ts.createPropertyAssignment( - ts.createIdentifier("name"), - ts.createLiteral(d.displayName) + ts.factory.createPropertyAssignment( + ts.factory.createIdentifier("name"), + ts.factory.createStringLiteral(d.displayName) ), - ts.createPropertyAssignment( - ts.createIdentifier("path"), - ts.createLiteral(`${relativeFilename}#${d.displayName}`) + ts.factory.createPropertyAssignment( + ts.factory.createIdentifier("path"), + ts.factory.createStringLiteral(`${relativeFilename}#${d.displayName}`) ), ]) ) @@ -287,29 +295,29 @@ function setComponentDocGen( options: GeneratorOptions ): ts.Statement { return insertTsIgnoreBeforeStatement( - ts.createStatement( - ts.createBinary( + ts.factory.createExpressionStatement( + ts.factory.createBinaryExpression( // SimpleComponent.__docgenInfo - ts.createPropertyAccess( - ts.createIdentifier(d.displayName), - ts.createIdentifier("__docgenInfo") + ts.factory.createPropertyAccessExpression( + ts.factory.createIdentifier(d.displayName), + ts.factory.createIdentifier("__docgenInfo") ), ts.SyntaxKind.EqualsToken, - ts.createObjectLiteral([ + ts.factory.createObjectLiteralExpression([ // SimpleComponent.__docgenInfo.description - ts.createPropertyAssignment( - ts.createLiteral("description"), - ts.createLiteral(d.description) + ts.factory.createPropertyAssignment( + ts.factory.createStringLiteral("description"), + ts.factory.createStringLiteral(d.description) ), // SimpleComponent.__docgenInfo.displayName - ts.createPropertyAssignment( - ts.createLiteral("displayName"), - ts.createLiteral(d.displayName) + ts.factory.createPropertyAssignment( + ts.factory.createStringLiteral("displayName"), + ts.factory.createStringLiteral(d.displayName) ), // SimpleComponent.__docgenInfo.props - ts.createPropertyAssignment( - ts.createLiteral("props"), - ts.createObjectLiteral( + ts.factory.createPropertyAssignment( + ts.factory.createStringLiteral("props"), + ts.factory.createObjectLiteralExpression( Object.entries(d.props).map(([propName, prop]) => createPropDefinition(propName, prop, options) ) @@ -333,13 +341,13 @@ export function generateDocgenCodeBlock(options: GeneratorOptions): string { .replace(/\\/g, "/"); const wrapInTryStatement = (statements: ts.Statement[]): ts.TryStatement => - ts.createTry( - ts.createBlock(statements, true), - ts.createCatchClause( - ts.createVariableDeclaration( - ts.createIdentifier("__react_docgen_typescript_loader_error") + ts.factory.createTryStatement( + ts.factory.createBlock(statements, true), + ts.factory.createCatchClause( + ts.factory.createVariableDeclaration( + ts.factory.createIdentifier("__react_docgen_typescript_loader_error") ), - ts.createBlock([]) + ts.factory.createBlock([]) ), undefined ); diff --git a/yarn.lock b/yarn.lock index 1178220..478c743 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6180,10 +6180,10 @@ typescript-memoize@^1.0.0-alpha.3: dependencies: core-js "2.4.1" -typescript@3.8.3: - version "3.8.3" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.8.3.tgz#409eb8544ea0335711205869ec458ab109ee1061" - integrity sha512-MYlEfn5VrLNsgudQTVJeNaQFUAI7DkhnOjdpAp4T+ku1TfQClewlbSuTVHiA+8skNBgaf02TL/kLOvig4y3G8w== +typescript@4.9.3: + version "4.9.3" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.9.3.tgz#3aea307c1746b8c384435d8ac36b8a2e580d85db" + integrity sha512-CIfGzTelbKNEnLpLdGFgdyKhG23CKdKgQPOBc+OUNrkJ2vr+KSzsSV5kq5iWhEQbok+quxgGzrAtGWCyU7tHnA== typical@^4.0.0: version "4.0.0"