Skip to content
31 changes: 31 additions & 0 deletions packages/extension/src/endoify.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import './endoify.js';
// eslint-disable-next-line n/no-extraneous-import
import type { HandledPromiseConstructor } from '@endo/eventual-send';
import { describe, expect, it } from 'vitest';

describe(`endoify`, () => {
const assertions = [
(): boolean => typeof globalThis === 'object',
(): boolean => typeof lockdown === 'function',
(): boolean => typeof repairIntrinsics === 'function',
(): boolean => typeof Compartment === 'function',
(): boolean => typeof assert === 'function',
(): boolean => typeof HandledPromise === 'function',
(): boolean => typeof harden === 'function',
(): boolean => typeof getStackString === 'function',
(): boolean => Object.isFrozen(Array.prototype),
];

for (const assertion of assertions) {
it(`asserts ${String(assertion).replace(/^.*?=>\s*/u, '')}`, () => {
expect(assertion()).toBe(true);
});
}
});

declare global {
// eslint-disable-next-line no-var
var getStackString: (error: Error) => string;
// eslint-disable-next-line no-var
var HandledPromise: HandledPromiseConstructor;
}
3 changes: 3 additions & 0 deletions packages/extension/src/endoify.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
/* eslint-disable import-x/extensions */
/* eslint-disable import-x/no-unassigned-import */
import '@ocap/shims/endoify';
1 change: 1 addition & 0 deletions packages/extension/src/iframe-manager.test.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import './endoify.js';
import * as snapsUtils from '@metamask/snaps-utils';
import { delay, makePromiseKitMock } from '@ocap/test-utils';
import { vi, describe, it, expect } from 'vitest';
Expand Down
1 change: 1 addition & 0 deletions packages/extension/src/shared.test.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import './endoify.js';
import { delay } from '@ocap/test-utils';
import { vi, describe, it, expect } from 'vitest';

Expand Down
14 changes: 11 additions & 3 deletions packages/extension/vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,20 +72,28 @@ function endoifyHtmlFilesPlugin(): Plugin {
return {
name: 'externalize-plugin',
async transformIndexHtml(htmlString): Promise<string> {
if (htmlString.includes('endoify.js')) {
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}`,
);
}

const htmlDoc = loadHtml(htmlString);
if (htmlDoc('head').length !== 1 || htmlDoc('head script').length < 1) {
if (htmlDoc('head').length !== 1 || htmlDoc('head > script').length < 1) {
throw new Error(
`Expected HTML document with a single <head> containing at least one <script>. Received:\n${htmlString}`,
);
}

htmlDoc(endoifyElement).insertBefore('head:first script:first');

return await prettierFormat(htmlDoc.html(), {
parser: 'html',
tabWidth: 2,
Expand Down
19 changes: 14 additions & 5 deletions packages/extension/vitest.config.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,32 @@
// eslint-disable-next-line spaced-comment
/// <reference types="vitest" />

import path from 'path';
import { defineConfig, mergeConfig } from 'vitest/config';

import viteConfig from './vite.config.js';
import { getDefaultConfig } from '../../vitest.config.packages.js';

const defaultConfig = getDefaultConfig();
// @ts-expect-error We can and will delete this.
delete defaultConfig.test.coverage.thresholds;

export default mergeConfig(
const config = mergeConfig(
viteConfig,
mergeConfig(
defaultConfig,
defineConfig({
test: {
setupFiles: '../test-utils/src/env/mock-endo.ts',
pool: 'vmThreads',
alias: [
{
find: '@ocap/shims/endoify',
replacement: path.resolve('../shims/src/endoify.js'),
customResolver: (id) => ({ external: true, id }),
},
],
},
}),
),
);

delete config.test.coverage.thresholds;

export default config;