i18n
CI/CD Pipeline / Build and Push PocketBase Docker Image (push) Successful in 8s
CI/CD Pipeline / i18n Catalog Check (push) Failing after 10s
CI/CD Pipeline / Build and Push App Docker Image (push) Skipped
CI/CD Pipeline / Deploy to Kubernetes (push) Skipped

This commit is contained in:
yohlo
2026-08-08 15:29:40 -07:00
parent 22c282d8fa
commit 0a7b5fa00f
178 changed files with 13099 additions and 1285 deletions
+7 -3
View File
@@ -1,11 +1,15 @@
import { createFileRoute } from "@tanstack/react-router";
import { msg } from "@lingui/core/macro";
import { SpotifyWebApiClient } from "@/lib/spotify/client";
import type { SpotifyPlaybackSnapshot } from "@/lib/spotify/types";
import { localizedFor } from "@/lib/i18n/server-messages";
export const Route = createFileRoute("/api/spotify/capture")({
server: {
handlers: {
POST: async ({ request }: { request: Request }) => {
// No session middleware on this route; localize with DEFAULT_LOCALE.
const i18n = localizedFor(null);
try {
const cookies = request.headers.get("Cookie") || "";
const accessTokenMatch = cookies.match(
@@ -14,7 +18,7 @@ export const Route = createFileRoute("/api/spotify/capture")({
if (!accessTokenMatch) {
return new Response(
JSON.stringify({ error: "No access token found" }),
JSON.stringify({ error: i18n._(msg`No access token found`) }),
{
status: 401,
headers: { "Content-Type": "application/json" },
@@ -29,7 +33,7 @@ export const Route = createFileRoute("/api/spotify/capture")({
if (!snapshot) {
return new Response(
JSON.stringify({ error: "No active playback to capture" }),
JSON.stringify({ error: i18n._(msg`No active playback to capture`) }),
{
status: 400,
headers: { "Content-Type": "application/json" },
@@ -47,7 +51,7 @@ export const Route = createFileRoute("/api/spotify/capture")({
const errorMessage =
error instanceof Error
? error.message
: "Failed to capture playback state";
: i18n._(msg`Failed to capture playback state`);
return new Response(JSON.stringify({ error: errorMessage }), {
status: 500,
+26 -14
View File
@@ -1,5 +1,7 @@
import { createFileRoute } from "@tanstack/react-router";
import { msg } from "@lingui/core/macro";
import { SpotifyWebApiClient } from "@/lib/spotify/client";
import { localizedFor } from "@/lib/i18n/server-messages";
function getAccessTokenFromCookies(request: Request): string | null {
const cookieHeader = request.headers.get("cookie");
@@ -16,11 +18,13 @@ export const Route = createFileRoute("/api/spotify/playback")({
server: {
handlers: {
POST: async ({ request }: { request: Request }) => {
// No session middleware on this route; localize with DEFAULT_LOCALE.
const i18n = localizedFor(null);
try {
const accessToken = getAccessTokenFromCookies(request);
if (!accessToken) {
return new Response(
JSON.stringify({ error: "No access token found" }),
JSON.stringify({ error: i18n._(msg`No access token found`) }),
{
status: 401,
headers: { "Content-Type": "application/json" },
@@ -41,7 +45,7 @@ export const Route = createFileRoute("/api/spotify/playback")({
if (!trackId) {
return new Response(
JSON.stringify({
error: "trackId is required for playTrack action",
error: i18n._(msg`trackId is required for playTrack action`),
}),
{
status: 400,
@@ -63,7 +67,7 @@ export const Route = createFileRoute("/api/spotify/playback")({
case "volume":
if (typeof volumePercent !== "number") {
return new Response(
JSON.stringify({ error: "volumePercent must be a number" }),
JSON.stringify({ error: i18n._(msg`volumePercent must be a number`) }),
{
status: 400,
headers: { "Content-Type": "application/json" },
@@ -76,7 +80,7 @@ export const Route = createFileRoute("/api/spotify/playback")({
if (!deviceId) {
return new Response(
JSON.stringify({
error: "deviceId is required for transfer action",
error: i18n._(msg`deviceId is required for transfer action`),
}),
{
status: 400,
@@ -87,10 +91,13 @@ export const Route = createFileRoute("/api/spotify/playback")({
await spotifyClient.transferPlayback(deviceId);
break;
default:
return new Response(JSON.stringify({ error: "Invalid action" }), {
status: 400,
headers: { "Content-Type": "application/json" },
});
return new Response(
JSON.stringify({ error: i18n._(msg`Invalid action`) }),
{
status: 400,
headers: { "Content-Type": "application/json" },
}
);
}
return new Response(JSON.stringify({ success: true }), {
@@ -104,8 +111,9 @@ export const Route = createFileRoute("/api/spotify/playback")({
if (error.message.includes("NO_ACTIVE_DEVICE")) {
return new Response(
JSON.stringify({
error:
"No active device found. Please select a device first.",
error: i18n._(
msg`No active device found. Please select a device first.`
),
}),
{
status: 400,
@@ -117,7 +125,9 @@ export const Route = createFileRoute("/api/spotify/playback")({
if (error.message.includes("PREMIUM_REQUIRED")) {
return new Response(
JSON.stringify({
error: "Spotify Premium is required for playback control.",
error: i18n._(
msg`Spotify Premium is required for playback control.`
),
}),
{
status: 403,
@@ -135,7 +145,7 @@ export const Route = createFileRoute("/api/spotify/playback")({
return new Response(
JSON.stringify({
error: "Playback control failed",
error: i18n._(msg`Playback control failed`),
details: error instanceof Error ? error.message : "Unknown error",
}),
{
@@ -147,11 +157,13 @@ export const Route = createFileRoute("/api/spotify/playback")({
},
GET: async ({ request }: { request: Request }) => {
// No session middleware on this route; localize with DEFAULT_LOCALE.
const i18n = localizedFor(null);
try {
const accessToken = getAccessTokenFromCookies(request);
if (!accessToken) {
return new Response(
JSON.stringify({ error: "No access token found" }),
JSON.stringify({ error: i18n._(msg`No access token found`) }),
{
status: 401,
headers: { "Content-Type": "application/json" },
@@ -190,7 +202,7 @@ export const Route = createFileRoute("/api/spotify/playback")({
} catch (error) {
console.error("Get playback data error:", error);
return new Response(
JSON.stringify({ error: "Failed to get playback data" }),
JSON.stringify({ error: i18n._(msg`Failed to get playback data`) }),
{
status: 500,
headers: { "Content-Type": "application/json" },
+8 -4
View File
@@ -1,11 +1,15 @@
import { createFileRoute } from "@tanstack/react-router";
import { msg } from "@lingui/core/macro";
import { SpotifyWebApiClient } from "@/lib/spotify/client";
import type { SpotifyPlaybackSnapshot } from "@/lib/spotify/types";
import { localizedFor } from "@/lib/i18n/server-messages";
export const Route = createFileRoute("/api/spotify/resume")({
server: {
handlers: {
POST: async ({ request }: { request: Request }) => {
// No session middleware on this route; localize with DEFAULT_LOCALE.
const i18n = localizedFor(null);
try {
const cookies = request.headers.get("Cookie") || "";
const accessTokenMatch = cookies.match(
@@ -14,7 +18,7 @@ export const Route = createFileRoute("/api/spotify/resume")({
if (!accessTokenMatch) {
return new Response(
JSON.stringify({ error: "No access token found" }),
JSON.stringify({ error: i18n._(msg`No access token found`) }),
{
status: 401,
headers: { "Content-Type": "application/json" },
@@ -30,7 +34,7 @@ export const Route = createFileRoute("/api/spotify/resume")({
if (!snapshot) {
return new Response(
JSON.stringify({ error: "No snapshot provided" }),
JSON.stringify({ error: i18n._(msg`No snapshot provided`) }),
{
status: 400,
headers: { "Content-Type": "application/json" },
@@ -47,14 +51,14 @@ export const Route = createFileRoute("/api/spotify/resume")({
} catch (error) {
console.error("Spotify resume error:", error);
let errorMessage = "Failed to resume playback state";
let errorMessage = i18n._(msg`Failed to resume playback state`);
if (error instanceof Error) {
if (
error.message.includes("Premium") ||
error.message.includes("403")
) {
errorMessage = "Spotify premium required";
errorMessage = i18n._(msg`Spotify premium required`);
} else {
errorMessage = error.message;
}