diff --git a/package.json b/package.json index f525bf4..72965e5 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ogp-fetcher", - "version": "0.0.1", + "version": "1.0.0", "description": "Library to fetch OGB", "main": "dist/index.js", "types": "dist/index.d.ts", diff --git a/src/fetchOgp.ts b/src/fetchOgp.ts index da2f85f..b16df98 100644 --- a/src/fetchOgp.ts +++ b/src/fetchOgp.ts @@ -1,6 +1,11 @@ import axios, { AxiosRequestHeaders } from "axios"; import { JSDOM } from "jsdom"; +/** + * + * @param targetUrls + * @returns ogp list + */ export const fetchOgp = async (targetUrls: string[]) => { const headers: AxiosRequestHeaders = { "User-Agent": "bot" }; @@ -9,24 +14,40 @@ export const fetchOgp = async (targetUrls: string[]) => { }); const responses = await Promise.all(fetches); + const htmlList = responses.reduce((prev: string[], res) => { + if (typeof res.data !== "string") return prev; + return [...prev, res.data]; + }, []); - const ogpsList = responses.reduce( - (prev: { [key: string]: string }[], res) => { - if (typeof res.data !== "string") return prev; - const dom = new JSDOM(res.data); - const meta = dom.window.document.head.querySelectorAll("meta"); + const ogps = parseOgp(htmlList); - const ogps = ogpFilter(meta); + return ogps; +}; - return [...prev, ogps]; - }, - [] - ); +/** + * + * @param htmlList + * @returns ogp list + */ +export const parseOgp = (htmlList: string[]) => { + const ogps = htmlList.reduce((prev: { [key: string]: string }[], html) => { + const dom = new JSDOM(html); + const meta = dom.window.document.head.querySelectorAll("meta"); - return ogpsList; + const ogps = ogpFilter(meta); + + return [...prev, ogps]; + }, []); + + return ogps; }; -const ogpFilter = (metaElements: NodeListOf) => { +/** + * + * @param metaElements + * @returns ogp object + */ +export const ogpFilter = (metaElements: NodeListOf) => { const ogps = [...Array(metaElements.length).keys()].reduce( (prev: { [key: string]: string }, i) => { const property = metaElements.item(i).getAttribute("property")?.trim(); @@ -39,3 +60,5 @@ const ogpFilter = (metaElements: NodeListOf) => { ); return ogps; }; + +export default fetchOgp; diff --git a/src/index.ts b/src/index.ts index 304f157..44b8165 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,3 +1 @@ -import { fetchOgp } from "./fetchOgp"; - -export default fetchOgp; +export * from "./fetchOgp"; diff --git a/test/index.test.ts b/test/index.test.ts index 9715907..778b302 100644 --- a/test/index.test.ts +++ b/test/index.test.ts @@ -1,9 +1,10 @@ -import fetchOGP from "../src/index"; +import { JSDOM } from "jsdom"; +import fetchOgp, { ogpFilter, parseOgp } from "../src/fetchOgp"; describe("test", () => { test("fetch ogp", () => { return expect( - fetchOGP(["https://takahirohimi.github.io/ogp-fetcher/"]) + fetchOgp(["https://takahirohimi.github.io/ogp-fetcher/"]) ).resolves.toStrictEqual([ { ["og:title"]: "title", @@ -20,7 +21,7 @@ describe("test", () => { test("fetch multiple ogp", () => { return expect( - fetchOGP([ + fetchOgp([ "https://takahirohimi.github.io/ogp-fetcher/", "https://takahirohimi.github.io/ogp-fetcher/foo.html", ]) @@ -47,4 +48,102 @@ describe("test", () => { }, ]); }); + + test("parse ogp", () => { + return expect(parseOgp([testHtmlTextIndex])).toStrictEqual([ + { + ["og:title"]: "title", + ["og:description"]: "description", + ["og:locale"]: "locale", + ["og:type"]: "type", + ["og:url"]: "https://example.com", + ["og:image:width"]: "200", + ["og:image:height"]: "100", + ["og:image"]: "https://example.com/image.png", + }, + ]); + }); + + test("parse multiple ogp", () => { + return expect(parseOgp([testHtmlTextIndex, testHtmlTextFoo])).toStrictEqual( + [ + { + ["og:title"]: "title", + ["og:description"]: "description", + ["og:locale"]: "locale", + ["og:type"]: "type", + ["og:url"]: "https://example.com", + ["og:image:width"]: "200", + ["og:image:height"]: "100", + ["og:image"]: "https://example.com/image.png", + }, + { + ["og:title"]: "footitle", + ["og:description"]: "foodescription", + ["og:locale"]: "foolocale", + ["og:type"]: "footype", + ["og:url"]: "https://example.com/foo", + ["og:image:width"]: "300", + ["og:image:height"]: "200", + ["og:image"]: "https://example.com/foo.png", + }, + ] + ); + }); + + test("ogp filter", () => { + const dom = new JSDOM(testHtmlTextIndex); + const meta = dom.window.document.head.querySelectorAll("meta"); + + return expect(ogpFilter(meta)).toStrictEqual({ + ["og:title"]: "title", + ["og:description"]: "description", + ["og:locale"]: "locale", + ["og:type"]: "type", + ["og:url"]: "https://example.com", + ["og:image:width"]: "200", + ["og:image:height"]: "100", + ["og:image"]: "https://example.com/image.png", + }); + }); }); + +const testHtmlTextIndex = ` + + + + + + + + + + + + Hello World + + +

Hello World

+ + +`; + +const testHtmlTextFoo = ` + + + + + + + + + + + + foo + + +

foo

+ + +`;