diff --git a/.dockerignore b/.dockerignore index 28069318613..cf10e8046c0 100644 --- a/.dockerignore +++ b/.dockerignore @@ -105,6 +105,7 @@ blocks/**/.env **/dist **/build **/target +**/pkg # vscode config **/.vscode/settings.json diff --git a/.gitignore b/.gitignore index 4c9d2ab525d..8c0a51f5ad3 100644 --- a/.gitignore +++ b/.gitignore @@ -88,6 +88,7 @@ blocks/**/.env **/dist **/build **/target +**/pkg # vscode config **/.vscode/settings.json diff --git a/.yarn/patches/@types-webextension-polyfill-npm-0.10.4-291152c615.patch b/.yarn/patches/@types-webextension-polyfill-npm-0.10.4-291152c615.patch deleted file mode 100644 index 5a34a7e4cb9..00000000000 --- a/.yarn/patches/@types-webextension-polyfill-npm-0.10.4-291152c615.patch +++ /dev/null @@ -1,22 +0,0 @@ -diff --git a/namespaces/runtime.d.ts b/namespaces/runtime.d.ts -index eaeaf9110a189d77894844591c5d575f10585f97..54b2b4ea914139affa3d772a49a60b057df41b76 100644 ---- a/namespaces/runtime.d.ts -+++ b/namespaces/runtime.d.ts -@@ -448,7 +448,7 @@ export namespace Runtime { - * will keep the message channel open to the other end until sendResponse is called). - */ - onMessage: Events.Event< -- (message: any, sender: MessageSender, sendResponse: () => void) => Promise | true | void -+ (message: any, sender: MessageSender, sendResponse: (response: any) => void) => Promise | true | void - >; - - /** -@@ -463,7 +463,7 @@ export namespace Runtime { - * will keep the message channel open to the other end until sendResponse is called). - */ - onMessageExternal: Events.Event< -- (message: any, sender: MessageSender, sendResponse: () => void) => Promise | true | void -+ (message: any, sender: MessageSender, sendResponse: (response: any) => void) => Promise | true | void - >; - - /** diff --git a/apps/plugin-browser/package.json b/apps/plugin-browser/package.json index 4cc21f47074..dbe40ab4b8c 100755 --- a/apps/plugin-browser/package.json +++ b/apps/plugin-browser/package.json @@ -45,7 +45,7 @@ "react": "19.0.0", "react-dom": "19.0.0", "uuid": "11.0.3", - "webextension-polyfill": "0.10.0", + "webextension-polyfill": "0.12.0", "ws": "8.18.0" }, "devDependencies": { @@ -65,7 +65,7 @@ "@types/lodash.debounce": "4.0.9", "@types/react": "19.0.1", "@types/react-dom": "19.0.2", - "@types/webextension-polyfill": "patch:@types/webextension-polyfill@npm%3A0.10.4#~/.yarn/patches/@types-webextension-polyfill-npm-0.10.4-291152c615.patch", + "@types/webextension-polyfill": "0.12.0", "@types/ws": "8.5.13", "babel-loader": "9.2.1", "babel-preset-react-app": "10.0.1", diff --git a/apps/plugin-browser/src/pages/popup/popup-contents/action-center/one-off/infer-entities-action.tsx b/apps/plugin-browser/src/pages/popup/popup-contents/action-center/one-off/infer-entities-action.tsx index dd487e0024a..1563a121ebd 100644 --- a/apps/plugin-browser/src/pages/popup/popup-contents/action-center/one-off/infer-entities-action.tsx +++ b/apps/plugin-browser/src/pages/popup/popup-contents/action-center/one-off/infer-entities-action.tsx @@ -62,10 +62,10 @@ export const InferEntitiesAction = ({ }; try { - const sourceWebPage = await (browser.tabs.sendMessage( - activeTab.id, - message, - ) as Promise); + const sourceWebPage = await browser.tabs.sendMessage< + GetTabContentRequest, + GetTabContentReturn + >(activeTab.id, message); void sendMessageToBackground({ createAs, diff --git a/apps/plugin-browser/src/scripts/background.ts b/apps/plugin-browser/src/scripts/background.ts index 6dd14195db0..fc7adda01ce 100644 --- a/apps/plugin-browser/src/scripts/background.ts +++ b/apps/plugin-browser/src/scripts/background.ts @@ -5,8 +5,8 @@ import { getUser } from "../shared/get-user"; import type { GetTabContentRequest, GetTabContentReturn, - Message, } from "../shared/messages"; +import { isWellFormattedMessage } from "../shared/messages"; import { clearLocalStorage, getFromLocalStorage, @@ -36,7 +36,11 @@ browser.runtime.onInstalled.addListener(({ reason }) => { } }); -browser.runtime.onMessage.addListener(async (message: Message, sender) => { +browser.runtime.onMessage.addListener(async (message, sender) => { + if (!isWellFormattedMessage(message)) { + return `Unrecognised message format ${String(message)}`; + } + if (sender.tab) { // We are not expecting any messages from the content script return; @@ -63,9 +67,12 @@ browser.tabs.onUpdated.addListener((tabId, changeInfo) => { setTimeout(resolve, 2_000); }); - const webPage = await (browser.tabs.sendMessage(tabId, { + const webPage = await browser.tabs.sendMessage< + GetTabContentRequest, + GetTabContentReturn + >(tabId, { type: "get-tab-content", - } satisfies GetTabContentRequest) as Promise); + }); const applicableRules = automaticInferenceConfig.rules.filter( ({ restrictToDomains }) => { diff --git a/apps/plugin-browser/src/scripts/background/infer-entities/get-website-content.ts b/apps/plugin-browser/src/scripts/background/infer-entities/get-website-content.ts index 331e9bbf5f4..56b7aa8ca2b 100644 --- a/apps/plugin-browser/src/scripts/background/infer-entities/get-website-content.ts +++ b/apps/plugin-browser/src/scripts/background/infer-entities/get-website-content.ts @@ -45,9 +45,12 @@ export const getWebsiteContent = async (urls: string[]) => { browser.tabs.onUpdated.addListener(tabChangeListener); }); - const webPage = await (browser.tabs.sendMessage(tab.id, { + const webPage = await browser.tabs.sendMessage< + GetTabContentRequest, + GetTabContentReturn + >(tab.id, { type: "get-tab-content", - } satisfies GetTabContentRequest) as Promise); + }); webPages.push(webPage); diff --git a/apps/plugin-browser/src/scripts/content.ts b/apps/plugin-browser/src/scripts/content.ts index 19fe32bb204..50679f092b6 100644 --- a/apps/plugin-browser/src/scripts/content.ts +++ b/apps/plugin-browser/src/scripts/content.ts @@ -1,6 +1,12 @@ import browser from "webextension-polyfill"; +import { + type GetTabContentReturn, + isWellFormattedMessage, +} from "../shared/messages"; + /** + * @file * Content scripts operate in the context of the webpage itself, for reading and manipulating context. * * They have access to a limited set of browser APIs @@ -10,11 +16,15 @@ import browser from "webextension-polyfill"; * * You must update the extension if you amend this file, from the extensions manager page in the browser. */ -import type { GetTabContentReturn, Message } from "../shared/messages"; -// Promise based API (see: https://github.com/mozilla/webextension-polyfill/?tab=readme-ov-file#using-the-promise-based-apis) +// Promise based API (see: +// https://github.com/mozilla/webextension-polyfill/?tab=readme-ov-file#using-the-promise-based-apis) // eslint-disable-next-line @typescript-eslint/require-await -browser.runtime.onMessage.addListener(async (message: Message, _sender) => { +browser.runtime.onMessage.addListener(async (message) => { + if (!isWellFormattedMessage(message)) { + return `Unrecognised message format ${String(message)}`; + } + if (message.type === "get-tab-content") { const docContent = document.querySelector("main") ?? document.querySelector("body"); diff --git a/apps/plugin-browser/src/shared/messages.ts b/apps/plugin-browser/src/shared/messages.ts index acb8d5c1e24..ab3adeec31a 100644 --- a/apps/plugin-browser/src/shared/messages.ts +++ b/apps/plugin-browser/src/shared/messages.ts @@ -27,3 +27,8 @@ export type Message = | InferEntitiesRequest | CancelInferEntitiesRequest | GetTabContentRequest; + +export const isWellFormattedMessage = (message: unknown): message is Message => + typeof message === "object" && + message !== null && + typeof (message as { type: unknown }).type === "string"; diff --git a/libs/@local/status/typescript/README.md b/libs/@local/status/typescript/README.md index fab1a370869..eb52767b484 100644 --- a/libs/@local/status/typescript/README.md +++ b/libs/@local/status/typescript/README.md @@ -84,9 +84,9 @@ This process works through code-generation using the [`quicktype`](https://githu This package is structured into two main areas: -- [`pkg`](./pkg) contains the TypeScript package that exports the `Status`, `StatusCode` types, and helper functions. - [`rust`](./rust) contains the Rust crate that defines the `Status` and `StatusCode` types. -- [`type-defs`](./type-defs) contains the plain type definitions for `Status`, `StatusCode`, and associated status payloads. These types are defined in TypeScript at the moment but could easily be represented in another schema format. +- [`typescript`](./src) contains the TypeScript package that exports the `Status`, `StatusCode` types, and helper functions. +- [`typescript/type-defs`](./type-defs) contains the plain type definitions for `Status`, `StatusCode`, and associated status payloads. These types are defined in TypeScript at the moment but could easily be represented in another schema format. Note: despite the `type-defs` being in TypeScript, we define them separately to keep a better separation of concerns, and to avoid `quicktype` breaking when it encounters non-type code (e.g. `const` definitions). diff --git a/libs/@local/status/typescript/package.json b/libs/@local/status/typescript/package.json index b9e373ffc5d..c69bcd48c9a 100644 --- a/libs/@local/status/typescript/package.json +++ b/libs/@local/status/typescript/package.json @@ -5,10 +5,10 @@ "license": "(MIT OR Apache-2.0)", "type": "module", "exports": { - ".": "./dist/pkg/src/main.js", + ".": "./dist/src/main.js", "./type-defs/*": "./dist/type-defs/*.js" }, - "types": "./dist/pkg/src/main.d.ts", + "types": "./dist/src/main.d.ts", "scripts": { "build": "rimraf dist && tsc --build tsconfig.build.json", "fix:eslint": "eslint --fix .", diff --git a/libs/@local/status/typescript/pkg/src/main.ts b/libs/@local/status/typescript/src/main.ts similarity index 87% rename from libs/@local/status/typescript/pkg/src/main.ts rename to libs/@local/status/typescript/src/main.ts index 4cfbd8bd692..ffc0d056921 100644 --- a/libs/@local/status/typescript/pkg/src/main.ts +++ b/libs/@local/status/typescript/src/main.ts @@ -3,10 +3,10 @@ * and RPC APIs. */ -import type { Status } from "../../type-defs/status.js"; +import type { Status } from "../type-defs/status.js"; import { StatusCode } from "./status-code.js"; -export type { Status } from "../../type-defs/status.js"; +export type { Status } from "../type-defs/status.js"; export { convertHttpCodeToStatusCode, convertStatusCodeToHttpCode, diff --git a/libs/@local/status/typescript/pkg/src/status-code.ts b/libs/@local/status/typescript/src/status-code.ts similarity index 98% rename from libs/@local/status/typescript/pkg/src/status-code.ts rename to libs/@local/status/typescript/src/status-code.ts index 05a0ac284cc..459ce488326 100644 --- a/libs/@local/status/typescript/pkg/src/status-code.ts +++ b/libs/@local/status/typescript/src/status-code.ts @@ -1,6 +1,6 @@ -import { StatusCode } from "../../type-defs/status-code.js"; +import { StatusCode } from "../type-defs/status-code.js"; -export { StatusCode } from "../../type-defs/status-code.js"; +export { StatusCode } from "../type-defs/status-code.js"; const STATUS_CODE_TO_HTTP_CODE: Record = { OK: 200, diff --git a/libs/@local/status/typescript/tsconfig.build.json b/libs/@local/status/typescript/tsconfig.build.json index df24c1073a1..21689d29105 100644 --- a/libs/@local/status/typescript/tsconfig.build.json +++ b/libs/@local/status/typescript/tsconfig.build.json @@ -1,6 +1,6 @@ { "extends": "./tsconfig.json", - "include": ["pkg", "type-defs"], + "include": ["src", "type-defs"], "compilerOptions": { "declaration": true, "outDir": "dist", diff --git a/libs/@local/status/typescript/tsconfig.json b/libs/@local/status/typescript/tsconfig.json index ab95f2df657..b2d3cc538e3 100644 --- a/libs/@local/status/typescript/tsconfig.json +++ b/libs/@local/status/typescript/tsconfig.json @@ -1,6 +1,6 @@ { "extends": "@local/tsconfig/legacy-base-tsconfig-to-refactor.json", - "include": ["./pkg/src/", "./scripts", "./type-defs", "eslint.config.js"], + "include": ["./src/", "./scripts", "./type-defs", "eslint.config.js"], "compilerOptions": { "module": "NodeNext", "moduleResolution": "NodeNext" diff --git a/libs/@local/tsconfig/legacy-base-tsconfig-to-refactor.json b/libs/@local/tsconfig/legacy-base-tsconfig-to-refactor.json index cbfe08d45c5..a975c50143a 100644 --- a/libs/@local/tsconfig/legacy-base-tsconfig-to-refactor.json +++ b/libs/@local/tsconfig/legacy-base-tsconfig-to-refactor.json @@ -30,7 +30,8 @@ "@local/hash-graph-sdk/*": ["../graph/sdk/typescript/src/*.ts"], "@local/hash-graph-types/*": ["../graph/types/typescript/src/*.ts"], "@local/hash-isomorphic-utils/*": ["../hash-isomorphic-utils/src/*.ts"], - "@local/status": ["../status/typescript/pkg/src/main.ts"], + "@local/status": ["../status/typescript/src/main.ts"], + "@local/status/type-defs/*": ["../status/typescript/src/type-defs/*.ts"], "@local/hash-subgraph": ["../hash-subgraph/src/main.ts"], "@local/hash-subgraph/*": ["../hash-subgraph/src/*.ts"], "@local/harpc-client": ["../harpc/client/typescript/src/index.ts"], diff --git a/yarn.lock b/yarn.lock index 4a0add8a2bd..c65d633368d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -813,7 +813,7 @@ __metadata: "@types/lodash.debounce": "npm:4.0.9" "@types/react": "npm:19.0.1" "@types/react-dom": "npm:19.0.2" - "@types/webextension-polyfill": "patch:@types/webextension-polyfill@npm%3A0.10.4#~/.yarn/patches/@types-webextension-polyfill-npm-0.10.4-291152c615.patch" + "@types/webextension-polyfill": "npm:0.12.0" "@types/ws": "npm:8.5.13" babel-loader: "npm:9.2.1" babel-preset-react-app: "npm:10.0.1" @@ -847,7 +847,7 @@ __metadata: type-fest: "npm:3.13.1" typescript: "npm:5.7.2" uuid: "npm:11.0.3" - webextension-polyfill: "npm:0.10.0" + webextension-polyfill: "npm:0.12.0" webpack: "npm:5.97.1" webpack-cli: "npm:4.10.0" webpack-dev-server: "npm:4.15.2" @@ -18613,17 +18613,10 @@ __metadata: languageName: node linkType: hard -"@types/webextension-polyfill@npm:0.10.4": - version: 0.10.4 - resolution: "@types/webextension-polyfill@npm:0.10.4" - checksum: 10c0/6ae62b0d0b61878c0c7f65ac484b436d8a07e3561ade441a12e363bdc7db7b2675db9f94e3d1e7efd5ad2c0a5ee0818ea5942f06246cc18384b14ec698371253 - languageName: node - linkType: hard - -"@types/webextension-polyfill@patch:@types/webextension-polyfill@npm%3A0.10.4#~/.yarn/patches/@types-webextension-polyfill-npm-0.10.4-291152c615.patch": - version: 0.10.4 - resolution: "@types/webextension-polyfill@patch:@types/webextension-polyfill@npm%3A0.10.4#~/.yarn/patches/@types-webextension-polyfill-npm-0.10.4-291152c615.patch::version=0.10.4&hash=ff32d6" - checksum: 10c0/86fb2c10a438117d9310f3924a5d64f1ce0100a7f539bd6208864af4b7f5a795d8bf27fd25587cb939ea35689ba9daacd15bd07aed4241ec711a7db5812065ad +"@types/webextension-polyfill@npm:0.12.0": + version: 0.12.0 + resolution: "@types/webextension-polyfill@npm:0.12.0" + checksum: 10c0/d8b69620e9af41802a144ddbefcaf1f627856ed1b1ccf42af0b4d546906a738fea01f45efcf4eb9c2e08761e1b3333105026eb7fd4b51cafb5b4e591079faa8c languageName: node linkType: hard @@ -47734,10 +47727,10 @@ __metadata: languageName: node linkType: hard -"webextension-polyfill@npm:0.10.0": - version: 0.10.0 - resolution: "webextension-polyfill@npm:0.10.0" - checksum: 10c0/6a45278f1fed8fbd5355f9b19a7b0b3fadc91fa3a6eef69125a1706bb3efa2181235eefbfb3f538443bb396cfcb97512361551888ce8465c08914431cb2d5b6d +"webextension-polyfill@npm:0.12.0": + version: 0.12.0 + resolution: "webextension-polyfill@npm:0.12.0" + checksum: 10c0/5ace2aaaf6a203515bdd2fb948622f186a5fbb50099b539ce9c0ad54896f9cc1fcc3c0e2a71d1f7071dd7236d7daebba1e0cbcf43bfdfe54361addf0333ee7d1 languageName: node linkType: hard