mirror of
https://github.com/kevin-DL/sapper.git
synced 2026-01-13 11:35:28 +00:00
Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d13d6209ed | ||
|
|
05aef8de71 | ||
|
|
429f44e3a6 | ||
|
|
f8e853c02b | ||
|
|
bedbcb834b |
30
CHANGELOG.md
30
CHANGELOG.md
@@ -1,33 +1,5 @@
|
||||
# sapper changelog
|
||||
|
||||
## 0.27.4
|
||||
|
||||
* Update devalue
|
||||
|
||||
|
||||
## 0.27.3
|
||||
|
||||
* Accommodate Svelte 3.5.0
|
||||
|
||||
|
||||
## 0.27.2
|
||||
|
||||
* Fix routes with regular expressions ([#707](https://github.com/sveltejs/sapper/issues/707))
|
||||
* Fix `sapper build --output` option ([#723](https://github.com/sveltejs/sapper/pull/723))
|
||||
|
||||
|
||||
## 0.27.1
|
||||
|
||||
* Prevent infinite loop if `preload` errors ([#677](https://github.com/sveltejs/sapper/pull/677))
|
||||
* Allow disabling of live reload ([#683](https://github.com/sveltejs/sapper/pull/683))
|
||||
* Let browser handle initial scroll ([#331](https://github.com/sveltejs/sapper/issues/331))
|
||||
* Allow custom route file extensions via `--ext` ([#632](https://github.com/sveltejs/sapper/pull/632))
|
||||
* Wait for server to restart before attaching debugger ([#694](https://github.com/sveltejs/sapper/pull/694))
|
||||
* Fix export queue ([#698](https://github.com/sveltejs/sapper/pull/698))
|
||||
* Rerun `preload` functions when query changes ([#701](https://github.com/sveltejs/sapper/issues/701))
|
||||
* Navigate when spread route changes ([#688](https://github.com/sveltejs/sapper/issues/688))
|
||||
|
||||
|
||||
## 0.27.0
|
||||
|
||||
* Change license from LIL to MIT ([#652](https://github.com/sveltejs/sapper/pull/652))
|
||||
@@ -639,4 +611,4 @@
|
||||
|
||||
## 0.1.0
|
||||
|
||||
* First public preview
|
||||
* First public preview
|
||||
250
package-lock.json
generated
250
package-lock.json
generated
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "sapper",
|
||||
"version": "0.27.3",
|
||||
"version": "0.27.0",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
@@ -43,15 +43,15 @@
|
||||
"dev": true
|
||||
},
|
||||
"@types/mocha": {
|
||||
"version": "5.2.7",
|
||||
"resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-5.2.7.tgz",
|
||||
"integrity": "sha512-NYrtPht0wGzhwe9+/idPaBB+TqkY9AhTvOLMkThm0IoEfLaiVQZwBwyJ5puCkO3AUCWrmcoePjp2mbFocKy4SQ==",
|
||||
"version": "5.2.6",
|
||||
"resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-5.2.6.tgz",
|
||||
"integrity": "sha512-1axi39YdtBI7z957vdqXI4Ac25e7YihYQtJa+Clnxg1zTJEaIRbndt71O3sP4GAMgiAm0pY26/b9BrY4MR/PMw==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/node": {
|
||||
"version": "12.0.7",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-12.0.7.tgz",
|
||||
"integrity": "sha512-1YKeT4JitGgE4SOzyB9eMwO0nGVNkNEsm9qlIt1Lqm/tG2QEiSMTD4kS3aO6L+w5SClLVxALmIBESK6Mk5wX0A==",
|
||||
"version": "12.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-12.0.0.tgz",
|
||||
"integrity": "sha512-Jrb/x3HT4PTJp6a4avhmJCDEVrPdqLfl3e8GGMbpkGGdwAV5UGlIs4vVEfsHHfylZVOKZWpOqmqFH8CbfOZ6kg==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/puppeteer": {
|
||||
@@ -301,9 +301,9 @@
|
||||
}
|
||||
},
|
||||
"agent-base": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz",
|
||||
"integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==",
|
||||
"version": "4.2.1",
|
||||
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.2.1.tgz",
|
||||
"integrity": "sha512-JVwXMr9nHYTUXsBFKUqhJwvlcYU/blreOEUkhNR2eXZIvwd+c+o5V4MgDPKWnMS/56awN3TRzIP+KoPn+roQtg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"es6-promisify": "^5.0.0"
|
||||
@@ -602,9 +602,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"bluebird": {
|
||||
"version": "3.5.5",
|
||||
"resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.5.tgz",
|
||||
"integrity": "sha512-5am6HnnfN+urzt4yfg7IgTbotDjIT/u8AJpEt0sIU9FtXfVeezXAPKswrG+xKUCOYAINpSdgZVDU6QFh+cuH3w==",
|
||||
"version": "3.5.4",
|
||||
"resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.4.tgz",
|
||||
"integrity": "sha512-FG+nFEZChJrbQ9tIccIfZJBz3J7mLrAhxakAbnrJWn8d7aKOC+LWifa0G+p4ZqKp4y13T7juYvdhq9NzKdsrjw==",
|
||||
"dev": true
|
||||
},
|
||||
"bn.js": {
|
||||
@@ -854,9 +854,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"chokidar": {
|
||||
"version": "2.1.6",
|
||||
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.6.tgz",
|
||||
"integrity": "sha512-V2jUo67OKkc6ySiRpJrjlpJKl9kDuG+Xb8VgsGzb+aEouhgS1D0weyPU4lEzdAcsCAvrih2J2BqyXqHWvVLw5g==",
|
||||
"version": "2.1.5",
|
||||
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.5.tgz",
|
||||
"integrity": "sha512-i0TprVWp+Kj4WRPtInjexJ8Q+BqTE909VpH8xVhXrJkoc5QC8VO9TryGOqTr+2hljzc1sC62t22h5tZePodM/A==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"anymatch": "^2.0.0",
|
||||
@@ -880,9 +880,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"chrome-trace-event": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz",
|
||||
"integrity": "sha512-9e/zx1jw7B4CO+c/RXoCsfg/x1AfUBioy4owYH0bJprEYAx5hRFLRhWBqHAG57D0ZM4H7vxbP7bPe0VwhQRYDQ==",
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.0.tgz",
|
||||
"integrity": "sha512-xDbVgyfDTT2piup/h8dK/y4QZfJRSa73bw1WZ8b4XM1o7fsFubUVGYcE+1ANtOzJJELGpYoG2961z0Z6OAld9A==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"tslib": "^1.9.0"
|
||||
@@ -1043,9 +1043,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"cookie": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz",
|
||||
"integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==",
|
||||
"version": "0.3.1",
|
||||
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz",
|
||||
"integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=",
|
||||
"dev": true
|
||||
},
|
||||
"copy-concurrently": {
|
||||
@@ -1243,9 +1243,9 @@
|
||||
}
|
||||
},
|
||||
"devalue": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/devalue/-/devalue-1.1.1.tgz",
|
||||
"integrity": "sha512-ULnighb7iXHiG+T3hoePM8LfaJWuMV/8TBYcdkYD2eOSRtGfZGVtc/66+gIx6BHRVOwEWGfUsMwzcDF7LxRwgw==",
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/devalue/-/devalue-1.1.0.tgz",
|
||||
"integrity": "sha512-mKj+DaZuxevfmjI78VdlkBr+NDmwaDAKQz0t5RDSmhwBn6m5z82KDnVRKVFeUvlMOmI1fzkAUx4USdqGGhas6g==",
|
||||
"dev": true
|
||||
},
|
||||
"diff": {
|
||||
@@ -1383,9 +1383,9 @@
|
||||
}
|
||||
},
|
||||
"es6-promise": {
|
||||
"version": "4.2.8",
|
||||
"resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz",
|
||||
"integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==",
|
||||
"version": "4.2.6",
|
||||
"resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.6.tgz",
|
||||
"integrity": "sha512-aRVgGdnmW2OiySVPUC9e6m+plolMAJKjZnQlCwNSuK5yQ0JN61DZSO1X1Ufd1foqWRAlig0rhduTCHe7sVtK5Q==",
|
||||
"dev": true
|
||||
},
|
||||
"es6-promisify": {
|
||||
@@ -1502,9 +1502,9 @@
|
||||
}
|
||||
},
|
||||
"eslint-plugin-import": {
|
||||
"version": "2.17.3",
|
||||
"resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.17.3.tgz",
|
||||
"integrity": "sha512-qeVf/UwXFJbeyLbxuY8RgqDyEKCkqV7YC+E5S5uOjAp4tOc8zj01JP3ucoBM8JcEqd1qRasJSg6LLlisirfy0Q==",
|
||||
"version": "2.17.2",
|
||||
"resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.17.2.tgz",
|
||||
"integrity": "sha512-m+cSVxM7oLsIpmwNn2WXTJoReOF9f/CtLMo7qOVmKd1KntBy0hEcuNZ3erTmWjx+DxRO0Zcrm5KwAvI9wHcV5g==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"array-includes": "^3.0.3",
|
||||
@@ -1517,7 +1517,7 @@
|
||||
"lodash": "^4.17.11",
|
||||
"minimatch": "^3.0.4",
|
||||
"read-pkg-up": "^2.0.0",
|
||||
"resolve": "^1.11.0"
|
||||
"resolve": "^1.10.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"debug": {
|
||||
@@ -1611,9 +1611,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"estree-walker": {
|
||||
"version": "0.6.1",
|
||||
"resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-0.6.1.tgz",
|
||||
"integrity": "sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==",
|
||||
"version": "0.6.0",
|
||||
"resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-0.6.0.tgz",
|
||||
"integrity": "sha512-peq1RfVAVzr3PU/jL31RaOjUKLoZJpObQWJJ+LgfcxDUifyLZ1RjPQZTl0pzj2uJ45b7A7XpyppXvxdEqzo4rw==",
|
||||
"dev": true
|
||||
},
|
||||
"esutils": {
|
||||
@@ -3105,15 +3105,6 @@
|
||||
"integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=",
|
||||
"dev": true
|
||||
},
|
||||
"is-reference": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.1.2.tgz",
|
||||
"integrity": "sha512-Kn5g8c7XHKejFOpTf2QN9YjiHHKl5xRj+2uAZf9iM2//nkBNi/NNeB5JMoun28nEaUVHyPUzqzhfRlfAirEjXg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/estree": "0.0.39"
|
||||
}
|
||||
},
|
||||
"is-regex": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz",
|
||||
@@ -3144,12 +3135,6 @@
|
||||
"integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==",
|
||||
"dev": true
|
||||
},
|
||||
"is-wsl": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz",
|
||||
"integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=",
|
||||
"dev": true
|
||||
},
|
||||
"isarray": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
|
||||
@@ -3474,9 +3459,9 @@
|
||||
}
|
||||
},
|
||||
"mime": {
|
||||
"version": "2.4.4",
|
||||
"resolved": "https://registry.npmjs.org/mime/-/mime-2.4.4.tgz",
|
||||
"integrity": "sha512-LRxmNwziLPT828z+4YkNzloCFC2YM4wrB99k+AV5ZbEyfGNWfG8SO1FUXLmLDBSo89NrJZ4DIWeLjy1CHGhMGA==",
|
||||
"version": "2.4.2",
|
||||
"resolved": "https://registry.npmjs.org/mime/-/mime-2.4.2.tgz",
|
||||
"integrity": "sha512-zJBfZDkwRu+j3Pdd2aHsR5GfH2jIWhmL1ZzBoc+X+3JEti2hbArWcyJ+1laC1D2/U/W1a/+Cegj0/OnEU2ybjg==",
|
||||
"dev": true
|
||||
},
|
||||
"mimic-fn": {
|
||||
@@ -3633,12 +3618,6 @@
|
||||
"path-exists": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"ms": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
|
||||
"integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==",
|
||||
"dev": true
|
||||
},
|
||||
"p-limit": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.0.tgz",
|
||||
@@ -3695,9 +3674,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"ms": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
|
||||
"integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==",
|
||||
"dev": true
|
||||
},
|
||||
"mute-stream": {
|
||||
@@ -3718,9 +3697,9 @@
|
||||
}
|
||||
},
|
||||
"nan": {
|
||||
"version": "2.14.0",
|
||||
"resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz",
|
||||
"integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==",
|
||||
"version": "2.13.2",
|
||||
"resolved": "https://registry.npmjs.org/nan/-/nan-2.13.2.tgz",
|
||||
"integrity": "sha512-TghvYc72wlMGMVMluVo9WRJc0mB8KxxF/gZ4YYFy7V2ZQX9l7rgbPg7vjS9mt6U5HXODVFVI2bOduCzwOMv/lw==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
@@ -3750,9 +3729,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"neo-async": {
|
||||
"version": "2.6.1",
|
||||
"resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.1.tgz",
|
||||
"integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==",
|
||||
"version": "2.6.0",
|
||||
"resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.0.tgz",
|
||||
"integrity": "sha512-MFh0d/Wa7vkKO3Y3LlacqAEeHK0mckVqzDieUKTT+KGxi+zIpeVsFxymkIiRpbpDziHc290Xr9A1O4Om7otoRA==",
|
||||
"dev": true
|
||||
},
|
||||
"nice-try": {
|
||||
@@ -3780,9 +3759,9 @@
|
||||
}
|
||||
},
|
||||
"node-fetch": {
|
||||
"version": "2.6.0",
|
||||
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz",
|
||||
"integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==",
|
||||
"version": "2.5.0",
|
||||
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.5.0.tgz",
|
||||
"integrity": "sha512-YuZKluhWGJwCcUu4RlZstdAxr8bFfOVHakc1mplwHkk8J+tqM1Y5yraYvIUpeX8aY7+crCwiELJq7Vl0o0LWXw==",
|
||||
"dev": true
|
||||
},
|
||||
"node-libs-browser": {
|
||||
@@ -4403,9 +4382,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"puppeteer": {
|
||||
"version": "1.17.0",
|
||||
"resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-1.17.0.tgz",
|
||||
"integrity": "sha512-3EXZSximCzxuVKpIHtyec8Wm2dWZn1fc5tQi34qWfiUgubEVYHjUvr0GOJojqf3mifI6oyKnCdrGxaOI+lWReA==",
|
||||
"version": "1.15.0",
|
||||
"resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-1.15.0.tgz",
|
||||
"integrity": "sha512-D2y5kwA9SsYkNUmcBzu9WZ4V1SGHiQTmgvDZSx6sRYFsgV25IebL4V6FaHjF6MbwLK9C6f3G3pmck9qmwM8H3w==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"debug": "^4.1.0",
|
||||
@@ -4554,9 +4533,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"resolve": {
|
||||
"version": "1.11.1",
|
||||
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.11.1.tgz",
|
||||
"integrity": "sha512-vIpgF6wfuJOZI7KKKSP+HmiKggadPQAdsp5HiC1mvqnfp0gF1vdwgBWZIdrVft9pgqoMFQN+R7BSWZiBxx+BBw==",
|
||||
"version": "1.10.1",
|
||||
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.10.1.tgz",
|
||||
"integrity": "sha512-KuIe4mf++td/eFb6wkaPbMDnP6kObCaEtIDuHOUED6MNUo4K670KZUHuuvYPZDxNF0WVLw49n06M2m2dXphEzA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"path-parse": "^1.0.6"
|
||||
@@ -4610,27 +4589,34 @@
|
||||
}
|
||||
},
|
||||
"rollup": {
|
||||
"version": "1.14.5",
|
||||
"resolved": "https://registry.npmjs.org/rollup/-/rollup-1.14.5.tgz",
|
||||
"integrity": "sha512-XKegaT6NhrKuBvFQCeLfDJ7bNpfnWIMQfLx9+Qe34rrKaVOtNGVIf5vyIKuwS4JlF2l/nA7RvEsItXqyF0ZFZg==",
|
||||
"version": "1.11.3",
|
||||
"resolved": "https://registry.npmjs.org/rollup/-/rollup-1.11.3.tgz",
|
||||
"integrity": "sha512-81MR7alHcFKxgWzGfG7jSdv+JQxSOIOD/Fa3iNUmpzbd7p+V19e1l9uffqT8/7YAHgGOzmoPGN3Fx3L2ptOf5g==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/estree": "0.0.39",
|
||||
"@types/node": "^12.0.7",
|
||||
"@types/node": "^11.13.9",
|
||||
"acorn": "^6.1.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"@types/node": {
|
||||
"version": "11.13.10",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-11.13.10.tgz",
|
||||
"integrity": "sha512-leUNzbFTMX94TWaIKz8N15Chu55F9QSH+INKayQr5xpkasBQBRF3qQXfo3/dOnMU/dEIit+Y/SU8HyOjq++GwA==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"rollup-plugin-commonjs": {
|
||||
"version": "10.0.0",
|
||||
"resolved": "https://registry.npmjs.org/rollup-plugin-commonjs/-/rollup-plugin-commonjs-10.0.0.tgz",
|
||||
"integrity": "sha512-B8MoX5GRpj3kW4+YaFO/di2JsZkBxNjVmZ9LWjUoTAjq8N9wc7HObMXPsrvolVV9JXVtYSscflXM14A19dXPNQ==",
|
||||
"version": "9.3.4",
|
||||
"resolved": "https://registry.npmjs.org/rollup-plugin-commonjs/-/rollup-plugin-commonjs-9.3.4.tgz",
|
||||
"integrity": "sha512-DTZOvRoiVIHHLFBCL4pFxOaJt8pagxsVldEXBOn6wl3/V21wVaj17HFfyzTsQUuou3sZL3lEJZVWKPFblJfI6w==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"estree-walker": "^0.6.0",
|
||||
"is-reference": "^1.1.2",
|
||||
"magic-string": "^0.25.2",
|
||||
"resolve": "^1.10.1",
|
||||
"rollup-pluginutils": "^2.7.0"
|
||||
"resolve": "^1.10.0",
|
||||
"rollup-pluginutils": "^2.6.0"
|
||||
}
|
||||
},
|
||||
"rollup-plugin-json": {
|
||||
@@ -4643,16 +4629,15 @@
|
||||
}
|
||||
},
|
||||
"rollup-plugin-node-resolve": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/rollup-plugin-node-resolve/-/rollup-plugin-node-resolve-5.0.1.tgz",
|
||||
"integrity": "sha512-9s3dTu44SKQZM/Pwll42GpqXgT+WdvO0Ga01lF8cwZqJGqRUATtD+GrP3uIzZdpnbPonEJbVasfFt80VGPQqKw==",
|
||||
"version": "4.2.3",
|
||||
"resolved": "https://registry.npmjs.org/rollup-plugin-node-resolve/-/rollup-plugin-node-resolve-4.2.3.tgz",
|
||||
"integrity": "sha512-r+WaesPzdGEynpLZLALFEDugA4ACa5zn7bc/+LVX4vAXQQ8IgDHv0xfsSvJ8tDXUtprfBtrDtRFg27ifKjcJTg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/resolve": "0.0.8",
|
||||
"builtin-modules": "^3.1.0",
|
||||
"is-module": "^1.0.0",
|
||||
"resolve": "^1.11.0",
|
||||
"rollup-pluginutils": "^2.8.0"
|
||||
"resolve": "^1.10.0"
|
||||
}
|
||||
},
|
||||
"rollup-plugin-replace": {
|
||||
@@ -4702,12 +4687,13 @@
|
||||
"dev": true
|
||||
},
|
||||
"rollup-pluginutils": {
|
||||
"version": "2.8.1",
|
||||
"resolved": "https://registry.npmjs.org/rollup-pluginutils/-/rollup-pluginutils-2.8.1.tgz",
|
||||
"integrity": "sha512-J5oAoysWar6GuZo0s+3bZ6sVZAC0pfqKz68De7ZgDi5z63jOVZn1uJL/+z1jeKHNbGII8kAyHF5q8LnxSX5lQg==",
|
||||
"version": "2.6.0",
|
||||
"resolved": "https://registry.npmjs.org/rollup-pluginutils/-/rollup-pluginutils-2.6.0.tgz",
|
||||
"integrity": "sha512-aGQwspEF8oPKvg37u3p7h0cYNwmJR1sCBMZGZ5b9qy8HGtETknqjzcxrDRrcAnJNXN18lBH4Q9vZYth/p4n8jQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"estree-walker": "^0.6.1"
|
||||
"estree-walker": "^0.6.0",
|
||||
"micromatch": "^3.1.10"
|
||||
}
|
||||
},
|
||||
"run-async": {
|
||||
@@ -4729,18 +4715,18 @@
|
||||
}
|
||||
},
|
||||
"rxjs": {
|
||||
"version": "6.5.2",
|
||||
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.2.tgz",
|
||||
"integrity": "sha512-HUb7j3kvb7p7eCUHE3FqjoDsC1xfZQ4AHFWfTKSpZ+sAhhz5X1WX0ZuUqWbzB2QhSLp3DoLUG+hMdEDKqWo2Zg==",
|
||||
"version": "6.5.1",
|
||||
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.1.tgz",
|
||||
"integrity": "sha512-y0j31WJc83wPu31vS1VlAFW5JGrnGC+j+TtGAa1fRQphy48+fDYiDmX8tjGloToEsMkxnouOg/1IzXGKkJnZMg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"tslib": "^1.9.0"
|
||||
}
|
||||
},
|
||||
"sade": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/sade/-/sade-1.5.0.tgz",
|
||||
"integrity": "sha512-d1BuDwSfXR3vKnV00YF09f5SgzZsexB0A3YR8c95KhiGlJwwepxPVEQZC17XOBxPeQZ5I7OZszsSHy0JloOcMA==",
|
||||
"version": "1.4.2",
|
||||
"resolved": "https://registry.npmjs.org/sade/-/sade-1.4.2.tgz",
|
||||
"integrity": "sha512-MTrQm+Nhl4m1mbssYDgAculC/HbShjj08QtHnA2GTpzivfU5aUp8EoHlECmrIHEaa8hZRZSp2Gygv8VMlpXEBw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"mri": "^1.1.0"
|
||||
@@ -5273,9 +5259,9 @@
|
||||
}
|
||||
},
|
||||
"svelte": {
|
||||
"version": "3.5.1",
|
||||
"resolved": "https://registry.npmjs.org/svelte/-/svelte-3.5.1.tgz",
|
||||
"integrity": "sha512-iMnuyteFGQ8Yl68G/DHTHY1sLwoAMya1eS0ZOHIm/dqn2etR8WEe8hUAoluLryde4Cft4gvMhtHV3NhE60nBmQ==",
|
||||
"version": "3.2.2",
|
||||
"resolved": "https://registry.npmjs.org/svelte/-/svelte-3.2.2.tgz",
|
||||
"integrity": "sha512-B6ePpPodCQodVFDwv/uByaWs0KvXojaXZiB/db1x7WXbyxgLJ8xZF3j1lk5M83Ox0AWlX0fQnCTAaZmfT6xqdw==",
|
||||
"dev": true
|
||||
},
|
||||
"svelte-dev-helper": {
|
||||
@@ -5285,9 +5271,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"svelte-loader": {
|
||||
"version": "2.13.4",
|
||||
"resolved": "https://registry.npmjs.org/svelte-loader/-/svelte-loader-2.13.4.tgz",
|
||||
"integrity": "sha512-seAB2Tn/OkJA8TvTY1fVlWdDCwyribzEagT6qPkTK8RGpG6NugPnjyKJv2jN72Sya4yGIo/fc874c6Je5L7vHA==",
|
||||
"version": "2.13.3",
|
||||
"resolved": "https://registry.npmjs.org/svelte-loader/-/svelte-loader-2.13.3.tgz",
|
||||
"integrity": "sha512-ZvNWbR77lZ04nCHqnN0XFxKCQ+fynARCy+kxwogagW3k2NTJWg2QfJwN1J9d4ch+OZwcGPgGZITVr7FGB3hPmQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"loader-utils": "^1.1.0",
|
||||
@@ -5295,9 +5281,9 @@
|
||||
}
|
||||
},
|
||||
"table": {
|
||||
"version": "5.4.0",
|
||||
"resolved": "https://registry.npmjs.org/table/-/table-5.4.0.tgz",
|
||||
"integrity": "sha512-nHFDrxmbrkU7JAFKqKbDJXfzrX2UBsWmrieXFTGxiI5e4ncg3VqsZeI4EzNmX0ncp4XNGVeoxIWJXfCIXwrsvw==",
|
||||
"version": "5.3.0",
|
||||
"resolved": "https://registry.npmjs.org/table/-/table-5.3.0.tgz",
|
||||
"integrity": "sha512-6V2qlZHIbbZQGzoP3Ghcj/IQDPhBvQYjZE4W4JEyFMkbzHziIzG6jxmAD87BZ1ZXgwPwgu3MzvCUGMOFRN7wlw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ajv": "^6.9.1",
|
||||
@@ -5341,9 +5327,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"terser": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/terser/-/terser-4.0.0.tgz",
|
||||
"integrity": "sha512-dOapGTU0hETFl1tCo4t56FN+2jffoKyER9qBGoUFyZ6y7WLoKT0bF+lAYi6B6YsILcGF3q1C2FBh8QcKSCgkgA==",
|
||||
"version": "3.17.0",
|
||||
"resolved": "https://registry.npmjs.org/terser/-/terser-3.17.0.tgz",
|
||||
"integrity": "sha512-/FQzzPJmCpjAH9Xvk2paiWrFq+5M6aVOf+2KRbwhByISDX/EujxsK+BAvrhb6H+2rtrLCHK9N01wO014vrIwVQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"commander": "^2.19.0",
|
||||
@@ -5352,21 +5338,19 @@
|
||||
}
|
||||
},
|
||||
"terser-webpack-plugin": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.3.0.tgz",
|
||||
"integrity": "sha512-W2YWmxPjjkUcOWa4pBEv4OP4er1aeQJlSo2UhtCFQCuRXEHjOFscO8VyWHj9JLlA0RzQb8Y2/Ta78XZvT54uGg==",
|
||||
"version": "1.2.3",
|
||||
"resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.2.3.tgz",
|
||||
"integrity": "sha512-GOK7q85oAb/5kE12fMuLdn2btOS9OBZn4VsecpHDywoUC/jLhSAKOiYo0ezx7ss2EXPMzyEWFoE0s1WLE+4+oA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"cacache": "^11.3.2",
|
||||
"cacache": "^11.0.2",
|
||||
"find-cache-dir": "^2.0.0",
|
||||
"is-wsl": "^1.1.0",
|
||||
"loader-utils": "^1.2.3",
|
||||
"schema-utils": "^1.0.0",
|
||||
"serialize-javascript": "^1.7.0",
|
||||
"serialize-javascript": "^1.4.0",
|
||||
"source-map": "^0.6.1",
|
||||
"terser": "^4.0.0",
|
||||
"webpack-sources": "^1.3.0",
|
||||
"worker-farm": "^1.7.0"
|
||||
"terser": "^3.16.1",
|
||||
"webpack-sources": "^1.1.0",
|
||||
"worker-farm": "^1.5.2"
|
||||
}
|
||||
},
|
||||
"text-table": {
|
||||
@@ -5518,9 +5502,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"uglify-js": {
|
||||
"version": "3.6.0",
|
||||
"resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.6.0.tgz",
|
||||
"integrity": "sha512-W+jrUHJr3DXKhrsS7NUVxn3zqMOFn0hL/Ei6v0anCIMoKC93TjcflTagwIHLW7SfMFfiQuktQyFVCFHGUE0+yg==",
|
||||
"version": "3.5.11",
|
||||
"resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.5.11.tgz",
|
||||
"integrity": "sha512-izPJg8RsSyqxbdnqX36ExpbH3K7tDBsAU/VfNv89VkMFy3z39zFjunQGsSHOlGlyIfGLGprGeosgQno3bo2/Kg==",
|
||||
"requires": {
|
||||
"commander": "~2.20.0",
|
||||
"source-map": "~0.6.1"
|
||||
@@ -5715,9 +5699,9 @@
|
||||
}
|
||||
},
|
||||
"webpack": {
|
||||
"version": "4.33.0",
|
||||
"resolved": "https://registry.npmjs.org/webpack/-/webpack-4.33.0.tgz",
|
||||
"integrity": "sha512-ggWMb0B2QUuYso6FPZKUohOgfm+Z0sVFs8WwWuSH1IAvkWs428VDNmOlAxvHGTB9Dm/qOB/qtE5cRx5y01clxw==",
|
||||
"version": "4.31.0",
|
||||
"resolved": "https://registry.npmjs.org/webpack/-/webpack-4.31.0.tgz",
|
||||
"integrity": "sha512-n6RVO3X0LbbipoE62akME9K/JI7qYrwwufs20VvgNNpqUoH4860KkaxJTbGq5bgkVZF9FqyyTG/0WPLH3PVNJA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@webassemblyjs/ast": "1.8.5",
|
||||
@@ -6101,9 +6085,9 @@
|
||||
}
|
||||
},
|
||||
"yootils": {
|
||||
"version": "0.0.16",
|
||||
"resolved": "https://registry.npmjs.org/yootils/-/yootils-0.0.16.tgz",
|
||||
"integrity": "sha512-aIVecm5ucOzwhtKbl0zkfg0ZSOUR9c2da0k8cIc9umjjzkvVCWUUX/UHZ1CLPsv4wmJLqt0aWeLB7p9n9JDwYQ==",
|
||||
"version": "0.0.15",
|
||||
"resolved": "https://registry.npmjs.org/yootils/-/yootils-0.0.15.tgz",
|
||||
"integrity": "sha512-GvGLuJ7XHJPGEUQ52vh8fh+vPjfikuGcu7yBswfrsNsHqnAoytOVuSb69eM0j8wQIjMz0U3kY3YsfwMhJgfG9w==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
|
||||
34
package.json
34
package.json
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "sapper",
|
||||
"version": "0.27.4",
|
||||
"version": "0.27.0",
|
||||
"description": "Military-grade apps, engineered by Svelte",
|
||||
"bin": {
|
||||
"sapper": "./sapper"
|
||||
@@ -25,43 +25,43 @@
|
||||
"string-hash": "^1.1.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/mocha": "^5.2.7",
|
||||
"@types/node": "^12.0.7",
|
||||
"@types/mocha": "^5.2.6",
|
||||
"@types/node": "^12.0.0",
|
||||
"@types/puppeteer": "^1.12.4",
|
||||
"agadoo": "^1.0.1",
|
||||
"cheap-watch": "^1.0.2",
|
||||
"cookie": "^0.4.0",
|
||||
"devalue": "^1.1.1",
|
||||
"cookie": "^0.3.1",
|
||||
"devalue": "^1.1.0",
|
||||
"eslint": "^5.16.0",
|
||||
"eslint-plugin-import": "^2.17.3",
|
||||
"eslint-plugin-import": "^2.17.2",
|
||||
"kleur": "^3.0.3",
|
||||
"mocha": "^6.1.4",
|
||||
"node-fetch": "^2.6.0",
|
||||
"node-fetch": "^2.5.0",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"polka": "^0.5.2",
|
||||
"port-authority": "^1.0.5",
|
||||
"pretty-bytes": "^5.2.0",
|
||||
"puppeteer": "^1.17.0",
|
||||
"puppeteer": "^1.15.0",
|
||||
"require-relative": "^0.8.7",
|
||||
"rollup": "^1.14.5",
|
||||
"rollup-plugin-commonjs": "^10.0.0",
|
||||
"rollup": "^1.11.3",
|
||||
"rollup-plugin-commonjs": "^9.3.4",
|
||||
"rollup-plugin-json": "^4.0.0",
|
||||
"rollup-plugin-node-resolve": "^5.0.1",
|
||||
"rollup-plugin-node-resolve": "^4.2.3",
|
||||
"rollup-plugin-replace": "^2.2.0",
|
||||
"rollup-plugin-string": "^3.0.0",
|
||||
"rollup-plugin-sucrase": "^2.1.0",
|
||||
"rollup-plugin-svelte": "^5.0.3",
|
||||
"sade": "^1.5.0",
|
||||
"sade": "^1.4.2",
|
||||
"sirv": "^0.4.2",
|
||||
"sucrase": "^3.10.1",
|
||||
"svelte": "^3.5.0",
|
||||
"svelte-loader": "^2.13.4",
|
||||
"webpack": "^4.33.0",
|
||||
"svelte": "^3.2.2",
|
||||
"svelte-loader": "^2.13.3",
|
||||
"webpack": "^4.31.0",
|
||||
"webpack-format-messages": "^2.0.5",
|
||||
"yootils": "0.0.16"
|
||||
"yootils": "0.0.15"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"svelte": "^3.5.0"
|
||||
"svelte": "^3.2.2"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "mocha --opts mocha.opts",
|
||||
|
||||
@@ -24,8 +24,9 @@ function template(kind, external) {
|
||||
external,
|
||||
plugins: [
|
||||
resolve({
|
||||
extensions: ['.mjs', '.js', '.ts']
|
||||
extensions: ['.mjs', '.js', '.json', '.ts']
|
||||
}),
|
||||
json(),
|
||||
commonjs(),
|
||||
string({
|
||||
include: '**/*.md'
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { writable } from 'svelte/store';
|
||||
import { writable } from 'svelte/store.mjs';
|
||||
import App from '@sapper/internal/App.svelte';
|
||||
import { root_preload, ErrorComponent, ignore, components, routes } from '@sapper/internal/manifest-client';
|
||||
import {
|
||||
@@ -22,7 +22,6 @@ let root_component: Component;
|
||||
let current_token: {};
|
||||
let root_preloaded: Promise<any>;
|
||||
let current_branch = [];
|
||||
let current_query = '{}';
|
||||
|
||||
const stores = {
|
||||
page: writable({}),
|
||||
@@ -251,28 +250,10 @@ async function render(redirect: Redirect, branch: any[], props: any, page: Page)
|
||||
}
|
||||
|
||||
current_branch = branch;
|
||||
current_query = JSON.stringify(page.query);
|
||||
ready = true;
|
||||
session_dirty = false;
|
||||
}
|
||||
|
||||
function part_changed(i, segment, match, stringified_query) {
|
||||
// TODO only check query string changes for preload functions
|
||||
// that do in fact depend on it (using static analysis or
|
||||
// runtime instrumentation)
|
||||
if (stringified_query !== current_query) return true;
|
||||
|
||||
const previous = current_branch[i];
|
||||
|
||||
if (!previous) return false;
|
||||
if (segment !== previous.segment) return true;
|
||||
if (previous.match) {
|
||||
if (JSON.stringify(previous.match.slice(1, i + 2)) !== JSON.stringify(match.slice(1, i + 2))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export async function hydrate_target(target: Target): Promise<{
|
||||
redirect?: Redirect;
|
||||
props?: any;
|
||||
@@ -311,15 +292,11 @@ export async function hydrate_target(target: Target): Promise<{
|
||||
let l = 1;
|
||||
|
||||
try {
|
||||
const stringified_query = JSON.stringify(page.query);
|
||||
const match = route.pattern.exec(page.path);
|
||||
|
||||
let segment_dirty = false;
|
||||
|
||||
branch = await Promise.all(route.parts.map(async (part, i) => {
|
||||
const segment = segments[i];
|
||||
|
||||
if (part_changed(i, segment, match, stringified_query)) segment_dirty = true;
|
||||
if (current_branch[i] && current_branch[i].segment !== segment) segment_dirty = true;
|
||||
|
||||
props.segments[l] = segments[i + 1]; // TODO make this less confusing
|
||||
if (!part) return { segment };
|
||||
@@ -347,7 +324,7 @@ export async function hydrate_target(target: Target): Promise<{
|
||||
preloaded = initial_data.preloaded[i + 1];
|
||||
}
|
||||
|
||||
return (props[`level${j}`] = { component, props: preloaded, segment, match, part: part.i });
|
||||
return (props[`level${j}`] = { component, props: preloaded, segment, part: part.i });
|
||||
}));
|
||||
} catch (error) {
|
||||
props.error = error;
|
||||
@@ -359,7 +336,7 @@ export async function hydrate_target(target: Target): Promise<{
|
||||
}
|
||||
|
||||
function load_css(chunk: string) {
|
||||
const href = `client/${chunk}`;
|
||||
const href = `sapper/${chunk}`;
|
||||
if (document.querySelector(`link[href="${href}"]`)) return;
|
||||
|
||||
return new Promise((fulfil, reject) => {
|
||||
|
||||
@@ -40,7 +40,7 @@ export default function start(opts: {
|
||||
if (initial_data.error) return handle_error(url);
|
||||
|
||||
const target = select_target(url);
|
||||
if (target) return navigate(target, uid, true, hash);
|
||||
if (target) return navigate(target, uid, false, hash);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -1 +1,17 @@
|
||||
export { default as middleware } from './middleware/index';
|
||||
import http from 'http';
|
||||
import middleware from './middleware/index';
|
||||
import { StartOptions, MiddlewareOptions, Handler } from './types';
|
||||
|
||||
export { middleware };
|
||||
|
||||
export function server(opts: MiddlewareOptions) {
|
||||
const handler = middleware(opts) as Handler;
|
||||
return http.createServer(handler as http.ServerOptions);
|
||||
}
|
||||
|
||||
export function start(opts: StartOptions = {}) {
|
||||
const s = server(opts);
|
||||
s.listen(opts.port || process.env.PORT);
|
||||
|
||||
return s;
|
||||
}
|
||||
@@ -1,11 +1,11 @@
|
||||
import { writable } from 'svelte/store';
|
||||
import { writable } from 'svelte/store.mjs';
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import cookie from 'cookie';
|
||||
import devalue from 'devalue';
|
||||
import fetch from 'node-fetch';
|
||||
import URL from 'url';
|
||||
import { Manifest, Page, Req, Res } from './types';
|
||||
import { Manifest, Page, Req, Res } from '../types';
|
||||
import { build_dir, dev, src_dir } from '@sapper/internal/manifest-server';
|
||||
import App from '@sapper/internal/App.svelte';
|
||||
|
||||
@@ -21,20 +21,10 @@ export function get_page_handler(
|
||||
? () => read_template(src_dir)
|
||||
: (str => () => str)(read_template(build_dir));
|
||||
|
||||
const has_service_worker = fs.existsSync(path.join(build_dir, 'service-worker.js'));
|
||||
const has_service_worker = fs.existsSync(path.join(build_dir, 'service-worker/service-worker.js'));
|
||||
|
||||
const { server_routes, pages } = manifest;
|
||||
const error_route = manifest.error;
|
||||
|
||||
function bail(req: Req, res: Res, err: Error) {
|
||||
console.error(err);
|
||||
|
||||
const message = dev ? escape_html(err.message) : 'Internal server error';
|
||||
|
||||
res.statusCode = 500;
|
||||
res.end(`<pre>${message}</pre>`);
|
||||
}
|
||||
|
||||
function handle_error(req: Req, res: Res, statusCode: number, error: Error | string) {
|
||||
handle_page({
|
||||
pattern: null,
|
||||
@@ -72,7 +62,7 @@ export function get_page_handler(
|
||||
// TODO add dependencies and CSS
|
||||
const link = preloaded_chunks
|
||||
.filter(file => file && !file.match(/\.map$/))
|
||||
.map(file => `<${req.baseUrl}/client/${file}>;rel="modulepreload"`)
|
||||
.map(file => `<${req.baseUrl}/sapper/${file}>;rel="modulepreload"`)
|
||||
.join(', ');
|
||||
|
||||
res.setHeader('Link', link);
|
||||
@@ -81,7 +71,7 @@ export function get_page_handler(
|
||||
.filter(file => file && !file.match(/\.map$/))
|
||||
.map((file) => {
|
||||
const as = /\.css$/.test(file) ? 'style' : 'script';
|
||||
return `<${req.baseUrl}/client/${file}>;rel="preload";as="${as}"`;
|
||||
return `<${req.baseUrl}/sapper/${file}>;rel="preload";as="${as}"`;
|
||||
})
|
||||
.join(', ');
|
||||
|
||||
@@ -178,10 +168,6 @@ export function get_page_handler(
|
||||
|
||||
preloaded = await Promise.all(toPreload);
|
||||
} catch (err) {
|
||||
if (error) {
|
||||
return bail(req, res, err)
|
||||
}
|
||||
|
||||
preload_error = { statusCode: 500, message: err };
|
||||
preloaded = []; // appease TypeScript
|
||||
}
|
||||
@@ -276,14 +262,14 @@ export function get_page_handler(
|
||||
}
|
||||
|
||||
const file = [].concat(build_info.assets.main).filter(file => file && /\.js$/.test(file))[0];
|
||||
const main = `${req.baseUrl}/client/${file}`;
|
||||
const main = `${req.baseUrl}/sapper/${file}`;
|
||||
|
||||
if (build_info.bundler === 'rollup') {
|
||||
if (build_info.legacy_assets) {
|
||||
const legacy_main = `${req.baseUrl}/client/legacy/${build_info.legacy_assets.main}`;
|
||||
script += `(function(){try{eval("async function x(){}");var main="${main}"}catch(e){main="${legacy_main}"};var s=document.createElement("script");try{new Function("if(0)import('')")();s.src=main;s.type="module";s.crossOrigin="use-credentials";}catch(e){s.src="${req.baseUrl}/client/shimport@${build_info.shimport}.js";s.setAttribute("data-main",main);}document.head.appendChild(s);}());`;
|
||||
const legacy_main = `${req.baseUrl}/sapper/legacy/${build_info.legacy_assets.main}`;
|
||||
script += `(function(){try{eval("async function x(){}");var main="${main}"}catch(e){main="${legacy_main}"};var s=document.createElement("script");try{new Function("if(0)import('')")();s.src=main;s.type="module";s.crossOrigin="use-credentials";}catch(e){s.src="${req.baseUrl}/sapper/shimport@${build_info.shimport}.js";s.setAttribute("data-main",main);}document.head.appendChild(s);}());`;
|
||||
} else {
|
||||
script += `var s=document.createElement("script");try{new Function("if(0)import('')")();s.src="${main}";s.type="module";s.crossOrigin="use-credentials";}catch(e){s.src="${req.baseUrl}/client/shimport@${build_info.shimport}.js";s.setAttribute("data-main","${main}")}document.head.appendChild(s)`;
|
||||
script += `var s=document.createElement("script");try{new Function("if(0)import('')")();s.src="${main}";s.type="module";s.crossOrigin="use-credentials";}catch(e){s.src="${req.baseUrl}/sapper/shimport@${build_info.shimport}.js";s.setAttribute("data-main","${main}")}document.head.appendChild(s)`;
|
||||
}
|
||||
} else {
|
||||
script += `</script><script src="${main}">`;
|
||||
@@ -308,7 +294,7 @@ export function get_page_handler(
|
||||
});
|
||||
|
||||
styles = Array.from(css_chunks)
|
||||
.map(href => `<link rel="stylesheet" href="client/${href}">`)
|
||||
.map(href => `<link rel="stylesheet" href="sapper/${href}">`)
|
||||
.join('')
|
||||
} else {
|
||||
styles = (css && css.code ? `<style>${css.code}</style>` : '');
|
||||
@@ -327,8 +313,11 @@ export function get_page_handler(
|
||||
res.statusCode = status;
|
||||
res.end(body);
|
||||
} catch(err) {
|
||||
console.log(err);
|
||||
if (error) {
|
||||
bail(req, res, err)
|
||||
// we encountered an error while rendering the error page — oops
|
||||
res.statusCode = 500;
|
||||
res.end(`<pre>${escape_html(err.message)}</pre>`);
|
||||
} else {
|
||||
handle_error(req, res, 500, err);
|
||||
}
|
||||
@@ -337,12 +326,12 @@ export function get_page_handler(
|
||||
|
||||
return function find_route(req: Req, res: Res, next: () => void) {
|
||||
if (req.path === '/service-worker-index.html') {
|
||||
const homePage = pages.find(page => page.pattern.test('/'));
|
||||
const homePage = manifest.pages.find(page => page.pattern.test('/'));
|
||||
handle_page(homePage, req, res);
|
||||
return;
|
||||
}
|
||||
|
||||
for (const page of pages) {
|
||||
for (const page of manifest.pages) {
|
||||
if (page.pattern.test(req.path)) {
|
||||
handle_page(page, req, res);
|
||||
return;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Req, Res, ServerRoute } from './types';
|
||||
import { Req, Res, ServerRoute } from '../types';
|
||||
|
||||
export function get_server_route_handler(routes: ServerRoute[]) {
|
||||
async function handle_route(route: ServerRoute, req: Req, res: Res, next: () => void) {
|
||||
|
||||
@@ -1,23 +1,42 @@
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import querystring from 'querystring';
|
||||
import sirv from 'sirv';
|
||||
import { build_dir, dev, manifest } from '@sapper/internal/manifest-server';
|
||||
import { Handler, Req, Res } from './types';
|
||||
import { Handler, Req, Res, MiddlewareOptions } from '../types';
|
||||
import { get_server_route_handler } from './get_server_route_handler';
|
||||
import { get_page_handler } from './get_page_handler';
|
||||
import { lookup } from './mime';
|
||||
|
||||
export default function middleware(opts: {
|
||||
session?: (req: Req, res: Res) => any,
|
||||
ignore?: any
|
||||
} = {}) {
|
||||
export default function middleware(opts: MiddlewareOptions = {}) {
|
||||
const { session, ignore } = opts;
|
||||
|
||||
let emitted_basepath = false;
|
||||
|
||||
return compose_handlers(ignore, [
|
||||
(req: Req, res: Res, next: () => void) => {
|
||||
fs.existsSync('static') && sirv('static', {
|
||||
dev,
|
||||
setHeaders: opts.static && opts.static.headers && ((res: Response, pathname: string, stats: fs.Stats) => {
|
||||
const headers = opts.static.headers(pathname, stats);
|
||||
for (const k in headers) res.setHeader(k, headers[k]);
|
||||
})
|
||||
}),
|
||||
|
||||
sirv(`${build_dir}/client`, {
|
||||
dev,
|
||||
maxAge: 31536000,
|
||||
immutable: true
|
||||
}),
|
||||
|
||||
sirv(`${build_dir}/service-worker`, {
|
||||
dev,
|
||||
maxAge: 300
|
||||
}),
|
||||
|
||||
function condition_request(req: Req, res: Res, next: () => void) {
|
||||
const qi = req.url.indexOf('?');
|
||||
req.query = ~qi ? querystring.parse(req.url.slice(qi + 1)) : {}
|
||||
|
||||
if (req.baseUrl === undefined) {
|
||||
let { originalUrl } = req;
|
||||
let originalUrl = req.originalUrl || req.url;
|
||||
if (req.url === '/' && originalUrl[originalUrl.length - 1] !== '/') {
|
||||
originalUrl += '/';
|
||||
}
|
||||
@@ -44,21 +63,6 @@ export default function middleware(opts: {
|
||||
next();
|
||||
},
|
||||
|
||||
fs.existsSync(path.join(build_dir, 'service-worker.js')) && serve({
|
||||
pathname: '/service-worker.js',
|
||||
cache_control: 'no-cache, no-store, must-revalidate'
|
||||
}),
|
||||
|
||||
fs.existsSync(path.join(build_dir, 'service-worker.js.map')) && serve({
|
||||
pathname: '/service-worker.js.map',
|
||||
cache_control: 'no-cache, no-store, must-revalidate'
|
||||
}),
|
||||
|
||||
serve({
|
||||
prefix: '/client/',
|
||||
cache_control: dev ? 'no-cache' : 'max-age=31536000, immutable'
|
||||
}),
|
||||
|
||||
get_server_route_handler(manifest.server_routes),
|
||||
|
||||
get_page_handler(manifest, session || noop)
|
||||
@@ -94,40 +98,4 @@ export function should_ignore(uri: string, val: any) {
|
||||
return uri.startsWith(val.charCodeAt(0) === 47 ? val : `/${val}`);
|
||||
}
|
||||
|
||||
export function serve({ prefix, pathname, cache_control }: {
|
||||
prefix?: string,
|
||||
pathname?: string,
|
||||
cache_control: string
|
||||
}) {
|
||||
const filter = pathname
|
||||
? (req: Req) => req.path === pathname
|
||||
: (req: Req) => req.path.startsWith(prefix);
|
||||
|
||||
const cache: Map<string, Buffer> = new Map();
|
||||
|
||||
const read = dev
|
||||
? (file: string) => fs.readFileSync(path.resolve(build_dir, file))
|
||||
: (file: string) => (cache.has(file) ? cache : cache.set(file, fs.readFileSync(path.resolve(build_dir, file)))).get(file)
|
||||
|
||||
return (req: Req, res: Res, next: () => void) => {
|
||||
if (filter(req)) {
|
||||
const type = lookup(req.path);
|
||||
|
||||
try {
|
||||
const file = decodeURIComponent(req.path.slice(1));
|
||||
const data = read(file);
|
||||
|
||||
res.setHeader('Content-Type', type);
|
||||
res.setHeader('Cache-Control', cache_control);
|
||||
res.end(data);
|
||||
} catch (err) {
|
||||
res.statusCode = 404;
|
||||
res.end('not found');
|
||||
}
|
||||
} else {
|
||||
next();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function noop(){}
|
||||
|
||||
@@ -1,767 +0,0 @@
|
||||
application/andrew-inset ez
|
||||
application/applixware aw
|
||||
application/atom+xml atom
|
||||
application/atomcat+xml atomcat
|
||||
application/atomsvc+xml atomsvc
|
||||
application/ccxml+xml ccxml
|
||||
application/cdmi-capability cdmia
|
||||
application/cdmi-container cdmic
|
||||
application/cdmi-domain cdmid
|
||||
application/cdmi-object cdmio
|
||||
application/cdmi-queue cdmiq
|
||||
application/cu-seeme cu
|
||||
application/davmount+xml davmount
|
||||
application/docbook+xml dbk
|
||||
application/dssc+der dssc
|
||||
application/dssc+xml xdssc
|
||||
application/ecmascript ecma
|
||||
application/emma+xml emma
|
||||
application/epub+zip epub
|
||||
application/exi exi
|
||||
application/font-tdpfr pfr
|
||||
application/gml+xml gml
|
||||
application/gpx+xml gpx
|
||||
application/gxf gxf
|
||||
application/hyperstudio stk
|
||||
application/inkml+xml ink inkml
|
||||
application/ipfix ipfix
|
||||
application/java-archive jar
|
||||
application/java-serialized-object ser
|
||||
application/java-vm class
|
||||
application/javascript js
|
||||
application/json json map
|
||||
application/jsonml+json jsonml
|
||||
application/lost+xml lostxml
|
||||
application/mac-binhex40 hqx
|
||||
application/mac-compactpro cpt
|
||||
application/mads+xml mads
|
||||
application/marc mrc
|
||||
application/marcxml+xml mrcx
|
||||
application/mathematica ma nb mb
|
||||
application/mathml+xml mathml
|
||||
application/mbox mbox
|
||||
application/mediaservercontrol+xml mscml
|
||||
application/metalink+xml metalink
|
||||
application/metalink4+xml meta4
|
||||
application/mets+xml mets
|
||||
application/mods+xml mods
|
||||
application/mp21 m21 mp21
|
||||
application/mp4 mp4s
|
||||
application/msword doc dot
|
||||
application/mxf mxf
|
||||
application/octet-stream bin dms lrf mar so dist distz pkg bpk dump elc deploy
|
||||
application/oda oda
|
||||
application/oebps-package+xml opf
|
||||
application/ogg ogx
|
||||
application/omdoc+xml omdoc
|
||||
application/onenote onetoc onetoc2 onetmp onepkg
|
||||
application/oxps oxps
|
||||
application/patch-ops-error+xml xer
|
||||
application/pdf pdf
|
||||
application/pgp-encrypted pgp
|
||||
application/pgp-signature asc sig
|
||||
application/pics-rules prf
|
||||
application/pkcs10 p10
|
||||
application/pkcs7-mime p7m p7c
|
||||
application/pkcs7-signature p7s
|
||||
application/pkcs8 p8
|
||||
application/pkix-attr-cert ac
|
||||
application/pkix-cert cer
|
||||
application/pkix-crl crl
|
||||
application/pkix-pkipath pkipath
|
||||
application/pkixcmp pki
|
||||
application/pls+xml pls
|
||||
application/postscript ai eps ps
|
||||
application/prs.cww cww
|
||||
application/pskc+xml pskcxml
|
||||
application/rdf+xml rdf
|
||||
application/reginfo+xml rif
|
||||
application/relax-ng-compact-syntax rnc
|
||||
application/resource-lists+xml rl
|
||||
application/resource-lists-diff+xml rld
|
||||
application/rls-services+xml rs
|
||||
application/rpki-ghostbusters gbr
|
||||
application/rpki-manifest mft
|
||||
application/rpki-roa roa
|
||||
application/rsd+xml rsd
|
||||
application/rss+xml rss
|
||||
application/rtf rtf
|
||||
application/sbml+xml sbml
|
||||
application/scvp-cv-request scq
|
||||
application/scvp-cv-response scs
|
||||
application/scvp-vp-request spq
|
||||
application/scvp-vp-response spp
|
||||
application/sdp sdp
|
||||
application/set-payment-initiation setpay
|
||||
application/set-registration-initiation setreg
|
||||
application/shf+xml shf
|
||||
application/smil+xml smi smil
|
||||
application/sparql-query rq
|
||||
application/sparql-results+xml srx
|
||||
application/srgs gram
|
||||
application/srgs+xml grxml
|
||||
application/sru+xml sru
|
||||
application/ssdl+xml ssdl
|
||||
application/ssml+xml ssml
|
||||
application/tei+xml tei teicorpus
|
||||
application/thraud+xml tfi
|
||||
application/timestamped-data tsd
|
||||
application/vnd.3gpp.pic-bw-large plb
|
||||
application/vnd.3gpp.pic-bw-small psb
|
||||
application/vnd.3gpp.pic-bw-var pvb
|
||||
application/vnd.3gpp2.tcap tcap
|
||||
application/vnd.3m.post-it-notes pwn
|
||||
application/vnd.accpac.simply.aso aso
|
||||
application/vnd.accpac.simply.imp imp
|
||||
application/vnd.acucobol acu
|
||||
application/vnd.acucorp atc acutc
|
||||
application/vnd.adobe.air-application-installer-package+zip air
|
||||
application/vnd.adobe.formscentral.fcdt fcdt
|
||||
application/vnd.adobe.fxp fxp fxpl
|
||||
application/vnd.adobe.xdp+xml xdp
|
||||
application/vnd.adobe.xfdf xfdf
|
||||
application/vnd.ahead.space ahead
|
||||
application/vnd.airzip.filesecure.azf azf
|
||||
application/vnd.airzip.filesecure.azs azs
|
||||
application/vnd.amazon.ebook azw
|
||||
application/vnd.americandynamics.acc acc
|
||||
application/vnd.amiga.ami ami
|
||||
application/vnd.android.package-archive apk
|
||||
application/vnd.anser-web-certificate-issue-initiation cii
|
||||
application/vnd.anser-web-funds-transfer-initiation fti
|
||||
application/vnd.antix.game-component atx
|
||||
application/vnd.apple.installer+xml mpkg
|
||||
application/vnd.apple.mpegurl m3u8
|
||||
application/vnd.aristanetworks.swi swi
|
||||
application/vnd.astraea-software.iota iota
|
||||
application/vnd.audiograph aep
|
||||
application/vnd.blueice.multipass mpm
|
||||
application/vnd.bmi bmi
|
||||
application/vnd.businessobjects rep
|
||||
application/vnd.chemdraw+xml cdxml
|
||||
application/vnd.chipnuts.karaoke-mmd mmd
|
||||
application/vnd.cinderella cdy
|
||||
application/vnd.claymore cla
|
||||
application/vnd.cloanto.rp9 rp9
|
||||
application/vnd.clonk.c4group c4g c4d c4f c4p c4u
|
||||
application/vnd.cluetrust.cartomobile-config c11amc
|
||||
application/vnd.cluetrust.cartomobile-config-pkg c11amz
|
||||
application/vnd.commonspace csp
|
||||
application/vnd.contact.cmsg cdbcmsg
|
||||
application/vnd.cosmocaller cmc
|
||||
application/vnd.crick.clicker clkx
|
||||
application/vnd.crick.clicker.keyboard clkk
|
||||
application/vnd.crick.clicker.palette clkp
|
||||
application/vnd.crick.clicker.template clkt
|
||||
application/vnd.crick.clicker.wordbank clkw
|
||||
application/vnd.criticaltools.wbs+xml wbs
|
||||
application/vnd.ctc-posml pml
|
||||
application/vnd.cups-ppd ppd
|
||||
application/vnd.curl.car car
|
||||
application/vnd.curl.pcurl pcurl
|
||||
application/vnd.dart dart
|
||||
application/vnd.data-vision.rdz rdz
|
||||
application/vnd.dece.data uvf uvvf uvd uvvd
|
||||
application/vnd.dece.ttml+xml uvt uvvt
|
||||
application/vnd.dece.unspecified uvx uvvx
|
||||
application/vnd.dece.zip uvz uvvz
|
||||
application/vnd.denovo.fcselayout-link fe_launch
|
||||
application/vnd.dna dna
|
||||
application/vnd.dolby.mlp mlp
|
||||
application/vnd.dpgraph dpg
|
||||
application/vnd.dreamfactory dfac
|
||||
application/vnd.ds-keypoint kpxx
|
||||
application/vnd.dvb.ait ait
|
||||
application/vnd.dvb.service svc
|
||||
application/vnd.dynageo geo
|
||||
application/vnd.ecowin.chart mag
|
||||
application/vnd.enliven nml
|
||||
application/vnd.epson.esf esf
|
||||
application/vnd.epson.msf msf
|
||||
application/vnd.epson.quickanime qam
|
||||
application/vnd.epson.salt slt
|
||||
application/vnd.epson.ssf ssf
|
||||
application/vnd.eszigno3+xml es3 et3
|
||||
application/vnd.ezpix-album ez2
|
||||
application/vnd.ezpix-package ez3
|
||||
application/vnd.fdf fdf
|
||||
application/vnd.fdsn.mseed mseed
|
||||
application/vnd.fdsn.seed seed dataless
|
||||
application/vnd.flographit gph
|
||||
application/vnd.fluxtime.clip ftc
|
||||
application/vnd.framemaker fm frame maker book
|
||||
application/vnd.frogans.fnc fnc
|
||||
application/vnd.frogans.ltf ltf
|
||||
application/vnd.fsc.weblaunch fsc
|
||||
application/vnd.fujitsu.oasys oas
|
||||
application/vnd.fujitsu.oasys2 oa2
|
||||
application/vnd.fujitsu.oasys3 oa3
|
||||
application/vnd.fujitsu.oasysgp fg5
|
||||
application/vnd.fujitsu.oasysprs bh2
|
||||
application/vnd.fujixerox.ddd ddd
|
||||
application/vnd.fujixerox.docuworks xdw
|
||||
application/vnd.fujixerox.docuworks.binder xbd
|
||||
application/vnd.fuzzysheet fzs
|
||||
application/vnd.genomatix.tuxedo txd
|
||||
application/vnd.geogebra.file ggb
|
||||
application/vnd.geogebra.tool ggt
|
||||
application/vnd.geometry-explorer gex gre
|
||||
application/vnd.geonext gxt
|
||||
application/vnd.geoplan g2w
|
||||
application/vnd.geospace g3w
|
||||
application/vnd.gmx gmx
|
||||
application/vnd.google-earth.kml+xml kml
|
||||
application/vnd.google-earth.kmz kmz
|
||||
application/vnd.grafeq gqf gqs
|
||||
application/vnd.groove-account gac
|
||||
application/vnd.groove-help ghf
|
||||
application/vnd.groove-identity-message gim
|
||||
application/vnd.groove-injector grv
|
||||
application/vnd.groove-tool-message gtm
|
||||
application/vnd.groove-tool-template tpl
|
||||
application/vnd.groove-vcard vcg
|
||||
application/vnd.hal+xml hal
|
||||
application/vnd.handheld-entertainment+xml zmm
|
||||
application/vnd.hbci hbci
|
||||
application/vnd.hhe.lesson-player les
|
||||
application/vnd.hp-hpgl hpgl
|
||||
application/vnd.hp-hpid hpid
|
||||
application/vnd.hp-hps hps
|
||||
application/vnd.hp-jlyt jlt
|
||||
application/vnd.hp-pcl pcl
|
||||
application/vnd.hp-pclxl pclxl
|
||||
application/vnd.hydrostatix.sof-data sfd-hdstx
|
||||
application/vnd.ibm.minipay mpy
|
||||
application/vnd.ibm.modcap afp listafp list3820
|
||||
application/vnd.ibm.rights-management irm
|
||||
application/vnd.ibm.secure-container sc
|
||||
application/vnd.iccprofile icc icm
|
||||
application/vnd.igloader igl
|
||||
application/vnd.immervision-ivp ivp
|
||||
application/vnd.immervision-ivu ivu
|
||||
application/vnd.insors.igm igm
|
||||
application/vnd.intercon.formnet xpw xpx
|
||||
application/vnd.intergeo i2g
|
||||
application/vnd.intu.qbo qbo
|
||||
application/vnd.intu.qfx qfx
|
||||
application/vnd.ipunplugged.rcprofile rcprofile
|
||||
application/vnd.irepository.package+xml irp
|
||||
application/vnd.is-xpr xpr
|
||||
application/vnd.isac.fcs fcs
|
||||
application/vnd.jam jam
|
||||
application/vnd.jcp.javame.midlet-rms rms
|
||||
application/vnd.jisp jisp
|
||||
application/vnd.joost.joda-archive joda
|
||||
application/vnd.kahootz ktz ktr
|
||||
application/vnd.kde.karbon karbon
|
||||
application/vnd.kde.kchart chrt
|
||||
application/vnd.kde.kformula kfo
|
||||
application/vnd.kde.kivio flw
|
||||
application/vnd.kde.kontour kon
|
||||
application/vnd.kde.kpresenter kpr kpt
|
||||
application/vnd.kde.kspread ksp
|
||||
application/vnd.kde.kword kwd kwt
|
||||
application/vnd.kenameaapp htke
|
||||
application/vnd.kidspiration kia
|
||||
application/vnd.kinar kne knp
|
||||
application/vnd.koan skp skd skt skm
|
||||
application/vnd.kodak-descriptor sse
|
||||
application/vnd.las.las+xml lasxml
|
||||
application/vnd.llamagraphics.life-balance.desktop lbd
|
||||
application/vnd.llamagraphics.life-balance.exchange+xml lbe
|
||||
application/vnd.lotus-1-2-3 123
|
||||
application/vnd.lotus-approach apr
|
||||
application/vnd.lotus-freelance pre
|
||||
application/vnd.lotus-notes nsf
|
||||
application/vnd.lotus-organizer org
|
||||
application/vnd.lotus-screencam scm
|
||||
application/vnd.lotus-wordpro lwp
|
||||
application/vnd.macports.portpkg portpkg
|
||||
application/vnd.mcd mcd
|
||||
application/vnd.medcalcdata mc1
|
||||
application/vnd.mediastation.cdkey cdkey
|
||||
application/vnd.mfer mwf
|
||||
application/vnd.mfmp mfm
|
||||
application/vnd.micrografx.flo flo
|
||||
application/vnd.micrografx.igx igx
|
||||
application/vnd.mif mif
|
||||
application/vnd.mobius.daf daf
|
||||
application/vnd.mobius.dis dis
|
||||
application/vnd.mobius.mbk mbk
|
||||
application/vnd.mobius.mqy mqy
|
||||
application/vnd.mobius.msl msl
|
||||
application/vnd.mobius.plc plc
|
||||
application/vnd.mobius.txf txf
|
||||
application/vnd.mophun.application mpn
|
||||
application/vnd.mophun.certificate mpc
|
||||
application/vnd.mozilla.xul+xml xul
|
||||
application/vnd.ms-artgalry cil
|
||||
application/vnd.ms-cab-compressed cab
|
||||
application/vnd.ms-excel xls xlm xla xlc xlt xlw
|
||||
application/vnd.ms-excel.addin.macroenabled.12 xlam
|
||||
application/vnd.ms-excel.sheet.binary.macroenabled.12 xlsb
|
||||
application/vnd.ms-excel.sheet.macroenabled.12 xlsm
|
||||
application/vnd.ms-excel.template.macroenabled.12 xltm
|
||||
application/vnd.ms-fontobject eot
|
||||
application/vnd.ms-htmlhelp chm
|
||||
application/vnd.ms-ims ims
|
||||
application/vnd.ms-lrm lrm
|
||||
application/vnd.ms-officetheme thmx
|
||||
application/vnd.ms-pki.seccat cat
|
||||
application/vnd.ms-pki.stl stl
|
||||
application/vnd.ms-powerpoint ppt pps pot
|
||||
application/vnd.ms-powerpoint.addin.macroenabled.12 ppam
|
||||
application/vnd.ms-powerpoint.presentation.macroenabled.12 pptm
|
||||
application/vnd.ms-powerpoint.slide.macroenabled.12 sldm
|
||||
application/vnd.ms-powerpoint.slideshow.macroenabled.12 ppsm
|
||||
application/vnd.ms-powerpoint.template.macroenabled.12 potm
|
||||
application/vnd.ms-project mpp mpt
|
||||
application/vnd.ms-word.document.macroenabled.12 docm
|
||||
application/vnd.ms-word.template.macroenabled.12 dotm
|
||||
application/vnd.ms-works wps wks wcm wdb
|
||||
application/vnd.ms-wpl wpl
|
||||
application/vnd.ms-xpsdocument xps
|
||||
application/vnd.mseq mseq
|
||||
application/vnd.musician mus
|
||||
application/vnd.muvee.style msty
|
||||
application/vnd.mynfc taglet
|
||||
application/vnd.neurolanguage.nlu nlu
|
||||
application/vnd.nitf ntf nitf
|
||||
application/vnd.noblenet-directory nnd
|
||||
application/vnd.noblenet-sealer nns
|
||||
application/vnd.noblenet-web nnw
|
||||
application/vnd.nokia.n-gage.data ngdat
|
||||
application/vnd.nokia.n-gage.symbian.install n-gage
|
||||
application/vnd.nokia.radio-preset rpst
|
||||
application/vnd.nokia.radio-presets rpss
|
||||
application/vnd.novadigm.edm edm
|
||||
application/vnd.novadigm.edx edx
|
||||
application/vnd.novadigm.ext ext
|
||||
application/vnd.oasis.opendocument.chart odc
|
||||
application/vnd.oasis.opendocument.chart-template otc
|
||||
application/vnd.oasis.opendocument.database odb
|
||||
application/vnd.oasis.opendocument.formula odf
|
||||
application/vnd.oasis.opendocument.formula-template odft
|
||||
application/vnd.oasis.opendocument.graphics odg
|
||||
application/vnd.oasis.opendocument.graphics-template otg
|
||||
application/vnd.oasis.opendocument.image odi
|
||||
application/vnd.oasis.opendocument.image-template oti
|
||||
application/vnd.oasis.opendocument.presentation odp
|
||||
application/vnd.oasis.opendocument.presentation-template otp
|
||||
application/vnd.oasis.opendocument.spreadsheet ods
|
||||
application/vnd.oasis.opendocument.spreadsheet-template ots
|
||||
application/vnd.oasis.opendocument.text odt
|
||||
application/vnd.oasis.opendocument.text-master odm
|
||||
application/vnd.oasis.opendocument.text-template ott
|
||||
application/vnd.oasis.opendocument.text-web oth
|
||||
application/vnd.olpc-sugar xo
|
||||
application/vnd.oma.dd2+xml dd2
|
||||
application/vnd.openofficeorg.extension oxt
|
||||
application/vnd.openxmlformats-officedocument.presentationml.presentation pptx
|
||||
application/vnd.openxmlformats-officedocument.presentationml.slide sldx
|
||||
application/vnd.openxmlformats-officedocument.presentationml.slideshow ppsx
|
||||
application/vnd.openxmlformats-officedocument.presentationml.template potx
|
||||
application/vnd.openxmlformats-officedocument.spreadsheetml.sheet xlsx
|
||||
application/vnd.openxmlformats-officedocument.spreadsheetml.template xltx
|
||||
application/vnd.openxmlformats-officedocument.wordprocessingml.document docx
|
||||
application/vnd.openxmlformats-officedocument.wordprocessingml.template dotx
|
||||
application/vnd.osgeo.mapguide.package mgp
|
||||
application/vnd.osgi.dp dp
|
||||
application/vnd.osgi.subsystem esa
|
||||
application/vnd.palm pdb pqa oprc
|
||||
application/vnd.pawaafile paw
|
||||
application/vnd.pg.format str
|
||||
application/vnd.pg.osasli ei6
|
||||
application/vnd.picsel efif
|
||||
application/vnd.pmi.widget wg
|
||||
application/vnd.pocketlearn plf
|
||||
application/vnd.powerbuilder6 pbd
|
||||
application/vnd.previewsystems.box box
|
||||
application/vnd.proteus.magazine mgz
|
||||
application/vnd.publishare-delta-tree qps
|
||||
application/vnd.pvi.ptid1 ptid
|
||||
application/vnd.quark.quarkxpress qxd qxt qwd qwt qxl qxb
|
||||
application/vnd.realvnc.bed bed
|
||||
application/vnd.recordare.musicxml mxl
|
||||
application/vnd.recordare.musicxml+xml musicxml
|
||||
application/vnd.rig.cryptonote cryptonote
|
||||
application/vnd.rim.cod cod
|
||||
application/vnd.rn-realmedia rm
|
||||
application/vnd.rn-realmedia-vbr rmvb
|
||||
application/vnd.route66.link66+xml link66
|
||||
application/vnd.sailingtracker.track st
|
||||
application/vnd.seemail see
|
||||
application/vnd.sema sema
|
||||
application/vnd.semd semd
|
||||
application/vnd.semf semf
|
||||
application/vnd.shana.informed.formdata ifm
|
||||
application/vnd.shana.informed.formtemplate itp
|
||||
application/vnd.shana.informed.interchange iif
|
||||
application/vnd.shana.informed.package ipk
|
||||
application/vnd.simtech-mindmapper twd twds
|
||||
application/vnd.smaf mmf
|
||||
application/vnd.smart.teacher teacher
|
||||
application/vnd.solent.sdkm+xml sdkm sdkd
|
||||
application/vnd.spotfire.dxp dxp
|
||||
application/vnd.spotfire.sfs sfs
|
||||
application/vnd.stardivision.calc sdc
|
||||
application/vnd.stardivision.draw sda
|
||||
application/vnd.stardivision.impress sdd
|
||||
application/vnd.stardivision.math smf
|
||||
application/vnd.stardivision.writer sdw vor
|
||||
application/vnd.stardivision.writer-global sgl
|
||||
application/vnd.stepmania.package smzip
|
||||
application/vnd.stepmania.stepchart sm
|
||||
application/vnd.sun.xml.calc sxc
|
||||
application/vnd.sun.xml.calc.template stc
|
||||
application/vnd.sun.xml.draw sxd
|
||||
application/vnd.sun.xml.draw.template std
|
||||
application/vnd.sun.xml.impress sxi
|
||||
application/vnd.sun.xml.impress.template sti
|
||||
application/vnd.sun.xml.math sxm
|
||||
application/vnd.sun.xml.writer sxw
|
||||
application/vnd.sun.xml.writer.global sxg
|
||||
application/vnd.sun.xml.writer.template stw
|
||||
application/vnd.sus-calendar sus susp
|
||||
application/vnd.svd svd
|
||||
application/vnd.symbian.install sis sisx
|
||||
application/vnd.syncml+xml xsm
|
||||
application/vnd.syncml.dm+wbxml bdm
|
||||
application/vnd.syncml.dm+xml xdm
|
||||
application/vnd.tao.intent-module-archive tao
|
||||
application/vnd.tcpdump.pcap pcap cap dmp
|
||||
application/vnd.tmobile-livetv tmo
|
||||
application/vnd.trid.tpt tpt
|
||||
application/vnd.triscape.mxs mxs
|
||||
application/vnd.trueapp tra
|
||||
application/vnd.ufdl ufd ufdl
|
||||
application/vnd.uiq.theme utz
|
||||
application/vnd.umajin umj
|
||||
application/vnd.unity unityweb
|
||||
application/vnd.uoml+xml uoml
|
||||
application/vnd.vcx vcx
|
||||
application/vnd.visio vsd vst vss vsw
|
||||
application/vnd.visionary vis
|
||||
application/vnd.vsf vsf
|
||||
application/vnd.wap.wbxml wbxml
|
||||
application/vnd.wap.wmlc wmlc
|
||||
application/vnd.wap.wmlscriptc wmlsc
|
||||
application/vnd.webturbo wtb
|
||||
application/vnd.wolfram.player nbp
|
||||
application/vnd.wordperfect wpd
|
||||
application/vnd.wqd wqd
|
||||
application/vnd.wt.stf stf
|
||||
application/vnd.xara xar
|
||||
application/vnd.xfdl xfdl
|
||||
application/vnd.yamaha.hv-dic hvd
|
||||
application/vnd.yamaha.hv-script hvs
|
||||
application/vnd.yamaha.hv-voice hvp
|
||||
application/vnd.yamaha.openscoreformat osf
|
||||
application/vnd.yamaha.openscoreformat.osfpvg+xml osfpvg
|
||||
application/vnd.yamaha.smaf-audio saf
|
||||
application/vnd.yamaha.smaf-phrase spf
|
||||
application/vnd.yellowriver-custom-menu cmp
|
||||
application/vnd.zul zir zirz
|
||||
application/vnd.zzazz.deck+xml zaz
|
||||
application/voicexml+xml vxml
|
||||
application/widget wgt
|
||||
application/winhlp hlp
|
||||
application/wsdl+xml wsdl
|
||||
application/wspolicy+xml wspolicy
|
||||
application/x-7z-compressed 7z
|
||||
application/x-abiword abw
|
||||
application/x-ace-compressed ace
|
||||
application/x-apple-diskimage dmg
|
||||
application/x-authorware-bin aab x32 u32 vox
|
||||
application/x-authorware-map aam
|
||||
application/x-authorware-seg aas
|
||||
application/x-bcpio bcpio
|
||||
application/x-bittorrent torrent
|
||||
application/x-blorb blb blorb
|
||||
application/x-bzip bz
|
||||
application/x-bzip2 bz2 boz
|
||||
application/x-cbr cbr cba cbt cbz cb7
|
||||
application/x-cdlink vcd
|
||||
application/x-cfs-compressed cfs
|
||||
application/x-chat chat
|
||||
application/x-chess-pgn pgn
|
||||
application/x-conference nsc
|
||||
application/x-cpio cpio
|
||||
application/x-csh csh
|
||||
application/x-debian-package deb udeb
|
||||
application/x-dgc-compressed dgc
|
||||
application/x-director dir dcr dxr cst cct cxt w3d fgd swa
|
||||
application/x-doom wad
|
||||
application/x-dtbncx+xml ncx
|
||||
application/x-dtbook+xml dtb
|
||||
application/x-dtbresource+xml res
|
||||
application/x-dvi dvi
|
||||
application/x-envoy evy
|
||||
application/x-eva eva
|
||||
application/x-font-bdf bdf
|
||||
application/x-font-ghostscript gsf
|
||||
application/x-font-linux-psf psf
|
||||
application/x-font-pcf pcf
|
||||
application/x-font-snf snf
|
||||
application/x-font-type1 pfa pfb pfm afm
|
||||
application/x-freearc arc
|
||||
application/x-futuresplash spl
|
||||
application/x-gca-compressed gca
|
||||
application/x-glulx ulx
|
||||
application/x-gnumeric gnumeric
|
||||
application/x-gramps-xml gramps
|
||||
application/x-gtar gtar
|
||||
application/x-hdf hdf
|
||||
application/x-install-instructions install
|
||||
application/x-iso9660-image iso
|
||||
application/x-java-jnlp-file jnlp
|
||||
application/x-latex latex
|
||||
application/x-lzh-compressed lzh lha
|
||||
application/x-mie mie
|
||||
application/x-mobipocket-ebook prc mobi
|
||||
application/x-ms-application application
|
||||
application/x-ms-shortcut lnk
|
||||
application/x-ms-wmd wmd
|
||||
application/x-ms-wmz wmz
|
||||
application/x-ms-xbap xbap
|
||||
application/x-msaccess mdb
|
||||
application/x-msbinder obd
|
||||
application/x-mscardfile crd
|
||||
application/x-msclip clp
|
||||
application/x-msdownload exe dll com bat msi
|
||||
application/x-msmediaview mvb m13 m14
|
||||
application/x-msmetafile wmf wmz emf emz
|
||||
application/x-msmoney mny
|
||||
application/x-mspublisher pub
|
||||
application/x-msschedule scd
|
||||
application/x-msterminal trm
|
||||
application/x-mswrite wri
|
||||
application/x-netcdf nc cdf
|
||||
application/x-nzb nzb
|
||||
application/x-pkcs12 p12 pfx
|
||||
application/x-pkcs7-certificates p7b spc
|
||||
application/x-pkcs7-certreqresp p7r
|
||||
application/x-rar-compressed rar
|
||||
application/x-research-info-systems ris
|
||||
application/x-sh sh
|
||||
application/x-shar shar
|
||||
application/x-shockwave-flash swf
|
||||
application/x-silverlight-app xap
|
||||
application/x-sql sql
|
||||
application/x-stuffit sit
|
||||
application/x-stuffitx sitx
|
||||
application/x-subrip srt
|
||||
application/x-sv4cpio sv4cpio
|
||||
application/x-sv4crc sv4crc
|
||||
application/x-t3vm-image t3
|
||||
application/x-tads gam
|
||||
application/x-tar tar
|
||||
application/x-tcl tcl
|
||||
application/x-tex tex
|
||||
application/x-tex-tfm tfm
|
||||
application/x-texinfo texinfo texi
|
||||
application/x-tgif obj
|
||||
application/x-ustar ustar
|
||||
application/x-wais-source src
|
||||
application/x-x509-ca-cert der crt
|
||||
application/x-xfig fig
|
||||
application/x-xliff+xml xlf
|
||||
application/x-xpinstall xpi
|
||||
application/x-xz xz
|
||||
application/x-zmachine z1 z2 z3 z4 z5 z6 z7 z8
|
||||
application/xaml+xml xaml
|
||||
application/xcap-diff+xml xdf
|
||||
application/xenc+xml xenc
|
||||
application/xhtml+xml xhtml xht
|
||||
application/xml xml xsl
|
||||
application/xml-dtd dtd
|
||||
application/xop+xml xop
|
||||
application/xproc+xml xpl
|
||||
application/xslt+xml xslt
|
||||
application/xspf+xml xspf
|
||||
application/xv+xml mxml xhvml xvml xvm
|
||||
application/yang yang
|
||||
application/yin+xml yin
|
||||
application/zip zip
|
||||
audio/adpcm adp
|
||||
audio/basic au snd
|
||||
audio/midi mid midi kar rmi
|
||||
audio/mp4 m4a mp4a
|
||||
audio/mpeg mpga mp2 mp2a mp3 m2a m3a
|
||||
audio/ogg oga ogg spx
|
||||
audio/s3m s3m
|
||||
audio/silk sil
|
||||
audio/vnd.dece.audio uva uvva
|
||||
audio/vnd.digital-winds eol
|
||||
audio/vnd.dra dra
|
||||
audio/vnd.dts dts
|
||||
audio/vnd.dts.hd dtshd
|
||||
audio/vnd.lucent.voice lvp
|
||||
audio/vnd.ms-playready.media.pya pya
|
||||
audio/vnd.nuera.ecelp4800 ecelp4800
|
||||
audio/vnd.nuera.ecelp7470 ecelp7470
|
||||
audio/vnd.nuera.ecelp9600 ecelp9600
|
||||
audio/vnd.rip rip
|
||||
audio/webm weba
|
||||
audio/x-aac aac
|
||||
audio/x-aiff aif aiff aifc
|
||||
audio/x-caf caf
|
||||
audio/x-flac flac
|
||||
audio/x-matroska mka
|
||||
audio/x-mpegurl m3u
|
||||
audio/x-ms-wax wax
|
||||
audio/x-ms-wma wma
|
||||
audio/x-pn-realaudio ram ra
|
||||
audio/x-pn-realaudio-plugin rmp
|
||||
audio/x-wav wav
|
||||
audio/xm xm
|
||||
chemical/x-cdx cdx
|
||||
chemical/x-cif cif
|
||||
chemical/x-cmdf cmdf
|
||||
chemical/x-cml cml
|
||||
chemical/x-csml csml
|
||||
chemical/x-xyz xyz
|
||||
font/collection ttc
|
||||
font/otf otf
|
||||
font/ttf ttf
|
||||
font/woff woff
|
||||
font/woff2 woff2
|
||||
image/bmp bmp
|
||||
image/cgm cgm
|
||||
image/g3fax g3
|
||||
image/gif gif
|
||||
image/ief ief
|
||||
image/jpeg jpeg jpg jpe
|
||||
image/ktx ktx
|
||||
image/png png
|
||||
image/prs.btif btif
|
||||
image/sgi sgi
|
||||
image/svg+xml svg svgz
|
||||
image/tiff tiff tif
|
||||
image/vnd.adobe.photoshop psd
|
||||
image/vnd.dece.graphic uvi uvvi uvg uvvg
|
||||
image/vnd.djvu djvu djv
|
||||
image/vnd.dvb.subtitle sub
|
||||
image/vnd.dwg dwg
|
||||
image/vnd.dxf dxf
|
||||
image/vnd.fastbidsheet fbs
|
||||
image/vnd.fpx fpx
|
||||
image/vnd.fst fst
|
||||
image/vnd.fujixerox.edmics-mmr mmr
|
||||
image/vnd.fujixerox.edmics-rlc rlc
|
||||
image/vnd.ms-modi mdi
|
||||
image/vnd.ms-photo wdp
|
||||
image/vnd.net-fpx npx
|
||||
image/vnd.wap.wbmp wbmp
|
||||
image/vnd.xiff xif
|
||||
image/webp webp
|
||||
image/x-3ds 3ds
|
||||
image/x-cmu-raster ras
|
||||
image/x-cmx cmx
|
||||
image/x-freehand fh fhc fh4 fh5 fh7
|
||||
image/x-icon ico
|
||||
image/x-mrsid-image sid
|
||||
image/x-pcx pcx
|
||||
image/x-pict pic pct
|
||||
image/x-portable-anymap pnm
|
||||
image/x-portable-bitmap pbm
|
||||
image/x-portable-graymap pgm
|
||||
image/x-portable-pixmap ppm
|
||||
image/x-rgb rgb
|
||||
image/x-tga tga
|
||||
image/x-xbitmap xbm
|
||||
image/x-xpixmap xpm
|
||||
image/x-xwindowdump xwd
|
||||
message/rfc822 eml mime
|
||||
model/iges igs iges
|
||||
model/mesh msh mesh silo
|
||||
model/vnd.collada+xml dae
|
||||
model/vnd.dwf dwf
|
||||
model/vnd.gdl gdl
|
||||
model/vnd.gtw gtw
|
||||
model/vnd.mts mts
|
||||
model/vnd.vtu vtu
|
||||
model/vrml wrl vrml
|
||||
model/x3d+binary x3db x3dbz
|
||||
model/x3d+vrml x3dv x3dvz
|
||||
model/x3d+xml x3d x3dz
|
||||
text/cache-manifest appcache
|
||||
text/calendar ics ifb
|
||||
text/css css
|
||||
text/csv csv
|
||||
text/html html htm
|
||||
text/n3 n3
|
||||
text/plain txt text conf def list log in
|
||||
text/prs.lines.tag dsc
|
||||
text/richtext rtx
|
||||
text/sgml sgml sgm
|
||||
text/tab-separated-values tsv
|
||||
text/troff t tr roff man me ms
|
||||
text/turtle ttl
|
||||
text/uri-list uri uris urls
|
||||
text/vcard vcard
|
||||
text/vnd.curl curl
|
||||
text/vnd.curl.dcurl dcurl
|
||||
text/vnd.curl.mcurl mcurl
|
||||
text/vnd.curl.scurl scurl
|
||||
text/vnd.dvb.subtitle sub
|
||||
text/vnd.fly fly
|
||||
text/vnd.fmi.flexstor flx
|
||||
text/vnd.graphviz gv
|
||||
text/vnd.in3d.3dml 3dml
|
||||
text/vnd.in3d.spot spot
|
||||
text/vnd.sun.j2me.app-descriptor jad
|
||||
text/vnd.wap.wml wml
|
||||
text/vnd.wap.wmlscript wmls
|
||||
text/x-asm s asm
|
||||
text/x-c c cc cxx cpp h hh dic
|
||||
text/x-fortran f for f77 f90
|
||||
text/x-java-source java
|
||||
text/x-nfo nfo
|
||||
text/x-opml opml
|
||||
text/x-pascal p pas
|
||||
text/x-setext etx
|
||||
text/x-sfv sfv
|
||||
text/x-uuencode uu
|
||||
text/x-vcalendar vcs
|
||||
text/x-vcard vcf
|
||||
video/3gpp 3gp
|
||||
video/3gpp2 3g2
|
||||
video/h261 h261
|
||||
video/h263 h263
|
||||
video/h264 h264
|
||||
video/jpeg jpgv
|
||||
video/jpm jpm jpgm
|
||||
video/mj2 mj2 mjp2
|
||||
video/mp4 mp4 mp4v mpg4
|
||||
video/mpeg mpeg mpg mpe m1v m2v
|
||||
video/ogg ogv
|
||||
video/quicktime qt mov
|
||||
video/vnd.dece.hd uvh uvvh
|
||||
video/vnd.dece.mobile uvm uvvm
|
||||
video/vnd.dece.pd uvp uvvp
|
||||
video/vnd.dece.sd uvs uvvs
|
||||
video/vnd.dece.video uvv uvvv
|
||||
video/vnd.dvb.file dvb
|
||||
video/vnd.fvt fvt
|
||||
video/vnd.mpegurl mxu m4u
|
||||
video/vnd.ms-playready.media.pyv pyv
|
||||
video/vnd.uvvu.mp4 uvu uvvu
|
||||
video/vnd.vivo viv
|
||||
video/webm webm
|
||||
video/x-f4v f4v
|
||||
video/x-fli fli
|
||||
video/x-flv flv
|
||||
video/x-m4v m4v
|
||||
video/x-matroska mkv mk3d mks
|
||||
video/x-mng mng
|
||||
video/x-ms-asf asf asx
|
||||
video/x-ms-vob vob
|
||||
video/x-ms-wm wm
|
||||
video/x-ms-wmv wmv
|
||||
video/x-ms-wmx wmx
|
||||
video/x-ms-wvx wvx
|
||||
video/x-msvideo avi
|
||||
video/x-sgi-movie movie
|
||||
video/x-smv smv
|
||||
x-conference/x-cooltalk ice
|
||||
@@ -1,20 +0,0 @@
|
||||
import mime_raw from './mime-types.md';
|
||||
|
||||
const map: Map<string, string> = new Map();
|
||||
|
||||
mime_raw.split('\n').forEach((row: string) => {
|
||||
const match = /(.+?)\t+(.+)/.exec(row);
|
||||
if (!match) return;
|
||||
|
||||
const type = match[1];
|
||||
const extensions = match[2].split(' ');
|
||||
|
||||
extensions.forEach(ext => {
|
||||
map.set(ext, type);
|
||||
});
|
||||
});
|
||||
|
||||
export function lookup(file: string) {
|
||||
const match = /\.([^\.]+)$/.exec(file);
|
||||
return match && map.get(match[1]);
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
import { Stats } from 'fs';
|
||||
import { ClientRequest, ServerResponse } from 'http';
|
||||
|
||||
export type ServerRoute = {
|
||||
@@ -37,6 +38,18 @@ export type Props = {
|
||||
[key: string]: any;
|
||||
};
|
||||
|
||||
export interface MiddlewareOptions {
|
||||
static?: {
|
||||
headers?: (pathname: string, stats: Stats) => Record<string, string>
|
||||
},
|
||||
session?: (req: Req, res: Res) => any,
|
||||
ignore?: any
|
||||
}
|
||||
|
||||
export interface StartOptions extends MiddlewareOptions {
|
||||
port?: number;
|
||||
}
|
||||
|
||||
export interface Req extends ClientRequest {
|
||||
url: string;
|
||||
baseUrl: string;
|
||||
@@ -44,7 +57,7 @@ export interface Req extends ClientRequest {
|
||||
method: string;
|
||||
path: string;
|
||||
params: Record<string, string>;
|
||||
query: Record<string, string>;
|
||||
query: Record<string, string | string[]>;
|
||||
headers: Record<string, string>;
|
||||
}
|
||||
|
||||
@@ -1,17 +1,88 @@
|
||||
## Running locally
|
||||
# sapper-template
|
||||
|
||||
Set up the project:
|
||||
The default [Sapper](https://github.com/sveltejs/sapper) template, with branches for Rollup and webpack. To clone it and get started:
|
||||
|
||||
```bash
|
||||
git clone https://github.com/sveltejs/sapper.git
|
||||
cd sapper/site
|
||||
npm ci
|
||||
# for Rollup
|
||||
npx degit sveltejs/sapper-template#rollup my-app
|
||||
# for webpack
|
||||
npx degit sveltejs/sapper-template#webpack my-app
|
||||
cd my-app
|
||||
npm install # or yarn!
|
||||
npm run dev
|
||||
```
|
||||
|
||||
Start the server with `npm run dev`, and navigate to [localhost:3000](http://localhost:3000).
|
||||
Open up [localhost:3000](http://localhost:3000) and start clicking around.
|
||||
|
||||
## Translating the API docs
|
||||
Consult [sapper.svelte.technology](https://sapper.svelte.technology) for help getting started.
|
||||
|
||||
Anchors are automatically generated using headings in the documentation and by default (for the english language) they are latinised to make sure the URL is always conforming to RFC3986.
|
||||
|
||||
If we need to translate the API documentation to a language using unicode chars, we can setup this app to export the correct anchors by setting up `SLUG_PRESERVE_UNICODE` to `true` in `config.js`.
|
||||
## Structure
|
||||
|
||||
Sapper expects to find two directories in the root of your project — `src` and `static`.
|
||||
|
||||
|
||||
### src
|
||||
|
||||
The [src](src) directory contains the entry points for your app — `client.js`, `server.js` and (optionally) a `service-worker.js` — along with a `template.html` file and a `routes` directory.
|
||||
|
||||
|
||||
#### src/routes
|
||||
|
||||
This is the heart of your Sapper app. There are two kinds of routes — *pages*, and *server routes*.
|
||||
|
||||
**Pages** are Svelte components written in `.html` files. When a user first visits the application, they will be served a server-rendered version of the route in question, plus some JavaScript that 'hydrates' the page and initialises a client-side router. From that point forward, navigating to other pages is handled entirely on the client for a fast, app-like feel. (Sapper will preload and cache the code for these subsequent pages, so that navigation is instantaneous.)
|
||||
|
||||
**Server routes** are modules written in `.js` files, that export functions corresponding to HTTP methods. Each function receives Express `request` and `response` objects as arguments, plus a `next` function. This is useful for creating a JSON API, for example.
|
||||
|
||||
There are three simple rules for naming the files that define your routes:
|
||||
|
||||
* A file called `src/routes/about.html` corresponds to the `/about` route. A file called `src/routes/blog/[slug].html` corresponds to the `/blog/:slug` route, in which case `params.slug` is available to the route
|
||||
* The file `src/routes/index.html` (or `src/routes/index.js`) corresponds to the root of your app. `src/routes/about/index.html` is treated the same as `src/routes/about.html`.
|
||||
* Files and directories with a leading underscore do *not* create routes. This allows you to colocate helper modules and components with the routes that depend on them — for example you could have a file called `src/routes/_helpers/datetime.js` and it would *not* create a `/_helpers/datetime` route
|
||||
|
||||
|
||||
### static
|
||||
|
||||
The [static](static) directory contains any static assets that should be available. These are served using [sirv](https://github.com/lukeed/sirv).
|
||||
|
||||
In your [service-worker.js](app/service-worker.js) file, you can import these as `files` from the generated manifest...
|
||||
|
||||
```js
|
||||
import { files } from '../__sapper__/service-worker.js';
|
||||
```
|
||||
|
||||
...so that you can cache them (though you can choose not to, for example if you don't want to cache very large files).
|
||||
|
||||
|
||||
## Bundler config
|
||||
|
||||
Sapper uses Rollup or webpack to provide code-splitting and dynamic imports, as well as compiling your Svelte components. With webpack, it also provides hot module reloading. As long as you don't do anything daft, you can edit the configuration files to add whatever plugins you'd like.
|
||||
|
||||
|
||||
## Production mode and deployment
|
||||
|
||||
To start a production version of your app, run `npm run build && npm start`. This will disable live reloading, and activate the appropriate bundler plugins.
|
||||
|
||||
You can deploy your application to any environment that supports Node 8 or above. As an example, to deploy to [Now](https://zeit.co/now), run these commands:
|
||||
|
||||
```bash
|
||||
npm install -g now
|
||||
now
|
||||
```
|
||||
|
||||
|
||||
## Using external components with webpack
|
||||
|
||||
When using Svelte components installed from npm, such as [@sveltejs/svelte-virtual-list](https://github.com/sveltejs/svelte-virtual-list), Svelte needs the original component source (rather than any precompiled JavaScript that ships with the component). This allows the component to be rendered server-side, and also keeps your client-side app smaller.
|
||||
|
||||
Because of that, it's essential that webpack doesn't treat the package as an *external dependency*. You can either modify the `externals` option in [webpack/server.config.js](webpack/server.config.js), or simply install the package to `devDependencies` rather than `dependencies`, which will cause it to get bundled (and therefore compiled) with your app:
|
||||
|
||||
```bash
|
||||
yarn add -D @sveltejs/svelte-virtual-list
|
||||
```
|
||||
|
||||
|
||||
## Bugs and feedback
|
||||
|
||||
Sapper is in early development, and may have the odd rough edge here and there. Please be vocal over on the [Sapper issue tracker](https://github.com/sveltejs/sapper/issues).
|
||||
|
||||
@@ -4,7 +4,7 @@ title: Introduction
|
||||
|
||||
### Before we begin
|
||||
|
||||
> Sapper is in early development, and some things may change before we hit version 1.0. This document is a work-in-progress. If you get stuck, reach out for help in the [Discord chatroom](https://svelte.dev/chat).
|
||||
> Sapper is in early development, and some things may change before we hit version 1.0. This document is a work-in-progress. If you get stuck, reach out for help in the [Discord chatroom](https://discord.gg/yy75DKs).
|
||||
>
|
||||
> See the [migration guides](migrating) for help upgrading from older versions.
|
||||
|
||||
@@ -32,7 +32,7 @@ For web developers, the stakes are generally lower than for combat engineers. Bu
|
||||
[Next.js](https://github.com/zeit/next.js) is a React framework from [Zeit](https://zeit.co), and is the inspiration for Sapper. There are a few notable differences, however:
|
||||
|
||||
* Sapper is powered by Svelte instead of React, so it's faster and your apps are smaller
|
||||
* Instead of route masking, we encode route parameters in filenames (see the [routing](docs#Routing) section below)
|
||||
* Instead of route masking, we encode route parameters in filenames (see the [routing](docs#routing) section below)
|
||||
* As well as *pages*, you can create *server routes* in your `src/routes` directory. This makes it very easy to, for example, add a JSON API such as the one powering this very page (try visiting [/docs.json](/docs.json))
|
||||
* Links are just `<a>` elements, rather than framework-specific `<Link>` components. That means, for example, that [this link right here](/), despite being inside a blob of markdown, works with the router as you'd expect
|
||||
|
||||
@@ -42,8 +42,8 @@ For web developers, the stakes are generally lower than for combat engineers. Bu
|
||||
The easiest way to start building a Sapper app is to clone the [sapper-template](https://github.com/sveltejs/sapper-template) repo with [degit](https://github.com/Rich-Harris/degit):
|
||||
|
||||
```bash
|
||||
npx degit "sveltejs/sapper-template#rollup" my-app
|
||||
# or: npx degit "sveltejs/sapper-template#webpack" my-app
|
||||
npx degit sveltejs/sapper-template#rollup my-app
|
||||
# or: npx degit sveltejs/sapper-template#webpack my-app
|
||||
cd my-app
|
||||
npm install
|
||||
npm run dev
|
||||
|
||||
@@ -24,9 +24,9 @@ If you take a look inside the [sapper-template](https://github.com/sveltejs/sapp
|
||||
|
||||
When you first run Sapper, it will create an additional `__sapper__` directory containing generated files.
|
||||
|
||||
You'll notice a few extra files and a `cypress` directory which relates to [testing](docs#Testing) — we don't need to worry about those right now.
|
||||
You'll notice a few extra files and a `cypress` directory which relates to [testing](docs#testing) — we don't need to worry about those right now.
|
||||
|
||||
> You *can* create these files from scratch, but it's much better to use the template. See [getting started](docs#Getting_started) for instructions on how to easily clone it
|
||||
> You *can* create these files from scratch, but it's much better to use the template. See [getting started](docs#getting-started) for instructions on how to easily clone it
|
||||
|
||||
|
||||
### package.json
|
||||
@@ -35,9 +35,9 @@ Your package.json contains your app's dependencies and defines a number of scrip
|
||||
|
||||
* `npm run dev` — start the app in development mode, and watch source files for changes
|
||||
* `npm run build` — build the app in production mode
|
||||
* `npm run export` — bake out a static version, if applicable (see [exporting](docs#Exporting))
|
||||
* `npm run export` — bake out a static version, if applicable (see [exporting](docs#exporting))
|
||||
* `npm start` — start the app in production mode after you've built it
|
||||
* `npm test` — run the tests (see [testing](docs#Testing))
|
||||
* `npm test` — run the tests (see [testing](docs#testing))
|
||||
|
||||
|
||||
### src
|
||||
@@ -56,7 +56,7 @@ sapper.start({
|
||||
});
|
||||
```
|
||||
|
||||
In many cases, that's the entirety of your entry module, though you can do as much or as little here as you wish. See the [client API](docs#Client_API) section for more information on functions you can import.
|
||||
In many cases, that's the entirety of your entry module, though you can do as much or as little here as you wish. See the [client API](docs#client-api) section for more information on functions you can import.
|
||||
|
||||
|
||||
#### src/server.js
|
||||
@@ -88,7 +88,7 @@ Because every app needs a slightly different service worker (sometimes it's appr
|
||||
|
||||
This file is a template for responses from the server. Sapper will inject content that replaces the following tags:
|
||||
|
||||
* `%sapper.base%` — a `<base>` element (see [base URLs](docs#Base_URLs))
|
||||
* `%sapper.base%` — a `<base>` element (see [base URLs](docs#base-urls))
|
||||
* `%sapper.styles%` — critical CSS for the page being requested
|
||||
* `%sapper.head%` — HTML representing page-specific `<head>` contents, like `<title>`
|
||||
* `%sapper.html%` — HTML representing the body of the page being rendered
|
||||
@@ -97,7 +97,7 @@ This file is a template for responses from the server. Sapper will inject conten
|
||||
|
||||
### src/routes
|
||||
|
||||
This is the meat of your app — the pages and server routes. See the section on [routing](docs#Routing) for the juicy details.
|
||||
This is the meat of your app — the pages and server routes. See the section on [routing](docs#routing) for the juicy details.
|
||||
|
||||
|
||||
### static
|
||||
|
||||
@@ -70,7 +70,7 @@ Dynamic parameters are encoded using `[brackets]`. For example, here's how you c
|
||||
</div>
|
||||
```
|
||||
|
||||
> See the section on [preloading](docs#Preloading) for more info about `preload` and `this.fetch`
|
||||
> See the section on [preloading](docs#preloading) for more info about `preload` and `this.fetch`
|
||||
|
||||
|
||||
### Server routes
|
||||
|
||||
@@ -36,7 +36,7 @@ Programmatically navigates to the given `href`. If the destination is a Sapper r
|
||||
|
||||
* `href` — the page to prefetch
|
||||
|
||||
Programmatically prefetches the given page, which means a) ensuring that the code for the page is loaded, and b) calling the page's `preload` method with the appropriate options. This is the same behaviour that Sapper triggers when the user taps or mouses over an `<a>` element with [rel=prefetch](docs#Prefetching).
|
||||
Programmatically prefetches the given page, which means a) ensuring that the code for the page is loaded, and b) calling the page's `preload` method with the appropriate options. This is the same behaviour that Sapper triggers when the user taps or mouses over an `<a>` element with [rel=prefetch](docs#prefetching).
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
title: Preloading
|
||||
---
|
||||
|
||||
As seen in the [routing](docs#Routing) section, page components can have an optional `preload` function that will load some data that the page depends on. This is similar to `getInitialProps` in Next.js or `asyncData` in Nuxt.js.
|
||||
As seen in the [routing](docs#routing) section, page components can have an optional `preload` function that will load some data that the page depends on. This is similar to `getInitialProps` in Next.js or `asyncData` in Nuxt.js.
|
||||
|
||||
```html
|
||||
<script context="module">
|
||||
|
||||
@@ -21,7 +21,7 @@ express() // or Polka, or a similar framework
|
||||
|
||||
Sapper will detect the base path and configure both the server-side and client-side routers accordingly.
|
||||
|
||||
If you're [exporting](docs#Exporting) your app, you will need to tell the exporter where to begin crawling:
|
||||
If you're [exporting](docs#exporting) your app, you will need to tell the exporter where to begin crawling:
|
||||
|
||||
```bash
|
||||
sapper export --basepath my-base-path
|
||||
|
||||
@@ -292,7 +292,7 @@ Once your `App.html` has been created and your server and client apps updated, y
|
||||
|
||||
##### app/template.html
|
||||
|
||||
* Your `<head>` element must contain `%sapper.base%` (see ([base URLs](docs#Base_URLs))
|
||||
* Your `<head>` element must contain `%sapper.base%` (see ([base URLs](docs#base-urls))
|
||||
* Remove references to your service worker; this is now handled by `%sapper.scripts%`
|
||||
|
||||
##### Pages
|
||||
|
||||
58
site/package-lock.json
generated
58
site/package-lock.json
generated
@@ -1705,18 +1705,26 @@
|
||||
"dev": true
|
||||
},
|
||||
"html-minifier": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/html-minifier/-/html-minifier-4.0.0.tgz",
|
||||
"integrity": "sha512-aoGxanpFPLg7MkIl/DDFYtb0iWz7jMFGqFhvEDZga6/4QTjneiD8I/NXL1x5aaoCp7FSIT6h/OhykDdPsbtMig==",
|
||||
"version": "3.5.21",
|
||||
"resolved": "https://registry.npmjs.org/html-minifier/-/html-minifier-3.5.21.tgz",
|
||||
"integrity": "sha512-LKUKwuJDhxNa3uf/LPR/KVjm/l3rBqtYeCOAekvG8F1vItxMUpueGd94i/asDDr8/1u7InxzFA5EeGjhhG5mMA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"camel-case": "^3.0.0",
|
||||
"clean-css": "^4.2.1",
|
||||
"commander": "^2.19.0",
|
||||
"he": "^1.2.0",
|
||||
"param-case": "^2.1.1",
|
||||
"relateurl": "^0.2.7",
|
||||
"uglify-js": "^3.5.1"
|
||||
"camel-case": "3.0.x",
|
||||
"clean-css": "4.2.x",
|
||||
"commander": "2.17.x",
|
||||
"he": "1.2.x",
|
||||
"param-case": "2.1.x",
|
||||
"relateurl": "0.2.x",
|
||||
"uglify-js": "3.4.x"
|
||||
},
|
||||
"dependencies": {
|
||||
"commander": {
|
||||
"version": "2.17.1",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-2.17.1.tgz",
|
||||
"integrity": "sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"http-link-header": {
|
||||
@@ -2630,14 +2638,14 @@
|
||||
}
|
||||
},
|
||||
"sapper": {
|
||||
"version": "0.27.1",
|
||||
"resolved": "https://registry.npmjs.org/sapper/-/sapper-0.27.1.tgz",
|
||||
"integrity": "sha512-RH0K1uQ3zJ1IXvowxr2SuboGXV69q22KaPMhhoM5VNDv9fsUlVHtluZE8WTcGxckiO2L1xFfgM7v/aINkSZpcw==",
|
||||
"version": "0.26.0-alpha.12",
|
||||
"resolved": "https://registry.npmjs.org/sapper/-/sapper-0.26.0-alpha.12.tgz",
|
||||
"integrity": "sha512-NEXr6Eu5jawY76N5IEQhKMKhcZW6+42E2alH4J8DxFMmOI7Gi2nlwCQ2jcZv7q/S+zMP+OSuqE44c94A5u1H8Q==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"html-minifier": "^4.0.0",
|
||||
"html-minifier": "^3.5.21",
|
||||
"http-link-header": "^1.0.2",
|
||||
"shimport": "^1.0.0",
|
||||
"shimport": "0.0.14",
|
||||
"sourcemap-codec": "^1.4.4",
|
||||
"string-hash": "^1.1.3"
|
||||
}
|
||||
@@ -2711,9 +2719,9 @@
|
||||
}
|
||||
},
|
||||
"shimport": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/shimport/-/shimport-1.0.0.tgz",
|
||||
"integrity": "sha512-XKd+39voZT1rFR1ct+pr8sFSYAW6IvM3LeF87FrgcGHc/uSZ4GfOZVA42LE5LXFOpTWgmDC5sS8DNDtiV4Vd4Q==",
|
||||
"version": "0.0.14",
|
||||
"resolved": "https://registry.npmjs.org/shimport/-/shimport-0.0.14.tgz",
|
||||
"integrity": "sha512-JfzpHhyZ6CYuPYUSitFNw2/IxWEABLN1chs9xDHnn4tPXXCmfIn1METCmIl8Vwvm2FZGW7b8WB4zMCKaJEhY6A==",
|
||||
"dev": true
|
||||
},
|
||||
"sirv": {
|
||||
@@ -3078,15 +3086,21 @@
|
||||
}
|
||||
},
|
||||
"uglify-js": {
|
||||
"version": "3.5.15",
|
||||
"resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.5.15.tgz",
|
||||
"integrity": "sha512-fe7aYFotptIddkwcm6YuA0HmknBZ52ZzOsUxZEdhhkSsz7RfjHDX2QDxwKTiv4JQ5t5NhfmpgAK+J7LiDhKSqg==",
|
||||
"version": "3.4.10",
|
||||
"resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.4.10.tgz",
|
||||
"integrity": "sha512-Y2VsbPVs0FIshJztycsO2SfPk7/KAF/T72qzv9u5EpQ4kB2hQoHlhNQTsNyy6ul7lQtqJN/AoWeS23OzEiEFxw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"commander": "~2.20.0",
|
||||
"commander": "~2.19.0",
|
||||
"source-map": "~0.6.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"commander": {
|
||||
"version": "2.19.0",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-2.19.0.tgz",
|
||||
"integrity": "sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg==",
|
||||
"dev": true
|
||||
},
|
||||
"source-map": {
|
||||
"version": "0.6.1",
|
||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
"rollup-plugin-replace": "^2.2.0",
|
||||
"rollup-plugin-svelte": "^5.0.3",
|
||||
"rollup-plugin-terser": "^4.0.4",
|
||||
"sapper": "^0.27.1",
|
||||
"sapper": "alpha",
|
||||
"svelte": "^3.2.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,7 +61,7 @@
|
||||
<p>Please try reloading the page.</p>
|
||||
{/if}
|
||||
|
||||
<p>If the error persists, please drop by <a href="https://svelte.dev/chat">Discord chatroom</a> and let us know, or raise an issue on <a href="https://github.com/sveltejs/svelte">GitHub</a>. Thanks!</p>
|
||||
<p>If the error persists, please drop by <a href="https://discord.gg/yy75DKs">Discord chatroom</a> and let us know, or raise an issue on <a href="https://github.com/sveltejs/svelte">GitHub</a>. Thanks!</p>
|
||||
{/if}
|
||||
{:else}
|
||||
<h1>It looks like you're offline</h1>
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
<script>
|
||||
import { stores } from '@sapper/app';
|
||||
import { page } from '@sapper/app';
|
||||
import { Icons, Icon, Nav, NavItem } from '@sveltejs/site-kit';
|
||||
|
||||
export let segment;
|
||||
|
||||
const { page } = stores();
|
||||
</script>
|
||||
|
||||
<style>
|
||||
@@ -28,7 +26,7 @@
|
||||
|
||||
<NavItem external="https://svelte.dev">Svelte</NavItem>
|
||||
|
||||
<NavItem external="https://svelte.dev/chat" title="Discord Chat">
|
||||
<NavItem external="https://discord.gg/yy75DKs" title="Discord Chat">
|
||||
<Icon name="message-square"/>
|
||||
</NavItem>
|
||||
|
||||
@@ -39,4 +37,4 @@
|
||||
|
||||
<main>
|
||||
<slot></slot>
|
||||
</main>
|
||||
</main>
|
||||
@@ -50,9 +50,9 @@
|
||||
<div style="grid-area: start; display: flex; flex-direction: column; min-width: 0" slot="how">
|
||||
<pre class="language-bash" style="margin: 0 0 1em 0; min-width: 0; min-height: 0">
|
||||
# for Rollup
|
||||
npx degit "sveltejs/sapper-template#rollup" my-app
|
||||
npx degit sveltejs/sapper-template#rollup my-app
|
||||
# for webpack
|
||||
npx degit "sveltejs/sapper-template#webpack" my-app
|
||||
npx degit sveltejs/sapper-template#webpack my-app
|
||||
cd my-app
|
||||
|
||||
npm install
|
||||
|
||||
@@ -19,7 +19,6 @@ type Opts = {
|
||||
static?: string;
|
||||
legacy?: boolean;
|
||||
bundler?: 'rollup' | 'webpack';
|
||||
ext?: string;
|
||||
oncompile?: ({ type, result }: { type: string, result: CompileResult }) => void;
|
||||
};
|
||||
|
||||
@@ -33,7 +32,6 @@ export async function build({
|
||||
|
||||
bundler,
|
||||
legacy = false,
|
||||
ext,
|
||||
oncompile = noop
|
||||
}: Opts = {}) {
|
||||
bundler = validate_bundler(bundler);
|
||||
@@ -70,7 +68,7 @@ export async function build({
|
||||
|
||||
fs.writeFileSync(`${dest}/template.html`, minify_html(template));
|
||||
|
||||
const manifest_data = create_manifest_data(routes, ext);
|
||||
const manifest_data = create_manifest_data(routes);
|
||||
|
||||
// create src/node_modules/@sapper/app.mjs and server.mjs
|
||||
create_app({
|
||||
@@ -124,7 +122,7 @@ export async function build({
|
||||
|
||||
const client_files = client_result.chunks
|
||||
.filter(chunk => !chunk.file.endsWith('.map')) // SW does not need to cache sourcemap files
|
||||
.map(chunk => `client/${chunk.file}`);
|
||||
.map(chunk => `sapper/${chunk.file}`);
|
||||
|
||||
create_serviceworker_manifest({
|
||||
manifest_data,
|
||||
|
||||
115
src/api/dev.ts
115
src/api/dev.ts
@@ -28,8 +28,7 @@ type Opts = {
|
||||
hot?: boolean,
|
||||
'devtools-port'?: number,
|
||||
bundler?: 'rollup' | 'webpack',
|
||||
port?: number,
|
||||
ext: string
|
||||
port?: number
|
||||
};
|
||||
|
||||
export function dev(opts: Opts) {
|
||||
@@ -48,7 +47,7 @@ class Watcher extends EventEmitter {
|
||||
}
|
||||
port: number;
|
||||
closed: boolean;
|
||||
|
||||
|
||||
dev_port: number;
|
||||
live: boolean;
|
||||
hot: boolean;
|
||||
@@ -68,7 +67,6 @@ class Watcher extends EventEmitter {
|
||||
unique_warnings: Set<string>;
|
||||
unique_errors: Set<string>;
|
||||
}
|
||||
ext: string;
|
||||
|
||||
constructor({
|
||||
cwd = '.',
|
||||
@@ -82,8 +80,7 @@ class Watcher extends EventEmitter {
|
||||
hot,
|
||||
'devtools-port': devtools_port,
|
||||
bundler,
|
||||
port = +process.env.PORT,
|
||||
ext
|
||||
port = +process.env.PORT
|
||||
}: Opts) {
|
||||
super();
|
||||
|
||||
@@ -98,7 +95,7 @@ class Watcher extends EventEmitter {
|
||||
output: path.resolve(cwd, output),
|
||||
static: path.resolve(cwd, static_files)
|
||||
};
|
||||
this.ext = ext;
|
||||
|
||||
this.port = port;
|
||||
this.closed = false;
|
||||
|
||||
@@ -164,7 +161,7 @@ class Watcher extends EventEmitter {
|
||||
let manifest_data: ManifestData;
|
||||
|
||||
try {
|
||||
manifest_data = create_manifest_data(routes, this.ext);
|
||||
manifest_data = create_manifest_data(routes);
|
||||
create_app({
|
||||
bundler: this.bundler,
|
||||
manifest_data,
|
||||
@@ -192,7 +189,7 @@ class Watcher extends EventEmitter {
|
||||
},
|
||||
() => {
|
||||
try {
|
||||
const new_manifest_data = create_manifest_data(routes, this.ext);
|
||||
const new_manifest_data = create_manifest_data(routes);
|
||||
create_app({
|
||||
bundler: this.bundler,
|
||||
manifest_data, // TODO is this right? not new_manifest_data?
|
||||
@@ -209,18 +206,14 @@ class Watcher extends EventEmitter {
|
||||
});
|
||||
}
|
||||
}
|
||||
)
|
||||
);
|
||||
),
|
||||
|
||||
if (this.live) {
|
||||
this.filewatchers.push(
|
||||
fs.watch(`${src}/template.html`, () => {
|
||||
this.dev_server.send({
|
||||
action: 'reload'
|
||||
});
|
||||
})
|
||||
);
|
||||
}
|
||||
fs.watch(`${src}/template.html`, () => {
|
||||
this.dev_server.send({
|
||||
action: 'reload'
|
||||
});
|
||||
})
|
||||
);
|
||||
|
||||
let deferred = new Deferred();
|
||||
|
||||
@@ -259,7 +252,7 @@ class Watcher extends EventEmitter {
|
||||
this.dev_server.send({
|
||||
status: 'completed'
|
||||
});
|
||||
} else if (this.live) {
|
||||
} else {
|
||||
this.dev_server.send({
|
||||
action: 'reload'
|
||||
});
|
||||
@@ -274,54 +267,48 @@ class Watcher extends EventEmitter {
|
||||
});
|
||||
};
|
||||
|
||||
const start_server = () => {
|
||||
// we need to give the child process its own DevTools port,
|
||||
// otherwise Node will try to use the parent's (and fail)
|
||||
const debugArgRegex = /--inspect(?:-brk|-port)?|--debug-port/;
|
||||
const execArgv = process.execArgv.slice();
|
||||
if (execArgv.some((arg: string) => !!arg.match(debugArgRegex))) {
|
||||
execArgv.push(`--inspect-port=${this.devtools_port}`);
|
||||
}
|
||||
|
||||
this.proc = child_process.fork(`${dest}/server/server.js`, [], {
|
||||
cwd: process.cwd(),
|
||||
env: Object.assign({
|
||||
PORT: this.port
|
||||
}, process.env),
|
||||
stdio: ['ipc'],
|
||||
execArgv
|
||||
});
|
||||
|
||||
this.proc.stdout.on('data', chunk => {
|
||||
this.emit('stdout', chunk);
|
||||
});
|
||||
|
||||
this.proc.stderr.on('data', chunk => {
|
||||
this.emit('stderr', chunk);
|
||||
});
|
||||
|
||||
this.proc.on('message', message => {
|
||||
if (message.__sapper__ && message.event === 'basepath') {
|
||||
this.emit('basepath', {
|
||||
basepath: message.basepath
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
this.proc.on('exit', emitFatal);
|
||||
};
|
||||
|
||||
if (this.proc) {
|
||||
this.proc.removeListener('exit', emitFatal);
|
||||
this.proc.kill();
|
||||
this.proc.on('exit', () => {
|
||||
start_server();
|
||||
restart();
|
||||
});
|
||||
this.proc.on('exit', restart);
|
||||
} else {
|
||||
start_server();
|
||||
restart();
|
||||
}
|
||||
|
||||
// we need to give the child process its own DevTools port,
|
||||
// otherwise Node will try to use the parent's (and fail)
|
||||
const debugArgRegex = /--inspect(?:-brk|-port)?|--debug-port/;
|
||||
const execArgv = process.execArgv.slice();
|
||||
if (execArgv.some((arg: string) => !!arg.match(debugArgRegex))) {
|
||||
execArgv.push(`--inspect-port=${this.devtools_port}`);
|
||||
}
|
||||
|
||||
this.proc = child_process.fork(`${dest}/server/server.js`, [], {
|
||||
cwd: process.cwd(),
|
||||
env: Object.assign({
|
||||
PORT: this.port
|
||||
}, process.env),
|
||||
stdio: ['ipc'],
|
||||
execArgv
|
||||
});
|
||||
|
||||
this.proc.stdout.on('data', chunk => {
|
||||
this.emit('stdout', chunk);
|
||||
});
|
||||
|
||||
this.proc.stderr.on('data', chunk => {
|
||||
this.emit('stderr', chunk);
|
||||
});
|
||||
|
||||
this.proc.on('message', message => {
|
||||
if (message.__sapper__ && message.event === 'basepath') {
|
||||
this.emit('basepath', {
|
||||
basepath: message.basepath
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
this.proc.on('exit', emitFatal);
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -346,7 +333,7 @@ class Watcher extends EventEmitter {
|
||||
JSON.stringify(result.to_json(manifest_data, this.dirs), null, ' ')
|
||||
);
|
||||
|
||||
const client_files = result.chunks.map(chunk => `client/${chunk.file}`);
|
||||
const client_files = result.chunks.map(chunk => `sapper/${chunk.file}`);
|
||||
|
||||
create_serviceworker_manifest({
|
||||
manifest_data,
|
||||
|
||||
@@ -60,9 +60,8 @@ async function _export({
|
||||
rimraf(export_dir);
|
||||
|
||||
copy(static_files, export_dir);
|
||||
copy(path.join(build_dir, 'client'), path.join(export_dir, 'client'));
|
||||
copy(path.join(build_dir, 'service-worker.js'), path.join(export_dir, 'service-worker.js'));
|
||||
copy(path.join(build_dir, 'service-worker.js.map'), path.join(export_dir, 'service-worker.js.map'));
|
||||
copy(path.join(build_dir, 'client'), export_dir);
|
||||
copy(path.join(build_dir, 'service-worker'), export_dir);
|
||||
|
||||
const defaultPort = process.env.PORT ? parseInt(process.env.PORT) : 3000;
|
||||
const port = await ports.find(defaultPort);
|
||||
@@ -132,23 +131,19 @@ async function _export({
|
||||
if (seen.has(pathname)) return;
|
||||
seen.add(pathname);
|
||||
|
||||
const r = await q.add(async () => {
|
||||
const timeout_deferred = new Deferred();
|
||||
const the_timeout = setTimeout(() => {
|
||||
timeout_deferred.reject(new Error(`Timed out waiting for ${url.href}`));
|
||||
}, timeout);
|
||||
const timeout_deferred = new Deferred();
|
||||
const the_timeout = setTimeout(() => {
|
||||
timeout_deferred.reject(new Error(`Timed out waiting for ${url.href}`));
|
||||
}, timeout);
|
||||
|
||||
const r = await Promise.race([
|
||||
fetch(url.href, {
|
||||
redirect: 'manual'
|
||||
}),
|
||||
timeout_deferred.promise
|
||||
]);
|
||||
const r = await Promise.race([
|
||||
q.add(() => fetch(url.href, {
|
||||
redirect: 'manual'
|
||||
})),
|
||||
timeout_deferred.promise
|
||||
]);
|
||||
|
||||
clearTimeout(the_timeout); // prevent it hanging at the end
|
||||
|
||||
return r;
|
||||
}) as Response;
|
||||
clearTimeout(the_timeout); // prevent it hanging at the end
|
||||
|
||||
let type = r.headers.get('Content-Type');
|
||||
|
||||
@@ -156,8 +151,6 @@ async function _export({
|
||||
|
||||
const range = ~~(r.status / 100);
|
||||
|
||||
let tasks = [];
|
||||
|
||||
if (range === 2) {
|
||||
if (type === 'text/html') {
|
||||
// parse link rel=preload headers and embed them in the HTML
|
||||
@@ -179,6 +172,8 @@ async function _export({
|
||||
let match;
|
||||
let pattern = /<a ([\s\S]+?)>/gm;
|
||||
|
||||
let promise;
|
||||
|
||||
while (match = pattern.exec(cleaned)) {
|
||||
const attrs = match[1];
|
||||
const href = get_href(attrs);
|
||||
@@ -187,10 +182,12 @@ async function _export({
|
||||
const url = resolve(base.href, href);
|
||||
|
||||
if (url.protocol === protocol && url.host === host) {
|
||||
tasks.push(handle(url));
|
||||
promise = handle(url);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
await promise;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -201,12 +198,10 @@ async function _export({
|
||||
type = 'text/html';
|
||||
body = `<script>window.location.href = "${location.replace(origin, '')}"</script>`;
|
||||
|
||||
tasks.push(handle(resolve(root.href, location)));
|
||||
await handle(resolve(root.href, location));
|
||||
}
|
||||
|
||||
save(pathname, r.status, type, body);
|
||||
|
||||
await Promise.all(tasks);
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
@@ -1,9 +1,13 @@
|
||||
import * as fs from 'fs';
|
||||
import { mkdirp } from './fs_utils';
|
||||
|
||||
export function copy_shimport(dest: string) {
|
||||
mkdirp(`${dest}/client/sapper`);
|
||||
|
||||
const shimport_version = require('shimport/package.json').version;
|
||||
|
||||
fs.writeFileSync(
|
||||
`${dest}/client/shimport@${shimport_version}.js`,
|
||||
`${dest}/client/sapper/shimport@${shimport_version}.js`,
|
||||
fs.readFileSync(require.resolve('shimport/index.js'))
|
||||
);
|
||||
}
|
||||
25
src/cli.ts
25
src/cli.ts
@@ -31,7 +31,6 @@ prog.command('dev')
|
||||
.option('--static', 'Static files directory', 'static')
|
||||
.option('--output', 'Sapper output directory', 'src/node_modules/@sapper')
|
||||
.option('--build-dir', 'Development build directory', '__sapper__/dev')
|
||||
.option('--ext', 'Custom Route Extension', '.svelte .html')
|
||||
.action(async (opts: {
|
||||
port: number,
|
||||
open: boolean,
|
||||
@@ -44,8 +43,7 @@ prog.command('dev')
|
||||
routes: string,
|
||||
static: string,
|
||||
output: string,
|
||||
'build-dir': string,
|
||||
ext: string
|
||||
'build-dir': string
|
||||
}) => {
|
||||
const { dev } = await import('./api/dev');
|
||||
|
||||
@@ -61,8 +59,7 @@ prog.command('dev')
|
||||
'dev-port': opts['dev-port'],
|
||||
live: opts.live,
|
||||
hot: opts.hot,
|
||||
bundler: opts.bundler,
|
||||
ext: opts.ext
|
||||
bundler: opts.bundler
|
||||
});
|
||||
|
||||
let first = true;
|
||||
@@ -154,7 +151,6 @@ prog.command('build [dest]')
|
||||
.option('--src', 'Source directory', 'src')
|
||||
.option('--routes', 'Routes directory', 'src/routes')
|
||||
.option('--output', 'Sapper output directory', 'src/node_modules/@sapper')
|
||||
.option('--ext', 'Custom Route Extension', '.svelte .html')
|
||||
.example(`build custom-dir -p 4567`)
|
||||
.action(async (dest = '__sapper__/build', opts: {
|
||||
port: string,
|
||||
@@ -163,13 +159,12 @@ prog.command('build [dest]')
|
||||
cwd: string,
|
||||
src: string,
|
||||
routes: string,
|
||||
output: string,
|
||||
ext: string
|
||||
output: string
|
||||
}) => {
|
||||
console.log(`> Building...`);
|
||||
|
||||
try {
|
||||
await _build(opts.bundler, opts.legacy, opts.cwd, opts.src, opts.routes, opts.output, dest, opts.ext);
|
||||
await _build(opts.bundler, opts.legacy, opts.cwd, opts.src, opts.routes, opts.output, dest);
|
||||
|
||||
const launcher = path.resolve(dest, 'index.js');
|
||||
|
||||
@@ -204,7 +199,6 @@ prog.command('export [dest]')
|
||||
.option('--static', 'Static files directory', 'static')
|
||||
.option('--output', 'Sapper output directory', 'src/node_modules/@sapper')
|
||||
.option('--build-dir', 'Intermediate build directory', '__sapper__/build')
|
||||
.option('--ext', 'Custom Route Extension', '.svelte .html')
|
||||
.action(async (dest = '__sapper__/export', opts: {
|
||||
build: boolean,
|
||||
legacy: boolean,
|
||||
@@ -218,12 +212,11 @@ prog.command('export [dest]')
|
||||
static: string,
|
||||
output: string,
|
||||
'build-dir': string,
|
||||
ext: string
|
||||
}) => {
|
||||
try {
|
||||
if (opts.build) {
|
||||
console.log(`> Building...`);
|
||||
await _build(opts.bundler, opts.legacy, opts.cwd, opts.src, opts.routes, opts.output, opts['build-dir'], opts.ext);
|
||||
await _build(opts.bundler, opts.legacy, opts.cwd, opts.src, opts.routes, opts.output, opts['build-dir']);
|
||||
console.error(`\n> Built in ${elapsed(start)}`);
|
||||
}
|
||||
|
||||
@@ -262,7 +255,7 @@ prog.command('export [dest]')
|
||||
}
|
||||
});
|
||||
|
||||
prog.parse(process.argv, { unknown: (arg: string) => `Unknown option: ${arg}` });
|
||||
prog.parse(process.argv);
|
||||
|
||||
|
||||
async function _build(
|
||||
@@ -272,8 +265,7 @@ async function _build(
|
||||
src: string,
|
||||
routes: string,
|
||||
output: string,
|
||||
dest: string,
|
||||
ext: string
|
||||
dest: string
|
||||
) {
|
||||
const { build } = await import('./api/build');
|
||||
|
||||
@@ -284,8 +276,7 @@ async function _build(
|
||||
src,
|
||||
routes,
|
||||
dest,
|
||||
ext,
|
||||
output,
|
||||
|
||||
oncompile: event => {
|
||||
let banner = `built ${event.type}`;
|
||||
let c = (txt: string) => colors.cyan(txt);
|
||||
|
||||
@@ -9,7 +9,7 @@ export default {
|
||||
},
|
||||
|
||||
output: () => {
|
||||
let dir = `${dest}/client`;
|
||||
let dir = `${dest}/client/sapper`;
|
||||
if (process.env.SAPPER_LEGACY_BUILD) dir += `/legacy`;
|
||||
|
||||
return {
|
||||
@@ -45,7 +45,7 @@ export default {
|
||||
|
||||
output: () => {
|
||||
return {
|
||||
file: `${dest}/service-worker.js`,
|
||||
file: `${dest}/service-worker/service-worker.js`,
|
||||
format: 'iife'
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,10 +12,10 @@ export default {
|
||||
|
||||
output: () => {
|
||||
return {
|
||||
path: `${dest}/client`,
|
||||
path: `${dest}/client/sapper`,
|
||||
filename: '[hash]/[name].js',
|
||||
chunkFilename: '[hash]/[name].[id].js',
|
||||
publicPath: `client/`
|
||||
publicPath: `sapper/`
|
||||
};
|
||||
}
|
||||
},
|
||||
@@ -46,7 +46,7 @@ export default {
|
||||
|
||||
output: () => {
|
||||
return {
|
||||
path: dest,
|
||||
path: `${dest}/service-worker`,
|
||||
filename: '[name].js',
|
||||
chunkFilename: '[name].[id].[hash].js'
|
||||
}
|
||||
|
||||
@@ -116,7 +116,7 @@ export default function extract_css(client_result: CompileResult, components: Pa
|
||||
|
||||
if (!client_result.css_files) return; // Rollup-only for now
|
||||
|
||||
let asset_dir = `${dirs.dest}/client`;
|
||||
let asset_dir = `${dirs.dest}/client/sapper`;
|
||||
if (process.env.SAPPER_LEGACY_BUILD) asset_dir += '/legacy';
|
||||
|
||||
const unclaimed = new Set(client_result.css_files.map(x => x.id));
|
||||
@@ -238,7 +238,7 @@ export default function extract_css(client_result: CompileResult, components: Pa
|
||||
map.file = output_file_name;
|
||||
map.sources = map.sources.map(source => path.relative(asset_dir, source));
|
||||
|
||||
fs.writeFileSync(`${asset_dir}/${output_file_name}`, `${code}\n/* sourceMappingURL=client/${output_file_name}.map */`);
|
||||
fs.writeFileSync(`${asset_dir}/${output_file_name}`, `${code}\n/* sourceMappingURL=sapper/${output_file_name}.map */`);
|
||||
fs.writeFileSync(`${asset_dir}/${output_file_name}.map`, JSON.stringify(map, null, ' '));
|
||||
|
||||
result.main = output_file_name;
|
||||
|
||||
@@ -4,10 +4,9 @@ import svelte from 'svelte/compiler';
|
||||
import { Page, PageComponent, ServerRoute, ManifestData } from '../interfaces';
|
||||
import { posixify, reserved_words } from '../utils';
|
||||
|
||||
export default function create_manifest_data(cwd: string, extensions: string = '.svelte .html'): ManifestData {
|
||||
|
||||
const component_extensions = extensions.split(' ');
|
||||
const component_extensions = ['.svelte', '.html']; // TODO make this configurable (to include e.g. .svelte.md?)
|
||||
|
||||
export default function create_manifest_data(cwd: string): ManifestData {
|
||||
// TODO remove in a future version
|
||||
if (!fs.existsSync(cwd)) {
|
||||
throw new Error(`As of Sapper 0.21, the routes/ directory should become src/routes/`);
|
||||
@@ -335,7 +334,7 @@ function get_pattern(segments: Part[][], add_trailing_slash: boolean) {
|
||||
const path = segments.map(segment => {
|
||||
return segment.map(part => {
|
||||
return part.dynamic
|
||||
? part.qualifier || (part.spread ? '(.+)' : '([^\\/]+?)')
|
||||
? part.qualifier || part.spread ? '(.+)' : '([^\\/]+?)'
|
||||
: encodeURI(part.content.normalize())
|
||||
.replace(/\?/g, '%3F')
|
||||
.replace(/#/g, '%23')
|
||||
|
||||
@@ -1,18 +1,8 @@
|
||||
<script context="module">
|
||||
export function preload({ query, params }) {
|
||||
const { rest } = params;
|
||||
return { rest };
|
||||
}
|
||||
</script>
|
||||
|
||||
<script>
|
||||
import { stores } from '@sapper/app';
|
||||
const { page } = stores();
|
||||
export let rest;
|
||||
</script>
|
||||
|
||||
<h1>{$page.params.rest.join(',')}</h1>
|
||||
<h2>{rest.join(',')}</h2>
|
||||
|
||||
<a href="xyz/abc/qwe/deep.json">deep</a>
|
||||
<a href="xyz/abc">back</a>
|
||||
|
||||
@@ -1,20 +1,8 @@
|
||||
<script context="module">
|
||||
export function preload({ query, params }) {
|
||||
const { rest } = params;
|
||||
return { rest };
|
||||
}
|
||||
</script>
|
||||
|
||||
<script>
|
||||
import { stores } from '@sapper/app';
|
||||
const { page } = stores();
|
||||
export let rest;
|
||||
</script>
|
||||
|
||||
<h1>{$page.params.rest.join(',')}</h1>
|
||||
<h2>{rest.join(',')}</h2>
|
||||
|
||||
<a href="xyz/abc/deep">deep</a>
|
||||
<a href="xyz/abc">deep</a>
|
||||
<a href="xyz/abc/def">deep</a>
|
||||
<a href="xyz/abc/def/ghi">deep</a>
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
<script>
|
||||
import { stores } from '@sapper/app';
|
||||
const { page } = stores();
|
||||
</script>
|
||||
|
||||
<h1>Regexp page {$page.params.id}</h1>
|
||||
|
||||
<a href="regexp/234">nested regexp route</a>
|
||||
@@ -3,6 +3,4 @@
|
||||
const { page } = stores();
|
||||
</script>
|
||||
|
||||
<h1>{$page.params.slug}</h1>
|
||||
|
||||
<a href="234">regexp route</a>
|
||||
<h1>{$page.params.slug.toUpperCase()}</h1>
|
||||
@@ -1,6 +0,0 @@
|
||||
<script>
|
||||
import { stores } from '@sapper/app';
|
||||
const { page } = stores();
|
||||
</script>
|
||||
|
||||
<h1>Nested regexp page {$page.params.id}</h1>
|
||||
@@ -1,9 +1,6 @@
|
||||
import polka from 'polka';
|
||||
import * as sapper from '@sapper/server';
|
||||
|
||||
import { start } from '../../common.js';
|
||||
|
||||
const app = polka()
|
||||
.use(sapper.middleware())
|
||||
const server = sapper.server();
|
||||
|
||||
start(app);
|
||||
start(server);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import * as assert from 'assert';
|
||||
import * as http from 'http';
|
||||
import {build} from '../../../api';
|
||||
import {AppRunner} from '../AppRunner';
|
||||
import { build } from '../../../api';
|
||||
import { AppRunner } from '../AppRunner';
|
||||
|
||||
declare let deleted: { id: number };
|
||||
declare let el: any;
|
||||
@@ -82,7 +82,7 @@ describe('basics', function() {
|
||||
|
||||
assert.equal(
|
||||
await r.text('h1'),
|
||||
'test-slug'
|
||||
'TEST-SLUG'
|
||||
);
|
||||
});
|
||||
|
||||
@@ -140,7 +140,7 @@ describe('basics', function() {
|
||||
);
|
||||
|
||||
// TODO preload more than just the entry point
|
||||
const regex = /<\/client\/client\.\w+\.js>;rel="modulepreload"/;
|
||||
const regex = /<\/sapper\/client\.\w+\.js>;rel="modulepreload"/;
|
||||
const link = <string>headers['link'];
|
||||
|
||||
assert.ok(regex.test(link), link);
|
||||
@@ -267,6 +267,7 @@ describe('basics', function() {
|
||||
await r.sapper.start();
|
||||
|
||||
assert.equal(await r.text('h1'), 'foo');
|
||||
|
||||
await r.page.click('[href="dirs/bar"]');
|
||||
await r.wait();
|
||||
assert.equal(await r.text('h1'), 'bar');
|
||||
@@ -277,26 +278,11 @@ describe('basics', function() {
|
||||
await r.sapper.start();
|
||||
|
||||
assert.equal(await r.text('h1'), 'abc,xyz');
|
||||
await r.page.click('[href="xyz/abc/def/ghi"]');
|
||||
await r.wait();
|
||||
assert.equal(await r.text('h1'), 'xyz,abc,def,ghi');
|
||||
assert.equal(await r.text('h2'), 'xyz,abc,def,ghi');
|
||||
await r.page.click('[href="xyz/abc/def"]');
|
||||
await r.wait();
|
||||
assert.equal(await r.text('h1'), 'xyz,abc,def');
|
||||
assert.equal(await r.text('h2'), 'xyz,abc,def');
|
||||
await r.page.click('[href="xyz/abc/def"]');
|
||||
await r.wait();
|
||||
assert.equal(await r.text('h1'), 'xyz,abc,def');
|
||||
assert.equal(await r.text('h2'), 'xyz,abc,def');
|
||||
await r.page.click('[href="xyz/abc"]');
|
||||
await r.wait();
|
||||
assert.equal(await r.text('h1'), 'xyz,abc');
|
||||
assert.equal(await r.text('h2'), 'xyz,abc');
|
||||
|
||||
await r.page.click('[href="xyz/abc/deep"]');
|
||||
await r.wait();
|
||||
assert.equal(await r.text('h1'), 'xyz,abc');
|
||||
assert.equal(await r.text('h2'), 'xyz,abc');
|
||||
|
||||
await r.page.click('[href="xyz/abc/qwe/deep.json"]');
|
||||
await r.wait();
|
||||
assert.equal(
|
||||
@@ -316,22 +302,6 @@ describe('basics', function() {
|
||||
assert.equal(await r.text('h1'), 'B page');
|
||||
});
|
||||
|
||||
it('find regexp routes', async () => {
|
||||
await r.load('/qwe');
|
||||
await r.sapper.start();
|
||||
|
||||
assert.equal(await r.text('h1'), 'qwe');
|
||||
|
||||
await r.page.click('[href="234"]');
|
||||
await r.wait();
|
||||
|
||||
assert.equal(await r.text('h1'), 'Regexp page 234');
|
||||
|
||||
await r.page.click('[href="regexp/234"]');
|
||||
await r.wait();
|
||||
assert.equal(await r.text('h1'), 'Nested regexp page 234');
|
||||
});
|
||||
|
||||
it('runs server route handlers before page handlers, if they match', async () => {
|
||||
const json = await get(`${r.base}/middleware`, {
|
||||
headers: {
|
||||
|
||||
@@ -2,11 +2,12 @@ const { NODE_ENV, PORT } = process.env;
|
||||
|
||||
export const dev = NODE_ENV === 'development';
|
||||
|
||||
export function start(app) {
|
||||
export function start(server) {
|
||||
const port = parseInt(PORT) || 0;
|
||||
|
||||
app.listen(port, () => {
|
||||
const address = app.server.address();
|
||||
server.listen(port, () => {
|
||||
server = server.server || server;
|
||||
const address = server.address();
|
||||
|
||||
process.env.PORT = address.port;
|
||||
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
import polka from 'polka';
|
||||
import * as sapper from '@sapper/server';
|
||||
|
||||
import { start } from '../../common.js';
|
||||
|
||||
const app = polka()
|
||||
.use(sapper.middleware());
|
||||
const server = sapper.server();
|
||||
|
||||
start(app);
|
||||
start(server);
|
||||
|
||||
@@ -1,60 +0,0 @@
|
||||
import resolve from 'rollup-plugin-node-resolve';
|
||||
import replace from 'rollup-plugin-replace';
|
||||
import svelte from 'rollup-plugin-svelte';
|
||||
|
||||
const mode = process.env.NODE_ENV;
|
||||
const dev = mode === 'development';
|
||||
|
||||
const config = require('../../../config/rollup.js');
|
||||
|
||||
export default {
|
||||
client: {
|
||||
input: config.client.input(),
|
||||
output: config.client.output(),
|
||||
plugins: [
|
||||
replace({
|
||||
'process.browser': true,
|
||||
'process.env.NODE_ENV': JSON.stringify(mode)
|
||||
}),
|
||||
svelte({
|
||||
extensions: ['.whokilledthemuffinman', '.jesuslivesineveryone', '.mdx', '.svelte', '.html'],
|
||||
dev,
|
||||
hydratable: true,
|
||||
emitCss: true
|
||||
}),
|
||||
resolve()
|
||||
]
|
||||
},
|
||||
|
||||
server: {
|
||||
input: config.server.input(),
|
||||
output: config.server.output(),
|
||||
plugins: [
|
||||
replace({
|
||||
'process.browser': false,
|
||||
'process.env.NODE_ENV': JSON.stringify(mode)
|
||||
}),
|
||||
svelte({
|
||||
extensions: ['.whokilledthemuffinman', '.jesuslivesineveryone', '.mdx', '.svelte', '.html'],
|
||||
generate: 'ssr',
|
||||
dev
|
||||
}),
|
||||
resolve({
|
||||
preferBuiltins: true
|
||||
})
|
||||
],
|
||||
external: ['sirv', 'polka']
|
||||
},
|
||||
|
||||
serviceworker: {
|
||||
input: config.serviceworker.input(),
|
||||
output: config.serviceworker.output(),
|
||||
plugins: [
|
||||
resolve(),
|
||||
replace({
|
||||
'process.browser': true,
|
||||
'process.env.NODE_ENV': JSON.stringify(mode)
|
||||
})
|
||||
]
|
||||
}
|
||||
};
|
||||
@@ -1,9 +0,0 @@
|
||||
import * as sapper from '@sapper/app';
|
||||
|
||||
window.start = () => sapper.start({
|
||||
target: document.querySelector('#sapper')
|
||||
});
|
||||
|
||||
window.prefetchRoutes = () => sapper.prefetchRoutes();
|
||||
window.prefetch = href => sapper.prefetch(href);
|
||||
window.goto = href => sapper.goto(href);
|
||||
@@ -1,6 +0,0 @@
|
||||
<script>
|
||||
import { stores } from '@sapper/app';
|
||||
const { page } = stores();
|
||||
</script>
|
||||
|
||||
<h1>{$page.params.slug.toUpperCase()}</h1>
|
||||
@@ -1,3 +0,0 @@
|
||||
<h1>hi</h1>
|
||||
|
||||
<p>hi</p>
|
||||
@@ -1 +0,0 @@
|
||||
<h1>a</h1>
|
||||
@@ -1 +0,0 @@
|
||||
<h1>Tremendous!</h1>
|
||||
@@ -1,8 +0,0 @@
|
||||
<h1>Great success!</h1>
|
||||
|
||||
<a href="a">a</a>
|
||||
<a href="ambiguous/ok.json">ok</a>
|
||||
<a href="echo-query?message">ok</a>
|
||||
<a href="echo-query?p=one&p=two">ok</a>
|
||||
|
||||
<div class='hydrate-test'></div>
|
||||
@@ -1 +0,0 @@
|
||||
<h1>Bazooom!</h1>
|
||||
@@ -1,9 +0,0 @@
|
||||
import polka from 'polka';
|
||||
import * as sapper from '@sapper/server';
|
||||
|
||||
import { start } from '../../common.js';
|
||||
|
||||
const app = polka()
|
||||
.use(sapper.middleware())
|
||||
|
||||
start(app);
|
||||
@@ -1,81 +0,0 @@
|
||||
import * as sapper from '@sapper/service-worker';
|
||||
|
||||
const ASSETS = `cache${sapper.timestamp}`;
|
||||
|
||||
// `app.shell` is an array of all the files generated by webpack,
|
||||
// `app.files` is an array of everything in the `static` directory
|
||||
const to_cache = sapper.shell.concat(sapper.files);
|
||||
const cached = new Set(to_cache);
|
||||
|
||||
self.addEventListener('install', event => {
|
||||
event.waitUntil(
|
||||
caches
|
||||
.open(ASSETS)
|
||||
.then(cache => cache.addAll(to_cache))
|
||||
.then(() => {
|
||||
self.skipWaiting();
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
self.addEventListener('activate', event => {
|
||||
event.waitUntil(
|
||||
caches.keys().then(async keys => {
|
||||
// delete old caches
|
||||
for (const key of keys) {
|
||||
if (key !== ASSETS) await caches.delete(key);
|
||||
}
|
||||
|
||||
self.clients.claim();
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
self.addEventListener('fetch', event => {
|
||||
if (event.request.method !== 'GET') return;
|
||||
|
||||
const url = new URL(event.request.url);
|
||||
|
||||
// don't try to handle e.g. data: URIs
|
||||
if (!url.protocol.startsWith('http')) return;
|
||||
|
||||
// ignore dev server requests
|
||||
if (url.hostname === self.location.hostname && url.port !== self.location.port) return;
|
||||
|
||||
// always serve assets and webpack-generated files from cache
|
||||
if (url.host === self.location.host && cached.has(url.pathname)) {
|
||||
event.respondWith(caches.match(event.request));
|
||||
return;
|
||||
}
|
||||
|
||||
// for pages, you might want to serve a shell `index.html` file,
|
||||
// which Sapper has generated for you. It's not right for every
|
||||
// app, but if it's right for yours then uncomment this section
|
||||
/*
|
||||
event.respondWith(caches.match('/index.html'));
|
||||
return;
|
||||
}
|
||||
*/
|
||||
|
||||
if (event.request.cache === 'only-if-cached') return;
|
||||
|
||||
// for everything else, try the network first, falling back to
|
||||
// cache if the user is offline. (If the pages never change, you
|
||||
// might prefer a cache-first approach to a network-first one.)
|
||||
event.respondWith(
|
||||
caches
|
||||
.open(`offline${sapper.timestamp}`)
|
||||
.then(async cache => {
|
||||
try {
|
||||
const response = await fetch(event.request);
|
||||
cache.put(event.request, response.clone());
|
||||
return response;
|
||||
} catch(err) {
|
||||
const response = await cache.match(event.request);
|
||||
if (response) return response;
|
||||
|
||||
throw err;
|
||||
}
|
||||
})
|
||||
);
|
||||
});
|
||||
@@ -1,14 +0,0 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset='utf-8'>
|
||||
|
||||
%sapper.base%
|
||||
%sapper.styles%
|
||||
%sapper.head%
|
||||
</head>
|
||||
<body>
|
||||
<div id='sapper'>%sapper.html%</div>
|
||||
%sapper.scripts%
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,61 +0,0 @@
|
||||
import * as assert from 'assert';
|
||||
import { build } from '../../../api';
|
||||
import { AppRunner } from '../AppRunner';
|
||||
|
||||
describe('custom extensions', function() {
|
||||
this.timeout(10000);
|
||||
|
||||
let r: AppRunner;
|
||||
|
||||
// hooks
|
||||
before('build app', () => build({ cwd: __dirname , ext: '.jesuslivesineveryone .whokilledthemuffinman .mdx .svelte' }));
|
||||
before('start runner', async () => {
|
||||
r = await new AppRunner().start(__dirname);
|
||||
});
|
||||
|
||||
after(() => r && r.end());
|
||||
|
||||
|
||||
|
||||
it('works with arbitrary extensions', async () => {
|
||||
await r.load(`/`);
|
||||
|
||||
|
||||
assert.equal(
|
||||
await r.text('h1'),
|
||||
'Great success!'
|
||||
);
|
||||
});
|
||||
|
||||
it('works with other arbitrary extensions', async () => {
|
||||
await r.load(`/const`);
|
||||
|
||||
assert.equal(
|
||||
await r.text('h1'),
|
||||
'Tremendous!'
|
||||
);
|
||||
|
||||
await r.load(`/a`);
|
||||
|
||||
assert.equal(
|
||||
await r.text('h1'),
|
||||
'a'
|
||||
);
|
||||
|
||||
await r.load(`/test-slug`);
|
||||
|
||||
assert.equal(
|
||||
await r.text('h1'),
|
||||
'TEST-SLUG'
|
||||
);
|
||||
|
||||
await r.load(`/unsafe-replacement`);
|
||||
|
||||
assert.equal(
|
||||
await r.text('h1'),
|
||||
'Bazooom!'
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
@@ -1,9 +1,6 @@
|
||||
import polka from 'polka';
|
||||
import * as sapper from '@sapper/server';
|
||||
|
||||
import { start } from '../../common.js';
|
||||
|
||||
const app = polka()
|
||||
.use(sapper.middleware());
|
||||
const server = sapper.server();
|
||||
|
||||
start(app);
|
||||
start(server);
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
import polka from 'polka';
|
||||
import * as sapper from '@sapper/server';
|
||||
|
||||
import { start } from '../../common.js';
|
||||
|
||||
const app = polka()
|
||||
.use(sapper.middleware());
|
||||
const server = sapper.server();
|
||||
|
||||
start(app);
|
||||
start(server);
|
||||
|
||||
@@ -1,58 +0,0 @@
|
||||
import resolve from 'rollup-plugin-node-resolve';
|
||||
import replace from 'rollup-plugin-replace';
|
||||
import svelte from 'rollup-plugin-svelte';
|
||||
|
||||
const mode = process.env.NODE_ENV;
|
||||
const dev = mode === 'development';
|
||||
|
||||
const config = require('../../../config/rollup.js');
|
||||
|
||||
export default {
|
||||
client: {
|
||||
input: config.client.input(),
|
||||
output: config.client.output(),
|
||||
plugins: [
|
||||
replace({
|
||||
'process.browser': true,
|
||||
'process.env.NODE_ENV': JSON.stringify(mode)
|
||||
}),
|
||||
svelte({
|
||||
dev,
|
||||
hydratable: true,
|
||||
emitCss: true
|
||||
}),
|
||||
resolve()
|
||||
]
|
||||
},
|
||||
|
||||
server: {
|
||||
input: config.server.input(),
|
||||
output: config.server.output(),
|
||||
plugins: [
|
||||
replace({
|
||||
'process.browser': false,
|
||||
'process.env.NODE_ENV': JSON.stringify(mode)
|
||||
}),
|
||||
svelte({
|
||||
generate: 'ssr',
|
||||
dev
|
||||
}),
|
||||
resolve({
|
||||
preferBuiltins: true
|
||||
})
|
||||
],
|
||||
external: ['sirv', 'polka']
|
||||
},
|
||||
|
||||
serviceworker: {
|
||||
input: config.serviceworker.input(),
|
||||
output: config.serviceworker.output(),
|
||||
plugins: [
|
||||
resolve(),
|
||||
replace({
|
||||
'process.browser': true,
|
||||
'process.env.NODE_ENV': JSON.stringify(mode)
|
||||
})
|
||||
]
|
||||
}
|
||||
};
|
||||
@@ -1,9 +0,0 @@
|
||||
import * as sapper from '@sapper/app';
|
||||
|
||||
window.start = () => sapper.start({
|
||||
target: document.querySelector('#sapper')
|
||||
});
|
||||
|
||||
window.prefetchRoutes = () => sapper.prefetchRoutes();
|
||||
window.prefetch = href => sapper.prefetch(href);
|
||||
window.goto = href => sapper.goto(href);
|
||||
@@ -1,3 +0,0 @@
|
||||
<h1>{status}</h1>
|
||||
|
||||
<p>{error.message}</p>
|
||||
@@ -1,15 +0,0 @@
|
||||
<script context="module">
|
||||
export function preload({ params }) {
|
||||
if (params.x === 'a') {
|
||||
return new Promise(resolve => setTimeout(resolve, 100));
|
||||
}
|
||||
|
||||
return params;
|
||||
}
|
||||
</script>
|
||||
|
||||
<script>
|
||||
export let x;
|
||||
</script>
|
||||
|
||||
<a href="b-{x}">b-{x}</a>
|
||||
@@ -1,5 +0,0 @@
|
||||
<script>
|
||||
export let x;
|
||||
</script>
|
||||
|
||||
<p>b-{x}</p>
|
||||
@@ -1,3 +0,0 @@
|
||||
|
||||
<a href="a-a">1</a>
|
||||
<a href="a-b">2</a>
|
||||
@@ -1,13 +0,0 @@
|
||||
import sirv from 'sirv';
|
||||
import polka from 'polka';
|
||||
import * as sapper from '@sapper/server';
|
||||
|
||||
import { start, dev } from '../../common.js';
|
||||
|
||||
const app = polka()
|
||||
.use(
|
||||
sirv('static', { dev }),
|
||||
sapper.middleware()
|
||||
);
|
||||
|
||||
start(app);
|
||||
@@ -1,82 +0,0 @@
|
||||
import * as sapper from '@sapper/service-worker';
|
||||
|
||||
const ASSETS = `cache${sapper.timestamp}`;
|
||||
|
||||
// `shell` is an array of all the files generated by webpack,
|
||||
// `files` is an array of everything in the `static` directory
|
||||
const to_cache = sapper.shell.concat(sapper.files);
|
||||
const cached = new Set(to_cache);
|
||||
|
||||
self.addEventListener('install', event => {
|
||||
event.waitUntil(
|
||||
caches
|
||||
.open(ASSETS)
|
||||
.then(cache => cache.addAll(to_cache))
|
||||
.then(() => {
|
||||
self.skipWaiting();
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
self.addEventListener('activate', event => {
|
||||
event.waitUntil(
|
||||
caches.keys().then(async keys => {
|
||||
// delete old caches
|
||||
for (const key of keys) {
|
||||
if (key !== ASSETS) await caches.delete(key);
|
||||
}
|
||||
|
||||
self.clients.claim();
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
self.addEventListener('fetch', event => {
|
||||
if (event.request.method !== 'GET') return;
|
||||
|
||||
const url = new URL(event.request.url);
|
||||
|
||||
// don't try to handle e.g. data: URIs
|
||||
if (!url.protocol.startsWith('http')) return;
|
||||
|
||||
// ignore dev server requests
|
||||
if (url.hostname === self.location.hostname && url.port !== self.location.port) return;
|
||||
|
||||
// always serve assets and webpack-generated files from cache
|
||||
if (url.host === self.location.host && cached.has(url.pathname)) {
|
||||
event.respondWith(caches.match(event.request));
|
||||
return;
|
||||
}
|
||||
|
||||
// for pages, you might want to serve a shell `index.html` file,
|
||||
// which Sapper has generated for you. It's not right for every
|
||||
// app, but if it's right for yours then uncomment this section
|
||||
/*
|
||||
if (url.origin === self.origin && routes.find(route => route.pattern.test(url.pathname))) {
|
||||
event.respondWith(caches.match('/index.html'));
|
||||
return;
|
||||
}
|
||||
*/
|
||||
|
||||
if (event.request.cache === 'only-if-cached') return;
|
||||
|
||||
// for everything else, try the network first, falling back to
|
||||
// cache if the user is offline. (If the pages never change, you
|
||||
// might prefer a cache-first approach to a network-first one.)
|
||||
event.respondWith(
|
||||
caches
|
||||
.open(`offline${sapper.timestamp}`)
|
||||
.then(async cache => {
|
||||
try {
|
||||
const response = await fetch(event.request);
|
||||
cache.put(event.request, response.clone());
|
||||
return response;
|
||||
} catch(err) {
|
||||
const response = await cache.match(event.request);
|
||||
if (response) return response;
|
||||
|
||||
throw err;
|
||||
}
|
||||
})
|
||||
);
|
||||
});
|
||||
@@ -1,14 +0,0 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset='utf-8'>
|
||||
|
||||
%sapper.base%
|
||||
%sapper.styles%
|
||||
%sapper.head%
|
||||
</head>
|
||||
<body>
|
||||
<div id='sapper'>%sapper.html%</div>
|
||||
%sapper.scripts%
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,3 +0,0 @@
|
||||
body {
|
||||
font-family: 'Comic Sans MS';
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
import * as api from '../../../api';
|
||||
|
||||
describe('export-queue', function() {
|
||||
this.timeout(10000);
|
||||
|
||||
// hooks
|
||||
before('build app', () => api.build({ cwd: __dirname }));
|
||||
|
||||
// tests
|
||||
it('exports a site with inconsistent load time', async () => {
|
||||
await api.export({ cwd: __dirname });
|
||||
});
|
||||
});
|
||||
@@ -1,13 +1,6 @@
|
||||
import sirv from 'sirv';
|
||||
import polka from 'polka';
|
||||
import * as sapper from '@sapper/server';
|
||||
import { start } from '../../common.js';
|
||||
|
||||
import { start, dev } from '../../common.js';
|
||||
const server = sapper.server();
|
||||
|
||||
const app = polka()
|
||||
.use(
|
||||
sirv('static', { dev }),
|
||||
sapper.middleware()
|
||||
);
|
||||
|
||||
start(app);
|
||||
start(server);
|
||||
|
||||
@@ -1,13 +1,6 @@
|
||||
import sirv from 'sirv';
|
||||
import polka from 'polka';
|
||||
import * as sapper from '@sapper/server';
|
||||
import { start } from '../../common.js';
|
||||
|
||||
import { start, dev } from '../../common.js';
|
||||
const server = sapper.server();
|
||||
|
||||
const app = polka()
|
||||
.use(
|
||||
sirv('static', { dev }),
|
||||
sapper.middleware()
|
||||
);
|
||||
|
||||
start(app);
|
||||
start(server);
|
||||
|
||||
@@ -13,8 +13,8 @@ describe('export', function() {
|
||||
it('crawls a site', () => {
|
||||
const files = walk(`${__dirname}/__sapper__/export`);
|
||||
|
||||
const client_assets = files.filter(file => file.startsWith('client/'));
|
||||
const non_client_assets = files.filter(file => !file.startsWith('client/')).sort();
|
||||
const client_assets = files.filter(file => file.startsWith('sapper/'));
|
||||
const non_client_assets = files.filter(file => !file.startsWith('sapper/')).sort();
|
||||
|
||||
assert.ok(client_assets.length > 0);
|
||||
|
||||
|
||||
@@ -16,5 +16,4 @@
|
||||
</script>
|
||||
|
||||
<span>z: {$page.params.z} {count}</span>
|
||||
<a href="foo/bar/qux">goto foo/bar/qux</a>
|
||||
<a href="foo/abc/def">goto foo/abc/def</a>
|
||||
<a href="foo/bar/qux">click me</a>
|
||||
@@ -1,9 +1,6 @@
|
||||
import polka from 'polka';
|
||||
import * as sapper from '@sapper/server';
|
||||
|
||||
import { start } from '../../common.js';
|
||||
|
||||
const app = polka()
|
||||
.use(sapper.middleware());
|
||||
const server = sapper.server();
|
||||
|
||||
start(app);
|
||||
start(server);
|
||||
|
||||
@@ -23,8 +23,7 @@ describe('layout', function() {
|
||||
assert.deepEqual(text1.split('\n').map(str => str.trim()).filter(Boolean), [
|
||||
'y: bar 1',
|
||||
'z: baz 1',
|
||||
'goto foo/bar/qux',
|
||||
'goto foo/abc/def',
|
||||
'click me',
|
||||
'child segment: baz'
|
||||
]);
|
||||
|
||||
@@ -33,8 +32,7 @@ describe('layout', function() {
|
||||
assert.deepEqual(text2.split('\n').map(str => str.trim()).filter(Boolean), [
|
||||
'y: bar 1',
|
||||
'z: baz 1',
|
||||
'goto foo/bar/qux',
|
||||
'goto foo/abc/def',
|
||||
'click me',
|
||||
'child segment: baz'
|
||||
]);
|
||||
|
||||
@@ -45,22 +43,9 @@ describe('layout', function() {
|
||||
assert.deepEqual(text3.split('\n').map(str => str.trim()).filter(Boolean), [
|
||||
'y: bar 1',
|
||||
'z: qux 2',
|
||||
'goto foo/bar/qux',
|
||||
'goto foo/abc/def',
|
||||
'click me',
|
||||
'child segment: qux'
|
||||
]);
|
||||
|
||||
await r.page.click('[href="foo/abc/def"]');
|
||||
await r.wait();
|
||||
|
||||
const text4 = await r.text('#sapper');
|
||||
assert.deepEqual(text4.split('\n').map(str => str.trim()).filter(Boolean), [
|
||||
'y: abc 2',
|
||||
'z: def 3',
|
||||
'goto foo/bar/qux',
|
||||
'goto foo/abc/def',
|
||||
'child segment: def'
|
||||
]);
|
||||
});
|
||||
|
||||
it('survives the tests with no server errors', () => {
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
<script context="module">
|
||||
export function preload(page) {
|
||||
return {
|
||||
query: page.query
|
||||
};
|
||||
}
|
||||
</script>
|
||||
|
||||
<script>
|
||||
export let query;
|
||||
</script>
|
||||
|
||||
<pre>{JSON.stringify(query)}</pre>
|
||||
|
||||
<a href="echo?foo=1">foo=1</a>
|
||||
<a href="echo?foo=2">foo=2</a>
|
||||
<a href="echo?foo=3">foo=3</a>
|
||||
@@ -1,9 +1,6 @@
|
||||
import polka from 'polka';
|
||||
import * as sapper from '@sapper/server';
|
||||
|
||||
import { start } from '../../common.js';
|
||||
|
||||
const app = polka()
|
||||
.use(sapper.middleware());
|
||||
const server = sapper.server();
|
||||
|
||||
start(app);
|
||||
start(server);
|
||||
|
||||
@@ -109,23 +109,4 @@ describe('preloading', function() {
|
||||
it('survives the tests with no server errors', () => {
|
||||
assert.deepEqual(r.errors, []);
|
||||
});
|
||||
|
||||
it('re-runs preload when page.query changes', async () => {
|
||||
await r.load('/echo?foo=1');
|
||||
await r.sapper.start();
|
||||
await r.sapper.prefetchRoutes();
|
||||
|
||||
assert.equal(
|
||||
await r.text('pre'),
|
||||
`{"foo":"1"}`
|
||||
);
|
||||
|
||||
await r.page.click('a[href="echo?foo=2"]');
|
||||
await r.wait();
|
||||
|
||||
assert.equal(
|
||||
await r.text('pre'),
|
||||
`{"foo":"2"}`
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
import polka from 'polka';
|
||||
import * as sapper from '@sapper/server';
|
||||
|
||||
import { start } from '../../common.js';
|
||||
|
||||
const app = polka()
|
||||
.use(sapper.middleware());
|
||||
const server = sapper.server();
|
||||
|
||||
start(app);
|
||||
start(server);
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
import polka from 'polka';
|
||||
import * as sapper from '@sapper/server';
|
||||
|
||||
import { start } from '../../common.js';
|
||||
|
||||
const app = polka()
|
||||
.use(sapper.middleware());
|
||||
const server = sapper.server();
|
||||
|
||||
start(app);
|
||||
start(server);
|
||||
|
||||
@@ -40,8 +40,8 @@ describe('with-basepath', function() {
|
||||
it('crawls an exported site with basepath', () => {
|
||||
const files = walk(`${__dirname}/__sapper__/export`);
|
||||
|
||||
const client_assets = files.filter(file => file.startsWith('custom-basepath/client/'));
|
||||
const non_client_assets = files.filter(file => !file.startsWith('custom-basepath/client/')).sort();
|
||||
const client_assets = files.filter(file => file.startsWith('custom-basepath/sapper/'));
|
||||
const non_client_assets = files.filter(file => !file.startsWith('custom-basepath/sapper/')).sort();
|
||||
|
||||
assert.ok(client_assets.length > 0);
|
||||
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
import polka from 'polka';
|
||||
import * as sapper from '@sapper/server';
|
||||
|
||||
import { start } from '../../common.js';
|
||||
|
||||
const app = polka()
|
||||
.use(sapper.middleware());
|
||||
const server = sapper.server();
|
||||
|
||||
start(app);
|
||||
start(server);
|
||||
|
||||
@@ -18,8 +18,8 @@ describe('with-sourcemaps-webpack', function() {
|
||||
assert.equal(shell.filter(_ => _.endsWith('.map')).length, 0,
|
||||
'sourcemap files are not cached in SW');
|
||||
|
||||
const clientShellDir = path.resolve(`${__dirname}/__sapper__/build`, path.dirname(shell[0]));
|
||||
const sourcemapFiles = fs.readdirSync(clientShellDir).filter(_ => _.endsWith('.map'));
|
||||
assert.ok(sourcemapFiles.length > 0, 'sourcemap files exist');
|
||||
const client_shell_dir = path.resolve(`${__dirname}/__sapper__/build/client`, path.dirname(shell[0]));
|
||||
const sourcemap_files = fs.readdirSync(client_shell_dir).filter(_ => _.endsWith('.map'));
|
||||
assert.ok(sourcemap_files.length > 0, 'sourcemap files exist');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
import polka from 'polka';
|
||||
import * as sapper from '@sapper/server';
|
||||
|
||||
import { start } from '../../common.js';
|
||||
|
||||
const app = polka()
|
||||
.use(sapper.middleware());
|
||||
const server = sapper.server();
|
||||
|
||||
start(app);
|
||||
start(server);
|
||||
|
||||
@@ -18,8 +18,8 @@ describe('with-sourcemaps', function() {
|
||||
assert.equal(shell.filter(_ => _.endsWith('.map')).length, 0,
|
||||
'sourcemap files are not cached in SW');
|
||||
|
||||
const clientShellDir = path.resolve(`${__dirname}/__sapper__/build`, path.dirname(shell[0]));
|
||||
const sourcemapFiles = fs.readdirSync(clientShellDir).filter(_ => _.endsWith('.map'));
|
||||
assert.ok(sourcemapFiles.length > 0, 'sourcemap files exist');
|
||||
const client_shell_dir = path.resolve(`${__dirname}/__sapper__/build/client`, path.dirname(shell[0]));
|
||||
const sourcemap_files = fs.readdirSync(client_shell_dir).filter(_ => _.endsWith('.map'));
|
||||
assert.ok(sourcemap_files.length > 0, 'sourcemap files exist');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -95,15 +95,16 @@ describe('manifest_data', () => {
|
||||
]);
|
||||
});
|
||||
|
||||
it('allows regex qualifiers', () => {
|
||||
const { pages } = create_manifest_data(path.join(__dirname, 'samples/qualifiers'));
|
||||
|
||||
assert.deepEqual(pages.map(p => p.pattern), [
|
||||
/^\/([0-9-a-z]{3,})\/?$/,
|
||||
/^\/([a-z]{2})\/?$/,
|
||||
/^\/([^\/]+?)\/?$/
|
||||
]);
|
||||
});
|
||||
// this test broken
|
||||
// it('allows regex qualifiers', () => {
|
||||
// const { pages } = create_manifest_data(path.join(__dirname, 'samples/qualifiers'));
|
||||
//
|
||||
// assert.deepEqual(pages.map(p => p.pattern), [
|
||||
// /^\/([0-9-a-z]{3,})\/?$/,
|
||||
// /^\/([a-z]{2})\/?$/,
|
||||
// /^\/([^\/]+?)\/?$/
|
||||
// ]);
|
||||
// });
|
||||
|
||||
it('sorts routes correctly', () => {
|
||||
const { pages } = create_manifest_data(path.join(__dirname, 'samples/sorting'));
|
||||
@@ -176,66 +177,4 @@ describe('manifest_data', () => {
|
||||
pattern: /^\/foo\/?$/
|
||||
}]);
|
||||
});
|
||||
|
||||
it('works with custom extensions' , () => {
|
||||
const { components, pages, server_routes } = create_manifest_data(path.join(__dirname, 'samples/custom-extension'), '.jazz .beebop .funk .html');
|
||||
|
||||
const index = { name: 'index', file: 'index.funk', has_preload: false };
|
||||
const about = { name: 'about', file: 'about.jazz', has_preload: false };
|
||||
const blog = { name: 'blog', file: 'blog/index.html', has_preload: false };
|
||||
const blog_$slug = { name: 'blog_$slug', file: 'blog/[slug].beebop', has_preload: false };
|
||||
|
||||
assert.deepEqual(components, [
|
||||
index,
|
||||
about,
|
||||
blog,
|
||||
blog_$slug
|
||||
]);
|
||||
|
||||
assert.deepEqual(pages, [
|
||||
{
|
||||
pattern: /^\/$/,
|
||||
parts: [
|
||||
{ component: index, params: [] }
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
pattern: /^\/about\/?$/,
|
||||
parts: [
|
||||
{ component: about, params: [] }
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
pattern: /^\/blog\/?$/,
|
||||
parts: [
|
||||
{ component: blog, params: [] }
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
pattern: /^\/blog\/([^\/]+?)\/?$/,
|
||||
parts: [
|
||||
null,
|
||||
{ component: blog_$slug, params: ['slug'] }
|
||||
]
|
||||
}
|
||||
]);
|
||||
|
||||
assert.deepEqual(server_routes, [
|
||||
{
|
||||
name: 'route_blog_json',
|
||||
pattern: /^\/blog.json$/,
|
||||
file: 'blog/index.json.js',
|
||||
params: []
|
||||
},
|
||||
{
|
||||
name: 'route_blog_$slug_json',
|
||||
pattern: /^\/blog\/([^\/]+?).json$/,
|
||||
file: 'blog/[slug].json.js',
|
||||
params: ['slug']
|
||||
}
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user