@stylable/core
Version:
CSS for Components
50 lines (47 loc) • 1.81 kB
text/typescript
import hash from 'murmurhash';
import * as nodePath from 'path'; /* type */
import { processNamespace } from './stylable-processor';
export function packageNamespaceFactory(
findConfig: (fileName: string, options: { cwd: string }) => string | null,
loadConfig: (filePath: string) => object,
{ dirname, relative }: Pick<typeof nodePath, 'relative' | 'dirname'>,
hashSalt = '',
prefix = '',
normalizeVersion = (semver: string) => semver
): typeof processNamespace {
return (namespace: string, stylesheetPath: string) => {
const configPath = findConfig('package.json', { cwd: dirname(stylesheetPath) });
if (!configPath) {
throw new Error(`Could not find package.json for ${stylesheetPath}`);
}
const config = loadConfig(configPath) as { name: string; version: string };
const fromRoot = relative(dirname(configPath), stylesheetPath).replace(/\\/g, '/');
return (
prefix +
namespace +
hash.v3(
hashSalt + config.name + '@' + normalizeVersion(config.version) + '/' + fromRoot
)
);
};
}
export function noCollisionNamespace({
prefix = '',
used: usedNamespaces = new Map<
string,
{ prefix: string; namespace: string; stylesheetPath: string }
>(),
} = {}): typeof processNamespace {
return (namespace, stylesheetPath) => {
const ns = prefix + namespace;
const used = usedNamespaces.get(ns);
if (used) {
if (used.stylesheetPath !== stylesheetPath) {
throw new Error(`namespace (${ns} of ${stylesheetPath}) is already in use`);
}
} else {
usedNamespaces.set(ns, { prefix, namespace, stylesheetPath });
}
return ns;
};
}