Files
t3mp3st/bench/cve-zero/samples/GHSA-vv9j-gjw2-j8wp/source/src/util/namespace.ts
T

78 lines
2.3 KiB
TypeScript

import { parse } from 'node:path';
import slash from 'slash';
import { escapeRegExp, findLast } from 'lodash-es';
type AsNamespaceOptions = {
lookups?: string[];
};
export const defaultLookups = ['.', 'generators', 'lib/generators', 'dist/generators'];
/**
* Given a String `filepath`, tries to figure out the relative namespace.
*
* ### Examples:
*
* this.namespace('backbone/all/index.js');
* // => backbone:all
*
* this.namespace('generator-backbone/model');
* // => backbone:model
*
* this.namespace('backbone.js');
* // => backbone
*
* this.namespace('generator-mocha/backbone/model/index.js');
* // => mocha:backbone:model
*
* @param filepath
* @param lookups paths
*/
export const asNamespace = (filepath: string, { lookups = defaultLookups }: AsNamespaceOptions): string => {
if (!filepath) {
throw new Error('Missing file path');
}
// Normalize path
let ns = slash(filepath);
// Ignore path before latest node_modules
const nodeModulesPath = '/node_modules/';
if (ns.includes(nodeModulesPath)) {
ns = ns.slice(ns.lastIndexOf(nodeModulesPath) + nodeModulesPath.length);
}
// Cleanup extension and normalize path for differents OS
const parsed = parse(ns);
ns = parsed.dir ? `${parsed.dir}/${parsed.name}` : parsed.name;
// Sort lookups by length so biggest are removed first
const nsLookups = [...lookups, '..']
.map(found => slash(found))
.sort((a, b) => a.split('/').length - b.split('/').length)
.toReversed();
// If `ns` contains a lookup dir in its path, remove it.
for (const lookup of nsLookups) {
// Only match full directory (begin with leading slash or start of input, end with trailing slash)
ns = ns.replaceAll(new RegExp(`(?:/|^)${escapeRegExp(lookup)}(?=/)`, 'g'), '');
}
const folders = ns.split('/');
const scope = findLast(folders, folder => folder.startsWith('@'));
// Cleanup `ns` from unwanted parts and then normalize slashes to `:`
ns = ns
.replaceAll('//', '') // Remove double `/`
.replace(/(.*generator-)/, '') // Remove before `generator-`
.replace(/\/(index|main)$/, '') // Remove `/index` or `/main`
.replace(/^\//, '') // Remove leading `/`
.replaceAll(/\/+/g, ':'); // Replace slashes by `:`
if (scope) {
ns = `${scope}/${ns}`;
}
return ns;
};