hoenir 0.0.0-probe → 1.6.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/CHANGELOG.md +167 -0
- package/LICENSE +1 -0
- package/README.md +235 -1
- package/dist/package.json +90 -0
- package/dist/src/hoenir.d.ts +2 -0
- package/dist/src/hoenir.js +345 -0
- package/dist/src/index.d.ts +62 -0
- package/dist/src/index.js +101 -0
- package/dist/src/kyrie.d.ts +2 -0
- package/dist/src/kyrie.js +345 -0
- package/dist/src/lib/api-download.d.ts +54 -0
- package/dist/src/lib/api-download.js +89 -0
- package/dist/src/lib/arl-setup.d.ts +82 -0
- package/dist/src/lib/arl-setup.js +274 -0
- package/dist/src/lib/auto-updater.d.ts +2 -0
- package/dist/src/lib/auto-updater.js +70 -0
- package/dist/src/lib/config.d.ts +53 -0
- package/dist/src/lib/config.js +164 -0
- package/dist/src/lib/decrypt-pool.d.ts +2 -0
- package/dist/src/lib/decrypt-pool.js +122 -0
- package/dist/src/lib/decrypt-worker.d.ts +1 -0
- package/dist/src/lib/decrypt-worker.js +17 -0
- package/dist/src/lib/decrypt.d.ts +3 -0
- package/dist/src/lib/decrypt.js +114 -0
- package/dist/src/lib/download-track.d.ts +24 -0
- package/dist/src/lib/download-track.js +163 -0
- package/dist/src/lib/email-login.d.ts +16 -0
- package/dist/src/lib/email-login.js +111 -0
- package/dist/src/lib/session.d.ts +84 -0
- package/dist/src/lib/session.js +118 -0
- package/dist/src/lib/signale.d.ts +15 -0
- package/dist/src/lib/signale.js +20 -0
- package/dist/src/lib/update-check.d.ts +2 -0
- package/dist/src/lib/update-check.js +30 -0
- package/dist/src/lib/util.d.ts +17 -0
- package/dist/src/lib/util.js +94 -0
- package/dist/src/q-fi.d.ts +2 -0
- package/dist/src/q-fi.js +345 -0
- package/package.json +88 -5
- package/setup-termux.js +41 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 1.6.2 - 2026-08-30
|
|
4
|
+
|
|
5
|
+
### Changed
|
|
6
|
+
|
|
7
|
+
- Renamed the package from `@soulwax/d-fi` to the unscoped **`hoenir`**. The CLI command, config file (`hoenir.config.json`), global config dir (`~/.config/hoenir/`), and env vars (`HOENIR_ARL` / `HOENIR_EMAIL` / `HOENIR_PASSWORD`) are renamed to match — existing `d-fi` configs and `D_FI_*` env vars are no longer read. Update `import`/`require` from `@soulwax/d-fi` → `hoenir`.
|
|
8
|
+
- Depends on `hoenir-core@^2.3.1` (was `@soulwax/d-fi-core`).
|
|
9
|
+
|
|
10
|
+
## 1.6.1 - 2026-07-12
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- `docs/api.md` — a complete programmatic API reference.
|
|
15
|
+
- `examples/` — runnable Node scripts for the API (login, search, track-info, in-memory buffer, download-url), reading credentials from env vars.
|
|
16
|
+
|
|
17
|
+
### Docs
|
|
18
|
+
|
|
19
|
+
- README links to the API reference and examples.
|
|
20
|
+
|
|
21
|
+
## 1.6.0 - 2026-07-12
|
|
22
|
+
|
|
23
|
+
### Added
|
|
24
|
+
|
|
25
|
+
- **Expanded programmatic API** — the package is now a full library, not just login helpers:
|
|
26
|
+
- `createSession({arl} | {email, password})` returning a `Session` with `parseUrl`, `search`, `getUser`, `getTrackBuffer`, `downloadTrack`, `downloadTracks`, and `downloadUrl`.
|
|
27
|
+
- `downloadTracks` / `downloadUrl` run with bounded `concurrency` and report progress via an `onProgress` callback (silent otherwise), returning one `{path, written} | null` per track.
|
|
28
|
+
- Download primitives: `getTrackBuffer(track, quality)` (returns a tagged audio Buffer without writing to disk) and `downloadTrackToFile(track, quality, options)`.
|
|
29
|
+
- Re-exported core query functions (`parseInfo`, `searchMusic`, `getUser`, `getTrackInfo`, `getAlbumInfo`, `getAlbumTracks`, `getPlaylistInfo`, `getPlaylistTracks`, `getArtistInfo`, `getDiscography`, `getLyrics`, `getTrackDownloadUrl`, `GeoBlocked`) so consumers don't need `hoenir-core` directly.
|
|
30
|
+
- Config helpers `globalConfigPath` and `resolveConfigFile` alongside the existing `Config`.
|
|
31
|
+
|
|
32
|
+
### Fixed
|
|
33
|
+
|
|
34
|
+
- The in-memory decrypt path now falls back to a pure-JS Blowfish implementation when OpenSSL 3 (Node 17+) disables the legacy `bf-cbc` cipher, matching the CLI. This makes programmatic downloads work out of the box on modern Node.
|
|
35
|
+
|
|
36
|
+
## 1.5.0 - 2026-07-12
|
|
37
|
+
|
|
38
|
+
### Added
|
|
39
|
+
|
|
40
|
+
- **Programmatic API.** The package now has a side-effect-free library entry point, so it can be used as a dependency: `import {getArl, loginWithEmail, LoginError, Config} from 'hoenir'`. Importing no longer runs the CLI. Ships `main`, `types`, and `exports`.
|
|
41
|
+
- `getArl(email, password)` — convenience that returns the arl or throws `LoginError`.
|
|
42
|
+
- `loginWithEmail(email, password)` — returns a typed `LoginResult` (`ok`/`reason`/`message`).
|
|
43
|
+
|
|
44
|
+
### Changed
|
|
45
|
+
|
|
46
|
+
- Email/password login now uses Deezer's mobile OAuth flow (`connect.deezer.com`) and works reliably, instead of the bot-blocked web form. It is now offered as the first option in guided setup (no longer hidden behind a flag), and used automatically for headless runs when `HOENIR_EMAIL`/`HOENIR_PASSWORD` are set and no arl is configured.
|
|
47
|
+
- `--experimental-login` is now a deprecated no-op (email login is on by default); the flag is still accepted for compatibility.
|
|
48
|
+
|
|
49
|
+
### Security
|
|
50
|
+
|
|
51
|
+
- Passwords are used only to authenticate and are never written to disk or logged; only the fetched arl is persisted (unless the user explicitly opts in to storing credentials).
|
|
52
|
+
|
|
53
|
+
## 1.4.2 - 2026-07-12
|
|
54
|
+
|
|
55
|
+
### Added
|
|
56
|
+
|
|
57
|
+
- Experimental email/password login (`--experimental-login`): attempts to fetch your `arl` from your Deezer credentials so you don't have to copy the cookie manually. This is best-effort — Deezer bot-protects scripted logins, so it commonly fails and falls back to pasting an `arl`. Only the fetched `arl` is persisted; the password is never written to disk unless you explicitly opt in.
|
|
58
|
+
- `HOENIR_EMAIL` / `HOENIR_PASSWORD` env vars and optional `cookies.email` / `cookies.password` config for non-interactive experimental login.
|
|
59
|
+
|
|
60
|
+
### Notes
|
|
61
|
+
|
|
62
|
+
- Email/password login is **off by default**; without `--experimental-login`, setup only offers the reliable "paste your arl" flow, unchanged from 1.4.1.
|
|
63
|
+
|
|
64
|
+
## 1.4.1 - 2026-07-12
|
|
65
|
+
|
|
66
|
+
### Added
|
|
67
|
+
|
|
68
|
+
- Guided `arl` setup on the first interactive run: when no `arl` is configured (or the bundled default is still in use), `hoenir` now explains where to find the cookie and prompts you to paste it, then saves it automatically.
|
|
69
|
+
- Interactive recovery when login fails: if the session cannot be verified (expired/invalid `arl`), `hoenir` offers to enter a fresh `arl` and retries instead of just erroring out.
|
|
70
|
+
- `hoenir setup` / `--setup` (`-s`): on-demand guided setup to (re)enter your `arl` cookie at any time.
|
|
71
|
+
- `HOENIR_ARL` environment variable: use an `arl` without a config file; it takes precedence over the config and is never written to disk (handy for CI, containers, and one-offs).
|
|
72
|
+
- Global config location: when no project-local `hoenir.config.json` exists, config is read from and saved to `$XDG_CONFIG_HOME/hoenir/hoenir.config.json` (or `~/.config/hoenir/hoenir.config.json`), so a saved `arl` works from any directory.
|
|
73
|
+
- `--overwrite` (`-w`) flag and `overwrite` config option to re-download and overwrite existing files (default remains to skip them).
|
|
74
|
+
|
|
75
|
+
### Changed
|
|
76
|
+
|
|
77
|
+
- Headless (`-d`), piped, and other non-interactive runs are unchanged — they never prompt and continue to use the configured `arl` (or `HOENIR_ARL`).
|
|
78
|
+
|
|
79
|
+
## 1.3.2 - 2026-07-09
|
|
80
|
+
|
|
81
|
+
### Changed
|
|
82
|
+
|
|
83
|
+
- Updated build scripts to be more os agnostic
|
|
84
|
+
|
|
85
|
+
## 1.3.1 - 2026-05-28
|
|
86
|
+
|
|
87
|
+
### Changed
|
|
88
|
+
|
|
89
|
+
- Updated the project screenshot asset.
|
|
90
|
+
|
|
91
|
+
## 1.3.0 - 2026-05-28
|
|
92
|
+
|
|
93
|
+
### Changed
|
|
94
|
+
|
|
95
|
+
- Completed the Tier 1-3 performance rollup for the CLI release line.
|
|
96
|
+
- Streamed encrypted tmpfile reads through the decrypt worker in fixed-size chunks instead of reading the whole encrypted file into memory first.
|
|
97
|
+
|
|
98
|
+
## 1.2.6 - 2026-05-28
|
|
99
|
+
|
|
100
|
+
### Changed
|
|
101
|
+
|
|
102
|
+
- Parallelized `--input-file` URL handling when quality is already provided, while keeping interactive quality prompts sequential.
|
|
103
|
+
|
|
104
|
+
## 1.2.5 - 2026-05-28
|
|
105
|
+
|
|
106
|
+
### Changed
|
|
107
|
+
|
|
108
|
+
- Offloaded encrypted track decryption to a small worker thread pool so parallel downloads are not blocked by CPU-bound decrypt work.
|
|
109
|
+
- Kept a pure-JS decrypt fallback for Node/OpenSSL builds where `bf-cbc` is unavailable.
|
|
110
|
+
|
|
111
|
+
## 1.2.4 - 2026-05-28
|
|
112
|
+
|
|
113
|
+
### Changed
|
|
114
|
+
|
|
115
|
+
- Switched CLI audio decryption to prefer the core implementation.
|
|
116
|
+
|
|
117
|
+
## 1.2.3 - 2026-05-28
|
|
118
|
+
|
|
119
|
+
### Changed
|
|
120
|
+
|
|
121
|
+
- Added a GitHub Actions workflow for npm publishing at `.github/workflows/publish.yml`.
|
|
122
|
+
- Bumped the package version to `1.2.3` for the release.
|
|
123
|
+
|
|
124
|
+
## 1.2.2 - 2026-05-28
|
|
125
|
+
|
|
126
|
+
### Changed
|
|
127
|
+
|
|
128
|
+
- Minor CLI banner and documentation cleanup.
|
|
129
|
+
|
|
130
|
+
## 1.2.0 - 2026-04-01
|
|
131
|
+
|
|
132
|
+
### Changed
|
|
133
|
+
|
|
134
|
+
- Bumped the CLI dependency to `hoenir-core@^2.2.0` so the published command-line package picks up the native HTTP transport release line.
|
|
135
|
+
- Switched internal type imports to the published `hoenir-core/types` subpath instead of reaching into `dist/` internals.
|
|
136
|
+
|
|
137
|
+
### Fixed
|
|
138
|
+
|
|
139
|
+
- Revalidated the CLI against the packed core artifact before publish so release verification matches the package shape that npm consumers install.
|
|
140
|
+
|
|
141
|
+
## 1.1.0 - 2026-04-01
|
|
142
|
+
|
|
143
|
+
### Changed
|
|
144
|
+
|
|
145
|
+
- Updated the CLI package to depend on the scoped core library package `hoenir-core`.
|
|
146
|
+
- Updated runtime and type imports to use the scoped core package name consistently, including the published `hoenir-core/types` subpath.
|
|
147
|
+
|
|
148
|
+
### Fixed
|
|
149
|
+
|
|
150
|
+
- Removed the last documentation link that still pointed at the old `hoenir/hoenir-core` repository path.
|
|
151
|
+
- Prepared the CLI package for the next scoped publish line without reintroducing the old unscoped dependency tree.
|
|
152
|
+
- Corrected the npm license metadata to use a valid `SEE LICENSE IN LICENSE` expression.
|
|
153
|
+
|
|
154
|
+
## 1.0.6 - 2026-03-26
|
|
155
|
+
|
|
156
|
+
### Changed
|
|
157
|
+
|
|
158
|
+
- Updated npm package metadata to use the GitHub repository at `https://github.com/soulwax/hoenir`.
|
|
159
|
+
- Limited the published npm package contents to runtime artifacts and release metadata.
|
|
160
|
+
- Updated README and docs links to use the current GitHub repository URLs.
|
|
161
|
+
|
|
162
|
+
### Fixed
|
|
163
|
+
|
|
164
|
+
- Corrected the repository URLs used in the README and CLI output.
|
|
165
|
+
- Fixed the auto-updater release API endpoint to target `soulwax/hoenir` on GitHub.
|
|
166
|
+
- Corrected npm and yarn install/update instructions to use the scoped package name `hoenir`.
|
|
167
|
+
- Made the test runner Windows-safe without adding dependencies.
|
package/LICENSE
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# Copyright Christian Kling 2024
|
package/README.md
CHANGED
|
@@ -1,3 +1,237 @@
|
|
|
1
1
|
# hoenir
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
<img src="https://raw.githubusercontent.com/soulwax/hoenir/main/.github/assets/logo.png" alt="hoenir logo" width="200" height="200" style="display: block; margin-left: auto; margin-right: auto;" />
|
|
4
|
+
|
|
5
|
+
> A crucial component of darkfloor streaming service systems.
|
|
6
|
+
> Source repository: https://github.com/soulwax/hoenir
|
|
7
|
+
>
|
|
8
|
+
> **hoenir** — the Norse god who gave the first humans _óðr_: mind, spirit, the power of expression. Formerly `d-fi` / `@soulwax/d-fi`.
|
|
9
|
+
|
|
10
|
+

|
|
11
|
+
|
|
12
|
+
**hoenir is a program for downloading music from streaming music services. Remember that the artists and studios put a lot of work into making music - purchase the original music to support them.**
|
|
13
|
+
|
|
14
|
+
## v2 Migration Guide
|
|
15
|
+
|
|
16
|
+
Please read [here](https://github.com/soulwax/hoenir/blob/main/docs/migration_v2.md) before contributing to the v2 branch.
|
|
17
|
+
|
|
18
|
+
## Features
|
|
19
|
+
|
|
20
|
+
- _Supports downloading tracks, albums, artists, and playlists_
|
|
21
|
+
- _Allows music quality selection (**128 kbps**, **320 kbps** and **FLAC**)_
|
|
22
|
+
- _Auto tagging **MP3** & **FLAC** (including album cover and lyrics)_
|
|
23
|
+
- _Support downloading from both links and via searching_
|
|
24
|
+
|
|
25
|
+
## Supported Sites
|
|
26
|
+
|
|
27
|
+
### _Deezer_, _Spotify_ and _Tidal_
|
|
28
|
+
|
|
29
|
+
- _Tracks_
|
|
30
|
+
- _Albums_
|
|
31
|
+
- _Audiobook_
|
|
32
|
+
- _Playlists_
|
|
33
|
+
- _Artists_
|
|
34
|
+
|
|
35
|
+
> Note that Spotify and Tidal tracks will be sourced from Deezer using ISRC matching and UPC for albums. Also Spotify artist tracks are limited upto 10 items.
|
|
36
|
+
|
|
37
|
+
## Install
|
|
38
|
+
|
|
39
|
+
### _Method 1_
|
|
40
|
+
|
|
41
|
+
First install `nodejs` following [this tutorial](https://nodejs.org/en/download/package-manager/)
|
|
42
|
+
|
|
43
|
+
Once `nodejs` installation is complete run this command.
|
|
44
|
+
|
|
45
|
+
npm i -g hoenir # may require sudo on linux and macOS
|
|
46
|
+
|
|
47
|
+
or if you are using yarn
|
|
48
|
+
|
|
49
|
+
yarn global add hoenir
|
|
50
|
+
|
|
51
|
+
or pnpm
|
|
52
|
+
|
|
53
|
+
pnpm add -g hoenir
|
|
54
|
+
|
|
55
|
+
Now you can run using command `hoenir` to start.
|
|
56
|
+
|
|
57
|
+
### First run — getting your `arl`
|
|
58
|
+
|
|
59
|
+
`hoenir` logs in to Deezer using an `arl` cookie. On the **first interactive run** (just
|
|
60
|
+
running `hoenir` with no `--headless`/scripting flags), if you have not configured an `arl`
|
|
61
|
+
yet, `hoenir` walks you through it: it prints where to find the cookie and prompts you to
|
|
62
|
+
paste it, then saves it for you. It will also offer to re-enter the `arl` if login fails
|
|
63
|
+
because the cookie has expired.
|
|
64
|
+
|
|
65
|
+
To get your `arl` manually:
|
|
66
|
+
|
|
67
|
+
1. Open [https://www.deezer.com](https://www.deezer.com) in your browser and log in.
|
|
68
|
+
2. Open DevTools (`F12`) → **Application** → **Cookies** → `deezer.com`.
|
|
69
|
+
3. Copy the value of the `arl` cookie (a long hex string).
|
|
70
|
+
|
|
71
|
+
You can set or update it any time without the prompt:
|
|
72
|
+
|
|
73
|
+
hoenir --set-arl <your_arl>
|
|
74
|
+
|
|
75
|
+
Or run the guided setup at any time:
|
|
76
|
+
|
|
77
|
+
hoenir setup # same as: hoenir --setup
|
|
78
|
+
|
|
79
|
+
#### Log in with email & password
|
|
80
|
+
|
|
81
|
+
`hoenir` can fetch your `arl` automatically from your Deezer email and password, so you
|
|
82
|
+
never have to open DevTools. The guided setup offers it as the first option:
|
|
83
|
+
|
|
84
|
+
hoenir setup
|
|
85
|
+
|
|
86
|
+
Only the fetched `arl` is stored; your password is never written to disk unless you
|
|
87
|
+
explicitly opt in when prompted. For headless use, supply `HOENIR_EMAIL` and
|
|
88
|
+
`HOENIR_PASSWORD` env vars and `hoenir` will log in automatically when no `arl` is set:
|
|
89
|
+
|
|
90
|
+
HOENIR_EMAIL=you@example.com HOENIR_PASSWORD=secret hoenir -q 320 -u <url>
|
|
91
|
+
|
|
92
|
+
> Login uses Deezer's mobile OAuth flow. If it ever fails (bad credentials or a change
|
|
93
|
+
> on Deezer's side), `hoenir` falls back to asking you to paste an `arl`.
|
|
94
|
+
|
|
95
|
+
### Zero-config usage (env var & global config)
|
|
96
|
+
|
|
97
|
+
`hoenir` works from **any directory** without a per-folder config file:
|
|
98
|
+
|
|
99
|
+
- Set the `HOENIR_ARL` environment variable and `hoenir` will use it (it takes precedence over
|
|
100
|
+
the config file, and is never written to disk). Handy for CI, containers, and one-offs:
|
|
101
|
+
|
|
102
|
+
HOENIR_ARL=<your_arl> hoenir -q 320 -u <url>
|
|
103
|
+
|
|
104
|
+
- When you save an `arl` (via `setup` or `--set-arl`) and there is no `hoenir.config.json` in
|
|
105
|
+
the current directory, `hoenir` stores it in a **global** location
|
|
106
|
+
(`$XDG_CONFIG_HOME/hoenir/hoenir.config.json`, or `~/.config/hoenir/hoenir.config.json`) so it is
|
|
107
|
+
reused everywhere. A `hoenir.config.json` in the current directory still takes precedence.
|
|
108
|
+
|
|
109
|
+
> Scripted, headless (`-d`), and non-interactive (piped) runs never prompt — they behave
|
|
110
|
+
> exactly as before and simply use the configured `arl` (or `HOENIR_ARL`).
|
|
111
|
+
|
|
112
|
+
### _Method 2_
|
|
113
|
+
|
|
114
|
+
Download pre-built binary from [here](https://github.com/soulwax/hoenir/releases) and then double click on Windows to run. For Linux and macOS user, first open your choice of terminal and the execute with `./hoenir`
|
|
115
|
+
|
|
116
|
+
## CLI Parameters
|
|
117
|
+
|
|
118
|
+
All options are optional. You can suppress prompts via providing `quality` and `url` if you are using scripts. You can also use config file. Read the docs [here](https://github.com/soulwax/hoenir/blob/main/docs/config.md) for more info.
|
|
119
|
+
|
|
120
|
+
| Parameter | Short | Supported values | Description |
|
|
121
|
+
| :-------------------- | :-------------: | :---------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------: |
|
|
122
|
+
| `--quality` | `-q` | 128/320/flac | The quality of the files to download |
|
|
123
|
+
| `--output` | `-o` | Output file format according to `saveLayout`. See more [here](https://github.com/soulwax/hoenir/blob/main/docs/config.md) | The path to download the files to |
|
|
124
|
+
| `--url` | `-u or nothing` | album/artist/playlist/track url | Downloads from url |
|
|
125
|
+
| `--input-file` | `-i` | Downloads all urls listed in text file. Example: `hoenir -i links.txt` | Downloads from url |
|
|
126
|
+
| `--concurrency` | `-c` 1 to 50 | Downloads X songs at a time | |
|
|
127
|
+
| `--set-arl` | `-a` | `arl` string | Set arl cookies |
|
|
128
|
+
| `--setup` | `-s` | _Nothing_ | Run guided setup to enter your `arl` cookie. Also available as `hoenir setup`. |
|
|
129
|
+
| `--overwrite` | `-w` | _Nothing_ | Re-download and overwrite existing files (default is to skip them). |
|
|
130
|
+
| `--experimental-login`| _None_ | _Nothing_ | Enable experimental email/password login to fetch an `arl` (often blocked by Deezer; falls back to arl paste). |
|
|
131
|
+
| `--headless` | `-d` | _Nothing_ | Run in headless mode. You must provide both `--url` and `--quality` if you run in headless mode. This mode is meant for scripting automation. |
|
|
132
|
+
| `--resolve-full-path` | `-rfp` | _Nothing_ | Create playlist file with absolute path location |
|
|
133
|
+
| `--create-playlist` | `-cp` | _Nothing_ | Create playlist for albums and artists |
|
|
134
|
+
| `--config-file` | `-conf` | Config location. Example: `hoenir -conf my-hoenir.config.json` | Specify custom location to config file |
|
|
135
|
+
| `--update` | `-U` | _Nothing_ | Download new update (binary only) |
|
|
136
|
+
| `--help` | `-h` | _Nothing_ | Shows the CLI help |
|
|
137
|
+
|
|
138
|
+
## Search Parameters
|
|
139
|
+
|
|
140
|
+
| Prefix | Description |
|
|
141
|
+
| :---------: | :-------------: |
|
|
142
|
+
| `artist:` | Search artist |
|
|
143
|
+
| `album:` | Search album |
|
|
144
|
+
| `playlist:` | Search playlist |
|
|
145
|
+
|
|
146
|
+
## Programmatic API
|
|
147
|
+
|
|
148
|
+
When installed as a dependency, `hoenir` exposes a side-effect-free API
|
|
149
|
+
(importing it does **not** print the banner or parse CLI args, and nothing logs to the
|
|
150
|
+
console — progress is delivered via callbacks). CommonJS and ESM both work.
|
|
151
|
+
|
|
152
|
+
> **Full reference:** [docs/api.md](https://github.com/soulwax/hoenir/blob/main/docs/api.md) ·
|
|
153
|
+
> **Runnable examples:** [examples/](https://github.com/soulwax/hoenir/tree/main/examples)
|
|
154
|
+
|
|
155
|
+
### High-level: sessions
|
|
156
|
+
|
|
157
|
+
The quickest path from credentials to files. `createSession` logs in (with an `arl` or
|
|
158
|
+
email/password), verifies the session, and returns helpers for querying and downloading:
|
|
159
|
+
|
|
160
|
+
```ts
|
|
161
|
+
import {createSession} from 'hoenir';
|
|
162
|
+
|
|
163
|
+
const session = await createSession({email: 'you@example.com', password: 'secret'});
|
|
164
|
+
// ...or: createSession({arl: '...'})
|
|
165
|
+
|
|
166
|
+
// Resolve any Deezer / Spotify / Tidal URL and download it:
|
|
167
|
+
await session.downloadUrl('https://deezer.com/album/302127', 'flac', {
|
|
168
|
+
output: 'Music/{ALB_TITLE}/{SNG_TITLE}',
|
|
169
|
+
concurrency: 4,
|
|
170
|
+
onProgress: ({index, total, track, result}) =>
|
|
171
|
+
console.log(`${index + 1}/${total} ${track.SNG_TITLE} -> ${result?.path ?? 'unavailable'}`),
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
// Or work with the pieces:
|
|
175
|
+
const {tracks} = await session.parseUrl('https://deezer.com/track/3135556');
|
|
176
|
+
const found = await session.search('daft punk', ['TRACK'], 10);
|
|
177
|
+
const results = await session.downloadTracks(tracks, '320', {output: '{ART_NAME} - {SNG_TITLE}'});
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
Session methods: `parseUrl`, `search`, `getUser`, `getTrackBuffer`, `downloadTrack`,
|
|
181
|
+
`downloadTracks`, `downloadUrl`. Every download call is silent; `downloadTracks` /
|
|
182
|
+
`downloadUrl` accept `concurrency` and an `onProgress` callback and return one
|
|
183
|
+
`{path, written} | null` per track.
|
|
184
|
+
|
|
185
|
+
### Low-level: primitives
|
|
186
|
+
|
|
187
|
+
```ts
|
|
188
|
+
import {getArl, initDeezerApi, getTrackInfo, getTrackBuffer, downloadTrackToFile} from 'hoenir';
|
|
189
|
+
|
|
190
|
+
const arl = await getArl('you@example.com', 'secret'); // throws LoginError on failure
|
|
191
|
+
await initDeezerApi(arl);
|
|
192
|
+
|
|
193
|
+
const track = await getTrackInfo('3135556');
|
|
194
|
+
|
|
195
|
+
// Get the tagged audio as a Buffer without touching the disk:
|
|
196
|
+
const mp3 = await getTrackBuffer(track, '320');
|
|
197
|
+
|
|
198
|
+
// ...or write it straight to a file:
|
|
199
|
+
const {path, written} = (await downloadTrackToFile(track, 'flac', {output: '{ART_NAME} - {SNG_TITLE}'}))!;
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
### Re-exported query functions
|
|
203
|
+
|
|
204
|
+
So you don't need `hoenir-core` as a second dependency (call after `initDeezerApi`
|
|
205
|
+
or `createSession`):
|
|
206
|
+
|
|
207
|
+
`parseInfo`, `searchMusic`, `getUser`, `getTrackInfo`, `getAlbumInfo`, `getAlbumTracks`,
|
|
208
|
+
`getPlaylistInfo`, `getPlaylistTracks`, `getArtistInfo`, `getDiscography`, `getLyrics`,
|
|
209
|
+
`getTrackDownloadUrl`, `GeoBlocked`.
|
|
210
|
+
|
|
211
|
+
### Auth & config helpers
|
|
212
|
+
|
|
213
|
+
```ts
|
|
214
|
+
import {loginWithEmail, LoginError, Config, globalConfigPath} from 'hoenir';
|
|
215
|
+
|
|
216
|
+
const result = await loginWithEmail('you@example.com', 'password');
|
|
217
|
+
if (result.ok) console.log(result.arl);
|
|
218
|
+
else console.error(result.reason, result.message); // 'wrong-credentials' | 'no-arl' | 'network' | 'unknown'
|
|
219
|
+
|
|
220
|
+
const conf = new Config(); // same config file the CLI uses
|
|
221
|
+
conf.set('cookies.arl', result.ok ? result.arl : '');
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
Passwords passed to these functions are used only to authenticate and are never written
|
|
225
|
+
to disk or logged; only the resulting `arl` is returned or stored.
|
|
226
|
+
|
|
227
|
+
### Disclaimer
|
|
228
|
+
|
|
229
|
+
> I am not responsible in any way for the usage of others.
|
|
230
|
+
|
|
231
|
+
---
|
|
232
|
+
|
|
233
|
+
> Made with :heart: by the Bluesix Team. If you want to contribute, please read the [contributing guidelines](.github/CONTRIBUTING.md) first.
|
|
234
|
+
|
|
235
|
+
### License
|
|
236
|
+
|
|
237
|
+
Copyright © 2026 Christian Kling, Saskia Falkenhagen, Jens Arnolds
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "hoenir",
|
|
3
|
+
"version": "1.6.2",
|
|
4
|
+
"description": "The crucial streaming module for dabox systems.",
|
|
5
|
+
"author": "Christian Kling",
|
|
6
|
+
"license": "SEE LICENSE IN LICENSE",
|
|
7
|
+
"scripts": {
|
|
8
|
+
"lint": "eslint .",
|
|
9
|
+
"prepublishOnly": "eslint . && tsc",
|
|
10
|
+
"prebuild": "eslint .",
|
|
11
|
+
"build": "tsc",
|
|
12
|
+
"postinstall": "node setup-termux.js",
|
|
13
|
+
"dev": "ts-node src/hoenir.ts",
|
|
14
|
+
"test": "node scripts/run-ava.cjs"
|
|
15
|
+
},
|
|
16
|
+
"bin": {
|
|
17
|
+
"hoenir": "dist/src/hoenir.js"
|
|
18
|
+
},
|
|
19
|
+
"main": "dist/src/index.js",
|
|
20
|
+
"types": "dist/src/index.d.ts",
|
|
21
|
+
"exports": {
|
|
22
|
+
".": {
|
|
23
|
+
"types": "./dist/src/index.d.ts",
|
|
24
|
+
"default": "./dist/src/index.js"
|
|
25
|
+
},
|
|
26
|
+
"./package.json": "./package.json"
|
|
27
|
+
},
|
|
28
|
+
"files": [
|
|
29
|
+
"dist/**/*",
|
|
30
|
+
"setup-termux.js",
|
|
31
|
+
"CHANGELOG.md"
|
|
32
|
+
],
|
|
33
|
+
"repository": {
|
|
34
|
+
"type": "git",
|
|
35
|
+
"url": "git+https://github.com/soulwax/hoenir.git"
|
|
36
|
+
},
|
|
37
|
+
"homepage": "https://github.com/soulwax/hoenir#readme",
|
|
38
|
+
"bugs": {
|
|
39
|
+
"url": "https://github.com/soulwax/hoenir/issues"
|
|
40
|
+
},
|
|
41
|
+
"publishConfig": {
|
|
42
|
+
"access": "public"
|
|
43
|
+
},
|
|
44
|
+
"engines": {
|
|
45
|
+
"node": ">=12"
|
|
46
|
+
},
|
|
47
|
+
"dependencies": {
|
|
48
|
+
"adm-zip": "^0.5.16",
|
|
49
|
+
"chalk": "^4.1.2",
|
|
50
|
+
"commander": "^9.5.0",
|
|
51
|
+
"hoenir-core": "^2.3.1",
|
|
52
|
+
"dot-prop": "^6.0.1",
|
|
53
|
+
"egoroof-blowfish": "^4.0.2",
|
|
54
|
+
"got": "^11.8.6",
|
|
55
|
+
"gradient-string": "^2.0.2",
|
|
56
|
+
"log-update": "^4.0.0",
|
|
57
|
+
"p-queue": "^6.6.2",
|
|
58
|
+
"prompts": "^2.4.2",
|
|
59
|
+
"true-case-path": "^2.2.1",
|
|
60
|
+
"update-check": "^1.5.4"
|
|
61
|
+
},
|
|
62
|
+
"devDependencies": {
|
|
63
|
+
"@types/adm-zip": "^0.4.34",
|
|
64
|
+
"@types/gradient-string": "^1.1.6",
|
|
65
|
+
"@types/node": "^17.0.45",
|
|
66
|
+
"@types/prompts": "^2.4.9",
|
|
67
|
+
"@typescript-eslint/eslint-plugin": "^5.62.0",
|
|
68
|
+
"@typescript-eslint/parser": "^5.62.0",
|
|
69
|
+
"ava": "^4.3.3",
|
|
70
|
+
"eslint": "^8.57.1",
|
|
71
|
+
"eslint-plugin-prettier": "^4.2.5",
|
|
72
|
+
"prettier": "^2.8.8",
|
|
73
|
+
"ts-node": "^10.9.2",
|
|
74
|
+
"typescript": "^4.9.5"
|
|
75
|
+
},
|
|
76
|
+
"ava": {
|
|
77
|
+
"extensions": [
|
|
78
|
+
"ts"
|
|
79
|
+
],
|
|
80
|
+
"files": [
|
|
81
|
+
"!dist"
|
|
82
|
+
],
|
|
83
|
+
"require": [
|
|
84
|
+
"ts-node/register"
|
|
85
|
+
],
|
|
86
|
+
"timeout": "5m",
|
|
87
|
+
"serial": true,
|
|
88
|
+
"verbose": true
|
|
89
|
+
}
|
|
90
|
+
}
|