diff --git a/README.md b/README.md index e97e7a86c..b6bbe7ecd 100644 --- a/README.md +++ b/README.md @@ -12,13 +12,13 @@ [![Join the community on Discord][Badge-Discord]][Discord] [**Documentation**][Documentation] · [**Quickstart**](#quickstart) · [**Example**](#example) · [**Support**](#support) · [**Contribute**](#contribute) · [**License**](#license) + > Internationalization is the design and development of a product, application or document content that enables easy localization for target audiences that vary in culture, region, or language. > > --- [ W3C Web Internationalization FAQ](https://www.w3.org/International/questions/qa-i18n) - Lingui is an easy yet powerful internationalization framework for global projects. - **Clean and readable** - Keep your code clean and readable, while the library uses @@ -76,14 +76,14 @@ If you're a react-intl user, check out [a comparison of react-intl and Lingui](h Short example how i18n looks with JSX: ```js -import { Trans } from "@lingui/macro" +import { Trans } from "@lingui/react/macro" function App() { return ( - - Read the documentation - for more info. - + + Read the documentation + for more info. + ) } ``` @@ -131,18 +131,15 @@ The project is licensed under the [MIT][License] license. [SetupVite]: https://lingui.dev/tutorials/setup-vite [RefCLI]: https://lingui.dev/ref/cli [Examples]: https://github.com/lingui/js-lingui/tree/main/examples - [SWCPlugin]: https://lingui.dev/ref/swc-plugin [VitePlugin]: https://lingui.dev/ref/vite-plugin [ESLintPlugin]: https://lingui.dev/ref/eslint-plugin - [Badge-MainSuite-GithubCI]: https://github.com/lingui/js-lingui/workflows/main-suite/badge.svg [Badge-ReleaseWorkflowTesting-GithubCI]: https://github.com/lingui/js-lingui/workflows/release-workflow-test/badge.svg [Badge-Coverage]: https://img.shields.io/codecov/c/github/lingui/js-lingui/main.svg [Badge-PRWelcome]: https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square [Badge-Discord]: https://img.shields.io/discord/974702239358783608.svg?label=Discord&logo=Discord&colorB=7289da&style=flat-square [Contributors]: https://github.com/lingui/js-lingui/graphs/contributors - [Coverage]: https://codecov.io/gh/lingui/js-lingui [License]: https://github.com/lingui/js-lingui/blob/main/LICENSE [Contributing]: https://github.com/lingui/js-lingui/blob/main/CONTRIBUTING.md diff --git a/examples/create-react-app/package.json b/examples/create-react-app/package.json index e4ca6c099..916f054db 100644 --- a/examples/create-react-app/package.json +++ b/examples/create-react-app/package.json @@ -34,7 +34,6 @@ "devDependencies": { "@lingui/cli": "^4.8.0-next.0", "@lingui/loader": "^4.8.0-next.0", - "@lingui/macro": "^4.8.0-next.0", "@testing-library/jest-dom": "^5.16.5", "@testing-library/react": "^14.0.0", "@testing-library/user-event": "^14.4.3", diff --git a/examples/create-react-app/src/App.tsx b/examples/create-react-app/src/App.tsx index 509c746d1..e25b3875c 100644 --- a/examples/create-react-app/src/App.tsx +++ b/examples/create-react-app/src/App.tsx @@ -1,6 +1,6 @@ import "./App.css" import React, { useState } from "react" -import { Trans, Plural } from "@lingui/macro" +import { Trans, Plural } from "@lingui/react/macro" import { locales, dynamicActivate } from "./i18n" import { useLingui } from "@lingui/react" diff --git a/examples/create-react-app/yarn.lock b/examples/create-react-app/yarn.lock index 19105dbcb..46846d494 100644 --- a/examples/create-react-app/yarn.lock +++ b/examples/create-react-app/yarn.lock @@ -12,6 +12,16 @@ __metadata: languageName: node linkType: hard +"@ampproject/remapping@npm:^2.1.0": + version: 2.3.0 + resolution: "@ampproject/remapping@npm:2.3.0" + dependencies: + "@jridgewell/gen-mapping": ^0.3.5 + "@jridgewell/trace-mapping": ^0.3.24 + checksum: d3ad7b89d973df059c4e8e6d7c972cbeb1bb2f18f002a3bd04ae0707da214cb06cc06929b65aa2313b9347463df2914772298bae8b1d7973f246bb3f2ab3e8f0 + languageName: node + linkType: hard + "@ampproject/remapping@npm:^2.2.0": version: 2.2.0 resolution: "@ampproject/remapping@npm:2.2.0" @@ -62,6 +72,16 @@ __metadata: languageName: node linkType: hard +"@babel/code-frame@npm:^7.23.5": + version: 7.23.5 + resolution: "@babel/code-frame@npm:7.23.5" + dependencies: + "@babel/highlight": ^7.23.4 + chalk: ^2.4.2 + checksum: d90981fdf56a2824a9b14d19a4c0e8db93633fd488c772624b4e83e0ceac6039a27cd298a247c3214faa952bf803ba23696172ae7e7235f3b97f43ba278c569a + languageName: node + linkType: hard + "@babel/compat-data@npm:^7.17.7, @babel/compat-data@npm:^7.20.1, @babel/compat-data@npm:^7.20.5": version: 7.21.0 resolution: "@babel/compat-data@npm:7.21.0" @@ -69,6 +89,29 @@ __metadata: languageName: node linkType: hard +"@babel/core@npm:7.20.12": + version: 7.20.12 + resolution: "@babel/core@npm:7.20.12" + dependencies: + "@ampproject/remapping": ^2.1.0 + "@babel/code-frame": ^7.18.6 + "@babel/generator": ^7.20.7 + "@babel/helper-compilation-targets": ^7.20.7 + "@babel/helper-module-transforms": ^7.20.11 + "@babel/helpers": ^7.20.7 + "@babel/parser": ^7.20.7 + "@babel/template": ^7.20.7 + "@babel/traverse": ^7.20.12 + "@babel/types": ^7.20.7 + convert-source-map: ^1.7.0 + debug: ^4.1.0 + gensync: ^1.0.0-beta.2 + json5: ^2.2.2 + semver: ^6.3.0 + checksum: 62e6c3e2149a70b5c9729ef5f0d3e2e97e9dcde89fc039c8d8e3463d5d7ba9b29ee84d10faf79b61532ac1645aa62f2bd42338320617e6e3a8a4d8e2a27076e7 + languageName: node + linkType: hard + "@babel/core@npm:^7.1.0": version: 7.8.4 resolution: "@babel/core@npm:7.8.4" @@ -129,6 +172,18 @@ __metadata: languageName: node linkType: hard +"@babel/generator@npm:^7.20.7, @babel/generator@npm:^7.23.6": + version: 7.23.6 + resolution: "@babel/generator@npm:7.23.6" + dependencies: + "@babel/types": ^7.23.6 + "@jridgewell/gen-mapping": ^0.3.2 + "@jridgewell/trace-mapping": ^0.3.17 + jsesc: ^2.5.1 + checksum: 1a1a1c4eac210f174cd108d479464d053930a812798e09fee069377de39a893422df5b5b146199ead7239ae6d3a04697b45fc9ac6e38e0f6b76374390f91fc6c + languageName: node + linkType: hard + "@babel/generator@npm:^7.21.1": version: 7.21.1 resolution: "@babel/generator@npm:7.21.1" @@ -274,6 +329,13 @@ __metadata: languageName: node linkType: hard +"@babel/helper-environment-visitor@npm:^7.22.20": + version: 7.22.20 + resolution: "@babel/helper-environment-visitor@npm:7.22.20" + checksum: d80ee98ff66f41e233f36ca1921774c37e88a803b2f7dca3db7c057a5fea0473804db9fb6729e5dbfd07f4bed722d60f7852035c2c739382e84c335661590b69 + languageName: node + linkType: hard + "@babel/helper-explode-assignable-expression@npm:^7.18.6": version: 7.18.6 resolution: "@babel/helper-explode-assignable-expression@npm:7.18.6" @@ -293,6 +355,16 @@ __metadata: languageName: node linkType: hard +"@babel/helper-function-name@npm:^7.23.0": + version: 7.23.0 + resolution: "@babel/helper-function-name@npm:7.23.0" + dependencies: + "@babel/template": ^7.22.15 + "@babel/types": ^7.23.0 + checksum: e44542257b2d4634a1f979244eb2a4ad8e6d75eb6761b4cfceb56b562f7db150d134bc538c8e6adca3783e3bc31be949071527aa8e3aab7867d1ad2d84a26e10 + languageName: node + linkType: hard + "@babel/helper-function-name@npm:^7.8.3": version: 7.8.3 resolution: "@babel/helper-function-name@npm:7.8.3" @@ -322,6 +394,15 @@ __metadata: languageName: node linkType: hard +"@babel/helper-hoist-variables@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/helper-hoist-variables@npm:7.22.5" + dependencies: + "@babel/types": ^7.22.5 + checksum: 394ca191b4ac908a76e7c50ab52102669efe3a1c277033e49467913c7ed6f7c64d7eacbeabf3bed39ea1f41731e22993f763b1edce0f74ff8563fd1f380d92cc + languageName: node + linkType: hard + "@babel/helper-member-expression-to-functions@npm:^7.20.7, @babel/helper-member-expression-to-functions@npm:^7.21.0": version: 7.21.0 resolution: "@babel/helper-member-expression-to-functions@npm:7.21.0" @@ -450,6 +531,15 @@ __metadata: languageName: node linkType: hard +"@babel/helper-split-export-declaration@npm:^7.22.6": + version: 7.22.6 + resolution: "@babel/helper-split-export-declaration@npm:7.22.6" + dependencies: + "@babel/types": ^7.22.5 + checksum: e141cace583b19d9195f9c2b8e17a3ae913b7ee9b8120246d0f9ca349ca6f03cb2c001fd5ec57488c544347c0bb584afec66c936511e447fd20a360e591ac921 + languageName: node + linkType: hard + "@babel/helper-split-export-declaration@npm:^7.8.3": version: 7.8.3 resolution: "@babel/helper-split-export-declaration@npm:7.8.3" @@ -466,6 +556,13 @@ __metadata: languageName: node linkType: hard +"@babel/helper-string-parser@npm:^7.23.4": + version: 7.23.4 + resolution: "@babel/helper-string-parser@npm:7.23.4" + checksum: c0641144cf1a7e7dc93f3d5f16d5327465b6cf5d036b48be61ecba41e1eece161b48f46b7f960951b67f8c3533ce506b16dece576baef4d8b3b49f8c65410f90 + languageName: node + linkType: hard + "@babel/helper-validator-identifier@npm:^7.10.4": version: 7.10.4 resolution: "@babel/helper-validator-identifier@npm:7.10.4" @@ -480,6 +577,13 @@ __metadata: languageName: node linkType: hard +"@babel/helper-validator-identifier@npm:^7.22.20": + version: 7.22.20 + resolution: "@babel/helper-validator-identifier@npm:7.22.20" + checksum: 136412784d9428266bcdd4d91c32bcf9ff0e8d25534a9d94b044f77fe76bc50f941a90319b05aafd1ec04f7d127cd57a179a3716009ff7f3412ef835ada95bdc + languageName: node + linkType: hard + "@babel/helper-validator-option@npm:^7.18.6, @babel/helper-validator-option@npm:^7.21.0": version: 7.21.0 resolution: "@babel/helper-validator-option@npm:7.21.0" @@ -499,6 +603,17 @@ __metadata: languageName: node linkType: hard +"@babel/helpers@npm:^7.20.7": + version: 7.24.0 + resolution: "@babel/helpers@npm:7.24.0" + dependencies: + "@babel/template": ^7.24.0 + "@babel/traverse": ^7.24.0 + "@babel/types": ^7.24.0 + checksum: 2c1d9547c7a6e5aa648d4f3959252f825d4176ee52ed5430d65e50e68a138776adfd87ff3c8f9719ea6cd36601e935936d006340770ad8282b8664770aca8e33 + languageName: node + linkType: hard + "@babel/helpers@npm:^7.21.0": version: 7.21.0 resolution: "@babel/helpers@npm:7.21.0" @@ -543,6 +658,17 @@ __metadata: languageName: node linkType: hard +"@babel/highlight@npm:^7.23.4": + version: 7.23.4 + resolution: "@babel/highlight@npm:7.23.4" + dependencies: + "@babel/helper-validator-identifier": ^7.22.20 + chalk: ^2.4.2 + js-tokens: ^4.0.0 + checksum: 643acecdc235f87d925979a979b539a5d7d1f31ae7db8d89047269082694122d11aa85351304c9c978ceeb6d250591ccadb06c366f358ccee08bb9c122476b89 + languageName: node + linkType: hard + "@babel/highlight@npm:^7.8.3": version: 7.8.3 resolution: "@babel/highlight@npm:7.8.3" @@ -590,6 +716,15 @@ __metadata: languageName: node linkType: hard +"@babel/parser@npm:^7.24.0": + version: 7.24.0 + resolution: "@babel/parser@npm:7.24.0" + bin: + parser: ./bin/babel-parser.js + checksum: 4a6afec49487a212e7a27345b0c090b56905efb62c0b3a1499b0a57a5b3bf43d9d1e99e31b137080eacc24dee659a29699740d0a6289999117c0d8c5a04bd68f + languageName: node + linkType: hard + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@npm:^7.18.6": version: 7.18.6 resolution: "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@npm:7.18.6" @@ -1759,6 +1894,17 @@ __metadata: languageName: node linkType: hard +"@babel/template@npm:^7.22.15, @babel/template@npm:^7.24.0": + version: 7.24.0 + resolution: "@babel/template@npm:7.24.0" + dependencies: + "@babel/code-frame": ^7.23.5 + "@babel/parser": ^7.24.0 + "@babel/types": ^7.24.0 + checksum: f257b003c071a0cecdbfceca74185f18fe62c055469ab5c1d481aab12abeebed328e67e0a19fd978a2a8de97b28953fa4bc3da6d038a7345fdf37923b9fcdec8 + languageName: node + linkType: hard + "@babel/template@npm:^7.3.3": version: 7.10.4 resolution: "@babel/template@npm:7.10.4" @@ -1781,6 +1927,24 @@ __metadata: languageName: node linkType: hard +"@babel/traverse@npm:^7.20.12, @babel/traverse@npm:^7.24.0": + version: 7.24.0 + resolution: "@babel/traverse@npm:7.24.0" + dependencies: + "@babel/code-frame": ^7.23.5 + "@babel/generator": ^7.23.6 + "@babel/helper-environment-visitor": ^7.22.20 + "@babel/helper-function-name": ^7.23.0 + "@babel/helper-hoist-variables": ^7.22.5 + "@babel/helper-split-export-declaration": ^7.22.6 + "@babel/parser": ^7.24.0 + "@babel/types": ^7.24.0 + debug: ^4.3.1 + globals: ^11.1.0 + checksum: 790cf14a6452575ceef767285bad0dd96d14b3640ed4e6a4ddb5b592e4e66020424bac21e4a4b965ac0d2fe9ed504fe3644748b1922fb8ac37c681cb435c3995 + languageName: node + linkType: hard + "@babel/traverse@npm:^7.20.5, @babel/traverse@npm:^7.21.0, @babel/traverse@npm:^7.21.2, @babel/traverse@npm:^7.21.3, @babel/traverse@npm:^7.7.2": version: 7.21.3 resolution: "@babel/traverse@npm:7.21.3" @@ -1878,6 +2042,17 @@ __metadata: languageName: node linkType: hard +"@babel/types@npm:^7.22.5, @babel/types@npm:^7.23.0, @babel/types@npm:^7.23.6, @babel/types@npm:^7.24.0": + version: 7.24.0 + resolution: "@babel/types@npm:7.24.0" + dependencies: + "@babel/helper-string-parser": ^7.23.4 + "@babel/helper-validator-identifier": ^7.22.20 + to-fast-properties: ^2.0.0 + checksum: 4b574a37d490f621470ff36a5afaac6deca5546edcb9b5e316d39acbb20998e9c2be42f3fc0bf2b55906fc49ff2a5a6a097e8f5a726ee3f708a0b0ca93aed807 + languageName: node + linkType: hard + "@bcoe/v8-coverage@npm:^0.2.3": version: 0.2.3 resolution: "@bcoe/v8-coverage@npm:0.2.3" @@ -2622,6 +2797,17 @@ __metadata: languageName: node linkType: hard +"@jridgewell/gen-mapping@npm:^0.3.5": + version: 0.3.5 + resolution: "@jridgewell/gen-mapping@npm:0.3.5" + dependencies: + "@jridgewell/set-array": ^1.2.1 + "@jridgewell/sourcemap-codec": ^1.4.10 + "@jridgewell/trace-mapping": ^0.3.24 + checksum: ff7a1764ebd76a5e129c8890aa3e2f46045109dabde62b0b6c6a250152227647178ff2069ea234753a690d8f3c4ac8b5e7b267bbee272bffb7f3b0a370ab6e52 + languageName: node + linkType: hard + "@jridgewell/resolve-uri@npm:3.1.0": version: 3.1.0 resolution: "@jridgewell/resolve-uri@npm:3.1.0" @@ -2629,6 +2815,13 @@ __metadata: languageName: node linkType: hard +"@jridgewell/resolve-uri@npm:^3.1.0": + version: 3.1.2 + resolution: "@jridgewell/resolve-uri@npm:3.1.2" + checksum: 83b85f72c59d1c080b4cbec0fef84528963a1b5db34e4370fa4bd1e3ff64a0d80e0cee7369d11d73c704e0286fb2865b530acac7a871088fbe92b5edf1000870 + languageName: node + linkType: hard + "@jridgewell/set-array@npm:^1.0.0, @jridgewell/set-array@npm:^1.0.1": version: 1.1.2 resolution: "@jridgewell/set-array@npm:1.1.2" @@ -2636,6 +2829,13 @@ __metadata: languageName: node linkType: hard +"@jridgewell/set-array@npm:^1.2.1": + version: 1.2.1 + resolution: "@jridgewell/set-array@npm:1.2.1" + checksum: 832e513a85a588f8ed4f27d1279420d8547743cc37fcad5a5a76fc74bb895b013dfe614d0eed9cb860048e6546b798f8f2652020b4b2ba0561b05caa8c654b10 + languageName: node + linkType: hard + "@jridgewell/source-map@npm:^0.3.2": version: 0.3.2 resolution: "@jridgewell/source-map@npm:0.3.2" @@ -2653,6 +2853,13 @@ __metadata: languageName: node linkType: hard +"@jridgewell/sourcemap-codec@npm:^1.4.14": + version: 1.4.15 + resolution: "@jridgewell/sourcemap-codec@npm:1.4.15" + checksum: b881c7e503db3fc7f3c1f35a1dd2655a188cc51a3612d76efc8a6eb74728bef5606e6758ee77423e564092b4a518aba569bbb21c9bac5ab7a35b0c6ae7e344c8 + languageName: node + linkType: hard + "@jridgewell/trace-mapping@npm:^0.3.17, @jridgewell/trace-mapping@npm:^0.3.9": version: 0.3.17 resolution: "@jridgewell/trace-mapping@npm:0.3.17" @@ -2663,6 +2870,16 @@ __metadata: languageName: node linkType: hard +"@jridgewell/trace-mapping@npm:^0.3.24": + version: 0.3.25 + resolution: "@jridgewell/trace-mapping@npm:0.3.25" + dependencies: + "@jridgewell/resolve-uri": ^3.1.0 + "@jridgewell/sourcemap-codec": ^1.4.14 + checksum: 9d3c40d225e139987b50c48988f8717a54a8c994d8a948ee42e1412e08988761d0754d7d10b803061cc3aebf35f92a5dbbab493bd0e1a9ef9e89a2130e83ba34 + languageName: node + linkType: hard + "@leichtgewicht/ip-codec@npm:^2.0.1": version: 2.0.4 resolution: "@leichtgewicht/ip-codec@npm:2.0.4" @@ -2670,27 +2887,28 @@ __metadata: languageName: node linkType: hard -"@lingui/babel-plugin-extract-messages@npm:4.1.2": - version: 4.1.2 - resolution: "@lingui/babel-plugin-extract-messages@npm:4.1.2" - checksum: 61cae1343e55073ae4cd7bbaf3e77362e71799af4be4e6cfc759e4d33eef6bca0f6a312bb43654ebc0abf8717e2c77c2b421420c47dfa2f0c3cc0f96dcf67015 +"@lingui/babel-plugin-extract-messages@npm:^4.8.0-next.1": + version: 4.8.0-next.1 + resolution: "@lingui/babel-plugin-extract-messages@npm:4.8.0-next.1" + checksum: 46393bed48c86388f4e827f90b10e2105dcdcdb20d337c38cb462cf110f514e827eef796e03140e10417d082f8a5b7f552fd1fe2e641af2fccd85ec6ba3547b7 languageName: node linkType: hard -"@lingui/cli@npm:4.1.2, @lingui/cli@npm:^4.1.2": - version: 4.1.2 - resolution: "@lingui/cli@npm:4.1.2" +"@lingui/cli@npm:^4.8.0-next.0, @lingui/cli@npm:^4.8.0-next.1": + version: 4.8.0-next.1 + resolution: "@lingui/cli@npm:4.8.0-next.1" dependencies: "@babel/core": ^7.21.0 "@babel/generator": ^7.21.1 "@babel/parser": ^7.21.2 "@babel/runtime": ^7.21.0 "@babel/types": ^7.21.2 - "@lingui/babel-plugin-extract-messages": 4.1.2 - "@lingui/conf": 4.1.2 - "@lingui/core": 4.1.2 - "@lingui/format-po": 4.1.2 - "@lingui/message-utils": 4.1.2 + "@lingui/babel-plugin-extract-messages": ^4.8.0-next.1 + "@lingui/conf": ^4.8.0-next.1 + "@lingui/core": ^4.8.0-next.1 + "@lingui/format-po": ^4.8.0-next.1 + "@lingui/macro": ^4.8.0-next.1 + "@lingui/message-utils": ^4.8.0-next.1 babel-plugin-macros: ^3.0.1 chalk: ^4.1.0 chokidar: 3.5.1 @@ -2712,13 +2930,13 @@ __metadata: source-map: ^0.8.0-beta.0 bin: lingui: dist/lingui.js - checksum: 3dd985af16702f2e6fc91c6e263fbfe93cbbdcaea01e54dd5a710a583fa40a48b070f4efdd872eb6518b960d431910b9e8a07cea2000a44e634285e953fdd7c6 + checksum: edeed971eec465c105d7b3866366ae11865e4d23d77525dbeb4c9040e2f605b660b9eefe0932742961246cccd684b3130c8f117abdbc26f97134a22533a2cb1d languageName: node linkType: hard -"@lingui/conf@npm:4.1.2": - version: 4.1.2 - resolution: "@lingui/conf@npm:4.1.2" +"@lingui/conf@npm:^4.8.0-next.1": + version: 4.8.0-next.1 + resolution: "@lingui/conf@npm:4.8.0-next.1" dependencies: "@babel/runtime": ^7.20.13 chalk: ^4.1.0 @@ -2726,7 +2944,7 @@ __metadata: jest-validate: ^29.4.3 jiti: ^1.17.1 lodash.get: ^4.4.2 - checksum: 2fbeeaf0c2e7b895c3128b7e5e7e72a43d21bfd2b8f5bff6d0ec46ee8ae22d1c9af54540d7d070a21639b652ff1b9482b33504db79787801d0db693763508fe0 + checksum: ac300bd2b82bcf9f9990cadacbdc13d2983b91d0aaa93f499f293f6e8b2d60015633c3e007d9c192ed63fd648aac66bd07b57a0d879451ccce59f60f8d7075ac languageName: node linkType: hard @@ -2740,44 +2958,59 @@ __metadata: languageName: node linkType: hard -"@lingui/format-po@npm:4.1.2": - version: 4.1.2 - resolution: "@lingui/format-po@npm:4.1.2" +"@lingui/core@npm:^4.8.0-next.1": + version: 4.8.0-next.1 + resolution: "@lingui/core@npm:4.8.0-next.1" dependencies: - "@lingui/conf": 4.1.2 - "@lingui/message-utils": 4.1.2 + "@babel/runtime": ^7.20.13 + "@lingui/message-utils": ^4.8.0-next.1 + unraw: ^3.0.0 + checksum: 5c96feba95c4226723e5aefd093fe13bd7735c3bd52b03b4cec53870de8434c19ffcff0a0bb7017b4ed460839ee0ea72e6d326c685acd951703befd9ab464a95 + languageName: node + linkType: hard + +"@lingui/format-po@npm:^4.8.0-next.1": + version: 4.8.0-next.1 + resolution: "@lingui/format-po@npm:4.8.0-next.1" + dependencies: + "@lingui/conf": ^4.8.0-next.1 + "@lingui/message-utils": ^4.8.0-next.1 date-fns: ^2.29.3 pofile: ^1.1.4 - checksum: 205afaea64d59c70d876610d4480195c20a5649bc64a7618b69ba6adf702886de723517b0526129e0fccca01a4d2185c02746d7d77fc47cfc4e01cc65ee540ad + checksum: 1403e0b00d42504aecdb54d9a752c5a2a64ba33cc2b17c475e966d6284a9ead58ce29e45f20676d06ca76cc0a451c983f696b4717fdf43968ccce99fb2999f85 languageName: node linkType: hard -"@lingui/loader@npm:^4.1.2": - version: 4.1.2 - resolution: "@lingui/loader@npm:4.1.2" +"@lingui/loader@npm:^4.8.0-next.0": + version: 4.8.0-next.1 + resolution: "@lingui/loader@npm:4.8.0-next.1" dependencies: "@babel/runtime": ^7.20.13 - "@lingui/cli": 4.1.2 - "@lingui/conf": 4.1.2 + "@lingui/cli": ^4.8.0-next.1 + "@lingui/conf": ^4.8.0-next.1 peerDependencies: webpack: ^5.0.0 - checksum: 7c2d00a0de024a4f5dab3651c3d7e15b03e92e5b91c1070cbc8975f3c9c2dcb5647f460ec7b88e151e73714229549a1ac87e842ebf40e1924b5c0dace3a89767 + checksum: e407a21e2d018bc876ddc519de70377de76ff94f619afae7ce87ab48a4926333e95d0efad222ee620e9054017d36df4d515d598e65073041faabcdccf51bc600 languageName: node linkType: hard -"@lingui/macro@npm:^4.1.2": - version: 4.1.2 - resolution: "@lingui/macro@npm:4.1.2" +"@lingui/macro@npm:^4.8.0-next.0, @lingui/macro@npm:^4.8.0-next.1": + version: 4.8.0-next.1 + resolution: "@lingui/macro@npm:4.8.0-next.1" dependencies: + "@babel/core": 7.20.12 "@babel/runtime": ^7.20.13 "@babel/types": ^7.20.7 - "@lingui/conf": 4.1.2 - "@lingui/core": 4.1.2 - "@lingui/message-utils": 4.1.2 + "@lingui/conf": ^4.8.0-next.1 + "@lingui/core": ^4.8.0-next.1 + "@lingui/message-utils": ^4.8.0-next.1 peerDependencies: "@lingui/react": ^4.0.0 babel-plugin-macros: 2 || 3 - checksum: bfe69b093a0724f54fc5bccee42787c0ef8f98479524226d5a34c4d5129878138e74be429e423da99633e02da6aa82026ad39dfe01ea8334bab4a39fdf282a89 + peerDependenciesMeta: + babel-plugin-macros: + optional: true + checksum: c78f835c21c3e9ca8d0dc9f53a849da784a5ec9d63ce531fc899ed9eea9b452f82a2699d2e17a90b93e7d4b5f4a19fe3ff49427dfb95ae529e71b9b5a6caaf39 languageName: node linkType: hard @@ -2790,6 +3023,16 @@ __metadata: languageName: node linkType: hard +"@lingui/message-utils@npm:^4.8.0-next.1": + version: 4.8.0-next.1 + resolution: "@lingui/message-utils@npm:4.8.0-next.1" + dependencies: + "@messageformat/parser": ^5.0.0 + js-sha256: ^0.10.1 + checksum: d6e3b628f0491d17473a546aa5d1a0af62295de525604babfa0d2b7f1e6130888f40ebabc2614af6a179e5c6cfa7033d077bf620b118bb985cc072d56b1f67d1 + languageName: node + linkType: hard + "@lingui/react@npm:^4.1.2": version: 4.1.2 resolution: "@lingui/react@npm:4.1.2" @@ -5053,7 +5296,7 @@ __metadata: languageName: node linkType: hard -"chalk@npm:^2.0.0, chalk@npm:^2.4.1": +"chalk@npm:^2.0.0, chalk@npm:^2.4.1, chalk@npm:^2.4.2": version: 2.4.2 resolution: "chalk@npm:2.4.2" dependencies: @@ -5571,10 +5814,10 @@ __metadata: version: 0.0.0-use.local resolution: "create-react-ts-app@workspace:." dependencies: - "@lingui/cli": ^4.1.2 + "@lingui/cli": ^4.8.0-next.0 "@lingui/core": ^4.1.2 - "@lingui/loader": ^4.1.2 - "@lingui/macro": ^4.1.2 + "@lingui/loader": ^4.8.0-next.0 + "@lingui/macro": ^4.8.0-next.0 "@lingui/react": ^4.1.2 "@testing-library/jest-dom": ^5.16.5 "@testing-library/react": ^14.0.0 @@ -5936,7 +6179,7 @@ __metadata: languageName: node linkType: hard -"debug@npm:4, debug@npm:^4.3.2, debug@npm:^4.3.3, debug@npm:^4.3.4": +"debug@npm:4, debug@npm:^4.3.1, debug@npm:^4.3.2, debug@npm:^4.3.3, debug@npm:^4.3.4": version: 4.3.4 resolution: "debug@npm:4.3.4" dependencies: @@ -9587,6 +9830,13 @@ __metadata: languageName: node linkType: hard +"js-sha256@npm:^0.10.1": + version: 0.10.1 + resolution: "js-sha256@npm:0.10.1" + checksum: 6eb5c9f95aa902cec1930f036deb3bc664024b75fede456c0ac74b855797776c18620f47efec36787077a56ba2f3b8d6aacc7733ff8a2b5bb9ce6b655a35c5e6 + languageName: node + linkType: hard + "js-tokens@npm:^3.0.0 || ^4.0.0, js-tokens@npm:^4.0.0": version: 4.0.0 resolution: "js-tokens@npm:4.0.0" @@ -14515,6 +14765,13 @@ __metadata: languageName: node linkType: hard +"unraw@npm:^3.0.0": + version: 3.0.0 + resolution: "unraw@npm:3.0.0" + checksum: 19eee0bc500ce197d262b79723a2c8c81c1d716baaa2a62c48a4d0d6b9e1fd9d350c5df86262e51343d591ab9c8a47ed150317d0b867b2b65795cdc17ef69873 + languageName: node + linkType: hard + "upath@npm:^1.2.0": version: 1.2.0 resolution: "upath@npm:1.2.0" diff --git a/examples/js/package.json b/examples/js/package.json index 6d67ccc6b..076ed79f1 100644 --- a/examples/js/package.json +++ b/examples/js/package.json @@ -12,8 +12,7 @@ "extract": "lingui extract --clean" }, "dependencies": { - "@lingui/core": "^4.1.2", - "@lingui/macro": "^4.1.2" + "@lingui/core": "^4.1.2" }, "devDependencies": { "@babel/core": "^7.20.12", diff --git a/examples/js/src/ids.js b/examples/js/src/ids.js index 42bb3159c..a5fd14cbb 100644 --- a/examples/js/src/ids.js +++ b/examples/js/src/ids.js @@ -1,5 +1,5 @@ import { i18n } from "@lingui/core" -import { t, plural, defineMessage } from "@lingui/macro" +import { t, plural, defineMessage } from "@lingui/core/macro" i18n.load({ en: require("./locale/en/messages").messages, diff --git a/examples/js/src/messages.js b/examples/js/src/messages.js index 378e17b13..3ec0210a6 100644 --- a/examples/js/src/messages.js +++ b/examples/js/src/messages.js @@ -1,5 +1,5 @@ import { i18n } from "@lingui/core" -import { t, plural, defineMessage } from "@lingui/macro" +import { t, plural, defineMessage } from "@lingui/core/macro" i18n.load({ en: require("./locale/en/messages").messages, diff --git a/examples/nextjs-babel/package.json b/examples/nextjs-babel/package.json index 0c72406f6..ccb31d28f 100644 --- a/examples/nextjs-babel/package.json +++ b/examples/nextjs-babel/package.json @@ -19,7 +19,6 @@ "devDependencies": { "@lingui/cli": "^4.8.0-next.0", "@lingui/loader": "^4.8.0-next.0", - "@lingui/macro": "^4.8.0-next.0", "@types/react": "^18.0.28", "babel-plugin-macros": "^3.1.0", "typescript": "^4.9.5", diff --git a/examples/nextjs-babel/src/components/Layout.tsx b/examples/nextjs-babel/src/components/Layout.tsx index d38e99f5e..c43f11538 100644 --- a/examples/nextjs-babel/src/components/Layout.tsx +++ b/examples/nextjs-babel/src/components/Layout.tsx @@ -1,7 +1,7 @@ import Head from "next/head" import classnames from "classnames" -import { t, Trans, useLingui } from "@lingui/macro" +import { Trans, useLingui } from "@lingui/react/macro" import styles from "./Layout.module.css" import { useRouter } from "next/router" diff --git a/examples/nextjs-babel/src/pages/examples.tsx b/examples/nextjs-babel/src/pages/examples.tsx index 95f3f5efb..5dfc2cb51 100644 --- a/examples/nextjs-babel/src/pages/examples.tsx +++ b/examples/nextjs-babel/src/pages/examples.tsx @@ -1,4 +1,5 @@ -import { Trans, Plural, plural, msg } from "@lingui/macro" +import { plural, msg } from "@lingui/core/macro" +import { Trans, Plural } from "@lingui/react/macro" import { Layout } from "../components/Layout" import { PluralExample } from "../components/PluralExample" diff --git a/examples/nextjs-babel/src/pages/index.tsx b/examples/nextjs-babel/src/pages/index.tsx index 7fc141161..260f36479 100644 --- a/examples/nextjs-babel/src/pages/index.tsx +++ b/examples/nextjs-babel/src/pages/index.tsx @@ -1,6 +1,6 @@ import Link from "next/link" -import { Trans } from "@lingui/macro" +import { Trans } from "@lingui/react/macro" import { Layout } from "../components/Layout" import styles from "./index.module.css" diff --git a/examples/nextjs-swc/package.json b/examples/nextjs-swc/package.json index d16d0d2ff..043a47aa4 100644 --- a/examples/nextjs-swc/package.json +++ b/examples/nextjs-swc/package.json @@ -20,7 +20,6 @@ "devDependencies": { "@lingui/cli": "^4.8.0-next.0", "@lingui/loader": "^4.8.0-next.0", - "@lingui/macro": "^4.8.0-next.0", "@lingui/swc-plugin": "4.0.6", "@types/react": "^18.0.14", "eslint": "8.35.0", diff --git a/examples/nextjs-swc/src/components/AboutText.tsx b/examples/nextjs-swc/src/components/AboutText.tsx index a8cc9bb69..87f24d511 100644 --- a/examples/nextjs-swc/src/components/AboutText.tsx +++ b/examples/nextjs-swc/src/components/AboutText.tsx @@ -1,4 +1,4 @@ -import { Trans } from '@lingui/macro' +import { Trans } from '@lingui/react/macro' export function AboutText() { return ( diff --git a/examples/nextjs-swc/src/components/Developers.tsx b/examples/nextjs-swc/src/components/Developers.tsx index 027f5bf4d..013607233 100644 --- a/examples/nextjs-swc/src/components/Developers.tsx +++ b/examples/nextjs-swc/src/components/Developers.tsx @@ -1,5 +1,5 @@ import { useState } from 'react' -import { Trans, Plural } from '@lingui/macro' +import { Trans, Plural } from '@lingui/react/macro' export default function Developers() { const [selected, setSelected] = useState('1') diff --git a/examples/nextjs-swc/src/components/Switcher.tsx b/examples/nextjs-swc/src/components/Switcher.tsx index 2b43020ba..c1bd9cf95 100644 --- a/examples/nextjs-swc/src/components/Switcher.tsx +++ b/examples/nextjs-swc/src/components/Switcher.tsx @@ -1,7 +1,7 @@ import { useRouter } from 'next/router' import { useState } from 'react' -import { t, msg } from '@lingui/macro' -import { MessageDescriptor } from '@lingui/core/src' +import { t, msg } from '@lingui/core/macro' +import { MessageDescriptor } from '@lingui/core' import { useLingui } from '@lingui/react' type LOCALES = 'en' | 'sr' | 'es' | 'pseudo' diff --git a/examples/nextjs-swc/src/pages/index.tsx b/examples/nextjs-swc/src/pages/index.tsx index 5269c75b1..37e7b53fd 100644 --- a/examples/nextjs-swc/src/pages/index.tsx +++ b/examples/nextjs-swc/src/pages/index.tsx @@ -1,4 +1,5 @@ -import { msg, Trans } from '@lingui/macro' +import { msg } from '@lingui/core/macro' +import { Trans } from '@lingui/react/macro' import { GetStaticProps, NextPage } from 'next' import Head from 'next/head' import { AboutText } from '../components/AboutText' diff --git a/examples/react-native/package.json b/examples/react-native/package.json index 374891e16..82e463067 100644 --- a/examples/react-native/package.json +++ b/examples/react-native/package.json @@ -28,7 +28,6 @@ "devDependencies": { "@babel/core": "^7.21.0", "@lingui/cli": "^4.1.2", - "@lingui/macro": "^4.1.2", "@react-native-community/eslint-config": "^3.2.0", "@types/react": "~18.0.14", "@typescript-eslint/eslint-plugin": "^5.59.11", diff --git a/examples/react-native/src/MainScreen.tsx b/examples/react-native/src/MainScreen.tsx index a0fa90da5..a16990904 100644 --- a/examples/react-native/src/MainScreen.tsx +++ b/examples/react-native/src/MainScreen.tsx @@ -1,13 +1,13 @@ import React, { useState } from "react"; import { StyleSheet, Text, View, Alert, SafeAreaView } from "react-native"; -import { Plural, SelectOrdinal, t, Trans } from "@lingui/macro"; -import { useLingui } from "@lingui/react"; +import { Plural, SelectOrdinal, Trans } from "@lingui/react/macro"; +import { useLingui } from "@lingui/react/macro"; import { Button } from "./PaddedButton"; import { Heading } from "./Components"; export const Body = React.memo(() => { const [messages, setMessages] = useState([]); - const { i18n } = useLingui(); + const { i18n, t } = useLingui(); const markAllAsRead = () => { // NOTE - here we're implicitly using the i18n instance that does NOT come from the React context, but from @lingui/core @@ -65,6 +65,8 @@ const Inbox = ({ markAsRead: () => void; addMessage: () => void; }) => { + const { t } = useLingui(); + const messagesCount = messages.length; return ( diff --git a/examples/rspack/package.json b/examples/rspack/package.json index 0d340aae2..622fdd34b 100644 --- a/examples/rspack/package.json +++ b/examples/rspack/package.json @@ -24,7 +24,6 @@ "devDependencies": { "@babel/core": "^7.22.10", "@lingui/cli": "^4.4.0", - "@lingui/macro": "^4.4.0", "@rspack/cli": "latest", "@types/react": "18.2.0", "@types/react-dom": "18.2.1", diff --git a/examples/rspack/src/Inbox.tsx b/examples/rspack/src/Inbox.tsx index bbb99848e..a63db4210 100644 --- a/examples/rspack/src/Inbox.tsx +++ b/examples/rspack/src/Inbox.tsx @@ -1,35 +1,44 @@ -import React from "react"; +import React from "react" -import { useLingui } from "@lingui/react"; +import { useLingui } from "@lingui/react" -import { Trans, Plural } from "@lingui/macro"; +import { Trans, Plural } from "@lingui/react/macro" -import LocaleSwitcher from './LocaleSwitcher'; +import LocaleSwitcher from "./LocaleSwitcher" export default function Inbox() { - const messages = [{}, {}]; - const messagesCount = messages.length; - const lastLogin = new Date(); - const markAsRead = () => { - alert("Marked as read."); - }; - const { i18n } = useLingui(); + const messages = [{}, {}] + const messagesCount = messages.length + const lastLogin = new Date() + const markAsRead = () => { + alert("Marked as read.") + } + const { i18n } = useLingui() - return ( -
- -

Message Inbox

-

- - See all unread messages - {" or "} - mark them as read. - -

-

- -

- < footer > Last login on {i18n.date(lastLogin)}. -
- ); -} \ No newline at end of file + return ( +
+ +

+ Message Inbox +

+

+ + See all unread messages + {" or "} + mark them as read. + +

+

+ +

+
+ {" "} + Last login on {i18n.date(lastLogin)}. +
+
+ ) +} diff --git a/examples/vite-project-react-babel/package.json b/examples/vite-project-react-babel/package.json index f4e339a4e..feeffa105 100644 --- a/examples/vite-project-react-babel/package.json +++ b/examples/vite-project-react-babel/package.json @@ -10,8 +10,8 @@ "preview": "vite preview" }, "dependencies": { - "@lingui/macro": "^4.1.2", "@lingui/react": "^4.1.2", + "@lingui/core": "^4.1.2", "react": "^18.2.0", "react-dom": "^18.2.0" }, diff --git a/examples/vite-project-react-babel/src/App.tsx b/examples/vite-project-react-babel/src/App.tsx index f49b33473..6e4bf77c5 100644 --- a/examples/vite-project-react-babel/src/App.tsx +++ b/examples/vite-project-react-babel/src/App.tsx @@ -3,7 +3,7 @@ import reactLogo from "./assets/react.svg" import linguiLogo from "./assets/lingui-logo.svg" import viteLogo from "/vite.svg" import "./App.css" -import { Plural, Trans } from "@lingui/macro" +import { Plural, Trans } from "@lingui/react/macro" import { I18nProvider } from "@lingui/react" import { i18n } from "@lingui/core" import { loadCatalog } from "./i18n" diff --git a/examples/vite-project-react-swc/package.json b/examples/vite-project-react-swc/package.json index 2f4819bb7..8676a69ea 100644 --- a/examples/vite-project-react-swc/package.json +++ b/examples/vite-project-react-swc/package.json @@ -13,7 +13,7 @@ "@swc/core": "1.3.56" }, "dependencies": { - "@lingui/macro": "^4.2.0", + "@lingui/core": "^4.2.0", "@lingui/react": "^4.2.0", "react": "^18.2.0", "react-dom": "^18.2.0" diff --git a/examples/vite-project-react-swc/src/App.tsx b/examples/vite-project-react-swc/src/App.tsx index 70b17c488..996e21c8e 100644 --- a/examples/vite-project-react-swc/src/App.tsx +++ b/examples/vite-project-react-swc/src/App.tsx @@ -3,7 +3,7 @@ import reactLogo from "./assets/react.svg" import linguiLogo from "./assets/lingui-logo.svg" import viteLogo from "/vite.svg" import "./App.css" -import { Plural, Trans } from "@lingui/macro" +import { Plural, Trans } from "@lingui/react/macro" import { I18nProvider } from "@lingui/react" import { i18n } from "@lingui/core" import { loadCatalog } from "./i18n" diff --git a/jest.config.js b/jest.config.js index 4299de529..19e6dc374 100644 --- a/jest.config.js +++ b/jest.config.js @@ -59,6 +59,7 @@ module.exports = { setupFilesAfterEnv: [require.resolve("./scripts/jest/env.js")], roots: [ "/packages/babel-plugin-extract-messages", + "/packages/babel-plugin-lingui-macro", "/packages/cli", "/packages/conf", "/packages/loader", diff --git a/packages/babel-plugin-extract-messages/package.json b/packages/babel-plugin-extract-messages/package.json index 3be8a712e..6f62b5bb0 100644 --- a/packages/babel-plugin-extract-messages/package.json +++ b/packages/babel-plugin-extract-messages/package.json @@ -43,8 +43,8 @@ "@babel/core": "^7.21.0", "@babel/traverse": "7.20.12", "@babel/types": "^7.20.7", + "@lingui/babel-plugin-lingui-macro": "workspace:*", "@lingui/jest-mocks": "workspace:*", - "@lingui/macro": "workspace:*", "unbuild": "2.0.0" } } diff --git a/packages/babel-plugin-extract-messages/test/__snapshots__/index.ts.snap b/packages/babel-plugin-extract-messages/test/__snapshots__/index.ts.snap index b2ec7dda0..a121c767e 100644 --- a/packages/babel-plugin-extract-messages/test/__snapshots__/index.ts.snap +++ b/packages/babel-plugin-extract-messages/test/__snapshots__/index.ts.snap @@ -149,7 +149,7 @@ exports[`@lingui/babel-plugin-extract-messages should extract Plural messages fr message: {count, plural, one {# book} other {# books}}, origin: [ jsx-without-trans.js, - 3, + 2, ], }, { @@ -159,7 +159,7 @@ exports[`@lingui/babel-plugin-extract-messages should extract Plural messages fr message: {count, plural, one {# book} other {# books}}, origin: [ jsx-without-trans.js, - 4, + 3, ], }, ] @@ -174,7 +174,7 @@ exports[`@lingui/babel-plugin-extract-messages should extract all messages from message: Message, origin: [ js-with-macros.js, - 3, + 4, ], }, { @@ -184,7 +184,7 @@ exports[`@lingui/babel-plugin-extract-messages should extract all messages from message: Message, origin: [ js-with-macros.js, - 5, + 6, ], }, { @@ -194,7 +194,7 @@ exports[`@lingui/babel-plugin-extract-messages should extract all messages from message: Description, origin: [ js-with-macros.js, - 7, + 8, ], }, { @@ -204,7 +204,7 @@ exports[`@lingui/babel-plugin-extract-messages should extract all messages from message: Message with id, origin: [ js-with-macros.js, - 12, + 13, ], }, { @@ -214,7 +214,7 @@ exports[`@lingui/babel-plugin-extract-messages should extract all messages from message: Values {param}, origin: [ js-with-macros.js, - 17, + 18, ], }, { @@ -224,7 +224,7 @@ exports[`@lingui/babel-plugin-extract-messages should extract all messages from message: Message with id some, origin: [ js-with-macros.js, - 19, + 20, ], }, { @@ -234,7 +234,7 @@ exports[`@lingui/babel-plugin-extract-messages should extract all messages from message: undefined, origin: [ js-with-macros.js, - 24, + 25, ], }, { @@ -244,7 +244,7 @@ exports[`@lingui/babel-plugin-extract-messages should extract all messages from message: undefined, origin: [ js-with-macros.js, - 28, + 29, ], }, { @@ -254,7 +254,7 @@ exports[`@lingui/babel-plugin-extract-messages should extract all messages from message: undefined, origin: [ js-with-macros.js, - 33, + 34, ], }, { @@ -264,7 +264,7 @@ exports[`@lingui/babel-plugin-extract-messages should extract all messages from message: undefined, origin: [ js-with-macros.js, - 38, + 39, ], }, { @@ -274,7 +274,7 @@ exports[`@lingui/babel-plugin-extract-messages should extract all messages from message: undefined, origin: [ js-with-macros.js, - 43, + 44, ], }, { @@ -284,7 +284,7 @@ exports[`@lingui/babel-plugin-extract-messages should extract all messages from message: TplLiteral, origin: [ js-with-macros.js, - 48, + 49, ], }, { @@ -294,7 +294,7 @@ exports[`@lingui/babel-plugin-extract-messages should extract all messages from message: [useLingui]: TplLiteral, origin: [ js-with-macros.js, - 53, + 54, ], }, { @@ -304,7 +304,7 @@ exports[`@lingui/babel-plugin-extract-messages should extract all messages from message: [useLingui]: Text {0, plural, offset:1 =0 {No books} =1 {1 book} other {# books}}, origin: [ js-with-macros.js, - 56, + 57, ], }, ] diff --git a/packages/babel-plugin-extract-messages/test/fixtures/js-with-macros.js b/packages/babel-plugin-extract-messages/test/fixtures/js-with-macros.js index d2c2e10ea..564320d27 100644 --- a/packages/babel-plugin-extract-messages/test/fixtures/js-with-macros.js +++ b/packages/babel-plugin-extract-messages/test/fixtures/js-with-macros.js @@ -1,4 +1,5 @@ -import { t, defineMessage, msg, useLingui, plural } from "@lingui/macro" +import { t, defineMessage, msg, plural } from "@lingui/core/macro" +import { useLingui } from "@lingui/react/macro" t`Message` diff --git a/packages/babel-plugin-extract-messages/test/fixtures/jsx-with-macros.js b/packages/babel-plugin-extract-messages/test/fixtures/jsx-with-macros.js index e9662b4e1..c14c5c394 100644 --- a/packages/babel-plugin-extract-messages/test/fixtures/jsx-with-macros.js +++ b/packages/babel-plugin-extract-messages/test/fixtures/jsx-with-macros.js @@ -1,5 +1,5 @@ -import { t, plural, Trans } from "@lingui/macro" - +import { Trans } from "@lingui/react/macro" +import { t, plural } from "@lingui/core/macro" ;Hi, my name is {name} ;Some message ;Some other message @@ -8,6 +8,6 @@ import { t, plural, Trans } from "@lingui/macro" ; diff --git a/packages/babel-plugin-extract-messages/test/fixtures/jsx-without-trans.js b/packages/babel-plugin-extract-messages/test/fixtures/jsx-without-trans.js index 1e9667701..6a6d0eecc 100644 --- a/packages/babel-plugin-extract-messages/test/fixtures/jsx-without-trans.js +++ b/packages/babel-plugin-extract-messages/test/fixtures/jsx-without-trans.js @@ -1,4 +1,3 @@ -import { Plural } from "@lingui/macro"; - +import { Plural } from "@lingui/react/macro" ; ; diff --git a/packages/babel-plugin-extract-messages/test/index.ts b/packages/babel-plugin-extract-messages/test/index.ts index 796548a89..8e67a165e 100644 --- a/packages/babel-plugin-extract-messages/test/index.ts +++ b/packages/babel-plugin-extract-messages/test/index.ts @@ -3,7 +3,9 @@ import fs from "fs" import { transform as babelTransform } from "@babel/core" import plugin, { ExtractedMessage, ExtractPluginOpts } from "../src/index" import { mockConsole } from "@lingui/jest-mocks" -import linguiMacroPlugin, { type LinguiPluginOpts } from "@lingui/macro/plugin" +import linguiMacroPlugin, { + type LinguiPluginOpts, +} from "@lingui/babel-plugin-lingui-macro" const transform = (filename: string) => { const rootDir = path.join(__dirname, "fixtures") diff --git a/packages/babel-plugin-lingui-macro/README.md b/packages/babel-plugin-lingui-macro/README.md new file mode 100644 index 000000000..733081af1 --- /dev/null +++ b/packages/babel-plugin-lingui-macro/README.md @@ -0,0 +1,40 @@ +[![License][badge-license]][license] +[![Version][badge-version]][package] +[![Downloads][badge-downloads]][package] + +# @lingui/babel-plugin-lingui-macro + +> Babel plugin that does actual transforms of Lingui's Macros + +`@lingui/babel-plugin-lingui-macro` is part of [LinguiJS][linguijs]. See the [documentation][documentation] for all information, tutorials and examples. + +## Installation + +```sh +npm install --save-dev @lingui/babel-plugin-lingui-macro +# yarn add --dev @lingui/babel-plugin-lingui-macro +``` + +## Usage + +### Via `.babelrc` + +**.babelrc** + +```json +{ + "plugins": ["@lingui/babel-plugin-lingui-macro"] +} +``` + +## License + +[MIT][license] + +[license]: https://github.com/lingui/js-lingui/blob/main/LICENSE +[linguijs]: https://github.com/lingui/js-lingui +[documentation]: https://lingui.dev +[package]: https://www.npmjs.com/package/@lingui/babel-plugin-lingui-macro +[badge-downloads]: https://img.shields.io/npm/dw/@lingui/babel-plugin-lingui-macro.svg +[badge-version]: https://img.shields.io/npm/v/@lingui/babel-plugin-lingui-macro.svg +[badge-license]: https://img.shields.io/npm/l/@lingui/babel-plugin-lingui-macro.svg diff --git a/packages/babel-plugin-lingui-macro/package.json b/packages/babel-plugin-lingui-macro/package.json new file mode 100644 index 000000000..41d3f4772 --- /dev/null +++ b/packages/babel-plugin-lingui-macro/package.json @@ -0,0 +1,96 @@ +{ + "name": "@lingui/babel-plugin-lingui-macro", + "version": "4.8.0-next.1", + "description": "Babel plugin for transforming Lingui Macros", + "main": "./dist/index.cjs", + "module": "./dist/index.mjs", + "types": "./dist/index.d.ts", + "contributors": [ + { + "name": "Timofei Iatsenko", + "email": "timiatsenko@gmail.com" + } + ], + "author": { + "name": "Tomáš Ehrlich", + "email": "tomas.ehrlich@gmail.com" + }, + "publishConfig": { + "access": "public" + }, + "license": "MIT", + "keywords": [ + "babel-plugin", + "i18n", + "internationalization", + "i10n", + "localization", + "i9n", + "translation", + "multilingual" + ], + "scripts": { + "build": "rimraf ./dist && unbuild", + "stub": "unbuild --stub" + }, + "exports": { + ".": { + "require": { + "types": "./dist/index.d.cts", + "default": "./dist/index.cjs" + }, + "import": { + "types": "./dist/index.d.mts", + "default": "./dist/index.mjs" + } + }, + "./macro": { + "require": { + "types": "./dist/macro.d.cts", + "default": "./dist/macro.cjs" + }, + "import": { + "types": "./dist/macro.d.mts", + "default": "./dist/macro.mjs" + } + } + }, + "files": [ + "LICENSE", + "README.md", + "dist/" + ], + "repository": { + "type": "git", + "url": "https://github.com/lingui/js-lingui.git" + }, + "bugs": { + "url": "https://github.com/lingui/js-lingui/issues" + }, + "engines": { + "node": ">=16.0.0" + }, + "dependencies": { + "@babel/core": "^7.20.12", + "@babel/runtime": "^7.20.13", + "@babel/types": "^7.20.7", + "@lingui/conf": "4.8.0-next.1", + "@lingui/core": "4.8.0-next.1", + "@lingui/message-utils": "4.8.0-next.1" + }, + "peerDependencies": { + "babel-plugin-macros": "2 || 3" + }, + "peerDependenciesMeta": { + "babel-plugin-macros": { + "optional": true + } + }, + "devDependencies": { + "@babel/parser": "^7.20.15", + "@babel/traverse": "^7.20.12", + "@types/babel-plugin-macros": "^2.8.5", + "prettier": "2.8.3", + "unbuild": "2.0.0" + } +} diff --git a/packages/macro/src/constants.ts b/packages/babel-plugin-lingui-macro/src/constants.ts similarity index 74% rename from packages/macro/src/constants.ts rename to packages/babel-plugin-lingui-macro/src/constants.ts index 00def66ca..e74209e98 100644 --- a/packages/macro/src/constants.ts +++ b/packages/babel-plugin-lingui-macro/src/constants.ts @@ -3,7 +3,9 @@ export const MESSAGE = "message" export const COMMENT = "comment" export const EXTRACT_MARK = "i18n" export const CONTEXT = "context" -export const MACRO_PACKAGE = "@lingui/macro" +export const MACRO_LEGACY_PACKAGE = "@lingui/macro" +export const MACRO_CORE_PACKAGE = "@lingui/core/macro" +export const MACRO_REACT_PACKAGE = "@lingui/react/macro" export enum JsMacroName { t = "t", diff --git a/packages/macro/src/icu.test.ts b/packages/babel-plugin-lingui-macro/src/icu.test.ts similarity index 100% rename from packages/macro/src/icu.test.ts rename to packages/babel-plugin-lingui-macro/src/icu.test.ts diff --git a/packages/macro/src/icu.ts b/packages/babel-plugin-lingui-macro/src/icu.ts similarity index 100% rename from packages/macro/src/icu.ts rename to packages/babel-plugin-lingui-macro/src/icu.ts diff --git a/packages/macro/src/plugin.ts b/packages/babel-plugin-lingui-macro/src/index.ts similarity index 95% rename from packages/macro/src/plugin.ts rename to packages/babel-plugin-lingui-macro/src/index.ts index 4bda43dc1..99637953b 100644 --- a/packages/macro/src/plugin.ts +++ b/packages/babel-plugin-lingui-macro/src/index.ts @@ -3,7 +3,11 @@ import type * as babelTypes from "@babel/types" import MacroJSX from "./macroJsx" import { NodePath } from "@babel/traverse" import MacroJs from "./macroJs" -import { MACRO_PACKAGE } from "./constants" +import { + MACRO_CORE_PACKAGE, + MACRO_REACT_PACKAGE, + MACRO_LEGACY_PACKAGE, +} from "./constants" import { type LinguiConfigNormalized, getConfig as loadConfig, @@ -83,7 +87,11 @@ export default function ({ return path.get("body").filter((statement) => { return ( statement.isImportDeclaration() && - statement.get("source").node.value === MACRO_PACKAGE + [ + MACRO_CORE_PACKAGE, + MACRO_REACT_PACKAGE, + MACRO_LEGACY_PACKAGE, + ].includes(statement.get("source").node.value) ) }) } diff --git a/packages/macro/src/index.ts b/packages/babel-plugin-lingui-macro/src/macro.ts similarity index 86% rename from packages/macro/src/index.ts rename to packages/babel-plugin-lingui-macro/src/macro.ts index f8051e334..13319d82f 100644 --- a/packages/macro/src/index.ts +++ b/packages/babel-plugin-lingui-macro/src/macro.ts @@ -3,7 +3,7 @@ import { createMacro, MacroParams } from "babel-plugin-macros" import { VisitNodeObject } from "@babel/traverse" import { Program } from "@babel/types" -import linguiPlugin from "../src/plugin" +import linguiPlugin from "./index" import { JsMacroName, JsxMacroName } from "./constants" function macro({ state, babel, config }: MacroParams) { @@ -43,7 +43,7 @@ function macro({ state, babel, config }: MacroParams) { Object.defineProperty(module.exports, name, { get() { throw new Error( - `The macro you imported from "@lingui/macro" is being executed outside the context of compilation with babel-plugin-macros. ` + + `The macro you imported from "@lingui/core/macro" or "@lingui/react/macro" is being executed outside the context of compilation with babel-plugin-macros. ` + `This indicates that you don't have the babel plugin "babel-plugin-macros" configured correctly. ` + `Please see the documentation for how to configure babel-plugin-macros properly: ` + "https://github.com/kentcdodds/babel-plugin-macros/blob/main/other/docs/user.md" @@ -54,4 +54,4 @@ function macro({ state, babel, config }: MacroParams) { export default createMacro(macro, { configName: "lingui", -}) +}) as { isBabelMacro: true } diff --git a/packages/macro/src/macroJs.test.ts b/packages/babel-plugin-lingui-macro/src/macroJs.test.ts similarity index 99% rename from packages/macro/src/macroJs.test.ts rename to packages/babel-plugin-lingui-macro/src/macroJs.test.ts index 6284540fa..2fda267a1 100644 --- a/packages/macro/src/macroJs.test.ts +++ b/packages/babel-plugin-lingui-macro/src/macroJs.test.ts @@ -8,7 +8,7 @@ import { JsMacroName } from "./constants" const parseExpression = (expression: string) => { let path: NodePath - const importExp = `import {t, plural, select, selectOrdinal} from "@lingui/macro"; \n` + const importExp = `import {t, plural, select, selectOrdinal} from "@lingui/core/macro"; \n` transformSync(importExp + expression, { filename: "unit-test.js", configFile: false, diff --git a/packages/macro/src/macroJs.ts b/packages/babel-plugin-lingui-macro/src/macroJs.ts similarity index 97% rename from packages/macro/src/macroJs.ts rename to packages/babel-plugin-lingui-macro/src/macroJs.ts index 2b4eae976..e85332c3e 100644 --- a/packages/macro/src/macroJs.ts +++ b/packages/babel-plugin-lingui-macro/src/macroJs.ts @@ -26,8 +26,10 @@ import { EXTRACT_MARK, ID, MESSAGE, - MACRO_PACKAGE, + MACRO_CORE_PACKAGE, JsMacroName, + MACRO_REACT_PACKAGE, + MACRO_LEGACY_PACKAGE, } from "./constants" import { generateMessageId } from "@lingui/message-utils/generateMessageId" @@ -154,10 +156,7 @@ export default class MacroJs { } // { t } = useLingui() - if ( - path.isCallExpression() && - this.isLinguiIdentifier(path.get("callee"), JsMacroName.useLingui) - ) { + if (path.isCallExpression() && this.isUseLinguiHook(path.get("callee"))) { this.needsUseLinguiImport = true return this.processUseLingui(path) } @@ -622,7 +621,21 @@ export default class MacroJs { * Custom matchers */ isLinguiIdentifier(path: NodePath, name: JsMacroName) { - if (path.isIdentifier() && path.referencesImport(MACRO_PACKAGE, name)) { + if ( + path.isIdentifier() && + (path.referencesImport(MACRO_CORE_PACKAGE, name) || + path.referencesImport(MACRO_LEGACY_PACKAGE, name)) + ) { + return true + } + } + + isUseLinguiHook(path: NodePath) { + if ( + path.isIdentifier() && + (path.referencesImport(MACRO_REACT_PACKAGE, JsMacroName.useLingui) || + path.referencesImport(MACRO_LEGACY_PACKAGE, JsMacroName.useLingui)) + ) { return true } } diff --git a/packages/macro/src/macroJsx.test.ts b/packages/babel-plugin-lingui-macro/src/macroJsx.test.ts similarity index 99% rename from packages/macro/src/macroJsx.test.ts rename to packages/babel-plugin-lingui-macro/src/macroJsx.test.ts index 2bb7b81a4..1624c9ca1 100644 --- a/packages/macro/src/macroJsx.test.ts +++ b/packages/babel-plugin-lingui-macro/src/macroJsx.test.ts @@ -8,7 +8,7 @@ import { JsxMacroName } from "./constants" const parseExpression = (expression: string) => { let path: NodePath - const importExp = `import {Trans, Plural, Select, SelectOrdinal} from "@lingui/macro";\n` + const importExp = `import {Trans, Plural, Select, SelectOrdinal} from "@lingui/react/macro";\n` transformSync(importExp + expression, { filename: "unit-test.js", diff --git a/packages/macro/src/macroJsx.ts b/packages/babel-plugin-lingui-macro/src/macroJsx.ts similarity index 97% rename from packages/macro/src/macroJsx.ts rename to packages/babel-plugin-lingui-macro/src/macroJsx.ts index 936a13655..55786c2a9 100644 --- a/packages/macro/src/macroJsx.ts +++ b/packages/babel-plugin-lingui-macro/src/macroJsx.ts @@ -26,8 +26,9 @@ import { CONTEXT, ID, MESSAGE, - MACRO_PACKAGE, JsxMacroName, + MACRO_REACT_PACKAGE, + MACRO_LEGACY_PACKAGE, } from "./constants" import { generateMessageId } from "@lingui/message-utils/generateMessageId" @@ -505,12 +506,15 @@ export default class MacroJSX { path: NodePath, name: JsxMacroName ): path is NodePath => { + if (!path.isJSXElement()) { + return false + } + + const identifier = path.get("openingElement").get("name") + return ( - path.isJSXElement() && - path - .get("openingElement") - .get("name") - .referencesImport(MACRO_PACKAGE, name) + identifier.referencesImport(MACRO_REACT_PACKAGE, name) || + identifier.referencesImport(MACRO_LEGACY_PACKAGE, name) ) } diff --git a/packages/macro/src/utils.ts b/packages/babel-plugin-lingui-macro/src/utils.ts similarity index 100% rename from packages/macro/src/utils.ts rename to packages/babel-plugin-lingui-macro/src/utils.ts diff --git a/packages/macro/test/fixtures/js-t-continuation-character.expected.js b/packages/babel-plugin-lingui-macro/test/fixtures/js-t-continuation-character.expected.js similarity index 100% rename from packages/macro/test/fixtures/js-t-continuation-character.expected.js rename to packages/babel-plugin-lingui-macro/test/fixtures/js-t-continuation-character.expected.js diff --git a/packages/babel-plugin-lingui-macro/test/fixtures/js-t-continuation-character.js b/packages/babel-plugin-lingui-macro/test/fixtures/js-t-continuation-character.js new file mode 100644 index 000000000..5af6829cf --- /dev/null +++ b/packages/babel-plugin-lingui-macro/test/fixtures/js-t-continuation-character.js @@ -0,0 +1,4 @@ +import { t } from "@lingui/core/macro" + +t`Multiline\ + with continuation` diff --git a/packages/macro/test/fixtures/js-t-var/js-t-var.expected.js b/packages/babel-plugin-lingui-macro/test/fixtures/js-t-var/js-t-var.expected.js similarity index 100% rename from packages/macro/test/fixtures/js-t-var/js-t-var.expected.js rename to packages/babel-plugin-lingui-macro/test/fixtures/js-t-var/js-t-var.expected.js diff --git a/packages/macro/test/fixtures/js-t-var/js-t-var.js b/packages/babel-plugin-lingui-macro/test/fixtures/js-t-var/js-t-var.js similarity index 68% rename from packages/macro/test/fixtures/js-t-var/js-t-var.js rename to packages/babel-plugin-lingui-macro/test/fixtures/js-t-var/js-t-var.js index 0cb13358a..c0156daf3 100644 --- a/packages/macro/test/fixtures/js-t-var/js-t-var.js +++ b/packages/babel-plugin-lingui-macro/test/fixtures/js-t-var/js-t-var.js @@ -1,6 +1,6 @@ -import { t } from '@lingui/macro' +import { t } from "@lingui/core/macro" -function scoped (foo) { +function scoped(foo) { if (foo) { const bar = 50 t`This is bar ${bar}` diff --git a/packages/macro/test/fixtures/jsx-plural-select-nested.expected.js b/packages/babel-plugin-lingui-macro/test/fixtures/jsx-plural-select-nested.expected.js similarity index 100% rename from packages/macro/test/fixtures/jsx-plural-select-nested.expected.js rename to packages/babel-plugin-lingui-macro/test/fixtures/jsx-plural-select-nested.expected.js diff --git a/packages/macro/test/fixtures/jsx-plural-select-nested.js b/packages/babel-plugin-lingui-macro/test/fixtures/jsx-plural-select-nested.js similarity index 94% rename from packages/macro/test/fixtures/jsx-plural-select-nested.js rename to packages/babel-plugin-lingui-macro/test/fixtures/jsx-plural-select-nested.js index a97a44685..07d3ac8f8 100644 --- a/packages/macro/test/fixtures/jsx-plural-select-nested.js +++ b/packages/babel-plugin-lingui-macro/test/fixtures/jsx-plural-select-nested.js @@ -1,6 +1,5 @@ -import { Select, Plural } from '@lingui/macro'; - - - Message - -) - -// @ts-expect-error: `value` could be string only -m = - -// @ts-expect-error: `value` required -m = - -// @ts-expect-error: exact cases should be prefixed with underscore -m = ...} - other={...} - /> -) - -//////////////////////// -//// React useLingui() -//////////////////////// -function MyComponent() { - const { t, i18n } = useLingui() - - expectType(t`Hello world`) - expectType(t({ message: "my message" })) - // @ts-expect-error: you could not pass a custom instance here - t(i18n)({ message: "my message" }) - - expectType(i18n) -} diff --git a/packages/core/macro/__typetests__/tsconfig.json b/packages/core/macro/__typetests__/tsconfig.json new file mode 100644 index 000000000..d6980fa22 --- /dev/null +++ b/packages/core/macro/__typetests__/tsconfig.json @@ -0,0 +1,7 @@ +{ + "compilerOptions": { + "esModuleInterop": true, + "skipLibCheck": true + }, + "paths": {} +} diff --git a/packages/core/macro/index.d.ts b/packages/core/macro/index.d.ts new file mode 100644 index 000000000..17deeca28 --- /dev/null +++ b/packages/core/macro/index.d.ts @@ -0,0 +1,214 @@ +import type { I18n, MessageDescriptor } from "@lingui/core" + +export type ChoiceOptions = { + /** Offset of value when calculating plural forms */ + offset?: number + zero?: string + one?: string + two?: string + few?: string + many?: string + + /** Catch-all option */ + other: string + /** Exact match form, corresponds to =N rule */ + [digit: `${number}`]: string +} + +type MacroMessageDescriptor = ( + | { + id: string + message?: string + } + | { + id?: string + message: string + } +) & { + comment?: string + context?: string +} + +/** + * Translates a message descriptor + * + * @example + * ``` + * import { t } from "@lingui/core/macro"; + * const message = t({ + * id: "msg.hello", + * comment: "Greetings at the homepage", + * message: `Hello ${name}`, + * }); + * ``` + * + * @example + * ``` + * import { t } from "@lingui/core/macro"; + * const message = t({ + * id: "msg.plural", + * message: plural(value, { one: "...", other: "..." }), + * }); + * ``` + * + * @param descriptor The message descriptor to translate + */ +export function t(descriptor: MacroMessageDescriptor): string + +/** + * Translates a template string using the global I18n instance + * + * @example + * ``` + * import { t } from "@lingui/core/macro"; + * const message = t`Hello ${name}`; + * ``` + */ +export function t( + literals: TemplateStringsArray, + ...placeholders: any[] +): string + +/** + * Translates a template string or message descriptor using a given I18n instance + * + * @example + * ``` + * import { t } from "@lingui/core/macro"; + * import { I18n } from "@lingui/core"; + * const i18n = new I18n({ + * locale: "nl", + * messages: { "Hello {0}": "Hallo {0}" }, + * }); + * const message = t(i18n)`Hello ${name}`; + * ``` + * + * @example + * ``` + * import { t } from "@lingui/core/macro"; + * import { I18n } from "@lingui/core"; + * const i18n = new I18n({ + * locale: "nl", + * messages: { "Hello {0}": "Hallo {0}" }, + * }); + * const message = t(i18n)({ message: `Hello ${name}` }); + * ``` + */ +export function t(i18n: I18n): { + (literals: TemplateStringsArray, ...placeholders: any[]): string + (descriptor: MacroMessageDescriptor): string +} + +/** + * Pluralize a message + * + * @example + * ``` + * import { plural } from "@lingui/core/macro"; + * const message = plural(count, { + * one: "# Book", + * other: "# Books", + * }); + * ``` + * + * @param value Determines the plural form + * @param options Object with available plural forms + */ +export function plural(value: number | string, options: ChoiceOptions): string + +/** + * Pluralize a message using ordinal forms + * + * Similar to `plural` but instead of using cardinal plural forms, + * it uses ordinal forms. + * + * @example + * ``` + * import { selectOrdinal } from "@lingui/core/macro"; + * const message = selectOrdinal(count, { + * one: "#st", + * two: "#nd", + * few: "#rd", + * other: "#th", + * }); + * ``` + * + * @param value Determines the plural form + * @param options Object with available plural forms + */ +export function selectOrdinal( + value: number | string, + options: ChoiceOptions +): string + +type SelectOptions = { + /** Catch-all option */ + other: string + [matches: string]: string +} + +/** + * Selects a translation based on a value + * + * Select works like a switch statement. It will + * select one of the forms in `options` object which + * key matches exactly `value`. + * + * @example + * ``` + * import { select } from "@lingui/core/macro"; + * const message = select(gender, { + * male: "he", + * female: "she", + * other: "they", + * }); + * ``` + * + * @param value The key of choices to use + * @param choices + */ +export function select(value: string, choices: SelectOptions): string + +/** + * Define a message for later use + * + * `defineMessage` can be used to add comments for translators, + * or to override the message ID. + * + * @example + * ``` + * import { defineMessage } from "@lingui/core/macro"; + * const message = defineMessage({ + * comment: "Greetings on the welcome page", + * message: `Welcome, ${name}!`, + * }); + * ``` + * + * @param descriptor The message descriptor + */ +export function defineMessage( + descriptor: MacroMessageDescriptor +): MessageDescriptor + +/** + * Define a message for later use + * + * @example + * ``` + * import { defineMessage, msg } from "@lingui/core/macro"; + * const message = defineMessage`Hello ${name}`; + * + * // or using shorter version + * const message = msg`Hello ${name}`; + * ``` + */ +export function defineMessage( + literals: TemplateStringsArray, + ...placeholders: any[] +): MessageDescriptor + +/** + * Define a message for later use + * Alias for {@see defineMessage} + */ +export const msg: typeof defineMessage diff --git a/packages/core/macro/index.js b/packages/core/macro/index.js new file mode 100644 index 000000000..fad7573b3 --- /dev/null +++ b/packages/core/macro/index.js @@ -0,0 +1 @@ +module.exports = require("@lingui/babel-plugin-lingui-macro/macro") diff --git a/packages/core/macro/index.test.ts b/packages/core/macro/index.test.ts new file mode 100644 index 000000000..d0f728d4f --- /dev/null +++ b/packages/core/macro/index.test.ts @@ -0,0 +1,7 @@ +import macro from "@lingui/core/macro" + +describe("react-macro", () => { + it("Should re-export Macro", () => { + expect((macro as any).isBabelMacro).toBeTruthy() + }) +}) diff --git a/packages/core/package.json b/packages/core/package.json index 9c624cf9d..14cab61b3 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -45,12 +45,20 @@ "default": "./dist/index.mjs" } }, + "./macro": { + "require": { + "types": "./macro/index.d.ts", + "default": "./macro/index.js" + } + }, "./package.json": "./package.json" }, "files": [ "LICENSE", "README.md", - "dist/" + "dist/", + "macro/index.d.ts", + "macro/index.js" ], "dependencies": { "@babel/runtime": "^7.20.13", @@ -59,6 +67,19 @@ }, "devDependencies": { "@lingui/jest-mocks": "*", + "tsd": "^0.26.1", "unbuild": "2.0.0" + }, + "peerDependencies": { + "@lingui/babel-plugin-lingui-macro": "4.8.0-next.1", + "babel-plugin-macros": "2 || 3" + }, + "peerDependenciesMeta": { + "@lingui/babel-plugin-lingui-macro": { + "optional": true + }, + "babel-plugin-macros": { + "optional": true + } } } diff --git a/packages/macro/README.md b/packages/macro/README.md index 8dfd2e450..872810319 100644 --- a/packages/macro/README.md +++ b/packages/macro/README.md @@ -24,7 +24,7 @@ See the [reference][reference] documentation. ```jsx import { setupI18n } from "@lingui/core" -import { t } from "@lingui/macro" +import { t } from "@lingui/core/macro" const i18n = setupI18n() diff --git a/packages/macro/build.config.ts b/packages/macro/build.config.ts deleted file mode 100644 index ab91d5fa3..000000000 --- a/packages/macro/build.config.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { defineBuildConfig } from "unbuild" - -export default defineBuildConfig({ - declaration: false, -}) diff --git a/packages/macro/global.d.ts b/packages/macro/global.d.ts deleted file mode 100644 index 3473c7249..000000000 --- a/packages/macro/global.d.ts +++ /dev/null @@ -1,225 +0,0 @@ -// read more about this file here -// https://github.com/lingui/js-lingui/issues/936 -// @ts-ignore -declare module "@lingui/macro" { - import type { MessageDescriptor, I18n } from "@lingui/core" - - type MacroMessageDescriptor = ( - | { - id: string - message?: string - } - | { - id?: string - message: string - } - ) & { - comment?: string - context?: string - } - - export type BasicType = { - id?: string - comment?: string - } - - /** - * Translates a message descriptor - * - * @example - * ``` - * import { t } from "@lingui/macro"; - * const message = t({ - * id: "msg.hello", - * comment: "Greetings at the homepage", - * message: `Hello ${name}`, - * }); - * ``` - * - * @example - * ``` - * import { t } from "@lingui/macro"; - * const message = t({ - * id: "msg.plural", - * message: plural(value, { one: "...", other: "..." }), - * }); - * ``` - * - * @param descriptor The message descriptor to translate - */ - export function t(descriptor: MacroMessageDescriptor): string - - /** - * Translates a template string using the global I18n instance - * - * @example - * ``` - * import { t } from "@lingui/macro"; - * const message = t`Hello ${name}`; - * ``` - */ - export function t( - literals: TemplateStringsArray, - ...placeholders: any[] - ): string - - /** - * Translates a template string or message descriptor using a given I18n instance - * - * @example - * ``` - * import { t } from "@lingui/macro"; - * import { I18n } from "@lingui/core"; - * const i18n = new I18n({ - * locale: "nl", - * messages: { "Hello {0}": "Hallo {0}" }, - * }); - * const message = t(i18n)`Hello ${name}`; - * ``` - * - * @example - * ``` - * import { t } from "@lingui/macro"; - * import { I18n } from "@lingui/core"; - * const i18n = new I18n({ - * locale: "nl", - * messages: { "Hello {0}": "Hallo {0}" }, - * }); - * const message = t(i18n)({ message: `Hello ${name}` }); - * ``` - */ - export function t(i18n: I18n): { - (literals: TemplateStringsArray, ...placeholders: any[]): string - (descriptor: MacroMessageDescriptor): string - } - - export type UnderscoreDigit = { [digit: string]: T } - export type ChoiceOptions = { - offset?: number - zero?: T - one?: T - few?: T - many?: T - other?: T - } & UnderscoreDigit - - /** - * Pluralize a message - * - * @example - * ``` - * import { plural } from "@lingui/macro"; - * const message = plural(count, { - * one: "# Book", - * other: "# Books", - * }); - * ``` - * - * @param value Determines the plural form - * @param options Object with available plural forms - */ - export function plural( - value: number | string, - options: ChoiceOptions & BasicType - ): string - - /** - * Pluralize a message using ordinal forms - * - * Similar to `plural` but instead of using cardinal plural forms, - * it uses ordinal forms. - * - * @example - * ``` - * import { selectOrdinal } from "@lingui/macro"; - * const message = selectOrdinal(count, { - * one: "#st", - * two: "#nd", - * few: "#rd", - * other: "#th", - * }); - * ``` - * - * @param value Determines the plural form - * @param options Object with available plural forms - */ - export function selectOrdinal( - value: number | string, - options: ChoiceOptions & BasicType - ): string - - /** - * Selects a translation based on a value - * - * Select works like a switch statement. It will - * select one of the forms in `options` object which - * key matches exactly `value`. - * - * @example - * ``` - * import { select } from "@lingui/macro"; - * const message = select(gender, { - * male: "he", - * female: "she", - * other: "they", - * }); - * ``` - * - * @param value The key of choices to use - * @param choices - */ - export function select( - value: string, - choices: Record & BasicType - ): string - - /** - * Define a message for later use - * - * `defineMessage` can be used to add comments for translators, - * or to override the message ID. - * - * @example - * ``` - * import { defineMessage } from "@lingui/macro"; - * const message = defineMessage({ - * comment: "Greetings on the welcome page", - * message: `Welcome, ${name}!`, - * }); - * ``` - * - * @param descriptor The message descriptor - */ - export function defineMessage( - descriptor: MacroMessageDescriptor - ): MessageDescriptor - - export type ChoiceProps = { - value?: string | number - } & ChoiceOptions - - /** - * The types should be changed after this PR is merged - * https://github.com/Microsoft/TypeScript/pull/26797 - * - * then we should be able to specify that key of values is same type as value. - * We would be able to remove separate type Values = {...} definition - * eg. - * type SelectProps = { - * value?: Values - * [key: Values]: string - * } - * - */ - type Values = { [key: string]: string } - - export type SelectProps = { - value: string - other: any - } & Values - - export const Trans: any - export const Plural: any - export const Select: any - export const SelectOrdinal: any -} diff --git a/packages/macro/index.d.ts b/packages/macro/index.d.ts index 8c6a84e8d..510eade7b 100644 --- a/packages/macro/index.d.ts +++ b/packages/macro/index.d.ts @@ -1,351 +1,8 @@ -// eslint-disable-next-line import/no-extraneous-dependencies -import type { ReactNode, VFC, FC } from "react" -import type { I18n, MessageDescriptor } from "@lingui/core" -import type { TransRenderCallbackOrComponent, I18nContext } from "@lingui/react" - -export type ChoiceOptions = { - /** Offset of value when calculating plural forms */ - offset?: number - zero?: string - one?: string - two?: string - few?: string - many?: string - - /** Catch-all option */ - other: string - /** Exact match form, corresponds to =N rule */ - [digit: `${number}`]: string -} - -type MacroMessageDescriptor = ( - | { - id: string - message?: string - } - | { - id?: string - message: string - } -) & { - comment?: string - context?: string -} - /** - * Translates a message descriptor - * - * @example - * ``` - * import { t } from "@lingui/macro"; - * const message = t({ - * id: "msg.hello", - * comment: "Greetings at the homepage", - * message: `Hello ${name}`, - * }); - * ``` - * - * @example - * ``` - * import { t } from "@lingui/macro"; - * const message = t({ - * id: "msg.plural", - * message: plural(value, { one: "...", other: "..." }), - * }); - * ``` - * - * @param descriptor The message descriptor to translate + * @deprecated please use `@lingui/core/macro` directly */ -export function t(descriptor: MacroMessageDescriptor): string - +export * from "@lingui/core/macro" /** - * Translates a template string using the global I18n instance - * - * @example - * ``` - * import { t } from "@lingui/macro"; - * const message = t`Hello ${name}`; - * ``` + * @deprecated please use `@lingui/react/macro` directly */ -export function t( - literals: TemplateStringsArray, - ...placeholders: any[] -): string - -/** - * Translates a template string or message descriptor using a given I18n instance - * - * @example - * ``` - * import { t } from "@lingui/macro"; - * import { I18n } from "@lingui/core"; - * const i18n = new I18n({ - * locale: "nl", - * messages: { "Hello {0}": "Hallo {0}" }, - * }); - * const message = t(i18n)`Hello ${name}`; - * ``` - * - * @example - * ``` - * import { t } from "@lingui/macro"; - * import { I18n } from "@lingui/core"; - * const i18n = new I18n({ - * locale: "nl", - * messages: { "Hello {0}": "Hallo {0}" }, - * }); - * const message = t(i18n)({ message: `Hello ${name}` }); - * ``` - */ -export function t(i18n: I18n): { - (literals: TemplateStringsArray, ...placeholders: any[]): string - (descriptor: MacroMessageDescriptor): string -} - -/** - * Pluralize a message - * - * @example - * ``` - * import { plural } from "@lingui/macro"; - * const message = plural(count, { - * one: "# Book", - * other: "# Books", - * }); - * ``` - * - * @param value Determines the plural form - * @param options Object with available plural forms - */ -export function plural(value: number | string, options: ChoiceOptions): string - -/** - * Pluralize a message using ordinal forms - * - * Similar to `plural` but instead of using cardinal plural forms, - * it uses ordinal forms. - * - * @example - * ``` - * import { selectOrdinal } from "@lingui/macro"; - * const message = selectOrdinal(count, { - * one: "#st", - * two: "#nd", - * few: "#rd", - * other: "#th", - * }); - * ``` - * - * @param value Determines the plural form - * @param options Object with available plural forms - */ -export function selectOrdinal( - value: number | string, - options: ChoiceOptions -): string - -type SelectOptions = { - /** Catch-all option */ - other: string - [matches: string]: string -} - -/** - * Selects a translation based on a value - * - * Select works like a switch statement. It will - * select one of the forms in `options` object which - * key matches exactly `value`. - * - * @example - * ``` - * import { select } from "@lingui/macro"; - * const message = select(gender, { - * male: "he", - * female: "she", - * other: "they", - * }); - * ``` - * - * @param value The key of choices to use - * @param choices - */ -export function select(value: string, choices: SelectOptions): string - -/** - * Define a message for later use - * - * `defineMessage` can be used to add comments for translators, - * or to override the message ID. - * - * @example - * ``` - * import { defineMessage } from "@lingui/macro"; - * const message = defineMessage({ - * comment: "Greetings on the welcome page", - * message: `Welcome, ${name}!`, - * }); - * ``` - * - * @param descriptor The message descriptor - */ -export function defineMessage( - descriptor: MacroMessageDescriptor -): MessageDescriptor - -/** - * Define a message for later use - * - * @example - * ``` - * import { defineMessage, msg } from "@lingui/macro"; - * const message = defineMessage`Hello ${name}`; - * - * // or using shorter version - * const message = msg`Hello ${name}`; - * ``` - */ -export function defineMessage( - literals: TemplateStringsArray, - ...placeholders: any[] -): MessageDescriptor - -/** - * Define a message for later use - * Alias for {@see defineMessage} - */ -export const msg: typeof defineMessage - -type CommonProps = TransRenderCallbackOrComponent & { - id?: string - comment?: string - context?: string -} - -type TransProps = { - children: ReactNode -} & CommonProps - -type PluralChoiceProps = { - value: string | number - /** Offset of value when calculating plural forms */ - offset?: number - zero?: ReactNode - one?: ReactNode - two?: ReactNode - few?: ReactNode - many?: ReactNode - - /** Catch-all option */ - other: ReactNode - /** Exact match form, corresponds to =N rule */ - [digit: `_${number}`]: ReactNode -} & CommonProps - -type SelectChoiceProps = { - value: string - /** Catch-all option */ - other: ReactNode - [option: `_${string}`]: ReactNode -} & CommonProps - -/** - * Trans is the basic macro for static messages, - * messages with variables, but also for messages with inline markup - * - * @example - * ``` - * Hello {username}. Read the docs. - * ``` - * @example - * ``` - * Hello {username}. - * ``` - */ -export const Trans: FC - -/** - * Props of Plural macro are transformed into plural format. - * - * @example - * ``` - * import { Plural } from "@lingui/macro" - * - * - * // ↓ ↓ ↓ ↓ ↓ ↓ - * import { Trans } from "@lingui/react" - * - * ``` - */ -export const Plural: VFC -/** - * Props of SelectOrdinal macro are transformed into selectOrdinal format. - * - * @example - * ``` - * // count == 1 -> 1st - * // count == 2 -> 2nd - * // count == 3 -> 3rd - * // count == 4 -> 4th - * - * ``` - */ -export const SelectOrdinal: VFC - -/** - * Props of Select macro are transformed into select format - * - * @example - * ``` - * // gender == "female" -> Her book - * // gender == "male" -> His book - * // gender == "non-binary" -> Their book - * - * + Message + +) + +// @ts-expect-error: `value` could be string only +m = + +// @ts-expect-error: `value` required +m = + +// @ts-expect-error: exact cases should be prefixed with underscore +m = ...} + other={...} + /> +) + +//////////////////////// +//// React useLingui() +//////////////////////// +function MyComponent() { + const { t, i18n } = useLingui() + + expectType(t`Hello world`) + expectType(t({ message: "my message" })) + // @ts-expect-error: you could not pass a custom instance here + t(i18n)({ message: "my message" }) + + expectType(i18n) +} diff --git a/packages/macro/__typetests__/tsconfig.json b/packages/react/macro/__typetests__/tsconfig.json similarity index 100% rename from packages/macro/__typetests__/tsconfig.json rename to packages/react/macro/__typetests__/tsconfig.json diff --git a/packages/react/macro/index.d.ts b/packages/react/macro/index.d.ts new file mode 100644 index 000000000..13d98ab7d --- /dev/null +++ b/packages/react/macro/index.d.ts @@ -0,0 +1,137 @@ +import type { ReactNode, VFC, FC } from "react" +import type { TransRenderCallbackOrComponent, I18nContext } from "@lingui/react" +import type { MacroMessageDescriptor } from "@lingui/core/macro" + +type CommonProps = TransRenderCallbackOrComponent & { + id?: string + comment?: string + context?: string +} + +type TransProps = { + children: ReactNode +} & CommonProps + +type PluralChoiceProps = { + value: string | number + /** Offset of value when calculating plural forms */ + offset?: number + zero?: ReactNode + one?: ReactNode + two?: ReactNode + few?: ReactNode + many?: ReactNode + + /** Catch-all option */ + other: ReactNode + /** Exact match form, corresponds to =N rule */ + [digit: `_${number}`]: ReactNode +} & CommonProps + +type SelectChoiceProps = { + value: string + /** Catch-all option */ + other: ReactNode + [option: `_${string}`]: ReactNode +} & CommonProps + +/** + * Trans is the basic macro for static messages, + * messages with variables, but also for messages with inline markup + * + * @example + * ``` + * Hello {username}. Read the docs. + * ``` + * @example + * ``` + * Hello {username}. + * ``` + */ +export const Trans: FC + +/** + * Props of Plural macro are transformed into plural format. + * + * @example + * ``` + * import { Plural } from "@lingui/core/macro" + * + * + * // ↓ ↓ ↓ ↓ ↓ ↓ + * import { Trans } from "@lingui/react" + * + * ``` + */ +export const Plural: VFC +/** + * Props of SelectOrdinal macro are transformed into selectOrdinal format. + * + * @example + * ``` + * // count == 1 -> 1st + * // count == 2 -> 2nd + * // count == 3 -> 3rd + * // count == 4 -> 4th + * + * ``` + */ +export const SelectOrdinal: VFC + +/** + * Props of Select macro are transformed into select format + * + * @example + * ``` + * // gender == "female" -> Her book + * // gender == "male" -> His book + * // gender == "non-binary" -> Their book + * + *