Why am I so anal about my types
This commit is contained in:
43
src/app.d.ts
vendored
43
src/app.d.ts
vendored
@@ -26,12 +26,21 @@ declare global {
|
|||||||
|
|
||||||
type serviceType = 'jellyfin' | 'youtube-music'
|
type serviceType = 'jellyfin' | 'youtube-music'
|
||||||
|
|
||||||
interface BaseConnection {
|
type Service = Jellyfin.Service | YouTubeMusic.Service
|
||||||
|
|
||||||
|
type Tokens<T> = T extends Jellyfin.Service ? Jellyfin.Tokens : T extends YouTubeMusic.Service ? YouTubeMusic.Tokens : {}
|
||||||
|
|
||||||
|
// type ServiceTokenPair = [Jellyfin.Service, Jellyfin.Tokens] | [YouTubeMusic.Service, YouTubeMusic.Tokens]
|
||||||
|
|
||||||
|
interface BaseConnection<T> {
|
||||||
id: string
|
id: string
|
||||||
userId: string
|
userId: string
|
||||||
type: serviceType
|
type: T extends Jellyfin.Service ? 'jellyfin' : T extends YouTubeMusic.Service ? 'youtube-music' : serviceType
|
||||||
|
service: T extends undefined ? Service : T
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Connection<T extends Service = undefined> = BaseConnection<T> & Tokens<T>
|
||||||
|
|
||||||
// These Schemas should only contain general info data that is necessary for data fetching purposes.
|
// These Schemas should only contain general info data that is necessary for data fetching purposes.
|
||||||
// They are NOT meant to be stores for large amounts of data, i.e. Don't include the data for every single song the Playlist type.
|
// They are NOT meant to be stores for large amounts of data, i.e. Don't include the data for every single song the Playlist type.
|
||||||
// Big data should be fetched as needed in the app, these exist to ensure that the info necessary to fetch that data is there.
|
// Big data should be fetched as needed in the app, these exist to ensure that the info necessary to fetch that data is there.
|
||||||
@@ -85,19 +94,17 @@ declare global {
|
|||||||
// The jellyfin API will not always return the data it says it will, for example /Users/AuthenticateByName says it will
|
// The jellyfin API will not always return the data it says it will, for example /Users/AuthenticateByName says it will
|
||||||
// retrun the ServerName, it wont. This must be fetched from /System/Info.
|
// retrun the ServerName, it wont. This must be fetched from /System/Info.
|
||||||
// So, ONLY DEFINE THE INTERFACES FOR DATA THAT IS GARUNTEED TO BE RETURNED (unless the data value itself is inherently optional)
|
// So, ONLY DEFINE THE INTERFACES FOR DATA THAT IS GARUNTEED TO BE RETURNED (unless the data value itself is inherently optional)
|
||||||
interface Connection<T = undefined> extends BaseConnection {
|
interface Service {
|
||||||
type: 'jellyfin'
|
userId: string
|
||||||
jellyfinUserId: string
|
|
||||||
urlOrigin: string
|
urlOrigin: string
|
||||||
accessToken: string
|
|
||||||
info?: T
|
|
||||||
}
|
|
||||||
|
|
||||||
interface ConnectionInfo {
|
|
||||||
username?: string
|
username?: string
|
||||||
serverName?: string
|
serverName?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface Tokens {
|
||||||
|
accessToken: string
|
||||||
|
}
|
||||||
|
|
||||||
interface User {
|
interface User {
|
||||||
Name: string
|
Name: string
|
||||||
Id: string
|
Id: string
|
||||||
@@ -164,17 +171,17 @@ declare global {
|
|||||||
}
|
}
|
||||||
|
|
||||||
namespace YouTubeMusic {
|
namespace YouTubeMusic {
|
||||||
interface Connection<T = undefined> extends BaseConnection {
|
interface Service {
|
||||||
type: 'youtube-music'
|
userId: string
|
||||||
youtubeUserId: string
|
|
||||||
accessToken: string
|
|
||||||
info?: T
|
|
||||||
}
|
|
||||||
|
|
||||||
interface ConnectionInfo {
|
|
||||||
username?: string
|
username?: string
|
||||||
profilePicture?: string
|
profilePicture?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface Tokens {
|
||||||
|
accessToken: string
|
||||||
|
refreshToken: string
|
||||||
|
expiry: number
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ const initUsersTable = `CREATE TABLE IF NOT EXISTS Users(
|
|||||||
const initConnectionsTable = `CREATE TABLE IF NOT EXISTS Connections(
|
const initConnectionsTable = `CREATE TABLE IF NOT EXISTS Connections(
|
||||||
id VARCHAR(36) PRIMARY KEY,
|
id VARCHAR(36) PRIMARY KEY,
|
||||||
userId VARCHAR(36) NOT NULL,
|
userId VARCHAR(36) NOT NULL,
|
||||||
|
type VARCHAR(36) NOT NULL,
|
||||||
service TEXT NOT NULL,
|
service TEXT NOT NULL,
|
||||||
accessToken TEXT NOT NULL,
|
accessToken TEXT NOT NULL,
|
||||||
refreshToken TEXT,
|
refreshToken TEXT,
|
||||||
@@ -23,6 +24,7 @@ db.exec(initUsersTable), db.exec(initConnectionsTable)
|
|||||||
interface ConnectionsTableSchema {
|
interface ConnectionsTableSchema {
|
||||||
id: string
|
id: string
|
||||||
userId: string
|
userId: string
|
||||||
|
type: string
|
||||||
service: string
|
service: string
|
||||||
accessToken: string
|
accessToken: string
|
||||||
refreshToken?: string
|
refreshToken?: string
|
||||||
@@ -71,17 +73,19 @@ export class Connections {
|
|||||||
return connections
|
return connections
|
||||||
}
|
}
|
||||||
|
|
||||||
static addConnection = (userId: string, service: Service, accessToken: string, refreshToken?: string, expiry?: number): Connection => {
|
static addConnection = (userId: string, service: Service, accessToken?: string, refreshToken?: string, expiry?: number): Connection => {
|
||||||
const connectionId = generateUUID()
|
const connectionId = generateUUID()
|
||||||
const ytConnection: YouTubeMusic.Connection = {
|
const test: Connection = {
|
||||||
id: 'test',
|
id: 'test',
|
||||||
userId: 'test',
|
userId: 'test',
|
||||||
youtubeUserId: 'test',
|
type: 'jellyfin',
|
||||||
type: 'youtube-music',
|
service: {
|
||||||
|
userId: 'test',
|
||||||
|
urlOrigin: 'test',
|
||||||
|
},
|
||||||
accessToken: 'test',
|
accessToken: 'test',
|
||||||
}
|
}
|
||||||
const test = this.insertConnection(ytConnection)
|
// if (!isValidURL(service.urlOrigin)) throw new Error('Service does not have valid url')
|
||||||
if (!isValidURL(service.urlOrigin)) throw new Error('Service does not have valid url')
|
|
||||||
db.prepare('INSERT INTO Connections(id, userId, service, accessToken, refreshToken, expiry) VALUES(?, ?, ?, ?, ?, ?)').run(connectionId, userId, JSON.stringify(service), accessToken, refreshToken, expiry)
|
db.prepare('INSERT INTO Connections(id, userId, service, accessToken, refreshToken, expiry) VALUES(?, ?, ?, ?, ?, ?)').run(connectionId, userId, JSON.stringify(service), accessToken, refreshToken, expiry)
|
||||||
return this.getConnection(connectionId)
|
return this.getConnection(connectionId)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user