mirror of
https://github.com/kevin-DL/sapper.git
synced 2026-01-14 12:04:39 +00:00
update folder structure (#432)
This commit is contained in:
14
test/app/src/client.js
Normal file
14
test/app/src/client.js
Normal file
@@ -0,0 +1,14 @@
|
||||
import { init, goto, prefetchRoutes } from '../../../runtime.js';
|
||||
import { Store } from 'svelte/store.js';
|
||||
import { manifest } from './manifest/client.js';
|
||||
|
||||
window.init = () => {
|
||||
return init({
|
||||
target: document.querySelector('#sapper'),
|
||||
manifest,
|
||||
store: data => new Store(data)
|
||||
});
|
||||
};
|
||||
|
||||
window.prefetchRoutes = prefetchRoutes;
|
||||
window.goto = goto;
|
||||
299
test/app/src/manifest/client.js
Normal file
299
test/app/src/manifest/client.js
Normal file
@@ -0,0 +1,299 @@
|
||||
// This file is generated by Sapper — do not edit it!
|
||||
import root from '../routes/_layout.html';
|
||||
import error from '../routes/_error.html';
|
||||
|
||||
const d = decodeURIComponent;
|
||||
|
||||
const index = {
|
||||
js: () => import(/* webpackChunkName: "index" */ '../routes/index.html'),
|
||||
css: "__SAPPER_CSS_PLACEHOLDER:index.html__"
|
||||
};
|
||||
const non$45sapper$45redirect$45to = {
|
||||
js: () => import(/* webpackChunkName: "non$45sapper$45redirect$45to" */ '../routes/non-sapper-redirect-to.html'),
|
||||
css: "__SAPPER_CSS_PLACEHOLDER:non-sapper-redirect-to.html__"
|
||||
};
|
||||
const unsafe$45replacement = {
|
||||
js: () => import(/* webpackChunkName: "unsafe$45replacement" */ '../routes/unsafe-replacement.html'),
|
||||
css: "__SAPPER_CSS_PLACEHOLDER:unsafe-replacement.html__"
|
||||
};
|
||||
const preload$45values = {
|
||||
js: () => import(/* webpackChunkName: "preload$45values" */ '../routes/preload-values/index.html'),
|
||||
css: "__SAPPER_CSS_PLACEHOLDER:preload-values/index.html__"
|
||||
};
|
||||
const preload$45values_custom$45class = {
|
||||
js: () => import(/* webpackChunkName: "preload$45values_custom$45class" */ '../routes/preload-values/custom-class.html'),
|
||||
css: "__SAPPER_CSS_PLACEHOLDER:preload-values/custom-class.html__"
|
||||
};
|
||||
const preload$45values_set = {
|
||||
js: () => import(/* webpackChunkName: "preload$45values_set" */ '../routes/preload-values/set.html'),
|
||||
css: "__SAPPER_CSS_PLACEHOLDER:preload-values/set.html__"
|
||||
};
|
||||
const missing$45index_ok = {
|
||||
js: () => import(/* webpackChunkName: "missing$45index_ok" */ '../routes/missing-index/ok.html'),
|
||||
css: "__SAPPER_CSS_PLACEHOLDER:missing-index/ok.html__"
|
||||
};
|
||||
const redirect$45from = {
|
||||
js: () => import(/* webpackChunkName: "redirect$45from" */ '../routes/redirect-from.html'),
|
||||
css: "__SAPPER_CSS_PLACEHOLDER:redirect-from.html__"
|
||||
};
|
||||
const redirect$45root = {
|
||||
js: () => import(/* webpackChunkName: "redirect$45root" */ '../routes/redirect-root.html'),
|
||||
css: "__SAPPER_CSS_PLACEHOLDER:redirect-root.html__"
|
||||
};
|
||||
const preload$45root = {
|
||||
js: () => import(/* webpackChunkName: "preload$45root" */ '../routes/preload-root/index.html'),
|
||||
css: "__SAPPER_CSS_PLACEHOLDER:preload-root/index.html__"
|
||||
};
|
||||
const slow$45preload = {
|
||||
js: () => import(/* webpackChunkName: "slow$45preload" */ '../routes/slow-preload.html'),
|
||||
css: "__SAPPER_CSS_PLACEHOLDER:slow-preload.html__"
|
||||
};
|
||||
const credentials = {
|
||||
js: () => import(/* webpackChunkName: "credentials" */ '../routes/credentials/index.html'),
|
||||
css: "__SAPPER_CSS_PLACEHOLDER:credentials/index.html__"
|
||||
};
|
||||
const delete$45test = {
|
||||
js: () => import(/* webpackChunkName: "delete$45test" */ '../routes/delete-test.html'),
|
||||
css: "__SAPPER_CSS_PLACEHOLDER:delete-test.html__"
|
||||
};
|
||||
const redirect$45to = {
|
||||
js: () => import(/* webpackChunkName: "redirect$45to" */ '../routes/redirect-to.html'),
|
||||
css: "__SAPPER_CSS_PLACEHOLDER:redirect-to.html__"
|
||||
};
|
||||
const about = {
|
||||
js: () => import(/* webpackChunkName: "about" */ '../routes/about.html'),
|
||||
css: "__SAPPER_CSS_PLACEHOLDER:about.html__"
|
||||
};
|
||||
const const_ = {
|
||||
js: () => import(/* webpackChunkName: "const_" */ '../routes/const.html'),
|
||||
css: "__SAPPER_CSS_PLACEHOLDER:const.html__"
|
||||
};
|
||||
const f$252nke = {
|
||||
js: () => import(/* webpackChunkName: "f$252nke" */ '../routes/fünke.html'),
|
||||
css: "__SAPPER_CSS_PLACEHOLDER:fünke.html__"
|
||||
};
|
||||
const store = {
|
||||
js: () => import(/* webpackChunkName: "store" */ '../routes/store.html'),
|
||||
css: "__SAPPER_CSS_PLACEHOLDER:store.html__"
|
||||
};
|
||||
const blog = {
|
||||
js: () => import(/* webpackChunkName: "blog" */ '../routes/blog/index.html'),
|
||||
css: "__SAPPER_CSS_PLACEHOLDER:blog/index.html__"
|
||||
};
|
||||
const blog_$slug = {
|
||||
js: () => import(/* webpackChunkName: "blog_$slug" */ '../routes/blog/[slug].html'),
|
||||
css: "__SAPPER_CSS_PLACEHOLDER:blog/[slug].html__"
|
||||
};
|
||||
const echo_page_$slug = {
|
||||
js: () => import(/* webpackChunkName: "echo_page_$slug" */ '../routes/echo/page/[slug].html'),
|
||||
css: "__SAPPER_CSS_PLACEHOLDER:echo/page/[slug].html__"
|
||||
};
|
||||
const $x$93_$91y__layout = {
|
||||
js: () => import(/* webpackChunkName: "$x$93_$91y__layout" */ '../routes/[x]/[y]/_layout.html'),
|
||||
css: "__SAPPER_CSS_PLACEHOLDER:[x]/[y]/_layout.html__"
|
||||
};
|
||||
const $x$93_$91y$93_$91z = {
|
||||
js: () => import(/* webpackChunkName: "$x$93_$91y$93_$91z" */ '../routes/[x]/[y]/[z].html'),
|
||||
css: "__SAPPER_CSS_PLACEHOLDER:[x]/[y]/[z].html__"
|
||||
};
|
||||
|
||||
export const manifest = {
|
||||
ignore: [/^\/throw-an-error$/, /^\/credentials\/test.json$/, /^\/f%C3%BCnke.json$/, /^\/blog.json$/, /^\/blog\/([^\/]+?).json$/, /^\/echo\/server-route\/([^\/]+?)$/, /^\/api\/delete\/([^\/]+?)$/],
|
||||
|
||||
pages: [
|
||||
{
|
||||
// index.html
|
||||
pattern: /^\/?$/,
|
||||
parts: [
|
||||
{ component: index }
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
// non-sapper-redirect-to.html
|
||||
pattern: /^\/non-sapper-redirect-to\/?$/,
|
||||
parts: [
|
||||
{ component: non$45sapper$45redirect$45to }
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
// unsafe-replacement.html
|
||||
pattern: /^\/unsafe-replacement\/?$/,
|
||||
parts: [
|
||||
{ component: unsafe$45replacement }
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
// preload-values/index.html
|
||||
pattern: /^\/preload-values\/?$/,
|
||||
parts: [
|
||||
null,
|
||||
{ component: preload$45values }
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
// preload-values/custom-class.html
|
||||
pattern: /^\/preload-values\/custom-class\/?$/,
|
||||
parts: [
|
||||
null,
|
||||
{ component: preload$45values_custom$45class }
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
// preload-values/set.html
|
||||
pattern: /^\/preload-values\/set\/?$/,
|
||||
parts: [
|
||||
null,
|
||||
{ component: preload$45values_set }
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
// missing-index/ok.html
|
||||
pattern: /^\/missing-index\/ok\/?$/,
|
||||
parts: [
|
||||
null,
|
||||
{ component: missing$45index_ok }
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
// redirect-from.html
|
||||
pattern: /^\/redirect-from\/?$/,
|
||||
parts: [
|
||||
{ component: redirect$45from }
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
// redirect-root.html
|
||||
pattern: /^\/redirect-root\/?$/,
|
||||
parts: [
|
||||
{ component: redirect$45root }
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
// preload-root/index.html
|
||||
pattern: /^\/preload-root\/?$/,
|
||||
parts: [
|
||||
null,
|
||||
{ component: preload$45root }
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
// slow-preload.html
|
||||
pattern: /^\/slow-preload\/?$/,
|
||||
parts: [
|
||||
{ component: slow$45preload }
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
// credentials/index.html
|
||||
pattern: /^\/credentials\/?$/,
|
||||
parts: [
|
||||
null,
|
||||
{ component: credentials }
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
// delete-test.html
|
||||
pattern: /^\/delete-test\/?$/,
|
||||
parts: [
|
||||
{ component: delete$45test }
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
// redirect-to.html
|
||||
pattern: /^\/redirect-to\/?$/,
|
||||
parts: [
|
||||
{ component: redirect$45to }
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
// about.html
|
||||
pattern: /^\/about\/?$/,
|
||||
parts: [
|
||||
{ component: about }
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
// const.html
|
||||
pattern: /^\/const\/?$/,
|
||||
parts: [
|
||||
{ component: const_ }
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
// fünke.html
|
||||
pattern: /^\/f%C3%BCnke\/?$/,
|
||||
parts: [
|
||||
{ component: f$252nke }
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
// store.html
|
||||
pattern: /^\/store\/?$/,
|
||||
parts: [
|
||||
{ component: store }
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
// blog/index.html
|
||||
pattern: /^\/blog\/?$/,
|
||||
parts: [
|
||||
null,
|
||||
{ component: blog }
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
// blog/[slug].html
|
||||
pattern: /^\/blog\/([^\/]+?)\/?$/,
|
||||
parts: [
|
||||
null,
|
||||
{ component: blog_$slug, params: match => ({ slug: d(match[1]) }) }
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
// echo/page/[slug].html
|
||||
pattern: /^\/echo\/page\/([^\/]+?)\/?$/,
|
||||
parts: [
|
||||
null,
|
||||
null,
|
||||
{ component: echo_page_$slug, params: match => ({ slug: d(match[1]) }) }
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
// [x]/[y]/[z].html
|
||||
pattern: /^\/([^\/]+?)\/([^\/]+?)\/([^\/]+?)\/?$/,
|
||||
parts: [
|
||||
null,
|
||||
{ component: $x$93_$91y__layout, params: match => ({ x: d(match[1]), y: d(match[2]) }) },
|
||||
{ component: $x$93_$91y$93_$91z, params: match => ({ x: d(match[1]), y: d(match[2]), z: d(match[3]) }) }
|
||||
]
|
||||
}
|
||||
],
|
||||
|
||||
root,
|
||||
|
||||
error
|
||||
};
|
||||
|
||||
// this is included for legacy reasons
|
||||
export const routes = {};
|
||||
1
test/app/src/manifest/default-layout.html
Normal file
1
test/app/src/manifest/default-layout.html
Normal file
@@ -0,0 +1 @@
|
||||
<svelte:component this={child.component} {...child.props}/>
|
||||
285
test/app/src/manifest/server.js
Normal file
285
test/app/src/manifest/server.js
Normal file
@@ -0,0 +1,285 @@
|
||||
// This file is generated by Sapper — do not edit it!
|
||||
import * as route_throw$45an$45error from '../routes/throw-an-error.js';
|
||||
import * as route_credentials_test_json from '../routes/credentials/test.json.js';
|
||||
import * as route_f$252nke_json from '../routes/fünke.json.js';
|
||||
import * as route_blog_json from '../routes/blog/index.json.js';
|
||||
import * as route_blog_$slug_json from '../routes/blog/[slug].json.js';
|
||||
import * as route_echo_server$45route_$slug from '../routes/echo/server-route/[slug].js';
|
||||
import * as route_api_delete_$id from '../routes/api/delete/[id].js';
|
||||
import index from '../routes/index.html';
|
||||
import non$45sapper$45redirect$45to from '../routes/non-sapper-redirect-to.html';
|
||||
import unsafe$45replacement from '../routes/unsafe-replacement.html';
|
||||
import preload$45values from '../routes/preload-values/index.html';
|
||||
import preload$45values_custom$45class from '../routes/preload-values/custom-class.html';
|
||||
import preload$45values_set from '../routes/preload-values/set.html';
|
||||
import missing$45index_ok from '../routes/missing-index/ok.html';
|
||||
import redirect$45from from '../routes/redirect-from.html';
|
||||
import redirect$45root from '../routes/redirect-root.html';
|
||||
import preload$45root from '../routes/preload-root/index.html';
|
||||
import slow$45preload from '../routes/slow-preload.html';
|
||||
import credentials from '../routes/credentials/index.html';
|
||||
import delete$45test from '../routes/delete-test.html';
|
||||
import redirect$45to from '../routes/redirect-to.html';
|
||||
import about from '../routes/about.html';
|
||||
import const_ from '../routes/const.html';
|
||||
import f$252nke from '../routes/fünke.html';
|
||||
import store from '../routes/store.html';
|
||||
import blog from '../routes/blog/index.html';
|
||||
import blog_$slug from '../routes/blog/[slug].html';
|
||||
import echo_page_$slug from '../routes/echo/page/[slug].html';
|
||||
import $x$93_$91y__layout from '../routes/[x]/[y]/_layout.html';
|
||||
import $x$93_$91y$93_$91z from '../routes/[x]/[y]/[z].html';
|
||||
import root from '../routes/_layout.html';
|
||||
import error from '../routes/_error.html';
|
||||
|
||||
const d = decodeURIComponent;
|
||||
|
||||
export const manifest = {
|
||||
server_routes: [
|
||||
{
|
||||
// throw-an-error.js
|
||||
pattern: /^\/throw-an-error$/,
|
||||
handlers: route_throw$45an$45error,
|
||||
params: () => ({})
|
||||
},
|
||||
|
||||
{
|
||||
// credentials/test.json.js
|
||||
pattern: /^\/credentials\/test.json$/,
|
||||
handlers: route_credentials_test_json,
|
||||
params: () => ({})
|
||||
},
|
||||
|
||||
{
|
||||
// fünke.json.js
|
||||
pattern: /^\/f%C3%BCnke.json$/,
|
||||
handlers: route_f$252nke_json,
|
||||
params: () => ({})
|
||||
},
|
||||
|
||||
{
|
||||
// blog/index.json.js
|
||||
pattern: /^\/blog.json$/,
|
||||
handlers: route_blog_json,
|
||||
params: () => ({})
|
||||
},
|
||||
|
||||
{
|
||||
// blog/[slug].json.js
|
||||
pattern: /^\/blog\/([^\/]+?).json$/,
|
||||
handlers: route_blog_$slug_json,
|
||||
params: match => ({ slug: d(match[1]) })
|
||||
},
|
||||
|
||||
{
|
||||
// echo/server-route/[slug].js
|
||||
pattern: /^\/echo\/server-route\/([^\/]+?)$/,
|
||||
handlers: route_echo_server$45route_$slug,
|
||||
params: match => ({ slug: d(match[1]) })
|
||||
},
|
||||
|
||||
{
|
||||
// api/delete/[id].js
|
||||
pattern: /^\/api\/delete\/([^\/]+?)$/,
|
||||
handlers: route_api_delete_$id,
|
||||
params: match => ({ id: d(match[1]) })
|
||||
}
|
||||
],
|
||||
|
||||
pages: [
|
||||
{
|
||||
// index.html
|
||||
pattern: /^\/?$/,
|
||||
parts: [
|
||||
{ name: "index", file: "index.html", component: index }
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
// non-sapper-redirect-to.html
|
||||
pattern: /^\/non-sapper-redirect-to\/?$/,
|
||||
parts: [
|
||||
{ name: "non$45sapper$45redirect$45to", file: "non-sapper-redirect-to.html", component: non$45sapper$45redirect$45to }
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
// unsafe-replacement.html
|
||||
pattern: /^\/unsafe-replacement\/?$/,
|
||||
parts: [
|
||||
{ name: "unsafe$45replacement", file: "unsafe-replacement.html", component: unsafe$45replacement }
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
// preload-values/index.html
|
||||
pattern: /^\/preload-values\/?$/,
|
||||
parts: [
|
||||
null,
|
||||
{ name: "preload$45values", file: "preload-values/index.html", component: preload$45values }
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
// preload-values/custom-class.html
|
||||
pattern: /^\/preload-values\/custom-class\/?$/,
|
||||
parts: [
|
||||
null,
|
||||
{ name: "preload$45values_custom$45class", file: "preload-values/custom-class.html", component: preload$45values_custom$45class }
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
// preload-values/set.html
|
||||
pattern: /^\/preload-values\/set\/?$/,
|
||||
parts: [
|
||||
null,
|
||||
{ name: "preload$45values_set", file: "preload-values/set.html", component: preload$45values_set }
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
// missing-index/ok.html
|
||||
pattern: /^\/missing-index\/ok\/?$/,
|
||||
parts: [
|
||||
null,
|
||||
{ name: "missing$45index_ok", file: "missing-index/ok.html", component: missing$45index_ok }
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
// redirect-from.html
|
||||
pattern: /^\/redirect-from\/?$/,
|
||||
parts: [
|
||||
{ name: "redirect$45from", file: "redirect-from.html", component: redirect$45from }
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
// redirect-root.html
|
||||
pattern: /^\/redirect-root\/?$/,
|
||||
parts: [
|
||||
{ name: "redirect$45root", file: "redirect-root.html", component: redirect$45root }
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
// preload-root/index.html
|
||||
pattern: /^\/preload-root\/?$/,
|
||||
parts: [
|
||||
null,
|
||||
{ name: "preload$45root", file: "preload-root/index.html", component: preload$45root }
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
// slow-preload.html
|
||||
pattern: /^\/slow-preload\/?$/,
|
||||
parts: [
|
||||
{ name: "slow$45preload", file: "slow-preload.html", component: slow$45preload }
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
// credentials/index.html
|
||||
pattern: /^\/credentials\/?$/,
|
||||
parts: [
|
||||
null,
|
||||
{ name: "credentials", file: "credentials/index.html", component: credentials }
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
// delete-test.html
|
||||
pattern: /^\/delete-test\/?$/,
|
||||
parts: [
|
||||
{ name: "delete$45test", file: "delete-test.html", component: delete$45test }
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
// redirect-to.html
|
||||
pattern: /^\/redirect-to\/?$/,
|
||||
parts: [
|
||||
{ name: "redirect$45to", file: "redirect-to.html", component: redirect$45to }
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
// about.html
|
||||
pattern: /^\/about\/?$/,
|
||||
parts: [
|
||||
{ name: "about", file: "about.html", component: about }
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
// const.html
|
||||
pattern: /^\/const\/?$/,
|
||||
parts: [
|
||||
{ name: "const_", file: "const.html", component: const_ }
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
// fünke.html
|
||||
pattern: /^\/f%C3%BCnke\/?$/,
|
||||
parts: [
|
||||
{ name: "f$252nke", file: "fünke.html", component: f$252nke }
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
// store.html
|
||||
pattern: /^\/store\/?$/,
|
||||
parts: [
|
||||
{ name: "store", file: "store.html", component: store }
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
// blog/index.html
|
||||
pattern: /^\/blog\/?$/,
|
||||
parts: [
|
||||
null,
|
||||
{ name: "blog", file: "blog/index.html", component: blog }
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
// blog/[slug].html
|
||||
pattern: /^\/blog\/([^\/]+?)\/?$/,
|
||||
parts: [
|
||||
null,
|
||||
{ name: "blog_$slug", file: "blog/[slug].html", component: blog_$slug, params: match => ({ slug: d(match[1]) }) }
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
// echo/page/[slug].html
|
||||
pattern: /^\/echo\/page\/([^\/]+?)\/?$/,
|
||||
parts: [
|
||||
null,
|
||||
null,
|
||||
{ name: "echo_page_$slug", file: "echo/page/[slug].html", component: echo_page_$slug, params: match => ({ slug: d(match[1]) }) }
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
// [x]/[y]/[z].html
|
||||
pattern: /^\/([^\/]+?)\/([^\/]+?)\/([^\/]+?)\/?$/,
|
||||
parts: [
|
||||
null,
|
||||
{ name: "$x$93_$91y__layout", file: "[x]/[y]/_layout.html", component: $x$93_$91y__layout, params: match => ({ x: d(match[1]), y: d(match[2]) }) },
|
||||
{ name: "$x$93_$91y$93_$91z", file: "[x]/[y]/[z].html", component: $x$93_$91y$93_$91z, params: match => ({ x: d(match[1]), y: d(match[2]), z: d(match[3]) }) }
|
||||
]
|
||||
}
|
||||
],
|
||||
|
||||
root,
|
||||
|
||||
error
|
||||
};
|
||||
|
||||
// this is included for legacy reasons
|
||||
export const routes = {};
|
||||
64
test/app/src/manifest/service-worker.js
Normal file
64
test/app/src/manifest/service-worker.js
Normal file
@@ -0,0 +1,64 @@
|
||||
// This file is generated by Sapper — do not edit it!
|
||||
export const timestamp = 1537372892007;
|
||||
|
||||
export const files = [
|
||||
"favicon.png",
|
||||
"global.css",
|
||||
"great-success.png",
|
||||
"manifest.json",
|
||||
"svelte-logo-192.png",
|
||||
"svelte-logo-512.png"
|
||||
];
|
||||
export { files as assets }; // legacy
|
||||
|
||||
export const shell = [
|
||||
"client/1b495d0233ee9a023603/credentials.12.js",
|
||||
"client/1b495d0233ee9a023603/main.js",
|
||||
"client/1b495d0233ee9a023603/non$45sapper$45redirect$45to.2.js",
|
||||
"client/1b495d0233ee9a023603/unsafe$45replacement.3.js",
|
||||
"client/1b495d0233ee9a023603/preload$45values.4.js",
|
||||
"client/1b495d0233ee9a023603/preload$45values_custom$45class.5.js",
|
||||
"client/1b495d0233ee9a023603/preload$45values_set.6.js",
|
||||
"client/1b495d0233ee9a023603/missing$45index_ok.7.js",
|
||||
"client/1b495d0233ee9a023603/redirect$45from.8.js",
|
||||
"client/1b495d0233ee9a023603/redirect$45root.9.js",
|
||||
"client/1b495d0233ee9a023603/preload$45root.10.js",
|
||||
"client/1b495d0233ee9a023603/slow$45preload.11.js",
|
||||
"client/1b495d0233ee9a023603/index.1.js",
|
||||
"client/1b495d0233ee9a023603/delete$45test.13.js",
|
||||
"client/1b495d0233ee9a023603/redirect$45to.14.js",
|
||||
"client/1b495d0233ee9a023603/about.15.js",
|
||||
"client/1b495d0233ee9a023603/const_.16.js",
|
||||
"client/1b495d0233ee9a023603/f$252nke.17.js",
|
||||
"client/1b495d0233ee9a023603/store.18.js",
|
||||
"client/1b495d0233ee9a023603/blog.19.js",
|
||||
"client/1b495d0233ee9a023603/blog_$slug.20.js",
|
||||
"client/1b495d0233ee9a023603/echo_page_$slug.21.js",
|
||||
"client/1b495d0233ee9a023603/$x$93_$91y__layout.22.js",
|
||||
"client/1b495d0233ee9a023603/$x$93_$91y$93_$91z.23.js"
|
||||
];
|
||||
|
||||
export const routes = [
|
||||
{ pattern: /^\/?$/ },
|
||||
{ pattern: /^\/non-sapper-redirect-to\/?$/ },
|
||||
{ pattern: /^\/unsafe-replacement\/?$/ },
|
||||
{ pattern: /^\/preload-values\/?$/ },
|
||||
{ pattern: /^\/preload-values\/custom-class\/?$/ },
|
||||
{ pattern: /^\/preload-values\/set\/?$/ },
|
||||
{ pattern: /^\/missing-index\/ok\/?$/ },
|
||||
{ pattern: /^\/redirect-from\/?$/ },
|
||||
{ pattern: /^\/redirect-root\/?$/ },
|
||||
{ pattern: /^\/preload-root\/?$/ },
|
||||
{ pattern: /^\/slow-preload\/?$/ },
|
||||
{ pattern: /^\/credentials\/?$/ },
|
||||
{ pattern: /^\/delete-test\/?$/ },
|
||||
{ pattern: /^\/redirect-to\/?$/ },
|
||||
{ pattern: /^\/about\/?$/ },
|
||||
{ pattern: /^\/const\/?$/ },
|
||||
{ pattern: /^\/f%C3%BCnke\/?$/ },
|
||||
{ pattern: /^\/store\/?$/ },
|
||||
{ pattern: /^\/blog\/?$/ },
|
||||
{ pattern: /^\/blog\/([^\/]+?)\/?$/ },
|
||||
{ pattern: /^\/echo\/page\/([^\/]+?)\/?$/ },
|
||||
{ pattern: /^\/([^\/]+?)\/([^\/]+?)\/([^\/]+?)\/?$/ }
|
||||
];
|
||||
20
test/app/src/routes/[x]/[y]/[z].html
Normal file
20
test/app/src/routes/[x]/[y]/[z].html
Normal file
@@ -0,0 +1,20 @@
|
||||
<span>z: {segment} {count}</span>
|
||||
<a href="foo/bar/qux"></a>
|
||||
|
||||
<script>
|
||||
import counts from '../_counts.js';
|
||||
|
||||
export default {
|
||||
preload() {
|
||||
return {
|
||||
count: counts.z += 1
|
||||
};
|
||||
},
|
||||
|
||||
oncreate() {
|
||||
this.set({
|
||||
segment: this.get().params.z
|
||||
});
|
||||
}
|
||||
};
|
||||
</script>
|
||||
22
test/app/src/routes/[x]/[y]/_layout.html
Normal file
22
test/app/src/routes/[x]/[y]/_layout.html
Normal file
@@ -0,0 +1,22 @@
|
||||
<span>y: {segment} {count}</span>
|
||||
<svelte:component this={child.component} {...child.props}/>
|
||||
|
||||
<span>child segment: {child.segment}</span>
|
||||
|
||||
<script>
|
||||
import counts from '../_counts.js';
|
||||
|
||||
export default {
|
||||
preload() {
|
||||
return {
|
||||
count: counts.y += 1
|
||||
};
|
||||
},
|
||||
|
||||
oncreate() {
|
||||
this.set({
|
||||
segment: this.get().params.y
|
||||
});
|
||||
}
|
||||
};
|
||||
</script>
|
||||
5
test/app/src/routes/[x]/_counts.js
Normal file
5
test/app/src/routes/[x]/_counts.js
Normal file
@@ -0,0 +1,5 @@
|
||||
export default {
|
||||
x: process.browser ? 1 : 0,
|
||||
y: process.browser ? 1 : 0,
|
||||
z: process.browser ? 1 : 0
|
||||
};
|
||||
6
test/app/src/routes/_error.html
Normal file
6
test/app/src/routes/_error.html
Normal file
@@ -0,0 +1,6 @@
|
||||
<svelte:head>
|
||||
<title>{status}</title>
|
||||
</svelte:head>
|
||||
|
||||
<h1>{status}</h1>
|
||||
<p>{error.message}</p>
|
||||
15
test/app/src/routes/_layout.html
Normal file
15
test/app/src/routes/_layout.html
Normal file
@@ -0,0 +1,15 @@
|
||||
{#if preloading}
|
||||
<progress class='preloading-progress' value=0.5/>
|
||||
{/if}
|
||||
|
||||
<svelte:component this={child.component} {rootPreloadFunctionRan} {...child.props}/>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
preload() {
|
||||
return {
|
||||
rootPreloadFunctionRan: true
|
||||
};
|
||||
}
|
||||
};
|
||||
</script>
|
||||
27
test/app/src/routes/about.html
Normal file
27
test/app/src/routes/about.html
Normal file
@@ -0,0 +1,27 @@
|
||||
<svelte:head>
|
||||
<title>About</title>
|
||||
</svelte:head>
|
||||
|
||||
<h1>About this site</h1>
|
||||
|
||||
<p>This is the 'about' page. There's not much here.</p>
|
||||
|
||||
<button class='prefetch' on:click='prefetch("blog/why-the-name")'>Why the name?</button>
|
||||
|
||||
<script>
|
||||
import { goto, prefetch } from '../../../../runtime.js';
|
||||
|
||||
export default {
|
||||
oncreate() {
|
||||
window.goto = goto;
|
||||
},
|
||||
|
||||
ondestroy() {
|
||||
window.goto = null;
|
||||
},
|
||||
|
||||
methods: {
|
||||
prefetch
|
||||
}
|
||||
};
|
||||
</script>
|
||||
9
test/app/src/routes/api/delete/[id].js
Normal file
9
test/app/src/routes/api/delete/[id].js
Normal file
@@ -0,0 +1,9 @@
|
||||
export function del(req, res) {
|
||||
res.writeHead(200, {
|
||||
'Content-Type': 'application/json'
|
||||
});
|
||||
|
||||
res.end(JSON.stringify({
|
||||
id: req.params.id
|
||||
}));
|
||||
}
|
||||
36
test/app/src/routes/blog/[slug].html
Normal file
36
test/app/src/routes/blog/[slug].html
Normal file
@@ -0,0 +1,36 @@
|
||||
<svelte:head>
|
||||
<title>{post.title}</title>
|
||||
</svelte:head>
|
||||
|
||||
<h1>{post.title}</h1>
|
||||
|
||||
<div class='content'>
|
||||
{@html post.html}
|
||||
</div>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
preload({ params, query }) {
|
||||
// the `slug` parameter is available because this file
|
||||
// is called [slug].html
|
||||
const { slug } = params;
|
||||
|
||||
if (slug === 'throw-an-error') {
|
||||
return this.error(500, 'something went wrong');
|
||||
}
|
||||
|
||||
return fetch(`blog/${slug}.json`).then(r => {
|
||||
if (r.status === 200) {
|
||||
return r.json().then(post => ({ post }));
|
||||
this.error(r.status, '')
|
||||
}
|
||||
|
||||
if (r.status === 404) {
|
||||
this.error(404, 'Not found');
|
||||
} else {
|
||||
throw new Error('Something went wrong');
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
</script>
|
||||
23
test/app/src/routes/blog/[slug].json.js
Normal file
23
test/app/src/routes/blog/[slug].json.js
Normal file
@@ -0,0 +1,23 @@
|
||||
import posts from './_posts.js';
|
||||
|
||||
const lookup = {};
|
||||
posts.forEach(post => {
|
||||
lookup[post.slug] = JSON.stringify(post);
|
||||
});
|
||||
|
||||
export function get(req, res, next) {
|
||||
// the `slug` parameter is available because this file
|
||||
// is called [slug].js
|
||||
const { slug } = req.params;
|
||||
|
||||
if (slug in lookup) {
|
||||
res.writeHead(200, {
|
||||
'Content-Type': 'application/json',
|
||||
'Cache-Control': `no-cache`
|
||||
});
|
||||
|
||||
res.end(lookup[slug]);
|
||||
} else {
|
||||
next();
|
||||
}
|
||||
}
|
||||
124
test/app/src/routes/blog/_posts.js
Normal file
124
test/app/src/routes/blog/_posts.js
Normal file
@@ -0,0 +1,124 @@
|
||||
// Ordinarily, you'd generate this data from markdown files in your
|
||||
// repo, or fetch them from a database of some kind. But in order to
|
||||
// avoid unnecessary dependencies in the starter template, and in the
|
||||
// service of obviousness, we're just going to leave it here.
|
||||
|
||||
// This file is called `_posts.js` rather than `posts.js`, because
|
||||
// we don't want to create an `/api/blog/posts` route — the leading
|
||||
// underscore tells Sapper not to do that.
|
||||
|
||||
const posts = [
|
||||
{
|
||||
title: 'What is Sapper?',
|
||||
slug: 'what-is-sapper',
|
||||
html: `
|
||||
<p>First, you have to know what <a href='https://svelte.technology'>Svelte</a> is. Svelte is a UI framework with a bold new idea: rather than providing a library that you write code with (like React or Vue, for example), it's a compiler that turns your components into highly optimized vanilla JavaScript. If you haven't already read the <a href='https://svelte.technology/blog/frameworks-without-the-framework'>introductory blog post</a>, you should!</p>
|
||||
|
||||
<p>Sapper is a Next.js-style framework (<a href='blog/how-is-sapper-different-from-next'>more on that here</a>) built around Svelte. It makes it embarrassingly easy to create extremely high performance web apps. Out of the box, you get:</p>
|
||||
|
||||
<ul>
|
||||
<li>Code-splitting, dynamic imports and hot module replacement, powered by webpack</li>
|
||||
<li>Server-side rendering (SSR) with client-side hydration</li>
|
||||
<li>Service worker for offline support, and all the PWA bells and whistles</li>
|
||||
<li>The nicest development experience you've ever had, or your money back</li>
|
||||
</ul>
|
||||
|
||||
<p>It's implemented as Express middleware. Everything is set up and waiting for you to get started, but you keep complete control over the server, service worker, webpack config and everything else, so it's as flexible as you need it to be.</p>
|
||||
`
|
||||
},
|
||||
|
||||
{
|
||||
title: 'How to use Sapper',
|
||||
slug: 'how-to-use-sapper',
|
||||
html: `
|
||||
<h2>Step one</h2>
|
||||
<p>Create a new project, using <a href='https://github.com/Rich-Harris/degit'>degit</a>:</p>
|
||||
|
||||
<pre><code>npx degit sveltejs/sapper-template my-app
|
||||
cd my-app
|
||||
npm install # or yarn!
|
||||
npm run dev
|
||||
</code></pre>
|
||||
|
||||
<h2>Step two</h2>
|
||||
<p>Go to <a href='http://localhost:3000'>localhost:3000</a>. Open <code>my-app</code> in your editor. Edit the files in the <code>routes</code> directory or add new ones.</p>
|
||||
|
||||
<h2>Step three</h2>
|
||||
<p>...</p>
|
||||
|
||||
<h2>Step four</h2>
|
||||
<p>Resist overdone joke formats.</p>
|
||||
`
|
||||
},
|
||||
|
||||
{
|
||||
title: 'Why the name?',
|
||||
slug: 'why-the-name',
|
||||
html: `
|
||||
<p>In war, the soldiers who build bridges, repair roads, clear minefields and conduct demolitions — all under combat conditions — are known as <em>sappers</em>.</p>
|
||||
|
||||
<p>For web developers, the stakes are generally lower than those for combat engineers. But we face our own hostile environment: underpowered devices, poor network connections, and the complexity inherent in front-end engineering. Sapper, which is short for <strong>S</strong>velte <strong>app</strong> mak<strong>er</strong>, is your courageous and dutiful ally.</p>
|
||||
`
|
||||
},
|
||||
|
||||
{
|
||||
title: 'How is Sapper different from Next.js?',
|
||||
slug: 'how-is-sapper-different-from-next',
|
||||
html: `
|
||||
<p><a href='https://github.com/zeit/next.js/'>Next.js</a> is a React framework from <a href='https://zeit.co'>Zeit</a>, and is the inspiration for Sapper. There are a few notable differences, however:</p>
|
||||
|
||||
<ul>
|
||||
<li>It's powered by <a href='https://svelte.technology'>Svelte</a> instead of React, so it's faster and your apps are smaller</li>
|
||||
<li>Instead of route masking, we encode route parameters in filenames. For example, the page you're looking at right now is <code>routes/blog/[slug].html</code></li>
|
||||
<li>As well as pages (Svelte components, which render on server or client), you can create <em>server routes</em> in your <code>routes</code> directory. These are just <code>.js</code> files that export functions corresponding to HTTP methods, and receive Express <code>request</code> and <code>response</code> objects as arguments. This makes it very easy to, for example, add a JSON API such as the one <a href='blog/how-is-sapper-different-from-next.json'>powering this very page</a></li>
|
||||
<li>Links are just <code><a></code> elements, rather than framework-specific <code><Link></code> components. That means, for example, that <a href='blog/how-can-i-get-involved'>this link right here</a>, despite being inside a blob of HTML, works with the router as you'd expect.</li>
|
||||
</ul>
|
||||
`
|
||||
},
|
||||
|
||||
{
|
||||
title: 'How can I get involved?',
|
||||
slug: 'how-can-i-get-involved',
|
||||
html: `
|
||||
<p>We're so glad you asked! Come on over to the <a href='https://github.com/sveltejs/svelte'>Svelte</a> and <a href='https://github.com/sveltejs/sapper'>Sapper</a> repos, and join us in the <a href='https://gitter.im/sveltejs/svelte'>Gitter chatroom</a>. Everyone is welcome, especially you!</p>
|
||||
`
|
||||
},
|
||||
|
||||
{
|
||||
title: 'A very long post with deep links',
|
||||
slug: 'a-very-long-post',
|
||||
html: `
|
||||
<h2 id='one'>One</h2>
|
||||
<p>I'll have a vodka rocks. (Mom, it's breakfast time.) And a piece of toast. Let me out that Queen. Fried cheese… with club sauce.</p>
|
||||
<p>Her lawyers are claiming the seal is worth $250,000. And that's not even including Buster's Swatch. This was a big get for God. What, so the guy we are meeting with can't even grow his own hair? COME ON! She's always got to wedge herself in the middle of us so that she can control everything. Yeah. Mom's awesome. It's, like, Hey, you want to go down to the whirlpool? Yeah, I don't have a husband. I call it Swing City. The CIA should've just Googled for his hideout, evidently. There are dozens of us! DOZENS! Yeah, like I'm going to take a whiz through this $5,000 suit. COME ON.</p>
|
||||
|
||||
<h2 id='two'>Two</h2>
|
||||
<p>Tobias Fünke costume. Heart attack never stopped old big bear.</p>
|
||||
<p>Nellie is blowing them all AWAY. I will be a bigger and hairier mole than the one on your inner left thigh! I'll sacrifice anything for my children.</p>
|
||||
<p>Up yours, granny! You couldn't handle it! Hey, Dad. Look at you. You're a year older…and a year closer to death. Buster: Oh yeah, I guess that's kind of funny. Bob Loblaw Law Blog. The guy runs a prison, he can have any piece of ass he wants.</p>
|
||||
|
||||
<h2 id='three'>Three</h2>
|
||||
<p>I prematurely shot my wad on what was supposed to be a dry run, so now I'm afraid I have something of a mess on my hands. Dead Dove DO NOT EAT. Never once touched my per diem. I'd go to Craft Service, get some raw veggies, bacon, Cup-A-Soup…baby, I got a stew goin'. You're losing blood, aren't you? Gob: Probably, my socks are wet. Sure, let the little fruit do it. HUZZAH! Although George Michael had only got to second base, he'd gone in head first, like Pete Rose. I will pack your sweet pink mouth with so much ice cream you'll be the envy of every Jerry and Jane on the block!</p>
|
||||
<p>Gosh Mom… after all these years, God's not going to take a call from you. Come on, this is a Bluth family celebration. It's no place for children.</p>
|
||||
<p>And I wouldn't just lie there, if that's what you're thinking. That's not what I WAS thinking. Who? i just dont want him to point out my cracker ass in front of ann. When a man needs to prove to a woman that he's actually… When a man loves a woman… Heyyyyyy Uncle Father Oscar. [Stabbing Gob] White power! Gob: I'm white! Let me take off my assistant's skirt and put on my Barbra-Streisand-in-The-Prince-of-Tides ass-masking therapist pantsuit. In the mid '90s, Tobias formed a folk music band with Lindsay and Maebe which he called Dr. Funke's 100 Percent Natural Good Time Family Band Solution. The group was underwritten by the Natural Food Life Company, a division of Chem-Grow, an Allen Crayne acqusition, which was part of the Squimm Group. Their motto was simple: We keep you alive.</p>
|
||||
|
||||
<h2 id='four'>Four</h2>
|
||||
<p>If you didn't have adult onset diabetes, I wouldn't mind giving you a little sugar. Everybody dance NOW. And the soup of the day is bread. Great, now I'm gonna smell to high heaven like a tuna melt!</p>
|
||||
<p>That's how Tony Wonder lost a nut. She calls it a Mayonegg. Go ahead, touch the Cornballer. There's a new daddy in town. A discipline daddy.</p>
|
||||
`
|
||||
},
|
||||
|
||||
{
|
||||
title: 'Encödïng test',
|
||||
slug: 'encödïng-test',
|
||||
html: `
|
||||
<p>It works</p>
|
||||
`
|
||||
}
|
||||
];
|
||||
|
||||
posts.forEach(post => {
|
||||
post.html = post.html.replace(/^\t{3}/gm, '');
|
||||
});
|
||||
|
||||
export default posts;
|
||||
25
test/app/src/routes/blog/index.html
Normal file
25
test/app/src/routes/blog/index.html
Normal file
@@ -0,0 +1,25 @@
|
||||
<svelte:head>
|
||||
<title>Blog</title>
|
||||
</svelte:head>
|
||||
|
||||
<h1>Recent posts</h1>
|
||||
|
||||
<ul>
|
||||
{#each posts as post}
|
||||
<!-- we're using the non-standard `rel=prefetch` attribute to
|
||||
tell Sapper to load the data for the page as soon as
|
||||
the user hovers over the link or taps it, instead of
|
||||
waiting for the 'click' event -->
|
||||
<li><a rel='prefetch' href='blog/{post.slug}'>{post.title}</a></li>
|
||||
{/each}
|
||||
</ul>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
preload({ params, query }) {
|
||||
return fetch(`blog.json`).then(r => r.json()).then(posts => {
|
||||
return { posts };
|
||||
});
|
||||
}
|
||||
};
|
||||
</script>
|
||||
17
test/app/src/routes/blog/index.json.js
Normal file
17
test/app/src/routes/blog/index.json.js
Normal file
@@ -0,0 +1,17 @@
|
||||
import posts from './_posts.js';
|
||||
|
||||
const contents = JSON.stringify(posts.map(post => {
|
||||
return {
|
||||
title: post.title,
|
||||
slug: post.slug
|
||||
};
|
||||
}));
|
||||
|
||||
export function get(req, res) {
|
||||
res.writeHead(200, {
|
||||
'Content-Type': 'application/json',
|
||||
'Cache-Control': `max-age=${30 * 60 * 1e3}` // cache for 30 minutes
|
||||
});
|
||||
|
||||
res.end(contents);
|
||||
}
|
||||
1
test/app/src/routes/const.html
Normal file
1
test/app/src/routes/const.html
Normal file
@@ -0,0 +1 @@
|
||||
<h1>reserved words are okay as routes</h1>
|
||||
11
test/app/src/routes/credentials/index.html
Normal file
11
test/app/src/routes/credentials/index.html
Normal file
@@ -0,0 +1,11 @@
|
||||
<h1>{message}</h1>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
preload({ query }) {
|
||||
return this.fetch(`credentials/test.json`, {
|
||||
credentials: query.creds
|
||||
}).then(r => r.json());
|
||||
}
|
||||
};
|
||||
</script>
|
||||
28
test/app/src/routes/credentials/test.json.js
Normal file
28
test/app/src/routes/credentials/test.json.js
Normal file
@@ -0,0 +1,28 @@
|
||||
export function get(req, res) {
|
||||
const cookies = req.headers.cookie
|
||||
? req.headers.cookie.split(/,\s+/).reduce((cookies, cookie) => {
|
||||
const [pair] = cookie.split('; ');
|
||||
const [name, value] = pair.split('=');
|
||||
cookies[name] = value;
|
||||
return cookies;
|
||||
}, {})
|
||||
: {};
|
||||
|
||||
if (cookies.test) {
|
||||
res.writeHead(200, {
|
||||
'Content-Type': 'application/json'
|
||||
});
|
||||
|
||||
res.end(JSON.stringify({
|
||||
message: cookies.test
|
||||
}));
|
||||
} else {
|
||||
res.writeHead(403, {
|
||||
'Content-Type': 'application/json'
|
||||
});
|
||||
|
||||
res.end(JSON.stringify({
|
||||
message: 'unauthorized'
|
||||
}));
|
||||
}
|
||||
}
|
||||
15
test/app/src/routes/delete-test.html
Normal file
15
test/app/src/routes/delete-test.html
Normal file
@@ -0,0 +1,15 @@
|
||||
<button class='del' on:click='del()'>delete</button>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
methods: {
|
||||
del() {
|
||||
fetch(`api/delete/42`, { method: 'DELETE' })
|
||||
.then(r => r.json())
|
||||
.then(data => {
|
||||
window.deleted = data;
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
12
test/app/src/routes/echo/page/[slug].html
Normal file
12
test/app/src/routes/echo/page/[slug].html
Normal file
@@ -0,0 +1,12 @@
|
||||
<h1>{slug} ({message})</h1>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
preload({ params, query }) {
|
||||
return {
|
||||
slug: params.slug,
|
||||
message: query.message
|
||||
};
|
||||
}
|
||||
};
|
||||
</script>
|
||||
15
test/app/src/routes/echo/server-route/[slug].js
Normal file
15
test/app/src/routes/echo/server-route/[slug].js
Normal file
@@ -0,0 +1,15 @@
|
||||
export function get(req, res) {
|
||||
res.writeHead(200, {
|
||||
'Content-Type': 'text/html'
|
||||
});
|
||||
|
||||
res.end(`
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head><meta charset="utf-8"></head>
|
||||
<body>
|
||||
<h1>${req.params.slug}</h1>
|
||||
</body>
|
||||
</html>
|
||||
`);
|
||||
}
|
||||
11
test/app/src/routes/fünke.html
Normal file
11
test/app/src/routes/fünke.html
Normal file
@@ -0,0 +1,11 @@
|
||||
<h1>{phrase}</h1>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
preload() {
|
||||
return this.fetch('fünke.json').then(r => r.json()).then(phrase => {
|
||||
return { phrase };
|
||||
});
|
||||
}
|
||||
};
|
||||
</script>
|
||||
9
test/app/src/routes/fünke.json.js
Normal file
9
test/app/src/routes/fünke.json.js
Normal file
@@ -0,0 +1,9 @@
|
||||
export function get(req, res) {
|
||||
res.writeHead(200, {
|
||||
'Content-Type': 'application/json'
|
||||
});
|
||||
|
||||
res.end(JSON.stringify(
|
||||
"I'm afraid I just blue myself"
|
||||
));
|
||||
}
|
||||
31
test/app/src/routes/index.html
Normal file
31
test/app/src/routes/index.html
Normal file
@@ -0,0 +1,31 @@
|
||||
<svelte:head>
|
||||
<title>Sapper project template</title>
|
||||
</svelte:head>
|
||||
|
||||
<h1>Great success!</h1>
|
||||
|
||||
<a href='.'>home</a>
|
||||
<a href='about'>about</a>
|
||||
<a href='slow-preload'>slow preload</a>
|
||||
<a href='non-sapper-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/throw-an-error'>error link</a>
|
||||
<a href='credentials?creds=include'>credentials</a>
|
||||
<a rel=prefetch class='{page === "blog" ? "selected" : ""}' href='blog'>blog</a>
|
||||
<a href="const">const</a>
|
||||
<a href="echo/page/encöded?message=hëllö+wörld">echo/page/encöded?message=hëllö+wörld</a>
|
||||
<a href="echo/page/empty?message">echo/page/empty?message</a>
|
||||
|
||||
<div class='hydrate-test'></div>
|
||||
|
||||
<style>
|
||||
h1 {
|
||||
text-align: center;
|
||||
font-size: 2.8em;
|
||||
text-transform: uppercase;
|
||||
font-weight: 700;
|
||||
margin: 0 0 0.5em 0;
|
||||
}
|
||||
</style>
|
||||
1
test/app/src/routes/missing-index/ok.html
Normal file
1
test/app/src/routes/missing-index/ok.html
Normal file
@@ -0,0 +1 @@
|
||||
<h1>it works</h1>
|
||||
1
test/app/src/routes/non-sapper-redirect-to.html
Normal file
1
test/app/src/routes/non-sapper-redirect-to.html
Normal file
@@ -0,0 +1 @@
|
||||
<h1>redirected</h1>
|
||||
1
test/app/src/routes/preload-root/index.html
Normal file
1
test/app/src/routes/preload-root/index.html
Normal file
@@ -0,0 +1 @@
|
||||
<h1>root preload function ran: {rootPreloadFunctionRan}</h1>
|
||||
17
test/app/src/routes/preload-values/custom-class.html
Normal file
17
test/app/src/routes/preload-values/custom-class.html
Normal file
@@ -0,0 +1,17 @@
|
||||
<h1>{foo.bar()}</h1>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
preload() {
|
||||
class Foo {
|
||||
bar() {
|
||||
return 42;
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
foo: new Foo()
|
||||
};
|
||||
}
|
||||
};
|
||||
</script>
|
||||
1
test/app/src/routes/preload-values/index.html
Normal file
1
test/app/src/routes/preload-values/index.html
Normal file
@@ -0,0 +1 @@
|
||||
<svelte:component this={child.component} {...child.props}/>
|
||||
11
test/app/src/routes/preload-values/set.html
Normal file
11
test/app/src/routes/preload-values/set.html
Normal file
@@ -0,0 +1,11 @@
|
||||
<h1>{set.has('x')}</h1>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
preload() {
|
||||
return {
|
||||
set: new Set(['x'])
|
||||
};
|
||||
}
|
||||
};
|
||||
</script>
|
||||
7
test/app/src/routes/redirect-from.html
Normal file
7
test/app/src/routes/redirect-from.html
Normal file
@@ -0,0 +1,7 @@
|
||||
<script>
|
||||
export default {
|
||||
preload() {
|
||||
this.redirect(301, 'redirect-to');
|
||||
}
|
||||
};
|
||||
</script>
|
||||
7
test/app/src/routes/redirect-root.html
Normal file
7
test/app/src/routes/redirect-root.html
Normal file
@@ -0,0 +1,7 @@
|
||||
<script>
|
||||
export default {
|
||||
preload() {
|
||||
this.redirect(301, '/');
|
||||
}
|
||||
};
|
||||
</script>
|
||||
1
test/app/src/routes/redirect-to.html
Normal file
1
test/app/src/routes/redirect-to.html
Normal file
@@ -0,0 +1 @@
|
||||
<h1>redirected</h1>
|
||||
15
test/app/src/routes/slow-preload.html
Normal file
15
test/app/src/routes/slow-preload.html
Normal file
@@ -0,0 +1,15 @@
|
||||
<h1>This page should never render</h1>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
preload() {
|
||||
return new Promise(fulfil => {
|
||||
if (typeof window !== 'undefined') {
|
||||
window.fulfil = fulfil;
|
||||
} else {
|
||||
fulfil({});
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
</script>
|
||||
1
test/app/src/routes/store.html
Normal file
1
test/app/src/routes/store.html
Normal file
@@ -0,0 +1 @@
|
||||
<h1>{$title}</h1>
|
||||
3
test/app/src/routes/throw-an-error.js
Normal file
3
test/app/src/routes/throw-an-error.js
Normal file
@@ -0,0 +1,3 @@
|
||||
export function get() {
|
||||
throw new Error('nope');
|
||||
}
|
||||
9
test/app/src/routes/unsafe-replacement.html
Normal file
9
test/app/src/routes/unsafe-replacement.html
Normal file
@@ -0,0 +1,9 @@
|
||||
$&
|
||||
|
||||
<script>
|
||||
export default {
|
||||
preload() {
|
||||
return '$&';
|
||||
}
|
||||
};
|
||||
</script>
|
||||
128
test/app/src/server.js
Normal file
128
test/app/src/server.js
Normal file
@@ -0,0 +1,128 @@
|
||||
import fs from 'fs';
|
||||
import { resolve } from 'url';
|
||||
import express from 'express';
|
||||
import serve from 'serve-static';
|
||||
import sapper from '../../../dist/middleware.js';
|
||||
import { Store } from 'svelte/store.js';
|
||||
import { manifest } from './manifest/server.js';
|
||||
|
||||
let pending;
|
||||
let ended;
|
||||
|
||||
process.on('message', message => {
|
||||
if (message.action === 'start') {
|
||||
if (pending) {
|
||||
throw new Error(`Already capturing`);
|
||||
}
|
||||
|
||||
pending = new Set();
|
||||
ended = false;
|
||||
process.send({ type: 'ready' });
|
||||
}
|
||||
|
||||
if (message.action === 'end') {
|
||||
ended = true;
|
||||
if (pending.size === 0) {
|
||||
process.send({ type: 'done' });
|
||||
pending = null;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
const app = express();
|
||||
|
||||
const { PORT = 3000, BASEPATH = '' } = process.env;
|
||||
const base = `http://localhost:${PORT}${BASEPATH}/`;
|
||||
|
||||
// this allows us to do e.g. `fetch('/api/blog')` on the server
|
||||
const fetch = require('node-fetch');
|
||||
global.fetch = (url, opts) => {
|
||||
return fetch(resolve(base, url), opts);
|
||||
};
|
||||
|
||||
const middlewares = [
|
||||
serve('assets'),
|
||||
|
||||
// set test cookie
|
||||
(req, res, next) => {
|
||||
res.setHeader('Set-Cookie', 'test=woohoo!; Max-Age=3600');
|
||||
next();
|
||||
},
|
||||
|
||||
// emit messages so we can capture requests
|
||||
(req, res, next) => {
|
||||
if (!pending) return next();
|
||||
|
||||
pending.add(req.url);
|
||||
|
||||
const { write, end } = res;
|
||||
const chunks = [];
|
||||
|
||||
res.write = function(chunk) {
|
||||
chunks.push(new Buffer(chunk));
|
||||
write.apply(res, arguments);
|
||||
};
|
||||
|
||||
res.end = function(chunk) {
|
||||
if (chunk) chunks.push(new Buffer(chunk));
|
||||
end.apply(res, arguments);
|
||||
|
||||
if (pending) pending.delete(req.url);
|
||||
|
||||
process.send({
|
||||
method: req.method,
|
||||
url: req.url,
|
||||
status: res.statusCode,
|
||||
headers: res._headers,
|
||||
body: Buffer.concat(chunks).toString()
|
||||
});
|
||||
|
||||
if (pending && pending.size === 0 && ended) {
|
||||
process.send({ type: 'done' });
|
||||
}
|
||||
};
|
||||
|
||||
next();
|
||||
},
|
||||
|
||||
// set up some values for the store
|
||||
(req, res, next) => {
|
||||
req.hello = 'hello';
|
||||
res.locals = { name: 'world' };
|
||||
next();
|
||||
},
|
||||
|
||||
sapper({
|
||||
manifest,
|
||||
store: (req, res) => {
|
||||
return new Store({
|
||||
title: `${req.hello} ${res.locals.name}`
|
||||
});
|
||||
},
|
||||
ignore: [
|
||||
/foobar/i,
|
||||
'/buzz',
|
||||
'fizz',
|
||||
x => x === '/hello'
|
||||
]
|
||||
}),
|
||||
];
|
||||
|
||||
app.get(`${BASEPATH}/non-sapper-redirect-from`, (req, res) => {
|
||||
res.writeHead(301, {
|
||||
Location: `${BASEPATH}/non-sapper-redirect-to`
|
||||
});
|
||||
res.end();
|
||||
});
|
||||
|
||||
if (BASEPATH) {
|
||||
app.use(BASEPATH, ...middlewares);
|
||||
} else {
|
||||
app.use(...middlewares);
|
||||
}
|
||||
|
||||
['foobar', 'buzz', 'fizzer', 'hello'].forEach(uri => {
|
||||
app.get('/'+uri, (req, res) => res.end(uri));
|
||||
});
|
||||
|
||||
app.listen(PORT);
|
||||
75
test/app/src/service-worker.js
Normal file
75
test/app/src/service-worker.js
Normal file
@@ -0,0 +1,75 @@
|
||||
import { assets, shell, timestamp, routes } from './manifest/service-worker.js';
|
||||
|
||||
const ASSETS = `cachetimestamp`;
|
||||
|
||||
// `shell` is an array of all the files generated by webpack,
|
||||
// `assets` is an array of everything in the `assets` directory
|
||||
const to_cache = shell.concat(assets);
|
||||
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);
|
||||
}
|
||||
|
||||
await self.clients.claim();
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
self.addEventListener('fetch', event => {
|
||||
const url = new URL(event.request.url);
|
||||
|
||||
// don't try to handle e.g. data: URIs
|
||||
if (!url.protocol.startsWith('http')) return;
|
||||
|
||||
// always serve assets and webpack-generated files from cache
|
||||
if (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;
|
||||
}
|
||||
*/
|
||||
|
||||
// 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')
|
||||
.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;
|
||||
}
|
||||
})
|
||||
);
|
||||
});
|
||||
33
test/app/src/template.html
Normal file
33
test/app/src/template.html
Normal file
@@ -0,0 +1,33 @@
|
||||
<!doctype html>
|
||||
<html lang='en'>
|
||||
<head>
|
||||
<meta charset='utf-8'>
|
||||
<meta name='viewport' content='width=device-width'>
|
||||
<meta name='theme-color' content='#aa1e1e'>
|
||||
|
||||
%sapper.base%
|
||||
|
||||
<link rel='stylesheet' href='global.css'>
|
||||
<link rel='manifest' href='manifest.json'>
|
||||
<link rel='icon' type='image/png' href='favicon.png'>
|
||||
|
||||
<!-- Sapper generates a <style> tag containing critical CSS
|
||||
for the current page. CSS for the rest of the app is
|
||||
lazily loaded when it precaches secondary pages -->
|
||||
%sapper.styles%
|
||||
|
||||
<!-- This contains the contents of the <:Head> component, if
|
||||
the current page has one -->
|
||||
%sapper.head%
|
||||
</head>
|
||||
<body>
|
||||
<!-- The application will be rendered inside this element,
|
||||
because `templates/main.js` references it -->
|
||||
<div id='sapper'>%sapper.html%</div>
|
||||
|
||||
<!-- Sapper creates a <script> tag containing `templates/main.js`
|
||||
and anything else it needs to hydrate the app and
|
||||
initialise the router -->
|
||||
%sapper.scripts%
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user