diff --git a/.editorconfig b/.editorconfig index d6b1b89..551e30b 100644 --- a/.editorconfig +++ b/.editorconfig @@ -7,5 +7,5 @@ charset = utf-8 end_of_line = lf indent_size = 2 indent_style = space -trim_trailing_whitespace = true insert_final_newline = true +trim_trailing_whitespace = true diff --git a/.eslintrc.json b/.eslintrc.json index a02f759..5f88250 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -5,20 +5,44 @@ "es6": true, "node": true }, + "overrides": [ + { + "files": ["*.mjs"], + "parserOptions": { + "ecmaVersion": 2022, + "sourceType": "module" + } + } + ], "extends": ["eslint:recommended"], "ignorePatterns": ["*.min.*"], "rules": { + "array-callback-return": "error", "curly": "error", + "default-case": "error", + "default-case-last": "error", "dot-notation": "error", "eqeqeq": "error", + "func-name-matching": "error", + "grouped-accessor-pairs": "error", "no-implicit-coercion": "error", + "no-implicit-globals": "error", "no-return-assign": "error", "no-shadow": "error", + "no-throw-literal": "error", "no-unneeded-ternary": "error", "no-undef": "error", + "no-useless-call": "error", + "no-useless-concat": "error", + "no-useless-return": "error", "no-var": "error", + "object-shorthand": "error", "prefer-const": "error", + "prefer-promise-reject-errors": "error", + "prefer-regex-literals": "error", "radix": "error", + "require-await": "error", + "vars-on-top": "error", "yoda": "error" } } diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index cf3e5ee..851975a 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -1,3 +1,4 @@ +--- name: "CodeQL" on: diff --git a/.github/workflows/eslint.yml b/.github/workflows/eslint.yml index 4183ec5..461af89 100644 --- a/.github/workflows/eslint.yml +++ b/.github/workflows/eslint.yml @@ -1,3 +1,4 @@ +--- name: ESLint on: diff --git a/.github/workflows/npm-publish.yml b/.github/workflows/npm-publish.yml new file mode 100644 index 0000000..5084034 --- /dev/null +++ b/.github/workflows/npm-publish.yml @@ -0,0 +1,94 @@ +--- +name: Publish to npm + +on: + release: + types: [published] + workflow_dispatch: + +permissions: {} + +concurrency: + group: npm-publish-${{ github.event.release.tag_name || github.ref_name || github.run_id }} + cancel-in-progress: false + +jobs: + build: + name: Build release artifact + runs-on: ubuntu-latest + if: ${{ github.repository == 'coliff/bootstrap-show-password-toggle' }} + permissions: + contents: read + + steps: + - name: Checkout repository + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + + - name: Setup Node.js + uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0 + with: + node-version-file: .nvmrc + + - name: Verify release tag matches package version + if: ${{ github.event_name == 'release' }} + run: | + PACKAGE_VERSION="$(node -p "require('./package.json').version")" + TAG_NAME="${{ github.event.release.tag_name }}" + + if [ "$TAG_NAME" != "$PACKAGE_VERSION" ] && [ "$TAG_NAME" != "v$PACKAGE_VERSION" ]; then + echo "Release tag '$TAG_NAME' does not match package version '$PACKAGE_VERSION'." + exit 1 + fi + + - name: Install dependencies + run: npm install --ignore-scripts --no-package-lock + + - name: Run tests + run: npm test + + - name: Build package assets + run: npm run build + + - name: Verify generated files are committed + run: git diff --exit-code -- css js scss package.json + + - name: Pack npm tarball + run: npm pack --json > npm-pack.json + + - name: Upload npm tarball + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 + with: + name: npm-package + path: | + *.tgz + npm-pack.json + if-no-files-found: error + retention-days: 7 + + publish: + name: Publish package + runs-on: ubuntu-latest + needs: build + environment: + name: npm + permissions: + contents: read + id-token: write + + steps: + - name: Download npm tarball + uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5.0.0 + with: + name: npm-package + path: dist + + - name: Setup Node.js + uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0 + with: + node-version-file: .nvmrc + registry-url: https://registry.npmjs.org + package-manager-cache: false + + - name: Publish to npm + working-directory: dist + run: npm publish --provenance "$(node -p 'require("./npm-pack.json")[0].filename')" diff --git a/.github/workflows/ossf-scorecard.yml b/.github/workflows/ossf-scorecard.yml index 86dea7f..7180512 100644 --- a/.github/workflows/ossf-scorecard.yml +++ b/.github/workflows/ossf-scorecard.yml @@ -1,3 +1,4 @@ +--- name: Scorecards supply-chain security on: branch_protection_rule: diff --git a/.github/workflows/super-linter.yml b/.github/workflows/super-linter.yml index 1ce383d..29fa80b 100644 --- a/.github/workflows/super-linter.yml +++ b/.github/workflows/super-linter.yml @@ -1,4 +1,5 @@ -name: Lint Code Base +--- +name: Super Linter on: push: @@ -16,9 +17,8 @@ jobs: issues: write pull-requests: write statuses: write - name: Lint Code Base + name: Super Linter runs-on: ubuntu-latest - if: ${{ github.actor != 'dependabot[bot]' && !startsWith(github.head_ref || github.ref_name, 'dependabot/') }} steps: - name: Checkout Code @@ -33,6 +33,7 @@ jobs: - name: Lint Code Base uses: super-linter/super-linter/slim@9e863354e3ff62e0727d37183162c4a88873df41 # v8.6.0 env: + CSS_FILE_NAME: stylelint.config.mjs DEFAULT_BRANCH: main GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} IGNORE_GITIGNORED_FILES: true @@ -45,6 +46,7 @@ jobs: VALIDATE_CHECKOV: false VALIDATE_EDITORCONFIG: false VALIDATE_GIT_COMMITLINT: false + VALIDATE_GITHUB_ACTIONS_ZIZMOR: false VALIDATE_GITLEAKS: false VALIDATE_JSCPD: false VALIDATE_MARKDOWN: false diff --git a/.prettierignore b/.prettierignore index 3f7152f..2120f8d 100644 --- a/.prettierignore +++ b/.prettierignore @@ -5,3 +5,4 @@ CODEOWNERS *.min.* *.md .cspell.json +package.json diff --git a/.vscode/settings.json b/.vscode/settings.json index 47dc48f..804813e 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -2,6 +2,9 @@ "editor.formatOnSave": true, "editor.defaultFormatter": "EditorConfig.EditorConfig", "editor.codeActionsOnSave": { - "source.fixAll.eslint": "explicit" - } + "source.fixAll.eslint": "always", + "source.fixAll.stylelint": "always" + }, + "eslint.validate": ["javascript"], + "stylelint.validate": ["scss"] } diff --git a/LICENSE b/LICENSE index f52dbd7..d7aa860 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2020-2025 Christian Oliff +Copyright (c) 2020-2026 Christian Oliff Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/js/show-password-toggle.js b/js/show-password-toggle.js index b814618..f83b3d2 100644 --- a/js/show-password-toggle.js +++ b/js/show-password-toggle.js @@ -1,6 +1,6 @@ /*! - * Bootstrap Show Password Toggle v1.4.1 - * Copyright 2020-2024 C.Oliff + * Bootstrap Show Password Toggle v1.4.2 + * Copyright 2020-2026 C.Oliff * Licensed under MIT (https://github.com/coliff/bootstrap-show-password-toggle/blob/main/LICENSE) */ diff --git a/js/show-password-toggle.min.js b/js/show-password-toggle.min.js index 93d4c10..c6c6d1c 100644 --- a/js/show-password-toggle.min.js +++ b/js/show-password-toggle.min.js @@ -1,6 +1,6 @@ /*! - * Bootstrap Show Password Toggle v1.4.1 - * Copyright 2020-2024 C.Oliff + * Bootstrap Show Password Toggle v1.4.2 + * Copyright 2020-2026 C.Oliff * Licensed under MIT (https://github.com/coliff/bootstrap-show-password-toggle/blob/main/LICENSE) */ const ShowPasswordToggle=document.querySelector("[type='password']");ShowPasswordToggle.onclick=function(){document.querySelector("[type='password']").classList.add("input-password");document.getElementById("toggle-password").classList.remove("d-none");const passwordInput=document.querySelector("[type='password']");const togglePasswordButton=document.getElementById("toggle-password");togglePasswordButton.addEventListener("click",togglePassword);function togglePassword(){if(passwordInput.type==="password"){passwordInput.type="text";togglePasswordButton.setAttribute("aria-label","Hide password.")}else{passwordInput.type="password";togglePasswordButton.setAttribute("aria-label","Show password as plain text. Warning: this will display your password on the screen.")}}}; \ No newline at end of file diff --git a/package.json b/package.json index 490e90a..b0ab935 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "bootstrap-show-password-toggle", - "version": "1.4.1", + "version": "1.4.2", "description": "A show password as text toggle for Bootstrap", "keywords": [ "bootstrap", @@ -57,4 +57,4 @@ "volta": { "node": "22.22.2" } -} +} \ No newline at end of file