diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..7cffc01 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,16 @@ +root=true + +[*] +end_of_line = lf +insert_final_newline = true +charset = utf-8 +trim_trailing_whitespace = true + +[*.{mjs,cjs,js,mts,cts,ts,json,vue,html,scss,css,toml,md}] +indent_style = tab + +[*.md] +trim_trailing_whitespace = false + +[*.{yml,yaml}] +indent_style = space diff --git a/.github/actions/setup/action.yml b/.github/actions/setup/action.yml new file mode 100644 index 0000000..4ca65b7 --- /dev/null +++ b/.github/actions/setup/action.yml @@ -0,0 +1,40 @@ +name: Setup +description: Configure Node.js + pnpm and install dependencies + +inputs: + registry: + description: NPM registry to set up for auth + required: false + +runs: + using: composite + steps: + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version-file: .node-version + registry-url: ${{ inputs.registry }} + + - uses: pnpm/action-setup@v4 + name: Setup pnpm + id: pnpm-install + with: + run_install: false + + - name: Get pnpm cache dir + id: pnpm-cache-dir + shell: bash + run: echo "pnpm-cache-dir=$(pnpm store path)" >> $GITHUB_OUTPUT + + - uses: actions/cache@v4 + name: Setup pnpm cache + with: + path: ${{ steps.pnpm-cache-dir.outputs.pnpm-cache-dir }} + key: + ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }} + restore-keys: | + ${{ runner.os }}-pnpm-store- + + - name: Install dependencies + shell: bash + run: pnpm install diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml new file mode 100644 index 0000000..99603b4 --- /dev/null +++ b/.github/workflows/check.yml @@ -0,0 +1,37 @@ +name: Check + +on: + pull_request: + branches: + - main + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + lint: + name: Lint + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Setup env + uses: ./.github/actions/setup + + - name: Run linter + run: pnpm run lint + + test: + name: Test + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Setup env + uses: ./.github/actions/setup + + - name: Run test + run: pnpm test diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..21655db --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,105 @@ +name: Release + +on: + workflow_dispatch: + inputs: + version: + description: SemVer for the release, for example "1.0.0" + required: true + type: string + +permissions: + contents: write + +jobs: + check-version: + name: Check Version + runs-on: ubuntu-latest + outputs: + version: ${{ steps.version.outputs.release }} + is-prerelease: ${{ steps.version.outputs.prerelease && true || false }} + steps: + - name: Check version + uses: madhead/semver-utils@v4 + id: version + with: + version: ${{ inputs.version }} + lenient: false + + create-version: + name: Create Version + runs-on: ubuntu-latest + needs: check-version + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Setup env + uses: ./.github/actions/setup + + - name: Bump version + run: pnpm version --no-git-tag-version '${{ needs.check-version.outputs.version }}' + + - name: Create version commit & tag + run: | + author='${{ github.actor }} <${{ github.actor }}@users.noreply.github.com>' + version='v${{ needs.check-version.outputs.version }}' + branch='${{ github.ref }}' + + git config user.name 'github-actions[bot]' + git config user.email '41898282+github-actions[bot]@users.noreply.github.com' + + git commit --all --author "$author" --message "$version" + + git tag --annotate "$version" --message "$version" + + git push --atomic origin "$branch" "$version" + + create-release: + name: Create Release + runs-on: ubuntu-latest + needs: + - check-version + - create-version + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Create release + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + gh release create \ + 'v${{ needs.check-version.outputs.version }}' \ + --verify-tag \ + --generate-notes \ + ${{ needs.check-version.outputs.is-prerelease == 'true' && '--prerelease' || '' }} + + publish-npm: + name: Publish to NPM + runs-on: ubuntu-latest + needs: + - check-version + - create-version + permissions: + id-token: write + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + ref: refs/tags/v${{ needs.check-version.outputs.version }} + + - name: Setup env + uses: ./.github/actions/setup + with: + registry: https://registry.npmjs.org + + - name: Publish + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} + NPM_CONFIG_PROVENANCE: true + run: | + pnpm publish \ + --access=public \ + --no-git-checks \ + --tag ${{ needs.check-version.outputs.is-prerelease == 'true' && 'canary' || 'latest' }} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e74ba01 --- /dev/null +++ b/.gitignore @@ -0,0 +1,18 @@ +# User preferences +.DS_Store + +# Dependencies +node_modules/ + +# Builds / Caches +dist/ +coverage/ +*.tsbuildinfo +.eslintcache + +# IDEs / Editors +.idea/ +*.code-workspace +.history/ +*.sublime-settings +.*.swp diff --git a/.node-version b/.node-version new file mode 100644 index 0000000..209e3ef --- /dev/null +++ b/.node-version @@ -0,0 +1 @@ +20 diff --git a/.npmrc b/.npmrc new file mode 100644 index 0000000..fcb5881 --- /dev/null +++ b/.npmrc @@ -0,0 +1,3 @@ +engine-strict=true +shell-emulator=true +save-prefix='' diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000..7a0d74d --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,3 @@ +{ + "recommendations": ["dbaeumer.vscode-eslint", "editorconfig.editorconfig"] +} diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..442eee9 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,49 @@ +{ + // Disable the default formatter, use eslint instead + "prettier.enable": false, + "editor.formatOnSave": false, + + // Auto fix + "editor.codeActionsOnSave": { + "source.fixAll.eslint": "explicit", + "source.organizeImports": "never" + }, + + // Silent the stylistic rules in you IDE, but still auto fix them + "eslint.rules.customizations": [ + { "rule": "style/*", "severity": "off", "fixable": true }, + { "rule": "format/*", "severity": "off", "fixable": true }, + { "rule": "*-indent", "severity": "off", "fixable": true }, + { "rule": "*-spacing", "severity": "off", "fixable": true }, + { "rule": "*-spaces", "severity": "off", "fixable": true }, + { "rule": "*-order", "severity": "off", "fixable": true }, + { "rule": "*-dangle", "severity": "off", "fixable": true }, + { "rule": "*-newline", "severity": "off", "fixable": true }, + { "rule": "*quotes", "severity": "off", "fixable": true }, + { "rule": "*semi", "severity": "off", "fixable": true } + ], + + // Enable eslint for all supported languages + "eslint.validate": [ + "javascript", + "javascriptreact", + "typescript", + "typescriptreact", + "vue", + "html", + "markdown", + "json", + "jsonc", + "yaml", + "toml", + "xml", + "gql", + "graphql", + "astro", + "css", + "less", + "scss", + "pcss", + "postcss" + ] +} diff --git a/base/tsconfig.json b/configs/base/tsconfig.json similarity index 92% rename from base/tsconfig.json rename to configs/base/tsconfig.json index 36b0a2d..07c73be 100644 --- a/base/tsconfig.json +++ b/configs/base/tsconfig.json @@ -2,12 +2,10 @@ "$schema": "https://json.schemastore.org/tsconfig", "display": "Base", "compilerOptions": { + "checkJs": true, "strict": true, - "esModuleInterop": true, - "skipLibCheck": true, - "forceConsistentCasingInFileNames": true, - "allowUnusedLabels": false, "allowUnreachableCode": false, + "allowUnusedLabels": false, "exactOptionalPropertyTypes": true, "noFallthroughCasesInSwitch": true, "noImplicitOverride": true, @@ -16,8 +14,10 @@ "noUncheckedIndexedAccess": true, "noUnusedLocals": true, "noUnusedParameters": true, - "checkJs": true, + "declaration": true, "allowSyntheticDefaultImports": true, - "declaration": true + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "skipLibCheck": true } } diff --git a/node18-cjs/tsconfig.json b/configs/node18-cjs/tsconfig.json similarity index 77% rename from node18-cjs/tsconfig.json rename to configs/node18-cjs/tsconfig.json index 4dacada..41ce42e 100644 --- a/node18-cjs/tsconfig.json +++ b/configs/node18-cjs/tsconfig.json @@ -3,7 +3,7 @@ "display": "Node.js 18 CommonJS", "extends": "../base/tsconfig.json", "compilerOptions": { - "module": "CommonJS", - "target": "ES2022" + "target": "ES2022", + "module": "CommonJS" } } diff --git a/node18-esm/tsconfig.json b/configs/node18-esm/tsconfig.json similarity index 100% rename from node18-esm/tsconfig.json rename to configs/node18-esm/tsconfig.json index 8508289..e4f20fb 100644 --- a/node18-esm/tsconfig.json +++ b/configs/node18-esm/tsconfig.json @@ -3,8 +3,8 @@ "display": "Node.js 18 ESM", "extends": "../base/tsconfig.json", "compilerOptions": { - "module": "Node16", "target": "ES2022", + "module": "Node16", "moduleResolution": "Node16", "verbatimModuleSyntax": true } diff --git a/vue3/tsconfig.json b/configs/vue3/tsconfig.json similarity index 91% rename from vue3/tsconfig.json rename to configs/vue3/tsconfig.json index da3bd97..05b602d 100644 --- a/vue3/tsconfig.json +++ b/configs/vue3/tsconfig.json @@ -3,10 +3,6 @@ "display": "Vue.js 3", "extends": "../base/tsconfig.json", "compilerOptions": { - // It's recommended to author and ship in ES modules. - // This recommendation includes environments like Vitest, Vite Config File, Vite SSR, etc. - "module": "ES2022", - // - Vue 3 supports ES2016+ // - For Vite, the actual compilation target is determined by the // `build.target` option in the Vite config. @@ -14,19 +10,23 @@ // at least `ES2020` for dynamic `import()`s and `import.meta` to work correctly. "target": "ES2022", + // Required in Vue projects. + "jsx": "preserve", + "jsxImportSource": "vue", + // Add DOM definitions. "lib": ["ES2022", "DOM", "DOM.Iterable"], + // It's recommended to author and ship in ES modules. + // This recommendation includes environments like Vitest, Vite Config File, Vite SSR, etc. + "module": "ES2022", + // Enable some resolution features that are only available in bundlers. "moduleResolution": "bundler", "resolveJsonModule": true, // Any imports or exports without a type modifier are left around. This is important for `