UNPKG

spotify-uri

Version:

Parse the various Spotify URI formats into Objects and back

300 lines (285 loc) 7.7 kB
"use strict"; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // src/index.ts var src_exports = {}; __export(src_exports, { Album: () => Album, Artist: () => Artist, Episode: () => Episode, Local: () => Local, Playlist: () => Playlist, Search: () => Search, Show: () => Show, Track: () => Track, User: () => User, formatEmbedURL: () => formatEmbedURL, formatOpenURL: () => formatOpenURL, formatPlayURL: () => formatPlayURL, formatURI: () => formatURI, parse: () => parse }); module.exports = __toCommonJS(src_exports); // src/util.ts function decode(str) { return decodeURIComponent(str.replace(/\+/g, " ")); } function encode(str) { return encodeURIComponent(str).replace(/%20/g, "+").replace(/[!'()*]/g, escape); } // src/spotify-uri.ts var SpotifyUri = class { type; id; uri; constructor(uri, id, type) { this.uri = uri; this.id = id; this.type = type; } static is(v) { return typeof v === "object" && typeof v.uri === "string"; } toURI() { return `spotify:${this.type}:${encode(this.id)}`; } toURL() { return `/${this.type}/${encode(this.id)}`; } toEmbedURL() { return `https://embed.spotify.com/?uri=${this.toURI()}`; } toOpenURL() { return `https://open.spotify.com${this.toURL()}`; } toPlayURL() { return `https://play.spotify.com${this.toURL()}`; } }; // src/local.ts var Local = class extends SpotifyUri { artist; album; track; seconds; constructor(uri, artist, album, track, seconds) { super(uri, "", "local" /* Local */); this.artist = artist; this.album = album; this.track = track; this.seconds = seconds; } static is(v) { return typeof v === "object" && v.type === "local"; } toURI() { return `spotify:${this.type}:${encode(this.artist)}:${encode( this.album )}:${encode(this.track)}:${this.seconds}`; } toURL() { return `/${this.type}/${encode(this.artist)}/${encode(this.album)}/${encode( this.track )}/${this.seconds}`; } }; // src/search.ts var Search = class extends SpotifyUri { get query() { return this.id; } static is(v) { return typeof v === "object" && v.type === "search"; } }; // src/playlist.ts var Playlist = class extends SpotifyUri { user; constructor(uri, id, user) { super(uri, id, "playlist" /* Playlist */); if (typeof user === "string") { this.user = user; } } static is(v) { return typeof v === "object" && v.type === "playlist"; } toURI() { if (this.user !== void 0) { if (this.id === "starred") { return `spotify:user:${encode(this.user)}:${encode(this.id)}`; } return `spotify:user:${encode(this.user)}:playlist:${encode(this.id)}`; } return `spotify:playlist:${encode(this.id)}`; } toURL() { if (this.user !== void 0) { if (this.id === "starred") { return `/user/${encode(this.user)}/${encode(this.id)}`; } return `/user/${encode(this.user)}/playlist/${encode(this.id)}`; } return `/playlist/${encode(this.id)}`; } }; // src/artist.ts var Artist = class extends SpotifyUri { static is(v) { return typeof v === "object" && v.type === "artist"; } }; // src/album.ts var Album = class extends SpotifyUri { static is(v) { return typeof v === "object" && v.type === "album"; } }; // src/track.ts var Track = class extends SpotifyUri { static is(v) { return typeof v === "object" && v.type === "track"; } }; // src/episode.ts var Episode = class extends SpotifyUri { static is(v) { return typeof v === "object" && v.type === "episode"; } }; // src/show.ts var Show = class extends SpotifyUri { static is(v) { return typeof v === "object" && v.type === "show"; } }; // src/user.ts var User = class extends SpotifyUri { get user() { return this.id; } static is(v) { return typeof v === "object" && v.type === "user"; } }; // src/parse.ts function parse(input) { const uri = SpotifyUri.is(input) ? input.uri : input; const { protocol, hostname, pathname = "/", searchParams } = new URL(uri); if (hostname === "embed.spotify.com") { const parsedQs = Object.fromEntries(searchParams); if (typeof parsedQs.uri !== "string") { throw new Error( "Parsed query string was not valid: " + searchParams.toString() ); } return parse(parsedQs.uri); } if (protocol === "spotify:") { const parts2 = uri.split(":"); return parseParts(uri, parts2); } if (pathname === null) { throw new TypeError("No pathname"); } const parts = pathname.split("/"); return parseParts(uri, parts); } function parseParts(uri, parts) { parts = parts.filter((p) => !p.startsWith("intl")); let spotifyType = parts[1]; if (spotifyType === "embed" /* Embed */) { parts = parts.slice(1); spotifyType = parts[1]; } const len = parts.length; if (spotifyType === "search" /* Search */) { return new Search(uri, decode(parts.slice(2).join(":")), spotifyType); } if (len >= 3 && spotifyType === "local" /* Local */) { return new Local( uri, decode(parts[2]), decode(parts[3]), decode(parts[4]), +parts[5] ); } if (len >= 4 || spotifyType === "playlist" /* Playlist */) { if (len >= 5) { return new Playlist(uri, decode(parts[4]), decode(parts[2])); } if (parts[3] === "starred") { return new Playlist(uri, "starred", decode(parts[2])); } return new Playlist(uri, decode(parts[2])); } if (len === 3 && spotifyType === "user" /* User */) { return new User(uri, decode(parts[2]), spotifyType); } if (spotifyType === "artist" /* Artist */) { return new Artist(uri, parts[2], spotifyType); } if (spotifyType === "album" /* Album */) { return new Album(uri, parts[2], spotifyType); } if (spotifyType === "track" /* Track */) { return new Track(uri, parts[2], spotifyType); } if (spotifyType === "episode" /* Episode */) { return new Episode(uri, parts[2], spotifyType); } if (spotifyType === "show" /* Show */) { return new Show(uri, parts[2], spotifyType); } throw new TypeError(`Could not determine type for: ${uri}`); } // src/index.ts function formatURI(input) { const uri = typeof input === "string" ? parse(input) : input; return uri.toURI(); } function formatEmbedURL(input) { const uri = typeof input === "string" ? parse(input) : input; return uri.toEmbedURL(); } function formatOpenURL(input) { const uri = typeof input === "string" ? parse(input) : input; return uri.toOpenURL(); } function formatPlayURL(input) { const uri = typeof input === "string" ? parse(input) : input; return uri.toPlayURL(); } // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { Album, Artist, Episode, Local, Playlist, Search, Show, Track, User, formatEmbedURL, formatOpenURL, formatPlayURL, formatURI, parse });