koishi-plugin-xhs-parser 0.1.0 → 0.1.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/lib/parser.js CHANGED
@@ -207,8 +207,17 @@ async function fetchWithTimeout(url, config, init) {
207
207
  clearTimeout(timer);
208
208
  }
209
209
  }
210
+ function sanitizeJsonPayload(payload) {
211
+ // The XHS __INITIAL_STATE__ is JavaScript, not JSON — it may contain
212
+ // literal undefined / NaN / Infinity which are not valid JSON tokens.
213
+ // Replace value-positions of these literals with null so JSON.parse succeeds.
214
+ return payload
215
+ .replace(/(?<=[:\[,{]\s*)undefined(?=\s*[,\]}\n])/g, 'null')
216
+ .replace(/(?<=[:\[,{]\s*)NaN(?=\s*[,\]}\n])/g, 'null')
217
+ .replace(/(?<=[:\[,{]\s*)Infinity(?=\s*[,\]}\n])/g, 'null');
218
+ }
210
219
  function parseLooseObject(payload) {
211
- return JSON.parse(payload);
220
+ return JSON.parse(sanitizeJsonPayload(payload));
212
221
  }
213
222
  function getFirstNoteFromDetailMap(map) {
214
223
  if (!map || typeof map !== 'object')
@@ -235,16 +244,22 @@ function buildNote(data, url, config) {
235
244
  videoUrls: extractVideoUrls(data),
236
245
  };
237
246
  }
247
+
248
+ const mobileLine = `------------------------------------`
249
+
238
250
  function formatNoteText(note, config) {
239
251
  const lines = [
240
- `小红书:${note.title}`,
241
- `作者:${note.authorName}`,
252
+ `📕: ${note.title}`,
253
+ `👤: ${note.authorName}`,
254
+ mobileLine,
242
255
  ];
243
256
  if (note.desc && config.maxDescLength > 0) {
244
257
  lines.push(trimText(note.desc, config.maxDescLength, config.descTruncateSuffix));
258
+ lines.push(mobileLine);
245
259
  }
246
260
  if (config.showStats) {
247
- lines.push(`点赞:${displayCount(note.likedCount)} 收藏:${displayCount(note.collectedCount)} 评论:${displayCount(note.commentCount)} 分享:${displayCount(note.shareCount)}`);
261
+ lines.push(`👍: ${displayCount(note.likedCount)} | 🌟: ${displayCount(note.collectedCount)} | 💬: ${displayCount(note.commentCount)} | 📤: ${displayCount(note.shareCount)}`);
262
+ lines.push(mobileLine);
248
263
  }
249
264
  if (config.showLink)
250
265
  lines.push(note.url);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "koishi-plugin-xhs-parser",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "Parse Xiaohongshu links and cards for Koishi.",
5
5
  "main": "lib/index.js",
6
6
  "typings": "lib/index.d.ts",
package/src/parser.ts CHANGED
@@ -255,8 +255,18 @@ async function fetchWithTimeout(url: string, config: XhsConfigLike, init: Reques
255
255
  }
256
256
  }
257
257
 
258
+ function sanitizeJsonPayload(payload: string): string {
259
+ // The XHS __INITIAL_STATE__ is JavaScript, not JSON — it may contain
260
+ // literal undefined / NaN / Infinity which are not valid JSON tokens.
261
+ // Replace value-positions of these literals with null so JSON.parse succeeds.
262
+ return payload
263
+ .replace(/(?<=[:\[,{]\s*)undefined(?=\s*[,\]}\n])/g, 'null')
264
+ .replace(/(?<=[:\[,{]\s*)NaN(?=\s*[,\]}\n])/g, 'null')
265
+ .replace(/(?<=[:\[,{]\s*)Infinity(?=\s*[,\]}\n])/g, 'null')
266
+ }
267
+
258
268
  function parseLooseObject(payload: string) {
259
- return JSON.parse(payload)
269
+ return JSON.parse(sanitizeJsonPayload(payload))
260
270
  }
261
271
 
262
272
  function getFirstNoteFromDetailMap(map: unknown) {