generated from ivangabriele/template-base
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
1465b09
commit f74a102
Showing
14 changed files
with
4,235 additions
and
950 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
name: E2E | ||
|
||
on: push | ||
|
||
jobs: | ||
test_e2e: | ||
name: E2E Test | ||
if: ${{ !startsWith(github.ref, 'refs/heads/ci-release-v') }} | ||
runs-on: ubuntu-latest | ||
steps: | ||
- name: Checkout | ||
uses: actions/checkout@v4 | ||
- name: Setup Node.js | ||
uses: actions/setup-node@v3 | ||
with: | ||
cache: yarn | ||
node-version: 20 | ||
- name: Install | ||
run: yarn | ||
- name: Test | ||
run: yarn test:e2e |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,35 @@ | ||
# FirePT | ||
<p align="center"> | ||
<img alt="FirePT Logo" height="128" src="public/images/logo.png" /> | ||
</p> | ||
<h1 align="center">FirePT</h1> | ||
<h3 align="center">A ChatGPT plugin server to give ChatGPT extra powers.</h3> | ||
|
||
A ChatGPT plugin to give ChatGPT extra powers. | ||
--- | ||
|
||
## Get started | ||
|
||
### Install | ||
|
||
```sh | ||
npm i -g firept | ||
``` | ||
|
||
### Run | ||
|
||
```sh | ||
firept | ||
``` | ||
|
||
## Features | ||
|
||
### Web Features | ||
|
||
- [x] Searching (Brave Search) | ||
- [x] Fetching web pages | ||
|
||
### Current Working Directory Features | ||
|
||
- [ ] Listing files | ||
- [ ] Reading files | ||
- [ ] Writing files | ||
- [ ] Running bash scripts |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
/** | ||
* For a detailed explanation regarding each configuration property, visit: | ||
* https://jestjs.io/docs/configuration | ||
*/ | ||
|
||
/** @type {import('jest').Config} */ | ||
const config = { | ||
clearMocks: true, | ||
coverageProvider: 'v8', | ||
errorOnDeprecated: true, | ||
extensionsToTreatAsEsm: ['.ts'], | ||
maxWorkers: '50%', | ||
moduleNameMapper: { | ||
'^(\\.{1,2}/.*)\\.js$': '$1', | ||
}, | ||
preset: 'ts-jest/presets/default-esm', | ||
rootDir: '..', | ||
globalSetup: '<rootDir>/config/jest.e2e.setup.ts', | ||
globalTeardown: '<rootDir>/config/jest.e2e.teardown.ts', | ||
silent: false, | ||
testMatch: ['<rootDir>/e2e/**/*.spec.ts'], | ||
transform: { | ||
'^.+\\.m?[tj]sx?$': [ | ||
'ts-jest', | ||
{ | ||
useESM: true, | ||
}, | ||
], | ||
}, | ||
} | ||
|
||
export default config |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
import { spawn } from 'child_process' | ||
import tcpPortUsed from 'tcp-port-used' | ||
|
||
const PORT = process.env.PORT ? Number(process.env.PORT) : 3333 | ||
|
||
export default async () => { | ||
console.info() | ||
|
||
console.info('[E2E]', 'Starting server...') | ||
spawn('yarn', ['start'], { | ||
stdio: 'inherit', | ||
shell: true, | ||
}) | ||
|
||
console.info('[E2E]', 'Waiting for server to start...') | ||
await tcpPortUsed.waitUntilUsed(PORT, 250, 5000) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
import killPort from 'kill-port' | ||
import tcpPortUsed from 'tcp-port-used' | ||
|
||
const PORT = process.env.PORT ? Number(process.env.PORT) : 3333 | ||
|
||
export default async () => { | ||
console.info('[E2E]', 'Stopping server...') | ||
await killPort(PORT) | ||
|
||
console.info('[E2E]', 'Waiting for server to stop...') | ||
await tcpPortUsed.waitUntilFree(PORT, 250, 5000) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
// Jest Snapshot v1, https://goo.gl/fbAQLP | ||
|
||
exports[`E2E tests should fetch and convert web page from /web/fetch 1`] = `"{"sourceAsMarkdown":"# Example Domain\\n\\nThis domain is for use in illustrative examples in documents. You may use this domain in literature without prior coordination or asking for permission.\\n\\n[More information...](https://www.iana.org/domains/example)"}"`; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
import got from 'got' | ||
// import nock from 'nock'; | ||
// import app from '../../src/index' | ||
|
||
describe('E2E tests', () => { | ||
// Mock Brave Search API response | ||
// beforeAll(() => { | ||
// nock('https://api.search.brave.com').get('/res/v1/web/search').query(true).reply(200, { | ||
// // Your mock response here | ||
// }) | ||
// }) | ||
|
||
// it('should fetch search results from /web/search', async () => { | ||
// const query = 'test query'; | ||
// const res = await request(app.callback()).get(`/web/search?query=${query}`); | ||
|
||
// expect(res.status).toBe(200); | ||
// expect(res.body).toHaveProperty('searchResults'); | ||
// }); | ||
|
||
it('should fetch and convert web page from /web/fetch', async () => { | ||
const url = 'https://example.org' | ||
const res = await got.get(`http://localhost:3333/web/fetch?url=${url}`) | ||
|
||
expect(res.ok).toBe(true) | ||
expect(res.body).toMatchSnapshot() | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
import { load as cheerioLoad } from 'cheerio' | ||
import got from 'got' | ||
import TurndownService from 'turndown' | ||
// @ts-ignore | ||
import turndownPluginGfm from 'turndown-plugin-gfm' | ||
|
||
const turndownService = new TurndownService({ | ||
bulletListMarker: '-', | ||
codeBlockStyle: 'fenced', | ||
headingStyle: 'atx', | ||
}) | ||
turndownService.use(turndownPluginGfm.gfm) | ||
|
||
export async function fetchWeb(url: string): Promise<string | null> { | ||
try { | ||
const sourceAsHtml = await got.get(url).text() | ||
|
||
const $ = cheerioLoad(sourceAsHtml) | ||
$('head').remove() | ||
$('body').each(function () { | ||
$(this).find('audio').remove() | ||
$(this).find('button').remove() | ||
$(this).find('footer').remove() | ||
$(this).find('img').remove() | ||
$(this).find('picture').remove() | ||
$(this).find('style').remove() | ||
$(this).find('template').remove() | ||
$(this).find('video').remove() | ||
|
||
// Anchors | ||
$(this) | ||
.find('a') | ||
.each(function () { | ||
if ($(this).attr('href')?.startsWith('#')) { | ||
$(this).remove() | ||
} | ||
}) | ||
|
||
$(this).find('br').replaceWith(' ') | ||
|
||
if (url.includes('github.com')) { | ||
$(this) | ||
.find('script[data-target="react-app.embeddedData"]') | ||
.each(function () { | ||
const embeddedData = JSON.parse($(this).text()) | ||
|
||
if (embeddedData?.payload?.blob?.rawLines) { | ||
const sourceCode = embeddedData.payload.blob.rawLines.join('\n') | ||
|
||
$(this).replaceWith($('<pre>').append($('<code>').text(sourceCode))) | ||
} | ||
}) | ||
|
||
$(this) | ||
.find('table') | ||
.each(function () { | ||
if ($(this).data('hpc') !== undefined) { | ||
let sourceCode = '' | ||
$(this) | ||
.find('tbody tr') | ||
.each(function () { | ||
const codeLine = $(this).find('td.blob-code').text() | ||
sourceCode += codeLine + '\n' | ||
}) | ||
|
||
$(this).replaceWith($('<pre>').append($('<code>').text(sourceCode))) | ||
} | ||
}) | ||
} | ||
|
||
$(this).find('script').remove() | ||
}) | ||
|
||
const sourceAsMarkdown = turndownService | ||
.turndown($.html()) | ||
.replace(/\[\s*\]\([^)]*\)/g, '') | ||
.replace(/\[[\n\s]*(.*)[\n\s]*\]\(([^)]*)\)/g, '[$1]($2)') | ||
.replace(/^-\s{2,}/gm, '- ') | ||
.replace(/\n{2,}/gm, '\n\n') | ||
// Github | ||
.replace('You can’t perform that action at this time.', '') | ||
.trim() | ||
|
||
return sourceAsMarkdown | ||
} catch (error) { | ||
console.error(`Error fetching or converting web page: ${error}`) | ||
return null | ||
} | ||
} |
Oops, something went wrong.