fluncle 0.87.0 → 0.88.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.
Files changed (2) hide show
  1. package/bin/fluncle.mjs +32 -178
  2. package/package.json +1 -1
package/bin/fluncle.mjs CHANGED
@@ -538,7 +538,7 @@ function parseVersion(version) {
538
538
  var currentVersion;
539
539
  var init_version = __esm(() => {
540
540
  init_output();
541
- currentVersion = "0.87.0".trim() ? "0.87.0".trim() : "0.1.0";
541
+ currentVersion = "0.88.0".trim() ? "0.88.0".trim() : "0.1.0";
542
542
  });
543
543
 
544
544
  // src/update-notifier.ts
@@ -1335,47 +1335,22 @@ __export(exports_mixtapes, {
1335
1335
  mixtapesCommand: () => mixtapesCommand,
1336
1336
  mixtapeUpdateCommand: () => mixtapeUpdateCommand,
1337
1337
  mixtapeResyncCommand: () => mixtapeResyncCommand,
1338
- mixtapePublishCommand: () => mixtapePublishCommand,
1339
- mixtapeMembersCommand: () => mixtapeMembersCommand,
1340
1338
  mixtapeListCommand: () => mixtapeListCommand,
1341
1339
  mixtapeGetCommand: () => mixtapeGetCommand,
1342
- mixtapeDistributeCommand: () => mixtapeDistributeCommand,
1343
- mixtapeDeleteCommand: () => mixtapeDeleteCommand,
1344
- mixtapeCreateCommand: () => mixtapeCreateCommand
1340
+ mixtapeDistributeCommand: () => mixtapeDistributeCommand
1345
1341
  });
1346
- import { existsSync, readFileSync as readFileSync2 } from "node:fs";
1347
1342
  async function mixtapesCommand() {
1348
1343
  const response = await publicApiGet("/api/mixtapes");
1349
1344
  return response.mixtapes;
1350
1345
  }
1351
- async function mixtapeCreateCommand(options) {
1352
- return adminApiPost("/api/admin/mixtapes", buildBody(options));
1353
- }
1354
1346
  async function mixtapeUpdateCommand(id, options) {
1355
1347
  return adminApiPatch(`/api/admin/mixtapes/${encodeURIComponent(id)}`, buildBody(options));
1356
1348
  }
1357
- async function mixtapeMembersCommand(id, refs, options) {
1358
- const members = refs.map((ref) => ({ ref }));
1359
- if (options.from) {
1360
- members.push(...parseCueFile(options.from));
1361
- }
1362
- return adminApiPut(`/api/admin/mixtapes/${encodeURIComponent(id)}/members`, { members });
1363
- }
1364
- async function mixtapePublishCommand(id) {
1365
- return adminApiPost(`/api/admin/mixtapes/${encodeURIComponent(id)}/publish`);
1366
- }
1367
- async function mixtapeDeleteCommand(id) {
1368
- return adminApiDelete(`/api/admin/mixtapes/${encodeURIComponent(id)}`);
1369
- }
1370
1349
  async function mixtapeDistributeCommand(idOrLogId, options, onProgress = () => {}) {
1371
1350
  const mixtape = await mixtapeGetCommand(idOrLogId);
1372
1351
  if (!mixtape.id) {
1373
1352
  throw new CliError2("mixtape_not_found", `No mixtape with id or log id ${idOrLogId}`);
1374
1353
  }
1375
- if (mixtape.status === "draft") {
1376
- throw new CliError2("mixtape_not_promoted", `${mixtape.id} is still a draft — promote its recording first:
1377
- ` + " fluncle admin recordings promote <recordingId>");
1378
- }
1379
1354
  const both = !options.youtube && !options.mixcloud;
1380
1355
  const doYoutube = both || Boolean(options.youtube);
1381
1356
  const doMixcloud = both || Boolean(options.mixcloud);
@@ -1388,7 +1363,8 @@ async function mixtapeDistributeCommand(idOrLogId, options, onProgress = () => {
1388
1363
  const mixtapeId = mixtape.id;
1389
1364
  const logId = mixtape.logId;
1390
1365
  if (!logId) {
1391
- throw new CliError2("missing_log_id", "The mixtape has no Log IDwas it promoted successfully?");
1366
+ throw new CliError2("mixtape_not_promoted", `${mixtapeId} has no coordinate yetpromote its recording first:
1367
+ ` + " fluncle admin recordings promote <recordingId>");
1392
1368
  }
1393
1369
  if (!mixtape.durationMs) {
1394
1370
  const source = options.audio ?? options.video;
@@ -1495,65 +1471,6 @@ function buildBody(options) {
1495
1471
  }
1496
1472
  return body;
1497
1473
  }
1498
- function parseCueFile(filePath) {
1499
- if (!existsSync(filePath)) {
1500
- throw new CliError2("file_not_found", `Cue file not found: ${filePath}`);
1501
- }
1502
- const text = readFileSync2(filePath, "utf-8");
1503
- const trimmed = text.trim();
1504
- if (trimmed.startsWith("[") || trimmed.startsWith("{")) {
1505
- try {
1506
- const parsed = JSON.parse(trimmed);
1507
- if (!Array.isArray(parsed)) {
1508
- throw new Error("not an array");
1509
- }
1510
- return parsed.map((entry, index) => {
1511
- if (typeof entry === "string") {
1512
- return { ref: entry.trim() };
1513
- }
1514
- const obj = entry;
1515
- if (typeof obj?.ref !== "string") {
1516
- throw new CliError2("invalid_cue_json", `Entry ${index + 1} missing "ref" string`);
1517
- }
1518
- const cue = { ref: obj.ref.trim() };
1519
- if (typeof obj.startMs === "number" && Number.isInteger(obj.startMs) && obj.startMs >= 0) {
1520
- cue.startMs = obj.startMs;
1521
- }
1522
- return cue;
1523
- });
1524
- } catch (error) {
1525
- if (error instanceof CliError2) {
1526
- throw error;
1527
- }
1528
- throw new CliError2("invalid_cue_json", `Cue JSON parse failed: ${error instanceof Error ? error.message : String(error)}`);
1529
- }
1530
- }
1531
- return parseCueSheet(text);
1532
- }
1533
- function parseCueSheet(text) {
1534
- const entries = [];
1535
- for (const line of text.split(/\r?\n/)) {
1536
- const trimmed = line.trim();
1537
- if (!trimmed || trimmed.startsWith("#")) {
1538
- continue;
1539
- }
1540
- const match = trimmed.match(/^(\d{1,2}:\d{2}(?::\d{2})?)\s+(.+)$/);
1541
- if (match) {
1542
- const [, time, ref] = match;
1543
- if (time === undefined || ref === undefined) {
1544
- continue;
1545
- }
1546
- const startMs = parseDuration(time);
1547
- if (startMs === null) {
1548
- continue;
1549
- }
1550
- entries.push({ ref: ref.trim(), startMs });
1551
- } else {
1552
- entries.push({ ref: trimmed });
1553
- }
1554
- }
1555
- return entries;
1556
- }
1557
1474
  var init_mixtapes = __esm(() => {
1558
1475
  init_util();
1559
1476
  init_api();
@@ -2251,7 +2168,7 @@ function parseVersion2(version) {
2251
2168
  var currentVersion2, latestReleaseUrl = "https://api.github.com/repos/mauricekleine/fluncle/releases/latest";
2252
2169
  var init_version2 = __esm(() => {
2253
2170
  init_output();
2254
- currentVersion2 = "0.87.0".trim() ? "0.87.0".trim() : "0.1.0";
2171
+ currentVersion2 = "0.88.0".trim() ? "0.88.0".trim() : "0.1.0";
2255
2172
  });
2256
2173
 
2257
2174
  // ../../packages/registry/src/index.ts
@@ -2773,7 +2690,7 @@ var init_src = __esm(() => {
2773
2690
  {
2774
2691
  command: "fluncle admin",
2775
2692
  exposedContent: [
2776
- "the operator/agent command group (hidden): tracks publish|update|enrich|video|draft|social|preview|observe|context|note, mixtapes create|update|members|publish|delete, newsletter draft|update|send|list, backfills, auth"
2693
+ "the operator/agent command group (hidden): tracks publish|update|enrich|video|draft|social|preview|observe|context|note, recordings create|promote, mixtapes update|distribute|resync, newsletter draft|update|send|list, backfills, auth"
2777
2694
  ],
2778
2695
  kind: "cli",
2779
2696
  name: "cli.admin",
@@ -3668,7 +3585,7 @@ var init_mixtape_youtube2 = __esm(() => {
3668
3585
 
3669
3586
  // src/commands/mixtape-set-video.ts
3670
3587
  import { randomUUID } from "node:crypto";
3671
- import { existsSync as existsSync2, rmSync as rmSync2, statSync as statSync3 } from "node:fs";
3588
+ import { existsSync, rmSync as rmSync2, statSync as statSync3 } from "node:fs";
3672
3589
  import { tmpdir } from "node:os";
3673
3590
  import { join as join4 } from "node:path";
3674
3591
  function planMultipart(contentLength, partSize = DEFAULT_PART_SIZE) {
@@ -3725,7 +3642,7 @@ function renditionFfmpegArgs(inputPath, outputPath) {
3725
3642
  ];
3726
3643
  }
3727
3644
  async function uploadRenditionMultipart(masterPath, presignPath, onProgress = () => {}) {
3728
- if (!existsSync2(masterPath)) {
3645
+ if (!existsSync(masterPath)) {
3729
3646
  throw new CliError2("file_not_found", `Set-video master not found: ${masterPath}`);
3730
3647
  }
3731
3648
  await assertFfmpeg();
@@ -3838,7 +3755,7 @@ __export(exports_recordings, {
3838
3755
  recordingDeleteCommand: () => recordingDeleteCommand,
3839
3756
  recordingCreateCommand: () => recordingCreateCommand
3840
3757
  });
3841
- import { existsSync as existsSync3, readFileSync as readFileSync3 } from "node:fs";
3758
+ import { existsSync as existsSync2, readFileSync as readFileSync2 } from "node:fs";
3842
3759
  async function recordingGet(id) {
3843
3760
  const response = await adminApiGet(`/api/admin/recordings/${encodeURIComponent(id)}`);
3844
3761
  return response.recording;
@@ -3907,7 +3824,7 @@ async function recordingCreateCommand(options = {}) {
3907
3824
  if (!options.video) {
3908
3825
  throw new CliError2("missing_video", "A recording needs a --video <file> to stage");
3909
3826
  }
3910
- if (!existsSync3(options.video)) {
3827
+ if (!existsSync2(options.video)) {
3911
3828
  throw new CliError2("file_not_found", `Set-video master not found: ${options.video}`);
3912
3829
  }
3913
3830
  const created = await adminApiPost("/api/admin/recordings", {
@@ -3943,11 +3860,11 @@ async function recordingUpdateCommand(id, options = {}) {
3943
3860
  body.parentId = options.parentId;
3944
3861
  }
3945
3862
  if (options.tracklistFile !== undefined) {
3946
- if (!existsSync3(options.tracklistFile)) {
3863
+ if (!existsSync2(options.tracklistFile)) {
3947
3864
  throw new CliError2("file_not_found", `Tracklist file not found: ${options.tracklistFile}`);
3948
3865
  }
3949
3866
  try {
3950
- body.tracklistJson = JSON.parse(readFileSync3(options.tracklistFile, "utf8"));
3867
+ body.tracklistJson = JSON.parse(readFileSync2(options.tracklistFile, "utf8"));
3951
3868
  } catch {
3952
3869
  throw new CliError2("invalid_tracklist", `Tracklist file is not valid JSON: ${options.tracklistFile}`);
3953
3870
  }
@@ -3992,12 +3909,12 @@ async function recordingReplaceCuesCommand(id, options = {}) {
3992
3909
  if (!options.cuesFile) {
3993
3910
  throw new CliError2("missing_cues_file", "replace-cues needs a --cues-file <file> (the ordered cue array)");
3994
3911
  }
3995
- if (!existsSync3(options.cuesFile)) {
3912
+ if (!existsSync2(options.cuesFile)) {
3996
3913
  throw new CliError2("file_not_found", `Cues file not found: ${options.cuesFile}`);
3997
3914
  }
3998
3915
  let cues;
3999
3916
  try {
4000
- cues = JSON.parse(readFileSync3(options.cuesFile, "utf8"));
3917
+ cues = JSON.parse(readFileSync2(options.cuesFile, "utf8"));
4001
3918
  } catch {
4002
3919
  throw new CliError2("invalid_cues", `Cues file is not valid JSON: ${options.cuesFile}`);
4003
3920
  }
@@ -4201,7 +4118,7 @@ __export(exports_recordings2, {
4201
4118
  recordingDeleteCommand: () => recordingDeleteCommand2,
4202
4119
  recordingCreateCommand: () => recordingCreateCommand2
4203
4120
  });
4204
- import { existsSync as existsSync4, readFileSync as readFileSync4 } from "node:fs";
4121
+ import { existsSync as existsSync3, readFileSync as readFileSync3 } from "node:fs";
4205
4122
  async function recordingGet2(id) {
4206
4123
  const response = await adminApiGet(`/api/admin/recordings/${encodeURIComponent(id)}`);
4207
4124
  return response.recording;
@@ -4270,7 +4187,7 @@ async function recordingCreateCommand2(options = {}) {
4270
4187
  if (!options.video) {
4271
4188
  throw new CliError2("missing_video", "A recording needs a --video <file> to stage");
4272
4189
  }
4273
- if (!existsSync4(options.video)) {
4190
+ if (!existsSync3(options.video)) {
4274
4191
  throw new CliError2("file_not_found", `Set-video master not found: ${options.video}`);
4275
4192
  }
4276
4193
  const created = await adminApiPost("/api/admin/recordings", {
@@ -4306,11 +4223,11 @@ async function recordingUpdateCommand2(id, options = {}) {
4306
4223
  body.parentId = options.parentId;
4307
4224
  }
4308
4225
  if (options.tracklistFile !== undefined) {
4309
- if (!existsSync4(options.tracklistFile)) {
4226
+ if (!existsSync3(options.tracklistFile)) {
4310
4227
  throw new CliError2("file_not_found", `Tracklist file not found: ${options.tracklistFile}`);
4311
4228
  }
4312
4229
  try {
4313
- body.tracklistJson = JSON.parse(readFileSync4(options.tracklistFile, "utf8"));
4230
+ body.tracklistJson = JSON.parse(readFileSync3(options.tracklistFile, "utf8"));
4314
4231
  } catch {
4315
4232
  throw new CliError2("invalid_tracklist", `Tracklist file is not valid JSON: ${options.tracklistFile}`);
4316
4233
  }
@@ -4355,12 +4272,12 @@ async function recordingReplaceCuesCommand2(id, options = {}) {
4355
4272
  if (!options.cuesFile) {
4356
4273
  throw new CliError2("missing_cues_file", "replace-cues needs a --cues-file <file> (the ordered cue array)");
4357
4274
  }
4358
- if (!existsSync4(options.cuesFile)) {
4275
+ if (!existsSync3(options.cuesFile)) {
4359
4276
  throw new CliError2("file_not_found", `Cues file not found: ${options.cuesFile}`);
4360
4277
  }
4361
4278
  let cues;
4362
4279
  try {
4363
- cues = JSON.parse(readFileSync4(options.cuesFile, "utf8"));
4280
+ cues = JSON.parse(readFileSync3(options.cuesFile, "utf8"));
4364
4281
  } catch {
4365
4282
  throw new CliError2("invalid_cues", `Cues file is not valid JSON: ${options.cuesFile}`);
4366
4283
  }
@@ -4386,7 +4303,7 @@ __export(exports_newsletter, {
4386
4303
  newsletterDraftCommand: () => newsletterDraftCommand,
4387
4304
  newsletterDeleteCommand: () => newsletterDeleteCommand
4388
4305
  });
4389
- import { existsSync as existsSync5, readFileSync as readFileSync5 } from "node:fs";
4306
+ import { existsSync as existsSync4, readFileSync as readFileSync4 } from "node:fs";
4390
4307
  function buildBody2(options, { requireContent }) {
4391
4308
  const body = {};
4392
4309
  if (options.contentFile !== undefined) {
@@ -4406,10 +4323,10 @@ function buildBody2(options, { requireContent }) {
4406
4323
  return body;
4407
4324
  }
4408
4325
  function readContentFile(filePath) {
4409
- if (!existsSync5(filePath)) {
4326
+ if (!existsSync4(filePath)) {
4410
4327
  throw new CliError2("file_not_found", `Content file not found: ${filePath}`);
4411
4328
  }
4412
- const text = readFileSync5(filePath, "utf-8");
4329
+ const text = readFileSync4(filePath, "utf-8");
4413
4330
  try {
4414
4331
  return JSON.parse(text);
4415
4332
  } catch (error) {
@@ -5044,7 +4961,7 @@ var init_format2 = __esm(() => {
5044
4961
  });
5045
4962
 
5046
4963
  // src/cli.ts
5047
- import { existsSync as existsSync6, readFileSync as readFileSync6 } from "fs";
4964
+ import { existsSync as existsSync5, readFileSync as readFileSync5 } from "fs";
5048
4965
  import path2 from "path";
5049
4966
 
5050
4967
  // ../../node_modules/commander/lib/error.js
@@ -7372,27 +7289,11 @@ function addAdminCommands(program2) {
7372
7289
  adminMixtapes.action(() => {
7373
7290
  adminMixtapes.outputHelp();
7374
7291
  });
7375
- adminMixtapes.command("create").description("Log a new mixtape draft").option("--duration-ms <duration>", "Duration (mm:ss, h:mm:ss, or ms)").option("--json", "Print JSON", false).option("--note <text>", "Operator note").option("--recorded-at <date>", "Recorded date (ISO)").option("--soundcloud-url <url>", "SoundCloud URL (manual; YouTube + Mixcloud come from distribute)").allowExcessArguments().action(async (options) => {
7376
- const { mixtapeCreateCommand: mixtapeCreateCommand2 } = await Promise.resolve().then(() => (init_mixtapes(), exports_mixtapes));
7377
- await runMixtapeCreate(options, mixtapeCreateCommand2);
7378
- });
7379
7292
  adminMixtapes.command("update").description("Update a mixtape's fields").argument("[id]").option("--duration-ms <duration>", "Duration (mm:ss, h:mm:ss, or ms)").option("--json", "Print JSON", false).option("--note <text>", "Operator note").option("--recorded-at <date>", "Recorded date (ISO)").option("--soundcloud-url <url>", "SoundCloud URL (manual; YouTube + Mixcloud come from distribute)").allowExcessArguments().action(async (id, options) => {
7380
7293
  const { mixtapeUpdateCommand: mixtapeUpdateCommand2 } = await Promise.resolve().then(() => (init_mixtapes(), exports_mixtapes));
7381
7294
  await runMixtapeUpdate(id, options, mixtapeUpdateCommand2);
7382
7295
  });
7383
- adminMixtapes.command("members").description("Set a mixtape's tracklist (refs and/or a cue-sheet file)").argument("[id]").argument("[refs...]").option("--from <file>", "Cue-sheet or JSON file with members").option("--json", "Print JSON", false).allowExcessArguments().action(async (id, refs, options) => {
7384
- const { mixtapeMembersCommand: mixtapeMembersCommand2 } = await Promise.resolve().then(() => (init_mixtapes(), exports_mixtapes));
7385
- await runMixtapeMembers(id, refs, options, mixtapeMembersCommand2);
7386
- });
7387
- adminMixtapes.command("publish").description("Publish a mixtape draft").argument("[id]").option("--json", "Print JSON", false).allowExcessArguments().action(async (id, options) => {
7388
- const { mixtapePublishCommand: mixtapePublishCommand2 } = await Promise.resolve().then(() => (init_mixtapes(), exports_mixtapes));
7389
- await runMixtapePublish(id, options, mixtapePublishCommand2);
7390
- });
7391
- adminMixtapes.command("delete").description("Discard a mixtape draft (published mixtapes can't be deleted)").argument("[id]").option("--json", "Print JSON", false).option("--yes", "Skip confirmation", false).allowExcessArguments().action(async (id, options) => {
7392
- const { mixtapeDeleteCommand: mixtapeDeleteCommand2 } = await Promise.resolve().then(() => (init_mixtapes(), exports_mixtapes));
7393
- await runMixtapeDelete(id, options, mixtapeDeleteCommand2);
7394
- });
7395
- adminMixtapes.command("list").description("List all mixtapes (including drafts)").option("--json", "Print JSON", false).allowExcessArguments().action(async (options) => {
7296
+ adminMixtapes.command("list").description("List all mixtapes (including distributing)").option("--json", "Print JSON", false).allowExcessArguments().action(async (options) => {
7396
7297
  const { mixtapeListCommand: mixtapeListCommand2 } = await Promise.resolve().then(() => (init_mixtapes(), exports_mixtapes));
7397
7298
  await runMixtapeList(options, mixtapeListCommand2);
7398
7299
  });
@@ -7559,7 +7460,7 @@ async function runTrackPreviewArchive(idOrLogId, options, previewArchiveUploadCo
7559
7460
  console.log(` mime: ${result.mime}`);
7560
7461
  }
7561
7462
  async function runTrackObserve(idOrLogId, options, trackObserveCommand2) {
7562
- const script = options.scriptFile ? readFileSync6(options.scriptFile, "utf8") : options.script;
7463
+ const script = options.scriptFile ? readFileSync5(options.scriptFile, "utf8") : options.script;
7563
7464
  if (!idOrLogId || !script || !script.trim()) {
7564
7465
  throw new Error("Usage: fluncle admin tracks observe <track_id|log_id> (--script <text> | --script-file <file>) [--voice-id <id>] [--duration-ms <ms>] [--context-note <text>] [--json]");
7565
7466
  }
@@ -7615,7 +7516,7 @@ async function runTrackContext(idOrLogId, options, trackContextCommand2) {
7615
7516
  }
7616
7517
  }
7617
7518
  async function runTrackNote(idOrLogId, options, trackNoteCommand2) {
7618
- const note = options.scriptFile ? readFileSync6(options.scriptFile, "utf8") : options.script;
7519
+ const note = options.scriptFile ? readFileSync5(options.scriptFile, "utf8") : options.script;
7619
7520
  if (!idOrLogId || !note || !note.trim()) {
7620
7521
  throw new Error("Usage: fluncle admin tracks note <track_id|log_id> (--script <text> | --script-file <file>) [--json]");
7621
7522
  }
@@ -7761,7 +7662,7 @@ async function runTrackVideo(idOrLogId, options, trackVideoCommand2) {
7761
7662
  return;
7762
7663
  }
7763
7664
  const candidate = path2.join(dir, name);
7764
- return existsSync6(candidate) ? candidate : undefined;
7665
+ return existsSync5(candidate) ? candidate : undefined;
7765
7666
  };
7766
7667
  const resolveFile = (explicit, name) => {
7767
7668
  if (explicit) {
@@ -7938,14 +7839,6 @@ async function runTrackPurgeVideo(idOrLogId, options, trackPurgeVideoCommand2) {
7938
7839
  }
7939
7840
  console.log(result.noVideo ? `${result.logId} has no video \u2014 nothing to purge.` : `Purging the stale renditions for ${result.logId} from the edge. The next play picks up the fresh render.`);
7940
7841
  }
7941
- async function runMixtapeCreate(options, mixtapeCreateCommand2) {
7942
- const result = await mixtapeCreateCommand2(options);
7943
- if (options.json) {
7944
- printJson(result);
7945
- return;
7946
- }
7947
- console.log(`Logged draft ${result.mixtape.id}. It stays a draft until you publish it.`);
7948
- }
7949
7842
  async function runMixtapeUpdate(id, options, mixtapeUpdateCommand2) {
7950
7843
  if (!id) {
7951
7844
  throw new Error("Missing mixtape id. Usage: fluncle admin mixtapes update <id>");
@@ -7957,31 +7850,6 @@ async function runMixtapeUpdate(id, options, mixtapeUpdateCommand2) {
7957
7850
  }
7958
7851
  console.log(`Saved ${result.mixtape.id}.`);
7959
7852
  }
7960
- async function runMixtapeMembers(id, refs, options, mixtapeMembersCommand2) {
7961
- if (!id) {
7962
- throw new Error("Missing mixtape id. Usage: fluncle admin mixtapes members <id> [refs...]");
7963
- }
7964
- if (refs.length === 0 && !options.from) {
7965
- throw new Error("Provide refs as arguments or a cue-sheet file with --from");
7966
- }
7967
- const result = await mixtapeMembersCommand2(id, refs, options);
7968
- if (options.json) {
7969
- printJson(result);
7970
- return;
7971
- }
7972
- console.log(`Saved the tracklist: ${result.mixtape.memberCount} bangers on ${result.mixtape.id}.`);
7973
- }
7974
- async function runMixtapePublish(id, options, mixtapePublishCommand2) {
7975
- if (!id) {
7976
- throw new Error("Missing mixtape id. Usage: fluncle admin mixtapes publish <id>");
7977
- }
7978
- const result = await mixtapePublishCommand2(id);
7979
- if (options.json) {
7980
- printJson(result);
7981
- return;
7982
- }
7983
- console.log(`Minted ${result.mixtape.logId} (fluncle://${result.mixtape.logId}) \u2014 distributing. ` + "Run `distribute` to push it to the platforms.");
7984
- }
7985
7853
  async function runMixtapeDistribute(idOrLogId, options, mixtapeDistributeCommand2) {
7986
7854
  if (!idOrLogId) {
7987
7855
  throw new Error("Missing mixtape id. Usage: fluncle admin mixtapes distribute <idOrLogId> --video <mp4> --audio <file>");
@@ -8023,20 +7891,6 @@ async function runMixtapeResync(idOrLogId, options, mixtapeResyncCommand2) {
8023
7891
  console.log(`Re-synced ${result.logId} (fluncle://${result.logId}).
8024
7892
  ${links}`);
8025
7893
  }
8026
- async function runMixtapeDelete(id, options, mixtapeDeleteCommand2) {
8027
- if (!id) {
8028
- throw new Error("Missing mixtape id. Usage: fluncle admin mixtapes delete <id> --yes");
8029
- }
8030
- if (!options.yes) {
8031
- throw new Error("Pass --yes to confirm the discard. Published mixtapes can't be deleted.");
8032
- }
8033
- await mixtapeDeleteCommand2(id);
8034
- if (options.json) {
8035
- printJson({ id, ok: true });
8036
- return;
8037
- }
8038
- console.log(`Discarded draft ${id}.`);
8039
- }
8040
7894
  async function runMixtapeList(options, mixtapeListCommand2) {
8041
7895
  const mixtapes = await mixtapeListCommand2();
8042
7896
  if (options.json) {
@@ -8048,8 +7902,8 @@ async function runMixtapeList(options, mixtapeListCommand2) {
8048
7902
  return;
8049
7903
  }
8050
7904
  for (const mixtape of mixtapes) {
8051
- const status = mixtape.status ?? "draft";
8052
- const coordinate3 = mixtape.logId ?? "draft";
7905
+ const status = mixtape.status ?? "distributing";
7906
+ const coordinate3 = mixtape.logId ?? "unminted";
8053
7907
  console.log(`${coordinate3} ${status} ${mixtape.memberCount} bangers ${mixtape.title}`);
8054
7908
  }
8055
7909
  }
@@ -8092,8 +7946,8 @@ async function runMixtapeGet(idOrLogId, options, mixtapeGetCommand2) {
8092
7946
  printJson(mixtape);
8093
7947
  return;
8094
7948
  }
8095
- const coordinate3 = mixtape.logId ?? "draft";
8096
- const status = mixtape.status ?? "draft";
7949
+ const coordinate3 = mixtape.logId ?? "unminted";
7950
+ const status = mixtape.status ?? "distributing";
8097
7951
  console.log(`${mixtape.title}`);
8098
7952
  console.log(` ${coordinate3} \xB7 ${status} \xB7 ${mixtape.memberCount} bangers`);
8099
7953
  if (mixtape.note) {
package/package.json CHANGED
@@ -31,5 +31,5 @@
31
31
  "url": "git+https://github.com/mauricekleine/fluncle.git"
32
32
  },
33
33
  "type": "module",
34
- "version": "0.87.0"
34
+ "version": "0.88.0"
35
35
  }