Skip to content

Commit

Permalink
Release v0.4.0 (#79)
Browse files Browse the repository at this point in the history
  • Loading branch information
5ouma committed Jun 14, 2024
2 parents f48e632 + 10e3a9d commit 1f422a7
Show file tree
Hide file tree
Showing 14 changed files with 176 additions and 47 deletions.
18 changes: 14 additions & 4 deletions .github/assets/example/feeds.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,18 @@ xmlUrl = "https://feed2.com/rss"
name = "list 2"

[[lists.feeds]]
title = "feed 1"
xmlUrl = "https://feed1.com/rss"
title = "bluesky"
type = "bluesky"
id = "username"
[[lists.feeds]]
title = "feed 2"
xmlUrl = "https://feed2.com/rss"
title = "note"
type = "note"
id = "username"
[[lists.feeds]]
title = "reddit"
type = "reddit"
id = "subreddit-name"
[[lists.feeds]]
title = "sizu.me"
type = "sizu.me"
id = "username"
2 changes: 1 addition & 1 deletion .github/workflows/deps-update.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:

steps:
- name: 🚚 Checkout Repository
uses: actions/checkout@v4
uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
with:
ref: dev

Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/gist-update.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ jobs:

steps:
- name: 🚚 Checkout Repository
uses: actions/checkout@v4
uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6

- name: 🦕 Setup Deno
uses: denoland/setup-deno@v1
uses: denoland/setup-deno@041b854f97b325bd60e53e9dc2de9cb9f9ac0cba # v1.1.4
with:
deno-version: v1.x

Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@ jobs:

steps:
- name: 🚚 Checkout Repository
uses: actions/checkout@v4
uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6

- name: 🦕 Setup Deno
uses: denoland/setup-deno@v1
uses: denoland/setup-deno@041b854f97b325bd60e53e9dc2de9cb9f9ac0cba # v1.1.4
with:
deno-version: v1.x

Expand All @@ -41,6 +41,6 @@ jobs:
run: deno check ./**/*.ts

- name: ☂️ Upload Coverage
uses: codecov/codecov-action@v4
uses: codecov/codecov-action@e28ff129e5465c2c0dcc6f003fc735cb6ae0c673 # v4.5.0
with:
token: ${{ secrets.CODECOV_TOKEN }}
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
/feeds.toml
/outputs/
/coverage
/coverage.lcov
11 changes: 8 additions & 3 deletions src/libs/convert.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
import { stringify } from "@libs/xml";
import { parse } from "@std/toml";
import { transcodeXmlUrl } from "./sites.ts";
import type { Feed, List, Lists, OPMLOutline } from "../types/mod.ts";

export function convertToTOML(data: string): Lists {
export function convertFromTOML(data: string): Lists {
const lists: Lists = parse(data) as Lists;
lists.lists.map((list: List) => {
list.feeds.map((feed: Feed) => {
feed.xmlUrl = new URL(feed.xmlUrl);
feed.xmlUrl = feed.xmlUrl
? new URL(feed.xmlUrl)
: transcodeXmlUrl(feed.title, feed.type, feed.id);
});
});
return lists;
Expand All @@ -18,7 +21,9 @@ export function convertToOPML(list: List): string {
return {
"@title": feed.title,
"@text": feed.title,
"@xmlUrl": feed.xmlUrl,
"@xmlUrl": feed.xmlUrl
? new URL(feed.xmlUrl)
: transcodeXmlUrl(feed.title, feed.type, feed.id),
"@type": "rss",
};
}),
Expand Down
4 changes: 2 additions & 2 deletions src/libs/io.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { paramCase } from "@wok/case";
import { format } from "@std/path";
import { convertToOPML, convertToTOML } from "./convert.ts";
import { convertFromTOML, convertToOPML } from "./convert.ts";
import type { List, Lists } from "../types/mod.ts";

export async function readTOML(file: string): Promise<Lists> {
try {
const data: string = await Deno.readTextFile(file);
return convertToTOML(data);
return convertFromTOML(data);
} catch (error) {
if (error instanceof Deno.errors.NotFound) {
throw new Error(`File not found: "${file}"`);
Expand Down
23 changes: 23 additions & 0 deletions src/libs/sites.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import type { site } from "../types/mod.ts";

const sites: site[] = [
{ type: "bluesky", url: new URL("https://bsky.app/profile/{id}/rss") },
{ type: "note", url: new URL("https://note.com/{id}/rss") },
{ type: "reddit", url: new URL("https://www.reddit.com/r/{id}/.rss") },
{ type: "sizu.me", url: new URL("https://sizu.me/{id}/rss") },
];

export function transcodeXmlUrl(
title: string,
type: string | undefined,
id: string | undefined,
): URL {
if (!type) throw new Error(`Parameter not set: "type" of "${title}"`);
if (!id) throw new Error(`Parameter not set: "id" of "${title}"`);

const url: URL | undefined = sites
.find((site: site) => site.type === type)?.url;
if (!url) throw new Error(`Site not found: "${type}" of "${title}"`);

return new URL(url.href.replace(encodeURI("{id}"), id));
}
5 changes: 3 additions & 2 deletions src/types/toml.ts → src/types/feed.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export type List = {
};
export type Feed = {
title: string;
text: string;
xmlUrl: URL;
type?: string;
id?: string;
xmlUrl?: URL;
};
3 changes: 2 additions & 1 deletion src/types/mod.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export * from "./toml.ts";
export * from "./opml.ts";
export * from "./feed.ts";
export * from "./sites.ts";
4 changes: 4 additions & 0 deletions src/types/sites.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export type site = {
type: string;
url: URL;
};
91 changes: 65 additions & 26 deletions test/libs/convert_test.ts
Original file line number Diff line number Diff line change
@@ -1,37 +1,57 @@
import { assertEquals } from "@std/assert";
import { convertToOPML, convertToTOML } from "../../src/libs/convert.ts";
import { convertFromTOML, convertToOPML } from "../../src/libs/convert.ts";
import type { List, Lists } from "../../src/types/mod.ts";

Deno.test("Parse TOML", () => {
Deno.test("Parse TOML (RSS)", () => {
const toml = `
[[lists]]
name = "list name"
[[lists.feeds]]
title = "feed title"
xmlUrl = "https://example.com/feed"
`;

const feeds: Lists = {
lists: [
{
name: "list name",
feeds: [
{
title: "feed title",
text: "feed title",
xmlUrl: new URL("https://example.com/feed"),
},
],
},
],
lists: [{
name: "list name",
feeds: [{
title: "feed title",
xmlUrl: new URL("https://example.com/feed"),
}],
}],
};

assertEquals(convertFromTOML(toml), feeds);
});

Deno.test("Parse TOML (Site)", () => {
const toml = `
[[lists]]
name = "list name"
[[lists.feeds]]
title = "feed title"
text = "feed title"
xmlUrl = "https://example.com/feed"
type = "bluesky"
id = "username"
`;

assertEquals(convertToTOML(toml), feeds);
const feeds: Lists = {
lists: [{
name: "list name",
feeds: [{
title: "feed title",
type: "bluesky",
id: "username",
xmlUrl: new URL("https://bsky.app/profile/username/rss"),
}],
}],
};

assertEquals(convertFromTOML(toml), feeds);
});

Deno.test("Convert Lists to OPML", () => {
Deno.test("Convert Lists to OPML (RSS)", () => {
const xml = `\
<?xml version="1.0" encoding="UTF-8"?>
<opml version="2.0">
Expand All @@ -43,14 +63,33 @@ Deno.test("Convert Lists to OPML", () => {

const list: List = {
name: "list name",
feeds: [
{
title: "feed title",
text: "feed title",
xmlUrl: new URL("https://example.com/feed"),
},
],
feeds: [{
title: "feed title",
xmlUrl: new URL("https://example.com/feed"),
}],
};

assertEquals(convertToOPML(list), xml);
});

Deno.test("Convert Lists to OPML (Site)", () => {
const xml = `\
<?xml version="1.0" encoding="UTF-8"?>
<opml version="2.0">
<body>
<outline title="feed title" text="feed title" xmlUrl="https://bsky.app/profile/username/rss" type="rss"/>
</body>
</opml>
`;

const list: List = {
name: "list name",
feeds: [{
title: "feed title",
type: "bluesky",
id: "username",
}],
};

assertEquals(xml, convertToOPML(list));
assertEquals(convertToOPML(list), xml);
});
5 changes: 2 additions & 3 deletions test/libs/io_test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { assertEquals, assertIsError } from "@std/assert";
import { join } from "@std/path";
import { readTOML, writeXML } from "../../src/libs/io.ts";
import { convertToOPML, convertToTOML } from "../../src/libs/convert.ts";
import { convertFromTOML, convertToOPML } from "../../src/libs/convert.ts";
import type { Lists } from "../../src/types/mod.ts";

Deno.test("Read TOML", async () => {
Expand All @@ -18,7 +18,7 @@ xmlUrl = "https://example.com/feed"
await Deno.writeTextFile(file, toml);
const lists: Lists = await readTOML(file);

assertEquals(convertToTOML(toml), lists);
assertEquals(convertFromTOML(toml), lists);
});

Deno.test("Read TOML (File not found)", async () => {
Expand Down Expand Up @@ -55,7 +55,6 @@ Deno.test("Write XML", async () => {
feeds: [
{
title: "feed title",
text: "feed title",
xmlUrl: new URL("https://example.com/feed"),
},
],
Expand Down
45 changes: 45 additions & 0 deletions test/libs/sites_test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { assertEquals } from "@std/assert";
import { transcodeXmlUrl } from "../../src/libs/sites.ts";
import type { Feed } from "../../src/types/mod.ts";

Deno.test("Get XML URL (Site)", () => {
const feed: Feed = {
title: "feed title",
type: "bluesky",
id: "username",
};
assertEquals(
transcodeXmlUrl(feed.title, feed.type, feed.id),
new URL("https://bsky.app/profile/username/rss"),
);
});

Deno.test("Get XML URL (type not set)", () => {
const feed: Feed = { title: "feed title", id: "username" };
try {
transcodeXmlUrl(feed.title, undefined, feed.id);
} catch (error) {
assertEquals(error.message, `Parameter not set: "type" of "${feed.title}"`);
}
});

Deno.test("Get XML URL (id not set)", () => {
const feed: Feed = { title: "feed title", type: "bluesky" };
try {
transcodeXmlUrl(feed.title, feed.type, undefined);
} catch (error) {
assertEquals(error.message, `Parameter not set: "id" of "${feed.title}"`);
}
});

Deno.test("Get XML URL (Site not found)", () => {
const feed: Feed = { title: "feed title", type: "unknown", id: "username" };
try {
transcodeXmlUrl(feed.title, feed.type, feed.id);
} catch (error) {
assertEquals(
error.message,
`Site not found: "${feed.type}" of "${feed.title}"`,
);
}
});

0 comments on commit 1f422a7

Please sign in to comment.