mirror of
https://github.com/GiriNeko/YesPlayMusic.git
synced 2025-12-16 21:28:06 +00:00
feat: updates
This commit is contained in:
parent
ccebe0a67a
commit
9a52681687
37 changed files with 160 additions and 55332 deletions
|
|
@ -5,13 +5,12 @@
|
|||
|
||||
const pkg = require('./package.json')
|
||||
const electronVersion = pkg.devDependencies.electron.replaceAll('^', '')
|
||||
const isDev = process.env.NODE_ENV === 'development'
|
||||
|
||||
module.exports = {
|
||||
appId: 'app.r3play',
|
||||
productName: pkg.productName,
|
||||
copyright: 'Copyright © 2022 qier222',
|
||||
asar: isDev ? true : false,
|
||||
asar: true,
|
||||
directories: {
|
||||
output: 'release',
|
||||
buildResources: 'build',
|
||||
|
|
|
|||
|
|
@ -9,27 +9,32 @@ import netease from './routes/netease/netease'
|
|||
import appleMusic from './routes/r3play/appleMusic'
|
||||
import audio from './routes/r3play/audio'
|
||||
|
||||
const server = fastify({
|
||||
ignoreTrailingSlash: true,
|
||||
})
|
||||
|
||||
server.register(fastifyCookie)
|
||||
server.register(fastifyMultipart)
|
||||
if (isProd) {
|
||||
server.register(fastifyStatic, {
|
||||
root: path.join(__dirname, '../web'),
|
||||
const initAppServer = async () => {
|
||||
const server = fastify({
|
||||
ignoreTrailingSlash: true,
|
||||
})
|
||||
|
||||
server.register(fastifyCookie)
|
||||
server.register(fastifyMultipart)
|
||||
if (isProd) {
|
||||
server.register(fastifyStatic, {
|
||||
root: path.join(__dirname, '../web'),
|
||||
})
|
||||
}
|
||||
|
||||
server.register(netease)
|
||||
server.register(audio)
|
||||
server.register(appleMusic)
|
||||
|
||||
const port = Number(
|
||||
isProd
|
||||
? process.env.ELECTRON_WEB_SERVER_PORT || 42710
|
||||
: process.env.ELECTRON_DEV_NETEASE_API_PORT || 30001
|
||||
)
|
||||
await server.listen({ port })
|
||||
log.info(`[appServer] http server listening on port ${port}`)
|
||||
|
||||
return server
|
||||
}
|
||||
|
||||
server.register(netease)
|
||||
server.register(audio)
|
||||
server.register(appleMusic)
|
||||
|
||||
const port = Number(
|
||||
isProd
|
||||
? process.env.ELECTRON_WEB_SERVER_PORT || 42710
|
||||
: process.env.ELECTRON_DEV_NETEASE_API_PORT || 30001
|
||||
)
|
||||
server.listen({ port })
|
||||
|
||||
log.info(`[appServer] http server listening on port ${port}`)
|
||||
export default initAppServer
|
||||
|
|
|
|||
|
|
@ -11,7 +11,8 @@ async function netease(fastify: FastifyInstance) {
|
|||
req: FastifyRequest<{ Querystring: { [key: string]: string } }>,
|
||||
reply: FastifyReply
|
||||
) => {
|
||||
// // Get track details from cache
|
||||
console.log(req.routerPath)
|
||||
// Get track details from cache
|
||||
if (name === CacheAPIs.Track) {
|
||||
const cacheData = await cache.get(name, req.query as any)
|
||||
if (cacheData) {
|
||||
|
|
|
|||
|
|
@ -11,7 +11,8 @@ import { createTaskbar, Thumbar } from './windowsTaskbar'
|
|||
import { createMenu } from './menu'
|
||||
import { isDev, isWindows, isLinux, isMac, appName } from './env'
|
||||
import store from './store'
|
||||
import './appServer/appServer'
|
||||
import initAppServer from './appServer/appServer'
|
||||
import { initDatabase } from './prisma'
|
||||
|
||||
class Main {
|
||||
win: BrowserWindow | null = null
|
||||
|
|
@ -32,8 +33,10 @@ class Main {
|
|||
process.exit(0)
|
||||
}
|
||||
|
||||
app.whenReady().then(() => {
|
||||
app.whenReady().then(async () => {
|
||||
log.info('[index] App ready')
|
||||
await initDatabase()
|
||||
await initAppServer()
|
||||
this.createWindow()
|
||||
this.handleAppEvents()
|
||||
this.handleWindowEvents()
|
||||
|
|
|
|||
|
|
@ -1,13 +1,15 @@
|
|||
import { app } from 'electron'
|
||||
import path from 'path'
|
||||
import { PrismaClient } from '../prisma/client'
|
||||
import { isDev } from './env'
|
||||
import { isDev, isWindows } from './env'
|
||||
import log from './log'
|
||||
import { createFileIfNotExist, dirname, isFileExist } from './utils'
|
||||
import fs from 'fs'
|
||||
import { dialog } from 'electron'
|
||||
|
||||
export const dbPath = path.join(app.getPath('userData'), 'r3play.db')
|
||||
export const dbUrl = 'file://' + dbPath
|
||||
export const dbUrl = 'file:' + (isWindows ? '' : '//') + dbPath
|
||||
log.info('[prisma] dbUrl', dbUrl)
|
||||
|
||||
const extraResourcesPath = app.getAppPath().replace('app.asar', '') // impacted by extraResources setting in electron-builder.yml
|
||||
function getPlatformName(): string {
|
||||
|
|
@ -49,16 +51,9 @@ log.info('[prisma] dbUrl', dbUrl)
|
|||
// the dbUrl into the prisma client constructor in datasources.db.url
|
||||
process.env.DATABASE_URL = dbUrl
|
||||
|
||||
const isInitialized = isFileExist(dbPath)
|
||||
if (!isInitialized) {
|
||||
const from = isDev ? path.join(dirname, './prisma/r3play.db') : path.join(dirname, './r3play.db')
|
||||
log.info(`[prisma] copy r3play.db file from ${from} to ${dbPath}`)
|
||||
fs.copyFileSync(from, dbPath)
|
||||
log.info('[prisma] Database tables initialized.')
|
||||
} else {
|
||||
log.info('[prisma] Database tables already initialized before.')
|
||||
}
|
||||
createFileIfNotExist(dbPath)
|
||||
|
||||
// @ts-expect-error
|
||||
let prisma: PrismaClient = null
|
||||
try {
|
||||
prisma = new PrismaClient({
|
||||
|
|
@ -79,6 +74,29 @@ try {
|
|||
log.info('[prisma] prisma initialized')
|
||||
} catch (e) {
|
||||
log.error('[prisma] failed to init prisma', e)
|
||||
dialog.showErrorBox('Failed to init prisma', String(e))
|
||||
app.exit()
|
||||
}
|
||||
|
||||
export const initDatabase = async () => {
|
||||
try {
|
||||
const initSQLFile = fs
|
||||
.readFileSync(path.join(dirname, 'migrations/init.sql'), 'utf-8')
|
||||
.toString()
|
||||
const tables = initSQLFile.split(';')
|
||||
await Promise.all(
|
||||
tables.map(sql => {
|
||||
if (!sql.trim()) return
|
||||
return prisma.$executeRawUnsafe(sql.trim()).catch(() => {
|
||||
log.error('[prisma] failed to execute init sql >>> ', sql.trim())
|
||||
})
|
||||
})
|
||||
)
|
||||
} catch (e) {
|
||||
dialog.showErrorBox('Failed to init prisma database', String(e))
|
||||
app.exit()
|
||||
}
|
||||
log.info('[prisma] database initialized')
|
||||
}
|
||||
|
||||
export default prisma
|
||||
|
|
|
|||
|
|
@ -1,58 +1,51 @@
|
|||
-- CreateTable
|
||||
CREATE TABLE "AccountData" IF NOT EXISTS (
|
||||
CREATE TABLE IF NOT EXISTS "AccountData" (
|
||||
"id" TEXT NOT NULL PRIMARY KEY,
|
||||
"json" TEXT NOT NULL,
|
||||
"updatedAt" DATETIME NOT NULL
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "AppData" IF NOT EXISTS (
|
||||
CREATE TABLE IF NOT EXISTS "AppData" (
|
||||
"id" TEXT NOT NULL PRIMARY KEY,
|
||||
"value" TEXT NOT NULL
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "Track" IF NOT EXISTS (
|
||||
CREATE TABLE IF NOT EXISTS "Track" (
|
||||
"id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
||||
"json" TEXT NOT NULL,
|
||||
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" DATETIME NOT NULL
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "Album" IF NOT EXISTS (
|
||||
CREATE TABLE IF NOT EXISTS "Album" (
|
||||
"id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
||||
"json" TEXT NOT NULL,
|
||||
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" DATETIME NOT NULL
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "Artist" IF NOT EXISTS (
|
||||
CREATE TABLE IF NOT EXISTS "Artist" (
|
||||
"id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
||||
"json" TEXT NOT NULL,
|
||||
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" DATETIME NOT NULL
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "ArtistAlbum" IF NOT EXISTS (
|
||||
|
||||
CREATE TABLE IF NOT EXISTS "ArtistAlbum" (
|
||||
"id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
||||
"hotAlbums" TEXT NOT NULL,
|
||||
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" DATETIME NOT NULL
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "Playlist" IF NOT EXISTS (
|
||||
CREATE TABLE IF NOT EXISTS "Playlist" (
|
||||
"id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
||||
"json" TEXT NOT NULL,
|
||||
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" DATETIME NOT NULL
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "Audio" IF NOT EXISTS (
|
||||
CREATE TABLE IF NOT EXISTS "Audio" (
|
||||
"id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
||||
"bitRate" INTEGER NOT NULL,
|
||||
"format" TEXT NOT NULL,
|
||||
|
|
@ -62,59 +55,23 @@ CREATE TABLE "Audio" IF NOT EXISTS (
|
|||
"queriedAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "Lyrics" IF NOT EXISTS (
|
||||
CREATE TABLE IF NOT EXISTS "Lyrics" (
|
||||
"id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
||||
"json" TEXT NOT NULL,
|
||||
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" DATETIME NOT NULL
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "AppleMusicAlbum" IF NOT EXISTS (
|
||||
CREATE TABLE IF NOT EXISTS "AppleMusicAlbum" (
|
||||
"id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
||||
"json" TEXT NOT NULL,
|
||||
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" DATETIME NOT NULL
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "AppleMusicArtist" IF NOT EXISTS (
|
||||
CREATE TABLE IF NOT EXISTS "AppleMusicArtist" (
|
||||
"id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
||||
"json" TEXT NOT NULL,
|
||||
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" DATETIME NOT NULL
|
||||
);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS "AccountData_id_key" ON "AccountData"("id");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS "AppData_id_key" ON "AppData"("id");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS "Track_id_key" ON "Track"("id");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS "Album_id_key" ON "Album"("id");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS "Artist_id_key" ON "Artist"("id");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS "ArtistAlbum_id_key" ON "ArtistAlbum"("id");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS "Playlist_id_key" ON "Playlist"("id");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS "Audio_id_key" ON "Audio"("id");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS "Lyrics_id_key" ON "Lyrics"("id");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS "AppleMusicAlbum_id_key" ON "AppleMusicAlbum"("id");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS "AppleMusicArtist_id_key" ON "AppleMusicArtist"("id");
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
"main": "./main/index.js",
|
||||
"author": "*",
|
||||
"scripts": {
|
||||
"post-install": "tsx scripts/build.sqlite3.ts",
|
||||
"postinstall": "prisma generate",
|
||||
"dev": "tsx scripts/build.main.ts --watch",
|
||||
"build": "tsx scripts/build.main.ts",
|
||||
"pack": "electron-builder build -c .electron-builder.config.js",
|
||||
|
|
@ -25,6 +25,7 @@
|
|||
"@fastify/cookie": "^8.3.0",
|
||||
"@fastify/http-proxy": "^8.4.0",
|
||||
"@fastify/multipart": "^7.4.0",
|
||||
"@fastify/static": "^6.6.1",
|
||||
"@prisma/client": "^4.8.1",
|
||||
"@prisma/engines": "^4.9.0",
|
||||
"@sentry/electron": "^3.0.7",
|
||||
|
|
@ -35,6 +36,7 @@
|
|||
"electron-log": "^4.4.8",
|
||||
"electron-store": "^8.1.0",
|
||||
"fast-folder-size": "^1.7.1",
|
||||
"fastify": "^4.5.3",
|
||||
"pretty-bytes": "^6.0.0",
|
||||
"prisma": "^4.8.1",
|
||||
"ytdl-core": "^4.11.2"
|
||||
|
|
@ -44,7 +46,7 @@
|
|||
"axios": "^1.2.1",
|
||||
"cross-env": "^7.0.3",
|
||||
"dotenv": "^16.0.3",
|
||||
"electron": "^22.0.0",
|
||||
"electron": "^22.1.0",
|
||||
"electron-builder": "23.6.0",
|
||||
"electron-devtools-installer": "^3.2.0",
|
||||
"electron-rebuild": "^3.2.9",
|
||||
|
|
|
|||
|
|
@ -1,206 +0,0 @@
|
|||
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
|
||||
const {
|
||||
Decimal,
|
||||
objectEnumValues,
|
||||
makeStrictEnum
|
||||
} = require('./runtime/index-browser')
|
||||
|
||||
|
||||
const Prisma = {}
|
||||
|
||||
exports.Prisma = Prisma
|
||||
|
||||
/**
|
||||
* Prisma Client JS version: 4.8.1
|
||||
* Query Engine version: d6e67a83f971b175a593ccc12e15c4a757f93ffe
|
||||
*/
|
||||
Prisma.prismaVersion = {
|
||||
client: "4.8.1",
|
||||
engine: "d6e67a83f971b175a593ccc12e15c4a757f93ffe"
|
||||
}
|
||||
|
||||
Prisma.PrismaClientKnownRequestError = () => {
|
||||
throw new Error(`PrismaClientKnownRequestError is unable to be run in the browser.
|
||||
In case this error is unexpected for you, please report it in https://github.com/prisma/prisma/issues`,
|
||||
)};
|
||||
Prisma.PrismaClientUnknownRequestError = () => {
|
||||
throw new Error(`PrismaClientUnknownRequestError is unable to be run in the browser.
|
||||
In case this error is unexpected for you, please report it in https://github.com/prisma/prisma/issues`,
|
||||
)}
|
||||
Prisma.PrismaClientRustPanicError = () => {
|
||||
throw new Error(`PrismaClientRustPanicError is unable to be run in the browser.
|
||||
In case this error is unexpected for you, please report it in https://github.com/prisma/prisma/issues`,
|
||||
)}
|
||||
Prisma.PrismaClientInitializationError = () => {
|
||||
throw new Error(`PrismaClientInitializationError is unable to be run in the browser.
|
||||
In case this error is unexpected for you, please report it in https://github.com/prisma/prisma/issues`,
|
||||
)}
|
||||
Prisma.PrismaClientValidationError = () => {
|
||||
throw new Error(`PrismaClientValidationError is unable to be run in the browser.
|
||||
In case this error is unexpected for you, please report it in https://github.com/prisma/prisma/issues`,
|
||||
)}
|
||||
Prisma.NotFoundError = () => {
|
||||
throw new Error(`NotFoundError is unable to be run in the browser.
|
||||
In case this error is unexpected for you, please report it in https://github.com/prisma/prisma/issues`,
|
||||
)}
|
||||
Prisma.Decimal = Decimal
|
||||
|
||||
/**
|
||||
* Re-export of sql-template-tag
|
||||
*/
|
||||
Prisma.sql = () => {
|
||||
throw new Error(`sqltag is unable to be run in the browser.
|
||||
In case this error is unexpected for you, please report it in https://github.com/prisma/prisma/issues`,
|
||||
)}
|
||||
Prisma.empty = () => {
|
||||
throw new Error(`empty is unable to be run in the browser.
|
||||
In case this error is unexpected for you, please report it in https://github.com/prisma/prisma/issues`,
|
||||
)}
|
||||
Prisma.join = () => {
|
||||
throw new Error(`join is unable to be run in the browser.
|
||||
In case this error is unexpected for you, please report it in https://github.com/prisma/prisma/issues`,
|
||||
)}
|
||||
Prisma.raw = () => {
|
||||
throw new Error(`raw is unable to be run in the browser.
|
||||
In case this error is unexpected for you, please report it in https://github.com/prisma/prisma/issues`,
|
||||
)}
|
||||
Prisma.validator = () => (val) => val
|
||||
|
||||
|
||||
/**
|
||||
* Shorthand utilities for JSON filtering
|
||||
*/
|
||||
Prisma.DbNull = objectEnumValues.instances.DbNull
|
||||
Prisma.JsonNull = objectEnumValues.instances.JsonNull
|
||||
Prisma.AnyNull = objectEnumValues.instances.AnyNull
|
||||
|
||||
Prisma.NullTypes = {
|
||||
DbNull: objectEnumValues.classes.DbNull,
|
||||
JsonNull: objectEnumValues.classes.JsonNull,
|
||||
AnyNull: objectEnumValues.classes.AnyNull
|
||||
}
|
||||
|
||||
/**
|
||||
* Enums
|
||||
*/
|
||||
// Based on
|
||||
// https://github.com/microsoft/TypeScript/issues/3192#issuecomment-261720275
|
||||
function makeEnum(x) { return x; }
|
||||
|
||||
exports.Prisma.AccountDataScalarFieldEnum = makeEnum({
|
||||
id: 'id',
|
||||
json: 'json',
|
||||
updatedAt: 'updatedAt'
|
||||
});
|
||||
|
||||
exports.Prisma.AlbumScalarFieldEnum = makeEnum({
|
||||
id: 'id',
|
||||
json: 'json',
|
||||
createdAt: 'createdAt',
|
||||
updatedAt: 'updatedAt'
|
||||
});
|
||||
|
||||
exports.Prisma.AppDataScalarFieldEnum = makeEnum({
|
||||
id: 'id',
|
||||
value: 'value'
|
||||
});
|
||||
|
||||
exports.Prisma.AppleMusicAlbumScalarFieldEnum = makeEnum({
|
||||
id: 'id',
|
||||
json: 'json',
|
||||
createdAt: 'createdAt',
|
||||
updatedAt: 'updatedAt'
|
||||
});
|
||||
|
||||
exports.Prisma.AppleMusicArtistScalarFieldEnum = makeEnum({
|
||||
id: 'id',
|
||||
json: 'json',
|
||||
createdAt: 'createdAt',
|
||||
updatedAt: 'updatedAt'
|
||||
});
|
||||
|
||||
exports.Prisma.ArtistAlbumScalarFieldEnum = makeEnum({
|
||||
id: 'id',
|
||||
hotAlbums: 'hotAlbums',
|
||||
createdAt: 'createdAt',
|
||||
updatedAt: 'updatedAt'
|
||||
});
|
||||
|
||||
exports.Prisma.ArtistScalarFieldEnum = makeEnum({
|
||||
id: 'id',
|
||||
json: 'json',
|
||||
createdAt: 'createdAt',
|
||||
updatedAt: 'updatedAt'
|
||||
});
|
||||
|
||||
exports.Prisma.AudioScalarFieldEnum = makeEnum({
|
||||
id: 'id',
|
||||
bitRate: 'bitRate',
|
||||
format: 'format',
|
||||
source: 'source',
|
||||
createdAt: 'createdAt',
|
||||
updatedAt: 'updatedAt',
|
||||
queriedAt: 'queriedAt'
|
||||
});
|
||||
|
||||
exports.Prisma.LyricsScalarFieldEnum = makeEnum({
|
||||
id: 'id',
|
||||
json: 'json',
|
||||
createdAt: 'createdAt',
|
||||
updatedAt: 'updatedAt'
|
||||
});
|
||||
|
||||
exports.Prisma.PlaylistScalarFieldEnum = makeEnum({
|
||||
id: 'id',
|
||||
json: 'json',
|
||||
createdAt: 'createdAt',
|
||||
updatedAt: 'updatedAt'
|
||||
});
|
||||
|
||||
exports.Prisma.SortOrder = makeEnum({
|
||||
asc: 'asc',
|
||||
desc: 'desc'
|
||||
});
|
||||
|
||||
exports.Prisma.TrackScalarFieldEnum = makeEnum({
|
||||
id: 'id',
|
||||
json: 'json',
|
||||
createdAt: 'createdAt',
|
||||
updatedAt: 'updatedAt'
|
||||
});
|
||||
|
||||
exports.Prisma.TransactionIsolationLevel = makeStrictEnum({
|
||||
Serializable: 'Serializable'
|
||||
});
|
||||
|
||||
|
||||
exports.Prisma.ModelName = makeEnum({
|
||||
AccountData: 'AccountData',
|
||||
AppData: 'AppData',
|
||||
Track: 'Track',
|
||||
Album: 'Album',
|
||||
Artist: 'Artist',
|
||||
ArtistAlbum: 'ArtistAlbum',
|
||||
Playlist: 'Playlist',
|
||||
Audio: 'Audio',
|
||||
Lyrics: 'Lyrics',
|
||||
AppleMusicAlbum: 'AppleMusicAlbum',
|
||||
AppleMusicArtist: 'AppleMusicArtist'
|
||||
});
|
||||
|
||||
/**
|
||||
* Create the Client
|
||||
*/
|
||||
class PrismaClient {
|
||||
constructor() {
|
||||
throw new Error(
|
||||
`PrismaClient is unable to be run in the browser.
|
||||
In case this error is unexpected for you, please report it in https://github.com/prisma/prisma/issues`,
|
||||
)
|
||||
}
|
||||
}
|
||||
exports.PrismaClient = PrismaClient
|
||||
|
||||
Object.assign(exports, Prisma)
|
||||
12729
packages/desktop/prisma/client/index.d.ts
vendored
12729
packages/desktop/prisma/client/index.d.ts
vendored
File diff suppressed because it is too large
Load diff
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
|
|
@ -1,6 +0,0 @@
|
|||
{
|
||||
"name": ".prisma/client",
|
||||
"main": "index.js",
|
||||
"types": "index.d.ts",
|
||||
"browser": "index-browser.js"
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -1,323 +0,0 @@
|
|||
declare class AnyNull extends NullTypesEnumValue {
|
||||
}
|
||||
|
||||
declare class DbNull extends NullTypesEnumValue {
|
||||
}
|
||||
|
||||
export declare namespace Decimal {
|
||||
export type Constructor = typeof Decimal;
|
||||
export type Instance = Decimal;
|
||||
export type Rounding = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8;
|
||||
export type Modulo = Rounding | 9;
|
||||
export type Value = string | number | Decimal;
|
||||
|
||||
// http://mikemcl.github.io/decimal.js/#constructor-properties
|
||||
export interface Config {
|
||||
precision?: number;
|
||||
rounding?: Rounding;
|
||||
toExpNeg?: number;
|
||||
toExpPos?: number;
|
||||
minE?: number;
|
||||
maxE?: number;
|
||||
crypto?: boolean;
|
||||
modulo?: Modulo;
|
||||
defaults?: boolean;
|
||||
}
|
||||
}
|
||||
|
||||
export declare class Decimal {
|
||||
readonly d: number[];
|
||||
readonly e: number;
|
||||
readonly s: number;
|
||||
private readonly toStringTag: string;
|
||||
|
||||
constructor(n: Decimal.Value);
|
||||
|
||||
absoluteValue(): Decimal;
|
||||
abs(): Decimal;
|
||||
|
||||
ceil(): Decimal;
|
||||
|
||||
clampedTo(min: Decimal.Value, max: Decimal.Value): Decimal;
|
||||
clamp(min: Decimal.Value, max: Decimal.Value): Decimal;
|
||||
|
||||
comparedTo(n: Decimal.Value): number;
|
||||
cmp(n: Decimal.Value): number;
|
||||
|
||||
cosine(): Decimal;
|
||||
cos(): Decimal;
|
||||
|
||||
cubeRoot(): Decimal;
|
||||
cbrt(): Decimal;
|
||||
|
||||
decimalPlaces(): number;
|
||||
dp(): number;
|
||||
|
||||
dividedBy(n: Decimal.Value): Decimal;
|
||||
div(n: Decimal.Value): Decimal;
|
||||
|
||||
dividedToIntegerBy(n: Decimal.Value): Decimal;
|
||||
divToInt(n: Decimal.Value): Decimal;
|
||||
|
||||
equals(n: Decimal.Value): boolean;
|
||||
eq(n: Decimal.Value): boolean;
|
||||
|
||||
floor(): Decimal;
|
||||
|
||||
greaterThan(n: Decimal.Value): boolean;
|
||||
gt(n: Decimal.Value): boolean;
|
||||
|
||||
greaterThanOrEqualTo(n: Decimal.Value): boolean;
|
||||
gte(n: Decimal.Value): boolean;
|
||||
|
||||
hyperbolicCosine(): Decimal;
|
||||
cosh(): Decimal;
|
||||
|
||||
hyperbolicSine(): Decimal;
|
||||
sinh(): Decimal;
|
||||
|
||||
hyperbolicTangent(): Decimal;
|
||||
tanh(): Decimal;
|
||||
|
||||
inverseCosine(): Decimal;
|
||||
acos(): Decimal;
|
||||
|
||||
inverseHyperbolicCosine(): Decimal;
|
||||
acosh(): Decimal;
|
||||
|
||||
inverseHyperbolicSine(): Decimal;
|
||||
asinh(): Decimal;
|
||||
|
||||
inverseHyperbolicTangent(): Decimal;
|
||||
atanh(): Decimal;
|
||||
|
||||
inverseSine(): Decimal;
|
||||
asin(): Decimal;
|
||||
|
||||
inverseTangent(): Decimal;
|
||||
atan(): Decimal;
|
||||
|
||||
isFinite(): boolean;
|
||||
|
||||
isInteger(): boolean;
|
||||
isInt(): boolean;
|
||||
|
||||
isNaN(): boolean;
|
||||
|
||||
isNegative(): boolean;
|
||||
isNeg(): boolean;
|
||||
|
||||
isPositive(): boolean;
|
||||
isPos(): boolean;
|
||||
|
||||
isZero(): boolean;
|
||||
|
||||
lessThan(n: Decimal.Value): boolean;
|
||||
lt(n: Decimal.Value): boolean;
|
||||
|
||||
lessThanOrEqualTo(n: Decimal.Value): boolean;
|
||||
lte(n: Decimal.Value): boolean;
|
||||
|
||||
logarithm(n?: Decimal.Value): Decimal;
|
||||
log(n?: Decimal.Value): Decimal;
|
||||
|
||||
minus(n: Decimal.Value): Decimal;
|
||||
sub(n: Decimal.Value): Decimal;
|
||||
|
||||
modulo(n: Decimal.Value): Decimal;
|
||||
mod(n: Decimal.Value): Decimal;
|
||||
|
||||
naturalExponential(): Decimal;
|
||||
exp(): Decimal;
|
||||
|
||||
naturalLogarithm(): Decimal;
|
||||
ln(): Decimal;
|
||||
|
||||
negated(): Decimal;
|
||||
neg(): Decimal;
|
||||
|
||||
plus(n: Decimal.Value): Decimal;
|
||||
add(n: Decimal.Value): Decimal;
|
||||
|
||||
precision(includeZeros?: boolean): number;
|
||||
sd(includeZeros?: boolean): number;
|
||||
|
||||
round(): Decimal;
|
||||
|
||||
sine() : Decimal;
|
||||
sin() : Decimal;
|
||||
|
||||
squareRoot(): Decimal;
|
||||
sqrt(): Decimal;
|
||||
|
||||
tangent() : Decimal;
|
||||
tan() : Decimal;
|
||||
|
||||
times(n: Decimal.Value): Decimal;
|
||||
mul(n: Decimal.Value) : Decimal;
|
||||
|
||||
toBinary(significantDigits?: number): string;
|
||||
toBinary(significantDigits: number, rounding: Decimal.Rounding): string;
|
||||
|
||||
toDecimalPlaces(decimalPlaces?: number): Decimal;
|
||||
toDecimalPlaces(decimalPlaces: number, rounding: Decimal.Rounding): Decimal;
|
||||
toDP(decimalPlaces?: number): Decimal;
|
||||
toDP(decimalPlaces: number, rounding: Decimal.Rounding): Decimal;
|
||||
|
||||
toExponential(decimalPlaces?: number): string;
|
||||
toExponential(decimalPlaces: number, rounding: Decimal.Rounding): string;
|
||||
|
||||
toFixed(decimalPlaces?: number): string;
|
||||
toFixed(decimalPlaces: number, rounding: Decimal.Rounding): string;
|
||||
|
||||
toFraction(max_denominator?: Decimal.Value): Decimal[];
|
||||
|
||||
toHexadecimal(significantDigits?: number): string;
|
||||
toHexadecimal(significantDigits: number, rounding: Decimal.Rounding): string;
|
||||
toHex(significantDigits?: number): string;
|
||||
toHex(significantDigits: number, rounding?: Decimal.Rounding): string;
|
||||
|
||||
toJSON(): string;
|
||||
|
||||
toNearest(n: Decimal.Value, rounding?: Decimal.Rounding): Decimal;
|
||||
|
||||
toNumber(): number;
|
||||
|
||||
toOctal(significantDigits?: number): string;
|
||||
toOctal(significantDigits: number, rounding: Decimal.Rounding): string;
|
||||
|
||||
toPower(n: Decimal.Value): Decimal;
|
||||
pow(n: Decimal.Value): Decimal;
|
||||
|
||||
toPrecision(significantDigits?: number): string;
|
||||
toPrecision(significantDigits: number, rounding: Decimal.Rounding): string;
|
||||
|
||||
toSignificantDigits(significantDigits?: number): Decimal;
|
||||
toSignificantDigits(significantDigits: number, rounding: Decimal.Rounding): Decimal;
|
||||
toSD(significantDigits?: number): Decimal;
|
||||
toSD(significantDigits: number, rounding: Decimal.Rounding): Decimal;
|
||||
|
||||
toString(): string;
|
||||
|
||||
truncated(): Decimal;
|
||||
trunc(): Decimal;
|
||||
|
||||
valueOf(): string;
|
||||
|
||||
static abs(n: Decimal.Value): Decimal;
|
||||
static acos(n: Decimal.Value): Decimal;
|
||||
static acosh(n: Decimal.Value): Decimal;
|
||||
static add(x: Decimal.Value, y: Decimal.Value): Decimal;
|
||||
static asin(n: Decimal.Value): Decimal;
|
||||
static asinh(n: Decimal.Value): Decimal;
|
||||
static atan(n: Decimal.Value): Decimal;
|
||||
static atanh(n: Decimal.Value): Decimal;
|
||||
static atan2(y: Decimal.Value, x: Decimal.Value): Decimal;
|
||||
static cbrt(n: Decimal.Value): Decimal;
|
||||
static ceil(n: Decimal.Value): Decimal;
|
||||
static clamp(n: Decimal.Value, min: Decimal.Value, max: Decimal.Value): Decimal;
|
||||
static clone(object?: Decimal.Config): Decimal.Constructor;
|
||||
static config(object: Decimal.Config): Decimal.Constructor;
|
||||
static cos(n: Decimal.Value): Decimal;
|
||||
static cosh(n: Decimal.Value): Decimal;
|
||||
static div(x: Decimal.Value, y: Decimal.Value): Decimal;
|
||||
static exp(n: Decimal.Value): Decimal;
|
||||
static floor(n: Decimal.Value): Decimal;
|
||||
static hypot(...n: Decimal.Value[]): Decimal;
|
||||
static isDecimal(object: any): object is Decimal;
|
||||
static ln(n: Decimal.Value): Decimal;
|
||||
static log(n: Decimal.Value, base?: Decimal.Value): Decimal;
|
||||
static log2(n: Decimal.Value): Decimal;
|
||||
static log10(n: Decimal.Value): Decimal;
|
||||
static max(...n: Decimal.Value[]): Decimal;
|
||||
static min(...n: Decimal.Value[]): Decimal;
|
||||
static mod(x: Decimal.Value, y: Decimal.Value): Decimal;
|
||||
static mul(x: Decimal.Value, y: Decimal.Value): Decimal;
|
||||
static noConflict(): Decimal.Constructor; // Browser only
|
||||
static pow(base: Decimal.Value, exponent: Decimal.Value): Decimal;
|
||||
static random(significantDigits?: number): Decimal;
|
||||
static round(n: Decimal.Value): Decimal;
|
||||
static set(object: Decimal.Config): Decimal.Constructor;
|
||||
static sign(n: Decimal.Value): number;
|
||||
static sin(n: Decimal.Value): Decimal;
|
||||
static sinh(n: Decimal.Value): Decimal;
|
||||
static sqrt(n: Decimal.Value): Decimal;
|
||||
static sub(x: Decimal.Value, y: Decimal.Value): Decimal;
|
||||
static sum(...n: Decimal.Value[]): Decimal;
|
||||
static tan(n: Decimal.Value): Decimal;
|
||||
static tanh(n: Decimal.Value): Decimal;
|
||||
static trunc(n: Decimal.Value): Decimal;
|
||||
|
||||
static readonly default?: Decimal.Constructor;
|
||||
static readonly Decimal?: Decimal.Constructor;
|
||||
|
||||
static readonly precision: number;
|
||||
static readonly rounding: Decimal.Rounding;
|
||||
static readonly toExpNeg: number;
|
||||
static readonly toExpPos: number;
|
||||
static readonly minE: number;
|
||||
static readonly maxE: number;
|
||||
static readonly crypto: boolean;
|
||||
static readonly modulo: Decimal.Modulo;
|
||||
|
||||
static readonly ROUND_UP: 0;
|
||||
static readonly ROUND_DOWN: 1;
|
||||
static readonly ROUND_CEIL: 2;
|
||||
static readonly ROUND_FLOOR: 3;
|
||||
static readonly ROUND_HALF_UP: 4;
|
||||
static readonly ROUND_HALF_DOWN: 5;
|
||||
static readonly ROUND_HALF_EVEN: 6;
|
||||
static readonly ROUND_HALF_CEIL: 7;
|
||||
static readonly ROUND_HALF_FLOOR: 8;
|
||||
static readonly EUCLID: 9;
|
||||
}
|
||||
|
||||
declare class JsonNull extends NullTypesEnumValue {
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates more strict variant of an enum which, unlike regular enum,
|
||||
* throws on non-existing property access. This can be useful in following situations:
|
||||
* - we have an API, that accepts both `undefined` and `SomeEnumType` as an input
|
||||
* - enum values are generated dynamically from DMMF.
|
||||
*
|
||||
* In that case, if using normal enums and no compile-time typechecking, using non-existing property
|
||||
* will result in `undefined` value being used, which will be accepted. Using strict enum
|
||||
* in this case will help to have a runtime exception, telling you that you are probably doing something wrong.
|
||||
*
|
||||
* Note: if you need to check for existence of a value in the enum you can still use either
|
||||
* `in` operator or `hasOwnProperty` function.
|
||||
*
|
||||
* @param definition
|
||||
* @returns
|
||||
*/
|
||||
export declare function makeStrictEnum<T extends Record<PropertyKey, string | number>>(definition: T): T;
|
||||
|
||||
declare class NullTypesEnumValue extends ObjectEnumValue {
|
||||
_getNamespace(): string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Base class for unique values of object-valued enums.
|
||||
*/
|
||||
declare abstract class ObjectEnumValue {
|
||||
constructor(arg?: symbol);
|
||||
abstract _getNamespace(): string;
|
||||
_getName(): string;
|
||||
toString(): string;
|
||||
}
|
||||
|
||||
export declare const objectEnumValues: {
|
||||
classes: {
|
||||
DbNull: typeof DbNull;
|
||||
JsonNull: typeof JsonNull;
|
||||
AnyNull: typeof AnyNull;
|
||||
};
|
||||
instances: {
|
||||
DbNull: DbNull;
|
||||
JsonNull: JsonNull;
|
||||
AnyNull: AnyNull;
|
||||
};
|
||||
};
|
||||
|
||||
export { }
|
||||
File diff suppressed because it is too large
Load diff
2075
packages/desktop/prisma/client/runtime/index.d.ts
vendored
2075
packages/desktop/prisma/client/runtime/index.d.ts
vendored
File diff suppressed because it is too large
Load diff
File diff suppressed because one or more lines are too long
|
|
@ -1,87 +0,0 @@
|
|||
generator client {
|
||||
provider = "prisma-client-js"
|
||||
output = "./client"
|
||||
binaryTargets = ["native", "darwin", "darwin-arm64"]
|
||||
}
|
||||
|
||||
datasource db {
|
||||
provider = "sqlite"
|
||||
url = env("DATABASE_URL")
|
||||
}
|
||||
|
||||
model AccountData {
|
||||
id String @id @unique
|
||||
json String
|
||||
updatedAt DateTime @updatedAt
|
||||
}
|
||||
|
||||
model AppData {
|
||||
id String @id @unique
|
||||
value String
|
||||
}
|
||||
|
||||
model Track {
|
||||
id Int @id @unique
|
||||
json String
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
}
|
||||
|
||||
model Album {
|
||||
id Int @id @unique
|
||||
json String
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
}
|
||||
|
||||
model Artist {
|
||||
id Int @id @unique
|
||||
json String
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
}
|
||||
|
||||
model ArtistAlbum {
|
||||
id Int @id @unique
|
||||
hotAlbums String
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
}
|
||||
|
||||
model Playlist {
|
||||
id Int @id @unique
|
||||
json String
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
}
|
||||
|
||||
model Audio {
|
||||
id Int @id @unique
|
||||
bitRate Int
|
||||
format String
|
||||
source String
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
queriedAt DateTime @default(now())
|
||||
}
|
||||
|
||||
model Lyrics {
|
||||
id Int @id @unique
|
||||
json String
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
}
|
||||
|
||||
model AppleMusicAlbum {
|
||||
id Int @id @unique
|
||||
json String
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
}
|
||||
|
||||
model AppleMusicArtist {
|
||||
id Int @id @unique
|
||||
json String
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
}
|
||||
Binary file not shown.
|
|
@ -1,155 +0,0 @@
|
|||
/* eslint-disable @typescript-eslint/no-var-requires */
|
||||
const { rebuild } = require('electron-rebuild')
|
||||
const fs = require('fs')
|
||||
const minimist = require('minimist')
|
||||
const pc = require('picocolors')
|
||||
const releases = require('electron-releases')
|
||||
const pkg = require(`${process.cwd()}/package.json`)
|
||||
const axios = require('axios')
|
||||
const { execSync } = require('child_process')
|
||||
const { resolve } = require('path')
|
||||
|
||||
const isWindows = process.platform === 'win32'
|
||||
const isMac = process.platform === 'darwin'
|
||||
const isLinux = process.platform === 'linux'
|
||||
|
||||
const electronVersion = pkg.devDependencies.electron.replaceAll('^', '')
|
||||
const betterSqlite3Version = pkg.dependencies['better-sqlite3'].replaceAll(
|
||||
'^',
|
||||
''
|
||||
)
|
||||
const electronModuleVersion = releases.find(r =>
|
||||
r.version.includes(electronVersion)
|
||||
)?.deps?.modules
|
||||
if (!electronModuleVersion) {
|
||||
console.error(
|
||||
pc.red('Can not find electron module version in electron-releases')
|
||||
)
|
||||
process.exit(1)
|
||||
}
|
||||
const argv = minimist(process.argv.slice(2))
|
||||
|
||||
const projectDir = resolve(process.cwd(), '../../')
|
||||
const tmpDir = resolve(projectDir, `./tmp/better-sqlite3`)
|
||||
const binDir = resolve(projectDir, `./tmp/bin`)
|
||||
console.log(pc.cyan(`projectDir=${projectDir}`))
|
||||
console.log(pc.cyan(`binDir=${binDir}`))
|
||||
|
||||
if (!fs.existsSync(binDir)) {
|
||||
console.log(pc.cyan(`Creating dist/binary directory: ${binDir}`))
|
||||
fs.mkdirSync(binDir, {
|
||||
recursive: true,
|
||||
})
|
||||
}
|
||||
|
||||
const download = async arch => {
|
||||
console.log(pc.cyan(`Downloading for ${arch}...`))
|
||||
if (!electronModuleVersion) {
|
||||
console.log(pc.red('No electron module version found! Skip download.'))
|
||||
return false
|
||||
}
|
||||
const fileName = `better-sqlite3-v${betterSqlite3Version}-electron-v${electronModuleVersion}-${process.platform}-${arch}`
|
||||
const zipFileName = `${fileName}.tar.gz`
|
||||
const url = `https://github.com/JoshuaWise/better-sqlite3/releases/download/v${betterSqlite3Version}/${zipFileName}`
|
||||
if (!fs.existsSync(tmpDir)) {
|
||||
fs.mkdirSync(tmpDir, {
|
||||
recursive: true,
|
||||
})
|
||||
}
|
||||
|
||||
try {
|
||||
await axios({
|
||||
method: 'get',
|
||||
url,
|
||||
responseType: 'stream',
|
||||
}).then(response => {
|
||||
response.data.pipe(
|
||||
fs.createWriteStream(resolve(tmpDir, `./${zipFileName}`))
|
||||
)
|
||||
return true
|
||||
})
|
||||
} catch (e) {
|
||||
console.log(pc.red('Download failed! Skip download.'))
|
||||
return false
|
||||
}
|
||||
|
||||
try {
|
||||
execSync(`tar -xvzf ${tmpDir}/${zipFileName} -C ${tmpDir}`)
|
||||
} catch (e) {
|
||||
console.log(pc.red('Extract failed! Skip extract.'))
|
||||
return false
|
||||
}
|
||||
|
||||
try {
|
||||
fs.copyFileSync(
|
||||
resolve(tmpDir, './build/Release/better_sqlite3.node'),
|
||||
resolve(binDir, `./better_sqlite3_${process.platform}_${arch}.node`)
|
||||
)
|
||||
} catch (e) {
|
||||
console.log(pc.red('Copy failed! Skip copy.', e))
|
||||
return false
|
||||
}
|
||||
|
||||
try {
|
||||
fs.rmSync(resolve(tmpDir, `./build`), { recursive: true, force: true })
|
||||
} catch (e) {
|
||||
console.log(pc.red('Delete failed! Skip delete.'))
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
const build = async arch => {
|
||||
const downloaded = await download(arch)
|
||||
if (downloaded) return
|
||||
|
||||
console.log(pc.cyan(`Building for ${arch}...`))
|
||||
await rebuild({
|
||||
projectRootPath: projectDir,
|
||||
buildPath: process.cwd(),
|
||||
electronVersion,
|
||||
arch,
|
||||
onlyModules: ['better-sqlite3'],
|
||||
force: true,
|
||||
})
|
||||
.then(() => {
|
||||
console.info('Build succeeded')
|
||||
|
||||
const from = resolve(
|
||||
projectDir,
|
||||
`./node_modules/better-sqlite3/build/Release/better_sqlite3.node`
|
||||
)
|
||||
const to = resolve(
|
||||
binDir,
|
||||
`./better_sqlite3_${process.platform}_${arch}.node`
|
||||
)
|
||||
console.info(`copy ${from} to ${to}`)
|
||||
fs.copyFileSync(from, to)
|
||||
})
|
||||
.catch(e => {
|
||||
console.error(pc.red('Build failed!'))
|
||||
console.error(pc.red(e))
|
||||
})
|
||||
}
|
||||
|
||||
const main = async () => {
|
||||
if (argv.x64 || argv.arm64 || argv.arm) {
|
||||
if (argv.x64) await build('x64')
|
||||
if (argv.arm64) await build('arm64')
|
||||
if (argv.arm) await build('arm')
|
||||
} else {
|
||||
if (isWindows) {
|
||||
await build('x64')
|
||||
} else if (isMac) {
|
||||
await build('x64')
|
||||
await build('arm64')
|
||||
} else if (isLinux) {
|
||||
await build('x64')
|
||||
await build('arm64')
|
||||
await build('arm')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
main()
|
||||
|
|
@ -1,63 +0,0 @@
|
|||
/* eslint-disable @typescript-eslint/no-var-requires */
|
||||
const path = require('path')
|
||||
const pc = require('picocolors')
|
||||
const fs = require('fs')
|
||||
|
||||
const archs = ['ia32', 'x64', 'armv7l', 'arm64', 'universal']
|
||||
|
||||
const projectDir = path.resolve(process.cwd(), '../../')
|
||||
const binDir = `${projectDir}/tmp/bin`
|
||||
console.log(pc.cyan(`projectDir=${projectDir}`))
|
||||
console.log(pc.cyan(`binDir=${binDir}`))
|
||||
|
||||
exports.default = async function (context) {
|
||||
// console.log(context)
|
||||
const platform = context.electronPlatformName
|
||||
const arch = archs?.[context.arch]
|
||||
|
||||
// Mac
|
||||
if (platform === 'darwin') {
|
||||
if (arch === 'universal') return // Skip universal we already copy binary for x64 and arm64
|
||||
if (arch !== 'x64' && arch !== 'arm64') return // Skip other archs
|
||||
|
||||
const from = `${binDir}/better_sqlite3_darwin_${arch}.node`
|
||||
const to = `${context.appOutDir}/${context.packager.appInfo.productFilename}.app/Contents/Resources/bin/better_sqlite3.node`
|
||||
console.info(`copy ${from} to ${to}`)
|
||||
|
||||
const toFolder = to.replace('/better_sqlite3.node', '')
|
||||
if (!fs.existsSync(toFolder)) {
|
||||
fs.mkdirSync(toFolder, {
|
||||
recursive: true,
|
||||
})
|
||||
}
|
||||
|
||||
try {
|
||||
fs.copyFileSync(from, to)
|
||||
} catch (e) {
|
||||
console.log(pc.red('Copy failed! Process stopped.'))
|
||||
throw e
|
||||
}
|
||||
}
|
||||
|
||||
if (platform === 'win32') {
|
||||
if (arch !== 'x64') return // Skip other archs
|
||||
|
||||
const from = `${binDir}/better_sqlite3_win32_${arch}.node`
|
||||
const to = `${context.appOutDir}/resources/bin/better_sqlite3.node`
|
||||
console.info(`copy ${from} to ${to}`)
|
||||
|
||||
const toFolder = to.replace('/better_sqlite3.node', '')
|
||||
if (!fs.existsSync(toFolder)) {
|
||||
fs.mkdirSync(toFolder, {
|
||||
recursive: true,
|
||||
})
|
||||
}
|
||||
|
||||
try {
|
||||
fs.copyFileSync(from, to)
|
||||
} catch (e) {
|
||||
console.log(pc.red('Copy failed! Process stopped.'))
|
||||
throw e
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -3,12 +3,12 @@ import AutoLoad, { AutoloadPluginOptions } from '@fastify/autoload'
|
|||
import { FastifyPluginAsync } from 'fastify'
|
||||
|
||||
const app: FastifyPluginAsync<AutoloadPluginOptions> = async (fastify, opts) => {
|
||||
void fastify.register(AutoLoad, {
|
||||
fastify.register(AutoLoad, {
|
||||
dir: join(__dirname, 'plugins'),
|
||||
options: opts,
|
||||
})
|
||||
|
||||
void fastify.register(AutoLoad, {
|
||||
fastify.register(AutoLoad, {
|
||||
dir: join(__dirname, 'routes'),
|
||||
options: opts,
|
||||
})
|
||||
|
|
|
|||
|
|
@ -82,7 +82,6 @@ const album: FastifyPluginAsync = async (fastify, opts): Promise<void> => {
|
|||
method: 'GET',
|
||||
url: `/albums/${album.id}`,
|
||||
params: {
|
||||
'fields[albums]': 'editorialNotes',
|
||||
'omit[resource:albums]': 'relationships',
|
||||
l: lang === 'zh-CN' ? 'en-US' : 'zh-CN',
|
||||
},
|
||||
|
|
@ -114,7 +113,12 @@ const album: FastifyPluginAsync = async (fastify, opts): Promise<void> => {
|
|||
.create({
|
||||
data: {
|
||||
...data,
|
||||
editorialNote: { create: editorialNote },
|
||||
editorialNote: {
|
||||
connectOrCreate: {
|
||||
where: { id: data.id },
|
||||
create: editorialNote,
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
.catch(e => console.error(e))
|
||||
|
|
|
|||
|
|
@ -102,7 +102,12 @@ const artist: FastifyPluginAsync = async (fastify, opts): Promise<void> => {
|
|||
.create({
|
||||
data: {
|
||||
...data,
|
||||
artistBio: { create: artistBio },
|
||||
artistBio: {
|
||||
connectOrCreate: {
|
||||
where: { id: data.id },
|
||||
create: artistBio,
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
.catch(e => console.error(e))
|
||||
|
|
|
|||
|
|
@ -1,17 +1,11 @@
|
|||
import axios, {
|
||||
AxiosError,
|
||||
AxiosInstance,
|
||||
AxiosRequestConfig,
|
||||
AxiosResponse,
|
||||
} from 'axios'
|
||||
import axios, { AxiosError, AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios'
|
||||
|
||||
export const baseURL = 'https://amp-api.music.apple.com/v1/catalog/us'
|
||||
|
||||
export const headers = {
|
||||
Authority: 'amp-api.music.apple.com',
|
||||
Accept: '*/*',
|
||||
Authorization:
|
||||
'Bearer eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IldlYlBsYXlLaWQifQ.eyJpc3MiOiJBTVBXZWJQbGF5IiwiaWF0IjoxNjYxNDQwNDMyLCJleHAiOjE2NzY5OTI0MzIsInJvb3RfaHR0cHNfb3JpZ2luIjpbImFwcGxlLmNvbSJdfQ.z4BMv9_O4MpMK2iFhYkDqPsx53soPSnlXXK3jm99pHqGOrZADvTgEUw2U7_B1W0MAtFiWBYhYcGvWrzaOig6Bw',
|
||||
Authorization: process.env.APPLE_MUSIC_TOKEN || '',
|
||||
Referer: 'https://music.apple.com/',
|
||||
'Sec-Fetch-Dest': 'empty',
|
||||
'Sec-Fetch-Mode': 'cors',
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ export default function useLyric(params: FetchLyricParams) {
|
|||
key,
|
||||
async () => {
|
||||
// fetch from cache as initial data
|
||||
const cache = window.ipcRenderer?.invoke(IpcChannels.GetApiCache, {
|
||||
const cache = await window.ipcRenderer?.invoke(IpcChannels.GetApiCache, {
|
||||
api: CacheAPIs.Lyric,
|
||||
query: {
|
||||
id: params.id,
|
||||
|
|
|
|||
|
|
@ -12,10 +12,7 @@ const Artist = ({ artist }: { artist: Artist }) => {
|
|||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
className='text-center'
|
||||
onMouseOver={() => prefetchArtist({ id: artist.id })}
|
||||
>
|
||||
<div className='text-center' onMouseOver={() => prefetchArtist({ id: artist.id })}>
|
||||
<Image
|
||||
onClick={to}
|
||||
src={resizeImage(artist.img1v1Url, 'md')}
|
||||
|
|
@ -41,10 +38,7 @@ const Placeholder = ({ row }: { row: number }) => {
|
|||
return (
|
||||
<div className='no-scrollbar flex snap-x overflow-x-scroll lg:grid lg:w-auto lg:grid-cols-5 lg:gap-10'>
|
||||
{[...new Array(row * 5).keys()].map(i => (
|
||||
<div
|
||||
className='flex snap-start flex-col items-center px-2.5 lg:px-0'
|
||||
key={i}
|
||||
>
|
||||
<div className='flex snap-start flex-col items-center px-2.5 lg:px-0' key={i}>
|
||||
<div
|
||||
className='aspect-square w-full rounded-full bg-white dark:bg-neutral-800'
|
||||
style={{
|
||||
|
|
@ -73,7 +67,7 @@ const ArtistRow = ({
|
|||
placeholderRow?: number
|
||||
}) => {
|
||||
return (
|
||||
<div className={className}>
|
||||
<div className={cx('@container', className)}>
|
||||
{/* Title */}
|
||||
{title && (
|
||||
<h4 className='mx-2.5 mb-6 text-12 font-medium uppercase dark:text-neutral-300 lg:mx-0 lg:text-14 lg:font-bold'>
|
||||
|
|
@ -83,7 +77,7 @@ const ArtistRow = ({
|
|||
|
||||
{/* Artists */}
|
||||
{artists && (
|
||||
<div className='no-scrollbar flex snap-x overflow-x-scroll lg:grid lg:w-auto lg:grid-cols-5 lg:gap-x-10 lg:gap-y-8'>
|
||||
<div className='no-scrollbar grid w-auto grid-cols-4 gap-x-10 gap-y-8 @3xl:grid-cols-5 @7xl:grid-cols-7'>
|
||||
{artists.map(artist => (
|
||||
<div className='snap-start px-2.5 lg:px-0' key={artist.id}>
|
||||
<Artist artist={artist} key={artist.id} />
|
||||
|
|
|
|||
|
|
@ -99,12 +99,12 @@ const CoverRow = ({
|
|||
itemSubtitle?: ItemSubTitle
|
||||
}) => {
|
||||
return (
|
||||
<div className={className}>
|
||||
<div className={cx('@container', className)}>
|
||||
{/* Title */}
|
||||
{title && <h4 className='mb-6 text-14 font-bold uppercase dark:text-neutral-300'>{title}</h4>}
|
||||
|
||||
{/* Items */}
|
||||
<div className='grid grid-cols-3 gap-4 lg:gap-6 xl:grid-cols-4 2xl:grid-cols-5'>
|
||||
<div className='grid grid-cols-3 gap-4 @lg:gap-6 @4xl:grid-cols-4 @7xl:grid-cols-5'>
|
||||
{albums?.map(album => (
|
||||
<Album key={album.id} album={album} itemTitle={itemTitle} itemSubtitle={itemSubtitle} />
|
||||
))}
|
||||
|
|
|
|||
|
|
@ -3,21 +3,20 @@ import uiStates from '../states/uiStates'
|
|||
|
||||
const VideoRow = ({ videos }: { videos: Video[] }) => {
|
||||
return (
|
||||
<div className='grid grid-cols-3 gap-6'>
|
||||
{videos.map(video => (
|
||||
<div
|
||||
key={video.vid}
|
||||
onClick={() => (uiStates.playingVideoID = Number(video.vid))}
|
||||
>
|
||||
<img
|
||||
src={video.coverUrl}
|
||||
className='aspect-video w-full rounded-24 border border-white/5 object-contain'
|
||||
/>
|
||||
<div className='line-clamp-2 mt-2 text-12 font-medium text-neutral-600'>
|
||||
{video.creator?.at(0)?.userName} - {video.title}
|
||||
<div className='@container'>
|
||||
<div className='grid grid-cols-2 gap-6 @3xl:grid-cols-3 @7xl:grid-cols-4'>
|
||||
{videos.map(video => (
|
||||
<div key={video.vid} onClick={() => (uiStates.playingVideoID = Number(video.vid))}>
|
||||
<img
|
||||
src={video.coverUrl}
|
||||
className='aspect-video w-full rounded-24 border border-white/5 object-contain'
|
||||
/>
|
||||
<div className='line-clamp-2 mt-2 text-12 font-medium text-neutral-600'>
|
||||
{video.creator?.at(0)?.userName} - {video.title}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@
|
|||
"@emotion/css": "^11.10.5",
|
||||
"@sentry/react": "^7.29.0",
|
||||
"@sentry/tracing": "^7.29.0",
|
||||
"@tailwindcss/container-queries": "^0.1.0",
|
||||
"@tanstack/react-query": "^4.20.9",
|
||||
"@tanstack/react-query-devtools": "^4.20.9",
|
||||
"ahooks": "^3.7.4",
|
||||
|
|
|
|||
|
|
@ -37,7 +37,9 @@ const Header = () => {
|
|||
const creatorLink = `/artist/${album?.artist.id}`
|
||||
const description = isLoadingAppleMusicAlbum
|
||||
? ''
|
||||
: appleMusicAlbum?.editorialNote?.[i18n.language.replace('-', '_')] || album?.description
|
||||
: appleMusicAlbum?.editorialNote?.[i18n.language.replace('-', '_')] ||
|
||||
album?.description ||
|
||||
appleMusicAlbum?.editorialNote?.en_US
|
||||
const extraInfo = useMemo(() => {
|
||||
const duration = album?.songs?.reduce((acc, cur) => acc + cur.dt, 0) || 0
|
||||
const albumDuration = formatDuration(duration, i18n.language, 'hh[hr] mm[min]')
|
||||
|
|
|
|||
|
|
@ -16,7 +16,9 @@ const ArtistInfo = ({ artist, isLoading }: { artist?: Artist; isLoading: boolean
|
|||
|
||||
const [isOpenDescription, setIsOpenDescription] = useState(false)
|
||||
const description =
|
||||
artistFromApple?.artistBio?.[i18n.language.replace('-', '_')] || artist?.briefDesc
|
||||
artistFromApple?.artistBio?.[i18n.language.replace('-', '_')] ||
|
||||
artist?.briefDesc ||
|
||||
artistFromApple?.artistBio?.en_US
|
||||
|
||||
return (
|
||||
<div>
|
||||
|
|
|
|||
|
|
@ -121,4 +121,7 @@ module.exports = {
|
|||
}
|
||||
},
|
||||
},
|
||||
plugins: [
|
||||
require('@tailwindcss/container-queries'),
|
||||
],
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,8 +21,8 @@ export function resizeImage(url: string, size: 'xs' | 'sm' | 'md' | 'lg'): strin
|
|||
lg: '1024',
|
||||
}
|
||||
|
||||
// from Apple Music
|
||||
if (url.includes('mzstatic.com')) {
|
||||
// from Apple Music
|
||||
return url.replace('{w}', sizeMap[size]).replace('{h}', sizeMap[size])
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue