@bkazemi/verily 0.8.1 → 0.9.0
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/README.md +5 -3
- package/dist/instance/auth.js +6 -9
- package/dist/instance/cloudflare.js +3 -2
- package/dist/instance/dashboard.d.ts +41 -0
- package/dist/instance/dashboard.js +334 -0
- package/dist/instance/env.d.ts +2 -0
- package/dist/instance/env.js +1 -0
- package/dist/instance/index.d.ts +16 -1
- package/dist/instance/index.js +224 -83
- package/dist/instance/limits.d.ts +5 -3
- package/dist/instance/limits.js +6 -5
- package/dist/instance/owner-sites.d.ts +17 -0
- package/dist/instance/owner-sites.js +130 -0
- package/dist/instance/page.d.ts +11 -1
- package/dist/instance/page.js +22 -2
- package/dist/instance/register.d.ts +44 -0
- package/dist/instance/register.js +254 -0
- package/dist/instance/routes.js +14 -0
- package/dist/instance/sites.d.ts +135 -4
- package/dist/instance/sites.js +326 -57
- package/dist/server/email.js +134 -46
- package/dist/server/html.d.ts +34 -0
- package/dist/server/html.js +67 -0
- package/dist/server/index.js +338 -164
- package/dist/server/render.d.ts +10 -7
- package/dist/server/render.js +71 -21
- package/dist/server/service.d.ts +3 -1
- package/dist/server/service.js +5 -1
- package/dist/server/style.d.ts +1 -1
- package/dist/server/style.js +13 -0
- package/dist/site/index.d.ts +6 -0
- package/dist/site/index.js +8 -1
- package/dist/verily.js +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
package/dist/server/email.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Refused } from '../core/index.js';
|
|
2
2
|
import { emailLogo } from './email-logo.js';
|
|
3
|
-
import {
|
|
3
|
+
import { html, raw } from './html.js';
|
|
4
4
|
/** The logotype as the message carries it. */
|
|
5
5
|
const logo = {
|
|
6
6
|
contentId: 'verily-logo',
|
|
@@ -71,51 +71,139 @@ export function emailProvider(options) {
|
|
|
71
71
|
* otherwise push the code that far off centre.
|
|
72
72
|
*/
|
|
73
73
|
function letter(parts) {
|
|
74
|
-
|
|
75
|
-
const
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
<
|
|
80
|
-
<
|
|
81
|
-
<meta
|
|
82
|
-
<meta name="
|
|
83
|
-
<
|
|
84
|
-
<
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
<
|
|
99
|
-
<
|
|
100
|
-
<table
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
<
|
|
110
|
-
<
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
74
|
+
// Constants, let in as written so the quotes in them stay quotes.
|
|
75
|
+
const sans = raw("system-ui,-apple-system,'Segoe UI',Roboto,Helvetica,Arial,sans-serif");
|
|
76
|
+
const mono = raw("ui-monospace,SFMono-Regular,Menlo,Consolas,'Liberation Mono',monospace");
|
|
77
|
+
return html `
|
|
78
|
+
<!doctype html>
|
|
79
|
+
<html lang="en">
|
|
80
|
+
<head>
|
|
81
|
+
<meta charset="utf-8">
|
|
82
|
+
<meta name="viewport" content="width=device-width,initial-scale=1">
|
|
83
|
+
<meta name="color-scheme" content="light dark">
|
|
84
|
+
<meta name="supported-color-schemes" content="light dark">
|
|
85
|
+
<title>Verily</title>
|
|
86
|
+
<style>
|
|
87
|
+
@media (prefers-color-scheme: dark) {
|
|
88
|
+
.page { background: #161a18 !important; }
|
|
89
|
+
.ink { color: #dde5e0 !important; }
|
|
90
|
+
.muted { color: #96a39b !important; }
|
|
91
|
+
.button { background: #7fc4a2 !important; }
|
|
92
|
+
.button a { color: #10231a !important; }
|
|
93
|
+
.code { background: #1d2220 !important; border-color: #2f3b35 !important; color: #dde5e0 !important; }
|
|
94
|
+
.rule { border-color: #2f3b35 !important; }
|
|
95
|
+
}
|
|
96
|
+
</style>
|
|
97
|
+
</head>
|
|
98
|
+
<body class="page" style="margin:0;padding:0;background:#ffffff;">
|
|
99
|
+
<div style="display:none;max-height:0;overflow:hidden;opacity:0;">${parts.ask} ${parts.lasts}</div>
|
|
100
|
+
<table
|
|
101
|
+
role="presentation"
|
|
102
|
+
class="page"
|
|
103
|
+
width="100%"
|
|
104
|
+
cellpadding="0"
|
|
105
|
+
cellspacing="0"
|
|
106
|
+
border="0"
|
|
107
|
+
style="background:#ffffff;">
|
|
108
|
+
<tr>
|
|
109
|
+
<td align="center" style="padding:40px 16px 48px;">
|
|
110
|
+
<table
|
|
111
|
+
role="presentation"
|
|
112
|
+
align="center"
|
|
113
|
+
width="100%"
|
|
114
|
+
cellpadding="0"
|
|
115
|
+
cellspacing="0"
|
|
116
|
+
border="0"
|
|
117
|
+
style="max-width:440px;margin:0 auto;">
|
|
118
|
+
<tr>
|
|
119
|
+
<td align="center" style="padding:0 0 28px;">
|
|
120
|
+
<img
|
|
121
|
+
src="cid:${logo.contentId}"
|
|
122
|
+
width="94"
|
|
123
|
+
height="40"
|
|
124
|
+
alt="Verily"
|
|
125
|
+
style="display:block;margin:0 auto;border:0;outline:none;font:700 20px/40px ${sans};color:#23312b;">
|
|
126
|
+
</td>
|
|
127
|
+
</tr>
|
|
128
|
+
<tr>
|
|
129
|
+
<td
|
|
130
|
+
class="ink"
|
|
131
|
+
align="center"
|
|
132
|
+
style="padding:0 0 10px;font:650 22px/1.3 ${sans};color:#23312b;text-align:center;">
|
|
133
|
+
Confirm your address
|
|
134
|
+
</td>
|
|
135
|
+
</tr>
|
|
136
|
+
<tr>
|
|
137
|
+
<td
|
|
138
|
+
class="ink"
|
|
139
|
+
align="center"
|
|
140
|
+
style="padding:0 0 24px;font:16px/1.6 ${sans};color:#23312b;text-align:center;">
|
|
141
|
+
${parts.ask}
|
|
142
|
+
</td>
|
|
143
|
+
</tr>
|
|
144
|
+
<tr>
|
|
145
|
+
<td align="center" style="padding:0 0 28px;">
|
|
146
|
+
<table
|
|
147
|
+
role="presentation"
|
|
148
|
+
align="center"
|
|
149
|
+
cellpadding="0"
|
|
150
|
+
cellspacing="0"
|
|
151
|
+
border="0"
|
|
152
|
+
style="margin:0 auto;">
|
|
153
|
+
<tr>
|
|
154
|
+
<td class="button" align="center" style="background:#245f43;border-radius:10px;">
|
|
155
|
+
<a
|
|
156
|
+
href="${parts.link}"
|
|
157
|
+
style="display:inline-block;padding:13px 26px;font:600 16px/1.2 ${sans};color:#ffffff;text-decoration:none;">
|
|
158
|
+
${parts.button}
|
|
159
|
+
</a>
|
|
160
|
+
</td>
|
|
161
|
+
</tr>
|
|
162
|
+
</table>
|
|
163
|
+
</td>
|
|
164
|
+
</tr>
|
|
165
|
+
<tr>
|
|
166
|
+
<td
|
|
167
|
+
class="muted"
|
|
168
|
+
align="center"
|
|
169
|
+
style="padding:0 0 10px;font:14px/1.5 ${sans};color:#6b786f;text-align:center;">
|
|
170
|
+
${parts.enter}
|
|
171
|
+
</td>
|
|
172
|
+
</tr>
|
|
173
|
+
<tr>
|
|
174
|
+
<td
|
|
175
|
+
class="code"
|
|
176
|
+
align="center"
|
|
177
|
+
style="padding:14px 12px 14px 15px;background:#f7f9f7;border:1px solid #dce2de;border-radius:10px;font:600 22px/1.2 ${mono};letter-spacing:.14em;color:#23312b;text-align:center;">
|
|
178
|
+
${parts.code}
|
|
179
|
+
</td>
|
|
180
|
+
</tr>
|
|
181
|
+
<tr>
|
|
182
|
+
<td
|
|
183
|
+
class="muted"
|
|
184
|
+
align="center"
|
|
185
|
+
style="padding:12px 0 28px;font:14px/1.5 ${sans};color:#6b786f;text-align:center;">
|
|
186
|
+
${parts.lasts}
|
|
187
|
+
</td>
|
|
188
|
+
</tr>
|
|
189
|
+
<tr>
|
|
190
|
+
<td class="rule" style="border-top:1px solid #dce2de;font-size:0;line-height:0;"> </td>
|
|
191
|
+
</tr>
|
|
192
|
+
<tr>
|
|
193
|
+
<td
|
|
194
|
+
class="muted"
|
|
195
|
+
align="center"
|
|
196
|
+
style="padding:18px 0 0;font:13px/1.6 ${sans};color:#6b786f;text-align:center;">
|
|
197
|
+
${parts.ignore}
|
|
198
|
+
</td>
|
|
199
|
+
</tr>
|
|
200
|
+
</table>
|
|
201
|
+
</td>
|
|
202
|
+
</tr>
|
|
203
|
+
</table>
|
|
204
|
+
</body>
|
|
205
|
+
</html>
|
|
206
|
+
`.markup;
|
|
119
207
|
}
|
|
120
208
|
/**
|
|
121
209
|
* The mailbox an address names. Lowercased throughout: the part before the @ may be case
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Markup that is safe to put in a page as it is: built by `html`, or let through by
|
|
3
|
+
* `raw()`. Everything else that goes into a page is text, and is escaped.
|
|
4
|
+
*/
|
|
5
|
+
export declare class Html {
|
|
6
|
+
readonly markup: string;
|
|
7
|
+
constructor(markup: string);
|
|
8
|
+
toString(): string;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* What can go inside `html`. Text and numbers are escaped. `Html` goes in as it is, and a
|
|
12
|
+
* list goes in as each of its items in turn. Nothing, false and null leave nothing, so a
|
|
13
|
+
* part that is only there sometimes can be written as `${shown && html`...`}`.
|
|
14
|
+
*/
|
|
15
|
+
export type Content = Html | string | number | false | null | undefined | readonly Content[];
|
|
16
|
+
/**
|
|
17
|
+
* Markup, or nothing: what a parameter takes that must not be given text. An empty string
|
|
18
|
+
* is allowed, since it holds nothing that could be read as markup.
|
|
19
|
+
*/
|
|
20
|
+
export type OptionalHtml = Html | '' | false | null | undefined;
|
|
21
|
+
/**
|
|
22
|
+
* Builds markup from a template, escaping every value put into it that is not markup
|
|
23
|
+
* already. This covers element text and quoted attributes. It does not make a URL safe to
|
|
24
|
+
* follow: pass an address through `safeUrl()` before it goes into `href`.
|
|
25
|
+
*
|
|
26
|
+
* The template can be written indented across lines: see `unindent` for how its line
|
|
27
|
+
* breaks are taken out. Values are never changed.
|
|
28
|
+
*/
|
|
29
|
+
export declare function html(template: TemplateStringsArray, ...values: Content[]): Html;
|
|
30
|
+
/**
|
|
31
|
+
* Markup let into a page unescaped. Only for markup this code wrote itself, such as the
|
|
32
|
+
* logo, and never for anything a request or a record supplied.
|
|
33
|
+
*/
|
|
34
|
+
export declare const raw: (markup: string) => Html;
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { escape } from './escape.js';
|
|
2
|
+
/**
|
|
3
|
+
* Markup that is safe to put in a page as it is: built by `html`, or let through by
|
|
4
|
+
* `raw()`. Everything else that goes into a page is text, and is escaped.
|
|
5
|
+
*/
|
|
6
|
+
export class Html {
|
|
7
|
+
markup;
|
|
8
|
+
constructor(markup) {
|
|
9
|
+
this.markup = markup;
|
|
10
|
+
}
|
|
11
|
+
toString() {
|
|
12
|
+
return this.markup;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
const write = (content) => content instanceof Html
|
|
16
|
+
? content.markup
|
|
17
|
+
: Array.isArray(content)
|
|
18
|
+
? content.map(write).join('')
|
|
19
|
+
: content === undefined || content === null || content === false
|
|
20
|
+
? ''
|
|
21
|
+
: escape(content);
|
|
22
|
+
/**
|
|
23
|
+
* One piece of a template's own text, without the line breaks and indentation it was
|
|
24
|
+
* written with. Whitespace that holds a line break is dropped where it touches a tag or
|
|
25
|
+
* either end of the template, or lies between two values. Anywhere else, between words or
|
|
26
|
+
* between a word and a value, it becomes one space.
|
|
27
|
+
*
|
|
28
|
+
* `first` and `last` say whether the piece starts or ends the template; otherwise a value
|
|
29
|
+
* comes before or after it.
|
|
30
|
+
*/
|
|
31
|
+
function unindent(text, first, last) {
|
|
32
|
+
return text.replace(/\s*\n\s*/g, (run, at) => {
|
|
33
|
+
const before = at === 0 ? (first ? '' : 'value') : text[at - 1];
|
|
34
|
+
const after = at + run.length === text.length ? (last ? '' : 'value') : text[at + run.length];
|
|
35
|
+
return before === '>' || after === '<' || !before || !after
|
|
36
|
+
? ''
|
|
37
|
+
: before === 'value' && after === 'value'
|
|
38
|
+
? ''
|
|
39
|
+
: ' ';
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
/** Each template's text, unindented once. The same template is the same array every call. */
|
|
43
|
+
const unindented = new WeakMap();
|
|
44
|
+
/**
|
|
45
|
+
* Builds markup from a template, escaping every value put into it that is not markup
|
|
46
|
+
* already. This covers element text and quoted attributes. It does not make a URL safe to
|
|
47
|
+
* follow: pass an address through `safeUrl()` before it goes into `href`.
|
|
48
|
+
*
|
|
49
|
+
* The template can be written indented across lines: see `unindent` for how its line
|
|
50
|
+
* breaks are taken out. Values are never changed.
|
|
51
|
+
*/
|
|
52
|
+
export function html(template, ...values) {
|
|
53
|
+
let strings = unindented.get(template);
|
|
54
|
+
if (!strings) {
|
|
55
|
+
strings = template.map((text, i) => unindent(text, i === 0, i === template.length - 1));
|
|
56
|
+
unindented.set(template, strings);
|
|
57
|
+
}
|
|
58
|
+
let markup = strings[0];
|
|
59
|
+
for (const [index, value] of values.entries())
|
|
60
|
+
markup += write(value) + strings[index + 1];
|
|
61
|
+
return new Html(markup);
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Markup let into a page unescaped. Only for markup this code wrote itself, such as the
|
|
65
|
+
* logo, and never for anything a request or a record supplied.
|
|
66
|
+
*/
|
|
67
|
+
export const raw = (markup) => new Html(markup);
|