@withpica/mcp-sdk 1.4.0 → 1.8.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/.mcpregistry_github_token +1 -0
- package/.mcpregistry_registry_token +1 -0
- package/CHANGELOG.md +278 -0
- package/dist/index.d.ts +479 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +365 -0
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -10,6 +10,7 @@ const LONG_TIMEOUT_PATTERNS = [
|
|
|
10
10
|
"/exports/",
|
|
11
11
|
"/enrichment/",
|
|
12
12
|
"/enrich",
|
|
13
|
+
"/resolve", // ADR-179 resolver fan-out (up to 5 sources per call)
|
|
13
14
|
"/industry-ready",
|
|
14
15
|
"/catalog-asset-report",
|
|
15
16
|
"/analyze",
|
|
@@ -51,6 +52,26 @@ class BaseResource {
|
|
|
51
52
|
this.apiKey = apiKey;
|
|
52
53
|
this.debug = debug;
|
|
53
54
|
}
|
|
55
|
+
/**
|
|
56
|
+
* Vercel Deployment Protection bypass header for preview self-fetches.
|
|
57
|
+
*
|
|
58
|
+
* When the SDK is used server-side on a Vercel preview (e.g. the MCP
|
|
59
|
+
* HTTP route calling back into its own admin resolve routes),
|
|
60
|
+
* Vercel's edge wraps the internal call in deployment protection and
|
|
61
|
+
* 401s before the request reaches the route handler. "Protection
|
|
62
|
+
* Bypass for Automation" auto-injects VERCEL_AUTOMATION_BYPASS_SECRET
|
|
63
|
+
* at runtime; forward it as the documented header so self-fetches
|
|
64
|
+
* reach the actual route. Empty outside Vercel — safe no-op.
|
|
65
|
+
*/
|
|
66
|
+
getBypassHeaders() {
|
|
67
|
+
if (typeof process !== "undefined" &&
|
|
68
|
+
process.env?.VERCEL_AUTOMATION_BYPASS_SECRET) {
|
|
69
|
+
return {
|
|
70
|
+
"x-vercel-protection-bypass": process.env.VERCEL_AUTOMATION_BYPASS_SECRET,
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
return {};
|
|
74
|
+
}
|
|
54
75
|
async fetchWithTimeout(url, init, timeoutMs) {
|
|
55
76
|
const controller = new AbortController();
|
|
56
77
|
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
@@ -122,6 +143,7 @@ class BaseResource {
|
|
|
122
143
|
headers: {
|
|
123
144
|
Authorization: `Bearer ${this.apiKey}`,
|
|
124
145
|
"Content-Type": "application/json",
|
|
146
|
+
...this.getBypassHeaders(),
|
|
125
147
|
},
|
|
126
148
|
body: body ? JSON.stringify(body) : undefined,
|
|
127
149
|
}, timeoutMs);
|
|
@@ -142,6 +164,7 @@ class BaseResource {
|
|
|
142
164
|
headers: {
|
|
143
165
|
Authorization: `Bearer ${this.apiKey}`,
|
|
144
166
|
"Content-Type": "application/json",
|
|
167
|
+
...this.getBypassHeaders(),
|
|
145
168
|
},
|
|
146
169
|
body: body ? JSON.stringify(body) : undefined,
|
|
147
170
|
}, timeoutMs);
|
|
@@ -202,6 +225,15 @@ class WorksResource extends BaseResource {
|
|
|
202
225
|
const result = await this.request("GET", `/admin/works/${workId}/production-assets`);
|
|
203
226
|
return result?.assets || [];
|
|
204
227
|
}
|
|
228
|
+
/**
|
|
229
|
+
* ADR-173 Decision 2: list every release this work appears on, with
|
|
230
|
+
* its track position. Distinct from listProductionAssets — this is
|
|
231
|
+
* release-context, not physical-asset provenance.
|
|
232
|
+
*/
|
|
233
|
+
async listReleases(workId) {
|
|
234
|
+
const result = await this.request("GET", `/admin/works/${workId}/releases`);
|
|
235
|
+
return result?.data || [];
|
|
236
|
+
}
|
|
205
237
|
}
|
|
206
238
|
class PeopleResource extends BaseResource {
|
|
207
239
|
async list(params) {
|
|
@@ -615,6 +647,15 @@ class RecordingsResource extends BaseResource {
|
|
|
615
647
|
const result = await this.request("GET", `/admin/recordings/${recordingId}/production-assets`);
|
|
616
648
|
return result?.assets || [];
|
|
617
649
|
}
|
|
650
|
+
/**
|
|
651
|
+
* ADR-173 Decision 2: list every release this recording appears on,
|
|
652
|
+
* with its track position. Backs the `releases` section on
|
|
653
|
+
* pica_recordings_inspect.
|
|
654
|
+
*/
|
|
655
|
+
async listReleases(recordingId) {
|
|
656
|
+
const result = await this.request("GET", `/admin/recordings/${recordingId}/releases`);
|
|
657
|
+
return result?.data || [];
|
|
658
|
+
}
|
|
618
659
|
}
|
|
619
660
|
// --- Enrichment Resource ---
|
|
620
661
|
class EnrichmentResource extends BaseResource {
|
|
@@ -645,6 +686,78 @@ class EnrichmentResource extends BaseResource {
|
|
|
645
686
|
async enrichWorkYouTube(workId) {
|
|
646
687
|
return this.request("POST", `/admin/youtube/enrich/${workId}`);
|
|
647
688
|
}
|
|
689
|
+
/**
|
|
690
|
+
* ADR-179 outcome resolver — fan a work out across every eligible
|
|
691
|
+
* enrichment source and return a structured receipt.
|
|
692
|
+
*
|
|
693
|
+
* The orchestration lives server-side (see
|
|
694
|
+
* `lib/services/enrichment-cascade/resolver.ts`); this SDK method is
|
|
695
|
+
* the thin wrapper the MCP tool layer calls. Future Tasks-primitive
|
|
696
|
+
* conversion (ADR-171) will turn the request into a Task so agents
|
|
697
|
+
* receive per-source status events as each provider resolves. Today
|
|
698
|
+
* the shape is the final receipt only — callers treat the object
|
|
699
|
+
* returned here as that single terminal event.
|
|
700
|
+
*
|
|
701
|
+
* sources: optional whitelist. Omit to fan out to every
|
|
702
|
+
* eligible source (mlc, spotify, youtube,
|
|
703
|
+
* musicbrainz, discogs).
|
|
704
|
+
* includeFuzzy: defaults true. When false, Tier B cascade rules
|
|
705
|
+
* (fuzzy matches that would file review proposals)
|
|
706
|
+
* are skipped entirely.
|
|
707
|
+
*/
|
|
708
|
+
async resolveWork(workId, options) {
|
|
709
|
+
const body = {};
|
|
710
|
+
if (options?.sources)
|
|
711
|
+
body.sources = options.sources;
|
|
712
|
+
if (options?.includeFuzzy !== undefined) {
|
|
713
|
+
body.include_fuzzy = options.includeFuzzy;
|
|
714
|
+
}
|
|
715
|
+
return this.request("POST", `/admin/works/${workId}/resolve`, body);
|
|
716
|
+
}
|
|
717
|
+
/**
|
|
718
|
+
* ADR-179 Phase 2 — person resolver. Fans a person across the two
|
|
719
|
+
* eligible identity-graph sources (ISNI + MusicBrainz) and returns
|
|
720
|
+
* a structured receipt in the same shape as `resolveWork`. Replaces
|
|
721
|
+
* the legacy `PeopleResource.enrichFromISNI` / `enrichFromMusicBrainz`
|
|
722
|
+
* calls at the MCP tool layer — those SDK methods stay available this
|
|
723
|
+
* release but are deprecated via `pica_people_enrich_*` returning
|
|
724
|
+
* `TOOL_DEPRECATED`.
|
|
725
|
+
*
|
|
726
|
+
* sources: optional whitelist. Omit to run both sources.
|
|
727
|
+
* Allowed: `isni` | `musicbrainz`.
|
|
728
|
+
* includeFuzzy: defaults true. When false, Tier B cascade rules
|
|
729
|
+
* (fuzzy matches that would file review proposals)
|
|
730
|
+
* are skipped entirely.
|
|
731
|
+
*/
|
|
732
|
+
async resolvePerson(personId, options) {
|
|
733
|
+
const body = {};
|
|
734
|
+
if (options?.sources)
|
|
735
|
+
body.sources = options.sources;
|
|
736
|
+
if (options?.includeFuzzy !== undefined) {
|
|
737
|
+
body.include_fuzzy = options.includeFuzzy;
|
|
738
|
+
}
|
|
739
|
+
return this.request("POST", `/admin/people/${personId}/resolve`, body);
|
|
740
|
+
}
|
|
741
|
+
/**
|
|
742
|
+
* ADR-179 Phase 3 — recording resolver. Fans a recording across eligible
|
|
743
|
+
* master-side sources (Spotify, YouTube, MusicBrainz, Discogs) and returns
|
|
744
|
+
* a structured receipt in the same shape as `resolveWork` / `resolvePerson`.
|
|
745
|
+
*
|
|
746
|
+
* sources: optional whitelist. Omit to run every eligible source.
|
|
747
|
+
* Allowed: `spotify` | `youtube` | `musicbrainz` | `discogs`.
|
|
748
|
+
* includeFuzzy: defaults true. When false, Tier B cascade rules
|
|
749
|
+
* (fuzzy matches that would file review proposals)
|
|
750
|
+
* are skipped entirely.
|
|
751
|
+
*/
|
|
752
|
+
async resolveRecording(recordingId, options) {
|
|
753
|
+
const body = {};
|
|
754
|
+
if (options?.sources)
|
|
755
|
+
body.sources = options.sources;
|
|
756
|
+
if (options?.includeFuzzy !== undefined) {
|
|
757
|
+
body.include_fuzzy = options.includeFuzzy;
|
|
758
|
+
}
|
|
759
|
+
return this.request("POST", `/admin/recordings/${recordingId}/resolve`, body);
|
|
760
|
+
}
|
|
648
761
|
/**
|
|
649
762
|
* ADR-164: manually re-evaluate a work against every cascade rule.
|
|
650
763
|
* Idempotent — rules whose preconditions are already satisfied skip.
|
|
@@ -717,6 +830,27 @@ class EnrichmentResource extends BaseResource {
|
|
|
717
830
|
async rejectEnrichmentProposal(proposalId, options) {
|
|
718
831
|
return this.request("POST", `/admin/enrichment-proposals/${proposalId}/reject`, options ?? {});
|
|
719
832
|
}
|
|
833
|
+
/**
|
|
834
|
+
* ADR-178: File a proposal sourced from open-web agent research.
|
|
835
|
+
*
|
|
836
|
+
* Distinct from cascade-sourced proposals. Every `proposed_fields`
|
|
837
|
+
* key must appear in at least one `sources[].fields` array —
|
|
838
|
+
* unsourced claims return a 400 with `code: "MISSING_SOURCE"` and
|
|
839
|
+
* the proposal is not persisted. The server hard-codes
|
|
840
|
+
* `source = 'agent_research'` and `rule_id = 'agent_research'`;
|
|
841
|
+
* callers omit both.
|
|
842
|
+
*
|
|
843
|
+
* Response codes carried through to the caller:
|
|
844
|
+
* - 201: `{ proposal_id, source, rule_id, status }` (pending)
|
|
845
|
+
* - 409 `DUPLICATE_SUPPRESSED`: identical content already filed
|
|
846
|
+
* - 400 `MISSING_SOURCE`: uncited proposed field or empty sources
|
|
847
|
+
* - 400 `MISSING_FIELDS`: proposed_fields was empty
|
|
848
|
+
* - 400 `INVALID_SOURCE_SHAPE`: a source entry lacked url/fields/accessed_at
|
|
849
|
+
* - 404 `ENTITY_NOT_FOUND`: entity_id not in caller's org
|
|
850
|
+
*/
|
|
851
|
+
async proposeAgentResearch(input) {
|
|
852
|
+
return this.request("POST", "/admin/enrichment-proposals", input);
|
|
853
|
+
}
|
|
720
854
|
/** Preview what a Spotify URL would do — delegates to streaming-link */
|
|
721
855
|
async spotifyUrlPreview(url) {
|
|
722
856
|
return this.request("POST", "/admin/import/streaming-link", { url });
|
|
@@ -830,6 +964,132 @@ class SettingsResource extends BaseResource {
|
|
|
830
964
|
async userProfile() {
|
|
831
965
|
return this.request("GET", "/admin/settings/user-profile");
|
|
832
966
|
}
|
|
967
|
+
/**
|
|
968
|
+
* Update the authenticated user's privacy / marketing-preference flags.
|
|
969
|
+
* Parity with ADR-183's settings-tab toggles — exposes the same fields
|
|
970
|
+
* the web UI writes, so an agent can unsubscribe on the user's behalf
|
|
971
|
+
* without leaving the conversation. ADR-184 slice 5.
|
|
972
|
+
*/
|
|
973
|
+
async updatePrivacySettings(params) {
|
|
974
|
+
return this.request("PATCH", "/admin/settings/user-profile", params);
|
|
975
|
+
}
|
|
976
|
+
/**
|
|
977
|
+
* Read the authenticated user's privacy / marketing-preference flags.
|
|
978
|
+
* Pulls from the same user-profile row the settings UI reads (ADR-184 slice
|
|
979
|
+
* 5 read-side sibling). Reuses the existing GET endpoint — no dedicated
|
|
980
|
+
* route needed; the MCP tool picks only the two privacy flags from the
|
|
981
|
+
* response so unrelated profile fields are not surfaced through this tool.
|
|
982
|
+
*/
|
|
983
|
+
async getPrivacySettings() {
|
|
984
|
+
return this.request("GET", "/admin/settings/user-profile");
|
|
985
|
+
}
|
|
986
|
+
/**
|
|
987
|
+
* Capture or update the authenticated user's own identifiers
|
|
988
|
+
* (stage_name, IPI, ISNI, IPN, PRO). Subject is always derived from
|
|
989
|
+
* the auth context — `user_id` is never accepted (ADR-184 rule 2).
|
|
990
|
+
*
|
|
991
|
+
* The route lazy-creates the backing `people` row if the user's
|
|
992
|
+
* `user_profiles.person_id` is null, then fires
|
|
993
|
+
* `crossLinkOnIdentifierUpdate` so newly-visible cross-org credits
|
|
994
|
+
* appear on the next `pica_discoveries_query`. Response includes the
|
|
995
|
+
* count of new discoveries in each of the 3 typed tables so the
|
|
996
|
+
* agent can surface "found N more…" in the same conversation.
|
|
997
|
+
* ADR-189 Phase 3.
|
|
998
|
+
*/
|
|
999
|
+
async updateMyIdentity(params) {
|
|
1000
|
+
return this.request("POST", "/admin/my-identity", params);
|
|
1001
|
+
}
|
|
1002
|
+
/**
|
|
1003
|
+
* Update the authenticated caller's organisation profile
|
|
1004
|
+
* (org_type, display_name, tagline, ipi_number). Scope bounded by
|
|
1005
|
+
* auth context — the org id is derived server-side, never accepted
|
|
1006
|
+
* as a parameter. Distinct from the settings-UI PUT at
|
|
1007
|
+
* `/admin/settings/organisation-profile`: this path validates
|
|
1008
|
+
* org_type against the CHECK enum, rate-limits, and stamps via
|
|
1009
|
+
* withAgentActionStamp for grant-auth callers (ADR-185 Part 3).
|
|
1010
|
+
* ADR-189 Phase 3.
|
|
1011
|
+
*/
|
|
1012
|
+
async updateOrganisationProfile(params) {
|
|
1013
|
+
return this.request("POST", "/admin/organisation-profile", params);
|
|
1014
|
+
}
|
|
1015
|
+
}
|
|
1016
|
+
// --- GDPR Resource (user self-service delete + export) ---
|
|
1017
|
+
class GdprResource extends BaseResource {
|
|
1018
|
+
/**
|
|
1019
|
+
* Create a soft-delete request for the authenticated user's account.
|
|
1020
|
+
* Never accepts a user_id — the subject is derived from the bearer token
|
|
1021
|
+
* (ADR-184 rule 2). Returns the deletion_request_id immediately; actual
|
|
1022
|
+
* erasure runs async through the gdpr-deletion processing path. Matches
|
|
1023
|
+
* the web UI's 30-day reversal window.
|
|
1024
|
+
*/
|
|
1025
|
+
async deleteMyAccount(params) {
|
|
1026
|
+
return this.request("POST", "/admin/gdpr/delete-my-account", params ?? {});
|
|
1027
|
+
}
|
|
1028
|
+
/**
|
|
1029
|
+
* Queue a GDPR Article 15 / 20 data export for the authenticated user.
|
|
1030
|
+
* Returns a job_id immediately; the signed download link is emailed when
|
|
1031
|
+
* the job completes. Format defaults to JSON (ADR-184 defers format
|
|
1032
|
+
* negotiation to a future parameter).
|
|
1033
|
+
*/
|
|
1034
|
+
async exportMyData() {
|
|
1035
|
+
return this.request("POST", "/admin/gdpr/export-my-data", {});
|
|
1036
|
+
}
|
|
1037
|
+
}
|
|
1038
|
+
// --- Feedback Resource (user feedback submissions) ---
|
|
1039
|
+
class FeedbackResource extends BaseResource {
|
|
1040
|
+
/**
|
|
1041
|
+
* Submit user feedback through the existing /api/feedback pipeline.
|
|
1042
|
+
* ADR-184 slice 8 — actionType is always of form `general_<category>`
|
|
1043
|
+
* so downstream teamTasksService.createFromGeneralFeedback routes
|
|
1044
|
+
* it to the correct team role.
|
|
1045
|
+
*/
|
|
1046
|
+
async submit(params) {
|
|
1047
|
+
return this.request("POST", "/feedback", params);
|
|
1048
|
+
}
|
|
1049
|
+
}
|
|
1050
|
+
// --- Agent Identity Resource (ADR-185 Part 1) ---
|
|
1051
|
+
/**
|
|
1052
|
+
* Session-auth-only surface: the three HTTP routes backing these
|
|
1053
|
+
* methods refuse `pica_grant_` callers with 403 `session_auth_required`
|
|
1054
|
+
* regardless of scope. When invoked via the stdio MCP server the caller
|
|
1055
|
+
* is an API key owned by the user, which passes; when invoked via HTTP
|
|
1056
|
+
* MCP behind a grant token the API rejects before any DB work.
|
|
1057
|
+
*/
|
|
1058
|
+
class AgentIdentityResource extends BaseResource {
|
|
1059
|
+
async createIdentity(params) {
|
|
1060
|
+
return this.request("POST", "/admin/agent-identities", {
|
|
1061
|
+
display_name: params.displayName,
|
|
1062
|
+
client_fingerprint: params.clientFingerprint ?? null,
|
|
1063
|
+
});
|
|
1064
|
+
}
|
|
1065
|
+
async listIdentities() {
|
|
1066
|
+
return this.request("GET", "/admin/agent-identities");
|
|
1067
|
+
}
|
|
1068
|
+
async issueGrant(params) {
|
|
1069
|
+
return this.request("POST", `/admin/agent-identities/${params.agentIdentityId}/grants`, {
|
|
1070
|
+
scopes: params.scopes,
|
|
1071
|
+
expires_at: params.expiresAt ?? null,
|
|
1072
|
+
});
|
|
1073
|
+
}
|
|
1074
|
+
async listMyGrants() {
|
|
1075
|
+
return this.request("GET", "/admin/agent-grants");
|
|
1076
|
+
}
|
|
1077
|
+
async revokeGrant(params) {
|
|
1078
|
+
return this.request("DELETE", `/admin/agent-grants/${params.grantId}`);
|
|
1079
|
+
}
|
|
1080
|
+
async getActivity(params) {
|
|
1081
|
+
const query = new URLSearchParams();
|
|
1082
|
+
if (params.agentIdentityId)
|
|
1083
|
+
query.set("agent_identity_id", params.agentIdentityId);
|
|
1084
|
+
if (params.agentGrantId)
|
|
1085
|
+
query.set("agent_grant_id", params.agentGrantId);
|
|
1086
|
+
if (typeof params.limit === "number")
|
|
1087
|
+
query.set("limit", String(params.limit));
|
|
1088
|
+
if (typeof params.offset === "number")
|
|
1089
|
+
query.set("offset", String(params.offset));
|
|
1090
|
+
const qs = query.toString();
|
|
1091
|
+
return this.request("GET", qs ? `/admin/agent-activity?${qs}` : "/admin/agent-activity");
|
|
1092
|
+
}
|
|
833
1093
|
}
|
|
834
1094
|
// --- Calendar Resource ---
|
|
835
1095
|
class CalendarResource extends BaseResource {
|
|
@@ -1220,6 +1480,9 @@ class ProjectsResource extends BaseResource {
|
|
|
1220
1480
|
async delete(id) {
|
|
1221
1481
|
return this.request("DELETE", `/admin/projects/${id}`);
|
|
1222
1482
|
}
|
|
1483
|
+
async attachWork(projectId, data) {
|
|
1484
|
+
return this.request("POST", `/admin/projects/${projectId}/works`, data);
|
|
1485
|
+
}
|
|
1223
1486
|
}
|
|
1224
1487
|
class SplitSheetsResource extends BaseResource {
|
|
1225
1488
|
async listForWork(workId) {
|
|
@@ -1263,6 +1526,18 @@ class PublishersResource extends BaseResource {
|
|
|
1263
1526
|
return this.request("POST", "/admin/publishers", data);
|
|
1264
1527
|
}
|
|
1265
1528
|
}
|
|
1529
|
+
class LabelsResource extends BaseResource {
|
|
1530
|
+
async list(params) {
|
|
1531
|
+
const queryParams = new URLSearchParams();
|
|
1532
|
+
if (params?.query)
|
|
1533
|
+
queryParams.set("query", params.query);
|
|
1534
|
+
if (params?.limit)
|
|
1535
|
+
queryParams.set("limit", String(params.limit));
|
|
1536
|
+
const qs = queryParams.toString();
|
|
1537
|
+
const res = await this.request("GET", `/admin/labels${qs ? `?${qs}` : ""}`);
|
|
1538
|
+
return (res?.data ?? []);
|
|
1539
|
+
}
|
|
1540
|
+
}
|
|
1266
1541
|
class ReleasesResource extends BaseResource {
|
|
1267
1542
|
async list(params) {
|
|
1268
1543
|
const qs = params?.limit ? `?limit=${params.limit}` : "";
|
|
@@ -1280,6 +1555,88 @@ class ReleasesResource extends BaseResource {
|
|
|
1280
1555
|
async delete(id) {
|
|
1281
1556
|
return this.request("DELETE", `/admin/releases/${id}`);
|
|
1282
1557
|
}
|
|
1558
|
+
/**
|
|
1559
|
+
* ADR-173: attach a recording and/or work to a release at a
|
|
1560
|
+
* specific (disc, track) position. Idempotent on position.
|
|
1561
|
+
*/
|
|
1562
|
+
async attachTrack(releaseId, data) {
|
|
1563
|
+
return this.request("POST", `/admin/releases/${releaseId}/tracks`, data);
|
|
1564
|
+
}
|
|
1565
|
+
/**
|
|
1566
|
+
* ADR-173: list tracks on a release in (disc, track) order with
|
|
1567
|
+
* inlined work + recording summary fields.
|
|
1568
|
+
*/
|
|
1569
|
+
async listTracks(releaseId) {
|
|
1570
|
+
return this.request("GET", `/admin/releases/${releaseId}/tracks`);
|
|
1571
|
+
}
|
|
1572
|
+
/**
|
|
1573
|
+
* ADR-173: soft-confirmation detach by position. Call without
|
|
1574
|
+
* confirm:true to get a preview; call with confirm:true to execute.
|
|
1575
|
+
*/
|
|
1576
|
+
async detachTrack(releaseId, data) {
|
|
1577
|
+
return this.request("POST", `/admin/releases/${releaseId}/tracks/detach`, data);
|
|
1578
|
+
}
|
|
1579
|
+
/**
|
|
1580
|
+
* ADR-173: transactional positional reorder. Input is the full
|
|
1581
|
+
* new order as [{ track_id, track_number, disc_number }].
|
|
1582
|
+
*/
|
|
1583
|
+
async reorderTracks(releaseId, newOrder) {
|
|
1584
|
+
return this.request("POST", `/admin/releases/${releaseId}/tracks/reorder`, {
|
|
1585
|
+
new_order: newOrder,
|
|
1586
|
+
});
|
|
1587
|
+
}
|
|
1588
|
+
/**
|
|
1589
|
+
* ADR-173 Decision 4: compound attach that resolves the
|
|
1590
|
+
* recording's work_id server-side before creating the track row.
|
|
1591
|
+
*/
|
|
1592
|
+
async attachRecordingWithWork(releaseId, data) {
|
|
1593
|
+
return this.request("POST", `/admin/releases/${releaseId}/tracks/attach-recording-with-work`, data);
|
|
1594
|
+
}
|
|
1595
|
+
/**
|
|
1596
|
+
* ADR-175 Decision 2: attach many tracks to a release atomically.
|
|
1597
|
+
* Duplicate (disc_number, track_number) pairs in the payload cause
|
|
1598
|
+
* the call to fail atomically — no rows are inserted.
|
|
1599
|
+
*/
|
|
1600
|
+
async bulkAttachTracks(releaseId, tracks) {
|
|
1601
|
+
return this.request("POST", `/admin/releases/${releaseId}/tracks/bulk-attach`, { tracks });
|
|
1602
|
+
}
|
|
1603
|
+
/**
|
|
1604
|
+
* ADR-175 Decision 3: swap two track positions on a release.
|
|
1605
|
+
*/
|
|
1606
|
+
async moveTrack(releaseId, from, to) {
|
|
1607
|
+
return this.request("POST", `/admin/releases/${releaseId}/tracks/move`, {
|
|
1608
|
+
from,
|
|
1609
|
+
to,
|
|
1610
|
+
});
|
|
1611
|
+
}
|
|
1612
|
+
/**
|
|
1613
|
+
* ADR-175 Decision 4: attach a track by external identifier. The SDK
|
|
1614
|
+
* resolves to an internal recording id server-side; on miss or
|
|
1615
|
+
* collision the route returns a 400 with a recovery hint and no row
|
|
1616
|
+
* is created.
|
|
1617
|
+
*/
|
|
1618
|
+
async attachTrackByIdentifier(releaseId, data) {
|
|
1619
|
+
return this.request("POST", `/admin/releases/${releaseId}/tracks/attach-by-identifier`, data);
|
|
1620
|
+
}
|
|
1621
|
+
/**
|
|
1622
|
+
* ADR-175 Decision 5: release-scoped completeness report. Pass a
|
|
1623
|
+
* release_id for a single-release report, or omit for a scan of every
|
|
1624
|
+
* release in the caller's organisation.
|
|
1625
|
+
*/
|
|
1626
|
+
async completenessCheck(params) {
|
|
1627
|
+
const qs = params?.release_id
|
|
1628
|
+
? `?release_id=${encodeURIComponent(params.release_id)}`
|
|
1629
|
+
: "";
|
|
1630
|
+
return this.request("GET", `/admin/releases/completeness-check${qs}`);
|
|
1631
|
+
}
|
|
1632
|
+
/**
|
|
1633
|
+
* ADR-175 Decision 1: create a release and its tracks in a single
|
|
1634
|
+
* atomic transaction. Track entries accept recording_id, work_id,
|
|
1635
|
+
* or identifier_lookup — whichever shape the agent has.
|
|
1636
|
+
*/
|
|
1637
|
+
async createWithTracks(data) {
|
|
1638
|
+
return this.request("POST", "/admin/releases/create-with-tracks", data);
|
|
1639
|
+
}
|
|
1283
1640
|
}
|
|
1284
1641
|
class SessionsResource extends BaseResource {
|
|
1285
1642
|
async list(params) {
|
|
@@ -1594,6 +1951,7 @@ export class PicaClient {
|
|
|
1594
1951
|
splitSheets;
|
|
1595
1952
|
recordingSplits;
|
|
1596
1953
|
publishers;
|
|
1954
|
+
labels;
|
|
1597
1955
|
agreementTemplates;
|
|
1598
1956
|
producerAgreements;
|
|
1599
1957
|
workForHire;
|
|
@@ -1604,6 +1962,9 @@ export class PicaClient {
|
|
|
1604
1962
|
disputes;
|
|
1605
1963
|
chain;
|
|
1606
1964
|
telegram;
|
|
1965
|
+
gdpr;
|
|
1966
|
+
feedback;
|
|
1967
|
+
agentIdentity;
|
|
1607
1968
|
/**
|
|
1608
1969
|
* Get accurate catalog stats via SQL counts (no pagination limits)
|
|
1609
1970
|
*/
|
|
@@ -1670,6 +2031,7 @@ export class PicaClient {
|
|
|
1670
2031
|
this.splitSheets = new SplitSheetsResource(baseUrl, config.apiKey, debug);
|
|
1671
2032
|
this.recordingSplits = new RecordingSplitsResource(baseUrl, config.apiKey, debug);
|
|
1672
2033
|
this.publishers = new PublishersResource(baseUrl, config.apiKey, debug);
|
|
2034
|
+
this.labels = new LabelsResource(baseUrl, config.apiKey, debug);
|
|
1673
2035
|
this.agreementTemplates = new AgreementTemplatesResource(baseUrl, config.apiKey, debug);
|
|
1674
2036
|
this.producerAgreements = new ProducerAgreementsResource(baseUrl, config.apiKey, debug);
|
|
1675
2037
|
this.workForHire = new WorkForHireResource(baseUrl, config.apiKey, debug);
|
|
@@ -1680,6 +2042,9 @@ export class PicaClient {
|
|
|
1680
2042
|
this.disputes = new DisputesResource(baseUrl, config.apiKey, debug);
|
|
1681
2043
|
this.chain = new ChainResource(baseUrl, config.apiKey, debug);
|
|
1682
2044
|
this.telegram = new TelegramResource(baseUrl, config.apiKey, debug);
|
|
2045
|
+
this.gdpr = new GdprResource(baseUrl, config.apiKey, debug);
|
|
2046
|
+
this.feedback = new FeedbackResource(baseUrl, config.apiKey, debug);
|
|
2047
|
+
this.agentIdentity = new AgentIdentityResource(baseUrl, config.apiKey, debug);
|
|
1683
2048
|
}
|
|
1684
2049
|
}
|
|
1685
2050
|
//# sourceMappingURL=index.js.map
|