Compare commits

...

1 Commits

Author SHA1 Message Date
tsukino
eabd70cf75 wip: testing extism host function 2024-04-04 03:12:11 +08:00
11 changed files with 97 additions and 4 deletions

11
package-lock.json generated
View File

@@ -9,6 +9,7 @@
"version": "0.1.0.4",
"license": "MIT",
"dependencies": {
"@extism/extism": "^1.0.2",
"@fortawesome/fontawesome-free": "^6.4.2",
"async-mutex": "^0.4.0",
"buffer": "^6.0.3",
@@ -3202,6 +3203,11 @@
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
}
},
"node_modules/@extism/extism": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/@extism/extism/-/extism-1.0.2.tgz",
"integrity": "sha512-cT48pP0mOroj4Z/gcS/PceRviIUH9vWMGhkDc5H84wXcEeOHjiyfcY4l67Gc6BvNBrvNl7sYq/XlOh2f9aEs6g=="
},
"node_modules/@fortawesome/fontawesome-free": {
"version": "6.5.1",
"resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-free/-/fontawesome-free-6.5.1.tgz",
@@ -16045,6 +16051,11 @@
"integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==",
"dev": true
},
"@extism/extism": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/@extism/extism/-/extism-1.0.2.tgz",
"integrity": "sha512-cT48pP0mOroj4Z/gcS/PceRviIUH9vWMGhkDc5H84wXcEeOHjiyfcY4l67Gc6BvNBrvNl7sYq/XlOh2f9aEs6g=="
},
"@fortawesome/fontawesome-free": {
"version": "6.5.1",
"resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-free/-/fontawesome-free-6.5.1.tgz",

View File

@@ -16,6 +16,7 @@
"lint:fix": "eslint . --fix"
},
"dependencies": {
"@extism/extism": "^1.0.2",
"@fortawesome/fontawesome-free": "^6.4.2",
"async-mutex": "^0.4.0",
"buffer": "^6.0.3",

4
plugins/hello/hello.d.ts vendored Normal file
View File

@@ -0,0 +1,4 @@
declare module 'main' {
// Extism exports take no params and return an I32
export function hello(): I32;
}

6
plugins/hello/hello.js Normal file
View File

@@ -0,0 +1,6 @@
function hello() {
const name = Host.inputString();
Host.outputString(`Hello, ${name}`);
}
module.exports = { hello };

BIN
plugins/hello/hello.wasm Normal file

Binary file not shown.

10
plugins/twitter_profile/index.d.ts vendored Normal file
View File

@@ -0,0 +1,10 @@
declare module 'main' {
// Extism exports take no params and return an I32
export function plugin(): I32;
}
declare module 'extism:host' {
interface user {
get_response(ptr: I64): I64;
}
}

View File

@@ -0,0 +1,14 @@
function plugin() {
const csrfToken = Config.get('x-csrf-token');
const authToken = Config.get('authorization');
const cookie = Config.get('Cookie');
const { get_response } = Host.getFunctions();
let msg = 'Hello from js 1';
let mem = Memory.fromString(msg);
let offset = get_response(mem.offset);
let response = Memory.find(offset).readString();
console.log(response);
Host.outputString(JSON.stringify({ csrfToken, authToken, cookie, response }));
}
module.exports = { plugin };

Binary file not shown.

View File

@@ -3,7 +3,6 @@ import React, {
ReactElement,
ReactNode,
useCallback,
useState,
} from 'react';
import Icon from '../../components/Icon';
import classNames from 'classnames';
@@ -18,6 +17,7 @@ import bookmarks from '../../../utils/bookmark/bookmarks.json';
import { replayRequest, urlify } from '../../utils/misc';
import { useDispatch } from 'react-redux';
import { get, NOTARY_API_LS_KEY, PROXY_API_LS_KEY } from '../../utils/storage';
import createPlugin, { CallContext } from '@extism/extism';
export default function Home(): ReactElement {
const requests = useRequests();
@@ -25,6 +25,42 @@ export default function Home(): ReactElement {
const navigate = useNavigate();
const dispatch = useDispatch();
const twReq =
requests.filter((req) =>
req.url.includes('https://api.twitter.com/1.1/account/settings.json'),
)[0] || {};
const plugin = useCallback(
async (name: string) => {
const config = {
...twReq.requestHeaders.reduce((acc: { [k: string]: string }, r) => {
if (r.name && r.value) {
acc[r.name] = r.value;
}
return acc;
}, {}),
};
const p = await createPlugin(
'http://localhost:61853/twitter_profile/index.wasm',
{
useWasi: true,
config,
functions: {
'extism:host/user': {
get_response: (context: CallContext, off: bigint) => {
const executed = context.read(off)?.string();
return context.store('wow okay then');
},
},
},
},
);
const out = await p.call('plugin', name);
console.log(out.text());
},
[JSON.stringify(twReq)],
);
return (
<div className="flex flex-col gap-4 py-4 overflow-y-auto">
<div className="flex flex-col flex-nowrap justify-center gap-2 mx-4">
@@ -61,6 +97,12 @@ export default function Home(): ReactElement {
</div>
</div>
)}
<div className="flex flex-col px-4 gap-4">
<h1>Plugins</h1>
<button className="button" onClick={() => plugin('tsukino')}>
Test Plugin
</button>
</div>
<div className="flex flex-col px-4 gap-4">
{bookmarks.map((bm, i) => {
try {

View File

@@ -146,9 +146,9 @@ var options = {
new webpack.ProgressPlugin(),
// expose and write the allowed env vars on the compiled bundle
new webpack.EnvironmentPlugin(["NODE_ENV"]),
new ExtReloader({
manifest: path.resolve(__dirname, "src/manifest.json")
}),
// new ExtReloader({
// manifest: path.resolve(__dirname, "src/manifest.json")
// }),
new CopyWebpackPlugin({
patterns: [
{

View File

@@ -1456,6 +1456,11 @@
"resolved" "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz"
"version" "8.57.0"
"@extism/extism@^1.0.2":
"integrity" "sha512-cT48pP0mOroj4Z/gcS/PceRviIUH9vWMGhkDc5H84wXcEeOHjiyfcY4l67Gc6BvNBrvNl7sYq/XlOh2f9aEs6g=="
"resolved" "https://registry.npmjs.org/@extism/extism/-/extism-1.0.2.tgz"
"version" "1.0.2"
"@fortawesome/fontawesome-free@^6.4.2":
"integrity" "sha512-CNy5vSwN3fsUStPRLX7fUYojyuzoEMSXPl7zSLJ8TgtRfjv24LOnOWKT2zYwaHZCJGkdyRnTmstR0P+Ah503Gw=="
"resolved" "https://registry.npmjs.org/@fortawesome/fontawesome-free/-/fontawesome-free-6.5.1.tgz"