Skip to content

Commit

Permalink
Revamp workers.new/list into a workers.new/template with new design (c…
Browse files Browse the repository at this point in the history
…loudflare#134)

* revamp workers.list into a new design
  • Loading branch information
lauragift21 authored Nov 14, 2022
1 parent 62445b4 commit a84595d
Show file tree
Hide file tree
Showing 102 changed files with 1,564 additions and 60 deletions.
162 changes: 102 additions & 60 deletions packages/workers.new/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { promisify } from 'util';
// Redirect https://workers.new/<known> requests to IDE.
// Redirect https://workers.new/*? requests to dashboard.
// Similar to the concept of https://docs.new.
Expand All @@ -8,6 +7,10 @@ type Redirects = Record<string, [string, string, string, string?]>;
// stackblitz repository source
const source = 'github/cloudflare/templates/tree/main';

// deploy with cloudflare source

const src = 'https://github.com/cloudflare/templates/tree/main';

const redirects: Redirects = {
'/durable-objects': ['worker-durable-objects', 'index.js', 'Workers Durable Objects counter'],
'/example-wordle': ['worker-example-wordle', 'src/index.ts', 'Workers Wordle example'],
Expand All @@ -16,9 +19,6 @@ const redirects: Redirects = {
'src/index.ts',
'Workers Request Scheduler',
],
'/router': ['worker-router', 'index.js', 'Workers router'],
'/typescript': ['worker-typescript', 'src/index.ts', 'Workers TypeScript'],
'/websocket': ['worker-websocket', 'index.js', 'Workers WebSocket'],
'/websocket-durable-objects': [
'worker-websocket-durable-objects',
'src/index.ts',
Expand Down Expand Up @@ -90,18 +90,13 @@ const redirects: Redirects = {
'src/index.html',
'Play live video (using WHEP) over WebRTC with Cloudflare Stream',
],
'/stream/stripe-checkout': [
'stream/auth/stripe',
'functions/api/success.js',
'Example of using Cloudflare Stream and Stripe Checkout to paywall content',
],
};

const worker: ExportedHandler = {
fetch(request) {
const { pathname } = new URL(request.url);

if (pathname === '/list') {
if (pathname === '/templates') {
return new Response(getListHTML(redirects), { headers: { 'content-type': 'text/html' } });
}

Expand All @@ -128,98 +123,145 @@ function getRedirectUrlForPathname(pathname: string): string | undefined {
function getListHTML(redirects: Redirects) {
return `
<html>
<head></head>
<head>
<link href='https://fonts.googleapis.com/css2?family=Inter:wght@200;300;500;700&display=swap' rel='stylesheet'>
</head>
<style>
body {
border: 20px solid #003682;
margin: 0px;
margin: 2rem 10rem;
font-family: "Inter", sans-serif;
}
h1{
text-align: center;
margin: 20px 0;
font-size: 5rem;
}
.title-accent {
color: #003682;
font-weight: 600;
text-decoration: underline;
.nav {
display: flex;
justify-content: space-between;
font-size: 18px;
}
a {
text-decoration: none;
}
.subtitle {
a {
color: inherit;
}
.heading {
font-size: 25px;
text-align: center;
margin: 0;
font-weight: 700;
}
.subheading {
text-align: center;
margin-top: 20px;
font-size: 2rem;
font-size: 18px;
font-weight: 300;
}
.title {
font-weight: 400;
margin-bottom: 50px;
}
ul {
text-decoration: none;
list-style: none;
display: flex;
flex-wrap: wrap;
gap: 20px;
justify-content: center;
min-height: 170px;
font-size: 24px;
text-align: center;
padding-top: 30px;
}
a {
color: inherit;
li {
padding: 20px 20px;
border: 1px solid #d5d7d8;
border-radius: 10px;
}
li {
border: 2px solid #003682;
box-sizing: border-box;
color: #00132C;
font-size: 24px;
font-weight: 900;
padding: 50px 30px;
position: relative;
}
.featured {
padding: 20px 20px;
border: 4px solid #f1740a;
border-radius: 10px;
background: #fef1e6;
}
li:before {
background-color: #D5EDF6;
content: "";
height: calc(100% + 3px);
position: absolute;
right: -7px;
top: -9px;
transition: background-color 300ms ease-in;
width: 100%;
z-index: -1;
}
.btn {
margin: 0 10px;
text-decoration: underline;
}
li:hover:before {
background-color: #C2E3FB;
}
.link {
padding: 10px;
border: 1px dotted #f1740a;
border-radius: 5px;
}
.title {
font-size: 20px;
font-weight: 400;
}
.link:hover {
background: #f1740a;
color: #fff;
}
.card-title {
font-weight: 600;
}
.url {
color: #f1740a;
font-weight: 700;
}
</style>
<body>
<h1>List of <span class="title-accent">workers.new</span> Redirects</h1>
<p class="subtitle">A collection of Stackblitz templates ready for you to use!</p>
<nav class="nav">
<a href="https://workers.cloudflare.com">
<img src="https://imagedelivery.net/T24Zz2DP7HaLOEAdMToO-g/70363224-4bee-4f48-a775-06ffdfbc6d00/public" height="50" alt="Cloudflare Workers" />
</a>
<a href="https://developers.cloudflare.com/workers">Documentation</a>
</nav>
<p class="heading">Cloudflare Workers Templates</p>
<p class="subheading">Ready to use templates to start building applications on Cloudflare Workers.</p>
<ul>
<li>
<a href="/">workers.new</a>
<p class="title"> Cloudflare Dashboard shortcut </p>
<li class="featured">
<p class="heading">Image Sharing Website</p>
<p class="title"> Image sharing with Pages Functions </p>
<span class="btn"><a href="https://workers.new/pages-image-sharing">Open with StackBlitz</a></span>
<span class="btn"><a href="https://deploy.workers.cloudflare.com/?url=https://github.com/cloudflare/templates/tree/main/pages-image-sharing">Deploy with Workers</a></span>
</li>
<li class="featured">
<p class="heading">Stream + Stripe Checkout </p>
<p class="title"> Host paid live event with Stream and Stripe</p>
<span class="btn"><a href="https://workers.new/stream/auth/stripe">Open with StackBlitz</a></span>
<span class="btn"><a href="https://deploy.workers.cloudflare.com/?url=https://github.com/cloudflare/templates/tree/main/stream/paste-video">Deploy with Workers</a></span>
</li>
<li class="featured">
<p class="heading">Paste.video</p>
<p class="title"> Made with Stream, Workers, D1 & R2 </p>
<span class="btn"><a href="https://workers.new/stream/paste-video">Open with StackBlitz</a></span>
<span class="btn"><a href="https://deploy.workers.cloudflare.com/?url=https://github.com/cloudflare/templates/tree/main/stream/auth/stripe">Deploy with Workers</a></span>
</li>
${Object.keys(redirects)
.map(pathname => {
const [subdir, file, title, terminal] = redirects[pathname] || [];
return `<li>
<a href="${pathname}">workers.new${pathname}</a>
<p class="title">${title}</p>
<p class="card-title">${subdir}</p>
<p class="title"> ${title} </p>
<span class="link"><a target="_blank" href="https://workers.new${pathname}">Open with StackBlitz</a></span>
<span class="link"><a target="_blank" href="https://deploy.workers.cloudflare.com/?url=${src}/${subdir}">Deploy with Workers</a></span>
</li>`;
})
.join('\n')}
</ul>
<p class="subheading">Want to contribute a template? <a class="url" href="https://github.com/cloudflare/templates"> Send a PR to the templates repository.</a></p>
</body>
</html>
`;
Expand Down
1 change: 1 addition & 0 deletions packages/workers.new/wrangler.toml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
name = "workers-dot-new"
compatibility_date = "2022-05-03"
main = "src/index.ts"
workers_dev = false
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Forum application built with Pages Functions, Workers KV and Durable Objects

[![Deploy to Cloudflare Workers](https://deploy.workers.cloudflare.com/button)](https://deploy.workers.cloudflare.com/?url=https://github.com/cloudflare/templates/tree/main/pages-example-forum-app)

## Overview

This example application showcases a forum application that allows authenticated users to leave comments, like comments and reply on other user’s comments using Pages Functions to handle server-side logic such as Authentication and posting comments to Workers KV. We will also use Workers KV for storage of our comment entries and Durable Objects to keep the count of likes consistent.
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes
File renamed without changes
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
26 changes: 26 additions & 0 deletions pages-image-sharing/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
/node_modules
/.pnp
.pnp.js

# testing
/coverage

# production
/build

# misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local

npm-debug.log*
yarn-debug.log*
yarn-error.log*

# Pages
/.pages
1 change: 1 addition & 0 deletions pages-image-sharing/.nvmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
v16.7.0
21 changes: 21 additions & 0 deletions pages-image-sharing/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2021 Cloudflare

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
5 changes: 5 additions & 0 deletions pages-image-sharing/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Image sharing platform build with Cloudflare Pages

[![Deploy to Cloudflare Workers](https://deploy.workers.cloudflare.com/button)](https://deploy.workers.cloudflare.com/?url=https://github.com/cloudflare/templates/tree/main/pages-image-sharing)

This example application showcases Cloudflare Pages functions powered by Cloudflare Workers
11 changes: 11 additions & 0 deletions pages-image-sharing/craco.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
module.exports = {
devServer: {
hot: false,
inline: false,
},
style: {
postcss: {
plugins: [require('tailwindcss'), require('autoprefixer')],
},
},
};
10 changes: 10 additions & 0 deletions pages-image-sharing/durable_objects/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Download Counter Durable Object

To maintain an accurate count of the number of downloads for each image, we're using Durable Objects. Each image has its own instance of the Durable Object class defined in [`./src/downloadCounter.js`](./src/downloadCounter.js). At present, wrangler v2 does not support Durable Objects, which is why this exists in its own little package. We'll update this repo when we can simplify the deployment process.

## Publish

```sh
npm install;
CF_ACCOUNT_ID="<YOUR CLOUDFLARE ACCOUNT ID>" npm run publish;
```
13 changes: 13 additions & 0 deletions pages-image-sharing/durable_objects/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"name": "@images.page.dev/durable_objects",
"version": "0.1.0",
"private": true,
"license": "MIT",
"module": "./src/downloadCounter.mjs",
"scripts": {
"publish": "npx wrangler publish"
},
"devDependencies": {
"@cloudflare/wrangler": "^1.19.5"
}
}
36 changes: 36 additions & 0 deletions pages-image-sharing/durable_objects/src/downloadCounter.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// Adapted from the example in our documentation: https://developers.cloudflare.com/workers/learning/using-durable-objects#example---counter

const jsonResponse = (value, init = {}) =>
new Response(JSON.stringify(value), {
headers: { 'Content-Type': 'application/json', ...init.headers },
...init,
});

export class DownloadCounter {
constructor(state) {
this.state = state;
// `blockConcurrencyWhile()` ensures no requests are delivered until initialization completes.
this.state.blockConcurrencyWhile(async () => {
let stored = await this.state.storage.get('value');
this.value = stored || 0;
});
}

async fetch(request) {
const url = new URL(request.url);
let currentValue = this.value;

if (url.pathname === '/increment') {
currentValue = ++this.value;
await this.state.storage.put('value', currentValue);
}

return jsonResponse(currentValue);
}
}

export default {
fetch() {
return new Response('This Worker creates the DownloadCounter Durable Object.');
},
};
Loading

0 comments on commit a84595d

Please sign in to comment.