1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
import { fetchJSON } from "https://esm.town/v/axelav/fetchJSON";
import process from "node:process";
export async function discogs(
request: express.Request,
response: express.Response
) {
console.log("Request!", request);
interface Artist {
name: string;
join: string;
}
interface RecordLabel {
name: string;
}
interface DiscogsRelease {
artists: Artist[];
title: string;
year: number;
genres: string[];
styles: string[];
labels: RecordLabel[];
master_id?: string;
main_release?: string;
uri: string;
id: string;
}
const token = process.env.DISCOGS_API_TOKEN;
const toLowerCaseAndSort = (list: string[]) =>
list.map((t) => t.toLowerCase()).sort();
const unique = (x: string, idx: number, self: string[]) =>
self.indexOf(x) === idx;
const getLabel = (list: RecordLabel[]) => {
const noLabelText = "Not On Label";
if (!list || !list.length) {
return noLabelText;
}
const first = list[0]?.name;
// Use generic not on label text; strip parentheticals eg. "Not On Label (Self-released)"
if (first.match(noLabelText)) {
return noLabelText;
}
// Trim any parenthetical marks from label name
return first.trim().replace(/\s\(\d+\)/g, "");
};
const addSpaceAfterJoin = (artist: Artist) => {
const join = artist.join;
if (join) {
return join.replace(/(\/)/g, "$1 ");
}
return "";
};
const formatArtist = (artist: Artist) => {
// Remove any parenthetical marks from artist name
const name = artist.name.trim().replace(/\s\(\d+\)/g, "");
const join = addSpaceAfterJoin(artist);
// This isn't perfect. Some joins needs spaces before and after, some after, etc...
return `${name}${join}`;
};
const formatRelease = (release: DiscogsRelease) => {
const {
artists = [],
title,
year,
genres = [],
styles = [],
labels = [],
} = release;
return {
artist: artists.reduce((acc, x) => `${acc}${formatArtist(x)}`, ""),
title,
year,
label: getLabel(labels),
tags: [
...toLowerCaseAndSort(genres),
...toLowerCaseAndSort(styles),
].filter(unique),
url: release.uri,
};
};
const getSearchResults = async (
query: string,
isMaster = true
): Promise<{
results: DiscogsRelease[];
}> =>
fetchJSON(
`https://api.discogs.com/database/search?token=${token}&q=${query}${
isMaster ? "&type=master" : ""
}`
);
const getMasterRelease = async (id: string): Promise<DiscogsRelease> =>
fetchJSON(
`https://api.discogs.com/masters/${id}?token=${token}`
);
const getMainRelease = async (id: string): Promise<DiscogsRelease> =>
fetchJSON(
`https://api.discogs.com/releases/${id}?token=${token}`
);
const params = request.params;
👆 This is a val. Vals are TypeScript snippets of code, written in the browser and run on our servers. Create scheduled functions, email yourself, and persist small pieces of data — all from the browser.