@kokiito0926/superhacker 0.0.3 → 0.0.4
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/index.js +51 -17
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -11,8 +11,17 @@ const BASE_URL = "https://hacker-news.firebaseio.com/v0";
|
|
|
11
11
|
|
|
12
12
|
async function getItem(id) {
|
|
13
13
|
if (!id) return null;
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
try {
|
|
15
|
+
const res = await fetch(`${BASE_URL}/item/${id}.json`);
|
|
16
|
+
if (!res.ok) {
|
|
17
|
+
console.error(`Error fetching item ${id}: ${res.statusText}`);
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
return await res.json();
|
|
21
|
+
} catch (error) {
|
|
22
|
+
console.error(`Error fetching item ${id}: ${error.message}`);
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
16
25
|
}
|
|
17
26
|
|
|
18
27
|
async function getCommentsRecursive(ids, allComments = []) {
|
|
@@ -32,27 +41,42 @@ async function getCommentsRecursive(ids, allComments = []) {
|
|
|
32
41
|
}
|
|
33
42
|
|
|
34
43
|
function buildTree(list, parentId) {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
.
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
44
|
+
const map = new Map();
|
|
45
|
+
for (const item of list) {
|
|
46
|
+
map.set(item.id, { ...item, replies: [] });
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const tree = [];
|
|
50
|
+
for (const item of list) {
|
|
51
|
+
if (item.parent === parentId) {
|
|
52
|
+
tree.push(map.get(item.id));
|
|
53
|
+
} else {
|
|
54
|
+
const parent = map.get(item.parent);
|
|
55
|
+
if (parent) {
|
|
56
|
+
parent.replies.push(map.get(item.id));
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return tree;
|
|
41
61
|
}
|
|
42
62
|
|
|
43
63
|
const command = argv._[0];
|
|
44
64
|
if (!command) {
|
|
45
|
-
console.error(`Error: Command is required.`);
|
|
65
|
+
console.error(`Error: Command is required (list, comment, comments).`);
|
|
46
66
|
process.exit(1);
|
|
47
67
|
}
|
|
48
68
|
// console.log(command);
|
|
49
69
|
|
|
50
|
-
const id = argv?.id;
|
|
70
|
+
const id = argv?.id ? parseInt(argv.id) : null;
|
|
51
71
|
const limit = argv?.limit ? parseInt(argv?.limit) : null;
|
|
52
72
|
const flat = argv?.format ? argv?.format === "flat" : false;
|
|
53
73
|
|
|
54
74
|
if (command === "list") {
|
|
55
75
|
const idsResponse = await fetch(`${BASE_URL}/topstories.json`);
|
|
76
|
+
if (!idsResponse.ok) {
|
|
77
|
+
console.error(`Error fetching top stories: ${idsResponse.statusText}`);
|
|
78
|
+
process.exit(1);
|
|
79
|
+
}
|
|
56
80
|
let ids = await idsResponse.json();
|
|
57
81
|
|
|
58
82
|
if (limit > 0) {
|
|
@@ -60,26 +84,32 @@ if (command === "list") {
|
|
|
60
84
|
}
|
|
61
85
|
|
|
62
86
|
const stories = await Promise.all(ids.map((id) => getItem(id)));
|
|
63
|
-
const sortedStories = stories
|
|
87
|
+
const sortedStories = stories
|
|
88
|
+
.filter((s) => s !== null)
|
|
89
|
+
.sort((a, b) => (b.score || 0) - (a.score || 0));
|
|
64
90
|
|
|
65
91
|
console.log(JSON.stringify(sortedStories, null, 2));
|
|
66
|
-
} else if (command === "comment") {
|
|
92
|
+
} else if (command === "comment" || command === "item") {
|
|
67
93
|
if (!id) {
|
|
68
|
-
console.error("Error: ID is required via --id
|
|
94
|
+
console.error("Error: ID is required via --id.");
|
|
69
95
|
process.exit(1);
|
|
70
96
|
}
|
|
71
97
|
const item = await getItem(id);
|
|
98
|
+
if (!item) {
|
|
99
|
+
console.error(`Error: Item ${id} not found.`);
|
|
100
|
+
process.exit(1);
|
|
101
|
+
}
|
|
72
102
|
console.log(JSON.stringify(item, null, 2));
|
|
73
103
|
} else if (command === "comments") {
|
|
74
104
|
if (!id) {
|
|
75
|
-
console.error("Error: Story ID is required.");
|
|
105
|
+
console.error("Error: Story/Comment ID is required via --id.");
|
|
76
106
|
process.exit(1);
|
|
77
107
|
}
|
|
78
108
|
|
|
79
109
|
const rootItem = await getItem(id);
|
|
80
110
|
if (!rootItem) {
|
|
81
|
-
console.
|
|
82
|
-
process.exit(
|
|
111
|
+
console.error(`Error: Root item ${id} not found.`);
|
|
112
|
+
process.exit(1);
|
|
83
113
|
}
|
|
84
114
|
|
|
85
115
|
const flatComments = rootItem.kids ? await getCommentsRecursive(rootItem.kids) : [];
|
|
@@ -88,15 +118,19 @@ if (command === "list") {
|
|
|
88
118
|
if (flat) {
|
|
89
119
|
console.log(JSON.stringify([rootItem, ...flatComments], null, 2));
|
|
90
120
|
} else {
|
|
121
|
+
const tree = buildTree(flatComments, id);
|
|
91
122
|
console.log(
|
|
92
123
|
JSON.stringify(
|
|
93
124
|
{
|
|
94
125
|
...rootItem,
|
|
95
|
-
replies:
|
|
126
|
+
replies: tree,
|
|
96
127
|
},
|
|
97
128
|
null,
|
|
98
129
|
2,
|
|
99
130
|
),
|
|
100
131
|
);
|
|
101
132
|
}
|
|
133
|
+
} else {
|
|
134
|
+
console.error(`Error: Unknown command "${command}". Available commands: list, comment, comments.`);
|
|
135
|
+
process.exit(1);
|
|
102
136
|
}
|