lavamoat-core
Advanced tools
Comparing version 15.1.1 to 15.1.2
# Changelog | ||
## [15.1.2](https://github.com/LavaMoat/LavaMoat/compare/lavamoat-core-v15.1.1...lavamoat-core-v15.1.2) (2024-02-07) | ||
### Bug Fixes | ||
* **core:** update LavamoatModuleRecord ([152534d](https://github.com/LavaMoat/LavaMoat/commit/152534debcc869d72dab50e7e6b031578d13324c)) | ||
* **deps:** update dependency @babel/types to v7.23.9 ([c2f91e9](https://github.com/LavaMoat/LavaMoat/commit/c2f91e9a3c00ff9cf47eb8d7a4eb1ace7e155c64)) | ||
* **deps:** update dependency json-stable-stringify to v1.1.1 ([7d28e79](https://github.com/LavaMoat/LavaMoat/commit/7d28e79a5430f1f7c3987fc128e800efe590dd2a)) | ||
* **deps:** update dependency type-fest to v4.10.0 ([9f2cf3c](https://github.com/LavaMoat/LavaMoat/commit/9f2cf3cb3e00fc5184268bedb6967ffc8d29d066)) | ||
* **deps:** update dependency type-fest to v4.10.1 ([36567e7](https://github.com/LavaMoat/LavaMoat/commit/36567e7f54efab0efd2021b9f82b5e4e4c77fe4d)) | ||
* **deps:** update dependency type-fest to v4.10.2 ([1580ed9](https://github.com/LavaMoat/LavaMoat/commit/1580ed967085ae277384fcee3eac32ab9930adcd)) | ||
* **deps:** update dependency type-fest to v4.9.0 ([70e9ffd](https://github.com/LavaMoat/LavaMoat/commit/70e9ffdf740a7d79cee9d583a55188e4ab02617d)) | ||
### Dependencies | ||
* The following workspace dependencies were updated | ||
* dependencies | ||
* lavamoat-tofu bumped from ^7.1.0 to ^7.2.0 | ||
## [15.1.1](https://github.com/LavaMoat/LavaMoat/compare/lavamoat-core-v15.1.0...lavamoat-core-v15.1.1) (2024-01-18) | ||
@@ -4,0 +24,0 @@ |
{ | ||
"name": "lavamoat-core", | ||
"version": "15.1.1", | ||
"version": "15.1.2", | ||
"description": "LavaMoat kernel and utils", | ||
@@ -38,6 +38,7 @@ "repository": { | ||
"dependencies": { | ||
"json-stable-stringify": "1.0.2", | ||
"lavamoat-tofu": "^7.1.0", | ||
"@babel/types": "7.23.9", | ||
"json-stable-stringify": "1.1.1", | ||
"lavamoat-tofu": "^7.2.0", | ||
"merge-deep": "3.0.3", | ||
"type-fest": "4.7.1" | ||
"type-fest": "4.10.2" | ||
}, | ||
@@ -44,0 +45,0 @@ "devDependencies": { |
@@ -25,2 +25,3 @@ // The "prelude" is the kernel of a browserify bundle. It initializes the modules and | ||
) | ||
const scuttleSrc = fs.readFileSync(require.resolve('./scuttle.js'), 'utf-8') | ||
const makePrepareRealmGlobalFromConfigSrc = fs.readFileSync( | ||
@@ -106,2 +107,3 @@ path.join(__dirname, '/makePrepareRealmGlobalFromConfig.js'), | ||
) | ||
output = replaceTemplateRequire(output, 'scuttle', scuttleSrc) | ||
output = replaceTemplateRequire( | ||
@@ -108,0 +110,0 @@ output, |
@@ -72,4 +72,4 @@ (function () { | ||
const { strictScopeTerminator } = templateRequire('strict-scope-terminator') | ||
const { scuttle } = templateRequire('scuttle') | ||
const scuttleOpts = generateScuttleOpts(scuttleGlobalThis) | ||
const moduleCache = new Map() | ||
@@ -82,9 +82,3 @@ const packageCompartmentCache = new Map() | ||
// scuttle globalThis right after we used it to create the root package compartment | ||
if (scuttleOpts.enabled) { | ||
if (!Array.isArray(scuttleOpts.exceptions)) { | ||
throw new Error(`LavaMoat - scuttleGlobalThis.exceptions must be an array, got "${typeof scuttleOpts.exceptions}"`) | ||
} | ||
scuttleOpts.scuttlerFunc(globalRef, realm => performScuttleGlobalThis(realm, scuttleOpts.exceptions)) | ||
} | ||
scuttle(globalRef, scuttleGlobalThis) | ||
@@ -101,81 +95,2 @@ const kernel = { | ||
// generate final scuttling options (1) by taking default | ||
// options into consideration, (2) turning RE strings into | ||
// actual REs and (3) without mutating original opts object | ||
function generateScuttleOpts(originalOpts) { | ||
const defaultOpts = { | ||
enabled: true, | ||
exceptions: [], | ||
scuttlerName: '', | ||
} | ||
const opts = Object.assign({}, | ||
originalOpts === true ? { ... defaultOpts } : { ...originalOpts }, | ||
{ scuttlerFunc: (globalRef, scuttle) => scuttle(globalRef) }, | ||
{ exceptions: (originalOpts.exceptions || defaultOpts.exceptions).map(e => toRE(e)) }, | ||
) | ||
if (opts.scuttlerName) { | ||
if (!globalRef[opts.scuttlerName]) { | ||
throw new Error( | ||
`LavaMoat - 'scuttlerName' function "${opts.scuttlerName}" expected on globalRef.` + | ||
'To learn more visit https://github.com/LavaMoat/LavaMoat/pull/462.', | ||
) | ||
} | ||
opts.scuttlerFunc = globalRef[opts.scuttlerName] | ||
} | ||
return opts | ||
function toRE(except) { | ||
// turn scuttleGlobalThis.exceptions regexes strings to actual regexes | ||
if (!except.startsWith('/')) { | ||
return except | ||
} | ||
const parts = except.split('/') | ||
const pattern = parts.slice(1, -1).join('/') | ||
const flags = parts[parts.length - 1] | ||
return new RegExp(pattern, flags) | ||
} | ||
} | ||
function performScuttleGlobalThis (globalRef, extraPropsToAvoid = []) { | ||
const props = [] | ||
getPrototypeChain(globalRef) | ||
.forEach(proto => | ||
props.push(...Object.getOwnPropertyNames(proto))) | ||
// support LM,SES exported APIs and polyfills | ||
const avoidForLavaMoatCompatibility = ['Compartment', 'Error', 'globalThis'] | ||
const propsToAvoid = new Set([...avoidForLavaMoatCompatibility, ...extraPropsToAvoid]) | ||
const obj = Object.create(null) | ||
for (const prop of props) { | ||
// eslint-disable-next-line no-inner-declarations | ||
function set() { | ||
console.warn( | ||
`LavaMoat - property "${prop}" of globalThis cannot be set under scuttling mode. ` + | ||
'To learn more visit https://github.com/LavaMoat/LavaMoat/pull/360.', | ||
) | ||
} | ||
// eslint-disable-next-line no-inner-declarations | ||
function get() { | ||
throw new Error( | ||
`LavaMoat - property "${prop}" of globalThis is inaccessible under scuttling mode. ` + | ||
'To learn more visit https://github.com/LavaMoat/LavaMoat/pull/360.', | ||
) | ||
} | ||
if (shouldAvoidProp(propsToAvoid, prop)) { | ||
continue | ||
} | ||
let desc = Object.getOwnPropertyDescriptor(globalRef, prop) | ||
if (desc?.configurable === true) { | ||
desc = { configurable: false, set, get } | ||
} else if (desc?.writable === true) { | ||
const p = new Proxy(obj, { getPrototypeOf: get, get, set } ) | ||
desc = { configurable: false, writable: false, value: p } | ||
} else { | ||
continue | ||
} | ||
Object.defineProperty(globalRef, prop, desc) | ||
} | ||
} | ||
// this function instantiaties a module from a moduleId. | ||
@@ -465,26 +380,3 @@ // 1. loads the module metadata and policy | ||
// util for getting the prototype chain as an array | ||
// includes the provided value in the result | ||
function getPrototypeChain (value) { | ||
const protoChain = [] | ||
let current = value | ||
while (current && (typeof current === 'object' || typeof current === 'function')) { | ||
protoChain.push(current) | ||
current = Reflect.getPrototypeOf(current) | ||
} | ||
return protoChain | ||
} | ||
function shouldAvoidProp(propsToAvoid, prop) { | ||
for (const avoid of propsToAvoid) { | ||
if (avoid instanceof RegExp && avoid.test(prop)) { | ||
return true | ||
} | ||
if (propsToAvoid.has(prop)) { | ||
return true | ||
} | ||
} | ||
return false | ||
} | ||
} | ||
})() |
// @ts-check | ||
/** | ||
* A module record | ||
* | ||
* @template {any[]} [InitArgs=unknown[]] - Arguments for | ||
* {@link LavamoatModuleRecord.moduleInitializer}. Default is `unknown[]` | ||
*/ | ||
class LavamoatModuleRecord { | ||
/** | ||
* @param {LavamoatModuleRecordOptions} opts | ||
* Module specifier | ||
* | ||
* @type {string} | ||
*/ | ||
specifier | ||
/** | ||
* A filepath if {@link type} is `js`; otherwise the same value as | ||
* {@link specifier} | ||
* | ||
* @type {string} | ||
*/ | ||
file | ||
/** | ||
* The type of module | ||
* | ||
* @type {ModuleRecordType} | ||
*/ | ||
type | ||
/** | ||
* The containing package name if {@link type} is `js`; otherwise the same | ||
* value as {@link specifier} | ||
* | ||
* @type {string} | ||
*/ | ||
packageName | ||
/** | ||
* Content of module (source code) | ||
* | ||
* Only applicable if {@link type} is `js`. | ||
* | ||
* @type {string | undefined} | ||
*/ | ||
content | ||
/** | ||
* Map of specifiers to resolved filepaths or specifiers | ||
* | ||
* @type {Record<string, string>} | ||
*/ | ||
importMap | ||
/** | ||
* Parsed AST, if any | ||
* | ||
* @type {import('@babel/types').File | undefined} | ||
*/ | ||
ast | ||
/** | ||
* Module initializer function | ||
* | ||
* @type {ModuleInitializer<InitArgs> | undefined} | ||
*/ | ||
moduleInitializer | ||
/** | ||
* Assigns properties! | ||
* | ||
* @param {LavamoatModuleRecordOptions<InitArgs>} opts | ||
*/ | ||
constructor({ | ||
@@ -31,14 +99,33 @@ specifier, | ||
/** | ||
* Options for {@link LavamoatModuleRecord} constructor. | ||
* | ||
* @template {any[]} [InitArgs=unknown[]] - Arguments for | ||
* {@link LavamoatModuleRecordOptions.moduleInitializer}. Default is | ||
* `unknown[]` | ||
* @typedef LavamoatModuleRecordOptions | ||
* @property {string} specifier | ||
* @property {string} file | ||
* @property {'builtin' | 'native' | 'js'} type | ||
* @property {string} packageName | ||
* @property {string} [content] | ||
* @property {Record<string, string>} [importMap] | ||
* @property {import('@babel/types').File} [ast] | ||
* @property {(...args: any[]) => any} [moduleInitializer] | ||
* @todo `moduleInitializer` probably needs narrowing | ||
* @property {string} specifier - Module specifier | ||
* @property {string} file - Path to module file (or specifier) | ||
* @property {ModuleRecordType} type - Module type | ||
* @property {string} packageName - Package containing module (or specifier) | ||
* @property {string} [content] - Content of module (source) | ||
* @property {Record<string, string>} [importMap] - Import map | ||
* @property {import('@babel/types').File} [ast] - Parsed AST | ||
* @property {ModuleInitializer<InitArgs>} [moduleInitializer] - Module | ||
* initializer function | ||
*/ | ||
/** | ||
* Possible value of {@link LavamoatModuleRecord.type}. | ||
* | ||
* @todo `@babel/types` should be a prod dep | ||
* _Note:_ `js` means "source code", **not** "JavaScript source code" | ||
* | ||
* @typedef {'builtin' | 'native' | 'js'} ModuleRecordType | ||
*/ | ||
/** | ||
* Module initializer function; provides non-global variables to module scope | ||
* | ||
* @template {any[]} [InitArgs=unknown[]] - Arguments for the function. Default | ||
* is `unknown[]` | ||
* @typedef {(...args: InitArgs) => void} ModuleInitializer | ||
*/ |
@@ -15,8 +15,8 @@ const { | ||
const DIRECT_EVAL_REPLACE_FN = (_, p1) => '(0,eval)' + p1 | ||
function evadeDirectEvalExpressions(source) { | ||
/* eslint-disable-next-line prefer-regex-literals */ | ||
const someDirectEvalPattern = new RegExp('\\beval(\\s*\\()', 'g') | ||
const replaceFn = (_, p1) => `(0,eval)${p1}` | ||
return source.replace(someDirectEvalPattern, replaceFn) | ||
return source.replace( | ||
/\beval(\s*\()/g, | ||
DIRECT_EVAL_REPLACE_FN | ||
) | ||
} | ||
@@ -23,0 +23,0 @@ |
@@ -1,25 +0,115 @@ | ||
export type LavamoatModuleRecordOptions = { | ||
/** | ||
* Options for {@link LavamoatModuleRecord } constructor. | ||
*/ | ||
export type LavamoatModuleRecordOptions<InitArgs extends any[] = unknown[]> = { | ||
/** | ||
* - Module specifier | ||
*/ | ||
specifier: string; | ||
/** | ||
* - Path to module file (or specifier) | ||
*/ | ||
file: string; | ||
type: 'builtin' | 'native' | 'js'; | ||
/** | ||
* - Module type | ||
*/ | ||
type: ModuleRecordType; | ||
/** | ||
* - Package containing module (or specifier) | ||
*/ | ||
packageName: string; | ||
/** | ||
* - Content of module (source) | ||
*/ | ||
content?: string | undefined; | ||
/** | ||
* - Import map | ||
*/ | ||
importMap?: Record<string, string> | undefined; | ||
/** | ||
* - Parsed AST | ||
*/ | ||
ast?: import("@babel/types").File | undefined; | ||
moduleInitializer?: ((...args: any[]) => any) | undefined; | ||
/** | ||
* - Module | ||
* initializer function | ||
*/ | ||
moduleInitializer?: ModuleInitializer<InitArgs> | undefined; | ||
}; | ||
export class LavamoatModuleRecord { | ||
/** | ||
* Possible value of {@link LavamoatModuleRecord.type }. | ||
* | ||
* _Note:_ `js` means "source code", **not** "JavaScript source code" | ||
*/ | ||
export type ModuleRecordType = 'builtin' | 'native' | 'js'; | ||
/** | ||
* Module initializer function; provides non-global variables to module scope | ||
*/ | ||
export type ModuleInitializer<InitArgs extends any[] = unknown[]> = (...args: InitArgs) => void; | ||
/** | ||
* A module record | ||
* | ||
* @template {any[]} [InitArgs=unknown[]] - Arguments for | ||
* {@link LavamoatModuleRecord.moduleInitializer}. Default is `unknown[]` | ||
*/ | ||
export class LavamoatModuleRecord<InitArgs extends any[] = unknown[]> { | ||
/** | ||
* @param {LavamoatModuleRecordOptions} opts | ||
* Assigns properties! | ||
* | ||
* @param {LavamoatModuleRecordOptions<InitArgs>} opts | ||
*/ | ||
constructor({ specifier, file, type, packageName, content, importMap, ast, moduleInitializer, }: LavamoatModuleRecordOptions); | ||
constructor({ specifier, file, type, packageName, content, importMap, ast, moduleInitializer, }: LavamoatModuleRecordOptions<InitArgs>); | ||
/** | ||
* Module specifier | ||
* | ||
* @type {string} | ||
*/ | ||
specifier: string; | ||
/** | ||
* A filepath if {@link type} is `js`; otherwise the same value as | ||
* {@link specifier} | ||
* | ||
* @type {string} | ||
*/ | ||
file: string; | ||
type: "builtin" | "native" | "js"; | ||
/** | ||
* The type of module | ||
* | ||
* @type {ModuleRecordType} | ||
*/ | ||
type: ModuleRecordType; | ||
/** | ||
* The containing package name if {@link type} is `js`; otherwise the same | ||
* value as {@link specifier} | ||
* | ||
* @type {string} | ||
*/ | ||
packageName: string; | ||
/** | ||
* Content of module (source code) | ||
* | ||
* Only applicable if {@link type} is `js`. | ||
* | ||
* @type {string | undefined} | ||
*/ | ||
content: string | undefined; | ||
/** | ||
* Map of specifiers to resolved filepaths or specifiers | ||
* | ||
* @type {Record<string, string>} | ||
*/ | ||
importMap: Record<string, string>; | ||
ast: import("@babel/types").File | undefined; | ||
moduleInitializer: ((...args: any[]) => any) | undefined; | ||
/** | ||
* Parsed AST, if any | ||
* | ||
* @type {import('@babel/types').File | undefined} | ||
*/ | ||
ast: import('@babel/types').File | undefined; | ||
/** | ||
* Module initializer function | ||
* | ||
* @type {ModuleInitializer<InitArgs> | undefined} | ||
*/ | ||
moduleInitializer: ModuleInitializer<InitArgs> | undefined; | ||
} | ||
//# sourceMappingURL=moduleRecord.d.ts.map |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
544940
70
13438
5
+ Added@babel/types@7.23.9
+ Added@babel/types@7.23.9(transitive)
+ Addedtype-fest@4.10.2(transitive)
- Removedjson-stable-stringify@1.0.2(transitive)
- Removedtype-fest@4.7.1(transitive)
Updatedjson-stable-stringify@1.1.1
Updatedlavamoat-tofu@^7.2.0
Updatedtype-fest@4.10.2