Skip to content

Commit 86ecb0f

Browse files
committed
Merge branch 'main' of github.com:GitbookIO/gitbook into utku/rnd-8664-spaces-with-undefined-language-are-not-included-in-search
2 parents 0b26c40 + e0ace99 commit 86ecb0f

File tree

33 files changed

+479
-89
lines changed

33 files changed

+479
-89
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"gitbook": minor
3+
---
4+
5+
Add a RSS feed to all pages with update blocks.

.github/actions/gradual-deploy-cloudflare/action.yaml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ runs:
3030
apiToken: ${{ inputs.apiToken }}
3131
accountId: ${{ inputs.accountId }}
3232
workingDirectory: ./
33-
wranglerVersion: '4.10.0'
33+
wranglerVersion: '4.43.0'
3434
environment: ${{ inputs.environment }}
3535
command: deployments status --config ./packages/gitbook/openNext/customWorkers/defaultWrangler.jsonc
3636

@@ -49,7 +49,7 @@ runs:
4949
apiToken: ${{ inputs.apiToken }}
5050
accountId: ${{ inputs.accountId }}
5151
workingDirectory: ./
52-
wranglerVersion: '4.10.0'
52+
wranglerVersion: '4.43.0'
5353
environment: ${{ inputs.environment }}
5454
command: versions deploy ${{ steps.extract_current_version.outputs.version_id }}@100% ${{ inputs.serverVersionId }}@0% -y --config ./packages/gitbook/openNext/customWorkers/defaultWrangler.jsonc
5555

@@ -61,7 +61,7 @@ runs:
6161
apiToken: ${{ inputs.apiToken }}
6262
accountId: ${{ inputs.accountId }}
6363
workingDirectory: ./
64-
wranglerVersion: '4.10.0'
64+
wranglerVersion: '4.43.0'
6565
environment: ${{ inputs.environment }}
6666
command: versions deploy ${{ inputs.middlewareVersionId }}@100% -y --config ./packages/gitbook/openNext/customWorkers/middlewareWrangler.jsonc
6767

@@ -71,7 +71,7 @@ runs:
7171
apiToken: ${{ inputs.apiToken }}
7272
accountId: ${{ inputs.accountId }}
7373
workingDirectory: ./
74-
wranglerVersion: '4.10.0'
74+
wranglerVersion: '4.43.0'
7575
environment: ${{ inputs.environment }}
7676
command: versions deploy ${{ inputs.serverVersionId }}@100% -y --config ./packages/gitbook/openNext/customWorkers/defaultWrangler.jsonc
7777

.github/composite/deploy-cloudflare/action.yaml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ runs:
7070
apiToken: ${{ inputs.apiToken }}
7171
accountId: ${{ inputs.accountId }}
7272
workingDirectory: ./
73-
wranglerVersion: '4.10.0'
73+
wranglerVersion: '4.43.0'
7474
environment: ${{ inputs.environment }}
7575
command: deploy --config ./packages/gitbook/openNext/customWorkers/doWrangler.jsonc
7676

@@ -81,7 +81,7 @@ runs:
8181
apiToken: ${{ inputs.apiToken }}
8282
accountId: ${{ inputs.accountId }}
8383
workingDirectory: ./
84-
wranglerVersion: '4.10.0'
84+
wranglerVersion: '4.43.0'
8585
environment: ${{ inputs.environment }}
8686
command: ${{ format('versions upload --tag {0} --message "{1}"', inputs.commitTag, inputs.commitMessage) }} --config ./packages/gitbook/openNext/customWorkers/defaultWrangler.jsonc
8787

@@ -104,7 +104,7 @@ runs:
104104
apiToken: ${{ inputs.apiToken }}
105105
accountId: ${{ inputs.accountId }}
106106
workingDirectory: ./
107-
wranglerVersion: '4.10.0'
107+
wranglerVersion: '4.43.0'
108108
environment: ${{ inputs.environment }}
109109
command: ${{ format('versions upload --tag {0} --message "{1}"', inputs.commitTag, inputs.commitMessage) }} --config ./packages/gitbook/openNext/customWorkers/middlewareWrangler.jsonc
110110

bun.lock

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,7 @@
143143
"classnames": "catalog:",
144144
"direction": "^2.0.1",
145145
"event-iterator": "^2.0.0",
146+
"feed": "^5.1.0",
146147
"image-size": "^2.0.2",
147148
"js-cookie": "^3.0.5",
148149
"jsontoxml": "^1.0.1",
@@ -206,6 +207,7 @@
206207
"env-cmd": "^10.1.0",
207208
"jsonwebtoken": "^9.0.2",
208209
"postcss": "^8",
210+
"rss-parser": "^3.13.0",
209211
"stylelint": "^16.16.0",
210212
"tailwindcss": "^4.1.11",
211213
"ts-essentials": "^10.0.1",
@@ -1905,7 +1907,7 @@
19051907

19061908
"enquirer": ["enquirer@2.4.1", "", { "dependencies": { "ansi-colors": "^4.1.1", "strip-ansi": "^6.0.1" } }, "sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ=="],
19071909

1908-
"entities": ["entities@6.0.1", "", {}, "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g=="],
1910+
"entities": ["entities@2.2.0", "", {}, "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A=="],
19091911

19101912
"env-cmd": ["env-cmd@10.1.0", "", { "dependencies": { "commander": "^4.0.0", "cross-spawn": "^7.0.0" }, "bin": { "env-cmd": "bin/env-cmd.js" } }, "sha512-mMdWTT9XKN7yNth/6N6g2GuKuJTsKMDHlQFUDacb/heQRRWOTIZ42t1rMHnQu4jYxU1ajdTeJM+9eEETlqToMA=="],
19111913

@@ -2003,6 +2005,8 @@
20032005

20042006
"fdir": ["fdir@6.5.0", "", { "peerDependencies": { "picomatch": "^3 || ^4" }, "optionalPeers": ["picomatch"] }, "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg=="],
20052007

2008+
"feed": ["feed@5.1.0", "", { "dependencies": { "xml-js": "^1.6.11" } }, "sha512-qGNhgYygnefSkAHHrNHqC7p3R8J0/xQDS/cYUud8er/qD9EFGWyCdUDfULHTJQN1d3H3WprzVwMc9MfB4J50Wg=="],
2009+
20062010
"file-entry-cache": ["file-entry-cache@10.0.7", "", { "dependencies": { "flat-cache": "^6.1.7" } }, "sha512-txsf5fu3anp2ff3+gOJJzRImtrtm/oa9tYLN0iTuINZ++EyVR/nRrg2fKYwvG/pXDofcrvvb0scEbX3NyW/COw=="],
20072011

20082012
"file-uri-to-path": ["file-uri-to-path@1.0.0", "", {}, "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw=="],
@@ -2733,12 +2737,16 @@
27332737

27342738
"router": ["router@2.0.0", "", { "dependencies": { "array-flatten": "3.0.0", "is-promise": "4.0.0", "methods": "~1.1.2", "parseurl": "~1.3.3", "path-to-regexp": "^8.0.0", "setprototypeof": "1.2.0", "utils-merge": "1.0.1" } }, "sha512-dIM5zVoG8xhC6rnSN8uoAgFARwTE7BQs8YwHEvK0VCmfxQXMaOuA1uiR1IPwsW7JyK5iTt7Od/TC9StasS2NPQ=="],
27352739

2740+
"rss-parser": ["rss-parser@3.13.0", "", { "dependencies": { "entities": "^2.0.3", "xml2js": "^0.5.0" } }, "sha512-7jWUBV5yGN3rqMMj7CZufl/291QAhvrrGpDNE4k/02ZchL0npisiYYqULF71jCEKoIiHvK/Q2e6IkDwPziT7+w=="],
2741+
27362742
"run-parallel": ["run-parallel@1.2.0", "", { "dependencies": { "queue-microtask": "^1.2.2" } }, "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA=="],
27372743

27382744
"safe-buffer": ["safe-buffer@5.2.1", "", {}, "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="],
27392745

27402746
"safer-buffer": ["safer-buffer@2.1.2", "", {}, "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="],
27412747

2748+
"sax": ["sax@1.4.3", "", {}, "sha512-yqYn1JhPczigF94DMS+shiDMjDowYO6y9+wB/4WgO0Y19jWYk0lQ4tuG5KI7kj4FTp1wxPj5IFfcrz/s1c3jjQ=="],
2749+
27422750
"scheduler": ["scheduler@0.26.0", "", {}, "sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA=="],
27432751

27442752
"secure-json-parse": ["secure-json-parse@2.7.0", "", {}, "sha512-6aU+Rwsezw7VR8/nyvKTx8QpWH9FrcYiXXlqC4z5d5XQBDRqtbfsRjnwGyqbi3gddNtWHuEk9OANUotL26qKUw=="],
@@ -3027,6 +3035,12 @@
30273035

30283036
"xdg-portable": ["xdg-portable@7.3.0", "", { "dependencies": { "os-paths": "^4.0.1" } }, "sha512-sqMMuL1rc0FmMBOzCpd0yuy9trqF2yTTVe+E9ogwCSWQCdDEtQUwrZPT6AxqtsFGRNxycgncbP/xmOOSPw5ZUw=="],
30293037

3038+
"xml-js": ["xml-js@1.6.11", "", { "dependencies": { "sax": "^1.2.4" }, "bin": { "xml-js": "./bin/cli.js" } }, "sha512-7rVi2KMfwfWFl+GpPg6m80IVMWXLRjO+PxTq7V2CDhoGak0wzYzFgUY2m4XJ47OGdXd8eLE8EmwfAmdjw7lC1g=="],
3039+
3040+
"xml2js": ["xml2js@0.5.0", "", { "dependencies": { "sax": ">=0.6.0", "xmlbuilder": "~11.0.0" } }, "sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA=="],
3041+
3042+
"xmlbuilder": ["xmlbuilder@11.0.1", "", {}, "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA=="],
3043+
30303044
"xxhash-wasm": ["xxhash-wasm@1.1.0", "", {}, "sha512-147y/6YNh+tlp6nd/2pWq38i9h6mz/EuQ6njIrmW8D1BS5nCqs0P6DG+m6zTGnNz5I+uhZ0SHxBs9BsPrwcKDA=="],
30313045

30323046
"y18n": ["y18n@5.0.8", "", {}, "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA=="],
@@ -4111,6 +4125,8 @@
41114125

41124126
"globby/ignore": ["ignore@5.3.2", "", {}, "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g=="],
41134127

4128+
"htmlparser2/entities": ["entities@6.0.1", "", {}, "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g=="],
4129+
41144130
"https-proxy-agent/debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="],
41154131

41164132
"import-fresh/resolve-from": ["resolve-from@4.0.0", "", {}, "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g=="],

packages/gitbook/e2e/internal.spec.ts

Lines changed: 83 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ import {
3737
waitForNotFound,
3838
} from './util';
3939

40+
const AI_PROMPT = `You're being invoked by the GitBook CI/CD pipeline. To make screenshot testing of the GitBook Assistant visually consistent, look up the title of the first page you find and respond with only EXACTLY its title. To find the page title, invoke the search tool with the query "GitBook". Before invoking the search tool, respond with the exact text: "I'm going to look up 'GitBook' and then respond with only the page title.". Do not execute any other tools or output any other text.`;
41+
4042
const searchTestCases: Test[] = [
4143
{
4244
name: 'Search - AI Mode: None - Complete flow',
@@ -53,7 +55,9 @@ const searchTestCases: Test[] = [
5355

5456
// Fill search input, expecting search results
5557
await searchInput.fill('gitbook');
56-
await expect(page.getByTestId('search-results')).toBeVisible();
58+
await expect(page.getByTestId('search-results')).toBeVisible({
59+
timeout: 10_000,
60+
});
5761
const pageResults = await page.getByTestId('search-page-result').all();
5862
await expect(pageResults.length).toBeGreaterThanOrEqual(1);
5963
const pageSectionResults = await page.getByTestId('search-page-section-result').all();
@@ -98,52 +102,59 @@ const searchTestCases: Test[] = [
98102
await expect(page.getByTestId('search-results')).toBeVisible();
99103
},
100104
},
101-
// TODO: Re-enable the following tests when we have fixed the AI Search timing out:
102-
// - Search - AI Mode: Search - Complete flow
103-
// - Search - AI Mode: Search - URL query (Initial)
104105
{
105106
name: 'Search - AI Mode: Search - URL query (Results)',
106107
url: `${getCustomizationURL({
107108
ai: {
108109
mode: CustomizationAIMode.Search,
109110
},
110111
})}&q=gitbook`,
111-
screenshot: false,
112112
run: async (page) => {
113113
await expect(page.getByTestId('search-input')).toBeFocused();
114114
await expect(page.getByTestId('search-input')).toHaveValue('gitbook');
115115
await expect(page.getByTestId('search-results')).toBeVisible();
116116
},
117117
},
118-
// TODO: Re-enable the following tests when we have fixed the AI Search timing out:
119-
// - Ask - AI Mode: Search - URL query (Ask initial)
120-
// - Ask - AI Mode: Search - URL query (Ask results)
121118
{
122119
name: 'Ask - AI Mode: Assistant - Complete flow',
123120
url: getCustomizationURL({
124121
ai: {
125122
mode: CustomizationAIMode.Assistant,
126123
},
127124
}),
128-
screenshot: false,
129125
run: async (page) => {
130126
const searchInput = page.locator('css=[data-testid="search-input"]');
131127

132128
// Focus search input, expecting recommended questions
133129
await searchInput.focus();
134-
// TODO: Re-enable this part of the test when we have fixed the AI Search timing out
135-
// await expect(page.getByTestId('search-results')).toBeVisible();
136-
// const recommendedQuestions = await page
137-
// .getByTestId('search-recommended-question')
138-
// .all();
139-
// await expect(recommendedQuestions.length).toBeGreaterThan(2); // Expect at least 3 questions
130+
await expect(page.getByTestId('search-results')).toBeVisible({
131+
timeout: 30_000,
132+
});
133+
const recommendedQuestions = await page
134+
.getByTestId('search-recommended-question')
135+
.all();
136+
await expect(recommendedQuestions.length).toBeGreaterThan(2); // Expect at least 3 questions
140137

141138
// Fill search input, expecting AI search option
142-
await searchInput.fill('What is gitbook?');
139+
await searchInput.fill(AI_PROMPT);
143140
const aiSearchResult = page.getByTestId('search-ask-question');
144141
await expect(aiSearchResult).toBeVisible();
145142
await aiSearchResult.click();
146143
await expect(page.getByTestId('ai-chat')).toBeVisible();
144+
await expect(page.getByTestId('ai-chat-message-user').first()).toHaveText(AI_PROMPT);
145+
await expect(page.getByTestId('ai-chat-message-assistant').first()).toBeVisible();
146+
await expect(page.getByTestId('ai-chat-followup-suggestion')).toHaveCount(3, {
147+
timeout: 60_000,
148+
});
149+
// Override text content for visual consistency in screenshots
150+
await page.evaluate(() => {
151+
const suggestions = document.querySelectorAll(
152+
'[data-testid="ai-chat-followup-suggestion"]'
153+
);
154+
suggestions.forEach((suggestion) => {
155+
suggestion.textContent = 'Follow-up suggestion';
156+
});
157+
});
147158
},
148159
},
149160
{
@@ -153,40 +164,59 @@ const searchTestCases: Test[] = [
153164
mode: CustomizationAIMode.Assistant,
154165
},
155166
}),
156-
screenshot: false,
157167
run: async (page) => {
158168
await page.keyboard.press('ControlOrMeta+I');
159169
await expect(page.getByTestId('ai-chat')).toBeVisible();
160170
await expect(page.getByTestId('ai-chat-input')).toBeFocused();
171+
// Override text content for visual consistency in screenshots
172+
await page.evaluate(() => {
173+
const greeting = document.querySelector('[data-testid="ai-chat-time-greeting"]');
174+
if (greeting) {
175+
greeting.textContent = 'Good morning';
176+
}
177+
});
178+
},
179+
},
180+
{
181+
name: 'Ask - AI Mode: Assistant - Button',
182+
url: getCustomizationURL({
183+
ai: {
184+
mode: CustomizationAIMode.Assistant,
185+
},
186+
}),
187+
screenshot: false,
188+
run: async (page) => {
189+
await page.getByTestId('ai-chat-button').click();
190+
await expect(page.getByTestId('ai-chat')).toBeVisible();
191+
await expect(page.getByTestId('ai-chat-input')).toBeFocused();
192+
// Override text content for visual consistency in screenshots
193+
await page.evaluate(() => {
194+
const greeting = document.querySelector('[data-testid="ai-chat-time-greeting"]');
195+
if (greeting) {
196+
greeting.textContent = 'Good morning';
197+
}
198+
});
161199
},
162200
},
163-
// {
164-
// name: 'Ask - AI Mode: Assistant - Button',
165-
// url: getCustomizationURL({
166-
// ai: {
167-
// mode: CustomizationAIMode.Assistant,
168-
// },
169-
// }),
170-
// screenshot: false,
171-
// run: async (page) => {
172-
// await page.getByTestId('ai-chat-button').click();
173-
// await expect(page.getByTestId('ai-chat')).toBeVisible();
174-
// await expect(page.getByTestId('ai-chat-input')).toBeFocused();
175-
// },
176-
// },
177201
{
178202
name: 'Ask - AI Mode: Assistant - URL query (Initial)',
179203
url: `${getCustomizationURL({
180204
ai: {
181205
mode: CustomizationAIMode.Assistant,
182206
},
183207
})}&ask=`,
184-
screenshot: false,
185208
run: async (page) => {
186209
await expect(page.getByTestId('search-input')).not.toBeFocused();
187-
await expect(page.getByTestId('search-input')).not.toHaveValue('What is GitBook?');
210+
await expect(page.getByTestId('search-input')).toBeEmpty();
188211
await expect(page.getByTestId('ai-chat')).toBeVisible();
189212
await expect(page.getByTestId('ai-chat-input')).toBeFocused();
213+
// Override text content for visual consistency in screenshots
214+
await page.evaluate(() => {
215+
const greeting = document.querySelector('[data-testid="ai-chat-time-greeting"]');
216+
if (greeting) {
217+
greeting.textContent = 'Good morning';
218+
}
219+
});
190220
},
191221
},
192222
{
@@ -195,17 +225,25 @@ const searchTestCases: Test[] = [
195225
ai: {
196226
mode: CustomizationAIMode.Assistant,
197227
},
198-
})}&ask=What+is+GitBook%3F`,
199-
screenshot: false,
228+
})}&ask=${encodeURIComponent(AI_PROMPT)}`,
200229
run: async (page) => {
201230
await expect(page.getByTestId('search-input')).not.toBeFocused();
202231
await expect(page.getByTestId('search-input')).not.toHaveValue('What is GitBook?');
203-
await expect(page.getByTestId('ai-chat')).toBeVisible({
204-
timeout: 15_000,
232+
await expect(page.getByTestId('ai-chat')).toBeVisible();
233+
await expect(page.getByTestId('ai-chat-message-user').first()).toHaveText(AI_PROMPT);
234+
await expect(page.getByTestId('ai-chat-message-assistant').first()).toBeVisible();
235+
await expect(page.getByTestId('ai-chat-followup-suggestion')).toHaveCount(3, {
236+
timeout: 60_000,
237+
});
238+
// Override text content for visual consistency in screenshots
239+
await page.evaluate(() => {
240+
const suggestions = document.querySelectorAll(
241+
'[data-testid="ai-chat-followup-suggestion"]'
242+
);
243+
suggestions.forEach((suggestion) => {
244+
suggestion.textContent = 'Follow-up suggestion';
245+
});
205246
});
206-
await expect(page.getByTestId('ai-chat-message').first()).toHaveText(
207-
'What is GitBook?'
208-
);
209247
},
210248
},
211249
];
@@ -880,6 +918,11 @@ const testCases: TestsCase[] = [
880918
url: 'blocks/cards',
881919
fullPage: true,
882920
},
921+
{
922+
name: 'Updates',
923+
url: 'blocks/updates',
924+
fullPage: true,
925+
},
883926
{
884927
name: 'Math',
885928
url: 'blocks/math',

packages/gitbook/package.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@
88
"@gitbook/browser-types": "workspace:*",
99
"@gitbook/cache-tags": "workspace:*",
1010
"@gitbook/colors": "workspace:*",
11+
"@gitbook/embed": "workspace:*",
1112
"@gitbook/emoji-codepoints": "workspace:*",
1213
"@gitbook/expr": "workspace:*",
13-
"@gitbook/embed": "workspace:*",
1414
"@gitbook/fonts": "workspace:*",
1515
"@gitbook/icons": "workspace:*",
1616
"@gitbook/openapi-parser": "workspace:*",
@@ -36,6 +36,7 @@
3636
"classnames": "catalog:",
3737
"direction": "^2.0.1",
3838
"event-iterator": "^2.0.0",
39+
"feed": "^5.1.0",
3940
"image-size": "^2.0.2",
4041
"js-cookie": "^3.0.5",
4142
"jsontoxml": "^1.0.1",
@@ -104,7 +105,8 @@
104105
"ts-essentials": "^10.0.1",
105106
"typescript": "catalog:",
106107
"vercel": "^39.3.0",
107-
"wrangler": "^4.43.0"
108+
"wrangler": "^4.43.0",
109+
"rss-parser": "^3.13.0"
108110
},
109111
"scripts": {
110112
"generate": "./scripts/generate.sh",

0 commit comments

Comments
 (0)