fluncle 0.201.0 → 0.203.0
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/bin/fluncle.mjs +126 -56
- package/package.json +1 -1
package/bin/fluncle.mjs
CHANGED
|
@@ -367,6 +367,55 @@ var require_main = __commonJS((exports, module) => {
|
|
|
367
367
|
module.exports = DotenvModule;
|
|
368
368
|
});
|
|
369
369
|
|
|
370
|
+
// src/env.ts
|
|
371
|
+
import { homedir } from "node:os";
|
|
372
|
+
import { join } from "node:path";
|
|
373
|
+
function loadEnv(keys) {
|
|
374
|
+
loadConfig();
|
|
375
|
+
const result = {};
|
|
376
|
+
const missing = [];
|
|
377
|
+
for (const key of keys) {
|
|
378
|
+
const value = process.env[key];
|
|
379
|
+
if (value === undefined) {
|
|
380
|
+
missing.push(key);
|
|
381
|
+
continue;
|
|
382
|
+
}
|
|
383
|
+
result[key] = value;
|
|
384
|
+
}
|
|
385
|
+
if (missing.length > 0) {
|
|
386
|
+
throw new Error(`Missing required env vars: ${missing.join(", ")}`);
|
|
387
|
+
}
|
|
388
|
+
return result;
|
|
389
|
+
}
|
|
390
|
+
function getApiBaseUrl() {
|
|
391
|
+
loadConfig();
|
|
392
|
+
return (process.env.FLUNCLE_API_BASE_URL ?? "https://www.fluncle.com").replace(/\/+$/, "");
|
|
393
|
+
}
|
|
394
|
+
function loadConfig() {
|
|
395
|
+
const profile = getEnvProfile();
|
|
396
|
+
if (loadedProfile === profile) {
|
|
397
|
+
return;
|
|
398
|
+
}
|
|
399
|
+
loadedProfile = profile;
|
|
400
|
+
if (false) {}
|
|
401
|
+
import_dotenv2.config({ path: join(homedir(), `.config/fluncle/.env.${profile}`), quiet: true });
|
|
402
|
+
}
|
|
403
|
+
function getEnvProfile() {
|
|
404
|
+
const profile = process.env.FLUNCLE_ENV ?? defaultEnvProfile;
|
|
405
|
+
if (!isEnvProfile2(profile)) {
|
|
406
|
+
throw new Error(`Unknown env profile: ${profile}. Expected local or production.`);
|
|
407
|
+
}
|
|
408
|
+
return profile;
|
|
409
|
+
}
|
|
410
|
+
function isEnvProfile2(value) {
|
|
411
|
+
return envProfiles2.includes(value);
|
|
412
|
+
}
|
|
413
|
+
var import_dotenv2, envProfiles2, defaultEnvProfile = "production", loadedProfile;
|
|
414
|
+
var init_env = __esm(() => {
|
|
415
|
+
import_dotenv2 = __toESM(require_main(), 1);
|
|
416
|
+
envProfiles2 = ["local", "production"];
|
|
417
|
+
});
|
|
418
|
+
|
|
370
419
|
// ../../packages/contracts/src/util.ts
|
|
371
420
|
function formatDuration(durationMs) {
|
|
372
421
|
const totalSeconds = Math.round(durationMs / 1000);
|
|
@@ -561,7 +610,7 @@ function parseVersion(version) {
|
|
|
561
610
|
var currentVersion;
|
|
562
611
|
var init_version = __esm(() => {
|
|
563
612
|
init_output();
|
|
564
|
-
currentVersion = "0.
|
|
613
|
+
currentVersion = "0.203.0".trim() ? "0.203.0".trim() : "0.1.0";
|
|
565
614
|
});
|
|
566
615
|
|
|
567
616
|
// src/update-notifier.ts
|
|
@@ -573,8 +622,8 @@ __export(exports_update_notifier, {
|
|
|
573
622
|
detectInstallMethod: () => detectInstallMethod
|
|
574
623
|
});
|
|
575
624
|
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
576
|
-
import { homedir, platform } from "node:os";
|
|
577
|
-
import { dirname, join, sep } from "node:path";
|
|
625
|
+
import { homedir as homedir2, platform } from "node:os";
|
|
626
|
+
import { dirname, join as join2, sep } from "node:path";
|
|
578
627
|
import { fileURLToPath } from "node:url";
|
|
579
628
|
async function notifyIfUpdateAvailable(args) {
|
|
580
629
|
try {
|
|
@@ -686,8 +735,8 @@ async function writeCache(state) {
|
|
|
686
735
|
} catch {}
|
|
687
736
|
}
|
|
688
737
|
function cacheFilePath() {
|
|
689
|
-
const base = process.env.XDG_CACHE_HOME?.trim() || platform() === "win32" && process.env.LOCALAPPDATA?.trim() ||
|
|
690
|
-
return
|
|
738
|
+
const base = process.env.XDG_CACHE_HOME?.trim() || platform() === "win32" && process.env.LOCALAPPDATA?.trim() || join2(homedir2(), ".config");
|
|
739
|
+
return join2(base, "fluncle", "update-check.json");
|
|
691
740
|
}
|
|
692
741
|
function buildNotice(current, latest) {
|
|
693
742
|
const method = detectInstallMethod({ entry: entryPath(), execPath: process.execPath || "" });
|
|
@@ -747,55 +796,6 @@ var init_update_notifier = __esm(() => {
|
|
|
747
796
|
cacheTtlMs = 24 * 60 * 60 * 1000;
|
|
748
797
|
});
|
|
749
798
|
|
|
750
|
-
// src/env.ts
|
|
751
|
-
import { homedir as homedir2 } from "node:os";
|
|
752
|
-
import { join as join2 } from "node:path";
|
|
753
|
-
function loadEnv(keys) {
|
|
754
|
-
loadConfig();
|
|
755
|
-
const result = {};
|
|
756
|
-
const missing = [];
|
|
757
|
-
for (const key of keys) {
|
|
758
|
-
const value = process.env[key];
|
|
759
|
-
if (value === undefined) {
|
|
760
|
-
missing.push(key);
|
|
761
|
-
continue;
|
|
762
|
-
}
|
|
763
|
-
result[key] = value;
|
|
764
|
-
}
|
|
765
|
-
if (missing.length > 0) {
|
|
766
|
-
throw new Error(`Missing required env vars: ${missing.join(", ")}`);
|
|
767
|
-
}
|
|
768
|
-
return result;
|
|
769
|
-
}
|
|
770
|
-
function getApiBaseUrl() {
|
|
771
|
-
loadConfig();
|
|
772
|
-
return (process.env.FLUNCLE_API_BASE_URL ?? "https://www.fluncle.com").replace(/\/+$/, "");
|
|
773
|
-
}
|
|
774
|
-
function loadConfig() {
|
|
775
|
-
const profile = getEnvProfile();
|
|
776
|
-
if (loadedProfile === profile) {
|
|
777
|
-
return;
|
|
778
|
-
}
|
|
779
|
-
loadedProfile = profile;
|
|
780
|
-
if (false) {}
|
|
781
|
-
import_dotenv2.config({ path: join2(homedir2(), `.config/fluncle/.env.${profile}`), quiet: true });
|
|
782
|
-
}
|
|
783
|
-
function getEnvProfile() {
|
|
784
|
-
const profile = process.env.FLUNCLE_ENV ?? defaultEnvProfile;
|
|
785
|
-
if (!isEnvProfile2(profile)) {
|
|
786
|
-
throw new Error(`Unknown env profile: ${profile}. Expected local or production.`);
|
|
787
|
-
}
|
|
788
|
-
return profile;
|
|
789
|
-
}
|
|
790
|
-
function isEnvProfile2(value) {
|
|
791
|
-
return envProfiles2.includes(value);
|
|
792
|
-
}
|
|
793
|
-
var import_dotenv2, envProfiles2, defaultEnvProfile = "production", loadedProfile;
|
|
794
|
-
var init_env = __esm(() => {
|
|
795
|
-
import_dotenv2 = __toESM(require_main(), 1);
|
|
796
|
-
envProfiles2 = ["local", "production"];
|
|
797
|
-
});
|
|
798
|
-
|
|
799
799
|
// src/user-token.ts
|
|
800
800
|
import { chmodSync, mkdirSync, readFileSync, rmSync, writeFileSync } from "node:fs";
|
|
801
801
|
import { homedir as homedir3 } from "node:os";
|
|
@@ -2452,7 +2452,7 @@ function parseVersion2(version) {
|
|
|
2452
2452
|
var currentVersion2, latestReleaseUrl = "https://api.github.com/repos/mauricekleine/fluncle/releases/latest";
|
|
2453
2453
|
var init_version2 = __esm(() => {
|
|
2454
2454
|
init_output();
|
|
2455
|
-
currentVersion2 = "0.
|
|
2455
|
+
currentVersion2 = "0.203.0".trim() ? "0.203.0".trim() : "0.1.0";
|
|
2456
2456
|
});
|
|
2457
2457
|
|
|
2458
2458
|
// ../../packages/registry/src/index.ts
|
|
@@ -3258,7 +3258,7 @@ var init_src = __esm(() => {
|
|
|
3258
3258
|
{
|
|
3259
3259
|
command: "ssh rave.fluncle.com",
|
|
3260
3260
|
exposedContent: [
|
|
3261
|
-
"the rave terminal TUI: Latest
|
|
3261
|
+
"the rave terminal TUI: Latest findings, Fresh releases, Artist archive, Sonic galaxies, Mixtape archive, Random banger, Submit, Subscribe, Install CLI, System status, About",
|
|
3262
3262
|
"deep-register one-shots: `ssh rave.fluncle.com latest|fresh|random`"
|
|
3263
3263
|
],
|
|
3264
3264
|
kind: "ssh",
|
|
@@ -6710,6 +6710,7 @@ __export(exports_admin_catalogue, {
|
|
|
6710
6710
|
verifyCaptureCommand: () => verifyCaptureCommand,
|
|
6711
6711
|
setTrackDismissedCommand: () => setTrackDismissedCommand,
|
|
6712
6712
|
requeueUnmatchedCommand: () => requeueUnmatchedCommand,
|
|
6713
|
+
requeueAnchorCommand: () => requeueAnchorCommand,
|
|
6713
6714
|
listUnverifiedCapturesCommand: () => listUnverifiedCapturesCommand,
|
|
6714
6715
|
forceCaptureCommand: () => forceCaptureCommand,
|
|
6715
6716
|
flagWrongAudioCommand: () => flagWrongAudioCommand,
|
|
@@ -6749,6 +6750,11 @@ async function clearWrongAudioCommand(trackId) {
|
|
|
6749
6750
|
async function requeueUnmatchedCommand() {
|
|
6750
6751
|
return adminApiPost("/api/v1/admin/catalogue/captures/requeue-unmatched", {});
|
|
6751
6752
|
}
|
|
6753
|
+
async function requeueAnchorCommand(trackIds) {
|
|
6754
|
+
return adminApiPost("/api/v1/admin/catalogue/anchor/requeue", {
|
|
6755
|
+
trackIds
|
|
6756
|
+
});
|
|
6757
|
+
}
|
|
6752
6758
|
async function forceCaptureCommand(trackId) {
|
|
6753
6759
|
return adminApiPost("/api/v1/admin/catalogue/force-capture", {
|
|
6754
6760
|
trackId
|
|
@@ -9362,6 +9368,60 @@ function isEnvProfile(value) {
|
|
|
9362
9368
|
var spotifyPlaylistUrl = "https://open.spotify.com/playlist/1m5LADqpLjiBERdtqrIiL0";
|
|
9363
9369
|
var telegramUrl = "https://t.me/fluncle";
|
|
9364
9370
|
|
|
9371
|
+
// src/live.ts
|
|
9372
|
+
init_env();
|
|
9373
|
+
var NEBULA_VIOLET = "\x1B[38;2;171;123;255m";
|
|
9374
|
+
var RESET = "\x1B[0m";
|
|
9375
|
+
var TIMEOUT_MS = 1500;
|
|
9376
|
+
function shouldSkip(args) {
|
|
9377
|
+
if (process.env.FLUNCLE_NO_LIVE_CALLOUT === "1") {
|
|
9378
|
+
return true;
|
|
9379
|
+
}
|
|
9380
|
+
if (process.env.CI) {
|
|
9381
|
+
return true;
|
|
9382
|
+
}
|
|
9383
|
+
if (args.length === 0) {
|
|
9384
|
+
return true;
|
|
9385
|
+
}
|
|
9386
|
+
const first = args[0];
|
|
9387
|
+
if (first === "admin" || first === "help") {
|
|
9388
|
+
return true;
|
|
9389
|
+
}
|
|
9390
|
+
return args.some((arg) => arg === "--json" || arg === "--help" || arg === "-h" || arg === "--version" || arg === "-V");
|
|
9391
|
+
}
|
|
9392
|
+
function displayUrl(url) {
|
|
9393
|
+
return url.replace(/^https?:\/\/(www\.)?/, "");
|
|
9394
|
+
}
|
|
9395
|
+
async function maybePrintLiveCallout(args) {
|
|
9396
|
+
if (shouldSkip(args) || process.stdout.isTTY !== true) {
|
|
9397
|
+
return;
|
|
9398
|
+
}
|
|
9399
|
+
try {
|
|
9400
|
+
const controller = new AbortController;
|
|
9401
|
+
const timer = setTimeout(() => controller.abort(), TIMEOUT_MS);
|
|
9402
|
+
let data;
|
|
9403
|
+
try {
|
|
9404
|
+
const response = await fetch(`${getApiBaseUrl()}/api/v1/status`, {
|
|
9405
|
+
signal: controller.signal
|
|
9406
|
+
});
|
|
9407
|
+
if (!response.ok) {
|
|
9408
|
+
return;
|
|
9409
|
+
}
|
|
9410
|
+
data = await response.json();
|
|
9411
|
+
} finally {
|
|
9412
|
+
clearTimeout(timer);
|
|
9413
|
+
}
|
|
9414
|
+
const live = data.live;
|
|
9415
|
+
if (!live?.on) {
|
|
9416
|
+
return;
|
|
9417
|
+
}
|
|
9418
|
+
const text = `On the decks, live now: ${displayUrl(live.url)}`;
|
|
9419
|
+
const line = process.env.NO_COLOR ? text : `${NEBULA_VIOLET}${text}${RESET}`;
|
|
9420
|
+
console.log(`${line}
|
|
9421
|
+
`);
|
|
9422
|
+
} catch {}
|
|
9423
|
+
}
|
|
9424
|
+
|
|
9365
9425
|
// src/output.ts
|
|
9366
9426
|
import { writeSync } from "node:fs";
|
|
9367
9427
|
var EAGAIN_WAIT = new Int32Array(new SharedArrayBuffer(4));
|
|
@@ -9440,6 +9500,7 @@ async function main(args = process.argv.slice(2)) {
|
|
|
9440
9500
|
program2.outputHelp();
|
|
9441
9501
|
return;
|
|
9442
9502
|
}
|
|
9503
|
+
await maybePrintLiveCallout(args);
|
|
9443
9504
|
try {
|
|
9444
9505
|
assertParseArgsCompatiblePositionals(args);
|
|
9445
9506
|
assertParseArgsCompatibleOptionValues(args);
|
|
@@ -10082,6 +10143,15 @@ function addAdminCommands(program2) {
|
|
|
10082
10143
|
}
|
|
10083
10144
|
console.log(cleared ? `Kept ${trackId}. Its audio re-embeds and rejoins the ranking on the next sweep.` : `${trackId} was not quarantined \u2014 nothing to clear.`);
|
|
10084
10145
|
});
|
|
10146
|
+
catalogue.command("requeue-anchor").description("Clear rows' anchor re-ask backoff so the next tick retries them (operator)").argument("<trackIds...>", "The catalogue track id(s) to requeue (up to 250)").option("--json", "Print JSON", false).action(async (trackIds, options) => {
|
|
10147
|
+
const { requeueAnchorCommand: requeueAnchorCommand2 } = await Promise.resolve().then(() => (init_admin_catalogue(), exports_admin_catalogue));
|
|
10148
|
+
const { requeued } = await requeueAnchorCommand2(trackIds);
|
|
10149
|
+
if (options.json) {
|
|
10150
|
+
printJson({ ok: true, requeued });
|
|
10151
|
+
return;
|
|
10152
|
+
}
|
|
10153
|
+
console.log(`Re-queued ${requeued} of ${trackIds.length} row(s) \u2014 the next anchor tick picks them up at their real priority.`);
|
|
10154
|
+
});
|
|
10085
10155
|
catalogue.command("requeue-unmatched").description("Re-queue terminal-unmatched captures after a matcher improvement (operator)").option("--json", "Print JSON", false).action(async (options) => {
|
|
10086
10156
|
const { requeueUnmatchedCommand: requeueUnmatchedCommand2 } = await Promise.resolve().then(() => (init_admin_catalogue(), exports_admin_catalogue));
|
|
10087
10157
|
const { requeued, skippedVetoed } = await requeueUnmatchedCommand2();
|
package/package.json
CHANGED