UNPKG

9.88 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3exports.StylableResolver = exports.isInPath = exports.resolverWarnings = void 0;
4const stylable_value_parsers_1 = require("./stylable-value-parsers");
5exports.resolverWarnings = {
6 UNKNOWN_IMPORTED_FILE(path) {
7 return `cannot resolve imported file: "${path}"`;
8 },
9 UNKNOWN_IMPORTED_SYMBOL(name, path) {
10 return `cannot resolve imported symbol "${name}" from stylesheet "${path}"`;
11 },
12};
13function isInPath(extendPath, { symbol: { name: name1 }, meta: { source: source1 } }) {
14 return extendPath.find(({ symbol: { name }, meta: { source } }) => {
15 return name1 === name && source === source1;
16 });
17}
18exports.isInPath = isInPath;
19class StylableResolver {
20 constructor(fileProcessor, requireModule) {
21 this.fileProcessor = fileProcessor;
22 this.requireModule = requireModule;
23 }
24 resolveImported(imported, name) {
25 const { context, from } = imported;
26 let symbol;
27 if (from.match(/\.css$/)) {
28 let meta;
29 try {
30 meta = this.fileProcessor.process(from, false, context);
31 symbol = !name ? meta.mappedSymbols[meta.root] : meta.mappedSymbols[name];
32 }
33 catch (e) {
34 return null;
35 }
36 return { _kind: 'css', symbol, meta };
37 }
38 else {
39 let _module;
40 try {
41 _module = this.requireModule(this.fileProcessor.resolvePath(from));
42 }
43 catch {
44 return null;
45 }
46 symbol = !name ? _module.default || _module : _module[name];
47 return { _kind: 'js', symbol, meta: null };
48 }
49 }
50 resolveImport(importSymbol) {
51 const name = importSymbol.type === 'named' ? importSymbol.name : '';
52 return this.resolveImported(importSymbol.import, name);
53 }
54 resolve(maybeImport) {
55 if (!maybeImport || maybeImport._kind !== 'import') {
56 if (maybeImport && maybeImport._kind !== 'var' && maybeImport._kind !== 'cssVar') {
57 if (maybeImport.alias && !maybeImport[stylable_value_parsers_1.valueMapping.extends]) {
58 maybeImport = maybeImport.alias;
59 }
60 else if (maybeImport[stylable_value_parsers_1.valueMapping.extends]) {
61 maybeImport = maybeImport[stylable_value_parsers_1.valueMapping.extends];
62 }
63 else {
64 return null;
65 }
66 }
67 else {
68 return null;
69 }
70 }
71 if (!maybeImport || maybeImport._kind !== 'import') {
72 return null;
73 }
74 return this.resolveImport(maybeImport);
75 }
76 deepResolve(maybeImport, path = []) {
77 let resolved = this.resolve(maybeImport);
78 while (resolved &&
79 resolved._kind === 'css' &&
80 resolved.symbol &&
81 resolved.symbol._kind === 'import') {
82 resolved = this.resolve(resolved.symbol);
83 }
84 if (resolved &&
85 resolved.symbol &&
86 resolved.meta &&
87 (resolved.symbol._kind === 'class' || resolved.symbol._kind === 'element') &&
88 resolved.symbol.alias &&
89 !resolved.symbol[stylable_value_parsers_1.valueMapping.extends]) {
90 if (path.includes(resolved.symbol)) {
91 return { _kind: 'css', symbol: resolved.symbol, meta: resolved.meta };
92 }
93 path.push(resolved.symbol);
94 return this.deepResolve(resolved.symbol.alias, path);
95 }
96 return resolved;
97 }
98 resolveSymbolOrigin(symbol, meta, path = []) {
99 if (!symbol || !meta) {
100 return null;
101 }
102 if (symbol._kind === 'element' || symbol._kind === 'class') {
103 if (path.includes(symbol)) {
104 return { meta, symbol, _kind: 'css' };
105 }
106 path.push(symbol);
107 const isAliasOnly = symbol.alias && !symbol[stylable_value_parsers_1.valueMapping.extends];
108 return isAliasOnly
109 ? this.resolveSymbolOrigin(symbol.alias, meta, path)
110 : { meta, symbol, _kind: 'css' };
111 }
112 else if (symbol._kind === 'cssVar') {
113 if (path.includes(symbol)) {
114 return { meta, symbol, _kind: 'css' };
115 }
116 }
117 else if (symbol._kind === 'import') {
118 const resolved = this.resolveImport(symbol);
119 if (resolved && resolved.symbol && resolved._kind === 'css') {
120 return this.resolveSymbolOrigin(resolved.symbol, resolved.meta, path);
121 }
122 else {
123 return null;
124 }
125 }
126 return null;
127 }
128 resolveClass(meta, symbol) {
129 return this.resolveName(meta, symbol, false);
130 }
131 resolveName(meta, symbol, isElement) {
132 const type = isElement ? 'element' : 'class';
133 let finalSymbol;
134 let finalMeta;
135 if (symbol._kind === type) {
136 finalSymbol = symbol;
137 finalMeta = meta;
138 }
139 else if (symbol._kind === 'import') {
140 const resolved = this.deepResolve(symbol);
141 if (resolved && resolved._kind === 'css' && resolved.symbol) {
142 if (resolved.symbol._kind === 'class' || resolved.symbol._kind === 'element') {
143 finalSymbol = resolved.symbol;
144 finalMeta = resolved.meta;
145 }
146 else {
147 // TODO: warn
148 }
149 }
150 else {
151 // TODO: warn
152 }
153 }
154 else {
155 // TODO: warn
156 }
157 if (finalMeta && finalSymbol) {
158 return {
159 _kind: 'css',
160 symbol: finalSymbol,
161 meta: finalMeta,
162 };
163 }
164 else {
165 return null;
166 }
167 }
168 resolveElement(meta, symbol) {
169 return this.resolveName(meta, symbol, true);
170 }
171 resolveExtends(meta, className, isElement = false, transformer, reportError) {
172 const bucket = isElement ? meta.elements : meta.classes;
173 const customSelector = isElement ? null : meta.customSelectors[':--' + className];
174 if (!bucket[className] && !customSelector) {
175 return [];
176 }
177 if (customSelector && transformer) {
178 const parsed = transformer.resolveSelectorElements(meta, customSelector);
179 if (parsed.length === 1) {
180 return parsed[0][parsed[0].length - 1].resolved;
181 }
182 else {
183 return [];
184 }
185 }
186 let current = {
187 _kind: 'css',
188 symbol: bucket[className],
189 meta,
190 };
191 const extendPath = [];
192 while (current === null || current === void 0 ? void 0 : current.symbol) {
193 if (isInPath(extendPath, current)) {
194 break;
195 }
196 extendPath.push(current);
197 const parent = current.symbol[stylable_value_parsers_1.valueMapping.extends] || current.symbol.alias;
198 if (parent) {
199 if (parent._kind === 'import') {
200 const res = this.resolve(parent);
201 if (res &&
202 res._kind === 'css' &&
203 res.symbol &&
204 (res.symbol._kind === 'element' || res.symbol._kind === 'class')) {
205 const { _kind, meta, symbol } = res;
206 current = {
207 _kind,
208 meta,
209 symbol,
210 };
211 }
212 else {
213 if (reportError) {
214 reportError(res, parent, extendPath, meta, className, isElement);
215 }
216 break;
217 }
218 }
219 else {
220 current = { _kind: 'css', symbol: parent, meta };
221 }
222 }
223 else {
224 break;
225 }
226 }
227 return extendPath;
228 }
229 validateImports(meta, diagnostics) {
230 for (const importObj of meta.imports) {
231 const resolvedImport = this.resolveImported(importObj, '');
232 if (!resolvedImport) {
233 // warn about unknown imported files
234 const fromDecl = importObj.rule.nodes &&
235 importObj.rule.nodes.find((decl) => decl.type === 'decl' && decl.prop === stylable_value_parsers_1.valueMapping.from);
236 if (fromDecl) {
237 diagnostics.warn(fromDecl, exports.resolverWarnings.UNKNOWN_IMPORTED_FILE(importObj.fromRelative), { word: importObj.fromRelative });
238 }
239 }
240 else if (resolvedImport._kind === 'css') {
241 // warn about unknown named imported symbols
242 for (const name in importObj.named) {
243 const origName = importObj.named[name];
244 const resolvedSymbol = this.resolveImported(importObj, origName);
245 const namedDecl = importObj.rule.nodes &&
246 importObj.rule.nodes.find((decl) => decl.type === 'decl' && decl.prop === stylable_value_parsers_1.valueMapping.named);
247 if (!resolvedSymbol.symbol && namedDecl) {
248 diagnostics.warn(namedDecl, exports.resolverWarnings.UNKNOWN_IMPORTED_SYMBOL(origName, importObj.fromRelative), { word: origName });
249 }
250 }
251 }
252 }
253 }
254}
255exports.StylableResolver = StylableResolver;
256//# sourceMappingURL=stylable-resolver.js.map
\No newline at end of file