diff --git a/packages/extension/.eslintrc.cjs b/packages/extension/.eslintrc.cjs index c747e0b88..8885bc716 100644 --- a/packages/extension/.eslintrc.cjs +++ b/packages/extension/.eslintrc.cjs @@ -19,5 +19,14 @@ module.exports = { project: ['./tsconfig.scripts.json'], }, }, + + { + files: ['src/**/*-trusted-prelude.js'], + rules: { + 'import-x/extensions': 'off', + 'import-x/no-unassigned-import': 'off', + 'import-x/no-unresolved': 'off', + }, + }, ], }; diff --git a/packages/extension/src/background-trusted-prelude.js b/packages/extension/src/background-trusted-prelude.js new file mode 100644 index 000000000..19405f97b --- /dev/null +++ b/packages/extension/src/background-trusted-prelude.js @@ -0,0 +1,2 @@ +import './dev-console.js'; +import './endoify.js'; diff --git a/packages/extension/src/background.ts b/packages/extension/src/background.ts index ddf252964..c22a61d42 100644 --- a/packages/extension/src/background.ts +++ b/packages/extension/src/background.ts @@ -1,6 +1,4 @@ -import './dev-console.js'; -import './endoify.js'; - +import './background-trusted-prelude.js'; import type { ExtensionMessage } from './shared.js'; import { Command, makeHandledCallback } from './shared.js'; diff --git a/packages/extension/tsconfig.build.json b/packages/extension/tsconfig.build.json index ab2ce37fb..9ce11ecb2 100644 --- a/packages/extension/tsconfig.build.json +++ b/packages/extension/tsconfig.build.json @@ -13,5 +13,9 @@ { "path": "../shims/tsconfig.build.json" }, { "path": "../streams/tsconfig.build.json" } ], - "include": ["./src/**/*.ts", "./src/dev-console.js"] + "include": [ + "./src/**/*.ts", + "./src/**/*-trusted-prelude.js", + "./src/dev-console.js" + ] } diff --git a/packages/extension/tsconfig.json b/packages/extension/tsconfig.json index 060acd4ab..449869536 100644 --- a/packages/extension/tsconfig.json +++ b/packages/extension/tsconfig.json @@ -9,6 +9,14 @@ "skipLibCheck": true, "types": ["chrome", "ses", "vitest", "vitest/jsdom"] }, - "references": [{ "path": "../streams" }, { "path": "../test-utils" }], - "include": ["./src/**/*.ts", "./src/dev-console.js"] + "references": [ + { "path": "../streams" }, + { "path": "../test-utils" }, + { "path": "../shims" } + ], + "include": [ + "./src/**/*.ts", + "./src/**/*-trusted-prelude.js", + "./src/dev-console.js" + ] } diff --git a/packages/extension/vite-plugins/html-trusted-prelude.ts b/packages/extension/vite-plugins/html-trusted-prelude.ts new file mode 100644 index 000000000..89ebb3385 --- /dev/null +++ b/packages/extension/vite-plugins/html-trusted-prelude.ts @@ -0,0 +1,46 @@ +import { load as loadHtml } from 'cheerio'; +import { format as prettierFormat } from 'prettier'; +import type { Plugin } from 'vite'; + +/** + * Vite plugin to insert the endoify script before the first script in the head element. + * + * @throws If the HTML document already references the endoify script or lacks the expected + * structure. + * @returns The Vite plugin. + */ +export function htmlTrustedPrelude(): Plugin { + const endoifyElement = ''; + + return { + name: 'ocap-kernel:html-trusted-prelude', + async transformIndexHtml(htmlString): Promise { + const htmlDoc = loadHtml(htmlString); + + if (htmlDoc('script[src="endoify.ts"]').length > 0) { + throw new Error( + `HTML document should not reference "endoify.ts" directly:\n${htmlString}`, + ); + } + + if (htmlDoc('script[src="endoify.js"]').length > 0) { + throw new Error( + `HTML document already references endoify script:\n${htmlString}`, + ); + } + + if (htmlDoc('head').length !== 1 || htmlDoc('head > script').length < 1) { + throw new Error( + `Expected HTML document with a single containing at least one '; - - return { - name: 'externalize-plugin', - async transformIndexHtml(htmlString): Promise { - const htmlDoc = loadHtml(htmlString); - - if (htmlDoc('script[src="endoify.ts"]').length > 0) { - throw new Error( - `HTML document should not reference "endoify.ts" directly:\n${htmlString}`, - ); - } - - if (htmlDoc('script[src="endoify.js"]').length > 0) { - throw new Error( - `HTML document already references endoify script:\n${htmlString}`, - ); - } - - if (htmlDoc('head').length !== 1 || htmlDoc('head > script').length < 1) { - throw new Error( - `Expected HTML document with a single containing at least one