Software zum Installieren eines Smart-Mirror Frameworks , zum Nutzen von hochschulrelevanten Informationen, auf einem Raspberry-Pi.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

index.cjs.cjs 14KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534
  1. 'use strict';
  2. Object.defineProperty(exports, '__esModule', { value: true });
  3. var jsdocTypePrattParser = require('jsdoc-type-pratt-parser');
  4. var esquery = require('esquery');
  5. var commentParser = require('comment-parser');
  6. function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
  7. var esquery__default = /*#__PURE__*/_interopDefaultLegacy(esquery);
  8. const stripEncapsulatingBrackets = (container, isArr) => {
  9. if (isArr) {
  10. const firstItem = container[0];
  11. firstItem.rawType = firstItem.rawType.replace(/^\{/u, '');
  12. const lastItem = container[container.length - 1];
  13. lastItem.rawType = lastItem.rawType.replace(/\}$/u, '');
  14. return;
  15. }
  16. container.rawType = container.rawType.replace(/^\{/u, '').replace(/\}$/u, '');
  17. };
  18. const commentParserToESTree = (jsdoc, mode) => {
  19. const {
  20. tokens: {
  21. delimiter: delimiterRoot,
  22. lineEnd: lineEndRoot,
  23. postDelimiter: postDelimiterRoot,
  24. end: endRoot,
  25. description: descriptionRoot
  26. }
  27. } = jsdoc.source[0];
  28. const ast = {
  29. delimiter: delimiterRoot,
  30. description: descriptionRoot,
  31. descriptionLines: [],
  32. // `end` will be overwritten if there are other entries
  33. end: endRoot,
  34. postDelimiter: postDelimiterRoot,
  35. lineEnd: lineEndRoot,
  36. type: 'JsdocBlock'
  37. };
  38. const tags = [];
  39. let lastDescriptionLine;
  40. let lastTag = null;
  41. jsdoc.source.slice(1).forEach((info, idx) => {
  42. const {
  43. tokens
  44. } = info;
  45. const {
  46. delimiter,
  47. description,
  48. postDelimiter,
  49. start,
  50. tag,
  51. end,
  52. type: rawType
  53. } = tokens;
  54. if (tag || end) {
  55. if (lastDescriptionLine === undefined) {
  56. lastDescriptionLine = idx;
  57. } // Clean-up with last tag before end or new tag
  58. if (lastTag) {
  59. // Strip out `}` that encapsulates and is not part of
  60. // the type
  61. stripEncapsulatingBrackets(lastTag);
  62. if (lastTag.typeLines.length) {
  63. stripEncapsulatingBrackets(lastTag.typeLines, true);
  64. } // With even a multiline type now in full, add parsing
  65. let parsedType = null;
  66. try {
  67. parsedType = jsdocTypePrattParser.parse(lastTag.rawType, mode);
  68. } catch {// Ignore
  69. }
  70. lastTag.parsedType = parsedType;
  71. }
  72. if (end) {
  73. ast.end = end;
  74. return;
  75. }
  76. const {
  77. end: ed,
  78. ...tkns
  79. } = tokens;
  80. const tagObj = { ...tkns,
  81. descriptionLines: [],
  82. rawType: '',
  83. type: 'JsdocTag',
  84. typeLines: []
  85. };
  86. tagObj.tag = tagObj.tag.replace(/^@/u, '');
  87. lastTag = tagObj;
  88. tags.push(tagObj);
  89. }
  90. if (rawType) {
  91. // Will strip rawType brackets after this tag
  92. lastTag.typeLines.push({
  93. delimiter,
  94. postDelimiter,
  95. rawType,
  96. start,
  97. type: 'JsdocTypeLine'
  98. });
  99. lastTag.rawType += rawType;
  100. }
  101. if (description) {
  102. const holder = lastTag || ast;
  103. holder.descriptionLines.push({
  104. delimiter,
  105. description,
  106. postDelimiter,
  107. start,
  108. type: 'JsdocDescriptionLine'
  109. });
  110. holder.description += holder.description ? '\n' + description : description;
  111. }
  112. });
  113. ast.lastDescriptionLine = lastDescriptionLine;
  114. ast.tags = tags;
  115. return ast;
  116. };
  117. const jsdocVisitorKeys = {
  118. JsdocBlock: ['tags', 'descriptionLines'],
  119. JsdocDescriptionLine: [],
  120. JsdocTypeLine: [],
  121. JsdocTag: ['descriptionLines', 'typeLines', 'parsedType']
  122. };
  123. /**
  124. * @callback CommentHandler
  125. * @param {string} commentSelector
  126. * @param {Node} jsdoc
  127. * @returns {boolean}
  128. */
  129. /**
  130. * @param {Settings} settings
  131. * @returns {CommentHandler}
  132. */
  133. const commentHandler = settings => {
  134. /**
  135. * @type {CommentHandler}
  136. */
  137. return (commentSelector, jsdoc) => {
  138. const {
  139. mode
  140. } = settings;
  141. const selector = esquery__default['default'].parse(commentSelector);
  142. const ast = commentParserToESTree(jsdoc, mode);
  143. return esquery__default['default'].matches(ast, selector, null, {
  144. visitorKeys: { ...jsdocTypePrattParser.visitorKeys,
  145. ...jsdocVisitorKeys
  146. }
  147. });
  148. };
  149. };
  150. const toCamelCase = str => {
  151. return str.toLowerCase().replace(/^[a-z]/gu, init => {
  152. return init.toUpperCase();
  153. }).replace(/_(?<wordInit>[a-z])/gu, (_, n1, o, s, {
  154. wordInit
  155. }) => {
  156. return wordInit.toUpperCase();
  157. });
  158. };
  159. /* eslint-disable prefer-named-capture-group -- Temporary */
  160. const {
  161. seedBlock,
  162. seedTokens
  163. } = commentParser.util;
  164. const {
  165. name: nameTokenizer,
  166. tag: tagTokenizer,
  167. type: typeTokenizer,
  168. description: descriptionTokenizer
  169. } = commentParser.tokenizers;
  170. const hasSeeWithLink = spec => {
  171. return spec.tag === 'see' && /\{@link.+?\}/u.test(spec.source[0].source);
  172. };
  173. const defaultNoTypes = ['default', 'defaultvalue', 'see'];
  174. const defaultNoNames = ['access', 'author', 'default', 'defaultvalue', 'description', 'example', 'exception', 'license', 'return', 'returns', 'since', 'summary', 'throws', 'version', 'variation'];
  175. const getTokenizers = ({
  176. noTypes = defaultNoTypes,
  177. noNames = defaultNoNames
  178. } = {}) => {
  179. // trim
  180. return [// Tag
  181. tagTokenizer(), // Type
  182. spec => {
  183. if (noTypes.includes(spec.tag)) {
  184. return spec;
  185. }
  186. return typeTokenizer()(spec);
  187. }, // Name
  188. spec => {
  189. if (spec.tag === 'template') {
  190. // const preWS = spec.postTag;
  191. const remainder = spec.source[0].tokens.description;
  192. const pos = remainder.search(/(?<![\s,])\s/u);
  193. const name = pos === -1 ? remainder : remainder.slice(0, pos);
  194. const extra = remainder.slice(pos + 1);
  195. let postName = '',
  196. description = '',
  197. lineEnd = '';
  198. if (pos > -1) {
  199. [, postName, description, lineEnd] = extra.match(/(\s*)([^\r]*)(\r)?/u);
  200. }
  201. spec.name = name;
  202. spec.optional = false;
  203. const {
  204. tokens
  205. } = spec.source[0];
  206. tokens.name = name;
  207. tokens.postName = postName;
  208. tokens.description = description;
  209. tokens.lineEnd = lineEnd || '';
  210. return spec;
  211. }
  212. if (noNames.includes(spec.tag) || hasSeeWithLink(spec)) {
  213. return spec;
  214. }
  215. return nameTokenizer()(spec);
  216. }, // Description
  217. spec => {
  218. return descriptionTokenizer('preserve')(spec);
  219. }];
  220. };
  221. /**
  222. *
  223. * @param {PlainObject} commentNode
  224. * @param {string} indent Whitespace
  225. * @returns {PlainObject}
  226. */
  227. const parseComment = (commentNode, indent) => {
  228. // Preserve JSDoc block start/end indentation.
  229. return commentParser.parse(`/*${commentNode.value}*/`, {
  230. // @see https://github.com/yavorskiy/comment-parser/issues/21
  231. tokenizers: getTokenizers()
  232. })[0] || seedBlock({
  233. source: [{
  234. number: 0,
  235. tokens: seedTokens({
  236. delimiter: '/**'
  237. })
  238. }, {
  239. number: 1,
  240. tokens: seedTokens({
  241. end: '*/',
  242. start: indent + ' '
  243. })
  244. }]
  245. });
  246. };
  247. /**
  248. * Obtained originally from {@link https://github.com/eslint/eslint/blob/master/lib/util/source-code.js#L313}.
  249. *
  250. * @license MIT
  251. */
  252. /**
  253. * Checks if the given token is a comment token or not.
  254. *
  255. * @param {Token} token - The token to check.
  256. * @returns {boolean} `true` if the token is a comment token.
  257. */
  258. const isCommentToken = token => {
  259. return token.type === 'Line' || token.type === 'Block' || token.type === 'Shebang';
  260. };
  261. const getDecorator = node => {
  262. var _node$declaration, _node$declaration$dec, _node$decorators, _node$parent, _node$parent$decorato;
  263. return (node === null || node === void 0 ? void 0 : (_node$declaration = node.declaration) === null || _node$declaration === void 0 ? void 0 : (_node$declaration$dec = _node$declaration.decorators) === null || _node$declaration$dec === void 0 ? void 0 : _node$declaration$dec[0]) || (node === null || node === void 0 ? void 0 : (_node$decorators = node.decorators) === null || _node$decorators === void 0 ? void 0 : _node$decorators[0]) || (node === null || node === void 0 ? void 0 : (_node$parent = node.parent) === null || _node$parent === void 0 ? void 0 : (_node$parent$decorato = _node$parent.decorators) === null || _node$parent$decorato === void 0 ? void 0 : _node$parent$decorato[0]);
  264. };
  265. /**
  266. * Check to see if its a ES6 export declaration.
  267. *
  268. * @param {ASTNode} astNode An AST node.
  269. * @returns {boolean} whether the given node represents an export declaration.
  270. * @private
  271. */
  272. const looksLikeExport = function (astNode) {
  273. return astNode.type === 'ExportDefaultDeclaration' || astNode.type === 'ExportNamedDeclaration' || astNode.type === 'ExportAllDeclaration' || astNode.type === 'ExportSpecifier';
  274. };
  275. const getTSFunctionComment = function (astNode) {
  276. const {
  277. parent
  278. } = astNode;
  279. const grandparent = parent.parent;
  280. const greatGrandparent = grandparent.parent;
  281. const greatGreatGrandparent = greatGrandparent && greatGrandparent.parent; // istanbul ignore if
  282. if (parent.type !== 'TSTypeAnnotation') {
  283. return astNode;
  284. }
  285. switch (grandparent.type) {
  286. case 'ClassProperty':
  287. case 'TSDeclareFunction':
  288. case 'TSMethodSignature':
  289. case 'TSPropertySignature':
  290. return grandparent;
  291. case 'ArrowFunctionExpression':
  292. // istanbul ignore else
  293. if (greatGrandparent.type === 'VariableDeclarator' // && greatGreatGrandparent.parent.type === 'VariableDeclaration'
  294. ) {
  295. return greatGreatGrandparent.parent;
  296. } // istanbul ignore next
  297. return astNode;
  298. case 'FunctionExpression':
  299. // istanbul ignore else
  300. if (greatGrandparent.type === 'MethodDefinition') {
  301. return greatGrandparent;
  302. }
  303. // Fallthrough
  304. default:
  305. // istanbul ignore if
  306. if (grandparent.type !== 'Identifier') {
  307. // istanbul ignore next
  308. return astNode;
  309. }
  310. } // istanbul ignore next
  311. switch (greatGrandparent.type) {
  312. case 'ArrowFunctionExpression':
  313. // istanbul ignore else
  314. if (greatGreatGrandparent.type === 'VariableDeclarator' && greatGreatGrandparent.parent.type === 'VariableDeclaration') {
  315. return greatGreatGrandparent.parent;
  316. } // istanbul ignore next
  317. return astNode;
  318. case 'FunctionDeclaration':
  319. return greatGrandparent;
  320. case 'VariableDeclarator':
  321. // istanbul ignore else
  322. if (greatGreatGrandparent.type === 'VariableDeclaration') {
  323. return greatGreatGrandparent;
  324. }
  325. // Fallthrough
  326. default:
  327. // istanbul ignore next
  328. return astNode;
  329. }
  330. };
  331. const invokedExpression = new Set(['CallExpression', 'OptionalCallExpression', 'NewExpression']);
  332. const allowableCommentNode = new Set(['VariableDeclaration', 'ExpressionStatement', 'MethodDefinition', 'Property', 'ObjectProperty', 'ClassProperty']);
  333. /**
  334. * Reduces the provided node to the appropriate node for evaluating
  335. * JSDoc comment status.
  336. *
  337. * @param {ASTNode} node An AST node.
  338. * @param {SourceCode} sourceCode The ESLint SourceCode.
  339. * @returns {ASTNode} The AST node that can be evaluated for appropriate
  340. * JSDoc comments.
  341. * @private
  342. */
  343. const getReducedASTNode = function (node, sourceCode) {
  344. let {
  345. parent
  346. } = node;
  347. switch (node.type) {
  348. case 'TSFunctionType':
  349. return getTSFunctionComment(node);
  350. case 'TSInterfaceDeclaration':
  351. case 'TSTypeAliasDeclaration':
  352. case 'TSEnumDeclaration':
  353. case 'ClassDeclaration':
  354. case 'FunctionDeclaration':
  355. return looksLikeExport(parent) ? parent : node;
  356. case 'TSDeclareFunction':
  357. case 'ClassExpression':
  358. case 'ObjectExpression':
  359. case 'ArrowFunctionExpression':
  360. case 'TSEmptyBodyFunctionExpression':
  361. case 'FunctionExpression':
  362. if (!invokedExpression.has(parent.type)) {
  363. while (!sourceCode.getCommentsBefore(parent).length && !/Function/u.test(parent.type) && !allowableCommentNode.has(parent.type)) {
  364. ({
  365. parent
  366. } = parent);
  367. if (!parent) {
  368. break;
  369. }
  370. }
  371. if (parent && parent.type !== 'FunctionDeclaration' && parent.type !== 'Program') {
  372. if (parent.parent && parent.parent.type === 'ExportNamedDeclaration') {
  373. return parent.parent;
  374. }
  375. return parent;
  376. }
  377. }
  378. return node;
  379. default:
  380. return node;
  381. }
  382. };
  383. /**
  384. * Checks for the presence of a JSDoc comment for the given node and returns it.
  385. *
  386. * @param {ASTNode} astNode The AST node to get the comment for.
  387. * @param {SourceCode} sourceCode
  388. * @param {{maxLines: Integer, minLines: Integer}} settings
  389. * @returns {Token|null} The Block comment token containing the JSDoc comment
  390. * for the given node or null if not found.
  391. * @private
  392. */
  393. const findJSDocComment = (astNode, sourceCode, settings) => {
  394. const {
  395. minLines,
  396. maxLines
  397. } = settings;
  398. let currentNode = astNode;
  399. let tokenBefore = null;
  400. while (currentNode) {
  401. const decorator = getDecorator(currentNode);
  402. if (decorator) {
  403. currentNode = decorator;
  404. }
  405. tokenBefore = sourceCode.getTokenBefore(currentNode, {
  406. includeComments: true
  407. });
  408. if (!tokenBefore || !isCommentToken(tokenBefore)) {
  409. return null;
  410. }
  411. if (tokenBefore.type === 'Line') {
  412. currentNode = tokenBefore;
  413. continue;
  414. }
  415. break;
  416. }
  417. if (tokenBefore.type === 'Block' && tokenBefore.value.charAt(0) === '*' && currentNode.loc.start.line - tokenBefore.loc.end.line >= minLines && currentNode.loc.start.line - tokenBefore.loc.end.line <= maxLines) {
  418. return tokenBefore;
  419. }
  420. return null;
  421. };
  422. /**
  423. * Retrieves the JSDoc comment for a given node.
  424. *
  425. * @param {SourceCode} sourceCode The ESLint SourceCode
  426. * @param {ASTNode} node The AST node to get the comment for.
  427. * @param {PlainObject} settings The settings in context
  428. * @returns {Token|null} The Block comment token containing the JSDoc comment
  429. * for the given node or null if not found.
  430. * @public
  431. */
  432. const getJSDocComment = function (sourceCode, node, settings) {
  433. const reducedNode = getReducedASTNode(node, sourceCode);
  434. return findJSDocComment(reducedNode, sourceCode, settings);
  435. };
  436. Object.defineProperty(exports, 'jsdocTypeVisitorKeys', {
  437. enumerable: true,
  438. get: function () {
  439. return jsdocTypePrattParser.visitorKeys;
  440. }
  441. });
  442. exports.commentHandler = commentHandler;
  443. exports.commentParserToESTree = commentParserToESTree;
  444. exports.defaultNoNames = defaultNoNames;
  445. exports.defaultNoTypes = defaultNoTypes;
  446. exports.findJSDocComment = findJSDocComment;
  447. exports.getDecorator = getDecorator;
  448. exports.getJSDocComment = getJSDocComment;
  449. exports.getReducedASTNode = getReducedASTNode;
  450. exports.getTokenizers = getTokenizers;
  451. exports.hasSeeWithLink = hasSeeWithLink;
  452. exports.jsdocVisitorKeys = jsdocVisitorKeys;
  453. exports.parseComment = parseComment;
  454. exports.toCamelCase = toCamelCase;