├── .github └── workflows │ └── test.yml ├── .gitignore ├── .vscode └── launch.json ├── LICENSE ├── README.md ├── index.d.ts ├── mocha.opts ├── package-lock.json ├── package.json ├── rollup.config.js ├── rollup.config.test.js ├── src ├── htmlxparser.ts ├── htmlxtojsx.ts ├── index.ts ├── knownevents.ts ├── svelte2tsx.ts └── svgattributes.ts ├── svelte-jsx.d.ts ├── svelte-shims.d.ts ├── test ├── helpers.js ├── htmlx2jsx │ ├── index.js │ └── samples │ │ ├── action-bare │ │ ├── expected.jsx │ │ └── input.svelte │ │ ├── action-params │ │ ├── expected.jsx │ │ └── input.svelte │ │ ├── animation-bare │ │ ├── expected.jsx │ │ └── input.svelte │ │ ├── animation-params │ │ ├── expected.jsx │ │ └── input.svelte │ │ ├── attribute-bare │ │ ├── expected.jsx │ │ └── input.svelte │ │ ├── attribute-multiple │ │ ├── expected.jsx │ │ └── input.svelte │ │ ├── attribute-quoted │ │ ├── expected.jsx │ │ └── input.svelte │ │ ├── attribute-shorthand │ │ ├── expected.jsx │ │ └── input.svelte │ │ ├── attribute-text │ │ ├── expected.jsx │ │ └── input.svelte │ │ ├── auto-closing-tag │ │ ├── expected.jsx │ │ └── input.svelte │ │ ├── await-block-basic-catch │ │ ├── expected.jsx │ │ └── input.svelte │ │ ├── await-block-basic │ │ ├── expected.jsx │ │ └── input.svelte │ │ ├── await-block-pending-catch │ │ ├── expected.jsx │ │ └── input.svelte │ │ ├── await-block-pending │ │ ├── expected.jsx │ │ └── input.svelte │ │ ├── binding-bare │ │ ├── expected.jsx │ │ └── input.svelte │ │ ├── binding-group │ │ ├── expected.jsx │ │ └── input.svelte │ │ ├── binding-oneway │ │ ├── expected.jsx │ │ └── input.svelte │ │ ├── binding-this-component │ │ ├── expected.jsx │ │ └── input.svelte │ │ ├── binding-this │ │ ├── expected.jsx │ │ └── input.svelte │ │ ├── binding │ │ ├── expected.jsx │ │ └── input.svelte │ │ ├── class-bare │ │ ├── expected.jsx │ │ └── input.svelte │ │ ├── class │ │ ├── expected.jsx │ │ └── input.svelte │ │ ├── comment │ │ ├── expected.jsx │ │ └── input.svelte │ │ ├── component-default-slot-let │ │ ├── expected.jsx │ │ └── input.svelte │ │ ├── component-default-slot │ │ ├── expected.jsx │ │ └── input.svelte │ │ ├── component-multi-slot │ │ ├── expected.jsx │ │ └── input.svelte │ │ ├── component-no-slots │ │ ├── expected.jsx │ │ └── input.svelte │ │ ├── debug-block │ │ ├── expected.jsx │ │ └── input.svelte │ │ ├── directive-quoted │ │ ├── expected.jsx │ │ └── input.svelte │ │ ├── each-block-basic │ │ ├── expected.jsx │ │ └── input.svelte │ │ ├── each-block-index │ │ ├── expected.jsx │ │ └── input.svelte │ │ ├── each-block-key-else │ │ ├── expected.jsx │ │ └── input.svelte │ │ ├── each-block-key │ │ ├── expected.jsx │ │ └── input.svelte │ │ ├── element-only │ │ ├── expected.jsx │ │ └── input.svelte │ │ ├── event-handler-bare │ │ ├── expected.jsx │ │ └── input.svelte │ │ ├── event-handler-component-bare │ │ ├── expected.jsx │ │ └── input.svelte │ │ ├── event-handler-component │ │ ├── expected.jsx │ │ └── input.svelte │ │ ├── event-handler-modifiers │ │ ├── expected.jsx │ │ └── input.svelte │ │ ├── event-handler │ │ ├── expected.jsx │ │ └── input.svelte │ │ ├── html-block │ │ ├── expected.jsx │ │ └── input.svelte │ │ ├── if-block │ │ ├── expected.jsx │ │ └── input.svelte │ │ ├── if-else-block │ │ ├── expected.jsx │ │ └── input.svelte │ │ ├── if-else-if-block │ │ ├── expected.jsx │ │ └── input.svelte │ │ ├── namespaced-attributes │ │ ├── expected.jsx │ │ └── input.svelte │ │ ├── simple-expression │ │ ├── expected.jsx │ │ └── input.svelte │ │ ├── svg-attributes │ │ ├── expected.jsx │ │ └── input.svelte │ │ ├── transition-bare │ │ ├── expected.jsx │ │ └── input.svelte │ │ ├── transition-modifiers │ │ ├── expected.jsx │ │ └── input.svelte │ │ ├── transition-params │ │ ├── expected.jsx │ │ └── input.svelte │ │ └── void-elements │ │ ├── expected.jsx │ │ └── input.svelte ├── sourcemaps │ ├── event-binding.html │ ├── index.js │ ├── let.html │ ├── repl.html │ ├── shorthand-prop.htmlx.html │ └── simple-element.htmlx.html ├── svelte2tsx │ ├── index.js │ ├── samples │ │ ├── array-binding-export │ │ │ ├── expected.tsx │ │ │ └── input.svelte │ │ ├── ast-offset-none │ │ │ ├── expected.tsx │ │ │ └── input.svelte │ │ ├── ast-offset-some │ │ │ ├── expected.tsx │ │ │ └── input.svelte │ │ ├── await-with-$store │ │ │ ├── expected.tsx │ │ │ └── input.svelte │ │ ├── binding-group-store │ │ │ ├── expected.tsx │ │ │ └── input.svelte │ │ ├── circle-drawer-example │ │ │ ├── expected.tsx │ │ │ └── input.svelte │ │ ├── component-default-slot │ │ │ ├── expected.tsx │ │ │ └── input.svelte │ │ ├── component-multiple-slots │ │ │ ├── expected.tsx │ │ │ └── input.svelte │ │ ├── component-slot-crazy-attributes │ │ │ ├── expected.tsx │ │ │ └── input.svelte │ │ ├── export-arrow-function │ │ │ ├── expected.tsx │ │ │ └── input.svelte │ │ ├── export-has-type │ │ │ ├── expected.tsx │ │ │ └── input.svelte │ │ ├── export-interface │ │ │ ├── expected.tsx │ │ │ └── input.svelte │ │ ├── export-list │ │ │ ├── expected.tsx │ │ │ └── input.svelte │ │ ├── export-references-local │ │ │ ├── expected.tsx │ │ │ └── input.svelte │ │ ├── import-single-quote │ │ │ ├── expected.tsx │ │ │ └── input.svelte │ │ ├── imports │ │ │ ├── expected.tsx │ │ │ └── input.svelte │ │ ├── module-script-and-script-in-line │ │ │ ├── expected.tsx │ │ │ └── input.svelte │ │ ├── module-script-and-script-in-line2 │ │ │ ├── expected.tsx │ │ │ └── input.svelte │ │ ├── module-script-and-script │ │ │ ├── expected.tsx │ │ │ └── input.svelte │ │ ├── module-script-and-script2 │ │ │ ├── expected.tsx │ │ │ └── input.svelte │ │ ├── multiple-export │ │ │ ├── expected.tsx │ │ │ └── input.svelte │ │ ├── nested-$-variables-script │ │ │ ├── expected.tsx │ │ │ └── input.svelte │ │ ├── nested-$-variables-template │ │ │ ├── expected.tsx │ │ │ └── input.svelte │ │ ├── object-binding-export │ │ │ ├── expected.tsx │ │ │ └── input.svelte │ │ ├── reactive-declare │ │ │ ├── expected.tsx │ │ │ └── input.svelte │ │ ├── renamed-exports │ │ │ ├── expected.tsx │ │ │ └── input.svelte │ │ ├── script-and-module-script │ │ │ ├── expected.tsx │ │ │ └── input.svelte │ │ ├── script-on-bottom │ │ │ ├── expected.tsx │ │ │ └── input.svelte │ │ ├── script-style-like-component │ │ │ ├── expected.tsx │ │ │ └── input.svelte │ │ ├── self-closing-component │ │ │ ├── expected.tsx │ │ │ └── input.svelte │ │ ├── single-element │ │ │ ├── expected.tsx │ │ │ └── input.svelte │ │ ├── single-export │ │ │ ├── expected.tsx │ │ │ └── input.svelte │ │ ├── stores-mustache │ │ │ ├── expected.tsx │ │ │ └── input.svelte │ │ ├── typed-export-with-default │ │ │ ├── expected.tsx │ │ │ └── input.svelte │ │ ├── uses-$$props-script │ │ │ ├── expected.tsx │ │ │ └── input.svelte │ │ ├── uses-$$props │ │ │ ├── expected.tsx │ │ │ └── input.svelte │ │ ├── uses-$store-in-event-binding │ │ │ ├── expected.tsx │ │ │ └── input.svelte │ │ ├── uses-$store │ │ │ ├── expected.tsx │ │ │ └── input.svelte │ │ └── uses-svelte-components │ │ │ ├── expected.tsx │ │ │ └── input.svelte │ └── tsconfig.json └── test.js └── tsconfig.json /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: Run tests 2 | on: [push, pull_request] 3 | 4 | jobs: 5 | build: 6 | name: Test 7 | runs-on: ubuntu-latest 8 | steps: 9 | - uses: actions/setup-node@v1 10 | with: 11 | node-version: 12.x 12 | - uses: actions/checkout@v2 13 | - name: npm install 14 | run: npm install 15 | - name: run tests 16 | run: npm run test 17 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /index.js 4 | /index.js.map 5 | /index.mjs 6 | test/typecheck/samples/**/input.svelte.tsx 7 | test/build 8 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [{ 7 | "type": "node", 8 | "request": "attach", 9 | "name": "Attach by Process ID", 10 | "processId": "${command:PickProcess}", 11 | "skipFiles": [ 12 | "/**" 13 | ] 14 | }, 15 | { 16 | "type": "node", 17 | "request": "launch", 18 | "name": "Launch Program", 19 | "skipFiles": [ 20 | "/**" 21 | ], 22 | "program": "${workspaceFolder}\\index.js", 23 | "outFiles": [ 24 | "${workspaceFolder}/**/*.js" 25 | ] 26 | } 27 | ] 28 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 David Pershouse 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, 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, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # We have moved 2 | 3 | This code has a new home in the svelte language tools monorepo https://github.com/sveltejs/language-tools/tree/master/packages 4 | 5 | # svelte2tsx 6 | 7 | Converts [Svelte](https://svelte.dev) component source into TSX. The TSX can be type checked using the included `svelte-jsx.d.ts` and `svelte-shims.d.ts`. 8 | 9 | _This project only converts svelte to tsx, type checking is left to consumers of this plugin such as language services_ 10 | 11 | 12 | ```typescript 13 | type SvelteCompiledToTsx = { 14 | code: string, 15 | map: import("magic-string").SourceMap 16 | } 17 | 18 | export default function svelte2tsx(svelte: string): SvelteCompiledToTsx 19 | ``` 20 | 21 | For example 22 | 23 | Input.svelte 24 | ```svelte 25 |

hello {world}

26 | 29 | ``` 30 | 31 | will produce this ugly but type checkable TSX 32 | ```tsx 33 | <>;function render() { 34 | 35 | let world = "name" 36 | ; 37 | <>

hello {world}

38 | 39 | return { props: {world}, slots: {} }} 40 | 41 | export default class { 42 | $$prop_def = __sveltets_partial(render().props) 43 | $$slot_def = render().slots 44 | } 45 | ``` 46 | 47 | with a v3 SourceMap back to the original source. 48 | 49 | For more examples of the transformations, see the `test/**/samples` folders 50 | -------------------------------------------------------------------------------- /index.d.ts: -------------------------------------------------------------------------------- 1 | type SvelteCompiledToTsx = { 2 | code: string, 3 | map: import("magic-string").SourceMap 4 | } 5 | 6 | export default function svelte2tsx(svelte: string, filename?: string): SvelteCompiledToTsx 7 | -------------------------------------------------------------------------------- /mocha.opts: -------------------------------------------------------------------------------- 1 | test/test.js -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "svelte2tsx", 3 | "version": "0.1.3", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "@types/estree": { 8 | "version": "0.0.39", 9 | "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz", 10 | "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==", 11 | "dev": true 12 | }, 13 | "@types/events": { 14 | "version": "3.0.0", 15 | "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz", 16 | "integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==", 17 | "dev": true 18 | }, 19 | "@types/glob": { 20 | "version": "7.1.1", 21 | "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz", 22 | "integrity": "sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w==", 23 | "dev": true, 24 | "requires": { 25 | "@types/events": "*", 26 | "@types/minimatch": "*", 27 | "@types/node": "*" 28 | } 29 | }, 30 | "@types/minimatch": { 31 | "version": "3.0.3", 32 | "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", 33 | "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==", 34 | "dev": true 35 | }, 36 | "@types/mocha": { 37 | "version": "5.2.7", 38 | "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-5.2.7.tgz", 39 | "integrity": "sha512-NYrtPht0wGzhwe9+/idPaBB+TqkY9AhTvOLMkThm0IoEfLaiVQZwBwyJ5puCkO3AUCWrmcoePjp2mbFocKy4SQ==", 40 | "dev": true 41 | }, 42 | "@types/node": { 43 | "version": "8.10.58", 44 | "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.58.tgz", 45 | "integrity": "sha512-NNcUk/rAdR7Pie7WiA5NHp345dTkD62qaxqscQXVIjCjog/ZXsrG8Wo7dZMZAzE7PSpA+qR2S3TYTeFCKuBFxQ==", 46 | "dev": true 47 | }, 48 | "@types/parse5": { 49 | "version": "5.0.2", 50 | "resolved": "https://registry.npmjs.org/@types/parse5/-/parse5-5.0.2.tgz", 51 | "integrity": "sha512-BOl+6KDs4ItndUWUFchy3aEqGdHhw0BC4Uu+qoDonN/f0rbUnJbm71Ulj8Tt9jLFRaAxPLKvdS1bBLfx1qXR9g==", 52 | "dev": true 53 | }, 54 | "@types/resolve": { 55 | "version": "0.0.8", 56 | "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-0.0.8.tgz", 57 | "integrity": "sha512-auApPaJf3NPfe18hSoJkp8EbZzer2ISk7o8mCC3M9he/a04+gbMF97NkpD2S8riMGvm4BMRI59/SZQSaLTKpsQ==", 58 | "dev": true, 59 | "requires": { 60 | "@types/node": "*" 61 | } 62 | }, 63 | "@types/unist": { 64 | "version": "2.0.3", 65 | "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.3.tgz", 66 | "integrity": "sha512-FvUupuM3rlRsRtCN+fDudtmytGO6iHJuuRKS1Ss0pG5z8oX0diNEw94UEL7hgDbpN94rgaK5R7sWm6RrSkZuAQ==", 67 | "dev": true 68 | }, 69 | "@types/vfile": { 70 | "version": "3.0.2", 71 | "resolved": "https://registry.npmjs.org/@types/vfile/-/vfile-3.0.2.tgz", 72 | "integrity": "sha512-b3nLFGaGkJ9rzOcuXRfHkZMdjsawuDD0ENL9fzTophtBg8FJHSGbH7daXkEpcwy3v7Xol3pAvsmlYyFhR4pqJw==", 73 | "dev": true, 74 | "requires": { 75 | "@types/node": "*", 76 | "@types/unist": "*", 77 | "@types/vfile-message": "*" 78 | } 79 | }, 80 | "@types/vfile-message": { 81 | "version": "1.0.1", 82 | "resolved": "https://registry.npmjs.org/@types/vfile-message/-/vfile-message-1.0.1.tgz", 83 | "integrity": "sha512-mlGER3Aqmq7bqR1tTTIVHq8KSAFFRyGbrxuM8C/H82g6k7r2fS+IMEkIu3D7JHzG10NvPdR8DNx0jr0pwpp4dA==", 84 | "dev": true, 85 | "requires": { 86 | "@types/node": "*", 87 | "@types/unist": "*" 88 | } 89 | }, 90 | "acorn": { 91 | "version": "7.1.1", 92 | "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.1.1.tgz", 93 | "integrity": "sha512-add7dgA5ppRPxCFJoAGfMDi7PIBXq1RtGo7BhbLaxwrXPOmw8gq48Y9ozT01hUKy9byMjlR20EJhu5zlkErEkg==", 94 | "dev": true 95 | }, 96 | "ansi-colors": { 97 | "version": "3.2.3", 98 | "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz", 99 | "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==", 100 | "dev": true 101 | }, 102 | "ansi-regex": { 103 | "version": "3.0.0", 104 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", 105 | "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", 106 | "dev": true 107 | }, 108 | "ansi-styles": { 109 | "version": "3.2.1", 110 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", 111 | "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", 112 | "dev": true, 113 | "requires": { 114 | "color-convert": "^1.9.0" 115 | } 116 | }, 117 | "argparse": { 118 | "version": "1.0.10", 119 | "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", 120 | "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", 121 | "dev": true, 122 | "requires": { 123 | "sprintf-js": "~1.0.2" 124 | } 125 | }, 126 | "array-union": { 127 | "version": "1.0.2", 128 | "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", 129 | "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", 130 | "dev": true, 131 | "requires": { 132 | "array-uniq": "^1.0.1" 133 | } 134 | }, 135 | "array-uniq": { 136 | "version": "1.0.3", 137 | "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", 138 | "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", 139 | "dev": true 140 | }, 141 | "balanced-match": { 142 | "version": "1.0.0", 143 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", 144 | "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", 145 | "dev": true 146 | }, 147 | "brace-expansion": { 148 | "version": "1.1.11", 149 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", 150 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", 151 | "dev": true, 152 | "requires": { 153 | "balanced-match": "^1.0.0", 154 | "concat-map": "0.0.1" 155 | } 156 | }, 157 | "browser-stdout": { 158 | "version": "1.3.1", 159 | "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", 160 | "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", 161 | "dev": true 162 | }, 163 | "buffer-from": { 164 | "version": "1.1.1", 165 | "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", 166 | "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", 167 | "dev": true 168 | }, 169 | "builtin-modules": { 170 | "version": "3.1.0", 171 | "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.1.0.tgz", 172 | "integrity": "sha512-k0KL0aWZuBt2lrxrcASWDfwOLMnodeQjodT/1SxEQAXsHANgo6ZC/VEaSEHCXt7aSTZ4/4H5LKa+tBXmW7Vtvw==", 173 | "dev": true 174 | }, 175 | "camelcase": { 176 | "version": "5.3.1", 177 | "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", 178 | "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", 179 | "dev": true 180 | }, 181 | "cliui": { 182 | "version": "5.0.0", 183 | "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", 184 | "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", 185 | "dev": true, 186 | "requires": { 187 | "string-width": "^3.1.0", 188 | "strip-ansi": "^5.2.0", 189 | "wrap-ansi": "^5.1.0" 190 | }, 191 | "dependencies": { 192 | "ansi-regex": { 193 | "version": "4.1.0", 194 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", 195 | "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", 196 | "dev": true 197 | }, 198 | "string-width": { 199 | "version": "3.1.0", 200 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", 201 | "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", 202 | "dev": true, 203 | "requires": { 204 | "emoji-regex": "^7.0.1", 205 | "is-fullwidth-code-point": "^2.0.0", 206 | "strip-ansi": "^5.1.0" 207 | } 208 | }, 209 | "strip-ansi": { 210 | "version": "5.2.0", 211 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", 212 | "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", 213 | "dev": true, 214 | "requires": { 215 | "ansi-regex": "^4.1.0" 216 | } 217 | } 218 | } 219 | }, 220 | "color-convert": { 221 | "version": "1.9.3", 222 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", 223 | "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", 224 | "dev": true, 225 | "requires": { 226 | "color-name": "1.1.3" 227 | } 228 | }, 229 | "color-name": { 230 | "version": "1.1.3", 231 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", 232 | "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", 233 | "dev": true 234 | }, 235 | "concat-map": { 236 | "version": "0.0.1", 237 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 238 | "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", 239 | "dev": true 240 | }, 241 | "debug": { 242 | "version": "3.2.6", 243 | "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", 244 | "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", 245 | "dev": true, 246 | "requires": { 247 | "ms": "^2.1.1" 248 | } 249 | }, 250 | "decamelize": { 251 | "version": "1.2.0", 252 | "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", 253 | "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", 254 | "dev": true 255 | }, 256 | "define-properties": { 257 | "version": "1.1.3", 258 | "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", 259 | "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", 260 | "dev": true, 261 | "requires": { 262 | "object-keys": "^1.0.12" 263 | } 264 | }, 265 | "del": { 266 | "version": "4.1.1", 267 | "resolved": "https://registry.npmjs.org/del/-/del-4.1.1.tgz", 268 | "integrity": "sha512-QwGuEUouP2kVwQenAsOof5Fv8K9t3D8Ca8NxcXKrIpEHjTXK5J2nXLdP+ALI1cgv8wj7KuwBhTwBkOZSJKM5XQ==", 269 | "dev": true, 270 | "requires": { 271 | "@types/glob": "^7.1.1", 272 | "globby": "^6.1.0", 273 | "is-path-cwd": "^2.0.0", 274 | "is-path-in-cwd": "^2.0.0", 275 | "p-map": "^2.0.0", 276 | "pify": "^4.0.1", 277 | "rimraf": "^2.6.3" 278 | } 279 | }, 280 | "diff": { 281 | "version": "3.5.0", 282 | "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", 283 | "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", 284 | "dev": true 285 | }, 286 | "emoji-regex": { 287 | "version": "7.0.3", 288 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", 289 | "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", 290 | "dev": true 291 | }, 292 | "es-abstract": { 293 | "version": "1.16.0", 294 | "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.16.0.tgz", 295 | "integrity": "sha512-xdQnfykZ9JMEiasTAJZJdMWCQ1Vm00NBw79/AWi7ELfZuuPCSOMDZbT9mkOfSctVtfhb+sAAzrm+j//GjjLHLg==", 296 | "dev": true, 297 | "requires": { 298 | "es-to-primitive": "^1.2.0", 299 | "function-bind": "^1.1.1", 300 | "has": "^1.0.3", 301 | "has-symbols": "^1.0.0", 302 | "is-callable": "^1.1.4", 303 | "is-regex": "^1.0.4", 304 | "object-inspect": "^1.6.0", 305 | "object-keys": "^1.1.1", 306 | "string.prototype.trimleft": "^2.1.0", 307 | "string.prototype.trimright": "^2.1.0" 308 | } 309 | }, 310 | "es-to-primitive": { 311 | "version": "1.2.0", 312 | "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.0.tgz", 313 | "integrity": "sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg==", 314 | "dev": true, 315 | "requires": { 316 | "is-callable": "^1.1.4", 317 | "is-date-object": "^1.0.1", 318 | "is-symbol": "^1.0.2" 319 | } 320 | }, 321 | "escape-string-regexp": { 322 | "version": "1.0.5", 323 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", 324 | "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", 325 | "dev": true 326 | }, 327 | "esprima": { 328 | "version": "4.0.1", 329 | "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", 330 | "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", 331 | "dev": true 332 | }, 333 | "find-up": { 334 | "version": "3.0.0", 335 | "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", 336 | "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", 337 | "dev": true, 338 | "requires": { 339 | "locate-path": "^3.0.0" 340 | } 341 | }, 342 | "flat": { 343 | "version": "4.1.0", 344 | "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.0.tgz", 345 | "integrity": "sha512-Px/TiLIznH7gEDlPXcUD4KnBusa6kR6ayRUVcnEAbreRIuhkqow/mun59BuRXwoYk7ZQOLW1ZM05ilIvK38hFw==", 346 | "dev": true, 347 | "requires": { 348 | "is-buffer": "~2.0.3" 349 | } 350 | }, 351 | "fs.realpath": { 352 | "version": "1.0.0", 353 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", 354 | "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", 355 | "dev": true 356 | }, 357 | "function-bind": { 358 | "version": "1.1.1", 359 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", 360 | "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", 361 | "dev": true 362 | }, 363 | "get-caller-file": { 364 | "version": "2.0.5", 365 | "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", 366 | "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", 367 | "dev": true 368 | }, 369 | "glob": { 370 | "version": "7.1.3", 371 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", 372 | "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", 373 | "dev": true, 374 | "requires": { 375 | "fs.realpath": "^1.0.0", 376 | "inflight": "^1.0.4", 377 | "inherits": "2", 378 | "minimatch": "^3.0.4", 379 | "once": "^1.3.0", 380 | "path-is-absolute": "^1.0.0" 381 | } 382 | }, 383 | "globalyzer": { 384 | "version": "0.1.4", 385 | "resolved": "https://registry.npmjs.org/globalyzer/-/globalyzer-0.1.4.tgz", 386 | "integrity": "sha512-LeguVWaxgHN0MNbWC6YljNMzHkrCny9fzjmEUdnF1kQ7wATFD1RHFRqA1qxaX2tgxGENlcxjOflopBwj3YZiXA==", 387 | "dev": true 388 | }, 389 | "globby": { 390 | "version": "6.1.0", 391 | "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", 392 | "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=", 393 | "dev": true, 394 | "requires": { 395 | "array-union": "^1.0.1", 396 | "glob": "^7.0.3", 397 | "object-assign": "^4.0.1", 398 | "pify": "^2.0.0", 399 | "pinkie-promise": "^2.0.0" 400 | }, 401 | "dependencies": { 402 | "pify": { 403 | "version": "2.3.0", 404 | "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", 405 | "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", 406 | "dev": true 407 | } 408 | } 409 | }, 410 | "globrex": { 411 | "version": "0.1.2", 412 | "resolved": "https://registry.npmjs.org/globrex/-/globrex-0.1.2.tgz", 413 | "integrity": "sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==", 414 | "dev": true 415 | }, 416 | "growl": { 417 | "version": "1.10.5", 418 | "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", 419 | "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", 420 | "dev": true 421 | }, 422 | "has": { 423 | "version": "1.0.3", 424 | "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", 425 | "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", 426 | "dev": true, 427 | "requires": { 428 | "function-bind": "^1.1.1" 429 | } 430 | }, 431 | "has-flag": { 432 | "version": "3.0.0", 433 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", 434 | "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", 435 | "dev": true 436 | }, 437 | "has-symbols": { 438 | "version": "1.0.0", 439 | "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz", 440 | "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=", 441 | "dev": true 442 | }, 443 | "he": { 444 | "version": "1.2.0", 445 | "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", 446 | "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", 447 | "dev": true 448 | }, 449 | "inflight": { 450 | "version": "1.0.6", 451 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", 452 | "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", 453 | "dev": true, 454 | "requires": { 455 | "once": "^1.3.0", 456 | "wrappy": "1" 457 | } 458 | }, 459 | "inherits": { 460 | "version": "2.0.4", 461 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 462 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", 463 | "dev": true 464 | }, 465 | "is-buffer": { 466 | "version": "2.0.4", 467 | "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz", 468 | "integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==", 469 | "dev": true 470 | }, 471 | "is-callable": { 472 | "version": "1.1.4", 473 | "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz", 474 | "integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==", 475 | "dev": true 476 | }, 477 | "is-date-object": { 478 | "version": "1.0.1", 479 | "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz", 480 | "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=", 481 | "dev": true 482 | }, 483 | "is-fullwidth-code-point": { 484 | "version": "2.0.0", 485 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", 486 | "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", 487 | "dev": true 488 | }, 489 | "is-module": { 490 | "version": "1.0.0", 491 | "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", 492 | "integrity": "sha1-Mlj7afeMFNW4FdZkM2tM/7ZEFZE=", 493 | "dev": true 494 | }, 495 | "is-path-cwd": { 496 | "version": "2.2.0", 497 | "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", 498 | "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==", 499 | "dev": true 500 | }, 501 | "is-path-in-cwd": { 502 | "version": "2.1.0", 503 | "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-2.1.0.tgz", 504 | "integrity": "sha512-rNocXHgipO+rvnP6dk3zI20RpOtrAM/kzbB258Uw5BWr3TpXi861yzjo16Dn4hUox07iw5AyeMLHWsujkjzvRQ==", 505 | "dev": true, 506 | "requires": { 507 | "is-path-inside": "^2.1.0" 508 | } 509 | }, 510 | "is-path-inside": { 511 | "version": "2.1.0", 512 | "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-2.1.0.tgz", 513 | "integrity": "sha512-wiyhTzfDWsvwAW53OBWF5zuvaOGlZ6PwYxAbPVDhpm+gM09xKQGjBq/8uYN12aDvMxnAnq3dxTyoSoRNmg5YFg==", 514 | "dev": true, 515 | "requires": { 516 | "path-is-inside": "^1.0.2" 517 | } 518 | }, 519 | "is-reference": { 520 | "version": "1.1.4", 521 | "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.1.4.tgz", 522 | "integrity": "sha512-uJA/CDPO3Tao3GTrxYn6AwkM4nUPJiGGYu5+cB8qbC7WGFlrKZbiRo7SFKxUAEpFUfiHofWCXBUNhvYJMh+6zw==", 523 | "dev": true, 524 | "requires": { 525 | "@types/estree": "0.0.39" 526 | } 527 | }, 528 | "is-regex": { 529 | "version": "1.0.4", 530 | "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", 531 | "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=", 532 | "dev": true, 533 | "requires": { 534 | "has": "^1.0.1" 535 | } 536 | }, 537 | "is-symbol": { 538 | "version": "1.0.2", 539 | "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.2.tgz", 540 | "integrity": "sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw==", 541 | "dev": true, 542 | "requires": { 543 | "has-symbols": "^1.0.0" 544 | } 545 | }, 546 | "isexe": { 547 | "version": "2.0.0", 548 | "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", 549 | "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", 550 | "dev": true 551 | }, 552 | "js-yaml": { 553 | "version": "3.13.1", 554 | "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", 555 | "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", 556 | "dev": true, 557 | "requires": { 558 | "argparse": "^1.0.7", 559 | "esprima": "^4.0.0" 560 | } 561 | }, 562 | "locate-path": { 563 | "version": "3.0.0", 564 | "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", 565 | "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", 566 | "dev": true, 567 | "requires": { 568 | "p-locate": "^3.0.0", 569 | "path-exists": "^3.0.0" 570 | } 571 | }, 572 | "lodash": { 573 | "version": "4.17.15", 574 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", 575 | "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", 576 | "dev": true 577 | }, 578 | "log-symbols": { 579 | "version": "2.2.0", 580 | "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", 581 | "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==", 582 | "dev": true, 583 | "requires": { 584 | "chalk": "^2.0.1" 585 | }, 586 | "dependencies": { 587 | "chalk": { 588 | "version": "2.4.2", 589 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", 590 | "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", 591 | "dev": true, 592 | "requires": { 593 | "ansi-styles": "^3.2.1", 594 | "escape-string-regexp": "^1.0.5", 595 | "supports-color": "^5.3.0" 596 | } 597 | }, 598 | "supports-color": { 599 | "version": "5.5.0", 600 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", 601 | "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", 602 | "dev": true, 603 | "requires": { 604 | "has-flag": "^3.0.0" 605 | } 606 | } 607 | } 608 | }, 609 | "magic-string": { 610 | "version": "0.25.4", 611 | "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.4.tgz", 612 | "integrity": "sha512-oycWO9nEVAP2RVPbIoDoA4Y7LFIJ3xRYov93gAyJhZkET1tNuB0u7uWkZS2LpBWTJUWnmau/To8ECWRC+jKNfw==", 613 | "dev": true, 614 | "requires": { 615 | "sourcemap-codec": "^1.4.4" 616 | } 617 | }, 618 | "minimatch": { 619 | "version": "3.0.4", 620 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", 621 | "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", 622 | "dev": true, 623 | "requires": { 624 | "brace-expansion": "^1.1.7" 625 | } 626 | }, 627 | "minimist": { 628 | "version": "0.0.8", 629 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", 630 | "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", 631 | "dev": true 632 | }, 633 | "mkdirp": { 634 | "version": "0.5.1", 635 | "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", 636 | "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", 637 | "dev": true, 638 | "requires": { 639 | "minimist": "0.0.8" 640 | } 641 | }, 642 | "mocha": { 643 | "version": "6.2.2", 644 | "resolved": "https://registry.npmjs.org/mocha/-/mocha-6.2.2.tgz", 645 | "integrity": "sha512-FgDS9Re79yU1xz5d+C4rv1G7QagNGHZ+iXF81hO8zY35YZZcLEsJVfFolfsqKFWunATEvNzMK0r/CwWd/szO9A==", 646 | "dev": true, 647 | "requires": { 648 | "ansi-colors": "3.2.3", 649 | "browser-stdout": "1.3.1", 650 | "debug": "3.2.6", 651 | "diff": "3.5.0", 652 | "escape-string-regexp": "1.0.5", 653 | "find-up": "3.0.0", 654 | "glob": "7.1.3", 655 | "growl": "1.10.5", 656 | "he": "1.2.0", 657 | "js-yaml": "3.13.1", 658 | "log-symbols": "2.2.0", 659 | "minimatch": "3.0.4", 660 | "mkdirp": "0.5.1", 661 | "ms": "2.1.1", 662 | "node-environment-flags": "1.0.5", 663 | "object.assign": "4.1.0", 664 | "strip-json-comments": "2.0.1", 665 | "supports-color": "6.0.0", 666 | "which": "1.3.1", 667 | "wide-align": "1.1.3", 668 | "yargs": "13.3.0", 669 | "yargs-parser": "13.1.1", 670 | "yargs-unparser": "1.6.0" 671 | } 672 | }, 673 | "ms": { 674 | "version": "2.1.1", 675 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", 676 | "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", 677 | "dev": true 678 | }, 679 | "node-environment-flags": { 680 | "version": "1.0.5", 681 | "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.5.tgz", 682 | "integrity": "sha512-VNYPRfGfmZLx0Ye20jWzHUjyTW/c+6Wq+iLhDzUI4XmhrDd9l/FozXV3F2xOaXjvp0co0+v1YSR3CMP6g+VvLQ==", 683 | "dev": true, 684 | "requires": { 685 | "object.getownpropertydescriptors": "^2.0.3", 686 | "semver": "^5.7.0" 687 | } 688 | }, 689 | "object-assign": { 690 | "version": "4.1.1", 691 | "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", 692 | "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", 693 | "dev": true 694 | }, 695 | "object-inspect": { 696 | "version": "1.6.0", 697 | "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.6.0.tgz", 698 | "integrity": "sha512-GJzfBZ6DgDAmnuaM3104jR4s1Myxr3Y3zfIyN4z3UdqN69oSRacNK8UhnobDdC+7J2AHCjGwxQubNJfE70SXXQ==", 699 | "dev": true 700 | }, 701 | "object-keys": { 702 | "version": "1.1.1", 703 | "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", 704 | "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", 705 | "dev": true 706 | }, 707 | "object.assign": { 708 | "version": "4.1.0", 709 | "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", 710 | "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", 711 | "dev": true, 712 | "requires": { 713 | "define-properties": "^1.1.2", 714 | "function-bind": "^1.1.1", 715 | "has-symbols": "^1.0.0", 716 | "object-keys": "^1.0.11" 717 | } 718 | }, 719 | "object.getownpropertydescriptors": { 720 | "version": "2.0.3", 721 | "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz", 722 | "integrity": "sha1-h1jIRvW0B62rDyNuCYbxSwUcqhY=", 723 | "dev": true, 724 | "requires": { 725 | "define-properties": "^1.1.2", 726 | "es-abstract": "^1.5.1" 727 | } 728 | }, 729 | "once": { 730 | "version": "1.4.0", 731 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 732 | "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", 733 | "dev": true, 734 | "requires": { 735 | "wrappy": "1" 736 | } 737 | }, 738 | "p-limit": { 739 | "version": "2.2.1", 740 | "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.1.tgz", 741 | "integrity": "sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg==", 742 | "dev": true, 743 | "requires": { 744 | "p-try": "^2.0.0" 745 | } 746 | }, 747 | "p-locate": { 748 | "version": "3.0.0", 749 | "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", 750 | "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", 751 | "dev": true, 752 | "requires": { 753 | "p-limit": "^2.0.0" 754 | } 755 | }, 756 | "p-map": { 757 | "version": "2.1.0", 758 | "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", 759 | "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", 760 | "dev": true 761 | }, 762 | "p-try": { 763 | "version": "2.2.0", 764 | "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", 765 | "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", 766 | "dev": true 767 | }, 768 | "parse5": { 769 | "version": "5.1.0", 770 | "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.0.tgz", 771 | "integrity": "sha512-fxNG2sQjHvlVAYmzBZS9YlDp6PTSSDwa98vkD4QgVDDCAo84z5X1t5XyJQ62ImdLXx5NdIIfihey6xpum9/gRQ==", 772 | "dev": true 773 | }, 774 | "path-exists": { 775 | "version": "3.0.0", 776 | "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", 777 | "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", 778 | "dev": true 779 | }, 780 | "path-is-absolute": { 781 | "version": "1.0.1", 782 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", 783 | "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", 784 | "dev": true 785 | }, 786 | "path-is-inside": { 787 | "version": "1.0.2", 788 | "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", 789 | "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", 790 | "dev": true 791 | }, 792 | "path-parse": { 793 | "version": "1.0.6", 794 | "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", 795 | "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", 796 | "dev": true 797 | }, 798 | "pify": { 799 | "version": "4.0.1", 800 | "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", 801 | "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", 802 | "dev": true 803 | }, 804 | "pinkie": { 805 | "version": "2.0.4", 806 | "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", 807 | "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", 808 | "dev": true 809 | }, 810 | "pinkie-promise": { 811 | "version": "2.0.1", 812 | "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", 813 | "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", 814 | "dev": true, 815 | "requires": { 816 | "pinkie": "^2.0.0" 817 | } 818 | }, 819 | "require-directory": { 820 | "version": "2.1.1", 821 | "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", 822 | "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", 823 | "dev": true 824 | }, 825 | "require-main-filename": { 826 | "version": "2.0.0", 827 | "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", 828 | "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", 829 | "dev": true 830 | }, 831 | "resolve": { 832 | "version": "1.12.0", 833 | "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.12.0.tgz", 834 | "integrity": "sha512-B/dOmuoAik5bKcD6s6nXDCjzUKnaDvdkRyAk6rsmsKLipWj4797iothd7jmmUhWTfinVMU+wc56rYKsit2Qy4w==", 835 | "dev": true, 836 | "requires": { 837 | "path-parse": "^1.0.6" 838 | } 839 | }, 840 | "rimraf": { 841 | "version": "2.7.1", 842 | "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", 843 | "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", 844 | "dev": true, 845 | "requires": { 846 | "glob": "^7.1.3" 847 | } 848 | }, 849 | "rollup": { 850 | "version": "1.26.0", 851 | "resolved": "https://registry.npmjs.org/rollup/-/rollup-1.26.0.tgz", 852 | "integrity": "sha512-5HljNYn9icFvXX+Oe97qY5TWvnWhKqgGT0HGeWWqFPx7w7+Anzg7dfHMtUif7YYy6QxAgynDSwK6uxbgcrVUxw==", 853 | "dev": true, 854 | "requires": { 855 | "@types/estree": "*", 856 | "@types/node": "*", 857 | "acorn": "^7.1.0" 858 | } 859 | }, 860 | "rollup-plugin-commonjs": { 861 | "version": "10.1.0", 862 | "resolved": "https://registry.npmjs.org/rollup-plugin-commonjs/-/rollup-plugin-commonjs-10.1.0.tgz", 863 | "integrity": "sha512-jlXbjZSQg8EIeAAvepNwhJj++qJWNJw1Cl0YnOqKtP5Djx+fFGkp3WRh+W0ASCaFG5w1jhmzDxgu3SJuVxPF4Q==", 864 | "dev": true, 865 | "requires": { 866 | "estree-walker": "^0.6.1", 867 | "is-reference": "^1.1.2", 868 | "magic-string": "^0.25.2", 869 | "resolve": "^1.11.0", 870 | "rollup-pluginutils": "^2.8.1" 871 | }, 872 | "dependencies": { 873 | "estree-walker": { 874 | "version": "0.6.1", 875 | "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-0.6.1.tgz", 876 | "integrity": "sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==", 877 | "dev": true 878 | } 879 | } 880 | }, 881 | "rollup-plugin-delete": { 882 | "version": "1.1.0", 883 | "resolved": "https://registry.npmjs.org/rollup-plugin-delete/-/rollup-plugin-delete-1.1.0.tgz", 884 | "integrity": "sha512-OnqtYhA+LQGOsn42mE6RSipiiEB/C4gLPmQoL9RxkxbLX0i2jLGpQTiZacLNmc2DtmCP/qAy6K23Hf6/8wYuYQ==", 885 | "dev": true, 886 | "requires": { 887 | "del": "^4.1.1" 888 | } 889 | }, 890 | "rollup-plugin-json": { 891 | "version": "4.0.0", 892 | "resolved": "https://registry.npmjs.org/rollup-plugin-json/-/rollup-plugin-json-4.0.0.tgz", 893 | "integrity": "sha512-hgb8N7Cgfw5SZAkb3jf0QXii6QX/FOkiIq2M7BAQIEydjHvTyxXHQiIzZaTFgx1GK0cRCHOCBHIyEkkLdWKxow==", 894 | "dev": true, 895 | "requires": { 896 | "rollup-pluginutils": "^2.5.0" 897 | } 898 | }, 899 | "rollup-plugin-node-resolve": { 900 | "version": "5.2.0", 901 | "resolved": "https://registry.npmjs.org/rollup-plugin-node-resolve/-/rollup-plugin-node-resolve-5.2.0.tgz", 902 | "integrity": "sha512-jUlyaDXts7TW2CqQ4GaO5VJ4PwwaV8VUGA7+km3n6k6xtOEacf61u0VXwN80phY/evMcaS+9eIeJ9MOyDxt5Zw==", 903 | "dev": true, 904 | "requires": { 905 | "@types/resolve": "0.0.8", 906 | "builtin-modules": "^3.1.0", 907 | "is-module": "^1.0.0", 908 | "resolve": "^1.11.1", 909 | "rollup-pluginutils": "^2.8.1" 910 | } 911 | }, 912 | "rollup-plugin-typescript": { 913 | "version": "1.0.1", 914 | "resolved": "https://registry.npmjs.org/rollup-plugin-typescript/-/rollup-plugin-typescript-1.0.1.tgz", 915 | "integrity": "sha512-rwJDNn9jv/NsKZuyBb/h0jsclP4CJ58qbvZt2Q9zDIGILF2LtdtvCqMOL+Gq9IVq5MTrTlHZNrn8h7VjQgd8tw==", 916 | "dev": true, 917 | "requires": { 918 | "resolve": "^1.10.0", 919 | "rollup-pluginutils": "^2.5.0" 920 | } 921 | }, 922 | "rollup-pluginutils": { 923 | "version": "2.8.2", 924 | "resolved": "https://registry.npmjs.org/rollup-pluginutils/-/rollup-pluginutils-2.8.2.tgz", 925 | "integrity": "sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ==", 926 | "dev": true, 927 | "requires": { 928 | "estree-walker": "^0.6.1" 929 | }, 930 | "dependencies": { 931 | "estree-walker": { 932 | "version": "0.6.1", 933 | "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-0.6.1.tgz", 934 | "integrity": "sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==", 935 | "dev": true 936 | } 937 | } 938 | }, 939 | "semver": { 940 | "version": "5.7.1", 941 | "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", 942 | "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", 943 | "dev": true 944 | }, 945 | "set-blocking": { 946 | "version": "2.0.0", 947 | "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", 948 | "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", 949 | "dev": true 950 | }, 951 | "source-map": { 952 | "version": "0.6.1", 953 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", 954 | "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", 955 | "dev": true 956 | }, 957 | "source-map-support": { 958 | "version": "0.5.16", 959 | "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.16.tgz", 960 | "integrity": "sha512-efyLRJDr68D9hBBNIPWFjhpFzURh+KJykQwvMyW5UiZzYwoF6l4YMMDIJJEyFWxWCqfyxLzz6tSfUFR+kXXsVQ==", 961 | "dev": true, 962 | "requires": { 963 | "buffer-from": "^1.0.0", 964 | "source-map": "^0.6.0" 965 | }, 966 | "dependencies": { 967 | "source-map": { 968 | "version": "0.6.1", 969 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", 970 | "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", 971 | "dev": true 972 | } 973 | } 974 | }, 975 | "sourcemap-codec": { 976 | "version": "1.4.6", 977 | "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.6.tgz", 978 | "integrity": "sha512-1ZooVLYFxC448piVLBbtOxFcXwnymH9oUF8nRd3CuYDVvkRBxRl6pB4Mtas5a4drtL+E8LDgFkQNcgIw6tc8Hg==", 979 | "dev": true 980 | }, 981 | "sprintf-js": { 982 | "version": "1.0.3", 983 | "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", 984 | "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", 985 | "dev": true 986 | }, 987 | "string-width": { 988 | "version": "2.1.1", 989 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", 990 | "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", 991 | "dev": true, 992 | "requires": { 993 | "is-fullwidth-code-point": "^2.0.0", 994 | "strip-ansi": "^4.0.0" 995 | } 996 | }, 997 | "string.prototype.trimleft": { 998 | "version": "2.1.0", 999 | "resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.0.tgz", 1000 | "integrity": "sha512-FJ6b7EgdKxxbDxc79cOlok6Afd++TTs5szo+zJTUyow3ycrRfJVE2pq3vcN53XexvKZu/DJMDfeI/qMiZTrjTw==", 1001 | "dev": true, 1002 | "requires": { 1003 | "define-properties": "^1.1.3", 1004 | "function-bind": "^1.1.1" 1005 | } 1006 | }, 1007 | "string.prototype.trimright": { 1008 | "version": "2.1.0", 1009 | "resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.0.tgz", 1010 | "integrity": "sha512-fXZTSV55dNBwv16uw+hh5jkghxSnc5oHq+5K/gXgizHwAvMetdAJlHqqoFC1FSDVPYWLkAKl2cxpUT41sV7nSg==", 1011 | "dev": true, 1012 | "requires": { 1013 | "define-properties": "^1.1.3", 1014 | "function-bind": "^1.1.1" 1015 | } 1016 | }, 1017 | "strip-ansi": { 1018 | "version": "4.0.0", 1019 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", 1020 | "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", 1021 | "dev": true, 1022 | "requires": { 1023 | "ansi-regex": "^3.0.0" 1024 | } 1025 | }, 1026 | "strip-json-comments": { 1027 | "version": "2.0.1", 1028 | "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", 1029 | "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", 1030 | "dev": true 1031 | }, 1032 | "supports-color": { 1033 | "version": "6.0.0", 1034 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz", 1035 | "integrity": "sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==", 1036 | "dev": true, 1037 | "requires": { 1038 | "has-flag": "^3.0.0" 1039 | } 1040 | }, 1041 | "svelte": { 1042 | "version": "3.16.0", 1043 | "resolved": "https://registry.npmjs.org/svelte/-/svelte-3.16.0.tgz", 1044 | "integrity": "sha512-k7nCQTd9/rGOi25iv/sBeJe2W89hK2lcaUsmUQqikH0Tye7Gh/tvvF9LuNTSF+dQY/isNX+g8K9fJf+5jMLfxw==", 1045 | "dev": true 1046 | }, 1047 | "tiny-glob": { 1048 | "version": "0.2.6", 1049 | "resolved": "https://registry.npmjs.org/tiny-glob/-/tiny-glob-0.2.6.tgz", 1050 | "integrity": "sha512-A7ewMqPu1B5PWwC3m7KVgAu96Ch5LA0w4SnEN/LbDREj/gAD0nPWboRbn8YoP9ISZXqeNAlMvKSKoEuhcfK3Pw==", 1051 | "dev": true, 1052 | "requires": { 1053 | "globalyzer": "^0.1.0", 1054 | "globrex": "^0.1.1" 1055 | } 1056 | }, 1057 | "tslib": { 1058 | "version": "1.10.0", 1059 | "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", 1060 | "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==", 1061 | "dev": true 1062 | }, 1063 | "typescript": { 1064 | "version": "3.6.4", 1065 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.6.4.tgz", 1066 | "integrity": "sha512-unoCll1+l+YK4i4F8f22TaNVPRHcD9PA3yCuZ8g5e0qGqlVlJ/8FSateOLLSagn+Yg5+ZwuPkL8LFUc0Jcvksg==", 1067 | "dev": true 1068 | }, 1069 | "which": { 1070 | "version": "1.3.1", 1071 | "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", 1072 | "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", 1073 | "dev": true, 1074 | "requires": { 1075 | "isexe": "^2.0.0" 1076 | } 1077 | }, 1078 | "which-module": { 1079 | "version": "2.0.0", 1080 | "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", 1081 | "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", 1082 | "dev": true 1083 | }, 1084 | "wide-align": { 1085 | "version": "1.1.3", 1086 | "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", 1087 | "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", 1088 | "dev": true, 1089 | "requires": { 1090 | "string-width": "^1.0.2 || 2" 1091 | } 1092 | }, 1093 | "wrap-ansi": { 1094 | "version": "5.1.0", 1095 | "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", 1096 | "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", 1097 | "dev": true, 1098 | "requires": { 1099 | "ansi-styles": "^3.2.0", 1100 | "string-width": "^3.0.0", 1101 | "strip-ansi": "^5.0.0" 1102 | }, 1103 | "dependencies": { 1104 | "ansi-regex": { 1105 | "version": "4.1.0", 1106 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", 1107 | "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", 1108 | "dev": true 1109 | }, 1110 | "string-width": { 1111 | "version": "3.1.0", 1112 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", 1113 | "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", 1114 | "dev": true, 1115 | "requires": { 1116 | "emoji-regex": "^7.0.1", 1117 | "is-fullwidth-code-point": "^2.0.0", 1118 | "strip-ansi": "^5.1.0" 1119 | } 1120 | }, 1121 | "strip-ansi": { 1122 | "version": "5.2.0", 1123 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", 1124 | "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", 1125 | "dev": true, 1126 | "requires": { 1127 | "ansi-regex": "^4.1.0" 1128 | } 1129 | } 1130 | } 1131 | }, 1132 | "wrappy": { 1133 | "version": "1.0.2", 1134 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 1135 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", 1136 | "dev": true 1137 | }, 1138 | "y18n": { 1139 | "version": "4.0.0", 1140 | "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", 1141 | "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", 1142 | "dev": true 1143 | }, 1144 | "yargs": { 1145 | "version": "13.3.0", 1146 | "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.0.tgz", 1147 | "integrity": "sha512-2eehun/8ALW8TLoIl7MVaRUrg+yCnenu8B4kBlRxj3GJGDKU1Og7sMXPNm1BYyM1DOJmTZ4YeN/Nwxv+8XJsUA==", 1148 | "dev": true, 1149 | "requires": { 1150 | "cliui": "^5.0.0", 1151 | "find-up": "^3.0.0", 1152 | "get-caller-file": "^2.0.1", 1153 | "require-directory": "^2.1.1", 1154 | "require-main-filename": "^2.0.0", 1155 | "set-blocking": "^2.0.0", 1156 | "string-width": "^3.0.0", 1157 | "which-module": "^2.0.0", 1158 | "y18n": "^4.0.0", 1159 | "yargs-parser": "^13.1.1" 1160 | }, 1161 | "dependencies": { 1162 | "ansi-regex": { 1163 | "version": "4.1.0", 1164 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", 1165 | "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", 1166 | "dev": true 1167 | }, 1168 | "string-width": { 1169 | "version": "3.1.0", 1170 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", 1171 | "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", 1172 | "dev": true, 1173 | "requires": { 1174 | "emoji-regex": "^7.0.1", 1175 | "is-fullwidth-code-point": "^2.0.0", 1176 | "strip-ansi": "^5.1.0" 1177 | } 1178 | }, 1179 | "strip-ansi": { 1180 | "version": "5.2.0", 1181 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", 1182 | "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", 1183 | "dev": true, 1184 | "requires": { 1185 | "ansi-regex": "^4.1.0" 1186 | } 1187 | } 1188 | } 1189 | }, 1190 | "yargs-parser": { 1191 | "version": "13.1.1", 1192 | "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.1.tgz", 1193 | "integrity": "sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ==", 1194 | "dev": true, 1195 | "requires": { 1196 | "camelcase": "^5.0.0", 1197 | "decamelize": "^1.2.0" 1198 | } 1199 | }, 1200 | "yargs-unparser": { 1201 | "version": "1.6.0", 1202 | "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz", 1203 | "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==", 1204 | "dev": true, 1205 | "requires": { 1206 | "flat": "^4.1.0", 1207 | "lodash": "^4.17.15", 1208 | "yargs": "^13.3.0" 1209 | } 1210 | } 1211 | } 1212 | } 1213 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "svelte2tsx", 3 | "version": "0.1.4", 4 | "description": "Convert Svelte components to TSX for type checking", 5 | "author": "David Pershouse", 6 | "license": "MIT", 7 | "keywords": [ 8 | "svelte", 9 | "typescript" 10 | ], 11 | "homepage": "https://github.com/halfnelson/svelte2tsx", 12 | "repository": { 13 | "type": "git", 14 | "url": "https://github.com/halfnelson/svelte2tsx.git" 15 | }, 16 | "type": "commonjs", 17 | "main": "index.js", 18 | "types": "index.d.ts", 19 | "devDependencies": { 20 | "@types/mocha": "^5.2.7", 21 | "@types/node": "^8.10.53", 22 | "@types/parse5": "^5.0.2", 23 | "@types/unist": "^2.0.3", 24 | "@types/vfile": "^3.0.2", 25 | "magic-string": "^0.25.4", 26 | "mocha": "^6.2.2", 27 | "parse5": "^5.1.0", 28 | "rollup": "^1.12.0", 29 | "rollup-plugin-commonjs": "^10.0.0", 30 | "rollup-plugin-delete": "^1.1.0", 31 | "rollup-plugin-json": "^4.0.0", 32 | "rollup-plugin-node-resolve": "^5.2.0", 33 | "rollup-plugin-typescript": "^1.0.1", 34 | "source-map": "^0.6.1", 35 | "source-map-support": "^0.5.16", 36 | "svelte": "^3.16.0", 37 | "tiny-glob": "^0.2.6", 38 | "tslib": "^1.10.0", 39 | "typescript": "^3.6.4" 40 | }, 41 | "peerDependencies": { 42 | "svelte": "^3.16.0", 43 | "typescript": "^3.6.4" 44 | }, 45 | "scripts": { 46 | "build": "rollup -c", 47 | "dev": "rollup -c -w", 48 | "test": "mocha --opts mocha.opts", 49 | "pretest": "rollup -c rollup.config.test.js", 50 | "prepublishOnly": "npm run build" 51 | }, 52 | "files": [ 53 | "index.mjs", 54 | "index.js", 55 | "index.d.ts", 56 | "README.md", 57 | "LICENSE", 58 | "svelte-jsx.d.ts", 59 | "svelte-shims.d.ts" 60 | ] 61 | } 62 | -------------------------------------------------------------------------------- /rollup.config.js: -------------------------------------------------------------------------------- 1 | import typescript from 'rollup-plugin-typescript'; 2 | import commonjs from 'rollup-plugin-commonjs'; 3 | import resolve from 'rollup-plugin-node-resolve'; 4 | import json from 'rollup-plugin-json'; 5 | import builtins from 'builtin-modules' 6 | 7 | export default [{ 8 | input: 'src/index.ts', 9 | output: [{ 10 | sourcemap: true, 11 | format: 'commonjs', 12 | file: 'index.js' 13 | },{ 14 | file: 'index.mjs', 15 | format: 'esm' 16 | }], 17 | plugins: [ 18 | resolve({ browser: false, preferBuiltins: true }), 19 | commonjs(), 20 | json(), 21 | typescript() 22 | ], 23 | watch: { 24 | clearScreen: false 25 | }, 26 | external: [...builtins, 'typescript', 'svelte', 'svelte/compiler'] 27 | }]; 28 | -------------------------------------------------------------------------------- /rollup.config.test.js: -------------------------------------------------------------------------------- 1 | import typescript from 'rollup-plugin-typescript'; 2 | import commonjs from 'rollup-plugin-commonjs'; 3 | import resolve from 'rollup-plugin-node-resolve'; 4 | import json from 'rollup-plugin-json'; 5 | import del from 'rollup-plugin-delete'; 6 | import builtins from 'builtin-modules' 7 | 8 | export default [{ 9 | input: ['src/index.ts'], 10 | output: { 11 | sourcemap: true, 12 | format: 'commonjs', 13 | file: 'test/build/index.js' 14 | }, 15 | plugins: [ 16 | del({ targets: 'test/build/index.*' }), 17 | resolve({ browser: false, preferBuiltins: true }), 18 | commonjs(), 19 | json(), 20 | typescript() 21 | ], 22 | external: [...builtins, 'typescript', 'svelte', 'svelte/compiler', 'parse5', 'magic-string'] 23 | }, { 24 | input: ['src/htmlxtojsx.ts'], 25 | output: { 26 | sourcemap: true, 27 | format: 'commonjs', 28 | file: 'test/build/htmlxtojsx.js' 29 | }, 30 | plugins: [ 31 | del({ targets: 'test/build/htmlxtojsx.*' }), 32 | resolve({ browser: false, preferBuiltins: true }), 33 | commonjs(), 34 | json(), 35 | typescript() 36 | ], 37 | external: [...builtins, 'typescript', 'svelte', 'svelte/compiler', 'parse5', 'magic-string'] 38 | 39 | } 40 | ]; 41 | -------------------------------------------------------------------------------- /src/htmlxparser.ts: -------------------------------------------------------------------------------- 1 | import parse5, { DefaultTreeDocumentFragment, DefaultTreeElement, DefaultTreeTextNode, DefaultTreeNode } from 'parse5' 2 | import compiler from 'svelte/compiler' 3 | import { Node } from 'svelte/types/compiler/interfaces'; 4 | 5 | 6 | 7 | function walkAst(doc: DefaultTreeElement, action: (c: DefaultTreeElement) => void) { 8 | action(doc); 9 | if (!doc.childNodes) return; 10 | for (let i = 0; i < doc.childNodes.length; i++) { 11 | walkAst(doc.childNodes[i] as DefaultTreeElement, action); 12 | } 13 | } 14 | 15 | export function findVerbatimElements(htmlx: string) { 16 | let elements:Node[] = [] 17 | let tag_names = ['script', 'style']; 18 | 19 | let doc: DefaultTreeDocumentFragment = parse5.parseFragment (htmlx, { sourceCodeLocationInfo: true }) as DefaultTreeDocumentFragment; 20 | 21 | const checkCase = (content: DefaultTreeTextNode, el: parse5.DefaultTreeElement) => { 22 | const orgStart = el.sourceCodeLocation.startOffset || 0; 23 | const orgEnd = el.sourceCodeLocation.endOffset || 0; 24 | const outerHtml = htmlx.substring(orgStart, orgEnd); 25 | const onlyTag = content ? outerHtml.replace(content.value, '') : outerHtml; 26 | 27 | return tag_names.some(tag => onlyTag.match(tag)); 28 | } 29 | 30 | 31 | walkAst(doc as DefaultTreeElement, el => { 32 | if (tag_names.includes(el.nodeName)) { 33 | let content = (el.childNodes && el.childNodes.length > 0) ? el.childNodes[0] as DefaultTreeTextNode : null; 34 | if(!checkCase(content, el)) { 35 | return; 36 | } 37 | elements.push({ 38 | start: el.sourceCodeLocation.startOffset, 39 | end: el.sourceCodeLocation.endOffset, 40 | type: el.nodeName[0].toUpperCase() + el.nodeName.substr(1), 41 | attributes: !el.attrs ? [] : el.attrs.map(a => {return { 42 | type: "Attribute", 43 | name: a.name, 44 | value: [{ 45 | type: "Text", 46 | start: htmlx.indexOf("=", el.sourceCodeLocation.attrs[a.name].startOffset) +1, 47 | end: el.sourceCodeLocation.attrs[a.name].endOffset, 48 | raw: a.value, 49 | }], 50 | start: el.sourceCodeLocation.attrs[a.name].startOffset, 51 | end: el.sourceCodeLocation.attrs[a.name].endOffset 52 | }}), 53 | content: !content ? null : { 54 | type: "Text", 55 | start: content.sourceCodeLocation.startOffset, 56 | end: content.sourceCodeLocation.endOffset, 57 | value: content.value, 58 | raw: content.value 59 | } 60 | }); 61 | } 62 | }); 63 | 64 | return elements; 65 | } 66 | 67 | export function blankVerbatimContent(htmlx: string, verbatimElements: Node[]) { 68 | let output = htmlx; 69 | for (var node of verbatimElements) { 70 | let content = node.content; 71 | if (content) { 72 | output = output.substring(0, content.start) 73 | + output.substring(content.start, content.end).replace(/[^\n]/g, " ") 74 | + output.substring(content.end); 75 | } 76 | } 77 | return output 78 | } 79 | 80 | 81 | export function parseHtmlx(htmlx: string): Node { 82 | //Svelte tries to parse style and script tags which doesn't play well with typescript, so we blank them out. 83 | //HTMLx spec says they should just be retained after processing as is, so this is fine 84 | let verbatimElements = findVerbatimElements(htmlx); 85 | let deconstructed = blankVerbatimContent(htmlx, verbatimElements); 86 | 87 | //extract the html content parsed as htmlx this excludes our script and style tags 88 | let svelteHtmlxAst = compiler.parse(deconstructed).html; 89 | 90 | //restore our script and style tags as nodes to maintain validity with HTMLx 91 | for (var s of verbatimElements) { 92 | svelteHtmlxAst.children.push(s); 93 | svelteHtmlxAst.start = Math.min(svelteHtmlxAst.start, s.start); 94 | svelteHtmlxAst.end = Math.max(svelteHtmlxAst.end, s.end); 95 | } 96 | return svelteHtmlxAst; 97 | } 98 | -------------------------------------------------------------------------------- /src/htmlxtojsx.ts: -------------------------------------------------------------------------------- 1 | import MagicString from 'magic-string'; 2 | import svelte from 'svelte/compiler'; 3 | import { Node } from 'estree-walker'; 4 | import { parseHtmlx } from './htmlxparser'; 5 | import KnownEvents from './knownevents'; 6 | import svgAttributes from './svgattributes'; 7 | 8 | type ElementType = String 9 | const oneWayBindingAttributes:Map = new Map( 10 | ['clientWidth', 'clientHeight', 'offsetWidth', 'offsetHeight'].map(e => [e, 'HTMLDivElement'] as [String, String]).concat( 11 | ['duration','buffered','seekable','seeking', 'played', 'ended'].map(e => [e, 'HTMLMediaElement']) 12 | )); 13 | 14 | 15 | export function convertHtmlxToJsx(str: MagicString, ast: Node, onWalk: (node: Node, parent: Node, prop:string, index: number) => void = null, onLeave: (node: Node, parent: Node, prop: string, index: number) => void = null) { 16 | let htmlx = str.original; 17 | str.prepend("<>"); 18 | str.append(""); 19 | const handleRaw = (rawBlock: Node) => { 20 | let tokenStart = htmlx.indexOf("@html", rawBlock.start); 21 | str.remove(tokenStart, tokenStart + "@html".length); 22 | }; 23 | const handleDebug = (debugBlock: Node) => { 24 | let tokenStart = htmlx.indexOf("@debug", debugBlock.start); 25 | str.remove(tokenStart, tokenStart + "@debug".length); 26 | }; 27 | 28 | const handleEventHandler = (attr: Node, parent: Node) => { 29 | let jsxEventName = attr.name; 30 | 31 | if (parent.type == "Element" /*&& KnownEvents.indexOf('on'+jsxEventName) >= 0*/) { 32 | if (attr.expression) { 33 | let endAttr = htmlx.indexOf("=", attr.start) 34 | str.overwrite(attr.start+'on:'.length-1, endAttr, jsxEventName) 35 | if (htmlx[attr.end - 1] == '"') { 36 | let firstQuote = htmlx.indexOf('"', endAttr); 37 | str.remove(firstQuote, firstQuote + 1); 38 | str.remove(attr.end - 1, attr.end); 39 | } 40 | } else { 41 | str.overwrite(attr.start+'on:'.length-1, attr.end, `${jsxEventName}={null}`) 42 | } 43 | } else { 44 | //We don't know the type of the event handler 45 | if (attr.expression) { 46 | //for handler assignment, we changeIt to call to our __sveltets_ensureFunction 47 | str.overwrite(attr.start, attr.expression.start, "{...__sveltets_ensureFunction(("); 48 | str.overwrite(attr.expression.end, attr.end, "))}"); 49 | } else { 50 | //for passthrough handlers, we just remove 51 | str.remove(attr.start, attr.end) 52 | } 53 | } 54 | } 55 | 56 | const handleClassDirective = (attr: Node) => { 57 | let needCurly = (attr.expression.start == attr.start + "class:".length); 58 | str.overwrite(attr.start, attr.expression.start, `{...__sveltets_ensureType(Boolean, !!(`) 59 | str.appendLeft(attr.expression.end, `))${needCurly ? "}" : ""}`) 60 | if (htmlx[attr.end - 1] == '"') { 61 | str.remove(attr.end - 1, attr.end); 62 | } 63 | } 64 | 65 | const handleActionDirective = (attr: Node) => { 66 | str.overwrite(attr.start, attr.start + "use:".length, "{...__sveltets_ensureAction(") 67 | 68 | if (!attr.expression) { 69 | str.appendLeft(attr.end, ")}"); 70 | return; 71 | } 72 | 73 | str.overwrite(attr.start + `use:${attr.name}`.length, attr.expression.start, ",") 74 | str.appendLeft(attr.expression.end, ")"); 75 | if (htmlx[attr.end - 1] == '"') { 76 | str.remove(attr.end - 1, attr.end); 77 | } 78 | } 79 | 80 | const handleTransitionDirective = (attr: Node) => { 81 | str.overwrite(attr.start, htmlx.indexOf(":", attr.start) + 1, "{...__sveltets_ensureTransition(") 82 | 83 | if (attr.modifiers.length) { 84 | let local = htmlx.indexOf("|", attr.start); 85 | str.remove(local, attr.expression ? attr.expression.start : attr.end); 86 | } 87 | 88 | if (!attr.expression) { 89 | str.appendLeft(attr.end, ", {})}"); 90 | return; 91 | } 92 | 93 | str.overwrite(htmlx.indexOf(":", attr.start) + 1 + `${attr.name}`.length, attr.expression.start, ", ") 94 | str.appendLeft(attr.expression.end, ")"); 95 | if (htmlx[attr.end - 1] == '"') { 96 | str.remove(attr.end - 1, attr.end); 97 | } 98 | } 99 | 100 | const handleAnimateDirective = (attr: Node) => { 101 | str.overwrite(attr.start, htmlx.indexOf(":", attr.start) + 1, "{...__sveltets_ensureAnimation(") 102 | 103 | if (!attr.expression) { 104 | str.appendLeft(attr.end, ", {})}"); 105 | return; 106 | } 107 | str.overwrite(htmlx.indexOf(":", attr.start) + 1 + `${attr.name}`.length, attr.expression.start, ", ") 108 | str.appendLeft(attr.expression.end, ")"); 109 | if (htmlx[attr.end - 1] == '"') { 110 | str.remove(attr.end - 1, attr.end); 111 | } 112 | } 113 | 114 | const handleBinding = (attr: Node, el: Node) => { 115 | //bind group on input 116 | if (attr.name == "group" && el.name == "input") { 117 | str.remove(attr.start, attr.expression.start); 118 | str.appendLeft(attr.expression.start, "{...__sveltets_any(") 119 | str.overwrite(attr.expression.end, attr.end, ")}") 120 | return; 121 | } 122 | 123 | //bind this on element 124 | if (attr.name == "this" && el.type == "Element") { 125 | str.remove(attr.start, attr.expression.start) 126 | str.appendLeft(attr.expression.start, "{...__sveltets_ensureType(HTMLElement, "); 127 | str.overwrite(attr.expression.end, attr.end, ")}"); 128 | return; 129 | } 130 | 131 | //bind this on component 132 | if (attr.name == "this" && el.type == "InlineComponent") { 133 | str.remove(attr.start, attr.expression.start) 134 | str.appendLeft(attr.expression.start, `{...__sveltets_ensureType(${el.name}, `); 135 | str.overwrite(attr.expression.end, attr.end, ")}"); 136 | return; 137 | } 138 | 139 | //one way binding 140 | if (oneWayBindingAttributes.has(attr.name) && el.type == "Element") { 141 | str.remove(attr.start, attr.expression.start) 142 | str.appendLeft(attr.expression.start, `{...__sveltets_any(`); 143 | if (attr.expression.end == attr.end) { 144 | str.appendLeft(attr.end, `=__sveltets_instanceOf(${oneWayBindingAttributes.get(attr.name)}).${attr.name})}`) 145 | } else { 146 | str.overwrite(attr.expression.end, attr.end, `=__sveltets_instanceOf(${oneWayBindingAttributes.get(attr.name)}).${attr.name})}`) 147 | } 148 | return; 149 | } 150 | 151 | 152 | str.remove(attr.start, attr.start + "bind:".length); 153 | if (attr.expression.start == attr.start + "bind:".length) { 154 | str.appendLeft(attr.end, `={${attr.name}}`); 155 | return 156 | } 157 | 158 | //remove possible quotes 159 | if (htmlx[attr.end - 1] == '"') { 160 | let firstQuote = htmlx.indexOf('"', attr.start); 161 | str.remove(firstQuote, firstQuote + 1); 162 | str.remove(attr.end - 1, attr.end); 163 | } 164 | 165 | } 166 | 167 | const handleSlot = (slotEl: Node, componentName: string, slotName: string) => { 168 | //collect "let" definitions 169 | let hasMoved = false; 170 | for (let attr of slotEl.attributes) { 171 | if (attr.type != "Let") continue; 172 | 173 | if (slotEl.children.length == 0) { 174 | //no children anyway, just wipe out the attribute 175 | str.remove(attr.start, attr.end); 176 | continue; 177 | } 178 | var afterTag = afterTag || htmlx.lastIndexOf(">", slotEl.children[0].start) + 1; 179 | 180 | str.move(attr.start, attr.end, afterTag); 181 | 182 | //remove let: 183 | if (hasMoved) { 184 | str.overwrite(attr.start, attr.start + "let:".length, ", "); 185 | } else { 186 | str.remove(attr.start, attr.start + "let:".length); 187 | } 188 | hasMoved = true; 189 | if (attr.expression) { 190 | //overwrite the = as a : 191 | let equalSign = htmlx.lastIndexOf("=", attr.expression.start); 192 | let curly = htmlx.lastIndexOf("{", attr.expression.start); 193 | str.overwrite(equalSign, curly + 1, ":"); 194 | str.remove(attr.expression.end, attr.end); 195 | } 196 | } 197 | if (!hasMoved) return; 198 | str.appendLeft(afterTag, "{() => { let {"); 199 | str.appendRight(afterTag, "} = __sveltets_instanceOf(" + componentName + ").$$slot_def." + slotName + ";<>") 200 | 201 | let closeTagStart = htmlx.lastIndexOf("<", slotEl.end) 202 | str.appendLeft(closeTagStart, "}}") 203 | } 204 | 205 | 206 | const handleComponent = (el: Node) => { 207 | //we need to remove : if it is a svelte component 208 | if (el.name.startsWith("svelte:")) { 209 | let colon = htmlx.indexOf(":", el.start); 210 | str.remove(colon, colon+1); 211 | 212 | let closeTag = htmlx.lastIndexOf("/"+el.name, el.end) 213 | if (closeTag > el.start) { 214 | let colon = htmlx.indexOf(":",closeTag) 215 | str.remove(colon, colon + 1); 216 | } 217 | } 218 | 219 | //we only need to do something if there is a let or slot 220 | handleSlot(el, el.name, "default"); 221 | 222 | //walk the direct children looking for slots. We do this here because we need the name of our component for handleSlot 223 | //we could lean on leave/enter, but I am lazy 224 | if (!el.children) return; 225 | for (let child of el.children) { 226 | if (!child.attributes) continue; 227 | let slot = child.attributes.find(a => a.name == "slot"); 228 | if (slot) { 229 | if (slot.value && slot.value.length) { 230 | handleSlot(child, el.name, slot.value[0].raw) 231 | } 232 | } 233 | } 234 | } 235 | 236 | const handleAttribute = (attr: Node, parent: Node) => { 237 | 238 | //if we are on an "element" we are case insensitive, lowercase to match our JSX 239 | if (parent.type == "Element") { 240 | //skip Attribute shorthand, that is handled below 241 | if (attr.value !== true && !(attr.value.length && attr.value.length == 1 && attr.value[0].type == "AttributeShorthand")) { 242 | 243 | let name = attr.name; 244 | if (!svgAttributes.find(x => x == name)) { 245 | name = name.toLowerCase(); 246 | } 247 | 248 | //strip ":" from out attribute name and uppercase the next letter to convert to jsx attribute 249 | let colonIndex = name.indexOf(":"); 250 | if (colonIndex >= 0) { 251 | let parts = name.split(":"); 252 | name = parts[0] + parts[1][0].toUpperCase() + parts[1].substring(1); 253 | } 254 | 255 | str.overwrite(attr.start, attr.start + attr.name.length, name) 256 | } 257 | 258 | } 259 | 260 | 261 | 262 | //we are a bare attribute 263 | if (attr.value === true) return; 264 | 265 | if (attr.value.length == 0) return; //wut? 266 | //handle single value 267 | if (attr.value.length == 1) { 268 | let attrVal = attr.value[0]; 269 | 270 | if (attr.name == "slot") { 271 | str.remove(attr.start, attr.end); 272 | return; 273 | } 274 | 275 | if (attrVal.type == "AttributeShorthand") { 276 | let attrName = attrVal.expression.name 277 | if (parent.type == "Element") { 278 | attrName = svgAttributes.find(a => a == attrName) ? attrName :attrName.toLowerCase() 279 | } 280 | 281 | str.appendRight(attr.start, `${attrName}=`); 282 | return; 283 | } 284 | 285 | let equals = htmlx.lastIndexOf("=", attrVal.start); 286 | if (attrVal.type == "Text") { 287 | if (attrVal.end == attr.end) { 288 | //we are not quoted. Add some 289 | str.prependRight(equals + 1, '"'); 290 | str.appendLeft(attr.end, '"'); 291 | } 292 | return; 293 | } 294 | 295 | if (attrVal.type == "MustacheTag") { 296 | //if the end doesn't line up, we are wrapped in quotes 297 | if (attrVal.end != attr.end) { 298 | str.remove(attrVal.start - 1, attrVal.start); 299 | str.remove(attr.end - 1, attr.end); 300 | } 301 | return; 302 | } 303 | return; 304 | } 305 | 306 | // we have multiple attribute values, so we build a string out of them. 307 | // technically the user can do something funky like attr="text "{value} or even attr=text{value} 308 | // so instead of trying to maintain a nice sourcemap with prepends etc, we just overwrite the whole thing 309 | 310 | let equals = htmlx.lastIndexOf("=", attr.value[0].start); 311 | str.overwrite(equals, attr.value[0].start, "={`"); 312 | 313 | for(let n of attr.value) { 314 | if (n.type == "MustacheTag") { 315 | str.appendRight(n.start, "$") 316 | } 317 | } 318 | 319 | if (htmlx[attr.end-1] == '"') { 320 | str.overwrite(attr.end-1, attr.end, "`}") 321 | } else { 322 | str.appendLeft(attr.end, "`}") 323 | } 324 | 325 | } 326 | 327 | const handleElement = (node: Node) => { 328 | //we just have to self close void tags since jsx always wants the /> 329 | let voidTags = "area,base,br,col,embed,hr,img,input,link,meta,param,source,track,wbr".split(','); 330 | if (voidTags.find(x => x == node.name)) { 331 | if (htmlx[node.end - 2] != '/') { 332 | str.appendRight(node.end - 1, "/"); 333 | } 334 | } 335 | 336 | //some tags auto close when they encounter certain elements, jsx doesn't support this 337 | if (htmlx[node.end-1] != '>') { 338 | str.appendRight(node.end, ``) 339 | } 340 | } 341 | 342 | const handleIf = (ifBlock: Node) => { 343 | if (ifBlock.elseif) { 344 | //we are an elseif so our work is easier 345 | str.appendLeft(ifBlock.expression.start,"(") 346 | str.appendLeft(ifBlock.expression.end, ")"); 347 | return; 348 | } 349 | // {#if expr} -> 350 | // {() => { if (expr) { <> 351 | str.overwrite(ifBlock.start, ifBlock.expression.start, "{() => {if ("); 352 | let end = htmlx.indexOf("}", ifBlock.expression.end); 353 | str.appendLeft(ifBlock.expression.end, ")"); 354 | str.overwrite(end, end + 1, "{<>"); 355 | 356 | // {/if} -> }}} 357 | let endif = htmlx.lastIndexOf("{", ifBlock.end); 358 | str.overwrite(endif, ifBlock.end, "}}}"); 359 | }; 360 | 361 | // {:else} -> } else {<> 362 | const handleElse = (elseBlock: Node, parent: Node) => { 363 | if (parent.type != "IfBlock") return; 364 | let elseEnd = htmlx.lastIndexOf("}", elseBlock.start); 365 | let elseword = htmlx.lastIndexOf(":else", elseEnd); 366 | let elseStart = htmlx.lastIndexOf("{", elseword); 367 | str.overwrite(elseStart, elseStart + 1, "}"); 368 | str.overwrite(elseEnd, elseEnd + 1, "{<>"); 369 | let colon = htmlx.indexOf(":", elseword); 370 | str.remove(colon, colon + 1); 371 | } 372 | 373 | const handleEach = (eachBlock: Node) => { 374 | // {#each items as item,i (key)} -> 375 | // {(items).map((item,i) => (key) && <> 376 | str.overwrite(eachBlock.start, eachBlock.expression.start, "{("); 377 | str.overwrite(eachBlock.expression.end, eachBlock.context.start, ").map(("); 378 | let contextEnd = eachBlock.context.end; 379 | if (eachBlock.index) { 380 | let idxLoc = htmlx.indexOf(eachBlock.index, contextEnd); 381 | contextEnd = idxLoc + eachBlock.index.length; 382 | } 383 | str.prependLeft(contextEnd, ") =>"); 384 | if (eachBlock.key) { 385 | let endEachStart = htmlx.indexOf("}", eachBlock.key.end); 386 | str.overwrite(endEachStart, endEachStart + 1, " && <>"); 387 | } 388 | else { 389 | let endEachStart = htmlx.indexOf("}", contextEnd); 390 | str.overwrite(endEachStart, endEachStart + 1, " <>"); 391 | } 392 | let endEach = htmlx.lastIndexOf("{", eachBlock.end); 393 | // {/each} -> )} or {:else} -> )} 394 | if (eachBlock.else) { 395 | let elseEnd = htmlx.lastIndexOf("}", eachBlock.else.start); 396 | let elseStart = htmlx.lastIndexOf("{", elseEnd); 397 | str.overwrite(elseStart, elseEnd + 1, ")}"); 398 | str.remove(endEach, eachBlock.end); 399 | } 400 | else { 401 | str.overwrite(endEach, eachBlock.end, ")}"); 402 | } 403 | }; 404 | // {#await somePromise then value} -> 405 | // {() => {let _$$p = (somePromise); 406 | const handleAwait = (awaitBlock: Node) => { 407 | str.overwrite(awaitBlock.start, awaitBlock.expression.start, "{() => {let _$$p = ("); 408 | str.prependLeft(awaitBlock.expression.end, ");"); 409 | // then value } | {:then value} -> 410 | // _$$p.then((value) => {<> 411 | let thenStart: number; 412 | let thenEnd: number; 413 | if (!awaitBlock.pending.skip) { 414 | //thenBlock seems to include the {:then} tag 415 | thenStart = awaitBlock.then.start; 416 | thenEnd = htmlx.indexOf("}", thenStart) + 1; 417 | str.prependLeft(thenStart, "; "); 418 | // add the start tag too 419 | let awaitEnd = htmlx.indexOf("}", awaitBlock.expression.end); 420 | str.remove(awaitEnd, awaitEnd + 1); 421 | str.appendRight(awaitEnd, " <>"); 422 | } 423 | else { 424 | thenEnd = htmlx.lastIndexOf("}", awaitBlock.then.start) + 1; 425 | thenStart = htmlx.indexOf("then", awaitBlock.expression.end); 426 | } 427 | // console.log("overwriting",thenStart, thenEnd); 428 | str.overwrite(thenStart, thenEnd, "_$$p.then((" + awaitBlock.value + ") => {<>"); 429 | //{:catch error} -> 430 | //}).catch((error) => {<> 431 | if (!awaitBlock.catch.skip) { 432 | //catch block includes the {:catch} 433 | let catchStart = awaitBlock.catch.start; 434 | let catchSymbolEnd = htmlx.indexOf(":catch", catchStart) + ":catch".length; 435 | let errorStart = awaitBlock.error ? htmlx.indexOf(awaitBlock.error, catchSymbolEnd) : catchSymbolEnd; 436 | let errorEnd = awaitBlock.error ? errorStart + awaitBlock.error.length : errorStart; 437 | let catchEnd = htmlx.indexOf("}", awaitBlock.catch.start) + 1; 438 | str.overwrite(catchStart, errorStart, "}).catch(("); 439 | str.overwrite(errorEnd, catchEnd, ") => {<>"); 440 | } 441 | // {/await} -> 442 | // <>})} 443 | let awaitEndStart = htmlx.lastIndexOf("{", awaitBlock.end); 444 | str.overwrite(awaitEndStart, awaitBlock.end, "})}}"); 445 | }; 446 | 447 | const handleComment = (node: Node) => { 448 | str.remove(node.start, node.end); 449 | } 450 | 451 | const handleSvelteTag = (node: Node) => { 452 | let colon = htmlx.indexOf(":", node.start); 453 | str.remove(colon, colon + 1); 454 | 455 | let closeTag = htmlx.lastIndexOf("/"+node.name, node.end) 456 | if (closeTag > node.start) { 457 | let colon = htmlx.indexOf(":",closeTag) 458 | str.remove(colon, colon + 1); 459 | } 460 | } 461 | 462 | 463 | (svelte as any).walk(ast, { 464 | enter: (node: Node, parent: Node, prop: string, index: number) => { 465 | try { 466 | switch (node.type) { 467 | case "IfBlock": handleIf(node); break; 468 | case "EachBlock": handleEach(node); break; 469 | case "ElseBlock": handleElse(node, parent); break; 470 | case "AwaitBlock": handleAwait(node); break; 471 | case "RawMustacheTag": handleRaw(node); break; 472 | case "DebugTag": handleDebug(node); break; 473 | case "InlineComponent": handleComponent(node); break; 474 | case "Element": handleElement(node); break; 475 | case "Comment": handleComment(node); break; 476 | case "Binding": handleBinding(node, parent); break; 477 | case "Class": handleClassDirective(node); break; 478 | case "Action": handleActionDirective(node); break; 479 | case "Transition": handleTransitionDirective(node); break; 480 | case "Animation": handleAnimateDirective(node); break; 481 | case "Attribute": handleAttribute(node, parent); break; 482 | case "EventHandler": handleEventHandler(node, parent); break; 483 | case "Options": handleSvelteTag(node); break; 484 | case "Window": handleSvelteTag(node); break; 485 | case "Head": handleSvelteTag(node); break; 486 | case "Body": handleSvelteTag(node); break; 487 | } 488 | if (onWalk) onWalk(node, parent, prop, index); 489 | } catch (e) { 490 | console.error("Error walking node ", node); 491 | throw e; 492 | } 493 | }, 494 | 495 | leave: (node: Node, parent: Node, prop: string, index: number ) => { 496 | try { 497 | if (onLeave) onLeave(node, parent, prop, index); 498 | } catch (e) { 499 | console.error("Error leaving node ", node); 500 | throw e; 501 | } 502 | } 503 | }); 504 | } 505 | 506 | export function htmlx2jsx(htmlx: string) { 507 | let ast = parseHtmlx(htmlx); 508 | let str = new MagicString(htmlx) 509 | 510 | convertHtmlxToJsx(str, ast); 511 | 512 | return { 513 | map: str.generateMap({ hires: true }), 514 | code: str.toString(), 515 | } 516 | } -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | export { svelte2tsx as default } from './svelte2tsx' -------------------------------------------------------------------------------- /src/knownevents.ts: -------------------------------------------------------------------------------- 1 | export default [ 2 | "oncopy", 3 | "oncopycapture", 4 | "oncut", 5 | "oncutcapture", 6 | "onpaste", 7 | "onpastecapture", 8 | 9 | // composition events 10 | "oncompositionend", 11 | "oncompositionendcapture", 12 | "oncompositionstart", 13 | "oncompositionstartcapture", 14 | "oncompositionupdate", 15 | "oncompositionupdatecapture", 16 | 17 | // focus events 18 | "onfocus", 19 | "onfocuscapture", 20 | "onblur", 21 | "onblurcapture", 22 | 23 | // form events 24 | "onchange", 25 | "onchangecapture", 26 | "oninput", 27 | "oninputcapture", 28 | "onreset", 29 | "onresetcapture", 30 | "onsubmit", 31 | "onsubmitcapture", 32 | 33 | // image events 34 | "onload", 35 | "onloadcapture", 36 | "onerror", 37 | "onerrorcapture", 38 | 39 | // keyboard events 40 | "onkeydown", 41 | "onkeydowncapture", 42 | "onkeypress", 43 | "onkeypresscapture", 44 | "onkeyup", 45 | "onkeyupcapture", 46 | 47 | // media events 48 | "onabort", 49 | "onabortcapture", 50 | "oncanplay", 51 | "oncanplaycapture", 52 | "oncanplaythrough", 53 | "oncanplaythroughcapture", 54 | "ondurationchange", 55 | "ondurationchangecapture", 56 | "onemptied", 57 | "onemptiedcapture", 58 | "onencrypted", 59 | "onencryptedcapture", 60 | "onended", 61 | "onendedcapture", 62 | "onloadeddata", 63 | "onloadeddatacapture", 64 | "onloadedmetadata", 65 | "onloadedmetadatacapture", 66 | "onloadstart", 67 | "onloadstartcapture", 68 | "onpause", 69 | "onpausecapture", 70 | "onplay", 71 | "onplaycapture", 72 | "onplaying", 73 | "onplayingcapture", 74 | "onprogress", 75 | "onprogresscapture", 76 | "onratechange", 77 | "onratechangecapture", 78 | "onseeked", 79 | "onseekedcapture", 80 | "onseeking", 81 | "onseekingcapture", 82 | "onstalled", 83 | "onstalledcapture", 84 | "onsuspend", 85 | "onsuspendcapture", 86 | "ontimeupdate", 87 | "ontimeupdatecapture", 88 | "onvolumechange", 89 | "onvolumechangecapture", 90 | "onwaiting", 91 | "onwaitingcapture", 92 | 93 | // mouseevents 94 | "onclick", 95 | "onclickcapture", 96 | "oncontextmenu", 97 | "oncontextmenucapture", 98 | "ondoubleclick", 99 | "ondoubleclickcapture", 100 | "ondrag", 101 | "ondragcapture", 102 | "ondragend", 103 | "ondragendcapture", 104 | "ondragenter", 105 | "ondragentercapture", 106 | "ondragexit", 107 | "ondragexitcapture", 108 | "ondragleave", 109 | "ondragleavecapture", 110 | "ondragover", 111 | "ondragovercapture", 112 | "ondragstart", 113 | "ondragstartcapture", 114 | "ondrop", 115 | "ondropcapture", 116 | "onmousedown", 117 | "onmousedowncapture", 118 | "onmouseenter", 119 | "onmouseleave", 120 | "onmousemove", 121 | "onmousemovecapture", 122 | "onmouseout", 123 | "onmouseoutcapture", 124 | "onmouseover", 125 | "onmouseovercapture", 126 | "onmouseup", 127 | "onmouseupcapture", 128 | 129 | // selection events 130 | "onselect", 131 | "onselectcapture", 132 | 133 | // touch events 134 | "ontouchcancel", 135 | "ontouchcancelcapture", 136 | "ontouchend", 137 | "ontouchendcapture", 138 | "ontouchmove", 139 | "ontouchmovecapture", 140 | "ontouchstart", 141 | "ontouchstartcapture", 142 | 143 | // ui events 144 | "onscroll", 145 | "onscrollcapture", 146 | 147 | // wheel events 148 | "onwheel", 149 | "onwheelcapture", 150 | 151 | // animation events 152 | "onanimationstart", 153 | "onanimationstartcapture", 154 | "onanimationend", 155 | "onanimationendcapture", 156 | "onanimationiteration", 157 | "onanimationiterationcapture", 158 | 159 | // transition events 160 | "ontransitionend", 161 | "ontransitionendcapture" 162 | ] -------------------------------------------------------------------------------- /src/svelte2tsx.ts: -------------------------------------------------------------------------------- 1 | import MagicString from 'magic-string' 2 | import { parseHtmlx } from './htmlxparser'; 3 | import { convertHtmlxToJsx } from './htmlxtojsx'; 4 | import { Node } from 'svelte/compiler' 5 | import * as ts from 'typescript'; 6 | 7 | function AttributeValueAsJsExpression(htmlx: string, attr: Node): string { 8 | if (attr.value.length == 0) return "''"; //wut? 9 | 10 | //handle single value 11 | if (attr.value.length == 1) { 12 | let attrVal = attr.value[0]; 13 | 14 | if (attrVal.type == "AttributeShorthand") { 15 | return attrVal.expression.name; 16 | } 17 | 18 | if (attrVal.type == "Text") { 19 | return '"' + attrVal.raw + '"'; 20 | } 21 | 22 | if (attrVal.type == "MustacheTag") { 23 | return htmlx.substring(attrVal.expression.start, attrVal.expression.end) 24 | } 25 | throw Error("Unknown attribute value type:" + attrVal.type); 26 | } 27 | 28 | // we have multiple attribute values, so we know we are building a string out of them. 29 | // so return a dummy string, it will typecheck the same :) 30 | return '"__svelte_ts_string"'; 31 | } 32 | 33 | 34 | type TemplateProcessResult = { 35 | uses$$props: boolean, 36 | slots: Map>; 37 | scriptTag: Node, 38 | moduleScriptTag: Node 39 | } 40 | 41 | 42 | class Scope { 43 | declared: Set = new Set() 44 | parent: Scope 45 | 46 | constructor(parent?: Scope) { 47 | this.parent = parent 48 | } 49 | } 50 | 51 | type pendingStoreResolution = { 52 | node: T, 53 | parent: T, 54 | scope: Scope 55 | } 56 | 57 | function processSvelteTemplate(str: MagicString): TemplateProcessResult { 58 | let htmlxAst = parseHtmlx(str.original); 59 | 60 | let uses$$props = false; 61 | 62 | //track if we are in a declaration scope 63 | let isDeclaration = false; 64 | 65 | 66 | //track $store variables since we are only supposed to give top level scopes special treatment, and users can declare $blah variables at higher scopes 67 | //which prevents us just changing all instances of Identity that start with $ 68 | 69 | let pendingStoreResolutions:pendingStoreResolution[] = [] 70 | let scope = new Scope(); 71 | const pushScope = () => scope = new Scope(scope) 72 | const popScope = () => scope = scope.parent 73 | 74 | const handleStore = (node: Node, parent: Node) => { 75 | //handle assign to 76 | if (parent.type == "AssignmentExpression" && parent.left == node && parent.operator == "=") { 77 | let dollar = str.original.indexOf("$", node.start); 78 | str.remove(dollar, dollar+1); 79 | str.overwrite(node.end, str.original.indexOf("=", node.end)+1, ".set("); 80 | str.appendLeft(parent.end, ")"); 81 | return; 82 | } 83 | 84 | //rewrite get 85 | let dollar = str.original.indexOf("$", node.start); 86 | str.overwrite(dollar, dollar+1, "__sveltets_store_get("); 87 | str.prependLeft(node.end, ")") 88 | } 89 | 90 | const resolveStore = (pending: pendingStoreResolution) => { 91 | let { node, parent, scope } = pending; 92 | let name = node.name 93 | while (scope) { 94 | if (scope.declared.has(name)) { 95 | //we were manually declared, this isn't a store access. 96 | return; 97 | } 98 | scope = scope.parent 99 | } 100 | //We haven't been resolved, we must be a store read/write, handle it. 101 | handleStore(node, parent); 102 | } 103 | 104 | const enterBlockStatement = () => pushScope() 105 | const leaveBlockStatement = () => popScope() 106 | 107 | const enterFunctionDeclaration = () => pushScope(); 108 | const leaveFunctionDeclaration = () => popScope(); 109 | 110 | const enterArrowFunctionExpression = () => pushScope(); 111 | const leaveArrowFunctionExpression = () => popScope(); 112 | 113 | const handleIdentifier = (node: Node, parent: Node, prop: string) => { 114 | if (node.name == "$$props") { 115 | uses$$props = true; 116 | return; 117 | } 118 | 119 | //handle potential store 120 | if (node.name[0] == "$") { 121 | if (isDeclaration) { 122 | if (parent.type == "Property" && prop == "key") return; 123 | scope.declared.add(node.name); 124 | } else { 125 | if (parent.type == "MemberExpression" && prop == "property") return; 126 | if (parent.type == "Property" && prop == "key") return; 127 | pendingStoreResolutions.push({ node, parent, scope }) 128 | } 129 | return 130 | } 131 | } 132 | 133 | let scriptTag: Node = null; 134 | let moduleScriptTag: Node = null; 135 | const handleScriptTag = (node: Node) => { 136 | if (node.attributes && node.attributes.find(a => a.name == "context" && a.value.length == 1 && a.value[0].raw == "module")) { 137 | moduleScriptTag = node; 138 | } else { 139 | scriptTag = node; 140 | } 141 | } 142 | 143 | let slots = new Map>(); 144 | const handleSlot = (node: Node) => { 145 | let nameAttr = node.attributes.find(a => a.name == "name"); 146 | let slotName = nameAttr ? nameAttr.value[0].raw : "default"; 147 | //collect attributes 148 | let attributes = new Map(); 149 | for (let attr of node.attributes) { 150 | if (attr.name == "name") continue; 151 | if (!attr.value.length) continue; 152 | attributes.set(attr.name, AttributeValueAsJsExpression(str.original, attr)); 153 | } 154 | slots.set(slotName, attributes) 155 | } 156 | 157 | const handleStyleTag = (node: Node) => { 158 | str.remove(node.start, node.end); 159 | } 160 | 161 | 162 | const onHtmlxWalk = (node:Node, parent:Node, prop: string, index: number) => { 163 | 164 | if (prop == "params" && (parent.type == "FunctionDeclaration" || parent.type == "ArrowFunctionExpression")) { 165 | isDeclaration = true; 166 | } 167 | if (prop == "id" && parent.type == "VariableDeclarator") { 168 | isDeclaration = true; 169 | } 170 | 171 | 172 | switch(node.type) { 173 | case "Identifier": handleIdentifier(node, parent, prop); break; 174 | case "Slot": handleSlot(node); break; 175 | case "Style": handleStyleTag(node); break; 176 | case "Script": handleScriptTag(node); break; 177 | case "BlockStatement": enterBlockStatement(); break; 178 | case "FunctionDeclaration": enterFunctionDeclaration(); break; 179 | case "ArrowFunctionExpression": enterArrowFunctionExpression(); break; 180 | case "VariableDeclarator": isDeclaration = true; break; 181 | } 182 | } 183 | 184 | const onHtmlxLeave = (node:Node, parent:Node, prop: string, index: number) => { 185 | 186 | if (prop == "params" && (parent.type == "FunctionDeclaration" || parent.type == "ArrowFunctionExpression")) { 187 | isDeclaration = false; 188 | } 189 | 190 | if (prop == "id" && parent.type == "VariableDeclarator") { 191 | isDeclaration = false; 192 | } 193 | 194 | switch(node.type) { 195 | case "BlockStatement": leaveBlockStatement(); break; 196 | case "FunctionDeclaration": leaveFunctionDeclaration(); break; 197 | case "ArrowFunctionExpression": leaveArrowFunctionExpression(); break; 198 | } 199 | } 200 | 201 | convertHtmlxToJsx(str, htmlxAst, onHtmlxWalk, onHtmlxLeave); 202 | 203 | //resolve stores 204 | pendingStoreResolutions.map(resolveStore) 205 | 206 | return { 207 | moduleScriptTag, 208 | scriptTag, 209 | slots, 210 | uses$$props 211 | } 212 | } 213 | 214 | type InstanceScriptProcessResult = { 215 | exportedNames: Map; 216 | uses$$props: boolean; 217 | } 218 | 219 | function processInstanceScriptContent(str: MagicString, script: Node): InstanceScriptProcessResult { 220 | let htmlx = str.original; 221 | let scriptContent = htmlx.substring(script.content.start, script.content.end) 222 | let tsAst = ts.createSourceFile("component.ts.svelte", scriptContent, ts.ScriptTarget.Latest, true, ts.ScriptKind.TS); 223 | let astOffset = script.content.start; 224 | let exportedNames = new Map(); 225 | 226 | let implicitTopLevelNames: Map = new Map(); 227 | let uses$$props = false; 228 | 229 | 230 | //track if we are in a declaration scope 231 | let isDeclaration = false; 232 | 233 | //track $store variables since we are only supposed to give top level scopes special treatment, and users can declare $blah variables at higher scopes 234 | //which prevents us just changing all instances of Identity that start with $ 235 | let pendingStoreResolutions:pendingStoreResolution[] = [] 236 | 237 | let scope = new Scope(); 238 | let rootScope = scope; 239 | 240 | const pushScope = () => scope = new Scope(scope) 241 | const popScope = () => scope = scope.parent 242 | 243 | const addExport = (name: ts.BindingName, target: ts.BindingName = null, type: ts.TypeNode = null) => { 244 | if (name.kind != ts.SyntaxKind.Identifier) { 245 | throw Error("export source kind not supported " + name) 246 | } 247 | if (target && target.kind != ts.SyntaxKind.Identifier) { 248 | throw Error("export target kind not supported " + target) 249 | } 250 | if (target) { 251 | exportedNames.set(type ? `${name.text} as ${type.getText()}` : name.text, (target as ts.Identifier).text); 252 | } else { 253 | exportedNames.set(name.text, null); 254 | } 255 | } 256 | 257 | const removeExport = (start: number, end: number) => { 258 | let exportStart = str.original.indexOf("export", start+astOffset); 259 | let exportEnd = exportStart + (end - start); 260 | str.remove(exportStart, exportEnd); 261 | } 262 | 263 | const handleStore = (ident: ts.Node, parent: ts.Node) => { 264 | //handle assign to 265 | if (parent && ts.isBinaryExpression(parent) && parent.operatorToken.kind == ts.SyntaxKind.EqualsToken && parent.left == ident) { 266 | //remove $ 267 | let dollar = str.original.indexOf("$", ident.getStart() + astOffset); 268 | str.remove(dollar, dollar + 1); 269 | // replace = with .set( 270 | str.overwrite(ident.end+astOffset, parent.operatorToken.end + astOffset, ".set("); 271 | // append ) 272 | str.appendLeft(parent.end+astOffset, ")"); 273 | return; 274 | } 275 | 276 | // we must be on the right or not part of assignment 277 | let dollar = str.original.indexOf("$", ident.getStart() + astOffset); 278 | str.overwrite(dollar, dollar+1, "__sveltets_store_get("); 279 | str.appendLeft(ident.end+astOffset, ")"); 280 | } 281 | 282 | const resolveStore = (pending: pendingStoreResolution) => { 283 | let { node, parent, scope } = pending; 284 | let name = (node as ts.Identifier).text; 285 | while (scope) { 286 | if (scope.declared.has(name)) { 287 | //we were manually declared, this isn't a store access. 288 | return; 289 | } 290 | scope = scope.parent 291 | } 292 | //We haven't been resolved, we must be a store read/write, handle it. 293 | handleStore(node, parent); 294 | } 295 | 296 | const handleIdentifier = (ident: ts.Identifier, parent: ts.Node) => { 297 | if (ident.text == "$$props") { 298 | uses$$props = true; 299 | return 300 | } 301 | if (ts.isLabeledStatement(parent) && parent.label == ident) { 302 | return; 303 | } 304 | 305 | if (isDeclaration || ts.isParameter(parent)) { 306 | if (!ts.isBindingElement(ident.parent) || ident.parent.name == ident) { //we are a key, not a name, so don't care 307 | if (ident.text.startsWith('$') || scope == rootScope) { //track all top level declared identifiers and all $ prefixed identifiers 308 | scope.declared.add(ident.text); 309 | } 310 | } 311 | } else { 312 | //track potential store usage to be resolved 313 | if (ident.text.startsWith('$')) { 314 | if ((!ts.isPropertyAccessExpression(parent) || parent.expression == ident ) && 315 | (!ts.isPropertyAssignment(parent) || parent.initializer == ident)) { 316 | pendingStoreResolutions.push({ node: ident, parent, scope }) 317 | } 318 | } 319 | } 320 | } 321 | 322 | const handleExportedVariableDeclarationList = (list: ts.VariableDeclarationList) => { 323 | ts.forEachChild(list, (node) => { 324 | if (ts.isVariableDeclaration(node)) { 325 | if (ts.isIdentifier(node.name)) { 326 | if (node.type) { 327 | addExport(node.name, node.name, node.type); 328 | } else { 329 | addExport(node.name); 330 | } 331 | } else if (ts.isObjectBindingPattern(node.name) || ts.isArrayBindingPattern(node.name)) { 332 | ts.forEachChild(node.name, (element) => { 333 | if (ts.isBindingElement(element)) { 334 | addExport(element.name); 335 | } 336 | }); 337 | } 338 | } 339 | }); 340 | } 341 | 342 | const walk = (node: ts.Node, parent: ts.Node) => { 343 | type onLeaveCallback = () => void; 344 | let onLeaveCallbacks:onLeaveCallback[] = [] 345 | 346 | if (ts.isVariableStatement(node)) { 347 | let exportModifier = node.modifiers ? node.modifiers.find(x => x.kind == ts.SyntaxKind.ExportKeyword): null; 348 | if (exportModifier) { 349 | handleExportedVariableDeclarationList(node.declarationList); 350 | removeExport(exportModifier.getStart(), exportModifier.end); 351 | } 352 | } 353 | 354 | if (ts.isFunctionDeclaration(node)) { 355 | if (node.modifiers) { 356 | let exportModifier = node.modifiers.find(x => x.kind == ts.SyntaxKind.ExportKeyword) 357 | if (exportModifier) { 358 | addExport(node.name) 359 | removeExport(exportModifier.getStart(), exportModifier.end); 360 | } 361 | } 362 | 363 | pushScope(); 364 | onLeaveCallbacks.push(() => popScope()); 365 | } 366 | 367 | if (ts.isBlock(node)) { 368 | pushScope(); 369 | onLeaveCallbacks.push(() => popScope()); 370 | } 371 | 372 | if (ts.isArrowFunction(node)) { 373 | pushScope(); 374 | onLeaveCallbacks.push(() => popScope()); 375 | } 376 | 377 | 378 | if (ts.isExportDeclaration(node)) { 379 | for (let ne of node.exportClause.elements) { 380 | if (ne.propertyName) { 381 | addExport(ne.propertyName, ne.name) 382 | } else { 383 | addExport(ne.name) 384 | } 385 | } 386 | //we can remove entire statement 387 | removeExport(node.getStart(), node.end); 388 | } 389 | 390 | //move imports to top of script so they appear outside our render function 391 | if (ts.isImportDeclaration(node)) { 392 | str.move(node.getStart()+astOffset, node.end+astOffset, script.start+1); 393 | //add in a \n 394 | const originalEndChar = str.original[node.end+astOffset-1]; 395 | str.overwrite(node.end+astOffset-1, node.end+astOffset, originalEndChar+"\n"); 396 | } 397 | 398 | if (ts.isVariableDeclaration(parent) && parent.name == node) { 399 | isDeclaration = true; 400 | onLeaveCallbacks.push(() => isDeclaration = false); 401 | } 402 | 403 | if (ts.isBindingElement(parent) && parent.name == node) { 404 | isDeclaration = true; 405 | onLeaveCallbacks.push(() => isDeclaration = false); 406 | } 407 | 408 | if (ts.isImportClause(node)) { 409 | isDeclaration = true; 410 | onLeaveCallbacks.push(() => isDeclaration = false); 411 | } 412 | 413 | //handle stores etc 414 | if (ts.isIdentifier(node)) handleIdentifier(node, parent); 415 | 416 | 417 | //track implicit declarations in reactive blocks at the top level 418 | if (ts.isLabeledStatement(node) 419 | && parent == tsAst //top level 420 | && node.label.text == "$" 421 | && node.statement 422 | && ts.isExpressionStatement(node.statement) 423 | && ts.isBinaryExpression(node.statement.expression) 424 | && node.statement.expression.operatorToken.kind == ts.SyntaxKind.EqualsToken 425 | && ts.isIdentifier(node.statement.expression.left)) { 426 | 427 | implicitTopLevelNames.set(node.statement.expression.left.text, node.label.getStart() ); 428 | } 429 | 430 | //to save a bunch of condition checks on each node, we recurse into processChild which skips all the checks for top level items 431 | ts.forEachChild(node, n => walk(n, node)) 432 | //fire off the on leave callbacks 433 | onLeaveCallbacks.map(c => c()) 434 | } 435 | 436 | //walk the ast and convert to tsx as we go 437 | tsAst.forEachChild(n => walk(n, tsAst)); 438 | 439 | //resolve stores 440 | pendingStoreResolutions.map(resolveStore) 441 | 442 | // declare implicit reactive variables we found in the script 443 | for ( var [name, pos] of implicitTopLevelNames.entries()) { 444 | if (!rootScope.declared.has(name)) { 445 | //add a declaration 446 | str.prependRight(pos + astOffset, `;let ${name}; `) 447 | } 448 | } 449 | 450 | return { 451 | exportedNames, 452 | uses$$props 453 | } 454 | } 455 | 456 | 457 | function addComponentExport(str: MagicString, uses$$props: boolean) { 458 | str.append(`\n\nexport default class {\n $$prop_def = __sveltets_partial${ uses$$props ? "_with_any" : "" }(render().props)\n $$slot_def = render().slots\n}`); 459 | } 460 | 461 | function processModuleScriptTag(str: MagicString, script: Node) { 462 | let htmlx = str.original; 463 | 464 | let scriptStartTagEnd = htmlx.indexOf(">", script.start)+1; 465 | let scriptEndTagStart = htmlx.lastIndexOf("<", script.end-1); 466 | 467 | str.overwrite(script.start, scriptStartTagEnd, ";"); 468 | str.overwrite(scriptEndTagStart, script.end, ";<>"); 469 | } 470 | 471 | 472 | 473 | function createRenderFunction(str: MagicString, scriptTag: Node, scriptDestination: number, slots: Map>, exportedNames: Map, uses$$props: boolean) { 474 | let htmlx = str.original; 475 | let propsDecl = uses$$props ? " let $$props: SvelteAllProps;" : "" 476 | 477 | if (scriptTag) { 478 | //I couldn't get magicstring to let me put the script before the <> we prepend during conversion of the template to jsx, so we just close it instead 479 | let scriptTagEnd = htmlx.lastIndexOf(">", scriptTag.content.start) + 1; 480 | str.overwrite(scriptTag.start, scriptTag.start+ 1, ";"); 481 | str.overwrite(scriptTag.start+1, scriptTagEnd, `function render() {${propsDecl}\n`); 482 | 483 | let scriptEndTagStart = htmlx.lastIndexOf("<", scriptTag.end-1); 484 | str.overwrite(scriptEndTagStart, scriptTag.end, ";\n<>"); 485 | } else { 486 | str.prependRight(scriptDestination, `;function render() {${propsDecl}\n<>`); 487 | } 488 | 489 | let returnElements = [...exportedNames.entries()].map(([key, value]) => value ? `${value}: ${key}` : key); 490 | let slotsAsDef = "{" + [...slots.entries()].map(([name, attrs]) => { 491 | let attrsAsString = [...attrs.entries()].map(([exportName, expr]) => `${exportName}:${expr}`).join(", "); 492 | return `${name}: {${attrsAsString}}` 493 | }).join(", ") + "}" 494 | 495 | 496 | let returnString = "\nreturn { props: {" + returnElements.join(" , ") + "}, slots: " + slotsAsDef + " }}" 497 | str.append(returnString) 498 | } 499 | 500 | 501 | export function svelte2tsx(svelte: string, filename?: string) { 502 | 503 | let str = new MagicString(svelte); 504 | // process the htmlx as a svelte template 505 | let { moduleScriptTag, scriptTag, slots, uses$$props } = processSvelteTemplate(str); 506 | 507 | /* Rearrange the script tags so that module is first, and instance second followed finally by the template 508 | * This is a bit convoluted due to some trouble I had with magic string. A simple str.move(start,end,0) for each script wasn't enough 509 | * since if the module script was already at 0, it wouldn't move (which is fine) but would mean the order would be swapped when the script tag tried to move to 0 510 | * In this case we instead have to move it to moduleScriptTag.end. We track the location for the script move in the MoveInstanceScriptTarget var 511 | */ 512 | let instanceScriptTarget = 0; 513 | 514 | if (moduleScriptTag) { 515 | if (moduleScriptTag.start != 0) { 516 | //move our module tag to the top 517 | str.move(moduleScriptTag.start, moduleScriptTag.end, 0); 518 | } else { 519 | //since our module script was already at position 0, we need to move our instance script tag to the end of it. 520 | instanceScriptTarget = moduleScriptTag.end; 521 | } 522 | } 523 | 524 | //move the instance script and process the content 525 | let exportedNames = new Map(); 526 | if (scriptTag) { 527 | //ensure it is between the module script and the rest of the template (the variables need to be declared before the jsx template) 528 | if (scriptTag.start != instanceScriptTarget) { 529 | str.move(scriptTag.start, scriptTag.end, instanceScriptTarget); 530 | } 531 | let res = processInstanceScriptContent(str, scriptTag); 532 | exportedNames = res.exportedNames; 533 | uses$$props = uses$$props || res.uses$$props; 534 | } 535 | 536 | //wrap the script tag and template content in a function returning the slot and exports 537 | createRenderFunction(str, scriptTag, instanceScriptTarget, slots, exportedNames, uses$$props); 538 | 539 | // we need to process the module script after the instance script has moved otherwise we get warnings about moving edited items 540 | if (moduleScriptTag) { 541 | processModuleScriptTag(str, moduleScriptTag); 542 | } 543 | 544 | addComponentExport(str, uses$$props); 545 | 546 | return { 547 | code: str.toString(), 548 | map: str.generateMap({ hires: true, source: filename }) 549 | } 550 | } 551 | -------------------------------------------------------------------------------- /src/svgattributes.ts: -------------------------------------------------------------------------------- 1 | export default 'accent-height accumulate additive alignment-baseline allowReorder alphabetic amplitude arabic-form ascent attributeName attributeType autoReverse azimuth baseFrequency baseline-shift baseProfile bbox begin bias by calcMode cap-height class clip clipPathUnits clip-path clip-rule color color-interpolation color-interpolation-filters color-profile color-rendering contentScriptType contentStyleType cursor cx cy d decelerate descent diffuseConstant direction display divisor dominant-baseline dur dx dy edgeMode elevation enable-background end exponent externalResourcesRequired fill fill-opacity fill-rule filter filterRes filterUnits flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight format from fr fx fy g1 g2 glyph-name glyph-orientation-horizontal glyph-orientation-vertical glyphRef gradientTransform gradientUnits hanging height href horiz-adv-x horiz-origin-x id ideographic image-rendering in in2 intercept k k1 k2 k3 k4 kernelMatrix kernelUnitLength kerning keyPoints keySplines keyTimes lang lengthAdjust letter-spacing lighting-color limitingConeAngle local marker-end marker-mid marker-start markerHeight markerUnits markerWidth mask maskContentUnits maskUnits mathematical max media method min mode name numOctaves offset onabort onactivate onbegin onclick onend onerror onfocusin onfocusout onload onmousedown onmousemove onmouseout onmouseover onmouseup onrepeat onresize onscroll onunload opacity operator order orient orientation origin overflow overline-position overline-thickness panose-1 paint-order pathLength patternContentUnits patternTransform patternUnits pointer-events points pointsAtX pointsAtY pointsAtZ preserveAlpha preserveAspectRatio primitiveUnits r radius refX refY rendering-intent repeatCount repeatDur requiredExtensions requiredFeatures restart result rotate rx ry scale seed shape-rendering slope spacing specularConstant specularExponent speed spreadMethod startOffset stdDeviation stemh stemv stitchTiles stop-color stop-opacity strikethrough-position strikethrough-thickness string stroke stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width style surfaceScale systemLanguage tabindex tableValues target targetX targetY text-anchor text-decoration text-rendering textLength to transform type u1 u2 underline-position underline-thickness unicode unicode-bidi unicode-range units-per-em v-alphabetic v-hanging v-ideographic v-mathematical values version vert-adv-y vert-origin-x vert-origin-y viewBox viewTarget visibility width widths word-spacing writing-mode x x-height x1 x2 xChannelSelector xlink:actuate xlink:arcrole xlink:href xlink:role xlink:show xlink:title xlink:type xml:base xml:lang xml:space y y1 y2 yChannelSelector z zoomAndPan'.split(' '); 2 | -------------------------------------------------------------------------------- /svelte-shims.d.ts: -------------------------------------------------------------------------------- 1 | declare module '*.svelte' { 2 | export default class { 3 | $$prop_def: any; 4 | $$slot_def: any; 5 | } 6 | } 7 | 8 | type AConstructorTypeOf = new (...args:any[]) => T; 9 | 10 | type SvelteAction = (node: HTMLElement, ...args:U) => { 11 | update?: (...args:U) => void, 12 | destroy?: () => void 13 | } 14 | 15 | 16 | type SvelteTransitionConfig = { 17 | delay?: number, 18 | duration?: number, 19 | easing?: (t: number) => number, 20 | css?: (t: number, u: number) => string, 21 | tick?: (t: number, u: number) => void 22 | } 23 | 24 | type SvelteTransition = (node: Element, ...args:U) => SvelteTransitionConfig | (() => SvelteTransitionConfig) 25 | 26 | type SvelteAnimation = (node: Element, move: { from: DOMRect, to: DOMRect}, ...args:U) => { 27 | delay?: number, 28 | duration?: number, 29 | easing?: (t: number) => number, 30 | css?: (t: number, u: number) => string, 31 | tick?: (t: number, u: number) => void 32 | } 33 | 34 | type SvelteAllProps = { [index: string]: any } 35 | type SvelteStore = { subscribe: (run: (value:T) => any, invalidate?: any) => any } 36 | 37 | declare var process: NodeJS.Process & { browser: boolean } 38 | 39 | declare function __sveltets_ensureAnimation(animation: SvelteAnimation, ...args: U): any; 40 | declare function __sveltets_ensureAction(action: SvelteAction, ...args: U): any; 41 | declare function __sveltets_ensureTransition(transition: SvelteTransition, ...args: U): any; 42 | declare function __sveltets_ensureFunction(expression: (e: Event) => unknown ):any; 43 | declare function __sveltets_ensureType(type: AConstructorTypeOf, el: T): any; 44 | declare function __sveltets_instanceOf(type: AConstructorTypeOf): T; 45 | declare function __sveltets_partial(obj: T): Partial; 46 | declare function __sveltets_partial_with_any(obj: T): Partial & SvelteAllProps 47 | declare function __sveltets_store_get(store: SvelteStore): T 48 | declare function __sveltets_any(dummy: any): any; -------------------------------------------------------------------------------- /test/helpers.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halfnelson/svelte2tsx/ff40785f6f20cc0339e2be9ea3d48f4f24d85768/test/helpers.js -------------------------------------------------------------------------------- /test/htmlx2jsx/index.js: -------------------------------------------------------------------------------- 1 | let converter = require('../build/htmlxtojsx') 2 | let fs = require('fs') 3 | let assert = require('assert') 4 | 5 | describe('htmlx2jsx', () => { 6 | fs.readdirSync(`${__dirname}/samples`).forEach(dir => { 7 | if (dir[0] === '.') return; 8 | 9 | // add .solo to a sample directory name to only run that test 10 | const solo = /\.solo$/.test(dir); 11 | 12 | if (solo && process.env.CI) { 13 | throw new Error( 14 | `Forgot to remove '.solo' from test parser/samples/${dir}` 15 | ); 16 | } 17 | 18 | (solo ? it.only : it)(dir, () => { 19 | const input = fs.readFileSync(`${__dirname}/samples/${dir}/input.svelte`, 'utf-8').replace(/\s+$/, '').replace(/\r\n/g, "\n"); 20 | const expectedOutput = fs.readFileSync(`${__dirname}/samples/${dir}/expected.jsx`, 'utf-8').replace(/\s+$/, '').replace(/\r\n/g, "\n"); 21 | 22 | const { map, code} = converter.htmlx2jsx(input); 23 | assert.equal(code, expectedOutput); 24 | }); 25 | }); 26 | }); -------------------------------------------------------------------------------- /test/htmlx2jsx/samples/action-bare/expected.jsx: -------------------------------------------------------------------------------- 1 | <>

Hello

2 | -------------------------------------------------------------------------------- /test/htmlx2jsx/samples/action-bare/input.svelte: -------------------------------------------------------------------------------- 1 |

Hello

-------------------------------------------------------------------------------- /test/htmlx2jsx/samples/action-params/expected.jsx: -------------------------------------------------------------------------------- 1 | <>

Hello

2 | -------------------------------------------------------------------------------- /test/htmlx2jsx/samples/action-params/input.svelte: -------------------------------------------------------------------------------- 1 |

Hello

-------------------------------------------------------------------------------- /test/htmlx2jsx/samples/animation-bare/expected.jsx: -------------------------------------------------------------------------------- 1 | <>

Hello

2 | -------------------------------------------------------------------------------- /test/htmlx2jsx/samples/animation-bare/input.svelte: -------------------------------------------------------------------------------- 1 |

Hello

-------------------------------------------------------------------------------- /test/htmlx2jsx/samples/animation-params/expected.jsx: -------------------------------------------------------------------------------- 1 | <>

Hello

2 | 3 | -------------------------------------------------------------------------------- /test/htmlx2jsx/samples/animation-params/input.svelte: -------------------------------------------------------------------------------- 1 |

Hello

-------------------------------------------------------------------------------- /test/htmlx2jsx/samples/attribute-bare/expected.jsx: -------------------------------------------------------------------------------- 1 | <> 2 | -------------------------------------------------------------------------------- /test/htmlx2jsx/samples/attribute-bare/input.svelte: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/htmlx2jsx/samples/attribute-multiple/expected.jsx: -------------------------------------------------------------------------------- 1 | <> 2 | -------------------------------------------------------------------------------- /test/htmlx2jsx/samples/attribute-multiple/input.svelte: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/htmlx2jsx/samples/attribute-quoted/expected.jsx: -------------------------------------------------------------------------------- 1 | <> 2 | -------------------------------------------------------------------------------- /test/htmlx2jsx/samples/attribute-quoted/input.svelte: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/htmlx2jsx/samples/attribute-shorthand/expected.jsx: -------------------------------------------------------------------------------- 1 | <> 2 | -------------------------------------------------------------------------------- /test/htmlx2jsx/samples/attribute-shorthand/input.svelte: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/htmlx2jsx/samples/attribute-text/expected.jsx: -------------------------------------------------------------------------------- 1 | <> 2 | -------------------------------------------------------------------------------- /test/htmlx2jsx/samples/attribute-text/input.svelte: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/htmlx2jsx/samples/auto-closing-tag/expected.jsx: -------------------------------------------------------------------------------- 1 | <>
2 |

test1 3 |

test2 4 |

-------------------------------------------------------------------------------- /test/htmlx2jsx/samples/auto-closing-tag/input.svelte: -------------------------------------------------------------------------------- 1 |
2 |

test1 3 |

test2 4 |

5 | -------------------------------------------------------------------------------- /test/htmlx2jsx/samples/await-block-basic-catch/expected.jsx: -------------------------------------------------------------------------------- 1 | <>{() => {let _$$p = (somePromise); _$$p.then((value) => {<> 2 |

Promise Resolved

3 | }).catch(() => {<> 4 |

Promise Errored

5 | })}} 6 | -------------------------------------------------------------------------------- /test/htmlx2jsx/samples/await-block-basic-catch/input.svelte: -------------------------------------------------------------------------------- 1 | {#await somePromise then value} 2 |

Promise Resolved

3 | {:catch} 4 |

Promise Errored

5 | {/await} -------------------------------------------------------------------------------- /test/htmlx2jsx/samples/await-block-basic/expected.jsx: -------------------------------------------------------------------------------- 1 | <>{() => {let _$$p = (somePromise); _$$p.then((value) => {<> 2 |

Promise Resolved

3 | })}} 4 | -------------------------------------------------------------------------------- /test/htmlx2jsx/samples/await-block-basic/input.svelte: -------------------------------------------------------------------------------- 1 | {#await somePromise then value} 2 |

Promise Resolved

3 | {/await} -------------------------------------------------------------------------------- /test/htmlx2jsx/samples/await-block-pending-catch/expected.jsx: -------------------------------------------------------------------------------- 1 | <>{() => {let _$$p = (somePromise); <> 2 |

Promise Pending

3 | ; _$$p.then((value) => {<> 4 |

Promise Resolved {value}

5 | }).catch((error) => {<> 6 |

Promise Errored {error}

7 | })}} 8 | -------------------------------------------------------------------------------- /test/htmlx2jsx/samples/await-block-pending-catch/input.svelte: -------------------------------------------------------------------------------- 1 | {#await somePromise} 2 |

Promise Pending

3 | {:then value} 4 |

Promise Resolved {value}

5 | {:catch error} 6 |

Promise Errored {error}

7 | {/await} -------------------------------------------------------------------------------- /test/htmlx2jsx/samples/await-block-pending/expected.jsx: -------------------------------------------------------------------------------- 1 | <>{() => {let _$$p = (somePromise); <> 2 |

Promise Pending

3 | ; _$$p.then((value) => {<> 4 |

Promise Resolved {value}

5 | })}} 6 | -------------------------------------------------------------------------------- /test/htmlx2jsx/samples/await-block-pending/input.svelte: -------------------------------------------------------------------------------- 1 | {#await somePromise} 2 |

Promise Pending

3 | {:then value} 4 |

Promise Resolved {value}

5 | {/await} -------------------------------------------------------------------------------- /test/htmlx2jsx/samples/binding-bare/expected.jsx: -------------------------------------------------------------------------------- 1 | <> 2 | 3 | -------------------------------------------------------------------------------- /test/htmlx2jsx/samples/binding-bare/input.svelte: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /test/htmlx2jsx/samples/binding-group/expected.jsx: -------------------------------------------------------------------------------- 1 | <> 2 | -------------------------------------------------------------------------------- /test/htmlx2jsx/samples/binding-group/input.svelte: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/htmlx2jsx/samples/binding-oneway/expected.jsx: -------------------------------------------------------------------------------- 1 | <>
7 | 8 | -------------------------------------------------------------------------------- /test/htmlx2jsx/samples/binding-oneway/input.svelte: -------------------------------------------------------------------------------- 1 |
7 | 8 | 17 | 18 | -------------------------------------------------------------------------------- /test/htmlx2jsx/samples/binding-this-component/expected.jsx: -------------------------------------------------------------------------------- 1 | <> 2 | -------------------------------------------------------------------------------- /test/htmlx2jsx/samples/binding-this-component/input.svelte: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/htmlx2jsx/samples/binding-this/expected.jsx: -------------------------------------------------------------------------------- 1 | <> 2 | -------------------------------------------------------------------------------- /test/htmlx2jsx/samples/binding-this/input.svelte: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/htmlx2jsx/samples/binding/expected.jsx: -------------------------------------------------------------------------------- 1 | <> 2 | -------------------------------------------------------------------------------- /test/htmlx2jsx/samples/binding/input.svelte: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/htmlx2jsx/samples/class-bare/expected.jsx: -------------------------------------------------------------------------------- 1 | <>

Hello

2 | -------------------------------------------------------------------------------- /test/htmlx2jsx/samples/class-bare/input.svelte: -------------------------------------------------------------------------------- 1 |

Hello

-------------------------------------------------------------------------------- /test/htmlx2jsx/samples/class/expected.jsx: -------------------------------------------------------------------------------- 1 | <>

Hello

2 | -------------------------------------------------------------------------------- /test/htmlx2jsx/samples/class/input.svelte: -------------------------------------------------------------------------------- 1 |

Hello

-------------------------------------------------------------------------------- /test/htmlx2jsx/samples/comment/expected.jsx: -------------------------------------------------------------------------------- 1 | <>

Hello

2 | 3 | -------------------------------------------------------------------------------- /test/htmlx2jsx/samples/comment/input.svelte: -------------------------------------------------------------------------------- 1 |

Hello

2 | -------------------------------------------------------------------------------- /test/htmlx2jsx/samples/component-default-slot-let/expected.jsx: -------------------------------------------------------------------------------- 1 | <>{() => { let {name:n, thing} = __sveltets_instanceOf(Component).$$slot_def.default;<> 2 |

Hello {thing} {n}

3 | }}
-------------------------------------------------------------------------------- /test/htmlx2jsx/samples/component-default-slot-let/input.svelte: -------------------------------------------------------------------------------- 1 | 2 |

Hello {thing} {n}

3 |
4 | -------------------------------------------------------------------------------- /test/htmlx2jsx/samples/component-default-slot/expected.jsx: -------------------------------------------------------------------------------- 1 | <> 2 |

Hello

3 |
-------------------------------------------------------------------------------- /test/htmlx2jsx/samples/component-default-slot/input.svelte: -------------------------------------------------------------------------------- 1 | 2 |

Hello

3 |
4 | -------------------------------------------------------------------------------- /test/htmlx2jsx/samples/component-multi-slot/expected.jsx: -------------------------------------------------------------------------------- 1 | <>{() => { let {var:new_var} = __sveltets_instanceOf(Component).$$slot_def.default;<> 2 |

Hello

3 |
{() => { let {slotvar:newvar} = __sveltets_instanceOf(Component).$$slot_def.someslot;<> 4 |

Hi Slot

5 | }}
6 |

7 | Test 8 |

9 | }}
-------------------------------------------------------------------------------- /test/htmlx2jsx/samples/component-multi-slot/input.svelte: -------------------------------------------------------------------------------- 1 | 2 |

Hello

3 |
4 |

Hi Slot

5 |
6 |

7 | Test 8 |

9 |
10 | -------------------------------------------------------------------------------- /test/htmlx2jsx/samples/component-no-slots/expected.jsx: -------------------------------------------------------------------------------- 1 | <> 2 | -------------------------------------------------------------------------------- /test/htmlx2jsx/samples/component-no-slots/input.svelte: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /test/htmlx2jsx/samples/debug-block/expected.jsx: -------------------------------------------------------------------------------- 1 | <>{ myfile, someOtherFile } -------------------------------------------------------------------------------- /test/htmlx2jsx/samples/debug-block/input.svelte: -------------------------------------------------------------------------------- 1 | {@debug myfile, someOtherFile } -------------------------------------------------------------------------------- /test/htmlx2jsx/samples/directive-quoted/expected.jsx: -------------------------------------------------------------------------------- 1 | <>

console.log("click")}>Hello

2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /test/htmlx2jsx/samples/directive-quoted/input.svelte: -------------------------------------------------------------------------------- 1 |

Hello

2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /test/htmlx2jsx/samples/each-block-basic/expected.jsx: -------------------------------------------------------------------------------- 1 | <>{(items).map((item) => <> 2 |
{item}
3 | )} -------------------------------------------------------------------------------- /test/htmlx2jsx/samples/each-block-basic/input.svelte: -------------------------------------------------------------------------------- 1 | {#each items as item} 2 |
{item}
3 | {/each} -------------------------------------------------------------------------------- /test/htmlx2jsx/samples/each-block-index/expected.jsx: -------------------------------------------------------------------------------- 1 | <>{(items).map((item,i) => <> 2 |
{item}{i}
3 | )} -------------------------------------------------------------------------------- /test/htmlx2jsx/samples/each-block-index/input.svelte: -------------------------------------------------------------------------------- 1 | {#each items as item,i} 2 |
{item}{i}
3 | {/each} -------------------------------------------------------------------------------- /test/htmlx2jsx/samples/each-block-key-else/expected.jsx: -------------------------------------------------------------------------------- 1 | <>{(items).map((item,i) => (item.id) && <> 2 |
{item}{i}
3 | )} 4 |
No Items
5 | -------------------------------------------------------------------------------- /test/htmlx2jsx/samples/each-block-key-else/input.svelte: -------------------------------------------------------------------------------- 1 | {#each items as item,i (item.id)} 2 |
{item}{i}
3 | {:else} 4 |
No Items
5 | {/each} -------------------------------------------------------------------------------- /test/htmlx2jsx/samples/each-block-key/expected.jsx: -------------------------------------------------------------------------------- 1 | <>{(items).map((item,i) => (item.id) && <> 2 |
{item}{i}
3 | )} -------------------------------------------------------------------------------- /test/htmlx2jsx/samples/each-block-key/input.svelte: -------------------------------------------------------------------------------- 1 | {#each items as item,i (item.id)} 2 |
{item}{i}
3 | {/each} -------------------------------------------------------------------------------- /test/htmlx2jsx/samples/element-only/expected.jsx: -------------------------------------------------------------------------------- 1 | <>

Hello

2 | -------------------------------------------------------------------------------- /test/htmlx2jsx/samples/element-only/input.svelte: -------------------------------------------------------------------------------- 1 |

Hello

-------------------------------------------------------------------------------- /test/htmlx2jsx/samples/event-handler-bare/expected.jsx: -------------------------------------------------------------------------------- 1 | <>

Hello

2 | -------------------------------------------------------------------------------- /test/htmlx2jsx/samples/event-handler-bare/input.svelte: -------------------------------------------------------------------------------- 1 |

Hello

-------------------------------------------------------------------------------- /test/htmlx2jsx/samples/event-handler-component-bare/expected.jsx: -------------------------------------------------------------------------------- 1 | <> 2 | -------------------------------------------------------------------------------- /test/htmlx2jsx/samples/event-handler-component-bare/input.svelte: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/htmlx2jsx/samples/event-handler-component/expected.jsx: -------------------------------------------------------------------------------- 1 | <> click()))} {...__sveltets_ensureFunction((() => log('hi')))}/> 2 | -------------------------------------------------------------------------------- /test/htmlx2jsx/samples/event-handler-component/input.svelte: -------------------------------------------------------------------------------- 1 | click()} on:UpperCaseEvent={() => log('hi')}/> -------------------------------------------------------------------------------- /test/htmlx2jsx/samples/event-handler-modifiers/expected.jsx: -------------------------------------------------------------------------------- 1 | <>

Hello

2 | -------------------------------------------------------------------------------- /test/htmlx2jsx/samples/event-handler-modifiers/input.svelte: -------------------------------------------------------------------------------- 1 |

Hello

-------------------------------------------------------------------------------- /test/htmlx2jsx/samples/event-handler/expected.jsx: -------------------------------------------------------------------------------- 1 | <>

console.log("click")} onUpperCaseEvent={() => log('hi')}>Hello

2 | -------------------------------------------------------------------------------- /test/htmlx2jsx/samples/event-handler/input.svelte: -------------------------------------------------------------------------------- 1 |

console.log("click")} on:UpperCaseEvent={() => log('hi')}>Hello

-------------------------------------------------------------------------------- /test/htmlx2jsx/samples/html-block/expected.jsx: -------------------------------------------------------------------------------- 1 | <>{ myfile + someOtherFile } -------------------------------------------------------------------------------- /test/htmlx2jsx/samples/html-block/input.svelte: -------------------------------------------------------------------------------- 1 | {@html myfile + someOtherFile } -------------------------------------------------------------------------------- /test/htmlx2jsx/samples/if-block/expected.jsx: -------------------------------------------------------------------------------- 1 | <>{() => {if (name == "world"){<> 2 |

Hello {name}

3 | }}} -------------------------------------------------------------------------------- /test/htmlx2jsx/samples/if-block/input.svelte: -------------------------------------------------------------------------------- 1 | {#if name == "world"} 2 |

Hello {name}

3 | {/if} -------------------------------------------------------------------------------- /test/htmlx2jsx/samples/if-else-block/expected.jsx: -------------------------------------------------------------------------------- 1 | <>{() => {if (name == "world"){<> 2 |

Hello {name}

3 | }else{<> 4 |

hello {name}

5 | }}} -------------------------------------------------------------------------------- /test/htmlx2jsx/samples/if-else-block/input.svelte: -------------------------------------------------------------------------------- 1 | {#if name == "world"} 2 |

Hello {name}

3 | {:else} 4 |

hello {name}

5 | {/if} -------------------------------------------------------------------------------- /test/htmlx2jsx/samples/if-else-if-block/expected.jsx: -------------------------------------------------------------------------------- 1 | <>{() => {if (name1 == "world"){<> 2 |

Hello {name2}

3 | }else if (name3 == "person"){<> 4 |

hello {name4}

5 | }}} -------------------------------------------------------------------------------- /test/htmlx2jsx/samples/if-else-if-block/input.svelte: -------------------------------------------------------------------------------- 1 | {#if name1 == "world"} 2 |

Hello {name2}

3 | {:else if name3 == "person"} 4 |

hello {name4}

5 | {/if} -------------------------------------------------------------------------------- /test/htmlx2jsx/samples/namespaced-attributes/expected.jsx: -------------------------------------------------------------------------------- 1 | <> -------------------------------------------------------------------------------- /test/htmlx2jsx/samples/namespaced-attributes/input.svelte: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/htmlx2jsx/samples/simple-expression/expected.jsx: -------------------------------------------------------------------------------- 1 | <>

Hello {name}

-------------------------------------------------------------------------------- /test/htmlx2jsx/samples/simple-expression/input.svelte: -------------------------------------------------------------------------------- 1 |

Hello {name}

-------------------------------------------------------------------------------- /test/htmlx2jsx/samples/svg-attributes/expected.jsx: -------------------------------------------------------------------------------- 1 | <> -------------------------------------------------------------------------------- /test/htmlx2jsx/samples/svg-attributes/input.svelte: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/htmlx2jsx/samples/transition-bare/expected.jsx: -------------------------------------------------------------------------------- 1 | <>

Hello

2 |

Hello

3 |

Hello

4 | -------------------------------------------------------------------------------- /test/htmlx2jsx/samples/transition-bare/input.svelte: -------------------------------------------------------------------------------- 1 |

Hello

2 |

Hello

3 |

Hello

-------------------------------------------------------------------------------- /test/htmlx2jsx/samples/transition-modifiers/expected.jsx: -------------------------------------------------------------------------------- 1 | <>
2 | {item} 3 |
-------------------------------------------------------------------------------- /test/htmlx2jsx/samples/transition-modifiers/input.svelte: -------------------------------------------------------------------------------- 1 |
2 | {item} 3 |
-------------------------------------------------------------------------------- /test/htmlx2jsx/samples/transition-params/expected.jsx: -------------------------------------------------------------------------------- 1 | <>

Hello

2 |

Hello

3 |

Hello

4 | -------------------------------------------------------------------------------- /test/htmlx2jsx/samples/transition-params/input.svelte: -------------------------------------------------------------------------------- 1 |

Hello

2 |

Hello

3 |

Hello

-------------------------------------------------------------------------------- /test/htmlx2jsx/samples/void-elements/expected.jsx: -------------------------------------------------------------------------------- 1 | <> 2 | 3 |
4 | 5 | 6 |
7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /test/htmlx2jsx/samples/void-elements/input.svelte: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 | 6 |
7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /test/sourcemaps/event-binding.html: -------------------------------------------------------------------------------- 1 | <>;function render() { 2 | <> 3 | 1==== 2================== 4 | 5 | 3==== 4================== 6 | return { props: {}, slots: {} }} 7 | 8 | export default class { 9 | $$prop_def = __sveltets_partial(render().props) 10 | $$slot_def = render().slots 11 | } 12 | !Expected 13 | 14 | 1==== 2================== 15 | 16 | 3==== 4================== -------------------------------------------------------------------------------- /test/sourcemaps/index.js: -------------------------------------------------------------------------------- 1 | let svelte2tsx = require('../build/index') 2 | let converter = require('../build/htmlxtojsx') 3 | let fs = require('fs') 4 | let assert = require('assert') 5 | let sm = require('source-map') 6 | 7 | 8 | 9 | describe('sourcemap', () => { 10 | /** 11 | * 12 | * @param {string} input 13 | * 14 | * @returns { {source: string, locations: Map } 15 | */ 16 | function extractLocations(input) { 17 | let lines = input.split("\n") 18 | let line 19 | let source_line = 0; 20 | let source = [] 21 | let locations = new Map() 22 | while (lines.length) { 23 | line = lines.shift() 24 | //are we a range line, we test to see if it starts with whitespace followed by a digit 25 | if (/^\s*[\d=]+[\s\d=]*$/.test(line)) { 26 | //create the ranges 27 | let currentId = null 28 | let offset = 0 29 | let offsets = [] 30 | let start = 0 31 | const endSpan = () => { 32 | if (offsets.length) { 33 | locations.set(currentId, { line: source_line, start: start, offsets:offsets }); 34 | } 35 | offset = 0 36 | offsets = [] 37 | } 38 | 39 | for (let char = 0; char < line.length; char++) { 40 | let c = line[char] 41 | let isDigit = /\d/.test(c), isEquals = /=/.test(c) 42 | if (isDigit) { 43 | endSpan() 44 | currentId = c 45 | start = char + 1; 46 | } 47 | if (isEquals || isDigit) { 48 | offsets.push(offset) 49 | offset++; 50 | } else { 51 | endSpan() 52 | } 53 | } 54 | endSpan(); 55 | } else { 56 | //we are a source line 57 | source.push(line) 58 | source_line++; 59 | } 60 | } 61 | 62 | return { source: source.join("\n") , locations } 63 | } 64 | 65 | 66 | fs.readdirSync(`${__dirname}`).forEach(dir => { 67 | if (dir[0] === '.') return; 68 | 69 | if (!dir.endsWith(".html") && !dir.endsWith(".html.solo")) return; 70 | 71 | // add .solo to a sample directory name to only run that test 72 | const solo = /\.solo$/.test(dir); 73 | 74 | if (solo && process.env.CI) { 75 | throw new Error( 76 | `Forgot to remove '.solo' from test parser/samples/${dir}` 77 | ); 78 | } 79 | 80 | let showWhitespace = (str) => { 81 | return str.replace(/\t/g, "\\t").replace(/\n/g,"\\n\n").replace(/\r/g, "\\r") 82 | } 83 | 84 | (solo ? it.only : it)(dir, () => { 85 | const testContent = fs.readFileSync(`${__dirname}/${dir}`, 'utf-8').replace(/\r\n/g, "\n").replace(/\t/g, " "); 86 | 87 | let [inputBlock, expectedBlock] = testContent.split(/\n!Expected.*?\n/) 88 | let input = extractLocations(inputBlock); 89 | let expected = extractLocations(expectedBlock); 90 | 91 | 92 | // seems backwards but we don't have an "input" source map, so we generate one from our expected output 93 | // but assert that the source it generates matches our input source. 94 | //console.log(expected.source) 95 | const { map, code } = dir.endsWith(".htmlx.html") ? converter.htmlx2jsx(expected.source) : svelte2tsx(expected.source); 96 | assert.equal(showWhitespace(code) , showWhitespace(input.source), "Couldn't generate input source map for test"); 97 | 98 | let decoder = new sm.SourceMapConsumer(map); 99 | 100 | for (let [id, span] of input.locations.entries()) { 101 | let expectedSpan = expected.locations.get(id); 102 | 103 | //walk our generated span checking it lines up 104 | let col = span.start 105 | let input_line = span.line 106 | let expected_line = expectedSpan.line 107 | 108 | 109 | assert.ok(input.source); 110 | let error_source = input.source.split("\n")[span.line-1]; 111 | assert.ok(error_source); 112 | let error_map = new Array(error_source.length).fill(" "); 113 | 114 | let actual_result_line, actual_result_source, actual_result 115 | let errorCount = 0; 116 | 117 | for (var off = 0; off < span.offsets.length; off++) { 118 | let input_col = col + off; 119 | let expected_col = expectedSpan.start + span.offsets[off]; 120 | 121 | //originalPositionFor uses 0 base cols and 1 base lines.... 122 | let { line: actual_line, column: decoded_col } = decoder.originalPositionFor({ line: input_line, column: input_col - 1 }) 123 | let actual_col = decoded_col + 1; 124 | 125 | if (!actual_result) { 126 | actual_result_source = expected.source.split("\n")[actual_line-1] 127 | actual_result = new Array(actual_result_source.length).fill(" "); 128 | actual_result_line = actual_line 129 | } 130 | if (actual_line == actual_result_line) { 131 | if (actual_result_line[actual_col - 1] == " ") { 132 | actual_result[actual_col - 1] = "1" 133 | } else { 134 | //track number of characters mapped to result 135 | actual_result[actual_col - 1] = `${Math.min((actual_result[actual_col - 1] << 0) + 1, 9)}` 136 | } 137 | } else { 138 | actual_result = actual_result + "X" 139 | } 140 | 141 | if (actual_col != expected_col || actual_line != expected_line) { 142 | errorCount++; 143 | error_map[input_col-1] = "X" 144 | } else { 145 | error_map[input_col-1] = "=" 146 | } 147 | } 148 | 149 | if (errorCount != 0) { 150 | assert.fail(` 151 | Errors on span ${id} 152 | 153 | Output 154 | ${actual_result_source} 155 | ${actual_result.join("").replace(/1/g,"=")} 156 | 157 | Errors 158 | ${error_source} 159 | ${error_map.join("")} 160 | `) 161 | } 162 | } 163 | }); 164 | }); 165 | }); -------------------------------------------------------------------------------- /test/sourcemaps/let.html: -------------------------------------------------------------------------------- 1 | <>;function render() { 2 | 3 | ;let selected; $: selected = lookup.get(slug); 4 | ; 5 | <> 6 | 7 | return { props: {}, slots: {} }} 8 | 9 | export default class { 10 | $$prop_def = __sveltets_partial(render().props) 11 | $$slot_def = render().slots 12 | } 13 | !Expected 14 | 17 | -------------------------------------------------------------------------------- /test/sourcemaps/repl.html: -------------------------------------------------------------------------------- 1 | <>; 2 | export async function preload({ params }) { 3 | const res = await this.fetch(`tutorial/${params.slug}.json`); 4 | 5 | if (!res.ok) { 6 | return this.redirect(301, `tutorial/basics`); 7 | } 8 | 9 | return { 10 | slug: params.slug, 11 | chapter: await res.json() 12 | }; 13 | } 14 | ;<>;import Repl from '@sveltejs/svelte-repl'; 15 | import { getContext } from 'svelte'; 16 | import ScreenToggle from '../../../components/ScreenToggle.svelte'; 17 | import TableOfContents from './_TableOfContents.svelte'; 18 | import { 19 | mapbox_setup, // needed for context API tutorial 20 | rollupUrl, 21 | svelteUrl 22 | } from '../../../config'; 23 | function render() { 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | let slug; 34 | let chapter; 35 | 36 | const { sections } = getContext('tutorial'); 37 | 38 | let repl; 39 | let prev; 40 | let scrollable; 41 | const lookup = new Map(); 42 | 43 | let width = process.browser ? window.innerWidth : 1000; 44 | let offset = 0; 45 | 46 | sections.forEach(section => { 47 | section.chapters.forEach(chapter => { 48 | const obj = { 49 | slug: chapter.slug, 50 | section, 51 | chapter, 52 | prev 53 | }; 54 | 55 | lookup.set(chapter.slug, obj); 56 | 57 | if (process.browser) { // pending https://github.com/sveltejs/svelte/issues/2135 58 | if (prev) prev.next = obj; 59 | prev = obj; 60 | } 61 | }); 62 | }); 63 | 64 | // TODO is there a non-hacky way to trigger scroll when chapter changes? 65 | $: if (scrollable) chapter, scrollable.scrollTo(0, 0); 66 | 67 | // TODO: this will need to be changed to the master branch, and probably should be dynamic instead of included 68 | // here statically 69 | const tutorial_repo_link = 'https://github.com/sveltejs/svelte/tree/master/site/content/tutorial'; 70 | 71 | ;let selected; $: selected = lookup.get(slug); 72 | ;let improve_link; $: improve_link = `${tutorial_repo_link}/${selected.chapter.section_dir}/${selected.chapter.chapter_dir}`; 73 | 74 | const clone = file => ({ 75 | name: file.name, 76 | type: file.type, 77 | source: file.source 78 | }); 79 | 80 | $: if (repl) { 81 | completed = false; 82 | repl.set({ 83 | components: chapter.app_a.map(clone) 84 | }); 85 | } 86 | 87 | ;let mobile; $: mobile = width < 768; 88 | 89 | function reset() { 90 | repl.update({ 91 | components: chapter.app_a.map(clone) 92 | }); 93 | } 94 | 95 | function complete() { 96 | repl.update({ 97 | components: chapter.app_b.map(clone) 98 | }); 99 | } 100 | 101 | let completed = false; 102 | 103 | function handle_change(event) { 104 | completed = event.detail.components.every((file, i) => { 105 | const expected = chapter.app_b[i]; 106 | return expected && ( 107 | file.name === expected.name && 108 | file.type === expected.type && 109 | file.source.trim().replace(/\s+$/gm, '') === expected.source.trim().replace(/\s+$/gm, '') 110 | ); 111 | }); 112 | } 113 | ; 114 | <> 115 | 116 | 117 | 118 | 119 | 120 | 121 | {selected.section.title} / {selected.chapter.title} • Svelte Tutorial 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 |
131 |
132 |
133 |
134 | 135 |
136 | 137 |
138 | { chapter.html} 139 | 140 |
141 | {() => {if (chapter.app_b){<> 142 | 143 | 146 | }}} 147 | 148 | {() => {if (selected.next){<> 149 | 150 | }}} 151 |
152 | 153 |
154 | Edit this chapter 155 |
156 |
157 |
158 | 159 |
160 | 171 |
172 |
173 | 174 | {() => {if (mobile){<> 175 | 176 | }}} 177 |
178 | return { props: {slug , chapter}, slots: {} }} 179 | 180 | export default class { 181 | $$prop_def = __sveltets_partial(render().props) 182 | $$slot_def = render().slots 183 | } 184 | !Expected 185 | 199 | 200 | 295 | 296 | 445 | 446 | 447 | {selected.section.title} / {selected.chapter.title} • Svelte Tutorial 448 | 449 | 450 | 451 | 452 | 453 | 454 | 455 | 456 |
457 |
458 |
459 |
460 | 461 |
462 | 463 |
464 | {@html chapter.html} 465 | 466 |
467 | {#if chapter.app_b} 468 | 470 | 473 | {/if} 474 | 475 | {#if selected.next} 476 | 477 | {/if} 478 |
479 | 480 |
481 | Edit this chapter 482 |
483 |
484 |
485 | 486 |
487 | 498 |
499 |
500 | 501 | {#if mobile} 502 | 503 | {/if} 504 |
-------------------------------------------------------------------------------- /test/sourcemaps/shorthand-prop.htmlx.html: -------------------------------------------------------------------------------- 1 | <> 2 | 2===== 1====== 3 | !Expected 4 | 5 | 2===== 1====== -------------------------------------------------------------------------------- /test/sourcemaps/simple-element.htmlx.html: -------------------------------------------------------------------------------- 1 | <>

Hello World

2 | 1=================== 3 | 4 | !Expected 5 |

Hello World

6 | 1=================== 7 | -------------------------------------------------------------------------------- /test/svelte2tsx/index.js: -------------------------------------------------------------------------------- 1 | let svelte2tsx = require('../build/index') 2 | let fs = require('fs') 3 | let assert = require('assert') 4 | 5 | describe('svelte2tsx', () => { 6 | fs.readdirSync(`${__dirname}/samples`).forEach(dir => { 7 | if (dir[0] === '.') return; 8 | 9 | // add .solo to a sample directory name to only run that test 10 | const solo = /\.solo$/.test(dir); 11 | 12 | if (solo && process.env.CI) { 13 | throw new Error( 14 | `Forgot to remove '.solo' from test parser/samples/${dir}` 15 | ); 16 | } 17 | 18 | (solo ? it.only : it)(dir, () => { 19 | const input = fs.readFileSync(`${__dirname}/samples/${dir}/input.svelte`, 'utf-8').replace(/\s+$/, '').replace(/\r\n/g, "\n"); 20 | const expectedOutput = fs.readFileSync(`${__dirname}/samples/${dir}/expected.tsx`, 'utf-8').replace(/\s+$/, '').replace(/\r\n/g, "\n"); 21 | 22 | const { map, code} = svelte2tsx(input); 23 | assert.equal(code, expectedOutput); 24 | }); 25 | }); 26 | }); -------------------------------------------------------------------------------- /test/svelte2tsx/samples/array-binding-export/expected.tsx: -------------------------------------------------------------------------------- 1 | <>;function render() { 2 | 3 | let [a,b,c] = [1,2,3]; 4 | ; 5 | <> 6 | return { props: {a , b , c}, slots: {} }} 7 | 8 | export default class { 9 | $$prop_def = __sveltets_partial(render().props) 10 | $$slot_def = render().slots 11 | } 12 | -------------------------------------------------------------------------------- /test/svelte2tsx/samples/array-binding-export/input.svelte: -------------------------------------------------------------------------------- 1 | 4 | -------------------------------------------------------------------------------- /test/svelte2tsx/samples/ast-offset-none/expected.tsx: -------------------------------------------------------------------------------- 1 | <>;function render() { 2 | __sveltets_store_get(var); 3 | <> 4 | return { props: {}, slots: {} }} 5 | 6 | export default class { 7 | $$prop_def = __sveltets_partial(render().props) 8 | $$slot_def = render().slots 9 | } -------------------------------------------------------------------------------- /test/svelte2tsx/samples/ast-offset-none/input.svelte: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/svelte2tsx/samples/ast-offset-some/expected.tsx: -------------------------------------------------------------------------------- 1 | <>;function render() { 2 | __sveltets_store_get(var); 3 | <> 4 | return { props: {}, slots: {} }} 5 | 6 | export default class { 7 | $$prop_def = __sveltets_partial(render().props) 8 | $$slot_def = render().slots 9 | } -------------------------------------------------------------------------------- /test/svelte2tsx/samples/ast-offset-some/input.svelte: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/svelte2tsx/samples/await-with-$store/expected.tsx: -------------------------------------------------------------------------------- 1 | <>;import { readable } from 'svelte/store'; 2 | function render() { 3 | 4 | 5 | const store = readable(Promise.resolve('test'), () => {}); 6 | ; 7 | <> 8 | 9 | {() => {let _$$p = (__sveltets_store_get(store)); <> 10 |

loading

11 | ; _$$p.then((data) => {<> 12 | {data} 13 | })}} 14 | return { props: {}, slots: {} }} 15 | 16 | export default class { 17 | $$prop_def = __sveltets_partial(render().props) 18 | $$slot_def = render().slots 19 | } -------------------------------------------------------------------------------- /test/svelte2tsx/samples/await-with-$store/input.svelte: -------------------------------------------------------------------------------- 1 | 5 | 6 | {#await $store} 7 |

loading

8 | {:then data} 9 | {data} 10 | {/await} -------------------------------------------------------------------------------- /test/svelte2tsx/samples/binding-group-store/expected.tsx: -------------------------------------------------------------------------------- 1 | <>;function render() { 2 | <> 3 | return { props: {}, slots: {} }} 4 | 5 | export default class { 6 | $$prop_def = __sveltets_partial(render().props) 7 | $$slot_def = render().slots 8 | } 9 | -------------------------------------------------------------------------------- /test/svelte2tsx/samples/binding-group-store/input.svelte: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/svelte2tsx/samples/circle-drawer-example/expected.tsx: -------------------------------------------------------------------------------- 1 | <>;function render() { 2 | 3 | let i = 0; 4 | let undoStack = [[]]; 5 | let circles = []; 6 | let selected; 7 | let adjusting = false; 8 | let adjusted = false; 9 | 10 | function handleClick(event) { 11 | if (adjusting) { 12 | adjusting = false; 13 | 14 | // if circle was adjusted, 15 | // push to the stack 16 | if (adjusted) push(); 17 | return; 18 | } 19 | 20 | const circle = { 21 | cx: event.clientX, 22 | cy: event.clientY, 23 | r: 50 24 | }; 25 | 26 | circles = circles.concat(circle); 27 | selected = circle; 28 | 29 | push(); 30 | } 31 | 32 | function adjust(event) { 33 | selected.r = +event.target.value; 34 | circles = circles; 35 | adjusted = true; 36 | } 37 | 38 | function select(circle, event) { 39 | if (!adjusting) { 40 | event.stopPropagation(); 41 | selected = circle; 42 | } 43 | } 44 | 45 | function push() { 46 | const newUndoStack = undoStack.slice(0, ++i); 47 | newUndoStack.push(clone(circles)); 48 | undoStack = newUndoStack; 49 | } 50 | 51 | function travel(d) { 52 | circles = clone(undoStack[i += d]); 53 | adjusting = false; 54 | } 55 | 56 | function clone(circles) { 57 | return circles.map(({ cx, cy, r }) => ({ cx, cy, r })); 58 | } 59 | ; 60 | <> 61 | 62 | 63 | 64 | 65 | 66 |
67 | 68 | 69 |
70 | 71 | 72 | {(circles).map((circle) => <> 73 | select(circle, event)} 75 | oncontextmenu={() => { 76 | adjusting = !adjusting; 77 | if (adjusting) selected = circle; 78 | }} 79 | fill={circle === selected ? '#ccc': 'white'} 80 | /> 81 | )} 82 | 83 | 84 | {() => {if (adjusting){<> 85 |
86 |

adjust diameter of circle at {selected.cx}, {selected.cy}

87 | 88 |
89 | }}} 90 | return { props: {}, slots: {} }} 91 | 92 | export default class { 93 | $$prop_def = __sveltets_partial(render().props) 94 | $$slot_def = render().slots 95 | } -------------------------------------------------------------------------------- /test/svelte2tsx/samples/circle-drawer-example/input.svelte: -------------------------------------------------------------------------------- 1 | 8 | 9 | 67 | 68 | 101 | 102 |
103 | 104 | 105 |
106 | 107 | 108 | {#each circles as circle} 109 | 117 | {/each} 118 | 119 | 120 | {#if adjusting} 121 |
122 |

adjust diameter of circle at {selected.cx}, {selected.cy}

123 | 124 |
125 | {/if} -------------------------------------------------------------------------------- /test/svelte2tsx/samples/component-default-slot/expected.tsx: -------------------------------------------------------------------------------- 1 | <>;function render() { 2 | 3 | let b = 7; 4 | ; 5 | <> 6 |
7 | Hello 8 |
9 | return { props: {}, slots: {default: {a:b}} }} 10 | 11 | export default class { 12 | $$prop_def = __sveltets_partial(render().props) 13 | $$slot_def = render().slots 14 | } -------------------------------------------------------------------------------- /test/svelte2tsx/samples/component-default-slot/input.svelte: -------------------------------------------------------------------------------- 1 | 4 |
5 | Hello 6 |
7 | -------------------------------------------------------------------------------- /test/svelte2tsx/samples/component-multiple-slots/expected.tsx: -------------------------------------------------------------------------------- 1 | <>;function render() { 2 | 3 | let b = 7; 4 | let d = 5; 5 | let e = 5; 6 | ; 7 | <> 8 |
9 | Hello 10 | 11 |
12 | return { props: {}, slots: {default: {a:b}, test: {c:d, e:e}} }} 13 | 14 | export default class { 15 | $$prop_def = __sveltets_partial(render().props) 16 | $$slot_def = render().slots 17 | } -------------------------------------------------------------------------------- /test/svelte2tsx/samples/component-multiple-slots/input.svelte: -------------------------------------------------------------------------------- 1 | 6 |
7 | Hello 8 | 9 |
10 | -------------------------------------------------------------------------------- /test/svelte2tsx/samples/component-slot-crazy-attributes/expected.tsx: -------------------------------------------------------------------------------- 1 | <>;function render() { 2 | 3 | let b = 7; 4 | ; 5 | <> 6 |
7 | Hello 8 |
9 | return { props: {}, slots: {default: {a:b, b:b, c:"b", d:"__svelte_ts_string", e:b}} }} 10 | 11 | export default class { 12 | $$prop_def = __sveltets_partial(render().props) 13 | $$slot_def = render().slots 14 | } -------------------------------------------------------------------------------- /test/svelte2tsx/samples/component-slot-crazy-attributes/input.svelte: -------------------------------------------------------------------------------- 1 | 4 |
5 | Hello 6 |
7 | -------------------------------------------------------------------------------- /test/svelte2tsx/samples/export-arrow-function/expected.tsx: -------------------------------------------------------------------------------- 1 | <>;function render() { 2 | 3 | let f = (a: number, b: number) => { 4 | let c = a + b; 5 | return c; 6 | } 7 | ; 8 | <> 9 | return { props: {f}, slots: {} }} 10 | 11 | export default class { 12 | $$prop_def = __sveltets_partial(render().props) 13 | $$slot_def = render().slots 14 | } 15 | -------------------------------------------------------------------------------- /test/svelte2tsx/samples/export-arrow-function/input.svelte: -------------------------------------------------------------------------------- 1 | 7 | -------------------------------------------------------------------------------- /test/svelte2tsx/samples/export-has-type/expected.tsx: -------------------------------------------------------------------------------- 1 | <>;function render() { 2 | 3 | interface A {} 4 | let a: A; 5 | ; 6 | <> 7 | return { props: {a: a as A}, slots: {} }} 8 | 9 | export default class { 10 | $$prop_def = __sveltets_partial(render().props) 11 | $$slot_def = render().slots 12 | } 13 | -------------------------------------------------------------------------------- /test/svelte2tsx/samples/export-has-type/input.svelte: -------------------------------------------------------------------------------- 1 | 5 | -------------------------------------------------------------------------------- /test/svelte2tsx/samples/export-interface/expected.tsx: -------------------------------------------------------------------------------- 1 | <>; 2 | export interface A {} 3 | ;<>;function render() { 4 | <> 5 | return { props: {}, slots: {} }} 6 | 7 | export default class { 8 | $$prop_def = __sveltets_partial(render().props) 9 | $$slot_def = render().slots 10 | } 11 | -------------------------------------------------------------------------------- /test/svelte2tsx/samples/export-interface/input.svelte: -------------------------------------------------------------------------------- 1 | 4 | -------------------------------------------------------------------------------- /test/svelte2tsx/samples/export-list/expected.tsx: -------------------------------------------------------------------------------- 1 | <>;function render() { 2 | 3 | let name = "world" 4 | let name2 = "world" 5 | 6 | ; 7 | <> 8 | return { props: {name , name2}, slots: {} }} 9 | 10 | export default class { 11 | $$prop_def = __sveltets_partial(render().props) 12 | $$slot_def = render().slots 13 | } 14 | -------------------------------------------------------------------------------- /test/svelte2tsx/samples/export-list/input.svelte: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /test/svelte2tsx/samples/export-references-local/expected.tsx: -------------------------------------------------------------------------------- 1 | <>;function render() { 2 | 3 | let world = "world"; 4 | let name = world; 5 | ; 6 | <> 7 | return { props: {name}, slots: {} }} 8 | 9 | export default class { 10 | $$prop_def = __sveltets_partial(render().props) 11 | $$slot_def = render().slots 12 | } 13 | -------------------------------------------------------------------------------- /test/svelte2tsx/samples/export-references-local/input.svelte: -------------------------------------------------------------------------------- 1 | 5 | -------------------------------------------------------------------------------- /test/svelte2tsx/samples/import-single-quote/expected.tsx: -------------------------------------------------------------------------------- 1 | <>;import Test from './Test.svelte'; 2 | function render() { 3 | 4 | 5 | ; 6 | <> 7 | 8 | return { props: {}, slots: {} }} 9 | 10 | export default class { 11 | $$prop_def = __sveltets_partial(render().props) 12 | $$slot_def = render().slots 13 | } -------------------------------------------------------------------------------- /test/svelte2tsx/samples/import-single-quote/input.svelte: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /test/svelte2tsx/samples/imports/expected.tsx: -------------------------------------------------------------------------------- 1 | <>;import { a as b } from "./test.svelte" 2 | import * as c from "b.ts" 3 | function render() { 4 | 5 | 6 | 7 | 8 | let world = "name" 9 | ; 10 | <>

hello {world}

11 | 12 | return { props: {world}, slots: {} }} 13 | 14 | export default class { 15 | $$prop_def = __sveltets_partial(render().props) 16 | $$slot_def = render().slots 17 | } -------------------------------------------------------------------------------- /test/svelte2tsx/samples/imports/input.svelte: -------------------------------------------------------------------------------- 1 |

hello {world}

2 | -------------------------------------------------------------------------------- /test/svelte2tsx/samples/module-script-and-script-in-line/expected.tsx: -------------------------------------------------------------------------------- 1 | <>;let b = 5;;<>;function render() { 2 | let world = "name"; 3 | <>

hello {world}

4 | return { props: {world}, slots: {} }} 5 | 6 | export default class { 7 | $$prop_def = __sveltets_partial(render().props) 8 | $$slot_def = render().slots 9 | } -------------------------------------------------------------------------------- /test/svelte2tsx/samples/module-script-and-script-in-line/input.svelte: -------------------------------------------------------------------------------- 1 |

hello {world}

2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /test/svelte2tsx/samples/module-script-and-script-in-line2/expected.tsx: -------------------------------------------------------------------------------- 1 | <>;let b = 5;;<>;function render() { 2 | let world = "name"; 3 | <>

hello {world}

4 | return { props: {world}, slots: {} }} 5 | 6 | export default class { 7 | $$prop_def = __sveltets_partial(render().props) 8 | $$slot_def = render().slots 9 | } -------------------------------------------------------------------------------- /test/svelte2tsx/samples/module-script-and-script-in-line2/input.svelte: -------------------------------------------------------------------------------- 1 |

hello {world}

2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /test/svelte2tsx/samples/module-script-and-script/expected.tsx: -------------------------------------------------------------------------------- 1 | <>; 2 | export function preload() {} 3 | let b = 5; 4 | ;<>;function render() { 5 | 6 | let world = "name" 7 | ; 8 | <> 9 | 10 |

hello {world}

11 | return { props: {world}, slots: {} }} 12 | 13 | export default class { 14 | $$prop_def = __sveltets_partial(render().props) 15 | $$slot_def = render().slots 16 | } -------------------------------------------------------------------------------- /test/svelte2tsx/samples/module-script-and-script/input.svelte: -------------------------------------------------------------------------------- 1 | 4 | 8 |

hello {world}

9 | -------------------------------------------------------------------------------- /test/svelte2tsx/samples/module-script-and-script2/expected.tsx: -------------------------------------------------------------------------------- 1 | <>; 2 | export function preload() {} 3 | let b = 5; 4 | ;<>;function render() { 5 | 6 | let world = "name" 7 | ; 8 | <>

hello {world}

9 | 10 | 11 | return { props: {world}, slots: {} }} 12 | 13 | export default class { 14 | $$prop_def = __sveltets_partial(render().props) 15 | $$slot_def = render().slots 16 | } -------------------------------------------------------------------------------- /test/svelte2tsx/samples/module-script-and-script2/input.svelte: -------------------------------------------------------------------------------- 1 |

hello {world}

2 | 5 | 9 | 10 | -------------------------------------------------------------------------------- /test/svelte2tsx/samples/multiple-export/expected.tsx: -------------------------------------------------------------------------------- 1 | <>;function render() { 2 | 3 | let number1: number 4 | let number2: number 5 | ; 6 | <> 7 |

{number1} + {number2} = {number1 + number2}

8 | return { props: {number1: number1 as number , number2: number2 as number}, slots: {} }} 9 | 10 | export default class { 11 | $$prop_def = __sveltets_partial(render().props) 12 | $$slot_def = render().slots 13 | } 14 | -------------------------------------------------------------------------------- /test/svelte2tsx/samples/multiple-export/input.svelte: -------------------------------------------------------------------------------- 1 | 5 |

{number1} + {number2} = {number1 + number2}

-------------------------------------------------------------------------------- /test/svelte2tsx/samples/nested-$-variables-script/expected.tsx: -------------------------------------------------------------------------------- 1 | <>;function render() { 2 | 3 | let top1 = someStore() 4 | let top2 = someStore() 5 | let topLevelGet = __sveltets_store_get(top1) 6 | topLevelGet = __sveltets_store_get(top2) 7 | 8 | function test(top1) { 9 | let passedGet = __sveltets_store_get(top1) 10 | } 11 | 12 | function test2($top1) { 13 | let paramShadowed = $top1 14 | } 15 | 16 | function test3() { 17 | let $top2 = "hi" 18 | let letshadowed = $top2 19 | } 20 | 21 | const test4 = ({a, b: { $top1: $top2 }}) => $top2 && __sveltets_store_get(top1) 22 | 23 | ; 24 | <> 25 | return { props: {}, slots: {} }} 26 | 27 | export default class { 28 | $$prop_def = __sveltets_partial(render().props) 29 | $$slot_def = render().slots 30 | } -------------------------------------------------------------------------------- /test/svelte2tsx/samples/nested-$-variables-script/input.svelte: -------------------------------------------------------------------------------- 1 | 23 | 24 | -------------------------------------------------------------------------------- /test/svelte2tsx/samples/nested-$-variables-template/expected.tsx: -------------------------------------------------------------------------------- 1 | <>;function render() { 2 | <>

{ 3 | 4 | let top1 = someStore() 5 | let top2 = someStore() 6 | let topLevelGet = __sveltets_store_get(top1) 7 | topLevelGet = __sveltets_store_get(top2) 8 | 9 | function test(top1) { 10 | let passedGet = __sveltets_store_get(top1) 11 | } 12 | 13 | function test2($top1) { 14 | let paramShadowed = $top1 15 | } 16 | 17 | function test3() { 18 | let $top2 = "hi" 19 | let letshadowed = $top2 20 | } 21 | 22 | const test4 = ({a, b: { $top1: $top2 }}) => $top2 && __sveltets_store_get(top1) 23 | 24 | }}>Hi

25 | return { props: {}, slots: {} }} 26 | 27 | export default class { 28 | $$prop_def = __sveltets_partial(render().props) 29 | $$slot_def = render().slots 30 | } -------------------------------------------------------------------------------- /test/svelte2tsx/samples/nested-$-variables-template/input.svelte: -------------------------------------------------------------------------------- 1 |

{ 2 | 3 | let top1 = someStore() 4 | let top2 = someStore() 5 | let topLevelGet = $top1 6 | topLevelGet = $top2 7 | 8 | function test(top1) { 9 | let passedGet = $top1 10 | } 11 | 12 | function test2($top1) { 13 | let paramShadowed = $top1 14 | } 15 | 16 | function test3() { 17 | let $top2 = "hi" 18 | let letshadowed = $top2 19 | } 20 | 21 | const test4 = ({a, b: { $top1: $top2 }}) => $top2 && $top1 22 | 23 | }}>Hi

24 | -------------------------------------------------------------------------------- /test/svelte2tsx/samples/object-binding-export/expected.tsx: -------------------------------------------------------------------------------- 1 | <>;function render() { 2 | 3 | let { name: rename } = { name: "world" }; 4 | ; 5 | <> 6 | return { props: {rename}, slots: {} }} 7 | 8 | export default class { 9 | $$prop_def = __sveltets_partial(render().props) 10 | $$slot_def = render().slots 11 | } 12 | -------------------------------------------------------------------------------- /test/svelte2tsx/samples/object-binding-export/input.svelte: -------------------------------------------------------------------------------- 1 | 4 | -------------------------------------------------------------------------------- /test/svelte2tsx/samples/reactive-declare/expected.tsx: -------------------------------------------------------------------------------- 1 | <>;function render() { 2 | 3 | 4 | ;let b; $: b = 7; 5 | 6 | let a; 7 | $: a = 5; 8 | ; 9 | <> 10 | return { props: {}, slots: {} }} 11 | 12 | export default class { 13 | $$prop_def = __sveltets_partial(render().props) 14 | $$slot_def = render().slots 15 | } -------------------------------------------------------------------------------- /test/svelte2tsx/samples/reactive-declare/input.svelte: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/svelte2tsx/samples/renamed-exports/expected.tsx: -------------------------------------------------------------------------------- 1 | <>;function render() { 2 | 3 | let name = "world" 4 | let name2 = "world" 5 | 6 | ; 7 | <> 8 | return { props: {name3: name , name4: name2}, slots: {} }} 9 | 10 | export default class { 11 | $$prop_def = __sveltets_partial(render().props) 12 | $$slot_def = render().slots 13 | } 14 | -------------------------------------------------------------------------------- /test/svelte2tsx/samples/renamed-exports/input.svelte: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /test/svelte2tsx/samples/script-and-module-script/expected.tsx: -------------------------------------------------------------------------------- 1 | <>; 2 | export function preload() {} 3 | let b = 5; 4 | ;<>;function render() { 5 | 6 | let world = "name" 7 | ; 8 | <> 9 |

hello {world}

10 | 11 | return { props: {world}, slots: {} }} 12 | 13 | export default class { 14 | $$prop_def = __sveltets_partial(render().props) 15 | $$slot_def = render().slots 16 | } -------------------------------------------------------------------------------- /test/svelte2tsx/samples/script-and-module-script/input.svelte: -------------------------------------------------------------------------------- 1 | 5 |

hello {world}

6 | -------------------------------------------------------------------------------- /test/svelte2tsx/samples/script-on-bottom/expected.tsx: -------------------------------------------------------------------------------- 1 | <>;function render() { 2 | 3 | let world = "name" 4 | ; 5 | <>

hello {world}

6 | 7 | return { props: {world}, slots: {} }} 8 | 9 | export default class { 10 | $$prop_def = __sveltets_partial(render().props) 11 | $$slot_def = render().slots 12 | } -------------------------------------------------------------------------------- /test/svelte2tsx/samples/script-on-bottom/input.svelte: -------------------------------------------------------------------------------- 1 |

hello {world}

2 | -------------------------------------------------------------------------------- /test/svelte2tsx/samples/script-style-like-component/expected.tsx: -------------------------------------------------------------------------------- 1 | <>;function render() { 2 | 3 | let Script, Style; 4 | ; 5 | <> 6 | 7 | 10 |