goblin-malin 0.1.0 → 0.1.2
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/.env.example +6 -0
- package/README.md +51 -31
- package/dist/assets/sounds/init.wav +0 -0
- package/dist/assets/themes/dark.json +74 -0
- package/dist/assets/themes/light.json +74 -0
- package/dist/chunk-Y4ZGX5NZ.js +13048 -0
- package/dist/{chunk-ECLAXOR2.js → chunk-ZZ35YTR2.js} +64 -14
- package/dist/cli.js +2 -2
- package/dist/index.js +2 -2
- package/dist/{metadata-Y5IDFTMA.js → metadata-AGDUAOW7.js} +1 -1
- package/package.json +123 -87
- package/dist/chunk-DJTET7PY.js +0 -9124
|
@@ -75,6 +75,7 @@ var LogLevel = /* @__PURE__ */ (function(LogLevel2) {
|
|
|
75
75
|
|
|
76
76
|
// src/utils/appPaths.ts
|
|
77
77
|
import path3 from "path";
|
|
78
|
+
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
78
79
|
|
|
79
80
|
// src/settings/settingsStore.ts
|
|
80
81
|
import * as fs from "fs";
|
|
@@ -84,19 +85,38 @@ import { EventEmitter } from "events";
|
|
|
84
85
|
// src/constants.ts
|
|
85
86
|
import dotenv from "dotenv";
|
|
86
87
|
import path from "path";
|
|
88
|
+
import os from "os";
|
|
87
89
|
import { fileURLToPath } from "url";
|
|
88
|
-
dotenv.config();
|
|
89
90
|
var __filename = fileURLToPath(import.meta.url);
|
|
90
91
|
var __dirname = path.dirname(__filename);
|
|
91
92
|
var PROJECT_ROOT = path.join(__dirname, "..");
|
|
93
|
+
var IS_DEV = __filename.endsWith(".ts");
|
|
94
|
+
function getPlatformDefaultDataDir() {
|
|
95
|
+
switch (process.platform) {
|
|
96
|
+
case "win32":
|
|
97
|
+
return path.join(process.env.APPDATA ?? path.join(os.homedir(), "AppData", "Roaming"), "goblin-malin");
|
|
98
|
+
case "darwin":
|
|
99
|
+
return path.join(os.homedir(), "Library", "Application Support", "goblin-malin");
|
|
100
|
+
default:
|
|
101
|
+
return path.join(process.env.XDG_DATA_HOME ?? path.join(os.homedir(), ".local", "share"), "goblin-malin");
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
__name(getPlatformDefaultDataDir, "getPlatformDefaultDataDir");
|
|
105
|
+
var DEFAULT_APP_DATA_DIR = IS_DEV ? path.join(PROJECT_ROOT, "data") : getPlatformDefaultDataDir();
|
|
106
|
+
dotenv.config({
|
|
107
|
+
path: path.join(DEFAULT_APP_DATA_DIR, ".env")
|
|
108
|
+
});
|
|
92
109
|
|
|
93
110
|
// src/settings/appSettings.ts
|
|
94
111
|
var DEFAULT_APP_SETTINGS = {
|
|
95
112
|
general: {
|
|
96
113
|
reopenLastSession: false,
|
|
97
|
-
appDataDir:
|
|
98
|
-
animationsEnabled: false
|
|
99
|
-
|
|
114
|
+
appDataDir: DEFAULT_APP_DATA_DIR,
|
|
115
|
+
animationsEnabled: false,
|
|
116
|
+
theme: "dark",
|
|
117
|
+
showWelcomeTutorial: true
|
|
118
|
+
},
|
|
119
|
+
keybindings: {}
|
|
100
120
|
};
|
|
101
121
|
|
|
102
122
|
// src/utils/deepMerge.ts
|
|
@@ -122,8 +142,7 @@ function deepMerge(target, source) {
|
|
|
122
142
|
__name(deepMerge, "deepMerge");
|
|
123
143
|
|
|
124
144
|
// src/settings/settingsStore.ts
|
|
125
|
-
var
|
|
126
|
-
var SETTINGS_PATH = path2.join(CONFIG_DIR, "settings.json");
|
|
145
|
+
var SETTINGS_PATH = path2.join(DEFAULT_APP_DATA_DIR, "settings.json");
|
|
127
146
|
var SettingsStore = class _SettingsStore {
|
|
128
147
|
static {
|
|
129
148
|
__name(this, "SettingsStore");
|
|
@@ -142,12 +161,13 @@ var SettingsStore = class _SettingsStore {
|
|
|
142
161
|
} catch {
|
|
143
162
|
return {
|
|
144
163
|
general: DEFAULT_APP_SETTINGS.general,
|
|
164
|
+
keybindings: {},
|
|
145
165
|
flows: {}
|
|
146
166
|
};
|
|
147
167
|
}
|
|
148
168
|
}
|
|
149
169
|
writeToDisk(settings) {
|
|
150
|
-
fs.mkdirSync(
|
|
170
|
+
fs.mkdirSync(path2.dirname(SETTINGS_PATH), {
|
|
151
171
|
recursive: true
|
|
152
172
|
});
|
|
153
173
|
const tmp = SETTINGS_PATH + ".tmp";
|
|
@@ -164,14 +184,32 @@ var SettingsStore = class _SettingsStore {
|
|
|
164
184
|
getAppSettings() {
|
|
165
185
|
const s = this.getCached();
|
|
166
186
|
return deepMerge(DEFAULT_APP_SETTINGS, {
|
|
167
|
-
general: s.general
|
|
187
|
+
general: s.general,
|
|
188
|
+
keybindings: s.keybindings ?? {}
|
|
168
189
|
});
|
|
169
190
|
}
|
|
170
191
|
writeAppSettings(settings) {
|
|
171
192
|
const current = this.getCached();
|
|
172
193
|
this.writeToDisk({
|
|
173
194
|
...current,
|
|
174
|
-
general: settings.general
|
|
195
|
+
general: settings.general,
|
|
196
|
+
keybindings: settings.keybindings ?? {}
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
/** Save a single key binding override. */
|
|
200
|
+
setKeybinding(actionId, shortcut) {
|
|
201
|
+
const current = this.getAppSettings();
|
|
202
|
+
const keybindings = {
|
|
203
|
+
...current.keybindings
|
|
204
|
+
};
|
|
205
|
+
if (shortcut === null) {
|
|
206
|
+
delete keybindings[actionId];
|
|
207
|
+
} else {
|
|
208
|
+
keybindings[actionId] = shortcut;
|
|
209
|
+
}
|
|
210
|
+
this.writeAppSettings({
|
|
211
|
+
...current,
|
|
212
|
+
keybindings
|
|
175
213
|
});
|
|
176
214
|
}
|
|
177
215
|
// ── Flow settings ──────────────────────────────────────────────────────────
|
|
@@ -189,6 +227,10 @@ var SettingsStore = class _SettingsStore {
|
|
|
189
227
|
}
|
|
190
228
|
});
|
|
191
229
|
}
|
|
230
|
+
patchFlowSettings(flowId, patch) {
|
|
231
|
+
const current = this.getFlowSettings(flowId, {});
|
|
232
|
+
this.writeFlowSettings(flowId, deepMerge(current, patch));
|
|
233
|
+
}
|
|
192
234
|
// ── Change notifications ───────────────────────────────────────────────────
|
|
193
235
|
onSettingsChanged(callback) {
|
|
194
236
|
this.emitter.on("change", callback);
|
|
@@ -199,20 +241,25 @@ var SettingsStore = class _SettingsStore {
|
|
|
199
241
|
};
|
|
200
242
|
|
|
201
243
|
// src/utils/appPaths.ts
|
|
202
|
-
|
|
244
|
+
var _assetsDir = path3.join(path3.dirname(fileURLToPath2(import.meta.url)), import.meta.url.endsWith(".ts") ? "../assets" : "assets");
|
|
245
|
+
function getAssetPath(...segments) {
|
|
246
|
+
return path3.join(_assetsDir, ...segments);
|
|
247
|
+
}
|
|
248
|
+
__name(getAssetPath, "getAssetPath");
|
|
249
|
+
function getAppDataDir() {
|
|
203
250
|
return SettingsStore.getInstance().getAppSettings().general.appDataDir;
|
|
204
251
|
}
|
|
205
|
-
__name(
|
|
252
|
+
__name(getAppDataDir, "getAppDataDir");
|
|
206
253
|
function getCacheDir() {
|
|
207
|
-
return path3.join(
|
|
254
|
+
return path3.join(getAppDataDir(), "cache");
|
|
208
255
|
}
|
|
209
256
|
__name(getCacheDir, "getCacheDir");
|
|
210
257
|
function getBinDir() {
|
|
211
|
-
return path3.join(
|
|
258
|
+
return path3.join(getAppDataDir(), "bin");
|
|
212
259
|
}
|
|
213
260
|
__name(getBinDir, "getBinDir");
|
|
214
261
|
function getLogsPath() {
|
|
215
|
-
return path3.join(
|
|
262
|
+
return path3.join(getAppDataDir(), "app.log");
|
|
216
263
|
}
|
|
217
264
|
__name(getLogsPath, "getLogsPath");
|
|
218
265
|
|
|
@@ -412,9 +459,12 @@ __name(moveFile, "moveFile");
|
|
|
412
459
|
|
|
413
460
|
export {
|
|
414
461
|
__name,
|
|
462
|
+
DEFAULT_APP_DATA_DIR,
|
|
415
463
|
deepMerge,
|
|
464
|
+
SETTINGS_PATH,
|
|
416
465
|
SettingsStore,
|
|
417
466
|
inkTransport,
|
|
467
|
+
getAssetPath,
|
|
418
468
|
getCacheDir,
|
|
419
469
|
getBinDir,
|
|
420
470
|
globalLogger,
|
package/dist/cli.js
CHANGED
package/dist/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,89 +1,125 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
2
|
+
"name": "goblin-malin",
|
|
3
|
+
"version": "0.1.2",
|
|
4
|
+
"description": "A keyboard-driven terminal UI for downloading and tagging music tracks with metadata from Spotify and YouTube",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"imports": {
|
|
9
|
+
"#base": "./src/base/index.ts",
|
|
10
|
+
"#base/*": "./src/base/*.ts",
|
|
11
|
+
"#components": "./src/components/index.ts",
|
|
12
|
+
"#components/*": "./src/components/*.ts",
|
|
13
|
+
"#contexts": "./src/contexts/index.ts",
|
|
14
|
+
"#contexts/*": "./src/contexts/*.ts",
|
|
15
|
+
"#exceptions": "./src/exceptions/index.ts",
|
|
16
|
+
"#exceptions/*": "./src/exceptions/*.ts",
|
|
17
|
+
"#flows": "./src/flows/index.ts",
|
|
18
|
+
"#flows/*": "./src/flows/*.ts",
|
|
19
|
+
"#hooks": "./src/hooks/index.ts",
|
|
20
|
+
"#hooks/*": "./src/hooks/*.ts",
|
|
21
|
+
"#settings": "./src/settings/index.ts",
|
|
22
|
+
"#settings/*": "./src/settings/*.ts",
|
|
23
|
+
"#utils": "./src/utils/index.ts",
|
|
24
|
+
"#utils/*": "./src/utils/*.ts",
|
|
25
|
+
"#assets/*": "./src/assets/*",
|
|
26
|
+
"#types": "./src/types/index.ts",
|
|
27
|
+
"#types/*": "./src/types/*.ts"
|
|
28
|
+
},
|
|
29
|
+
"exports": {
|
|
30
|
+
".": {
|
|
31
|
+
"types": "./dist/index.d.ts",
|
|
32
|
+
"default": "./dist/index.js"
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
"bin": {
|
|
36
|
+
"goblin-malin": "dist/cli.js"
|
|
37
|
+
},
|
|
38
|
+
"files": [
|
|
39
|
+
"dist",
|
|
40
|
+
"README.md"
|
|
41
|
+
],
|
|
42
|
+
"scripts": {
|
|
43
|
+
"dev": "tsx src/cli.ts",
|
|
44
|
+
"start": "ts-node src/index.ts",
|
|
45
|
+
"build": "tsup",
|
|
46
|
+
"type-check": "tsc --noEmit",
|
|
47
|
+
"lint": "eslint src/",
|
|
48
|
+
"format": "prettier --write src/",
|
|
49
|
+
"format:check": "prettier --check src/",
|
|
50
|
+
"prepack": "node scripts/patch-readme.mjs",
|
|
51
|
+
"postpack": "git checkout -- README.md",
|
|
52
|
+
"prepublishOnly": "tsup"
|
|
53
|
+
},
|
|
54
|
+
"keywords": [
|
|
55
|
+
"music",
|
|
56
|
+
"download",
|
|
57
|
+
"downloader",
|
|
58
|
+
"tui",
|
|
59
|
+
"cli",
|
|
60
|
+
"terminal",
|
|
61
|
+
"spotify",
|
|
62
|
+
"youtube",
|
|
63
|
+
"yt-dlp",
|
|
64
|
+
"metadata",
|
|
65
|
+
"tags",
|
|
66
|
+
"ink",
|
|
67
|
+
"react"
|
|
68
|
+
],
|
|
69
|
+
"author": "Tetraxel",
|
|
70
|
+
"license": "SEE LICENSE IN LICENSE",
|
|
71
|
+
"repository": {
|
|
72
|
+
"type": "git",
|
|
73
|
+
"url": "git+https://github.com/Tetraxel/goblin-malin.git"
|
|
74
|
+
},
|
|
75
|
+
"devDependencies": {
|
|
76
|
+
"@eslint/js": "^9.39.4",
|
|
77
|
+
"@swc/core": "^1.10.0",
|
|
78
|
+
"@types/adm-zip": "^0.5.7",
|
|
79
|
+
"@types/dotenv": "^8.2.3",
|
|
80
|
+
"@types/ink": "^2.0.3",
|
|
81
|
+
"@types/ink-select-input": "^3.0.5",
|
|
82
|
+
"@types/ink-spinner": "^3.0.5",
|
|
83
|
+
"@types/ink-text-input": "^2.0.5",
|
|
84
|
+
"@types/node": "^25.6.2",
|
|
85
|
+
"@types/react": "^19.2.14",
|
|
86
|
+
"eslint": "^9.39.4",
|
|
87
|
+
"eslint-plugin-react": "^7.37.5",
|
|
88
|
+
"eslint-plugin-react-hooks": "^7.1.1",
|
|
89
|
+
"prettier": "^3.8.3",
|
|
90
|
+
"ts-node": "^10.9.2",
|
|
91
|
+
"tsup": "^8.0.0",
|
|
92
|
+
"tsx": "^4.21.0",
|
|
93
|
+
"typescript": "^6.0.3",
|
|
94
|
+
"typescript-eslint": "^8.59.3"
|
|
95
|
+
},
|
|
96
|
+
"dependencies": {
|
|
97
|
+
"7zip-bin": "^5.2.0",
|
|
98
|
+
"@spotify/web-api-ts-sdk": "^1.2.0",
|
|
99
|
+
"adm-zip": "^0.5.17",
|
|
100
|
+
"chalk": "^5.6.2",
|
|
101
|
+
"clipboardy": "^5.3.1",
|
|
102
|
+
"dotenv": "^17.4.2",
|
|
103
|
+
"flac-tagger": "^2.0.0",
|
|
104
|
+
"flat-cache": "^6.1.22",
|
|
105
|
+
"fullscreen-ink": "^0.1.0",
|
|
106
|
+
"ink": "^7.0.2",
|
|
107
|
+
"ink-big-text": "^2.0.0",
|
|
108
|
+
"ink-form": "^2.0.1",
|
|
109
|
+
"ink-gradient": "^4.0.0",
|
|
110
|
+
"ink-link": "^5.0.0",
|
|
111
|
+
"ink-picture": "^1.3.5",
|
|
112
|
+
"ink-select-input": "^6.2.0",
|
|
113
|
+
"ink-spinner": "^5.0.0",
|
|
114
|
+
"ink-text-input": "^6.0.0",
|
|
115
|
+
"musicbrainz-api": "^1.2.1",
|
|
116
|
+
"node-id3": "^0.2.9",
|
|
117
|
+
"open": "^11.0.0",
|
|
118
|
+
"react": "^19.2.6",
|
|
119
|
+
"slsk-client": "^1.1.0",
|
|
120
|
+
"winston": "^3.19.0",
|
|
121
|
+
"winston-transport": "^4.9.0",
|
|
122
|
+
"ytdlp-nodejs": "^3.4.4",
|
|
123
|
+
"ytmusic-api": "^5.3.1"
|
|
12
124
|
}
|
|
13
|
-
|
|
14
|
-
"bin": {
|
|
15
|
-
"goblin-malin": "dist/cli.js"
|
|
16
|
-
},
|
|
17
|
-
"files": [
|
|
18
|
-
"dist",
|
|
19
|
-
"README.md"
|
|
20
|
-
],
|
|
21
|
-
"scripts": {
|
|
22
|
-
"dev": "tsx src/cli.ts",
|
|
23
|
-
"start": "ts-node src/index.ts",
|
|
24
|
-
"build": "tsup",
|
|
25
|
-
"type-check": "tsc --noEmit",
|
|
26
|
-
"prepublishOnly": "tsup"
|
|
27
|
-
},
|
|
28
|
-
"keywords": [
|
|
29
|
-
"music",
|
|
30
|
-
"download",
|
|
31
|
-
"downloader",
|
|
32
|
-
"tui",
|
|
33
|
-
"cli",
|
|
34
|
-
"terminal",
|
|
35
|
-
"spotify",
|
|
36
|
-
"youtube",
|
|
37
|
-
"yt-dlp",
|
|
38
|
-
"metadata",
|
|
39
|
-
"tags",
|
|
40
|
-
"ink",
|
|
41
|
-
"react"
|
|
42
|
-
],
|
|
43
|
-
"author": "Tetraxel",
|
|
44
|
-
"license": "SEE LICENSE IN LICENSE",
|
|
45
|
-
"devDependencies": {
|
|
46
|
-
"@types/adm-zip": "^0.5.7",
|
|
47
|
-
"@types/dotenv": "^8.2.3",
|
|
48
|
-
"@types/ink": "^2.0.3",
|
|
49
|
-
"@types/ink-select-input": "^3.0.5",
|
|
50
|
-
"@types/ink-spinner": "^3.0.5",
|
|
51
|
-
"@types/ink-text-input": "^2.0.5",
|
|
52
|
-
"@types/node": "^25.6.2",
|
|
53
|
-
"@types/react": "^19.2.14",
|
|
54
|
-
"@swc/core": "^1.10.0",
|
|
55
|
-
"ts-node": "^10.9.2",
|
|
56
|
-
"tsup": "^8.0.0",
|
|
57
|
-
"tsx": "^4.21.0",
|
|
58
|
-
"typescript": "^6.0.3"
|
|
59
|
-
},
|
|
60
|
-
"dependencies": {
|
|
61
|
-
"7zip-bin": "^5.2.0",
|
|
62
|
-
"@spotify/web-api-ts-sdk": "^1.2.0",
|
|
63
|
-
"adm-zip": "^0.5.17",
|
|
64
|
-
"chalk": "^5.6.2",
|
|
65
|
-
"clipboardy": "^5.3.1",
|
|
66
|
-
"dotenv": "^17.4.2",
|
|
67
|
-
"flac-tagger": "^2.0.0",
|
|
68
|
-
"flat-cache": "^6.1.22",
|
|
69
|
-
"fullscreen-ink": "^0.1.0",
|
|
70
|
-
"ink": "^7.0.2",
|
|
71
|
-
"ink-big-text": "^2.0.0",
|
|
72
|
-
"ink-form": "^2.0.1",
|
|
73
|
-
"ink-gradient": "^4.0.0",
|
|
74
|
-
"ink-link": "^5.0.0",
|
|
75
|
-
"ink-picture": "^1.3.5",
|
|
76
|
-
"ink-select-input": "^6.2.0",
|
|
77
|
-
"ink-spinner": "^5.0.0",
|
|
78
|
-
"ink-text-input": "^6.0.0",
|
|
79
|
-
"musicbrainz-api": "^1.2.1",
|
|
80
|
-
"node-id3": "^0.2.9",
|
|
81
|
-
"open": "^11.0.0",
|
|
82
|
-
"react": "^19.2.6",
|
|
83
|
-
"slsk-client": "^1.1.0",
|
|
84
|
-
"winston": "^3.19.0",
|
|
85
|
-
"winston-transport": "^4.9.0",
|
|
86
|
-
"ytdlp-nodejs": "^3.4.4",
|
|
87
|
-
"ytmusic-api": "^5.3.1"
|
|
88
|
-
}
|
|
89
|
-
}
|
|
125
|
+
}
|