@deadair/plugin-sdk 0.8.3 → 0.10.0
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 +58 -1
- package/dist/boundary.json.safe.d.ts +9 -2
- package/dist/boundary.json.safe.d.ts.map +1 -1
- package/dist/capabilities/podcast.d.ts +248 -0
- package/dist/capabilities/podcast.d.ts.map +1 -0
- package/dist/capabilities/similarity.d.ts +15 -1
- package/dist/capabilities/similarity.d.ts.map +1 -1
- package/dist/define.plugin.d.ts +3 -0
- package/dist/define.plugin.d.ts.map +1 -1
- package/dist/feed.parse.d.ts +84 -0
- package/dist/feed.parse.d.ts.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +122 -4
- package/dist/index.js.map +1 -1
- package/dist/plugin.config.fields.d.ts +10 -1
- package/dist/plugin.config.fields.d.ts.map +1 -1
- package/dist/plugin.manifest.d.ts +16 -1
- package/dist/plugin.manifest.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -53,6 +53,12 @@ var JSON_SAFE_PAYLOAD_TYPES = [
|
|
|
53
53
|
"NewsFeedDescriptor",
|
|
54
54
|
"NewsQuery",
|
|
55
55
|
"NewsItem",
|
|
56
|
+
"PodcastShow",
|
|
57
|
+
"PodcastAudio",
|
|
58
|
+
"PodcastEpisode",
|
|
59
|
+
"PodcastEpisodesQuery",
|
|
60
|
+
"PodcastDirectoryQuery",
|
|
61
|
+
"PodcastDirectoryEntry",
|
|
56
62
|
"SimilarArtist",
|
|
57
63
|
"ArtistTrack",
|
|
58
64
|
"SearchQuery",
|
|
@@ -87,6 +93,7 @@ var BOUNDARY_METHOD_TYPES = [
|
|
|
87
93
|
"MixerProvider",
|
|
88
94
|
"ChartsProvider",
|
|
89
95
|
"NewsProvider",
|
|
96
|
+
"PodcastProvider",
|
|
90
97
|
"SimilarityProvider",
|
|
91
98
|
"SearchProvider",
|
|
92
99
|
"WeatherProvider",
|
|
@@ -599,6 +606,18 @@ function parseFeed(xml) {
|
|
|
599
606
|
if (title !== void 0) feed.title = title;
|
|
600
607
|
const homeUrl = readLink(channel.link);
|
|
601
608
|
if (homeUrl !== void 0) feed.homeUrl = homeUrl;
|
|
609
|
+
const description = plainText2(channel.description ?? channel.summary ?? channel.subtitle);
|
|
610
|
+
if (description !== void 0) feed.description = description;
|
|
611
|
+
const author = readAuthor(channel.author);
|
|
612
|
+
if (author !== void 0) feed.author = author;
|
|
613
|
+
const imageUrl = readImage(channel.image);
|
|
614
|
+
if (imageUrl !== void 0) feed.imageUrl = imageUrl;
|
|
615
|
+
const language = text(channel.language);
|
|
616
|
+
if (language !== void 0) feed.language = language;
|
|
617
|
+
const categories = readCategories(channel.category);
|
|
618
|
+
if (categories.length > 0) feed.categories = categories;
|
|
619
|
+
const explicit = readExplicit(channel.explicit);
|
|
620
|
+
if (explicit !== void 0) feed.explicit = explicit;
|
|
602
621
|
return feed;
|
|
603
622
|
}
|
|
604
623
|
__name(parseFeed, "parseFeed");
|
|
@@ -632,6 +651,18 @@ function readItem(entry) {
|
|
|
632
651
|
if (publishedAt !== void 0) item.publishedAt = publishedAt;
|
|
633
652
|
if (author !== void 0) item.author = author;
|
|
634
653
|
if (categories.length > 0) item.categories = categories;
|
|
654
|
+
const enclosure = readEnclosure(entry.enclosure) ?? readEnclosure(entry.link);
|
|
655
|
+
if (enclosure !== void 0) item.enclosure = enclosure;
|
|
656
|
+
const durationMs = readDuration(entry.duration);
|
|
657
|
+
if (durationMs !== void 0) item.durationMs = durationMs;
|
|
658
|
+
const imageUrl = readImage(entry.image);
|
|
659
|
+
if (imageUrl !== void 0) item.imageUrl = imageUrl;
|
|
660
|
+
const explicit = readExplicit(entry.explicit);
|
|
661
|
+
if (explicit !== void 0) item.explicit = explicit;
|
|
662
|
+
const season = readOrdinal(entry.season);
|
|
663
|
+
if (season !== void 0) item.season = season;
|
|
664
|
+
const episode = readOrdinal(entry.episode);
|
|
665
|
+
if (episode !== void 0) item.episode = episode;
|
|
635
666
|
return item;
|
|
636
667
|
}
|
|
637
668
|
__name(readItem, "readItem");
|
|
@@ -668,15 +699,91 @@ function readAuthor(value) {
|
|
|
668
699
|
__name(readAuthor, "readAuthor");
|
|
669
700
|
function readCategories(value) {
|
|
670
701
|
const seen = /* @__PURE__ */ new Set();
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
702
|
+
const visit = /* @__PURE__ */ __name((candidates) => {
|
|
703
|
+
for (const candidate of candidates) {
|
|
704
|
+
const name = typeof candidate === "string" ? trimmed(candidate) : isRecord(candidate) ? text(candidate["@_term"]) ?? text(candidate["@_text"]) ?? text(candidate["#text"]) : void 0;
|
|
705
|
+
if (name !== void 0) seen.add(name);
|
|
706
|
+
if (isRecord(candidate)) visit(asArray(candidate.category));
|
|
707
|
+
}
|
|
708
|
+
}, "visit");
|
|
709
|
+
visit(asArray(value));
|
|
675
710
|
return [
|
|
676
711
|
...seen
|
|
677
712
|
];
|
|
678
713
|
}
|
|
679
714
|
__name(readCategories, "readCategories");
|
|
715
|
+
function readEnclosure(value) {
|
|
716
|
+
const found = [];
|
|
717
|
+
for (const candidate of asArray(value)) {
|
|
718
|
+
if (!isRecord(candidate)) continue;
|
|
719
|
+
const rel = text(candidate["@_rel"]);
|
|
720
|
+
const isAtomLink = candidate["@_href"] !== void 0;
|
|
721
|
+
if (isAtomLink && rel !== "enclosure") continue;
|
|
722
|
+
const url = webAddress(text(candidate["@_url"]) ?? text(candidate["@_href"]));
|
|
723
|
+
if (url === void 0) continue;
|
|
724
|
+
const enclosure = {
|
|
725
|
+
url
|
|
726
|
+
};
|
|
727
|
+
const type = text(candidate["@_type"])?.toLowerCase();
|
|
728
|
+
if (type !== void 0) enclosure.type = type;
|
|
729
|
+
const lengthBytes = positiveWhole(text(candidate["@_length"]));
|
|
730
|
+
if (lengthBytes !== void 0) enclosure.lengthBytes = lengthBytes;
|
|
731
|
+
found.push(enclosure);
|
|
732
|
+
}
|
|
733
|
+
return found.find((enclosure) => enclosure.type?.startsWith("audio/") === true) ?? found[0];
|
|
734
|
+
}
|
|
735
|
+
__name(readEnclosure, "readEnclosure");
|
|
736
|
+
function readDuration(value) {
|
|
737
|
+
const raw = text(asArray(value)[0]);
|
|
738
|
+
if (raw === void 0) return void 0;
|
|
739
|
+
const parts = raw.split(":").map((part) => part.trim());
|
|
740
|
+
if (parts.length > 3) return void 0;
|
|
741
|
+
if (!parts.every((part, at) => (at === parts.length - 1 ? /^\d+(\.\d+)?$/ : /^\d+$/).test(part))) return void 0;
|
|
742
|
+
if (parts.slice(1).some((part) => Number(part) >= 60)) return void 0;
|
|
743
|
+
const seconds = parts.reduce((total, part) => total * 60 + Number(part), 0);
|
|
744
|
+
const ms = Math.round(seconds * 1e3);
|
|
745
|
+
return Number.isFinite(ms) && ms > 0 ? ms : void 0;
|
|
746
|
+
}
|
|
747
|
+
__name(readDuration, "readDuration");
|
|
748
|
+
function readImage(value) {
|
|
749
|
+
const candidates = asArray(value);
|
|
750
|
+
for (const candidate of candidates) {
|
|
751
|
+
if (isRecord(candidate)) {
|
|
752
|
+
const href = webAddress(text(candidate["@_href"]));
|
|
753
|
+
if (href !== void 0) return href;
|
|
754
|
+
}
|
|
755
|
+
}
|
|
756
|
+
for (const candidate of candidates) {
|
|
757
|
+
const url = isRecord(candidate) ? webAddress(text(candidate.url)) : webAddress(text(candidate));
|
|
758
|
+
if (url !== void 0) return url;
|
|
759
|
+
}
|
|
760
|
+
return void 0;
|
|
761
|
+
}
|
|
762
|
+
__name(readImage, "readImage");
|
|
763
|
+
function readExplicit(value) {
|
|
764
|
+
const raw = text(asArray(value)[0])?.toLowerCase();
|
|
765
|
+
if (raw === "yes" || raw === "true" || raw === "explicit") return true;
|
|
766
|
+
if (raw === "no" || raw === "false" || raw === "clean") return false;
|
|
767
|
+
return void 0;
|
|
768
|
+
}
|
|
769
|
+
__name(readExplicit, "readExplicit");
|
|
770
|
+
var readOrdinal = /* @__PURE__ */ __name((value) => positiveWhole(text(asArray(value)[0])), "readOrdinal");
|
|
771
|
+
function positiveWhole(raw) {
|
|
772
|
+
if (raw === void 0 || !/^\d+$/.test(raw)) return void 0;
|
|
773
|
+
const parsed = Number(raw);
|
|
774
|
+
return Number.isSafeInteger(parsed) && parsed > 0 ? parsed : void 0;
|
|
775
|
+
}
|
|
776
|
+
__name(positiveWhole, "positiveWhole");
|
|
777
|
+
function webAddress(raw) {
|
|
778
|
+
if (raw === void 0) return void 0;
|
|
779
|
+
try {
|
|
780
|
+
const { protocol } = new URL(raw);
|
|
781
|
+
return protocol === "http:" || protocol === "https:" ? raw : void 0;
|
|
782
|
+
} catch {
|
|
783
|
+
return void 0;
|
|
784
|
+
}
|
|
785
|
+
}
|
|
786
|
+
__name(webAddress, "webAddress");
|
|
680
787
|
function plainText2(value) {
|
|
681
788
|
const raw = text(value);
|
|
682
789
|
return raw === void 0 ? void 0 : plainText(raw, FEED_SUMMARY_MAX_CHARS);
|
|
@@ -704,6 +811,13 @@ var trimmed = /* @__PURE__ */ __name((value) => value.trim().length === 0 ? void
|
|
|
704
811
|
function text(value) {
|
|
705
812
|
if (typeof value === "string") return trimmed(value);
|
|
706
813
|
if (typeof value === "number" || typeof value === "boolean") return String(value);
|
|
814
|
+
if (Array.isArray(value)) {
|
|
815
|
+
for (const candidate of value) {
|
|
816
|
+
const found = text(candidate);
|
|
817
|
+
if (found !== void 0) return found;
|
|
818
|
+
}
|
|
819
|
+
return void 0;
|
|
820
|
+
}
|
|
707
821
|
if (isRecord(value)) return text(value["#text"]);
|
|
708
822
|
return void 0;
|
|
709
823
|
}
|
|
@@ -880,6 +994,7 @@ var configFieldControlSchema = z.enum([
|
|
|
880
994
|
var configFieldOptionSourceSchema = z.enum([
|
|
881
995
|
"station.newsCategories",
|
|
882
996
|
"station.newsFeeds",
|
|
997
|
+
"station.podcastShows",
|
|
883
998
|
"intl.timeZones",
|
|
884
999
|
"plugins.speech",
|
|
885
1000
|
"plugins.llm",
|
|
@@ -1032,6 +1147,7 @@ var PLUGIN_CAPABILITY_ANALYSIS = "analysis";
|
|
|
1032
1147
|
var PLUGIN_CAPABILITY_MIXER = "mixer";
|
|
1033
1148
|
var PLUGIN_CAPABILITY_CHARTS = "charts";
|
|
1034
1149
|
var PLUGIN_CAPABILITY_NEWS = "news";
|
|
1150
|
+
var PLUGIN_CAPABILITY_PODCAST = "podcast";
|
|
1035
1151
|
var PLUGIN_CAPABILITY_SIMILARITY = "similarity";
|
|
1036
1152
|
var PLUGIN_CAPABILITY_SEARCH = "search";
|
|
1037
1153
|
var PLUGIN_CAPABILITY_WEATHER = "weather";
|
|
@@ -1048,6 +1164,7 @@ var KNOWN_PLUGIN_CAPABILITIES = [
|
|
|
1048
1164
|
PLUGIN_CAPABILITY_MIXER,
|
|
1049
1165
|
PLUGIN_CAPABILITY_CHARTS,
|
|
1050
1166
|
PLUGIN_CAPABILITY_NEWS,
|
|
1167
|
+
PLUGIN_CAPABILITY_PODCAST,
|
|
1051
1168
|
PLUGIN_CAPABILITY_SIMILARITY,
|
|
1052
1169
|
PLUGIN_CAPABILITY_SEARCH,
|
|
1053
1170
|
PLUGIN_CAPABILITY_WEATHER,
|
|
@@ -1097,6 +1214,7 @@ export {
|
|
|
1097
1214
|
PLUGIN_CAPABILITY_MIXER,
|
|
1098
1215
|
PLUGIN_CAPABILITY_NEWS,
|
|
1099
1216
|
PLUGIN_CAPABILITY_OAUTH,
|
|
1217
|
+
PLUGIN_CAPABILITY_PODCAST,
|
|
1100
1218
|
PLUGIN_CAPABILITY_SCROBBLE,
|
|
1101
1219
|
PLUGIN_CAPABILITY_SEARCH,
|
|
1102
1220
|
PLUGIN_CAPABILITY_SIMILARITY,
|