rehype-og-card 1.0.1 → 1.0.3

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/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import type { Plugin } from "unified";
2
- import { RehypeOGCardOptions } from "./types.js";
2
+ import type { RehypeOGCardOptions } from "./types.js";
3
3
  import type { Root } from "hast";
4
4
  /**
5
5
  * Rehype plugin to create OG card from bare links.
@@ -8,4 +8,4 @@ import type { Root } from "hast";
8
8
  */
9
9
  declare const rehypeOGCard: Plugin<[RehypeOGCardOptions | undefined], Root>;
10
10
  export default rehypeOGCard;
11
- export { RehypeOGCardOptions };
11
+ export type { RehypeOGCardOptions };
package/dist/index.js CHANGED
@@ -1,12 +1,3 @@
1
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
- return new (P || (P = Promise))(function (resolve, reject) {
4
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
- step((generator = generator.apply(thisArg, _arguments || [])).next());
8
- });
9
- };
10
1
  import { convertTextToAnchorElement, createOGCard, isAnchorElement, isTextNode } from "./util/hast.js";
11
2
  import { checkFileExistsSync, createDirectorySync } from "./util/file.js";
12
3
  import { downloadImage, getOGData, isValidURL } from "./util/network.js";
@@ -36,7 +27,10 @@ const DEFAULT_OPTIONS = {
36
27
  */
37
28
  // eslint-disable-next-line max-lines-per-function, max-statements
38
29
  const rehypeOGCard = (options) => {
39
- const mergedOptions = Object.assign(Object.assign({}, DEFAULT_OPTIONS), options);
30
+ const mergedOptions = {
31
+ ...DEFAULT_OPTIONS,
32
+ ...options
33
+ };
40
34
  if (mergedOptions.buildCache && !mergedOptions.serverCache) {
41
35
  throw new Error("[rehype-og-card] `buildCache` option requires `serverCache` option to be enabled.");
42
36
  }
@@ -56,11 +50,10 @@ const rehypeOGCard = (options) => {
56
50
  * @param tree Root node of the HAST tree.
57
51
  */
58
52
  // eslint-disable-next-line max-lines-per-function
59
- const transform = (tree) => __awaiter(void 0, void 0, void 0, function* () {
53
+ const transform = async (tree) => {
60
54
  const linkCardPromises = [];
61
55
  // eslint-disable-next-line max-statements, max-lines-per-function
62
56
  visitParents(tree, ["element", "text"], (node, ancestors) => {
63
- var _a;
64
57
  let anchorNode = null;
65
58
  const isBareLink = node.type === "text" && isValidURL(node.value.trim());
66
59
  const isValidAnchor = isAnchorElement(node) && isValidURL(node.properties.href);
@@ -91,15 +84,15 @@ const rehypeOGCard = (options) => {
91
84
  if (!isTheOnlyChild)
92
85
  return;
93
86
  const targetURL = new URL(anchorNode.properties.href);
94
- if ((_a = mergedOptions.excludeDomains) === null || _a === void 0 ? void 0 : _a.includes(targetURL.hostname))
87
+ if (mergedOptions.excludeDomains.includes(targetURL.hostname))
95
88
  return;
96
89
  // eslint-disable-next-line jsdoc/require-jsdoc, max-statements, max-lines-per-function
97
- const linkCardPromise = () => __awaiter(void 0, void 0, void 0, function* () {
90
+ const linkCardPromise = async () => {
98
91
  let OGData = mergedOptions.buildCache
99
- ? yield restoreOGDataBuildCache(anchorNode.properties.href, mergedOptions.buildCachePath)
92
+ ? await restoreOGDataBuildCache(anchorNode.properties.href, mergedOptions.buildCachePath)
100
93
  : null;
101
94
  if (!OGData) {
102
- OGData = yield getOGData(anchorNode.properties.href, mergedOptions.crawlerUserAgent);
95
+ OGData = await getOGData(anchorNode.properties.href, mergedOptions.crawlerUserAgent);
103
96
  if (!OGData)
104
97
  return;
105
98
  if (mergedOptions.buildCache) {
@@ -107,12 +100,12 @@ const rehypeOGCard = (options) => {
107
100
  }
108
101
  }
109
102
  if (OGData.OGImageURL && mergedOptions.serverCache) {
110
- const filename = yield downloadImage({
103
+ const filename = await downloadImage({
111
104
  directory: mergedOptions.serverCachePath,
112
105
  url: OGData.OGImageURL,
113
106
  userAgent: mergedOptions.crawlerUserAgent
114
107
  });
115
- if (filename && mergedOptions.serverCache) {
108
+ if (filename) {
116
109
  OGData.OGImageURL = path.posix.join("/rehype-og-card", filename);
117
110
  }
118
111
  if (filename && mergedOptions.buildCache) {
@@ -122,12 +115,12 @@ const rehypeOGCard = (options) => {
122
115
  }
123
116
  }
124
117
  if (OGData.faviconURL && mergedOptions.serverCache) {
125
- const filename = yield downloadImage({
118
+ const filename = await downloadImage({
126
119
  directory: mergedOptions.serverCachePath,
127
120
  url: OGData.faviconURL,
128
121
  userAgent: mergedOptions.crawlerUserAgent
129
122
  });
130
- if (filename && mergedOptions.serverCache) {
123
+ if (filename) {
131
124
  OGData.faviconURL = path.posix.join("/rehype-og-card", filename);
132
125
  }
133
126
  if (filename && mergedOptions.buildCache) {
@@ -148,11 +141,11 @@ const rehypeOGCard = (options) => {
148
141
  return;
149
142
  // eslint-disable-next-line no-magic-numbers
150
143
  ancestors[ancestors.length - 1].children.splice(index, 1, OGCard);
151
- });
144
+ };
152
145
  linkCardPromises.push(linkCardPromise());
153
146
  });
154
- yield Promise.all(linkCardPromises);
155
- });
147
+ await Promise.all(linkCardPromises);
148
+ };
156
149
  return transform;
157
150
  };
158
151
  export default rehypeOGCard;
package/dist/types.d.ts CHANGED
@@ -70,4 +70,4 @@ interface OGCardData {
70
70
  OGImageWidth?: number;
71
71
  OGImageHeight?: number;
72
72
  }
73
- export { RehypeOGCardOptions, OGCardData };
73
+ export type { RehypeOGCardOptions, OGCardData };
@@ -1,4 +1,4 @@
1
- import { OGCardData } from "../types.js";
1
+ import type { OGCardData } from "../types.js";
2
2
  /**
3
3
  * Save build cache if server cache exists.
4
4
  * @param serverCachePath Server cache path.
@@ -1,12 +1,3 @@
1
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
- return new (P || (P = Promise))(function (resolve, reject) {
4
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
- step((generator = generator.apply(thisArg, _arguments || [])).next());
8
- });
9
- };
10
1
  import { checkFileExists, copyDirectory, generateFilename } from "./file.js";
11
2
  import fs from "fs/promises";
12
3
  import path from "path";
@@ -15,13 +6,13 @@ import path from "path";
15
6
  * @param serverCachePath Server cache path.
16
7
  * @param buildCachePath Build cache path.
17
8
  */
18
- const saveBuildCacheFile = (serverCachePath, buildCachePath) => __awaiter(void 0, void 0, void 0, function* () {
19
- const serverCacheExists = yield checkFileExists(serverCachePath);
20
- const buildCacheExists = yield checkFileExists(buildCachePath);
9
+ const saveBuildCacheFile = async (serverCachePath, buildCachePath) => {
10
+ const serverCacheExists = await checkFileExists(serverCachePath);
11
+ const buildCacheExists = await checkFileExists(buildCachePath);
21
12
  if (serverCacheExists && !buildCacheExists) {
22
- yield fs.copyFile(serverCachePath, buildCachePath);
13
+ await fs.copyFile(serverCachePath, buildCachePath);
23
14
  }
24
- });
15
+ };
25
16
  /**
26
17
  * Restore build cache if it exists.
27
18
  * @param buildCachePath Build cache path.
@@ -36,30 +27,30 @@ const restoreBuildCache = (buildCachePath, serverCachePath) => {
36
27
  * @param OGData OG data to save.
37
28
  * @param buildCachePath Build cache path.
38
29
  */
39
- const saveOGDataBuildCache = (url, OGData, buildCachePath) => __awaiter(void 0, void 0, void 0, function* () {
30
+ const saveOGDataBuildCache = async (url, OGData, buildCachePath) => {
40
31
  const filename = generateFilename(url, false);
41
32
  const savePath = `${path.join(buildCachePath, filename)}.json`;
42
- const cacheDirectoryExists = yield checkFileExists(buildCachePath);
33
+ const cacheDirectoryExists = await checkFileExists(buildCachePath);
43
34
  if (!cacheDirectoryExists) {
44
- yield fs.mkdir(buildCachePath, { recursive: true });
35
+ await fs.mkdir(buildCachePath, { recursive: true });
45
36
  }
46
- yield fs.writeFile(savePath, JSON.stringify(OGData));
47
- });
37
+ await fs.writeFile(savePath, JSON.stringify(OGData));
38
+ };
48
39
  /**
49
40
  * Restore OG data from build cache.
50
41
  * @param url URL of the OG data.
51
42
  * @param buildCachePath Build cache path.
52
43
  * @returns Restored OG data. If not found, returns `null`.
53
44
  */
54
- const restoreOGDataBuildCache = (url, buildCachePath) => __awaiter(void 0, void 0, void 0, function* () {
45
+ const restoreOGDataBuildCache = async (url, buildCachePath) => {
55
46
  const filename = generateFilename(url, false);
56
47
  const savePath = `${path.join(buildCachePath, filename)}.json`;
57
48
  try {
58
- const data = yield fs.readFile(savePath, "utf-8");
49
+ const data = await fs.readFile(savePath, "utf-8");
59
50
  return JSON.parse(data);
60
51
  }
61
- catch (_a) {
52
+ catch {
62
53
  return null;
63
54
  }
64
- });
55
+ };
65
56
  export { saveBuildCacheFile, restoreBuildCache, saveOGDataBuildCache, restoreOGDataBuildCache };
package/dist/util/file.js CHANGED
@@ -1,12 +1,3 @@
1
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
- return new (P || (P = Promise))(function (resolve, reject) {
4
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
- step((generator = generator.apply(thisArg, _arguments || [])).next());
8
- });
9
- };
10
1
  import { createHash } from "crypto";
11
2
  import fs from "fs";
12
3
  import path from "path";
@@ -15,15 +6,15 @@ import path from "path";
15
6
  * @param filePath Path to check.
16
7
  * @returns `true` if the file exists, `false` otherwise.
17
8
  */
18
- const checkFileExists = (filePath) => __awaiter(void 0, void 0, void 0, function* () {
9
+ const checkFileExists = async (filePath) => {
19
10
  try {
20
- yield fs.promises.access(filePath);
11
+ await fs.promises.access(filePath);
21
12
  return true;
22
13
  }
23
- catch (_a) {
14
+ catch {
24
15
  return false;
25
16
  }
26
- });
17
+ };
27
18
  /**
28
19
  * Check if the file exists.
29
20
  * @param filePath Path to check.
@@ -1,5 +1,5 @@
1
1
  import type { Element, ElementContent, Text } from "hast";
2
- import { OGCardData, RehypeOGCardOptions } from "../types.js";
2
+ import type { OGCardData, RehypeOGCardOptions } from "../types.js";
3
3
  interface AnchorElement extends Element {
4
4
  tagName: "a";
5
5
  properties: {
@@ -35,4 +35,4 @@ declare const createOGCard: (data: OGCardData, options: Required<{
35
35
  decoding: RehypeOGCardOptions["decoding"];
36
36
  openInNewTab: RehypeOGCardOptions["openInNewTab"];
37
37
  }>) => Element;
38
- export { AnchorElement, isTextNode, isAnchorElement, convertTextToAnchorElement, createOGCard };
38
+ export { type AnchorElement, isTextNode, isAnchorElement, convertTextToAnchorElement, createOGCard };
package/dist/util/hast.js CHANGED
@@ -38,7 +38,7 @@ const createOGCard = (data, options) => {
38
38
  };
39
39
  const card = h("div.og-card-container", [
40
40
  // eslint-disable-next-line no-extra-parens
41
- h("a", Object.assign({ href: data.url }, (options.openInNewTab ? openInNewTab : {})), [
41
+ h("a", { href: data.url, ...(options.openInNewTab ? openInNewTab : {}) }, [
42
42
  h("div.og-card-info", [
43
43
  h("div.og-card-title", data.title),
44
44
  data.description ? h("div.og-card-description", data.description) : null,
@@ -57,6 +57,7 @@ const createOGCard = (data, options) => {
57
57
  data.OGImageURL
58
58
  ? h("div.og-card-image-container", [
59
59
  h("img.og-card-image", {
60
+ // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
60
61
  alt: data.OGImageAlt || data.OGImageURL,
61
62
  decoding: options.decoding,
62
63
  height: data.OGImageHeight,
@@ -1,12 +1,3 @@
1
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
- return new (P || (P = Promise))(function (resolve, reject) {
4
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
- step((generator = generator.apply(thisArg, _arguments || [])).next());
8
- });
9
- };
10
1
  import { checkFileExists, generateFilename } from "./file.js";
11
2
  import fetch from "node-fetch";
12
3
  import fs from "fs/promises";
@@ -27,7 +18,7 @@ const isValidURL = (url) => {
27
18
  new URL(url);
28
19
  return true;
29
20
  }
30
- catch (_a) {
21
+ catch {
31
22
  return false;
32
23
  }
33
24
  };
@@ -37,9 +28,9 @@ const isValidURL = (url) => {
37
28
  * @param userAgent User agent to use for fetching.
38
29
  * @returns OG card data.
39
30
  */
40
- const getOGData = (url, userAgent) => __awaiter(void 0, void 0, void 0, function* () {
31
+ const getOGData = async (url, userAgent) => {
41
32
  try {
42
- const { result } = yield scraper({
33
+ const { result } = await scraper({
43
34
  fetchOptions: {
44
35
  headers: {
45
36
  "user-agent": userAgent
@@ -53,13 +44,14 @@ const getOGData = (url, userAgent) => __awaiter(void 0, void 0, void 0, function
53
44
  : // eslint-disable-next-line no-undefined
54
45
  undefined;
55
46
  return {
56
- OGImageAlt: OGImage === null || OGImage === void 0 ? void 0 : OGImage.alt,
57
- OGImageHeight: OGImage === null || OGImage === void 0 ? void 0 : OGImage.height,
58
- OGImageURL: OGImage === null || OGImage === void 0 ? void 0 : OGImage.url,
59
- OGImageWidth: OGImage === null || OGImage === void 0 ? void 0 : OGImage.width,
47
+ OGImageAlt: OGImage?.alt,
48
+ OGImageHeight: OGImage?.height,
49
+ OGImageURL: OGImage?.url,
50
+ OGImageWidth: OGImage?.width,
60
51
  description: result.ogDescription,
61
52
  displayURL: url,
62
53
  faviconURL,
54
+ // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
63
55
  title: result.ogTitle || url,
64
56
  url
65
57
  };
@@ -69,14 +61,14 @@ const getOGData = (url, userAgent) => __awaiter(void 0, void 0, void 0, function
69
61
  console.error("[rehype-og-card] Error fetching OG data:", error);
70
62
  return null;
71
63
  }
72
- });
64
+ };
73
65
  /**
74
66
  * Download image from given URL. If the image already exists, return the filename.
75
67
  * @param options Options to download image.
76
68
  * @returns Filename of the downloaded image.
77
69
  */
78
70
  // eslint-disable-next-line max-statements
79
- const downloadImage = (options) => __awaiter(void 0, void 0, void 0, function* () {
71
+ const downloadImage = async (options) => {
80
72
  if (!isValidURL(options.url)) {
81
73
  // eslint-disable-next-line no-console
82
74
  console.error("[rehype-og-card] Invalid thumbnail URL:", options.url);
@@ -86,23 +78,23 @@ const downloadImage = (options) => __awaiter(void 0, void 0, void 0, function* (
86
78
  const filename = generateFilename(options.url);
87
79
  const savePath = path.posix.join(options.directory, filename);
88
80
  // If the file already exists, return the filename.
89
- const fileExists = yield checkFileExists(savePath);
81
+ const fileExists = await checkFileExists(savePath);
90
82
  if (fileExists)
91
83
  return filename;
92
- const response = yield fetch(options.url, {
84
+ const response = await fetch(options.url, {
93
85
  headers: {
94
86
  "user-agent": options.userAgent
95
87
  },
96
88
  // eslint-disable-next-line no-magic-numbers
97
89
  signal: AbortSignal.timeout(10 * 1000)
98
90
  });
99
- const arrayBuffer = yield response.arrayBuffer();
91
+ const arrayBuffer = await response.arrayBuffer();
100
92
  const buffer = Buffer.from(arrayBuffer);
101
- const saveDirectoryExists = yield checkFileExists(options.directory);
93
+ const saveDirectoryExists = await checkFileExists(options.directory);
102
94
  if (!saveDirectoryExists) {
103
- yield fs.mkdir(options.directory, { recursive: true });
95
+ await fs.mkdir(options.directory, { recursive: true });
104
96
  }
105
- yield fs.writeFile(savePath, buffer);
97
+ await fs.writeFile(savePath, buffer);
106
98
  return filename;
107
99
  }
108
100
  catch (error) {
@@ -110,5 +102,5 @@ const downloadImage = (options) => __awaiter(void 0, void 0, void 0, function* (
110
102
  console.error("[rehype-og-card] Error downloading image:", error);
111
103
  return null;
112
104
  }
113
- });
105
+ };
114
106
  export { isValidURL, getOGData, downloadImage };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rehype-og-card",
3
- "version": "1.0.1",
3
+ "version": "1.0.3",
4
4
  "description": "Rehype plugin to convert text links to link cards",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -42,7 +42,8 @@
42
42
  "devDependencies": {
43
43
  "@changesets/changelog-github": "^0.5.0",
44
44
  "@changesets/cli": "^2.27.7",
45
- "@robot-inventor/eslint-config": "^0.2.21",
45
+ "@robot-inventor/eslint-config": "^4.0.0",
46
+ "@robot-inventor/tsconfig-base": "^1.1.0",
46
47
  "@types/node": "^20.14.11",
47
48
  "@types/sanitize-html": "^2.11.0",
48
49
  "eslint": "^9.7.0",