├── .editorconfig ├── .eslintignore ├── .eslintrc.cjs ├── .gitattributes ├── .githooks └── pre-commit ├── .github ├── FUNDING.yml ├── ISSUE_TEMPLATE │ ├── bug_report.yml │ ├── config.yml │ └── feature_request.yml ├── PULL_REQUEST_TEMPLATE.md ├── labels.yml ├── release.yml ├── test.js └── workflows │ ├── ci.yml │ ├── github-label-sync.yml │ └── release.yml ├── .gitignore ├── .npmignore ├── .npmrc ├── .prettierignore ├── .prettierrc ├── .secretlintrc.json ├── .vscode └── settings.json ├── CHANGELOG.md ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── examples ├── vue-i18n-v8-vue2 │ ├── README.md │ ├── env.d.ts │ ├── index.html │ ├── package.json │ ├── public │ │ └── favicon.ico │ ├── specs │ │ └── app.spec.ts │ ├── src │ │ ├── App.vue │ │ ├── assets │ │ │ ├── base.css │ │ │ └── logo.svg │ │ ├── components │ │ │ ├── HelloWorld.vue │ │ │ ├── TheWelcome.vue │ │ │ ├── WelcomeItem.vue │ │ │ └── icons │ │ │ │ ├── IconCommunity.vue │ │ │ │ ├── IconDocumentation.vue │ │ │ │ ├── IconEcosystem.vue │ │ │ │ ├── IconSupport.vue │ │ │ │ └── IconTooling.vue │ │ └── main.ts │ ├── tsconfig.json │ ├── vite.config.ts │ └── vitest.config.ts ├── vue-i18n-v9-vue3 │ ├── README.md │ ├── env.d.ts │ ├── index.html │ ├── package.json │ ├── public │ │ └── favicon.ico │ ├── specs │ │ └── app.spec.ts │ ├── src │ │ ├── App.vue │ │ ├── assets │ │ │ ├── base.css │ │ │ └── logo.svg │ │ ├── components │ │ │ ├── HelloWorld.vue │ │ │ ├── TheWelcome.vue │ │ │ ├── WelcomeItem.vue │ │ │ └── icons │ │ │ │ ├── IconCommunity.vue │ │ │ │ ├── IconDocumentation.vue │ │ │ │ ├── IconEcosystem.vue │ │ │ │ ├── IconSupport.vue │ │ │ │ └── IconTooling.vue │ │ └── main.ts │ ├── tsconfig.json │ ├── vite.config.ts │ └── vitest.config.ts ├── vue-router-v3-vue2 │ ├── README.md │ ├── env.d.ts │ ├── index.html │ ├── package.json │ ├── public │ │ └── favicon.ico │ ├── specs │ │ └── app.spec.ts │ ├── src │ │ ├── App.vue │ │ ├── assets │ │ │ ├── base.css │ │ │ └── logo.svg │ │ ├── components │ │ │ ├── HelloWorld.vue │ │ │ ├── TheWelcome.vue │ │ │ ├── WelcomeItem.vue │ │ │ └── icons │ │ │ │ ├── IconCommunity.vue │ │ │ │ ├── IconDocumentation.vue │ │ │ │ ├── IconEcosystem.vue │ │ │ │ ├── IconSupport.vue │ │ │ │ └── IconTooling.vue │ │ ├── main.ts │ │ ├── router │ │ │ └── index.ts │ │ └── views │ │ │ ├── AboutView.vue │ │ │ └── HomeView.vue │ ├── tsconfig.json │ ├── vite.config.ts │ └── vitest.config.ts ├── vue-router-v36-vue2 │ ├── README.md │ ├── env.d.ts │ ├── index.html │ ├── package.json │ ├── public │ │ └── favicon.ico │ ├── specs │ │ └── app.spec.ts │ ├── src │ │ ├── App.vue │ │ ├── assets │ │ │ ├── base.css │ │ │ └── logo.svg │ │ ├── components │ │ │ ├── HelloWorld.vue │ │ │ ├── TheWelcome.vue │ │ │ ├── WelcomeItem.vue │ │ │ └── icons │ │ │ │ ├── IconCommunity.vue │ │ │ │ ├── IconDocumentation.vue │ │ │ │ ├── IconEcosystem.vue │ │ │ │ ├── IconSupport.vue │ │ │ │ └── IconTooling.vue │ │ ├── main.ts │ │ ├── router │ │ │ └── index.ts │ │ └── views │ │ │ ├── AboutView.vue │ │ │ └── HomeView.vue │ ├── tsconfig.json │ ├── vite.config.ts │ └── vitest.config.ts └── vue-router-v4-vue3 │ ├── README.md │ ├── env.d.ts │ ├── index.html │ ├── package.json │ ├── public │ └── favicon.ico │ ├── specs │ └── app.spec.ts │ ├── src │ ├── App.vue │ ├── assets │ │ ├── base.css │ │ └── logo.svg │ ├── components │ │ ├── HelloWorld.vue │ │ ├── TheWelcome.vue │ │ ├── WelcomeItem.vue │ │ └── icons │ │ │ ├── IconCommunity.vue │ │ │ ├── IconDocumentation.vue │ │ │ ├── IconEcosystem.vue │ │ │ ├── IconSupport.vue │ │ │ └── IconTooling.vue │ ├── main.ts │ ├── router │ │ └── index.ts │ └── views │ │ ├── AboutView.vue │ │ └── HomeView.vue │ ├── tsconfig.json │ ├── vite.config.ts │ └── vitest.config.ts ├── package.json ├── packages ├── vue-i18n-bridge │ ├── LICENSE │ ├── README.md │ ├── bin │ │ ├── fix.js │ │ └── switch.js │ ├── lib │ │ ├── index.cjs │ │ ├── index.d.ts │ │ ├── index.mjs │ │ ├── v8 │ │ │ ├── index.cjs │ │ │ ├── index.d.ts │ │ │ └── index.mjs │ │ └── v9 │ │ │ ├── index.cjs │ │ │ ├── index.d.ts │ │ │ └── index.mjs │ ├── package.json │ └── scripts │ │ ├── postinstall.js │ │ ├── switch.js │ │ └── utils.js └── vue-router-bridge │ ├── LICENSE │ ├── README.md │ ├── bin │ ├── fix.js │ └── switch.js │ ├── lib │ ├── index.cjs │ ├── index.d.ts │ ├── index.mjs │ ├── v3.6 │ │ ├── index.cjs │ │ ├── index.d.ts │ │ └── index.mjs │ ├── v3 │ │ ├── index.cjs │ │ ├── index.d.ts │ │ └── index.mjs │ └── v4 │ │ ├── index.cjs │ │ ├── index.d.ts │ │ └── index.mjs │ ├── package.json │ └── scripts │ ├── postinstall.js │ ├── switch.js │ └── utils.js ├── pnpm-lock.yaml ├── pnpm-workspace.yaml ├── renovate.json ├── scripts ├── bump.ts ├── e2e.sh ├── preinstall.mjs ├── release-edge.sh ├── release.sh └── replaceDeps.ts └── tsconfig.json /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | dist 2 | dist_ssr 3 | docsgen.config.js 4 | examples 5 | .nyc_output -------------------------------------------------------------------------------- /.eslintrc.cjs: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | module.exports = { 4 | root: true, 5 | env: { 6 | node: true 7 | }, 8 | extends: [ 9 | 'plugin:@typescript-eslint/recommended', 10 | 'plugin:@typescript-eslint/eslint-recommended', 11 | 'plugin:prettier/recommended', 12 | 'prettier' 13 | ], 14 | plugins: ['@typescript-eslint'], 15 | parserOptions: { 16 | parser: '@typescript-eslint/parser', 17 | sourceType: 'module' 18 | }, 19 | rules: { 20 | '@typescript-eslint/ban-types': 'off', 21 | '@typescript-eslint/no-empty-function': 'off' 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | *.json linguist-language=JSON-with-Comments -------------------------------------------------------------------------------- /.githooks/pre-commit: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | npx --no-install lint-staged 3 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: kazupon 2 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.yml: -------------------------------------------------------------------------------- 1 | name: 🐛 Bug report 2 | description: Report an issue 3 | labels: ['status: review needed'] 4 | body: 5 | - type: markdown 6 | attributes: 7 | value: | 8 | Thanks for taking the time to fill out this bug report! 9 | - type: textarea 10 | id: bug-description 11 | attributes: 12 | label: Describe the bug 13 | description: A clear and concise description of what the bug is. If you intend to submit a PR for this issue, tell us in the description. Thanks! 14 | placeholder: Bug description 15 | validations: 16 | required: true 17 | - type: input 18 | id: reproduction 19 | attributes: 20 | label: Reproduction 21 | description: A [minimal reproduction](https://stackoverflow.com/help/minimal-reproducible-example) is **required**, otherwise the issue might be closed without further notice. [**Why & How?**](https://antfu.me/posts/why-reproductions-are-required) 22 | placeholder: Reproduction 23 | validations: 24 | required: true 25 | - type: textarea 26 | id: system-info 27 | attributes: 28 | label: System Info 29 | description: Output of `npx envinfo --system --binaries --browsers` 30 | render: Shell 31 | placeholder: System, Binaries, Browsers 32 | validations: 33 | required: true 34 | - type: dropdown 35 | id: package-manager 36 | attributes: 37 | label: Used Package Manager 38 | description: Select the used package manager 39 | options: 40 | - npm 41 | - yarn 42 | - pnpm 43 | - other (if you use other package manager, please describe at the `Additional context`) 44 | - n/a 45 | validations: 46 | required: true 47 | - type: textarea 48 | id: additional-context 49 | attributes: 50 | label: Additional context 51 | description: Any other context or screenshots about the bug report here. 52 | - type: checkboxes 53 | id: checkboxes 54 | attributes: 55 | label: Validations 56 | description: Before submitting the issue, please make sure you do the following 57 | options: 58 | - label: Follow our [Code of Conduct](https://github.com/intlify/bridging/blob/main/CODE_OF_CONDUCT.md) 59 | required: true 60 | - label: Read the [Contributing Guide](https://github.com/intlify/bridging/blob/main/CONTRIBUTING.md). 61 | required: true 62 | - label: Check that there isn't already an issue that reports the same bug to avoid creating a duplicate. 63 | required: true 64 | - label: Check that this is a concrete bug. For Q&A, please open a GitHub Discussion instead. 65 | required: true 66 | - label: The provided reproduction is a [minimal reproducible](https://stackoverflow.com/help/minimal-reproducible-example) of the bug. 67 | required: true 68 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | contact_links: 2 | - name: 🙌 Contribution Guide 3 | url: https://github.com/intlify/bridging/blob/main/CONTRIBUTING.md 4 | about: Please read through before making contributions. 5 | - name: ⁉️ Why and How to make a reproduction? 6 | url: https://antfu.me/posts/why-reproductions-are-required 7 | about: Reproduction is very important for maintainer to help on your issues! 8 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.yml: -------------------------------------------------------------------------------- 1 | name: 🚀 New feature proposal 2 | description: Propose a new feature 3 | labels: [feature] 4 | body: 5 | - type: markdown 6 | attributes: 7 | value: | 8 | Thanks for your interest in the project and taking the time to fill out this feature report! 9 | - type: textarea 10 | id: feature-description 11 | attributes: 12 | label: Clear and concise description of the problem 13 | description: 'As a developer using @intlify/bridging I want [goal / wish] so that [benefit]. If you intend to submit a PR for this issue, tell us in the description. Thanks!' 14 | validations: 15 | required: true 16 | - type: textarea 17 | id: suggested-solution 18 | attributes: 19 | label: Suggested solution 20 | description: 'In module [xy] we could provide following implementation...' 21 | validations: 22 | required: true 23 | - type: textarea 24 | id: alternative 25 | attributes: 26 | label: Alternative 27 | description: Clear and concise description of any alternative solutions or features you've considered. 28 | - type: textarea 29 | id: additional-context 30 | attributes: 31 | label: Additional context 32 | description: Any other context or screenshots about the feature request here. 33 | - type: checkboxes 34 | id: checkboxes 35 | attributes: 36 | label: Validations 37 | description: Before submitting the issue, please make sure you do the following 38 | options: 39 | - label: Follow our [Code of Conduct](https://github.com/intlify/bridging/blob/main/CODE_OF_CONDUCT.md) 40 | required: true 41 | - label: Read the [Contributing Guide](https://github.com/intlify/bridging/blob/main/CONTRIBUTING.md). 42 | required: true 43 | - label: Check that there isn't already an issue that request the same feature to avoid creating a duplicate. 44 | required: true 45 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 13 | 14 | ### Description 15 | 16 | 17 | 18 | ### Linked Issues 19 | 20 | ### Additional context 21 | 22 | 23 | -------------------------------------------------------------------------------- /.github/labels.yml: -------------------------------------------------------------------------------- 1 | - name: feature 2 | description: Includes new features 3 | color: 'ffff00' 4 | - name: bug 5 | description: Includes new features 6 | color: 'ee0701' 7 | - name: improvement 8 | description: Includes backwards-compatible fixes 9 | color: '1d76db' 10 | - name: breaking 11 | description: Includes backwards-incompatible fixes 12 | color: 'b60205' 13 | - name: refactoring 14 | description: A code change that neither fixes a bug nor adds a feature 15 | color: 'fbca04' 16 | - name: security 17 | description: Security fixes 18 | color: 'b60205' 19 | - name: documentation 20 | description: Includes documetation fixes 21 | color: '5319e7' 22 | - name: example 23 | description: Includes example and demo code fixes 24 | color: 'db0875' 25 | - name: deprecated 26 | description: Includes deprecate fixes 27 | color: 'f7ffa8' 28 | - name: performance 29 | description: Includes performance fixes 30 | color: 'cc317c' 31 | - name: i18n 32 | description: Includes internationalization fixes 33 | color: 'ffd412' 34 | - name: a11y 35 | description: Inlucdes accessibility fixes 36 | color: '0000ff' 37 | - name: dependency 38 | description: Includes dependency fixes 39 | color: 'ffbce7' 40 | - name: todo 41 | description: todo tasks 42 | color: 'c2e0c6' 43 | - name: duplicate 44 | description: This issue or Pull Request already exists 45 | color: 'ededed' 46 | - name: help wanted 47 | description: Extra attention is needed 48 | color: 'e99695' 49 | - name: good first issue 50 | description: Good for newcomers 51 | color: '7057ff' 52 | - name: 'status: abandoned' 53 | description: The issue or Pull Request is wontfix 54 | color: '000000' 55 | - name: 'status: blocked' 56 | description: Progress on the issue is Blocked 57 | color: 'ee0701' 58 | - name: 'status: in progress' 59 | description: Work in Progress 60 | color: 'cccccc' 61 | - name: 'status: proposal' 62 | description: Request for comments 63 | color: 'd4c5f9' 64 | - name: 'status: pull request welcome' 65 | description: Welcome to Pull Request 66 | color: '2E7733' 67 | - name: 'status: review needed' 68 | description: Request for review 69 | color: 'fbca04' 70 | - name: 'status: need more repro codes or info' 71 | description: Lacks enough info to make progress 72 | color: 'F9C90A' 73 | -------------------------------------------------------------------------------- /.github/release.yml: -------------------------------------------------------------------------------- 1 | changelog: 2 | exclude: 3 | labels: 4 | - ignore-for-release 5 | authors: 6 | - octocat 7 | - renovate[bot] 8 | categories: 9 | - title: 🌟 Features 10 | labels: 11 | - feature 12 | - title: 🐛 Bug Fixes 13 | labels: 14 | - bug 15 | - title: 💥 Breaking Changes 16 | labels: 17 | - breaking 18 | - title: ⚠️ Deprecated Features 19 | labels: 20 | - deprecated 21 | - title: ⚡ Improvement Features 22 | labels: 23 | - improvement 24 | - title: 🔒 Security Fixes 25 | labels: 26 | - security 27 | - title: 📈 Performance Fixes 28 | labels: 29 | - performance 30 | - title: 📝️ Documentations 31 | labels: 32 | - documentation 33 | - title: 👕 Refactoring 34 | labels: 35 | - refactoring 36 | - title: 🍭 Examples 37 | labels: 38 | - example 39 | - title: 🌐 ♿ Internationalization or Accessibility Fixes 40 | labels: 41 | - a11y 42 | - i18n 43 | - title: 🪄 Others 44 | labels: 45 | - chore 46 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | env: 4 | CI: true 5 | # install playwright binary manually (because pnpm only runs install script once) 6 | PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: '1' 7 | 8 | on: 9 | push: 10 | branches: 11 | - main 12 | pull_request: 13 | branches: 14 | - main 15 | 16 | jobs: 17 | lint: 18 | runs-on: ${{ matrix.os }} 19 | strategy: 20 | matrix: 21 | os: [ubuntu-latest] 22 | node: [18.x] 23 | timeout-minutes: 10 24 | 25 | steps: 26 | - name: Checkout codes 27 | uses: actions/checkout@v4 28 | with: 29 | fetch-depth: 0 30 | 31 | - name: Install pnpm 32 | uses: pnpm/action-setup@v2 33 | with: 34 | version: 8.6.2 35 | 36 | - name: Setup node 37 | uses: actions/setup-node@v4 38 | with: 39 | node-version: ${{ matrix.node }} 40 | cache: 'pnpm' 41 | 42 | - name: Install dependencies 43 | run: pnpm install --no-frozen-lockfile 44 | 45 | - name: Lint codes 46 | run: pnpm lint 47 | 48 | e2e: 49 | runs-on: ${{ matrix.os }} 50 | strategy: 51 | matrix: 52 | os: [ubuntu-latest] 53 | node: [18.x] 54 | timeout-minutes: 10 55 | 56 | steps: 57 | - name: Checkout codes 58 | uses: actions/checkout@v4 59 | with: 60 | fetch-depth: 0 61 | 62 | - name: Install pnpm 63 | uses: pnpm/action-setup@v2 64 | with: 65 | version: 8.6.2 66 | 67 | - name: Setup node 68 | uses: actions/setup-node@v4 69 | with: 70 | node-version: ${{ matrix.node }} 71 | cache: 'pnpm' 72 | 73 | - name: Install dependencies 74 | run: pnpm install --no-frozen-lockfile --ignore-scripts 75 | 76 | # https://github.com/vitejs/vite/blob/main/.github/workflows/ci.yml#L91 77 | # Install playwright's binary under custom directory to cache 78 | - name: (non-windows) Set Playwright path and Get playwright version 79 | if: runner.os != 'Windows' 80 | run: | 81 | echo "PLAYWRIGHT_BROWSERS_PATH=$HOME/.cache/playwright-bin" >> $GITHUB_ENV 82 | PLAYWRIGHT_VERSION="$(pnpm ls --depth 0 --json -w playwright | jq --raw-output '.[0].devDependencies["playwright"].version')" 83 | echo "PLAYWRIGHT_VERSION=$PLAYWRIGHT_VERSION" >> $GITHUB_ENV 84 | - name: (windows) Set Playwright path and Get playwright version 85 | if: runner.os == 'Windows' 86 | run: | 87 | echo "PLAYWRIGHT_BROWSERS_PATH=$HOME\.cache\playwright-bin" >> $env:GITHUB_ENV 88 | $env:PLAYWRIGHT_VERSION="$(pnpm ls --depth 0 --json -w playwright | jq --raw-output '.[0].devDependencies[\"playwright\"].version')" 89 | echo "PLAYWRIGHT_VERSION=$env:PLAYWRIGHT_VERSION" >> $env:GITHUB_ENV 90 | 91 | - name: Cache Playwright's binary 92 | uses: actions/cache@v3 93 | with: 94 | key: ${{ runner.os }}-playwright-bin-v1-${{ env.PLAYWRIGHT_VERSION }} 95 | path: ${{ env.PLAYWRIGHT_BROWSERS_PATH }} 96 | restore-keys: | 97 | ${{ runner.os }}-playwright-bin-v1- 98 | 99 | - name: Install Playwright 100 | # does not need to explicitly set chromium after https://github.com/microsoft/playwright/issues/14862 is solved 101 | run: npx playwright install chromium 102 | 103 | - name: Run test 104 | run: ./scripts/e2e.sh 105 | 106 | npm: 107 | strategy: 108 | matrix: 109 | node: [18.x] 110 | os: [ubuntu-latest] 111 | vue: [2.6, 2.7, 3] 112 | bridge: [vue-i18n-bridge, vue-router-bridge] 113 | type: [commonjs, module] 114 | fail-fast: false 115 | timeout-minutes: 10 116 | 117 | runs-on: ${{ matrix.os }} 118 | 119 | steps: 120 | - name: Checkout codes 121 | uses: actions/checkout@v4 122 | with: 123 | fetch-depth: 0 124 | 125 | - name: Setup node 126 | uses: actions/setup-node@v4 127 | with: 128 | node-version: ${{ matrix.node }} 129 | 130 | - name: Print npm version 131 | run: npm -v 132 | 133 | - name: Test 134 | run: node .github/test.js "npm" ${{ matrix.bridge }} ${{ matrix.vue }} ${{matrix.type}} 135 | 136 | yarn: 137 | strategy: 138 | matrix: 139 | node: [18.x] 140 | os: [ubuntu-latest] 141 | vue: [2.6, 2.7, 3] 142 | # yarn: [1.22.19, berry] 143 | yarn: [1.22.19] 144 | bridge: [vue-i18n-bridge, vue-router-bridge] 145 | type: [commonjs, module] 146 | fail-fast: false 147 | timeout-minutes: 10 148 | 149 | runs-on: ${{ matrix.os }} 150 | 151 | steps: 152 | - name: Checkout codes 153 | uses: actions/checkout@v4 154 | with: 155 | fetch-depth: 0 156 | 157 | - name: Setup node 158 | uses: actions/setup-node@v4 159 | with: 160 | node-version: ${{ matrix.node }} 161 | 162 | - name: Install yarn 163 | run: yarn set version ${{ matrix.yarn }} 164 | 165 | - name: Print yarn version 166 | run: yarn --version 167 | 168 | - name: Test 169 | run: node .github/test.js "yarn@${{ matrix.yarn }}" ${{ matrix.bridge }} ${{ matrix.vue }} ${{matrix.type}} 170 | 171 | pnpm: 172 | strategy: 173 | matrix: 174 | node: [18.x] 175 | os: [ubuntu-latest] 176 | bridge: [vue-i18n-bridge, vue-router-bridge] 177 | vue: [2.6, 2.7, 3] 178 | type: [commonjs, module] 179 | fail-fast: false 180 | timeout-minutes: 10 181 | 182 | runs-on: ${{ matrix.os }} 183 | 184 | steps: 185 | - name: Checkout codes 186 | uses: actions/checkout@v4 187 | with: 188 | fetch-depth: 0 189 | 190 | - name: Setup node 191 | uses: actions/setup-node@v4 192 | with: 193 | node-version: ${{ matrix.node }} 194 | 195 | - name: Install pnpm 196 | run: npm i -g pnpm 197 | 198 | - name: Print pnpm version 199 | run: pnpm -v 200 | 201 | - name: Test 202 | run: node .github/test.js "pnpm" ${{ matrix.bridge }} ${{ matrix.vue }} ${{matrix.type}} 203 | 204 | edge-release: 205 | needs: 206 | - npm 207 | - yarn 208 | - pnpm 209 | - lint 210 | - e2e 211 | 212 | strategy: 213 | matrix: 214 | os: [ubuntu-latest] 215 | node: [18.x] 216 | 217 | runs-on: ${{ matrix.os }} 218 | 219 | steps: 220 | - name: Checkout codes 221 | uses: actions/checkout@v4 222 | 223 | - name: Install pnpm 224 | uses: pnpm/action-setup@v2 225 | with: 226 | version: 8.6.2 227 | 228 | - name: Setup node 229 | uses: actions/setup-node@v4 230 | with: 231 | node-version: ${{ matrix.node }} 232 | cache: 'pnpm' 233 | 234 | - name: Install dependencies 235 | run: pnpm install --no-frozen-lockfile --ignore-scripts 236 | 237 | - name: Release Edge version 238 | if: | 239 | github.event_name == 'push' && 240 | !startsWith(github.event.head_commit.message, '[skip-release]') && 241 | !startsWith(github.event.head_commit.message, 'chore') && 242 | !startsWith(github.event.head_commit.message, 'docs') 243 | run: ./scripts/release-edge.sh 244 | env: 245 | NODE_AUTH_TOKEN: ${{secrets.NODE_AUTH_TOKEN}} 246 | -------------------------------------------------------------------------------- /.github/workflows/github-label-sync.yml: -------------------------------------------------------------------------------- 1 | name: Label sync 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | paths: 8 | - .github/labels.yml 9 | - .github/workflows/github-label-sync.yml 10 | workflow_dispatch: 11 | 12 | jobs: 13 | sync: 14 | runs-on: ubuntu-latest 15 | steps: 16 | - uses: r7kamura/github-label-sync-action@v0 17 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Release 2 | 3 | on: 4 | push: 5 | branches-ignore: 6 | - '**' 7 | tags: 8 | - 'v*' 9 | 10 | jobs: 11 | release: 12 | runs-on: ubuntu-latest 13 | steps: 14 | - name: Checkout codes 15 | uses: actions/checkout@v4 16 | with: 17 | ref: ${{ github.head_ref }} 18 | 19 | - name: Setup Node 20 | uses: actions/setup-node@v3 21 | with: 22 | node-version: 18.x 23 | 24 | - name: Install pnpm 25 | uses: pnpm/action-setup@v2 26 | with: 27 | version: 8.6.2 28 | 29 | - name: Install dependencies 30 | run: pnpm install --no-frozen-lockfile --ignore-scripts 31 | 32 | - name: Extract version tag 33 | if: startsWith( github.ref, 'refs/tags/v' ) 34 | uses: jungwinter/split@v2 35 | id: split 36 | with: 37 | msg: ${{ github.ref }} 38 | separator: '/' 39 | 40 | - name: Create Github Release 41 | run: gh release create ${{ steps.split.outputs._2 }} --generate-notes 42 | env: 43 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 44 | 45 | - name: Generate changelog 46 | run: npx gh-changelogen --repo=intlify/bridging --tag=${{ steps.split.outputs._2 }} 47 | env: 48 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 49 | 50 | - name: Commit changelog 51 | uses: stefanzweifel/git-auto-commit-action@v4 52 | with: 53 | branch: main 54 | file_pattern: '*.md' 55 | commit_message: 'chore: sync changelog' 56 | 57 | - name: Publish package 58 | run: | 59 | ./scripts/release.sh 60 | env: 61 | NODE_AUTH_TOKEN: ${{secrets.NODE_AUTH_TOKEN}} 62 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | build 13 | dist-ssr 14 | *.local 15 | .vercel 16 | .output 17 | .vite 18 | temp 19 | 20 | # Editor directories and files 21 | .vscode/extensions.json 22 | .idea 23 | .DS_Store 24 | *.suo 25 | *.ntvs* 26 | *.njsproj 27 | *.sln 28 | *.sw? 29 | 30 | .yarn/* 31 | !.yarn/releases 32 | !.yarn/plugins 33 | 34 | .env 35 | .env.* 36 | *.tgz 37 | coverage 38 | package-lock.json 39 | yarn.lock -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | .* 2 | *.log 3 | *.swp 4 | coverage 5 | test 6 | temp 7 | scripts 8 | .nyc_output -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | strict-peer-dependencies=false 2 | ignore-scripts=true -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | dist 2 | dist-ssr 3 | coverage 4 | tsconfig.json 5 | packages/**/lib/**/**.d.ts -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | semi: false 2 | singleQuote: true 3 | printWidth: 120 4 | trailingComma: "none" 5 | endOfLine: "auto" 6 | arrowParens: "avoid" 7 | -------------------------------------------------------------------------------- /.secretlintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "rules": [ 3 | { 4 | "id": "@secretlint/secretlint-rule-preset-recommend" 5 | } 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "files.associations": { 3 | "*.json": "jsonc" 4 | }, 5 | "[typescript]": { 6 | "editor.defaultFormatter": "esbenp.prettier-vscode" 7 | }, 8 | "editor.formatOnSave": true, 9 | "editor.codeActionsOnSave": { 10 | "source.fixAll.eslint": true 11 | }, 12 | "typescript.tsdk": "node_modules/typescript/lib" 13 | } 14 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as 6 | contributors and maintainers pledge to making participation in our project and 7 | our community a harassment-free experience for everyone, regardless of age, body 8 | size, disability, ethnicity, sex characteristics, gender identity and expression, 9 | level of experience, education, socio-economic status, nationality, personal 10 | appearance, race, religion, or sexual identity and orientation. 11 | 12 | ## Our Standards 13 | 14 | Examples of behavior that contributes to creating a positive environment 15 | include: 16 | 17 | - Using welcoming and inclusive language 18 | - Being respectful of differing viewpoints and experiences 19 | - Gracefully accepting constructive criticism 20 | - Focusing on what is best for the community 21 | - Showing empathy towards other community members 22 | 23 | Examples of unacceptable behavior by participants include: 24 | 25 | - The use of sexualized language or imagery and unwelcome sexual attention or 26 | advances 27 | - Trolling, insulting/derogatory comments, and personal or political attacks 28 | - Public or private harassment 29 | - Publishing others' private information, such as a physical or electronic 30 | address, without explicit permission 31 | - Other conduct which could reasonably be considered inappropriate in a 32 | professional setting 33 | 34 | ## Our Responsibilities 35 | 36 | Project maintainers are responsible for clarifying the standards of acceptable 37 | behavior and are expected to take appropriate and fair corrective action in 38 | response to any instances of unacceptable behavior. 39 | 40 | Project maintainers have the right and responsibility to remove, edit, or 41 | reject comments, commits, code, wiki edits, issues, and other contributions 42 | that are not aligned to this Code of Conduct, or to ban temporarily or 43 | permanently any contributor for other behaviors that they deem inappropriate, 44 | threatening, offensive, or harmful. 45 | 46 | ## Scope 47 | 48 | This Code of Conduct applies both within project spaces and in public spaces 49 | when an individual is representing the project or its community. Examples of 50 | representing a project or community include using an official project e-mail 51 | address, posting via an official social media account, or acting as an appointed 52 | representative at an online or offline event. Representation of a project may be 53 | further defined and clarified by project maintainers. 54 | 55 | ## Enforcement 56 | 57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 58 | reported by contacting the project team at kawakazu80@gmail.com. All 59 | complaints will be reviewed and investigated and will result in a response that 60 | is deemed necessary and appropriate to the circumstances. The project team is 61 | obligated to maintain confidentiality with regard to the reporter of an incident. 62 | Further details of specific enforcement policies may be posted separately. 63 | 64 | Project maintainers who do not follow or enforce the Code of Conduct in good 65 | faith may face temporary or permanent repercussions as determined by other 66 | members of the project's leadership. 67 | 68 | ## Attribution 69 | 70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, 71 | available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html 72 | 73 | [homepage]: https://www.contributor-covenant.org 74 | 75 | For answers to common questions about this code of conduct, see 76 | https://www.contributor-covenant.org/faq 77 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing Guide 2 | 3 | - [Contributing Guide](#contributing-guide) 4 | - [General Guidelines](#general-guidelines) 5 | - [Pull Request Guidelines](#pull-request-guidelines) 6 | - [Work Step Example](#work-step-example) 7 | - [Development Setup](#development-setup) 8 | - [Scripts](#scripts) 9 | - [`pnpm test`](#pnpm-test) 10 | - [Project Structure](#project-structure) 11 | - [Contributing Tests](#contributing-tests) 12 | - [Financial Contribution](#financial-contribution) 13 | - [Credits](#credits) 14 | 15 | ## General Guidelines 16 | 17 | Thanks for understanding that English is used as a shared language in this repository. 18 | Maintainers do not use machine translation to avoid miscommunication due to error in translation. 19 | If description of issue / PR are written in non-English languages, those may be closed. 20 | 21 | It is of course fine to use non-English language, when you open a PR to translate documents and communicates with other users in same language. 22 | 23 | ## Pull Request Guidelines 24 | 25 | - The `main` branch is the latest stable version release. All development should be done in dedicated branches. 26 | 27 | - Checkout a topic branch from the relevant branch, e.g. `main`, and merge back against that branch. 28 | 29 | - Work in the `src` folder and **DO NOT** checkin `dist` in the commits. 30 | 31 | - If adding new feature: 32 | 33 | - Add accompanying test case. 34 | - Provide convincing reason to add this feature. Ideally you should open a suggestion issue first and have it greenlighted before working on it. 35 | 36 | - If fixing a bug: 37 | 38 | - Provide detailed description of the bug in the PR. Live demo preferred. 39 | - Add appropriate test coverage if applicable. 40 | 41 | - It's OK to have multiple small commits as you work on the PR - we will let GitHub automatically squash it before merging. 42 | 43 | - Make sure `pnpm test` passes. (see [development setup](#development-setup)) 44 | 45 | ### Work Step Example 46 | 47 | - Fork the repository from [intlify/bridging](https://github.com/intlify/bridging) ! 48 | - Create your topic branch from `main`: `git branch my-new-topic origin/main` 49 | - Add codes and pass tests ! 50 | - Commit your changes: `git commit -am 'Add some topic'` 51 | - Push to the branch: `git push origin my-new-topic` 52 | - Submit a pull request to `main` branch of `intlify/bridging` repository ! 53 | 54 | ## Development Setup 55 | 56 | You will need [Node.js](http://nodejs.org) **version 14.16+**, and [PNPM](https://pnpm.io). 57 | 58 | After cloning the repo, run: 59 | 60 | ```sh 61 | $ pnpm i # install the dependencies of the project 62 | ``` 63 | 64 | A high level overview of tools used: 65 | 66 | - [TypeScript](https://www.typescriptlang.org/) as the development language 67 | - [Vite](https://vitejs.dev/) for bundling 68 | - [Vitest](https://vitest.dev/) for testing 69 | - [ESLint](https://eslint.org/) for code linting 70 | - [Prettier](https://prettier.io/) for code formatting 71 | 72 | ## Scripts 73 | 74 | ### `pnpm test` 75 | 76 | The `test` script calls the following npm scripts: 77 | 78 | - `test:i18n9:unit`: unit test `@intlify/vue-i18n-bridge` on vue-i18n v9 79 | - `test:i18n8:unit`: unit test `@intlify/vue-i18n-bridge` on vue-i18n v8 80 | - `test:router4:unit`: unit test `@intlify/vue-router-bridge` on vue-router v4 81 | - `test:router3:unit`: unit test `@intlify/vue-router-bridge` on vue-router v3 82 | 83 | ## Project Structure 84 | 85 | This repository employs a [monorepo](https://en.wikipedia.org/wiki/Monorepo) setup which hosts a number of associated packages under the `packages` directory: 86 | 87 | - `vue-i18n-bridge`: Vue I18n bridging for Vue 2 & Vue 3 88 | - `vue-router-bridge`: Vue Router bridging for Vue 2 & Vue 3 89 | 90 | ## Contributing Tests 91 | 92 | Unit tests are collocated with directories named `test` on `examples/**/`. Consult the [Vitest docs](https://vitest.dev/api/) and existing test cases for how to write new test specs. 93 | 94 | ## Financial Contribution 95 | 96 | As a pure community-driven project without major corporate backing, we also welcome financial contributions via GitHub Sponsors 97 | 98 | - [Become a backer or sponsor on GitHub Sponsors](https://github.com/sponsors/kazupon) 99 | 100 | Funds donated via GitHub Sponsors and Patreon go to support kazuya kawaguchi full-time work on Intlify. 101 | 102 | ## Credits 103 | 104 | Thank you to all the people who have already contributed to Intlify project and my OSS work ! 105 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2021 kazuya kawaguchi 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # @intlify/bridging 2 | 3 | Utilities that provide compatibility for Vue 2 & Vue 3 4 | 5 | [![CI](https://github.com/intlify/bridging/actions/workflows/ci.yml/badge.svg)](https://github.com/intlify/bridging/actions/workflows/ci.yml) 6 | 7 | ## 📦 Packages 8 | 9 | | Package | NPM | 10 | | -------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ | 11 | | [@intlify/vue-router-bridge](packages/vue-router-bridge) | [![@intlify/vue-router-bridge](https://img.shields.io/npm/v/@intlify/vue-router-bridge.svg)](https://www.npmjs.com/package/@intlify/vue-router-bridge) | 12 | | [@intlify/vue-i18n-bridge](packages/vue-i18n-bridge) | [![@intlify/vue-i18n-bridge](https://img.shields.io/npm/v/@intlify/vue-i18n-bridge.svg)](https://www.npmjs.com/package/@intlify/vue-i18n-bridge) | 13 | 14 | ## 🏃 Project using bridging packages 15 | 16 | - [`@intlify/routing`](https://github.com/intlify/routing) 17 | 18 | ## 🙌 Contributing guidelines 19 | 20 | If you are interested in contributing to `@intlify/bridging` project, We highly recommend checking out [the contributing guidelines](/CONTRIBUTING.md) here. You'll find all the relevant information such as [how to make a PR](/CONTRIBUTING.md#pull-request-guidelines), [how to setup development](/CONTRIBUTING.md#development-setup) etc., there. 21 | 22 | ## ©️ License 23 | 24 | [MIT](http://opensource.org/licenses/MIT) 25 | -------------------------------------------------------------------------------- /examples/vue-i18n-v8-vue2/README.md: -------------------------------------------------------------------------------- 1 | # vue-i18n-v8-vue2 2 | 3 | This project is Vue 2 & Vue I18n v8 example for `@intlify/vue-i18n-bridge` 4 | -------------------------------------------------------------------------------- /examples/vue-i18n-v8-vue2/env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | declare module '*.vue' { 4 | import Vue from 'vue' 5 | export default Vue 6 | } 7 | 8 | declare global { 9 | namespace JSX { 10 | interface Element extends VNode {} 11 | interface ElementClass extends Vue {} 12 | interface IntrinsicElements { 13 | [elem: string]: any 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /examples/vue-i18n-v8-vue2/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Vite App 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /examples/vue-i18n-v8-vue2/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vue-i18n-v8-vue2", 3 | "version": "0.0.0", 4 | "scripts": { 5 | "dev": "vite", 6 | "build": "vue-tsc --noEmit && vite build", 7 | "preview": "vite preview --port 5050", 8 | "test": "vitest run specs", 9 | "typecheck": "vue-tsc --noEmit" 10 | }, 11 | "dependencies": { 12 | "@vue/composition-api": "1.4.9", 13 | "vue": "2.6.14", 14 | "vue-i18n": "8.27.2", 15 | "vue-i18n-bridge": "9.2.2", 16 | "@intlify/vue-i18n-bridge": "0.5.0" 17 | }, 18 | "devDependencies": { 19 | "@types/node": "16.11.17", 20 | "@vitejs/plugin-legacy": "1.6.3", 21 | "@vue/runtime-dom": "3.2.22", 22 | "typescript": "4.5.4", 23 | "unplugin-vue2-script-setup": "0.7.1", 24 | "playwright": "1.38.0", 25 | "vite": "2.9.12", 26 | "vite-test-utils": "0.6.0", 27 | "vitest": "0.23.2", 28 | "vite-plugin-vue2": "2.0.2", 29 | "vue-template-compiler": "2.6.14", 30 | "vue-tsc": "0.30.1" 31 | } 32 | } -------------------------------------------------------------------------------- /examples/vue-i18n-v8-vue2/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intlify/bridging/feb740a8bae26a5b4fc38cc4b6f73fa353920a1f/examples/vue-i18n-v8-vue2/public/favicon.ico -------------------------------------------------------------------------------- /examples/vue-i18n-v8-vue2/specs/app.spec.ts: -------------------------------------------------------------------------------- 1 | import { test, expect } from 'vitest' 2 | import { setup, url, createPage } from 'vite-test-utils' 3 | 4 | await setup({ 5 | browser: true 6 | }) 7 | 8 | test('pages', async () => { 9 | const page = await createPage() 10 | await page.goto(url('/')) 11 | 12 | page.on('console', (...args) => console.log(...args)) 13 | 14 | const header = await page.locator('h1.green') 15 | expect(await header.textContent()).toBe('You did it!') 16 | }) 17 | -------------------------------------------------------------------------------- /examples/vue-i18n-v8-vue2/src/App.vue: -------------------------------------------------------------------------------- 1 | 5 | 6 | 21 | 22 | 84 | -------------------------------------------------------------------------------- /examples/vue-i18n-v8-vue2/src/assets/base.css: -------------------------------------------------------------------------------- 1 | /* color palette from */ 2 | :root { 3 | --vt-c-white: #ffffff; 4 | --vt-c-white-soft: #f8f8f8; 5 | --vt-c-white-mute: #f2f2f2; 6 | 7 | --vt-c-black: #181818; 8 | --vt-c-black-soft: #222222; 9 | --vt-c-black-mute: #282828; 10 | 11 | --vt-c-indigo: #2c3e50; 12 | 13 | --vt-c-divider-light-1: rgba(60, 60, 60, 0.29); 14 | --vt-c-divider-light-2: rgba(60, 60, 60, 0.12); 15 | --vt-c-divider-dadarkrk-1: rgba(84, 84, 84, 0.65); 16 | --vt-c-divider-dark-2: rgba(84, 84, 84, 0.48); 17 | 18 | --vt-c-text-light-1: var(--vt-c-indigo); 19 | --vt-c-text-light-2: rgba(60, 60, 60, 0.66); 20 | --vt-c-text-dark-1: var(--vt-c-white); 21 | --vt-c-text-dark-2: rgba(235, 235, 235, 0.64); 22 | } 23 | 24 | /* semantic color variables for this project */ 25 | :root { 26 | --color-background: var(--vt-c-white); 27 | --color-background-soft: var(--vt-c-white-soft); 28 | --color-background-mute: var(--vt-c-white-mute); 29 | 30 | --color-border: var(--vt-c-divider-light-2); 31 | --color-border-hover: var(--vt-c-divider-light-1); 32 | 33 | --color-heading: var(--vt-c-text-light-1); 34 | --color-text: var(--vt-c-text-light-1); 35 | 36 | --section-gap: 160px; 37 | } 38 | 39 | @media (prefers-color-scheme: dark) { 40 | :root { 41 | --color-background: var(--vt-c-black); 42 | --color-background-soft: var(--vt-c-black-soft); 43 | --color-background-mute: var(--vt-c-black-mute); 44 | 45 | --color-border: var(--vt-c-divider-dark-2); 46 | --color-border-hover: var(--vt-c-divider-dark-1); 47 | 48 | --color-heading: var(--vt-c-text-dark-1); 49 | --color-text: var(--vt-c-text-dark-2); 50 | } 51 | } 52 | 53 | *, 54 | *::before, 55 | *::after { 56 | box-sizing: border-box; 57 | margin: 0; 58 | position: relative; 59 | font-weight: normal; 60 | } 61 | 62 | body { 63 | min-height: 100vh; 64 | color: var(--color-text); 65 | background: var(--color-background); 66 | transition: color 0.5s, background-color 0.5s; 67 | line-height: 1.6; 68 | font-family: Inter, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, 69 | Cantarell, 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif; 70 | font-size: 15px; 71 | text-rendering: optimizeLegibility; 72 | -webkit-font-smoothing: antialiased; 73 | -moz-osx-font-smoothing: grayscale; 74 | } 75 | -------------------------------------------------------------------------------- /examples/vue-i18n-v8-vue2/src/assets/logo.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /examples/vue-i18n-v8-vue2/src/components/HelloWorld.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 16 | 17 | 41 | -------------------------------------------------------------------------------- /examples/vue-i18n-v8-vue2/src/components/TheWelcome.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 84 | -------------------------------------------------------------------------------- /examples/vue-i18n-v8-vue2/src/components/WelcomeItem.vue: -------------------------------------------------------------------------------- 1 | 14 | 15 | 87 | -------------------------------------------------------------------------------- /examples/vue-i18n-v8-vue2/src/components/icons/IconCommunity.vue: -------------------------------------------------------------------------------- 1 | 8 | -------------------------------------------------------------------------------- /examples/vue-i18n-v8-vue2/src/components/icons/IconDocumentation.vue: -------------------------------------------------------------------------------- 1 | 8 | -------------------------------------------------------------------------------- /examples/vue-i18n-v8-vue2/src/components/icons/IconEcosystem.vue: -------------------------------------------------------------------------------- 1 | 8 | -------------------------------------------------------------------------------- /examples/vue-i18n-v8-vue2/src/components/icons/IconSupport.vue: -------------------------------------------------------------------------------- 1 | 8 | -------------------------------------------------------------------------------- /examples/vue-i18n-v8-vue2/src/components/icons/IconTooling.vue: -------------------------------------------------------------------------------- 1 | 2 | 20 | -------------------------------------------------------------------------------- /examples/vue-i18n-v8-vue2/src/main.ts: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import VueCompositionAPI from '@vue/composition-api' 3 | import { default as VueI18n, createI18n, castToVueI18n, isVueI18n8 } from '@intlify/vue-i18n-bridge' 4 | 5 | import App from './App.vue' 6 | 7 | Vue.use(VueCompositionAPI) 8 | Vue.use(VueI18n, { bridge: true }) 9 | 10 | console.log('isVueI18n8', isVueI18n8) 11 | 12 | const i18n = castToVueI18n( 13 | createI18n( 14 | { 15 | locale: 'en', 16 | messages: { 17 | en: { 18 | done: 'You did it!' 19 | } 20 | } 21 | }, 22 | VueI18n 23 | ) 24 | ) 25 | 26 | Vue.use(i18n) 27 | 28 | const app = new Vue({ 29 | i18n, 30 | render: h => h(App) 31 | }) 32 | 33 | app.$mount('#app') 34 | -------------------------------------------------------------------------------- /examples/vue-i18n-v8-vue2/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "baseUrl": "./", 4 | "target": "esnext", 5 | "useDefineForClassFields": true, 6 | "module": "esnext", 7 | "moduleResolution": "node", 8 | "isolatedModules": true, 9 | "strict": true, 10 | "jsx": "preserve", 11 | "sourceMap": true, 12 | "resolveJsonModule": true, 13 | "esModuleInterop": true, 14 | "paths": { 15 | "@/*": ["src/*"] 16 | }, 17 | "lib": ["esnext", "dom", "dom.iterable", "scripthost"], 18 | "skipLibCheck": true 19 | }, 20 | "vueCompilerOptions": { 21 | "experimentalCompatMode": 2 22 | }, 23 | "include": ["vite.config.*", "env.d.ts", "src/**/*", "src/**/*.vue"] 24 | } 25 | -------------------------------------------------------------------------------- /examples/vue-i18n-v8-vue2/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { fileURLToPath } from 'url' 2 | 3 | import { defineConfig } from 'vite' 4 | import legacy from '@vitejs/plugin-legacy' 5 | import { createVuePlugin as vue2 } from 'vite-plugin-vue2' 6 | import scriptSetup from 'unplugin-vue2-script-setup/vite' 7 | 8 | // https://vitejs.dev/config/ 9 | export default defineConfig({ 10 | plugins: [ 11 | vue2({ 12 | jsx: true 13 | }), 14 | scriptSetup(), 15 | legacy({ 16 | targets: ['ie >= 11'], 17 | additionalLegacyPolyfills: ['regenerator-runtime/runtime'] 18 | }) 19 | ], 20 | resolve: { 21 | alias: { 22 | '@': fileURLToPath(new URL('./src', import.meta.url)) 23 | } 24 | } 25 | }) 26 | -------------------------------------------------------------------------------- /examples/vue-i18n-v8-vue2/vitest.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vitest/config' 2 | 3 | export default defineConfig({ 4 | test: { 5 | globals: true, 6 | clearMocks: true, 7 | deps: { 8 | inline: [/vite-test-utils/] 9 | } 10 | } 11 | }) 12 | -------------------------------------------------------------------------------- /examples/vue-i18n-v9-vue3/README.md: -------------------------------------------------------------------------------- 1 | # vue-i18n-v9-vue3 2 | 3 | This project is Vue 3 & Vue I18n v9 example for `@intlify/vue-i18n-bridge` 4 | -------------------------------------------------------------------------------- /examples/vue-i18n-v9-vue3/env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | declare module '*.vue' { 4 | import { DefineComponent } from 'vue' 5 | // eslint-disable-next-line 6 | const component: DefineComponent<{}, {}, any> 7 | export default component 8 | } 9 | -------------------------------------------------------------------------------- /examples/vue-i18n-v9-vue3/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Vite App 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /examples/vue-i18n-v9-vue3/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vue-i18n-v9-vue3", 3 | "version": "0.0.0", 4 | "private": true, 5 | "scripts": { 6 | "dev": "vite", 7 | "build": "vue-tsc --noEmit && vite build", 8 | "preview": "vite preview --port 5050", 9 | "test": "vitest run specs", 10 | "typecheck": "vue-tsc --noEmit" 11 | }, 12 | "dependencies": { 13 | "vue": "^3.2.26", 14 | "vue-i18n": "9.2.2", 15 | "@intlify/vue-i18n-bridge": "0.5.0" 16 | }, 17 | "devDependencies": { 18 | "@types/node": "16.11.17", 19 | "@vitejs/plugin-vue": "2.0.1", 20 | "typescript": "4.5.4", 21 | "playwright": "1.38.0", 22 | "vite": "2.9.12", 23 | "vite-test-utils": "0.6.0", 24 | "vitest": "0.23.2", 25 | "vue-tsc": "0.30.1" 26 | } 27 | } -------------------------------------------------------------------------------- /examples/vue-i18n-v9-vue3/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intlify/bridging/feb740a8bae26a5b4fc38cc4b6f73fa353920a1f/examples/vue-i18n-v9-vue3/public/favicon.ico -------------------------------------------------------------------------------- /examples/vue-i18n-v9-vue3/specs/app.spec.ts: -------------------------------------------------------------------------------- 1 | import { test, expect } from 'vitest' 2 | import { setup, url, createPage } from 'vite-test-utils' 3 | 4 | await setup({ 5 | browser: true 6 | }) 7 | 8 | test('pages', async () => { 9 | const page = await createPage() 10 | await page.goto(url('/')) 11 | 12 | page.on('console', (...args) => console.log(...args)) 13 | 14 | const header = await page.locator('h1.green') 15 | expect(await header.textContent()).toBe('You did it!') 16 | }) 17 | -------------------------------------------------------------------------------- /examples/vue-i18n-v9-vue3/src/App.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 22 | 23 | 85 | -------------------------------------------------------------------------------- /examples/vue-i18n-v9-vue3/src/assets/base.css: -------------------------------------------------------------------------------- 1 | /* color palette from */ 2 | :root { 3 | --vt-c-white: #ffffff; 4 | --vt-c-white-soft: #f8f8f8; 5 | --vt-c-white-mute: #f2f2f2; 6 | 7 | --vt-c-black: #181818; 8 | --vt-c-black-soft: #222222; 9 | --vt-c-black-mute: #282828; 10 | 11 | --vt-c-indigo: #2c3e50; 12 | 13 | --vt-c-divider-light-1: rgba(60, 60, 60, 0.29); 14 | --vt-c-divider-light-2: rgba(60, 60, 60, 0.12); 15 | --vt-c-divider-dark-1: rgba(84, 84, 84, 0.65); 16 | --vt-c-divider-dark-2: rgba(84, 84, 84, 0.48); 17 | 18 | --vt-c-text-light-1: var(--vt-c-indigo); 19 | --vt-c-text-light-2: rgba(60, 60, 60, 0.66); 20 | --vt-c-text-dark-1: var(--vt-c-white); 21 | --vt-c-text-dark-2: rgba(235, 235, 235, 0.64); 22 | } 23 | 24 | /* semantic color variables for this project */ 25 | :root { 26 | --color-background: var(--vt-c-white); 27 | --color-background-soft: var(--vt-c-white-soft); 28 | --color-background-mute: var(--vt-c-white-mute); 29 | 30 | --color-border: var(--vt-c-divider-light-2); 31 | --color-border-hover: var(--vt-c-divider-light-1); 32 | 33 | --color-heading: var(--vt-c-text-light-1); 34 | --color-text: var(--vt-c-text-light-1); 35 | 36 | --section-gap: 160px; 37 | } 38 | 39 | @media (prefers-color-scheme: dark) { 40 | :root { 41 | --color-background: var(--vt-c-black); 42 | --color-background-soft: var(--vt-c-black-soft); 43 | --color-background-mute: var(--vt-c-black-mute); 44 | 45 | --color-border: var(--vt-c-divider-dark-2); 46 | --color-border-hover: var(--vt-c-divider-dark-1); 47 | 48 | --color-heading: var(--vt-c-text-dark-1); 49 | --color-text: var(--vt-c-text-dark-2); 50 | } 51 | } 52 | 53 | *, 54 | *::before, 55 | *::after { 56 | box-sizing: border-box; 57 | margin: 0; 58 | position: relative; 59 | font-weight: normal; 60 | } 61 | 62 | body { 63 | min-height: 100vh; 64 | color: var(--color-text); 65 | background: var(--color-background); 66 | transition: color 0.5s, background-color 0.5s; 67 | line-height: 1.6; 68 | font-family: Inter, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, 69 | Cantarell, 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif; 70 | font-size: 15px; 71 | text-rendering: optimizeLegibility; 72 | -webkit-font-smoothing: antialiased; 73 | -moz-osx-font-smoothing: grayscale; 74 | } 75 | -------------------------------------------------------------------------------- /examples/vue-i18n-v9-vue3/src/assets/logo.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /examples/vue-i18n-v9-vue3/src/components/HelloWorld.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 17 | 18 | 41 | -------------------------------------------------------------------------------- /examples/vue-i18n-v9-vue3/src/components/TheWelcome.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 81 | -------------------------------------------------------------------------------- /examples/vue-i18n-v9-vue3/src/components/WelcomeItem.vue: -------------------------------------------------------------------------------- 1 | 14 | 15 | 87 | -------------------------------------------------------------------------------- /examples/vue-i18n-v9-vue3/src/components/icons/IconCommunity.vue: -------------------------------------------------------------------------------- 1 | 8 | -------------------------------------------------------------------------------- /examples/vue-i18n-v9-vue3/src/components/icons/IconDocumentation.vue: -------------------------------------------------------------------------------- 1 | 8 | -------------------------------------------------------------------------------- /examples/vue-i18n-v9-vue3/src/components/icons/IconEcosystem.vue: -------------------------------------------------------------------------------- 1 | 8 | -------------------------------------------------------------------------------- /examples/vue-i18n-v9-vue3/src/components/icons/IconSupport.vue: -------------------------------------------------------------------------------- 1 | 8 | -------------------------------------------------------------------------------- /examples/vue-i18n-v9-vue3/src/components/icons/IconTooling.vue: -------------------------------------------------------------------------------- 1 | 2 | 20 | -------------------------------------------------------------------------------- /examples/vue-i18n-v9-vue3/src/main.ts: -------------------------------------------------------------------------------- 1 | import { createApp } from 'vue' 2 | import App from './App.vue' 3 | import { createI18n, isVueI18n8 } from '@intlify/vue-i18n-bridge' 4 | 5 | console.log('isVueI18n8', isVueI18n8) 6 | 7 | const i18n = createI18n({ 8 | legacy: false, 9 | locale: 'en', 10 | messages: { 11 | en: { 12 | done: 'You did it!' 13 | } 14 | } 15 | }) 16 | 17 | createApp(App).use(i18n).mount('#app') 18 | -------------------------------------------------------------------------------- /examples/vue-i18n-v9-vue3/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "baseUrl": "./", 4 | "target": "esnext", 5 | "useDefineForClassFields": true, 6 | "module": "esnext", 7 | "moduleResolution": "node", 8 | "isolatedModules": true, 9 | "strict": true, 10 | "jsx": "preserve", 11 | "sourceMap": true, 12 | "resolveJsonModule": true, 13 | "esModuleInterop": true, 14 | "paths": { 15 | "@/*": ["src/*"] 16 | }, 17 | "lib": ["esnext", "dom", "dom.iterable", "scripthost"], 18 | "skipLibCheck": true 19 | }, 20 | "include": ["vite.config.*", "env.d.ts", "src/**/*", "src/**/*.vue"] 21 | } 22 | -------------------------------------------------------------------------------- /examples/vue-i18n-v9-vue3/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { fileURLToPath } from 'url' 2 | 3 | import { defineConfig } from 'vite' 4 | import vue from '@vitejs/plugin-vue' 5 | 6 | // https://vitejs.dev/config/ 7 | export default defineConfig({ 8 | plugins: [vue()], 9 | resolve: { 10 | alias: { 11 | '@': fileURLToPath(new URL('./src', import.meta.url)) 12 | } 13 | } 14 | }) 15 | -------------------------------------------------------------------------------- /examples/vue-i18n-v9-vue3/vitest.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vitest/config' 2 | 3 | export default defineConfig({ 4 | test: { 5 | globals: true, 6 | clearMocks: true, 7 | deps: { 8 | inline: [/vite-test-utils/] 9 | } 10 | } 11 | }) 12 | -------------------------------------------------------------------------------- /examples/vue-router-v3-vue2/README.md: -------------------------------------------------------------------------------- 1 | # vue-router-v3-vue2 2 | 3 | This project is Vue 2 & Vue Router v3.5 example for `@intlify/vue-router-bridge` 4 | -------------------------------------------------------------------------------- /examples/vue-router-v3-vue2/env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | declare module '*.vue' { 4 | import Vue from 'vue' 5 | export default Vue 6 | } 7 | 8 | declare global { 9 | namespace JSX { 10 | interface Element extends VNode {} 11 | interface ElementClass extends Vue {} 12 | interface IntrinsicElements { 13 | [elem: string]: any 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /examples/vue-router-v3-vue2/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Vite App 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /examples/vue-router-v3-vue2/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vue-router-v3-vue2", 3 | "version": "0.0.0", 4 | "scripts": { 5 | "dev": "vite", 6 | "build": "vue-tsc --noEmit && vite build", 7 | "preview": "vite preview --port 5050", 8 | "test": "vitest run specs", 9 | "typecheck": "vue-tsc --noEmit" 10 | }, 11 | "dependencies": { 12 | "@vue/composition-api": "1.4.9", 13 | "vue": "2.6.14", 14 | "vue-router": "3.5.2", 15 | "@intlify/vue-router-bridge": "0.5.0" 16 | }, 17 | "devDependencies": { 18 | "@types/node": "16.11.17", 19 | "@vitejs/plugin-legacy": "1.6.3", 20 | "@vue/runtime-dom": "3.2.22", 21 | "typescript": "4.5.4", 22 | "unplugin-vue2-script-setup": "0.7.1", 23 | "playwright": "1.38.0", 24 | "vite": "2.9.12", 25 | "vite-test-utils": "0.6.0", 26 | "vitest": "0.23.2", 27 | "vite-plugin-vue2": "2.0.2", 28 | "vue-template-compiler": "2.6.14", 29 | "vue-tsc": "0.30.1" 30 | } 31 | } -------------------------------------------------------------------------------- /examples/vue-router-v3-vue2/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intlify/bridging/feb740a8bae26a5b4fc38cc4b6f73fa353920a1f/examples/vue-router-v3-vue2/public/favicon.ico -------------------------------------------------------------------------------- /examples/vue-router-v3-vue2/specs/app.spec.ts: -------------------------------------------------------------------------------- 1 | import { test, expect } from 'vitest' 2 | import { setup, createPage, url } from 'vite-test-utils' 3 | 4 | await setup({ 5 | browser: true 6 | }) 7 | 8 | test('pages', async () => { 9 | const page = await createPage() 10 | await page.goto(url('/')) 11 | 12 | page.on('console', (...args) => console.log(...args)) 13 | 14 | const aboutLink = await page.locator('nav a[href="/about"]') 15 | await aboutLink.click() 16 | const about = await page.locator('.about h1') 17 | expect(await about.textContent()).toBe('This is an about page') 18 | }) 19 | -------------------------------------------------------------------------------- /examples/vue-router-v3-vue2/src/App.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 23 | 24 | 121 | -------------------------------------------------------------------------------- /examples/vue-router-v3-vue2/src/assets/base.css: -------------------------------------------------------------------------------- 1 | /* color palette from */ 2 | :root { 3 | --vt-c-white: #ffffff; 4 | --vt-c-white-soft: #f8f8f8; 5 | --vt-c-white-mute: #f2f2f2; 6 | 7 | --vt-c-black: #181818; 8 | --vt-c-black-soft: #222222; 9 | --vt-c-black-mute: #282828; 10 | 11 | --vt-c-indigo: #2c3e50; 12 | 13 | --vt-c-divider-light-1: rgba(60, 60, 60, 0.29); 14 | --vt-c-divider-light-2: rgba(60, 60, 60, 0.12); 15 | --vt-c-divider-dark-1: rgba(84, 84, 84, 0.65); 16 | --vt-c-divider-dark-2: rgba(84, 84, 84, 0.48); 17 | 18 | --vt-c-text-light-1: var(--vt-c-indigo); 19 | --vt-c-text-light-2: rgba(60, 60, 60, 0.66); 20 | --vt-c-text-dark-1: var(--vt-c-white); 21 | --vt-c-text-dark-2: rgba(235, 235, 235, 0.64); 22 | } 23 | 24 | /* semantic color variables for this project */ 25 | :root { 26 | --color-background: var(--vt-c-white); 27 | --color-background-soft: var(--vt-c-white-soft); 28 | --color-background-mute: var(--vt-c-white-mute); 29 | 30 | --color-border: var(--vt-c-divider-light-2); 31 | --color-border-hover: var(--vt-c-divider-light-1); 32 | 33 | --color-heading: var(--vt-c-text-light-1); 34 | --color-text: var(--vt-c-text-light-1); 35 | 36 | --section-gap: 160px; 37 | } 38 | 39 | @media (prefers-color-scheme: dark) { 40 | :root { 41 | --color-background: var(--vt-c-black); 42 | --color-background-soft: var(--vt-c-black-soft); 43 | --color-background-mute: var(--vt-c-black-mute); 44 | 45 | --color-border: var(--vt-c-divider-dark-2); 46 | --color-border-hover: var(--vt-c-divider-dark-1); 47 | 48 | --color-heading: var(--vt-c-text-dark-1); 49 | --color-text: var(--vt-c-text-dark-2); 50 | } 51 | } 52 | 53 | *, 54 | *::before, 55 | *::after { 56 | box-sizing: border-box; 57 | margin: 0; 58 | position: relative; 59 | font-weight: normal; 60 | } 61 | 62 | body { 63 | min-height: 100vh; 64 | color: var(--color-text); 65 | background: var(--color-background); 66 | transition: color 0.5s, background-color 0.5s; 67 | line-height: 1.6; 68 | font-family: Inter, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, 69 | Cantarell, 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif; 70 | font-size: 15px; 71 | text-rendering: optimizeLegibility; 72 | -webkit-font-smoothing: antialiased; 73 | -moz-osx-font-smoothing: grayscale; 74 | } 75 | -------------------------------------------------------------------------------- /examples/vue-router-v3-vue2/src/assets/logo.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /examples/vue-router-v3-vue2/src/components/HelloWorld.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 17 | 18 | 42 | -------------------------------------------------------------------------------- /examples/vue-router-v3-vue2/src/components/TheWelcome.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 84 | -------------------------------------------------------------------------------- /examples/vue-router-v3-vue2/src/components/WelcomeItem.vue: -------------------------------------------------------------------------------- 1 | 14 | 15 | 87 | -------------------------------------------------------------------------------- /examples/vue-router-v3-vue2/src/components/icons/IconCommunity.vue: -------------------------------------------------------------------------------- 1 | 8 | -------------------------------------------------------------------------------- /examples/vue-router-v3-vue2/src/components/icons/IconDocumentation.vue: -------------------------------------------------------------------------------- 1 | 8 | -------------------------------------------------------------------------------- /examples/vue-router-v3-vue2/src/components/icons/IconEcosystem.vue: -------------------------------------------------------------------------------- 1 | 8 | -------------------------------------------------------------------------------- /examples/vue-router-v3-vue2/src/components/icons/IconSupport.vue: -------------------------------------------------------------------------------- 1 | 8 | -------------------------------------------------------------------------------- /examples/vue-router-v3-vue2/src/components/icons/IconTooling.vue: -------------------------------------------------------------------------------- 1 | 2 | 20 | -------------------------------------------------------------------------------- /examples/vue-router-v3-vue2/src/main.ts: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import VueCompositionAPI from '@vue/composition-api' 3 | 4 | import App from './App.vue' 5 | import router from './router' 6 | 7 | Vue.use(VueCompositionAPI) 8 | 9 | const app = new Vue({ 10 | router, 11 | render: h => h(App) 12 | }) 13 | 14 | app.$mount('#app') 15 | -------------------------------------------------------------------------------- /examples/vue-router-v3-vue2/src/router/index.ts: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import { default as VueRouter, isVueRouter3 } from '@intlify/vue-router-bridge' 3 | import HomeView from '../views/HomeView.vue' 4 | 5 | Vue.use(VueRouter) 6 | 7 | console.log('isVueRouter3', isVueRouter3) 8 | 9 | const router = new VueRouter({ 10 | mode: 'history', 11 | base: import.meta.env.BASE_URL, 12 | routes: [ 13 | { 14 | path: '/', 15 | name: 'home', 16 | component: HomeView 17 | }, 18 | { 19 | path: '/about', 20 | name: 'about', 21 | // route level code-splitting 22 | // this generates a separate chunk (About.[hash].js) for this route 23 | // which is lazy-loaded when the route is visited. 24 | component: () => import('../views/AboutView.vue') 25 | } 26 | ] 27 | }) 28 | 29 | export default router 30 | -------------------------------------------------------------------------------- /examples/vue-router-v3-vue2/src/views/AboutView.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 16 | -------------------------------------------------------------------------------- /examples/vue-router-v3-vue2/src/views/HomeView.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 10 | -------------------------------------------------------------------------------- /examples/vue-router-v3-vue2/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "baseUrl": "./", 4 | "target": "esnext", 5 | "useDefineForClassFields": true, 6 | "module": "esnext", 7 | "moduleResolution": "node", 8 | "isolatedModules": true, 9 | "strict": true, 10 | "jsx": "preserve", 11 | "sourceMap": true, 12 | "resolveJsonModule": true, 13 | "esModuleInterop": true, 14 | "paths": { 15 | "@/*": ["src/*"] 16 | }, 17 | "lib": ["esnext", "dom", "dom.iterable", "scripthost"], 18 | "skipLibCheck": true 19 | }, 20 | "vueCompilerOptions": { 21 | "experimentalCompatMode": 2 22 | }, 23 | "include": ["vite.config.*", "env.d.ts", "src/**/*", "src/**/*.vue"] 24 | } 25 | -------------------------------------------------------------------------------- /examples/vue-router-v3-vue2/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { fileURLToPath } from 'url' 2 | 3 | import { defineConfig } from 'vite' 4 | import legacy from '@vitejs/plugin-legacy' 5 | import { createVuePlugin as vue2 } from 'vite-plugin-vue2' 6 | import scriptSetup from 'unplugin-vue2-script-setup/vite' 7 | 8 | // https://vitejs.dev/config/ 9 | export default defineConfig({ 10 | plugins: [ 11 | vue2({ 12 | jsx: true 13 | }), 14 | scriptSetup(), 15 | legacy({ 16 | targets: ['ie >= 11'], 17 | additionalLegacyPolyfills: ['regenerator-runtime/runtime'] 18 | }) 19 | ], 20 | resolve: { 21 | alias: { 22 | '@': fileURLToPath(new URL('./src', import.meta.url)) 23 | } 24 | } 25 | }) 26 | -------------------------------------------------------------------------------- /examples/vue-router-v3-vue2/vitest.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vitest/config' 2 | 3 | export default defineConfig({ 4 | test: { 5 | globals: true, 6 | clearMocks: true, 7 | deps: { 8 | inline: [/vite-test-utils/] 9 | } 10 | } 11 | }) 12 | -------------------------------------------------------------------------------- /examples/vue-router-v36-vue2/README.md: -------------------------------------------------------------------------------- 1 | # vue-router-v36-vue2 2 | 3 | This project is Vue 2.7 & Vue Router v3.6 example for `@intlify/vue-router-bridge` 4 | -------------------------------------------------------------------------------- /examples/vue-router-v36-vue2/env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | declare module '*.vue' { 4 | import Vue from 'vue' 5 | export default Vue 6 | } 7 | 8 | declare global { 9 | namespace JSX { 10 | interface Element extends VNode {} 11 | interface ElementClass extends Vue {} 12 | interface IntrinsicElements { 13 | [elem: string]: any 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /examples/vue-router-v36-vue2/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Vite App 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /examples/vue-router-v36-vue2/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vue-router-v36-vue2", 3 | "version": "0.0.0", 4 | "scripts": { 5 | "dev": "vite", 6 | "build": "vue-tsc --noEmit && vite build", 7 | "preview": "vite preview --port 5050", 8 | "test": "vitest run specs", 9 | "typecheck": "vue-tsc --noEmit" 10 | }, 11 | "dependencies": { 12 | "@vue/composition-api": "1.4.9", 13 | "vue": "2.7.10", 14 | "vue-router": "3.6", 15 | "@intlify/vue-router-bridge": "0.5.0" 16 | }, 17 | "devDependencies": { 18 | "@types/node": "16.11.17", 19 | "@vitejs/plugin-legacy": "1.6.3", 20 | "@vue/runtime-dom": "3.2.22", 21 | "typescript": "4.5.4", 22 | "unplugin-vue2-script-setup": "0.7.1", 23 | "playwright": "1.38.0", 24 | "vite": "2.9.12", 25 | "vite-test-utils": "0.6.0", 26 | "vitest": "0.23.2", 27 | "vite-plugin-vue2": "2.0.2", 28 | "vue-template-compiler": "2.7.10", 29 | "vue-tsc": "0.30.1" 30 | } 31 | } -------------------------------------------------------------------------------- /examples/vue-router-v36-vue2/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intlify/bridging/feb740a8bae26a5b4fc38cc4b6f73fa353920a1f/examples/vue-router-v36-vue2/public/favicon.ico -------------------------------------------------------------------------------- /examples/vue-router-v36-vue2/specs/app.spec.ts: -------------------------------------------------------------------------------- 1 | import { test, expect } from 'vitest' 2 | import { setup, createPage, url } from 'vite-test-utils' 3 | 4 | await setup({ 5 | browser: true 6 | }) 7 | 8 | test('pages', async () => { 9 | const page = await createPage() 10 | await page.goto(url('/')) 11 | 12 | page.on('console', (...args) => console.log(...args)) 13 | 14 | const aboutLink = await page.locator('nav a[href="/about"]') 15 | await aboutLink.click() 16 | const about = await page.locator('.about h1') 17 | expect(await about.textContent()).toBe('This is an about page') 18 | }) 19 | -------------------------------------------------------------------------------- /examples/vue-router-v36-vue2/src/App.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 23 | 24 | 121 | -------------------------------------------------------------------------------- /examples/vue-router-v36-vue2/src/assets/base.css: -------------------------------------------------------------------------------- 1 | /* color palette from */ 2 | :root { 3 | --vt-c-white: #ffffff; 4 | --vt-c-white-soft: #f8f8f8; 5 | --vt-c-white-mute: #f2f2f2; 6 | 7 | --vt-c-black: #181818; 8 | --vt-c-black-soft: #222222; 9 | --vt-c-black-mute: #282828; 10 | 11 | --vt-c-indigo: #2c3e50; 12 | 13 | --vt-c-divider-light-1: rgba(60, 60, 60, 0.29); 14 | --vt-c-divider-light-2: rgba(60, 60, 60, 0.12); 15 | --vt-c-divider-dark-1: rgba(84, 84, 84, 0.65); 16 | --vt-c-divider-dark-2: rgba(84, 84, 84, 0.48); 17 | 18 | --vt-c-text-light-1: var(--vt-c-indigo); 19 | --vt-c-text-light-2: rgba(60, 60, 60, 0.66); 20 | --vt-c-text-dark-1: var(--vt-c-white); 21 | --vt-c-text-dark-2: rgba(235, 235, 235, 0.64); 22 | } 23 | 24 | /* semantic color variables for this project */ 25 | :root { 26 | --color-background: var(--vt-c-white); 27 | --color-background-soft: var(--vt-c-white-soft); 28 | --color-background-mute: var(--vt-c-white-mute); 29 | 30 | --color-border: var(--vt-c-divider-light-2); 31 | --color-border-hover: var(--vt-c-divider-light-1); 32 | 33 | --color-heading: var(--vt-c-text-light-1); 34 | --color-text: var(--vt-c-text-light-1); 35 | 36 | --section-gap: 160px; 37 | } 38 | 39 | @media (prefers-color-scheme: dark) { 40 | :root { 41 | --color-background: var(--vt-c-black); 42 | --color-background-soft: var(--vt-c-black-soft); 43 | --color-background-mute: var(--vt-c-black-mute); 44 | 45 | --color-border: var(--vt-c-divider-dark-2); 46 | --color-border-hover: var(--vt-c-divider-dark-1); 47 | 48 | --color-heading: var(--vt-c-text-dark-1); 49 | --color-text: var(--vt-c-text-dark-2); 50 | } 51 | } 52 | 53 | *, 54 | *::before, 55 | *::after { 56 | box-sizing: border-box; 57 | margin: 0; 58 | position: relative; 59 | font-weight: normal; 60 | } 61 | 62 | body { 63 | min-height: 100vh; 64 | color: var(--color-text); 65 | background: var(--color-background); 66 | transition: color 0.5s, background-color 0.5s; 67 | line-height: 1.6; 68 | font-family: Inter, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, 69 | Cantarell, 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif; 70 | font-size: 15px; 71 | text-rendering: optimizeLegibility; 72 | -webkit-font-smoothing: antialiased; 73 | -moz-osx-font-smoothing: grayscale; 74 | } 75 | -------------------------------------------------------------------------------- /examples/vue-router-v36-vue2/src/assets/logo.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /examples/vue-router-v36-vue2/src/components/HelloWorld.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 17 | 18 | 42 | -------------------------------------------------------------------------------- /examples/vue-router-v36-vue2/src/components/TheWelcome.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 84 | -------------------------------------------------------------------------------- /examples/vue-router-v36-vue2/src/components/WelcomeItem.vue: -------------------------------------------------------------------------------- 1 | 14 | 15 | 87 | -------------------------------------------------------------------------------- /examples/vue-router-v36-vue2/src/components/icons/IconCommunity.vue: -------------------------------------------------------------------------------- 1 | 8 | -------------------------------------------------------------------------------- /examples/vue-router-v36-vue2/src/components/icons/IconDocumentation.vue: -------------------------------------------------------------------------------- 1 | 8 | -------------------------------------------------------------------------------- /examples/vue-router-v36-vue2/src/components/icons/IconEcosystem.vue: -------------------------------------------------------------------------------- 1 | 8 | -------------------------------------------------------------------------------- /examples/vue-router-v36-vue2/src/components/icons/IconSupport.vue: -------------------------------------------------------------------------------- 1 | 8 | -------------------------------------------------------------------------------- /examples/vue-router-v36-vue2/src/components/icons/IconTooling.vue: -------------------------------------------------------------------------------- 1 | 2 | 20 | -------------------------------------------------------------------------------- /examples/vue-router-v36-vue2/src/main.ts: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import VueCompositionAPI from '@vue/composition-api' 3 | 4 | import App from './App.vue' 5 | import router from './router' 6 | 7 | Vue.use(VueCompositionAPI) 8 | 9 | const app = new Vue({ 10 | router, 11 | render: h => h(App) 12 | }) 13 | 14 | app.$mount('#app') 15 | -------------------------------------------------------------------------------- /examples/vue-router-v36-vue2/src/router/index.ts: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import { default as VueRouter, isVueRouter3 } from '@intlify/vue-router-bridge' 3 | import HomeView from '../views/HomeView.vue' 4 | 5 | Vue.use(VueRouter) 6 | 7 | console.log('isVueRouter3', isVueRouter3) 8 | 9 | const router = new VueRouter({ 10 | mode: 'history', 11 | base: import.meta.env.BASE_URL, 12 | routes: [ 13 | { 14 | path: '/', 15 | name: 'home', 16 | component: HomeView 17 | }, 18 | { 19 | path: '/about', 20 | name: 'about', 21 | // route level code-splitting 22 | // this generates a separate chunk (About.[hash].js) for this route 23 | // which is lazy-loaded when the route is visited. 24 | component: () => import('../views/AboutView.vue') 25 | } 26 | ] 27 | }) 28 | 29 | export default router 30 | -------------------------------------------------------------------------------- /examples/vue-router-v36-vue2/src/views/AboutView.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 16 | -------------------------------------------------------------------------------- /examples/vue-router-v36-vue2/src/views/HomeView.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 10 | -------------------------------------------------------------------------------- /examples/vue-router-v36-vue2/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "baseUrl": "./", 4 | "target": "esnext", 5 | "useDefineForClassFields": true, 6 | "module": "esnext", 7 | "moduleResolution": "node", 8 | "isolatedModules": true, 9 | "strict": true, 10 | "jsx": "preserve", 11 | "sourceMap": true, 12 | "resolveJsonModule": true, 13 | "esModuleInterop": true, 14 | "paths": { 15 | "@/*": ["src/*"] 16 | }, 17 | "lib": ["esnext", "dom", "dom.iterable", "scripthost"], 18 | "skipLibCheck": true 19 | }, 20 | "vueCompilerOptions": { 21 | "experimentalCompatMode": 2 22 | }, 23 | "include": ["vite.config.*", "env.d.ts", "src/**/*", "src/**/*.vue"] 24 | } 25 | -------------------------------------------------------------------------------- /examples/vue-router-v36-vue2/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { fileURLToPath } from 'url' 2 | 3 | import { defineConfig } from 'vite' 4 | import legacy from '@vitejs/plugin-legacy' 5 | import { createVuePlugin as vue2 } from 'vite-plugin-vue2' 6 | import scriptSetup from 'unplugin-vue2-script-setup/vite' 7 | 8 | // https://vitejs.dev/config/ 9 | export default defineConfig({ 10 | plugins: [ 11 | vue2({ 12 | jsx: true 13 | }), 14 | scriptSetup(), 15 | legacy({ 16 | targets: ['ie >= 11'], 17 | additionalLegacyPolyfills: ['regenerator-runtime/runtime'] 18 | }) 19 | ], 20 | resolve: { 21 | alias: { 22 | '@': fileURLToPath(new URL('./src', import.meta.url)) 23 | } 24 | } 25 | }) 26 | -------------------------------------------------------------------------------- /examples/vue-router-v36-vue2/vitest.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vitest/config' 2 | 3 | export default defineConfig({ 4 | test: { 5 | globals: true, 6 | clearMocks: true, 7 | deps: { 8 | inline: [/vite-test-utils/] 9 | } 10 | } 11 | }) 12 | -------------------------------------------------------------------------------- /examples/vue-router-v4-vue3/README.md: -------------------------------------------------------------------------------- 1 | # vue-router-v4-vue3 2 | 3 | This project is Vue 3 & Vue Router v4 example for `@intlify/vue-router-bridge` 4 | -------------------------------------------------------------------------------- /examples/vue-router-v4-vue3/env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | declare module '*.vue' { 4 | import { DefineComponent } from 'vue' 5 | // eslint-disable-next-line 6 | const component: DefineComponent<{}, {}, any> 7 | export default component 8 | } 9 | -------------------------------------------------------------------------------- /examples/vue-router-v4-vue3/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Vite App 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /examples/vue-router-v4-vue3/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vue-router-v4-vue3", 3 | "version": "0.0.0", 4 | "scripts": { 5 | "dev": "vite", 6 | "build": "vue-tsc --noEmit && vite build", 7 | "preview": "vite preview --port 5050", 8 | "test": "vitest run specs", 9 | "typecheck": "vue-tsc --noEmit" 10 | }, 11 | "dependencies": { 12 | "vue": "^3.2.26", 13 | "vue-router": "4.1.2", 14 | "@intlify/vue-router-bridge": "0.5.0" 15 | }, 16 | "devDependencies": { 17 | "@types/node": "16.11.17", 18 | "@vitejs/plugin-vue": "2.0.1", 19 | "typescript": "4.5.4", 20 | "playwright": "1.38.0", 21 | "vite": "2.9.12", 22 | "vite-test-utils": "0.6.0", 23 | "vitest": "0.23.2", 24 | "vue-tsc": "0.30.1" 25 | } 26 | } -------------------------------------------------------------------------------- /examples/vue-router-v4-vue3/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intlify/bridging/feb740a8bae26a5b4fc38cc4b6f73fa353920a1f/examples/vue-router-v4-vue3/public/favicon.ico -------------------------------------------------------------------------------- /examples/vue-router-v4-vue3/specs/app.spec.ts: -------------------------------------------------------------------------------- 1 | import { test, expect } from 'vitest' 2 | import { setup, createPage, url } from 'vite-test-utils' 3 | 4 | await setup({ 5 | browser: true 6 | }) 7 | 8 | test('pages', async () => { 9 | const page = await createPage() 10 | await page.goto(url('/')) 11 | 12 | page.on('console', (...args) => console.log(...args)) 13 | 14 | const aboutLink = await page.locator('nav a[href="/about"]') 15 | await aboutLink.click() 16 | const about = await page.locator('.about h1') 17 | expect(await about.textContent()).toBe('This is an about page') 18 | }) 19 | -------------------------------------------------------------------------------- /examples/vue-router-v4-vue3/src/App.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 21 | 22 | 119 | -------------------------------------------------------------------------------- /examples/vue-router-v4-vue3/src/assets/base.css: -------------------------------------------------------------------------------- 1 | /* color palette from */ 2 | :root { 3 | --vt-c-white: #ffffff; 4 | --vt-c-white-soft: #f8f8f8; 5 | --vt-c-white-mute: #f2f2f2; 6 | 7 | --vt-c-black: #181818; 8 | --vt-c-black-soft: #222222; 9 | --vt-c-black-mute: #282828; 10 | 11 | --vt-c-indigo: #2c3e50; 12 | 13 | --vt-c-divider-light-1: rgba(60, 60, 60, 0.29); 14 | --vt-c-divider-light-2: rgba(60, 60, 60, 0.12); 15 | --vt-c-divider-dark-1: rgba(84, 84, 84, 0.65); 16 | --vt-c-divider-dark-2: rgba(84, 84, 84, 0.48); 17 | 18 | --vt-c-text-light-1: var(--vt-c-indigo); 19 | --vt-c-text-light-2: rgba(60, 60, 60, 0.66); 20 | --vt-c-text-dark-1: var(--vt-c-white); 21 | --vt-c-text-dark-2: rgba(235, 235, 235, 0.64); 22 | } 23 | 24 | /* semantic color variables for this project */ 25 | :root { 26 | --color-background: var(--vt-c-white); 27 | --color-background-soft: var(--vt-c-white-soft); 28 | --color-background-mute: var(--vt-c-white-mute); 29 | 30 | --color-border: var(--vt-c-divider-light-2); 31 | --color-border-hover: var(--vt-c-divider-light-1); 32 | 33 | --color-heading: var(--vt-c-text-light-1); 34 | --color-text: var(--vt-c-text-light-1); 35 | 36 | --section-gap: 160px; 37 | } 38 | 39 | @media (prefers-color-scheme: dark) { 40 | :root { 41 | --color-background: var(--vt-c-black); 42 | --color-background-soft: var(--vt-c-black-soft); 43 | --color-background-mute: var(--vt-c-black-mute); 44 | 45 | --color-border: var(--vt-c-divider-dark-2); 46 | --color-border-hover: var(--vt-c-divider-dark-1); 47 | 48 | --color-heading: var(--vt-c-text-dark-1); 49 | --color-text: var(--vt-c-text-dark-2); 50 | } 51 | } 52 | 53 | *, 54 | *::before, 55 | *::after { 56 | box-sizing: border-box; 57 | margin: 0; 58 | position: relative; 59 | font-weight: normal; 60 | } 61 | 62 | body { 63 | min-height: 100vh; 64 | color: var(--color-text); 65 | background: var(--color-background); 66 | transition: color 0.5s, background-color 0.5s; 67 | line-height: 1.6; 68 | font-family: Inter, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, 69 | Cantarell, 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif; 70 | font-size: 15px; 71 | text-rendering: optimizeLegibility; 72 | -webkit-font-smoothing: antialiased; 73 | -moz-osx-font-smoothing: grayscale; 74 | } 75 | -------------------------------------------------------------------------------- /examples/vue-router-v4-vue3/src/assets/logo.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /examples/vue-router-v4-vue3/src/components/HelloWorld.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 17 | 18 | 41 | -------------------------------------------------------------------------------- /examples/vue-router-v4-vue3/src/components/TheWelcome.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 81 | -------------------------------------------------------------------------------- /examples/vue-router-v4-vue3/src/components/WelcomeItem.vue: -------------------------------------------------------------------------------- 1 | 14 | 15 | 87 | -------------------------------------------------------------------------------- /examples/vue-router-v4-vue3/src/components/icons/IconCommunity.vue: -------------------------------------------------------------------------------- 1 | 8 | -------------------------------------------------------------------------------- /examples/vue-router-v4-vue3/src/components/icons/IconDocumentation.vue: -------------------------------------------------------------------------------- 1 | 8 | -------------------------------------------------------------------------------- /examples/vue-router-v4-vue3/src/components/icons/IconEcosystem.vue: -------------------------------------------------------------------------------- 1 | 8 | -------------------------------------------------------------------------------- /examples/vue-router-v4-vue3/src/components/icons/IconSupport.vue: -------------------------------------------------------------------------------- 1 | 8 | -------------------------------------------------------------------------------- /examples/vue-router-v4-vue3/src/components/icons/IconTooling.vue: -------------------------------------------------------------------------------- 1 | 2 | 20 | -------------------------------------------------------------------------------- /examples/vue-router-v4-vue3/src/main.ts: -------------------------------------------------------------------------------- 1 | import { createApp } from 'vue' 2 | import App from './App.vue' 3 | import router from './router' 4 | 5 | const app = createApp(App) 6 | 7 | app.use(router) 8 | 9 | app.mount('#app') 10 | -------------------------------------------------------------------------------- /examples/vue-router-v4-vue3/src/router/index.ts: -------------------------------------------------------------------------------- 1 | import { createRouter, createWebHistory, isVueRouter3 } from '@intlify/vue-router-bridge' 2 | import HomeView from '../views/HomeView.vue' 3 | 4 | console.log('isVueRouter3', isVueRouter3) 5 | 6 | const router = createRouter({ 7 | history: createWebHistory(import.meta.env.BASE_URL), 8 | routes: [ 9 | { 10 | path: '/', 11 | name: 'home', 12 | component: HomeView 13 | }, 14 | { 15 | path: '/about', 16 | name: 'about', 17 | // route level code-splitting 18 | // this generates a separate chunk (About.[hash].js) for this route 19 | // which is lazy-loaded when the route is visited. 20 | component: () => import('../views/AboutView.vue') 21 | } 22 | ] 23 | }) 24 | 25 | export default router 26 | -------------------------------------------------------------------------------- /examples/vue-router-v4-vue3/src/views/AboutView.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 16 | -------------------------------------------------------------------------------- /examples/vue-router-v4-vue3/src/views/HomeView.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 10 | -------------------------------------------------------------------------------- /examples/vue-router-v4-vue3/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "baseUrl": "./", 4 | "target": "esnext", 5 | "useDefineForClassFields": true, 6 | "module": "esnext", 7 | "moduleResolution": "node", 8 | "isolatedModules": true, 9 | "strict": true, 10 | "jsx": "preserve", 11 | "sourceMap": true, 12 | "resolveJsonModule": true, 13 | "esModuleInterop": true, 14 | "paths": { 15 | "@/*": ["src/*"] 16 | }, 17 | "lib": ["esnext", "dom", "dom.iterable", "scripthost"], 18 | "skipLibCheck": true 19 | }, 20 | "include": ["vite.config.*", "env.d.ts", "src/**/*", "src/**/*.vue"] 21 | } 22 | -------------------------------------------------------------------------------- /examples/vue-router-v4-vue3/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { fileURLToPath } from 'url' 2 | 3 | import { defineConfig } from 'vite' 4 | import vue from '@vitejs/plugin-vue' 5 | 6 | // https://vitejs.dev/config/ 7 | export default defineConfig({ 8 | plugins: [vue()], 9 | resolve: { 10 | alias: { 11 | '@': fileURLToPath(new URL('./src', import.meta.url)) 12 | } 13 | } 14 | }) 15 | -------------------------------------------------------------------------------- /examples/vue-router-v4-vue3/vitest.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vitest/config' 2 | 3 | export default defineConfig({ 4 | test: { 5 | globals: true, 6 | clearMocks: true, 7 | deps: { 8 | inline: [/vite-test-utils/] 9 | } 10 | } 11 | }) 12 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@intlify/bridging", 3 | "description": "Utilities that provide compatibility for Vue 2 & Vue 3", 4 | "version": "1.1.0", 5 | "author": { 6 | "name": "kazuya kawaguchi", 7 | "email": "kawakazu80@gmail.com" 8 | }, 9 | "bugs": { 10 | "url": "https://github.com/inlitify/bridging/issues" 11 | }, 12 | "devDependencies": { 13 | "@secretlint/secretlint-rule-preset-recommend": "^7.0.7", 14 | "@types/js-yaml": "^4.0.5", 15 | "@types/node": "^20.6.0", 16 | "@typescript-eslint/eslint-plugin": "^6.6.0", 17 | "@typescript-eslint/parser": "^6.6.0", 18 | "bumpp": "^9.2.0", 19 | "eslint": "^8.49.0", 20 | "eslint-config-prettier": "^9.0.0", 21 | "eslint-plugin-prettier": "^5.0.0", 22 | "globby": "^12.0.2", 23 | "jiti": "^1.20.0", 24 | "js-yaml": "^4.1.0", 25 | "lint-staged": "^14.0.1", 26 | "mlly": "^1.4.2", 27 | "node-actionlint": "^1.2.1", 28 | "npm-run-all": "^4.1.5", 29 | "pathe": "^1.1.1", 30 | "pkg-types": "^1.0.2", 31 | "playwright": "^1.40.1", 32 | "prettier": "^3.0.3", 33 | "rimraf": "^3.0.2", 34 | "secretlint": "^7.0.7", 35 | "typescript": "^5.2.2" 36 | }, 37 | "engines": { 38 | "node": ">= 14.6" 39 | }, 40 | "license": "MIT", 41 | "lint-staged": { 42 | "*.{json,md,yml}": [ 43 | "prettier --write" 44 | ], 45 | "*.{js,vue}": [ 46 | "prettier --write", 47 | "eslint --fix --ext .js" 48 | ], 49 | "*.ts?(x)": [ 50 | "prettier --parser=typescript --write", 51 | "eslint --fix --ext .ts" 52 | ], 53 | "*": [ 54 | "secretlint" 55 | ] 56 | }, 57 | "private": true, 58 | "repository": { 59 | "type": "git", 60 | "url": "git+https://github.com/intlify/bridging.git" 61 | }, 62 | "scripts": { 63 | "build": "echo build!", 64 | "format:fix": "run-p \"format:prettier --write\"", 65 | "format:prettier": "prettier --config .prettierrc --ignore-path .prettierignore --list-different '**/*.{js,mjs,json,html}'", 66 | "lint": "run-p lint:action lint:codes", 67 | "lint:action": "node-actionlint", 68 | "lint:codes": "eslint --config .eslintrc.cjs --ext .js,.mjs,.ts,.vue ./packages", 69 | "lint:fix": "run-p \"lint:codes --fix\"", 70 | "lint:secret": "npx secretlint \"**/*\"", 71 | "fix": "run-p lint:fix format:fix", 72 | "install:i18n8": "cd examples/vue-i18n-v8-vue2 && npm install", 73 | "install:i18n9": "cd examples/vue-i18n-v9-vue3 && npm install", 74 | "install:router3": "cd examples/vue-router-v3-vue2 && npm install", 75 | "install:router36": "cd examples/vue-router-v36-vue2 && npm install", 76 | "install:router4": "cd examples/vue-router-v4-vue3 && npm install", 77 | "setup:examples": "run-p \"install:*\"", 78 | "play:i18n8": "cd examples/vue-i18n-v8-vue2 && npm run dev", 79 | "play:i18n9": "cd examples/vue-i18n-v9-vue3 && npm run dev", 80 | "play:router3": "cd examples/vue-router-v3-vue2 && npm run dev", 81 | "play:router36": "cd examples/vue-router-v36-vue2 && npm run dev", 82 | "play:router4": "cd examples/vue-router-v4-vue3 && npm run dev", 83 | "test": "run-p \"test:*\"", 84 | "test:i18n8": "cd examples/vue-i18n-v8-vue2 && npx --no-install vue-demi-switch 2 && npx --no-install vue-i18n-switch 8 && npm test", 85 | "test:i18n9": "cd examples/vue-i18n-v9-vue3 && npx --no-install vue-i18n-switch 9 && npm test", 86 | "test:router3": "cd examples/vue-router-v3-vue2 && npx --no-install vue-demi-switch 2 && npx --no-install vue-router-switch 3 && npm test", 87 | "test:router36": "cd examples/vue-router-v36-vue2 && npx --no-install vue-demi-switch 2 && npx --no-install vue-router-switch 3 && npm test", 88 | "test:router4": "cd examples/vue-router-v4-vue3 && npx --no-install vue-router-switch 4 && npm test", 89 | "release": "bumpp package.json packages/**/package.json --commit \"release: v\" --push --tag", 90 | "prepare": "git config --local core.hooksPath .githooks", 91 | "preinstall": "node ./scripts/preinstall.mjs" 92 | }, 93 | "workspaces": [ 94 | "packages/*" 95 | ] 96 | } 97 | -------------------------------------------------------------------------------- /packages/vue-i18n-bridge/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2021 kazuya kawaguchi 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /packages/vue-i18n-bridge/README.md: -------------------------------------------------------------------------------- 1 | # @intlify/vue-i18n-bridge 2 | 3 | Vue I18n bridging for Vue 2 & Vue 3 4 | 5 | > This library is inspired by [vue-demi](https://github.com/vueuse/vue-demi) 6 | 7 | ## 🌟 Features 8 | 9 | - Vue I18n composable APIs available on Vue 2 & Vue 3 (e.g `createI18n`, `useI18n`) 10 | - Auto detect Vue I18n version on bundling 11 | - Manual switch versions 12 | 13 | ## 💿 Installation 14 | 15 | ```sh 16 | # npm 17 | npm install @intlify/vue-i18n-bridge 18 | 19 | # yarn 20 | yarn add @intlify/vue-i18n-bridge 21 | 22 | # pnpm 23 | pnpm add @intlify/vue-i18n-bridge 24 | ``` 25 | 26 | ## ⛓️ Dependencies 27 | 28 | You need to add `vue-i18n` and `@vue/composition-api` to your plugin's peer dependencies to specify what versions you support. 29 | 30 | ```js 31 | { 32 | "dependencies": { 33 | "@intlify/vue-i18n-bridge": "latest" 34 | }, 35 | "peerDependencies": { 36 | "@vue/composition-api": "^1.0.0-rc.1", 37 | "vue-i18n": "^8.26.1" // or "^9.2.0-beta.25" or later base on your preferred working environment 38 | "vue-i18n-bridge": "^9.2.0-beta.25" // if you use `vue-i18n@v8.26.1` or later, you need to configure deps 39 | }, 40 | "peerDependenciesMeta": { 41 | "@vue/composition-api": { 42 | "optional": true 43 | } 44 | }, 45 | "devDependencies": { 46 | "vue-i18n": "^8.26.1", // or "^9.2.0-beta.25" or later base on your preferred working environment 47 | "vue-i18n-bridge": "^9.2.0-beta.25" // if you use `vue-i18n@v8.26.1` or later, you need to configure deps 48 | }, 49 | } 50 | ``` 51 | 52 | Import everything related to Vue I18n from it, it will redirect to `vue-i18n@8.26` + `@vue/composition-api` or `vue-i18n@9.2` based on users' environments. 53 | 54 | ```js 55 | import { createI18n, useI18n } from '@intlify/vue-i18n-bridge' 56 | ``` 57 | 58 | When using with [Vite](https://vitejs.dev), you will need to opt-out the pre-bundling to get `@intlify/vue-i18n-bridge` work properly by 59 | 60 | ```js 61 | // vite.config.js 62 | export default defineConfig({ 63 | optimizeDeps: { 64 | exclude: ['@intlify/vue-i18n-bridge'] 65 | } 66 | }) 67 | ``` 68 | 69 | ## 🤝 Extra APIs 70 | 71 | `@intlify/vue-i18n-bridge` provides extra APIs to help distinguish users' environments and to do some version-specific logic. 72 | 73 | ### `isVueI18n8` / `isVueI18n9` 74 | 75 | ```js 76 | import { isVueI18n8, isVueI18n9 } from '@intlify/vue-i18n-bridge' 77 | 78 | if (isVueI18n8) { 79 | // Vue I18n 8 only 80 | } else { 81 | // Vue I18n 9 only 82 | } 83 | ``` 84 | 85 | ## 📺 CLI 86 | 87 | To explicitly switch the redirecting version, you can use these commands in your project's root: 88 | 89 | ### 🤏 Manually Switch Versions 90 | 91 | ```sh 92 | npx vue-i18n-switch 8 93 | # or 94 | npx vue-i18n-switch 9 95 | ``` 96 | 97 | ### 📦 Package Aliasing 98 | 99 | If you would like to import `vue-i18n` under an alias, you can use the following command: 100 | 101 | ```sh 102 | npx vue-i18n-switch 8 vue-i18n-8 103 | # or 104 | npx vue-i18n-switch 9 vue-i18n-9 105 | ``` 106 | 107 | ### 🩹 Auto Fix 108 | 109 | If the postinstall hook doesn't get triggered or you have updated the Vue I18n version, try to run the following command to resolve the redirecting: 110 | 111 | ```sh 112 | npx vue-i18n-fix 113 | ``` 114 | 115 | ### ✳️ Isomorphic Testings 116 | 117 | You can support testing for both versions by adding npm alias in your dev dependencies. For example: 118 | 119 | ```js 120 | { 121 | "scripts": { 122 | "test:8": "vue-i18n-switch 8 vue-i18n-legacy && jest", 123 | "test:9": "vue-i18n-switch 9 && jest", 124 | }, 125 | "devDependencies": { 126 | "vue-i18n-legacy": "npm:vue-i18n@^8.26.1", 127 | "vue-i18n-bridge": "^9.2.0-beta.25", 128 | "vue-i18n": "^9.2.0-beta.25" 129 | }, 130 | } 131 | ``` 132 | 133 | or 134 | 135 | ```js 136 | { 137 | "scripts": { 138 | "test:8": "vue-i18n-switch 8 && jest", 139 | "test:9": "vue-i18n-switch 9 vue-i18n-next && jest", 140 | }, 141 | "devDependencies": { 142 | "vue-i18n": "^8.26.1", 143 | "vue-i18n-next": "npm:vue-i18n@9.2.0-beta.25" 144 | }, 145 | } 146 | ``` 147 | 148 | ## 🍭 Examples 149 | 150 | - [Vue 2 + Vue I18n v8](../../examples/vue-i18n-v8-vue2) 151 | - [Vue 3 + Vue I18n v9](../../examples/vue-i18n-v9-vue3) 152 | 153 | ## 💖 Thanks 154 | 155 | This package idea was inspired from [vue-demi](https://github.com/vueuse/vue-demi), [@antfu](https://github.com/antfu)'s great work! 156 | 157 | ## ©️ License 158 | 159 | [MIT](http://opensource.org/licenses/MIT) 160 | -------------------------------------------------------------------------------- /packages/vue-i18n-bridge/bin/fix.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 'use strict' 3 | require('../scripts/postinstall') 4 | -------------------------------------------------------------------------------- /packages/vue-i18n-bridge/bin/switch.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 'use strict' 3 | require('../scripts/switch') 4 | -------------------------------------------------------------------------------- /packages/vue-i18n-bridge/lib/index.cjs: -------------------------------------------------------------------------------- 1 | Object.defineProperty(exports, '__esModule', { 2 | value: true 3 | }) 4 | 5 | var VueI18n = require('vue-i18n') 6 | 7 | // stub vue-i18n 8 class 8 | class VueI18nLegacy { 9 | static install() {} 10 | static version = '' 11 | } 12 | 13 | Object.keys(VueI18n).forEach(function (key) { 14 | VueI18nLegacy[key] = VueI18n[key] 15 | }) 16 | 17 | VueI18nLegacy.isVueI18n8 = false 18 | VueI18nLegacy.isVueI18n9 = true 19 | 20 | exports.default = VueI18nLegacy 21 | module.exports = VueI18nLegacy 22 | -------------------------------------------------------------------------------- /packages/vue-i18n-bridge/lib/index.d.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable @typescript-eslint/no-explicit-any */ 2 | declare type Vue = any // emulate Vue (v2) 3 | declare namespace _VueI18n { 4 | type Path = string 5 | type Locale = string 6 | type FallbackLocale = string | string[] | false | { [locale: string]: string[] } 7 | type Values = any[] | { [key: string]: any } 8 | type Choice = number 9 | interface MessageContext { 10 | list(index: number): unknown 11 | named(key: string): unknown 12 | linked(key: string): TranslateResult 13 | values: any 14 | path: string 15 | formatter: Formatter 16 | messages: LocaleMessages 17 | locale: Locale 18 | } 19 | type MessageFunction = (ctx: MessageContext) => string 20 | type LocaleMessage = string | MessageFunction | LocaleMessageObject | LocaleMessageArray 21 | interface LocaleMessageObject { 22 | [key: string]: LocaleMessage 23 | } 24 | interface LocaleMessageArray { 25 | [index: number]: LocaleMessage 26 | } 27 | interface LocaleMessages { 28 | [key: string]: LocaleMessageObject 29 | } 30 | type TranslateResult = string | LocaleMessages 31 | 32 | type LocaleMatcher = 'lookup' | 'best fit' 33 | type FormatMatcher = 'basic' | 'best fit' 34 | 35 | type DateTimeHumanReadable = 'long' | 'short' | 'narrow' 36 | type DateTimeDigital = 'numeric' | '2-digit' 37 | 38 | interface SpecificDateTimeFormatOptions extends Intl.DateTimeFormatOptions { 39 | year?: DateTimeDigital 40 | month?: DateTimeDigital | DateTimeHumanReadable 41 | day?: DateTimeDigital 42 | hour?: DateTimeDigital 43 | minute?: DateTimeDigital 44 | second?: DateTimeDigital 45 | weekday?: DateTimeHumanReadable 46 | era?: DateTimeHumanReadable 47 | timeZoneName?: 'long' | 'short' 48 | localeMatcher?: LocaleMatcher 49 | formatMatcher?: FormatMatcher 50 | } 51 | 52 | type DateTimeFormatOptions = Intl.DateTimeFormatOptions | SpecificDateTimeFormatOptions 53 | 54 | interface DateTimeFormat { 55 | [key: string]: DateTimeFormatOptions 56 | } 57 | interface DateTimeFormats { 58 | [locale: string]: DateTimeFormat 59 | } 60 | type DateTimeFormatResult = string 61 | 62 | type CurrencyDisplay = 'symbol' | 'code' | 'name' 63 | 64 | interface SpecificNumberFormatOptions extends Intl.NumberFormatOptions { 65 | style?: 'decimal' | 'percent' 66 | currency?: string 67 | currencyDisplay?: CurrencyDisplay 68 | localeMatcher?: LocaleMatcher 69 | formatMatcher?: FormatMatcher 70 | } 71 | 72 | interface CurrencyNumberFormatOptions extends Intl.NumberFormatOptions { 73 | style: 'currency' 74 | currency: string 75 | currencyDisplay?: CurrencyDisplay 76 | localeMatcher?: LocaleMatcher 77 | formatMatcher?: FormatMatcher 78 | } 79 | 80 | type NumberFormatOptions = Intl.NumberFormatOptions | SpecificNumberFormatOptions | CurrencyNumberFormatOptions 81 | 82 | interface NumberFormat { 83 | [key: string]: NumberFormatOptions 84 | } 85 | interface NumberFormats { 86 | [locale: string]: NumberFormat 87 | } 88 | type NumberFormatResult = string 89 | type PluralizationRulesMap = { 90 | [lang: string]: (choice: number, choicesLength: number) => number 91 | } 92 | type Modifiers = { [key: string]: (str: string) => string } 93 | 94 | type FormattedNumberPartType = 95 | | 'currency' 96 | | 'decimal' 97 | | 'fraction' 98 | | 'group' 99 | | 'infinity' 100 | | 'integer' 101 | | 'literal' 102 | | 'minusSign' 103 | | 'nan' 104 | | 'plusSign' 105 | | 'percentSign' 106 | 107 | type WarnHtmlInMessageLevel = 'off' | 'warn' | 'error' 108 | 109 | interface FormattedNumberPart { 110 | type: FormattedNumberPartType 111 | value: string 112 | } 113 | interface NumberFormatToPartsResult { 114 | [index: number]: FormattedNumberPart 115 | } 116 | 117 | interface Formatter { 118 | interpolate(message: string, values: Values | undefined, path: string): any[] | null 119 | } 120 | 121 | type MissingHandler = (locale: Locale, key: Path, vm: Vue | null, values: any) => string | void 122 | type PostTranslationHandler = (str: string, key?: string) => string 123 | type ComponentInstanceCreatedListener = (newVm: VueI18n, rootVm: VueI18n) => void 124 | 125 | interface IntlAvailability { 126 | dateTimeFormat: boolean 127 | numberFormat: boolean 128 | } 129 | 130 | interface I18nOptions { 131 | locale?: Locale 132 | fallbackLocale?: FallbackLocale 133 | messages?: LocaleMessages 134 | dateTimeFormats?: DateTimeFormats 135 | numberFormats?: NumberFormats 136 | formatter?: Formatter 137 | modifiers?: Modifiers 138 | missing?: MissingHandler 139 | fallbackRoot?: boolean 140 | formatFallbackMessages?: boolean 141 | sync?: boolean 142 | silentTranslationWarn?: boolean | RegExp 143 | silentFallbackWarn?: boolean | RegExp 144 | preserveDirectiveContent?: boolean 145 | pluralizationRules?: PluralizationRulesMap 146 | warnHtmlInMessage?: WarnHtmlInMessageLevel 147 | sharedMessages?: LocaleMessages 148 | postTranslation?: PostTranslationHandler 149 | componentInstanceCreatedListener?: ComponentInstanceCreatedListener 150 | escapeParameterHtml?: boolean 151 | } 152 | } 153 | 154 | // Stub vue-i18n class interfaces 155 | declare interface VueI18n { 156 | readonly messages: _VueI18n.LocaleMessages 157 | readonly dateTimeFormats: _VueI18n.DateTimeFormats 158 | readonly numberFormats: _VueI18n.NumberFormats 159 | 160 | locale: _VueI18n.Locale 161 | fallbackLocale: _VueI18n.FallbackLocale 162 | missing: _VueI18n.MissingHandler 163 | formatter: _VueI18n.Formatter 164 | formatFallbackMessages: boolean 165 | silentTranslationWarn: boolean | RegExp 166 | silentFallbackWarn: boolean | RegExp 167 | preserveDirectiveContent: boolean 168 | sync: boolean 169 | pluralizationRules: _VueI18n.PluralizationRulesMap 170 | warnHtmlInMessage: _VueI18n.WarnHtmlInMessageLevel 171 | postTranslation: _VueI18n.PostTranslationHandler 172 | t(key: _VueI18n.Path, values?: _VueI18n.Values): _VueI18n.TranslateResult 173 | t(key: _VueI18n.Path, locale: _VueI18n.Locale, values?: _VueI18n.Values): _VueI18n.TranslateResult 174 | tc(key: _VueI18n.Path, choice?: _VueI18n.Choice, values?: _VueI18n.Values): string 175 | tc(key: _VueI18n.Path, choice: _VueI18n.Choice, locale: _VueI18n.Locale, values?: _VueI18n.Values): string 176 | te(key: _VueI18n.Path, locale?: _VueI18n.Locale): boolean 177 | d(value: number | Date, key?: _VueI18n.Path, locale?: _VueI18n.Locale): _VueI18n.DateTimeFormatResult 178 | d(value: number | Date, args?: { [key: string]: string }): _VueI18n.DateTimeFormatResult 179 | d(value: number | Date, options?: _VueI18n.DateTimeFormatOptions): _VueI18n.DateTimeFormatResult 180 | n(value: number, key?: _VueI18n.Path, locale?: _VueI18n.Locale): _VueI18n.NumberFormatResult 181 | n(value: number, args?: { [key: string]: string }): _VueI18n.NumberFormatResult 182 | n(value: number, options?: _VueI18n.NumberFormatOptions, locale?: _VueI18n.Locale): _VueI18n.NumberFormatResult 183 | getLocaleMessage(locale: _VueI18n.Locale): _VueI18n.LocaleMessageObject 184 | setLocaleMessage(locale: _VueI18n.Locale, message: _VueI18n.LocaleMessageObject): void 185 | mergeLocaleMessage(locale: _VueI18n.Locale, message: _VueI18n.LocaleMessageObject): void 186 | getDateTimeFormat(locale: _VueI18n.Locale): _VueI18n.DateTimeFormat 187 | setDateTimeFormat(locale: _VueI18n.Locale, format: _VueI18n.DateTimeFormat): void 188 | mergeDateTimeFormat(locale: _VueI18n.Locale, format: _VueI18n.DateTimeFormat): void 189 | getNumberFormat(locale: _VueI18n.Locale): _VueI18n.NumberFormat 190 | setNumberFormat(locale: _VueI18n.Locale, format: _VueI18n.NumberFormat): void 191 | mergeNumberFormat(locale: _VueI18n.Locale, format: _VueI18n.NumberFormat): void 192 | getChoiceIndex: (choice: number, choicesLength: number) => number 193 | } 194 | declare const isVueI18n8: boolean 195 | declare const isVueI18n9: boolean 196 | 197 | declare class VueI18nLegacy { 198 | static install() 199 | static version 200 | } 201 | 202 | export * from 'vue-i18n' 203 | export { isVueI18n8, isVueI18n9 } 204 | export default VueI18nLegacy 205 | 206 | /* eslint-enable @typescript-eslint/no-explicit-any */ 207 | -------------------------------------------------------------------------------- /packages/vue-i18n-bridge/lib/index.mjs: -------------------------------------------------------------------------------- 1 | var isVueI18n8 = false 2 | var isVueI18n9 = true 3 | 4 | // stub vue-i18n 8 class 5 | class VueI18nLegacy { 6 | static install() {} 7 | static version = '' 8 | } 9 | 10 | export * from 'vue-i18n' 11 | export { isVueI18n8, isVueI18n9 } 12 | export default VueI18nLegacy 13 | -------------------------------------------------------------------------------- /packages/vue-i18n-bridge/lib/v8/index.cjs: -------------------------------------------------------------------------------- 1 | Object.defineProperty(exports, '__esModule', { 2 | value: true 3 | }) 4 | 5 | var VueI18n = require('vue-i18n') 6 | var VueI18nBridge = require('vue-i18n-bridge') 7 | 8 | Object.keys(VueI18nBridge).forEach(function (key) { 9 | VueI18n[key] = VueI18nBridge[key] 10 | }) 11 | VueI18n.isVueI18n8 = true 12 | VueI18n.isVueI18n9 = false 13 | 14 | exports.default = VueI18n 15 | module.exports = VueI18n 16 | -------------------------------------------------------------------------------- /packages/vue-i18n-bridge/lib/v8/index.d.ts: -------------------------------------------------------------------------------- 1 | import VueI18n from 'vue-i18n' 2 | 3 | declare const isVueI18n8: boolean 4 | declare const isVueI18n9: boolean 5 | 6 | export * from 'vue-i18n-bridge' 7 | export { VueI18n, isVueI18n8, isVueI18n9 } 8 | export default VueI18n 9 | -------------------------------------------------------------------------------- /packages/vue-i18n-bridge/lib/v8/index.mjs: -------------------------------------------------------------------------------- 1 | import VueI18n from 'vue-i18n' 2 | 3 | var isVueI18n8 = true 4 | var isVueI18n9 = false 5 | 6 | export * from 'vue-i18n-bridge' 7 | export { isVueI18n8, isVueI18n9 } 8 | export default VueI18n 9 | -------------------------------------------------------------------------------- /packages/vue-i18n-bridge/lib/v9/index.cjs: -------------------------------------------------------------------------------- 1 | Object.defineProperty(exports, '__esModule', { 2 | value: true 3 | }) 4 | 5 | var VueI18n = require('vue-i18n') 6 | 7 | // stub vue-i18n 8 class 8 | class VueI18nLegacy { 9 | static install() {} 10 | static version = '' 11 | } 12 | 13 | Object.keys(VueI18n).forEach(function (key) { 14 | VueI18nLegacy[key] = VueI18n[key] 15 | }) 16 | 17 | VueI18nLegacy.isVueI18n8 = false 18 | VueI18nLegacy.isVueI18n9 = true 19 | 20 | exports.default = VueI18nLegacy 21 | module.exports = VueI18nLegacy 22 | -------------------------------------------------------------------------------- /packages/vue-i18n-bridge/lib/v9/index.mjs: -------------------------------------------------------------------------------- 1 | var isVueI18n8 = false 2 | var isVueI18n9 = true 3 | 4 | // stub vue-i18n 8 class 5 | class VueI18nLegacy { 6 | static install() {} 7 | static version = '' 8 | } 9 | 10 | export * from 'vue-i18n' 11 | export { isVueI18n8, isVueI18n9 } 12 | export default VueI18nLegacy 13 | -------------------------------------------------------------------------------- /packages/vue-i18n-bridge/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@intlify/vue-i18n-bridge", 3 | "version": "1.1.0", 4 | "description": "Vue I18n bridging for Vue 2 & Vue 3", 5 | "scripts": { 6 | "postinstall": "node ./scripts/postinstall.js" 7 | }, 8 | "peerDependencies": { 9 | "vue-i18n": "^8.26.1 || >=9.2.0", 10 | "vue-i18n-bridge": ">=9.2.0", 11 | "@vue/composition-api": "^1.0.0-rc.1" 12 | }, 13 | "peerDependenciesMeta": { 14 | "vue-i18n": { 15 | "optional": true 16 | }, 17 | "vue-i18n-bridge": { 18 | "optional": true 19 | }, 20 | "@vue/composition-api": { 21 | "optional": true 22 | } 23 | }, 24 | "main": "lib/index.cjs", 25 | "module": "lib/index.mjs", 26 | "types": "lib/index.d.ts", 27 | "exports": { 28 | ".": { 29 | "require": "./lib/index.cjs", 30 | "import": "./lib/index.mjs" 31 | }, 32 | "./*": "./*" 33 | }, 34 | "keywords": [ 35 | "vue", 36 | "vuejs", 37 | "vue-i18n", 38 | "i18n", 39 | "internationalization", 40 | "intlify", 41 | "bridge", 42 | "bridging", 43 | "stub" 44 | ], 45 | "files": [ 46 | "lib", 47 | "bin", 48 | "scripts", 49 | "LICENSE", 50 | "README.md" 51 | ], 52 | "bin": { 53 | "vue-i18n-fix": "bin/fix.js", 54 | "vue-i18n-switch": "bin/switch.js" 55 | }, 56 | "license": "MIT", 57 | "author": { 58 | "name": "kazuya kawaguchi", 59 | "email": "kawakazu80@gmail.com" 60 | }, 61 | "funding": "https://github.com/sponsors/kazupon", 62 | "homepage": "https://github.com/intlify/bridging/tree/main/packages/vue-i18n-bridge#readme", 63 | "repository": { 64 | "type": "git", 65 | "url": "git+https://github.com/intlify/bridging.git", 66 | "directory": "packages/vue-i18n-bridge" 67 | }, 68 | "bugs": { 69 | "url": "https://github.com/intlify/bridging/issues" 70 | }, 71 | "engines": { 72 | "node": ">= 12" 73 | }, 74 | "publishConfig": { 75 | "access": "public" 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /packages/vue-i18n-bridge/scripts/postinstall.js: -------------------------------------------------------------------------------- 1 | const { switchVersion, loadModule, warn, log } = require('./utils') // eslint-disable-line @typescript-eslint/no-var-requires 2 | 3 | log('start vue-i18n-bridge postinstall script') 4 | const VueI18n = loadModule('vue-i18n/package.json') 5 | 6 | if (!VueI18n || typeof VueI18n.version !== 'string') { 7 | warn('VueI18n is not found. Please run "npm install vue-i18n" to install.') 8 | } else if (VueI18n.version.startsWith('8.')) { 9 | switchVersion(8) 10 | } else if (VueI18n.version.startsWith('9.')) { 11 | switchVersion(9) 12 | } else { 13 | warn(`VueI18n version v${VueI18n.version} is not suppported.`) 14 | } 15 | -------------------------------------------------------------------------------- /packages/vue-i18n-bridge/scripts/switch.js: -------------------------------------------------------------------------------- 1 | const { switchVersion, warn, log } = require('./utils') // eslint-disable-line @typescript-eslint/no-var-requires 2 | 3 | const version = process.argv[2] 4 | const vueI18nEntry = process.argv[3] || 'vue-i18n' 5 | 6 | if (version == '8') { 7 | switchVersion(8, vueI18nEntry) 8 | log(`Switched for Vue I18n 8 (entry: "${vueI18nEntry}")`) 9 | } else if (version == '9') { 10 | switchVersion(9, vueI18nEntry) 11 | log(`Switched for Vue I18n 9 (entry: "${vueI18nEntry}")`) 12 | } else { 13 | warn(`expecting version "8" or "9" but got "${version}"`) 14 | process.exit(1) 15 | } 16 | -------------------------------------------------------------------------------- /packages/vue-i18n-bridge/scripts/utils.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs') // eslint-disable-line @typescript-eslint/no-var-requires 2 | const path = require('path') // eslint-disable-line @typescript-eslint/no-var-requires 3 | 4 | const DEBUG = process.env.DEBUG 5 | 6 | const dir = path.resolve(__dirname, '..', 'lib') 7 | 8 | function loadModule(name) { 9 | try { 10 | return require(name) 11 | } catch (e) { 12 | DEBUG && error(e) 13 | return undefined 14 | } 15 | } 16 | 17 | function error(...args) { 18 | console.error(`[vue-i18n-bridge] `, ...args) 19 | } 20 | 21 | function warn(...args) { 22 | console.warn(`[vue-i18n-bridge] `, ...args) 23 | } 24 | 25 | function log(...args) { 26 | console.log(`[vue-i18n-bridge] `, ...args) 27 | } 28 | 29 | function copy(name, version, i18n, esm = false) { 30 | const src = path.join(dir, `v${version}`, name) 31 | const dest = path.join(dir, name) 32 | let content = fs.readFileSync(src, 'utf-8') 33 | content = esm 34 | ? content.replace(/from 'vue-i18n'/g, `from '${i18n}'`) 35 | : content.replace(/require\('vue-i18n'\)/g, `require('${i18n}')`) 36 | try { 37 | fs.unlinkSync(dest) 38 | } catch (error) {} 39 | fs.writeFileSync(dest, content, 'utf-8') 40 | } 41 | 42 | function checkBridge() { 43 | const bridge = loadModule('vue-i18n-bridge') 44 | if (!bridge) { 45 | warn('Vue I18n Bridge plugin is not found. Please run "npm install vue-i18n-bridge" to install.') 46 | return false 47 | } 48 | return true 49 | } 50 | 51 | function checkVueI18n(pkg) { 52 | const i18n = loadModule(pkg) 53 | if (!i18n) { 54 | warn(`Vue I18n plugin is not found. Please run "npm install ${pkg}" to install.`) 55 | return false 56 | } 57 | return true 58 | } 59 | 60 | function switchVersion(version, i18n) { 61 | i18n = i18n || 'vue-i18n' 62 | if (!checkVueI18n(i18n)) { 63 | return 64 | } 65 | if (version === 8 && !checkBridge()) { 66 | return 67 | } 68 | copy('index.cjs', version, i18n) 69 | copy('index.mjs', version, i18n, true) 70 | copy('index.d.ts', version, i18n, true) 71 | } 72 | 73 | module.exports.warn = warn 74 | module.exports.log = log 75 | module.exports.loadModule = loadModule 76 | module.exports.switchVersion = switchVersion 77 | -------------------------------------------------------------------------------- /packages/vue-router-bridge/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2021 kazuya kawaguchi 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /packages/vue-router-bridge/README.md: -------------------------------------------------------------------------------- 1 | # @intlify/vue-router-bridge 2 | 3 | Vue Router bridging for Vue 2 & Vue 3 4 | 5 | > This library is inspired by [vue-demi](https://github.com/vueuse/vue-demi) 6 | 7 | ## 🌟 Features 8 | 9 | - Vue Router composable APIs available on Vue 2 & Vue 3 10 | - `useRouter` 11 | - `useRoute` 12 | - Stubbed Vue Router 4 APIs on Vue Router 3 13 | - About details [here](https://github.com/intlify/bridging/blob/63b1fb5dab4be772f4f564f023e9028979d37196/packages/vue-router-bridge/lib/v3/index.d.ts#L7-L75) 14 | - Auto detect Vue Router version on bundling 15 | - Manual switch versions 16 | 17 | ## 💿 Installation 18 | 19 | ```sh 20 | # npm 21 | npm install @intlify/vue-router-bridge 22 | 23 | # yarn 24 | yarn add @intlify/vue-router-bridge 25 | 26 | # pnpm 27 | pnpm add @intlify/vue-router-bridge 28 | ``` 29 | 30 | ## ⛓️ Dependencies 31 | 32 | You need to add `vue-router` and `@vue/composition-api` to your plugin's peer dependencies to specify what versions you support. 33 | 34 | ```js 35 | { 36 | "dependencies": { 37 | "@intlify/vue-router-bridge": "latest" 38 | }, 39 | "peerDependencies": { 40 | "@vue/composition-api": "^1.0.0-rc.1", 41 | "vue-router": "^3.0.0" // or "^4.0.0" base on your preferred working environment 42 | }, 43 | "peerDependenciesMeta": { 44 | "@vue/composition-api": { 45 | "optional": true 46 | } 47 | }, 48 | "devDependencies": { 49 | "vue-router": "^3.0.0" // or "^4.0.0" base on your preferred working environment 50 | }, 51 | } 52 | ``` 53 | 54 | Import everything related to Vue Router from it, it will redirect to `vue-router@3` + `@vue/composition-api` or `vue-router@4` based on users' environments. 55 | 56 | ```js 57 | import { useRouter, useRoute } from '@intlify/vue-router-bridge' 58 | ``` 59 | 60 | When using with [Vite](https://vitejs.dev), you will need to opt-out the pre-bundling to get `@intlify/vue-router-bridge` work properly by 61 | 62 | ```js 63 | // vite.config.js 64 | export default defineConfig({ 65 | optimizeDeps: { 66 | exclude: ['@intlify/vue-router-bridge'] 67 | } 68 | }) 69 | ``` 70 | 71 | ## 🤝 Extra APIs 72 | 73 | `@intlify/vue-router-bridge` provides extra APIs to help distinguish users' environments and to do some version-specific logic. 74 | 75 | ### `isVueRouter3` / `isVueRouter4` 76 | 77 | ```js 78 | import { isVueRouter3, isVueRouter4 } from '@intlify/vue-router-bridge' 79 | 80 | if (isVueRouter3) { 81 | // Vue Router 3 only 82 | } else { 83 | // Vue Router 4 only 84 | } 85 | ``` 86 | 87 | ## 📺 CLI 88 | 89 | To explicitly switch the redirecting version, you can use these commands in your project's root: 90 | 91 | ### 🤏 Manually Switch Versions 92 | 93 | ```sh 94 | npx vue-router-switch 3 95 | # or 96 | npx vue-router-switch 4 97 | ``` 98 | 99 | ### 📦 Package Aliasing 100 | 101 | If you would like to import `vue-router` under an alias, you can use the following command: 102 | 103 | ```sh 104 | npx vue-router-switch 3 vue-router3 105 | # or 106 | npx vue-router-switch 4 vue-router4 107 | ``` 108 | 109 | ### 🩹 Auto Fix 110 | 111 | If the postinstall hook doesn't get triggered or you have updated the Vue Router version, try to run the following command to resolve the redirecting: 112 | 113 | ```sh 114 | npx vue-router-fix 115 | ``` 116 | 117 | ### ✳️ Isomorphic Testings 118 | 119 | You can support testing for both versions by adding npm alias in your dev dependencies. For example: 120 | 121 | ```js 122 | { 123 | "scripts": { 124 | "test:3": "vue-router-switch 3 vue-router3 && jest", 125 | "test:4": "vue-router-switch 4 && jest", 126 | }, 127 | "devDependencies": { 128 | "vue-router": "^4.0.0", 129 | "vue-router3": "npm:vue-router@3" 130 | }, 131 | } 132 | ``` 133 | 134 | or 135 | 136 | ```js 137 | { 138 | "scripts": { 139 | "test:3": "vue-router-switch 3 && jest", 140 | "test:4": "vue-router-switch 4 vue-router4 && jest", 141 | }, 142 | "devDependencies": { 143 | "vue-router": "^3.0.0", 144 | "vue-router4": "npm:vue-router@4" 145 | }, 146 | } 147 | ``` 148 | 149 | ## 🍭 Examples 150 | 151 | - [Vue 2 + Vue Router v3.6 before](../../examples/vue-router-v3-vue2) 152 | - [Vue 2 + Vue Router v3.6 or v3.x later](../../examples/vue-router-v36-vue2) 153 | - [Vue 3 + Vue Router v4](../../examples/vue-router-v4-vue3) 154 | 155 | ## 💖 Thanks 156 | 157 | This package idea was inspired from [vue-demi](https://github.com/vueuse/vue-demi), [@antfu](https://github.com/antfu)'s great work! 158 | 159 | ## ©️ License 160 | 161 | [MIT](http://opensource.org/licenses/MIT) 162 | -------------------------------------------------------------------------------- /packages/vue-router-bridge/bin/fix.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 'use strict' 3 | require('../scripts/postinstall') 4 | -------------------------------------------------------------------------------- /packages/vue-router-bridge/bin/switch.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 'use strict' 3 | require('../scripts/switch') 4 | -------------------------------------------------------------------------------- /packages/vue-router-bridge/lib/index.cjs: -------------------------------------------------------------------------------- 1 | Object.defineProperty(exports, '__esModule', { 2 | value: true 3 | }) 4 | 5 | var VueRouter = require('vue-router') 6 | 7 | // stub vue-router 3 class 8 | class VueRouterLegacy { 9 | static install() {} 10 | static version = '' 11 | } 12 | 13 | Object.keys(VueRouter).forEach(function (key) { 14 | VueRouterLegacy[key] = VueRouter[key] 15 | }) 16 | 17 | VueRouterLegacy.isVueRouter3 = false 18 | VueRouterLegacy.isVueRouter4 = true 19 | 20 | exports.default = VueRouterLegacy 21 | module.exports = VueRouterLegacy 22 | -------------------------------------------------------------------------------- /packages/vue-router-bridge/lib/index.d.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable @typescript-eslint/no-explicit-any */ 2 | import type { RouteLocationNormalizedLoaded, Router, RouteRecord, RouteMeta, NavigationGuard } from 'vue-router' 3 | 4 | /** 5 | * shim vue-router@3 typings 6 | */ 7 | 8 | // Stub VueRouter class interfaces 9 | declare interface VueRouter { 10 | app: Vue 11 | options: RouterOptions 12 | mode: RouterMode 13 | currentRoute: Route 14 | beforeEach(guard: NavigationGuard): Function 15 | beforeResolve(guard: NavigationGuard): Function 16 | afterEach(hook: (to: Route, from: Route) => any): Function 17 | push(location: RawLocation): Promise 18 | push(location: RawLocation, onComplete?: Function, onAbort?: ErrorHandler): void 19 | replace(location: RawLocation): Promise 20 | replace(location: RawLocation, onComplete?: Function, onAbort?: ErrorHandler): void 21 | go(n: number): void 22 | back(): void 23 | forward(): void 24 | match(raw: RawLocation, current?: Route, redirectedFrom?: Location): Route 25 | getMatchedComponents(to?: RawLocation | Route): Component[] 26 | onReady(cb: Function, errorCb?: ErrorHandler): void 27 | onError(cb: ErrorHandler): void 28 | addRoutes(routes: RouteConfig[]): void 29 | AddRoute(parent: string, route: RouteConfig): void 30 | AddRoute(route: RouteConfig): void 31 | resolve( 32 | to: RawLocation, 33 | current?: Route, 34 | append?: boolean 35 | ): { 36 | location: Location 37 | route: Route 38 | href: string 39 | normalizedTo: Location 40 | resolved: Route 41 | } 42 | } 43 | declare type ErrorHandler = (err: Error) => void 44 | declare type RouterMode = 'hash' | 'history' | 'abstract' 45 | declare type Dictionary = { [key: string]: T } 46 | declare interface Location { 47 | name?: string 48 | path?: string 49 | hash?: string 50 | query?: Dictionary 51 | params?: Dictionary 52 | append?: boolean 53 | replace?: boolean 54 | } 55 | declare type RawLocation = string | Location 56 | declare interface Route { 57 | path: string 58 | name?: string | null 59 | hash: string 60 | query: Dictionary 61 | params: Dictionary 62 | fullPath: string 63 | matched: RouteRecord[] 64 | redirectedFrom?: string 65 | meta?: RouteMeta 66 | } 67 | declare type RedirectOption = RawLocation | ((to: Route) => RawLocation) 68 | declare interface PathToRegexpOptions { 69 | sensitive?: boolean 70 | strict?: boolean 71 | end?: boolean 72 | } 73 | declare type Vue = any // emulate Vue (v2) 74 | declare type Component = any // emulate Vue Component (v2) 75 | declare type Position = { x: number; y: number } 76 | declare type PositionResult = Position | { selector: string; offset?: Position; behavior?: ScrollBehavior } | void 77 | declare interface RouterOptions { 78 | routes?: RouteConfig[] 79 | mode?: RouterMode 80 | fallback?: boolean 81 | base?: string 82 | linkActiveClass?: string 83 | linkExactActiveClass?: string 84 | parseQuery?: (query: string) => Record 85 | stringifyQuery?: (query: Record) => string 86 | scrollBehavior?: ( 87 | to: Route, 88 | from: Route, 89 | savedPosition: Position | void 90 | ) => PositionResult | Promise | undefined | null 91 | } 92 | declare type RoutePropsFunction = (route: Route) => Record 93 | declare interface _RouteConfigBase { 94 | path: string 95 | name?: string 96 | children?: RouteConfig[] 97 | redirect?: RedirectOption 98 | alias?: string | string[] 99 | meta?: RouteMeta 100 | beforeEnter?: NavigationGuard 101 | caseSensitive?: boolean 102 | pathToRegexpOptions?: PathToRegexpOptions 103 | } 104 | declare interface RouteConfigSingleView extends _RouteConfigBase { 105 | component?: Component 106 | props?: boolean | Record | RoutePropsFunction 107 | } 108 | declare interface RouteConfigMultipleViews extends _RouteConfigBase { 109 | components?: Dictionary 110 | props?: Dictionary | RoutePropsFunction> 111 | } 112 | declare type RouteConfig = RouteConfigSingleView | RouteConfigMultipleViews 113 | declare interface RouteRecordPublic { 114 | path: string 115 | components: Dictionary 116 | instances: Dictionary 117 | name?: string 118 | redirect?: RedirectOption 119 | meta: any 120 | beforeEnter?: (route: Route, redirect: (location: RawLocation) => void, next: () => void) => any 121 | props: 122 | | boolean 123 | | Record 124 | | RoutePropsFunction 125 | | Dictionary | RoutePropsFunction> 126 | } 127 | 128 | /** 129 | * Returns the router instance. Equivalent to using `$router` inside templates. 130 | */ 131 | declare function useRouter(): T 132 | /** 133 | * Returns the current route location. Equivalent to using `$route` inside templates. 134 | */ 135 | declare function useRoute(): T 136 | 137 | /** 138 | * Wheter the current vue-router version is 3 139 | */ 140 | declare const isVueRouter3: boolean 141 | /** 142 | * Wheter the current vue-router version is 4 143 | */ 144 | declare const isVueRouter4: boolean 145 | 146 | /** 147 | * Define stub vue-router 3 class 148 | */ 149 | declare class VueRouterLegacy { 150 | constructor(options?: RouterOptions) 151 | } 152 | 153 | // export vue-router@4 typings 154 | export * from 'vue-router' 155 | 156 | export { 157 | VueRouter, 158 | useRouter, 159 | useRoute, 160 | isVueRouter3, 161 | isVueRouter4, 162 | RouterMode, 163 | RawLocation, 164 | RedirectOption, 165 | RouteConfig, 166 | RouteRecordPublic, 167 | Location, 168 | Route 169 | } 170 | 171 | // Export dummy VueRouter class 172 | export default VueRouterLegacy 173 | 174 | /* eslint-enable @typescript-eslint/no-explicit-any */ 175 | -------------------------------------------------------------------------------- /packages/vue-router-bridge/lib/index.mjs: -------------------------------------------------------------------------------- 1 | import { useRouter, useRoute } from 'vue-router' 2 | 3 | var isVueRouter3 = false 4 | var isVueRouter4 = true 5 | 6 | // stub vue-router 3 class 7 | class VueRouterLegacy { 8 | static install() {} 9 | static version = '' 10 | } 11 | 12 | export * from 'vue-router' 13 | export { useRouter, useRoute, isVueRouter3, isVueRouter4 } 14 | 15 | export default VueRouterLegacy 16 | -------------------------------------------------------------------------------- /packages/vue-router-bridge/lib/v3.6/index.cjs: -------------------------------------------------------------------------------- 1 | Object.defineProperty(exports, '__esModule', { 2 | value: true 3 | }) 4 | 5 | var VueRouter = require('vue-router') 6 | var { useRoute, useRouter, useLink, onBeforeRouteUpdate, onBeforeRouteLeave } = require('vue-router/composables') 7 | 8 | VueRouter.useRouter = useRouter 9 | VueRouter.useRoute = useRoute 10 | VueRouter.useLink = useLink 11 | VueRouter.onBeforeRouteUpdate = onBeforeRouteUpdate 12 | VueRouter.onBeforeRouteLeave = onBeforeRouteLeave 13 | VueRouter.isVueRouter3 = true 14 | VueRouter.isVueRouter4 = false 15 | 16 | /** 17 | * shim vue-router@4 typings 18 | */ 19 | const STUB = () => ({}) 20 | VueRouter.createRouter = STUB 21 | VueRouter.createMemoryHistory = STUB 22 | VueRouter.createRouterMatcher = STUB 23 | VueRouter.createWebHashHistory = STUB 24 | VueRouter.createWebHistory = STUB 25 | 26 | exports.default = VueRouter 27 | module.exports = VueRouter 28 | -------------------------------------------------------------------------------- /packages/vue-router-bridge/lib/v3.6/index.mjs: -------------------------------------------------------------------------------- 1 | import VueRouter from 'vue-router' 2 | import { useRoute, useRouter, useLink, onBeforeRouteUpdate, onBeforeRouteLeave } from 'vue-router/composables' 3 | 4 | var isVueRouter3 = true 5 | var isVueRouter4 = false 6 | 7 | /** 8 | * shim vue-router@4 typings 9 | */ 10 | const STUB = () => ({}) 11 | const createRouter = STUB 12 | const createMemoryHistory = STUB 13 | const createRouterMatcher = STUB 14 | const createWebHashHistory = STUB 15 | const createWebHistory = STUB 16 | 17 | export { 18 | useRouter, 19 | useRoute, 20 | useLink, 21 | onBeforeRouteUpdate, 22 | onBeforeRouteLeave, 23 | isVueRouter3, 24 | isVueRouter4, 25 | createRouter, 26 | createMemoryHistory, 27 | createRouterMatcher, 28 | createWebHashHistory, 29 | createWebHistory 30 | } 31 | export default VueRouter 32 | -------------------------------------------------------------------------------- /packages/vue-router-bridge/lib/v3/index.cjs: -------------------------------------------------------------------------------- 1 | Object.defineProperty(exports, '__esModule', { 2 | value: true 3 | }) 4 | 5 | var VueRouter = require('vue-router') 6 | var VueDemi = require('vue-demi') 7 | 8 | const useRouter = () => { 9 | const instance = VueDemi.getCurrentInstance() 10 | if (instance == null) { 11 | throw new Error(`should be used in setup`) 12 | } 13 | const vm = instance.proxy || instance 14 | return vm.$router 15 | } 16 | 17 | const useRoute = () => { 18 | const instance = VueDemi.getCurrentInstance() 19 | if (instance == null) { 20 | throw new Error(`should be used in setup`) 21 | } 22 | const vm = instance.proxy || instance 23 | return VueDemi.reactive(vm.$route) 24 | } 25 | 26 | VueRouter.useRouter = useRouter 27 | VueRouter.useRoute = useRoute 28 | VueRouter.isVueRouter3 = true 29 | VueRouter.isVueRouter4 = false 30 | 31 | /** 32 | * shim vue-router@4 typings 33 | */ 34 | const STUB = () => ({}) 35 | VueRouter.createRouter = STUB 36 | VueRouter.createMemoryHistory = STUB 37 | VueRouter.createRouterMatcher = STUB 38 | VueRouter.createWebHashHistory = STUB 39 | VueRouter.createWebHistory = STUB 40 | 41 | exports.default = VueRouter 42 | module.exports = VueRouter 43 | -------------------------------------------------------------------------------- /packages/vue-router-bridge/lib/v3/index.mjs: -------------------------------------------------------------------------------- 1 | import VueRouter from 'vue-router' 2 | import { getCurrentInstance, reactive } from 'vue-demi' 3 | 4 | var isVueRouter3 = true 5 | var isVueRouter4 = false 6 | 7 | function useRouter() { 8 | const instance = getCurrentInstance() 9 | if (instance == null) { 10 | throw new Error(`should be used in setup`) 11 | } 12 | const vm = instance.proxy || instance 13 | return vm.$router 14 | } 15 | 16 | function useRoute() { 17 | const instance = getCurrentInstance() 18 | if (instance == null) { 19 | throw new Error(`should be used in setup`) 20 | } 21 | const vm = instance.proxy || instance 22 | return reactive(vm.$route) 23 | } 24 | 25 | /** 26 | * shim vue-router@4 typings 27 | */ 28 | const STUB = () => ({}) 29 | const createRouter = STUB 30 | const createMemoryHistory = STUB 31 | const createRouterMatcher = STUB 32 | const createWebHashHistory = STUB 33 | const createWebHistory = STUB 34 | 35 | export { 36 | useRouter, 37 | useRoute, 38 | isVueRouter3, 39 | isVueRouter4, 40 | createRouter, 41 | createMemoryHistory, 42 | createRouterMatcher, 43 | createWebHashHistory, 44 | createWebHistory 45 | } 46 | export default VueRouter 47 | -------------------------------------------------------------------------------- /packages/vue-router-bridge/lib/v4/index.cjs: -------------------------------------------------------------------------------- 1 | Object.defineProperty(exports, '__esModule', { 2 | value: true 3 | }) 4 | 5 | var VueRouter = require('vue-router') 6 | 7 | // stub vue-router 3 class 8 | class VueRouterLegacy { 9 | static install() {} 10 | static version = '' 11 | } 12 | 13 | Object.keys(VueRouter).forEach(function (key) { 14 | VueRouterLegacy[key] = VueRouter[key] 15 | }) 16 | 17 | VueRouterLegacy.isVueRouter3 = false 18 | VueRouterLegacy.isVueRouter4 = true 19 | 20 | exports.default = VueRouterLegacy 21 | module.exports = VueRouterLegacy 22 | -------------------------------------------------------------------------------- /packages/vue-router-bridge/lib/v4/index.d.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable @typescript-eslint/no-explicit-any */ 2 | import type { RouteLocationNormalizedLoaded, Router, RouteRecord, RouteMeta, NavigationGuard, RouteLocationRaw, LocationQuery, RouteParams } from 'vue-router' 3 | 4 | /** 5 | * shim vue-router@3 typings 6 | */ 7 | 8 | // Stub VueRouter class interfaces 9 | declare interface VueRouter { 10 | app: Vue 11 | options: RouterOptions 12 | mode: RouterMode 13 | currentRoute: Route 14 | beforeEach(guard: NavigationGuard): Function 15 | beforeResolve(guard: NavigationGuard): Function 16 | afterEach(hook: (to: Route, from: Route) => any): Function 17 | push(location: RouteLocationRaw): Promise 18 | push(location: RouteLocationRaw, onComplete?: Function, onAbort?: ErrorHandler): void 19 | replace(location: RouteLocationRaw): Promise 20 | replace(location: RouteLocationRaw, onComplete?: Function, onAbort?: ErrorHandler): void 21 | go(n: number): void 22 | back(): void 23 | forward(): void 24 | match(raw: RouteLocationRaw, current?: Route, redirectedFrom?: Location): Route 25 | getMatchedComponents(to?: RouteLocationRaw | Route): Component[] 26 | onReady(cb: Function, errorCb?: ErrorHandler): void 27 | onError(cb: ErrorHandler): void 28 | addRoutes(routes: RouteConfig[]): void 29 | AddRoute(parent: string, route: RouteConfig): void 30 | AddRoute(route: RouteConfig): void 31 | resolve( 32 | to: RouteLocationRaw, 33 | current?: Route, 34 | append?: boolean 35 | ): { 36 | location: Location 37 | route: Route 38 | href: string 39 | normalizedTo: Location 40 | resolved: Route 41 | } 42 | } 43 | declare type ErrorHandler = (err: Error) => void 44 | declare type RouterMode = 'hash' | 'history' | 'abstract' 45 | declare type Dictionary = { [key: string]: T } 46 | declare interface Location { 47 | name?: string 48 | path?: string 49 | hash?: string 50 | query?: Dictionary 51 | params?: Dictionary 52 | append?: boolean 53 | replace?: boolean 54 | } 55 | declare type RawLocation = RouteLocationRaw 56 | declare interface Route { 57 | path: string 58 | name?: string | null 59 | hash: string 60 | query: LocationQuery 61 | params: RouteParams 62 | fullPath: string 63 | matched: RouteRecord[] 64 | redirectedFrom?: string 65 | meta?: RouteMeta 66 | } 67 | declare type RedirectOption = RouteLocationRaw | ((to: Route) => RouteLocationRaw) 68 | declare interface PathToRegexpOptions { 69 | sensitive?: boolean 70 | strict?: boolean 71 | end?: boolean 72 | } 73 | declare type Vue = any // emulate Vue (v2) 74 | declare type Component = any // emulate Vue Component (v2) 75 | declare type Position = { x: number; y: number } 76 | declare type PositionResult = Position | { selector: string; offset?: Position; behavior?: ScrollBehavior } | void 77 | declare interface RouterOptions { 78 | routes?: RouteConfig[] 79 | mode?: RouterMode 80 | fallback?: boolean 81 | base?: string 82 | linkActiveClass?: string 83 | linkExactActiveClass?: string 84 | parseQuery?: (query: string) => Record 85 | stringifyQuery?: (query: Record) => string 86 | scrollBehavior?: ( 87 | to: Route, 88 | from: Route, 89 | savedPosition: Position | void 90 | ) => PositionResult | Promise | undefined | null 91 | } 92 | declare type RoutePropsFunction = (route: Route) => Record 93 | declare interface _RouteConfigBase { 94 | path: string 95 | name?: string 96 | children?: RouteConfig[] 97 | redirect?: RedirectOption 98 | alias?: string | string[] 99 | meta?: RouteMeta 100 | beforeEnter?: NavigationGuard 101 | caseSensitive?: boolean 102 | pathToRegexpOptions?: PathToRegexpOptions 103 | } 104 | declare interface RouteConfigSingleView extends _RouteConfigBase { 105 | component?: Component 106 | props?: boolean | Record | RoutePropsFunction 107 | } 108 | declare interface RouteConfigMultipleViews extends _RouteConfigBase { 109 | components?: Dictionary 110 | props?: Dictionary | RoutePropsFunction> 111 | } 112 | declare type RouteConfig = RouteConfigSingleView | RouteConfigMultipleViews 113 | declare interface RouteRecordPublic { 114 | path: string 115 | components: Dictionary 116 | instances: Dictionary 117 | name?: string 118 | redirect?: RedirectOption 119 | meta: any 120 | beforeEnter?: (route: Route, redirect: (location: RouteLocationRaw) => void, next: () => void) => any 121 | props: 122 | | boolean 123 | | Record 124 | | RoutePropsFunction 125 | | Dictionary | RoutePropsFunction> 126 | } 127 | 128 | /** 129 | * Returns the router instance. Equivalent to using `$router` inside templates. 130 | */ 131 | declare function useRouter(): T 132 | /** 133 | * Returns the current route location. Equivalent to using `$route` inside templates. 134 | */ 135 | declare function useRoute(): T 136 | 137 | /** 138 | * Wheter the current vue-router version is 3 139 | */ 140 | declare const isVueRouter3: boolean 141 | /** 142 | * Wheter the current vue-router version is 4 143 | */ 144 | declare const isVueRouter4: boolean 145 | 146 | /** 147 | * Define stub vue-router 3 class 148 | */ 149 | declare class VueRouterLegacy { 150 | constructor(options?: RouterOptions) 151 | } 152 | 153 | // export vue-router@4 typings 154 | export * from 'vue-router' 155 | 156 | export { 157 | VueRouter, 158 | useRouter, 159 | useRoute, 160 | isVueRouter3, 161 | isVueRouter4, 162 | RouterMode, 163 | RawLocation, 164 | RouteLocationRaw, 165 | RedirectOption, 166 | RouteConfig, 167 | RouteRecordPublic, 168 | Location, 169 | Route 170 | } 171 | 172 | // Export dummy VueRouter class 173 | export default VueRouterLegacy 174 | 175 | /* eslint-enable @typescript-eslint/no-explicit-any */ 176 | -------------------------------------------------------------------------------- /packages/vue-router-bridge/lib/v4/index.mjs: -------------------------------------------------------------------------------- 1 | import { useRouter, useRoute } from 'vue-router' 2 | 3 | var isVueRouter3 = false 4 | var isVueRouter4 = true 5 | 6 | // stub vue-router 3 class 7 | class VueRouterLegacy { 8 | static install() {} 9 | static version = '' 10 | } 11 | 12 | export * from 'vue-router' 13 | export { useRouter, useRoute, isVueRouter3, isVueRouter4 } 14 | 15 | export default VueRouterLegacy 16 | -------------------------------------------------------------------------------- /packages/vue-router-bridge/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@intlify/vue-router-bridge", 3 | "version": "1.1.0", 4 | "description": "Vue Router bridging for Vue 2 & Vue 3", 5 | "scripts": { 6 | "postinstall": "node ./scripts/postinstall.js" 7 | }, 8 | "dependencies": { 9 | "vue-demi": ">=0.13.5 < 1.0.0" 10 | }, 11 | "peerDependencies": { 12 | "vue-router": "^4.0.0-0 || ^3.0.0", 13 | "@vue/composition-api": "^1.0.0-rc.1" 14 | }, 15 | "peerDependenciesMeta": { 16 | "vue-router": { 17 | "optional": true 18 | }, 19 | "@vue/composition-api": { 20 | "optional": true 21 | } 22 | }, 23 | "main": "lib/index.cjs", 24 | "module": "lib/index.mjs", 25 | "types": "lib/index.d.ts", 26 | "exports": { 27 | ".": { 28 | "require": "./lib/index.cjs", 29 | "import": "./lib/index.mjs" 30 | }, 31 | "./*": "./*" 32 | }, 33 | "keywords": [ 34 | "vue", 35 | "vuejs", 36 | "vue-router", 37 | "router", 38 | "bridge", 39 | "bridging", 40 | "stub", 41 | "routing" 42 | ], 43 | "files": [ 44 | "lib", 45 | "bin", 46 | "scripts", 47 | "LICENSE", 48 | "README.md" 49 | ], 50 | "bin": { 51 | "vue-router-fix": "bin/fix.js", 52 | "vue-router-switch": "bin/switch.js" 53 | }, 54 | "license": "MIT", 55 | "author": { 56 | "name": "kazuya kawaguchi", 57 | "email": "kawakazu80@gmail.com" 58 | }, 59 | "funding": "https://github.com/sponsors/kazupon", 60 | "homepage": "https://github.com/intlify/bridging/tree/main/packages/vue-router-bridge#readme", 61 | "repository": { 62 | "type": "git", 63 | "url": "git+https://github.com/intlify/bridging.git", 64 | "directory": "packages/vue-router-bridge" 65 | }, 66 | "bugs": { 67 | "url": "https://github.com/intlify/bridging/issues" 68 | }, 69 | "engines": { 70 | "node": ">= 12" 71 | }, 72 | "publishConfig": { 73 | "access": "public" 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /packages/vue-router-bridge/scripts/postinstall.js: -------------------------------------------------------------------------------- 1 | const { switchVersion, loadModule, warn } = require('./utils') // eslint-disable-line @typescript-eslint/no-var-requires 2 | 3 | const VueRouter = loadModule('vue-router/package.json') 4 | 5 | if (!VueRouter || typeof VueRouter.version !== 'string') { 6 | warn('VueRouter is not found. Please run "npm install vue-router" to install.') 7 | } else if (VueRouter.version.startsWith('3.6')) { 8 | switchVersion(3.6) 9 | } else if (VueRouter.version.startsWith('3.')) { 10 | switchVersion(3) 11 | } else if (VueRouter.version.startsWith('4.')) { 12 | switchVersion(4) 13 | } else { 14 | warn(`VueRouter version v${VueRouter.version} is not suppported.`) 15 | } 16 | -------------------------------------------------------------------------------- /packages/vue-router-bridge/scripts/switch.js: -------------------------------------------------------------------------------- 1 | const { switchVersion, warn, log } = require('./utils') // eslint-disable-line @typescript-eslint/no-var-requires 2 | 3 | const version = process.argv[2] 4 | const vueRouterEntry = process.argv[3] || 'vue-router' 5 | 6 | if (version == '3.6') { 7 | switchVersion(3.6, vueRouterEntry) 8 | log(`Switched for Vue Router 3.6 (entry: "${vueRouterEntry}")`) 9 | } else if (version == '3') { 10 | switchVersion(3, vueRouterEntry) 11 | log(`Switched for Vue Router 3 (entry: "${vueRouterEntry}")`) 12 | } else if (version == '4') { 13 | switchVersion(4, vueRouterEntry) 14 | log(`Switched for Vue Router 4 (entry: "${vueRouterEntry}")`) 15 | } else { 16 | warn(`expecting version "3" or "4" but got "${version}"`) 17 | process.exit(1) 18 | } 19 | -------------------------------------------------------------------------------- /packages/vue-router-bridge/scripts/utils.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs') // eslint-disable-line @typescript-eslint/no-var-requires 2 | const path = require('path') // eslint-disable-line @typescript-eslint/no-var-requires 3 | 4 | const DEBUG = process.env.DEBUG 5 | 6 | const dir = path.resolve(__dirname, '..', 'lib') 7 | 8 | function loadModule(name) { 9 | try { 10 | return require(name) 11 | } catch (e) { 12 | DEBUG && error(e) 13 | return undefined 14 | } 15 | } 16 | 17 | function error(...args) { 18 | console.error(`[vue-router-bridge] `, ...args) 19 | } 20 | 21 | function warn(...args) { 22 | console.warn(`[vue-router-bridge] `, ...args) 23 | } 24 | 25 | function log(...args) { 26 | console.log(`[vue-router-bridge] `, ...args) 27 | } 28 | 29 | function copy(name, version, router, esm = false) { 30 | const src = path.join(dir, `v${version}`, name) 31 | const dest = path.join(dir, name) 32 | let content = fs.readFileSync(src, 'utf-8') 33 | content = esm 34 | ? content.replace(/from 'vue-router'/g, `from '${router}'`) 35 | : content.replace(/require\('vue-router'\)/g, `require('${router}')`) 36 | try { 37 | fs.unlinkSync(dest) 38 | } catch (error) {} 39 | fs.writeFileSync(dest, content, 'utf-8') 40 | } 41 | 42 | function checkVueRouter(pkg) { 43 | const router = loadModule(pkg) 44 | if (!router) { 45 | warn('Vue Router plugin is not found. Please run "npm install vue-router" to install.') 46 | return false 47 | } 48 | return true 49 | } 50 | 51 | function checkVCA() { 52 | const demi = loadModule('vue-demi') 53 | if (!demi) { 54 | return false 55 | } 56 | 57 | if (demi.Vue.version.startsWith('2.7.')) { 58 | return true 59 | } else if (demi.Vue.version.startsWith('2.')) { 60 | const VCA = loadModule('@vue/composition-api') 61 | if (!VCA) { 62 | warn('Composition API plugin is not found. Please run "npm install @vue/composition-api" to install.') 63 | return false 64 | } 65 | return true 66 | } else { 67 | return false 68 | } 69 | } 70 | 71 | function switchVersion(version, router) { 72 | router = router || 'vue-router' 73 | if (!checkVueRouter(router)) { 74 | return 75 | } 76 | if (version === 3 && !checkVCA()) { 77 | return 78 | } 79 | copy('index.cjs', version, router) 80 | copy('index.mjs', version, router, true) 81 | copy('index.d.ts', version, router, true) 82 | } 83 | 84 | module.exports.warn = warn 85 | module.exports.log = log 86 | module.exports.loadModule = loadModule 87 | module.exports.switchVersion = switchVersion 88 | -------------------------------------------------------------------------------- /pnpm-workspace.yaml: -------------------------------------------------------------------------------- 1 | packages: 2 | - 'packages/*' 3 | -------------------------------------------------------------------------------- /renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["config:base", ":preserveSemverRanges"], 3 | "labels": ["dependency"], 4 | "automerge": true, 5 | "ignoreDeps": [], 6 | "major": { 7 | "automerge": false 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /scripts/bump.ts: -------------------------------------------------------------------------------- 1 | import { promises as fs } from 'node:fs' 2 | import { execSync } from 'node:child_process' 3 | import { resolve } from 'pathe' 4 | import { createCommonJS } from 'mlly' 5 | import { globby } from 'globby' 6 | import yaml from 'js-yaml' 7 | 8 | const { __dirname } = createCommonJS(import.meta.url) 9 | 10 | type Deps = { 11 | name: string 12 | range: string 13 | type: string 14 | } 15 | type DepsReviver = (deps: Deps) => Deps | undefined 16 | 17 | async function loadPackage(dir: string) { 18 | const pkgPath = resolve(dir, 'package.json') 19 | const data = JSON.parse(await fs.readFile(pkgPath, 'utf-8').catch(() => '{}')) 20 | const save = () => fs.writeFile(pkgPath, JSON.stringify(data, null, 2) + '\n') 21 | // const save = () => 22 | // console.log(`package: ${dir}`, JSON.stringify(data, null, 2)) 23 | 24 | const updateDeps = (reviver: DepsReviver) => { 25 | for (const type of ['dependencies', 'devDependencies', 'optionalDependencies', 'peerDependencies']) { 26 | if (!data[type]) { 27 | continue 28 | } 29 | for (const e of Object.entries(data[type])) { 30 | const dep = { name: e[0], range: e[1] as string, type } 31 | delete data[type][dep.name] 32 | const updated = reviver(dep) || dep 33 | data[updated.type] = data[updated.type] || {} 34 | data[updated.type][updated.name] = updated.range 35 | } 36 | } 37 | } 38 | 39 | return { 40 | dir, 41 | data, 42 | save, 43 | updateDeps 44 | } 45 | } 46 | 47 | type ThenArg = T extends PromiseLike ? U : T 48 | type Package = ThenArg> 49 | 50 | async function loadWorkspaceData(path: string): Promise { 51 | const workspacesYaml = await fs.readFile(path, 'utf-8') 52 | // eslint-disable-next-line @typescript-eslint/no-explicit-any 53 | const data = (yaml.load(workspacesYaml) as any).packages 54 | return Array.isArray(data) ? (data as string[]) : [] 55 | } 56 | 57 | async function loadWorkspace(dir: string, workspaces: string[] = []) { 58 | const workspacePkg = await loadPackage(dir) 59 | const workspacesYaml = await loadWorkspaceData(resolve(__dirname, '../pnpm-workspace.yaml')) 60 | workspacePkg.data.workspaces = [...workspaces, ...workspacesYaml] 61 | 62 | const pkgDirs = await globby([...(workspacePkg.data.workspaces || []), ...workspaces], { 63 | onlyDirectories: true 64 | }) 65 | 66 | const packages: Package[] = [] 67 | 68 | for (const pkgDir of pkgDirs) { 69 | const pkg = await loadPackage(pkgDir) 70 | if (!pkg.data.name) { 71 | continue 72 | } 73 | packages.push(pkg) 74 | } 75 | 76 | const find = (name: string) => { 77 | const pkg = packages.find(pkg => pkg.data.name === name) 78 | if (!pkg) { 79 | throw new Error('Workspace package not found: ' + name) 80 | } 81 | return pkg 82 | } 83 | 84 | const rename = (from: string, to: string) => { 85 | find(from).data.name = to 86 | for (const pkg of packages) { 87 | // eslint-disable-next-line @typescript-eslint/no-unused-vars 88 | pkg.updateDeps(dep => { 89 | return undefined 90 | }) 91 | } 92 | } 93 | 94 | const setVersion = (name: string, newVersion: string) => { 95 | find(name).data.version = newVersion 96 | for (const pkg of packages) { 97 | pkg.updateDeps(dep => { 98 | if (dep.name === name) { 99 | dep.range = newVersion 100 | } 101 | return undefined 102 | }) 103 | } 104 | } 105 | 106 | const save = async () => { 107 | await workspacePkg.save() 108 | return Promise.all(packages.map(pkg => pkg.save())) 109 | } 110 | 111 | return { 112 | dir, 113 | workspacePkg, 114 | packages, 115 | save, 116 | find, 117 | rename, 118 | setVersion 119 | } 120 | } 121 | 122 | async function main() { 123 | const workspace = await loadWorkspace(process.cwd()) 124 | 125 | const commit = execSync('git rev-parse --short HEAD').toString('utf-8').trim() 126 | const release = `${workspace.workspacePkg.data.version}-${commit}` 127 | 128 | for (const pkg of workspace.packages.filter(p => !p.data.private)) { 129 | workspace.setVersion(pkg.data.name, release) 130 | if (pkg.data.name !== 'vue-i18n-routing') { 131 | workspace.rename(pkg.data.name, pkg.data.name) 132 | } 133 | } 134 | 135 | await workspace.save() 136 | } 137 | 138 | main().catch(err => { 139 | console.error(err) 140 | process.exit(1) 141 | }) 142 | -------------------------------------------------------------------------------- /scripts/e2e.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | # Pack packages 6 | for PKG in packages/* ; do 7 | pushd $PKG 8 | echo "⚡ Packing $PKG ..." 9 | npm pack 10 | popd > /dev/null 11 | done 12 | 13 | # Replace deps 14 | npx jiti ./scripts/replaceDeps.ts 15 | 16 | # show the diff of deps 17 | git diff 18 | 19 | # setup examples for e2e 20 | pnpm setup:examples 21 | 22 | # just do e2e! 23 | pnpm test 24 | -------------------------------------------------------------------------------- /scripts/preinstall.mjs: -------------------------------------------------------------------------------- 1 | if (!/pnpm/.test(process.env.npm_execpath || '')) { 2 | console.warn( 3 | `\u001b[33mThis repository requires using pnpm as the package manager ` + 4 | ` for scripts to work properly.\u001b[39m\n` 5 | ) 6 | process.exit(1) 7 | } 8 | -------------------------------------------------------------------------------- /scripts/release-edge.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -xe 4 | 5 | # Restore all git changes 6 | git restore -s@ -SW -- packages 7 | 8 | # Build 9 | pnpm build 10 | 11 | # Bump versions 12 | npx jiti ./scripts/bump.ts 13 | 14 | # Update token 15 | if [[ ! -z ${NODE_AUTH_TOKEN} ]] ; then 16 | echo "//registry.npmjs.org/:_authToken=${NODE_AUTH_TOKEN}" >> ~/.npmrc 17 | echo "registry=https://registry.npmjs.org/" >> ~/.npmrc 18 | echo "always-auth=true" >> ~/.npmrc 19 | npm whoami 20 | fi 21 | 22 | # Release packages 23 | for PKG in packages/* ; do 24 | pushd $PKG 25 | echo "⚡ Publishing $PKG with edge tag" 26 | pnpm publish --access public --no-git-checks --tag edge 27 | popd 28 | done 29 | -------------------------------------------------------------------------------- /scripts/release.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | # Restore all git changes 6 | git restore -s@ -SW -- packages 7 | 8 | # Build packages 9 | pnpm build 10 | 11 | # Update token 12 | if [[ ! -z ${NODE_AUTH_TOKEN} ]] ; then 13 | echo "//registry.npmjs.org/:_authToken=${NODE_AUTH_TOKEN}" >> ~/.npmrc 14 | echo "registry=https://registry.npmjs.org/" >> ~/.npmrc 15 | echo "always-auth=true" >> ~/.npmrc 16 | npm whoami 17 | fi 18 | 19 | # Release packages 20 | for PKG in packages/* ; do 21 | pushd $PKG 22 | TAG="latest" 23 | echo "⚡ Publishing $PKG with tag $TAG" 24 | npx npm@8.17.0 publish --tag $TAG --access public --tolerate-republish 25 | popd > /dev/null 26 | done 27 | -------------------------------------------------------------------------------- /scripts/replaceDeps.ts: -------------------------------------------------------------------------------- 1 | import { promises as fs, constants as FS_CONSTANTS } from 'node:fs' 2 | import { resolve } from 'node:path' 3 | import { fileURLToPath } from 'node:url' 4 | import { readPackageJSON, writePackageJSON } from 'pkg-types' 5 | 6 | const __dirname = fileURLToPath(new URL('.', import.meta.url)) 7 | const TGZ_MAP = new Map() 8 | const PKG_MAP = { 9 | 'vue-i18n-v8-vue2': 'vue-i18n-bridge', 10 | 'vue-i18n-v9-vue3': 'vue-i18n-bridge', 11 | 'vue-router-v3-vue2': 'vue-router-bridge', 12 | 'vue-router-v36-vue2': 'vue-router-bridge', 13 | 'vue-router-v4-vue3': 'vue-router-bridge' 14 | } as Record 15 | 16 | export async function isExists(path: string) { 17 | try { 18 | await fs.access(path, FS_CONSTANTS.F_OK) 19 | return true 20 | } catch { 21 | return false 22 | } 23 | } 24 | 25 | async function main() { 26 | const packagesPath = resolve(__dirname, '../packages') 27 | for (const pkg of await fs.readdir(packagesPath)) { 28 | const pkgJson = await readPackageJSON(resolve(packagesPath, pkg, 'package.json')) 29 | const tgzPath = resolve(packagesPath, pkg, `intlify-${pkg}-${pkgJson.version}.tgz`) 30 | if (await isExists(tgzPath)) { 31 | TGZ_MAP.set(pkg, tgzPath) 32 | } 33 | } 34 | const examplesPath = resolve(__dirname, '../examples') 35 | const projectPkgJson = await readPackageJSON(resolve(__dirname, 'package.json')) 36 | for (const ex of await fs.readdir(examplesPath)) { 37 | const examplePath = resolve(examplesPath, ex, 'package.json') 38 | const pkgJson = await readPackageJSON(examplePath) 39 | const pkg = PKG_MAP[ex] 40 | const tgzPath = TGZ_MAP.get(pkg) 41 | 42 | if (pkgJson.dependencies) { 43 | if (tgzPath) { 44 | pkgJson.dependencies[`@intlify/${pkg}`] = `file:${tgzPath}` 45 | } 46 | 47 | if (projectPkgJson && projectPkgJson.devDependencies?.playwright) { 48 | pkgJson.devDependencies['playwright'] = projectPkgJson.devDependencies.playwright 49 | } 50 | await writePackageJSON(examplePath, pkgJson) 51 | } 52 | } 53 | } 54 | 55 | main().catch(err => { 56 | console.error(err) 57 | process.exit(1) 58 | }) 59 | --------------------------------------------------------------------------------