basant307/AI_Governance_Project
045
1'use strict';2 3const utils = require('./utils');4const {5 CHAR_ASTERISK, /* * */6 CHAR_AT, /* @ */7 CHAR_BACKWARD_SLASH, /* \ */8 CHAR_COMMA, /* , */9 CHAR_DOT, /* . */10 CHAR_EXCLAMATION_MARK, /* ! */11 CHAR_FORWARD_SLASH, /* / */12 CHAR_LEFT_CURLY_BRACE, /* { */13 CHAR_LEFT_PARENTHESES, /* ( */14 CHAR_LEFT_SQUARE_BRACKET, /* [ */15 CHAR_PLUS, /* + */16 CHAR_QUESTION_MARK, /* ? */17 CHAR_RIGHT_CURLY_BRACE, /* } */18 CHAR_RIGHT_PARENTHESES, /* ) */19 CHAR_RIGHT_SQUARE_BRACKET /* ] */20} = require('./constants');21 22const isPathSeparator = code => {23 return code === CHAR_FORWARD_SLASH || code === CHAR_BACKWARD_SLASH;24};25 26const depth = token => {27 if (token.isPrefix !== true) {28 token.depth = token.isGlobstar ? Infinity : 1;29 }30};31 32/**33 * Quickly scans a glob pattern and returns an object with a handful of34 * useful properties, like `isGlob`, `path` (the leading non-glob, if it exists),35 * `glob` (the actual pattern), `negated` (true if the path starts with `!` but not36 * with `!(`) and `negatedExtglob` (true if the path starts with `!(`).37 *38 * ```js39 * const pm = require('picomatch');40 * console.log(pm.scan('foo/bar/*.js'));41 * { isGlob: true, input: 'foo/bar/*.js', base: 'foo/bar', glob: '*.js' }42 * ```43 * @param {String} `str`44 * @param {Object} `options`45 * @return {Object} Returns an object with tokens and regex source string.46 * @api public47 */48 49const scan = (input, options) => {50 const opts = options || {};51 52 const length = input.length - 1;53 const scanToEnd = opts.parts === true || opts.scanToEnd === true;54 const slashes = [];55 const tokens = [];56 const parts = [];57 58 let str = input;59 let index = -1;60 let start = 0;61 let lastIndex = 0;62 let isBrace = false;63 let isBracket = false;64 let isGlob = false;65 let isExtglob = false;66 let isGlobstar = false;67 let braceEscaped = false;68 let backslashes = false;69 let negated = false;70 let negatedExtglob = false;71 let finished = false;72 let braces = 0;73 let prev;74 let code;75 let token = { value: '', depth: 0, isGlob: false };76 77 const eos = () => index >= length;78 const peek = () => str.charCodeAt(index + 1);79 const advance = () => {80 prev = code;81 return str.charCodeAt(++index);82 };83 84 while (index < length) {85 code = advance();86 let next;87 88 if (code === CHAR_BACKWARD_SLASH) {89 backslashes = token.backslashes = true;90 code = advance();91 92 if (code === CHAR_LEFT_CURLY_BRACE) {93 braceEscaped = true;94 }95 continue;96 }97 98 if (braceEscaped === true || code === CHAR_LEFT_CURLY_BRACE) {99 braces++;100 101 while (eos() !== true && (code = advance())) {102 if (code === CHAR_BACKWARD_SLASH) {103 backslashes = token.backslashes = true;104 advance();105 continue;106 }107 108 if (code === CHAR_LEFT_CURLY_BRACE) {109 braces++;110 continue;111 }112 113 if (braceEscaped !== true && code === CHAR_DOT && (code = advance()) === CHAR_DOT) {114 isBrace = token.isBrace = true;115 isGlob = token.isGlob = true;116 finished = true;117 118 if (scanToEnd === true) {119 continue;120 }121 122 break;123 }124 125 if (braceEscaped !== true && code === CHAR_COMMA) {126 isBrace = token.isBrace = true;127 isGlob = token.isGlob = true;128 finished = true;129 130 if (scanToEnd === true) {131 continue;132 }133 134 break;135 }136 137 if (code === CHAR_RIGHT_CURLY_BRACE) {138 braces--;139 140 if (braces === 0) {141 braceEscaped = false;142 isBrace = token.isBrace = true;143 finished = true;144 break;145 }146 }147 }148 149 if (scanToEnd === true) {150 continue;151 }152 153 break;154 }155 156 if (code === CHAR_FORWARD_SLASH) {157 slashes.push(index);158 tokens.push(token);159 token = { value: '', depth: 0, isGlob: false };160 161 if (finished === true) continue;162 if (prev === CHAR_DOT && index === (start + 1)) {163 start += 2;164 continue;165 }166 167 lastIndex = index + 1;168 continue;169 }170 171 if (opts.noext !== true) {172 const isExtglobChar = code === CHAR_PLUS173 || code === CHAR_AT174 || code === CHAR_ASTERISK175 || code === CHAR_QUESTION_MARK176 || code === CHAR_EXCLAMATION_MARK;177 178 if (isExtglobChar === true && peek() === CHAR_LEFT_PARENTHESES) {179 isGlob = token.isGlob = true;180 isExtglob = token.isExtglob = true;181 finished = true;182 if (code === CHAR_EXCLAMATION_MARK && index === start) {183 negatedExtglob = true;184 }185 186 if (scanToEnd === true) {187 while (eos() !== true && (code = advance())) {188 if (code === CHAR_BACKWARD_SLASH) {189 backslashes = token.backslashes = true;190 code = advance();191 continue;192 }193 194 if (code === CHAR_RIGHT_PARENTHESES) {195 isGlob = token.isGlob = true;196 finished = true;197 break;198 }199 }200 continue;201 }202 break;203 }204 }205 206 if (code === CHAR_ASTERISK) {207 if (prev === CHAR_ASTERISK) isGlobstar = token.isGlobstar = true;208 isGlob = token.isGlob = true;209 finished = true;210 211 if (scanToEnd === true) {212 continue;213 }214 break;215 }216 217 if (code === CHAR_QUESTION_MARK) {218 isGlob = token.isGlob = true;219 finished = true;220 221 if (scanToEnd === true) {222 continue;223 }224 break;225 }226 227 if (code === CHAR_LEFT_SQUARE_BRACKET) {228 while (eos() !== true && (next = advance())) {229 if (next === CHAR_BACKWARD_SLASH) {230 backslashes = token.backslashes = true;231 advance();232 continue;233 }234 235 if (next === CHAR_RIGHT_SQUARE_BRACKET) {236 isBracket = token.isBracket = true;237 isGlob = token.isGlob = true;238 finished = true;239 break;240 }241 }242 243 if (scanToEnd === true) {244 continue;245 }246 247 break;248 }249 250 if (opts.nonegate !== true && code === CHAR_EXCLAMATION_MARK && index === start) {251 negated = token.negated = true;252 start++;253 continue;254 }255 256 if (opts.noparen !== true && code === CHAR_LEFT_PARENTHESES) {257 isGlob = token.isGlob = true;258 259 if (scanToEnd === true) {260 while (eos() !== true && (code = advance())) {261 if (code === CHAR_LEFT_PARENTHESES) {262 backslashes = token.backslashes = true;263 code = advance();264 continue;265 }266 267 if (code === CHAR_RIGHT_PARENTHESES) {268 finished = true;269 break;270 }271 }272 continue;273 }274 break;275 }276 277 if (isGlob === true) {278 finished = true;279 280 if (scanToEnd === true) {281 continue;282 }283 284 break;285 }286 }287 288 if (opts.noext === true) {289 isExtglob = false;290 isGlob = false;291 }292 293 let base = str;294 let prefix = '';295 let glob = '';296 297 if (start > 0) {298 prefix = str.slice(0, start);299 str = str.slice(start);300 lastIndex -= start;301 }302 303 if (base && isGlob === true && lastIndex > 0) {304 base = str.slice(0, lastIndex);305 glob = str.slice(lastIndex);306 } else if (isGlob === true) {307 base = '';308 glob = str;309 } else {310 base = str;311 }312 313 if (base && base !== '' && base !== '/' && base !== str) {314 if (isPathSeparator(base.charCodeAt(base.length - 1))) {315 base = base.slice(0, -1);316 }317 }318 319 if (opts.unescape === true) {320 if (glob) glob = utils.removeBackslashes(glob);321 322 if (base && backslashes === true) {323 base = utils.removeBackslashes(base);324 }325 }326 327 const state = {328 prefix,329 input,330 start,331 base,332 glob,333 isBrace,334 isBracket,335 isGlob,336 isExtglob,337 isGlobstar,338 negated,339 negatedExtglob340 };341 342 if (opts.tokens === true) {343 state.maxDepth = 0;344 if (!isPathSeparator(code)) {345 tokens.push(token);346 }347 state.tokens = tokens;348 }349 350 if (opts.parts === true || opts.tokens === true) {351 let prevIndex;352 353 for (let idx = 0; idx < slashes.length; idx++) {354 const n = prevIndex ? prevIndex + 1 : start;355 const i = slashes[idx];356 const value = input.slice(n, i);357 if (opts.tokens) {358 if (idx === 0 && start !== 0) {359 tokens[idx].isPrefix = true;360 tokens[idx].value = prefix;361 } else {362 tokens[idx].value = value;363 }364 depth(tokens[idx]);365 state.maxDepth += tokens[idx].depth;366 }367 if (idx !== 0 || value !== '') {368 parts.push(value);369 }370 prevIndex = i;371 }372 373 if (prevIndex && prevIndex + 1 < input.length) {374 const value = input.slice(prevIndex + 1);375 parts.push(value);376 377 if (opts.tokens) {378 tokens[tokens.length - 1].value = value;379 depth(tokens[tokens.length - 1]);380 state.maxDepth += tokens[tokens.length - 1].depth;381 }382 }383 384 state.slashes = slashes;385 state.parts = parts;386 }387 388 return state;389};390 391module.exports = scan;392 