source: frontend/node_modules/@rollup/pluginutils/dist/es/index.js

Last change on this file was 9af201e, checked in by MBK <marija.karapandzova@…>, 12 days ago

Fix frontend appearance

  • Property mode set to 100644
File size: 14.0 KB
Line 
1import { extname, sep, resolve, posix } from 'path';
2import pm from 'picomatch';
3
4const addExtension = function addExtension(filename, ext = '.js') {
5 let result = `${filename}`;
6 if (!extname(filename))
7 result += ext;
8 return result;
9};
10
11function walk(ast, { enter, leave }) {
12 return visit(ast, null, enter, leave);
13}
14
15let should_skip = false;
16let should_remove = false;
17let replacement = null;
18const context = {
19 skip: () => should_skip = true,
20 remove: () => should_remove = true,
21 replace: (node) => replacement = node
22};
23
24function replace(parent, prop, index, node) {
25 if (parent) {
26 if (index !== null) {
27 parent[prop][index] = node;
28 } else {
29 parent[prop] = node;
30 }
31 }
32}
33
34function remove(parent, prop, index) {
35 if (parent) {
36 if (index !== null) {
37 parent[prop].splice(index, 1);
38 } else {
39 delete parent[prop];
40 }
41 }
42}
43
44function visit(
45 node,
46 parent,
47 enter,
48 leave,
49 prop,
50 index
51) {
52 if (node) {
53 if (enter) {
54 const _should_skip = should_skip;
55 const _should_remove = should_remove;
56 const _replacement = replacement;
57 should_skip = false;
58 should_remove = false;
59 replacement = null;
60
61 enter.call(context, node, parent, prop, index);
62
63 if (replacement) {
64 node = replacement;
65 replace(parent, prop, index, node);
66 }
67
68 if (should_remove) {
69 remove(parent, prop, index);
70 }
71
72 const skipped = should_skip;
73 const removed = should_remove;
74
75 should_skip = _should_skip;
76 should_remove = _should_remove;
77 replacement = _replacement;
78
79 if (skipped) return node;
80 if (removed) return null;
81 }
82
83 for (const key in node) {
84 const value = (node )[key];
85
86 if (typeof value !== 'object') {
87 continue;
88 }
89
90 else if (Array.isArray(value)) {
91 for (let j = 0, k = 0; j < value.length; j += 1, k += 1) {
92 if (value[j] !== null && typeof value[j].type === 'string') {
93 if (!visit(value[j], node, enter, leave, key, k)) {
94 // removed
95 j--;
96 }
97 }
98 }
99 }
100
101 else if (value !== null && typeof value.type === 'string') {
102 visit(value, node, enter, leave, key, null);
103 }
104 }
105
106 if (leave) {
107 const _replacement = replacement;
108 const _should_remove = should_remove;
109 replacement = null;
110 should_remove = false;
111
112 leave.call(context, node, parent, prop, index);
113
114 if (replacement) {
115 node = replacement;
116 replace(parent, prop, index, node);
117 }
118
119 if (should_remove) {
120 remove(parent, prop, index);
121 }
122
123 const removed = should_remove;
124
125 replacement = _replacement;
126 should_remove = _should_remove;
127
128 if (removed) return null;
129 }
130 }
131
132 return node;
133}
134
135const extractors = {
136 ArrayPattern(names, param) {
137 for (const element of param.elements) {
138 if (element)
139 extractors[element.type](names, element);
140 }
141 },
142 AssignmentPattern(names, param) {
143 extractors[param.left.type](names, param.left);
144 },
145 Identifier(names, param) {
146 names.push(param.name);
147 },
148 MemberExpression() { },
149 ObjectPattern(names, param) {
150 for (const prop of param.properties) {
151 // @ts-ignore Typescript reports that this is not a valid type
152 if (prop.type === 'RestElement') {
153 extractors.RestElement(names, prop);
154 }
155 else {
156 extractors[prop.value.type](names, prop.value);
157 }
158 }
159 },
160 RestElement(names, param) {
161 extractors[param.argument.type](names, param.argument);
162 }
163};
164const extractAssignedNames = function extractAssignedNames(param) {
165 const names = [];
166 extractors[param.type](names, param);
167 return names;
168};
169
170const blockDeclarations = {
171 const: true,
172 let: true
173};
174class Scope {
175 constructor(options = {}) {
176 this.parent = options.parent;
177 this.isBlockScope = !!options.block;
178 this.declarations = Object.create(null);
179 if (options.params) {
180 options.params.forEach((param) => {
181 extractAssignedNames(param).forEach((name) => {
182 this.declarations[name] = true;
183 });
184 });
185 }
186 }
187 addDeclaration(node, isBlockDeclaration, isVar) {
188 if (!isBlockDeclaration && this.isBlockScope) {
189 // it's a `var` or function node, and this
190 // is a block scope, so we need to go up
191 this.parent.addDeclaration(node, isBlockDeclaration, isVar);
192 }
193 else if (node.id) {
194 extractAssignedNames(node.id).forEach((name) => {
195 this.declarations[name] = true;
196 });
197 }
198 }
199 contains(name) {
200 return this.declarations[name] || (this.parent ? this.parent.contains(name) : false);
201 }
202}
203const attachScopes = function attachScopes(ast, propertyName = 'scope') {
204 let scope = new Scope();
205 walk(ast, {
206 enter(n, parent) {
207 const node = n;
208 // function foo () {...}
209 // class Foo {...}
210 if (/(Function|Class)Declaration/.test(node.type)) {
211 scope.addDeclaration(node, false, false);
212 }
213 // var foo = 1
214 if (node.type === 'VariableDeclaration') {
215 const { kind } = node;
216 const isBlockDeclaration = blockDeclarations[kind];
217 // don't add const/let declarations in the body of a for loop #113
218 const parentType = parent ? parent.type : '';
219 if (!(isBlockDeclaration && /ForOfStatement/.test(parentType))) {
220 node.declarations.forEach((declaration) => {
221 scope.addDeclaration(declaration, isBlockDeclaration, true);
222 });
223 }
224 }
225 let newScope;
226 // create new function scope
227 if (/Function/.test(node.type)) {
228 const func = node;
229 newScope = new Scope({
230 parent: scope,
231 block: false,
232 params: func.params
233 });
234 // named function expressions - the name is considered
235 // part of the function's scope
236 if (func.type === 'FunctionExpression' && func.id) {
237 newScope.addDeclaration(func, false, false);
238 }
239 }
240 // create new block scope
241 if (node.type === 'BlockStatement' && !/Function/.test(parent.type)) {
242 newScope = new Scope({
243 parent: scope,
244 block: true
245 });
246 }
247 // catch clause has its own block scope
248 if (node.type === 'CatchClause') {
249 newScope = new Scope({
250 parent: scope,
251 params: node.param ? [node.param] : [],
252 block: true
253 });
254 }
255 if (newScope) {
256 Object.defineProperty(node, propertyName, {
257 value: newScope,
258 configurable: true
259 });
260 scope = newScope;
261 }
262 },
263 leave(n) {
264 const node = n;
265 if (node[propertyName])
266 scope = scope.parent;
267 }
268 });
269 return scope;
270};
271
272// Helper since Typescript can't detect readonly arrays with Array.isArray
273function isArray(arg) {
274 return Array.isArray(arg);
275}
276function ensureArray(thing) {
277 if (isArray(thing))
278 return thing;
279 if (thing == null)
280 return [];
281 return [thing];
282}
283
284function getMatcherString(id, resolutionBase) {
285 if (resolutionBase === false) {
286 return id;
287 }
288 // resolve('') is valid and will default to process.cwd()
289 const basePath = resolve(resolutionBase || '')
290 .split(sep)
291 .join('/')
292 // escape all possible (posix + win) path characters that might interfere with regex
293 .replace(/[-^$*+?.()|[\]{}]/g, '\\$&');
294 // Note that we use posix.join because:
295 // 1. the basePath has been normalized to use /
296 // 2. the incoming glob (id) matcher, also uses /
297 // otherwise Node will force backslash (\) on windows
298 return posix.join(basePath, id);
299}
300const createFilter = function createFilter(include, exclude, options) {
301 const resolutionBase = options && options.resolve;
302 const getMatcher = (id) => id instanceof RegExp
303 ? id
304 : {
305 test: (what) => {
306 // this refactor is a tad overly verbose but makes for easy debugging
307 const pattern = getMatcherString(id, resolutionBase);
308 const fn = pm(pattern, { dot: true });
309 const result = fn(what);
310 return result;
311 }
312 };
313 const includeMatchers = ensureArray(include).map(getMatcher);
314 const excludeMatchers = ensureArray(exclude).map(getMatcher);
315 return function result(id) {
316 if (typeof id !== 'string')
317 return false;
318 if (/\0/.test(id))
319 return false;
320 const pathId = id.split(sep).join('/');
321 for (let i = 0; i < excludeMatchers.length; ++i) {
322 const matcher = excludeMatchers[i];
323 if (matcher.test(pathId))
324 return false;
325 }
326 for (let i = 0; i < includeMatchers.length; ++i) {
327 const matcher = includeMatchers[i];
328 if (matcher.test(pathId))
329 return true;
330 }
331 return !includeMatchers.length;
332 };
333};
334
335const reservedWords = 'break case class catch const continue debugger default delete do else export extends finally for function if import in instanceof let new return super switch this throw try typeof var void while with yield enum await implements package protected static interface private public';
336const builtins = 'arguments Infinity NaN undefined null true false eval uneval isFinite isNaN parseFloat parseInt decodeURI decodeURIComponent encodeURI encodeURIComponent escape unescape Object Function Boolean Symbol Error EvalError InternalError RangeError ReferenceError SyntaxError TypeError URIError Number Math Date String RegExp Array Int8Array Uint8Array Uint8ClampedArray Int16Array Uint16Array Int32Array Uint32Array Float32Array Float64Array Map Set WeakMap WeakSet SIMD ArrayBuffer DataView JSON Promise Generator GeneratorFunction Reflect Proxy Intl';
337const forbiddenIdentifiers = new Set(`${reservedWords} ${builtins}`.split(' '));
338forbiddenIdentifiers.add('');
339const makeLegalIdentifier = function makeLegalIdentifier(str) {
340 let identifier = str
341 .replace(/-(\w)/g, (_, letter) => letter.toUpperCase())
342 .replace(/[^$_a-zA-Z0-9]/g, '_');
343 if (/\d/.test(identifier[0]) || forbiddenIdentifiers.has(identifier)) {
344 identifier = `_${identifier}`;
345 }
346 return identifier || '_';
347};
348
349function stringify(obj) {
350 return (JSON.stringify(obj) || 'undefined').replace(/[\u2028\u2029]/g, (char) => `\\u${`000${char.charCodeAt(0).toString(16)}`.slice(-4)}`);
351}
352function serializeArray(arr, indent, baseIndent) {
353 let output = '[';
354 const separator = indent ? `\n${baseIndent}${indent}` : '';
355 for (let i = 0; i < arr.length; i++) {
356 const key = arr[i];
357 output += `${i > 0 ? ',' : ''}${separator}${serialize(key, indent, baseIndent + indent)}`;
358 }
359 return `${output}${indent ? `\n${baseIndent}` : ''}]`;
360}
361function serializeObject(obj, indent, baseIndent) {
362 let output = '{';
363 const separator = indent ? `\n${baseIndent}${indent}` : '';
364 const entries = Object.entries(obj);
365 for (let i = 0; i < entries.length; i++) {
366 const [key, value] = entries[i];
367 const stringKey = makeLegalIdentifier(key) === key ? key : stringify(key);
368 output += `${i > 0 ? ',' : ''}${separator}${stringKey}:${indent ? ' ' : ''}${serialize(value, indent, baseIndent + indent)}`;
369 }
370 return `${output}${indent ? `\n${baseIndent}` : ''}}`;
371}
372function serialize(obj, indent, baseIndent) {
373 if (obj === Infinity)
374 return 'Infinity';
375 if (obj === -Infinity)
376 return '-Infinity';
377 if (obj === 0 && 1 / obj === -Infinity)
378 return '-0';
379 if (obj instanceof Date)
380 return `new Date(${obj.getTime()})`;
381 if (obj instanceof RegExp)
382 return obj.toString();
383 if (obj !== obj)
384 return 'NaN'; // eslint-disable-line no-self-compare
385 if (Array.isArray(obj))
386 return serializeArray(obj, indent, baseIndent);
387 if (obj === null)
388 return 'null';
389 if (typeof obj === 'object')
390 return serializeObject(obj, indent, baseIndent);
391 return stringify(obj);
392}
393const dataToEsm = function dataToEsm(data, options = {}) {
394 const t = options.compact ? '' : 'indent' in options ? options.indent : '\t';
395 const _ = options.compact ? '' : ' ';
396 const n = options.compact ? '' : '\n';
397 const declarationType = options.preferConst ? 'const' : 'var';
398 if (options.namedExports === false ||
399 typeof data !== 'object' ||
400 Array.isArray(data) ||
401 data instanceof Date ||
402 data instanceof RegExp ||
403 data === null) {
404 const code = serialize(data, options.compact ? null : t, '');
405 const magic = _ || (/^[{[\-\/]/.test(code) ? '' : ' '); // eslint-disable-line no-useless-escape
406 return `export default${magic}${code};`;
407 }
408 let namedExportCode = '';
409 const defaultExportRows = [];
410 for (const [key, value] of Object.entries(data)) {
411 if (key === makeLegalIdentifier(key)) {
412 if (options.objectShorthand)
413 defaultExportRows.push(key);
414 else
415 defaultExportRows.push(`${key}:${_}${key}`);
416 namedExportCode += `export ${declarationType} ${key}${_}=${_}${serialize(value, options.compact ? null : t, '')};${n}`;
417 }
418 else {
419 defaultExportRows.push(`${stringify(key)}:${_}${serialize(value, options.compact ? null : t, '')}`);
420 }
421 }
422 return `${namedExportCode}export default${_}{${n}${t}${defaultExportRows.join(`,${n}${t}`)}${n}};${n}`;
423};
424
425// TODO: remove this in next major
426var index = {
427 addExtension,
428 attachScopes,
429 createFilter,
430 dataToEsm,
431 extractAssignedNames,
432 makeLegalIdentifier
433};
434
435export default index;
436export { addExtension, attachScopes, createFilter, dataToEsm, extractAssignedNames, makeLegalIdentifier };
Note: See TracBrowser for help on using the repository browser.