diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000..0b4f9a7 --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1 @@ +* @tjcouch-sil @lyonsil diff --git a/.github/actions/bump-versions-action/action.yml b/.github/actions/bump-versions-action/action.yml new file mode 100644 index 0000000..d0be760 --- /dev/null +++ b/.github/actions/bump-versions-action/action.yml @@ -0,0 +1,19 @@ +name: Bump Versions Action +description: | + Runs bump-versions.ts script + +inputs: + newVersion: + description: "Version to bump all the repo's versions to on a new branch (called `bump-versions-`), e.g. 0.3.0-alpha.0." + required: true + +runs: + using: 'composite' + steps: + - name: Bump repo versions + # Bump versions using the built-in git token https://github.com/actions/checkout/tree/v4/?tab=readme-ov-file#push-a-commit-using-the-built-in-token + shell: bash + run: | + git config user.name "github-actions[bot]" + git config user.email "41898282+github-actions[bot]@users.noreply.github.com" + npm run bump-versions -- ${{ inputs.newVersion }} diff --git a/.github/workflows/bump-versions.yml b/.github/workflows/bump-versions.yml new file mode 100644 index 0000000..c151813 --- /dev/null +++ b/.github/workflows/bump-versions.yml @@ -0,0 +1,51 @@ +name: Bump Versions +run-name: Bump versions on ${{ github.head_ref || github.ref_name }} to ${{ github.event.inputs.newVersion }} + +on: + workflow_dispatch: + inputs: + newVersion: + description: "Version to bump all the repo's versions to on a new branch (called `bump-versions-`), e.g. 0.3.0-alpha.0." + required: true + +jobs: + bump-versions: + name: Bump versions on ${{ matrix.os }} + + runs-on: ${{ matrix.os }} + + permissions: + contents: write + + strategy: + matrix: + os: [ubuntu-latest] + + steps: + - name: Output Workflow Dispatch Inputs + run: echo "${{ toJSON(github.event.inputs) }}" + + - name: Checkout git repo + uses: actions/checkout@v4 + + - name: Read package.json + id: package_json + uses: zoexx/github-action-json-file-properties@1.0.6 + with: + file_path: 'package.json' + + - name: Install Node and NPM + uses: actions/setup-node@v4 + with: + cache: npm + node-version: ${{ fromJson(steps.package_json.outputs.volta).node }} + + - name: Install packages + run: | + npm ci + + - name: Bump repo versions + if: ${{ inputs.newVersion != '' }} + uses: ./.github/actions/bump-versions-action + with: + newVersion: ${{ inputs.newVersion }} diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 3106eba..d5748cf 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -102,7 +102,10 @@ jobs: omitPrereleaseDuringUpdate: true # make the new release a pre-release prerelease: true + # tag+commit creates a version tag for this release with the tag name at the commit ref + # so the GitHub Release doesn't have to create the tag and assume it is on `main` tag: v${{ inputs.version }} + commit: ${{ github.head_ref || github.ref_name }} # only update if the release is still a draft updateOnlyUnreleased: true @@ -116,11 +119,9 @@ jobs: - name: Bump repo versions if: ${{ inputs.newVersionAfterPublishing != '' }} - # Bump versions using the built-in git token https://github.com/actions/checkout/tree/v4/?tab=readme-ov-file#push-a-commit-using-the-built-in-token - run: | - git config user.name "github-actions[bot]" - git config user.email "41898282+github-actions[bot]@users.noreply.github.com" - npm run bump-versions -- ${{ inputs.newVersionAfterPublishing }} + uses: ./.github/actions/bump-versions-action + with: + newVersion: ${{ inputs.newVersionAfterPublishing }} # Enable tmate debugging of manually-triggered workflows if the input option was provided - name: Setup tmate session diff --git a/README.md b/README.md index 213dea3..bfa332d 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,5 @@ + + # scripture-forge-platform-extensions Scripture Forge extensions for Platform.Bible @@ -6,9 +8,11 @@ Scripture Forge extensions for Platform.Bible ## Template Info -This Webpack project template is pre-configured to build an arbitrary number of Platform.Bible extensions. It contains only the essential components needed for a multi-extension repository. Note that many of the files mentioned in [Summary](#summary) are not present in this template because they describe extension code which must be added to this template. For inspiration on what extensions in a multi-extension repo could look like, refer to any repo forked from this template. A good example is [platform-bible-sample-extensions](https://github.com/paranext/platform-bible-sample-extensions). +This is a Webpack project template pre-configured to build an arbitrary number of Platform.Bible extensions. It includes only the bare essentials required for a multi-extension repository to work. + +Note that many of the files mentioned in [Summary](#summary) are not present in this template because they describe extension code which must be added to this template. For examples of what extensions in a multi-extension repo might look like, refer to any repo based on this template — for instance, the [platform-bible-sample-extensions](https://github.com/paranext/platform-bible-sample-extensions). -There is also a simple [template pre-configured to build a single Platform.Bible extension](https://github.com/paranext/paranext-extension-template). +**Important:** Before proceding to use this template, consider whether you intend to build a single extension to be packaged and installed independently, or a set of related extensions that should be used together. If the former, it would be better to use the simple [template pre-configured to build a single Platform.Bible extension](https://github.com/paranext/paranext-extension-template). ### Customize repo details @@ -79,6 +83,8 @@ This is a Webpack project configured to build Platform.Bible extensions. The gen - `dist/` is a generated folder containing the built extension files - `release/` is a generated folder containing zips of the built extension files +> See the [Extension Anatomy wiki page](https://github.com/paranext/paranext-extension-template/wiki/Extension-Anatomy) for more information about the various files that comprise extensions and their relationships to each other. + ## To install ### Install dependencies @@ -148,14 +154,14 @@ These steps will walk you through releasing a version on GitHub and bumping the 2. Manually dispatch the Publish workflow in GitHub Actions targeting the branch you want to release from (in the previous example, this would be `my-branch`). This workflow creates a new pre-release for the version you intend to release and creates a new `bump-versions-` branch to bump the version after the release so future changes apply to a new in-progress version instead of to the already released version. This workflow has the following inputs: - - `version`: enter the version you intend to publish (e.g. 0.2.0). This is simply for verification to make sure you release the code that you intend to release. It is compared to the version in the code, and the workflow will fail if they do not match. - - `newVersionAfterPublishing`: enter the version you want to bump to after releasing (e.g. 0.3.0-alpha.0). Future changes will apply to this new version instead of to the version that was already released. Leave blank if you don't want to bump - - `bumpRef`: enter the Git ref you want to create the bump versions branch from, e.g. `main`. Leave blank if you want to use the branch selected for the workflow run. For example, if you release from a stable branch named `release-prep`, you may want to bump the version on `main` so future development work happens on the new version, then you can rebase `release-prep` onto `main` when you are ready to start preparing the next stable release. + - `version`: Enter the version you intend to publish (e.g. 0.2.0). This is simply for verification to make sure you release the code that you intend to release. It is compared to the version in the code, and the workflow will fail if they do not match. + - `newVersionAfterPublishing`: Enter the version you want to bump to after releasing (e.g. 0.3.0-alpha.0). Future changes will apply to this new version instead of to the version that was already released. Leave blank if you don't want to bump. + - `bumpRef`: Enter the Git ref you want to create the bump versions branch from, e.g. `main`. Leave blank if you want to use the branch selected for the workflow run. For example, if you release from a stable branch named `release-prep`, you may want to bump the version on `main` so future development work happens on the new version, then you can rebase `release-prep` onto `main` when you are ready to start preparing the next stable release.
[Optional] Create a new pre-release and bump versions branch manually - ### Manually create a new pre-release and bump versions branch + #### Manually create a new pre-release and bump versions branch Alternatively, you can create a new pre-release manually: @@ -197,7 +203,7 @@ Following are some problems you may encounter while publishing and steps to solv If you see the following error in the GitHub Actions workflow logs while packaging: -```bash +``` Module build failed (from ./node_modules/swc-loader/src/index.js): Error: Failed to load native binding ``` @@ -281,6 +287,8 @@ npm run update-from-templates If you encounter errors from merge conflicts, please resolve the merge conflicts, finish the commit, and run the script above again. +For more information, read [the instructions on the Paranext Extension Template wiki](https://github.com/paranext/paranext-extension-template/wiki/Merging-Template-Changes-into-Your-Extension). + **Note:** The merge/squash commits created when updating this repo and its extensions from the templates are important; Git uses them to compare the files for future updates. If you edit this repo's Git history, please preserve these commits (do not squash them, for example) to avoid duplicated merge conflicts in the future.
@@ -341,7 +349,7 @@ Adding this import to your WebView's styles enables Tailwind CSS in the WebView. - [Tailwind's preflight](https://tailwindcss.com/docs/preflight) is enabled by default, meaning some default HTML tag styles are significantly modified. You can [disable it](https://tailwindcss.com/docs/preflight#disabling-preflight) or [restrict its scope](https://www.npmjs.com/package/tailwindcss-scoped-preflight) if desired. However, the preferred approach is generally to use [`@tailwindcss/typography`](https://github.com/tailwindlabs/tailwindcss-typography), included in this project's Tailwind configuration by default, when displaying flowing content. - You can apply theme colors using Tailwind classes corresponding to the CSS property and theme color variable name like `tw-bg-primary`. -Please see the wiki's [Tailwind CSS in Web Views](https://github.com/paranext/paranext-extension-template/wiki/Extension-Anatomy#web-view-component) page for more information about using Tailwind in your web view. +Please see the wiki's [Tailwind CSS in WebViews](https://github.com/paranext/paranext-extension-template/wiki/Extension-Anatomy#webview-component) page for more information about using Tailwind in your WebView. ### Special imports diff --git a/lib/bump-versions.ts b/lib/bump-versions.ts index 9e4ffc1..249fa6a 100644 --- a/lib/bump-versions.ts +++ b/lib/bump-versions.ts @@ -3,7 +3,7 @@ import path from 'path'; import { getExtensions } from '../webpack/webpack.util'; import { checkForWorkingChanges, execCommand } from './git.util'; -// #region shared with https://github.com/paranext/paranext-extension-template/blob/main/lib/bump-versions.ts and https://github.com/paranext/paranext/blob/main/lib/bump-versions.ts +// #region shared with https://github.com/paranext/paranext-extension-template/blob/main/lib/bump-versions.ts // This script checks out a new branch, bumps the versions of all extensions in the repo, // and then commits the changes. It is generally expected that you will be on `main` when you run @@ -16,9 +16,13 @@ import { checkForWorkingChanges, execCommand } from './git.util'; const newVersion = process.argv[2]; const shouldAllowWorkingChanges = process.argv.includes('--allow-working-changes'); +// #endregion + +// #region shared with https://github.com/paranext/paranext-extension-template/blob/main/lib/bump-versions.ts and https://github.com/paranext/paranext/blob/main/lib/bump-versions.ts + (async () => { // Make sure there are not working changes so we don't interfere with normal edits - if (!shouldAllowWorkingChanges && (await checkForWorkingChanges())) return 1; + if (!shouldAllowWorkingChanges && (await checkForWorkingChanges())) process.exit(1); const branchName = `bump-versions-${newVersion}`; @@ -27,7 +31,7 @@ const shouldAllowWorkingChanges = process.argv.includes('--allow-working-changes await execCommand(`git checkout -b ${branchName}`); } catch (e) { console.error(`Error on git checkout: ${e}`); - return 1; + process.exit(1); } const bumpVersionCommand = `npm version ${newVersion} --git-tag-version false`; @@ -37,7 +41,7 @@ const shouldAllowWorkingChanges = process.argv.includes('--allow-working-changes await execCommand(bumpVersionCommand); } catch (e) { console.error(`Error on bumping version: ${e}`); - return 1; + process.exit(1); } // #endregion @@ -68,7 +72,7 @@ const shouldAllowWorkingChanges = process.argv.includes('--allow-working-changes }); } catch (e) { console.error(`Error on bumping package version for extension ${ext.name}: ${e}`); - return 1; + process.exit(1); } } @@ -83,32 +87,40 @@ const shouldAllowWorkingChanges = process.argv.includes('--allow-working-changes ); } catch (e) { console.error(`Error on bumping manifest version for extension ${ext.name}: ${e}`); - return 1; + process.exit(1); } } /* eslint-enable no-restricted-syntax, no-await-in-loop */ // #region shared with https://github.com/paranext/paranext-extension-template/blob/main/lib/bump-versions.ts and https://github.com/paranext/paranext/blob/main/lib/bump-versions.ts + // Format the changes + try { + await execCommand(`npm run format`); + } catch (e) { + console.error(`Error on formatting changes: ${e}`); + process.exit(1); + } + // Commit the changes try { await execCommand(`git commit -a -m "Bump versions to ${newVersion}"`); } catch (e) { console.error(`Error on committing changes: ${e}`); - return 1; + process.exit(1); } // Publish the branch and push the changes try { await execCommand(`git push -u origin HEAD`); } catch (e) { console.error(`Error on publishing branch and pushing changes: ${e}`); - return 1; + process.exit(1); } console.log( `Bumped versions to ${newVersion} and pushed to branch ${branchName}. Please create a pull request to merge this branch into main.`, ); - return 0; + process.exit(0); })(); // #endregion diff --git a/lib/git.util.ts b/lib/git.util.ts index 4f600c2..a8e00e8 100644 --- a/lib/git.util.ts +++ b/lib/git.util.ts @@ -132,6 +132,8 @@ export async function checkForWorkingChanges(quiet = false) { return false; } +// #endregion + /** * Fetch latest from SINGLE_TEMPLATE_REMOTE_NAME * @@ -283,7 +285,11 @@ export async function formatExtensionFolder(extensionFolderPath: string) { console.log(`Updated module declaration and references in types file`); } catch (error) { - console.error(`Could not update types file: ${error.message}`); + if (error instanceof Error) { + console.error(`Could not update types file: ${error.message}`); + } else { + console.error(`An unknown error occurred while updating types file: ${error}`); + } } // Update README.md @@ -317,9 +323,12 @@ export async function formatExtensionFolder(extensionFolderPath: string) { const modifiedTitle = titleSection.map((line) => line.replace(/paranext-extension-template/g, extensionName), ); - const modifiedSummary = summarySection.map((line) => - line.replace(/paranext-extension-template/g, extensionName), - ); + const modifiedSummary = summarySection.map((line) => { + if (line.includes('https://github.com/paranext/paranext-extension-template/wiki')) + return line; + + return line.replace(/paranext-extension-template/g, extensionName); + }); // Reconstruct the README const finalLines = [...modifiedTitle, ...betweenTitleAndSummary, ...modifiedSummary, ...after]; @@ -327,7 +336,11 @@ export async function formatExtensionFolder(extensionFolderPath: string) { await fs.writeFile(readmePath, finalLines.join('\n'), 'utf8'); console.log(`Updated README.md: modified title and summary sections only`); } catch (error) { - console.error(`Could not update README.md: ${error.message}`); + if (error instanceof Error) { + console.error(`Could not update README.md: ${error.message}`); + } else { + console.error(`An unknown error occurred while updating README.md: ${error}`); + } } // Update manifest.json @@ -350,7 +363,11 @@ export async function formatExtensionFolder(extensionFolderPath: string) { await fs.writeFile(manifestPath, manifestContent, 'utf8'); console.log(`Updated manifest.json with ${extensionName} information`); } catch (error) { - console.error(`Could not update manifest.json: ${error.message}`); + if (error instanceof Error) { + console.error(`Could not update manifest.json: ${error.message}`); + } else { + console.error(`An unknown error occurred while updating manifest.json: ${error}`); + } } // Update package.json @@ -367,6 +384,10 @@ export async function formatExtensionFolder(extensionFolderPath: string) { await fs.writeFile(packagePath, packageContent, 'utf8'); console.log(`Updated package.json with ${extensionName} information`); } catch (error) { - console.error(`Could not update package.json: ${error.message}`); + if (error instanceof Error) { + console.error(`Could not update package.json: ${error.message}`); + } else { + console.error(`An unknown error occurred while updating package.json: ${error}`); + } } } diff --git a/src/scripture-forge/.gitattributes b/src/scripture-forge/.gitattributes new file mode 100644 index 0000000..01fa7c9 --- /dev/null +++ b/src/scripture-forge/.gitattributes @@ -0,0 +1,14 @@ +* text eol=lf +*.exe binary +*.png binary +*.jpg binary +*.jpeg binary +*.ico binary +*.icns binary +*.eot binary +*.otf binary +*.ttf binary +*.woff binary +*.woff2 binary +*.ldml binary +*.zip binary diff --git a/src/scripture-forge/.github/CODEOWNERS b/src/scripture-forge/.github/CODEOWNERS new file mode 100644 index 0000000..0b4f9a7 --- /dev/null +++ b/src/scripture-forge/.github/CODEOWNERS @@ -0,0 +1 @@ +* @tjcouch-sil @lyonsil diff --git a/src/scripture-forge/.github/actions/bump-versions-action/action.yml b/src/scripture-forge/.github/actions/bump-versions-action/action.yml new file mode 100644 index 0000000..d0be760 --- /dev/null +++ b/src/scripture-forge/.github/actions/bump-versions-action/action.yml @@ -0,0 +1,19 @@ +name: Bump Versions Action +description: | + Runs bump-versions.ts script + +inputs: + newVersion: + description: "Version to bump all the repo's versions to on a new branch (called `bump-versions-`), e.g. 0.3.0-alpha.0." + required: true + +runs: + using: 'composite' + steps: + - name: Bump repo versions + # Bump versions using the built-in git token https://github.com/actions/checkout/tree/v4/?tab=readme-ov-file#push-a-commit-using-the-built-in-token + shell: bash + run: | + git config user.name "github-actions[bot]" + git config user.email "41898282+github-actions[bot]@users.noreply.github.com" + npm run bump-versions -- ${{ inputs.newVersion }} diff --git a/src/scripture-forge/.github/assets/release-body.md b/src/scripture-forge/.github/assets/release-body.md index c92ce95..50bae47 100644 --- a/src/scripture-forge/.github/assets/release-body.md +++ b/src/scripture-forge/.github/assets/release-body.md @@ -2,7 +2,7 @@ Includes: - Extension template -Tested on Platform.Bible vY.Z.X. Expected to be compatible with at least vY.Z.x. +Tested on Platform.Bible vX.Y.Z. Expected to be compatible with at least vX.Y.\*. Install instructions: diff --git a/src/scripture-forge/.github/workflows/bump-versions.yml b/src/scripture-forge/.github/workflows/bump-versions.yml new file mode 100644 index 0000000..c151813 --- /dev/null +++ b/src/scripture-forge/.github/workflows/bump-versions.yml @@ -0,0 +1,51 @@ +name: Bump Versions +run-name: Bump versions on ${{ github.head_ref || github.ref_name }} to ${{ github.event.inputs.newVersion }} + +on: + workflow_dispatch: + inputs: + newVersion: + description: "Version to bump all the repo's versions to on a new branch (called `bump-versions-`), e.g. 0.3.0-alpha.0." + required: true + +jobs: + bump-versions: + name: Bump versions on ${{ matrix.os }} + + runs-on: ${{ matrix.os }} + + permissions: + contents: write + + strategy: + matrix: + os: [ubuntu-latest] + + steps: + - name: Output Workflow Dispatch Inputs + run: echo "${{ toJSON(github.event.inputs) }}" + + - name: Checkout git repo + uses: actions/checkout@v4 + + - name: Read package.json + id: package_json + uses: zoexx/github-action-json-file-properties@1.0.6 + with: + file_path: 'package.json' + + - name: Install Node and NPM + uses: actions/setup-node@v4 + with: + cache: npm + node-version: ${{ fromJson(steps.package_json.outputs.volta).node }} + + - name: Install packages + run: | + npm ci + + - name: Bump repo versions + if: ${{ inputs.newVersion != '' }} + uses: ./.github/actions/bump-versions-action + with: + newVersion: ${{ inputs.newVersion }} diff --git a/src/scripture-forge/.github/workflows/codeql.yml b/src/scripture-forge/.github/workflows/codeql.yml new file mode 100644 index 0000000..5a941a5 --- /dev/null +++ b/src/scripture-forge/.github/workflows/codeql.yml @@ -0,0 +1,88 @@ +name: 'CodeQL' + +on: + push: + branches: ['main', 'release-prep', 'hotfix-*'] + pull_request: + branches: ['main', 'release-prep', 'hotfix-*'] + workflow_dispatch: + +jobs: + analyze: + name: Analyze (${{ matrix.language }}) + # Runner size impacts CodeQL analysis time. To learn more, please see: + # - https://gh.io/recommended-hardware-resources-for-running-codeql + # - https://gh.io/supported-runners-and-hardware-resources + # - https://gh.io/using-larger-runners (GitHub.com only) + # Consider using larger runners or machines with greater resources for possible analysis time improvements. + runs-on: ${{ (matrix.language == 'swift' && 'macos-latest') || 'ubuntu-latest' }} + permissions: + # required for all workflows + security-events: write + + # required to fetch internal or private CodeQL packs + packages: read + + # only required for workflows in private repositories + actions: read + contents: read + + strategy: + fail-fast: false + matrix: + include: + - language: actions + build-mode: none + - language: javascript-typescript + build-mode: none + # CodeQL supports the following values keywords for 'language': 'actions', 'c-cpp', 'csharp', 'go', 'java-kotlin', 'javascript-typescript', 'python', 'ruby', 'swift' + # Use `c-cpp` to analyze code written in C, C++ or both + # Use 'java-kotlin' to analyze code written in Java, Kotlin or both + # Use 'javascript-typescript' to analyze code written in JavaScript, TypeScript or both + # To learn more about changing the languages that are analyzed or customizing the build mode for your analysis, + # see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/customizing-your-advanced-setup-for-code-scanning. + # If you are analyzing a compiled language, you can modify the 'build-mode' for that language to customize how + # your codebase is analyzed, see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/codeql-code-scanning-for-compiled-languages + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + # Add any setup steps before running the `github/codeql-action/init` action. + # This includes steps like installing compilers or runtimes (`actions/setup-node` + # or others). This is typically only required for manual builds. + # - name: Setup runtime (example) + # uses: actions/setup-example@v1 + + # Initializes the CodeQL tools for scanning. + - name: Initialize CodeQL + uses: github/codeql-action/init@v3 + with: + languages: ${{ matrix.language }} + build-mode: ${{ matrix.build-mode }} + # If you wish to specify custom queries, you can do so here or in a config file. + # By default, queries listed here will override any specified in a config file. + # Prefix the list here with "+" to use these queries and those in the config file. + + # For more details on CodeQL's query packs, refer to: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs + # queries: security-extended,security-and-quality + + # If the analyze step fails for one of the languages you are analyzing with + # "We were unable to automatically build your code", modify the matrix above + # to set the build mode to "manual" for that language. Then modify this step + # to build your code. + # â„šī¸ Command-line programs to run using the OS shell. + # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun + - if: matrix.build-mode == 'manual' + shell: bash + run: | + echo 'If you are using a "manual" build mode for one or more of the' \ + 'languages you are analyzing, replace this with the commands to build' \ + 'your code, for example:' + echo ' make bootstrap' + echo ' make release' + exit 1 + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v3 + with: + category: '/language:${{matrix.language}}' diff --git a/src/scripture-forge/.github/workflows/lint.yml b/src/scripture-forge/.github/workflows/lint.yml new file mode 100644 index 0000000..fe3cba9 --- /dev/null +++ b/src/scripture-forge/.github/workflows/lint.yml @@ -0,0 +1,53 @@ +name: Lint + +on: + push: + branches: ['main', 'release-prep', 'hotfix-*'] + pull_request: + branches: ['main', 'release-prep', 'hotfix-*'] + +permissions: + contents: read + +jobs: + lint: + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-latest] + steps: + - name: Checkout git repo + uses: actions/checkout@v4 + with: + path: extension-repo + + - name: Checkout paranext-core repo to use its sub-packages + uses: actions/checkout@v4 + with: + path: paranext-core + repository: paranext/paranext-core + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + cache: 'npm' + cache-dependency-path: | + extension-repo/package-lock.json + paranext-core/package-lock.json + node-version-file: extension-repo/package.json + + - name: Install extension dependencies + working-directory: extension-repo + run: npm ci + + - name: Install core dependencies + working-directory: paranext-core + run: npm ci --ignore-scripts + + - name: Run format checking + working-directory: extension-repo + run: npm run format:check + + - name: Run all linters + working-directory: extension-repo + run: npm run lint diff --git a/src/scripture-forge/.github/workflows/publish.yml b/src/scripture-forge/.github/workflows/publish.yml index 3106eba..d5748cf 100644 --- a/src/scripture-forge/.github/workflows/publish.yml +++ b/src/scripture-forge/.github/workflows/publish.yml @@ -102,7 +102,10 @@ jobs: omitPrereleaseDuringUpdate: true # make the new release a pre-release prerelease: true + # tag+commit creates a version tag for this release with the tag name at the commit ref + # so the GitHub Release doesn't have to create the tag and assume it is on `main` tag: v${{ inputs.version }} + commit: ${{ github.head_ref || github.ref_name }} # only update if the release is still a draft updateOnlyUnreleased: true @@ -116,11 +119,9 @@ jobs: - name: Bump repo versions if: ${{ inputs.newVersionAfterPublishing != '' }} - # Bump versions using the built-in git token https://github.com/actions/checkout/tree/v4/?tab=readme-ov-file#push-a-commit-using-the-built-in-token - run: | - git config user.name "github-actions[bot]" - git config user.email "41898282+github-actions[bot]@users.noreply.github.com" - npm run bump-versions -- ${{ inputs.newVersionAfterPublishing }} + uses: ./.github/actions/bump-versions-action + with: + newVersion: ${{ inputs.newVersionAfterPublishing }} # Enable tmate debugging of manually-triggered workflows if the input option was provided - name: Setup tmate session diff --git a/src/scripture-forge/.vscode/launch.json b/src/scripture-forge/.vscode/launch.json index fb0f3a0..2bf7f5e 100644 --- a/src/scripture-forge/.vscode/launch.json +++ b/src/scripture-forge/.vscode/launch.json @@ -44,7 +44,7 @@ "runtimeArgs": ["run", "start"], "skipFiles": ["/**"], "env": { - "MAIN_ARGS": "--inspect=5858 --remote-debugging-port=9223", + "MAIN_ARGS": "--inspect=5858 --remote-debugging-port=9223 --remote-allow-origins=http://localhost:9223", "IN_VSCODE": "true" }, "presentation": { diff --git a/src/scripture-forge/README.md b/src/scripture-forge/README.md index f47c50c..1c92e69 100644 --- a/src/scripture-forge/README.md +++ b/src/scripture-forge/README.md @@ -1,3 +1,5 @@ + + # scripture-forge Scripture Forge extension for Platform.Bible @@ -6,9 +8,11 @@ Scripture Forge extension for Platform.Bible ## Template Info -This is a Webpack project template pre-configured to build a Platform.Bible extension. It contains the bare minimum of what an extension needs. Note that the `*.web-view.*` files and the `public/assets` folder mentioned in [Summary](#summary) are not present in this template. For inspiration on what these could look like, refer to any extension that is built using this template. An example would be the [Text Collection extension](https://github.com/paranext/paranext-extension-text-collection). +This is a Webpack project template pre-configured to build a Platform.Bible extension. It includes only the bare essentials required for an extension to work. + +Note that the `*.web-view.*` files and the `assets` folder mentioned in [Summary](#summary) are **not** included in this template. For examples of what these might look like, refer to any extension that is based on either this template or the [paranext-multi-extension-template](https://github.com/paranext/paranext-multi-extension-template) — for instance, the [Text Collection extension](https://github.com/paranext/paratext-bible-extensions/tree/main/src/paratext-bible-text-collection). -There is also a [template pre-configured to build an arbitrary number of Platform.Bible extensions in one repo](https://github.com/paranext/paranext-multi-extension-template). +**Important:** Before proceding to use this template, consider whether you intend to build a single extension to be packaged and installed independently, or a set of related extensions that should be used together. If the latter, it would be better to use the [template pre-configured to build an arbitrary number of Platform.Bible extensions in one repo](https://github.com/paranext/paranext-multi-extension-template) instead of this template. ### Customize extension details @@ -27,7 +31,7 @@ To make the process of customizing from the template as smooth as possible, we r For your extension name, we recommend that you use [lowerCamelCase](https://developer.mozilla.org/en-US/docs/Glossary/Camel_case) in some contexts and [kebab-case](https://developer.mozilla.org/en-US/docs/Glossary/Kebab_case) in other contexts. We generally recommend lowerCamelCase when using the name in code (like making a new command on the PAPI, for example), and we recommend kebab-case when using the name in relation to the file system, the repository, `npm`, and the extension's `.d.ts` types module. The following instructions are written accordingly. -- At the top of this `README.md`: +- In this `README.md`: - Replace the first line `# paranext-extension-template` with `# your-extension-name` (kebab-case) - Below the first line, replace the extension description with your own description @@ -84,7 +88,7 @@ Note: if you [update this extension from the template](#to-update-this-extension ## Summary -The general file structure is as follows: +The general file structure for an extension is as follows: - `package.json` contains information about this extension's npm package. It is required for Platform.Bible to use the extension properly. It is copied into the build folder - `manifest.json` is the manifest file that defines the extension and important properties for Platform.Bible. It is copied into the build folder @@ -105,6 +109,8 @@ The general file structure is as follows: - `dist/` is a generated folder containing the built extension files - `release/` is a generated folder containing a zip of the built extension files +> See the [Extension Anatomy wiki page](https://github.com/paranext/paranext-extension-template/wiki/Extension-Anatomy) for more information about the various files that comprise an extension and their relationships to each other. + ## To install ### Install dependencies: @@ -157,9 +163,9 @@ These steps will walk you through releasing a version on GitHub and bumping the 2. Manually dispatch the Publish workflow in GitHub Actions targeting the branch you want to release from (in the previous example, this would be `my-branch`). This workflow creates a new pre-release for the version you intend to release and creates a new `bump-versions-` branch to bump the version after the release so future changes apply to a new in-progress version instead of to the already released version. This workflow has the following inputs: - - `version`: enter the version you intend to publish (e.g. 0.2.0). This is simply for verification to make sure you release the code that you intend to release. It is compared to the version in the code, and the workflow will fail if they do not match. - - `newVersionAfterPublishing`: enter the version you want to bump to after releasing (e.g. 0.3.0-alpha.0). Future changes will apply to this new version instead of to the version that was already released. Leave blank if you don't want to bump - - `bumpRef`: enter the Git ref you want to create the bump versions branch from, e.g. `main`. Leave blank if you want to use the branch selected for the workflow run. For example, if you release from a stable branch named `release-prep`, you may want to bump the version on `main` so future development work happens on the new version, then you can rebase `release-prep` onto `main` when you are ready to start preparing the next stable release. + - `version`: Enter the version you intend to publish (e.g. 0.2.0). This is simply for verification to make sure you release the code that you intend to release. It is compared to the version in the code, and the workflow will fail if they do not match. + - `newVersionAfterPublishing`: Enter the version you want to bump to after releasing (e.g. 0.3.0-alpha.0). Future changes will apply to this new version instead of to the version that was already released. Leave blank if you don't want to bump. + - `bumpRef`: Enter the Git ref you want to create the bump versions branch from, e.g. `main`. Leave blank if you want to use the branch selected for the workflow run. For example, if you release from a stable branch named `release-prep`, you may want to bump the version on `main` so future development work happens on the new version, then you can rebase `release-prep` onto `main` when you are ready to start preparing the next stable release.
[Optional] Create a new pre-release and bump versions branch manually @@ -171,9 +177,9 @@ These steps will walk you through releasing a version on GitHub and bumping the ```bash npm run package # Create a new pre-release in GitHub on tag `v` - # Copy `.github/assets/release-body.md` into the GitHub branch - # Generate changelog - # Attach contents of `release` folder + # Copy `.github/assets/release-body.md` into the release body + # Press the "Generate release notes" button in the release creation page to generate a changelog + # Attach contents of `release` folder to the release ``` Then bump versions by running the following: @@ -187,7 +193,7 @@ These steps will walk you through releasing a version on GitHub and bumping the ```bash git checkout -b bump-versions- npm version --git-tag-version false - # Change version in each extension's `manifest.json` + # Change version in the extension's `manifest.json` git commit -a -m "Bumped versions to "; git push -u origin HEAD ``` @@ -209,7 +215,7 @@ Module build failed (from ./node_modules/swc-loader/src/index.js): Error: Failed to load native binding ``` -You may have a different effective version of `@swc/core` than `paranext-core` does. Please make sure the version of `@swc/core` in your `package-lock.json` is the same as its version in [`paranext-core/package-lock.json`](https://github.com/paranext/paranext-core/blob/main/package-lock.json). If they are not the same, please fix them to be the same by running `npm i -D @swc/core ` where the version is the version of `@swc/core` installed in `paranext-core/package-lock.json` (if you would like to set the version of `@swc/core` back to what it was before in `package.json` to stay synced with the extension template, change it back manually in `package.json` and then run `npm i`). If they are already the same, you may need to try regenerating your `package-lock.json` file by deleting it and running `npm i`. +You may have a different effective version of `@swc/core` than `paranext-core` does. Please make sure the version of `@swc/core` in your `package-lock.json` is the same as its version in [`paranext-core/package-lock.json`](https://github.com/paranext/paranext-core/blob/main/package-lock.json). If they are not the same, please fix them to be the same by running `npm i -D @swc/core@` where the version is the version of `@swc/core` installed in `paranext-core/package-lock.json` (if you would like to set the version of `@swc/core` back to what it was before in `package.json` to stay synced with the extension template, change it back manually in `package.json` and then run `npm i`). If they are already the same, you may need to try regenerating your `package-lock.json` file by deleting it and running `npm i`. ## To update this extension from the template @@ -234,4 +240,4 @@ For more information, read [the instructions on the wiki](https://github.com/par ## Special features in this project -This project has special features and specific configuration to make building an extension for Platform.Bible easier. See [Special features of `paranext-multi-extension-template`](https://github.com/paranext/paranext-multi-extension-template#special-features-of-the-template) for information on these special features. +This project has special features and specific configuration to make building an extension for Platform.Bible easier. Rather than duplicating the full explanation here, please refer to the [`Special Features in this project` section of the multi-extension template README](https://github.com/paranext/paranext-multi-extension-template?tab=readme-ov-file#special-features-in-this-project) for details on these features. diff --git a/src/scripture-forge/contributions/themes.json b/src/scripture-forge/contributions/themes.json new file mode 100644 index 0000000..0967ef4 --- /dev/null +++ b/src/scripture-forge/contributions/themes.json @@ -0,0 +1 @@ +{} diff --git a/src/scripture-forge/lib/bump-versions.ts b/src/scripture-forge/lib/bump-versions.ts index 1935c0f..6b62114 100644 --- a/src/scripture-forge/lib/bump-versions.ts +++ b/src/scripture-forge/lib/bump-versions.ts @@ -1,7 +1,7 @@ import fs from 'fs'; import { checkForWorkingChanges, execCommand } from './git.util'; -// #region shared with https://github.com/paranext/paranext-multi-extension-template/blob/main/lib/bump-versions.ts and https://github.com/paranext/paranext/blob/main/lib/bump-versions.ts +// #region shared with https://github.com/paranext/paranext-multi-extension-template/blob/main/lib/bump-versions.ts // This script checks out a new branch, bumps the versions of all extensions in the repo, // and then commits the changes. It is generally expected that you will be on `main` when you run @@ -14,9 +14,13 @@ import { checkForWorkingChanges, execCommand } from './git.util'; const newVersion = process.argv[2]; const shouldAllowWorkingChanges = process.argv.includes('--allow-working-changes'); +// #endregion + +// #region shared with https://github.com/paranext/paranext-extension-template/blob/main/lib/bump-versions.ts and https://github.com/paranext/paranext/blob/main/lib/bump-versions.ts + (async () => { // Make sure there are not working changes so we don't interfere with normal edits - if (!shouldAllowWorkingChanges && (await checkForWorkingChanges())) return 1; + if (!shouldAllowWorkingChanges && (await checkForWorkingChanges())) process.exit(1); const branchName = `bump-versions-${newVersion}`; @@ -25,7 +29,7 @@ const shouldAllowWorkingChanges = process.argv.includes('--allow-working-changes await execCommand(`git checkout -b ${branchName}`); } catch (e) { console.error(`Error on git checkout: ${e}`); - return 1; + process.exit(1); } const bumpVersionCommand = `npm version ${newVersion} --git-tag-version false`; @@ -35,7 +39,7 @@ const shouldAllowWorkingChanges = process.argv.includes('--allow-working-changes await execCommand(bumpVersionCommand); } catch (e) { console.error(`Error on bumping version: ${e}`); - return 1; + process.exit(1); } // #endregion @@ -53,30 +57,38 @@ const shouldAllowWorkingChanges = process.argv.includes('--allow-working-changes ); } catch (e) { console.error(`Error on bumping manifest version: ${e}`); - return 1; + process.exit(1); } // #region shared with https://github.com/paranext/paranext-multi-extension-template/blob/main/lib/bump-versions.ts and https://github.com/paranext/paranext/blob/main/lib/bump-versions.ts + // Format the changes + try { + await execCommand(`npm run format`); + } catch (e) { + console.error(`Error on formatting changes: ${e}`); + process.exit(1); + } + // Commit the changes try { await execCommand(`git commit -a -m "Bump versions to ${newVersion}"`); } catch (e) { console.error(`Error on committing changes: ${e}`); - return 1; + process.exit(1); } // Publish the branch and push the changes try { await execCommand(`git push -u origin HEAD`); } catch (e) { console.error(`Error on publishing branch and pushing changes: ${e}`); - return 1; + process.exit(1); } console.log( `Bumped versions to ${newVersion} and pushed to branch ${branchName}. Please create a pull request to merge this branch into main.`, ); - return 0; + process.exit(0); })(); // #endregion diff --git a/src/scripture-forge/manifest.json b/src/scripture-forge/manifest.json index e25652a..0526f33 100644 --- a/src/scripture-forge/manifest.json +++ b/src/scripture-forge/manifest.json @@ -13,5 +13,6 @@ "settings": "contributions/settings.json", "projectSettings": "contributions/projectSettings.json", "localizedStrings": "contributions/localizedStrings.json", + "themes": "contributions/themes.json", "activationEvents": [] } diff --git a/src/scripture-forge/package-lock.json b/src/scripture-forge/package-lock.json index c4b64b2..4908938 100644 --- a/src/scripture-forge/package-lock.json +++ b/src/scripture-forge/package-lock.json @@ -78,8 +78,9 @@ "platform-bible-utils": "file:../platform-bible-utils" }, "devDependencies": { + "electron-log": "^5.0.3", "escape-string-regexp": "^5.0.0", - "typescript": "^5.4.5" + "typescript": "^5.8.3" } }, "../paranext-core/lib/papi-dts/node_modules/escape-string-regexp": { @@ -114,27 +115,27 @@ "dev": true, "license": "MIT", "dependencies": { - "@emotion/react": ">=11.11.4", - "@emotion/styled": ">=11.11.0", - "@mui/material": ">=5.15.10", - "@radix-ui/react-checkbox": "^1.1.4", - "@radix-ui/react-dialog": "^1.1.6", - "@radix-ui/react-dropdown-menu": "^2.1.6", - "@radix-ui/react-label": "^2.1.2", - "@radix-ui/react-menubar": "^1.1.6", - "@radix-ui/react-popover": "^1.1.6", - "@radix-ui/react-radio-group": "^1.2.3", - "@radix-ui/react-select": "^2.1.6", - "@radix-ui/react-separator": "^1.1.2", - "@radix-ui/react-slider": "^1.2.3", - "@radix-ui/react-slot": "^1.1.2", - "@radix-ui/react-switch": "^1.1.3", - "@radix-ui/react-tabs": "^1.1.3", - "@radix-ui/react-toast": "^1.2.6", - "@radix-ui/react-toggle": "^1.1.2", - "@radix-ui/react-toggle-group": "^1.1.2", - "@radix-ui/react-tooltip": "^1.1.8", - "@tanstack/react-table": "^8.20.5", + "@radix-ui/react-avatar": "^1.1.9", + "@radix-ui/react-checkbox": "^1.3.1", + "@radix-ui/react-dialog": "^1.1.14", + "@radix-ui/react-dropdown-menu": "^2.1.14", + "@radix-ui/react-label": "^2.1.6", + "@radix-ui/react-menubar": "^1.1.14", + "@radix-ui/react-popover": "^1.1.13", + "@radix-ui/react-progress": "^1.1.7", + "@radix-ui/react-radio-group": "^1.3.6", + "@radix-ui/react-select": "^2.2.4", + "@radix-ui/react-separator": "^1.1.6", + "@radix-ui/react-slider": "^1.3.4", + "@radix-ui/react-slot": "^1.2.2", + "@radix-ui/react-switch": "^1.2.4", + "@radix-ui/react-tabs": "^1.1.11", + "@radix-ui/react-toast": "^1.2.13", + "@radix-ui/react-toggle": "^1.1.8", + "@radix-ui/react-toggle-group": "^1.1.9", + "@radix-ui/react-tooltip": "^1.2.6", + "@tailwindcss/container-queries": "^0.1.1", + "@tanstack/react-table": "^8.21.3", "autoprefixer": "^10.4.20", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", @@ -143,16 +144,21 @@ "markdown-to-jsx": "^7.7.4", "next-themes": "^0.4.4", "platform-bible-utils": "file:../platform-bible-utils", + "react-hotkeys-hook": "^4.6.1", "sonner": "^1.7.4", "tailwind-merge": "^2.6.0", - "tailwindcss-animate": "^1.0.7" + "tailwindcss-animate": "^1.0.7", + "vaul": "^1.1.2" }, "devDependencies": { "@babel/preset-env": "^7.26.9", "@babel/preset-react": "^7.26.3", "@babel/preset-typescript": "^7.26.0", - "@mui/icons-material": "^5.15.10", + "@chromatic-com/storybook": "^4.0.0", "@senojs/rollup-plugin-style-inject": "^0.2.3", + "@storybook/addon-a11y": "^9.0.6", + "@storybook/addon-links": "^9.0.6", + "@storybook/react-vite": "^9.0.6", "@tailwindcss/typography": "^0.5.16", "@testing-library/dom": "^10.4.0", "@testing-library/jest-dom": "^6.6.3", @@ -164,14 +170,21 @@ "@typescript-eslint/eslint-plugin": "^6.21.0", "@typescript-eslint/parser": "^6.21.0", "@vitejs/plugin-react-swc": "^3.8.0", + "axe-playwright": "^2.1.0", "dts-bundle-generator": "^9.5.1", "eslint": "^8.57.1", "eslint-config-prettier": "^9.1.0", "eslint-plugin-prettier": "^5.2.3", + "eslint-plugin-storybook": "^9.0.6", "jsonpath-plus": "^10.3.0", "prettier": "^3.5.2", "prettier-plugin-jsdoc": "^1.3.2", "prettier-plugin-tailwindcss": "^0.6.11", + "remark-cli": "^12.0.1", + "remark-gfm": "^4.0.1", + "remark-mdx": "^3.1.0", + "storybook": "^9.0.5", + "storybook-addon-rtl": "^2.0.0", "stylelint": "^16.11.0", "stylelint-config-recommended": "^14.0.1", "stylelint-config-sass-guidelines": "^12.1.0", @@ -179,9 +192,9 @@ "tailwindcss": "^3.4.17", "tailwindcss-scoped-preflight": "^2.2.4", "tslib": "^2.8.1", - "typedoc": "^0.27.9", - "typescript": "^5.4.5", - "vite": "^6.2.0", + "typedoc": "^0.28.2", + "typescript": "^5.8.3", + "vite": "^6.3.4", "vite-tsconfig-paths": "^5.1.4", "vitest": "^3.0.7" }, @@ -198,7 +211,7 @@ "jsonpath-plus": "^10.3.0" }, "devDependencies": { - "@biblionexus-foundation/scripture-utilities": "^0.0.7", + "@biblionexus-foundation/scripture-utilities": "~0.1.0", "@types/jest": "^29.5.14", "@typescript-eslint/eslint-plugin": "^6.21.0", "@typescript-eslint/parser": "^6.21.0", @@ -211,9 +224,9 @@ "prettier-plugin-jsdoc": "^1.3.2", "stringz": "^2.1.0", "tslib": "^2.8.1", - "typedoc": "^0.27.9", - "typescript": "^5.4.5", - "vite": "^6.2.0", + "typedoc": "^0.28.3", + "typescript": "^5.8.3", + "vite": "^6.3.4", "vitest": "^3.0.7" } }, @@ -4286,9 +4299,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001666", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001666.tgz", - "integrity": "sha512-gD14ICmoV5ZZM1OdzPWmpx+q4GyefaK06zi8hmfHV5xe4/2nOQX3+Dw5o+fSqOws2xVwL9j+anOPFwHzdEdV4g==", + "version": "1.0.30001731", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001731.tgz", + "integrity": "sha512-lDdp2/wrOmTRWuoB5DpfNkC0rJDU8DqRa6nYL6HK6sytw70QMopt/NIc/9SM7ylItlBWfACXk0tEn37UWM/+mg==", "dev": true, "funding": [ { @@ -4303,7 +4316,8 @@ "type": "github", "url": "https://github.com/sponsors/ai" } - ] + ], + "license": "CC-BY-4.0" }, "node_modules/chalk": { "version": "2.4.2", @@ -18044,9 +18058,9 @@ "dev": true }, "caniuse-lite": { - "version": "1.0.30001666", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001666.tgz", - "integrity": "sha512-gD14ICmoV5ZZM1OdzPWmpx+q4GyefaK06zi8hmfHV5xe4/2nOQX3+Dw5o+fSqOws2xVwL9j+anOPFwHzdEdV4g==", + "version": "1.0.30001731", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001731.tgz", + "integrity": "sha512-lDdp2/wrOmTRWuoB5DpfNkC0rJDU8DqRa6nYL6HK6sytw70QMopt/NIc/9SM7ylItlBWfACXk0tEn37UWM/+mg==", "dev": true }, "chalk": { @@ -22953,9 +22967,10 @@ "papi-dts": { "version": "file:../paranext-core/lib/papi-dts", "requires": { + "electron-log": "^5.0.3", "escape-string-regexp": "^5.0.0", "platform-bible-utils": "file:../platform-bible-utils", - "typescript": "^5.4.5" + "typescript": "^5.8.3" }, "dependencies": { "escape-string-regexp": { @@ -22965,7 +22980,7 @@ "platform-bible-utils": { "version": "file:../paranext-core/lib/platform-bible-utils", "requires": { - "@biblionexus-foundation/scripture-utilities": "^0.0.7", + "@biblionexus-foundation/scripture-utilities": "~0.1.0", "@types/jest": "^29.5.14", "@typescript-eslint/eslint-plugin": "^6.21.0", "@typescript-eslint/parser": "^6.21.0", @@ -22980,9 +22995,9 @@ "prettier-plugin-jsdoc": "^1.3.2", "stringz": "^2.1.0", "tslib": "^2.8.1", - "typedoc": "^0.27.9", - "typescript": "^5.4.5", - "vite": "^6.2.0", + "typedoc": "^0.28.3", + "typescript": "^5.8.3", + "vite": "^6.3.4", "vitest": "^3.0.7" } }, @@ -23115,30 +23130,33 @@ "@babel/preset-env": "^7.26.9", "@babel/preset-react": "^7.26.3", "@babel/preset-typescript": "^7.26.0", - "@emotion/react": ">=11.11.4", - "@emotion/styled": ">=11.11.0", - "@mui/icons-material": "^5.15.10", - "@mui/material": ">=5.15.10", - "@radix-ui/react-checkbox": "^1.1.4", - "@radix-ui/react-dialog": "^1.1.6", - "@radix-ui/react-dropdown-menu": "^2.1.6", - "@radix-ui/react-label": "^2.1.2", - "@radix-ui/react-menubar": "^1.1.6", - "@radix-ui/react-popover": "^1.1.6", - "@radix-ui/react-radio-group": "^1.2.3", - "@radix-ui/react-select": "^2.1.6", - "@radix-ui/react-separator": "^1.1.2", - "@radix-ui/react-slider": "^1.2.3", - "@radix-ui/react-slot": "^1.1.2", - "@radix-ui/react-switch": "^1.1.3", - "@radix-ui/react-tabs": "^1.1.3", - "@radix-ui/react-toast": "^1.2.6", - "@radix-ui/react-toggle": "^1.1.2", - "@radix-ui/react-toggle-group": "^1.1.2", - "@radix-ui/react-tooltip": "^1.1.8", + "@chromatic-com/storybook": "^4.0.0", + "@radix-ui/react-avatar": "^1.1.9", + "@radix-ui/react-checkbox": "^1.3.1", + "@radix-ui/react-dialog": "^1.1.14", + "@radix-ui/react-dropdown-menu": "^2.1.14", + "@radix-ui/react-label": "^2.1.6", + "@radix-ui/react-menubar": "^1.1.14", + "@radix-ui/react-popover": "^1.1.13", + "@radix-ui/react-progress": "^1.1.7", + "@radix-ui/react-radio-group": "^1.3.6", + "@radix-ui/react-select": "^2.2.4", + "@radix-ui/react-separator": "^1.1.6", + "@radix-ui/react-slider": "^1.3.4", + "@radix-ui/react-slot": "^1.2.2", + "@radix-ui/react-switch": "^1.2.4", + "@radix-ui/react-tabs": "^1.1.11", + "@radix-ui/react-toast": "^1.2.13", + "@radix-ui/react-toggle": "^1.1.8", + "@radix-ui/react-toggle-group": "^1.1.9", + "@radix-ui/react-tooltip": "^1.2.6", "@senojs/rollup-plugin-style-inject": "^0.2.3", + "@storybook/addon-a11y": "^9.0.6", + "@storybook/addon-links": "^9.0.6", + "@storybook/react-vite": "^9.0.6", + "@tailwindcss/container-queries": "^0.1.1", "@tailwindcss/typography": "^0.5.16", - "@tanstack/react-table": "^8.20.5", + "@tanstack/react-table": "^8.21.3", "@testing-library/dom": "^10.4.0", "@testing-library/jest-dom": "^6.6.3", "@testing-library/react": "^16.2.0", @@ -23150,6 +23168,7 @@ "@typescript-eslint/parser": "^6.21.0", "@vitejs/plugin-react-swc": "^3.8.0", "autoprefixer": "^10.4.20", + "axe-playwright": "^2.1.0", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", "cmdk": "^1.0.4", @@ -23157,6 +23176,7 @@ "eslint": "^8.57.1", "eslint-config-prettier": "^9.1.0", "eslint-plugin-prettier": "^5.2.3", + "eslint-plugin-storybook": "^9.0.6", "jsonpath-plus": "^10.3.0", "lucide-react": "^0.475.0", "markdown-to-jsx": "^7.7.4", @@ -23165,7 +23185,13 @@ "prettier": "^3.5.2", "prettier-plugin-jsdoc": "^1.3.2", "prettier-plugin-tailwindcss": "^0.6.11", + "react-hotkeys-hook": "^4.6.1", + "remark-cli": "^12.0.1", + "remark-gfm": "^4.0.1", + "remark-mdx": "^3.1.0", "sonner": "^1.7.4", + "storybook": "^9.0.5", + "storybook-addon-rtl": "^2.0.0", "stylelint": "^16.11.0", "stylelint-config-recommended": "^14.0.1", "stylelint-config-sass-guidelines": "^12.1.0", @@ -23175,9 +23201,10 @@ "tailwindcss-animate": "^1.0.7", "tailwindcss-scoped-preflight": "^2.2.4", "tslib": "^2.8.1", - "typedoc": "^0.27.9", - "typescript": "^5.4.5", - "vite": "^6.2.0", + "typedoc": "^0.28.2", + "typescript": "^5.8.3", + "vaul": "^1.1.2", + "vite": "^6.3.4", "vite-tsconfig-paths": "^5.1.4", "vitest": "^3.0.7" } @@ -23185,7 +23212,7 @@ "platform-bible-utils": { "version": "file:../paranext-core/lib/platform-bible-utils", "requires": { - "@biblionexus-foundation/scripture-utilities": "^0.0.7", + "@biblionexus-foundation/scripture-utilities": "~0.1.0", "@types/jest": "^29.5.14", "@typescript-eslint/eslint-plugin": "^6.21.0", "@typescript-eslint/parser": "^6.21.0", @@ -23200,9 +23227,9 @@ "prettier-plugin-jsdoc": "^1.3.2", "stringz": "^2.1.0", "tslib": "^2.8.1", - "typedoc": "^0.27.9", - "typescript": "^5.4.5", - "vite": "^6.2.0", + "typedoc": "^0.28.3", + "typescript": "^5.8.3", + "vite": "^6.3.4", "vitest": "^3.0.7" } }, diff --git a/src/scripture-forge/package.json b/src/scripture-forge/package.json index 0876d0b..85d6442 100644 --- a/src/scripture-forge/package.json +++ b/src/scripture-forge/package.json @@ -22,8 +22,8 @@ "start": "cross-env MAIN_ARGS=\"--extensions $INIT_CWD/dist\" concurrently \"npm:watch\" \"npm:start:core\"", "start:production": "cross-env MAIN_ARGS=\"--extensions $INIT_CWD/dist\" concurrently \"npm:watch:production\" \"npm:start:core\"", "lint": "npm run lint:scripts && npm run lint:styles", - "lint:scripts": "eslint --ext .cjs,.js,.jsx,.ts,.tsx --cache .", - "lint:styles": "stylelint **/*.{css,scss}", + "lint:scripts": "cross-env NODE_ENV=development eslint --ext .cjs,.js,.jsx,.ts,.tsx --cache .", + "lint:styles": "stylelint **/*.{css,scss} --allow-empty-input", "lint-fix": "npm run lint-fix:scripts && npm run lint:styles -- --fix", "lint-fix:scripts": "npm run format && npm run lint:scripts", "bump-versions": "ts-node ./lib/bump-versions.ts" diff --git a/src/scripture-forge/src/main.ts b/src/scripture-forge/src/main.ts index a39b124..94cd652 100644 --- a/src/scripture-forge/src/main.ts +++ b/src/scripture-forge/src/main.ts @@ -37,7 +37,7 @@ const homeWebViewProvider: IWebViewProviderWithType = { }; export async function activate(context: ExecutionActivationContext) { - logger.info('Scripture Forge Extension is activating!'); + logger.debug('Scripture Forge Extension is activating!'); const homeWebViewProviderPromise = papi.webViewProviders.registerWebViewProvider( homeWebViewProvider.webViewType, @@ -269,6 +269,6 @@ export async function activate(context: ExecutionActivationContext) { } export async function deactivate() { - logger.info('Scripture Forge Extension is deactivating!'); + logger.debug('Scripture Forge Extension is deactivating!'); return true; } diff --git a/src/scripture-forge/tailwind.config.ts b/src/scripture-forge/tailwind.config.ts index d9c586c..34e608b 100644 --- a/src/scripture-forge/tailwind.config.ts +++ b/src/scripture-forge/tailwind.config.ts @@ -76,6 +76,28 @@ const config: Config = { 'accordion-down': 'accordion-down 0.2s ease-out', 'accordion-up': 'accordion-up 0.2s ease-out', }, + typography: { + DEFAULT: { + css: { + '--tw-prose-body': 'hsl(var(--foreground))', + '--tw-prose-headings': 'hsl(var(--foreground))', + '--tw-prose-lead': 'hsl(var(--muted-foreground))', + '--tw-prose-links': 'hsl(var(--primary))', + '--tw-prose-bold': 'hsl(var(--foreground))', + '--tw-prose-counters': 'hsl(var(--muted-foreground))', + '--tw-prose-bullets': 'hsl(var(--muted-foreground))', + '--tw-prose-hr': 'hsl(var(--border))', + '--tw-prose-quotes': 'hsl(var(--foreground))', + '--tw-prose-quote-borders': 'hsl(var(--border))', + '--tw-prose-captions': 'hsl(var(--muted-foreground))', + '--tw-prose-code': 'hsl(var(--foreground))', + '--tw-prose-pre-code': 'hsl(var(--muted-foreground))', + '--tw-prose-pre-bg': 'hsl(var(--muted))', + '--tw-prose-th-borders': 'hsl(var(--border))', + '--tw-prose-td-borders': 'hsl(var(--border))', + }, + }, + }, }, }, plugins: [ diff --git a/src/scripture-forge/webpack.config.ts b/src/scripture-forge/webpack.config.ts index 64f3284..9810e64 100644 --- a/src/scripture-forge/webpack.config.ts +++ b/src/scripture-forge/webpack.config.ts @@ -7,7 +7,7 @@ import configMain from './webpack/webpack.config.main'; // Note: Using a .ts file as the webpack config requires not having "type": "module" in package.json // https://stackoverflow.com/a/76005614 -// We want to build web views and then build main +// We want to build WebViews and then build main const config: webpack.Configuration[] = [configWebView, configMain]; export default config; diff --git a/src/scripture-forge/webpack/web-view-resolve-webpack-plugin.ts b/src/scripture-forge/webpack/web-view-resolve-webpack-plugin.ts index ad28003..ea04e51 100644 --- a/src/scripture-forge/webpack/web-view-resolve-webpack-plugin.ts +++ b/src/scripture-forge/webpack/web-view-resolve-webpack-plugin.ts @@ -87,7 +87,7 @@ export default class WebViewResolveWebpackPlugin { } } - // If it isn't calling for a webView, continue resolving without changing anything here + // If it isn't calling for a WebView, continue resolving without changing anything here if (!webViewTsxRegex.test(requestPath)) return callback(); // Get the path to the relevant file in the temp dir diff --git a/src/scripture-forge/webpack/webpack.config.base.ts b/src/scripture-forge/webpack/webpack.config.base.ts index 9a34325..3c2b8fb 100644 --- a/src/scripture-forge/webpack/webpack.config.base.ts +++ b/src/scripture-forge/webpack/webpack.config.base.ts @@ -11,15 +11,15 @@ const shouldGenerateSourceMaps = isDev || process.env.DEBUG_PROD; /** The base directory from which webpack should operate (should be the root repo folder) */ export const rootDir = path.resolve(__dirname, '..'); -// Note: we do not want to do any chunking because neither webViews nor main can import dependencies -// other than those listed in configBase.externals. Each webView must contain all its dependency +// Note: we do not want to do any chunking because neither WebViews nor main can import dependencies +// other than those listed in configBase.externals. Each WebView must contain all its dependency // code, and main must contain all its dependency code. -/** Webpack configuration shared by webView building and main building */ +/** Webpack configuration shared by WebView building and main building */ const configBase: webpack.Configuration = { // The operating directory for webpack instead of current working directory context: rootDir, mode: isDev ? 'development' : 'production', - // Bundle the sourcemap into the file since webviews are injected as strings into the main file + // Bundle the sourcemap into the file since WebViews are injected as strings into the main file devtool: shouldGenerateSourceMaps ? 'inline-source-map' : false, watchOptions: { ignored: ['**/node_modules'], @@ -58,7 +58,9 @@ const configBase: webpack.Configuration = { // This must be the first rule in order to be applied after all other transformations // https://webpack.js.org/guides/asset-modules/#replacing-inline-loader-syntax { - resourceQuery: /inline/, + resourceQuery: { + and: [/inline/, { not: [/raw/] }], + }, type: 'asset/source', }, // Load TypeScript with SWC https://swc.rs/docs/usage/swc-loader @@ -66,6 +68,7 @@ const configBase: webpack.Configuration = { // https://github.com/TypeStrong/ts-loader#options { test: /\.tsx?$/, + resourceQuery: { not: [/raw/] }, use: { loader: 'swc-loader', options: { @@ -88,6 +91,7 @@ const configBase: webpack.Configuration = { // https://webpack.js.org/loaders/sass-loader/#getting-started { test: /\.(sa|sc|c)ss$/, + resourceQuery: { not: [/raw/] }, use: [ // We are not using style-loader since we are passing styles to papi, not inserting them // into dom. style-loader would add html style elements for our styles if we used it @@ -107,6 +111,7 @@ const configBase: webpack.Configuration = { // https://webpack.js.org/guides/asset-management/#loading-images { test: /\.(png|svg|jpg|jpeg|gif)$/i, + resourceQuery: { not: [/raw/] }, type: 'asset/inline', }, /** @@ -117,6 +122,7 @@ const configBase: webpack.Configuration = { // https://webpack.js.org/guides/asset-management/#loading-fonts { test: /\.(woff|woff2|eot|ttf|otf)$/i, + resourceQuery: { not: [/raw/] }, type: 'asset/inline', }, /** Import files with no transformation as strings with "./file?raw" */ diff --git a/src/scripture-forge/webpack/webpack.config.main.ts b/src/scripture-forge/webpack/webpack.config.main.ts index da76ed1..d3a0440 100644 --- a/src/scripture-forge/webpack/webpack.config.main.ts +++ b/src/scripture-forge/webpack/webpack.config.main.ts @@ -21,11 +21,11 @@ const configMain: webpack.Configuration = merge(configBase, { target: 'web', // configuration name name: 'main', - // wait until webView bundling finishes - webpack.config.web-view.ts + // Wait until WebView bundling finishes - webpack.config.web-view.ts dependencies: ['webView'], // Instructions on what output to create output: { - // extension output directory + // Extension output directory path: path.resolve(rootDir, outputFolder), // Exporting the library https://webpack.js.org/guides/author-libraries/#expose-the-library library: { @@ -39,7 +39,7 @@ const configMain: webpack.Configuration = merge(configBase, { }, resolve: { plugins: [ - // Get web view files from the temp dir where they are built + // Get WebView files from the temp dir where they are built new WebViewResolveWebpackPlugin(), ], }, diff --git a/src/scripture-forge/webpack/webpack.config.web-view.ts b/src/scripture-forge/webpack/webpack.config.web-view.ts index 4fe4aa9..cc2c6aa 100644 --- a/src/scripture-forge/webpack/webpack.config.web-view.ts +++ b/src/scripture-forge/webpack/webpack.config.web-view.ts @@ -5,7 +5,7 @@ import merge from 'webpack-merge'; import configBase, { rootDir } from './webpack.config.base'; import { getWebViewEntries } from './webpack.util'; -/** Webpack configuration for building webViews */ +/** Webpack configuration for building WebViews */ const configWebView: webpack.Configuration = merge(configBase, { // Build for web since Platform.Bible loads WebViews in browser. Platform.Bible provides specific // modules that extensions may import as listed in `webpack.config.base`'s `externals`. Read more at @@ -14,12 +14,12 @@ const configWebView: webpack.Configuration = merge(configBase, { // documented at https://webpack.js.org/configuration/resolve/#resolvefallback // https://webpack.js.org/concepts/targets/ target: 'web', - // configuration name so we can depend on it in main + // Configuration name so we can depend on it in main name: 'webView', - // instructions to build each extension webview source file + // Instructions to build each extension WebView source file entry: getWebViewEntries, output: { - // Build all the web views in the folders where they are with the temp dir appended + // Build all the WebViews in the folders where they are with the temp dir appended path: rootDir, }, }); diff --git a/src/scripture-forge/webpack/webpack.util.ts b/src/scripture-forge/webpack/webpack.util.ts index ea78e4a..ce0243b 100644 --- a/src/scripture-forge/webpack/webpack.util.ts +++ b/src/scripture-forge/webpack/webpack.util.ts @@ -5,16 +5,16 @@ import { glob } from 'glob'; // #region shared with https://github.com/paranext/paranext-multi-extension-template/blob/main/webpack/webpack.util.ts /** - * String of what a web view needs to have in its name before the file extension to be considered a - * web-view + * String of what a WebView needs to have in its name before the file extension to be considered a + * WebView * - * Web Views should be named .web-view. + * WebViews should be named .web-view. */ const webViewTag = '.web-view'; -/** Glob filename matcher for React web views. React Web Views should be named .web-view.tsx */ +/** Glob filename matcher for React WebViews. React WebViews should be named .web-view.tsx */ const webViewTsxGlob = '**/*.web-view.tsx'; /** - * Regex file name matcher for React web views. React Web Views should be named .web-view.tsx + * Regex file name matcher for React WebViews. React WebViews should be named .web-view.tsx * * Note: this regex allows the extension to be optional. */ @@ -43,7 +43,7 @@ function getWebViewTsxPaths() { /** * Gets the bundled WebView path for a WebView file path * - * @param webViewPath Relative path to webView e.g. './src/extension-template.web-view.tsx' + * @param webViewPath Relative path to WebView e.g. './src/extension-template.web-view.tsx' * @param join Function to use to join the paths together * @returns WebView path with temporary WebView directory inserted into the module path */ @@ -53,7 +53,7 @@ export function getWebViewTempPath( ) { const webViewInfo = path.parse(webViewPath); - // If the web view doesn't have a file extension, parsing makes it think the extension is + // If the WebView doesn't have a file extension, parsing makes it think the extension is // '.web-view', so we need to add it back const webViewName = webViewInfo.ext === webViewTag ? webViewInfo.base : webViewInfo.name; // Put transpiled WebViews in a temp folder in the same directory as the original WebView @@ -65,10 +65,10 @@ export function getWebViewTempPath( } /** - * Get webpack entry configuration to build each web-view source file and put it in a temporary + * Get webpack entry configuration to build each WebView source file and put it in a temporary * folder in the same directory * - * @returns Promise that resolves to the webView entry config + * @returns Promise that resolves to the WebView entry config */ export async function getWebViewEntries(): Promise { const tsxWebViews = await getWebViewTsxPaths(); diff --git a/tailwind.config.ts b/tailwind.config.ts index f379da3..c65681f 100644 --- a/tailwind.config.ts +++ b/tailwind.config.ts @@ -76,6 +76,28 @@ const config: Config = { 'accordion-down': 'accordion-down 0.2s ease-out', 'accordion-up': 'accordion-up 0.2s ease-out', }, + typography: { + DEFAULT: { + css: { + '--tw-prose-body': 'hsl(var(--foreground))', + '--tw-prose-headings': 'hsl(var(--foreground))', + '--tw-prose-lead': 'hsl(var(--muted-foreground))', + '--tw-prose-links': 'hsl(var(--primary))', + '--tw-prose-bold': 'hsl(var(--foreground))', + '--tw-prose-counters': 'hsl(var(--muted-foreground))', + '--tw-prose-bullets': 'hsl(var(--muted-foreground))', + '--tw-prose-hr': 'hsl(var(--border))', + '--tw-prose-quotes': 'hsl(var(--foreground))', + '--tw-prose-quote-borders': 'hsl(var(--border))', + '--tw-prose-captions': 'hsl(var(--muted-foreground))', + '--tw-prose-code': 'hsl(var(--foreground))', + '--tw-prose-pre-code': 'hsl(var(--muted-foreground))', + '--tw-prose-pre-bg': 'hsl(var(--muted))', + '--tw-prose-th-borders': 'hsl(var(--border))', + '--tw-prose-td-borders': 'hsl(var(--border))', + }, + }, + }, }, }, plugins: [ diff --git a/webpack.config.ts b/webpack.config.ts index 815804c..7efa067 100644 --- a/webpack.config.ts +++ b/webpack.config.ts @@ -7,7 +7,7 @@ import configMain from './webpack/webpack.config.main'; // Note: Using a .ts file as the webpack config requires not having "type": "module" in package.json // https://stackoverflow.com/a/76005614 -// We want to build web views and then build main +// We want to build WebViews and then build main const config: (webpack.Configuration | (() => Promise))[] = [ configWebView, configMain, diff --git a/webpack/web-view-resolve-webpack-plugin.ts b/webpack/web-view-resolve-webpack-plugin.ts index c9aa94e..b34e839 100644 --- a/webpack/web-view-resolve-webpack-plugin.ts +++ b/webpack/web-view-resolve-webpack-plugin.ts @@ -87,7 +87,7 @@ export default class WebViewResolveWebpackPlugin { } } - // If it isn't calling for a webView, continue resolving without changing anything here + // If it isn't calling for a WebView, continue resolving without changing anything here if (!webViewTsxRegex.test(requestPath)) return callback(); // Get the path to the relevant file in the temp dir diff --git a/webpack/webpack.config.base.ts b/webpack/webpack.config.base.ts index 2c1e0cc..0b913f4 100644 --- a/webpack/webpack.config.base.ts +++ b/webpack/webpack.config.base.ts @@ -22,15 +22,15 @@ const shouldGenerateSourceMaps = isDev || process.env.DEBUG_PROD; /** The base directory from which webpack should operate (should be the root repo folder) */ export const rootDir = path.resolve(__dirname, '..'); -// Note: we do not want to do any chunking because neither webViews nor main can import dependencies -// other than those listed in configBase.externals. Each webView must contain all its dependency +// Note: we do not want to do any chunking because neither WebViews nor main can import dependencies +// other than those listed in configBase.externals. Each WebView must contain all its dependency // code, and main must contain all its dependency code. -/** Webpack configuration shared by webView building and main building */ +/** Webpack configuration shared by WebView building and main building */ const configBase: webpack.Configuration = { // The operating directory for webpack instead of current working directory context: rootDir, mode: isDev ? 'development' : 'production', - // Bundle the sourcemap into the file since webviews are injected as strings into the main file + // Bundle the sourcemap into the file since WebViews are injected as strings into the main file devtool: shouldGenerateSourceMaps ? 'inline-source-map' : false, watchOptions: { ignored: ['**/node_modules'], diff --git a/webpack/webpack.config.main.ts b/webpack/webpack.config.main.ts index 3441624..9aebe77 100644 --- a/webpack/webpack.config.main.ts +++ b/webpack/webpack.config.main.ts @@ -30,11 +30,11 @@ const configMain: () => Promise = async () => { target: 'web', // configuration name name: 'main', - // wait until webView bundling finishes - webpack.config.web-view.ts + // Wait until WebView bundling finishes - webpack.config.web-view.ts dependencies: ['webView'], // Instructions on what output to create output: { - // extension output directory + // Extension output directory path: path.resolve(rootDir, outputFolder), // Exporting the library https://webpack.js.org/guides/author-libraries/#expose-the-library library: { @@ -48,7 +48,7 @@ const configMain: () => Promise = async () => { }, resolve: { plugins: [ - // Get web view files from the temp dir where they are built + // Get WebView files from the temp dir where they are built new WebViewResolveWebpackPlugin(), ], }, diff --git a/webpack/webpack.config.web-view.ts b/webpack/webpack.config.web-view.ts index 03eefa4..79692d7 100644 --- a/webpack/webpack.config.web-view.ts +++ b/webpack/webpack.config.web-view.ts @@ -5,7 +5,7 @@ import merge from 'webpack-merge'; import configBase, { rootDir } from './webpack.config.base'; import { getWebViewEntries } from './webpack.util'; -/** Webpack configuration for building webViews */ +/** Webpack configuration for building WebViews */ const configWebView: webpack.Configuration = merge(configBase, { // Build for web since Platform.Bible loads WebViews in browser. Platform.Bible provides specific // modules that extensions may import as listed in `webpack.config.base`'s `externals`. Read more at @@ -14,12 +14,12 @@ const configWebView: webpack.Configuration = merge(configBase, { // documented at https://webpack.js.org/configuration/resolve/#resolvefallback // https://webpack.js.org/concepts/targets/ target: 'web', - // configuration name so we can depend on it in main + // Configuration name so we can depend on it in main name: 'webView', - // instructions to build each extension webview source file + // Instructions to build each extension WebView source file entry: getWebViewEntries, output: { - // Build all the web views in the folders where they are with the temp dir appended + // Build all the WebViews in the folders where they are with the temp dir appended path: rootDir, }, }); diff --git a/webpack/webpack.util.ts b/webpack/webpack.util.ts index 6564cd5..b924391 100644 --- a/webpack/webpack.util.ts +++ b/webpack/webpack.util.ts @@ -7,16 +7,16 @@ import { Pattern } from 'copy-webpack-plugin'; // #region shared with https://github.com/paranext/paranext-extension-template/blob/main/webpack/webpack.util.ts /** - * String of what a web view needs to have in its name before the file extension to be considered a - * web-view + * String of what a WebView needs to have in its name before the file extension to be considered a + * WebView * - * Web Views should be named .web-view. + * WebViews should be named .web-view. */ const webViewTag = '.web-view'; -/** Glob filename matcher for React web views. React Web Views should be named .web-view.tsx */ +/** Glob filename matcher for React WebViews. React WebViews should be named .web-view.tsx */ const webViewTsxGlob = '**/*.web-view.tsx'; /** - * Regex file name matcher for React web views. React Web Views should be named .web-view.tsx + * Regex file name matcher for React WebViews. React WebViews should be named .web-view.tsx * * Note: this regex allows the extension to be optional. */ @@ -45,7 +45,7 @@ function getWebViewTsxPaths() { /** * Gets the bundled WebView path for a WebView file path * - * @param webViewPath Relative path to webView e.g. './src/extension-template.web-view.tsx' + * @param webViewPath Relative path to WebView e.g. './src/extension-template.web-view.tsx' * @param join Function to use to join the paths together * @returns WebView path with temporary WebView directory inserted into the module path */ @@ -55,7 +55,7 @@ export function getWebViewTempPath( ) { const webViewInfo = path.parse(webViewPath); - // If the web view doesn't have a file extension, parsing makes it think the extension is + // If the WebView doesn't have a file extension, parsing makes it think the extension is // '.web-view', so we need to add it back const webViewName = webViewInfo.ext === webViewTag ? webViewInfo.base : webViewInfo.name; // Put transpiled WebViews in a temp folder in the same directory as the original WebView @@ -67,14 +67,14 @@ export function getWebViewTempPath( } /** - * Get webpack entry configuration to build each web-view source file and put it in a temporary + * Get webpack entry configuration to build each WebView source file and put it in a temporary * folder in the same directory * - * @returns Promise that resolves to the webView entry config + * @returns Promise that resolves to the WebView entry config */ export async function getWebViewEntries(): Promise { const tsxWebViews = await getWebViewTsxPaths(); - const webViewEntries: webpack.EntryObject = Object.fromEntries( + const webViewEntries = Object.fromEntries( tsxWebViews.map((webViewPath): [string, webpack.EntryObject[string]] => [ webViewPath, {