@rathnasgala/theme 2.0.4 → 2.0.6
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
CHANGED
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rathnasgala/theme",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.6",
|
|
4
4
|
"description": "Managed Gala static-site theme payload",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
8
8
|
"url": "git+https://github.com/rathnasgala/site-template.git"
|
|
9
9
|
},
|
|
10
|
+
"gala": {
|
|
11
|
+
"sourceCommit": "d7df1af8ecdfa3d92981e6cde8981e7d4734225f"
|
|
12
|
+
},
|
|
10
13
|
"files": [
|
|
11
14
|
"payload"
|
|
12
15
|
],
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"schemaVersion": 1,
|
|
3
3
|
"themePackage": {
|
|
4
4
|
"name": "@rathnasgala/theme",
|
|
5
|
-
"version": "2.0.
|
|
5
|
+
"version": "2.0.6",
|
|
6
6
|
"availableDesignThemes": [
|
|
7
7
|
"editorial",
|
|
8
8
|
"modern",
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"lib/render-markdown.js": "275b7da721aef1f68cda515673153471c0d597061e8fdf867c5f2b32c98b91db",
|
|
29
29
|
"lib/seo.js": "19cf1d67d5b711b8d3a533f207f267e770ee46fd4a4e6561c5f7fd4e9c1989ff",
|
|
30
30
|
"lib/share-targets.js": "458aff86fab2b62a364442cd8c612565c6e0b53eef2f20cb6237cc562b1e0731",
|
|
31
|
-
"lib/site-config.js": "
|
|
31
|
+
"lib/site-config.js": "55eccfc4eab65a58fdcb06aa53f578b7b423cc186b93cad18c30705aec219d34",
|
|
32
32
|
"package-lock.json": "dc11470b1ad897c58d91745f23ff25711c593e62972ec9fb83f4e10fd77e1ecd",
|
|
33
33
|
"package.json": "1b3b70f6e94391d309625cb8cef503ee92ecd282bec587643b535ae7a14c24c0",
|
|
34
34
|
"scripts/build-reader.js": "743194c8dc9cfb9b6631db1732b5f36a92e3a4f905a2965c71d56e1ef50c2e45",
|
|
@@ -27,6 +27,29 @@ const CONTACT_KEYS = Object.freeze([
|
|
|
27
27
|
const PROFILE_KEYS = Object.freeze(['displayName', 'bio', 'avatarUrl', 'profileUrl']);
|
|
28
28
|
const PUBLISHER_KEYS = Object.freeze(['name', 'url', 'logoUrl']);
|
|
29
29
|
|
|
30
|
+
export function validateCanonicalUrlTemplate(value) {
|
|
31
|
+
if (value == null || value === '' || value === 'unavailable') return '';
|
|
32
|
+
if (typeof value !== 'string' || [...value.trim()].length > 2048) {
|
|
33
|
+
throw new TypeError('seo.canonicalUrlTemplate must be a string of at most 2048 characters');
|
|
34
|
+
}
|
|
35
|
+
const template = value.trim();
|
|
36
|
+
const count = (token) => template.split(token).length - 1;
|
|
37
|
+
if (count('{language}') !== 1 || count('{slug}') !== 1
|
|
38
|
+
|| /[{}]/.test(template.replace('{language}', '').replace('{slug}', ''))) {
|
|
39
|
+
throw new TypeError('seo.canonicalUrlTemplate must contain {language} and {slug} exactly once');
|
|
40
|
+
}
|
|
41
|
+
let resolved;
|
|
42
|
+
try {
|
|
43
|
+
resolved = new URL(template.replace('{language}', 'en').replace('{slug}', 'example-post'));
|
|
44
|
+
} catch {
|
|
45
|
+
throw new TypeError('seo.canonicalUrlTemplate must resolve to an absolute URL');
|
|
46
|
+
}
|
|
47
|
+
if (resolved.protocol !== 'https:' || resolved.username || resolved.password || resolved.hash) {
|
|
48
|
+
throw new TypeError('seo.canonicalUrlTemplate must use HTTPS without credentials or a fragment');
|
|
49
|
+
}
|
|
50
|
+
return template;
|
|
51
|
+
}
|
|
52
|
+
|
|
30
53
|
/*
|
|
31
54
|
* `layout` and `palette` have always been required. The rest were added later and are optional:
|
|
32
55
|
* a publication written before they existed is still a valid publication, and the theme falls
|
|
@@ -182,6 +205,7 @@ export async function loadSiteConfiguration({
|
|
|
182
205
|
validatePerformanceBudgets(config?.performance?.budgets);
|
|
183
206
|
config.statistics = validateStatistics(config.statistics);
|
|
184
207
|
config.contact = validateContact(config.contact);
|
|
208
|
+
config.seo = { canonicalUrlTemplate: validateCanonicalUrlTemplate(config.seo?.canonicalUrlTemplate) };
|
|
185
209
|
const profile = validateProfile(config.site);
|
|
186
210
|
config.site = {
|
|
187
211
|
...(config.site ?? {}),
|