osu-play 1.0.4 → 1.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,48 +1,61 @@
1
- # OSU!Pplay
1
+ <h1 align="center">
2
+ <br>
3
+ osu!play
4
+ <br>
2
5
 
3
- Listen to your favourite [OSU!Lazer](https://lazer.ppy.sh) beatmaps as a spotify playlist from the terminal
6
+ [![NPM version](https://img.shields.io/npm/v/osu-play.svg?style=flat)](https://npmjs.org/package/osu-play)
7
+ [![Downloads](https://badgen.net/npm/dt/osu-play)](https://www.npmjs.com/package/osu-play)
8
+ [![MIT License](https://img.shields.io/badge/license-MIT-blue.svg?style=flat)](LICENSE)
9
+
10
+ </h1>
11
+
12
+ > Listen to your favourite [osu!lazer](https://lazer.ppy.sh) beatmaps as a
13
+ > spotify playlist from the terminal
4
14
 
5
15
  ## Installation
6
16
 
7
17
  ### Requirements
8
18
 
9
19
  - [Node.js](https://nodejs.org/en/) (v18 or higher)
10
- - [osu!lazer](https://lazer.ppy.sh/home/download) with some beatmaps to listen to 😉
20
+ - [osu!lazer](https://lazer.ppy.sh/home/download) with some beatmaps to listen
21
+ to 😉
11
22
  - That's it!
12
23
 
13
24
  ### Quick start
14
25
 
15
26
  - Try out the latest release without installing anything:
16
27
 
17
- ```sh
18
- npx osu-play # using npm
19
- pnpm dlx osu-play # using pnpm
20
- ```
28
+ ```sh
29
+ npx osu-play # using npm
30
+ pnpm dlx osu-play # using pnpm
31
+ ```
21
32
 
22
33
  - Install the latest release globally:
23
34
 
24
- ```sh
25
- npm i -g osu-play # using npm
26
- pnpm i -g osu-play # using pnpm
27
- ```
35
+ ```sh
36
+ npm i -g osu-play # using npm
37
+ pnpm i -g osu-play # using pnpm
38
+ ```
28
39
 
29
40
  ## Usage
30
41
 
31
- ### Cli
32
-
33
42
  The `osu-play` command can be used with the following options:
43
+
34
44
  ```sh
35
45
  ➜ korigamik git:(main) ✗ osu-play --help
36
46
  Play music from your osu!lazer beatmaps from the terminal
37
47
  Usage: osu-play [options]
38
48
 
39
49
  Options:
40
- --help Show help [boolean]
41
- --version Show version number [boolean]
42
- -r, --reload Reload lazer database [boolean] [default: false]
43
- -d, --osuDataDir Osu!lazer data directory [string] [default: "~/.local/share/osu"]
44
- -c, --configDir Config directory [string] [default: "~/.config/osu-play"]
45
- -l, --loop Loop the playlist on end [boolean] [default: false]
50
+ --help Show help [boolean]
51
+ --version Show version number [boolean]
52
+ -r, --reload Reload lazer database [boolean] [default: false]
53
+ --exportPlaylist Export playlist to a file [string]
54
+ -d, --osuDataDir Osu!lazer data directory
55
+ [string] [default: "/home/origami/.local/share/osu"]
56
+ -c, --configDir Config directory
57
+ [string] [default: "/home/origami/.config/osu-play"]
58
+ -l, --loop Loop the playlist on end [boolean] [default: false]
46
59
  ```
47
60
 
48
61
  This package can be used as a library or as a cli application. To use the lazer
@@ -54,4 +67,3 @@ import { lazer } from "osu-play";
54
67
 
55
68
  const realm = getLazerDB();
56
69
  ```
57
-
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "osu-play",
3
- "version": "1.0.4",
3
+ "version": "1.0.7",
4
4
  "description": "Play music from your osu!lazer beatmaps from the terminal.",
5
5
  "type": "module",
6
6
  "main": "bin/osu-play.js",
@@ -31,11 +31,11 @@
31
31
  "devDependencies": {
32
32
  "@types/node": "^20.8.9",
33
33
  "@types/prompts": "^2.4.7",
34
- "tsup": "^7.2.0",
34
+ "tsup": "^8.0.2",
35
35
  "typescript": "^5.2.2"
36
36
  },
37
37
  "dependencies": {
38
- "@types/yargs": "^17.0.29",
38
+ "@types/yargs": "^17.0.32",
39
39
  "prompts": "^2.4.2",
40
40
  "realm": "^12.2.1",
41
41
  "yargs": "^17.7.2"
package/src/cli/main.ts CHANGED
@@ -1,6 +1,5 @@
1
1
  import path from "node:path";
2
- import { existsSync } from "node:fs";
3
- import { execFileSync } from "node:child_process";
2
+ import { existsSync, writeFileSync } from "node:fs";
4
3
 
5
4
  import Realm from "realm";
6
5
  import prompts from "prompts";
@@ -10,42 +9,55 @@ import { getLazerDB, getNamedFileHash, hashedFilePath } from "../realm/mod.js";
10
9
 
11
10
  import yargs from "yargs/yargs";
12
11
  import { hideBin } from "yargs/helpers";
12
+ import util from "node:util";
13
+ import { execFile } from "node:child_process";
14
+
15
+ const execFilePromise = util.promisify(execFile);
13
16
 
14
17
  export function getArgs() {
15
18
  const argv = yargs(hideBin(process.argv))
16
19
  .usage("Play music from your osu!lazer beatmaps from the terminal\nUsage: $0 [options]")
17
20
  .options({
18
- reload: {
19
- type: "boolean",
20
- default: false,
21
- alias: "r",
22
- describe: "Reload lazer database",
23
- },
24
- osuDataDir: {
25
- type: "string",
26
- default: path.join(getDataDir() || ".", "osu"),
27
- alias: "d",
28
- describe: "Osu!lazer data directory",
29
- },
30
- configDir: {
31
- type: "string",
32
- default: path.join(getConfigDir() || ".", "osu-play"),
33
- alias: "c",
34
- describe: "Config directory",
35
- },
36
- loop: {
37
- type: "boolean",
38
- default: false,
39
- alias: "l",
40
- describe: "Loop the playlist on end",
41
- },
42
- }).argv;
21
+ reload: {
22
+ type: "boolean",
23
+ default: false,
24
+ alias: "r",
25
+ describe: "Reload lazer database",
26
+ },
27
+ exportPlaylist: {
28
+ type: "string",
29
+ describe: "Export playlist to a file",
30
+ },
31
+ osuDataDir: {
32
+ type: "string",
33
+ default: path.join(getDataDir() || ".", "osu"),
34
+ alias: "d",
35
+ describe: "Osu!lazer data directory",
36
+ },
37
+ configDir: {
38
+ type: "string",
39
+ default: path.join(getConfigDir() || ".", "osu-play"),
40
+ alias: "c",
41
+ describe: "Config directory",
42
+ },
43
+ loop: {
44
+ type: "boolean",
45
+ default: false,
46
+ alias: "l",
47
+ describe: "Loop the playlist on end",
48
+ },
49
+ help: {
50
+ type: "boolean",
51
+ alias: "h",
52
+ describe: "Show help",
53
+ }
54
+ }).argv;
43
55
  return argv;
44
56
  }
45
57
 
46
58
  export async function main() {
47
59
  const argv = await getArgs();
48
- console.log("[INFO] OSU!list");
60
+ console.log("[INFO] osu!play");
49
61
 
50
62
  let reload = false;
51
63
  let osuDataDir = argv.osuDataDir;
@@ -56,7 +68,7 @@ export async function main() {
56
68
  }
57
69
 
58
70
  if (argv.osuDataDir !== getDataDir()) {
59
- console.log(`[INFO] Using osu!lazer data directory: ${argv.osuDataDir}`);
71
+ console.log(`[INFO] Using osu!lazer data directory: ${ argv.osuDataDir }`);
60
72
  }
61
73
 
62
74
  const realmDBPath = getRealmDBPath(argv.configDir, { reload, osuDataDir });
@@ -67,14 +79,12 @@ export async function main() {
67
79
  }
68
80
 
69
81
  const currentSchema = Realm.schemaVersion(realmDBPath);
70
- console.log(`currentSchema: ${currentSchema}`);
82
+ console.log(`currentSchema: ${ currentSchema }`);
71
83
 
72
84
  Realm.flags.ALLOW_CLEAR_TEST_STATE = true;
73
85
 
74
86
  const realm: Realm = await getLazerDB(realmDBPath);
75
87
 
76
- console.log(`realm.isClosed: ${realm.isClosed}`);
77
-
78
88
  const beatmapSets = realm.objects(BeatmapSet);
79
89
 
80
90
  const songSet = new Set<string>();
@@ -92,14 +102,21 @@ export async function main() {
92
102
  songSet.add(hash);
93
103
  const meta = beatmap.Metadata;
94
104
  const path = hashedFilePath(hash);
95
- const title = `${meta.Title} : ${meta.Artist} - ${meta.TitleUnicode} : ${meta.ArtistUnicode}`;
105
+ const title = `${ meta.Title } : ${ meta.Artist } - ${ meta.TitleUnicode } : ${ meta.ArtistUnicode }`;
96
106
  uniqueBeatmaps.push({ title, path });
97
107
  }
98
108
  }
99
109
 
100
- console.log(`beatmap songs: ${beatmapSets.length}`);
110
+ console.log(`beatmap songs: ${ beatmapSets.length }`);
111
+
112
+ if (argv.exportPlaylist) {
113
+ console.log(`[INFO] Exporting playlist to ${ argv.exportPlaylist }`);
114
+ const playlist = uniqueBeatmaps.map((mp) => mp.path).join("\n");
115
+ writeFileSync(argv.exportPlaylist, playlist);
116
+ console.log(`[INFO] Done. Use something like \`mpv --playlist=${ argv.exportPlaylist }\` to play the playlist`);
117
+ return;
118
+ }
101
119
 
102
- // Get the map index from the user
103
120
  let selectedBeatmap: number = (
104
121
  await prompts({
105
122
  type: "autocomplete",
@@ -111,22 +128,18 @@ export async function main() {
111
128
  })),
112
129
  })
113
130
  ).beatmap;
131
+ console.log(`Selected: ${ selectedBeatmap }`);
114
132
 
115
- for (let i = selectedBeatmap; i < uniqueBeatmaps.length; ++i) {
133
+ let i = selectedBeatmap
134
+
135
+ for (; i < uniqueBeatmaps.length; ++i) {
116
136
  const beatmap = uniqueBeatmaps[i];
117
- console.log(`Map : ${beatmap.title}`);
137
+ console.log(`Map : ${ beatmap.title }`);
118
138
  if (beatmap.path && existsSync(beatmap.path)) {
119
- // Open file using exo-open.
120
- console.log(`File exists: ${beatmap.path}`);
121
- console.log(`Playing ${beatmap.title}`);
122
- try {
123
- execFileSync("exo-open", [beatmap.path]);
124
- } catch (err) {
125
- console.log(`Error: ${err}`);
126
- break;
127
- }
139
+ console.log(`Playing ${ beatmap.title }`);
140
+ await execFilePromise('exo-open', [beatmap.path]);
128
141
  } else {
129
- console.log(`File does not exist: ${beatmap.path}`);
142
+ console.log(`File does not exist: ${ beatmap.path }`);
130
143
  }
131
144
  if (i < uniqueBeatmaps.length - 1) {
132
145
  // Wait 1 second between
@@ -134,13 +147,10 @@ export async function main() {
134
147
  } else if (argv.loop) {
135
148
  console.log('[INFO] Looping playlist');
136
149
  i = 0;
137
- } else {
150
+ } else {
138
151
  console.log('[INFO] Done. Use --loop to loop the playlist');
139
152
  }
140
153
  }
141
154
 
142
155
  realm.close();
143
- console.log(`realm.isClosed: ${realm.isClosed}`);
144
-
145
- // Realm.clearTestState();
146
156
  }
package/src/realm/mod.ts CHANGED
@@ -21,7 +21,7 @@ export const getLazerDB = async (realmDBPath: string) => {
21
21
  RealmUser,
22
22
  ],
23
23
  path: realmDBPath,
24
- schemaVersion: 36,
24
+ schemaVersion: 41,
25
25
  onMigration: (oldRealm, newRealm) => {
26
26
  console.log(
27
27
  `[onMigration]: Migrating ${oldRealm.path} - ${oldRealm.schemaVersion} -> ${newRealm.path} - ${newRealm.schemaVersion}`,
package/dist/index.d.ts DELETED
@@ -1,124 +0,0 @@
1
- import Realm, { ObjectSchema } from 'realm';
2
-
3
- declare function getDataDir(): string | undefined;
4
- declare function getConfigDir(): string | undefined;
5
- /**
6
- * Get Realm for the app, import to the config if it doesn't exist
7
- */
8
- declare function getRealmDBPath(appConfigDir: string, options?: {
9
- osuDataDir: string;
10
- reload: boolean;
11
- }): string | null;
12
-
13
- declare const mod$1_getConfigDir: typeof getConfigDir;
14
- declare const mod$1_getDataDir: typeof getDataDir;
15
- declare const mod$1_getRealmDBPath: typeof getRealmDBPath;
16
- declare namespace mod$1 {
17
- export {
18
- mod$1_getConfigDir as getConfigDir,
19
- mod$1_getDataDir as getDataDir,
20
- mod$1_getRealmDBPath as getRealmDBPath,
21
- };
22
- }
23
-
24
- declare class RealmUser extends Realm.Object<RealmUser> {
25
- OnlineID: number;
26
- Username?: string;
27
- CountryCode?: string;
28
- static embedded: boolean;
29
- static schema: ObjectSchema;
30
- }
31
-
32
- declare class BeatmapMetadata extends Realm.Object<BeatmapMetadata> {
33
- Title?: string;
34
- TitleUnicode?: string;
35
- Artist?: string;
36
- ArtistUnicode?: string;
37
- Author?: RealmUser;
38
- Source?: string;
39
- Tags?: string;
40
- PreviewTime?: number;
41
- AudioFile?: string;
42
- BackgroundFile?: string;
43
- static schema: ObjectSchema;
44
- }
45
-
46
- declare class Beatmap extends Realm.Object<Beatmap> {
47
- ID: string;
48
- DifficultyName?: string;
49
- Ruleset: any;
50
- Difficulty: any;
51
- Metadata: BeatmapMetadata;
52
- UserSettings: any;
53
- BeatmapSet: any;
54
- Status: number;
55
- OnlineID: number;
56
- Length: number;
57
- BPM: number;
58
- Hash?: string;
59
- StarRating: number;
60
- MD5Hash?: string;
61
- OnlineMD5Hash?: string;
62
- LastLocalUpdate?: Date;
63
- LastOnlineUpdate?: Date;
64
- Hidden: boolean;
65
- AudioLeadIn: number;
66
- StackLeniency: number;
67
- SpecialStyle: boolean;
68
- LetterboxInBreaks: boolean;
69
- WidescreenStoryboard: boolean;
70
- EpilepsyWarning: boolean;
71
- SamplesMatchPlaybackRate: boolean;
72
- LastPlayed?: Date;
73
- DistanceSpacing: number;
74
- BeatDivisor: number;
75
- GridSize: number;
76
- TimelineZoom: number;
77
- EditorTimestamp?: number;
78
- CountdownOffset: number;
79
- static schema: ObjectSchema;
80
- }
81
-
82
- declare class RealmFile extends Realm.Object<RealmFile> {
83
- Hash?: string;
84
- static schema: ObjectSchema;
85
- }
86
-
87
- declare class RealmNamedFileUsage extends Realm.Object<RealmNamedFileUsage> {
88
- File: RealmFile;
89
- Filename?: string;
90
- static embedded: boolean;
91
- static schema: ObjectSchema;
92
- }
93
-
94
- declare class BeatmapSet extends Realm.Object<BeatmapSet> {
95
- ID: string;
96
- OnlineID: number;
97
- DateAdded: Date;
98
- DateSubmitted?: Date;
99
- DateRanked?: Date;
100
- Beatmaps: Array<Beatmap>;
101
- Files: Array<RealmNamedFileUsage>;
102
- Status: number;
103
- DeletePending: boolean;
104
- Hash?: string;
105
- Protected: boolean;
106
- static schema: ObjectSchema;
107
- }
108
-
109
- declare const getLazerDB: (realmDBPath: string) => Promise<Realm>;
110
- declare const hashedFilePath: (hash: string) => string | null;
111
- declare const getNamedFileHash: (fileName: string, beatmapSet: BeatmapSet) => string | undefined;
112
-
113
- declare const mod_getLazerDB: typeof getLazerDB;
114
- declare const mod_getNamedFileHash: typeof getNamedFileHash;
115
- declare const mod_hashedFilePath: typeof hashedFilePath;
116
- declare namespace mod {
117
- export {
118
- mod_getLazerDB as getLazerDB,
119
- mod_getNamedFileHash as getNamedFileHash,
120
- mod_hashedFilePath as hashedFilePath,
121
- };
122
- }
123
-
124
- export { mod as lazer, mod$1 as utils };
package/dist/index.js DELETED
@@ -1,329 +0,0 @@
1
- var __defProp = Object.defineProperty;
2
- var __export = (target, all) => {
3
- for (var name in all)
4
- __defProp(target, name, { get: all[name], enumerable: true });
5
- };
6
-
7
- // src/utils/mod.ts
8
- var mod_exports = {};
9
- __export(mod_exports, {
10
- getConfigDir: () => getConfigDir,
11
- getDataDir: () => getDataDir,
12
- getRealmDBPath: () => getRealmDBPath
13
- });
14
- import path from "path";
15
- import { copyFileSync, existsSync, mkdirSync } from "fs";
16
- function getDataDir() {
17
- switch (process.platform) {
18
- case "linux":
19
- case "openbsd":
20
- case "freebsd": {
21
- const xdg = process.env["XDG_DATA_HOME"];
22
- if (xdg)
23
- return xdg;
24
- const home = process.env["HOME"];
25
- if (home)
26
- return path.join(home, ".local", "share");
27
- break;
28
- }
29
- case "darwin": {
30
- const home = process.env["HOME"];
31
- if (home)
32
- return path.join(home, "Library", "Application Support");
33
- break;
34
- }
35
- case "win32":
36
- return process.env["LOCALAPPDATA"] ?? void 0;
37
- }
38
- return void 0;
39
- }
40
- function getConfigDir() {
41
- switch (process.platform) {
42
- case "openbsd":
43
- case "freebsd":
44
- case "linux": {
45
- const xdg = process.env["XDG_CONFIG_HOME"];
46
- if (xdg)
47
- return xdg;
48
- const home = process.env["HOME"];
49
- if (home)
50
- return path.join(home, ".config");
51
- break;
52
- }
53
- case "darwin": {
54
- const home = process.env["HOME"];
55
- if (home)
56
- return path.join(home, "Library", "Preferences");
57
- break;
58
- }
59
- case "win32":
60
- return process.env["APPDATA"] ?? void 0;
61
- }
62
- return void 0;
63
- }
64
- function getRealmDBPath(appConfigDir, options = { reload: false, osuDataDir: getDataDir() || "." }) {
65
- const localDBPath = path.join(appConfigDir, "client.realm");
66
- if (!options.reload && existsSync(localDBPath))
67
- return localDBPath;
68
- const osuDBPath = path.join(options.osuDataDir, "client.realm");
69
- if (existsSync(osuDBPath)) {
70
- console.log(`[getRealmDBPath]: ${osuDBPath} is being imported from osu!lazer to ${localDBPath}`);
71
- mkdirSync(appConfigDir, { recursive: true });
72
- copyFileSync(osuDBPath, localDBPath);
73
- return localDBPath;
74
- } else {
75
- console.log(`[getRealmDBPath]: ${osuDBPath} not found`);
76
- return null;
77
- }
78
- }
79
-
80
- // src/realm/mod.ts
81
- var mod_exports2 = {};
82
- __export(mod_exports2, {
83
- getLazerDB: () => getLazerDB,
84
- getNamedFileHash: () => getNamedFileHash,
85
- hashedFilePath: () => hashedFilePath
86
- });
87
- import Realm7 from "realm";
88
- import path2 from "path";
89
-
90
- // src/realm/schema/beatmap.ts
91
- import Realm from "realm";
92
- var Beatmap = class extends Realm.Object {
93
- ID;
94
- DifficultyName;
95
- Ruleset;
96
- Difficulty;
97
- Metadata;
98
- UserSettings;
99
- BeatmapSet;
100
- Status;
101
- OnlineID;
102
- Length;
103
- BPM;
104
- Hash;
105
- StarRating;
106
- MD5Hash;
107
- OnlineMD5Hash;
108
- LastLocalUpdate;
109
- LastOnlineUpdate;
110
- Hidden;
111
- AudioLeadIn;
112
- StackLeniency;
113
- SpecialStyle;
114
- LetterboxInBreaks;
115
- WidescreenStoryboard;
116
- EpilepsyWarning;
117
- SamplesMatchPlaybackRate;
118
- LastPlayed;
119
- DistanceSpacing;
120
- BeatDivisor;
121
- GridSize;
122
- TimelineZoom;
123
- EditorTimestamp;
124
- CountdownOffset;
125
- static schema = {
126
- name: "Beatmap",
127
- primaryKey: "ID",
128
- properties: {
129
- ID: { type: "uuid", default: "" },
130
- DifficultyName: { type: "string", default: "", optional: true },
131
- // Ruleset: { type: "object", objectType: "Ruleset", default: null },
132
- // Difficulty: { type: "object", objectType: "BeatmapDifficulty", default: null },
133
- Metadata: {
134
- type: "object",
135
- objectType: "BeatmapMetadata",
136
- default: null
137
- },
138
- // UserSettings: { type: "object", objectType: "BeatmapUserSettings", default: null },
139
- BeatmapSet: { type: "object", objectType: "BeatmapSet", default: null },
140
- Status: { type: "int", default: -3 },
141
- OnlineID: { type: "int", default: -1 },
142
- Length: { type: "double", default: 0 },
143
- BPM: { type: "double", default: 0 },
144
- Hash: { type: "string", default: "", optional: true },
145
- StarRating: { type: "double", default: -1 },
146
- MD5Hash: { type: "string", default: "", optional: true },
147
- OnlineMD5Hash: {
148
- type: "string",
149
- default: "",
150
- optional: true
151
- },
152
- LastLocalUpdate: { type: "date", optional: true },
153
- LastOnlineUpdate: { type: "date", optional: true },
154
- Hidden: { type: "bool", default: false },
155
- AudioLeadIn: { type: "double", default: 0 },
156
- StackLeniency: { type: "float", default: 0.7 },
157
- SpecialStyle: { type: "bool", default: false },
158
- LetterboxInBreaks: { type: "bool", default: false },
159
- WidescreenStoryboard: { type: "bool", default: false },
160
- EpilepsyWarning: { type: "bool", default: false },
161
- SamplesMatchPlaybackRate: { type: "bool", default: false },
162
- LastPlayed: { type: "date", optional: true },
163
- DistanceSpacing: { type: "double", default: 0 },
164
- BeatDivisor: { type: "int", default: 0 },
165
- GridSize: { type: "int", default: 0 },
166
- TimelineZoom: { type: "double", default: 0 },
167
- EditorTimestamp: { type: "double", optional: true },
168
- CountdownOffset: { type: "int", default: 0 }
169
- }
170
- };
171
- };
172
-
173
- // src/realm/schema/beatmapMetadata.ts
174
- import Realm2 from "realm";
175
- var BeatmapMetadata = class extends Realm2.Object {
176
- Title;
177
- TitleUnicode;
178
- Artist;
179
- ArtistUnicode;
180
- Author;
181
- Source;
182
- Tags;
183
- PreviewTime;
184
- AudioFile;
185
- BackgroundFile;
186
- static schema = {
187
- name: "BeatmapMetadata",
188
- properties: {
189
- Title: { type: "string", default: "", optional: true },
190
- TitleUnicode: { type: "string", default: "", optional: true },
191
- Artist: { type: "string", default: "", optional: true },
192
- ArtistUnicode: { type: "string", default: "", optional: true },
193
- Author: { type: "object", objectType: "RealmUser", default: null },
194
- Source: { type: "string", default: "", optional: true },
195
- Tags: { type: "string", default: "", optional: true },
196
- PreviewTime: { type: "int", default: 0 },
197
- AudioFile: { type: "string", default: "", optional: true },
198
- BackgroundFile: { type: "string", default: "", optional: true }
199
- }
200
- };
201
- };
202
-
203
- // src/realm/schema/beatmapSet.ts
204
- import Realm3 from "realm";
205
- var BeatmapSet = class extends Realm3.Object {
206
- ID;
207
- OnlineID;
208
- DateAdded;
209
- DateSubmitted;
210
- DateRanked;
211
- Beatmaps;
212
- Files;
213
- Status;
214
- DeletePending;
215
- Hash;
216
- Protected;
217
- static schema = {
218
- name: "BeatmapSet",
219
- primaryKey: "ID",
220
- properties: {
221
- ID: { type: "uuid", default: "" },
222
- OnlineID: { type: "int", default: -1 },
223
- DateAdded: { type: "date" },
224
- DateSubmitted: { type: "date", optional: true },
225
- DateRanked: { type: "date", optional: true },
226
- Beatmaps: { type: "list", objectType: "Beatmap", default: [] },
227
- Files: { type: "list", objectType: "RealmNamedFileUsage", default: [] },
228
- Status: { type: "int", default: -3 },
229
- DeletePending: { type: "bool", default: false },
230
- Hash: { type: "string", default: "", optional: true },
231
- Protected: { type: "bool", default: false }
232
- }
233
- };
234
- };
235
-
236
- // src/realm/schema/realmFile.ts
237
- import Realm4 from "realm";
238
- var RealmFile = class extends Realm4.Object {
239
- Hash;
240
- static schema = {
241
- name: "File",
242
- primaryKey: "Hash",
243
- properties: {
244
- Hash: { type: "string", default: "", optional: true }
245
- }
246
- };
247
- };
248
-
249
- // src/realm/schema/realmUser.ts
250
- import Realm5 from "realm";
251
- var RealmUser = class extends Realm5.Object {
252
- OnlineID;
253
- Username;
254
- CountryCode;
255
- static embedded = true;
256
- static schema = {
257
- name: "RealmUser",
258
- embedded: true,
259
- properties: {
260
- OnlineID: { type: "int", default: 1 },
261
- Username: { type: "string", default: "", optional: true },
262
- CountryCode: { type: "string", optional: true }
263
- }
264
- };
265
- };
266
-
267
- // src/realm/schema/realmNamedFileUsage.ts
268
- import Realm6 from "realm";
269
- var RealmNamedFileUsage = class extends Realm6.Object {
270
- File;
271
- Filename;
272
- static embedded = true;
273
- static schema = {
274
- name: "RealmNamedFileUsage",
275
- embedded: true,
276
- properties: {
277
- File: "File",
278
- Filename: { type: "string", optional: true }
279
- }
280
- };
281
- };
282
-
283
- // src/realm/mod.ts
284
- var getLazerDB = async (realmDBPath) => {
285
- const realm = await Realm7.open({
286
- schema: [
287
- BeatmapSet,
288
- RealmFile,
289
- RealmNamedFileUsage,
290
- Beatmap,
291
- BeatmapMetadata,
292
- RealmUser
293
- ],
294
- path: realmDBPath,
295
- schemaVersion: 36,
296
- onMigration: (oldRealm, newRealm) => {
297
- console.log(
298
- `[onMigration]: Migrating ${oldRealm.path} - ${oldRealm.schemaVersion} -> ${newRealm.path} - ${newRealm.schemaVersion}`
299
- );
300
- }
301
- });
302
- return realm;
303
- };
304
- var hashedFilePath = (hash) => {
305
- const dataDir = getDataDir();
306
- if (!dataDir)
307
- return null;
308
- return path2.join(
309
- dataDir,
310
- "osu",
311
- "files",
312
- hash.slice(0, 1),
313
- hash.slice(0, 2),
314
- hash
315
- );
316
- };
317
- var getNamedFileHash = (fileName, beatmapSet) => {
318
- const files = beatmapSet.Files;
319
- for (const file of files) {
320
- if (file.Filename == fileName)
321
- return file.File.Hash;
322
- }
323
- return void 0;
324
- };
325
- export {
326
- mod_exports2 as lazer,
327
- mod_exports as utils
328
- };
329
- //# sourceMappingURL=index.js.map
package/dist/index.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/utils/mod.ts","../src/realm/mod.ts","../src/realm/schema/beatmap.ts","../src/realm/schema/beatmapMetadata.ts","../src/realm/schema/beatmapSet.ts","../src/realm/schema/realmFile.ts","../src/realm/schema/realmUser.ts","../src/realm/schema/realmNamedFileUsage.ts"],"sourcesContent":["import path from \"node:path\";\nimport { copyFileSync, existsSync, mkdirSync } from \"node:fs\";\n\nexport function getDataDir(): string | undefined {\n switch (process.platform) {\n case \"linux\":\n case \"openbsd\":\n case \"freebsd\": {\n const xdg = process.env[\"XDG_DATA_HOME\"];\n if (xdg) return xdg;\n const home = process.env[\"HOME\"];\n if (home) return path.join(home, \".local\", \"share\");\n break;\n }\n\n case \"darwin\": {\n const home = process.env[\"HOME\"];\n if (home) return path.join(home, \"Library\", \"Application Support\");\n break;\n }\n\n case \"win32\":\n return process.env[\"LOCALAPPDATA\"] ?? undefined;\n }\n\n return undefined;\n}\n\nexport function getConfigDir(): string | undefined {\n switch (process.platform) {\n case \"openbsd\":\n case \"freebsd\":\n case \"linux\": {\n const xdg = process.env[\"XDG_CONFIG_HOME\"];\n if (xdg) return xdg;\n const home = process.env[\"HOME\"];\n if (home) return path.join(home, \".config\");\n break;\n }\n\n case \"darwin\": {\n const home = process.env[\"HOME\"];\n if (home) return path.join(home, \"Library\", \"Preferences\");\n break;\n }\n\n case \"win32\":\n return process.env[\"APPDATA\"] ?? undefined;\n }\n\n return undefined;\n}\n\n/**\n * Get Realm for the app, import to the config if it doesn't exist\n */\nexport function getRealmDBPath(\n appConfigDir: string,\n options: {\n osuDataDir: string;\n reload: boolean;\n } = { reload: false, osuDataDir: getDataDir() || \".\" },\n) {\n const localDBPath = path.join(appConfigDir, \"client.realm\");\n if (!options.reload && existsSync(localDBPath)) return localDBPath;\n\n const osuDBPath = path.join(options.osuDataDir, \"client.realm\");\n if (existsSync(osuDBPath)) {\n console.log( `[getRealmDBPath]: ${osuDBPath} is being imported from osu!lazer to ${localDBPath}`);\n mkdirSync(appConfigDir, { recursive: true });\n copyFileSync(osuDBPath, localDBPath );\n return localDBPath;\n } else {\n console.log(`[getRealmDBPath]: ${osuDBPath} not found`);\n return null;\n }\n}\n","import Realm from \"realm\";\nimport path from \"node:path\";\nimport { getDataDir } from \"../utils/mod.js\";\nimport {\n Beatmap,\n BeatmapMetadata,\n BeatmapSet,\n RealmFile,\n RealmNamedFileUsage,\n RealmUser,\n} from \"./schema/mod.js\";\n\nexport const getLazerDB = async (realmDBPath: string) => {\n const realm = await Realm.open({\n schema: [\n BeatmapSet,\n RealmFile,\n RealmNamedFileUsage,\n Beatmap,\n BeatmapMetadata,\n RealmUser,\n ],\n path: realmDBPath,\n schemaVersion: 36,\n onMigration: (oldRealm, newRealm) => {\n console.log(\n `[onMigration]: Migrating ${oldRealm.path} - ${oldRealm.schemaVersion} -> ${newRealm.path} - ${newRealm.schemaVersion}`,\n );\n },\n });\n\n return realm;\n};\n\nexport const hashedFilePath = (hash: string) => {\n const dataDir = getDataDir();\n if (!dataDir) return null;\n return path.join(\n dataDir,\n \"osu\",\n \"files\",\n hash.slice(0, 1),\n hash.slice(0, 2),\n hash,\n );\n};\n\nexport const getNamedFileHash = (fileName: string, beatmapSet: BeatmapSet) => {\n const files = beatmapSet.Files;\n for (const file of files) {\n if (file.Filename == fileName) return file.File.Hash;\n }\n return undefined;\n};\n","import Realm from \"realm\";\nimport type { ObjectSchema } from \"realm\";\nimport { BeatmapMetadata } from \"./beatmapMetadata.js\";\n\nexport class Beatmap extends Realm.Object<Beatmap> {\n ID!: string;\n DifficultyName?: string;\n Ruleset!: any;\n Difficulty!: any;\n Metadata!: BeatmapMetadata;\n UserSettings!: any;\n BeatmapSet!: any;\n Status!: number;\n OnlineID!: number;\n Length!: number;\n BPM!: number;\n Hash?: string;\n StarRating!: number;\n MD5Hash?: string;\n OnlineMD5Hash?: string;\n LastLocalUpdate?: Date;\n LastOnlineUpdate?: Date;\n Hidden!: boolean;\n AudioLeadIn!: number;\n StackLeniency!: number;\n SpecialStyle!: boolean;\n LetterboxInBreaks!: boolean;\n WidescreenStoryboard!: boolean;\n EpilepsyWarning!: boolean;\n SamplesMatchPlaybackRate!: boolean;\n LastPlayed?: Date;\n DistanceSpacing!: number;\n BeatDivisor!: number;\n GridSize!: number;\n TimelineZoom!: number;\n EditorTimestamp?: number;\n CountdownOffset!: number;\n\n static schema: ObjectSchema = {\n name: \"Beatmap\",\n primaryKey: \"ID\",\n properties: {\n ID: { type: \"uuid\", default: \"\" },\n DifficultyName: { type: \"string\", default: \"\", optional: true },\n // Ruleset: { type: \"object\", objectType: \"Ruleset\", default: null },\n // Difficulty: { type: \"object\", objectType: \"BeatmapDifficulty\", default: null },\n Metadata: {\n type: \"object\",\n objectType: \"BeatmapMetadata\",\n default: null,\n },\n // UserSettings: { type: \"object\", objectType: \"BeatmapUserSettings\", default: null },\n BeatmapSet: { type: \"object\", objectType: \"BeatmapSet\", default: null },\n Status: { type: \"int\", default: -3 },\n OnlineID: { type: \"int\", default: -1 },\n Length: { type: \"double\", default: 0 },\n BPM: { type: \"double\", default: 0 },\n Hash: { type: \"string\", default: \"\", optional: true },\n StarRating: { type: \"double\", default: -1 },\n MD5Hash: { type: \"string\", default: \"\", optional: true },\n OnlineMD5Hash: {\n type: \"string\",\n default: \"\",\n optional: true,\n },\n LastLocalUpdate: { type: \"date\", optional: true },\n LastOnlineUpdate: { type: \"date\", optional: true },\n Hidden: { type: \"bool\", default: false },\n AudioLeadIn: { type: \"double\", default: 0 },\n StackLeniency: { type: \"float\", default: 0.7 },\n SpecialStyle: { type: \"bool\", default: false },\n LetterboxInBreaks: { type: \"bool\", default: false },\n WidescreenStoryboard: { type: \"bool\", default: false },\n EpilepsyWarning: { type: \"bool\", default: false },\n SamplesMatchPlaybackRate: { type: \"bool\", default: false },\n LastPlayed: { type: \"date\", optional: true },\n DistanceSpacing: { type: \"double\", default: 0 },\n BeatDivisor: { type: \"int\", default: 0 },\n GridSize: { type: \"int\", default: 0 },\n TimelineZoom: { type: \"double\", default: 0 },\n EditorTimestamp: { type: \"double\", optional: true },\n CountdownOffset: { type: \"int\", default: 0 },\n },\n };\n}\n","import Realm from \"realm\";\nimport type { ObjectSchema } from \"realm\";\nimport { RealmUser } from \"./realmUser.js\";\n\nexport class BeatmapMetadata extends Realm.Object<BeatmapMetadata> {\n Title?: string;\n TitleUnicode?: string;\n Artist?: string;\n ArtistUnicode?: string;\n Author?: RealmUser;\n Source?: string;\n Tags?: string;\n PreviewTime?: number;\n AudioFile?: string;\n BackgroundFile?: string;\n\n static schema: ObjectSchema = {\n name: \"BeatmapMetadata\",\n properties: {\n Title: { type: \"string\", default: \"\", optional: true },\n TitleUnicode: { type: \"string\", default: \"\", optional: true },\n Artist: { type: \"string\", default: \"\", optional: true },\n ArtistUnicode: { type: \"string\", default: \"\", optional: true },\n Author: { type: \"object\", objectType: \"RealmUser\", default: null },\n Source: { type: \"string\", default: \"\", optional: true },\n Tags: { type: \"string\", default: \"\", optional: true },\n PreviewTime: { type: \"int\", default: 0 },\n AudioFile: { type: \"string\", default: \"\", optional: true },\n BackgroundFile: { type: \"string\", default: \"\", optional: true },\n },\n };\n}\n\n","import Realm from \"realm\";\nimport type { ObjectSchema } from \"realm\";\nimport { Beatmap } from \"./beatmap.js\";\nimport { RealmNamedFileUsage } from \"./realmNamedFileUsage.js\";\n\nexport class BeatmapSet extends Realm.Object<BeatmapSet> {\n ID!: string;\n OnlineID!: number;\n DateAdded!: Date;\n DateSubmitted?: Date;\n DateRanked?: Date;\n Beatmaps!: Array<Beatmap>;\n Files!: Array<RealmNamedFileUsage>;\n Status!: number;\n DeletePending!: boolean;\n Hash?: string;\n Protected!: boolean;\n\n static schema: ObjectSchema = {\n name: \"BeatmapSet\",\n primaryKey: \"ID\",\n properties: {\n ID: { type: \"uuid\", default: \"\" },\n OnlineID: { type: \"int\", default: -1 },\n DateAdded: { type: \"date\" },\n DateSubmitted: { type: \"date\", optional: true },\n DateRanked: { type: \"date\", optional: true },\n Beatmaps: { type: \"list\", objectType: \"Beatmap\", default: [] },\n Files: { type: \"list\", objectType: \"RealmNamedFileUsage\", default: [] },\n Status: { type: \"int\", default: -3 },\n DeletePending: { type: \"bool\", default: false },\n Hash: { type: \"string\", default: \"\", optional: true },\n Protected: { type: \"bool\", default: false },\n },\n };\n}\n","import Realm from \"realm\";\nimport type { ObjectSchema } from \"realm\";\n\nexport class RealmFile extends Realm.Object<RealmFile> {\n Hash?: string;\n\n static schema: ObjectSchema = {\n name: \"File\",\n primaryKey: \"Hash\",\n properties: {\n Hash: { type: \"string\", default: \"\", optional: true },\n },\n };\n}\n\n","import Realm from \"realm\";\nimport type { ObjectSchema } from \"realm\";\n\nexport class RealmUser extends Realm.Object<RealmUser> {\n OnlineID!: number;\n Username?: string;\n CountryCode?: string;\n\n static embedded = true;\n\n static schema: ObjectSchema = {\n name: \"RealmUser\",\n embedded: true,\n properties: {\n OnlineID: { type: \"int\", default: 1 },\n Username: { type: \"string\", default: \"\", optional: true },\n CountryCode: { type: \"string\", optional: true },\n },\n };\n}\n\n","import Realm from \"realm\";\nimport type { ObjectSchema } from \"realm\";\nimport { RealmFile } from \"./realmFile.js\";\n\nexport class RealmNamedFileUsage extends Realm.Object<RealmNamedFileUsage> {\n File!: RealmFile;\n Filename?: string;\n\n static embedded = true;\n\n static schema: ObjectSchema = {\n name: \"RealmNamedFileUsage\",\n embedded: true,\n properties: {\n File: \"File\",\n Filename: { type: \"string\", optional: true },\n },\n };\n}\n"],"mappings":"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","names":["mod_exports","Realm","path","Realm","Realm","Realm","Realm","Realm","Realm","path"]}
@@ -1,20 +0,0 @@
1
- declare function getArgs(): {
2
- [x: string]: unknown;
3
- reload: boolean;
4
- osuDataDir: string;
5
- configDir: string;
6
- loop: boolean;
7
- _: (string | number)[];
8
- $0: string;
9
- } | Promise<{
10
- [x: string]: unknown;
11
- reload: boolean;
12
- osuDataDir: string;
13
- configDir: string;
14
- loop: boolean;
15
- _: (string | number)[];
16
- $0: string;
17
- }>;
18
- declare function main(): Promise<void>;
19
-
20
- export { getArgs, main };
@@ -1,426 +0,0 @@
1
- // src/cli/main.ts
2
- import path3 from "path";
3
- import { existsSync as existsSync2 } from "fs";
4
- import { execFileSync } from "child_process";
5
- import Realm8 from "realm";
6
- import prompts from "prompts";
7
-
8
- // src/realm/schema/beatmap.ts
9
- import Realm from "realm";
10
- var Beatmap = class extends Realm.Object {
11
- ID;
12
- DifficultyName;
13
- Ruleset;
14
- Difficulty;
15
- Metadata;
16
- UserSettings;
17
- BeatmapSet;
18
- Status;
19
- OnlineID;
20
- Length;
21
- BPM;
22
- Hash;
23
- StarRating;
24
- MD5Hash;
25
- OnlineMD5Hash;
26
- LastLocalUpdate;
27
- LastOnlineUpdate;
28
- Hidden;
29
- AudioLeadIn;
30
- StackLeniency;
31
- SpecialStyle;
32
- LetterboxInBreaks;
33
- WidescreenStoryboard;
34
- EpilepsyWarning;
35
- SamplesMatchPlaybackRate;
36
- LastPlayed;
37
- DistanceSpacing;
38
- BeatDivisor;
39
- GridSize;
40
- TimelineZoom;
41
- EditorTimestamp;
42
- CountdownOffset;
43
- static schema = {
44
- name: "Beatmap",
45
- primaryKey: "ID",
46
- properties: {
47
- ID: { type: "uuid", default: "" },
48
- DifficultyName: { type: "string", default: "", optional: true },
49
- // Ruleset: { type: "object", objectType: "Ruleset", default: null },
50
- // Difficulty: { type: "object", objectType: "BeatmapDifficulty", default: null },
51
- Metadata: {
52
- type: "object",
53
- objectType: "BeatmapMetadata",
54
- default: null
55
- },
56
- // UserSettings: { type: "object", objectType: "BeatmapUserSettings", default: null },
57
- BeatmapSet: { type: "object", objectType: "BeatmapSet", default: null },
58
- Status: { type: "int", default: -3 },
59
- OnlineID: { type: "int", default: -1 },
60
- Length: { type: "double", default: 0 },
61
- BPM: { type: "double", default: 0 },
62
- Hash: { type: "string", default: "", optional: true },
63
- StarRating: { type: "double", default: -1 },
64
- MD5Hash: { type: "string", default: "", optional: true },
65
- OnlineMD5Hash: {
66
- type: "string",
67
- default: "",
68
- optional: true
69
- },
70
- LastLocalUpdate: { type: "date", optional: true },
71
- LastOnlineUpdate: { type: "date", optional: true },
72
- Hidden: { type: "bool", default: false },
73
- AudioLeadIn: { type: "double", default: 0 },
74
- StackLeniency: { type: "float", default: 0.7 },
75
- SpecialStyle: { type: "bool", default: false },
76
- LetterboxInBreaks: { type: "bool", default: false },
77
- WidescreenStoryboard: { type: "bool", default: false },
78
- EpilepsyWarning: { type: "bool", default: false },
79
- SamplesMatchPlaybackRate: { type: "bool", default: false },
80
- LastPlayed: { type: "date", optional: true },
81
- DistanceSpacing: { type: "double", default: 0 },
82
- BeatDivisor: { type: "int", default: 0 },
83
- GridSize: { type: "int", default: 0 },
84
- TimelineZoom: { type: "double", default: 0 },
85
- EditorTimestamp: { type: "double", optional: true },
86
- CountdownOffset: { type: "int", default: 0 }
87
- }
88
- };
89
- };
90
-
91
- // src/realm/schema/beatmapMetadata.ts
92
- import Realm2 from "realm";
93
- var BeatmapMetadata = class extends Realm2.Object {
94
- Title;
95
- TitleUnicode;
96
- Artist;
97
- ArtistUnicode;
98
- Author;
99
- Source;
100
- Tags;
101
- PreviewTime;
102
- AudioFile;
103
- BackgroundFile;
104
- static schema = {
105
- name: "BeatmapMetadata",
106
- properties: {
107
- Title: { type: "string", default: "", optional: true },
108
- TitleUnicode: { type: "string", default: "", optional: true },
109
- Artist: { type: "string", default: "", optional: true },
110
- ArtistUnicode: { type: "string", default: "", optional: true },
111
- Author: { type: "object", objectType: "RealmUser", default: null },
112
- Source: { type: "string", default: "", optional: true },
113
- Tags: { type: "string", default: "", optional: true },
114
- PreviewTime: { type: "int", default: 0 },
115
- AudioFile: { type: "string", default: "", optional: true },
116
- BackgroundFile: { type: "string", default: "", optional: true }
117
- }
118
- };
119
- };
120
-
121
- // src/realm/schema/beatmapSet.ts
122
- import Realm3 from "realm";
123
- var BeatmapSet = class extends Realm3.Object {
124
- ID;
125
- OnlineID;
126
- DateAdded;
127
- DateSubmitted;
128
- DateRanked;
129
- Beatmaps;
130
- Files;
131
- Status;
132
- DeletePending;
133
- Hash;
134
- Protected;
135
- static schema = {
136
- name: "BeatmapSet",
137
- primaryKey: "ID",
138
- properties: {
139
- ID: { type: "uuid", default: "" },
140
- OnlineID: { type: "int", default: -1 },
141
- DateAdded: { type: "date" },
142
- DateSubmitted: { type: "date", optional: true },
143
- DateRanked: { type: "date", optional: true },
144
- Beatmaps: { type: "list", objectType: "Beatmap", default: [] },
145
- Files: { type: "list", objectType: "RealmNamedFileUsage", default: [] },
146
- Status: { type: "int", default: -3 },
147
- DeletePending: { type: "bool", default: false },
148
- Hash: { type: "string", default: "", optional: true },
149
- Protected: { type: "bool", default: false }
150
- }
151
- };
152
- };
153
-
154
- // src/realm/schema/realmFile.ts
155
- import Realm4 from "realm";
156
- var RealmFile = class extends Realm4.Object {
157
- Hash;
158
- static schema = {
159
- name: "File",
160
- primaryKey: "Hash",
161
- properties: {
162
- Hash: { type: "string", default: "", optional: true }
163
- }
164
- };
165
- };
166
-
167
- // src/realm/schema/realmUser.ts
168
- import Realm5 from "realm";
169
- var RealmUser = class extends Realm5.Object {
170
- OnlineID;
171
- Username;
172
- CountryCode;
173
- static embedded = true;
174
- static schema = {
175
- name: "RealmUser",
176
- embedded: true,
177
- properties: {
178
- OnlineID: { type: "int", default: 1 },
179
- Username: { type: "string", default: "", optional: true },
180
- CountryCode: { type: "string", optional: true }
181
- }
182
- };
183
- };
184
-
185
- // src/realm/schema/realmNamedFileUsage.ts
186
- import Realm6 from "realm";
187
- var RealmNamedFileUsage = class extends Realm6.Object {
188
- File;
189
- Filename;
190
- static embedded = true;
191
- static schema = {
192
- name: "RealmNamedFileUsage",
193
- embedded: true,
194
- properties: {
195
- File: "File",
196
- Filename: { type: "string", optional: true }
197
- }
198
- };
199
- };
200
-
201
- // src/utils/mod.ts
202
- import path from "path";
203
- import { copyFileSync, existsSync, mkdirSync } from "fs";
204
- function getDataDir() {
205
- switch (process.platform) {
206
- case "linux":
207
- case "openbsd":
208
- case "freebsd": {
209
- const xdg = process.env["XDG_DATA_HOME"];
210
- if (xdg)
211
- return xdg;
212
- const home = process.env["HOME"];
213
- if (home)
214
- return path.join(home, ".local", "share");
215
- break;
216
- }
217
- case "darwin": {
218
- const home = process.env["HOME"];
219
- if (home)
220
- return path.join(home, "Library", "Application Support");
221
- break;
222
- }
223
- case "win32":
224
- return process.env["LOCALAPPDATA"] ?? void 0;
225
- }
226
- return void 0;
227
- }
228
- function getConfigDir() {
229
- switch (process.platform) {
230
- case "openbsd":
231
- case "freebsd":
232
- case "linux": {
233
- const xdg = process.env["XDG_CONFIG_HOME"];
234
- if (xdg)
235
- return xdg;
236
- const home = process.env["HOME"];
237
- if (home)
238
- return path.join(home, ".config");
239
- break;
240
- }
241
- case "darwin": {
242
- const home = process.env["HOME"];
243
- if (home)
244
- return path.join(home, "Library", "Preferences");
245
- break;
246
- }
247
- case "win32":
248
- return process.env["APPDATA"] ?? void 0;
249
- }
250
- return void 0;
251
- }
252
- function getRealmDBPath(appConfigDir, options = { reload: false, osuDataDir: getDataDir() || "." }) {
253
- const localDBPath = path.join(appConfigDir, "client.realm");
254
- if (!options.reload && existsSync(localDBPath))
255
- return localDBPath;
256
- const osuDBPath = path.join(options.osuDataDir, "client.realm");
257
- if (existsSync(osuDBPath)) {
258
- console.log(`[getRealmDBPath]: ${osuDBPath} is being imported from osu!lazer to ${localDBPath}`);
259
- mkdirSync(appConfigDir, { recursive: true });
260
- copyFileSync(osuDBPath, localDBPath);
261
- return localDBPath;
262
- } else {
263
- console.log(`[getRealmDBPath]: ${osuDBPath} not found`);
264
- return null;
265
- }
266
- }
267
-
268
- // src/realm/mod.ts
269
- import Realm7 from "realm";
270
- import path2 from "path";
271
- var getLazerDB = async (realmDBPath) => {
272
- const realm = await Realm7.open({
273
- schema: [
274
- BeatmapSet,
275
- RealmFile,
276
- RealmNamedFileUsage,
277
- Beatmap,
278
- BeatmapMetadata,
279
- RealmUser
280
- ],
281
- path: realmDBPath,
282
- schemaVersion: 36,
283
- onMigration: (oldRealm, newRealm) => {
284
- console.log(
285
- `[onMigration]: Migrating ${oldRealm.path} - ${oldRealm.schemaVersion} -> ${newRealm.path} - ${newRealm.schemaVersion}`
286
- );
287
- }
288
- });
289
- return realm;
290
- };
291
- var hashedFilePath = (hash) => {
292
- const dataDir = getDataDir();
293
- if (!dataDir)
294
- return null;
295
- return path2.join(
296
- dataDir,
297
- "osu",
298
- "files",
299
- hash.slice(0, 1),
300
- hash.slice(0, 2),
301
- hash
302
- );
303
- };
304
- var getNamedFileHash = (fileName, beatmapSet) => {
305
- const files = beatmapSet.Files;
306
- for (const file of files) {
307
- if (file.Filename == fileName)
308
- return file.File.Hash;
309
- }
310
- return void 0;
311
- };
312
-
313
- // src/cli/main.ts
314
- import yargs from "yargs/yargs";
315
- import { hideBin } from "yargs/helpers";
316
- function getArgs() {
317
- const argv = yargs(hideBin(process.argv)).usage("Play music from your osu!lazer beatmaps from the terminal\nUsage: $0 [options]").options({
318
- reload: {
319
- type: "boolean",
320
- default: false,
321
- alias: "r",
322
- describe: "Reload lazer database"
323
- },
324
- osuDataDir: {
325
- type: "string",
326
- default: path3.join(getDataDir() || ".", "osu"),
327
- alias: "d",
328
- describe: "Osu!lazer data directory"
329
- },
330
- configDir: {
331
- type: "string",
332
- default: path3.join(getConfigDir() || ".", "osu-play"),
333
- alias: "c",
334
- describe: "Config directory"
335
- },
336
- loop: {
337
- type: "boolean",
338
- default: false,
339
- alias: "l",
340
- describe: "Loop the playlist on end"
341
- }
342
- }).argv;
343
- return argv;
344
- }
345
- async function main() {
346
- const argv = await getArgs();
347
- console.log("[INFO] OSU!list");
348
- let reload = false;
349
- let osuDataDir = argv.osuDataDir;
350
- if (argv.reload) {
351
- console.log("[INFO] Reloading lazer database");
352
- reload = true;
353
- }
354
- if (argv.osuDataDir !== getDataDir()) {
355
- console.log(`[INFO] Using osu!lazer data directory: ${argv.osuDataDir}`);
356
- }
357
- const realmDBPath = getRealmDBPath(argv.configDir, { reload, osuDataDir });
358
- if (realmDBPath == null) {
359
- console.log("[ERROR] Realm DB not found");
360
- process.exit(1);
361
- }
362
- const currentSchema = Realm8.schemaVersion(realmDBPath);
363
- console.log(`currentSchema: ${currentSchema}`);
364
- Realm8.flags.ALLOW_CLEAR_TEST_STATE = true;
365
- const realm = await getLazerDB(realmDBPath);
366
- console.log(`realm.isClosed: ${realm.isClosed}`);
367
- const beatmapSets = realm.objects(BeatmapSet);
368
- const songSet = /* @__PURE__ */ new Set();
369
- const uniqueBeatmaps = [];
370
- for (const beatmapSet of beatmapSets) {
371
- for (const beatmap of beatmapSet.Beatmaps) {
372
- const fileName = beatmap.Metadata.AudioFile;
373
- const hash = getNamedFileHash(fileName ?? "", beatmapSet);
374
- if (!hash)
375
- continue;
376
- if (songSet.has(hash))
377
- continue;
378
- songSet.add(hash);
379
- const meta = beatmap.Metadata;
380
- const path4 = hashedFilePath(hash);
381
- const title = `${meta.Title} : ${meta.Artist} - ${meta.TitleUnicode} : ${meta.ArtistUnicode}`;
382
- uniqueBeatmaps.push({ title, path: path4 });
383
- }
384
- }
385
- console.log(`beatmap songs: ${beatmapSets.length}`);
386
- let selectedBeatmap = (await prompts({
387
- type: "autocomplete",
388
- name: "beatmap",
389
- message: "Which map do you want to play:",
390
- choices: uniqueBeatmaps.map((mp, index) => ({
391
- title: mp.title,
392
- value: index
393
- }))
394
- })).beatmap;
395
- for (let i = selectedBeatmap; i < uniqueBeatmaps.length; ++i) {
396
- const beatmap = uniqueBeatmaps[i];
397
- console.log(`Map : ${beatmap.title}`);
398
- if (beatmap.path && existsSync2(beatmap.path)) {
399
- console.log(`File exists: ${beatmap.path}`);
400
- console.log(`Playing ${beatmap.title}`);
401
- try {
402
- execFileSync("exo-open", [beatmap.path]);
403
- } catch (err) {
404
- console.log(`Error: ${err}`);
405
- break;
406
- }
407
- } else {
408
- console.log(`File does not exist: ${beatmap.path}`);
409
- }
410
- if (i < uniqueBeatmaps.length - 1) {
411
- await new Promise((resolve) => setTimeout(resolve, 1e3));
412
- } else if (argv.loop) {
413
- console.log("[INFO] Looping playlist");
414
- i = 0;
415
- } else {
416
- console.log("[INFO] Done. Use --loop to loop the playlist");
417
- }
418
- }
419
- realm.close();
420
- console.log(`realm.isClosed: ${realm.isClosed}`);
421
- }
422
- export {
423
- getArgs,
424
- main
425
- };
426
- //# sourceMappingURL=main.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../../src/cli/main.ts","../../../src/realm/schema/beatmap.ts","../../../src/realm/schema/beatmapMetadata.ts","../../../src/realm/schema/beatmapSet.ts","../../../src/realm/schema/realmFile.ts","../../../src/realm/schema/realmUser.ts","../../../src/realm/schema/realmNamedFileUsage.ts","../../../src/utils/mod.ts","../../../src/realm/mod.ts"],"sourcesContent":["import path from \"node:path\";\nimport { existsSync } from \"node:fs\";\nimport { execFileSync } from \"node:child_process\";\n\nimport Realm from \"realm\";\nimport prompts from \"prompts\";\nimport { BeatmapSet } from \"../realm/schema/mod.js\";\nimport { getConfigDir, getDataDir, getRealmDBPath } from \"../utils/mod.js\";\nimport { getLazerDB, getNamedFileHash, hashedFilePath } from \"../realm/mod.js\";\n\nimport yargs from \"yargs/yargs\";\nimport { hideBin } from \"yargs/helpers\";\n\nexport function getArgs() {\n const argv = yargs(hideBin(process.argv))\n .usage(\"Play music from your osu!lazer beatmaps from the terminal\\nUsage: $0 [options]\")\n .options({\n reload: {\n type: \"boolean\",\n default: false,\n alias: \"r\",\n describe: \"Reload lazer database\",\n },\n osuDataDir: {\n type: \"string\",\n default: path.join(getDataDir() || \".\", \"osu\"),\n alias: \"d\",\n describe: \"Osu!lazer data directory\",\n },\n configDir: {\n type: \"string\",\n default: path.join(getConfigDir() || \".\", \"osu-play\"),\n alias: \"c\",\n describe: \"Config directory\",\n },\n loop: {\n type: \"boolean\",\n default: false,\n alias: \"l\",\n describe: \"Loop the playlist on end\",\n },\n }).argv;\n return argv;\n}\n\nexport async function main() {\n const argv = await getArgs();\n console.log(\"[INFO] OSU!list\");\n\n let reload = false;\n let osuDataDir = argv.osuDataDir;\n\n if (argv.reload) {\n console.log(\"[INFO] Reloading lazer database\");\n reload = true;\n }\n\n if (argv.osuDataDir !== getDataDir()) {\n console.log(`[INFO] Using osu!lazer data directory: ${argv.osuDataDir}`);\n }\n\n const realmDBPath = getRealmDBPath(argv.configDir, { reload, osuDataDir });\n\n if (realmDBPath == null) {\n console.log(\"[ERROR] Realm DB not found\");\n process.exit(1);\n }\n\n const currentSchema = Realm.schemaVersion(realmDBPath);\n console.log(`currentSchema: ${currentSchema}`);\n\n Realm.flags.ALLOW_CLEAR_TEST_STATE = true;\n\n const realm: Realm = await getLazerDB(realmDBPath);\n\n console.log(`realm.isClosed: ${realm.isClosed}`);\n\n const beatmapSets = realm.objects(BeatmapSet);\n\n const songSet = new Set<string>();\n const uniqueBeatmaps: {\n title: string;\n path: string | null;\n }[] = [];\n\n for (const beatmapSet of beatmapSets) {\n for (const beatmap of beatmapSet.Beatmaps) {\n const fileName = beatmap.Metadata.AudioFile;\n const hash = getNamedFileHash(fileName ?? \"\", beatmapSet);\n if (!hash) continue;\n if (songSet.has(hash)) continue;\n songSet.add(hash);\n const meta = beatmap.Metadata;\n const path = hashedFilePath(hash);\n const title = `${meta.Title} : ${meta.Artist} - ${meta.TitleUnicode} : ${meta.ArtistUnicode}`;\n uniqueBeatmaps.push({ title, path });\n }\n }\n\n console.log(`beatmap songs: ${beatmapSets.length}`);\n\n // Get the map index from the user\n let selectedBeatmap: number = (\n await prompts({\n type: \"autocomplete\",\n name: \"beatmap\",\n message: \"Which map do you want to play:\",\n choices: uniqueBeatmaps.map((mp, index) => ({\n title: mp.title,\n value: index,\n })),\n })\n ).beatmap;\n\n for (let i = selectedBeatmap; i < uniqueBeatmaps.length; ++i) {\n const beatmap = uniqueBeatmaps[i];\n console.log(`Map : ${beatmap.title}`);\n if (beatmap.path && existsSync(beatmap.path)) {\n // Open file using exo-open.\n console.log(`File exists: ${beatmap.path}`);\n console.log(`Playing ${beatmap.title}`);\n try {\n execFileSync(\"exo-open\", [beatmap.path]);\n } catch (err) {\n console.log(`Error: ${err}`);\n break;\n }\n } else {\n console.log(`File does not exist: ${beatmap.path}`);\n }\n if (i < uniqueBeatmaps.length - 1) {\n // Wait 1 second between\n await new Promise((resolve) => setTimeout(resolve, 1000));\n } else if (argv.loop) {\n console.log('[INFO] Looping playlist');\n i = 0;\n } else { \n console.log('[INFO] Done. Use --loop to loop the playlist');\n }\n }\n\n realm.close();\n console.log(`realm.isClosed: ${realm.isClosed}`);\n\n // Realm.clearTestState();\n}\n","import Realm from \"realm\";\nimport type { ObjectSchema } from \"realm\";\nimport { BeatmapMetadata } from \"./beatmapMetadata.js\";\n\nexport class Beatmap extends Realm.Object<Beatmap> {\n ID!: string;\n DifficultyName?: string;\n Ruleset!: any;\n Difficulty!: any;\n Metadata!: BeatmapMetadata;\n UserSettings!: any;\n BeatmapSet!: any;\n Status!: number;\n OnlineID!: number;\n Length!: number;\n BPM!: number;\n Hash?: string;\n StarRating!: number;\n MD5Hash?: string;\n OnlineMD5Hash?: string;\n LastLocalUpdate?: Date;\n LastOnlineUpdate?: Date;\n Hidden!: boolean;\n AudioLeadIn!: number;\n StackLeniency!: number;\n SpecialStyle!: boolean;\n LetterboxInBreaks!: boolean;\n WidescreenStoryboard!: boolean;\n EpilepsyWarning!: boolean;\n SamplesMatchPlaybackRate!: boolean;\n LastPlayed?: Date;\n DistanceSpacing!: number;\n BeatDivisor!: number;\n GridSize!: number;\n TimelineZoom!: number;\n EditorTimestamp?: number;\n CountdownOffset!: number;\n\n static schema: ObjectSchema = {\n name: \"Beatmap\",\n primaryKey: \"ID\",\n properties: {\n ID: { type: \"uuid\", default: \"\" },\n DifficultyName: { type: \"string\", default: \"\", optional: true },\n // Ruleset: { type: \"object\", objectType: \"Ruleset\", default: null },\n // Difficulty: { type: \"object\", objectType: \"BeatmapDifficulty\", default: null },\n Metadata: {\n type: \"object\",\n objectType: \"BeatmapMetadata\",\n default: null,\n },\n // UserSettings: { type: \"object\", objectType: \"BeatmapUserSettings\", default: null },\n BeatmapSet: { type: \"object\", objectType: \"BeatmapSet\", default: null },\n Status: { type: \"int\", default: -3 },\n OnlineID: { type: \"int\", default: -1 },\n Length: { type: \"double\", default: 0 },\n BPM: { type: \"double\", default: 0 },\n Hash: { type: \"string\", default: \"\", optional: true },\n StarRating: { type: \"double\", default: -1 },\n MD5Hash: { type: \"string\", default: \"\", optional: true },\n OnlineMD5Hash: {\n type: \"string\",\n default: \"\",\n optional: true,\n },\n LastLocalUpdate: { type: \"date\", optional: true },\n LastOnlineUpdate: { type: \"date\", optional: true },\n Hidden: { type: \"bool\", default: false },\n AudioLeadIn: { type: \"double\", default: 0 },\n StackLeniency: { type: \"float\", default: 0.7 },\n SpecialStyle: { type: \"bool\", default: false },\n LetterboxInBreaks: { type: \"bool\", default: false },\n WidescreenStoryboard: { type: \"bool\", default: false },\n EpilepsyWarning: { type: \"bool\", default: false },\n SamplesMatchPlaybackRate: { type: \"bool\", default: false },\n LastPlayed: { type: \"date\", optional: true },\n DistanceSpacing: { type: \"double\", default: 0 },\n BeatDivisor: { type: \"int\", default: 0 },\n GridSize: { type: \"int\", default: 0 },\n TimelineZoom: { type: \"double\", default: 0 },\n EditorTimestamp: { type: \"double\", optional: true },\n CountdownOffset: { type: \"int\", default: 0 },\n },\n };\n}\n","import Realm from \"realm\";\nimport type { ObjectSchema } from \"realm\";\nimport { RealmUser } from \"./realmUser.js\";\n\nexport class BeatmapMetadata extends Realm.Object<BeatmapMetadata> {\n Title?: string;\n TitleUnicode?: string;\n Artist?: string;\n ArtistUnicode?: string;\n Author?: RealmUser;\n Source?: string;\n Tags?: string;\n PreviewTime?: number;\n AudioFile?: string;\n BackgroundFile?: string;\n\n static schema: ObjectSchema = {\n name: \"BeatmapMetadata\",\n properties: {\n Title: { type: \"string\", default: \"\", optional: true },\n TitleUnicode: { type: \"string\", default: \"\", optional: true },\n Artist: { type: \"string\", default: \"\", optional: true },\n ArtistUnicode: { type: \"string\", default: \"\", optional: true },\n Author: { type: \"object\", objectType: \"RealmUser\", default: null },\n Source: { type: \"string\", default: \"\", optional: true },\n Tags: { type: \"string\", default: \"\", optional: true },\n PreviewTime: { type: \"int\", default: 0 },\n AudioFile: { type: \"string\", default: \"\", optional: true },\n BackgroundFile: { type: \"string\", default: \"\", optional: true },\n },\n };\n}\n\n","import Realm from \"realm\";\nimport type { ObjectSchema } from \"realm\";\nimport { Beatmap } from \"./beatmap.js\";\nimport { RealmNamedFileUsage } from \"./realmNamedFileUsage.js\";\n\nexport class BeatmapSet extends Realm.Object<BeatmapSet> {\n ID!: string;\n OnlineID!: number;\n DateAdded!: Date;\n DateSubmitted?: Date;\n DateRanked?: Date;\n Beatmaps!: Array<Beatmap>;\n Files!: Array<RealmNamedFileUsage>;\n Status!: number;\n DeletePending!: boolean;\n Hash?: string;\n Protected!: boolean;\n\n static schema: ObjectSchema = {\n name: \"BeatmapSet\",\n primaryKey: \"ID\",\n properties: {\n ID: { type: \"uuid\", default: \"\" },\n OnlineID: { type: \"int\", default: -1 },\n DateAdded: { type: \"date\" },\n DateSubmitted: { type: \"date\", optional: true },\n DateRanked: { type: \"date\", optional: true },\n Beatmaps: { type: \"list\", objectType: \"Beatmap\", default: [] },\n Files: { type: \"list\", objectType: \"RealmNamedFileUsage\", default: [] },\n Status: { type: \"int\", default: -3 },\n DeletePending: { type: \"bool\", default: false },\n Hash: { type: \"string\", default: \"\", optional: true },\n Protected: { type: \"bool\", default: false },\n },\n };\n}\n","import Realm from \"realm\";\nimport type { ObjectSchema } from \"realm\";\n\nexport class RealmFile extends Realm.Object<RealmFile> {\n Hash?: string;\n\n static schema: ObjectSchema = {\n name: \"File\",\n primaryKey: \"Hash\",\n properties: {\n Hash: { type: \"string\", default: \"\", optional: true },\n },\n };\n}\n\n","import Realm from \"realm\";\nimport type { ObjectSchema } from \"realm\";\n\nexport class RealmUser extends Realm.Object<RealmUser> {\n OnlineID!: number;\n Username?: string;\n CountryCode?: string;\n\n static embedded = true;\n\n static schema: ObjectSchema = {\n name: \"RealmUser\",\n embedded: true,\n properties: {\n OnlineID: { type: \"int\", default: 1 },\n Username: { type: \"string\", default: \"\", optional: true },\n CountryCode: { type: \"string\", optional: true },\n },\n };\n}\n\n","import Realm from \"realm\";\nimport type { ObjectSchema } from \"realm\";\nimport { RealmFile } from \"./realmFile.js\";\n\nexport class RealmNamedFileUsage extends Realm.Object<RealmNamedFileUsage> {\n File!: RealmFile;\n Filename?: string;\n\n static embedded = true;\n\n static schema: ObjectSchema = {\n name: \"RealmNamedFileUsage\",\n embedded: true,\n properties: {\n File: \"File\",\n Filename: { type: \"string\", optional: true },\n },\n };\n}\n","import path from \"node:path\";\nimport { copyFileSync, existsSync, mkdirSync } from \"node:fs\";\n\nexport function getDataDir(): string | undefined {\n switch (process.platform) {\n case \"linux\":\n case \"openbsd\":\n case \"freebsd\": {\n const xdg = process.env[\"XDG_DATA_HOME\"];\n if (xdg) return xdg;\n const home = process.env[\"HOME\"];\n if (home) return path.join(home, \".local\", \"share\");\n break;\n }\n\n case \"darwin\": {\n const home = process.env[\"HOME\"];\n if (home) return path.join(home, \"Library\", \"Application Support\");\n break;\n }\n\n case \"win32\":\n return process.env[\"LOCALAPPDATA\"] ?? undefined;\n }\n\n return undefined;\n}\n\nexport function getConfigDir(): string | undefined {\n switch (process.platform) {\n case \"openbsd\":\n case \"freebsd\":\n case \"linux\": {\n const xdg = process.env[\"XDG_CONFIG_HOME\"];\n if (xdg) return xdg;\n const home = process.env[\"HOME\"];\n if (home) return path.join(home, \".config\");\n break;\n }\n\n case \"darwin\": {\n const home = process.env[\"HOME\"];\n if (home) return path.join(home, \"Library\", \"Preferences\");\n break;\n }\n\n case \"win32\":\n return process.env[\"APPDATA\"] ?? undefined;\n }\n\n return undefined;\n}\n\n/**\n * Get Realm for the app, import to the config if it doesn't exist\n */\nexport function getRealmDBPath(\n appConfigDir: string,\n options: {\n osuDataDir: string;\n reload: boolean;\n } = { reload: false, osuDataDir: getDataDir() || \".\" },\n) {\n const localDBPath = path.join(appConfigDir, \"client.realm\");\n if (!options.reload && existsSync(localDBPath)) return localDBPath;\n\n const osuDBPath = path.join(options.osuDataDir, \"client.realm\");\n if (existsSync(osuDBPath)) {\n console.log( `[getRealmDBPath]: ${osuDBPath} is being imported from osu!lazer to ${localDBPath}`);\n mkdirSync(appConfigDir, { recursive: true });\n copyFileSync(osuDBPath, localDBPath );\n return localDBPath;\n } else {\n console.log(`[getRealmDBPath]: ${osuDBPath} not found`);\n return null;\n }\n}\n","import Realm from \"realm\";\nimport path from \"node:path\";\nimport { getDataDir } from \"../utils/mod.js\";\nimport {\n Beatmap,\n BeatmapMetadata,\n BeatmapSet,\n RealmFile,\n RealmNamedFileUsage,\n RealmUser,\n} from \"./schema/mod.js\";\n\nexport const getLazerDB = async (realmDBPath: string) => {\n const realm = await Realm.open({\n schema: [\n BeatmapSet,\n RealmFile,\n RealmNamedFileUsage,\n Beatmap,\n BeatmapMetadata,\n RealmUser,\n ],\n path: realmDBPath,\n schemaVersion: 36,\n onMigration: (oldRealm, newRealm) => {\n console.log(\n `[onMigration]: Migrating ${oldRealm.path} - ${oldRealm.schemaVersion} -> ${newRealm.path} - ${newRealm.schemaVersion}`,\n );\n },\n });\n\n return realm;\n};\n\nexport const hashedFilePath = (hash: string) => {\n const dataDir = getDataDir();\n if (!dataDir) return null;\n return path.join(\n dataDir,\n \"osu\",\n \"files\",\n hash.slice(0, 1),\n hash.slice(0, 2),\n hash,\n );\n};\n\nexport const getNamedFileHash = (fileName: string, beatmapSet: BeatmapSet) => {\n const files = beatmapSet.Files;\n for (const file of files) {\n if (file.Filename == fileName) return file.File.Hash;\n }\n return undefined;\n};\n"],"mappings":"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","names":["path","existsSync","Realm","Realm","Realm","Realm","Realm","Realm","Realm","path","Realm","path","path","Realm","existsSync"]}