bgmt 0.1.0 → 0.1.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/README.md CHANGED
@@ -1,8 +1,10 @@
1
- # Bangumi Data Toolkit
1
+ # bgmt
2
2
 
3
3
  [![version](https://img.shields.io/npm/v/bgmt?label=bgmt)](https://www.npmjs.com/package/bgmt)
4
4
  [![CI](https://github.com/yjl9903/bgmc/actions/workflows/ci.yml/badge.svg)](https://github.com/yjl9903/bgmc/actions/workflows/ci.yml)
5
5
 
6
+ Shared bangumi helper functions used by [bgmx](https://github.com/yjl9903/bgmx).
7
+
6
8
  ## Installation
7
9
 
8
10
  ```bash
@@ -11,6 +13,33 @@ npm i bgmt
11
13
 
12
14
  ## Usage
13
15
 
16
+ ### CDN
17
+
18
+ You can use the following APIs to fetch the latest bgmd data from cdn.
19
+
20
+ ```ts
21
+ import { fetchBasicSubjects, fetchFullSubjects, fetchCalendarSubjects } from 'bgmt/cdn'
22
+
23
+ // https://unpkg.com/bgmd@0/dist/index.json
24
+ await fetchBasicSubjects()
25
+
26
+ // https://unpkg.com/bgmd@0/dist/full.json
27
+ await fetchFullSubjects()
28
+
29
+ // https://unpkg.com/bgmd@0/dist/calendar.json
30
+ await fetchCalendarSubjects()
31
+ ```
32
+
33
+ ### Utilities
34
+
35
+ WIP
36
+
37
+ ```ts
38
+ trimSeason('xxx 第二季')
39
+
40
+ // ...
41
+ ```
42
+
14
43
  ## License
15
44
 
16
45
  MIT License © 2024 [XLor](https://github.com/yjl9903)
package/dist/cdn.cjs ADDED
@@ -0,0 +1,25 @@
1
+
2
+ //#region src/cdn/index.ts
3
+ async function fetchBasicSubjects(options = {}) {
4
+ const { version = "0", baseURL = "https://unpkg.com" } = options;
5
+ const resp = await fetch(`${baseURL}/bgmd@${version}/dist/index.json`);
6
+ if (!resp.ok) throw new Error(`Fetch bgmd index.json failed`, { cause: resp });
7
+ return (await resp.json()).bangumis;
8
+ }
9
+ async function fetchFullSubjects(options = {}) {
10
+ const { version = "0", baseURL = "https://unpkg.com" } = options;
11
+ const resp = await fetch(`${baseURL}/bgmd@${version}/dist/full.json`);
12
+ if (!resp.ok) throw new Error(`Fetch bgmd full.json failed`, { cause: resp });
13
+ return (await resp.json()).bangumis;
14
+ }
15
+ async function fetchCalendarSubjects(options) {
16
+ const { version = "0", baseURL = "https://unpkg.com" } = options;
17
+ const resp = await fetch(`${baseURL}/bgmd@${version}/dist/calendar.json`);
18
+ if (!resp.ok) throw new Error(`Fetch bgmd calendar.json failed`, { cause: resp });
19
+ return (await resp.json()).calendar;
20
+ }
21
+
22
+ //#endregion
23
+ exports.fetchBasicSubjects = fetchBasicSubjects;
24
+ exports.fetchCalendarSubjects = fetchCalendarSubjects;
25
+ exports.fetchFullSubjects = fetchFullSubjects;
package/dist/cdn.d.cts ADDED
@@ -0,0 +1,25 @@
1
+ import { a as SubjectSearch, i as SubjectRating, n as FullSubject, r as SubjectImage, t as BasicSubject } from "./types-qUxe1mrZ.cjs";
2
+
3
+ //#region src/cdn/index.d.ts
4
+ interface CdnOptions {
5
+ /**
6
+ * bgmd version
7
+ *
8
+ * @default '0'
9
+ */
10
+ version?: string;
11
+ /**
12
+ * cdn base URL
13
+ *
14
+ * @default 'https://unpkg.com'
15
+ */
16
+ baseURL?: string;
17
+ }
18
+ declare function fetchBasicSubjects(options?: CdnOptions): Promise<BasicSubject[]>;
19
+ declare function fetchFullSubjects(options?: CdnOptions): Promise<FullSubject[]>;
20
+ declare function fetchCalendarSubjects(options: CdnOptions): Promise<{
21
+ calendar: [BasicSubject[], BasicSubject[], BasicSubject[], BasicSubject[], BasicSubject[], BasicSubject[], BasicSubject[]];
22
+ web: BasicSubject[];
23
+ }>;
24
+ //#endregion
25
+ export { BasicSubject, CdnOptions, FullSubject, SubjectImage, SubjectRating, SubjectSearch, fetchBasicSubjects, fetchCalendarSubjects, fetchFullSubjects };
package/dist/cdn.d.mts ADDED
@@ -0,0 +1,25 @@
1
+ import { a as SubjectSearch, i as SubjectRating, n as FullSubject, r as SubjectImage, t as BasicSubject } from "./types-CDKF8vJi.mjs";
2
+
3
+ //#region src/cdn/index.d.ts
4
+ interface CdnOptions {
5
+ /**
6
+ * bgmd version
7
+ *
8
+ * @default '0'
9
+ */
10
+ version?: string;
11
+ /**
12
+ * cdn base URL
13
+ *
14
+ * @default 'https://unpkg.com'
15
+ */
16
+ baseURL?: string;
17
+ }
18
+ declare function fetchBasicSubjects(options?: CdnOptions): Promise<BasicSubject[]>;
19
+ declare function fetchFullSubjects(options?: CdnOptions): Promise<FullSubject[]>;
20
+ declare function fetchCalendarSubjects(options: CdnOptions): Promise<{
21
+ calendar: [BasicSubject[], BasicSubject[], BasicSubject[], BasicSubject[], BasicSubject[], BasicSubject[], BasicSubject[]];
22
+ web: BasicSubject[];
23
+ }>;
24
+ //#endregion
25
+ export { BasicSubject, CdnOptions, FullSubject, SubjectImage, SubjectRating, SubjectSearch, fetchBasicSubjects, fetchCalendarSubjects, fetchFullSubjects };
package/dist/cdn.mjs ADDED
@@ -0,0 +1,22 @@
1
+ //#region src/cdn/index.ts
2
+ async function fetchBasicSubjects(options = {}) {
3
+ const { version = "0", baseURL = "https://unpkg.com" } = options;
4
+ const resp = await fetch(`${baseURL}/bgmd@${version}/dist/index.json`);
5
+ if (!resp.ok) throw new Error(`Fetch bgmd index.json failed`, { cause: resp });
6
+ return (await resp.json()).bangumis;
7
+ }
8
+ async function fetchFullSubjects(options = {}) {
9
+ const { version = "0", baseURL = "https://unpkg.com" } = options;
10
+ const resp = await fetch(`${baseURL}/bgmd@${version}/dist/full.json`);
11
+ if (!resp.ok) throw new Error(`Fetch bgmd full.json failed`, { cause: resp });
12
+ return (await resp.json()).bangumis;
13
+ }
14
+ async function fetchCalendarSubjects(options) {
15
+ const { version = "0", baseURL = "https://unpkg.com" } = options;
16
+ const resp = await fetch(`${baseURL}/bgmd@${version}/dist/calendar.json`);
17
+ if (!resp.ok) throw new Error(`Fetch bgmd calendar.json failed`, { cause: resp });
18
+ return (await resp.json()).calendar;
19
+ }
20
+
21
+ //#endregion
22
+ export { fetchBasicSubjects, fetchCalendarSubjects, fetchFullSubjects };
package/dist/index.cjs CHANGED
@@ -1,60 +1,125 @@
1
- 'use strict';
2
-
3
- const simptrad = require('simptrad');
1
+ let simptrad = require("simptrad");
4
2
 
3
+ //#region src/utils/tags.ts
4
+ const MERGE_TAGS = [
5
+ ["漫改", "漫画改"],
6
+ ["轻改", "轻小说改"],
7
+ ["东映アニメーション", "东映动画"],
8
+ ["TV", "TVA"]
9
+ ];
10
+ const REMOVE_TAGS = new Set([
11
+ "未定档",
12
+ "未确定",
13
+ "日本",
14
+ "日本动画"
15
+ ]);
5
16
  function normalizeTags(tags, options = {}) {
6
- const merged = mergeSimpleTags(tags);
7
- const reliable = options.count ? merged.filter((t) => t.count >= options.count) : merged;
8
- return reliable.map((t) => t.name).sort();
17
+ const merged = mergeSimpleTags(tags.filter((t) => !REMOVE_TAGS.has(t.name)));
18
+ return (options.count ? merged.filter((t) => t.count >= options.count) : merged).map((t) => t.name).sort();
9
19
  }
10
20
  function mergeSimpleTags(tags) {
11
- const map = /* @__PURE__ */ new Map();
12
- for (const t of tags) {
13
- const name = simptrad.fullToHalf(simptrad.tradToSimple(t.name), { punctuation: true });
14
- map.set(name, (map.get(name) ?? 0) + t.count);
15
- }
16
- return [...map.entries()].map(([k, v]) => ({ name: k, count: v }));
21
+ const map = /* @__PURE__ */ new Map();
22
+ for (const t of tags) {
23
+ if (/(19|20)\d{2}(春|夏|秋|冬)/.test(t.name)) {
24
+ if (t.name.includes("春")) t.name = t.name.replace("春", "年4月");
25
+ else if (t.name.includes("夏")) t.name = t.name.replace("夏", "年7月");
26
+ else if (t.name.includes("秋")) t.name = t.name.replace("秋", "年10月");
27
+ else if (t.name.includes("冬")) t.name = t.name.replace("冬", "年1月");
28
+ }
29
+ if (/(19|20)\d{2}年(春|夏|秋|冬)/.test(t.name)) {
30
+ if (t.name.includes("春")) t.name = t.name.replace("春", "4月");
31
+ else if (t.name.includes("夏")) t.name = t.name.replace("夏", "7月");
32
+ else if (t.name.includes("秋")) t.name = t.name.replace("秋", "10月");
33
+ else if (t.name.includes("冬")) t.name = t.name.replace("冬", "1月");
34
+ }
35
+ if (/(19|20)\d{2}?|\d{1,2}月/.test(t.name)) {
36
+ let target = t.name;
37
+ for (const tt of tags) if (tt.name.indexOf(t.name) !== -1 && tt.name.length > target.length) target = tt.name;
38
+ t.name = target;
39
+ }
40
+ const name0 = t.name;
41
+ const name1 = (0, simptrad.fullToHalf)((0, simptrad.tradToSimple)(name0), { punctuation: true });
42
+ const name = MERGE_TAGS.find((arr) => arr.includes(name1))?.[0] ?? name1;
43
+ map.set(name, (map.get(name) ?? 0) + t.count);
44
+ }
45
+ return [...map.entries()].map(([k, v]) => ({
46
+ name: k,
47
+ count: v
48
+ }));
17
49
  }
18
50
 
51
+ //#endregion
52
+ //#region src/utils/season.ts
19
53
  const REs = [
20
- /(?:S|Season|season\s?)(\d+)$/,
21
- /(1st|2nd|3rd|[456789]th) Season$/,
22
- /第?(\d+)[季期]$/,
23
- /第?((?:[零一二三四五六七八九]十|十)?[零一二三四五六七八九])[季期]$/,
24
- /\((?:19|20)\d{2}\)$/
54
+ /(?:S|Season|season\s?)(\d+)$/,
55
+ /(1st|2nd|3rd|[456789]th) Season$/,
56
+ /第?(\d+)[季期]$/,
57
+ /第?((?:[零一二三四五六七八九]十|十)?[零一二三四五六七八九])[季期]$/,
58
+ /\((?:19|20)\d{2}\)$/
25
59
  ];
26
60
  function trimSeason(bgm) {
27
- let changed = false;
28
- function trim(t) {
29
- for (const RE of REs) {
30
- const match = RE.exec(t);
31
- if (match) {
32
- changed = true;
33
- return t.slice(0, t.length - match[0].length).trimEnd();
34
- }
35
- }
36
- }
37
- const trimmed = bgm.alias.map(trim);
38
- trimmed.push(trim(bgm.name));
39
- const original = [...new Set(trimmed.filter(Boolean))].sort();
40
- if (original.length === bgm.alias.length && !changed) {
41
- return {
42
- name: bgm.name,
43
- original: void 0
44
- };
45
- }
46
- return {
47
- name: bgm.name,
48
- original
49
- };
61
+ let changed = false;
62
+ function trim(t) {
63
+ for (const RE of REs) {
64
+ const match = RE.exec(t);
65
+ if (match) {
66
+ changed = true;
67
+ return t.slice(0, t.length - match[0].length).trimEnd();
68
+ }
69
+ }
70
+ }
71
+ const trimmed = bgm.alias.map(trim);
72
+ trimmed.push(trim(bgm.name));
73
+ const original = [...new Set(trimmed.filter(Boolean))].sort();
74
+ if (original.length === bgm.alias.length && !changed) return {
75
+ name: bgm.name,
76
+ original: void 0
77
+ };
78
+ return {
79
+ name: bgm.name,
80
+ original
81
+ };
82
+ }
83
+
84
+ //#endregion
85
+ //#region src/utils/title.ts
86
+ function normalizeTitle(t) {
87
+ return (0, simptrad.fullToHalf)((0, simptrad.tradToSimple)(t), { punctuation: true });
88
+ }
89
+ function getSubjectDisplayName(bgm) {
90
+ return bgm?.name_cn || bgm?.name || "";
91
+ }
92
+ function getSubjectInfoboxArray(infobox) {
93
+ return Array.isArray(infobox?.value) ? infobox?.value.map((v) => v?.v).filter(Boolean) ?? [] : typeof infobox?.value === "string" ? [infobox.value] : [];
94
+ }
95
+ function getSubjectAlias(subject) {
96
+ const translations = (subject.infobox?.filter((box) => [
97
+ "别名",
98
+ "中文名",
99
+ "英文名"
100
+ ].includes(box.key)) ?? [])?.flatMap((box) => getSubjectInfoboxArray(box)) ?? [];
101
+ return [...new Set([
102
+ subject.name,
103
+ subject.name_cn,
104
+ ...translations
105
+ ].filter(Boolean).map(decodeSubjectTitle))].sort();
106
+ }
107
+ function decodeSubjectTitle(name) {
108
+ return name.replace(/&quot;/g, "\"").replace(/&amp;/g, "&").replace(/&lt;/g, "<").replace(/&gt;/g, ">");
50
109
  }
51
110
 
111
+ //#endregion
112
+ //#region src/utils/summary.ts
52
113
  function normalizeSummary(text) {
53
- if (!text) return "";
54
- const t = text.trim().replace(/\u2028|\r\n/g, "\n");
55
- return t;
114
+ if (!text) return "";
115
+ return text.trim().replace(/\u2028|\r\n/g, "\n");
56
116
  }
57
117
 
118
+ //#endregion
119
+ exports.decodeSubjectTitle = decodeSubjectTitle;
120
+ exports.getSubjectAlias = getSubjectAlias;
121
+ exports.getSubjectDisplayName = getSubjectDisplayName;
58
122
  exports.normalizeSummary = normalizeSummary;
59
123
  exports.normalizeTags = normalizeTags;
60
- exports.trimSeason = trimSeason;
124
+ exports.normalizeTitle = normalizeTitle;
125
+ exports.trimSeason = trimSeason;