Socket
Socket
Sign inDemoInstall

@lavamoat/aa

Package Overview
Dependencies
10
Maintainers
6
Versions
13
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 4.0.1 to 4.1.0

8

CHANGELOG.md
# Changelog
## [4.1.0](https://github.com/LavaMoat/LavaMoat/compare/aa-v4.0.1...aa-v4.1.0) (2024-02-29)
### Features
* **aa:** add custom resolver ([90ed26e](https://github.com/LavaMoat/LavaMoat/commit/90ed26e54b62327a240eed47186541afab4aff24))
* **aa:** support symlinks for workspace and devtime linking compatibility ([66996c7](https://github.com/LavaMoat/LavaMoat/commit/66996c7964fecee08e4fcb0f01ee66047c8d204d))
## [4.0.1](https://github.com/LavaMoat/LavaMoat/compare/aa-v4.0.0...aa-v4.0.1) (2024-01-18)

@@ -4,0 +12,0 @@

2

package.json
{
"name": "@lavamoat/aa",
"version": "4.0.1",
"version": "4.1.0",
"description": "LavaMoat's secure package naming convention",

@@ -5,0 +5,0 @@ "author": "kumavis",

'use strict'
const { readFileSync } = require('fs')
const path = require('path')
const { readFileSync, realpathSync, lstatSync } = require('node:fs')
const path = require('node:path')
const nodeResolve = require('resolve')

@@ -16,24 +16,48 @@

/**
* Default resolver if none provided
*/
const performantResolve = createPerformantResolve()
/**
* A `string` or something coercible to a `string`
*
* @remarks
* This is equivalent to the internal `StringOrToString` type of `resolve`
* @typedef {string | { toString: () => string }} StringOrToString
*/
/**
* Performant resolve avoids loading package.jsons if their path is what's being
* resolved, offering 2x performance improvement compared to using original
* resolve
*
* This resolver, using the `resolve` package, is incompatible with subpath
* exports.
*
* @returns {Resolver}
* @see {@link https://npm.im/resolve}
* @see {@link https://nodejs.org/api/packages.html#subpath-exports}
*/
function createPerformantResolve() {
/**
* @param {string} self
* @returns {(
* readFileSync: (file: string) => string | { toString(): string },
* pkgfile: string
* ) => Record<string, unknown>}
* @param {string} filepath
*/
const readPackageWithout = (self) => (readFileSync, pkgfile) => {
// avoid loading the package.json we're just trying to resolve
if (pkgfile.endsWith(self)) {
return {}
const readPackageWithout = (filepath) => {
/**
* @param {(path: string) => StringOrToString} readFileSync - Sync file
* reader
* @param {string} otherFilepath - Path to another `package.json`
* @returns {Record<string, unknown> | undefined}
*/
return (readFileSync, otherFilepath) => {
// avoid loading the package.json we're just trying to resolve
if (otherFilepath.endsWith(filepath)) {
return {}
}
// original readPackageSync implementation from resolve internals:
const body = readFileSync(otherFilepath)
try {
return JSON.parse(`${body}`)
} catch (jsonErr) {}
}
// original readPackageSync implementation from resolve internals:
var body = readFileSync(pkgfile)
try {
// @ts-expect-error - JSON.parse calls toString() on its parameter if not given a string
var pkg = JSON.parse(body)
return pkg
} catch (jsonErr) {}
}

@@ -54,8 +78,8 @@

*/
async function loadCanonicalNameMap({ rootDir, includeDevDeps, resolve }) {
async function loadCanonicalNameMap({
rootDir,
includeDevDeps,
resolve = performantResolve,
}) {
const canonicalNameMap = /** @type {CanonicalNameMap} */ (new Map())
// performant resolve avoids loading package.jsons if their path is what's being resolved,
// offering 2x performance improvement compared to using original resolve
resolve = resolve || createPerformantResolve()
// resolve = resolve || nodeResolve
// walk tree

@@ -79,17 +103,26 @@ const logicalPathMap = walkDependencyTreeForBestLogicalPaths({

/**
* @param {Resolver} resolve
* @param {string} depName
* @param {string} packageDir
* Resolves `package.json` of a dependency relative to `basedir`
*
* @param {Resolver} resolve - Resolver function
* @param {string} depName - Dependency name
* @param {string} basedir - Dir to resolve from
* @returns {string | undefined}
*/
function wrappedResolveSync(resolve, depName, packageDir) {
function wrappedResolveSync(resolve, depName, basedir) {
const depRelativePackageJsonPath = path.join(depName, 'package.json')
try {
return resolve.sync(depRelativePackageJsonPath, { basedir: packageDir })
} catch (err) {
if (!(/** @type {Error} */ (err).message.includes('Cannot find module'))) {
throw err
return resolve.sync(depRelativePackageJsonPath, {
basedir,
})
} catch (e) {
const err = /** @type {Error} */ (e)
if (
err &&
typeof err === 'object' &&
(('code' in err && err.code === 'MODULE_NOT_FOUND') ||
err.message?.startsWith('Cannot find module'))
) {
return
}
// debug: log resolution failures
// console.log('resolve failed', depName, packageDir)
throw err
}

@@ -116,2 +149,10 @@ }

/**
* @param {string} location
*/
function isSymlink(location) {
const info = lstatSync(location)
return info.isSymbolicLink()
}
/** @type {WalkDepTreeOpts[]} */

@@ -132,5 +173,4 @@ let currentLevelTodos

visited = new Set(),
resolve,
resolve = performantResolve,
}) {
resolve = resolve ?? createPerformantResolve()
/** @type {Map<string, string[]>} */

@@ -152,2 +192,11 @@ const preferredPackageLogicalPathMap = new Map()

for (const [
packageDir,
logicalPath,
] of preferredPackageLogicalPathMap.entries()) {
if (isSymlink(packageDir)) {
const realPath = realpathSync(packageDir)
preferredPackageLogicalPathMap.set(realPath, logicalPath)
}
}
return preferredPackageLogicalPathMap

@@ -154,0 +203,0 @@ }

@@ -0,1 +1,7 @@

/**
* A `string` or something coercible to a `string`
*/
export type StringOrToString = string | {
toString: () => string;
};
export type Resolver = {

@@ -25,3 +31,3 @@ sync: (path: string, opts: {

*/
export function loadCanonicalNameMap({ rootDir, includeDevDeps, resolve }: LoadCanonicalNameMapOpts): Promise<CanonicalNameMap>;
export function loadCanonicalNameMap({ rootDir, includeDevDeps, resolve, }: LoadCanonicalNameMapOpts): Promise<CanonicalNameMap>;
/**

@@ -45,5 +51,21 @@ * @param {WalkDepTreeOpts} options

/**
* A `string` or something coercible to a `string`
*
* @remarks
* This is equivalent to the internal `StringOrToString` type of `resolve`
* @typedef {string | { toString: () => string }} StringOrToString
*/
/**
* Performant resolve avoids loading package.jsons if their path is what's being
* resolved, offering 2x performance improvement compared to using original
* resolve
*
* This resolver, using the `resolve` package, is incompatible with subpath
* exports.
*
* @returns {Resolver}
* @see {@link https://npm.im/resolve}
* @see {@link https://nodejs.org/api/packages.html#subpath-exports}
*/
export function createPerformantResolve(): Resolver;
//# sourceMappingURL=index.d.ts.map

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Packages

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc