sonovault 1.1.0 → 2.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 CHANGED
@@ -3,7 +3,7 @@
3
3
  [![CI](https://github.com/rekordcloud/sonovault-js/actions/workflows/ci.yml/badge.svg)](https://github.com/rekordcloud/sonovault-js/actions/workflows/ci.yml)
4
4
  [![npm](https://img.shields.io/npm/v/sonovault)](https://www.npmjs.com/package/sonovault)
5
5
 
6
- TypeScript/Node client for the **[SonoVault](https://sonovault.now)** music metadata API. 90M+ 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.
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).
@@ -17,6 +17,8 @@ npm install sonovault
17
17
 
18
18
  Node 18+ (uses the built-in `fetch`). ESM and CommonJS both supported.
19
19
 
20
+ Use this library server-side. Shipping your API key in browser code exposes it to anyone who opens devtools. If a key leaks, rotate it in your [dashboard](https://sonovault.now/dashboard/keys).
21
+
20
22
  ## Quickstart
21
23
 
22
24
  ```ts
@@ -61,6 +63,16 @@ for (const row of batch.results) {
61
63
 
62
64
  List endpoints return `{ results, next_cursor }`. Pass the cursor back to get the next page. `next_cursor` is `null` on the last page.
63
65
 
66
+ ```ts
67
+ import { paginate } from "sonovault";
68
+
69
+ for await (const release of paginate((cursor) => sv.artists.releases(42, { cursor }))) {
70
+ console.log(release.title);
71
+ }
72
+ ```
73
+
74
+ Or walk the cursor yourself:
75
+
64
76
  ```ts
65
77
  let cursor: string | undefined;
66
78
  do {
@@ -88,11 +100,16 @@ try {
88
100
 
89
101
  Rate-limited responses that carry a `Retry-After` header are retried automatically. The default is 2 retries, configurable with `maxRetries`.
90
102
 
103
+
104
+ ## Examples
105
+
106
+ Runnable scripts live in [`examples/`](examples/): find an ISRC, resolve cross-platform links, enrich a play log, follow live stream events over SSE, and verify webhook deliveries.
107
+
91
108
  ## API coverage
92
109
 
93
110
  | Namespace | Methods |
94
111
  |---|---|
95
- | `sv.tracks` | `search`, `get`, `byIsrc`, `iswc`, `byIswc`, `links`, `resolve`, `identify`, `identifyAudio`, `browse` |
112
+ | `sv.tracks` | `search`, `get`, `byIsrc`, `iswc`, `byIswc`, `links`, `resolve`, `identifyAudio`, `browse` |
96
113
  | `sv.artists` | `search`, `get`, `releases` |
97
114
  | `sv.labels` | `search`, `get`, `releases`, `artists` |
98
115
  | `sv.releases` | `search`, `get`, `latest` |
package/dist/index.cjs CHANGED
@@ -22,6 +22,7 @@ var index_exports = {};
22
22
  __export(index_exports, {
23
23
  SonoVault: () => SonoVault,
24
24
  SonoVaultError: () => SonoVaultError,
25
+ paginate: () => paginate,
25
26
  verifyWebhookSignature: () => verifyWebhookSignature
26
27
  });
27
28
  module.exports = __toCommonJS(index_exports);
@@ -49,7 +50,7 @@ var SonoVaultError = class extends Error {
49
50
  };
50
51
 
51
52
  // src/version.ts
52
- var VERSION = "1.1.0";
53
+ var VERSION = "2.0.0";
53
54
 
54
55
  // src/client.ts
55
56
  var SonoVault = class {
@@ -72,8 +73,6 @@ var SonoVault = class {
72
73
  links: (params) => this.request("/v1/tracks/links", { query: params }),
73
74
  /** Resolve up to 100 track names, ISRCs, or platform IDs in one request. */
74
75
  resolve: (body) => this.request("/v1/tracks/resolve", { method: "POST", json: body }),
75
- /** Identify a track from a Chromaprint fingerprint (`fpcalc -raw`). Paid tiers. */
76
- identify: (body) => this.request("/v1/tracks/identify", { method: "POST", json: body }),
77
76
  /**
78
77
  * Identify a track from raw audio bytes (any ffmpeg-decodable format).
79
78
  * Send the whole track when you can — the matching section is often mid-track.
@@ -276,9 +275,20 @@ function verifyWebhookSignature(options) {
276
275
  const b = Buffer.from(expected);
277
276
  return a.length === b.length && (0, import_node_crypto.timingSafeEqual)(a, b);
278
277
  }
278
+
279
+ // src/pagination.ts
280
+ async function* paginate(fetchPage) {
281
+ let cursor;
282
+ do {
283
+ const page = await fetchPage(cursor);
284
+ for (const item of page.results) yield item;
285
+ cursor = page.next_cursor ?? void 0;
286
+ } while (cursor);
287
+ }
279
288
  // Annotate the CommonJS export names for ESM import in node:
280
289
  0 && (module.exports = {
281
290
  SonoVault,
282
291
  SonoVaultError,
292
+ paginate,
283
293
  verifyWebhookSignature
284
294
  });
package/dist/index.d.cts CHANGED
@@ -120,14 +120,6 @@ interface ResolveResponse {
120
120
  credits_remaining: number;
121
121
  message: string | null;
122
122
  }
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
123
  interface IdentifyResult {
132
124
  id: number;
133
125
  title: string;
@@ -238,8 +230,6 @@ declare class SonoVault {
238
230
  }) => Promise<PlatformLinksResponse>;
239
231
  /** Resolve up to 100 track names, ISRCs, or platform IDs in one request. */
240
232
  resolve: (body: ResolveRequest) => Promise<ResolveResponse>;
241
- /** Identify a track from a Chromaprint fingerprint (`fpcalc -raw`). Paid tiers. */
242
- identify: (body: IdentifyRequest) => Promise<IdentifyResponse>;
243
233
  /**
244
234
  * Identify a track from raw audio bytes (any ffmpeg-decodable format).
245
235
  * Send the whole track when you can — the matching section is often mid-track.
@@ -410,4 +400,17 @@ declare function verifyWebhookSignature(options: {
410
400
  toleranceSeconds?: number;
411
401
  }): boolean;
412
402
 
413
- export { type Artist, type Genre, type IdentifyRequest, 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 Track, type TrackArtist, type TrackRelease, type Webhook, verifyWebhookSignature };
403
+ /**
404
+ * Iterate every item across all pages of a cursor-paginated endpoint.
405
+ *
406
+ * ```ts
407
+ * import { paginate } from "sonovault";
408
+ *
409
+ * for await (const release of paginate((cursor) => sv.artists.releases(42, { cursor }))) {
410
+ * console.log(release.title);
411
+ * }
412
+ * ```
413
+ */
414
+ declare function paginate<T>(fetchPage: (cursor: string | undefined) => Promise<Page<T>>): AsyncGenerator<T>;
415
+
416
+ 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 Track, type TrackArtist, type TrackRelease, type Webhook, paginate, verifyWebhookSignature };
package/dist/index.d.ts CHANGED
@@ -120,14 +120,6 @@ interface ResolveResponse {
120
120
  credits_remaining: number;
121
121
  message: string | null;
122
122
  }
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
123
  interface IdentifyResult {
132
124
  id: number;
133
125
  title: string;
@@ -238,8 +230,6 @@ declare class SonoVault {
238
230
  }) => Promise<PlatformLinksResponse>;
239
231
  /** Resolve up to 100 track names, ISRCs, or platform IDs in one request. */
240
232
  resolve: (body: ResolveRequest) => Promise<ResolveResponse>;
241
- /** Identify a track from a Chromaprint fingerprint (`fpcalc -raw`). Paid tiers. */
242
- identify: (body: IdentifyRequest) => Promise<IdentifyResponse>;
243
233
  /**
244
234
  * Identify a track from raw audio bytes (any ffmpeg-decodable format).
245
235
  * Send the whole track when you can — the matching section is often mid-track.
@@ -410,4 +400,17 @@ declare function verifyWebhookSignature(options: {
410
400
  toleranceSeconds?: number;
411
401
  }): boolean;
412
402
 
413
- export { type Artist, type Genre, type IdentifyRequest, 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 Track, type TrackArtist, type TrackRelease, type Webhook, verifyWebhookSignature };
403
+ /**
404
+ * Iterate every item across all pages of a cursor-paginated endpoint.
405
+ *
406
+ * ```ts
407
+ * import { paginate } from "sonovault";
408
+ *
409
+ * for await (const release of paginate((cursor) => sv.artists.releases(42, { cursor }))) {
410
+ * console.log(release.title);
411
+ * }
412
+ * ```
413
+ */
414
+ declare function paginate<T>(fetchPage: (cursor: string | undefined) => Promise<Page<T>>): AsyncGenerator<T>;
415
+
416
+ 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 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 = "1.1.0";
24
+ var VERSION = "2.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.
@@ -248,8 +246,19 @@ function verifyWebhookSignature(options) {
248
246
  const b = Buffer.from(expected);
249
247
  return a.length === b.length && timingSafeEqual(a, b);
250
248
  }
249
+
250
+ // src/pagination.ts
251
+ async function* paginate(fetchPage) {
252
+ let cursor;
253
+ do {
254
+ const page = await fetchPage(cursor);
255
+ for (const item of page.results) yield item;
256
+ cursor = page.next_cursor ?? void 0;
257
+ } while (cursor);
258
+ }
251
259
  export {
252
260
  SonoVault,
253
261
  SonoVaultError,
262
+ paginate,
254
263
  verifyWebhookSignature
255
264
  };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "sonovault",
3
- "version": "1.1.0",
4
- "description": "TypeScript/Node client for the SonoVault music metadata API — ISRC, ISWC, genre, labels, release dates, and cross-platform IDs for 90M+ tracks.",
3
+ "version": "2.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",