diff --git a/.babelrc b/.babelrc
index 9189172..3457add 100644
--- a/.babelrc
+++ b/.babelrc
@@ -1,11 +1,12 @@
{
- "presets": [
- "next/babel"
- ],
+ "presets": ["next/babel"],
"plugins": [
- ["styled-components", {
- "displayName": false,
- "ssr": true
- }]
+ [
+ "styled-components",
+ {
+ "displayName": false,
+ "ssr": true
+ }
+ ]
]
}
diff --git a/.husky/pre-commit b/.husky/pre-commit
new file mode 100755
index 0000000..9841c7a
--- /dev/null
+++ b/.husky/pre-commit
@@ -0,0 +1,2 @@
+#!/usr/bin/env sh
+yarn lint-staged
diff --git a/.prettierignore b/.prettierignore
new file mode 100644
index 0000000..d93ee08
--- /dev/null
+++ b/.prettierignore
@@ -0,0 +1,11 @@
+.next
+node_modules
+coverage
+dist
+build
+out
+test-results
+public/static
+.yarn
+.pnp.*
+yarn.lock
diff --git a/.prettierrc.json b/.prettierrc.json
new file mode 100644
index 0000000..578076d
--- /dev/null
+++ b/.prettierrc.json
@@ -0,0 +1,7 @@
+{
+ "semi": true,
+ "singleQuote": false,
+ "trailingComma": "all",
+ "arrowParens": "avoid",
+ "printWidth": 120
+}
diff --git a/README.md b/README.md
index 0adbe08..c6899be 100755
--- a/README.md
+++ b/README.md
@@ -22,7 +22,6 @@ In addition to the software requirements, you need access to the following APIs:
- [Discogs](https://www.discogs.com/applications/edit) for searching and getting release info
- [Last.fm](https://www.last.fm/api/account/create) for authentication and scrobbling data
-
### Installing
First you need to clone the repository from github:
@@ -85,6 +84,7 @@ yarn test
```
You can also use watch-mode and display the current test coverage:
+
```
yarn test:watch
yarm test:coverage
@@ -110,7 +110,7 @@ yarn start
## Authors
-* **Daniel Puscher** - *Initial work* - [dpuscher](https://github.com/dpuscher)
+- **Daniel Puscher** - _Initial work_ - [dpuscher](https://github.com/dpuscher)
See also the list of [contributors](https://github.com/dpuscher/code-scrobble/contributors) who participated in this project.
diff --git a/app/__mocks__/redis.ts b/app/__mocks__/redis.ts
index 5086d14..13249d7 100644
--- a/app/__mocks__/redis.ts
+++ b/app/__mocks__/redis.ts
@@ -2,10 +2,10 @@
const store = new Map();
-const mockGet = jest.fn(async (key) => store.get(key) || null);
+const mockGet = jest.fn(async key => store.get(key) || null);
const mockSet = jest.fn(async (key, value) => {
store.set(key, value);
- return 'OK';
+ return "OK";
});
const mockConnect = jest.fn(async () => {});
const mockOn = jest.fn();
diff --git a/app/cache.ts b/app/cache.ts
index 8a99241..9c1deb5 100644
--- a/app/cache.ts
+++ b/app/cache.ts
@@ -1,11 +1,10 @@
-import { createClient } from 'redis';
+import { createClient } from "redis";
const client = createClient({ url: process.env.REDISCLOUD_URL });
client.connect().catch(console.error);
-client.on('error', console.error);
+client.on("error", console.error);
-export const set = (key: string, value: unknown, ttl = 86400) =>
- client.set(key, JSON.stringify(value), { EX: ttl });
+export const set = (key: string, value: unknown, ttl = 86400) => client.set(key, JSON.stringify(value), { EX: ttl });
export const get = async (key: string): Promise => {
const value = await client.get(key);
diff --git a/app/discogs.ts b/app/discogs.ts
index c438cdc..43bdf72 100644
--- a/app/discogs.ts
+++ b/app/discogs.ts
@@ -1,10 +1,10 @@
-import orderBy from 'lodash/orderBy';
-import pick from 'lodash/pick';
-import find from 'lodash/find';
-import * as Cache from './cache';
+import orderBy from "lodash/orderBy";
+import pick from "lodash/pick";
+import find from "lodash/find";
+import * as Cache from "./cache";
// eslint-disable-next-line @typescript-eslint/no-require-imports
-const DiscogsClient = require('disconnect').Client;
+const DiscogsClient = require("disconnect").Client;
interface DiscogsError {
statusCode: number;
@@ -71,19 +71,17 @@ const Database = new DiscogsClient({
const convertTimecode = (timecode: string | undefined): number => {
if (!timecode) return 0;
return timecode
- .split(':')
- .map(n => (parseInt(n, 10) || 0))
+ .split(":")
+ .map(n => parseInt(n, 10) || 0)
.reverse()
- .map((n, i) => n * (60 ** i))
+ .map((n, i) => n * 60 ** i)
.reduce((pv, cv) => pv + cv);
};
const normalizeTracklist = (tracks: DiscogsTrack[]): DiscogsTrack[] => {
const vinylPositionRegex = /^[A-Z]-?[0-9]+$/;
// eslint-disable-next-line no-underscore-dangle
- let tracklist = tracks
- .filter(track => track.type_ === 'track')
- .filter(track => !/video/i.test(track.position));
+ let tracklist = tracks.filter(track => track.type_ === "track").filter(track => !/video/i.test(track.position));
// Remove Bonus CDs from vinyl releases:
if (tracklist.length && vinylPositionRegex.test(tracklist[0].position)) {
@@ -97,67 +95,70 @@ const normalizeTracklist = (tracks: DiscogsTrack[]): DiscogsTrack[] => {
};
const getBarcode = (data: DiscogsIdentifier[] = []): string | undefined =>
- (find(data, { type: 'Barcode' }) || {}).value;
+ (find(data, { type: "Barcode" }) || {}).value;
const buildRelease = (id: number, data: DiscogsData): ReleaseData => ({
id,
- artist: (data.artists || []).map(a => a.name).join(', '),
+ artist: (data.artists || []).map(a => a.name).join(", "),
title: data.title,
image: data?.images?.[0]?.uri,
url: data.uri,
year: data.year,
- tracks: normalizeTracklist(data.tracklist || [])
- .map((track, index) => ({
- title: track.title,
- trackNumber: index + 1,
- duration: convertTimecode(track.duration),
- })),
+ tracks: normalizeTracklist(data.tracklist || []).map((track, index) => ({
+ title: track.title,
+ trackNumber: index + 1,
+ duration: convertTimecode(track.duration),
+ })),
barcode: getBarcode(data.identifiers),
});
export const barcode = (barcodeValue: string): Promise =>
- new Promise((resolve) => {
+ new Promise(resolve => {
const cacheKey = `barcode--${barcodeValue}`;
Cache.get(cacheKey)
- .then((result) => {
+ .then(result => {
resolve(result);
})
.catch(() => {
- Database.search(undefined, { barcode: barcodeValue, type: 'release' }, (err: DiscogsError, data: { results: DiscogsSearchResult[] }) => {
- if (err || !data || !data.results || !data.results.length) {
- return resolve(undefined);
- }
- const results = orderBy(
- data.results,
- ['community.have', 'community.want'],
- ['desc', 'desc'],
- ) as DiscogsSearchResult[];
+ Database.search(
+ undefined,
+ { barcode: barcodeValue, type: "release" },
+ (err: DiscogsError, data: { results: DiscogsSearchResult[] }) => {
+ if (err || !data || !data.results || !data.results.length) {
+ return resolve(undefined);
+ }
+ const results = orderBy(
+ data.results,
+ ["community.have", "community.want"],
+ ["desc", "desc"],
+ ) as DiscogsSearchResult[];
- Cache.set(cacheKey, results[0].id);
+ Cache.set(cacheKey, results[0].id);
- return resolve(results[0].id);
- });
+ return resolve(results[0].id);
+ },
+ );
});
});
export const search = (query: string): Promise =>
- new Promise((resolve) => {
+ new Promise(resolve => {
const cacheKey = `search--${query}`;
Cache.get(cacheKey)
- .then((results) => {
+ .then(results => {
resolve(results);
})
.catch(() => {
// eslint-disable-next-line consistent-return
- Database.search(query, { type: 'release' }, (err: DiscogsError, data: { results: any[] }) => {
+ Database.search(query, { type: "release" }, (err: DiscogsError, data: { results: any[] }) => {
if (err || !data || !data.results || !data.results.length) {
return resolve(undefined);
}
const results: SearchResult[] = data.results.map(result =>
- pick(result, ['id', 'title', 'thumb', 'country', 'year', 'format', 'uri']),
+ pick(result, ["id", "title", "thumb", "country", "year", "format", "uri"]),
);
Cache.set(cacheKey, results);
@@ -174,7 +175,7 @@ export const getRelease = (id: number): Promise =>
if (err.statusCode === 404) {
Database.getMaster(id, (masterErr: DiscogsError, masterData: DiscogsData) => {
if (masterErr || !masterData) {
- reject(masterErr || new Error('No data returned from Discogs'));
+ reject(masterErr || new Error("No data returned from Discogs"));
} else {
resolve(buildRelease(id, masterData));
}
@@ -183,7 +184,7 @@ export const getRelease = (id: number): Promise =>
reject(err);
}
} else if (!data) {
- reject(new Error('No data returned from Discogs'));
+ reject(new Error("No data returned from Discogs"));
} else {
resolve(buildRelease(id, data));
}
diff --git a/app/lastfm.ts b/app/lastfm.ts
index c3c3ce7..5757963 100644
--- a/app/lastfm.ts
+++ b/app/lastfm.ts
@@ -1,5 +1,5 @@
// eslint-disable-next-line @typescript-eslint/no-require-imports
-const LastFMApi = require('lastfmapi');
+const LastFMApi = require("lastfmapi");
interface ScrobbleTrack {
album: string;
@@ -28,7 +28,7 @@ const getScrobble = (data: ReleaseForScrobble): ScrobbleTrack[] => {
let nextTimestamp = Math.floor(Date.now() / 1000);
const trackData: ScrobbleTrack[] = [];
- data.tracks.forEach((track) => {
+ data.tracks.forEach(track => {
trackData.push({
album: data.title,
artist: data.artist,
@@ -44,27 +44,21 @@ const getScrobble = (data: ReleaseForScrobble): ScrobbleTrack[] => {
export const scrobbleTracks = (username: string, key: string, data: ReleaseForScrobble): Promise =>
new Promise((resolve, reject) => {
- createApiClient(username, key).track.scrobble(
- getScrobble(data),
- (err: unknown, scrobbles: unknown) => {
- if (err) reject(err);
- resolve(scrobbles);
- },
- );
+ createApiClient(username, key).track.scrobble(getScrobble(data), (err: unknown, scrobbles: unknown) => {
+ if (err) reject(err);
+ resolve(scrobbles);
+ });
});
export interface LastFMUserData {
url: string;
- image?: Array<{ '#text': string }>;
+ image?: Array<{ "#text": string }>;
}
export const getUserData = (username: string, key: string): Promise =>
new Promise((resolve, reject) => {
- createApiClient(username, key).user.getInfo(
- null,
- (err: unknown, userData: unknown) => {
- if (err) reject(err);
- resolve(userData as LastFMUserData);
- },
- );
+ createApiClient(username, key).user.getInfo(null, (err: unknown, userData: unknown) => {
+ if (err) reject(err);
+ resolve(userData as LastFMUserData);
+ });
});
diff --git a/app/models/release.ts b/app/models/release.ts
index 4603eab..2408b06 100644
--- a/app/models/release.ts
+++ b/app/models/release.ts
@@ -1,6 +1,6 @@
-import mongoose, { Schema, HydratedDocument, Model } from 'mongoose';
-import pick from 'lodash/pick';
-import * as Discogs from '../discogs';
+import mongoose, { Schema, HydratedDocument, Model } from "mongoose";
+import pick from "lodash/pick";
+import * as Discogs from "../discogs";
interface ITrack {
title: string;
@@ -27,7 +27,10 @@ interface IReleaseMethods {
interface IReleaseModel extends Model {
createFromDiscogs(id: number, barcode?: string): Promise>;
- firstOrCreate(param: { id?: string | number; barcode?: string }): Promise | null>;
+ firstOrCreate(param: {
+ id?: string | number;
+ barcode?: string;
+ }): Promise | null>;
}
const releaseSchema = new Schema(
@@ -41,11 +44,13 @@ const releaseSchema = new Schema(
image: String,
url: String,
year: String,
- tracks: [{
- title: String,
- trackNumber: Number,
- duration: Number,
- }],
+ tracks: [
+ {
+ title: String,
+ trackNumber: Number,
+ duration: Number,
+ },
+ ],
barcode: String,
},
{ timestamps: true },
@@ -60,7 +65,7 @@ releaseSchema.methods.toJSON = function toJSON() {
image: this.image,
url: this.url,
year: this.year,
- tracks: this.tracks.map((track: ITrack) => pick(track, ['title', 'trackNumber', 'duration'])),
+ tracks: this.tracks.map((track: ITrack) => pick(track, ["title", "trackNumber", "duration"])),
};
};
@@ -82,7 +87,7 @@ releaseSchema.methods.updateFromDiscogs = async function updateFromDiscogs() {
};
releaseSchema.statics.createFromDiscogs = async function createFromDiscogs(id: number, barcodeValue?: string) {
- const release = new (this)({ id });
+ const release = new this({ id });
if (barcodeValue) release.barcode = barcodeValue;
await release.updateFromDiscogs();
return release;
@@ -92,12 +97,13 @@ releaseSchema.statics.firstOrCreate = async function firstOrCreate(param: { id?:
const release = await this.findOne(param).exec();
if (!release) {
const paramId = param.id ? Number(param.id) : undefined;
- const id = paramId || await Discogs.barcode(param.barcode);
+ const id = paramId || (await Discogs.barcode(param.barcode));
if (!id) return null;
try {
return await this.createFromDiscogs(id, param.barcode);
- } catch (err: any) { // eslint-disable-line @typescript-eslint/no-explicit-any
+ } catch (err: any) {
+ // eslint-disable-line @typescript-eslint/no-explicit-any
if (err.code === 11000) {
return this.findOne({ id }).exec();
}
@@ -113,7 +119,7 @@ releaseSchema.statics.firstOrCreate = async function firstOrCreate(param: { id?:
return release;
};
-const Release = (mongoose.models.Release as IReleaseModel) ||
- mongoose.model('Release', releaseSchema);
+const Release =
+ (mongoose.models.Release as IReleaseModel) || mongoose.model("Release", releaseSchema);
export default Release;
diff --git a/app/models/user.ts b/app/models/user.ts
index d0b49cd..34ecfab 100644
--- a/app/models/user.ts
+++ b/app/models/user.ts
@@ -1,4 +1,4 @@
-import mongoose, { Schema, HydratedDocument, Model } from 'mongoose';
+import mongoose, { Schema, HydratedDocument, Model } from "mongoose";
interface IHistoryItem {
id: string;
@@ -40,10 +40,12 @@ const userSchema = new Schema({
imageLarge: String,
imageXLarge: String,
instantScrobbles: [String],
- history: [{
- id: String,
- time: { type: Date, default: Date.now },
- }],
+ history: [
+ {
+ id: String,
+ time: { type: Date, default: Date.now },
+ },
+ ],
});
userSchema.methods.toJSON = function toJSON(): UserJSON {
@@ -62,7 +64,8 @@ userSchema.methods.isInstantScrobble = function isInstantScrobble(id: string) {
return (this.instantScrobbles || []).includes(String(id));
};
-const User = (mongoose.models.User as UserModel & { new(): HydratedDocument }) ||
- mongoose.model('User', userSchema);
+const User =
+ (mongoose.models.User as UserModel & { new (): HydratedDocument }) ||
+ mongoose.model("User", userSchema);
export default User;
diff --git a/app/spec/cache.spec.ts b/app/spec/cache.spec.ts
index adf554e..cf6682b 100644
--- a/app/spec/cache.spec.ts
+++ b/app/spec/cache.spec.ts
@@ -1,23 +1,23 @@
/* eslint-disable no-underscore-dangle */
-import * as Cache from '../cache';
+import * as Cache from "../cache";
// eslint-disable-next-line @typescript-eslint/no-require-imports
-const redis = require('redis');
+const redis = require("redis");
-jest.mock('redis');
+jest.mock("redis");
-describe('cache', () => {
+describe("cache", () => {
beforeEach(() => {
redis._get.mockClear();
redis._set.mockClear();
redis._reset();
});
- describe('set', () => {
- it('writes given data to redis store', async () => {
- const key = 'foo';
- const value = ['bar'];
+ describe("set", () => {
+ it("writes given data to redis store", async () => {
+ const key = "foo";
+ const value = ["bar"];
await Cache.set(key, value);
@@ -27,9 +27,9 @@ describe('cache', () => {
expect(redis._set.mock.calls[0][2]).toEqual({ EX: 86400 });
});
- it('passes given ttl to redis store', async () => {
- const key = 'foo';
- const value = ['bar'];
+ it("passes given ttl to redis store", async () => {
+ const key = "foo";
+ const value = ["bar"];
const ttl = 1337;
await Cache.set(key, value, ttl);
@@ -37,9 +37,9 @@ describe('cache', () => {
expect(redis._set.mock.calls[0][2]).toEqual({ EX: ttl });
});
- it('uses 24 hours as default ttl', async () => {
- const key = 'foo';
- const value = ['bar'];
+ it("uses 24 hours as default ttl", async () => {
+ const key = "foo";
+ const value = ["bar"];
await Cache.set(key, value);
@@ -47,13 +47,13 @@ describe('cache', () => {
});
});
- describe('get', () => {
- it('queries data from redis store', async () => {
- const key = 'foo';
+ describe("get", () => {
+ it("queries data from redis store", async () => {
+ const key = "foo";
try {
await Cache.get(key);
- } catch (e) {
+ } catch {
// ignore errors
}
@@ -61,9 +61,9 @@ describe('cache', () => {
expect(redis._get.mock.calls[0][0]).toBe(key);
});
- it('returns correct data from redis store after it was saved', async () => {
- const key = 'foo';
- const value = ['bar'];
+ it("returns correct data from redis store after it was saved", async () => {
+ const key = "foo";
+ const value = ["bar"];
await Cache.set(key, value);
const cachedData = await Cache.get(key);
@@ -71,8 +71,8 @@ describe('cache', () => {
expect(cachedData).toEqual(value);
});
- it('rejects the promise when no data is stored in redis', () => {
- const key = 'foo';
+ it("rejects the promise when no data is stored in redis", () => {
+ const key = "foo";
expect(Cache.get(key)).rejects.toBeUndefined();
});
diff --git a/client/reduxStore.ts b/client/reduxStore.ts
index d09fd96..1253fb7 100644
--- a/client/reduxStore.ts
+++ b/client/reduxStore.ts
@@ -1,13 +1,13 @@
-import { thunk as thunkMiddleware } from 'redux-thunk';
-import { combineReducers, createStore, applyMiddleware } from 'redux';
-import { composeWithDevToolsLogOnlyInProduction as composeWithDevTools } from '@redux-devtools/extension';
-import { createWrapper } from 'next-redux-wrapper';
+import { thunk as thunkMiddleware } from "redux-thunk";
+import { combineReducers, createStore, applyMiddleware } from "redux";
+import { composeWithDevToolsLogOnlyInProduction as composeWithDevTools } from "@redux-devtools/extension";
+import { createWrapper } from "next-redux-wrapper";
-import sessionReducer from '../components/session/reducers/sessionReducer';
-import historyReducer from '../components/profile/reducers/historyReducer';
-import autoScrobbleReducer from '../components/profile/reducers/autoScrobbleReducer';
-import releaseReducer from '../components/release/reducers/releaseReducer';
-import queryReducer from '../components/query/reducers/queryReducer';
+import sessionReducer from "../components/session/reducers/sessionReducer";
+import historyReducer from "../components/profile/reducers/historyReducer";
+import autoScrobbleReducer from "../components/profile/reducers/autoScrobbleReducer";
+import releaseReducer from "../components/release/reducers/releaseReducer";
+import queryReducer from "../components/query/reducers/queryReducer";
const reducer = combineReducers({
session: sessionReducer,
@@ -17,10 +17,7 @@ const reducer = combineReducers({
query: queryReducer,
});
-const makeStore = () => createStore(
- reducer,
- composeWithDevTools(applyMiddleware(thunkMiddleware)),
-);
+const makeStore = () => createStore(reducer, composeWithDevTools(applyMiddleware(thunkMiddleware)));
export const wrapper = createWrapper(makeStore);
export default makeStore;
diff --git a/components/assets/Logo.tsx b/components/assets/Logo.tsx
index 2368ff8..0d33585 100644
--- a/components/assets/Logo.tsx
+++ b/components/assets/Logo.tsx
@@ -1,7 +1,10 @@
const Logo = ({ className = undefined, ...props }: { className?: string; [key: string]: any }) => (
CodeScrobble
-
+
diff --git a/components/assets/LogoSmall.tsx b/components/assets/LogoSmall.tsx
index 7b8ae2e..8b0e0e4 100644
--- a/components/assets/LogoSmall.tsx
+++ b/components/assets/LogoSmall.tsx
@@ -1,7 +1,10 @@
const Logo = ({ className = undefined, ...props }: { className?: string; [key: string]: any }) => (
CodeScrobble
-
+
);
diff --git a/components/icons/ErrorIcon.tsx b/components/icons/ErrorIcon.tsx
index 8490401..8e7bc0d 100644
--- a/components/icons/ErrorIcon.tsx
+++ b/components/icons/ErrorIcon.tsx
@@ -4,7 +4,7 @@ interface ErrorIconProps {
className?: string;
}
-const ErrorIcon = ({ color = '#000', size = 100, className }: ErrorIconProps) => (
+const ErrorIcon = ({ color = "#000", size = 100, className }: ErrorIconProps) => (
Error
diff --git a/components/icons/LastfmIcon.tsx b/components/icons/LastfmIcon.tsx
index b44f0d6..3db2d1f 100644
--- a/components/icons/LastfmIcon.tsx
+++ b/components/icons/LastfmIcon.tsx
@@ -4,10 +4,13 @@ interface LastfmIconProps {
[key: string]: any;
}
-const LastfmIcon = ({ color = '#fff', ...props }: LastfmIconProps) => (
+const LastfmIcon = ({ color = "#fff", ...props }: LastfmIconProps) => (
Last.fm
-
+
);
diff --git a/components/icons/LogoIcon.tsx b/components/icons/LogoIcon.tsx
index 26c8648..d310102 100644
--- a/components/icons/LogoIcon.tsx
+++ b/components/icons/LogoIcon.tsx
@@ -4,7 +4,7 @@ interface LogoIconProps {
className?: string;
}
-const LogoIcon = ({ color = '#000', size = 100, className }: LogoIconProps) => (
+const LogoIcon = ({ color = "#000", size = 100, className }: LogoIconProps) => (
diff --git a/components/icons/NoResultsIcon.tsx b/components/icons/NoResultsIcon.tsx
index e798c4a..d3d202f 100644
--- a/components/icons/NoResultsIcon.tsx
+++ b/components/icons/NoResultsIcon.tsx
@@ -4,7 +4,7 @@ interface NoResultsIconProps {
className?: string;
}
-const NoResultsIcon = ({ color = '#000', size = 100, className }: NoResultsIconProps) => (
+const NoResultsIcon = ({ color = "#000", size = 100, className }: NoResultsIconProps) => (
diff --git a/components/layout/BaseStyles.ts b/components/layout/BaseStyles.ts
index e896885..2d99977 100644
--- a/components/layout/BaseStyles.ts
+++ b/components/layout/BaseStyles.ts
@@ -1,5 +1,5 @@
-import { createGlobalStyle } from 'styled-components';
-import { dark, silver } from '../../lib/colors';
+import { createGlobalStyle } from "styled-components";
+import { dark, silver } from "../../lib/colors";
export default createGlobalStyle`
html {
diff --git a/components/layout/CircleLayout.tsx b/components/layout/CircleLayout.tsx
index b907d33..b61130a 100644
--- a/components/layout/CircleLayout.tsx
+++ b/components/layout/CircleLayout.tsx
@@ -1,11 +1,19 @@
-import React from 'react';
-import { createGlobalStyle } from 'styled-components';
-import Link from 'next/link';
+import React from "react";
+import { createGlobalStyle } from "styled-components";
+import Link from "next/link";
import {
- Center, Content, Footer, Header, HeightWrapper, Logo, LogoWrapper, SessionWrapper, Wrapper,
-} from '../../styles/layout.styles';
-import Session from '../session/Session';
-import LegalLinks from '../ui/LegalLinks';
+ Center,
+ Content,
+ Footer,
+ Header,
+ HeightWrapper,
+ Logo,
+ LogoWrapper,
+ SessionWrapper,
+ Wrapper,
+} from "../../styles/layout.styles";
+import Session from "../session/Session";
+import LegalLinks from "../ui/LegalLinks";
const ScrollLock = createGlobalStyle`
body {
@@ -37,9 +45,7 @@ const CircleLayout = ({ children = null, header = null, footer = null }: CircleL
{header}
-
- {children}
-
+ {children}
diff --git a/components/layout/Loading.tsx b/components/layout/Loading.tsx
index cdad63d..3874a95 100644
--- a/components/layout/Loading.tsx
+++ b/components/layout/Loading.tsx
@@ -1,4 +1,4 @@
-import { LoadingSpinner, LoadingWrapper } from './styles/Loading.styles';
+import { LoadingSpinner, LoadingWrapper } from "./styles/Loading.styles";
const Loading = () => (
diff --git a/components/layout/Spinner.tsx b/components/layout/Spinner.tsx
index ff026be..c6f3aa6 100644
--- a/components/layout/Spinner.tsx
+++ b/components/layout/Spinner.tsx
@@ -1,5 +1,5 @@
-import styled, { keyframes } from 'styled-components';
-import { yellow, yellowRGB } from '../../lib/colors';
+import styled, { keyframes } from "styled-components";
+import { yellow, yellowRGB } from "../../lib/colors";
export const animation = keyframes`
to {
@@ -12,7 +12,7 @@ const Spinner = styled.div<{ size?: number | string }>`
width: ${props => props.size}px;
height: ${props => props.size}px;
animation: ${animation} 1s ease-in-out infinite;
- border: 3px solid rgba(${yellowRGB}, .3);
+ border: 3px solid rgba(${yellowRGB}, 0.3);
border-radius: 50%;
border-top-color: ${yellow};
`;
diff --git a/components/layout/styles/Error.styles.ts b/components/layout/styles/Error.styles.ts
index 7d01e8c..819bace 100644
--- a/components/layout/styles/Error.styles.ts
+++ b/components/layout/styles/Error.styles.ts
@@ -1,5 +1,5 @@
-import styled from 'styled-components';
-import ErrorIconSVG from '../../icons/ErrorIcon';
+import styled from "styled-components";
+import ErrorIconSVG from "../../icons/ErrorIcon";
export const Error = styled.div`
display: flex;
diff --git a/components/layout/styles/Loading.styles.ts b/components/layout/styles/Loading.styles.ts
index e06e205..86891ef 100644
--- a/components/layout/styles/Loading.styles.ts
+++ b/components/layout/styles/Loading.styles.ts
@@ -1,5 +1,5 @@
-import styled from 'styled-components';
-import Spinner from '../Spinner';
+import styled from "styled-components";
+import Spinner from "../Spinner";
export const LoadingWrapper = styled.div`
display: flex;
diff --git a/components/profile/ProfileAutoScrobbleItem.tsx b/components/profile/ProfileAutoScrobbleItem.tsx
index 3a35482..f692315 100644
--- a/components/profile/ProfileAutoScrobbleItem.tsx
+++ b/components/profile/ProfileAutoScrobbleItem.tsx
@@ -1,9 +1,9 @@
-import { bindActionCreators } from 'redux';
-import { connect } from 'react-redux';
-import React from 'react';
-import { TrashAlt as DeleteIcon } from 'styled-icons/fa-regular';
-import { deleteAutoScrobble } from './actions/autoScrobbleActions';
-import { DeleteButton, ListCaption, ListItem } from '../../styles/profile.styles';
+import { bindActionCreators } from "redux";
+import { connect } from "react-redux";
+import React from "react";
+import { TrashAlt as DeleteIcon } from "styled-icons/fa-regular";
+import { deleteAutoScrobble } from "./actions/autoScrobbleActions";
+import { DeleteButton, ListCaption, ListItem } from "../../styles/profile.styles";
interface ProfileAutoScrobbleItemProps {
id: string;
@@ -18,12 +18,10 @@ class ProfileAutoScrobbleItem extends React.PureComponent {
const { id } = this.props;
this.props.deleteAutoScrobble(id);
- }
+ };
render() {
- const {
- id, artist, title, year, isDeleting = false,
- } = this.props;
+ const { id, artist, title, year, isDeleting = false } = this.props;
return (
@@ -38,11 +36,6 @@ class ProfileAutoScrobbleItem extends React.PureComponent (
- bindActionCreators({ deleteAutoScrobble }, dispatch)
-);
+const mapDispatchToProps = dispatch => bindActionCreators({ deleteAutoScrobble }, dispatch);
-export default connect(
- null,
- mapDispatchToProps,
-)(ProfileAutoScrobbleItem);
+export default connect(null, mapDispatchToProps)(ProfileAutoScrobbleItem);
diff --git a/components/profile/ProfileAutoScrobbles.tsx b/components/profile/ProfileAutoScrobbles.tsx
index e1f025d..e0cae5f 100644
--- a/components/profile/ProfileAutoScrobbles.tsx
+++ b/components/profile/ProfileAutoScrobbles.tsx
@@ -1,12 +1,10 @@
-import { bindActionCreators } from 'redux';
-import { connect } from 'react-redux';
-import React from 'react';
-import { fetchAutoScrobbles } from './actions/autoScrobbleActions';
-import {
- Fallback, H3, List, Meta,
-} from '../../styles/profile.styles';
-import ProfileAutoScrobbleItem from './ProfileAutoScrobbleItem';
-import Spinner from '../layout/Spinner';
+import { bindActionCreators } from "redux";
+import { connect } from "react-redux";
+import React from "react";
+import { fetchAutoScrobbles } from "./actions/autoScrobbleActions";
+import { Fallback, H3, List, Meta } from "../../styles/profile.styles";
+import ProfileAutoScrobbleItem from "./ProfileAutoScrobbleItem";
+import Spinner from "../layout/Spinner";
interface ProfileAutoScrobblesProps {
data?: any[];
@@ -21,33 +19,25 @@ class ProfileAutoScrobbles extends React.PureComponent
Auto-scrobbles
These items are automatically scrobbled the next time they are scanned
- {loading
- ?
- : (
-
- {!data.length && (
-
- No entries found. Activate the option "Auto-scrobble"
- during your next scan.
-
- )}
- {data.map(item => (
-
- ))}
-
- )
- }
+ {loading ? (
+
+ ) : (
+
+ {!data.length && (
+
+ No entries found. Activate the option "Auto-scrobble" during your next scan.
+
+ )}
+ {data.map(item => (
+
+ ))}
+
+ )}
>
);
}
@@ -59,11 +49,6 @@ const mapStateToProps = state => ({
deleting: state.autoScrobbles.deleting,
});
-const mapDispatchToProps = dispatch => (
- bindActionCreators({ fetchAutoScrobbles }, dispatch)
-);
+const mapDispatchToProps = dispatch => bindActionCreators({ fetchAutoScrobbles }, dispatch);
-export default connect(
- mapStateToProps,
- mapDispatchToProps,
-)(ProfileAutoScrobbles);
+export default connect(mapStateToProps, mapDispatchToProps)(ProfileAutoScrobbles);
diff --git a/components/profile/ProfileHistory.tsx b/components/profile/ProfileHistory.tsx
index 857ea6d..0189f0e 100644
--- a/components/profile/ProfileHistory.tsx
+++ b/components/profile/ProfileHistory.tsx
@@ -1,12 +1,10 @@
-import { bindActionCreators } from 'redux';
-import { connect } from 'react-redux';
-import React from 'react';
-import { fetchHistory } from './actions/historyActions';
-import {
- Fallback, H3, List, Meta,
-} from '../../styles/profile.styles';
-import ProfileHistoryItem from './ProfileHistoryItem';
-import Spinner from '../layout/Spinner';
+import { bindActionCreators } from "redux";
+import { connect } from "react-redux";
+import React from "react";
+import { fetchHistory } from "./actions/historyActions";
+import { Fallback, H3, List, Meta } from "../../styles/profile.styles";
+import ProfileHistoryItem from "./ProfileHistoryItem";
+import Spinner from "../layout/Spinner";
interface ProfileHistoryProps {
history?: any[];
@@ -25,24 +23,16 @@ class ProfileHistory extends React.PureComponent {
<>
History
Your recently scanned items. Tap one to scrobble it again.
- {loading
- ?
- : (
-
- {!history.length && (
-
- No entries found.
-
- )}
- {history.map(item => (
-
- ))}
-
- )
- }
+ {loading ? (
+
+ ) : (
+
+ {!history.length && No entries found. }
+ {history.map(item => (
+
+ ))}
+
+ )}
>
);
}
@@ -53,11 +43,6 @@ const mapStateToProps = state => ({
loading: state.history.loading,
});
-const mapDispatchToProps = dispatch => (
- bindActionCreators({ fetchHistory }, dispatch)
-);
+const mapDispatchToProps = dispatch => bindActionCreators({ fetchHistory }, dispatch);
-export default connect(
- mapStateToProps,
- mapDispatchToProps,
-)(ProfileHistory);
+export default connect(mapStateToProps, mapDispatchToProps)(ProfileHistory);
diff --git a/components/profile/ProfileHistoryItem.tsx b/components/profile/ProfileHistoryItem.tsx
index 4983271..6a12026 100644
--- a/components/profile/ProfileHistoryItem.tsx
+++ b/components/profile/ProfileHistoryItem.tsx
@@ -1,6 +1,6 @@
-import React from 'react';
-import Link from 'next/link';
-import { ListCaption, ListItem, Time } from '../../styles/profile.styles';
+import React from "react";
+import Link from "next/link";
+import { ListCaption, ListItem, Time } from "../../styles/profile.styles";
interface ProfileHistoryItemProps {
id: string;
@@ -15,9 +15,7 @@ interface ProfileHistoryItemProps {
class ProfileHistoryItem extends React.PureComponent {
render() {
- const {
- id, artist, title, year, barcode, discogsId, time, isDeleting = false,
- } = this.props;
+ const { id, artist, title, year, barcode, discogsId, time, isDeleting = false } = this.props;
const barcodeParam = barcode || `id:${discogsId}`;
diff --git a/components/profile/actions/autoScrobbleActionCreators.ts b/components/profile/actions/autoScrobbleActionCreators.ts
index 20f27f1..9962faa 100644
--- a/components/profile/actions/autoScrobbleActionCreators.ts
+++ b/components/profile/actions/autoScrobbleActionCreators.ts
@@ -1,7 +1,11 @@
import {
- SET_LOADING_STATE, SET_ERROR_STATE, RECEIVED_AUTO_SCROBBLES, START_DELETING,
- REMOVE_AUTO_SCROBBLE, END_DELETING,
-} from '../constants/autoScrobbleConstants';
+ SET_LOADING_STATE,
+ SET_ERROR_STATE,
+ RECEIVED_AUTO_SCROBBLES,
+ START_DELETING,
+ REMOVE_AUTO_SCROBBLE,
+ END_DELETING,
+} from "../constants/autoScrobbleConstants";
export const setLoadingState = loading => ({
type: SET_LOADING_STATE,
diff --git a/components/profile/actions/autoScrobbleActions.ts b/components/profile/actions/autoScrobbleActions.ts
index 96e33b5..0a0fdb8 100644
--- a/components/profile/actions/autoScrobbleActions.ts
+++ b/components/profile/actions/autoScrobbleActions.ts
@@ -1,37 +1,37 @@
import {
- setLoadingState, receivedAutoScrobbles, setErrorState, startDeleting,
- removeAutoScrobble, endDeleting,
-} from './autoScrobbleActionCreators';
+ setLoadingState,
+ receivedAutoScrobbles,
+ setErrorState,
+ startDeleting,
+ removeAutoScrobble,
+ endDeleting,
+} from "./autoScrobbleActionCreators";
-export const fetchAutoScrobbles = () => (
- async (dispatch) => {
- try {
- dispatch(setLoadingState(true));
- const response = await fetch('/api/user/autoscrobbles', { credentials: 'include' });
- if (!response.ok) throw new Error(`HTTP ${response.status}`);
- const data = await response.json();
- dispatch(receivedAutoScrobbles(data));
- } catch (error) {
- dispatch(setErrorState(error));
- }
- dispatch(setLoadingState(false));
+export const fetchAutoScrobbles = () => async dispatch => {
+ try {
+ dispatch(setLoadingState(true));
+ const response = await fetch("/api/user/autoscrobbles", { credentials: "include" });
+ if (!response.ok) throw new Error(`HTTP ${response.status}`);
+ const data = await response.json();
+ dispatch(receivedAutoScrobbles(data));
+ } catch (error) {
+ dispatch(setErrorState(error));
}
-);
+ dispatch(setLoadingState(false));
+};
-export const deleteAutoScrobble = id => (
- async (dispatch) => {
- try {
- dispatch(startDeleting(id));
- await fetch('/api/user/autoscrobbles', {
- method: 'DELETE',
- credentials: 'include',
- headers: { 'Content-Type': 'application/json' },
- body: JSON.stringify({ id }),
- });
- dispatch(removeAutoScrobble(id));
- } catch (error) {
- dispatch(setErrorState(error));
- }
- dispatch(endDeleting(id));
+export const deleteAutoScrobble = id => async dispatch => {
+ try {
+ dispatch(startDeleting(id));
+ await fetch("/api/user/autoscrobbles", {
+ method: "DELETE",
+ credentials: "include",
+ headers: { "Content-Type": "application/json" },
+ body: JSON.stringify({ id }),
+ });
+ dispatch(removeAutoScrobble(id));
+ } catch (error) {
+ dispatch(setErrorState(error));
}
-);
+ dispatch(endDeleting(id));
+};
diff --git a/components/profile/actions/historyActionCreators.ts b/components/profile/actions/historyActionCreators.ts
index 503fed4..d346f72 100644
--- a/components/profile/actions/historyActionCreators.ts
+++ b/components/profile/actions/historyActionCreators.ts
@@ -1,4 +1,4 @@
-import { SET_LOADING_STATE, SET_ERROR_STATE, RECEIVED_HISTORY } from '../constants/historyConstants';
+import { SET_LOADING_STATE, SET_ERROR_STATE, RECEIVED_HISTORY } from "../constants/historyConstants";
export const setLoadingState = loading => ({
type: SET_LOADING_STATE,
diff --git a/components/profile/actions/historyActions.ts b/components/profile/actions/historyActions.ts
index 6acaa76..1ac0604 100644
--- a/components/profile/actions/historyActions.ts
+++ b/components/profile/actions/historyActions.ts
@@ -1,17 +1,15 @@
-import { setLoadingState, receivedHistory, setErrorState } from './historyActionCreators';
+import { setLoadingState, receivedHistory, setErrorState } from "./historyActionCreators";
// eslint-disable-next-line import/prefer-default-export
-export const fetchHistory = () => (
- async (dispatch) => {
- try {
- dispatch(setLoadingState(true));
- const response = await fetch('/api/user/history', { credentials: 'include' });
- if (!response.ok) throw new Error(`HTTP ${response.status}`);
- const data = await response.json();
- dispatch(receivedHistory(data));
- } catch (error) {
- dispatch(setErrorState(error));
- }
- dispatch(setLoadingState(false));
+export const fetchHistory = () => async dispatch => {
+ try {
+ dispatch(setLoadingState(true));
+ const response = await fetch("/api/user/history", { credentials: "include" });
+ if (!response.ok) throw new Error(`HTTP ${response.status}`);
+ const data = await response.json();
+ dispatch(receivedHistory(data));
+ } catch (error) {
+ dispatch(setErrorState(error));
}
-);
+ dispatch(setLoadingState(false));
+};
diff --git a/components/profile/actions/spec/autoScrobbleActionCreators.spec.ts b/components/profile/actions/spec/autoScrobbleActionCreators.spec.ts
index 3886d96..30ba317 100644
--- a/components/profile/actions/spec/autoScrobbleActionCreators.spec.ts
+++ b/components/profile/actions/spec/autoScrobbleActionCreators.spec.ts
@@ -1,86 +1,94 @@
import {
- setLoadingState, setErrorState, receivedAutoScrobbles, startDeleting, removeAutoScrobble,
+ setLoadingState,
+ setErrorState,
+ receivedAutoScrobbles,
+ startDeleting,
+ removeAutoScrobble,
endDeleting,
-} from '../autoScrobbleActionCreators';
+} from "../autoScrobbleActionCreators";
import {
- SET_LOADING_STATE, SET_ERROR_STATE, RECEIVED_AUTO_SCROBBLES, START_DELETING, END_DELETING,
+ SET_LOADING_STATE,
+ SET_ERROR_STATE,
+ RECEIVED_AUTO_SCROBBLES,
+ START_DELETING,
+ END_DELETING,
REMOVE_AUTO_SCROBBLE,
-} from '../../constants/autoScrobbleConstants';
+} from "../../constants/autoScrobbleConstants";
-describe('autoScrobbleActionCreators', () => {
- describe('setLoadingState', () => {
+describe("autoScrobbleActionCreators", () => {
+ describe("setLoadingState", () => {
const setLoadingStateAction = setLoadingState(true);
- it('returns correct type', () => {
+ it("returns correct type", () => {
expect(setLoadingStateAction).toMatchObject({ type: SET_LOADING_STATE });
});
- it('returns passed loading state in action', () => {
+ it("returns passed loading state in action", () => {
expect(setLoadingStateAction).toMatchObject({ loading: true });
});
});
- describe('setErrorState', () => {
- const error = 'FooBar';
+ describe("setErrorState", () => {
+ const error = "FooBar";
const setErrorStateAction = setErrorState(error);
- it('returns correct type', () => {
+ it("returns correct type", () => {
expect(setErrorStateAction).toMatchObject({ type: SET_ERROR_STATE });
});
- it('returns passed error state in action', () => {
+ it("returns passed error state in action", () => {
expect(setErrorStateAction).toMatchObject({ error });
});
});
- describe('receivedAutoScrobbles', () => {
- const autoScrobbles = ['foo', 'bar'];
+ describe("receivedAutoScrobbles", () => {
+ const autoScrobbles = ["foo", "bar"];
const receivedAutoScrobblesAction = receivedAutoScrobbles(autoScrobbles);
- it('returns correct type', () => {
+ it("returns correct type", () => {
expect(receivedAutoScrobblesAction).toMatchObject({ type: RECEIVED_AUTO_SCROBBLES });
});
- it('returns autoScrobbles in action', () => {
+ it("returns autoScrobbles in action", () => {
expect(receivedAutoScrobblesAction).toMatchObject({ autoScrobbles });
});
});
- describe('startDeleting', () => {
+ describe("startDeleting", () => {
const id = 1337;
const startDeletingAction = startDeleting(id);
- it('returns correct type', () => {
+ it("returns correct type", () => {
expect(startDeletingAction).toMatchObject({ type: START_DELETING });
});
- it('returns id in action', () => {
+ it("returns id in action", () => {
expect(startDeletingAction).toMatchObject({ id });
});
});
- describe('removeAutoScrobble', () => {
+ describe("removeAutoScrobble", () => {
const id = 1337;
const removeAutoScrobbleAction = removeAutoScrobble(id);
- it('returns correct type', () => {
+ it("returns correct type", () => {
expect(removeAutoScrobbleAction).toMatchObject({ type: REMOVE_AUTO_SCROBBLE });
});
- it('returns id in action', () => {
+ it("returns id in action", () => {
expect(removeAutoScrobbleAction).toMatchObject({ id });
});
});
- describe('endDeleting', () => {
+ describe("endDeleting", () => {
const id = 1337;
const endDeletingAction = endDeleting(id);
- it('returns correct type', () => {
+ it("returns correct type", () => {
expect(endDeletingAction).toMatchObject({ type: END_DELETING });
});
- it('returns id in action', () => {
+ it("returns id in action", () => {
expect(endDeletingAction).toMatchObject({ id });
});
});
diff --git a/components/profile/actions/spec/autoScrobbleActions.spec.ts b/components/profile/actions/spec/autoScrobbleActions.spec.ts
index 0ad5577..4d68c33 100644
--- a/components/profile/actions/spec/autoScrobbleActions.spec.ts
+++ b/components/profile/actions/spec/autoScrobbleActions.spec.ts
@@ -1,10 +1,8 @@
-import configureMockStore from 'redux-mock-store';
-import { thunk } from "redux-thunk";;
+import configureMockStore from "redux-mock-store";
+import { thunk } from "redux-thunk";
-import * as actionCreators from '../autoScrobbleActionCreators';
-import {
- fetchAutoScrobbles, deleteAutoScrobble,
-} from '../autoScrobbleActions';
+import * as actionCreators from "../autoScrobbleActionCreators";
+import { fetchAutoScrobbles, deleteAutoScrobble } from "../autoScrobbleActions";
const middlewares = [thunk];
const mockStore = configureMockStore(middlewares);
@@ -13,14 +11,14 @@ const emptyStore = () => mockStore();
const demoAutoScrobbleData = [
{
- id: '5ccb6ad74c5f76adff751342',
- artist: 'Farin Urlaub',
- title: 'Am Ende Der Sonne',
- year: '2005',
+ id: "5ccb6ad74c5f76adff751342",
+ artist: "Farin Urlaub",
+ title: "Am Ende Der Sonne",
+ year: "2005",
},
];
-describe('historyActions', () => {
+describe("historyActions", () => {
beforeEach(() => {
fetch.mockResponse(JSON.stringify(demoAutoScrobbleData));
});
@@ -28,115 +26,117 @@ describe('historyActions', () => {
fetch.resetMocks();
});
- describe('fetchAutoScrobbles', () => {
- it('sets loading state to true as first action', () => {
+ describe("fetchAutoScrobbles", () => {
+ it("sets loading state to true as first action", () => {
const expectedAction = actionCreators.setLoadingState(true);
const store = emptyStore();
- return store.dispatch(fetchAutoScrobbles())
- .then(() => expect(store.getActions()[0]).toEqual(expectedAction));
+ return store.dispatch(fetchAutoScrobbles()).then(() => expect(store.getActions()[0]).toEqual(expectedAction));
});
- it('sets loading state back to false as last action', () => {
+ it("sets loading state back to false as last action", () => {
const expectedAction = actionCreators.setLoadingState(false);
const store = emptyStore();
- return store.dispatch(fetchAutoScrobbles())
+ return store
+ .dispatch(fetchAutoScrobbles())
.then(() => expect(store.getActions().slice(-1)[0]).toEqual(expectedAction));
});
- it('creates RECEIVED_HISTORY when fetching history has been done', () => {
+ it("creates RECEIVED_HISTORY when fetching history has been done", () => {
const expectedAction = actionCreators.receivedAutoScrobbles(demoAutoScrobbleData);
const store = emptyStore();
- return store.dispatch(fetchAutoScrobbles())
- .then(() => expect(store.getActions()).toContainEqual(expectedAction));
+ return store.dispatch(fetchAutoScrobbles()).then(() => expect(store.getActions()).toContainEqual(expectedAction));
});
- it('sets error state to store when loading fails', () => {
- const error = new Error('Foooo!');
+ it("sets error state to store when loading fails", () => {
+ const error = new Error("Foooo!");
fetch.mockReject(error);
const expectedAction = actionCreators.setErrorState(error);
const store = emptyStore();
- return store.dispatch(fetchAutoScrobbles())
- .then(() => expect(store.getActions()).toContainEqual(expectedAction));
+ return store.dispatch(fetchAutoScrobbles()).then(() => expect(store.getActions()).toContainEqual(expectedAction));
});
- it('sets loading state back to false after an error occured', () => {
+ it("sets loading state back to false after an error occured", () => {
const expectedAction = actionCreators.setLoadingState(false);
const store = emptyStore();
- return store.dispatch(fetchAutoScrobbles())
+ return store
+ .dispatch(fetchAutoScrobbles())
.then(() => expect(store.getActions().slice(-1)[0]).toEqual(expectedAction));
});
- it('sends a GET request to the api to get the history data', () => {
+ it("sends a GET request to the api to get the history data", () => {
const store = emptyStore();
return store.dispatch(fetchAutoScrobbles()).then(() => {
expect(fetch.mock.calls.length).toEqual(1);
- expect(fetch.mock.calls[0][0]).toEqual('/api/user/autoscrobbles');
+ expect(fetch.mock.calls[0][0]).toEqual("/api/user/autoscrobbles");
});
});
});
- describe('deleteAutoScrobble', () => {
- it('adds given id to deleting array as first action', () => {
+ describe("deleteAutoScrobble", () => {
+ it("adds given id to deleting array as first action", () => {
const id = 1337;
const expectedAction = actionCreators.startDeleting(id);
const store = emptyStore();
- return store.dispatch(deleteAutoScrobble(id))
- .then(() => expect(store.getActions()[0]).toEqual(expectedAction));
+ return store.dispatch(deleteAutoScrobble(id)).then(() => expect(store.getActions()[0]).toEqual(expectedAction));
});
- it('removes given id from deleting array as last action', () => {
+ it("removes given id from deleting array as last action", () => {
const id = 1337;
const expectedAction = actionCreators.endDeleting(id);
const store = emptyStore();
- return store.dispatch(deleteAutoScrobble(id))
+ return store
+ .dispatch(deleteAutoScrobble(id))
.then(() => expect(store.getActions().slice(-1)[0]).toEqual(expectedAction));
});
- it('removes the given id from autoscrobbles after deleting', () => {
+ it("removes the given id from autoscrobbles after deleting", () => {
const id = 1337;
const expectedAction = actionCreators.removeAutoScrobble(id);
const store = emptyStore();
- return store.dispatch(deleteAutoScrobble(id))
+ return store
+ .dispatch(deleteAutoScrobble(id))
.then(() => expect(store.getActions()).toContainEqual(expectedAction));
});
- it('sets error state to store when loading fails', () => {
+ it("sets error state to store when loading fails", () => {
const id = 1337;
- const error = new Error('Foooo!');
+ const error = new Error("Foooo!");
fetch.mockReject(error);
const expectedAction = actionCreators.setErrorState(error);
const store = emptyStore();
- return store.dispatch(deleteAutoScrobble(id))
+ return store
+ .dispatch(deleteAutoScrobble(id))
.then(() => expect(store.getActions()).toContainEqual(expectedAction));
});
- it('sets loading state back to false after an error occured', () => {
+ it("sets loading state back to false after an error occured", () => {
const id = 1337;
const expectedAction = actionCreators.endDeleting(id);
const store = emptyStore();
- return store.dispatch(deleteAutoScrobble(id))
+ return store
+ .dispatch(deleteAutoScrobble(id))
.then(() => expect(store.getActions().slice(-1)[0]).toEqual(expectedAction));
});
- it('sends a DELETE request to the api to delete the data', () => {
+ it("sends a DELETE request to the api to delete the data", () => {
const id = 1337;
const store = emptyStore();
return store.dispatch(deleteAutoScrobble(id)).then(() => {
expect(fetch.mock.calls.length).toEqual(1);
- expect(fetch.mock.calls[0][0]).toEqual('/api/user/autoscrobbles');
- expect(fetch.mock.calls[0][1].method).toEqual('DELETE');
+ expect(fetch.mock.calls[0][0]).toEqual("/api/user/autoscrobbles");
+ expect(fetch.mock.calls[0][1].method).toEqual("DELETE");
expect(fetch.mock.calls[0][1].body).toEqual(JSON.stringify({ id }));
});
});
diff --git a/components/profile/actions/spec/historyActionCreators.spec.ts b/components/profile/actions/spec/historyActionCreators.spec.ts
index eaad1c2..c28c314 100644
--- a/components/profile/actions/spec/historyActionCreators.spec.ts
+++ b/components/profile/actions/spec/historyActionCreators.spec.ts
@@ -1,41 +1,41 @@
-import { setLoadingState, setErrorState, receivedHistory } from '../historyActionCreators';
-import { SET_LOADING_STATE, SET_ERROR_STATE, RECEIVED_HISTORY } from '../../constants/historyConstants';
+import { setLoadingState, setErrorState, receivedHistory } from "../historyActionCreators";
+import { SET_LOADING_STATE, SET_ERROR_STATE, RECEIVED_HISTORY } from "../../constants/historyConstants";
-describe('historyActionCreators', () => {
- describe('setLoadingState', () => {
+describe("historyActionCreators", () => {
+ describe("setLoadingState", () => {
const setLoadingStateAction = setLoadingState(true);
- it('returns correct type', () => {
+ it("returns correct type", () => {
expect(setLoadingStateAction).toMatchObject({ type: SET_LOADING_STATE });
});
- it('returns passed loading state in action', () => {
+ it("returns passed loading state in action", () => {
expect(setLoadingStateAction).toMatchObject({ loading: true });
});
});
- describe('setErrorState', () => {
- const error = 'FooBar';
+ describe("setErrorState", () => {
+ const error = "FooBar";
const setErrorStateAction = setErrorState(error);
- it('returns correct type', () => {
+ it("returns correct type", () => {
expect(setErrorStateAction).toMatchObject({ type: SET_ERROR_STATE });
});
- it('returns passed error state in action', () => {
+ it("returns passed error state in action", () => {
expect(setErrorStateAction).toMatchObject({ error });
});
});
- describe('receivedHistory', () => {
- const history = ['foo', 'bar'];
+ describe("receivedHistory", () => {
+ const history = ["foo", "bar"];
const receivedHistoryAction = receivedHistory(history);
- it('returns correct type', () => {
+ it("returns correct type", () => {
expect(receivedHistoryAction).toMatchObject({ type: RECEIVED_HISTORY });
});
- it('returns history in action', () => {
+ it("returns history in action", () => {
expect(receivedHistoryAction).toMatchObject({ history });
});
});
diff --git a/components/profile/actions/spec/historyActions.spec.ts b/components/profile/actions/spec/historyActions.spec.ts
index a8bbb5a..99eeb1d 100644
--- a/components/profile/actions/spec/historyActions.spec.ts
+++ b/components/profile/actions/spec/historyActions.spec.ts
@@ -1,25 +1,27 @@
-import configureMockStore from 'redux-mock-store';
-import { thunk } from "redux-thunk";;
+import configureMockStore from "redux-mock-store";
+import { thunk } from "redux-thunk";
-import * as actionCreators from '../historyActionCreators';
-import { fetchHistory } from '../historyActions';
+import * as actionCreators from "../historyActionCreators";
+import { fetchHistory } from "../historyActions";
const middlewares = [thunk];
const mockStore = configureMockStore(middlewares);
const emptyStore = () => mockStore({});
-const demoHistoryData = [{
- id: '5ccb6ae44c5f76adff751352',
- time: '2019-05-02T22:10:44.378Z',
- artist: 'Farin Urlaub',
- title: 'Am Ende Der Sonne',
- year: '2005',
- barcode: '0419594000028',
- discogsId: 2852926,
-}];
-
-describe('historyActions', () => {
+const demoHistoryData = [
+ {
+ id: "5ccb6ae44c5f76adff751352",
+ time: "2019-05-02T22:10:44.378Z",
+ artist: "Farin Urlaub",
+ title: "Am Ende Der Sonne",
+ year: "2005",
+ barcode: "0419594000028",
+ discogsId: 2852926,
+ },
+];
+
+describe("historyActions", () => {
beforeEach(() => {
fetch.mockResponse(JSON.stringify(demoHistoryData));
});
@@ -27,54 +29,49 @@ describe('historyActions', () => {
fetch.resetMocks();
});
- it('sets loading state to true as first action', () => {
+ it("sets loading state to true as first action", () => {
const expectedAction = actionCreators.setLoadingState(true);
const store = emptyStore();
- return store.dispatch(fetchHistory())
- .then(() => expect(store.getActions()[0]).toEqual(expectedAction));
+ return store.dispatch(fetchHistory()).then(() => expect(store.getActions()[0]).toEqual(expectedAction));
});
- it('sets loading state back to false as last action', () => {
+ it("sets loading state back to false as last action", () => {
const expectedAction = actionCreators.setLoadingState(false);
const store = emptyStore();
- return store.dispatch(fetchHistory())
- .then(() => expect(store.getActions().slice(-1)[0]).toEqual(expectedAction));
+ return store.dispatch(fetchHistory()).then(() => expect(store.getActions().slice(-1)[0]).toEqual(expectedAction));
});
- it('creates RECEIVED_HISTORY when fetching history has been done', () => {
+ it("creates RECEIVED_HISTORY when fetching history has been done", () => {
const expectedAction = actionCreators.receivedHistory(demoHistoryData);
const store = emptyStore();
- return store.dispatch(fetchHistory())
- .then(() => expect(store.getActions()).toContainEqual(expectedAction));
+ return store.dispatch(fetchHistory()).then(() => expect(store.getActions()).toContainEqual(expectedAction));
});
- it('sets error state to store when loading fails', () => {
- const error = new Error('Foooo!');
+ it("sets error state to store when loading fails", () => {
+ const error = new Error("Foooo!");
fetch.mockReject(error);
const expectedAction = actionCreators.setErrorState(error);
const store = emptyStore();
- return store.dispatch(fetchHistory())
- .then(() => expect(store.getActions()).toContainEqual(expectedAction));
+ return store.dispatch(fetchHistory()).then(() => expect(store.getActions()).toContainEqual(expectedAction));
});
- it('sets loading state back to false after an error occured', () => {
+ it("sets loading state back to false after an error occured", () => {
const expectedAction = actionCreators.setLoadingState(false);
const store = emptyStore();
- return store.dispatch(fetchHistory())
- .then(() => expect(store.getActions().slice(-1)[0]).toEqual(expectedAction));
+ return store.dispatch(fetchHistory()).then(() => expect(store.getActions().slice(-1)[0]).toEqual(expectedAction));
});
- it('sends a GET request to the api to get the history data', () => {
+ it("sends a GET request to the api to get the history data", () => {
const store = emptyStore();
return store.dispatch(fetchHistory()).then(() => {
expect(fetch.mock.calls.length).toEqual(1);
- expect(fetch.mock.calls[0][0]).toEqual('/api/user/history');
+ expect(fetch.mock.calls[0][0]).toEqual("/api/user/history");
});
});
});
diff --git a/components/profile/constants/autoScrobbleConstants.ts b/components/profile/constants/autoScrobbleConstants.ts
index 95c537c..1dce47d 100644
--- a/components/profile/constants/autoScrobbleConstants.ts
+++ b/components/profile/constants/autoScrobbleConstants.ts
@@ -1,6 +1,6 @@
-export const SET_LOADING_STATE = 'SET_AUTO_SCROBBLES_LOADING_STATE';
-export const SET_ERROR_STATE = 'SET_AUTO_SCROBBLES_ERROR_STATE';
-export const RECEIVED_AUTO_SCROBBLES = 'RECEIVED_AUTO_SCROBBLES';
-export const START_DELETING = 'START_DELETING_AUTO_SCROBBLE';
-export const END_DELETING = 'END_DELETING_AUTO_SCROBBLE';
-export const REMOVE_AUTO_SCROBBLE = 'REMOVE_AUTO_SCROBBLE';
+export const SET_LOADING_STATE = "SET_AUTO_SCROBBLES_LOADING_STATE";
+export const SET_ERROR_STATE = "SET_AUTO_SCROBBLES_ERROR_STATE";
+export const RECEIVED_AUTO_SCROBBLES = "RECEIVED_AUTO_SCROBBLES";
+export const START_DELETING = "START_DELETING_AUTO_SCROBBLE";
+export const END_DELETING = "END_DELETING_AUTO_SCROBBLE";
+export const REMOVE_AUTO_SCROBBLE = "REMOVE_AUTO_SCROBBLE";
diff --git a/components/profile/constants/historyConstants.ts b/components/profile/constants/historyConstants.ts
index fdf1c6b..bf7c9a6 100644
--- a/components/profile/constants/historyConstants.ts
+++ b/components/profile/constants/historyConstants.ts
@@ -1,3 +1,3 @@
-export const SET_LOADING_STATE = 'SET_HISTORY_LOADING_STATE';
-export const SET_ERROR_STATE = 'SET_HISTORY_ERROR_STATE';
-export const RECEIVED_HISTORY = 'RECEIVED_HISTORY';
+export const SET_LOADING_STATE = "SET_HISTORY_LOADING_STATE";
+export const SET_ERROR_STATE = "SET_HISTORY_ERROR_STATE";
+export const RECEIVED_HISTORY = "RECEIVED_HISTORY";
diff --git a/components/profile/reducers/autoScrobbleReducer.ts b/components/profile/reducers/autoScrobbleReducer.ts
index 397670a..4bf93ce 100644
--- a/components/profile/reducers/autoScrobbleReducer.ts
+++ b/components/profile/reducers/autoScrobbleReducer.ts
@@ -1,7 +1,11 @@
import {
- RECEIVED_AUTO_SCROBBLES, SET_LOADING_STATE, SET_ERROR_STATE, START_DELETING,
- END_DELETING, REMOVE_AUTO_SCROBBLE,
-} from '../constants/autoScrobbleConstants';
+ RECEIVED_AUTO_SCROBBLES,
+ SET_LOADING_STATE,
+ SET_ERROR_STATE,
+ START_DELETING,
+ END_DELETING,
+ REMOVE_AUTO_SCROBBLE,
+} from "../constants/autoScrobbleConstants";
const initialState = {
data: null,
diff --git a/components/profile/reducers/historyReducer.ts b/components/profile/reducers/historyReducer.ts
index b6912e8..7b54e83 100644
--- a/components/profile/reducers/historyReducer.ts
+++ b/components/profile/reducers/historyReducer.ts
@@ -1,4 +1,4 @@
-import { RECEIVED_HISTORY, SET_LOADING_STATE, SET_ERROR_STATE } from '../constants/historyConstants';
+import { RECEIVED_HISTORY, SET_LOADING_STATE, SET_ERROR_STATE } from "../constants/historyConstants";
const historyReducer = (state = {}, action: any = {}) => {
switch (action.type) {
diff --git a/components/profile/reducers/spec/autoScrobbleReducer.spec.ts b/components/profile/reducers/spec/autoScrobbleReducer.spec.ts
index 1250c2f..2273ab8 100644
--- a/components/profile/reducers/spec/autoScrobbleReducer.spec.ts
+++ b/components/profile/reducers/spec/autoScrobbleReducer.spec.ts
@@ -1,11 +1,15 @@
-import autoScrobbleReducer from '../autoScrobbleReducer';
+import autoScrobbleReducer from "../autoScrobbleReducer";
import {
- setLoadingState, setErrorState, receivedAutoScrobbles, startDeleting, removeAutoScrobble,
+ setLoadingState,
+ setErrorState,
+ receivedAutoScrobbles,
+ startDeleting,
+ removeAutoScrobble,
endDeleting,
-} from '../../actions/autoScrobbleActionCreators';
+} from "../../actions/autoScrobbleActionCreators";
-describe('autoScrobbleReducer', () => {
- it('uses the correct initial state', () => {
+describe("autoScrobbleReducer", () => {
+ it("uses the correct initial state", () => {
expect(autoScrobbleReducer()).toEqual({
data: null,
deleting: [],
@@ -14,11 +18,11 @@ describe('autoScrobbleReducer', () => {
});
});
- it('saves autoScrobbles to store', () => {
+ it("saves autoScrobbles to store", () => {
const state = {
data: null,
};
- const autoScrobbles = ['foo', 'bar'];
+ const autoScrobbles = ["foo", "bar"];
const action = receivedAutoScrobbles(autoScrobbles);
const nextState = autoScrobbleReducer(state, action);
@@ -27,7 +31,7 @@ describe('autoScrobbleReducer', () => {
});
});
- it('saves loading state to store', () => {
+ it("saves loading state to store", () => {
const state = {
loading: false,
};
@@ -39,11 +43,11 @@ describe('autoScrobbleReducer', () => {
});
});
- it('saves error state to store', () => {
+ it("saves error state to store", () => {
const state = {
error: null,
};
- const error = 'FooBar';
+ const error = "FooBar";
const action = setErrorState(error);
const nextState = autoScrobbleReducer(state, action);
@@ -52,42 +56,42 @@ describe('autoScrobbleReducer', () => {
});
});
- it('saves starting of delete-process to store', () => {
+ it("saves starting of delete-process to store", () => {
const state = {
- deleting: ['foo'],
+ deleting: ["foo"],
};
- const deleting = 'bar';
+ const deleting = "bar";
const action = startDeleting(deleting);
const nextState = autoScrobbleReducer(state, action);
expect(nextState).toEqual({
- deleting: ['foo', 'bar'],
+ deleting: ["foo", "bar"],
});
});
- it('removes autoScrobble from store', () => {
+ it("removes autoScrobble from store", () => {
const state = {
- data: [{ id: 'foo' }, { id: 'bar' }],
+ data: [{ id: "foo" }, { id: "bar" }],
};
- const deleting = 'foo';
+ const deleting = "foo";
const action = removeAutoScrobble(deleting);
const nextState = autoScrobbleReducer(state, action);
expect(nextState).toEqual({
- data: [{ id: 'bar' }],
+ data: [{ id: "bar" }],
});
});
- it('saves ending of delete-process to store', () => {
+ it("saves ending of delete-process to store", () => {
const state = {
- deleting: ['foo', 'bar'],
+ deleting: ["foo", "bar"],
};
- const deleting = 'bar';
+ const deleting = "bar";
const action = endDeleting(deleting);
const nextState = autoScrobbleReducer(state, action);
expect(nextState).toEqual({
- deleting: ['foo'],
+ deleting: ["foo"],
});
});
});
diff --git a/components/profile/reducers/spec/historyReducer.spec.ts b/components/profile/reducers/spec/historyReducer.spec.ts
index 3e25f6c..9bc089a 100644
--- a/components/profile/reducers/spec/historyReducer.spec.ts
+++ b/components/profile/reducers/spec/historyReducer.spec.ts
@@ -1,16 +1,16 @@
-import historyReducer from '../historyReducer';
-import { setLoadingState, setErrorState, receivedHistory } from '../../actions/historyActionCreators';
+import historyReducer from "../historyReducer";
+import { setLoadingState, setErrorState, receivedHistory } from "../../actions/historyActionCreators";
-describe('historyReducer', () => {
- it('uses an empty object as initial state', () => {
+describe("historyReducer", () => {
+ it("uses an empty object as initial state", () => {
expect(historyReducer()).toEqual({});
});
- it('saves history to store', () => {
+ it("saves history to store", () => {
const state = {
data: null,
};
- const history = ['foo', 'bar'];
+ const history = ["foo", "bar"];
const action = receivedHistory(history);
const nextState = historyReducer(state, action);
@@ -19,7 +19,7 @@ describe('historyReducer', () => {
});
});
- it('saves loading state to store', () => {
+ it("saves loading state to store", () => {
const state = {
loading: false,
};
@@ -31,11 +31,11 @@ describe('historyReducer', () => {
});
});
- it('saves error state to store', () => {
+ it("saves error state to store", () => {
const state = {
error: null,
};
- const error = 'FooBar';
+ const error = "FooBar";
const action = setErrorState(error);
const nextState = historyReducer(state, action);
diff --git a/components/query/QueryRelease.tsx b/components/query/QueryRelease.tsx
index bf94131..2592449 100644
--- a/components/query/QueryRelease.tsx
+++ b/components/query/QueryRelease.tsx
@@ -1,29 +1,44 @@
-import { bindActionCreators } from 'redux';
-import { connect, ConnectedProps } from 'react-redux';
-import React from 'react';
-import Head from 'next/head';
-import Link from 'next/link';
-import { IoIosSearch } from 'react-icons/io';
-import { MdClose } from 'react-icons/md';
-import compact from 'lodash/compact';
-import { trackEvent } from '../../lib/analytics';
-import { silver } from '../../lib/colors';
-import NoResultsIcon from '../icons/NoResultsIcon';
-import Loading from '../layout/Loading';
-import { queryRelease, resetResults, setQuery } from './actions/queryActions';
+import { bindActionCreators } from "redux";
+import { connect } from "react-redux";
+import type { ConnectedProps } from "react-redux";
+import React from "react";
+import Head from "next/head";
+import Link from "next/link";
+import { IoIosSearch } from "react-icons/io";
+import { MdClose } from "react-icons/md";
+import compact from "lodash/compact";
+import { trackEvent } from "../../lib/analytics";
+import { silver } from "../../lib/colors";
+import NoResultsIcon from "../icons/NoResultsIcon";
+import Loading from "../layout/Loading";
+import { queryRelease, resetResults, setQuery } from "./actions/queryActions";
import {
- Button, CloseButton, Content, FallbackIcon, FallbackWrapper, HeadWrapper, Icon, Input,
- LoadingWrapper, Meta, Overlay, Result, ResultInfo, ResultWrapper, Submit, Thumbnail,
- ThumbnailWrapper, Title, Wrapper,
-} from './styles/QueryRelease.styles';
+ Button,
+ CloseButton,
+ Content,
+ FallbackIcon,
+ FallbackWrapper,
+ HeadWrapper,
+ Icon,
+ Input,
+ LoadingWrapper,
+ Meta,
+ Overlay,
+ Result,
+ ResultInfo,
+ ResultWrapper,
+ Submit,
+ Thumbnail,
+ ThumbnailWrapper,
+ Title,
+ Wrapper,
+} from "./styles/QueryRelease.styles";
const mapStateToProps = (state: any) => ({
...(state.query as { results?: any[]; query?: string; loading?: boolean }),
});
-const mapDispatchToProps = (dispatch: any) => (
- bindActionCreators({ queryRelease, resetResults, setQuery }, dispatch)
-);
+const mapDispatchToProps = (dispatch: any) => bindActionCreators({ queryRelease, resetResults, setQuery }, dispatch);
const connector = connect(mapStateToProps, mapDispatchToProps);
type PropsFromRedux = ConnectedProps;
@@ -34,48 +49,56 @@ class QueryRelease extends React.Component {
this.props.resetResults();
this.props.setQuery();
this.setState({ searched: false });
- }
+ };
open = () => {
this.reset();
- trackEvent('Detect', 'Query Release');
+ trackEvent("Detect", "Query Release");
this.setState({ open: true });
- }
+ };
close = () => {
this.setState({ open: false, searched: false });
- }
+ };
- onInput = (e) => {
+ onInput = e => {
this.props.setQuery(e.target.value);
- }
+ };
- onSubmit = (e) => {
+ onSubmit = e => {
e.preventDefault();
this.inputRef.current.blur();
this.props.queryRelease();
this.setState({ searched: true });
- }
+ };
render() {
const { open, searched } = this.state;
- const { loading = false, results = [], query = '' } = this.props;
+ const { loading = false, results = [], query = "" } = this.props;
- let content = ;
+ let content = (
+
+
+
+ );
if (loading) {
- content = ;
+ content = (
+
+
+
+
+
+ );
} else if (results.length) {
content = (
- {results.map(({
- id, title, thumb, country, year, format = [],
- }) => (
+ {results.map(({ id, title, thumb, country, year, format = [] }) => (
@@ -86,9 +109,7 @@ class QueryRelease extends React.Component
-
- {compact([country, (format || []).join(', ')]).join(' · ')}
-
+ {compact([country, (format || []).join(", ")]).join(" · ")}
@@ -98,7 +119,7 @@ class QueryRelease extends React.Component
-
+
No results were found
for your query
@@ -121,7 +142,15 @@ class QueryRelease extends React.Component
-
+ {/* eslint-disable jsx-a11y/no-autofocus */}
+
+ {/* eslint-enable jsx-a11y/no-autofocus */}
diff --git a/components/query/actions/queryActionCreators.ts b/components/query/actions/queryActionCreators.ts
index 669060d..cec7fb0 100644
--- a/components/query/actions/queryActionCreators.ts
+++ b/components/query/actions/queryActionCreators.ts
@@ -1,6 +1,4 @@
-import {
- SET_LOADING_STATE, SET_ERROR_STATE, SET_QUERY_STRING, RECEIVED_RESULTS,
-} from '../constants/queryConstants';
+import { SET_LOADING_STATE, SET_ERROR_STATE, SET_QUERY_STRING, RECEIVED_RESULTS } from "../constants/queryConstants";
export const setLoadingState = loading => ({
type: SET_LOADING_STATE,
diff --git a/components/query/actions/queryActions.ts b/components/query/actions/queryActions.ts
index 9d3ce44..a24f944 100644
--- a/components/query/actions/queryActions.ts
+++ b/components/query/actions/queryActions.ts
@@ -1,30 +1,26 @@
-import {
- setLoadingState, setErrorState, setQueryString, receivedResults,
-} from './queryActionCreators';
+import { setLoadingState, setErrorState, setQueryString, receivedResults } from "./queryActionCreators";
-export const queryRelease = () => (
- async (dispatch, getState) => {
- try {
- dispatch(setLoadingState(true));
- const { query } = getState().query;
- const data = await fetch(`/api/search/${encodeURIComponent(query)}`, { credentials: 'include' }).then(r => r.json());
- dispatch(receivedResults(data));
- } catch (error) {
- dispatch(receivedResults([]));
- dispatch(setErrorState(error));
- }
- dispatch(setLoadingState(false));
+export const queryRelease = () => async (dispatch, getState) => {
+ try {
+ dispatch(setLoadingState(true));
+ const { query } = getState().query;
+ const data = await fetch(`/api/search/${encodeURIComponent(query)}`, { credentials: "include" }).then(r =>
+ r.json(),
+ );
+ dispatch(receivedResults(data));
+ } catch (error) {
+ dispatch(receivedResults([]));
+ dispatch(setErrorState(error));
}
-);
+ dispatch(setLoadingState(false));
+};
-export const setQuery = (query = '') => (
- (dispatch) => {
+export const setQuery =
+ (query = "") =>
+ dispatch => {
dispatch(setQueryString(query));
- }
-);
+ };
-export const resetResults = () => (
- (dispatch) => {
- dispatch(receivedResults([]));
- }
-);
+export const resetResults = () => dispatch => {
+ dispatch(receivedResults([]));
+};
diff --git a/components/query/constants/queryConstants.ts b/components/query/constants/queryConstants.ts
index 13729ba..b5d8c50 100644
--- a/components/query/constants/queryConstants.ts
+++ b/components/query/constants/queryConstants.ts
@@ -1,4 +1,4 @@
-export const SET_LOADING_STATE = 'SET_QUERY_LOADING_STATE';
-export const SET_ERROR_STATE = 'SET_QUERY_ERROR_STATE';
-export const SET_QUERY_STRING = 'SET_QUERY_STRING';
-export const RECEIVED_RESULTS = 'RECEIVED_QUERY_RESULTS';
+export const SET_LOADING_STATE = "SET_QUERY_LOADING_STATE";
+export const SET_ERROR_STATE = "SET_QUERY_ERROR_STATE";
+export const SET_QUERY_STRING = "SET_QUERY_STRING";
+export const RECEIVED_RESULTS = "RECEIVED_QUERY_RESULTS";
diff --git a/components/query/reducers/queryReducer.ts b/components/query/reducers/queryReducer.ts
index 82fb66f..e5a0bfe 100644
--- a/components/query/reducers/queryReducer.ts
+++ b/components/query/reducers/queryReducer.ts
@@ -1,9 +1,7 @@
-import {
- SET_LOADING_STATE, SET_ERROR_STATE, SET_QUERY_STRING, RECEIVED_RESULTS,
-} from '../constants/queryConstants';
+import { SET_LOADING_STATE, SET_ERROR_STATE, SET_QUERY_STRING, RECEIVED_RESULTS } from "../constants/queryConstants";
const initialState = {
- query: '',
+ query: "",
results: [],
error: null,
loading: false,
diff --git a/components/query/styles/QueryRelease.styles.ts b/components/query/styles/QueryRelease.styles.ts
index ce022ab..c1eedf4 100644
--- a/components/query/styles/QueryRelease.styles.ts
+++ b/components/query/styles/QueryRelease.styles.ts
@@ -1,8 +1,8 @@
-import { IoIosSearch } from 'react-icons/io';
-import styled from 'styled-components';
-import LogoIcon from '../../icons/LogoIcon';
-import { dark } from '../../../lib/colors';
-import { buttonReset } from '../../../styles/mixins';
+import { IoIosSearch } from "react-icons/io";
+import styled from "styled-components";
+import LogoIcon from "../../icons/LogoIcon";
+import { dark } from "../../../lib/colors";
+import { buttonReset } from "../../../styles/mixins";
export const Wrapper = styled.div`
position: relative;
@@ -43,7 +43,7 @@ export const Overlay = styled.div`
width: 100%;
height: 100%;
overflow: auto;
- background: rgba(0,0,0,.7);
+ background: rgba(0, 0, 0, 0.7);
backdrop-filter: blur(10px);
-webkit-overflow-scrolling: touch;
`;
diff --git a/components/release/ReleaseInfo.tsx b/components/release/ReleaseInfo.tsx
index 6ffe00a..18c0549 100644
--- a/components/release/ReleaseInfo.tsx
+++ b/components/release/ReleaseInfo.tsx
@@ -1,13 +1,29 @@
-import React from 'react';
-import { MdClose } from 'react-icons/md'; // TODO: replace
-import durationFormat from '../../lib/durationFormat';
-import targetBlank from '../../lib/targetBlank';
+import React from "react";
+import { MdClose } from "react-icons/md"; // TODO: replace
+import durationFormat from "../../lib/durationFormat";
+import targetBlank from "../../lib/targetBlank";
import {
- Artist, Button, CloseButton, Content, Cover, ExternalButton, Head, HeadWrapper, Icon, Meta,
- Overlay, Title, TrackDuration, TrackListWrapper, TrackNumber, TrackTitle, Wrapper, Year,
-} from './styles/ReleaseInfo.styles';
-import { silver } from '../../lib/colors';
-import { autotrackParams, trackEvent } from '../../lib/analytics';
+ Artist,
+ Button,
+ CloseButton,
+ Content,
+ Cover,
+ ExternalButton,
+ Head,
+ HeadWrapper,
+ Icon,
+ Meta,
+ Overlay,
+ Title,
+ TrackDuration,
+ TrackListWrapper,
+ TrackNumber,
+ TrackTitle,
+ Wrapper,
+ Year,
+} from "./styles/ReleaseInfo.styles";
+import { silver } from "../../lib/colors";
+import { autotrackParams, trackEvent } from "../../lib/analytics";
type Track = {
trackNumber: string;
@@ -31,21 +47,17 @@ interface ReleaseInfoProps {
class ReleaseInfo extends React.Component {
state = {
open: false,
- }
+ };
handleButton = () => {
const { open } = this.state;
- if (!open) trackEvent('Detected', 'Show Release Info');
+ if (!open) trackEvent("Detected", "Show Release Info");
this.setState(state => ({ open: !state.open }));
- }
+ };
render() {
const { open } = this.state;
- const {
- release: {
- image, title, year, artist, tracks, url,
- } = {} as Release,
- } = this.props;
+ const { release: { image, title, year, artist, tracks, url } = {} as Release } = this.props;
return (
@@ -80,7 +92,7 @@ class ReleaseInfo extends React.Component {
-
+
Show on Discogs
diff --git a/components/release/SearchRelease.tsx b/components/release/SearchRelease.tsx
index e391743..cb21393 100644
--- a/components/release/SearchRelease.tsx
+++ b/components/release/SearchRelease.tsx
@@ -1,13 +1,13 @@
-import { bindActionCreators } from 'redux';
-import { connect } from 'react-redux';
-import React from 'react';
-import { FaLastfm } from 'react-icons/fa';
-import { MdClose } from 'react-icons/md';
-import { fetchRelease } from './actions/releaseActions';
-import Loading from '../layout/Loading';
-import SearchReleaseError from './SearchReleaseError';
-import { Button, Poster, PosterContent } from './styles/SearchRelease.styles';
-import { autotrackParams } from '../../lib/analytics';
+import { bindActionCreators } from "redux";
+import { connect } from "react-redux";
+import React from "react";
+import { FaLastfm } from "react-icons/fa";
+import { MdClose } from "react-icons/md";
+import { fetchRelease } from "./actions/releaseActions";
+import Loading from "../layout/Loading";
+import SearchReleaseError from "./SearchReleaseError";
+import { Button, Poster, PosterContent } from "./styles/SearchRelease.styles";
+import { autotrackParams } from "../../lib/analytics";
interface SearchReleaseProps {
code: string;
@@ -32,23 +32,21 @@ class SearchRelease extends React.Component {
}
render() {
- const {
- code, error = null, loading = true, data = {}, onCancel, onScrobble,
- } = this.props;
+ const { code, error = null, loading = true, data = {}, onCancel, onScrobble } = this.props;
return (
<>
{loading && }
{!loading && error && (
-
+
)}
{!loading && !error && (
-
+
Cancel
-
+
Scrobble
@@ -70,11 +68,6 @@ const mapStateToProps = (state, { code }) => ({
...state.release[code],
});
-const mapDispatchToProps = dispatch => (
- bindActionCreators({ fetchRelease }, dispatch)
-);
+const mapDispatchToProps = dispatch => bindActionCreators({ fetchRelease }, dispatch);
-export default connect(
- mapStateToProps,
- mapDispatchToProps,
-)(SearchRelease) as any;
+export default connect(mapStateToProps, mapDispatchToProps)(SearchRelease) as any;
diff --git a/components/release/SearchReleaseError.tsx b/components/release/SearchReleaseError.tsx
index 57e1647..a95aca7 100644
--- a/components/release/SearchReleaseError.tsx
+++ b/components/release/SearchReleaseError.tsx
@@ -1,8 +1,8 @@
-import React from 'react';
-import { IoIosRefresh } from 'react-icons/io';
-import { yellow } from '../../lib/colors';
-import { FlexContent } from '../../styles/layout.styles';
-import { ErrorIcon, RetryButton } from '../layout/styles/Error.styles';
+import React from "react";
+import { IoIosRefresh } from "react-icons/io";
+import { yellow } from "../../lib/colors";
+import { FlexContent } from "../../styles/layout.styles";
+import { ErrorIcon, RetryButton } from "../layout/styles/Error.styles";
interface SearchReleaseErrorProps {
code: string;
@@ -12,7 +12,11 @@ interface SearchReleaseErrorProps {
const SearchReleaseError = ({ code, onRetry }: SearchReleaseErrorProps) => (
- No release found {code}
+
+ No release found
+
+ {code}
+
Retry
diff --git a/components/release/actions/releaseActionCreators.ts b/components/release/actions/releaseActionCreators.ts
index c197b35..77836d3 100644
--- a/components/release/actions/releaseActionCreators.ts
+++ b/components/release/actions/releaseActionCreators.ts
@@ -1,4 +1,4 @@
-import { SET_LOADING_STATE, SET_ERROR_STATE, RECEIVED_RELEASE } from '../constants/releaseConstants';
+import { SET_LOADING_STATE, SET_ERROR_STATE, RECEIVED_RELEASE } from "../constants/releaseConstants";
export const setLoadingState = (code, loading) => ({
type: SET_LOADING_STATE,
diff --git a/components/release/actions/releaseActions.ts b/components/release/actions/releaseActions.ts
index 9d9a2ba..3e3beb3 100644
--- a/components/release/actions/releaseActions.ts
+++ b/components/release/actions/releaseActions.ts
@@ -1,33 +1,29 @@
-import { setLoadingState, receivedRelease, setErrorState } from './releaseActionCreators';
+import { setLoadingState, receivedRelease, setErrorState } from "./releaseActionCreators";
-const shouldFetchRelease = release => (!release || !release.data?.id);
+const shouldFetchRelease = release => !release || !release.data?.id;
-export const fetchRelease = code => (
- async (dispatch) => {
- try {
- dispatch(setErrorState(code, null));
- dispatch(setLoadingState(code, true));
+export const fetchRelease = code => async dispatch => {
+ try {
+ dispatch(setErrorState(code, null));
+ dispatch(setLoadingState(code, true));
- const response = await fetch(`/api/barcode/${code}`, { credentials: 'include' });
- if (!response.ok) throw new Error(`HTTP ${response.status}`);
- const data = await response.json();
+ const response = await fetch(`/api/barcode/${code}`, { credentials: "include" });
+ if (!response.ok) throw new Error(`HTTP ${response.status}`);
+ const data = await response.json();
- if (data.id) {
- dispatch(receivedRelease(code, data));
- } else {
- dispatch(setErrorState(code, 'No release found'));
- }
- } catch (error) {
- dispatch(setErrorState(code, error));
+ if (data.id) {
+ dispatch(receivedRelease(code, data));
+ } else {
+ dispatch(setErrorState(code, "No release found"));
}
- dispatch(setLoadingState(code, false));
+ } catch (error) {
+ dispatch(setErrorState(code, error));
}
-);
+ dispatch(setLoadingState(code, false));
+};
-export const fetchReleaseIfNeeded = code => (
- (dispatch, getState) => {
- if (shouldFetchRelease(getState().release[code])) {
- dispatch(fetchRelease(code));
- }
+export const fetchReleaseIfNeeded = code => (dispatch, getState) => {
+ if (shouldFetchRelease(getState().release[code])) {
+ dispatch(fetchRelease(code));
}
-);
+};
diff --git a/components/release/constants/releaseConstants.ts b/components/release/constants/releaseConstants.ts
index 14307e1..38d7e4b 100644
--- a/components/release/constants/releaseConstants.ts
+++ b/components/release/constants/releaseConstants.ts
@@ -1,3 +1,3 @@
-export const SET_LOADING_STATE = 'SET_RELEASE_LOADING_STATE';
-export const SET_ERROR_STATE = 'SET_RELEASE_ERROR_STATE';
-export const RECEIVED_RELEASE = 'RECEIVED_RELEASE';
+export const SET_LOADING_STATE = "SET_RELEASE_LOADING_STATE";
+export const SET_ERROR_STATE = "SET_RELEASE_ERROR_STATE";
+export const RECEIVED_RELEASE = "RECEIVED_RELEASE";
diff --git a/components/release/reducers/releaseReducer.ts b/components/release/reducers/releaseReducer.ts
index ab02b84..64d6651 100644
--- a/components/release/reducers/releaseReducer.ts
+++ b/components/release/reducers/releaseReducer.ts
@@ -1,4 +1,4 @@
-import { SET_LOADING_STATE, SET_ERROR_STATE, RECEIVED_RELEASE } from '../constants/releaseConstants';
+import { SET_LOADING_STATE, SET_ERROR_STATE, RECEIVED_RELEASE } from "../constants/releaseConstants";
const releaseReducer = (state: any = {}, action: any = {}) => {
switch (action.type) {
diff --git a/components/release/styles/ReleaseInfo.styles.ts b/components/release/styles/ReleaseInfo.styles.ts
index c6f487e..799610f 100644
--- a/components/release/styles/ReleaseInfo.styles.ts
+++ b/components/release/styles/ReleaseInfo.styles.ts
@@ -1,6 +1,6 @@
-import { IoIosInformationCircleOutline } from 'react-icons/io';
-import styled from 'styled-components';
-import { dark } from '../../../lib/colors';
+import { IoIosInformationCircleOutline } from "react-icons/io";
+import styled from "styled-components";
+import { dark } from "../../../lib/colors";
export const Wrapper = styled.div`
position: relative;
@@ -41,7 +41,7 @@ export const Overlay = styled.div`
width: 100%;
height: 100%;
overflow: auto;
- background: rgba(0,0,0,.7);
+ background: rgba(0, 0, 0, 0.7);
backdrop-filter: blur(10px);
-webkit-overflow-scrolling: touch;
`;
@@ -79,7 +79,7 @@ export const Cover = styled.img`
height: 100%;
object-fit: cover;
filter: blur(10px);
- opacity: .4;
+ opacity: 0.4;
`;
export const Meta = styled.div`
@@ -97,12 +97,12 @@ export const Title = styled.div`
`;
export const Year = styled.div`
- font-size: .5em;
+ font-size: 0.5em;
`;
export const Artist = styled.div`
margin-bottom: 8px;
- font-size: .8em;
+ font-size: 0.8em;
`;
export const TrackListWrapper = styled.div`
diff --git a/components/release/styles/SearchRelease.styles.ts b/components/release/styles/SearchRelease.styles.ts
index 638b0f4..a2157d8 100644
--- a/components/release/styles/SearchRelease.styles.ts
+++ b/components/release/styles/SearchRelease.styles.ts
@@ -1,4 +1,4 @@
-import styled from 'styled-components';
+import styled from "styled-components";
export const Poster = styled.div<{ image?: string }>`
display: flex;
@@ -18,7 +18,7 @@ export const PosterContent = styled.div`
display: flex;
width: 100%;
padding: 0 20%;
- background: rgba(0, 0, 0, .5);
+ background: rgba(0, 0, 0, 0.5);
text-align: center;
backdrop-filter: blur(10px);
`;
diff --git a/components/scanner/Scanner.tsx b/components/scanner/Scanner.tsx
index ecb26ee..5cf5b85 100644
--- a/components/scanner/Scanner.tsx
+++ b/components/scanner/Scanner.tsx
@@ -1,10 +1,10 @@
-import React from 'react';
-import Quagga from 'quagga';
-import { yellow } from '../../lib/colors';
-import { FlexContent } from '../../styles/layout.styles';
-import { ErrorDescription, ErrorIcon } from '../layout/styles/Error.styles';
-import { Camera } from './styles/Scanner.styles';
-import Loading from '../layout/Loading';
+import React from "react";
+import Quagga from "quagga";
+import { yellow } from "../../lib/colors";
+import { FlexContent } from "../../styles/layout.styles";
+import { ErrorDescription, ErrorIcon } from "../layout/styles/Error.styles";
+import { Camera } from "./styles/Scanner.styles";
+import Loading from "../layout/Loading";
interface ScannerProps {
onDetected: (result: any) => void;
@@ -21,36 +21,39 @@ class Scanner extends React.Component {
+ if (err) {
+ this.setState({ videoError: true, loading: false });
+ return;
+ }
+ this.onInitSuccess();
},
- }, (err) => {
- if (err) {
- this.setState({ videoError: true, loading: false });
- return;
- }
- this.onInitSuccess();
- });
+ );
Quagga.onDetected(this.onDetected);
}
}
@@ -62,33 +65,33 @@ class Scanner extends React.Component {
Quagga.start();
this.setState({ loading: false });
- }
+ };
- onDetected = (result) => {
+ onDetected = result => {
const { onDetected } = this.props;
this.setState({ loading: true });
Quagga.offDetected(this.onDetected);
onDetected(result);
- }
+ };
render() {
const { videoError, loading } = this.state;
const ready = !loading && !videoError;
return (
<>
- {loading && }
+ {loading && }
{videoError && (
An error occurred
-
- Please make sure this website is allowed to use the camera.
-
+ Please make sure this website is allowed to use the camera.
)}
- {/* eslint-disable-next-line jsx-a11y/media-has-caption */}
-
+
+ {/* eslint-disable-next-line jsx-a11y/media-has-caption */}
+
+
>
);
}
diff --git a/components/scanner/styles/Scanner.styles.ts b/components/scanner/styles/Scanner.styles.ts
index d8412c3..c8765a8 100644
--- a/components/scanner/styles/Scanner.styles.ts
+++ b/components/scanner/styles/Scanner.styles.ts
@@ -1,14 +1,15 @@
-import styled from 'styled-components';
+import styled from "styled-components";
// eslint-disable-next-line import/prefer-default-export
export const Camera = styled.div<{ $visible?: boolean }>`
- visibility: ${props => (props.$visible ? 'visible' : 'hidden')};
+ visibility: ${props => (props.$visible ? "visible" : "hidden")};
position: absolute;
width: 100%;
height: 100%;
transform: translate3d(0, 0, 0);
- video, canvas {
+ video,
+ canvas {
position: absolute;
top: 0;
left: 0;
diff --git a/components/scrobble/Scrobble.tsx b/components/scrobble/Scrobble.tsx
index c7a1401..a118bb1 100644
--- a/components/scrobble/Scrobble.tsx
+++ b/components/scrobble/Scrobble.tsx
@@ -1,6 +1,6 @@
-import React from 'react';
-import { Loading, LoadingContent, LoadingWrapper } from './styles/Scrobble.styles';
-import ScrobbleError from './ScrobbleError';
+import React from "react";
+import { Loading, LoadingContent, LoadingWrapper } from "./styles/Scrobble.styles";
+import ScrobbleError from "./ScrobbleError";
interface ScrobbleProps {
release: { id: string; image?: string; [key: string]: any };
@@ -18,34 +18,36 @@ class Scrobble extends React.Component
}
doRequest = async () => {
- const { release: { id }, autoScrobble, onScrobbled } = this.props;
+ const {
+ release: { id },
+ autoScrobble,
+ onScrobbled,
+ } = this.props;
try {
this.setState({ loadingError: false });
- await fetch('/api/scrobble', {
- method: 'POST',
- headers: { 'Content-Type': 'application/json' },
+ await fetch("/api/scrobble", {
+ method: "POST",
+ headers: { "Content-Type": "application/json" },
body: JSON.stringify({ id, autoScrobble }),
});
- } catch (error) {
+ } catch {
return this.setState({ loadingError: true });
}
return onScrobbled();
- }
+ };
render() {
const { loadingError } = this.state;
const { release } = this.props;
- return (
- loadingError
- ?
- : (
-
-
- Sending data to Last.fm
-
- )
+ return loadingError ? (
+
+ ) : (
+
+
+ Sending data to Last.fm
+
);
}
}
diff --git a/components/scrobble/ScrobbleError.tsx b/components/scrobble/ScrobbleError.tsx
index 6965b89..c98f73f 100644
--- a/components/scrobble/ScrobbleError.tsx
+++ b/components/scrobble/ScrobbleError.tsx
@@ -1,8 +1,8 @@
-import React from 'react';
-import { IoIosRefresh } from 'react-icons/io';
-import { yellow } from '../../lib/colors';
-import { FlexContent } from '../../styles/layout.styles';
-import { ErrorIcon, RetryButton } from '../layout/styles/Error.styles';
+import React from "react";
+import { IoIosRefresh } from "react-icons/io";
+import { yellow } from "../../lib/colors";
+import { FlexContent } from "../../styles/layout.styles";
+import { ErrorIcon, RetryButton } from "../layout/styles/Error.styles";
interface ScrobbleErrorProps {
onRetry: () => void;
diff --git a/components/scrobble/styles/Scrobble.styles.ts b/components/scrobble/styles/Scrobble.styles.ts
index c24e741..3447303 100644
--- a/components/scrobble/styles/Scrobble.styles.ts
+++ b/components/scrobble/styles/Scrobble.styles.ts
@@ -1,5 +1,5 @@
-import styled from 'styled-components';
-import Spinner from '../../layout/Spinner';
+import styled from "styled-components";
+import Spinner from "../../layout/Spinner";
export const Loading = styled(Spinner)`
width: 100%;
@@ -23,8 +23,11 @@ export const LoadingContent = styled.div`
left: 0;
width: 100%;
padding: 12% 20%;
- background: rgba(0, 0, 0, .5);
+ background: rgba(0, 0, 0, 0.5);
text-align: center;
backdrop-filter: blur(10px);
- text-shadow: 0 0 3px black, 0 0 3px black, 0 0 3px black;
+ text-shadow:
+ 0 0 3px black,
+ 0 0 3px black,
+ 0 0 3px black;
`;
diff --git a/components/session/Session.tsx b/components/session/Session.tsx
index 6bd3eba..c766789 100644
--- a/components/session/Session.tsx
+++ b/components/session/Session.tsx
@@ -1,15 +1,13 @@
-import { bindActionCreators } from 'redux';
-import { connect } from 'react-redux';
-import React from 'react';
-import Head from 'next/head';
-import Link from 'next/link';
-import Router from 'next/router';
-import { fetchSessionIfNeeded } from './actions/sessionActions';
-import {
- Arrow, Image, ImageAndUser, Loader, Menu, MenuItem, Username,
-} from './styles/Session.styles';
-import targetBlank from '../../lib/targetBlank';
-import { autotrackParams } from '../../lib/analytics';
+import { bindActionCreators } from "redux";
+import { connect } from "react-redux";
+import React from "react";
+import Head from "next/head";
+import Link from "next/link";
+import Router from "next/router";
+import { fetchSessionIfNeeded } from "./actions/sessionActions";
+import { Arrow, Avatar, ImageAndUser, Loader, Menu, MenuItem, Username } from "./styles/Session.styles";
+import targetBlank from "../../lib/targetBlank";
+import { autotrackParams } from "../../lib/analytics";
interface SessionProps {
session?: any;
@@ -22,35 +20,35 @@ class Session extends React.Component {
state = {
open: false,
- }
+ };
componentDidMount() {
this.props.fetchSessionIfNeeded();
- document.addEventListener('click', this.handleClickOutside);
+ document.addEventListener("click", this.handleClickOutside);
}
componentDidUpdate(prevProps: SessionProps) {
if (!prevProps.error && this.props.error) {
- Router.push('/login');
+ Router.push("/login");
}
}
componentWillUnmount() {
- document.removeEventListener('click', this.handleClickOutside);
+ document.removeEventListener("click", this.handleClickOutside);
}
- handleClickOutside = (event) => {
+ handleClickOutside = event => {
const { open } = this.state;
const ref = this.overlayRef.current;
if (open && !ref.contains(event.target) && document.body.contains(event.target)) {
this.setState({ open: false });
}
- }
+ };
handleClick = () => {
this.setState(state => ({ open: !state.open }));
- }
+ };
render() {
const { session = {}, error = null } = this.props;
@@ -65,22 +63,24 @@ class Session extends React.Component {
{session && session.name ? (
<>
- {session.name}
-
+
+ {session.name}
+
+
>
) : (
-
+
-
+
)}
- Profile
+ Profile
- Logout
+ Logout
@@ -93,11 +93,6 @@ const mapStateToProps = state => ({
error: state.session.error,
});
-const mapDispatchToProps = dispatch => (
- bindActionCreators({ fetchSessionIfNeeded }, dispatch)
-);
+const mapDispatchToProps = dispatch => bindActionCreators({ fetchSessionIfNeeded }, dispatch);
-export default connect(
- mapStateToProps,
- mapDispatchToProps,
-)(Session);
+export default connect(mapStateToProps, mapDispatchToProps)(Session);
diff --git a/components/session/actions/sessionActionCreators.ts b/components/session/actions/sessionActionCreators.ts
index f6567c7..4abdfcb 100644
--- a/components/session/actions/sessionActionCreators.ts
+++ b/components/session/actions/sessionActionCreators.ts
@@ -1,4 +1,4 @@
-import { SET_LOADING_STATE, SET_ERROR_STATE, RECEIVED_SESSION } from '../constants/sessionConstants';
+import { SET_LOADING_STATE, SET_ERROR_STATE, RECEIVED_SESSION } from "../constants/sessionConstants";
export const setLoadingState = loading => ({
type: SET_LOADING_STATE,
diff --git a/components/session/actions/sessionActions.ts b/components/session/actions/sessionActions.ts
index ac51c06..7ebb4dc 100644
--- a/components/session/actions/sessionActions.ts
+++ b/components/session/actions/sessionActions.ts
@@ -1,30 +1,26 @@
-import { setLoadingState, receivedSession, setErrorState } from './sessionActionCreators';
+import { setLoadingState, receivedSession, setErrorState } from "./sessionActionCreators";
const shouldFetchSession = session => !session.data;
-export const fetchSession = () => (
- async (dispatch) => {
- try {
- dispatch(setLoadingState(true));
- const response = await fetch('/api/session', { credentials: 'include' });
- if (!response.ok) {
- dispatch(setErrorState(response.status));
- } else {
- const data = await response.json();
- dispatch(receivedSession(data));
- }
- } catch (error) {
- dispatch(setErrorState(error));
+export const fetchSession = () => async dispatch => {
+ try {
+ dispatch(setLoadingState(true));
+ const response = await fetch("/api/session", { credentials: "include" });
+ if (!response.ok) {
+ dispatch(setErrorState(response.status));
+ } else {
+ const data = await response.json();
+ dispatch(receivedSession(data));
}
- dispatch(setLoadingState(false));
+ } catch (error) {
+ dispatch(setErrorState(error));
}
-);
+ dispatch(setLoadingState(false));
+};
-export const fetchSessionIfNeeded = () => (
- (dispatch, getState) => {
- const state = getState().session;
- if (shouldFetchSession(state)) {
- dispatch(fetchSession());
- }
+export const fetchSessionIfNeeded = () => (dispatch, getState) => {
+ const state = getState().session;
+ if (shouldFetchSession(state)) {
+ dispatch(fetchSession());
}
-);
+};
diff --git a/components/session/constants/sessionConstants.ts b/components/session/constants/sessionConstants.ts
index 53e27f7..00cbd39 100644
--- a/components/session/constants/sessionConstants.ts
+++ b/components/session/constants/sessionConstants.ts
@@ -1,3 +1,3 @@
-export const SET_LOADING_STATE = 'SET_SESSION_LOADING_STATE';
-export const SET_ERROR_STATE = 'SET_SESSION_ERROR_STATE';
-export const RECEIVED_SESSION = 'RECEIVED_SESSION';
+export const SET_LOADING_STATE = "SET_SESSION_LOADING_STATE";
+export const SET_ERROR_STATE = "SET_SESSION_ERROR_STATE";
+export const RECEIVED_SESSION = "RECEIVED_SESSION";
diff --git a/components/session/reducers/sessionReducer.ts b/components/session/reducers/sessionReducer.ts
index 5eae3c8..006952b 100644
--- a/components/session/reducers/sessionReducer.ts
+++ b/components/session/reducers/sessionReducer.ts
@@ -1,4 +1,4 @@
-import { RECEIVED_SESSION, SET_LOADING_STATE, SET_ERROR_STATE } from '../constants/sessionConstants';
+import { RECEIVED_SESSION, SET_LOADING_STATE, SET_ERROR_STATE } from "../constants/sessionConstants";
const sessionReducer = (state = {}, action: any = {}) => {
switch (action.type) {
diff --git a/components/session/styles/Session.styles.ts b/components/session/styles/Session.styles.ts
index 99e8fe3..c27932a 100644
--- a/components/session/styles/Session.styles.ts
+++ b/components/session/styles/Session.styles.ts
@@ -1,19 +1,21 @@
-import styled, { css } from 'styled-components';
-import { dark, yellow, yellowRGB } from '../../../lib/colors';
-import { animation } from '../../layout/Spinner';
-import { buttonReset } from '../../../styles/mixins';
+import styled, { css } from "styled-components";
+import { dark, yellow, yellowRGB } from "../../../lib/colors";
+import { animation } from "../../layout/Spinner";
+import { buttonReset } from "../../../styles/mixins";
const fadeInOnOpen = css<{ open?: boolean }>`
- transition: opacity .3s;
+ transition: opacity 0.3s;
opacity: 0;
- pointer-events:none;
- ${props => props.open && css`
- opacity: 1;
- pointer-events: auto;
- `}
+ pointer-events: none;
+ ${props =>
+ props.open &&
+ css`
+ opacity: 1;
+ pointer-events: auto;
+ `}
`;
-export const Image = styled.div<{ image?: string }>`
+export const Avatar = styled.div<{ image?: string }>`
z-index: 1;
width: 8vw;
max-width: 50px;
@@ -30,7 +32,7 @@ export const Loader = styled.div`
width: 100%;
height: 100%;
animation: ${animation} 1s ease-in-out infinite;
- border: 2px solid rgba(${yellowRGB}, .3);
+ border: 2px solid rgba(${yellowRGB}, 0.3);
border-radius: 50%;
border-top-color: ${yellow};
`;
@@ -44,7 +46,7 @@ export const Arrow = styled.div<{ open?: boolean }>`
height: 8px;
&:before {
- content: '';
+ content: "";
position: absolute;
top: 0;
left: 50%;
diff --git a/components/ui/BackButton.tsx b/components/ui/BackButton.tsx
index 9b77546..3e6e09d 100644
--- a/components/ui/BackButton.tsx
+++ b/components/ui/BackButton.tsx
@@ -1,11 +1,9 @@
-import Router from 'next/router';
-import { ChevronLeft } from 'styled-icons/boxicons-regular';
-import { silver } from '../../lib/colors';
-import { Button } from './styles/BackButton.styles';
+import Router from "next/router";
+import { ChevronLeft } from "styled-icons/boxicons-regular";
+import { silver } from "../../lib/colors";
+import { Button } from "./styles/BackButton.styles";
-const getHostFromUrl = url => (
- (/\/\/([^/]+)\//i.exec(url) || [])[1]
-);
+const getHostFromUrl = url => (/\/\/([^/]+)\//i.exec(url) || [])[1];
const hasExternalReferrer = () => {
if (!document.referrer) return true;
@@ -14,7 +12,7 @@ const hasExternalReferrer = () => {
const handleClick = () => {
if (hasExternalReferrer()) {
- Router.push('/');
+ Router.push("/");
} else {
Router.back();
}
diff --git a/components/ui/Checkbox.tsx b/components/ui/Checkbox.tsx
index d590675..1e25e86 100644
--- a/components/ui/Checkbox.tsx
+++ b/components/ui/Checkbox.tsx
@@ -1,6 +1,6 @@
-import React from 'react';
+import React from "react";
-import { Input, Label, Wrapper } from './styles/Checkbox.styles';
+import { Input, Label, Wrapper } from "./styles/Checkbox.styles";
interface CheckboxProps {
checked?: boolean;
@@ -21,7 +21,7 @@ class Checkbox extends React.Component {
shouldComponentUpdate(nextProps: CheckboxProps) {
// eslint-disable-next-line react/destructuring-assignment
- return ['checked', 'disabled'].some(prop => this.props[prop] !== nextProps[prop]);
+ return ["checked", "disabled"].some(prop => this.props[prop] !== nextProps[prop]);
}
handleCheck(event) {
@@ -30,18 +30,11 @@ class Checkbox extends React.Component {
}
render() {
- const {
- name, className = null, checked = false, disabled = false, children = null,
- } = this.props;
+ const { name, className = null, checked = false, disabled = false, children = null } = this.props;
const id = `checkbox-${name}`;
return (
-
+
{
onChange={this.handleCheck}
disabled={disabled}
/>
- { this.label = e; }}>
+ {
+ this.label = e;
+ }}
+ >
{children}
diff --git a/components/ui/LegalLinks.tsx b/components/ui/LegalLinks.tsx
index 58ab6fe..21fb5b2 100644
--- a/components/ui/LegalLinks.tsx
+++ b/components/ui/LegalLinks.tsx
@@ -1,5 +1,5 @@
-import NextLink from 'next/link';
-import { Link, Links } from './styles/LegalLinks.styles';
+import NextLink from "next/link";
+import { Link, Links } from "./styles/LegalLinks.styles";
const LegalLinks = () => (
diff --git a/components/ui/LoginButton.tsx b/components/ui/LoginButton.tsx
index 4d4e56c..26e337f 100644
--- a/components/ui/LoginButton.tsx
+++ b/components/ui/LoginButton.tsx
@@ -1,5 +1,5 @@
-import LastfmIcon from '../icons/LastfmIcon';
-import { Caption, Wrapper } from './styles/LoginButton.styles';
+import LastfmIcon from "../icons/LastfmIcon";
+import { Caption, Wrapper } from "./styles/LoginButton.styles";
const LoginButton = props => (
diff --git a/components/ui/styles/BackButton.styles.ts b/components/ui/styles/BackButton.styles.ts
index c9c7688..0dbbe45 100644
--- a/components/ui/styles/BackButton.styles.ts
+++ b/components/ui/styles/BackButton.styles.ts
@@ -1,6 +1,6 @@
-import styled from 'styled-components';
-import { silver } from '../../../lib/colors';
-import { buttonReset } from '../../../styles/mixins';
+import styled from "styled-components";
+import { silver } from "../../../lib/colors";
+import { buttonReset } from "../../../styles/mixins";
// eslint-disable-next-line import/prefer-default-export
export const Button = styled.button`
@@ -14,7 +14,7 @@ export const Button = styled.button`
padding: 5px;
overflow: hidden;
border-bottom: 1px solid ${silver};
- background: rgba(0, 0, 0, .6);
+ background: rgba(0, 0, 0, 0.6);
box-shadow: 0 0 3px 2px black;
backdrop-filter: blur(5px);
font-size: 16px;
diff --git a/components/ui/styles/Checkbox.styles.ts b/components/ui/styles/Checkbox.styles.ts
index 4106535..6d8db60 100644
--- a/components/ui/styles/Checkbox.styles.ts
+++ b/components/ui/styles/Checkbox.styles.ts
@@ -1,6 +1,6 @@
// Source: https://github.com/iceteabottle/css-checkbox
-import styled, { keyframes } from 'styled-components';
-import { dark, silver, yellow } from '../../../lib/colors';
+import styled, { keyframes } from "styled-components";
+import { dark, silver, yellow } from "../../../lib/colors";
// custom checkbox/radios
const inputHeight = 30;
@@ -27,7 +27,7 @@ export const Label = styled.label`
display: inline-flex;
position: relative;
align-items: center;
- height: ${inputHeight + (2 * inputBorderWidth)}px;
+ height: ${inputHeight + 2 * inputBorderWidth}px;
padding: 0 6px 0 42px;
cursor: pointer;
user-select: none;
@@ -38,15 +38,15 @@ export const Label = styled.label`
width: ${inputWidth}px;
height: ${inputHeight}px;
margin-top: ${-(inputHeight / 2 + inputBorderWidth)}px;
- transition: .2s ease;
+ transition: 0.2s ease;
transition-property: background-color, border-color;
border: ${inputBorderWidth}px solid ${borderColor};
border-radius: 50%;
- background: rgba(255, 255, 255, .1);
+ background: rgba(255, 255, 255, 0.1);
text-align: center;
}
- &:after{
+ &:after {
top: 50%;
left: 9px;
width: 11px;
@@ -54,7 +54,7 @@ export const Label = styled.label`
margin-top: 0;
transform: translateY(-5px) rotate(-45deg) scale(0);
transform-origin: 50%;
- transition: transform .2s ease-out;
+ transition: transform 0.2s ease-out;
border-width: 0 0 3px 3px;
border-style: solid;
border-color: ${dark};
@@ -63,8 +63,8 @@ export const Label = styled.label`
}
&:before,
- &:after{
- content: '';
+ &:after {
+ content: "";
position: absolute;
box-sizing: content-box;
}
@@ -91,13 +91,13 @@ export const Input = styled.input`
&:checked {
& + ${Label} {
&:after {
- content: '';
+ content: "";
transform: translateY(-5px) rotate(-45deg) scale(1);
- transition: transform .2s ease-out;
+ transition: transform 0.2s ease-out;
border-color: ${dark};
}
&:before {
- animation: ${borderscale1} .2s ease-in;
+ animation: ${borderscale1} 0.2s ease-in;
border-color: ${checkboxColor};
background: ${checkboxColor};
}
diff --git a/components/ui/styles/LegalLinks.styles.ts b/components/ui/styles/LegalLinks.styles.ts
index 0d2c55f..6bdb821 100644
--- a/components/ui/styles/LegalLinks.styles.ts
+++ b/components/ui/styles/LegalLinks.styles.ts
@@ -1,4 +1,4 @@
-import styled from 'styled-components';
+import styled from "styled-components";
export const Links = styled.div`
display: flex;
diff --git a/components/ui/styles/LoginButton.styles.ts b/components/ui/styles/LoginButton.styles.ts
index 0e77c7b..7da10a7 100644
--- a/components/ui/styles/LoginButton.styles.ts
+++ b/components/ui/styles/LoginButton.styles.ts
@@ -1,12 +1,12 @@
-import styled from 'styled-components';
-import { lastFm, lastFmDark } from '../../../lib/colors';
+import styled from "styled-components";
+import { lastFm, lastFmDark } from "../../../lib/colors";
export const Wrapper = styled.a`
display: inline-flex;
flex-direction: column;
align-items: flex-start;
padding: 10px 25px;
- transition: .25s;
+ transition: 0.25s;
transition-property: box-shadow, transform;
border: 1px solid ${lastFmDark};
border-radius: 5px;
@@ -18,7 +18,7 @@ export const Wrapper = styled.a`
&:active {
transform: translateY(3px);
- box-shadow: none
+ box-shadow: none;
}
`;
diff --git a/config/setupTests.ts b/config/setupTests.ts
index e1284da..4054b19 100644
--- a/config/setupTests.ts
+++ b/config/setupTests.ts
@@ -1,3 +1,3 @@
-import fetchMock from 'jest-fetch-mock';
+import fetchMock from "jest-fetch-mock";
global.fetch = fetchMock as any;
diff --git a/eslint.config.js b/eslint.config.js
index 295e748..a5a78c9 100644
--- a/eslint.config.js
+++ b/eslint.config.js
@@ -1,5 +1,6 @@
-const { FlatCompat } = require('@eslint/eslintrc');
-const babelParser = require('@babel/eslint-parser');
+const { FlatCompat } = require("@eslint/eslintrc");
+const js = require("@eslint/js");
+const prettierConfig = require("eslint-config-prettier/flat");
const compat = new FlatCompat({
baseDirectory: __dirname,
@@ -7,44 +8,48 @@ const compat = new FlatCompat({
module.exports = [
{
- ignores: ['.next/**', 'node_modules/**', 'public/**'],
+ ignores: [
+ ".next/**",
+ "node_modules/**",
+ ".storybook/**",
+ "coverage/**",
+ "dist/**",
+ "build/**",
+ "out/**",
+ "public/static/**",
+ "test-results/**",
+ ],
},
+ js.configs.recommended,
...compat.extends(
- 'eslint:recommended',
- 'plugin:react/recommended',
- 'plugin:jest/recommended',
- 'airbnb',
+ "next/core-web-vitals",
+ "next/typescript",
+ "plugin:jsx-a11y/recommended",
+ "plugin:import/recommended",
),
{
+ files: ["**/*.spec.{js,jsx,ts,tsx}", "**/*.test.{js,jsx,ts,tsx}"],
languageOptions: {
- parser: babelParser,
- parserOptions: {
- requireConfigFile: false,
- babelOptions: {
- presets: ['next/babel'],
- },
- },
globals: {
- browser: true,
- es6: true,
- node: true,
+ describe: "readonly",
+ it: "readonly",
+ test: "readonly",
+ expect: "readonly",
+ beforeAll: "readonly",
+ beforeEach: "readonly",
+ afterAll: "readonly",
+ afterEach: "readonly",
+ jest: "readonly",
},
},
+ },
+ {
rules: {
- 'import/extensions': 'off',
- 'import/no-extraneous-dependencies': ['error', { devDependencies: true }],
- 'import/no-unresolved': 'off',
- 'jsx-a11y/anchor-is-valid': ['error', {
- components: ['Link'],
- specialLink: ['route'],
- aspects: ['invalidHref', 'preferButton'],
- }],
- 'no-unused-vars': ['error', { args: 'none' }],
- 'react/destructuring-assignment': 'off',
- 'react/forbid-prop-types': 'off',
- 'react/jsx-filename-extension': [1, { extensions: ['.js', '.jsx', '.ts', '.tsx'] }],
- 'react/jsx-one-expression-per-line': 'off',
- 'react/react-in-jsx-scope': 'off',
+ "@typescript-eslint/no-empty-object-type": "warn",
+ "@typescript-eslint/no-explicit-any": "warn",
+ "@typescript-eslint/no-require-imports": "off",
+ "import/no-unresolved": "off",
},
},
+ prettierConfig,
];
diff --git a/jest.config.js b/jest.config.js
index af79000..2d7e281 100644
--- a/jest.config.js
+++ b/jest.config.js
@@ -1,21 +1,16 @@
module.exports = {
- testEnvironment: 'jsdom',
- testPathIgnorePatterns: [
- '/.next/',
- '/node_modules/',
- ],
+ testEnvironment: "jsdom",
+ testPathIgnorePatterns: ["/.next/", "/node_modules/"],
transform: {
- '\\.(js|jsx|ts|tsx)$': 'babel-jest',
+ "\\.(js|jsx|ts|tsx)$": "babel-jest",
},
- transformIgnorePatterns: [
- '/node_modules/',
- ],
- setupFilesAfterEnv: ['/config/setupTests.ts'],
+ transformIgnorePatterns: ["/node_modules/"],
+ setupFilesAfterEnv: ["/config/setupTests.ts"],
collectCoverageFrom: [
- 'app/**/*.{js,jsx,ts,tsx}',
- 'components/**/*.{js,jsx,ts,tsx}',
- 'lib/**/*.{js,jsx,ts,tsx}',
- '!lib/colors.js',
- '!lib/polyfills.js',
+ "app/**/*.{js,jsx,ts,tsx}",
+ "components/**/*.{js,jsx,ts,tsx}",
+ "lib/**/*.{js,jsx,ts,tsx}",
+ "!lib/colors.js",
+ "!lib/polyfills.js",
],
};
diff --git a/lib/analytics.ts b/lib/analytics.ts
index ac2a525..577c477 100644
--- a/lib/analytics.ts
+++ b/lib/analytics.ts
@@ -1,16 +1,17 @@
-export const ANALYTICS_ID = 'UA-135908212-1';
+export const ANALYTICS_ID = "UA-135908212-1";
export const trackEvent = (action: string, category: string, label?: string, value?: string) => {
- (window as any).ga('send', 'event', category, action, label, value);
+ (window as any).ga("send", "event", category, action, label, value);
};
export const autotrackParams = (category: string, action: string, label?: string, value?: string) => {
- if ((typeof category === 'undefined' || category === null) || (typeof action === 'undefined' || action === null)) return {};
+ if (typeof category === "undefined" || category === null || typeof action === "undefined" || action === null)
+ return {};
return {
- 'data-event-category': category,
- 'data-event-action': action,
- 'data-event-label': label,
- 'data-event-value': value,
- 'data-on': 'click,auxclick,contextmenu',
+ "data-event-category": category,
+ "data-event-action": action,
+ "data-event-label": label,
+ "data-event-value": value,
+ "data-on": "click,auxclick,contextmenu",
};
};
diff --git a/lib/colors.ts b/lib/colors.ts
index a156ea3..66e8055 100644
--- a/lib/colors.ts
+++ b/lib/colors.ts
@@ -1,8 +1,8 @@
-export const yellow = '#feda6a';
-export const silver = '#d4d4dc';
-export const grey = '#393f4d';
-export const dark = '#1d1e22';
-export const lastFm = '#d51007';
-export const lastFmDark = '#d51007';
+export const yellow = "#feda6a";
+export const silver = "#d4d4dc";
+export const grey = "#393f4d";
+export const dark = "#1d1e22";
+export const lastFm = "#d51007";
+export const lastFmDark = "#d51007";
-export const yellowRGB = '254, 218, 106';
+export const yellowRGB = "254, 218, 106";
diff --git a/lib/durationFormat.ts b/lib/durationFormat.ts
index d49252e..b40fa2f 100644
--- a/lib/durationFormat.ts
+++ b/lib/durationFormat.ts
@@ -1,13 +1,13 @@
export default function durationFormat(duration) {
- if (duration <= 0) return '';
+ if (duration <= 0) return "";
const hrs = Math.floor(duration / 3600);
const mins = Math.floor((duration % 3600) / 60);
const secs = Math.floor(duration % 60);
- let ret = '';
- if (hrs > 0) ret += `${hrs}:${mins < 10 ? '0' : ''}`;
- ret += `${mins}:${secs < 10 ? '0' : ''}`;
+ let ret = "";
+ if (hrs > 0) ret += `${hrs}:${mins < 10 ? "0" : ""}`;
+ ret += `${mins}:${secs < 10 ? "0" : ""}`;
ret += `${secs}`;
return ret;
}
diff --git a/lib/initNProgress.ts b/lib/initNProgress.ts
index bead7be..f27193a 100644
--- a/lib/initNProgress.ts
+++ b/lib/initNProgress.ts
@@ -1,5 +1,5 @@
-import Router from 'next/router';
-import NProgress from 'nprogress';
+import Router from "next/router";
+import NProgress from "nprogress";
let progressTimeout = null;
@@ -11,10 +11,10 @@ const stopProgress = () => {
export default () => {
NProgress.configure({ showSpinner: false });
- Router.events.on('routeChangeStart', () => {
+ Router.events.on("routeChangeStart", () => {
progressTimeout = setTimeout(NProgress.start, 100);
});
- Router.events.on('routeChangeComplete', stopProgress);
- Router.events.on('routeChangeError', stopProgress);
+ Router.events.on("routeChangeComplete", stopProgress);
+ Router.events.on("routeChangeError", stopProgress);
};
diff --git a/lib/mongodb.ts b/lib/mongodb.ts
index d8139cb..aefd61e 100644
--- a/lib/mongodb.ts
+++ b/lib/mongodb.ts
@@ -1,4 +1,4 @@
-import mongoose from 'mongoose';
+import mongoose from "mongoose";
let isConnected = false;
diff --git a/lib/offline.ts b/lib/offline.ts
index 6f90c33..88f8a48 100644
--- a/lib/offline.ts
+++ b/lib/offline.ts
@@ -1,8 +1,12 @@
/* eslint-disable no-console */
-if (typeof window !== 'undefined' && 'serviceWorker' in navigator) {
+if (typeof window !== "undefined" && "serviceWorker" in navigator) {
navigator.serviceWorker
- .register('/service-worker.js')
- .then(() => { console.log('Service worker registered'); })
- .catch((e) => { console.error('Error during worker registration:', e); });
+ .register("/service-worker.js")
+ .then(() => {
+ console.log("Service worker registered");
+ })
+ .catch(e => {
+ console.error("Error during worker registration:", e);
+ });
}
diff --git a/lib/session.ts b/lib/session.ts
index 5080ea4..a7687ee 100644
--- a/lib/session.ts
+++ b/lib/session.ts
@@ -1,5 +1,5 @@
-import { getIronSession, IronSession, SessionOptions } from 'iron-session';
-import type { IncomingMessage, ServerResponse } from 'http';
+import { getIronSession, IronSession, SessionOptions } from "iron-session";
+import type { IncomingMessage, ServerResponse } from "http";
export interface SessionData {
userId?: string;
@@ -15,9 +15,9 @@ export interface SessionData {
export const sessionOptions: SessionOptions = {
password: process.env.SESSION_SECRET as string,
- cookieName: 'code-scrobble-session',
+ cookieName: "code-scrobble-session",
cookieOptions: {
- secure: process.env.NODE_ENV === 'production',
+ secure: process.env.NODE_ENV === "production",
maxAge: 2592000, // 30 days in seconds
},
};
diff --git a/lib/targetBlank.ts b/lib/targetBlank.ts
index 15447e1..5b3e9fe 100644
--- a/lib/targetBlank.ts
+++ b/lib/targetBlank.ts
@@ -1,4 +1,4 @@
export default {
- target: '_blank',
- rel: 'noopener noreferrer',
+ target: "_blank",
+ rel: "noopener noreferrer",
};
diff --git a/lib/withAuth.ts b/lib/withAuth.ts
index f490666..925abea 100644
--- a/lib/withAuth.ts
+++ b/lib/withAuth.ts
@@ -1,20 +1,20 @@
-import type { NextApiRequest, NextApiResponse } from 'next';
-import { connectToDatabase } from './mongodb';
-import { getSession } from './session';
-import User from '../app/models/user';
+import type { NextApiRequest, NextApiResponse } from "next";
+import { connectToDatabase } from "./mongodb";
+import { getSession } from "./session";
+import User from "../app/models/user";
export async function requireUser(req: NextApiRequest, res: NextApiResponse): Promise {
await connectToDatabase();
const session = await getSession(req, res);
if (!session.userId) {
- res.status(401).json({ error: 'Unauthorized' });
+ res.status(401).json({ error: "Unauthorized" });
return null;
}
const user = await User.findById(session.userId);
if (!user) {
- res.status(401).json({ error: 'Unauthorized' });
+ res.status(401).json({ error: "Unauthorized" });
return null;
}
diff --git a/middleware.ts b/middleware.ts
index a261760..87a0136 100644
--- a/middleware.ts
+++ b/middleware.ts
@@ -1,17 +1,17 @@
-import { NextResponse } from 'next/server';
-import type { NextRequest } from 'next/server';
+import { NextResponse } from "next/server";
+import type { NextRequest } from "next/server";
-const PUBLIC_PATHS = ['/login', '/legal', '/privacy', '/api/auth/'];
+const PUBLIC_PATHS = ["/login", "/legal", "/privacy", "/api/auth/"];
export function middleware(request: NextRequest) {
const { pathname } = request.nextUrl;
// Skip API routes, Next.js internals, and static assets
if (
- pathname.startsWith('/api/')
- || pathname.startsWith('/_next/')
- || pathname.startsWith('/static/')
- || pathname.includes('.')
+ pathname.startsWith("/api/") ||
+ pathname.startsWith("/_next/") ||
+ pathname.startsWith("/static/") ||
+ pathname.includes(".")
) {
return NextResponse.next();
}
@@ -22,14 +22,14 @@ export function middleware(request: NextRequest) {
}
// Redirect to login if session cookie is absent
- const sessionCookie = request.cookies.get('code-scrobble-session');
+ const sessionCookie = request.cookies.get("code-scrobble-session");
if (!sessionCookie) {
- return NextResponse.redirect(new URL('/login', request.url));
+ return NextResponse.redirect(new URL("/login", request.url));
}
return NextResponse.next();
}
export const config = {
- matcher: ['/((?!_next/static|_next/image|favicon.ico).*)'],
+ matcher: ["/((?!_next/static|_next/image|favicon.ico).*)"],
};
diff --git a/next.config.js b/next.config.js
index 39d91cc..d240877 100644
--- a/next.config.js
+++ b/next.config.js
@@ -1,5 +1,5 @@
-const withBundleAnalyzer = require('@next/bundle-analyzer')({
- enabled: process.env.BUNDLE_ANALYZE === 'true',
+const withBundleAnalyzer = require("@next/bundle-analyzer")({
+ enabled: process.env.BUNDLE_ANALYZE === "true",
});
/** @type {import('next').NextConfig} */
diff --git a/package.json b/package.json
index 3f11c7e..daeb04b 100644
--- a/package.json
+++ b/package.json
@@ -19,8 +19,12 @@
"test": "jest",
"test:watch": "yarn test --watch",
"test:coverage": "yarn test --coverage",
- "lint": "eslint './**/*.{js,jsx,ts,tsx}'",
+ "lint": "eslint .",
+ "lint:fix": "eslint . --fix",
"lint:css": "stylelint './**/*.{js,jsx,ts,tsx}'",
+ "format": "prettier . --write",
+ "format:check": "prettier . --check",
+ "prepare": "husky",
"analyze": "BUNDLE_ANALYZE=true yarn build"
},
"dependencies": {
@@ -49,7 +53,6 @@
},
"devDependencies": {
"@babel/core": "^7.26.0",
- "@babel/eslint-parser": "^7.25.9",
"@babel/runtime-corejs2": "^7.26.0",
"@eslint/eslintrc": "^3.2.0",
"@eslint/js": "^9.18.0",
@@ -63,16 +66,17 @@
"@types/react-dom": "^18.3.5",
"babel-jest": "^29.7.0",
"babel-plugin-styled-components": "^2.1.4",
- "eslint": "^9.18.0",
- "eslint-config-airbnb": "^19.0.4",
+ "eslint": "^8.57.0",
+ "eslint-config-next": "^14.2.0",
+ "eslint-config-prettier": "10.1.8",
"eslint-plugin-import": "^2.31.0",
- "eslint-plugin-jest": "^28.11.0",
"eslint-plugin-jsx-a11y": "^6.10.2",
- "eslint-plugin-react": "^7.37.4",
- "eslint-plugin-react-hooks": "^5.1.0",
+ "husky": "^9.0.0",
"jest": "^29.7.0",
"jest-environment-jsdom": "^29.7.0",
"jest-fetch-mock": "^3.0.1",
+ "lint-staged": "^16.2.4",
+ "prettier": "^3.8.1",
"react-test-renderer": "^18.0.0",
"redis-mock": "^0.47.0",
"redux-mock-store": "^1.5.4",
@@ -88,5 +92,14 @@
"jest-environment-jsdom>jest-util>jest-util>fsevents": false,
"@babel/runtime-corejs2>core-js": false
}
+ },
+ "lint-staged": {
+ "*.{js,jsx,ts,tsx}": [
+ "prettier --write",
+ "eslint --fix"
+ ],
+ "*.{json,md,yaml,yml,css,scss}": [
+ "prettier --write"
+ ]
}
}
diff --git a/pages/_app.tsx b/pages/_app.tsx
index 7c9b398..9d4209a 100644
--- a/pages/_app.tsx
+++ b/pages/_app.tsx
@@ -1,10 +1,10 @@
-import React from 'react';
-import Head from 'next/head';
-import { Provider } from 'react-redux';
-import BaseStyles from '../components/layout/BaseStyles';
-import NProgressStyles from '../styles/nprogress.styles';
-import initNProgress from '../lib/initNProgress';
-import { wrapper } from '../client/reduxStore';
+import React from "react";
+import Head from "next/head";
+import { Provider } from "react-redux";
+import BaseStyles from "../components/layout/BaseStyles";
+import NProgressStyles from "../styles/nprogress.styles";
+import initNProgress from "../lib/initNProgress";
+import { wrapper } from "../client/reduxStore";
initNProgress();
diff --git a/pages/_document.tsx b/pages/_document.tsx
index 46e0cc4..6b2bef4 100644
--- a/pages/_document.tsx
+++ b/pages/_document.tsx
@@ -1,10 +1,8 @@
-import Document, { Html, Head, Main, NextScript } from 'next/document';
-import { ServerStyleSheet } from 'styled-components';
-import { ANALYTICS_ID } from '../lib/analytics';
+import Document, { Html, Head, Main, NextScript } from "next/document";
+import { ServerStyleSheet } from "styled-components";
+import { ANALYTICS_ID } from "../lib/analytics";
-const isSafari = userAgent => (
- /Version\/([0-9._]+).*Safari/.test(userAgent)
-);
+const isSafari = userAgent => /Version\/([0-9._]+).*Safari/.test(userAgent);
export default class MyDocument extends Document {
static async getInitialProps(ctx) {
@@ -12,15 +10,21 @@ export default class MyDocument extends Document {
const originalRenderPage = ctx.renderPage;
try {
- ctx.renderPage = () => originalRenderPage({
- enhanceApp: App => props => sheet.collectStyles( ),
- });
+ ctx.renderPage = () =>
+ originalRenderPage({
+ enhanceApp: App => props => sheet.collectStyles( ),
+ });
const initialProps = await Document.getInitialProps(ctx);
return {
...initialProps,
- showManifest: ctx.req ? !isSafari(ctx.req.headers['user-agent']) : true,
- styles: <>{initialProps.styles}{sheet.getStyleElement()}>,
+ showManifest: ctx.req ? !isSafari(ctx.req.headers["user-agent"]) : true,
+ styles: (
+ <>
+ {initialProps.styles}
+ {sheet.getStyleElement()}
+ >
+ ),
};
} finally {
sheet.seal();
@@ -34,9 +38,10 @@ export default class MyDocument extends Document {
{/* eslint-disable-next-line react/no-danger */}
-
@@ -45,24 +50,65 @@ export default class MyDocument extends Document {
-
+
- {(this.props as any).showManifest && (
-
- )}
+ {(this.props as any).showManifest && }
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
diff --git a/pages/api/auth/callback/lastfm.ts b/pages/api/auth/callback/lastfm.ts
index ee269da..6ff35a8 100644
--- a/pages/api/auth/callback/lastfm.ts
+++ b/pages/api/auth/callback/lastfm.ts
@@ -1,20 +1,20 @@
-import crypto from 'crypto';
-import type { NextApiRequest, NextApiResponse } from 'next';
-import { connectToDatabase } from '../../../../lib/mongodb';
-import { getSession } from '../../../../lib/session';
-import * as LastFM from '../../../../app/lastfm';
-import type { LastFMUserData } from '../../../../app/lastfm';
-import User from '../../../../app/models/user';
-import type { UserJSON } from '../../../../app/models/user';
+import crypto from "crypto";
+import type { NextApiRequest, NextApiResponse } from "next";
+import { connectToDatabase } from "../../../../lib/mongodb";
+import { getSession } from "../../../../lib/session";
+import * as LastFM from "../../../../app/lastfm";
+import type { LastFMUserData } from "../../../../app/lastfm";
+import User from "../../../../app/models/user";
+import type { UserJSON } from "../../../../app/models/user";
async function getLastFMSession(token: string): Promise<{ name: string; key: string }> {
- const method = 'auth.getSession';
+ const method = "auth.getSession";
const apiKey = process.env.LASTFM_KEY as string;
const secret = process.env.LASTFM_SECRET as string;
// Build signature: sorted params (excluding format/callback) concatenated, then append secret
const sigStr = `api_key${apiKey}method${method}token${token}${secret}`;
- const apiSig = crypto.createHash('md5').update(sigStr).digest('hex');
+ const apiSig = crypto.createHash("md5").update(sigStr).digest("hex");
const url = `https://ws.audioscrobbler.com/2.0/?method=${method}&api_key=${apiKey}&token=${token}&api_sig=${apiSig}&format=json`;
const response = await fetch(url);
@@ -27,8 +27,8 @@ async function getLastFMSession(token: string): Promise<{ name: string; key: str
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
const { token } = req.query;
- if (!token || typeof token !== 'string') {
- return res.redirect('/login');
+ if (!token || typeof token !== "string") {
+ return res.redirect("/login");
}
try {
@@ -42,11 +42,11 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
user.name = name;
user.key = key;
- const userData = await LastFM.getUserData(name, key) as LastFMUserData;
+ const userData = (await LastFM.getUserData(name, key)) as LastFMUserData;
user.url = userData.url;
- user.image = userData?.image?.[1]?.['#text'];
- user.imageLarge = userData?.image?.[2]?.['#text'];
- user.imageXLarge = userData?.image?.[3]?.['#text'];
+ user.image = userData?.image?.[1]?.["#text"];
+ user.imageLarge = userData?.image?.[2]?.["#text"];
+ user.imageXLarge = userData?.image?.[3]?.["#text"];
await user.save();
@@ -56,9 +56,9 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
session.user = user.toJSON() as unknown as UserJSON;
await session.save();
- return res.redirect('/');
+ return res.redirect("/");
} catch (err) {
- console.error('Last.fm auth error:', err);
- return res.redirect('/login');
+ console.error("Last.fm auth error:", err);
+ return res.redirect("/login");
}
}
diff --git a/pages/api/auth/lastfm.ts b/pages/api/auth/lastfm.ts
index 49df2c4..f3ae769 100644
--- a/pages/api/auth/lastfm.ts
+++ b/pages/api/auth/lastfm.ts
@@ -1,7 +1,7 @@
-import type { NextApiRequest, NextApiResponse } from 'next';
+import type { NextApiRequest, NextApiResponse } from "next";
export default function handler(req: NextApiRequest, res: NextApiResponse) {
- const protocol = req.headers['x-forwarded-proto'] || 'https';
+ const protocol = req.headers["x-forwarded-proto"] || "https";
const host = req.headers.host;
const callbackUrl = `${protocol}://${host}/api/auth/callback/lastfm`;
const authUrl = `https://www.last.fm/api/auth/?api_key=${process.env.LASTFM_KEY}&cb=${encodeURIComponent(callbackUrl)}`;
diff --git a/pages/api/auth/logout.ts b/pages/api/auth/logout.ts
index 6d4b692..a1abdbb 100644
--- a/pages/api/auth/logout.ts
+++ b/pages/api/auth/logout.ts
@@ -1,8 +1,8 @@
-import type { NextApiRequest, NextApiResponse } from 'next';
-import { getSession } from '../../../lib/session';
+import type { NextApiRequest, NextApiResponse } from "next";
+import { getSession } from "../../../lib/session";
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
const session = await getSession(req, res);
session.destroy();
- res.redirect('/');
+ res.redirect("/");
}
diff --git a/pages/api/barcode/[id].ts b/pages/api/barcode/[id].ts
index 571aac8..4995a92 100644
--- a/pages/api/barcode/[id].ts
+++ b/pages/api/barcode/[id].ts
@@ -1,6 +1,6 @@
-import type { NextApiRequest, NextApiResponse } from 'next';
-import { requireUser } from '../../../lib/withAuth';
-import Release from '../../../app/models/release';
+import type { NextApiRequest, NextApiResponse } from "next";
+import { requireUser } from "../../../lib/withAuth";
+import Release from "../../../app/models/release";
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
const user = await requireUser(req, res);
@@ -8,7 +8,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
try {
const raw = req.query.id as string;
- const [barcode, id] = raw.split('id:');
+ const [barcode, id] = raw.split("id:");
const query = id ? { id } : { barcode };
const release = await Release.firstOrCreate(query);
@@ -18,6 +18,6 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
const instantScrobble = user.isInstantScrobble(release._id);
res.json({ instantScrobble, ...release.toJSON() });
} catch (error) {
- res.status(400).json({ error: error instanceof Error ? error.message : 'Unknown error' });
+ res.status(400).json({ error: error instanceof Error ? error.message : "Unknown error" });
}
}
diff --git a/pages/api/scrobble.ts b/pages/api/scrobble.ts
index a0af0bb..270c18d 100644
--- a/pages/api/scrobble.ts
+++ b/pages/api/scrobble.ts
@@ -1,10 +1,10 @@
-import type { NextApiRequest, NextApiResponse } from 'next';
-import { requireUser } from '../../lib/withAuth';
-import Release from '../../app/models/release';
-import * as LastFM from '../../app/lastfm';
+import type { NextApiRequest, NextApiResponse } from "next";
+import { requireUser } from "../../lib/withAuth";
+import Release from "../../app/models/release";
+import * as LastFM from "../../app/lastfm";
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
- if (req.method !== 'POST') return res.status(405).json({ error: 'Method not allowed' });
+ if (req.method !== "POST") return res.status(405).json({ error: "Method not allowed" });
const user = await requireUser(req, res);
if (!user) return;
@@ -14,21 +14,23 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
const release = await Release.findOne({ _id: releaseId });
if (!release) {
- return res.status(400).json({ error: 'Release not found' });
+ return res.status(400).json({ error: "Release not found" });
}
user.history = [{ id: releaseId }].concat(user.history.slice(0, 19));
if (autoScrobble) user.instantScrobbles.addToSet(releaseId);
await user.save();
- if (process.env.NODE_ENV !== 'production') {
+ if (process.env.NODE_ENV !== "production") {
// eslint-disable-next-line no-console
- console.log([
- 'Scrobble:',
- '-------------------------------',
- `User: ${user.name}`,
- `Release: ${JSON.stringify(release.toJSON(), ['id', 'artist', 'title'], 2)}`,
- ].join('\n'));
+ console.log(
+ [
+ "Scrobble:",
+ "-------------------------------",
+ `User: ${user.name}`,
+ `Release: ${JSON.stringify(release.toJSON(), ["id", "artist", "title"], 2)}`,
+ ].join("\n"),
+ );
return res.json({});
}
diff --git a/pages/api/search/[query].ts b/pages/api/search/[query].ts
index 16ca1ca..15dc5f1 100644
--- a/pages/api/search/[query].ts
+++ b/pages/api/search/[query].ts
@@ -1,6 +1,6 @@
-import type { NextApiRequest, NextApiResponse } from 'next';
-import { requireUser } from '../../../lib/withAuth';
-import * as Discogs from '../../../app/discogs';
+import type { NextApiRequest, NextApiResponse } from "next";
+import { requireUser } from "../../../lib/withAuth";
+import * as Discogs from "../../../app/discogs";
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
const user = await requireUser(req, res);
diff --git a/pages/api/session.ts b/pages/api/session.ts
index 9e7e181..bcd3fdf 100644
--- a/pages/api/session.ts
+++ b/pages/api/session.ts
@@ -1,5 +1,5 @@
-import type { NextApiRequest, NextApiResponse } from 'next';
-import { requireUser } from '../../lib/withAuth';
+import type { NextApiRequest, NextApiResponse } from "next";
+import { requireUser } from "../../lib/withAuth";
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
const user = await requireUser(req, res);
diff --git a/pages/api/user/autoscrobbles.ts b/pages/api/user/autoscrobbles.ts
index 5b1e906..9098a34 100644
--- a/pages/api/user/autoscrobbles.ts
+++ b/pages/api/user/autoscrobbles.ts
@@ -1,14 +1,14 @@
-import sortBy from 'lodash/sortBy';
-import type { NextApiRequest, NextApiResponse } from 'next';
-import { requireUser } from '../../../lib/withAuth';
-import Release from '../../../app/models/release';
-import User from '../../../app/models/user';
+import sortBy from "lodash/sortBy";
+import type { NextApiRequest, NextApiResponse } from "next";
+import { requireUser } from "../../../lib/withAuth";
+import Release from "../../../app/models/release";
+import User from "../../../app/models/user";
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
const user = await requireUser(req, res);
if (!user) return;
- if (req.method === 'GET') {
+ if (req.method === "GET") {
try {
const releases = await Release.find({ _id: { $in: user.instantScrobbles } });
@@ -20,13 +20,13 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
year: release.year,
}));
- return res.json(sortBy(data, ['artist', 'title']));
+ return res.json(sortBy(data, ["artist", "title"]));
} catch (err) {
return res.status(400).json({ err });
}
}
- if (req.method === 'DELETE') {
+ if (req.method === "DELETE") {
try {
const { id } = req.body;
// eslint-disable-next-line no-underscore-dangle
@@ -37,5 +37,5 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
}
}
- return res.status(405).json({ error: 'Method not allowed' });
+ return res.status(405).json({ error: "Method not allowed" });
}
diff --git a/pages/api/user/history.ts b/pages/api/user/history.ts
index b8ef74d..4f82cfe 100644
--- a/pages/api/user/history.ts
+++ b/pages/api/user/history.ts
@@ -1,9 +1,9 @@
-import find from 'lodash/find';
-import sortBy from 'lodash/sortBy';
-import compact from 'lodash/compact';
-import type { NextApiRequest, NextApiResponse } from 'next';
-import { requireUser } from '../../../lib/withAuth';
-import Release from '../../../app/models/release';
+import find from "lodash/find";
+import sortBy from "lodash/sortBy";
+import compact from "lodash/compact";
+import type { NextApiRequest, NextApiResponse } from "next";
+import { requireUser } from "../../../lib/withAuth";
+import Release from "../../../app/models/release";
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
const user = await requireUser(req, res);
@@ -29,8 +29,8 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
};
});
- res.json(sortBy(compact(data), ['time']).reverse());
+ res.json(sortBy(compact(data), ["time"]).reverse());
} catch (err) {
- res.status(400).json({ error: err instanceof Error ? err.message : 'Unknown error' });
+ res.status(400).json({ error: err instanceof Error ? err.message : "Unknown error" });
}
}
diff --git a/pages/detected/[barcode].tsx b/pages/detected/[barcode].tsx
index d6c63e1..6ff9470 100644
--- a/pages/detected/[barcode].tsx
+++ b/pages/detected/[barcode].tsx
@@ -1,14 +1,14 @@
-import { connect } from 'react-redux';
-import React from 'react';
-import Router from 'next/router';
-import Head from 'next/head';
-import ReleaseInfo from '../../components/release/ReleaseInfo';
-import Scrobble from '../../components/scrobble/Scrobble';
-import SearchRelease from '../../components/release/SearchRelease';
-import CircleLayout from '../../components/layout/CircleLayout';
-import { trackEvent } from '../../lib/analytics';
-import { FooterContent } from '../../styles/layout.styles';
-import Checkbox from '../../components/ui/Checkbox';
+import { connect } from "react-redux";
+import React from "react";
+import Router from "next/router";
+import Head from "next/head";
+import ReleaseInfo from "../../components/release/ReleaseInfo";
+import Scrobble from "../../components/scrobble/Scrobble";
+import SearchRelease from "../../components/release/SearchRelease";
+import CircleLayout from "../../components/layout/CircleLayout";
+import { trackEvent } from "../../lib/analytics";
+import { FooterContent } from "../../styles/layout.styles";
+import Checkbox from "../../components/ui/Checkbox";
interface DetectedProps {
barcode: string;
@@ -19,10 +19,10 @@ class Detected extends React.Component {
- Router.push('/');
+ Router.push("/");
};
scrobble = () => {
@@ -34,10 +34,10 @@ class Detected extends React.Component {
- if (autoScrobble) trackEvent('Detected', 'AutoScrobble');
+ handleAutoScrobble = autoScrobble => {
+ if (autoScrobble) trackEvent("Detected", "AutoScrobble");
this.setState({ autoScrobble });
- }
+ };
render() {
const { scrobbling, autoScrobble } = this.state;
@@ -49,31 +49,22 @@ class Detected extends React.Component
-
- Auto-scrobble on next scan
-
-
- )}
+ footer={
+ showRelease && (
+
+
+ Auto-scrobble on next scan
+
+
+ )
+ }
header={showRelease && }
>
- {scrobbling
- ? (
-
- )
- : (
-
- )
- }
+ {scrobbling ? (
+
+ ) : (
+
+ )}
>
);
@@ -86,6 +77,4 @@ const mapStateToProps = (state, { barcode }) => ({
...state.release[barcode],
});
-export default connect(
- mapStateToProps,
-)(Detected);
+export default connect(mapStateToProps)(Detected);
diff --git a/pages/index.tsx b/pages/index.tsx
index 2a13fea..878447d 100644
--- a/pages/index.tsx
+++ b/pages/index.tsx
@@ -1,8 +1,8 @@
-import React from 'react';
-import Router from 'next/router';
-import QueryRelease from '../components/query/QueryRelease';
-import Scanner from '../components/scanner/Scanner';
-import CircleLayout from '../components/layout/CircleLayout';
+import React from "react";
+import Router from "next/router";
+import QueryRelease from "../components/query/QueryRelease";
+import Scanner from "../components/scanner/Scanner";
+import CircleLayout from "../components/layout/CircleLayout";
const codeDetected = ({ codeResult: { code: barcode } }) => {
Router.push(`/detected/${barcode}`);
diff --git a/pages/legal.tsx b/pages/legal.tsx
index 28b8583..5ed0e78 100644
--- a/pages/legal.tsx
+++ b/pages/legal.tsx
@@ -1,45 +1,74 @@
-import React from 'react';
+import React from "react";
-import BackButton from '../components/ui/BackButton';
-import targetBlank from '../lib/targetBlank';
-import { Anchor, Wrapper } from '../styles/legal.styles';
+import BackButton from "../components/ui/BackButton";
+import targetBlank from "../lib/targetBlank";
+import { Anchor, Wrapper } from "../styles/legal.styles";
const images = (
<>
- Favicon: Icon made by Roundicons from www.flaticon.com is licensed by CC 3.0 BY
-
-
- No Results: Icons made by Darius Dan from www.flaticon.com is licensed by CC 3.0 BY
+ Favicon: Icon made by{" "}
+
+ Roundicons
+ {" "}
+ from{" "}
+
+ www.flaticon.com
+ {" "}
+ is licensed by{" "}
+
+ CC 3.0 BY
+
+
+
+ No Results: Icons made by{" "}
+
+ Darius Dan
+ {" "}
+ from{" "}
+
+ www.flaticon.com
+ {" "}
+ is licensed by{" "}
+
+ CC 3.0 BY
+
>
);
-
const Index = () => (
- 🇩🇪
- {' '}
- Deutsche Fassung siehe unten
+
+ 🇩🇪
+ {" "}
+
+ Deutsche Fassung siehe unten
+
Legal Notice
Information according to § 5 TMG
- Daniel Puscher
- Neue Bahnhofstr. 33
- 10245 Berlin
+ Daniel Puscher
+
+ Neue Bahnhofstr. 33
+
+ 10245 Berlin
+
Germany
Contact us
- Phone: +49 (0) 30 81455966
- Fax: +49 (0) 30 81455966
- E-Mail: daniel {'{ät}'} codescrobble.com
+ Phone: +49 (0) 30 81455966
+
+ Fax: +49 (0) 30 81455966
+
+ E-Mail: daniel {"{ät}"} codescrobble.com
Indication of source for images and graphics
@@ -47,50 +76,48 @@ const Index = () => (
Liability for contents
- As a service provider we are responsible according to § 7 Abs.1 TMG for our own
- contents on these pages according to the general laws. According to §§ 8 to 10 TMG, we
- are not obliged to monitor transmitted or stored third-party information or to
- investigate circumstances that indicate illegal activity.
+ As a service provider we are responsible according to § 7 Abs.1 TMG for our own contents on these pages according
+ to the general laws. According to §§ 8 to 10 TMG, we are not obliged to monitor transmitted or stored third-party
+ information or to investigate circumstances that indicate illegal activity.
- Obligations to remove or block the use of information in accordance with general laws
- remain unaffected by this. However, liability in this respect is only possible from the
- time of knowledge of a concrete violation of the law. As soon as we become aware of
- such infringements, we will remove the content immediately.
+ Obligations to remove or block the use of information in accordance with general laws remain unaffected by this.
+ However, liability in this respect is only possible from the time of knowledge of a concrete violation of the law.
+ As soon as we become aware of such infringements, we will remove the content immediately.
Liability for links
- Our offer contains links to external websites of third parties on whose contents we
- have no influence. Therefore, we cannot assume any liability for these external
- contents. The respective provider or operator of the pages is always responsible for
- the contents of the linked pages. The linked pages were checked for possible legal
- infringements at the time of linking. Illegal contents were not recognisable at the
- time of linking.
+ Our offer contains links to external websites of third parties on whose contents we have no influence. Therefore,
+ we cannot assume any liability for these external contents. The respective provider or operator of the pages is
+ always responsible for the contents of the linked pages. The linked pages were checked for possible legal
+ infringements at the time of linking. Illegal contents were not recognisable at the time of linking.
- A permanent control of the contents of the linked pages is not reasonable without
- concrete evidence of an infringement. As soon as we become aware of any legal
- infringements, we will remove such links immediately.
+ A permanent control of the contents of the linked pages is not reasonable without concrete evidence of an
+ infringement. As soon as we become aware of any legal infringements, we will remove such links immediately.
Copyright
- The contents and works on these pages created by the site operators are subject to
- German copyright law. Duplication, processing, distribution and any form of
- commercialization of such material beyond the scope of the copyright law shall require
- the prior written consent of its respective author or creator. Downloads and copies of
+ The contents and works on these pages created by the site operators are subject to German copyright law.
+ Duplication, processing, distribution and any form of commercialization of such material beyond the scope of the
+ copyright law shall require the prior written consent of its respective author or creator. Downloads and copies of
these pages are only permitted for private, non-commercial use.
- Insofar as the content on this site was not created by the operator, the copyrights of
- third parties are respected. In particular, contents of third parties are marked as
- such. Should you nevertheless become aware of a copyright infringement, please inform
- us accordingly. As soon as we become aware of any infringements, we will remove such
- content immediately.
+ Insofar as the content on this site was not created by the operator, the copyrights of third parties are
+ respected. In particular, contents of third parties are marked as such. Should you nevertheless become aware of a
+ copyright infringement, please inform us accordingly. As soon as we become aware of any infringements, we will
+ remove such content immediately.
- Source: https://www.e-recht24.de/impressum-generator.html
+
+ Source:{" "}
+
+ https://www.e-recht24.de/impressum-generator.html
+
+
@@ -113,7 +140,7 @@ const Index = () => (
Telefax: +49 (0) 30 81455966
- E-Mail: daniel {'{ät}'} codescrobble.com
+ E-Mail: daniel {"{ät}"} codescrobble.com
Bildnachweise
@@ -121,56 +148,53 @@ const Index = () => (
Haftung für Inhalte
- Als Diensteanbieter sind wir gemäß § 7 Abs.1 TMG für eigene
- Inhalte auf diesen Seiten nach den allgemeinen Gesetzen verantwortlich. Nach
- §§ 8 bis 10 TMG sind wir als Diensteanbieter jedoch nicht verpflichtet,
- übermittelte oder gespeicherte fremde Informationen zu überwachen oder nach
- Umständen zu forschen, die auf eine rechtswidrige Tätigkeit hinweisen.
+ Als Diensteanbieter sind wir gemäß § 7 Abs.1 TMG für eigene Inhalte auf diesen Seiten nach den
+ allgemeinen Gesetzen verantwortlich. Nach §§ 8 bis 10 TMG sind wir als Diensteanbieter jedoch nicht
+ verpflichtet, übermittelte oder gespeicherte fremde Informationen zu überwachen oder nach Umständen zu
+ forschen, die auf eine rechtswidrige Tätigkeit hinweisen.
- Verpflichtungen zur Entfernung oder Sperrung der Nutzung von Informationen nach den
- allgemeinen Gesetzen bleiben hiervon unberührt. Eine diesbezügliche Haftung
- ist jedoch erst ab dem Zeitpunkt der Kenntnis einer konkreten Rechtsverletzung
- möglich. Bei Bekanntwerden von entsprechenden Rechtsverletzungen werden wir
- diese Inhalte umgehend entfernen.
+ Verpflichtungen zur Entfernung oder Sperrung der Nutzung von Informationen nach den allgemeinen Gesetzen bleiben
+ hiervon unberührt. Eine diesbezügliche Haftung ist jedoch erst ab dem Zeitpunkt der Kenntnis einer
+ konkreten Rechtsverletzung möglich. Bei Bekanntwerden von entsprechenden Rechtsverletzungen werden wir diese
+ Inhalte umgehend entfernen.
Haftung für Links
- Unser Angebot enthält Links zu externen Websites Dritter, auf deren Inhalte wir
- keinen Einfluss haben. Deshalb können wir für diese fremden Inhalte auch
- keine Gewähr übernehmen. Für die Inhalte der verlinkten Seiten ist
- stets der jeweilige Anbieter oder Betreiber der Seiten verantwortlich. Die verlinkten
- Seiten wurden zum Zeitpunkt der Verlinkung auf mögliche
- Rechtsverstöße überprüft. Rechtswidrige Inhalte waren zum
- Zeitpunkt der Verlinkung nicht
- erkennbar.
+ Unser Angebot enthält Links zu externen Websites Dritter, auf deren Inhalte wir keinen Einfluss haben. Deshalb
+ können wir für diese fremden Inhalte auch keine Gewähr übernehmen. Für die Inhalte der
+ verlinkten Seiten ist stets der jeweilige Anbieter oder Betreiber der Seiten verantwortlich. Die verlinkten Seiten
+ wurden zum Zeitpunkt der Verlinkung auf mögliche Rechtsverstöße überprüft. Rechtswidrige
+ Inhalte waren zum Zeitpunkt der Verlinkung nicht erkennbar.
- Eine permanente inhaltliche Kontrolle der verlinkten Seiten ist jedoch ohne konkrete
- Anhaltspunkte einer Rechtsverletzung nicht zumutbar. Bei Bekanntwerden von
- Rechtsverletzungen werden wir derartige Links umgehend entfernen.
+ Eine permanente inhaltliche Kontrolle der verlinkten Seiten ist jedoch ohne konkrete Anhaltspunkte einer
+ Rechtsverletzung nicht zumutbar. Bei Bekanntwerden von Rechtsverletzungen werden wir derartige Links umgehend
+ entfernen.
Urheberrecht
- Die durch die Seitenbetreiber erstellten Inhalte und Werke auf diesen Seiten
- unterliegen dem deutschen Urheberrecht. Die Vervielfältigung, Bearbeitung,
- Verbreitung und jede Art der Verwertung außerhalb der Grenzen des
- Urheberrechtes bedürfen der schriftlichen Zustimmung des jeweiligen Autors bzw.
- Erstellers. Downloads und Kopien dieser Seite sind nur für den privaten, nicht
- kommerziellen Gebrauch gestattet.
+ Die durch die Seitenbetreiber erstellten Inhalte und Werke auf diesen Seiten unterliegen dem deutschen
+ Urheberrecht. Die Vervielfältigung, Bearbeitung, Verbreitung und jede Art der Verwertung außerhalb der Grenzen des
+ Urheberrechtes bedürfen der schriftlichen Zustimmung des jeweiligen Autors bzw. Erstellers. Downloads und
+ Kopien dieser Seite sind nur für den privaten, nicht kommerziellen Gebrauch gestattet.
- Soweit die Inhalte auf dieser Seite nicht vom Betreiber erstellt wurden, werden die
- Urheberrechte Dritter beachtet. Insbesondere werden Inhalte Dritter als solche
- gekennzeichnet. Sollten Sie trotzdem auf eine Urheberrechtsverletzung aufmerksam
- werden, bitten wir um einen entsprechenden Hinweis. Bei Bekanntwerden von
+ Soweit die Inhalte auf dieser Seite nicht vom Betreiber erstellt wurden, werden die Urheberrechte Dritter
+ beachtet. Insbesondere werden Inhalte Dritter als solche gekennzeichnet. Sollten Sie trotzdem auf eine
+ Urheberrechtsverletzung aufmerksam werden, bitten wir um einen entsprechenden Hinweis. Bei Bekanntwerden von
Rechtsverletzungen werden wir derartige Inhalte umgehend entfernen.
- Quelle: https://www.e-recht24.de/impressum-generator.html
+
+ Quelle:{" "}
+
+ https://www.e-recht24.de/impressum-generator.html
+
+
);
diff --git a/pages/login.tsx b/pages/login.tsx
index 44d56ed..24d0dfa 100644
--- a/pages/login.tsx
+++ b/pages/login.tsx
@@ -1,30 +1,28 @@
-import React from 'react';
+import React from "react";
-import LegalLinks from '../components/ui/LegalLinks';
-import LoginButton from '../components/ui/LoginButton';
-import { Center } from '../styles/layout.styles';
-import {
- Description, H1, Logo, P, Wrapper,
-} from '../styles/login.styles';
-import { autotrackParams } from '../lib/analytics';
+import LegalLinks from "../components/ui/LegalLinks";
+import LoginButton from "../components/ui/LoginButton";
+import { Center } from "../styles/layout.styles";
+import { Description, H1, Logo, P, Wrapper } from "../styles/login.styles";
+import { autotrackParams } from "../lib/analytics";
const Index = () => (
+ CodeScrobble makes it easy to scrobble your CD or vinyl records to Last.fm.
- CodeScrobble makes it easy to scrobble your CD or vinyl records to Last.fm.
-
-
- Just use you smartphone camera to scan the barcode, check the result and you
- are done. We also have an auto-scrobble mode, that makes scrobbling even faster.
+ Just use you smartphone camera to scan the barcode, check the result and you are done. We also have an
+ auto-scrobble mode, that makes scrobbling even faster.
-
+
diff --git a/pages/privacy.tsx b/pages/privacy.tsx
index 3b54d01..17c6ea4 100644
--- a/pages/privacy.tsx
+++ b/pages/privacy.tsx
@@ -1,204 +1,176 @@
-import React from 'react';
+import React from "react";
-import BackButton from '../components/ui/BackButton';
-import targetBlank from '../lib/targetBlank';
-import { Anchor, Wrapper } from '../styles/legal.styles';
+import BackButton from "../components/ui/BackButton";
+import targetBlank from "../lib/targetBlank";
+import { Anchor, Wrapper } from "../styles/legal.styles";
const Index = () => (
- 🇩🇪
- {' '}
- Deutsche Fassung siehe unten
+
+ 🇩🇪
+ {" "}
+
+ Deutsche Fassung siehe unten
+
Privacy Policy
- Personal data (usually referred to just as "data" below) will only be
- processed by us to the extent necessary and for the purpose of providing a
- functional and user-friendly website, including its contents, and the services
- offered there.
+ Personal data (usually referred to just as "data" below) will only be processed by us to the extent
+ necessary and for the purpose of providing a functional and user-friendly website, including its contents, and the
+ services offered there.
- Per Art. 4 No. 1 of Regulation (EU) 2016/679, i.e. the General Data Protection
- Regulation (hereinafter referred to as the "GDPR"),
- "processing" refers to any operation or set of operations such as
- collection, recording, organization, structuring, storage, adaptation,
- alteration, retrieval, consultation, use, disclosure by transmission,
- dissemination, or otherwise making available, alignment, or combination,
- restriction, erasure, or destruction performed on personal data, whether by
- automated means or not.
+ Per Art. 4 No. 1 of Regulation (EU) 2016/679, i.e. the General Data Protection Regulation (hereinafter referred to
+ as the "GDPR"), "processing" refers to any operation or set of operations such as collection,
+ recording, organization, structuring, storage, adaptation, alteration, retrieval, consultation, use, disclosure by
+ transmission, dissemination, or otherwise making available, alignment, or combination, restriction, erasure, or
+ destruction performed on personal data, whether by automated means or not.
- The following privacy policy is intended to inform you in particular about the
- type, scope, purpose, duration, and legal basis for the processing of such
- data either under our own control or in conjunction with others. We also
- inform you below about the third-party components we use to optimize our
- website and improve the user experience which may result in said third parties
- also processing data they collect and control.
+ The following privacy policy is intended to inform you in particular about the type, scope, purpose, duration, and
+ legal basis for the processing of such data either under our own control or in conjunction with others. We also
+ inform you below about the third-party components we use to optimize our website and improve the user experience
+ which may result in said third parties also processing data they collect and control.
Our privacy policy is structured as follows:
- I. Information about us as controllers of your data II. The rights of
- users and data subjects III. Information about the data processing
+ I. Information about us as controllers of your data
+
+ II. The rights of users and data subjects
+
+ III. Information about the data processing
I. Information about us as controllers of your data
-
- The party responsible for this website (the "controller") for purposes of data
- protection law is:
-
-
- Daniel Puscher
- Neue Bahnhofstr. 33
- 10245 Berlin
+
The party responsible for this website (the "controller") for purposes of data protection law is:
+
+ Daniel Puscher
+
+ Neue Bahnhofstr. 33
+
+ 10245 Berlin
+
Germany
- Phone: +49 (0) 30 81455966
- Fax: +49 (0) 30 81455966
- E-Mail: daniel {'{ät}'} codescrobble.com
+ Phone: +49 (0) 30 81455966
+
+ Fax: +49 (0) 30 81455966
+
+ E-Mail: daniel {"{ät}"} codescrobble.com
The controller's data protection officer is:
Daniel Puscher
II. The rights of users and data subjects
- With regard to the data processing to be described in more detail below, users
- and data subjects have the right
+ With regard to the data processing to be described in more detail below, users and data subjects have the right
- to confirmation of whether data concerning them is being processed,
- information about the data being processed, further information about the
- nature of the data processing, and copies of the data (cf. also Art. 15
- GDPR);
-
-
- to correct or complete incorrect or incomplete data (cf. also Art. 16 GDPR);
+ to confirmation of whether data concerning them is being processed, information about the data being processed,
+ further information about the nature of the data processing, and copies of the data (cf. also Art. 15 GDPR);
+ to correct or complete incorrect or incomplete data (cf. also Art. 16 GDPR);
- to the immediate deletion of data concerning them (cf. also Art. 17 DSGVO),
- or, alternatively, if further processing is necessary as stipulated in Art.
- 17 Para. 3 GDPR, to restrict said processing per Art. 18 GDPR;
+ to the immediate deletion of data concerning them (cf. also Art. 17 DSGVO), or, alternatively, if further
+ processing is necessary as stipulated in Art. 17 Para. 3 GDPR, to restrict said processing per Art. 18 GDPR;
- to receive copies of the data concerning them and/or provided by them and to
- have the same transmitted to other providers/controllers (cf. also Art. 20
- GDPR);
+ to receive copies of the data concerning them and/or provided by them and to have the same transmitted to other
+ providers/controllers (cf. also Art. 20 GDPR);
- to file complaints with the supervisory authority if they believe that data
- concerning them is being processed by the controller in breach of data
- protection provisions (see also Art. 77 GDPR).
+ to file complaints with the supervisory authority if they believe that data concerning them is being processed
+ by the controller in breach of data protection provisions (see also Art. 77 GDPR).
- In addition, the controller is obliged to inform all recipients to whom it
- discloses data of any such corrections, deletions, or restrictions placed on
- processing the same per Art. 16, 17 Para. 1, 18 GDPR. However, this obligation
- does not apply if such notification is impossible or involves a
- disproportionate effort. Nevertheless, users have a right to information about
- these recipients.
+ In addition, the controller is obliged to inform all recipients to whom it discloses data of any such corrections,
+ deletions, or restrictions placed on processing the same per Art. 16, 17 Para. 1, 18 GDPR. However, this
+ obligation does not apply if such notification is impossible or involves a disproportionate effort. Nevertheless,
+ users have a right to information about these recipients.
- Likewise, under Art. 21 GDPR, users and data subjects have the right to
- object to the controller's future processing of their data pursuant to Art.
- 6 Para. 1 lit. f) GDPR. In particular, an objection to data processing for
- the purpose of direct advertising is permissible.
+ Likewise, under Art. 21 GDPR, users and data subjects have the right to object to the controller's future
+ processing of their data pursuant to Art. 6 Para. 1 lit. f) GDPR. In particular, an objection to data processing
+ for the purpose of direct advertising is permissible.
III. Information about the data processing
- Your data processed when using our website will be deleted or blocked as soon
- as the purpose for its storage ceases to apply, provided the deletion of the
- same is not in breach of any statutory storage obligations or unless otherwise
- stipulated below.
+ Your data processed when using our website will be deleted or blocked as soon as the purpose for its storage
+ ceases to apply, provided the deletion of the same is not in breach of any statutory storage obligations or unless
+ otherwise stipulated below.
Server data
- For technical reasons, the following data sent by your internet browser to us
- or to our server provider will be collected, especially to ensure a secure and
- stable website: These server log files record the type and version of your
- browser, operating system, the website from which you came (referrer URL), the
- webpages on our site visited, the date and time of your visit, as well as the
- IP address from which you visited our site.
+ For technical reasons, the following data sent by your internet browser to us or to our server provider will be
+ collected, especially to ensure a secure and stable website: These server log files record the type and version of
+ your browser, operating system, the website from which you came (referrer URL), the webpages on our site visited,
+ the date and time of your visit, as well as the IP address from which you visited our site.
+ The data thus collected will be temporarily stored, but not in association with any other of your data.
- The data thus collected will be temporarily stored, but not in association
- with any other of your data.
+ The basis for this storage is Art. 6 Para. 1 lit. f) GDPR. Our legitimate interest lies in the improvement,
+ stability, functionality, and security of our website.
- The basis for this storage is Art. 6 Para. 1 lit. f) GDPR. Our legitimate
- interest lies in the improvement, stability, functionality, and security of
- our website.
-
-
- The data will be deleted within no more than seven days, unless continued
- storage is required for evidentiary purposes. In which case, all or part of
- the data will be excluded from deletion until the investigation of the
+ The data will be deleted within no more than seven days, unless continued storage is required for evidentiary
+ purposes. In which case, all or part of the data will be excluded from deletion until the investigation of the
relevant incident is finally resolved.
Cookies
a) Session cookies
- We use cookies on our website. Cookies are small text files or other storage
- technologies stored on your computer by your browser. These cookies process
- certain specific information about you, such as your browser, location data,
- or IP address.
+ We use cookies on our website. Cookies are small text files or other storage technologies stored on your computer
+ by your browser. These cookies process certain specific information about you, such as your browser, location
+ data, or IP address.
- This processing makes our website more user-friendly, efficient, and secure,
- allowing us, for example, to display our website in different languages or to
- offer a shopping cart function.
+ This processing makes our website more user-friendly, efficient, and secure, allowing us, for example, to display
+ our website in different languages or to offer a shopping cart function.
- The legal basis for such processing is Art. 6 Para. 1 lit. b) GDPR, insofar as
- these cookies are used to collect data to initiate or process contractual
- relationships.
+ The legal basis for such processing is Art. 6 Para. 1 lit. b) GDPR, insofar as these cookies are used to collect
+ data to initiate or process contractual relationships.
- If the processing does not serve to initiate or process a contract, our
- legitimate interest lies in improving the functionality of our website. The
- legal basis is then Art. 6 Para. 1 lit. f) GDPR.
+ If the processing does not serve to initiate or process a contract, our legitimate interest lies in improving the
+ functionality of our website. The legal basis is then Art. 6 Para. 1 lit. f) GDPR.
When you close your browser, these session cookies are deleted.
b) Third-party cookies
- If necessary, our website may also use cookies from companies with whom we
- cooperate for the purpose of advertising, analyzing, or improving the features
- of our website.
+ If necessary, our website may also use cookies from companies with whom we cooperate for the purpose of
+ advertising, analyzing, or improving the features of our website.
- Please refer to the following information for details, in particular for the
- legal basis and purpose of such third-party collection and processing of data
- collected through cookies.
+ Please refer to the following information for details, in particular for the legal basis and purpose of such
+ third-party collection and processing of data collected through cookies.
c) Disabling cookies
- You can refuse the use of cookies by changing the settings on your browser.
- Likewise, you can use the browser to delete cookies that have already been
- stored. However, the steps and measures required vary, depending on the
- browser you use. If you have any questions, please use the help function or
- consult the documentation for your browser or contact its maker for support.
- Browser settings cannot prevent so-called flash cookies from being set.
- Instead, you will need to change the setting of your Flash player. The steps
- and measures required for this also depend on the Flash player you are using.
- If you have any questions, please use the help function or consult the
+ You can refuse the use of cookies by changing the settings on your browser. Likewise, you can use the browser to
+ delete cookies that have already been stored. However, the steps and measures required vary, depending on the
+ browser you use. If you have any questions, please use the help function or consult the documentation for your
+ browser or contact its maker for support. Browser settings cannot prevent so-called flash cookies from being set.
+ Instead, you will need to change the setting of your Flash player. The steps and measures required for this also
+ depend on the Flash player you are using. If you have any questions, please use the help function or consult the
documentation for your Flash player or contact its maker for support.
- If you prevent or restrict the installation of cookies, not all of the
- functions on our site may be fully usable.
+ If you prevent or restrict the installation of cookies, not all of the functions on our site may be fully usable.
Google Analytics
- We use Google Analytics on our website. This is a web analytics service
- provided by Google Inc., 1600 Amphitheatre Parkway, Mountain View, CA 94043
- (hereinafter: Google).
+ We use Google Analytics on our website. This is a web analytics service provided by Google Inc., 1600 Amphitheatre
+ Parkway, Mountain View, CA 94043 (hereinafter: Google).
Through certification according to the EU-US Privacy Shield
@@ -207,36 +179,33 @@ const Index = () => (
- Google guarantees that it will follow the EU's data protection regulations
- when processing data in the United States.
+ Google guarantees that it will follow the EU's data protection regulations when processing data in the United
+ States.
- The Google Analytics service is used to analyze how our website is used. The
- legal basis is Art. 6 Para. 1 lit. f) GDPR. Our legitimate interest lies in
- the analysis, optimization, and economic operation of our site.
+ The Google Analytics service is used to analyze how our website is used. The legal basis is Art. 6 Para. 1 lit. f)
+ GDPR. Our legitimate interest lies in the analysis, optimization, and economic operation of our site.
- Usage and user-related information, such as IP address, place, time, or
- frequency of your visits to our website will be transmitted to a Google server
- in the United States and stored there. However, we use Google Analytics with
- the so-called anonymization function, whereby Google truncates the IP address
- within the EU or the EEA before it is transmitted to the US.
+ Usage and user-related information, such as IP address, place, time, or frequency of your visits to our website
+ will be transmitted to a Google server in the United States and stored there. However, we use Google Analytics
+ with the so-called anonymization function, whereby Google truncates the IP address within the EU or the EEA before
+ it is transmitted to the US.
- The data collected in this way is in turn used by Google to provide us with an
- evaluation of visits to our website and what visitors do once there. This data
- can also be used to provide other services related to the use of our website
- and of the internet in general.
+ The data collected in this way is in turn used by Google to provide us with an evaluation of visits to our website
+ and what visitors do once there. This data can also be used to provide other services related to the use of our
+ website and of the internet in general.
- Google states that it will not connect your IP address to other data. In
- addition, Google provides further information with regard to its data
- protection practices at
+ Google states that it will not connect your IP address to other data. In addition, Google provides further
+ information with regard to its data protection practices at
https://www.google.com/intl/de/policies/privacy/partners
- ,
+
+ ,
including options you can exercise to prevent such use of your data.
In addition, Google offers an opt-out add-on at
@@ -246,20 +215,18 @@ const Index = () => (
- in addition with further information. This add-on can be installed on the most
- popular browsers and offers you further control over the data that Google
- collects when you visit our website. The add-on informs Google Analytics'
- JavaScript (ga.js) that no information about the website visit should be
- transmitted to Google Analytics. However, this does not prevent information
- from being transmitted to us or to other web analytics services we may use as
- detailed herein.
+ in addition with further information. This add-on can be installed on the most popular browsers and offers you
+ further control over the data that Google collects when you visit our website. The add-on informs Google
+ Analytics' JavaScript (ga.js) that no information about the website visit should be transmitted to Google
+ Analytics. However, this does not prevent information from being transmitted to us or to other web analytics
+ services we may use as detailed herein.
Model Data Protection Statement
- {' for '}
+ {" for "}
Anwaltskanzlei Weiß & Partner
@@ -270,255 +237,213 @@ const Index = () => (
Datenschutzerklärung
- Personenbezogene Daten (nachfolgend zumeist nur „Daten“ genannt) werden von
- uns nur im Rahmen der Erforderlichkeit sowie zum Zwecke der Bereitstellung
- eines funktionsfähigen und nutzerfreundlichen Internetauftritts, inklusive
+ Personenbezogene Daten (nachfolgend zumeist nur „Daten“ genannt) werden von uns nur im Rahmen der Erforderlichkeit
+ sowie zum Zwecke der Bereitstellung eines funktionsfähigen und nutzerfreundlichen Internetauftritts, inklusive
seiner Inhalte und der dort angebotenen Leistungen, verarbeitet.
- Gemäß Art. 4 Ziffer 1. der Verordnung (EU) 2016/679, also der
- Datenschutz-Grundverordnung (nachfolgend nur „DSGVO“ genannt), gilt als
- „Verarbeitung“ jeder mit oder ohne Hilfe automatisierter Verfahren
- ausgeführter Vorgang oder jede solche Vorgangsreihe im Zusammenhang mit
- personenbezogenen Daten, wie das Erheben, das Erfassen, die Organisation, das
- Ordnen, die Speicherung, die Anpassung oder Veränderung, das Auslesen, das
- Abfragen, die Verwendung, die Offenlegung durch Übermittlung, Verbreitung oder
- eine andere Form der Bereitstellung, den Abgleich oder die Verknüpfung, die
- Einschränkung, das Löschen oder die Vernichtung.
+ Gemäß Art. 4 Ziffer 1. der Verordnung (EU) 2016/679, also der Datenschutz-Grundverordnung (nachfolgend nur „DSGVO“
+ genannt), gilt als „Verarbeitung“ jeder mit oder ohne Hilfe automatisierter Verfahren ausgeführter Vorgang oder
+ jede solche Vorgangsreihe im Zusammenhang mit personenbezogenen Daten, wie das Erheben, das Erfassen, die
+ Organisation, das Ordnen, die Speicherung, die Anpassung oder Veränderung, das Auslesen, das Abfragen, die
+ Verwendung, die Offenlegung durch Übermittlung, Verbreitung oder eine andere Form der Bereitstellung, den Abgleich
+ oder die Verknüpfung, die Einschränkung, das Löschen oder die Vernichtung.
- Mit der nachfolgenden Datenschutzerklärung informieren wir Sie insbesondere
- über Art, Umfang, Zweck, Dauer und Rechtsgrundlage der Verarbeitung
- personenbezogener Daten, soweit wir entweder allein oder gemeinsam mit anderen
- über die Zwecke und Mittel der Verarbeitung entscheiden. Zudem informieren wir
- Sie nachfolgend über die von uns zu Optimierungszwecken sowie zur Steigerung
- der Nutzungsqualität eingesetzten Fremdkomponenten, soweit hierdurch Dritte
- Daten in wiederum eigener Verantwortung verarbeiten.
+ Mit der nachfolgenden Datenschutzerklärung informieren wir Sie insbesondere über Art, Umfang, Zweck, Dauer und
+ Rechtsgrundlage der Verarbeitung personenbezogener Daten, soweit wir entweder allein oder gemeinsam mit anderen
+ über die Zwecke und Mittel der Verarbeitung entscheiden. Zudem informieren wir Sie nachfolgend über die von uns zu
+ Optimierungszwecken sowie zur Steigerung der Nutzungsqualität eingesetzten Fremdkomponenten, soweit hierdurch
+ Dritte Daten in wiederum eigener Verantwortung verarbeiten.
Unsere Datenschutzerklärung ist wie folgt gegliedert:
- I. Informationen über uns als Verantwortliche II. Rechte der Nutzer und
- Betroffenen III. Informationen zur Datenverarbeitung
+ I. Informationen über uns als Verantwortliche
+
+ II. Rechte der Nutzer und Betroffenen
+
+ III. Informationen zur Datenverarbeitung
I. Informationen über uns als Verantwortliche
-
- Verantwortlicher Anbieter dieses Internetauftritts im datenschutzrechtlichen
- Sinne ist:
-
-
- Daniel Puscher
- Neue Bahnhofstr. 33
- 10245 Berlin
+
Verantwortlicher Anbieter dieses Internetauftritts im datenschutzrechtlichen Sinne ist:
+
+ Daniel Puscher
+
+ Neue Bahnhofstr. 33
+
+ 10245 Berlin
+
Germany
- Phone: +49 (0) 30 81455966
- Fax: +49 (0) 30 81455966
- E-Mail: daniel {'{ät}'} codescrobble.com
+ Phone: +49 (0) 30 81455966
+
+ Fax: +49 (0) 30 81455966
+
+ E-Mail: daniel {"{ät}"} codescrobble.com
Datenschutzbeauftragte/r beim Anbieter ist:
Daniel Puscher
II. Rechte der Nutzer und Betroffenen
- Mit Blick auf die nachfolgend noch näher beschriebene Datenverarbeitung haben
- die Nutzer und Betroffenen das Recht
+ Mit Blick auf die nachfolgend noch näher beschriebene Datenverarbeitung haben die Nutzer und Betroffenen das Recht
- auf Bestätigung, ob sie betreffende Daten verarbeitet werden, auf Auskunft
- über die verarbeiteten Daten, auf weitere Informationen über die
- Datenverarbeitung sowie auf Kopien der Daten (vgl. auch Art. 15 DSGVO);
+ auf Bestätigung, ob sie betreffende Daten verarbeitet werden, auf Auskunft über die verarbeiteten Daten, auf
+ weitere Informationen über die Datenverarbeitung sowie auf Kopien der Daten (vgl. auch Art. 15 DSGVO);
+ auf Berichtigung oder Vervollständigung unrichtiger bzw. unvollständiger Daten (vgl. auch Art. 16 DSGVO);
- auf Berichtigung oder Vervollständigung unrichtiger bzw. unvollständiger
- Daten (vgl. auch Art. 16 DSGVO);
-
-
- auf unverzügliche Löschung der sie betreffenden Daten (vgl. auch Art. 17
- DSGVO), oder, alternativ, soweit eine weitere Verarbeitung gemäß Art. 17
- Abs. 3 DSGVO erforderlich ist, auf Einschränkung der Verarbeitung nach
+ auf unverzügliche Löschung der sie betreffenden Daten (vgl. auch Art. 17 DSGVO), oder, alternativ, soweit eine
+ weitere Verarbeitung gemäß Art. 17 Abs. 3 DSGVO erforderlich ist, auf Einschränkung der Verarbeitung nach
Maßgabe von Art. 18 DSGVO;
- auf Erhalt der sie betreffenden und von ihnen bereitgestellten Daten und auf
- Übermittlung dieser Daten an andere Anbieter/Verantwortliche (vgl. auch Art.
- 20 DSGVO);
+ auf Erhalt der sie betreffenden und von ihnen bereitgestellten Daten und auf Übermittlung dieser Daten an andere
+ Anbieter/Verantwortliche (vgl. auch Art. 20 DSGVO);
- auf Beschwerde gegenüber der Aufsichtsbehörde, sofern sie der Ansicht sind,
- dass die sie betreffenden Daten durch den Anbieter unter Verstoß gegen
- datenschutzrechtliche Bestimmungen verarbeitet werden (vgl. auch Art. 77
+ auf Beschwerde gegenüber der Aufsichtsbehörde, sofern sie der Ansicht sind, dass die sie betreffenden Daten
+ durch den Anbieter unter Verstoß gegen datenschutzrechtliche Bestimmungen verarbeitet werden (vgl. auch Art. 77
DSGVO).
- Darüber hinaus ist der Anbieter dazu verpflichtet, alle Empfänger, denen
- gegenüber Daten durch den Anbieter offengelegt worden sind, über jedwede
- Berichtigung oder Löschung von Daten oder die Einschränkung der Verarbeitung,
- die aufgrund der Artikel 16, 17 Abs. 1, 18 DSGVO erfolgt, zu unterrichten.
- Diese Verpflichtung besteht jedoch nicht, soweit diese Mitteilung unmöglich
- oder mit einem unverhältnismäßigen Aufwand verbunden ist. Unbeschadet dessen
- hat der Nutzer ein Recht auf Auskunft über diese Empfänger.
+ Darüber hinaus ist der Anbieter dazu verpflichtet, alle Empfänger, denen gegenüber Daten durch den Anbieter
+ offengelegt worden sind, über jedwede Berichtigung oder Löschung von Daten oder die Einschränkung der
+ Verarbeitung, die aufgrund der Artikel 16, 17 Abs. 1, 18 DSGVO erfolgt, zu unterrichten. Diese Verpflichtung
+ besteht jedoch nicht, soweit diese Mitteilung unmöglich oder mit einem unverhältnismäßigen Aufwand verbunden ist.
+ Unbeschadet dessen hat der Nutzer ein Recht auf Auskunft über diese Empfänger.
- Ebenfalls haben die Nutzer und Betroffenen nach Art. 21 DSGVO das Recht auf
- Widerspruch gegen die künftige Verarbeitung der sie betreffenden Daten,
- sofern die Daten durch den Anbieter nach Maßgabe von Art. 6 Abs. 1 lit. f)
- DSGVO verarbeitet werden. Insbesondere ist ein Widerspruch gegen die
- Datenverarbeitung zum Zwecke der Direktwerbung statthaft.
+ Ebenfalls haben die Nutzer und Betroffenen nach Art. 21 DSGVO das Recht auf Widerspruch gegen die künftige
+ Verarbeitung der sie betreffenden Daten, sofern die Daten durch den Anbieter nach Maßgabe von Art. 6 Abs. 1 lit.
+ f) DSGVO verarbeitet werden. Insbesondere ist ein Widerspruch gegen die Datenverarbeitung zum Zwecke der
+ Direktwerbung statthaft.
III. Informationen zur Datenverarbeitung
- Ihre bei Nutzung unseres Internetauftritts verarbeiteten Daten werden gelöscht
- oder gesperrt, sobald der Zweck der Speicherung entfällt, der Löschung der
- Daten keine gesetzlichen Aufbewahrungspflichten entgegenstehen und nachfolgend
- keine anderslautenden Angaben zu einzelnen Verarbeitungsverfahren gemacht
- werden.
+ Ihre bei Nutzung unseres Internetauftritts verarbeiteten Daten werden gelöscht oder gesperrt, sobald der Zweck der
+ Speicherung entfällt, der Löschung der Daten keine gesetzlichen Aufbewahrungspflichten entgegenstehen und
+ nachfolgend keine anderslautenden Angaben zu einzelnen Verarbeitungsverfahren gemacht werden.
Serverdaten
- Aus technischen Gründen, insbesondere zur Gewährleistung eines sicheren und
- stabilen Internetauftritts, werden Daten durch Ihren Internet-Browser an uns
- bzw. an unseren Webspace-Provider übermittelt. Mit diesen sog. Server-Logfiles
- werden u.a. Typ und Version Ihres Internetbrowsers, das Betriebssystem, die
- Website, von der aus Sie auf unseren Internetauftritt gewechselt haben
- (Referrer URL), die Website(s) unseres Internetauftritts, die Sie besuchen,
- Datum und Uhrzeit des jeweiligen Zugriffs sowie die IP-Adresse des
- Internetanschlusses, von dem aus die Nutzung unseres Internetauftritts
- erfolgt, erhoben.
+ Aus technischen Gründen, insbesondere zur Gewährleistung eines sicheren und stabilen Internetauftritts, werden
+ Daten durch Ihren Internet-Browser an uns bzw. an unseren Webspace-Provider übermittelt. Mit diesen sog.
+ Server-Logfiles werden u.a. Typ und Version Ihres Internetbrowsers, das Betriebssystem, die Website, von der aus
+ Sie auf unseren Internetauftritt gewechselt haben (Referrer URL), die Website(s) unseres Internetauftritts, die
+ Sie besuchen, Datum und Uhrzeit des jeweiligen Zugriffs sowie die IP-Adresse des Internetanschlusses, von dem aus
+ die Nutzung unseres Internetauftritts erfolgt, erhoben.
- Diese so erhobenen Daten werden vorrübergehend gespeichert, dies jedoch nicht
- gemeinsam mit anderen Daten von Ihnen.
+ Diese so erhobenen Daten werden vorrübergehend gespeichert, dies jedoch nicht gemeinsam mit anderen Daten von
+ Ihnen.
- Diese Speicherung erfolgt auf der Rechtsgrundlage von Art. 6 Abs. 1 lit. f)
- DSGVO. Unser berechtigtes Interesse liegt in der Verbesserung, Stabilität,
- Funktionalität und Sicherheit unseres Internetauftritts.
+ Diese Speicherung erfolgt auf der Rechtsgrundlage von Art. 6 Abs. 1 lit. f) DSGVO. Unser berechtigtes Interesse
+ liegt in der Verbesserung, Stabilität, Funktionalität und Sicherheit unseres Internetauftritts.
- Die Daten werden spätestens nach sieben Tage wieder gelöscht, soweit keine
- weitere Aufbewahrung zu Beweiszwecken erforderlich ist. Andernfalls sind die
- Daten bis zur endgültigen Klärung eines Vorfalls ganz oder teilweise von der
- Löschung ausgenommen.
+ Die Daten werden spätestens nach sieben Tage wieder gelöscht, soweit keine weitere Aufbewahrung zu Beweiszwecken
+ erforderlich ist. Andernfalls sind die Daten bis zur endgültigen Klärung eines Vorfalls ganz oder teilweise von
+ der Löschung ausgenommen.
Cookies
a) Sitzungs-Cookies/Session-Cookies
- Wir verwenden mit unserem Internetauftritt sog. Cookies. Cookies sind kleine
- Textdateien oder andere Speichertechnologien, die durch den von Ihnen
- eingesetzten Internet-Browser auf Ihrem Endgerät ablegt und gespeichert
- werden. Durch diese Cookies werden im individuellen Umfang bestimmte
- Informationen von Ihnen, wie beispielsweise Ihre Browser- oder Standortdaten
- oder Ihre IP-Adresse, verarbeitet.
+ Wir verwenden mit unserem Internetauftritt sog. Cookies. Cookies sind kleine Textdateien oder andere
+ Speichertechnologien, die durch den von Ihnen eingesetzten Internet-Browser auf Ihrem Endgerät ablegt und
+ gespeichert werden. Durch diese Cookies werden im individuellen Umfang bestimmte Informationen von Ihnen, wie
+ beispielsweise Ihre Browser- oder Standortdaten oder Ihre IP-Adresse, verarbeitet.
- Durch diese Verarbeitung wird unser Internetauftritt benutzerfreundlicher,
- effektiver und sicherer, da die Verarbeitung bspw. die Wiedergabe unseres
- Internetauftritts in unterschiedlichen Sprachen oder das Angebot einer
+ Durch diese Verarbeitung wird unser Internetauftritt benutzerfreundlicher, effektiver und sicherer, da die
+ Verarbeitung bspw. die Wiedergabe unseres Internetauftritts in unterschiedlichen Sprachen oder das Angebot einer
Warenkorbfunktion ermöglicht.
- Rechtsgrundlage dieser Verarbeitung ist Art. 6 Abs. 1 lit b.) DSGVO, sofern
- diese Cookies Daten zur Vertragsanbahnung oder Vertragsabwicklung verarbeitet
- werden.
+ Rechtsgrundlage dieser Verarbeitung ist Art. 6 Abs. 1 lit b.) DSGVO, sofern diese Cookies Daten zur
+ Vertragsanbahnung oder Vertragsabwicklung verarbeitet werden.
- Falls die Verarbeitung nicht der Vertragsanbahnung oder Vertragsabwicklung
- dient, liegt unser berechtigtes Interesse in der Verbesserung der
- Funktionalität unseres Internetauftritts. Rechtsgrundlage ist in dann Art. 6
+ Falls die Verarbeitung nicht der Vertragsanbahnung oder Vertragsabwicklung dient, liegt unser berechtigtes
+ Interesse in der Verbesserung der Funktionalität unseres Internetauftritts. Rechtsgrundlage ist in dann Art. 6
Abs. 1 lit. f) DSGVO.
-
- Mit Schließen Ihres Internet-Browsers werden diese Session-Cookies gelöscht.
-
+ Mit Schließen Ihres Internet-Browsers werden diese Session-Cookies gelöscht.
b) Drittanbieter-Cookies
- Gegebenenfalls werden mit unserem Internetauftritt auch Cookies von
- Partnerunternehmen, mit denen wir zum Zwecke der Werbung, der Analyse oder der
- Funktionalitäten unseres Internetauftritts zusammenarbeiten, verwendet.
+ Gegebenenfalls werden mit unserem Internetauftritt auch Cookies von Partnerunternehmen, mit denen wir zum Zwecke
+ der Werbung, der Analyse oder der Funktionalitäten unseres Internetauftritts zusammenarbeiten, verwendet.
- Die Einzelheiten hierzu, insbesondere zu den Zwecken und den Rechtsgrundlagen
- der Verarbeitung solcher Drittanbieter-Cookies, entnehmen Sie bitte den
- nachfolgenden Informationen.
+ Die Einzelheiten hierzu, insbesondere zu den Zwecken und den Rechtsgrundlagen der Verarbeitung solcher
+ Drittanbieter-Cookies, entnehmen Sie bitte den nachfolgenden Informationen.
c) Beseitigungsmöglichkeit
- Sie können die Installation der Cookies durch eine Einstellung Ihres
- Internet-Browsers verhindern oder einschränken. Ebenfalls können Sie bereits
- gespeicherte Cookies jederzeit löschen. Die hierfür erforderlichen Schritte
- und Maßnahmen hängen jedoch von Ihrem konkret genutzten Internet-Browser ab.
- Bei Fragen benutzen Sie daher bitte die Hilfefunktion oder Dokumentation Ihres
- Internet-Browsers oder wenden sich an dessen Hersteller bzw. Support. Bei sog.
- Flash-Cookies kann die Verarbeitung allerdings nicht über die Einstellungen
- des Browsers unterbunden werden. Stattdessen müssen Sie insoweit die
- Einstellung Ihres Flash-Players ändern. Auch die hierfür erforderlichen
- Schritte und Maßnahmen hängen von Ihrem konkret genutzten Flash-Player ab. Bei
- Fragen benutzen Sie daher bitte ebenso die Hilfefunktion oder Dokumentation
- Ihres Flash-Players oder wenden sich an den Hersteller bzw. Benutzer-Support.
+ Sie können die Installation der Cookies durch eine Einstellung Ihres Internet-Browsers verhindern oder
+ einschränken. Ebenfalls können Sie bereits gespeicherte Cookies jederzeit löschen. Die hierfür erforderlichen
+ Schritte und Maßnahmen hängen jedoch von Ihrem konkret genutzten Internet-Browser ab. Bei Fragen benutzen Sie
+ daher bitte die Hilfefunktion oder Dokumentation Ihres Internet-Browsers oder wenden sich an dessen Hersteller
+ bzw. Support. Bei sog. Flash-Cookies kann die Verarbeitung allerdings nicht über die Einstellungen des Browsers
+ unterbunden werden. Stattdessen müssen Sie insoweit die Einstellung Ihres Flash-Players ändern. Auch die hierfür
+ erforderlichen Schritte und Maßnahmen hängen von Ihrem konkret genutzten Flash-Player ab. Bei Fragen benutzen Sie
+ daher bitte ebenso die Hilfefunktion oder Dokumentation Ihres Flash-Players oder wenden sich an den Hersteller
+ bzw. Benutzer-Support.
- Sollten Sie die Installation der Cookies verhindern oder einschränken, kann
- dies allerdings dazu führen, dass nicht sämtliche Funktionen unseres
- Internetauftritts vollumfänglich nutzbar sind.
+ Sollten Sie die Installation der Cookies verhindern oder einschränken, kann dies allerdings dazu führen, dass
+ nicht sämtliche Funktionen unseres Internetauftritts vollumfänglich nutzbar sind.
Google Analytics
- In unserem Internetauftritt setzen wir Google Analytics ein. Hierbei handelt
- es sich um einen Webanalysedienst der Google LLC, 1600 Amphitheatre Parkway,
- Mountain View, CA 94043 USA, nachfolgend nur „Google“ genannt.
-
-
- Durch die Zertifizierung nach dem EU-US-Datenschutzschild („EU-US Privacy
- Shield“)
+ In unserem Internetauftritt setzen wir Google Analytics ein. Hierbei handelt es sich um einen Webanalysedienst der
+ Google LLC, 1600 Amphitheatre Parkway, Mountain View, CA 94043 USA, nachfolgend nur „Google“ genannt.
+ Durch die Zertifizierung nach dem EU-US-Datenschutzschild („EU-US Privacy Shield“)
https://www.privacyshield.gov/participant?id=a2zt000000001L5AAI&status=Active
- garantiert Google, dass die Datenschutzvorgaben der EU auch bei der
- Verarbeitung von Daten in den USA eingehalten werden.
+ garantiert Google, dass die Datenschutzvorgaben der EU auch bei der Verarbeitung von Daten in den USA eingehalten
+ werden.
- Der Dienst Google Analytics dient zur Analyse des Nutzungsverhaltens unseres
- Internetauftritts. Rechtsgrundlage ist Art. 6 Abs. 1 lit. f) DSGVO. Unser
- berechtigtes Interesse liegt in der Analyse, Optimierung und dem
+ Der Dienst Google Analytics dient zur Analyse des Nutzungsverhaltens unseres Internetauftritts. Rechtsgrundlage
+ ist Art. 6 Abs. 1 lit. f) DSGVO. Unser berechtigtes Interesse liegt in der Analyse, Optimierung und dem
wirtschaftlichen Betrieb unseres Internetauftritts.
- Nutzungs- und nutzerbezogene Informationen, wie bspw. IP-Adresse, Ort, Zeit
- oder Häufigkeit des Besuchs unseres Internetauftritts, werden dabei an einen
- Server von Google in den USA übertragen und dort gespeichert. Allerdings
- nutzen wir Google Analytics mit der sog. Anonymisierungsfunktion. Durch diese
- Funktion kürzt Google die IP-Adresse schon innerhalb der EU bzw. des EWR.
-
-
- Die so erhobenen Daten werden wiederum von Google genutzt, um uns eine
- Auswertung über den Besuch unseres Internetauftritts sowie über die dortigen
- Nutzungsaktivitäten zur Verfügung zu stellen. Auch können diese Daten genutzt
- werden, um weitere Dienstleistungen zu erbringen, die mit der Nutzung unseres
- Internetauftritts und der Nutzung des Internets zusammenhängen.
+ Nutzungs- und nutzerbezogene Informationen, wie bspw. IP-Adresse, Ort, Zeit oder Häufigkeit des Besuchs unseres
+ Internetauftritts, werden dabei an einen Server von Google in den USA übertragen und dort gespeichert. Allerdings
+ nutzen wir Google Analytics mit der sog. Anonymisierungsfunktion. Durch diese Funktion kürzt Google die IP-Adresse
+ schon innerhalb der EU bzw. des EWR.
- Google gibt an, Ihre IP-Adresse nicht mit anderen Daten zu verbinden. Zudem
- hält Google unter
+ Die so erhobenen Daten werden wiederum von Google genutzt, um uns eine Auswertung über den Besuch unseres
+ Internetauftritts sowie über die dortigen Nutzungsaktivitäten zur Verfügung zu stellen. Auch können diese Daten
+ genutzt werden, um weitere Dienstleistungen zu erbringen, die mit der Nutzung unseres Internetauftritts und der
+ Nutzung des Internets zusammenhängen.
+ Google gibt an, Ihre IP-Adresse nicht mit anderen Daten zu verbinden. Zudem hält Google unter
https://www.google.com/intl/de/policies/privacy/partners
- weitere datenschutzrechtliche Informationen für Sie bereit, so bspw. auch zu
- den Möglichkeiten, die Datennutzung zu unterbinden.
+ weitere datenschutzrechtliche Informationen für Sie bereit, so bspw. auch zu den Möglichkeiten, die Datennutzung
+ zu unterbinden.
Zudem bietet Google unter
@@ -527,15 +452,12 @@ const Index = () => (
- ein sog. Deaktivierungs-Add-on nebst weiteren Informationen hierzu an. Dieses
- Add-on lässt sich mit den gängigen Internet-Browsern installieren und bietet
- Ihnen weitergehende Kontrollmöglichkeit über die Daten, die Google bei Aufruf
- unseres Internetauftritts erfasst. Dabei teilt das Add-on dem JavaScript
- (ga.js) von Google Analytics mit, dass Informationen zum Besuch unseres
- Internetauftritts nicht an Google Analytics übermittelt werden sollen. Dies
- verhindert aber nicht, dass Informationen an uns oder an andere
- Webanalysedienste übermittelt werden. Ob und welche weiteren Webanalysedienste
- von uns eingesetzt werden, erfahren Sie natürlich ebenfalls in dieser
+ ein sog. Deaktivierungs-Add-on nebst weiteren Informationen hierzu an. Dieses Add-on lässt sich mit den gängigen
+ Internet-Browsern installieren und bietet Ihnen weitergehende Kontrollmöglichkeit über die Daten, die Google bei
+ Aufruf unseres Internetauftritts erfasst. Dabei teilt das Add-on dem JavaScript (ga.js) von Google Analytics mit,
+ dass Informationen zum Besuch unseres Internetauftritts nicht an Google Analytics übermittelt werden sollen. Dies
+ verhindert aber nicht, dass Informationen an uns oder an andere Webanalysedienste übermittelt werden. Ob und
+ welche weiteren Webanalysedienste von uns eingesetzt werden, erfahren Sie natürlich ebenfalls in dieser
Datenschutzerklärung.
@@ -544,7 +466,7 @@ const Index = () => (
Muster-Datenschutzerklärung
- {' der '}
+ {" der "}
Anwaltskanzlei Weiß & Partner
diff --git a/pages/profile.tsx b/pages/profile.tsx
index 5a29f05..4be7791 100644
--- a/pages/profile.tsx
+++ b/pages/profile.tsx
@@ -1,16 +1,14 @@
-import React from 'react';
-import { connect } from 'react-redux';
-import { bindActionCreators } from 'redux';
-import { fetchSessionIfNeeded } from '../components/session/actions/sessionActions';
-import { receivedSession } from '../components/session/actions/sessionActionCreators';
-import { getSession } from '../lib/session';
-import BackButton from '../components/ui/BackButton';
-import ProfileAutoScrobbles from '../components/profile/ProfileAutoScrobbles';
-import ProfileHistory from '../components/profile/ProfileHistory';
-import { wrapper } from '../client/reduxStore';
-import {
- H1, H2, Header, ProfileImg, Wrapper,
-} from '../styles/profile.styles';
+import React from "react";
+import { connect } from "react-redux";
+import { bindActionCreators } from "redux";
+import { fetchSessionIfNeeded } from "../components/session/actions/sessionActions";
+import { receivedSession } from "../components/session/actions/sessionActionCreators";
+import { getSession } from "../lib/session";
+import BackButton from "../components/ui/BackButton";
+import ProfileAutoScrobbles from "../components/profile/ProfileAutoScrobbles";
+import ProfileHistory from "../components/profile/ProfileHistory";
+import { wrapper } from "../client/reduxStore";
+import { H1, H2, Header, ProfileImg, Wrapper } from "../styles/profile.styles";
interface ProfileProps {
session?: any;
@@ -43,9 +41,7 @@ const mapStateToProps = state => ({
session: state.session.data,
});
-const mapDispatchToProps = dispatch => (
- bindActionCreators({ fetchSessionIfNeeded }, dispatch)
-);
+const mapDispatchToProps = dispatch => bindActionCreators({ fetchSessionIfNeeded }, dispatch);
export const getServerSideProps = wrapper.getServerSideProps(store => async ({ req, res }) => {
const session = await getSession(req, res);
@@ -55,7 +51,4 @@ export const getServerSideProps = wrapper.getServerSideProps(store => async ({ r
return { props: {} };
});
-export default connect(
- mapStateToProps,
- mapDispatchToProps,
-)(Profile);
+export default connect(mapStateToProps, mapDispatchToProps)(Profile);
diff --git a/pages/scrobbled/[barcode].tsx b/pages/scrobbled/[barcode].tsx
index 1396cf7..d83950b 100644
--- a/pages/scrobbled/[barcode].tsx
+++ b/pages/scrobbled/[barcode].tsx
@@ -1,16 +1,16 @@
-import { bindActionCreators } from 'redux';
-import { connect } from 'react-redux';
-import React from 'react';
-import Router from 'next/router';
-import { FaCheckCircle } from 'react-icons/fa';
-import { IoMdQrScanner } from 'react-icons/io';
-import { fetchReleaseIfNeeded } from '../../components/release/actions/releaseActions';
-import CircleLayout from '../../components/layout/CircleLayout';
-import { RetryButton } from '../../components/layout/styles/Error.styles';
-import { trackEvent } from '../../lib/analytics';
-import { yellow } from '../../lib/colors';
-import { FlexContent } from '../../styles/layout.styles';
-import { CoverBackground } from '../../styles/scrobbled.styles';
+import { bindActionCreators } from "redux";
+import { connect } from "react-redux";
+import React from "react";
+import Router from "next/router";
+import { FaCheckCircle } from "react-icons/fa";
+import { IoMdQrScanner } from "react-icons/io";
+import { fetchReleaseIfNeeded } from "../../components/release/actions/releaseActions";
+import CircleLayout from "../../components/layout/CircleLayout";
+import { RetryButton } from "../../components/layout/styles/Error.styles";
+import { trackEvent } from "../../lib/analytics";
+import { yellow } from "../../lib/colors";
+import { FlexContent } from "../../styles/layout.styles";
+import { CoverBackground } from "../../styles/scrobbled.styles";
interface ScrobbledProps {
barcode: string;
@@ -24,9 +24,9 @@ class Scrobbled extends React.Component {
}
onRetry = () => {
- trackEvent('Scrobbled', 'Rescan');
- Router.push('/');
- }
+ trackEvent("Scrobbled", "Rescan");
+ Router.push("/");
+ };
render() {
const { data = {} } = this.props;
@@ -53,11 +53,6 @@ const mapStateToProps = (state, { barcode }) => ({
...state.release[barcode],
});
-const mapDispatchToProps = dispatch => (
- bindActionCreators({ fetchReleaseIfNeeded }, dispatch)
-);
+const mapDispatchToProps = dispatch => bindActionCreators({ fetchReleaseIfNeeded }, dispatch);
-export default connect(
- mapStateToProps,
- mapDispatchToProps,
-)(Scrobbled);
+export default connect(mapStateToProps, mapDispatchToProps)(Scrobbled);
diff --git a/stylelint.config.js b/stylelint.config.js
index 2c4f534..0c74b0c 100644
--- a/stylelint.config.js
+++ b/stylelint.config.js
@@ -1,5 +1,3 @@
module.exports = {
- extends: [
- 'stylelint-config-recommended',
- ],
+ extends: ["stylelint-config-recommended"],
};
diff --git a/styles/layout.styles.ts b/styles/layout.styles.ts
index 648f376..c8e732e 100644
--- a/styles/layout.styles.ts
+++ b/styles/layout.styles.ts
@@ -1,13 +1,13 @@
-import styled from 'styled-components';
-import LogoSmall from '../components/assets/LogoSmall';
-import { grey } from '../lib/colors';
+import styled from "styled-components";
+import LogoSmall from "../components/assets/LogoSmall";
+import { grey } from "../lib/colors";
export const Center = styled.div<{ useMinHeight?: boolean }>`
display: flex;
align-items: center;
justify-content: center;
width: 100%;
- ${props => (props.useMinHeight ? 'min-height: 100%' : 'height: 100%')};
+ ${props => (props.useMinHeight ? "min-height: 100%" : "height: 100%")};
padding: 15px 0;
`;
diff --git a/styles/legal.styles.ts b/styles/legal.styles.ts
index 4c02db9..7d95d35 100644
--- a/styles/legal.styles.ts
+++ b/styles/legal.styles.ts
@@ -1,4 +1,4 @@
-import styled from 'styled-components';
+import styled from "styled-components";
export const Wrapper = styled.div`
width: 100%;
@@ -8,7 +8,8 @@ export const Wrapper = styled.div`
line-height: 1.4;
word-wrap: break-word;
- h2, h3 {
+ h2,
+ h3 {
margin: 1.5em 0 0.5em;
}
diff --git a/styles/login.styles.ts b/styles/login.styles.ts
index 594cba5..090342a 100644
--- a/styles/login.styles.ts
+++ b/styles/login.styles.ts
@@ -1,5 +1,5 @@
-import styled from 'styled-components';
-import LogoModule from '../components/assets/Logo';
+import styled from "styled-components";
+import LogoModule from "../components/assets/Logo";
export const Wrapper = styled.div`
display: flex;
diff --git a/styles/mixins.ts b/styles/mixins.ts
index 06e26eb..d95b8bb 100644
--- a/styles/mixins.ts
+++ b/styles/mixins.ts
@@ -1,4 +1,4 @@
-import { css } from 'styled-components';
+import { css } from "styled-components";
// eslint-disable-next-line import/prefer-default-export
export const buttonReset = css`
diff --git a/styles/nprogress.styles.ts b/styles/nprogress.styles.ts
index 3a7e5d4..40ebeb0 100644
--- a/styles/nprogress.styles.ts
+++ b/styles/nprogress.styles.ts
@@ -1,5 +1,5 @@
-import { createGlobalStyle, keyframes } from 'styled-components';
-import { yellow } from '../lib/colors';
+import { createGlobalStyle, keyframes } from "styled-components";
+import { yellow } from "../lib/colors";
const spinnerAnimation = keyframes`
0% {
diff --git a/styles/profile.styles.ts b/styles/profile.styles.ts
index ce48a72..a631581 100644
--- a/styles/profile.styles.ts
+++ b/styles/profile.styles.ts
@@ -1,7 +1,7 @@
-import TimeAgo from 'react-timeago';
-import styled, { css } from 'styled-components';
-import { grey, silver } from '../lib/colors';
-import { liReset, ulReset, buttonReset } from './mixins';
+import TimeAgo from "react-timeago";
+import styled, { css } from "styled-components";
+import { grey, silver } from "../lib/colors";
+import { liReset, ulReset, buttonReset } from "./mixins";
export const Wrapper = styled.div`
width: 100%;
@@ -58,11 +58,13 @@ export const ListItem = styled.li`
export const ListCaption = styled.span<{ disabled?: boolean }>`
flex-grow: 1;
padding: 10px 0;
- transition: opacity .3s;
+ transition: opacity 0.3s;
text-decoration: none;
- ${props => props.disabled && css`
- opacity: .3;
- `}
+ ${props =>
+ props.disabled &&
+ css`
+ opacity: 0.3;
+ `}
`;
export const DeleteButton = styled.button<{ disabled?: boolean }>`
@@ -70,15 +72,17 @@ export const DeleteButton = styled.button<{ disabled?: boolean }>`
position: relative;
right: -20px;
padding: 15px;
- transition: opacity .3s;
- ${props => props.disabled && css`
- opacity: .3;
- `}
+ transition: opacity 0.3s;
+ ${props =>
+ props.disabled &&
+ css`
+ opacity: 0.3;
+ `}
`;
export const Fallback = styled.div`
padding: 10px 40px;
- opacity: .5;
+ opacity: 0.5;
color: ${silver};
font-style: italic;
text-align: center;
@@ -90,7 +94,7 @@ export const Meta = styled.div`
export const Time = styled(TimeAgo)`
display: inline-block;
- opacity: .5;
+ opacity: 0.5;
font-size: 12px;
white-space: nowrap;
`;
diff --git a/styles/scrobbled.styles.ts b/styles/scrobbled.styles.ts
index 48c4bcf..6ad9760 100644
--- a/styles/scrobbled.styles.ts
+++ b/styles/scrobbled.styles.ts
@@ -1,4 +1,4 @@
-import styled from 'styled-components';
+import styled from "styled-components";
// eslint-disable-next-line import/prefer-default-export
export const CoverBackground = styled.div<{ image?: string }>`
@@ -6,7 +6,7 @@ export const CoverBackground = styled.div<{ image?: string }>`
z-index: -1;
width: 100%;
height: 100%;
- opacity: .5;
+ opacity: 0.5;
background-size: cover;
filter: blur(20px);
${props => props.image && `background-image: url('${props.image}');`}
diff --git a/tsconfig.json b/tsconfig.json
index eaecc70..ee67138 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -1,11 +1,7 @@
{
"compilerOptions": {
"target": "ES2020",
- "lib": [
- "dom",
- "dom.iterable",
- "esnext"
- ],
+ "lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"skipLibCheck": true,
"strict": false,
@@ -23,24 +19,10 @@
}
],
"paths": {
- "@/*": [
- "./*"
- ]
+ "@/*": ["./*"]
},
"strictNullChecks": false
},
- "include": [
- "next-env.d.ts",
- "types/**/*.d.ts",
- "**/*.ts",
- "**/*.tsx",
- ".next/types/**/*.ts"
- ],
- "exclude": [
- "node_modules",
- "**/*.spec.ts",
- "**/*.spec.tsx",
- "**/*.test.ts",
- "**/*.test.tsx"
- ]
+ "include": ["next-env.d.ts", "types/**/*.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
+ "exclude": ["node_modules", "**/*.spec.ts", "**/*.spec.tsx", "**/*.test.ts", "**/*.test.tsx"]
}
diff --git a/types/styled-components.d.ts b/types/styled-components.d.ts
index 5bd152a..3f73999 100644
--- a/types/styled-components.d.ts
+++ b/types/styled-components.d.ts
@@ -1,6 +1,7 @@
-import type { CSSProp } from 'styled-components';
+import type { CSSProp } from "styled-components";
-declare module 'react' {
+declare module "react" {
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
interface DOMAttributes {
css?: CSSProp;
}
diff --git a/yarn.lock b/yarn.lock
index c7042b8..644eab3 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -55,20 +55,6 @@ __metadata:
languageName: node
linkType: hard
-"@babel/eslint-parser@npm:^7.25.9":
- version: 7.28.6
- resolution: "@babel/eslint-parser@npm:7.28.6"
- dependencies:
- "@nicolo-ribaudo/eslint-scope-5-internals": "npm:5.1.1-v1"
- eslint-visitor-keys: "npm:^2.1.0"
- semver: "npm:^6.3.1"
- peerDependencies:
- "@babel/core": ^7.11.0
- eslint: ^7.5.0 || ^8.0.0 || ^9.0.0
- checksum: 10c0/58a85f67a056ba8389978c4654b690b890a6dcd19aa9655c5d7d9349a0c25f124cabad8a190b6bf7045a063aeee1b8e2ab23cfe4d8fa0e0517716a8b70e758bc
- languageName: node
- linkType: hard
-
"@babel/generator@npm:^7.29.0":
version: 7.29.1
resolution: "@babel/generator@npm:7.29.1"
@@ -557,6 +543,34 @@ __metadata:
languageName: node
linkType: hard
+"@emnapi/core@npm:^1.4.3":
+ version: 1.8.1
+ resolution: "@emnapi/core@npm:1.8.1"
+ dependencies:
+ "@emnapi/wasi-threads": "npm:1.1.0"
+ tslib: "npm:^2.4.0"
+ checksum: 10c0/2c242f4b49779bac403e1cbcc98edacdb1c8ad36562408ba9a20663824669e930bc8493be46a2522d9dc946b8d96cd7073970bae914928c7671b5221c85b432e
+ languageName: node
+ linkType: hard
+
+"@emnapi/runtime@npm:^1.4.3":
+ version: 1.8.1
+ resolution: "@emnapi/runtime@npm:1.8.1"
+ dependencies:
+ tslib: "npm:^2.4.0"
+ checksum: 10c0/f4929d75e37aafb24da77d2f58816761fe3f826aad2e37fa6d4421dac9060cbd5098eea1ac3c9ecc4526b89deb58153852fa432f87021dc57863f2ff726d713f
+ languageName: node
+ linkType: hard
+
+"@emnapi/wasi-threads@npm:1.1.0":
+ version: 1.1.0
+ resolution: "@emnapi/wasi-threads@npm:1.1.0"
+ dependencies:
+ tslib: "npm:^2.4.0"
+ checksum: 10c0/e6d54bf2b1e64cdd83d2916411e44e579b6ae35d5def0dea61a3c452d9921373044dff32a8b8473ae60c80692bdc39323e98b96a3f3d87ba6886b24dd0ef7ca1
+ languageName: node
+ linkType: hard
+
"@emotion/is-prop-valid@npm:1.4.0":
version: 1.4.0
resolution: "@emotion/is-prop-valid@npm:1.4.0"
@@ -580,7 +594,7 @@ __metadata:
languageName: node
linkType: hard
-"@eslint-community/eslint-utils@npm:^4.8.0, @eslint-community/eslint-utils@npm:^4.9.1":
+"@eslint-community/eslint-utils@npm:^4.2.0, @eslint-community/eslint-utils@npm:^4.9.1":
version: 4.9.1
resolution: "@eslint-community/eslint-utils@npm:4.9.1"
dependencies:
@@ -591,43 +605,31 @@ __metadata:
languageName: node
linkType: hard
-"@eslint-community/regexpp@npm:^4.12.1":
+"@eslint-community/regexpp@npm:^4.12.2, @eslint-community/regexpp@npm:^4.6.1":
version: 4.12.2
resolution: "@eslint-community/regexpp@npm:4.12.2"
checksum: 10c0/fddcbc66851b308478d04e302a4d771d6917a0b3740dc351513c0da9ca2eab8a1adf99f5e0aa7ab8b13fa0df005c81adeee7e63a92f3effd7d367a163b721c2d
languageName: node
linkType: hard
-"@eslint/config-array@npm:^0.21.1":
- version: 0.21.1
- resolution: "@eslint/config-array@npm:0.21.1"
+"@eslint/eslintrc@npm:^2.1.4":
+ version: 2.1.4
+ resolution: "@eslint/eslintrc@npm:2.1.4"
dependencies:
- "@eslint/object-schema": "npm:^2.1.7"
- debug: "npm:^4.3.1"
+ ajv: "npm:^6.12.4"
+ debug: "npm:^4.3.2"
+ espree: "npm:^9.6.0"
+ globals: "npm:^13.19.0"
+ ignore: "npm:^5.2.0"
+ import-fresh: "npm:^3.2.1"
+ js-yaml: "npm:^4.1.0"
minimatch: "npm:^3.1.2"
- checksum: 10c0/2f657d4edd6ddcb920579b72e7a5b127865d4c3fb4dda24f11d5c4f445a93ca481aebdbd6bf3291c536f5d034458dbcbb298ee3b698bc6c9dd02900fe87eec3c
- languageName: node
- linkType: hard
-
-"@eslint/config-helpers@npm:^0.4.2":
- version: 0.4.2
- resolution: "@eslint/config-helpers@npm:0.4.2"
- dependencies:
- "@eslint/core": "npm:^0.17.0"
- checksum: 10c0/92efd7a527b2d17eb1a148409d71d80f9ac160b565ac73ee092252e8bf08ecd08670699f46b306b94f13d22e88ac88a612120e7847570dd7cdc72f234d50dcb4
- languageName: node
- linkType: hard
-
-"@eslint/core@npm:^0.17.0":
- version: 0.17.0
- resolution: "@eslint/core@npm:0.17.0"
- dependencies:
- "@types/json-schema": "npm:^7.0.15"
- checksum: 10c0/9a580f2246633bc752298e7440dd942ec421860d1946d0801f0423830e67887e4aeba10ab9a23d281727a978eb93d053d1922a587d502942a713607f40ed704e
+ strip-json-comments: "npm:^3.1.1"
+ checksum: 10c0/32f67052b81768ae876c84569ffd562491ec5a5091b0c1e1ca1e0f3c24fb42f804952fdd0a137873bc64303ba368a71ba079a6f691cee25beee9722d94cc8573
languageName: node
linkType: hard
-"@eslint/eslintrc@npm:^3.2.0, @eslint/eslintrc@npm:^3.3.1":
+"@eslint/eslintrc@npm:^3.2.0":
version: 3.3.3
resolution: "@eslint/eslintrc@npm:3.3.3"
dependencies:
@@ -644,44 +646,28 @@ __metadata:
languageName: node
linkType: hard
-"@eslint/js@npm:9.39.2, @eslint/js@npm:^9.18.0":
- version: 9.39.2
- resolution: "@eslint/js@npm:9.39.2"
- checksum: 10c0/00f51c52b04ac79faebfaa65a9652b2093b9c924e945479f1f3945473f78aee83cbc76c8d70bbffbf06f7024626575b16d97b66eab16182e1d0d39daff2f26f5
+"@eslint/js@npm:8.57.1":
+ version: 8.57.1
+ resolution: "@eslint/js@npm:8.57.1"
+ checksum: 10c0/b489c474a3b5b54381c62e82b3f7f65f4b8a5eaaed126546520bf2fede5532a8ed53212919fed1e9048dcf7f37167c8561d58d0ba4492a4244004e7793805223
languageName: node
linkType: hard
-"@eslint/object-schema@npm:^2.1.7":
- version: 2.1.7
- resolution: "@eslint/object-schema@npm:2.1.7"
- checksum: 10c0/936b6e499853d1335803f556d526c86f5fe2259ed241bc665000e1d6353828edd913feed43120d150adb75570cae162cf000b5b0dfc9596726761c36b82f4e87
- languageName: node
- linkType: hard
-
-"@eslint/plugin-kit@npm:^0.4.1":
- version: 0.4.1
- resolution: "@eslint/plugin-kit@npm:0.4.1"
- dependencies:
- "@eslint/core": "npm:^0.17.0"
- levn: "npm:^0.4.1"
- checksum: 10c0/51600f78b798f172a9915dffb295e2ffb44840d583427bc732baf12ecb963eb841b253300e657da91d890f4b323d10a1bd12934bf293e3018d8bb66fdce5217b
- languageName: node
- linkType: hard
-
-"@humanfs/core@npm:^0.19.1":
- version: 0.19.1
- resolution: "@humanfs/core@npm:0.19.1"
- checksum: 10c0/aa4e0152171c07879b458d0e8a704b8c3a89a8c0541726c6b65b81e84fd8b7564b5d6c633feadc6598307d34564bd53294b533491424e8e313d7ab6c7bc5dc67
+"@eslint/js@npm:^9.18.0":
+ version: 9.39.2
+ resolution: "@eslint/js@npm:9.39.2"
+ checksum: 10c0/00f51c52b04ac79faebfaa65a9652b2093b9c924e945479f1f3945473f78aee83cbc76c8d70bbffbf06f7024626575b16d97b66eab16182e1d0d39daff2f26f5
languageName: node
linkType: hard
-"@humanfs/node@npm:^0.16.6":
- version: 0.16.7
- resolution: "@humanfs/node@npm:0.16.7"
+"@humanwhocodes/config-array@npm:^0.13.0":
+ version: 0.13.0
+ resolution: "@humanwhocodes/config-array@npm:0.13.0"
dependencies:
- "@humanfs/core": "npm:^0.19.1"
- "@humanwhocodes/retry": "npm:^0.4.0"
- checksum: 10c0/9f83d3cf2cfa37383e01e3cdaead11cd426208e04c44adcdd291aa983aaf72d7d3598844d2fe9ce54896bb1bf8bd4b56883376611c8905a19c44684642823f30
+ "@humanwhocodes/object-schema": "npm:^2.0.3"
+ debug: "npm:^4.3.1"
+ minimatch: "npm:^3.0.5"
+ checksum: 10c0/205c99e756b759f92e1f44a3dc6292b37db199beacba8f26c2165d4051fe73a4ae52fdcfd08ffa93e7e5cb63da7c88648f0e84e197d154bbbbe137b2e0dd332e
languageName: node
linkType: hard
@@ -692,10 +678,24 @@ __metadata:
languageName: node
linkType: hard
-"@humanwhocodes/retry@npm:^0.4.0, @humanwhocodes/retry@npm:^0.4.2":
- version: 0.4.3
- resolution: "@humanwhocodes/retry@npm:0.4.3"
- checksum: 10c0/3775bb30087d4440b3f7406d5a057777d90e4b9f435af488a4923ef249e93615fb78565a85f173a186a076c7706a81d0d57d563a2624e4de2c5c9c66c486ce42
+"@humanwhocodes/object-schema@npm:^2.0.3":
+ version: 2.0.3
+ resolution: "@humanwhocodes/object-schema@npm:2.0.3"
+ checksum: 10c0/80520eabbfc2d32fe195a93557cef50dfe8c8905de447f022675aaf66abc33ae54098f5ea78548d925aa671cd4ab7c7daa5ad704fe42358c9b5e7db60f80696c
+ languageName: node
+ linkType: hard
+
+"@isaacs/cliui@npm:^8.0.2":
+ version: 8.0.2
+ resolution: "@isaacs/cliui@npm:8.0.2"
+ dependencies:
+ string-width: "npm:^5.1.2"
+ string-width-cjs: "npm:string-width@^4.2.0"
+ strip-ansi: "npm:^7.0.1"
+ strip-ansi-cjs: "npm:strip-ansi@^6.0.1"
+ wrap-ansi: "npm:^8.1.0"
+ wrap-ansi-cjs: "npm:wrap-ansi@^7.0.0"
+ checksum: 10c0/b1bf42535d49f11dc137f18d5e4e63a28c5569de438a221c369483731e9dac9fb797af554e8bf02b6192d1e5eba6e6402cf93900c3d0ac86391d00d04876789e
languageName: node
linkType: hard
@@ -1121,6 +1121,17 @@ __metadata:
languageName: node
linkType: hard
+"@napi-rs/wasm-runtime@npm:^0.2.11":
+ version: 0.2.12
+ resolution: "@napi-rs/wasm-runtime@npm:0.2.12"
+ dependencies:
+ "@emnapi/core": "npm:^1.4.3"
+ "@emnapi/runtime": "npm:^1.4.3"
+ "@tybys/wasm-util": "npm:^0.10.0"
+ checksum: 10c0/6d07922c0613aab30c6a497f4df297ca7c54e5b480e00035e0209b872d5c6aab7162fc49477267556109c2c7ed1eb9c65a174e27e9b87568106a87b0a6e3ca7d
+ languageName: node
+ linkType: hard
+
"@next/bundle-analyzer@npm:^14.2.0":
version: 14.2.35
resolution: "@next/bundle-analyzer@npm:14.2.35"
@@ -1137,6 +1148,15 @@ __metadata:
languageName: node
linkType: hard
+"@next/eslint-plugin-next@npm:14.2.35":
+ version: 14.2.35
+ resolution: "@next/eslint-plugin-next@npm:14.2.35"
+ dependencies:
+ glob: "npm:10.3.10"
+ checksum: 10c0/7dca56c70b43c38e8fd30dc00383400bd5be0c0edf11ef307f615b1f99cb169e51234f6f12d23bf8f54dbcc160868c9922caa2ae2786903cdf0dedef87ab6654
+ languageName: node
+ linkType: hard
+
"@next/swc-darwin-arm64@npm:14.2.33":
version: 14.2.33
resolution: "@next/swc-darwin-arm64@npm:14.2.33"
@@ -1200,15 +1220,6 @@ __metadata:
languageName: node
linkType: hard
-"@nicolo-ribaudo/eslint-scope-5-internals@npm:5.1.1-v1":
- version: 5.1.1-v1
- resolution: "@nicolo-ribaudo/eslint-scope-5-internals@npm:5.1.1-v1"
- dependencies:
- eslint-scope: "npm:5.1.1"
- checksum: 10c0/75dda3e623b8ad7369ca22552d6beee337a814b2d0e8a32d23edd13fcb65c8082b32c5d86e436f3860dd7ade30d91d5db55d4ef9a08fb5a976c718ecc0d88a74
- languageName: node
- linkType: hard
-
"@nodelib/fs.scandir@npm:2.1.5":
version: 2.1.5
resolution: "@nodelib/fs.scandir@npm:2.1.5"
@@ -1226,7 +1237,7 @@ __metadata:
languageName: node
linkType: hard
-"@nodelib/fs.walk@npm:^1.2.3":
+"@nodelib/fs.walk@npm:^1.2.3, @nodelib/fs.walk@npm:^1.2.8":
version: 1.2.8
resolution: "@nodelib/fs.walk@npm:1.2.8"
dependencies:
@@ -1236,6 +1247,13 @@ __metadata:
languageName: node
linkType: hard
+"@nolyfill/is-core-module@npm:1.0.39":
+ version: 1.0.39
+ resolution: "@nolyfill/is-core-module@npm:1.0.39"
+ checksum: 10c0/34ab85fdc2e0250879518841f74a30c276bca4f6c3e13526d2d1fe515e1adf6d46c25fcd5989d22ea056d76f7c39210945180b4859fc83b050e2da411aa86289
+ languageName: node
+ linkType: hard
+
"@npmcli/agent@npm:^4.0.0":
version: 4.0.0
resolution: "@npmcli/agent@npm:4.0.0"
@@ -1319,6 +1337,13 @@ __metadata:
languageName: node
linkType: hard
+"@pkgjs/parseargs@npm:^0.11.0":
+ version: 0.11.0
+ resolution: "@pkgjs/parseargs@npm:0.11.0"
+ checksum: 10c0/5bd7576bb1b38a47a7fc7b51ac9f38748e772beebc56200450c4a817d712232b8f1d3ef70532c80840243c657d491cf6a6be1e3a214cff907645819fdc34aadd
+ languageName: node
+ linkType: hard
+
"@polka/url@npm:^1.0.0-next.24":
version: 1.0.0-next.29
resolution: "@polka/url@npm:1.0.0-next.29"
@@ -1390,6 +1415,13 @@ __metadata:
languageName: node
linkType: hard
+"@rushstack/eslint-patch@npm:^1.3.3":
+ version: 1.16.1
+ resolution: "@rushstack/eslint-patch@npm:1.16.1"
+ checksum: 10c0/4928bac90e52ed15e3a9a2a5bcd89e69b24141773fc3689aa6f1ee8c4d2576c4f0fe0fb1be080b7989cc44dfef7c52cf0a1940f8ded9e78a464cf4bc76e8cab3
+ languageName: node
+ linkType: hard
+
"@sinclair/typebox@npm:^0.27.8":
version: 0.27.10
resolution: "@sinclair/typebox@npm:0.27.10"
@@ -1962,6 +1994,15 @@ __metadata:
languageName: node
linkType: hard
+"@tybys/wasm-util@npm:^0.10.0":
+ version: 0.10.1
+ resolution: "@tybys/wasm-util@npm:0.10.1"
+ dependencies:
+ tslib: "npm:^2.4.0"
+ checksum: 10c0/b255094f293794c6d2289300c5fbcafbb5532a3aed3a5ffd2f8dc1828e639b88d75f6a376dd8f94347a44813fd7a7149d8463477a9a49525c8b2dcaa38c2d1e8
+ languageName: node
+ linkType: hard
+
"@types/aria-query@npm:^5.0.1":
version: 5.0.4
resolution: "@types/aria-query@npm:5.0.4"
@@ -2017,13 +2058,6 @@ __metadata:
languageName: node
linkType: hard
-"@types/estree@npm:^1.0.6":
- version: 1.0.8
- resolution: "@types/estree@npm:1.0.8"
- checksum: 10c0/39d34d1afaa338ab9763f37ad6066e3f349444f9052b9676a7cc0252ef9485a41c6d81c9c4e0d26e9077993354edf25efc853f3224dd4b447175ef62bdcc86a5
- languageName: node
- linkType: hard
-
"@types/graceful-fs@npm:^4.1.3":
version: 4.1.9
resolution: "@types/graceful-fs@npm:4.1.9"
@@ -2086,13 +2120,6 @@ __metadata:
languageName: node
linkType: hard
-"@types/json-schema@npm:^7.0.15":
- version: 7.0.15
- resolution: "@types/json-schema@npm:7.0.15"
- checksum: 10c0/a996a745e6c5d60292f36731dd41341339d4eeed8180bb09226e5c8d23759067692b1d88e5d91d72ee83dfc00d3aca8e7bd43ea120516c17922cbcb7c3e252db
- languageName: node
- linkType: hard
-
"@types/json5@npm:^0.0.29":
version: 0.0.29
resolution: "@types/json5@npm:0.0.29"
@@ -2202,53 +2229,105 @@ __metadata:
languageName: node
linkType: hard
-"@typescript-eslint/project-service@npm:8.55.0":
- version: 8.55.0
- resolution: "@typescript-eslint/project-service@npm:8.55.0"
+"@typescript-eslint/eslint-plugin@npm:^5.4.2 || ^6.0.0 || ^7.0.0 || ^8.0.0":
+ version: 8.56.0
+ resolution: "@typescript-eslint/eslint-plugin@npm:8.56.0"
dependencies:
- "@typescript-eslint/tsconfig-utils": "npm:^8.55.0"
- "@typescript-eslint/types": "npm:^8.55.0"
+ "@eslint-community/regexpp": "npm:^4.12.2"
+ "@typescript-eslint/scope-manager": "npm:8.56.0"
+ "@typescript-eslint/type-utils": "npm:8.56.0"
+ "@typescript-eslint/utils": "npm:8.56.0"
+ "@typescript-eslint/visitor-keys": "npm:8.56.0"
+ ignore: "npm:^7.0.5"
+ natural-compare: "npm:^1.4.0"
+ ts-api-utils: "npm:^2.4.0"
+ peerDependencies:
+ "@typescript-eslint/parser": ^8.56.0
+ eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
+ typescript: ">=4.8.4 <6.0.0"
+ checksum: 10c0/26e56d14562b3d2d34b366859ec56668fdac909d6ea534451cdb4267846ff50dcccd0026a4eba71ca41f7c8bdef30ef1356620c1ff2363ad64bd8fad33a72b19
+ languageName: node
+ linkType: hard
+
+"@typescript-eslint/parser@npm:^5.4.2 || ^6.0.0 || ^7.0.0 || ^8.0.0":
+ version: 8.56.0
+ resolution: "@typescript-eslint/parser@npm:8.56.0"
+ dependencies:
+ "@typescript-eslint/scope-manager": "npm:8.56.0"
+ "@typescript-eslint/types": "npm:8.56.0"
+ "@typescript-eslint/typescript-estree": "npm:8.56.0"
+ "@typescript-eslint/visitor-keys": "npm:8.56.0"
+ debug: "npm:^4.4.3"
+ peerDependencies:
+ eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
+ typescript: ">=4.8.4 <6.0.0"
+ checksum: 10c0/f3a29c6fdc4e0d1a1e7ddb9909ab839c2f67591933e432c10f44aabb69ae2229f8d2072a220f63b70618cc35c67ff53de0ed110be86b33f4f354c19993f764cb
+ languageName: node
+ linkType: hard
+
+"@typescript-eslint/project-service@npm:8.56.0":
+ version: 8.56.0
+ resolution: "@typescript-eslint/project-service@npm:8.56.0"
+ dependencies:
+ "@typescript-eslint/tsconfig-utils": "npm:^8.56.0"
+ "@typescript-eslint/types": "npm:^8.56.0"
debug: "npm:^4.4.3"
peerDependencies:
typescript: ">=4.8.4 <6.0.0"
- checksum: 10c0/f35273a63635d2de84409f68dfcea901ed2cd3f08206abb825d742b929c8fce66e0a6a32524d87ce895a7c4c2549e4388baa08644c0a5244c9708151b0f62f52
+ checksum: 10c0/8302dc30ad8c0342137998ea872782cdd673f9e7ec4b244eeb0976915b86d6c44ef55485e2cdac2987dbf309d3663aaf293c85e88326093fc7656b51432369f6
languageName: node
linkType: hard
-"@typescript-eslint/scope-manager@npm:8.55.0":
- version: 8.55.0
- resolution: "@typescript-eslint/scope-manager@npm:8.55.0"
+"@typescript-eslint/scope-manager@npm:8.56.0":
+ version: 8.56.0
+ resolution: "@typescript-eslint/scope-manager@npm:8.56.0"
dependencies:
- "@typescript-eslint/types": "npm:8.55.0"
- "@typescript-eslint/visitor-keys": "npm:8.55.0"
- checksum: 10c0/c42bd6b8e4936cac8bee3adbc2f707e3aee5f16af3dd18c1d095f4a1b881471b58de73abc0ad176db98654683a808946902e51d86efff39dc7610d29152c3078
+ "@typescript-eslint/types": "npm:8.56.0"
+ "@typescript-eslint/visitor-keys": "npm:8.56.0"
+ checksum: 10c0/898b705295e0a4081702a52f98e0d1e50f8047900becd087b232bc71f8af2b87ed70a065bed0076a26abec8f4e5c6bb4a3a0de33b7ea0e3704ecdc7487043b57
+ languageName: node
+ linkType: hard
+
+"@typescript-eslint/tsconfig-utils@npm:8.56.0, @typescript-eslint/tsconfig-utils@npm:^8.56.0":
+ version: 8.56.0
+ resolution: "@typescript-eslint/tsconfig-utils@npm:8.56.0"
+ peerDependencies:
+ typescript: ">=4.8.4 <6.0.0"
+ checksum: 10c0/20f48af8b497d8a730dcac3724314b4f49ecc436f8871f3e17f5193d83e7d290c8838a126971767cd011208969bc4ff0f4bddc40eac167348c88d29fdb379c8b
languageName: node
linkType: hard
-"@typescript-eslint/tsconfig-utils@npm:8.55.0, @typescript-eslint/tsconfig-utils@npm:^8.55.0":
- version: 8.55.0
- resolution: "@typescript-eslint/tsconfig-utils@npm:8.55.0"
+"@typescript-eslint/type-utils@npm:8.56.0":
+ version: 8.56.0
+ resolution: "@typescript-eslint/type-utils@npm:8.56.0"
+ dependencies:
+ "@typescript-eslint/types": "npm:8.56.0"
+ "@typescript-eslint/typescript-estree": "npm:8.56.0"
+ "@typescript-eslint/utils": "npm:8.56.0"
+ debug: "npm:^4.4.3"
+ ts-api-utils: "npm:^2.4.0"
peerDependencies:
+ eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
typescript: ">=4.8.4 <6.0.0"
- checksum: 10c0/77b9a0d0b1d6ab0ce26c81394bb1aa969649016d2857e5f915a15b88012ac3dccec9fc5ff65535e1cc373434e1462513f7964e416a8d7a695f7277dcd39ec2af
+ checksum: 10c0/4da61c36fa46f9d21a519a06b4ea6c91e9fa8a8e420fede41fb5d0f29866faa11641562b6e01c221ca6ec86bc0c3ecd7b8f11fc85b92277c3fd450ffc8fa2522
languageName: node
linkType: hard
-"@typescript-eslint/types@npm:8.55.0, @typescript-eslint/types@npm:^8.55.0":
- version: 8.55.0
- resolution: "@typescript-eslint/types@npm:8.55.0"
- checksum: 10c0/dc572f55966e2f0fee149e5d5e42a91cedcdeac451bff29704eb701f9336f123bbc7d7abcfbda717f9e1ef6b402fa24679908bc6032e67513287403037ef345f
+"@typescript-eslint/types@npm:8.56.0, @typescript-eslint/types@npm:^8.56.0":
+ version: 8.56.0
+ resolution: "@typescript-eslint/types@npm:8.56.0"
+ checksum: 10c0/5deb4ebf5fa62f9f927f6aa45f7245aa03567e88941cd76e7b083175fd59fc40368a804ba7ff7581eac75706e42ddd5c77d2a60d6b1e76ab7865d559c9af9937
languageName: node
linkType: hard
-"@typescript-eslint/typescript-estree@npm:8.55.0":
- version: 8.55.0
- resolution: "@typescript-eslint/typescript-estree@npm:8.55.0"
+"@typescript-eslint/typescript-estree@npm:8.56.0":
+ version: 8.56.0
+ resolution: "@typescript-eslint/typescript-estree@npm:8.56.0"
dependencies:
- "@typescript-eslint/project-service": "npm:8.55.0"
- "@typescript-eslint/tsconfig-utils": "npm:8.55.0"
- "@typescript-eslint/types": "npm:8.55.0"
- "@typescript-eslint/visitor-keys": "npm:8.55.0"
+ "@typescript-eslint/project-service": "npm:8.56.0"
+ "@typescript-eslint/tsconfig-utils": "npm:8.56.0"
+ "@typescript-eslint/types": "npm:8.56.0"
+ "@typescript-eslint/visitor-keys": "npm:8.56.0"
debug: "npm:^4.4.3"
minimatch: "npm:^9.0.5"
semver: "npm:^7.7.3"
@@ -2256,32 +2335,174 @@ __metadata:
ts-api-utils: "npm:^2.4.0"
peerDependencies:
typescript: ">=4.8.4 <6.0.0"
- checksum: 10c0/2db3ff9489945ad04508b14009eb0f6b2b7c6c2469805327fa09ffa460af354cd181ff2e8153f9008bd60254efb54a004a59ccacbdbc9c963956e2c2c1189dbc
+ checksum: 10c0/cc2ba5bbfabb71c1510aea8fb8bf0d8385cabb9ca5b65a621e73f3088a91089a02aea56a9d9a31bd707593b5ba4d33d0aa2fcbdeee3cc7f4eca8226107523c28
languageName: node
linkType: hard
-"@typescript-eslint/utils@npm:^6.0.0 || ^7.0.0 || ^8.0.0":
- version: 8.55.0
- resolution: "@typescript-eslint/utils@npm:8.55.0"
+"@typescript-eslint/utils@npm:8.56.0":
+ version: 8.56.0
+ resolution: "@typescript-eslint/utils@npm:8.56.0"
dependencies:
"@eslint-community/eslint-utils": "npm:^4.9.1"
- "@typescript-eslint/scope-manager": "npm:8.55.0"
- "@typescript-eslint/types": "npm:8.55.0"
- "@typescript-eslint/typescript-estree": "npm:8.55.0"
+ "@typescript-eslint/scope-manager": "npm:8.56.0"
+ "@typescript-eslint/types": "npm:8.56.0"
+ "@typescript-eslint/typescript-estree": "npm:8.56.0"
peerDependencies:
- eslint: ^8.57.0 || ^9.0.0
+ eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
typescript: ">=4.8.4 <6.0.0"
- checksum: 10c0/b57b86ac531e433c8057279805e6c903250460bc937cea46ec3b9284181a38f23b7c1ef092e8a1e37179432b39bd587c33db7f031b4243b1207ef37f23e4f24f
+ checksum: 10c0/49545d399345bb4d8113d1001ec60c05c7e0d28fd44cb3c75128e58a53c9bf7ae8d0680ca089a4f37ab9eea8a3ef39011fc731eb4ad8dd4ab642849d84318645
languageName: node
linkType: hard
-"@typescript-eslint/visitor-keys@npm:8.55.0":
- version: 8.55.0
- resolution: "@typescript-eslint/visitor-keys@npm:8.55.0"
+"@typescript-eslint/visitor-keys@npm:8.56.0":
+ version: 8.56.0
+ resolution: "@typescript-eslint/visitor-keys@npm:8.56.0"
dependencies:
- "@typescript-eslint/types": "npm:8.55.0"
- eslint-visitor-keys: "npm:^4.2.1"
- checksum: 10c0/995c5ca91f7c7c1f3c4fdb4f98654abdff55efa570076b9b012da4cc203ebe7e2aee57ba83208ae51c2aef496c45cb8f6909560349131b779f31ce6f8758da23
+ "@typescript-eslint/types": "npm:8.56.0"
+ eslint-visitor-keys: "npm:^5.0.0"
+ checksum: 10c0/4cb7668430042da70707ac5cad826348e808af94095aca1f3d07d39d566745a33991d3defccd1e687f1b1f8aeea52eeb47591933e962452eb51c4bcd88773c12
+ languageName: node
+ linkType: hard
+
+"@ungap/structured-clone@npm:^1.2.0":
+ version: 1.3.0
+ resolution: "@ungap/structured-clone@npm:1.3.0"
+ checksum: 10c0/0fc3097c2540ada1fc340ee56d58d96b5b536a2a0dab6e3ec17d4bfc8c4c86db345f61a375a8185f9da96f01c69678f836a2b57eeaa9e4b8eeafd26428e57b0a
+ languageName: node
+ linkType: hard
+
+"@unrs/resolver-binding-android-arm-eabi@npm:1.11.1":
+ version: 1.11.1
+ resolution: "@unrs/resolver-binding-android-arm-eabi@npm:1.11.1"
+ conditions: os=android & cpu=arm
+ languageName: node
+ linkType: hard
+
+"@unrs/resolver-binding-android-arm64@npm:1.11.1":
+ version: 1.11.1
+ resolution: "@unrs/resolver-binding-android-arm64@npm:1.11.1"
+ conditions: os=android & cpu=arm64
+ languageName: node
+ linkType: hard
+
+"@unrs/resolver-binding-darwin-arm64@npm:1.11.1":
+ version: 1.11.1
+ resolution: "@unrs/resolver-binding-darwin-arm64@npm:1.11.1"
+ conditions: os=darwin & cpu=arm64
+ languageName: node
+ linkType: hard
+
+"@unrs/resolver-binding-darwin-x64@npm:1.11.1":
+ version: 1.11.1
+ resolution: "@unrs/resolver-binding-darwin-x64@npm:1.11.1"
+ conditions: os=darwin & cpu=x64
+ languageName: node
+ linkType: hard
+
+"@unrs/resolver-binding-freebsd-x64@npm:1.11.1":
+ version: 1.11.1
+ resolution: "@unrs/resolver-binding-freebsd-x64@npm:1.11.1"
+ conditions: os=freebsd & cpu=x64
+ languageName: node
+ linkType: hard
+
+"@unrs/resolver-binding-linux-arm-gnueabihf@npm:1.11.1":
+ version: 1.11.1
+ resolution: "@unrs/resolver-binding-linux-arm-gnueabihf@npm:1.11.1"
+ conditions: os=linux & cpu=arm
+ languageName: node
+ linkType: hard
+
+"@unrs/resolver-binding-linux-arm-musleabihf@npm:1.11.1":
+ version: 1.11.1
+ resolution: "@unrs/resolver-binding-linux-arm-musleabihf@npm:1.11.1"
+ conditions: os=linux & cpu=arm
+ languageName: node
+ linkType: hard
+
+"@unrs/resolver-binding-linux-arm64-gnu@npm:1.11.1":
+ version: 1.11.1
+ resolution: "@unrs/resolver-binding-linux-arm64-gnu@npm:1.11.1"
+ conditions: os=linux & cpu=arm64 & libc=glibc
+ languageName: node
+ linkType: hard
+
+"@unrs/resolver-binding-linux-arm64-musl@npm:1.11.1":
+ version: 1.11.1
+ resolution: "@unrs/resolver-binding-linux-arm64-musl@npm:1.11.1"
+ conditions: os=linux & cpu=arm64 & libc=musl
+ languageName: node
+ linkType: hard
+
+"@unrs/resolver-binding-linux-ppc64-gnu@npm:1.11.1":
+ version: 1.11.1
+ resolution: "@unrs/resolver-binding-linux-ppc64-gnu@npm:1.11.1"
+ conditions: os=linux & cpu=ppc64 & libc=glibc
+ languageName: node
+ linkType: hard
+
+"@unrs/resolver-binding-linux-riscv64-gnu@npm:1.11.1":
+ version: 1.11.1
+ resolution: "@unrs/resolver-binding-linux-riscv64-gnu@npm:1.11.1"
+ conditions: os=linux & cpu=riscv64 & libc=glibc
+ languageName: node
+ linkType: hard
+
+"@unrs/resolver-binding-linux-riscv64-musl@npm:1.11.1":
+ version: 1.11.1
+ resolution: "@unrs/resolver-binding-linux-riscv64-musl@npm:1.11.1"
+ conditions: os=linux & cpu=riscv64 & libc=musl
+ languageName: node
+ linkType: hard
+
+"@unrs/resolver-binding-linux-s390x-gnu@npm:1.11.1":
+ version: 1.11.1
+ resolution: "@unrs/resolver-binding-linux-s390x-gnu@npm:1.11.1"
+ conditions: os=linux & cpu=s390x & libc=glibc
+ languageName: node
+ linkType: hard
+
+"@unrs/resolver-binding-linux-x64-gnu@npm:1.11.1":
+ version: 1.11.1
+ resolution: "@unrs/resolver-binding-linux-x64-gnu@npm:1.11.1"
+ conditions: os=linux & cpu=x64 & libc=glibc
+ languageName: node
+ linkType: hard
+
+"@unrs/resolver-binding-linux-x64-musl@npm:1.11.1":
+ version: 1.11.1
+ resolution: "@unrs/resolver-binding-linux-x64-musl@npm:1.11.1"
+ conditions: os=linux & cpu=x64 & libc=musl
+ languageName: node
+ linkType: hard
+
+"@unrs/resolver-binding-wasm32-wasi@npm:1.11.1":
+ version: 1.11.1
+ resolution: "@unrs/resolver-binding-wasm32-wasi@npm:1.11.1"
+ dependencies:
+ "@napi-rs/wasm-runtime": "npm:^0.2.11"
+ conditions: cpu=wasm32
+ languageName: node
+ linkType: hard
+
+"@unrs/resolver-binding-win32-arm64-msvc@npm:1.11.1":
+ version: 1.11.1
+ resolution: "@unrs/resolver-binding-win32-arm64-msvc@npm:1.11.1"
+ conditions: os=win32 & cpu=arm64
+ languageName: node
+ linkType: hard
+
+"@unrs/resolver-binding-win32-ia32-msvc@npm:1.11.1":
+ version: 1.11.1
+ resolution: "@unrs/resolver-binding-win32-ia32-msvc@npm:1.11.1"
+ conditions: os=win32 & cpu=ia32
+ languageName: node
+ linkType: hard
+
+"@unrs/resolver-binding-win32-x64-msvc@npm:1.11.1":
+ version: 1.11.1
+ resolution: "@unrs/resolver-binding-win32-x64-msvc@npm:1.11.1"
+ conditions: os=win32 & cpu=x64
languageName: node
linkType: hard
@@ -2336,6 +2557,15 @@ __metadata:
languageName: node
linkType: hard
+"acorn@npm:^8.9.0":
+ version: 8.16.0
+ resolution: "acorn@npm:8.16.0"
+ bin:
+ acorn: bin/acorn
+ checksum: 10c0/c9c52697227661b68d0debaf972222d4f622aa06b185824164e153438afa7b08273432ca43ea792cadb24dada1d46f6f6bb1ef8de9956979288cc1b96bf9914e
+ languageName: node
+ linkType: hard
+
"agent-base@npm:6":
version: 6.0.2
resolution: "agent-base@npm:6.0.2"
@@ -2397,6 +2627,15 @@ __metadata:
languageName: node
linkType: hard
+"ansi-escapes@npm:^7.0.0":
+ version: 7.3.0
+ resolution: "ansi-escapes@npm:7.3.0"
+ dependencies:
+ environment: "npm:^1.0.0"
+ checksum: 10c0/068961d99f0ef28b661a4a9f84a5d645df93ccf3b9b93816cc7d46bbe1913321d4cdf156bb842a4e1e4583b7375c631fa963efb43001c4eb7ff9ab8f78fc0679
+ languageName: node
+ linkType: hard
+
"ansi-regex@npm:^5.0.0":
version: 5.0.0
resolution: "ansi-regex@npm:5.0.0"
@@ -2411,6 +2650,13 @@ __metadata:
languageName: node
linkType: hard
+"ansi-regex@npm:^6.0.1":
+ version: 6.2.2
+ resolution: "ansi-regex@npm:6.2.2"
+ checksum: 10c0/05d4acb1d2f59ab2cf4b794339c7b168890d44dda4bf0ce01152a8da0213aca207802f930442ce8cd22d7a92f44907664aac6508904e75e038fa944d2601b30f
+ languageName: node
+ linkType: hard
+
"ansi-styles@npm:^3.2.1":
version: 3.2.1
resolution: "ansi-styles@npm:3.2.1"
@@ -2446,6 +2692,13 @@ __metadata:
languageName: node
linkType: hard
+"ansi-styles@npm:^6.1.0, ansi-styles@npm:^6.2.1":
+ version: 6.2.3
+ resolution: "ansi-styles@npm:6.2.3"
+ checksum: 10c0/23b8a4ce14e18fb854693b95351e286b771d23d8844057ed2e7d083cd3e708376c3323707ec6a24365f7d7eda3ca00327fe04092e29e551499ec4c8b7bfac868
+ languageName: node
+ linkType: hard
+
"anymatch@npm:^3.0.3":
version: 3.1.3
resolution: "anymatch@npm:3.1.3"
@@ -3081,6 +3334,25 @@ __metadata:
languageName: node
linkType: hard
+"cli-cursor@npm:^5.0.0":
+ version: 5.0.0
+ resolution: "cli-cursor@npm:5.0.0"
+ dependencies:
+ restore-cursor: "npm:^5.0.0"
+ checksum: 10c0/7ec62f69b79f6734ab209a3e4dbdc8af7422d44d360a7cb1efa8a0887bbe466a6e625650c466fe4359aee44dbe2dc0b6994b583d40a05d0808a5cb193641d220
+ languageName: node
+ linkType: hard
+
+"cli-truncate@npm:^5.0.0":
+ version: 5.1.1
+ resolution: "cli-truncate@npm:5.1.1"
+ dependencies:
+ slice-ansi: "npm:^7.1.0"
+ string-width: "npm:^8.0.0"
+ checksum: 10c0/3842920829a62f3e041ce39199050c42706c3c9c756a4efc8b86d464e102d1fa031d8b1b9b2e3bb36e1017c763558275472d031bdc884c1eff22a2f20e4f6b0a
+ languageName: node
+ linkType: hard
+
"client-only@npm:0.0.1":
version: 0.0.1
resolution: "client-only@npm:0.0.1"
@@ -3125,7 +3397,6 @@ __metadata:
resolution: "code-scrobble@workspace:."
dependencies:
"@babel/core": "npm:^7.26.0"
- "@babel/eslint-parser": "npm:^7.25.9"
"@babel/runtime-corejs2": "npm:^7.26.0"
"@eslint/eslintrc": "npm:^3.2.0"
"@eslint/js": "npm:^9.18.0"
@@ -3143,23 +3414,24 @@ __metadata:
babel-plugin-styled-components: "npm:^2.1.4"
disconnect: "npm:^1.2.2"
dotenv: "npm:^16.4.7"
- eslint: "npm:^9.18.0"
- eslint-config-airbnb: "npm:^19.0.4"
+ eslint: "npm:^8.57.0"
+ eslint-config-next: "npm:^14.2.0"
+ eslint-config-prettier: "npm:10.1.8"
eslint-plugin-import: "npm:^2.31.0"
- eslint-plugin-jest: "npm:^28.11.0"
eslint-plugin-jsx-a11y: "npm:^6.10.2"
- eslint-plugin-react: "npm:^7.37.4"
- eslint-plugin-react-hooks: "npm:^5.1.0"
+ husky: "npm:^9.0.0"
iron-session: "npm:^8.0.4"
jest: "npm:^29.7.0"
jest-environment-jsdom: "npm:^29.7.0"
jest-fetch-mock: "npm:^3.0.1"
lastfmapi: "npm:^0.1.1"
+ lint-staged: "npm:^16.2.4"
lodash: "npm:^4.17.21"
mongoose: "npm:^8.0.0"
next: "npm:^14.2.0"
next-redux-wrapper: "npm:^8.1.0"
nprogress: "npm:^0.2.0"
+ prettier: "npm:^3.8.1"
quagga: "npm:^0.12.1"
react: "npm:^18.0.0"
react-dom: "npm:^18.0.0"
@@ -3226,6 +3498,13 @@ __metadata:
languageName: node
linkType: hard
+"colorette@npm:^2.0.20":
+ version: 2.0.20
+ resolution: "colorette@npm:2.0.20"
+ checksum: 10c0/e94116ff33b0ff56f3b83b9ace895e5bf87c2a7a47b3401b8c3f3226e050d5ef76cf4072fb3325f9dc24d1698f9b730baf4e05eeaf861d74a1883073f4c98a40
+ languageName: node
+ linkType: hard
+
"combined-stream@npm:^1.0.6, combined-stream@npm:^1.0.8, combined-stream@npm:~1.0.6":
version: 1.0.8
resolution: "combined-stream@npm:1.0.8"
@@ -3235,6 +3514,13 @@ __metadata:
languageName: node
linkType: hard
+"commander@npm:^14.0.2":
+ version: 14.0.3
+ resolution: "commander@npm:14.0.3"
+ checksum: 10c0/755652564bbf56ff2ff083313912b326450d3f8d8c85f4b71416539c9a05c3c67dbd206821ca72635bf6b160e2afdefcb458e86b317827d5cb333b69ce7f1a24
+ languageName: node
+ linkType: hard
+
"commander@npm:^7.2.0":
version: 7.2.0
resolution: "commander@npm:7.2.0"
@@ -3249,13 +3535,6 @@ __metadata:
languageName: node
linkType: hard
-"confusing-browser-globals@npm:^1.0.10":
- version: 1.0.11
- resolution: "confusing-browser-globals@npm:1.0.11"
- checksum: 10c0/475d0a284fa964a5182b519af5738b5b64bf7e413cfd703c1b3496bf6f4df9f827893a9b221c0ea5873c1476835beb1e0df569ba643eff0734010c1eb780589e
- languageName: node
- linkType: hard
-
"convert-source-map@npm:^2.0.0":
version: 2.0.0
resolution: "convert-source-map@npm:2.0.0"
@@ -3328,7 +3607,7 @@ __metadata:
languageName: node
linkType: hard
-"cross-spawn@npm:^7.0.3, cross-spawn@npm:^7.0.6":
+"cross-spawn@npm:^7.0.2, cross-spawn@npm:^7.0.3, cross-spawn@npm:^7.0.6":
version: 7.0.6
resolution: "cross-spawn@npm:7.0.6"
dependencies:
@@ -3496,7 +3775,7 @@ __metadata:
languageName: node
linkType: hard
-"debug@npm:4, debug@npm:4.x, debug@npm:^4.3.1, debug@npm:^4.3.2, debug@npm:^4.3.4, debug@npm:^4.4.3":
+"debug@npm:4, debug@npm:4.x, debug@npm:^4.3.1, debug@npm:^4.3.2, debug@npm:^4.3.4, debug@npm:^4.4.0, debug@npm:^4.4.3":
version: 4.4.3
resolution: "debug@npm:4.4.3"
dependencies:
@@ -3645,6 +3924,15 @@ __metadata:
languageName: node
linkType: hard
+"doctrine@npm:^3.0.0":
+ version: 3.0.0
+ resolution: "doctrine@npm:3.0.0"
+ dependencies:
+ esutils: "npm:^2.0.2"
+ checksum: 10c0/c96bdccabe9d62ab6fea9399fdff04a66e6563c1d6fb3a3a063e8d53c3bb136ba63e84250bbf63d00086a769ad53aef92d2bd483f03f837fc97b71cbee6b2520
+ languageName: node
+ linkType: hard
+
"dom-accessibility-api@npm:^0.5.9":
version: 0.5.16
resolution: "dom-accessibility-api@npm:0.5.16"
@@ -3686,6 +3974,13 @@ __metadata:
languageName: node
linkType: hard
+"eastasianwidth@npm:^0.2.0":
+ version: 0.2.0
+ resolution: "eastasianwidth@npm:0.2.0"
+ checksum: 10c0/26f364ebcdb6395f95124fda411f63137a4bfb5d3a06453f7f23dfe52502905bd84e0488172e0f9ec295fdc45f05c23d5d91baf16bd26f0fe9acd777a188dc39
+ languageName: node
+ linkType: hard
+
"ecc-jsbn@npm:~0.1.1":
version: 0.1.2
resolution: "ecc-jsbn@npm:0.1.2"
@@ -3710,6 +4005,13 @@ __metadata:
languageName: node
linkType: hard
+"emoji-regex@npm:^10.3.0":
+ version: 10.6.0
+ resolution: "emoji-regex@npm:10.6.0"
+ checksum: 10c0/1e4aa097bb007301c3b4b1913879ae27327fdc48e93eeefefe3b87e495eb33c5af155300be951b4349ff6ac084f4403dc9eff970acba7c1c572d89396a9a32d7
+ languageName: node
+ linkType: hard
+
"emoji-regex@npm:^8.0.0":
version: 8.0.0
resolution: "emoji-regex@npm:8.0.0"
@@ -3754,6 +4056,13 @@ __metadata:
languageName: node
linkType: hard
+"environment@npm:^1.0.0":
+ version: 1.1.0
+ resolution: "environment@npm:1.1.0"
+ checksum: 10c0/fb26434b0b581ab397039e51ff3c92b34924a98b2039dcb47e41b7bca577b9dbf134a8eadb364415c74464b682e2d3afe1a4c0eb9873dc44ea814c5d3103331d
+ languageName: node
+ linkType: hard
+
"err-code@npm:^2.0.2":
version: 2.0.3
resolution: "err-code@npm:2.0.3"
@@ -3957,39 +4266,42 @@ __metadata:
languageName: node
linkType: hard
-"eslint-config-airbnb-base@npm:^15.0.0":
- version: 15.0.0
- resolution: "eslint-config-airbnb-base@npm:15.0.0"
- dependencies:
- confusing-browser-globals: "npm:^1.0.10"
- object.assign: "npm:^4.1.2"
- object.entries: "npm:^1.1.5"
- semver: "npm:^6.3.0"
+"eslint-config-next@npm:^14.2.0":
+ version: 14.2.35
+ resolution: "eslint-config-next@npm:14.2.35"
+ dependencies:
+ "@next/eslint-plugin-next": "npm:14.2.35"
+ "@rushstack/eslint-patch": "npm:^1.3.3"
+ "@typescript-eslint/eslint-plugin": "npm:^5.4.2 || ^6.0.0 || ^7.0.0 || ^8.0.0"
+ "@typescript-eslint/parser": "npm:^5.4.2 || ^6.0.0 || ^7.0.0 || ^8.0.0"
+ eslint-import-resolver-node: "npm:^0.3.6"
+ eslint-import-resolver-typescript: "npm:^3.5.2"
+ eslint-plugin-import: "npm:^2.28.1"
+ eslint-plugin-jsx-a11y: "npm:^6.7.1"
+ eslint-plugin-react: "npm:^7.33.2"
+ eslint-plugin-react-hooks: "npm:^4.5.0 || 5.0.0-canary-7118f5dd7-20230705"
peerDependencies:
- eslint: ^7.32.0 || ^8.2.0
- eslint-plugin-import: ^2.25.2
- checksum: 10c0/93639d991654414756f82ad7860aac30b0dc6797277b7904ddb53ed88a32c470598696bbc6c503e066414024d305221974d3769e6642de65043bedf29cbbd30f
+ eslint: ^7.23.0 || ^8.0.0
+ typescript: ">=3.3.1"
+ peerDependenciesMeta:
+ typescript:
+ optional: true
+ checksum: 10c0/8e489c74ded72a68cc26999a7504cf916a74e53df603ccd40cd3ac8ee7d5d1cf99569aa2a2509b464bceff1d604cdfab679b53004d894698e8689c499f956a8a
languageName: node
linkType: hard
-"eslint-config-airbnb@npm:^19.0.4":
- version: 19.0.4
- resolution: "eslint-config-airbnb@npm:19.0.4"
- dependencies:
- eslint-config-airbnb-base: "npm:^15.0.0"
- object.assign: "npm:^4.1.2"
- object.entries: "npm:^1.1.5"
+"eslint-config-prettier@npm:10.1.8":
+ version: 10.1.8
+ resolution: "eslint-config-prettier@npm:10.1.8"
peerDependencies:
- eslint: ^7.32.0 || ^8.2.0
- eslint-plugin-import: ^2.25.3
- eslint-plugin-jsx-a11y: ^6.5.1
- eslint-plugin-react: ^7.28.0
- eslint-plugin-react-hooks: ^4.3.0
- checksum: 10c0/867feeda45c4b480b1b8eff8fabc1bb107e837da8b48e5039e0c175ae6ad34af383b1924fc163bbfcef24a324e6651b1515e5bd12cbcbb19535a8838e2544a02
+ eslint: ">=7.0.0"
+ bin:
+ eslint-config-prettier: bin/cli.js
+ checksum: 10c0/e1bcfadc9eccd526c240056b1e59c5cd26544fe59feb85f38f4f1f116caed96aea0b3b87868e68b3099e55caaac3f2e5b9f58110f85db893e83a332751192682
languageName: node
linkType: hard
-"eslint-import-resolver-node@npm:^0.3.9":
+"eslint-import-resolver-node@npm:^0.3.6, eslint-import-resolver-node@npm:^0.3.9":
version: 0.3.9
resolution: "eslint-import-resolver-node@npm:0.3.9"
dependencies:
@@ -4000,6 +4312,30 @@ __metadata:
languageName: node
linkType: hard
+"eslint-import-resolver-typescript@npm:^3.5.2":
+ version: 3.10.1
+ resolution: "eslint-import-resolver-typescript@npm:3.10.1"
+ dependencies:
+ "@nolyfill/is-core-module": "npm:1.0.39"
+ debug: "npm:^4.4.0"
+ get-tsconfig: "npm:^4.10.0"
+ is-bun-module: "npm:^2.0.0"
+ stable-hash: "npm:^0.0.5"
+ tinyglobby: "npm:^0.2.13"
+ unrs-resolver: "npm:^1.6.2"
+ peerDependencies:
+ eslint: "*"
+ eslint-plugin-import: "*"
+ eslint-plugin-import-x: "*"
+ peerDependenciesMeta:
+ eslint-plugin-import:
+ optional: true
+ eslint-plugin-import-x:
+ optional: true
+ checksum: 10c0/02ba72cf757753ab9250806c066d09082e00807b7b6525d7687e1c0710bc3f6947e39120227fe1f93dabea3510776d86fb3fd769466ba3c46ce67e9f874cb702
+ languageName: node
+ linkType: hard
+
"eslint-module-utils@npm:^2.12.1":
version: 2.12.1
resolution: "eslint-module-utils@npm:2.12.1"
@@ -4012,7 +4348,7 @@ __metadata:
languageName: node
linkType: hard
-"eslint-plugin-import@npm:^2.31.0":
+"eslint-plugin-import@npm:^2.28.1, eslint-plugin-import@npm:^2.31.0":
version: 2.32.0
resolution: "eslint-plugin-import@npm:2.32.0"
dependencies:
@@ -4041,25 +4377,7 @@ __metadata:
languageName: node
linkType: hard
-"eslint-plugin-jest@npm:^28.11.0":
- version: 28.14.0
- resolution: "eslint-plugin-jest@npm:28.14.0"
- dependencies:
- "@typescript-eslint/utils": "npm:^6.0.0 || ^7.0.0 || ^8.0.0"
- peerDependencies:
- "@typescript-eslint/eslint-plugin": ^6.0.0 || ^7.0.0 || ^8.0.0
- eslint: ^7.0.0 || ^8.0.0 || ^9.0.0
- jest: "*"
- peerDependenciesMeta:
- "@typescript-eslint/eslint-plugin":
- optional: true
- jest:
- optional: true
- checksum: 10c0/da9c99dd8a1a80aa0c126ff4558882451dcee61b7e4c88e2407ac27d0c86fad2951384a4b037748e26f8743890b4628c6917b0760b01b7017c53fb29768584bc
- languageName: node
- linkType: hard
-
-"eslint-plugin-jsx-a11y@npm:^6.10.2":
+"eslint-plugin-jsx-a11y@npm:^6.10.2, eslint-plugin-jsx-a11y@npm:^6.7.1":
version: 6.10.2
resolution: "eslint-plugin-jsx-a11y@npm:6.10.2"
dependencies:
@@ -4084,16 +4402,16 @@ __metadata:
languageName: node
linkType: hard
-"eslint-plugin-react-hooks@npm:^5.1.0":
- version: 5.2.0
- resolution: "eslint-plugin-react-hooks@npm:5.2.0"
+"eslint-plugin-react-hooks@npm:^4.5.0 || 5.0.0-canary-7118f5dd7-20230705":
+ version: 5.0.0-canary-7118f5dd7-20230705
+ resolution: "eslint-plugin-react-hooks@npm:5.0.0-canary-7118f5dd7-20230705"
peerDependencies:
- eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0
- checksum: 10c0/1c8d50fa5984c6dea32470651807d2922cc3934cf3425e78f84a24c2dfd972e7f019bee84aefb27e0cf2c13fea0ac1d4473267727408feeb1c56333ca1489385
+ eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0
+ checksum: 10c0/554c4e426bfeb126155510dcba8345391426af147ee629f1c56c9ef6af08340d11008213e4e15b0138830af2c4439d7158da2091987f7efb01aeab662c44b274
languageName: node
linkType: hard
-"eslint-plugin-react@npm:^7.37.4":
+"eslint-plugin-react@npm:^7.33.2":
version: 7.37.5
resolution: "eslint-plugin-react@npm:7.37.5"
dependencies:
@@ -4121,34 +4439,17 @@ __metadata:
languageName: node
linkType: hard
-"eslint-scope@npm:5.1.1":
- version: 5.1.1
- resolution: "eslint-scope@npm:5.1.1"
- dependencies:
- esrecurse: "npm:^4.3.0"
- estraverse: "npm:^4.1.1"
- checksum: 10c0/d30ef9dc1c1cbdece34db1539a4933fe3f9b14e1ffb27ecc85987902ee663ad7c9473bbd49a9a03195a373741e62e2f807c4938992e019b511993d163450e70a
- languageName: node
- linkType: hard
-
-"eslint-scope@npm:^8.4.0":
- version: 8.4.0
- resolution: "eslint-scope@npm:8.4.0"
+"eslint-scope@npm:^7.2.2":
+ version: 7.2.2
+ resolution: "eslint-scope@npm:7.2.2"
dependencies:
esrecurse: "npm:^4.3.0"
estraverse: "npm:^5.2.0"
- checksum: 10c0/407f6c600204d0f3705bd557f81bd0189e69cd7996f408f8971ab5779c0af733d1af2f1412066b40ee1588b085874fc37a2333986c6521669cdbdd36ca5058e0
- languageName: node
- linkType: hard
-
-"eslint-visitor-keys@npm:^2.1.0":
- version: 2.1.0
- resolution: "eslint-visitor-keys@npm:2.1.0"
- checksum: 10c0/9f0e3a2db751d84067d15977ac4b4472efd6b303e369e6ff241a99feac04da758f46d5add022c33d06b53596038dbae4b4aceb27c7e68b8dfc1055b35e495787
+ checksum: 10c0/613c267aea34b5a6d6c00514e8545ef1f1433108097e857225fed40d397dd6b1809dffd11c2fde23b37ca53d7bf935fe04d2a18e6fc932b31837b6ad67e1c116
languageName: node
linkType: hard
-"eslint-visitor-keys@npm:^3.4.3":
+"eslint-visitor-keys@npm:^3.4.1, eslint-visitor-keys@npm:^3.4.3":
version: 3.4.3
resolution: "eslint-visitor-keys@npm:3.4.3"
checksum: 10c0/92708e882c0a5ffd88c23c0b404ac1628cf20104a108c745f240a13c332a11aac54f49a22d5762efbffc18ecbc9a580d1b7ad034bf5f3cc3307e5cbff2ec9820
@@ -4162,56 +4463,62 @@ __metadata:
languageName: node
linkType: hard
-"eslint@npm:^9.18.0":
- version: 9.39.2
- resolution: "eslint@npm:9.39.2"
- dependencies:
- "@eslint-community/eslint-utils": "npm:^4.8.0"
- "@eslint-community/regexpp": "npm:^4.12.1"
- "@eslint/config-array": "npm:^0.21.1"
- "@eslint/config-helpers": "npm:^0.4.2"
- "@eslint/core": "npm:^0.17.0"
- "@eslint/eslintrc": "npm:^3.3.1"
- "@eslint/js": "npm:9.39.2"
- "@eslint/plugin-kit": "npm:^0.4.1"
- "@humanfs/node": "npm:^0.16.6"
+"eslint-visitor-keys@npm:^5.0.0":
+ version: 5.0.1
+ resolution: "eslint-visitor-keys@npm:5.0.1"
+ checksum: 10c0/16190bdf2cbae40a1109384c94450c526a79b0b9c3cb21e544256ed85ac48a4b84db66b74a6561d20fe6ab77447f150d711c2ad5ad74df4fcc133736bce99678
+ languageName: node
+ linkType: hard
+
+"eslint@npm:^8.57.0":
+ version: 8.57.1
+ resolution: "eslint@npm:8.57.1"
+ dependencies:
+ "@eslint-community/eslint-utils": "npm:^4.2.0"
+ "@eslint-community/regexpp": "npm:^4.6.1"
+ "@eslint/eslintrc": "npm:^2.1.4"
+ "@eslint/js": "npm:8.57.1"
+ "@humanwhocodes/config-array": "npm:^0.13.0"
"@humanwhocodes/module-importer": "npm:^1.0.1"
- "@humanwhocodes/retry": "npm:^0.4.2"
- "@types/estree": "npm:^1.0.6"
+ "@nodelib/fs.walk": "npm:^1.2.8"
+ "@ungap/structured-clone": "npm:^1.2.0"
ajv: "npm:^6.12.4"
chalk: "npm:^4.0.0"
- cross-spawn: "npm:^7.0.6"
+ cross-spawn: "npm:^7.0.2"
debug: "npm:^4.3.2"
+ doctrine: "npm:^3.0.0"
escape-string-regexp: "npm:^4.0.0"
- eslint-scope: "npm:^8.4.0"
- eslint-visitor-keys: "npm:^4.2.1"
- espree: "npm:^10.4.0"
- esquery: "npm:^1.5.0"
+ eslint-scope: "npm:^7.2.2"
+ eslint-visitor-keys: "npm:^3.4.3"
+ espree: "npm:^9.6.1"
+ esquery: "npm:^1.4.2"
esutils: "npm:^2.0.2"
fast-deep-equal: "npm:^3.1.3"
- file-entry-cache: "npm:^8.0.0"
+ file-entry-cache: "npm:^6.0.1"
find-up: "npm:^5.0.0"
glob-parent: "npm:^6.0.2"
+ globals: "npm:^13.19.0"
+ graphemer: "npm:^1.4.0"
ignore: "npm:^5.2.0"
imurmurhash: "npm:^0.1.4"
is-glob: "npm:^4.0.0"
+ is-path-inside: "npm:^3.0.3"
+ js-yaml: "npm:^4.1.0"
json-stable-stringify-without-jsonify: "npm:^1.0.1"
+ levn: "npm:^0.4.1"
lodash.merge: "npm:^4.6.2"
minimatch: "npm:^3.1.2"
natural-compare: "npm:^1.4.0"
optionator: "npm:^0.9.3"
- peerDependencies:
- jiti: "*"
- peerDependenciesMeta:
- jiti:
- optional: true
+ strip-ansi: "npm:^6.0.1"
+ text-table: "npm:^0.2.0"
bin:
eslint: bin/eslint.js
- checksum: 10c0/bb88ca8fd16bb7e1ac3e13804c54d41c583214460c0faa7b3e7c574e69c5600c7122295500fb4b0c06067831111db740931e98da1340329527658e1cf80073d3
+ checksum: 10c0/1fd31533086c1b72f86770a4d9d7058ee8b4643fd1cfd10c7aac1ecb8725698e88352a87805cf4b2ce890aa35947df4b4da9655fb7fdfa60dbb448a43f6ebcf1
languageName: node
linkType: hard
-"espree@npm:^10.0.1, espree@npm:^10.4.0":
+"espree@npm:^10.0.1":
version: 10.4.0
resolution: "espree@npm:10.4.0"
dependencies:
@@ -4222,6 +4529,17 @@ __metadata:
languageName: node
linkType: hard
+"espree@npm:^9.6.0, espree@npm:^9.6.1":
+ version: 9.6.1
+ resolution: "espree@npm:9.6.1"
+ dependencies:
+ acorn: "npm:^8.9.0"
+ acorn-jsx: "npm:^5.3.2"
+ eslint-visitor-keys: "npm:^3.4.1"
+ checksum: 10c0/1a2e9b4699b715347f62330bcc76aee224390c28bb02b31a3752e9d07549c473f5f986720483c6469cf3cfb3c9d05df612ffc69eb1ee94b54b739e67de9bb460
+ languageName: node
+ linkType: hard
+
"esprima@npm:^4.0.0, esprima@npm:^4.0.1":
version: 4.0.1
resolution: "esprima@npm:4.0.1"
@@ -4232,7 +4550,7 @@ __metadata:
languageName: node
linkType: hard
-"esquery@npm:^1.5.0":
+"esquery@npm:^1.4.2":
version: 1.7.0
resolution: "esquery@npm:1.7.0"
dependencies:
@@ -4250,13 +4568,6 @@ __metadata:
languageName: node
linkType: hard
-"estraverse@npm:^4.1.1":
- version: 4.3.0
- resolution: "estraverse@npm:4.3.0"
- checksum: 10c0/9cb46463ef8a8a4905d3708a652d60122a0c20bb58dec7e0e12ab0e7235123d74214fc0141d743c381813e1b992767e2708194f6f6e0f9fd00c1b4e0887b8b6d
- languageName: node
- linkType: hard
-
"estraverse@npm:^5.1.0, estraverse@npm:^5.2.0, estraverse@npm:^5.3.0":
version: 5.3.0
resolution: "estraverse@npm:5.3.0"
@@ -4271,6 +4582,13 @@ __metadata:
languageName: node
linkType: hard
+"eventemitter3@npm:^5.0.1":
+ version: 5.0.4
+ resolution: "eventemitter3@npm:5.0.4"
+ checksum: 10c0/575b8cac8d709e1473da46f8f15ef311b57ff7609445a7c71af5cd42598583eee6f098fa7a593e30f27e94b8865642baa0689e8fa97c016f742abdb3b1bf6d9a
+ languageName: node
+ linkType: hard
+
"execa@npm:^5.0.0":
version: 5.1.1
resolution: "execa@npm:5.1.1"
@@ -4444,12 +4762,12 @@ __metadata:
languageName: node
linkType: hard
-"file-entry-cache@npm:^8.0.0":
- version: 8.0.0
- resolution: "file-entry-cache@npm:8.0.0"
+"file-entry-cache@npm:^6.0.1":
+ version: 6.0.1
+ resolution: "file-entry-cache@npm:6.0.1"
dependencies:
- flat-cache: "npm:^4.0.0"
- checksum: 10c0/9e2b5938b1cd9b6d7e3612bdc533afd4ac17b2fc646569e9a8abbf2eb48e5eb8e316bc38815a3ef6a1b456f4107f0d0f055a614ca613e75db6bf9ff4d72c1638
+ flat-cache: "npm:^3.0.4"
+ checksum: 10c0/58473e8a82794d01b38e5e435f6feaf648e3f36fdb3a56e98f417f4efae71ad1c0d4ebd8a9a7c50c3ad085820a93fc7494ad721e0e4ebc1da3573f4e1c3c7cdd
languageName: node
linkType: hard
@@ -4482,13 +4800,14 @@ __metadata:
languageName: node
linkType: hard
-"flat-cache@npm:^4.0.0":
- version: 4.0.1
- resolution: "flat-cache@npm:4.0.1"
+"flat-cache@npm:^3.0.4":
+ version: 3.2.0
+ resolution: "flat-cache@npm:3.2.0"
dependencies:
flatted: "npm:^3.2.9"
- keyv: "npm:^4.5.4"
- checksum: 10c0/2c59d93e9faa2523e4fda6b4ada749bed432cfa28c8e251f33b25795e426a1c6dbada777afb1f74fcfff33934fdbdea921ee738fcc33e71adc9d6eca984a1cfc
+ keyv: "npm:^4.5.3"
+ rimraf: "npm:^3.0.2"
+ checksum: 10c0/b76f611bd5f5d68f7ae632e3ae503e678d205cf97a17c6ab5b12f6ca61188b5f1f7464503efae6dc18683ed8f0b41460beb48ac4b9ac63fe6201296a91ba2f75
languageName: node
linkType: hard
@@ -4519,6 +4838,16 @@ __metadata:
languageName: node
linkType: hard
+"foreground-child@npm:^3.1.0":
+ version: 3.3.1
+ resolution: "foreground-child@npm:3.3.1"
+ dependencies:
+ cross-spawn: "npm:^7.0.6"
+ signal-exit: "npm:^4.0.1"
+ checksum: 10c0/8986e4af2430896e65bc2788d6679067294d6aee9545daefc84923a0a4b399ad9c7a3ea7bd8c0b2b80fdf4a92de4c69df3f628233ff3224260e9c1541a9e9ed3
+ languageName: node
+ linkType: hard
+
"forever-agent@npm:~0.6.1":
version: 0.6.1
resolution: "forever-agent@npm:0.6.1"
@@ -4634,6 +4963,13 @@ __metadata:
languageName: node
linkType: hard
+"get-east-asian-width@npm:^1.0.0, get-east-asian-width@npm:^1.3.1, get-east-asian-width@npm:^1.5.0":
+ version: 1.5.0
+ resolution: "get-east-asian-width@npm:1.5.0"
+ checksum: 10c0/bff8bbc8d81790b9477f7aa55b1806b9f082a8dc1359fff7bd8b96939622c86b729685afc2bfeb22def1fc6ef1e5228e4d87dd4e6da60bc43a5edfb03c4ee167
+ languageName: node
+ linkType: hard
+
"get-intrinsic@npm:^1.2.4, get-intrinsic@npm:^1.2.5, get-intrinsic@npm:^1.2.6, get-intrinsic@npm:^1.2.7, get-intrinsic@npm:^1.3.0":
version: 1.3.1
resolution: "get-intrinsic@npm:1.3.1"
@@ -4709,6 +5045,15 @@ __metadata:
languageName: node
linkType: hard
+"get-tsconfig@npm:^4.10.0":
+ version: 4.13.6
+ resolution: "get-tsconfig@npm:4.13.6"
+ dependencies:
+ resolve-pkg-maps: "npm:^1.0.0"
+ checksum: 10c0/bab6937302f542f97217cbe7cbbdfa7e85a56a377bc7a73e69224c1f0b7c9ae8365918e55752ae8648265903f506c1705f63c0de1d4bab1ec2830fef3e539a1a
+ languageName: node
+ linkType: hard
+
"getpass@npm:^0.1.1":
version: 0.1.7
resolution: "getpass@npm:0.1.7"
@@ -4757,6 +5102,21 @@ __metadata:
languageName: node
linkType: hard
+"glob@npm:10.3.10":
+ version: 10.3.10
+ resolution: "glob@npm:10.3.10"
+ dependencies:
+ foreground-child: "npm:^3.1.0"
+ jackspeak: "npm:^2.3.5"
+ minimatch: "npm:^9.0.1"
+ minipass: "npm:^5.0.0 || ^6.0.2 || ^7.0.0"
+ path-scurry: "npm:^1.10.1"
+ bin:
+ glob: dist/esm/bin.mjs
+ checksum: 10c0/13d8a1feb7eac7945f8c8480e11cd4a44b24d26503d99a8d8ac8d5aefbf3e9802a2b6087318a829fad04cb4e829f25c5f4f1110c68966c498720dd261c7e344d
+ languageName: node
+ linkType: hard
+
"glob@npm:^13.0.0":
version: 13.0.5
resolution: "glob@npm:13.0.5"
@@ -4802,6 +5162,15 @@ __metadata:
languageName: node
linkType: hard
+"globals@npm:^13.19.0":
+ version: 13.24.0
+ resolution: "globals@npm:13.24.0"
+ dependencies:
+ type-fest: "npm:^0.20.2"
+ checksum: 10c0/d3c11aeea898eb83d5ec7a99508600fbe8f83d2cf00cbb77f873dbf2bcb39428eff1b538e4915c993d8a3b3473fa71eeebfe22c9bb3a3003d1e26b1f2c8a42cd
+ languageName: node
+ linkType: hard
+
"globals@npm:^14.0.0":
version: 14.0.0
resolution: "globals@npm:14.0.0"
@@ -4854,6 +5223,13 @@ __metadata:
languageName: node
linkType: hard
+"graphemer@npm:^1.4.0":
+ version: 1.4.0
+ resolution: "graphemer@npm:1.4.0"
+ checksum: 10c0/e951259d8cd2e0d196c72ec711add7115d42eb9a8146c8eeda5b8d3ac91e5dd816b9cd68920726d9fd4490368e7ed86e9c423f40db87e2d8dfafa00fa17c3a31
+ languageName: node
+ linkType: hard
+
"gzip-size@npm:^6.0.0":
version: 6.0.0
resolution: "gzip-size@npm:6.0.0"
@@ -5065,6 +5441,15 @@ __metadata:
languageName: node
linkType: hard
+"husky@npm:^9.0.0":
+ version: 9.1.7
+ resolution: "husky@npm:9.1.7"
+ bin:
+ husky: bin.js
+ checksum: 10c0/35bb110a71086c48906aa7cd3ed4913fb913823715359d65e32e0b964cb1e255593b0ae8014a5005c66a68e6fa66c38dcfa8056dbbdfb8b0187c0ffe7ee3a58f
+ languageName: node
+ linkType: hard
+
"iconv-lite@npm:0.6.3, iconv-lite@npm:^0.6.2":
version: 0.6.3
resolution: "iconv-lite@npm:0.6.3"
@@ -5255,6 +5640,15 @@ __metadata:
languageName: node
linkType: hard
+"is-bun-module@npm:^2.0.0":
+ version: 2.0.0
+ resolution: "is-bun-module@npm:2.0.0"
+ dependencies:
+ semver: "npm:^7.7.1"
+ checksum: 10c0/7d27a0679cfa5be1f5052650391f9b11040cd70c48d45112e312c56bc6b6ca9c9aea70dcce6cc40b1e8947bfff8567a5c5715d3b066fb478522dab46ea379240
+ languageName: node
+ linkType: hard
+
"is-callable@npm:^1.2.7":
version: 1.2.7
resolution: "is-callable@npm:1.2.7"
@@ -5315,6 +5709,15 @@ __metadata:
languageName: node
linkType: hard
+"is-fullwidth-code-point@npm:^5.0.0":
+ version: 5.1.0
+ resolution: "is-fullwidth-code-point@npm:5.1.0"
+ dependencies:
+ get-east-asian-width: "npm:^1.3.1"
+ checksum: 10c0/c1172c2e417fb73470c56c431851681591f6a17233603a9e6f94b7ba870b2e8a5266506490573b607fb1081318589372034aa436aec07b465c2029c0bc7f07a4
+ languageName: node
+ linkType: hard
+
"is-generator-fn@npm:^2.0.0":
version: 2.1.0
resolution: "is-generator-fn@npm:2.1.0"
@@ -5384,6 +5787,13 @@ __metadata:
languageName: node
linkType: hard
+"is-path-inside@npm:^3.0.3":
+ version: 3.0.3
+ resolution: "is-path-inside@npm:3.0.3"
+ checksum: 10c0/cf7d4ac35fb96bab6a1d2c3598fe5ebb29aafb52c0aaa482b5a3ed9d8ba3edc11631e3ec2637660c44b3ce0e61a08d54946e8af30dec0b60a7c27296c68ffd05
+ languageName: node
+ linkType: hard
+
"is-plain-object@npm:^5.0.0":
version: 5.0.0
resolution: "is-plain-object@npm:5.0.0"
@@ -5603,6 +6013,19 @@ __metadata:
languageName: node
linkType: hard
+"jackspeak@npm:^2.3.5":
+ version: 2.3.6
+ resolution: "jackspeak@npm:2.3.6"
+ dependencies:
+ "@isaacs/cliui": "npm:^8.0.2"
+ "@pkgjs/parseargs": "npm:^0.11.0"
+ dependenciesMeta:
+ "@pkgjs/parseargs":
+ optional: true
+ checksum: 10c0/f01d8f972d894cd7638bc338e9ef5ddb86f7b208ce177a36d718eac96ec86638a6efa17d0221b10073e64b45edc2ce15340db9380b1f5d5c5d000cbc517dc111
+ languageName: node
+ linkType: hard
+
"jest-changed-files@npm:^29.7.0":
version: 29.7.0
resolution: "jest-changed-files@npm:29.7.0"
@@ -6354,7 +6777,7 @@ __metadata:
languageName: node
linkType: hard
-"keyv@npm:^4.5.4":
+"keyv@npm:^4.5.3":
version: 4.5.4
resolution: "keyv@npm:4.5.4"
dependencies:
@@ -6451,6 +6874,37 @@ __metadata:
languageName: node
linkType: hard
+"lint-staged@npm:^16.2.4":
+ version: 16.2.7
+ resolution: "lint-staged@npm:16.2.7"
+ dependencies:
+ commander: "npm:^14.0.2"
+ listr2: "npm:^9.0.5"
+ micromatch: "npm:^4.0.8"
+ nano-spawn: "npm:^2.0.0"
+ pidtree: "npm:^0.6.0"
+ string-argv: "npm:^0.3.2"
+ yaml: "npm:^2.8.1"
+ bin:
+ lint-staged: bin/lint-staged.js
+ checksum: 10c0/9a677c21a8112d823ae5bc565ba2c9e7b803786f2a021c46827a55fe44ed59def96edb24fc99c06a2545cdbbf366022ad82addcb3bf60c712f3b98ef92069717
+ languageName: node
+ linkType: hard
+
+"listr2@npm:^9.0.5":
+ version: 9.0.5
+ resolution: "listr2@npm:9.0.5"
+ dependencies:
+ cli-truncate: "npm:^5.0.0"
+ colorette: "npm:^2.0.20"
+ eventemitter3: "npm:^5.0.1"
+ log-update: "npm:^6.1.0"
+ rfdc: "npm:^1.4.1"
+ wrap-ansi: "npm:^9.0.0"
+ checksum: 10c0/46448d1ba0addc9d71aeafd05bb8e86ded9641ccad930ac302c2bd2ad71580375604743e18586fcb8f11906edf98e8e17fca75ba0759947bf275d381f68e311d
+ languageName: node
+ linkType: hard
+
"locate-path@npm:^5.0.0":
version: 5.0.0
resolution: "locate-path@npm:5.0.0"
@@ -6504,6 +6958,19 @@ __metadata:
languageName: node
linkType: hard
+"log-update@npm:^6.1.0":
+ version: 6.1.0
+ resolution: "log-update@npm:6.1.0"
+ dependencies:
+ ansi-escapes: "npm:^7.0.0"
+ cli-cursor: "npm:^5.0.0"
+ slice-ansi: "npm:^7.1.0"
+ strip-ansi: "npm:^7.1.0"
+ wrap-ansi: "npm:^9.0.0"
+ checksum: 10c0/4b350c0a83d7753fea34dcac6cd797d1dc9603291565de009baa4aa91c0447eab0d3815a05c8ec9ac04fdfffb43c82adcdb03ec1fceafd8518e1a8c1cff4ff89
+ languageName: node
+ linkType: hard
+
"loose-envify@npm:^1.1.0, loose-envify@npm:^1.4.0":
version: 1.4.0
resolution: "loose-envify@npm:1.4.0"
@@ -6515,6 +6982,13 @@ __metadata:
languageName: node
linkType: hard
+"lru-cache@npm:^10.2.0":
+ version: 10.4.3
+ resolution: "lru-cache@npm:10.4.3"
+ checksum: 10c0/ebd04fbca961e6c1d6c0af3799adcc966a1babe798f685bb84e6599266599cd95d94630b10262f5424539bc4640107e8a33aa28585374abf561d30d16f4b39fb
+ languageName: node
+ linkType: hard
+
"lru-cache@npm:^11.0.0, lru-cache@npm:^11.1.0, lru-cache@npm:^11.2.1":
version: 11.2.6
resolution: "lru-cache@npm:11.2.6"
@@ -6659,6 +7133,13 @@ __metadata:
languageName: node
linkType: hard
+"mimic-function@npm:^5.0.0":
+ version: 5.0.1
+ resolution: "mimic-function@npm:5.0.1"
+ checksum: 10c0/f3d9464dd1816ecf6bdf2aec6ba32c0728022039d992f178237d8e289b48764fee4131319e72eedd4f7f094e22ded0af836c3187a7edc4595d28dd74368fd81d
+ languageName: node
+ linkType: hard
+
"minimatch@npm:^10.2.1":
version: 10.2.1
resolution: "minimatch@npm:10.2.1"
@@ -6677,7 +7158,7 @@ __metadata:
languageName: node
linkType: hard
-"minimatch@npm:^3.1.2":
+"minimatch@npm:^3.0.5, minimatch@npm:^3.1.2":
version: 3.1.2
resolution: "minimatch@npm:3.1.2"
dependencies:
@@ -6686,7 +7167,7 @@ __metadata:
languageName: node
linkType: hard
-"minimatch@npm:^9.0.5":
+"minimatch@npm:^9.0.1, minimatch@npm:^9.0.5":
version: 9.0.5
resolution: "minimatch@npm:9.0.5"
dependencies:
@@ -6769,6 +7250,13 @@ __metadata:
languageName: node
linkType: hard
+"minipass@npm:^5.0.0 || ^6.0.2 || ^7.0.0":
+ version: 7.1.3
+ resolution: "minipass@npm:7.1.3"
+ checksum: 10c0/539da88daca16533211ea5a9ee98dc62ff5742f531f54640dd34429e621955e91cc280a91a776026264b7f9f6735947629f920944e9c1558369e8bf22eb33fbb
+ languageName: node
+ linkType: hard
+
"minipass@npm:^7.0.2, minipass@npm:^7.0.3, minipass@npm:^7.0.4, minipass@npm:^7.1.2":
version: 7.1.2
resolution: "minipass@npm:7.1.2"
@@ -6881,6 +7369,13 @@ __metadata:
languageName: node
linkType: hard
+"nano-spawn@npm:^2.0.0":
+ version: 2.0.0
+ resolution: "nano-spawn@npm:2.0.0"
+ checksum: 10c0/d00f9b5739f86e28cb732ffd774793e110810cded246b8393c75c4f22674af47f98ee37b19f022ada2d8c9425f800e841caa0662fbff4c0930a10e39339fb366
+ languageName: node
+ linkType: hard
+
"nanoid@npm:^3.3.11, nanoid@npm:^3.3.6, nanoid@npm:^3.3.7":
version: 3.3.11
resolution: "nanoid@npm:3.3.11"
@@ -6890,6 +7385,15 @@ __metadata:
languageName: node
linkType: hard
+"napi-postinstall@npm:^0.3.0":
+ version: 0.3.4
+ resolution: "napi-postinstall@npm:0.3.4"
+ bin:
+ napi-postinstall: lib/cli.js
+ checksum: 10c0/b33d64150828bdade3a5d07368a8b30da22ee393f8dd8432f1b9e5486867be21c84ec443dd875dd3ef3c7401a079a7ab7e2aa9d3538a889abbcd96495d5104fe
+ languageName: node
+ linkType: hard
+
"natural-compare@npm:^1.4.0":
version: 1.4.0
resolution: "natural-compare@npm:1.4.0"
@@ -7171,7 +7675,7 @@ __metadata:
languageName: node
linkType: hard
-"object.assign@npm:^4.1.2, object.assign@npm:^4.1.4, object.assign@npm:^4.1.7":
+"object.assign@npm:^4.1.4, object.assign@npm:^4.1.7":
version: 4.1.7
resolution: "object.assign@npm:4.1.7"
dependencies:
@@ -7185,7 +7689,7 @@ __metadata:
languageName: node
linkType: hard
-"object.entries@npm:^1.1.5, object.entries@npm:^1.1.9":
+"object.entries@npm:^1.1.9":
version: 1.1.9
resolution: "object.entries@npm:1.1.9"
dependencies:
@@ -7257,6 +7761,15 @@ __metadata:
languageName: node
linkType: hard
+"onetime@npm:^7.0.0":
+ version: 7.0.0
+ resolution: "onetime@npm:7.0.0"
+ dependencies:
+ mimic-function: "npm:^5.0.0"
+ checksum: 10c0/5cb9179d74b63f52a196a2e7037ba2b9a893245a5532d3f44360012005c9cadb60851d56716ebff18a6f47129dab7168022445df47c2aff3b276d92585ed1221
+ languageName: node
+ linkType: hard
+
"opener@npm:^1.5.2":
version: 1.5.2
resolution: "opener@npm:1.5.2"
@@ -7408,6 +7921,16 @@ __metadata:
languageName: node
linkType: hard
+"path-scurry@npm:^1.10.1":
+ version: 1.11.1
+ resolution: "path-scurry@npm:1.11.1"
+ dependencies:
+ lru-cache: "npm:^10.2.0"
+ minipass: "npm:^5.0.0 || ^6.0.2 || ^7.0.0"
+ checksum: 10c0/32a13711a2a505616ae1cc1b5076801e453e7aae6ac40ab55b388bb91b9d0547a52f5aaceff710ea400205f18691120d4431e520afbe4266b836fadede15872d
+ languageName: node
+ linkType: hard
+
"path-scurry@npm:^2.0.0":
version: 2.0.1
resolution: "path-scurry@npm:2.0.1"
@@ -7460,6 +7983,15 @@ __metadata:
languageName: node
linkType: hard
+"pidtree@npm:^0.6.0":
+ version: 0.6.0
+ resolution: "pidtree@npm:0.6.0"
+ bin:
+ pidtree: bin/pidtree.js
+ checksum: 10c0/0829ec4e9209e230f74ebf4265f5ccc9ebfb488334b525cb13f86ff801dca44b362c41252cd43ae4d7653a10a5c6ab3be39d2c79064d6895e0d78dc50a5ed6e9
+ languageName: node
+ linkType: hard
+
"pirates@npm:^4.0.4":
version: 4.0.7
resolution: "pirates@npm:4.0.7"
@@ -7570,6 +8102,15 @@ __metadata:
languageName: node
linkType: hard
+"prettier@npm:^3.8.1":
+ version: 3.8.1
+ resolution: "prettier@npm:3.8.1"
+ bin:
+ prettier: bin/prettier.cjs
+ checksum: 10c0/33169b594009e48f570471271be7eac7cdcf88a209eed39ac3b8d6d78984039bfa9132f82b7e6ba3b06711f3bfe0222a62a1bfb87c43f50c25a83df1b78a2c42
+ languageName: node
+ linkType: hard
+
"pretty-format@npm:30.2.0, pretty-format@npm:^30.0.0":
version: 30.2.0
resolution: "pretty-format@npm:30.2.0"
@@ -7995,6 +8536,13 @@ __metadata:
languageName: node
linkType: hard
+"resolve-pkg-maps@npm:^1.0.0":
+ version: 1.0.0
+ resolution: "resolve-pkg-maps@npm:1.0.0"
+ checksum: 10c0/fb8f7bbe2ca281a73b7ef423a1cbc786fb244bd7a95cbe5c3fba25b27d327150beca8ba02f622baea65919a57e061eb5005204daa5f93ed590d9b77463a567ab
+ languageName: node
+ linkType: hard
+
"resolve.exports@npm:^2.0.0":
version: 2.0.3
resolution: "resolve.exports@npm:2.0.3"
@@ -8080,6 +8628,16 @@ __metadata:
languageName: node
linkType: hard
+"restore-cursor@npm:^5.0.0":
+ version: 5.1.0
+ resolution: "restore-cursor@npm:5.1.0"
+ dependencies:
+ onetime: "npm:^7.0.0"
+ signal-exit: "npm:^4.1.0"
+ checksum: 10c0/c2ba89131eea791d1b25205bdfdc86699767e2b88dee2a590b1a6caa51737deac8bad0260a5ded2f7c074b7db2f3a626bcf1fcf3cdf35974cbeea5e2e6764f60
+ languageName: node
+ linkType: hard
+
"retry@npm:^0.12.0":
version: 0.12.0
resolution: "retry@npm:0.12.0"
@@ -8094,6 +8652,24 @@ __metadata:
languageName: node
linkType: hard
+"rfdc@npm:^1.4.1":
+ version: 1.4.1
+ resolution: "rfdc@npm:1.4.1"
+ checksum: 10c0/4614e4292356cafade0b6031527eea9bc90f2372a22c012313be1dcc69a3b90c7338158b414539be863fa95bfcb2ddcd0587be696841af4e6679d85e62c060c7
+ languageName: node
+ linkType: hard
+
+"rimraf@npm:^3.0.2":
+ version: 3.0.2
+ resolution: "rimraf@npm:3.0.2"
+ dependencies:
+ glob: "npm:^7.1.3"
+ bin:
+ rimraf: bin.js
+ checksum: 10c0/9cb7757acb489bd83757ba1a274ab545eafd75598a9d817e0c3f8b164238dd90eba50d6b848bd4dcc5f3040912e882dc7ba71653e35af660d77b25c381d402e8
+ languageName: node
+ linkType: hard
+
"run-parallel@npm:^1.1.9":
version: 1.2.0
resolution: "run-parallel@npm:1.2.0"
@@ -8187,7 +8763,7 @@ __metadata:
languageName: node
linkType: hard
-"semver@npm:^7.1.1, semver@npm:^7.3.5, semver@npm:^7.5.3, semver@npm:^7.5.4, semver@npm:^7.7.3":
+"semver@npm:^7.1.1, semver@npm:^7.3.5, semver@npm:^7.5.3, semver@npm:^7.5.4, semver@npm:^7.7.1, semver@npm:^7.7.3":
version: 7.7.4
resolution: "semver@npm:7.7.4"
bin:
@@ -8318,7 +8894,7 @@ __metadata:
languageName: node
linkType: hard
-"signal-exit@npm:^4.0.1":
+"signal-exit@npm:^4.0.1, signal-exit@npm:^4.1.0":
version: 4.1.0
resolution: "signal-exit@npm:4.1.0"
checksum: 10c0/41602dce540e46d599edba9d9860193398d135f7ff72cab629db5171516cfae628d21e7bfccde1bbfdf11c48726bc2a6d1a8fb8701125852fbfda7cf19c6aa83
@@ -8361,6 +8937,16 @@ __metadata:
languageName: node
linkType: hard
+"slice-ansi@npm:^7.1.0":
+ version: 7.1.2
+ resolution: "slice-ansi@npm:7.1.2"
+ dependencies:
+ ansi-styles: "npm:^6.2.1"
+ is-fullwidth-code-point: "npm:^5.0.0"
+ checksum: 10c0/36742f2eb0c03e2e81a38ed14d13a64f7b732fe38c3faf96cce0599788a345011e840db35f1430ca606ea3f8db2abeb92a8d25c2753a819e3babaa10c2e289a2
+ languageName: node
+ linkType: hard
+
"smart-buffer@npm:^4.2.0":
version: 4.2.0
resolution: "smart-buffer@npm:4.2.0"
@@ -8500,6 +9086,13 @@ __metadata:
languageName: node
linkType: hard
+"stable-hash@npm:^0.0.5":
+ version: 0.0.5
+ resolution: "stable-hash@npm:0.0.5"
+ checksum: 10c0/ca670cb6d172f1c834950e4ec661e2055885df32fee3ebf3647c5df94993b7c2666a5dbc1c9a62ee11fc5c24928579ec5e81bb5ad31971d355d5a341aab493b3
+ languageName: node
+ linkType: hard
+
"stack-utils@npm:^2.0.3, stack-utils@npm:^2.0.6":
version: 2.0.6
resolution: "stack-utils@npm:2.0.6"
@@ -8526,6 +9119,13 @@ __metadata:
languageName: node
linkType: hard
+"string-argv@npm:^0.3.2":
+ version: 0.3.2
+ resolution: "string-argv@npm:0.3.2"
+ checksum: 10c0/75c02a83759ad1722e040b86823909d9a2fc75d15dd71ec4b537c3560746e33b5f5a07f7332d1e3f88319909f82190843aa2f0a0d8c8d591ec08e93d5b8dec82
+ languageName: node
+ linkType: hard
+
"string-length@npm:^4.0.1":
version: 4.0.2
resolution: "string-length@npm:4.0.2"
@@ -8536,7 +9136,7 @@ __metadata:
languageName: node
linkType: hard
-"string-width@npm:^4.1.0, string-width@npm:^4.2.0":
+"string-width-cjs@npm:string-width@^4.2.0, string-width@npm:^4.1.0, string-width@npm:^4.2.0":
version: 4.2.0
resolution: "string-width@npm:4.2.0"
dependencies:
@@ -8558,6 +9158,38 @@ __metadata:
languageName: node
linkType: hard
+"string-width@npm:^5.0.1, string-width@npm:^5.1.2":
+ version: 5.1.2
+ resolution: "string-width@npm:5.1.2"
+ dependencies:
+ eastasianwidth: "npm:^0.2.0"
+ emoji-regex: "npm:^9.2.2"
+ strip-ansi: "npm:^7.0.1"
+ checksum: 10c0/ab9c4264443d35b8b923cbdd513a089a60de339216d3b0ed3be3ba57d6880e1a192b70ae17225f764d7adbf5994e9bb8df253a944736c15a0240eff553c678ca
+ languageName: node
+ linkType: hard
+
+"string-width@npm:^7.0.0":
+ version: 7.2.0
+ resolution: "string-width@npm:7.2.0"
+ dependencies:
+ emoji-regex: "npm:^10.3.0"
+ get-east-asian-width: "npm:^1.0.0"
+ strip-ansi: "npm:^7.1.0"
+ checksum: 10c0/eb0430dd43f3199c7a46dcbf7a0b34539c76fe3aa62763d0b0655acdcbdf360b3f66f3d58ca25ba0205f42ea3491fa00f09426d3b7d3040e506878fc7664c9b9
+ languageName: node
+ linkType: hard
+
+"string-width@npm:^8.0.0":
+ version: 8.2.0
+ resolution: "string-width@npm:8.2.0"
+ dependencies:
+ get-east-asian-width: "npm:^1.5.0"
+ strip-ansi: "npm:^7.1.2"
+ checksum: 10c0/d8915428b43519b0f494da6590dbe4491857d8a12e40250e50fc01fbb616ffd8400a436bbe25712255ee129511fe0414c49d3b6b9627e2bc3a33dcec1d2eda02
+ languageName: node
+ linkType: hard
+
"string.prototype.includes@npm:^2.0.1":
version: 2.0.1
resolution: "string.prototype.includes@npm:2.0.1"
@@ -8638,6 +9270,15 @@ __metadata:
languageName: node
linkType: hard
+"strip-ansi-cjs@npm:strip-ansi@^6.0.1, strip-ansi@npm:^6.0.1":
+ version: 6.0.1
+ resolution: "strip-ansi@npm:6.0.1"
+ dependencies:
+ ansi-regex: "npm:^5.0.1"
+ checksum: 10c0/1ae5f212a126fe5b167707f716942490e3933085a5ff6c008ab97ab2f272c8025d3aa218b7bd6ab25729ca20cc81cddb252102f8751e13482a5199e873680952
+ languageName: node
+ linkType: hard
+
"strip-ansi@npm:^6.0.0":
version: 6.0.0
resolution: "strip-ansi@npm:6.0.0"
@@ -8647,12 +9288,12 @@ __metadata:
languageName: node
linkType: hard
-"strip-ansi@npm:^6.0.1":
- version: 6.0.1
- resolution: "strip-ansi@npm:6.0.1"
+"strip-ansi@npm:^7.0.1, strip-ansi@npm:^7.1.0, strip-ansi@npm:^7.1.2":
+ version: 7.1.2
+ resolution: "strip-ansi@npm:7.1.2"
dependencies:
- ansi-regex: "npm:^5.0.1"
- checksum: 10c0/1ae5f212a126fe5b167707f716942490e3933085a5ff6c008ab97ab2f272c8025d3aa218b7bd6ab25729ca20cc81cddb252102f8751e13482a5199e873680952
+ ansi-regex: "npm:^6.0.1"
+ checksum: 10c0/0d6d7a023de33368fd042aab0bf48f4f4077abdfd60e5393e73c7c411e85e1b3a83507c11af2e656188511475776215df9ca589b4da2295c9455cc399ce1858b
languageName: node
linkType: hard
@@ -8941,6 +9582,13 @@ __metadata:
languageName: node
linkType: hard
+"text-table@npm:^0.2.0":
+ version: 0.2.0
+ resolution: "text-table@npm:0.2.0"
+ checksum: 10c0/02805740c12851ea5982686810702e2f14369a5f4c5c40a836821e3eefc65ffeec3131ba324692a37608294b0fd8c1e55a2dd571ffed4909822787668ddbee5c
+ languageName: node
+ linkType: hard
+
"through@npm:^2.3.4":
version: 2.3.8
resolution: "through@npm:2.3.8"
@@ -8948,7 +9596,7 @@ __metadata:
languageName: node
linkType: hard
-"tinyglobby@npm:^0.2.12, tinyglobby@npm:^0.2.15":
+"tinyglobby@npm:^0.2.12, tinyglobby@npm:^0.2.13, tinyglobby@npm:^0.2.15":
version: 0.2.15
resolution: "tinyglobby@npm:0.2.15"
dependencies:
@@ -9095,6 +9743,13 @@ __metadata:
languageName: node
linkType: hard
+"type-fest@npm:^0.20.2":
+ version: 0.20.2
+ resolution: "type-fest@npm:0.20.2"
+ checksum: 10c0/dea9df45ea1f0aaa4e2d3bed3f9a0bfe9e5b2592bddb92eb1bf06e50bcf98dbb78189668cd8bc31a0511d3fc25539b4cd5c704497e53e93e2d40ca764b10bfc3
+ languageName: node
+ linkType: hard
+
"type-fest@npm:^0.8.1":
version: 0.8.1
resolution: "type-fest@npm:0.8.1"
@@ -9240,6 +9895,73 @@ __metadata:
languageName: node
linkType: hard
+"unrs-resolver@npm:^1.6.2":
+ version: 1.11.1
+ resolution: "unrs-resolver@npm:1.11.1"
+ dependencies:
+ "@unrs/resolver-binding-android-arm-eabi": "npm:1.11.1"
+ "@unrs/resolver-binding-android-arm64": "npm:1.11.1"
+ "@unrs/resolver-binding-darwin-arm64": "npm:1.11.1"
+ "@unrs/resolver-binding-darwin-x64": "npm:1.11.1"
+ "@unrs/resolver-binding-freebsd-x64": "npm:1.11.1"
+ "@unrs/resolver-binding-linux-arm-gnueabihf": "npm:1.11.1"
+ "@unrs/resolver-binding-linux-arm-musleabihf": "npm:1.11.1"
+ "@unrs/resolver-binding-linux-arm64-gnu": "npm:1.11.1"
+ "@unrs/resolver-binding-linux-arm64-musl": "npm:1.11.1"
+ "@unrs/resolver-binding-linux-ppc64-gnu": "npm:1.11.1"
+ "@unrs/resolver-binding-linux-riscv64-gnu": "npm:1.11.1"
+ "@unrs/resolver-binding-linux-riscv64-musl": "npm:1.11.1"
+ "@unrs/resolver-binding-linux-s390x-gnu": "npm:1.11.1"
+ "@unrs/resolver-binding-linux-x64-gnu": "npm:1.11.1"
+ "@unrs/resolver-binding-linux-x64-musl": "npm:1.11.1"
+ "@unrs/resolver-binding-wasm32-wasi": "npm:1.11.1"
+ "@unrs/resolver-binding-win32-arm64-msvc": "npm:1.11.1"
+ "@unrs/resolver-binding-win32-ia32-msvc": "npm:1.11.1"
+ "@unrs/resolver-binding-win32-x64-msvc": "npm:1.11.1"
+ napi-postinstall: "npm:^0.3.0"
+ dependenciesMeta:
+ "@unrs/resolver-binding-android-arm-eabi":
+ optional: true
+ "@unrs/resolver-binding-android-arm64":
+ optional: true
+ "@unrs/resolver-binding-darwin-arm64":
+ optional: true
+ "@unrs/resolver-binding-darwin-x64":
+ optional: true
+ "@unrs/resolver-binding-freebsd-x64":
+ optional: true
+ "@unrs/resolver-binding-linux-arm-gnueabihf":
+ optional: true
+ "@unrs/resolver-binding-linux-arm-musleabihf":
+ optional: true
+ "@unrs/resolver-binding-linux-arm64-gnu":
+ optional: true
+ "@unrs/resolver-binding-linux-arm64-musl":
+ optional: true
+ "@unrs/resolver-binding-linux-ppc64-gnu":
+ optional: true
+ "@unrs/resolver-binding-linux-riscv64-gnu":
+ optional: true
+ "@unrs/resolver-binding-linux-riscv64-musl":
+ optional: true
+ "@unrs/resolver-binding-linux-s390x-gnu":
+ optional: true
+ "@unrs/resolver-binding-linux-x64-gnu":
+ optional: true
+ "@unrs/resolver-binding-linux-x64-musl":
+ optional: true
+ "@unrs/resolver-binding-wasm32-wasi":
+ optional: true
+ "@unrs/resolver-binding-win32-arm64-msvc":
+ optional: true
+ "@unrs/resolver-binding-win32-ia32-msvc":
+ optional: true
+ "@unrs/resolver-binding-win32-x64-msvc":
+ optional: true
+ checksum: 10c0/c91b112c71a33d6b24e5c708dab43ab80911f2df8ee65b87cd7a18fb5af446708e98c4b415ca262026ad8df326debcc7ca6a801b2935504d87fd6f0b9d70dce1
+ languageName: node
+ linkType: hard
+
"update-browserslist-db@npm:^1.2.0":
version: 1.2.3
resolution: "update-browserslist-db@npm:1.2.3"
@@ -9529,7 +10251,7 @@ __metadata:
languageName: node
linkType: hard
-"wrap-ansi@npm:^7.0.0":
+"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0, wrap-ansi@npm:^7.0.0":
version: 7.0.0
resolution: "wrap-ansi@npm:7.0.0"
dependencies:
@@ -9540,6 +10262,28 @@ __metadata:
languageName: node
linkType: hard
+"wrap-ansi@npm:^8.1.0":
+ version: 8.1.0
+ resolution: "wrap-ansi@npm:8.1.0"
+ dependencies:
+ ansi-styles: "npm:^6.1.0"
+ string-width: "npm:^5.0.1"
+ strip-ansi: "npm:^7.0.1"
+ checksum: 10c0/138ff58a41d2f877eae87e3282c0630fc2789012fc1af4d6bd626eeb9a2f9a65ca92005e6e69a75c7b85a68479fe7443c7dbe1eb8fbaa681a4491364b7c55c60
+ languageName: node
+ linkType: hard
+
+"wrap-ansi@npm:^9.0.0":
+ version: 9.0.2
+ resolution: "wrap-ansi@npm:9.0.2"
+ dependencies:
+ ansi-styles: "npm:^6.2.1"
+ string-width: "npm:^7.0.0"
+ strip-ansi: "npm:^7.1.0"
+ checksum: 10c0/3305839b9a0d6fb930cb63a52f34d3936013d8b0682ff3ec133c9826512620f213800ffa19ea22904876d5b7e9a3c1f40682f03597d986a4ca881fa7b033688c
+ languageName: node
+ linkType: hard
+
"wrappy@npm:1":
version: 1.0.2
resolution: "wrappy@npm:1.0.2"
@@ -9639,6 +10383,15 @@ __metadata:
languageName: node
linkType: hard
+"yaml@npm:^2.8.1":
+ version: 2.8.2
+ resolution: "yaml@npm:2.8.2"
+ bin:
+ yaml: bin.mjs
+ checksum: 10c0/703e4dc1e34b324aa66876d63618dcacb9ed49f7e7fe9b70f1e703645be8d640f68ab84f12b86df8ac960bac37acf5513e115de7c970940617ce0343c8c9cd96
+ languageName: node
+ linkType: hard
+
"yargs-parser@npm:^21.1.1":
version: 21.1.1
resolution: "yargs-parser@npm:21.1.1"