create-qwik 0.0.39 → 0.0.40-0-dev20220808233008
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/starters/apps/base/package.json +3 -3
- package/starters/apps/blank/src/entry.express.tsx +2 -1
- package/starters/apps/qwik-city/package.json +1 -1
- package/starters/apps/qwik-city/src/components/body/body.tsx +2 -2
- package/starters/apps/qwik-city/src/components/breadcrumbs/breadcrumbs.tsx +2 -2
- package/starters/apps/qwik-city/src/components/counter/counter.tsx +2 -2
- package/starters/apps/qwik-city/src/components/menu/menu.tsx +2 -2
- package/starters/apps/qwik-city/src/root.tsx +1 -1
- package/starters/apps/qwik-city/src/routes/api/[org]/[user].json/index.ts +4 -10
- package/starters/apps/qwik-city/src/routes/api/_layout-foo/index.tsx +2 -2
- package/starters/apps/qwik-city/src/routes/api/data.json.ts +2 -6
- package/starters/apps/qwik-city/src/routes/api/index@foo.tsx +1 -10
- package/starters/apps/qwik-city/src/routes/blog/[...slug].tsx +2 -2
- package/starters/apps/qwik-city/src/routes/index.tsx +1 -1
- package/starters/apps/qwik-city/src/routes/products/[id].tsx +31 -44
- package/starters/servers/cloudflare-pages/src/entry.cloudflare.tsx +3 -49
- package/starters/servers/express/src/entry.express.tsx +18 -7
- package/starters/servers/{netlify → netlify-edge}/.node-version +0 -0
- package/starters/servers/{netlify → netlify-edge}/README.md +0 -0
- package/starters/servers/{netlify → netlify-edge}/netlify.toml +0 -0
- package/starters/servers/{netlify → netlify-edge}/package.json +0 -0
- package/starters/servers/{netlify → netlify-edge}/public/_headers +0 -0
- package/starters/servers/netlify-edge/src/entry.netlify.ts +6 -0
- package/starters/servers/{netlify → netlify-edge}/tsconfig.json +0 -0
- package/starters/servers/netlify/src/entry.netlify.ts +0 -27
package/package.json
CHANGED
|
@@ -15,12 +15,12 @@
|
|
|
15
15
|
"typecheck": "tsc --incremental --noEmit"
|
|
16
16
|
},
|
|
17
17
|
"devDependencies": {
|
|
18
|
-
"@builder.io/qwik": "0.0.
|
|
18
|
+
"@builder.io/qwik": "0.0.40-0-dev20220808233008",
|
|
19
19
|
"@types/eslint": "8.4.5",
|
|
20
20
|
"@types/node": "latest",
|
|
21
21
|
"@typescript-eslint/eslint-plugin": "5.30.7",
|
|
22
22
|
"@typescript-eslint/parser": "5.30.7",
|
|
23
|
-
"eslint-plugin-qwik": "0.0.
|
|
23
|
+
"eslint-plugin-qwik": "0.0.40-0-dev20220808233008",
|
|
24
24
|
"eslint": "8.20.0",
|
|
25
25
|
"node-fetch": "3.2.9",
|
|
26
26
|
"typescript": "4.7.4",
|
|
@@ -30,6 +30,6 @@
|
|
|
30
30
|
"homepage": "https://qwik.builder.io/",
|
|
31
31
|
"private": true,
|
|
32
32
|
"engines": {
|
|
33
|
-
"node": ">=
|
|
33
|
+
"node": "^14.18.0 || >=16.0.0"
|
|
34
34
|
}
|
|
35
35
|
}
|
|
@@ -36,12 +36,13 @@ app.get('/*', async (req, res, next) => {
|
|
|
36
36
|
// Render the Root component to a string
|
|
37
37
|
const result = await render({
|
|
38
38
|
stream: res,
|
|
39
|
-
url: req.url,
|
|
40
39
|
});
|
|
41
40
|
|
|
42
41
|
// respond with SSR'd HTML
|
|
43
42
|
if ('html' in result) {
|
|
44
43
|
res.send((result as any).html);
|
|
44
|
+
} else {
|
|
45
|
+
res.end();
|
|
45
46
|
}
|
|
46
47
|
} catch (e) {
|
|
47
48
|
// Error while server-side rendering
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { component$, Host } from '@builder.io/qwik';
|
|
2
|
-
import {
|
|
2
|
+
import { RouterOutlet } from '@builder.io/qwik-city';
|
|
3
3
|
|
|
4
4
|
export const Body = component$(
|
|
5
5
|
() => {
|
|
6
6
|
return (
|
|
7
7
|
<Host>
|
|
8
|
-
<
|
|
8
|
+
<RouterOutlet />
|
|
9
9
|
</Host>
|
|
10
10
|
);
|
|
11
11
|
},
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { component$, Host,
|
|
1
|
+
import { component$, Host, useStyles$ } from '@builder.io/qwik';
|
|
2
2
|
import { useContent, useLocation, ContentMenu } from '@builder.io/qwik-city';
|
|
3
3
|
import styles from './breadcrumbs.css?inline';
|
|
4
4
|
|
|
5
5
|
export const Breadcrumbs = component$(
|
|
6
6
|
() => {
|
|
7
|
-
|
|
7
|
+
useStyles$(styles);
|
|
8
8
|
|
|
9
9
|
const { menu } = useContent();
|
|
10
10
|
const loc = useLocation();
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { component$,
|
|
1
|
+
import { component$, useStyles$, useStore } from '@builder.io/qwik';
|
|
2
2
|
|
|
3
3
|
export const Counter = component$(() => {
|
|
4
4
|
const store = useStore({ count: 0 });
|
|
5
|
-
|
|
5
|
+
useStyles$(`
|
|
6
6
|
.counter {
|
|
7
7
|
border: 3px solid #1474ff;
|
|
8
8
|
padding: 10px;
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { component$, Host,
|
|
1
|
+
import { component$, Host, useStyles$ } from '@builder.io/qwik';
|
|
2
2
|
import { useContent, Link, useLocation } from '@builder.io/qwik-city';
|
|
3
3
|
import styles from './menu.css?inline';
|
|
4
4
|
|
|
5
5
|
export const Menu = component$(
|
|
6
6
|
() => {
|
|
7
|
-
|
|
7
|
+
useStyles$(styles);
|
|
8
8
|
|
|
9
9
|
const { menu } = useContent();
|
|
10
10
|
const loc = useLocation();
|
|
@@ -1,21 +1,15 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import os from 'os';
|
|
1
|
+
import type { RequestHandler } from '@builder.io/qwik-city';
|
|
3
2
|
|
|
4
|
-
export const onGet:
|
|
3
|
+
export const onGet: RequestHandler = ({ request, params }) => {
|
|
5
4
|
return {
|
|
6
5
|
timestamp: Date.now(),
|
|
7
6
|
method: request.method,
|
|
8
7
|
url: request.url,
|
|
9
8
|
params,
|
|
10
|
-
os: os.platform(),
|
|
11
|
-
arch: os.arch(),
|
|
12
|
-
node: process.versions.node,
|
|
13
9
|
};
|
|
14
10
|
};
|
|
15
11
|
|
|
16
|
-
export const onPost:
|
|
12
|
+
export const onPost: RequestHandler = async ({ request, response }) => {
|
|
17
13
|
response.headers.set('Content-Type', 'text/plain');
|
|
18
|
-
return `
|
|
19
|
-
request.method
|
|
20
|
-
}`;
|
|
14
|
+
return `HTTP Method: ${request.method}`;
|
|
21
15
|
};
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { component$, Host, Slot,
|
|
1
|
+
import { component$, Host, Slot, useStyles$ } from '@builder.io/qwik';
|
|
2
2
|
import type { DocumentHead } from '@builder.io/qwik-city';
|
|
3
3
|
import styles from './api.css?inline';
|
|
4
4
|
|
|
5
5
|
export default component$(() => {
|
|
6
|
-
|
|
6
|
+
useStyles$(styles);
|
|
7
7
|
|
|
8
8
|
return (
|
|
9
9
|
<Host class="api">
|
|
@@ -1,13 +1,9 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import os from 'os';
|
|
1
|
+
import type { RequestHandler } from '@builder.io/qwik-city';
|
|
3
2
|
|
|
4
|
-
export const onGet:
|
|
3
|
+
export const onGet: RequestHandler = ({ request }) => {
|
|
5
4
|
return {
|
|
6
5
|
timestamp: Date.now(),
|
|
7
6
|
method: request.method,
|
|
8
7
|
url: request.url,
|
|
9
|
-
os: os.platform(),
|
|
10
|
-
arch: os.arch(),
|
|
11
|
-
node: process.versions.node,
|
|
12
8
|
};
|
|
13
9
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { component$, Host, useClientEffect$, useStore } from '@builder.io/qwik';
|
|
2
2
|
|
|
3
3
|
export default component$(() => {
|
|
4
|
-
const store = useStore({ timestamp: ''
|
|
4
|
+
const store = useStore({ timestamp: '' });
|
|
5
5
|
|
|
6
6
|
useClientEffect$(async () => {
|
|
7
7
|
const url = `/api/builder.io/oss.json`;
|
|
@@ -9,9 +9,6 @@ export default component$(() => {
|
|
|
9
9
|
const data: any = await rsp.json();
|
|
10
10
|
|
|
11
11
|
store.timestamp = data.timestamp;
|
|
12
|
-
store.os = data.os;
|
|
13
|
-
store.arch = data.arch;
|
|
14
|
-
store.node = data.node;
|
|
15
12
|
});
|
|
16
13
|
|
|
17
14
|
return (
|
|
@@ -28,12 +25,6 @@ export default component$(() => {
|
|
|
28
25
|
</ul>
|
|
29
26
|
|
|
30
27
|
<p>Timestamp: {store.timestamp}</p>
|
|
31
|
-
<p>
|
|
32
|
-
Node: <span>{store.node}</span>
|
|
33
|
-
</p>
|
|
34
|
-
<p>
|
|
35
|
-
OS: <span>{store.os}</span>
|
|
36
|
-
</p>
|
|
37
28
|
</Host>
|
|
38
29
|
);
|
|
39
30
|
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { component$, Host, Resource } from '@builder.io/qwik';
|
|
2
|
-
import { useEndpoint, DocumentHead,
|
|
2
|
+
import { useEndpoint, DocumentHead, RequestHandler } from '@builder.io/qwik-city';
|
|
3
3
|
|
|
4
4
|
export default component$(() => {
|
|
5
5
|
const resource = useEndpoint<typeof onGet>();
|
|
@@ -19,7 +19,7 @@ export default component$(() => {
|
|
|
19
19
|
);
|
|
20
20
|
});
|
|
21
21
|
|
|
22
|
-
export const onGet:
|
|
22
|
+
export const onGet: RequestHandler<EndpointData> = async ({ params, request }) => {
|
|
23
23
|
return {
|
|
24
24
|
blogTitle: `Blog: ${params.slug}`,
|
|
25
25
|
blogContent: `${params.slug}, ${request.url}`,
|
|
@@ -4,7 +4,7 @@ import type { DocumentHead } from '@builder.io/qwik-city';
|
|
|
4
4
|
export default component$(() => {
|
|
5
5
|
return (
|
|
6
6
|
<Host>
|
|
7
|
-
<h1
|
|
7
|
+
<h1>Welcome to Qwik City</h1>
|
|
8
8
|
|
|
9
9
|
<p>The meta-framework for Qwik.</p>
|
|
10
10
|
</Host>
|
|
@@ -1,10 +1,8 @@
|
|
|
1
|
-
import { Resource, component$, Host
|
|
2
|
-
import { useEndpoint, useLocation,
|
|
3
|
-
import os from 'os';
|
|
1
|
+
import { Resource, component$, Host } from '@builder.io/qwik';
|
|
2
|
+
import { useEndpoint, useLocation, RequestHandler, DocumentHead } from '@builder.io/qwik-city';
|
|
4
3
|
|
|
5
4
|
export default component$(() => {
|
|
6
|
-
const { params
|
|
7
|
-
const store = useStore({ productFetchData: '' });
|
|
5
|
+
const { params } = useLocation();
|
|
8
6
|
|
|
9
7
|
const resource = useEndpoint<typeof onGet>();
|
|
10
8
|
|
|
@@ -30,23 +28,6 @@ export default component$(() => {
|
|
|
30
28
|
|
|
31
29
|
<p>(Artificial response delay of 250ms)</p>
|
|
32
30
|
|
|
33
|
-
<p>
|
|
34
|
-
<button
|
|
35
|
-
onClick$={async () => {
|
|
36
|
-
const rsp = await fetch(pathname, {
|
|
37
|
-
headers: { accept: 'application/json' },
|
|
38
|
-
});
|
|
39
|
-
store.productFetchData = JSON.stringify(await rsp.json(), null, 2);
|
|
40
|
-
}}
|
|
41
|
-
>
|
|
42
|
-
fetch("{pathname}") data
|
|
43
|
-
</button>
|
|
44
|
-
</p>
|
|
45
|
-
|
|
46
|
-
<pre>
|
|
47
|
-
<code>{store.productFetchData}</code>
|
|
48
|
-
</pre>
|
|
49
|
-
|
|
50
31
|
<hr />
|
|
51
32
|
|
|
52
33
|
<ul>
|
|
@@ -67,53 +48,59 @@ export default component$(() => {
|
|
|
67
48
|
);
|
|
68
49
|
});
|
|
69
50
|
|
|
70
|
-
export const head: DocumentHead<ProductData
|
|
71
|
-
if (!data) {
|
|
72
|
-
return {
|
|
73
|
-
title: 'Product Not Found',
|
|
74
|
-
};
|
|
75
|
-
}
|
|
76
|
-
|
|
51
|
+
export const head: DocumentHead<ProductData> = ({ data }) => {
|
|
77
52
|
return {
|
|
78
53
|
title: `Product ${data.productId}, ${data.price}`,
|
|
79
54
|
};
|
|
80
55
|
};
|
|
81
56
|
|
|
82
|
-
export const onGet:
|
|
57
|
+
export const onGet: RequestHandler<EndpointData> = async ({ params, response }) => {
|
|
83
58
|
// Serverside Endpoint
|
|
84
59
|
// During SSR, this method is called directly on the server and returns the data object
|
|
85
60
|
// On the client, this same data can be requested with fetch() at the same URL, but also
|
|
86
61
|
// requires the "accept: application/json" request header.
|
|
87
62
|
|
|
88
|
-
// artificial slow response
|
|
89
|
-
await new Promise<void>((resolve) => setTimeout(resolve, 250));
|
|
90
|
-
|
|
91
63
|
if (params.id === 'shirt') {
|
|
92
64
|
// Redirect, which will skip any rendering and the server will immediately redirect
|
|
93
65
|
response.redirect('/products/tshirt');
|
|
94
66
|
return;
|
|
95
67
|
}
|
|
96
68
|
|
|
97
|
-
|
|
69
|
+
// artificially slow database call
|
|
70
|
+
const productData = await loadProduct(params.id);
|
|
98
71
|
|
|
99
|
-
if (!
|
|
72
|
+
if (!productData) {
|
|
100
73
|
// Product data not found
|
|
101
74
|
// but the data is still given to the renderer to decide what to do
|
|
102
75
|
response.status = 404;
|
|
103
|
-
return
|
|
76
|
+
return;
|
|
104
77
|
}
|
|
105
78
|
|
|
106
79
|
// Found the product data
|
|
107
80
|
// This same data is passed to the head() function
|
|
108
81
|
// and in the component$() it can be access with useEndpoint()
|
|
109
82
|
response.headers.set('Cache-Control', 'no-cache, no-store, no-fun');
|
|
110
|
-
return
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
83
|
+
return productData;
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
// our pretty awesome function to load product data
|
|
87
|
+
const loadProduct = (productId: string) => {
|
|
88
|
+
return new Promise<ProductData | null>((resolve) =>
|
|
89
|
+
setTimeout(() => {
|
|
90
|
+
const productPrice = PRODUCT_DB[productId];
|
|
91
|
+
if (!productPrice) {
|
|
92
|
+
return null;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
const productData: ProductData = {
|
|
96
|
+
productId,
|
|
97
|
+
price: productPrice,
|
|
98
|
+
description: `Product description here.`,
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
resolve(productData);
|
|
102
|
+
}, 250)
|
|
103
|
+
);
|
|
117
104
|
};
|
|
118
105
|
|
|
119
106
|
// Our pretty awesome database of prices
|
|
@@ -123,7 +110,7 @@ const PRODUCT_DB: Record<string, string> = {
|
|
|
123
110
|
tshirt: '$18.96',
|
|
124
111
|
};
|
|
125
112
|
|
|
126
|
-
type EndpointData = ProductData
|
|
113
|
+
type EndpointData = ProductData;
|
|
127
114
|
|
|
128
115
|
interface ProductData {
|
|
129
116
|
productId: string;
|
|
@@ -1,52 +1,6 @@
|
|
|
1
1
|
import render from './entry.ssr';
|
|
2
|
+
import { qwikCity } from '@builder.io/qwik-city/middleware/cloudflare-pages';
|
|
2
3
|
|
|
3
|
-
|
|
4
|
-
* Cloudflare Pages Request Handler
|
|
5
|
-
*/
|
|
6
|
-
export const onRequest: PagesFunction = async ({ request, next, waitUntil }) => {
|
|
7
|
-
try {
|
|
8
|
-
const url = new URL(request.url);
|
|
4
|
+
const qwikCityMiddleware = qwikCity(render);
|
|
9
5
|
|
|
10
|
-
|
|
11
|
-
if (/\.\w+$/.test(request.url)) {
|
|
12
|
-
return next(request);
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
// Do not using caching during development
|
|
16
|
-
const useCache = url.hostname !== 'localhost' && request.method === 'GET';
|
|
17
|
-
|
|
18
|
-
// Early return from cache
|
|
19
|
-
const cache = await caches.open('custom:qwik');
|
|
20
|
-
if (useCache) {
|
|
21
|
-
const cachedResponse = await cache.match(request);
|
|
22
|
-
if (cachedResponse) {
|
|
23
|
-
return cachedResponse;
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
// Generate Qwik SSR HTML
|
|
28
|
-
const result = await render({
|
|
29
|
-
url: request.url,
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
// Create HTTP Response
|
|
33
|
-
const response = new Response(result.html, {
|
|
34
|
-
headers: {
|
|
35
|
-
'Content-Type': 'text/html; charset=utf-8',
|
|
36
|
-
'Cache-Control': useCache
|
|
37
|
-
? `max-age=60, s-maxage=10, stale-while-revalidate=604800, stale-if-error=604800`
|
|
38
|
-
: `no-cache, max-age=0`,
|
|
39
|
-
},
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
if (useCache) {
|
|
43
|
-
waitUntil(cache.put(request, response.clone()));
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
// Return Qwik SSR response
|
|
47
|
-
return response;
|
|
48
|
-
} catch (e) {
|
|
49
|
-
// 500 Error
|
|
50
|
-
return new Response(String(e), { status: 500 });
|
|
51
|
-
}
|
|
52
|
-
};
|
|
6
|
+
export const onRequestGet = [qwikCityMiddleware];
|
|
@@ -1,19 +1,30 @@
|
|
|
1
1
|
import express from 'express';
|
|
2
2
|
import { fileURLToPath } from 'url';
|
|
3
3
|
import { join } from 'path';
|
|
4
|
-
import cityPlan from '@qwik-city-plan';
|
|
5
4
|
import { qwikCity } from '@builder.io/qwik-city/middleware/express';
|
|
6
5
|
import render from './entry.ssr';
|
|
7
6
|
|
|
7
|
+
// directories where the static assets are located
|
|
8
|
+
const distDir = join(fileURLToPath(import.meta.url), '..', '..', 'dist');
|
|
9
|
+
const buildDir = join(distDir, 'build');
|
|
10
|
+
|
|
11
|
+
// create the Qwik City express middleware
|
|
12
|
+
const { router, notFound } = qwikCity(render);
|
|
13
|
+
|
|
14
|
+
// create the express server
|
|
8
15
|
const app = express();
|
|
9
16
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
);
|
|
17
|
+
// use Qwik City's page and endpoint handler
|
|
18
|
+
app.use(router);
|
|
19
|
+
|
|
20
|
+
// static asset handlers
|
|
21
|
+
app.use(`/build`, express.static(buildDir, { immutable: true, maxAge: '1y', index: false }));
|
|
22
|
+
app.use(express.static(distDir, { index: false }));
|
|
23
|
+
|
|
24
|
+
// use Qwik City's 404 handler
|
|
25
|
+
app.use(notFound);
|
|
16
26
|
|
|
27
|
+
// start the express server
|
|
17
28
|
app.listen(8080, () => {
|
|
18
29
|
/* eslint-disable */
|
|
19
30
|
console.log(`http://localhost:8080/`);
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import render from './entry.ssr';
|
|
2
|
-
|
|
3
|
-
const handler = async (request: Request) => {
|
|
4
|
-
try {
|
|
5
|
-
// Handle static files
|
|
6
|
-
if (/\.\w+$/.test(request.url)) {
|
|
7
|
-
return;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
const ssrResult = await render({
|
|
11
|
-
url: request.url,
|
|
12
|
-
base: '/build/',
|
|
13
|
-
});
|
|
14
|
-
|
|
15
|
-
const response = new Response(ssrResult.html, {
|
|
16
|
-
headers: {
|
|
17
|
-
'Content-Type': 'text/html; charset=utf-8',
|
|
18
|
-
},
|
|
19
|
-
});
|
|
20
|
-
return response;
|
|
21
|
-
} catch (e) {
|
|
22
|
-
// 500 Error
|
|
23
|
-
return new Response(String(e), { status: 500 });
|
|
24
|
-
}
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
export default handler;
|