fix: integrate community bugfixes for PRs 1, 4, 6 and Issue 7

- Fix zhihu id truncation issue beyond safe integer
- Add json filter to template engine
- Escape evaluate args in browser scripts using json filter
- Resolve module not found bug for index.ts

Co-authored-by: 袁鑫 <eric.yuanxin@gmail.com>
Co-authored-by: zhenxing jiang <jiangzhx@gmail.com>
Co-authored-by: wangruotian <wangruotian@meituan.com>
Co-authored-by: 滕文证 <83223457+tenwz@users.noreply.github.com>
This commit is contained in:
committed 2026-03-15 15:43:33 +08:00
1 parent 829172fc59
commit 71f2f3d6e6
5 files changed
+21 -6

No files matched your search

+3 -2
View File
@@ -18,9 +18,10 @@ pipeline:
- evaluate: |
(async () => {
const sub = '${{ args.subreddit }}';
const sub = ${{ args.subreddit | json }};
const path = sub ? '/r/' + sub + '/hot.json' : '/hot.json';
const res = await fetch(path + '?limit=${{ args.limit }}&raw_json=1', {
const limit = ${{ args.limit }};
const res = await fetch(path + '?limit=' + limit + '&raw_json=1', {
credentials: 'include'
});
const d = await res.json();
+6 -2
View File
@@ -17,12 +17,16 @@ pipeline:
const res = await fetch('https://www.zhihu.com/api/v3/feed/topstory/hot-lists/total?limit=50', {
credentials: 'include'
});
const d = await res.json();
const text = await res.text();
const d = JSON.parse(
text.replace(/("id"\s*:\s*)(\d{16,})/g, '$1"$2"')
);
return (d?.data || []).map((item) => {
const t = item.target || {};
const questionId = t.id == null ? '' : String(t.id);
return {
title: t.title,
url: 'https://www.zhihu.com/question/' + t.id,
url: 'https://www.zhihu.com/question/' + questionId,
answer_count: t.answer_count,
follower_count: t.follower_count,
heat: item.detail_text || '',
+3 -1
View File
@@ -19,7 +19,9 @@ pipeline:
- evaluate: |
(async () => {
const strip = (html) => (html || '').replace(/<[^>]+>/g, '').replace(/&nbsp;/g, ' ').replace(/&lt;/g, '<').replace(/&gt;/g, '>').replace(/&amp;/g, '&').replace(/<em>/g, '').replace(/<\/em>/g, '').trim();
const res = await fetch('https://www.zhihu.com/api/v4/search_v3?q=' + encodeURIComponent('${{ args.keyword }}') + '&t=general&offset=0&limit=${{ args.limit }}', {
const keyword = ${{ args.keyword | json }};
const limit = ${{ args.limit }};
const res = await fetch('https://www.zhihu.com/api/v4/search_v3?q=' + encodeURIComponent(keyword) + '&t=general&offset=0&limit=' + limit, {
credentials: 'include'
});
const d = await res.json();
+6
View File
@@ -75,6 +75,12 @@ describe('evalExpr', () => {
it('applies length filter', () => {
expect(evalExpr('item.items | length', { item: { items: [1, 2, 3] } })).toBe(3);
});
it('applies json filter to strings with quotes', () => {
expect(evalExpr('args.keyword | json', { args: { keyword: "O'Reilly" } })).toBe('"O\'Reilly"');
});
it('applies json filter to nullish values', () => {
expect(evalExpr('args.keyword | json', { args: {} })).toBe('null');
});
});
describe('render', () => {
+3 -1
View File
@@ -75,7 +75,7 @@ export function evalExpr(expr: string, ctx: RenderContext): any {
* Apply a named filter to a value.
* Supported filters:
* default(val), join(sep), upper, lower, truncate(n), trim,
* replace(old,new), keys, length, first, last
* replace(old,new), keys, length, first, last, json
*/
function applyFilter(filterExpr: string, value: any): any {
const match = filterExpr.match(/^(\w+)(?:\((.+)\))?$/);
@@ -117,6 +117,8 @@ function applyFilter(filterExpr: string, value: any): any {
return Array.isArray(value) ? value[0] : value;
case 'last':
return Array.isArray(value) ? value[value.length - 1] : value;
case 'json':
return JSON.stringify(value ?? null);
default:
return value;
}