sonovault 1.2.0 → 3.0.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 +2 -2
- package/dist/index.cjs +1 -3
- package/dist/index.d.cts +49 -22
- package/dist/index.d.ts +49 -22
- package/dist/index.js +1 -3
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
[](https://github.com/rekordcloud/sonovault-js/actions/workflows/ci.yml)
|
|
4
4
|
[](https://www.npmjs.com/package/sonovault)
|
|
5
5
|
|
|
6
|
-
TypeScript/Node client for the **[SonoVault](https://sonovault.now)** music metadata API.
|
|
6
|
+
TypeScript/Node client for the **[SonoVault](https://sonovault.now)** music metadata API. 93M+ tracks with ISRC, ISWC, genre, record label, canonical release dates, and cross-platform IDs for Spotify, Apple Music, Tidal, Beatport, Discogs, and MusicBrainz. One call resolves them all.
|
|
7
7
|
|
|
8
8
|
- **One key, no OAuth.** A single `x-api-key` header, no approval queue.
|
|
9
9
|
- **Free tier.** 1,000 requests/month, no credit card: [get an API key](https://sonovault.now).
|
|
@@ -109,7 +109,7 @@ Runnable scripts live in [`examples/`](examples/): find an ISRC, resolve cross-p
|
|
|
109
109
|
|
|
110
110
|
| Namespace | Methods |
|
|
111
111
|
|---|---|
|
|
112
|
-
| `sv.tracks` | `search`, `get`, `byIsrc`, `iswc`, `byIswc`, `links`, `resolve`, `
|
|
112
|
+
| `sv.tracks` | `search`, `get`, `byIsrc`, `iswc`, `byIswc`, `links`, `resolve`, `identifyAudio`, `browse` |
|
|
113
113
|
| `sv.artists` | `search`, `get`, `releases` |
|
|
114
114
|
| `sv.labels` | `search`, `get`, `releases`, `artists` |
|
|
115
115
|
| `sv.releases` | `search`, `get`, `latest` |
|
package/dist/index.cjs
CHANGED
|
@@ -50,7 +50,7 @@ var SonoVaultError = class extends Error {
|
|
|
50
50
|
};
|
|
51
51
|
|
|
52
52
|
// src/version.ts
|
|
53
|
-
var VERSION = "
|
|
53
|
+
var VERSION = "3.0.0";
|
|
54
54
|
|
|
55
55
|
// src/client.ts
|
|
56
56
|
var SonoVault = class {
|
|
@@ -73,8 +73,6 @@ var SonoVault = class {
|
|
|
73
73
|
links: (params) => this.request("/v1/tracks/links", { query: params }),
|
|
74
74
|
/** Resolve up to 100 track names, ISRCs, or platform IDs in one request. */
|
|
75
75
|
resolve: (body) => this.request("/v1/tracks/resolve", { method: "POST", json: body }),
|
|
76
|
-
/** Identify a track from a Chromaprint fingerprint (`fpcalc -raw`). Paid tiers. */
|
|
77
|
-
identify: (body) => this.request("/v1/tracks/identify", { method: "POST", json: body }),
|
|
78
76
|
/**
|
|
79
77
|
* Identify a track from raw audio bytes (any ffmpeg-decodable format).
|
|
80
78
|
* Send the whole track when you can — the matching section is often mid-track.
|
package/dist/index.d.cts
CHANGED
|
@@ -30,8 +30,10 @@ interface Track {
|
|
|
30
30
|
artists: TrackArtist[];
|
|
31
31
|
isrc: string | null;
|
|
32
32
|
duration: number | null;
|
|
33
|
-
|
|
34
|
-
|
|
33
|
+
/** Canonical genres. Empty array when the track is unclassified. */
|
|
34
|
+
genre: string[];
|
|
35
|
+
/** Canonical subgenres. Empty array when none apply. */
|
|
36
|
+
subgenre: string[];
|
|
35
37
|
}
|
|
36
38
|
/** A cursor-paginated page. `next_cursor` is null on the last page. */
|
|
37
39
|
interface Page<T> {
|
|
@@ -66,10 +68,10 @@ interface Release {
|
|
|
66
68
|
interface Genre {
|
|
67
69
|
id: number;
|
|
68
70
|
name: string;
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
71
|
+
/** Whether this is a top-level genre or a subgenre. */
|
|
72
|
+
type: "main" | "subgenre";
|
|
73
|
+
/** Name of the parent genre; null for a top-level genre. */
|
|
74
|
+
parent: string | null;
|
|
73
75
|
[key: string]: unknown;
|
|
74
76
|
}
|
|
75
77
|
/** A track's ID on an external platform, with a deep link. */
|
|
@@ -81,6 +83,8 @@ interface PlatformLink {
|
|
|
81
83
|
interface PlatformLinksResponse {
|
|
82
84
|
track_id: number;
|
|
83
85
|
title: string;
|
|
86
|
+
/** One representative ISRC for the track; null when none is known. */
|
|
87
|
+
isrc: string | null;
|
|
84
88
|
links: PlatformLink[];
|
|
85
89
|
[key: string]: unknown;
|
|
86
90
|
}
|
|
@@ -120,14 +124,6 @@ interface ResolveResponse {
|
|
|
120
124
|
credits_remaining: number;
|
|
121
125
|
message: string | null;
|
|
122
126
|
}
|
|
123
|
-
interface IdentifyRequest {
|
|
124
|
-
/** 50–50,000 integers from `fpcalc -raw` (Chromaprint). */
|
|
125
|
-
fingerprint: number[];
|
|
126
|
-
/** Clip duration in seconds. */
|
|
127
|
-
fingerprint_duration?: number;
|
|
128
|
-
/** Max results to return, 1–25. */
|
|
129
|
-
top_n?: number;
|
|
130
|
-
}
|
|
131
127
|
interface IdentifyResult {
|
|
132
128
|
id: number;
|
|
133
129
|
title: string;
|
|
@@ -143,11 +139,44 @@ interface IdentifyResponse {
|
|
|
143
139
|
}
|
|
144
140
|
interface Stream {
|
|
145
141
|
id: string;
|
|
146
|
-
url
|
|
147
|
-
name
|
|
148
|
-
status
|
|
142
|
+
url: string;
|
|
143
|
+
name: string | null;
|
|
144
|
+
status: "active" | "stopped";
|
|
145
|
+
detection_mode: "precise" | "balanced" | "broad";
|
|
146
|
+
/** Whether we email you when this stream goes down and when it recovers. */
|
|
147
|
+
outage_notifications: boolean;
|
|
148
|
+
created_at: string;
|
|
149
|
+
stopped_at: string | null;
|
|
149
150
|
[key: string]: unknown;
|
|
150
151
|
}
|
|
152
|
+
/**
|
|
153
|
+
* A stream's live state, as returned by `streams.get()`: the stream fields plus
|
|
154
|
+
* what is playing right now.
|
|
155
|
+
*/
|
|
156
|
+
interface StreamStatus extends Stream {
|
|
157
|
+
/** What the monitor is doing now: `pending`, `running`, `errored` or `stopped`. */
|
|
158
|
+
runtime_status: string;
|
|
159
|
+
/** Why it is in that state (e.g. an auth wall on the host); null when it is fine. */
|
|
160
|
+
status_reason: string | null;
|
|
161
|
+
/** Null during ad breaks, talk, or audio we cannot place. */
|
|
162
|
+
now_playing: {
|
|
163
|
+
track: Track;
|
|
164
|
+
started_at: string;
|
|
165
|
+
} | null;
|
|
166
|
+
last_recognized_at: string | null;
|
|
167
|
+
/** Recognition tuning hint in force; null means auto (all recognisers). */
|
|
168
|
+
format: "electronic" | "classical" | "pop" | null;
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* The response to `streams.update()`. The API echoes back only the fields you
|
|
172
|
+
* changed, so everything but `id` is optional.
|
|
173
|
+
*/
|
|
174
|
+
interface StreamUpdateResponse {
|
|
175
|
+
id: string;
|
|
176
|
+
format?: "electronic" | "classical" | "pop" | null;
|
|
177
|
+
detection_mode?: "precise" | "balanced" | "broad";
|
|
178
|
+
outage_notifications?: boolean;
|
|
179
|
+
}
|
|
151
180
|
interface Webhook {
|
|
152
181
|
id: string;
|
|
153
182
|
url: string;
|
|
@@ -238,8 +267,6 @@ declare class SonoVault {
|
|
|
238
267
|
}) => Promise<PlatformLinksResponse>;
|
|
239
268
|
/** Resolve up to 100 track names, ISRCs, or platform IDs in one request. */
|
|
240
269
|
resolve: (body: ResolveRequest) => Promise<ResolveResponse>;
|
|
241
|
-
/** Identify a track from a Chromaprint fingerprint (`fpcalc -raw`). Paid tiers. */
|
|
242
|
-
identify: (body: IdentifyRequest) => Promise<IdentifyResponse>;
|
|
243
270
|
/**
|
|
244
271
|
* Identify a track from raw audio bytes (any ffmpeg-decodable format).
|
|
245
272
|
* Send the whole track when you can — the matching section is often mid-track.
|
|
@@ -323,8 +350,8 @@ declare class SonoVault {
|
|
|
323
350
|
list: () => Promise<{
|
|
324
351
|
streams: Stream[];
|
|
325
352
|
}>;
|
|
326
|
-
get: (id: string) => Promise<
|
|
327
|
-
update: (id: string, body: Record<string, unknown>) => Promise<
|
|
353
|
+
get: (id: string) => Promise<StreamStatus>;
|
|
354
|
+
update: (id: string, body: Record<string, unknown>) => Promise<StreamUpdateResponse>;
|
|
328
355
|
history: (id: string, params?: {
|
|
329
356
|
since?: string;
|
|
330
357
|
}) => Promise<Record<string, unknown>>;
|
|
@@ -423,4 +450,4 @@ declare function verifyWebhookSignature(options: {
|
|
|
423
450
|
*/
|
|
424
451
|
declare function paginate<T>(fetchPage: (cursor: string | undefined) => Promise<Page<T>>): AsyncGenerator<T>;
|
|
425
452
|
|
|
426
|
-
export { type Artist, type Genre, type
|
|
453
|
+
export { type Artist, type Genre, type IdentifyResponse, type IdentifyResult, type IswcLookupResponse, type Label, type Page, type PlatformLink, type PlatformLinksResponse, type Release, type ResolveInputType, type ResolveRequest, type ResolveResponse, type ResolveResult, SonoVault, SonoVaultError, type SonoVaultOptions, type Stream, type StreamEvent, type StreamStatus, type StreamUpdateResponse, type Track, type TrackArtist, type TrackRelease, type Webhook, paginate, verifyWebhookSignature };
|
package/dist/index.d.ts
CHANGED
|
@@ -30,8 +30,10 @@ interface Track {
|
|
|
30
30
|
artists: TrackArtist[];
|
|
31
31
|
isrc: string | null;
|
|
32
32
|
duration: number | null;
|
|
33
|
-
|
|
34
|
-
|
|
33
|
+
/** Canonical genres. Empty array when the track is unclassified. */
|
|
34
|
+
genre: string[];
|
|
35
|
+
/** Canonical subgenres. Empty array when none apply. */
|
|
36
|
+
subgenre: string[];
|
|
35
37
|
}
|
|
36
38
|
/** A cursor-paginated page. `next_cursor` is null on the last page. */
|
|
37
39
|
interface Page<T> {
|
|
@@ -66,10 +68,10 @@ interface Release {
|
|
|
66
68
|
interface Genre {
|
|
67
69
|
id: number;
|
|
68
70
|
name: string;
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
71
|
+
/** Whether this is a top-level genre or a subgenre. */
|
|
72
|
+
type: "main" | "subgenre";
|
|
73
|
+
/** Name of the parent genre; null for a top-level genre. */
|
|
74
|
+
parent: string | null;
|
|
73
75
|
[key: string]: unknown;
|
|
74
76
|
}
|
|
75
77
|
/** A track's ID on an external platform, with a deep link. */
|
|
@@ -81,6 +83,8 @@ interface PlatformLink {
|
|
|
81
83
|
interface PlatformLinksResponse {
|
|
82
84
|
track_id: number;
|
|
83
85
|
title: string;
|
|
86
|
+
/** One representative ISRC for the track; null when none is known. */
|
|
87
|
+
isrc: string | null;
|
|
84
88
|
links: PlatformLink[];
|
|
85
89
|
[key: string]: unknown;
|
|
86
90
|
}
|
|
@@ -120,14 +124,6 @@ interface ResolveResponse {
|
|
|
120
124
|
credits_remaining: number;
|
|
121
125
|
message: string | null;
|
|
122
126
|
}
|
|
123
|
-
interface IdentifyRequest {
|
|
124
|
-
/** 50–50,000 integers from `fpcalc -raw` (Chromaprint). */
|
|
125
|
-
fingerprint: number[];
|
|
126
|
-
/** Clip duration in seconds. */
|
|
127
|
-
fingerprint_duration?: number;
|
|
128
|
-
/** Max results to return, 1–25. */
|
|
129
|
-
top_n?: number;
|
|
130
|
-
}
|
|
131
127
|
interface IdentifyResult {
|
|
132
128
|
id: number;
|
|
133
129
|
title: string;
|
|
@@ -143,11 +139,44 @@ interface IdentifyResponse {
|
|
|
143
139
|
}
|
|
144
140
|
interface Stream {
|
|
145
141
|
id: string;
|
|
146
|
-
url
|
|
147
|
-
name
|
|
148
|
-
status
|
|
142
|
+
url: string;
|
|
143
|
+
name: string | null;
|
|
144
|
+
status: "active" | "stopped";
|
|
145
|
+
detection_mode: "precise" | "balanced" | "broad";
|
|
146
|
+
/** Whether we email you when this stream goes down and when it recovers. */
|
|
147
|
+
outage_notifications: boolean;
|
|
148
|
+
created_at: string;
|
|
149
|
+
stopped_at: string | null;
|
|
149
150
|
[key: string]: unknown;
|
|
150
151
|
}
|
|
152
|
+
/**
|
|
153
|
+
* A stream's live state, as returned by `streams.get()`: the stream fields plus
|
|
154
|
+
* what is playing right now.
|
|
155
|
+
*/
|
|
156
|
+
interface StreamStatus extends Stream {
|
|
157
|
+
/** What the monitor is doing now: `pending`, `running`, `errored` or `stopped`. */
|
|
158
|
+
runtime_status: string;
|
|
159
|
+
/** Why it is in that state (e.g. an auth wall on the host); null when it is fine. */
|
|
160
|
+
status_reason: string | null;
|
|
161
|
+
/** Null during ad breaks, talk, or audio we cannot place. */
|
|
162
|
+
now_playing: {
|
|
163
|
+
track: Track;
|
|
164
|
+
started_at: string;
|
|
165
|
+
} | null;
|
|
166
|
+
last_recognized_at: string | null;
|
|
167
|
+
/** Recognition tuning hint in force; null means auto (all recognisers). */
|
|
168
|
+
format: "electronic" | "classical" | "pop" | null;
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* The response to `streams.update()`. The API echoes back only the fields you
|
|
172
|
+
* changed, so everything but `id` is optional.
|
|
173
|
+
*/
|
|
174
|
+
interface StreamUpdateResponse {
|
|
175
|
+
id: string;
|
|
176
|
+
format?: "electronic" | "classical" | "pop" | null;
|
|
177
|
+
detection_mode?: "precise" | "balanced" | "broad";
|
|
178
|
+
outage_notifications?: boolean;
|
|
179
|
+
}
|
|
151
180
|
interface Webhook {
|
|
152
181
|
id: string;
|
|
153
182
|
url: string;
|
|
@@ -238,8 +267,6 @@ declare class SonoVault {
|
|
|
238
267
|
}) => Promise<PlatformLinksResponse>;
|
|
239
268
|
/** Resolve up to 100 track names, ISRCs, or platform IDs in one request. */
|
|
240
269
|
resolve: (body: ResolveRequest) => Promise<ResolveResponse>;
|
|
241
|
-
/** Identify a track from a Chromaprint fingerprint (`fpcalc -raw`). Paid tiers. */
|
|
242
|
-
identify: (body: IdentifyRequest) => Promise<IdentifyResponse>;
|
|
243
270
|
/**
|
|
244
271
|
* Identify a track from raw audio bytes (any ffmpeg-decodable format).
|
|
245
272
|
* Send the whole track when you can — the matching section is often mid-track.
|
|
@@ -323,8 +350,8 @@ declare class SonoVault {
|
|
|
323
350
|
list: () => Promise<{
|
|
324
351
|
streams: Stream[];
|
|
325
352
|
}>;
|
|
326
|
-
get: (id: string) => Promise<
|
|
327
|
-
update: (id: string, body: Record<string, unknown>) => Promise<
|
|
353
|
+
get: (id: string) => Promise<StreamStatus>;
|
|
354
|
+
update: (id: string, body: Record<string, unknown>) => Promise<StreamUpdateResponse>;
|
|
328
355
|
history: (id: string, params?: {
|
|
329
356
|
since?: string;
|
|
330
357
|
}) => Promise<Record<string, unknown>>;
|
|
@@ -423,4 +450,4 @@ declare function verifyWebhookSignature(options: {
|
|
|
423
450
|
*/
|
|
424
451
|
declare function paginate<T>(fetchPage: (cursor: string | undefined) => Promise<Page<T>>): AsyncGenerator<T>;
|
|
425
452
|
|
|
426
|
-
export { type Artist, type Genre, type
|
|
453
|
+
export { type Artist, type Genre, type IdentifyResponse, type IdentifyResult, type IswcLookupResponse, type Label, type Page, type PlatformLink, type PlatformLinksResponse, type Release, type ResolveInputType, type ResolveRequest, type ResolveResponse, type ResolveResult, SonoVault, SonoVaultError, type SonoVaultOptions, type Stream, type StreamEvent, type StreamStatus, type StreamUpdateResponse, type Track, type TrackArtist, type TrackRelease, type Webhook, paginate, verifyWebhookSignature };
|
package/dist/index.js
CHANGED
|
@@ -21,7 +21,7 @@ var SonoVaultError = class extends Error {
|
|
|
21
21
|
};
|
|
22
22
|
|
|
23
23
|
// src/version.ts
|
|
24
|
-
var VERSION = "
|
|
24
|
+
var VERSION = "3.0.0";
|
|
25
25
|
|
|
26
26
|
// src/client.ts
|
|
27
27
|
var SonoVault = class {
|
|
@@ -44,8 +44,6 @@ var SonoVault = class {
|
|
|
44
44
|
links: (params) => this.request("/v1/tracks/links", { query: params }),
|
|
45
45
|
/** Resolve up to 100 track names, ISRCs, or platform IDs in one request. */
|
|
46
46
|
resolve: (body) => this.request("/v1/tracks/resolve", { method: "POST", json: body }),
|
|
47
|
-
/** Identify a track from a Chromaprint fingerprint (`fpcalc -raw`). Paid tiers. */
|
|
48
|
-
identify: (body) => this.request("/v1/tracks/identify", { method: "POST", json: body }),
|
|
49
47
|
/**
|
|
50
48
|
* Identify a track from raw audio bytes (any ffmpeg-decodable format).
|
|
51
49
|
* Send the whole track when you can — the matching section is often mid-track.
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sonovault",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "TypeScript/Node client for the SonoVault music metadata API — ISRC, ISWC, genre, labels, release dates, and cross-platform IDs for
|
|
3
|
+
"version": "3.0.0",
|
|
4
|
+
"description": "TypeScript/Node client for the SonoVault music metadata API — ISRC, ISWC, genre, labels, release dates, and cross-platform IDs for 93M+ tracks.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"music",
|
|
7
7
|
"metadata",
|