open-nami 1.2.8 → 1.3.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/dist/cli.js +79 -34
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -9,7 +9,7 @@ var require_package = __commonJS({
|
|
|
9
9
|
"package.json"(exports, module) {
|
|
10
10
|
module.exports = {
|
|
11
11
|
name: "open-nami",
|
|
12
|
-
version: "1.
|
|
12
|
+
version: "1.3.0",
|
|
13
13
|
description: "Open Nami: terminal-first bulk social media profile downloader for Instagram, TikTok, Facebook & X.",
|
|
14
14
|
type: "module",
|
|
15
15
|
bin: {
|
|
@@ -4368,32 +4368,55 @@ async function dispatchDownload(options) {
|
|
|
4368
4368
|
}
|
|
4369
4369
|
|
|
4370
4370
|
// src/components/views/picking-view.tsx
|
|
4371
|
-
import { jsx as jsx8, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
4371
|
+
import { Fragment as Fragment2, jsx as jsx8, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
4372
4372
|
function ChoiceIndicator({ isSelected }) {
|
|
4373
4373
|
const theme = useTheme();
|
|
4374
|
-
return /* @__PURE__ */
|
|
4374
|
+
return /* @__PURE__ */ jsxs6(Box6, { children: [
|
|
4375
|
+
/* @__PURE__ */ jsx8(Text7, { color: theme.primary, children: "\u258E " }),
|
|
4376
|
+
/* @__PURE__ */ jsx8(Text7, { color: theme.primary, bold: true, children: isSelected ? "\u276F " : " " })
|
|
4377
|
+
] });
|
|
4375
4378
|
}
|
|
4376
|
-
function ChoiceItem({
|
|
4379
|
+
function ChoiceItem({
|
|
4380
|
+
isSelected,
|
|
4381
|
+
label,
|
|
4382
|
+
value,
|
|
4383
|
+
description
|
|
4384
|
+
}) {
|
|
4377
4385
|
const theme = useTheme();
|
|
4378
|
-
|
|
4386
|
+
const rawTag = `[${value === "all" ? "EVERYTHING" : String(value || label).toUpperCase()}]`;
|
|
4387
|
+
const paddedTag = rawTag.padEnd(12, " ");
|
|
4388
|
+
return /* @__PURE__ */ jsxs6(Box6, { children: [
|
|
4389
|
+
/* @__PURE__ */ jsx8(
|
|
4390
|
+
Text7,
|
|
4391
|
+
{
|
|
4392
|
+
color: isSelected ? theme.background : theme.primary,
|
|
4393
|
+
backgroundColor: isSelected ? theme.primary : void 0,
|
|
4394
|
+
bold: isSelected,
|
|
4395
|
+
children: paddedTag
|
|
4396
|
+
}
|
|
4397
|
+
),
|
|
4398
|
+
/* @__PURE__ */ jsx8(Text7, { color: theme.gray, children: " " }),
|
|
4399
|
+
/* @__PURE__ */ jsx8(Text7, { color: isSelected ? theme.primary : theme.gray, dimColor: !isSelected, bold: isSelected, children: description || label })
|
|
4400
|
+
] });
|
|
4379
4401
|
}
|
|
4380
4402
|
function getPickingOptions(platform) {
|
|
4381
4403
|
const items = [
|
|
4382
|
-
{ label: "Photos", value: "photos" },
|
|
4383
|
-
{ label: "Videos", value: "videos" }
|
|
4404
|
+
{ label: "Photos", value: "photos", description: "Feed images and carousels" },
|
|
4405
|
+
{ label: "Videos", value: "videos", description: "Reels and timeline clips" }
|
|
4384
4406
|
];
|
|
4385
4407
|
if (platform === "instagram") {
|
|
4386
|
-
items.push({ label: "Stories", value: "stories" });
|
|
4387
|
-
items.push({ label: "Highlights", value: "highlights" });
|
|
4408
|
+
items.push({ label: "Stories", value: "stories", description: "Active 24h stories" });
|
|
4409
|
+
items.push({ label: "Highlights", value: "highlights", description: "Saved story archive reels" });
|
|
4388
4410
|
}
|
|
4389
4411
|
items.push({
|
|
4390
4412
|
label: "Everything",
|
|
4391
|
-
value: "all"
|
|
4413
|
+
value: "all",
|
|
4414
|
+
description: "Complete profile download"
|
|
4392
4415
|
});
|
|
4393
4416
|
return items;
|
|
4394
4417
|
}
|
|
4395
4418
|
function PickingView({
|
|
4396
|
-
contentWidth,
|
|
4419
|
+
contentWidth: _contentWidth,
|
|
4397
4420
|
profile,
|
|
4398
4421
|
outputDir,
|
|
4399
4422
|
initialLimit,
|
|
@@ -4404,7 +4427,7 @@ function PickingView({
|
|
|
4404
4427
|
onSelect,
|
|
4405
4428
|
onHighlight,
|
|
4406
4429
|
theme,
|
|
4407
|
-
gapComponent:
|
|
4430
|
+
gapComponent: _Gap
|
|
4408
4431
|
}) {
|
|
4409
4432
|
const platformName = profile.platform.charAt(0).toUpperCase() + profile.platform.slice(1);
|
|
4410
4433
|
const items = getPickingOptions(profile.platform);
|
|
@@ -4432,23 +4455,26 @@ function PickingView({
|
|
|
4432
4455
|
resume: initialResume
|
|
4433
4456
|
});
|
|
4434
4457
|
};
|
|
4435
|
-
return /* @__PURE__ */ jsxs6(Box6, { width:
|
|
4436
|
-
/* @__PURE__ */ jsxs6(Box6, {
|
|
4458
|
+
return /* @__PURE__ */ jsx8(Box6, { flexDirection: "column", alignItems: "center", width: "100%", children: /* @__PURE__ */ jsxs6(Box6, { flexDirection: "column", width: 56, children: [
|
|
4459
|
+
/* @__PURE__ */ jsxs6(Box6, { children: [
|
|
4460
|
+
/* @__PURE__ */ jsx8(Text7, { color: theme.primary, children: "\u258E " }),
|
|
4437
4461
|
/* @__PURE__ */ jsxs6(Text7, { bold: true, color: theme.primary, children: [
|
|
4438
4462
|
"@",
|
|
4439
4463
|
profile.username
|
|
4440
4464
|
] }),
|
|
4441
|
-
/* @__PURE__ */ jsx8(
|
|
4442
|
-
|
|
4443
|
-
|
|
4444
|
-
|
|
4445
|
-
|
|
4446
|
-
|
|
4447
|
-
|
|
4448
|
-
|
|
4449
|
-
|
|
4465
|
+
/* @__PURE__ */ jsx8(Text7, { color: theme.gray, dimColor: theme.dimSecondary, children: ` \xB7 ${platformName}` })
|
|
4466
|
+
] }),
|
|
4467
|
+
profile.cleanUrl ? /* @__PURE__ */ jsxs6(Box6, { children: [
|
|
4468
|
+
/* @__PURE__ */ jsx8(Text7, { color: theme.primary, children: "\u258E " }),
|
|
4469
|
+
/* @__PURE__ */ jsx8(Text7, { color: theme.gray, dimColor: theme.dimSecondary, children: profile.cleanUrl })
|
|
4470
|
+
] }) : null,
|
|
4471
|
+
/* @__PURE__ */ jsx8(Box6, { children: /* @__PURE__ */ jsx8(Text7, { color: theme.primary, children: "\u258E" }) }),
|
|
4472
|
+
/* @__PURE__ */ jsxs6(Box6, { children: [
|
|
4473
|
+
/* @__PURE__ */ jsx8(Text7, { color: theme.primary, children: "\u258E " }),
|
|
4474
|
+
/* @__PURE__ */ jsx8(Text7, { color: theme.gray, dimColor: theme.dimSecondary, children: "Select target media:" })
|
|
4450
4475
|
] }),
|
|
4451
|
-
/* @__PURE__ */ jsx8(
|
|
4476
|
+
/* @__PURE__ */ jsx8(Box6, { children: /* @__PURE__ */ jsx8(Text7, { color: theme.primary, children: "\u258E" }) }),
|
|
4477
|
+
/* @__PURE__ */ jsx8(
|
|
4452
4478
|
SelectInput,
|
|
4453
4479
|
{
|
|
4454
4480
|
indicatorComponent: ChoiceIndicator,
|
|
@@ -4456,13 +4482,21 @@ function PickingView({
|
|
|
4456
4482
|
items: items.map((item, index) => ({
|
|
4457
4483
|
key: String(index),
|
|
4458
4484
|
label: item.label,
|
|
4459
|
-
value: item.value
|
|
4485
|
+
value: item.value,
|
|
4486
|
+
description: item.description
|
|
4460
4487
|
})),
|
|
4461
4488
|
onSelect: (item) => handleItemSelect(item.value),
|
|
4462
4489
|
onHighlight: (item) => onHighlight?.(item.value)
|
|
4463
4490
|
}
|
|
4464
|
-
)
|
|
4465
|
-
|
|
4491
|
+
),
|
|
4492
|
+
hasCheckpoint ? /* @__PURE__ */ jsxs6(Fragment2, { children: [
|
|
4493
|
+
/* @__PURE__ */ jsx8(Box6, { children: /* @__PURE__ */ jsx8(Text7, { color: theme.primary, children: "\u258E" }) }),
|
|
4494
|
+
/* @__PURE__ */ jsxs6(Box6, { children: [
|
|
4495
|
+
/* @__PURE__ */ jsx8(Text7, { color: theme.primary, children: "\u258E " }),
|
|
4496
|
+
/* @__PURE__ */ jsx8(Text7, { color: theme.primary, bold: true, children: "\u26A1 Checkpoint found (cursor saved)" })
|
|
4497
|
+
] })
|
|
4498
|
+
] }) : null
|
|
4499
|
+
] }) });
|
|
4466
4500
|
}
|
|
4467
4501
|
|
|
4468
4502
|
// src/components/views/platform-view.tsx
|
|
@@ -4673,7 +4707,7 @@ function DownloadingView({
|
|
|
4673
4707
|
// src/components/views/completion-view.tsx
|
|
4674
4708
|
import os7 from "os";
|
|
4675
4709
|
import { Box as Box10, Text as Text12 } from "ink";
|
|
4676
|
-
import { Fragment as
|
|
4710
|
+
import { Fragment as Fragment3, jsx as jsx13, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
4677
4711
|
var DONE_LABEL = "\u21B5 download another";
|
|
4678
4712
|
function CompletionView({
|
|
4679
4713
|
profile,
|
|
@@ -4685,10 +4719,10 @@ function CompletionView({
|
|
|
4685
4719
|
const plural = result.downloadedCount === 1 ? "" : "s";
|
|
4686
4720
|
const skipText = result.skippedCount > 0 ? ` (${result.skippedCount} archived)` : "";
|
|
4687
4721
|
return /* @__PURE__ */ jsxs10(Box10, { flexDirection: "column", alignItems: "center", children: [
|
|
4688
|
-
/* @__PURE__ */ jsx13(Text12, { children: isZero ? /* @__PURE__ */ jsxs10(
|
|
4722
|
+
/* @__PURE__ */ jsx13(Text12, { children: isZero ? /* @__PURE__ */ jsxs10(Fragment3, { children: [
|
|
4689
4723
|
/* @__PURE__ */ jsx13(Text12, { bold: true, color: theme.primary, children: "\u2713 profile scanned " }),
|
|
4690
4724
|
/* @__PURE__ */ jsx13(Text12, { color: theme.primary, children: "\u2014 0 media items found" })
|
|
4691
|
-
] }) : /* @__PURE__ */ jsxs10(
|
|
4725
|
+
] }) : /* @__PURE__ */ jsxs10(Fragment3, { children: [
|
|
4692
4726
|
/* @__PURE__ */ jsx13(Text12, { bold: true, color: theme.primary, children: "\u2713 profile downloaded! " }),
|
|
4693
4727
|
/* @__PURE__ */ jsx13(Text12, { color: theme.primary, children: "saved to:" })
|
|
4694
4728
|
] }) }),
|
|
@@ -5701,7 +5735,7 @@ async function runBatchQueue(options) {
|
|
|
5701
5735
|
}
|
|
5702
5736
|
|
|
5703
5737
|
// src/components/views/batch-view.tsx
|
|
5704
|
-
import { Fragment as
|
|
5738
|
+
import { Fragment as Fragment4, jsx as jsx17, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
5705
5739
|
var PLATFORMS = ["instagram", "tiktok", "facebook", "x"];
|
|
5706
5740
|
var CHOICES2 = ["all", "photos", "videos", "stories", "highlights"];
|
|
5707
5741
|
var DATE_PRESETS = ["all", "24h", "7d", "30d", "2024", "2023", "2022", "2021", "custom"];
|
|
@@ -6408,7 +6442,7 @@ function BatchView({
|
|
|
6408
6442
|
}
|
|
6409
6443
|
) }),
|
|
6410
6444
|
/* @__PURE__ */ jsx17(Text16, { color: theme.gray, dimColor: theme.dimSecondary, children: "\u21B5 confirm \xB7 esc cancel" })
|
|
6411
|
-
] }) : /* @__PURE__ */ jsxs14(
|
|
6445
|
+
] }) : /* @__PURE__ */ jsxs14(Fragment4, { children: [
|
|
6412
6446
|
/* @__PURE__ */ jsxs14(Box14, { justifyContent: "space-between", width: "100%", children: [
|
|
6413
6447
|
/* @__PURE__ */ jsxs14(Box14, { width: colWidth, children: [
|
|
6414
6448
|
/* @__PURE__ */ jsx17(Text16, { color: theme.gray, dimColor: theme.dimSecondary, children: "[p] Platform: " }),
|
|
@@ -6620,7 +6654,7 @@ function frameRowSpan(row) {
|
|
|
6620
6654
|
}
|
|
6621
6655
|
|
|
6622
6656
|
// src/app.tsx
|
|
6623
|
-
import { Fragment as
|
|
6657
|
+
import { Fragment as Fragment5, jsx as jsx18, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
6624
6658
|
var TAGLINE = "grab any profile. paste. download. done.";
|
|
6625
6659
|
var DOWNLOAD_BUTTON = "download";
|
|
6626
6660
|
var Gap = ({ lines = 1 }) => /* @__PURE__ */ jsx18(Box15, { flexDirection: "column", flexShrink: 0, children: Array.from({ length: lines }, (_, i) => /* @__PURE__ */ jsx18(Text17, { children: " " }, i)) });
|
|
@@ -7001,6 +7035,17 @@ function InnerApp({
|
|
|
7001
7035
|
match: item.label,
|
|
7002
7036
|
action: () => handleModeSelect(item.value, phase.profile)
|
|
7003
7037
|
});
|
|
7038
|
+
const tag = `[${item.value === "all" ? "EVERYTHING" : item.value.toUpperCase()}]`;
|
|
7039
|
+
targets.push({
|
|
7040
|
+
match: tag,
|
|
7041
|
+
action: () => handleModeSelect(item.value, phase.profile)
|
|
7042
|
+
});
|
|
7043
|
+
if (item.description) {
|
|
7044
|
+
targets.push({
|
|
7045
|
+
match: item.description,
|
|
7046
|
+
action: () => handleModeSelect(item.value, phase.profile)
|
|
7047
|
+
});
|
|
7048
|
+
}
|
|
7004
7049
|
}
|
|
7005
7050
|
}
|
|
7006
7051
|
if (phase.name === "done") {
|
|
@@ -7184,7 +7229,7 @@ function InnerApp({
|
|
|
7184
7229
|
onRegisterClickTargets: setBatchClickTargets
|
|
7185
7230
|
}
|
|
7186
7231
|
),
|
|
7187
|
-
hints.length > 0 ? /* @__PURE__ */ jsxs15(
|
|
7232
|
+
hints.length > 0 ? /* @__PURE__ */ jsxs15(Fragment5, { children: [
|
|
7188
7233
|
/* @__PURE__ */ jsx18(Gap, { lines: 2 }),
|
|
7189
7234
|
/* @__PURE__ */ jsx18(
|
|
7190
7235
|
Shortcuts,
|