Compare commits

...

24 Commits

Author SHA1 Message Date
Rich Harris
cbbf4a95db -> v0.15.8 2018-08-16 12:46:13 -04:00
Rich Harris
55b7ffd2ed Merge pull request #361 from sveltejs/handle-unknown-preload-errors
handle unknown preload errors
2018-08-16 12:44:27 -04:00
Rich Harris
9f4d4e70de can remove this, preloading is set false on render 2018-08-16 12:39:54 -04:00
Rich Harris
deef1bbfcf handle unknown preload errors 2018-08-16 12:25:23 -04:00
Seth Thompson
17b0fc0d0c nit 2018-08-11 17:52:53 -04:00
Seth Thompson
3c44c511e4 make sure page has expected preloading value 2018-08-11 17:51:44 -04:00
Seth Thompson
7cf1b9613a prefetching should not set root preloading value, closes #352 2018-08-11 12:26:27 -04:00
Rich Harris
99e5a9601c -> v0.15.7 2018-08-09 20:14:37 -04:00
Rich Harris
4c9c1dccf5 Merge pull request #350 from sveltejs/gh-344
pass response object to store getter
2018-08-09 20:13:17 -04:00
Rich Harris
2cddd5afa0 Merge pull request #345 from sveltejs/fix/redirect
Fix Preload's Redirect
2018-08-09 20:08:51 -04:00
Rich Harris
8c6a0c4773 Merge branch 'master' into gh-344 2018-08-09 20:03:37 -04:00
Rich Harris
af5063552d Merge pull request #351 from sveltejs/argh-windows
doh
2018-08-09 20:02:51 -04:00
Rich Harris
419d154794 fffffuuuuu 2018-08-09 19:53:26 -04:00
Rich Harris
abda059be5 doh 2018-08-09 19:46:09 -04:00
Rich Harris
444908cac5 pass response object to store getter - fixes #344 2018-08-08 10:57:10 -04:00
Luke Edwards
c6da26e1a0 add redirect test to root (“/“) 2018-08-06 20:29:28 -07:00
Luke Edwards
aad87857ce fix: replace leading slash in preload’s redirect 2018-08-06 20:28:28 -07:00
Rich Harris
666c113297 -> v0.15.6 2018-08-06 22:36:17 -04:00
Rich Harris
84a58f34a0 add test for exporting with custom basepath 2018-08-06 22:35:02 -04:00
Rich Harris
75f5b5c721 Merge pull request #342 from aubergene/gh-338
Remove basepath from deferred urls and add trailing slash to root
2018-08-06 22:06:09 -04:00
Julian Burgess
a176a3b79b Remove basepath from deferred urls and add trailing slash to root request 2018-08-06 16:43:02 +01:00
Rich Harris
1627a5767a -> v0.15.5 2018-08-03 01:18:12 -04:00
Rich Harris
6ff3a9e9ab Merge branch 'master' of github.com:sveltejs/sapper 2018-08-03 01:16:43 -04:00
Rich Harris
3ce2bd30f9 Use npm ci instead of npm install (#336)
* dont write server_info.json either - second half of #318

* use npm ci

* update lockfile

* try this
2018-08-03 01:16:26 -04:00
11 changed files with 104 additions and 27 deletions

View File

@@ -18,4 +18,4 @@ addons:
install: install:
- export DISPLAY=':99.0' - export DISPLAY=':99.0'
- Xvfb :99 -screen 0 1024x768x24 > /dev/null 2>&1 & - Xvfb :99 -screen 0 1024x768x24 > /dev/null 2>&1 &
- npm install - npm ci || npm i

View File

@@ -1,5 +1,19 @@
# sapper changelog # sapper changelog
## 0.15.8
* Only set `preloading: true` on navigation, not prefetch ([#352](https://github.com/sveltejs/sapper/issues/352))
* Provide fallback for missing preload errors ([#361](https://github.com/sveltejs/sapper/pull/361))
## 0.15.7
* Strip leading slash from redirects ([#291](https://github.com/sveltejs/sapper/issues/291))
* Pass `(req, res)` to store getter ([#344](https://github.com/sveltejs/sapper/issues/344))
## 0.15.6
* Fix exporting with custom basepath ([#342](https://github.com/sveltejs/sapper/pull/342))
## 0.15.5 ## 0.15.5
* Faster `export` with more explanatory output ([#335](https://github.com/sveltejs/sapper/pull/335)) * Faster `export` with more explanatory output ([#335](https://github.com/sveltejs/sapper/pull/335))

View File

@@ -14,7 +14,7 @@ environment:
install: install:
- ps: Install-Product node $env:nodejs_version - ps: Install-Product node $env:nodejs_version
- npm install - npm ci
test_script: test_script:
- node --version && npm --version - node --version && npm --version

View File

@@ -1,6 +1,6 @@
{ {
"name": "sapper", "name": "sapper",
"version": "0.15.4", "version": "0.15.8",
"description": "Military-grade apps, engineered by Svelte", "description": "Military-grade apps, engineered by Svelte",
"main": "dist/middleware.ts.js", "main": "dist/middleware.ts.js",
"bin": { "bin": {

View File

@@ -51,9 +51,10 @@ async function execute(emitter: EventEmitter, {
const port = await ports.find(3000); const port = await ports.find(3000);
const origin = `http://localhost:${port}`; const origin = `http://localhost:${port}`;
const root = new URL(basepath || '', origin);
emitter.emit('info', { emitter.emit('info', {
message: `Crawling ${origin}` message: `Crawling ${root.href}`
}); });
const proc = child_process.fork(path.resolve(`${build}/server.js`), [], { const proc = child_process.fork(path.resolve(`${build}/server.js`), [], {
@@ -71,8 +72,10 @@ async function execute(emitter: EventEmitter, {
const deferreds = new Map(); const deferreds = new Map();
function get_deferred(pathname: string) { function get_deferred(pathname: string) {
pathname = pathname.replace(root.pathname, '');
if (!deferreds.has(pathname)) { if (!deferreds.has(pathname)) {
deferreds.set(pathname, new Deferred()) ; deferreds.set(pathname, new Deferred());
} }
return deferreds.get(pathname); return deferreds.get(pathname);
@@ -107,7 +110,7 @@ async function execute(emitter: EventEmitter, {
}); });
async function handle(url: URL) { async function handle(url: URL) {
const pathname = url.pathname || '/'; const pathname = (url.pathname.replace(root.pathname, '') || '/');
if (seen.has(pathname)) return; if (seen.has(pathname)) return;
seen.add(pathname); seen.add(pathname);
@@ -138,6 +141,9 @@ async function execute(emitter: EventEmitter, {
} }
return ports.wait(port) return ports.wait(port)
.then(() => handle(new URL(`/${basepath}`, origin))) // TODO all static routes .then(() => {
// TODO all static routes
return handle(root);
})
.then(() => proc.kill()); .then(() => proc.kill());
} }

View File

@@ -83,7 +83,7 @@ function toIgnore(uri: string, val: any) {
export default function middleware(opts: { export default function middleware(opts: {
manifest: Manifest, manifest: Manifest,
store: (req: Req) => Store, store: (req: Req, res: ServerResponse) => Store,
ignore?: any, ignore?: any,
routes?: any // legacy routes?: any // legacy
}) { }) {
@@ -276,7 +276,10 @@ function get_server_route_handler(routes: ServerRoute[]) {
}; };
} }
function get_page_handler(manifest: Manifest, store_getter: (req: Req) => Store) { function get_page_handler(
manifest: Manifest,
store_getter: (req: Req, res: ServerResponse) => Store
) {
const output = locations.dest(); const output = locations.dest();
const get_chunks = dev() const get_chunks = dev()
@@ -296,13 +299,10 @@ function get_page_handler(manifest: Manifest, store_getter: (req: Req) => Store)
parts: [ parts: [
{ name: null, component: error_route } { name: null, component: error_route }
] ]
}, req, res, statusCode, error); }, req, res, statusCode, error || new Error('Unknown error in preload function'));
} }
function handle_page(page: Page, req: Req, res: ServerResponse, status = 200, error: Error | string = null) { function handle_page(page: Page, req: Req, res: ServerResponse, status = 200, error: Error | string = null) {
const get_params = page.parts[page.parts.length - 1].params || (() => ({}));
const match = error ? null : page.pattern.exec(req.path);
const chunks: Record<string, string | string[]> = get_chunks(); const chunks: Record<string, string | string[]> = get_chunks();
res.setHeader('Content-Type', 'text/html'); res.setHeader('Content-Type', 'text/html');
@@ -326,7 +326,7 @@ function get_page_handler(manifest: Manifest, store_getter: (req: Req) => Store)
res.setHeader('Link', link); res.setHeader('Link', link);
const store = store_getter ? store_getter(req) : null; const store = store_getter ? store_getter(req, res) : null;
let redirect: { statusCode: number, location: string }; let redirect: { statusCode: number, location: string };
let preload_error: { statusCode: number, message: Error | string }; let preload_error: { statusCode: number, message: Error | string };
@@ -336,6 +336,7 @@ function get_page_handler(manifest: Manifest, store_getter: (req: Req) => Store)
if (redirect && (redirect.statusCode !== statusCode || redirect.location !== location)) { if (redirect && (redirect.statusCode !== statusCode || redirect.location !== location)) {
throw new Error(`Conflicting redirects`); throw new Error(`Conflicting redirects`);
} }
location = location.replace(/^\//g, ''); // leading slash (only)
redirect = { statusCode, location }; redirect = { statusCode, location };
}, },
error: (statusCode: number, message: Error | string) => { error: (statusCode: number, message: Error | string) => {
@@ -387,6 +388,8 @@ function get_page_handler(manifest: Manifest, store_getter: (req: Req) => Store)
}) })
: {}; : {};
const match = error ? null : page.pattern.exec(req.path);
Promise.all([root_preloaded].concat(page.parts.map(part => { Promise.all([root_preloaded].concat(page.parts.map(part => {
if (!part) return null; if (!part) return null;
@@ -582,4 +585,4 @@ function escape_html(html: string) {
}; };
return html.replace(/["'&<>]/g, c => `&${chars[c]};`); return html.replace(/["'&<>]/g, c => `&${chars[c]};`);
} }

View File

@@ -136,10 +136,6 @@ function prepare_page(target: Target): Promise<{
data?: any; data?: any;
nullable_depth?: number; nullable_depth?: number;
}> { }> {
if (root) {
root.set({ preloading: true });
}
const { page, path, query } = target; const { page, path, query } = target;
const new_segments = path.split('/').filter(Boolean); const new_segments = path.split('/').filter(Boolean);
let changed_from = 0; let changed_from = 0;
@@ -285,6 +281,9 @@ async function navigate(target: Target, id: number): Promise<any> {
cid = id; cid = id;
if (root) {
root.set({ preloading: true });
}
const loaded = prefetching && prefetching.href === target.url.href ? const loaded = prefetching && prefetching.href === target.url.href ?
prefetching.promise : prefetching.promise :
prepare_page(target); prepare_page(target);

View File

@@ -85,11 +85,18 @@ const middlewares = [
next(); next();
}, },
// set up some values for the store
(req, res, next) => {
req.hello = 'hello';
res.locals = { name: 'world' };
next();
},
sapper({ sapper({
manifest, manifest,
store: () => { store: (req, res) => {
return new Store({ return new Store({
title: 'Stored title' title: `${req.hello} ${res.locals.name}`
}); });
}, },
ignore: [ ignore: [

View File

@@ -8,6 +8,7 @@
<a href='about'>about</a> <a href='about'>about</a>
<a href='slow-preload'>slow preload</a> <a href='slow-preload'>slow preload</a>
<a href='redirect-from'>redirect</a> <a href='redirect-from'>redirect</a>
<a href='redirect-root'>redirect (root)</a>
<a href='blog/nope'>broken link</a> <a href='blog/nope'>broken link</a>
<a href='blog/throw-an-error'>error link</a> <a href='blog/throw-an-error'>error link</a>
<a href='credentials?creds=include'>credentials</a> <a href='credentials?creds=include'>credentials</a>

View File

@@ -0,0 +1,7 @@
<script>
export default {
preload() {
this.redirect(301, '/');
}
};
</script>

View File

@@ -59,9 +59,19 @@ describe('sapper', function() {
basepath: '/custom-basepath' basepath: '/custom-basepath'
}); });
describe('export', () => { testExport({});
testExport({ basepath: '/custom-basepath' });
});
function testExport({ basepath = '' }) {
describe(basepath ? `export --basepath ${basepath}` : 'export', () => {
before(() => { before(() => {
return exec(`node ${cli} export`); if (basepath) {
process.env.BASEPATH = basepath;
}
return exec(`node ${cli} export ${basepath ? `--basepath ${basepath}` : ''}`);
}); });
it('export all pages', () => { it('export all pages', () => {
@@ -96,7 +106,10 @@ describe('sapper', function() {
'service-worker.js', 'service-worker.js',
'svelte-logo-192.png', 'svelte-logo-192.png',
'svelte-logo-512.png', 'svelte-logo-512.png',
]; ].map(file => {
return basepath ? `${basepath.replace(/^[\/\\]/, '')}/${file}` : file;
});
// Client scripts that should show up in the extraction directory. // Client scripts that should show up in the extraction directory.
const expectedClientRegexes = [ const expectedClientRegexes = [
/client\/[^/]+\/main(\.\d+)?\.js/, /client\/[^/]+\/main(\.\d+)?\.js/,
@@ -126,7 +139,7 @@ describe('sapper', function() {
}); });
}); });
}); });
}); }
function run({ mode, basepath = '' }) { function run({ mode, basepath = '' }) {
describe(`mode=${mode}`, function () { describe(`mode=${mode}`, function () {
@@ -423,6 +436,33 @@ function run({ mode, basepath = '' }) {
}); });
}); });
it('redirects on server (root)', () => {
return nightmare.goto(`${base}/redirect-root`)
.path()
.then(path => {
assert.equal(path, `${basepath}/`);
})
.then(() => nightmare.page.title())
.then(title => {
assert.equal(title, 'Great success!');
});
});
it('redirects in client (root)', () => {
return nightmare.goto(base)
.wait('[href="redirect-root"]')
.click('[href="redirect-root"]')
.wait(200)
.path()
.then(path => {
assert.equal(path, `${basepath}/`);
})
.then(() => nightmare.page.title())
.then(title => {
assert.equal(title, 'Great success!');
});
});
it('handles 4xx error on server', () => { it('handles 4xx error on server', () => {
return nightmare.goto(`${base}/blog/nope`) return nightmare.goto(`${base}/blog/nope`)
.path() .path()
@@ -568,11 +608,11 @@ function run({ mode, basepath = '' }) {
return nightmare.goto(`${base}/store`) return nightmare.goto(`${base}/store`)
.page.title() .page.title()
.then(title => { .then(title => {
assert.equal(title, 'Stored title'); assert.equal(title, 'hello world');
return nightmare.init().page.title(); return nightmare.init().page.title();
}) })
.then(title => { .then(title => {
assert.equal(title, 'Stored title'); assert.equal(title, 'hello world');
}); });
}); });