From ef5a0340246a1bbf1eacb1ccca5466dd5646a91d Mon Sep 17 00:00:00 2001 From: Ira Hopkinson Date: Tue, 12 Nov 2024 11:01:46 +1300 Subject: [PATCH] add type checking (#1088) - fixes #1085 - include core, extensions, platform-bible-utils, platform-bible-react - fix existing type checking errors - add typecheck to pre-commit - use `noImplicitReturns` instead of `consistent-return` - type check in CI - fix jsdom type check errors - also make VS Code use the repo TS version - remember to remove the patch and the type overrides when the BNF types are fixed --- .eslintrc.js | 2 + .github/workflows/test.yml | 3 + .husky/pre-commit | 7 +- .vscode/settings.json | 1 + extensions/.eslintrc.cjs | 2 + .../src/c-sharp-provider-test/index.d.ts | 1 + extensions/src/hello-someone/.eslintrc.js | 2 + extensions/src/hello-someone/package.json | 3 +- .../src/types/hello-someone.d.ts | 1 + extensions/src/hello-world/.eslintrc.js | 2 + extensions/src/hello-world/package.json | 3 +- .../hello-world/src/types/hello-world.d.ts | 1 + .../src/web-views/hello-world.web-view.tsx | 2 +- .../src/types/legacy-comment-manager.d.ts | 1 + .../platform-scripture-editor/.eslintrc.js | 2 + .../platform-scripture-editor/package.json | 3 +- ...blionexus-foundation__platform-editor.d.ts | 65 +++++++ .../src/platform-scripture/.eslintrc.js | 2 + .../src/platform-scripture/package.json | 3 +- .../src/types/platform-scripture.d.ts | 1 + .../project-notes-data-provider/index.d.ts | 1 + extensions/src/quick-verse/.eslintrc.js | 2 + extensions/src/quick-verse/package.json | 3 +- .../quick-verse/src/types/quick-verse.d.ts | 1 + extensions/tsconfig.json | 2 +- lib/papi-dts/package.json | 3 +- lib/papi-dts/tsconfig.lint.json | 10 +- lib/platform-bible-react/package.json | 3 +- lib/platform-bible-react/tsconfig.json | 3 +- lib/platform-bible-utils/package.json | 3 +- lib/platform-bible-utils/tsconfig.json | 3 +- package-lock.json | 4 + package.json | 15 +- ...xus-foundation+platform-editor+0.6.4.patch | 13 ++ patches/@types+jsdom+20.0.1.patch | 14 ++ .../services/extension.service.ts | 6 +- ...form-dock-layout-positioning.util.test.ts} | 0 src/renderer/global-this.model.ts | 3 - src/stories/basics/combo-box.stories.tsx | 20 -- src/stories/basics/context-menu.stories.tsx | 174 ------------------ src/stories/basics/menu-item-list.stories.tsx | 64 ------- src/stories/basics/slider.stories.ts | 19 +- src/stories/basics/switch.stories.ts | 15 +- src/stories/basics/text-field.stories.ts | 8 - src/stories/basics/toolbar.stories.tsx | 13 +- tsconfig.json | 3 +- 46 files changed, 175 insertions(+), 337 deletions(-) create mode 100644 extensions/src/platform-scripture-editor/src/types/@biblionexus-foundation__platform-editor.d.ts create mode 100644 patches/@biblionexus-foundation+platform-editor+0.6.4.patch create mode 100644 patches/@types+jsdom+20.0.1.patch rename src/renderer/components/docking/{platform-dock-layout-positioning.util.tests.ts => platform-dock-layout-positioning.util.test.ts} (100%) delete mode 100644 src/stories/basics/context-menu.stories.tsx delete mode 100644 src/stories/basics/menu-item-list.stories.tsx diff --git a/.eslintrc.js b/.eslintrc.js index 3a148cabfa..8dba4cb1bb 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -15,6 +15,8 @@ module.exports = { // #region ERB rules + // Use `noImplicitReturns` instead. See https://typescript-eslint.io/rules/consistent-return/. + 'consistent-return': 'off', 'import/extensions': 'off', // A temporary hack related to IDE not resolving correct package.json 'import/no-extraneous-dependencies': 'off', diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 721eae3bcd..4bc583708a 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -57,6 +57,9 @@ jobs: - name: Install packages run: npm ci + - name: type checking + run: npm run typecheck + - name: Build run: npm run build diff --git a/.husky/pre-commit b/.husky/pre-commit index aa248530a5..71cf002c29 100755 --- a/.husky/pre-commit +++ b/.husky/pre-commit @@ -1,11 +1,14 @@ #!/bin/sh . "$(dirname "$0")/_/husky.sh" -echo "Running Lint check..." - +echo "Lint checking..." # generate papi.d.ts as part of lint:staged npm run lint:staged echo "Lint check finished" +echo "Type checking..." +npm run typecheck +echo "Type check finished" + echo "If the following fails run npm run editor:unlink" npx yalc check diff --git a/.vscode/settings.json b/.vscode/settings.json index d6b62044f7..7dbd8fa1d4 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -25,6 +25,7 @@ "javascript.validate.enable": false, "javascript.format.enable": false, "typescript.format.enable": false, + "typescript.tsdk": "node_modules/typescript/lib", "search.exclude": { ".git": true, diff --git a/extensions/.eslintrc.cjs b/extensions/.eslintrc.cjs index ad3672f562..0d40d87c22 100644 --- a/extensions/.eslintrc.cjs +++ b/extensions/.eslintrc.cjs @@ -16,6 +16,8 @@ module.exports = { // #region ERB rules + // Use `noImplicitReturns` instead. See https://typescript-eslint.io/rules/consistent-return/. + 'consistent-return': 'off', 'import/extensions': 'off', // A temporary hack related to IDE not resolving correct package.json 'import/no-extraneous-dependencies': 'off', diff --git a/extensions/src/c-sharp-provider-test/index.d.ts b/extensions/src/c-sharp-provider-test/index.d.ts index a98f1025e4..4f9736d330 100644 --- a/extensions/src/c-sharp-provider-test/index.d.ts +++ b/extensions/src/c-sharp-provider-test/index.d.ts @@ -1,4 +1,5 @@ declare module 'c-sharp-provider-test' { + // @ts-ignore: TS2307 - Cannot find module '@papi/core' or its corresponding type declarations import { IDataProvider, DataProviderDataType } from '@papi/core'; type TimeDataTypes = { diff --git a/extensions/src/hello-someone/.eslintrc.js b/extensions/src/hello-someone/.eslintrc.js index 279bb37dcd..c1de14ea7b 100644 --- a/extensions/src/hello-someone/.eslintrc.js +++ b/extensions/src/hello-someone/.eslintrc.js @@ -16,6 +16,8 @@ module.exports = { // #region ERB rules + // Use `noImplicitReturns` instead. See https://typescript-eslint.io/rules/consistent-return/. + 'consistent-return': 'off', 'import/extensions': 'off', // A temporary hack related to IDE not resolving correct package.json 'import/no-extraneous-dependencies': 'off', diff --git a/extensions/src/hello-someone/package.json b/extensions/src/hello-someone/package.json index 4687aec00b..ec7aa27ff6 100644 --- a/extensions/src/hello-someone/package.json +++ b/extensions/src/hello-someone/package.json @@ -23,7 +23,8 @@ "lint:scripts": "eslint --ext .cjs,.js,.jsx,.ts,.tsx --cache .", "lint:styles": "stylelint **/*.{css,scss}", "lint-fix": "npm run lint-fix:scripts && npm run lint:styles -- --fix", - "lint-fix:scripts": "prettier --write \"**/*.{ts,tsx,js,jsx,cjs}\" && npm run lint:scripts" + "lint-fix:scripts": "prettier --write \"**/*.{ts,tsx,js,jsx,cjs}\" && npm run lint:scripts", + "typecheck": "tsc -p ./tsconfig.json" }, "browserslist": [], "peerDependencies": { diff --git a/extensions/src/hello-someone/src/types/hello-someone.d.ts b/extensions/src/hello-someone/src/types/hello-someone.d.ts index e96fb9a93e..ebac819be2 100644 --- a/extensions/src/hello-someone/src/types/hello-someone.d.ts +++ b/extensions/src/hello-someone/src/types/hello-someone.d.ts @@ -1,4 +1,5 @@ declare module 'hello-someone' { + // @ts-ignore: TS2307 - Cannot find module '@papi/core' or its corresponding type declarations import { IDataProvider, DataProviderDataType } from '@papi/core'; export type Person = { diff --git a/extensions/src/hello-world/.eslintrc.js b/extensions/src/hello-world/.eslintrc.js index 279bb37dcd..c1de14ea7b 100644 --- a/extensions/src/hello-world/.eslintrc.js +++ b/extensions/src/hello-world/.eslintrc.js @@ -16,6 +16,8 @@ module.exports = { // #region ERB rules + // Use `noImplicitReturns` instead. See https://typescript-eslint.io/rules/consistent-return/. + 'consistent-return': 'off', 'import/extensions': 'off', // A temporary hack related to IDE not resolving correct package.json 'import/no-extraneous-dependencies': 'off', diff --git a/extensions/src/hello-world/package.json b/extensions/src/hello-world/package.json index 33ada0f8b2..22952d2d13 100644 --- a/extensions/src/hello-world/package.json +++ b/extensions/src/hello-world/package.json @@ -23,7 +23,8 @@ "lint:scripts": "eslint --ext .cjs,.js,.jsx,.ts,.tsx --cache .", "lint:styles": "stylelint **/*.{css,scss}", "lint-fix": "npm run lint-fix:scripts && npm run lint:styles -- --fix", - "lint-fix:scripts": "prettier --write \"**/*.{ts,tsx,js,jsx,cjs}\" && npm run lint:scripts" + "lint-fix:scripts": "prettier --write \"**/*.{ts,tsx,js,jsx,cjs}\" && npm run lint:scripts", + "typecheck": "tsc -p ./tsconfig.json" }, "browserslist": [], "peerDependencies": { diff --git a/extensions/src/hello-world/src/types/hello-world.d.ts b/extensions/src/hello-world/src/types/hello-world.d.ts index 412ee19c3a..ff6232375b 100644 --- a/extensions/src/hello-world/src/types/hello-world.d.ts +++ b/extensions/src/hello-world/src/types/hello-world.d.ts @@ -1,4 +1,5 @@ declare module 'hello-world' { + // @ts-ignore: TS2307 - Cannot find module '@papi/core' or its corresponding type declarations import type { DataProviderDataType, MandatoryProjectDataTypes } from '@papi/core'; import type { IBaseProjectDataProvider } from 'papi-shared-types'; diff --git a/extensions/src/hello-world/src/web-views/hello-world.web-view.tsx b/extensions/src/hello-world/src/web-views/hello-world.web-view.tsx index be5b95a4b1..18949cea36 100644 --- a/extensions/src/hello-world/src/web-views/hello-world.web-view.tsx +++ b/extensions/src/hello-world/src/web-views/hello-world.web-view.tsx @@ -1,4 +1,4 @@ -import { VerseRef } from '@sillsdev/scripture'; +import { VerseRef } from '@sillsdev/scripture'; import papi, { logger } from '@papi/frontend'; import { useData, diff --git a/extensions/src/legacy-comment-manager/src/types/legacy-comment-manager.d.ts b/extensions/src/legacy-comment-manager/src/types/legacy-comment-manager.d.ts index a7bfa4432c..ee7ce4646c 100644 --- a/extensions/src/legacy-comment-manager/src/types/legacy-comment-manager.d.ts +++ b/extensions/src/legacy-comment-manager/src/types/legacy-comment-manager.d.ts @@ -3,6 +3,7 @@ declare module 'legacy-comment-manager' { DataProviderDataType, DataProviderSubscriberOptions, DataProviderUpdateInstructions, + // @ts-ignore: TS2307 - Cannot find module '@papi/core' or its corresponding type declarations } from '@papi/core'; import type { IProjectDataProvider } from 'papi-shared-types'; import { UnsubscriberAsync } from 'platform-bible-utils'; diff --git a/extensions/src/platform-scripture-editor/.eslintrc.js b/extensions/src/platform-scripture-editor/.eslintrc.js index 279bb37dcd..c1de14ea7b 100644 --- a/extensions/src/platform-scripture-editor/.eslintrc.js +++ b/extensions/src/platform-scripture-editor/.eslintrc.js @@ -16,6 +16,8 @@ module.exports = { // #region ERB rules + // Use `noImplicitReturns` instead. See https://typescript-eslint.io/rules/consistent-return/. + 'consistent-return': 'off', 'import/extensions': 'off', // A temporary hack related to IDE not resolving correct package.json 'import/no-extraneous-dependencies': 'off', diff --git a/extensions/src/platform-scripture-editor/package.json b/extensions/src/platform-scripture-editor/package.json index 9c4e59673f..5b970ea84f 100644 --- a/extensions/src/platform-scripture-editor/package.json +++ b/extensions/src/platform-scripture-editor/package.json @@ -23,7 +23,8 @@ "lint:scripts": "eslint --ext .cjs,.js,.jsx,.ts,.tsx --cache .", "lint:styles": "stylelint **/*.{css,scss}", "lint-fix": "npm run lint-fix:scripts && npm run lint:styles -- --fix", - "lint-fix:scripts": "prettier --write \"**/*.{ts,tsx,js,jsx,cjs}\" && npm run lint:scripts" + "lint-fix:scripts": "prettier --write \"**/*.{ts,tsx,js,jsx,cjs}\" && npm run lint:scripts", + "typecheck": "tsc -p ./tsconfig.json" }, "browserslist": [], "peerDependencies": { diff --git a/extensions/src/platform-scripture-editor/src/types/@biblionexus-foundation__platform-editor.d.ts b/extensions/src/platform-scripture-editor/src/types/@biblionexus-foundation__platform-editor.d.ts new file mode 100644 index 0000000000..1ddea9951b --- /dev/null +++ b/extensions/src/platform-scripture-editor/src/types/@biblionexus-foundation__platform-editor.d.ts @@ -0,0 +1,65 @@ +/** + * Work-around until the `@biblionexus-foundation/platform-editor` package fully includes its types. + * Note there is also a patch that should be removed when this is fixed. + */ + +declare module 'shared-react/annotation/selection.model' { + type UsjLocation = { + jsonPath: string; + offset: number; + }; + + export type SelectionRange = { + start: UsjLocation; + end?: UsjLocation; + }; + + export type AnnotationRange = { + start: UsjLocation; + end: UsjLocation; + }; +} + +declare module 'shared-react/nodes/scripture/usj/ImmutableNoteCallerNode' { + export const immutableNoteCallerNodeName = 'ImmutableNoteCallerNode'; +} + +declare module 'shared-react/plugins/logger-basic.model' { + export type LoggerBasic = { + error(message: string): void; + warn(message: string): void; + info(message: string): void; + }; +} + +declare module 'shared-react/plugins/text-direction.model' { + /** Left-to-right or Right-to-left or Automatically determined from the content. */ + export type TextDirection = 'ltr' | 'rtl' | 'auto'; +} + +declare module 'shared-react/nodes/scripture/usj/usj-node-options.model' { + import { SyntheticEvent } from 'react'; + + /** Option properties to use with each node. */ + type NodeOptions = { [nodeClassName: string]: { [prop: string]: unknown } | undefined }; + type OnClick = (event: SyntheticEvent) => void; + const immutableNoteCallerNodeName = 'ImmutableNoteCallerNode'; + + export const MarkNodeName = 'MarkNode'; + + export type AddMissingComments = (usjCommentIds: string[]) => void; + + /** Options for each editor node. */ + export interface UsjNodeOptions extends NodeOptions { + [immutableNoteCallerNodeName]?: { + /** Possible note callers to use when caller is '+'. */ + noteCallers?: string[]; + /** Click handler method. */ + onClick?: OnClick; + }; + [MarkNodeName]?: { + /** Method to add missing comments. */ + addMissingComments?: AddMissingComments; + }; + } +} diff --git a/extensions/src/platform-scripture/.eslintrc.js b/extensions/src/platform-scripture/.eslintrc.js index 279bb37dcd..c1de14ea7b 100644 --- a/extensions/src/platform-scripture/.eslintrc.js +++ b/extensions/src/platform-scripture/.eslintrc.js @@ -16,6 +16,8 @@ module.exports = { // #region ERB rules + // Use `noImplicitReturns` instead. See https://typescript-eslint.io/rules/consistent-return/. + 'consistent-return': 'off', 'import/extensions': 'off', // A temporary hack related to IDE not resolving correct package.json 'import/no-extraneous-dependencies': 'off', diff --git a/extensions/src/platform-scripture/package.json b/extensions/src/platform-scripture/package.json index 7c14b83004..0e6a7294da 100644 --- a/extensions/src/platform-scripture/package.json +++ b/extensions/src/platform-scripture/package.json @@ -23,7 +23,8 @@ "lint:scripts": "eslint --ext .cjs,.js,.jsx,.ts,.tsx --cache .", "lint:styles": "stylelint **/*.{css,scss}", "lint-fix": "npm run lint-fix:scripts && npm run lint:styles -- --fix", - "lint-fix:scripts": "prettier --write \"**/*.{ts,tsx,js,jsx,cjs}\" && npm run lint:scripts" + "lint-fix:scripts": "prettier --write \"**/*.{ts,tsx,js,jsx,cjs}\" && npm run lint:scripts", + "typecheck": "tsc -p ./tsconfig.json" }, "browserslist": [], "peerDependencies": { diff --git a/extensions/src/platform-scripture/src/types/platform-scripture.d.ts b/extensions/src/platform-scripture/src/types/platform-scripture.d.ts index 4670d6a059..81942e0210 100644 --- a/extensions/src/platform-scripture/src/types/platform-scripture.d.ts +++ b/extensions/src/platform-scripture/src/types/platform-scripture.d.ts @@ -6,6 +6,7 @@ declare module 'platform-scripture' { DataProviderUpdateInstructions, ExtensionDataScope, IDataProvider, + // @ts-ignore: TS2307 - Cannot find module '@papi/core' or its corresponding type declarations } from '@papi/core'; import type { IProjectDataProvider } from 'papi-shared-types'; import { Dispose, LocalizeKey, UnsubscriberAsync } from 'platform-bible-utils'; diff --git a/extensions/src/project-notes-data-provider/index.d.ts b/extensions/src/project-notes-data-provider/index.d.ts index b1b1a174ad..528459fa78 100644 --- a/extensions/src/project-notes-data-provider/index.d.ts +++ b/extensions/src/project-notes-data-provider/index.d.ts @@ -3,6 +3,7 @@ import type { DataProviderDataType, DataProviderSubscriberOptions, IDataProvider, + // @ts-ignore: TS2307 - Cannot find module '@papi/core' or its corresponding type declarations } from '@papi/core'; import { PlatformEvent, Unsubscriber } from 'platform-bible-utils'; diff --git a/extensions/src/quick-verse/.eslintrc.js b/extensions/src/quick-verse/.eslintrc.js index 279bb37dcd..c1de14ea7b 100644 --- a/extensions/src/quick-verse/.eslintrc.js +++ b/extensions/src/quick-verse/.eslintrc.js @@ -16,6 +16,8 @@ module.exports = { // #region ERB rules + // Use `noImplicitReturns` instead. See https://typescript-eslint.io/rules/consistent-return/. + 'consistent-return': 'off', 'import/extensions': 'off', // A temporary hack related to IDE not resolving correct package.json 'import/no-extraneous-dependencies': 'off', diff --git a/extensions/src/quick-verse/package.json b/extensions/src/quick-verse/package.json index befd192c15..4c4f917172 100644 --- a/extensions/src/quick-verse/package.json +++ b/extensions/src/quick-verse/package.json @@ -24,7 +24,8 @@ "lint:scripts": "eslint --ext .cjs,.js,.jsx,.ts,.tsx --cache .", "lint:styles": "stylelint **/*.{css,scss}", "lint-fix": "npm run lint-fix:scripts && npm run lint:styles -- --fix", - "lint-fix:scripts": "prettier --write \"**/*.{ts,tsx,js,jsx,cjs}\" && npm run lint:scripts" + "lint-fix:scripts": "prettier --write \"**/*.{ts,tsx,js,jsx,cjs}\" && npm run lint:scripts", + "typecheck": "tsc -p ./tsconfig.json" }, "browserslist": [], "peerDependencies": { diff --git a/extensions/src/quick-verse/src/types/quick-verse.d.ts b/extensions/src/quick-verse/src/types/quick-verse.d.ts index 451747d5c3..205520b507 100644 --- a/extensions/src/quick-verse/src/types/quick-verse.d.ts +++ b/extensions/src/quick-verse/src/types/quick-verse.d.ts @@ -1,4 +1,5 @@ declare module 'quick-verse' { + // @ts-ignore: TS2307 - Cannot find module '@papi/core' or its corresponding type declarations import { DataProviderDataType, IDataProvider } from '@papi/core'; export type QuickVerseSetData = string | { text: string; isHeresy: boolean }; diff --git a/extensions/tsconfig.json b/extensions/tsconfig.json index f2cdd36969..c96bf4e996 100644 --- a/extensions/tsconfig.json +++ b/extensions/tsconfig.json @@ -23,7 +23,7 @@ "jsx": "react-jsx", "typeRoots": [ // Include default type declarations - "./node_modules/@types", + "../node_modules/@types", // Include papi-dts type declarations (for papi.d.ts) "../lib", // Include these bundled extensions' type declarations diff --git a/lib/papi-dts/package.json b/lib/papi-dts/package.json index b6eb775061..0c5b6473a3 100644 --- a/lib/papi-dts/package.json +++ b/lib/papi-dts/package.json @@ -32,7 +32,8 @@ "clean": "rimraf papi.tsbuildinfo", "lint": "cross-env NODE_ENV=development eslint --ext .cjs,.js,.jsx,.ts,.tsx --cache .", "lint-fix": "prettier --write \"**/*.{ts,tsx,js,jsx,cjs}\" && npm run lint", - "lint:staged": "lint-staged -q" + "lint:staged": "lint-staged -q", + "typecheck": "tsc -p ./tsconfig.lint.json" }, "lint-staged": { "*.{cjs,js,jsx,ts,tsx}": ["prettier --write", "cross-env NODE_ENV=development eslint --cache"], diff --git a/lib/papi-dts/tsconfig.lint.json b/lib/papi-dts/tsconfig.lint.json index 0d9138dbbf..ddf86de666 100644 --- a/lib/papi-dts/tsconfig.lint.json +++ b/lib/papi-dts/tsconfig.lint.json @@ -1,4 +1,10 @@ { - "extends": "./tsconfig", - "files": [".eslintrc.cjs", "edit-papi-d-ts.ts", "papi.d.ts"] + "extends": "../../tsconfig", + "compilerOptions": { + "module": "ESNext", + "baseUrl": "./", + "noEmit": true + }, + "include": [".eslintrc.cjs", "edit-papi-d-ts.ts", "papi.d.ts"], + "exclude": [] } diff --git a/lib/platform-bible-react/package.json b/lib/platform-bible-react/package.json index 786e4e1cb1..104f05f935 100644 --- a/lib/platform-bible-react/package.json +++ b/lib/platform-bible-react/package.json @@ -39,7 +39,8 @@ "lint:styles": "stylelint **/*.{css,scss}", "lint-fix": "npm run lint-fix:scripts && npm run lint:styles -- --fix", "lint-fix:scripts": "prettier --write \"**/*.{ts,tsx,js,jsx,cjs}\" && npm run lint:scripts", - "test": "jest --silent" + "test": "jest --silent", + "typecheck": "tsc -p ./tsconfig.json" }, "peerDependencies": { "react": ">=18.3.1", diff --git a/lib/platform-bible-react/tsconfig.json b/lib/platform-bible-react/tsconfig.json index 449f442c51..af0da8fb01 100644 --- a/lib/platform-bible-react/tsconfig.json +++ b/lib/platform-bible-react/tsconfig.json @@ -2,7 +2,6 @@ "extends": "../../tsconfig", "compilerOptions": { "baseUrl": "./src", - "rootDir": "./src", "target": "ESNext", "module": "ESNext", // Running npm i removes packages that are in common between the current directory's @@ -16,7 +15,7 @@ "incremental": false, "isolatedModules": true, "noEmit": true, - "noImplicitReturns": false, + "noImplicitReturns": true, "skipLibCheck": false, "useDefineForClassFields": true, "outDir": "", diff --git a/lib/platform-bible-utils/package.json b/lib/platform-bible-utils/package.json index 26bdde5ea1..eaa751af70 100644 --- a/lib/platform-bible-utils/package.json +++ b/lib/platform-bible-utils/package.json @@ -38,7 +38,8 @@ "lint:scripts": "cross-env NODE_ENV=development eslint --ext .cjs,.js,.jsx,.ts,.tsx --cache .", "lint-fix": "npm run lint-fix:scripts", "lint-fix:scripts": "prettier --write \"**/*.{ts,tsx,js,jsx,cjs}\" && npm run lint:scripts", - "test": "jest --silent" + "test": "jest --silent", + "typecheck": "tsc -p ./tsconfig.json" }, "peerDependencies": {}, "dependencies": { diff --git a/lib/platform-bible-utils/tsconfig.json b/lib/platform-bible-utils/tsconfig.json index 045c685224..028770a8fd 100644 --- a/lib/platform-bible-utils/tsconfig.json +++ b/lib/platform-bible-utils/tsconfig.json @@ -2,7 +2,6 @@ "extends": "../../tsconfig", "compilerOptions": { "baseUrl": "./src", - "rootDir": "./src", "target": "ESNext", "module": "ESNext", // Running npm i removes packages that are in common between the current directory's @@ -16,7 +15,7 @@ "incremental": false, "isolatedModules": true, "noEmit": true, - "noImplicitReturns": false, + "noImplicitReturns": true, "skipLibCheck": false, "useDefineForClassFields": true, "outDir": "", diff --git a/package-lock.json b/package-lock.json index d9f5c11219..1b136c4eb8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12271,6 +12271,8 @@ }, "node_modules/@types/jsdom": { "version": "20.0.1", + "resolved": "https://registry.npmjs.org/@types/jsdom/-/jsdom-20.0.1.tgz", + "integrity": "sha512-d0r18sZPmMQr1eG35u12FZfhIXNrnsPU/g5wvRKCUf/tOGilKKwYMYGqh33BNR6ba+2gkHw1EUiHoN3mn7E5IQ==", "dev": true, "license": "MIT", "dependencies": { @@ -39723,6 +39725,8 @@ }, "@types/jsdom": { "version": "20.0.1", + "resolved": "https://registry.npmjs.org/@types/jsdom/-/jsdom-20.0.1.tgz", + "integrity": "sha512-d0r18sZPmMQr1eG35u12FZfhIXNrnsPU/g5wvRKCUf/tOGilKKwYMYGqh33BNR6ba+2gkHw1EUiHoN3mn7E5IQ==", "dev": true, "requires": { "@types/node": "*", diff --git a/package.json b/package.json index b3c2820edc..4e4a3be98e 100644 --- a/package.json +++ b/package.json @@ -63,13 +63,13 @@ "format": "prettier --write .", "format:check": "prettier --check .", "lint": "cross-env NODE_OPTIONS=\"--max-old-space-size=4096\" npm run build:types && npm run lint:scripts && npm run lint:styles && cd lib/papi-dts && npm run lint && cd ../../extensions && npm run lint", + "lint:config": "cross-env NODE_ENV=development eslint --print-config .eslintrc.js > .eslintConfig.json", "lint:scripts": "cross-env NODE_ENV=development eslint --ext .cjs,.js,.jsx,.ts,.tsx --cache .", + "lint:staged": "npm run build:types && lint-staged -q && cd lib/papi-dts && npm run lint:staged && cd ../../extensions && npm run lint:staged", "lint:styles": "stylelint **/*.{css,scss}", "lint-fix": "npm run build:types && npm run lint-fix:scripts && npm run lint-fix:styles && cd lib/papi-dts && npm run lint-fix && cd ../../extensions && npm run lint-fix", "lint-fix:scripts": "prettier --write \"**/*.{ts,tsx,js,jsx,cjs}\" && npm run lint:scripts", "lint-fix:styles": "npm run lint:styles -- --fix", - "lint:config": "cross-env NODE_ENV=development eslint --print-config .eslintrc.js > .eslintConfig.json", - "lint:staged": "npm run build:types && lint-staged -q && cd lib/papi-dts && npm run lint:staged && cd ../../extensions && npm run lint:staged", "ncu:group": "npx npm-check-updates --interactive --format group", "package": "tsx ./.erb/scripts/clean.js dist && npm run build && npm run build:extensions:production && electron-builder build --publish never && npm run build:dll", "package:debug": "cross-env DEBUG_PROD=true npm run package", @@ -85,10 +85,15 @@ "start:renderer": "cross-env NODE_ENV=development TS_NODE_TRANSPILE_ONLY=true webpack serve --config ./.erb/configs/webpack.config.renderer.dev.ts", "start:data": "dotnet watch --project c-sharp/ParanextDataProvider.csproj", "stop": "tsx stop-processes.mjs", - "test:core": "jest --silent", - "test": "npm run test:core && npm run test --workspaces --if-present", "storybook": "storybook dev -p 6006", - "storybook:build": "storybook build" + "storybook:build": "storybook build", + "test": "npm run test:core && npm run test --workspaces --if-present", + "test:core": "jest --silent", + "typecheck": "npm run typecheck:core && npm run typecheck --workspaces --if-present", + "typecheck:core": "tsc -p ./tsconfig.json", + "typecheck:papi-dts": "cd lib/papi-dts && npm run typecheck", + "typecheck:platform-bible-react": "cd lib/platform-bible-react && npm run typecheck", + "typecheck:platform-bible-utils": "cd lib/platform-bible-utils && npm run typecheck" }, "lint-staged": { "*.{cjs,js,jsx,ts,tsx}": ["prettier --write", "cross-env NODE_ENV=development eslint --cache"], diff --git a/patches/@biblionexus-foundation+platform-editor+0.6.4.patch b/patches/@biblionexus-foundation+platform-editor+0.6.4.patch new file mode 100644 index 0000000000..11dbde872b --- /dev/null +++ b/patches/@biblionexus-foundation+platform-editor+0.6.4.patch @@ -0,0 +1,13 @@ +diff --git a/node_modules/@biblionexus-foundation/platform-editor/dist/index.d.ts b/node_modules/@biblionexus-foundation/platform-editor/dist/index.d.ts +index fae3dbf..471303c 100644 +--- a/node_modules/@biblionexus-foundation/platform-editor/dist/index.d.ts ++++ b/node_modules/@biblionexus-foundation/platform-editor/dist/index.d.ts +@@ -5,7 +5,7 @@ import { LoggerBasic } from 'shared-react/plugins/logger-basic.model'; + import { ScriptureReference } from 'platform-bible-utils'; + import { SelectionRange } from 'shared-react/annotation/selection.model'; + import { TextDirection } from 'shared-react/plugins/text-direction.model'; +-import { Usj } from '../../../utilities/src'; ++import { Usj } from '@biblionexus-foundation/scripture-utilities'; + import { UsjNodeOptions } from 'shared-react/nodes/scripture/usj/usj-node-options.model'; + + declare type Comment_2 = { diff --git a/patches/@types+jsdom+20.0.1.patch b/patches/@types+jsdom+20.0.1.patch new file mode 100644 index 0000000000..d8f79c68a5 --- /dev/null +++ b/patches/@types+jsdom+20.0.1.patch @@ -0,0 +1,14 @@ +diff --git a/node_modules/@types/jsdom/base.d.ts b/node_modules/@types/jsdom/base.d.ts +index 67d7514..745c643 100644 +--- a/node_modules/@types/jsdom/base.d.ts ++++ b/node_modules/@types/jsdom/base.d.ts +@@ -191,7 +191,9 @@ declare module "jsdom" { + + /* ECMAScript Globals */ + globalThis: DOMWindow; ++ // @ts-ignore error TS2411: Property '["Infinity"]' of type 'number' is not assignable to 'number' index type 'Window'. + readonly ["Infinity"]: number; ++ // @ts-ignore error TS2411: Property '["NaN"]' of type 'number' is not assignable to 'number' index type 'Window'. + readonly ["NaN"]: number; + readonly undefined: undefined; + diff --git a/src/extension-host/services/extension.service.ts b/src/extension-host/services/extension.service.ts index 490fcaab9a..e843263066 100644 --- a/src/extension-host/services/extension.service.ts +++ b/src/extension-host/services/extension.service.ts @@ -765,7 +765,9 @@ async function getInstalledExtensions(): Promise { !enabled.find((enabledId) => enabledId.extensionName === disabledId.extensionName), ); - // "Packaged" extensions are all the running extensions that aren't "enabled" + // "Packaged" extensions are all the running extensions that aren't "enabled". + // `undefined` items are filtered out so can assert here. + // eslint-disable-next-line no-type-assertion/no-type-assertion const packaged = [...activeExtensions.values()] .map((active) => { const packagedId: ExtensionIdentifier = { @@ -777,7 +779,7 @@ async function getInstalledExtensions(): Promise { ? undefined : packagedId; }) - .filter((identifier) => !!identifier); + .filter((identifier) => !!identifier) as ExtensionIdentifier[]; return { enabled, diff --git a/src/renderer/components/docking/platform-dock-layout-positioning.util.tests.ts b/src/renderer/components/docking/platform-dock-layout-positioning.util.test.ts similarity index 100% rename from src/renderer/components/docking/platform-dock-layout-positioning.util.tests.ts rename to src/renderer/components/docking/platform-dock-layout-positioning.util.test.ts diff --git a/src/renderer/global-this.model.ts b/src/renderer/global-this.model.ts index b9aac97e32..53a376be74 100644 --- a/src/renderer/global-this.model.ts +++ b/src/renderer/global-this.model.ts @@ -72,9 +72,6 @@ type WebViewRequire = typeof webViewRequire; /* eslint-disable vars-on-top, no-var */ declare global { var papi: Papi; - // @ts-expect-error ts(2300) we're declaring React here because it may not always be available in - // all contexts - var React: typeof ReactModule; var ReactJsxRuntime: ReactJsxRuntimeType; // For some reason, TypeScript throws an index signature error on assignment to // globalThis.ReactDOM, so this is ReactDom, not ReactDOM diff --git a/src/stories/basics/combo-box.stories.tsx b/src/stories/basics/combo-box.stories.tsx index 6486103a90..e65329aad8 100644 --- a/src/stories/basics/combo-box.stories.tsx +++ b/src/stories/basics/combo-box.stories.tsx @@ -6,10 +6,6 @@ const meta: Meta = { component: ComboBox, tags: ['autodocs'], argTypes: { - title: { control: 'text' }, - isDisabled: { control: 'boolean' }, - hasError: { control: 'boolean' }, - isFullWidth: { control: 'boolean' }, options: { control: 'object' }, className: { control: 'text' }, }, @@ -22,22 +18,6 @@ export const Default: Story = { args: {}, }; -export const Disabled: Story = { - args: { isDisabled: true }, -}; - -export const ErrorState: Story = { - args: { hasError: true }, -}; - -export const FullWidth: Story = { - args: { isFullWidth: true }, -}; - -export const Title: Story = { - args: { title: 'Combo box' }, -}; - export const Placeholder: Story = { args: { options: ['Option 1', 'Option2', 'Option3'], diff --git a/src/stories/basics/context-menu.stories.tsx b/src/stories/basics/context-menu.stories.tsx deleted file mode 100644 index c4a706ab86..0000000000 --- a/src/stories/basics/context-menu.stories.tsx +++ /dev/null @@ -1,174 +0,0 @@ -import type { Meta, StoryObj } from '@storybook/react'; -import { Command, ContextMenu, MenuPropsBase } from 'platform-bible-react'; -import { SingleColumnMenu } from 'platform-bible-utils'; -import { LocalizedMenus } from '@shared/utils/menu-document-combiner'; - -const meta: Meta = { - title: 'Basics/ContextMenu', - component: ContextMenu, - tags: ['autodocs'], -}; -export default meta; - -type Story = StoryObj; - -export const Default: Story = { - render: (args) => ( -
-

Prior text

- - - Sample text to right-click. Since there are no menu items, only the browser default menu - should show. - - -

Following text

-
- ), -}; - -function HandleMenuCommand(command: Command) { - if (command.command === 'storybookMenu.log') { - // eslint-disable-next-line no-console - console.log(command.command); - } else if (command.command === 'storybookMenu.warn') { - // eslint-disable-next-line no-console - console.warn(command.command); - } else { - // eslint-disable-next-line no-console - console.error(`Unexpected command: ${command.command}`); - } -} - -type LocalizedContextMenu = LocalizedMenus['defaultWebViewContextMenu']; - -function GetMenuDefinition(): Partial { - const contextMenuDefinition: LocalizedContextMenu = { - groups: { - 'group.2': { order: 2, column: 'TODO: this should not be required' }, - 'group.1': { order: 1, column: 'TODO: this should not be required' }, - 'group.submenu': { order: 1, menuItem: 'submenu.root' }, - }, - items: [ - { - label: 'Do something scary', - localizeNotes: 'N/A', - tooltip: 'Proceed with caution!', - group: 'group.2', - order: 1, - command: 'storybookMenu.warn', - iconPathAfter: '/sample-icon.png', - }, - { - label: 'Do something normal in group 2', - localizeNotes: 'N/A', - tooltip: 'Perform a normal action', - group: 'group.2', - order: 0, - command: 'storybookMenu.log', - iconPathBefore: '/sample-icon.png', - }, - { - label: 'Do something normal in group 1', - localizeNotes: 'N/A', - tooltip: 'Perform a normal action', - group: 'group.1', - order: 0, - command: 'storybookMenu.log', - iconPathBefore: '/sample-icon.png', - }, - { - label: 'I have a submenu', - localizeNotes: 'N/A', - tooltip: 'Click me to see submenu', - group: 'group.1', - order: 0, - id: 'submenu.root', - iconPathBefore: '/sample-icon.png', - }, - { - label: 'Do something else in group 1', - localizeNotes: 'N/A', - tooltip: 'Perform another action', - group: 'group.1', - order: 1, - command: 'storybookMenu.other', - iconPathBefore: '/sample-icon.png', - }, - { - label: 'I am thing 2 on the submenu', - localizeNotes: 'N/A', - tooltip: 'Do not click me - it tickles!', - group: 'group.submenu', - order: 4, - command: 'storybookMenu.tickle', - }, - { - label: 'I am thing 1 on the submenu', - localizeNotes: 'N/A', - tooltip: 'Log something to the console', - group: 'group.submenu', - order: 2, - command: 'storybookMenu.log', - }, - ], - }; - - // TODO: As part of #425 (Menus: Stitch together back end services and UI components to get menu - // contributions working end-to-end), we will want to create a parallel type to SingleColumnMenu - // that should be used in the React components (and returned here) that does not expect the - // ReferencedItem keys, but rather takes a plain string. - return { - // eslint-disable-next-line no-type-assertion/no-type-assertion - menuDefinition: contextMenuDefinition as SingleColumnMenu, - commandHandler: HandleMenuCommand, - }; -} - -export const Normal: Story = { - args: GetMenuDefinition(), - render: (args) => ( -
-

Prior text

-

- Some - - - sample text to right-click - - - . -

-

Following text

-
- ), -}; - -export const Paratext: Story = { - args: GetMenuDefinition(), - render: (args) => ( -
-

Prior text

- - Sample text to right-click. - -

Following text

-
- ), -}; - -export const ParatextBright: Story = { - args: GetMenuDefinition(), - render: (args) => ( -
-

Prior text

- - - Sample text to right-click. Sample text to right-click. Sample text to right-click. Sample - text to right-click. Sample text to right-click. Sample text to right-click. - - -

Following text

-
- ), -}; diff --git a/src/stories/basics/menu-item-list.stories.tsx b/src/stories/basics/menu-item-list.stories.tsx deleted file mode 100644 index 3b9576a831..0000000000 --- a/src/stories/basics/menu-item-list.stories.tsx +++ /dev/null @@ -1,64 +0,0 @@ -import type { Meta, StoryObj } from '@storybook/react'; -import { MenuItemList, Command } from 'platform-bible-react'; - -const meta: Meta = { - title: 'Basics/MenuItemList', - component: MenuItemList, - tags: ['autodocs'], - argTypes: { - items: { control: 'object' }, - }, -}; -export default meta; - -type Story = StoryObj; - -export const DefaultNoMenuItems: Story = { - args: {}, -}; - -function HandleMenuCommand(command: Command) { - if (command.command === 'storybookMenu.log') { - // eslint-disable-next-line no-console - console.log(command.name); - } else if (command.command === 'storybookMenu.warn') { - // eslint-disable-next-line no-console - console.warn(command.name); - } else { - // eslint-disable-next-line no-console - console.error(`Unexpected command: ${command.name}`); - } -} - -function GetMenuDefinition(className: string) { - const menuDefinition = { - className, - commandHandler: HandleMenuCommand, - items: [ - { - name: 'Do something normal', - command: 'storybookMenu.log', - iconPathBefore: '/sample-icon.png', - hasDivider: true, - }, - { - name: 'Do something scary', - command: 'storybookMenu.warn', - iconPathAfter: '/sample-icon.png', - }, - ], - }; - return menuDefinition; -} - -export const Normal: Story = { - args: GetMenuDefinition(''), -}; - -export const Paratext: Story = { - args: GetMenuDefinition('paratext'), -}; - -export const ParatextBright: Story = { - args: GetMenuDefinition('paratext bright'), -}; diff --git a/src/stories/basics/slider.stories.ts b/src/stories/basics/slider.stories.ts index 944086fe4d..380b978b66 100644 --- a/src/stories/basics/slider.stories.ts +++ b/src/stories/basics/slider.stories.ts @@ -6,7 +6,6 @@ const meta: Meta = { component: Slider, tags: ['autodocs'], argTypes: { - isDisabled: { control: 'boolean' }, orientation: { options: [0, 1], mapping: ['horizontal', 'vertical'], @@ -18,16 +17,6 @@ const meta: Meta = { min: { control: 'number' }, max: { control: 'number' }, step: { control: 'number' }, - showMarks: { control: 'boolean' }, - defaultValue: { control: 'number' }, - valueLabelDisplay: { - options: [0, 1, 2], - mapping: ['on', 'auto', 'off'], - control: { - type: 'select', - labels: ['On', 'Auto', 'Off'], - }, - }, className: { control: 'text' }, }, }; @@ -39,18 +28,12 @@ export const Default: Story = { args: {}, }; -export const Disabled: Story = { - args: { isDisabled: true }, -}; - export const DiscreteValues: Story = { args: { min: -10, max: 10, step: 2, - showMarks: true, - defaultValue: 0, - valueLabelDisplay: 'on', + defaultValue: [0], }, }; diff --git a/src/stories/basics/switch.stories.ts b/src/stories/basics/switch.stories.ts index f9cb48b277..2187db73c9 100644 --- a/src/stories/basics/switch.stories.ts +++ b/src/stories/basics/switch.stories.ts @@ -6,8 +6,6 @@ const meta: Meta = { component: Switch, tags: ['autodocs'], argTypes: { - isDisabled: { control: 'boolean' }, - hasError: { control: 'boolean' }, className: { control: 'text' }, }, }; @@ -27,14 +25,6 @@ export const Secondary: Story = { args: { className: 'secondary' }, }; -export const Disabled: Story = { - args: { isDisabled: true }, -}; - -export const ErrorState: Story = { - args: { hasError: true }, -}; - export const Paratext: Story = { args: { className: 'paratext', @@ -50,8 +40,9 @@ export const ParatextBright: Story = { export const OnChange: Story = { args: { onChange(event) { - // eslint-disable-next-line no-console - console.log(event.target.checked); + // There is likely a better way to do this without using `as`. + // eslint-disable-next-line no-console, no-type-assertion/no-type-assertion + console.log((event.target as HTMLInputElement).checked); }, }, }; diff --git a/src/stories/basics/text-field.stories.ts b/src/stories/basics/text-field.stories.ts index 32fedefd68..d42d24b1d6 100644 --- a/src/stories/basics/text-field.stories.ts +++ b/src/stories/basics/text-field.stories.ts @@ -6,14 +6,6 @@ const meta: Meta = { component: TextField, tags: ['autodocs'], argTypes: { - variant: { - options: [0, 1], - mapping: ['outlined', 'filled'], - control: { - type: 'select', - labels: ['Outlined', 'Filled'], - }, - }, helperText: { control: 'text' }, label: { control: 'text' }, placeholder: { control: 'text' }, diff --git a/src/stories/basics/toolbar.stories.tsx b/src/stories/basics/toolbar.stories.tsx index 5dada06004..38737cc83b 100644 --- a/src/stories/basics/toolbar.stories.tsx +++ b/src/stories/basics/toolbar.stories.tsx @@ -109,19 +109,8 @@ const menuLayoutWithIcons: LocalizedMainMenu = { ], }; -// Function to localize MultiColumnMenu and return Promise> -function localizeMenu(menu: MultiColumnMenu): Promise> { - // Implement localization logic here - // For demonstration purposes, let's assume we're just converting keys to strings - // eslint-disable-next-line no-type-assertion/no-type-assertion - const localizedMenu: Localized = menu as Localized; - - // Returning a resolved Promise with the localized menu - return Promise.resolve(localizedMenu); -} - function provideMenuData(isSupportAndDevelopment: boolean): Promise> { - return localizeMenu(isSupportAndDevelopment ? menuLayoutWithIcons : menuLayoutWithoutIcons); + return Promise.resolve(isSupportAndDevelopment ? menuLayoutWithIcons : menuLayoutWithoutIcons); } type Story = StoryObj; diff --git a/tsconfig.json b/tsconfig.json index 663f916396..459d88b3f3 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -38,9 +38,10 @@ "resolveJsonModule": true, "outDir": ".erb/dll" }, - "include": ["src", "assets"], + "include": ["src", "assets", "!**/*.test.{ts,tsx}"], "exclude": [ "node_modules", + "dist", "test", "release/build", "release/app/dist",