@bwog/bwog 0.0.0-stage → 0.1.1

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.
@@ -0,0 +1,168 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <% if (it.title === null) { %>
7
+ <meta name="description" content="A microblog of music I'm currently interested in.">
8
+ <% } else { %>
9
+ <meta name="description" content="An archive of posts from <%= `${it.title}` %>.">
10
+ <% } %>
11
+ <link rel="icon" type="image/svg+xml" sizes="any" href="data:image/svg+xml;charset=utf-8,<svg viewBox='0 0 100 100' xmlns='http://www.w3.org/2000/svg'><rect style='fill: %23ee009a' width='100' height='100' /><path style='fill: white' d='m 46.896145,88.64921 C 40.374404,74.369955 49.107189,69.176421 63.300981,75.966678 a 1.0075789,1.0075789 128.88245 0 0 1.239574,-1.537184 C 52.98292,61.336397 44.490904,53.053429 54.4857,40.9555 62.7098,31.0007 63.8784,28.384 56.693,22.0911 L 44.70917,11.59588 a 0.99988834,0.99988834 139.8069 0 0 -1.50978,1.275551 C 51.301904,26.208399 50.713597,27.307903 44.5515,34.8343 32.9606,48.9916 34.6,51.1771 49.6209,64.3152 32.226741,63.721624 28.851587,76.714805 45.431949,89.900492 a 0.99029164,0.99029164 139.48324 0 0 1.464196,-1.251282 z' /></svg>">
12
+ <% if (it.canonical !== null) { %>
13
+ <link rel="canonical" href="<%= it.canonical %>">
14
+ <% } %>
15
+ <link rel="alternate" type="application/atom+xml" href="feed.atom">
16
+ <title>music blog<%= it.title === null ? '' : ` (${it.title.toLowerCase()})` %></title>
17
+ <style>
18
+ body {
19
+ font-family: sans-serif;
20
+ width: 100%;
21
+ max-width: 35em;
22
+ margin: 0 auto;
23
+ padding: 1em;
24
+ box-sizing: border-box;
25
+ }
26
+
27
+ body > .title {
28
+ font-style: oblique;
29
+ display: block;
30
+ width: 70%;
31
+ }
32
+
33
+ body > .title > svg {
34
+ width: 100%;
35
+ }
36
+
37
+ #editor {
38
+ display: none;
39
+ }
40
+
41
+ form.editor {
42
+ margin-top: 2em;
43
+ }
44
+
45
+ form.editor textarea {
46
+ width: 100%;
47
+ box-sizing: border-box;
48
+ resize: vertical;
49
+ }
50
+
51
+ form.editor input[type="submit"] {
52
+ float: right;
53
+ }
54
+
55
+ a {
56
+ color: #099;
57
+ }
58
+
59
+ ol.posts {
60
+ list-style-type: none;
61
+ padding-left: 0;
62
+ margin: 0;
63
+ clear: both;
64
+ }
65
+
66
+ ol.posts > li .timestamp {
67
+ margin-left: -1em;
68
+ font-size: 0.7em;
69
+ }
70
+
71
+ ol.posts > li .text a {
72
+ line-break: anywhere;
73
+ }
74
+
75
+ ol.posts > li .song, ol.posts > li .album {
76
+ font-style: italic;
77
+ }
78
+
79
+ ol.posts > li > .playlist {
80
+ list-style-type: none;
81
+ padding-left: 0;
82
+ margin: 1em 0;
83
+ }
84
+
85
+ .pagination {
86
+ text-align: right;
87
+ }
88
+
89
+ .pagination > a:not(:first-child) {
90
+ margin-left: 1em;
91
+ }
92
+
93
+ .pagination.top {
94
+ margin: 0;
95
+ float: right;
96
+ }
97
+ </style>
98
+ <script>
99
+ window.addEventListener('load', () => {
100
+ document.querySelectorAll('ol.posts > li > time').forEach(element => {
101
+ const datetime = element.getAttribute('datetime');
102
+ const date = (new Date(datetime)).toLocaleDateString();
103
+ const time = (new Date(datetime)).toLocaleTimeString([], {timeStyle: 'short'});
104
+ element.innerHTML = `${date} (${time})`;
105
+ });
106
+
107
+ const isAuthed = document.cookie.split('; ').find((row) => row.startsWith('isAuthed='))?.split("=")[1] === 'true';
108
+ if (isAuthed) {
109
+ document.getElementById('editor').style.display = 'block';
110
+ }
111
+ });
112
+ </script>
113
+ </head>
114
+ <body>
115
+ <a class="title" href="/">
116
+ <svg viewBox="0 0 100 30">
117
+ <path style="fill: #ee009a;" d="m 6,0
118
+ L 100,0
119
+ L 94,30
120
+ L 0,30 z" />
121
+ <text role="heading" aria-level="1" style="fill: white; font-size: 16px; font-style: oblique" x="5" y="25">music</text>
122
+ </svg>
123
+ </a>
124
+ <p class="pagination top">
125
+ <% if (it.prevPage !== null) { %>
126
+ <a href="<%= it.prevPage %>">←prev</a>
127
+ <% } %>
128
+ <% if (it.nextPage !== null) { %>
129
+ <a href="<%= it.nextPage %>">next→</a>
130
+ <% } %>
131
+ </p>
132
+ <form id="editor" class="editor" action="./post" method="POST">
133
+ <textarea name="text" rows="3"></textarea>
134
+ <textarea name="tracks" rows="1" placeholder="Artist - Title"></textarea>
135
+ <input type="submit" value="post">
136
+ </form>
137
+ <ol class="posts">
138
+ <% it.posts.forEach(function(post) { %>
139
+ <li id="<%= post.id %>">
140
+ <time class="timestamp" datetime="<%= post.createdAt %>">
141
+ <%= (new Date(post.createdAt)).toLocaleDateString() %>
142
+ (<%= (new Date(post.createdAt)).toLocaleTimeString([], {timeStyle: 'short'}) %>)
143
+ </time>
144
+ <p class="text"><%~ post.text.replace(/(https:\/\/\S*)/g, '<a href="$1">$1</a>').replaceAll('\n', '<br />') %></p>
145
+ <% if (post.type === 'song') { %>
146
+ <p class="song"><span class="artist"><%= post.artist%></span> - <span class="title"><%= post.title %></span></p>
147
+ <% } else if (post.type === 'album') { %>
148
+ <p class="album"><span class="artist"><%= post.artist%></span> - <span class="title"><%= post.title %></span></p>
149
+ <% } else if (post.type === 'playlist') { %>
150
+ <ol class="playlist">
151
+ <% post.tracks.forEach(function(song) { %>
152
+ <li class="song"><span class="artist"><%= song.artist %></span> - <span class="title"><%= song.title %></span></li>
153
+ <% }) %>
154
+ </ol>
155
+ <% } %>
156
+ </li>
157
+ <% }) %>
158
+ </ol>
159
+ <p class="pagination">
160
+ <% if (it.prevPage !== null) { %>
161
+ <a href="<%= it.prevPage %>">←prev</a>
162
+ <% } %>
163
+ <% if (it.nextPage !== null) { %>
164
+ <a href="<%= it.nextPage %>">next→</a>
165
+ <% } %>
166
+ </p>
167
+ </body>
168
+ </html>
@@ -0,0 +1,9 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
3
+ <% it.pages.forEach(function(page) { %>
4
+ <url>
5
+ <loc><%= page.url %></loc>
6
+ <lastmod><%= page.updatedAt %></lastmod>
7
+ </url>
8
+ <% }) %>
9
+ </urlset>
package/wrangler.jsonc ADDED
@@ -0,0 +1,72 @@
1
+ {
2
+ "name": "bwog-app",
3
+ "main": "./node_modules/@bwog/bwog/cloudflare/worker.js",
4
+ "upload_source_maps": true,
5
+ "compatibility_date": "2026-11-11",
6
+ "workers_dev": false,
7
+ "preview_urls": false,
8
+ "durable_objects": {
9
+ "bindings": [
10
+ {
11
+ "name": "DATABASE",
12
+ "class_name": "Database"
13
+ }
14
+ ]
15
+ },
16
+ "r2_buckets": [
17
+ {
18
+ "binding": "STORE",
19
+ "bucket_name": "blog-public"
20
+ },
21
+ {
22
+ "binding": "PRIVATE_BUCKET",
23
+ "bucket_name": "blog-private"
24
+ }
25
+ ],
26
+ "exports": {
27
+ "Database": {
28
+ "type": "durable-object",
29
+ "storage": "sqlite"
30
+ }
31
+ },
32
+ "keep_vars": true,
33
+ "vars": {
34
+ "SITE_DOMAIN": "example.com",
35
+ "GOOGLE_OAUTH_AUTHORIZED_USER_ID": "12345ABCDE",
36
+ "GOOGLE_OAUTH_CLIENT_ID": "12345ABCDE.apps.googleusercontent.com",
37
+ "AUTHOR_NAME": "Alice Smith",
38
+ "AUTHOR_EMAIL": "author@example.com",
39
+ "ENABLE_AP": "false",
40
+ "AP_HANDLE": "author@example.com",
41
+ "AP_USERNAME": "author",
42
+ "AP_PUBLIC_KEY_STRING": "-----BEGIN PUBLIC KEY-----\n1234567890\n-----END PUBLIC KEY-----"
43
+ },
44
+ "secrets": {
45
+ "required": ["JWT_SECRET", "GOOGLE_OAUTH_CLIENT_SECRET"]
46
+ },
47
+ "alias": {
48
+ "bwog.config": "./bwog.config.js"
49
+ },
50
+ "routes": [
51
+ {
52
+ "pattern": "example.org/setup*",
53
+ "zone_name": "example.org"
54
+ },
55
+ {
56
+ "pattern": "example.org/generate*",
57
+ "zone_name": "example.org"
58
+ },
59
+ {
60
+ "pattern": "example.org/post*",
61
+ "zone_name": "example.org"
62
+ },
63
+ {
64
+ "pattern": "example.org/login*",
65
+ "zone_name": "example.org"
66
+ },
67
+ {
68
+ "pattern": "example.org/logout*",
69
+ "zone_name": "example.org"
70
+ }
71
+ ]
72
+ }