@discord-player/plugin-host 8.0.0-dev.0 → 8.0.0-dev.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 +199 -29
- package/dist/compat/base-extractor.d.ts +6 -0
- package/dist/compat/base-extractor.js.map +1 -1
- package/dist/compat/extractor-execution-context.js.map +1 -1
- package/dist/compat/extractor-plugin.js +109 -68
- package/dist/compat/extractor-plugin.js.map +1 -1
- package/dist/compat/utils.js.map +1 -1
- package/dist/errors.d.ts +0 -2
- package/dist/errors.js +0 -2
- package/dist/errors.js.map +1 -1
- package/dist/host.d.ts +24 -3
- package/dist/host.js +198 -50
- package/dist/host.js.map +1 -1
- package/dist/index.d.ts +5 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/legacy-player.d.ts +1 -1
- package/dist/lyrics.d.ts +56 -0
- package/dist/lyrics.js +110 -0
- package/dist/lyrics.js.map +1 -0
- package/dist/media.d.ts +15 -0
- package/dist/media.js +193 -0
- package/dist/media.js.map +1 -0
- package/dist/plugins/execution-options.d.ts +2 -0
- package/dist/plugins/operation-dispatch.js +30 -11
- package/dist/plugins/operation-dispatch.js.map +1 -1
- package/dist/plugins/plugin-error.js.map +1 -1
- package/dist/plugins/registry-internals.d.ts +2 -2
- package/dist/plugins/registry.d.ts +48 -6
- package/dist/plugins/registry.js +180 -18
- package/dist/plugins/registry.js.map +1 -1
- package/dist/plugins/stream-resolver.js +24 -4
- package/dist/plugins/stream-resolver.js.map +1 -1
- package/dist/plugins/types.d.ts +28 -23
- package/dist/plugins/types.js.map +1 -1
- package/dist/protocol.d.ts +43 -3
- package/dist/protocol.js +11 -1
- package/dist/protocol.js.map +1 -1
- package/dist/providers/lrclib.d.ts +120 -0
- package/dist/providers/lrclib.js +183 -0
- package/dist/providers/lrclib.js.map +1 -0
- package/dist/remote.d.ts +29 -0
- package/dist/remote.js +142 -0
- package/dist/remote.js.map +1 -0
- package/dist/runtime.d.ts +2 -8
- package/dist/runtime.js +42 -44
- package/dist/runtime.js.map +1 -1
- package/dist/structures/search-result.js.map +1 -1
- package/dist/structures/track-types.d.ts +7 -3
- package/dist/structures/track.d.ts +6 -11
- package/dist/structures/track.js +10 -10
- package/dist/structures/track.js.map +1 -1
- package/dist/types.d.ts +4 -4
- package/dist/utils/legacy-serialization-schemas.d.ts +12 -0
- package/dist/utils/serialization-schemas.d.ts +18 -0
- package/dist/utils/serialization-schemas.js +6 -1
- package/dist/utils/serialization-schemas.js.map +1 -1
- package/dist/utils/serialization.js.map +1 -1
- package/docs/remedia-contract.md +55 -0
- package/package.json +5 -4
package/dist/protocol.js
CHANGED
|
@@ -3,7 +3,7 @@ import { Playlist } from './structures/playlist.js';
|
|
|
3
3
|
import { SearchResult } from './structures/search-result.js';
|
|
4
4
|
import { deserialize } from './utils/serde.js';
|
|
5
5
|
/** Reconstruct source-host metadata in a consumer process without restoring private extractor objects.
|
|
6
|
-
*
|
|
6
|
+
* The normal Track retains the transient hint without requiring a second representation.
|
|
7
7
|
* @param result HTTP result payload (after unwrapping Remedia's handled/result envelope).
|
|
8
8
|
* @returns Shared model instances suitable for application metadata display and persistence.
|
|
9
9
|
*/
|
|
@@ -12,6 +12,9 @@ export function deserializeSourceResult(result) {
|
|
|
12
12
|
const track = deserialize(entity);
|
|
13
13
|
if (!(track instanceof Track))
|
|
14
14
|
throw new TypeError('Expected source Track metadata');
|
|
15
|
+
if (_state !== undefined && typeof _state !== 'string')
|
|
16
|
+
throw new TypeError('Invalid source state');
|
|
17
|
+
track.sourceState = _state;
|
|
15
18
|
return track;
|
|
16
19
|
});
|
|
17
20
|
const playlist = result.playlist ? deserialize(result.playlist) : null;
|
|
@@ -24,4 +27,11 @@ export function deserializeSourceResult(result) {
|
|
|
24
27
|
}
|
|
25
28
|
return new SearchResult({ tracks, playlist });
|
|
26
29
|
}
|
|
30
|
+
/** Encode a queued Track for a host operation, retaining its transient state hint.
|
|
31
|
+
* @param track Normal model from search, queue, or history.
|
|
32
|
+
* @returns Portable metadata with an optional opaque state token. Persistence should use serialize().
|
|
33
|
+
*/
|
|
34
|
+
export function serializeSourceTrack(track) {
|
|
35
|
+
return { ...track.serialize(), ...(track.sourceState ? { sourceState: track.sourceState } : {}) };
|
|
36
|
+
}
|
|
27
37
|
//# sourceMappingURL=protocol.js.map
|
package/dist/protocol.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"protocol.js","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"protocol.js","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAwB,MAAM,uBAAuB,CAAC;AACpE,OAAO,EAAE,QAAQ,EAA2B,MAAM,0BAA0B,CAAC;AAC7E,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAC7D,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAmB/C;;;;GAIG;AACH,MAAM,UAAU,uBAAuB,CAAC,MAA4B;IAClE,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,WAAW,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,EAAE,EAAE;QACtE,MAAM,KAAK,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC;QAElC,IAAI,CAAC,CAAC,KAAK,YAAY,KAAK,CAAC;YAAE,MAAM,IAAI,SAAS,CAAC,gCAAgC,CAAC,CAAC;QAErF,IAAI,MAAM,KAAK,SAAS,IAAI,OAAO,MAAM,KAAK,QAAQ;YAAE,MAAM,IAAI,SAAS,CAAC,sBAAsB,CAAC,CAAC;QAEpG,KAAK,CAAC,WAAW,GAAG,MAAM,CAAC;QAE3B,OAAO,KAAK,CAAC;IACf,CAAC,CAAC,CAAC;IACH,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,WAAW,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAEvE,IAAI,QAAQ,KAAK,IAAI,IAAI,CAAC,CAAC,QAAQ,YAAY,QAAQ,CAAC;QAAE,MAAM,IAAI,SAAS,CAAC,mCAAmC,CAAC,CAAC;IAEnH,IAAI,QAAQ,EAAE,CAAC;QACb,QAAQ,CAAC,MAAM,GAAG,MAAM,CAAC;QAEzB,KAAK,MAAM,KAAK,IAAI,MAAM;YAAE,KAAK,CAAC,QAAQ,GAAG,QAAQ,CAAC;IACxD,CAAC;IAED,OAAO,IAAI,YAAY,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC;AAChD,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,oBAAoB,CAAC,KAAY;IAC/C,OAAO,EAAE,GAAG,KAAK,CAAC,SAAS,EAAE,EAAE,GAAG,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;AACpG,CAAC"}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
/** Search parameters supported by the LRCLIB API. */
|
|
2
|
+
export interface LrcSearchParams {
|
|
3
|
+
/** Free-form query. Either `q` or `trackName` is required. */
|
|
4
|
+
q?: string;
|
|
5
|
+
/** Track title. Either `q` or `trackName` is required. */
|
|
6
|
+
trackName?: string;
|
|
7
|
+
/** Artist name filter. */
|
|
8
|
+
artistName?: string;
|
|
9
|
+
/** Album name filter. */
|
|
10
|
+
albumName?: string;
|
|
11
|
+
}
|
|
12
|
+
/** Parameters accepted by LRCLIB's exact lookup endpoints. */
|
|
13
|
+
export interface LrcGetParams extends LrcSearchParams {
|
|
14
|
+
/** Track duration in seconds. */
|
|
15
|
+
duration?: number;
|
|
16
|
+
}
|
|
17
|
+
/** Lyrics record returned by LRCLIB search. */
|
|
18
|
+
export interface LrcSearchResult {
|
|
19
|
+
/** LRCLIB record ID. */
|
|
20
|
+
id: number;
|
|
21
|
+
/** Display name supplied by LRCLIB. */
|
|
22
|
+
name: string;
|
|
23
|
+
/** Track title. */
|
|
24
|
+
trackName: string;
|
|
25
|
+
/** Artist name. */
|
|
26
|
+
artistName: string;
|
|
27
|
+
/** Album name. */
|
|
28
|
+
albumName: string;
|
|
29
|
+
/** Track duration in seconds. */
|
|
30
|
+
duration: number;
|
|
31
|
+
/** Whether the recording is instrumental. */
|
|
32
|
+
instrumental: boolean;
|
|
33
|
+
/** Plain lyric text, when available. */
|
|
34
|
+
plainLyrics: string;
|
|
35
|
+
/** Synchronized LRC text, when supplied by the service. */
|
|
36
|
+
syncedLyrics?: string;
|
|
37
|
+
}
|
|
38
|
+
/** Lyrics record returned by exact LRCLIB lookups. */
|
|
39
|
+
/** Lyrics record returned by the LRCLIB exact lookup endpoints. */
|
|
40
|
+
export type LrcGetResult = Omit<LrcSearchResult, 'name'>;
|
|
41
|
+
/** LRCLIB API client with serialized requests and bounded retries. */
|
|
42
|
+
export declare class LrcLib {
|
|
43
|
+
#private;
|
|
44
|
+
/** Player used to identify requests and publish debug messages. */
|
|
45
|
+
readonly player: {
|
|
46
|
+
version: string;
|
|
47
|
+
debug(message: string): void;
|
|
48
|
+
};
|
|
49
|
+
/** Base API URL. */
|
|
50
|
+
api: string;
|
|
51
|
+
/** Request timeout in milliseconds. */
|
|
52
|
+
timeout: number;
|
|
53
|
+
/** Maximum retry count for rate limits and server errors. */
|
|
54
|
+
retryLimit: number;
|
|
55
|
+
/**
|
|
56
|
+
* Create an LRCLIB client owned by one Player.
|
|
57
|
+
* @param player Player used to identify requests and publish debug messages.
|
|
58
|
+
*/
|
|
59
|
+
constructor(
|
|
60
|
+
/** Player used to identify requests and publish debug messages. */
|
|
61
|
+
player: {
|
|
62
|
+
version: string;
|
|
63
|
+
debug(message: string): void;
|
|
64
|
+
});
|
|
65
|
+
/**
|
|
66
|
+
* Set the request timeout.
|
|
67
|
+
* @param timeout Positive request timeout in milliseconds.
|
|
68
|
+
*/
|
|
69
|
+
setRequestTimeout(
|
|
70
|
+
/** Timeout in milliseconds. */
|
|
71
|
+
timeout: number): void;
|
|
72
|
+
/**
|
|
73
|
+
* Set the maximum retry count.
|
|
74
|
+
* @param limit Non-negative retry count for rate limits and server errors.
|
|
75
|
+
*/
|
|
76
|
+
setRetryLimit(
|
|
77
|
+
/** Non-negative retry count. */
|
|
78
|
+
limit: number): void;
|
|
79
|
+
/**
|
|
80
|
+
* Get lyrics by exact track metadata.
|
|
81
|
+
* @param params Track title, artist, album, and optional duration.
|
|
82
|
+
*/
|
|
83
|
+
get(
|
|
84
|
+
/** Exact lookup metadata. */
|
|
85
|
+
params: LrcGetParams): Promise<LrcGetResult>;
|
|
86
|
+
/**
|
|
87
|
+
* Get lyrics by LRCLIB record ID.
|
|
88
|
+
* @param id Numeric LRCLIB record ID.
|
|
89
|
+
*/
|
|
90
|
+
getById(
|
|
91
|
+
/** Numeric LRCLIB record ID. */
|
|
92
|
+
id: `${number}` | number): Promise<LrcGetResult>;
|
|
93
|
+
/**
|
|
94
|
+
* Get cached lyrics by exact track metadata.
|
|
95
|
+
* @param params Track title, artist, album, and optional duration.
|
|
96
|
+
*/
|
|
97
|
+
getCached(
|
|
98
|
+
/** Exact lookup metadata. */
|
|
99
|
+
params: LrcGetParams): Promise<LrcGetResult>;
|
|
100
|
+
/**
|
|
101
|
+
* Search LRCLIB for matching lyric records.
|
|
102
|
+
* @param params Free-form query or track and artist metadata.
|
|
103
|
+
*/
|
|
104
|
+
search(
|
|
105
|
+
/** Search query or track and artist metadata. */
|
|
106
|
+
params: LrcSearchParams): Promise<LrcSearchResult[]>;
|
|
107
|
+
/**
|
|
108
|
+
* Send one serialized request to LRCLIB.
|
|
109
|
+
* @param path API path, with or without a leading slash.
|
|
110
|
+
* @param options Additional fetch options merged with the default GET request.
|
|
111
|
+
* @returns Parsed JSON response.
|
|
112
|
+
*/
|
|
113
|
+
request<Result>(
|
|
114
|
+
/** API path, with or without a leading slash. */
|
|
115
|
+
path: string,
|
|
116
|
+
/** Additional fetch options merged with the default GET request. */
|
|
117
|
+
options?: RequestInit): Promise<Result>;
|
|
118
|
+
}
|
|
119
|
+
/** Optional LRCLIB provider. No provider is installed by constructing a Player. */
|
|
120
|
+
export declare const lrclibPlugin: (options?: Record<string, never> | undefined) => import("../plugins/types.js").PluginRegistration<Record<string, never>>;
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
import { definePlugin } from '../plugins/types.js';
|
|
2
|
+
import { parseLyrics } from '../lyrics.js';
|
|
3
|
+
function toSnakeCase(params) {
|
|
4
|
+
const result = new URLSearchParams();
|
|
5
|
+
for (const [key, value] of Object.entries(params)) {
|
|
6
|
+
if (value === undefined || value === null || value === '')
|
|
7
|
+
continue;
|
|
8
|
+
const snake = key.replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`);
|
|
9
|
+
result.set(snake, String(value));
|
|
10
|
+
}
|
|
11
|
+
return result;
|
|
12
|
+
}
|
|
13
|
+
function delayWait(ms, signal) {
|
|
14
|
+
signal?.throwIfAborted();
|
|
15
|
+
return new Promise((resolve, reject) => {
|
|
16
|
+
const abort = () => {
|
|
17
|
+
clearTimeout(timer);
|
|
18
|
+
reject(signal?.reason);
|
|
19
|
+
};
|
|
20
|
+
const timer = setTimeout(() => {
|
|
21
|
+
signal?.removeEventListener('abort', abort);
|
|
22
|
+
resolve();
|
|
23
|
+
}, ms);
|
|
24
|
+
signal?.addEventListener('abort', abort, { once: true });
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
/** LRCLIB API client with serialized requests and bounded retries. */
|
|
28
|
+
export class LrcLib {
|
|
29
|
+
player;
|
|
30
|
+
/** Base API URL. */
|
|
31
|
+
api = 'https://lrclib.net/api';
|
|
32
|
+
/** Request timeout in milliseconds. */
|
|
33
|
+
timeout = 15_000;
|
|
34
|
+
/** Maximum retry count for rate limits and server errors. */
|
|
35
|
+
retryLimit = 5;
|
|
36
|
+
#tail = Promise.resolve();
|
|
37
|
+
/**
|
|
38
|
+
* Create an LRCLIB client owned by one Player.
|
|
39
|
+
* @param player Player used to identify requests and publish debug messages.
|
|
40
|
+
*/
|
|
41
|
+
constructor(
|
|
42
|
+
/** Player used to identify requests and publish debug messages. */
|
|
43
|
+
player) {
|
|
44
|
+
this.player = player;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Set the request timeout.
|
|
48
|
+
* @param timeout Positive request timeout in milliseconds.
|
|
49
|
+
*/
|
|
50
|
+
setRequestTimeout(
|
|
51
|
+
/** Timeout in milliseconds. */
|
|
52
|
+
timeout) {
|
|
53
|
+
if (!Number.isFinite(timeout) || timeout <= 0)
|
|
54
|
+
throw new RangeError('Request timeout must be a positive finite number.');
|
|
55
|
+
this.timeout = timeout;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Set the maximum retry count.
|
|
59
|
+
* @param limit Non-negative retry count for rate limits and server errors.
|
|
60
|
+
*/
|
|
61
|
+
setRetryLimit(
|
|
62
|
+
/** Non-negative retry count. */
|
|
63
|
+
limit) {
|
|
64
|
+
if (!Number.isInteger(limit) || limit < 0)
|
|
65
|
+
throw new RangeError('Retry limit must be a non-negative integer.');
|
|
66
|
+
this.retryLimit = limit;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Get lyrics by exact track metadata.
|
|
70
|
+
* @param params Track title, artist, album, and optional duration.
|
|
71
|
+
*/
|
|
72
|
+
get(
|
|
73
|
+
/** Exact lookup metadata. */
|
|
74
|
+
params) {
|
|
75
|
+
return this.request(`get?${toSnakeCase(params)}`);
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Get lyrics by LRCLIB record ID.
|
|
79
|
+
* @param id Numeric LRCLIB record ID.
|
|
80
|
+
*/
|
|
81
|
+
getById(
|
|
82
|
+
/** Numeric LRCLIB record ID. */
|
|
83
|
+
id) {
|
|
84
|
+
return this.request(`get/${id}`);
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Get cached lyrics by exact track metadata.
|
|
88
|
+
* @param params Track title, artist, album, and optional duration.
|
|
89
|
+
*/
|
|
90
|
+
getCached(
|
|
91
|
+
/** Exact lookup metadata. */
|
|
92
|
+
params) {
|
|
93
|
+
return this.request(`get-cached?${toSnakeCase(params)}`);
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Search LRCLIB for matching lyric records.
|
|
97
|
+
* @param params Free-form query or track and artist metadata.
|
|
98
|
+
*/
|
|
99
|
+
search(
|
|
100
|
+
/** Search query or track and artist metadata. */
|
|
101
|
+
params) {
|
|
102
|
+
if (!params.q && !params.trackName)
|
|
103
|
+
throw new TypeError('Provide either q or trackName when searching lyrics.');
|
|
104
|
+
return this.request(`search?${toSnakeCase(params)}`);
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Send one serialized request to LRCLIB.
|
|
108
|
+
* @param path API path, with or without a leading slash.
|
|
109
|
+
* @param options Additional fetch options merged with the default GET request.
|
|
110
|
+
* @returns Parsed JSON response.
|
|
111
|
+
*/
|
|
112
|
+
async request(
|
|
113
|
+
/** API path, with or without a leading slash. */
|
|
114
|
+
path,
|
|
115
|
+
/** Additional fetch options merged with the default GET request. */
|
|
116
|
+
options = {}) {
|
|
117
|
+
let release;
|
|
118
|
+
const turn = new Promise((resolve) => {
|
|
119
|
+
release = resolve;
|
|
120
|
+
});
|
|
121
|
+
const previous = this.#tail;
|
|
122
|
+
this.#tail = previous.then(() => turn);
|
|
123
|
+
await previous;
|
|
124
|
+
try {
|
|
125
|
+
const url = `${this.api}${path.startsWith('/') ? path : `/${path}`}`;
|
|
126
|
+
this.player.debug(`[LrcLib] Requesting ${path}`);
|
|
127
|
+
for (let attempt = 0;; attempt++) {
|
|
128
|
+
const response = await fetch(url, {
|
|
129
|
+
method: 'GET',
|
|
130
|
+
redirect: 'follow',
|
|
131
|
+
...options,
|
|
132
|
+
signal: options.signal ?? AbortSignal.timeout(this.timeout),
|
|
133
|
+
headers: {
|
|
134
|
+
'User-Agent': `Discord-Player/${this.player.version}`,
|
|
135
|
+
'Content-Type': 'application/json',
|
|
136
|
+
...options.headers,
|
|
137
|
+
},
|
|
138
|
+
});
|
|
139
|
+
if (response.ok)
|
|
140
|
+
return (await response.json());
|
|
141
|
+
if ((response.status === 429 || response.status >= 500) && attempt < this.retryLimit) {
|
|
142
|
+
const retryAfter = Number(response.headers.get('retry-after'));
|
|
143
|
+
const delay = Number.isFinite(retryAfter) && retryAfter > 0 ? retryAfter * 1000 : Math.min(250 * 2 ** attempt, 4000);
|
|
144
|
+
await delayWait(delay, options.signal);
|
|
145
|
+
continue;
|
|
146
|
+
}
|
|
147
|
+
throw new Error(`LRCLIB request failed with HTTP ${response.status} ${response.statusText}.`);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
finally {
|
|
151
|
+
release();
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
/** Optional LRCLIB provider. No provider is installed by constructing a Player. */
|
|
156
|
+
export const lrclibPlugin = definePlugin({
|
|
157
|
+
id: 'org.lrclib',
|
|
158
|
+
setup(ctx) {
|
|
159
|
+
const client = new LrcLib({ version: 'plugin-host', debug: (message) => ctx.player.debug(message) });
|
|
160
|
+
ctx.on('lyrics.search', async ({ input }, { signal }) => {
|
|
161
|
+
const params = typeof input === 'string' ? { q: input } : { trackName: input.title, artistName: input.author };
|
|
162
|
+
const records = await client.request(`search?${toSnakeCase(params)}`, {
|
|
163
|
+
signal: AbortSignal.any([signal, AbortSignal.timeout(client.timeout)]),
|
|
164
|
+
});
|
|
165
|
+
return records.map((record) => ({
|
|
166
|
+
plain: record.plainLyrics
|
|
167
|
+
? { available: true, text: record.plainLyrics }
|
|
168
|
+
: { available: false },
|
|
169
|
+
synced: record.syncedLyrics
|
|
170
|
+
? { available: true, lines: parseLyrics(record.syncedLyrics) }
|
|
171
|
+
: { available: false },
|
|
172
|
+
metadata: {
|
|
173
|
+
id: record.id,
|
|
174
|
+
trackName: record.trackName,
|
|
175
|
+
artistName: record.artistName,
|
|
176
|
+
albumName: record.albumName,
|
|
177
|
+
instrumental: record.instrumental,
|
|
178
|
+
},
|
|
179
|
+
}));
|
|
180
|
+
});
|
|
181
|
+
},
|
|
182
|
+
});
|
|
183
|
+
//# sourceMappingURL=lrclib.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lrclib.js","sourceRoot":"","sources":["../../src/providers/lrclib.ts"],"names":[],"mappings":"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"}
|
package/dist/remote.d.ts
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { OperationName } from './plugins/types.js';
|
|
2
|
+
/** Existing standalone HTTP deployment. Authentication stays outside Track metadata. */
|
|
3
|
+
export interface RemotePluginHostOptions {
|
|
4
|
+
/** Stable deployment identity matching the audio node's configured host. */
|
|
5
|
+
hostId: string;
|
|
6
|
+
/** HTTP(S) origin without embedded credentials. */
|
|
7
|
+
url: string;
|
|
8
|
+
/** Optional bearer credential. */
|
|
9
|
+
token?: string;
|
|
10
|
+
/** Bounded discovery and execution deadline, default 15000ms. */
|
|
11
|
+
timeoutMs?: number;
|
|
12
|
+
}
|
|
13
|
+
/** Advertised provider capabilities from a standalone host. */
|
|
14
|
+
export interface RemoteProvider {
|
|
15
|
+
/** Actual provider identity, separate from deployment identity. */
|
|
16
|
+
id: string;
|
|
17
|
+
/** Implemented operation names. */
|
|
18
|
+
operations: OperationName[];
|
|
19
|
+
/** Registered source protocols. */
|
|
20
|
+
protocols: string[];
|
|
21
|
+
/** Advertised operation priorities, applied unless the client descriptor overrides them. */
|
|
22
|
+
priorities?: Partial<Record<OperationName, number>>;
|
|
23
|
+
}
|
|
24
|
+
/** Validate live advertised capabilities; no plugin is installed on the remote server.
|
|
25
|
+
* @param host Existing standalone deployment.
|
|
26
|
+
* @param signal Registration lifetime.
|
|
27
|
+
* @returns Actual remote provider declarations.
|
|
28
|
+
*/
|
|
29
|
+
export declare function discoverRemote(host: RemotePluginHostOptions, signal: AbortSignal): Promise<RemoteProvider[]>;
|
package/dist/remote.js
ADDED
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { lyricsResultSchema } from './lyrics.js';
|
|
3
|
+
import { deserializeSourceResult, serializeSourceTrack, } from './protocol.js';
|
|
4
|
+
import { Track } from './structures/track.js';
|
|
5
|
+
/** Fetch one authenticated metadata response through the current HTTP boundary.
|
|
6
|
+
* @internal
|
|
7
|
+
* @param host Existing deployment.
|
|
8
|
+
* @param path Discovery or execution path.
|
|
9
|
+
* @param signal Request cancellation.
|
|
10
|
+
* @param body Optional serialized execution request.
|
|
11
|
+
* @returns Parsed metadata; operational failures reject.
|
|
12
|
+
*/
|
|
13
|
+
export async function remoteMetadata(host, path, signal, body) {
|
|
14
|
+
const url = new URL(host.url);
|
|
15
|
+
if (!/^[a-zA-Z0-9][a-zA-Z0-9._-]{0,127}$/.test(host.hostId) ||
|
|
16
|
+
!['http:', 'https:'].includes(url.protocol) ||
|
|
17
|
+
url.username ||
|
|
18
|
+
url.password ||
|
|
19
|
+
url.pathname !== '/' ||
|
|
20
|
+
url.search ||
|
|
21
|
+
url.hash)
|
|
22
|
+
throw new TypeError('Source host requires a stable ID and an HTTP(S) origin without credentials');
|
|
23
|
+
if (!Number.isSafeInteger(host.timeoutMs ?? 15000) || (host.timeoutMs ?? 15000) < 1)
|
|
24
|
+
throw new RangeError('Source host timeout must be a positive safe integer');
|
|
25
|
+
const response = await fetch(`${url.origin}${path}`, {
|
|
26
|
+
method: body === undefined ? 'GET' : 'POST',
|
|
27
|
+
redirect: 'error',
|
|
28
|
+
signal: AbortSignal.any([signal, AbortSignal.timeout(host.timeoutMs ?? 15000)]),
|
|
29
|
+
headers: { 'content-type': 'application/json', ...(host.token ? { authorization: `Bearer ${host.token}` } : {}) },
|
|
30
|
+
...(body === undefined ? {} : { body: JSON.stringify(body) }),
|
|
31
|
+
});
|
|
32
|
+
if (!response.ok)
|
|
33
|
+
throw new Error(`Source host ${host.hostId}: metadata request failed (HTTP ${response.status})`);
|
|
34
|
+
return response.json();
|
|
35
|
+
}
|
|
36
|
+
/** Validate live advertised capabilities; no plugin is installed on the remote server.
|
|
37
|
+
* @param host Existing standalone deployment.
|
|
38
|
+
* @param signal Registration lifetime.
|
|
39
|
+
* @returns Actual remote provider declarations.
|
|
40
|
+
*/
|
|
41
|
+
export async function discoverRemote(host, signal) {
|
|
42
|
+
const manifest = await remoteMetadata(host, '/.well-known/remedia', signal);
|
|
43
|
+
if (!manifest ||
|
|
44
|
+
typeof manifest !== 'object' ||
|
|
45
|
+
!('protocolVersion' in manifest) ||
|
|
46
|
+
manifest.protocolVersion !== 1 ||
|
|
47
|
+
!('providers' in manifest) ||
|
|
48
|
+
!Array.isArray(manifest.providers))
|
|
49
|
+
throw new Error(`Source host ${host.hostId}: incompatible metadata manifest`);
|
|
50
|
+
if (!('hostId' in manifest) || manifest.hostId !== host.hostId)
|
|
51
|
+
throw new Error(`Source host ${host.hostId}: deployment identity does not match advertised host`);
|
|
52
|
+
return manifest.providers.map((provider) => {
|
|
53
|
+
if (!provider ||
|
|
54
|
+
typeof provider.id !== 'string' ||
|
|
55
|
+
!Array.isArray(provider.operations) ||
|
|
56
|
+
!provider.operations.every((name) => typeof name === 'string') ||
|
|
57
|
+
!Array.isArray(provider.protocols) ||
|
|
58
|
+
!provider.protocols.every((name) => typeof name === 'string'))
|
|
59
|
+
throw new TypeError('Invalid remote provider manifest');
|
|
60
|
+
if (provider.priorities !== undefined)
|
|
61
|
+
z.record(z.string(), z.number()).parse(provider.priorities);
|
|
62
|
+
return provider;
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
/** Register remote metadata operations into the ordinary capability registry.
|
|
66
|
+
* @internal
|
|
67
|
+
* @param ctx Registration owner.
|
|
68
|
+
* @param providerId Actual remote provider ID.
|
|
69
|
+
* @param host Existing deployment configuration.
|
|
70
|
+
* @param advertised Already validated discovery for a bulk host registration.
|
|
71
|
+
*/
|
|
72
|
+
export async function registerRemote(ctx, providerId, host, advertised) {
|
|
73
|
+
const provider = (advertised ?? (await discoverRemote(host, ctx.signal))).find((item) => item.id === providerId);
|
|
74
|
+
if (!provider)
|
|
75
|
+
throw new Error(`Source host ${host.hostId}: provider ${providerId} is not advertised`);
|
|
76
|
+
const execute = async (request, signal) => {
|
|
77
|
+
const envelope = await remoteMetadata(host, '/remedia/v1/execute', signal, {
|
|
78
|
+
pluginId: 'discord-player.source',
|
|
79
|
+
operation: 'metadata.execute',
|
|
80
|
+
input: request,
|
|
81
|
+
});
|
|
82
|
+
if (!envelope ||
|
|
83
|
+
typeof envelope !== 'object' ||
|
|
84
|
+
!('handled' in envelope) ||
|
|
85
|
+
envelope.handled !== true ||
|
|
86
|
+
!('result' in envelope))
|
|
87
|
+
throw new Error(`Source host ${host.hostId}: invalid metadata response`);
|
|
88
|
+
return envelope.result;
|
|
89
|
+
};
|
|
90
|
+
const portableQuery = (input) => {
|
|
91
|
+
const original = input.options ?? {};
|
|
92
|
+
return {
|
|
93
|
+
...input,
|
|
94
|
+
options: {
|
|
95
|
+
limit: original.limit,
|
|
96
|
+
blockExtractors: original.blockExtractors,
|
|
97
|
+
requestedBy: typeof original.requestedBy === 'object' ? original.requestedBy?.id : original.requestedBy,
|
|
98
|
+
},
|
|
99
|
+
};
|
|
100
|
+
};
|
|
101
|
+
if (provider.operations.includes('search.query.match')) {
|
|
102
|
+
ctx.on('search.query.match', async (input, { signal }) => {
|
|
103
|
+
const result = await execute({ providerId, operation: 'search.query.match', input: portableQuery(input) }, signal);
|
|
104
|
+
const matches = z
|
|
105
|
+
.array(z.object({ score: z.number(), pluginId: z.string().optional() }).nullable())
|
|
106
|
+
.parse(result);
|
|
107
|
+
return matches.find((match) => match !== null && match.score >= 0) ?? null;
|
|
108
|
+
}, { protocols: provider.protocols, priority: provider.priorities?.['search.query.match'] });
|
|
109
|
+
}
|
|
110
|
+
if (provider.operations.includes('search.query.resolve')) {
|
|
111
|
+
ctx.on('search.query.resolve', async (input, { signal }) => {
|
|
112
|
+
const result = deserializeSourceResult((await execute({ providerId, operation: 'search.query.resolve', input: portableQuery(input) }, signal)));
|
|
113
|
+
for (const track of result.tracks)
|
|
114
|
+
if (track.sourceReference?.pluginId !== providerId || track.sourceReference.hostId !== host.hostId)
|
|
115
|
+
throw new Error('Remote Track provider or deployment identity does not match its registration');
|
|
116
|
+
return result;
|
|
117
|
+
}, { protocols: provider.protocols, priority: provider.priorities?.['search.query.resolve'] });
|
|
118
|
+
}
|
|
119
|
+
if (provider.operations.includes('track.related')) {
|
|
120
|
+
ctx.on('track.related', async ({ track }, { signal }) => {
|
|
121
|
+
const result = await execute({ providerId, operation: 'track.related', input: { track: serializeSourceTrack(track) } }, signal);
|
|
122
|
+
return deserializeSourceResult(result);
|
|
123
|
+
}, { priority: provider.priorities?.['track.related'] });
|
|
124
|
+
}
|
|
125
|
+
if (provider.operations.includes('lyrics.search')) {
|
|
126
|
+
ctx.on('lyrics.search', async ({ input }, { signal }) => {
|
|
127
|
+
const result = await execute({
|
|
128
|
+
providerId,
|
|
129
|
+
operation: 'lyrics.search',
|
|
130
|
+
input: { input: input instanceof Track ? input.serialize() : input },
|
|
131
|
+
}, signal);
|
|
132
|
+
const groups = z.array(z.array(lyricsResultSchema).nullable()).parse(result);
|
|
133
|
+
return groups
|
|
134
|
+
.flatMap((group) => group ?? [])
|
|
135
|
+
.map((record) => ({
|
|
136
|
+
...record,
|
|
137
|
+
provider: { pluginId: providerId, hostId: host.hostId, data: record.provider?.data ?? null },
|
|
138
|
+
}));
|
|
139
|
+
}, { priority: provider.priorities?.['lyrics.search'] });
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
//# sourceMappingURL=remote.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"remote.js","sourceRoot":"","sources":["../src/remote.ts"],"names":[],"mappings":"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"}
|
package/dist/runtime.d.ts
CHANGED
|
@@ -7,6 +7,8 @@ import type { LegacyPlayerContext, SourceRuntimeEvents } from './legacy-player.j
|
|
|
7
7
|
import type { MediaResource, SearchOptions } from './types.js';
|
|
8
8
|
/** Standalone source configuration; no playback services are created. */
|
|
9
9
|
export interface SourcePluginRuntimeOptions {
|
|
10
|
+
/** Stable deployment identifier for standalone execution. */
|
|
11
|
+
hostId?: string;
|
|
10
12
|
/** Actual Player context when embedded. */
|
|
11
13
|
player?: LegacyPlayerContext;
|
|
12
14
|
/** Disabled provider IDs. */
|
|
@@ -28,20 +30,12 @@ export declare class SourcePluginRuntime extends SafeEventEmitter<SourceRuntimeE
|
|
|
28
30
|
* @param options Source settings and optional embedding context.
|
|
29
31
|
*/
|
|
30
32
|
constructor(options?: SourcePluginRuntimeOptions);
|
|
31
|
-
/** Queue orchestration requires an actual DiscordPlayer. */
|
|
32
|
-
get queues(): never;
|
|
33
|
-
/** Voice nodes require an actual DiscordPlayer. */
|
|
34
|
-
get nodes(): never;
|
|
35
|
-
/** Audio clients are unavailable in standalone source execution. */
|
|
36
|
-
get remedia(): never;
|
|
37
33
|
/** Required audio access is unavailable in standalone execution. */
|
|
38
34
|
getRemedia(): RemediaClient;
|
|
39
35
|
/** Optional audio access returns null.
|
|
40
36
|
* @param throwOnMissing Optional lookup flag.
|
|
41
37
|
*/
|
|
42
38
|
getRemedia(throwOnMissing: false): RemediaClient | null;
|
|
43
|
-
/** Playback is outside the source compatibility API. */
|
|
44
|
-
play(): never;
|
|
45
39
|
/** Emit a source diagnostic.
|
|
46
40
|
* @param message Diagnostic text.
|
|
47
41
|
*/
|