mirror of
https://github.com/20kaushik02/spotify-manager.git
synced 2025-12-06 08:04:06 +00:00
package (and their typing) updates
This commit is contained in:
parent
5e4396031e
commit
935a18f2cc
@ -4,11 +4,11 @@ import logger from "../utils/logger.ts";
|
|||||||
|
|
||||||
const __controller_func: RequestHandler = async (req, res) => {
|
const __controller_func: RequestHandler = async (req, res) => {
|
||||||
try {
|
try {
|
||||||
return null;
|
return;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
res.status(500).send({ message: "Internal Server Error" });
|
res.status(500).send({ message: "Internal Server Error" });
|
||||||
logger.error("__controller_func", { error });
|
logger.error("__controller_func", { error });
|
||||||
return null;
|
return;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -9,7 +9,8 @@ if (!process.env["SPOTMGR_REDIS_URI"])
|
|||||||
const redisClient: ReturnType<typeof createClient> = createClient({
|
const redisClient: ReturnType<typeof createClient> = createClient({
|
||||||
url: process.env["SPOTMGR_REDIS_URI"],
|
url: process.env["SPOTMGR_REDIS_URI"],
|
||||||
socket: {
|
socket: {
|
||||||
keepAlive: 25 * 1000, // 25s
|
keepAlive: true,
|
||||||
|
keepAliveInitialDelay: 25 * 1000, // 25s
|
||||||
connectTimeout: 15 * 1000,
|
connectTimeout: 15 * 1000,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@ -31,11 +31,11 @@ const login: RequestHandler = async (_req, res) => {
|
|||||||
state: state,
|
state: state,
|
||||||
} as Record<string, string>).toString()
|
} as Record<string, string>).toString()
|
||||||
);
|
);
|
||||||
return null;
|
return;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
res.status(500).send({ message: "Internal Server Error" });
|
res.status(500).send({ message: "Internal Server Error" });
|
||||||
logger.error("login", { error });
|
logger.error("login", { error });
|
||||||
return null;
|
return;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -52,11 +52,11 @@ const callback: RequestHandler = async (req, res) => {
|
|||||||
if (state === null || state !== storedState) {
|
if (state === null || state !== storedState) {
|
||||||
res.status(409).send({ message: "Invalid state" });
|
res.status(409).send({ message: "Invalid state" });
|
||||||
logger.warn("state mismatch");
|
logger.warn("state mismatch");
|
||||||
return null;
|
return;
|
||||||
} else if (error) {
|
} else if (error) {
|
||||||
res.status(401).send({ message: "Auth callback error" });
|
res.status(401).send({ message: "Auth callback error" });
|
||||||
logger.error("callback error", { error });
|
logger.error("callback error", { error });
|
||||||
return null;
|
return;
|
||||||
} else {
|
} else {
|
||||||
// get auth tokens
|
// get auth tokens
|
||||||
res.clearCookie(stateKey);
|
res.clearCookie(stateKey);
|
||||||
@ -83,14 +83,14 @@ const callback: RequestHandler = async (req, res) => {
|
|||||||
.status(tokenResponse.status)
|
.status(tokenResponse.status)
|
||||||
.send({ message: "Error: Login failed" });
|
.send({ message: "Error: Login failed" });
|
||||||
logger.error("login failed", { statusCode: tokenResponse.status });
|
logger.error("login failed", { statusCode: tokenResponse.status });
|
||||||
return null;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const { resp } = await getCurrentUsersProfile({
|
const { resp } = await getCurrentUsersProfile({
|
||||||
res,
|
res,
|
||||||
authHeaders,
|
authHeaders,
|
||||||
});
|
});
|
||||||
if (!resp) return null;
|
if (!resp) return;
|
||||||
|
|
||||||
req.session.user = {
|
req.session.user = {
|
||||||
username: resp.data.display_name ?? "",
|
username: resp.data.display_name ?? "",
|
||||||
@ -105,14 +105,14 @@ const callback: RequestHandler = async (req, res) => {
|
|||||||
res.redirect(process.env["SPOTMGR_APP_URI"] + "?login=success");
|
res.redirect(process.env["SPOTMGR_APP_URI"] + "?login=success");
|
||||||
logger.debug("New login.", { username: resp.data.display_name });
|
logger.debug("New login.", { username: resp.data.display_name });
|
||||||
}
|
}
|
||||||
return null;
|
return;
|
||||||
});
|
});
|
||||||
return null;
|
return;
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
res.status(500).send({ message: "Internal Server Error" });
|
res.status(500).send({ message: "Internal Server Error" });
|
||||||
logger.error("callback", { error });
|
logger.error("callback", { error });
|
||||||
return null;
|
return;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -144,7 +144,7 @@ const refresh: RequestHandler = async (req, res) => {
|
|||||||
: ""
|
: ""
|
||||||
}.`
|
}.`
|
||||||
);
|
);
|
||||||
return null;
|
return;
|
||||||
} else {
|
} else {
|
||||||
res
|
res
|
||||||
.status(response.status)
|
.status(response.status)
|
||||||
@ -153,12 +153,12 @@ const refresh: RequestHandler = async (req, res) => {
|
|||||||
statusCode: response.status,
|
statusCode: response.status,
|
||||||
data: response.data,
|
data: response.data,
|
||||||
});
|
});
|
||||||
return null;
|
return;
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
res.status(500).send({ message: "Internal Server Error" });
|
res.status(500).send({ message: "Internal Server Error" });
|
||||||
logger.error("refresh", { error });
|
logger.error("refresh", { error });
|
||||||
return null;
|
return;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -178,11 +178,11 @@ const logout: RequestHandler = async (req, res) => {
|
|||||||
logger.debug("Logged out.", { sessionID: delSession.id });
|
logger.debug("Logged out.", { sessionID: delSession.id });
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return null;
|
return;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
res.status(500).send({ message: "Internal Server Error" });
|
res.status(500).send({ message: "Internal Server Error" });
|
||||||
logger.error("logout", { error });
|
logger.error("logout", { error });
|
||||||
return null;
|
return;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -33,11 +33,11 @@ const exportData: RequestHandler = async (req, res) => {
|
|||||||
);
|
);
|
||||||
res.send(JSON.stringify({ currentPlaylists, currentLinks }));
|
res.send(JSON.stringify({ currentPlaylists, currentLinks }));
|
||||||
logger.debug("exported data");
|
logger.debug("exported data");
|
||||||
return null;
|
return;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
res.status(500).send({ message: "Internal Server Error" });
|
res.status(500).send({ message: "Internal Server Error" });
|
||||||
logger.error("exportData", { error });
|
logger.error("exportData", { error });
|
||||||
return null;
|
return;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -50,7 +50,7 @@ const importData: RequestHandler = async (req, res) => {
|
|||||||
if (!req.file) {
|
if (!req.file) {
|
||||||
res.status(400).send({ message: "No file provided!" });
|
res.status(400).send({ message: "No file provided!" });
|
||||||
logger.debug("no file provided");
|
logger.debug("no file provided");
|
||||||
return null;
|
return;
|
||||||
}
|
}
|
||||||
let exportedLinks: Pick<Links, "from" | "to">[];
|
let exportedLinks: Pick<Links, "from" | "to">[];
|
||||||
let exportedPls: Pick<Playlists, "playlistID" | "playlistName">[];
|
let exportedPls: Pick<Playlists, "playlistID" | "playlistName">[];
|
||||||
@ -62,7 +62,7 @@ const importData: RequestHandler = async (req, res) => {
|
|||||||
const message = "Could not parse data file";
|
const message = "Could not parse data file";
|
||||||
res.status(400).send({ message });
|
res.status(400).send({ message });
|
||||||
logger.info(message, { error });
|
logger.info(message, { error });
|
||||||
return null;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const delPlNum = await Playlists.destroy({ where: { userID: uID } });
|
const delPlNum = await Playlists.destroy({ where: { userID: uID } });
|
||||||
@ -100,11 +100,11 @@ const importData: RequestHandler = async (req, res) => {
|
|||||||
links: addedLinks.length,
|
links: addedLinks.length,
|
||||||
playlists: addedPls.length,
|
playlists: addedPls.length,
|
||||||
});
|
});
|
||||||
return null;
|
return;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
res.status(500).send({ message: "Internal Server Error" });
|
res.status(500).send({ message: "Internal Server Error" });
|
||||||
logger.error("exportData", { error });
|
logger.error("exportData", { error });
|
||||||
return null;
|
return;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -47,7 +47,7 @@ const updateUser: RequestHandler = async (req, res) => {
|
|||||||
authHeaders,
|
authHeaders,
|
||||||
res,
|
res,
|
||||||
});
|
});
|
||||||
if (!resp) return null;
|
if (!resp) return;
|
||||||
const respData = resp.data;
|
const respData = resp.data;
|
||||||
|
|
||||||
currentPlaylists = respData.items.map((playlist) => {
|
currentPlaylists = respData.items.map((playlist) => {
|
||||||
@ -65,7 +65,7 @@ const updateUser: RequestHandler = async (req, res) => {
|
|||||||
res,
|
res,
|
||||||
nextURL,
|
nextURL,
|
||||||
});
|
});
|
||||||
if (!resp) return null;
|
if (!resp) return;
|
||||||
const nextData = resp.data;
|
const nextData = resp.data;
|
||||||
|
|
||||||
currentPlaylists.push(
|
currentPlaylists.push(
|
||||||
@ -155,7 +155,7 @@ const updateUser: RequestHandler = async (req, res) => {
|
|||||||
if (delNum !== deleted.length) {
|
if (delNum !== deleted.length) {
|
||||||
res.status(500).send({ message: "Internal Server Error" });
|
res.status(500).send({ message: "Internal Server Error" });
|
||||||
logger.error("Could not remove all old playlists");
|
logger.error("Could not remove all old playlists");
|
||||||
return null;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -169,7 +169,7 @@ const updateUser: RequestHandler = async (req, res) => {
|
|||||||
if (addPls.length !== added.length) {
|
if (addPls.length !== added.length) {
|
||||||
res.status(500).send({ message: "Internal Server Error" });
|
res.status(500).send({ message: "Internal Server Error" });
|
||||||
logger.error("Could not add all new playlists");
|
logger.error("Could not add all new playlists");
|
||||||
return null;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -186,7 +186,7 @@ const updateUser: RequestHandler = async (req, res) => {
|
|||||||
} catch (error) {
|
} catch (error) {
|
||||||
res.status(500).send({ message: "Internal Server Error" });
|
res.status(500).send({ message: "Internal Server Error" });
|
||||||
logger.error("Could not update playlist names");
|
logger.error("Could not update playlist names");
|
||||||
return null;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
res
|
res
|
||||||
@ -198,11 +198,11 @@ const updateUser: RequestHandler = async (req, res) => {
|
|||||||
addPls: addPls.length,
|
addPls: addPls.length,
|
||||||
updatedPls: updateNum,
|
updatedPls: updateNum,
|
||||||
});
|
});
|
||||||
return null;
|
return;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
res.status(500).send({ message: "Internal Server Error" });
|
res.status(500).send({ message: "Internal Server Error" });
|
||||||
logger.error("updateUser", { error });
|
logger.error("updateUser", { error });
|
||||||
return null;
|
return;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -213,7 +213,7 @@ const fetchUser: RequestHandler = async (req, res) => {
|
|||||||
try {
|
try {
|
||||||
// if (randomBool(0.5)) {
|
// if (randomBool(0.5)) {
|
||||||
// res.status(404).send({ message: "Not Found" });
|
// res.status(404).send({ message: "Not Found" });
|
||||||
// return null;
|
// return;
|
||||||
// }
|
// }
|
||||||
if (!req.session.user)
|
if (!req.session.user)
|
||||||
throw new ReferenceError("session does not have user object");
|
throw new ReferenceError("session does not have user object");
|
||||||
@ -243,11 +243,11 @@ const fetchUser: RequestHandler = async (req, res) => {
|
|||||||
pls: currentPlaylists.length,
|
pls: currentPlaylists.length,
|
||||||
links: currentLinks.length,
|
links: currentLinks.length,
|
||||||
});
|
});
|
||||||
return null;
|
return;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
res.status(500).send({ message: "Internal Server Error" });
|
res.status(500).send({ message: "Internal Server Error" });
|
||||||
logger.error("fetchUser", { error });
|
logger.error("fetchUser", { error });
|
||||||
return null;
|
return;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -268,12 +268,12 @@ const createLink: RequestHandler = async (req, res) => {
|
|||||||
if (fromPl.type !== "playlist" || toPl.type !== "playlist") {
|
if (fromPl.type !== "playlist" || toPl.type !== "playlist") {
|
||||||
res.status(400).send({ message: "Links must be playlist links!" });
|
res.status(400).send({ message: "Links must be playlist links!" });
|
||||||
logger.debug("non-playlist link provided");
|
logger.debug("non-playlist link provided");
|
||||||
return null;
|
return;
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
res.status(400).send({ message: "Could not parse link" });
|
res.status(400).send({ message: "Could not parse link" });
|
||||||
logger.info("parseSpotifyLink", { error });
|
logger.info("parseSpotifyLink", { error });
|
||||||
return null;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const playlists = await Playlists.findAll({
|
const playlists = await Playlists.findAll({
|
||||||
@ -287,7 +287,7 @@ const createLink: RequestHandler = async (req, res) => {
|
|||||||
if (![fromPl, toPl].every((pl) => playlistIDs.includes(pl.id))) {
|
if (![fromPl, toPl].every((pl) => playlistIDs.includes(pl.id))) {
|
||||||
res.status(404).send({ message: "Unknown playlists, resync first." });
|
res.status(404).send({ message: "Unknown playlists, resync first." });
|
||||||
logger.debug("unknown playlists, resync");
|
logger.debug("unknown playlists, resync");
|
||||||
return null;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if exists
|
// check if exists
|
||||||
@ -299,7 +299,7 @@ const createLink: RequestHandler = async (req, res) => {
|
|||||||
if (existingLink) {
|
if (existingLink) {
|
||||||
res.status(409).send({ message: "Link already exists!" });
|
res.status(409).send({ message: "Link already exists!" });
|
||||||
logger.debug("link already exists");
|
logger.debug("link already exists");
|
||||||
return null;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const allLinks = await Links.findAll({
|
const allLinks = await Links.findAll({
|
||||||
@ -318,7 +318,7 @@ const createLink: RequestHandler = async (req, res) => {
|
|||||||
.status(400)
|
.status(400)
|
||||||
.send({ message: "The link cannot cause a cycle in the graph." });
|
.send({ message: "The link cannot cause a cycle in the graph." });
|
||||||
logger.debug("potential cycle detected");
|
logger.debug("potential cycle detected");
|
||||||
return null;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const newLink = await Links.create({
|
const newLink = await Links.create({
|
||||||
@ -329,16 +329,16 @@ const createLink: RequestHandler = async (req, res) => {
|
|||||||
if (!newLink) {
|
if (!newLink) {
|
||||||
res.status(500).send({ message: "Internal Server Error" });
|
res.status(500).send({ message: "Internal Server Error" });
|
||||||
logger.error("Could not create link");
|
logger.error("Could not create link");
|
||||||
return null;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
res.status(201).send({ message: "Created link." });
|
res.status(201).send({ message: "Created link." });
|
||||||
logger.debug("Created link");
|
logger.debug("Created link");
|
||||||
return null;
|
return;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
res.status(500).send({ message: "Internal Server Error" });
|
res.status(500).send({ message: "Internal Server Error" });
|
||||||
logger.error("createLink", { error });
|
logger.error("createLink", { error });
|
||||||
return null;
|
return;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -358,12 +358,12 @@ const removeLink: RequestHandler = async (req, res) => {
|
|||||||
if (fromPl.type !== "playlist" || toPl.type !== "playlist") {
|
if (fromPl.type !== "playlist" || toPl.type !== "playlist") {
|
||||||
res.status(400).send({ message: "Links must be playlist links!" });
|
res.status(400).send({ message: "Links must be playlist links!" });
|
||||||
logger.debug("non-playlist link provided");
|
logger.debug("non-playlist link provided");
|
||||||
return null;
|
return;
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
res.status(400).send({ message: "Could not parse link" });
|
res.status(400).send({ message: "Could not parse link" });
|
||||||
logger.info("parseSpotifyLink", { error });
|
logger.info("parseSpotifyLink", { error });
|
||||||
return null;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if exists
|
// check if exists
|
||||||
@ -375,7 +375,7 @@ const removeLink: RequestHandler = async (req, res) => {
|
|||||||
if (!existingLink) {
|
if (!existingLink) {
|
||||||
res.status(409).send({ message: "Link does not exist!" });
|
res.status(409).send({ message: "Link does not exist!" });
|
||||||
logger.debug("link does not exist");
|
logger.debug("link does not exist");
|
||||||
return null;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const removedLink = await Links.destroy({
|
const removedLink = await Links.destroy({
|
||||||
@ -386,16 +386,16 @@ const removeLink: RequestHandler = async (req, res) => {
|
|||||||
if (!removedLink) {
|
if (!removedLink) {
|
||||||
res.status(500).send({ message: "Internal Server Error" });
|
res.status(500).send({ message: "Internal Server Error" });
|
||||||
logger.error("Could not remove link");
|
logger.error("Could not remove link");
|
||||||
return null;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
res.status(200).send({ message: "Deleted link." });
|
res.status(200).send({ message: "Deleted link." });
|
||||||
logger.debug("Deleted link");
|
logger.debug("Deleted link");
|
||||||
return null;
|
return;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
res.status(500).send({ message: "Internal Server Error" });
|
res.status(500).send({ message: "Internal Server Error" });
|
||||||
logger.error("removeLink", { error });
|
logger.error("removeLink", { error });
|
||||||
return null;
|
return;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -409,7 +409,7 @@ interface _GetPlaylistTracks {
|
|||||||
}
|
}
|
||||||
const _getPlaylistTracks: (
|
const _getPlaylistTracks: (
|
||||||
opts: _GetPlaylistTracksArgs
|
opts: _GetPlaylistTracksArgs
|
||||||
) => Promise<_GetPlaylistTracks | null> = async ({
|
) => Promise<_GetPlaylistTracks | void> = async ({
|
||||||
res,
|
res,
|
||||||
authHeaders,
|
authHeaders,
|
||||||
playlistID,
|
playlistID,
|
||||||
@ -421,7 +421,7 @@ const _getPlaylistTracks: (
|
|||||||
initialFields: "snapshot_id",
|
initialFields: "snapshot_id",
|
||||||
playlistID,
|
playlistID,
|
||||||
});
|
});
|
||||||
if (!snapshotResp) return null;
|
if (!snapshotResp) return;
|
||||||
|
|
||||||
const currentSnapshotID = snapshotResp.data.snapshot_id;
|
const currentSnapshotID = snapshotResp.data.snapshot_id;
|
||||||
|
|
||||||
@ -444,7 +444,7 @@ const _getPlaylistTracks: (
|
|||||||
initialFields: firstPageFields.join(),
|
initialFields: firstPageFields.join(),
|
||||||
playlistID,
|
playlistID,
|
||||||
});
|
});
|
||||||
if (!firstResp) return null;
|
if (!firstResp) return;
|
||||||
const firstRespData = firstResp.data;
|
const firstRespData = firstResp.data;
|
||||||
|
|
||||||
const pl: _GetPlaylistTracks = {
|
const pl: _GetPlaylistTracks = {
|
||||||
@ -472,7 +472,7 @@ const _getPlaylistTracks: (
|
|||||||
res,
|
res,
|
||||||
nextURL,
|
nextURL,
|
||||||
});
|
});
|
||||||
if (!resp) return null;
|
if (!resp) return;
|
||||||
const nextData = resp.data;
|
const nextData = resp.data;
|
||||||
|
|
||||||
pl.tracks.push(
|
pl.tracks.push(
|
||||||
@ -555,12 +555,12 @@ const populateSingleLink: RequestHandler = async (req, res) => {
|
|||||||
if (fromPl.type !== "playlist" || toPl.type !== "playlist") {
|
if (fromPl.type !== "playlist" || toPl.type !== "playlist") {
|
||||||
res.status(400).send({ message: "Link is not a playlist" });
|
res.status(400).send({ message: "Link is not a playlist" });
|
||||||
logger.debug("non-playlist link provided", { link });
|
logger.debug("non-playlist link provided", { link });
|
||||||
return null;
|
return;
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
res.status(400).send({ message: "Could not parse link" });
|
res.status(400).send({ message: "Could not parse link" });
|
||||||
logger.info("parseSpotifyLink", { error });
|
logger.info("parseSpotifyLink", { error });
|
||||||
return null;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if exists
|
// check if exists
|
||||||
@ -572,7 +572,7 @@ const populateSingleLink: RequestHandler = async (req, res) => {
|
|||||||
if (!existingLink) {
|
if (!existingLink) {
|
||||||
res.status(409).send({ message: "Link does not exist!" });
|
res.status(409).send({ message: "Link does not exist!" });
|
||||||
logger.debug("link does not exist", { link });
|
logger.debug("link does not exist", { link });
|
||||||
return null;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const editableResp = await checkPlaylistEditable({
|
const editableResp = await checkPlaylistEditable({
|
||||||
@ -584,7 +584,7 @@ const populateSingleLink: RequestHandler = async (req, res) => {
|
|||||||
if (!editableResp.status) {
|
if (!editableResp.status) {
|
||||||
res.status(403).send({ message: editableResp.message });
|
res.status(403).send({ message: editableResp.message });
|
||||||
logger.debug(editableResp.message, { editableResp });
|
logger.debug(editableResp.message, { editableResp });
|
||||||
return null;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const fromTracks = await _getPlaylistTracks({
|
const fromTracks = await _getPlaylistTracks({
|
||||||
@ -592,13 +592,13 @@ const populateSingleLink: RequestHandler = async (req, res) => {
|
|||||||
authHeaders,
|
authHeaders,
|
||||||
playlistID: fromPl.id,
|
playlistID: fromPl.id,
|
||||||
});
|
});
|
||||||
if (!fromTracks) return null;
|
if (!fromTracks) return;
|
||||||
const toTracks = await _getPlaylistTracks({
|
const toTracks = await _getPlaylistTracks({
|
||||||
res,
|
res,
|
||||||
authHeaders,
|
authHeaders,
|
||||||
playlistID: toPl.id,
|
playlistID: toPl.id,
|
||||||
});
|
});
|
||||||
if (!toTracks) return null;
|
if (!toTracks) return;
|
||||||
|
|
||||||
const { missing, localNum } = _populateSingleLinkCore({
|
const { missing, localNum } = _populateSingleLinkCore({
|
||||||
from: fromTracks.tracks,
|
from: fromTracks.tracks,
|
||||||
@ -630,11 +630,11 @@ const populateSingleLink: RequestHandler = async (req, res) => {
|
|||||||
|
|
||||||
res.status(200).send({ message, toAddNum, addedNum, localNum });
|
res.status(200).send({ message, toAddNum, addedNum, localNum });
|
||||||
logger.debug(message, { toAddNum, addedNum, localNum });
|
logger.debug(message, { toAddNum, addedNum, localNum });
|
||||||
return null;
|
return;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
res.status(500).send({ message: "Internal Server Error" });
|
res.status(500).send({ message: "Internal Server Error" });
|
||||||
logger.error("populateSingleLink", { error });
|
logger.error("populateSingleLink", { error });
|
||||||
return null;
|
return;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -654,12 +654,12 @@ const populateChain: RequestHandler = async (req, res) => {
|
|||||||
if (rootPl.type !== "playlist") {
|
if (rootPl.type !== "playlist") {
|
||||||
res.status(400).send({ message: "Link is not a playlist" });
|
res.status(400).send({ message: "Link is not a playlist" });
|
||||||
logger.debug("non-playlist link provided");
|
logger.debug("non-playlist link provided");
|
||||||
return null;
|
return;
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
res.status(400).send({ message: "Could not parse link" });
|
res.status(400).send({ message: "Could not parse link" });
|
||||||
logger.info("parseSpotifyLink", { error });
|
logger.info("parseSpotifyLink", { error });
|
||||||
return null;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const playlists = await Playlists.findAll({
|
const playlists = await Playlists.findAll({
|
||||||
@ -689,7 +689,7 @@ const populateChain: RequestHandler = async (req, res) => {
|
|||||||
});
|
});
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
if (res.headersSent) return null; // error, resp sent and logged in singleRequest
|
if (res.headersSent) return; // error, resp sent and logged in singleRequest
|
||||||
// else, respond with the non-editable playlists
|
// else, respond with the non-editable playlists
|
||||||
const nonEditablePlaylists = editableStatuses.filter(
|
const nonEditablePlaylists = editableStatuses.filter(
|
||||||
(statusObj) => statusObj.status === false
|
(statusObj) => statusObj.status === false
|
||||||
@ -700,7 +700,7 @@ const populateChain: RequestHandler = async (req, res) => {
|
|||||||
nonEditablePlaylists.map((pl) => pl.error?.playlistName).join(", ");
|
nonEditablePlaylists.map((pl) => pl.error?.playlistName).join(", ");
|
||||||
res.status(403).send({ message });
|
res.status(403).send({ message });
|
||||||
logger.debug(message, { nonEditablePlaylists });
|
logger.debug(message, { nonEditablePlaylists });
|
||||||
return null;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const affectedPlaylistsTracks = await Promise.all(
|
const affectedPlaylistsTracks = await Promise.all(
|
||||||
@ -708,14 +708,14 @@ const populateChain: RequestHandler = async (req, res) => {
|
|||||||
return _getPlaylistTracks({ res, authHeaders, playlistID: pl });
|
return _getPlaylistTracks({ res, authHeaders, playlistID: pl });
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
if (affectedPlaylistsTracks.some((plTracks) => !plTracks)) return null;
|
if (affectedPlaylistsTracks.some((plTracks) => !plTracks)) return;
|
||||||
|
|
||||||
const rootTracks = await _getPlaylistTracks({
|
const rootTracks = await _getPlaylistTracks({
|
||||||
res,
|
res,
|
||||||
authHeaders,
|
authHeaders,
|
||||||
playlistID: rootPl.id,
|
playlistID: rootPl.id,
|
||||||
});
|
});
|
||||||
if (!rootTracks) return null;
|
if (!rootTracks) return;
|
||||||
|
|
||||||
const populateData = affectedPlaylistsTracks.map((plTracks) => {
|
const populateData = affectedPlaylistsTracks.map((plTracks) => {
|
||||||
return _populateSingleLinkCore({
|
return _populateSingleLinkCore({
|
||||||
@ -775,11 +775,11 @@ const populateChain: RequestHandler = async (req, res) => {
|
|||||||
|
|
||||||
res.status(200).send({ message, ...reducedResult });
|
res.status(200).send({ message, ...reducedResult });
|
||||||
logger.debug(message, { ...reducedResult });
|
logger.debug(message, { ...reducedResult });
|
||||||
return null;
|
return;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
res.status(500).send({ message: "Internal Server Error" });
|
res.status(500).send({ message: "Internal Server Error" });
|
||||||
logger.error("populateChain", { error });
|
logger.error("populateChain", { error });
|
||||||
return null;
|
return;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -834,12 +834,12 @@ const pruneSingleLink: RequestHandler = async (req, res) => {
|
|||||||
if (fromPl.type !== "playlist" || toPl.type !== "playlist") {
|
if (fromPl.type !== "playlist" || toPl.type !== "playlist") {
|
||||||
res.status(400).send({ message: "Link is not a playlist" });
|
res.status(400).send({ message: "Link is not a playlist" });
|
||||||
logger.debug("non-playlist link provided");
|
logger.debug("non-playlist link provided");
|
||||||
return null;
|
return;
|
||||||
}
|
}
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
res.status(400).send({ message: error.message });
|
res.status(400).send({ message: error.message });
|
||||||
logger.info("parseSpotifyLink", { error });
|
logger.info("parseSpotifyLink", { error });
|
||||||
return null;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if exists
|
// check if exists
|
||||||
@ -851,7 +851,7 @@ const pruneSingleLink: RequestHandler = async (req, res) => {
|
|||||||
if (!existingLink) {
|
if (!existingLink) {
|
||||||
res.status(409).send({ message: "Link does not exist!" });
|
res.status(409).send({ message: "Link does not exist!" });
|
||||||
logger.warn("link does not exist", { link });
|
logger.warn("link does not exist", { link });
|
||||||
return null;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const editableResp = await checkPlaylistEditable({
|
const editableResp = await checkPlaylistEditable({
|
||||||
@ -863,7 +863,7 @@ const pruneSingleLink: RequestHandler = async (req, res) => {
|
|||||||
if (!editableResp.status) {
|
if (!editableResp.status) {
|
||||||
res.status(403).send({ message: editableResp.message });
|
res.status(403).send({ message: editableResp.message });
|
||||||
logger.debug(editableResp.message, { editableResp });
|
logger.debug(editableResp.message, { editableResp });
|
||||||
return null;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const fromTracks = await _getPlaylistTracks({
|
const fromTracks = await _getPlaylistTracks({
|
||||||
@ -871,14 +871,14 @@ const pruneSingleLink: RequestHandler = async (req, res) => {
|
|||||||
authHeaders,
|
authHeaders,
|
||||||
playlistID: fromPl.id,
|
playlistID: fromPl.id,
|
||||||
});
|
});
|
||||||
if (!fromTracks) return null;
|
if (!fromTracks) return;
|
||||||
|
|
||||||
const toTracks = await _getPlaylistTracks({
|
const toTracks = await _getPlaylistTracks({
|
||||||
res,
|
res,
|
||||||
authHeaders,
|
authHeaders,
|
||||||
playlistID: toPl.id,
|
playlistID: toPl.id,
|
||||||
});
|
});
|
||||||
if (!toTracks) return null;
|
if (!toTracks) return;
|
||||||
|
|
||||||
const { missingPositions } = _pruneSingleLinkCore({
|
const { missingPositions } = _pruneSingleLinkCore({
|
||||||
from: fromTracks.tracks,
|
from: fromTracks.tracks,
|
||||||
@ -918,11 +918,11 @@ const pruneSingleLink: RequestHandler = async (req, res) => {
|
|||||||
|
|
||||||
res.status(200).send({ message, toDelNum, deletedNum });
|
res.status(200).send({ message, toDelNum, deletedNum });
|
||||||
logger.debug(message, { toDelNum, deletedNum });
|
logger.debug(message, { toDelNum, deletedNum });
|
||||||
return null;
|
return;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
res.status(500).send({ message: "Internal Server Error" });
|
res.status(500).send({ message: "Internal Server Error" });
|
||||||
logger.error("pruneSingleLink", { error });
|
logger.error("pruneSingleLink", { error });
|
||||||
return null;
|
return;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -942,12 +942,12 @@ const pruneChain: RequestHandler = async (req, res) => {
|
|||||||
if (rootPl.type !== "playlist") {
|
if (rootPl.type !== "playlist") {
|
||||||
res.status(400).send({ message: "Link is not a playlist" });
|
res.status(400).send({ message: "Link is not a playlist" });
|
||||||
logger.debug("non-playlist link provided");
|
logger.debug("non-playlist link provided");
|
||||||
return null;
|
return;
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
res.status(400).send({ message: "Could not parse link" });
|
res.status(400).send({ message: "Could not parse link" });
|
||||||
logger.info("parseSpotifyLink", { error });
|
logger.info("parseSpotifyLink", { error });
|
||||||
return null;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const playlists = await Playlists.findAll({
|
const playlists = await Playlists.findAll({
|
||||||
@ -977,7 +977,7 @@ const pruneChain: RequestHandler = async (req, res) => {
|
|||||||
});
|
});
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
if (res.headersSent) return null; // error, resp sent and logged in singleRequest
|
if (res.headersSent) return; // error, resp sent and logged in singleRequest
|
||||||
// else, respond with the non-editable playlists
|
// else, respond with the non-editable playlists
|
||||||
const nonEditablePlaylists = editableStatuses.filter(
|
const nonEditablePlaylists = editableStatuses.filter(
|
||||||
(statusObj) => statusObj.status === false
|
(statusObj) => statusObj.status === false
|
||||||
@ -988,7 +988,7 @@ const pruneChain: RequestHandler = async (req, res) => {
|
|||||||
nonEditablePlaylists.map((pl) => pl.error?.playlistName).join(", ");
|
nonEditablePlaylists.map((pl) => pl.error?.playlistName).join(", ");
|
||||||
res.status(403).send({ message });
|
res.status(403).send({ message });
|
||||||
logger.debug(message, { nonEditablePlaylists });
|
logger.debug(message, { nonEditablePlaylists });
|
||||||
return null;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const rootTracks = await _getPlaylistTracks({
|
const rootTracks = await _getPlaylistTracks({
|
||||||
@ -996,14 +996,14 @@ const pruneChain: RequestHandler = async (req, res) => {
|
|||||||
authHeaders,
|
authHeaders,
|
||||||
playlistID: rootPl.id,
|
playlistID: rootPl.id,
|
||||||
});
|
});
|
||||||
if (!rootTracks) return null;
|
if (!rootTracks) return;
|
||||||
|
|
||||||
const affectedPlaylistsTracks = await Promise.all(
|
const affectedPlaylistsTracks = await Promise.all(
|
||||||
affectedPlaylists.map((pl) => {
|
affectedPlaylists.map((pl) => {
|
||||||
return _getPlaylistTracks({ res, authHeaders, playlistID: pl });
|
return _getPlaylistTracks({ res, authHeaders, playlistID: pl });
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
if (affectedPlaylistsTracks.some((plTracks) => !plTracks)) return null;
|
if (affectedPlaylistsTracks.some((plTracks) => !plTracks)) return;
|
||||||
|
|
||||||
const pruneData = affectedPlaylistsTracks.map((plTracks) => {
|
const pruneData = affectedPlaylistsTracks.map((plTracks) => {
|
||||||
return _pruneSingleLinkCore({
|
return _pruneSingleLinkCore({
|
||||||
@ -1060,11 +1060,11 @@ const pruneChain: RequestHandler = async (req, res) => {
|
|||||||
|
|
||||||
res.status(200).send({ message, ...reducedResult });
|
res.status(200).send({ message, ...reducedResult });
|
||||||
logger.debug(message, { ...reducedResult });
|
logger.debug(message, { ...reducedResult });
|
||||||
return null;
|
return;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
res.status(500).send({ message: "Internal Server Error" });
|
res.status(500).send({ message: "Internal Server Error" });
|
||||||
logger.error("pruneChain", { error });
|
logger.error("pruneChain", { error });
|
||||||
return null;
|
return;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -24,7 +24,7 @@ const fetchUserPlaylists: RequestHandler = async (req, res) => {
|
|||||||
res,
|
res,
|
||||||
authHeaders,
|
authHeaders,
|
||||||
});
|
});
|
||||||
if (!resp) return null;
|
if (!resp) return;
|
||||||
|
|
||||||
const userPlaylists: Pick<
|
const userPlaylists: Pick<
|
||||||
Pagination<SimplifiedPlaylistObject>,
|
Pagination<SimplifiedPlaylistObject>,
|
||||||
@ -41,7 +41,7 @@ const fetchUserPlaylists: RequestHandler = async (req, res) => {
|
|||||||
res,
|
res,
|
||||||
nextURL,
|
nextURL,
|
||||||
});
|
});
|
||||||
if (!resp) return null;
|
if (!resp) return;
|
||||||
const nextData = resp.data;
|
const nextData = resp.data;
|
||||||
|
|
||||||
userPlaylists.items.push(...nextData.items);
|
userPlaylists.items.push(...nextData.items);
|
||||||
@ -50,11 +50,11 @@ const fetchUserPlaylists: RequestHandler = async (req, res) => {
|
|||||||
|
|
||||||
res.status(200).send(userPlaylists);
|
res.status(200).send(userPlaylists);
|
||||||
logger.debug("Fetched user playlists", { num: userPlaylists.total });
|
logger.debug("Fetched user playlists", { num: userPlaylists.total });
|
||||||
return null;
|
return;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
res.status(500).send({ message: "Internal Server Error" });
|
res.status(500).send({ message: "Internal Server Error" });
|
||||||
logger.error("fetchUserPlaylists", { error });
|
logger.error("fetchUserPlaylists", { error });
|
||||||
return null;
|
return;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
10
index.ts
10
index.ts
@ -84,7 +84,7 @@ app.use(express.static(import.meta.dirname + "/static"));
|
|||||||
// Healthcheck
|
// Healthcheck
|
||||||
app.use("/health", (_req, res) => {
|
app.use("/health", (_req, res) => {
|
||||||
res.status(200).send({ message: "OK" });
|
res.status(200).send({ message: "OK" });
|
||||||
return null;
|
return;
|
||||||
});
|
});
|
||||||
app.use("/auth-health", isAuthenticated, async (req, res) => {
|
app.use("/auth-health", isAuthenticated, async (req, res) => {
|
||||||
try {
|
try {
|
||||||
@ -92,13 +92,13 @@ app.use("/auth-health", isAuthenticated, async (req, res) => {
|
|||||||
if (!authHeaders)
|
if (!authHeaders)
|
||||||
throw new ReferenceError("session does not have auth headers");
|
throw new ReferenceError("session does not have auth headers");
|
||||||
const { resp } = await getCurrentUsersProfile({ authHeaders, res });
|
const { resp } = await getCurrentUsersProfile({ authHeaders, res });
|
||||||
if (!resp) return null;
|
if (!resp) return;
|
||||||
res.status(200).send({ message: "OK" });
|
res.status(200).send({ message: "OK" });
|
||||||
return null;
|
return;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
res.status(500).send({ message: "Internal Server Error" });
|
res.status(500).send({ message: "Internal Server Error" });
|
||||||
logger.error("authHealthCheck", { error });
|
logger.error("authHealthCheck", { error });
|
||||||
return null;
|
return;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -116,7 +116,7 @@ app.use((req, res) => {
|
|||||||
'Guess the <a href="https://github.com/20kaushik02/spotify-manager">cat\'s</a> out of the bag!'
|
'Guess the <a href="https://github.com/20kaushik02/spotify-manager">cat\'s</a> out of the bag!'
|
||||||
);
|
);
|
||||||
logger.info("404", { url: req.url });
|
logger.info("404", { url: req.url });
|
||||||
return null;
|
return;
|
||||||
});
|
});
|
||||||
|
|
||||||
const port = process.env["SPOTMGR_PORT"] || 5000;
|
const port = process.env["SPOTMGR_PORT"] || 5000;
|
||||||
|
|||||||
@ -15,14 +15,14 @@ const isAuthenticated: RequestHandler = (req, res, next) => {
|
|||||||
if (Object.keys(error).length) {
|
if (Object.keys(error).length) {
|
||||||
res.status(500).send({ message: "Internal Server Error" });
|
res.status(500).send({ message: "Internal Server Error" });
|
||||||
logger.error("session.destroy", { error });
|
logger.error("session.destroy", { error });
|
||||||
return null;
|
return;
|
||||||
} else {
|
} else {
|
||||||
res.clearCookie(sessionName);
|
res.clearCookie(sessionName);
|
||||||
res.status(401).send({ message: "Unauthorized" });
|
res.status(401).send({ message: "Unauthorized" });
|
||||||
logger.debug("Session invalid, destroyed.", {
|
logger.debug("Session invalid, destroyed.", {
|
||||||
sessionID: delSession.id,
|
sessionID: delSession.id,
|
||||||
});
|
});
|
||||||
return null;
|
return;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
921
package-lock.json
generated
921
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
26
package.json
26
package.json
@ -20,34 +20,34 @@
|
|||||||
},
|
},
|
||||||
"homepage": "https://api.spotify-manager.knravish.me",
|
"homepage": "https://api.spotify-manager.knravish.me",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"axios": "^1.8.4",
|
"axios": "^1.9.0",
|
||||||
"bottleneck": "^2.19.5",
|
"bottleneck": "^2.19.5",
|
||||||
"connect-redis": "^8.0.3",
|
"connect-redis": "^8.1.0",
|
||||||
"cookie-parser": "^1.4.7",
|
"cookie-parser": "^1.4.7",
|
||||||
"cors": "^2.8.5",
|
"cors": "^2.8.5",
|
||||||
"express": "^4.21.2",
|
"express": "^5.1.0",
|
||||||
"express-session": "^1.18.1",
|
"express-session": "^1.18.1",
|
||||||
"express-validator": "^7.2.1",
|
"express-validator": "^7.2.1",
|
||||||
"helmet": "^8.1.0",
|
"helmet": "^8.1.0",
|
||||||
"multer": "^1.4.5-lts.2",
|
"multer": "^2.0.0",
|
||||||
"pg": "^8.15.1",
|
"pg": "^8.16.0",
|
||||||
"redis": "^4.7.0",
|
"redis": "^5.1.1",
|
||||||
"reflect-metadata": "^0.2.2",
|
"reflect-metadata": "^0.2.2",
|
||||||
"sequelize": "^6.37.7",
|
"sequelize": "^6.37.7",
|
||||||
"sequelize-cli": "^6.6.2",
|
"sequelize-cli": "^6.6.3",
|
||||||
"sequelize-typescript": "^2.1.6",
|
"sequelize-typescript": "^2.1.6",
|
||||||
"serializr": "^3.0.4",
|
"serializr": "^3.0.5",
|
||||||
"winston": "^3.17.0"
|
"winston": "^3.17.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/cookie-parser": "^1.4.8",
|
"@types/cookie-parser": "^1.4.8",
|
||||||
"@types/cors": "^2.8.17",
|
"@types/cors": "^2.8.8",
|
||||||
"@types/express": "^4.17.21",
|
"@types/express": "^5.0.2",
|
||||||
"@types/express-session": "^1.18.1",
|
"@types/express-session": "^1.18.1",
|
||||||
"@types/multer": "^1.4.12",
|
"@types/multer": "^1.4.12",
|
||||||
"@types/node": "^22.13.11",
|
"@types/node": "^22.15.29",
|
||||||
"@types/sequelize": "^4.28.20",
|
"@types/sequelize": "^4.28.20",
|
||||||
"@types/validator": "^13.12.2",
|
"@types/validator": "^13.15.1",
|
||||||
"typescript": "^5.8.2"
|
"typescript": "^5.8.3"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -32,7 +32,7 @@ const validate: RequestHandler = (req, res, next) => {
|
|||||||
errors: extractedErrors,
|
errors: extractedErrors,
|
||||||
});
|
});
|
||||||
logger.warn("invalid request", { extractedErrors });
|
logger.warn("invalid request", { extractedErrors });
|
||||||
return null;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
export { validate };
|
export { validate };
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user