mirror of
https://github.com/langbot-app/LangBot.git
synced 2026-08-22 18:27:12 +00:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| bf5170ea52 |
@@ -710,11 +710,32 @@ export class BackendClient extends BaseHttpClient {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async getAuthenticatedObjectURL(path: string): Promise<string> {
|
private async getAuthenticatedObjectURL(
|
||||||
|
path: string,
|
||||||
|
rewritePluginPageSdk = false,
|
||||||
|
): Promise<string> {
|
||||||
const response = await this.instance.get<Blob>(path, {
|
const response = await this.instance.get<Blob>(path, {
|
||||||
responseType: 'blob',
|
responseType: 'blob',
|
||||||
});
|
});
|
||||||
return URL.createObjectURL(response.data);
|
let blob = response.data;
|
||||||
|
if (rewritePluginPageSdk && blob.type.startsWith('text/html')) {
|
||||||
|
const apiBase =
|
||||||
|
this.instance.defaults.baseURL === '/'
|
||||||
|
? window.location.origin
|
||||||
|
: this.instance.defaults.baseURL?.replace(/\/$/, '');
|
||||||
|
const pageSdkUrl = `${apiBase}/api/v1/plugins/_sdk/page-sdk.js`;
|
||||||
|
const html = await blob.text();
|
||||||
|
blob = new Blob(
|
||||||
|
[
|
||||||
|
html.replace(
|
||||||
|
/(<script\b[^>]*\bsrc\s*=\s*)(["'])\/api\/v1\/plugins\/_sdk\/page-sdk\.js\2/gi,
|
||||||
|
`$1$2${pageSdkUrl}$2`,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
{ type: blob.type },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return URL.createObjectURL(blob);
|
||||||
}
|
}
|
||||||
|
|
||||||
public getAuthenticatedPluginAssetURL(
|
public getAuthenticatedPluginAssetURL(
|
||||||
@@ -724,6 +745,7 @@ export class BackendClient extends BaseHttpClient {
|
|||||||
): Promise<string> {
|
): Promise<string> {
|
||||||
return this.getAuthenticatedObjectURL(
|
return this.getAuthenticatedObjectURL(
|
||||||
`/api/v1/plugins/${author}/${name}/authenticated-assets/${filepath}`,
|
`/api/v1/plugins/${author}/${name}/authenticated-assets/${filepath}`,
|
||||||
|
true,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -69,7 +69,55 @@ test('loads a Cloud plugin page through the authenticated asset route', async ({
|
|||||||
await route.fulfill({
|
await route.fulfill({
|
||||||
status: 200,
|
status: 200,
|
||||||
contentType: 'text/html',
|
contentType: 'text/html',
|
||||||
body: '<!doctype html><html><body><h1>LangRAG Observability</h1></body></html>',
|
body: `<!doctype html>
|
||||||
|
<html>
|
||||||
|
<body>
|
||||||
|
<h1>LangRAG Observability</h1>
|
||||||
|
<button id="save">Save</button>
|
||||||
|
<script src="/api/v1/plugins/_sdk/page-sdk.js"></script>
|
||||||
|
<script>
|
||||||
|
document.querySelector('#save').addEventListener('click', async () => {
|
||||||
|
await window.langbot.api('/settings', { enabled: true }, 'POST');
|
||||||
|
document.body.dataset.saved = 'true';
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>`,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
);
|
||||||
|
let pageSdkRequests = 0;
|
||||||
|
await page.route('**/api/v1/plugins/_sdk/page-sdk.js', async (route) => {
|
||||||
|
pageSdkRequests += 1;
|
||||||
|
await route.fulfill({
|
||||||
|
status: 200,
|
||||||
|
contentType: 'application/javascript',
|
||||||
|
body: `window.langbot = {
|
||||||
|
api(endpoint, body, method) {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
const requestId = 'request-' + Date.now();
|
||||||
|
const handler = (event) => {
|
||||||
|
if (event.data?.type === 'langbot:api:response' && event.data.requestId === requestId) {
|
||||||
|
window.removeEventListener('message', handler);
|
||||||
|
resolve(event.data.data);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
window.addEventListener('message', handler);
|
||||||
|
window.parent.postMessage({ type: 'langbot:api', requestId, endpoint, body, method }, '*');
|
||||||
|
});
|
||||||
|
},
|
||||||
|
};`,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
let pageApiRequests = 0;
|
||||||
|
await page.route(
|
||||||
|
'**/api/v1/plugins/langbot-team/LangRAG/page-api',
|
||||||
|
async (route) => {
|
||||||
|
pageApiRequests += 1;
|
||||||
|
await route.fulfill({
|
||||||
|
status: 200,
|
||||||
|
contentType: 'application/json',
|
||||||
|
body: wrapped({ saved: true }),
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
@@ -78,11 +126,17 @@ test('loads a Cloud plugin page through the authenticated asset route', async ({
|
|||||||
'/home/plugin-pages?id=langbot-team%2FLangRAG%2Fobservability',
|
'/home/plugin-pages?id=langbot-team%2FLangRAG%2Fobservability',
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const pluginFrame = page.frameLocator('iframe');
|
||||||
await expect(
|
await expect(
|
||||||
page
|
pluginFrame.getByRole('heading', { name: 'LangRAG Observability' }),
|
||||||
.frameLocator('iframe')
|
|
||||||
.getByRole('heading', { name: 'LangRAG Observability' }),
|
|
||||||
).toBeVisible();
|
).toBeVisible();
|
||||||
|
await pluginFrame.getByRole('button', { name: 'Save' }).click();
|
||||||
|
await expect(pluginFrame.locator('body')).toHaveAttribute(
|
||||||
|
'data-saved',
|
||||||
|
'true',
|
||||||
|
);
|
||||||
expect(authenticatedAssetRequests).toBeGreaterThan(0);
|
expect(authenticatedAssetRequests).toBeGreaterThan(0);
|
||||||
|
expect(pageSdkRequests).toBe(1);
|
||||||
|
expect(pageApiRequests).toBe(1);
|
||||||
await expect(page.getByText('Loading...')).toHaveCount(0);
|
await expect(page.getByText('Loading...')).toHaveCount(0);
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user