@stylable/core
Version:
CSS for Components
256 lines • 9.88 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.StylableResolver = exports.isInPath = exports.resolverWarnings = void 0;
const stylable_value_parsers_1 = require("./stylable-value-parsers");
exports.resolverWarnings = {
UNKNOWN_IMPORTED_FILE(path) {
return `cannot resolve imported file: "${path}"`;
},
UNKNOWN_IMPORTED_SYMBOL(name, path) {
return `cannot resolve imported symbol "${name}" from stylesheet "${path}"`;
},
};
function isInPath(extendPath, { symbol: { name: name1 }, meta: { source: source1 } }) {
return extendPath.find(({ symbol: { name }, meta: { source } }) => {
return name1 === name && source === source1;
});
}
exports.isInPath = isInPath;
class StylableResolver {
constructor(fileProcessor, requireModule) {
this.fileProcessor = fileProcessor;
this.requireModule = requireModule;
}
resolveImported(imported, name) {
const { context, from } = imported;
let symbol;
if (from.match(/\.css$/)) {
let meta;
try {
meta = this.fileProcessor.process(from, false, context);
symbol = !name ? meta.mappedSymbols[meta.root] : meta.mappedSymbols[name];
}
catch (e) {
return null;
}
return { _kind: 'css', symbol, meta };
}
else {
let _module;
try {
_module = this.requireModule(this.fileProcessor.resolvePath(from));
}
catch {
return null;
}
symbol = !name ? _module.default || _module : _module[name];
return { _kind: 'js', symbol, meta: null };
}
}
resolveImport(importSymbol) {
const name = importSymbol.type === 'named' ? importSymbol.name : '';
return this.resolveImported(importSymbol.import, name);
}
resolve(maybeImport) {
if (!maybeImport || maybeImport._kind !== 'import') {
if (maybeImport && maybeImport._kind !== 'var' && maybeImport._kind !== 'cssVar') {
if (maybeImport.alias && !maybeImport[stylable_value_parsers_1.valueMapping.extends]) {
maybeImport = maybeImport.alias;
}
else if (maybeImport[stylable_value_parsers_1.valueMapping.extends]) {
maybeImport = maybeImport[stylable_value_parsers_1.valueMapping.extends];
}
else {
return null;
}
}
else {
return null;
}
}
if (!maybeImport || maybeImport._kind !== 'import') {
return null;
}
return this.resolveImport(maybeImport);
}
deepResolve(maybeImport, path = []) {
let resolved = this.resolve(maybeImport);
while (resolved &&
resolved._kind === 'css' &&
resolved.symbol &&
resolved.symbol._kind === 'import') {
resolved = this.resolve(resolved.symbol);
}
if (resolved &&
resolved.symbol &&
resolved.meta &&
(resolved.symbol._kind === 'class' || resolved.symbol._kind === 'element') &&
resolved.symbol.alias &&
!resolved.symbol[stylable_value_parsers_1.valueMapping.extends]) {
if (path.includes(resolved.symbol)) {
return { _kind: 'css', symbol: resolved.symbol, meta: resolved.meta };
}
path.push(resolved.symbol);
return this.deepResolve(resolved.symbol.alias, path);
}
return resolved;
}
resolveSymbolOrigin(symbol, meta, path = []) {
if (!symbol || !meta) {
return null;
}
if (symbol._kind === 'element' || symbol._kind === 'class') {
if (path.includes(symbol)) {
return { meta, symbol, _kind: 'css' };
}
path.push(symbol);
const isAliasOnly = symbol.alias && !symbol[stylable_value_parsers_1.valueMapping.extends];
return isAliasOnly
? this.resolveSymbolOrigin(symbol.alias, meta, path)
: { meta, symbol, _kind: 'css' };
}
else if (symbol._kind === 'cssVar') {
if (path.includes(symbol)) {
return { meta, symbol, _kind: 'css' };
}
}
else if (symbol._kind === 'import') {
const resolved = this.resolveImport(symbol);
if (resolved && resolved.symbol && resolved._kind === 'css') {
return this.resolveSymbolOrigin(resolved.symbol, resolved.meta, path);
}
else {
return null;
}
}
return null;
}
resolveClass(meta, symbol) {
return this.resolveName(meta, symbol, false);
}
resolveName(meta, symbol, isElement) {
const type = isElement ? 'element' : 'class';
let finalSymbol;
let finalMeta;
if (symbol._kind === type) {
finalSymbol = symbol;
finalMeta = meta;
}
else if (symbol._kind === 'import') {
const resolved = this.deepResolve(symbol);
if (resolved && resolved._kind === 'css' && resolved.symbol) {
if (resolved.symbol._kind === 'class' || resolved.symbol._kind === 'element') {
finalSymbol = resolved.symbol;
finalMeta = resolved.meta;
}
else {
// TODO: warn
}
}
else {
// TODO: warn
}
}
else {
// TODO: warn
}
if (finalMeta && finalSymbol) {
return {
_kind: 'css',
symbol: finalSymbol,
meta: finalMeta,
};
}
else {
return null;
}
}
resolveElement(meta, symbol) {
return this.resolveName(meta, symbol, true);
}
resolveExtends(meta, className, isElement = false, transformer, reportError) {
const bucket = isElement ? meta.elements : meta.classes;
const customSelector = isElement ? null : meta.customSelectors[':--' + className];
if (!bucket[className] && !customSelector) {
return [];
}
if (customSelector && transformer) {
const parsed = transformer.resolveSelectorElements(meta, customSelector);
if (parsed.length === 1) {
return parsed[0][parsed[0].length - 1].resolved;
}
else {
return [];
}
}
let current = {
_kind: 'css',
symbol: bucket[className],
meta,
};
const extendPath = [];
while (current === null || current === void 0 ? void 0 : current.symbol) {
if (isInPath(extendPath, current)) {
break;
}
extendPath.push(current);
const parent = current.symbol[stylable_value_parsers_1.valueMapping.extends] || current.symbol.alias;
if (parent) {
if (parent._kind === 'import') {
const res = this.resolve(parent);
if (res &&
res._kind === 'css' &&
res.symbol &&
(res.symbol._kind === 'element' || res.symbol._kind === 'class')) {
const { _kind, meta, symbol } = res;
current = {
_kind,
meta,
symbol,
};
}
else {
if (reportError) {
reportError(res, parent, extendPath, meta, className, isElement);
}
break;
}
}
else {
current = { _kind: 'css', symbol: parent, meta };
}
}
else {
break;
}
}
return extendPath;
}
validateImports(meta, diagnostics) {
for (const importObj of meta.imports) {
const resolvedImport = this.resolveImported(importObj, '');
if (!resolvedImport) {
// warn about unknown imported files
const fromDecl = importObj.rule.nodes &&
importObj.rule.nodes.find((decl) => decl.type === 'decl' && decl.prop === stylable_value_parsers_1.valueMapping.from);
if (fromDecl) {
diagnostics.warn(fromDecl, exports.resolverWarnings.UNKNOWN_IMPORTED_FILE(importObj.fromRelative), { word: importObj.fromRelative });
}
}
else if (resolvedImport._kind === 'css') {
// warn about unknown named imported symbols
for (const name in importObj.named) {
const origName = importObj.named[name];
const resolvedSymbol = this.resolveImported(importObj, origName);
const namedDecl = importObj.rule.nodes &&
importObj.rule.nodes.find((decl) => decl.type === 'decl' && decl.prop === stylable_value_parsers_1.valueMapping.named);
if (!resolvedSymbol.symbol && namedDecl) {
diagnostics.warn(namedDecl, exports.resolverWarnings.UNKNOWN_IMPORTED_SYMBOL(origName, importObj.fromRelative), { word: origName });
}
}
}
}
}
}
exports.StylableResolver = StylableResolver;
//# sourceMappingURL=stylable-resolver.js.map