@mannisto/astro-metadata 1.0.1 → 1.0.2
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,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mannisto/astro-metadata",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"description": "Astro components for managing your page head — metadata, social sharing, favicons, and SEO.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"homepage": "https://github.com/eremannisto/astro-metadata#readme",
|
|
8
8
|
"repository": {
|
|
9
9
|
"type": "git",
|
|
10
|
-
"url": "https://github.com/eremannisto/astro-metadata"
|
|
10
|
+
"url": "git+https://github.com/eremannisto/astro-metadata.git"
|
|
11
11
|
},
|
|
12
12
|
"bugs": {
|
|
13
13
|
"url": "https://github.com/eremannisto/astro-metadata/issues"
|
|
@@ -23,15 +23,24 @@
|
|
|
23
23
|
"src",
|
|
24
24
|
"index.ts"
|
|
25
25
|
],
|
|
26
|
+
"scripts": {
|
|
27
|
+
"lint": "eslint . --fix",
|
|
28
|
+
"format": "prettier --write .",
|
|
29
|
+
"check": "eslint . && prettier --check .",
|
|
30
|
+
"test": "pnpm run test:unit && pnpm run test:e2e",
|
|
31
|
+
"test:unit": "vitest run",
|
|
32
|
+
"test:e2e": "pnpm test:fixtures && playwright test",
|
|
33
|
+
"test:fixtures": "pnpm --filter \"./tests/e2e/fixtures/**\" exec astro build"
|
|
34
|
+
},
|
|
26
35
|
"peerDependencies": {
|
|
27
|
-
"astro": "^4.3.0 || ^5.0.0 || ^6.0.0"
|
|
36
|
+
"astro": "^4.3.0 || ^5.0.0 || ^6.0.0 || ^7.0.0"
|
|
28
37
|
},
|
|
29
38
|
"devDependencies": {
|
|
30
39
|
"@eslint/js": "^10.0.1",
|
|
31
40
|
"@ianvs/prettier-plugin-sort-imports": "^4.7.1",
|
|
32
41
|
"@playwright/test": "^1.58.2",
|
|
33
42
|
"@types/node": "^22.19.15",
|
|
34
|
-
"astro": "^
|
|
43
|
+
"astro": "^6.4.8",
|
|
35
44
|
"eslint": "^10.0.3",
|
|
36
45
|
"eslint-config-prettier": "^10.1.8",
|
|
37
46
|
"prettier": "^3.8.1",
|
|
@@ -40,12 +49,5 @@
|
|
|
40
49
|
"typescript-eslint": "^8.57.0",
|
|
41
50
|
"vitest": "^4.1.0"
|
|
42
51
|
},
|
|
43
|
-
"
|
|
44
|
-
|
|
45
|
-
"format": "prettier --write .",
|
|
46
|
-
"check": "eslint . && prettier --check .",
|
|
47
|
-
"test": "pnpm run test:unit && pnpm run test:e2e",
|
|
48
|
-
"test:unit": "vitest run",
|
|
49
|
-
"test:e2e": "playwright test"
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
+
"packageManager": "pnpm@10.32.1"
|
|
53
|
+
}
|
|
@@ -14,6 +14,19 @@ export type Props = {
|
|
|
14
14
|
|
|
15
15
|
const { icons, manifest, sort = true } = Astro.props
|
|
16
16
|
|
|
17
|
+
/**
|
|
18
|
+
* Returns the file extension of a favicon path in lowercase, without the
|
|
19
|
+
* query string or the hash. For example, "/icon.SVG?v=2" gives "svg".
|
|
20
|
+
*
|
|
21
|
+
* @param path - The path to the favicon file.
|
|
22
|
+
* @returns The file extension, or an empty string if the path has none.
|
|
23
|
+
*/
|
|
24
|
+
function getExtension(path: string): string {
|
|
25
|
+
const file = path.split(/[?#]/)[0].toLowerCase()
|
|
26
|
+
const dot = file.lastIndexOf(".")
|
|
27
|
+
return dot === -1 ? "" : file.slice(dot + 1)
|
|
28
|
+
}
|
|
29
|
+
|
|
17
30
|
/**
|
|
18
31
|
* Detects the MIME type of a favicon file from its extension.
|
|
19
32
|
*
|
|
@@ -21,11 +34,11 @@ const { icons, manifest, sort = true } = Astro.props
|
|
|
21
34
|
* @returns The MIME type of the file.
|
|
22
35
|
*/
|
|
23
36
|
function getMimeType(path: string): string {
|
|
24
|
-
|
|
25
|
-
if (
|
|
26
|
-
if (
|
|
27
|
-
if (
|
|
28
|
-
if (
|
|
37
|
+
const extension = getExtension(path)
|
|
38
|
+
if (extension === "svg") return "image/svg+xml"
|
|
39
|
+
if (extension === "png") return "image/png"
|
|
40
|
+
if (extension === "webp") return "image/webp"
|
|
41
|
+
if (extension === "jpg" || extension === "jpeg") return "image/jpeg"
|
|
29
42
|
return "image/x-icon"
|
|
30
43
|
}
|
|
31
44
|
|
|
@@ -50,15 +63,10 @@ function getMedia(theme?: "light" | "dark"): string | undefined {
|
|
|
50
63
|
function getSortOrder(file: FaviconFile): number {
|
|
51
64
|
if (file.apple) return 4
|
|
52
65
|
if (file.theme) return 5
|
|
53
|
-
|
|
54
|
-
if (
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
file.path.endsWith(".jpg") ||
|
|
58
|
-
file.path.endsWith(".jpeg")
|
|
59
|
-
)
|
|
60
|
-
return 1
|
|
61
|
-
if (file.path.endsWith(".svg")) return 2
|
|
66
|
+
const extension = getExtension(file.path)
|
|
67
|
+
if (extension === "ico") return 0
|
|
68
|
+
if (["png", "webp", "jpg", "jpeg"].includes(extension)) return 1
|
|
69
|
+
if (extension === "svg") return 2
|
|
62
70
|
return 3
|
|
63
71
|
}
|
|
64
72
|
|
|
@@ -68,16 +68,14 @@ const tw =
|
|
|
68
68
|
title,
|
|
69
69
|
description: enabled(description) ? description : undefined,
|
|
70
70
|
image: enabled(image) ? image : undefined,
|
|
71
|
-
url: enabled(canonical) ? canonical : undefined,
|
|
72
71
|
...twitter,
|
|
73
72
|
}
|
|
74
73
|
: false
|
|
75
74
|
---
|
|
76
75
|
|
|
77
76
|
<head>
|
|
78
|
-
<slot name="top" />
|
|
79
|
-
|
|
80
77
|
<meta charset={charset} />
|
|
78
|
+
<slot name="top" />
|
|
81
79
|
<meta name="viewport" content={viewport} />
|
|
82
80
|
|
|
83
81
|
<Title value={title} template={titleTemplate} />
|
|
@@ -4,6 +4,15 @@ export type Props = {
|
|
|
4
4
|
}
|
|
5
5
|
|
|
6
6
|
const { schema } = Astro.props
|
|
7
|
+
|
|
8
|
+
// Escape the characters that can end the script tag or break the JavaScript parser.
|
|
9
|
+
// A value such as "</script>" in the schema then stays inside the JSON.
|
|
10
|
+
const json = JSON.stringify(schema)
|
|
11
|
+
.replace(/</g, "\\u003c")
|
|
12
|
+
.replace(/>/g, "\\u003e")
|
|
13
|
+
.replace(/&/g, "\\u0026")
|
|
14
|
+
.replace(/\u2028/g, "\\u2028")
|
|
15
|
+
.replace(/\u2029/g, "\\u2029")
|
|
7
16
|
---
|
|
8
17
|
|
|
9
|
-
<script is:inline type="application/ld+json" set:html={
|
|
18
|
+
<script is:inline type="application/ld+json" set:html={json} />
|
|
@@ -5,6 +5,9 @@ export type Props = {
|
|
|
5
5
|
}
|
|
6
6
|
|
|
7
7
|
const { value, template = "%s" } = Astro.props
|
|
8
|
+
|
|
9
|
+
// A replacer function keeps "$&" and other "$" patterns in the title as text
|
|
10
|
+
const title = template.replace("%s", () => value)
|
|
8
11
|
---
|
|
9
12
|
|
|
10
|
-
<title>{
|
|
13
|
+
<title>{title}</title>
|
|
@@ -2,6 +2,9 @@
|
|
|
2
2
|
export type Props = {
|
|
3
3
|
title?: string
|
|
4
4
|
description?: string
|
|
5
|
+
/**
|
|
6
|
+
* @deprecated X does not read `twitter:url`. The component ignores this value.
|
|
7
|
+
*/
|
|
5
8
|
url?: string
|
|
6
9
|
card?: "summary" | "summary_large_image" | "player" | "app"
|
|
7
10
|
site?: string
|
|
@@ -12,13 +15,12 @@ export type Props = {
|
|
|
12
15
|
}
|
|
13
16
|
}
|
|
14
17
|
|
|
15
|
-
const { title, description,
|
|
18
|
+
const { title, description, card = "summary_large_image", site, creator, image } = Astro.props
|
|
16
19
|
---
|
|
17
20
|
|
|
18
21
|
{card && <meta name="twitter:card" content={card} />}
|
|
19
22
|
{title && <meta name="twitter:title" content={title} />}
|
|
20
23
|
{description && <meta name="twitter:description" content={description} />}
|
|
21
|
-
{url && <meta name="twitter:url" content={url} />}
|
|
22
24
|
{image?.url && <meta name="twitter:image" content={image.url} />}
|
|
23
25
|
{image?.alt && <meta name="twitter:image:alt" content={image.alt} />}
|
|
24
26
|
{site && <meta name="twitter:site" content={site} />}
|