diff --git a/packages/endomoat/src/constants.js b/packages/endomoat/src/constants.js index 22bf598152..9f09dca017 100644 --- a/packages/endomoat/src/constants.js +++ b/packages/endomoat/src/constants.js @@ -29,3 +29,7 @@ export const RSRC_POLICY_GLOBALS = 'globals' export const LMR_TYPE_BUILTIN = 'builtin' export const LMR_TYPE_SOURCE = 'js' + +export const LMR_TYPE_NATIVE = 'native' + +export const ENDO_PARSER_BYTES = 'bytes' diff --git a/packages/endomoat/src/policy-gen/policy-generator-context.js b/packages/endomoat/src/policy-gen/policy-generator-context.js index 4f4f130413..ca2df46864 100644 --- a/packages/endomoat/src/policy-gen/policy-generator-context.js +++ b/packages/endomoat/src/policy-gen/policy-generator-context.js @@ -8,8 +8,10 @@ import { isBuiltin as nodeIsBuiltin } from 'node:module' import { fileURLToPath } from 'node:url' import path from 'path' import { + ENDO_PARSER_BYTES, LAVAMOAT_PKG_POLICY_ROOT, LMR_TYPE_BUILTIN, + LMR_TYPE_NATIVE, LMR_TYPE_SOURCE, } from '../constants.js' import { defaultReadPower } from '../power.js' @@ -271,7 +273,10 @@ export class PolicyGeneratorContext { * @returns {Promise} * @internal */ - async buildModuleRecordsForSource(specifier, { record, sourceLocation }) { + async buildModuleRecordsForSource( + specifier, + { parser, record, sourceLocation } + ) { if (!sourceLocation) { // XXX: why would we not have a sourceLocation? throw new TypeError( @@ -299,17 +304,24 @@ export class PolicyGeneratorContext { * The `ModuleSource.content` prop is already pre-processed by Endo, and we * do not want that, since it befouls our AST crawling. * + * This will not be run if the `parser` is `bytes`. + * * @remarks * Doing this first since it may be more likely to fail than the other - * operations below - * @type {NonNullable< - * import('lavamoat-core').LavamoatModuleRecord['content'] - * >} + * operations below. + * @type {string | undefined} * @todo Modify Endo to surface the original source + * + * @todo Add more exceptions to the parsers? */ - const content = await this.readPower(sourceLocation).then((buffer) => - PolicyGeneratorContext.#decoder.decode(buffer) - ) + let content + + await Promise.resolve() + if (parser !== ENDO_PARSER_BYTES) { + content = await this.readPower(sourceLocation).then((buffer) => + PolicyGeneratorContext.#decoder.decode(buffer) + ) + } /** * The {@link LavamoatModuleRecord.file} prop @@ -338,7 +350,7 @@ export class PolicyGeneratorContext { packageName: this.packageName, importMap, content, - type: LMR_TYPE_SOURCE, + type: parser === ENDO_PARSER_BYTES ? LMR_TYPE_NATIVE : LMR_TYPE_SOURCE, }), ] diff --git a/packages/endomoat/test/fixture/json/native.json b/packages/endomoat/test/fixture/json/native.json new file mode 100644 index 0000000000..6f0fcf1485 --- /dev/null +++ b/packages/endomoat/test/fixture/json/native.json @@ -0,0 +1,8 @@ +{ + "/package.json": "{\n \"name\": \"native\",\n \"version\": \"1.0.0\",\n \"type\": \"module\",\n \"license\": \"ISC\",\n \"private\": true,\n \"main\": \"app.js\",\n \"dependencies\": {\n \"hello\": \"^1.0.0\"\n }\n}\n", + "/index.js": "import addon from 'hello'\nexport const hello = addon.hello()\n", + "/node_modules/hello/package.json": "{\n \"name\": \"hello\",\n \"version\": \"0.0.0\",\n \"description\": \"this code does not run\",\n \"private\": true,\n \"main\": \"index.js\",\n \"parsers\": {\n \"node\": \"bytes\"\n }\n}\n", + "/node_modules/hello/index.js": "var addon = require('./hello')\n\nconsole.log(addon.hello()) // 'world'\n\nmodule.exports = addon\n", + "/node_modules/hello/hello.node": "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000", + "/node_modules/hello/README.md": "This fixture is an example of a package shipping a native module (`hello.node`). `hello.node` is not _actually_ a native module, but it has the right extension and is full of null bytes. Good enough.\n" +} diff --git a/packages/endomoat/test/policy-gen/generate-policy.spec.js b/packages/endomoat/test/policy-gen/generate-policy.spec.js index c0346dce21..1dffa9223b 100644 --- a/packages/endomoat/test/policy-gen/generate-policy.spec.js +++ b/packages/endomoat/test/policy-gen/generate-policy.spec.js @@ -10,6 +10,8 @@ test(testPolicyForJSON, 'builtins.json') test(testPolicyForJSON, 'kitchen-sink.json') +test(testPolicyForJSON, 'native.json') + test('basic nested global access', testPolicyForModule, 'location.href', { resources: { test: { diff --git a/packages/endomoat/test/policy-gen/snapshots/generate-policy.spec.js.md b/packages/endomoat/test/policy-gen/snapshots/generate-policy.spec.js.md index 8d24cc2d57..6e1f3df57a 100644 --- a/packages/endomoat/test/policy-gen/snapshots/generate-policy.spec.js.md +++ b/packages/endomoat/test/policy-gen/snapshots/generate-policy.spec.js.md @@ -58,3 +58,18 @@ Generated by [AVA](https://avajs.dev). }, }, } + +## policy for fixture matches snapshot (native.json) + +> Snapshot 1 + + { + resources: { + hello: { + globals: { + 'console.log': true, + }, + native: true, + }, + }, + } diff --git a/packages/endomoat/test/policy-gen/snapshots/generate-policy.spec.js.snap b/packages/endomoat/test/policy-gen/snapshots/generate-policy.spec.js.snap index a3d79d56e7..38619d4e76 100644 Binary files a/packages/endomoat/test/policy-gen/snapshots/generate-policy.spec.js.snap and b/packages/endomoat/test/policy-gen/snapshots/generate-policy.spec.js.snap differ