1 | "use strict";
|
2 |
|
3 | exports.__esModule = true;
|
4 | exports.buildDependencyError = buildDependencyError;
|
5 | exports.collectStyles = collectStyles;
|
6 | exports.replaceStyleTemplates = replaceStyleTemplates;
|
7 | exports.resolveOptions = resolveOptions;
|
8 |
|
9 | var _codeFrame = require("@babel/code-frame");
|
10 |
|
11 | var _fastLevenshtein = _interopRequireDefault(require("fast-levenshtein"));
|
12 |
|
13 | var _sortBy = _interopRequireDefault(require("lodash/sortBy"));
|
14 |
|
15 | var _magicString = _interopRequireDefault(require("magic-string"));
|
16 |
|
17 | var _picocolors = _interopRequireDefault(require("picocolors"));
|
18 |
|
19 | var _config = _interopRequireDefault(require("../config"));
|
20 |
|
21 | var _traverse = _interopRequireDefault(require("../traverse"));
|
22 |
|
23 | var _createFilename = require("./createFilename");
|
24 |
|
25 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
26 |
|
27 | class AstroturfLoaderError extends Error {
|
28 | constructor(errorOrMessage, codeFrame) {
|
29 | super();
|
30 | this.name = 'AstroturfLoaderError';
|
31 |
|
32 | if (typeof errorOrMessage !== 'string') {
|
33 | this.error = errorOrMessage;
|
34 |
|
35 | if (errorOrMessage.name === 'CssSyntaxError') {
|
36 | this.handleCssError(errorOrMessage);
|
37 | } else {
|
38 | this.handleBabelError(errorOrMessage);
|
39 | }
|
40 | } else {
|
41 | this.message = errorOrMessage;
|
42 | Error.captureStackTrace(this, AstroturfLoaderError);
|
43 | }
|
44 |
|
45 | if (codeFrame) this.message += `\n\n${codeFrame}\n`;
|
46 | }
|
47 |
|
48 | handleBabelError(error) {
|
49 | this.message = error.message;
|
50 |
|
51 | try {
|
52 | this.stack = error.stack.replace(/^(.*?):/, `${this.name}:`);
|
53 | } catch (e) {
|
54 | Error.captureStackTrace(this, AstroturfLoaderError);
|
55 | }
|
56 | }
|
57 |
|
58 | handleCssError(error) {
|
59 | const {
|
60 | line,
|
61 | column,
|
62 | reason,
|
63 | plugin,
|
64 | file
|
65 | } = error;
|
66 | this.message = `${this.name}\n\n`;
|
67 |
|
68 | if (typeof line !== 'undefined') {
|
69 | this.message += `(${line}:${column}) `;
|
70 | }
|
71 |
|
72 | this.message += plugin ? `${plugin}: ` : '';
|
73 | this.message += file ? `${file} ` : '<css input> ';
|
74 | this.message += `${reason}`;
|
75 | const code = error.showSourceCode();
|
76 |
|
77 | if (code) {
|
78 | this.message += `\n\n${code}\n`;
|
79 | }
|
80 |
|
81 |
|
82 | this.stack = false;
|
83 | }
|
84 |
|
85 | }
|
86 |
|
87 | function buildDependencyError(content, {
|
88 | type,
|
89 | identifier,
|
90 | request
|
91 | }, styles, resource, loc) {
|
92 | let idents = styles.map(s => s.identifier);
|
93 | let closest;
|
94 | let minDistance = 2;
|
95 | idents.forEach(ident => {
|
96 | const d = _fastLevenshtein.default.get(ident, identifier);
|
97 |
|
98 | if (d < minDistance) {
|
99 | minDistance = d;
|
100 | closest = ident;
|
101 | }
|
102 | });
|
103 | const isDefaultImport = type === 'ImportDefaultSpecifier';
|
104 |
|
105 | if (!closest && isDefaultImport) {
|
106 | closest = idents.find(ident => ident === (0, _createFilename.getNameFromFile)(resource));
|
107 | }
|
108 |
|
109 | if (closest) idents = idents.filter(ident => ident !== closest);
|
110 | const identMsg = idents.map(s => _picocolors.default.yellow(s)).join(', ');
|
111 | const alternative = isDefaultImport ? `Instead try: ${_picocolors.default.yellow(`import ${closest} from '${request}';`)}` : `Did you mean to import as ${_picocolors.default.yellow(closest)} instead?`;
|
112 | return new AstroturfLoaderError(
|
113 | `Could not find a style associated with the interpolated value. ` + `Styles should use the same name used by the intended component or class set in the imported file.\n\n` + (0, _codeFrame.codeFrameColumns)(content, {
|
114 | start: loc.start
|
115 | }, {
|
116 | highlightCode: true,
|
117 | message: !isDefaultImport ? `(Imported as ${_picocolors.default.bold(identifier)})` : ''
|
118 | }) + `\n\n${closest ? `${alternative}\n\nAlso available: ${identMsg}` : `Available: ${identMsg}`}`);
|
119 | }
|
120 |
|
121 | function collectStyles(src, filename, resolveDependency, opts) {
|
122 |
|
123 | try {
|
124 | const {
|
125 | metadata
|
126 | } = (0, _traverse.default)(src, filename, { ...opts,
|
127 | resolveDependency,
|
128 | writeFiles: false,
|
129 | generateInterpolations: true
|
130 | });
|
131 | return metadata.astroturf;
|
132 | } catch (err) {
|
133 | throw new AstroturfLoaderError(err);
|
134 | }
|
135 | }
|
136 |
|
137 | function replaceStyleTemplates(loaderContext, filename, src, locations // content: Map<string, string>,
|
138 | ) {
|
139 | locations = (0, _sortBy.default)(locations, i => i.start || 0);
|
140 | const magic = new _magicString.default(src);
|
141 | locations.forEach(({
|
142 | start = 0,
|
143 | end = 0,
|
144 | code = ''
|
145 | }) => {
|
146 | if (code.endsWith(';')) code = code.slice(0, -1);
|
147 |
|
148 | if (start === end) {
|
149 | magic.appendLeft(start, code);
|
150 | } else {
|
151 | magic.overwrite(start, end, code);
|
152 | }
|
153 | });
|
154 | return {
|
155 | code: magic.toString(),
|
156 | map: loaderContext.sourceMap ? magic.generateMap({
|
157 | includeContent: true,
|
158 | source: filename
|
159 | }) : null
|
160 | };
|
161 | }
|
162 |
|
163 | async function resolveOptions(loaderContext) {
|
164 | const loaderOpts = loaderContext.getOptions() || {};
|
165 |
|
166 | if (loaderOpts.config === false) {
|
167 | return loaderOpts;
|
168 | }
|
169 |
|
170 | const result = await (typeof loaderOpts.config === 'string' ? _config.default.load(loaderOpts.config) : _config.default.search(loaderContext.resourcePath));
|
171 | return (result == null ? void 0 : result.config) || loaderOpts;
|
172 | } |
\ | No newline at end of file |