@lwc/module-resolver
Advanced tools
Comparing version
@@ -13,3 +13,3 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const glob_1 = __importDefault(require("glob")); | ||
const fast_glob_1 = __importDefault(require("fast-glob")); | ||
const path_1 = __importDefault(require("path")); | ||
@@ -19,3 +19,3 @@ const fs_1 = __importDefault(require("fs")); | ||
const DEFAULT_IGNORE = ['**/node_modules/**', '**/__tests__/**']; | ||
const PACKAGE_PATTERN = `**/*/package.json`; | ||
const PACKAGE_PATTERN = ['*/*/package.json', '*/package.json', 'package.json']; | ||
const MODULE_ENTRY_PATTERN = `**/*.[jt]s`; | ||
@@ -31,17 +31,24 @@ const LWC_CONFIG_FILE = '.lwcrc'; | ||
try { | ||
const jsonPkg = require(packageJsonPath); | ||
config = JSON.parse(fs_1.default.readFileSync(lwcConfigPath, 'utf8')); | ||
} | ||
catch (ignore) { | ||
// ignore | ||
} | ||
if (!config) { | ||
try { | ||
config = fs_1.default.readFileSync(lwcConfigPath, 'utf8'); | ||
config = JSON.parse(fs_1.default.readFileSync(packageJsonPath, 'utf8')).lwc; | ||
} | ||
catch (e) { | ||
config = jsonPkg.lwc; | ||
catch (ignore) { | ||
// ignore | ||
} | ||
} | ||
catch (ignore) { | ||
// ignore | ||
} | ||
return config; | ||
} | ||
function resolveModulesInDir(absPath) { | ||
return glob_1.default.sync(MODULE_ENTRY_PATTERN, { cwd: absPath }).reduce((mappings, file) => { | ||
return fast_glob_1.default | ||
.sync(MODULE_ENTRY_PATTERN, { | ||
cwd: absPath, | ||
transform: entry => typeof entry === 'string' ? { path: entry } : { path: entry.path }, | ||
}) | ||
.reduce((mappings, { path: file }) => { | ||
const ext = path_1.default.extname(file); | ||
@@ -70,5 +77,11 @@ const fileName = path_1.default.basename(file, ext); | ||
} | ||
function expandModuleDirectories({ moduleDirectories, rootDir, } = {}) { | ||
function expandModuleDirectories({ moduleDirectories, rootDir, modulePaths, } = {}) { | ||
if (modulePaths) { | ||
return modulePaths; | ||
} | ||
if (!moduleDirectories && !rootDir) { | ||
return module.paths; | ||
// paths() is spec'd to return null only for built-in node | ||
// modules like 'http'. To be safe, return empty array in | ||
// instead of null in this case. | ||
return require.resolve.paths('.') || []; | ||
} | ||
@@ -107,5 +120,9 @@ return node_modules_paths_1.default(rootDir || __dirname, moduleDirectories); | ||
return modulePaths.reduce((m, nodeModulesDir) => { | ||
return glob_1.default | ||
.sync(PACKAGE_PATTERN, { cwd: nodeModulesDir, ignore: DEFAULT_IGNORE }) | ||
.reduce((mappings, file) => { | ||
return fast_glob_1.default | ||
.sync(PACKAGE_PATTERN, { | ||
cwd: nodeModulesDir, | ||
ignore: options.ignorePatterns || DEFAULT_IGNORE, | ||
transform: entry => typeof entry === 'string' ? { path: entry } : { path: entry.path }, | ||
}) | ||
.reduce((mappings, { path: file }) => { | ||
const moduleRoot = path_1.default.dirname(path_1.default.join(nodeModulesDir, file)); | ||
@@ -112,0 +129,0 @@ const lwcConfig = loadLwcConfig(moduleRoot); |
@@ -10,2 +10,4 @@ export interface RegistryEntry { | ||
rootDir: string; | ||
modulePaths: string[]; | ||
ignorePatterns?: string[]; | ||
} | ||
@@ -12,0 +14,0 @@ export declare function resolveModulesInDir(absPath: string): { |
{ | ||
"name": "@lwc/module-resolver", | ||
"description": "Resolves paths for LWC components", | ||
"version": "0.37.3-alpha9", | ||
"version": "0.38.0-alpha1", | ||
"main": "./dist/commonjs/index.js", | ||
@@ -11,3 +11,3 @@ "scripts": { | ||
"dependencies": { | ||
"glob": "^7.1.2" | ||
"fast-glob": "~2.2.6" | ||
}, | ||
@@ -17,3 +17,3 @@ "publishConfig": { | ||
}, | ||
"gitHead": "47b5590bcc9f1b43fc4e5524a30c1fae042b20d7" | ||
"gitHead": "1477d56275cab6ba33ae45bc18a726434fa83410" | ||
} |
@@ -20,5 +20,7 @@ /* | ||
expect(moduleNames).toHaveLength(2); | ||
expect(moduleNames).toContain('ns/simpleCmp', 'ns/simple-module'); | ||
expect(moduleNames).toEqual( | ||
expect.arrayContaining(['ns/simpleCmp', 'ns/simple-module']) | ||
); | ||
}); | ||
}); | ||
}); |
@@ -20,9 +20,55 @@ /* | ||
expect(lwcModuleNames).toHaveLength(4); | ||
expect(lwcModuleNames).toContain( | ||
'alias-fake-package', | ||
'fake-module1', | ||
'fake-module2', | ||
'other-resource' | ||
expect(lwcModuleNames).toEqual( | ||
expect.arrayContaining([ | ||
'alias-fake-package', | ||
'fake/module1', | ||
'fake/module2', | ||
'other-resource', | ||
]) | ||
); | ||
}); | ||
it('resolve from npm: modulePaths options', () => { | ||
const resolverOptions = { | ||
modulePaths: [path.join(__dirname, 'fixtures', 'fake_node_modules')], | ||
}; | ||
const lwcModules = lwcResolver.resolveLwcNpmModules(resolverOptions); | ||
const lwcModuleNames = Object.keys(lwcModules); | ||
expect(lwcModuleNames).toHaveLength(4); | ||
expect(lwcModuleNames).toEqual( | ||
expect.arrayContaining([ | ||
'alias-fake-package', | ||
'fake/module1', | ||
'fake/module2', | ||
'other-resource', | ||
]) | ||
); | ||
}); | ||
it('resolve from npm: ignorePattern', () => { | ||
const resolverOptions = { | ||
modulePaths: [path.join(__dirname, 'fixtures', 'fake_node_modules')], | ||
ignorePatterns: ['**/fake-module-package/**'], | ||
}; | ||
const lwcModules = lwcResolver.resolveLwcNpmModules(resolverOptions); | ||
const lwcModuleNames = Object.keys(lwcModules); | ||
expect(lwcModuleNames).toHaveLength(3); | ||
expect(lwcModuleNames).toEqual( | ||
expect.arrayContaining(['fake/module1', 'fake/module2', 'other-resource']) | ||
); | ||
}); | ||
it('resolve from npm: modulePaths has direct package.json folder reference', () => { | ||
const resolverOptions = { | ||
modulePaths: [ | ||
path.join(__dirname, 'fixtures', 'fake_node_modules', 'fake-multi-component'), | ||
], | ||
}; | ||
const lwcModules = lwcResolver.resolveLwcNpmModules(resolverOptions); | ||
const lwcModuleNames = Object.keys(lwcModules); | ||
expect(lwcModuleNames).toHaveLength(3); | ||
expect(lwcModuleNames).toEqual( | ||
expect.arrayContaining(['fake/module1', 'fake/module2', 'other-resource']) | ||
); | ||
}); | ||
}); |
@@ -9,3 +9,3 @@ /* | ||
import glob from 'glob'; | ||
import glob from 'fast-glob'; | ||
import path from 'path'; | ||
@@ -16,3 +16,3 @@ import fs from 'fs'; | ||
const DEFAULT_IGNORE = ['**/node_modules/**', '**/__tests__/**']; | ||
const PACKAGE_PATTERN = `**/*/package.json`; | ||
const PACKAGE_PATTERN = ['*/*/package.json', '*/package.json', 'package.json']; | ||
const MODULE_ENTRY_PATTERN = `**/*.[jt]s`; | ||
@@ -31,4 +31,10 @@ const LWC_CONFIG_FILE = '.lwcrc'; | ||
rootDir: string; | ||
modulePaths: string[]; | ||
ignorePatterns?: string[]; | ||
} | ||
interface FlatEntry { | ||
path: string; | ||
} | ||
function createRegistryEntry(entry, moduleSpecifier, moduleName, moduleNamespace): RegistryEntry { | ||
@@ -43,11 +49,13 @@ return { entry, moduleSpecifier, moduleName, moduleNamespace }; | ||
try { | ||
const jsonPkg = require(packageJsonPath); | ||
try { | ||
config = fs.readFileSync(lwcConfigPath, 'utf8'); | ||
} catch (e) { | ||
config = jsonPkg.lwc; | ||
} | ||
config = JSON.parse(fs.readFileSync(lwcConfigPath, 'utf8')); | ||
} catch (ignore) { | ||
// ignore | ||
} | ||
if (!config) { | ||
try { | ||
config = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8')).lwc; | ||
} catch (ignore) { | ||
// ignore | ||
} | ||
} | ||
return config; | ||
@@ -57,23 +65,29 @@ } | ||
export function resolveModulesInDir(absPath: string): { [name: string]: RegistryEntry } { | ||
return glob.sync(MODULE_ENTRY_PATTERN, { cwd: absPath }).reduce((mappings, file) => { | ||
const ext = path.extname(file); | ||
const fileName = path.basename(file, ext); | ||
const rootDir = path.dirname(file); | ||
const rootParts = rootDir.split('/'); // the glob library normalizes paths to forward slashes only - https://github.com/isaacs/node-glob#windows | ||
const entry = path.join(absPath, file); | ||
return glob | ||
.sync<FlatEntry>(MODULE_ENTRY_PATTERN, { | ||
cwd: absPath, | ||
transform: entry => | ||
typeof entry === 'string' ? { path: entry } : { path: entry.path }, | ||
}) | ||
.reduce((mappings, { path: file }) => { | ||
const ext = path.extname(file); | ||
const fileName = path.basename(file, ext); | ||
const rootDir = path.dirname(file); | ||
const rootParts = rootDir.split('/'); // the glob library normalizes paths to forward slashes only - https://github.com/isaacs/node-glob#windows | ||
const entry = path.join(absPath, file); | ||
const dirModuleName = rootParts.pop(); | ||
const dirModuleNamespace = rootParts.pop(); | ||
if (dirModuleNamespace && dirModuleName === fileName) { | ||
const registryNode = createRegistryEntry( | ||
entry, | ||
`${dirModuleNamespace}/${fileName}`, | ||
fileName, | ||
dirModuleNamespace.toLowerCase() | ||
); | ||
mappings[registryNode.moduleSpecifier] = registryNode; | ||
} | ||
const dirModuleName = rootParts.pop(); | ||
const dirModuleNamespace = rootParts.pop(); | ||
if (dirModuleNamespace && dirModuleName === fileName) { | ||
const registryNode = createRegistryEntry( | ||
entry, | ||
`${dirModuleNamespace}/${fileName}`, | ||
fileName, | ||
dirModuleNamespace.toLowerCase() | ||
); | ||
mappings[registryNode.moduleSpecifier] = registryNode; | ||
} | ||
return mappings; | ||
}, {}); | ||
return mappings; | ||
}, {}); | ||
} | ||
@@ -93,5 +107,12 @@ | ||
rootDir, | ||
modulePaths, | ||
}: Partial<ModuleResolverConfig> = {}) { | ||
if (modulePaths) { | ||
return modulePaths; | ||
} | ||
if (!moduleDirectories && !rootDir) { | ||
return module.paths; | ||
// paths() is spec'd to return null only for built-in node | ||
// modules like 'http'. To be safe, return empty array in | ||
// instead of null in this case. | ||
return require.resolve.paths('.') || []; | ||
} | ||
@@ -132,4 +153,9 @@ | ||
return glob | ||
.sync(PACKAGE_PATTERN, { cwd: nodeModulesDir, ignore: DEFAULT_IGNORE }) | ||
.reduce((mappings, file) => { | ||
.sync<FlatEntry>(PACKAGE_PATTERN, { | ||
cwd: nodeModulesDir, | ||
ignore: options.ignorePatterns || DEFAULT_IGNORE, | ||
transform: entry => | ||
typeof entry === 'string' ? { path: entry } : { path: entry.path }, | ||
}) | ||
.reduce((mappings, { path: file }) => { | ||
const moduleRoot = path.dirname(path.join(nodeModulesDir, file)); | ||
@@ -136,0 +162,0 @@ const lwcConfig = loadLwcConfig(moduleRoot); |
Sorry, the diff of this file is not supported yet
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
26398
18.81%494
21.98%2
-33.33%+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed